From aa50195e756ddea8b54c6b0c98d25c4cafc52375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Mich=C3=A1lek?= Date: Mon, 8 Sep 2025 16:19:07 +0200 Subject: [PATCH] tab5: add support --- CMakeLists.txt | 6 + README.md | 39 +- boards/m5stack_tab5.cfg | 1 + boards/m5stack_tab5/diagram.json | 32 + boards/m5stack_tab5/wokwi.toml | 15 + components/m5stack_tab5/CMakeLists.txt | 13 + components/m5stack_tab5/Kconfig | 126 ++ components/m5stack_tab5/LICENSE | 202 +++ components/m5stack_tab5/README.md | 1 + components/m5stack_tab5/idf_component.yml | 7 + components/m5stack_tab5/include/bsp/config.h | 16 + components/m5stack_tab5/include/bsp/display.h | 181 ++ components/m5stack_tab5/include/bsp/esp-bsp.h | 8 + .../include/bsp/ili9881_init_data.c | 216 +++ .../m5stack_tab5/include/bsp/m5stack_tab5.h | 436 +++++ components/m5stack_tab5/include/bsp/touch.h | 51 + components/m5stack_tab5/m5stack_tab5.c | 1454 +++++++++++++++++ .../m5stack_tab5/priv_include/bsp_err_check.h | 63 + docs/img/m5stack-tab5.webp | Bin 0 -> 173790 bytes main/BridgingHeader.h | 2 +- main/Main.swift | 6 +- main/idf_component.yml | 6 + sdkconfig.defaults.m5stack_tab5 | 32 + 23 files changed, 2907 insertions(+), 6 deletions(-) create mode 100644 boards/m5stack_tab5.cfg create mode 100644 boards/m5stack_tab5/diagram.json create mode 100644 boards/m5stack_tab5/wokwi.toml create mode 100644 components/m5stack_tab5/CMakeLists.txt create mode 100644 components/m5stack_tab5/Kconfig create mode 100644 components/m5stack_tab5/LICENSE create mode 100644 components/m5stack_tab5/README.md create mode 100644 components/m5stack_tab5/idf_component.yml create mode 100644 components/m5stack_tab5/include/bsp/config.h create mode 100644 components/m5stack_tab5/include/bsp/display.h create mode 100644 components/m5stack_tab5/include/bsp/esp-bsp.h create mode 100644 components/m5stack_tab5/include/bsp/ili9881_init_data.c create mode 100644 components/m5stack_tab5/include/bsp/m5stack_tab5.h create mode 100644 components/m5stack_tab5/include/bsp/touch.h create mode 100644 components/m5stack_tab5/m5stack_tab5.c create mode 100644 components/m5stack_tab5/priv_include/bsp_err_check.h create mode 100644 docs/img/m5stack-tab5.webp create mode 100644 sdkconfig.defaults.m5stack_tab5 diff --git a/CMakeLists.txt b/CMakeLists.txt index 0396cf7..ea37741 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,9 +8,15 @@ else() set(ENV{BUILD_BOARD} ${BUILD_BOARD}) endif() +# Add BSP-specific configurations +if(BUILD_BOARD STREQUAL "m5stack_tab5") + add_compile_definitions(BSP_CONFIG_NO_GRAPHIC_LIB=1) +endif() + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(esp32-sdl3-swift-example) get_filename_component(configName "${CMAKE_BINARY_DIR}" NAME) list(APPEND EXTRA_COMPONENT_DIRS "${CMAKE_SOURCE_DIR}/components/esp_littlefs") +list(APPEND EXTRA_COMPONENT_DIRS "${CMAKE_SOURCE_DIR}/components") littlefs_create_partition_image(assets assets FLASH_IN_PROJECT) diff --git a/README.md b/README.md index 205819b..bd057a3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Test Status](https://github.com/georgik/esp32-sdl3-swift-example/actions/workflows/test.yml/badge.svg) -Example of graphical application for ESP32-C3, ESP32-P4. +Example of graphical application for ESP32-C3, ESP32-C6, ESP32-P4 using Swift programming language with SDL3 graphics library. Read more about Swift for ESP32 at [Espressif Developer Portal](https://developer.espressif.com/tags/swift/). @@ -23,15 +23,50 @@ Read more about Swift for ESP32 at [Espressif Developer Portal](https://develope ```shell source esp-idf/export.sh +``` + +If you want to use specific Swift toolchain, you can set the environment variable `TOOLCHAINS`. +The step is not required for Swift 6.1 and newer. +```shell export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2024-10-30-a.xctoolchain/Info.plist) ``` -### Build for ESP32-P4-Function-Ev-Board +## Supported Boards + +This project supports multiple ESP32 development boards with different display configurations: + +| Board | MCU | Display | Resolution | Interface | Status | +|-------|-----|---------|------------|-----------|--------| +| ESP32-P4 Function Evaluation Board | ESP32-P4 | RGB LCD | 480x480 | RGB | ✅ Working | +| M5Stack Tab5 | ESP32-P4 | MIPI-DSI LCD | 720x1280 | MIPI-DSI | ✅ Working | +| ESP32-C3 LCD Kit | ESP32-C3 | SPI LCD | 240x240 | SPI | ✅ Working | +| ESP32-C6 DevKit | ESP32-C6 | SPI LCD | 320x240 | SPI | ✅ Working | +| Waveshare ESP32-C6-LCD-1.47 | ESP32-C6 | SPI LCD | 172x320 | SPI | ✅ Working | + +## Build Instructions + +### Build for ESP32-P4 Function Evaluation Board ```shell idf.py @boards/esp32_p4_function_ev_board.cfg flash monitor ``` +### Build for M5Stack Tab5 + +![M5Stack Tab5](docs/img/m5stack-tab5.webp) + +The M5Stack Tab5 is a premium ESP32-P4 tablet with a high-resolution 5-inch MIPI-DSI display (720x1280) and GT911 capacitive touch controller. + +- **Board**: [M5Stack Tab5](https://shop.m5stack.com/products/m5stack-tab5-esp32-p4-tablet) +- **MCU**: ESP32-P4 RISC-V dual-core +- **Display**: 5-inch IPS LCD, 720x1280 resolution +- **Touch**: GT911 capacitive touch controller +- **Interface**: MIPI-DSI for display + +```shell +idf.py @boards/m5stack_tab5.cfg flash monitor +``` + ### Build for ESP32-C3-LcdKit ![ESP32-C3-LcdKit](docs/img/esp32-c3-lcdkit.webp) diff --git a/boards/m5stack_tab5.cfg b/boards/m5stack_tab5.cfg new file mode 100644 index 0000000..357c4a7 --- /dev/null +++ b/boards/m5stack_tab5.cfg @@ -0,0 +1 @@ +-DSDKCONFIG_DEFAULTS="sdkconfig.defaults.m5stack_tab5;sdkconfig.defaults" -DBUILD_BOARD="m5stack_tab5" -DIDF_TARGET=esp32p4 -B build.m5stack_tab5 diff --git a/boards/m5stack_tab5/diagram.json b/boards/m5stack_tab5/diagram.json new file mode 100644 index 0000000..44b8319 --- /dev/null +++ b/boards/m5stack_tab5/diagram.json @@ -0,0 +1,32 @@ +{ + "version": 1, + "author": "ESP32-SDL3-Swift Example", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-p4", + "id": "esp32p4", + "top": 0, + "left": 0, + "attrs": { + "psram": "16", + "flash": "16" + } + }, + { + "type": "wokwi-ili9341", + "id": "lcd", + "top": 0, + "left": 300, + "attrs": { + "width": "720", + "height": "1280" + } + } + ], + "connections": [ + ["esp32p4:GND", "lcd:GND", "black", []], + ["esp32p4:3V3", "lcd:VCC", "red", []] + ], + "dependencies": {} +} diff --git a/boards/m5stack_tab5/wokwi.toml b/boards/m5stack_tab5/wokwi.toml new file mode 100644 index 0000000..44797bd --- /dev/null +++ b/boards/m5stack_tab5/wokwi.toml @@ -0,0 +1,15 @@ +[wokwi] +version = 1 +elf = "../../build.m5stack_tab5/esp32-sdl3-swift-example.elf" +firmware = "../../build.m5stack_tab5/esp32-sdl3-swift-example.bin" + +[esp32] +# M5Stack Tab5 ESP32-P4 configuration +# - Dual-core RISC-V +# - 16MB Flash, 32MB PSRAM +# - 1280x720 MIPI-DSI display +# - GT911 touch controller + +[[esp32.chip]] +model = "esp32p4" +flash_size = "16MB" diff --git a/components/m5stack_tab5/CMakeLists.txt b/components/m5stack_tab5/CMakeLists.txt new file mode 100644 index 0000000..aa466f0 --- /dev/null +++ b/components/m5stack_tab5/CMakeLists.txt @@ -0,0 +1,13 @@ + +idf_component_register( + SRCS "m5stack_tab5.c" + INCLUDE_DIRS "include" + INCLUDE_DIRS "include/bsp" + PRIV_INCLUDE_DIRS "priv_include" + REQUIRES + driver + esp_lcd + esp_codec_dev + esp_lcd_ili9881c + PRIV_REQUIRES usb spiffs fatfs +) diff --git a/components/m5stack_tab5/Kconfig b/components/m5stack_tab5/Kconfig new file mode 100644 index 0000000..b3fe8ae --- /dev/null +++ b/components/m5stack_tab5/Kconfig @@ -0,0 +1,126 @@ +menu "Board Support Package (ESP32-P4)" + + config BSP_ERROR_CHECK + bool "Enable error check in BSP" + default y + help + Error check assert the application before returning the error code. + + menu "I2C" + config BSP_I2C_NUM + int "I2C peripheral index" + default 1 + range 0 1 + help + ESP32P4 has two I2C peripherals, pick the one you want to use. + + config BSP_I2C_FAST_MODE + bool "Enable I2C fast mode" + default y + help + I2C has two speed modes: normal (100kHz) and fast (400kHz). + + config BSP_I2C_CLK_SPEED_HZ + int + default 400000 if BSP_I2C_FAST_MODE + default 100000 + endmenu + + menu "I2S" + config BSP_I2S_NUM + int "I2S peripheral index" + default 1 + range 0 2 + help + ESP32P4 has three I2S peripherals, pick the one you want to use. + endmenu + + menu "uSD card - Virtual File System" + config BSP_SD_FORMAT_ON_MOUNT_FAIL + bool "Format uSD card if mounting fails" + default n + help + The SDMMC host will format (FAT) the uSD card if it fails to mount the filesystem. + + config BSP_SD_MOUNT_POINT + string "uSD card mount point" + default "/sdcard" + help + Mount point of the uSD card in the Virtual File System + + endmenu + + menu "SPIFFS - Virtual File System" + config BSP_SPIFFS_FORMAT_ON_MOUNT_FAIL + bool "Format SPIFFS if mounting fails" + default n + help + Format SPIFFS if it fails to mount the filesystem. + + config BSP_SPIFFS_MOUNT_POINT + string "SPIFFS mount point" + default "/spiffs" + help + Mount point of SPIFFS in the Virtual File System. + + config BSP_SPIFFS_PARTITION_LABEL + string "Partition label of SPIFFS" + default "storage" + help + Partition label which stores SPIFFS. + + config BSP_SPIFFS_MAX_FILES + int "Max files supported for SPIFFS VFS" + default 5 + help + Supported max files for SPIFFS in the Virtual File System. + endmenu + + menu "Display" + config BSP_LCD_DPI_BUFFER_NUMS + int "Set number of frame buffers" + default 1 + range 1 3 + help + Let DPI LCD driver create a specified number of frame-size buffers. Only when it is set to multiple can the avoiding tearing be turned on. + + config BSP_DISPLAY_LVGL_AVOID_TEAR + bool "Avoid tearing effect" + depends on BSP_LCD_DPI_BUFFER_NUMS > 1 + default "n" + help + Avoid tearing effect through LVGL buffer mode and double frame buffers of RGB LCD. This feature is only available for RGB LCD. + + choice BSP_DISPLAY_LVGL_MODE + depends on BSP_DISPLAY_LVGL_AVOID_TEAR + prompt "Select LVGL buffer mode" + default BSP_DISPLAY_LVGL_FULL_REFRESH + config BSP_DISPLAY_LVGL_FULL_REFRESH + bool "Full refresh" + config BSP_DISPLAY_LVGL_DIRECT_MODE + bool "Direct mode" + endchoice + + config BSP_DISPLAY_BRIGHTNESS_LEDC_CH + int "LEDC channel index" + default 1 + range 0 7 + help + LEDC channel is used to generate PWM signal that controls display brightness. + Set LEDC index that should be used. + + choice BSP_LCD_COLOR_FORMAT + prompt "Select LCD color format" + default BSP_LCD_COLOR_FORMAT_RGB565 + help + Select the LCD color format RGB565/RGB888. + + config BSP_LCD_COLOR_FORMAT_RGB565 + bool "RGB565" + config BSP_LCD_COLOR_FORMAT_RGB888 + bool "RGB888" + endchoice + + endmenu + +endmenu diff --git a/components/m5stack_tab5/LICENSE b/components/m5stack_tab5/LICENSE new file mode 100644 index 0000000..75b5248 --- /dev/null +++ b/components/m5stack_tab5/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/components/m5stack_tab5/README.md b/components/m5stack_tab5/README.md new file mode 100644 index 0000000..ba450b7 --- /dev/null +++ b/components/m5stack_tab5/README.md @@ -0,0 +1 @@ +# BSP: M5STACK_TAB5 diff --git a/components/m5stack_tab5/idf_component.yml b/components/m5stack_tab5/idf_component.yml new file mode 100644 index 0000000..5be6927 --- /dev/null +++ b/components/m5stack_tab5/idf_component.yml @@ -0,0 +1,7 @@ +dependencies: + espressif/esp_lcd_st7703: ^1.0.1 + espressif/esp_codec_dev: ^1.3.0 + # lvgl/lvgl: ^8.4 + # espressif/esp_lvgl_port: ^2.5.0 + espressif/esp_lcd_touch_gt911: ^1.1.1~2 + espressif/usb_host_hid: ^1.0.3 diff --git a/components/m5stack_tab5/include/bsp/config.h b/components/m5stack_tab5/include/bsp/config.h new file mode 100644 index 0000000..37dde18 --- /dev/null +++ b/components/m5stack_tab5/include/bsp/config.h @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +/************************************************************************************************** + * BSP configuration + **************************************************************************************************/ +// By default, this BSP is shipped with LVGL graphical library. Enabling this option will exclude it. +// If you want to use BSP without LVGL, select BSP version with 'noglib' suffix. +#if !defined(BSP_CONFIG_NO_GRAPHIC_LIB) // Check if the symbol is not coming from compiler definitions (-D...) +#define BSP_CONFIG_NO_GRAPHIC_LIB (0) +#endif diff --git a/components/m5stack_tab5/include/bsp/display.h b/components/m5stack_tab5/include/bsp/display.h new file mode 100644 index 0000000..fec1b82 --- /dev/null +++ b/components/m5stack_tab5/include/bsp/display.h @@ -0,0 +1,181 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief BSP LCD + * + * This file offers API for basic LCD control. + * It is useful for users who want to use the LCD without the default Graphical Library LVGL. + * + * For standard LCD initialization with LVGL graphical library, you can call all-in-one function bsp_display_start(). + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp_lcd_types.h" +#include "esp_lcd_mipi_dsi.h" +#include "sdkconfig.h" + +/* LCD color formats */ +#define ESP_LCD_COLOR_FORMAT_RGB565 (1) +#define ESP_LCD_COLOR_FORMAT_RGB888 (2) + +/* LCD display color format */ +// #if CONFIG_BSP_LCD_COLOR_FORMAT_RGB888 +// #define BSP_LCD_COLOR_FORMAT (ESP_LCD_COLOR_FORMAT_RGB888) +// #else +#define BSP_LCD_COLOR_FORMAT (ESP_LCD_COLOR_FORMAT_RGB565) +//#endif +/* LCD display color bytes endianess */ +#define BSP_LCD_BIGENDIAN (0) +/* LCD display color bits */ +#define BSP_LCD_BITS_PER_PIXEL (16) +/* LCD display color space */ +#define BSP_LCD_COLOR_SPACE (ESP_LCD_COLOR_SPACE_RGB) + +/* LCD display definition 720x1280 */ +#define BSP_LCD_H_RES (720) +#define BSP_LCD_V_RES (1280) + +#define BSP_LCD_MIPI_DSI_LCD_HSYNC (10) +#define BSP_LCD_MIPI_DSI_LCD_HBP (40) +#define BSP_LCD_MIPI_DSI_LCD_HFP (40) +#define BSP_LCD_MIPI_DSI_LCD_VSYNC (4) +#define BSP_LCD_MIPI_DSI_LCD_VBP (16) +#define BSP_LCD_MIPI_DSI_LCD_VFP (16) + +#define BSP_LCD_MIPI_DSI_LANE_NUM (2) // 2 data lanes +#define BSP_LCD_MIPI_DSI_LANE_BITRATE_MBPS (730) // 720*1280 RGB24 60Hz //(900) // 900Mbps + +#define BSP_MIPI_DSI_PHY_PWR_LDO_CHAN (3) // LDO_VO3 is connected to VDD_MIPI_DPHY +#define BSP_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV (2500) + +/** + * @brief BSP display configuration structure + * + */ +typedef struct { + int dummy; +} bsp_display_config_t; + +/** + * @brief BSP display return handles + * + */ +typedef struct { + esp_lcd_dsi_bus_handle_t mipi_dsi_bus; /*!< MIPI DSI bus handle */ + esp_lcd_panel_io_handle_t io; /*!< ESP LCD IO handle */ + esp_lcd_panel_handle_t panel; /*!< ESP LCD panel (color) handle */ + esp_lcd_panel_handle_t control; /*!< ESP LCD panel (control) handle */ +} bsp_lcd_handles_t; + +/** + * @brief Create new display panel + * + * For maximum flexibility, this function performs only reset and initialization of the display. + * You must turn on the display explicitly by calling esp_lcd_panel_disp_on_off(). + * The display's backlight is not turned on either. You can use bsp_display_backlight_on/off(), + * bsp_display_brightness_set() (on supported boards) or implement your own backlight control. + * + * If you want to free resources allocated by this function, you can use esp_lcd API, ie.: + * + * \code{.c} + * esp_lcd_panel_del(panel); + * esp_lcd_panel_io_del(io); + * esp_lcd_del_dsi_bus(mipi_dsi_bus); + * \endcode + * + * @param[in] config display configuration + * @param[out] ret_panel esp_lcd panel handle + * @param[out] ret_io esp_lcd IO handle + * @return + * - ESP_OK On success + * - Else esp_lcd failure + */ +esp_err_t bsp_display_new(const bsp_display_config_t *config, esp_lcd_panel_handle_t *ret_panel, + esp_lcd_panel_io_handle_t *ret_io); + +/** + * @brief Create new display panel + * + * For maximum flexibility, this function performs only reset and initialization of the display. + * You must turn on the display explicitly by calling esp_lcd_panel_disp_on_off(). + * The display's backlight is not turned on either. You can use bsp_display_backlight_on/off(), + * bsp_display_brightness_set() (on supported boards) or implement your own backlight control. + * + * If you want to free resources allocated by this function, you can use esp_lcd API, ie.: + * + * \code{.c} + * esp_lcd_panel_del(panel); + * esp_lcd_panel_del(control); + * esp_lcd_panel_io_del(io); + * esp_lcd_del_dsi_bus(mipi_dsi_bus); + * \endcode + * + * @param[in] config display configuration + * @param[out] ret_handles all esp_lcd handles in one structure + * @return + * - ESP_OK On success + * - Else esp_lcd failure + */ +esp_err_t bsp_display_new_with_handles(const bsp_display_config_t *config, bsp_lcd_handles_t *ret_handles); + +/** + * @brief Initialize display's brightness + * + * Brightness is controlled with PWM signal to a pin controlling backlight. + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_display_brightness_init(void); + +/** + * @brief Set display's brightness + * + * Brightness is controlled with PWM signal to a pin controlling backlight. + * Brightness must be already initialized by calling bsp_display_brightness_init() or bsp_display_new() + * + * @param[in] brightness_percent Brightness in [%] + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_display_brightness_set(int brightness_percent); + +/** + * @brief Turn on display backlight + * + * Brightness is controlled with PWM signal to a pin controlling backlight. + * Brightness must be already initialized by calling bsp_display_brightness_init() or bsp_display_new() + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_display_backlight_on(void); + +/** + * @brief Turn off display backlight + * + * Brightness is controlled with PWM signal to a pin controlling backlight. + * Brightness must be already initialized by calling bsp_display_brightness_init() or bsp_display_new() + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_display_backlight_off(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/m5stack_tab5/include/bsp/esp-bsp.h b/components/m5stack_tab5/include/bsp/esp-bsp.h new file mode 100644 index 0000000..c7abbc3 --- /dev/null +++ b/components/m5stack_tab5/include/bsp/esp-bsp.h @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "bsp/m5stack_tab5.h" diff --git a/components/m5stack_tab5/include/bsp/ili9881_init_data.c b/components/m5stack_tab5/include/bsp/ili9881_init_data.c new file mode 100644 index 0000000..0def92f --- /dev/null +++ b/components/m5stack_tab5/include/bsp/ili9881_init_data.c @@ -0,0 +1,216 @@ + + +static const ili9881c_lcd_init_cmd_t tab5_lcd_ili9881c_specific_init_code_default[] = { + // {cmd, { data }, data_size, delay} + /**** CMD_Page 1 ****/ + {0xFF, (uint8_t[]){0x98, 0x81, 0x01}, 3, 0}, + {0xB7, (uint8_t[]){0x03}, 1, 0}, // set 2 lane + /**** CMD_Page 3 ****/ + {0xFF, (uint8_t[]){0x98, 0x81, 0x03}, 3, 0}, + {0x01, (uint8_t[]){0x00}, 1, 0}, + {0x02, (uint8_t[]){0x00}, 1, 0}, + {0x03, (uint8_t[]){0x73}, 1, 0}, + {0x04, (uint8_t[]){0x00}, 1, 0}, + {0x05, (uint8_t[]){0x00}, 1, 0}, + {0x06, (uint8_t[]){0x08}, 1, 0}, + {0x07, (uint8_t[]){0x00}, 1, 0}, + {0x08, (uint8_t[]){0x00}, 1, 0}, + {0x09, (uint8_t[]){0x1B}, 1, 0}, + {0x0a, (uint8_t[]){0x01}, 1, 0}, + {0x0b, (uint8_t[]){0x01}, 1, 0}, + {0x0c, (uint8_t[]){0x0D}, 1, 0}, + {0x0d, (uint8_t[]){0x01}, 1, 0}, + {0x0e, (uint8_t[]){0x01}, 1, 0}, + {0x0f, (uint8_t[]){0x26}, 1, 0}, + {0x10, (uint8_t[]){0x26}, 1, 0}, + {0x11, (uint8_t[]){0x00}, 1, 0}, + {0x12, (uint8_t[]){0x00}, 1, 0}, + {0x13, (uint8_t[]){0x02}, 1, 0}, + {0x14, (uint8_t[]){0x00}, 1, 0}, + {0x15, (uint8_t[]){0x00}, 1, 0}, + {0x16, (uint8_t[]){0x00}, 1, 0}, + {0x17, (uint8_t[]){0x00}, 1, 0}, + {0x18, (uint8_t[]){0x00}, 1, 0}, + {0x19, (uint8_t[]){0x00}, 1, 0}, + {0x1a, (uint8_t[]){0x00}, 1, 0}, + {0x1b, (uint8_t[]){0x00}, 1, 0}, + {0x1c, (uint8_t[]){0x00}, 1, 0}, + {0x1d, (uint8_t[]){0x00}, 1, 0}, + {0x1e, (uint8_t[]){0x40}, 1, 0}, + {0x1f, (uint8_t[]){0x00}, 1, 0}, + {0x20, (uint8_t[]){0x06}, 1, 0}, + {0x21, (uint8_t[]){0x01}, 1, 0}, + {0x22, (uint8_t[]){0x00}, 1, 0}, + {0x23, (uint8_t[]){0x00}, 1, 0}, + {0x24, (uint8_t[]){0x00}, 1, 0}, + {0x25, (uint8_t[]){0x00}, 1, 0}, + {0x26, (uint8_t[]){0x00}, 1, 0}, + {0x27, (uint8_t[]){0x00}, 1, 0}, + {0x28, (uint8_t[]){0x33}, 1, 0}, + {0x29, (uint8_t[]){0x03}, 1, 0}, + {0x2a, (uint8_t[]){0x00}, 1, 0}, + {0x2b, (uint8_t[]){0x00}, 1, 0}, + {0x2c, (uint8_t[]){0x00}, 1, 0}, + {0x2d, (uint8_t[]){0x00}, 1, 0}, + {0x2e, (uint8_t[]){0x00}, 1, 0}, + {0x2f, (uint8_t[]){0x00}, 1, 0}, + {0x30, (uint8_t[]){0x00}, 1, 0}, + {0x31, (uint8_t[]){0x00}, 1, 0}, + {0x32, (uint8_t[]){0x00}, 1, 0}, + {0x33, (uint8_t[]){0x00}, 1, 0}, + {0x34, (uint8_t[]){0x00}, 1, 0}, + {0x35, (uint8_t[]){0x00}, 1, 0}, + {0x36, (uint8_t[]){0x00}, 1, 0}, + {0x37, (uint8_t[]){0x00}, 1, 0}, + {0x38, (uint8_t[]){0x00}, 1, 0}, + {0x39, (uint8_t[]){0x00}, 1, 0}, + {0x3a, (uint8_t[]){0x00}, 1, 0}, + {0x3b, (uint8_t[]){0x00}, 1, 0}, + {0x3c, (uint8_t[]){0x00}, 1, 0}, + {0x3d, (uint8_t[]){0x00}, 1, 0}, + {0x3e, (uint8_t[]){0x00}, 1, 0}, + {0x3f, (uint8_t[]){0x00}, 1, 0}, + {0x40, (uint8_t[]){0x00}, 1, 0}, + {0x41, (uint8_t[]){0x00}, 1, 0}, + {0x42, (uint8_t[]){0x00}, 1, 0}, + {0x43, (uint8_t[]){0x00}, 1, 0}, + {0x44, (uint8_t[]){0x00}, 1, 0}, + + {0x50, (uint8_t[]){0x01}, 1, 0}, + {0x51, (uint8_t[]){0x23}, 1, 0}, + {0x52, (uint8_t[]){0x45}, 1, 0}, + {0x53, (uint8_t[]){0x67}, 1, 0}, + {0x54, (uint8_t[]){0x89}, 1, 0}, + {0x55, (uint8_t[]){0xab}, 1, 0}, + {0x56, (uint8_t[]){0x01}, 1, 0}, + {0x57, (uint8_t[]){0x23}, 1, 0}, + {0x58, (uint8_t[]){0x45}, 1, 0}, + {0x59, (uint8_t[]){0x67}, 1, 0}, + {0x5a, (uint8_t[]){0x89}, 1, 0}, + {0x5b, (uint8_t[]){0xab}, 1, 0}, + {0x5c, (uint8_t[]){0xcd}, 1, 0}, + {0x5d, (uint8_t[]){0xef}, 1, 0}, + + {0x5e, (uint8_t[]){0x11}, 1, 0}, + {0x5f, (uint8_t[]){0x02}, 1, 0}, + {0x60, (uint8_t[]){0x00}, 1, 0}, + {0x61, (uint8_t[]){0x07}, 1, 0}, + {0x62, (uint8_t[]){0x06}, 1, 0}, + {0x63, (uint8_t[]){0x0E}, 1, 0}, + {0x64, (uint8_t[]){0x0F}, 1, 0}, + {0x65, (uint8_t[]){0x0C}, 1, 0}, + {0x66, (uint8_t[]){0x0D}, 1, 0}, + {0x67, (uint8_t[]){0x02}, 1, 0}, + {0x68, (uint8_t[]){0x02}, 1, 0}, + {0x69, (uint8_t[]){0x02}, 1, 0}, + {0x6a, (uint8_t[]){0x02}, 1, 0}, + {0x6b, (uint8_t[]){0x02}, 1, 0}, + {0x6c, (uint8_t[]){0x02}, 1, 0}, + {0x6d, (uint8_t[]){0x02}, 1, 0}, + {0x6e, (uint8_t[]){0x02}, 1, 0}, + {0x6f, (uint8_t[]){0x02}, 1, 0}, + {0x70, (uint8_t[]){0x02}, 1, 0}, + {0x71, (uint8_t[]){0x02}, 1, 0}, + {0x72, (uint8_t[]){0x02}, 1, 0}, + {0x73, (uint8_t[]){0x05}, 1, 0}, + {0x74, (uint8_t[]){0x01}, 1, 0}, + {0x75, (uint8_t[]){0x02}, 1, 0}, + {0x76, (uint8_t[]){0x00}, 1, 0}, + {0x77, (uint8_t[]){0x07}, 1, 0}, + {0x78, (uint8_t[]){0x06}, 1, 0}, + {0x79, (uint8_t[]){0x0E}, 1, 0}, + {0x7a, (uint8_t[]){0x0F}, 1, 0}, + {0x7b, (uint8_t[]){0x0C}, 1, 0}, + {0x7c, (uint8_t[]){0x0D}, 1, 0}, + {0x7d, (uint8_t[]){0x02}, 1, 0}, + {0x7e, (uint8_t[]){0x02}, 1, 0}, + {0x7f, (uint8_t[]){0x02}, 1, 0}, + {0x80, (uint8_t[]){0x02}, 1, 0}, + {0x81, (uint8_t[]){0x02}, 1, 0}, + {0x82, (uint8_t[]){0x02}, 1, 0}, + {0x83, (uint8_t[]){0x02}, 1, 0}, + {0x84, (uint8_t[]){0x02}, 1, 0}, + {0x85, (uint8_t[]){0x02}, 1, 0}, + {0x86, (uint8_t[]){0x02}, 1, 0}, + {0x87, (uint8_t[]){0x02}, 1, 0}, + {0x88, (uint8_t[]){0x02}, 1, 0}, + {0x89, (uint8_t[]){0x05}, 1, 0}, + {0x8A, (uint8_t[]){0x01}, 1, 0}, + + /**** CMD_Page 4 ****/ + {0xFF, (uint8_t[]){0x98, 0x81, 0x04}, 3, 0}, + {0x38, (uint8_t[]){0x01}, 1, 0}, + {0x39, (uint8_t[]){0x00}, 1, 0}, + {0x6C, (uint8_t[]){0x15}, 1, 0}, + {0x6E, (uint8_t[]){0x1A}, 1, 0}, + {0x6F, (uint8_t[]){0x25}, 1, 0}, + {0x3A, (uint8_t[]){0xA4}, 1, 0}, + {0x8D, (uint8_t[]){0x20}, 1, 0}, + {0x87, (uint8_t[]){0xBA}, 1, 0}, + {0x3B, (uint8_t[]){0x98}, 1, 0}, + + /**** CMD_Page 1 ****/ + {0xFF, (uint8_t[]){0x98, 0x81, 0x01}, 3, 0}, + {0x22, (uint8_t[]){0x0A}, 1, 0}, + {0x31, (uint8_t[]){0x00}, 1, 0}, + {0x50, (uint8_t[]){0x6B}, 1, 0}, + {0x51, (uint8_t[]){0x66}, 1, 0}, + {0x53, (uint8_t[]){0x73}, 1, 0}, + {0x55, (uint8_t[]){0x8B}, 1, 0}, + {0x60, (uint8_t[]){0x1B}, 1, 0}, + {0x61, (uint8_t[]){0x01}, 1, 0}, + {0x62, (uint8_t[]){0x0C}, 1, 0}, + {0x63, (uint8_t[]){0x00}, 1, 0}, + + // Gamma P + {0xA0, (uint8_t[]){0x00}, 1, 0}, + {0xA1, (uint8_t[]){0x15}, 1, 0}, + {0xA2, (uint8_t[]){0x1F}, 1, 0}, + {0xA3, (uint8_t[]){0x13}, 1, 0}, + {0xA4, (uint8_t[]){0x11}, 1, 0}, + {0xA5, (uint8_t[]){0x21}, 1, 0}, + {0xA6, (uint8_t[]){0x17}, 1, 0}, + {0xA7, (uint8_t[]){0x1B}, 1, 0}, + {0xA8, (uint8_t[]){0x6B}, 1, 0}, + {0xA9, (uint8_t[]){0x1E}, 1, 0}, + {0xAA, (uint8_t[]){0x2B}, 1, 0}, + {0xAB, (uint8_t[]){0x5D}, 1, 0}, + {0xAC, (uint8_t[]){0x19}, 1, 0}, + {0xAD, (uint8_t[]){0x14}, 1, 0}, + {0xAE, (uint8_t[]){0x4B}, 1, 0}, + {0xAF, (uint8_t[]){0x1D}, 1, 0}, + {0xB0, (uint8_t[]){0x27}, 1, 0}, + {0xB1, (uint8_t[]){0x49}, 1, 0}, + {0xB2, (uint8_t[]){0x5D}, 1, 0}, + {0xB3, (uint8_t[]){0x39}, 1, 0}, + + // Gamma N + {0xC0, (uint8_t[]){0x00}, 1, 0}, + {0xC1, (uint8_t[]){0x01}, 1, 0}, + {0xC2, (uint8_t[]){0x0C}, 1, 0}, + {0xC3, (uint8_t[]){0x11}, 1, 0}, + {0xC4, (uint8_t[]){0x15}, 1, 0}, + {0xC5, (uint8_t[]){0x28}, 1, 0}, + {0xC6, (uint8_t[]){0x1B}, 1, 0}, + {0xC7, (uint8_t[]){0x1C}, 1, 0}, + {0xC8, (uint8_t[]){0x62}, 1, 0}, + {0xC9, (uint8_t[]){0x1C}, 1, 0}, + {0xCA, (uint8_t[]){0x29}, 1, 0}, + {0xCB, (uint8_t[]){0x60}, 1, 0}, + {0xCC, (uint8_t[]){0x16}, 1, 0}, + {0xCD, (uint8_t[]){0x17}, 1, 0}, + {0xCE, (uint8_t[]){0x4A}, 1, 0}, + {0xCF, (uint8_t[]){0x23}, 1, 0}, + {0xD0, (uint8_t[]){0x24}, 1, 0}, + {0xD1, (uint8_t[]){0x4F}, 1, 0}, + {0xD2, (uint8_t[]){0x5F}, 1, 0}, + {0xD3, (uint8_t[]){0x39}, 1, 0}, + + /**** CMD_Page 0 ****/ + {0xFF, (uint8_t[]){0x98, 0x81, 0x00}, 3, 0}, + {0x35, (uint8_t[]){0x00}, 0, 0}, + // {0x11, (uint8_t []){0x00}, 0}, + {0xFE, (uint8_t[]){0x00}, 0, 0}, + {0x29, (uint8_t[]){0x00}, 0, 0}, + //============ Gamma END=========== +}; diff --git a/components/m5stack_tab5/include/bsp/m5stack_tab5.h b/components/m5stack_tab5/include/bsp/m5stack_tab5.h new file mode 100644 index 0000000..af53e2d --- /dev/null +++ b/components/m5stack_tab5/include/bsp/m5stack_tab5.h @@ -0,0 +1,436 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief ESP BSP: ESP32-P4 Function EV Board + */ + +#pragma once + +#include "sdkconfig.h" +#include "driver/gpio.h" +#include "driver/i2c_master.h" +#include "driver/sdmmc_host.h" +#include "driver/i2s_std.h" +#include "driver/i2s_tdm.h" +#include "bsp/config.h" +#include "bsp/display.h" +#include "esp_codec_dev.h" +#include "sdkconfig.h" + +// LVGL includes removed for SDL-based build - no LVGL functions called + +/************************************************************************************************** + * BSP Capabilities + **************************************************************************************************/ +#define BSP_CAPS_DISPLAY 1 +#define BSP_CAPS_TOUCH 1 +#define BSP_CAPS_BUTTONS 0 +#define BSP_CAPS_AUDIO 1 +#define BSP_CAPS_AUDIO_SPEAKER 1 +#define BSP_CAPS_AUDIO_MIC 1 +#define BSP_CAPS_SDCARD 1 +#define BSP_CAPS_IMU 0 + +/************************************************************************************************** + * ESP-BOX pinout + **************************************************************************************************/ +/* SYS I2C */ +#define BSP_I2C_NUM 0 +#define BSP_I2C_SCL (GPIO_NUM_32) +#define BSP_I2C_SDA (GPIO_NUM_31) + +/* EXT I2C */ +#define BSP_EXT_I2C_NUM 1 +#define BSP_EXT_I2C_SCL (GPIO_NUM_54) +#define BSP_EXT_I2C_SDA (GPIO_NUM_53) + +// /* Ext Keyboard */ +// #define TAB5_TCA8418_INT_PIN 50 // 中断输入 + +/* Audio */ +#define BSP_I2S_SCLK (GPIO_NUM_27) // 位时钟 BSP_I2S_BCLK <--> ES7210/ESP311 I2S_BCLK +#define BSP_I2S_MCLK (GPIO_NUM_30) // 主时钟 BSP_I2S_MCLK <--> ES7210/ESP311 I2S_MCLK +#define BSP_I2S_LCLK (GPIO_NUM_29) // 字(声道)选择 BSP_I2S_WR <--> ES7210/ESP311 I2S_WR +#define BSP_I2S_DOUT (GPIO_NUM_26) // 数据输出 BSP_I2S_DOUT ---> ES8388 I2S_DSIN +#define BSP_I2S_DSIN (GPIO_NUM_28) // 数据输入 BSP_I2S_DIN <--- ES7210 I2S_DOUT +#define BSP_POWER_AMP_IO (GPIO_NUM_NC) // (GPIO_NUM_53) + +/* Display */ +#define BSP_LCD_BACKLIGHT (GPIO_NUM_22) +#define BSP_LCD_RST (GPIO_NUM_NC) // +#define BSP_LCD_TOUCH_RST (GPIO_NUM_NC) // IO Exanpder 控制 +#define BSP_LCD_TOUCH_INT (GPIO_NUM_NC) // 23 + +/* uSD card */ +#define BSP_SD_D0 (GPIO_NUM_39) +#define BSP_SD_D1 (GPIO_NUM_40) +#define BSP_SD_D2 (GPIO_NUM_41) +#define BSP_SD_D3 (GPIO_NUM_42) +#define BSP_SD_CMD (GPIO_NUM_44) +#define BSP_SD_CLK (GPIO_NUM_43) + +#ifdef __cplusplus +extern "C" { +#endif + +esp_err_t bsp_cam_osc_init(void); + +/************************************************************************************************** + * + * I2C interface + * + * There are multiple devices connected to I2C peripheral: + * - Codec ES8311 (configuration only) + * - LCD Touch controller + **************************************************************************************************/ + +/** + * @brief Init I2C driver + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG I2C parameter error + * - ESP_FAIL I2C driver installation error + * + */ +esp_err_t bsp_i2c_init(void); + +/** + * @brief Deinit I2C driver and free its resources + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG I2C parameter error + * + */ +esp_err_t bsp_i2c_deinit(void); + +/** + * @brief Get I2C driver handle + * + * @return + * - I2C handle + * + */ +i2c_master_bus_handle_t bsp_i2c_get_handle(void); + +esp_err_t bsp_i2c_scan(); + +esp_err_t bsp_ext_i2c_init(void); +esp_err_t bsp_ext_i2c_deinit(void); +i2c_master_bus_handle_t bsp_ext_i2c_get_handle(void); + +esp_err_t bsp_grove_i2c_init(void); +esp_err_t bsp_grove_i2c_deinit(void); +i2c_master_bus_handle_t bsp_grove_i2c_get_handle(void); + +/************************************************************************************************** + * + * I2S audio interface + * + * There are two devices connected to the I2S peripheral: + * - Codec ES8311 for output(playback) and input(recording) path + * + * For speaker initialization use bsp_audio_codec_speaker_init() which is inside initialize I2S with bsp_audio_init(). + * For microphone initialization use bsp_audio_codec_microphone_init() which is inside initialize I2S with + *bsp_audio_init(). After speaker or microphone initialization, use functions from esp_codec_dev for play/record audio. + * Example audio play: + * \code{.c} + * esp_codec_dev_set_out_vol(spk_codec_dev, DEFAULT_VOLUME); + * esp_codec_dev_open(spk_codec_dev, &fs); + * esp_codec_dev_write(spk_codec_dev, wav_bytes, bytes_read_from_spiffs); + * esp_codec_dev_close(spk_codec_dev); + * \endcode + **************************************************************************************************/ + +/** + * @brief Init audio + * + * @note There is no deinit audio function. Users can free audio resources by calling i2s_del_channel() + * @warning The type of i2s_config param is depending on IDF version. + * @param[in] i2s_config I2S configuration. Pass NULL to use default values (Mono, duplex, 16bit, 22050 Hz) + * @return + * - ESP_OK On success + * - ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip + * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration + * - ESP_ERR_NOT_FOUND No available I2S channel found + * - ESP_ERR_NO_MEM No memory for storing the channel information + * - ESP_ERR_INVALID_STATE This channel has not initialized or already started + */ +esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config); + +/** + * @brief Initialize speaker codec device + * + * @return Pointer to codec device handle or NULL when error occurred + */ +esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void); + +/** + * @brief Initialize microphone codec device + * + * @return Pointer to codec device handle or NULL when error occurred + */ +esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void); + +typedef esp_err_t (*bsp_i2s_read_fn)(void *audio_buffer, size_t len, size_t *bytes_read, uint32_t timeout_ms); +typedef esp_err_t (*bsp_i2s_write_fn)(void *audio_buffer, size_t len, size_t *bytes_written, uint32_t timeout_ms); +typedef esp_err_t (*bsp_codec_set_in_gain_fn)(float gain); +typedef esp_err_t (*bsp_codec_mute_fn)(bool enable); +typedef int (*bsp_codec_volume_fn)(int volume); +typedef esp_err_t (*bsp_codec_get_volume_fn)(void); +typedef esp_err_t (*bsp_codec_reconfig_fn)(uint32_t rate, uint32_t bps, i2s_slot_mode_t ch); +typedef esp_err_t (*bsp_i2s_reconfig_clk_fn)(uint32_t rate, uint32_t bits_cfg, i2s_slot_mode_t ch); + +typedef struct { + bsp_i2s_read_fn i2s_read; + bsp_i2s_write_fn i2s_write; + bsp_codec_mute_fn set_mute; + bsp_codec_volume_fn set_volume; + bsp_codec_get_volume_fn get_volume; + bsp_codec_set_in_gain_fn set_in_gain; + bsp_codec_reconfig_fn codec_reconfig_fn; + bsp_i2s_reconfig_clk_fn i2s_reconfig_clk_fn; +} bsp_codec_config_t; + +void bsp_codec_init(void); +bsp_codec_config_t *bsp_get_codec_handle(void); +uint8_t bsp_codec_feed_channel(void); + +/************************************************************************************************** + * + * SPIFFS + * + * After mounting the SPIFFS, it can be accessed with stdio functions ie.: + * \code{.c} + * FILE* f = fopen(BSP_SPIFFS_MOUNT_POINT"/hello.txt", "w"); + * fprintf(f, "Hello World!\n"); + * fclose(f); + * \endcode + **************************************************************************************************/ +#define BSP_SPIFFS_MOUNT_POINT CONFIG_BSP_SPIFFS_MOUNT_POINT + +/** + * @brief Mount SPIFFS to virtual file system + * + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if esp_vfs_spiffs_register was already called + * - ESP_ERR_NO_MEM if memory can not be allocated + * - ESP_FAIL if partition can not be mounted + * - other error codes + */ +esp_err_t bsp_spiffs_mount(void); + +/** + * @brief Unmount SPIFFS from virtual file system + * + * @return + * - ESP_OK on success + * - ESP_ERR_NOT_FOUND if the partition table does not contain SPIFFS partition with given label + * - ESP_ERR_INVALID_STATE if esp_vfs_spiffs_unregister was already called + * - ESP_ERR_NO_MEM if memory can not be allocated + * - ESP_FAIL if partition can not be mounted + * - other error codes + */ +esp_err_t bsp_spiffs_unmount(void); + +/************************************************************************************************** + * + * uSD card + * + * After mounting the uSD card, it can be accessed with stdio functions ie.: + * \code{.c} + * FILE* f = fopen(BSP_MOUNT_POINT"/hello.txt", "w"); + * fprintf(f, "Hello %s!\n", bsp_sdcard->cid.name); + * fclose(f); + * \endcode + **************************************************************************************************/ +/** + * @brief Init SD crad + * + * @param mount_point Path where partition should be registered (e.g. "/sdcard") + * @param max_files Maximum number of files which can be open at the same time + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_STATE If esp_vfs_fat_register was already called + * - ESP_ERR_NOT_SUPPORTED If dev board not has SDMMC/SDSPI + * - ESP_ERR_NO_MEM If not enough memory or too many VFSes already registered + * - Others Fail + */ +esp_err_t bsp_sdcard_init(char *mount_point, size_t max_files); + +/** + * @brief Deinit SD card + * + * @param mount_point Path where partition was registered (e.g. "/sdcard") + * @return + * - ESP_OK: Success + * - Others: Fail + */ +esp_err_t bsp_sdcard_deinit(char *mount_point); + +/************************************************************************************************** + * + * LCD interface + * + * ESP-BOX is shipped with 2.4inch ST7789 display controller. + * It features 16-bit colors, 320x240 resolution and capacitive touch controller. + * + * LVGL is used as graphics library. LVGL is NOT thread safe, therefore the user must take LVGL mutex + * by calling bsp_display_lock() before calling and LVGL API (lv_...) and then give the mutex with + * bsp_display_unlock(). + * + * Display's backlight must be enabled explicitly by calling bsp_display_backlight_on() + **************************************************************************************************/ +#define BSP_LCD_PIXEL_CLOCK_MHZ (80) + +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) + +#define BSP_LCD_DRAW_BUFF_SIZE (BSP_LCD_H_RES * 50) // Frame buffer size in pixels +#define BSP_LCD_DRAW_BUFF_DOUBLE (0) + +/** + * @brief BSP display configuration structure + * + */ +typedef struct { + lvgl_port_cfg_t lvgl_port_cfg; /*!< LVGL port configuration */ + uint32_t buffer_size; /*!< Size of the buffer for the screen in pixels */ + bool double_buffer; /*!< True, if should be allocated two buffers */ + struct { + unsigned int buff_dma : 1; /*!< Allocated LVGL buffer will be DMA capable */ + unsigned int buff_spiram : 1; /*!< Allocated LVGL buffer will be in PSRAM */ + unsigned int + sw_rotate : 1; /*!< Use software rotation (slower), The feature is unavailable under avoid-tear mode */ + } flags; +} bsp_display_cfg_t; + +/** + * @brief Initialize display + * + * This function initializes SPI, display controller and starts LVGL handling task. + * LCD backlight must be enabled separately by calling bsp_display_brightness_set() + * + * @return Pointer to LVGL display or NULL when error occured + */ +lv_display_t *bsp_display_start(void); + +/** + * @brief Initialize display + * + * This function initializes SPI, display controller and starts LVGL handling task. + * LCD backlight must be enabled separately by calling bsp_display_brightness_set() + * + * @param cfg display configuration + * + * @return Pointer to LVGL display or NULL when error occured + */ +lv_display_t *bsp_display_start_with_config(const bsp_display_cfg_t *cfg); + +/** + * @brief Get pointer to input device (touch, buttons, ...) + * + * @note The LVGL input device is initialized in bsp_display_start() function. + * + * @return Pointer to LVGL input device or NULL when not initialized + */ +lv_indev_t *bsp_display_get_input_dev(void); + +/** + * @brief Take LVGL mutex + * + * @param timeout_ms Timeout in [ms]. 0 will block indefinitely. + * @return true Mutex was taken + * @return false Mutex was NOT taken + */ +bool bsp_display_lock(uint32_t timeout_ms); + +/** + * @brief Give LVGL mutex + * + */ +void bsp_display_unlock(void); + +/** + * @brief Rotate screen + * + * Display must be already initialized by calling bsp_display_start() + * + * @param[in] disp Pointer to LVGL display + * @param[in] rotation Angle of the display rotation + */ +void bsp_display_rotate(lv_display_t *disp, lv_disp_rotation_t rotation); +#endif // BSP_CONFIG_NO_GRAPHIC_LIB == 0 + +void bsp_io_expander_pi4ioe_init(i2c_master_bus_handle_t bus_handle); + +void bsp_set_charge_qc_en(bool en); + +void bsp_set_charge_en(bool en); + +void bsp_set_usb_5v_en(bool en); + +void bsp_set_ext_5v_en(bool en); + +void bsp_generate_poweroff_signal(); + +bool bsp_headphone_detect(); + +void bsp_set_ext_antenna_enable(bool en); + +void bsp_set_wifi_power_enable(bool en); + +void bsp_reset_tp(); + +bool bsp_usb_c_detect(); + +bool bsp_usb_a_detect(); + +/************************************************************************************************** + * + * USB + * + **************************************************************************************************/ + +/** + * @brief Power modes of USB Host connector + */ +typedef enum bsp_usb_host_power_mode_t { + BSP_USB_HOST_POWER_MODE_USB_DEV, //!< Power from USB DEV port +} bsp_usb_host_power_mode_t; + +/** + * @brief Start USB host + * + * This is a one-stop-shop function that will configure the board for USB Host mode + * and start USB Host library + * + * @param[in] mode USB Host connector power mode (Not used on this board) + * @param[in] limit_500mA Limit output current to 500mA (Not used on this board) + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_ERR_NO_MEM Memory cannot be allocated + */ +esp_err_t bsp_usb_host_start(bsp_usb_host_power_mode_t mode, bool limit_500mA); + +/** + * @brief Stop USB host + * + * USB Host lib will be uninstalled and power from connector removed. + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t bsp_usb_host_stop(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/m5stack_tab5/include/bsp/touch.h b/components/m5stack_tab5/include/bsp/touch.h new file mode 100644 index 0000000..fb9e019 --- /dev/null +++ b/components/m5stack_tab5/include/bsp/touch.h @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief BSP Touchscreen + * + * This file offers API for basic touchscreen initialization. + * It is useful for users who want to use the touchscreen without the default Graphical Library LVGL. + * + * For standard LCD initialization with LVGL graphical library, you can call all-in-one function bsp_display_start(). + */ + +#pragma once +#include "esp_lcd_touch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief BSP touch configuration structure + * + */ +typedef struct { + void *dummy; /*!< Prepared for future use. */ +} bsp_touch_config_t; + +/** + * @brief Create new touchscreen + * + * If you want to free resources allocated by this function, you can use esp_lcd_touch API, ie.: + * + * \code{.c} + * esp_lcd_touch_del(tp); + * \endcode + * + * @param[in] config touch configuration + * @param[out] ret_touch esp_lcd_touch touchscreen handle + * @return + * - ESP_OK On success + * - Else esp_lcd_touch failure + */ +esp_err_t bsp_touch_new(const bsp_touch_config_t *config, esp_lcd_touch_handle_t *ret_touch); + +#ifdef __cplusplus +} +#endif diff --git a/components/m5stack_tab5/m5stack_tab5.c b/components/m5stack_tab5/m5stack_tab5.c new file mode 100644 index 0000000..fd8fab5 --- /dev/null +++ b/components/m5stack_tab5/m5stack_tab5.c @@ -0,0 +1,1454 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" +#include "driver/gpio.h" +#include "driver/ledc.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_spiffs.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_mipi_dsi.h" +#include "esp_ldo_regulator.h" +#include "esp_vfs_fat.h" +#include "usb/usb_host.h" +#include "sd_pwr_ctrl_by_on_chip_ldo.h" +#include "freertos/task.h" +#include "sdmmc_cmd.h" +#include "esp_lcd_st7703.h" +#include "esp_lcd_ili9881c.h" +#include "bsp/m5stack_tab5.h" +#include "bsp/display.h" +#include "bsp/touch.h" +#include "esp_lcd_touch_gt911.h" +#include "bsp_err_check.h" +#include "esp_codec_dev_defaults.h" + +static const char* TAG = "M5STACK_TAB5"; + +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) +static lv_indev_t* disp_indev = NULL; +#endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) + +// Global uSD card handler +sdmmc_card_t* bsp_sdcard = NULL; + +// USB Host Library task +static TaskHandle_t usb_host_task; + +// sys i2c +static bool i2c_initialized = false; +static i2c_master_bus_handle_t i2c_handle = NULL; +// ext i2c +static bool ext_i2c_initialized = false; +static i2c_master_bus_handle_t ext_i2c_bus_handle = NULL; +// grove i2c +static bool grove_i2c_initialized = false; +static i2c_master_bus_handle_t grove_i2c_bus_handle = NULL; +// i2s +static i2s_chan_handle_t i2s_tx_chan = NULL; +static i2s_chan_handle_t i2s_rx_chan = NULL; +static const audio_codec_data_if_t* i2s_data_if = NULL; /* Codec data interface */ + +//================================================================================== +// camera 设置输出时钟 +//================================================================================== + +esp_err_t bsp_cam_osc_init(void) +{ + ledc_timer_config_t timer_conf; + timer_conf.duty_resolution = LEDC_TIMER_1_BIT; + timer_conf.freq_hz = 24000000; // <<<< change this to the frequency you want + timer_conf.speed_mode = LEDC_LOW_SPEED_MODE; + timer_conf.deconfigure = false; + timer_conf.clk_cfg = LEDC_AUTO_CLK; + timer_conf.timer_num = LEDC_TIMER_0; + esp_err_t err = ledc_timer_config(&timer_conf); + if (err != ESP_OK) { + ESP_LOGE(TAG, "ledc_timer_config failed for freq %d, rc=%x", 24000000, err); + } + + ledc_channel_config_t ch_conf; + ch_conf.gpio_num = 36; // 摄像头时钟输入 + ch_conf.speed_mode = LEDC_LOW_SPEED_MODE; + ch_conf.channel = LEDC_CHANNEL_0; + ch_conf.intr_type = LEDC_INTR_DISABLE; + ch_conf.timer_sel = LEDC_TIMER_0; + ch_conf.duty = 1; + ch_conf.hpoint = 0; + ch_conf.sleep_mode = LEDC_SLEEP_MODE_KEEP_ALIVE; + err = ledc_channel_config(&ch_conf); + if (err != ESP_OK) { + ESP_LOGE(TAG, "ledc_channel_config failed, rc=%x", err); + } + + return ESP_OK; +} + +//================================================================================== +// i2c +//================================================================================== +esp_err_t bsp_i2c_init(void) +{ + /* I2C was initialized before */ + if (i2c_initialized) { + return ESP_OK; + } + + i2c_master_bus_config_t i2c_bus_conf = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .sda_io_num = BSP_I2C_SDA, + .scl_io_num = BSP_I2C_SCL, + .i2c_port = BSP_I2C_NUM, + .flags.enable_internal_pullup = true, + }; + BSP_ERROR_CHECK_RETURN_ERR(i2c_new_master_bus(&i2c_bus_conf, &i2c_handle)); + + i2c_initialized = true; + + return ESP_OK; +} + +esp_err_t bsp_i2c_deinit(void) +{ + BSP_ERROR_CHECK_RETURN_ERR(i2c_del_master_bus(i2c_handle)); + i2c_initialized = false; + return ESP_OK; +} + +i2c_master_bus_handle_t bsp_i2c_get_handle(void) +{ + return i2c_handle; +} + +esp_err_t bsp_ext_i2c_init(void) +{ + if (ext_i2c_initialized) { + return ESP_OK; + } + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = BSP_EXT_I2C_NUM, + .scl_io_num = BSP_EXT_I2C_SCL, + .sda_io_num = BSP_EXT_I2C_SDA, + .flags.enable_internal_pullup = true, + }; + i2c_new_master_bus(&i2c_mst_config, &ext_i2c_bus_handle); + + ext_i2c_initialized = true; + + return ESP_OK; +} + +esp_err_t bsp_ext_i2c_deinit(void) +{ + ext_i2c_initialized = false; + return i2c_del_master_bus(ext_i2c_bus_handle); +} + +i2c_master_bus_handle_t bsp_ext_i2c_get_handle(void) +{ + return ext_i2c_bus_handle; +} + +esp_err_t bsp_grove_i2c_init(void) +{ + if (grove_i2c_initialized) { + return ESP_OK; + } + + i2c_master_bus_config_t i2c_mst_config = { + .clk_source = I2C_CLK_SRC_DEFAULT, + .i2c_port = BSP_EXT_I2C_NUM, + .scl_io_num = 54, // BSP_EXT_I2C_SCL, + .sda_io_num = 53, // BSP_EXT_I2C_SDA, + .flags.enable_internal_pullup = true, + }; + i2c_new_master_bus(&i2c_mst_config, &grove_i2c_bus_handle); + + grove_i2c_initialized = true; + + return ESP_OK; +} + +esp_err_t bsp_grove_i2c_deinit(void) +{ + grove_i2c_initialized = false; + return i2c_del_master_bus(grove_i2c_bus_handle); +} + +i2c_master_bus_handle_t bsp_grove_i2c_get_handle(void) +{ + return grove_i2c_bus_handle; +} + +esp_err_t bsp_i2c_scan() +{ + esp_err_t ret; + uint8_t address; + + printf("scan i2c device\n"); + printf("\n 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n"); + for (int i = 0; i < 128; i += 16) { + printf("%02x: ", i); + for (int j = 0; j < 16; j++) { + fflush(stdout); + address = i + j; + ret = i2c_master_probe(i2c_handle, address, 50); + if (ret == ESP_OK) { + printf("%02x ", address); + } else if (ret == ESP_ERR_TIMEOUT) { + printf("UU "); + } else { + printf("-- "); + } + } + printf("\r\n"); + } + printf("\nscan i2c device finished\n"); + + return ESP_OK; +} + +//================================================================================== +// I/O Exapnder PI4IOE5V6416 +//================================================================================== +#define I2C_DEV_ADDR_PI4IOE1 0x43 // addr pin low +#define I2C_DEV_ADDR_PI4IOE2 0x44 // addr pin high +#define I2C_MASTER_TIMEOUT_MS 50 + +static i2c_master_dev_handle_t i2c_dev_handle_pi4ioe1; +static i2c_master_dev_handle_t i2c_dev_handle_pi4ioe2; + +// PI4IO registers +#define PI4IO_REG_CHIP_RESET 0x01 +#define PI4IO_REG_IO_DIR 0x03 +#define PI4IO_REG_OUT_SET 0x05 +#define PI4IO_REG_OUT_H_IM 0x07 +#define PI4IO_REG_IN_DEF_STA 0x09 +#define PI4IO_REG_PULL_EN 0x0B +#define PI4IO_REG_PULL_SEL 0x0D +#define PI4IO_REG_IN_STA 0x0F +#define PI4IO_REG_INT_MASK 0x11 +#define PI4IO_REG_IRQ_STA 0x13 + +#define setbit(x, y) x |= (0x01 << y) +#define clrbit(x, y) x &= ~(0x01 << y) + +void bsp_io_expander_pi4ioe_init(i2c_master_bus_handle_t bus_handle) +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + /* */ + i2c_device_config_t dev_cfg1 = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = I2C_DEV_ADDR_PI4IOE1, + .scl_speed_hz = 400000, + }; + ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg1, &i2c_dev_handle_pi4ioe1)); + + write_buf[0] = PI4IO_REG_CHIP_RESET; + write_buf[1] = 0xFF; + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + write_buf[0] = PI4IO_REG_CHIP_RESET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe1, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + write_buf[0] = PI4IO_REG_IO_DIR; + write_buf[1] = 0b01111111; + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, I2C_MASTER_TIMEOUT_MS); // 0: input 1: output + write_buf[0] = PI4IO_REG_OUT_H_IM; + write_buf[1] = 0b00000000; + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, + I2C_MASTER_TIMEOUT_MS); // 使用到的引脚关闭 High-Impedance + write_buf[0] = PI4IO_REG_PULL_SEL; + write_buf[1] = 0b01111111; + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, + I2C_MASTER_TIMEOUT_MS); // pull up/down select, 0 down, 1 up + write_buf[0] = PI4IO_REG_PULL_EN; + write_buf[1] = 0b01111111; + + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, + I2C_MASTER_TIMEOUT_MS); // P7 中断使能 0 enable, 1 disable + /* Output Port Register P1(SPK_EN), P2(EXT5V_EN), P4(LCD_RST), P5(TP_RST), P6(CAM)RST 输出高电平 */ + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = 0b01110110; + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + + /* */ + i2c_device_config_t dev_cfg2 = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = I2C_DEV_ADDR_PI4IOE2, + .scl_speed_hz = 400000, + }; + ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg2, &i2c_dev_handle_pi4ioe2)); + + write_buf[0] = PI4IO_REG_CHIP_RESET; + write_buf[1] = 0xFF; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + write_buf[0] = PI4IO_REG_CHIP_RESET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + write_buf[0] = PI4IO_REG_IO_DIR; + write_buf[1] = 0b10111001; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); // 0: input 1: output + write_buf[0] = PI4IO_REG_OUT_H_IM; + write_buf[1] = 0b00000110; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, + I2C_MASTER_TIMEOUT_MS); // 使用到的引脚关闭 High-Impedance + write_buf[0] = PI4IO_REG_PULL_SEL; + write_buf[1] = 0b10111001; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, + I2C_MASTER_TIMEOUT_MS); // pull up/down select, 0 down, 1 up + write_buf[0] = PI4IO_REG_PULL_EN; + write_buf[1] = 0b11111001; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, + I2C_MASTER_TIMEOUT_MS); // pull up/down enable, 0 disable, 1 enable + write_buf[0] = PI4IO_REG_IN_DEF_STA; + write_buf[1] = 0b01000000; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); // P6 默认高电平 + write_buf[0] = PI4IO_REG_INT_MASK; + write_buf[1] = 0b10111111; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, + I2C_MASTER_TIMEOUT_MS); // P6 中断使能 0 enable, 1 disable + /* Output Port Register P0(WLAN_PWR_EN), P3(USB5V_EN), P7(CHG_EN) 输出高电平 */ + write_buf[0] = PI4IO_REG_OUT_SET; + // write_buf[1] = 0b10001001; + write_buf[1] = 0b00001001; + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); +} + +void bsp_set_charge_qc_en(bool en) +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + if (en) { + clrbit(write_buf[1], 5); + } else { + setbit(write_buf[1], 5); + } + + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); +} + +void bsp_set_charge_en(bool en) +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + if (en) { + setbit(write_buf[1], 7); + } else { + clrbit(write_buf[1], 7); + } + + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); +} + +void bsp_set_usb_5v_en(bool en) +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + if (en) { + setbit(write_buf[1], 3); + } else { + clrbit(write_buf[1], 3); + } + + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); +} + +void bsp_set_ext_5v_en(bool en) +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe1, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + if (en) { + setbit(write_buf[1], 2); + } else { + clrbit(write_buf[1], 2); + } + + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, I2C_MASTER_TIMEOUT_MS); +} + +void bsp_generate_poweroff_signal() +{ + ESP_LOGW(TAG, "Generate poweroff signal!"); + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[1] = read_buf[0]; + + // Try to generate poweroff signal 3 times to make sure it works :) + for (int i = 0; i < 3; i++) { + setbit(write_buf[1], 4); + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + vTaskDelay(100 / portTICK_PERIOD_MS); + + clrbit(write_buf[1], 4); + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + vTaskDelay(100 / portTICK_PERIOD_MS); + } +} + +bool bsp_headphone_detect() +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_IN_STA; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe1, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + // printf("get %02x\n", read_buf[0]); + + // Get bit 8 + bool ret = false; + if (read_buf[0] & 0b10000000) { + ret = true; + } + + return ret; +} + +bool bsp_usb_c_detect() +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_IN_STA; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + // printf("get %02x\n", read_buf[0]); + + // Get bit 6 + bool ret = false; + if (read_buf[0] & 0b01000000) { + ret = true; + } + + return ret; +} + +void bsp_set_ext_antenna_enable(bool en) +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe1, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + if (en) { + setbit(write_buf[1], 0); + } else { + clrbit(write_buf[1], 0); + } + + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, I2C_MASTER_TIMEOUT_MS); +} + +void bsp_set_wifi_power_enable(bool en) +{ + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + ESP_LOGI(TAG, "set_wifi_power_enable: %d", en); + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + if (en) { + setbit(write_buf[1], 0); + } else { + clrbit(write_buf[1], 0); + } + + i2c_master_transmit(i2c_dev_handle_pi4ioe2, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe2, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + printf("0x%02X: %02x\n", PI4IO_REG_OUT_SET, read_buf[0]); +} + +void bsp_reset_tp() +{ + ESP_LOGI(TAG, "reset tp"); + + ESP_LOGI(TAG, "reset gpio %d", GPIO_NUM_23); + gpio_reset_pin(GPIO_NUM_23); + + uint8_t write_buf[2] = {0}; + uint8_t read_buf[1] = {0}; + + write_buf[0] = PI4IO_REG_OUT_SET; + i2c_master_transmit_receive(i2c_dev_handle_pi4ioe1, write_buf, 1, read_buf, 1, I2C_MASTER_TIMEOUT_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + clrbit(write_buf[1], 4); + clrbit(write_buf[1], 5); + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + vTaskDelay(100 / portTICK_PERIOD_MS); + + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = read_buf[0]; + setbit(write_buf[1], 4); + setbit(write_buf[1], 5); + i2c_master_transmit(i2c_dev_handle_pi4ioe1, write_buf, 2, I2C_MASTER_TIMEOUT_MS); + vTaskDelay(100 / portTICK_PERIOD_MS); +} + +//================================================================================== +// sd card +//================================================================================== +#define BSP_LDO_PROBE_SD_CHAN 4 +#define BSP_LDO_PROBE_SD_VOLTAGE_MV 3300 + +#define SDMMC_BUS_WIDTH (4) // SDIO 4 线模式 +#define GPIO_SDMMC_DET (GPIO_NUM_NC) // SDIO 卡检测 +// M5Stack-Tab5-P4 +#define GPIO_SDMMC_CLK (GPIO_NUM_43) // SDIO 时钟 +#define GPIO_SDMMC_CMD (GPIO_NUM_44) // SDIO 命令 +#define GPIO_SDMMC_D0 (GPIO_NUM_39) // SDIO 数据 0 +#define GPIO_SDMMC_D1 (GPIO_NUM_40) // SDIO 数据 1 +#define GPIO_SDMMC_D2 (GPIO_NUM_41) // SDIO 数据 2 +#define GPIO_SDMMC_D3 (GPIO_NUM_42) // SDIO 数据 3 + +static sdmmc_card_t* card; + +esp_err_t bsp_sdcard_init(char* mount_point, size_t max_files) +{ + esp_err_t ret_val = ESP_OK; + + if (NULL != card) { + return ESP_ERR_INVALID_STATE; + } + + /** + * @brief Use settings defined above to initialize SD card and mount FAT filesystem. + * Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions. + * Please check its source code and implement error recovery when developing + * production applications. + * + */ + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + host.slot = SDMMC_HOST_SLOT_0; // + // host.slot = SDMMC_HOST_SLOT_1; // + host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; + sd_pwr_ctrl_ldo_config_t ldo_config = { + .ldo_chan_id = BSP_LDO_PROBE_SD_CHAN, // `LDO_VO4` is used as the SDMMC IO power + }; + static sd_pwr_ctrl_handle_t pwr_ctrl_handle = NULL; + + if (pwr_ctrl_handle == NULL) { + ret_val = sd_pwr_ctrl_new_on_chip_ldo(&ldo_config, &pwr_ctrl_handle); + if (ret_val != ESP_OK) { + ESP_LOGE(TAG, "Failed to new an on-chip ldo power control driver"); + return ret_val; + } + } + host.pwr_ctrl_handle = pwr_ctrl_handle; + + /** + * @brief This initializes the slot without card detect (CD) and write protect (WP) signals. + * Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. + * + */ + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + slot_config.width = SDMMC_BUS_WIDTH; + slot_config.clk = GPIO_SDMMC_CLK; + slot_config.cmd = GPIO_SDMMC_CMD; + slot_config.d0 = GPIO_SDMMC_D0; + slot_config.d1 = GPIO_SDMMC_D1; + slot_config.d2 = GPIO_SDMMC_D2; + slot_config.d3 = GPIO_SDMMC_D3; + // slot_config.cd = GPIO_SDMMC_DET; + // slot_config.flags |= SDMMC_SLOT_FLAG_INTERNAL_PULLUP; + + /** + * @brief Options for mounting the filesystem. + * If format_if_mount_failed is set to true, SD card will be partitioned and + * formatted in case when mounting fails. + */ + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = false, .max_files = max_files, .allocation_unit_size = 16 * 1024}; + + ret_val = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card); + + /* Check for SDMMC mount result. */ + if (ret_val != ESP_OK) { + if (ret_val == ESP_FAIL) { + ESP_LOGE(TAG, + "Failed to mount filesystem. " + "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option."); + } else { + ESP_LOGE(TAG, + "Failed to initialize the card (%s). " + "Make sure SD card lines have pull-up resistors in place.", + esp_err_to_name(ret_val)); + } + return ret_val; + } + + /* Card has been initialized, print its properties. */ + sdmmc_card_print_info(stdout, card); + + return ret_val; +} + +esp_err_t bsp_sdcard_deinit(char* mount_point) +{ + if (mount_point == NULL) { + return ESP_ERR_INVALID_STATE; + } + + /* Unmount an SD card from the FAT filesystem and release resources acquired */ + esp_err_t ret_val = esp_vfs_fat_sdcard_unmount(mount_point, card); + + // ret_val = sd_pwr_ctrl_del_on_chip_ldo(card->host.pwr_ctrl_handle); + // if (ret_val != ESP_OK) { + // ESP_LOGE(TAG, "Failed to delete on-chip ldo power control driver"); + // } + + /* Make SD/MMC card information structure pointer NULL */ + card = NULL; + + return ret_val; +} + +//================================================================================== +// spiffs +//================================================================================== +esp_err_t bsp_spiffs_mount(void) +{ + esp_vfs_spiffs_conf_t conf = { + .base_path = CONFIG_BSP_SPIFFS_MOUNT_POINT, + .partition_label = CONFIG_BSP_SPIFFS_PARTITION_LABEL, + .max_files = CONFIG_BSP_SPIFFS_MAX_FILES, +#ifdef CONFIG_BSP_SPIFFS_FORMAT_ON_MOUNT_FAIL + .format_if_mount_failed = true, +#else + .format_if_mount_failed = false, +#endif + }; + + esp_err_t ret_val = esp_vfs_spiffs_register(&conf); + + BSP_ERROR_CHECK_RETURN_ERR(ret_val); + + size_t total = 0, used = 0; + ret_val = esp_spiffs_info(conf.partition_label, &total, &used); + if (ret_val != ESP_OK) { + ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret_val)); + } else { + ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used); + } + + return ret_val; +} + +esp_err_t bsp_spiffs_unmount(void) +{ + return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL); +} + +//================================================================================== +// audio es7210 + es8388 +//================================================================================== +static esp_codec_dev_handle_t play_dev_handle; +static esp_codec_dev_handle_t record_dev_handle; +static bsp_codec_config_t g_codec_handle; +static int volume; + +/* Can be used for `i2s_std_gpio_config_t` and/or `i2s_std_config_t` initialization */ +#define BSP_I2S_GPIO_CFG \ + { \ + .mclk = BSP_I2S_MCLK, .bclk = BSP_I2S_SCLK, .ws = BSP_I2S_LCLK, .dout = BSP_I2S_DOUT, .din = BSP_I2S_DSIN, \ + .invert_flags = { \ + .mclk_inv = false, \ + .bclk_inv = false, \ + .ws_inv = false, \ + }, \ + } + +/* This configuration is used by default in `bsp_extra_audio_init()` */ +#define BSP_I2S_DUPLEX_MONO_CFG(_sample_rate) \ + { \ + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(_sample_rate), \ + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), \ + .gpio_cfg = BSP_I2S_GPIO_CFG, \ + } + +esp_err_t bsp_audio_init(const i2s_std_config_t* i2s_config) +{ + if (i2s_tx_chan && i2s_rx_chan) { + /* Audio was initialized before */ + return ESP_OK; + } + + /* Setup I2S peripheral */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_BSP_I2S_NUM, I2S_ROLE_MASTER); + chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer + ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &i2s_tx_chan, &i2s_rx_chan)); + + /* Setup I2S channels */ + // const i2s_std_config_t std_cfg_default = BSP_I2S_DUPLEX_MONO_CFG(16000); + const i2s_std_config_t std_cfg_default = BSP_I2S_DUPLEX_MONO_CFG(48000); + const i2s_std_config_t* p_i2s_cfg = &std_cfg_default; + if (i2s_config != NULL) { + p_i2s_cfg = i2s_config; + } + + if (i2s_tx_chan != NULL) { + ESP_ERROR_CHECK(i2s_channel_init_std_mode(i2s_tx_chan, p_i2s_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(i2s_tx_chan)); + } + + // if (i2s_rx_chan != NULL) { + // ESP_ERROR_CHECK(i2s_channel_init_std_mode(i2s_rx_chan, p_i2s_cfg)); + // ESP_ERROR_CHECK(i2s_channel_enable(i2s_rx_chan)); + // } + + i2s_tdm_config_t tdm_cfg = { + .clk_cfg = + { + .sample_rate_hz = (uint32_t)48000, + .clk_src = I2S_CLK_SRC_DEFAULT, + .ext_clk_freq_hz = 0, + .mclk_multiple = I2S_MCLK_MULTIPLE_256, + .bclk_div = 8, + }, + .slot_cfg = {.data_bit_width = I2S_DATA_BIT_WIDTH_16BIT, + .slot_bit_width = I2S_SLOT_BIT_WIDTH_AUTO, + .slot_mode = I2S_SLOT_MODE_STEREO, + .slot_mask = (I2S_TDM_SLOT0 | I2S_TDM_SLOT1 | I2S_TDM_SLOT2 | I2S_TDM_SLOT3), + .ws_width = I2S_TDM_AUTO_WS_WIDTH, + .ws_pol = false, + .bit_shift = true, + .left_align = false, + .big_endian = false, + .bit_order_lsb = false, + .skip_mask = false, + .total_slot = I2S_TDM_AUTO_SLOT_NUM}, + .gpio_cfg = BSP_I2S_GPIO_CFG, + }; + + if (i2s_rx_chan != NULL) { + ESP_ERROR_CHECK(i2s_channel_init_tdm_mode(i2s_rx_chan, &tdm_cfg)); + ESP_ERROR_CHECK(i2s_channel_enable(i2s_rx_chan)); + } + + audio_codec_i2s_cfg_t i2s_cfg = { + .port = CONFIG_BSP_I2S_NUM, + .tx_handle = i2s_tx_chan, + .rx_handle = i2s_rx_chan, + }; + i2s_data_if = audio_codec_new_i2s_data(&i2s_cfg); + + return ESP_OK; +} + +esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) +{ + static esp_codec_dev_handle_t codec = NULL; + if (codec) { + return codec; + } + + if (i2s_data_if == NULL) { + /* Initilize I2C */ + bsp_i2c_init(); + /* Configure I2S peripheral and Power Amplifier */ + bsp_audio_init(NULL); + } + assert(i2s_data_if); + + const audio_codec_gpio_if_t* gpio_if = audio_codec_new_gpio(); + + i2c_master_bus_handle_t i2c_bus_handle = bsp_i2c_get_handle(); + audio_codec_i2c_cfg_t i2c_cfg = { + .port = BSP_I2C_NUM, + .addr = ES8388_CODEC_DEFAULT_ADDR, + .bus_handle = i2c_bus_handle, + }; + const audio_codec_ctrl_if_t* i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); + BSP_NULL_CHECK(i2c_ctrl_if, NULL); + + esp_codec_dev_hw_gain_t gain = { + .pa_voltage = 5.0, + .codec_dac_voltage = 3.3, + }; + + es8388_codec_cfg_t es8388_cfg = { + .codec_mode = ESP_CODEC_DEV_WORK_MODE_DAC, + .master_mode = false, + .ctrl_if = i2c_ctrl_if, + .pa_pin = -1, // PI4IOE1 P1 控制 + }; + const audio_codec_if_t* es8388_dev = es8388_codec_new(&es8388_cfg); + BSP_NULL_CHECK(es8388_dev, NULL); + + esp_codec_dev_cfg_t codec_dev_cfg = { + .dev_type = ESP_CODEC_DEV_TYPE_OUT, + .codec_if = es8388_dev, + .data_if = i2s_data_if, + }; + codec = esp_codec_dev_new(&codec_dev_cfg); + BSP_NULL_CHECK(codec, NULL); + + return codec; +} + +esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void) +{ + if (i2s_data_if == NULL) { + /* Initilize I2C */ + ESP_ERROR_CHECK(bsp_i2c_init()); + /* Configure I2S peripheral and Power Amplifier */ + ESP_ERROR_CHECK(bsp_audio_init(NULL)); + // i2s_data_if = bsp_get_codec_data_if(); + } + assert(i2s_data_if); + + i2c_master_bus_handle_t i2c_bus_handle = bsp_i2c_get_handle(); + audio_codec_i2c_cfg_t i2c_cfg = { + .port = BSP_I2C_NUM, + .addr = ES7210_CODEC_DEFAULT_ADDR, + .bus_handle = i2c_bus_handle, + }; + const audio_codec_ctrl_if_t* i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg); + BSP_NULL_CHECK(i2c_ctrl_if, NULL); + + es7210_codec_cfg_t es7210_cfg = { + .ctrl_if = i2c_ctrl_if, // Codec Control interface + }; + es7210_cfg.mic_selected = ES7210_SEL_MIC1 | ES7210_SEL_MIC2 | ES7210_SEL_MIC3 | ES7210_SEL_MIC4; + const audio_codec_if_t* es7210_dev = es7210_codec_new(&es7210_cfg); + BSP_NULL_CHECK(es7210_dev, NULL); + + esp_codec_dev_cfg_t codec_es7210_dev_cfg = { + .dev_type = + ESP_CODEC_DEV_TYPE_IN, // Codec device type: Codec input device like ADC (capture data from microphone) + .codec_if = es7210_dev, // Codec interface + .data_if = i2s_data_if, // Codec data interface + }; + + return esp_codec_dev_new(&codec_es7210_dev_cfg); +} + +static esp_err_t bsp_i2s_read(void* audio_buffer, size_t len, size_t* bytes_read, uint32_t timeout_ms) +{ + esp_err_t ret = ESP_OK; + ret = esp_codec_dev_read(record_dev_handle, audio_buffer, len); + *bytes_read = len; + return ret; +} + +static esp_err_t bsp_i2s_write(void* audio_buffer, size_t len, size_t* bytes_written, uint32_t timeout_ms) +{ + esp_err_t ret = ESP_OK; + ret = esp_codec_dev_write(play_dev_handle, audio_buffer, len); + *bytes_written = len; + return ret; +} + +static esp_err_t bsp_codec_set_in_gain(float gain) +{ + return esp_codec_dev_set_in_gain(record_dev_handle, gain); +} + +static esp_err_t bsp_codec_set_mute(bool enable) +{ + esp_err_t ret = ESP_OK; + ret = esp_codec_dev_set_out_mute(play_dev_handle, enable); + return ret; +} + +static esp_err_t bsp_codec_set_volume(int v) +{ + esp_err_t ret = ESP_OK; + + if (v <= 0) { + volume = 0; + ret = esp_codec_dev_set_out_mute(play_dev_handle, true); + } else { + volume = v; + ret = esp_codec_dev_set_out_mute(play_dev_handle, false); + ret |= esp_codec_dev_set_out_vol(play_dev_handle, volume); + } + + return ret; +} + +static int bsp_codec_get_volume(void) +{ + return volume; +} + +bsp_codec_config_t* bsp_get_codec_handle(void) +{ + return &g_codec_handle; +} + +static esp_err_t bsp_codec_es8388_set(uint32_t rate, uint32_t bps, i2s_slot_mode_t ch) +{ + esp_err_t ret = ESP_OK; + + esp_codec_dev_sample_info_t fs = { + .sample_rate = rate, + .channel = ch, + .bits_per_sample = bps, + }; + + if (play_dev_handle) { + ret = esp_codec_dev_close(play_dev_handle); + } + ret = esp_codec_dev_open(play_dev_handle, &fs); + + return ret; +} + +static esp_err_t bsp_codec_es7210_set(uint32_t rate, uint32_t bps, i2s_slot_mode_t ch) +{ + esp_err_t ret = ESP_OK; + + esp_codec_dev_sample_info_t fs = { + .sample_rate = rate, + .channel = ch, + .bits_per_sample = bps, + }; + + if (record_dev_handle) { + ret = esp_codec_dev_close(record_dev_handle); + } + ret = esp_codec_dev_open(record_dev_handle, &fs); + + // esp_codec_dev_set_in_gain(record_dev_handle, 80.0); // Set codec input gain + + return ret; +} + +void bsp_codec_init(void) +{ + play_dev_handle = bsp_audio_codec_speaker_init(); + assert((play_dev_handle) && "play_dev_handle not initialized"); + + record_dev_handle = bsp_audio_codec_microphone_init(); + assert((record_dev_handle) && "record_dev_handle not initialized"); + + // bsp_codec_es7210_set(16000, 16, 2); + // bsp_codec_es8388_set(16000, 16, 2); + // bsp_codec_es7210_set(48000, 16, 2); + bsp_codec_es7210_set(48000, 16, 4); + bsp_codec_es8388_set(48000, 16, 2); + + /* 初始化 codec handle */ + bsp_codec_config_t* codec_cfg = bsp_get_codec_handle(); // 获取 codec handle + codec_cfg->i2s_read = bsp_i2s_read; // I2S 读数据 + codec_cfg->i2s_write = bsp_i2s_write; // I2S 写数据 + codec_cfg->set_mute = bsp_codec_set_mute; // 静音设置 + codec_cfg->set_volume = bsp_codec_set_volume; // 音量设置 + codec_cfg->get_volume = bsp_codec_get_volume; + codec_cfg->set_in_gain = bsp_codec_set_in_gain; // 麦克风输入增益设置 + codec_cfg->codec_reconfig_fn = bsp_codec_es7210_set; + codec_cfg->i2s_reconfig_clk_fn = bsp_codec_es8388_set; + + codec_cfg->set_volume(80); +} + +uint8_t bsp_codec_feed_channel(void) +{ + return 3; // 2*mic_num + ref_num +} + +//================================================================================== +// lcd st7703 1280x720 gt911 +//================================================================================== +// Bit number used to represent command and parameter +#define LCD_LEDC_CH LEDC_CHANNEL_1 // CONFIG_BSP_DISPLAY_BRIGHTNESS_LEDC_CH +esp_err_t bsp_display_brightness_init(void) +{ + // gpio_config_t io_conf = {}; + + // io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt + // io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode + // io_conf.pin_bit_mask = 1 << BSP_LCD_BACKLIGHT; //select pin + // io_conf.pull_down_en = 0; //disable pull-down mode + // io_conf.pull_up_en = 0; //disable pull-up mode + // gpio_config(&io_conf); //configure GPIO with the given settings + + // gpio_set_level(BSP_LCD_BACKLIGHT, 1); + + // Setup LEDC peripheral for PWM backlight control + const ledc_timer_config_t lcd_backlight_timer = {.speed_mode = LEDC_LOW_SPEED_MODE, + // .duty_resolution = LEDC_TIMER_10_BIT, + .duty_resolution = LEDC_TIMER_12_BIT, + .timer_num = LEDC_TIMER_0, + .freq_hz = 5000, + // .freq_hz = 20000, + .clk_cfg = LEDC_AUTO_CLK}; + ESP_ERROR_CHECK(ledc_timer_config(&lcd_backlight_timer)); + + const ledc_channel_config_t lcd_backlight_channel = {.gpio_num = BSP_LCD_BACKLIGHT, + .speed_mode = LEDC_LOW_SPEED_MODE, + .channel = LCD_LEDC_CH, + .intr_type = LEDC_INTR_DISABLE, + .timer_sel = LEDC_TIMER_0, + .duty = 0, + .hpoint = 0}; + + ESP_ERROR_CHECK(ledc_channel_config(&lcd_backlight_channel)); + + return ESP_OK; +} + +esp_err_t bsp_display_brightness_set(int brightness_percent) +{ + if (brightness_percent > 100) { + brightness_percent = 100; + } + if (brightness_percent < 0) { + brightness_percent = 0; + } + + ESP_LOGI(TAG, "Setting LCD backlight: %d%%", brightness_percent); + // uint32_t duty_cycle = (1023 * brightness_percent) / 100; // LEDC resolution set to 10bits, thus: 100% = 1023 + uint32_t duty_cycle = (4095 * brightness_percent) / 100; // LEDC resolution set to 12bits, thus: 100% = 4095 + BSP_ERROR_CHECK_RETURN_ERR(ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle)); + BSP_ERROR_CHECK_RETURN_ERR(ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH)); + return ESP_OK; +} + +esp_err_t bsp_display_backlight_off(void) +{ + return bsp_display_brightness_set(0); +} + +esp_err_t bsp_display_backlight_on(void) +{ + return bsp_display_brightness_set(100); +} + +static esp_err_t bsp_enable_dsi_phy_power(void) +{ +#if BSP_MIPI_DSI_PHY_PWR_LDO_CHAN > 0 + // Turn on the power for MIPI DSI PHY, so it can go from "No Power" state to "Shutdown" state + static esp_ldo_channel_handle_t phy_pwr_chan = NULL; + esp_ldo_channel_config_t ldo_cfg = { + .chan_id = BSP_MIPI_DSI_PHY_PWR_LDO_CHAN, + .voltage_mv = BSP_MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV, + }; + ESP_RETURN_ON_ERROR(esp_ldo_acquire_channel(&ldo_cfg, &phy_pwr_chan), TAG, "Acquire LDO channel for DPHY failed"); + ESP_LOGI(TAG, "MIPI DSI PHY Powered on"); +#endif // BSP_MIPI_DSI_PHY_PWR_LDO_CHAN > 0 + + return ESP_OK; +} + +esp_err_t bsp_display_new(const bsp_display_config_t* config, esp_lcd_panel_handle_t* ret_panel, + esp_lcd_panel_io_handle_t* ret_io) +{ + esp_err_t ret = ESP_OK; + bsp_lcd_handles_t handles; + ret = bsp_display_new_with_handles(config, &handles); + + *ret_panel = handles.panel; + *ret_io = handles.io; + + return ret; +} + +#define LCD_MIPI_DSI_USE_ILI9881C + +#if defined(LCD_MIPI_DSI_USE_ILI9881C) && !defined(LCD_MIPI_DSI_USE_ST7703) +#include "ili9881_init_data.c" +#endif + +esp_err_t bsp_display_new_with_handles(const bsp_display_config_t* config, bsp_lcd_handles_t* ret_handles) +{ + esp_err_t ret = ESP_OK; + esp_lcd_panel_io_handle_t io = NULL; + esp_lcd_panel_handle_t disp_panel = NULL; + + ESP_RETURN_ON_ERROR(bsp_display_brightness_init(), TAG, "Brightness init failed"); + ESP_RETURN_ON_ERROR(bsp_enable_dsi_phy_power(), TAG, "DSI PHY power failed"); + + /* create MIPI DSI bus first, it will initialize the DSI PHY as well */ + esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL; + esp_lcd_dsi_bus_config_t bus_config = { + .bus_id = 0, + .num_data_lanes = BSP_LCD_MIPI_DSI_LANE_NUM, + .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, + .lane_bit_rate_mbps = BSP_LCD_MIPI_DSI_LANE_BITRATE_MBPS, + }; + ESP_RETURN_ON_ERROR(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus), TAG, "New DSI bus init failed"); + + ESP_LOGI(TAG, "Install MIPI DSI LCD control panel"); + // we use DBI interface to send LCD commands and parameters + esp_lcd_dbi_io_config_t dbi_config = { + .virtual_channel = 0, + .lcd_cmd_bits = 8, // according to the LCD spec + .lcd_param_bits = 8, // according to the LCD spec + }; + ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &io), err, TAG, "New panel IO failed"); + +#if defined(LCD_MIPI_DSI_USE_ILI9881C) && !defined(LCD_MIPI_DSI_USE_ST7703) + ESP_LOGI(TAG, "Install LCD driver of ili9881c"); + esp_lcd_dpi_panel_config_t dpi_config = { + .virtual_channel = 0, + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = 60, // 720*1280 RGB24 60Hz RGB24 // 80, + .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565, + .num_fbs = 1, + .video_timing = + { + .h_size = BSP_LCD_H_RES, + .v_size = BSP_LCD_V_RES, + .hsync_back_porch = 140, + .hsync_pulse_width = 40, + .hsync_front_porch = 40, + .vsync_back_porch = 20, + .vsync_pulse_width = 4, + .vsync_front_porch = 20, + }, + .flags.use_dma2d = true, + }; + + ili9881c_vendor_config_t vendor_config = { + .init_cmds = tab5_lcd_ili9881c_specific_init_code_default, + .init_cmds_size = sizeof(tab5_lcd_ili9881c_specific_init_code_default) / + sizeof(tab5_lcd_ili9881c_specific_init_code_default[0]), + .mipi_config = + { + .dsi_bus = mipi_dsi_bus, + .dpi_config = &dpi_config, + .lane_num = 2, + }, + }; + + const esp_lcd_panel_dev_config_t lcd_dev_config = { + .bits_per_pixel = 16, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .reset_gpio_num = -1, + .vendor_config = &vendor_config, + }; + ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(io, &lcd_dev_config, &disp_panel)); + ESP_ERROR_CHECK(esp_lcd_panel_reset(disp_panel)); + ESP_ERROR_CHECK(esp_lcd_panel_init(disp_panel)); + // ESP_ERROR_CHECK(esp_lcd_panel_mirror(disp_panel, false, true)); + ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(disp_panel, true)); + +#elif defined(LCD_MIPI_DSI_USE_ST7703) && !defined(LCD_MIPI_DSI_USE_ILI9881C) + ESP_LOGI(TAG, "Install LCD driver of ST7703"); + esp_lcd_dpi_panel_config_t dpi_config = { + .virtual_channel = 0, + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = 60, // LCD_MIPI_DSI_DPI_CLK_MHZ_ST7703, + .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565, // LCD_COLOR_PIXEL_FORMAT_RGB888, + .num_fbs = 1, + .video_timing = + { + .h_size = BSP_LCD_H_RES, // lcd_param.width, + .v_size = BSP_LCD_V_RES, // lcd_param.height, + .hsync_back_porch = 40, + .hsync_pulse_width = 10, + .hsync_front_porch = 40, + .vsync_back_porch = 16, + .vsync_pulse_width = 4, + .vsync_front_porch = 16, + }, + //.flags.use_dma2d = true, // ??? 开启后需要等待 previous draw 完成 + }; + + st7703_vendor_config_t vendor_config = { + .flags.use_mipi_interface = 1, + .mipi_config = + { + .dsi_bus = mipi_dsi_bus, + .dpi_config = &dpi_config, + }, + }; + esp_lcd_panel_dev_config_t lcd_dev_config = { + .bits_per_pixel = 16, // 24, + .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, + .reset_gpio_num = -1, + .vendor_config = &vendor_config, + }; + ESP_GOTO_ON_ERROR(esp_lcd_new_panel_st7703(io, &lcd_dev_config, &disp_panel), err, TAG, + "New LCD panel EK79007 failed"); + ESP_GOTO_ON_ERROR(esp_lcd_panel_init(disp_panel), err, TAG, "LCD panel init failed"); +#endif + + /* Return all handles */ + ret_handles->io = io; + ret_handles->mipi_dsi_bus = mipi_dsi_bus; + ret_handles->panel = disp_panel; + ret_handles->control = NULL; + + ESP_LOGI(TAG, "Display initialized with resolution %dx%d", BSP_LCD_H_RES, BSP_LCD_V_RES); + + return ret; + +err: + if (disp_panel) { + esp_lcd_panel_del(disp_panel); + } + if (io) { + esp_lcd_panel_io_del(io); + } + if (mipi_dsi_bus) { + esp_lcd_del_dsi_bus(mipi_dsi_bus); + } + return ret; +} + +esp_err_t bsp_touch_new(const bsp_touch_config_t* config, esp_lcd_touch_handle_t* ret_touch) +{ + /* Initilize I2C */ + BSP_ERROR_CHECK_RETURN_ERR(bsp_i2c_init()); + + /* Initialize touch */ + const esp_lcd_touch_config_t tp_cfg = { + .x_max = BSP_LCD_H_RES, + .y_max = BSP_LCD_V_RES, + .rst_gpio_num = -1, // BSP_LCD_TOUCH_RST, // NC + .int_gpio_num = 23, // BSP_LCD_TOUCH_INT, + .levels = + { + .reset = 0, + .interrupt = 0, + }, + .flags = + { + .swap_xy = 0, + .mirror_x = 0, + .mirror_y = 0, + }, + }; + esp_lcd_panel_io_handle_t tp_io_handle = NULL; + esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG(); + tp_io_config.dev_addr = ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP; // 更改 GT911 地址 + tp_io_config.scl_speed_hz = CONFIG_BSP_I2C_CLK_SPEED_HZ; + ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c(i2c_handle, &tp_io_config, &tp_io_handle), TAG, ""); + return esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, ret_touch); +} + +#if (BSP_CONFIG_NO_GRAPHIC_LIB == 0) +static lv_display_t* bsp_display_lcd_init(const bsp_display_cfg_t* cfg) +{ + assert(cfg != NULL); + bsp_lcd_handles_t lcd_panels; + BSP_ERROR_CHECK_RETURN_NULL(bsp_display_new_with_handles(NULL, &lcd_panels)); + + /* Add LCD screen */ + ESP_LOGD(TAG, "Add LCD screen"); + const lvgl_port_display_cfg_t disp_cfg = + {.io_handle = lcd_panels.io, + .panel_handle = lcd_panels.panel, + .control_handle = lcd_panels.control, + .buffer_size = cfg->buffer_size, + .double_buffer = cfg->double_buffer, + .hres = BSP_LCD_H_RES, + .vres = BSP_LCD_V_RES, + .monochrome = false, + /* Rotation values must be same as used in esp_lcd for initial settings of the screen */ + .rotation = + { + .swap_xy = false, + .mirror_x = false, + .mirror_y = false, + }, +#if LVGL_VERSION_MAJOR >= 9 +#if CONFIG_BSP_LCD_COLOR_FORMAT_RGB888 + .color_format = LV_COLOR_FORMAT_RGB888, +#else + .color_format = LV_COLOR_FORMAT_RGB565, +#endif +#endif + .flags = { + .buff_dma = cfg->flags.buff_dma, + .buff_spiram = cfg->flags.buff_spiram, +#if LVGL_VERSION_MAJOR >= 9 + .swap_bytes = (BSP_LCD_BIGENDIAN ? true : false), +#endif +#if CONFIG_BSP_DISPLAY_LVGL_AVOID_TEAR + .sw_rotate = false, /* Avoid tearing is not supported for SW rotation */ +#else + .sw_rotate = cfg->flags.sw_rotate, /* Only SW rotation is supported for 90° and 270° */ +#endif +#if CONFIG_BSP_DISPLAY_LVGL_FULL_REFRESH + .full_refresh = true, +#elif CONFIG_BSP_DISPLAY_LVGL_DIRECT_MODE + .direct_mode = true, +#endif + } }; + + const lvgl_port_display_dsi_cfg_t dpi_cfg = {.flags = { +#if CONFIG_BSP_DISPLAY_LVGL_AVOID_TEAR + .avoid_tearing = true, +#else + .avoid_tearing = false, +#endif + }}; + + return lvgl_port_add_disp_dsi(&disp_cfg, &dpi_cfg); +} + +static esp_lcd_touch_handle_t _touch_handle; + +esp_lcd_touch_handle_t bsp_display_get_touch_handle(void) +{ + return _touch_handle; +} + +esp_lcd_touch_handle_t _lcd_touch_handle; + +static lv_indev_t* bsp_display_indev_init(lv_display_t* disp) +{ + esp_lcd_touch_handle_t tp; + BSP_ERROR_CHECK_RETURN_NULL(bsp_touch_new(NULL, &tp)); + esp_lcd_touch_exit_sleep(tp); // !!! + assert(tp); + _lcd_touch_handle = tp; + + /* Add touch input (for selected screen) */ + const lvgl_port_touch_cfg_t touch_cfg = { + .disp = disp, + .handle = tp, + }; + + return lvgl_port_add_touch(&touch_cfg); +} + +lv_display_t* bsp_display_start(void) +{ + bsp_display_cfg_t cfg = {.lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG(), + .buffer_size = BSP_LCD_DRAW_BUFF_SIZE, + .double_buffer = BSP_LCD_DRAW_BUFF_DOUBLE, + .flags = { +#if CONFIG_BSP_LCD_COLOR_FORMAT_RGB888 + .buff_dma = false, +#else + .buff_dma = true, +#endif + .buff_spiram = false, + .sw_rotate = true, + }}; + return bsp_display_start_with_config(&cfg); +} + +lv_display_t* bsp_display_start_with_config(const bsp_display_cfg_t* cfg) +{ + lv_display_t* disp; + + assert(cfg != NULL); + BSP_ERROR_CHECK_RETURN_NULL(lvgl_port_init(&cfg->lvgl_port_cfg)); + + BSP_ERROR_CHECK_RETURN_NULL(bsp_display_brightness_init()); + + BSP_NULL_CHECK(disp = bsp_display_lcd_init(cfg), NULL); + BSP_NULL_CHECK(disp_indev = bsp_display_indev_init(disp), NULL); + return disp; +} + +lv_indev_t* bsp_display_get_input_dev(void) +{ + return disp_indev; +} + +void bsp_display_rotate(lv_display_t* disp, lv_disp_rotation_t rotation) +{ + lv_disp_set_rotation(disp, rotation); +} + +bool bsp_display_lock(uint32_t timeout_ms) +{ + return lvgl_port_lock(timeout_ms); +} + +void bsp_display_unlock(void) +{ + lvgl_port_unlock(); +} +#endif // (BSP_CONFIG_NO_GRAPHIC_LIB == 0) + +//================================================================================== +// usb +//================================================================================== +static void usb_lib_task(void* arg) +{ + while (1) { + // Start handling system events + uint32_t event_flags; + usb_host_lib_handle_events(portMAX_DELAY, &event_flags); + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { + ESP_ERROR_CHECK(usb_host_device_free_all()); + } + if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { + ESP_LOGI(TAG, "USB: All devices freed"); + // Continue handling USB events to allow device reconnection + // The only way this task can be stopped is by calling bsp_usb_host_stop() + } + } +} + +esp_err_t bsp_usb_host_start(bsp_usb_host_power_mode_t mode, bool limit_500mA) +{ + // Install USB Host driver. Should only be called once in entire application + ESP_LOGI(TAG, "Installing USB Host"); + const usb_host_config_t host_config = { + .skip_phy_setup = false, + .intr_flags = ESP_INTR_FLAG_LEVEL1, + }; + BSP_ERROR_CHECK_RETURN_ERR(usb_host_install(&host_config)); + + // Create a task that will handle USB library events + if (xTaskCreate(usb_lib_task, "usb_lib", 4096, NULL, 10, &usb_host_task) != pdTRUE) { + ESP_LOGE(TAG, "Creating USB host lib task failed"); + abort(); + } + + return ESP_OK; +} + +esp_err_t bsp_usb_host_stop(void) +{ + usb_host_uninstall(); + if (usb_host_task) { + vTaskSuspend(usb_host_task); + vTaskDelete(usb_host_task); + } + return ESP_OK; +} diff --git a/components/m5stack_tab5/priv_include/bsp_err_check.h b/components/m5stack_tab5/priv_include/bsp_err_check.h new file mode 100644 index 0000000..90fbda7 --- /dev/null +++ b/components/m5stack_tab5/priv_include/bsp_err_check.h @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_check.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Assert on error, if selected in menuconfig. Otherwise return error code. */ +#if CONFIG_BSP_ERROR_CHECK +#define BSP_ERROR_CHECK_RETURN_ERR(x) ESP_ERROR_CHECK(x) +#define BSP_ERROR_CHECK_RETURN_NULL(x) ESP_ERROR_CHECK(x) +#define BSP_ERROR_CHECK(x, ret) ESP_ERROR_CHECK(x) +#define BSP_NULL_CHECK(x, ret) assert(x) +#define BSP_NULL_CHECK_GOTO(x, goto_tag) assert(x) +#else +#define BSP_ERROR_CHECK_RETURN_ERR(x) \ + do { \ + esp_err_t err_rc_ = (x); \ + if (unlikely(err_rc_ != ESP_OK)) { \ + return err_rc_; \ + } \ + } while (0) + +#define BSP_ERROR_CHECK_RETURN_NULL(x) \ + do { \ + if (unlikely((x) != ESP_OK)) { \ + return NULL; \ + } \ + } while (0) + +#define BSP_NULL_CHECK(x, ret) \ + do { \ + if ((x) == NULL) { \ + return ret; \ + } \ + } while (0) + +#define BSP_ERROR_CHECK(x, ret) \ + do { \ + if (unlikely((x) != ESP_OK)) { \ + return ret; \ + } \ + } while (0) + +#define BSP_NULL_CHECK_GOTO(x, goto_tag) \ + do { \ + if ((x) == NULL) { \ + goto goto_tag; \ + } \ + } while (0) +#endif + +#ifdef __cplusplus +} +#endif diff --git a/docs/img/m5stack-tab5.webp b/docs/img/m5stack-tab5.webp new file mode 100644 index 0000000000000000000000000000000000000000..16123b8a63b966014202bdd388c604fe90410735 GIT binary patch literal 173790 zcmZ^}b95z9)98J2VkZ;Zwrx*r+qOjwj<00A;$VoF}XuU!Dp>pwjN zGXP-k;O3$tB}%NNtwRib1b_yB{l@|T7@N8}sY;0bm;XQc-<|){Jud%m-vx&MxBdS( z{=Wdu%-q%V%kcKq%uJnJ+yDSDqc8ULbaVO-Z+w(w*0@?U9J#0_eX;?#pHdVEoTKe&zYv{%3w%E!bH9s{%t1001C2 zKR@s2008I&0N_30^YgX%^YgtJ003VH0QzG7XMFJ290>G$etvfSkM4U90MNh*0Kj$p zkB<5)CMp5|FuLkw>|*@iJm6nF(82-$xGe_&5VZjSwArsQx?fkM9Cry2z|HZ7AEkM(6XpGUOd1je!X%p{CT<3pTFQVo7QN9kPGV}{thN@ z!6xmL=lGwr!8DIZa_oD-xD`Po#f48i@S<)#>DLyr(MFcRR!dHkbiarT z(=rsL50x)1V&P{MF9vfz<;Fy*zkiDQ%LnNA`r|Z zVQ9H9-7xCzg>V(hl`zy>KwmgS2@Z%G#YNQr(=RS1Uh6FI;>?~tXnKNt{u zf{BV4w*am(1`bF~45T%}{LwrB011Pk4k1yk^7I>>L!d&~RgkJ(L-fJ=ansIs>fkrq zlS|8#zsbyOeuzaxzzTEN{K*t&2ikP=po29jp$KFAW@ELgzkTTsh&mj3%-F9@Z%ums zc2d}$k2~5J6v1Q}f{9MytA2%fm;r7jytX|WGlHoUN@iHwBc1^BE5HYKFuT21zcLw4(`<8oI0&ft^IcGHqb~{`%3VbhZXJ$x8ku%GB2$>((8G2 zu*%ureH+;&=LSdWt2w=Dsie)A;@LbMAn_xiIi)&f;RZ6~z|s9I0osLz`h>^IU7+)t z#04GlM3?aSsp!ogQ}>Py zk+g)WT0_SAl%|@Til0G9Z*2)`eg8MGRziSz74pj}jPJK!8JhMg4gID*t=33D7hiW` z%6%^JD@6SOMe`38?%Y4U^B5PA_=5vmd-?Y)!gd>y3F79z>aQ;>eqH^7{mq;N0UK+R zH`K6j)M^TRoBsU#NFt{rWvlA6E%SW5!mz60_zYMs!^}(jg!}=}+O>g)$5XVmwyxQW z%H7(|s;#Y@bd6(qiuc0tiDeze0e^@ynrnV_<~3n7nT?iaj}(k>L&{=BW3j^3Hz(Jz zwNjHp&k}h<33Xs+f=)#Z#%6aMBIPuh^+mP6;20(#o5N?fBx{UyMv2T6ALYQEG8>Wy zuQ4ZEw<2Z4?UgL1VRzh*V;MFmp6f>N#7IJ-ih`P&`-C z0F79NUmnYOC0QUCA-QnU)-+rlXmc;pWLofC$O>Gt!kvqVm1bX)#EFLD%H{AtV0VoX zwMG0o1l$@SDBSgT;`LR$z-4?-E+C?1jJT@RxYZDDXju&7S1~xAv$8|Pan2LMbc4y{ zGD-FuNg?FtdUabP2WWRbkAGc;T6Rh=##-%{S{Y<)YU*5xd{N*c%|z#KnkW!DhPa!2 zJD;lOOn`3+fM4558jt++NMj-^i(| zyQ^Cm@EYq8aLglW zwN^3?8Tv)dhYVPn)D&>7Cq-f7661(}zhJ8li_(dH#i)j6SazQGQZrE>D%ls--i^Q^OeGde999#r`-_&MW$h1Xzla^rYH}LI0dKNZik_}TLESH| z*WiF>J!x8Y&VRz0Mp;zn{5y*SQa}=y#%h0V#i~K2`Z}1^hE$SXpgpS3n#CM%1*LS7 z-G-E~RO@F%M_2|+toHVH1iGH7O0~!G4f$BBooo_0>g63FmIl(=YMIVT3l7`F=abzn zu}qT9Myq|Mce9{TzcKw~j%&UPD_cISUo%2H>}<0A>)WU6Z9e_Sd!yOw`(LLPE3c}5 zyvErsRwKa9B4XNF5Pi4W+mM`W7hWHW15rAoZ^>`yAb&V&L%||a6Dt-pb0Q2! z^@flfeei*1`{MiCvLEp{(i@biy?8(50CmEr8Dt5Vxu0gxlOnxXB~^BMCn1TSBy8=GacUfpaEr>Js1Q_8GvdwlZ z3$Xd8J6_&FyP1r9Mi9NejCFVrP@E(dIN&6F4$~hB0DB4vhtMi#!4oLdy+H?Ho;rxN zK-kT~3FDjtOzFPa(hbExWk8_7Nz-&X}#c?(jYgEY=U zaseR#P-zN7jV^l3HYC|pwNi8dOqDcxQ3PgbC@c;-06daHq{;+d6z*QoLI+Pz*qC^% zUuy7#a#9PSAUrxGP_2_HE6Rrz5ZD+|L`uBp=52B%!V{Eq!Oy0nys!@el1g%U384Jd$!(s8+y=3WJoqLb3kGiUOOcm6iW4*1jCz%7vL+JX;;QK=bP4FJFd zjE)E4yRir(b0S~gvj+qbCj!Eq5j;Am`k3M9YJLZ3^ifONDt|kroShuKB1T;fDgn^o zc49X^va69r;`V0&QP&V?`pLutf^>+1w@L`Q2t!lYQMjkXl)>Qj04)<-ym@h$#e88% zQrt$cMhzBpwV*I=eIqa^bcxfm8!MKKaD15kptLTjR2&RgVTNK&WEgQ_HAv_zt3gM=CecJhvku0SJJQ zL^MrD<-qhRY>}H3;5xGP$IjQ{5T#^j^rlwYUyRFBK@zUH)@~!Q059ig?VXoVXh^w8_Xqyal%Za zkd^!)qLotZA#k=}HIK&%%BP$$s71S3WA2m*04N%O9SVQvAnJ5W$IZl@F?Zt?P0xEz z1|*icFkWL^nOZbZLPR_S8l8RTLGSX)zFaW}a{?xf2yOh*0 zb8uTV6UC0DBqDvNrZVBlK!6B91T7L196^qLl$J4|V9tan7^=R@e23Hr9?qV2!V19~ z7=|Lz9z}5wHO5YGTOb->@_edaJBrD?kzQpK;UHo%5A5Sq711s^>te$T>?$OYDW2~HJNTqyFnwD0eWYcmFr8W@ z9K#KqnvGbZQ)SRSvVny6oT?8J%2BvHl(o4c+i5q%-Bga3v zx|Tstk_^ff^chaZ-*x9R8<0up*Pp`<_h5*yeZYZky=_I9KNyQ5$o@V>J%E3G80=1Y z?FMk89YYe}u89Z;RH&5T3|TGsfZXcDeAsPZ{svwkN{Hl;etfq5+djmbptE5h5*OLezBv*n^=lJBN2L%>WP+q*)8ft?CB9me#z@-h_P75|X$8W?@K%6+0tv8bpI0c~`&Jo1t2sDOwJE6n& zA9Aw*dfw@K0>NVJ7ZuQI%0={7)7=SXzk_9Cl=$jc(;$(+)wF@eYI_Cw~Le*jlIn;%so647#IR|J`YSiA36FS)v0e*%BNR@mb-? zAUH7Wo8`y3n()$pd7MY>AE35{yYUr+Im<0afvS;5)!yDd*YdN};&G=R7bhL7<%-Zq!T=QZklhw&wPHSNec%Bs zcWNFk9}0?&XS8#M+58+;|NKGe9GO_G^z{@<&@jr+I&->LA86GOl02DgCES7p%~HL> z*dseuq5C6%!GK#~-ro<10V5b2OZiXtMU zmKJK@7+KCnUlw#tJGL9NYZ58vd$CiIG>a`Kx`VJdglC@WtAy*z;0h^(7&QcLT=n^A zotd&y-(E@vN(FQ3Ss_m}+@$l^>pB^hhAF=~1TX*$5X?*h^Lsc4rb!hm56=E_KXn~W zfH*#6&eRlAS8N3nF=V?AbJ8BUa z92I&Dl$fF?%)MY3hVBo_a{m!vHo2riW1}nywTM`o+f$NyDM)buT_$F*szR7KYR!PM zKM07qy%YJ~Vka-@GQeBHBOI8BYi-6zn-QOL8vt3Gr?TlWl4W8N8eGuXoedLIk3@A! zDo!fip%~ok>-X$t>a>A_kl3EH^TzN~#QKw3tsiBnV{1;=kvC}!nyD4*g5bwm_uHQ4 z8~EKaPaX-re{EO(28u4QyWS;5hU=RfwZw5)&GE;Bah>*kJ&kX#r*-Z+KOVAOV>#(Y zi#I8j23MD`QnP5bp{w`Wb*$G(Fej1!lmL@Mi8-&)?xBP}pWBn=T`6eyq90L+Pg5=D zAss5b27LPuA;EpF0Nv*ACEHq~U_ie^kUm;n!B5_?n^r%yi95~sP1dqHnzG@KC&W$9 zk3zDD`RYNGw9InC6Bg3J_6im6MdoP*A$kSR3D!x+4Vuq)aH733C_bt7Nd8> z^24;ipsaGyhP<^QJwCNL+L{A%>g;tg(EQ2?dIf}Ca>cdTP2oehw}uVqFpoglcrOk zc5Sv+zt=gV3OZoHMdIq93pg9~+I8q;k`ayxWa|dFVGA62P$BD_j33nRWOXp#3H$Bp z9d5X>vTUXFa?VP8$SJ7p;kLlE)$S5(U(FN#*o6&!?rHs_l*&elRpUtid$tG^A!x~sd{;b`NZ_qG-Er)oX1kiVleyr>fnU^nc9JnmpV z|H|4*+1?h#Jck<5oTo&Qui9Ed7{%hx^azwj*5on>AHyOB>7bSer!Rz0)E49zcD)FF zw$Q-04wF~2OiAj-{Y zGj(-U&wm?oX|Mp|_>w5*HOy;*J1<*yKYo@Wn#=LsvLFuxLbf&hA=d0@_4Z!?61vpd z|FRL`mjRoF&#Tl-ioY=AG;C{|l48nL>wcHWeOjj0ANiFg8-93ejD@2f2zT8NDZ1u$ zqaBaGS71Iu!3f_AXw6hkulu`cK$vxXrR{z4e7HT4{jwqGV}IA^M!rlg{qnoF#jWBx zE8%8WCj{28Pi!lYfb@4L3B$BNI;{)Y@zkf&4{pXzRaXzU-lOHjRn@yLQ$5LpZ_Av> zYh`I0#Zk|C^K1TRlV{NXKn|M^yZBf0&MSI7_p_9X^?hVee4h7g&y>rx%8skP&&kM+ zD~q`i&jMT~MH)BKzq==vE(fE+L%7m=9b{hJjOF4WYTM^K)5kp&21~EfJh;itKzK)M z>v`WA-OUq&rvz>cZiW}0Ri4%RObuCIYS+01^gQpbi=RKzW(2*x_-lO*$@1bJX>P8t zYnCP20@e(A?@avfzu6&ODtM1zPAsQ%tsiB!$D~i0Tn}t#5$^YHx}H$6G&yZGP}ObZ zc{LO?AutEc7BAO&XzMRzYa~gZRv3D3z5Bjark#{2G+U7QU~^uJ8cuE)`i8-??hLw0 zot|s?xM;^;FS+J7+{)B|!4<|mMi6=1<*m05=G8y+19{G_FRyjQW58H2wSTUv8wxef zV>Tu`B9ukIYoZ`Q$h`cN?|s`m@^07Pf2Px?esml* zEE+rvsiuh3ESR{pZ`HSI*H*`Lq=h!8YYM(}((P$=p4am#<|hsP)IOQ6)l;IdPCg9N zOzz3Ws$e^g8{L+$6nszg5NQxL{8o2dmG5`w_i}#uvL3y>lU+VewA?!sJ~@4pXS!(0 zlylbLtTDl_Y4F2VzDlNr;-TVu2eL(J&wAHl+b$&%6DR-qSX-fPx32cC>OT=TX6&RK zVvAmTB?y{Aa!i?yn$I+~ZgH)Gc8ux;O8WCCGJCYEcD}2uiQm6}ynMTq~-MzJsPC)l9o(I1`=yx5rmld5_C$Jgb6KSAS(7O!+sdR~|uW z`$5_(R*IS2g6DV;z7ux6Rasq{(s%sNxc%3!}6PD+bHXkpX?dL5hHDl04j2`kXy*~69 zY5(0WQdk>{esnl{H+bDgTvJVV-%e)t#&kI5tgc<>i3C5C$-Kd(33VSXJs0%YF1S3# z;Uw)m(7x*4YC5A&{|rZT9r8f-joj)Xx`F{+0uKYRkQ4`>b%S1?D?Jx}m&fm23iPHA z%8Si>m^pu_?t|zL!}*V2-qg-HX7oHaFSJ`nwmCjT1zOJ@&N+laRs>wCeCFJrch;7p z)9WApcpa^JOXokd{(iV9ZzprT>+l+c$FyVR2gUM!;#7tuzk_;Rk~Gyd%Oa%CSD&`t zal1~cLCCSK2?Mrj@w)zhOrbFoWpp$`o7mME4)IKVzS-ja>dO648f{YY5JWFs~yrD5r*@YAp#5gS@wurqB{z)~jw+ik8KS_iSM!S(Q{ zX=nUde&@CHvBQZ=lg>xXVULkYxP)?ndi1v%UkCqOzlNaq{{F@U(~?1)Ys-j+QZ2!^ z2wc#VRG6ne_u-y(p1pb8c=%I~)ime>TyT)84RYIvtKGY9hu6)`kFl0v9G7TyP~Udh zV6~Ti6K&S`b8<1JGNt21)9GC=j7$3pZ-vq|gY#uMPSX0&rgmrOgf0GV0om|? zAUrQ!?Da?L#xULct*D@h;(Go>T(AGnBhUP5hXaC-f2Krk1-P|>k8i z1@3E59D&9m`&<3FcPHA4{9J`LZ#xb5FvHtTW*gGHg zk!h;v1iH&e;rhci6-5sH#WLJsa;!ugB$*b#l?{@9=5OE2|A7tdW+EXXp=hQ{J@mLBKN|*6JZZ z1lRF(!=Q`K0SH|ukTvpxc6DOR+5EY(l$f*o-EL_Xx6dgxxQruRb2}F*9R6J;w&ULOGTc@?9+pq73Jpnl&!%lf#!Q? zM#=v9D-vnYt5n#U64`EH_zEAc5rX#3?%)Q?DU<Cuqwy- z0k10I=hmS?HOw7ab|^kt6h!s&hvhD8QwcpH>=?@y%+79g_h!SOhlF~ zmZR_8NbyxeR}5sb#_Ah=+}%-BTuH{hv9y(o{$dg)7Fk|cn=j2jwY88-KF^JAviD)h zNjU(Rhy^`12-+cBTvmJI8fY@IMHt*>z4yfMDZqhmuM zA=Y8uWA~AR0LWs0keztEY4_tisvc9#3->R)f8IswA#M#ku6uYAd_Aqc(t9fxdgP`W zRCRY2vXnBY{#)sXO=}@VF`x)p>bCiRIMSJ{HQ#OiS|AutjRiSA zN=0-OcQvCtY)9yUjgf#(%DOChnGyB^Ve!B13w(27+(N zB&m$DWe)F_HOS(7&4M@`(%jq?In>10T&4+5Qp{s2Z zI(r#1OA^__va7A#k|2u(orMZbzUvNYnCpx#&CRY-xG$~fe38LaJ+dO$dqI}xmckU1 z-+vc*#%E+?ncKtqq2G1@o4~>{J!PnnO2|+S1k)pTi{P9dEdt(olN*^~F!7GwD*r?EyISd?;0&Rb}d3tMrC4 zAjdtwMpLW5LsiputWpF$GDac&QKTX|2cxVCcQ?f}#w0rqbuVY9Q}DN`skenhE{9_A zG*aGL37R`%J}oyORwRM@o6V7sHkk7q@yT4rUJsW|JXKkj+>TB9WQB?QaMPW~$7pgS zwu#M8VFK+Je~+J67sKDY85v$rHfF|Q(SLLEMuo}5eXz%D7cO;x{TM0STC{=M1o2Jk zGmlgd1d-Za>k^2LzLJZ0r7Kf)g{R6(s19>=)e4{+Sn?1=aoUpp5pdw!9eybiR2?k? zk%@I7E3LJG`VZ@dbj-?Q$q9OB9z&?%&&dK@{zz*3b63(8Jd0O3Y(R}+8yZt2E%G!4 zqZQ)`W}+`6@4VneLptj6Mj~uO>`_Jc$wP@Ipgb>*g-nNFP;2}YYE;jTzRp-2yXev<6t5~(D0_VUO+uT+uV^OWJplXi!+dGa8=fO zAla1A;+_dYveNDG{!UT#btRsz`54|mqF4vZmw}CNmN=9oD&$zMU{`D@RC{FCe*YGd zR7RY(BBbyBZDGkJ@j50=Y>0a0_-*QvcX=Ifr68d-?_%F%J)%{!B4^sM8lQ|&9U1^C z27k0s6OCXYy%_yjQQX$5r|^&^M6X?i?eBVJriQx8$x#ILP$Ez@$p zJIYFBM0%)b??oCbK}YwJ1A|W~!6yk+02l~e6s0996M_ou91@zSdxMiDGKu&E8E3QB zB(IK6$kwpw_-_g`_L|%l8%D!v+s! zn0M>)Q~~`?DGvARmmM#WnP>?Vk>4_r#=TV3I?_DN%ZhL&Yu~Rq@3w$}S{MN)!{|=m zz_4?z42u{Tl?93(a0#v5JoIuvKOg;r4v+C&*>hL3B)1xB+D>?6Hh8uKP9^W55)-NA1>rMlgDR}v85lh6T;L_}4aGG&JEWC(7J+E@m42;_G>t`CLBLE-cb&xCA z^1tjuWHw5@$2HrH4j?)vJq7X?(;iaatg3rhypP7qB{50syA(I^#d*sv^WfCSOcdub zm+#_EMlB>Z@Tt>nck+kVLFCr-1qCR0w0TXRRZaxMsacPQqXm_Rj&MWf{PA-TA1+ye z5n5xJu9O?|o6=6^kl`8_WTizF&UfQB9t^Bk45Y4jq1~Hyu1>sA9JzWH4ha?Rvv!Yw za_b8*>omM&%>ORjmx@VxJ~l7x4!+3a*mC(h`&`0F=WG;-b|hk$v4xRC>@|ybrBk;p zcKGMtQ{Bf)uX);P%nigrX0Saa5F%WkWCuZHIr(17JwV36YcD>16Pdwb| z)7u_yj6wA5+^&ABDww-9ee>QnFJdrpi4_$awSANyI=fuaN+_6y(4G}7hc%eiMI9)88bj;*a2P8%j1Z^-oj>0f{htg|Mg2MtY7p|X$8(rm%n~$-kEKT`t?lNCZcBQry^?`@9Zu7A)cJ8N4^?}8%-2Z>zr}y zw^<*p7nd8SvY2n>NK$sRbF63=SQT*4Z)QcF@ZY~8+3VPlT?q0J3W1P-Ki^v%E}zp0 zaq`;TRYF9-@sd8G&>Z}dRCH*mGF_-4yp8-M6-O;X1v2>n1nY^LkGjW{1(vWRrFzd|bhZRo+Fl5nv<-+%sRhlRhz+mCtiX z=`CZNO%D5$W=60z4$@mAx-{L(qto{&k38~-2pP@&Nq9t25MQs-dXd|O+K5#)apDQ> zg94BxEdu5$i=n3=2Q|mj*@?oy16I;zWV^t=SD9VH-#reQ7^q?y&GGW1GX@P>d7nVK z`31EPZ8RsNFbZr{)kZ`F(4YD_zz`aT(Ba!A zsGWXRa1yc7ZC}fB4YsXf@TQ9exda}{i}anpOZX`~d3U3jn`uT*V_`r77tq)IZ#>X^ zPYzaHEsBV|-48tn=CpI@q%_8ys4)84W(u_{IL)_ZRE&^7N^_Wq@sQj}w;35`0H1pZ zt~-I7<0|#Im4VGuf!MNXEUv`4)gr!jC)HDxF0=pxgn@@LKOvF4;K}|F`dKqc!)srv zCIN{e=ns;41`djHB#ha2>yuHAhq>)qnACxN_>sW2B;V>mJvlwiJ2o%`9MmSv(P7(dtS*4$&5UXb$j?Q!~CRw9CwEON%xv@8`6Z> zwPl&=M&#RaIw7EkVNf@+oc*QM5}`Gm&!;_zU%3rT7h!X7KtZ3#+@|03s1vO zRHk2#P`+>S-cOg^tY|u7o;pV1M4lJIxZ*A@o)8N%GBx57z_cTgP(Ik4&259ujy5IH z5q}noGthCXqbMNrM1lbs?0aZ8c1&IkcaPfq?~wV$DkxLB_&x_D#1gtr z4<7E>#x`aUmnbo!IJGVk7Y(s{Y&5&%L?hlP)b(6YftxKv88Skc2ii*mN&M^_8G58$5{W%4#bw`G z#kw-Bgj+{*b>s5;c*t2qRP)OCcK-X#lvD2Kg?#a8UZ@rYMCWSui`f)-^pD@uIr z6Ylah%ykRhZLR(#Ub2pUipJc{yWo)Lg7Rs0;OQ`;Nz*r|3Y>#Lv1bZm<>ohp;3Pc+c$=Dl!yq^ltiFs4y z>pz-E7LXb(!y&{xdLUF7S$4nvFvfAa@N5na5)2@Bx$yRJnd2QDMq>^9a;|)zp&}=16|&BYPf!CF|6=80S*7W+`tjV6^V?@&rF6t{SM=>Q}9cuDvyi6F1Ip7y0}RNaA` z|M8iuaMlH=F^fw@=eS_77Thycd<(rfLAs*BiZzx}LsCxsbkzNbazPbNw9_NypuG%3 zg0B2qIT(U!Jf~WK_*GdF1M0RgtE3A4@YuATSJskZV6HVs3$p*tzRP0<^Pg0#&5fS; zXmTl;SqujDc4b-UpxL~wPHWyX--FdXpMKMAC>=pk`0s$pr9(_Gx(2*$veO`Z+WNlw zB@8PB85mGH3nkHedsS%?hBD0)@#~p`+5 z#*2>5Fuc4+({hn`!0KLURtLwEuc6tU1|^uW!}FnM1)?q8S+?h>8wO2et{7uZMR1E2 zP7~(dK%E&Az&xpt&W{qzHN%)m}Dd-dScGLx-i&{JB(JNkX$5lc5i zVmp2Fk4-T0gPG&$_N%t^>BB&tM=`p<;Yl7b%!He`^Ao!}7K*}T>#(PTyYg9*yCOJ- zuWua~4Gxrig;I<0%N|2gnTUF51W~i9UlD(Gnwa?lJUyZR_SW63O$Y?#1!5F5Za{e> z^w)P$XJQ`|t3?GqST~h>n?SJ$W1$hB{o3Lu!Fw`3)NpvRzh|lYEgv)DClwN-434KJu|BiL^IHq>5 zNEIu~%|@)CM!cgWr!C?{nGj~qNqZq@=|K*>grIRX;ZueYFa&|u*NeC*EpgRgxpE}QAP;lGS5t~0H_wMU#IEofX_ z=NeaG!rTBUuZS2ZTc9XyaZB(ch0^AP*)n69vm!{t_K32~^t$CzS{!~{#f>SYx-E|k zCxPk^T7QqzkC@2&PwL%UwRXO4on5zeMMHzod9w+~YVM?#IW=t&OVF`fFsxhQ-q%jC8=qt?e7c~vy(eF^!em7`0@FmlqE}f<9{@Y#&x$C8fz}mR$p-?*T0cA9E&|^Zm>k1| zeE4bXKB@Zk0t@@(7A_aEfQ+j~Hftf4YmuBhA^fV>!z$XA?D(cq|Js z6ac3(rcO#IQ-TlANRUSyDY0B4<_UD*wDPowIinU;`(db30i9NK;HFtEQd2w@;cf6R znT3U-zsa5Ca-OCz-j%47;R$pKZS+8H;Y?FnBPd2lOT$-;As&fv;Dsat=@YL7Fjgs; z7X&MZ`?@2dUS>(f#xXrX`tS*S`^K#dWwm+Xb{Kw7V&e2*YCsc0!C*=khY17&RDgMSD3}XQO!-_WLoNlrC=Wd>nsJY#RGzZz(C^N zJ5ho!kvIns55ODI%1ipRLq{Rj;Mt(QV8`gp*<7%E$6W9?L!l_$YXoPc2=9BgY;)_> zxx)AsnWseBVVhW0q?=I-R(L6DMb6epMqq>=-C@+61|v?(TPi1YZ*XOi>hTjGROZrO zR-0zxka{x|1+h>(Zje%ho!F5A7w8mdUj6krl8t+814KgM;dQ`3QhUTlHe%rj8u>)^Wdohbl&GRgxhRA&1|c#?a^! z6|(zHP*`6bCySN7_^5zIM$+HrM7GH2DRs@>0MwL+WI1#q>Vk)xqurI(iiVX%UAwVd zwGtZxxUCQaloj@O~}EzCRdsMuDijU(c0VvEKnXPDZq5sd#X81t3OXzQ%FaNxm8zD%EgQx|fkPf5Ii6 zcd0^V@z9Lf%c#Uh8p^gAgJM@9JR;VkVVvLvN)aA2KkC@1q@t3A&6ODsnyq&?XCNeZ z@_lp4{41UC6QCu#43iwD5h!7kMhmPJN$PAzN1Y>wN>Gzz*qLHTk`$$u|4=Fah6K}- zBk;WUMsq*C@tR8XGCWcD>ovFT?OK;B9fo&({rvc@XF969H`mdyQ{RSVENSa<*52*5 zw1zaNN8@k&-B?>47zTG|-w5TFL~f_c{h-Zz%H7u@Rp|QS_2Gl1o?qQ3Hc_KOP4R92 zlkbf{+eKZERi#*_C{gzS=mGk~=ifzkZREE99i&SX-F7gVTa4mRQd}NiGM$E%$HRcD zh$9x}zf}m-0-v)=pX^EuY>_ONf$NE=MaD%3YzivWrW#{SY`gZ=#ObJN!O;aWg7))% z*)hKlLF(L|%4oL^I`YQDtHhBygPz}v^%5+yw2e`Nzx(&Cxdql!Hsxh=x!;8$*&-ao zgk(X`L*rLY@>^aTBWi35y4fC|ck}}9Jn76XFq~;joneQaQs-2AWHFXvc3c>N5QGN> z8sGT6zxi?I`>_$r!(&dU# z!+Jsa*T)s~^VvhjmG>)TGTpiYCo_7n1(eq)&-3k0N&w5Or_YO7UNr77q(3&gjlIQq z+MxJk6oIW*9kn=eQ`2m{E6c3nb#qKjh={uSiMqPaDJBAW8%>gV9c-t!vL-C) zzdt+LoH?7O5AoJ7!5a*1oat6 zB%ob!=a!MGzpXgsDYf6bNQ)Jrhn%9*{Pd&=V%_%fr1C3e8RG)emXil2MuRTl3HMXI zOgqj^YT{7-rphkBOsX{FwD81rlAAdi#ff@yH$7L+(VeYB7+B^z{k$rwl@fR`kb3a` z9d+}2QuX@LJqNj;gM+1zon<1Ir5(O7!97cg(^7|pF5nvjv&EvwRgZaRBiNq$PU1kd zrlWTGVv0Hi-O#oq`atF_X-mIeB)^rWr17K0W1&r1*xD=xk9)XhJn7&1?Xeo`{D1E} zEJ!2MhWKAk?2l+Y>w9BQNiR7&6F6hrq4gJnV3A`93=k4>9_z9JnD*^|qI0DemGwgq zgfnTrhXBR`9cIh|!xzrN_#$vQJF|s7^QW#-zWfuG0>&~TD zJgSJ!i@lJ&$--v2B`!Q7OTrdt%8Yl(LGn#&R!>qJ18RBWiK8JMRK>8WH9i_6Iqy#7 zluh_lOqkquW#ki~%A50gC=Gu_1)4^ZkDTDL~f0{VSiFozp24J%r3YkN{f2 z`Ind&eaMK6ljgpMF9YLCh3Zf`Q3EH>Y9mlwl;_@W_!F<9}@H|xmtBr$VP zukI#?Su3L@JoP@Qsm)f=Pm=tTNl^Ea}cv z=!54C)TNuY_@?I*(;gvf&DyiwXsV9<86ouMw9u2&d)i ze^Io+ZTHlc%G`X%^mI9Vv^SAI!8RJEh%ws`%;ut2^egv^GYzpoQyxCCQ$Byz<2jFd zJhIQj*~hCHA4fk{G~agIeN;TzeVq1@C#CazJloz&mAlP-anI97-G{q1TIVtSu=Q=K zr`uIulCP)7^hGXjZt}rXrc0y!xUM?BZ9RFcwI7Z=&9_yjZ@0eH?2opF=3MjWu6EDo z$1a{uw&IqN$f0IUhsN11iYWkS+FHc!CmXjs9WHZ3cgwj$al%s*A$uP~0mYs_^vl1% z9tgOlnMrHve2zkR2zzub4KQXHmeoY$Mf>#iwHKP-%P+P+zSG*GSAE3%dd0b^Dxf1< zt~t`2F=2YcbEMO#3P+Uk=8We&<`|E0)SY!tS9I;GZ7uG}bf5f@SH~jV1dTcf+`8>d z-VJqkM!zyox8|{9bzH<~KN_z{RJ1;<(x3Y&Y@c0c@5--&J;i1vDy}E3nXIkjNK2-A zzD?HTv<^>k%W%5L> zKC})<5|x}pe%_vu7Qfe_D9bG+e3fXiL`0UZ^fgtndYHGe5JIT7%xGqN9=Nx43&h7n zzM;nLbrB$16?+WK(W9ai#pKjtdiSvxdaoK=*f#~1ub@(F=OmGUIZ^@_d`>+ zfNu2^%`|iQ$<6ocx>}F*RI`tjc35q#OiN$-=yLCs8TtTe9S`Gv`f!))(q31cQ?`5U zZu)TbzUCeu*UT1ASDcIcI_=6Dmvlb8lhJrxp2S5dc{P=@FKcRDYnE& z)cY@*N@{4uoY5A(JnIs>AVtH}MOQrgpFZexDHsh>%8~3Fi+XN=9IF}tm{Mz0g{17c z>fhOAn2JRrkd{j%5S;EyXZLYG)@K+o>W4nh$x|jxVAV_Pav;%lUNR*O3UJ#uY$rFH4-7f3HCf(_b>x?&sT*uH)(&6Ao+Ux;*N#Yd^`kJ31g6x{s0{TC#I61tM`ULoKIKdo( zLh9(b$hwz}&kVmh*UEF!xoI<(y@@Z(tqC!D!5I!hk-NIHkgJc3nMK57fhq%ISzb z4WQMO5vovg%)XV11F!bV9M`LCN?ZEqL|!_z#l8+pH?nhBd91)8W@T!iB;Tz{vQybn5((Az_9$FqMv&gj)Xt|f*ocs^aAWm6_Ty9TMJF0`cgZrb2zPHwIWD8ZqACH` zq>Ky;#)T~m?m7lVgT=YPFb%dg($J&Zj6AB;itgOD%l-KW-+puw1$=l??y2d}oC?*_ zadJFad@0wt(C&yj?(!lf-AB$?CC0(#H4adW(GZj#+|D{>vW?;0 zTDCqzTh<04Tz2EIyDEdcuc`Mm-Fe1;xo>j42*?%^b;8uc7M*b(cC?`5`jNqE_BlAg zZrm-GIT~7!s{knP>Eu{*ul}}uxT~kd97zg!1towaFBfXP z9qPV?weYx%R*XEL2{cQRaf*%SES?in;-Y#$mKaZ+kP{b z^utIj+cImEa><}k>Lz<%|K+X&_5MJ2Akg|aTnTfmnEfzuyjD0%dRWs}-=88Xh1@GU z^ho!cL))WABITeh*5l1qwsk(SoPJoVcS#jR?7j7>nVma_?$sXc-F@yWo*`PbIh-i> zy6I?9#>3h*kJh@m?-#Rwh5LSU;?&|g^Vr#&`Cd-aVLlA#TG51_nW8c zzv+(MPyBOT7fmOx?LT6F?#tCLwxrwKwlXi)8cv>b|A)?%Nsl~~E z@xj&gZNQ;lMQ4Zwtr64?urtf4ltyh%l{Y{Y<7Wyxa`jnn_;b%OfJ|Fr^7w5X^wr+Hm=j!g`^RPBMdJwfa z@UFGf58DWVc=*YaK0f@M+ux|CJ$CK9zvww@|E8@!*F7H;|Grxe@5#pLY~qmQm)O=eu3mV_ z+uCVAyXc!PzXGG1f=Hd?>7gPI|G)%w{RH5yqk6Oz#ga}!Mz>6k{*P-Rr^V3JL%YFM z$Y#2`d-Y=EScwwbawHNR(wSX#0rRW{iRI6|XzOKj*Zi+HYUE#(<1#Hdo!rFB*6wrT zyX#(aSsVVmpLFem8~*ml*5c=uYUzFK@$u1ZBrFi=I@2P{%ZB~1uMr}X?sFgOCtr~h zDZ36w-q)T=)1x3By2>z3C&fhFT1j#z$60-x#BgutxOK8?DT*R;n8I~jpg>hrB=ZqI+fE35!3P>6|0)JkdxY2;G8qx|s?HJY(et-^eCniK&uC*P4CKo~Mo%odLg z_QF})@-n0&Fk+OF2hceo9md6639HaUdJ6Aac6+-oEz&mh^o;%bM)kv8>L(H(0iOUT zK*7g90iMD9i9`SW$MZlR7zXI()x4V*Rq$95z<&d!|?qrk|Q;#L!e`8nv--#M=jP- znLb7er^oO_cm@Px53}05lTn9g-t>_OoJM$zKZR}wz0@eoIlD;<#MA8<+Tx(>gX*kn z+mQASB21vUL#{ZdkldK)oj%gAPw)E@sSugGHWgqf04OV0eASFR`^~%%0co3;Zod2C z_T-1v+IZdWz(3r}`L^8e>-tpF!+VjUyH&ac|Ho_p{Xgyd{pW5W-?;AkzUzAMmwxM9 zy#Wb#)O4A7SiKz`tJmSD=W<6xsm%#QM_{hqlIWBa#k-`vm(H~{obvL0nmW>jOHOi( zPHrhF)2*q@PV1&5)byFH>%q=09*QR?HKts%YOec{fy%?y_;!qUbGY~-*<`1grtWY| zD|c>!?YkbQxvXT?iR}pLy8$psGt_rNhj-P5R^9`LTY!Wk!WdCzv>}31PywDb8biA9 z-T9?!p__;T!tO>1kveJwgF@C};-2cB@l4K_-!Pv5Ce7!Qo}tMY24yfz<^4 zwdL9LMfk>G0nFeGK2B|$sMv(jf)47j;gzRksO;Y4$EP>w|9v^VuS3_ZN8LM;S~N~1 zZ-HMz|M@lZA4b&u&Brr8EPgtB_NnR3WZj!HUVTn)RGITZ?JiBM>rSiM`;jGIrE_(v zXXK-#DfO6hA+`FdCHKRhOKYe1UTP{+7JBvjQGJXgx8_<%*)7tFuI0yQR6TR=EG~D* z(R1C;XTE-R@&VpuT_x{l-MTy=n z(#VNYrX4q~n=*_YRuIFWw!4KuiaiPnt7puGwkh(k_`^7AU4D4yrItf?OsfF7^mv=! z)ptqm<~ZjEE`9aQ=XNh$b4v)EWP}bg^l2-JJ)!IU6PtXT z4t)4U%|GYc>iif{GA+`O%oM&!6`?R#fxLjGrS0q1OK|v_%DIJn#qK%}b>W^Y?b(lW zt>bp}#A4SGcDNl>zH~kLD4_24F^XgD(Q!~w&pvSLvDL#UfTTIX8r3A0jLMFtSD9|j z=ic-Emh;BEb|4QNH=hqK$Lg^!_KW(ck9$UbsQuHE$VTgur%!9Mv;j7o%+w0U!(K~f z>O&rBOIlgbN{cRfcTe|`E)Hc3V}K@Pa#v29fDLK9+F6_gAwSF0pX9mr?|Qzyk#Bvi zWj{zjcaN2(KR&7@SoN*zS({j{G^VW64UdMAmNKgo-}P{q8jSg@19m-Vnr0;0p(DGD z%vi#3=5UIc+&`9PzFc)vyo|=lk~4w=cqAHt0lE^umKva^M0q8@`hj-gp8e0or9!vf z!J$pN+&MUQS{WoIUVUh~rV1ZpSVAVX~w3Bzv>Z?p!N#YtGxDU}K>@PGXX6PcFpj&3UlI zeRKKXd|0sW3HuC~Oskkw>*HVo1wcwwN)Gs-8qrcVm6a}!mLOr)BCD7OcSDwbmI~&B z_0{9qScQ(hJ|wfdpSzRNy#8lGG(T%S7vOm&H8e`X{$bys)i`_99&j)KZwaUQP#}f4 zvKe^N&~5PE3z|9|Sqf8Q(J;_88PeDMp($(7YvW%(xk>-~9sm3PguVei52`l~JSnZ{L z%+lUHYj&?XyqLpK(Umh(-ILliRX81II8JG{P#+$7fW%(9cF%Q`!gXYVuWsEU^}d;X z?6a3r`%=};Wv8zB5^eku_xoiGTRV? zJ)|Lby3->eu{laplasJYS18SweaxeA)jkJAdzw?a(mpG)E-_2Q0MI=m(f_$VRovuFDaUCqMS{~TFa#1UM#Qn zQp!r-S0ZnQrYgRlfK- zI$KfA%rd!ia63!Kb$BJ2tou20TD$F$_L@w5r**6!4|C3(E!_7_XG+I}ySM0WGF0Kr zk$q;aHd3~E^7Q*b-%GcnU(JkL%wc_oR6o zKu1r{*(zw^wu8m4D+HoJmy=<<7Qy1eV9kOk3|SS^FGqGYyBEsknNhZN zb<)K?>fQnZz`yHxZ`69Ry&E~TpD@fJEO>)VTtB+6cSR%*KtiZmxDU}>)6t;D-mIzX zuJ+{X%yJbe_FOh2@RI}H<_ROUo(vHq}*$?p}dbs2VO*&I9 zv9oVGTxpYs_A=R*wzkGg7kB$u+v%BP%ymVQ8r(oT&JDY`)=i?pX-qi%@^GO*S5pk; zBpHE_nqwptsO%ehjF`Mg#}=Hh1WJ8l69q4eR-gdv4n2!VYU1mrt@L3AnPj3dc%KWh zW-~yw_U60>`_gbhL5M}QSR-l%^~RFi_A_AaLUUo6+tkYvz25BX`JG+Azdg$PqjR?f z6%$yX!P7eUe*fSXudkdNdz_|?q-^|Ur&sB9* zEB85=qq3c7xAud4!nO&6+NWA&Rl&jNYU`=oSg~+Xh>BuS!5lPPn}6g1j+Dp}{H z^ba$DfRLb-SvQ=lPKHP-G105f-4F}oQ2Uf?ua7zVHNEXK6er@<;nyEOL%xxd7o>y#-SxA5rB)ZL ziPZ|YGumXg!3FmRq24aar(_(%c|R1H2=2R&nUpN)nBCspnyx$9Qrc77UR<-JGtAEN zy*&L3D!aV*g*9LIjueMY6NM#(wdc-K7iHK(sO`*5h4?tK(hH!1F3*}{m& z1{2KWLc=n29f0Tg*NNb^uM3Kvq+^(`)6`%RhXPG;|H;A4ZTS9xg*?Py9IW@<2S=#w zR;vN>hA2VGzi-#dxTe|w5a@IN*cV&B_c}PJCl2 zBOtgZ`@3NFU-ylpFWa*g-@Ut=-z|x#AP}CIw6_OaBB5TTV#FXMKfM$a}&Au8hT-^?|khax7tcn6Ep6Ly1J(-RD{g( zoxLa@YB@WIuJ)cx4YcY?w4Lr`EpzNri1N@gHb+Td#&gV?Ryez?W#7|UmMHIQ5NCUY z8(V1{s}I$=%IBfDTQPf%ooqO>*E|(1`dn>QLD|RFJy}=5Sk=IIS0yk!R+OAcG5huT zy4E9YdCIT!b%u~i3hIFutSd4$Guy|_2QO_e#I;L7HMn1@cJ1J{sr1rI_1am}l==D3 znrXA?>7gq?7NG#}te$!NSbnfocfM858FkRg-KLQJyje>6C=yLlWV=1xErN1Q8u(hj zZZ59noU4h3Dz4Hv?Lj-T18O^4a<+6=W}jK857Xp&tWsy0OE$BwEwbP<@-(VUdD-Y0 z!!0lQJa@hjH)<;`wlY&bqR2I|+DEHPjrYyhQ(20gaiqv3>J9cZeXe~CQ zuoa8s=yX?O@4l6eQO8yW?{;N7Eo~^ZTC+;ELyNu+>q%*K>&GKU0PaADq?kK!sC&gV zWwAivA#`e}>KcD~p;J~j5!$n)jHaO4kL$cvjw+u7&(qA_gIQKa?dprnWi&vFL2MP0 zKnLmMVyNtgGpZ6wR~@(hdX8`l$5f_kwB~N;BTT8MMnQU2tcjg)xw1#2%6WMw)!unp zzm2Nt$6guByEe<+b68J%nBih2ld9+TovO0W+=vu;C|{)^QlhFCP3S)L0MYFc6j_Eb ztflw6w6Vg~JRN+rg9$07omNLATU)3)-N2DNh!_AAK+qz{&4`ed0$+w6HALX)kJV5) zRQcE`QX!G%Zay}+ea5+b&OI@wcFXcfwd~rBridX~89D?oB1uggos#(w_m$<-8`bYV z2Y43p<({Y$gn%;1dzP=N9=cn%t3+jTWhSj_iYNE9qqV0eoQ=*k=IBAgA=CpU6IZ6a zYxTrfBFE&ur<?X<)*QAlITjx&28FE+cm1o)#~Cncnt2<>fE_HXT?$U z=qHoDFIJ&m*EP)<&DD}(h7d&dA{ca5n_0rYJf)?^9$NkMa3hyS$YDykAz9j@iUQ6^ zFocF+pFypXgIQ0jY3{xWp?Y&{S)vzhac82mOJf*X*>zl}76bq_pavpA!rvn~oo-wy zZFOmiyexH^YN%T?T9j!JDN51nB;51f&mT`dJs-<59kwjH1X&?N8L&!9v|9 zSW>bfan4S6XCI!_c2+h+(v9=tfdDleUC1DtEoWTo4%Tn4>AW71V?gs145!WE6z67= zKAURq!+~!liMsjV>kopBv5z4Y$vb9Kl_n-j(vuD!`!G%pf74K@7ejjKq+1CX0YI%E z%w?s;<*^6@Bo?HplK!I4)x5ZUZYq@SnMt}g>oYI1m=Y17U?D{tHPoeT(>JUiC}VqS_)FB3CQ$xA29}% z+oPID9;qCNQ;rZJ6Kt2RND13stRvJi*n-MgTD5gMEPF-jr=2>sJReO7CG+)A5wl9& zk&1hwW@9gDDsJg;!-PfX^no-aY7}swUAxYxR}4{&RAYM*qw(kIHt!#4=QpqmP)dLe zu*=PRN5B8jKK+&H*DgG+SH0i>oJ~S5*ReB6FU&$NgXcrAY>$Ga_hd0As;`qOsH>lH znuE1LWFo|Nq!zHNl`R#U(>V1g(;gm|nioet{2yOBka94%y}dUM-u9Y)&7cRDZ zzhnT{PRkOc9NVsZdwUhve6wcvDzK$WDhugl%WE{yOFIxz1U(RF!la!YT9K{@%g3Qz zuD;3j%xu2t-?^4=_X&U-4&-ZYTa4AY^x9|w;4#?bB=)Qaeb?B=v?DmRz{l_9yKi?Z zHjR1xEkb7iOjSj8?>!Q9rAWGdY+YOcp(&}0y$?aMc63PaBig$MVE?XA&ViA|(8kQp*%h;{H!~9;_ z;Zn5q%hY4FfDV#oM5VbELnR$4>f&69F=eV7?vgy&uLV}_ftopv$XqfFE(}H@TE!+G zeCfG&$DN$b#8a3Kvvc!2%Ia>g^C`Vu-nyA1H03r zKuDbZ#Ql-ersXa$^3cAz#&ONzR~t0QNK5p2v@kewD++mumkzE|o?<;5s_lCewvPb^scdH^_3&^_=%_u%k>q%nnsPm# ztA@6)A4dJ_hd`D1y#;H?nAMv}?x?RNx=#8!6MY8!?`!A}M$o-P^NAIq`k__vwGDLuIO;mlfOGvx(wWUY`U4eh>7t*%yN|Gw!1x+0Qu_99LVY5#-ep*uobG%#A#w_50TWDS2+nHvjPp?tkO}Q zRm*h9kv4_ANVR$*ufCX!GSfSkxf}Kthj#5ej68ZI-5Tj3>%6K`rHqem zZL)9am|^?LzVa&SnL}Q;!1v)a;1%>n+KbEx>ENR4T%$KNX5hZzdc2PQ?dGb!l$8_T zn~qz4qI}YQlB%H+k-#L(xNs?`GgM$N&@9m z8CAP`mN^t&h>Q-a?t-@wsqmR~u5Gk=`r?=hwe3W>_0O2^`L?yb)S|4n2tk*ZWUHcM z$^{B;AZ0FN+~6+NNuN{Mj&(&+8nTNWcRG=Km^R8mswZRW*orG9%U6?(_8i%eZKBR@ zA6sg>_LJsNvn5;dt9#pf;@RtouuNn|-RHH{>s1tbcV9a2K7F*$b>s0O_st_-wQgNE zc~_G0$fLbc_R(wdDl_L<=iGCC5g!mZ_}=|IKnt*~_AEtN2lNGX(p8RR!V1uvs0~Br zW&DTV@E|)gz4Q&6c4{P?N(Q|<8;W|b-mQHz@R_p`D+8#yK?D#1piz+H5JZ@vQaVu- zbw?l7qaYppEvvCH%I#Uk21f1`arrb8YiVy($wS9G8-im zu%8Z|ZQ(poL56zC%I|AhDN+<0yUig6sOe@n$i$5{-NzhA*F!w!R=g zBTtP!NHUtYNA#FzT~{PW)Jh~-@=O?U-tH>(AUoR=Ep4x$v@@e=Pi9G;Z5=kqQcY!q zDCRChL2b%xhuTdjJpvRV3`0#h%#m~s8!2v6IjrI%7CK_AEsdWHYiTt5g9W9{u|2#Cw-VnYQvp{f373JAV)+x8fDJjMjj#6J2T#tt$g) z)>cW;H(mC~It|qmZ8b1LEWjuEDDF{=pA}mNaMuB!vr=JD-I_dx=k zt$IS4XszkYsq0>+=I7jYQ``61&?b@ZzsLRI7IkI8y}trSo^v05%6<67k3TKBjwt8- zSR6uVF|)PRQ79>_wS;B{6ZdQZyK|f^C)SeIs3NOeDtCyKCLV0YZG+QTv0Ep&?HWR` z)gFX3=17hhZV%&{I!5i8YrCt1e|Me3;it^`bTh5lw~zYTwF_{u4u;AoZK_Vw*L7PD zR+IacV+Zc$wDoH7hUEu65YM}oo-im}w$~{wjzSq0dfdF~^2d3+kDu->-`>nWegOQg zq*8aFly-UGYj?E&@B#ft@^hVWcEe5)Lc;7Xb)LnSw}04K6J6HYu9GcyLRs|j<5LGo zi&XBJM{CQ;*O_c{N)eDO2H|9bj_0J9R4}tp#hLxOW%;$MNLROT1iQ=Kr&|QF4CTGB zpt)GmO~_Boo$Ess`@{sbtLqsVpj)MAU7QD?jKsn0G}DF=vLzxCLi)xi8&ymlPmtH% zku8?nYPm&N`@S(dH^vRzJO6M_Pxg z?PD|6v3%eft$v(|$sESF&mZ=@`l?I^SOCvH!Vxe37!PS}bvX}9=&g-qC>3toLN5YA zlO_ulzcmy=6Lm@QuW z2P|hZMppD*hJj8*mUv8$T~BXSp_9t1XVx$FF*!jYCAgqE&)6$~cbh$$j&m%gt2fw4|(E#nes7v zol6eGZZ<)YNsh~>h`5=CyLxAZcWGBh&gD}#Fd)?yLCUx5T0eaW6Hvi zcPN(0h`FqD@#Nu3&$UH%Xny=ccq=MOUtPmkmNoy!K+wfec#?LP{y*}N={AT!j)n?3H zIQuHc%2!W6AHsc|pTXOrgbuBUIq}u|dDE`FXn^~un9?FvUL9F7YB4IDBT?Q_U;q$C zFg@4s0NBylAN`-~1d4M55W$M&}a<@B+B{PH!|Xq1?Y z<~bEht2@M9p$~#ohpx4HkLTJ^%F_|@(8<{{rhwRyYAE_>$&EI2q*yI&xiSi+EN(DC zsmo`pU@l8TZ%i{Fez1n^@=rfMI_lOpvPeH>&oqGkxn zOoU{vqmKg&ZLXV&9^S&OSY4-q z#eS@P5Mu2LtsZkRv?!1icjSqeB9LSfV~w^Ek{OjpAl!+SENwT|))m+CIvaVN-IFEU zh+TsOsz-_v#yA*@GiTT1?p?ZR68ow=oVT0SgSs!N7y-=XcBE^Sl4y(Iy~WuT-H*}U zG`$T1D)G6le;Azk&?=Atunef_k>s|m#pUgNDq)x*ztd+N5Oh`*`(dac;hVT0ula3i zitu6}G-j)<{Un!00AKF3^~fP0HB(DVjeGBVTx?H5D62B=h=Dbb954+IALvTHKi-u% zitbpGHLoPv*xpluz;2Rx&?}KB5O=Y5K7dOL`N68w4_;-Yf{3KyQ;M|PaYVT@Bau!A z#ij@Pw6dfz@<3~rL8jz@?RK}LU}-Nm+Hq^4dtD_n&CkD7JO?(}k zOd?z!G52Lm%lH1l%q7`D0FNsbKt^q-TY8Xq8Q(~wat3mhm$AgyD>ge^oFPhfW5(<**`o=dx8lmQ! z&nog2`QjT+t`CZ1rxqV;D21Gqp~)RVx+e~q3DFn{&_S>(IZLCZh>&x#*D)peP%b@5 zm`ooJ_cflW*2JT+o*X(o1DF%HTzkWO>g3grx?(cYJ1!(w*coR=Oc?(9_2m)%ipfGz zr4N#5VW!nxUs!ypm&)G4h zr3`lovV?MCV7E$T3f8&ZD`(OzJ#V{~2yY2+)d5Oq#uAPsN_%_0W8MzF$NE(7{$w^< zUj}Ke9x7Y01h3?Ip@DE(lX((as=*`6VLY2zhGxsb+Rcat&P0Oh;2`Iz)UjJi@7nZT z-p~3tQ9^tFyj3EyPV?UxIxSO=Q7&2r|1ITFYM;~Gf4Zl<<3sMzyN}2~`kdWr$=Pvd zyaR6HzIk>-OTs;?y0ca6wN=?#-QyCeb9GNRb_k8&z#kRnc9gLHN9L16?K2C9yTh z%yBzWSZbgv9K5F8=Bm|qnFGMdx%bDwz%KwJ0XEL|?bxf9@5lP;1_{w=fmL~k6udSu zV+i8p+Szs8oX;*c9d;*yPMHI4o9J1+RUdHNgm2NxnDViNWI!rdQr#K*q#PM-C5rd7 zFeNe0plNRxHKmTdJ25K0x}KLt)M0u0y$-XzgZJ&#?7c|X1B_%ppd$d8_jBEkVOuQCLVfJQYN6VQZ5_ zcXyFqW9JzFkU|64bI5Qll7qpyQ|H(=r4FTtaY_@sVu1@9$#}wzv)PtTB+Bc$0CxGl z$cNWTn64QqNu=qF6yUZtHHVt9Un2|xV8TAm%H+znJMRZ86e$R&ma9d8 zH9Gr9v@NxG>wMsB=o3s?hhWw=&=K^w0ru<7WY*}(>f>5N0R&0*-a@9V^ngo4f#ik; z5g}x?sI;45s7NNoeYL-#zV3XFefi*8C;NeIXWr*uzW{FG<%pzGiZs6(q}vy!L^+m2(TGWuv2} ztj;#-hBNi}(drPRwwz7i-CSO}kM8JEfYeM$7DLA3PTY2q$Zdxv4dFT{Q1Fc^iqDrE z&7F;9g3V`-NS@O}n~?yH%B6YSS*XsVIRO*^q4~SrG~{`}$+C_deRNpH87foTUO^@0D3DZ(>mf;D_dqKC~z|shO$<= zt{Ls_ttb(_gNZFEZe)e`TMt*A~eEDYA2S2q{OE5 zWH;~aF}|MOj@lo1_52I-aLZl{-If6qoUzk0HOi4O&Umh?jC5v-)v?KEMCuB2kXrJC z)7eeV;pWtp7V34|Pjbi%m=Oljlat8al)Xl@)*CBm%s>>vaFKE$coM6q&5;(jb_`xD zR=>~2K1#H1v3CqKVcD4`#=2ClL-r8Iirv}EJ9<|G04|*4DBgkTK?WkR_Bvu*l58`d zDr;S;g{UG`l0L!IW5TjG9v2xW9GadS!j%rmPN>>5e(NpCp6zFI|YWF@;_&R=a;{NE~cADzpn50SQZqw>!C;BAF=sPqTGXzJpnPXE< z9c~a@OZ(B-m6HtPLd9{l0pusr`xz>deWb7~w1{reLoJdBd#6o#SCe9Hj?LJFTPCVuJCOr$82G4= zM2Z;bgXHKbRMx-bTR;A#{CZZGYT?4tb!nkC@Agb#9EMhb-EIxn!>`7khC{C$J+}|U z>b;v}D+=gF+Q#7npjyq`j0S1i!BdHh$$`zRkfYf>&29l01S@R^t+aa>RC;pn8{YGE z`~5M03i=hk`^E2o{EDr;J_R~tQ<-3r5W|4cF`j4Ig|UUrN+X@m*?p=QpOx9909e! zl_ecnY2&O-2a9Ug*&hCkuIEO-+4k}bWwy{s37|lmN+=IYu%}VkIT5QMfTH2V>+GKA zn*n#L4rwCu^rXaebTdbBB##;|cgTZ+o7Y?!x}`t^Z+8y}(6eXzBlvxc(i5lx9`SXQ z5Vga+p2ggL&_TI1fun5!HY$qTkyrB3m8}!uP{&CHn=-*$S*=I}JCHs&VxkUOr{``r z^$^+~*_J{r0oql@TfMEIJ(3k4rxa!kJ828fi(>>wVI$>N-M`mgt1M)%x&GV&4C&q`KgQ|CC*b`igN(?E8{A|mE>ZjA9_F5HdtAW^U9zDR$c^3^xn z7ho=tQivZ`TH{9`ypbrNo2%#?rx3qs{&?^E*+XNn)o2M-Z2=-hzosiqTA+*<$u7Fq`x+NVU`H-oBl)EaBY{QuGZSQIDr$ z#uiF0GNj$9q22_m8>RQ@PW3agS6n-P~%V!_(7o zSd`W-$*ncPImCZGsHxRz0xgJ=Lx3Pd| z-IftywhuX7Gf16Ve_tpqG-s%EUvxYjapd~aa-RoJ|3 zu}4!$>&11zo+TwX%OYdXS$kh`&qOAdL&7N_$kSXrKQ0E&nM%0&bW2>$*wOnui?voL zu{$h%1jPaIs`#v0pR|&acNqZ~HZeo;?q@q@@2>0CDE+vZHtcpG)zTU6or$^=9m+&< z(xOKZ(gjlNqfDeW6b&9vxCYnM*@yQVTH$F2G4o!tzU%GetEc+&%iw`<)V-B`4Ro=* z)D9Y2@ZNscpPrI;K9!#?csAy&5wQdSL13~{a~->nVo0yYJ)Y9JJ=UhWW=TZq2;uOS zcQcz>mm&r?A;GOXFUli=xOSh#d4u>f-<%)(gQ z3pF7L#7;#m968#!Ho#F^fnZ73VX_%GcJfMj9DF=b2}Qu=i0-A`T|N5)6;aRBlRd4K z)kgI0^isV`@E$Qkr7suL?Tn(ppm-)@bx$9oJ2=Q4fi|_vHF~)IcUp|Hpl_-gy?S}+ z?EmrNFnsNLzy9yo_s5=THRc=?bUlp@H>E#$yna)k{k$K)!0r2(5$;na7_bfmW1Z!PKp!Tk)8RFw_`ww4Le!BVd+Xj8@uUE^-vpezc zKa{?4`n(sIL$vW5`K%MvLS2{rI+5*{f=+?k{AQjs3+N_TnS+#MP$Qy|~+rl}ApU`sfQ+ zze;Q`)Fj4furXzU7;7JQ4;Qs)lJ#5|4v9;5=;Y|D_MtpLInN8qZ?@}-gV}w+(jbq3 z683ll6)}vOc*%W&$Z+P;)$#G?J{S9W>Qvs$Bi?+1;f~}JuUg~m&{HMAo;vFd@Ta2>i1HLhcg`jk_IbY06Q`caCu$_NX2w1Y{pbsi zKGlvKxrs-@8V1@pBphLxvsu1rfTf1sDPM&wW>VH-@a^oYu%Z;mH{BZTf!n>(NrD2x zeI7v|xBx-|I1_2lHQim?6WbFuz(@|wlCxxQoK9?-@?D(4%J>9^W=?>S-WZ9!_pqng z>2lwd(Y1RixHK3b*dRl8lCwL#DoSej%(+HZj5Pa-nGxBC4?DDHq|SG0a=mMbUYFhd z{ABENG9iuliy9&8An_`cFYV>)E0cXA<2juE{+i#9fz^iOkCjuj?jV~yRaucKjX3E> z8nOi#v9&w9kH=MAb09|L*~I(UZS9trqi-6|BMf=cSd-x?^x|^%m=-`yar5qvGCoFH zw}y|M*oi)bPB}bn3&_?CJ@GW?L&9R^sv8FRP%UeAohq|It zz-gtA?E?2I&&^}R)LJoB^p`YyKHkXvt5Lrbc;~#tsp}}$lDMqI^MJosaK3uYuRrh& zWj$gVuK)htf4J)Fu&Tc?U8FQNxWnbvL3p?juJU+yDY6OYB_+apk|$ez<)D}JIIVSc zWr!>`&;U>FGK~zuJq+$CKQZo_LHFZ;dpO+VaYZ1Cjv_k5balkV-Vn+`2zn?o+AJ<+ zIO;6yoxAt%B7=QbnM1!Q^ho5gZ?Z>?2n+be>c>-E=Ns9YGXR3=X&7 z8lrbuSFnPPyS(q`ac-ebmpKLt7-6~lrnt!fMdEdRN<0fu^-=V8XZL3ph7J+~(ID&T zyMoO6+)3*x(I*-E*C)OI;5GASf~w7$;fYy%_(Kx~ARqEebw}41_&5U;AaKmRUO-kj z2J9T?!+lDfQL8>`Ja}#Oii|PRAcw58MYw>176D8>r||w$Vva_)yGL;4%I>BB{Y>=T z6FV_n0I3~}yc1;@hMt_BI6YV@SgWPM+6fZ}j@}PnsR8#XfD!N8r!r{^-#FE%`(7rG z@wuhn*Y;(_l;aFIfS^P?*8-ea-_-Vz-|bsi?Z_Yxj%%IPK*@sZ`5mbAONR~_;`QmZJhJ_i=t6#@6Y%N~BBHBsiGLlZ}h#8yAO zX@;)pYtAVIN>R2xuzS?nA0RBp-Okyl?u<}`+pGanQL&!0)7cx?`grD%p}YE>gy*;z zKf(;u4z)$!JRLDM%15T)*Z=(`fze?J=^@2ChMn{*@aRE82%^eyElI;|f^-ldVc-sS z=Sj5aYFlgy9NAFp?!Gvb-K{I!eMmPKMDG5cE-_JO6{EW8o-WSC{=pNIN_406zPql6 z9*={wQMNl0wS~Kurxi_Yv575akt(mDxHa)f{T`PE4b&`^lbV~PK_a?zZB`T{BesmZ zNV7^F0m{l*Y*UqV(ubym(4rxNbPMV5{=NwNP)b~k#>dpCSnX>2WIW-!In(&$-1v7*u5XhyMU+^Yk+Am;-PkGKdZKMR-KAyG*-p!XiUXH7~6q_?3~ zBPFcG>NAJ>Tx210M|23AJiAOhvf3}NJ-T~x4FJhTTUOk4A5CuIe)-UuX66>5{kgPw zJ@T$g`;S}fSMujtdfWf})7~7P{(e9H|NHve8(%eQ1<#_V^Ryk;a(d6X$8AL=G`(8S zpXH2JS5Y0mD%@MRmUO2}Nvz$ZA#q503e{80Nts4eV#)RWdj%5sghk2?10Ch)xx`FJ zF^qX&;f_O~^L5_8|JJrI_m59|p!*SCH=p@fh~;j<=Th&| z<3T_2u}f}c9yS>|unYy5)4_JTGe@sogm&1AEpWj$j_l){`Chv)o1NgrnN3v6bO{*i z07aH&Q4<*L{z>g2r`^BRBZfAXr(rCDd$I;Y3C++$i(*$)oNb`<>5S&D*dQ0l!i*q- zXhCi)4Br48T)Pqb6zZmF!=8{sJpkAg2SRF->I#Uiu0_8N5`%anpRXKVIE-#KaviSocG=^djE()(Q#7` zL!q^fDAgfUw3F*<4R-r5oHe@T+IKDg^DNyh+mzNViIoLx**>4L@!Xzt#+mN)99sN# zy6U@2YS550wS_iltpSRp=aa7|N83-&c)$0eqtws8F2=YJfYLmP6F1{^vyS$_O3b=PiGJDda#mz&UJQIx@g z7+~%Gtv(_^HpDJnfQ;9aCT7$@NFcur}opo-KXns^~Fv-Hi^6# zIU~!J65yzhk|G(U6M-^Z=PeDhGSn&bh1=az!_T)9o=fnA)V4?=I6(t&HPL!!Kl}Gj zvR)|OJWW~QP{VQJ4)OrHG7KQXYJI3NRumb_gSO6Ii(@F;Iego@uj}d4ezu-(-|*Ri zJ^Q-7aqFi~y?6fq_tbwrzgpkl?8|Tc=lf5%es}Y`*WU5uf-S#Z8sSNq>}%zC%I)5D8-k1qGhqA}sq{=u@q$X{Jk-v{2D9b9w^SD23Os4axil#ThxuNtx{(d~r`$r9Y0_qQOp(-DjF+3mfU!)Dv`A9IV>e|+Nazy6f@^Jm(> zzw`aa#!npH4>t4r$G$$eReg9ye{f+%QPhPXI~k)%8`0$~FfRpe^gL!;BP(lnlt|~? z)>c4GwKU&RSc|a9iFxmVN0i7|&b_ipPFFua+fgqKA5+1KNH5`co9MMaG|%qr+6KhP zf{y1nTu%q95$aNpju63xJJ*w+d|m50r!{iq@tvtdC+?wMl=P27-yCe10u|$Gk*RB8~PwunQHLZ-P_Vk;>BB? zu;<fvYZmTp7%bgI?92!j7>$I*mQcGEHw7Pp|Qww)mCY>Sx2c-HyPHg2D8uE!!Fh%sU7?@hMh?oW0euhDae%tm&JxX!t{R4r#OvB6Rd1I+>+MR4h zRTB0-Hoo5{{joD|n&*lw^YHou-nOsn!mE$}%jdiK{s_8nOVkN>OA>9BRN_7!)9(I_ zw{kx_vF)QQ)>3_?wHs1IZEe>(?RDZA_bGLB*hA{*^eQ)H7f;vwPx$0;j=d-6kI((1 zx%43Cel&}eGESGIPnjozMhhJ$)h8`_vs7!0U}FqDXp0M4nSs2XC^5$2J?kJq z4H=P^%#V15r+a0-HiUp4owR=B%2Sq}@p|g(wfomwmlldA+up~#&CiWzY;%vjwi*k8 z)$M>IBI$XNl9Dvf$f>#Q*kT&_CVhNC*8II}C*Og0c?_w8lc8`$mfXsA8Yf#=Q3ZUp{%+lQ&fq+tvZrlQx5%Aj zq^Hc8DUiZZ<@RgaT!H7&hW==ot9zVt8Gw`;(fi|ul$|IYx#~nRO(R{mxU%Gq%p+nX zaQH^N8=moD|G)a0^*HVQ`)BaimM~osI78S@V%0m!48Y^ae;juHS03=akA|=RmF!Q! zV8(FfVBXrR=0Ui$j?y{awKUa}v1*S=gs0!>IknnWUpM_WatPU~k8E%Tgf0d(-YH)V zdyQB>_Q$^WXTy0QDP*8o5R4R%Gzs(kHfL3rr<+%UDKqqpTW5HX6!n5@1n)E=`U&F+ z`s$?9$kM@jyiGYGC`_$sbwR+lON)F|nI;7Ry1-E*Bwit0x^H{6%Z$zoVZ;BQwdub< zf3HOENE&1agtg?OT@GaE3|bO?1ap$d-|5yaEu_FG!bnIGDA#3c8zLe50%w$1#iFCJ zM$b>%G)Q}OoMg$@q(%LMD^(#RdF;xsN+R@73nkHmy>eyDH@{UNx}!mq8riK3_hZtX zJtH9jD-QQL3x}wVHnlw;m;e3$j_Y5-zb(KZbs{uLRo07lC*|~Wky*$ZrQUD#LoMEM zTKWxIS`P!^Su(&OB7MynXV+u2DHoP$)5nY`YJKFicet=iJZgJptB2#Z^q7t8jMf2@ z=ky2i_?Yo*vumA`wr{M}43JdMn#owPR43d0h$l*c=DJWjp3Zm#U4SPTCvu%SsA`G4 z-aW1G?R2wT_X@Hj#;K1Xv%t=)(e!lMa=>d)6Oj-KdIU+Lc#^^Q6-nw@{ZwXp*%PB- z8P^3$$uk7el#-pzccoMBJ&*VPo9heMe4fD&xFD2|9rYfM&h2WfnF}r7*>jwE08KPB z9o12x=|aykv0zXR7itwi|8&`X6e^MzhKes-QfLe379Njw3f7fKflxii7GYg0o{2lE z8D-GM%Cf>~CC!W3f$rA-@ITw@J-kL}1?qVTK{U!!3Aru^(inW(U}fVoonh)t&-cCl z(Vfdst5r6dG#akVtX}C&qSaBlpQEo^RTxU2q$W_x2fK2E2k@;Ve?NWzoqZf8)-4o6 zZzB&M(bcNJDRn;(tI?4dhUhhL8q4K!dGqA;Mmocq-OLs^xpR*&kl5jpJNA+NKrD&w zcLmbwDYi_lENO{g$fGy85;H{GJd;sZYd9EVQ%dqAM+b;zETYOWv{QEZAYyYV@IIaP z<9ahC>BYPx(G0zR@xbPighkTT^xAwOuRl%s_MIl{o2YZpqSjboK0QUx%4A>K21<8D zgIifz0co;QDI3-ir&~gQHd2{?;=9d4&6m{fG-||_tYA`_**mN|-?Cdj^IWGWEg%4i zEr(0HBsPy%M_H$*_j-J+!&gp0A&Wqn#I3RP@Bd}!9)bALzykzC9V!ZHget?DOKDzn zHPpZH)W>z(2ZG*>BuluQy3X^i6>&}}b_^WHaJNvv2Gs5y88HbR=jm(vskpDMyMmt6YN5jr)(#LdHMMlD5V6l+aK9vswkU^=W86zc_!KB_2j;5@m63w&r z=5MoiY%USKK=Z|9UT=XSgq>wrWd2pBAA(Vm=a;f@rg zT3BsITMN@2ZeFUT8|IHQBw}-Kc6VQB$qQR*Z~BDJ}j<%m3=1r(PvXXGxonkE}^% zmAU{;qF&epE}(rgwH$IJx5Zm5H2~-x2td?2=cz8H@rt(z6TEk~olb-iU`p;mORCn4 zc=B`|Is@-Un{un+gxkfgkLIH*w=Qz5WP5pL#9*%K7d?y-mm^JhT3;XZLq-@e3?C*z z!1UDeTdv#LC0c%V)w7b!%`-$3)@o2f2tr`9D@t5m4;nWoog$NL<2JP!>HKnbu&(hRB{FMOPxXUev{pPPHE?MWbs zNCH3vRoqdAYi`IV$TN2r16Eg;Mj=h2C1gF)=>hJY>CT@Tq-@Oam^SmV*~c&I7T%A_ z02j)+uXp#{-dw1hk23W5g>Rh)dY;-~BRC9fkoTalW_kp}Zfit!9fNzff6^nT%A)4z zgO7~qe(z1c{`XAX4g2dd(%<(WNjZE7qI+Ezxf67(A+p5P9ZQXU8Ljw#E&p;~v4+Ez z0Xm108q*rrK>MJ5tm}=hh%L3`+=sAxOH7?Dz2P!yP9a8MWMr1o1G{> zb^Cs-@v-V;XdVQc#hr**3@5t0`cQsjUdux}nx!ARU>tG9nO#DpV zJ$rzTldN$!QyrutIO5SBYjOE8tS)mrw@1cWOY<1g4SS-lYj#~_c23`p&+BqpE9vhuggWUZkL|xTQ^ZoKT(j;#VKX-}eG2xzF!K(Z>tDPhVG-7c2t^$${*K86V>XgjivFCobVrpVV*)xxTUf_>!CT zXS#iUebRM3!!OrkK3@;}{RJdI8&E(OQ=(nypE;Y_?ag5X=DBqKcJG*n69U}o_a!@9 z$KmQZx)(lk%y@KH`=jf<_WsSGd)AiL;%|>v_IILY!RL9PF^@Ny>c{~OBrb-B&D+n= z?>Y{x7vZM09?ONW36yu{onsR)$96p+2NKjr0 z3Ar2wF)xb|kgH9|%O}?k9oj!8ym0nL{#yB*p#_^3W;R3Hht}5gsIt$`N@)6VU3Y7u zqidWV8DZ3$yO_i2{q(Gl7@B1ips%5R%h?=vsA;%dHhCV0n;zcR_MN&mvAiY&3+Mt) z6DX?H)?`0|1}WL<9DVF-);VQUP{;(L!RR|kJDp9`J>CqKbQA}a;F<2omAx95>M8r0 zcV8Vr?+^bxkN5F$leNf0OX_-|mS4a`*V9{^S511_#EBL?-Qb>k$`AmPU4)-pxm{9? z%*@T_sv3vfl2_+*OMi1VWGCX@>ykE+pf&nPrqZv{K4d;MdN|t5W^pz7DLK-8I9HCR zdoJDXaUy&OPQheXw}*2?+BId;8MHp_=J(Xk5aXz%84bobr;+*LUbDV`v>Aied*9R7H4!AfKppk%MWc+^?p+;@`+m6D(}9@7t*MapUmsk zS?AD#-5IsZR7_RY%W>>Ej;%JI=TY4m_fYpDm;wMPE3vqsHIlZ$l$JW|@pM$<)in&o zhCzr?FSyla_<5Gs9pvT@Fu=H)GoEgP=I{Z?%^yYn4u1Yb5^Q+ z3W@J|Uv+MA>|3{H%9jT%99+x+(2`SY9dfmq!P}4>l$)?NOm@&)C5F_{Q443B5tucK zMPVh0-2euYNGlLMb*^a6jlKcqe9X|Ru`X})IVCDs5D@{9j-b6pvNj3bI*vW*PB8{pL@Puj64r^WWVHC> zJlr$0{^4dnO6Un~Q?-B6@+x&vUrrNoi`VT_u9x517U&I=>QX2x9ctoz?DFY$q{$sf z7^6U#B^KS(kDkhVZXK`(|E#)O^Ic!G_mpU;gn9DNt3|d&6LNB82G*NLHjmAr_c6kw zxtLDnqu{$CezyDe8 zi#eXZW7N#{(l&`|OL#D$(Pp`E&=b8X>I@Hz{lcqG*T~dgsc# zqS6q~Hcpw|gwbwNl3v&uFS`Coll|M}+_;u@+g$F6r5|X9&UQ%M^jw;!$CezmON6ox zW5E62`aroBxu$}{+NExo2|*I1Eyg|GmO$y9`bLueCV8;1JT(vxT>!~QBzV`yAJ&&Y zJZJ}YSl0T*3sSm+L86?*z1OabNZx+PI= zH$d{PfAVLkC2xyvdK)K#5zL+s3+z$%8PTrdjrbS^Rs8pz40fQ3|H?=&7QK(K|Si_<9?eO7RRgS zA8Rjq#mV;Q?GLXl58v}~{^QLb|MMStQ(%bfwBjBdYoA9|nFOqmz!2<{nc=xd7PxGS zw!xN)V20=Mz1}Q;NQRcgfQEg=T5w37{pAEhNC_p+e*4K@+!#rwgE$)oa?P&~F02Hx zu6upV9KF3arm2mTP0d@XJkHp!a!>vB*iZk@H`aY_H~}aE z40`p?@{aiBFEsZ)pUUgn@+v+CmEj0Yh+L*|l;W;_EM{fO+gRWRW9P+70n>7NN1Opq9L}ENMlJv zkg_Oc2rX-r+VKY;3rbY<@ZOZxn?D%PmSWFbE8o^UkMOXB1q6o&OvRm@#5z0Ifiz{8 zOyV3x<;=r9jhcOJxXJq_ggTw+DBetvu&W1EDPlB1p^RHD&7{Wk^eqaKB?n<(j8ewq z!Z4hERKyH{F%7R(rwOx)sw&nqf#fJH2kfEST@(Wk_Ji17FN9~!iNpJ=wtDXS;kqAG zTQn6+>e*-Zt!I~g_(=GW?$OD~uFaxF?R>&AYHzI@=%;senhzUYQ8Sj6T2k3%^RgKT z#~YM%Afd%kPb-MC9qdGsP;L361{k#`i#Ms1S3gIbX zzxj&nMiG`oDe~pXittn&4Qgkd>a?6V%8t9VcX!y5N%>&ppqUnjZieafdh&yYbD8z| zc&?u>KiIjvGaoK!W@hWq_bu$Ws8QbTFTddD|G$KP{%84p9@twm1xJre%5q=_?>O>E zAW80r2U`w}vxJQl5gDUM1-BU=XvP`00P4t1BGFbd!-f&Hl_SX^jhS)ybEfc6cFmmi zj@mTg^l;K!OCU|q-g901SPoeyUGl>P3GFyfSM6b^mDVGqu9-GY=v8(Y(Adj|A#O?Q zVjnCALlO~C2&^g4-9hqfC4jklg#5O1)q&h%v*HS4vyZ*KSwkn^_WHV5=l}sAOMt*h z8l^w@&dw4`mu)4x4Rma-ur;)+rFQRD6w(qPOT9k~wW3@|8$N@KlCby&b>c^b< znfCw75AT1ug;&ewH4n6l9J=tt(7Wl6%>CG#pNnnYBKBe#bU>ySM0+G9sz)4wTud)- zdEz3aHggS|avF0O+Oeb)7s*<4ux%TRip{Mw-7=H!PutP1KAGks*HD~W5hH=!4k1cm zcnzP)$n-?e$8o#R=btXR4bTuN?e;RI&)7XrA$p@HGM%#k*UPU-N{-{79xm_;9O*Cd0ZD$5?NS=H2#wo7;Ns=Gc+>L@p z#@qbu{6Coa|0K9tb|?O&|LgpP&AO)H>7$+9J-fNv-g8g7!otNcHW7&kO4acsvRxw$ z8aZyUowOMf0^QkKJ8qKe@?xqmuR)8A3Ma+{myRh;EgYnBk|SADC7kW@xsiR0sDlFJ z5=$9csc&gf!V^W(R(fY^?=$!5!22b1bVI8)un&5i72ycTsnt5}UZ(?Ala5ex9mXq- z)R5Oo1ay!|HpJpv;iBzJXUX2|X* ze%{(@fN;ba_C`hob^6If+wLCTdb2-x^BKM0SW2Pmoy|nwS-s*-zpL#!aTijpoEMkR zE{y=yvcsHonz)U$Gohn%+zf!wN^6TtET-WYh%0?y9Y>|VE+hGDR7WLLz5xr{OT^Kk z3C<19M;ESiQkF9T6XjUy?Tt<6bM6Ptom`4HZ}v*_wzOp7yV=v+1&)=kJD8-cS${A!!u?$`0z| zv|J6{Z^rMd`)yK`h8g63_=`RGnk3;B+YhT#dme91n|hdJ)I+kHpfg@%B7=(a6I z^}ez$tC{&|IHwL@dRA&^D*}+Op(1(S{Mz$&dqO&zo~T*0GBaYPw;Y7MK9Hg3{Tf3uGvlA36iS z4U*_8h4Fv*UtjI*goBclh67H3%ejV4g`ixAu@Mo5tc~0i+q1kzTKHl0$!ou{z5m(8 zKR$W8rYh5;qh>=!k?84#$DloDZOMmU6}*!fgA+ra^%3S)YbDTp^5`hq?+P>lS|S2TQ`eo zF$k0%Z6~9QJBUs+Zv*aElJ@lzhD3w0tn!(ZYB(ecsr3!IC%~XXjqFO8DNB){Y(sW|-8=be0CvlS!*9tm}HrIyJJ^=pJ!#@+G0{_&&~&2y`S! zt#s{{UR=M^z8u|*R^{jfdt!fyB7pJbLGQ|lL`XCU62V#Vq$7}ojx?%-)SQ{>cYQGq zgKzn+!|*{1W6dVKZ+W$9a5hj<3=-*a$?x;F`?m7rGE9_VKPPcnb#&GQ6E|w4pcicl z?jtpm)5>TaWp|b|9$`msN50Lx*^Ta%Q(zest%-y|v(nT+B7+9FLE2X&$7#D~iXNp* z%Mgk!=cRSOrC#XONB;ypL0-#UHcxvQ!BdsGu{&9AYA^PU^kr@O8k{q#j_hDrvZocv zlNssusNNj}N-f^_9KwV9*(%J-s5Z79X5?6_p6)v!->B@!0U6%1MRND)82AKRWRN7N zdDs^E_^Hw}OFBEFLY~ntf*BNKK1d~z0-Y9z!#yp}1e}lwR{SlEG8ov%=CtN<>_8Ic zxw#8hKi(F&KR)Gk@5e06C@HE84$ed);clY05-+Y@PcEqq8Gm+I=kgND5Q3uVHG1o7 zUlmQFDa|C2(rc;l40Hi*K9G8fdC{a~s9o-r;MG(E$cNQe= ziABmZgrU1O2TzZznakeGkw;m`ft1ut}Jz?JlgAEPZvph8*?P%1+~IeK6@wNxl>` z7q0C~x&LNxECge^mF*eT^jPXd_5|~KV>)jVIiO<`F$t1rRG?gW2Baj0qZ4CM5Ql9= ziiH}HFePO%tu*NTFBHh!y=Je6{jZOX>mOz54RA&i*sJ&R+di-M=vU!gQeG4iAN$*M zdKOcz4T?IE?UgvktU5HDN1`!V=~LEzsHmf6ri%h;7LBH9MpNBso$ATZ!x-Mpxa%3ps_+#DwGqdpj-Z+*3~(ab}&nqS>pWe(9L&cvl!uyEZuxyNvtC4 zqjN;7!X~vFqDKz2GNiwd=-#sjQpc>^AG(j$aeZ_LxC(gSCS~RWW|SlZzKd_-HPp~C zB^SDpxB38&TT%zrYv20XGx_+~gAYA)aH$=8Qi!C*=Kfl)yXWh^#X7a1H?6N|G_i*KqBktxFx6w(VKZe?-HQ3 zBa?1PnlP0rB~3IgU`j*i_d^1)7TG9Z1%hPJATUpw!xV{dB8_a5k+HHww?=7MBOFw< z1eF@$D%(BR^X~n6yZ1*#zm|IYBM@e77I4a{5W>dDT8A46P`+vx?JR;?_dm`7)4;cYd<0#_DAp!ZZG(}2p1}(G8!lF9@p!Z&T zaq#RGloqLg?%C*P1&g2#9W75C!H9cH#JMiIZo4H~OnISngvaKSyb;fQzWUtFQD#Yo zyc^L{$|?!rch#NiHZl0E=n6xs&7?S=-n*x!)z5h!v{lOCtC6hHP*Zv$yzNNRtjU;C zIOC_^*|F2gmYGpgWJm)LYFCa(b!zM`PnAUX7A+}kXJ@9vsirvX-d`0wiAy)N$G9GD z;Qj^h+1oxh;a;LBYkwiq1vE+QCB72o&+Pd8zKPb}ufEIzBzjbi#ng6RE171dC{6aA zL9qJx0Vpas4pZ0lk!o>}Qr~sY{s7&#qQ~RCZ}E}1*?owVA$KNLBeQEieJCV7fMB}( zMUy5j>WC5YHZP~bL(sDrX3sU({A4fxBq#(0)WMv`gXM)b6+22|C91H|0%b`)nJ^!^ zud_A-Bewd&jO|I?&8Tk~1*nA!Hk9Ls9+NjM>1Zcz{C2m7HA$vTIqKL2dS6<~dF{Od zqEe%vS;{zAAxP}9Ro&zI8VAc_VjD9^SzE;d7#$Y?(Hm(Bx6RO=A~2egB~Nn>VA1;( z{uwiE9BiNAxomB}&OW~Y-mFN}%YpF&04Kr&P(cTn8_9oSxAP|sua}udeudt82s$Y3 zb=)yUT9Jmzvge`NUXLLio^;+hbZ;zU(8lSIyqm(>h)>@H?Cd#WB##!_>K`+Ek)(wB&MLH zPK<-p89BhhJ~>rm=wSyFQQQsDeQ)9Qch)G$gHf|92xnx1y?eF%W^}ITh+}wGGJz&- zK^>P;gW5?O1;kvZiCOy0CLRgU0fDGWO{B;k67DO=*dJ&#<8F79WCvmqy}r9eTOvXm z0&2BISu|N!Z8~AttQ$UHdC@1B)ypRRIq({~fOrW|K)28ix}?&Vc&{HZp!2Up+M})Q z%NVtBrz2jy&ThpW0aK4L(h`P38MM>d%v8s;Y}xpxm^=<8L7-$iqFSp6;tg z_1It~3fhU(GQC=fMNQ$RooB=tjb^pNxxHBHdh>?`8`ykcM=*>in1g2Cr4H3dWs~Qm zo)adR6Hm78XLBJCk-|(HmI1V}BEfN7)}Wfzv#woH+<8p5T;}o^z;7W*1}0naj^ZSK zMTk~sL}aPskw)1*ONBZz3>u7;01jG*C_-W*l~eaH_48`j*Bhea&kH@TDJ4pz4n!ki z1id=DKHSCmgPElywkg%equq~dvrip5b$u3a0DpI!Uwns=;U@hDumwKTad>~ z*S)tsx{|Pa!kROptDI(e@#*1o?*d)D=ZL< zzx{P!b|m)Y`Pyc6-yx$A4qw zqN-Y=mn;X*g7))+PgX%2?-;;(KId%+q^R_>U#fAcJ;|zNlG8{e&>*vujO&Hrsb}5VKwZv zZF~FbrEFj&f~|bo<@QC7eS03S-B00QZeQBoT)lKKRu>OfL@;VuLsp%C zE_#+gNESNeC4I`A+XvS=uF! zTb_d{$aF06dOJjwGuPhl){y{4OeLnB?xv|Bd+n?>L$;G4O2^FwQ(n33enT@1_3`>R zeeYzC>j}O;d#2~cOG8JA;eiM@2i7~crE1$d7t!b-8442Sf znva;fTi%`!jmnfynuT&~w$hMF4jC}aJrpFQXb9&BUs`uBtF-stC|Vdn5`Opbn$Fsg zqJn(v=z-{KYl}L?a5;gnkhd2dZ?#M$!Mh~UQOC_Lo48;yL^NC!ZFsqk5do#1=mS;& z1Qo0%y(sLJ_#EM&GEKC+-!8@=qMi+%%=Hyai{NZ9{T*D(fww#`nbsg5Rt_3 z=jEy9ox|y?o^vzZs`aS9(RUIJ!ic#^CK`|dMC5UsrV-sERGPX?kxr4B*2S_?eJJC# zkIR!f<>sD#l2k^4)&?;FBxKVY@!T?)a+f|Hh!(R!*t@H>(`|uR;M|8(m0}RF0tA#i zpymnD;M8*u-+CT(^YjFfF1URGQl$-Lo{8O zO7h>bn7SX1SJEu;ii8MY90e0G(Q|_b@345sl~3{oUT}{l_mrnz$4&YL*`4vkh+U5t zj+UENJd4vE$orX@VIiZ}apap%JDtd;G?qpPdUYQyI&P_BqRkoQ%P90JIrL8<8y=Rk z-(P)^!Rws$$Y!FJ;+akJa~0-!euh9}aiw_i4z6UNjg#IIXSKrGcxO#ZXKtC;K_4cF zmgzO67X3K0QR^sY+i`bxuZP=IGLbbKY?mIOwaHMHHB31XNC!2UOw`grN5^mgK+|V0 z+4miOvEo-KSwVu^;huu?Dgs>`pe?u6YFVPA%{2pLad(gys1kB@hikfx3tyJ1Ee{3V ziHJI4)58#m1&k>Z}B{- zv}A~Q=t@uM)Eic5BqasaCE0nWCdjZWjo4~K8`T+Xt`KYY@xWz4d0Mlc7=3@>DZIWG z_=ZciaoG%!0z$3R&qk3w2$Z*yjQ84391)pckoR0gv!SeQ24%@dgjF<2LiO5J)@2`a zo@FfQm6j$h01-&Npb3TE&#{ozBcvG?=k-{hFUK)t+9BV`wd6dm*4omg8dtUq2NO@S zhY^|X=~NE3y0#$k6f5l3j$Z!7=ScSx41IK1DDci#hq9T2pf@ZLBzVT(NdGoOeDd7^ z*}T{evgXMPbSzxT8d>Sqk_lHpL2tWZq`JC|PNThR9&%pWdXi&bOSN8&h&m&DHVjdt z-hbM5x2917+O4?;uhF(U-8avwG{+K*WV)O`xq*JTOelzqEAXCU15OW=Jl!2pAOxW) zUfg{{`=P(OWi57J>2d5ot_$3o#sFM09~S1qbM3>mHuvtWbC1b9?@cv105YlAmg$h8 zqE{HzJgGh^*6Vre1-+e>o~Gz8Hwu*gKoz6g1<$de4kOMK@Q@?qyfD?h?tMRB?8~y} z{PEI;42D=6@9S+pC%|u`s@#XQ6GHm{jc%*Ti?lBAH4q-#E;!? zKh{3_Z$HS%D0unaSqQ15A-%HU@F+>GY0D#1>fR#RgInEY3k2>_iBKe2BL;Zu`2aY4?g&7w&9xuKZq$mN9|YT)WG|@Y%3e zd!H-y6KI?7Kq#ZZ)kGCrok&7KUF>~yh(35-+n>@a^9sPt^mNU~F;Q=G$ z=z^;u1SvE#xo2N9(TkFCYk1|)IZ2#>)X+xcx7^zwy!O{A@D1Hi2J8FYfan`@zd3M! zuzcSw9Qz&;jS(FdM2MwCB3XkCSvN{r9fU^c14XU8HKIn@?osKuJo{>}$Z;tiW_Hif zgx<92X(>5I>2#8nQ_fsF5!bQcB4Jm~Z~F>^3)%(^$~faBQWD83xy73>4RtofJNEtN zas$2BQ0UO|aZEvu4_jfTmS#Ap^V&zNvo3tK9-s+@B&{@b`^=NK#H7JEo$|l{VRJ0g zN~-JOhJ?Wu%K4pVhgE@~#=1q_HEkoN=aqvAHL!L=DqyKrA!yg z7xLb&TI%c9KYjiCdSgF%#r71F!ckO0xYavIb!KBlM!g+XNj1obw}iy-!PL=FD=`e} zWp_cl9j7=lx0_p(kuKyl zWA=3Bsned3pd%v&xX_iKuR-l70x;)*#638>_i$e)&qPaZ3)c~!8EUOo4z5r6X$ z9_w)b@S>npj@I|TT@-or#lP+w{?~tgmF}lE?Z-2H55fu^Bt{V;;11n9W|TSPaXgLU zN&LYFf#!!Vx9tzyM%iUWGhsYxX+-Mbt}*H$MiB(}ail2;&JvuV5W*4EKtYka4#gQ2 zOxV&IN3+j9)atYu+m<7v*Y!u~83_&O`?u}CNvM0lym~Tl+&q$|t+BStBX3VS3U;En zI+KH6jOr$Zy9WW^QhBM>%Ha#J5}`JGFI;+V-ym8!03JLQ;5k?I+!xQuG%-=CUwhGL z8w+(Xo$%cmTt@Grh9f<<%AUD4M~o{z4o!$~QuHBSmV~rn@`8Erac}Kb`fag#FV^O= ze}Z>=`rmTTf9CG~$*Ku9UQQl7%H{OcZ~cp}=KH^|_5Et@p1xFV2fH*CfszwFj%rYI zraMXoN@Go*S)Sn0o6pL6y?0CRCQ&v}8nUD0Xz1-rQfo=kJw#_k3=)ho@q{ZFBIS%T z1Cb+h97ZY)!ARnqHf1gF6Cc``@qJI7znw(lnzenkK9oQwq#9sG+AmKvFUhAQ;sG zCI^W#8)^`TG&;WdlkDV`58idBv%9OzN?JvSWMcT^FX$}((1TtOdIoI-;ilJu?5v#2 zZ}%nY+6z`6w2v*(Q88Eg-u3^1Bmamo|FuUg-?${YaVg*JA5S^?p?UqP5*SHspt9qk_OQ1pl0 zVQRohgwENroGPL|KI<3b{WpM(1PREb;}B%H?GFDH@Bi(2^UXJ3`C;|`h{%j+tq5sj zqD9D5uYCqszJBlP?Bgp})auxmCWo@~;m03-_O{~umK8oc+^o99T6UuJNHe9zZm18ri+TEo;MlB|6b zkQivSY8>5PU5-fiVZf2c{+-Y1{qLA|pWVl#qex8@ zLp*&GXA%<<@6KS+BSdKo7Ph3IeArD;bjBF1Y`OLKIq6G}^Jl>sy~C}T>~&RU#3Qp4Q0wY97BueG&@A3giNvH!LF+V^eg^}qSQ{%YpGvBk7lpVr45 z6;0IcwzU{KAe_)=`g#K&Tz2d03qadKBA+P@%D4G#*bXzfbgq$P@uWBH zdbb=RGLzF`=yns#^6a4_Uph{o2|?n@H4Q~bBq@-)BX z)%<_o(qA?6<$`B;C*|YFM&Rb>NTka+?iCHg3?C_yw&(BdoWaIaj>gXE{uE8V5B2n( zolMRmpltJ0JS}#JK=l+kg{9Gn#4tG>#;8jo&WaPMfF!F)MH>oCWk-_)8>W=AQO`paBOFDg8^ zlHQWdH_dN-NB=7i`Y%I?wt>)8qV>CA+d=5K*s;IafYSK>J}ss&HlxX*J=qI!>2SLo zYD{mSmQ%EJ2|0EH$uxaa73R+Q>czSk2m(P5Jf<`Wsm zHa*!QCM|Y#$E(V8rT~DiU>Xy<-6&$z{iGR3_!NG6<4e?;jp*PYbwZL9N=rp$x40l) z^E0OI5Wv@>oxji9L}3`KiU_779wV$BiBV;vG*lL zEYmB1XZW=}k^j;U@UO!olwwK><+xMH935_$l;0ii`_GaD=BoQYoU*7vSy?H2*^IA( z0aJB~E)JlIh0*1#h6IwG(5u!vtJ=P>_tdmK_n9oONB4Bg(Rmc+FluC^K-3CRM=qnp zi70lEl`wHiYenPCSkQ*gKN^5OfX!HU8=3SlZ{-eGli=7Im|Dm8q+v*qT5r1%xaV zX~*%*2}o@VjX+mvJqM+skB2oW4pvT+bog$cX3L(_(hV_1PH($*S|cK0W75^#`h$CZ z*U<~r-IE<=S$F}p4m0UasyXE%BTw#pyYNlLPY=$~Z5BNt7=%Woed_$^c7Aa{jTOfN zj}Sr?72qf=vr%MPyT8QFn)%_>FpHQ((A&s#ML)K7Wi4N68|74bmFU$IM(Q1-;-ENZ z`j-)37cK{%v2f_EqB}1T{gK!Ii^koOFJBxIg#HerM6gKIFY})KkpJhW`u+AN9;Hrs zii)%%R65hX0#mz=|8s*QpBWBjWN0vRkwEFr7~8PS;mE4jG;(gsuR~EYeu7yG;u%;U8nZP z!?tzoNi8U8lSpE#u_&NijkxxHV7lAT2U)u6b!5mVf-`z2dcR|3yk$Jrx83rT60`?W z8MLc0r0m=E)pv7qKg}GBl9kp&TrRO#5tRk~!R%j9@0p>6MJl~T)5J z=Lyr+E{2n)0Ik@=gz0Hb@1O7+^zQ3#&3C@_{=4~Vy?-w<{oKYm`8;D;t_7ZB%ix3+ z+~H(NaM|YJ^r5StRp#y2d*~Q>NC|yjFGI0 z3A1{=>K`yLlYJU6sb#`j^Od}EP8U`taz|=LCAnIqPQoXX-g^7}>B*1Yce&f=+z*K> z(E!9hWEk`gz-pN=C=xD?}`7U{i$1;OXKX?r)k?M3IV!%64qWb@$;4xZ9wAf zueY~T(z@uu5ES{yg&5_9Lqhv8Jh!>jt(*hFnK)|d1*?^{nWs<7vpt>Kcga(>J%9gfv85u24tCXN9}d3T@KRlCj|WSn06}CR*;0>J z^8prCXqf&%(jbut56Py)Q8s{`L0B{~5Z%jCgmvoH$4~gS>O3juaF7d+v100BX`E;x zh-kUBPw&-kNkk$DHSblt34vFA{)MEhxH>3iY5*w)85SO~+l$i|0$418okB^lulicj~Ddf!3%I>(^ICYo}_xI2Cnd7>+^SEz-4j&{05+T%B z6g)tQ^w1_-;lv(!o+)y7m)#BB+c206}G3Yf!JPO8;Pcwc(FJ1w2Q z`RT*$5}}mQM2v?8d)_&PViaj%-`<`bvrAhQsZ1--Vj>Zqp*TBbq_Wl0)KPqJ)1&7C zjh=>t%tmC=|c3O!N}&Iheli0MKd9p;<+D$Kop! zBI+b}cTb;28x-;8Tf+!)+V>>oC5NqwMHaK2LlFXF9*hDyK{8Z zOC!&9J;izIB;-MFDcy}hARI{@pj@n0S`pq_yuPz%$|g}>ZZ>cyLOH|DpiO64<^eqzqhke z7JgTDcbSlw)Q|$eZ8wGKU6bi4Y?06IdKw`>QhK1H;hem?0~t<@eUzk|C3SSrdUrjZ zXZeWFo`Wt^MHvgSn>KbE5nGmWoJ?O^oZU*AQrb})0O59;(ZVfA$yqs6xMvF(gJh*g zWZ!@GaXQgq^UyH)irt=u-EM_$p|N=nJSv8!)wcXM9SK|Y&m2QA;?8cE{7DN5;C#AJ+Qvc4k?3V)wBjDrmZ+6 zj#9_MA1Lv2YENJ=KUMq*b%wVvTH~lXl5o~yqv{Zs!^6XY-RBxX4iVF}S z@!9tyD@7D&SDj8=OWKKPg=c1;`|yW+c`hGR>5k4q<^&iG?an9mS??Pk@v%$wNjmcz zdTlY(LiSo|kcxNGg3<_cw`!FoQZRuOp-c(0O7K)yy3~3cI26!nj<{@r%R0I&SxQL+ zp3&>i=~;d7`djb!`|rQ?{v>JT@r@^NR5$a&M_;&wdwBFH8J#$C5I^n^J0yAMPw_^6vaej<(ss`W-=O#3`Z|5^`hVsh{FD4={&WF}~g5-4SBX7Xci&;)6wyM8s*3)__+~G=l8?jeE9+d$|8lP4- zj6M0KKA)0{$8xuF&po{I|9;V4cL0S#nxIf_9!Kf0TFUo+V~e$&WFHDx4D5l1o?z@= z4eW_~AM*U}Pq#xsY4Tt@P)US}dArN3sX1k(qec$ef^ifA1=<2RTg+=PiWn)c!DOpd z<0j2SwBurfh$GR5tkW}Xr@^hyX2#Tz^gu~S&^zvg)(rEa8nu+}eME|8nrUx}gAw1o z9A$noEBm8)P7eL8nx2{S>Lc)A`naa=c&L=|iAMzpu%wt~#RBOipl--X;h;z`cs6VI zi(>H*U9nnI`s0( zAPq?fAw@zIQmPHEbhorUw?ExXq$Y5+EmzWp>O0X0)XAa1kx#AD#rKQ5zj_5p>_O0N zZ$-9Wd6P6LUFjgF9oIN54vm!ruj~Xk#0=R@W;bX?Bt~I;Ry?UF93$0zC=+)~En}P7 zL=&4a71E% zbmuYAEXM}X+;>}`W1C$-TKgt+Xm0~VnqXKl&zDd1_;Cqn^!|rPPAno5G?`+S$kySF zLz6a-#TbFDUfjwM?z3?mQq88yIEUz8;MTfZ^)gl>a>+e*11J05Bh+fn&>qmHyH zi_z-tHfG~cEt?|U`O-RTV?XNcU%c6EQs_oaV!Aa%Yf%b^INiDkk~1VMGZFOIbeJ3o zLYj170J326`zmV<07}0Hkdlp!#08*$Kyin8u%bV-3c+JK+igiuK+9~%1T=j=Vf)MY z>^lxt7wt6ibSGO+)9<{q9VahZcUMMiO}{Hy13TL7k*(R|nHA}TZdKi*+2eB$2O19& zc!H3nK@w8yJ;#Wt^pI22-KYo80N2uQ+HZN?;|Z`F~I<(m;)Z~ zWO!Wn&M6Bf(_2z?s!6wqVG>=W(e_8V6ZSn*het|wylMiy!;=Dv>@%ncr8i*e4|c$d zS%a7GR$E%c#lFZ3Xarit+IhecipMR4El^_19T|LJj47l6jNAH*BS8rvkQ;66GiT%M^uKQfE z51thaJv9VY#}g&WHc%yX8QnlpCGBAr8#&!VGRhEY9fUhs>I74L>@lFGD~U(BulN8b zpKb51X+f!H#B=};_Sbi3Z?^d{zsT1=l&v8zophrlq5f_2BIqf{qu1&nndI(c34gvD z?e3$8YjjIJy;oRzSkt@j?j&2veQ4S0v6{18R6^B02xT%i^(;=48Wz+_vBABZy7F8q z1|OPM0hR2DNRLJDX+S`&vi6k6b_DcQCjs9T&J`n@pn3F%rXtkQMIAdi93Kg1T?k=; zEHzUBq&KIFhSqQbHavIj|F!=g_O6rP++XSB+ItDL-uTK)xj%&DMTwRoA7E1$t?fIF^7KN}8D0~)z@iHT?htlP{& zekre{*FlyVUo4oTLsgJb-AbQ<@fwsfOGQW)G$NO*S*mpbpih92h0$|sbNlnoJ@<2+ zb-(tp(2jSoReJA@H-79pZ&>0j``z{}x8*(KbWO5djLdae%3v~E1yKjbW4SFx>D4o` zpzMrdr$a|X#_IgMj7QgQck$J)zS-lfbOskf`{7;@GQ91{l`wUrkMGaWQTKei&o^YnM`=AGe=>>+%bQLuKaDFBkuK_p!x~YtLI)6#dN~TWL7> zd9TRXYIdQc?4x%dx7(TR?%Pqa2kRudtCqODHdB55(l0Vk*d#x8r{X)l^x;74)=9o= z9-NL*qWs&Z$X2?%H*c#5l0A3oJMjm~&earbVHfYgn}!ImmZ3%;mNR%2=>?pDV`=h>)3XLdtf7t_|mwN^ZS z>=u9^nz>iYw71(wjw7w%w3P{V=8(GsXo?};t1s5aHacjWpNNsZ(rX32qmO&=cxSrl zhw_|wDN~l7{^)Mg^N}QQIKHOr7mvAxvqa{@gTry38`vVXT0Cw<#M(zK{ZWI~a0Qx_ zI^1&h*`!|nf_U9`Dw0DZtvMibP?GB|4O?te({A{nY2PJ|OLixVuw^Ie2fmmQIQ@Z$ zu{pHmp8~7~565t_5)7S(vK?)cjtZ(wo$>G{SR^48Ak907HWeQUVvwAJ3{G&Uc!5ou z6N##NRYCgTjg|~VGu1TY>bgGFcpULV)-;W{+HtC=R^9>;7xlgj$S@N`lSbN%Mvzpo*b!DDB z-N9F#YD>eOm%97pt;M=5c0DJV5L#y&r!OEPl*gu%cLO+GiP<100ui$>5o|xbo~364 z8+)}TkUYr<*dmoLR7(A;|KPm~|3F#O8C%y=Zyb**gA{v9U9Bj{CiH}3@AYu*dG~6>&`osAXl$2)(ykn* z8G{NZLyzXxxOEikYAN9{)vtmc{r1@KStEWzlgzuj^c}mdE4b%=o1Y4PsMBVLyxK!J z*JE_%;{DW`J9nq7ovti~G7*OgXNHL+hBh0;)rZRNv`HRp)3Ky!nEWCiZ%TTfU5s_8 z?zgLaMK{iCEJlq;4U`=2sW?4-Lm7A4TXMHQmSf0k1MZz@wv(TEGMha>cw?CsqoxB1 zJ<(l|Y>35jUS3rXFa?XK0I!bWV;h+VyiXI*o25Vgl27Yh?8B` zVznmjOlFk<>e=e052E$(V_%C^{k-gN`}@@1`$*nDGo;=FPsIZE+0v@Y#lpL5HG zONXKj=`Y%b($qbgjk`k&c{C0(c6iYD#mic61NM`%*aB%v`mvX8pzz=GF7= zUT6VgrpiHW+IIqC!uhp@*03RjQvsH zEsg1?iD>c@_fx7_Sx=a2V$;LcfbsUo_K=ywG~!8WTALv=V{?_+SXO>Ql zcSKfZ?F-|~Rptci9y+1bh2xg|0FU8?dv*LX&YvIql=IMuI>48ebB~R$_%knk`-jtOnjVNegLOd=X|Ze@Ahy{NbBw;tNo;%cky0!A9@ z*q-Q#kF&MsgWn6$c#^IaE1wCQcK6Pcr9_D$2cg&<=%y`aN&_WR$Wwc0+&rXo^3vCy z)1j|@;9lb#VwhZP`?%0!ZPtFfQ99Gp$s+r%C?5{2`81oh;5uZz^2uROs*eZ%eg}Ry zNRNjpL!3$Wu3p23EIeNOaHa`qxxLlCEbJ;11|sDOF>*qKLOHwpwqd+YFPn}* zr_?y29lW$XZeIG_m0RxF-%_tm>vRXK7{3B{ixNm=Pwgky%>s&mD}yJrXA9jl-b33o zLPCj*$SxcpH0dS_#xEIAx!T2EBLDFJUg!4@n zef!EatjFD{bslC=9;a4MPm?h)lkYeh6Gsrvw!!V#B@8VU@JvkU4tn}qAu2pW>S&_H zuC$^Z{g6vtf-Bb53(R)`!+>{s>donq8vEpS^I40i13ekyxZB;MR?q$dP zVtE?s`bw)9YqB4gO9^Hzx|d#^yJBHWszo`zPL;6~P_}G>7-3*TQLQ(ZLT}h^pas&R zMjs=L*zCKfE75!L*0;ui{p#tbLvKHMn|Y;RIzn^Zu8gWM(!8RRJ=y(mG4V`uFj*7K(fb~Bv_ZQ=Q(A~3+W|+dUjgKkFq1%z@@J`*u+l zK-jLfC(S@KSsBH2B7zZ}@pCwO03oT6hql|`O@U$)AZiC=+h^7f2Nf~d1@fixvALS` zg%3J|L~IUMSx!qlmCdT-YodDpr$8Mz0TV%g)MgLXeP_fr|DKx z5Jq!7$8{A5J2^?rQP~t|+huC9xrU_VAuxjSW%&gOSaCrj+Nt@TuK@^>*q7_&F<0?0 z4{e6V76f9=I=yafHM40cUGww7^WU+X>{Q)7p5N&$QPYzfmWIhP)fMwPeOTF!fRcj> z*-~6rc57EOD`ThkkKTQ3vQ;Jm2y1)YBLo)9g*1Ic8_c+ zn|03GePT4x-~_XWB=o3mg|s3RW0h`?`(w28-IWGNaQ+QA8}qiYWWI3(M+o?A`xWW+ z_w^#5eK!&lga?^u%B1xqTl- zQBTX865%}TO;a`Ne%Q*<>~zl%r5tb1S^Hrg*OR!%t=pO8il)j_*NvSY=3zIu`o z0cEPNx zd*aBcGaFBM@9Iq+bWcyGceX?w!dn!>m?ERbXI%XZ3;EE;KG8CJuOJx18aE&-bHD^ao&D*lMzX+}ucusGIAU|&}8p23kr3mPX zWg14OG7YoIG?-CGnj@0TXYk0IIeCLOUc+vPE-MKgRpzk2xAw|f__!Gf6oa#qbeQgX zszr}_uy4`Oy^n_pr1O1P#EIDJ>#4(S1w7EsETgXd+aA9FYJ%_8a zbLm*aimHef#n8=zZQ86m0v*oQtB228xTll~qnuz%D^8DA!o5zFNbGxgmrYpUBJN%E zG`1?@e)-P91Ho2;gS0w1RGoA8cJw3_Wp}~Z_T(#P-P+ge-h>(E5%9PIgXH#pkf<|Ztf9K9t$}HLV z?$YAes^9+2pw6_aCcHC~Yki5NJ8u~m`W!u{sicVk?H+;{qdCl)-VM1g)+2qLBy29X z)Tq0TN@wH4j*K;RJB8`V(Vh6}PODpPssz+shgC{<=V(1A4QuA82y0Jtp)mkjP;{k- zGg}0Zh-hLU9Jw_Jj-audCAh#0Du^pJ4aJwAoCYkH*w2s{y z_0;I8RO{(Ob2xp!+6UY9K17g9fsl=%k#IY0R9Op*@j3S$k&8@bQi%6VF(L$jcEw6) zz5c8Ef4`m-G^7y5Tvmm((+L#8U0bZ2IF}<@-I;#r~A8 z($hfW5sYInTl8Qg5<$v({nuc-FTbk$q zVTBpRN}}6IV)s_(m3Kdg_d^V?eZmsfRU^WHkY;Xxi=8>DyHB0&>>MMcti@>R>6Yv@ z5qw@2g(9XS&m!R6yGAl@O{GR!7(&jv*5kTZ?kmb-j9%68>W`k=COcd6j6%Zcd=xEW z$-+l*^!6N5nmCHa%tN3uwZ*3cXdsVmQ-A}22argV+3NiR*LH(fpBKu*0B(alKUiG$5Kyg#>?(LaPGZL_bcgtaHrFK}PeCLgCeJ}u$J&B=4w-HOF9iFys zhe#IhQy*pj6soT`k;Y*L+kM_tDi_81N9YS;>)F62(=;if|W* zH3mTvBvF(s4e0$BOvEGMlsa{#Osg8unTTg)ue%!1a|jH*%yW%@p(i{1VFD@}wo5M5 z8eM&wchmG?j@$_Bz$%(UR%g1>>C2vO6{opIJ>y>NeRU6#YR8>NZ;}jmQPQ4EkB-T4 zo2?^~xeiC(m!mo=#isl05zDeAzg<3#QQ0K!bFV7ut<#d0pmGFyPGaWy?Ca-n5kYX| z%-y?baENMpH=On!&K9VOk9nCEcCqg=z@?$mq_tbPMz-Z38>=l8Xd}rgT!gVeXk7xRO`Yk44pO_3Ua+^``~db) zz({Dljgc)GFon04gIjubFCO8WAG-W;Pka6@U;W}6X(koC5Gb7~KYhB&MzcF-M`Ya* z2o?{r(LOZJc4JSPQZkB~eck72?*2Aww<0{f+%46G+iLcc#?g`U!k2N?bnNzak1|n+ zOzSeeS2udz=Kgf0xK|6G;|df2T5rK93cQJ8?1PNv9K8 zGg~cs!=LQPdHhQbHMT^JUW=y5wU6mJSQ|-14Bjy)r*wI)*c65@<=M`@qn{+1<>qtv^;Qjv<=dLC^n_!EeyFd1eeo=QFB0ulvzw5m6 za-`SZcui~Y^VUina?p{;Q;dMBkK~Pb%NODaAEE|~K8_)u<87C2$BftgC5&XXAn(mg zBlN_Y)>P?f7mziltxe0Mvs-Zo+9q9bUln)6q3qjP=gqFpCJBivGqX42mT33lLJvj4 z4n6HLw?V6`WA8YMrM7fmIl8wlfu|?XZkg4awSgL%?!r_YAkUDs{QFOTaS5iqAD!?P zp~B_>irIAH_wOn{?_b<`xgC0Qz2BYPcVkvg<8gVl<2Fp4yPIo`#^$Z3Eo~0kOQ*!` zxDqec)9QuldbZfC5^)?(mnR~wC|pzwSXNZ%=zC|2kErcacbcT6W1E`*p+ljM`22OP z1JlLFL_p>u+?k2U_DF!WHzujW?#(Wudvne1pSF}8oV*?+QA<&WU_M-}a~8sN<94{S zmHni$H75bkPAY2brZLghtFhE29hdt4R5>4VWQ{6gCE3y5>)OZop_}aUSb-x1rA)Jn zT?m$>iBtQYo_LaJ+A+-G1_(S8lrT{$TuGPMLAzd;N4DVq^|LE;3~+FFW%@YO^bqd3 zoxNtgx921~Mjzrj`>N^NmGr&ikcRR8lO?-2MPc@64H)9Bt#x0$H|NY`wkAEZRizwg zsbI?WVHx_hd0mD!;Q|Be`?BtQ-;qknc zc4tM6FDn|mxpaT%wIkx}?-{VMWu)q_bpl!MouN=? z!cyANs7s=^M$Mi;ggaGe=xgG%#B4(sh+d`a$humHWOC``Ivi7$kBnG-5j-hQNtRVqw@;WxjLEddhZySM$)$@aZqw%KZ6HDt+oO*5E>fMDUMvP!MTOslM_I=xHMfP@>Ds-? z@=ZCbaRcw)dBsE_R-nXzpG;9;|78lnf1|wIt?8O6Mvk+O6CLM$TpCh4Js>S}?ZfT4 z+D#Cs5NGW>l+xOG;hxs#zch8~wZ;&m+7nDT#GS10v=o1C>uYUV`8~bm!%K?VthQN0 zm&xofJjRZGY4NK?jzPK&GSQIoG!3ARUR4STkOVFUANXedlULkBrGh96W!qHJ&we4p5Pfuf9Pp94q$5dlM*U9({pZnZ_{c&G2Q2&v|5 zpEGx#>+1Wy`Qf8ey=yU4)j~e^SfBa?oh>?`ZdFqc`!i0i05cdIeRaOnuZ?)N?(0*K zj1+MQv8v5{+(P-d6Ya1#>P%c&Th^8Jy7J)W>cLA--gdg}^gH_({&U^%TzDSZ_k1FI zQu_9Odtd)W7Uoxe;HykMqgs;k-bB6IbV;v2=bm-n`Qc}u(~Gd5`t8y4x1V2L{ho)< z9y)ZE;>+*6^Tx}1<16pH_Y=JFljfaoe)*l3zx%u2`|g+Dd*|gh-uUjvmt|eO)5=78 z>EEpiwjSiDl|wkYQHG_uJ$X2)wQq7&#NpLvbD&iv1$dmS==Hb0^YyR2Z!(N^8Z~Il zv|d9bc-SVNf9`Se{OxD|wy@>{P3man+QQ`Su!@fh5DlcD_c246be9tyQQX^U=PWdk zXtzb#!6YWF)PSqEyDax9bE+S-k1l8Q@L0#X5oaEt7l4w;XzD)lsOzv+HdbP+HZQ9- zG*o{~zOE+6so4SOuDd7z4}Pf5pZ8T*Gs(wkA*niP-VVVkd){3K_hyH)MsP!A_)Ity zFdMO-zIN{A@7+#rwA$&mM{^8PbuC5&UUdCI3+b|^y|01Z)tC?ut1H^k5w)l|amW<9 z;hOEsTzhKjnY?77$$Fet1>$l?R>CQbD!Z_23QzN}tJOoYRnW3zAKeZv^-jzhTjqn? zrOEP^^UjYsuy5%c2V+zOgj5>$J{QBfd1JV>GJVaf(|Wj4ksu`V$O0f*rwIXdj{P)N zhhk;wa95X`L=*35t1K&HHa|Lt`IZS}&P;R4M$JRdaW9#!8AxYr>W#0t^aVW>=ARCU zAQA|UgpN!oHA;$YMo$qhbHx$7al-7iY}N9Nd@Q7t492T^Q@i@f1aqveRvZx|yW!I| zdC_!eb$yomJiM<&F-Ew%eCl|#ir#KX+O<{*m34G;Jas&K_S#`SNxW)LYNWG_y~Ok& zmLI!FTVXh8$E`jkb$rwaiM4uFHXV+yw{<+|0Ar!IAETb3{B(cQ5B=tE+M*jajY)|< z2`7;?w;u$@|yfJ$f`>tJP&TUzG>|f7sFmZ0yiU|~aOrq>|Lxtr?q?dS2Ndw2g==I?;G@w?;;CupyPFRJkcr;evKEF9 zyD6ulSa1xh6PefmMhEh6w7gE;&Yvo+Gi53FIi5aw(?+xoGyrmxHsRQGlAz(H9xihA zchd2kL$9@SX-FhUbqEO{Noh5Rd@$HZtGw@V#_sg9^}=xmVd%sC*<38ws|Z)0bE9tG zF$h4h_r4)Kw~O}vK4_htD zH7GS&$AeAnn+Y6A7+Q@Zq!?$YQiP7qB7N`C7^~$vk*}SO-kxaGY6kV!UG|WqPegWO zv~V!pnFry+PI1>H&+0r8=IYL5IE+3h1u@NL+6@njaFTSU()X#*?t5R44uipu6Xj?R|e@uQ>pHT}#uDDz5hu2KI*KyDe-)S!G?HnT%Ts37EEYT(# zjJi|CLr2Q$Q4Nc!-M2B6r1|nEzm=RU`x+RpOZP=P12y|5G)HdPu{!QULX~akR&gde zrgxen)ca!9C^z*{-&@QfA+qT=T$gl6?!^LXhxI{Ui5K|GaSu4uFmLkqoN#((mxBiL zKEO$%M5uUi6WAm^eZm)rT4SLJ&YPh@am~}PE|L<3xH@{mY21h)3_Z&B(A^Sd;x}5dxJgsl;>jV z`sXJ;yl&Q0OYY5nZ?#Ntvib#k(fd{Xs{Y^4n-z{{&U22Zzy+j*TV!W6Xsc__K$qN= zq^FFcw5MIMl#)>K-Jg7{>FY=)JyA;y$G&O$;l672ebSjD>5jWc!~HfRd`o(F0xlhX z`+ep0x8L92*(J5`aE)F1d9-y59SzCF4==m@;0Kc3>WPorykfb<#SHrgowS;mi%duDSyXIYRFAT4{AJ zWQ*2$=<|+ycJJ8Fm;VZU&)ze?dVTz@FRPPInzUL-`2s+__hqb)%FP;tC}HebLIy;G zO4YQ}YcY^$d+**%uAvX)$T1mc_0l1U^qG_C1uY+;{58#@u%T^To&h8*2-d=}Hu()m#G z)JB0Rk-SXCs~v4t{WD%4tyG#%VUj|@jAk_ltR<8YeMCA-dbXj8rNy*)hh_K}hM;!6 z@7y0lTvQ+HWIK;~nuEu6V|$GqDv8+bQz<(_gtJE5ax~c)+bLNihl>gx5n z+m^H)4R8a5=47vSkMhu?*}6W;Zs&9dfy@X^_xV7QW1RKce*)A&P9s?@B^ettY7?Yt zP#R65spO=K-par>n8~_Z zf(&%ZQyr5a1&h+1*yUl1tapZNMorSHlVTs*Y;LX6+|KOQ81j$r-NZ~<_CPd1)+b%Lq?n(6r4=u}2Z_)z@ zkxD`~35Q%)6iNCjpO5P}IbRZT>rDnGqvIaD&xQrZP`jtW^yJo%_SM9gIc}6bH4_^nrIX=>UpbrK#DK zAw<|-VXk7FRRd`jsaKEbSVI7LqDgy zu3?y-!%PY(3>Bukv6ZNJqSH7)(lB?fqH9_?mi9xR=VyHUWqVwi!y}i3TFH({@5GvJ z7)_9}b529GG9f~-=-nb`p+;(fPE|S+jsIYvKoB&4$_LxJe=OXcPG(-F5dx4w3zpkE z8^bJEMDxL=?B?nf)5^|1j`c}TM)M3+J{(7Ow#E&*gB}jwc$H(kItGbNmo-xg8QptZ z9PQrpBzuq(ePu6w_V`#xFHP5v1d>irlnAwyAU*+s7)j7=L=TXqc~H}XpXDWQ{<#0^ ze_h@hDsG$K>a}0N%j?u+g`h6U?!6Du4m7dz)%()NFZz*l=c`6el;-F|2TfVm;}*p} z#UzT%X6okT$;?iD_@h4j0? zHoxrG9Q%lc^L2NB#+Q8I&-fW%cDBdF1p$5Sp@k2hW%JDszT_Fl@8sqWzs9+1&xidV z6w@}z8m6<4UL=Ep+k0-i_wg_n7gZNE&wcik?a|98*UsL4GN7hiU6xr#OF7M8>eo&$ zeLl{Vo9)Q{TDV(wzr#H9)%+|k5DAKcLI|`3&o)~Cl3h+DLXumHFYp?7LY$^Y?uq9< zba7wHh<-tOyetlDsUjlS6nNHy@iXDmy8ca@=w$(@HCv?yl=vqk%}tHr+K; z`=t-j+2oUtOQMyzF(D-Xq=Gm2*mY2QHkL!@a;h7NotDy-%0acH;FdrQ+O-c5HbCfDDf|BD^IcCT3aKqzNnK`QDzB=WO1Y zJ+`K^y}EBqWvZF6L8E$Tdw%#GFV=0$-Wib$>D;3uin33yavg`C9v~cHE9xZwxYnU- z&Fqp^dAiPSxw5;rKl$XP^hSbN6K#(?i#=N-=Mb@UXR#^TeWuhCscM%6!E_`#VxGAQ ztS|pKI?~a0d@|4!I&Fs9dh3FXnHWwqI9w1NmuGF-6DR_8({Wf8nMBChg^Yq`J*S-0 zoyUsPySU1A%foG-=dOvB@+NrYac7tb1=7>DD$}y2wpGnGPWfJa`Xf-kJ`#{t1VMsa zGYzkG8Y#c#Wb7KdlkO4p=(pL$Iz+^@7^We<;q=8%T$m@uajyi*^^yvO>5+5M&YL}R zk8*ISMu!@#(t=g$*w;)tj+>{+9+fkCEqfgmWt$S< zviImlSE6aT^RVU~YDX??p@lKdQ7ejbe<*#v*Pz|`G5b$x3W*uHl?cy?66(>W1_5`r z62{say9b2J225mNhT#V@hM$;@9;13TZ{Bv9VO5`ryyrZ4$nYlE2cN| ziYIvuNos`LA&xR(3dN?=T+(3U_)>(|ex$k)Amj+r9<|hOe4^)nU1UE(AW9}Sq!VKA zvo<;$Dys0fzCPqvumg7s%qj;Nq9KLIa`gIq?doX9kGnN=5gg=2+AE$eDn@3ey~Z=u zX|L?Y^_o@5o!b2nsXTK#Os13Rb>94vs*Z$0#%*X(t42Dzq$4;0Q$Vc0XKU`$7GbF- zz-Jp2TE`J|v=Yz_h}}cax8m`kmm)yQ+Sp;vkzG*G*&<9QN;XG?atv?mpRGmhl&C~` z`iJ6*fphm1@iEt{Yj=8H)v38q`zenX5BpFs1&C5oE-Q70t1h{m(2O6lWsTa+c%^U6 ziZ8KW-cMZHUMuwFZYKy(Gy;YAE4;U?sx$u&HQlF zB&QiVp5%>|ou<0i8W&uj&EamV$H@db=?=^eGNQ+OGTF{tJCE0ucCb?+(#PSvroR3A z9CaME*PiD7(6-i3@QJ7M+DnSgTTa$aB6fFA>)30ROt%#rtH)Og++8fVyAP9^*4*5Rzre=_9?Kqabg){% zy_V?N8cRv<_wSQ9zxtr8dqebehJ)2&J05$-8FSL7yvb3mSmARa?&aq{XlY(E;*Hlh z0gaISXR^v9wWmCR4=`fWS} zcrBK}Fbw0~_#tU>&dhOSd?U$sl9zhx2T_{EZt* zO)g|#;4Y84aZLAUAJ?h}UH9DgW#RE?bP{8AhAh}adiki%(x>wp0u%0d8o^SrqAFW^{inLU}8Oird5`D_|Mh7yO zW|Pq`o#T=wwQlu3N^`_~PC8DM&`dJb=iZ*{PC^PE&ZMKHW~Gwj@w`b}ZHsYPTl;8f z=mAY1WO_GGR#1A{FV823{c!)nOm^mrFFki~aha7$@Scm z2a$qKM?Bm$$0xN3w&3B6k<9I}p;>NuyK|Es?wPBE+t;>5M4;x-FC$BKPyCucuGE3r zX7kd2?V8TJ ziITOMs=N`>$z76JXpDP6TVf)dC1)HLwfmOmZ%X-AkcWsyz-SyfX7HtDB4tHi1sw1S zw7ce06ue;k#4z z?Xk12E`{lJeVcaA?lVT&4_($mn20rovGg*i*%_A`R%f9`qgI>|usblIbE~OyBgZ(K zm(wkw$ZY|J79iiwh-?bBa%c6z*rF z^O*kQ;u`6>gJ}t>YwvpsL`9KR^e%7N!U;};Jz16~w~d|Fr1>PH)*}nGU)rVRc;Yrh zDq+vk-suq?ETu6W2xK%Sr6_l&Wgt2PnbjU-xTlLr+L^K&j=sA)1oGucwR-J!=A1&V z3^Yiv9)ZS!dg63WdRLu#QA(qAuYDfpdKg)*(a2Rpc0`BK;FhpakeeO7dE2f6oIo6ohD;S?LGyn0 zLPWjl=a#)oryH=STo1-R;k~~cD}*U>qL|%BE(Bu96IK3O&ix9Ctyag zOjI*O)n^(ZCP!XUa!)Qn_lKM@Ir#7wwpn}k%?IvcCQE~6P&T?)xA*>_UWuSVSgl%d zEG50m&{f3&T@Dul*Nah6`~6WYX{{l;yG6oADdHplUnk$^QxAK2OeJ<-!IO8E$7+dgQ0I1i=e}He zZ#0``Nbs>Leea0W+39`LR$Fh!yMJMAzC0a|s@95}xT*JFhv=lAJ*$Pk>9#FSIt7lEEzcGKlU^l}1QdnF$7GtB>`koc^Ltl-NsBaD2XV zLx9X(s{-qdFXLWcm&&-;$h&$;aV9bDSZlpB`%nWtJc&>$R*fK2%@pqaHEjePC~(D_ z(mK3xY!*DeefOnfZ+~d!$$skS7Y=&M&&TON>!Fruh!*H+jZEh*)&6DNKf2XiGP0;q zxi3P!YJ!D(s!W~ehwq1G;LyhACc5Fo)O2cXMa@Dgym;c1cAqhSNoT@4pMWGxchbpB zrE}2ZeWKJ5S&+-zLAagtPAX!YLhV|3+=zo8K4Bm_*-GO#`qoa8mf|>{kNF;$97r__ zbCH-$HFAiyj>27Ac1&avOX15LqoVQLdV9$g@tSb@{&2Xfm=v!Kc=vxV1!lS}s+5R5 zU-P|1?)LHcS7cL9&=TSv<=R9*6o%Dw7&=R!fY4E(MNBQi!%~*&(bQ(X!1Z*rq3l0U zCs34TF&I%AGiq9ICY7s>#-ugie6+l@qD*QD#gcuHl^U>dIvU!r%K`iXjj6-EXD&55 znxQ9qAk;n@vWI=C=md-eL<&7SUP1zdMV~J5%2c-Rf{GYkoD&AUfo}Z*Htl*`U@(kHHkI*g98m|>(uTZKYi@( z1Jat-(NBIE_2{EAauEFE)|Pe>j+xVBvG@b5L_B{MsfrwT-iw{38T^- zL{b?IATv#_AQgqOgLA)`pJJw6J66~vLoY7LqSV%VnXsu3j>QSaG}NA%(`z4LHle}O zy#-xUkLH8RZRVrm6&)z5Vb@sdZX~(a5lFw8z1zjJ_ecPNNI}9LN5M?mR7*#fo44rR zeFs!gJ1zk|-GRP)_DHW!N1NwxFEYz1#u|;5qcPM(1P1+Cj3(kb+!yC^AV7 zx%-HadUngRd$(xqC+q%Nr2hDCI!^bQoi%8=qlc|ddRCL57~nOfrvoCsE~(+X*9VWv z7v0O*tlfOjOMr%Uq8W!kf&e!I){y3P3b2lsprDakHt}4& zYaazIw9AfngP4!!<6qcrgg)w-jcT}lV$I7(M^5c@SuK-{m;Brar)5_rhdjOM4242c zQ0@}RKtPl-8i4Sy!tlW@pZFDAep#3Po;@<18P<}JMYdq`0iLOW+oRMu9D!hxFl}x3 zP`K6ZN_lV7n90VYJ_)p7fV9FSee@P4m9D|soBm1k-8YgM1W7`tDvBEtG6y{hja7Nh z@A=5$`dupRTBL#^j)AMJ_8^18U{IS*At~cg~ z4qv%`r$1;O&*{0R`JX-O%%c1?*VW z9?L$NtL@GE?!EUu$uXkG6ms5mxxez3ZLeKlGa(a`?p`c6Gho!(&di&Z?aYFyyc5so zx%{oZ;rPHW5=GL;dy?sp5|NQ4&vDTZrMMQwKCbB}88H$XeplTcm z-qAO|^K!rOOuCb?l}HT%447lD-AYof`akCHA>wJe=ab;k7ZyC{##ur;Bg%ihX;?dJ z(O)@ddmB!&Wh{bgx5r)_I?2Dd@Bbbm>vtUJ@}C#PXV#9X`z@oIZf929mp=C!`uOX{ zpYo-D$v^Hx5;MhNRg$r2CBUvhwbno)f)hIR2Y#~kI4WpQ|V z%cdR2Qd=MyZdvB-fZg$n`=wX^iQfEx7YUzXh!ABGut(csr+QZQm2>6T)N;Ny-6t&! z#SzZBr7WlL;SWz_W3)xj^ON=l3@-E~k|G4Ll?Id}XEe1TBjv+xN z<#E$z(LcA_Tfw!>QLS ztZ;83c6aQF^K0OfAG#!p?WaDkBi-xaq!mkrnoLX1gI~3}9$DHonHZ$n*ZO?d{ZVUj z&#i^F>wZ%v2S$3#wi#dSe5c_~n})1vla%d%8b(8pnBCmO>B!xQ$0t9M*Aa4)N&*6! z2X&{S>S`9@r{V>Onp_1K832-kq8j9{e(32K7L}#BlXOY?vO1zWpoqO%&+LMB^VOBN z>ex5Yx;Bw}HsIyp+DBhAG}uM;qn(;rCT_AOYc#zFcP?i2fm(R(8@1&2I_O!E=Y>~; zyw#(;!&Ixw8j7t*(>zOq&w5~Vbzc|norriW-W-6#ZC3R&Ycw7A>@7ag1ut%RI6*4< zr9Hn9lBb??N(78y5&p)~(2i-Vawc_DpIi53M=C^HoDq0espMbAK25HpotAdyzG^+W zM=R^fwbzrz*X(HyFLtKFbzf&hPH*9zdBy`6@?_AZR!7MmcUh?B$?$qn7rifac+owd zw~^H)Vo^s2W?&&Z)jLKHkjsi}tov&|;rxPTrH{G&4Bx#`wXBvN5Fxp|^ zUVTfxsQ&qO-h+D)mc1B)SVjjFrkYc(WnDLOZIn5o)jEE|b}faY%c9d?EepEawAr-Y zi)fK89n;p@s@B0}Aj>Q{+iFMCGPNg`9Ph&|;;NykF6@y=kYM?U&XY0w=$m^S_rcOR zok(b9!luCNK3I6vt)93fx~;-s0c|M$(5p7C=tcM0u3KAGN;m-_AR#?PUj6P!6AyZu zwp^&C(ES>dEW4Pdxe6Avz;XRX{0hvI0Xh$9(eEHg=O8-PoguJ#T*GH0m24=rN=vh7 zwCAKo9*?T!HG4bVy0wV#byF349~{wmse?Yj)DU#tXS24)zR&++ zvkSYvfgtxSLlaZ!`t%#`;_*;#W>EOWu1*^v4*slCH6ee^+>hr8=Ekgg8Me-|%Roe( zw;U>yMn{utOD%=&z8sFakfs~b?Wm)z&TLg}+oNLQI>WB5jFlDfwA60?>@8j&k(_t*K{Cm%A7 zhj^0WNrjy2^Hy^Pq~^aZ+xxN9dv#s95|){T#KLsZmN|{Bn(wVAZ(BxT|ClTg>DuEkHlj2W#!rg|oNX8!l%s z0-oX^-izIXOt4rYXtLbT4}Rm753+STtRCcQ?L8c+Slyut;=2+lpWPD6iAEGg7>p+%~H2CRH-D@710&n z0U{vl6^th3YeQ6`OEUBx%z2m3Z9>L9kKVNeUZ%p&@eu}+X?0&Nu4tSL$zEGclPS#3 zdYFko@t_l>f+MCUWVS2eAc&xi7L2YAEzY$!Y}cIK?q-%AQ;@^8k9lXCwXzaZBv-@X zvU_ePqd}iJ3Bc66pBul#c)y$5Rd`*YSCu3P0~`s8>hQ%}6zV|ug~ec}r`67=>!7>p z7os#Ne3WhTwlfWqa_&MEi3klfbA&%($IVE}~YeCpG8r_4r?Wn_<%zdrw9!BlGTf z&fD!tu{QP~!*C5m71!g_nzC68F-uC3~BdFM3odQ#bI8*I+2S$KA~Bs5s44 zq80bv`&7tbCweevj z(CrYM;hvg_oyBq4&LCT6pWQjRlW#}p51>16Ym0-pO_a026wtwRP;qJ-f?8*Ur2r3| zdK`45Z9e&>Vf%GV_q2+x(SErKB^CyE0A84*mmc}<9FUPl-%;nZ@|bH2rAxMV+XLh} zvfLGMG1-c&NuT4G$TIQKNW>E#{)DOFjVZ|xC@%8c26cTZK||eaxY4du89=FR%5hog zjLZ~umJV*SD#7TOyImsLC9`kfWV0))i%R-~{-kMc}E?^>d7Fc?cCOn*8<6&kp+BE9U zvtsLWZSstG(Sx9HP6q+>@OzxjyGo=z3l)TaB;>tytZZmebG+ag2tS%_J=2#bzn7bS ziUv_mb_YI;zWs1`@5DN3%>%3*qrM{1u2eG!avOC8xviG#mS}Q4DUZ{9zNRK1*T*6#K4OM=2>xr|^oYIZB!%n!XE$X=AFgBq_v)x1=Z`ySgC?jbjI4d0ta`@-kKc#TE|0MS@{8R2Q@hXa4tT|1LKaY@meA zKon6}_KMv@WnfrvaL8=3?~^iXsCX8if3RLptslE~NLTU{5U_AEstpeF8id#aVw##D zoRr$L@|a3D63#j6tf4hz)^0^X_?R;7R^mu1)@IMd%_Q{GS?8L*Z59q|yXvCcBWUR! zLpHP6W2eU@x)n}#d! zq<7|#70BHoS8YADD8JxZX#Q#DlR0=p)F^6$^;&9aU?3X1n^%s{Zb<8$4_n62Ih7zZ z1!uCSbBNJwhaHQk-EB{I)J{1~tG6Y^n<-7zNej6@2a~*auQqXHP#c0+WYmiU(l)uv zk*PbqM#-#ie8a!xb9+8BeY}zCe{VMQ{AKAZz3Iz&^gQSXLfyKbLP8b@z5T{6}_WZ5=-hRu@J?4K71Jv62c~)nmZ)9 z)-Ae+ktM!fSu-o4Gxb8d9YfSi)mWZ3QXffQc{w}?R&K+ zwb#KQB)UsTG;;{=kwCVJ-A1vbYJd2N+~VcwTxU=?I>x$oAh;)g7`Q=xdWOGJbo7Z{ z{HAG^kW(%^=VJP#+U!}-ptZ4t3&|5r4hBVeVX!&WD5^|bmXJVcqLX@j(!$%f=GS*oTLtoP$YuTyMK;&tp;|_8i8#N5CBftJ&PGLh)h>qmULfrko94l zp2DJr2<#F8df_S0CS{6K5lEt;k>ZB6$X4e;+`48hW{+7OF+`(@5^7r6p(GkLEsL~O zLw)<_(sD*b4#HR_U-*8VzV7&Oex9y{r@wsh?h^j%SKGevuRC$4UD>-n39iU$y(K`x zNgXp;p$SreBFOGjW9w2VS_qoZmXx8VlabUZ*=lByJq`41Z)`;@CEGahf| znM*u;Oz)Om4C&J-;{&O^FUwIJEIe)YW3^f+iY3WTMxZwE$tNHpp?zf{G)ChWe_rU< z$hLF2{^9W6U-pvdjL*G+MAxg$m`5M@Za@U|KyXX3m}mILW4|1H(f@TSAqv600~c-2N~W~g{ojX z{qDSD4h>`{L@t~tm<$7O!CN#H^HQ$O|4`2!j4t&gdhd>zjxV2t#JJsf-=(RP#YSw? zgS*-i@<>DyUQE_jPb-s8M{$oOQd@|yj{R}Z@i)9}>9e`Qm9rOqaev@{Q+?IX>8A5N z9_4Jk?e^$SG*DsDy$;zN(F#QhdAukh!X|Rs4MaGCzMZ5QO4iaD8ue{kb18x8nd6ds zqAT8+X_<>zf*G9}DvLViXlZ4!htc%Z#gGq7b6X^n1e%&eX~a%B9a*CD5@QuSh=>|{xncySa=J>>x%I#XOM9j133ZuV4%C<; z;G&B-Cku>gClAf@&-Q{t$6H7t2&u)Y2hVX%T}wM0v!T=7-0H50OoW1&K1zy)?k;Ph zFv_r}zMW4#e9f=DVcZ?9BYv$p4j8$Lx##K}%W}D089w3zUqAo+z|Tc3YW1OyeUT#? z4GAK~VhIBv;xZx(AR+3qNTnM?fk^l&Y>_fWg*xOVbIdLI{ z6v1;B{%{vOpLPA0pXmG}&YbKhW+h$kc{Fp(?W%cVnT))0jC)6NN>TSg#w$rn0jxVS~y)9-VDxXpFG!neW7^pr|Ah; zHQ1 zr#c;wNgai*gPoC+-8waE=+j{$OakK6SI3TKWRw}f=$W#8T;M#nUjO{1?!#yLy*P(K zg+voAq_hZfKO1QG&?STsj)XiYFl7Lu*Th@PCf)u}e z9Dm*OhW#zOWF7KQ4uT?$9G7BM^7LreXxNz?T3aKQ)xkSzXl9@HLjo(B#z@b;3 zKiF$fZKY@Oni3+SmF7&DO7jQ@Jsq`c6sc@QeYaZzE`{MmISKpOa8lpX;g!sm279Hs;&ktN~V%)tgFuO`RAs`|O zM7H359>^y0i3K9txQ7cV(=b^$jv|-kqQ(ZZf1QDxU{8*4us5Yfc`T{2r)PJKIQDFz z$}|zxA+~I7Mstlw4n!|$tP#6$N-vQLFQeqVE%i)3{CHP@t|TW(q#NXpa5XJTh2`bt3;Ck_v6K1c#kEF;9A%OO$De$Gf`b9} zaJOOD_;eB-00U{^qZCoDhD)%nFIjTCYfI)nx-UD@QOA@bwfjmG1Ca_OM_*QIr=@wg zv*pO2lo5^Hqb3AeMhg!_S(15ge(s)CNEEqQNcqG@qboWM?~=bc7&B*;w&}+^Z`YDlL}XhVJ

VVLiczQRr@%)sF~HNqc(tBQII4^ymu>&#E%l;Pk^N1a8uKK zY%CFG>N#d03`n|wcvCiJSIPo?GS9s-D82iu_TyMVSu|Y9MYvj; z(htpr&^h+*!dAI!Ys(0UR?kC%Jl)bgdzg@PBBEiWa>YbdB;zu9`Q^O#245iEm6CR& zFB2+4EseAe?_-`@l+!O9f%i5ZdY>9|ZGDmZc6P_(AAd9Pl+XU+|F~D_RlkMDwH>x@ zb5fn|wAoT)_xIe+C<|V%PvTLx6eKTXgVgD{p(pji3zzZpkZ3+Iiw$aYRtuQY+`%9?p+Ft&ExBz{R8jX z$Ggr#Oj~KkFRNlu0Px1d15p?9(xtsz9cTh z5Oa$(Bhq$iqXA9OpbFZnhL6=rM^HjGMoq{`$CAQ`UhgYMq3ZdY5l)Gm(RS8 zT>tv%<7(fE&qg|5S=}abzwN;!G}nCCn~ui%5|=53nV2ps&)}e=$3A)z_AYA2@-*r$ zDf^tmJJm#3G?U0HZQIvOrl+Xm9%g-CbRF@`Z9eyl+E#g@8wYC+IA~5H6m^UPG6T5v z=F6|$Y4+0luXJn?DX2x^5NqAI$6kezAO+eA;VD3vsUF`1gT4~FkR95ZJ5R{p4v4l( zao&i4&j5Cs|g|~sHC{3 z`GUkcB4r{%OdopH0?DvoG&L&#yQF<&H*A0D-rrbV{DY_BKq^)RYqQjzG z(QyO9w8&$kO`rSU-9S`$Is|1)Ki6G|=9Y~ymtWTFhNhD}|0j#}8RmO5?{n>guWLWe z_k9@tr;eS|>6MUa+;Q;yZ>*HOw%C(G^1`RId0x7zv8$08X!Mjc9n}${v}PetBdOyt z!o8AFme`Q&gF2lywB-Rx4Y429Xw9ZkRxE~HO}|r`q^bl^ER(*sHB!wU+rdm9CPG1A2$n%HX3HA2dopT5s7R0& zM0B!AX&1nZITk6fA`cfCn$&2UbY@&=?E=&4mod(NKzD(1=p@tMogS1BAwu5MV)t`n zfhDxIDW-c`h<&=Nl@Pab+>+)xlN5b$!dUmLZjY{AJsu>Py~+O2ssi4;qD zb|~orK)}1JRFUZ}mCEok-qVHU-9PQ0^UUs!tT%apDv$#-|fGT1^c}Gb-MPq zS8VopZop}OJ#X8`teZFI*L2ss^(YMYIp?qE``dT3eb~nd!IYF)W(cUKjyb0~lC={hKF*b>r*n)#1(D%dxVjig9LP6&;~s=TgrIKE z;KI2271#g6wfBDH^ZE`4BznLlcBg_wYmx}IorUs@VYL)vdb#?*TCB?x-YcOr ziek_x$|3+vD4&y#64B=r{Nhh5yr?3f{yKDX< z_t?7kpSyK0v}8bUJ3r8cr22Lk{}834Br4f*E$xR z0qGVAVZ2<}KuT8WJkws?8<(eS4c$4wJrZD^Jzt3B*Y`saskjUWn`=j-*)t|xsT%54 zH|+fmtt{E~+Y4{4-|q|d0kVi70lBB^Jvt;$wE&s;-RSCcO^sNTwhEb_Tx6zbqL7^T9H`&@fGbl>rY#%iM3fLpu{D)MzAnqEx0A9XXGLq5h6mr5!1NqOj-(f7>wTfozS6%6MNnCz5lMsq;SQ5L9foA)yI+WVfuRY)w0~68)37my zJ%aS0157FuU{TC5qZED-+dYc>2Y1fHHQcAqxGm7qCiIem2J|)P$sRO~(bJiI)u7{R zX!fy;eC18PL&;3g95tyL1lXDIb|@VWz}qG|YRX1Uk>tswLk-R=m}3-R(IiL;?do>u z9n@xbJ=VQ6n$_wcNmh0=EwB@HA}q^Mgs3}I^j#L7Urr=B;Np5yab|Baq!6%x(S(|@Sufb4$iwPxkME0b^w?|Eq*JB|N}>uqHdZ-U zXPp_=T5vUa&DWJ_n7bm#YnUb=#I(c$+>P#et9=O5BFdx=gCNG8VnhWbc()j4ADE*6 zm>IY{;E1OLg_e4HU8hzoi9KNlhwNN%D3Fx)S_FFOYP33wksrGBcLSaZsC^}tNJbd~ z(zIqKdrWs*$ZLc}HkRwx{`lOVeBs6Gl^`K(kQjbjF>t#BDQo?=dappY8O=Zu z$cFE#8KYAPg$1Vda^k2FPAF&R0+T+AYxF-^zNILA>0-R@ryV9n7)akh@|2r8QC~8aiUKpq9z@HT$YkFSa*tm0T>8?!IWH2T^m__yxflR zK1m%-G*bx3ERvd_eB0Y6hi6vz6^L2uJa*0|S~VtGmT6fvOJ0MH9_AnM`|9bS8`D9p zsN*akh=o{HVk3fOALUOW<&Y-0M@o>_8pjL^swMTTpCXRRYI{JPy$bb2fIDKp3btA8=+npvs`1sKH3(S&w`1eh|$GJ%mNg9q}P0+E%Q3b!#< zTaphC5{y#1vYlxnr4SfIP>@iM0}KaA@w|YV{i)R`mY^gm34U?31`wi%3(1-$fk9ys zCT3z~BK*L->!5Eb5BstJA{wBpWul2_LRqrp z2x^ylunG+)Z5>b>sZBA42#~Cr7Nx)g@RHieA~-1Nc(nVBq;AJOIP^U?7=^8X%Ln4o zX~+uzI|wA{LpM@dpcX}TH>QDX1yUMDu5$^5fFc(>*70OWdh%syrq_&6R2Z(ULTRgxI-TiIq!cED)zEIQ4)IIBz|F!ZA=w!1m|>U0{kp zsJ8b~vWYbVY9>rvgZ}DrnAbyeJLo!RpaBZ z$NSW^U<((;vSc^&mv>#>ocR-bo!7q=i$DfeO%4V<2Xy*Dq8RykqY<=t9Ng5N_^2fr zIz8?xIq1=nrL@#GdwRW3mm#9bvkR11jY>*H+PP(ksq5mw7v3h(s_OBf)PTW~Euo%N z&(%-vxp&%!mUsyLKI=@RE3=`!`peDPH$YR+=@+z`rD00Cj90WyYo20StJQ2x2d zTgUfV(^2MNv1&}4tdNkVPXDQztA1pEQwH-39WXXeMVux;92&V~FQK;O2&Sy<8D2z@ zOr*^qiPkK3!Il)%>^waQMO4sL{loM+v5uxu|s+r6_w5RgP445x>dLDa!n^Mct0#)I9RNYq4c=XL+)(s&ZbKCX*g z6ai%NPJ#oyTM1n7)Dg4BHd<0$#rV9EqiI!oZ_#Qot2LQiRdwuu2c|HjKl`rBJFfnA z`%hknek?kbb>)**%s{z~@H%z1jB6UVg4FY3K1LbT^mgRjg@7UZ*3kSNS0zyP3n~yB zQMrK*Zt|txnXiueDA)BhLPsJ2>RgB=ppvrKk*mXKQW)pTdhbtUobtNe()-0gXoU_n zrUjB!2CkD)j;?EI>KkvPgP0vN>I{xCHXeo~AAx9t@hHTlveK5Wa>g^Nag#9eQIPUh zPdL19j;tf<4e5Pv6TO8g>a>y7p1`zMUXBPE20A2XBr(RcXkdUzOEKEX%dS`AL?9YK zzSWrkwWj*oO6x^Kq#ryUEVjf?0;ZDAvRae#YxSzF+48ljia^pE3E8UNOIAu`GE$DO zxD>{R9`CC*G}0RRv2NO(k+q$$RT&%0eJ^+F>d$`7hr6$L9t)fqnI?6+?Yni>XOBF7 zaV6$JO2~kiTQoqXF{VM}#gUAfL@8)dF&(`-1AC9n*7TPNOKw^vP=I`5S>~RBspNS& zw6_Pje*o%$fMRy5W|;1F>^vORTUi@DXp`xfA=kI`=r{BAU!FfuFTxl=LR4G1%6+Y8 z)8%Q#6j?F2q5wEfLSWLtX+7mpwvhp?rpv(~+ZP^t~-p2HyHGlBKU->wYpoEq`LuMS( zkS390E3asHc--;00Upi7Th6q zxt6w@9aq{rXtJs>0&U0*s@DVNtZS2P`=q0lan8@Pow`^$zh2c~XWo0!m#5mp;h7$y zAxZ=T6ebO}3i$Tc#!j}N3)u$LT!AeeH{btgVBBQhV*s#LK;W{JCAdyoK`&+yMc><^axT zv3I+kpENJ)XB(yJ_1g(S?k2pzHvC}exD8-8?cZKcn&AeY&VkMg#vq#ZbT-hDbY*9( zv8E)cJxP$y?uQEFE`x&N7QmS!gYs~0&i&?%>_fKa+9)%~4_GMEXO zcf{8sR}=(v=cB@HC=(Rt?yu0_uAHT-?Vf$y^h#kw}UHR=T zF`4b|l2Gr%jhwjlPR1qM?r9qncIM&52jj`hqgKv;O=pl^f!(HG}pXfN7gqUv&pAje`G(e->awQ%^%v+uchwgf}7#xX|l}O zh=(DydT#^UG!xPA?w?Bj_tfo6S-;^Mgk7pG z+4R;>i<9xSjD7LWeej&T)EPiXQ~q3$*IvFi;g--U*-9;`7mRYpMM@plj>Qc$kP{co zgk*M^;cW3`W`G%a{jBz$Y6-2DYzwmyDw~BteQP_hQ-TP!9ZZ0R0EhuzUUmH_W8&mp zV|XOkN>=a0M49W_6SLMTa!i-+*fX@+ue|nw1aC`3-Dgsl%5sT10T1h|w6^gbK(c!G zSx%PnobfWbdbkMZFMeq^%Ny3e6ABYx61Comf*_X(-796xcHDNGEY-$++-(mtv#Ihz zm(tE^I-x)OFewk2tQ-B8&t!jC_uT3pc!__+{rv6JTp!oCx3MU^n- z+n;&8*XlFVTRoGOkB4s`Pq@y)_)VKMaJ{l;z@$&fqM?kp0c6$IWwOPMHElz^DrCpLuvpnLk zGk1MoUh|?&>nE+fA9i0`c%B-ZbMkZg{yd30>5V*A)P%GQqE*`pnMqdL<(8x=(Y|ks`?axN(PKu!l za-@`2`d0QU#zQ|S=5Tiut-+?|wfl_x*g{y0gANR-M_#5YIx^- z90Z5^?dN`cMwl1<41y3k4RmZoGtop0O@IY5OI6 zP%d49K}xdMypec)s9FY8!Xj>Dq{=Ip5N^C!HYE^>w47Fi+PhNvBLk5)-uRPFvcvdYJ4wjzkj;OOf#2L2eHcY%VY-JMkjl zJR>50 z)f=v^NRHfKZAm|cG@Bx5U=o=S>Ah$OLB8B%ildF{B@eyQLN%(PuUJ~#uZdfUOr<%z zdsl%;k#b(s-k^^D-p}N{pTy@vNbn`9i)J*UR*D)pN|E+;Xr$?%>f7E+z0t$^Y{A4E$R>V2iljPI4nk=vc3NCI+=J} zH}k;pj&~|6wcW>dyQRSv4-wheZF}Hy`#RrvhSL$5?E{x<1cG2X5F>yh()r`UU=P4(tk~-Bg0?k(nt(8iklTq_G`o@=R@18Q zgyj@EKSvLoN(yu|P!QDOjH9pJovW-Vz4d~j?%ZCDvG$ZQdhHw9Md-)!?WmWWfRJ%E2t=l87?(g5*gxdHkrh+1kFu-yt6_pST;J6f=X?k_B=(-il)2Y zLOq4j<}O>_ya7aaKIao(cZH=YWJ{!lhsDoC$XrGdCW%$sF_M{M45ZC`s^?E@zZ1(wE@qXr-xYXR%#Pyr9e)kZKEqBwHeU0x(^4Y z!OAsGf)*j!5D<Bi)eA#x#=XrVRiU+emz2jm;dQ=_uP>BhMdB`XDMXOhSn^dZF=eNn5(EBKiC`Ha74@@Ur;VhPA5c10|OP&3CfPNOVUNjgi>m05AJwr6oJoG)&$6kG-X zW|LNxhE8?EajD$<0kwB$%gb2lKo>Wcet5z4Klt1amje;Fbjf_$lu#eTgzu=k=z1{a z8k%72$2io+s`;8CplQQxk`z6WE>_oef-!8k5;!XKh_)t zUa<6L1?Vx6J?D+1-GvfKia2$HkcE9_d)dBjQ83!m!Z1^@B@4<_P$6FK_u<*ahRIQX zd2TMVeg%qy@Dk=u$5F5%6LmuNnNJ1|vPAbnYP_5`h>%1nCW=RTO%YNqm&VszR3;-z zpFHf!ZRWSY$pZRiKr1MrC7nV_Yc{(sve!?$AR=U`b(ut0Tfk3qApFS6^6k{RPV4KJgL9`YhF5vJoc1CxlbG)oN9j!cP(yGA2>RMH6M~?12!i=b~tfh74Y0vrX5Xm!-9|1N% zIpN5+XJq-fm|T-1Uto7-RY)Qr|O4@Fy$E6PqFBgBaIjm3nIWxD%>}90Wf_8S=l;LTqE!g>pmEUd#R*4H6(L7f zdq5dd_u;wEcz%xM=V~O5EbtW82}KCXZk8y+m+yVRCEgvUxO$&6*}MR$W42Vx-~_CA z;Gl$UNe=^(pZSXK#lD-O4aaVC2Pt82vv485HpFdS&ym*TK)YQ|2} z=X4dJD>r^00NA|9D^`C0?)ik_a*^P+kcS9?M=MDH{f6F4O!fEWOgQK9;dNRBe$pF~ z&$p*%0(23ue>kagVNL20h;$hXw3|*0F8+}otMHd2isjuUq*^4+lXA)f^e%^|CoR+! ztleae*X%tO;whi^ssHjF?IzxxcWjFgsO^i0_?wQlbapP&>%2W~Z}|IR*aP6uO|t8; z;#j^GPTO>51Z)$^o8b4g z*h<-f7(DvgU6HDH4_z6iUaOea4J)$G{dB;WWTF6)faFGxD9WDIHchFWp%vz;1H#99 zhDi?^1TT1f4U`_H9KDJ07@B1P!%vAvxkC=GV+u%Syjkso4PCH z9W5ZzIZjO>1wEpMh!)W!hhBE?TJGNUueW|&<_kDtEyZ)rY9Geg;&Iw#KflJm3_MGp z8v*&*jVE1O&nM4v>)QPc-7};dymFnMf|kU4Uc$sG#eF~$h;`Gbv-(i()zI=o2oY9X zPQcSb&v}uD1BZxCtx0p5ix8xU#cg%MZcM5 z?R>$<6{q153Dn)&q@hE%ATi`RqN2^mF5Rsr->s(PoQ8qKw32u1j^!zn43GloDs?2O ztD}}mC%sVsmc|PTGJb9RO%GsKoFK?PO-;3lKfqzwnusK%NH}3Gju3k zQ$os~%fZIAY>u-oP2buU%!3s1oA}%ZdZ`T`pWfkvpoGR{YKX_nKt~WPKm$$y&M*i6 z*{CCB5Ks@fIEb}`1+;`cFfU^QLZTH9ON%gt!)4yHgAYxgxGukgnKhPEq&VYc8s}~0 z&GycB9*AfKDoULJ74^wf-FtP`x!jtLk|rP_OC_KM7uZf0_DsW*WzYq<<L2 z!T~^@LV5Fg4(v4wp#Cp+!;+K^>U173Ql{RkQkJyHt(hSN5mbO`6V!2W9Ehdu7kShF zf2PA&hBI1(WvDHT%G-UtZh;pFbvYp*>MLnEcj@1>m*(-Zo{&vQR;f=IPE^SVKp`5B z-B`}SIQX`YXrx4pofQEDMdPLS*2ke$P<}|g$#Wu79-d8tbLvdHi?gfU)%Q4dZrePoxhY< zIC8hhtP-tH{#E*Ow*omA%%O_9jbv%kc27)w;-iy11RY!+>{sZa=tJ^?@*!{U zcC|m;eLmX8DbIfmK;Vlxwer|&xaGb(S>Da)CLNI#6qV$vOff}8<`Ntc?&;3VRx^$C z5JfRUWF+aOzipAff_MKuO$|JkWr!FyHrvN>=LC#Ek=lWf)b9?I2nY#lhU$*896Ef| z3~_-^)W#*aTu=)Ex=r=Y(ha*+mK@^n&L{8O_wtwCy$68+5d;L0d_Tuz*FchX*G$%_ zK13!71ktnUsR~=l3%0hYRRKC82C2Gmnkb&eesw<3i{5^YhgXgl%p~)1Ag*oAI^^@b zu%B1U{`Mh${;%7&7u8KKb{6FfP8+tsT4eTBV5VQ&_lI(rBOS3|`^-1~>7RSma@f%R zj2QLyjouy0(}a;Ff(+N%4TJiO=lf>V&EO;JqZ7V`vqmo+O;BDeoh557TGo8w=Xhvu z&_NFtUS$@JHf_bTD~L{{MBAE|8}0dM4#TE`lmrd%N_wmMj_~X!oe%fJH^%4F3HA9H zYu0vY5ubSur^=V^{C=L>tIQsLA0bEb0ECrGw80Yo2Jatt8=%rch?a18rYvCSH30>h zdBTTV|6yU=`aYiVKYw!cGoJF{p}`{A;DYn_9!i)=uk*{V>a;&Df&Ji5BO1y;Mog8Y zOmhz4JRX=_HHQr$7kjU-PxcO6Kn4{Vgb&V__MYA)r?E74H_CJ0efQU%yX#vX+M6L7 z30P3px;vmqCY$DluWv@>Tjyne;hlct3$jLU*~oG7hyRnkaAUp}V|Dwy1PKI?fBEPA z_xQ~t9M56V()0GpR_D#P(ot-$4u+5ooFh-ggPd8dJUL3=f1S)6i9KXMy?XGABt-kN z0Hp|WrNx`KQ=IZQ>-8yc2I|6DU5`m^|oYmh75S`Gle1~FvT1RW~aNTYf zT*8RdMq**?zFHYlhEc%8}{ z`O4xwy+o#ZL9b+e^})59^V3JnF%$qH0r>OZo+JN>;IkJ9)25+cP$bay=B&XHs_5Lj z7jYbM9yxE{N;X0WxJE3sWUVzDXGBx#h`5KEs8{b!h!AQzI*v^%B9PCtaC(~-7r@+9 z1m&Skc0xEb8D4mkBNB`X+8+mSn>th|GC|YLs)>nsW53fiAx=_ojwoVAuRtZIk_;O5 z2~k>LWmHw03daRAK+DrCM-~?Q*C9_tuQ_*KD%KK&T<9L~5FI4aoM4pf%{rDo=$3!j z_y71=-n1gV;a4`-vk+lfDwRo9RyGq32`B-OAk{-pt1Nvqtw}RGLHNdg*y+(atq;vIJz{_!Z@bTblN-BZrm>b47(A*-2})}ukx za5lssx&r~gs1=m<9%lgpqoGFH!?c`=BsC+VWB{58MuWkmr3am|Zq0(ynAdXcCDD_* zK@?-Gf+8~*GQ+VM5_Jnw_mN6pET@D0DZC5n=7^_AX=TA7Q05f}`l6@E%xP zy7}IucthVS^WHqsZn^82HJc(i22=xtXkzE&a{HzFdo2kFGXUQyx|W*VP6(^209(xebJ3LYPN z8xgKP0gHFDRLclsy2ThocvSk!;<~Rl#LYo{5|iY(-nI?k4VW>pSC2|=h{moxbJ zsjhVk_e_||iPV)S=BRmuxussrW9X_0Ne0Us$UWaD?j+Kz{pI zk$=lUxfoT~H4n!{XXgi?*$WN^y0wJM%c^l-PRS|WXj|e?g0g09+jO8qfgKYR;dw6o zb<=jOQ%a{>qafjgAR(vKJ!Fr=d-71v>-8)*zpB^2i|Wg2Owmrb{?&hd4g0&BxIY{J zJ^;lcO6;;I{xm=wP2-;Rw&x}c8W$KMMx@3E8278I_@cNp@{Q6 z$5k;btdvF;!<>(p5C`KjixvUV(ed62q`$(l{gp5KRHZf>G2DnjA9Cj@6A>i$3d;m3 z@oVJBZ+?qDt)AAr|1RC93MqK3hMb7bNtE4(YAAgvyhkKua%g9(W&jy!xx`d6mq|oW z<}u9k#QxVUBeEVH&UsWKde2xBS&4$Jqi1%$BRkvk#b>oYD_eD5H33bDil3T3B5P}u z0IF({2o>a@mG51-fF-p^8^&86*XKeve%Ri}{NsT6e7D34=NDoFEyB|ke8a6D_Tt*Y zw7l}r%g=3e=cX)R$po9tZUJ`~^{@RaFV1~jFM7c|_dIXNaeVXT554fIUY~A{+t=rp z@Gt*mH2-uruTLhNQR0ArOqPyvd&C@WdVfvlg_50G-tT;S3g7!pOJIgXWF;WJ4VUgp z6i}q}c0TNH`P@q{rd{hoi9yyrUDs0wy=pBm0K28}U15Q2Ft#b(eK9N4(G5%#W-9 zbR;|=AS|B0>Io+T{^pwx6u5J!Y??N?rEWPr)k?7v4##KMzQ{d0&!^mPviFn3_YKBS~Q>vXB1Klbej9sEe(o z`KHf(*I)48Io%;5Kr_K^_lQsRXgB*)INm9(j%OU=A)Ztbqp_mk)0g~AK8!#7m{jzh zSuoA~`7B{;@ws3&*SpTP@+(&l+(7gmiX9hwHNNX3{MhZ?V+djPIb)C@>OwzM$P6&)_zyXVMg@a}T& zfasl$-KjD3<~e4JW#2K$>vkiTMYMPx$41wq&zE7lX7)Udn9q>kP5Aq1m{GC_tLLWd=0&r;J#OBJQXz)dm2qj)f{jIo^>6nS7Z ztQF|(t+Jp7RGyWzhGLXJ_}(m!ngF3jQZ>fPFicjuV&uTCcfQEvQ7oW5$#e{1LNsIZ zVD&aO3=&teyDKx8Zb|acO7yCzgQdkA=D%(RjE-=r1CBHZOgSSO{NSDsFSoRS6JA_u zdc2%CyF^To?833lXiwcu{HcsI|9IcFwh>nIvpkzfMsiBzP;He9Ng1YyE8po;?xuns z0MhEt^=T@ewHqg`6wA2xnxS`-0_REorya?MYVjtPSvaUeZCeJA1{c zNFs}pH7CS~B%~n*!R0b#Z5Y6YR6`;~YDABF+glQ#p-;DGDu)mgFU}|+kdRkLg&w^X zREnLrwsm!-zg+3GQHi*tTF-`{r+j{X5k^ag2x;ILMpEGc4-uY!lZT$)9bzEOArX{g zbw-`O4NMP(_T)9hTbINiY67y}^HazYROLk^xIRSDKvI{jCrI+Gp%q((x*{rqiV*EO zC`D81u|`R1bRBcnu3wIq6OU}tp`SZkpnhkQaL7NnwsA;Ix8-|5TL6xUC%neRab{x= zZ0aHJt@)A~--6*8hyVeXAdrO}LIUh~oza%NHK|&_@h(}>h*0&k3%5-XE!*Cx$l{0= zO?IkmWY28^B^^9-ILfA2Fc}R(1{je{#vvH6+IRD7(gdm7+|Ewq##5v-X4{_Wl8q#n zvi3OgxE!H$uJoiM+aQ2aN_P6dk>I48&j* zZ9RgBAkhjMh{wo>w_dcj=}g~x6xTkB)Cp%-%yLl(2;ZIZDhrYqqBJ>SR*O%*`RucW z2%?rpE-tM;IxqxQVT2f!n08Bz6;Rv>zvuyvs?E05SOyBi^lT+sNw?IAgHG3Y_d3w@ zGQu*1b54nvOo3QkeD3*jo6-p>6yYr-hS*)v!V{XiZo`9XY=hOQLsZjtS}}1#D%7T` zzo?3R?qn>Oejqo8fE6}+ek0O2r}j3h0V-IRsF<8!1rTuWv~KB*VoFo&tTU48-l2Ui z$7&U$pshdWsMl-o_5CfqUgnH$zQ7;zg1>3?ry0z7$Be%UWw9)pK>*<^k}O%&UG4@n z!5K(dzi7s5h%<#)MATBNdQXFyWX}XCu&8`bx4u4laUHwk%=u$)yY0}PJb%oW^@a@0 z#XXxjdE(Rt6~2DHiyU=)jw?sjH|8&6x2!e?3k5(*qkxyj@Xd{UsqE-dm2s<=D39f% zk_^0lauDM#ML-bgaK>Cm)zRv;Q2E8e(iYJ`=7JNb3JO=F_^l2Fl9Zc^ee@Hn)guZrTJ)3 zZ8Lo}(mv_=v(I{9HG?DhWHjK`9J>)PeMs4He)n{aubVe5he^j#U*1Vf+yeG}yM=75 zL^_hKUj0T(G^-ndB~i#4i~rnpSp#wOZpt%mMg$cPE)IriU#>MOTDhw!-DY^h=F2zp z$0<6Tx#Wy5h@qA4HPeEkNT<_My~Zp50S2c_%!1KRuoJ6 ztWT8L#6UPL2p<%nEY7HNj%PMVO1=RCQlL_jr2|1yt+5tT^@Kcch=ZtjE*>v2$O8a) zSb)(ga=xHO=j|u>vfDupQpa^+doue%^JJi|<#H>LO)rcmiKMpWxd->fdybOyTsn@2 z0dgRX294SgR&QhlF_M(DB7ZVF>d2KsUve8tpT}?Yz4qp!&foULZDMee#cNOuy3iX% z;H@J%4TC9~FMJ3`j>#x%hsUd;%_=5nm>Hsy;bdrY;ZSM|!IQ;tD*9CLMsen7I&W+u zN{+a^sYz|`x*he@;8lag^KbOO@EN`Ne&5{>0L8A=PtWrQ-`87V6W4*HvFA+T!Tnkx zEIlTzYVD=m9yoEMhHA}J^NC4u0U&{8K>%V#D?9FtL31fd&MM(#Cuw=@8fR=yOQ&M9 z0;3f`P|Wl%{>QSboRaH+6oHdDVcv*ypxi!Mxp(iu^hjQG*T_?}w*l;dE1b^JhacL> zNWp0#g6wjbIRmEc5mqZh`D&YlM69q*g1VI#J zo(|WSj;S>|PqVAEp$l22PlG1A*rI6QDQ*bw+5QND0Ku8i9pM^stPN!K0X%SkpYX^H z*lo~J!iNCKdO|@2Vcvss@sHCk#exJfa&0yorNTzu5t>eny|$Pwt`1u`YH*~Yn2MQ#21V<}uw*eMK?K;YH@j3y98) zA{Az-1-(rsI@fZSR3wAGG| zBAo^cvYk&N)@sv9%S)Hxy)HZ~1fooYAf1K;6*cKdAeMAqAi5?+iq-Agbo^~@ksx1I zht%CGjetV*bWb$S8O9hz!I9V570IZGa7y8xC@nEkzxKwIL$)oU;B`IGM_L7EyrJ&p zjBgzA;#0fUe-s1(5CF30f9Bb6-W#|M^&0454Wwvw58doMT-_|S)oLws>gdBODa_CH zbgUCb5>>Ip5<^F&ND4^+Nz6;%tS?_*iOU6v zJr81mx8&vDU{r6#jvNWlHVhy;L?s2!y^jveZ|mFuv7JVOTq~%rrTj%5*{;*512vfS0fzW|x<|Dz+t-h2iO#O_Yhy**<#?yUhlD#*F z+L-K59KK_Ma~ns<4Im|F=X_&eVE{rho>8flYJ>Uozuv4Y+mRz@HhUc&Y`Pn+<#HLU z8pvdd<=5!E)Ha})3K!0|B|9^H$DoT z7_}9v35_90%1h5a{#Vb9AN8mF#(bP93~YEm^qeiE1qBM}AWfkVlrH6%DbH*^f2VX? zd&ApEw#-H`CTV%`w|Yqd=Ce>nZ6srCr=@Q*2`-gC{3 z*)}tSmIkv$ct)SkN{;n?rhKSXA)B`US_K}6pwrDHtJn*4M|1{#z|HvA-8t+ETHun+ z8P7$8ATH0=vyTpH#4qXq(Xg z=T8WcgdPagDhmDO>b6f_-sYPqT7jU%*2!gh3|SdPSnl}k5&qKZXRhtKnkx_26onbr zU1!eHIqz+t@PRY#3NVp{Y&JAIpZWE*Zm*m7ulJaHMfJ?D21Qf+Qkt^F@lc#KcGQYR z=X*Z?Q6h-*wIE68AjbR_?HX|C>}&3YqJ_FoHVZ^9#&wUl%};*%g?ua@6%qthNyiNh z8DLD;vmy`fsTVgtQMxf5NfxV(2cnFkDui|O4TRO(GlQ_)wqVF%5l2Rmm6UfEjau?2 z+pu1X1GEV5jY(&U1d3S!gP_$#se7wUh*~UJ`S?R`j`y4UcGhI>mx4rP#QV&PPqalf zEszMoqRCpcLzLNTosa&J>o%>Hmdf|vKA=QaSHT2zDItoA^DIU^($&?h*A4_Vq+*%7 zXaDHEXEC&xrp?0>r{NrMv*$b~i(R?pjs<{^GxJ^x?)Aub>5|$Ag3&L+Yed$1^rZlF zt7BA(Kl0l+VEnA9iy$d(>IA6!?csm~ybdjjIWjx1H4p5MvaBnNjjU$u4bXrjcP!(c zCIKmy>uqfkXQrGWlH!R}MLQbQQV6mVMIKJaEfms@qsW<#F&ShDc1Q)!T1LBdth}^z ztf8fP15<42Y`9oNG>nKC6L&`1iix#?)tgDkd@PdlORpB$=@lhLOlP-zq`8ji=Jath z9CVUh!J>9H*}mceipqMC6;VZS57{6*`OlTlX+F*R(I39v3AAigcNqzw@L*K81Os8* zWSh!S+MO&@*Y~9vJap~c7tYB``3g|%Dh(C^YM23Mow4&Inf7gWH);_42|@1Mmlj)g z`AC3kWYfH5ORs{OS}o29^r zP`DX;uf0Oc7yUN#q){K6EREVkvtjP6Uh1dA{^KC6T|C8_XbUpPz=+f#4_Bl}&Sj!Q zW}4=x+nPw?9cW-od=3a(QN|pEd03|^U*+7!*o+GVU4Fkoez?==|HxKsGTOJ%$ohbf^YOFCyBqP=z3B&* zo;)18tyeg;C!ph^>wY^20!j-vmWVtM&hon5+-0#m{I+*^ zUDO6zCxu`F8IXj|dq^PC48WyB$xg_nbl-Oq)gMw%!_Nu-_jtlahT0MAh``{&NbSk!a{8cyGg2~2f>4@OP zC_}oFq!G+y?_KtAX%qvTvql7Kw>T;>vyZ|MMT+H=I`3sx`8Xu5@;gC&YR7(+6)HTWqgA=F6W+ z^4h&)SWo&Re-bV5<86VIMGHibU-0Cod&#Q$!%^pT4E8q29w6eFIqiwZW9qW&4wJX| zp|R__xjEeJFMAfh{~JN07CRRYWj%X*ZBe_O)cjiW<1C4_y{oz&N1BEwd!MAN_x6YO z@iKdy^}2pd4F`98U%|4+2J)KCCh+k>&!d5_&D;YU=g|MW%HvJ&g_n|JDM$$u#o0|p z*KoX`=l$(|^Ud06-W0Jxb_cpRUwiG7OD|Y`$9*4{*AT<4=zS8aANNH* z-xphx<$aen1;^e$w&g^$t)|OD8C=r)@r|J-$_SoFPpS*Al+V^IEgh z$?dJby+sS&B!~_n!s!#Xq6VW)o*AEH93ChWIVG@i2mFB3pAffCfj9(1ggNGxNt=#i z2+{XcEXv~qnwh3|jjt1iN)k{cX(;@l*v66}!p)R=Cz-7&d~N5HJ7Y`Mbx636Zo$!l zjQOFPYgP|CJV;dxfGtOgm;mwC-qx1!$Y`dc_R7}8$~wX$JSUi^*dC0jp~9P2XI|V%=?2515fvDXK#d#;iprHk zKrVE<6SB{&eRZ0eehtAju}!_M;Ipki?+2z2e3iF&8LvoPAOCT0$e@NYFc$I>@O2Md z8`H94a4}xHZr}0S@Xe9)ww_gx8}m_pU$+oeFWGz6?H9jA*9eFqs3kEz4R|SQ_0)LN4Fzv1wv_LV)-Br8Ak0K(O)ZuAh zNLS&%;ID~hh?|ZW#H{UgdF}f12lLEdhMs+=c-&hhsnQw4J!#pNufyo8aZQh7k~Lx> z5sV`exvasQfxv6%yBW(%%}_yd5dFWe@}GUFKw593P)@iZEDYc2anqMhaE$pG^6#v( zWrjKu`N|=$WEX>ET&EW2bINby=u%d{`JFgolM_3U<0jCixn1lJD-_smOr~XoarLm4 zGV1agW}`dYNv!u$ZIOy*yPytL;EwI6=-CUx4pn0iyONxVLx=31)q~vZQ!P5KM79~M z^>{iKzK>kcX%44s)VpJ$GWenJM4LwKiiJUhv>0tFWdv8u5#j3WMiT9@(lxz#{x|_o zKuu{T;i{j=Id9VK=-|+HDeaut`gDJZn~zI-K4xredsK!W2Zw3j1?w$othed*0lmJm zVxvFeFNiSGOkml4B^dOM@tlkxIzN`VrC>bYHN5>my zfd_wbD<>P_33I@&X+Yh_ba!KJ3HE;c%Y^^B04j!s2oN5)LHAkuyMVp_+ z64c@f3oqU!2ES+JD+mC8sE8mz zhhVpReC$a&2sJ}cvL&|@20+`ZbOc*a#)GQxfhXsCe~Zh$ipOJK_Zyb2tz(R52PGB9 zfW+;Gf)cgWJrH1j{Ne(;#i$W*Bw=N7VvC8z)z|WEV>o6MFofws z`2xix4|^@j?ny`KvsW*yWyNzv_4K0@Ms!73G!gmvJ<%(?!V89E=~qyfyLl^+& zJGFA^+{)8-itXRnZ|u!GD&gA1>gtF6#Ux^4OPvBX=js)1Y@WZFby6;;F&zC9`ITo% z&+4u6;ARpqBgNMsuOpU%JDRlRphjK_LO!OEB$BYBO7IuAyN4i&QY=6B+-_~()7cwD ztp?vYZpl~EdHO^1eCR`2-XUSyOF{}#9}io-8L(hH_#?X9aQ)Kaxr)oYiA^r$GlY=G z;yU!!AN1bWp|Ws{63?B&HL+|)5bKjeskYUD;`&7sZNuZfg)6T379Nfd59F@7-6_-d zfx7MB*)JQ{pl~1Q>9XA#AJRGwADFOuAlsWpw_k0Cg0@M*;ctHT$h~Y_WS-^I8S7RIvHEu@BWBd0L%v zemgPux@`=-=S_l-%~o$qBEiJ)<@$3)=b`OsHtU##DxNp@YtO1bYguN59U+vKgq!lp zVH13q7}0nqW~)1c1`|7i)&xG@ro{^mb!swWTfUF$xcJZ2btZ%Nw4QNx8=ie9kAMdq zOCwb5kv9)F52ab^5Y`r%<`X?~CgYW?p=)DDtjI zEkAF6pQE1Ly$g}bV>Q%^(xFfQi#MT+z$I1srj zDP@7Oio*~UC2o%8LMw-RpZz25dUx`o&0Ejux$RrGw$ko}vAcmS6yxL4xRXXfsihH7 zyCt#PV7CBI%C6RP>zQmSTuK-m@1nN++5W#aTR!EvK8?9<)+TqKZ?7Nv^LXw{{e3p@ zBb+^(wNEZmyw#mrbe)?XM$HxtJ8{4(iI96dTHi4)1`btRxYU{6I(D;S_w=iKjvTgA zAe#WYR+n}q5UWc`DYt)l*YyqSmhNZbh3EAgZy&k`qVinlY@6wpxII0R?56 z8I-P}DKMe3&Bset^FzZm`ccRwO|@L+;e%`OI*wvPY|W9=7Z{Qk`ZS!hP3$r-j&+!B z`3?*w-zx{UHitf8?=;8>*27fpJt(A604SuDnu#QT&rJBC-H*wzhuy=dRM0AVbDd)( z-7~y7Sg(Z*;N8oogFX{y2L+}j*L38_gC__brRc+XHcDAdngJ1c>O(Df&9j{DZ*qbg zh=@5V`(?^os8`5tQd_j0wQu{}qz6VG&+No(%2BWsH}VgSKq3exj>l@!l4qhKyL*a) zF*}|#Vyh0mCwuj$?Ag@gDF!EB-0B(dHvbbX`pp<> z0Lj~4y!(xnRi8XJ02GXTQlo64$}kA^+J$t24tPYm&eUDOMfs&9&0j<`5UX+f>q#dY zTywj)dn0rPVmS1kQBp;Zmt`Ty%uH#kHY5jDyEELO)_BLMM!oU%%X)tIi81NCVNNkX zMgo)$zPuKNm3%ZfSi>^xcEuij6xez3SS$*kv5q>L57omvs}qRn;X#nLl+oI;BhVlu zje_mzkfKaVw&ETp`Gl+pgDPk{{Zvm^zPa5W=EoT|c`+hM^i-$p_I>wwU~QU7jSPk2 zwy6Rsr0upE`?}@4TCLup4O0F$W^nF_FDs(TNT9vMtIF&(Gt_Vq9R*rny{8C<8 z+N07`Itqz%>QZpRIwZF5aZftE7ozoLF_VZ=5t}LOkGb)v3+g(Ey@RAnyF`D9_{#6h zK-7&85yEo@psnK}x`+e8{(}1s>Lb^&v9hEKu~!!^-0@+L^mJJq>2Y)W_GG^IB{IXs zpopae-a}+j0wJ8q`t-yVKKtw6N3A~a%H@i3;ffhZkd;7=Wday_g0$#T$V(A52Qj=k z#N;z+Y1y6l=pEWElSv#KaP))7NUmc$wob$cs<1Twla7uC- zyB4ON-V z;|9negm|ZgAu9-j^$cJhWrc$SK>T^hLFlKntDG<;Q&_LN7IiHUvH-i^n0`_j`P**Y z`}pDy3ygN|=!$%v>pJz_edXD!{61g)SdDg>+6mMCK3o)~MvqAF&=*{ouf!Yj9=`SV z+pl|_f5&ogS=qeMJb~D59sY1AyIr$7)r?xv)YI=J8wrm%LlOZ&NseMLn#bnfWcAXX zxcAbM&e@9I^ri#u!W|!f;gPHpML#lUhYo$NPx-d=b|||fFc^PCwe_BT-{KJwgn^+6 zpC0%c`Wv@9-F9>Op~_t}NlE z2$}nE>`KP!L=KX))t1-{&S<>%$k}ED!LD823Lp23Ev^Y`!)@zKhi95*Kk4bG82}KW zOr_I(Ew6k>8h6eUIipHw^6T>jU)f`v;JqzE)atD^UF@fs+w_3WI;hCA{m_dJ;qJ{N z)Lt$S;V_bYr1tsj=Hyy)-G`qH%fDQtsle7uo-V(7pGe`2w2GkbQYkP)&W&d=R=wdz z@4azZPG-uUbhu|Usa zwIqTqPwojAX^B`41j2>l?#XGZ8ygIJf^N-R3aB3E0B9=x1lB=A8G+91vJl9$!r&Z3mu&ZL6Cok4u92bBQW79e_J@mr02gJm z3p?b=iQ%)z-y$HU&_WY&D{WiF;k_xyNmqE2pWTm;)EY^ElLN3c?eQ{C@s4LBL7wk) z%0f!z+##yKoe0r$pvPr}6=r?HU@~O1RAiqWq`#E~m+%If6g^;idXy4{SvU`yJrk^F z$%Lu>$Rm}MX9r?}o2{Fawh&{fEOs=8jyB17!NN?2Xo>6K2m4coue5-NBOM~6A<(=B z|Fns~?YKwt{jJI%q?#i#@ScTqsAD2h*X{!{vY2O-5~Wy_h$M_+sc+JRfs9N@_l8b5 zWHTZr8Y(LeDYiv9uni}U<_Hk^w>y z(Lxk+0NOUko8$WL@Psl{ zgVw$PJ3z$0U(qG)wU1rrd%j1Kn%49;Vc^Q+@s{nO07KhZjGjvc1HIbv$ z()(N0j&(|ih9sGxd>a`w_t;zo0FfqdbxbK?W=X$-v*Gi3rK?#$GQ%-?2)ICOHLF+< zbFDB#DlU`z^4b-wp6$ymo3jqZJ+mCucwCC17v0K z1P}~CHIjRyL>^6J$5J~oGlM+FvpvuTqJf#raKeraf2q##=kjj_#L_ZE#B#v6MV6PV zODX~yRNt%VTC1ug65LU`x9W_mtkuo##jc$P2q=Rl-WoIp&LLpTY4_w|x`tE%7V6P* z)jaFCV|}rep2w&C%mu;87*5P|Crmn%LMf=9ybd+2z@%Wz5#8G$SA;?kBHea>id>xK z+Dg!Qap*cGByx4+xRmo>k_>9}bhLUCo?FdR^zH!CL?tY!YqXektmER*H&3tTStVs)&vXvkbDNF<#Ik^{v{R zNOKxUB(jF_ZdA53ai0U>QsGex5C+&lmq*w-zW>_{a{>Udvhn;AlkO*H06Van$03<{#?S{#X>5gZ^ zOJjaKZf7!0l;=&Og}8>)UJ4o~(!+Irv-rB=%gbb%M?|&gpx7e=VH6z*jS5FY_iAid zm7WwU4F;)D4-!~#(^<|dw3stDbR`y8p28WoFeo&{)7*_%m0I{|_t4q-h>0aSQYNt^ zv1Vuc(s3m7(%cV37zh`Qf0KnDj{miJ)Dl5Pu`=5H@V?cv*E~G;w>b}E&fbKckr;)5 zBo*`Iov*J~O}X-`$Yl~Fj#LM%qABFf8sUUscAXbTky%!OW}KQ?U5@7^!9(Dhj04Tc zW3R=?=IE56LD&)jq1`QT>|dP*XqCWt$?F+@TE8Bp)L{Z@GW%O{Pl zw$-j#vrU($O$(68@KPncuFUHDsT!NmG;Tihpr0G5@2P+DeMrDdKVQb!DZW;-bV6tZVp zBMH&Cn3fdi8A=LUVNkRH6uaovc= z+wyMyy&rMtlU9EF1PKpF3qdyy?vL%{lGuBU2uVh-$%IGQxEuS3=il?aeBt}t`~ahM zrKEep7?Jp(u;9diw%>HLuTEW@bf+QK%&v$Qpfp+x+EW7{fzR#Tx)+b-_>1T3-s_QI z6KUJjzza}{c4nQ`XWGL!0?XDo_7qH*y|=N^P#Q%M2h@w*?VHM01CDl3ga|@#Lc=Nn z*=m8OYbVXMqA(<`u9$8>h>o&bZnu(1uJqCn65x^#;XTeTtTUWjPd?|s>A^VmnW?#> z-oD7s`yKISf~hr_PN&lrsCSs1Xuevs3mtFGH$`hNt;rqSq;LaN08TCvUMmtw%GtM|L)#bP`G2bqouGPrm)0J>%ZWRxAJzHD&ju?m!d( z=bV9LT7h!9KWWT+;{ zgTA~+vQm-V?Y&i2_cpW>B^13fO>{=MAnnyLFLTMycp!Q~zxW{gR}Ihux!+M90paZF z8bs6VYu2oI^<3(A{^e>z$V+_HGBnUhE`g05p#UgQ_H-#yxP16xr(1=m#*6c0$OIZe zibHLEx(c1WZ-9CAz~uetv!?1p7)|QU`R1H~Ma&Eo@r1CBA(LBqhjC(_hW(~7H8P#g%toofqcpG41>n>FxFMwh1u>d)LHLNwDRT8Nef2uG$j z==#@&I|N|}Nib#z9fT`Xl8pjG(Tc8vXqF5h9EY=~={-~mVF@57rMq@ymdpnanWA?x z76Sx<@TdqL&EC=N=xA|d9D!5lmjO@^1Scp465v9CLNJ<}x}?U$gIp=oW0&z!uYC4} zW(Y=*aJUV&>%GSz5n@@ABKvpuN{U_PuHM6QL?_a`{doq6sHCJelR@*oJCwKR-4TkL z``rURZo{yLBvMp}1J*c2%Ev6ffV(wP1aVaAT|u;I+uEI-Zlh6TL75@gLSu~xFMsn7 zzJPnZoHNlcDob5g1tYIfTM?FX$MD6Bp+>glg#LoY+RoJNOl<=hl~m0h z9u$Bi7{t=p{=zlQ4i@%zs-GtBMl$+a0i%Uz0YcO2BvqDQ&TOBW7efK+sL)Apu8^Tu z^@=3~WPJ^2?j zONrK27NTW4o5_Kk%&YBEbdk1LnK+qTMdq^mXI+yYN`SRKtklgYLf1|c1(nU zn!Uih)r~&yrdL{MSwNtLR;guL%~?WnPG8MX`$(?@DqnL2VlbxFneq$>5snU;!q@%E zz)ItIrlpDT5GAEU1W`4PJrm0j{X}#G{Ln{+lL>Pqkx}S1)5%dff0%Xp;#eL>mgG8% zppe`p8>p74!&@{oq>IzMGMD$h2W&nI&$c`#u5M$peQ2ykbZ2I6cy{u_@d(U|?fL6X zR|*H!;{VZa@v2Y*E`+Yj9@*al4fz+xkmNXJs&rZ z&$kN%1b~6TuIHTVIhB~_IVIVXqh`c4>s!XheG3!*aCvIt9_sA10Z`84(Zdgu3le|r1%)2O%a z!6B!WeXcz}3iA2%`)Pi^zV~;Y`}TFW7jNJE&Kvb2^6;4h_ky1Dp7uFID2f5p2*g?o z`KwZL6iJFEYH2K4o*s3K++l+Bsqq{7v8DSsujj5j(8oQGXcifVmLWmuQNR(f^wvX( zEy+SmM&+O>p4%bpm({au5jC<4xv9Bld>)7PM+bP_Z~A_*Y>FUIs{tf6073=ITpo9+ z@$`9_$1bcf06k+;{(8iTF~y2Y`V`3vWJZl8=QiJ;$Pp{jfsMqd6H6lK?t~52%3$L4 zK)abXjLp-i^?ZsLb*sdh7+SRzrFmq_o8m)1^xWCKUlu05ObrfO9P(B>ZXyG6S1UQ1 zGor&{w`QHqp76moZtU8(HxGTOc<_UY0+L)ns(>6-ap?EVFf?8-#~s_1s`z#{E>65? ze|^;Rzjx$+ZhOApobx-oN4)*#w^~1bKefO5ULWJdA1{RMMpRQRGD3`m1##XAZHOtP z8UcB`vv>%uGa&=P8(T~3!VZ(Rn<%?K{NzYWD~1@$`9n4}XGb-Ys2SgCCxHkk(VYg7 zVNFC2t!`Y|Q!QEhquIjP@VAuY*|YbmUH6;w@Amy#MmyI)0J6*?DXRG{)t>h&-{yKA zoSXb?KKnj|)FYAP*CJkbYMGN7pa1OiZNST1i8 zW&;TzB@#%O>u49W)dar$hMp29F?O_rJP$&Oa&Qj?JJ)VULwAOtOdtRxfm1?q125=J zVk0Qz1LTobXW)oJyVl^x#pAooK5Q$G6ZSIx8A(c5OTLypF7R{Vj zYgPuVXX$W5nr_Ks5g~|LjkXS^X4+e_wDxL?4m+390waS1LV>jbaPeTZw@0M*iK%S7eren0EcH>!zj7garFGzLsv}sGg>FKHKP&$=W z0}&B&iXgc_3Y(Cg=oJyos_impdlJFP|318+s=v_anzPp8yJpD`L-(;!mbIIvPIccz z=UUGutc_khLBtT{eTF>gKu8gHBhg)#1V~h?BX!BPV`mFa8Cz#o?1HD5Re7P* zDmXK%Nfn#A>dAI9&T-ioA6I=kI3AJ~^1-=vl7v8Aj_D+Hk)9%5B%`%VX1kURB9Yji ze;Ml0MJMOyollPo)94vdEEQ~|ZVgHM&^r#7)ej3O`t-3L3JUMLu61oN?L0NO)DNAn z)@;7wfIjE32#vahXiPPMDD0RJ6yTBwli<^&jx}S0CkSQ6!4itBti6;;9g5-#5Um(t z>0NYklxc+OyI%u}t3zV<06|DAlkP3yp6PPuIeSqNz07zQBF*WU9$3&6>ZI({3?GZS zGs7*94oGVFX1HQL;m^?ZJFTm?97VdU%JW9bn9vJg6uUe|Skma|V+ppRRxeQu;D`az zp*VZn(sVZ3*_ZC#fXp~$)}6{Gitp3))JLAOikj)1SJ#>O39}X+BjePA5KOuONGZm+ zvJMe~(^lu=1uuIrJzTK&x=VdJ60+s#w!y&!-tS4Fo#)T$Rae-ZaHAIpr8TwS9o{1? zEWk@H>fHS6wR3Gazf6;er$Kd=Wy#TxT%vemKvUal!Z>uv5EFc8?sJ={9t}r02m^z| zXX%{_m#)dVI6#n0ICwR@)rYy<`h`ladJ$&A|J4i=*yXuklZBCuqXL~%$3)JfYDg%VT zkx0^WAUoItZSH*8Yxc!*yu0y@2fwjwsjvihpX8GX?>37UE^d8HG}1^%7|Te!Q{T-` z`i-kI#L^G!KGWHoXM4HJ88h6sm=~>3YW>_xb$ zhwq8EI`4>j-(q+;U7$E=bj9^edCR5KVKKvqx0z4F&%b+onSmZS>wv|xLBCk9$9bV; z4n;w!yQ+mldP>u2N%^StfcHj<;<$-y53A_=tL^Xa^1Ln(FL};~y83)Rxaa&0{&R}m z3wX_@iP}gw{Smr4Vy{-WcQ@hv3pZ19?2?`PB!Fa;;~@GG@{ZlMbiXzs0KT@w|h;{>1q$B%pJ8evqVDu_x%n5-hKkwlz;2zh2NkN3;J z=&{0tM3uZ1O;*|Eijj`P5MiY(Wk(1>5QST0dgQQ#u|uCF1ZA(Y#B?LAld@s)2Yh!y zLbx1pM*8@5C7X6)6ioZGV_BLPMq`biJ!RgsVpH*ArN2_bgQ zI8ls)Dq~$H%EBEw;N4Psy1gCgzAz2)=QzSWn!P0-<#R5WWYPL|wc@ThBOH2{yq;XG z-Q$AW?kY)~b-iaDD8u+!nUcG~8a#E4A-Ol#Kq+Wp2sRp=?qEZB41!xemFAI|2lah!(2{8@iSHjJ638 z-638*hd!2;kJdrR>#rdP!K4$llPGcCS}p_?)QEE zz+++W2@3m~D;TSxcaSx(?<;P?VJDIgPW*CvWUgmngvtVYSKD!a%gyOaR2 zvvtM;crv32;>gbn2qI(`L0F5AFnSb-HEWA`6Zbxl8P2?lQQb+GCXP0`5)pSdnnFO3 z3y3ZON~BO0)`X&v1rjF~WYmD;%fp~PoS;BPM>rN)B38hk*U^_$;MRm>+HFm=IA)>_ zXI2!ejVl#^hdvSpVkeiTGDj5#I@*~opE)j@N$))~dn<^RVv-?2ijBWq(&9Fy1~-K5 z^dQ)EViX;Q@q|O2m~g4%idgDo)Q!8dnluu(`yp8gLgO?|uR`ymXMj6dA(9co>h$#j#ZsaHgwgstEiwt-4s7z@bAI^A@pR`Bhy@xKIUuyM= z)3U+ zngc5YH+-ofXRf}N&tKRx&lG`hk+9TLjyWt{ZRo-LSX*e1|A97+K{Qs76e5Zs2#93T z8AlVLW1r8Vl-Y^*=_h#D-ah!`^yJ6W#`&Koy)HcHlE2kAjE|4|h*e!L0-hcjM97xx zR-#riw2edCn>f1)K^}qhoDbmMYbu|%3uJ_*9EXE1`J#*G%Z@)kds`k7g=rkbJj_=0 z`R_Riy&--aIDg@)mldeG-x0AIj$r6o0qK>*q1>dU@JFzrQHY%>tSVBeslOl)U z0f8_Ac>cmazR#X-3$N?HEj&0EOTXM77mmYeCZj>Qe1NJh*SOqhius67y3xJz`rgeY z_xicVXZhHG1Nz1L-~RGH{LkP1f`2HWO}Mp8)ZHk;QTx^HbeIcl;ZK$=hxfDj~|>D^&hdA7!O+WByi7U8QN z+!b=_PlK6O&dfb2FQ3Q1@J;5K_Ng&z9Ui>*q+Lf#QlyHaL@_~Xh!A4?8u4Y?jqYyZ zO#1BG{+_EwglChI_b&Z$-w$;1exuOiv|By1jn7Ck;R!K zY>YEUaHwNHm8P;&PW+H_tTv=Gl1*fK_Q;1jyf@Jah0b4lYijqFwcGgO=(NZK7*(&5W+AB-Rah&BY8SeR}TYIN0oueOsnnzX&; z&_4cs|Fpl;57p-J-Y3n+9*5Ck*9@j^=lQ1>yl?RDz3;Q%yUWkOR5uA+PM*a`9mSEC zA_BNTVs%@vL{=q&CCLrA<9Dwe!bwBOmVfwSggtA|?ma7r<6Vf|Lo-);-SvWX0XJ4% zv(B{*j)u)BMMPm#2t+4=t$8s=i#9sEkEcu>-Q!WmrtUh#Zuj1M8sQ|Y$e?bFDkrex zCCXHToqmNZp^rXUbtRpPM|#B*bvwGR=Jo$psCz&JB{KNSA9>q;obzd1N0uq`%YLe9l_XyhK1is)*J3a>ZI37HsxGEiSZGkT^IR+oCN%XR8f8 zkFjs2BAehW?5CJD?GO0y&ndJS>71qc8g!nJ%+Ls`&6)229gofQYJU1fdlBVE4^5Gx zgPbxk>{D1R$rDkaAM7CYI6RjZ#@_?&YR3j`A%tKyH-v2`L{G} zZAD?fp|MVz&~1{#d>|^c`V9$QGnXgm z+1q~Z?s}*qN)m44=&Ejw7r3&GPaX4l>@}8zRe6W2QM%1{E0n`Db&uut8(fsNYZ>D> zfYP(hP&+N5h;`)h?CEVXop2uA7Ahfo_&p>wRm&drcpXI(cAYz8ddX93y(y^mR2h{5 zvW{L@!Vrv7>T-K8v#Y0jq+-v?ND;xbk^E=+1=1pQXbOrPsUhNmJBb)K7)w%WELY5u zw3sE);LoQkGdd=o@+dyTG=24a>mT{M5RkPq3DN1!QK9ZIPrgKeA|%ymIgxFbC@ES+ zb2f~kvLj_ft2BwG`DS;o$@(hQM~XqPrdJ-RRXYnURpDyy>~(I^M;r*xz_~z>%Ars5 zu_SsF5z3TT3e+R0B+3xUEMV^(u)r1k3ZA@qd~vmS&%H%Rjfn`L7=Sd~cGti3-lAuD zW>-m8v+J}aiyo<^JlGwAlw@RX@sR-QqPly5mwoqsms8S^<-XHWI;gY-s*Ucvx&ymy36d`n7-J>fHTY84Va2pSw(dr9NYk(tb-#2`!9TP=B_#`PUq zNY0eG1Xx$JXZF%w-TRHdXd)bCztA`KbBH>{sz2MTkB*JkWfxiwvfw(>PrlmoG#+r{ z%i|m+;hWN+mmyMBf}^H!wFKo(nJ~vkYRt+IROKOi{anvWp2^qkYfE&eE9K#!#{q^` zRRX6FOZL(FSH9|5mz#oNQb&-9h{jZpk+paA*oh1(oqp++_ZAYotB2QRPu%WunC^ZR zi3_w_Kv>YM-e1=dxR*GByJY*xdFEY(p&^6}5c&u@mNMI&?n3Q&hm5zV*dMT4V+Zj83WrjO~g6CcjM zMAuf|y#HLtrMy~L{$c9f{n(#8JmCkC=yt&8#ceU!z%IeJ3tO#t+2h%jf?1|k45G5ReK*bfZ}9<)8b}5p5vBI-n$wLFATs(ouO6*C&nqG^G80Ba z*^NEs2kWGa5(!3M!k>tUo$>2&C!RC9Gfh0_*%1(0+XKV)^61FXrPNLsh9Q6zJ7T|p znn(&`&77!HPS0tiywn=8UTv8yKRpN4f#bEKa*K7@91qu!^CnMipz-GPxEtPV$zPCl z@@rPekaWL)&PSIC!E77v0X3I~5F;K!5d%*XK!jQqW0>8R%Iue8XJVO zP1$0k$+1d0l*V-&$+dlTyyWggBfPI;Nx$7kX=^>|#9opih^#kstBNeJGLbW}QfK2O z-1*)X%jGz#2#JVTZ_p5=jyi!qf((ekAhbjv;?5}X_74-Vaq<)2G(5jiE_a6f(BMth z7eaZ**a17UZ(Mwu&=v-$8QhXGMqNAHJ4s81aZVQ9TTN>{`SHd)m1m?}7}f*^po3z? zG$1rhLFjX{Ow_pj%LO?bRN#hO2d-OTqnoXShITB*GJ@_lBXZ-mVwysH} z5QauBF?JN<`7TaTpB@SdcY4~j2KRZbf&#wXY+_MA0J962~M5F z5#`mvt+%&3Ef&VjG?Eywf;6-m3#n&5`J$)U6<%GPUQ=R11xgbwK$b-mHF?T>1`lNc zM*&4uD&$lL45_U&TZ261$TARtwc`-U zDJ|0L92^2&oL%r$&QCZ10wU=RAdn;^*((&Il^IiA?Pw;dG%-Aa0Nx{?y)-iv#!k|+ zRm~uwmrE!X4K%%BeWiOA*wI@Pm;@4S$x$ZbkwMFjleTsH%GZxyV4IKb-RC>bpnDlG zbG3!o2~ZhBJaaIer%pQH^V{5HNL_&uV8(XnKsN%ZEn$`jnW$g-__u4t3zCH%bDbAP z3G3#jZ?RjT%nZtQ_p5?{@E`@d8ce4#|I=B{huM)(UX+X>n2^fsgOO{Eck}h%4_S=gW z?C885*-PwcbN76fC->Tox5c-`uOIx{V#^Rjgn*x4@4fsopIYx}$BrU;g2d8uaeL_4 z%?H7w6f7iXEHYAigOskSw0hh=Zg^hEJ8uNS9{GJb{QCUVI&EQY%rp=tQDT=4AeA-i zvOx~ z8Gv`7cV_1Y1)&=#K)x4HPp5Zij=sJ&ttc=`M2vHzs~ z&Awf>J;Go`BF2-Wu=nLw`o-zq_9MG%DgMiQrtPY%ywPvG_vQDz6Cti+Mr>_wT_RKe z|KGfg3+^kOzvk@aSOUIGMf9Q6k^;97(4K8WcdJD6>?Lm^pPL(F=|_$sU%15Q7w(3D zkl?ZFW5ml*RfB!W{{woT))a*W4x?7<+H01Da9 zNBZQQT%JtxT;=Gn5N~)sKjL$}oB&|WZS@MRMu848t}tSfQ!7?fNxP3<%&y1SKgT z0#ihJ%5qdkhRYRX=^^CDkG9U>Ma_6iye&WvFhiw?s57CvBe7mg*z#DIPsAgwdpzT` zEL!bON2-zBlq9;W7|yHNekx|kP6Ophc(!M2&uKO=nwDi%&%oWyx*bnfGKWaCP6$;S zNy=SBim2#Q4DumMQAu^i8paHs7>Sx6a(-C5wbyl*lkpRHmU6H3_5n0PG9^_OAYJN0 zG%o`U!~>&n|DCHNVGDs@jm1yua%hf}=n>mSDOeU&rB=YY1vONQs1T zpZelSFT3wBLuhxwrecFY)-Z{NQ9@c>f@P&rM_>Y~R7y!KP)>y;M9^1e8xGbj!%Bz& z!R4MD%DgusK~}(H5hb~w;m(1GdJJ*gR*M5-Z;_aIB&9I26(w=0C&^^gXq3HlUv`Ec zLym=hw?;^BfCwTO5gWIS z>}gG)Dqw;$F5m`efw0d!pNp~j@_PURAdPx>Bg-l=+3t1#c>zcFbSgRUWDPudkn6=TJPsErtSYx#$?4aaOl|YTMnW->v>0o?95y{B7EyQ&N*_%tSSACA!(SJW%uQe~`w?lAO zr@)aY0}-p!Wo4a#0Xj;p=_4faW>OA*#90lu0_|2;Ku z3ah-|Nc40^YBa8vl-V~$c}s}%0V-XI)da#%lo%!8LCKGM$v?tB?#0~;`dB~FcWD(N z5&|k?aH)dl|3Hr&*}T>WQ83qadpTJ-LTIPy(Hd3#<1Vbcp#gSCN?SW4$IIH9Eh(tu zvg7XYQq?%^&1*dP+x(Z_cJ#Vq;kc!q^5yKG?Hl{=i(mXWAFQ?Ns`dcmb5Q7k$YG)$ z2?aVX&+hi|T2wJ?_+`4o6VhM$jMLBf87MjkUEmNvWS6c!e(sOdjhFE;WI1AaCDeh_ zQ}vcmyTZ$(HZMI(Vp_u2p?-e8tg0pC3i~QX+a=Xaru(vp=)-gJ=t$UWz(FRP<0VeLUa6}2|(Ep5w__C!Ei z>8O?s{>F~$SMlkw|F|zvxiSCG^J#ycbMw!CruSyVA&K}?Y`JMoiinwHT23aXJRaiU zR`ZhPeq8(&d&ji?bB}uUt)3qK0OJ5fxKDtcjw|oudNO?sEjs#Ex?5C&9oxM1mg06l zcfIiycOrlOzG>JqpRMA`%S$>pd+ZULtsml)7xcX}{XM@o;> zNoxBZgD^xcdrMo^?-FjuUuraL$PrO#Q& z-icszv!?$$5yuu2xr-3W>a`ae@deb#L60%-2%Sj z*HZIb)bpSE)?IJ;<3FgIbPQF3paT^7R+2!9B#}fABIX~5xw&>?dTZ|;v*S~IfR}XV zqk7v^PrTj{s$PTSg_sm^2cclUY$=M!&EzHD5%>lvJ^jq=`8t9F^mK@oc)Pl6W*@4G z@mQ^;l37y*LJW2(1{O4yP@rH0dNAaPMiQHVlbge*YY%cwQe!ACi3H+yhFf2iGP~qS zBG93yrLtVq+M%Ub`FlR}f!i2% z7vI*3@_x6+(;!azhLe9z=vB;6thAFS|3Wwiff$9TR5>MrbZ9Z>~)lbbSRT* zK#x>`*DzyEv7p(lOaWCTCNnvyQb=-7{v{ZsyyJljR0M*+C6MwsuK>V(loT(=5+D2^ zH)+8Kv?N|xK?@0QzWISrDFIL@Vd=@<3rNi+@=|5CKmsz39iUG4tMS5xNmOgW2rlfn z(o-_FflSz;jS1FocXOFdTMZ=+q}+RE!VtG(Vt1#u1UYxF*7ex_!Rcpz5$pE7dZv4^ z`=vbBJ=?t_XO%`F(b3tqKO@s)Z$O!D#X+cH@*#WaUvj`*emOf*?yUAd{F1{)VxYwv z8W5^TBQFjh<{(GPdI7$G#%sic^#&wxIRfyHdH(U=V<9u^b|(qyQ1n<Jh`(Wr6XB{GAvA~iBRk)VMv>*xqkI8KPAeo{!p`<$Ix;S%n;mLPn7ZadO)Ka9&xXi+((wH9JKIr#Hz&7n6Mw) zgqfGOt2r9x>FR9t>N<^?{_$o%po-~fN#$}%JFt^N$?VBQYj+|ikyZ+vsJ)Z4iU5?Y z2xt(c1&u<4Q{v>-AC~^G_YAb?y-v2a;mw;6+H^s{S*EDvn8Q&+AJdng)BEJcQ~Bw& zxlTby;_Ww;M8PdWM94~epXu7ww!{DgpsD7fCAj!>&TMk2J6YX1^!B|%$LNp}DU%1H zt-Z;2h9>s5jMY)o*`lZWXlPH5JCRt8dk~DBnj@FA5)dp&Q?agU3qljz%^7A;tjwsI z4an}^T~eY>^xCfD!L#X>E3(1q8VxV`E{jSNPcYX;ZEKAvh`DYdwcnW_Cm@S6!jb{d zMt`O+BeWOcSdozF$#{1r@v+DIqjM>dCW7Nwg-F$s=t2b}2m(l203sqJhO;vIwmV|j zs=dGHXkobb+Nq@=*l|1R;667`qSv}K7W+KP(hp$=J z(c7C|(@?Jtc8=a@^MZpp$mC%BC1`F$)Mfc=dHzbfY}>_-E0VG=<(uQEI|=tVcM?m= z?Nf`_lb7y((cXUdTZoDX8?xN-A#N-=M{d-L_nC7x#(k*KU8D!}MGm~2sdRsX-ps$V zj)eo4|3Z9PqB>M7;S!njWIgut`kO3#{J1an<;(8to`Ruo!jsS^H%aPGR@bm?P9&+w%ZI_TWYRPtB zT7pEjR2rpQNJSv!>40-+ZMH|&WGT%w#1WG17Lxb$rqPt^fNb@#e9(RgSxt>gi(HhP z-tAsr_{^vGaU25R82B+b5zWs<>*^M!hHPhf4a$P0v6d1H#04zlY}j|jhe?pWQE zn`vYNv@1u)Iv+MgCeyTlNmNTDX7t@1rW1@X9{>3Sa?!%Yi?TN~;I?ZN_V+TMI)#u= z+=CtUwwKwlC$|^RsH@Zcp|K77V%q>GC7hiMP-zKLH;Sg$cYZKO{)|33XUke=*t%BQ z%K95WM!b?~`RAcbjDmWy7*a6JSw0h@?IYUqcDSh#^mQiFY$c2h| z-Zonjql4;>TWCa65)+A8+AvZ!!RczXrgf+VrS7hD$%ev7V@9Znr%jwd0G7HymrO*r zx?56s?c38k?yKg&J=EQNKbueNmBw?qj>k06C5a{RwC+^JnR1ijWWy8O0l7q3)V5W# zAR2ZOsWd{9HwLVX7x;LPhP0QhlE`j%L!7ae$2+3advq_wnsum|twfuWMNy|=CW98b z)!wSpey6Ev?~I+4F_q~$AXJt?X~+O9rW7dPrI%7SYK^!y(%2|^ho3xq5Dj0EW%f=p zYIUs<>naCqTMGmz7k*42yapX21Sj1LNe!2kN{S_k$fr7_A{s(He?Hterr~!3l9-Kx z=N+5`WtE8FF3I;Qh&cwCyMs4rj3UPvAw_E02|_hUilTI-Ns)5WAWIsF#KKmDBsE*d zoGCOO6h*<5_dqDUq=ep;SYBt9b8Vh9-TBe)<-M-iGoCqZ#JvQMt!FcAxv9sIf#+?~ zPRNg45U#Ou%yy6gd5-kF*M#U0A-qT+Uw`dx3%O%8NIZCU#ffA~OU;sTZ4hHkO9_}$ z)t%`Fc37uE$G^OxHhOVV zaXV6guR2_dt&D_cgT5;r5yV8sQa!1Ol_?vm7YSaeMAo0bXugkrmo) zS9MI$8K6@i5F-a*(}kR@yRb#)=WYGI`2YY?9q#0f51U4jlt{#>BS&BSk^@{+x8Pl~4+`dw|43=}Jq{h)5ZWnbvNrDd?F9ja$gNnU4+8 z+8TjCy1I<2)3)8Zi@)8K8V&`DC#?it@nT+iqt!xC3;t3EyUt0!{f*b4(HlV$2`LHz zEa#K{B-4uQw5B6^_u z?3%T0K$KC4Xg<`SG*06HTA$;BEfeRitjEUP?skNsrL8VmAr@OG2GNmx&2h7&AOM6w z8N}`qk}R>-&?pgf?=&Vzd*g}Kk|lzaSbpQZFTC^eJK`*8)x*dXe#XGSJLxCEjUqLe zVTBbosbp|HtS}PvWxf3J%isK!uNb#F11I!RbH_&>IG%j+7%dd5><;1R%5D|0JGjF~hTvb|>Mv(LVn4^CnIFrK z{j-&l%AQ@!XcDS)w^}0cAn5xd15idp%L-hc7P<>GRv1N!6mZ-)MA8_6fLruvX^kQ+ zkbG`AEriG@f-q5}c9$ncq>^_dW2o{iOpY#D52r7es&OID&y4PhX1OByRvy_p7~ zs0&vL9Uv4^)}T(ramhJLB*L{F)owXbgRO~R*){&Z=DKs&&m|tH>+ik(e)To(|Gu%^ zbMX5P$z}m^kPG0yPra@^Y$*p3|a#Cm`JIzOt}Zv`neT}a8&h% zGBPa$0bq1pJySjqJe?YMeA{rLo{d2B?M14(WdlZWx(b+pBFujg+$MNl2=Xq9_O<~Gzcdw{HO1uXmxb0r5 zuP{=AA*U=!ZA6yflwyKY%3U|^P>wFA0}hr+)G^uy6%|qZqSx^^+eGb#*CpKB8(3{~ zJSXG_wrWfu@zDUuY<8pl=2%a!T}E0{m!(>rzXufw`<`h&=o!-iI_?56?fy_FE@T>k zN^ZDN+tG|}+SNnk6)S_ZJ5L-tmvJueo+U|~aE#NKQsK^GHNrv!Krtt4Fj?JWyGF97 zysRNy-6U5JO7Y3WiJNxlaV6gCjcuyxAp~tHqODCvks=v&WGkNLNJbf=Y}ZEj?(x|e zz6R@y=7fx}HH-kpGAK(~BH2TFXL5~N!IE2}UB}*3RiwBFz-u@(3zEUwo)AMWM(t>E z6?7mK26f#erA!F44aY^nkQs*UI+(5XUc*|hwi~mo zZRrQDHq%m9pn!_sPfwN4cE+=aku5B4ez`h&#%RaNm+_Ev2D~0T4nRiV}bVkn#wj1SYY2j5L}k(6Dw}-2df< zV|jHwT(kly5$>E`$Ea|PCm>Mon6943Y>={Y;*us&D;SO2mMgPG=zw;5$0nIm{BVe# zdwdrie0z0V5!bO1F)>o`aYn2W7z}cdXoq2CKOFaU+1Bb6CKgIGBdit~S#(w~lF8#x z#|osNOwhOxu5c)e8IG_M4yA}(2!@O~NpuDpWN{*-cCt3nd1a@a<{0WaW$3g$)?hYi z3zQOPy+)l92{31VvVMPf?3`+dT_G z?4NZFoO_MZw$;QkrJ$rOzWA}DeF2}SH|~Rw;YQOkGgjr6l2q~JJWzoVVdjv93m}}A zt~(rgKKtUB=#8IX=~hRPR#MYDJrUK+UcIkF;+eeOo^Gzu&Odu=^yA&c`20=#43P&9zIYL$! zlzuWAzCs-CdP5=p?XH2ofbuVWY7`WLXIWS*sDa_BasQ6)=@0oL$b?k)x5)J%dboBPP;x z2}KiST8-qsj_tbCvu66~(Jhy5j41|WF+*=H*{~kCH`(RI$WqMxp*6tj?j=zUmuMje zq1RHPm5HM8I{-mmk``YmLx*yJ!nQ*nv_mzs`%F?~h{d7OKb=W(?qP1@RF_nBOoL(# z2+~s0vH(?=;AvL==$>R;n(~z`Ll*KcykSkN-BqV+L z54KmwURh1O3+zsWmQ{!{sTjZv`J7$!7D+RF&0aB9w1?V~L`q6i+ozN)#HiwVHxs3U z48=U0+et&bt=P4Z5EOH@Z11!Vn-G}9JyRv8icL>D(_~!BvwQnU=A3S*Ns^&ioQPGq zb43V`8SKrslNTxp>|Y+;?md&dvU$`%Qg&Atz>a6g3Qfa8#~TSWG4AXMNM%5-s zWKT(ZBLLZ|CSX|tTxur!%mkAhKomE%MjP2>TT^!xo#op5Gi-6rVG$Xp+}N$kv1jSr zOIlWqP<2lvVTh{IWiQ*bLvOnQ_gIJzo%gMl#Yr=r;&h4BzR^>qqX7AV`l!l=$I z!&S&9k1vW_&O%-gDf&DW9h-zqR~FlJnw9LdvPM8Q*#-C0+CD) zNH^?$6@8Le!p5z@bnJjf=fk0@K;o1{y9SYV-=CV{Luy2TL@+5HQwl5&Ddqv#%)-7X zyIX-&fyxm!OCJ;1=~M+4R&G*ZiEvQ0-k3?E9-^y*?iaiVva>;GYeKTK;|?=1o*l`? z4qNo9o>a$P-{g5>iMxl~cVN#s!(3%N4zxs1Wk@2gpqiechRjl~8!czfMNM-|TS}is z2bPUnszmB-m4;>|kMI8>6gVOhHa(AQ5;-Jz)B)=~ma>wdI|m=LslFN(2#W zC>~6Aw;=>N-lZT;WnC2CkHC8UtvhVZWQR4K_oZn%=A(c^hSM_nDT{w<-Mn|D3p}*| zf(^pfH)gMFg@YWQg6Ubxxe|#^N6!&$DTK#7gYF1jzN*|Api+$D( zI>p_u9o~A?!ztR{??7UZ%LBy9wLK4#EJeE_-D1oo^`TL%Ds9IFC-zRsoq!KKSToxl zO?$T}vc+R4WpIG+Eh3<;`vv@}!OalNNtG&VpnEpx}&9dvfLHfX{{(OK5)qxFy= z)>0=S3}av)^880{pnHqEnRu5s_z`P%QpW^w=pAk&nHPvJKD z_V7Z6o<6-fHW=C&(PdLU9weL5@@z%uVuA#ni8VBv8)A1$>bs;AbRv{<_p$BnMq23r zmO`vTo@AZiKs4?a1Q*IW7(G2%1Ac!igB+=$#oEbbm6D9Rea)MeY=OSM-U6iiGTce%V|G;=Z`AULjzpohQgoxF zEr~h|;=Jo~c-PkiRE&j{c)A42J`Va!$Be-7F;&^xI1{;rL}z<-C$TIcE4x%(R%_dq zy3s|x^rd&{(XX)YUAKRcW2`Qdl$-gaZ)ZsJHKiY@o2n%(Kt$?7w5~V-`~8DVE;VWS z;4A$}5^bdD%^SkrGaLtNM8!DC|u-sRna@4NK9d$_i_c};( zWrV$n60q7t(y)-kzG|!5nFG;M=3GRW)O>~%x8sVk0An_W-dciCOyI}Z(hEh$vU_;t z=<+^L)f$$Wp50uL2!yto?w(lPxTkDdWp`S+nztwvu4s2^d60};F=R$8!Dy}P6cqD# z$dK29d;c9yb8b%Bt-eDi)LN^eQ#>=m8CBwkB~6)>ZLimB6t~pviUiiQO`8^?RXPDz zJE7l-HhVp*%kH|}(%zfabnkAcH^uyzYADY^+8RB60j=lAnXqypfxZo{R`>B080^MVG%CWF7kd zi>XXyKoVB3ee{!=78Xmft+Y-@myeb@7&~$fH{^OvF7{dU9=J(>vkwWe+wELI$QY@Z z>fUp?>2zYJL9u}AA-0BDh2|v4n_=5J!3h%9*9{(qi2h|8yddoATWzT8xN9wqI<1Il zOrt5KL(?Sm&2iX8mOL(?7HRU1trl-Z4f`yd(g?=BmSgicjWeD!Hmc=$P*1G}MOK#? zzMqw|7+Sv~e_n3E3%dP2j`5I`YO^c{lD_$#Yl$;lQ&g+)lk>{0m z_W@zYC$ms1liO97vsrN;yBcX7{z+f@FzF_YYzHAWz;XRDj8~?v9!_Uus@}aT2AW6p ze`6m0HhWre${M};TsoA)upQkS4XzXj_J(x4Z8yN$7wFZicUU5UNe~Z0l89+pTQiBB zu<9g1Cr93KW_G%$++lWUSm0JLJ&F{Bs3XxdBa+NqN**IcPQVh)R>m%ZGqZ{UH+xH& z?r8y_ZdWJ(pfqlu&gbjib?NBOlo{E}fT(chDO*D^yhf5-ebO#{^ zGW_(eqT@YN2`RX?kAK~fQgY^&$kbpjF`w-jWOgXI%GtozYUj}$nHpP zF8&yc=Ja+z5o#4dD<2$HY?r6TC&N}pN+FwLX_pnpqj;Foq_Zs(B*&h3GXzCj0wncB z1m-&EL51DVLeuxUoq3F~kz_a+@0!CS+%ypi5|AinI;yU!>WO4u#HW!FlGt0XPzE`9 zX7+~X?SF;Ll|FZ!G*gykp=nxKaEjwu9heutzwXbtHY&NGSl{m5>Fntx@9V;YdF4f$ z>(hGHz5hb~E*Ut>WgRydSN|G=D5P}a;H5|G-T3|gKB@2j@Tr2rL_nA}EyNUJy0G0G zL$BEL3Img1d1#+f35fL~p~S<-)LBTx5;`ng%%*p^h{>bI26Q=O5iJWsgb>0c!8Dha zYjaO6)wQeFI3tIj(c?!q7P!PGPF*68tbUq3^Yhc)bM@^zqnXa4g*p-f86>~IYtQ4= z%a5%B60C-T?6ot94mmG`bhND&QDstL5oFCMv1nP5BRgs%1G$yG%plGaXG###;09E# zw5sC_?ipfbqYSjtZD?C!rv++!^d(|QLYDoN52XSPB#xHt>DN9v%#{G8SsE=1Q;?-x zZdsi<@b~@3%84l(YpgX{nz_MA#V;VUzW4p`g0r8wp1)oHje3p3-E9}7@0!_cpe>qo zQ+sCZnfv|!Z~gsWCsDCX%L0@xvd}82HZ|IlPA>oFR`#9DxTgm>qr3NcG$p$n;;#j{hF1>DFnCEw_Nux7dyA`P1e?8y`*Z+zvA_rCJYKlBX}xy*)uBLVS1 zc=4e^gs6RW@tV5jEC5B4xI-HR3I&8O#hyxuq`T86W^GAbaiD0l8%0yy%nUP-Xm*0E zrHs_A!`{oLlZhL97s5S2=$@98Nh+|TD7z+mf)P8Y+fgDJiyGOuw!vX`M`+T?CVmOC zZZ<(gSNiGxTmWN)*79CAZ zD4N}i2_Q+dcgda$If6UWo``hd2Qw&6r#v%5oDEX!(P!+53Z_eJf%dH>kyepXmKFxD zUct-w(a_G8GX`1;nwfYzBtj`$-6J8zX${KZ-P2?wg)w&OXl*C*n;|ZB@!r5;??J5 zbv%G2LZ@eTNJ91=Hj;v(E060OzDneBkXjHahp3@4z<|0B@L_x}jIU!2viEI!5IvYG zTc1hO)9=3fx*CyzI~ww;%dRqW-q{}1-tFX;XXj-s0U5FC^wrPB*Y8I?(l?Kv-_z9N zOJ~)jtYM%{RJ$OKS`8qWAOM&iC8Bgix#SV`+^27xwolKvwg=>LJ&c>{9@LfxWT6@A z>4;el;Ejh(0kz%f3ML+*?FvJ11a!U-nHR841uJw{rRD6~OEwt^*ToASWXjaweVp6K)LcbkYp%Sa=nNJ$oJ++$mW9UCNk z?G3T9>E>z4j%R}d>T!>w81v@qJ(D_0MzsR(Zdo6xXr1J2Zra>&`*x;+P8SA*bIjw% z=iB|m+Pt`LN#1@jK2z}N_5gaStaW#glH=NGOk{)P^3bxN$mxP4QOCNv^u5Px{?(#- zHtDs$`OiK9-254afAckz13F{YI}A^*z1*Fq8jTuATBE|%9sssb8wC)>RPd|>(+;z; z9RWkZgc@|sI-ouktjfrENdN^%(qm*K1Vp$F)HOo#@U#fu^$d~>)BgB`vyxHM-L!z2 zC<-G>k@_5?-8XTuOrxlqghd>@1HEOFo;1Sh2`G$ZjdWU5Omr+*Y_s>a6gyEXyFRaQ z<0BZnk%T}aSvu^FyAxRxBv#d)X?c4w-eENNPK~(4F?}R$M~O3qNEqBy^dKoDh%_P{ zWv`QQIK(Pr+--DWtW}jYy#ML${zX4NPp@G=r+Mt?^t=KzdaC5mh{o7Bh~}hdS;!%g zQ33!%HlWOk4SCP0ACl)_ z9hxX{L&pXQk7{CXFJBR|I~p0>o%hMR>)6hwcUs8|xUjmF0Wt|ekRz+2rroo81aTg? zD}97;$RUbBde-DA$u(l)~s1L2>i0`6TmvnAON<4_wTT)Sq~J`}0g5t-J+u zxlO>eA6(Lz8wKEkUc~A$#H?xBA(7Rh`w$7ELXs%!s$ZAyc1=Fi2&&I;4?(4-*2ROC zuU|V+s+P!C)tmG8a+p@eCqBLOa+jRxF=t&IU=|R%_KSQ2w-%_MV@s$>r4iu-V4}gn zc6A0%&inm8uGiTFchWcRrY8|f0}29KtiBlBR5t+Gm1T(N%}lv3mLuM_^~`}k>7||C z;7Kc?urP?vH2e{3Q_(PnK*rP3gjOcFBpGY0*g2rr$WbH{(P*O}$!W^`;DhLP5;|ew zJekUFMOE7~LgP6vSx0x!2yG7EjrX?qHu?-&q%9HG8gNV$`rWU-C}h$(4Q7j$7Wzw1 z2FQWrNsDux|47;C3B5O7?O5Ml>+4+AfI2SA5NSdzw*WCe0cavzx|8-{_t%8y#M`8PSfGbDcX1Qjd~@f(l)8D52;j2@0nW z=8V`s5AOOh{nUFQg*b?w5htIJ>+J7&D>T7KBozS!C^F!7r;kvh4}Ey`+m6iDr{PVt zr(UojQ9-gdv>X&XJs!e(NXL><8ync^m{67!IZ``8vLZvo#v}%$3=vVV5)s1A)-E>4 z9f13sH5h{!cJ-EBm5wm3(v&p9C`ctO%3bcF)3N5xRuQ+^naK{=aPVwfsqtcK5Lq(T zr=wVH7O$kG$gk>AcFfP<4KR~w)SpjPM3cc-qjDhGWwn=bK&E1Pj;9u40yYvsz5xh~ z#V8prG9!B#Po$s*4i}Eg7GddkUgN54O@x*^L?@OGilQa0f*+ z{AIe4l1Vqi#f!Lul%wBpwn1ox>;xZ0_Xq)z%~ec*18z6rzN=5*$Oqo@Xvw6ph;f== zr9n-9T62Ve-GDQO3`ceYkqA-9)WjLEhcLLUwhRgy6-KyYjXg)Nc1!Z0L5-_O6IyAG z*emyAq_jNcF-?s|AeboW!s>B|WUrfRHj+R`OY}HuwZ40xA53>BvoUdBG*RSRPI|-E zI^nff4@>8V`%j~tCSe*Xlj6Bem;zjwb`wu7?TT_otT7gZ03|Z03VfE!sHpTgzCO{S zc!)n|P)_j*S9ejBNeINKjh(@JtlP$T~y*31!Rxf)EdTH$ZPk zX_NtlNOzg{sTk3NtZ|*7rE#`tE)skZDbxz_*lmQ9$P&+P&abrWq?{gN8dDQ1jQWueHlCQYI)n(E99uD9o;V}hi z5Rq(pp{#26Efa#O)gqNO|DLV-sh-VLJ0zB!&XH3R4lK&z^=j4X0HHv zBZf*zU-I2P%k~VdyCJ3_k2_*pd!Q!P825xCbn>|-6>SOdtv*a5spQCDZaLi zf?!x;F5jPe9aIXG9kpgvZ-ZMvX^Xmgy&ibviJaVbISS}mCp{uQVPH|$_7T(zMbGF1 zJ*(FRA}Aig2suquEg^JMDt5~BGriB!<8yrJ$Kv+#tB(d;3C>JpJImV)%6H6p@Q1wZ z>QD8Qg?U(3vgaekv83XvV%r(|AQ>!MQKMs9lgtT1maH|=%q~Q(vKV~cVjS8t6lSlO zPV?38e&2rH`~z&h$}7^xDzgPv5tW^c+luLuBIrYtNyz_;3zS7^Sh;RbJ^x6Yj z2!K(9xUDoPM-7WOGv<0W26HS5P%M?lhFj;hZnvPU3K9?P8LvK82bamX-{uca0aG2m{^!n>B>h;%O(3^^|ULaCQYj-QuaTKH_+C3es zpe81s>aJtsRqdG~ltxl-B5H_cT_E1o^tppQ)?V7xAvS2Qi!qaUGbf3H*v4XerNC%9 z(2am}g%hG%7q@y+BI~G`0z3)=w_+g|!WNuy+u&u$1!-MC1`@%u5ZFj+S&9})8X%bGK66tt&-c6Bk_&fb1g%wc8j&O&T<{I1{2i1t>p(xTHo|iLE8z# zGnbZI$C_EQAxf4cLD6iA82e2);cwBKN(*_#t(N;_S%&cXVSS7kY_f|!XmWkhx<9lY zPPZBy={cb!HG&&84tqR95Lz^J4wxqo8uV_PZW(TZ*;Euw6a-Vc?IR?w&xcI7u(Y|g zsdRLJ&EOb}Gr2qn31!>Om{c_~=}ejw1$sa!W9TER2KhvCGo}Kdnni>{7!?AkV_+D* z`;Dj|W-EqR7*5b=P@P0R>}ge!wBZ2TfjP;JLuF4!QwXn19zJ-%T10L2Zcq(rH>Q>J z=?a-vyT#GC<*<*E`?*P0m>x~@PP8M}(Ls{{apRsM(>lUxtv-A3MKwsqu>o>cr@ZsM z|8O34n%8U9eG>hRTa8M>9fFXg_eExaj6<~K2k2aJG?;0Ln9~AK!Ud8MSMLF_h!P~P z(UxR^6q(0n@#J~4Bq_#Gv>SCx${zM{vpS=6<3^Th2o?^xI2eo~5|$k5Em~8FMB`*M zraclvJI0W4PWg9f^Q0YFj8)7)H6#KCS(8*G-(^KM&V{WAlC(8Il2K1f)E>FhuUNF( zR`tHlxnUJSV;c829X9@u#dHkx?{LmPyyYyhMnZ7;qSNtPw} zq_j6Yv^#)tI?sf1&ty;v6!`WGES4+Qf;J#+r8Lt+#abY3h%>fK;uK&Y{+B zu!Pb{;*KgU`EVoMG-+2Sqh8yMmOYvntqVdu7?i@P#(Uc5x?*kdP69+1_236gbM;7P~!>I}?y4q{yx0nAYGJC6SW2_L7}srdR8@9pz(@ z+U;Js1|l(F9hQnUhU|>VGtB?7a_lK#h zArmFqI|_EWtezWZP$qz1Z_DFp;2UrKj{4(uowhBlm0-1onED(7htis_Et05!mnJBH zi8VFBLF>5LUfOWq5>iFxt=*<<1OkDR0m*{M$Sb<6w$&G77^!r6Km?FB4vx5!qGRE> zq@|?nww^jgNWFcbfCaUl$4t?go*A=kXV228zJ&=?9tc_-B$8UUTkJ+)wwehL zjiX2rN{6l3P=R{slNZ_tFKNA@ok$gB-JM0I`pEtU#+MtrXC|7&aatO;K6vA2`_6a& z)qlk6U-%JUc;}5TtjTOZJ+vGOgB*8u$p%bH44ay^zFG?Ps20}O-hC~eT;P)IQR~^T zzY^ls_?-8SWqqokPOZHE`>&k(j;=D#NkAk5U$Od`_Nmm?!>Dc9NXo(j`x2PzNR4gL zrxQ~>no3GLQWT*M!Qzv!(fS>`o?Qe}ViFSp%C0@g!U`lpeF%HT^6Zf@!I1&&+z8u& z4~Z1z?1d)9j$%duVl*l3*N}`Zes+ax$!*0wRA&Lo2Cu(0v3Xc4<`2{^_eBeVplwv( zZRKboleSWBk#x$kYE$-%I{OwW>_X4#;}7)ZpXi-wD67@GuYCknZQZsKXhm5<5bIck zwrVrg{RQS<@d4Mp-DrPw5R{C<^|(xFcG<<4c^_d{#^R;|@=ikQ>+Kb!1#D=Z)w`=I zFF&XLXxnmNePvne@Bd4G-Sqf%f|i#!`poi&rItgsEK5uZ%{CUev>8UQsZ#2)OHMmX z31yIXl2aRgs=N^#0eEEF4VvaNBBkw;H3((Y%|=JBMMo?gLWG5PTI)cYJxx!wQJ66q zS~2)I9Dz=G-NK~yL)8o$t9n-NrJ|R7-Ja^`H`u5!@R2hy0RjaEJKC}irVQR>M_9+9 zVHg?BK6c17NZw6x5a;Dr#PWnl9WZ^+Q7bWwNP2{1(zayB4Iz{Hma08%pt2FZ4U>q7 zVtbGrrx$VmyW`I5E;9|~425u*Z%%hgsc?~w#v!VI>G%y^THqDPeWUnAXJy_Oo~mXb zJ;jGBdn_l7+Eya8+?NF|PmfY;wFbwAE}_WH^zM>;ZdqOPWBa{&08VH9N8%bp^r zqF8O?Op?ga5yk4Y>1`tf4?66m1wkTdiC7X|u~k@7y2{fPM;V@MiZOy9b}E_-w4_!Y z-MERICeXE$qVH?D?2~G-*37o6R@*!p0VwHb#&?$9?$h(*i1QH)`SJ{FeA&&yWF^Yp z35fJ9Q+ryDqESi4NT!=!ilzsPkrIUq`vrS1*@7re&k{QgxCExHR@yN{YaE#Vj7E_X ztXo8ocmeq1xDGOM)zJz$8+E=Fm~uAvFD`%u{GkdWH_;ofsntSJVntFblGi2(JL+i~p`bS6FxusV1a`grAs|F^rr@F`f_v0f zw_ZUjtTVAX5t{XW?joBb&IkQuMB`5NIMOGAk}mi;hoonf7MCnIjQIG)hDQe#nM@OY zxV)0n@7s?PA8xT$M~mLa=YPt)D!tL^-dgf56A3v7^M@R>gaS0QU=U$90$H)mXIds2 z(spQ#-=Bw%MbS=u)$3pO@~1?chPihB72h>^45bxcf z`Q{f4{7l|^R&T1NUw<>GY+iq}{pB}4{^suzjx9w}3kVx>l+}|^g`C7K$&J(w{qa}o zcwpoU+z58iP;M#joScnQYOE;7i&l@UX!R`o)?+PokXm5WvX2L7*W>gyG;ybZci&PR zgwuSxS|2;fRM|j}kC9IU_VoQ;>)hQu86}FBaGlJvp!GB6BlOZnA}DbQMfBrK;+}8I zdXIB^pwK9`QD=$0SEIrv7-0eJaT-Z2u=2)_(ERq?gSXV>c`h8wW4fP5p4@ZHZC|-Q ze9^5#zt2f_icIKH7!nKqjg}`OOSU?5bYFHT?~TDnKo(F`0|e4c|4pBLUVos@AL3gM zYj&o4dSbhId1i54c=5i_-WZ!mWyqyQ+&n@k)^*whlx#QH6 z2Rw)7x$xzcKh)R0^||OgrvAnd5^UZrZ_P)h$CL!tQ*ky|e=zN!L>_ z8_*@Oa>#kBC*Yp2R~OI=+&XP(_K&Sj1ENI&2}kD1rI9i?P$`3r(z|ga#w{XR_AX_l zRf z1?#r|f(n$BEJTOT<(gM-+=poQp=TK1FEJNa>#KOFC%O~UNaoO+Vx$d-5k z9adC~I;xmVHsdBX>6X=!TCR4SGDnrms7rSD%yJu5CV?S!@4W&qaU>Rm2;38AI|4Nb zO@*dWdwuU~__k@A(rp8DFQx``o}#xcEb-(DCKIz{=@O@AjCAAf>{HHb;IcNrT3oNZ zF4}g<0`1K0;!}CHWyOr-wzL}nMhlw*WwW?%P*=_;_wPaTnCpmr*a8PlE0bK%`Tn@g zc55JALU*t%#frO|1rtr|Lq@iDMHyRub8LafZ`s{&-O@etzApIoSvTg7|I(NKKHkl< zZ(nY`=hJ_E>hxpYdbWG-yCg&U?CX@=E)VM7cO75)Rcgw{|LJ}UCXii+Kzel=s}LP= zF?*OVpZsLO+^ISL>#f?cf>eg%xpI9Y(}CC&!DLF1q0%wg7Ll<9PC95Nrn6bh%E-&{ z()rQWEFI~N9kuk<&m-d%Pb1;Ai9wh5iV&va6CEPs+mCZkPr4qt`iLV2Yle42`eW!> zPm@TgZg(8U3~ox6$AWB3yZy3miZi3f3OpkGjMS~j5=}B~=v3Qka0`N6+Fv;a*yM_`Tv zMYE$ri6R$+wvMYna7}MTqwaBB3{AIOHHtLLVjA2^46~$p(VA_!?-h=h5fGm9>3O`#=1C|s_(*fRY(QtU zk2C=g37C^0f6zM)kX~E;dAHp#%K&9R3lY&QMMSeLTA*@N--T9J=b%L-b`XV|_`*Z& z4eD-p?@uu;O+B1)A*WKQ5Gx|2dphib9jyazEHq*SW72(0e`K0gcYEXPVlpd{vDStR zHPbszbWHWa#qPitQ!>nx#tL`gL>rA$t0mt6dbcP}E5V{ZQmCEmdNFge)qQpYKfAs3 z-B(*Z0(vz3*Z=q->2y;kh}Ay5$4vzyrE`30r1v@rsSbx7z3v(=r0Dh3{Nz8S^;6-e zvit+C3z-0=v@}x|?cnaakHbvTVWL0*VI;%^0LWxeMc5Q#J6OU=YI^>@&$1-EGT)}| zbsP3AhuPf#jnK_GN{H*+UFmr%a6l6>rOwrMKIQ&LFJ|3B~9>tH*a`+}e+0aSWwT^u%pDINI*eK~KkYroqI0uKL zm@sM|l8C_78$~2-kdk&{V&(Mqn8sSu|B}z?)AcRiP#^r&{(|52E&VMY06Wl~V{b^`jwrg3P`7k!ra|WKoH?g&@)Jybe_(oCAsv;f%kS)S*z&oT^HZ5^oD;@ z?LfK@rHz?z)w*3feE-rmZ{7j|JUk#C1kTP|2p=h~gY^iG*iRU!a& z{9Oi8?~pjzoLSB6TzgC{I_Sykk#8FV#&JJ&qgmW9wivhcp+`2XS#DZ z5i+W_eKiLN#f~jHB7*50Kuev8%NgQHP5Ka>#8W1RKmO|5mvc&*gcPJBJD#4>f=Fnd z_A+S%4quNcjhcifZbZJ?y@+xWh#Vtip~5xkFnH}oOkXj%X}qG@8Y33$h;g_QVlb2? z`!JCoBT4rfnh zq=2Wyz-3@r!LBebpqgX8=!**<%*;+SPdUiS+k9^V9YM69nj1|7gl5^@O{L>x@v;k6 z%(a+Ey2cBL76D_-8rM~Y22CPCBzZSAhg-*@GpVt=b{x$bA?@AUp5B>mTba!N%=5$)y>(h2!-kbyy2S5sVj#ez7jq(ykgpH-@ZbR36rs7ndw=&lj znrT3Y7Ge>equKmWNl0a+dMl1lfWVi($&R*FFVLFZ_sU@;DPRO@x;?ZyUgQvsA%b>e zCJ<>98@Wd=AMGeJ$SbC1wWYial5kp*`&=O!p)9qXZdF0XF$GiLOqNLF*io}iF76Ns z2n--yA$8nR!mM3swB9cDSGKcv$I&zLc5M`t3>%|vE@653qOLwg2+Ak&Ivhg% zz%zkRh!!Fuh~^xh#-Y+qSQT(kORr)ndpWel&*Sa1FdEYr$#u}92+4`9(J(4Nn$?1- z3GNB9K(r#?ZY7kS+eA0qMs=Z$er6a<$p$7)o?<*<5=0 zMi^!fal!Bj_e@bo=(TBgNMI5rQX-+=(K=cw5-1~#70;k;6+t2ZgBoZh_ai>j@r+C_ zV2dC>kAjE*7wv*(+DfH4tqIG}0GGwFMnXW`QfBQ$VSV!( zR^$i$C^16uW;$toi#qKtPe82d0vOS%qB`rL@_4FQJxAI&4+a%aUa#Zm(D{~qC;&pw zp;3jPQ>oXtA!)wX_Q<34wXvL1z%OvY)Vq&j8{fla6tm_Kz z4sjLGr0yB#Wf8rOF1cFt4W6(SSMYea4X-DrN^*IF0#^E)FM@g>BsGj!w$_kPXXD=-?p#s&n)46AU4PUBP9+oc)p+aOGQnlMkALRJEc$&rH z75Ybk6QM`*F&(-(sE@nsYNmO$;9?Bw%ZO@bo1a)syozK0hw8y%6damoYFg)i4V79Tw0-7oe`RVCz7Vs&Gs zjZ5gtqW4Yv+s(%-*RR+aJsuPU>|Gxn`Q_EeO_{&bSmE;v6q7>{R|NeDn%08cvg6&*%o59 zg1Vt2hY9VJ*eN?5+m40Y};Q}W>kzli0fA+A0Yj1ZK_W~fh&m4Ga|#qd!JA3t{cHix$pY@~{34RSjpM2nut zjj_3YGiJ+zB4`X}jtcf;^jHecO>&x6Y%59^mgpfnYY*QRv zcwFAAJ@wo)HpigcVNak6^mH1D)CEc+f&!=~B$*dzh6+=P6<+(K13rSRjx(QMRCAVR$?~ zgQ34-@tm>!?rc2Ee=+m$S}As!zx2&rhUYg9mrwd$lRXVBELn5{q|r8xfZTIlG5dzz z)4zK2aBExvf|hhSLFw|E6Rw9_1r7X^?2+0lEZ=kwh_HZ0KxT7XnV@L&T{Al_?^#Sk zd2c^>(6*T*$mj8tX?4@7r|Ksu9TtA>G1B6ZtDWFlUng1K0mgS`#C z^|vQSnpq!3#^=?@(7B3G?n830j+zv3l+MKZ#fx408AzzTJwi$&Mj}b$9u!CMUcKW; zLIS)=}!X5BxXf#{9?}TjZnf7|C(!xX`R)u7)YXhsm)u&&6DY%Bi8hNGRW42Dpc3 zV>5_O!ptGi?M<1c>tvsxEl){8qkX$3FQZgGK9U@APd8sLbGp-K zn@*p_^SP2wxw%<7Jm7D7B>M%y52_v$?#(=|=k`g;w8g?pc7fdyAeYxYbKAb#{0S(3 zk`QWlq1ohX-kdzviV+txu$XLoio_&?N1~M^zGtbt+11yK72r z>>y@XL_s)e#@p*GZ#^z`XliRTlGBmXl(*Xib(YA5WXI%)-5@8#N=8F;#A6;|V2exx z{We5r?@vQ!i<>dIXY%})Vy3MOY>z0OMpwM7%<=SCqvA}s>)Hp$jf+4oE7Ei$Y!IH! z1GRlh$V7%484P=sj~?oT$kxfJtzM>(vfXw(p0py9E!r;JLQF+)|1dgukyn0u{&3Vh zKkYd`u+1%b|MzBKJnIm82YvrOb)IWIoa@K$-w%Cp{bgVI@(X-3_bORLKy)DjOPc4x zZGW_fzCeB>Q;Zt^TQMN(36qR=4er$$^DMqR4CFaRJjrwTYgqufF+ua7)&P9f1=eVuwdA zJh+(0PMtcIcLV2EmIlvja=K!&@&ym=`7-x7=?9+_N%PCPZ|8&YG0cN^i?s^_M=Z4G zKI6!n^XwHKTIL}u&T|Ps4)9@{7K$cXB_2*>%^|H(Uq4mvb$f_k5730b8Pm#EFOmljazj&e-_|x=yFD zefB?pQKEDDJ8h&5R+?d`kOUDuav^of-}POe`>tnJf9vvV`FQ_*Zn+NB7h8yT;b*#O z-0^Q-*vB%LL~8r0r!0jC)YEb!!t~cNj@-R4_yN1cEUoAGoRV+sp6R~Jxy|g*iAfG4 zY|Bk78X?vIS^=OGVu)vfLIs8(QpjDKwhb&Emz#LH0d243D8U#cZ&7=cP0s`~mLyVK zUt%T&r=weT?*)F?llNM@{Z6!yW7%WpZgX5aa(rRke(2oNTGqopWMn?&^B%aCf8AGl z+wGa!x7>fy*Y5lF?>?YsDz#T+0boyWFtb2Ioj2oR)!Dvwcqu}IQgS3A3{hgrv@%*9 z>jD7P33d$bctqA0Hzn-aFRV7AZG+O27zGtBm5+{%H*n$=k1f8>t)*Xh*0LXZ12#mf ziRWyl2CYKC+f=q*C|*g89$JMt@e)4pr_sBi9H^KtoO zmTSkQhf=OoD1gSa90jZG0a$$e2lv($kRH>IpDy)r)NQGKnyBa;yJZBRCXB5@1OQeV zAsQpV$RIKT81 z?!fC+XL@V|<%|#nNGei05O>5J`aL=8&9;*BvyvN93BWM{s2AXnz=={_<+*nE$sfz3 z`)j}F(A@bxAF%>DRbj!4@pD_ zcqtSBVA$OQRwlh0)gw-e2&1u;+m;tuCU`z=FudTr)Q*JoJ*iRm{B}n|BrTWHiy$eQ{Ug!p@c+PhKB4>hRqUevT)vKKno|~k(Ez%Uwx}0{ zgQ?9_+aqXewV^CO@aS z&UmRE@|vx#6T16xu?Azc#P*cS#(t06f z^?|J;NX|&6!JM6=^|fn77QocozI)yAB-S6*1&JsRr|J#^PCxpOPUdXr5{Rj+9#GEkYQrBd5Ky4!nsj~1}* zjy`@-E&3Wf%@H+1s2L3cMx)YJfk46JxxleKDMrvS2qB0X2jgIHi%A;EXvQqlV{WT&xeD?nL;0+ckCU zZ<}I{e|H8asvX+84v4TO6(a_)1a1H$XA<0{a9$(67<Xn)$NH<-XiU2?efZ(HOKyn7Yt7Li zSN49vzV&sJ!`0-V3+&C<88-^Rj~m5Hyh<>G3Y$^87ccGKR%bJz6u} z`cy6%Re$ciIxBl^!GeivC&IMp%JE=MtV@bWtcIBA$#R2~S(}t*tpPd6pJ*%U&UN4o z`SQQppM23Db|y$N9`_(g7O!4^fC--_mvu`WIRE*l%z}l5(6FvBd#Tk0GIlTtm$O&N zXX+ljhlZQiS<-}Q6wt(6kV;RSkepl^JGf`P=6pYNYW3Ko#~zONdVw>;B_ViZo{M%0 zpVFt@yUV1!FF!Un0vWon#69DhG8XlCe#_tU)7|$`ANx|I!^qY|)~Fpz#4G~59YrnS zI($!cZ9YkNR0o!eTMkV!SpmV0N-`0$kGaPB!6Fm&6iO>v7#t~TVbMwU=%wwk$DaKG z3-Ph{zUFmz(@8LH3oXTEpXb<1?_Roa=n&4`?PqU~1wMOU9$&5U4$K}{vNL*eD<(&7 z8ncF^w$>~TeYy5rK*~3fU&BZ*FCDr|JD&WZ2Biifp`mADe~1>VzaEw7J_MG4$b_^f ziktLzmN07>)RXy`JeN13$YW@lQ3PtaxsfSZ*w!uUJ9yLcy3hZeWD+)a6S-ZWyJI8gTJ3~Y|1xh?(SQ-HV6z(6Ww3XkfbojJGJ-C6EbzIwl ziV;|lVuV0g>GW~Q#*Jhd1>3YdB+w{!n2xu20n?>rW$Acu{#^KBds|B*V}yG^QI{`k zb7k!sbNL%$aTVr6*RJY$N26P7yQde(=k_)ASoColntOF>2y+eLwd@!zb!L2tvz&bC zTA5riIB1WS+s+X6My8I4BymZ~7)lIf3ko^{x>b8Y>4^QbtsK;`nQQuG3_SoZI z!ErWy*Zl6?ur0hF?j-f7T6Wr-PF;wi%OYz6v_NU%VY42wbob$zZG*M#XDSu}B8&AY z_KGV?H$p(T=!rCh$yJ09m?SQUE=k?qi}bavu~?#4(z01kycdNscr*;#QnpX<|l^ycdjvWDas@y5lw| zMr)q_Q1LgvX6^@&hnP)I+yKfUuJwM8v^xLrkYjpDYUO;7Nsqph^M$bE!V!^Gaqsh^ z9{cIop}sN33NBqbtU8_|gH;41T7o2zM?2@ziaG+t`;ygGgXSDydz{jdH^{QCl$tOk zNLCCs(v=g{9&gIttXlu*wWWRWbN1W*K9PW=LYaIe!+DVlr z;D#z|KqADR*0`^wV|S@~z`9i?0m9K0bkacA23UYdMr9p40YYBbWa>iqo~=vJZV7@d z;fxcKLa}J#+4Z`fO15>Vr;X86|3L4qsoge{o|heaW!=SI*De=BHZmNTMT-h27v{9mD3c28 z-d%OVl5bCv;=?egw4AoBd`eb!WTO+-|5BYawGw; zfDmpgYk~u^Qt|O=gh+_&F$imWiP&XJQIc6@F{I{BOGK2Da_y<(8XAF0AUtCe?hGw) zFQc?-jNB@AU$ID6h?0q;jx-H)@0##MPQa=2AEb2=xAg+hewGpuZ&hz4;s;l7q|7>V zAt@r#fO6tVkkYHA#Bzl)dBZN$u}x?<20WliNS@Pr;fUJfKB~$l!o2&g*Q$1Pt(&4q z)Gp0wf5NfGr)lw@C(-Vs3{FYt3QkEN0HTNhm{ga&G_&J?VCj~i2q)m?3V9~evA}>B zsZCW#UrtxF6BPu;1VZxGYL#SlWIEP9T-X`Ol9uneu3Z|^YCsoxp5~b(eY5Q0a&J5P zb>Cy>4|D|1+dM5?hPz^|<4Db5rB2RkXn%6ukxI%z zSqU{@vE(C2VUPnF@Opmxvi?#Z|CH9R@Ef-IglSi4CPqX$IqGy0H}45T%@LC@FIPiA zOULyO&n~=d2%eNCrh2@_Y;?(q(j-FZ{Km}SD4E4=&nWTo z7>_KTBH7e&n3w^x4ed7;x_{y~dX|@;IrGUcw{#lY{L#Z(!yj>dYs>6S(rw=%99p~z za{^P#E$?)1Ns(>stG+KStW2YfqM%toV$@q32iBQM;fwY#c!%$2>dOq%gr<}dxwDIqQS zEr1}H0PV$PT|2Ev&y0pP3P2FWujxrEaW?l$bCPZsPU{O_c<-I}zG1bDwx=iYG$F)~ z9&eg!H5RzkV!nN`FH)44p^;hsAsJoHtF-AP5MCnG!B_bln)Rgt+7UnlJi!$g1PFyu zG)71cjxw!rQ1T2oNA!>a41kI&M>kArBsCUY6GE}Np0 zJpwUgR|ck%$QU^r1$Zc09$h1elu$;*YM;j_Wo6yQYPI~w(neW>^zKw%| zkju&pb;ys@=l8Rzcf%XphYWTvFVNeASdNSP2_JNq&nK2Q zm`DN=36Xqny}G(T-gq0S06;`C2P|#$&?sRl>R86IBsYqPWJ$0J27$o>0L77_V7etm zZ7zzD3JD5u?4^+|2@$ce#KJb1+Dc728`OQ+jcIkV?{>68QWn~62{M+GPBc9o`1`~a z{7~sP$@h7t_+fr_&Rzf@4~9X=jDJSGeja@Io%iPOKr02s?VTbx@{Upw;uuBJR_P$L zJ!Yxu$LD5x+PTi7$FMn;7~DP&!DPBS)9=$m$%*9SL7}1uPHgXe9C(r@MrIkuqLbR* zOS;|L?dw#dr-$G=Ko#Xvd3cD?fm|)>6v{I*0Dt=ji9|%%Op3(!6M=o&HnA`>QwJZ5 z-LG`Doo<=^1_`yg8=sm4B`I~UT2i-@2LpuHDnK67H$7GM@Jp_Dd-dK&j_$eLv}Rv} z%8;m?L3mVn#4$huL^yLK(`=hEj_5FI_mN=2juDE|7z3J!5s+~+*h<@Fgh&IXr`SRW zNXBfZlgK1cv{99{4SA=u=4)@y&H!{Eu&s&M)~bdI6xUtf2uY?Ax=QIw2NFzeqPDH} zv>JQ6C#WZDO171#kap_6Ch{~#SJ$PzJTE`!gWvt^Ao!k{8=t>&LoOKSj8YV|PiYK! zPm0u~LMja#Ogg>R=}xWL4>el%_UamtS#w!YCJ=p`0xJyI*RChVv8|RM#4IK18-A8i zPy(dIntqCDk~bD9O~ecU!Y%X-FJYs0xA9jr%HEJr6A5{=6uG;HjPfX*9wlG_Qb#vF z;O-^eq3_t$yBGDrd*f^Atyp9-5jY^<;^b~f(gP$U2wYZSBu z3W+mSr^!YO^%{j?2Gul3BH1l*;Ig1Z6A=L-nm`*@-c|F& zQ=g+qx`o1k$Z}&PA{gmYbk=SWuz*4K$jR0mq=~wYL$~m_892S^Xc-UzEhmVh|<3R33xFX0!bSk(4WQ;8>WBz-Z(INJUr!NRt9ekBv0( zP9nvj^(5O~&@NMBZFTwMaeB77s-RK`5QNJS2VP>$(k@mt<~OI7HA6C3Z`wmRP9)p> zUmL`BYv*%D|ho&-gu@yv@+9?Vta`V9!qL3nH*h^?dg^lKCS0Gw#3_B`^ig0j= zD|*6pNx1ObE3JE%bFa4Hf_|G9_l`IDR>s8NZ9M$U`kOrR$+xFnGiP;Ok#@~oQ+3d| z<;A+tJ-jq6Pl|Ue8kZ~;U&aan36VbSSpdG*tkucJNsLnpVuN_szm0@bFcoZeG zO-~D8qP@vQ?-&=CFA?OVS<+!*it-4EE+-jN4)GK-&X+kKP6tzilVVba3!iDhmL|b0 zuCDl7HXaOCC?!*P3E}|4G^4$o&HY3({L^N9fqqL3c>%YLGBZ-s(nHc4O~shF z5r$+GAIWxMf(p{}Q$R`|86wi68x9)F0}NSDYCUgzr~H@@uKg08zohgu-_@%mq$nL? z)Cn0lf@>3z7F#zV$|@EW)7z4BBoAqdaebO8TKL+@E{sB9z-q-nSi$z=GlEJODzUn8 zMSD<+FZ?k}(_#oBM9i7LnKSieWWw|$4M$Q7YR~EJMgR(T14V~Nu}7m!h9K!s7dl?HV4-_<5IV{@2ru^gnu`*P8hmm_ z0qeeKBxjhn8bWj>QglXwq=*&L5t3BWzSxzsX&kEu%aJ@)d(6i-bDLz$*SyGd<#hEe8}~tS579jt+>APG{4Q;RNbek_buQ zSLdUnyK&=mj*1(!0%eBoU${Svi>{e>(_kg|ZrEBav|;a$KL(dkN=O*`;p}MNz9Phs zOOp4Nay^C!M8ZH3GYPKask>YTmn0}sbhY9@0Nb~oAtoVueCsG)z8^&-vpeXKxD@fu z)w(5DVLSKX4zot8OGcxh`f6cEw7#e>Z8JcKQrfH{T^=v&tr#L4U>G-Qt6K_@7z0cJ zhqU3s7!=oJz4j!IA>Yw8gJdE>WoTimGEfb7-ks*DI)pWN8;h)}NCdCU%9;pCm5m(& zYBv&=q%;Q{w=U6Abz80`%5p9zfvy7wdkAeh(h3$Eyv&2o;iY@zC+AxXk#gE!5)1?B zAt%_;#jqJPW!ozohK(*oBO&=>80GtM{b(cIZS8Jgb8)0yX-Vn(Q}@=8XloqRtAKhk zq-b-HuH=HOrAfYeR)DP1A#!LD5QQ{lPJxu1I1DPm)YYwpEDC|5CJ3ZgEM%Kq)@5Y$ z)>DFDg=#4D`MD&lRD#5Z3(Chpz{1qZ_L~ZH$_Y*ErsFAq!=Wz z+!Hr1?(xR9GXViYwTXz;d7N*_^C?^8PI*MGN_`Y+)DggO96_uY+6klX8jPdZJS}i8-mJ~$I!Lva+Y$gkV^wms)t`iJL{wc@#^X9$;I22 z33_|5NIERW9l@Th5X)r81doC#~SltFkF9F@W=hMv!FLGkQ(h zX>TQ|MjswTN&WO`2ej}2gJvW9RXd3?!z7;RJ`PPUB`r|qWZJ1c6k`nD6XQXy7KB`} zFcJniQxeflR4l*%&DQu#+^(M85`brQh-7@^{`=_dwX>I-(XTUky{D10qCJw4B^_`L zM_rrjDkJFedwx_`qyT`2BtVaX+LkxxU5_0ZFpilSmR8zEQ6xp#Ebl9xQi25Mlyz9f z)8d_)b1joi?5q8{!S1yoE=mmNUgAu@#k4+fqDBVIr?tRtzOh-b7)a@ zM^2AVFBh>e)HN}&B1MMd$f7;*$?>=(&NQXlL67SX5fPQ-n5?@_KaGcjvI!EQwABZf zv|{1Q`*2aF<*{+-YjvOSa*55m?)^jD+LqnI-2d3?ek>dN+hjn>YMz5pKw~1JSP_~a zCqgjVZUrTL)7lI}F}Gm6MQPLc)^$6AxYlzxmhMkY+;N;=yd%9s9^q9y-FFyY4ij;M z69@Yn(81y7Q6D+BfDzT`wCJ9Uki9f9)q9qeepZk%jn~i5d*bi(Mc(j%H#~D?MOr;X zBQ#LcuNdLd^}Tb4Lq8*$7UHdH*q;RpWHqnaR~i{dLOb5^(Ro!hmxqRq*v--obUHO3X52vl2J?n8Qniy+e?DL!i z;UNHwJPhQyS zj;lksfgU7#(o6}o3II2aHx&jtL_v6UZk=B1T2F8L$-yy+D+0t#c>nS98FfXdjg}@x zo>!Jk0m}x9ZWqq9&#<~qC#;9u>GXpOX$U$E1b4ThCa$u|$}wA(iPA_Ei0uZ>aVh3* zPy25>hja932QOer3TJek{czm3wz=A+`#Q^M-}|T0VjSW^(PwY&ebjiAy|sJu`3Q!k zpR8~1{B|u5^W* z40o$5^X^01PX+{)LZnY@T}aJH0Fn%Qek$rXB4CiV7(AoXK>0{zGUPxW;00);X48r3 zRqC+rgus5<(aW@c_ZgsT?I%YZT3Sb%+ui+ACq^hQRWOYNCiY1{r`1Ry z8l}xCakp0MV!Dg-`eiJ``{`s2St_^de^~~O6WQR5k8UT>j=%i*R1Kjp~tyo>pax;_oLHC^=BPo-~M&o|}uX+FPs*Y~mSd)O1VSm)T0 z=B+5U8ahY8-1Jy&Gc7JIPzbijLcvlWNrYT!iGVoo`2jsdJ<|Aj164OiF$4-kwDp-U zfNCpo#aGuAcO899Y2fG?w9Np_)tYw8+q>EFsT_$^l;`iwXTRh>{&FKqZO!$rb&H&K zc$S)UU#ke`MxtUOA-B)4O<7@;)ZX{gcrAj!9v2r*<+Ly0>dt@`&mKys4sse1F1ll5e?Pu2ImBqT0CO;bx`$IVq=9Lb zCM}D+b~}z6BSmAnTM0ujrQz1~%r)+3UEoGiAiJaVPuvs*5D<`LQa#N$it^yY{I~}u zc~B4&+~D$O2mZxI#G8K^u~aH%tcvb9=VPu&&UjwcuX8YAUw;N4_o$ym=lkHxEqTCw zem(m5VSeL%extwaeP5p1^QI+nlCYjlG2M;QXV8?QZcvCcZj!N*)oH?0z6Om9zyhI7 zSTQ(LQs8t%tsOC=VepiZ(TXwCM+;3#a7=cnQ5>%UqI5@rP!^LFSI@B!ExM-% zsLj>a^;!S*ciKcv*^k?w**ghM1i4UZCkixYPXoO~V)$Yku}bPL!7*0VZWa_lcJAQ_ zD?GpQ+-KI2s>sUCs)w30xSf!&*GtfVNI}PEaa#4ZgmEAub|ixM%z>}NKIHY#QRK35 zx*34jl;~UlJLDlOrjx#@%%ZACy9)EM7f8lE^0@!wmlf+55MuC^De3ObFaaPbm)Lvc zmS`*?ZiC$-l3~d8qu_OXinaM4_WzG<{sux#9A!A;5^0U2C}_M8@AZzi&#*h`wtKrh z)1J@F=MT7-r&V3-%EF-|*Bic(@l9Dv-u<2h_MtgkM1?leRJlWY0?{UvV2&#~N%1{* z$P2JfzHARvl^0lVi6>7P28~aWair9B>|txJ(TfC&ujk^iMdS^eL`u7(ie?Qq?NP+u zP7T53m#K*)fq2%vB4`03DzgKYnkL9?$3+<`{W9sj^RO5C zL^K4}zPkiTqnux^SUT zDgbq4uPri;oC5ASvT|fuI*`eB-Eur=YtW$pMOdOf(x{@I5#Szjfv3)FT)0q9t!`iU zi{%=%M9Y-QbAdq14u*1-_BLYOFQNHZb#>kA7_09YW@v!+M=;Z-m7co-+AX;`)K@{CB%A zNen^-bDd)FQc3AU!cz#jHz-bqY0J>I38HQHECg@EZD)=VA;oro2}bLg@5Ip4q-RLvWP+39vr0~^fr1xq``-Q@H*<1f-VPAEZ5h#@ICX)rwUu;*o&0+MSRUK@ z{Nem=?l}X7pd=y=ugeo8aOBLTQ%5e$*@ZLvZM^09JU9Jf`Cl-OiB?%jb;*pR(zscz zVd-lD)7M#b^X^8j+?z2X8xvH{TZ3qx7nC4Z$>;__7IT4Hhu5h%30am9_ zD*h1wb?|{Nw*G?O`nliG^SO@-G?{2RyK1%ia7Aj(%x<*Ra)_HP4VC~o zM`-tjBy#H5#)D5hxp7Wn80O+uu6KcmBrAT>2;D49krlJ2(-wA`+d`~bObv9j;L^_d z2G8@R=UqLzkY_GY#j^X&^VN=@guRYS>9}uFrH+NaECZp9z>7Lis=AZe%p!e>#3g``|0(&n*n)Ku)>9@>jXD6qGBN-EP$ZF z0P2YC{@N|^z&_V$%#IdNkWM%OSjqwfiAD-3fYy?UGX7d%rh*fX%h3UZ zk~XqFdYlKUN<&Jw15c)~;dD9zZPQL<;9z$yF*ryUjkZc1@9twVwA187tbjqp_H^;V zD)Q}9i%!SCYVOst?!y{DfTGAmlPD}KvQFE6#-M>lwL?sYu0@xd)nO{dFixv(!1MX4 z+fX;cu5J*u*U+!+PS>3p1d*s0!(7?XsXIl)+t7^&XzNEfA(@->@ptu^7!??hY2P}U zX_O#Bs;M0`Vx66UIuoht7<1{E4~z#ULl-Q=N|*(KG^NtVDFt?S3C~%I7EV!?=fsyY z0)}0KBu5IbxM%!5OEs3JyOb_UhkY+0f-@!ug8+rO9aotrl6||ctOFz=&=OPID%qfslHFO-iPE(rqA}I8 zJ0oZ)Z38I9BS~2Jo)3>J?JgPl?xK8e?tL1AwgYTAQyu;||Bi>QimfQ3K>-sTxkYi9sO^#e3HoFBy;{Qi4?H z?!`G$w?uOIh0$x2hXQHa6XlMsgBzg+0K%Pex1;T%rrJ&^Q+dJS)B<4^UH}M94CjK_ zAuCBC1Ve}28l9p@S4?0c2P;+`IgkK#0dw2jcPhd%kPxd85lgTP&(=vgs~@XoXKxVw zSoC+-)$v?cS6hfcG*b+SB9CI>V&>Yu>^sk$*t-u2JSsbvO9iQ()Fo&4GFM89td@*T zD~!@B+Bc%N5X$6i-QtsW*F zKGt#Ddf4eHSd274y={goCA3*UGz2M7f^-l-xOIK`>q@w+tRRR|Uqy$Y2)RdPSwd3R z@M-HEVy%?X!9W@V8YzpECHeS@gY>B&g8?l_1w=WGi27`IohAU?MDNPrQhdi2{?~J` zQ}*-5(6YWjSIb`!?VjJLh$4Q+W($+g}L>N-x>-9dN1_7}E02QPz( zi{jjXbo#M-IRL8yy_9AhA;n#$((0>{1UpM`()2V8qu+PKxZ|G2D@8|JM4G3W0R4$f zydOM9NJIeBxi;QX^H9f@dIRm zjVO97nu%_Y>zX@Z8)8dLT#HGN)apGxoWTT)Eun;?!vff{%o>3wC5(Uzaq2)mxTlQ^ z=c)6LdY}=m<5QPjr++OC^>`q>4Y;G0F=p_pNNs=!%h}bBo_@?qVhCv{NcpNfk}fGw z=pZ6cAwmGi$~^RpI2dQUwINEnCp9mLmRcnhhw3JPUcF@WjP!a*%F{NR4L9LxicY7; zR*?jOuRUD*qug<`Z!_ZIwcZ{UQkOWW2q!VfAtol0!dtKh3MqWN{orM|Mh2-Yr6`S^ z?F>)RH6`A&L9uq%($LwLx^*#PO5h;*1^H;AJp91eGymfIU+R(?O?^s$LOK9iUKMIf z5(CP~jWbh%N^qXXD@W^@^IL#Z1I?%Oy2WgWIw&L(EriMfxw>iRLk>by@}uXrS{QdI z6Ap^|BhDh3MS>b^5iUNRGl8QR{%rCXLXS}IsT8aT$ zbSUK=@Pv66f%Gk8rP1t0NYdDlC92I_^E+kiT~bw*gqA{#REgVbPzd_aQvS{@yaG)& zp7*=IA9)bg#;bYH1!d?r_l=^mg{_ zsH=CM)fttp6FG~>p(9WL!BkA7k`Rh9Ewt6Mr<6ynElE)ea?p~LD&5HVgC z7^gxLzK&#eKJt&u^5Socw(G^m&R6J6??|oIR>DY8Q1z#Mf*{Ed2{6VsFv{^*s&RMe zwx)X0PQm9?ZP6xa&%;Kh)+nHBOY3LF>t-mKRzNcXG$f+wc60|L(lZZ9@vUfP#i~WC z6e(Z`a#~SpgSgRgif9+ze0<4c$guFPv5}3v+F+hShe?Rtq(?FYc{&DZ%cU5HlG6fB zthxImdz&Wd0h!*_6M3io8D*`}dB*OB9@(R&G=GbMl7dA@sgdD6MPrX%kFk#1NCnlJ z8cbw9n#WFB5-y#WqB zNFD2h4=E0fh@h@H4WIDPy%GXh+>rs?&_jNwedaatdiJDN=81ZPk}rID)}gfeprW~? z3`1u_3iU$*ERUiXdR9VJX%zinTah8Hr22_3W@ZFIm9G87b_j_i<|w3*4Tm98n?AGa zZlaP3Q|3TSo2*wyz|+uJU_k-tp0<#Y6)Tc1kQBHqB&f)eGaZ`0J)`k;^^!Dm>6v0i zJEDdc@X()1FS+m*brEP?wucDBT5Ck}bS?WNHz(fGbvH`pp@n+YarJgDnfEk4U5c!l zb8Yk2(6U#L61D7ZbBfZ3eK2#tVbooX$I(``)$X1i`8+Pvib)hJ7HUZfZV97BS*`t0 zt-xra}2E@5fU&yXh7m0v$_nPbwm-I!N|yn=W74w|_+fLqhBsOSx{S zAt_2o%aX1Z(zFnO9-UI6{NS`=fLgT^L&-=Jsi!MG_EXd&7pMkKukJPrxbOh3unwM1 zq#PK`)BSu%NA{$zgCK0HK!MVrh7^HZwt4nprm%`v(Mt#&tVfx{EDcd_ zv%wy1>^WVnp^;GH^iG#GNoLoL_)GALBz+m;+VSmV zR3RvlAIsmx+ogb9tohmJWo$;d;1BzJWb}sZHUr{A3@#LP!1+{X^TKz1K6e08Sv4-x zaVBgXF1lru4b$4=Q4}T9sd~IyM``WeM#fABWqTb$i6_afL7)&0PoO{aNk=H67?fB0 zm6j|m_;$jp-0$PdumIL0LSp5dgH`GIm$l^7P6{sQPA0FPUDow!^Fp}w#M6`Bbapp& z2AozDEt)5{ReRfVCR9g58cxBFH$tLN+Ry!VH%kOpbfTD~m zE1z^_(Zv!N9BmGB@w@~$m&d|EPlHCgPhFCZ$Y>8YJOcpeqn7m_lc8of@r6tuDI7+7 zKlT5HzsD=(M*aISfitu10P~4}0%FU75C_YC+m`X}4!7~nZX_7G)Inyx3Hk29+7myI@M z^c}tyH;1CDNW@1;8p2^LA%x3?t8q(pE*=>eU+&IO;g! z=&tD{_R3?lbPytM+|f>?D3GmI=#f?fNyy8w6{E-)N24}LW1_f%_MDB`m=rW=JBYS{ zE+(_)e=gL>YC9`equWeZM4}~nXw`XX9**8+pn^o!L?2E_Yf7MgH+T;cSd!MtAPcvw zeQEcVz#stm(DsKx`%%%2A_F3p%BIZikQ1KKm-wJihlQ6hZbHtM%*Zj%Eh>c;6v%pg z&P9V509}16cXnY(3Uq`8tRFo^(WrEW09UGYq#C=o@NP$*s@@=JrkefC+i zG<8cOmrxv_BVabbDT+DaAPdyYE|Wxh(gAo+M<~KmlstMRJjBLm=`)uh1tkbev!t~Q zC9)^q(Y*mq3c%DAl=)-`!W~Z9qw}o4Aq1@{u(d6H4g;@ zdR8$)-X#Ix`T@Ht0&s){KzOjJ!08><$DHH)pPFuAHhSp~KbZ^TvzJ9J5G~>3tVS3- zK~VtO;3-8;ddtZa7P2DJEGc>j(MJUop1m2#U^;hm)?D=P$Qr}0Ps^Q*%scOwhdF3T z2MDKvaweguK`~vVNzCG^J)^%d;1O)Woon{;9?f0$RegoGi~IZOX=ead3tV*@}yOKNKO5 zIks+7w{%)}cz|GISLKek0;v^_8XQ8l9ETB8$~?k7f@XfW32g9!G{6!7T|o)y^{~O| zLvsS50EC2*^l^~Uy9X5Lo!-X6@zA9?1{;$YypKo=_jmV!$~*C)eJR z$`$PYOwJL$p0+>oIa^RfkJdg7Ki*!xilgUAE{3Fss0Mz0%=rJ zmU|MU28Nr$8^4bGg|zCmBN9Tb(61m#ND*Xb9{T;aUs`C?XMJdHJ+!v7S2xYWla`Ki z;hZqToVgIMQ5$MHBIPR088~!y+?(sMWbbcB0o?U6oLSje(n1Tt6$+Yl5#5DuSE|pi zmt8oLh7kNw;nYKq9*7N29UiSX%!^Ucf`k)nc}O4j_|ke32PLF?TF!7IW=%m#t+&M9 zb#{Tu*RS0M&;rx3rA5Z5BBM>422DKah~hOpEa`+0a7OLDN$FV&8j2Om#_s8aI+J?G zgAXk?KFF}1@f*A)U-r;G9=mn{Kys)NZ3xfN(^NoJw|4gN_1kDyoYR}7&ugVui8&5e zPfsvcHCulK&#<`-&w1-txaWAL<${(Tx+J@qLwcL39Y)c%m#Ua7U)ypLW+jc06l(kRcs-F)pozF?KOa_h?f-BVTX=&5P9Ad)=CL7_AL< z>*Me^&+&Rbg@4GJ4myPNn7gNS8DdGXtfRpN`aG8ua>Cy~SB@e;A>b&I#uSGN#yB|D zf(i*pwC)O=|3zN2^LzE=;t5E_+K?Vw-2>>}2C?St`O;c!ZT<`oX?o{iL8nsbw7mc6 z;0zZVrgRtEi6%=yL3lV6p*EcqPBNVgQ)V+HBU|c(Ch@?=9PyD{h(H9Vx3)bzGk1#( zN5kMFDGYU-1>NEk$I}CJIFD^XW|Z=+7tGV&^d4nJb={arp;m@VlQ{MNI&wr#SgRMx zMI3rZ+uGULilwnPs!w4dot%%e+s|Kn@V%@U(O&oeDwD7n{FXSivvF%ZaD#n&|8@4F zw-1vGSK%Hla{Y|BzGCXsoVE2Mmg`5djLVJ?7qA2w2KkvQo|CD2m-U!X=oYMj$So1g;NBgSqW=BMOB-{WN2wr z8U$C5N}o!sCC8o>WQ`smLus-;I3h(_kEZ8s5Q;zyVLi+!q;TihkFDWYze1^a87l>Hno1V(on_?kff6z}pxS&&4);{t2 zRbG`BE`Q>1&qK3MfBtoEz3sKDzNk~5b#+@0oZ73ErpUF|JaOcKBVYWDsGAAZ|PCg)5_@yH6> zQ0{MbGx>q*7cL$B(5Dh2P$%r!Fu0v|1~meMh^R}rlGiu!8k4#u7NErPI8JtAmJ_{? z_A)znzQ+sZ9v|?Df3k;qyDM{a1Ot?Y_g?iG$L9!s@a(;3XS)lvFjqe*&+MrY| z^){IzOwp}&MEkF&37fpzLZC%9C*Xx<#inK%h{Echhs+crn_}wK1IIT%Vn)LLhX@w7!W!Gx$Dq_$&DVGPZX z98cSL*!#cfdOdlJy3+A3M(f9l9UW!0DyUIu0Ma+3;>i3w_i{>cV1-E7c3+OBbU0}U z1Q~^1Z#=I71_aBJ8rhOcm<}0QXmU!p5=ZB`v7`)Rpem*qpS(*6Q#J;c)<>T@f(v|N zdEGnD5BrxMT;d(ix^!~BTdsWKRd4?}UDr)MTk~trQR70sbT1Ykcjc+|+djDTR|c=X zi5pj5Jiga~di24z+(?gf^ydd1^i`X5Jbxv zcFQEm2sENM@L`NW;O@RVRHh-bO(%3X@y=ZvT01>n`h|gan8T+TeDM8Ad+YJuFHFmqQjFR>9pm9ToLiPer$udD~|{bagv3>T74A zbI8=SI=XihdRIr(q1)>F<@$s1Iza;VmKEi7jhrCUB3py7u>P3yb4Gn?F^(t2LIWax zx8GL;7CY{?;00T7PmJMtblKLG&O7F5t-o@CH90gBIz5)OSkqVK%GyJI<;-jM1*%_d z=kS3aurY7BWGh%%MrxjqTv$1?ej&cd*~Pf*v8_Gnx>yZxf}|GG>aTRHzO=beY| z{Nk5FS?A_+t;fmL%X9Ip19kgxb3|O;t}S1N;7QKaN6Vu|%NKp_yh~4NTE{88&30p_ zLFVB_bvEg!gBmb3%h)=+J9UT6c7q(d2GcNhga?U?hJFFkaU6&}G!(b2midp{SAq}h z%5rD5*gRNUjxG8WMNpxrWBS2aRXle0vJ>EdDKF%Wc-xzf-FD7jXrq;CiE7D6b*rr< zRy3ls6tY=Mx#n_Oik$Yi3vcpHv4t{(&MU9H`TKqM-S_7^D zE$std_32)z4ay=`LEa4Y5m-9K*+U1Sc_9ye0 zUszJM=PV0nJ}WNHS7bi$VO4SjK3{>N+U&Gz^+@BKXU$MS8ykGF$@x{`FaICF@WaH3-=(#bVoz5a~hjwHfT z#1KFcNs!Xd>Gh~3wXP$fJn0HoI^Q2?(2I}ME@QTCR4lnRRm!B&Vjh(wM5zO=gn5Dx z(j0m1P?uPvG)E8+ogUd>D-XRb9oL>Ex)ld%rt&Z3(AGrGRxb~dMo1ZdnidfVfAAN!PyXwYV*1mK1)4hHCjB&~Dz4XwvS7dB` zI{$c>`#vseaUE_t9B-LUC+PfH;qZQ(9;Q!6fAM+^8^Qp(BwJuOGT$Oz(M^ zDs*4>ot^B4zO%(hX7Y~4%29RiU}TbX!TE{-^EJow%k;~U?N}#kt-d10t?lJQwN(fx zuu`(JrIsX?Rh=|T*@5cV>WJ4rrNGchZDI6)gMn83ljtB8_&9-ZCoN)GOYXVW5}1b- z3pm2V3G~s?!#%9iLP{rP8Sqv_SH36jGAJP@loo<|Bg#l8owe^}?Tv8;MU$Y!qb1&d zQD|4wm)<>zD|%phUj1|Xi!MD@w&r>;GSAOFHxD0tfLh?$Yo6*>XZ5v9 z9B_?u)R3;z%%ahX$Kbep{_@Q$2W*}?bp+4#7d`r@#c=5zZ+^k%ecKC9+~Y9_&$?&v z@rs24s%eD6l`jJ?|bZWbSgJNFAjx^Y28vVMW1kRgu9180JRvA7Sx5S2gqDm zreEOED`y6aH_?e;G=-hGF)nu}2_GhndUb=Me=Cy0S zAUxsM!o&6GP;blI&pq^3-*}9%Xy=~7x9=MQ3{S(;vALh`I-Ym?boC7kzx2DVZ~u`Q z7C4E+TkZbW#POFL^k*LSj>nFoGB)S##$$HJ4!ZKl>N$w@sSo$k^dPD7%#Q=Pl* zU%GlIuJ|33#_F!jo@~-l5J{&bBh1Ks=E=KrG-64pQlpkr&`Ezv&$tPbNH1V@h*S+C zeE9TtfTn)tfhaVIqEes47Vros8^a0GkaP=@vTlSIuPA^A9YEt?L}SVlk#(FJ1?$}$ zAp~2%0`3JyDS|GF(LhHwCLnqm(2d6K6ug^j5L%Q2KkQ>+gozOu*E~|51r(MOeavMOM0=5eKrbOc`g+#W@Bv&@@Gc-0@przF+TCy>b-AT z*6QZ^xljMfgFnG*AAaxpLsp6=Q!WB=H?wJz+BM;7Xpelq$8*H zUVG}Aa(WN_OxKuwjIq?o`1{aBM&{OiB`e1?7JJpxv5Wci>)9VRhy<+=!aZZnsL?Y5 zT3KdHeO1n6*j8SxR!8^W8*z1$O^J1t$pd}YmX%jx zO4q2a$av_qGci5hVfTF}$L*Tk_2S`IzTu1)j_2+Dyw9627(ZcskW@XR>x0g%|Jl#m zE34nS-lm>@jkZ!APhY?F?B&q4LwYMcuHy^mzqj@@`6ygx*wq}Tf0=d6^NvO4N*sM9 z2X4HwFXS)o(;j&IBJVBJS}xy+`45Y=ERty1Erj%Kmj&SpOIRR~%dXpNeL8fCY~$%$ z3zGy+CxS%AsKT4inY*)(Qlq+r$HY%$^P*Ak>lQ%1j<{k6wczc%o9FZj@3$k>Anhd1 zviq~6&pxB~rC39c(Az_%NGrH2r`xDHoh}KFhNQ*gTqtHI(psCT_qm>$E|$v&7<{rV*5o~d*hWawsQPmTFcs- zAAS4Up^ZZs+N*ct)Ai4JlZBFf^8`lvsOv7?A*<~}2-9wBdZsRX%K5(v+!xp{?;X?x zNkG)cCGm_4I7~Ye1a0y9Gw!Xg zeej*%=@)>Yf<|(rjYN4o-BCM|_Q)91wT%_WY1#7o1I?BhP1{PW2Ddu26G_Nq)S}ae zErho^6DjT5iTB=Elhx5ag9b~}w@5w5fVLbjNP90o# zk*QC#>x9x6j!Yh|Oq1=MuQ&~G(dO6F1QBJh*@DzPC9^`%s$hFd#dg6>8<6@D!z2TQ zbth_R^fg9r4T^(ANyt%>16H+;cJH2O-jXmV8KoMJ(e5dycgOLJ>S!5-vucKu!z@HFz$0oVe2-JEq;!oV%$l%gB?J$Y{1orqy+ha+)niEsk2cfpt5I zbDgRQa_!9r^Ng5or8Dr>z4Jki%Q7T&R)$-bhl(kbt+QGQLnz!R4U@njz<3RvWTJj+Rid3%q|UV5n!t=EvItxKwux1YC`sZ5P=h@Tm@-56CY>EDr9Y1q0vb$)z4HOEREAou31GCQPR!U=NO_N%3ut@GOCJlL$*=jgOi2<`yw|rD_(A z*39NL`}$z9D2+nl&?7KX3BO&_Ag&7|B`VaW|bzPX{skmG7`bDv?x*&_fttF%oyEl3zQx@n+0gmSYcf^hRmhZykv$5+KPP*GTI$H#=lV=6J!q`uj2dJuA4K?p0-X;0zHdxOW0otD(?qLsJ<6BJ3LFxr8)^Tb7Y1Xk^qZh;3uaD}Q^Q(A_tFV1R8X~`DQIEZY63-Txv%^CnuglT82C2l`xmyu3asz6!~ z6La&~qG|@sqU1;e#u%f-PAys>P1;!;oP0(|5DE1Pcw#*)GlgHY$!(xdP-m z`hjYoBpHE{hD;Na5aeZA132h-!CntatA5zCx(=YH5#6|>$UbJqba&gWnt0k$7#qt0 zgUMk#=W-u1W$zv>TTFyn%)~WJjmbDQ*&rB!vQG<$@R*h$v1u~3B`k1b8Axcxvn3VM z&68TQ+sNvvkeNwGiNdVvx|f%aJ`e?vtc$LI;BAL;DIB4&gg2G+Fd94k+FJUxM-Rb3 zD1f?VtIq_EtF2|NE8s#yJBARLg*IQ%cSb8B>{_>4vP9$Ylxy`GpP6}Bhwk*^NbPAP z#R<~O2t})WN?Ie!sz^~HlV}38f=XdMC$}%Q^)-2wGc1k4K6ys1?hKN+8%8AFK)K&faXD<)qXBw>l#q8n=T6 z)w)Bl`*1NqbvLlmvOC8FT%1*BS8kdYhd}T2aG{&1&IZD13@TgA-#Yu($dGB^>UViNle`bjy)NkOa=e zrJhJp0kV(fjnuL^D7h>5u_Z)GB9bug(F9L1%!>=?%{x4LQ=fDXWqs6=kb}^qKJV3* zYm~4yU4Cb`ojjyKG*Ln8OGZaMB;K5R{dG;RE;?;D6VN_;MfI+cP+0o);_H~yfJTH7 zo$1JpqQ~PFHC-4YiS(8tHOjPybl6J}cT96gLLz0gP23>FphU8S>>+WWlXCO*WQU`{ z1`>lo6T*o`jfk49K}3>K5NWWGkgbY#G+|77mx+fd=?GTTrh_twt(9SVU$$tFyc?xw zB{f@D)>&3bbEz1^pl~J(h=za?^bow8C{pR7Bi(~y2$xL)6;y0ZD4m;|CyGgbsNE0t zJ$KD&2xCL`VzbvQ4Rwdz@dyzEglfL${a)SbAGUjlRY^LbqjqhF>OinMjv}v`h)%P$ zVI+07DaDk6Y6x-FKBOW@m|%iJ4@i>fFb2{=R#Hlb#ImL1$_RK*N~Op09A33)r7f(< zjUwlelaPmA0$|iM#few-a-kq@`GC}KOx8qPJlaBlqznD0ZFTcCd5f%Q>B^Q)6#~gy7utriWo&Z2s zK!4ocEwWTnlx4;Rop@$g>dgcjj*BGx!g<%)M%>P1a*Z*qh)Yvu4*+JC>*b$(WG;( zI+IR2QjgSbbm?3cwc=J3q1JLm*R0Ytzh z4LK5)oXl#U^zfjEt4oAhanh~G1u@dmamchXi=D!4W>n*VmKN%UW|D9%g-Pu2|_EmqAuj| z^^_n;k*Z_K47+2Cmv8h%hRbg};u!IMXcaNBLPnv8%ZNgRDKQz|Ik^#-(&2=<0WJm{ z#kxtBo*)Ez8YxQI7@n=W0182PsIkBq7ETJJ!BZXzhyoOZAOId&gERbgkehK-@#xu8dZ1DAI#+&@F;8EbUI6 z&Hkb~)9nNct6NS>1RUt2EBDH=mZ#kuOZ2|1911~%oSf`vx$kz3+P4`u7q~nVFfQl| zO9y-kamTv}O+s3`Gm1GwM+ku=ozX+v+SvlNtAFWlb3JN5H}EAiU5USfh=oBhv1k!s zg`jsCX637bZyP2dx?EuqEu&7!Q2|Kdj20n@^biCQ#pz0efM`Ply*DL6x`#qp3u*uY z815=^gb)Tgx)SDS95+r(&9WkJL2J@DuC7MXf>N*%=XI7@B)MPXYPMMwEX}H(s7qq+ z3YAE>MNi_IK2{&y)0NBQSP~QlML`ZqYx<>TE}6~|f;BSMOgXKduq%Cd_0GdK>0=$a z9UhCHBq(7znVyd6J#-EyCkaBBvCLrNtY1#uc+qhez1wPp1|l!*0C;F_XD%Y-=$V)P z6*oy(XOW=3b>jMG7ozjS;IHw1l!*n2v@ieynN$HhC)vHzWNEaZ6Uf?S3_%D>DJ6#$ zd(pkn<;7@);VMm}2U|Em7>iRL@DPivV&bb;Lx8B7pyY@P4F23-;^c|Gb(g%)FOX_NKJt#py zF(ZalvZEK{zq7a2&7vxFkRo^Z3fB&OejWs)$XWsbqoa-Zo_0L>mh|oE-S%_cTmzyYaObt|+5Kh7}^mc6s&es&M{boY!Wa zufxb9PgVt628@&fo`@QTq!kw^geM&kqA4krCL&r$eT;HBZEBN9s;vv_!AI56jyfIb zN(pJY&+p-YaFiAK`x63$B>zw}yvtk*v77czeDW3}FSjrTs0-t&inm-XeZ zyk_`{t_fP<#LGbVgt>jCKRGcKV^+sTtsqZN$yykuAJ30I(!DP0o6p;D@a6aB?Xy={ zr)5j2H#`2)r&C{kiKH`)D?*kGC5eai#Dwm;6mhLP#~Ghd^SC9dyQA^Sb0};t1Rw`8 zNf~!Dg)=pJGR_)rKE55lH1oNVvHlMxIxyqj$ZICug0{(RRu4@sARW zo8)$QGkKeS?o2M3+^w6?paafhVim~D@-yOUOU`B>VgZl0Ru&4Z&J8YcoBH`P{&b{!ou zs!@Gz$#KV8y;Vy0Shh=(xcV^{+v=;O)~s3kohf=Qj$AQRN6xmAMhXX^XCdFU=;%TV z5}`(Y{ZthIh;MZ2R(f2mmd66G-hB{`sAjc5A->t*C>zx*+L}g zAfUxW<<=x>MX1$FqPt3Th+V4oBWWbcl_#sVx^p(m3j5~ix<)lc7GbjOCWYaIfZZpU5akd6+=nlfpo%WNJ7viHO$T#P+$ zzcQApQzl6zL&8?K!MdA4LI$|+H2q`wA9a6>($mAu^acBLz%P)PldsBgN^Rlzo(B&5GdT7#-u1)K3go?Wr52QCc>r)ey6zBo>2!KwI zat{wm!PdhNGW8gPq5?1!=UB1|Aw*E^ieu724i?v$B_{w9jx;4b8{56ogF1r?f;u^B zv^^c9;9W6_l>~+oUPnnaL`yZ)Hhede+L>$4{%8vvU!R;UL8eKt$Jx0wWxB&GPpQ}8 zD&=v3sCS69vOhX0o|8mKbU1Rgne1cjYFe$fJgtrerGO`-)sj-#uPQCPySHb{NsKzQ z`S_76(>_x$==^~g#`HOuDGoeCyrq}P`TQb&I`T3jp8A))?_iHld-mcid;s$)F+8s< z>1b@u&qE@jatW9<=(1}Mc88!DpR>9tT7*2(k#G}wTN`&=5s<~}pOg{;oGp6Ki`f!l zgezQWz9Ww&;5~)V>~QP`D@h_sZLU$kwM!9g12wH=PRwJ_4 zbV*^2(h|wzwGJI!4xlxqXg)~2o$GGAKgTy!Pn72 zVGXfW*<5E_$5Z)@?wuM4fK*I@a3@{q)b!5WT67OU#FrV3gky8#x{f|pN*zg$;-lLk zG!h55^WZ$^81K8fU;D7pGa@+dV^A}bY@?;p) zhfCwhAntnwhpl_s*GoV0s~@}~5)s{IubuG0o6b8gv^i32;G_3xeCgCBm&Qumov0-c$4*G!D zgk0@M6%aujS>Qd-fBqYuyP$iul_pLNp}xkBF?!`8boJ^z1Gna&IV$d^_k#J$g7xxp z6Ump;Bt3b6X&0aKhupfE*nGqProJkHC#LoZcdcH&To*^~mF8Q&eH?B87T-O1*WJK- z-FnZdD|8%s)4`M13;Ww;zSq{#<2WhYz;3mF0bYHf_HA;K_gbbTV!|4Y510p=l@VA6fa%ev=n$pme{Pn)km!`@i+> z&qH(Vx#nY(<=4hz?acavOYszR)cv_u&>KCa%;z^U$1zd5T<%$3mp;n%u;aLD<0Yo7 z4s?xQPET>iPqDwaFORtPG7YX#PlH5onBHbcWGijaZz%5Q@AFe-;ptMC+6y<}#S*?8 zBr$fv{rhqM`~lakIx&FVbkf z@B85ASbX&Pd_6V8kwuM9)zY5ZU(yqP$8GoU(mm&%zp>txx8CMRSLtuGh27@sU-XN= zHNIRM+iYWu?y$L}%?tKkKG*d_Uw6O#F8k(SzCrIgFM3}&^51!M^>VK!F5uo*Yumf- z>z&uW@VRGKfBAQ6P9$GGUw5lrKt#Zt@~wM-g={K_FReZhw(b}(dV0L zBBtdIqZJPcDl09MOj(!vweS9+5BvW8nTKs(87UDxEm?YY-ygUwe)Oc%BqDl#-SJ0LFlGS=%8SO6WGy5n)+|m^Jnz zlnwWndyzcUgaYg6&(6!lv3(DVdEUN#b@8Cqw$pC+P3Zi&C3|FZ!)}@H`|QhhOT6#3 z$0zl%H%%T{T6g}ZZ=s#fXYj+0{_9Tqn;y5@=j%PTWzVt>ZTepR#9pQ|9zVv#dHFgl z)!bZaSL1<4=d-`!2YoQ~SzmMJ35SLYwtnWN>!_bjJDQXQ9%ehUteDVW&&}`ionNgy zcbC-uu-|g4uAlri)$ejKJD+`4c+`69c1iiZTzP|L5@)!%;+2*`qEy%=yP8=&>%1~f z-BW9Jlk9TQUbC-Gk4kz?)2mLH>Z6HhDK!&SQ`+M~ZhMHlkmluUXYbqhJaMGpFM>6aqZ#R_PrbHxxi)N{q^{I*t5}Ud)|R{NSm(9x3-tOrSFe- zAIA>tU9UIeFZ8~zdS*|%_=<-X<}=@Zp~H>w@&obAdEJ+dS1mfeit+eANgFR;=&o9X z&+`k9J3pV351u)rmp;j*_5F6=(ciwVH+GzTdqeM!`We2C^*V*JKV@Hg?cB0kpnce@ z%G_MQM6cf6-hT8;$60#wn@Y?J-s{iu3jgn~%WISUxz|4a@+U9ZpZj<|{^DzYm)#3g zrVoAe`AdYo;sRVuANQXw5Fk4_+;`J83q~YQ%9nQ(w_X`~1>5 zOFj2*bG+BNf@CHX>+N8#qy|e;e_MRBB9%e7sI;=h_3f2)uH#mop>z)J`bwVG^(9Mt zZ#o^ZF&qIWztZ&!2;4V!(ml8bo~1dCbO4ykW%1gDLzfn)H!Nx4gJP|6+m>Qzonf)D zl6(Gxrsr?I!P6Ht&v>slT}N@SV=1AGlHsSQoxiU>fa`L&H6uX7(&Q znW+C!1F~#DIYxjK!{ysDH}vI?h5F5^Z+fif0ZW@K?b>fnS>SZGLwv4p&Tm@jjI+w> zospT~CoZ0)^Fn$Yi(9q>bl2HBYQ9w-nAQUa?AK|~8xR1AQuED#pPERu;R5-}PP%37f|+6o{T zbj-l00SMa#2Tg7r^x`x7u3?sHU~BBb)3yw z(mK3N8{9I{6SO?JrCrdCKIVY--gMpI!1XG#%*C}6R>^R8wWnj(M3;{~?df#umM0Ew zJ+XZJY39;1;8+-Ygvwi78IsTJ{gI#UJ^QX-?!i;ne|P06|C+e{n7*hd9=PD~3&+h*f zdczsPa^tuZp(EUm^LS^r)5e>DhE?wLU~tG@4|haC3j!jM5e#T;$rB|2L^O3KMjGLa zBW`ShOjk&A)~ARA4yuBb4#5O4tlbcFY9Lt;)26yG3wz=Y3hUq*YL{X4ai1+^K~^cU;V;-$UYzv)Zgzn9sAQ$9`gXd)C+P|L$79lAp(EaR5evQPw5 z4XlfLtqd$uIE>5q-#J3y;4h_os!w~PGejc3^nhVIt=9}JU%$@w0FxG#9R8g%Xg(SN zlEr_Nym`FRh%sHLDdy?#Z~(#Vp3;QEpzodn)G_0oHy*$W+lPQVs7No`(=tPFirh(R zq9JIPXgOZ|PA89#CZ)LIS^%w$J_{UZ>kfc%`*&dTtx{oCId*l2RLl|RRG`@Kg`yCgaYWIv z8d@*GdcHr}_3Kt_<-y@HX#yZMcuwD=GY=%AGlOv-G7*-1_oUHdA)pU%+O3^+v+mrl z^f|~gZCch$qByqsv|c6>8Co4h69{w4{os6w071e7qCWh#!}N4@EXOetjsS!b(h`aY zu2`P#9Bq%5+1ERlxz8QV778{8`0aH9xtX3Gz*?4iy$w7(*uHiWxwGWp4i7tokOA=@ zBa5Iq?%npi%TOoA!-*5az<@z@#KnQGuO-`^<83mW?afxVxryQ&){@}CkWGj|P_=On zj27`J2!Qa6GYY#nRTH>d5SY(P9|ai)*3z1->+4}_Ko4!{pyL)6k!0dmGt#LCGb{X| z8d4VpUv_Ozb?pSKgU4EX&%WgDweh09709_j z(3a_>7#l%(B?K(){2W>JO7XsqjtgyCj5d$c{{L`)6oH~wf>L|KR%F?D*;QQr%a}2K z4H*WoA^;diDnAGAzkx(1BBP>s_az)N^7=;3x;D`;@P1r$+|;>mdCup+e2VwsKl)tB zW$+aO`Z>2!&5^V}MXVMT1we$BYh@!ta;F8nl~4QOZPp3l`E$pn5EAHQ@M#H9fL;7z z-(mOLnf}c_sVARg`Ot!?z<>ekFC~!hHMTJUI_R(COMN;}e)JsdSRA;2#f3h*TF?Q# z@rJRz&gh{>!e#TggR*4T0nPbTY2@_-x`PRpp_HSro+X6>e@@Qj8A+G ziMEF1pm4bMB6NGYc1wx2b`bU!eClCed_cg#!R4+!oos)nWHKXwxX>wpOu2)_!L8ed z-{tEpJfq#gO>N8Rtz&jF*VEcOx^l|Batwp8r(IH6zi&P~U>-@BV`y8vc3#)x12)#_ z`u81UEomRplDMPa)SN=at;%BRz%!l+la^idiP@FR5AC{mg3U9(A6Hej8Mwf}zWXN8 zR4hF)iP)iQ*LIw_BEN6jKD9y~sis$8W|Ix6tzA%7A34uRI&JHvwO)U2X@&&Hl>Nru zqW9-$-tu1ly}t7EqjGAP{E22cy4(V!Wct$)Q&&h_4R$$F0T6v{;o6hcckrGc+_VUZ z5CuKjBgjg2wb^@~eFyHvPyhIAn#(b%x0ohtFSbBX@y2 zEQ?aL)3vM^GZSsc*NxC?0>-gnyMF663Q{NiA%2h_IjB#!+>X4!_@f;TTRyp%zkLDw zjTRc@4slC)!8j7O-yGI&KO&C1fYQ4Ck@JAAKPOh|goSzl?V(Z^TA@h~OMAv4Nv{Xl zW+#Fu4is5rCoIe`l4C>$g~NJ~iybvtUhJ9>*j5A%5ODbb2nuj-M}~Ar-evaq4a;f& z@%?E;l+~unAnOnkxMgs;%Vc`Eb4f^u#4O~YX{-)B(Hx(4!f3y z_=c-hY2473g@Qe+9^O7K1|XGcPq9;NG5u00^4%GOSq7f=wiegsi7!4OL&=(r(|#SJ zMEAe4h<(-bWs;xd^u-$<6Q3Ra(|zXypS`;kFF*AsvSRenU-5f8bFg_^H__=WGSYBI zYMdE(@yxoZ&?a3lVo&-8mKt55c4@Q_uh?|V*nWE3b3QfBr}ucvd;KG8C+qTc2k~pT z#Q-HrsQZcV7W9bifFV;(h+z*d#=?=!PjmveZ95=ENI)YcF@SLDnxm&LFy}?xJ6)gs zVXg`YwbC)|VO~qL>DN$i0%?nT7`ksHl zVb`XvMrQX+HoNINE!Nzb5=6g(yTc{7TJCvxvEf$mmaZ?beY@}#r|Ypgw?4CcA^7&- zw)9r`_Q8HyaPzYPD|6v7&kN5j|K(+O&1ZpIOVK4$hmt`djC;}V0&5J!z6oRoGyOu5 zLSibiOrn>I8d5Ea7zJo>Cm__a;#CKiVpmvmp@AgzF$*X)7#wiXdywL|6rCA=f+!rO zw>2Ovz19FB_K+~D(SQjk*G44gWk?mrQQ{_6YbRW?*<(WpLJK-1UkQNKB5zfWk-o`b zH!~uS%2hQlUUfmn8I$AjW@D|t9{>2S9=S~C*Mbf0xkw{;T+cV z!tTVR3jh&9w&<>&bq+5sccgP@JAR4FHayW0^Z<0Z^rp|R&$%3R^Lg&8gNbVr>!!D! z-gVmZCV!IF?3s-}0UO-ie5*sfyS;Jsmqi|OM?*cdWDi8s>gF=JZM(dv9G$m-ThL?S z9YFL<^k(WP4JU-2D2Z9lb4L)cVkt^kW20uk7%A%?{eTn0h;q9ijcH11xDZKhFNmg- zG=^+-NncTlPuAd3HR2FJK@ZSbP!J~{8^8`->>c#Y$+^MdaewWOh`_on($aCYEA)Do zB^R?8UT^H$Rg#5)T@g6CGbB4hH(b~D(XPkIau{4owQ+o%iLU?i;)Gp#5NqxNFxfY; zX&eATI@(KXI{;rNJF3_HyK_#9I21{{yUW+}!L~0!mb!35RF>1SB92)7KY|_1SbZ#X zP4+Bb4szOR1W^<-JZ8{CzsiEKRqT%Z&iyU7FbCAii@*FP8r@P~{x)z2m}T$u;rmyo z{I8NX9f-$#ifhLiiFnBo<9zO!A?E6aNKq`6W!~Vj1ySWir;qmn7Da{ z*&2qFG@t+sw#t0DcRf7Z&3$v%`VWNcf&cY%e>iU zN!SbB!8?ZA0UAy$x4GQ0rY<+X^CR}U!)x33y4POi*Ply`C-s;1F!fp-YsA8`2V(;k zq!X8DJ6nHG?BEQF-&I22+f30XU)J-o|AYXRy`If3I=RpwtJk#JfqySMoH@46I^#Qr zHw#8b7q!Ca*jdlYjsfL!BDKridHC!7?(T7EUQ09a?xbgKeHGnKvbkvY4N0mu>cKgY zk_NU$&_cH?>v??7^bFc_br5G=@6`MLowl@s?apm*^9?5s6scp}E*j3({L42z!5+HB z*I`^8I!Kx2FSli_4o&(n9?&iSBXDwA2f$iq;jQbp9q0fM_F`ey*;<sUNI0Zd`^ zk>1s@72BQqC3D5(V~gSF3l~(}vxXOVK60ov&sWt$lQ;Ab1P@sX;7-bssMRpX$4x80YOR-&H`?A8F3`M!${h(Rst|qdZTVqKV#{#HQHY zB!TS9FTgfa!gU>`ZzEih#|Q9{FWc*mlZvme%gXhaTz{|4d|bD@f97zT^YMwjb`GE> zI+uyE4vJsv)}W);@Ivr{b<_Xs z`nhpO`E?(oceK-$$AbrI0Tm1ZW4ks!n;;FrDF=jzj1Q&OSb+&D10hYNyr`VL?-FN-BCy zoKkaPo`QjHN%nv)P)7gWt1jLi20fOH5V?14}!^uf7Q+ z>tfnDF2RA$9$eBxC?zKk0F!Elr*LNwfar)sh=Lt-sJm0bk#*8H35CGeJSM1S6xcZU zZ|_~%Gx8%T0wDkZ)dbNV=jyWEDY$Rl)=Rvse_+iT44|&g(dp)VZ*%h( zGj&oxhni!$MURB5HYM}?Enng(H})>D^EDnF^Ggd^A8v~E(|vb*Z3$4y>N^#X6iToA zv~_jUwnfv7hi&Uo@V3eeUf#m;XAGA4&OB%|;#PIOBc-a1-v z2>UEn!~xmzGyfI1`0Bka<_S4D66fQcHFbM5J=|%Q#!Q+yFnjrTZv5{Yo&(1m=E?~g zaarGWSAGj=kvthlG0yV`0$ULK_oSttA=)Avh z;=80Yh7oQZyx;0@GWnr4Bx+*09lYR>T5nwa?ta()k`^S|6xcuG1MZ8hcdw-#e(UIH z2jeM<-@qs!9IhX{>4E*DyDK)iz(?Nq^S*556#wlW={m3X8=ael2fUDOo{!%X0M>z* zDf=oHFR6uPLD$>fdE3pAadftisdR5!OL}!y=*b?a$990zqa=Yb9bN9a4RlKH-8VUB z#AD!&*}=J6$gkjTacjK=e8qK=w70LbrgPa}L3-{_+w&csxZ~^=>oBe~F4`%7+4DmV zkftPr<^|HJ?{v>TpSsqGX7din(d60m#cJ5rInNJs;I?>kSg?Ho)YESXo`1Lpycw8( zwKsz!hv^2qMIHqoLGvw@7Q^q34zBu!@g-l`WqUSw*&}1_7>H zb_tSH9ErYxka=Cz- zX%f_=1##6q0q<&eFF|$^Ak_0h;v+YS&Jymo85rRX;5v-UZUMsJTs%Ak(BrfcGb^7Q z(&E>?O>Z^~fv37xWC!!dsbG!72m}CPp$*C-V?_GF5>{XKa^h}MDZBIebPxA^4Qm%F zZ}c!BAzjCeu^czJ?~s|Un0m<=vp;O}Bna!9$A{UDPneQDabj`Q&-t)*Yt=>lJwMSo z>}{|I_P@@@d|%r&TL}=Gp}HoFGv3yn&v&mEDc{B$9A=K*ec7*kG(lnvU7JFK2h*g7 z0Vw|RNS&Hhu%n@pM!Uc`c{LVSnd0~oZ@T1-lC#gwxhp$sILsb4+>U;!uj1E{9*@Ac zI}1T^WuAFaJ*=GBx?D1&`#*e6uHEa(FL9oIRI`&_f^f*Sdz^8u{O-?b!JA&zT{B;C z+t5BVkZ<%qKf9K02`~Re4ZGiCAxV3#dZz)c-SFd>TU++PNey80weNY~fg8?5XYpjR zHN8w)$N3_hpX^xmFR}@6=U^*e5CW2Mr3jWnHy1iJ2B*yy1Enmd!YBo7O{8NDv*p0jR6vpef+pT2?UgJ@GQ3ss z?f^ig6Slq%XvaQ|PN8<&xW`4od_qD72s%8$zi%OId^+AZ#W<{9dwVG;VGq?NFRTWM zV>SUTJP0SnMauT3mUOj`KiD#9F=OiYy?L@a0aewg(^$wu*~bX60DqYBWrbKEsJLP( zh(&eniVXL9wCeBV+Q$uPL2r3Axvmsl7piODllWaefhX)1CeSDQvp0ln(7gZox4(?p zj{}>p3n+$5?n^zS2BP0HUDia<1H%Gfublv4bwMi*jqxv~7Q?g!?d<+U$@*iG1lvo$ zhO9HxPY24=q?CkRUe(*zs_SoAOiEn885Z>zaWpBy+ z{;s*zy0GNyiXBkTJg})v-=uOZaqtf>-h7#VnsnP1w~=r3tNClhZM9t=l$uGA5x`qQ zIq~^%U&}-;dPb1f*Dt#sx8POnuG{`rUx@j4jx7ER^+A2y#D-~69-CcnwChgNGWFCu z>C-Gv^Ley-AG$y}7N|GtNEfMB~4<5pD2= zII^rGP*qF(x=cybsvd$@yB^;6M)~Wn{b=XMqJ)`VU*2T~8sKw78ubK}%`)L^5=+&! zcpX&|_V|ezhldnb`EJ{i|4_BQ$(Hd9?jD{AtrM|%B~XxV*S$co+Fg#3O#|4K!;2O($BP)uZYl%v(Ac#HZ*mFm===Pfk9z*BpJB)VorcbAT+k#(%aaD2stzkn? z{XNjvamhrIJgm(gKjf4x>BEbC?Y+MCsmaIC-gN)jcM?;{!;4W_x~;?4=?0X6ernvGnj)-!ES(m7c;erb`%8FE zH2yO$_>Ug>FKzfqWAlvW_GWM6+8nPnOTGwc;d~z3J3(+e$0TDoO#=+*kc(*yp?^E7 zB@S{<2tmqvf4}O&WSv!Gp(gGgkV~t{(2s^#N_qY-+KQU_hR>gdtu3% zdE>dSPhIc4@p4tuH``mt^8)yTXSNsJJMX{!@;h&Q-R=wTec}K8<||))!M^9s4`lYd z{KgwC^5VX4%7|}xLeo~?)5blfZKY1eQuKwMAJM~y_(flqx7k9z=I)yy%N%2Br;Y?? zr{Ud2ZJawX*_}*V=kb@fc}Ssp4-iW z@%di!z`AkYA8)wr`Lj#&wqQ?Tf3H2S>&N{im%%dof=?{DUkj>{6 zowwfepeMDm*uKez-Te2NaSd+nb|1|<=e%Nb{a_2w+3@PpJ@p>U7w+|iW>cTqY#n>J zbN8j$y^Z^3Jt?lY-Mo$K-JGMK<*8%9*@a1`1puf!)J3v>gMXS^*gFrm={z0YEdI+L z4BVZ0TQi^c_!i_-lH2co(Cj5M;t1M)GVC!~?CpslAXrwGOOZr;_}loQX+F#5FGSP5 zcL%%aX7HV3efh&RPYW-2y!r8H_AZ|vb2`uSb#9Zl{iBJSbi3dS=`YMX9q#U#&53`* z$^RRo|G8u>HGGvu-_hWW98<4J)Az~Af2aD8|KIU~f8&CGoy2e6?6Yt7a9W=VfD6N7ejwjgz0;y2vu`1| zBT%#>Mru*ROCla&>!+K&S_)>ujw^F{7aq*AELmEdR=xGu=;3y z^%f6*tJl)Itk;Oa0T0sApOXvmPzwa7lbK34q<7w_X}7WU90Sa0^R3uA{FUE`x|0vD zw?%uM8Ykbu{c95G!z$9>oowWf^|dKx>W<|vvUy4_Nvj^rv3C1C&&R?aG#RFSoajdM zX;!-#=$w*IpRmS7;wMj)9T_zH#gfMy%RC=BCfgRDJ-u3!Qu}z*|M0o}@&bIhxu5Pr zZ$anF7d^DjeqzU-W3KZzFOn|=N9EC_X*sYpF*q=T&V~2Y3NI$DR{#KKnEmD#|C}+m z{ZeLa--bRHxjDJH+}j?(&XdDmKD`{V++iDT&kx5N7*QfeZN9i}Dh%wny(^CQsnAoC zJEwg&WqNQ^6Sj7+(|_PUT+f<>Cg<|D$$Qc^cu#Wk(ygBKw(&Uo#k;+TzTNc0`lq#r zWt4Rya2Th z-L$SVcjj#wi(DYC=L#i+oO5lNAjoAcjMYO}#lkz3kN$J@s;)p}%CjN}Lm{N1Q=`_T zCF#9>Kh->bPvUy=E1#}`PwuD z_T1U@+2EdVH*@c7tTVPZlOy!~-%1~t3co%Re17r6wX1_GJT>wHNlrRBGMQ73{uA5z8%<9dI>k08 zG*R+yXoF+2`MAFQi+2ZO9ky4RQCnFlFGm#mz$VTg2oTvk^QVsXOH6j9_cZ?(^_yFq zyt|{X!LxVz?46!HT%2Qaeb$eC*2^tFP42wTQeK<$YZ?pzbXF%Jhr z=jPsV_oMy>?)w(Abn-OvEF2<-HbEyr@ak;{FS!e}X#^%Oq-T8o2cX^e$+WFW3!>Ni zi%LWRj}AEf)ox6KQ`vL*`6fX_Mw8R~*l&qz^O+N6vUMnnr`1`xm`tZ#L{7`ZJitnKF$f+{E%%rvu@f6f1>yDercGgl;_Xm#YE)`LwGc6EBE zr@h*bD@tWoh^-MDMM-pPLv1TZHw(zI<{11$UuG+2AJL>OyLB<+^2$%&dB%8i@btU4 z&ZF};yVbdEv$O0Or_PGuG-CF&Vn<7zjpW2bO+qI#9(rT+R`IRLuQq9Khi4p9Z|?pP zZlj0ejO~K0E@0Y0^gwE!c7in&D5jMT{EWN{`bz1+#+x0cFLYzl!8QM#Tl|Uk>y4T8 znV-lvb+ADyEpfR+>bFbR-_+|af7O;=ISL0w0+7Mf!#`)5PaWp>GQ*EPnwNR@kDD+H z>ok10^Y3$)kM;8T%_skvPwY20f8yQ*o9e=~dSK5D^EO>jEbIV}#LVJO~ z_#fip#V5h5-F9~f@l*tYpcY~wp{2;to6jx6bm;DE_%TZ0=}d@cdqurnNJ4MC_VEaT zXiB2PTfeGu602FGTO~`4g$_V<`@u*3+LKwp_8xc_G^3-|r=hfq<4gcET5oL#D4HkS zlY3UZFxPYRelz;5?t{zlZ@>R5G87w#Agr5=TZY@V{`UOL?cH2qf`T-mw8r+O;8Wm6 z4AFYH2fK6ozWkK=($iR7kI|790)=>aRCAZ+viIQH1Xkaub^M<YwxX zefB$_(jU(Hh`W!XROjQ__k4L*eFY(S5HFZ->xRIEg>i0)+j{1D`Wm#eRV#f~s2p|8 z^idHanNThUbuvxTU$|93Qh*+*dfNA2IhLJ-bkgFT7t_g?-+W1!1d=#Gk)F3DaNxv_8e$qjhjeH%21-}LXFx#u+3JlsKFw;uoCU%x|gHw8M?YImE0iE4en zMYnFe{>gqD9eALp(L)2*n`uOs1l!cz`a>Uvw*gEpbI)kN5Pa&J?Dn;Uh;Y)AEM7u3 zi4d*_`4$~{5WdxVCV84}k8|2NOE5{98Mh1DCSkbNiR9M7R>tBVSghkUb%_M)ukHBB zDR$;Rm3h(WOy%l_qh;R1oZCCKtDgDOn|RS|?nK zyT{L8s8Y#%%}cbZsfDz@8X(etzhuzJa{4Jlb; zDq^&rrM>q-UD%~!n6#%V@7YxQiqBm2AXgW=9%p#`eEJ5DY@MOriTOV~4aJ=qX~o8YbNc7wnwd1WrEyHvo(DaNxiACvH*4i8Cn{?3lU56? zceJ`0yZ*9mNqR)m&;qm6t>2%w^2Q<23!-rzy3Dhe*aX!+n&M#9CF?Um9sI~cqD}W} zUi+6DqShU`t>H`zn+pdtvEi!^c}rsJ4~>_P{=c>{muQ~nAHObYoLbU6m&KKg7cTIW z#bXb>{;rqR^VXJ;x)9xos2A|j;*`j@w|rO1RxZ47rRE5s@cWX zdst`-JBE-~Wek<+VQsK+hcshLM18$M*z>-M1}eVI(a?xGecH;90R<@|gJRuE65V2_ z`M&n;@yUFDW|ai98!Z>K=%^ot_Eg`ccCZ4YYZ{jh9FoXfZlX7CjdI$gFk)}pc3XII z*VA^}m=#st_}&oBKuZ?*B)wA(PK>87^u$YwLVB3fpoNhP^V!_0( z-lQXp90eo*p~#?)8#5g0Zdl~n-97d_2RmCQLiW7I6_))LKeF*)c$pyM((uAN9J%N? zhtRn>+W?eHcvy{akQPl{yU(o3(IP(>p_EK?m3Gt&5B7T>{zR*IKBd?(+sY@6co3ZI z#~DFF^2#UDUX&yS#TIm5ryy!vuY|n3tT%3Bf{2E`)nyX57~z2wrX0%TqGpt{!&{uV zXz6m5hJbkpDr^cEdkVd|VAhtDa+#khAz4ynkoxe4m1E(x5{Tc&C73h#>?bK9Xj z)r1N+#ugW9J+;QeNVu0hGlh>lkyzwHqHa6(a=DEQU*^YrZNnHzRL<|ND5P`BJgOrd zfw8)qVYEkqwLn4$AjxVe68STXQwf5;6^~HAqtd^8rp;p1PD{yEnmo}#F`&J!tJH)XjrK3K4^co0 z2Ax2Uh_2eD>mk?B!e>7Xep>vr=^y={N zk@w^q@JUaD;!kDM;i_WJ!{GoTQYiNpPSS_~1sE8T(J2Be$buB*mp@PI9KeyP0XnVS zeqN{zS_sjQ0s<`<_f&DZVC_og#9e2hw_wotc{*n$rR4hKJHAuRx=^nXNbibXbxC37;7pBBBnSMoP4N%}8&7;kivf2Fg|sSKa555r{}> zz4Rtc`lbY0rb#p^;!#Jwy=aoM0SST}O)L}a7=~bRwG!U4W|tA>wfC7_+@1D}+E6pG zQzx88bxyN2j?fgXL(uT_NcmT?8wE`-*y1hhwuD$V5(l(frUi4Ov+IFJ96-y&wOV9{7cc4`eauLGrnUo#8Bw$w3i-Ig6`8_< zMNLr90~}vj6GlQ{Eiskajw!)soCp@>RgSQ=vV=pKG-_d$?WrTA7`aXg2^euwgLrq0 zQ>#2CC%2y^23r;xtP zB-cocV!$4Ku-Hw=a4`_d1{f7M#1%J6(bVK;ELpuOxykMO?D;i3}}?*|f+GCg619 z;)hkg{t5uHLa;-;w1)GmmoKf+v3BXvP4LURZ~w?EpZ$#opHuUOFx!n2PX{|njV34s zWzXHo{W1@l4&x%zWrUg4`K|TRSHEPXN9NSfW<9+`uxC1)J;Iv=r2sO5vDR>0br>qK z(*$e?_ndkDX=ipUqzh4c#y@fg;h3%Vkg}PD$BpTenxml(zk)*4qDW(b%2!%V%o=R| z%Y^HL+@3vE09aInRHjt~%gsE2Gy|e)B}J_>;1Nnd*sK@Q$=ik{*3tH|o{7|h$(Ra` zqJ+vtD@xaUaqn&I)d6iBViTRb3pBA%;XIcKi2;D%c|ixyql{gatSVK~@k73{b|*^o z@fQ+(_y%NdI|5XFo|~-A|0)@M3di&Y6lZPIC*Y)t)*+Z^ugijBg+up$DLm9(*t%HW# z&5H4GRfeh!7~J88Bbml){ScOg zIV`}CVym}aGyE@Hmb4RMZ4Q@oDg-R#dr@Dl)bPtRidoTJbc!X;pM*jch4}*oO+@Da zl!uHypA~8aEmUKskf-JzWjPH`_Q&cl$AN~s@C<7Xo^WN z0<_3n?qiJvArV9&W*g}Aw2MWo*r^a4%LM|DDA9WTHN!B?+7;+9mx`Varw-aoOF{Vk zvnJMBD`ePS6NIEuB#2@jbimlW&&8S&>GDk*FJ&CoPQMHyQlsmbt4WTIEc&ZQr->v; zCngiSoO6jG_h#{?67gZP#mEYFfZ*~@ms;Xl2n1P!9a}luLb?N9V+i_$mTUaS+`*CcA2{>C;M7ewBhglR@tW2QMU00O3|gp!CN2O+-2(GTNdA zof8qOBGAYni_wDa?Ey3v9LI(%4MOU=q-GwqFDv8Dd(yn(}K>)3>V`^LbVU$~&)4$(w!?W70qbRWay~SI zy*J%QRV4O`32sffo88>9H-}-%YyxV)r&Es}?sU*PU+M-Kf~rZ2Il9bRPK==GDXghA z>%!Rhnz_6#zT@Fb&%44jsauQTPL3AdA~o!^Y2W;cha(KLVd&{~_W~dXbFkL=-qiF_ zuPby{o*dokaI9OYGn>D77?AzYwT@k1_=%&3Cy}uqp14oFA#Y!;bz)b~u_Z@XN>~k> zEeh2c2vhDfQt-JX)G6SZPU5DjYvIs+tL zH;WJkt`%2$?Q{v4Rs{R0&pp617}CNCMij(@Mz?iDb6m^Bvsi0L1VfwzlU1MxsC=$y zv(u@2{5ak!Anf+m?5ZRtGwA^q#!xU7rl5S}A< z@!tIw-dZxO0@D{apQ2}nyq;2QS|6xu$1^C4c;&tyDuP=NG|}GZj>PC zfxt3;ocbtF)FfHS8?PxS$bevE(xfr!a{H)#P>?(^V7UkaQ5I J1(Klwv?0ommJI*^ literal 0 HcmV?d00001 diff --git a/main/BridgingHeader.h b/main/BridgingHeader.h index a3ade9f..87318ce 100644 --- a/main/BridgingHeader.h +++ b/main/BridgingHeader.h @@ -7,6 +7,6 @@ #include "SDL3/SDL.h" #include "SDL3_ttf/SDL_ttf.h" #include "pthread.h" -#include "bsp/esp-bsp.h" +#include "bsp/display.h" #include "esp_vfs.h" #include "esp_littlefs.h" diff --git a/main/Main.swift b/main/Main.swift index 42abb66..be2e893 100644 --- a/main/Main.swift +++ b/main/Main.swift @@ -173,9 +173,9 @@ func sdl_thread_entry_point(arg: UnsafeMutableRawPointer?) -> UnsafeMutableRawPo running = false break } else if event.type == SDL_EVENT_FINGER_UP.rawValue { - // Get touch coordinates (normalized between 0 and 1) - let touchX = event.tfinger.x - let touchY = event.tfinger.y + // Get touch coordinates (normalized between 0 and 1) and convert to screen coordinates + let touchX = event.tfinger.x * screenWidth + let touchY = event.tfinger.y * screenHeight // Check if touch intersects any sprite for i in 0..