From 7f54a357a433bf8a85853f7db2ed8365697753f0 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 2 Jul 2020 02:16:07 +0300 Subject: [PATCH] Change driver attach api and remove DFU from CDC --- cores/esp32/esp32-hal-tinyusb.c | 105 +++++++---------------------- cores/esp32/esp32-hal-tinyusb.h | 4 +- libraries/USB/src/USB.cpp | 33 +++++++++ libraries/USB/src/USB.h | 1 + libraries/USB/src/USBCDC.cpp | 56 ++------------- tools/sdk/esp32s2/lib/libtinyusb.a | Bin 749772 -> 749316 bytes 6 files changed, 66 insertions(+), 133 deletions(-) diff --git a/cores/esp32/esp32-hal-tinyusb.c b/cores/esp32/esp32-hal-tinyusb.c index b7aa3ece8..e47fed962 100644 --- a/cores/esp32/esp32-hal-tinyusb.c +++ b/cores/esp32/esp32-hal-tinyusb.c @@ -168,6 +168,8 @@ static tinyusb_desc_webusb_url_t tinyusb_url_descriptor = { /* * Configuration Descriptor * */ + +static tinyusb_descriptor_cb_t tinyusb_loaded_interfaces_callbacks[USB_INTERFACE_MAX]; static uint32_t tinyusb_loaded_interfaces_mask = 0; static uint8_t tinyusb_loaded_interfaces_num = 0; static uint16_t tinyusb_config_descriptor_len = 0; @@ -308,47 +310,6 @@ __attribute__ ((weak)) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_ * Private API * */ -__attribute__ ((weak)) uint16_t tusb_cdc_load_descriptor(uint8_t * dst, uint8_t * itf) { return 0; } -__attribute__ ((weak)) uint16_t tusb_dfu_load_descriptor(uint8_t * dst, uint8_t * itf) { return 0; } -__attribute__ ((weak)) uint16_t tusb_hid_load_descriptor(uint8_t * dst, uint8_t * itf) { return 0; } -__attribute__ ((weak)) uint16_t tusb_msc_load_descriptor(uint8_t * dst, uint8_t * itf) { return 0; } -__attribute__ ((weak)) uint16_t tusb_midi_load_descriptor(uint8_t * dst, uint8_t * itf) { return 0; } -__attribute__ ((weak)) uint16_t tusb_vendor_load_descriptor(uint8_t * dst, uint8_t * itf) { return 0; } - -__attribute__ ((weak)) uint16_t tusb_custom_get_descriptor_len() { return 0; } -__attribute__ ((weak)) uint16_t tusb_custom_load_descriptor(uint8_t * dst, uint8_t * itf) { return 0; } - -static uint16_t tinyusb_load_descriptor(tinyusb_interface_t interface, uint8_t * dst, uint8_t * itf) -{ - switch (interface) { - case USB_INTERFACE_CDC: - return tusb_cdc_load_descriptor(dst, itf); - break; - case USB_INTERFACE_DFU: - return tusb_dfu_load_descriptor(dst, itf); - break; - case USB_INTERFACE_HID: - return tusb_hid_load_descriptor(dst, itf); - break; - case USB_INTERFACE_VENDOR: - return tusb_vendor_load_descriptor(dst, itf); - break; - case USB_INTERFACE_MSC: - return tusb_msc_load_descriptor(dst, itf); - break; - case USB_INTERFACE_MIDI: - return tusb_midi_load_descriptor(dst, itf); - break; - case USB_INTERFACE_CUSTOM: - return tusb_custom_load_descriptor(dst, itf); - break; - default: - - break; - } - return 0; -} - static bool tinyusb_reserve_in_endpoint(uint8_t endpoint){ if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){ return false; @@ -379,6 +340,14 @@ static bool tinyusb_has_available_fifos(void){ return active_endpoints < max_endpoints; } +static uint16_t tinyusb_load_descriptor(tinyusb_interface_t interface, uint8_t * dst, uint8_t * itf) +{ + if(tinyusb_loaded_interfaces_callbacks[interface]){ + return tinyusb_loaded_interfaces_callbacks[interface](dst, itf); + } + return 0; +} + static bool tinyusb_load_enabled_interfaces(){ tinyusb_config_descriptor_len += TUD_CONFIG_DESC_LEN; tinyusb_config_descriptor = (uint8_t *)malloc(tinyusb_config_descriptor_len); @@ -411,7 +380,7 @@ static bool tinyusb_load_enabled_interfaces(){ TUD_CONFIG_DESCRIPTOR(1, tinyusb_loaded_interfaces_num, str_index, tinyusb_config_descriptor_len, USB_DEVICE_ATTRIBUTES, USB_DEVICE_POWER) }; memcpy(tinyusb_config_descriptor, descriptor, TUD_CONFIG_DESC_LEN); - if ((tinyusb_loaded_interfaces_mask & ~(BIT(USB_INTERFACE_CDC) | BIT(USB_INTERFACE_DFU))) == 0) { + if ((tinyusb_loaded_interfaces_mask == (BIT(USB_INTERFACE_CDC) | BIT(USB_INTERFACE_DFU))) || (tinyusb_loaded_interfaces_mask == BIT(USB_INTERFACE_CDC))) { tinyusb_persist_set_enable(true); log_d("USB Persist enabled"); } @@ -493,6 +462,19 @@ static void usb_device_task(void *param) { * PUBLIC API * */ +esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb) +{ + if((interface >= USB_INTERFACE_MAX) || (tinyusb_loaded_interfaces_mask & (1U << interface))){ + log_e("Interface %u not enabled", interface); + return ESP_FAIL; + } + tinyusb_loaded_interfaces_mask |= (1U << interface); + tinyusb_config_descriptor_len += descriptor_len; + tinyusb_loaded_interfaces_callbacks[interface] = cb; + log_d("Interface %u enabled", interface); + return ESP_OK; +} + esp_err_t tinyusb_init(tinyusb_device_config_t *config) { static bool initialized = false; if(initialized){ @@ -518,45 +500,6 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) { return err; } -esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface) -{ - uint16_t descriptor_len = 0; - switch (interface) { - case USB_INTERFACE_CDC: - descriptor_len = CFG_TUD_CDC * TUD_CDC_DESC_LEN; - break; - case USB_INTERFACE_DFU: - descriptor_len = CFG_TUD_DFU_RT * TUD_DFU_RT_DESC_LEN; - break; - case USB_INTERFACE_HID: - descriptor_len = CFG_TUD_HID * TUD_HID_INOUT_DESC_LEN; - break; - case USB_INTERFACE_MSC: - descriptor_len = CFG_TUD_MSC * TUD_MSC_DESC_LEN; - break; - case USB_INTERFACE_MIDI: - descriptor_len = CFG_TUD_MIDI * TUD_MIDI_DESC_LEN; - break; - case USB_INTERFACE_VENDOR: - descriptor_len = CFG_TUD_VENDOR * TUD_VENDOR_DESC_LEN; - break; - case USB_INTERFACE_CUSTOM: - descriptor_len = tusb_custom_get_descriptor_len(); - break; - default: - - break; - } - if (descriptor_len) { - tinyusb_config_descriptor_len += descriptor_len; - tinyusb_loaded_interfaces_mask |= (1U << interface); - log_d("Driver %u enabled", interface); - return ESP_OK; - } - log_e("Driver %u not enabled", interface); - return ESP_FAIL; -} - uint8_t tinyusb_add_string_descriptor(const char * str){ if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){ return 0; diff --git a/cores/esp32/esp32-hal-tinyusb.h b/cores/esp32/esp32-hal-tinyusb.h index f75dabd34..1067a9405 100644 --- a/cores/esp32/esp32-hal-tinyusb.h +++ b/cores/esp32/esp32-hal-tinyusb.h @@ -73,7 +73,9 @@ typedef enum { USB_INTERFACE_MAX } tinyusb_interface_t; -esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface); +typedef uint16_t (*tinyusb_descriptor_cb_t)(uint8_t * dst, uint8_t * itf); + +esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb); uint8_t tinyusb_add_string_descriptor(const char * str); uint8_t tinyusb_get_free_duplex_endpoint(void); uint8_t tinyusb_get_free_in_endpoint(void); diff --git a/libraries/USB/src/USB.cpp b/libraries/USB/src/USB.cpp index 736ab60af..87726ba51 100644 --- a/libraries/USB/src/USB.cpp +++ b/libraries/USB/src/USB.cpp @@ -15,11 +15,38 @@ #include "esp32-hal-tinyusb.h" #include "USB.h" #if CONFIG_USB_ENABLED +#include "usb_persist.h" extern "C" { #include "tinyusb.h" } +#if CFG_TUD_DFU_RT +static uint16_t load_dfu_descriptor(uint8_t * dst, uint8_t * itf) +{ +#define DFU_ATTR_CAN_DOWNLOAD 1 +#define DFU_ATTR_CAN_UPLOAD 2 +#define DFU_ATTR_MANIFESTATION_TOLERANT 4 +#define DFU_ATTR_WILL_DETACH 8 +#define DFU_ATTRS (DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_CAN_UPLOAD | DFU_ATTR_MANIFESTATION_TOLERANT) + + uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB DFU_RT"); + uint8_t descriptor[TUD_DFU_RT_DESC_LEN] = { + // Interface number, string index, attributes, detach timeout, transfer size */ + TUD_DFU_RT_DESCRIPTOR(*itf, str_index, DFU_ATTRS, 700, 64) + }; + *itf+=1; + memcpy(dst, descriptor, TUD_DFU_RT_DESC_LEN); + return TUD_DFU_RT_DESC_LEN; +} +// Invoked on DFU_DETACH request to reboot to the bootloader +void tud_dfu_rt_reboot_to_dfu(void) +{ + tinyusb_persist_set_mode(REBOOT_BOOTLOADER_DFU); + esp_restart(); +} +#endif /* CFG_TUD_DFU_RT */ + ESP_EVENT_DEFINE_BASE(ARDUINO_USB_EVENTS); static esp_event_loop_handle_t arduino_usb_event_loop_handle = NULL; @@ -141,6 +168,12 @@ ESPUSB::operator bool() const return _started && tinyusb_device_mounted; } +bool ESPUSB::enableDFU(){ +#if CFG_TUD_DFU_RT + return tinyusb_enable_interface(USB_INTERFACE_DFU, TUD_DFU_RT_DESC_LEN, load_dfu_descriptor) == ESP_OK; +#endif /* CFG_TUD_DFU_RT */ + return false; +} bool ESPUSB::VID(uint16_t v){ if(!_started){ diff --git a/libraries/USB/src/USB.h b/libraries/USB/src/USB.h index 5dfac3e6e..ede527915 100644 --- a/libraries/USB/src/USB.h +++ b/libraries/USB/src/USB.h @@ -88,6 +88,7 @@ class ESPUSB { bool webUSBURL(const char * name); const char * webUSBURL(void); + bool enableDFU(); bool begin(); operator bool() const; diff --git a/libraries/USB/src/USBCDC.cpp b/libraries/USB/src/USBCDC.cpp index ee97d738d..7bf46a214 100644 --- a/libraries/USB/src/USBCDC.cpp +++ b/libraries/USB/src/USBCDC.cpp @@ -24,29 +24,13 @@ esp_err_t arduino_usb_event_handler_register_with(esp_event_base_t event_base, i extern "C" { #include "tinyusb.h" - -#if CFG_TUD_DFU_RT -uint16_t tusb_dfu_load_descriptor(uint8_t * dst, uint8_t * itf) -{ -#define DFU_ATTR_CAN_DOWNLOAD 1 -#define DFU_ATTR_CAN_UPLOAD 2 -#define DFU_ATTR_MANIFESTATION_TOLERANT 4 -#define DFU_ATTR_WILL_DETACH 8 -#define DFU_ATTRS (DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_CAN_UPLOAD | DFU_ATTR_MANIFESTATION_TOLERANT) - - uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB DFU_RT"); - uint8_t descriptor[TUD_DFU_RT_DESC_LEN] = { - // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_RT_DESCRIPTOR(*itf, str_index, DFU_ATTRS, 700, 64) - }; - *itf+=1; - memcpy(dst, descriptor, TUD_DFU_RT_DESC_LEN); - return TUD_DFU_RT_DESC_LEN; } -#endif /* CFG_TUD_DFU_RT */ #if CFG_TUD_CDC -uint16_t tusb_cdc_load_descriptor(uint8_t * dst, uint8_t * itf) +#define MAX_USB_CDC_DEVICES 2 +USBCDC * devices[MAX_USB_CDC_DEVICES] = {NULL, NULL}; + +static uint16_t load_cdc_descriptor(uint8_t * dst, uint8_t * itf) { uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC"); // Interface number, string index, attributes, detach timeout, transfer size */ @@ -58,22 +42,6 @@ uint16_t tusb_cdc_load_descriptor(uint8_t * dst, uint8_t * itf) memcpy(dst, descriptor, TUD_CDC_DESC_LEN); return TUD_CDC_DESC_LEN; } -#endif /* CFG_TUD_CDC */ -} - -#if CFG_TUD_CDC -#define MAX_USB_CDC_DEVICES 2 -USBCDC * devices[MAX_USB_CDC_DEVICES] = {NULL, NULL}; - -#if CFG_TUD_DFU_RT -// Invoked on DFU_DETACH request to reboot to the bootloader -void tud_dfu_rt_reboot_to_dfu(void) -{ - if(devices[0] != NULL){ - devices[0]->_onDFU(); - } -} -#endif /* CFG_TUD_DFU_RT */ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { @@ -103,8 +71,7 @@ static void usb_unplugged_cb(void* arg, esp_event_base_t event_base, int32_t eve } USBCDC::USBCDC(uint8_t itfn) : itf(itfn), bit_rate(0), stop_bits(0), parity(0), data_bits(0), dtr(false), rts(false), connected(false), reboot_enable(true), rx_queue(NULL) { - tinyusb_enable_interface(USB_INTERFACE_CDC); - tinyusb_enable_interface(USB_INTERFACE_DFU); + tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor); if(itf < MAX_USB_CDC_DEVICES){ devices[itf] = this; arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this); @@ -127,12 +94,10 @@ void USBCDC::begin(size_t rx_queue_len) if(!rx_queue){ return; } - tinyusb_persist_set_mode(REBOOT_PERSIST); } void USBCDC::end() { - tinyusb_persist_set_mode(REBOOT_NO_PERSIST); } void USBCDC::_onUnplugged(void){ @@ -145,13 +110,6 @@ void USBCDC::_onUnplugged(void){ } } -void USBCDC::_onDFU(void){ - if(reboot_enable){ - tinyusb_persist_set_mode(REBOOT_BOOTLOADER_DFU); - esp_restart(); - } -} - enum { CDC_LINE_IDLE, CDC_LINE_1, CDC_LINE_2, CDC_LINE_3 }; void USBCDC::_onLineState(bool _dtr, bool _rts){ static uint8_t lineState = CDC_LINE_IDLE; @@ -202,10 +160,6 @@ void USBCDC::_onLineState(bool _dtr, bool _rts){ l.line_state.rts = rts; arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_LINE_STATE_EVENT, &l, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY); } else { - //[I][USBSerial.cpp:76] _onLineState(): dtr: 0, rts: 1 - //[I][USBSerial.cpp:76] _onLineState(): dtr: 1, rts: 1 - //[I][USBSerial.cpp:76] _onLineState(): dtr: 1, rts: 0 - //[I][USBSerial.cpp:76] _onLineState(): dtr: 0, rts: 0 log_d("CDC RESET: itf: %u, dtr: %u, rts: %u, state: %u", itf, dtr, rts, lineState); } diff --git a/tools/sdk/esp32s2/lib/libtinyusb.a b/tools/sdk/esp32s2/lib/libtinyusb.a index 4704da611f78db513bd2c2f687037e1450b1b1b9..1d9ca88e3308096d4de25a5bc2ce3d2f547ac0fc 100644 GIT binary patch delta 32381 zcmb`w2YeLO{{KB^b|=|vLP$0t$&l<45&{eaNTGxtdhZ}zQNc!01QiP`U;z;k8Ff)n zKtQpeC@Siusd#~VQ4t#`C@5YVDqa;E>ht-Wb5_ppdHtXA`ajRSUbFlDe9!mvGBdj; zoBhXI-1Je4<*{H*W$T(dOGd_*uD9$9&z^y_A1!%~oNopGFV0}bN$dZwGtPvZO}qb> zXG+yx>;LPSI^YTGe|c`(ZKZD89p}sc;~Bc|S?mAqOxx7d`rkXfrdIg*f&XvLEk*XX zA=zzyW_o_Grfs{niM7i_6T9aX{_ynQR%E35=Vc5^vE;Gkv5bIY-!jO5D!YmI&+gXn zSNd+gIeVC8Eg7||*cwyz^OP0~VOp8Jz_RXJe5Yl>dT&#|Zlo}tI^_Z*C?kfDFPlE| z)cnoQ6kD-cYvI~vix22{8FgMM2yNaxds7`Gb1Y`+ z7NoswS!-S@UTay(g^Dm7r%YOueJRuYWrqEbic4pyD8aKs8Nq>c=WH%xCz#NrG+J@ueATU`LF1yEq_HC zi_Cvp8H~H|g1>sFS=N@(x$W)Lk=FCG?SGE+6L}5en{Uc)Xj#n`!>4Hot+Kp?se6pG zGE@=>6c^_nD-ml^m6GCz0>P?)Q&G`qes%Vm>f(x$;$p8@dY>)htnRzBG9p%Pt<`;P zZC{4=oAuAumeqJcmhZ|vwqNXeta$nI z+{Ug0dvD9iNL%wL0?%f>99chByk;X4f7FK4mIw2@2Sp$McwsB?ZDMAFV1DAv;M4-Y zwx~kf>d!2?KmJE&%L>Y25)`+VBF%MmENf2#%PLTVN50y@)DAJr3Y0+wQ-gfV?36j* zwk&60E`;+|j%5jFYYWS=owvjAbdI-ytMlIw0-ckomX+eH_AD#aDJ`+Akn>)1%Sv5$rmXk#c>fwv}ZSI&;v}Mb3dr%ZfTZ5E^p= zC}_Naa||^tcDBQ*p>ttF%PMi!G`6f#$3r0+IX~xFR+;l3)U2^HDATf4ej2^IptVZXQvWA zU7S7Dmetky7)7sj79fRg&JJYR-4ST^9?oFYxTkX%MeODLf{c4RlVI=TOhZBYI(H(q zeop)*G;DuoJeqWX^AP%Gpz}1EWsvhVYB1OtfL$r+xEbdhLI;g^juu_em&5#m7ltA+W9|Ox4p*DyVkZe2K(O4;8q2&YZ-DenVr}jtX1LV}8 zbLouPR$vD>WhKfN7~*n>+9Bs-C_9vT7&7I2#Sp=`Z3A*+`H)jSL;i2KRSns?n5qV&tmX9M~Y->Q_v*NcZ%1bLe44WvjWZI z{GvDuUF7_#cn=!h`91m~)5&ByXB3y`ga4B0WZs4`;8;S5d8njg$AyfZ*$2Jhj2DsD z5I^%J3~gtb_B+f1-l4^Fm?h3~QS=Eakhu|K!?{z7l%^2APVE6^be9%EtQpSTT6}_* za_-UM`leR8bEGV&fMD;4y&}O$e&T-#uwLvX|*;z&V1HrF`ZrUkQUw0%Fa3= ztDX5EGu@y|y`8Q8h!zJZHfm9qHGNczahQqDV_GB%As%PtFrhN{Frz1QRsY-EFDUJh zIf$*i(Jrh_fkUZ3skC9{I*cS|lU;N@b`EZCmxloJJ7GwdjKmaX!(aGy~#OEgG?kC$u=qoIledfQje)M~S+b z)vRM?Ae$pUv!#DUBezWjW~|dRpt5Vm2Jy7mg&FEJ(;|jd$7!xb*x%8}yYzL;d#5r` zv=7WhWoNe4A`NZpwA12oiW)8Q{h?)U{Noas zI%?BJOs10-H?TuGYhj}>P8Tg&bF%c-g`UMU`)F~5)#(>d!+#80ufG6}OE{|T*J4!_!~J&AP7DLH}TzKcvNGCbv#kqBkS0*WwJ8e&=EBHi~f`(V~UFt+87) zlD+kqHqB`Z@wgJ%zc%#0Z`{PjTm2@*ahv1e#$c=|mgCGqTpv=}II2|J(8Vcj9o3qZ zm5vZSj+E{?WDCY`N-u`s;*{Cm z-`>P6tjCqQzjk;DlOko1j=I7BzKPraBV3A7hO2Np==8^+t`p41tjI0FOT8K_SXRoD zsC8<39eF)yhIKkMBb%Wq3($_C^2{)Kk3X_$3-PAEuxVNR1m;O-Ln{3(_W`_w9&^rv zQ_xB|gWeB49=MZHdXt|jYzf8<(MI$`N+~KA&U0UfslJc)C(tG>9_Ry#lz^OaECOSg6>3&#BfI`Lhg1n zUbvGK8SWlj?!%p>$Z{*t`r$58m zmFW5K9HF{3b}>eHc&Jk|h7 zhVM|SBG$bg)N+}$)jD=DW?guN$Qg}zHL;LiTwd5`JFfQOgh-zOThAEVJbb^%VLSJY zeZ+iLiAYnZfw6_mXSK-kQH4XXJ!sAF8dcd7v9J7v7Djd6tvzZU%yP1neMO+f64mLP+s?%fReSDoGvvdJf48jPekJ;|Aly}i8ep-FUCGkb ziU1tL_2ri^{U@jXTLu@(E0t$UG>^$y0? zvk@*9nd8|E8L?_Cec?+~U~a4{dLVqMN~I`P#b&)sm7-Cs6U#JJc{Yu?SeC-ml&Xkj z;>IyNU8$Pb9e!TLHRoQB^urrONsCOZvu|S64L_{Kc+QbWv?#+!3Woy)oIPoqTHvAV z;!F&CE9Er|wT$su*+?d(7g|5#+|om+NijKPvj25O@M*3Nm`4M!6<#wxrsLD)%2)aL`?pf6`B;>~9 zSb(!y%b*N*WHX31GAPSkh7pt1R*GDA3ZiDUlcK=Am2qlhoFXgbC-g*C`vA*a|6+7N zaaO0S*H{Dx^CGLWjH8RtMHk`66ohn@Apw-Zzq6`wTqfE>Iuy7*bLg4Op-nMVufPx_ z+VFn#C_3B9F34H|bW35(c6BD-Q`DCt=-z{|on0tJ$bA_TCA&z94EH=v)Tk6$?m*Nz zJC@&%viG zZD8vuZJmPA1Y`Hge4kkcqr0(eX7^TEhNAu1e0`(}hN4ekXk_=5Din%tU~T)!-p&X` zZ}U61DU4r)X_-AxdK84BchF;yR7Iia(~Lb>s^U=eMXDiEH3~)F!?@2LDpk`^bR`~J zvWH1k9*PQ#s_fxXRfM9uGoeOE)jAZd!&F8}RTGNV>&?JXQg#YOC$RA6hHRx5&;7xkGU6h&-zXxm(SopOYfXy^!L0DRSL86kDYzaGzwa zydXu9`xC{BQWU%OFp45CQN(eF(*x5Z@(&r*)a`_2AhJ!0a(4^Gb}1^{cPMs9(b_#j zu~Ui~_cYeZ$Sx^5x!rIzio7gEtvi_F6)AeUb17bxqOY69Zr+`l%aJzF<>DN9O$H5h zr}|Sny77DRVA?B96Wltu{fz9BVv^g1;$Kosb}yp%w-lGStJ!}0rI_ZHVNOL}m*NVy zKgAnT%yvgpyeY*T*TMLY9FXD$cQVCW6me_5JCo|547$mkNAb24i`^xdT#8eu~?>$VXB<>mKwscXHd*RKj#zns&KkDL#>6x7&pS_fskMy8CfG zkDQQVzk9L&XD2uQTs2IeOVc6uCC=6_q&VUha0-1X#WA-T#aB|CaHCkSBVSALh1-=g z<)joR-G5MgBgHBAD~fNW_z~?6@tqXExNSM^PEo|IGtpV>$nRwku0~H${Z}enjXt3I zL8_35M!CBDC{>1tPG)ERBvqD(&ZIgmRj!E6qxxB@0uild5B?%mk%-<#^{Z6H9Yyp8 z+-XIAld_SB?qJ~WQZ*IP*0_>I&PY`*q6L_pkw2uW5YaM!XqUqHm+V_hNMk4A{l+y* zC|N7K7PyW?Y$baNuPhfbpk!a+U4}(G5>#@a@E+t8c9a|{yuKVlDN2qM-c^*TN{$iU zYFu|BArY4uPY~Yw)M+YslJHJahLxNwyfiM`=}KNAyy>No8A?tQUKd=}BXyL#LU>~+ zGnJezyeX7*m7F8IQl^}xI}i&g&O+K%yc zZ1JYb>xl3=*FOQ?BLifiRXnCPj!ItffrmRvjXnR*uRx25@y#kKb)=FmB-e%UJjgncm zcapNLlDW2bKQnHpWP$Bn!xpYlvdE5me^9qqy4d!z+2S3PY-D?FDLX3J)b=bkaVI6q zZErSZXC*6aZzW|HC0pCxO-#9~k~OyX4*R24$xgPn!h`G zO7^wAM$I96Dml>hrc?G(a;WXyPT5<@k+$~;WgjKS*xuT5$i7NWu)Y6K_EU0FCF;aw zw7=4mZLfrKfRdNk-Y_n!1C^X+d*8P7PjxS95aRkeL|Nz9-q;Grp-SFhd(ZmKdql+n zzh952eJ0btq(@Oa#AS1|@>pqm-MDa$QF4{-jbp=&RdS8(J;SjvPRaGQ_cP^qB{$mM zHnz+JC7(cfdAXjb59+iUE<*)ux+f;<>6SH@p# z?=CLKsUvPQ{m0k4RqT&v`+fLBBLkdnL6mmL4=l-wKe ze&qmPujKxK_cSli83m^0dGI$qe>nNc-uHg zA5-!~z{}^g`f(+{2zX0)HGV?LlL4<)HsmHHPX)X?DW6pG$AFi|OXgEel>P<7m3p%% z>5Q9&GXX2-Ikx80BG4T=^Fse{-xBXQ7PXw>y8PBM=>6%xSdnd~mp`*#uKh!~zo=jH z_%5vBmeT=A3Vh?o;7{`SS<$B$>OrRqMu_8FgPNx}zhge8I>%A5kh2=yo#uRpMK0`Q zqEPA1M2DXTCi9MqLQF^}9c^SeyAVY-UkkkZy~yKH+;Zpl}L=di{GZ;5^pQIsZ zHJ?I{zDWbzn%TC$xqk>>WWLzHyw6r#-0WJB!33<>6X<-qn^GdS04BSKQg-ZIw3gjp zI4o2kww3t|6+xCF7~A5P4`>!Sjn=c*i@LHfPQYqD-M?f&dEWx`lKqHC?TQ3i^uR^H zepD65Y8JBBinOm`Z#fq)R_yg+gg%kXKNExA-Xt>kjlCTU`$q<}i{FCjYB`^ySA^4w zt$}aIP#))A^k~p|6zh)T96`6IIHxgsQl0*2y^xcOsh4IIWQg`@%dj50OAsbHWRfj+ zaS24nOy&}FU%_=pbdn;)eFCFMbe1CI-h(tmi!Nb)bQ#8Hz^rA;ujn_?HP8bIwHn#2 zk0rY09zl63Mk8U--QPK|DCH>pMKAyOz>@gASj$A;oMZ4t^Wdns6DWpcF)d}OyecY`qg^e zUpS~~%Fk#J@u|OgP+s1rb|ZfLk5-gN&23ETbN|SoqWCv>91vN7+7{(#)*nHV!WtoBPNJSY;nPqvp$Dk^}r-d0&Ih&!!!UR4Ts;~5i3>14vTf*V5dE8*8y97FpIZ)fvL zI|8O5I6GqYTCEXQ!$~8y+S!aT2gWNI%2YELnvNM!DqgblSodA9?!Z|+5ihTz8nQlb z0!sbqL-I#4Dl6WBZSx__{g9@v=0rBqxva?Z$;gKQjC`f?asq5Pw1w(>tM#vt$E*Fr zL!#p@WoIl?70i)a0t>CPwQl(xEvslGgU1XwFw#PINA-#8Sc8PPK zRN3t~5&nSTSDZCJad@|}^Wsdl7$Gs7HFr0JwVf^3n|3f%)9A8-9h7k_45Mglh9ymO zw9}dBwK%V#aRW=zNqH`VVJVHTAOlfrXK<-m2g6#N?R&zL)jXDq^{UgQSRU*gEZSGu+CJ; z);KMivNgo;s<#>Wv>3;H#0b@{zluEB-Lm3;sfD%=679y^W^%=`?2Jnp<7!y0ptUzf ztVmZiUkk%(8pCK)k)dk-0u0a6C~IC<)%*|)@8N8ZvRGYZsa3^uRmFcm*w+ES%ZLJ} zIhG^OA3vfnUJL4iQ`Ngz)q4~SBXDBn3$PR36>_D#1qQKdbi3qA`K~BcD_@tdnoF;0 z%4vvr2~%8>4dY>v&j@$Ga664rw$KM6Zz7EAgZPN%AzI}CKO(X@>UYAh6=$c(mtJX! zqso|ydw{=SY+n~;;9B`PTEFJ1DaVRcnX?)><0_E4<3F~@IPGHZb^$(=76{l*j^{T;+!El5|*h4mCey2bs~qw2+3`BdJ#;ly=dP8(Emwn*U>TOP8~3(x^wC}O2! z@UD+j4VBrVoW>q7bj4XEZxv>XE}Xz(WS1DE7Yez?l%tPhIOXVIf7^VK zgJX_xC!j`bkGPeGn}=MSYII}(Qu!hsuNAHw9nBH$(FePe^N~f9vki2sY@knZu~!Y$ zL^V)%cz5AB3T+MlT6$a#!-Y82&?x87h+EcfSYDx3j*S*-Y#fH+eH!K1Xr)@@Gz=$k zs%ENC#vZunwa2NNsg0=1X1WE2g*bb#%=aK`HCRTene!Gx_A$zn<;Y)LCUSYzNkg?+ z^_tNL5>u5i215~z%Xv#SO~|{OY8WbUR&Ph@MHoP52VL6VgRYfucOYXq==#FBH_o#& zFjIF%+!7Uf3Z4sx33S5b<6}nUmGBW!HTmkpELLT8OisRNa`IV~=Ql@Cp6S-^Z?`;A zU(HdgazazMWhpmII;3_k+=i*U#4J&q^y^)UuvF!TOAY+C|D9Z_&^L!&Iz**cOUAky zg}xGJYc#xdf&cE92Jr?=WFyIAZc!7wg2n%H$<8ic4Q1FMl1<5dH)D@H&L^E)4fx`(TncqVEEDBf3V1$vaqm zBii~T0(o3PiMvcOLAJm-a2hTh`<-b9>u~uHz=%aMV*k;&M%n)o`EfRJfR}{< zGp?FWlU$$%@EQcsp21fCb{G-%YeM!%fR~1WS4O2p_Nvu?94U};;&MHv5X;K)I)lcb5uo)?CUcZ)BAhSby$Mp8;{c^HJB&D_>(cMkF zJR_yBP6&2~b`;%7d^sbfI&mN#NJ|{~E;ZfHn>1APNo0SSmg^OuoV>{uxDCKt3eLK? zgRg9KrBzbhXqHt{nz5S3uKxN-rKz2z=P3WS=|x+HpMP1JxHXYAHR!I$2*u~InXM6g zdzNWhKZp^lNp)qM5q!H2rwSk~QUQG9N~r=6K_A2MJ{G62Nc#8}-rvG0tT9QGdQbc{ zCne-}oLW$Sx=eN?->$$Jux58#t+Gq(`Z1NCzVXfimmefDmTy-{9LKV5Q}_zrb}MAe zoBije&hN>M`l`s|5TuWRFiyt#Kgu%>hKr?fMAA=rUFTmr?aDZ3Ju5qW_1RF&PU}~k zj&;3N(crVm06Q;6%ysDi0(kA4nLRE_{~{IA*hPqK}p(8gBWQOl~PCX#+Fu>_ec?M`LnJX zBtF>k@>QLMxMRy-SAQGqoP|xIfq=j*x^N04^LAZ0)so|q8yh|?4W9;En%%HOOiT@= z;5H5yE?y;&6keSitSnN>)W9~3sVOQWhGFMFUQ=LoQUbgoKyVr4ONJv;hS)3(+?lDfWx>3#Z3nEx%-=#e{*n2S zR40w)%<+Gp-$Qf6AF!Z}2>1&Y6pE()Tk~^$Z$Z7k{oY=?4zv+FkF>wVfe&Nk+ zvz&aLI2$dHR%grfo67?Bayv0og!2=dW~JuX_fWw7(BfkI0fQg0{co>{`6E|k`=f8I z8@vZSo>-Fz=K1q)O{??eJeDtLJM{y1h{PLr1Y?2hz<2)ETc`Sc{o)HmS~^PncT2WG z>#!wpWsn`%G9ZTu6zks(&5L&(HV|PL8&09}QRPNA{XIaOVtA(e%a;_Px|^1C^AD^j zj;jpoCo9`nXV?mfFyq$9f+MGc&ZNCgyrat6!Lyz$${^TT^0xn@NLRtiBGnJfm0oDd z6poy;MRHtOrg^uuZB&sgLwB7QyoL1coeb&ZAG)nq-5zW~1j!K{Xy%tMeOToCKQC>t z<-bcaLW-fcUtje@=kp>qs=EIebM+hhRUA)u&t?=J^y?)}3<*AMQ%irQT z>9SfK#tR`2#vxygcgErJ$Afk<^RRKo!3?5(zP8h!R}3DslW|Fx{s5uMo*K4N#O3iqa zAL20`9{X^T8TU=iEX;AuvNotbd~hR!gBP7-Au9doi3V}rS9GI0o}f4~Mw5{w>p@N* zj29dnF|_lZj-1Xq;FyM!_F~QHtP>8V#WXp>9wEc0k>>P4034gpfqy$~hJj9Ob#gM} zgWAp>ASW|s!pwlf_6O}#fp>CxUA*An$Dm0c`jJ`TuA1@X10Ei?bpC9B9Y>Iri`v!V zot4bRttH!!I>}=+vyQxXq5s`@=dD-LXR&7X$^C|%Qzq%d8y+(InRoi&xXg^V4@`70 z-W#X@X|L4G&h4g|Jv7Ylxm+^~&w0TNiouU-X6y6Ofp#`B3&_0ae>d`%Vh+Sg9l#QA z)6B<;KQ(ib2XsR06>_@1-{L2_Oq7cPD?#Suf0c}k*+b;?FaXD!+TJ>!NRSeSFctb`nDV7BH8oV2r{Hj|6hJ=0FjTnu;{M;|sI?`X+v zg#Tz}I9 zZtyI_Cw>n_waV;4GHZ+DA#jf7O@{qxZO3e~cG2ESx?8&q-e>r~uKhWW4$`jk`bha> zEaLb?3CW+6b;f^?@leNuyEu~e7G#}J8*;YtX%EiP+|%$GO4bD(Y4F%;d0c1M=NWvX;d6&!_YGc2)`eRIW~~n;NBrNG3<{^P7H1&O5?hW`(R>uIkFEL(LOSwePZwz zWF7Y;m~nY)`V;NC%|yGi^>YlaOV)AYxrQhJGochDC8OANk;tb6D_gI60qj~n)<41U(|*=5*w8@#U_uI$c6AG+umT~8ijFv&xWy~_TK3T_YU~nmz>9CPo8~!y0cQ^dweGDw4IDpiGuA#o%)*g>r)(F~l zX-6A;zTtn7!IyyyEhF;QPor?heEMwT@Uy1s_##>_b3~=64LIkI6dGPYwRU z@cF^8|7`FXvQCpb0GR$Pk6e`4?# zXMGZ_T8NZ5A6szz0DF$+Kk1{{#$zk(0r;eXlVymIb^3V*M-88*Wc^h@IXFjiwc!(= zWQZ#bo^S99gVz|m-ry$;-fZv-25&QXw_*+gd@E=K95DDDgO3<|%-}B!K56ie2LEDk z5cvsLW{Z#X62G++-(K`SZMn+!p~0UT{JFuu7<|UyR17)c!GME1#F7tGg_09pW`^6w zdmHxt2A^l}g$7?{@C<{mGWc49mm0j>;DlnXruZ-^akv7vD*vEOm-l7E_cepLXDs;u zb;RIL4gTCHM} zzs_32v?1}zN&ea3KMm$j<|KX64X$f&o?nD1( zMl*AxTr%ERgSiJT`G|9c!Pgjky}{fbm-P1y#tyl^?Hdi|9y$1{0spEI@GpbkF!)1* zKQ{P327hHR_uC~4lx}du;5>%|zLD%|{LJ53ZftN1gDVa0XYe3{M;biFVD8;Z<~1|P ztpA*(0N-FR_wXen_y%*|UednNVD7?8J}>Pw_@4&<%iv?+crwBXBj9U;zcZMd_mci0 zgXU>sMJrjSl#Uqj2KUS)GWvmfA$>7Nb&ouZdgKsc+zQNpD zn5@TIgSmML_JrR~WS6~Q1Z*?-RfG2=j<-X3j~gcLHB6>`+Fmv#*;RwIFr0cAPW=q~ zAcHS6e6BF;vkhKi_$)WO4kla%~^yA9L3 z1|K%~FS4hy;Re)XvFaP#JQ4jgB|pxcq@q~4_BMEs!NUyZCex(?gFIj*GUouN4;u)>J_+C6MewO?H>7!y z!Iv96$KVB;d%~Z862iFT<(fx>?=g6l!Rs|ogU=?#arvG4^E%*41Z>lM75Ei{|821R zl^JAApQGBo2>hAB-)O!a_8&Dr0RBVsCU7`{A1{4zggaASj8X+8v>8iTuN z=Enm)4VFLWf;4GA$FNV({4MggrfBgic&foOHFJB?wVJt2cY$W^=UAed`%iq$+$F;ymP}VyJAJNw)4U6j|6}lX2LEF4pPJu>e=3%BR_riX{)m-kSKGgU zy@VV`07X+B@HM!l!EFuhs`-2P^fh>}<{x1nX)u3Mj)kCoiss+IQw@&K(!$1ky+(5# z@a<%MVYw-@h{FP>w>6F30 z8f@pOLenQ*b0s*};Hc(W*c<0@{f9S2D;+QbTw`!I%@@Mn-{9ezXTd(+;0q1DLi1Jd znX7pY_|_zI{l8la&Vp5%?*?zsyb}DR!CN(RcI+~EpXLp)A2j$w%}>C7!r*Vf*{uE3 z2so_+o=&_qUNnj42L7KmX{TzeO(|j8COANk3 zaa?ZeyH*GM3McMVV}ZzvHUAF2Q!}^D-K&`w#toXeO;G+$7~*m}A%C))>2Uw!KF$0t z=skl!&DX=C908|v0QnEioxo`YDj{+`%>%(jnz<*jOfxr6HaEDnX8yTGXU!LbdnK8> zDhFvX4LnLScV3>WnIG|AteHENuP~Uu<-uAmfqkLD^2b1&kFqbDr%!| zjO!a*s+nt16N5XG_04l{g9mD+|0she8hpNF^gr^quAyiEz%k$8TQoDFI}A=3%wLgZ zT&D9hxfp=sC4+ZqW;*{gct0--jKF|{1|Kr`xWV5T{F7#`vVR&Jtgq6fJxen_hOi0^ zF4Y`oK)Df6WpHQBT&;T>%-QG1J$|hr`19$E{0ahY)4Ut(8+@;3UL#g( z{ug+o=C{C4Yd!*g(cqUgABTOP;<(%*{gw_miGahJ{|i2@`6uv~ntuU*ulaZIubTP5 z^p|E{7gDjX$w3OPtGNIyf3UF_vjN<&i0eNDw_tnPiCn3p)$O{Y}Iyt zZMYO!&GW$@YvwL@`CD1=Uj*il*fK7epJhZETJlIW zI7>4ZqCCx9ZyKKExaFM{R+Ygu2KUs=g=mPuqYa*9@I?mC)Xc@|I)nMYu_6uG{|H#B z1ITx4t_Ob5;72r9z`ohw7d2PI{))l>)?5SoI|d)s+!6LqBZ`M2u_S<4y|52i=A@0%v*Mc9=ycqnj!B1&k1N-v^@6@~w_B{r_ zsrgCR4{3fLd|dO(T>n4+TUgdNnz_22*8Cp$FU=>w4zBeqG&x=K=ipq;UxA~V&wv{m z+>VS->Uh+W`O_Xedg}mAm4OBiH+a0k7aDx2=4`~BsW}&Xon~B@tQ$2myW0(p-))F{ zHCMsuDRLwYvyz6Ce7WDzx8}lfM3x(4E(0S9~yi@Gw1g=n#Y1q8*HP5?7mB3uWN9j!HvLi zI?aGn3mq^M+}7Z(nt4~#%isZ;uZMkv=6T@pn&*QjYrYvgT{EZjRcASF&DG*I1l*#T zpCzr(yb>&b*cb&RKW^Bc)4T@u9hx5o?=kpogO6(72%pa-qx~O;_(2Ce3I0p-W^f4e zg)Q_PI9u}zVAtRVn*RZNndTkfmYQD!x6}MCxU<2%Isci#Ap{K9d=h+~!BY*Mt@%gz z%+>re_!fg#XbuUqoWYM9{H*3UKLXmWMHcv<2EVD9d)VGL_(RPtVE>-XDS+cQgZYn5DCI+`KxJEPAhVBOUH+Y!A;|-o{u>7rS6fOh#TUYALfn#*C|sks&SH8TH@gW`1^z@_&+&27LR zYpwx*X7IO~2f+Tb!G9U-AZ=D=FnrQAb6v^RJO&((YH=Y%nZYeJUjlnO%~Qdh4eq6x z>&IZtTt7x@o(-O8@D$BA!G5XYxJAKMh?D_vEH-$V<^b#ogXPa%!=GL7H0^A294{HX zOEcr{Gx&AQnKH)KuV#p6GVS1j#DjCiU_0wT;#R7c2ix3*o>1U}Eq>*muF6rR+;--+M6eAngZW&rtRw zv>!W|_?Gq~GJRRK@*80fzKuUy7mdY<#DYiC@)I|}mgMyY?^k^EM*K_WqPG(%Hz6s@ z#^bljqUTLWYT(<6b6^*H6LW8Z+Y4_e9;O?9>%!Wk+)mJ~(L0ILbo((8y%}!LzLV&E zGu-Y9;_9W`%6p}vZQo7Y1G@+&w$p9zyNUl$7A5N3BAPg}u^9D9ynHiyXy7eKwBr55 zxwjydZK;^?%D#&BqQi+NY2P1Wv&w3pgxz@u`dj6fy9j#dhjbaSBayc#|7o;OJC>M7 z`wdv*@@daaY`+y_=ESkY8?@gAyB-@EOW>b-JP}(0`+C?#;!ZidVRtq{Z&c~tl+>Zb zg3aOF#HJ;pE`C>J`x3MW-A<`uondk{#}k>iA-R>=Os@THsOgWN;p3vj`NVsNU=k

6PIY@7J+Qc+^3?M$3oCzzKgza2$twKLJ>c0{{)C+;v* z4R4_R)cJ{JwEqSBvBb**QK>ge8Fx!oKf|2neX4qJS&`Wzh+U$m#)F zY*Z9*0R&Mr;Esagjtc^ciX6lRT#n+39(m;b-&HkO=e?fq`M&FW-@dM%`Tg&@YhSv1 zrZQQ4qU7LbC95Oui87yWO~KIE?NgXB>F?8%^gI*i$llEJ|8RO!ceDRnXN(duA6xm~ zp1wA#+5hR8Frb$Gx91BhS;7k|WAyU>dipmkVE@yZ_~=>o|L?TVvcS`s|6k7fT;qE` zbz38EWo7Gf_hi3>W=8T%XK2#D-Qg3B3};yKfckC8+%$R)adrfoRxatuhQ8E$*QDSO z#;zT)FUpn{)=l>g-BdStRC@A~3D=~byQbA5IIIsYWNh`)x;2c!Y3((J^Jg$8*08B> zCIW8@&R}f$4apG%eckkl$Le-H5oM7YHgj|H8{Uftro5Ep-?giDX9^NJ>1W@~mhWd5 z1*1#r-dj&e+W{?TfOxh0$HLl{-Ds z3}dCbz%g1YkHuJUMU zUNqV~D!kWzL=h_Hc0G`u9AcR@tn22QZWPpK?yKz?D;geHD4OhGhb84Kd34@^-n$kB zn>gniM*1{iEV?~PIjzn-c^6;3J&G)gLO$4+Fcja|bboZM$D8LdqtSx8yx?l&x;?sS zTNH&aLptTb4wd_&>|sy+=&Y_@KGNMh+LPt%&dD}HhVxF&IKEC=y5}yon^iOBMWT4+ z_vIt;r&Aa^-k7m$VU#b1H(`+TV{TUL@=O@auQC|p=D`xi4D;gvV;(cD9pamR_z`G+ zm%y0M+-)TY<~P4>!C0ahGZ+h)^+Cpx%&8vaWac$xEX8~T{;B4cG{(}*`;r+; zH_g_J177WsLPOe@DhW z&8uPWWiCWPdz)L3Tp#nUQpWn4)6t~;%%{*b{mrM*Dg(@KQGtQxgtm+gGM(m(4K^=9 z+YB+AHezh3$r>;=%xrWKjm30`yZv|8qQ0qom}0(u5ns2nr=<}Xl&KjC{w-!;g>o1JkRygXl! z>nQZIw;*#18Ga?hLg&54<@_7R8_jQYHF7kcNo|I9NX)gsFH(Q8#G-aimuTbE&oOGu z{W)tXn6-7LMZ3o$RJ_w<_=ZOPt2rMMUzZO)EaTqg1AmZvH}Xmxfu1#wNqz&f!91QT z(w~PmGJlY~2URrBN}sK0FY|ZFh3GW%56Qm>ZO-HO8!YuM%@H zbj|yexECYO+^EDpN@kN1i>SlyS7Idk!hC>>mPoCqay+DJa)A0~s}diQ*hZofg)gA$ zKdgeT$9y%nEAdDU#12*C!Cs+3sc)D&8=J~T0Ussb*h_`Q_)k&52OBS-pF zYN@_TJWMs{uiPw}l>?M`lP1KSO596HyGr~<18lt#nKZWVA`wFyd_~FKt%5evV7W($ z$Hm}P;tUn;J|%LnV4541_?)_DlM;PsOl?-;J!;r5(f$DT1ka&d#Ey2Hrj>ipH{NJlx`qG{XX& zT8ayXudOME%^`HLubnB2&=cd{SE)kIW0~}IP$5sCBYd4y$WSz$uUdsH$6Dg+qCy6t zi+o*G$mBfDzJz#-^*x;grpR4(ddlTJRvzqp}srOcK+hj0P%4ry;%wW z!l`an82bZr$Nx|Q`7`TYy!f}9AC6jkYo{!hbDnvbrNf#LRjTH!Xone6j}Jv0Mj6B~C|(-wI)| zb?oNFt%e|Ne_*zMH$}d)DO~0RiJ7$1tO+usL&f?~!{99*F^Pr=eGDdcy_X9U_*|m`c82N#lc+&frtlr2es`^bl zlaxQ=Mum!yN{&2Bxx~1i>X06J8sjOjkSG40&Y~8L* zY^`t-O3L~BPREj>)WbAdKNhJBwrZT~ORUt_s3pHh-Gfmy)|%zqS@O)~Us932K81YI-u(V0Z%p!_r#YJ;5E1AArSZMMms01bykZ4 zj8JA?g)z^~{$Rr#g;$R`5wBizI$lllIfVMmY-dR8%vfu*ATu9D@wxdNUJbJ+EFNN2u@&)Qqc|3^wRWhm>AYCNH4v0R)|)0Ya~|h^s-bRgx5;O&`2*A zA%5!)EPv^3L`bqVxj95z5t43AegMg(w-YMUnuMt7?S;s;?xRQ*B2q5%1<+dQm7cdT z*%~cCQ%2LP(qEw>G{VqL?~ zbvf!BjAZquhRU?gp@)NwMNqc2j?#__k!!6Y(L{)-bqhvGFi(gA>%&Bdd?A`yr<@Mu zMLFMKiUperQ-xJV;mw4ovU)i4%PoGZv#z`-mP^HLDFTLDt10JJLX5IzQu?JrjJ4jv z5*m~}Il)?k&JUKQQr#zpAH$Ff%AUkU=XRRhZL*#~ke7!SQF?7tpMt94;n`H6jv_(k z4R^tk6s#%~(hG@6AC&#%_lD=SgOVMU>7JKfDuDBRE8; zVt=?HMpSU9P^JFxN2yT5glgjt=TR!dg{ts}oA;!^5kgk^!!xMxBeTv?#r)x>m}$XF zgsSt0+hdvsN2Sso-adc$H>^a#(OJppE|wVH;(XLLr`J1_?YPt`*iI&e^RUJQ$BW9c z)bJa)Ckajv%9|QKMxK|a^oOTEHT)9w-W92rQCjJF{pvfmE8?+cSiFLhJcm%C#0%6$ zSBKWaA=?|uF`Hvj7oNaa4mAmhY0ew7!dAH2h6={@g)7nip-Yt^jTPRDksP{A z=~PxYjuNOz!v1ZcXG(4Q zIV&9Dd|uIlmpf^dR_iJZl+Z288O^~5%(z?&{9vaa9End*6Tg-;2ZQ(lS-O3h5u*^AMX~lvVs-ee=hQNbaA7MO% zo@jaw!fRcQ86K(^qsebg#8oJ?Th1!0HzmDCh;-{l5>E<|X{{phln~k0%hcIV3z2ID zsAHZHB5F0qunj#+BE|}=Q55u?2x?{x!I~3#UWj7rbrO4pD7C&O@q!R-tRU9n(2GJ; zSV_2)hV}_jWsM}UUx*s(N)j&#(cM~0;$qZXonh>L`9avvOuM08O%A>jPh7c31VI=xrgU zTjL>Op?8F;wWd(eyF%P(HNq?my(h#1Yc7dHLeyDHNW3q^V#^_MScs+8M$GWg5g}Gu z-;g*e#A@pTi4TOh!+InN@u3jwtt-Y*J025igSCyimn1$BVw;st zL;AQ7k65cod@95)>vI$0gb=%})6SGCD>eYjO6W6T+GkB8aY~2-Ru3A?p9}H2^%?Fb zLSG1R&{|Lq@ud*&SqErBeI>*Z>rDzdEyOYFU0N&72yxshp?USS5GSq9B)%b0%)YP+ za3u+SD}v5gQ)x|C z$S4o5!OdIf-$E7e@L_WOQ>bP<+=f=d^FkH#a0#Yt=)Z(2<>3xaa&=DZFX~&yg|Uj; zX}ElaxRf>A?n=^-vOBjs;ASi2k+L_pW4M%ryi)e(c0J8&Q_8{IzKq6@Ps-ukUQRMW z%2C|jO-qWO$3(_sx&0mKL>WAR+Z;Esp@5VVxg8;yB;_^SUPM=nWGSa`dl)UpDN;`7 z_EeIoQr2>N9?3K*Z{&6bWt1-E0)Cx+1W(7IpwxBT{)}Wu%EjC^X?@F(aw)gZlFXEH zCAUY=qS`>p)!e>?tJ6r1Tp0Z6wR3^c!{wjm$PuCL8uEREM@wrW-b{|18u_ z%1p!FMH#o3GTX3MQsY)gnQO%C5H)9|)KSAOBH2O80>kb{vZIvE47&j}XO)!2hP{kr zCn-w}dnd_iDcczKU6fO2DJu;7Yq~PkNLgjrTW!cLF{x_|`vmE(Qg%1&19U^vP0HSe zUD*P%yOjM6dlAVVQVurk`$_hca=2kXPqLSkqYV4WV#wZ7jy3E*N%oO)LTl8Cmdw6V zPc-cIB>PEujbUHa60*OPQw-bF%6X(~ZsRa5rh}yQM#G*~3OQKH1%~~GbGmCd_9YpI zN#j!Vs26g$lq(H8NY~sEQm!`a4@}6BQr=wCGKi@}yy}AbG8nUl{g!lK7B-;+`?=-E>

Wr4@8aW3l-PH#@5;U;M;_1IO;@*d%9>!=WQ(pcrOzb3g*${LTIL4C1E%I+RJ zO7a#ddwc9IbU9rtWq*%-7s*?t9PF{5CAmb(;i#<>?Ae$1bjJ1!^O!TQXK}2I?v&O@ zhdPfvgydQ&7klhCsQ!+WOFi~jx)|Oezry+O)HJoY|XGw+phm&bma z_U-#IlLC6QC zJm|4sr7QkJQoiT0e;~O<$|D~8Jjtz69`o3|$E!cgWx~9(yBQ-XD?jJCEI+%CS?*vmSd3$w#I9#bdXiYw%-I{*EC|au?6*ga?oF z9+vSYHRj{o(-k`PMp{Dl@T?cGSY)R=_xEmK|AtjGBbr8ElX|Tqn5`L2()(f_`mG|Y zm>GE@B$@f{c24$=@`VoXW7)SOO=bpgS>Wb*Ecb>v8pGYgya`^|m{G%5AXU>};&kiN zqT5kiFPJ$9sd0RhNZ#i#g+1o)me+{N@()dZOt?+<=+y zJl>~KMl?$497QNMt1#OP({)btX_T-6sd2N;xd6Tw^PQPPoM_*M`9b7p^yDe@l{hzi zti@~SZKGG*;AJi5IhXd$!Izh_`xd7iM9GaBo=n~>vftU&Hzz!cQs~RgE3s^NA_pn@ zVD8-v<&8Y+oax&(*@me3E(|IQ$eAa$6HLn)J zZ|y)Dyri?g8`2HnGiI@gAQfH0YdqbMP^;lxdNJNL^Ek>=dI=Kd-JJRTbA3O-9}CL8 z{qth4VXfhPGETx9&48nH3y=>^r?jM{^}+xw!#q9;#ubP04Sms#Wz%qL0&`>0hC|C! z5%OjyytF<>#Tp>}(JJu2_oDv*Pel5+!Bk=&IMoB1l_g_9@vjU_dF-#@V zuO@Q=eT9Q&6-UJ;O8XmU{eav?2Ktp}crvpPUWL#OINR*R%PHrb0aj%QWhw6uDPRKN zG`u=YAqNBvMHX%OXkOZukKwJ`^0B-%>#&ppo#?>aHgzad`HzraqqoZc4WKfycArzv zJTA*RQk3;`ICP|@8{$kKm=o&;V+9Ri{*)1dT`r946yhs_paA_&p5Yk?{a|?v=&_q-Ro^VGKh4f{`4f_)%CQILoKP z|9e!n!ves+0XLvPsI}=yh5?n9J!+c;eYg)^p89d4H`)(~dCq0X5xD66zHxFek?IX*Q-9Ym|$ zAzN(%4C8Qi=!4J@3N*%fdQh(6t9CvZ)Hs%edCD)7X-2f1P4I4w` znypHD9L?grz{TCR{;;alK`3#&{lz}MW zR3j!jwjmM>;Vj4CW|Pq=tm6oB#Mvp4GQG*jree{zKlBlIyB;*N%4DfG!pt{NtZI>H znPJmlsX=;GIIHi-6TaQ8OLBC^Ca0qiCAm-djL9Zl$zc>z<~R>x9>uWh5Z|WbteQA^CgYz9 zE4vBjQ&qrpx>(dG&rAp*wN1%6{~MbKFIjZ>7so1Ro-o&dagDP?fy& zg3e+5IJcI-zb3W;LFeG~D>-)A4u!i8mPjvjpg>tQ&%>IGr~!(ODM;UorFiKJy4D}i zjM*gHs}*(bh9@iH?X`)A_4eAtOGxG;k;XV>d&M4<4b~f$?qn4W_K<9_DKK0`M$uqf zWz%eiVI5A{UfZP6#4Xf+!B`nW0q?*$8KtNYGyhqhLF-iycyz=0zcofow8mC$twDqu zYK+lv8byx(O=E0Rjd4A~r;-orx(efv*K!|SEW{xi;V3$!T3pp@c`ns@3A`8KltZVM z7n5;E0{VX|tYzYsrIuIIXyn7I3uz+O@rb_zO^(igy9C9vhwX@+opd_xDcjJ#)T5}#tM^_&(6YNWeee$lNFZzN|TYdxbG+%lybru--*xAdZ4CXdGb z#^l22#cXHlGw;C~cn&tWt=cZu8Y^U(jsS?MBLA3&m=lV+<#QL-;Mm1JbdTbs}zJcxp zdk%nsuS=#&_)Oq53h#5A77oguvDbwwjUaLNOLgwK1^2l8GEw6@;3U)R8>CJiCY~rL zVy=kTZwjtF#+y7VMosFW#lHWv*;C0RmYM!^Wr3)qVAiicMu71O7wzw%1%JS8VPO%y z$oe_R&UleGq6b*dn-{}hQ zS#$B|4qA%SWH+$VmUJ(wj=p&R9;eA>|7XA;82ckZlg-fsIHLecKM@Z)0an*YOO84Y zqleXxn=mJluX7&1%37Q3@4OHul$+jmy`tl8bFijX`U} z2Al>f-AM1>;^gd7yov*nSR=epY;vLZ4mi2q`?Mm=cOIIu5uaAeX!OWT2l5^{HG+1Y zJ+*V9s2c(tXYbTr|C4J+{#*TwY2AF-8Mmi)0RN=kGrJS#tLwYW`QF>90k({KJREob z+zbn*CjoAj3yukHq4`L=^eL#HGJiR5ZhCyUFT*v8E(k~puVxU7ijcw+Y`|zb(VH4X zJU$Oyz#%<;+<^aQyh8WTr#$m2(}#4j5atmcUg2;3N1A3sr0N&Zsk|ZvWfJ!i;rIgt z3Na{qSs>G+a_2seJ7cN0LH((lzU3WETP1ELP}Y> zxWP?ECjY8_#=@N(X*Is(Lt{I4FPrbpa?%#J%SFZ+qCn|z&x#imb@wEu){j_R=rQgv z+;?UqH0O6apWRl;H;dODc+GHHE)6>UmZo{vq2lhQ72d`v-`q?^@ET?#&+XjZ_lX(t z1U+Y+9ZRnpT<~`*(;YWMCaJGEMSj~qocXn1I49RVu_jalH#TNdVi zXZ^BV)N0SNF0p*A@H{aGJ{K*mRMHiQOj&f2Nt)eMqFq&1-C?Kxm<~I=kAyuL@12!> zHgpvy`d}95$d#?AS)ZRG$s>xSfKYr5G>9up~58ij) zPPy@_Ni)Y^dHvMsQzq3;a`$ic<^~X>cJkCo*Uzr4KlM5{jNZ(B^f6CEchxgKzq=xm znC@h}wbHd;^d>ty-pY30jU*P-pML9rQ8E`RP9DxhIImKC2JeFvS77nM!g zF~y;{SPmB+Y~;RndqROT<~=$mOzx(_=wmaAMscvUh~2F0v})2pc4ErIz_|iUL1bU4 z?34#xH|QWcG42tB|2k3O`p$D-x>Ew#JT3v29!f~{av5F>*WKT$)}pe=&GKHn_LPQ zr!XOflk%hmyFR?m8&ZnRurUwBz;> zilgwKq?lTNw&p|kQRGhz{s50jL9P6*3ZT}cXA^Rwu}>{PnbqK(YC*gK@6Riy0-sb& zk1cr=7e3VTO;tKHZ-|rBU0GY@6CMDdT2KU99ZnM?<0?cTPQr6K9X~63jpC%iWW}dP z$dLTI3wDamw2bu!X4c3_KUOi-VYXuGtzE=Xc~dDGA506xn`Ez%agQjbUi?}y#pP6# z8UPOZT%6LOk03?8Ygn~dZEjHk)Y?lmzFlL)6OoJXp09X`6aG4juXNgeozJtKOTW%Z z{7Z%S>u>t{Y+0-v5=R2YByS}-N#k^4<&&$~qZ*43f|L*a;bc6Wwigcy&qbd1&P3yE>k zA-)yC!!{kOV9QXvUh{d7m9}I}1T24ZEL3cyS+P&2EEoD$WIy#|R|ZgzShxM>~zHiD?PO(Uttu+-Z&ZJ@HY# zlY&+MJg)JR#45R$H2bR>zoq$nsM$Z!_@w6Zoo0`n)x@vFs*HbtGr+XmB)9#$aOoO1 zAXfesnEZRezq#hqQscIof2H(~;n@^_X0JI7)OZ-Ns{MG)ex=6OYCbcG@%alKbHL(* zF7QIlXSK!~+j=PjcX<=uD&7-sQ+O+p1Usbh2U@&Snw|dIHSYhd=5tQ7)1L^(eONon zQl_6wtn!MbYoY%#?=~k)i~CR zgeqe{FqJoi!Vf3A%6NhnVWP&bf}S+YW^!VzEk?k%kn)^P@}O&G^bq} zKSitx^fGZ1;m%$IXDEJO^EpARTJ)60r!}9SE6_u6r*oRqdEw;VUBm~*x>Ww{(?jFF z#Hv6eHT!6d$7?>ZUg1&3!(6rG#a_tQqgxwTf6ZdyU3D zgpZ6nM6-|3cr~l^0ON;Q6#=n6nGBv&jkD~F&2^!NQYP_Ji#Es#MBMQz?+(Pr|C|UM;Hxl$= z3yxkCLGe&6!W9}{OB|N|)5u@(T+L^h#%qZ4r2jhdSG=hs@{gDLF)hM##Hxv2)c63g zihM@%|A81Ih>oAZ8H)eXd=jhvPBSIWRR0hO)yLs@0PIaPE+WpQGL!kmw+=AkJEfsXne26J2c*_@mrGRBzRW~_)z0dH2z%U z(;EMv@y{CnsqqDk6RQ8NeNuJl-y%Z`$kMp6#`)Dx%`4$P9y^Mrh(F$bq%nN~7q|bU zaRSCr+@7RyRO14TX@_0>DU&|MiE}^6Zd$%!P93BLOwf3u#@7?uC> z?cj?SXs*T!HNI72+T0iSzguJ4niqfks@M2gjbHH4B}YA@y`lxYp)qaei~GdhU?KJMDaWBboL=Dse@PmFA6Qx~+@eF2ZJWu1BHD0dq?HaGs_%4kfH)%u_ zi1uT9w1DR|-ls9`P>lP3r143OztEUAD#rc))R;CW3OhdYVd-%Jrp<=&=cT3^x74`I zJ=7LG*IzRY)A$mNX+vT>x#=3yAK=IB^EF#8o#db zL5)9h?`_Ak+%vU2x$ul;r@fK!!X;{)?xxJf<8XmyYN2r}jcM~_Jc&LU(_YEAeVoR$ zKQeBgr7`V-tZtl6XLWEnu+5 zmuNi3N}aqhwJrEy$%eJvZsq zJUK?2c;ogQjq^2bsxfWrjr&(?+*9Me8q>boxc_*KY5Oe?Fu7x5jufJBH)*_3W7>Ng zf0$pd@g|KQd}?zwzuFt?lL22#B*)%upcMeN_-8~bh~>h`ULkHQ{VxzlCFg{}YS9>m z@OXp2MVv2vQt%$X6S@a?T)a?xpvKtSPp#_4oz&Qsc(4p*VXHa(X@78>XDjXw`^_5P zrnoQct2Mq;@gUeYXneoMJ2c)cIVQHO>{S6n5&30}4=Nr3JN@1w74B;AF^x}X{FUMb z@cBXUBJl4T|E2g=*u5c4B1)7*O6YIS&^TA|Quq`qrVp}8G;XW-Uf8P??*#WyycaxF zlmxBySn_y)yiV6W47iQ;czU#amrjqlO;LB;eT$9Bbkf$8@LVpMzj)4^v{ z0P%~8X`l0JifL=}yNWIFF~zho=QG8$C+TaAe^lHY_J1pG1@>S9P`=ns5@X4K3)Vm} zZHCFwxT#{=@l&pGN5!-YsI%hX;1R@_DRhj}c%ouFaI&d_(f%Z6X#ooqFJB@!;OmqD&jT5k}Q)TwRo}zI>#k3wYCXT_0L^Ca*rQ&_C)8A}U zLd4h`evx}>++Xow_>55e5qO-&S1YEqWV*(&IZDuCvOwd-8q=>qQXzhX&z%}?Q2Yz* z_iMae<9fyahR-t^@0T272IedMp&(_D0{(90Xv()dlqVb~96 zso_H6BQ4;RV!8l+tGE#Svts(2u?vc6pJZaTEFA5pY^a#7dHIUztE*CtJ1HJaUj_7y z3-Be1CxEZi_z0@s}b;+3ZTu9 zPb*MTqBc(USqVV|LR6L_BDZQwe^yTP$#npmsxJ&K=# z(}NmsS4{Uf^%_5~_$An1QG5XWj>aD<{wM7JlpGU(9C2C&e1U);6n_n--?OIi@dH@= zt|<6da02Ew*?$M8DgG0jrT8y!W5u-XyQyNj9ciVQo^#sfqW>u&TIZ`(0R8P`FU4ix zK^kA8nAY|Qio1d*EA9)Pq48YB^bPSM#Y4d>6py0y--!$G2F3KdEe|QCzn9#p@gBw3 z!2W{bY2eos(>3BqBwWPST zBR@qkT|0sr)6Y$ZnxHRmlxW;eG1ih8t5Sj%jb0klUzk&5veUozit{*)uT@NI#%zsm z(s+r+;`f)4Ci%ON8!7Gu&R0yI+!SlvR`FoiJ8Ilb@krSFDUOYW7^cJ( zVEW%tRESC7Ns6xlU#D@c;%i}_r+6y3PUB@7uhsY-#na*cK!nzRWJY3#3YZ0cT=5+6 zvx?_}Usgo;OXgp0ZU3P0Vo~Q9G8n4iJjbi#t z<1WQ`q-FOj#&wLvb|^u4@6mX##`_i11Jj4Z`2ZXzHU3I574$oef71B8#@?t%Cnjzv zQlt=^p>aeptpUw6F4efb#$7b-tMM?!H1Ef1JSiHJwV}B_Lj@4eS4_=yt76>lvo(sT z>F!mW3*Mp_y~!R^TmXJbV`cnIw0H1;4z>JG9e zD;^1Mp!ia7MC0a)C&S(z9HYo2x@iIZ6;FeGgyI?CaT;H(_(s^LYCKEveAwqJz8QRr z;yUn3#rTjm#?~o8bNXJ5A5y#m_D2=320yEKJ@_?^4{Q9X;!W`RO7Rx(4;ud|80}91 zCWb$?1l=B`Dc%9jQT!;lsp4JWQpJ0~m5QGRchR_);^$x=p!fywNX4&!$H$a73NcCJ zX^M}*K2Py?;M+8IG~S^27x+A+_#F6Ajh|Iaf35qP;uwj;TEKC|bgT5G;&kx$8lO{~ z1^We!J!nB{#S+*pVwwUt@-%LynAVAw`RIRgB0)bH6X$A;dulvL;}IH9P)zH@wHnXV zc&^5`Tx9hB%8LR&jiHzp3i>yxR3PH5is}B~F^%^qrZwX^#p3=zF|7@6E2epWRO1uG zF=SATfYU0V75HBo|EjnQ_P-Rj1t%aL6|MrDqH#mT{a|mbaZ`;;6c2 z_z7^uPb#|y_7^pNSuu6NN5s_TI8JGNMlr?xu^>r0k@)qg22=TqsfpQ#WS?K>{&;_4 z{+$bWfl+YCEn2__8l{KaIrQH9kozjV4?pBKyb13U4!Kv+`|3mPlk|S@kn6h{?_=M0 zN8Zev^WH9Bz%$%CZszI6$@kqYH}fJs!F~H?-qdJw*!>OCq`jhE>DDF&x0=Il&lv1< zlb`F(i1B>0|6$rGcNfrD%-z4{^M>vba-DwI{R*z`>W31&Zh9TcyY#Tzt`3nOMC7PU zw6+eOn-056VCM(iops3jz+v|TaytUIWa*Z<5N^j0yG0A(cG4ZN5N_;Mcg;hI zS?+GQ#QC_!-bFm!JR^!LYFi9#WFK*>7aAHb}yclea zq&@&`6rXTExRn$*UbYCT> zBPm!iWn$jjkXZ6bx8ZF_#GmR`(|hSj_bPg?NONze_m!WyPvYI&hb1ga#`}fhc~7~% zrKsjHw`3`jZ*$5WNfO`LLz>^gdz6RXDmZaGEY-VcM-Eqs2X7!bf?UVKmWM}Q&N6G#d?EiKby8aCJJJ`+iN=`*z!Sj8;FU1$V z?cL@pc%Bj7=MG!}_ip>Jc)G!^37PJy6+F$Dzt6o7cH`+Q-B;;7W54@7y>FQ4He8AK zUtV{s@oxU|4z6eJjD89E#)2ug-M*6JG;n%wdU2XKeK-?v`f(;cb^FS|oKyb`Lw-?e