From ff9d3af9f8b466df2e1d1a87a7d6259bf2f72ce9 Mon Sep 17 00:00:00 2001
From: Max Gramser
Date: Sat, 19 Sep 2026 08:16:41 +0200
Subject: [PATCH] Show a spinner while a screen starts and while a camera
loads, bring a camera's first picture sooner, and round the alert's camera
picture (0.2.87)
Starting screen: until the first layout, render() keeps the status text
("Connecting to Home Assistant", "Waiting for ESP Screens") and a spinner
as one block in the middle of the page; the first layout deletes both.
The room label stays empty meanwhile, and ROOM_NAME defaults to "".
Camera: the full screen shows a spinner instead of "Loading image". The
screen asks when the camera opens and loads a link as soon as it comes
(camera_load, never under a finger) instead of waiting for the 250 ms
tick twice, and online_image reads 16 KB per loop instead of 4 KB. On the
bench Guition with the EZVIZ camera: cold 5.8 -> 4.55 s, warm 3.4 -> 2.06 s.
Alert picture: the image takes the frame's radius (18, the alert card's);
LVGL's software renderer clips it row by row, without a layer.
One spinner_create() makes the busy sheet's, the starting screen's and the
camera's spinner; theme role CAMERA_TRACK colours the camera's ring. The
README gets a row of camera pictures; docs/CAMERA.md, RELEASING.md and
TEST_RESULTS_0287.md describe the measurements.
Checked with tools/check.sh (473 Python tests, 19/19 C++, editor) and
--firmware: CYD 1,678,816 B (91.5 %, +1,312 B), Guition 2,055,280 B
(25.3 %). Host renders of both boards in both looks; four OTA builds on
the bench Guition Wallbox, which runs this firmware.
Co-Authored-By: Claude Opus 5
---
README.md | 8 +-
README_EXTENDED.md | 9 ++
components/smart_display/runtime_tiles.h | 117 ++++++++++++---
components/smart_display/theme.h | 4 +-
docs/CAMERA.md | 24 +++-
docs/RELEASING.md | 26 ++++
docs/TEST_RESULTS_0287.md | 172 +++++++++++++++++++++++
docs/images/guition-alert-camera.png | Bin 137153 -> 137620 bytes
docs/images/guition-camera-tiles.png | Bin 0 -> 31049 bytes
packages/boards/guition-4848s040.yaml | 15 +-
packages/core.yaml | 4 +-
screen_manager/CHANGELOG.md | 10 ++
screen_manager/app/core.py | 2 +-
screen_manager/config.yaml | 2 +-
tests/test_camera.py | 15 ++
tests/test_header_bar.py | 17 ++-
tests/test_theme.py | 2 +-
17 files changed, 387 insertions(+), 40 deletions(-)
create mode 100644 docs/TEST_RESULTS_0287.md
create mode 100644 docs/images/guition-camera-tiles.png
diff --git a/README.md b/README.md
index d4c8ac8..dd540e1 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ lights, the heating or the vacuum.
**What.** Firmware for two affordable panels, the 2.8-inch CYD and the 4-inch Guition, with up to
48 tiles over eight pages: lights, climate, blinds and curtains, the vacuum, media, the weather,
-history graphs, clocks and timers. A tile can take the whole page, one big switch you push without
+history graphs, clocks and timers, and on a Guition your cameras. A tile can take the whole page, one big switch you push without
looking, and a tile can go to another page. An automation can put an alert on every screen when someone rings
the bell, and a Guition shows who is there with the doorbell camera's picture. A tap can run any
action Home Assistant has for a tile, and Dark mode suits a screen beside the bed.
@@ -62,6 +62,12 @@ also be changed on the screen or by an automation, and your own YAML for one scr
Tap a tile to switch it, hold it for the full card. Keys and sliders right on the tile, pastel colors, a clock, the weather and history you can read with a finger. A lamp with modes (a WLED) gets an effects page with a drum picker, named and filled from what Home Assistant lists for it. The media card shows what plays with its album cover, fetched by ESP Screens like a camera picture (how). Rendered from the firmware's own LVGL code with a demo home.
+
+
+
+
+
+Cameras are tiles too, not only part of an alert: any camera or snapshot in Home Assistant (a doorbell's last ring, for example) goes on a Guition like any other tile. Tap it for the picture full screen, refreshed every four seconds; an alert can carry the same picture. The CYD has no memory for pictures (how it works).
diff --git a/README_EXTENDED.md b/README_EXTENDED.md
index 9652c03..e6d7be9 100644
--- a/README_EXTENDED.md
+++ b/README_EXTENDED.md
@@ -117,6 +117,11 @@ on the screen itself, and how updates work.
off shows a power key. A Guition fetches the cover through ESP Screens, like a camera picture
([docs/CAMERA.md](docs/CAMERA.md)); the CYD shows the player's icon in its place. A media tile of
size **Full page** is the same card on the page, with the keys and the volume working on the tile.
+- **Cameras** on a Guition (app 0.2.66 / firmware 0.2.57): a `camera.*` entity, or an `image.*` one such
+ as a doorbell's last ring, is a tile like any other. A tap opens the picture full screen, refreshed every
+ four seconds, with the round back key; standby and **Back to page 1** close it. The same camera can bring its
+ picture to an alert ([With a camera picture](#with-a-camera-picture)). The CYD has no memory for pictures and
+ the editor doesn't offer it camera tiles. How the picture travels: [docs/CAMERA.md](docs/CAMERA.md).
- **History card** for sensors, numbers, binary sensors, people, and switches, the way Home
Assistant shows history: a line with an axis in round steps and clock times for numbers,
with the highest and lowest moment, and a timeline with the time in each state for on/off,
@@ -297,6 +302,10 @@ actions:
camera: camera.front_door
```
+
+
+
+
A camera or image entity also works as a **tile** on a Guition: a tap opens it full screen, refreshed
every four seconds. How the image travels (port 8098 of the app, no token on the screen) is in
[docs/CAMERA.md](docs/CAMERA.md).
diff --git a/components/smart_display/runtime_tiles.h b/components/smart_display/runtime_tiles.h
index 92384c5..da5bb54 100644
--- a/components/smart_display/runtime_tiles.h
+++ b/components/smart_display/runtime_tiles.h
@@ -2875,6 +2875,26 @@ inline void control_event(lv_event_t *e) {
auto a=tile_controls::press_key(t,command,w.key_args[n]);
if(a.valid())action(a.service,t.entity,a.key,a.value);
}
+// The one spinner of the firmware: a busy card, the starting screen and a camera that loads (firmware 0.2.73+). The
+// ring in the spinner paint, the arc in Home Assistant's blue. Null where the board builds no spinner.
+inline lv_obj_t *spinner_create(lv_obj_t *parent, int size, int arc) {
+#if LV_USE_SPINNER
+ auto *spinner = lv_spinner_create(parent);
+ lv_spinner_set_anim_params(spinner, 900, 200);
+ lv_obj_set_size(spinner, size, size);
+ lv_obj_remove_flag(spinner, LV_OBJ_FLAG_CLICKABLE);
+ lv_obj_set_style_arc_width(spinner, arc, LV_PART_MAIN);
+ lv_obj_set_style_arc_width(spinner, arc, LV_PART_INDICATOR);
+ lv_obj_add_style(spinner, theme::style(theme::Paint::spinner), LV_PART_MAIN);
+ lv_obj_set_style_arc_color(spinner, lv_color_hex(theme::ha::RAIN), LV_PART_INDICATOR);
+ lv_obj_set_style_bg_opa(spinner, LV_OPA_TRANSP, LV_PART_KNOB);
+ lv_obj_set_style_pad_all(spinner, 0, LV_PART_KNOB);
+ return spinner;
+#else
+ (void) parent; (void) size; (void) arc;
+ return nullptr;
+#endif
+}
// A busy card is covered by a translucent white sheet with a small spinner until
// Home Assistant confirms; the sheet also swallows taps meanwhile.
inline void set_busy(Widgets &w,bool busy,bool large){
@@ -2883,13 +2903,8 @@ inline void set_busy(Widgets &w,bool busy,bool large){
w.busy=lv_obj_create(w.tile);lv_obj_remove_style_all(w.busy);lv_obj_remove_flag(w.busy,LV_OBJ_FLAG_SCROLLABLE);lv_obj_add_flag(w.busy,LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_style(w.busy,theme::style(theme::Paint::veil),0);lv_obj_set_style_bg_opa(w.busy,LV_OPA_60,0);
lv_obj_set_style_radius(w.busy,lv_obj_get_style_radius(w.tile,LV_PART_MAIN),0);
-#if LV_USE_SPINNER
- w.spinner=lv_spinner_create(w.busy);lv_spinner_set_anim_params(w.spinner,900,200);
- int size=large?30:20;lv_obj_set_size(w.spinner,size,size);lv_obj_center(w.spinner);lv_obj_remove_flag(w.spinner,LV_OBJ_FLAG_CLICKABLE);
- lv_obj_set_style_arc_width(w.spinner,large?4:3,LV_PART_MAIN);lv_obj_set_style_arc_width(w.spinner,large?4:3,LV_PART_INDICATOR);
- lv_obj_add_style(w.spinner,theme::style(theme::Paint::spinner),LV_PART_MAIN);lv_obj_set_style_arc_color(w.spinner,lv_color_hex(theme::ha::RAIN),LV_PART_INDICATOR);
- lv_obj_set_style_bg_opa(w.spinner,LV_OPA_TRANSP,LV_PART_KNOB);lv_obj_set_style_pad_all(w.spinner,0,LV_PART_KNOB);
-#endif
+ w.spinner=spinner_create(w.busy,large?30:20,large?4:3);
+ if(w.spinner)lv_obj_center(w.spinner);
}
// Cover the whole card, padding included, at the width the card asks for: a slot that just turned
// wide is still single width in LVGL's own coordinates. Unchanged sizes cost LVGL nothing.
@@ -3297,11 +3312,45 @@ inline lv_timer_t *fill_timer=nullptr;
inline bool fill_refreshed=false;
inline uint32_t fill_step_ms=0;
inline bool fill_cards(size_t cards);
+// The starting screen (firmware 0.2.73+): what the screen waits for in the middle of the page with a spinner under it,
+// until the first layout arrives. The first render() makes it and the first layout deletes it, spinner and all.
+inline lv_obj_t *boot_panel = nullptr, *boot_text = nullptr, *boot_spinner = nullptr;
+inline void boot_status(lv_obj_t *page, const char *text) {
+ const int width = lv_display_get_horizontal_resolution(lv_obj_get_display(page));
+ const bool large = width >= 480;
+ const int ring = large ? 48 : 32, gap = large ? 24 : 16, text_width = width - 2 * lv_obj_get_style_x(room_label, LV_PART_MAIN);
+ const lv_font_t *font = watch_font ? watch_font : lv_obj_get_style_text_font(room_label, LV_PART_MAIN);
+ if (!boot_panel) {
+ boot_panel = lv_obj_create(page);
+ lv_obj_remove_style_all(boot_panel);
+ lv_obj_remove_flag(boot_panel, LV_OBJ_FLAG_CLICKABLE);
+ lv_obj_remove_flag(boot_panel, LV_OBJ_FLAG_SCROLLABLE);
+ lv_obj_set_size(boot_panel, lv_pct(100), lv_pct(100));
+ // The name's place in the drawing order: under the tiles, the cards and an alert.
+ lv_obj_move_to_index(boot_panel, lv_obj_get_index(room_label));
+ boot_text = lv_label_create(boot_panel);
+ lv_obj_add_style(boot_text, theme::style(theme::Paint::ink), 0);
+ lv_obj_set_style_text_font(boot_text, font, 0);
+ lv_obj_set_style_text_align(boot_text, LV_TEXT_ALIGN_CENTER, 0);
+ lv_label_set_long_mode(boot_text, LV_LABEL_LONG_WRAP);
+ lv_obj_set_width(boot_text, text_width);
+ boot_spinner = spinner_create(boot_panel, ring, large ? 5 : 4);
+ }
+ if (strcmp(lv_label_get_text(boot_text), text) == 0) return;
+ lv_label_set_text(boot_text, text);
+ // The text and the spinner as one block in the middle of the page.
+ lv_point_t size;
+ lv_text_get_size(&size, text, font, 0, 0, text_width, LV_TEXT_FLAG_NONE);
+ lv_obj_align(boot_text, LV_ALIGN_CENTER, 0, -(ring + gap) / 2);
+ if (boot_spinner) lv_obj_align(boot_spinner, LV_ALIGN_CENTER, 0, (size.y + gap) / 2);
+}
// Before the first layout the screen is starting: HA connects, then ESP Screens sends the tiles.
inline void render(lv_obj_t *room) {
if (!enabled) return;
room_label=room; swipe_profile::Lap lap;
- label(room, !model.configured ? (!ha_connected() ? "Connecting to Home Assistant..." : "Waiting for ESP Screens...") : !model.ready() ? "Loading tiles..." : !ha_connected() ? "HA not connected" : !feed_alive() ? "ESP Screens not active" : model.title);
+ if (!model.configured) boot_status(lv_obj_get_parent(room), !ha_connected() ? "Connecting to Home Assistant" : "Waiting for ESP Screens");
+ else if (boot_panel) { lv_obj_delete(boot_panel); boot_panel = boot_text = boot_spinner = nullptr; }
+ label(room, !model.configured ? "" : !model.ready() ? "Loading tiles..." : !ha_connected() ? "HA not connected" : !feed_alive() ? "ESP Screens not active" : model.title);
render_header();
lap(swipe_profile::HEADER);
bool all=dirty_all || (!dirty_tiles && !dirty_header);
@@ -3927,6 +3976,8 @@ inline camera_view::Feed camera;
// show the page below at once.
inline bool camera_release_due = false;
inline lv_obj_t *camera_root = nullptr, *camera_picture = nullptr, *camera_note = nullptr, *camera_back = nullptr, *camera_title = nullptr;
+// Turns in the middle until the first image is there (firmware 0.2.73+); a note (no image) takes its place.
+inline lv_obj_t *camera_spinner = nullptr;
// The alert's image: the board's frame at the bottom left of the card, the camera the app announced for the next alert
// and the one the card on screen shows.
inline lv_obj_t *alert_frame = nullptr, *alert_picture = nullptr, *alert_frame_icon = nullptr;
@@ -4061,6 +4112,7 @@ inline void camera_request(const std::string &entity, int size, uint32_t backgro
inline void camera_note_text(const char *text) {
if (!camera_note) return;
+ if (camera_spinner) { lv_obj_delete(camera_spinner); camera_spinner = nullptr; }
lv_label_set_text(camera_note, text);
if (text[0]) lv_obj_remove_flag(camera_note, LV_OBJ_FLAG_HIDDEN);
else lv_obj_add_flag(camera_note, LV_OBJ_FLAG_HIDDEN);
@@ -4074,7 +4126,7 @@ inline void camera_release() {
inline void camera_close() {
if (!camera_root) return;
lv_obj_delete(camera_root);
- camera_root = camera_picture = camera_note = camera_back = camera_title = nullptr;
+ camera_root = camera_picture = camera_note = camera_back = camera_title = camera_spinner = nullptr;
camera_release_due = true;
ESP_LOGI("camera", "closed %s", camera.entity.c_str());
camera = camera_view::Feed{};
@@ -4102,7 +4154,13 @@ inline void camera_open(const std::string &entity, const std::string &name) {
if (detail_font) lv_obj_set_style_text_font(camera_note, detail_font, 0);
lv_obj_set_style_text_color(camera_note, theme::color(theme::CAMERA_NOTE), 0);
lv_obj_center(camera_note);
- camera_note_text("Loading image");
+ camera_note_text("");
+ // The starting screen's spinner, its ring dark on the black page in both looks.
+ camera_spinner = spinner_create(camera_root, large ? 48 : 32, large ? 5 : 4);
+ if (camera_spinner) {
+ lv_obj_set_style_arc_color(camera_spinner, theme::color(theme::CAMERA_TRACK), LV_PART_MAIN);
+ lv_obj_center(camera_spinner);
+ }
// The same top bar as a tile's card: a round back arrow at the left, the name centred.
const int bar = large ? 60 : 40, bar_x = large ? 16 : 10, bar_y = large ? 16 : 8;
camera_back = lv_obj_create(camera_root);
@@ -4133,6 +4191,20 @@ inline void camera_open(const std::string &entity, const std::string &name) {
lv_obj_set_size(camera_title, width - 2 * (bar_x + bar + 8), title_font ? lv_font_get_line_height(title_font) : 20);
lv_label_set_text(camera_title, name.c_str());
ESP_LOGI("camera", "open %s", entity.c_str());
+ // Asked for now rather than on the next tick (firmware 0.2.73+): the answer is most of the wait.
+ const uint32_t now = esphome::millis();
+ if (awake() && fresh() && camera.should_ask(now)) {
+ camera.ask(now);
+ camera_request(entity);
+ }
+}
+
+// The next image, never under a finger: a load that starts now would hold up the tap on its way.
+inline void camera_load(uint32_t now) {
+ auto *input = lv_indev_get_next(nullptr);
+ if (input && lv_indev_get_state(input) == LV_INDEV_STATE_PRESSED) return;
+ camera.start(now);
+ camera_full.load(camera.url);
}
// The board's interval (250 ms): ask for a link, or load the image again when it is time. Loading happens here, in
@@ -4156,11 +4228,7 @@ inline void camera_tick() {
camera.ask(now);
camera_request(camera.entity);
} else if (camera.should_load(now)) {
- // Not under a finger: a load that starts now would hold up the tap that is on its way.
- auto *input = lv_indev_get_next(nullptr);
- if (input && lv_indev_get_state(input) == LV_INDEV_STATE_PRESSED) return;
- camera.start(now);
- camera_full.load(camera.url);
+ camera_load(now);
}
}
@@ -4202,7 +4270,13 @@ inline void camera_answer(const std::string &view, const std::string &entity, co
if (view == "full") {
if (!camera_root || camera.entity != entity) return;
camera.link(url);
- if (url.empty() && !camera.shown) camera_note_text("No image from this camera");
+ if (url.empty()) {
+ if (!camera.shown) camera_note_text("No image from this camera");
+ return;
+ }
+ // Loaded now rather than on the next tick (firmware 0.2.73+), as an alert's image is.
+ const uint32_t now = esphome::millis();
+ if (awake() && camera.should_load(now)) camera_load(now);
return;
}
if (view == "cover") { // the media card's album cover (firmware 0.2.64+)
@@ -4233,12 +4307,16 @@ inline void camera_answer(const std::string &view, const std::string &entity, co
}
// LVGL's image widget is only built for a board whose profile draws images (the Guition's hidden seed); the CYD's has none.
-inline void camera_show(lv_obj_t *parent, lv_obj_t *&picture, lv_image_dsc_t *source, bool fresh_pixels) {
+// `radius` rounds the picture's corners (the alert's, firmware 0.2.73+): LVGL 9.5's software renderer clips an image
+// to its own radius row by row with a one-row mask (radius_only in lv_draw_sw_img.c), without a layer; clip_corner on
+// the frame would draw the frame into a layer of its size instead.
+inline void camera_show(lv_obj_t *parent, lv_obj_t *&picture, lv_image_dsc_t *source, bool fresh_pixels, int32_t radius = 0) {
#if LV_USE_IMAGE
if (!source || !source->data) return;
if (!picture) {
picture = lv_image_create(parent);
lv_obj_remove_flag(picture, LV_OBJ_FLAG_CLICKABLE);
+ if (radius > 0) lv_obj_set_style_radius(picture, radius, LV_PART_MAIN);
lv_image_set_src(picture, source);
lv_obj_center(picture);
return;
@@ -4249,7 +4327,7 @@ inline void camera_show(lv_obj_t *parent, lv_obj_t *&picture, lv_image_dsc_t *so
lv_image_set_src(picture, source);
lv_obj_invalidate(picture);
#else
- (void) parent; (void) picture; (void) source; (void) fresh_pixels;
+ (void) parent; (void) picture; (void) source; (void) fresh_pixels; (void) radius;
#endif
}
@@ -4258,7 +4336,8 @@ inline void camera_loaded(bool thumb, bool cached) {
if (thumb) {
alert_thumb_loading = false;
if (alert_camera.empty() || !alert_frame) return;
- camera_show(alert_frame, alert_picture, camera_thumb.source(), !cached);
+ // The picture takes the frame's radius, the alert card's own (the board profile sets it on the frame).
+ camera_show(alert_frame, alert_picture, camera_thumb.source(), !cached, lv_obj_get_style_radius(alert_frame, LV_PART_MAIN));
if (alert_picture && alert_frame_icon) lv_obj_add_flag(alert_frame_icon, LV_OBJ_FLAG_HIDDEN);
ESP_LOGI("camera", "alert picture shown");
return;
diff --git a/components/smart_display/theme.h b/components/smart_display/theme.h
index 6ba482a..eff1577 100644
--- a/components/smart_display/theme.h
+++ b/components/smart_display/theme.h
@@ -76,7 +76,8 @@ enum Role : uint8_t {
// ---- a camera image: dark in both looks, like a photo viewer (firmware 0.2.57+)
CAMERA_PAGE, // behind the image full screen and in the alert's image frame
CAMERA_INK, // the camera's name over the image
- CAMERA_NOTE, // "Loading image", "No image from this camera"
+ CAMERA_NOTE, // "No image from this camera"
+ CAMERA_TRACK, // the ring of the spinner while the first image loads (firmware 0.2.73+)
// ---- the CYD's touch calibration: dark in both looks, a yellow crosshair
CALIBRATION_PAGE,
CALIBRATION_INK,
@@ -144,6 +145,7 @@ inline constexpr Pair ROLES[ROLE_COUNT] = {
/* CAMERA_PAGE */ {0x000000, 0x000000},
/* CAMERA_INK */ {0xF2F2F2, 0xDADADA},
/* CAMERA_NOTE */ {0x9E9E9E, 0x8A8A8A},
+ /* CAMERA_TRACK */ {0x393D42, 0x393D42},
/* CALIBRATION_PAGE */ {0x101820, 0x101820},
/* CALIBRATION_INK */ {0xFFFFFF, 0xFFFFFF},
/* CALIBRATION_MARK */ {0xFFD34D, 0xFFD34D},
diff --git a/docs/CAMERA.md b/docs/CAMERA.md
index 07c0b01..f3c471f 100644
--- a/docs/CAMERA.md
+++ b/docs/CAMERA.md
@@ -3,11 +3,13 @@
App 0.2.66 with firmware 0.2.57 shows camera images on a Guition 4848S040:
- **A camera tile.** Add a `camera.*` or `image.*` entity as a tile. A tap opens the image full
- screen, with the round back key at the top left like every card. The image is refreshed every
- four seconds while it is open. It is not video: ESPHome has no video decoder.
+ screen, with the round back key at the top left like every card, and a spinner until the first
+ image is there (firmware 0.2.73). The image is refreshed every four seconds while it is open. It
+ is not video: ESPHome has no video decoder.
- **An alert with a picture.** Add `camera: camera.front_door` to the `esp_screens_show_alert`
- event. The card shows the picture of that moment across its top (it stays that picture); a tap
- on it opens the camera full screen over the alert, and Back returns to the alert.
+ event. The card shows the picture of that moment across its top (it stays that picture), with
+ the card's round corners (firmware 0.2.73); a tap on it opens the camera full screen over the
+ alert, and Back returns to the alert.
The CYD has no memory for images (a 320×180 image needs 115 KB in one piece, the CYD's largest
free block is about 45 KB). It shows the alert without the picture, and the editor doesn't offer
@@ -70,9 +72,10 @@ screen's made the picture change after 1.5 s one time and 6 s the next.) A slow
images older, never the screen slower, and nothing queues up. Nobody loading means nothing fetched.
A link that nobody loads for two minutes stops working; an alert's picture stays for half an hour.
-**Why BMP.** ESPHome decodes a BMP piece by piece while it downloads (4 KB per round of its main
-loop). A JPEG of the full screen took 0.6 s in one piece on the Guition, during which the screen
-missed taps. A full-screen BMP is about 390 KB; on the LAN that takes one to three seconds.
+**Why BMP.** ESPHome decodes a BMP piece by piece while it downloads (16 KB per round of its main
+loop since firmware 0.2.73, 4 KB before). A JPEG of the full screen took 0.6 s in one piece on the
+Guition, during which the screen missed taps. A full-screen BMP is about 390 KB; on the bench
+Guition it comes in about 1.8 s (2.8 s with 4 KB).
## Network
@@ -91,6 +94,13 @@ missed taps. A full-screen BMP is about 390 KB; on the LAN that takes one to thr
- The internal heap stays level while a camera refreshes: 77.2 KB free after 91 images in six minutes,
and PSRAM unchanged.
- Standby, **Back to page 1** and a new layout close the camera; nothing loads in standby.
+- The first image (firmware 0.2.73, measured 2026-09-19 with an EZVIZ camera): the screen asks when
+ the camera opens and loads the link as soon as it comes. About 2 s when the app still has the
+ camera's last snapshot (it keeps one for 30 s after the last load), 4.5 s when it must ask Home
+ Assistant first, of which 2.4 s is the camera's own snapshot. Firmware 0.2.72 took 3.4 s and
+ 5.8 s. Details in docs/TEST_RESULTS_0287.md.
+- `power_save_mode: none` under `wifi:` (the YAML ESP Screens writes has it since app 0.2.24) keeps
+ the screen from waiting on its Wi-Fi now and then while an image comes in.
## For developers
diff --git a/docs/RELEASING.md b/docs/RELEASING.md
index c7b299f..da2b8b2 100644
--- a/docs/RELEASING.md
+++ b/docs/RELEASING.md
@@ -219,6 +219,32 @@ icons sit off-center in the browser).
The `MDI_GLYPH_*` substitutions are retired: `TILEn_ICON` in manual
profiles must come from the set. No changed preferences or keys.
+### Compatibility 0.2.87 / firmware 0.2.73
+
+Firmware only, plus README pictures and docs/CAMERA.md. No protocol, storage, preference or key change: an older app
+drives this firmware as before, and the camera messages are the same; only when the screen sends and loads changed.
+
+- Starting screen: while `!model.configured`, `render()` calls `boot_status()`, which keeps a text in `watch_font`
+ (paint `ink`) and a spinner as one block in the middle of the page, at the room label's index in the drawing order;
+ the room label is empty meanwhile. The first layout deletes the block (`boot_panel`), spinner and all.
+ `ROOM_NAME` defaults to "" (was "Choose tiles in HA").
+- `spinner_create(parent, size, arc)` makes every spinner: the busy sheet (30/20 px, unchanged), the starting screen
+ and the camera (48/32 px).
+- Camera full screen: `camera_open()` asks at once (awake and fresh); `camera_answer()` loads a new link at once
+ through `camera_load()`, which like `camera_tick()` never starts under a finger. `camera_tick()` still does the
+ 4 s refresh and the retries. `camera_spinner` turns until the first picture or a note; its ring is the new theme
+ role `CAMERA_TRACK` (0x393D42 in both looks). "Loading image" is gone.
+- Guition `online_image` `buffer_size` 16384 (was 4096) for `camera_image` and `alert_image`: the full picture in
+ about 1.8 s instead of 2.8 s on the bench; without Wi-Fi power save no loop over 50 ms. 32 KB held a loop 0.1 s.
+- Alert picture: `alert_image_frame` has the alert card's radius (18) and `camera_show()` gives the alert's picture the
+ frame's radius. LVGL 9.5 clips an image to its own radius row by row (`radius_only` in `lv_draw_sw_img.c`) without a
+ layer, so `clip_corner` stays out (`tests/test_layer_free.py`). About 5 % more render time for the picture on the
+ host, only when it is drawn.
+- Tests: `test_camera` (the first picture waits for no tick), `test_header_bar` (the starting screen;
+ `render_header()` anywhere in `render()`), `test_theme` (the spinner paint in `spinner_create()`).
+
+Details: docs/TEST_RESULTS_0287.md.
+
### Compatibility 0.2.85 / firmware 0.2.71
Tile colours as Home Assistant draws them. No protocol, storage or editor change: the state messages are the same as
diff --git a/docs/TEST_RESULTS_0287.md b/docs/TEST_RESULTS_0287.md
new file mode 100644
index 0000000..82411d7
--- /dev/null
+++ b/docs/TEST_RESULTS_0287.md
@@ -0,0 +1,172 @@
+# Test results app 0.2.87 / firmware 0.2.73 (2026-09-19)
+
+After the README picture refresh Max asked for four things:
+
+- cameras in the README as tiles of their own ("zodat mensen snappen dat camera niet alleen tijdens alert is");
+- the alert card's rounded corners on its camera picture, if that stays light;
+- the spinner instead of "Loading image" on a camera that opens, and a look at why its first picture takes so long;
+- a nicer starting screen: the text in the middle, a spinner under it.
+
+Performance comes first for him, and the add-on often runs on a Raspberry Pi 4 class machine (his Home Assistant
+Yellow is one), so work moved to the add-on is not free either. Everything below stays on ESPHome's and LVGL's own
+means: `online_image`'s `buffer_size`, LVGL's spinner and image radius, no ESP-IDF or lwIP settings.
+
+## Round corners on the alert's picture
+
+### Three ways to round the picture
+
+- **`clip_corner` on the frame.** LVGL 9.5 then draws the frame and its picture into a layer of the frame's size to
+ clip them (392 × 220 ARGB8888, about 345 KB, on every redraw). The project keeps layers out:
+ `tests/test_layer_free.py` refuses `clip_corner` (see the CYD memory research of 0.2.50).
+- **Corners baked in by the add-on**, as for the media covers. The screen would copy a square picture as it does now,
+ but the add-on would have to know the exact colour behind each corner: the alert's swatch in the light or the dark
+ look, which only `theme.h` on the screen knows, and it would have to make the picture again (Pillow, on a Pi) when
+ the look changes while the alert is up. A wrong guess shows as coloured corners.
+- **LVGL's own image radius (chosen).** `lv_image` passes its `radius` style to the draw as `clip_radius`, and the
+ software renderer's `radius_only()` (`lv_draw_sw_img.c`) blends the picture row by row with a mask of one row
+ (392 bytes). Rows between the corners come back from the mask as fully covered and are copied as before; only the
+ rows of the corners are blended through the mask. No layer and no allocation beyond that row.
+ `LV_DRAW_SW_COMPLEX` is 1 in ESPHome's `lv_conf.h`, so this path is compiled in; rounded rectangles already use it.
+
+### What changed
+
+- `packages/boards/guition-4848s040.yaml`: `alert_image_frame` has radius 18, the radius of the alert card
+ (`packages/core.yaml`), instead of 0, so the frame behind a picture that doesn't fill it is rounded too.
+- `components/smart_display/runtime_tiles.h`: `camera_show(..., radius)` gives the picture that radius when it
+ creates it; `camera_loaded()` passes the frame's radius for the alert's picture. The camera full screen and the
+ media cover pass none and stay square.
+- README.md: a camera row under "On the screen" (`guition-camera-tiles.png` new: a page with a camera, a live camera
+ and a doorbell's last ring; the camera full screen; the alert with its round picture). README_EXTENDED.md: a
+ Cameras bullet under "What you can configure" and the tiles picture beside "With a camera picture".
+
+### Measured (host build on the Mac, `.esphome/readme-render/readme-0919/time_radius.py`)
+
+The render time of the picture's frame after invalidating it (LVGL's render events minus the flushes to the SDL
+window, which are the same for both), 40 redraws per run, four runs alternating between the two radii:
+
+| Radius | Fastest | Median of the runs' medians |
+|---|---|---|
+| 0 (square, as before) | 1269 µs | 1340 µs |
+| 18 (the card's) | 1352 µs | 1413 µs |
+
+About 5 % more, and only when the picture is drawn: when the alert appears, when the camera full screen closes over
+it, when something next to it is redrawn. A picture that stays up costs nothing afterwards. These are host numbers;
+the Guition is slower in absolute terms, and per row the extra work stays one 392-byte memset and one blend call.
+
+## The starting screen
+
+Until the first layout the top bar read "Connecting to Home Assistant..." and then "Waiting for ESP Screens..." where
+the screen's name goes (0.2.43). Now `render()` calls `boot_status()`, which puts the text in the middle of the page in
+the name's font (`watch_font`, 27 px Guition, 18 px CYD) with a spinner under it (48/32 px, 24/16 px apart), the two
+as one block in the middle; the name stays empty. The first layout deletes the block, spinner and all, so nothing
+turns behind the tiles and no animation runs for the rest of the day. The block sits in the name's place in the
+drawing order, under the tiles, the cards and an alert (an alert can come before the tiles). It is drawn in the
+shared paints (`ink`, `spinner`), so Dark mode colours it like the rest. `ROOM_NAME`, the name in the profile until the
+first `render()`, is empty instead of "Choose tiles in HA", which showed for a moment at every start. The text has no
+"..." any more; the spinner says it is busy.
+
+The three spinners of the firmware (a busy card, the starting screen, a camera that loads) come from one
+`spinner_create()` in `runtime_tiles.h`; the busy card's looks the same as before.
+
+## A camera that opens
+
+### The spinner
+
+The camera full screen shows the spinner in the middle until the first picture is there, instead of "Loading image".
+Its ring uses the new theme role `CAMERA_TRACK` (0x393D42, the dark look's spinner ring), since the camera page is
+black in both looks. A note ("No image from this camera") takes the spinner's place; the first picture ends both.
+
+### Where the wait went
+
+A camera opened full screen on the bench Guition (fw 0.2.72, 4 KB chunks), timed from the screen's own log
+(`.esphome/camera-speed/timeline.py`), with Max's EZVIZ camera `camera.max`:
+
+1. 0.2-0.35 s until the screen asked: `camera_tick()`, every 250 ms, sent the request, not `camera_open()`.
+2. 2.6 s until the link came: Home Assistant's snapshot of the EZVIZ takes 2.4 s (the camera itself; measured the
+ same in 0.2.66); the add-on's encoding is small next to it (a 1080p JPEG to the 480 × 270 BMP takes 10 ms on the
+ Mac, several times that on a Pi 4 class machine).
+3. Up to 0.25 s until the load started: the next tick again.
+4. 2.8 s download: 388,854 bytes at 136 KB/s.
+
+Step 4 is ESPHome's `online_image`: every round of the main loop it reads one `buffer_size` (then 4 KB) from the
+connection and decodes it, and `esp_http_client_read` waits until that chunk is complete. 4 KB a round came to about
+136 KB/s. A bigger chunk a round is faster (the table below), up to what one TCP connection with lwIP's 5,760-byte
+window gets over this Wi-Fi, roughly 300 KB/s. The same 2.7-3.3 s was measured in 0.2.66 from the Mac and from the
+Yellow: the limit was on the screen's side, not the sender's.
+
+### What changed
+
+- `camera_open()` asks right away; `camera_answer()` starts the load as soon as the link comes, as an alert's
+ picture already did. Both through `camera_load()`, which, like the tick, never starts under a finger.
+ `camera_tick()` keeps doing the refresh every 4 s and the retries.
+- `online_image` `buffer_size` 16384 instead of 4096, for both images.
+
+### Measured on the bench Guition
+
+`.esphome/camera-speed/speed.py`: per open, from the `preview_camera` call (the same path as a tap on the tile) until
+`online_image` reports the picture complete. Cold: 35 s after the last close, so the add-on has forgotten the snapshot
+and asks Home Assistant for a new one. Warm: 5 s after the last close, so the add-on answers with the snapshot it has
+and fetches the next one meanwhile. Three opens each (two cold for 32 KB); medians. The 0.2.73 builds went over the
+air from `.esphome/camera-speed/guition-wallbox*.yaml` (the Device Builder's API, OTA and Wi-Fi settings, the packages
+of this branch). One "cold" open of the power-save-off build found the snapshot still there and is left out.
+
+| Build | Wi-Fi power save | Cold open | Warm open | Download | Longest loop wait during the opens |
+|---|---|---|---|---|---|
+| fw 0.2.72, 4 KB, tick | light (ESPHome's default) | 5.80 s | 3.40 s | 2.86 s (136 KB/s) | 131 ms (lvgl), 65 ms |
+| 0.2.73, 16 KB | light | 4.36 s | 2.09 s | 1.74-1.91 s (216-223 KB/s) | 58, 61, 77 ms |
+| 0.2.73, 16 KB | none | 4.24 s | 1.99 s | 1.73-1.80 s (223 KB/s) | none over 50 ms |
+| 0.2.73, 32 KB | none | 3.94 s | 1.62 s | 1.42-1.45 s (271 KB/s) | 101 ms |
+| 0.2.73, 16 KB (this release) | light | 4.55 s | 2.06 s | 1.75-1.90 s (208-218 KB/s) | 93, 107 ms |
+
+The screen now asks 20-150 ms after the call (the API call and the log line's way back included) instead of
+210-345 ms, and loads about 150 ms after asking when the add-on has the snapshot. "Longest loop wait" is ESPHome's own
+"took a long time" warning (over 50 ms). With Wi-Fi power save, `online_image` now and then held a loop up to 107 ms
+(65 ms with 4 KB, next to a 131 ms LVGL frame in the same opens); without power save nothing went over 50 ms.
+
+- **16 KB, not 32 KB.** 32 KB saves 0.3 s more, but a read of 32 KB waits for several TCP windows (lwIP's is 5,760
+ bytes in ESPHome's build) and held a loop 101 ms even without power save: a tap in that moment waits as long.
+- **Wi-Fi power save.** The bench Guition's Device Builder YAML dates from before 0.2.24 and has no
+ `power_save_mode: none`, so it runs ESPHome's default `light`: pings 103-191 ms (117 ms average) against 5-94 ms
+ (21 ms) without it. With 16 KB chunks it made no difference to the download, but without it no loop waited over
+ 50 ms. The YAML the app writes has had `power_save_mode: none` since 0.2.24 (EASY_SETUP.md says why); the package
+ doesn't set it, since it is the owner's Wi-Fi block.
+- **What remains** of a cold open is the camera: 2.4 s of the 4.5 s is Home Assistant's snapshot of the EZVIZ. Only
+ fetching before the tap would hide it (when a camera's page shows, or when the screen wakes). That polls cameras
+ nobody looks at, and a battery camera wakes for it; it is left for Max to decide.
+- Not changed: lwIP's TCP window and other ESP-IDF settings (`sdkconfig_options`). They would speed up the reads
+ further but are memory and platform tuning outside ESPHome's defaults.
+
+## Automated
+
+- `tools/check.sh` (worktree, after the rebase on 0.2.86): Python 473 tests OK (two new: `test_camera` "the first
+ picture waits for no tick", `test_header_bar` "a starting screen says what it waits for in the middle"; the
+ position check of `render_header()` now looks in `render()` as a whole, and the spinner paint check in
+ `spinner_create()`), C++ 19/19, packages, icons, editor tests, types, build and bundle PASS.
+- `tools/check.sh --firmware --baseline 1677504`: CYD 1,678,816 B of 1,835,008 B = 91.5 % (156,192 B free),
+ +1,312 B against 0.2.86 (WARN: the 90-93 % band, under the 8 KB that needs Max's OK); Guition 2,055,280 B = 25.3 %.
+
+## Renders
+
+- Host builds from this branch (`.esphome/readme-render/readme-0919/boot_camera_host.py`, both boards, light and
+ dark): the starting screen with both texts, page 1 after the layout without it, and on the Guition the camera page
+ with the spinner, with the picture and with the note.
+- `guition-alert-camera.png` from the new firmware on the host: only the four corners of the picture changed
+ (1,400 pixels of the 960 × 960 README image).
+- `guition-camera-tiles.png`: the camera tiles page of the README demo home (Home Assistant's icons and words), the
+ front door camera idle and grey, the garden camera live and amber, since 0.2.85's colours.
+
+## Hardware
+
+- Bench Guition Wallbox (192.168.146.136): four builds of this branch over the air for the table above (its first
+ row is the toggle-key session's 0.2.72 bench build that was on it); it runs this release's firmware (16 KB, its
+ own `light` Wi-Fi). An LVGL snapshot during an open shows the spinner on the black camera page. After a
+ restart the add-on's layout was there before my own API connection (6.8 s), and the snapshot showed "Loading tiles..."
+ with the tiles in place: the starting screen had gone as it should.
+- The CYD: compiled only.
+
+## Not tested
+
+- The round alert picture on the panel: the add-on sends an alert picture only with the `esp_screens_show_alert`
+ event, which goes to every screen, Studio 1 included. It shows with the next doorbell or camera alert.
+- The starting screen on the panels themselves: it is up for the few seconds between the start and ESP Screens'
+ layout. Max sees it at the next update or restart.
diff --git a/docs/images/guition-alert-camera.png b/docs/images/guition-alert-camera.png
index ad8f9dfe99917c4b035acf519fb51c94db0fe231..cac706a2efffb812cf7f54702771b943e6986756 100644
GIT binary patch
literal 137620
zcmZsCcRbts_kUX#S1BEKjh3s5+Iyyos#;Z4s|cmFYVVn%Xw52Wv_w&}k`60IqE)L#
zsFBtRf*>Ral87X~-0%1IyPtbM_xDF0?>ye)yw2;K*Ez3qp67L*-?B12byE1`v17+h
zncXnHee4)Z*Pp-N*_d|@r%t~2&!+qVrK?fTSbtIE$NG^67$mS%VFK&B)+*h2>IU|
z|8w7Em5^fHAq+n@Q{eJ{U;Oj(o`NTT!yK^wgp-B;qL8$B2`vqdd1e&b))q1)B_&1VzRjccUi#noPH@S*@<
z@e)kYVt!GPedNykVhl_MK7Y1WQ6T==P-6Vp-?_NjdkpcE90uGQWWL}RK-1)5IXtwM
zmMFIdEuAwqR@2`Z=q7X{#?LV(*oOaFFQ?Cp?Y5~(NbH_FcV_Io0Zxd?2~jZyw@3n$
z|NM{dqbo3nZxAQjoL6fTVtLGV_iyuzY{Fnm$#Xzr%ogYN$qvj`z$J-t#b_*4f;lYK
zT2i81*ZN8-2+aGpnFY#4l0UOQA}=B>jg9wIgV(Om62y-#GRHbF5^w(3tg4P19B0r2
zD7Pgf+9JpGnKIav7C(DttVB9OL+dYA7IQ9y7tX)!M(`xvA*UmjotdP~4G7z`WyXF1
zqwN$wlk>kV1eP;rir89{0NY_eOJmap0wp)*PYrOK*Z4~T+q(;%AUp^2_V#DhGonpj
zK!^7c-E65D$2I;kAvP8!S-VH9pluS}UqWK~jc5w?6qM?qarr-t@jV9})FS_oD6hw{
zs2)|*0~oMVC;!Qfihvi3s5+weKNgkJ$J$4b2N%Ubl`WP2>t(h=7mPMyY>RRV`Z@ML
zR(>^G>fC13>p0}cH?AsdKmSs&AeRT%wl6ColKPstE|x4w&z`Lv4G8$%`D+#_eZp94
zJo91hVvN<%JaIGCz@qnGORH|jgm7ff6zeZ*13kOnNZh2CF7yb(IHDDG505b
za~`f2+@AoO{&!8TtsTZ<%|hb-BR#0XY}9QgH*SH+S?DDC6wlG+e@>Mt-J`m%GxLW5
z|D$jI*R1~$t9>T9Q#zjKpEG4sVI$ioX}aizX>FrGI%m$zMeVw4aQy~U5ulB
z>xbxcgJ_EKznB#dIQqY)xhHMl=867GiXBy_5$rt#lYhwta6tZFD=sc2SC+*6MLEo0y(gMxC*9`0(@c@V&K(>R3NP$q|UUhubLf;*JrTSjEwFC#CO330fS&OV`C8R
z7nUiURM1g3Q|M#aG*0Hymo5;OVp^7y^O-YaR@@4KXX#QvwEq#coiP_7PN#h$iOeI=
z%x68X6_)yYBShkZ-vmfM1{ck!D&tdmsH`()2*QY~m>VQ3T^Nvm526?_^aB|t=oJSUrYS?g|1Uqn!4-xkk?h$
zR*+QqQa>3a-~$G8jF?7)VnyMKBY;>i640WBT%`4k@k3v4R4f!6cHkg|wg>RWxexj&
z2vVYxt
zHwlO385s=f*g#q8i1n2aZ=**X7wqp1odco?p-xsYC7pLS-WD-KF3sp8AX4@RuBH5BQVA#5BEXedXfr*LR&1}
zJ3+rkbD|`>Bhv!1(L2#V*LdqKij;Yre$_iwh4JAj+DPo>g&FJVpt!8Q+|}bd4FJGfys6U
zozMQ^f|3$4j>m5zb`bGK#>PzNzW31}3vqy^WiwaJ9HSe3QKB3PCnp;lhmvZMOz*4<
z4zV&eCgQHeg;ENPjT?F1sixd)+LJ9tEuuf?56P*hNU>kT32M3aA6a^;DINE2-=_Kw
z6b?vs2azK{O@s4{EJZ!L>jcnVyi4I;=xtWVheK&;EtlWqs>J8yV8W$hf=Y-B8|MpM
z0WWN(MjRfz6jkC<0@|-?#yzh2&~EiktSGggm)GL!%eW7fBul@l(XhgX#2mX-?*|!|
z9%@*JT`vgf)mH}PIka)EhBcaAv>(##Ti@UV1&3X?^}Laf6W7sBLlVPQ3)zd_OkDh;
zJuX_*W(MPar8O_?Ua+d^Qt-n?T6d@{+PNz%*}}t-rZc2C^4h&G;m1b|ZfJZ7Hc}FH^XEjgSUwQ)uOKxUE{qoj)KI@Kc6$w!7l#fC>xSP
z<6cY`JhuHNwNR1G0}^YtD3sEYA@S<8HSHWE)^Fi|YEY^TJ0?g_mpTtVb#1QP`s;WP^(-fk8ww
zwZj8i4PuNIKRCeg8&)~i;o)=U0$Kq~))8YAn#e?6gO
z@jtb4e`cGksv<^=B}akC)Oc|#DYrPUe%et~}*3D#krC5pWR6~`#T;r?l!%CZU0QJptgF7A77grMv
z)9sWZ{s^locTKDuXk5T5WyW!j$lYm#`AE?xbYF-+WNU@c_*`R8vcVv4Ju`P$svJ;-
zxAT9=2}yZJ)U_H`MZEBKe-~1%W&LBU88ff5rZgsKDg4j^*Z1*UZNyNhka(?1e6oh4
z5PEGTaQ8^QFmmn5=oCvKf)yj@$7T^-Vq!IB5o2Pm_no|m(*mY)rrh0HE(`B_0<6uM
zDg?eWk`8~FhiOr3+SZEKBRfgJF^gr&h{#`wy`s9Jg1|lsq9-i0$}32QPXU=qD2N7@L<9lw4^`@Z|pr>_5A6c@mM#!b2%v_)5
zo)2}%ZCiG96%N&wS2Hh3t3Hen3W+!f{Y+|)Hp#6PniqHaK=5Zd9$WK=3)^+qd6D?|
znNAj#SRtW>%G%sZJrr~Q#Hr_LnH95_8(6Kw3R
z5H{UV25>ur6ATwMFathV!?<|q-Uk&*c&7++@b)2#yc|3}At)Q=OF29YpU^dcdf;^|
z^6(l8VFEG2xW__aM6s}UcXacd?%yAQ3{UWjUTM4&^K*^WQXS~vzjrx|0R*fdv?
zzVFaT%Jhk>)ye)w(&;Zha0$YMH{O(s(*yn3Te`g3InkoHvH#18^8g@35RdB2dnh
z%dVYny4HZPmv0Kt>wWvP#~F9q$$?e
z1rRKJ%kEI#n!4&Z>F@G>X?529hxAh2>$<8P?cKMtdcbt-8^fx$OM-HvX70xBlqc`l
zv{9F>7glS1dtPPL*S>0Z@_aU^=UnIWG#%`GKS{sNJNM_WGuLl>K2wtqiaGFwbtL!R
z3ON<7-=NxR#_5yBCtuO~Q%1Yc1b@Zn+vMzs4ki->SRKDKQ~-{?s!E%s%->i(flnOA=dO*6^A
z)kLA$cDB4k!dsx9HML`VH(sUp_xcjqpWQ4`D|P%ca#p>Mhij8hQu`1H3|m
zU{dGEyOFl>$x33OY0A=f=SYFBxQc%0b)I7$SEV7yTrK>7$nti_XOQwT&OmBEs-YE<
zu7S*dvtB8WeLwlm$YARk6sb-ZU>NZ9kNr%%|5l@~yiyx!dGHo}d9c=lp01#2NGX=u7Fteus$`&H&*)s!D
z2*~Y`M7^^5+I$O%+IDd8`1oo{s#6(<(5=$mUGL{pFunHX6bHRbm{o4o`b!P>3%8LE
zw|vxPyg)n_+w?CN86=m>0|=tupUD(YEIM@>RwH^zpXQ`=O$m~w;s51i(9U6#-0w>E
z3t77R^QihK5rRfGf}j1x8mfjZGdS!b`ABx5alIs|6hT1`KZZo^r{a%akkZ~!XB=kV
zMcp9Q4xh^m>OI-Eag8&hrcFPv<)O*vlphxJjn2>BReOtu1~_jgxu-t04SuXE+*pf!
zzA%>AIV@tzrdf4jVP}zG>&Xh8;FUDW&|c_&7SY&}oENQx%=Ip*x;HGnzvZ-x-!JzL
z;HxTjJF;sq@bQ+4s6ab!eWn`eWe-g_d7jjK{_zte@Yr*$#q)3WnNujj(b+;3&NmVUc;g~d#O`;0XP?-
zR_;^|b!5nlv&;BZBkVbW61o0k=DL|4jjBnojh!d8>?d4!h(b`}-ZSFDxl~mu6tok-
zOvVrl8sk*wS)n3(2Q?ZOCB`&D$o9%R9WF(kmK&9e=^g$&>KoHr5
z*b6lNm-@$jZHUx|z#RlL(MHl{k?({fZ0(vM>~f1AzZT2hp}zkl0~ua$Ve{+5yB8Eq
zN!o9WY(#Z^4cp4B3zCstpj_^^FO`2t4X-PEtRMEB1osp&G;rPnJ=)JO6
z`LfjprriT2qe4o|Xu>VC$vJ9H@@X}kcc)AzqLNXoFtw&%iK53U9IrxSvut;tbpAMg
z?dCkh7n{Bmc{}?fziTUJW~E*2SCjQ)GQBf4uWKvvg$L&kbTT@0{6#N)4A3Z3S}2su
zLP$%c-U*^wla4W~I+r0GSY`8S_lT#HSJ`ZO1)-lC~Y-ibe}bAlw!jIuWLe!l%;gz|Gl
zH(^Z?yBt;9I%RLw@+c#3N>W0F9w=lyMk5W(;ZnD|K8~&mmHO1stK6
z?xP5Jz-8aW<9Qo(`PSU2TjNf_Z&{~Txf1JozB?PS5*3hn$o&o##s?RI1tT%sBszbk
zluhc+dvUzVCGuD23AqH+3wPlIX_eBmPEDk;KP^M0;*MKpDMT@-H7{di(_2Cx!)!!!o!t;$(7@$u`LQ6IZclW|_wlem24
zd7%C+ofB#)k3nggZII5e{#!o8u)G~Mlw08y31)i;d);-rA$St3B0&apbMiD4y6&
z=_{PQHrU`y@H-Vfan}dui^@&hz?C&yg=}U7;clO~lxzl2IaI0237?$`j5
zoK>UHUK|5mN-kSPLN>b`Ysb&&
z%qVb^YS{~THmn1`xAF-G%CmReuo3K39rzjce4Q17rvx&pOL<84up;c$pYwfC97?8t@sF5Q|46@
zIN)3aKnFn-xW@#S4i`d5N&IBP62m}Eb47kfY+^=KG*{I7IofU#?3D?mPK|if)|X5v
zp)X59v8R^y6Q^yjx48J{D(PMW*-O;wRo2?|9$>eW{sdA!_KNxWctu=?#i2
zp~&wh=1V6I$O)VKU{ic7yuW-C@Sj}sIX@4YJdiDvs0gzseSd~P=^P7pNNc_a6X9Pu
zyv7?f+Nn1qA&?*3;$j-6`&hoEvEri@O3_DM-SVL$C|bLT5_Wev252^JbZyYm3U@^$
zVyN2lAt*hoLd(EMA*>{)lAEPL`FVL5zJ{dguLAFRrS1^?(0I^_7b3>+FNpZyG&@XO
z*@0ciBH%YZNPvAK{A;nQeOsTVWj?=u5ScB*?ugChnqyZ|JX)IX>_)hW>62!8vh<;_
zL)sq@Q^tZgh#9uQaR}OLruOrJ2RPsqL0Z@d=Wq5I_eNE~>o0_di4FA&x<*@ifzZTK
z(ydqZRrWt?oZnjVDfZi#!^&$`o-^PZR=MPD4_k4Stb@fAm
zfQ6`^vd@(rqL6Ig+uM<$W|ap~+iAM8D^bPfqa%6|j55)v)pTwsf)tf{b14Ksxpn{x
z>Nqeo)(aqCcbu)UH~XQ#deLDzZd8R>HSZQUQT6@SN|Bk{@|b)G*jKJcX6Ui$;P`kR
zPFNx|$YZoPK||JGYgIgPN>0r5OXR6G2Zfkg6~MX4qREG&tPbv6(b}J$7ZDu|uC%B>
zTf^7EIHh~9@%Hi(ABMu
z2MeuFV#CTcD)J2ad_~WOtv%ws-Wr}1SvbUg=$-iPnwqwHVr!RJ=^d2wt3)I$
z*m03u5-J!9nFpTSYWv#7hhHpC51v&(g?t&`zp^E=`*m{8e3GvvQ1xK{$la+=iAN}8
zwP`=sI(ApTtv!U;_D81Kensh(@A2WCSEfZ-9lu}SnXOosBaqtl7!fSUoKoGW?X8a8
zuQNSO1v8NACDCF^TS0lH?RwF+p|jQMJbWpXd_jU`X~j_j5B>C+&LghCA)Lu$EOICw
z&IS8YT(8=8y{}`T=G3KsxqF}=*_ScLxM6JU0H88~n&{PGHx}eELV)KlV)J`{2`~XV<$HMFMW3kZam{*AQ8By6B0NEY6GJUbyUhrP+4KbhZ
zgu|B+td^5`_Jst79US<4bVlTWItScq?vB^z%fj^WKtTto2*vsv2#hGMcO
zv>iE%>{wA65hu%``3?x@ulet~QN@oI41HD6B^R@|w~?vwOJ%i;1|a3(uXsNHg}Xc4
zGg0@+M}#9NTy;=61Jy^%7Ezl)95^Emw+~yyMo2Am7(>FVvRMd2-vZGC;RqVys9E{u
zHQckSmf%zod)MnWlGSZ#;e|ktzyhlteHFWxvp#RfjR$QH+>0?kPH9Da2J`w=UFMSG
zDb4PYvxxapdAlUxi<6IcyG`y($(tut?OXQ}b%Pd{GNOv@2oqzMMaP1tYPWV}T{eWR
zLUET|`}4U|)PN>#tGv9$K2lp(bp$pmm71L+fO?3VrrZ&;J3Ac;`aGwry^Hy>Plbv3
zWJJf6$Oi}URVj>A_e_Q~|B7&8@TJ_jjuP-evfL4J_g}pmsK{EDJ8mgwD>OkoM$`xs
zuA&Cd%S3KIU8sv`do|vE3Tc^v!EE5JPv1wV{ED0iE15>7cO0A_E$hp=asRcR42p&W
z5Ccsqihyl2b0rZXkpYn=aUjax2Q*@@AXbc-yLK}6tC?s&JN4drsERt@>0+e
zjBkr^iX!tQIv`prD}oUNWR8QT$P+mG&IpbINCG_6{Q~AM48g#C3NkBp4Mn|EzP~n?
z)J>1W0(F#L6R1XnLBWwwG3YLF2M#!(Z|)Pw>Zv>Abac?qk=LMKuj?HZIkdkI_{~fb
zuQJjBF|JlE*wi3$3X}&!6;0iVqgV4_NPg(xLNtLYi9Y7&KO%Uaa)v{=svC{ul#dv(
zC~wxj`>;EfrRh^Ko0GZti!nVX
zzxY7UBd;4FGMycd`$RPttVTkmt4rJaPKkPnqCgEs$!+-Quz+*&EqB}vigvl{N^Y!b
zl4ddh;({Ta#LK&X3p2_f;UUW!1DEJ3f{%5(a)vseahvgiJM5kXQ;3DE^s_qK;Y2j-s
zN-<_epBJr?Rh2pw#R})=43@`TYpn#$7nYes*!866ra>OH`n2+>6DzxmR?-KnYM
zjot&t+m1TAq?{z5ZOj)ite`HI<;1n&H{Qd_*c`e&!MY;oPQ}Pe?r=#w00i({W3Iyx
zEpCr%OFQ$7wZ%B`qZ#%T3QU~t8VE8_N*1T*B!%ynAn*$Zv;;&DnTn#rSt?+lNI?`&
zEHc3`mMS22K+sK02}OWz4F^;iM$7<6*grvs5hONajIXD2dk%O|`d)Iu`be7nIu%O)
zj)>MmTvVhKA$2#gp8*GtU7c7YsRfJ~B>)eV7RDGO46P1yYKo~X1%UbtCF%3f_<+$e
zP(U*PxGTl(x2MTi?g2ZKuvT+H2tYM|&5wWgmV4e~V^l8C3wut!}
zeFVcc73B<%EX-Ey*uHSSkB2@?7#_Lb;iAB-$;!nO9iB!t59>%ZL%J&uX0NlKDH=3k
zLqolJsr2nh+GMbQde*U_hoL33;L7DU;e|GtZ$mpPmhG`_w*^CmC*lP%_=M
z&+g~flJh#86MIQEet~_q2~GPiU>nhj`qyo6Tt5nT=Gz3ojISYP8=LD&i^Z4jcBvb<
zNbkThO?6pgkXZ)jE-~CkH>0J5do12!YZU&_}KZhb@fnEuJ&!Q1kqcH9fqw?PWf&{;_uy
z2e^EF2b?A!z>~izaCA<%=)9x}e!ON`GE{d|B4$DZsjfW^(=hpzUO^l7MUEt@MI}
z?v@aQGEhZX%HhYOHMQ#}i|!@wm{f(o)FU;nEd&w3a@pDsR6<4^N`hbvX%eHP{KEpXcdK8TN9S9xDocbo`X0gZ||oA8NU7
zJGXyl3TM?+P64f-omG3ovL=RYA?~)?R_IP_BBpn%<57nqEUVqj3E*nLOZjP1eRbx(
zTj<Z4V0scGkZ-0u5Urt9csg-i#DxYsAoB(H-a=@hs)opE-|9C^&WG~gQ=wAi(L
zXibqNrV|*mn)LE+9Icv(e2CL9pli$mmX=aC_}p&NfZ*Sc=rHr8g+5U<<8kWoDw~$B
zBlO(_TeP@r1d`nn;}E;z;DPT2GN=dxB_H|u%I-m``L2xD^o6?nIh9HH)=K{zqshCIxXqP@DrS0Ro
z5AW;~Oa9{+{DvfIR`RE;DC$K}D
zTX?_!$kYK_L&+>&(K?CVtA?u&RVxnb3g^Yno4L8DYdXHaDlRmpgDG1{w1QMz+<&ix
zaC-PMjRb3J7SYvcQ-GRC0o~U&94&(jO=bKdwyfB>Ra$p+iquHAMmKy)S^I|Byrf|i`2HY_EB$c{(g4dd!y21j}OJ_(q}3!+f8{9J}=h_s%VF9
z@I$<{p678_wmov>Wdpzh+^g9l3Lo4FF0;X;WrUf|+;uXov7f?Amk%k54T?*v17QW{
zAS>sv3VWPk9sI2$mjy)SrxW<_eJ^~uWP~2#14_QgtA8DRUItS#f_$p8NePqpIb_zq
zCaS8agz_3_Hx_>oR&dDu*)jC@gx-R#{9+p_&h$q=dq+51&d6XBS6DbN;N0>rBkXsP
zAI8mZ-8aGXbZ}G@T(Avg4+4el@6?@F3v;djsJcH9cZqvr@s9&TNld6mq2u)K1H>99
z8vfncK2NX9E{L~w6^1w9cPd5iTC6^bneZ{|^@y89knF#NQM!)efUdVdxBy0jeaco1
zYtCk1c|C!LKFY)9u$)BQZHHsJ-p5fv`&;*VqQn~u(FdaJElZxDg>6_s%%Gt;wTZEa
zdIb38a5JK;NApZ$u|V=jms&;d70>zRgq=CI>pFOcZwgN0NX9bp
zS8E*e{EM#p6Kp&7-uyP0Zp%JQXgBIJ9*T&+=+z0Pbig{7E(th@1y{V`U47|1lOMhg
zqw9uZNL8rdMouHcc%t~Hn(3e?`HgPO9oy+ZQ
zZJ02N3y{P){HeOGzNt97wl!6f_#%stRt%xna47W3_=O2=IQ>wI&nVV9E0z7Z^!k&b
zqn(c5R&Ts=l3U*xdbr3|I&xo&;BPbgZN}p0P2=3{Nxjd$SoZ?Rz}Dy*#2s
zS(L%5`uJTd*;XsXV$>5BP2b_ctCi!FE_+L57oG}j%$k_NMV8@NIH3J7_8UsnIj^s=
zZMyAtV4KUpmxHwHuVCNzmJV*mt1GScP@cQU$N16e04RQ(q*BLwc6~en7U=ZD?h!fwb
zIX|eD1w6ztVbj!7>aBikoI(99eMT<(FlHP~Qe#%9NiA{qRf}<#ynNhQm3$J>6ccu~
zeQ5jw^ikhV0wUCPbDlrg6-gLzYX=r>F{Jy&buL^w
zI_T;Ek^6WuFfsAOMJ@P2JFi?AQX@c8S0_vBX+th
zTsqcWMvXy0EjprbMF>O%^T3)D4C&vY21>JN(dKM2{6mTR+go?M?cuAWSW7JiVTev|
zLSVb>5RzVg2ns-V6Ge(gF1ErKN#d*POiUr*l;c9gDsfrb$bWC{&EgRlOdA{8XNJu8
z5o)?f5+K?&96@C!VD*H<^6sd^baa?tbQcYZT2`7P`N#Le*rQX~lv9)YN>3#$b$S7e@=eK#P
z?)-VRmDH$hXVCiS&h}9@pjxT^Mg7k)t_SRFe8nn1{U_?$G*~RvR?7zQ7|0&gEDjZz
zuwY@YTbYt8;a{58CY?|~nhN-Q@6c#lKPzU9SW-R?`Ih{MA5!z2H?uNy7IP6Co{**P
zaqAxDCVP=#{>QAo#f@oai!TfLzd1k|*~-v%oUk+4A-5iD+J{?cwYu`lxUfm|AZ?X4
z!WA{R77tKY|K|LJ`gzZ(y{TitW(&GhbgOmVH)^azE#Y~7*xC65A#m6H!0(XJ07@b#!yKL!$Dy()DxRRN#8ed@<{{X(626WUaRMVK_u<;mywsDyp;DQ!
z_X1z^iz3)9@g4d|*#R5sc>th|Mqlh&GjW)2VZDB67>JHLUHD~={$VbFKF*#=_za@n
zV?z49FQCF9PB~G3Sl08(hUUCYp8>@L#$_S0@o*A+!DUn!V12JgWVU4(!FLJQZ%dFM%~
zMy2>9bi~j38ThteQHow^b|Eh2jE+DlCw7Gf+NIrtE2*67Z=~%bf?R)s;|^eNayW=b
zl&;5U#@A7qouQc%xu8OE^npD3)e0?GOFXE3y`yL3Y5($-i<-JlpqX}2(qhe)C!}qe
zAJPCHxqPttyf^fuH(zY>uiqZYsoV9(W#8isphaQxRVslQA()pA%8{
zog<_zaa_Vn!E>c4PNfBxtIoOZx$2r)KYKUw$6>U=dQi*%9>9gK-5b6?co`W+(5^{ob
zRf^g+Nce4NVQHhUUb)ReuT^0R+HMj=vbJc3s&2NrxO$FFt-wZlXzX)s)!|u0r1-D4
zS0#1RQI^yh_ow$L)b-OQzGA)D_wnefJjwot$J*k6TQ0AlQiwl7qkW#i;NmemKoL3(
zn+gK0nZ{oU-Jm5}5Zh-M^;a~>wMhE=OWpr{es}c*ja=b8wzUH4P5VJi2+H89GH#i>
zyK_qF=T^xJmZPu4qIM!Jdmh@hxXYFBgLZj|dbe77Yo?BK9}ZJq}*
zJeI84)=b|4Q2OeJPRco|PVAcWl3?QT8m(@G4Vd5C6QH0V#rhWp40$%@P|xcZkK;OlOhk`4
z-NR57@FQuf5PYv=>xzV=WWU}Lp?iPnf@xF#SOfNoPrlDV+SEF{5>DLew0DPjC5lxZOFU2+5D)a?#dl
z#0ur9X*~(Gd(enSmAI9Y>e;s8@Bu>I^bjUa3Q?*o9lcQkE}cxtikCT9|2jwExx)xdp~QubzK9x%s2V>6nNM1443v>Iy<9$uXmq
z3KQd3llTP=9C%xPCJtC}RZSGpzJ}eMdCTGS)CN;TKpQAU)y$PF?gw?=EYYvAf6+dX_Ek;I$rgC5|#R1Hf&*+1#~mD_GF4pdLj2pWh7t5y8WS=pGj
z@CdI?+`-myKK6*_Z$)qznX|u_C}bG0EIufb&UG)CtQEb|HoBkRPHBaYL|PYWLC%>4KRe+SfyjAMAF@u@n^f
zcDuZNR=hwaVA%dqY-667Kfkte=cK^2?r30T8o9}X%QrOF*z%W^get7wmm}5L5r+5w
zeJE(C?~33BU_QidmmN3c_SR<6YToU~b@|~pH#2L~Ez$GrAxjl>9C>7a^wyN5aypB1u0aA|>@GJMlo)yOn
zeHx|EANoR8Nc(vDrPTV;iK6{LmrEY4$^l_&1v;e!IUh*+Ii+Xj#f<5&+nY9FB`=oX
zO=`|C0W=({@Ig!*Dfd1#xjjx_Qwwhyn(Okke#Z1vOEGD<5ID4dw^rd36x5wajH#@SKFh!wulcr*`kfNFCi)V
zcmZ{Ab)a5T=&_v=?$gQZ`r&V`Oj;G$^uo2wOJ+CorY^Yqk9&7$MOa&-eudH7{BAg}
zuL909Yvuneoi8}7K8ujO{qaL3EcbR_gMtcgQtd}6+qZ4?H%q=;aVoN&aN+gOdcRD2
zJNO4m4(9kS_X3GmuCVOO&HQOyLn;Rs>ICFha(%#q->^rXnL-g;G}+lm&fda4*%^2V
z$f5PlLGY1U*r#5tvpmWtlQ}UP-!B`PbTpL6s%1avF}t6H)1~4zgsXNV3%FHT@C}YG
zwM#D@eF}Dwx;}jGHcB&wG!5Z$5o$qpN}sv}sinSnyRF92RX}%G=KM)>Wh9Xpu_sX`
zi^-ijeyJz7Z2n8`Y|cef`|+nFwW$n8^;uA8+@y|8D}Ezw+IHV8F&}3R^Uos2BoNyt
zobz^w+6cuz<~6gDZp}#*bn!dK(pKg%M$*@_>RbnZ39G+WiD$2
zOIk6BGUB~6F
z-^TBG^p{sf1H)*%io;IGAFK{;jnSC3oG+r|&3PH@(C-eG7CbBX`g6N!q5_LHrw+GI
zu5O$}Tw}4g?b*m{DGe7V#&I@?6>Ka=uSD0i`S@V%-MO=fg)^dJ$^2orW!IfNU-3n(
z{Fo~Y@q>i-@?AQrSB>3Zx6!GrMxLxH5$8(T8^*7>xu%J@-$kx!mlFI|
z@g1#)(LJn0-AVP-+A)vsMMw4Fsa$R1)lpYIZE&1$9+V!ERDg&NsH4kvtRPdPXFm2I
z0h0Yi1<_fb%UQv#2G%zl4phEfkUF)KQlDV}Id3bB*CEz9W6vp7rbD5F>#?nEk3wx4
z@g|-bgZD)|vV~1o4C>oN!|HA5oyx~8sJF{^qQ5L0_J&zD
z|B%j|vfg`qV|r7U5;CCSlVI50mR%xS$ln#k{UO{F5MI_rH?2BH9Et0+P001tl@X46
zm)pl<017S5jr0NZy}f_<8*C<7BRZ!}R}DN}^k<{ifAwvxuMCmo<#O^I8b@ljAgTGi
zCL2-lj;>d{mdee86@jlxUMW^zz7RVX);zSsqIn%vzmTa?gM&P|JJ5?%lznyUOR2AA3I(Cn-;#9>-`tnOa{)}nQbhYQ17n0
zV>!@1>EvuPQ)53bZNicv%HbA6EmJr5PCpL;1}!WV>1Z!KWZW9;tdc#~^JOx6dgxdD
z%|L-jV$@8hllxcm;V7n;>SwW%Ilf44G0eT=b&-!vUgf&k*?RB6bGG02Ss$!>GpaXJ
zG~DSmOFtUu@88LJp$3IcFK}1)O>E|^0khp9Urp#AmUKEFx?0)9%-pZGFNl5DeO$<(
z+~?4EV)d+2%AB6FJYqJYlxJegJSL_>)HiF&uexHNf8(J
zA$JBr!@F6a&U;=tv&{ACM^)z8xm#m7l`7l8j(vr%WPikb5DXVZbqGxp)x%G0E$Z|-
zZHJaTW&@vR_WFJJTfgm}t$%XAsjQZ_hX!xQI#csB2s1-x_-EVlRRVMDoCDMgW?Y=l
z2|bu7i}C|i-ji7=t!l*_%KZjOm5G4G8{|$|?xuA-W*#l)kR!?o`QlejM9{4&xJ*KY
z>}TNunKn0s8=Lvf!xrs`ImEQ}r^54zLJ;iJlS8MjQ`Y*o}%+=!${!8&j6V6qqJyPr=91IY(PNBbxqN1kBs18
z>L1D8mugjzZ_}zGpB57Cm?Ib2e)0gg@TLMcZqG-=rO!_1o+x`%6lA^yG=Ckub{z|DQei^)TeS
zLBG!K3v)btnV=un`eGkB5JC&pQg~ZlJBnXMuJ>|3v-G5SBy(hoY8Fb05kGLIyr{KiobxvRH0R{l!31aFXcNyGU+M*KKXMu-IGODD@&Y7;zR=A@69-#X5Wwm&6O
zBzbs$jqM&FpmJZ}y;L=Jg`STF9rn@(A@KI)y=Y5sz(a4+tv42_i$Rbcir{=Jd&
z&-TWhC(=@=Y__Iv%mE+XL
zp~o&U9?B;0$yUcqL}@n=WRdZzthasSnT@qB81H+NTUi8^mlaSOe#DD{UZvwNG1P5K
zqNbcCb8#(K_NiK8&7M-p$9B`3s46m|_QmP@*Q2;|-j(t|qH3Pmq3+q}b}e|D@e-a*
zP>lEY=UZBIVdub{F^MPYXgUk#`apzq^sf?AZHH7cASK4SZF7
zFFDw%P83aO!!!woxjK_YQa}MlR@-k8AwOb
zKCE&StlhBa9p@#pF&C2Bi2r-yt*y~OIWWlo=tyC5;`g1KS*l*O(vbEL-}#IGAH!8X
zAC+8WA}=e)XSLpTg;=PO>tzvgTKyZ9B_t{+$YyxJBqcGXSPnH{xEB_&eplv^NqYq{
zbc;|zDw!1O{ibF)n^k^&*>EDTs*lhcy2ZxM8oZD
zC^(OHgDV>;_lXNuaRt`yBkXx^L;FWhY&HdH+jJYi_nnqiPkH1M;m^zE2f1ereg;E$
zZVgH*&wIium7IB!FWucmy=_;$)g7cKy;wySEz(Y*_07()s?|OpaOyI5U6NJ3*E$w5
za@qwRSVW5z6QqQeR9v5wQK$?8kv>3DXZx>Vvbe$p5$Ro5H%V^uTOk5Vg`}9-k(a6y
zhJykmPk}k;_-}KQmBp;%iZY(so-Q9T65e0C(b(ZiFJ+wem_(ZN@kkb>)xmRZVdf<^
zI<}90eayXp@4E+gxtY2qzbcJIAt%OU(+I7xrt~ULA9y}IYnlSuT-zi|HIaMhO_20@6)Yd=Q>|S~I%c2|
z?s#tBCed;!8cNtNK6?|rS-;}N9}$dl?q#l_5}n>sk|dwW5uc8bTS|EWQMo@9JdvO`
zg0qcV@_Q!fS7st9Wn|0)9hUWg(9a$3jc1HX(2uL}Rspk%iPM0DGsRnv5}6!5*DBRc
zTe0@@A{qRoaPHJQG*!FprF(05UORzhM1yiBlx;WAU1Ey3ETO^@n_C2ZiM;P*+9jm`
zXVqx$##+69cU=oL=Q99fO6m??KgnFhCEM!suVwwy2`&a#MB&On5)c_HdJXuiqMjjF
z<_2rtcP#r6o#o6Ex?WR%wTUd7aV&Vwk4@f0t^4x83XCGz_G$U_!c!K@{EEma>E-yV
z&M6v|g`+=UJtud%E@3hmYNX=Q;y6u~*fGos+j=~kYiQ)3xGAXheLjzHtJ<;hUy=cHMP(b+iMzMRd5qd_xmAw1b__C0#1
zM_vI`kGePc;Dn5v$3eA@))DluTMOEVl7)In2
zPx*)$nI$ztU@g{&HHg1AGF52k$m^Jp(p(+k_j@J%o0)r_@~vTO0_P;^gcR4j7KqM6
zZ)h^^clO>A_a@S@=4aV>g?CeAq^#kZ=@n}kA?v>99sdG^|0I%?{5@x8NRx!CQXCQm&(%-+3x-;T}?DSM)#WT1JU@R{&Raf4y%rbo)?(322~t-!D*MoB8sA#
zD+>tUAKXqiu{0a$(m^{<{dyP9&^>QDgsBz-UD}C}OZa@BEGGrL`;^OJP=$ABViDKh
zQ$?>zSl$D^pa&ZEHOeSr6YY3}5tuK0+3da5T?C0;qU)g51ky}V2Ht&WKw>tU`gbKG8e!eXi0Cr6GOFkD!ga4?&`jh`-U`^*=8&Yq{XNpSJF
zJJ@otNw4Q@OD~O1-fqjnL0+*aaorTiCuiK|YSHla7N4~5=NRz?@otFclPiZ$dvJ_P
zAuErlQepCm_|`l~tk|6Zo##83v+5V(W_ZU)#7nt&00mx4_UOSUd33nUc#kKFD)w6%
ze5sb1?MaL#7N6e?%Bqj!I(`M)hP5hcAGJou=ikDs^q&9$;$vMQ>D9bEsgqy3$A6nE
zNcZP1z2k?h)1WFf#UobVkfda(gx4b7Mf)J(A)K6$M>(IbY`f`Vr!F`y4qs#(W}xEt
z;YB^|*>q9`DT%tt5XCS2-
z*_C%kj>&NV!W
zMhi(uAqb`FZxWTq86}z@6Qo*TvvWH1QQjo^_~r>j|rpJ{cp$
zy}?QuN-q=mz(2w*l5@Q=SWuNXw&JJZAjBJ^Xm21io)vy{n5<3$l6!6wuB>nrW{2OY
z!gn&-V)!pcZ3pLvOXW^c;;UuI7hzp7cQV)NLV{topTyPn{^2H*A_fx68VQvt{7Dxd
zzVThvY?=<>QQ%KPtfjeRAdju(4397^`NdI^($AC*ES>`p?T4XTc|@}?W8xSx@wyQ)
zazWN&kJ0zuV!W3`OGB3D)Su@ocU2woJes%AN9@ylte7aIe?cmy%%qRqfS1)kce;YC
zC|T6gZQEmfvZF%@_dC(N_BL*qQ^s>g`Iq!xcI*w?nR*jI5&-eDc>i$z`K5fi1_K$v
z^d}8?R=wKmg6WT8tuMM&@{&;E>cZ0zNj#I~+bs?2O6W{tHo{)CPwAQ&iBAtS_aI9wtUiMYI!({Is|``^y6e<&K_>Q?hQyRI(o%Ha
zZ8j)LaVXgXR_VI_aLNrUx9|4pv~H#q0EZ&}X;sZ9EMEC)ss!DWoRcF^D~j|8^=|&M
zU%7pkyruw!%KSzum)l8P#kKIsk5-RS_
z?c96ab}di($Wc_Y&BV|rl~x&=t3kz3l+|95Z)wZq-5Gl7QCnT%lG$;>scbhN9+^vZ
zSvG_9{JT>;o9ACdf7O|~+m{7DWC3Q&>T?GTN|l-^LVB}qDS8(s+m)rmjVq;n7E5ck
zed=(RFy%(OIu0+!9zD?rT18zbqm7Rwer|mdg40X18L9KY^3;rpA7LiTz5f1&%J(4}
zc{#pkk+mbIi$A~mRoo3R-mCX|*fI*Z^%flmS6W%j5>Cj@s)GN`TFAx>=
zkzbD0wQfccyjkDGy38zgKqCRfAT!#mU#FHlA##mcyr9<$@ZU2bZL?2A=0*EV@2fEX
zEzEqMAz%~0@Qu>AQpHsp_w5Vl7c748C2B^%o(=i2r;}xqLE=iAzy#tTy;c+m2ab;+Ak#P&C59_nv~;ZAMwx4
zDtN@zZW>z7elZb1$cHQDgn;~ajA)26HvAR=)9b2-xNWieFIg)vEbK30)kGVsb#9J(O{mx;K}3#XN%|X`jRvbMxaz3GoeZ`=n=7AN(c7LH#=6||KO`&iH^Fjd@jvncZ2nUu{nRPpqvg$2pYEWwlG`
z4Q?@W5wdTsNm4{j1az!V339-whZ<4rL>rFls5*
zmn{DlrDn`K-)9dn&i3_?mRyOea?xZpiAA>YcIAybd0p^sHZqKO|HL
zYPmbCdwoF6Y9DfQZfxcB9^m|!8y%BW*L7tcjw>Py#9Zc!V
zqx$||jOpW79yxFRNI>6RgG;zn7a8fU6?PEDu(UUVXPgI)f>pgX7}tH?Oby?>-Sm
z1qthOK~h&SQl`uW_Z9tib)>J67506~C>{xY?uyb6H9YPDNh;7x&nmb4w?EBjx7hs0
z$AA7>gM~9$&h`cve0>+kHm{%KEuy4x+p>5y1B{S+Qscw3zlh@o@Q6!91UU^q%8#Zf
zo1gBp?D5kO#a0rM?o-NIz*pNkt#9CjAg<9b{yWOeo3~w;!!l+rq01WDYHly&a#2fu+@lZLXJ6XXrnK@~C1s@5=h(D)hw{s1W#I?WVsg$(
zNqRQE#bs~6A84z`!8uYnUm?!#h_fr7utDCy4M`C|EAAGvw3x?s|M7jth+6WLW_O5x
zDN2e}x``Nydwzu69Q;OP1DwKG^p;hn+do=``p$M+y!2-`uojT~D}?=9sL46G2_DW;
z3%KC}?K~J7bibB`g9@n-Y;Byxi=*VxC^7Lv?FD`1wA;q2HotwsrYmn$X#!#S4?{QC
z@&E_e&p}b&lw&IyiuuI1lu-}6-K+duIsfYZ%dny5_;@2T#jwov@>TtFC@IY*rI_?Z
z5y+vy@T2RH=+)k2kTf_%P4?ma<(jW4NmKTIaXb!@+1x`LVzRE{czf0av_qd<+s6TU
zyCuBH!n(C%lXuN%4E(l@32qIZ(Sb~FfVDKxzQ{Rh4;%?t%eQ)|%x!Oc5|dga^C6=?
zJL^YG*A-0D$@eCG{gijs%MDYhd_?@7Ns5>ZDzS{G=NLPf9DX&AnHE*e6!_}hoh08d
zK{?vMXbq^Qp(*=$k-B?&x!KgSyK4bVzh&1CR8^DD^SyrVQc8K28I$bST1i2D65|yr
zcTF}*ec;u$IN@;!1^yXmX@G1dC!aTb`#slvtyXPDLi{nKp;^;(FShG=E-PuUa8Bjg
zVa-tz*pZJnI8TkCmor{qF|nA@Lt-|6?i6KHLd~1YEQ^y*G<>yeQI+QdACRSPO5yjm
zHX|4m7cgzH@owMfK60ykNA
zP`-TV&209+|5{-ChkA;$QJT)@`-8wihP0JQVYIpMGM}b&
z!|oSw(vB-KuT@D(Oa;F#m2SBuzV=O7fgTayg30OOnffiQRTx4|m`y`>&7Vs8zSM&t
zRAzdx;3}DyT4iqii8haObVqi%h)>xiBH(}b0*jX2kH!whT9@PDc@O?T@40tdTJ$99
zEpv>KfOGv1Th7!Bx+8PHCZ$lmogn+yZx}r|a?)_REwg^H6)RnS&e3t*0|xu*ssYV?Mp*7_k~hp)lW}DE4PU*9j4yXm)*o
z!ckWn-`MZah#Uf|rw{vjhZP+WBVf-NR?w~J{EmNpA4;&bZ4h?VrIhzl8g*6?e?(A>
z`knmpPWA$3EJhybA|vj;x<~cN$WSrd{V6ABs9>
z8Gm+s_1NEx{*LsG$lF_=LqqD|x-XsH1x+=8ZQ~ndq~}2nOnWKK4>Dnha`eNvp515m
z!AjsN)xQhkOx2HFxV>xSmG=Y^gmL%r~9$B&S!0Wf_CZd6mcDn50CgWol-8Zk4+3
z(f<}gdN|!gK--sV=SVH%U@_==t!t56hZ20J=<%IiFm7;2#@QxW9XebTp5`%f#l*i!
zA8uHl&3YfUNbqXYqse~`sx)zRU1sCw1f#;(CYhl7E1x2SF>+e+YrO$DslW25r<-Rt
z6>NAYU+v;xaW{K@&MPO9luagNNMgxjevM{y3_=y`7Zj9G(T{)CT{~>+A-Yvsy;h)p
zZZgH^5C9&zOiS!CiS=dPexu{Zv2}kBa@lDlG}+}>dg3|T(4^JtjHoCw+;%*mhs@E)
z^FO@P|92+q;FJ@Kt%k7^?1EWkG>R@{$+)N5cSRcB8tO5vajvtfRNNSRPL;Zv*xlfk
zN5tlr=|Kg)7t~f(C4gUyL8jp>pMQ&beC%A{lXXe`bl8OjjaOt?a;-_;mje3ri5`@8
zs}w{}>-Th-EF__*I*Dvc0t>paK~mSGRy4>xytu9aWjW+&vrZzo3c_49ufT
zjQhZirnSa(3hhN8Q%xCCL;i(?z3Q?@&9wA>a3f*q)$H|PH-E>nU6q>;;TBxXCx76m6<@!uKwR;T&GEtOBV|}z#g{6Y
z%jf&!*v?ix6;oQT?<&DMBQuQq)Kum8O(x8tL}zGJjrC#fW2W!CP4iFe>8ZJq%X)pB
z*3J*2lhuQ&!Jd(mIa5>HrPaHp#DZEMq2MPqAy~e#-A4&S_USR#3XZOmr|s0vm{ScQ
zYs!lkZ5(O9hC~LW%qIw#g$&Zw62K*Wa7$OO5pU`6S+KdYFW~^*pviEV1e?gOj~sRC
zlUlt=>5k&a`$wI;1mX{i^sHG_t3J$H3@&RjjN)t2xWEb^TM|Qh<+N(<@MQ)nALPEJ
zgh%Y&NVLD<;^!*m%hyHFa(wed^A;&v>e4%QuS{I_k-dS0!{N8C6Ba<@V
zvBw~62#G9>vRbpgR%sIdIC*Hd;d;4>(+jeq?dSUS1MH`O4%_Gy0+!_&td)y)ea;Af
zaig_JS>h{qP{Aa+=|#DW-UtWY&RQ=gP&lo3hU5SEi@cxpESc6u=pvXuuqjrOQ#UGc
z!wQTU`!jQ{sIqxR=hMK0}*Qe^E7p6C_Q_lbR3<
zq4(Ip)W1_)6uA~^u$w#Y=8$_eVVJ{&D-7N=ohx$nZV4D`ka_as-~b0*qvuo-7UQ%~
z9J!PQtl=htod_akHfL)qsLxXu2hlpE1eXl0?g3g%tg52-y@Q6s$qnZ<)U+tm^hix(
zO$`Vpi|RqfQ`VdNH7m(1)=T2i4S+VE(x7tl^Qy@r
zBQ$4NFY*!Q&Q}O70sUh_~3yQKI%ol8d&HTiQ;59ZhS4$vOB6
z*dPjOP`$lBG5qO{9O^sy|L5zTGvhwYc_4a}HZ{W9WU
z{`6cOO7%WOBK6ikeB&n{0r?o(=Rq}|5p9t>E_B>N0rOaEg{T$N1s;wNtU
zWp@Ygb9~WQ+s`f`B^-JCTk*G2aAyy~&(3T5>s`V=cROf0pa30ou0^B9-Pb>zZAp*=CnBE?W+
zL?>l}dR?Avb?8xKAQ|*n|oU)&6
zNtTM0n4^>&%GBl05B``SM}#pQf4(ZeGHdQ5`i1S;$FC)4n|059&$a%H6z6Snt=Z{Q
z@i&>R{%sJu3^fATmw&z5Xp&`nX?p0hb0Qm%f+K506?@HH6oOrYAEn&MgToK(Bjxe-
zpf5Y?X*{l<2Wh4g&Mt=;3tZEU%?ha*#r@T{uqv9HWfU=lanpj6A0nDxzFD4cI+~U@DVkidaNrekM!VBA#a|x$YevGA4y9odxgp6BK~n%D
zo`N!?@;www*w{AIFwtI^AGkTzx0HL2d)8Mqa&5}{$7UK=dqh6q-z&8&K1QH(MMX@T
zoxys=fnAa$zl!`U_hG`vqhZ($l6AFs=S>sV>4K_2yS9ZclI!MFx;$aqO6m$2Oiq$V?TbUP8qxa7v#dZc
zwzTuxry%tGJYQDl5+p_Mcm?{SwRnZgLQ(%|g3Fy@&Tn)3(<@Uo&cR09Hj>T5B3{2W
zrMmwcwekP3)VX)yw@Z7D6J4Jw4ZbMiY$-E?e-M=PAd?|27cw}?8tF@NW-852i7R@D
zYL+g4(Kn%-uY|4+?aDcA+EgGkva=|brfn(PQMAu4aqp)*Vh;9=SrgHHtfc$+G}&d}
z(!bU7m@H5wYvfxd|M8W-Q%^=Ep`+sh)Y;%@2i=_-o9ezNbgr(vjmMD43wuWbOD~{-5{1JeECX?OlJ+I676=
z;XyKvsB*;&med4-iv4NTCvQEnyAomZXeE??wu$tp;Mxx(vjv+sNo(S}&FuaY235Tu
zG}tM8W086CmuQuezbjc?>A2k6#&{vS8~mB2G*M1Js&_P^Af%)SCbk^v2pe*+LX}%6aj<@`CfsR9k)!1oFQ`_?!`O4s(R&%U2!p=^gvX=$a88wc`
z?7&u*+gv7U>Bxt<_&q4uohB4G-ToPUBqyR5<^+Br+p0oezjb-Lf_Ju&9Q}NP&i?O~
zmojAKS=O!P#^;w}7IY3zUKFw>0c&&Qv7;m08rrkJlprz%7>eS}^GuteZPyORAxc^Y
zH|*-s5Y)Qrq4t?Q=DV<(`m<+-%G<9GGNq%k{v`{0^jovF7`kik5is8Outc4G1)-F0
z!eKG~!<8*SKI=%g#2I>P!?*lqm5Z%$BEMwgsNEu`tkLQ^D5C7?h)yN?Be7#b3u$X$jg
zEZy?NeM6!-ooTsJ5ib9mp5x3CnmC(`g!PH-7iWq+unc@Vc?U|bcZ+N}`2@n1g$l^e
z6vGkJhq>khKh?xJh<;Czi5r-M_ydg=26k~52z;>Zqu>^76q&WQ^ahW0TPKUSF{nXm
zQvq|>oz5-$<%fF1^B}$w@|C4iR?Zz*eGT4_&)4Q7AmYAjsJOFR980@kvqaqUUG#_c
z69wrujh>?U(v&^CL^-&v#o*&SIw76BVYJD?7dX4PM!Q5Nsgm%J4gXwunsRiQ#2PP~
z#0{M4##mjL+I9>b>v7*!Ed=+!J_cL58ZY3a=z=loBp(y9>fG^4BfwAqZh|r1na9q%
zQc&Qy=!G)hzPn9^)kOCA6=}ayhOY-Xl|RO@7Q=NF;tj=9
zYO{`fDUMei=PsbXM^faV0H#UT4FUTgdhw#f980fbVxI`L+9Wij_i3eTJ$VD2!icd-
zcM2H?@gvB;{dSe1fEylb2#V*=1pgYp40=+Ujhp{LyZ0@@Xx{@YF>PBo@Sfh0EBhN8
zd8>>$*u9AYN35E7?!ylwDt>KvIkc9L!sdZpG?xp#VU!fm7i;56Z7uQb_&6D!1}NP_
zci#f-j>RjP?0A4D*8eIPa*i?HUio5Cw-0GwcR>)oghHsFf_Vy#A-Wsh2x!6~&O0oT
z+VM-feH^Dz_J{Uy?W)8sIc@Q3ixE``PKeLAeV$gfelOz0M`x|OFHhvx(kB(867NU~
zn=$)naI`^Pp9p@)0A~FSCl%_jbiVC$w-%o@TX2|Npm=l(S$oHp`1?(@UKfa;icF(klA;XU^$IXp%Lb=(_G1vv8888`o{HkbMCro`e=WfrAuWARga%+ULz
znUi$QQvwsU!`M(vp}3Lzp=8aoBEfrQfP?&QX~|)4wTwV5gMJHgZo7)~h;cbzv6JTU
zF*9(}Q=}j-?KeG($9Hd1e2s(=BnUaKG&y{U6Yw!*0D7>;kqc9nr*8R*f~@!hAaj?RE-23t|a5UR#KsZ6>H>P>26(9sZvlnh1F9
zF6fqaz#=6fNr0RK)+Tr^~JR2wt}y`))yn%z5H$>tY%TYsGDP_
zLZ|=XlRK}Y_;D8Z{MVGc&9K)B{-J|Il2R;l(75MgC-4~aB_OM0m-ckMy8KE=v&@se
zB_;DoG}Q-_Au=la(a9d()aO0%kS+VD#4L$xE5BIW%aCLnPyO}>W{s(vI*xft$4SGs!V|wJp8bUj
z(%J+N-f+Ul;>=nVzhC?%|DOAsuPo2U9F!0;Un2x(gi|seN!G;lF{7Ip5!2cWn8%cf
z#;O|7aL&8?ZH5}}kNPewNWqLJ^;I|id<3w5;5F`~xGHZOY)i*f(g7JIas9N9K7SKy
zzk5FbjBOqFY`E`;x$y&19UW$3QpjSbj#T_;P$*UM7iKTB8z2p)E*VL-u{4kq0bFks
zYCrkvVV`U*rZRN{nUb|I0jZHgtB@JRKtW@@fthtTgHbr%dW<{tcb9
zYcNZwU#72d2FGIOtb90m9bUwqRFRq3#S<>ZOFHMh5SW7WXzHhT-+NG)+;wcBKmA$M
zvGA@)l_vWPo;d!PoeNOVobhS$R`&16wZkOA2q}j!oA-9jhsyeBIIHB4E-s+3?h2{?
zlIXUs3bUeF$^uL*n+IY3p7kk@lFSovd*8YEp74dH--z`m+>a_=`|{G`{C(67k5vjP
zP@o~~%ofY^257q}DB5vrk3gI)?RoLSiSJ+huCF`Q@KjZ&vs5*9W4Xzy8d?fa1|0Et6>&|6+20kCdh%s}08`%Vx4VtK+U1N$l{-aTM$8@0&omkkEb
zYZeMAWqRaHOcPK*;0sTuXeoaYKruJz>%2W-7|s-HuIVrm+iPzeD3fqtEniO912D`
zE_-w{)_0&bDO|h+Tta@}VZJ3xUA0VGPg{@9{`k0odp10ePCJh2Xy{`P2YFy|4UL80
zwyu7ywH%t?q`1IM;@KQL^i~-pcPV?D(b8poQ{0LND7rome;99mu?4CnULp;ENz8CL
zdS+nO$u;D}q+xKW&}f+%d@1KTuLFe=D}>
zSMOf?lohB*avv7me3#?LB~ku4HKkdE-G!+Oda(r{B^;XSf3vXqcOwnkiP-1)B1<40
zoNmzXgqsLIA*oExaIuP)<1LV>_>OWX7-yQ70{55=ZoU8@x$DIohN
zO{rmhaLwTwUnwa3(Gzow+>;qwo;D9$T^%@+JXd+x`m$f^VW#=d@BOvLE+v5~3Q_?^
zLDE$dYlw>m11{E0c_kt{6u_ObyYhz3J}5-G536&2+Ep)KtJbkq+jH#851)p<9{*Ob
zq}W=5(%>hLm^y^s6j%U&ZW-#A?X`Pk{yo7x;$|;`atRnU0EL72QR+=JJ^?`g^FQex
z6QK?swapfy=Vtvv>(*w5?BTDMXr%-Z*|q*n22wi7#c~131V2#U8OC#`uUc
zV5(YcGhtL^Nm%#V15RuKlnP*s@tCZC!CC-JsmqG7L=(v~f0$JMul<|FN9{2>SLg
zh#TPJ2Q-E%8W1?+i~U0EqF-Pny7$2*O77p57S5_?z!w<@C_({9O4b;;#ZM}>P@GL2
zRlI+-xFD#b1Sgw>KLbPcNo=I0A)3zIfV_U?1Z9^sJfyDo2kblE#1G=n2H5Rr`F5TB0NaY8D#7*VZUSpkGHE@dCD@o
zYWeNYY!aDY76=!+v;6akxOe4l&KlFjrk?YTE(fhKiF!rZCb0f4tDx@%fmRiP)T)64l+Mh4DdMFXNJYR&=W
z7Iyc>jwl6cGS0ejEMkI@cf=Q*Kn_JEgbh0%2)Je}Xy7+()+qbo~YOsSY)>@f=
znWvC|9k`Xan5C_Ud9JabNf}X2UdmHCgJxyAIK38c)SZ6ZuM>=Su&i+&_(482==wP!
z_Df6ilImuBHP>cwMgS+IJjy#EeesH%skC{jIPt5JSbGWj)xrTF>Z%X!+~7+Kq2UX#
zafFz7=SRcmdHv2@5*k+G+xsuuRf_+3LmMEGkASipw@^TPYcW(d?w2tp8Z;Nefu|LQ
zvraAZUN-gTws9WLBNb#U=oG`6s2N!{1n*QoF;WIY5!!A*w<{nKu`qR-fN@Y0ZCcdI
z>kPIs)O5oWV&EI!4@yu!1g-X2i+j=CvIy?Vh&}?XkG-<_L_&w0?N{&s_J$85{&G9^
zAFn)3c2Zm%TGb#6qUL?piFfkQCex3e|MtC)l>y}|v7z;TwleF0v@QcU`Am1_d-fTM%{>&Vb|wimiUk3Ah@(c2PMJM8;)`=sQ*TlVW`2IAWDU7p!a6ad_$z>QvqU|T8e
z95*1=r&}&PNjQCisQMIs)9@)=pRMA=EPHAsSC?}PgI@hEqf@Bgk9-~zZWH97bE1&h
zvY2iYr40B-!D7UBH6BFe1F%gA44+E+6U#F(%h6@7kyapZL}a`=kvf8uE|7@1BGel`
z-cYrDtnu)~g8GM(p%ImsXZ(}FomFZ4st&32R&Di{StA-Z(k|I9^V>OntPsW=D#J|YF{g`+u|3ChLi0ZBfFE~=C
z?LkwPZ(0SL+$|_Vt#!1b*ORE0)4IAg7TPSt@B^x~3*__9@$-w+0`HcX>FL1@*cciw
zjDP30UUELuO?70#{6c+83x|*A?IEl4E!?p@K{%8175Pb4D6xg~5?`T*D_^g3hU!Is
z0|g219zE+Z;~>K-^%*=<77zbPw>r@}>o
z*c0Ao6P$-m!V7Qjrk3}NUgGlJb166r$0#^h6z-M%Uzyr(%cXbGK3B~A9V%{tbx9-z
z$=ABkw5(yl>#|RoxCVYsfGuqKABDlWzY+l^Ub>t6
zNl~05K3PATz~d9!(56Mqv9a4H&zQMQa8F?9>W@Kj*#;4yAHw=CqpK#Eggk7IYyM)O
z=e~IZF`7xs@fGy+oGJ*)t240E!S(1{Ls@Cj$SHn^x_Y{6*aO8`qT)J
z{KZPx95e71n^YEVz=_tngk`!iSgx|&g$gw(h?mkCG#jET``=Vi99{<&=WII`NRi(S
z)@HVolkzh%rm1+38hV?Nm;Nnx6vi^}bE_RNi=VnPTgZwf%rC{Y*VC|!UQR&rL1dl8TS16b1mLPRzLsIx8vK2J;~Y~
z0-&`)R+L%Y=(d+HV-5MLu3>Rt+3_hCtqJlZb690+DcxV$+7A_GGIp|^H66fF5OQ#$
z3>nim89k-aHo&uWx|_^OfN`utn9^V#_8C{52`NcVXs?XgzJ|eVK$~+|5oH&MJI9=P
z3=(FlziplL2@|=f;wxk!)^v{XGd@3eOe<-E?~M9GN=`zTMiT}c-|gyD9sYhdy$Om5
zHsAL+i`IQZ&hj5H+bEgQrnA1T(et8Zj51HXq%09L4>t0bNu;b9>}`nU(T;*Zgwo!Y
zOPTHkZoSCy^BbE1EwRqLW&=L}!>hLxUB}aZGXeCU&Qfx&*M9CrG`(_*uWtYs@|K0&
z=L57DJcXX5a>IDB#@>EsS)x9}7nI2VTHA%D+d~om5X6p*{|1epKJXYO-OPSIbV+h)
z1h?C7Q3cxBFt0P0zN8|rhFo5G+$pLHPL;!|eRlR-D^QB;|5P@S|A=_1Y~Enme^`(f
z`?~0`>#DD>V7?;0z|`k=qDO{F%LVXMW+T4*1qpgXZY8zjN3l6`gL&OzI`j;Xe6A$Vw&`%n>%kl5K76Z`KzkX{zQ7ifrFW(o|{<48>@rs$usOQZ&8jU@b+(
zbRlT)X*{k42{gY3F+E9L(04}8X
z{hTNe8zyBHjoHq0K*%?n54Y{rKF_Q*@NOq#X(rsO!P6zE~if7SvQGZ8_OPE2#_
zXW1E|9FmbY%t=X}76Tf2Tp>kJi>QXk%1=zu;ph)q^f1@_{Y#>mD_kG+M8x2)H8t6A
z1M^C7M+N?v^9cpqNS7Byxw$)v*52t4cYM_8icv{dF=`7jK2R3DiNeSYs^8I{rNfVp
z7kELL!XDCpdT50S>;}0N+l*9r(b(NYG1o6+P_{>q)3S(0cYdOE65CNF?06+`AnAa`
zSab_rDYbyqyB~Pt7c`vrYGI#~+RD3-Y4Pq;zlLu_PGKs#t2w8pxrgFUKh#>sf-*3u
zHSt+)>5#Nnec^b0Dznrp{LwI)7o4WjmaoMe1SD4ss@%g~yetf@2k)*V>b>PRErR)m
z;Cimmm=?&mNTEkgp<~`QV$=~X6E377aMUghRb?b9HnX_|GK!iY%j#MR1B21^$24QNl1p15g6=+*9=a?cil
zNGB~hn=6aSD9!=PT$&)|oblJ^wD-^M%JUjbwTbYP
zWh&3a4CxID{GpYnt+r=eex>rX@$e_jBF$@%&ad`y>Ex@G(q%2Mpxph!8&nr(6YYyYTlWN+?R&5XdbIl{}GUq1Th>vx_x^jM!++vz?DT78-eL^-ls%bz95
z{s>zQkT~N)7So5Z7j$+&@3WufSDET4x-1hmR@qkPtBgCFN#Q)d~$aDIYG)YQhG-QzgYM{JJ*;)Yz@f)s4u6J
zMXG%T#`JZ>ZK~p*mY<_CKu8JFOY0YCUau9(0Z)~dJeIUO>B!K`dk)ip&a=>E!N{Nd
zB~iD>cg_pkp!}g7wust`{8G(c4hPW#*X}FM&_@MwQG#FgeYu-D;L9aIv*{ms
z|O1zdi~2`p0|`dV8%d&c25
zLK{|-gY;+t+ugL_leQ^&CC>RXw<3h(Frz-BOw>}qJl37*gZ{p7p5A!%UUqRDWTjAq
zXqEu84le+H)@9}63;rR{92a&5-d!|&eQq)o5U`bVf79R8~K0;h!#
zm(G5g^$9kU0w$g0rjLIp*5m}}%+Ge7t}pB!cmZ1w#^o0Sw0V>sKF;A?wiu^s$?u=F
zaFCYOiLP^hbN>ewclP9#;fevWRYg86!L}BwTwwe)Yg6DzCq*2Gf7&H#N~KClj*h=J
zjg7UH*hk5*5WUqMqM2MsY%d|(Vp$i)Pp!%DjC&qFjFOwCHB2dGb5|BP#gLVEc}aJ(
zr{UYb{^a1I&z#DCWK5kGU|CQ3><7af%NJ){PcHwWSFOowOV$?miElDv-;nii;mKHo
z%?j3xrX)O14qIQdY_S-*-c7MH25=@u9syY6Eop*OVV<5xrm+(Hndl%5BSww+_2=pXW
zNDJ~%n82q!IZ8jC_-XG?uxLr~hAHwev5HqLvU}{SH1%+|wmUWu|TI9CtW)7?^ZeWo7%`>|t;_s8jjM;HIkU%l2JG5`V|RX6hca4~cEf
z-_J=bzOHX*_VCN+;5wVj$Zz2=;<={?kj=_z2vf{2SK&-&@xdP>%MG&UhJ%Z>-e#Po
zfbV_&Mpi3_jvCoIk_%Nb*0B$=^3QL^!H;^ky61jc^8i|Kosiw{M4V07;5O!rE(uXP
zs=syL?%yzz3B`GYi6T%`r_#7Pf~hJ3&X3_|S>_Vb@4?o{ym~SO(kPooltRWrFkZYG
zKwW*A&)z%+k0EpmJfiJir8(vJmD=!}>K@ITYfQvZTzSORopk^@oww;3eG~ar8~$as
zaK#WV$=M2Zhgu&S;uEeJCFFuX^CCt1DY(|uW?<-pDrFF?(wtq&?K%(~4?msw+2TpM
zKa#ty+6|IQ&xsGS6`J=fe)MOaT9ks-T?jll@*6{}%r>w_dcu8X`V8->m0b}hc8n~w
za`>MKK@u+uZu+A`g3O?6PD86kI;TA630w4rHO?wOk(finfPT*mhr1
zYAMO9I|D-<`{BkIKTW2cp~wR9nfc~WAGV`D*^F{ZI*zT>{zdZ|vboTA(ny_I!Eh`1
z)@Bn#HHo8v;FAB$e`9!#P4=+f2HpC9SXO|S14=C`5Ed$~9{WRv7P3O)MMBwWSA+A5
zW2YU)-!i%O{sw9JGEO%5Nt+g#Ljt3b<-7gRBD*+`&XJSsvn=9tw`@NNYUgGtRVSvW
zK=cb#Qx0<+E1(gPFg1fp56QdX3-a&uh0;@dONyqqQj+kTC?CykJAUFVhXOL_({05!
zPVCnFVn4JgyvUXOX||;q><=#$dD9WT+aA4u-|{;cM8Zi|r8u
zgZe2vW6xFHo9sKANWPvM2BwR@cSIA!{E1ZLEF(1Qa+p$2pY;e;Onk7xoLf0?f4gZB
zK-x|mMmXtL3u~NW8o(HBTK-2XBrIbBHts8?w=?haa4v(*-4~OjryhjybOqQmu-IL_
zxIA(cXdN=eqAHOKC3Z^9p27VBT7
z7QR-M?++OujNKlt$tHm&u%8;66x4KBs3Y8^^)paq&@+ARmsNS!O9J|x36;Kp=crU5
zKFdCy7Q?2gsM_}7K6PSFu@}F4^zr{tsprFTG#T@ov=T+sJ=6zn~
zi^W!DwZN$W)10MSnSC>OuBU{BZk&X@X**c*(RjwG%fCh`b^Z-RpUH%tr|-l(|6Dt(ZsL|
zjxzWmeQF_Lxcz$eu`h4C!UF{s6O}L-zpL+cg2uBn-Y`CF9j9F%DF#RjWL@L<|JXXu
za5fwN?RTlWC~fWC(o)o>HdVFv9*v+jH6w^wl-AyR)}Bd?AokvSMG$r~ZI?vAu3_iEacb+*|Kq;DT*=3=WiH1t-!Vxrz*=04#mG_a(fh^3p
zB1RiCDXjQ~@|eIMMn9qEXGHd!H+ySt+8CgX(OF*{w<%@@C*^u7Hg`#$$g&wZ2V
zk^604jYVZ(ZUSE{5OkXJdoGd+g`b?nLXL}@{|V!~UBpwXFa3%M3<#EJC6CX2{L=~5
zO8!mQk(GY39==N4oKGr%OAzuX^?LgTSofOs_czchrvSl{Td43|l7U>rkK2aLlKvIW
zctf}QULi&z&A=>))j}YDGi&?hpV}PUf#1&(SqfvnS1E%i?5m8dRk{CCv?;SRSHX*b
zx$i5!I#%RIZ)gow)V(YdyjPAo0n{9&rZ#A8e|Hb8`P<<|`i@p(OgJTu@%M}utpOe*
z;_?DLRhN_;8B+)owjO4oYCz=yYn(hYIxwKkLSGbuB_v!N+gEb7_1E
zEA#!w{lopR_Z~a1BF}$jEg!Z0uv5-xNTveyNm#5=*Brb%^@tz!{vdL5+1Z*~zfb6%
zODtNYkYc8)Yzmn(PnRjC`$cB~^O_4Wq7%jRgGS*EhlItaJ6(p^O$I*jbSHZQWIHOp
zM1d-g9ysbkQ)2x&oB8qn62tL^-vFjoSM%&hay$$=o8n_rfNkG=Mv+s|EQeu{`}iL^
zT}wYhU-=8~SaG4pV?54hV&jkT*601U%o^4$_eH%J@O#Y_5e4dyR*MGh30=bg9D
zm<7xxiEIbJleLGqtlpWR94qfx^A9l#ZtDJ-B;rqD|<7O9bjro+5^s>ea
zw`wXmvQ1BB5s<}r=C6Uz~w%YqG>*Q
zo>-d3bXZh!(O5mZb2Gqt5L%9zOVe4#uYUXwAxrlEIc>>~)XCr*C5}vfqJh;q=K8{u
zO+EvZvnE@&K*=6lsPksC%ERY4pk7^3vP6=0`lxk&c?iXt(6>F90t8rPK$%
zHo*HXpO-DE
zt*1nFl!h`hX&WJl8AfbVrlqRtSmIjbd{8RKl3rpq#o7T$Q}lLF^jDh0H#OGN@+lZ#
zy4eS)aOAajUcfuhMJc6u3$gh?CKdwo2;@77Z!d+9&EAW{C}{1GWgoiZCDx=j&(ueJsjc$Ah
z7qfCajid8K>cm@3|9D4Q83JBhOMRa#dNPvnV&dNs+j2(D6ZEeb4z4iIT&Ss2`5m1&
z2JJ(uSJu3N_OK`X#RBvVY3r`7%_J?-E%L@@^W&lh0+VmUk6H#3G!4--JXy7RIgOMk
z8Td$$jjYdwhQC^eFvUwBETGVcbVWFMKt*zCKaNJ&FwK18Y@@4m#cE1xkaV|P6%8OI
zi)pole!m5pa2cQ#HL5SP`1tE5Bt=nBA#D7JU
z`wKZ>6Uq^-r>ALd5b20X+WMp>pnbKMQW92nc4atR@u5(h^9S^cS(d{bJM
z^D3X&>J^9F>P|=SzRt$S*6CBp_PpXH!6%3Qw1fju8RaOgM-y`KJ%JqPK~Bxuw7A=Z
zT~*xEM>}JqhyJycWcs1A7$F7j&twp_uUUE_2WKh%nSFTo1#bl{!sah&VMA02QQIAZ
zSb<|zE~0+C;~^n|uh7L!m5U0XP5n)Ljd1?^gR7UjkM@$~e%pT#Fn(qHc@ys#$<)Nt
zT$z2MH-GN~(4C*+cu0DhXHUhQ#$
zQPh18xUZFQ6o#Vm9>JRzMdc3i1OrD5kNQyR)_9I{+Se@CjGg91pITT6Kox;!UY+1f}KhDhaW$|@&%84`M^}3sX
z7heUTcnRHfo#J0)XGb1<{i&O-!7!`FJQ-H)6>Kc>`MEWuT_(caS9aR*V8r>5lJjK2
zbM|Us;lU)1$;JY?kb0hdicOHZ!MlIzmsA(KaXv)KE<;hKkCBn)D{DU!1>E-X?lzOt
zN=)%#$gDY|hepoVPr$}$&9a+U1$hljnM*_q%F?XLVi!aQ77)x_4709US*9f?3-qS*
za0<(NEZp3u-YBQ~UfPl6p7^2Ul5UB9cv;SE;1f{%;p9zvuK-G6TzN2#zRc^1IgfEj
zb{2lGJNn`>s7`kQY)r6QhaT0F76(vCNp>=V~F!hR(=uwo)oGtSJqH*dYA2MP%2vMS*qGH6om
zMl5uc4ASl^Nn-)K?L6kvo#K}Ad0rqdu{$Hc|N1KoLz|XrZOOff8C8_4+0jsxrJcem9(LNZ-Ef8L9Lz59UKhl}iULV&-W8fHeiIq2=k{q>W9b$g_9?
z-B#|)Jc)|Smp9&lL%PGI#L&N5YL6|E2P;2WW)CWIXC)SIe_v93?~#cU(kiD9M=h~!
z`j?EwXHZV!8vfym)80Ej9l7RP$Lr_)F`f9e-qP3^oH>p?KTyp3lGo5x=mpepmklEh
z+e8NfQgZBDdJWx(R_9=#xuw#Jxm-l$V@g`-On0P%rA7HMzQ)xaFFB^_E0m>01Z@~zG3qrY32+8NUT3au1mrLS6ZtWy76
zzvGZbJgc9Ra{MX1FV{FaXkX><(VRb+CPN7dlhdW-ZF_@ZGR!Y(1RP$fT>1c5r)(ur
z#^?g~j{cXo5JHrzu#RX4dOhxV{
zCc(6#wS&!C*P(#RUPwRBdI(0XV=>HUa1xTp2axq2`%;?ft@y{Sbl%Y-_!
z7UtPE1xgi}+rvg5N+s>g-Gm0nK{u|$37iyszcaEQ#$;ALh?w|VRM;>s&MGBbylEDw
z5G%!{K|iRKOPqNjz#=BJj>6mymyga`-zG^dit?8eC{e!8u+aK5FMtK$+K;P~Uh@t9
z)6MFqwQDeptSDRaU0ltUI|Rzu7PxbfLw_uH8CdX!nf>t_eDBdwa_}c#vM%7gLWhHE
zckYFT-&N@WI$vb7ZAPIhRwm!7Ojptcc?MDUH$QSg`u)!OavwQ+E9$iPhP&jq`4Z1>
z?xPN~es>(lH6wWsUE8wbL)N{ir#OzZs~hxsl~Mk2^o1!6~tMt
zBednp!6GWqoUFILavu#|xoVOnzd&7m&letxk0W&*J1kitl5k3!4Jc}(EVPUZkl~aF
znz#eSya?0Kj0i~K*Tkp8sf|I-L})Iw&Id(FF9tw|`_xaDN&W&oRyfG{E}$Zdlbg9|
zmCqWYKTzHK${Xc*L)zmA4w2PI(Q)iU&f7VebL|SxS%XJr1*eMGuVT*U
z*2M{|{s}&oF3owR>vSSh>IV!=NNdiKhdju<4Uo!o;(Y7m`Jbzo-cHQ;eB%7zZhWD8
znehVTVB1`3`%e+2lzjsx`4<3gfXWO1ZKzH05)OZ2%B@37oMKhw&u&DZHNjGaPrH&~WN3E_WJp|#e4o2{yp
zqW(Xr*kV-sgwH>CXCj_m`zZf!3bAfbnW#=}4TmxM-(S?W4%8}{iK@33Z?GY5Ie@Gt
zT14qXl7(ToP|)|6Su(F4x_#<4l%)DvK5p47FSIZ{!3;oHmU6v@V?_#}pCvD<4t>*!#LdP!^m;jhJGVXJXb8oC|fN~fW;JVrL59!d%!C;cz$ca%&=
zd!zaKjUoL(o?xGGB2-%-@V12x<;t*vG}`Gt?V-4QVXOBF-|gO4r*WSRzIm^BiPHSz
zszH7I>paRRMWN&8`T9+sIEzl|Zrq`ib-#;W@KV%IsX(ghh>mG#B<8XE$7)|DGGSOa
zPf+`;f=Fz6D=Gk3Dj5G+cK|4&bX^*={c@K4LZ%yBe3i4{BCiy;mrG6#?`z{m2DLas
z>tSoOeetpNpX^Mtn-aSfBI1bY$9uqjE?VJt2c%0#=a3SrWBm4c)E>cQH(7pk*UhfD
zcUc5v1K$Uh)(v3pz_^bH0h-5}59pRJ@|V6j>;V+Hq+)+o}EY99=rG)F}9kBrPkh+=;2&Na9SSu
z#grVh-y+MxI>6Vj)V0HE5RD)ix3;NE(EImo;fWURG7RI!2m77Pt5<2+oA0{H6-(iB
zQB6|RbC7$n9M#)#`Z8a@^0Dltj|Eng6Mj6*eVtt8mM_K3X{P*;v>B=3T656xkU*N`
z#LzoUB(V~IFg707HYc&gVR;YHanK{FsW&MhE3~cdu9)x1pMd=nsExcs>FfQx!~|}1*1|`cj=ybiCXOCF=QYod;@YhpX08DvIyiFr!?sEohxDQCrtUtTDYnI
zB9d|XAzBL&`{8N}kg-lu>h3_BzQz^V-Y&11kpO+Im>#XpJdJ{`zaYE5wx|3;X?mZU7u;WmE3KJgO$qc*L-FY5l{3`&HBlA*JLtN
zNy#Fo=Q5O}cIpNLZR8%=5%B0FI4t78HxDD<^h}dEg>T_a)Lp#EdM-UjSG;kJ~Q*}
zx7^{;B2MtHNGHD|q^r=e*sy5_uAygh2lK}d`x{)-J|`6+-XbZ*Yko6)>FFI(u6T_q
zPu>oQi^Mzmz+pbm3rZQ0ieFf6ft$SaBpH5R*uI*V_ply>FoFQ_%=-Fx2vj5f#;6f|
zho39}XszM@4?#5}o{RYol=NUri_#Y&pgBMBy{NUx01v6a>>W@&^qi(oIyCkR@?7bd
zPy(S+A+I`e?c*@KEUt;9G0Q}Wf1lj+kof)_&tT&G&VM6r1loJ%ySzw>9`Q8by-Njg
zwA)K^HpOj)2m{dBo&-p-WR_Q_nw5=P~d#g!7VsRq((cyrz_S|0v$bi(nFIKa3}4BnHowc3-n91)jlk@x9=
z=?MfroEc7pCPhbRId$yo+4p>{T4GL}-tr^9&67(~v4LB5ZJ%a_Fc$ZKGB}UdGSs<@
zN%R#?+m5H(Ob-BZZ+YZUTtY*-***|OLk?e6jqlZC
z-{fMCY4=su$&-N&rg(6BGphsSlmU;fn1#rjVpMbFRPj3?w8TN&4bA{HhQr*VxP8&hxJ<-tVTEGMt5
zVOGYfmf9VgtA5s&C^-^!+L^4dI^TgLz_7Ki!mwY7dFy_+XsHe9zR$M^(JM|E(&4m(
zCD$)YP)Ugwl}(sKOX&qN@BiB^8q}uL2K3l-45e@QT#*3bJ#8}@mzjXW-&|d>jOw;K
zk_$PWySXMHrs;0ft0}sS_fvHa98%&_ZKn*hbRYmvWPdTLW8f-@yEn*Y6*TZ%us`uZ
ze#mPpUA#u6_h0cW^SjlGL{Q9|FLOK=BD8K8YSaM@6?ZYV57#IxvXDI__RP
z5o;&i82~;Yp*0m~n6ZoUcg=?$@IKAW8Dqp?yjPmG(+-cS9av2z++@Vobr0{&U2?ea
z^O&ubSfigr6g}fT~{v?cJ}KtuN<4-a&ewAGjLd;8IRk2zo^?aVv)T
z!tmBO<#$W0zb15`RSyn~9RtBDRx>48!qG5oW|uA%EcEbHi|yAfm4o%qh#Bxhx0A15
zfv<*X#3wQR#7Xx*jqUusmEX|0vXH=oEpcF$XphU(
z3W80UjJ!?!`y*_Iqfj~!vSWzsD#4^CHsxYnh`l%&zqrKf$<$6ahSVB
zJis9+w~l*%A6Iy*mm$;A*uFqzwp5;o20rf*tY`Z==0efZ@&+BoF!%ec0=fd+TMEpo
zMBXG%SaF68e5JYQ{Z%LVoC-_ZT*u9z-vh233OAHg7Wc8>rIT5kmW6>ky>lnNE`JEU
zid+VBqTfjk;lM**x3g5{ZqYj4O`Ilr=sx$PjKGDIaeA8gLlyr|(1PeeQ_*dU%SG{l
z$y|ER1vnUqAyl=mg(&&l8E8c9KFeA#x!G^87#Gh<2#LEcE;fE@y6fb&dD{9Ax}?s}
zy23+vur0wJ=WpW`E*c-g<&&>9J0nxn&rrE*FeK`*9{#zYkHQntars%LEFGzdiPLaX#uGYWvCOw$=s$}>+uugJkMLaOWii0|n+D|^Z_-z@_%hN5qxO@=
z>mOuZI!6S&t!zc-nq0DIy=t%bLi9E4>GnjXu-ob%^-6+lTm38r5I=|
z12(Vst@6AYO0PwltRM!E-KgK>q7c$~^Mds0I7S$tDSj^wD@9hWyTbB|0@XL9eBK4{VV}wv3pBL@X0Sf%=NoL<#>y~OP{@CBrXq4llD)ln4+MIO_@F@&k(2x)3Q_lIGk^Akzm7EI
zf<00mKQzrF&d#u~WINZWq;^irt9re~%N?^#)tH>2;~uymvNIczE&KxgT5k@jSi0#n
z{M%XUyhnZBkO7s>sado#eZX^E3z%;>(H%RRUbW^i?LOnepu~{}_(WNDo
zF6mfu{XrQHai6O#IK!eoQk9r2c4WvSdwLprwh<63SkP2LgxfxY+HOS^osI+?9_I&@
zI3o_5&s$YZEjYJjZ|HH9lwX%`qs0(!MonaQi=mr!&|X!EV4*+HISLS`q%qD@86&dQ
z>7au7Cu^9)0UoVHL9CXZ}z+eR3vtiC|ZPGKj*j*{Ex$Aau~*9
zk_atL$Sbw8PkA|M9pgx+HaK(^SW!fOD7Xs6H3FOc@QUJY(xu?n|K{TUGI0z>wM1!G
zKQFyp)a9)-dN9`zDbwVD2A{h^dm-g!sw^{VBavC=yIXu!2vE8CX~8L%ET{ceoW$n~
zX=7Tt5jK0z%2t-L5l(}zMXk@2(T6u&m>9F-p<)_nl39?~7d{FJTA)k)B9mW3nkBQ*RhiG0UySG#WZ4M
zFHpNi_ORVx2qJ@Rp6t7$LPsXK|EFuh?fvM(D)wrCj~`jhXNH%Qe*$-nTW>aAp>=DM4`%O`{
z4BfG>IIOzg{F)L;$R4Ci2vt?mtlT)s;m#TQRjMZAPb
zO)8ZCL}VxfDK4Lfnwfsep@|g1U~p<4(TeH24-GRHi>)G}DyQgXC!w>Bx&lneJphnD
zaHa*4+Sr+iKW7!`EC9Ne#NDXG{7mDC?JqR5nF$hQU#j;*nT
zy(@PxI^CaHv@B0q+M-}udyHQIPPs)yy4|@Je$E_xBfgaoZh6CZbii%@I=z_7!beWV
zNpE{vS~Vn1SLN7Ag+S@JYVl;V(m?_PjfT|)Sw`Jn_4!m0!z}1@{hI0TlLcKRF--A~
zSmad-41We-Klh_MtZI%UStT&71|x7!n4}U_thy3a+v524yPgA)@bc=_?+O@$eX<+}
z)SnXcBo9x!{tAAc!U1!OJ&Y&nK7hcXBgsuY9^fg%inHuaO)Z%fe;x1GZ#ga0|IqoqAg=&ZO;&iz^TXRJU
z^G}K%R{Lnt*+*hjD0;;zle`))Vof&Ia6$I_11a6%3_QO<=#92FtNc6|{7xL%vLazM
zHfe1y`Yvhsg21HMjg_o!#NBI}Y6PWT#B=f)y4zPK=#C<3v036AqXk+(jJZ44&oE-L
z565WdMH6@I{56~QYziFfx6&G_oLEH1FzoDe$4{m*?ozn!5>e{<;B6K0!(rGOFG(}s
zZ9n1DpnOkLV$mustIz(3Y>&&STxmzo8#gaeu&fh%Sf_V6grfJn$XRkf4RL`w
zkM=bVyDVWB8ym09(^peJo<$KW9|y3VkHrJ&x$8*><-Vmy^qtpD9`blx4?^gq++}G7
zaBTU5$~ezv3$4?Mw5__ykru|Xi`*kT&;u@4G-fM~f_b!ijs$wnDSWeROP>JOYB|H?
z>`zSMS`Qs_kr3JM*%8uDzt2Vs61^>7{ei(TGW;u=^U|az9(_yQ5Oi)ycxrHsew|;k
z{f|_C{}0VfZ_w_xxnG6xD}VTLXrz9_n>+74mW&Xl9voum#$0YMG6w!?CZ|;8^0q>6
z)f)ahT|>N{(Yp{2`|;Dv0zKJnvvNgG-Z}WEG&;}V5c+An3|6AD7@;HCUn1=xcC#AI
z&7W-lr`c00Od^;k(^8tezeG|Xvli}
zTg)a2zH&72r}3+o=ciQdR|~n4VLAdfVN0uTK{74OJ`BknzZ(49b4SV>-+P1@wc9X@
znVU~5o}S_F;UP{Pd@b^u7f~Ku8PwtOfK31D*3waKibucLR0z-9;hG2iiSjWqoAc`g
ze89H=vKBUH=Eu=VGq)IwV84{ap-y3=IjBF^C0cPu%e+3)>V6n5gpr$6jCA!Uj{y3W
z3g(C4uRp2jk=W=0>IF%UjqCBmAF&bx>L{WtINiyQj}G4{xiIpeSRL=?W7)@_
zoP8m(XZQ8Knx$2vUBe?x!y&p9s6C-;07Z8f$T
z11;U~QRD2>!+E{rUW`gB7l-xXa!imNP*TkTe}i1!Uo*{^)<*wpk>YpG0vEt(w4dbg
zi>w8w5N)Q(ir#ztVKIM>g1mz)nlosy)~J4ZIBpQBjm!7Aioq_;>w&MBk*?~?u_%IP
zeWFMDZ_11`jz??E8EfVMWBKTjr~zFN++I=5jKvN5gSR24V?snJeHka+3r@#mvi2uL
zMbLS6L}IfRhPrrvLUftrE(1d|b52&6fpXQ&ro?VhWu9(P)|@J57CUV{82OdBms!A2
zz-BQ{^SrBzF25hoh#pN%lC8~LBBY*4KbGX@3#DnFI=X0#pgnXRTkL*4GSz4dJPq0*
zhF!49C<=-B@iK>fqr4Lz%(_rSFEu27=-_v>G0`FNZ%9o%<;0R4Cx%b5xhZ-RH`=lkhhjuNUvp<(4t;n>ez4cX3o2xX
zO_9j^wi0{J-*Y|;-;~KQ`Za!37E|!snBpYvo=p}4s;iwfT;Fn^cl)j@e-__HxDpcn
zzbda+yy+Ro{NRomtNS#K*nmn@fgNju=g=>gjX~fod`FdV^mQ7bzzSI5IxIFm$vpqD
zB*)m*pMtC#@?|qXNAfMr&fBVj>iZ!%_$uPX1X##2i{=yZP
zwd}L-=lPnNrrJ)35Y&9M^(Xll286vUA2yJ>CuQUbkj;5&iu{DocU9@>Z#O6?NZ)
zWWacdi#(-ug>@*(6?j$&kqtDc^+uz@4sq*%a^@PQk
zkGOHT3r-FOvx?O363&>2^Rt6k
zsC{`bNlK)!Puy8s&g`Bgrivo{B$ah75)3e3&Xc@X+`cw=@h8OvBkfh^ayapA^P}^B
zvBC#^w@jzUDqUNBmJl}rA-3DSG$JveIdoeyA8~B0o(edka%%C@0;0TawPiVXjwd03
z`0J*$H6Lg&7B=N4F?BDjRBGFp#w_Cxq>rR|pFg-mRp>aI&(m(nqh3!tYQeTNk5tGN
z4n5Z-v)>UnDKt{5y2-t68RJBkVnuk&rc|p`?hXzRDUijyzI%6@x`uJ{TFZT9#U{xR
zY3=*BSRht^uKKp_q+>vtACw2BlZZ7E3Kg5sE|a%&nM3+%L_;=j>x-nK0`L>QgaHXi
zrGNh^WU8uQ@Z%AR$!qO%9}HX-_k|>V8>%UW1By{ZufP)O_46b!l!Nj
z6kRIz_1`0YknLSKhiykjgQ!VdwnSLP%;K!)+3Wh@@P&IknV^Xsz1EX7lA^d}NDH@q
zg+r2mPO`Ievlq^NLWgFFt48Qhby^8l-1oDM3O!(de!s~?*9MBlyg;Ku{KcFsGa?%5
z6!R?IU&KNuDVYZK1YX||xNq(egJ53Ld`xkydLwH;;UnIVa~MFHW$8?
z7hF77%3>3JB5(3=pOKlHjTg080Y08**N+jZvku$&yAgoZ1a8P2QI-q}vz4JNnf;v7rmrHkQ;l(&sNY(CFG4}qmKVinV$*YPhUdiOkIJ~9hkaY~0s7EV
zD$BpY8+Dd*tPWlF4K`}nYt|Ydm%dX|E