From 5296f827825dc5ca10f28326c19963896d087287 Mon Sep 17 00:00:00 2001 From: Dave Williams | DitroniX | G8PUO <20687856+DitroniX@users.noreply.github.com> Date: Sat, 20 Jun 2026 15:43:33 +0100 Subject: [PATCH] IPEM SIX ESPHome Integration --- README.md | 3 +- .../ipem-six-c5-hello_atm90e32.yaml | 217 ++++ .../Basic Examples/ipem-six-c5-rgb-test.yaml | 122 ++ YAML Examples/IPEM SIX/README.md | 135 ++ .../ipem-six-c5-single-phase-six-channel.png | Bin 0 -> 78785 bytes .../ipem-six-c5-single-phase-six-channel.yaml | 1146 +++++++++++++++++ 6 files changed, 1622 insertions(+), 1 deletion(-) create mode 100644 YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-hello_atm90e32.yaml create mode 100644 YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-rgb-test.yaml create mode 100644 YAML Examples/IPEM SIX/README.md create mode 100644 YAML Examples/IPEM SIX/ipem-six-c5-single-phase-six-channel.png create mode 100644 YAML Examples/IPEM SIX/ipem-six-c5-single-phase-six-channel.yaml diff --git a/README.md b/README.md index 364e3e0..a4d18f3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Home Assistant Development and Integration -#### Welcome to the DitroniX Home Asssitant Integration +#### Welcome to the DitroniX Home Assistant ESPHome Integration This repository is for integration of DitroniX boards into Home Assistant using the ESPHome Components. @@ -71,6 +71,7 @@ An example guide has been put together which should help get your boards up and ## Versions + - 260620 - Added IPEM SIX Integration for ESPHome - 260618 - Added WREN Integration for ESPHome - 260613 - Added TCA6408 for Dev Testing - 260529 - Refresh Information diff --git a/YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-hello_atm90e32.yaml b/YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-hello_atm90e32.yaml new file mode 100644 index 0000000..edda08f --- /dev/null +++ b/YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-hello_atm90e32.yaml @@ -0,0 +1,217 @@ + # Dave Williams, DitroniX 2019-2026 (ditronix.net) + # IPEM SIX - ESP32-C5 | ATM90E32 | WiFi 2.4/5GHz | Zigbee | Bluetooth | SIX Channel IoT Mains Power Energy Monitor + + # June 2026: Example Code, to demonstrate and test the IPEM SIX + + # Remember! + # - Set the BOARD to Use ESP32C5 Dev Module (or similar). + # - You can also set the BAUD rate up to 921600 to speed up flashing. + # - The SDK does NOT need external power to flash. It will take Power from the USB 5V. + # - The Serial Monitor is configured for BAUD 115200 + + # The purpose of this test code is to cycle through the various main functions of the board as part of bring up testing. + + # This test code is OPEN SOURCE and formatted for easier viewing. Although is is not intended for real world use, it may be freely used, or modified as needed. + # It is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + # For board configuration, see github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor/wiki/Arduino-IDE + + # Further information, details and examples can be found on our website or github.com/DitroniX + + # * ditronix.net + # * github.com/DitroniX + # * github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor + # * github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor/wiki + # * hackster.io/DitroniX/ipem-six-esp32c5-atm90e32-iot-mains-power-energy-monitor-e323bd + + # This YAML code is used to be the equivalent of the Hello World but for the IPEM SIX and both ATM90E32's. + +esphome: + name: ipem-six-c5 + friendly_name: IPEM SIX C5 + + on_boot: + priority: -100 + then: + - delay: 2s + - light.turn_on: + id: heartbeat_led + effect: "Green Heartbeat" + +esp32: + board: esp32-c5-devkitc-1 + variant: esp32c5 + framework: + type: esp-idf + +# ############################# CONFIG ############################# + +# Enable Home Assistant API +api: + encryption: + key: "xxxx=" + +ota: + - platform: esphome + password: "xxxx" + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + + # Enable fallback hotspot (captive portal) in case wifi connection fails + ap: + ssid: "IPEM SIX C5 Fallback Hotspot" + password: "xxxx" + +captive_portal: + +# ==================== LOGGING ==================== +logger: + # level: WARN # Reduces spam - only shows warnings and errors + # level: ERROR # Even quieter (uncomment if you want) + # level: DEBUG # Head scratching time. + +# ############################# CODE ############################# + +# ========================= SPI BUS (Shared) ========================= + +spi: + clk_pin: GPIO10 + mosi_pin: GPIO8 + miso_pin: GPIO9 + +# ========================= HEARTBEAT LED ========================= + +light: + + - platform: esp32_rmt_led_strip + id: heartbeat_led + pin: GPIO27 + num_leds: 1 + chipset: WS2812 + rgb_order: GRB + restore_mode: RESTORE_AND_ON + + effects: + + - addressable_lambda: + name: "Green Heartbeat" + update_interval: 50ms + + lambda: |- + static uint8_t step = 0; + + uint8_t b = 0; + + if (step == 0 || step == 2) + b = 30; + else if (step == 1 || step == 3) + b = 10; + + it[0] = Color(0, b, 0); + + step++; + + if (step > 20) + step = 0; + +# ========================= ENERGY MONITORS ========================= + +sensor: + + +# ==================== ATM90E32 BANK A CS GPIO6 ====================== + + - platform: atm90e32 + + id: bank_a + cs_pin: GPIO6 + + phase_a: + + voltage: + name: "Bank A Mains Voltage" + id: bank_a_voltage + accuracy_decimals: 1 + + current: + name: "Bank A Current" + id: bank_a_current + accuracy_decimals: 3 + + power: + name: "Bank A Power" + id: bank_a_power + accuracy_decimals: 1 + + gain_voltage: 38300 + gain_ct: 64800 + + frequency: + name: "Bank A Frequency" + + chip_temperature: + name: "Bank A Temperature" + + line_frequency: 50Hz + + gain_pga: 2X + + update_interval: 1s + +# ==================== ATM90E32 BANK B CS GPIO7 ====================== + + - platform: atm90e32 + + id: bank_b + cs_pin: GPIO7 + + phase_a: + + voltage: + name: "Bank B Mains Voltage" + id: bank_b_voltage + accuracy_decimals: 1 + + current: + name: "Bank B Current" + id: bank_b_current + accuracy_decimals: 3 + + power: + name: "Bank B Power" + id: bank_b_power + accuracy_decimals: 1 + + gain_voltage: 38300 + gain_ct: 64800 + + frequency: + name: "Bank B Frequency" + + chip_temperature: + name: "Bank B Temperature" + + line_frequency: 50Hz + + gain_pga: 2X + + update_interval: 1s + +# ========================== TOTALS ============================ + + - platform: template + + name: "IPEM SIX Total Power" + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + + return id(bank_a_power).state + + id(bank_b_power).state; + + + update_interval: 1s \ No newline at end of file diff --git a/YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-rgb-test.yaml b/YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-rgb-test.yaml new file mode 100644 index 0000000..b07cc73 --- /dev/null +++ b/YAML Examples/IPEM SIX/Basic Examples/ipem-six-c5-rgb-test.yaml @@ -0,0 +1,122 @@ + # Dave Williams, DitroniX 2019-2026 (ditronix.net) + # IPEM SIX - ESP32-C5 | ATM90E32 | WiFi 2.4/5GHz | Zigbee | Bluetooth | SIX Channel IoT Mains Power Energy Monitor + + # June 2026: Example Code, to demonstrate and test the IPEM SIX + + # Remember! + # - Set the BOARD to Use ESP32C5 Dev Module (or similar). + # - You can also set the BAUD rate up to 921600 to speed up flashing. + # - The SDK does NOT need external power to flash. It will take Power from the USB 5V. + # - The Serial Monitor is configured for BAUD 115200 + + # The purpose of this test code is to cycle through the various main functions of the board as part of bring up testing. + + # This test code is OPEN SOURCE and formatted for easier viewing. Although is is not intended for real world use, it may be freely used, or modified as needed. + # It is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + # For board configuration, see github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor/wiki/Arduino-IDE + + # Further information, details and examples can be found on our website or github.com/DitroniX + + # * ditronix.net + # * github.com/DitroniX + # * github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor + # * github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor/wiki + # * hackster.io/DitroniX/ipem-six-esp32c5-atm90e32-iot-mains-power-energy-monitor-e323bd + + # This YAML code is used to be the equivalent of the Hello World but for the IPEM SIX and RGB LED. + +esphome: + name: ipem-six-c5 + friendly_name: IPEM SIX C5 + + on_boot: + priority: -100 + then: + - delay: 2s + - light.turn_on: + id: heartbeat_led + effect: "Green Heartbeat" + +esp32: + board: esp32-c5-devkitc-1 + variant: esp32c5 + framework: + type: esp-idf + +# ############################# CONFIG ############################# + +# Enable Home Assistant API +api: + encryption: + key: "xxxx=" + +ota: + - platform: esphome + password: "xxxx" + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + + # Enable fallback hotspot (captive portal) in case wifi connection fails + ap: + ssid: "IPEM SIX C5 Fallback Hotspot" + password: "xxxx" + +captive_portal: + +# ==================== LOGGING ==================== +logger: + # level: WARN # Reduces spam - only shows warnings and errors + # level: ERROR # Even quieter (uncomment if you want) + # level: DEBUG # Head scratching time. + +# ############################# CODE ############################# + +# ========================= SPI BUS (Shared) ========================= + +spi: + clk_pin: GPIO10 + mosi_pin: GPIO8 + miso_pin: GPIO9 + +# ========================= HEARTBEAT LED ========================= + +light: + + - platform: esp32_rmt_led_strip + id: heartbeat_led + pin: GPIO27 + num_leds: 1 + chipset: WS2812 + rgb_order: GRB + restore_mode: RESTORE_AND_ON + + effects: + + - addressable_lambda: + name: "Green Heartbeat" + update_interval: 50ms + + lambda: |- + static uint8_t step = 0; + + uint8_t b = 0; + + if (step == 0 || step == 2) + b = 30; + else if (step == 1 || step == 3) + b = 10; + + it[0] = Color(0, b, 0); + + step++; + + if (step > 20) + step = 0; + + + + + diff --git a/YAML Examples/IPEM SIX/README.md b/YAML Examples/IPEM SIX/README.md new file mode 100644 index 0000000..0c3813c --- /dev/null +++ b/YAML Examples/IPEM SIX/README.md @@ -0,0 +1,135 @@ +# IPEM SIX | ESP32C5 | DUAL ATM90E32 IoT Mains Power Energy Monitor + +## **IPEM SIX - ESPHome Example Code** + +This is a working ESPHome YAML development code for IPEM SIX, for Home Assistant. + +![IPEM SIX Preview](https://github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor/blob/main/Datasheets%20and%20Information/IPEM%20SIX%20-%20Overview.png) + +## Summary + +IPEM SIX C5 provides a complete energy monitoring platform: + +✅ 6 CT channels +✅ Dual ATM90E32 metering +✅ Import/export detection +✅ Per-channel energy tracking +✅ Home Assistant native integration +✅ WiFi diagnostics +✅ Health monitoring +✅ Configurable load alerts +✅ OTA updates +✅ ESP32-C5 performance platform + +Designed as a professional-grade residential and small commercial energy monitoring solution. + +## **Code Overview** + +**IPEM SIX C5** is a professional 6-channel dual-bank energy monitoring device based on the **ESP32-C5** platform and dual **ATM90E32** energy measurement ICs. + +Demonstrate the power of the IPEM SIX by reading the all the data from the six current clamps and input voltages, and provide a large range of information. + +Provide: + +- Live sensor updates +- Configuration control +- Device status +- Diagnostics + +The device code presents: + +- 6 independent CT current channels +- Dual-bank monitoring architecture +- Real-time power monitoring +- Import/export power calculation +- Energy accumulation (kWh) +- Voltage and frequency measurement +- Power factor and reactive power monitoring +- Internal temperature monitoring +- Wi-Fi diagnostics +- Health/Status monitoring +- Configurable load activity thresholds +- LED heartbeat indication + +Designed for integration with **Home Assistant via ESPHome API**. + +## Documentation - IPEM SIX Firmware Overview + +### **Basic Examples** + +During development, I took baby steps in understanding how YAML worked and how to integrate the various elements of the IPEM SIX board. These examples have been included for your information, in the Basic Examples folder. + +### **Status** + +The code should work as it is but you will ideally need to update the ESPHome API details, which I have xxxx out. + +### Enable Home Assistant API + api: + encryption: + key: "xxxx=" + + ota: + - platform: esphome + password: "xxxx" + + wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + + # Enable fallback hotspot (captive portal) in case wifi connection fails + ap: + ssid: "Wren-C5-Test Fallback Hotspot" + password: "xxxx" + +## **Full Code Example View** + +The initial release of this code is for single phase and six channels. The code will be updated for split and three phase. + +This is an example of the ESPHome Dash view + + +## **Open Source** + + This test code is OPEN SOURCE and formatted for easier viewing. Although is is not intended for real world use, it may be freely used, or modified as needed. + + It is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +## **Further Information** + +Additional information, and other technical details on this project, maybe found in the related repository pages. + +**Repository Folders** + + - **Code** *(Code examples for Arduino IDE, Raspberry Pi and PlatformIO)* + - **Datasheets and Information** *(Component Datasheets, Schematics, Board Layouts, Photos, Technical Documentation)* + - **Certification** *(Related Repository Project or Part, Certification Information)* + +**Repository Tabs** + + - **Wiki** *(Related Repository Wiki pages and Technical User Information)* + - **Discussions** *(Related Repository User Discussion Forum)* + - **Issues** *(Related Repository Technical Issues and Fixes)* + +*** + +We value our Customers, Users of our designs and STEM Communities, all over the World . Should you have any other questions, or feedback to share to others, please feel free to: + +* Visit the related [Project](https://github.com/DitroniX?tab=repositories) *plus the related* **Discussions** and **Wiki** Pages. See tab in each separate repository. +* **Project Community Information** can be found at https://www.hackster.io/DitroniX +* [DitroniX.net Website - Contact Us](https://ditronix.net/contact/) +* **Twitter**: [https://twitter.com/DitroniX](https://twitter.com/DitroniX) +* [Supporting the STEM Projects - BuyMeACoffee](https://www.buymeacoffee.com/DitroniX) +* **LinkedIN**: [https://www.linkedin.com/in/g8puo/](https://www.linkedin.com/in/g8puo/) + +***Dave Williams, Maidstone, UK.*** + +Electronics Engineer | Software Developer | R&D Support | RF Engineering | Product Certification and Testing | STEM Ambassador + +## STEM + +**Supporting [STEM Learning](https://www.stem.org.uk/)** + +Life is one long exciting learning curve, help others by setting the seed to knowledge. + +![DitroniX Supporting STEM](https://hackster.imgix.net/uploads/attachments/1606838/stem_ambassador_-_100_volunteer_badge_edxfxlrfbc1_bjdqharfoe1_xbqi2KUcri.png?auto=compress%2Cformat&w=540&fit=max) + diff --git a/YAML Examples/IPEM SIX/ipem-six-c5-single-phase-six-channel.png b/YAML Examples/IPEM SIX/ipem-six-c5-single-phase-six-channel.png new file mode 100644 index 0000000000000000000000000000000000000000..772fc5ec0358ea44822c148d1ae8ded05a6e8946 GIT binary patch literal 78785 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

c+ph* zYI0`CFcclb)OOrC5tU{O+*iE$$kt7* zX_lBTjQZT1KT2ThPyD~*TPEb&kvXqID;%e9t!d8)Fo(kf@_7dn z9~^Qw=Q13AmH>a8_w`sUAr}yC5{$o>d6%@;j5J8a<+DDgVT1m~rF``)ckfcM2~Jd9 zhkV9hR{z8IRvfks+XiVa-%lI~t8x%4)2<^v{g4Y=S{IRs8L9_-tW(9DTS|<{9$6V) zv&He{N8B|#i4K9Ewz)pt>XP5jSarpK8)ov>Xz~O-NDC8`c7D{cM=6YhMMW@MLUB^_ z^W^%Xm)hHVbRSh1X_J`iN**%yD)=C|aKiC6g^ICTwPv3jTRg*3xS(^0qhcG>w;fJS ztzD`eLSUFWW4U=Gz&8>NNQSwHXGR0;4HQoM2 zP88CwRDm*Wq0y{{uGZuW8bT(AY{{(IBA*l3W3L&anhIQ-<(uC7u95q6EKC5Vd@FXA zaOQrsqBa}xg`~5kze?T0Nq!-NBpUvUea|d(?a9 z{r5fg&8F{Z-_0JH^0-7*9*Q&J1B1I1bYqL{B^|s0`t_!{<3N5+@Ka6iXlGv|!&lnB zO6NEKb~}tie+|@_6j^0VKuT9RdB-Hqkm!_Ydvq|Q{50sC?REl#pVsILe+#ROA_Or2ST3pi=>wN%zftE z!!Whsj=&HzP@%74iG;nd;>Bghr*+PL4bq^4^0&;jisO$BJz0_h)JyCcs*9O?uL4c) zzUS?6f)pPyI1&4?bC1v_?n-u(%PyGfm*e1a6aV}CWQvOYEG43a&$`>{Y&dH!A*GU!>t^~EiBST|0_BG(*v+WA+H>WzxM z$mk!bNC1(D(>@kYG4_R9Qm~|#yyu4qJcEcM56kWW>9LChUo9K2egY3wfoi1*4@Wjz z$z>@~6D_?*ZTW{Ibb4a{)ZPedwja&bTE=0MG{D%zb;wr+aE1OH!VX}OCxaQGQZXLe0hzpi-MMGVw;<$tdz2MUH1Y&Xl`uoJOEbEg%SWwLeUbiN%Hm zU~#|8P=ZlxYGPJd?)qW$PzoEwzpQOP;`>zTUGV;IsZ!qkDB2E|T zKcGjLKN|*{*LD+01upuyY>k<&^``@*#^#N3D^6*$lGCW(bd4g~_{Yf6=jOGG+(+ND z6}9_>{i+)QY-?*v1Q0z78LMQyF7IKrWu&#U&*+e5b=p?G)GEMHILS1c!q_CV#0( z50U*ZIidx_aqb-;v2B5+a3Wc-0p!*g)xyMJYHQyTF3p(kPkm<8zq^^>*RQtYaEvT- zl@wM@Lu5@+uer-{uj$c?7TZCWAET78XZf=?f%LZKfUICqSJ;y#gi@B}%avUJ88JRW zCh)cr#ya-TK@wQD!adoY&z}&=4bMzqli&2bs4)jHxP?#F1?dX7v8Xnj^_1_^^%kJ1 zgG3JeJTe=NeYx|~4bsL1gq7`LC%_5DwW>t-Z}9I^tmRB?my+ z;SV>~bh%+OMkm#t+css{KgJPPE*@+8#u~`NrZH40Q)fMu$I*o(4lXXIujuL-a|~y` zhs7Jv9ecyk{(w?c-*4dpKzk_>6$6iVc{3u~1`u?;X^yuYHTFe)O^6Ih=0hxMQ6L7A zISfCGx9E2-P}R?1_xz-Vkyd18-^Me#9vWRKY4_#Lc^0`6hwG_b^ER7lVJ?AWrAeHE z7nODm+vt}sUs|B4(Uw)Zfbdm0&SF@?yZc%#&!9F%+g`Q$We-wgsi`PP`UzG;xpVMG z>OG7hf3asJ7lO$|I5;>zaI&2Wz(UYd!gro%xru{cdSJOJ_Fx88sxyPA`RafG3;4F3W>4*dnkQeD41wyZ(gf1Yx2nitlMG$GyklV1|;FwPxm;^SQ74e%fGq6y=M9=Hu-3LOT^pZF#ac4SsPYJ>pQG-dXXy`uL#^ z-$S9JC1n?S_eVXw|m72P{ZL|ji6B3_lkK_&43(UR!6Nzgm@NC=KSVbyWc zKY3X{mna>dQuaX!?09Nu?{U+0oYA#`_KMP3o{<=n9_KE_9J zl~KK9-_XfQzGr_8F{d0mR9QS6m|SZn*qPIiO6>$PZ|8F0>8qQG zanfI26zvx}K1f_M9PQXFg~oLAB*uk%IHo{rU8W`)Ubv|?i=xjxvsq4@ar<~s24H3u zA>QYSifQ|LXoGu6^q}*V6=a|HVq^83k=FO`k86CGbLB^g7d7ABC+-%)e@x~jU}O7$ zJ{f^-pDewS`M2XW16_FG@;$$n)jJWp%~;%7aRO&WuA6pBh5AWl+q{PPdU!yWM9584 zJ4J&MeYz8%`TDHLb=4=t3dsb@h>b9pu0WH*p-bi?7=#8EW{UsbMI; zeLamc7JknBR~)k3WrYc7M+csP^t*AP&%57%=Usg>#p+?;(my$hyy(lsCnd{J^)oU! zN!N=JK+HY3zfb+t?t6G8H#5>H^Z1Bsld@=8Z5?f_!GxE?*lj|s+8jGrl+?_-w2_48d1Dtw|l#6HcwKs|p1i7eW<#2C!{ z1L4AjB;XfIRXG(1ApIe`!Tr2=&;NWt zZSMj-XRUmm_AVgoQ#0G!le>cce5&a-G#~z&;uFsLhT#aS(_z|Rg4^F~PGByBdxHJ7K)o|8U^^IV&cY#TLRsF*$;)woKkPGeS=CDKHB$1o)FFqK^jZF2E(7a zqg+~ZVi&the=t{Z%^epqRaisvg=CLpY+oNyEf&U?9khKYl)UgYbPABf;s(X`^TMTN zLnlA%q%pM(Cy#$^C$HTpG9;}$NIMDX)m2bLyPTCSLs#R~HzgG4~g}B#RYbH=b$;Wb1IKEh%#EpK3E+qzV$z&!u`>_*k6lS)5rAk!@gr$KD}W& zmjqNPg{xMh%XA$rz~?o%pK_f?FZyRs&ecYr))$URbL=cvPcWMC)(Mv$)He?^uBOp_ zITeF_!Ar0;^zCaW;)kS~Kr*sr$dJ6maT;0Nn{ajVdMCgbl`FaCz()?|5P z(C!u{M=LJ>u0^5sVCbpvWk-wKM{dyb21W;6NGisS3hucvWCz@r+5=EELKVo}rC&Mz zar`8@t8L6fZ3-tsN-q@WWjkGjfl1@$VxX;hd(um0*Jsx#YQIlwj&`I-Iwe3_x!)e9 z7O0)e#VMM7IDQWe9q6}kb{)2tgz^mDp&ihkA`&cwE3I}WKb)}#z-=a{@G8dMCtt5% zBs4pXx~;S9kWoW8pIu#uN7kISGf@Nq_heeIhWENe0d0ty9o1MO_*P>4G}!0SlZD{B z#l@v(B`}P33iW+1mxx~UJYuEs&M@9? z$R@_`*vx4x@a8-dRymeu@Oze|IV>H1{-By?a5Mi0dEpWkrI`MxU1I9z<4mM=hkfy} zx5GHI1XHHHV}Q7o#}s4EdHvyM3qS6sogJ?s&40N2crT>45eN7S{6P;MS_OD$m7#?PF(sBQj$o@qRrn4=AD z5x?IyTroc;xbNnru(Y)2EJZGmB%hntV~cHZ-`})qOz7(?!#3ad|CTMc5Cm?+ujVg&5BxZnJ*p!0+6~d#bL_8vbew0I)VN+k*uTgNp&lCF>A8 zWf!nYmFHMhZI~>rTS0sE_h2lUztxZQow+r5x~`dcirgC)l7@8#SVVmKqFz*hfl#yq z_hr)a@=ID1ZoL6(+{~QFah_Glh|^!fy}kJF>fev=8{f7_@p0aFGhbvl!t4Z>2Ix!) zZW^D|B4y$GxRMY>--l+mr-OHNi+*zh6eh!e<)7%>a5MtDBL~mSmBABgW6s^p3?q z(a*TP%jgyh)9J@Wo&i(3@V-y0C8$Rh@?h~KiyaR>ZpJo3N=k9Nl5IO9=+5nt%QL5~ zT!o570+dD4AssuKql5y48m9L5{n%~@lsu0$98=a^8^#tjs||C6yKOG|ES*0nb<%{^ zs(y@=J@`3e=FTPZBbrj{Zs&!nV)(pYq}0kzZ-;^z)Sh?s0tF6qczd1==nGRy0efgp z+hdYpcwg-o@EV2Da8A!_Ia*D>lBxWJ_)%=*j>1$;#f#0^N(oxT`=0%x{ely$rzvX3 zF-1^N%UBrP%TTVkZ|Io^IwcWtH4>Lu2n3;=*>&+4ofcDlt1z-_=6(C!@E@y&yWN;$ ztcOizsbx0w3@w3DxRW`_dvmUTbrlnDJXOM8W%R}cw*Y-pwcXkJQY?_J@ZV&aJM1w~ z>XQK;=M^t{<#ZQS$VLh7gyGmZ3}khi>ytv9qb7ISgqZ}U@OK_6XoaDLJyWO z7VcqdmyW(JTZnqU)`x@|!sCod^ z7#11D&lCppk{RIzX7<3A;2dpYnf~Nx*LwVk-J5tVbsOIF7PZrXI61nwF}m$?j%J4t zJ)kDu{M$)zC`~y_HRX{eTKpVjigyIFzpTU;80}wb`X%qbAxfFwp+bR-hjwF|KZ081 z2riN+PBqKf;`o0)E(gWdr#=708~!%0X+hE>H2zfjF{RAq!{sgw&ZFURj0x(At|S80 zYdgP-f=*-&d7~C2s|J0z61<_h0n~h#zkwNA(gf)UR3!pCZGn%GT0f^DUBX6s#&?@# zmf$Nkpbp40MjAgh%;7^QL>;7k>aofK}-jF^cu6=k~?K>jOCxCr@ZmMASNe z4F*_WY|U?tXKPFJO<0(igoFWf-pKp}&;tN0v-v}M;ptqy1;L8+Mg*v{TjC6T=|VC$=|*N}OKQDe6h!5HK#Z4U zw_T}tOQ^J5>IdTM^#x{|cOt>;)+hMyiFi8Bv$L}+pX2za6^|6Cuwbi=fH)K&WQmcE zOte^am!{DxS!)o_6Gjc*Cu6_U_)xgj&(*_10`ohhoW$+iCSr1OtOEBrmuW8&Nften zt_y0>5F8wt^YsP2%g*NFtUH4=$3Fol99-)*9P5R)<)Q08r2&ZijuVJCDk?q$@BE05 zj?m|c` zEBgBA*x1;S5-JZ1U5DGWqRD;mN|`t4bK+oA`kp71dp)}=cGEz;9D4?w`_sD#E!&Fybof|<~mMypbSHYn|FU2OxX(0Dpp3c0fC-XX-X za{?Tt;21Gd6^eo_KC_EbubUF=kw3-=!h7@c>PsWR8Oh>y5ng`xRP0}vj8eqw!t@9s zA__u_`Btj2b{#jq0wV=i^v@(n^&a-yy(e79nm~NS7N6y@O^;scE?orhvz^iJ zkXqn~K3aey;x3>2NW{3W%A+e#h(njmS@ItI7Q})6Y<_!W;X|VupQ9Z3{}A3dYuwa{ zd)x#pE8Tzn4T<;{2mPOUy#G1H;)WY|{C}x&{{Juv0^{r1ueq4P!AFwGh^G&d)6+Zo z^V9Sa{db1~&c(|l!;!W(u8_fvLw(GhaNy8C7zZH!wE=ZuZJLk*zFpVB6$L4vFJ{la z@9jyPJmPkI0Brf&T^wastC3x(f4?WPFalVA^-lXjI9~=1ONRbs&772$Ry-Mo{RYJ` zK>uDj{+Mz09mnAU;FOn+7WEqNs+fZRWITYc)%uUG6%_Cm{*|r!f5-g+Syt|Ht;VIO zK_h3R{eV2j*?>*<4Is;9-FKAY$`Tr_F}~N52i++9H3?^bWm3Lpay3gADO0dW@l3a?;#K2^Fk zvA45FzxTyPy6p+fl$ll5FjLw!{h@;LV%bsML(8K&^tY8sB9!pbOY}EV^l|mkz1a}X z$*b{UNTYod(gI6heAN~B$H9v$RW`6NdMGJ(0Z*75_d6hjgUA8_JMHeax4>KHDNBiG z>kY3GUc}!7Zw=cTxQ2)KVSLu~_`8BD`*r{!!On=3=Pk9C?XJo_=<1$$a;0yG+iaku z+brHw_T&%j##HPGEkYvCu992}1~_GU1o#-ev-bR2lLk4$%6`h%k*r9?4e}<$1 z3GS>4lH+QGpk#_q=d@Xp|tM1WJJ@W5qvYhFZY<+wIU896QmuU3^uACzqsRBHaf<#xJ*klS* zrc5b<>h8(`?RLPv*A>O2rg@TDLvW2O<_;gLie@?Ml)k6C;9!+Sy)VseoU4QPdO!4B z9)yefY^3LEQEb6Crfv)%CvFgt7p7BNSlHU$3+BiX##1WfG4iwZ++TRVT z&o4Y9?ma0g-9!;PO~kyKsD?6ChQVD9v{$HJ@XcIP+P_j(^R6-8 zX?26K5PrlJcw^l|{8ZVCQygiG_}-h0JVPfS4Xa&RFZI5?Y(b-9naQ0xkRY{sjPg;XGY8CJ_!Z3eR^>OKlTTJ%HjAPYFYqUei@37Zb>ugc+yP($t!>EO{l?j}?^q(bk%?qQ-6nGyWd$ZR=ze z3aS=F%a8i!CvMEx1)n-iMfMH!Napw=Q0Z-rvhUZFD)EeChS7ii0j`r zhAShX`GwHqVhhU)hs|coSL>z?GF$Oeyvw>Ioww_Y%`>xJ#h{NdzbfAkWzrE|_3WY) zp!=L?#~kVN?R`-#@_Fc;8W&;Prw$HNfuWpsM#xCJ!j7x-j_fmZ${4<|?vr-r-Vd@| zL)`B&{?hH`!3rJpbttsgh!qN(n?6o=Y`Aq_dwF=ta0*OJq#DL+SG-iG3%PnbO3DOV zJbx00J?fk{%QW>$CDTjKozhxmzX^s-PQo{DD!I*WJiXHZ97qCCl=8D3Exf>})IO3z zZVTrZe&^=bk0ZtzbExbq-#2w67t7i4yL|c#&=35Aa{zBdj*8s5{f^$2uBo-AZ;&Xs zCZ2eyO{~_!>!W<7>C|VS+{gS2@lZcH>j59$V8|**M8CJJM#K1X!R_bx+(S=5G`p^S zJlLLI+~FAFE9%tv7`ihF@wIxgjHA6a`Rmfz8~78FGAdW9lyfR39=d?-hG8h7P^HR z&5}Gh!eAZZR~-`%n?W2f{5RB48u|59BnJajSLsR83_?V`6^uwQVL zGh1bDSsH`b^PPIbvHe0%s3~LByVwzKsNwe7?kNFn{3xYmde4?y3O*-;=9w``4;~Ig zX_wf?zeFoTvkwSXbvw?dlU&s3UF9Qyi9}F{B3IIZhDJdm7O6~Oj>Ugo;<@44xtsW7 zl*EcNU0*%9o|6Q!_$%oL(a+=4`U(FdUXz}|k#!3D92o-M;zsBN7+9UA00F5LB`4f8 z%TWF>C>k4@E>M9Tky5(w&zio(gYZKiWNc?&yXDV;g#TaGI%a>-`ZjQQT_Zp-_kH4Y zBhQw_g*`TS33;tg1Vu;psy_Ml^hqW^@h7#8&1SbL=4s1QB+JZGgT<)0=v!TgqR9$J z-I7wrm8f9~7f$HYe+Vv%muz^jF2iL4rIr13<20+Q^RjU`UL~eM!K(2FY$kNvkRpjv zK=+{)z=WJzeDxhTU;K*iY+En(yo>u5X`I+{Q+EgvD_`pf)OB^^Z>3q69w798al~6p zx^g!SRzfu6PQ-V3F!drm0>1$I$b~xL@F>KSs+L5Y&Mw51B}d3nHdrcLj&wFN#mZmg z(KDyerzd;YpXKQ(6#Ls(9_~(p^9d-ZW&ifh&R=;MWnh|lHZL9j?r%4vghMx8gG2h<%h`ptgM$EgF5~CF&#m}$WWF*m6i0JL0ZzP!1t{gdm&p9 z6zr`?C-02!L8D9ZBF7z}{4MVj5sWc)Li4T;%J;WjYB-4vck&+YF|K*=M$UOgqIf>Z zw7tK;aX3jf)CR(PH=pxH5^PMB-lTf^VTb$rjBeh1-zHz-fGhxGZb;OII#bt&J`rXe zut@@_pMe<9jR>Ff7v^w()p8r*yDQRnxndp?A(GbEz@xme5^3ptc*y=)|2q4)LI)bMBKL8Wm3BAc!NV} zSHmu;Zj`Op49om2EiZvr3_tSIAMqII;(6rx20J8KW?Yr%6xpc}GdM zF6!~P8bO29)!bIKG|#r~CtDK^of7T0BQJ)YR4)bXNRgr&9nGR!Gz$9e>LuO}SeGF9 zaE(&VD<$aLCck2|b@F88q-Q}ox&|N+E(CZjcybP}D*PHA-PN-c{&2Szg7Hne6{&XF zh6ZtKt|PL|+d(Y|`QnN?qnH8l=N;IqSE7h%cDZdHXPuk*cj>$esJyKq+aD38C-;4t zPzy);@&eoly|p9#m=_5K=X)BZWiQ_rnYW|~&wfa2R(N^*hBXc8Q@Z$-S+a&Q<+e50 zJO5#aq+X7Y2D5Nu&@UN)Pf0SCWYS1f^o?CYXK561zb0`f<{@?j|9x)35yTsCdMGZ< ziHf(H#0`(gi4Q!2CHUJC$JC_6S=MDy9zvw|Tr=%dLb!SzCs_^@7OJ%xrGigYCQfeT zgxUjQlz#*8_(AwdL%hZND22LTz&_s0_7sH{7`TLP^ZvN<)G-OeFT0|7_a+Ff9>yhU{=L`CV2bA-Qvv` z*c3ytt@{&Ur6nP5;C#Npm1(dqH}-+6R_9O|_USzV6MF=C;4SZO!|??N3ZEt!RgJ;_ zj=hyVt&-ia^!lk-s5$W!T3W*$-P6UJC9#}R^aLzUH5@G6Wn^~Th}+;d(yYli%Uz+M z#V5SKgq`B`EM!}I;NjCs@=$y3W~#1rP8}Zdy|mu&LAjUFD-Lvxq5j4h_=RNYZIADF zepAA+k5^eCkx_|apb{1-B9BtJYeKD{OX0vZC^_ZF8er_+M9#zVQ6o}gb;NMN#3{Hd zLZ!f}*+s?TL-u3^W>2rRm14Hbp)F3i~CyQsY zj^6twjutwr`lDDWNE2h1e&1zlIJu)NcQhZeOMgz}i{8lk8Q4^d7vQQkIIK)E77*LN zak)>xzjd=2=lAKrd1HP*{@(%wBm+xKA+^bMf00rDTH`IJ!yq%8rOJjX0d0!<4>~=JwZA}?MraPaIR1sEwb^hUu zA6q(jyFB+Ri6a_mT&h^um}XpZZ(Ish9BtmLbJGCBHs%#?YYJ)~3@$pV*n$k|{j6=YL#2o&tS1bl|2_elbM6*x>4z}~Yr^6~QSQK1XDKoM~;*u59{f;=jK#(^JI zy-_aK=HrwDboq~te1Ub_U>(45xsP8rZ8`!amvMaI*E$4ZU<}fY9UU*r%gcjn{N=Cj z-s~XeO;l2ns9hAZsLDlr1b~x0C`E)&-z~}=@nlVK6gz!Eq=X?)O%1%c(jO&`fFtd- zn<~IZ_$pXkzMS>YRJl=vt-i6;r4Z~l<=+VYFM0x}09AJ+<%Mr=Z|k)NuYvc~yM9~) z+~jX#VnmK9$i;Y+s4gRvYYq<-soc$iCor7t=C&bIGK*-YR8nSSt%Jm*O8Rr|l$Oqo zui*&fPt8#Xz&hJPNZk9yxKXU!^18_Iv=;LkWk^;+uXl?MU>)$GsyenZQe|DiT(y#>W#;B zqWJgV!tWnv$5U!N$q{lerjS?3Xl)^Z{336xpNA$i|Rs68H{C&HSF)aso#xn3z9yU`C?P8vA=j4G{c8c~uhZH!q0jb6cRD6~3GIx%exziXO0pqPX z5|6MTzp#ihV__261pLO9RK(RRtO5j#wct0FPFHA!a*P_r%#%dnMLT{lU+Ggisn({S zkLt!}$Sz(}wjTbp`N#W2D@jPeSn1dBcUb^_+6xP^fEkCa@pPlpi(@9d6R)EB-$gH= zWCn@Cf?#%?metY2)+$$Gvnea$nzWPHqgY1dNtu}M6hxtu-gQ`}6 zu?mbb*NFsP-wU(;7!&&Z3)6h&=c#-D+-4Y|C&YrcTnW6PNBx(v9oEczicw(Hqd*4~ zY8wv^y%{ast@ik(Zd=VprI02{&icew7Y@no6r0p znQuLG-mWy#RfX0%J~gBZ2l-veZM*z%}|1D zO;OQ65MdIlo(K}{Kr}@W516KR-bO{m_mX-vaf|5QO#w+WruONfEk~&>%ChO7L86S7 zFNl_Lo|uCa`5{1(712I=>^;d&>Dodtx$sT$D+pL8Fv}ObO%pD~*0|0@Xr)TwE2$=z zA7f=Z=H-g1VtHGlcTJhF3aCc5U5%QfpG=#kT68O)aA_nPZyi$w*XtawN^Fd5@IjqR zyh^@W*1mq~O0dmKMZmrlu6apOQ8F~MWOLY6(JJwiZ8G6J{_LeW_P-wG_en`|axJqk zGq+Amm=x%H&MZjK*312N+RNPm&@v9&DV%n8@S z<7NA`*+A*WzbQ}CZ*b=nf`Av`MHH2jGv8i{rC}_d0FfH&u&pMCQQqHm_~eLF>-|1> zH%1oky`383TjaPq1f^|9f`8RJu8aYw+25-JfUJm6sD4?RPM#i%d-e1)EiBQdY;_O^3XwjHJ!0*9g zaaC8m=gIBE&(h67a~J2oD4@VNs)bpT0x_YvZ6$K=;zRHjP;9Y>x}5=M!dRd=%bF`)RA zJEZ}pY0!}j1P}o+G+<(+RT-d~+1 zW?DtI#N@Q`PMLw782pzPbBYAocO>^5IEnE*K|ID&a%r|_+ZP#ITj@>g{vNGeEk8ZC z@TUkUmOg5+5`*q#jpL0ZNphU|{o%}eeW}b7_P3Kql&q)-IX_mtA6-IJ{shs!MpMbX zRd+DSS9gwCf|DFU!Lv3AS(^$LB$arix>Y@d%8|Gv7~lw39F+fM4s5jBD_mezR`ph5 zEqhYQXpx~Us^0&eNHD|BdX&s!;On0g?vs2w2p`C^d(**!a}T*nX_tU&HDgr^EI-eJ z)6|<1z&?0f0YB2AHDIhSs30vxk8Ak^s5M;|TIj?5kCAhl=sNgh=ik0!FkS0g#>KCo zTF7(|ak{3B_)6-rEDu(km(3Bdkm(+u3}f1@cWc9JVE%B*Z^r^)TNU8XPE5K2;C}g8 z{?~K}P}4x)C%=;ep&xUX!QSdHrw|I`=`{~w(7AL4{gnh9Y^j#2e6X!4021ieK?Kle z;Hw3xJ-wGmc9`7u8ONlONhiC5SoRaHa6?~iz_Bwk3@Cd z*4I1ieZYVE9Yf{o?@|to&&j?OKV`3QT-pf>`cc=Z;QlHUIAVtb!!%0*vI{n@va&)_ zw6ACLdV##;G|!O-b&G##09#2A=owZ7n(U>5{N)lm7k+T#b!P>gOTkLqb-K>oX|)98 zAiJ|}WYxtZ@Pg%N5((!29W@Z5T%EVFl;(D(j3{60klCQ?8pp~5egS|RKJvgvJqgPA zAA3%g#<9qy*X1=>?qXL9=rn+Bau2+V3tZZdmguuImpt&-g$^e?9$uyjteuS``OC&u zE4HU=S^I&t_optipD!wIkr{Lt3z3H}|H9j4_MK`&)1s9d*^2Q&_Ngh_WeOM41pzsL&95n1@s^W|I6rT2oB9@-h}2@q8^-{WwL2D1Uk?s zmXuS>=f^3$BQRQ1;8+8}j6ESfW+@KY8gU_)(1W_~jYA00mFRAcrFM|M2{OOC z+=s!%it$^243^WBlt!>11qk5UD?FASvVuMgGSBAma6K0w-1zOHy;6V(Svc|k`dx+! zbXdE|3diXF4*1@f3Ij+3Y9bA@1dW?~Q_^2LFL>GU2Dy7l{X1|N1dK6^qUZfo({Iv4i!H6(;QUrRdZwlBi4E{1<^PW^X?dg1^cl{$7DH? ze6hLf`GdytsMpvA>`!ptxU0vnpqtdOU%#3bTQ*(oVtc{L?tf_gGQ-$wQxr(|{PdSW zvOg|g&TDfP*MAptrsvjsrwBn1&jZ`}G`V&IKPx#45g$q%{C1Ai(c*l!4a}t)(!hqK8;mdrR ze)q)!XsEZ_EdNn>9Do`^SsCLgQ92d$_oklvHQMEeh;#IRD^_HvT|O%a%#3QdzvE1c zikh9BeM2I!+OsPMvfhD=k4r5Fi~28rfgW;z3+IWE3kI(O_fpMGZV-~d<|0KH)2u%A z3*VDv;_NLwue8^^PI;8udh41IpXlFsfgBzqIcvP!j@Lo>JlOGrR+K8)tuU}p8cCk;&q2yBm#8A z_vj!P%zxyb<6eOh;&8Vrba{O zL=bJ--DXuoaUPyeP|%D0m^tF|iR9Tuwec%@K1K3x+EXx14&o~VEzihkCChvSUmM({ zF9%r#xLL=}?hOcD`SRBiS{RffaDyFOr$KKuQ;Skb;NVn}FO|Gj;CG4fCb5u?48@_h zBoR>y3En%2Jj}<{xAgCzpTW5sFarrE9`&pl$C!MZUq5F=wc-Hc`Lt&zL>nm8x}6^l1=s;3M+o$dLpI#{2cP<{P!<5}6#Nt50@|F2YCTfo%^7=~!VBt7*euom z5uXC$;^RQNiniP~A=B3NoP;OL#9(eKIVP#Ea11%{RyAPAziZ{LAu%R$A9!g7lLba{~Hn2lk|s(x?SerlQyXdLe<$v zQ@^@h(QQED>V`seirfZ^JC~7Oah$7R2-Z!G;l&{~gqF1w`h8>L+;o@6PTw8K-Jc*KpV3 zi^}he$3l=_|0n6v)=VnZb{>bD^;S>9m5Wfd>A&sev5@i{P(XSBvPx`&!1?o9)|`08 z8@(5{fI_eIB2!b?d0o-MnT^_s>?mAHh6P%fTB1v@4-^%5kY$Gdjc$;Rcz!wv)7>p9 zyVe78WTK)_{cvT}!JCcz&+|A83sh*0TubdU`AG!+>bVXw$xYGs#kJ_b-5l^zwkr?_ zc}eoImi?#C$B{Lc@P0OX(BZ*=1LkjUDot_SgcrZn_MZ3gu`EWHa99E-l0Z2K2>2Yv%!Du>&*2{H>W#nJ5z%-zAu<#meFwc?<{&VVp0# zpZF~9X6g^38Ve)VdAI3C)O+FR`i@s19cx{Yj!)QTS-t=z>UGI0uAOjC_yC2462v&b#8TOqw^)n2rPN|a z%oAP+LRXsrDnZcmAE?At-;gpYqb0YCc7)q0ogWJjp+lxdMe3Vv@I-30DA1~B;j=r9 z@1i#wI`JD$&nb$0)m}f8ehDJmaG(TJ7+rsc%oC;y3!s}9w;)Yw?@!fv3rv42dW74zgBGQkBr$o^{xPvQ#Q%Q?AO#qRg-z`=S)#)%dlTTfl9-HjL5| zD&k25JsKF`VW{*~TtS-qGH3{ZE(#`vBK7$@NsfUr({#QaWPOd}VT`ce(6pt!QLbu&JPj5+UBtV_)}7AfKmp zat#gZ^u5Xm5eI=O0}-@UYKyS2l)UrCjzE7H3=fPvoKrW%2Ut=^Xs6X2N$~w?Z_Yk)mJ@l_jOR91~qY8?9e7CkK6+J(;Bs}kxSSb-Lv0;zEJC0Uxd~`5xEiA z68yfmw^dRa+PVGc1=V6*wML^|UXbSsQ$|UdCK&3f-AIfhkU&+3ASU&{2KwxDD>1jZ z5beM$eXB~S(Am?MxmL-{;5=Uv`6*>OrI&VE?`r1MPUL|P(CHSke>LX^@y}eCswke+ zz(T79`?IxKtE61t^Fpx!o;5q9xMoK&_3KmCtoKab9WH`9#k7RWkS488p?=2z%Y`cK zb3ytb(!R=vA-?YNT-|MW%IAuO@0mK5%aPjWf2lTE;`Y-@1cmPz7T2!En_G@c6@my_ zz}3D#?j$Y^U67AU3RDmVSX7Yg$&VV8+!gM!7d9L31Wo~ zLAXX^i3;1Zt}lbj+V7^Av9qG?y)to~fzhNo#Vt>Z4iZ?lzw!lGMhrCu1qD?$>Q?r; zFj!}{psrXw>W1sD{Z@y#amjHnv&qeW5N~tGbQ=rFh%$MceZyF}`cV z!s*D`O|&QcT`4iOV+Cf&s!Dh0S9H-}*Gvi@5(z19zPg=Eu~HM^Da&?rWG=9MBV?kZ z|GpzmBB9ka1hx9P)j$M_1H$=fx3N<7=8_iGQ_MrEobE0if}1;`ak336H&%;pyt|#~ z1=5A}NHEW1NnLd(z&BRP+&4YN{4*J&*?W6}>%l7*8TnQcS9%}Ib(UN~PvJjtM4MFW zQXFDKufe-Y?D#VkQSAFDw05E;wGCs0$q>)FdE}6SWGiRD&rU9dm^I)nu65yB&Hw!S zeA&=)96N4tJ8qDSQd}g7X;m%Q9;+n~1mE0ude8y&5Za!BUz7eO%KI&m^S-y@K1=KR(~ zLeCO*MK66P&~zXKc18r>AgXW;smoQtENNcKxAKtZq^wzz9XuSSWFRoQW5Ie4B+9z| z=yajKCT*NogxSq)rW%b{)|Qt>?}p7Yw~$X}YcM@ZWS_d#!m;19GFZ_4q2>Xrwxu{> z+j7RsPj5(xflvn8V-Ndras8K2!qb;InCokTCcTMJm4n+ZJzhiPzeO&o&g?d2WIy}g zA@4=!w+BKM9SG=p2Nha>EQzquN*evo*bz+8(EAoi#4%@$%QcV_sI>K-;y$_Mjkuof z%G)UR`nSSbgm@Tq=Q(uh`YcHPd*O^?wW+x`a1XLOu6f4$5p}I&{*hnF2dXDT^;AG> zdn6g7Sz;x`cd)X`kh7{D|Cmz^omHa@{>7M3b?=e>TG+?|NMq`pF-{OMC>+aWH&e*) zah7y5U{{vU;3WBm9dg+h*Pi*~AX`6tp5)9nj#TAeQ-@) zq=8huX)`jgE`5@a%J-Np>3G{vh@*PTo;UF9%WnJIdFuZ0)4$2NscD6ZaWP*-L)G_) zw{Dq|s+zD!QnrPXsRZ*oo`YU`xnUbj4k*xsWwi*bdUAZ?2pFxEL%bdX z4eRGjB+l1$pz6n{U;mHhoEH=gAA0kJ><~0}+lP7L&4{oRroq41oFl_*L!Uv%8FFu#UBhy3g ztX)h?aHjEXAK?xRUBJkj3rK~z##hDgCAV|w>)NH;vov>Ys6l-^`4#OG^MDcOWlhxM(k6zY(s~AYktP}=ZNB4K z_?;`-3RM0-yOGl(cs-A`mF5~0iH4|LS&p`(W1CmD(L_R!`RmcpokCe{dGcAp^0j1Q zHTaYoff_FXPh8uN&kM~n_Sce*Hbku1W{g_ct2?4%V!rM4fu64R8R5%v%XeNb-<<WA>$XIA;MZUE_t6h=R6 zKN7Vb-D&Vd4P0eB{}}Z%@s!8N(#O#Kb0GO473?FPTcOA0pfA>+?&F<1i&0;}^M%cI z33u#iH`AkQLP-UGjQPF`p$eIb%(oz<_=GT%l(wJ-Lo zuV>J-%dD%ttG(gA&$Z%Kc6u?vG-ReTrb$k6i|H~@me=8i_BHG9DLY33~L)nb|;`YIQHjX&xjGQ7G| z2lHb9w))EIwcnubvtR4{w0zjFmS-EdN_!X`$2H%Azoo~2VA29A-W#gUZ zJFpp=8vMLo=1=&cNLx1e6NQ~}x7?C5N!4{4!W+>oeO=%TF}3-Ev(q)lL&Ou@s3v-^ zyJo#GqB>Exg1<88 zD}IHV8|V)xlYz0<+qSE3YZlc8cKiP7 zz8JuvaM)#`*=Kr37f?fTBN`#e|9+p;z|i@VkzQ){`E_rK;gXU?g0WS}c>9~5(bsoe zxH3HM-hVGS6BInF<(G#q|>H>jUUuE^2o6_}CO#PVHC07dR<^v;bO z#CPi=%tXA1wDC>5TSGH5qZo>B#=2T?Iog6iiMqpuNb4yn*QR|V=h;RU@QR}pcvo-G zdjgnZaA7-IR1Xbs@6N;h=8Hy{qIl3?)H3I;KF92O?3Y?FX6067SkJ=UK2^CKYENwO zIfKdWgW|T}dA*yz*ZZ3Vi*zhZ z78}Z(q&s=G*VTMY#6-FJ^%g&nTdId4qBg&`5on22ZNeLcxskFREjttx`;xS}caw&O zYvFZqe1K zK>Y**x)i%IF+{fb|)OvRPVr}-ln)=e-L@RI3uo_`pjI+2}&4H zPH>+APq3d!F!ZLql~2x{l|A_BomHeKC`Amj<40m1_Pd^trG2T0=t|)xg_;1kV%E4B z-_PxWvv|*)0kkvC#OGD`Wy$O(Mtr=W6CWn{Q#>;0twlbOHZg6CFfLT{pq z0Ie-j3^bTg&5D?$T z?5sgu9MD%jKq+d?BBDi6&gl5`i0P$2d!dL3cT&7mRdk5ZtLl3lD`9;=uN{=RJI{77 zujQRPrPQCnshvnxHU7GOy5n5?jNmPTFXeKsday#(PDR%0HKk()G-YmP^z|GrEZQecXel6q57A%o%sd9h{nYieA0s9_3 z_xRvo?(ynzS?iA|=?Nx$5{qX_wN`^bo-D&Q#s;r2FC4_CNaa%H~te?mi)%|XUo89}+AyPQVOR{sA(*qet#`NjXkQ%T9bq_U)BsceOiHAS|N zk~JpTV=M_-hNLVNLP)lyxp=p0hpLHq5jBj$LR`Tz9?4m{Ta!G>%K!t<)eizPPfgW zZ4;-jc>)+6fOQWAiWM$|Gz8H!UC^H$_)eQNZRw6WE^|3{saFR}9Y4ohpNB z0cVv~p4C=GKhhRUq)Qoqrpq#L%-&c#q?(Oz34|&%I7x@3!R0IRlKt^p{rlUmfI1a; z3^+pH5&ygX|Fnz1U+0i(!3z+o^Di6<6ed+7K&&(5Uf_{Rf8C|Iswb%&R~!6Co>Ph* z$kf-ySCI}nnqXW(bkP5e@A+aW006H82|xp)tfB%0LP|q)_%Uk2*5Dy0e?%BC3_&nu zItXcyyc7TeFt-3}m8JD=;y)qI1U-@|U>A0GpI>^^>WU;Q@uhp>VnH{kP*u>&`%9RlGuzkGH& zFZ{$6+@kBWfP4-N?=$oRrY6G2uK+sp>T$3+`M*60q|=2frl@b^`EO?a7FL!2KAo6c zBWxtX^?ZM`gC0^91g@0U*8#ygMiz+y#Jk0|MjQ(atakfmuQ2xEZAB z|M(Di1@IXCQ#6mM+LO0#-TD_O=HA`&g&`(p`~1l=g$GK7!-C0Qxi)m%?OeB~Wb%u^ z8F$#yQ+Vyuo2HrHlv{}0CZfPkVWZ=E83-f=hr=x@omdZm6ZG@(x_`UQYyBPsv7(m( z=pwmtpCuy!)#qN*hu;3*9u4VjlkorXm<&#KpL+&qLy#wFX5A?G%XEY<&dhzHiU~~9 z2$&l>x{9uWdA6rD{r$g6`IPQ#z){b+KvD!%c;eje3aotZJr3P9AwIsA&d%cyQ--Jo z^25g7GmygDo7%Q#NBDXIqexf7h<=+;0L~Kb6__C(N*6Y0nHFrx zeDCu0^LyN%sWw*ab}Clm;CZn{`C&jxcnRe17>b@+6v=j)r>Lv;gYcuE*1;c?R=?$V zfnG3Q-f^}SMCbZ7K3>3k0f=2i=<1E~)khD`F24;cIW89Exl|OLcQqk zI9u1;NXgf(MG%n)4LnaXNQsGw{cSqJ4k9|tyy7-$Dtu4`vcQC{0D;#5+p7pT{%gH} z3YA3DiC%i7CvGF9L*OWO*s-%sKYudNjaY++!2JYkND-@|FXj{S3w&M0a)SpTNo-P-0UK)N4ASA7W&2g1K z6P$GI`^u}uBD2OZ;2Vb1tkmk0Zc23h;~ANeg!e;VijSPn@1nHf_Hw(PZL}tP;O}l1 zIR36}9elPF?Q;H~*8mXH`ZxgfJdQHGHRa~Kc4SE2?lj|_q2i#=H@}fyD*|zMQAe9U zNOJ1N?_}OKo}Zu1S!~-HP4-$=Pf>aMJ zd`fq>S6&`@qJG`e0`q&D&+IIxFK+P9)Ai^-|H9x(MblX@L6Z$;Pf&2PxVIaDq_nLU zW{STE^2Swnv;KZT=a1wtUR_Xb+0w4g;kENMH{f2ezM1*+JhIo_0*AZ%RvAVP%phSl7H)y*C>;s7@A* zk0K|ZeEGwU7XP;AHZD$NuH8{;S-qVkf3YL-&%@=xmI;CC#tFC7b)~J42NvqSjePY? zK#*|Z|FCk&A7B6Y%LwW3YL;1x%-V)dR5{T7lq5%)igyTbn=>O`H+ zOV>}0dyA+9{R-`7{vJ4w74~-#`bt!NrG|ua_wA@#sP+1v2celO#*1tDA%K#>`E6c| zy>F1=9WLkPIO?*czB1`#SMv86d#ukzVKIa8fIUoO??N zqZUcRDcqFbq{}qulz0|9AvhvKCIAZf4i{#rcUGY(4z<{vE8fSPhC@hTF=qG=N!O@5 z?g_wj2}b;!A;#aa)S&oXx=v2d`P zpxY8!Cc(#+E#bmjktF-Q&HTADz;~YSDO>Qfi5!wfv8`0v#+c4408U3L( zOu*r{MsVF$@Fb~P@%+H}k)j;_aV(X6y>>2ma(nObgixuHP~_RVV+D>n_N$wbk9g+! zSw$HiJpL>i)vWlT?Z}dxjSXwW@i~jtV)jid^RKqN*&ajk=)Q4aZWe1wR5Na>C;lf(UnSQoTE5Q>v5Z`>fZ3F zFSK0eW`E|fO8o891tA2Ew?+qFp9A4;%goF<;NiE3Q3b@1IJ-QWs0`t`zlpnckq7(r zE$MpJ_U+z+iH$qeJ6D*g^x8FGr(3%6o@UM(UrCdZ$I2RcJnR@dG6;<6f8UVi3tFM= zh4-NhSgDz2oJ`yA^}0u21Aosk_a&b#E2x8OvTU{8a4)?-+@?4%%;>ZAE-ujI2-6nj z0oJ%-y6mB`g2jbbR*AdU3tJ967REViL8_boQauGy-Ju~#q^k)TB)cU_kxyY!&{yY9 z*ZAJ-H^Uz$M$kzkh7+8Iq9@j!Mx$P*LHNa|A9j2(|FGRL)g%wQ;8v{J6qdn17M82Q zdqr5z5`Vb7(?OWINUP?>=&8rW%%}OSWlTkCOHykvw9LcGsvq+W>1q7+*$DI0>)@N$%|bp1+C@aKORg`Ln7J zh)6+kNeL_LJmitLud?9y#6$u(MRF^Q|%&NCNI zDzi>Z24ZEcoN(2R#TBZ)-K7^|rabB%PJk5WC5E1k%EK4N|0Py+hpW#rsp?$?p?lOn zv$no=s?^=Xqnk)XNXp1yRv#LXeYhd92Ao-`9V@0Hl8oVDER09autmzAW^um;`EZ+q z;a-8M$nnEWFLP2C+J&YeeF?$`yCeO*8zH1RInp7Bc!^bSNJRks1Fm1VdBdA;kg2HO zPp$=EFwA4s@-3I&nO)z1?~dQ5fivq;RzZ7WGRv^)+Cg|4G09yPQB$|7MDnqqDn zpq-qYtaY0`LD=%pXZMKK@VE)3SVtuReGZ1FD}$o{iYtTK&8`P=7b_|%9-m5MVq%6k z>v4t#(Yl8}v5{L{tmljB${G)j;a zQabB(vBB2(a?+c6%G5@3ify1?scnOm?%>N;M_*LtMrok-CK-@yk!OEA5>fg&|*biqke;`GOMC~yo91Oib?`5B3AjzF~MY``S*)$Z9f_M&*h)kM&~!PfOlw$;NJ=G1vpY04ibBF*G#G z;pmI|w>A{rk(ezavN6Mw7d+OK{jU>&WG$_&6G64T#@v9UD-S<;05)!-Zf zqmu=AXr{+H>ecIarK)~)HU*}a5hox%^DH z$c6m_-!qKY&b+#I#_UZO4diira`FQnk56snjPAb!ac0U&yRoNbBGT(L#G5jb9pisi zJJ{*0I2Uiz8PhXtBJW6fLZ*uotF>!V*h^d^S`O!A1>Ueka&_Omth(#%Zc(5sc{09x zSu{*{GHJMvzXE}j7}kW&c{#5C)aGo|+U;TRO8$WNsSH));*4L-3!l-!T3g9npBPgw zsV8(J*H`nL9&6|=mR9*j<=d*lepX6jpC)`~O~$tZ7qi*6dn0PN0~|E&>t*A|7!0Z7 z(i>q{B<5b(=qX{Q_t&O}l6x-F$5s4yNZ-dR>z!V|Qq0$X7!%D$wLz7)hM7jFE_hqD z>Ywu#wl`==q!?n-q#OOh52dMTDLyxs~z&rT!3gu!iWogbk(Q;`f)!f))G&xG*S?c;k)+ z+~{DNwuN1?Lb;gm=oJko+|DWI2n(5bUYT&_?YF4@o_Tp}-VF$|V*w?iz9!hjw%*x* z*pC$*4$&zLSMPdr=0OBFwL!jz_jjP}+icCLS#SN>(zaYh*`*zZ^hGs)mI-ghH`&l= z)p2V7in%w@!FG6)UDex?+?NzoGMd6){6vVFHvh+-nie^Fy|gYwWo+aii;B;Rj|`z! zRtO0eTc?!Ras&{O?1%TkdjSv2aKS_*wYgGEA`?8OH>G|R^O5Hr26i1!={MZ^G5K_= z?||U4{}e}7WS_v*7N&gKN(v2Bv5c>(hi~W?`DmNShwSAJ*ZCrBvEsv&Rd;^tEToaE zjet;yM`~TLmC#2aCgz!U-|#wHgBcqiMr9iA-;B=VBe`?;eBmRBe6X->+%XDR>GRiz zWkGErFEE9t*ba9kIr#`YqpVJ)oOoHdzp{J+#cDQHMAO@O6H2&uA3X6ALoZL{;phJD ze9zoy!_0}WHcQ$S_2Xkx_@Y;da>A0(znSesPpP>BbdJU+HSY_`yQJn08FYA@&`yaj zXzq%i4b)8{p-f05eusuyoFZwEC6L@#Wc6=~4%cK4tc9BuiQ@e*{6E~_MZ=%I#oeyt zn@kyTYxJPGqU&HVAyoOeBYbi(sA2jGDzQCwj^2S^OjyV7Kcb#rDV-J_K2Y!fswA8= zd$*7Zr{B=92-SV!xrt_mczu+4j>o3g7sATiM{k=?!QM*>Z!H?D1}-Nvu3RSue)ddF5X`|S*DYHJs>I-%=eu9cd_+?$I;7(!-^kA zB`^xhygm}Ih>1JDV^;J2D9!wqSoE05$PJu*bSHE%8oiZuyWdTBo_VsP>x~ISfZl|-Wi5Bp4ClxXKTtPKXC0Y_DUheu(qAI zJCy#|U`kQM3L|XkeV8qQ_mrp=W)2j>tDSYe>xEU>Be!2g&B23mryY3S)rJ)YiKD zN%7o?4PAd<8~P2q$?{>aJl^zV_6m0m8iof~W42isk%pqhXL}S*+b|h3Yx&;3>ASOb ztO0)GcC%~3L2tN7Q;Nps@-CbY+Q2#p+j_*852q!?Okpv`>X-WiP?~LnXO3A0BOl1~ zv2I94S{~KBGC*o?XOuh7%fs~c!dH^MRJQh6ilzA(HV36;H11RyL$|o(JC!YR+gFx7 z1zw2Kkoyg_x2wy%ujw;U$l7RT#V|KHCsL}m@=#&U3N1X0_9gx?s{Oua(%&hznF<2= z*KO8ad^kTG*ZcGnDGT3$LOPiHN_u&VWYjXzCq{ zW%m0MMaNBex+?qCCHmDV?so9ADcWaMv|64+ZENP$<3G0?Q82b}RN`T}ywxp8(mTC@ zc>;lG-PZiZxJ%v|cwwo^UiZw^OFh$MMwMo_|Khe>T@x#!QGx9At}F(%*?LOET*h#O zRHiepKDl&mSxS&HfG1~zDdc{w=OlG$kU?+cz`$C^w$^ZcQ$J8FO6;h7$P*+c8e2O% zudX#jnn6oiqU#7!+cD=X(N5*?`Q`MQSFai8px_h(7gU>Z1=zog;g3rTSJ|~q?9ulY z#=L_sw}$P67p|3+ZV%^)n#2TEG}cN}KX*$qLzEU@epcR$;U>Zp*mG6o2jNY*O7Pl4 zm9PsrOEP25GRr>vJIN>TMWOc>zCdZkQQYozaMgYOEES&bwS-zW#YdwOJAwRd$1;^3 zdX7^avEr6Lsm`PrPg<9YV5lr#WSOnnLNIXCsOEQXL=CZ!(Twh z+-G4{p|nW(2$`-(TNh1*?5{|o#fRN)Y6{J*SdZ8s<3i9;Hq#B&uTuqda{k#n=&}qW z9Rvd5;Os2E?a+mhd{##t+)wQR&NrPgZ*H-2yzi6l0TRgM_7x+#V-fBHb+H zmvQmhsBrYNL{1~B9Z}3bO3d7Zy&qu~Y>;`d#AKweqxnzgKi<1V(2=9_@;{Itd&O zH!tg?yzpNpe2}j!dI!QSCP#0vtBKg1)-M}1XiyWmJX3QD!4B0x$?9D?W!&iMjwvQy zEPKR(E=e*Fwu7xZyyn{pl3hL(HS7f+E5h3G0f?4j+_KojxvzCJL--DaU&M&Ym zl&l66uq-t`I0k{FhYTAWgXVXyz0vC(kdvP*lNPn~R*wJvF@b-kuIpX%qxT=Rz9*15 z;(IIwT@%QLd})Xcg4hvtmJDv=?V1h0bb-m}c3{szdE3%4_f`$;oWh z{z(3}4(GU}lN9XE=U8$ktqwNxr`_>#f(HL(F6;aya;;+3@x%LFG_+ocPOPo{+i_X?!DQbHaZ77`--12|Jpx0*2Pbm%xKsXHn@cQaQwnCM4) zg^rqm9TG(DIv6T&wpSaAln4&R_%D+pkx|bRS_ zt8u})4pc$z#mhyuT4J~n?8?Zyl(K`)NRPPLkERi~;;*Rs3N?UQOzwle-zEt0p6#da z-Llh58$U6BhVnmgHjDBx(6*|$fU9Beb-I5x_;2%O5d6KB{ns**2c@NhsIBU67wweh)M2T=O896DMVE% z*q#0pco4oZ`%$}71(7}aw&HZu&vF)tlh*NtR*lA}eIE^JD0Mkf3>vzP+AKK|3n2?rW+&z}W5M9kke13Ko*i~D!HJ>x2o-6uu=ZT;?(R17Kg^9W3;|Mm2A z%h(4avfCpD?Ex8853MY%LILD;X$ksK{3m=Y*OT#OTF)<{UYSVzc0CjJmZI~u-my=r zrrSKsT63A5ALJxsCztKg=9hGom^d4xv=Wce>*E-9@~TyPcj2jwt6Q@{?Ohy-PU+;0ttjSTULBGImAjmCewcU?(6e<5cy!-mt}V|$NRL zPrlO#48F%(9Ojuxm~q&RwHzt$wsM*dOxdV6QWmOKE$JD>x}IFTb3%0Z5QHr~7Id6H zX^yjudnkv9k5D7mHKfl%lDtHAXSrSTgPS#DQxXqavNgz`OgL%V;_Z6JmNe7pIo?WX zd~Qe|RU!|s%gl+KPgrF?)62FubILZpai4AH^zo6m67t{U|EiUonS4EXVX_dmj#Yby?b&)UC&E-!JC-8{hIA80GP7lup zTOnF$SEZnyFIdVZr3{{=nEIJ%=WO3dw-*ymUDBEWZQ(qiKn(sJQa9!CB-PsgQ~&Eu zz17`>o3(h7hKau#N1RS6*iX-{a#mpnsQRyWf-21$1AUeJf*0igFDdX z3ca#(*Nwjx_>a1x@c}Sg>BAafS!MQTHs+-dQ=gZiMKVGwFApt!rBr6`IBSt^4ThMS z@Whacwi=GTu>6PT?We58E2AH~y6Q28H-GV*T_yx_F@)`p#ZfKhWVn!^TK&Jp<(}cv z?;s?V1v{3O_o}dc7&>=+5nxF1KO|aTW?tejP2uuv=yVHaj*2W9B3U`5pbP!S5r`gX zHwu9oY6hSdE`RVm;ip5J@Mdo*2j`h~>Shs_+2U*G%ny$oVcETUQRziB3YK4*Z(Ue? z8DeW}fE=Cj=o(}5UyB*&d54h8z}k$6NlX$0wWnCe z9=cMFE;{tPEgrDEvb)I7&);_snRqI&eqPB)m1cB-x(Aczo6jORRR*|d)INja8l{{g zB2fOJ(uZcMB*d~UuV`|JOxvCp+eKEbgN0W8cVwTb7mZ`PM52HOfMNRDn*#6|Xx8rQ z4^`=({M_}ZHS^!8pZ6m)4b4_uA2KsaDaFi}b_r!E5%gxXh?|6~kQm+Ru z@7nIq<%|6As;HFMIZ=k%VTUV5C7U!YqTFXPMPu!20J!{9ibJo;(}q@s)3-;OBd^0$ z3x}WRm5rv2v2VM4dhy%v_oJ(Kd~9*$VwZfq*4>^~OnIQmB4k$*X zYq#oaJ6!odhY!7fJT5xb=M`!`y{DM@e)e3lzJ*}pL&sE`tE>%ys)k-0gA@{Ap=A>V zKQVYE9(J4&d-7-el-bC^jete9GFXOKeua}`y4k0Xe?|2UL5Aq)!A&r304nJjB$uG{ zaNk)>vO?)$GP2=}p6EB}{k0RE@qcgLN6|J8%J;`NLbMQB!KU;d>L6ODL+`C@Un$2n zhd#E1Es$_O-@9L#|3-LXF$L|MO1;ABA2ifHJHP&RWckc#*Fj=NP@7$-wCi>+;MP0qQ$it2WczkyT z($Dz8+{OA|A67+|d}sY^&N!P_^=x1I+4Jp}^;vnPvQbGnX#g6-}7Tdy%ACt1w6x*(Q?wod#lJjhE zjLQqMb%P>e-X$AcMg}|Px5?|BhrED-m9gDOVl zjFydPDJw2U`eh}pchBB9r^ktnflp?o0<_g#jrhUza@dZCZK5Zw2%4~p+49^r(btEJ z&Gf)V1=Oze!|bsbS?e;YW71;5eLq2UOAK%gmOQRrkz8$6lB~G==W>14RHUEKUSCW- z`kN~*N$roGeL0#k;Tn)x;hKc^x!)h)kBFDKv_KjE?ie4?7n?l32su|K3@90HfMT+I zYdF~j&@GVPY*UJ$b<9gb5n4C{WY;#ptQJh%_7zc3;SOqQ0n^)a4-+;*53;(f%e3=q z1sQZM@WE|zD6GdB%#@fM_b1b@U0RUX7JcE)59utTBf~$X&NrR;r8fFOXaWvmCzt6r z*0zKz#dUta7a!uQ4Q`z6DgG#HS>Ad1-lfG#39o0LdcPKzl^F!>upZazdSjV&?672o zQ=jMR=J2>IREVesNjDRbd?A-zH~4`v{oHoij~Wmyx*%c9Ji?wLl6;r`|C)`MrTkjf z1^I8U7K8kb#@hPqTxpNkE)nO`t?^|r2k~)v>7U3oue&epH~oPE9ZycOF4JqQm89O^ z!k-kkvtY^~*|=_an`32;YX{|0d8L7eXh zNTa_88m+@CMSIOrm*{)>O|Ns*?_$*Nm#ODIgow@{IPC!?(a0sRmIZEor~jG$6#Z!u zYCOS?Fj+uWcwhfA>00!`?jgZSw5kMI{YfnP_z6NpL4O$Uqvk_h!-ue{8GI{NN$|#RAj9!Lm$^O1TFw zCkiLs;gRDfK@xy5=Q?~tOY5bkB-pV!oPOJRLn~rIUYtcM_vv@z%U@U|9-LwL0+UAy zXHNEjLrj&g`VAqSW%P#ClBd7OsCm)*hom>5{^u|=m${7oLz~5GAvOZ|lx?m^v`#`X zNCV=<4@g1!byrzL^4~vhtN;cSTqk(7lcLfId%r^-uls#{V1&@u14 z1|b&4$nIcV<>15*Uxa#rzzuHzA%p9vi$dDG){WETMnnBX2H7VvMqKCLWJk|5jJq3E zof5w|>Ns_73V*>>z>?~$hr^r{?GfATWgB?PdN761!>>`m@h7X=sdX*vIyoUhR?oh| z7ZF#r2;qtRuSgt*BD+7mgD<`~)z1>{RC%54hlbjxr1-W`odip=e;xr=Q>m9}lq#4V zeTp+4Sfw6mBYkjMd|a^Blj?~do}8%`P!0jMAYnPoPn#4mk*Yq!wJ~Lt+mN>F`-$|% z`s@X^{D6m0bp0|}M3Oy0-WFlns)|piy8W`%;wXiS_p+6@T=@{EghY!}8*ID!px;bk z=R^V?uGg+Tw?TL$Up?IUADyZ6xObq02mDSaa4kHsHuM;~5oBvgtz%-fMqZp#%KSJ$ zZ&GFNP#huzv`?~9EbQ6~Zms`XKHg%RJLJ4}S}?Jugl#_{EQ`kJ56MM1LTyme-CdM!z31a#r8X)R-mC zesU5Rs(@P~)ba2^+7!u;GW9CPI=_nvS)$%KG^G(hsYJdVs|_HYfAK7-y1M#{lw=y< z{;jR8D=I55R9p3$9cd~U_`+@%9}`dJ-EA=k$wIK;oO*n?8$-x>-|JkfPx#sNUN+8?&ygL;b{ zvm&D^1b-| zde@7ke{W`AOqiOQ;ugGb@^y;0PUd|H3)a#$;wrsmF7~DBTj<`tYmdtwaA$$%>AAUK z>m12tHpmf2f-4RmWPUFcbyYsi&=LyO*x|T<-Le9H$z6T*29xy)EA7iMk8x9r1e#^X zg&0g9q8dlkv+^5Jt~0XMFwRIC87c7rpMa)%)_`fmxnPK-N1!Jf+nyS@>?HrmZoox8 zcgn+{!8YsoRUKj_Mk@++OIeQ8zw8Vb1VID&ko@}#NI02Vv4BX@&L8j z|8#O~OAiPk;vW!p-B8>>QYSdfWPzAl~ z-fw3yh~!~)#Y5*B>2||VYMrRoH9l6R)?d8Fzh2~mX^o+>6ikhD>PNkx#Mr7S5fKvf z+9Dlux~d1BrO;k=^~Y9hhk2QO{40!M@L=*L%q>XXtvR->f)GH|p0Fr(B_<{zGOJ*I zDTxEe;u%N$GW_niqQAy;Bq3s*+V{kB789q%V`OBJPPs9f_sCs^=+#r8nVSZb0OrP; zJ#kd+VfnSdkNGHfh$*AET03ZD!T|!kJnYY}tH>7-ie_-rGd8fu%1KLw`?rC@nppzub>wW3n$Y>Ii3+3w4sRMvE-FNc0tY5w+BUb(tj zo1e-wYu)bOlWo6CWW-v;zVuYn!?@$Vs-Xgs2{F#RmP=W&t%Amxz-{A*v6Wx~p-gAI zj9-T$#{@9HA^aV2Ne7HN_CuqddPG32xLmC^uZdOv+VkpW z=LuO4FWkrq%ZsY=W!luD=q&o`kQ<~$C#W8k2*@YREW*;H{+3(Ly4hi|wN0@YSXl=|nJbJg$5 zhL%Cp(1LfRMwlBqXh)uNj+i_`qUjQUVp;J;?ciZk0OzRx&(?s&o+i`&*(!0m*KG?QN-($w#|*5A zL+)zBJq|kK_M?C+2Bw#C{%Y(^mpB;0>URbWfW{0q{OZ3!YGCnMHG4qnm>x7KfJa!| z&if&b;j0OtTyhS2dh{(`Rr_pF`)P6kxN2Qs7nZ0e#mYt>J!cc2l~!UVu^k78T+9JN zF$#r}syF&S+lBOR^9L6+x<3vaO0NGc83IZuCQrMfb`mF+E!;yR1E%+z0!npEoiNqt-Fy8N<~= zhd({@tiK#2sV-sb{Klo1#)%Q;v z3uv!je#WRZ7=ru?+ZbH<5VRIt=?08oy6OEoDo8M3qd(-~+1;f4g)nHa)ihzK@xiBD z?S+R@qh(DnWoU`y8S|JrP-q=F!Gwt@?!Qm6&%54EVRW$!`;_LA`WpDB>ll1e-M)d# zDLXuZ|Bi1P@4MJ>(yy)_1+dV2B%NecoDpzKW7H7zu7cRCYTtf{bo#a3^NS{@B4(AC z4ntmO1JmyA#~-8dc9SXkKScUzvmLn=6&`5<60E-nd12oMEm_u+9+PO7fvVx}CqKuU zYk_COMJ7Z3FrsVMbL!u0#9EJU)`W#*;(yN!ntP^@@Zs{GPRGA;Fq)`Ms*9U~34C`b3 z+Hu8#Suw$_H}e*B4AZ+k{A%076@P4&V|a5@nuR_lPMwbjr#>7yrS-t=+1odD>H_SB zk9HGGAdp@9hUQLQV8JE2Olv%3%Vdu%el|nbiedQE8Z^kVRDJsllX*U~LR>;n8#cpk zwr=?IfJ@KGyWv4|VYxWU^`%3~bXsG1d3@^HubDB{WbY$%fEEEWcu1E6PIqr zMIWpkg3MG}gqmbR8cr!(I^A7pEZ1M*`ewaK&}YyJDH{4F=?bqjI$tXeRkxSZ0Q2gG+oy-5+Sf9)3^PMz=gFCXdv zlwV(8|Dti_4M)Jsma5HD*ORLV3nmK|e-=R-O&HOXs(c;CGv^b0*&K%Fmya5tx8_c1 zh|a3HAy&1j0V*UiI~&7SHG=a6AU`*J_pmLpXQVEyQAwlUwL<;WnsRWYbat(6xIKbiJ>Odhm;UD5v3N(6sw$~>@d)f@d}BL}@p zbj_S+gWULENN8xKb7UlWZEa0}e9M8C$Sy{CJ2HZ_Dv5@64*fR9AO|(r2D=kR<`F|Q z@#0FMfSw5k*QG$Lr0l z+auXo3*8&LW6`A@=3j&7iNks=frH6l7buz;hz-##0yy|ktV&6#%an(?f})~hP>^+U zigVB-#{n?El1DF$2d-UWa$8zhlnFJOfRf*tZm3Scm#i6%K6oDCz@Nn#SgsodF&4v3-h~keS`^>*?tw~_j z2?VtwZOSA=-(hS&JXLDq`I5;$QGpNB+fKRH1B{whW#*rPH3O|0jKoLC^>7J%t28cI zw4?(j-j_H~U9vDXo$K4-EeX`YK;GO=#qGkWOM;b){P#!HlLrv(eca?~A$qm^g_V_5 z67+CSJLV;PNI9ND7yY3w9J46@QG5lZ8wp4G=EH)f3A=qqB}!zhv!1a5ec#|nlJlf1 zW#J;vra^9Je~%pvid`CKZ*e$dz-H>xa9G-LulDxMN)(fnYT2 z0^HNJVZp_oQnfWAfvqh{`4mkRNdjLypBcDW#o1pQjMi&Wut2b5$qsJ<7p+Ofl(JB@ zPlc+{Fi)&depTZ&^hLM&flCHX|45KN)0P%i)!^o=4S3yDvIkNns$+e3 zl8_(M2G0V9h4Wx-0{Jd+_p7&tmZ%-S=;Fr--|=#Zy0e>WDOFh+RX)wg%qrAcP!OmS zjPE#t2%q@T=Cc;ObSwTp;;d+ZBIW$>@h`b%$wtUEWEWMG?2E)FgI zX?C7-1Payl#JH%aP9O+N2Fgy&D|^>|K`CPwDh5@LKlMFhE?V5J7_#K7bsOIK&6xky zgzp5IdNBbgtm0#h?&$6P(F4%8>M@oX2AoTV;K+Y8;>@R5R6<$~J146D!I^tb=Fx4NU&nteU+ z^e0B)IR;T_HOp$a%X;~pqEU&eLJU6k$hj^HKfd+APrZM>G(l_3U#0zV!Y7d@2YXr1hRjA>_kIAii`}E}XaI~i($+j_@BYbo zsRJ8VZ4iN)3*%Vz<9{{&{#^8KDBT{%5|8zNDt=BxhKl)8e!AP=yW)XdtlH2}?3#ay z_En*b=4_%%z!zQ0aD}!{y3G$(@DAF8Tf_#5lD?DI*{g|qMgBPV29$9jX?R=#q3)S6 zs7yhA9$8#DvaNETiFsI-{n2*Dt4fz@t3ez=jI6F-GH_&$cO}wc`l>U2zIOZBL9Y8Z zwLg5hPwt&733WVTO}ZRBt?rc9>>rla$Kj&8WR(?*2X8&%0USWP7teeyO5t{_ak>D(pYB zR)=n!ABKqhJz7RhOEj;>C*dcS3+q@Dw1H|RT8Di~_KUptXX*o)Yo7f#{=REvt*y&h z1oH4!pq+82>Q`RB+N$Y%HFzdE{E_96b<4f>hE9qMD0d2bj8pj!Cg7kPh{rW8e^kj{ zecPJx#V$pNg}h~+`9n4HWKQMnNr%Xi$_|4gff?6uw(>mA$)zeqW;EicW80qfuacC3 zcOzAcQ;nj&Q&S#_KJI$xiN?jWzIQWud3l>hRqN^n`Ttdoet1mwk=O|CXM) zFyYUr02Pkp0oYNGD`n;g*e|I+X2M$-sGe5A(2QSl8apGVjJw4Z8~$+-I52LX>*I?bP%lRo z{A_@4Z0gq~DdCebPO+Hqp=9%QYy#nu$N7|Zjt?fV@bxWJ`4=T;Sv$MRAmS_O3Y6nl zK1V5>{u6%fcrZg7F(jgdD(VwP?&rF8q+b)ms>j|o{yTi9Af$6|xpvA|L{Jv4*)N-_ju(fVBW^N7S4-_DaOSvxF@ zXO8B0d|tI>GCpD2mWuxzhKy}y%u)~6gsLwvndX}`Jo|pIq#od9{hIa1wi23RTw{NS z-!nlKz2kXSI{T~XI?U4C4D)9>ED5%Rl2lak=RSnWeG$|)hCGXvl~%Oat|pXdxb<9iy%Rw4 z=JS{Q^xJE6R>dfQGAdbg=j!dLI6kjB%C+bztR8O55e}ye0laLJVBe8!nmjyOPmsop ztPAO#wjb=*9V};noQs*}onagz7E*SfAeX?@n5J)`_7QfamMfDtYW3Z#)#Y*aK+21E zFNZ{^X~*HxNbaoaonNf#Z;D4#%KDJS5=A8_f85m8SGl$>Jl6bAsd!B6B~Kbc-L)sV zR2+s$B$kh04q&OCk^vNCuu!Qh+$Cem*smvfiV>;mYJ-?YYS>sgcccu*l^H`*ty6xR za}uPHB~u!xMR&`IEeK@6@yM#BsSffY7=`F9`$po2lFVO1YVHFWtak+sX+kXf>@hss z*D?byHTkQ&K#$;V@n4%kvU}{5D58N<93cdZu)Wo{pDXX~1f12QSkV+JLXY5H|ES;b zEX<~rKJD=1q0T=C7|UxV@lyWx0uSI;87Sj~;gONLMHCHF;qojk!k{ukZ;d=iM$$$} z2zDU=rTXJw86(yRNw>YKz^m*#o7H-BW|5?qFp*mV@<0(mz^pPbVg>MoD%6{A{xvX| z3T4_n83B&)X)img%HMNslFW>>sg+j}>c8lfNxKqqBPZ2nh7kkhhs(8(-p20EGA9(J zh~dCu<1MuA!?BYbOI`MZ5Ab@^E=?(}ANaVw6mg^Fm0XaS5+gkqRpZu5JnYx*Wm|H| zV}sCTHC-}lS%Xr>R#>`Ym6XA73p--ylNRAwtGe$*^*REOY-Jbe3@~@U^XH z&TbQTB<}xd@5{rX{NJ{xlu}8dWQme3dkAGOWJpvZdu1KW*vYO`QX%`6rI2Kq3}!G4 zZDbEw$Jj-fkv*p2{oM3jf8XExKF9ONd%Vx{ymK6N)ExKB-0SDMuJbz2^Af{X&rtau zmu<`t=Ey4S1*3YJqu)F8LZ6|Lp13+xigUUHr-FcaI<@Hl`^SSz_e{h1Z_>N9i{S`F zKRaXP+<}4iY11xm$D%y4qC{)A++0W7mdf#FF92zNX&jqk7&;y+GR3INlALEGSaXTw zhOb{=IypNx&d*~CTJA&2CwQ;2-02%%hFSH%J{;qEche&!`=0FXkmpaVCS9d;Rb}bwe2mI!%=|D@&~@dX!%U5O>tlKidbBTk^#cQGNDJRz zeMb464yDQdqnv|JO$r1+`QTeMpx*o9j61_#YHInXS-xcwJb&R;YAq7d-MP%Sq$&uu zDlR+$qB9W@5g=&f1%;+`tKx}?mek^Ao!N{0qM*m&g%5bWy*9J|Fm5)c$6KSI16PTj zk!LN{g$`oK9olOiS{qL|Puc2)pv4Q&Vf5MV9R?p(S09nbYU~wx#M?_EDMb%;vt3XB zKuGaUC6K?z9nJB<0n8Q#i#Eu+_RZt$Jg`HzP~KQ=1;gp097-Kh#O_HaywL~DDNAfq zcT2kzU_ATc`s15Tx}9Xfq8jk?w6a&K&l=p}#K}9QQzqELS#Qd-nc3OK_4W001AATw1Cio+)9bRo6W{F$ zciji)rNB^!Bm6-Lk?i`p&t67dz1AjN^E}9!%L0x(fRs1PbYw5nsin2&fgWdY7V23R zXubRsxvhw){w4cCxK(=~AS^umRK{aoiz~E13xd-;x*oHf>THZ>j8`~}W3o)i@~j{_ z*9}p2c`NwaP>Q@(yGA)f<2sG{WV6L2&a_;{>2{q`J>&VCTo7q&VS()|XI)BSfIZFt zs`T_23wV;wCIRD_pWq~9S$z9wxy3#`GJ16il&|^T5dW^AKhmW zGH4%bjPvx(yI_)Xj@$zv*!HdFysA(wH52-K2Ro_nun->EQne#;=^HEe4)ZfsHo zL3OHe8WfC!M|i%R13!APoLXBbI4kc_U9p5krV%i;(TmEnP_r#`r`oai!#`spm%Pge z`T4#u`91H4_3z#&x&nKAy6=Q-$oVQ0rCAB)Du;pTr7WO`vNX)=)UM=BGc=<2!RkF@ z-wiJErY1V1-I*xbPy6gpx}TrfHk;uf$OSil#lFmI4oyTn!I7rhKU;DeDk($X5087G9|px&-tIcN~b* zfiu2*Rz!2G#9-pfUIEi|0fcdCTn7qQMcoDqE*9Ut9W1l+wVckMz(}GKRTizX+k)={ zX~{SRKN~MMaQi$U7`)>Xg`V|nz2j^&QcrW6k+Cr6?x|~YSvO44W{xhe`mq(4{^SV0=<&~{i|y5cKNiNGs%H7_n&1r1y!K(@<&&4%M#6`Dfaj|qBqIk`d-fv( z?79pH1OQA1J;eq{C4PSm`xHDlpO|g4M0*TxtMq}x-UY0 zK{&?VR>hNV8R*BVdysAlA{^r<*-KM(wM>9f4-?X$7rtbh&N4KS^Yd&)y*~X8~ z-VTMFMKRUY612b||Lo{cx9vhHKr|0n$lwTo93FIO=CQac-GR9X?@xOrDvueVE#l(h z4&kqVgQ9h;*1@YOk!#YBqPUidOA5hq2 zwmp5!Cect}iW>tG_4e77Y$6$)GkxJWZ4D4wf%yAO(0b)Fl^}}&{{>w{sR>ZwziZBi znhg*q;XU=0igX9_VZc4DO6eXWZcHU)tzl!BhREmbuSM10S8P?DPZFq)T6tbxS5zf$ zv7Fdvm2^$wWjJ~uE=MKKYrkM>F~P>)rbB4NUAq2;#~v?RWHSUWrG6`JD(0Lb~ebLySqjSh$_1CDy@<^Vmai^U=@+UTMK9#!&R>Xz0` z_le=+Sp2pS*WUGf^x^0aeaSd1SA$L~%Sx{arKst3x9pmGhGl)4hxm^`Tc;plGM87~ zI42ta1np#^;g7Nf@~%-+HLy|^&qp^lK5nf&l zuyYh&QL;XR^z$^$@j*M4<6EO^8C8_lL5tn&E4L0iKPGz0bC75g9T9>qAh#lkC>*#x z4YjooaC%ht;k1HqZ0L+3STJ$VKw8twb& zDoXb9n%>+Y`2Cii>(D1+}z|2nBwk5WC$NU}|N11DN|gWUnmr^<1k zm7VS7b?q%_MN8U|#qtaf6=mMupkDR8IK5QiEsF3Ec<9%%YP(|_ECV7%?K!w|c77n8 zR;Kt}M6aH%`bSCSbWTv74E(XsquOntYssmn(mkZ3c_-P=rkC*zogGON+|HO0 zM;}0mvmU%=vof%eCDJOjr$r`XW#)u_c=vuZ9w#df{hTcz5ma^r5(^JQA z5a0UrVq~0OleNeGZ?5(@B8H&6x-dpD@7qb#G-Dw(t_>K&b{c~H&ZSr`CGG*V+ zm4M6O){}$B$O`C$=p0R1pQg_Ps}D$VKU7F6>25EpYZMTh$}|=xxEoQwr{ZK0v9Zq@ zP9TnUd|o2%;DEv4zzO4ET@iqf@2^^M!(N`|+MjKh*L>&zSLjssOU0G?3)a;73**!2 zw>@|f2MruCL1dfqwI(}0vu2)SJf|6ZWPV)bxEJRBSpCHCnQcC++qF+^OXnP$_8XKc z-hFpSKU%;U^NzlBx$BT0s?QVY(CSFpUcws((HCn#?+P5lDs25vO;$d(2 zP_GdlxD6&5eqZbQ4z*+5h2}9p<^h5^=#^i(5AtR<35!_A?!vgh2lw^fl!!_M&Ru05 zD7MYJ6zivPoleqQ^FF;FhZ7LQ|LSjfg8o)r8v0W6p0VO+E!o2VCmV6uh68|*kKp>?tPC(FJ1p@ z7ijxkCRidpAhOC=*={`kkqFS;w65D5w3S8|c}0&PF_>sF2u>gt2mS~Jqi=2x?*syi zLhFz4S3BOGQ?_RT>FqdHKgirL@0!n2r%`sNLp^?wh5|7JK<7@}~0~?NI{-oZ0@L1;7^^CW2MNdT|F0oa6>5z|ZVtJ!{A-#++G@%_80 z6)IpQ0m*#1%kW*OAOvGL`GHYTGzy1*YRRyB$b(~l=%^iBR7|YC+d(8$Qf$0rG0 zzg=J3l?$qIO>wCDX*BQ#fa15qaBIFi1;p=Xe4zFRpZ9oojuDtNfsp&H3#M-f%Wpo04mNj_YVvZ$0YGcG4HI9qCNTd2QD+Z0V%6ho&gyQn8#Ftc1;HRSjtz1q zb9E<1_fmlnuNnZ<^h+B0fXm(C?Xbf};HrQJytlVE%A~+HFH*fSNVkQwbjhc6V<8>1 z_*PUlT+5dlEVV$ssvCLj3h(n?r@j|S8khODKmY@p=H*y?73zW^b+l*T1y|kmoZhcDA?ePi>@H#La zx+x&qXdqx;HKIicF8|UiNfBwQ2JVAP5-5gkuqGQ9cOy!`kAt~8u6;AB7B)&hvub@m zug(5qrT+_|Kzjoy)-$%X;(K4YbXH zl`+3`8b8CVIj;GV8K9)^0>jvK@FZnct#S#@pAJ+nJQ+Fa7E+Z3yx{>Q1Z#f|NYj0* z(nM}7wjr_blKF6g8dbK#P$yEq$@USSLnn4TvxPLz_UK6YbiG zBa*fKJW9{xhRds=>HSbJO1r7-OaW&+DSrya2Y#{i{s)x2Kep73{LCmipVK#LJI6nSd?Z& zUO(kJ=~P8P@7RNZue@miw!K!Fb%Gp9Lej0SMN|{J)+{)2Isa6;AtCD^3}&MWZUD*B z+Y-@!LGyOw5#EYIA%R9H#SKs6@(pF+eqo!E_DXVJolyrV@4J`RJ;rCqW50xD+J&Jk z71FHzD;i)y3XO(!v>g7N6%wJl;mM+0&?d%4sd#xaGMt;o`x(4W!%nA+dWq!#mMN>_ zL#!X+DG;{D?gS5FjR6pB8W@Rxs#00UX*@XJ8zdI({c|Zuh;xIyp%X7Yz#kG=C+;?~ z_^8~X+=%1HBOh2+YLsMn{Dk4bQ)*bocQNrv8V7dd!h>bJy6#kYeiSg8sgRYG6^L(r zuOxf6#W=FjIEDT44q8&;xIdutyn+^miyF>5a|_L4jW&L62oBP^H?&Y>WeM;8YJMQC zW(jKqWp=v@iX~Cw$OBM+90#{rl3FSK66$FXs}u7Lj%0OLXLDCO8T(u3ah_dE*6_39 zUbIK19JZrrB3_nsFqdd3xpwO?RipI()N#wB(fJGy23>hj3Npvejbps$jSH%E9?&?w zidZHF($Pi~^Rw^Oa_WdlJA4o>>8A_UvqH{$`vp)>0O~dMSj6aghV65UaZCHc5Y|W8 zjz$s%90ASwmTU!+xz92(O%@Q#!CD_|1}R^4cvsec494HycscX)ZCy4-RBFZ}ik;2eyA^Z( z*Ir%U;{We}i5C8@0B{$Ye0D+N(HJdq!`;}#JVvcrWVjszJZ{jpnMMf@9~!)SUHs+F zu~!Z5>Hg}k6C&g!;Xncgs|OOWfSoUiwZKaTYe8)kZoHZU_(}7NC(>vmj?Ue7Ta24q zK#v$PI^sB*S4xXWf9;99Ebqvt)_3P#{+axMK z|Erg!1Mu=Yv2~#YMc14)F?~JJ)S!`|*l~r~gSij)ttlNmn0xP9u9ilHGeKD5XI;=q zoL7))`}Ufs&FjmCy9XXuPLCDq(jxxZRebeH9k#Bl!QPnl^|XC!=Io1jW^WX{x>&Gt z!Mgz;w8o=zWCs4T>ok!O9MaP;kZm2q{fKjP+tB+N$?Uyi^Le&!swiZKrryB9N?L68 zg7>pEI}`QG)=*X=DF|XMi0!XX3}J%~aN6@~iOnZ=-PF0y0sR{%bGdlK@SQuOX~0-C zGk_*K4mXSb=B$@9CHLq>KiN|O)5lY{{IZB>J;*kkg_|qOK1xNbXrwJ;b+1_3yc0VP zGQq7h;uG^>xf8uVO{&r6$goWF zzIi9{H-hnPVDZRY=Q?%PgA0V>BM(?S5simFqOSh#Omn}03VvMP=BOWO(3ML;=ja&BdrBs>M3{=+#1D98xfTy;gDu@e>yYDV2kr=e^zkT>AMb%^ED-vOTgMuSDB z=Hi~~#gnp*L%IFrH&#t}iGCXr1`_A@7jzRml&}TP7ZL5)QwW8ASKWnyh-PGWi)&?0 z)Jo6v@^m?=C9yOHSB1AkZvQ~yp%C8GNh3D!0bCymbU<7r_*0M%cH^?axu~jyYT(RL zZ^#cQ`sK@{4ZgVS7@B9MTI@rhen}}qJ}03b%NxynbiY;(dL|+GEZLDAw>X^oRP_-D z>_gNV8O0wDMWEa4wIIEZRL8PLJBC+E+|Vg~Kd8l7_$(vB)6mB<31V`v zF3(n$XE|*dS3|sQLQJYoYdrf9f*~Ssx^{VEH)EtJ)T~oBWHyrK+~VL7CBNh3+vRod zmG=A83ZyOEGORdCS-$w*`&kEHX}7h8pUm{lfB=##dok5?uysv(CoGr=%J7wkG5!AE zQrZI+PUoiK?H!rG-$JR5M&sifvmJu-jK`(+JX#b+``z!Se~-HIUia+Sp}HcoayN}z zt?v(ttxQ!>2>?~TQF)Y-XkC(8W#N3wv>+?s=E`G%?ek_warNwSuCaC(!C)3K!Gm$9 z_a_uyz`-|Cy`4JRX~U>SQTX1Z;cZETW#9bhK*N67<=Yhj<<$Js?^}TZE7T-@YNT%- z56Kxwt;zx&T$gTX| z6octrlV)(p!&Z36$fpVDd)(jjbO32l6ni3~W}3d{f*PH>_iIAHEO8(!V0iD@%#+SH z-_+l!w9! zx!CBU)^C{7hm4&Z2vHN23wk5g`FMP{q0F006&3l?Tr&2>M!gH|HF6@~Q{?1R<5S-b zqnsT*IPaocD0>+%lGgH(*C>R!X5R1NC-th~PC@w@!kG>7^(2R;J)`^UZ8KWMk068o^P}3Be>8R;0EaPC|+ai#pdXvF*dk1 z?Wxw(%NfWS*Fq?J8evZv>nHGL6$o-E<$R=wC{4`x#C;jywj2y>d{2?~_I_bs12ce`PGgr|RN~v=Ppnc;Zr@Z-TQDVN-cSkR36;5Uoh-E$Uf8m5U&$ z5$F1RF;gGh{bTxc8n6QJsaA4Mk_-20e9GSpR~TW}Z$Md6?3sv7OChN@*}H_VotXpf zz{PhU)WV{lc{?l-z7#QbZ$~{;dpA9XaF7Nr;=acak5*^Hklxk#h2rjnvGSnxm2BUz ztewG`b^9QEDG{mJ*Kr~%Tg>1o5LM~f@Y4Yx~gN)dZzyh$g?QnMmDqek~)ZRmvKP;Su zjjt>tCKH{Ct(*l47o|INGi0IRkrsN}+;%t&^*q>d3PsF(eaof^* zffpLIRdRRiyhI!)whmNX#bai@sWt?%WKSQFmj4Vs^95Y8d#@o1@EuS#zTOC?g zyhsJV6%3p=VHpQ(Qp}%k+9_RNpZh*!$JDO4+s4 zlzIE7EV7jt*J-B55)oFjtCGz{X;?sIn1S*~A$9N^rmFlX+cz45Rt|TL7d(QH zO=)-H_OEgPkx-hRxAo#a&Jstz)NeP4WhLfa`S-%Z8BJvXPNWUm(Q)}Mr#ZsU6Q@z8 z==-+BoVX&SJ5f*y8*17h_2Tlvy``aWJ>&={Or0(0t` zU4fZR{*HrZVxLZW;oG^JJ+vH7T#|elMz70p{pOKNKT|&FDvmv;eJg|5-s}Q^+fk0S zRIepYi=RkiXG107nLOg_Abm-|{f{~Id)QM|&Sutm2Wq`5S8E5+>j88&C0)@c-j_+l zxxmvl-bcc1Y)G!#Bqr1;tcOk+D)PI+Sg2?a!7{h zKDfaPEb7M7wY?d|r=TuTIXz6311g_$4J1yFm+L9>LdL0<8y_-R;E%x_O>>lJ?6gxp zG3?;>Ik10m3QfP*a0$_E)OTn^6wa{SJRx;67+*YZXHZ5=l3`Il`f*t-lZzLElYEbs2NOAx>;PGn9lFv48Uigj7W!h+lPygvQS z3@>a{?PC1S{hQHpWJ-&&iydp3%;)Z!pe|Eh8P!(p1NLtW4QgIad-7D|PJ8o6C0oan ztEzV71GBztxVoBwo{7Mt7jx%jJ@*;IxkRy9?#IK3gpUR1VZp4MH{EW~YWgS#5pJyQ)bsjQ?#I#s$KkavYXM9#0 z(_@wsluvXjG_u_0?fd=GhhlZ#V3^+3y^@3xIM_kk*?q z7^Npx$2=bMK!= zsXUS<`$Tmr=PAS6>Ii=#p1S#{L;{W7FCc+WbcE)JDZvOk&Qcl5SLilUJy1X+Yg8>^ zRQ=OAJ81eEgVE!?%8!5zE^rkz1&#yZnwf8c;lCIaec})r0iulSR~Sg9tl{)$7h$iW|y|9q5&8Ucx%X4|v!2`6=_|HSgjZsJ3O32#0FqWX`P`Iiq5;Mh-6cdyO3C z@e|I#=88SfvW+5j^GF1-$FHeT=05pknQq{U4pwQ9MjWl`5e+I_!D&;JbiX=!6aCeKGyuQT!Q zTh0QkC))HkbWFxu3{)X=>RsrDnMf6~dgILz3es%;$PWx%(@VZnvEI7JCaaYJrb4{X zCpD53?@XO*c5-R#M;3HXhuKipUv*Ej)Q4u#_<2V$+1dQF%flXx?i9K$@&+>_l{asN zpaXCu0q@GuZL2zf!46qhIVr8jf`I`_{NYSArEg^OgsD}9aoWa^WnW?5TcGw~uzIJCE+l08v>X#DP_4ZB%6}nfgD0y3BRo9sgP_&VHp(f_y#l6ZTwiDt zdWynw7C)qO%`0`5E!GJJ`{z09w9$*xapu`?afzYsEz;&Bf%CB`9&hTSvTQy`*Opjo zMQ0HvfZX?kGO?#e>zU8pVq}*)4-5wVwgCu~i`~RzsaN?8-W!oY!fMy!s2eFk$HLQp z`nk=Kc%DwBvW@4B(NSgGmbGesy?|fUR-_Bbylo=_I!|K z;16e7>->7;x{h(s5V{fkP|)g(bHjkn;L{AO1DlFl)WT9SfygHFse34}D|gCgw%Oax zpU)MoJ>9hPXlA4?Um4L6m-7nPs{#Du;N5vlUE{a{uDx#}ccuRKJ8RG7s-9S!g`Wjs z)vx*(dVQ5`+;&my8_D0?Vy$B^VU|XXtS`tLjGg*8%5=r#>ndyXch4srE}P^Af%Nyo zDW`{j1MlDZn?%1q8f2odIf$qaITzO(=%M6`4@agO#AC&TF163KFPv-DQ{pxz7f+cl zq)|a~QUE-@WlQeEf0JbvI{0pgJQAWio`{j{QbX{ljg71Q=)!;A6(ZhcNwHwf1U;IO_AD5 zS2|=BPQkZbDK_pu0tjh<-1nzwe7;W#TcB-9FWAUktXL=PnB+6fKU&!}9xx8KLC~7> z{uG#jB7`0$DhW;Vu^nkCe5inPS_%WUOn^kcVnc`Z*{uH%-{Vj3M<&?Kz=qf0FO)gJAP&sh+5@ZTH z&Z5!wp|SmMPP+;8eh`K=gJ^tc=SLFh^TD3TZ2|ghybYWj-O%#d-h=z0dlTR256B)d z;4tzkx|=C(`b?_f*DhCa7;Jvic_G=^>!T#4F_PAI6|>ay_IGC(A&quu1V_j+nAcIb z=5S-2(61`&R>+JmJ{o;j3~7g!HHEs}LQxSaCx>q#{JilCPNAlDD^d9T^+A$1s)`s% z3?;Me3JXC*Izxub)UvvP3wC;Cb&3&Iz?!He_QL`b47OE&5PAz))K*Z==oLN=HEWKGWs|#9+S|}fSQ+|I*N1-DYZa)j6`-Rph(Pb{o1c)h6 z7GGl!ZEI8}tR}Qc6*H6X?LFjs-^eog*c&5Hvd!mtSKHM%+adxjN zf>*Waz3>D>g_D$eIeb?N7u-Zs(dyz}jyQakPhZ}j%}$N$567DJoq4@D0W1~jf$0*M zzy`YtrJ|pZWz{0HKRNY2xg5~p&yTPy#55HqJ`mXcl7V9GyRlwdt7(fl9|J>OIaV(U zoFdD^l6{u%$Caw+Tllm(0%Nw^Ol3RJ!vu4BV5+F$`!D@B25DBS#e=kmPAaRfpg;aJ zmdJ>h!#2;%kAFQLOE5jUIOQtid+9@d@wUZ1?tSjSJv3Nrq~+6Re%?CahJN{|o}*wIxs-`i(rxCq@AdipoetL1qORcH}?0X%hA zujKA%$NT6KXy`!rYi9+npU>`P)eO+vq3~ZPr!SFYm#YBI+h=KLY-m0(mzTfn^$fTa zUFgC9dB{9H$?X10G4(U$#9(=pH~VR16{b!RA?oF0sUX&RRrW7U=0<>ky{Q2=JLoZA z`3J|)P5DzCq$W$Mx}}HNUiT-&)Ko(_+aFkVUfP_z;E9MN2*{o^J~h3d3RddP0AR?_ zxH7YctLp3I%_oc#rg|O%_f6|&02n6;slFxSXbyp+=QgWT{;lft&u@iWL#C0Bw%iNlz)>$?MQq47ZtfFu!CiK5SwLo3rwLUZ|^@NGACPVO% zpFDFCfP~4-A!wuU(c2@B3h8y>M&TzW_PkLbzNJTK6K%{-4?r#2t@1Oy#C6&a&lBB; z4-g>dWsRE_#4q|*HPMcl?G z?+Tnl_;l-S7$Tw%N4b|)8s@>PED|8w(Tn_}uU&x|Jyx3dwp;UAFwO!U**%=O&BP?* zrBN=D2hn)ls~_~w^Ex@Ifdw;*S~*gp#Y^){;Tz)kQfW!a7%9GTK3@TOI8=U#a;l+k z*TNI_UHw+9n{0hB@QM$pOriLtdUM3$!UI=J;o)e-jZmJLhK35HTfU5HcLMzj?U?O< zHH-p)E1i`kY|}8RB<}|ZnZ1hrt|AJ`a-Um^Q#s7mrpWU?b-6O9cp1WyN<2lpRm!Pd zQ>#bvHJCpufJ$S8{CZ@szFW3RON6>l4Ny0eW>8L3FnXerDF3BW+TJrB3meypn{ z!X<_S)qWfe#yA4q2A~Xl?Yy<3T}@REZ;|}e;dKzuR-JF1M5?UW>*rJ9fFgDcP{f2O zYc7g1cZPK|0W%At3rNQOA4vD9;ysGmltV$@5AM$zhG=GdKf$r%6($9(nl3Cb@zmjrR+TqKV+-xa&XCJlqopOi?W`v| zgN}|~4oh{`uP;XXFI_n4NV<81`>dDiJDh$Gp)WHOop#zwrObcA)P%~1VrGB^BerhL z>n8D=Jr&RcqD5HbvgV~;(edk~`BU2t{F{P#a3JMCLcX2O(;UW}VnY&u*8!gwLl~gaX=MH>h zvbc0tLiO+hne$d3;>}lV(Jbyyc)W|-&!oZ+NUW-6ddpS~c@2dnoB;gp&5<|mP^Fr< zceBgMwex>ajry{yn%kxtrS1i(Zja&q9c_97Y*xSJhUA=AD|{si*v_qX&C>1~%-Z)k zz=SUTb(ROzT5bZ6%tfT+WTWJzz-#YbLu3Tz{QO=GC~q-?vY@35=3dWKy%B@1 z1K@4L$~Pa6*Ua}ez0Tg=FO~+q#oHFUK>E|R`I)O&(1T?4vDA39Y3%!j_7$np+=C=4 zHV%2DESr6DNWX@To?3|C20I3&OB%u*GmnHG0fjL5$Sy5cF5(M=%PoAN*hXnD(g3ic z<62$5b?QeTeS6FO{AHik3%FG0)qJU62&@u_oqDXb_*EHjJ+&@7Wm$f@H2CMtxpTvhfSX<_cl4=2p@jmeoOTk3v!%3h?- zdf{_{<9gZV!CcNYu%2L27JvU^C{J%RB{bwkOuLh8cCX?O-%hBQoOJjc>(P0g?(~+B z4O7VB?Bvw*LjCM|*1gAi?NSKPb)1%&1)&kAI7_H$1Ct}eChqE`Eu(;v9eXxP;7h+d zK(ce!fH8p>bUOZR^AUI_j-xvrKpfA8hBG?A%U!_J}*l z7TMT+_q8*?H}OWi z*EqDi(D_1Pa1~UJK(+?LpeWF;37nZX)9~(|h-f1>f{-W6Ha8I@6cmG!c}w-GIwsW*n=k6<|+c9ldEaeu@e~DSmykap5oc4 zlHIRQ_f{`s%mThjGZ%hkdK#H*G2VSc2P!c`K#BP(db_;bw;M4h-~gX^VjKo0Xz%Ao zVB#+?zb=C~(HDPlqU*lBn0Pg7cT&Q<@bsD{(0H{&kITgZFq8Cqg`_dJs90m^YykW& z{_u1+#B-uwj{l3GEaqZLzDqeg8G&H_Smmh^BQnA#>tSkV&U83*U{7@H^~PI4;)`a< z%a!!tetEpa#t+LV`I{9Y=0b~+^BT(hGy8sy*xoJ5^P!$`xIme-lt`L6pQWh z^EV?boGhqnc#Z2H1CGa=W|l(gf6;vzG%BW_W9B}a`_>C&W+nx)ZJ`qS-i=NHGpkcy z@>P|^>W3p#3d{j3sCESNciornF(j9~FTCzTu!w*Tc(3)#rdC#VRLB?2^Gd#{Bg#5`r~A;KDwId7l+iMjl`Q6VtyOQa2T zsdNQ-^@@T~yYkz5t+UFgRP@DOtHf)wqY7;P(`ncKydcH|e3pP^TnA4eAlp#xeWZ(2 z5+hXsE8Ibvjj`~tA6scbaK~fQbD*u5`-j-7)-nMkCOdhnOy#se&;tvk=q9qC^f%QL z1P|0S{l#Vrz>HATlw<>pXJE{{2YUR$>$j-||GCZ{_=10#fAIg_H(e|UQfde!J)F4( z9Wd%2cxqBPRkrYeO;%IiKbS9r zAKD6C!a!B&H+rqt@1`kacLqEhU~bT=AY{P5d$R+7cdwnDmj>%x<$l$26{ep~;5tF{ zxqmJU>(V-bQIQSAhT%^&YM}YJY%sxUM7JX0ODGb8N!Ig(NBc7%QcjfYH4MjvO zm5{f=?AV~f<~U#*LW%{OBRu{~2>)Wmw_qeitnI?k^tDki9pTggAKP0!8Ro=akZ8hb zk(-buFn{};AitRzm~H%dxq=89d~V2Ud=*8CvaXM9GVj8E{5F!N0tP)B^1Let=^3P4 zR6P!Ar~zs*Pr|Oi@smD7Z0Ygdv_<_TK`Bu@fT^7fL&mUjT38)Br47~WUgSd;_sG7bl3!JY6 z{Xj-LLp@;iqx-toTC=O*GHCFGLs_eXntq)2?eCb^6XKf^CtwZ%Mi>#NtPVXG2J@vD zCy~Kpe`^!Eevki<8a71G%QV6i_c{D4k7mLJjFOV?2Ef#RsDjho-xrx;LF){*=sihZ z)5f2B#(z?6NZ_cG+c5=u$*@r&`hbQ;~j=!58?!jEf9FSd2$s{w+^Z_1sw1bTZ^P5cJ|R-jl1 zgqklOg0bPv{|QD7sNonFPk&Eeir>xnxtMteM}GEBr?ZAt&FYQ*v?*UwD9S-$<#;CC zwikGQyb$70vA$aOH15OOTRLaiqRYsp{bzT;v^F2rhk*REIk&6QuGuhEsA}n)5pMr z+X-WZ8V%2+>Qdj_9xBSo#(M*>6<;l?<4(^FlN19PoQp5y#BoDB?%4HDnmiM&gNuCnOwf`doJxUheu+e>?68PFI58|>u;sO(P4)VltG+HH-n zxz;tX!s0f&YhB@6|Ltqbg@KlZfvbbs8(n$Kg@@VvS)m!Cf2dHl#r#sCl$dkXjbieb znlMeSjd&U`4wyJju7oPJ^f93bC9tT=S3&fwr@{l(0uvP9oXU;N4YTB+rGxDIZsn3( zas3NJq2uO36X{yC;q;hw&h?~yHlH_r?k}_IR*H)0IF4#NX5O&?2Vj^N*LR6d!Fy&w zeAE9R>!dC_Q-O8q6jQwLJr*E)xMS_f&2 zx%YIKX*rGa{es+avp=VU_}Vs>oX6f(%|@55_-h%aFlki=HH%wtfH32KS}wv0fg`f0 zdFFK{-|mH(5^+SNGiL(Uy?eO0sOaWn=5IeheRS`peV)cM@@Ms6XLfJX{_&C~R30@5 zgc&Bh3gE<nxU!GY3@fDgorTSuc{daL`;l{^eW+mXn zF8OOlEpwDe*Ju3lPNmNd#F6?^+GF$~Ia%{lkdE z|FMt!gknc$4D%i^PI3DDprF`^mLH@dz4zTKm4JfUV+Xp&VbXdo*k*{@vk7Y$1B3i; zXxwQVedD;rDhJq-^JZ?X=hUq)rjW?r4lVf^X@lXp~sFCJzhwfHP^w!~LL z=M}OfxPcmONbav#(_NKFr|E|IIoAj9tWoFR2TcdXuLLbxHmuPFnLlvVTW_=ry1Hz! z_FzZpHT;jL$IsB+izGsZ8i9VL_|mmjKWBo%=!wXZB9Rm=mxLnX)i28xv=YtM-D*C) zqvP#vMkZ9nCFPDyRtuE$WE|*xtP4haOpK=h8?5=M^q|Wq&B5q_=I-%q6wu0p$ZZ?e};=-%z{cPh*YvnO+M5_!)Y3aU-5ZMlI3q64P|4=@-3w>AK4;G9Espe77Ke-&c zV!S7ddBEqEw1~gITAXQ)T8incsb-^7)pEi$S>4q6(jrVeupGjR!EH<^$uA>IkhN`E zXDzl$#<*)}|A2|y#(&^UK*6@*nFm;fBUpZ4CZQPd|EZ>1r$F^MP)$QrQ<&{$zJUXg zu(VSFZUWxPkc5&{Y{)X)4 z_UvH$m7pI+HuA?zA*ga>bMuRKMrQVvMi1UUFHn|#A%xMWc_*?~DPExhtNCUGKy?Lt z(9P{NC%^noz5;ZN-l=m-gHOgnHKu#U@SN;C~ndD5$L$%EaiUQ`RwZOcjjuC<~A!FQHgc2T&5=vbi}Om zOf?mW(-v(l|2)2$y-p5l_ZQoz0D{LWv(|4VQn(2BZLp`1f~4k)f3XN?iv`YfrvX#9 z{T57$%O#Z?6B`;QqYp!+TuGg)qHCuSoyf{K{go*9xSmw-%tFz|dQ zS<)G5|L@r~bSpo;MnMOzOetDv>t&&wiX83nBM78|V~3y_*wuyR!l#$p&soO35tdL~ z$l4*|$b!6dm%ba4Wgr!&RYN4}%SQUiUfJX(ukWP?1z&+f&s~{vJTS5Mt3h$^vmD-4FB`_BrNpfVD9y(oD$cXZ-0wLP+oL&(a23 zn5898qV-*p1<6+K)kWfd>XU6%NDakC;T4B~Dhrj^dqrwuha;8HK~*%*^bmdY31md!Q$;LiQ8xjvp9sxYZ||`*6sH2cn^titFy+3n$t9eM0e@ zZMiA0-rh?5TG?f#du0zyKWnTS5bz}rBfReGpeG%^qj_7;@8&#{&Jx9U@_EKIruf)m z0B8k189eI80p=pzy$Dr~v^Ssw80C?8!SELSc)UkM#UdB7)C3GiK4i)W?jHybapR=S zHYjY=vPf}#fMR|^o@lYi%jZUsIe%x`)Ld}hS-*$*@yI_-4hD*FNcD6K_aB`Jd_87I zaSQ!tktXA?2M9ZrtZ-5tX`saQM;Z0SX2Y> zXW%o-eW555O8y>i%gMDxSyp^L5>0KvUNs(7cAQyXIBKc%?}q)tV6Xn6%X5bHHqZTE zS`FbiRbM%DJ#M2@0=|R{4M~r=fu_5_Q}oO!J&wob1KpPz7h-k)ZJ0B7#|wmn)btIz z`7X!Hxu{)l+W_eSn!-(R=(H#jG`<5IT7Pc?7VyShQO0k-kOTZR*VcST#6*(w6PJ9B zfrWf?8PEHDYVNaeXlm}+n0EzMUZA#2+_Ww62bNR=oK1!DnaM43X+0nAq4$CImjrY@ z%E5CFIZ8DZg6~p&4&7T{!L;#l+i8VAzoofZuWCRQE%f?Z)dt@A6T@|NgYJRq@=G!C RPh!xvaE(jqh39VE{a=(+Q)2)C literal 0 HcmV?d00001 diff --git a/YAML Examples/IPEM SIX/ipem-six-c5-single-phase-six-channel.yaml b/YAML Examples/IPEM SIX/ipem-six-c5-single-phase-six-channel.yaml new file mode 100644 index 0000000..22b2b51 --- /dev/null +++ b/YAML Examples/IPEM SIX/ipem-six-c5-single-phase-six-channel.yaml @@ -0,0 +1,1146 @@ +# Dave Williams, DitroniX 2019-2026 (ditronix.net) +# IPEM SIX - ESP32-C5 | ATM90E32 | WiFi 2.4/5GHz | Zigbee | Bluetooth | SIX Channel IoT Mains Power Energy Monitor + +# June 2026: Example Code, to demonstrate and test the IPEM SIX + +# Remember! +# - Set the BOARD to Use ESP32C5 Dev Module (or similar). +# - You can also set the BAUD rate up to 921600 to speed up flashing. +# - The SDK does NOT need external power to flash. It will take Power from the USB 5V. +# - The Serial Monitor is configured for BAUD 115200 + +# The purpose of this test code is to cycle through the various main functions of the board as part of bring up testing. + +# This test code is OPEN SOURCE and formatted for easier viewing. Although is is not intended for real world use, it may be freely used, or modified as needed. +# It is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +# For board configuration, see github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor/wiki/Arduino-IDE + +# Further information, details and examples can be found on our website or github.com/DitroniX + +# * ditronix.net +# * github.com/DitroniX +# * github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor +# * github.com/DitroniX/IPEM-SIX-ESP32C5-ATM90E32-IoT-Mains-Power-Energy-Monitor/wiki +# * hackster.io/DitroniX/ipem-six-esp32c5-atm90e32-iot-mains-power-energy-monitor-e323bd + +# This YAML code has been created to show the features and functionality of IPEM SIX. +# IPEM SIX C5 is a professional 6-channel dual-bank energy monitoring device based on the ESP32-C5 platform and dual ATM90E32 energy measurement ICs. + +esphome: + name: ipem-six-c5 + friendly_name: IPEM SIX C5 + + on_boot: + priority: -100 + then: + - delay: 2s + - light.turn_on: + id: heartbeat_led + effect: "Green Heartbeat" + +esp32: + board: esp32-c5-devkitc-1 + variant: esp32c5 + framework: + type: esp-idf + +substitutions: + author: "DitroniX - Dave Williams" + firmware_version: "1.00.00" + release_date: "2026-06-20" + board_name: "IPEM Plus" + board_mcu: "ESP32-C5" + board_rev: "1.2606.102" + + project: + name: "ditronix.ipem_six" + version: "${firmware_version}" + +api: + encryption: + key: "xxxx=" + +ota: + - platform: esphome + +wifi: + ssid: !secret wifi_ssid + password: !secret wifi_password + + ap: + ssid: IPEM SIX C5 Fallback Hotspot + password: "xxxx" + +captive_portal: + +logger: + level: WARN + +# ===================================================== +# SPI BUS +# ===================================================== + +spi: + clk_pin: GPIO10 + mosi_pin: GPIO8 + miso_pin: GPIO9 + +# ===================================================== +# I2C TMP102 +# ===================================================== + +i2c: + sda: GPIO2 + scl: GPIO3 + frequency: 400kHz + scan: true + +# ===================================================== +# ADS1115 16-bit ADC +# Address 0x49 +# ===================================================== + +ads1115: + address: 0x49 + +# ===================================================== +# ADS1115 USER CALIBRATION VALUES +# ===================================================== + +globals: + - id: average_samples + type: int + initial_value: "50" + + - id: dc_voltage_factor + type: float + initial_value: "9.0588235" + + - id: adc_voltage_factor + type: float + initial_value: "24.105" + + - id: dc_voltage_drop + type: float + initial_value: "0.54" + +# ===================================================== +# HEARTBEAT +# ===================================================== + +light: + - platform: esp32_rmt_led_strip + + id: heartbeat_led + + # name: "Heartbeat LED" + + pin: GPIO27 + + num_leds: 1 + + chipset: WS2812 + + rgb_order: GRB + + effects: + - addressable_lambda: + name: "Green Heartbeat" + + update_interval: 50ms + + lambda: |- + + static uint8_t step = 0; + + uint8_t b = 0; + + + if(step == 0 || step == 2) + b = 30; + + else if(step == 1 || step == 3) + b = 10; + + + it[0] = Color(0,b,0); + + + step++; + + if(step > 20) + step = 0; + +# ===================================================== +# USER ADJUSTMENTS +# ===================================================== + +number: + - platform: template + + name: "IPEM SIX CT Activity Threshold" + + id: ct_activity_threshold + + min_value: 0.100 + max_value: 5.00 + step: 0.100 + unit_of_measurement: A + optimistic: true + restore_value: true + initial_value: 0.100 + + - platform: template + + name: "IPEM SIX High Load Threshold" + id: high_load_threshold + + min_value: 1 + max_value: 100 + step: 1 + unit_of_measurement: A + optimistic: true + restore_value: true + initial_value: 10 + +text_sensor: + # ===================================================== + # IPEM SIX FIRMWARE METADATA + # ===================================================== + + - platform: template + name: "Author" + entity_category: diagnostic + lambda: |- + return {"${author}"}; + + - platform: template + name: "Firmware Version" + entity_category: diagnostic + lambda: |- + return {"${firmware_version}"}; + + - platform: template + name: "Release Date" + entity_category: diagnostic + lambda: |- + return {"${release_date}"}; + + - platform: template + name: "Board Name" + entity_category: diagnostic + lambda: |- + return {"${board_name}"}; + + - platform: template + name: "Board MCU" + entity_category: diagnostic + lambda: |- + return {"${variant}"}; + + - platform: template + name: "Board Build" + entity_category: diagnostic + lambda: |- + return {"${board_rev}"}; + + # ===================================================== + # IPEM SIX CHANNEL METADATA + # ===================================================== + + - platform: template + name: "Bank A Channel 1 Description" + id: bank_a_1_description + icon: mdi:information + lambda: |- + return {"Kitchen"}; + + - platform: template + name: "Bank A Channel 2 Description" + id: bank_a_2_description + icon: mdi:information + lambda: |- + return {"EV Charger"}; + + - platform: template + name: "Bank A Channel 3 Description" + id: bank_a_3_description + icon: mdi:information + lambda: |- + return {"Solar Inverter"}; + + - platform: template + name: "Bank B Channel 1 Description" + id: bank_b_1_description + icon: mdi:information + lambda: |- + return {"Heat Pump"}; + + - platform: template + name: "Bank B Channel 2 Description" + id: bank_b_2_description + icon: mdi:information + lambda: |- + return {"Workshop"}; + + - platform: template + name: "Bank B Channel 3 Description" + id: bank_b_3_description + icon: mdi:information + lambda: |- + return {"Ring"}; + + - platform: template + name: "IPEM SIX Product" + icon: mdi:information + + lambda: |- + return {"Professional Energy Monitor"}; + + - platform: template + name: "IPEM SIX Hardware" + icon: mdi:information + + lambda: |- + + return {"ESP32-C5 Dual ATM90E32"}; + + - platform: template + name: "IPEM SIX Configuration" + icon: mdi:information + + lambda: |- + + return {"6 Channel Dual Bank CT Meter"}; + + - platform: template + name: "IPEM SIX Status" + icon: mdi:heart-pulse + + lambda: |- + + if(id(mains_voltage).state < 90) + return {"Voltage Fault"}; + + if(id(mains_voltage).state > 250) + return {"Voltage Warning"}; + + if(id(bank_a_total_current).state > 99 || id(bank_b_total_current).state > 99) + return {"Warning: Over Current"}; + + if(id(wifi_signal_db).state < -80) + return {"Signal Warning"}; + + return {"Healthy"}; + + update_interval: 15s + + - platform: template + name: "IPEM SIX WiFi Signal Quality" + id: wifi_signal_quality + entity_category: diagnostic + update_interval: 30s + lambda: |- + if (!id(wifi_signal_db).has_state()) { + return {"No Signal"}; + } + + int rssi = abs((int)id(wifi_signal_db).state); + + if (rssi <= 30) { + return {"Signal Very Strong"}; + } else if (rssi <= 50) { + return {"Signal Excellent"}; + } else if (rssi <= 60) { + return {"Signal Healthy"}; + } else if (rssi <= 70) { + return {"Signal Very Good"}; + } else if (rssi <= 80) { + return {"Signal Good"}; + } else if (rssi <= 90) { + return {"Signal Poor - Try Moving Position"}; + } else if (rssi <= 100) { + return {"Signal Very Low - Move Position"}; + } else { + return {"No Signal"}; + } + + # ===================================================== + # VOLTAGE INFORMATION + # ===================================================== + + # Mains Voltage range in the UK. + # 230V -6% / +10% + # Low < 216V + # Normal 216V - 253V + # High > 253V + + - platform: template + + name: "IPEM SIX Voltage Status" + icon: mdi:sine-wave + + lambda: |- + + if (id(mains_voltage).state < 216.0) + return {"Low"}; + + if (id(mains_voltage).state > 253.0) + return {"High"}; + + return {"Normal"}; + + update_interval: 10s + + # ===================================================== + # FREQUENCY INFORMATION + # ===================================================== + + # Mains Frequency ranges. + # Europe and UK which typically is 230 V @ 50 Hz + + # With ranges around 216 V to 253 V + # USA and Canada which typically is 120 V or 230 V @ 60 Hz + + # With ranges around 114 V to 126 V + # Japan which typically is 100 V @ 50 Hz or 60 Hz + + # Eastern Japan is 50 Hz, and Western Japan is 60 Hz + + # World typically is 220V-240 V @ 50 Hz + + # Based on 50 Hz + # Low <49 Hz + # Normal 49-51 Hz + # High >51 Hz + + - platform: template + + name: "IPEM SIX Frequency Status" + icon: mdi:waves-arrow-right + + lambda: |- + + if (id(mains_frequency).state < 49.0) + return {"Low"}; + + if (id(mains_frequency).state > 51.0) + return {"High"}; + + return {"Normal"}; + + update_interval: 10s + + - platform: template + + name: "IPEM SIX Meter Type" + + lambda: |- + return {"IPEM SIX - Dual ATM90E32 / 6 Channel"}; + + # ===================================================== + # HEALTH + # ===================================================== + + - platform: uptime + name: "IPEM SIX Uptime" + + # ===================================================== + # CT CHANNEL ACTIVITY STATUS + # ===================================================== + + - platform: template + name: "Bank A 1 Status" + icon: mdi:flash + + lambda: |- + + if(id(bank_a_1_current).state >= id(high_load_threshold).state) + return {"High Load"}; + + if(id(bank_a_1_current).state >= id(ct_activity_threshold).state) + return {"Active"}; + + return {"Idle"}; + + - platform: template + name: "Bank A 2 Status" + icon: mdi:flash + + lambda: |- + + if(id(bank_a_2_current).state >= id(ct_activity_threshold).state) + + return {"Active"}; + + return {"Idle"}; + + - platform: template + name: "Bank A 3 Status" + icon: mdi:flash + + lambda: |- + + if(id(bank_a_3_current).state >= id(ct_activity_threshold).state) + + return {"Active"}; + + return {"Idle"}; + + - platform: template + name: "Bank B 1 Status" + icon: mdi:flash + + lambda: |- + + if(id(bank_b_1_current).state >= id(ct_activity_threshold).state) + + return {"Active"}; + + return {"Idle"}; + + - platform: template + name: "Bank B 2 Status" + icon: mdi:flash + + lambda: |- + + if(id(bank_b_2_current).state >= id(ct_activity_threshold).state) + + return {"Active"}; + + return {"Idle"}; + + - platform: template + name: "Bank B 3 Status" + icon: mdi:flash + + lambda: |- + + if(id(bank_b_3_current).state >= id(ct_activity_threshold).state) + + return {"Active"}; + + return {"Idle"}; + +# ===================================================== +# SENSORS +# ===================================================== + +sensor: + # ===================================================== + # TMP102 + # ===================================================== + + - platform: tmp102 + name: "IPEM SIX Internal Temperature" + address: 0x4A + update_interval: 10s + + # ===================================================== + # BANK A + # CS GPIO6 + # ===================================================== + + - platform: atm90e32 + + id: bank_a + + cs_pin: GPIO6 + gain_pga: 2X + line_frequency: 50Hz + + phase_a: + voltage: + name: "IPEM SIX Mains Voltage" + id: mains_voltage + + current: + name: "Bank A 1 Current" + id: bank_a_1_current + + power: + name: "Bank A 1 Power" + id: bank_a_1_power + + reactive_power: + name: "Bank A 1 Reactive Power" + + power_factor: + name: "Bank A 1 Power Factor" + + gain_voltage: 38300 + gain_ct: 64800 + + phase_b: + current: + name: "Bank A 2 Current" + id: bank_a_2_current + + power: + name: "Bank A 2 Power" + id: bank_a_2_power + + gain_voltage: 38300 + gain_ct: 64800 + + phase_c: + current: + name: "Bank A 3 Current" + id: bank_a_3_current + + power: + name: "Bank A 3 Power" + id: bank_a_3_power + + gain_voltage: 38300 + gain_ct: 64800 + + frequency: + name: "IPEM SIX Frequency" + id: mains_frequency + + chip_temperature: + name: "Bank A Temperature" + + update_interval: 2s + + # ===================================================== + # BANK B + # CS GPIO7 + # ===================================================== + + - platform: atm90e32 + + id: bank_b + + cs_pin: GPIO7 + gain_pga: 2X + line_frequency: 50Hz + + phase_a: + current: + name: "Bank B 1 Current" + id: bank_b_1_current + + power: + name: "Bank B 1 Power" + id: bank_b_1_power + + gain_voltage: 38300 + gain_ct: 64800 + + phase_b: + current: + name: "Bank B 2 Current" + id: bank_b_2_current + + power: + name: "Bank B 2 Power" + id: bank_b_2_power + + gain_voltage: 38300 + gain_ct: 64800 + + phase_c: + current: + name: "Bank B 3 Current" + id: bank_b_3_current + + power: + name: "Bank B 3 Power" + id: bank_b_3_power + + gain_voltage: 38300 + gain_ct: 64800 + + chip_temperature: + name: "Bank B Temperature" + + update_interval: 2s + + # ===================================================== + # BANK A IMPORT POWER + # ===================================================== + + - platform: template + name: "Bank A Import Power" + id: bank_a_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + + float t = 0; + + if(id(bank_a_1_power).state > 0) + t += id(bank_a_1_power).state; + + if(id(bank_a_2_power).state > 0) + t += id(bank_a_2_power).state; + + if(id(bank_a_3_power).state > 0) + t += id(bank_a_3_power).state; + + return t; + + update_interval: 10s + + # ===================================================== + # BANK B IMPORT POWER + # ===================================================== + + - platform: template + name: "Bank B Import Power" + id: bank_b_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + + float t = 0; + + if(id(bank_b_1_power).state > 0) + t += id(bank_b_1_power).state; + + if(id(bank_b_2_power).state > 0) + t += id(bank_b_2_power).state; + + if(id(bank_b_3_power).state > 0) + t += id(bank_b_3_power).state; + + return t; + + update_interval: 10s + + # ===================================================== + # BANK A ENERGY + # ===================================================== + + - platform: integration + name: "Bank A Import Energy" + sensor: bank_a_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: template + name: "Bank A 1 Import Power" + id: bank_a_1_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + return id(bank_a_1_power).state > 0 ? + id(bank_a_1_power).state : 0; + + update_interval: 10s + + - platform: template + name: "Bank A 2 Import Power" + id: bank_a_2_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + return id(bank_a_2_power).state > 0 ? + id(bank_a_2_power).state : 0; + + update_interval: 10s + + - platform: template + name: "Bank A 3 Import Power" + id: bank_a_3_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + return id(bank_a_3_power).state > 0 ? + id(bank_a_3_power).state : 0; + + update_interval: 10s + + - platform: integration + name: "Bank A 1 Energy" + sensor: bank_a_1_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: integration + name: "Bank A 2 Energy" + sensor: bank_a_2_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: integration + name: "Bank A 3 Energy" + sensor: bank_a_3_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: integration + name: "Bank B 1 Energy" + sensor: bank_b_1_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: integration + name: "Bank B 2 Energy" + sensor: bank_b_2_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: integration + name: "Bank B 3 Energy" + sensor: bank_b_3_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + # ===================================================== + # BANK B ENERGY + # ===================================================== + + - platform: integration + name: "Bank B Import Energy" + sensor: bank_b_import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: template + name: "Bank B 1 Import Power" + id: bank_b_1_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + return id(bank_b_1_power).state > 0 ? + id(bank_b_1_power).state : 0; + + update_interval: 10s + + - platform: template + name: "Bank B 2 Import Power" + id: bank_b_2_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + return id(bank_b_2_power).state > 0 ? + id(bank_b_2_power).state : 0; + + update_interval: 10s + + - platform: template + name: "Bank B 3 Import Power" + id: bank_b_3_import_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + return id(bank_b_3_power).state > 0 ? + id(bank_b_3_power).state : 0; + + update_interval: 10s + + # ===================================================== + # BANK TOTAL CURRENT + # ===================================================== + + - platform: template + name: "Bank A Total Current" + id: bank_a_total_current + unit_of_measurement: A + device_class: current + state_class: measurement + accuracy_decimals: 2 + + lambda: |- + return id(bank_a_1_current).state + + id(bank_a_2_current).state + + id(bank_a_3_current).state; + + update_interval: 10s + + - platform: template + name: "Bank B Total Current" + id: bank_b_total_current + unit_of_measurement: A + device_class: current + state_class: measurement + accuracy_decimals: 2 + + lambda: |- + return id(bank_b_1_current).state + + id(bank_b_2_current).state + + id(bank_b_3_current).state; + + update_interval: 10s + + # ===================================================== + # BANK TOTAL POWER + # ===================================================== + + - platform: template + name: "Bank A Total Power" + id: bank_a_total_power + unit_of_measurement: W + device_class: power + state_class: measurement + accuracy_decimals: 1 + + lambda: |- + return id(bank_a_1_power).state + + id(bank_a_2_power).state + + id(bank_a_3_power).state; + + update_interval: 10s + + - platform: template + name: "Bank B Total Power" + id: bank_b_total_power + unit_of_measurement: W + device_class: power + state_class: measurement + accuracy_decimals: 1 + + lambda: |- + return id(bank_b_1_power).state + + id(bank_b_2_power).state + + id(bank_b_3_power).state; + + update_interval: 10s + + # ===================================================== + # TOTAL POWER + # ===================================================== + - platform: template + name: "IPEM SIX Total Power" + id: total_power + unit_of_measurement: W + device_class: power + state_class: measurement + + lambda: |- + + return + + id(bank_a_1_power).state + + id(bank_a_2_power).state + + id(bank_a_3_power).state + + id(bank_b_1_power).state + + id(bank_b_2_power).state + + id(bank_b_3_power).state; + + update_interval: 10s + + # ===================================================== + # NET POWER + # ===================================================== + + - platform: template + name: "IPEM SIX Net Power" + id: ipem_net_power + unit_of_measurement: W + device_class: power + state_class: measurement + accuracy_decimals: 1 + + lambda: |- + return id(import_power).state - + id(export_power).state; + + update_interval: 10s + + # ===================================================== + # IMPORT EXPORT + # ===================================================== + + - platform: template + name: "IPEM SIX Import Power" + id: import_power + unit_of_measurement: W + device_class: power + + lambda: |- + + float t=0; + + if(id(bank_a_1_power).state>0)t+=id(bank_a_1_power).state; + if(id(bank_a_2_power).state>0)t+=id(bank_a_2_power).state; + if(id(bank_a_3_power).state>0)t+=id(bank_a_3_power).state; + if(id(bank_b_1_power).state>0)t+=id(bank_b_1_power).state; + if(id(bank_b_2_power).state>0)t+=id(bank_b_2_power).state; + if(id(bank_b_3_power).state>0)t+=id(bank_b_3_power).state; + + return t; + + - platform: template + name: "IPEM SIX Export Power" + id: export_power + unit_of_measurement: W + device_class: power + + lambda: |- + + float t=0; + + if(id(bank_a_1_power).state<0)t+=abs(id(bank_a_1_power).state); + if(id(bank_a_2_power).state<0)t+=abs(id(bank_a_2_power).state); + if(id(bank_a_3_power).state<0)t+=abs(id(bank_a_3_power).state); + if(id(bank_b_1_power).state<0)t+=abs(id(bank_b_1_power).state); + if(id(bank_b_2_power).state<0)t+=abs(id(bank_b_2_power).state); + if(id(bank_b_3_power).state<0)t+=abs(id(bank_b_3_power).state); + + return t; + + # ===================================================== + # ENERGY DASHBOARD + # ===================================================== + + - platform: integration + + name: "IPEM SIX Import Energy" + sensor: import_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: integration + name: "IPEM SIX Export Energy" + sensor: export_power + time_unit: h + integration_method: trapezoid + unit_of_measurement: kWh + device_class: energy + state_class: total_increasing + + - platform: template + name: "IPEM SIX Total Current" + id: total_current + unit_of_measurement: A + device_class: current + state_class: measurement + update_interval: 5s + lambda: |- + float t = 0; + + if (id(bank_a_total_current).has_state()) + t += abs(id(bank_a_total_current).state); + + if (id(bank_b_total_current).has_state()) + t += abs(id(bank_b_total_current).state); + + return t; + + # ===================================================== + # OTHER SENSORS + # ===================================================== + + - platform: wifi_signal + name: "IPEM SIX WiFi Signal" + id: wifi_signal_db + unit_of_measurement: "dBm" + device_class: signal_strength + state_class: measurement + entity_category: diagnostic + update_interval: 30s + + # ------------------------- + # ADC0 - VDC Input + # ------------------------- + + - platform: ads1115 + multiplexer: A0_GND + gain: 4.096 + id: adc0_raw + update_interval: 1s + filters: + - sliding_window_moving_average: + window_size: 50 + send_every: 50 + + - platform: template + name: "IPEM SIX ADC Scaled Voltage VDC" + unit_of_measurement: "V" + accuracy_decimals: 2 + + lambda: |- + + float voltage; + + voltage = + (id(adc0_raw).state * + id(dc_voltage_factor)) + + + id(dc_voltage_drop); + + if (voltage < 0.010) + voltage = 0; + + return voltage; + + # ------------------------- + # ADC1 + # ------------------------- + + - platform: ads1115 + multiplexer: A1_GND + gain: 4.096 + id: adc1_raw + update_interval: 1s + filters: + - sliding_window_moving_average: + window_size: 50 + send_every: 50 + + - platform: template + name: "IPEM SIX ADC Scaled Voltage ADC1" + unit_of_measurement: "V" + accuracy_decimals: 3 + + lambda: |- + + float voltage = + (id(adc1_raw).state * + id(adc_voltage_factor)) + + + id(dc_voltage_drop); + + if (voltage < 0.65) + voltage = 0; + + return voltage;