minimal: embedded lhp examples

Implements a carousel rendering and displaying remote HTML + JPEG + PNGs
on a variety of display devices, including several EPDs.
This commit is contained in:
Andy Green 2022-02-14 09:01:28 +00:00
parent 4a443c3e2e
commit 31ff36e09d
67 changed files with 31446 additions and 21 deletions

View File

@ -26,6 +26,16 @@ sdevent, glib and uloop, as well as custom event libs.
News
----
## HTML + CSS + JPEG + PNG display stack in lws
Want to drive your EPD or TFT / OLED display using HTML + CSS? Only got an ESP32?
Want remote JPEGs, PNGs, HTML, RGBA composition, gamma, error diffusion if needed?
Realtime render into a line buffer because you don't have enough heap for a framebuffer?
[Take a look here...](https://libwebsockets.org/git/libwebsockets/tree/READMEs/README.html-parser.md)
## Perl binding for lws available
Thanks to Felipe Gasper, there's now a [perl binding for lws available at metacpan](https://metacpan.org/pod/Net::Libwebsockets),

View File

@ -3,19 +3,10 @@
## Please note this is working end-end, but some parts incomplete and generally pre-alpha... looking for interested parties to help
![overview](../doc-assets/lhp-overview.png)
<figcaption>*LHP Stream-parses HTML and CSS into a DOM and then into DLOs (lws
Display List Objects). Multiple, antialiased, proportional fonts, JPEG and PNGs
are supported. A linewise rasterizer is provided well-suited to resource-
constrained devices with SPI based displays.*</figcaption>
<figcaption>*LHP Stream-parses HTML and CSS into a DOM and then into DLOs (lws Display List Objects). Multiple, antialiased, proportional fonts, JPEG and PNGs are supported. A linewise rasterizer is provided well-suited to resource-constrained devices with SPI based displays.*</figcaption>
![example](../doc-assets/lhp-acep7.jpg)
<figcaption>*Page fetched from `https://libwebsockets.org/lhp-tests/t1.html` by
an ESP32, and rendered by lws on a 600x448 ACEP 7-colour EPD with 24-bit
composition. The warning symbol at the bottom right is a .png `<img>` in an
absolutely positioned `<div>`. The yellow shapes at the top right are divs with
css-styled rounded corners. The red div is partly transparent. Display only
has a 7 colour palette. Server only sends CSS/HTML/JPEG/PNG, all parsing and
rendering done on the ESP32.*</figcaption>
<figcaption>*Page fetched from `https://libwebsockets.org/lhp-tests/t1.html` by an ESP32, and rendered by lws on a 600x448 ACEP 7-colour EPD with 24-bit composition. The warning symbol at the bottom right is a .png img in an absolutely positioned `<div>`. The yellow shapes at the top right are divs with css-styled rounded corners. The red div is partly transparent. Display only has a 7 colour palette. Server only sends CSS/HTML/JPEG/PNG, all parsing and rendering done on the ESP32.*</figcaption>
## Overview
@ -265,6 +256,25 @@ display pipline using native 565.
![overview](https://libwebsockets.org/wrover-boot.gif)
<figcaption>*ESP32 WROVER KIT running the example carousel on a 320x200 565 RGB SPI display. 10s delay between tests snipped for brevity, otherwise shown realtime. Moire is artifact of camera. As composition is linewise, the JPEG and other data from libwebsockets.org is arriving and being completely parsed / composed in the time taken to update the display. Interleaved SPI DMA used to send line to display while rendering the next.*</figcaption>
## Implications of stream-parsing HTML
To maximize the scalability, HTML is parsed into an element stack, consisting
of a set of nested parent-child elements. As an element goes out of scope and
the parsing moves on to the next, its parents also go out of scope and are
destroyed... new parsents are kept in the stack again only while they have
children in scope. This keeps a strict pressure against large instantaneous
heap allocations for HTML parsing, but it has some implications.
This "goldfish memory" "keyhole parsing" scheme by itself is inadequate when the
dimensions of future elements will affect the dimensions of the current one, eg,
a table where we don't find out until later how many rows it has, and so how
high it is. There's also a class of retrospective dimension acquisition, eg,
where a JPEG `img` is in a table, but we don't find out its dimensions until we
parse its header much later, long after the whole http parser stack related to
it has been destroyed, and possibly many other things laid out after it.
## Top level API
```

View File

@ -87,17 +87,17 @@ if (LWS_WITH_DLO)
misc/dlo/dlo-ss.c)
endif()
if (LWS_WITH_UPNG AND LWS_WITH_SECURE_STREAMS AND LWS_WITH_CLIENT)
if (LWS_WITH_UPNG)
list(APPEND SOURCES
misc/dlo/dlo-png.c)
endif()
if (LWS_WITH_JPEG AND LWS_WITH_SECURE_STREAMS AND LWS_WITH_CLIENT)
if (LWS_WITH_JPEG)
list(APPEND SOURCES
misc/dlo/dlo-jpeg.c)
endif()
if (LWS_WITH_LHP AND LWS_WITH_DLO AND LWS_WITH_SECURE_STREAMS AND LWS_WITH_CLIENT)
if (LWS_WITH_LHP)
list(APPEND SOURCES
misc/dlo/dlo-lhp.c
)

View File

@ -114,7 +114,8 @@ render(lws_sorted_usec_list_t *sul)
if (!rs->line) {
lws_display_dl_dump(&rs->displaylist);
lws_display_get_ids_boxes(rs);
//lws_display_dl_dump(&rs->displaylist);
/* allocate one line of RGB output pixels to render into */
@ -167,7 +168,6 @@ render(lws_sorted_usec_list_t *sul)
free(rs->line);
lws_display_list_destroy(&rs->displaylist);
lws_default_loop_exit(cx);
}

View File

@ -98,7 +98,7 @@ static const lws_display_ssd1306_t disp = {
static const lws_led_gpio_map_t lgm[] = {
{
.name = "alert",
.name = "red",
.gpio = GPIO_NUM_25,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
@ -205,7 +205,7 @@ init_plat_devices(struct lws_context *ctx)
lws_display_state_init(&lds, ctx, 10000, 20000, lls, &disp.disp);
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
lws_led_transition(lls, "alert", &lws_pwmseq_static_off,
lws_led_transition(lls, "red", &lws_pwmseq_static_off,
&lws_pwmseq_static_on);
return 0;

View File

@ -197,7 +197,7 @@ app_main(void)
/* put the logo on the OLED display */
lds.disp->blit(&lds, img, &box);
lds.disp->blit(&lds, img, &box, NULL);
lws_display_state_active(&lds);
/* the lws event loop */

View File

@ -232,7 +232,7 @@ app_main(void)
/* put the cat picture up there and enable the backlight */
lds.disp->blit(&lds, logo, &box);
lds.disp->blit(&lds, logo, &box, NULL);
lws_display_state_active(&lds);
/* the lws event loop */

View File

@ -0,0 +1,81 @@
# lhp (HTML renderer) embedded demos
These are demos for various ESP32 + display combinations. A lot of
the code is common between the demos and is in the toplevel dir
(where this README lives).
Notice that although the demos are for ESP32 currently, there is no
ESP32-specific code in the common part. Only `main/devices.c` in the
combination-specific directories has the platform-specific init.
The demo visits some sites using h2 and renders them on the device +
display combination, with a 10s wait between, in a carousel.
ESP32 WROVER KIT, and ESP32S2 Kaluga boards and displays are
supported, along with Waveshare ESP32 dev board and a variety of
E-ink displays.
## Setting up wifi
Edit ./main/devices.c in your platform-specific subdir, enable this section
and set your wifi SSID and passphrase in the `xxx` strings. This will store
the information on flash on the device.
Boot once with that and then remove your information and disable the code
section again and rebuild.
```
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xxx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
```
Eventually there will be a better way to set this up.
## Building
Set up for esp-idf, enter the platform-specific subdir and edit
`build.sh` to point to the correct USB device path.
The first time we need to erase the whole flash and blow the whole
image and partition table
```
$ ./build.sh erase-flash
$ ./build.sh
```
Afterwards you can force-build like this which flashes both OTA
partitions with the new imahe
```
$ ./build.sh f
```
After you have changed `./build.sh` to your own OTA keys and upload path, and adapted the
policy to look at your firmware server, you will typically build via uploading to that,
which resets the board so it can find and install the update and reboot
```
$ ./build.sh u
```

View File

@ -0,0 +1,53 @@
cmake_minimum_required(VERSION 3.5)
if (ESP_PLATFORM)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lws-minimal-esp32 C)
enable_testing()
target_link_libraries(lws-minimal-esp32.elf websockets)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_STRUCT_JSON "With lws_struct JSON" ON)
set(LWS_WITH_STRUCT_JSON ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
option(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY "Static policy" OFF)
set(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY OFF)
option(LWS_WITH_TLS_JIT_TRUST "With JIT Trust" ON)
set(LWS_WITH_TLS_JIT_TRUST ON)
option(LWS_WITH_COMPRESSED_BACKTRACES "Build with support for compressed backtraces" ON)
set(LWS_WITH_COMPRESSED_BACKTRACES ON)
set(LWS_COMPRESSED_BACKTRACES_SNIP_PRE 2 CACHE STRING "Amount of callstack to snip from top" FORCE)
set(LWS_COMPRESSED_BACKTRACES_SNIP_POST 2 CACHE STRING "Amount of callstack to snip from bottom" FORCE)
option(LWS_WITH_ALLOC_METADATA_LWS "Build lws_*alloc() with compressed backtraces (requires WITH_COMPRESSED_BACKTRACES)" OFF)
set(LWS_WITH_ALLOC_METADATA_LWS OFF)
option(LWS_WITH_OTA "Build with support for Over The Air update download and validation" ON)
set(LWS_WITH_OTA ON)
set(LWS_OTA_VARIANT "esp32-heltec-128-64" CACHE STRING "Build variant for OTA filtering" FORCE)
set(LWS_OTA_PUBLIC_JWK_FILE "$ENV{HOME}/.lws_ota/libwebsockets.org-ota-v1.public.jwk" CACHE STRING "JWK path" FORCE)
set(CMAKE_BUILD_TYPE RELEASE)
add_subdirectory(libwebsockets)
add_test(NAME flashing COMMAND idf.py flash)
set_tests_properties(flashing PROPERTIES
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 120)
add_test(NAME boot COMMAND /usr/local/bin/sai-expect)
set_tests_properties(boot PROPERTIES
DEPENDS flashing
TIMEOUT 60)
endif()

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,8 @@
idf_component_register(SRCS
../../main.c
../../lhp-ss.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)
include_directories(../build/libwebsockets)

View File

@ -0,0 +1,307 @@
/*
* devices for ESP32 Heltec + 128x64 OLED
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include "../../main.h"
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
lws_settings_instance_t *si;
const char *carousel_urls[] = {
"https://libwebsockets.org/lhp-tests/t4-320.html",
"https://libwebsockets.org/lhp-tests/t1-320.html",
"https://libwebsockets.org/lhp-tests/t2-320.html",
};
static const uint8_t fira_c_r_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular10.mcufont.h"
};
static const uint8_t fira_c_r_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular12.mcufont.h"
};
static const uint8_t fira_c_r_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular14.mcufont.h"
};
static const uint8_t fira_c_r_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular16.mcufont.h"
};
static const uint8_t fira_c_r_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular20.mcufont.h"
};
static const uint8_t fira_c_r_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular24.mcufont.h"
};
static const uint8_t fira_c_r_32[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular32.mcufont.h"
};
static const uint8_t fira_c_b_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold10.mcufont.h"
};
static const uint8_t fira_c_b_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold12.mcufont.h"
};
static const uint8_t fira_c_b_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold14.mcufont.h"
};
static const uint8_t fira_c_b_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold16.mcufont.h"
};
static const uint8_t fira_c_b_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold20.mcufont.h"
};
static const uint8_t fira_c_b_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold24.mcufont.h"
};
static const uint8_t splash_jpg[] = {
#include "splash-128-64.jpg.h"
};
static const lws_dlo_filesystem_t fs_splash = {
.name = "splash.jpg",
.data = &splash_jpg,
.len = sizeof(splash_jpg)
};
static void
esp32_i2c_delay(void)
{
volatile int n = 0;
while (n < 2)
n++;
}
static const lws_bb_i2c_t li2c = {
.bb_ops = lws_bb_i2c_ops,
.scl = GPIO_NUM_15,
.sda = GPIO_NUM_4,
.gpio = &lws_gpio_plat,
.delay = esp32_i2c_delay
};
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_0,
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_25, .index = 0, .active_level = 1 }
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_25,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* I2C display
*/
static const lws_display_colour_t palette[] = {
PALETTE_RGBY(0, 0, 0), /* black */
PALETTE_RGBY(255, 255, 255), /* white */
};
const lws_display_ssd1306_t disp = {
.disp = {
lws_display_ssd1306_ops,
.ic = {
.wh_px = { { 128,0 }, { 64,0 } },
.wh_mm = { { 22,00000000 }, { 10,00000000 } },
.palette = palette,
.palette_depth = LWS_ARRAY_SIZE(palette),
.type = LWSSURF_PALETTE,
.greyscale = 1, /* line buffer is Y */
},
.name = "ESP HELTEC 128x64 OLED",
.latency_wake_ms = 150,
},
.cb = display_completion_cb,
.i2c = (lws_i2c_ops_t *)&li2c,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_16,
.i2c7_address = SSD1306_I2C7_ADS1,
};
/*
* Settings stored in platform nv
*/
static const lws_settings_ops_t sett = {
lws_settings_ops_plat
};
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *cx)
{
lws_netdevs_t *netdevs = lws_netdevs_from_ctx(cx);
si = lws_settings_init(&sett, (void *)"nvs");
if (!si) {
lwsl_err("%s: failed to create settings instance\n", __func__);
return 1;
}
netdevs->si = si;
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
lws_font_register(cx, fira_c_r_10, sizeof(fira_c_r_10));
lws_font_register(cx, fira_c_r_12, sizeof(fira_c_r_12));
lws_font_register(cx, fira_c_r_14, sizeof(fira_c_r_14));
lws_font_register(cx, fira_c_r_16, sizeof(fira_c_r_16));
lws_font_register(cx, fira_c_r_20, sizeof(fira_c_r_20));
lws_font_register(cx, fira_c_r_24, sizeof(fira_c_r_24));
lws_font_register(cx, fira_c_r_32, sizeof(fira_c_r_32));
lws_font_register(cx, fira_c_b_10, sizeof(fira_c_b_10));
lws_font_register(cx, fira_c_b_12, sizeof(fira_c_b_12));
lws_font_register(cx, fira_c_b_14, sizeof(fira_c_b_14));
lws_font_register(cx, fira_c_b_16, sizeof(fira_c_b_16));
lws_font_register(cx, fira_c_b_20, sizeof(fira_c_b_20));
lws_font_register(cx, fira_c_b_24, sizeof(fira_c_b_24));
lws_dlo_file_register(cx, &fs_splash);
// if (lws_netdev_instance_wifi_settings_get(si, "netdev.wl0", &niw, &ac)) {
// lwsl_err("%s: unable to fetch wl0 settings\n", __func__);
// return 1;
// }
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(cx, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(cx, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
//lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, cx, 60000, 40000, lls, &disp.disp);
return 0;
}
void
show_demo_phase(int phase)
{
switch (phase) {
case LWS_LHPCD_PHASE_IDLE:
lws_led_transition(lls, "red", &lws_pwmseq_static_off,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_FETCHING:
lws_led_transition(lls, "red", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_RENDERING:
lws_led_transition(lls, "red", &lws_pwmseq_static_on,
&lws_pwmseq_linear_wipe);
break;
}
}

View File

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

View File

@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x1f0000
ota_1, app, ota_1, , 0x1f0000
nvs_key, data, nvs_keys, , 0x1000
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 ota_0, app, ota_0, 0x10000, 0x1f0000
7 ota_1, app, ota_1, , 0x1f0000
8 nvs_key, data, nvs_keys, , 0x1000

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -0,0 +1,56 @@
cmake_minimum_required(VERSION 3.5)
if (ESP_PLATFORM)
set(CMAKE_C_FLAGS "-DLWS_DISPLAY_TYPE=$ENV{LWS_DISPLAY_TYPE}" CACHE STRING x FORCE)
#message(FATAL_ERROR "ldt $ENV{LWS_DISPLAY_TYPE}")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lws-minimal-esp32 C)
enable_testing()
target_link_libraries(lws-minimal-esp32.elf websockets)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_STRUCT_JSON "With lws_struct JSON" ON)
set(LWS_WITH_STRUCT_JSON ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
option(LWS_WITH_TLS_JIT_TRUST "With JIT Trust" ON)
set(LWS_WITH_TLS_JIT_TRUST ON)
option(LWS_WITH_COMPRESSED_BACKTRACES "Build with support for compressed backtraces" ON)
set(LWS_WITH_COMPRESSED_BACKTRACES ON)
set(LWS_COMPRESSED_BACKTRACES_SNIP_PRE 2 CACHE STRING "Amount of callstack to snip from top" FORCE)
set(LWS_COMPRESSED_BACKTRACES_SNIP_POST 2 CACHE STRING "Amount of callstack to snip from bottom" FORCE)
option(LWS_WITH_ALLOC_METADATA_LWS "Build lws_*alloc() with compressed backtraces (requires WITH_COMPRESSED_BACKTRACES)" OFF)
set(LWS_WITH_ALLOC_METADATA_LWS OFF)
option(LWS_WITH_OTA "Build with support for Over The Air update download and validation" ON)
set(LWS_WITH_OTA ON)
set(LWS_OTA_VARIANT "esp32-waveshare-104-212" CACHE STRING "Build variant for OTA filtering" FORCE)
set(LWS_OTA_PUBLIC_JWK_FILE "$ENV{HOME}/.lws_ota/libwebsockets.org-ota-v1.public.jwk" CACHE STRING "JWK path" FORCE)
set(CMAKE_BUILD_TYPE RELEASE)
add_subdirectory(libwebsockets)
add_test(NAME flashing COMMAND idf.py flash)
set_tests_properties(flashing PROPERTIES
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 120)
add_test(NAME boot COMMAND /usr/local/bin/sai-expect)
set_tests_properties(boot PROPERTIES
DEPENDS flashing
TIMEOUT 60)
endif()

View File

@ -0,0 +1,38 @@
#!/bin/sh
USBPORT="/dev/serial/by-path/pci-0000:00:14.0-usb-0:8.4.2.3.4:1.0-port0"
idf.py build
if [ $? -ne 0 ] ; then
exit 1;
fi
#
# (no arg) flash from scratch
# u Upload to repo and reboot
# f Force update into both OTA and reboot
#
if [ -z "$1" ] ; then
idf.py -p $USBPORT build flash
fi
if [ "$1" == "p" ] ; then
idf.py -p $USBPORT partition-table-flash
fi
if [ "$1" == "u" ] ; then
../../../../contrib/lws_ota-manifest.sh \
build/lws-minimal-esp32.bin \
../../../../libwebsockets.org-ota-v1.private.jwk \
"libwebsockets.org:/var/www/libwebsockets.org/firmware/examples/"
fi
if [ "$1" == "f" ] ; then
parttool.py --baud 921600 --port $USBPORT -f partitions.csv write_partition --partition-name=ota_0 --input build/lws-minimal-esp32.bin
parttool.py --baud 921600 --port $USBPORT -f partitions.csv write_partition --partition-name=ota_1 --input build/lws-minimal-esp32.bin
fi
idf.py -p $USBPORT monitor

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,8 @@
idf_component_register(SRCS
../../main.c
../../lhp-ss.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)
include_directories(../build/libwebsockets)

View File

@ -0,0 +1,318 @@
/*
* devices for Waveshare ESP32 dev board + 104 x 212 4-gray EPD
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include "../../main.h"
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
lws_settings_instance_t *si;
const char *carousel_urls[] = {
"https://libwebsockets.org/lhp-tests/t4.html",
"https://libwebsockets.org/lhp-tests/t1.html",
"https://libwebsockets.org/lhp-tests/t2.html",
NULL
};
static const uint8_t fira_c_r_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular10.mcufont.h"
};
static const uint8_t fira_c_r_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular12.mcufont.h"
};
static const uint8_t fira_c_r_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular14.mcufont.h"
};
static const uint8_t fira_c_r_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular16.mcufont.h"
};
static const uint8_t fira_c_r_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular20.mcufont.h"
};
static const uint8_t fira_c_r_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular24.mcufont.h"
};
static const uint8_t fira_c_r_32[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular32.mcufont.h"
};
static const uint8_t fira_c_b_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold10.mcufont.h"
};
static const uint8_t fira_c_b_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold12.mcufont.h"
};
static const uint8_t fira_c_b_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold14.mcufont.h"
};
static const uint8_t fira_c_b_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold16.mcufont.h"
};
static const uint8_t fira_c_b_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold20.mcufont.h"
};
static const uint8_t fira_c_b_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold24.mcufont.h"
};
static const uint8_t splash_jpg[] = {
#include "splash-212-104.jpg.h"
};
static const lws_dlo_filesystem_t fs_splash = {
.name = "splash.jpg",
.data = &splash_jpg,
.len = sizeof(splash_jpg)
};
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_0, /* "BOOT" button */
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_2, .index = 0, .active_level = 1 },
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_2,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
// lws_bb_spi_ops,
lws_esp32_spi_ops,
.spi_clk_hz = 8000000,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_13,
.ncs = { GPIO_NUM_15 },
.ncmd = { GPIO_NUM_27 },
.mosi = GPIO_NUM_14,
.miso = GPIO_NUM_16,
.unit = 1,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI Electrophoretic Display
* Waveshare 104 x 212 2-level
* Ultrachip SSD1675B
*/
static const lws_display_colour_t palette[] = {
PALETTE_RGBY(0, 0, 0), /* black */
PALETTE_RGBY(255, 255, 255), /* white */
};
const lws_display_uc8176_spi_t disp = {
.disp = {
lws_display_uc8176_ops,
.ic = {
.wh_px = { { 104,0 }, { 212,0 } },
.wh_mm = { { 23,7000000 }, { 48,5500000 } },
.palette = palette,
.palette_depth = LWS_ARRAY_SIZE(palette),
.type = LWSSURF_PALETTE,
.greyscale = 1, /* line buffer is Y */
.partial = 1, /* capable of partial */
},
.name = "EPD: 104x212 mono",
.latency_wake_ms = 50,
},
.cb = display_completion_cb,
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_26,
.busy_gpio = GPIO_NUM_25,
.spi_index = 0,
};
/*
* Settings stored in platform nv
*/
static const lws_settings_ops_t sett = {
lws_settings_ops_plat
};
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *cx)
{
lws_netdevs_t *netdevs = lws_netdevs_from_ctx(cx);
si = lws_settings_init(&sett, (void *)"nvs");
if (!si) {
lwsl_err("%s: failed to create settings instance\n", __func__);
return 1;
}
netdevs->si = si;
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
lws_font_register(cx, fira_c_r_10, sizeof(fira_c_r_10));
lws_font_register(cx, fira_c_r_12, sizeof(fira_c_r_12));
lws_font_register(cx, fira_c_r_14, sizeof(fira_c_r_14));
lws_font_register(cx, fira_c_r_16, sizeof(fira_c_r_16));
lws_font_register(cx, fira_c_r_20, sizeof(fira_c_r_20));
lws_font_register(cx, fira_c_r_24, sizeof(fira_c_r_24));
lws_font_register(cx, fira_c_r_32, sizeof(fira_c_r_32));
lws_font_register(cx, fira_c_b_10, sizeof(fira_c_b_10));
lws_font_register(cx, fira_c_b_12, sizeof(fira_c_b_12));
lws_font_register(cx, fira_c_b_14, sizeof(fira_c_b_14));
lws_font_register(cx, fira_c_b_16, sizeof(fira_c_b_16));
lws_font_register(cx, fira_c_b_20, sizeof(fira_c_b_20));
lws_font_register(cx, fira_c_b_24, sizeof(fira_c_b_24));
lws_dlo_file_register(cx, &fs_splash);
// if (lws_netdev_instance_wifi_settings_get(si, "netdev.wl0", &niw, &ac)) {
// lwsl_err("%s: unable to fetch wl0 settings\n", __func__);
// return 1;
// }
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(cx, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(cx, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, cx, 30000, 10000, NULL, &disp.disp);
return 0;
}
void
show_demo_phase(int phase)
{
switch (phase) {
case LWS_LHPCD_PHASE_IDLE:
lws_led_transition(lls, "red", &lws_pwmseq_static_off,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_FETCHING:
lws_led_transition(lls, "red", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_RENDERING:
lws_led_transition(lls, "red", &lws_pwmseq_static_on,
&lws_pwmseq_linear_wipe);
break;
}
}

View File

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

View File

@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x1f0000
ota_1, app, ota_1, , 0x1f0000
nvs_key, data, nvs_keys, , 0x1000
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 ota_0, app, ota_0, 0x10000, 0x1f0000
7 ota_1, app, ota_1, , 0x1f0000
8 nvs_key, data, nvs_keys, , 0x1000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
cmake_minimum_required(VERSION 3.5)
if (ESP_PLATFORM)
set(CMAKE_C_FLAGS "-DLWS_DISPLAY_TYPE=$ENV{LWS_DISPLAY_TYPE}" CACHE STRING x FORCE)
#message(FATAL_ERROR "ldt $ENV{LWS_DISPLAY_TYPE}")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lws-minimal-esp32 C)
enable_testing()
target_link_libraries(lws-minimal-esp32.elf websockets)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_STRUCT_JSON "With lws_struct JSON" ON)
set(LWS_WITH_STRUCT_JSON ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
option(LWS_WITH_TLS_JIT_TRUST "With JIT Trust" ON)
set(LWS_WITH_TLS_JIT_TRUST ON)
option(LWS_WITH_COMPRESSED_BACKTRACES "Build with support for compressed backtraces" ON)
set(LWS_WITH_COMPRESSED_BACKTRACES ON)
set(LWS_COMPRESSED_BACKTRACES_SNIP_PRE 2 CACHE STRING "Amount of callstack to snip from top" FORCE)
set(LWS_COMPRESSED_BACKTRACES_SNIP_POST 2 CACHE STRING "Amount of callstack to snip from bottom" FORCE)
option(LWS_WITH_ALLOC_METADATA_LWS "Build lws_*alloc() with compressed backtraces (requires WITH_COMPRESSED_BACKTRACES)" OFF)
set(LWS_WITH_ALLOC_METADATA_LWS OFF)
option(LWS_WITH_OTA "Build with support for Over The Air update download and validation" ON)
set(LWS_WITH_OTA ON)
set(LWS_OTA_VARIANT "esp32-waveshare-122-250-bw" CACHE STRING "Build variant for OTA filtering" FORCE)
set(LWS_OTA_PUBLIC_JWK_FILE "$ENV{HOME}/.lws_ota/libwebsockets.org-ota-v1.public.jwk" CACHE STRING "JWK path" FORCE)
set(CMAKE_BUILD_TYPE RELEASE)
add_subdirectory(libwebsockets)
add_test(NAME flashing COMMAND idf.py flash)
set_tests_properties(flashing PROPERTIES
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 120)
add_test(NAME boot COMMAND /usr/local/bin/sai-expect)
set_tests_properties(boot PROPERTIES
DEPENDS flashing
TIMEOUT 60)
endif()

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,8 @@
idf_component_register(SRCS
../../main.c
../../lhp-ss.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)
include_directories(../build/libwebsockets)

View File

@ -0,0 +1,318 @@
/*
* devices for Waveshare ESP32 dev board + 400 x 300 4-gray EPD
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include "../../main.h"
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
lws_settings_instance_t *si;
const char *carousel_urls[] = {
"https://libwebsockets.org/lhp-tests/t4.html",
"https://libwebsockets.org/lhp-tests/t1.html",
"https://libwebsockets.org/lhp-tests/t2.html",
NULL
};
static const uint8_t fira_c_r_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular10.mcufont.h"
};
static const uint8_t fira_c_r_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular12.mcufont.h"
};
static const uint8_t fira_c_r_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular14.mcufont.h"
};
static const uint8_t fira_c_r_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular16.mcufont.h"
};
static const uint8_t fira_c_r_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular20.mcufont.h"
};
static const uint8_t fira_c_r_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular24.mcufont.h"
};
static const uint8_t fira_c_r_32[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular32.mcufont.h"
};
static const uint8_t fira_c_b_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold10.mcufont.h"
};
static const uint8_t fira_c_b_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold12.mcufont.h"
};
static const uint8_t fira_c_b_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold14.mcufont.h"
};
static const uint8_t fira_c_b_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold16.mcufont.h"
};
static const uint8_t fira_c_b_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold20.mcufont.h"
};
static const uint8_t fira_c_b_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold24.mcufont.h"
};
static const uint8_t splash_jpg[] = {
#include "splash-250-122.jpg.h"
};
static const lws_dlo_filesystem_t fs_splash = {
.name = "splash.jpg",
.data = &splash_jpg,
.len = sizeof(splash_jpg)
};
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_0, /* "BOOT" button */
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_2, .index = 0, .active_level = 1 },
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_2,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
// lws_bb_spi_ops,
lws_esp32_spi_ops,
.spi_clk_hz = 16000000,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_13,
.ncs = { GPIO_NUM_15 },
.ncmd = { GPIO_NUM_27 },
.mosi = GPIO_NUM_14,
.miso = GPIO_NUM_16,
.unit = 1,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI Electrophoretic Display
* Waveshare 250 x 122 2-level
* Ultrachip SSD1675B
*/
static const lws_display_colour_t palette[] = {
PALETTE_RGBY(0, 0, 0), /* black */
PALETTE_RGBY(255, 255, 255), /* white */
};
const lws_display_uc8176_spi_t disp = {
.disp = {
lws_display_ssd1675b_ops,
.ic = {
.wh_px = { { 122,0 }, { 250,0 } },
.wh_mm = { { 23,7000000 }, { 48,5500000 } },
.palette = palette,
.palette_depth = LWS_ARRAY_SIZE(palette),
.type = LWSSURF_PALETTE,
.greyscale = 1, /* line buffer is Y */
.partial = 1, /* capable of partial */
},
.name = "EPD: 250x122 mono",
.latency_wake_ms = 50,
},
.cb = display_completion_cb,
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_26,
.busy_gpio = GPIO_NUM_25,
.spi_index = 0,
};
/*
* Settings stored in platform nv
*/
static const lws_settings_ops_t sett = {
lws_settings_ops_plat
};
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *cx)
{
lws_netdevs_t *netdevs = lws_netdevs_from_ctx(cx);
si = lws_settings_init(&sett, (void *)"nvs");
if (!si) {
lwsl_err("%s: failed to create settings instance\n", __func__);
return 1;
}
netdevs->si = si;
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
lws_font_register(cx, fira_c_r_10, sizeof(fira_c_r_10));
lws_font_register(cx, fira_c_r_12, sizeof(fira_c_r_12));
lws_font_register(cx, fira_c_r_14, sizeof(fira_c_r_14));
lws_font_register(cx, fira_c_r_16, sizeof(fira_c_r_16));
lws_font_register(cx, fira_c_r_20, sizeof(fira_c_r_20));
lws_font_register(cx, fira_c_r_24, sizeof(fira_c_r_24));
lws_font_register(cx, fira_c_r_32, sizeof(fira_c_r_32));
lws_font_register(cx, fira_c_b_10, sizeof(fira_c_b_10));
lws_font_register(cx, fira_c_b_12, sizeof(fira_c_b_12));
lws_font_register(cx, fira_c_b_14, sizeof(fira_c_b_14));
lws_font_register(cx, fira_c_b_16, sizeof(fira_c_b_16));
lws_font_register(cx, fira_c_b_20, sizeof(fira_c_b_20));
lws_font_register(cx, fira_c_b_24, sizeof(fira_c_b_24));
lws_dlo_file_register(cx, &fs_splash);
// if (lws_netdev_instance_wifi_settings_get(si, "netdev.wl0", &niw, &ac)) {
// lwsl_err("%s: unable to fetch wl0 settings\n", __func__);
// return 1;
// }
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(cx, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(cx, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, cx, 30000, 10000, NULL, &disp.disp);
return 0;
}
void
show_demo_phase(int phase)
{
switch (phase) {
case LWS_LHPCD_PHASE_IDLE:
lws_led_transition(lls, "red", &lws_pwmseq_static_off,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_FETCHING:
lws_led_transition(lls, "red", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_RENDERING:
lws_led_transition(lls, "red", &lws_pwmseq_static_on,
&lws_pwmseq_linear_wipe);
break;
}
}

View File

@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x1f0000
ota_1, app, ota_1, , 0x1f0000
nvs_key, data, nvs_keys, , 0x1000
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 ota_0, app, ota_0, 0x10000, 0x1f0000
7 ota_1, app, ota_1, , 0x1f0000
8 nvs_key, data, nvs_keys, , 0x1000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
cmake_minimum_required(VERSION 3.5)
if (ESP_PLATFORM)
set(CMAKE_C_FLAGS "-DLWS_DISPLAY_TYPE=$ENV{LWS_DISPLAY_TYPE}" CACHE STRING x FORCE)
#message(FATAL_ERROR "ldt $ENV{LWS_DISPLAY_TYPE}")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lws-minimal-esp32 C)
enable_testing()
target_link_libraries(lws-minimal-esp32.elf websockets)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_STRUCT_JSON "With lws_struct JSON" ON)
set(LWS_WITH_STRUCT_JSON ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
option(LWS_WITH_TLS_JIT_TRUST "With JIT Trust" ON)
set(LWS_WITH_TLS_JIT_TRUST ON)
option(LWS_WITH_COMPRESSED_BACKTRACES "Build with support for compressed backtraces" ON)
set(LWS_WITH_COMPRESSED_BACKTRACES ON)
set(LWS_COMPRESSED_BACKTRACES_SNIP_PRE 2 CACHE STRING "Amount of callstack to snip from top" FORCE)
set(LWS_COMPRESSED_BACKTRACES_SNIP_POST 2 CACHE STRING "Amount of callstack to snip from bottom" FORCE)
option(LWS_WITH_ALLOC_METADATA_LWS "Build lws_*alloc() with compressed backtraces (requires WITH_COMPRESSED_BACKTRACES)" OFF)
set(LWS_WITH_ALLOC_METADATA_LWS OFF)
option(LWS_WITH_OTA "Build with support for Over The Air update download and validation" ON)
set(LWS_WITH_OTA ON)
set(LWS_OTA_VARIANT "esp32-waveshare-400-300-4gray" CACHE STRING "Build variant for OTA filtering" FORCE)
option(LWS_WITH_SUL_DEBUGGING "Sul debugging" OFF)
set(LWS_WITH_SUL_DEBUGGING OFF)
set(CMAKE_BUILD_TYPE RELEASE)
add_subdirectory(libwebsockets)
add_test(NAME flashing COMMAND idf.py flash)
set_tests_properties(flashing PROPERTIES
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 120)
add_test(NAME boot COMMAND /usr/local/bin/sai-expect)
set_tests_properties(boot PROPERTIES
DEPENDS flashing
TIMEOUT 60)
endif()

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,8 @@
idf_component_register(SRCS
../../main.c
../../lhp-ss.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)
include_directories(../build/libwebsockets)

View File

@ -0,0 +1,322 @@
/*
* devices for Waveshare ESP32 dev board + 400 x 300 4-gray EPD
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include "../../main.h"
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
lws_settings_instance_t *si;
const char *carousel_urls[] = {
"https://libwebsockets.org/lhp-tests/t4.html",
"https://libwebsockets.org/lhp-tests/t1.html",
"https://libwebsockets.org/lhp-tests/t2.html",
};
static const uint8_t fira_c_r_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular10.mcufont.h"
};
static const uint8_t fira_c_r_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular12.mcufont.h"
};
static const uint8_t fira_c_r_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular14.mcufont.h"
};
static const uint8_t fira_c_r_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular16.mcufont.h"
};
static const uint8_t fira_c_r_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular20.mcufont.h"
};
static const uint8_t fira_c_r_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular24.mcufont.h"
};
static const uint8_t fira_c_r_32[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular32.mcufont.h"
};
static const uint8_t fira_c_b_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold10.mcufont.h"
};
static const uint8_t fira_c_b_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold12.mcufont.h"
};
static const uint8_t fira_c_b_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold14.mcufont.h"
};
static const uint8_t fira_c_b_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold16.mcufont.h"
};
static const uint8_t fira_c_b_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold20.mcufont.h"
};
static const uint8_t fira_c_b_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold24.mcufont.h"
};
static const uint8_t splash_jpg[] = {
#include "splash-400-300.jpg.h"
};
static const lws_dlo_filesystem_t fs_splash = {
.name = "splash.jpg",
.data = &splash_jpg,
.len = sizeof(splash_jpg)
};
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_0, /* "BOOT" button */
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_2, .index = 0, .active_level = 1 },
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_2,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
// lws_bb_spi_ops,
lws_esp32_spi_ops,
.spi_clk_hz = 16000000,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_13,
.ncs = { GPIO_NUM_15 },
.ncmd = { GPIO_NUM_27 },
.mosi = GPIO_NUM_14,
.miso = GPIO_NUM_16,
.unit = 1,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI 4-grey Electrophoretic Display
* Waveshare 400 x 300 4-level
* Ultrachip UC8176
*
* Disordered intermediate grays are the mapping on the UC8176
*/
static const lws_display_colour_t palette[] = {
PALETTE_RGBY(0, 0, 0), /* black */
PALETTE_RGBY(170, 170, 170), /* grey2 */
PALETTE_RGBY(85, 85, 85), /* grey1 */
PALETTE_RGBY(255, 255, 255), /* white */
};
const lws_display_uc8176_spi_t disp = {
.disp = {
lws_display_uc8176_ops,
.ic = {
.wh_px = { { 400,0 }, { 300,0 } },
.wh_mm = { { 84,8000000 }, { 63,6000000 } },
.palette = palette,
.palette_depth = LWS_ARRAY_SIZE(palette),
.type = LWSSURF_PALETTE,
.greyscale = 1, /* line buffer is Y */
.partial = 1, /* capable of partial */
},
.name = "EPD: 400x300 4-gray",
.latency_wake_ms = 50,
.latency_update_ms = 1500,
},
.cb = display_completion_cb,
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_26,
.busy_gpio = GPIO_NUM_25,
.spi_index = 0,
};
/*
* Settings stored in platform nv
*/
static const lws_settings_ops_t sett = {
lws_settings_ops_plat
};
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *cx)
{
lws_netdevs_t *netdevs = lws_netdevs_from_ctx(cx);
si = lws_settings_init(&sett, (void *)"nvs");
if (!si) {
lwsl_err("%s: failed to create settings instance\n", __func__);
return 1;
}
netdevs->si = si;
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
lws_font_register(cx, fira_c_r_10, sizeof(fira_c_r_10));
lws_font_register(cx, fira_c_r_12, sizeof(fira_c_r_12));
lws_font_register(cx, fira_c_r_14, sizeof(fira_c_r_14));
lws_font_register(cx, fira_c_r_16, sizeof(fira_c_r_16));
lws_font_register(cx, fira_c_r_20, sizeof(fira_c_r_20));
lws_font_register(cx, fira_c_r_24, sizeof(fira_c_r_24));
lws_font_register(cx, fira_c_r_32, sizeof(fira_c_r_32));
lws_font_register(cx, fira_c_b_10, sizeof(fira_c_b_10));
lws_font_register(cx, fira_c_b_12, sizeof(fira_c_b_12));
lws_font_register(cx, fira_c_b_14, sizeof(fira_c_b_14));
lws_font_register(cx, fira_c_b_16, sizeof(fira_c_b_16));
lws_font_register(cx, fira_c_b_20, sizeof(fira_c_b_20));
lws_font_register(cx, fira_c_b_24, sizeof(fira_c_b_24));
lws_dlo_file_register(cx, &fs_splash);
// if (lws_netdev_instance_wifi_settings_get(si, "netdev.wl0", &niw, &ac)) {
// lwsl_err("%s: unable to fetch wl0 settings\n", __func__);
// return 1;
// }
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(cx, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(cx, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, cx, 30000, 10000, NULL, &disp.disp);
return 0;
}
void
show_demo_phase(int phase)
{
switch (phase) {
case LWS_LHPCD_PHASE_IDLE:
lws_led_transition(lls, "red", &lws_pwmseq_static_off,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_FETCHING:
lws_led_transition(lls, "red", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_RENDERING:
lws_led_transition(lls, "red", &lws_pwmseq_static_on,
&lws_pwmseq_linear_wipe);
break;
}
}

View File

@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x1f0000
ota_1, app, ota_1, , 0x1f0000
nvs_key, data, nvs_keys, , 0x1000
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 ota_0, app, ota_0, 0x10000, 0x1f0000
7 ota_1, app, ota_1, , 0x1f0000
8 nvs_key, data, nvs_keys, , 0x1000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
cmake_minimum_required(VERSION 3.5)
if (ESP_PLATFORM)
set(CMAKE_C_FLAGS "-DLWS_DISPLAY_TYPE=$ENV{LWS_DISPLAY_TYPE}" CACHE STRING x FORCE)
#message(FATAL_ERROR "ldt $ENV{LWS_DISPLAY_TYPE}")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lws-minimal-esp32 C)
enable_testing()
target_link_libraries(lws-minimal-esp32.elf websockets)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_STRUCT_JSON "With lws_struct JSON" ON)
set(LWS_WITH_STRUCT_JSON ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
option(LWS_WITH_TLS_JIT_TRUST "With JIT Trust" ON)
set(LWS_WITH_TLS_JIT_TRUST ON)
option(LWS_WITH_COMPRESSED_BACKTRACES "Build with support for compressed backtraces" ON)
set(LWS_WITH_COMPRESSED_BACKTRACES ON)
set(LWS_COMPRESSED_BACKTRACES_SNIP_PRE 2 CACHE STRING "Amount of callstack to snip from top" FORCE)
set(LWS_COMPRESSED_BACKTRACES_SNIP_POST 2 CACHE STRING "Amount of callstack to snip from bottom" FORCE)
option(LWS_WITH_ALLOC_METADATA_LWS "Build lws_*alloc() with compressed backtraces (requires WITH_COMPRESSED_BACKTRACES)" OFF)
set(LWS_WITH_ALLOC_METADATA_LWS OFF)
option(LWS_WITH_OTA "Build with support for Over The Air update download and validation" ON)
set(LWS_WITH_OTA ON)
set(LWS_OTA_VARIANT "esp32-waveshare-600-448-7col" CACHE STRING "Build variant for OTA filtering" FORCE)
set(LWS_OTA_PUBLIC_JWK_FILE "$ENV{HOME}/.lws_ota/libwebsockets.org-ota-v1.public.jwk" CACHE STRING "JWK path" FORCE)
set(CMAKE_BUILD_TYPE RELEASE)
add_subdirectory(libwebsockets)
add_test(NAME flashing COMMAND idf.py flash)
set_tests_properties(flashing PROPERTIES
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 120)
add_test(NAME boot COMMAND /usr/local/bin/sai-expect)
set_tests_properties(boot PROPERTIES
DEPENDS flashing
TIMEOUT 60)
endif()

View File

@ -0,0 +1,33 @@
#!/bin/sh
USBPORT="/dev/serial/by-path/pci-0000:00:14.0-usb-0:8.4.2.3.1:1.0-port0"
idf.py build
if [ $? -ne 0 ] ; then
exit 1;
fi
#
# (no arg) flash from scratch
# u Upload to repo and reboot
# f Force update into both OTA and reboot
#
if [ -z "$1" ] ; then
idf.py -p $USBPORT build flash
fi
if [ "$1" == "u" ] ; then
../../../../contrib/lws_ota-manifest.sh \
build/lws-minimal-esp32.bin \
../../../../libwebsockets.org-ota-v1.private.jwk \
"libwebsockets.org:/var/www/libwebsockets.org/firmware/examples/"
fi
if [ "$1" == "f" ] ; then
parttool.py --baud 921600 --port $USBPORT -f partitions.csv write_partition --partition-name=ota_0 --input build/lws-minimal-esp32.bin
parttool.py --baud 921600 --port $USBPORT -f partitions.csv write_partition --partition-name=ota_1 --input build/lws-minimal-esp32.bin
fi
idf.py -p $USBPORT monitor

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,8 @@
idf_component_register(SRCS
../../main.c
../../lhp-ss.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)
include_directories(../build/libwebsockets)

View File

@ -0,0 +1,324 @@
/*
* devices for ESP32 Waveshare board + 600 x 448 7-colour ACEP EPD display
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include "../../main.h"
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
lws_settings_instance_t *si;
const char *carousel_urls[] = {
"https://libwebsockets.org/lhp-tests/t4.html",
"https://libwebsockets.org/lhp-tests/t1.html",
"https://libwebsockets.org/lhp-tests/t2.html",
NULL
};
static const uint8_t fira_c_r_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular10.mcufont.h"
};
static const uint8_t fira_c_r_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular12.mcufont.h"
};
static const uint8_t fira_c_r_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular14.mcufont.h"
};
static const uint8_t fira_c_r_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular16.mcufont.h"
};
static const uint8_t fira_c_r_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular20.mcufont.h"
};
static const uint8_t fira_c_r_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular24.mcufont.h"
};
static const uint8_t fira_c_r_32[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular32.mcufont.h"
};
static const uint8_t fira_c_b_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold10.mcufont.h"
};
static const uint8_t fira_c_b_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold12.mcufont.h"
};
static const uint8_t fira_c_b_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold14.mcufont.h"
};
static const uint8_t fira_c_b_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold16.mcufont.h"
};
static const uint8_t fira_c_b_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold20.mcufont.h"
};
static const uint8_t fira_c_b_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold24.mcufont.h"
};
static const uint8_t splash_jpg[] = {
#include "splash-600-448.jpg.h"
};
static const lws_dlo_filesystem_t fs_splash = {
.name = "splash.jpg",
.data = &splash_jpg,
.len = sizeof(splash_jpg)
};
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_0, /* "BOOT" button */
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_2, .index = 0, .active_level = 1 },
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_2,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
// lws_bb_spi_ops,
lws_esp32_spi_ops,
.spi_clk_hz = 16000000,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_13,
.ncs = { GPIO_NUM_15 },
.ncmd = { GPIO_NUM_27 },
.mosi = GPIO_NUM_14,
.miso = GPIO_NUM_16,
.unit = 1,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI 7-colour Electrophoretic Display
*/
static const lws_display_colour_t palette[] = {
PALETTE_RGBY(0, 0, 0), /* black */
PALETTE_RGBY(255, 255, 255), /* white */
PALETTE_RGBY(0, 255, 0), /* green */
PALETTE_RGBY(0, 0, 255), /* blue */
PALETTE_RGBY(255, 0, 0), /* red */
PALETTE_RGBY(255, 255, 0), /* yellow */
PALETTE_RGBY(255, 127, 0), /* orange */
};
const lws_display_spd1656_spi_t disp = {
.disp = {
lws_display_spd1656_ops,
.ic = {
.wh_px = { { 600,0 }, { 448,0 } },
.wh_mm = { { 114,5000000 }, { 82,5000000 } },
.palette = palette,
.palette_depth = LWS_ARRAY_SIZE(palette),
.type = LWSSURF_PALETTE,
},
.name = "EPD: 600x448 7-colour",
.latency_wake_ms = 50,
},
.cb = display_completion_cb,
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_26,
.busy_gpio = GPIO_NUM_25,
.spi_index = 0,
};
/*
* Settings stored in platform nv
*/
static const lws_settings_ops_t sett = {
lws_settings_ops_plat
};
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *cx)
{
lws_netdevs_t *netdevs = lws_netdevs_from_ctx(cx);
si = lws_settings_init(&sett, (void *)"nvs");
if (!si) {
lwsl_err("%s: failed to create settings instance\n", __func__);
return 1;
}
netdevs->si = si;
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
lws_font_register(cx, fira_c_r_10, sizeof(fira_c_r_10));
lws_font_register(cx, fira_c_r_12, sizeof(fira_c_r_12));
lws_font_register(cx, fira_c_r_14, sizeof(fira_c_r_14));
lws_font_register(cx, fira_c_r_16, sizeof(fira_c_r_16));
lws_font_register(cx, fira_c_r_20, sizeof(fira_c_r_20));
lws_font_register(cx, fira_c_r_24, sizeof(fira_c_r_24));
lws_font_register(cx, fira_c_r_32, sizeof(fira_c_r_32));
lws_font_register(cx, fira_c_b_10, sizeof(fira_c_b_10));
lws_font_register(cx, fira_c_b_12, sizeof(fira_c_b_12));
lws_font_register(cx, fira_c_b_14, sizeof(fira_c_b_14));
lws_font_register(cx, fira_c_b_16, sizeof(fira_c_b_16));
lws_font_register(cx, fira_c_b_20, sizeof(fira_c_b_20));
lws_font_register(cx, fira_c_b_24, sizeof(fira_c_b_24));
lws_dlo_file_register(cx, &fs_splash);
// if (lws_netdev_instance_wifi_settings_get(si, "netdev.wl0", &niw, &ac)) {
// lwsl_err("%s: unable to fetch wl0 settings\n", __func__);
// return 1;
// }
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(cx, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(cx, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, cx, 30000, 10000, NULL, &disp.disp);
lws_led_transition(lls, "red", &lws_pwmseq_static_off,
&lws_pwmseq_linear_wipe);
return 0;
}
void
show_demo_phase(int phase)
{
switch (phase) {
case LWS_LHPCD_PHASE_IDLE:
lws_led_transition(lls, "red", &lws_pwmseq_static_off,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_FETCHING:
lws_led_transition(lls, "red", &lws_pwmseq_sine_endless_slow,
&lws_pwmseq_linear_wipe);
break;
case LWS_LHPCD_PHASE_RENDERING:
lws_led_transition(lls, "red", &lws_pwmseq_static_on,
&lws_pwmseq_linear_wipe);
break;
}
}

View File

@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x1f0000
ota_1, app, ota_1, , 0x1f0000
nvs_key, data, nvs_keys, , 0x1000
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 ota_0, app, ota_0, 0x10000, 0x1f0000
7 ota_1, app, ota_1, , 0x1f0000
8 nvs_key, data, nvs_keys, , 0x1000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.5)
if (ESP_PLATFORM)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lws-minimal-esp32 C)
enable_testing()
target_link_libraries(lws-minimal-esp32.elf websockets)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_STRUCT_JSON "With lws_struct JSON" ON)
set(LWS_WITH_STRUCT_JSON ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
option(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY "Static policy" OFF)
set(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY OFF)
option(LWS_WITH_TLS_JIT_TRUST "With JIT Trust" ON)
set(LWS_WITH_TLS_JIT_TRUST ON)
option(LWS_WITH_COMPRESSED_BACKTRACES "Build with support for compressed backtraces" ON)
set(LWS_WITH_COMPRESSED_BACKTRACES ON)
set(LWS_COMPRESSED_BACKTRACES_SNIP_PRE 2 CACHE STRING "Amount of callstack to snip from top" FORCE)
set(LWS_COMPRESSED_BACKTRACES_SNIP_POST 2 CACHE STRING "Amount of callstack to snip from bottom" FORCE)
option(LWS_WITH_ALLOC_METADATA_LWS "Build lws_*alloc() with compressed backtraces (requires WITH_COMPRESSED_BACKTRACES)" OFF)
set(LWS_WITH_ALLOC_METADATA_LWS OFF)
option(LWS_WITH_OTA "Build with support for Over The Air update download and validation" ON)
set(LWS_WITH_OTA ON)
set(LWS_OTA_VARIANT "esp32-wrover-kit-320-200" CACHE STRING "Build variant for OTA filtering" FORCE)
set(CMAKE_BUILD_TYPE RELEASE)
add_subdirectory(libwebsockets)
add_test(NAME flashing COMMAND idf.py flash)
set_tests_properties(flashing PROPERTIES
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 120)
add_test(NAME boot COMMAND /usr/local/bin/sai-expect)
set_tests_properties(boot PROPERTIES
DEPENDS flashing
TIMEOUT 60)
endif()

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,8 @@
idf_component_register(SRCS
../../main.c
../../lhp-ss.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)
include_directories(../build/libwebsockets)

View File

@ -0,0 +1,337 @@
/*
* devices for ESP32 Waveshare board
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include "../../main.h"
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
lws_settings_instance_t *si;
const char *carousel_urls[] = {
"https://libwebsockets.org/lhp-tests/t4-320.html",
"https://libwebsockets.org/lhp-tests/t7.html",
"https://libwebsockets.org/lhp-tests/t1-320.html",
"https://libwebsockets.org/lhp-tests/t2-320.html",
};
static const uint8_t fira_c_r_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular10.mcufont.h"
};
static const uint8_t fira_c_r_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular12.mcufont.h"
};
static const uint8_t fira_c_r_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular14.mcufont.h"
};
static const uint8_t fira_c_r_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular16.mcufont.h"
};
static const uint8_t fira_c_r_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular20.mcufont.h"
};
static const uint8_t fira_c_r_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular24.mcufont.h"
};
static const uint8_t fira_c_r_32[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular32.mcufont.h"
};
static const uint8_t fira_c_b_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold10.mcufont.h"
};
static const uint8_t fira_c_b_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold12.mcufont.h"
};
static const uint8_t fira_c_b_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold14.mcufont.h"
};
static const uint8_t fira_c_b_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold16.mcufont.h"
};
static const uint8_t fira_c_b_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold20.mcufont.h"
};
static const uint8_t fira_c_b_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold24.mcufont.h"
};
/*
* Button controller
*
* On the WROVER KIT, it's a bit overloaded... the two buttons are reset and
* gpio0, gpio is also used for one of the RGB LEDs channels control so it's not
* really usable as a general user button.
*
* Instead we use GPIO 14 (available on J1) for a button with the other side
* of the switch connected to 0V.
*/
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_14,
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_2, .index = 0, .active_level = 1 },
{ .gpio = GPIO_NUM_0, .index = 1, .active_level = 1 },
{ .gpio = GPIO_NUM_4, .index = 2, .active_level = 1 },
{ .gpio = GPIO_NUM_5, .index = 3, .active_level = 0 }
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_2,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "green",
.gpio = GPIO_NUM_0,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "blue",
.gpio = GPIO_NUM_4,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
{
.name = "backlight",
.gpio = GPIO_NUM_5,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 0,
/*
* The wrover kit uses a 2 NPN in series to drive the backlight
* which means if the GPIO provides no current, the backlight is
* full-on. This causes a white flash during boot... they mark
* the first stage with "Modify In ESP-WROVER-KIT!" on the
* schematics but on Kit v4.1, it's still like that.
*/
}
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
// lws_bb_spi_ops,
lws_esp32_spi_ops,
.spi_clk_hz = 40000000,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_19,
.ncs = { GPIO_NUM_22 },
.ncmd = { GPIO_NUM_21 },
.mosi = GPIO_NUM_23,
.miso = GPIO_NUM_25,
.unit = 1,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI display
*/
const lws_display_ili9341_t disp = {
.disp = {
lws_display_ili9341_ops,
.bl_pwm_ops = &pwm_ops,
.bl_active = &lws_pwmseq_static_on,
.bl_dim = &lws_pwmseq_static_half,
.bl_transition = &lws_pwmseq_linear_wipe,
.bl_index = 3,
/*
* On the Kaluga dev board, backlight is stuck on in hardware...
*/
.ic = {
.wh_px = { { 320,0 }, { 240,0 } },
.wh_mm = { { 64,00000000 }, { 48,00000000 } },
.type = LWSSURF_565
},
.name = "ESP WROVER KIT 320x240 LCD",
.latency_wake_ms = 150,
},
.cb = display_completion_cb,
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_18,
.spi_index = 0
};
/*
* Settings stored in platform nv
*/
static const lws_settings_ops_t sett = {
lws_settings_ops_plat
};
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *cx)
{
lws_netdevs_t *netdevs = lws_netdevs_from_ctx(cx);
si = lws_settings_init(&sett, (void *)"nvs");
if (!si) {
lwsl_err("%s: failed to create settings instance\n", __func__);
return 1;
}
netdevs->si = si;
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
lws_font_register(cx, fira_c_r_10, sizeof(fira_c_r_10));
lws_font_register(cx, fira_c_r_12, sizeof(fira_c_r_12));
lws_font_register(cx, fira_c_r_14, sizeof(fira_c_r_14));
lws_font_register(cx, fira_c_r_16, sizeof(fira_c_r_16));
lws_font_register(cx, fira_c_r_20, sizeof(fira_c_r_20));
lws_font_register(cx, fira_c_r_24, sizeof(fira_c_r_24));
lws_font_register(cx, fira_c_r_32, sizeof(fira_c_r_32));
lws_font_register(cx, fira_c_b_10, sizeof(fira_c_b_10));
lws_font_register(cx, fira_c_b_12, sizeof(fira_c_b_12));
lws_font_register(cx, fira_c_b_14, sizeof(fira_c_b_14));
lws_font_register(cx, fira_c_b_16, sizeof(fira_c_b_16));
lws_font_register(cx, fira_c_b_20, sizeof(fira_c_b_20));
lws_font_register(cx, fira_c_b_24, sizeof(fira_c_b_24));
// if (lws_netdev_instance_wifi_settings_get(si, "netdev.wl0", &niw, &ac)) {
// lwsl_err("%s: unable to fetch wl0 settings\n", __func__);
// return 1;
// }
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(cx, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(cx, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, cx, 60000, 40000, lls, &disp.disp);
return 0;
}
void
show_demo_phase(int phase)
{
/* switch (phase) {
case LWS_LHPCD_PHASE_IDLE:
lws_led_transition(lls, "red", &lws_pwmseq_static_half,
&lws_pwmseq_linear_wipe);
break;
}
*/
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x1f0000
ota_1, app, ota_1, , 0x1f0000
nvs_key, data, nvs_keys, , 0x1000
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 ota_0, app, ota_0, 0x10000, 0x1f0000
7 ota_1, app, ota_1, , 0x1f0000
8 nvs_key, data, nvs_keys, , 0x1000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.5)
if (ESP_PLATFORM)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(lws-minimal-esp32 C)
enable_testing()
target_link_libraries(lws-minimal-esp32.elf websockets)
option(LWS_WITH_DRIVERS "With generic drivers for gpio, i2c, display etc" ON)
set(LWS_WITH_DRIVERS ON)
option(LWS_WITH_SECURE_STREAMS "With secure streams" ON)
set(LWS_WITH_SECURE_STREAMS ON)
option(LWS_WITH_LWSAC "With lwsac" ON)
set(LWS_WITH_LWSAC ON)
option(LWS_WITH_STRUCT_JSON "With lws_struct JSON" ON)
set(LWS_WITH_STRUCT_JSON ON)
option(LWS_WITH_SYS_NTPCLIENT "With ntpclient" ON)
set(LWS_WITH_SYS_NTPCLIENT ON)
option(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY "Static policy" OFF)
set(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY OFF)
option(LWS_WITH_TLS_JIT_TRUST "With JIT Trust" ON)
set(LWS_WITH_TLS_JIT_TRUST ON)
option(LWS_WITH_COMPRESSED_BACKTRACES "Build with support for compressed backtraces" ON)
set(LWS_WITH_COMPRESSED_BACKTRACES ON)
set(LWS_COMPRESSED_BACKTRACES_SNIP_PRE 2 CACHE STRING "Amount of callstack to snip from top" FORCE)
set(LWS_COMPRESSED_BACKTRACES_SNIP_POST 2 CACHE STRING "Amount of callstack to snip from bottom" FORCE)
option(LWS_WITH_ALLOC_METADATA_LWS "Build lws_*alloc() with compressed backtraces (requires WITH_COMPRESSED_BACKTRACES)" OFF)
set(LWS_WITH_ALLOC_METADATA_LWS OFF)
option(LWS_WITH_OTA "Build with support for Over The Air update download and validation" ON)
set(LWS_WITH_OTA ON)
set(LWS_OTA_VARIANT "esp32s2-kaluga-320-200" CACHE STRING "Build variant for OTA filtering" FORCE)
set(CMAKE_BUILD_TYPE RELEASE)
add_subdirectory(libwebsockets)
add_test(NAME flashing COMMAND idf.py flash)
set_tests_properties(flashing PROPERTIES
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
TIMEOUT 120)
add_test(NAME boot COMMAND /usr/local/bin/sai-expect)
set_tests_properties(boot PROPERTIES
DEPENDS flashing
TIMEOUT 60)
endif()

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,8 @@
idf_component_register(SRCS
../../main.c
../../lhp-ss.c
devices.c
INCLUDE_DIRS "../libwebsockets/include;${IDF_PATH}/components/spi_flash/include;${IDF_PATH}/components/nvs_flash/include;${IDF_PATH}/components/mdns/include")
target_link_libraries(${COMPONENT_LIB} websockets)
include_directories(../build/libwebsockets)

View File

@ -0,0 +1,313 @@
/*
* devices for ESP32 Waveshare board
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#include "../../main.h"
struct lws_led_state *lls;
lws_display_state_t lds;
struct lws_button_state *bcs;
lws_netdev_instance_wifi_t *wnd;
lws_settings_instance_t *si;
static const uint8_t splash_jpg[] = {
#include "splash-320-240.jpg.h"
};
static const lws_dlo_filesystem_t fs_splash = {
.name = "splash.jpg",
.data = &splash_jpg,
.len = sizeof(splash_jpg)
};
const char *carousel_urls[] = {
"https://libwebsockets.org/lhp-tests/t4-320.html",
"https://libwebsockets.org/lhp-tests/t1-320.html",
"https://libwebsockets.org/lhp-tests/t2-320.html",
};
static const uint8_t fira_c_r_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular10.mcufont.h"
};
static const uint8_t fira_c_r_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular12.mcufont.h"
};
static const uint8_t fira_c_r_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular14.mcufont.h"
};
static const uint8_t fira_c_r_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular16.mcufont.h"
};
static const uint8_t fira_c_r_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular20.mcufont.h"
};
static const uint8_t fira_c_r_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular24.mcufont.h"
};
static const uint8_t fira_c_r_32[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Regular32.mcufont.h"
};
static const uint8_t fira_c_b_10[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold10.mcufont.h"
};
static const uint8_t fira_c_b_12[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold12.mcufont.h"
};
static const uint8_t fira_c_b_14[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold14.mcufont.h"
};
static const uint8_t fira_c_b_16[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold16.mcufont.h"
};
static const uint8_t fira_c_b_20[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold20.mcufont.h"
};
static const uint8_t fira_c_b_24[] = {
#include "../contrib/mcufont/fonts/FiraSansCondensed-Bold24.mcufont.h"
};
/*
* Button controller
*
* On the WROVER KIT, it's a bit overloaded... the two buttons are reset and
* gpio0, gpio is also used for one of the RGB LEDs channels control so it's not
* really usable as a general user button.
*
* Instead we use GPIO 14 (available on J1) for a button with the other side
* of the switch connected to 0V.
*/
static const lws_button_map_t bcm[] = {
{
.gpio = GPIO_NUM_14,
.smd_interaction_name = "user"
},
};
static const lws_button_controller_t bc = {
.smd_bc_name = "bc",
.gpio_ops = &lws_gpio_plat,
.button_map = &bcm[0],
.active_state_bitmap = 0,
.count_buttons = LWS_ARRAY_SIZE(bcm),
};
/*
* pwm controller
*/
static const lws_pwm_map_t pwm_map[] = {
{ .gpio = GPIO_NUM_45, .index = 0, .active_level = 1 },
{ .gpio = GPIO_NUM_6, .index = 1, .active_level = 0 }
};
static const lws_pwm_ops_t pwm_ops = {
lws_pwm_plat_ops,
.pwm_map = &pwm_map[0],
.count_pwm_map = LWS_ARRAY_SIZE(pwm_map)
};
/*
* led controller
*/
static const lws_led_gpio_map_t lgm[] = {
{
.name = "red",
.gpio = GPIO_NUM_45,
.pwm_ops = &pwm_ops, /* managed by pwm */
.active_level = 1,
},
};
static const lws_led_gpio_controller_t lgc = {
.led_ops = lws_led_gpio_ops,
.gpio_ops = &lws_gpio_plat,
.led_map = &lgm[0],
.count_leds = LWS_ARRAY_SIZE(lgm)
};
/*
* Bitbang SPI configuration for display
*/
static const lws_bb_spi_t lbspi = {
.bb_ops = {
// lws_bb_spi_ops,
lws_esp32_spi_ops,
.spi_clk_hz = 40000000,
.bus_mode = LWS_SPI_BUSMODE_CLK_IDLE_LOW_SAMP_RISING
},
.gpio = &lws_gpio_plat,
.clk = GPIO_NUM_15,
.ncs = { GPIO_NUM_11 },
.ncmd = { GPIO_NUM_13 },
.mosi = GPIO_NUM_9,
.miso = GPIO_NUM_8,
.unit = 1,
.flags = LWSBBSPI_FLAG_USE_NCS0 |
LWSBBSPI_FLAG_USE_NCMD0
};
/*
* SPI display
*/
const lws_display_ili9341_t disp = {
.disp = {
lws_display_ili9341_ops,
/*
* On the Kaluga dev board, backlight is stuck on in hardware...
*/
.ic = {
.wh_px = { { 320,0 }, { 240,0 } },
.wh_mm = { { 64,00000000 }, { 48,00000000 } },
.type = LWSSURF_565
},
.name = "Kaluga 320x240 LCD",
.latency_wake_ms = 150,
},
.cb = display_completion_cb,
.spi = (lws_spi_ops_t *)&lbspi,
.gpio = &lws_gpio_plat,
.reset_gpio = GPIO_NUM_16,
.spi_index = 0
};
/*
* Settings stored in platform nv
*/
static const lws_settings_ops_t sett = {
lws_settings_ops_plat
};
/*
* Wifi
*/
static const lws_netdev_ops_t wifi_ops = {
lws_netdev_wifi_plat_ops
};
int
init_plat_devices(struct lws_context *cx)
{
lws_netdevs_t *netdevs = lws_netdevs_from_ctx(cx);
si = lws_settings_init(&sett, (void *)"nvs");
if (!si) {
lwsl_err("%s: failed to create settings instance\n", __func__);
return 1;
}
netdevs->si = si;
#if 0
/*
* This is a temp hack to bootstrap the settings to contain the test
* AP ssid and passphrase for one time, so the settings can be stored
* while there's no UI atm
*/
{
lws_wifi_creds_t creds;
memset(&creds, 0, sizeof(creds));
lws_strncpy(creds.ssid, "xx", sizeof(creds.ssid));
lws_strncpy(creds.passphrase, "xxx", sizeof(creds.passphrase));
lws_dll2_add_tail(&creds.list, &netdevs->owner_creds);
if (lws_netdev_credentials_settings_set(netdevs)) {
lwsl_err("%s: failed to write bootstrap creds\n",
__func__);
return 1;
}
}
#endif
lws_font_register(cx, fira_c_r_10, sizeof(fira_c_r_10));
lws_font_register(cx, fira_c_r_12, sizeof(fira_c_r_12));
lws_font_register(cx, fira_c_r_14, sizeof(fira_c_r_14));
lws_font_register(cx, fira_c_r_16, sizeof(fira_c_r_16));
lws_font_register(cx, fira_c_r_20, sizeof(fira_c_r_20));
lws_font_register(cx, fira_c_r_24, sizeof(fira_c_r_24));
lws_font_register(cx, fira_c_r_32, sizeof(fira_c_r_32));
lws_font_register(cx, fira_c_b_10, sizeof(fira_c_b_10));
lws_font_register(cx, fira_c_b_12, sizeof(fira_c_b_12));
lws_font_register(cx, fira_c_b_14, sizeof(fira_c_b_14));
lws_font_register(cx, fira_c_b_16, sizeof(fira_c_b_16));
lws_font_register(cx, fira_c_b_20, sizeof(fira_c_b_20));
lws_font_register(cx, fira_c_b_24, sizeof(fira_c_b_24));
lws_dlo_file_register(cx, &fs_splash);
// if (lws_netdev_instance_wifi_settings_get(si, "netdev.wl0", &niw, &ac)) {
// lwsl_err("%s: unable to fetch wl0 settings\n", __func__);
// return 1;
// }
/* create the wifi network device and configure it */
wnd = (lws_netdev_instance_wifi_t *)
wifi_ops.create(cx, &wifi_ops, "wl0", NULL);
if (!wnd) {
lwsl_err("%s: failed to create wifi object\n", __func__);
return 1;
}
wnd->flags |= LNDIW_MODE_STA;
if (wifi_ops.configure(&wnd->inst, NULL)) {
lwsl_err("%s: failed to configure wifi object\n", __func__);
return 1;
}
wifi_ops.up(&wnd->inst);
/* bring up the led controller */
lls = lgc.led_ops.create(&lgc.led_ops);
if (!lls) {
lwsl_err("%s: could not create led\n", __func__);
return 1;
}
/* pwm init must go after the led controller init */
pwm_ops.init(&pwm_ops);
/* ... and the button controller */
bcs = lws_button_controller_create(cx, &bc);
if (!bcs) {
lwsl_err("%s: could not create buttons\n", __func__);
return 1;
}
lws_button_enable(bcs, 0, lws_button_get_bit(bcs, "user"));
/* ... bring up spi bb and the display */
lbspi.bb_ops.init(&lbspi.bb_ops);
lws_display_state_init(&lds, cx, 30000, 10000, NULL, &disp.disp);
return 0;
}
void
show_demo_phase(int phase)
{
/* switch (phase) {
case LWS_LHPCD_PHASE_IDLE:
lws_led_transition(lls, "red", &lws_pwmseq_static_half,
&lws_pwmseq_linear_wipe);
break;
}
*/
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x4000,
otadata, data, ota, 0xd000, 0x2000,
phy_init, data, phy, 0xf000, 0x1000,
ota_0, app, ota_0, 0x10000, 0x1f0000
ota_1, app, ota_1, , 0x1f0000
nvs_key, data, nvs_keys, , 0x1000
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x4000,
4 otadata, data, ota, 0xd000, 0x2000,
5 phy_init, data, phy, 0xf000, 0x1000,
6 ota_0, app, ota_0, 0x10000, 0x1f0000
7 ota_1, app, ota_1, , 0x1f0000
8 nvs_key, data, nvs_keys, , 0x1000

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,130 @@
/*
* devices for Waveshare ESP32 driver board
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*/
#define LWIP_PROVIDE_ERRNO 1
#define _ESP_PLATFORM_ERRNO_H_
#include "main.h"
static void
render(lws_sorted_usec_list_t *sul)
{
lws_display_render_state_t *rs = lws_container_of(sul,
lws_display_render_state_t, sul);
lws_stateful_ret_t r;
lws_box_t box;
int budget = 10;
lws_fx_set(box.x, 0, 0);
lws_fx_set(box.y, 0, 0);
if (!rs->line) {
/*
* We must finalize the ids list with the accurate dlo box info
* before starting the render, since some EPD need to keep
* copies of the pixel data for that region in order to over-
* write it later.
*/
lws_display_get_ids_boxes(rs);
rs->sp = 0;
rs->st[0].dlo = NULL;
/* allocate one line of output pixels to render into */
rs->line = malloc((size_t)rs->ic->wh_px[0].whole * (rs->ic->greyscale ? 1 : 3));
if (!rs->line) {
lwsl_err("%s: OOM\n", __func__);
/* !!! cleanup */
return;
}
rs->curr = 0;
/*
* Initialize the blitter with the dimensions of the data we
* will send.
*/
box.w = rs->ic->wh_px[0];
box.h = rs->ic->wh_px[1];
rs->lds->disp->blit(rs->lds, (uint8_t *)rs, &box, &rs->ids);
show_demo_phase(LWS_LHPCD_PHASE_RENDERING);
#if defined(LWS_WITH_ALLOC_METADATA_LWS)
_lws_alloc_metadata_dump_lws(lws_alloc_metadata_dump_stdout, NULL);
#endif
}
/* single-line blits are line data */
box.w = rs->ic->wh_px[0];
box.h.whole = 1;
while (rs->curr != rs->lowest_id_y) {
if (!budget--) {
lws_sul_schedule(rs->lds->ctx, 0, &rs->sul, render, 1);
return;
}
r = lws_display_list_render_line(rs);
if (r & LWS_SRET_YIELD)
lws_sul_schedule(rs->lds->ctx, 0, &rs->sul, render, 1);
if (r) {
if (r & LWS_SRET_WANT_INPUT) {
lws_sul_schedule(rs->lds->ctx, 0, &rs->sul, render, LWS_US_PER_MS);
return;
}
}
box.y.whole = rs->curr;
/* rs->line is a line of Y or RGB pixels, the blitter will
* convert to the panel's packed format and deal with diffusion
*/
rs->lds->disp->blit(rs->lds, (uint8_t *)rs->line, &box, &rs->ids);
rs->curr++;
}
lws_sul_cancel(sul);
lwsl_notice("%s: zero-height blit for end\n", __func__);
/* zero-height blit indicates update finished */
box.h.whole = 0;
rs->lds->disp->blit(rs->lds, (uint8_t *)rs->line, &box, &rs->ids);
free(rs->line);
rs->line = NULL;
lws_display_list_destroy(&rs->displaylist);
show_demo_phase(LWS_LHPCD_PHASE_IDLE);
}
int
init_browse(struct lws_context *cx, lws_display_render_state_t *rs,
const char *url)
{
show_demo_phase(LWS_LHPCD_PHASE_FETCHING);
lws_display_dl_init(&rs->displaylist, &lds);
rs->ic = &lds.disp->ic;
rs->lds = &lds;
rs->lds->display_busy = 1;
lws_strncpy(rs->lds->current_url, url, sizeof(rs->lds->current_url));
return lws_lhp_ss_browse(cx, rs, url, render);
}

View File

@ -0,0 +1,511 @@
/*
* main
*
* Written in 2010-2022 by Andy Green <andy@warmcat.com>
*
* This file is made available under the Creative Commons CC0 1.0
* Universal Public Domain Dedication.
*
* General main() for embedded LHP examples. Board-specific stuff like
* differences in platform / device / display availability and bringup is in
* ./main/devices.c in the individual directories.
*
* This example moves through a carousel of URLs every 10s and updates the
* display with them via LHP.
*
* These examples are currently available for a bunch of ESP32 variants... but
* there is no ESP32-specific code here.
*/
#include "main.h"
struct lws_context *cx;
static lws_dlo_filesystem_t *fs_splash_html, *fs_update_html;
static char did_splash, seen_operational, subsequent;
static int carousel, boot_step = -1, lbs, update_pc, lupc = -1;
static lws_sorted_usec_list_t sul_display_update;
static struct lws_plat_file_ops dlo_fops;
static lws_display_render_state_t rs;
static uint8_t flip;
extern const char *carousel_urls[];
#if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
#include "./static-policy.h"
#else
#include "./policy.h"
#endif
static const uint8_t jit_trust_blob[] = {
#include "./trust_blob.h"
};
static const uint8_t update_icon[] = {
#include "update-icon.png.h"
};
static const lws_dlo_filesystem_t fs_update_icon = {
.name = "update-icon.png",
.data = &update_icon,
.len = sizeof(update_icon)
};
static const char * const ui_css =
"body { font-family: sun; font-size: 12pt; background-color: #fff; }"
"h1 { font-family: sans; font-size: 32px; text-align: center; margin-bottom: 12px; color:#000; }"
".vari { font-family: sans; font-size: 20px; text-align: center; margin-bottom: 4px; color:#00f; }"
".icon { display: block; width: 96px; height: 96px; color: #000; margin-left: auto; margin-right:auto; margin-bottom: 10px }"
".bar { display: inline; width: 260px; height: 30px; color: #fff; background-color: #000; margin-left: auto; margin-right:auto; padding-left:4px; padding-right:4px; padding-top:4px; padding-bottom: 4px; margin-bottom: 48px }"
".c { display: inline-block; background-color: #ccf; width: 50%; padding-top: 1px; padding-bottom: 1px; }";
static lws_dlo_filesystem_t fs_ui_css = {
.name = "ui.css",
.data = ui_css,
};
static const lws_led_sequence_def_t *seqs[] = {
&lws_pwmseq_static_on,
&lws_pwmseq_static_off,
&lws_pwmseq_sine_endless_slow,
&lws_pwmseq_sine_endless_fast,
};
static int
jit_trust_query(struct lws_context *cx, const uint8_t *skid,
size_t skid_len, void *got_opaque)
{
const uint8_t *der = NULL;
size_t der_len = 0;
/*
* For this example, we look up SKIDs using a trust table that's
* compiled in, synchronously. Lws provides the necessary helper.
*
* DER will remain NULL if no match.
*/
lws_tls_jit_trust_blob_queury_skid(jit_trust_blob,
sizeof(jit_trust_blob), skid,
skid_len, &der, &der_len);
if (der)
lwsl_info("%s: found len %d\n", __func__, (int)der_len);
else
lwsl_info("%s: not trusted\n", __func__);
/* Once we have a result, pass it to the completion helper */
return lws_tls_jit_trust_got_cert_cb(cx, got_opaque, skid, skid_len,
der, der_len);
}
static int
do_reboot(void)
{
esp_restart();
}
static int
display_update(lws_display_state_t *lds)
{
char *p;
if (lupc == update_pc)
return 0;
lws_dlo_file_unregister(&fs_update_html);
lws_display_state_active(lds);
if (lds->display_busy)
return 0;
lwsl_err("%s\n", __func__);
/* Do modal update display instead of normal display content */
fs_update_html = malloc(sizeof(*fs_update_html) + 1024);
if (!fs_update_html)
return 0;
/* stop the carousel */
lws_sul_cancel(&sul_display_update);
memset(fs_update_html, 0, sizeof(*fs_update_html));
fs_update_html->name = "update.html";
fs_update_html->data = p = (char *)(fs_update_html + 1);
fs_update_html->len = lws_snprintf(p, 1024,
"<!doctype html><html>"
"<head><meta charset=\"utf-8\" /><link rel=\"stylesheet\" href=\"ui.css\"></head>"
"<style>.done { background-color: #fff; color: #000; width: %dpx; height: 20px; padding-top: 1px; font-size: 20pt; text-align: center }</style>"
"<body><h1>UPDATING</h1>"
"<div class=\"vari\">%s</div><br>"
"<div class=\"bar\" id=\"progress\"><div class=\"done\">%d%%</div></div>"
"<div class=\"icon\"><img src=\"file://dlofs/update-icon.png\"></div><br>"
"</body></html>",
update_pc * 3,
lws_ota_variant_name(),
update_pc);
lws_dlo_file_register(cx, fs_update_html);
//lws_display_render_add_id(&rs, "progress", NULL);
lupc = update_pc;
if (init_browse(cx, &rs, "file://dlofs/update.html"))
lwsl_err("%s: init_browse failed\n", __func__);
return 0;
}
static int
ota_progress(lws_ota_ret_t state, int percent)
{
update_pc = percent;
display_update(&lds);
return 0;
}
static lws_system_ops_t system_ops = {
.reboot = do_reboot,
.ota_ops = {
.ota_start = lws_plat_ota_start,
.ota_queue = lws_plat_ota_queue,
.ota_report_current = lws_plat_ota_report_current,
.ota_get_last_fw_unixtime = lws_plat_ota_get_last_fw_unixtime,
.ota_progress = ota_progress,
},
.jit_trust_query = jit_trust_query
};
static void
start_frame(lws_sorted_usec_list_t *sul)
{
if (lds.display_busy) {
lws_sul_schedule(cx, 0, &sul_display_update, start_frame,
LWS_US_PER_SEC);
return;
}
/* browsing / waiting / layout */
show_demo_phase(LWS_LHPCD_PHASE_FETCHING);
if (lws_system_get_state_manager(cx)->state == LWS_SYSTATE_MODAL_UPDATING)
return;
if (lws_system_get_state_manager(cx)->state == LWS_SYSTATE_AWAITING_MODAL_UPDATING) { //&&
//strcmp(lds.current_url, "file://dlofs/update.html")) {
display_update(&lds);
return;
}
if (fs_update_html)
lws_dlo_file_unregister(&fs_update_html);
lwsl_notice("%s: %s\n", __func__, carousel_urls[carousel]);
if (init_browse(cx, &rs, carousel_urls[carousel++]))
lwsl_err("%s: init_browse failed\n", __func__);
if (!carousel_urls[carousel])
carousel = 0;
}
static int
display_splash(lws_display_state_t *lds)
{
char *p, age[32], varbuf[64];
uint64_t fw = 0;
lws_dll2_t *d;
lwsl_err("%s: boot_step %d... fs_splash_html %p, choose splash.html %p\n", __func__, boot_step, fs_splash_html, lws_dlo_file_choose(cx, "splash.html"));
if (lbs == boot_step || did_splash || fs_splash_html)
return 0;
if (boot_step < 0)
boot_step = 0;
if (lds->display_busy)
return 0;
if (boot_step > LWS_SYSTATE_OPERATIONAL)
return 0;
if (boot_step == LWS_SYSTATE_OPERATIONAL)
did_splash = 1;
fs_splash_html = malloc(sizeof(*fs_splash_html) + 4096);
if (!fs_splash_html)
return 0;
lds->display_busy = 1;
memset(fs_splash_html, 0, sizeof(*fs_splash_html));
fs_splash_html->name = "splash.html";
p = (char *)(fs_splash_html + 1);
fs_splash_html->data = p;
age[0] = '\0';
if (!system_ops.ota_ops.ota_get_last_fw_unixtime(&fw)) {
struct tm lt;
time_t t = (time_t)fw;
localtime_r(&t, &lt);
strftime(age, sizeof(age), "%Y-%m-%d %H:%M:%S UTC", &lt);
} else
strcpy(age, "unknown");
strncpy(varbuf, lws_ota_variant_name(), sizeof(varbuf));
fs_splash_html->len = lws_snprintf(p, 4096,
"<!doctype html><html><head><meta charset=\"utf-8\" /><link rel=\"stylesheet\" href=\"ui.css\"></head>"
"<style>.done { background-color: #fff; color: #000; width: %dpx; height: 20px; padding-top: 1px; font-size: 20pt; text-align: center }</style>"
"<body>"
"<div class=\"c\"><h1>Booting</h1>"
"<div class=\"bar\" id=\"progress\"><div class=\"done\">%d%%</div></div>"
"%s<br>%s"
"</div>"
"<div class=\"c\">"
"<table><tr><td>RSSI</td><td>Ch</td><td>BSSID</td></tr>",
(boot_step * 250) / 13,
(boot_step * 100) / 13,
varbuf, age
// lds->disp->ic.wh_px[0].whole,
// lds->disp->ic.wh_px[1].whole,
);
d = wnd->scan.tail;
while (d) {
lws_wifi_sta_t *w = lws_container_of(d, lws_wifi_sta_t, list);
fs_splash_html->len += lws_snprintf(p + fs_splash_html->len,
4096 - fs_splash_html->len,
"<tr><td>%d</td><td>%d</td><td>%s</td></tr>",
rssi_averaged(w), w->ch, (const char *)&w[1]);
d = d->prev;
};
fs_splash_html->len += lws_snprintf(p + fs_splash_html->len, 4096 - fs_splash_html->len, "</table></div></body></html>");
lbs = boot_step;
if (!lws_dlo_file_register(cx, fs_splash_html))
lwsl_err("registering splash failed\n");
lws_display_render_free_ids(&rs);
// if (!strcmp(lds->current_url, "file://dlofs/splash.html"))
/* subsequent update... do partial */
// lws_display_render_add_id(&rs, "progress", NULL);
if (init_browse(cx, &rs, "file://dlofs/splash.html")) {
lwsl_err("%s: init_browse ended badly\n", __func__);
lws_dlo_file_unregister_by_name(cx, "splash.html");
free(fs_splash_html);
fs_splash_html = NULL;
}
if (did_splash)
lws_display_render_free_ids(&rs);
return 0;
}
int
display_completion_cb(lws_display_state_t *lds, int a)
{
lwsl_warn("%s: %d\n", __func__, a);
switch (a) {
case 1: /* display initialization finished */
if (!did_splash)
display_splash(lds);
break;
case 2: /* display update finished */
lds->display_busy = 0;
show_demo_phase(LWS_LHPCD_PHASE_IDLE);
if (fs_splash_html) {
lws_dlo_file_unregister_by_name(cx, fs_splash_html->name);
free(fs_splash_html);
fs_splash_html = NULL;
lws_display_state_active(lds);
}
if (!did_splash) {
display_splash(lds);
return 0;
}
/* trigger doing the next browse */
lws_sul_schedule(lds->ctx, 0, &sul_display_update, start_frame,
subsequent ? 10 * LWS_US_PER_SEC : 1);
subsequent = 1;
break;
}
return 0;
}
static int
smd_cb(void *opaque, lws_smd_class_t _class, lws_usec_t timestamp, void *buf,
size_t len)
{
if (!lws_json_simple_strcmp(buf, len, "\"src\":", "bc/user") &&
!lws_json_simple_strcmp(buf, len, "\"event\":", "click")) {
lws_led_transition(lls, "blue", seqs[flip & 3],
&lws_pwmseq_linear_wipe);
flip++;
}
lwsl_hexdump_notice(buf, len);
if (_class & LWSSMDCL_INTERACTION)
/*
* Any kind of user interaction brings the display back up and
* resets the dimming / blanking timers
*/
lws_display_state_active(&lds);
return 0;
}
static int
system_notify_cb(lws_state_manager_t *mgr, lws_state_notify_link_t *link,
int current, int target)
{
if (current == LWS_SYSTATE_OPERATIONAL &&
target == LWS_SYSTATE_OPERATIONAL)
seen_operational = 1;
if (current == target) {
boot_step = current;
if (!strcmp(lds.current_url, "file://dlofs/splash.html"))
display_splash(&lds);
}
if (current != LWS_SYSTATE_MODAL_UPDATING &&
target == LWS_SYSTATE_MODAL_UPDATING) {
/* do we feel like we should okay the transition to
* MODAL_UPDATING? Or are we busy using heap right now?
*/
if (strcmp(lds.current_url, "file://dlofs/update.html")) {
/* did not start showing the modal update display yet */
lws_sul_schedule(cx, 0, &sul_display_update, start_frame, 1);
return 1;
}
if (lds.display_busy)
/* still updating display / using heap for that */
return 1;
/*
* We are showing the update display, and we're not busy
* updating the display any more... at least we don't have any
* objection now to the transition
*/
return 0;
}
return 0;
}
void
app_main(void)
{
struct lws_context_creation_info *info;
lws_state_notify_link_t notifier = { { NULL, NULL, NULL },
system_notify_cb, "app" };
lws_state_notify_link_t *na[] = { &notifier, NULL };
lws_set_log_level(LLL_USER | LLL_NOTICE | LLL_WARN | LLL_ERR, NULL);
lws_netdev_plat_init();
lws_netdev_plat_wifi_init();
info = malloc(sizeof(*info));
if (!info)
goto spin;
memset(info, 0, sizeof(*info));
#if 1
#if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
info->pss_policies_json = ss_policy;
#else
info->pss_policies = &_ss_static_policy_entry;
#endif
#endif
info->options = LWS_SERVER_OPTION_EXPLICIT_VHOSTS |
LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
info->port = CONTEXT_PORT_NO_LISTEN;
info->early_smd_cb = smd_cb;
info->early_smd_class_filter = LWSSMDCL_INTERACTION |
LWSSMDCL_SYSTEM_STATE |
LWSSMDCL_NETWORK;
info->smd_ttl_us = 20 * LWS_USEC_PER_SEC; /* we can spend a long time in display */
info->system_ops = &system_ops;
info->register_notifier_list = na;
cx = lws_create_context(info);
if (!cx) {
lwsl_err("lws init failed\n");
goto spin;
}
/*
* We don't need this after context creation... things it pointed to
* still need to exist though since the context copied the pointers.
*/
free(info);
/*
* Make a soft copy of the dlo fops, insert it in fops chain so that
* the plat one is first, as expected by the VFS code
*/
dlo_fops = lws_dlo_fops;
dlo_fops.cx = cx;
dlo_fops.next = lws_get_fops(cx)->next; /* insert after plat */
lws_get_fops(cx)->next = &dlo_fops;
lws_dlo_file_register(cx, &fs_update_icon);
fs_ui_css.len = strlen((const char *)fs_ui_css.data);
lws_dlo_file_register(cx, &fs_ui_css);
/* devices and init are in devices.c */
if (init_plat_devices(cx))
goto spin;
show_demo_phase(LWS_LHPCD_PHASE_IDLE);
/* the lws event loop */
do {
taskYIELD();
lws_service(cx, 0);
} while (1);
lwsl_notice("%s: exited event loop\n", __func__);
spin:
vTaskDelay(10);
taskYIELD();
goto spin;
}

View File

@ -0,0 +1,35 @@
#define LWIP_PROVIDE_ERRNO 1
#define _ESP_PLATFORM_ERRNO_H_
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <driver/gpio.h>
#include <libwebsockets.h>
enum {
LWS_LHPCD_PHASE_IDLE,
LWS_LHPCD_PHASE_FETCHING,
LWS_LHPCD_PHASE_RENDERING,
};
extern struct lws_led_state *lls;
extern lws_display_state_t lds;
extern struct lws_button_state *bcs;
extern lws_netdev_instance_wifi_t *wnd;
extern struct lws_context *cx;
extern int
init_plat_devices(struct lws_context *);
extern int
display_completion_cb(lws_display_state_t *lds, int a);
extern void
show_demo_phase(int phase);
extern void
next_carousel(lws_sorted_usec_list_t *sul);
extern int
init_browse(struct lws_context *cx, lws_display_render_state_t *rs, const char *url);

View File

@ -0,0 +1,83 @@
/*
* Since we're using JIT Trust, we don't need explict CA trust for this.
*/
static const char * const ss_policy =
"{"
"\"release\":" "\"01234567\","
"\"product\":" "\"myproduct\","
"\"schema-version\":" "1,"
"\"retry\": [" /* named backoff / retry strategies */
"{\"default\": {"
"\"backoff\": [" "1000,"
"2000,"
"3000,"
"5000,"
"10000"
"],"
"\"conceal\":" "25,"
"\"jitterpc\":" "20,"
"\"svalidping\":" "30,"
"\"svalidhup\":" "35"
"}}"
"],"
"\"s\": ["
"{\"__default\": {"
"\"endpoint\":" "\"${endpoint}\","
"\"port\":" "443,"
"\"protocol\":" "\"h2\","
"\"http_method\":" "\"GET\","
"\"http_url\":" "\"\","
"\"metadata\": [{\n"
"\"endpoint\":" "\"\",\n"
"\"acc\":" "\"accept\",\n"
"\"ua\":" "\"user-agent\"\n"
"}],\n"
"\"tls\":" "true,"
"\"allow_redirects\": true,\n"
"\"nghttp2_quirk_end_stream\": true,\n"
"\"h2q_oflow_txcr\": true,\n"
"\"opportunistic\":" "true,"
"\"retry\":" "\"default\""
"}},{\"ota\": {"
"\"endpoint\":" "\"libwebsockets.org\","
"\"port\":" "443,"
"\"protocol\":" "\"h2\","
"\"http_method\":" "\"GET\","
"\"http_url\":" "\"firmware/examples/${ota_variant}/${file}\","
"\"metadata\": [{\n"
"\"ota_variant\":" "\"\",\n"
"\"file\":" "\"\"\n"
"}],\n"
"\"tls\":" "true,"
"\"allow_redirects\": true,\n"
"\"nghttp2_quirk_end_stream\": true,\n"
"\"h2q_oflow_txcr\":" "true,\n"
"\"opportunistic\":" "true,"
"\"retry\":" "\"default\""
"}},{"
/*
* "captive_portal_detect" describes
* what to do in order to check if the path to
* the Internet is being interrupted by a
* captive portal.
*/
"\"captive_portal_detect\": {"
"\"endpoint\":" "\"connectivitycheck.android.com\","
"\"http_url\":" "\"generate_204\","
"\"port\":" "80,"
"\"protocol\":" "\"h1\","
"\"http_method\":" "\"GET\","
"\"opportunistic\":" "true,"
"\"http_expect\":" "204,"
"\"http_fail_redirect\": true"
"}}"
"]}"
;

View File

@ -0,0 +1,83 @@
/*
* Autogenerated from the following JSON policy
*/
#if 0
Original JSON size: 706
#endif
static const lws_ss_metadata_t _md_default_ua = {
.name = "ua",
.value__may_own_heap = (void *)"user-agent",
.value_length = 0xa,
.length = 0,
.value_is_http_token = 0x45,
},
_md_default_acc = {
.next = (void *)&_md_default_ua,
.name = "acc",
.value__may_own_heap = (void *)"accept",
.value_length = 0x6,
.length = 1,
.value_is_http_token = 0x11,
},
_md_default_endpoint = {
.next = (void *)&_md_default_acc,
.name = "endpoint",
.value__may_own_heap = (void *)"",
.value_length = 0x0,
.length = 2,
.value_is_http_token = 0x0,
};
static const uint32_t _rbo_bo_0[] = {
1000,
};
static const lws_retry_bo_t _rbo_0 = {
.retry_ms_table = _rbo_bo_0,
.retry_ms_table_count = 1,
.conceal_count = 25,
.secs_since_valid_ping = 30,
.secs_since_valid_hangup = 35,
.jitter_percent = 20,
};
static const lws_ss_policy_t _ssp_captive_portal_detect = {
.streamtype = "captive_portal_detect",
.endpoint = "connectivitycheck.android.com",
.u = {
.http = {
.method = "GET",
.url = "generate_204",
.resp_expect = 204,
.fail_redirect = 1,
}
},
.flags = 0x1,
.priority = 0x0,
.port = 80,
.protocol = 0,
},
_ssp_default = {
.next = (void *)&_ssp_captive_portal_detect,
.streamtype = "__default",
.endpoint = "${endpoint}",
.metadata = (void *)&_md_default_endpoint,
.u = {
.http = {
.method = "GET",
.url = "",
}
},
.retry_bo = &_rbo_0,
.flags = 0x10311,
.priority = 0x0,
.port = 443,
.metadata_count = 3,
.protocol = 1,
};
#define _ss_static_policy_entry _ssp_default
/* estimated footprint 676 (when sizeof void * = 8) */

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -28,7 +28,25 @@
"server_cert":"self_localhost",
"server_key":"self_localhost_key"
}
}
},
{"ota": {
"endpoint": "libwebsockets.org",
"port": 443,
"protocol": "h2",
"http_method": "GET",
"http_url": "firmware/examples/${ota_variant}/${file}",
"metadata": [{
"ota_variant": "",
"file": ""
}],
"tls": true,
"allow_redirects": true,
"nghttp2_quirk_end_stream": true,
"h2q_oflow_txcr": true,
"opportunistic": true,
"retry": "default"
}}
]
}