next iteration on display, still some artifacting issues, and ux with buttons states and updating

This commit is contained in:
matt committed 2026-08-04 19:38:58 -07:00
1 parent 45998b6176
commit ae5d12b3a2
14 files changed
+859 -397

No files matched your search

+14 -6
View File
@@ -225,10 +225,14 @@ about PSRAM bandwidth or panel timing.
- **`lv_label_set_text()` invalidates unconditionally**, even when the text is
identical — so setting an unchanged value still forces a repaint. All label
updates go through `label_set_if_changed()`.
- **WiFi must be brought up before `display_init()`.** The bounce refill ISR
reads PSRAM, which shares the cache with flash; an NVS write while the panel
is running faults it with *"Cache disabled but cached memory region
accessed"*.
- **Display bring-up is two-phase, and both orderings are load-bearing.**
`display_alloc()` runs *before* WiFi: the bounce buffers need two contiguous
25.6KB internal DMA blocks, and WiFi's RX buffer churn fragments the heap
within seconds — observed as a boot-loop with 84KB free and no block big
enough. `display_start()` runs *after* WiFi: once scan-out begins, the
bounce refill ISR reads PSRAM, which shares the cache with flash, and an
NVS/PHY write would fault it with *"Cache disabled but cached memory region
accessed"*. Allocate early, scan late.
## Partitions
@@ -256,5 +260,9 @@ enabled (the panel cannot stream straight from PSRAM), which is exactly why
flash writes are dangerous while the panel runs: the refill ISR reads PSRAM,
which shares the cache with flash on the S3, so an NVS write faults it with
*"Cache disabled but cached memory region accessed"*. All flash writes happen
before `display_init()` and `CONFIG_ESP_WIFI_NVS_ENABLED` is off to keep the
WiFi stack from writing later.
before `display_start()` and `CONFIG_ESP_WIFI_NVS_ENABLED` is off to keep the
WiFi stack from writing later. Static buffers beware: `.bss` lives in the
same internal RAM the bounce buffers come from, with only ~33KB of slack
after the panel is up — a few KB of new static array is enough to matter
(the trend ring is deliberately time-bucketed down to ~720 bytes for this
reason).
+19 -15
View File
@@ -2,20 +2,22 @@
## Not yet verified on hardware
Flashed and booting clean (icons on, first poll ~8s, no errors), but eyes and
fingers haven't confirmed:
Flashed and booting clean (two-phase display init, icons on, first poll ~9s,
no errors), but eyes and fingers haven't confirmed:
1. Touch actually toggling a light end-to-end. Tiles are now **optimistic**:
they flip on tap immediately and hold that state up to 5s until HA
confirms (see `light_hold_t` in ui_manager.c). If a tile flips then snaps
back 5s later, the command failed — check `ha_client` on serial.
2. Whether the full-screen invalidate after each poll actually bounds the
left-edge artefacts (it repaints them away; it cannot prevent them). If
lines still persist for longer than one poll interval, that mechanism is
not working and the next lever is pausing only around LVGL's flush.
3. That the six light tiles are comfortable finger targets at ~125px, and
that sliders track the finger without jumping (poll updates skip pressed
sliders by design).
1. Slider feel: press sends one command at the touch position immediately,
drag is display-only tracking the finger, lift sends the final level.
Poll data never moves a pressed knob.
2. Trend arrows appear ~5 minutes after boot (indoor big card, outdoor and
pressure cells) once the local ring has history. They are local-history
based and reset on reboot — that is by design, not a bug.
3. Artefact lifetime: interactions schedule a one-shot full repaint 600ms
after the last touch, and every poll repaints too. Artefacts should now
visibly self-clean in under a second after touching, and within a poll
otherwise. If they *persist* beyond that, the repaint isn't reaching
them; if they merely *recur* during interaction, that is the PSRAM
bandwidth ceiling (README) and the honest remaining levers are fewer
redraws or 120MHz PSRAM on a newer IDF.
## Done
@@ -95,8 +97,10 @@ hosts the thermostat before building it twice.
- The `°` glyph exists in LVGL's built-in Montserrat fonts; the `·` separator
that does not appears only in log strings, never on screen.
- LVGL recursive-mutex locking is consistent across all UI entry points.
- Init order in `main.c` is deliberate and load-bearing: WiFi/NVS before
`display_init()`, `backlight_init()` before `touch_init()`. Never reorder.
- Init order in `main.c` is deliberate and load-bearing:
`display_alloc()` before WiFi (contiguous bounce buffers from a virgin
heap), WiFi/NVS before `display_start()` (flash writes finished before
scan-out), `backlight_init()` before `touch_init()`. Never reorder.
- The bounce buffer is enabled and load-bearing.
- Board is N16R8 (16MB flash / 8MB octal PSRAM).
- `touch_get_indev()`, `display_get_panel()` and `lvgl_port_is_paused()` are
+8 -4
View File
@@ -63,15 +63,19 @@
* put the sofa icon on the patio. Only ui_manager.c expands it; the api-layer
* consumers ignore the argument, so this header does not include ui_icons.h.
*
* Note light.main_room is a GROUP containing blue_lamp, brown_lamp and
* landing_chandelier. Toggling it changes three of the other tiles; that is
* expected, and the UI reflects it on the next poll.
* light.main_room used to be here and was removed deliberately: it is a
* GROUP of blue_lamp, brown_lamp and landing_chandelier -- three of the
* other tiles. One tap restyled four tiles at once, which both confused the
* optimistic-hold logic and triggered a redraw storm big enough to glitch
* the panel (see README on PSRAM bandwidth). Groups spanning other tiles do
* not belong in this list. light.tv_room is also a group (of 2), but of
* lights that have no tile of their own, which is fine.
*/
/* Labels must fit one line of Montserrat 16 in a ~125px tile -- roughly 11
* characters. Longer ones are truncated with an ellipsis, which reads as a
* mistake. "Dining Room" is one character too wide, hence "Dining". */
#define HA_LIGHT_LIST(X) \
X("light.main_room", "Main Room", true, ICON_SOFA) \
X("light.tv_room", "TV Room", true, ICON_TV) \
X("light.dining_room", "Dining", true, ICON_DINING) \
X("light.blue_lamp", "Blue Lamp", true, ICON_FLOOR_LAMP) \
X("light.brown_lamp", "Brown Lamp", true, ICON_DESK_LAMP) \
+114
View File
@@ -305,6 +305,120 @@ const char *ha_condition_short(const char *slug)
return (c != NULL) ? c->shrt : (slug != NULL ? slug : "--");
}
/* ------------------------------------------------------------------ trends */
/*
* 20 slots, one kept per ~4 minutes, covers ~80 minutes. Feeding faster than
* that overwrites the newest slot instead of consuming a new one, so a 60s
* poll cadence still fills the ring at 4-minute spacing.
*
* Size matters here more than it looks: this array is .bss, which lives in
* internal RAM on the S3 -- the same internal RAM the RGB panel's bounce
* buffers come from, with only a few KB of slack (README, memory notes). A
* naive 72-slot-per-poll ring cost 2.6KB and was enough to tip display_init
* into "no mem for bounce buffer" on an unlucky boot. Keep this structure
* small; if it ever needs to grow, it must move to PSRAM instead.
*
* Static per channel; a reboot forgets history, and the display shows no
* arrow until enough accumulates again (see ha_data.h).
*/
#define TREND_SLOTS 20
#define TREND_BUCKET_MS (4u * 60u * 1000u)
typedef struct {
float value;
uint32_t ms;
bool used;
} trend_sample_t;
static trend_sample_t trend_ring[HA_TREND_CHANNELS][TREND_SLOTS];
static int trend_head[HA_TREND_CHANNELS]; /* slot most recently written */
void ha_trend_feed(int channel, float value, uint32_t now_ms)
{
if (channel < 0 || channel >= HA_TREND_CHANNELS) {
return;
}
trend_sample_t *newest = &trend_ring[channel][trend_head[channel]];
/* Inside the current bucket: refresh the newest sample in place, so
* compute always sees the latest reading without spending a slot. */
if (newest->used && (now_ms - newest->ms) < TREND_BUCKET_MS) {
newest->value = value;
return;
}
const int next = newest->used ? (trend_head[channel] + 1) % TREND_SLOTS
: trend_head[channel];
trend_ring[channel][next] = (trend_sample_t){ value, now_ms, true };
trend_head[channel] = next;
}
ha_trend_t ha_trend_compute(int channel, float threshold_per_hour, uint32_t now_ms)
{
if (channel < 0 || channel >= HA_TREND_CHANNELS) {
return HA_TREND_UNKNOWN;
}
/* The newest sample is the one just fed; find the usable sample whose
* age is closest to the window. Unsigned subtraction keeps this correct
* across tick wrap. */
const trend_sample_t *newest = NULL;
const trend_sample_t *anchor = NULL;
uint32_t best_dist = UINT32_MAX;
for (int i = 0; i < TREND_SLOTS; i++) {
const trend_sample_t *s = &trend_ring[channel][i];
if (!s->used) {
continue;
}
const uint32_t age = now_ms - s->ms;
if (age > HA_TREND_WINDOW_MS + HA_TREND_MIN_AGE_MS) {
continue; /* too old even for a sparse ring; ignore */
}
if (newest == NULL || age < (now_ms - newest->ms)) {
newest = s;
}
if (age >= HA_TREND_MIN_AGE_MS) {
const uint32_t dist = (age > HA_TREND_WINDOW_MS)
? age - HA_TREND_WINDOW_MS
: HA_TREND_WINDOW_MS - age;
if (dist < best_dist) {
best_dist = dist;
anchor = s;
}
}
}
if (newest == NULL || anchor == NULL || newest == anchor) {
return HA_TREND_UNKNOWN;
}
/*
* Scale the threshold to the actual span so a 20-minute-old anchor uses
* a proportionally smaller bar than a full hour would. Without this the
* first hour after boot under-reports every trend.
*/
const uint32_t span_ms = anchor->ms == newest->ms
? 1
: newest->ms - anchor->ms;
const float threshold = threshold_per_hour *
((float)span_ms / (float)HA_TREND_WINDOW_MS);
const float delta = newest->value - anchor->value;
if (delta > threshold) {
return HA_TREND_RISING;
}
if (delta < -threshold) {
return HA_TREND_FALLING;
}
return HA_TREND_FLAT;
}
const char *ha_wind_cardinal(float degrees)
{
static const char *const points[16] = {
+46
View File
@@ -56,6 +56,27 @@ typedef struct {
bool dimmable;
} ha_light_cfg_t;
/*
* Which way a reading has moved over the last hour.
*
* UNKNOWN is deliberately 0 so a freshly wiped ha_data_t renders no arrow --
* after boot there is no history, and "no arrow" is the honest display until
* at least HA_TREND_MIN_AGE_MS of samples exist.
*/
typedef enum {
HA_TREND_UNKNOWN = 0,
HA_TREND_FLAT,
HA_TREND_RISING,
HA_TREND_FALLING,
} ha_trend_t;
enum {
HA_TREND_CH_INDOOR = 0,
HA_TREND_CH_OUTDOOR,
HA_TREND_CH_PRESSURE,
HA_TREND_CHANNELS,
};
/* Generated from HA_LIGHT_LIST; index-aligned with ha_data_t.lights. */
extern const ha_light_cfg_t HA_LIGHTS[HA_LIGHT_COUNT];
@@ -93,6 +114,16 @@ typedef struct {
ha_forecast_day_t forecast[HA_FORECAST_DAYS];
uint8_t forecast_count; /* 0 when no forecast has been fetched yet */
/*
* Filled by the CALLER after parsing, from ha_trend_feed/compute --
* the parser wipes them to UNKNOWN. Local ring-buffer history, not an HA
* query: an /api/history call returns hundreds of points per entity,
* which is silly when the device already sees every reading each poll.
*/
ha_trend_t trend_indoor;
ha_trend_t trend_outdoor;
ha_trend_t trend_pressure;
} ha_data_t;
/*
@@ -133,4 +164,19 @@ const char *ha_condition_short(const char *slug);
/* Compass point for a bearing in degrees ("NNE"). */
const char *ha_wind_cardinal(float degrees);
/*
* Trend tracking. Feed one sample per poll; compute compares the newest
* sample against the one closest to an hour old. Timestamps come from the
* caller (lv_tick_get() or xTaskGetTickCount-derived ms) so this file stays
* free of LVGL and FreeRTOS. Wrap-safe on uint32 ms.
*
* compute returns UNKNOWN until the oldest usable sample is at least
* HA_TREND_MIN_AGE_MS old -- "trending" over 90 seconds is noise.
*/
#define HA_TREND_WINDOW_MS (60u * 60u * 1000u)
#define HA_TREND_MIN_AGE_MS (5u * 60u * 1000u)
void ha_trend_feed(int channel, float value, uint32_t now_ms);
ha_trend_t ha_trend_compute(int channel, float threshold_per_hour, uint32_t now_ms);
#endif
+40 -7
View File
@@ -108,14 +108,24 @@ static void rgb_flush_cb(lv_display_t *display, const lv_area_t *area, uint8_t *
lv_display_flush_ready(display);
}
esp_err_t display_init(void)
/*
* Phase 1: allocate everything, scan nothing.
*
* Called BEFORE wifi_init_sta(), on a heap nothing else has touched. The
* bounce buffers need two contiguous 25.6KB DMA-capable internal blocks, and
* WiFi's dynamic RX buffers churn that same pool hard enough to fragment it:
* observed on hardware (2026-08-04) as "no mem for bounce buffer" with 84KB
* of total free heap -- plenty of bytes, no block big enough, and retries
* useless because the fragmentation is not transient.
*
* Allocating first is deterministic where retrying was a dice roll. The
* panel is NOT scanning after this returns -- scan-out (and with it the
* PSRAM-reading refill ISR that flash writes would fault) starts only in
* display_start().
*/
esp_err_t display_alloc(void)
{
ESP_LOGI(TAG, "Initializing 800x480 RGB panel (CrowPanel Advance)");
/* lv_display_create() below allocates from LVGL's heap. Without lv_init()
* that heap is a null pool and the call faults with LoadProhibited. */
ESP_RETURN_ON_FALSE(lv_is_initialized(), ESP_ERR_INVALID_STATE, TAG,
"lv_init() must run before display_init()");
ESP_LOGI(TAG, "Allocating 800x480 RGB panel (CrowPanel Advance)");
const esp_lcd_rgb_panel_config_t panel_config = {
.clk_src = LCD_CLK_SRC_DEFAULT,
@@ -175,6 +185,29 @@ esp_err_t display_init(void)
ESP_RETURN_ON_ERROR(esp_lcd_new_rgb_panel(&panel_config, &panel), TAG,
"esp_lcd_new_rgb_panel failed");
ESP_LOGI(TAG, "Panel buffers allocated; free internal heap: %u KB",
(unsigned)(heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024));
return ESP_OK;
}
/*
* Phase 2: start scan-out and hand the framebuffers to LVGL.
*
* From esp_lcd_panel_init() onward the bounce-refill ISR is reading PSRAM
* continuously, so every flash write (NVS, WiFi PHY calibration) must already
* be done -- see the init-order comment in main.c.
*/
esp_err_t display_start(void)
{
ESP_RETURN_ON_FALSE(panel != NULL, ESP_ERR_INVALID_STATE, TAG,
"display_alloc() must run before display_start()");
/* lv_display_create() below allocates from LVGL's heap. Without lv_init()
* that heap is a null pool and the call faults with LoadProhibited. */
ESP_RETURN_ON_FALSE(lv_is_initialized(), ESP_ERR_INVALID_STATE, TAG,
"lv_init() must run before display_start()");
ESP_RETURN_ON_ERROR(esp_lcd_panel_reset(panel), TAG, "panel reset failed");
ESP_RETURN_ON_ERROR(esp_lcd_panel_init(panel), TAG, "panel init failed");
+16 -3
View File
@@ -9,9 +9,22 @@
#define DISPLAY_H_RES 800
#define DISPLAY_V_RES 480
/* Requires lv_init() to have already run -- call lvgl_port_init() first.
* Backlight is NOT owned here on the Advance; see drivers/backlight. */
esp_err_t display_init(void);
/*
* Two-phase bring-up, and the order is load-bearing:
*
* display_alloc() -- BEFORE wifi_init_sta(). Grabs the framebuffers and
* the two contiguous bounce buffers while the internal
* heap is still unfragmented; WiFi's RX buffer churn
* destroys the needed contiguity within seconds.
* The panel is not scanning after this.
* display_start() -- AFTER WiFi (all flash writes done) and after
* lvgl_port_init(). Starts scan-out and registers the
* display with LVGL.
*
* Backlight is NOT owned here on the Advance; see drivers/backlight.
*/
esp_err_t display_alloc(void);
esp_err_t display_start(void);
lv_display_t *display_get_default(void);
+48 -7
View File
@@ -38,6 +38,14 @@ static const char *TAG = "main";
/* Consecutive failed polls before the displayed reading is treated as stale. */
#define STALE_AFTER_POLLS 2
/*
* Trend arrow thresholds, per hour. Below these a reading renders as flat:
* a thermostat's indoor temp wobbles a couple of tenths continuously, and an
* arrow that flickers on noise is worse than none.
*/
#define TREND_TEMP_PER_HOUR_F 0.5f
#define TREND_PRESS_PER_HOUR_INHG 0.02f
/* Depth 8: a burst of taps while the network is slow should queue rather than
* be dropped, but a user cannot meaningfully get more than a few ahead. */
#define CMD_QUEUE_DEPTH 8
@@ -190,6 +198,29 @@ static void ha_task(void *arg)
consecutive_failures = 0;
have_reading = true;
/*
* Trend history is local: the device sees every reading anyway,
* so an /api/history query would be hundreds of JSON points to
* answer a question one ring buffer answers for free. History is
* lost on reboot; arrows reappear ~5 minutes later.
*/
const uint32_t now_ms = xTaskGetTickCount() * portTICK_PERIOD_MS;
if (ha_data.indoor_temp_f.valid) {
ha_trend_feed(HA_TREND_CH_INDOOR, ha_data.indoor_temp_f.value, now_ms);
}
if (ha_data.outdoor_temp_f.valid) {
ha_trend_feed(HA_TREND_CH_OUTDOOR, ha_data.outdoor_temp_f.value, now_ms);
}
if (ha_data.pressure_inhg.valid) {
ha_trend_feed(HA_TREND_CH_PRESSURE, ha_data.pressure_inhg.value, now_ms);
}
ha_data.trend_indoor =
ha_trend_compute(HA_TREND_CH_INDOOR, TREND_TEMP_PER_HOUR_F, now_ms);
ha_data.trend_outdoor =
ha_trend_compute(HA_TREND_CH_OUTDOOR, TREND_TEMP_PER_HOUR_F, now_ms);
ha_data.trend_pressure =
ha_trend_compute(HA_TREND_CH_PRESSURE, TREND_PRESS_PER_HOUR_INHG, now_ms);
ui_update(&ha_data);
ui_set_stale(false);
@@ -227,14 +258,23 @@ void app_main(void)
ESP_LOGI(TAG, "Thermostat HMI -- CrowPanel 7.0\" ESP32-S3 (800x480)");
/*
* WiFi comes up FIRST, before the RGB panel exists.
* Panel BUFFERS first, WiFi second, panel SCAN-OUT third. Both orderings
* are load-bearing:
*
* The panel's bounce-buffer ISR reads the framebuffer out of PSRAM, and
* PSRAM shares the cache with flash on the ESP32-S3. Bringing up NVS and
* the WiFi PHY writes calibration data to flash, which disables the cache
* and faults that ISR. Doing it here means every flash write is finished
* before the panel starts scanning.
* - display_alloc() before WiFi: the bounce buffers need two contiguous
* 25.6KB internal DMA blocks, and WiFi's RX buffer churn fragments
* the internal heap within seconds of association. Allocating from
* the virgin heap is deterministic; observed otherwise as a
* boot-loop with 84KB free and no block big enough.
*
* - display_start() after WiFi: from the moment scan-out begins, the
* bounce-refill ISR reads PSRAM continuously, and PSRAM shares the
* cache with flash on the S3. NVS and WiFi PHY calibration write
* flash; doing all of that before the first scan means the ISR can
* never hit "Cache disabled but cached memory region accessed".
*/
ESP_ERROR_CHECK(display_alloc());
const esp_err_t wifi_err = wifi_init_sta();
if (wifi_err != ESP_OK) {
ESP_LOGE(TAG, "WiFi not up yet -- polling starts when it connects");
@@ -254,7 +294,8 @@ void app_main(void)
}
i2c_bus_scan(TAG);
ESP_ERROR_CHECK(display_init());
/* Buffers were allocated before WiFi; this only starts scan-out. */
ESP_ERROR_CHECK(display_start());
if (touch_init() != ESP_OK) {
/* A dead touch panel should not stop the display from working -- but
+354 -341
View File
@@ -6,27 +6,27 @@
#include <stddef.h>
const size_t icon_font_data_size = 5972;
const size_t icon_font_data_size = 6192;
const unsigned char icon_font_data[] = {
0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x80, 0x00, 0x03, 0x00, 0x30, 0x47, 0x53, 0x55, 0x42,
0xb8, 0xfa, 0xb8, 0xf4, 0x00, 0x00, 0x17, 0x28, 0x00, 0x00, 0x00, 0x2a, 0x4f, 0x53, 0x2f, 0x32,
0xb8, 0xfa, 0xb8, 0xf4, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x2a, 0x4f, 0x53, 0x2f, 0x32,
0x4f, 0xb3, 0x5b, 0xd3, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, 0x56, 0x63, 0x6d, 0x61, 0x70,
0x01, 0xb4, 0x33, 0xcc, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x00, 0xcc, 0x67, 0x6c, 0x79, 0x66,
0x07, 0x29, 0x77, 0x5e, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x13, 0x74, 0x68, 0x65, 0x61, 0x64,
0x02, 0x0e, 0x52, 0xf7, 0x00, 0x00, 0x01, 0xd0, 0x00, 0x00, 0x00, 0xf0, 0x67, 0x6c, 0x79, 0x66,
0x7b, 0x20, 0xfe, 0x3a, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x20, 0x68, 0x65, 0x61, 0x64,
0x59, 0x6d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61,
0x03, 0xc6, 0x01, 0xbf, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78,
0x02, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x3a, 0x6c, 0x6f, 0x63, 0x61,
0x3f, 0xd5, 0x44, 0xe9, 0x00, 0x00, 0x02, 0x98, 0x00, 0x00, 0x00, 0x38, 0x6d, 0x61, 0x78, 0x70,
0x01, 0x52, 0x01, 0x85, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
0x0b, 0xcc, 0x24, 0x14, 0x00, 0x00, 0x16, 0x44, 0x00, 0x00, 0x00, 0xc2, 0x70, 0x6f, 0x73, 0x74,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x17, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0xe2, 0xcc, 0x9f, 0xb1, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x0b, 0x02, 0x00,
0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x40, 0x6c, 0x6f, 0x63, 0x61,
0x4a, 0x8f, 0x44, 0xe6, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x3e, 0x6d, 0x61, 0x78, 0x70,
0x01, 0x55, 0x01, 0x85, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65,
0x0b, 0xcc, 0x24, 0x14, 0x00, 0x00, 0x17, 0x20, 0x00, 0x00, 0x00, 0xc2, 0x70, 0x6f, 0x73, 0x74,
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x17, 0xe4, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0xe4, 0xb3, 0x4f, 0xdb, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x0b, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0x25, 0x9d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x25, 0x9d, 0xc0,
0xff, 0xff, 0xff, 0xbe, 0x02, 0x04, 0x01, 0xc5, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xc0, 0xff, 0xc0, 0x00, 0x00, 0x02, 0x00,
0xff, 0xff, 0xff, 0xfc, 0x02, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x01, 0x79,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x79,
0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00,
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x90, 0x00, 0x05,
0x00, 0x00, 0x01, 0x44, 0x01, 0x66, 0x00, 0x00, 0x00, 0x47, 0x01, 0x44, 0x01, 0x66, 0x00, 0x00,
@@ -37,23 +37,26 @@ const unsigned char icon_font_data[] = {
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14,
0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
0x00, 0x0f, 0x02, 0x9a, 0x00, 0x0f, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x05, 0x0f,
0x00, 0x0f, 0x05, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x05, 0x90, 0x00, 0x0f, 0x05, 0x99,
0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x05, 0x9b, 0x00, 0x0f, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x0d,
0x00, 0x0f, 0x05, 0xd6, 0x00, 0x0f, 0x05, 0xd6, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0f, 0x06, 0x7e,
0x00, 0x0f, 0x06, 0x7f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0f, 0x08, 0xdd, 0x00, 0x0f, 0x08, 0xdd,
0x00, 0x00, 0x00, 0x13, 0x00, 0x0f, 0x09, 0x5f, 0x00, 0x0f, 0x09, 0x5f, 0x00, 0x00, 0x00, 0x14,
0x00, 0x0f, 0x0a, 0x70, 0x00, 0x0f, 0x0a, 0x70, 0x00, 0x00, 0x00, 0x15, 0x00, 0x0f, 0x0e, 0x0a,
0x00, 0x0f, 0x0e, 0x0a, 0x00, 0x00, 0x00, 0x16, 0x00, 0x0f, 0x0f, 0x55, 0x00, 0x0f, 0x0f, 0x55,
0x00, 0x00, 0x00, 0x17, 0x00, 0x0f, 0x12, 0xba, 0x00, 0x0f, 0x12, 0xba, 0x00, 0x00, 0x00, 0x18,
0x00, 0x0f, 0x15, 0x6d, 0x00, 0x0f, 0x15, 0x6d, 0x00, 0x00, 0x00, 0x19, 0x00, 0x0f, 0x17, 0x93,
0x00, 0x0f, 0x17, 0x93, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0xa5,
0x00, 0xe3, 0x01, 0x58, 0x01, 0xc6, 0x02, 0x1b, 0x02, 0x78, 0x02, 0xfb, 0x03, 0x88, 0x03, 0xfd,
0x04, 0x84, 0x04, 0xdd, 0x05, 0x38, 0x05, 0x92, 0x05, 0xf4, 0x06, 0x2e, 0x06, 0x96, 0x07, 0x30,
0x07, 0x47, 0x07, 0x80, 0x07, 0xac, 0x07, 0xf1, 0x08, 0x29, 0x08, 0xe1, 0x09, 0x4d, 0x09, 0xba,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x03, 0x00, 0x0a,
0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x11, 0x00, 0x0f, 0x02, 0x9a, 0x00, 0x0f, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01,
0x00, 0x0f, 0x05, 0x02, 0x00, 0x0f, 0x05, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x05, 0x0f,
0x00, 0x0f, 0x05, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x05, 0x33, 0x00, 0x0f, 0x05, 0x33,
0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0x05, 0x35, 0x00, 0x0f, 0x05, 0x35, 0x00, 0x00, 0x00, 0x05,
0x00, 0x0f, 0x05, 0x90, 0x00, 0x0f, 0x05, 0x99, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0x05, 0x9b,
0x00, 0x0f, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0f, 0x05, 0xd6, 0x00, 0x0f, 0x05, 0xd6,
0x00, 0x00, 0x00, 0x13, 0x00, 0x0f, 0x06, 0x7e, 0x00, 0x0f, 0x06, 0x7f, 0x00, 0x00, 0x00, 0x14,
0x00, 0x0f, 0x08, 0xdd, 0x00, 0x0f, 0x08, 0xdd, 0x00, 0x00, 0x00, 0x16, 0x00, 0x0f, 0x09, 0x5f,
0x00, 0x0f, 0x09, 0x5f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x0f, 0x0a, 0x70, 0x00, 0x0f, 0x0a, 0x70,
0x00, 0x00, 0x00, 0x18, 0x00, 0x0f, 0x0e, 0x0a, 0x00, 0x0f, 0x0e, 0x0a, 0x00, 0x00, 0x00, 0x19,
0x00, 0x0f, 0x0f, 0x55, 0x00, 0x0f, 0x0f, 0x55, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x0f, 0x12, 0xba,
0x00, 0x0f, 0x12, 0xba, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x0f, 0x15, 0x6d, 0x00, 0x0f, 0x15, 0x6d,
0x00, 0x00, 0x00, 0x1c, 0x00, 0x0f, 0x17, 0x93, 0x00, 0x0f, 0x17, 0x93, 0x00, 0x00, 0x00, 0x1d,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0xa3, 0x00, 0xcb, 0x00, 0xe3, 0x00, 0xfb, 0x01, 0x39,
0x01, 0xae, 0x02, 0x1c, 0x02, 0x71, 0x02, 0xce, 0x03, 0x51, 0x03, 0xde, 0x04, 0x53, 0x04, 0xda,
0x05, 0x33, 0x05, 0x8e, 0x05, 0xe8, 0x06, 0x4a, 0x06, 0x84, 0x06, 0xec, 0x07, 0x86, 0x07, 0x9d,
0x07, 0xd6, 0x08, 0x02, 0x08, 0x47, 0x08, 0x7f, 0x09, 0x37, 0x09, 0xa3, 0x0a, 0x10, 0x00, 0x00,
0x00, 0x06, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x10, 0x00, 0x23, 0x00, 0x38,
0x00, 0x41, 0x00, 0x4a, 0x00, 0x53, 0x00, 0x00, 0x01, 0x22, 0x0e, 0x02, 0x14, 0x1e, 0x02, 0x32,
0x3e, 0x02, 0x34, 0x2e, 0x02, 0x07, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x2e, 0x01, 0x23,
@@ -69,318 +72,328 @@ const unsigned char icon_font_data[] = {
0x20, 0x2a, 0x2e, 0x4f, 0x2e, 0x26, 0x42, 0x18, 0x15, 0x16, 0x2b, 0x18, 0x42, 0x26, 0x2e, 0x4f,
0x2e, 0x29, 0x07, 0x07, 0x49, 0x02, 0x0f, 0x0a, 0x11, 0x20, 0x0d, 0x0e, 0x10, 0x0b, 0x16, 0x09,
0x4b, 0x08, 0x10, 0x04, 0x01, 0x02, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x40, 0x0c, 0x12, 0x0d,
0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea,
0x01, 0x71, 0x01, 0x96, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x00, 0x25, 0x35, 0x34, 0x26, 0x22, 0x06,
0x1d, 0x01, 0x0e, 0x01, 0x1e, 0x01, 0x32, 0x3e, 0x01, 0x26, 0x27, 0x32, 0x16, 0x1d, 0x01, 0x23,
0x35, 0x34, 0x36, 0x01, 0x40, 0x25, 0x36, 0x25, 0x1c, 0x14, 0x16, 0x38, 0x44, 0x38, 0x16, 0x14,
0x5c, 0x09, 0x0c, 0x2a, 0x0c, 0xab, 0xaa, 0x1b, 0x25, 0x25, 0x1b, 0xaa, 0x15, 0x42, 0x41, 0x28,
0x28, 0x41, 0x42, 0xd5, 0x0d, 0x09, 0x40, 0x40, 0x09, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x01, 0xeb, 0x01, 0x56, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01, 0x34, 0x3e,
0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x35,
0x23, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x33,
0x21, 0x32, 0x36, 0x34, 0x26, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24,
0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c,
0x0b, 0x1b, 0x25, 0x25, 0x1b, 0x01, 0x15, 0x12, 0x19, 0x19, 0x2b, 0x1c, 0x31, 0x3a, 0x31, 0x1d,
0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x80, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04,
0x25, 0x35, 0x26, 0x19, 0x24, 0x19, 0x00, 0x05, 0x00, 0x00, 0xff, 0xff, 0x01, 0xeb, 0x01, 0x81,
0x00, 0x0b, 0x00, 0x17, 0x00, 0x3c, 0x00, 0x48, 0x00, 0x54, 0x00, 0x00, 0x37, 0x33, 0x32, 0x16,
0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x21, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01,
0x22, 0x26, 0x34, 0x36, 0x25, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17,
0x37, 0x32, 0x16, 0x17, 0x23, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06,
0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x23, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b,
0x01, 0x22, 0x26, 0x34, 0x36, 0x33, 0x21, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34,
0x36, 0x40, 0xd5, 0x09, 0x0d, 0x0d, 0x09, 0xd5, 0x09, 0x0c, 0x0c, 0x01, 0x1e, 0x6b, 0x09, 0x0c,
0x0c, 0x09, 0x6b, 0x09, 0x0c, 0x0c, 0xfe, 0xc9, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e,
0x26, 0x03, 0x0a, 0x23, 0x32, 0x01, 0x2b, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06,
0x0c, 0x0b, 0x1b, 0x25, 0x04, 0x2d, 0x29, 0x2b, 0x09, 0x0c, 0x0c, 0x09, 0x2b, 0x09, 0x0c, 0x0c,
0x74, 0x01, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0xeb, 0x09, 0x0d, 0x0d, 0x80, 0x0c, 0x12, 0x0d,
0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x40, 0x1d, 0x31, 0x1d, 0x26, 0x2f, 0x22,
0x3b, 0x24, 0x01, 0x32, 0x23, 0x11, 0x19, 0x16, 0x1d, 0x31, 0x1c, 0x33, 0x26, 0x04, 0x25, 0x1b,
0x0b, 0x0a, 0x80, 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x00,
0x00, 0x04, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x3d, 0x00, 0x46,
0x00, 0x4f, 0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01,
0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22,
0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23,
0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26,
0x34, 0x36, 0x37, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x27, 0x32, 0x16, 0x14, 0x06,
0x22, 0x26, 0x34, 0x36, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10,
0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09,
0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25,
0x25, 0x70, 0x12, 0x19, 0x19, 0x23, 0x19, 0x19, 0x71, 0x0e, 0x12, 0x12, 0x1b, 0x13, 0x13, 0x48,
0x0d, 0x13, 0x13, 0x1a, 0x13, 0x13, 0x95, 0x0c, 0x12, 0x0c, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26,
0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31,
0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x55, 0x19, 0x23, 0x19, 0x19, 0x23, 0x19, 0x2b, 0x13,
0x1b, 0x12, 0x12, 0x1b, 0x13, 0x55, 0x13, 0x1a, 0x13, 0x13, 0x1a, 0x13, 0x00, 0x02, 0x00, 0x00,
0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x36, 0x00, 0x3d, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01,
0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06,
0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34,
0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x3b, 0x01, 0x32, 0x16,
0x14, 0x06, 0x23, 0x37, 0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31,
0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c,
0x0c, 0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b,
0x1b, 0x25, 0x25, 0x1b, 0x15, 0x09, 0x0d, 0x0d, 0x09, 0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x35,
0x6b, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12,
0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x0c, 0x12,
0x0c, 0x6a, 0x55, 0x95, 0x6a, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xe3, 0x01, 0xc6, 0x01, 0xab,
0x00, 0x09, 0x00, 0x13, 0x00, 0x2b, 0x00, 0x37, 0x00, 0x00, 0x01, 0x07, 0x17, 0x27, 0x07, 0x37,
0x27, 0x3f, 0x01, 0x1f, 0x01, 0x07, 0x17, 0x27, 0x07, 0x37, 0x27, 0x3f, 0x01, 0x17, 0x07, 0x36,
0x1e, 0x01, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x2e, 0x02, 0x36, 0x37, 0x36, 0x37, 0x36, 0x1e, 0x01,
0x07, 0x06, 0x1e, 0x02, 0x17, 0x2e, 0x03, 0x27, 0x0e, 0x01, 0x1e, 0x02, 0x36, 0x01, 0x7b, 0x36,
0x13, 0x38, 0x38, 0x13, 0x36, 0x44, 0x17, 0x17, 0x8e, 0x23, 0x0d, 0x24, 0x25, 0x0d, 0x23, 0x2c,
0x0f, 0x0e, 0x04, 0x08, 0x11, 0x05, 0x05, 0x0b, 0x0c, 0x29, 0x6e, 0x6e, 0x52, 0x1c, 0x1c, 0x29,
0x0d, 0x0e, 0x08, 0x14, 0x0d, 0x01, 0x04, 0x1f, 0x45, 0x5a, 0x0c, 0x2e, 0x57, 0x44, 0x26, 0x02,
0x1e, 0x13, 0x18, 0x3f, 0x54, 0x56, 0x01, 0x69, 0x2a, 0x41, 0x27, 0x27, 0x41, 0x2a, 0x02, 0x40,
0x40, 0x96, 0x1a, 0x2b, 0x19, 0x19, 0x2b, 0x1a, 0x01, 0x2a, 0x2a, 0x6a, 0x01, 0x0e, 0x13, 0x08,
0x10, 0x0b, 0x29, 0x1d, 0x1d, 0x52, 0x6e, 0x6e, 0x29, 0x0d, 0x0a, 0x05, 0x06, 0x10, 0x09, 0x2e,
0x5a, 0x45, 0x20, 0x26, 0x02, 0x26, 0x44, 0x56, 0x2e, 0x21, 0x55, 0x54, 0x3f, 0x18, 0x13, 0x00,
0x00, 0x07, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x9a, 0x00, 0x1b, 0x00, 0x29, 0x00, 0x2f,
0x00, 0x35, 0x00, 0x3b, 0x00, 0x41, 0x00, 0x54, 0x00, 0x00, 0x01, 0x1e, 0x01, 0x07, 0x1e, 0x01,
0x1d, 0x01, 0x36, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01,
0x2e, 0x01, 0x37, 0x3e, 0x02, 0x17, 0x26, 0x06, 0x07, 0x06, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32,
0x17, 0x2e, 0x01, 0x37, 0x26, 0x27, 0x37, 0x17, 0x26, 0x07, 0x06, 0x07, 0x37, 0x17, 0x06, 0x17,
0x26, 0x27, 0x17, 0x07, 0x36, 0x05, 0x16, 0x17, 0x27, 0x37, 0x06, 0x05, 0x23, 0x35, 0x34, 0x26,
0x22, 0x06, 0x15, 0x23, 0x22, 0x06, 0x14, 0x16, 0x33, 0x21, 0x32, 0x36, 0x34, 0x26, 0x01, 0x10,
0x25, 0x26, 0x07, 0x14, 0x18, 0x0a, 0x0b, 0x1b, 0x25, 0x25, 0x1b, 0xfe, 0xeb, 0x23, 0x32, 0x32,
0x23, 0x06, 0x15, 0x0a, 0x0e, 0x0d, 0x33, 0x3e, 0x0c, 0x1d, 0x3a, 0x0c, 0x07, 0x01, 0x08, 0x12,
0x33, 0x1d, 0x16, 0x15, 0x01, 0x18, 0x0f, 0x11, 0x13, 0x36, 0x13, 0x11, 0xb3, 0x10, 0x0c, 0x03,
0x3f, 0x14, 0xec, 0x03, 0x06, 0x33, 0x2c, 0x04, 0xfe, 0xbf, 0x02, 0x06, 0x32, 0x2b, 0x03, 0x01,
0x56, 0x40, 0x32, 0x46, 0x32, 0x2b, 0x12, 0x19, 0x19, 0x12, 0x01, 0x15, 0x09, 0x0d, 0x0d, 0x01,
0x4b, 0x10, 0x48, 0x27, 0x12, 0x33, 0x1c, 0x04, 0x04, 0x26, 0x35, 0x25, 0x32, 0x46, 0x32, 0x1a,
0x42, 0x1f, 0x1d, 0x24, 0x07, 0x34, 0x0d, 0x16, 0x1c, 0x10, 0x23, 0x0f, 0x15, 0x19, 0x08, 0x15,
0x23, 0x57, 0x08, 0x03, 0x1c, 0x3d, 0x0d, 0x08, 0x0b, 0x0e, 0x3c, 0x0f, 0x06, 0x7e, 0x14, 0x10,
0x20, 0x2f, 0x14, 0x0b, 0x13, 0x11, 0x20, 0x2f, 0x16, 0xa4, 0x2b, 0x23, 0x32, 0x32, 0x23, 0x19,
0x24, 0x19, 0x0d, 0x12, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xef, 0x01, 0xeb, 0x01, 0x96,
0x00, 0x0c, 0x00, 0x19, 0x00, 0x26, 0x00, 0x5f, 0x00, 0x00, 0x37, 0x1e, 0x01, 0x0f, 0x01, 0x0e,
0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01,
0x3f, 0x01, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e,
0x01, 0x37, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14,
0x16, 0x17, 0x31, 0x1e, 0x01, 0x0e, 0x01, 0x27, 0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e,
0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x31, 0x06, 0x2e,
0x01, 0x36, 0x37, 0x31, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0xc0, 0x08, 0x09, 0x02, 0x1c, 0x02,
0x0f, 0x11, 0x09, 0x03, 0x1b, 0x02, 0x0f, 0x5e, 0x09, 0x09, 0x03, 0x2c, 0x02, 0x0f, 0x11, 0x09,
0x02, 0x2c, 0x03, 0x0f, 0x5e, 0x08, 0x09, 0x02, 0x1c, 0x02, 0x0f, 0x12, 0x08, 0x02, 0x1c, 0x02,
0x0f, 0x09, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x11, 0x0f, 0x08, 0x04,
0x09, 0x10, 0x08, 0x19, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a,
0x24, 0x32, 0x17, 0x14, 0x08, 0x11, 0x09, 0x05, 0x08, 0x09, 0x0c, 0x19, 0x12, 0xc0, 0x02, 0x10,
0x08, 0x67, 0x09, 0x08, 0x04, 0x0f, 0x09, 0x67, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0xa5, 0x09,
0x08, 0x04, 0x10, 0x08, 0xa5, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0x67, 0x09, 0x08, 0x04, 0x0f,
0x09, 0x67, 0x08, 0x09, 0x29, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e,
0x08, 0x04, 0x12, 0x0f, 0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23,
0x32, 0x23, 0x18, 0x27, 0x0b, 0x04, 0x04, 0x10, 0x11, 0x04, 0x06, 0x13, 0x0c, 0x12, 0x19, 0x00,
0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb, 0x01, 0x95, 0x00, 0x34, 0x00, 0x40, 0x00, 0x54,
0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e,
0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x37, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34,
0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06,
0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26,
0x35, 0x34, 0x3f, 0x01, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x16, 0x32, 0x36,
0x35, 0x34, 0x27, 0x2e, 0x01, 0x27, 0x31, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d,
0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09,
0x0c, 0x0c, 0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0b,
0x0c, 0x1b, 0x25, 0x25, 0x9b, 0x05, 0x07, 0x1f, 0x19, 0x24, 0x19, 0x1f, 0x0c, 0x0b, 0x0b, 0x0e,
0x0b, 0x12, 0x08, 0x0c, 0x32, 0x46, 0x32, 0x0c, 0x08, 0x24, 0x12, 0x95, 0x0d, 0x11, 0x0d, 0x1d,
0x31, 0x3a, 0x31, 0x1c, 0x27, 0x2f, 0x23, 0x3a, 0x24, 0x01, 0x32, 0x47, 0x32, 0x0d, 0x11, 0x0d,
0x19, 0x23, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x26, 0x04, 0x26, 0x35, 0x25, 0x03, 0x07, 0x0a,
0x2b, 0x16, 0x12, 0x19, 0x19, 0x12, 0x16, 0x2b, 0x54, 0x0c, 0x0e, 0x11, 0x11, 0x19, 0x12, 0x19,
0x15, 0x23, 0x32, 0x32, 0x23, 0x15, 0x19, 0x12, 0x34, 0x15, 0x00, 0x02, 0x00, 0x00, 0xff, 0xd6,
0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x5e, 0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23,
0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32,
0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b,
0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17,
0x37, 0x27, 0x26, 0x34, 0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37,
0x36, 0x1e, 0x01, 0x06, 0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01,
0x2e, 0x01, 0x3f, 0x01, 0x07, 0x06, 0x2e, 0x01, 0x36, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31,
0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24,
0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b,
0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25, 0x43, 0x2f, 0x23, 0x06, 0x0d, 0x12, 0x06, 0x22, 0x0c, 0x03,
0x0f, 0x11, 0x09, 0x02, 0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x08, 0x2f, 0x23, 0x06, 0x0d, 0x12,
0x06, 0x22, 0x0c, 0x03, 0x0f, 0x11, 0x09, 0x02, 0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x95, 0x0c,
0x12, 0x0c, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c,
0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x56,
0x0c, 0x22, 0x06, 0x12, 0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10, 0x08, 0x2f, 0x0d, 0x02,
0x09, 0x11, 0x0f, 0x03, 0x0c, 0x22, 0x06, 0x12, 0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10,
0x08, 0x2f, 0x0d, 0x02, 0x09, 0x11, 0x0f, 0x00, 0x00, 0x08, 0x00, 0x00, 0xff, 0xea, 0x01, 0xb9,
0x01, 0x96, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x1f, 0x00, 0x24, 0x00, 0x29, 0x00, 0x2e,
0x00, 0x33, 0x00, 0x00, 0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x22, 0x2e, 0x01, 0x34, 0x3e,
0x01, 0x17, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x27, 0x17, 0x26, 0x22, 0x0f, 0x01,
0x37, 0x0e, 0x01, 0x0f, 0x01, 0x37, 0x1e, 0x01, 0x17, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x17, 0x07,
0x3e, 0x01, 0x37, 0x07, 0x27, 0x16, 0x32, 0x37, 0x01, 0x00, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x3a,
0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x1b, 0x25, 0x25, 0x36, 0x25, 0x25, 0x1b, 0x33, 0x19, 0x34, 0x19,
0x86, 0x59, 0x14, 0x1a, 0x05, 0x25, 0x25, 0x05, 0x1a, 0x14, 0x01, 0x19, 0x26, 0x05, 0x1a, 0x14,
0x58, 0x58, 0x14, 0x1a, 0x05, 0x93, 0x33, 0x19, 0x33, 0x1a, 0x01, 0x2b, 0x1d, 0x31, 0x3a, 0x31,
0x1d, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x2b, 0x25, 0x36, 0x25, 0x25, 0x36, 0x25, 0x95, 0x49, 0x09,
0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x85, 0x51, 0x1a, 0x2d, 0x12, 0xde, 0x51, 0x1a, 0x2e, 0x10,
0xdd, 0x07, 0x11, 0x2d, 0x1a, 0xbb, 0x49, 0x09, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0xff,
0x01, 0xd6, 0x01, 0x96, 0x00, 0x13, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x39,
0x00, 0x00, 0x37, 0x33, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x15, 0x33, 0x32, 0x16, 0x14, 0x06,
0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x21, 0x34, 0x26, 0x22, 0x06, 0x15, 0x37, 0x17, 0x26, 0x22,
0x0f, 0x01, 0x37, 0x0e, 0x01, 0x07, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x03, 0x37, 0x36, 0x34, 0x26,
0x22, 0x0f, 0x01, 0x27, 0x26, 0x22, 0x06, 0x14, 0x1f, 0x01, 0x16, 0x32, 0x40, 0x55, 0x1d, 0x31,
0x3a, 0x31, 0x1d, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x01, 0x09, 0x25,
0x36, 0x25, 0x40, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a, 0x05, 0x01, 0x4c, 0x26, 0x05,
0x1a, 0x14, 0x51, 0x42, 0x07, 0x0d, 0x11, 0x07, 0x33, 0x33, 0x07, 0x11, 0x0d, 0x07, 0x42, 0x07,
0x10, 0xc0, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x1b, 0x25,
0x25, 0x1b, 0xd5, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x51, 0x51, 0x1a, 0x2e, 0x10,
0xfe, 0xd4, 0x43, 0x06, 0x12, 0x0c, 0x06, 0x34, 0x34, 0x06, 0x0c, 0x12, 0x06, 0x43, 0x06, 0x00,
0x00, 0x06, 0x00, 0x00, 0xff, 0xfd, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x13, 0x00, 0x19, 0x00, 0x1e,
0x00, 0x23, 0x00, 0x28, 0x00, 0x39, 0x00, 0x00, 0x37, 0x33, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01,
0x15, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x21, 0x34, 0x26, 0x22,
0x06, 0x15, 0x37, 0x17, 0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e, 0x01, 0x07, 0x25, 0x07, 0x2e, 0x01,
0x27, 0x07, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x06, 0x22, 0x26, 0x34, 0x3f, 0x01,
0x36, 0x32, 0x40, 0x55, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80,
0x09, 0x0c, 0x0c, 0x01, 0x09, 0x25, 0x36, 0x25, 0x40, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14,
0x1a, 0x05, 0x01, 0x4c, 0x26, 0x05, 0x1a, 0x14, 0x51, 0x42, 0x07, 0x0d, 0x11, 0x07, 0x33, 0x33,
0x07, 0x11, 0x0d, 0x07, 0x42, 0x07, 0x10, 0xc0, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12,
0x0d, 0x0d, 0x12, 0x0c, 0x1b, 0x25, 0x25, 0x1b, 0xd5, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11, 0x2c,
0x1b, 0x51, 0x51, 0x1a, 0x2e, 0x10, 0xce, 0x42, 0x06, 0x12, 0x0c, 0x06, 0x33, 0x33, 0x06, 0x0c,
0x12, 0x06, 0x42, 0x07, 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x17,
0x00, 0x2e, 0x00, 0x45, 0x00, 0x00, 0x37, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34,
0x26, 0x22, 0x07, 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x17, 0x32,
0x36, 0x34, 0x26, 0x22, 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21,
0x22, 0x26, 0x34, 0x36, 0x33, 0x05, 0x21, 0x22, 0x26, 0x34, 0x36, 0x33, 0x21, 0x32, 0x16, 0x14,
0x06, 0x22, 0x27, 0x26, 0x34, 0x36, 0x32, 0x16, 0x32, 0x36, 0x34, 0x26, 0x55, 0x09, 0x0c, 0x0c,
0x09, 0xab, 0x12, 0x19, 0x19, 0x24, 0x0c, 0x06, 0x12, 0x0d, 0x07, 0x19, 0x46, 0x32, 0x32, 0x23,
0x95, 0x09, 0x0d, 0x0d, 0x12, 0x0c, 0x12, 0x0c, 0x06, 0x13, 0x35, 0x25, 0x25, 0x1b, 0xfe, 0xd6,
0x09, 0x0d, 0x0d, 0x09, 0x01, 0x15, 0xfe, 0xd5, 0x09, 0x0c, 0x0c, 0x09, 0x01, 0x2b, 0x1b, 0x25,
0x25, 0x35, 0x13, 0x06, 0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x0c, 0xeb, 0x0c, 0x12, 0x0c, 0x19, 0x24,
0x19, 0x0d, 0x06, 0x0c, 0x12, 0x06, 0x19, 0x32, 0x46, 0x32, 0x2b, 0x0c, 0x12, 0x0d, 0x0d, 0x0d,
0x11, 0x07, 0x12, 0x25, 0x35, 0x26, 0x0d, 0x12, 0x0c, 0x80, 0x0c, 0x12, 0x0d, 0x26, 0x35, 0x25,
0x12, 0x07, 0x11, 0x0d, 0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x04, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6,
0x01, 0x96, 0x00, 0x03, 0x00, 0x07, 0x00, 0x18, 0x00, 0x25, 0x00, 0x00, 0x37, 0x33, 0x15, 0x23,
0x35, 0x33, 0x15, 0x23, 0x37, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x34,
0x2e, 0x02, 0x03, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0xeb,
0x2a, 0x2a, 0x2a, 0x2a, 0x15, 0x3a, 0x62, 0x39, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20, 0x20,
0x3c, 0x4f, 0x2a, 0x2e, 0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x80, 0x2b, 0xd6,
0x80, 0xea, 0x39, 0x62, 0x3a, 0x2a, 0x4f, 0x3c, 0x20, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20,
0xfe, 0x80, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x00, 0x03, 0x00, 0x00,
0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x3b, 0x00, 0x49, 0x00, 0x00, 0x37, 0x1e,
0x01, 0x0e, 0x01, 0x27, 0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e,
0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36, 0x34,
0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15,
0x14, 0x16, 0x17, 0x37, 0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x17, 0x14, 0x06, 0x22, 0x26, 0x34,
0x37, 0x36, 0x37, 0x31, 0x17, 0x16, 0x17, 0x16, 0x60, 0x08, 0x04, 0x09, 0x10, 0x08, 0x19, 0x1d,
0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09,
0x0c, 0x0c, 0x09, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b,
0x1b, 0x25, 0x11, 0x0f, 0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x36, 0xe0, 0x1c, 0x28, 0x1c, 0x18,
0x0c, 0x0c, 0x0d, 0x0e, 0x09, 0x0c, 0x9e, 0x04, 0x12, 0x0f, 0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31,
0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15,
0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e, 0x08, 0x37, 0x55, 0x95, 0x6a, 0x23,
0x15, 0x1d, 0x1d, 0x29, 0x25, 0x12, 0x0e, 0x10, 0x13, 0x11, 0x17, 0x00, 0x00, 0x03, 0x00, 0x00,
0xff, 0xfd, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x0d, 0x00, 0x38, 0x00, 0x6a, 0x00, 0x00, 0x25, 0x14,
0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x37, 0x31, 0x17, 0x16, 0x17, 0x16, 0x25, 0x26, 0x36, 0x3f,
0x01, 0x27, 0x26, 0x34, 0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37,
0x36, 0x1e, 0x01, 0x06, 0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01,
0x2e, 0x01, 0x3f, 0x01, 0x07, 0x06, 0x26, 0x27, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32,
0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36,
0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06,
0x14, 0x17, 0x16, 0x14, 0x06, 0x22, 0x27, 0x2e, 0x01, 0x01, 0x8b, 0x1c, 0x28, 0x1c, 0x18, 0x0c,
0x0c, 0x0c, 0x0e, 0x09, 0x0d, 0xfe, 0xca, 0x02, 0x09, 0x09, 0x30, 0x23, 0x07, 0x0d, 0x13, 0x06,
0x23, 0x0d, 0x02, 0x10, 0x11, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x10, 0x05, 0x09, 0x09, 0x30, 0x23,
0x06, 0x0d, 0x12, 0x06, 0x23, 0x0d, 0x03, 0x0f, 0x12, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x0f, 0x43,
0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09,
0x0c, 0x0c, 0x09, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b,
0x1b, 0x25, 0x13, 0x06, 0x0c, 0x12, 0x06, 0x0f, 0x11, 0x32, 0x15, 0x1d, 0x1d, 0x29, 0x25, 0x12,
0x0e, 0x10, 0x13, 0x11, 0x17, 0x0e, 0x08, 0x10, 0x02, 0x0d, 0x23, 0x07, 0x12, 0x0d, 0x07, 0x23,
0x30, 0x09, 0x09, 0x04, 0x10, 0x09, 0x30, 0x0c, 0x03, 0x09, 0x12, 0x0f, 0x02, 0x0d, 0x23, 0x07,
0x12, 0x0d, 0x06, 0x24, 0x30, 0x09, 0x09, 0x04, 0x10, 0x09, 0x30, 0x0d, 0x02, 0x09, 0x90, 0x1d,
0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
0x01, 0xeb, 0x01, 0x81, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x25, 0x21, 0x11, 0x21, 0x35, 0x21,
0x22, 0x06, 0x15, 0x11, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x33, 0x35, 0x33, 0x32, 0x36, 0x35, 0x11,
0x34, 0x26, 0x01, 0xc0, 0xfe, 0x80, 0x01, 0x80, 0xfe, 0x80, 0x12, 0x19, 0x19, 0x12, 0x6b, 0xaa,
0x6b, 0x12, 0x19, 0x19, 0x55, 0x01, 0x00, 0x2b, 0x19, 0x12, 0xff, 0x00, 0x11, 0x19, 0x2b, 0x2b,
0x19, 0x11, 0x01, 0x00, 0x12, 0x19, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0x71, 0x01, 0x96,
0x00, 0x0f, 0x00, 0x18, 0x00, 0x00, 0x25, 0x35, 0x34, 0x26, 0x22, 0x06, 0x1d, 0x01, 0x0e, 0x01,
0x1e, 0x01, 0x32, 0x3e, 0x01, 0x26, 0x27, 0x32, 0x16, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, 0x01,
0x40, 0x25, 0x36, 0x25, 0x1c, 0x14, 0x16, 0x38, 0x44, 0x38, 0x16, 0x14, 0x5c, 0x09, 0x0c, 0x2a,
0x0c, 0xab, 0xaa, 0x1b, 0x25, 0x25, 0x1b, 0xaa, 0x15, 0x42, 0x41, 0x28, 0x28, 0x41, 0x42, 0xd5,
0x0d, 0x09, 0x40, 0x40, 0x09, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd6, 0x01, 0x40,
0x00, 0x0a, 0x00, 0x00, 0x25, 0x37, 0x27, 0x07, 0x27, 0x37, 0x17, 0x37, 0x17, 0x37, 0x15, 0x01,
0x55, 0x31, 0x68, 0x55, 0x9e, 0x1e, 0x80, 0x55, 0x86, 0x31, 0x40, 0x31, 0x68, 0x55, 0x9e, 0x1e,
0x80, 0x55, 0x86, 0x31, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd6, 0x01, 0x40,
0x00, 0x0a, 0x00, 0x00, 0x01, 0x17, 0x07, 0x27, 0x07, 0x17, 0x37, 0x17, 0x37, 0x17, 0x35, 0x01,
0x55, 0x31, 0x68, 0x55, 0x9e, 0x1e, 0x80, 0x55, 0x86, 0x31, 0x01, 0x40, 0x31, 0x68, 0x55, 0x9e,
0x1e, 0x80, 0x55, 0x86, 0x31, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0xeb, 0x01, 0x56,
0x00, 0x14, 0x00, 0x2a, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01,
0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x35, 0x23, 0x35, 0x34, 0x2e,
0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x33, 0x21, 0x32, 0x36, 0x34,
0x26, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a,
0x24, 0x32, 0x32, 0x24, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25,
0x1b, 0x01, 0x15, 0x12, 0x19, 0x19, 0x2b, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b,
0x23, 0x32, 0x46, 0x32, 0x80, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x19,
0x24, 0x19, 0x00, 0x05, 0x00, 0x00, 0xff, 0xff, 0x01, 0xeb, 0x01, 0x81, 0x00, 0x0b, 0x00, 0x17,
0x00, 0x3c, 0x00, 0x48, 0x00, 0x54, 0x00, 0x00, 0x37, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01,
0x22, 0x26, 0x34, 0x36, 0x21, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36,
0x25, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x37, 0x32, 0x16, 0x17,
0x23, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22,
0x06, 0x15, 0x14, 0x17, 0x23, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34,
0x36, 0x33, 0x21, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x40, 0xd5, 0x09,
0x0d, 0x0d, 0x09, 0xd5, 0x09, 0x0c, 0x0c, 0x01, 0x1e, 0x6b, 0x09, 0x0c, 0x0c, 0x09, 0x6b, 0x09,
0x0c, 0x0c, 0xfe, 0xc9, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x23,
0x32, 0x01, 0x2b, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25,
0x04, 0x2d, 0x29, 0x2b, 0x09, 0x0c, 0x0c, 0x09, 0x2b, 0x09, 0x0c, 0x0c, 0x74, 0x01, 0x15, 0x09,
0x0c, 0x0c, 0x09, 0xfe, 0xeb, 0x09, 0x0d, 0x0d, 0x80, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x0c,
0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x40, 0x1d, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x24, 0x01, 0x32,
0x23, 0x11, 0x19, 0x16, 0x1d, 0x31, 0x1c, 0x33, 0x26, 0x04, 0x25, 0x1b, 0x0b, 0x0a, 0x80, 0x0d,
0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x00,
0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x3d, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x00,
0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33,
0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b,
0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26,
0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x37, 0x32,
0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x27, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36,
0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e,
0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15, 0x12, 0x19, 0x19,
0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25, 0x70, 0x12, 0x19,
0x19, 0x23, 0x19, 0x19, 0x71, 0x0e, 0x12, 0x12, 0x1b, 0x13, 0x13, 0x48, 0x0d, 0x13, 0x13, 0x1a,
0x13, 0x13, 0x95, 0x0c, 0x12, 0x0c, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23,
0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04,
0x25, 0x35, 0x26, 0x55, 0x19, 0x23, 0x19, 0x19, 0x23, 0x19, 0x2b, 0x13, 0x1b, 0x12, 0x12, 0x1b,
0x13, 0x55, 0x13, 0x1a, 0x13, 0x13, 0x1a, 0x13, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb,
0x01, 0x96, 0x00, 0x36, 0x00, 0x3d, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33,
0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26,
0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22,
0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x3b, 0x01, 0x32, 0x16, 0x14, 0x06, 0x23, 0x37,
0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b,
0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15, 0x12,
0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25, 0x1b,
0x15, 0x09, 0x0d, 0x0d, 0x09, 0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x35, 0x6b, 0x1c, 0x31, 0x3a,
0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19,
0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x36, 0x13, 0x06, 0x11, 0x0c, 0x06, 0x0f, 0x27,
0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0x6b, 0x01, 0x96, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00,
0x01, 0x17, 0x23, 0x37, 0x17, 0x33, 0x15, 0x33, 0x15, 0x23, 0x35, 0x33, 0x01, 0x40, 0x2b, 0xd6,
0x2b, 0x2b, 0x2a, 0x40, 0xaa, 0x40, 0x01, 0x95, 0x95, 0x95, 0xaa, 0xd6, 0x2a, 0x2a, 0x00, 0x02,
0x00, 0x00, 0xff, 0xea, 0x01, 0x98, 0x01, 0x96, 0x00, 0x1d, 0x00, 0x23, 0x00, 0x00, 0x13, 0x07,
0x17, 0x07, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x23, 0x15, 0x33, 0x35, 0x23, 0x27,
0x36, 0x35, 0x34, 0x27, 0x37, 0x06, 0x16, 0x17, 0x37, 0x2e, 0x01, 0x07, 0x17, 0x07, 0x16, 0x3e,
0x01, 0x26, 0xe7, 0x23, 0x18, 0x44, 0x03, 0x11, 0x19, 0x13, 0x0e, 0x57, 0x4e, 0xd6, 0x56, 0x5f,
0x0a, 0x04, 0x44, 0x04, 0x1d, 0x1b, 0x5f, 0x1b, 0x3d, 0x18, 0x64, 0x23, 0x0b, 0x1a, 0x0e, 0x05,
0x01, 0x95, 0x35, 0x10, 0x65, 0x19, 0x12, 0x0f, 0x17, 0x04, 0x81, 0x2a, 0x2a, 0x90, 0x0c, 0x0f,
0x0a, 0x09, 0x65, 0x1b, 0x36, 0x12, 0x8e, 0x12, 0x06, 0x0e, 0x42, 0x36, 0x07, 0x05, 0x16, 0x1a,
0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0xc0, 0x01, 0x96, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x00,
0x13, 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x14, 0x16, 0x17, 0x15, 0x33, 0x35, 0x3e,
0x01, 0x3d, 0x01, 0x23, 0x17, 0x15, 0x33, 0x15, 0x33, 0x11, 0x22, 0x07, 0x0e, 0x01, 0xeb, 0x2b,
0x2b, 0x2a, 0x2b, 0x2e, 0x22, 0x35, 0x22, 0x2e, 0x2a, 0x6a, 0x36, 0x35, 0x1c, 0x1a, 0x17, 0x1e,
0x01, 0x00, 0x95, 0x95, 0x95, 0x95, 0x22, 0x31, 0x02, 0xc0, 0xc0, 0x02, 0x31, 0x22, 0x95, 0x55,
0xab, 0xaa, 0x01, 0xaa, 0x0d, 0x0d, 0x28, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81,
0x01, 0x70, 0x00, 0x16, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06,
0x15, 0x14, 0x1e, 0x01, 0x32, 0x3e, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x07,
0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, 0x35, 0x34, 0x37, 0x36,
0x37, 0x36, 0x37, 0x01, 0x00, 0x10, 0x11, 0x15, 0x11, 0x1a, 0x0d, 0x12, 0x22, 0x3b, 0x46, 0x3b,
0x22, 0x12, 0x0d, 0x1a, 0x11, 0x15, 0x11, 0x10, 0x01, 0x03, 0x10, 0x10, 0x14, 0x0e, 0x0f, 0x31,
0x48, 0x31, 0x0f, 0x0e, 0x14, 0x10, 0x10, 0x01, 0x70, 0x12, 0x15, 0x19, 0x19, 0x27, 0x1a, 0x27,
0x1f, 0x22, 0x3b, 0x23, 0x23, 0x3b, 0x22, 0x1f, 0x27, 0x1a, 0x27, 0x19, 0x19, 0x15, 0x31, 0x02,
0x03, 0x13, 0x16, 0x1e, 0x1e, 0x21, 0x12, 0x23, 0x32, 0x32, 0x23, 0x12, 0x21, 0x1e, 0x1e, 0x16,
0x13, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x80, 0x00, 0x0e, 0x00, 0x17,
0x00, 0x24, 0x00, 0x00, 0x01, 0x32, 0x16, 0x1d, 0x01, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x37,
0x35, 0x34, 0x36, 0x17, 0x22, 0x06, 0x1d, 0x01, 0x33, 0x35, 0x34, 0x26, 0x27, 0x07, 0x15, 0x33,
0x07, 0x17, 0x23, 0x35, 0x23, 0x37, 0x17, 0x06, 0x07, 0x01, 0x95, 0x12, 0x19, 0x15, 0x25, 0x35,
0x26, 0x16, 0x19, 0x11, 0x08, 0x0d, 0x2b, 0x0d, 0x9e, 0x6b, 0x98, 0x02, 0x02, 0xc2, 0x40, 0xd5,
0x5e, 0x10, 0x09, 0x01, 0x15, 0x19, 0x11, 0x91, 0x13, 0x37, 0x25, 0x25, 0x37, 0x13, 0x91, 0x11,
0x19, 0x15, 0x0d, 0x08, 0x16, 0x16, 0x08, 0x0d, 0x47, 0x60, 0xa7, 0x15, 0x16, 0xab, 0xc0, 0x54,
0x0f, 0x15, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0xee, 0x01, 0x56, 0x00, 0x3e, 0x00, 0x52,
0x00, 0x65, 0x00, 0x77, 0x00, 0x00, 0x25, 0x2e, 0x01, 0x2f, 0x01, 0x36, 0x37, 0x35, 0x06, 0x07,
0x06, 0x22, 0x27, 0x26, 0x27, 0x15, 0x16, 0x17, 0x07, 0x0e, 0x01, 0x07, 0x06, 0x17, 0x16, 0x17,
0x16, 0x37, 0x36, 0x37, 0x36, 0x27, 0x37, 0x16, 0x17, 0x15, 0x0e, 0x01, 0x15, 0x14, 0x17, 0x16,
0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x26, 0x27, 0x35, 0x36, 0x37, 0x17, 0x06, 0x17, 0x16, 0x17,
0x16, 0x37, 0x36, 0x37, 0x36, 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x37, 0x36, 0x3f,
0x01, 0x36, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x07, 0x17, 0x22, 0x27, 0x26, 0x2f, 0x01, 0x37,
0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x1f, 0x01, 0x07, 0x06, 0x07, 0x06, 0x37, 0x06, 0x27, 0x26,
0x2f, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x16, 0x1f, 0x01, 0x16, 0x07, 0x06, 0x01, 0xe1,
0x03, 0x11, 0x0c, 0x09, 0x10, 0x0d, 0x23, 0x33, 0x3b, 0x88, 0x3b, 0x33, 0x23, 0x0d, 0x10, 0x09,
0x0c, 0x11, 0x03, 0x0c, 0x03, 0x04, 0x24, 0x18, 0x15, 0x1e, 0x12, 0x07, 0x10, 0x09, 0x1a, 0x20,
0x0a, 0x0b, 0x0b, 0x10, 0x25, 0x19, 0x10, 0x17, 0x0b, 0x0a, 0x20, 0x1a, 0x09, 0x10, 0x07, 0x12,
0x1e, 0x15, 0x18, 0x23, 0x05, 0x03, 0xfe, 0x8f, 0x04, 0x03, 0x09, 0x0a, 0x0e, 0x0e, 0x13, 0x03,
0x02, 0x06, 0x03, 0x05, 0x07, 0x0a, 0x0d, 0x14, 0x04, 0x02, 0x02, 0x84, 0x0e, 0x09, 0x05, 0x03,
0x01, 0x01, 0x03, 0x05, 0x09, 0x1c, 0x09, 0x05, 0x03, 0x01, 0x01, 0x03, 0x05, 0x09, 0xac, 0x13,
0x14, 0x09, 0x06, 0x01, 0x05, 0x06, 0x0e, 0x13, 0x0c, 0x05, 0x02, 0x05, 0x04, 0x01, 0x02, 0xcd,
0x0d, 0x16, 0x07, 0x24, 0x05, 0x06, 0x2f, 0x13, 0x0b, 0x0d, 0x0d, 0x0b, 0x13, 0x2f, 0x06, 0x05,
0x24, 0x07, 0x16, 0x0d, 0x31, 0x21, 0x31, 0x09, 0x06, 0x12, 0x1a, 0x48, 0x1c, 0x17, 0x25, 0x04,
0x02, 0x26, 0x09, 0x1a, 0x0d, 0x32, 0x20, 0x2e, 0x16, 0x20, 0x4a, 0x0d, 0x1a, 0x09, 0x26, 0x02,
0x04, 0x25, 0x17, 0x1c, 0x48, 0x1a, 0x12, 0x06, 0x09, 0x31, 0x21, 0x1a, 0x0c, 0x0c, 0x1b, 0x10,
0x16, 0x03, 0x05, 0x31, 0x18, 0x17, 0x08, 0x09, 0x04, 0x06, 0x03, 0x05, 0x11, 0x09, 0x08, 0x6b,
0x19, 0x11, 0x1d, 0x19, 0x08, 0x09, 0x06, 0x09, 0x09, 0x06, 0x09, 0x08, 0x19, 0x1d, 0x11, 0x19,
0x15, 0x05, 0x2d, 0x17, 0x17, 0x08, 0x0a, 0x07, 0x0a, 0x04, 0x04, 0x0d, 0x07, 0x08, 0x18, 0x1c,
0x13, 0x1a, 0x00, 0x04, 0xff, 0xff, 0xff, 0xea, 0x02, 0x00, 0x01, 0x6b, 0x00, 0x22, 0x00, 0x2f,
0x00, 0x3c, 0x00, 0x52, 0x00, 0x00, 0x01, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x26, 0x2b,
0x01, 0x22, 0x06, 0x1d, 0x01, 0x22, 0x06, 0x1d, 0x01, 0x14, 0x16, 0x33, 0x15, 0x33, 0x35, 0x21,
0x15, 0x33, 0x35, 0x32, 0x36, 0x3d, 0x01, 0x34, 0x26, 0x27, 0x33, 0x32, 0x16, 0x1d, 0x01, 0x06,
0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, 0x07, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x16, 0x1d, 0x01, 0x23,
0x35, 0x34, 0x27, 0x05, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x3d, 0x01, 0x34, 0x36, 0x32, 0x16,
0x1d, 0x01, 0x21, 0x35, 0x34, 0x36, 0x32, 0x16, 0x15, 0x01, 0xc0, 0x26, 0x1a, 0x55, 0x19, 0x12,
0x12, 0x19, 0x55, 0x1a, 0x26, 0x1a, 0x26, 0x26, 0x1a, 0x2b, 0x01, 0x2a, 0x2b, 0x1a, 0x26, 0x26,
0xaf, 0x55, 0x09, 0x0c, 0x15, 0x6b, 0x0d, 0xb7, 0x0c, 0x09, 0x55, 0x09, 0x0d, 0x6b, 0x15, 0x01,
0x6a, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x12, 0x0c, 0x01, 0x56, 0x0c, 0x12, 0x0c, 0x01,
0x00, 0x2b, 0x1a, 0x26, 0x11, 0x11, 0x26, 0x1a, 0x2b, 0x26, 0x1a, 0x6b, 0x1a, 0x26, 0x2a, 0x2a,
0x2a, 0x2a, 0x26, 0x1a, 0x6b, 0x1a, 0x26, 0x40, 0x0d, 0x08, 0x3c, 0x13, 0x1c, 0x2b, 0x96, 0x08,
0x0d, 0x15, 0x08, 0x0d, 0x0d, 0x08, 0x96, 0x2b, 0x1c, 0x13, 0x9a, 0x08, 0x0d, 0x0d, 0x08, 0x6b,
0x09, 0x0c, 0x0c, 0x09, 0x55, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0x00, 0x05, 0x00, 0x00, 0xff, 0xe8,
0x01, 0xeb, 0x01, 0x96, 0x00, 0x08, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x28, 0x00, 0x4c, 0x00, 0x00,
0x25, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x32, 0x16, 0x27, 0x15, 0x14, 0x16, 0x33, 0x15, 0x36,
0x32, 0x17, 0x35, 0x32, 0x36, 0x3d, 0x01, 0x07, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26,
0x21, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x07, 0x22, 0x27, 0x06, 0x22, 0x26, 0x27,
0x06, 0x22, 0x27, 0x0e, 0x01, 0x22, 0x27, 0x06, 0x23, 0x22, 0x27, 0x1e, 0x01, 0x33, 0x32, 0x37,
0x15, 0x14, 0x16, 0x32, 0x36, 0x3d, 0x01, 0x16, 0x33, 0x32, 0x36, 0x37, 0x06, 0x01, 0x40, 0x25,
0x36, 0x25, 0x25, 0x36, 0x25, 0x80, 0x19, 0x12, 0x0b, 0x14, 0x0b, 0x12, 0x19, 0xeb, 0x1a, 0x26,
0x26, 0x35, 0x25, 0x25, 0x01, 0x3b, 0x1b, 0x25, 0x25, 0x35, 0x26, 0x26, 0x1a, 0x16, 0x13, 0x11,
0x22, 0x1f, 0x0a, 0x11, 0x2a, 0x11, 0x0a, 0x1f, 0x22, 0x11, 0x13, 0x16, 0x07, 0x0a, 0x11, 0x30,
0x1b, 0x2a, 0x21, 0x0c, 0x12, 0x0c, 0x21, 0x2a, 0x1b, 0x30, 0x11, 0x0a, 0xa9, 0x1b, 0x25, 0x25,
0x35, 0x26, 0x26, 0xd2, 0x15, 0x12, 0x19, 0x57, 0x02, 0x02, 0x57, 0x19, 0x12, 0x15, 0xc2, 0x25,
0x35, 0x26, 0x26, 0x35, 0x25, 0x25, 0x35, 0x26, 0x26, 0x35, 0x25, 0x95, 0x08, 0x08, 0x0f, 0x0d,
0x07, 0x07, 0x0d, 0x0f, 0x08, 0x08, 0x02, 0x15, 0x18, 0x1b, 0x30, 0x09, 0x0c, 0x0c, 0x09, 0x30,
0x1b, 0x18, 0x15, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x4e, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
0x00, 0x01, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e,
0x00, 0x2a, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
0x00, 0x05, 0x00, 0x16, 0x00, 0x38, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x26,
0x00, 0x4e, 0x00, 0x4d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61,
0x00, 0x6c, 0x00, 0x20, 0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e,
0x00, 0x20, 0x00, 0x49, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x52, 0x00, 0x65,
0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72,
0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30,
0x00, 0x4d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c,
0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x49, 0x00, 0x63,
0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x26,
0x00, 0x28, 0x00, 0x02, 0x44, 0x46, 0x4c, 0x54, 0x00, 0x0e, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x18,
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x0c, 0x12, 0x0c, 0x6a, 0x55, 0x95,
0x6a, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xe3, 0x01, 0xc6, 0x01, 0xab, 0x00, 0x09, 0x00, 0x13,
0x00, 0x2b, 0x00, 0x37, 0x00, 0x00, 0x01, 0x07, 0x17, 0x27, 0x07, 0x37, 0x27, 0x3f, 0x01, 0x1f,
0x01, 0x07, 0x17, 0x27, 0x07, 0x37, 0x27, 0x3f, 0x01, 0x17, 0x07, 0x36, 0x1e, 0x01, 0x07, 0x06,
0x07, 0x0e, 0x01, 0x2e, 0x02, 0x36, 0x37, 0x36, 0x37, 0x36, 0x1e, 0x01, 0x07, 0x06, 0x1e, 0x02,
0x17, 0x2e, 0x03, 0x27, 0x0e, 0x01, 0x1e, 0x02, 0x36, 0x01, 0x7b, 0x36, 0x13, 0x38, 0x38, 0x13,
0x36, 0x44, 0x17, 0x17, 0x8e, 0x23, 0x0d, 0x24, 0x25, 0x0d, 0x23, 0x2c, 0x0f, 0x0e, 0x04, 0x08,
0x11, 0x05, 0x05, 0x0b, 0x0c, 0x29, 0x6e, 0x6e, 0x52, 0x1c, 0x1c, 0x29, 0x0d, 0x0e, 0x08, 0x14,
0x0d, 0x01, 0x04, 0x1f, 0x45, 0x5a, 0x0c, 0x2e, 0x57, 0x44, 0x26, 0x02, 0x1e, 0x13, 0x18, 0x3f,
0x54, 0x56, 0x01, 0x69, 0x2a, 0x41, 0x27, 0x27, 0x41, 0x2a, 0x02, 0x40, 0x40, 0x96, 0x1a, 0x2b,
0x19, 0x19, 0x2b, 0x1a, 0x01, 0x2a, 0x2a, 0x6a, 0x01, 0x0e, 0x13, 0x08, 0x10, 0x0b, 0x29, 0x1d,
0x1d, 0x52, 0x6e, 0x6e, 0x29, 0x0d, 0x0a, 0x05, 0x06, 0x10, 0x09, 0x2e, 0x5a, 0x45, 0x20, 0x26,
0x02, 0x26, 0x44, 0x56, 0x2e, 0x21, 0x55, 0x54, 0x3f, 0x18, 0x13, 0x00, 0x00, 0x07, 0x00, 0x00,
0xff, 0xea, 0x01, 0xd6, 0x01, 0x9a, 0x00, 0x1b, 0x00, 0x29, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x3b,
0x00, 0x41, 0x00, 0x54, 0x00, 0x00, 0x01, 0x1e, 0x01, 0x07, 0x1e, 0x01, 0x1d, 0x01, 0x36, 0x33,
0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x2e, 0x01, 0x37, 0x3e,
0x02, 0x17, 0x26, 0x06, 0x07, 0x06, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x2e, 0x01, 0x37,
0x26, 0x27, 0x37, 0x17, 0x26, 0x07, 0x06, 0x07, 0x37, 0x17, 0x06, 0x17, 0x26, 0x27, 0x17, 0x07,
0x36, 0x05, 0x16, 0x17, 0x27, 0x37, 0x06, 0x05, 0x23, 0x35, 0x34, 0x26, 0x22, 0x06, 0x15, 0x23,
0x22, 0x06, 0x14, 0x16, 0x33, 0x21, 0x32, 0x36, 0x34, 0x26, 0x01, 0x10, 0x25, 0x26, 0x07, 0x14,
0x18, 0x0a, 0x0b, 0x1b, 0x25, 0x25, 0x1b, 0xfe, 0xeb, 0x23, 0x32, 0x32, 0x23, 0x06, 0x15, 0x0a,
0x0e, 0x0d, 0x33, 0x3e, 0x0c, 0x1d, 0x3a, 0x0c, 0x07, 0x01, 0x08, 0x12, 0x33, 0x1d, 0x16, 0x15,
0x01, 0x18, 0x0f, 0x11, 0x13, 0x36, 0x13, 0x11, 0xb3, 0x10, 0x0c, 0x03, 0x3f, 0x14, 0xec, 0x03,
0x06, 0x33, 0x2c, 0x04, 0xfe, 0xbf, 0x02, 0x06, 0x32, 0x2b, 0x03, 0x01, 0x56, 0x40, 0x32, 0x46,
0x32, 0x2b, 0x12, 0x19, 0x19, 0x12, 0x01, 0x15, 0x09, 0x0d, 0x0d, 0x01, 0x4b, 0x10, 0x48, 0x27,
0x12, 0x33, 0x1c, 0x04, 0x04, 0x26, 0x35, 0x25, 0x32, 0x46, 0x32, 0x1a, 0x42, 0x1f, 0x1d, 0x24,
0x07, 0x34, 0x0d, 0x16, 0x1c, 0x10, 0x23, 0x0f, 0x15, 0x19, 0x08, 0x15, 0x23, 0x57, 0x08, 0x03,
0x1c, 0x3d, 0x0d, 0x08, 0x0b, 0x0e, 0x3c, 0x0f, 0x06, 0x7e, 0x14, 0x10, 0x20, 0x2f, 0x14, 0x0b,
0x13, 0x11, 0x20, 0x2f, 0x16, 0xa4, 0x2b, 0x23, 0x32, 0x32, 0x23, 0x19, 0x24, 0x19, 0x0d, 0x12,
0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xef, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x0c, 0x00, 0x19,
0x00, 0x26, 0x00, 0x5f, 0x00, 0x00, 0x37, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f,
0x01, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e, 0x01,
0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e, 0x01, 0x37, 0x35, 0x34,
0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x31, 0x1e,
0x01, 0x0e, 0x01, 0x27, 0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e,
0x01, 0x17, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x31, 0x06, 0x2e, 0x01, 0x36, 0x37, 0x31,
0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0xc0, 0x08, 0x09, 0x02, 0x1c, 0x02, 0x0f, 0x11, 0x09, 0x03,
0x1b, 0x02, 0x0f, 0x5e, 0x09, 0x09, 0x03, 0x2c, 0x02, 0x0f, 0x11, 0x09, 0x02, 0x2c, 0x03, 0x0f,
0x5e, 0x08, 0x09, 0x02, 0x1c, 0x02, 0x0f, 0x12, 0x08, 0x02, 0x1c, 0x02, 0x0f, 0x09, 0x1d, 0x31,
0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x11, 0x0f, 0x08, 0x04, 0x09, 0x10, 0x08, 0x19,
0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x17, 0x14,
0x08, 0x11, 0x09, 0x05, 0x08, 0x09, 0x0c, 0x19, 0x12, 0xc0, 0x02, 0x10, 0x08, 0x67, 0x09, 0x08,
0x04, 0x0f, 0x09, 0x67, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0xa5, 0x09, 0x08, 0x04, 0x10, 0x08,
0xa5, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0x67, 0x09, 0x08, 0x04, 0x0f, 0x09, 0x67, 0x08, 0x09,
0x29, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e, 0x08, 0x04, 0x12, 0x0f,
0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x23, 0x18, 0x27,
0x0b, 0x04, 0x04, 0x10, 0x11, 0x04, 0x06, 0x13, 0x0c, 0x12, 0x19, 0x00, 0x00, 0x03, 0x00, 0x00,
0xff, 0xea, 0x01, 0xeb, 0x01, 0x95, 0x00, 0x34, 0x00, 0x40, 0x00, 0x54, 0x00, 0x00, 0x37, 0x32,
0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e,
0x01, 0x17, 0x37, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32,
0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22,
0x06, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, 0x35, 0x34, 0x3f, 0x01,
0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x16, 0x32, 0x36, 0x35, 0x34, 0x27, 0x2e,
0x01, 0x27, 0x31, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45,
0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15,
0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0b, 0x0c, 0x1b, 0x25, 0x25,
0x9b, 0x05, 0x07, 0x1f, 0x19, 0x24, 0x19, 0x1f, 0x0c, 0x0b, 0x0b, 0x0e, 0x0b, 0x12, 0x08, 0x0c,
0x32, 0x46, 0x32, 0x0c, 0x08, 0x24, 0x12, 0x95, 0x0d, 0x11, 0x0d, 0x1d, 0x31, 0x3a, 0x31, 0x1c,
0x27, 0x2f, 0x23, 0x3a, 0x24, 0x01, 0x32, 0x47, 0x32, 0x0d, 0x11, 0x0d, 0x19, 0x23, 0x19, 0x15,
0x1d, 0x31, 0x1d, 0x33, 0x26, 0x04, 0x26, 0x35, 0x25, 0x03, 0x07, 0x0a, 0x2b, 0x16, 0x12, 0x19,
0x19, 0x12, 0x16, 0x2b, 0x54, 0x0c, 0x0e, 0x11, 0x11, 0x19, 0x12, 0x19, 0x15, 0x23, 0x32, 0x32,
0x23, 0x15, 0x19, 0x12, 0x34, 0x15, 0x00, 0x02, 0x00, 0x00, 0xff, 0xd6, 0x01, 0xeb, 0x01, 0x96,
0x00, 0x34, 0x00, 0x5e, 0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34,
0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b,
0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e,
0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x37, 0x27, 0x26, 0x34,
0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37, 0x36, 0x1e, 0x01, 0x06,
0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01,
0x07, 0x06, 0x2e, 0x01, 0x36, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d,
0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c,
0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b,
0x25, 0x25, 0x43, 0x2f, 0x23, 0x06, 0x0d, 0x12, 0x06, 0x22, 0x0c, 0x03, 0x0f, 0x11, 0x09, 0x02,
0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x08, 0x2f, 0x23, 0x06, 0x0d, 0x12, 0x06, 0x22, 0x0c, 0x03,
0x0f, 0x11, 0x09, 0x02, 0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x95, 0x0c, 0x12, 0x0c, 0x1c, 0x31,
0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24,
0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x56, 0x0c, 0x22, 0x06, 0x12,
0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10, 0x08, 0x2f, 0x0d, 0x02, 0x09, 0x11, 0x0f, 0x03,
0x0c, 0x22, 0x06, 0x12, 0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10, 0x08, 0x2f, 0x0d, 0x02,
0x09, 0x11, 0x0f, 0x00, 0x00, 0x08, 0x00, 0x00, 0xff, 0xea, 0x01, 0xb9, 0x01, 0x96, 0x00, 0x0c,
0x00, 0x15, 0x00, 0x1a, 0x00, 0x1f, 0x00, 0x24, 0x00, 0x29, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x00,
0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x17, 0x22, 0x06,
0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x27, 0x17, 0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e, 0x01, 0x0f,
0x01, 0x37, 0x1e, 0x01, 0x17, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x17, 0x07, 0x3e, 0x01, 0x37, 0x07,
0x27, 0x16, 0x32, 0x37, 0x01, 0x00, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x1d, 0x31,
0x1d, 0x1b, 0x25, 0x25, 0x36, 0x25, 0x25, 0x1b, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a,
0x05, 0x25, 0x25, 0x05, 0x1a, 0x14, 0x01, 0x19, 0x26, 0x05, 0x1a, 0x14, 0x58, 0x58, 0x14, 0x1a,
0x05, 0x93, 0x33, 0x19, 0x33, 0x1a, 0x01, 0x2b, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x1d, 0x31, 0x3a,
0x31, 0x1d, 0x2b, 0x25, 0x36, 0x25, 0x25, 0x36, 0x25, 0x95, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11,
0x2c, 0x1b, 0x85, 0x51, 0x1a, 0x2d, 0x12, 0xde, 0x51, 0x1a, 0x2e, 0x10, 0xdd, 0x07, 0x11, 0x2d,
0x1a, 0xbb, 0x49, 0x09, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0xff, 0x01, 0xd6, 0x01, 0x96,
0x00, 0x13, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x39, 0x00, 0x00, 0x37, 0x33,
0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x15, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26,
0x34, 0x36, 0x21, 0x34, 0x26, 0x22, 0x06, 0x15, 0x37, 0x17, 0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e,
0x01, 0x07, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x03, 0x37, 0x36, 0x34, 0x26, 0x22, 0x0f, 0x01, 0x27,
0x26, 0x22, 0x06, 0x14, 0x1f, 0x01, 0x16, 0x32, 0x40, 0x55, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x55,
0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x01, 0x09, 0x25, 0x36, 0x25, 0x40, 0x33,
0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a, 0x05, 0x01, 0x4c, 0x26, 0x05, 0x1a, 0x14, 0x51, 0x42,
0x07, 0x0d, 0x11, 0x07, 0x33, 0x33, 0x07, 0x11, 0x0d, 0x07, 0x42, 0x07, 0x10, 0xc0, 0x1d, 0x31,
0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x1b, 0x25, 0x25, 0x1b, 0xd5, 0x49,
0x09, 0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x51, 0x51, 0x1a, 0x2e, 0x10, 0xfe, 0xd4, 0x43, 0x06,
0x12, 0x0c, 0x06, 0x34, 0x34, 0x06, 0x0c, 0x12, 0x06, 0x43, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00,
0xff, 0xfd, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x13, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28,
0x00, 0x39, 0x00, 0x00, 0x37, 0x33, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x15, 0x33, 0x32, 0x16,
0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x21, 0x34, 0x26, 0x22, 0x06, 0x15, 0x37, 0x17,
0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e, 0x01, 0x07, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x07, 0x17, 0x16,
0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x06, 0x22, 0x26, 0x34, 0x3f, 0x01, 0x36, 0x32, 0x40, 0x55,
0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x01,
0x09, 0x25, 0x36, 0x25, 0x40, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a, 0x05, 0x01, 0x4c,
0x26, 0x05, 0x1a, 0x14, 0x51, 0x42, 0x07, 0x0d, 0x11, 0x07, 0x33, 0x33, 0x07, 0x11, 0x0d, 0x07,
0x42, 0x07, 0x10, 0xc0, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c,
0x1b, 0x25, 0x25, 0x1b, 0xd5, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x51, 0x51, 0x1a,
0x2e, 0x10, 0xce, 0x42, 0x06, 0x12, 0x0c, 0x06, 0x33, 0x33, 0x06, 0x0c, 0x12, 0x06, 0x42, 0x07,
0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x17, 0x00, 0x2e, 0x00, 0x45,
0x00, 0x00, 0x37, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x22, 0x07, 0x06,
0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x17, 0x32, 0x36, 0x34, 0x26, 0x22,
0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36,
0x33, 0x05, 0x21, 0x22, 0x26, 0x34, 0x36, 0x33, 0x21, 0x32, 0x16, 0x14, 0x06, 0x22, 0x27, 0x26,
0x34, 0x36, 0x32, 0x16, 0x32, 0x36, 0x34, 0x26, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xab, 0x12, 0x19,
0x19, 0x24, 0x0c, 0x06, 0x12, 0x0d, 0x07, 0x19, 0x46, 0x32, 0x32, 0x23, 0x95, 0x09, 0x0d, 0x0d,
0x12, 0x0c, 0x12, 0x0c, 0x06, 0x13, 0x35, 0x25, 0x25, 0x1b, 0xfe, 0xd6, 0x09, 0x0d, 0x0d, 0x09,
0x01, 0x15, 0xfe, 0xd5, 0x09, 0x0c, 0x0c, 0x09, 0x01, 0x2b, 0x1b, 0x25, 0x25, 0x35, 0x13, 0x06,
0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x0c, 0xeb, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x0d, 0x06, 0x0c,
0x12, 0x06, 0x19, 0x32, 0x46, 0x32, 0x2b, 0x0c, 0x12, 0x0d, 0x0d, 0x0d, 0x11, 0x07, 0x12, 0x25,
0x35, 0x26, 0x0d, 0x12, 0x0c, 0x80, 0x0c, 0x12, 0x0d, 0x26, 0x35, 0x25, 0x12, 0x07, 0x11, 0x0d,
0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x04, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x03,
0x00, 0x07, 0x00, 0x18, 0x00, 0x25, 0x00, 0x00, 0x37, 0x33, 0x15, 0x23, 0x35, 0x33, 0x15, 0x23,
0x37, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x34, 0x2e, 0x02, 0x03, 0x22,
0x2e, 0x01, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0xeb, 0x2a, 0x2a, 0x2a, 0x2a,
0x15, 0x3a, 0x62, 0x39, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20, 0x20, 0x3c, 0x4f, 0x2a, 0x2e,
0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x80, 0x2b, 0xd6, 0x80, 0xea, 0x39, 0x62,
0x3a, 0x2a, 0x4f, 0x3c, 0x20, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20, 0xfe, 0x80, 0x2e, 0x4f,
0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb,
0x01, 0x96, 0x00, 0x34, 0x00, 0x3b, 0x00, 0x49, 0x00, 0x00, 0x37, 0x1e, 0x01, 0x0e, 0x01, 0x27,
0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32,
0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35,
0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x37,
0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x17, 0x14, 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x37, 0x31,
0x17, 0x16, 0x17, 0x16, 0x60, 0x08, 0x04, 0x09, 0x10, 0x08, 0x19, 0x1d, 0x1d, 0x31, 0x1d, 0x10,
0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09, 0x0c, 0x0c, 0x09, 0x12,
0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x11, 0x0f,
0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x36, 0xe0, 0x1c, 0x28, 0x1c, 0x18, 0x0c, 0x0c, 0x0d, 0x0e,
0x09, 0x0c, 0x9e, 0x04, 0x12, 0x0f, 0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22,
0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33,
0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e, 0x08, 0x37, 0x55, 0x95, 0x6a, 0x23, 0x15, 0x1d, 0x1d, 0x29,
0x25, 0x12, 0x0e, 0x10, 0x13, 0x11, 0x17, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0xfd, 0x01, 0xeb,
0x01, 0x96, 0x00, 0x0d, 0x00, 0x38, 0x00, 0x6a, 0x00, 0x00, 0x25, 0x14, 0x06, 0x22, 0x26, 0x34,
0x37, 0x36, 0x37, 0x31, 0x17, 0x16, 0x17, 0x16, 0x25, 0x26, 0x36, 0x3f, 0x01, 0x27, 0x26, 0x34,
0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37, 0x36, 0x1e, 0x01, 0x06,
0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01,
0x07, 0x06, 0x26, 0x27, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33,
0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01,
0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x17, 0x16, 0x14,
0x06, 0x22, 0x27, 0x2e, 0x01, 0x01, 0x8b, 0x1c, 0x28, 0x1c, 0x18, 0x0c, 0x0c, 0x0c, 0x0e, 0x09,
0x0d, 0xfe, 0xca, 0x02, 0x09, 0x09, 0x30, 0x23, 0x07, 0x0d, 0x13, 0x06, 0x23, 0x0d, 0x02, 0x10,
0x11, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x10, 0x05, 0x09, 0x09, 0x30, 0x23, 0x06, 0x0d, 0x12, 0x06,
0x23, 0x0d, 0x03, 0x0f, 0x12, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x0f, 0x43, 0x1d, 0x31, 0x1d, 0x10,
0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09, 0x0c, 0x0c, 0x09, 0x12,
0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x13, 0x06,
0x0c, 0x12, 0x06, 0x0f, 0x11, 0x32, 0x15, 0x1d, 0x1d, 0x29, 0x25, 0x12, 0x0e, 0x10, 0x13, 0x11,
0x17, 0x0e, 0x08, 0x10, 0x02, 0x0d, 0x23, 0x07, 0x12, 0x0d, 0x07, 0x23, 0x30, 0x09, 0x09, 0x04,
0x10, 0x09, 0x30, 0x0c, 0x03, 0x09, 0x12, 0x0f, 0x02, 0x0d, 0x23, 0x07, 0x12, 0x0d, 0x06, 0x24,
0x30, 0x09, 0x09, 0x04, 0x10, 0x09, 0x30, 0x0d, 0x02, 0x09, 0x90, 0x1d, 0x31, 0x1d, 0x26, 0x2f,
0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d,
0x33, 0x27, 0x04, 0x25, 0x36, 0x13, 0x06, 0x11, 0x0c, 0x06, 0x0f, 0x27, 0x00, 0x02, 0x00, 0x00,
0xff, 0xea, 0x01, 0x6b, 0x01, 0x96, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x17, 0x23, 0x37,
0x17, 0x33, 0x15, 0x33, 0x15, 0x23, 0x35, 0x33, 0x01, 0x40, 0x2b, 0xd6, 0x2b, 0x2b, 0x2a, 0x40,
0xaa, 0x40, 0x01, 0x95, 0x95, 0x95, 0xaa, 0xd6, 0x2a, 0x2a, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea,
0x01, 0x98, 0x01, 0x96, 0x00, 0x1d, 0x00, 0x23, 0x00, 0x00, 0x13, 0x07, 0x17, 0x07, 0x23, 0x22,
0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x23, 0x15, 0x33, 0x35, 0x23, 0x27, 0x36, 0x35, 0x34, 0x27,
0x37, 0x06, 0x16, 0x17, 0x37, 0x2e, 0x01, 0x07, 0x17, 0x07, 0x16, 0x3e, 0x01, 0x26, 0xe7, 0x23,
0x18, 0x44, 0x03, 0x11, 0x19, 0x13, 0x0e, 0x57, 0x4e, 0xd6, 0x56, 0x5f, 0x0a, 0x04, 0x44, 0x04,
0x1d, 0x1b, 0x5f, 0x1b, 0x3d, 0x18, 0x64, 0x23, 0x0b, 0x1a, 0x0e, 0x05, 0x01, 0x95, 0x35, 0x10,
0x65, 0x19, 0x12, 0x0f, 0x17, 0x04, 0x81, 0x2a, 0x2a, 0x90, 0x0c, 0x0f, 0x0a, 0x09, 0x65, 0x1b,
0x36, 0x12, 0x8e, 0x12, 0x06, 0x0e, 0x42, 0x36, 0x07, 0x05, 0x16, 0x1a, 0x00, 0x02, 0x00, 0x00,
0xff, 0xea, 0x01, 0xc0, 0x01, 0x96, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x00, 0x13, 0x23, 0x35, 0x23,
0x15, 0x23, 0x35, 0x23, 0x15, 0x14, 0x16, 0x17, 0x15, 0x33, 0x35, 0x3e, 0x01, 0x3d, 0x01, 0x23,
0x17, 0x15, 0x33, 0x15, 0x33, 0x11, 0x22, 0x07, 0x0e, 0x01, 0xeb, 0x2b, 0x2b, 0x2a, 0x2b, 0x2e,
0x22, 0x35, 0x22, 0x2e, 0x2a, 0x6a, 0x36, 0x35, 0x1c, 0x1a, 0x17, 0x1e, 0x01, 0x00, 0x95, 0x95,
0x95, 0x95, 0x22, 0x31, 0x02, 0xc0, 0xc0, 0x02, 0x31, 0x22, 0x95, 0x55, 0xab, 0xaa, 0x01, 0xaa,
0x0d, 0x0d, 0x28, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x01, 0x70, 0x00, 0x16,
0x00, 0x2a, 0x00, 0x00, 0x01, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x1e, 0x01,
0x32, 0x3e, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x07, 0x16, 0x17, 0x16, 0x17,
0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x01,
0x00, 0x10, 0x11, 0x15, 0x11, 0x1a, 0x0d, 0x12, 0x22, 0x3b, 0x46, 0x3b, 0x22, 0x12, 0x0d, 0x1a,
0x11, 0x15, 0x11, 0x10, 0x01, 0x03, 0x10, 0x10, 0x14, 0x0e, 0x0f, 0x31, 0x48, 0x31, 0x0f, 0x0e,
0x14, 0x10, 0x10, 0x01, 0x70, 0x12, 0x15, 0x19, 0x19, 0x27, 0x1a, 0x27, 0x1f, 0x22, 0x3b, 0x23,
0x23, 0x3b, 0x22, 0x1f, 0x27, 0x1a, 0x27, 0x19, 0x19, 0x15, 0x31, 0x02, 0x03, 0x13, 0x16, 0x1e,
0x1e, 0x21, 0x12, 0x23, 0x32, 0x32, 0x23, 0x12, 0x21, 0x1e, 0x1e, 0x16, 0x13, 0x00, 0x00, 0x03,
0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x80, 0x00, 0x0e, 0x00, 0x17, 0x00, 0x24, 0x00, 0x00,
0x01, 0x32, 0x16, 0x1d, 0x01, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x37, 0x35, 0x34, 0x36, 0x17,
0x22, 0x06, 0x1d, 0x01, 0x33, 0x35, 0x34, 0x26, 0x27, 0x07, 0x15, 0x33, 0x07, 0x17, 0x23, 0x35,
0x23, 0x37, 0x17, 0x06, 0x07, 0x01, 0x95, 0x12, 0x19, 0x15, 0x25, 0x35, 0x26, 0x16, 0x19, 0x11,
0x08, 0x0d, 0x2b, 0x0d, 0x9e, 0x6b, 0x98, 0x02, 0x02, 0xc2, 0x40, 0xd5, 0x5e, 0x10, 0x09, 0x01,
0x15, 0x19, 0x11, 0x91, 0x13, 0x37, 0x25, 0x25, 0x37, 0x13, 0x91, 0x11, 0x19, 0x15, 0x0d, 0x08,
0x16, 0x16, 0x08, 0x0d, 0x47, 0x60, 0xa7, 0x15, 0x16, 0xab, 0xc0, 0x54, 0x0f, 0x15, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x01, 0xee, 0x01, 0x56, 0x00, 0x3e, 0x00, 0x52, 0x00, 0x65, 0x00, 0x77,
0x00, 0x00, 0x25, 0x2e, 0x01, 0x2f, 0x01, 0x36, 0x37, 0x35, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26,
0x27, 0x15, 0x16, 0x17, 0x07, 0x0e, 0x01, 0x07, 0x06, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37,
0x36, 0x27, 0x37, 0x16, 0x17, 0x15, 0x0e, 0x01, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36,
0x35, 0x34, 0x26, 0x27, 0x35, 0x36, 0x37, 0x17, 0x06, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37,
0x36, 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x37, 0x36,
0x17, 0x16, 0x17, 0x16, 0x07, 0x17, 0x22, 0x27, 0x26, 0x2f, 0x01, 0x37, 0x36, 0x37, 0x36, 0x32,
0x17, 0x16, 0x1f, 0x01, 0x07, 0x06, 0x07, 0x06, 0x37, 0x06, 0x27, 0x26, 0x2f, 0x01, 0x34, 0x37,
0x36, 0x37, 0x36, 0x17, 0x16, 0x1f, 0x01, 0x16, 0x07, 0x06, 0x01, 0xe1, 0x03, 0x11, 0x0c, 0x09,
0x10, 0x0d, 0x23, 0x33, 0x3b, 0x88, 0x3b, 0x33, 0x23, 0x0d, 0x10, 0x09, 0x0c, 0x11, 0x03, 0x0c,
0x03, 0x04, 0x24, 0x18, 0x15, 0x1e, 0x12, 0x07, 0x10, 0x09, 0x1a, 0x20, 0x0a, 0x0b, 0x0b, 0x10,
0x25, 0x19, 0x10, 0x17, 0x0b, 0x0a, 0x20, 0x1a, 0x09, 0x10, 0x07, 0x12, 0x1e, 0x15, 0x18, 0x23,
0x05, 0x03, 0xfe, 0x8f, 0x04, 0x03, 0x09, 0x0a, 0x0e, 0x0e, 0x13, 0x03, 0x02, 0x06, 0x03, 0x05,
0x07, 0x0a, 0x0d, 0x14, 0x04, 0x02, 0x02, 0x84, 0x0e, 0x09, 0x05, 0x03, 0x01, 0x01, 0x03, 0x05,
0x09, 0x1c, 0x09, 0x05, 0x03, 0x01, 0x01, 0x03, 0x05, 0x09, 0xac, 0x13, 0x14, 0x09, 0x06, 0x01,
0x05, 0x06, 0x0e, 0x13, 0x0c, 0x05, 0x02, 0x05, 0x04, 0x01, 0x02, 0xcd, 0x0d, 0x16, 0x07, 0x24,
0x05, 0x06, 0x2f, 0x13, 0x0b, 0x0d, 0x0d, 0x0b, 0x13, 0x2f, 0x06, 0x05, 0x24, 0x07, 0x16, 0x0d,
0x31, 0x21, 0x31, 0x09, 0x06, 0x12, 0x1a, 0x48, 0x1c, 0x17, 0x25, 0x04, 0x02, 0x26, 0x09, 0x1a,
0x0d, 0x32, 0x20, 0x2e, 0x16, 0x20, 0x4a, 0x0d, 0x1a, 0x09, 0x26, 0x02, 0x04, 0x25, 0x17, 0x1c,
0x48, 0x1a, 0x12, 0x06, 0x09, 0x31, 0x21, 0x1a, 0x0c, 0x0c, 0x1b, 0x10, 0x16, 0x03, 0x05, 0x31,
0x18, 0x17, 0x08, 0x09, 0x04, 0x06, 0x03, 0x05, 0x11, 0x09, 0x08, 0x6b, 0x19, 0x11, 0x1d, 0x19,
0x08, 0x09, 0x06, 0x09, 0x09, 0x06, 0x09, 0x08, 0x19, 0x1d, 0x11, 0x19, 0x15, 0x05, 0x2d, 0x17,
0x17, 0x08, 0x0a, 0x07, 0x0a, 0x04, 0x04, 0x0d, 0x07, 0x08, 0x18, 0x1c, 0x13, 0x1a, 0x00, 0x04,
0xff, 0xff, 0xff, 0xea, 0x02, 0x00, 0x01, 0x6b, 0x00, 0x22, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x52,
0x00, 0x00, 0x01, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x26, 0x2b, 0x01, 0x22, 0x06, 0x1d,
0x01, 0x22, 0x06, 0x1d, 0x01, 0x14, 0x16, 0x33, 0x15, 0x33, 0x35, 0x21, 0x15, 0x33, 0x35, 0x32,
0x36, 0x3d, 0x01, 0x34, 0x26, 0x27, 0x33, 0x32, 0x16, 0x1d, 0x01, 0x06, 0x1d, 0x01, 0x23, 0x35,
0x34, 0x36, 0x07, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x16, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x27, 0x05,
0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x3d, 0x01, 0x34, 0x36, 0x32, 0x16, 0x1d, 0x01, 0x21, 0x35,
0x34, 0x36, 0x32, 0x16, 0x15, 0x01, 0xc0, 0x26, 0x1a, 0x55, 0x19, 0x12, 0x12, 0x19, 0x55, 0x1a,
0x26, 0x1a, 0x26, 0x26, 0x1a, 0x2b, 0x01, 0x2a, 0x2b, 0x1a, 0x26, 0x26, 0xaf, 0x55, 0x09, 0x0c,
0x15, 0x6b, 0x0d, 0xb7, 0x0c, 0x09, 0x55, 0x09, 0x0d, 0x6b, 0x15, 0x01, 0x6a, 0x0c, 0x09, 0xfe,
0x80, 0x09, 0x0c, 0x0c, 0x12, 0x0c, 0x01, 0x56, 0x0c, 0x12, 0x0c, 0x01, 0x00, 0x2b, 0x1a, 0x26,
0x11, 0x11, 0x26, 0x1a, 0x2b, 0x26, 0x1a, 0x6b, 0x1a, 0x26, 0x2a, 0x2a, 0x2a, 0x2a, 0x26, 0x1a,
0x6b, 0x1a, 0x26, 0x40, 0x0d, 0x08, 0x3c, 0x13, 0x1c, 0x2b, 0x96, 0x08, 0x0d, 0x15, 0x08, 0x0d,
0x0d, 0x08, 0x96, 0x2b, 0x1c, 0x13, 0x9a, 0x08, 0x0d, 0x0d, 0x08, 0x6b, 0x09, 0x0c, 0x0c, 0x09,
0x55, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0x00, 0x05, 0x00, 0x00, 0xff, 0xe8, 0x01, 0xeb, 0x01, 0x96,
0x00, 0x08, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x28, 0x00, 0x4c, 0x00, 0x00, 0x25, 0x14, 0x06, 0x22,
0x26, 0x34, 0x36, 0x32, 0x16, 0x27, 0x15, 0x14, 0x16, 0x33, 0x15, 0x36, 0x32, 0x17, 0x35, 0x32,
0x36, 0x3d, 0x01, 0x07, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x21, 0x22, 0x06, 0x14,
0x16, 0x32, 0x36, 0x34, 0x26, 0x07, 0x22, 0x27, 0x06, 0x22, 0x26, 0x27, 0x06, 0x22, 0x27, 0x0e,
0x01, 0x22, 0x27, 0x06, 0x23, 0x22, 0x27, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x15, 0x14, 0x16, 0x32,
0x36, 0x3d, 0x01, 0x16, 0x33, 0x32, 0x36, 0x37, 0x06, 0x01, 0x40, 0x25, 0x36, 0x25, 0x25, 0x36,
0x25, 0x80, 0x19, 0x12, 0x0b, 0x14, 0x0b, 0x12, 0x19, 0xeb, 0x1a, 0x26, 0x26, 0x35, 0x25, 0x25,
0x01, 0x3b, 0x1b, 0x25, 0x25, 0x35, 0x26, 0x26, 0x1a, 0x16, 0x13, 0x11, 0x22, 0x1f, 0x0a, 0x11,
0x2a, 0x11, 0x0a, 0x1f, 0x22, 0x11, 0x13, 0x16, 0x07, 0x0a, 0x11, 0x30, 0x1b, 0x2a, 0x21, 0x0c,
0x12, 0x0c, 0x21, 0x2a, 0x1b, 0x30, 0x11, 0x0a, 0xa9, 0x1b, 0x25, 0x25, 0x35, 0x26, 0x26, 0xd2,
0x15, 0x12, 0x19, 0x57, 0x02, 0x02, 0x57, 0x19, 0x12, 0x15, 0xc2, 0x25, 0x35, 0x26, 0x26, 0x35,
0x25, 0x25, 0x35, 0x26, 0x26, 0x35, 0x25, 0x95, 0x08, 0x08, 0x0f, 0x0d, 0x07, 0x07, 0x0d, 0x0f,
0x08, 0x08, 0x02, 0x15, 0x18, 0x1b, 0x30, 0x09, 0x0c, 0x0c, 0x09, 0x30, 0x1b, 0x18, 0x15, 0x02,
0x00, 0x00, 0x00, 0x06, 0x00, 0x4e, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x2a,
0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x03,
0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09,
0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x16,
0x00, 0x38, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x26, 0x00, 0x4e, 0x00, 0x4d,
0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20,
0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x49,
0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75,
0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69,
0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x4d, 0x00, 0x61,
0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x44, 0x00, 0x65,
0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x49, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e,
0x00, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x26, 0x00, 0x28, 0x00, 0x02,
0x44, 0x46, 0x4c, 0x54, 0x00, 0x0e, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
+1 -1
View File
@@ -4,7 +4,7 @@
#include <stdbool.h>
#include "esp_err.h"
/* Calls lv_init() and creates the LVGL mutex. Must run before display_init()
/* Calls lv_init() and creates the LVGL mutex. Must run before display_start()
* and touch_init(), which register themselves with LVGL. */
esp_err_t lvgl_port_init(void);
+3
View File
@@ -35,6 +35,9 @@ extern const size_t icon_font_data_size;
#define ICON_SUNRISE "\xf3\xb0\x96\x9c" /* U+F059C */
#define ICON_SUNSET "\xf3\xb0\x96\x9b" /* U+F059B */
#define ICON_GAUGE "\xf3\xb0\x8a\x9a" /* U+F029A */
#define ICON_TREND_UP "\xf3\xb0\x94\xb5" /* U+F0535 */
#define ICON_TREND_DOWN "\xf3\xb0\x94\xb3" /* U+F0533 */
#define ICON_TV "\xf3\xb0\x94\x82" /* U+F0502 */
#define ICON_SOFA "\xf3\xb1\x95\xad" /* U+F156D */
#define ICON_DINING "\xf3\xb0\xa9\xb0" /* U+F0A70 */
#define ICON_FLOOR_LAMP "\xf3\xb0\xa3\x9d" /* U+F08DD */
+173 -13
View File
@@ -109,6 +109,7 @@ static lv_obj_t *cond_icon;
static lv_obj_t *temp_label;
static lv_obj_t *temp_unit_label;
static lv_obj_t *indoor_detail_label;
static lv_obj_t *trend_indoor_icon;
/* 3x2 reading grid: value and caption per cell. */
enum {
@@ -122,6 +123,8 @@ enum {
};
static lv_obj_t *cell_value[CELL_COUNT];
static lv_obj_t *cell_sub[CELL_COUNT];
/* Trend arrows; only the outdoor and pressure slots are created. */
static lv_obj_t *cell_trend[CELL_COUNT];
static lv_obj_t *light_tile[HA_LIGHT_COUNT];
static lv_obj_t *light_icon[HA_LIGHT_COUNT];
@@ -170,6 +173,41 @@ typedef struct {
} light_hold_t;
static light_hold_t light_hold[HA_LIGHT_COUNT];
/* Slider press bookkeeping: whether the press-down command has been sent for
* the current touch, and at what percentage, so the release command can be
* skipped when the finger never moved. */
static bool slider_touched[HA_LIGHT_COUNT];
static int32_t slider_sent_pct[HA_LIGHT_COUNT];
/*
* One-shot "repair" repaint, rescheduled by every interaction to fire 600ms
* after the last one.
*
* Redrawing is itself what glitches the panel: the flush's PSRAM writes
* contend with the LCD's scan-out, and a burst of interactive redraws is the
* most likely moment for the bounce ISR to lose (README, PSRAM bandwidth).
* The glitched lines then persist because LVGL believes those pixels are
* fine. One full repaint after the burst settles cleans them up within
* ~0.6s instead of leaving them until the next poll's repaint, up to 60s
* away. It runs once per burst, not periodically -- a constant repaint loop
* would be a constant supply of fresh glitch opportunities.
*/
static lv_timer_t *repair_timer;
static void repair_timer_cb(lv_timer_t *t)
{
lv_obj_invalidate(lv_screen_active());
lv_timer_pause(t);
}
static void schedule_repair(void)
{
if (repair_timer != NULL) {
lv_timer_reset(repair_timer);
lv_timer_resume(repair_timer);
}
}
/* --------------------------------------------------------- condition icons */
typedef struct {
@@ -284,6 +322,32 @@ static lv_obj_t *icon_create(lv_obj_t *parent, const char *glyph,
return l;
}
/*
* Trend arrow: up warm, down blue, nothing for flat or unknown. "No arrow"
* covers both "steady" and "not enough history yet" -- a reading that is
* going nowhere and a reading we cannot judge should both look calm.
*/
static void trend_render(lv_obj_t *icon, ha_trend_t t)
{
if (icon == NULL || icon_font_16 == NULL) {
return;
}
switch (t) {
case HA_TREND_RISING:
label_set_if_changed(icon, ICON_TREND_UP);
lv_obj_set_style_text_color(icon, lv_color_hex(COL_ACCENT_WARM), LV_PART_MAIN);
break;
case HA_TREND_FALLING:
label_set_if_changed(icon, ICON_TREND_DOWN);
lv_obj_set_style_text_color(icon, lv_color_hex(COL_ACCENT), LV_PART_MAIN);
break;
default:
label_set_if_changed(icon, "");
break;
}
}
/* ------------------------------------------------------------ light tiles */
static void light_tile_update(int idx, const ha_light_status_t *st);
@@ -341,6 +405,7 @@ static void light_tile_clicked(lv_event_t *e)
: -1,
};
light_apply_optimistic(idx, expect);
schedule_repair();
/* -1: a tap is on/off only. Brightness is the slider's job, and sending
* the current brightness here would fight a user who dimmed the light
@@ -348,6 +413,68 @@ static void light_tile_clicked(lv_event_t *e)
light_cb(idx, turn_on, -1);
}
/* One command for a slider position. Dragging to zero means off, not "on at
* zero brightness" -- HA accepts brightness 0 but leaves the light on, which
* looks like a bug. */
static void light_send_pct(int idx, int32_t pct)
{
if (pct <= 0) {
light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_OFF, -1 });
light_cb(idx, false, -1);
} else {
const int16_t brightness = (int16_t)((pct * 255) / 100);
light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_ON, brightness });
light_cb(idx, true, brightness);
}
slider_sent_pct[idx] = pct;
}
/*
* Fires as the knob moves under a finger (programmatic set_value does not
* raise VALUE_CHANGED, so this is user input only). Two jobs:
*
* - keep the tile's readout live under the finger ("On 43%" tracks the
* drag), because the screen must follow the finger, never the light;
* - send ONE command at the first touch position, so the light comes on
* at the level the finger landed on without waiting for the lift.
*
* Everything between first touch and lift is display-only.
*/
static void light_slider_changed(lv_event_t *e)
{
const int idx = (int)(intptr_t)lv_event_get_user_data(e);
if (idx < 0 || idx >= HA_LIGHT_COUNT) {
return;
}
lv_obj_t *slider = lv_event_get_target_obj(e);
const int32_t pct = lv_slider_get_value(slider);
char buf[24];
if (pct <= 0) {
snprintf(buf, sizeof(buf), "Off");
} else {
snprintf(buf, sizeof(buf), "On %d%%", (int)pct);
}
label_set_if_changed(light_state[idx], buf);
lv_obj_set_style_text_color(light_state[idx],
lv_color_hex(pct > 0 ? COL_ON : COL_TEXT_DIM),
LV_PART_MAIN);
schedule_repair();
if (light_cb == NULL || !lv_obj_has_state(slider, LV_STATE_PRESSED)) {
return;
}
if (!slider_touched[idx]) {
slider_touched[idx] = true;
light_send_pct(idx, pct);
}
}
/* Finger lifted: send the final position -- unless the finger never moved
* from where the press-down command already put it. */
static void light_slider_released(lv_event_t *e)
{
const int idx = (int)(intptr_t)lv_event_get_user_data(e);
@@ -358,17 +485,16 @@ static void light_slider_released(lv_event_t *e)
lv_obj_t *slider = lv_event_get_target_obj(e);
const int32_t pct = lv_slider_get_value(slider);
/* Dragging to zero means off, not "on at zero brightness" -- HA accepts
* brightness 0 but leaves the light on, which looks like a bug. */
if (pct <= 0) {
light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_OFF, -1 });
light_cb(idx, false, -1);
return;
const bool touched = slider_touched[idx];
slider_touched[idx] = false;
schedule_repair();
if (touched && pct == slider_sent_pct[idx]) {
return; /* tap without drag: the press command already said this */
}
const int16_t brightness = (int16_t)((pct * 255) / 100);
light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_ON, brightness });
light_cb(idx, true, brightness);
light_send_pct(idx, pct);
}
static void light_tile_build(lv_obj_t *parent, int idx, int32_t w, int32_t h)
@@ -430,11 +556,15 @@ static void light_tile_build(lv_obj_t *parent, int idx, int32_t w, int32_t h)
lv_obj_set_style_pad_all(s, 2, LV_PART_KNOB);
/*
* RELEASED only: the command is sent when the finger lifts, once.
* VALUE_CHANGED fires per pixel of drag and would queue a command
* storm; it is also why ui_update never writes to a pressed slider
* -- nothing may move the knob out from under the finger.
* Two commands per touch, not per pixel: VALUE_CHANGED sends one at
* the first touch position (light responds immediately where the
* finger lands), RELEASED sends the final position. In between, the
* drag only updates the display -- and ui_update never writes to a
* pressed slider, so nothing moves the knob out from under the
* finger.
*/
lv_obj_add_event_cb(s, light_slider_changed, LV_EVENT_VALUE_CHANGED,
(void *)(intptr_t)idx);
lv_obj_add_event_cb(s, light_slider_released, LV_EVENT_RELEASED,
(void *)(intptr_t)idx);
light_slider[idx] = s;
@@ -492,7 +622,11 @@ static void light_tile_update(int idx, const ha_light_status_t *st)
const int32_t pct = (on && st->brightness >= 0)
? (st->brightness * 100 + 127) / 255
: 0;
/* Never move a knob a finger is holding -- the optimistic apply on
* press-down lands here while the drag is still in progress. */
if (!lv_obj_has_state(light_slider[idx], LV_STATE_PRESSED)) {
lv_slider_set_value(light_slider[idx], pct, LV_ANIM_OFF);
}
/* Bright knob only while the light is on, so the lit tiles are what
* draw the eye along the row. */
@@ -601,6 +735,11 @@ static void build_body(lv_obj_t *scr)
temp_unit_label = label_create(card, "°F", &lv_font_montserrat_20, COL_TEXT_DIM);
lv_obj_align_to(temp_unit_label, temp_label, LV_ALIGN_OUT_RIGHT_TOP, 4, 8);
/* Unit sits high beside the number; the trend arrow sits low, so the
* pair reads as one annotated figure. */
trend_indoor_icon = icon_create(card, "", icon_font_26, COL_TEXT_DIM);
lv_obj_align_to(trend_indoor_icon, temp_label, LV_ALIGN_OUT_RIGHT_BOTTOM, 8, -4);
indoor_detail_label = label_create(card, "--", &lv_font_montserrat_16, COL_TEXT_DIM);
lv_obj_align(indoor_detail_label, LV_ALIGN_BOTTOM_LEFT, 0, 0);
@@ -641,6 +780,12 @@ static void build_body(lv_obj_t *scr)
cell_value[i] = label_create(cell, NO_VALUE, &lv_font_montserrat_24, COL_TEXT);
lv_obj_align(cell_value[i], LV_ALIGN_LEFT_MID, 0, 4);
/* Only readings with a meaningful hourly drift get an arrow slot. */
if (i == CELL_OUTDOOR || i == CELL_PRESSURE) {
cell_trend[i] = icon_create(cell, "", icon_font_16, COL_TEXT_DIM);
lv_obj_align_to(cell_trend[i], cell_value[i], LV_ALIGN_OUT_RIGHT_MID, 6, 0);
}
cell_sub[i] = label_create(cell, "", &lv_font_montserrat_12, COL_TEXT_DIM);
lv_obj_align(cell_sub[i], LV_ALIGN_BOTTOM_LEFT, 0, 0);
}
@@ -709,7 +854,10 @@ static void update_body(const ha_data_t *d)
snprintf(buf, sizeof(buf), NO_VALUE);
}
label_set_if_changed(temp_label, buf);
/* Both hang off the number, whose width just changed with its digits. */
lv_obj_align_to(temp_unit_label, temp_label, LV_ALIGN_OUT_RIGHT_TOP, 4, 8);
trend_render(trend_indoor_icon, d->trend_indoor);
lv_obj_align_to(trend_indoor_icon, temp_label, LV_ALIGN_OUT_RIGHT_BOTTOM, 8, -4);
if (d->indoor_humidity.valid) {
snprintf(buf, sizeof(buf), "%.0f%% humidity", d->indoor_humidity.value);
@@ -725,6 +873,9 @@ static void update_body(const ha_data_t *d)
snprintf(buf, sizeof(buf), NO_VALUE);
}
label_set_if_changed(cell_value[CELL_OUTDOOR], buf);
trend_render(cell_trend[CELL_OUTDOOR], d->trend_outdoor);
lv_obj_align_to(cell_trend[CELL_OUTDOOR], cell_value[CELL_OUTDOOR],
LV_ALIGN_OUT_RIGHT_MID, 6, 0);
if (d->outdoor_humidity.valid && d->dew_point_f.valid) {
snprintf(sub, sizeof(sub), "%.0f%% dew %.0f°",
@@ -783,6 +934,9 @@ static void update_body(const ha_data_t *d)
/* Pressure */
format_value(&d->pressure_inhg, "%.2f", buf, sizeof(buf));
label_set_if_changed(cell_value[CELL_PRESSURE], buf);
trend_render(cell_trend[CELL_PRESSURE], d->trend_pressure);
lv_obj_align_to(cell_trend[CELL_PRESSURE], cell_value[CELL_PRESSURE],
LV_ALIGN_OUT_RIGHT_MID, 6, 0);
label_set_if_changed(cell_sub[CELL_PRESSURE], "inHg");
}
@@ -936,6 +1090,12 @@ void ui_init(void)
lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_COLUMN);
lv_obj_remove_flag(scr, LV_OBJ_FLAG_SCROLLABLE);
/* Created paused; interactions reset-and-resume it. See schedule_repair. */
repair_timer = lv_timer_create(repair_timer_cb, 600, NULL);
if (repair_timer != NULL) {
lv_timer_pause(repair_timer);
}
build_header(scr);
build_body(scr);
build_lights(scr);
+18
View File
@@ -233,6 +233,24 @@ static void apply_mock_data(void)
sim_data.lights[0].brightness = 178; /* 70% */
sim_data.lights[4].state = HA_LIGHT_UNAVAILABLE;
/*
* Synthetic trend history: an "hour-old" anchor per channel so the
* arrows render in the mock. Unsigned tick arithmetic makes now-55min
* safe even seconds after boot. Snapshot mode gets no history and shows
* no arrows -- which is exactly what a freshly booted device does.
*/
const uint32_t now = lv_tick_get();
const uint32_t hour_ago = now - 55u * 60u * 1000u;
ha_trend_feed(HA_TREND_CH_INDOOR, 77.1f, hour_ago); /* -> rising */
ha_trend_feed(HA_TREND_CH_INDOOR, 78.1f, now);
ha_trend_feed(HA_TREND_CH_OUTDOOR, 74.6f, hour_ago); /* -> falling */
ha_trend_feed(HA_TREND_CH_OUTDOOR, 73.0f, now);
ha_trend_feed(HA_TREND_CH_PRESSURE, 29.95f, hour_ago); /* -> falling */
ha_trend_feed(HA_TREND_CH_PRESSURE, 29.89f, now);
sim_data.trend_indoor = ha_trend_compute(HA_TREND_CH_INDOOR, 0.5f, now);
sim_data.trend_outdoor = ha_trend_compute(HA_TREND_CH_OUTDOOR, 0.5f, now);
sim_data.trend_pressure = ha_trend_compute(HA_TREND_CH_PRESSURE, 0.02f, now);
static const char *const days[HA_FORECAST_DAYS] = { "Tue", "Wed", "Thu", "Fri", "Sat" };
static const char *const cond[HA_FORECAST_DAYS] = {
"partlycloudy", "sunny", "sunny", "clear-night", "rainy"
+5
View File
@@ -67,7 +67,12 @@ ICONS = {
"ICON_SUNSET": ["weather-sunset-down"],
"ICON_GAUGE": ["gauge"],
# trend arrows for temperature / pressure readings
"ICON_TREND_UP": ["trending-up"],
"ICON_TREND_DOWN": ["trending-down"],
# light tiles (order-independent; ha_config.h references these by name)
"ICON_TV": ["television"],
"ICON_SOFA": ["sofa-outline", "sofa"],
"ICON_DINING": ["silverware-fork-knife", "silverware"],
"ICON_FLOOR_LAMP": ["floor-lamp"],