From 589a61b287893b3482f82104fe69aad5a4f403d5 Mon Sep 17 00:00:00 2001 From: Kato Gangstad Date: Mon, 6 Apr 2026 15:33:17 +0200 Subject: [PATCH] esp32: replace port with PlatformIO implementation and add CI build (#1292) --- .github/workflows/gcc.yml | 12 + ports/esp32/.gitignore | 5 + ports/esp32/README.md | 132 ++ ports/esp32/boards/m5stamplc.json | 21 + ports/esp32/docs/board-photos/.gitkeep | 0 ports/esp32/docs/board-photos/M5-StamPlc.webp | Bin 0 -> 381249 bytes .../docs/board-photos/Olimex-ESP32-POE.jpg | Bin 0 -> 10032 bytes ports/esp32/docs/board-photos/Xiao.webp | Bin 0 -> 10774 bytes ports/esp32/extra_script.py | 120 ++ ports/esp32/lib/readme.txt | 36 - ports/esp32/platformio.ini | 155 +- ports/esp32/readme.txt | 67 - ports/esp32/src/.clang-format | 7 - ports/esp32/src/ai.c | 1294 ------------ ports/esp32/src/ai.h | 151 -- ports/esp32/src/bacnet_app.c | 365 ++++ ports/esp32/src/bacnet_app.h | 69 + ports/esp32/src/bip.c | 350 ++++ ports/esp32/src/bip.h | 226 +++ ports/esp32/src/bip_init.c | 116 +- ports/esp32/src/bip_socket.cpp | 178 ++ ports/esp32/src/bo.c | 433 ---- ports/esp32/src/bo.h | 118 -- ports/esp32/src/bvlc.c | 164 ++ ports/esp32/src/bvlc.h | 46 + ports/esp32/src/device.c | 1753 ----------------- ports/esp32/src/device.h | 461 ----- ports/esp32/src/dlenv.c | 81 + ports/esp32/src/dlenv.h | 48 + ports/esp32/src/main.c | 218 -- ports/esp32/src/main.cpp | 57 + ports/esp32/src/main_bip.cpp | 152 ++ ports/esp32/src/main_gateway_router.cpp | 332 ++++ ports/esp32/src/mstimer_init.c | 26 + ports/esp32/src/mstimer_init.h | 32 + ports/esp32/src/rs485.c | 184 ++ ports/esp32/src/rs485.h | 100 + ports/esp32/src/sdkconfig.h | 125 -- 38 files changed, 2926 insertions(+), 4708 deletions(-) create mode 100644 ports/esp32/.gitignore create mode 100644 ports/esp32/README.md create mode 100644 ports/esp32/boards/m5stamplc.json create mode 100644 ports/esp32/docs/board-photos/.gitkeep create mode 100644 ports/esp32/docs/board-photos/M5-StamPlc.webp create mode 100644 ports/esp32/docs/board-photos/Olimex-ESP32-POE.jpg create mode 100644 ports/esp32/docs/board-photos/Xiao.webp create mode 100644 ports/esp32/extra_script.py delete mode 100644 ports/esp32/lib/readme.txt delete mode 100644 ports/esp32/readme.txt delete mode 100644 ports/esp32/src/.clang-format delete mode 100644 ports/esp32/src/ai.c delete mode 100644 ports/esp32/src/ai.h create mode 100644 ports/esp32/src/bacnet_app.c create mode 100644 ports/esp32/src/bacnet_app.h create mode 100644 ports/esp32/src/bip.c create mode 100644 ports/esp32/src/bip.h create mode 100644 ports/esp32/src/bip_socket.cpp delete mode 100644 ports/esp32/src/bo.c delete mode 100644 ports/esp32/src/bo.h create mode 100644 ports/esp32/src/bvlc.c create mode 100644 ports/esp32/src/bvlc.h delete mode 100644 ports/esp32/src/device.c delete mode 100644 ports/esp32/src/device.h create mode 100644 ports/esp32/src/dlenv.c create mode 100644 ports/esp32/src/dlenv.h delete mode 100644 ports/esp32/src/main.c create mode 100644 ports/esp32/src/main.cpp create mode 100644 ports/esp32/src/main_bip.cpp create mode 100644 ports/esp32/src/main_gateway_router.cpp create mode 100644 ports/esp32/src/mstimer_init.c create mode 100644 ports/esp32/src/mstimer_init.h create mode 100644 ports/esp32/src/rs485.c create mode 100644 ports/esp32/src/rs485.h delete mode 100644 ports/esp32/src/sdkconfig.h diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml index d8cdd198..91e6643b 100644 --- a/.github/workflows/gcc.yml +++ b/.github/workflows/gcc.yml @@ -328,3 +328,15 @@ jobs: gcc --version make clean make gtk-discover + + ports-esp32: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Install PlatformIO + run: | + python3 -m pip install --upgrade pip + pip3 install platformio + - name: Build ESP32 Port + run: | + pio run -d ports/esp32 diff --git a/ports/esp32/.gitignore b/ports/esp32/.gitignore new file mode 100644 index 00000000..89cc49cb --- /dev/null +++ b/ports/esp32/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/ports/esp32/README.md b/ports/esp32/README.md new file mode 100644 index 00000000..19771285 --- /dev/null +++ b/ports/esp32/README.md @@ -0,0 +1,132 @@ +# ESP32 Port + +Date: 2026-04-04 +Author: Kato Gangstad + +This folder contains the ESP32 BACnet port built with PlatformIO. +It targets multiple ESP32-family boards and covers BACnet MS/TP, BACnet/IP, and BACnet Gateway (based on apps/gateway2) profiles. +It is based on the current lwIP port and Pico port patterns in this repository. + +## Current Scope + +- BACnet MS/TP transport for ESP32 boards with RS485 +- BACnet/IP transport for compact WiFi and Ethernet ESP32 targets +- BACnet routing between BACnet/IP and BACnet MS/TP + +## Port Identity + +It is the ESP32 BACnet port for the current PlatformIO-based targets in this repository. + +## Supported Board Profiles + +The current board coverage includes: + +- Seeed Studio XIAO ESP32C3 for ultra-compact BACnet/IP +- M5StamPLC for BACnet MS/TP and BACnet router builds +- Olimex ESP32-POE for BACnet/IP + +The upstream BACnet stack has a broad source set and multiple app profiles. +This port selects the ESP32-specific transport, board, and application wiring needed for the environments documented below. + +## Files + +- src/main.cpp: Application loop, BACnet object table, and PLC I/O sync +- src/mstimer_init.c: millisecond timer hook used by mstimer +- src/rs485.c: ESP32 RS485 low-level driver for MS/TP +- src/dlenv.c: MS/TP datalink environment setup and port wiring +- src/bip_socket.cpp: BACnet/IP UDP socket bridge for WiFi and Ethernet targets +- extra_script.py: Injects BACnet core/basic sources into the PlatformIO build + +## Build Notes + +1. Open this folder as a PlatformIO project root, or run PlatformIO with this folder as cwd. +2. Start with the environment that matches your board and transport profile. +3. The `platformio.ini` file defines all tested board environments for this port. +4. Ensure PlatformIO CLI is available in your shell (`pio --version`). +5. Build with `pio run -e `. + +## Tested Environments + +The following PlatformIO environments have been built and uploaded successfully: + +- `xiao-esp32c3-wifi-bip` on Seeed Studio XIAO ESP32C3 +- `m5stamplc-mstp` on M5StamPLC +- `m5stamplc-gateway-bip-mstp` on M5StamPLC +- `esp32-poe-wifi-bip` on Olimex ESP32-POE + +## Validation Tools + +Interoperability and functional verification have been tested with: + +- YABE +- Honeywell Eaglehawk 4.15 +- Tridium Niagara 4.15 + +## Board Pictures + +The following board photos document the hardware used for the tested environments. + +### Seeed Studio XIAO ESP32C3 + +Used for: + +- `xiao-esp32c3-wifi-bip` + +Why this board stands out: + +- Extremely compact form factor for a BACnet/IP target +- Physical size: 21 x 17.8 mm +- Strong candidate for one of the smallest BACnet/IP device ever ! + +Hardware summary: + +- MCU: ESP32-C3 +- CPU type: 32-bit single-core RISC-V +- CPU clock: 160 MHz +- RAM: 320 KB +- Flash: 4 MB + +![XIAO ESP32C3](docs/board-photos/Xiao.webp) + +### M5StamPLC + +- BACnet server object model with Device + Binary Input + Binary Output objects +- Runtime mapping: + - BI 0..7 <- PLC inputs 1..8 + - BO 0..3 -> PLC relays 1..4 +- RS485 pin mapping aligned with the M5StamPLC hardware profile: + - TX: GPIO0 + - RX: GPIO39 + - DIR: GPIO46 + +Used for: + +- `m5stamplc-mstp` +- `m5stamplc-bip` +- `m5stamplc-gateway-bip-mstp` +- soon to come `m5stamplc-poe-bip` + +Hardware summary: + +- MCU: ESP32-S3 +- CPU clock: 240 MHz +- RAM: 320 KB +- Flash: 8 MB + +![M5StamPLC](docs/board-photos/M5-StamPlc.webp) + +### Olimex ESP32-POE + +Used for: + +- `esp32-poe-wifi-bip` +- `esp32-poe-eth-bip` + +Hardware summary: + +- MCU: ESP32 +- CPU clock: 240 MHz +- RAM: 320 KB +- Flash: 4 MB + +![Olimex ESP32-POE](docs/board-photos/Olimex-ESP32-POE.jpg) diff --git a/ports/esp32/boards/m5stamplc.json b/ports/esp32/boards/m5stamplc.json new file mode 100644 index 00000000..e9f553a1 --- /dev/null +++ b/ports/esp32/boards/m5stamplc.json @@ -0,0 +1,21 @@ +{ + "build": { + "core": "esp32", + "mcu": "esp32s3", + "variant": "esp32s3", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio" + }, + "frameworks": [ + "arduino" + ], + "name": "M5Stack StamPLC", + "url": "https://m5stack.com/products/m5stamplc", + "vendor": "M5Stack", + "upload": { + "speed": 460800, + "maximum_size": 8388608, + "maximum_ram_size": 327680 + } +} diff --git a/ports/esp32/docs/board-photos/.gitkeep b/ports/esp32/docs/board-photos/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/ports/esp32/docs/board-photos/M5-StamPlc.webp b/ports/esp32/docs/board-photos/M5-StamPlc.webp new file mode 100644 index 0000000000000000000000000000000000000000..08f95c1a3c5c970477a65024d08329f3dbdf51a4 GIT binary patch literal 381249 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%0AQJnHNRHSqor%bdQ?LWy6&PZLSzu9 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%0AoMLh<9C%uttB+4$ze3h%!& z)?E1#q1Xyu_66YjWr0CFMvJkVDX9J{)>{%mXO=4H)=U4i995WC%+LQ4wagh;tBB;&a%pt; z(Z8c*wzFe0OXSFI<v`&TJ|pGC4daD&X)#{g_$=y0P3Ueqg9Zmk#48~wy1;cFP@->wlS z`=j~dv#%DtN~XS`9eq-~{GF3an`Uq?m8;+ZfnTU}{9lFE|M1v&^>??BW03C3e3f74zo`P*o=g3_Xn_0cNp#Y@iS2j6vh zZ?fduVimnr{Fdt3vA-eit%`c)Zw&nxonlf2F==V3?1UxflB4W3ci5RMxscXki%p(a zT(4MrlKIzIk4YH?*dsma}UHAWiRTL z?%HGUKVK;8+&tWf+7tgO=+(Ns@c9XPQKf{0?4T*~1Rx-JQ8X4JCnD`8r>J&MCOoFr zBsle^aAvH zZ%_}Rs}@(~v%a????~w1%gTcc6Mr1mcr@%&KLH0Cg_n zqiVwi4D~O#S1jrph?XRz-{!9d4UW^({Yo(|aI75HjoAo&(;{eR0I%WWK%=je~Kx!-AikCd7gIk z$B!b7OYRS3turBFKG?}LVN{HdeK0P(LC*rC19}>UIN$Vdx?d!!y!-C@AD;WYO;~hs z=J&WYe2P#eu@7lD@4vr0#r%rp=YdB_2S?h#LYk+2i11ITWF(_2N1LXWqgQ|Z8SxVF zgIZ3)*4Y70L~TBhXEg4IgLwV?q0L*o1OBv>AoSfaK5=TW13$S!c-8L>JJIq#_{MT1 zkQ#f}ee%wEZT-v%&cSi-Y2RhSpVdC zeT`ci*zcaTZs6|!A$+q-FSCOyeTRxIvh~x8x3uf9ymRGl)s9o1xrpCpThVi8t)nkC z_2d@VhZM!%$tq93BmtuEu|18_aL2KN7QN9G;%)a?TDE3!QgevGRr53F5#i)ck@=FB z555SUR=){T^jK5xcPhC}FSfu#J&7wWANu{s+{gIdgB;cJ2gQ0+YBhMEKi#?p;Y zSOY!9*!I7^I$BS9RhIipz6=DLa>OY0(@0SL&XMJiNAem*liaM!T7p55htw-`|J=8l zC@~A%JFXQRrPq5ou;cv=`Hq*eV%%ma22p|0^5wJsFrM3wuV6HE=>5!IT|K#(1Z9DS z9k1gyv)q}-ST4QLBR8O0$O^CIqvMTt4EV!D?y?t{is=L&GY}IJ3TTAQMWp$5a>zG% z422_CX%#Y(&_;MNDhaJ={q}k!KWT{50CESGA{h|tbg$GD<_m0Y(~P8Rg5vYn4@m9A z>wB6aF66Jd_ne4auf9#y6BE_{ve8J4usz86&6}G9XvW|-B0~w{~ zpj|xv%kPz=DN=ux&RJXRBFPr&Da1w0SwSh{dWOYUM84aE+b~gsX#{YhLy+>^&a|S5 zY{|Ih_~D_?vb%p~qwqzeLtt;Q!^lqGm?krQE~VK^eUTKq>gz64W$3YW4NfQZgWX5Z zj^@2kQ4;q7cHf-Hk7Q+eb?&?lJhi>x z(dM9d{rnU$Q;9;Zw{QMlRW=`?QCfH=VCY%5)NbRe$Bv~gr6fM6VUfW6iF)t4mOF9V?zz9=_?JNKr@FE z60m3y5UUJuKI`P0%X@Kp=}kjf3Dz<>N?ofz+ZC!(J)H10hQd7=9wE8J*x` z)QvMB*R&+ll)WiWyZNI2I8veXWZw*G+1IG*#vMfGEv}`c8fMxLkQm@?@uS)IVgA1g z1LIUZiR$ne9R9mpbg22|cuW4Lf5t$@0{tKf~Cf)_xy z3z=fhq)Jeb+JKG@T9u7&2nq^XmHy?78))pWd~ $(G;k=BayIRvq{>x%c^9^1^m7 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

5Ce8=h3l#IESxK(U|eDk7;9`1E%5eB z$=97V8FE>tFWOfS0cV7AtcEQ(;Wit-Z2#3(Yt{wNl04TfxV-ag)0_NRJz6Xsy#N$! zb6e$#!`|7W<|3ZS5HojsrCke(FQnOm#Ermz2e|e0!)Dg$dXP(7_!WXLw!!8*Hoi77 zk{3oa0m4SNnJ<%_f}cDz$Cf=sL+vc@+0N4Ul zWyMenF}e^yy00m35Wd8QDej-(1=v_b1aQ!fbpzb(1y6J)Ga>GdHw1tN4(dv^;&eLm z&f3e;f*cTE_6Fs22XELE*@(74Oadq$z%}4TwF89`=mbR=r*^=N>*%*$lP6?iGB0^U zC8n>BR3^CqN@+*Qnw=+Jynmw^zvaJ(bB}nDCoot^+k&@FIDOMF-MH*3<{_YpJaH!S zM{*H*iI1R*@c*<(1hJ1wFu;;&6FSgc<_kBcE?*I}H&wV~AC}sme^>?(mwhnAP9$DW zb-ZOW|EJJoT}D{O?x5H zf!}74oY_Q2e>Rdn`8)LL_GIlKG8M0+Gmx10ysc;n2W2BEwRNP(R9aAPw>0BVyzPd5 zRsB&A-ox)z?cTrj#WpPT=43P^pvjoW(d4hq`1acFi$@f!{D28AmQ{amrcKq`Kt10F z#dft}FQ&j%r)Q^k<1gdj@YYx11X#H~CCb~|;79&FHeLJ2g{}O|3;+>w8nZjK#u(`3 zdK3^;gut@OEiDggi6!TZAt0{*A0#*azkCLF@;c=F0ut6ik8-c>7b|aZ-qoC6eL_g` zo2s=29kMH^Q)J#5LDeU=X7WMD_j~-Hj^E0o>7S^ag)*b#SccT;q_Sz1Es0~I7oSvC z*~(izEie@XtrX|#wN5;t!k2$5U@hgjrw7V1M8_4l)G<&K5{$*Tew~%J-;%VZNZp9Q z^|-Alm%KeUWv{YQlF0%&4uEw2rbvIh@V~$6A|Fs;Cz7ak$f;k?s3{JchhbpLp6cBJ z+!cT;qOaFJ>OeF8q{l#?Pk8U75O`qH`w=$Szw83;r8GIFW-%qg6m zu#C`z_j^nK$)t|tA*g=zzHfmZgAC+n#vjUdnywcE+EYz)*O9EAOGz`&3zabg_!k0( zom6Dg)QALr8%eR*+Z)hSQ@nlcIlh=e8U}8Hh4Zx)%9_)qh4`|wBpB+eGxi}<#NJ-g z>3MlQxgO@Jz_z?RcEx!_`?XCZ1dEL8)C$#fh$m^8mA1sc&PgZ!WJosj1-|9Q1@8(y$Ru)q;Z|8EhVsi8n4T%T zeewC(|1(!B1H|Vf&hC&fAhij>KK!lR(bZH~e$YVlSTV=X6WGKjwHq9U#1Fb?6hCB( zUy|$0NiJC<%iz}tYL#n(S{4KuIudu}>igfZTAu$ver(G(rvimLeX>pE=F)D|HMVfd zD%+2I9h^@EdV5BMKH68%{k=@i-J(Qo{mZqZkb~DD-d-8KN!@b?`+kk;tJSXg&oh=NyAQKXwIY%Z z+_UfGnj)9Z&|O);UWly(Zg_{9#AVu!?mS{Jbl$E?QTpP2d}h7fNT{EQoBPTB?3Jd5 zp6L=ZXkHbaPOU z#ZB;iVwEGwlbi|joyb5oZ^b@$%W)#a5M`jhz+920xETxF*{kczVz6~NHFVwpQg}xb z=mAP7W|w^);a%gGC?s)v|#07}G;yyjeQ>jZ1i z-z$}){lan44C9QL*Kt`IG^Ag{<9r#`T(t_I$lkWq#^@krMWiTQK>^4ry>zqnNSLtK zi(~>&ukaK=4|N2_49IA@qTt+-2DqbS`PXX;2!P4dJTYqBf)il%W^DX!RPM3l`+FgW zQG15()xDCR+ojYMzu*MZ2{cjdGrf7$a`d&k{i6hkmbpJcT8K^T2Lx3Q^yb|o z$mvc2N?P_L4-SU;CHth`M41tynuETyf5Y(aJAMNl)J(&HT*|UFRAhWqLFV}rWC|x~ zKq2d8xYPpK`Ok7Oq6|ir3XI`mf{eyt4GdKWR3>~U?aEH#bnS^3WqI?vg&@~2n))9VRFr7SE!YI-KM-_+@F2@M4R7>Jw zJsHnX2Ml=~1be?SFL!?Jj~o)?TULrg1Y`{hg<@OwN5t{UKjg0fhRQpc3c#0-w0=ng z=HkAu=JYQ#j35If2Dl9Aa&2m>%jYQ9c1K>|{R5eqTv^D8J<_KJ4=#7+@7nG^?Mh+3 zJ7q`LVhExTJAn!&P%=l#QMd!c4aB0kuJR4?vFh^)Z5737)S@oI{B(i``!<(*ow0Vs z%QJ}l=8{0X++}Tj+%xrRxe%rf_m0MNz|-R(v0{6>5~T6)MTJhwaz_i+D~=BjUzI`Z zVW$O^JLMEXy43IkAO8Nz)W zo5A$QgkfEA0?cgYPx^y}`^C>HwYKxW6n;a7WfCp>oGvebAQgYFR+vh=rWO7IJ-)!7 z$2WWm?644!G;IekuC>2X*M%o~0qr&b;3;yQTn_Unq>`1w9mSz=$BqsJI#gz#>$mb>js8g@V%UvK zgrk0nM3eP=V0qiX#PW&w8g8{ksQ{9pfo zk9s!32oh6u_3fDhV3Cddb^4;+DQ#n1fuo-A2M+s+1P?dQ_qQ*}9_w`^`G9pLGFFNN zfJLx!G6Yk2=!TZ16~s&*zYbeiw^A{BZXz*}qq>qi;f;U7Cwrz`Y8}cZ%X8Q1;+-DI zj5m?@(Ld0~5G45=hAsJD|EN7-`;PS|akQ`B%=wR7wc+HZT+V8wAz^#|j6-HuJh{-n z`q7eF#=J^kh{R93<$5dYi{75{xkm^H)5 z_oZETK`8h->+x-YHNGpY*_(HM@$drE0rbrOuT${(gW0Uy`pwPg!=ImgL6mdF$8ILto_@TY{F5 z$~MclHjOz&I(jsbLw88_Ch^L z6=$8;6v0e)ix*x!M?ajt8abLm;io0Qh$~D zB6BiCVQ?o#Z3Cv{LFVE@FSs$5V5|yhRKytAD?vZ>Ewdgb*l_f)>uJ^J6eVKOFx2lO!sVcBYdrRqy9PDhmHb^# zV;9KS#ZwKRX^1r|D#CF9ScSw6r?NP}Fo4*p$nW4jk-@VV3O_Mtfo6+eeE?)hZUb(T zRRw~i{{a!VY)>xfmfD8!b#ntfaK6>8xWi9G-LR29pe+M1E-XRJKp@8ehz;nhLlV2M z*Xb&>H)qI1S=&vqrjy%&w|MNmIQ!e5Cji_wT!1;c2vl%-uf}ocN>P@-wfe6DmSC1( zct?~St`bSlPjix!VRb=qAaR9`!V2(8#PV=21DOsaK%_IYKSX>QSL~1(4Z?;C$86I| zk#08urs&!cG4!T6{V@4G#3yc{TnY~pe;lA_coBpGfpmqO2`XC@2CL5EdLE4j8H;Ht{n)wyxIh=7uwH2s98L_s_UPQ)dVQ$RR;eJt0USMCAany= zq*=kQir@O5-?v3kX-3k~#1WOCztl04u)b)rCe#YnZwiQVe+E8_W!Zm{8HV^D|J8w` z^+Gf@&W`lJtSuz|6JWgMYqn6}+0h`7D4`silsyE>9zs39@JaEB#%l0gp9K=U5D4Jh z4#E0smtW|2Xc-Oozw&r!EXI-b z+1#)O^2j(&UK0BdC39SXWT>zVsG@!Pn?t$s7+5+!*c1T)3}b-k`VVvpxkuNBgY|v{ zV@=*XJn4iH{Y}tRFMyrdg#EnApRn4`Mz|N`%eSJpX1{C5G(-{rQeHHlY=&XNl;u&v z_J3NsX-{9nrBJMj>gO+8)HMXX4}ppgodU3(n7=C#!;G>6l!%Iy#dE1i*dQb*s&Wsq z2&f_ft|AQz7)>l7DZtx1v3P`kpNUcEpJ0rH%t5buuknKEpt>a88&1?y+6HK6Mz8$s zdFWM=Jk}zyrhBB8uzPf?w{n z=m02CGSM36@8suY;h0hPvcr zlQ2QUstDBIpqtX2hnMsM%Iag9l6%E6)Q3e2L{wsa;GCDd@kQif7{Fy3TXc;Kq?tVd zNIQ}NkT;M&L*)A>k=zvGN$wcQ1~~2o+y$Mscu07-bILSay6fMDN2mv1wtfzu(3!>FP#!o_l$$6qnAYE%W2NUVo7 zi6d~98&`W!&*}F7wthmA$=RUWyjPAA)ew!g7cXC4_u9ck zuOD_sR{?F7RCLg*%m}{8cmnIdFIVZBbHPj034+2&2$9 z`BRTy6w=egY`k(aODj$2X;kk&&?Q+|FXIFW=~h2Mwgax>^o)0q6aUtoESSJ8V8;Ni zZZBhfCc&@ci54|c0lK(|{|EXI^+)RDBU`)?Nq`C1G1V*Y35i5c-v?hT2pwR?_+5X zG#%O;SVB07y#fg85g~TZhalh24pLS`Ea>o&Lr%~}DjeX7^a6ViYa*%y*!#?bH~k<6 z|1>bG&>?e7@+A^)q6SNv^ipZAyxxFqCWS>9c;dT;i&4S&-d4v_o;(aBCU1*RW0|dw zJ{qjJ5JO-GcFmf1vHi63P|Z|0e7oXzGt0Y+W9@2qUw- zp~96Sv7TTOhdy4`F7qHz&_#`#FoV9r$I_dzK(J6stM8SPWoM?565SjF<}dxfv-$L? zhqeLHvFEF}`8J%F#H~<}v^#y%&f?YZ@Aos$pXuo*YR!G9AVyHG{Exdv1l|(T0y_t8 zm1SPI18h)t8nEg}?9CoSh~E#3R&pNPM_z~GA5DFJk8Y5T!XgQb(xl4k^9jD*Qx}&- z^1u$umgb5vVe2km(=~YfQMgS*D#RR)^>in3m{DiLypn@@KILJY5-x~7=qz<+c@oaQ z>|Jm@LfPorMVKehw{}FhTD;E!1Q$7=QAq^ zm$ZU9ZjlBGDrhhg6Qe89dKv%|nSOXYy`Kdht7RA7#R`Gg%Q9$moiyR9_ zWq`33#RSQ%bO36tg0~|W*LcD>we8W{B!v(RaEU-w=K$nQrapGrWM&r-zL8f=@MKGBf*Tlc^_xT5^SoyQJeFwpJN48HEHX9i`a7xXj0(>O#RQw$ao{ z8FV+5>3WQ^5VX5WKJDZr0&#lsgn|Ex6V{~%Whh*m5BDZp?0-<>LD0#%_$jp< zfo^74lz+LXeh3?BpfH+(mmuE$OH>lB;I~9`=I;f5(3;uS3OOTbp zZgXT|`J~t}D-;|KA(3iAkIT{O?_uY*3 zoVHb?W%^LIS0(#=?B-7~u3kU!2+x|*_@z5EaxzstCj7&190zA)o2}(5#;!-)oiVy{ zxYL{;)sxQ6w@6w$fT*uhs zkST(CA52EN=Mb|d6B+vZg7(0u*kk+1uq!Ygln30fB6%`EWZ^|!TO`%6xhc8jVT zxhgkl)V9Tnm=G_gHE$mq2VO93IJo@esl8TWilO0h8`=YNtdKNgOGvdPL}AaKrn}U5 zYa$0MIBZusbL&^O0j6_>=U~Rg^LpFr)tnLCLJW6$dG77wKO=(gez(}({SJCbdeJV0 z&&VMse+zTBo-S?f@Q5@(jiA46hqB)a7Uwl(Ia=KRV=FAx!r}a-+S4VN?~*wC5Hr5P zG}vOscVOU6kUq;Pr`>A9Et=f=u@H_cRmb*mAo}@i3mRYT=IRR$4ntH*je8A7K zZ;%83(+>~2^OTI-suIlz(`zkOTe4TOVAoxwrfwK9GEPm__r=#x54)MYI@z#FE z8GElUP43zJCZOqVOT+5>?0ZAYn>6L9%n3H;SF|sZZVar{27NDW5AaSM5e%Jj8sBs? zO#d^G@Y8gU|M?FISIHt(?h_HuPelfGONT1q^1gi*fsyZc)oz=(cG-;3G$cRmYOzo~(`;*iN7T?BN zc0!b2wVz3<&6-vOq{)E%x#cz8$v~T$bRREe6^2^gscD>848`~($azZJ#lXb~Br=v# z5ftvmh!>4bSbTE$dL@fqnC2R<&1MS5V2-uyo6~?S&!7UqSZ?yR7?U`>pRG^dL)*A~ z%sV8|#Vb!h;&;x<^4hPKqfU#`cUvFK6Gls!gz6e|u`73E)CZ zI*wFOhLFvw8`CCd))1@}Z0U>VTCmDbHy9g9tmu}Q!cDz?+W#CS0?0RT3;t8NSE#1hDiQ&?KnQbKGRL1-xUIv|k<8kV zs-5`B1aDv0+p{6U*Zy93;jp;ou>3vvJm8B}kiBA3FVV^VYe?YhsuH`gaJyr8p#8;$oY9>9x(3zL7(d?vdcNVy z5t$7ptrj}MBS+$f5>3S0jJRc;Zh4oC>C+*GZp9o%k_RQ#{KdvWBrO% z6;)%x8%*W>@=NP72r+W9Z>{KT*|GRrmwdq_|DQu1uZ^_Xf4nx|{|E9O`(FR-Ej!iV zAor`)VPAKDno8L{rG%ern|BV7K2x0?a=#wO&gFS4y&cDZ^v_1|c)PoGNH4pV6m42m zwfxUVDO#B#gpxbh>h6XLgwU1EncL0XxqHs@&+ho``}rL@M$ zmoN=)AIApxb(R_h`iFX%u6+JEmZ@p#@wp}Z-Fe`${-yzYYw;#TD@#4rlK9cHFw>|j?UX7RHCb_U*y(x^Zf=DjTg^;(9Qc+kTmT>vnMbXJ-_5I zMcx53gq;KI>(QwJWqaLZ01#x#+5daN*!9}^fuF=Rj;dZy?v+5K=gZ7jr2C~;j-sr4 zMJ`X0oaOU4$py(frRWFus*Wb%t^Go3cKYd-(kamvt`hylIaD3LT^<{`V zEZ*DSKjey$Fc6E2Tv-+8yvXh_4%PPD2^2L;uSmZk6RCG3Q8$w!i4?&lye%P6W2_Nm z(>@XAMuHo_ud(X>jlibY0U*p%LmwZn*%^Pcu_x^HL$BgEJOt*NM(^#!68r5AI*)hG z7H-(3jQC;us7}rH4`?pk_Wj&E`$+mo9u@1asA&I5{p#gApOO!&p1k8Le|o&4DeF#8 z2XXgzk?1h>4aA3)e(&sTPOy=GJ)@W!cDXG@Ey2dM>GE5!uFvru=65Mb?i=Y5!tq_z z{Zo!k1|eTQc$heW6H*y}Ga#@t(6*a2-%mIBuUwiqX&;sFTz ze}r3fi|y|^0r!Vi8;CJp5`w10GH7D8RxSGBTt0`{<4WTGLERy}(=ef+o$N=L_@ zeC4D2`)=*ZP-w7#^h49+zL-fijUSYd3*_GuW{C5-RLqCvhP^-_cpF;YA$|LgpqaEy zO#)IQs8%OQobCtWbLeaUAwy&RgBAIUwpU1$^2q-5t*_ex7JdIf(G)>~F)R}9EeFQK zqWKRWF4^Ca%X6CDXuS}gCPQe8x?o%Kv+kO$+{RdF*wpd_<5GLLr}zcaOjU%*1MeS) zZt?Cp2liiBxu5>WC>8q`fkzUqsvYS2N_2+asEfQiDIQkiyOlj}?57Km3pqDb)i>TR zTdA`%lZC+(Y}Q+{(FIEgMQ}!K>H9<3+RyFnEu9JDk#=(Pr6PBJpGe%O55HjVof~c5 z0bQmoe=9IZlgHrS9DU8K!Z=XK&bPEV^wm=N;`8&zOhQw3cH2 zLtNGV0>0t;5pb`zl)2g?_mtgr+kKxev74hMbc-&5eyLa5m)CTD77WYcl8tRhpQmT4 zY_9c6XUCOX+9-M#mAMTm*QhxlTs4g!@H%W6Y1miIDu4(o-R_d!czJ zNP@jtme*3v>+&D?X)`x;rG5G{$`6N?+jj#TmV4SG_wmQ)5B4M6t}^IRO-qz@7osc8 z{x9C%I;_d>j~_+_5h>{gk&^BnOuD3{OFBo#l$e0hAuX+hG)RZQq#LBWM)w8+Q^r2O z`}_R)d;Wc{=O4Cv*BBS)K0D`qUhh{J4l%Q#gOO9J3ugi}Y6~G2h^X1pMLt3L1=V@J z5FoFNuz!=ht|(&L^Q}DV59C|{bC<@v$Av>j%g>bd;KFAiA{`W~E}Km>zebAQ6__#2 z?gS=T-`vdX4tTcyga69sQfyAyds-thNft*4Bo&rRJ5PAHh0x z+jY_Zs$g&3HVNfvwaRjpL+xxxO`&PM=3R}iQ?(r{m)s^0Kg;bqTGa4XwA^!5TU_4$ zoGoDJZ;yFY_w&Wn8w>GB&GwGjv$K*&y_W8ofC-v6&2z>x`}ngV3PqMDGR(!_H!_9A z&y&kHmwz3x5fr#SOk@~{b2)E1>YfO~tCr~x{IP1Wwz~S|xhwt2>2G1zw*^~$4fsMU zq7`xP3SK(=1wSS$)@?5{0be~KVX$jXmwlvGY;zJy7 z5RKKz?+!-FmUw%Z&OYQ{6Ra$Dzlp68Y^+jmg+RRdotJ&7-N#mi3CBF1r;VkZPEU!C zzM34L?tPGAhH%2Eap2Q?@_J@O^(Sk_sCJvE zi53zl*t7vQ!tQjfxCLQawZ-uZFA>T%CE`Dd2YQV@eDNMPhkN|%&j{F4*>Htv92xI( zv&F~CJ->GROza+q)QGKGRB*=WQ>s(tO?W}SZxFB*T>kFCW{728xQhu@8|W@T&8g#u z{&{6CK3laoriL(o_b}&8<*#q=*K7^cb0Zt4rQdN&KF}6b>JZ%b=lfWuilT{SMecptyB{p2n(EOG zGGQ|*&{oQ=QM}pTH!W$N7vJ?=)PwoLkfxh|l`k-qeytc=z&^iL4vfh7S$EZZUvcdP z#uB(9!J`Ea$}FK?TiRWj`8NzwoQ-Y2yK$jBeI^>7RNANYHg1oBbM7}*iJR1Q_tep| z;Bwjf_-*t`^|mf&F}_)-muM1IhiEznErOYpR3@>Ewr!>?rb53$wroU-^Jqlyg7oWI z2(txgi6ohw$O`SL^HZpbQmn}Pwz{fL2^#THzqK8@s6^<(=#|D~frzQ;?|dGizBhHM znJ*HAg=+Y~f{V;}_ut@KpTX1^HLkvkM^F~TDg8|y1oAiwsJtVv_^U3)estv1BsC#e zoQ9vXH6ES;xw~!j3^oJ|ry8!1uo0IPo6GyVSIbLBo6KPnNB`coSxF2bF8Xuj zZns95ujuX4Qk`O^RXl_gzmwEBp3+7AKi&NmaY^_tuC!5&D)h4>&sb(XI~iT!Kr`d*>H z3B?Qk00jA5@?T5US5sH>=7m)&3ya@P?WObIw|aEo#7=~J5XK6(+II0t~s zR!-&3aD{6IRi(q#S94HuXF>%8!FaW{G}j3fLs;O7@du#?OdvLJ1{%L#GW zJEQfH!u8)|W^4!oLHvV&pEGCbW)(S5wbr!RIMqYIk)uvG4wzN_y(w||_KD*Ye@(aG zvclf5zS&4@Ewcvux=7+DIhkebyTBjI#$;`SB;GZKOx)a>{G;5{B}HpYMXL>7+3Ot4 zUL&q(sy`vWs%0lSy%8RxwB@S)D3DyQG%=AFxxvkk@~hM1Pih9adY1LtnxaOmJU>ie z`Gm-wp$i7h?x!d%#V)VO6$=QkU)%AqzD>5khvXdeZ%|AN4yd~*cH3qD<6^-IB+4}X*Bo+nf*O2{I0!Xu3MfJ((4V~EQ%K!7+soxl zT}j0``=wFZhVDC`rgCFG23$Ok``LtGIFNMRV^rr)Y&UP#?>2k1=u@SxH~fq`=Hb8t z@8bNg1sVTX1kd`mvuk#e1eX`L3Ue~AzGR<=NoScrH=c}q>Xy`U-+x8eX|0kqdigHN z`Q>N`kf3*8|0gkUpR@%-jZ8{(B}$Q9M@!nE&I($EqIC;K-qKi0qHL0z+RkcAvc0?% zes93!@w9m3pEwoZpMT3n8L3Hv3I%*3jT3~WR{T;Ij;|}q2es>h)EKzNXI=hU4)qll z^V1oYMxnBjgeJR;bTUO*0J42zkKv~ZO(WE^kw*Hq^4YlbEOysBiw;kHEg-z3mS3QT z&iHr*vHXR+%7^H4pdOJx%`weMsnBr^$C0AdGRd zcGG+v&CuJS789aNIgMuNAv;3Do^7}U!j|<2;m_9PGE-_Ms>l4hU4O()a}?O*!0o^* z&Nuq?=^ST( z+7`wV!)otWV{;tFj)MTl z?9U)3AaUA~3PD2iVx+#^=0+!o@7nwR{W6~)qkubKAag!rm`|GCFM~2Awtj@$?}?Xp z^mDw3ZS&|wI58YDwFDl-av+lmk$pQ{Lrl&?5^35MF5N6yTT_wLh*gtWLtT0Z#v7Ws zaM4Ftx$Y+USuXLcYt?eu#sy_l-C|=uGjB**Zt|>aGZq9cwHSTQP?F=&)*YwdPT$=3-098RD0uA@TG9$5Cy1fpx=GIJ zlaT!9S;&Q<;2K~KO)3qBz8b!8r{u z234cA6R8xbJenJmuaCZIi1W*LxesRCc_P(QZuG|RevOGkUy(OeE9<1wZs&At5cV|{ zr4=WVmxVuI1PU9yBzQ9{()pN>K#g)fDEX*d&_ZU`W@$G8pyz|c??H@*pv$T;dldCbH1FFZ{iXkgQ zoIYK}1*|6E&J6FKWjs~}lkux3c!E-1sBwz6JsI)9S-Pj^&CyT3(gcd9U!_$43irnM z#t1adXh(HtgwqSLsbL&uVWU7#P5`V2Gmd#rYiTjkrBy6J3QFK_VILf5 z!a811invi<__%K|$@5laJG2E+FKmP8f-BJPCuP%kWB7Bl7~U;RZnq5G7$*s4gSWm3 zuc_P#)n->&i+#365B;iNH5;KztlpY^F=N->^o4xv#aPwht@)R?Pc+Uo$=^`x7Q(lZ z-?Q`q#JwFvK}H>PvriuP=R8Jto5@Lbip>3=XNtRE^g*V}cWP>gyL*+j)nO~7%F24k zwtOQuSL4q>>yIWE&y9q<(v%F?fCzY$J*s)Qxj!>~@#%-1`hw`_qC`q(`{nfRkX77Na_w&) zn?>g#7BpAgDgK=p^pOF2{X0~Lg?3}Ayd@uQi2~~8ltdZCg=01Zs8L)?t#v&F z>IC^e&40X9ATDNzBow$SOap;YJ2&0{@#>xZHuxjC#nRe%Yva=43Qbf9H{-1%9lgqI zjenPZ?M05%!~3raEayfLB$03==9AiCS9Y}yXBh}O0e z=}R2NGi_Oko#{WPQ+zKUFgyrgrG-_las1gEfu2MiIfVhbAcPwA)(`QQyJ>?5f-kq< z2Z-|35r6oWJ)I}qwl>6As`!VC{<=~!rhv6$GOw#-53~D)>k%j2t83vlmTW2pUhY0_ z!^2;Zf9bK=_V+d2wAD34u&3f5t+It-ZfIYQOldaSKy{2XC(%dAJgQ9fj2xy*^@Kl1 zV0Sp~3ad*Pr5mSI4jw~@TCqjcN)@A@#xB%pd-wV9vAq-fhmQ@<1>^|sX`#N;87$O7 z&4w*&vUD!9UFo9HVP?S%LHfxi9oDTF?W`D2P2R(cTyD)to-&qQvGdZFI(&}cn~uh= z^Bi!tN3#CkI1xFuecpeDo%cu^BoXJ&O$CemOiSjxZhi&CLq zfusco;N;6_8q-{bMH;=1oPCytlMWSl?0&M|6At&t%8~CSP7hc7X@pfbv~7x$D5$KH z2-#7R(LScfmo+b^CqyvDCMv&+RgFq^Vv6GjrR^N?pxYUO!5g=;@vXYg?s=~Y2)08m z5~Rj}oXFC22mi}O^Fo3hp%9ZVcJ5B^J`r{234QU9f4CI)hR2S3e!#d?Gi)@yea+zY zzs4Iml;CL!vJ6Xbi=;sa4s|{1VPofy`Wv>66_~tnqvV(p+{mfh@-iXGKey zGs-57d9M*?sR@rGDTS_mC?*?Dzng0Q_WQ`8L%EkQny>R(xioQiklW~!^jsutpV@J1 z(h9*9-Yp)=f%;pRfZ;8)3(?pi+KiSmi4o4u)cTO5mV~Hg7R00fYwQJlpQ}OM7>(Fp zlV<+NW#xKWY9#5>be_#MK*xE!ZEkJ~%p6tNRs#^LT)(tj77e!_YHf}`?UiCHR6teV z;V<+3x$}MSIdyuur!95z)0imCYFv_>;CWshF67|HpvEIQBLm8Rw=5&17>4pVfYmRE z=8H{SP{{&lMfKvt0R~iwi;*Bh-!OwAT37YwRCM@mMcXw0HoQ7@rB70YeBXfr4>0bS zJrr{uH}unxe+7mTJruh`2;-T&!lyzGIkI=to*`?p?yR=7)l7O=@ZB^G)62Gla5N1n zxHWy#wqNH1FRbQ$U$aR6zE;ZHF3Gv{A&*2=1gAG8;lXEJx}IS!Mv2EFHLAgW$wN3F zaDENS`1CxgkbeGK_xj|TD=pdb(xol|Y)nzG`p$90<1-EV2W7>`p@{kj?$$$ssk&N` z2R&2z2|fu#MC3Rl6N3NYR0sRB9MGO5`{t2a?$i>nla__O4*(%PJR}&NBzc0*BqAjj z%;?~g=abajUhGLex`ac!6d4)*!Eg4$z9H>{UxbKX^xvS7qpAOJY@}-@C_kmzDHg5^ z_xX}gwM0C?uj5)}WW0QEA`Gic#!b{8rKUf19@c-zKjAUthmP z=dvtiwIAi`e-=@Y%-muORj)bjK?y%n?qv6TP$McLMc`T(ktNzP7s zdiH!b>bZ0I-y~Jxyga6F9kb^zHU*M|n_zBB!h1i^-m0o^u2>Ccakqq|R$ssJ6{6BP zjbbORRHDcLCE%?wM6^wzxU2XJ!5Vn)AO^z)8tj?I><(!k)Q|AtRHkn$r7nIK(J}m7ivrE$wFN{u@bg zxh^{e?`W#os`>JY@^R+PEPHCTuG}<0&otnrwu~z=LKJ2>&03$b|ti8Hv@yt5(-}bze`uw+%+n`~cZ%|mSS6DLhg9d#ecOWR*i-|F9;Gvs-iSI@e z%2a`MmQ9lSy@Ti5l+B5#b>}FAT9lx?7F-HsX!Tb#`eW%p(yc*k?o@l*JZo#~oG0J8 zpl#HSZgWe!kg2P|6yImr(xiO;%9W!`Q$mQC7JJ|k(FYu>`rp?R+BITYMn7D=xTsOb z1{?+1&US*#xP(x_7b&1tr#7h8gxG7#UNX8*P@8Cs(zYN?h&{TjZWEAgbyGDoBX693rys;myWMFTuH!3`th4oBYd52<8Z~sM(z9 z81MEP)VB@$fIz~dJZeDtTflAE$+FktdeX{xIU+)YzI0ph3BpvC9f(RS_)V?x&>r%a|Xep?sR+V5_y zm3%gzBtGZgu%{ob=THfc=ZmIn>zbA25Pm+CXKew0vEYACj9%=SDkW+F{C~+swp$JDJro)cU#5_74BX62YBLO9ra0XfF#n*m-H#4wNr+|(`g-3$jk8)63(SGp@jG!{?;+8)@$ z5d2Qwy}=6lmy%qgZ;VXsUT|2oaiMq6oQ>Ad%Mof`uIARcPFa{2RllK{ScD+GOPR)x z&dd#$M>=0CRY(LlM0#i5c`+JzVuxW{ODAluceL1LGOd@XYQUQG9XlUHUZvImT?h2@ zGCi2RD<%cl>Hg;m_R5xDrZ4#(+%s-%r7i6o4bk07f$UqYd69-#5+7qP^b6-RH%e-L zgx7NWt4HjOVbgG;S2#qe8e2G`1$m1XrYzhCkM^GXMLaqCb9+z+vV#-AxAvk5fTG6! zzMOG~V5e|7bmTcB-hC;SnxY4n8Q{A!@6dfE-2yAOw#_CUTWWhblz*|o1R+TEPu$IMzeE378aj6tYHmK;#qHsr?@IU8qCzK)nzXxQK4u>)A4pH! z?uY{2ew%$a%lTEr?e$K@-|$)*B&%pFqx4&3q|P9kRkL)Ge&vy!&^uaGkG)ghkP z?e?VSDQziw=EZEI3TDc@WM(V}_qx4{1&`3v+o5Vho6nrkxju+H=~}TVrXe51_ipAF z1qkhDtL|lkH`Me8t726P4sEIG=X}cod|qdsp4;Mo0yg^(y*x@N!iF}REd#xR1Xm0; zhu)JfKay)Q7`?e#4;yLCy1BLEwUGxmyU9fMdBpEdJWCkgkVaJ5Jj2+d3d3JCqfHQ- zpR6AuIhXf3Q0a>~(J{?*>_3~j;lZ2amQYylzrdQRV-X95$7w)!)lX&Czsl@|h$$%L z*nFY#0l+Njg`96(GiY_hjd;}H5;CmxerC|3Lp0LRAT;ca1Av6_+B&7!m6t95Y9r&J_k|D4PbuEB^i{w;7fj`y+Fm#;9sUbeQt)`)-~fg(Do zH3iFkeO|irF3CS zRkw>{FHqFCY?^$FQ|gGzY4SPtTc#6qx~PSSXu9_TZ(@9(Zp+MGEuBkP_3~Y8_6I^6 zfK64u%K>)rLUS>GJ);1MbPJ%JnDbXz^d0BICIY`d(pD%jyEx(<-u$TLi_R22@8vH! z)TyRw2ep9VsvwPCftC%wV_WKqsY6TL^+%_2CtOK&EMNS0c2Bl6rOUzZZ@t*S|E_=I|Lp`m{C%0kCejeR zQsm!xM>v3D>l3}NuHbdN@%jjUNICBPi$&UtxG`#pNJK040WRtAe&)jYf<-n*foZ_Y zyxhD#2-f890=le|U2x-B;zz_s=&jM`iCqTP1unN><09o6Znf z{g$|`sDk;lkqpqBMFpY8P43}G{hVrvA5dMRRxP^I-Vj+-U@ZIMTT2{DDV$0 zC-juWso4mBkatBBxMZ;qf7uJFi@jD>;6vcK7S~VjW-ftrJU@@dKfDO{Dx+pQ&V9H~vB64PnELowWhC)M)CPMLtGg#reP*UpDnYH;iwJdcFc`Vmn;Zvw z+H6Bf`Z(mpLYRCA3yLyYudxwX682&aq_pi`WZ8Gqj-l`cMl(vh${jDK&oExEaSkL` zt>T$BVq3+Lkw4IC=7X?_S#g19sozI+3juV+F?QJUCNjqYV>JJVK~Cj)qx-vyKUOS# z@`SDPcwKq=mfEhhR@O)K;o~_Q+2v-s0bVchZQX{$Cr{j4|(%?RS#R-y<5Oz)Xe zygmQ}EElf;b%Q*hDtLWTa%9%{BN!rcLzw$gw#_bw3VK!@Hsub!F^Co9=R0rehs+Ey z_4{eNIkiM#|LwD^Tdi7-m02rMwk(pV#+*Kw9KIY02qhp}wp6I-3vgLj38`-?v}Zl z@&5$aOu#V=c~g8aq%pVpD!}E6h;yfQsiw0Wu|;kww&tj+^69DL>QuD1IHvhLCBUYF zr~dwjBiEgd^JmDr3@5EEr9enH$+w+9e340t3PM6fOT#E4+y~(uoX+I!SyN1B4d)5m zul)L&G0)i>AD`{f^A98>7aa=22hSrOd+-JO(mLZrsD^pcIynA%O0u5xaM!^X`jvDN zj^^_O!hC|TPo`?xjb86{)cYje39M_i!bIOJ)WMas2b0S^s{>M75oU*++AqH#obfxs?OU7 z{(GZq^3CA}ZlLLXtsL&VMjzk!Ca<7-_#gR%|8V9uO9zY$o|UQ{-sb33ThY$tYayW7 z`UyOm`Zqk{bB_9@l17^O^11zWn_ALB|^W&!Yjvm?rvaN^6L-H1yFO_eKc*kNa<7G`e@XE+;i1_-Qt&vk1BBM(7MJzrU4|HvC7lMO*y#{7uGA zsN!m0NB%?<+@~1o{AM;l&XY;}PfP%zcvo=Dm@1FKo9nnhef|AZ%_EiI%Co~XR~r+@ zK$l~q%A;P>*s<&@jrj`wL5eIfi}W&X-pkT=uy?!{UNjAz)HjBzpF);xTpx?2eBmah z$s9NRYQmoJgm6#6Nqfx9a7~N1kBL_H(jo2CT5C)s%Lh7N@ zBTyrTB!0*o!}7F_eY#V3yFxI80&jKou=PL@l@*T(LQHVoDb9%hq_$>71vXYGH{y2X z&}l8NqQejV+&|`(5d(yKp~E{oqvDKiDmQkgUFGQA&KD*7ov2Q1f1u5D z^vj~kPK$L!+(>u~a((r46G{%Gr9-?S*8J-&TjNhyzmN?-|EzG0%NPd<9Ybji!s^d% zPc4uXJvPLkM`cIgW}OrS#Ly5uyVHU^=x-MX=q5+L8|dxl^_{4&MpVP?cDng%36n4) zZQi~D5;WoWV_oW;tbb+6Z|B$+{MTXIl?!?8vuPhInz>bHH8jdcO8EuPN7tt34;L-+ z40R-Q+%!r##snPlvaHMv8Z-_IGJ{QD)|G=D&0tO?sI1tc`?7QTp`KQ2vK(SU!{i=j zS@frXQuODO_hN+}vp_^IIHB;7XI+5csrq$%Fk3BpK17zW@o!cO#biqz&A36#f*G#B zr6RizWvc3nlpP{vFLo{VF^Y!m9Pu2z1kG4R;(-cl!(_fJLBY=XVgZ+{;M%ihmM9a= znQ1FG&g!D`Lh(Pkrpv1vR)QVp$vm5^&+vP*%smWF~ zp4Q(32&Tuo%dc~1WMiB&pM3mmDY;zo>#8R~2)v|=VOTCxD24R^>>!sDS+nP<6R@o> z8!rpSEjEwoQ`PV`0Vmewf|F6noXqUv$xFUQb;m?L1436q3l;v+eosgAijQuRkEliz{sjoV zk>72=NVURPeJaIPFf-g~$wAdEShl3b%|p35U^o9lj z$%N~j(y@j^Ve~B?A1ZH-f)PQ%0Y<%#xSJ9`hCHipXdGg6!p8>Ig_w8+acjjx9gV!w zE!hoYrekc$3Fwezt}n!Js-CGs4o&{y0e60260jS5V49_Rr`GR9qPk6$g1_v45z`S9 zE6Fy-`K$h%kh8a5o$Z}&<``xgTEtKld(PQxq&V&*v>Nq5F)!VSPe4@OY(3mQA0Hk2jkWU zvynPebk){oq%}1Xzi)LaYJ&|aUyJ}#Y@$cR3!k9b5MHriTyF9#$lIv1PEybOjf; z%AnZ(oHesSx{*upZv*|DsFK)%e}ye9WdhI!h-zHcIQ zDBmDYF5jtiL~_%$KrpB?N}7X@XbIXm&&B7x{YZp11Il&5Nd1x!GI>1}>+ocZ;>l%I zy>bi=$8y94kaYEX_+K;gl3X6w_f=k} zmg!RQq#LP$K)IeZQr5zGbC9P6CqdIbP8hi?TV7irPNm}MpT8>!p-U^~Rws`y#;a$t z_-s07M4G|R*2TwDb$v
m+4t1Bm=Z-Z(NoOH$6x4ld7o*o$?7G94fV&A?U(9DZ6 z5K? z%^1e20>}+kg+&F@9}H!4pf(emS%{#j28F>GHkqWK!SCF^%1t!KudjLAp`$6H zC%l(KUo(rmLFrd6h)@?W=N+kv+ypoj%1OV8mTX9ii}d#PGfaPr%_UBGTe$}}EjA%3 zQ_N2DXvcD94)lEXQ<3*JZ?d;t*onxe zf|JLz+}rf5XD=HmYF)D(3|{^fHo8gUj4JKU0-x~!&c=Ua!BJVQ%+l!WQg?H3=S=ICH{eI_iJuiC&J6Tgvhfy4gkFjk#rtn7HOg}P;h=%;wmu0 zm=fXneEuK`EFhigVxK$wGlL_4%h{bP=ZUoh-tz(d2bFB?@Zud%J0kDP^Sk8O1 zaYxyaf~R0U#r+j6t#A+QQoiYWFX4*Sun=dmwP087Gdi6%wwmhOAIM=(6Cf_qM zChL02I>%vkU|SnYEr3`DzV$;S`R{u)?2gis+<`oGsIOZ(PN~aUg>5|c$D@|{-n?gT zU}lE@;nb$xU!4IPcvac9%@~%WjD-w}(r5=?_r?xb{+Q4u-FT z9@Ly+2$62h>7iwx)}H(|uH^S#u%TgCww@%m9zByb2d&k|WBwFl{=+G}nqWD&mcoRF z`mDsEBd>cNt0_(S{VrIR4LnHj_LXAv=2im*NP!&4pPbxk(BZeT$t6=V2K|R4b@1mA z_?62Ja^&V*$7fY8H1;3|M-(f+S*W=>4PQ_XvfoWh?0<_#_ZA1Vb=`B6#7i1^2n35v zUDd49WM$Qn4J$C_o$fr9_ek;^3X}dyYWi{iWpcF(Oq_~C#nTTLe}Q%iE7i>Z|G(dA zI0B%R+F9GDb&oO0+;=as1Si4oJ>A3FfvN{KOoF`bTP7D#eFbmkN*P9c099!0NUsc4 z;3lL*_As_AoGKhD9Jk#}(J@BVkR_M^{xRp@DowPmHsoN@x^#evdta0elXp)v%bM^H*bVZ7*QAUH1TrmArfWLsnH{ys75 z6M#v*0i-$A933G;Wrxf($cwl?XQT?#O=xOfeo@U?zM3<>>aS5x(g@P-fultaIm{8z zTu2VRK@OdT-#LXXfm=dgkLJ&s>mqF)i*Ev{Rw0rs^qg_J5>tZ(;`Ld8t+*?)Xyc7W zQ|JrmP9Z|MvQ-opsrU``KaVC-00DuaIR*PR8K5RZ!e}s%zs-d#Xtu9iMH?a{`zJ*E z`eVcP>DuGpKV2n;@F$0+t&q`y$839xXMW{i{qZy z#_h3 zif6tv(PB_*t3e;c)t#tuf=7ix2ulTk-SuFkciG_oTAPA}TP&wqs8z&m-_(bVCkx{_ z2ZN;e7zGskV~9JdvH!h8g9_7rTBYm1@7c9zzwN+60f*mzQaEbAA%1>L?w4mxqE$^R zI)csLp23mMH^KKsVU(^gT(B!Fsel75jod^?#`)h9-Vye}XaNIhPn-CES0K^D4ZJRZ z5M6ZqJ~?h%Ysqd762kCx&Ek7SNXspKX;S5a%-aS`Avzpbje(-6hozhRP;G#Psxtru z+lED%7_>|$$I7#X&A>=I$-Xk#UGlb{iG8a^XZ@0K$_wBv=M!{lskcZA00m|ls8Fzz zr(;A9ZFeL;TGKdxv3VBag%D(sT21t!t=1v!t0f;5@p^`?`{bS4H+I}seVN;j8tX+R zlLwn;2z}vujL$tO1QMq)sAVILokEF~X5350wX={r&!Ol9iMHAd`9{3o92!mf%nN5f zwn?fyRuwH(BOCirYQg_&Xx)8fp>J+bgKO#%#>L)ho7)F2iJs5tNd7Gh;L?$|9e*H zikr+v@psp(!oyg=`kM?jbQ+H|QAI;4uroF+-Lg>Zp~W$rJWMb|AKi$e7?4?v$LPIX zmim1LQbUB=V9CIbj~w@!keg9|{=x&CbI!RS)7`&bQ_cIIQ zk?;Kc05Hd9u9>~Dh4#*9aTycuJ+?pmDN8m~usava8u~(*wzI1DwICC+Fd~G*f;fI~ zpU#OQreSA{mEx%|zmG<+0IXn^Y6gx91#HK<5xb z!y`4xJpeGWdB$0#-u{qEFt)Ldq9B!%7J4J>sXvHtAIe&>EB;hLJE)mN$8pB<=5I9i zsTWWW_#+Q66wcf9(CB_^DU@U)RtCD#do53dp-CQMejasV)A1>1MVA&jsAZ+R?gA$9 z=j|=RqW{uh**gI{y6r(pd&4<@-KzsMV1$Ne3Jh=x#t3yAAI1hvzCqkqik*24n(v*r z!@i@Hb`}S8@u4QKgWCyJzC-}u=D`a?Tz9GV=?f>b3%vv${@OnOB__|Y|GVZWJ$kl3#U zJdNl#K({ogw=PabH`ewyogk+!Ih3X6y-IC+9n^EaUs9&)^Up}__Hg-$YQjVT_n)$b zhsi~YGtR%j#f4E)39FL5_Z*$7J9$?xle`8P-E*Nq2xiHsy{BSaalN}B-drC^^8ICI z?cOhzx*Xij^Ct$G?(zASSCWHD1X_>Mx4H?Fp(gRr#TdDCH*aI@@IE^rYt4~1i(!+w}K9u2|tJ z;mz;pEk1*u>JS#RY;712CdaVVhTilctZuOuLItFEOH!=qZfgFt-p@Ob-_Hdz6zs(l1M8#GM4PkkeK&h=Te_(I(g?M&TnWqCn&DY z*K{VS+Zg5kb9J@iYjaael*U1(RI#&7iv4{P*lrjRMGJPnSe97W*r2Vcso@9k9dKl3 z%R=S?s#*fTpz5J5QZ}^DRqbXQE=>u}e@@|7*Cw);W!7EaJqrA+I(+ z45w_MQ`Zn*1L4y)?kO)-y(p5$Ym{l!w?r?+!%~M#CiGr>irnWC-2USI9}cw-%RII* zCL_dH+ZuZ6re8{@6JVP?_9)BtK)>9uOh=-OW`gHSB?g7nf^XHs{1;pl zhXkU3B7u8n5)m*ZYJ(mEfTb9DNn~=Oyf`%Zbx=*<(2~h6;@LK zN8@Po6IhqDIGMm9i~-HP<*AMEB11iXH?T(2lN~15|60KI6Ligs+DAeq?O@Gzz|t@q zWkLZ&w)hJzb@quQJ;GDX;6b-WFuur_DQwZ7VXu9jU)>anuYzp(hDfG{3aX+Gdcg_ZbjZ0| z3bef@x@YU|p3tP7nH^bVwQ&?ifzB#Y2tx3)^kprE(Zgq(yEx^j`AP2`!H>XGN}7vJ zOA1lPZycLGr+>E8BE7L&Y6@}>a)-P%c8}efBZy&A`3>0IPW&h`fBcQ4>wEK1VVR{8 zglVpVYM>gy&Dj+P~woY#~(*g$$3)CcHQQ~>jVr1-L< zn{IZr0_QHnniT@A2ELo*fjNurrV`pwskc)wa&oBdTO zBr)V_*r%`JyLWE*fSJa#StX)y0}&nAq-#3)QbeMqg*RD@EV^Vj-JxwEJ($89Q}U-; z;imckPMB~XFjsChMh@TnJ`yz_Z_o%J(1Hqb8AlP?f(xcYyUE9RJ8k>a*ai7g)L61P z;vvDBv+@&u_T@`!0>$>B!NdclHD~>qH-9r_4+^YAv=ps3*6B^RTGLm}JCyAc&-Ns) z0GEnLECKKhz~f2KWwiML+^XIUku09UKA=b+3+&QB&_x}b*$|v(9^52ehIDV6TWprtuus;-BvOauIz~_oh}Yp9;UPbR3WNH7`g#9Wp8Qco zfori#ro!l}#rT0`I4}*t#A}qaW!WUE##4;jDd8pbQ(1{D#wN7V#oU5>J7>ZGu|hZT z2lBN1p~UPgC}2AaqNF+JybAc5NZ$Hsms_l9cm>Y%`P^5~4^&Xdt;eKZ?>6VdX1ZtM zN*(x82#Gd1k<4_;sf{yjFb$WaCxbilTdh;ow;M~36hdG}= zsUx@+$6i8 z+-{-Ehkg#{B;GIQj#JSC^ww3*O!t%J(;TI9D;~x#2mq@94Nnet(}DT)8IJtw)a0hF zxe^5mEot{4{ymL**#D+qCoqk^D}l0MRCP-8 zce5-|o=3O@(D~ogchn>IGfHj7>fD6ZCp)y^U%sEZIf?0>ieiaNk;dP?!FnV?CMb~; z)wUUbuNA|a(feYoJevCWX2F7R0`@EC`rspmqQt$z#PmRAEC>cKQF|?XAArYQJdVP+W=^Dca&L z1&RkMXo2Edq(Fh||d7Bu5Sr@?4uD(Os0t{QeCbh_?pPFH|0Xvy-BCodlT|>e6J!6D2RO zIidJa;MKH5h2%)ol=f_ubz`XM*CmdPXQKjgwS=0yn;KyTAu5C?p257tCW8hWGcK!k zbITSN58EtD?frgyY%?l#!pD9sKlmKkk@-35YnjPA&Zg$&p!=Lzvvt$eVNQCf^HH)9 zR68FCfVpT zmh(JGJAa!0esVUA9H8f~)a36M9J4ks*^cx2o%r)e>>+WgDvgq9guY-rmDLI1)-{G{ z9KjZqPvc`njqS;McAs@Q71G6z;yMHP8@3xO^?mCK^H??v*Ic8zyT~Piqd{ugW8#Zg?DU$_<@tCy%M}Z`?=fQ>a#^cWjQ6u8z>8xmG?FwZx>$U%Vqu|tHCoiP8rSt| z2G9&HuX{1W>-3!22$;n$zOxEK&$(b%*`=``>g@= z*Rl6-L#0b%wSCfPs3E51z1mJYFoPwrvlmpfZ1waQYAFE`DMtCSU{UN$-DF^c*O4IN zN;$#7DBCHlCWF}gLn56Y1hW9b@^PXhq-GW6b*gUaEYz;)jn>&0xH3<74^2vR@h8?x zy@kGOG$nA>E?Y>pwg$u})fM;}jLb;}nA%1io*qu=ISm@uGN)M-HORU(evGT-UtZ~`H+$)!WOAB%&KLdy z<<=~vOImm4HGfWT7gE(Rv?W*xV8;_R7^?cKrWRxWZo3*ZmsAFmvO>A3MerXeo10A> zX+_L#ZXq38-NVr+^T;TGP!zNk$)(@7NDc9(;?B)z0D3&YU$2)ZsBNuOR+V5DIIY>blaSY zGB0PMQw#oUn&2^h3-!8O`s$ zw6J;E9h==}9(yMA$reS}_uOl>fqz}FIgv48;h6B40=Ty^^z%ECb@axTfh@KPReF_= zt}iijw4&{HbflByEj!s8dL%G5(*6KjEGQWwQI*Cz;u^ByYVW& z^iYv^;qoX~PE*!{@PLUqHAo#?1%d+=>MAZ;9BiN!(vl)_oe$^~35&!2<-VHNbTv2Z z07N?Cds1FA5(0;EGI>K}{w5#{UejofE7_6Y$;rx(_D4*SzZU9nueU@doWNW=3v+_0 zCbn18A+G@l+KwPKPvzh{E%YXAPR{F6Id zpzK1mi_6}82V>P2R=F?6hRC7D%_K@evpHz0B@^%Tmg+V3;Vfv)4xhD=!s!qO4xLtG0>@@io)5z~25}~KJz}!8$(@=|dcmEFLMM7Kk zg#OK7BE{!FFCqr#U#soV9loLvls7+p_{7I2T58~bYnVdt>=b9W^)KM^{qjnNrt_x` z^g9&b-^4`Zno!k2aK$LGM^pZcaknvUX4yq0))w!D!53V#K*Owy+1TyyTNG=S|J53= zPU&mOTIzQzbUxjhPfDk}C1U=h{M7kbGG}yNQm>M-w5pao_49V}8(!+Fg@jpTF_5y& zI;3jZs>Qrh=M;DQHH&GVE?u|Sm3A!^6K(pHXby3(Z%zk*I!F~T)M58!Z(Inz0#_{n zz^5_1DKZQd>eEhBZNm9f#`J2W%OW&BEX6;8Uxlh1+W#HwVs9s=34FWO(5Qzx5SVq` z_K`2XSOZk5lzC}8UGbu4JUQ}z4N`Jfanb4xD7NTRn+DB?8k2(wITd8?0nS%3Uw+36 zMhSchABm*us1dV%QpMarH9<{GeRsI5o#g6Q5$Yt>?CxE97)F}=esa2c#V{a#!CYXd z(=-#lxMU%&221VXs=q(BF+I9#``_5U4F0>X+&b3{|8mu_N-2oN!}zu*a<^pi?X-lE z)-bNTX8Bj&Pg`fjljX5);CRL#P3;TJ`CfLgqxqoWTo(^;4R)c@W0;WxFA*Zho0^W? zogXFq3ath^Dd11T>zkUQ`1D6pUQto5e2-1XMdQrLzbi8Rn00-2A6;zv?o}#N`-z^* z@>JQX+NUqUI%!u&0g<5frC91yh+XrA`t{UO+NMK-q6qq~e->?}Et?omS6EV# zS;cQ|{<7@Qm_FI5O(7v-fg9gMlC<^s)Rx%MO|Wuaph+q#6WM~D2dc^Fr_Co~KVOSG zLK}6C)eAJey_qj8z!;j9fwrR}m0m<1RW){QIq~kxy0nLznMtw9p9!W>W)W8R=x%rz z8@;^7uLHIQdJOIO&~+Y8OW2v_Jcjs=8~b~M4EllTUcbLNl)V#qQaVs}c^0cE_~&1h zt+sQg$h+p+ka4Juze1&-5%SqEJ0P!wVQMUW=gju78(x&p*no2PK_U>q??!J8+#tAj-Uld*J0 zI>R^mrj|A~!9ZRa3dIYgFTu#6wUEvIO7{Fc#oVb|qpP23SJ&T0&Gv71^|cIDS>^_gVk;S`D1e;(0haW|#8- zX9Q%+q>48mBtuMA?6WF|kWYN3#P$V@v?znIAyuc)ys)?vMqr`0i1s=iHBW%{UmfSO z3pKq?9=gHt6}uq$u?3ziy_%Xg2dar-j=`hvJ!!A$^2h+B|7x@(=1_daDW9T?%4DhU zw>reB6JkvNu*)bm zFdoc+HaguWT#w9IQ5MNye9xU+ELcZO^8DrmV}*W+(m`w-^WBM|c{X*zMKIpL<%TZm1Mrlw63td z$m#F-x${+po?=u`n}_ME!%`DD13zu?=E+A}gH9Oxk$!j?iH3#`SF{HX^u*)=@ISKKNr0((r%9| zrhdt*qhXz@(lQ?pkRIt6%oSl{_+?qG2AsyOw(~zEn z%Ukl!Nn+eYY35{#L*aa25iGthJ&XK)fTio~$}~@pS#dI!RjCS|>HV1X-279O?CFsK zn*+_O=i`pks;!~6?4Oc8gVCH;C!V`bsB!q3FF}`ch0+3@%8JjN=&1ZJe?KDbM006d zr@@dGIb^B7g7hCCkkDk^U z!kV<@&`a|Tf752)sndZ8T}TNnL^P4AN)n zegD4p^2aFum_y{i+ktxXs)1*uEoQ47O&>YF9S@pv^LQ`Ji7{Fcp z1IXDNYvzH|Pnb;b0=?Vo?l2x|O@)a{QO!!oNA5638>gPOXNM?;E&l3PsWD!*kgQKF z%HMo|FhcJuh1PiifKW(LGj(fyZy;C{sTz6ACAO>?c<|^f2GBWP*5U`u>^W}eX0K1rgrn^C_De5JoL4C^vwcm|!#g{@WW>~6exJgK- zMG6>t!gBNzh&&0K({gi)9;r7nwcaV3dSUgZtxEHN%6Zru?A$uppT>OZBLQTO<1)e5 zpC6Y?){=%cLfg7ioJ&@w6vkBDi!j>V9qk=oH_ch(bQ+qn{{tERb!eKEICB0r{tZ%s zV8Rl6-hF(?E##_5Wi?Sc?#?n31R(gk$X><5`)?n|ZJi~qsmFsn-UpC6(wWDPYgUjR zL5l0=TzFbH?%$8n`j>vuE6!VAezf1}?C$%la6(AmOl7JlNM1UKEzq$>*n&PfQ2Fb! zuvexo8M(7ImBw|MG5*)F47rMyAw!w%^j4=XQ}fCHKsM^H*c!l5!W?l)g@L*SDBz(8A3pY@V*}EL9EN$T!_g z>JILYr`iOFp-vP_lg{{g0pT2LYeA`MuO}AUy3|X^jLxkUt#$*hbnio;P8%SMaWg79 zp#!H9^0Mz%`0G#2pXk!JwVfssB@OvHt!>@2CzeZ`D7@v5D)wnQv#$n!?X0aj)z)tS ztyFK>kjk21q9uT(+9k^qAsJ+D3Q%IX^5b{^y7?%OD?E_)c?lS#PI;2PQ=IlmcyC&e zq!q87dUfhuDwzFyImh?2%jZv0e#ZG?;lsMao`V`KGJ+~hcd}xc{Q2TPN;Pq1y}r*K zys(@$%9u~TUz{_}HnLif*GYE3klrZ@AfxG!Scm>qRsCTYx4o6fZ*hzk|39zWFNcky zhNuj_tzQg}sRzaq`K4vFiz_BG9-|#p^5yxvPak&!#R~W?jsUb*=xm1hCh5)yI~v#W zI&ByHNJuI$kpz4u6<8_ttFK9!9g8)F8)KL&f9E6L$gmK+13N>P7?W*f?9nwJ3~XWB zp+o*PbK*ZQcE4H(1qV(EB{VF26B|dkep<+0KB#W907P=6qx7OF_AZhJ$)XiJb`Dazm zvreo6bqkWM{}d$86o*~ppCgW4est7d(5V=vyl{7O51V_tv-)&N%F(xyA@ zXoQgPy57^4?iQqF#ZRtcU1F{j#H_2U+3v2*(?J(Kj>q}Zqdp2HZ5?IU3`l+ew~6{uh8}aJda#n{exuUkn?lW0{fJWDzaPac#vYGpPyYuJ2##6x>kZ_B z6DVgn1X}ek89Asv-&#ihCXkcp(;I$!JMXI9$>tQ9C@dXw_wmz?QCQ|9!zz5@nTXb{ zsXU1)fw5RMu?$rz5XG6YO(r#MM*2YcT@e>}ByB_Vf+|F}MSUB;j86zFmLv!B;;Z~eeH3%9jAdP`5(^1R+}(tKgh7NG zY6puNvjrko1e@y2*H(1M_5zdG+}V!t?_Smo)teql)v4&Io1I?$R^5F?C!NAE+rad- z$SbvH7T*-E&mNHVK=*NAFk2`j?ro%M`j)M>*7?Nj=Z!pme)*2WSy+)1Z~NfjxkSqC zx-CK^%EaZJ$@@SR_@PhPU#B6{Mq&^(4dKnsFDaI{2nKq zxoPJvYynHWcBiDp`9Zogag8Iz&CPzkkxx%Dj*rMc8;qxwx}s=tM#^DJv~DUpZ-vyc zTE^StOx#+tk28fOc>in_W60a&XtqN>9;#DQGg%n7l797IZ*u*47S7%wNwIjxEB{oB z^)aC_Bd?tXyB%Sx#&M>PMeX(HVtEQ^LrEt{VW0T+PWt!yM*+n%ZF*_Db-UYIqbj;> z>SZF6TJEYe98r`ZHBX8DD%wSVI3KHNC$qEvK*F5grL+n{EcA=Nq8T@$(v0*y-$|PA zgfUzV;f6$nOy%Z$mkS&SE}j6kqpkab-GCPNndMQ;oumD8v&=F)kBF34c}Cv@NhJ2S zGVJ(yoPKM45tDdA&IDlmc=PBxg2jTrMX@&4TUUD$FGmOMP=9R^<@2Thpr3_azfGpKy{y;$-^n@9!PZ0M5@MaxkT#Ze z`=iS))5xAIvoeqJjg~~+m+74tl{E2Ki&p82nnyr#CKCwV>;%}!=3VmC&*>r=^|9Zt2%A5QjlYzVUB71Bxcz-V@U> zqm+!+5~GFdqVkA>(~Omjti^3BwQj;v%Sb_R%+15k=5O> zo+N|jvdXu>oS9O8S!l-A()=5^-NU8cyYU_nGsVlWVEqLailb-@wTQ`Fr6LbxRx|8c zKVEA={+R>*Nka9{tEMdRmsLaa&9WJZJn{OPe(qvV9sfqBPYVsa{}6|m)WOhrBc2dA zyOW^1EWU5LQBM~G-W@)X9BZZR?;1zWan&DiMyUOYa3Q&izGApf4i*ZeKn(%(J%@fp z_PVh)p^QDqEWhmZ13;lAA!sY{JyaG z0kLQd`h2;ap>5?9Ht>3^v>uDcx3*l|x&IeN9o;p9t|_)ku%tm*h2^ntGrBV&=WV`z zkdfzwdsr+YT%Gu9%Ty%!G$_-H^hh%eR@0{rz}ScXfDEqpH56V& zkMs1UAF};Qpw%ag_eqR8SM)$3yINJM^wW3yJ+EmUQ$jcl4c`)8hI&Z-RvUg|;&tzkF1k%sE&Lu0|z!GmylsFxD`Ry9N5Z=yX%YbB4uzMrl|x6|zw zvd^!xF3EyAhXH^Zl@xcNI&elw`)=WOGhgDSwK`8`RMD+jPy6hh>mO|Et^5lE3<1(D zJxx0+s)J3vG@!;lZT3f6ySrK+|HPWvl)>1Vj$5}f(7nbl!})J-A9OaXeDWV?p_l`J z#f^jSZ-Zo!PAl4f)>>I8ScbI4($Ye-kIBCXo8)ca~R_GMDHb9>S-? z`Rh>qP+9)md-kG-uvtUr0t=n`SActSIs5}EOfEgbBh%a4v;HUKqF81~_aY_3ni4hJ zgh-h?eOFM6AiTY}2b1T5Suv;k;}=azPl~dBx{z_pu-81Pg-C-i!vJsB9E!dU$F>Xt zV7^F=q~vRN?02@?9X9QJ&yQvx-tTe$Pd@^<0|;5Jjr&h^BbRLMjht*ss(5*zZB+I~ zB^%9yPv*6vr0RC93Is=Yy7~P8qn023U{HyfcbLP2xpsAl(~n_s4e4pIFrXO7SYvIk z5?~?oZjLn&C%AL_=4X8adt{3DVSfU~-5Mbu#B;rKcbey^y*Y5r* z<8)=3b7flGp^|H1Ei>Nlw3GhZ5?dC?+H;nt8u}CH-o2l%I(!_on-bvty) zq{WH_hpM0+&)bn6X3;0pwT2lP>B-6x*A%)p3m5~3C2r4tnR(a#)t8xwx;GbGzr|WV zxTk;kVz$WKFER{AN!Frsgat@rN>v*98_M-k=Y=2H@EiU#9I&a_{3V@qDL@?8Z;NaR zbR+2$w4`~Yk_S-u`sWhNB!B*maL_K1P2b@i6NhC^q5}Wq*hm{hfWLv!GR}R}fy!u_ zJ30sn%WH{PjQgFBes86srF>$Wxpqo7dPa9pH3MO_j~S{PGXIR# zf&x?4l>$Z&?3EkLzyy{AyJ&ds0ooZ>O{RXLOZba z=p@P#4&5^Pc_z*9p13f=&JGzc1ov#;*%xzRAbX0=}b$ z$Y)p*&l13>aj1)9u8Stn1Pu-FB#c%Rf!OwET5`{GBMmVNS#3$c+C#bD+}0IJ&|2^x z=;P{tAXi7PiE?GX%}(7*nNLl0%h+ZoC^jyLr7O*n#6y)Vh!G+%@S7Rc3XSggAGvbZ zLNjxFDN_3>avb&%70kxcdy@#nK)z(aLSQgZEM`*NQhXEBxb<=7N8OwG4C&paS2p@L zdx?PxfYzEUqGN*-R#rKMp9bf(-is+>R)l7CJd`!LB^NKxATzRp0j)eH8jT1o4UJCe zsnn8<{(PiKymQSm#})d2)e>Of6|fwTA~R(EaU*KVVqPAK(jHd%>+r`GoxcU8uso#8 zV?pAdmg2>8=p>NOzW8I4ByMs9rarke;m9%saH0l4XC5FR0jTBT9gq;g8Yz|$fDK$w z5q1>7VknL$5LS_9!+kX@fkN|v$_0mQ*urwi*$d=2+Fjp#?E}Vnd4NtfcPg&ZXQ`+K zC9ApFI)9E!o_vceU1h#%-d6CU=U93l?gZV^VqJfHYPp5;Q zVnk8uaWgWPEac~Er$VRyI<@}YOKCYPw?ANNZI}?o_FZVs|I6hu`Gw{l#}d_)2fjf; zLnK93nz1A_cN)QK-47M%kLdE)k&__girb>DU|9H@;@2oOoopb^lP6evC}&zM9l0!X2cN$bZw3uH@> ztXJfls>c}Fgjb{)mG&~O3nWSVNsOZ@Vm;RRl;3V*x&n<6aJxN`wO*+`{c>zNeaP{K;i#)|0Cw6F~AwMFR5JCgI>Z}-3q=+_@ z8e=?LSyO~^YrsCuK3}nLK8o&6om81SIVp(S$s8qC>v{22=AP!hRFU8yzoGm11eJE> z+lgZC!k-Bi!6?itvQBI%@VsvNyMvratiUtcI@9^X`X5NOp`GsS(65z6raOj5QstwM z3uwFR@_X*(u1xOpx`?q;*;aAF7}wH32Bc9Iyj_IO>VR^eJ{$Ac<@(w1PmBHe<-{t2 zT)}+D<@xDDzc?uZ8kQB+t(($BNTvJq_;ch2{*Z-f<_GCBrVGI{{N8l$Q-QK{`z~r* zX+p_yWR8F;^@U{m+~)6g`62i@P(_{d$Z*J-nXuG3YdbnTK+=>9NnFT&RU~{ARoYAX zP+vTgjR2slw-^U5-n`JgI$|*+{tH=B&HgLIzdBlkE(hk99$K~E?Cf|4akplRB`T=^ zrrWF2qWePm0GE7LiT^+hXlOrjpHda5c}7#0_Wh`v!+^`z)On&Uo#c(&=r-S{1bU@# zKH2;LJvo9$M|Q};Yr@$`83j_h6A9E6upBqo6Y`95YS&>UBJ@8Di;<$J4F98C+2eCs%jX2H9VqzUxt1J z+`%B=X-f&A*&H6AfB}%-Jwk`X>9!<4Mo}EHp%bqOh>Z)ocf77VGHOd~EbT2j5;NEN zanP2V6%BtiSDkU(5a6U7(;6l+gUwbHMAFAwD8shM@lb>~1E!YG62$y}Fg+=WzkM+* zUJ^R!fqfTR^5ugJTdYh1l;oTd{)^FCD7Ncmk=;Eqk{&hs8i-XkCwau zIe|Q%`8yNSPao1d6vbC}8&|h2Wx-?k09oqOempN|_1786QSNT4TfyzG-Bdvw7_uHa z{||CfgMU!wAs1%<#4(aC2FN8#&4C+B_iwu0$YEnMqNFfSTm)4UYWNz1yUz5|B}ep`b?*CzeHF z3Kvzus)R*hLhi+(xoRmfqlY>#v}GM?F)}iWi+k);F$4rAd(22tih|oux3iX%i+jzMxz7$JvMoMc4(V{Pwy+{vCcS%D3mE4NPhwLw_;_l@#Dj~i_cmmHEg6u-${4yAOK#59%I&VcO z78=;a5YbkJe)m5 z|9f@J_kDw8?~QXt5LM!!8t46%>dWyL1iH^KulV74ExmY%W;{xnQ3=q9>7wX+H6|c{ z#A_*O$Am2HJ~G*%fY%)_3kXCp0=-4SF7zTsKnYbtIIE=eY{H`CUdkLKMaiVh;Yw7x zMs(B={sFj`;{NE+mbNS<1S@FGT1mCJNYrZ^;yp4flw8E%(c?x&+@qgNp+v-6Y7NgV z-5ElJC#v`IG(m6|j`18JDk@IfO*V4ZT`G>7Ai}?KzBM&Oziw%P=Vo zeTZ5WUhpDj-%$e#EAOk8Xa^K20-&PSU+tl-koi4%eCS*h+YlJ9TH=fdP1(TOGt|T$HFg=pkq2`+fdiq9Xcx3t;R-12pX2m45o&>4(0Wee*9 zA;JAYfHOG79i%iG^9XK5f>v3#A`avLG!tlku6|UcM_$Djip0V)yU8UrDVmO`ow7bh z)wp_=t`2(LhM98=y4yTxzI7?HXRn}CRUsriN`VD4lm$6V;6+RrdU;?gMmG z{$GM+iTNOSY39(RgAlc1JkQevm<>wS9hx=w*3=cPty+%FSgtx5FNpR0p#5DhITOfo zXN@5THnjolY@QI3Euji{E!SwmE8+fk+IM~k`5AU_(qJDg9HLjW~g6;kO z#&G-Z>S!Uc!#J0mar6nRy0wj2KDglu@^x-Ne{aWg*P~3>RHAr!Z%;RE4`vI7-1ErZ z8lh2nJEEh%cZ@Mv0oV@TXBhi!{6=$Y%(2gh}30|O3rHU>xlPJ@# zAfAn`&qrg;g8RFXW=GE$3!`$WdueJ)&mQ-n4mffhZDWf zkYN!~c4qJJDNn3&!P;-|&X#+7d)Al0j+||{HAwx6b*KutK+(zvwY6UzyGrd>5qigY z34>qi#(i!tPV3C*@=cl%8E&IA*hddXhIpDTWHy6c#lnC2ZdwAZa< zv-|&kdpV@g@clh3nEzEpcsoA_`cnaO&fdZO-{Ct@d|8s_SM4Cq^xNPTc0?I-$m@qb zvJWOaMM--V?K)Vchb<#mzi_1d`3uB#iN?#FcYJ&Mj8F3+@tF3>kxc8v;mW*k`{$2m z;@yGiQs%rd#rrsa0mLuk@+@BkQTK45(Wyr%zw?pvS# z{K5h4XU3S`FHbSX*}*8HL-@yOB)rIiQKsRiqvd+oJ}acTOm3bInrGu=NRz(|_evUF z{qqI?PcHh+MZLw>s{?f2sROC%0E|V^INng(mi`lz%9V^zzyYP@>n6%=rJba1CN10d zC6oH6+U9+c>GupDg0Nqg2(yfE(G%M(*%fjZZwj*Ty&ir2TG7;7;OCH-mf5tr5VZ=; ztrFxw-xS@yWssNU4)d;Pmyw*{dZ%IJots|5*_xZGJ&eBIx2griSzhX(bfPfIRlreI z3P@(pXq=XLVkB~H-y(Mwjx$g-nsq4r#C)i`Ur@oi)&4qO-QUV%pKp$Kv!|z@j>etQ zLVNy#r|h{LKKGh+=n`PXTmAKit)CD}{PNEJuDs}<{1w&Vt#4tea&UI#f{sKD_6yW4&F!o~rlZciZbr87O!d3fZ?E0`HdNApke+i($S zl?7@1cxbfq(Q zW?GW;=T@o!X=~bDfh_C`&tw~%0>M$EUAKn<#U*Mfe^nEbD29@bo`=tNM6ebyaImA6 zD{%Ukq)d$-)iOMWd~QJK(e6F|65BG={JbIVswJ-M;zGU4&B0$P+g)2x5_LU9K_$+I zoO1o33`lhLi@JZjFOaZ})n5xk7oy=`U`(PIZfHYrhJTK!QoA5Wm(u7xY z*o#1hGsoI^%K^hogG}4H9@;>2XT?i^L#>EAf>5(VSnB%%=!cpZJ&Xj}d^6W-$Wj4C z7~Sy%rLUfE3CLu7_qE~CKVEMX%IMto%bGr@m0NVuwfcCi<67#pkmV6PZo$ZvG5UcM z_K1+Ayy8!?FGYF|EGJo~#C+D?aV^E7@Du)nUwGmk1J;@NQC^~5;T(_7Hjn1|wnWk8 zLi~#sugSFNdCOiK^&1z(6z|a6^Om=K*4B09doA6R{tZk&2)J0+e(9ilqG1x~M*k>m zK!qklW}E`n|K1}5@i^tWY|KE+r-*TQJtD_}?K2g4N=Fj~2&mC(*8Zw%1|qBp?bRt1 zg-?#(abT3bQuS+}x<*_P>_ilptQ4dkC{8@;NW!KGhP(bk@nA`qAE*F4-er86Fz;#ynK3>0Y-vYLRS_QsvAL-6zvI!0U9j}#eD`*vM5fuL2%Rx$ZDKdH_AlBhJrgv>p=UZ@!5%75ys1d zm}fF8bfw}J>klHk)H#u>gjOb>tKJ@nOS3ei7RneD+8!f<1t8gf^Vv`V#+}{Go=u%q z0i3D6bwHnndQ-|ibbuJC`=fh{2IBW2-OPe3tzu9!mm8rXR1N*SuyG0=y>*Y=Kzi5@ zeBcAySgq(5@jg9Yxq6Ha+ke7#K5C>Bl}Pt&XxoBtIrN%n)`dEd8;DtGaqM?+ZPrO~ zVOZF~9Vz;T>&CO0TBM(SkzwdrGak%(;dYQkWgj}O9$-t;I;rBlAde_y{v`c0`J*4p zx?9A5pc+6P188|#D9eh=xvsh~z!CC48TWp{{mQWa zzXP&V*^ja zcg)(X9#zp*$0%C+$8&{}SifluP&^DvUq(BdM1tXoR!F_7mxJ{5bOHrh{zwtTyUc{m zJ4X?h-R}0#PaA~83iD-UX3E}nw(U*%s*Q;|ACj~KjvylX6OwE(R!Ae#ejr9+ve4ca z4{D!U08SVaOkFqJ7bfHMy%z!_$g!u?&rbVNcybx3YHn44O&A*hAjnW)LyRjrp=Y~T zcfSKFDHy|`2E|lG(HD@`;aHF6AtRsiGCKfX>C;Zis!WobIv78`Cq+km<`^XbqXdK z+S|lN0$7o=;9eyFcN`sPeP7aT$Cd=GOUN47hz7)^xDz&+L=wPcm;kt@JM}tRP8VH9 z*T@##Nbwlrr=;~UNOAp6t7We0-_Dl<)P|YFD48E6?)`_g@N|V38#K(}Ca&vzl>7O} zS>m^~Z)|VU463tsR20O=VTe>5LQLW!PfF78v%m$GyxrDBpReIxaGs=UK;i+kr$MQ%xz=DE15M`&*aNoW8 zv;(Y;m0N>x&gadvgAJAd>x+A$YZm`rH8mDBMuq=Cx7bcFn}uGocTzvY8D?s8&Wjg> zxWOuxmR$}j!;G#Hu19!qiZawk_j@Wp-VGkmrJ>_I4}k08H%VyOU#%dAU|l-uF53LU z$G&6tuIMM6CS`6LH^(6{fEn~TqimwF^)ig+W~foY@Yn9x6t>g#KhQsofc)LyA60L0 zUeo@+{g^0n_fET=v3tEP zgQpD1Y=@{xbD%Z*LWBc3HsxvYJG#mD5n)OSg5e?n{>@JJ#3X#G@XHgXs6O9TLT|Nl zkXvQzTHcOw??L(0q?u*vQ%iRYyDD())t z%qg(NB%AuGX5|y3-xBDcUt##dJUll$8EO}`JvMAy+j|5u*i%xqMPINHqxH|AeO#Nm z$uhv1(@zyIWD(D`o*Ajkjtk4TxQ$+P)lr*d$Xu=V7=T5AMIRm{6Hl!(juN@J)_OCt zKQJJ0>p+F)b&ddMU7SBT|KC4<$tQ;BbNnx=)Q1G%O_mv)Q3Xi7f=9QoK~AbD6Mi=` z4)SIbx=DpBV@D;CJKpf{I7-)#Q{@CMjUE!$=+V)|=e#0N=dl&PJn0?ABln+_F2+vP z6W+gYz|Ec1xxdT+$O5>i(h1?S+Z+5WJAVkWG-5;=nG_jpBmx9@Jt2>1Xv<~Pg)GX_ zunWa33VDDiL&ZKC-w5{``4RcP8 zd=8>ZGcE1ZoXwAu1V5ovpCsSv>kSVl{PZYUX8~_F(ciS%$+SY^n|j6igaCJST76ra z_JVq3#%x{N(vs7`B0}mH2qD8$um|($IoN;J!vY%8cedrEdewErJ#~f?-3vvpVD|sKpC8M9v zA8OArGBK&iX`SV_(^ zmV7SB|iVHBlY90^-B$@VAq9HeqD-Xr$C8io;@yhSr} z+!V@5v2mG8g_Rlwm1m*ZileRzqZYS2H@6rJRzdE4h;$(nwYK<+5Ygw%QsQ#fWEZ3T zWR$YA9Y1hP!W$62I1GnsjJU~!P3nD7+Y3%t<}Q1qZ<743+1CGY1`%IM1ZA(th(19u zpUMZ=Cn|JOJPnbq5j-U+NIQq6dXC^R*D{QZZs)+^DWj0)+q?5c*=Df;(tFH%riHAW$u0h&&wZNk;V!yfxjv^;-;M2y(Q>V*KKhl zDq_D))(lM;W*}rgCCGl7?5b!w3GabZinS!mu&8h9=n)W43jDg0Y{npy@~^wml}UX` z_2!Ams(D}8({9t0m{WU}JPgQOah({4#C>b6zSOz|T+8FCxyFL3H@+mQ3pA=6=XQiJ z!N@W}WarwlXZ5{Pr?$YvvJ3vw%OV$WJAD=4ezQq$albBoFa*8-gflEpjY^+Bc;c5E`s&*Z!W z)QD?d<}FV6f*r!Kkm3J8ffUG+J9)N?Az{ERvlCl%J_z!Bzpht|VBi4NvV6`7e#fWP z5faq1zBv?dPT-xWqRi6nAh{HjM{$E-JX8d*JBqQKCn3;rA|1=0a``TwP7()hJ#dDr z>TNl_TC7VJ$kYe{Qxh-Il|*u}ynp!)>>RE)&BFR#wr(IW1mP{JKn!Ar8{2Fv1F{(J z50WmOuxvG!T|biQd&A_vv<}M=s3<6Q?&GG?t*PsE3qOdZ?ZPDG%aG7M2!6K&B>OZ( zlkmwgG)eo53=psM$_3yy#+ANT%TS$Tz5?52xP^KK1*u8jhUmEcLp|*Nt<}Js0{B5K zkoFFbhsoxgQ^>HOLA#(QYHP56yoE#~>^ZQV#LsZo6BzQFGDu8V^~GxF5D`fUfoGl$ zhx}(_J@$~W@9Si?sqghRJ`uPMkSpPZsNpJ1Nf1@tGCaWzO?e>J^RD$KQQQkq?rEHa zfIwb9ct<(EBUr>&VwuC#-&d<>V@ESCta!m19tqzJq8SVSxVug%gBN2vZr9}DiwIG|+b-J%q??(&%{{)X z^z`FoyjS1X-m~xu_RIm{AZYVH+~rVQU9fNGZ{ir%60%A8@5wpWofnL# zAwA5<^5WlNN2%!ysQG7Z2rN19g#@ z3i-1fgj2t5!lJx~G%zrskvg~`(zqPE%-%53zLX4$oG`DK`VqX+f@&i?JB$iSZ@q%w zk_t;9nZm^0IT_%xzT%LPp;D1?gY<>=*o1gD!)!?&Y)RpL*<$DcIRAA1YpIHFA<_&} zFO(;}m6)q>7+e>*yrelpVeW)cV0WC>T+YOZX6fpj^5?7; zFBLqQol;c@)O34}DL}yzr8fV8GIhzle23!G8jW*=1E@VzIT5rt<9-U=%>RKzc^QWn z7_rdki|W$%QPOeGQdQQ<2W;_9ICgPYsZx^FdrRz;D!zPYwtLS>C_~8A6rN)Xyoj|E zAg>1UqE6RCv4RG@_{S%$;lkwxwHs?q;mr&Tr)p%PUZRr$J|`(DX|vJ-b18WStRZ3E zN)PN`l(`Oo#I@H>W;sK&)fsyj3G*^6;dJ;R9Nu-+{&-=^L&S_;6l}ueqU4%}d0%hh zU@!zD31mo_fh#WA!%I}uJB=8|oFjg+=l8_-OwYH1xtj2;IeQo(j^l$CBhD}lw$4_A z`>kO={!(c;GI)Q;Ge@o1{fYLD-pglEjGSaUDnxHphBbp zytTBFJE%hA-0)?h$)Jbynz4Iwxf2^Ks~etX#h`F z*HdSd;T6Ss$S!J6GN=wG+jHXT($+YAHyCRq7eboY0LroN=_7k|^FqLToR4!y^<{su z7lpJW`QU3#F*eaE>b^7aNNAoO7G1 z9fp|pAfHhlQrz#6hkxz(A++nJP0Wed!An&!*=|zj;P8GR+De+C9DTF+{B@5E2dC)6 zOay0$3N8<)7~w96s%dv*NP9KqPZ-0tEep{?7iA*3iNlo;!fGK!Kd!%W6*tc?sk z-`{=zp69vW`~Ds8_8jl?{^2+rS4Y0*bzbLnZr6E!PDR#AzF14#UKo#~>Nnt0iS7S|L~*nJS?~_?haOuo;cE#}n3)OkSp^XPv7<8pN`jtn# zv!mfN69XtXkU+d0j>wmM*^YL}>D*%7ew>h(MFOCdLM;xmWXkV(VO)kz0@e7y(wcvT zqY;yRt|38~*tFgRPe3g!mMz}N7+4_@)%TInf!1CoA}khLJxvDiCL}O4 zk;j969f#$(dT}7r>An6*X|@aUY08vqw5sD!Nsd#ael4_Qp!H6$u!$t;Lo`yTD$(HB zy7>ooE{Sn>`UbbBGQ;sqz=Vty_d~~u<)dpc&ctLK%&7>#2O;l#Lx$tRZ?ze9OX*2C znr+y^8#uYFiT08)>P=@3!@*8GAdGUaq!Az|B|;Dg22_Lm(1tw@1PdGEArQAP zSv;X_W>q~cY9FM}mB_ezZzINyIFVHr?r_YkYS!ZA8ROH%(2`GEscKZpBa!p}eD?=u zV*aZ+ng3s`rDvH|(#S z&%$$#=)=w&cPkH#^e9kC?WhzM1)n9vC{YhK_;+tWurC9HU4Ymxvu38WY_n{Qd zBGlht)Fj?oo=AoRz!|ed>a2=Wyp33+$FY;ycjO>GcZZ_A>YLxhe%j5xfKL2)29DYD z#x(e<_Swh`8;-Y)sIv6S5>A>U(!adh@;JZ(PIb8Fs5pJB6}ff3?vH8>J2;};#;{=U zsVEH2VV7W+Eeyy@R0+$|%|dwx8-+!o7{rN;d^SQAvm@y*@SR=4M5ximNwPj@$_KEr zIqr2MC!F48rBJuEi?~&=&iUg*5iB^^QyxXl=jC&0p%!61Sf~QvzpxQ!f&D!%D4FDY zUDbFw6RjE(!BMj=ng`3`Jx8bKCmAJA*@JMnP=*aY8V&`#HpIJt&j996%$GJZA974s z&tKq$9rPuVMypllQtCf6ws(Mk-)hDp6c5$Zz%oJIx&WNhnw=u<`2r5JeZb{0*Vx7N z(X$T!KH3(=?OXeD_&7Mccd*O_*Oj@ypEkcu4 zm*M2tn}po3Fv{coSwY=ZT_I|$_=HH zZ)jrJqG{CMGZ2={BdBVOOw>N1wRq4Gg619U(t_9q3#m3Iz1OTjdU-9I&rOoU9NSMM zG_JV`*9gnHjUUZMCjwaY0>H*Ww#!tC#h#{mZ5FcgUTA5Kcc8%uCv0d&*blY)=HdB5 z)Om(Y2iz~ER1(MhrwNp`debqeHoL2j6P<>hIjFPIo@&7?g#8^HoB0|7(4 zq5TlvC^N}s+zYCCiKWCwUUlh%YDzM(oAPO*8TL%;3@a``b2O#$puaMIX3?&*xZ`b+ zTf!3E#?eY`P6t9ULJHl4`Nj=f&tGfa_xMgIEsYwK0aDIj$x9T}tkk7;NP1eF0i!1= zGa;$X1~T2{7#ez}c)c8MAM32(lu%s2ahrPMrd_h!3y^w z9)r;66&1pwr6^JCBnC$FsWkvh*$pL;BhA3glso>6LYZg+pY%Y;0*SJRbz&f7vWt{p{H}u zaxGO`k(&rOE{Xy)GA~eU2t9zaKaxwB?1~bCH?qi!25q8o*7lw3z=Y)trrRa# znHJcNe6i3QC#jDCx#D@RjGC@r9l~U_vtd;$zwCmyrUJ>o=#6WRJ=H>KpCWPsZ=ltz z&%W*G)kw7JIzERE72h6F?P2H?E0lTt(xZ3JsZ_Gw_L|9BR~Z`{QR|BuF97}0uAUE- zvRjN*-`jI2a4=$nzd~+-dlz`6e6sX9qDU9caQtR=_BI16y`<|}(kXYjgK{9+UO$G{ zT!Hj~W7^xfG->_8x7PjY5_P3gkzSY+ACeFJN;QiCtJtcxs4Kti5~E|#JRyUS5(_b$ zu>?uf)e1lQkxaXDmm!3OBD~!$iG?0m9&UAAL?yneOiD^u$*?nfm!l!s&Q#oAy?w$* z*eAg3j{ML%J`!&wksn5qVmQA@hBzwV#gKpzc$W$(MpQyd%(IsWZwMxEi!#QmkW3m9 z4JJwX2m@lbBN=);teZ5HITLBVCAHHl>kK5zOIG>vvbIsx zuREdr3J}{1NU|bAY9vaERFO`?OA>Chx2w~nwVa#94wMQdM#m~~Ry(}#;zDy=>b4Ji zvu4S*>Oe5Mtm1QKX4P(C(n%qjA*hA}MDBL6Z=|ujj5{PRq(YKMa%m}eaqWY~65S$7 zn&Tf!CDZi98Zj!jFg_%GBYL2GN3*&Lp>Cng(xq2^gJqa6pC;C!9?{-y9J#ad)yL*w z)>D(=M}@vXK{3iinCh#Bzgyg;e|on}#9u(D{BwRRJ!mLuvO@^rZLa`1L?YBA^lr%y zGM6ssCPv@JHgbiX6&oRL=!`;tX=?WNn}-3iEW^T{4X+P;Ds|+rMr?E8(H7-4d*`hO z$Q&d)#5(O{`i~)U-VWzbu?s4^(8w(jFQKIes~V)cAnIFkzB^kxA4vot){1vfcE-NFh?&}MPVJ7sCjaSyTZNVTr?vf#zWYV+NQ&z%>ge6%R z@HH3FG5D*aio^~)ny0_FO(L^eCc2TXg{6BzY%gIjfkEzy?wr)Dl?zGf-COKbYR0LB zk2TRip-vDGj*3dCNwbp{9Es`zMEiTj5ndVPV(M$5LNiu6G=nrlEM}M_X)@!S0kNfb ziMH+G@Qm&@V=ZhUj*j+p;8{M`d`>vyMW#S~&Z3=(hERPnJCxZ;L}XSEDX>JllsZ45K=e8aTGwdG^Py--9u!%NhNiS0m} zVAm=SU;3XzY8_IrQb60ey-XN7A?Mas##jv)<&x3Ix63lzrrgQ3b6H5&Odmz={9;Kah`6 zDX5=rA4LzAl6iLRfr*5kc?gX!WG*q@u5D*7Yo{@U+%{uwx6oXy@*q@6{KRb_M`e+u zi|wpEtTtXZvK|(q<2#t-cYf}`tH!AVEo>~d>Gjq&b}t}JPM-;VE;fZhgZPS};`3>y z-i6}Lv7J;ONbd?%I2)sZ2gqD(mw{_WRHFC$_(nC+u-jeMaLFW&b}3@W4$cz#aS}E7 z)$8U1&8>4Xj_TJN!O-B{{?SZNuj$tc<%hredu z=m~IkQMnfh*W5Gus*T0?MTgx8yy^8g6@2y(-`~~LaDn{FyHKTXkNAZexwkU~kT%7{ zl2Cayu2?!L*uZf=QG zXp6BJw19qstOaj}B3bD*{y>`DP@FvzTW-54ca~RENlsKq^T&re!gh%aSV1E(&_~Y# zoNkwkk2Oj8-9}x`j1YDDC{hbX3uviG=VL&4KQ|+KmAL|-BHAr)?vsjvbYSSH7JGA9 zY!?iHWq!Pp2EIT&FTv$)8umzO0tQO^&%E zml<=F*lC&-f?=*HK=%=~jE(73p*y$T5N6hloH}2MJ@lDg!`*DeL$^JFGX*0bY_pNmY3a?y2@b8_Um_; z!db{{$ibJxB$;NxUm&meFYqjd%}CK(ee7T+yjCA#G+T~v{7QJs@=@OcpOc7qtMWSa zcKJf0oDooK4u2rs_F%NE}>>6S#5)eJUhWNX6V`7$3o9CC9qjxKasc1OAP`liWr zrB2V!k1S5a*Jroo$xXpetX`8!NL`84d^I7`&dIya#nJ%?HIJ7*vT`Z#Rc7As5H%dz z@vg({Dk4$%+Nm{JYz?zGwmoDfQMjQVj zmb92?-)F9yAOOfr5ditAT~LaW(OYj5=V%0+-I9u(k;VtjY9d_MoHPIy&(C= z>|~F)s>PpD>X9x$AU8^QHFK)Bp;&N#{a@S(3%W&l5BK77&)=U(CuSvnKg=G|zz0`L0-X1rTgQ274+3HBDNes-RW1*_6 z(|rlQ!}=+99c*320I#_1$U)X)TPvkre5slnc(elm!Q<& zUXVuBMaZCRj2g*5U)VR3gh6ky3&a6t?xU*UP`ap#ht(B6SIs;?TXT6dNmb9|S-pX$jRJ=y3BnIC~0w zuoGL$?e@`7xUlfsP4fMtnrTuP!`;W6DlukzYsK7a;|`+h%jJFyd))ugZFAohDHUXF zW9FvZUI+M&Pap!{eKphN`^a$MDjFmdzNeH!Xea+4Qbk@hts8jNNy}}htZmk$PZtIzsIsB?kRQX1L z9cq`ACIJK>PLmmdZch-->>?~rSVPU(BCn~C*6kket<=e>xfp0(U^dc3SV|7Bf8`c< z?QXgN7iM9axQUPWld10?xF+-=AsK`&PZ#l?DCIpD7 zbU@AQgwU^kxw7V%z(bkZ^4L%Qw>XQ3Uz7-ElB}A&*urViLgQHBXO|UI$)>o=iyULHEeizJTS_C4`0z-ZS#`+D6k&^xThA+3w{}|z6Uy3sam>oMhWez7Ft5p{rZ}h@b+A<3wbth zA$88I2IYg<&FGKv9YMte`f-N(7LKfVM+Y1pDCgjF%XGZPG5&iUmB^^W(6K_nZFJ3u zo`f1NFX<}gY+PXClezuq)ZCezV;yMKf_AJ7CNQZ=tC7$rA6?=|zUefQJJ;3s>o`7QlYJSi zl1)26)l)rlrQz-VY}CSP5yk#ONWlAY=q@RlUsiCaG?@&Z&P2c0C&OAmpSwp?bTqB- zm%Z7`Vk{iK`yN-C0?!d~jG*#P0)<;dn-gy)Bn~Z}6FUr_6enQKYcaY2;*BJ%w0aFho^ve2BqAg~7 z4c5YXU+(?bLYf^E&JEs@PKnghz-wASG_a$%xBIE&;kOEk8Z+Mu{WGh^Mrwam+WGv> zr3jT>IW)WO=7W4T(4XBQB&`3IKAZqLJF#?GEujw=gH^_{UM&V)j$e|RfdZB< zJOAivqZ9@Nu0dxr069Cx&V;=+NX}Ne@r&nawu9##gfds%^qV6rWA_&a%H}7QE&0V9 zfA{uf*YxUSf>4;eNQs1)7Z6f8E4;;(WRKFd5;+V+(jN`^Su>GBAJecZwg>wl_)r_8 ztO5JRj!`G?2o_|dTnuuJ2ffVdDt(@r`qrLteDAD&ytlqvI~vjf-|p(GkC8rRTK;la zZx>u0P=B+m0XH7{!+kmz4PKbIm+Oh*aBb^$;WRVfNa17-AU>9x7~N>TGTrfe#eBU_ zXruIn-j3BsuYO3-3n8OmO>a=!KAB^DEX**Z&#T;)GJRU}e#?}+$@=&2*0~{Q$m*^k zfR4`S??96iAro#Y-OErKM)T72JmVGfalQs}xt%FY3N>ZPcbWC&J#soflsCDUK(l`P zx^oL2s`Lz^ZbZ0Sv-a+x%E>;|p8eu2KG4p^z;4(*?Z`W)f{L-YxUlq(DZn!9{$i+& zRR`GkS-R}*pU>DAWZ6un#YiPE$1wxk!=Y zm=4|Z4j$&jfTJIcv!#Rl5<2$SUpahSg`?r+PKxvu^g5&ZHSonzf%PxkkKEY4s?bop>t9$}7}0VPw1GmrlpB=c87= zC?PCyN4G&&x1&-&9v`(mtK88FLx&awaxZa6;^rg>m=2Nx@}XwkV~} zz6fvtr}lges#D(~DU=K-!Ih$dKONixL2%Nka?(y(2}Hj=s_Qi05iyt)8TF3-((QqXsS#3%>0Qka|D0Z(}Jbl`I(M8e_X;I*_CSe+pr z*7Gi;}gw_+%{~tg4v5rQM zFKYmsQ$~q~7@7w4nvcfNnY#*ck6%W$W8vya%)oW2M+{*vU6E^=DUSP84{_lXy}-Xf z;lZ@9HkHRrxTg7;jEpVRoIs6GyS=~dy70EbU|Vvxh-#Okq+h6Oxw6Vje2i2~TByDg zk`r-)uX!p*i?e>3CY*j-@oc$}R{FswkKPu>);2b>@J1tPw-Fqx{EYJoklt5b01}zm zA44N0wets8bHTFd9%7>&(K}V8m6y5taHFD5lD9q@T4c^52b{E)L-O(3pgssgxDxeoLIj~6zGq<(fkWww|RUlUUZoA z6r{UUx%BEmr*SHp2~bczf&a)&P1`|MjVZ5e8C=r>&j=qIPZgz`6BwgY7B2L z!0;f2|3CVeMYa>?-cZAu`gm&iMr`VjQC5&Ua--~Mm)Kw6Y~+y7W*n{~pRaNTx42T2 zS};uc3#?402*94(Te%Ia$Ux>_fO;3TARj4^?b}SPwgrI)q`^peDZQZo zCeaPo0lQJ{MJ+99F z1$2|l7o*j(`M>@phj3%N=K0$zHc-LfYg@9)YT;jit6^JND#%#B_ZL7T|DA7Oz#*nv z@fX0w_#X}1If9u70YV<}+0>Yao_y>5=Uc#C0(onb5q7Fjl;4ynhKZKS&{<$??g$2j zZrfkr%jyIOF@2%oveRbhK4QzU5#B-1KbFH_Tbz{1EZ7FwWs~aXvbOWL-liS4V3_Es zv1+y{d+f|6ao?97etBvz@z-E2`v-Cbt`Vht3cF?Ak%2_$0hS=K1zR($%%$X`DbU7zkT_VN}yLov&|)X|Lka9Bq%o z(A0SBzuw8e6wjGwM07oP1RcWKiROiJc~(RCs>)`OuVeTX#(u6h+94Xc)aq1jS37 z;$q+RK#zL6b;X2+1x(W(g-y~0q5totk^)L46LqBr&_s*tZiumsi!mK=4R9;w`=aE} zG=3h>rD5gHFAc3!sfSVVQEf42*m;6O!(emme(*SF!Hdjmj_=JAa4!8z8r1%IrPIQ| z0onDoGkD&vGD`4rcUYI&1P8Sqj^vuhKgrybwQwnY*CUQheK=j=*x=V?z+ewHj5C^u zd_7NroC}+Lj`J6gY`8M3)6yLkG~@H#pLpG~O7wkFuasBj`PcFU@&%g|pMxMEi}D!Q|EHh5{6j{B9oQ#stN)RYOEKCby8YPb zLXA|CaoYu*XW^PQ1qHX8SPae!r{ce!^H~3|LflqrQh%NgTR5ow@1HGoj(;U`gGECB0=FY!e}Sd;b?~MJ9fjr0JGoF2=IG{LoDC|^(NRq2N9okIdXe6> z;qa$&RujQki;f*%?4}%TUBLRfD{S0<;v=YB^s9*fP9gT_U2 z!R;?_{|IhuTNK!KbO^SMIHpGM(02zt<*o*yC4(AJX0D3P2e|S zS3z}o6|@KlgU3sM0cX9|kiJbVM;!75h&|TV67okq3am@m8Vmm0qtSok!+$!9-F4Ds zndy;FlNxb#@29(>jc*Pjr9!b&C;6x|*w(Il$(j+q?e%1>zW*~~to{PI_q#W6oWuO*#Cr)ik1S%#{sra#D56os|4POuPoXI~5L`7Q zgWvhC8JW~>?7OwGoq-XuOo@d(qaFL1SF^IifuwIE2K37s43d3FqL2#me?FlRK@)fi zu&{re5b?{WOGN$w!Rf!ixctc4pKYLg@bCOz$;WHlsMt5Kxy}(v-MX{Ox+@a4Y>=#( zXoInAhVXPt$&xS3u+#MuK2M|8b%NEBbdrX~>+QN5SY;q^UdYyI(~C((n?06_+b9*$ z(sxr=^OEb;CrqPjYY0e($mdt;xAt6(Gu{;eDG%3Kcku1*`p0)Es%U)^f!i3$5iaEJGk8`%m-u$G$`M$8&3RF(r zp#XcE!jia1Y3tJ`e`!6Vb-Ca}Q%zI%x!2#(7^5M^E_rL?N4EO9TT7u!n-$G7O*)rc zM~hGEo-DW(g*?6eOSlH&NZuQ=La$#thrJV}_YW`YB>nUENAF2i8Cd(Y@5Kx$AjrKBP^(X9pNJx4mFcG&;&P5eHLDA%3yr3`%EU7W5F(*6Kc zn`2DA#`(G)Q2gE=Fgu7&H_sV){TGiQPBfpr(P z9L1de3+$R*KTTY^yJ7m3o4RB>fB4$AhNY?EO^Dti?ksUsw0F^M_F)u8IJQr7FLg2g zlRnf@IiDr;Sx=xokcxQsN)ws6x1*8$G)TrK)G>yqkKMm!^v@6DCKmF*Uk6t~tH4#Y z6&&&djRmLz3fkgpPz#iiH~#2whQM`>FrpB~SS$FQzj}(u9d;6I@#Mr;!h|kIVczv* zrPkioZHIRmZIVCOLjf?vS<$r=?KQpgUbbHtWz0>Ya=d$yln>Ds(~JI_I}E`~wvYIQ zjU%pAhYY-~-sqm%5Z%aX2oCAjSsmro7l5bN@5WBOUauE$ZeNphDAVDNTerDOzF8+) zA9u?f##Ys7uHWD7^*#fU(=_eM+sJ;Kza#y5QO!y3ZCM^E_Vpc)O~X>^9%IVq_Ue5o z_+gvy2KnkrnW(T-?C-N(-Qt=v{RphZLYtT{3Dn;XdvjmlgfBR*XV|JQTDB{2)2!95 zdo8a>>`se*!r#H)?OElDWS0%S#7t8MX>_ohP;Etv=eKGzU8ZZ0wvCktncRF#NKa@p zpcs9xW3S%aD98EZ`Yjnv@9xb?F5r&x1N_)mW^Ir0>i*=Ujs=|!zcRdQK;^TI*uCZ$ z-AbN{Tfk`c&)FdMg&og>=d=HDkD5XC&w4nr9Igf;7dPR?h<^bC#b0A#pYB1=MFn0A z$sQ#r^tw-Y6Zl6I^NSTR*so>h#lf@rmG?6aR9mBHNPvs&NX!IE**cf+#! znnrm15dN-)4OQF?kQmCpvBCmm#eZGYTggoZznI^F`yY(B1z|UAAUu_b3+@Z4e*sMD zyPHWNmOiU@ELy12OMxe-6zNjUB_#6d)E(AzcW7|nA0I?+URK44K$uJB5Jg;b93=@J zeFN(u*iC$OQyG*Av$2~Y>*=75yV(rFPJrK=6o68HJ+c+Hd13M|@O%jS7dR{mMvniQ z4@8g;-_23cZId%jfc_^wz5Qc)FkHSZKDa(VNb9Feowt2Wr8~*ElnP08T8@9frPBIa zW3@(juAn?r>KMg;Q&Wam?;(!L@E_BKG!s~{JgAkCXTI8&g^}y^ntYw6k*%>JFRaIK zB2j|}dj$5QaWMmuoo;cShraFoI@PqP5_jO|*FW&NAddZMvocrB<8*sDef4nGQec?@ zb@JC*jwhwmQKINbl=(#!c~g8S$Ax<7RH;@YbJ#h5yBO$Q zjI9Wzg$Ye;UBF5D*NQ45?i3#$yLui?24vwapuaj$4!q@3z=+UQ$_#p z#*hUV8%5r04rBdTIfgqN7rM$g(|h5()2Vd!%Qwb6x+gXK9rzgd`B>M4J_#W7n#A>b)>>RYJ<{utJNS3sWV z@Y0<-29x)wYz_EdAoap;TWvzd&|AVsl;}^dvGGs7%flv;8CD%{_oh$NV!Wh$z>EMt zCRHH6UM$#`m;4^Q-mexUt2aI>5SzhyUU?16q48j7)Z{Y;ikzY1O5TEW?BTz_6X;#s zf)W!PR~_pqI82mmnBeeWo4edWF=Qsq!1xDs7l~i@ipIn*ve?BTuYG?*HS29KU@qdi z;qNz}X_)pALbCeS%+1tB^q({=!yT4}8=d+G`0*bsP6|{h1`FUle*gw+|7o$|AB6n} zht|y!G`L>>bZDKx5M#`**;Bx`{9q~7(9t?fGX*@@#j#@}2%J+eXpgTO3cMuWoBQO^ zSYb@-RUd|9J$on?yv{IZ(45ADNth1)74V5Q^_Hig{U5IE|8bf4&t)*q@cd_-5x5S< z8Hu2uQ85~_fuw;Hv~(sntnuQmfhzvuW18*^o%wrC{15n^^^OcGYPG0?toH)s`F_sb z!jKwuAu4+VRiVC&;K+CPwG(+OD8Al<-J~gU2~z+k<=CkJ~k> zobC@bNT4o})9f*8Dw}FWpy}CAB?jQ6Ve2`T+lfotK^5{J7~$Wyc{ugfc?%-vI2d?V z|M$SN|2G(T+Wz-|%UlT5{r9AaORPULQMwy8N^Ga&QR)_r=&PKKEcs>grCeOl%SnpIe7984qCvM>6hnyCBhcVC z^Lp3~37~zwjT1LN6To&7zFd9oZgz5mpMU9(!J+d3XF`8W$-a2|%BR?K_uKc$c4rIU z9J+Ym%j?Hdak}*miq~7c2pF=Gne?qjwtn`r3k$ACPi?y&>$vU1?$B?KZ#_PzF!kky zqsQ!#@a^JF=Z@^2h%1L7u7A?M9~dvBn9T4ZWbGcq-~Xf<<4WD713PEF{0bg;SiHBu zgx`vTuJytyF#s22U4rJhv75FXaoRztkb-|we9t@G#Ol#?&~}k9po|#M8qI> zi#q3PN)(hIU}Glollm|ibF~`9Nt&X_p(D^O*0fq?|D0HR8=y%5U;6Up>6RheI27@< zd+BMmXr8q@UWMlLF>2~cPpm=P7jo);gP!94;M$K=If#TEyb-z34h{L=jh*q&?}@^0 zCtuxb6;pT+Oh-@3E=)5WvCHFiSwhuhgTWpQmT{1(7DJ$b)$oeb@w=F-s+%%0?S!`I z^+V>cux14e*YRguHjn3J~2p$-R3N+s5?v#^iLk819yF4AnOT z058bm3TjMq-T$&_a>csm=C^H>vbgBdDP_+p&$g$v^$oQT7Z*n}$8fjCY#xq}avnOr zdSX*Fobp6lN}GfmY_KKk7JKD$-psz__y~PQ3NaC0VPu{)^9Yz8!40f$Ix<(mq|NKw z{C*JiPp74KZsyx??y<7>#^srpSA%xV3L9 zVgCBaB=T|>9W~Rl8V;fqU25=a=)bob!KWX`VsRQ)cnE)AgV`W`-yWL#Ppx?C^Hk7f;fuiKq^sB_ovSMq33HroQH_&^HkgYc0up@lZCdsdaJnPO}VLo z@eEyo(Y|w(VIRkrQIQ)D{V2cADe}!W5uKY-VC6tT%LZr^mM}yok^)3<;)JKy=Eynd zOy+3Fz;E`&gmsCiGLMDoncSz-@6ev2buMF(-}BCYTRv;PeRS|{@Ri>SO1DQp2RuY6 z9~)C~#Z~QdL)3Q)L!4c&N6HD}tV9$ymci-kV667NqF;y26v)3G)og(cy84wg^^ah>uPGR_&1*NLma!8C5H`vu8)5BRKKO}%Un20j!_U`T5-et6x(x$zwvjP zR$?1_#_vLyKwEH{@5k0l9FdP#7pU`Z7Yy->6ywnQ6xZN=Ot~nRGw;9b zzhi5kvD>&c&QJgD!2Tuge(k&ET0#j=QZ{_SW84wXz=;w=i2U6sdR~7RTVT06Z#1OE z40o$?dVz1^;VFG(JVZ)hzMyyeYC%9*uIj;=h4SK}bGcb=-aXdihg401^I;wDbbkA9 zN`hX1@ZHQ!akKUFgHbM{GakFX5&ixGS)eBv_P6l%z-Bj;g9R z4GXaAD-TBB%ZaH!*~f?39y&U zp5MqmuiU7n(6gOlOZL2??4U4^^B8S6-edD+&yDY|%P-4mB^~=RqgOG9P_IrWK~s9a zuPzM_SzifK$Q&B_toWgB>+a}_G=JBzlzj+2bcW#*E#cR)&|MAB^Z1y1n_`*kTExa( zM1S0mK~FxaG}dkb+KReO(*Q}e+!K}8y1DzNbN3t2J(7&lInYr5Z68d!wdkDQP4C|Q z)9*XqUpZ9&etjqTRlohtP8(gFwOf1%2!E7!Rkje7qP9g?U#bwL5D=@Vo@iks6Q}cj zPvi4uqt4LZC%&Fd_PfVYJ*B8=@AHa}lz;YQ!1?NTgI*A-(Dd@&qFsG?xoq0mtnq$o zz_YKNq0f5^?ka1FoI4xucAw3*|GbO!tWKhEJdJ|7Xw^}eR zO{qH-PfgqM@qJd~_&ZHcFuCMS}d>OQMY zO$9ID>+Stm=G?h-H1~#n&C#DZy5&l=^T=w$tTGIXfYGjO>n*#t9`okBt@!sg?)T>o?y>S_ck>)pHTixE#xPib z+V0$@zL81`O10@F(}mh?j*nO8r36~vt19nZ>|*UXuso!h6Z@m!BbVF$7YGdD@7LWt zR0TTzXI2$H&Adt?tgCvQJ0OYN^4kO@GMXYQ&b+^v@ARRTkS+kT1M;b32VywpqIv$; znd~^?%(d{or}z9<4gZKmozg1z&{)tuF{$^0_v!0bFm~*~`uhd_e0wI+KJQcBP0L+^ z{R`wWOnvtLY>VW0LGuM^kzj*SFpvaqw{8J0f zt#Sg7jfb0i!13m1=oJHd_xSd3-+tSBFE(C;pK#f?HudlVQYlqZ#U(E60x_V$<%_N* zQ)J^t>a^vyjlFpH!?~+K&9G;g|FQ^ww5PpfQA{S@V6*7-8Z zaR&`5c_fN_KK33W>&?CK8uEUL{RH{WD_;7TnZw)m*B7|RpL^IihADFG4E$lp-~^WJ z%nE9%@WS12kad;)gf9vszFC%fyZ^ID#BAGahyyxnx=y8Nz#hQ}j!d)?is&+SC^=Qn ze{isTlrdi$sC2Q-5E!W4)32$4yHTygyC|qSu@qLCabzhoJgftwIg%PkXpMiwF1{O; zCpwA$G=U$M*&ch)#jF@JW)$dnX2oeH=4{X*_KZHJ&uy@-=|slEqM3~pLMZn#E+bCW zGW7>h?eap9xvk>q(eS3_nwS^6M=Ou&;uktCUgWwE@~S_Dt{j{y+e>D#rjJxq6G~X6 z<-{S^qb~UwMygGw4>W47x9&5v709*m8gjh73dThb$K&b#hT3gndq^3rU{6=Tua_pq z!;M+0wSl|+Fij6x@$&iLpm|T;@`1UdD8Z9-aV>Jyk&yc<{wwB278hH83VC$YF}Gz;waKT&A7>uz+^ro}f&6gl z>PFGwW8XQ>8Hu@S51rK;q@MDGh{14=Cv=5Oxu$d78#9DPv- z+qFbKsULmuY+}(Y0rPAziJCi}ZF*Jf>-EcH1lPJl6Bl0IKezuCoO~D@$2?NBrrTMo zXmuO@S{U$^Ysu(`97xXz1tbmv22_;_#i#>KClt9Uv3o%w6;`?bgMfTsmv=ICX5} z?m6D&aNL#WAn*1?mHN^$Jd@N3^>uup7Pee zFU8ahztUT511Ec+M<~ZssZEe(mh33ol)t@3MTc?Ud&AqPtn=CGx_DZJuHk@0}~aH|K&UxO zdtQ!X-}4g|!0~0C z{ierUPQK(Dts6%fHJ)4I+aNwp()RER7KE(tw4PDZ?VWwBwI5LxA~p4HSHdV??@(zG zbE7)^O69TB&JDs*otxr2!I4?*v;`fw&@8JbejKkfq+_Jta;I>$OB(rj4i|$jm4>)H6A#0o#+z<4rKfF zE!@q%A~@v5&R>;TQ=SD8LH(M~`rKyT#W6~Xv`=0Nz4Xx0-exiTYw*DS$jEC|KXY)q z1Yr71_+nqZMy%q0Bks%pq3Xl;^+=Lsl6{>Dku|#{^OUkArp3NZC3{RlM#fB$vBi`^ z2~#PPER$Wx*j0+MZ<(!`30{`9XRPii-d z(9Y+ZX>TPf^6wCtd6;_76*?O|O*sy2;hIq~`T_FW}hHQyeSFb_SY3B&qC zl?q?Io6RO|j-|*a#O>-@l!TXw+m`Yi+GWw$d?T`makBQINx4od=J-HD;!vxT z0srcEH>!Kg^QQeVKRXl63XF7%o~}f!4!o}Z@i43ujNn@GZxU<-pFJ@3p^$utt#$j6xpUM<>MEcYK z{TY#RE1Wwej(i6$jCdy(5V}soAO#1}MV!i9?LyT#bgWK`!Y`qc7>=F3fX!$bFJM++ z zBuA1s6@a)R28#9vh=FP84Ol50=})&cDO)zbU1ZEmX|?zF6G!<0w^t+` zY~}l54abfIayN0OV1y1hA|aitDbZ}_L`oV%Q6S7a3e07JmUf@wEJoYRK?Ex#BdWf& zIO3#&#cBkWP1%N<=<*Ca{pn(}W5CSW%)aH`z>0-)GlH}QWc?qW47C#jI3XZS`VC?j zd5Yt}Z*1R>H$bWwO|URG>7kH7EdsMO?p0f2d4z{4-UlF)R=-U6o&+z6p0x1rS;>1c zAW}(=DiFKk4wsbCFRf0~*@%^H7}+?=rwX*gtc}uaoIr7R;Mp^Bs*R=QgtAczPm2|* zZ-x=a1-uh1>KHcIm4yMTtz%J-lOvA`63csEw;9OQpEY#5>$>XDnqX#~AJE@YueGsEG)4dy3o0vbnQAd*)1S{ip%2cSie8!q#}{giLXf zq+G+V68|0)Dspf6##4cBG5%)sh(J0C-i2JQHVngNjL7$}T1l1km?yodQ6Z563bP## zTO%bx8B7Nbqlj37>RX+e;gGv2Sup7*{>TTCa#84-(;JKRH=ywh4QVcUPX&Icux5o% z2_te!@sqDETs|N|d_2KZO@Y78a~T$n1qrhqmRQ9Kyu;0drZc=YRQS;PL8ENdK!Kq= zy^~4opIS^zq>R(|mfj0`(4T=nYiHhZzUEih#dUWdH_+{~|?z3r?&G|d~iuQNY3h(fC_3=1_6fVnQly{JQST}H61&blQVA&%7x@_>NVDYbzAxj-po3vr@$8&KQY+CHMp{8$&VMl+nv6PbT}HECZq$sCxQKdbnj9M(b$~ zt6lYeBz4q7)4Qw&N<2JNw6vZ6pZ#J3Pr5U~FtYEJt?o0az3fYOjXOO1tfvNp?6a5; zK4v?$$VMOR+NkoQ%DC=~{kEvzRqW)N<+hulPoJXi;t|*s@wM3&*mK{z_n<8{Z6NF% zRp3XmE1Mc?}TJbrW-5b-e8h$NBsn9#J7^#>x` z5&{MCU_2Q|6Xu}O+6?aFI{R#7I-zP=P~4I&;UEU8+ufZQGPcpOORu}sr1x$uKx<&} zi=xd?M#L90T#U~9wTmy^bc64Qp%DQMc�bV!jssJcz#ea`sR*vs#mF(Wv7}Q7Yj9P+TnLY+29iQ z2(a=a-2g8N3U~O7HYsC!(WFAdiUidbRGOh#E8hdL^Lyd3{3hk2v%Wp~6D6w7DpJQoE)XjFO#9?>fRCk*%G!v_s7QC#uZ)XIz%gh-7>ju6p z4u7MjR=MUmI!Gs%>o((0YU$|a5w<}E@QN>i--|g<0n~*|VMX4`5$!IzLSsQ#6*X0` zS1>xa0|-f1v2QP26jwVPi@k2Z+08ycHi za`k+}{C6jNdmpu5Hl;_xt%oo?nO1HSd~f3r%AMcRmITbOU7NrHt`TMjUY>sk+knh$ zM}WWQXaKoSc_JNu1avi0#vcYfNtG9Cvbr~_8>kB3wR@9R&U|*uuAB}h&kAFVx`=&9{46{nyAj6ON%jGKyI{8;<{gD9vozb#^ zCVt|A+ORrd6#noXegY;GZ^B=Hjkkq=(~Nk1geUW`zd(lPI@U%!&$i=WWt%c~`a)Ry zVWZf!bIR{VmU9y(M#LuN*UpCS-svQG4i9n(p3udp^@584?0D9Hg+{Nwqwj=2{)$=u zNAL#4HO6B&bY2!gWqw2h9=&Qh7R4+f{=5M1av}WN#5BwX+1v9C&@L*P4`uZ>>u*!e zkr8vyepjr2c>B*YWsA;;GgSQqYE;78!2oV;BxM*rYXXeeIfphR_{vrlx7L=2GMew2 zf~cOj`yt+adoI*TT)gaNS}8B>S^fO{y>XOm@bG;ckCD{RQ~Apn-zYmhX;p%k^dq5N&N9D;I#)Amr+M2UBaq7d#%~m;3Ep^8 z>N`RCIzYTbU7nw7K18Tp z(v#&0)Ahj&NRzR02&8sk{z>Z`N+tY{23^FI|3t7$@QDGCzPB5Kf5?<$F!ctr1OX}* zKJpc1{!m)a^vaUczH+VVyOz^Gep|&tPnzoaGQAjuw$txyoH%V%JcKiPnXnaSOu-#zl_eJA0y|$-M;8Jf z$8+A-sa`#^bfISQy{mj3Ewg86(_XsVr!Mo}{4ys&?t|2GAWM=rF94F`)H)TF`W>LmBnGaKeZhxtNL2? zjAwD}p2bFLUh%T0{3imH@ZKk_Z)n;R4Oy~=wnFiaAi5Wo*)Cf@R=+A0c8yS6mhJ0- zLCoROPS=n4o@ybD%Wx%ae>mgzy;2X{+mUnejtD`D*ohHnMj+);%qMVP^MY)1s9oH5 z$z;h^3>f1VEQ6qtC)5ihx)gL^B-#|1X2U!+P|xp^&EaxfwWJ|J^7#1|n4xD!YnHBV zeX^pr;SGrxN|N@E|0?YY&o)E4maU^0vMEl+ho<$A(# zpOLQfpHDti5c9}8MkU>PK8W(-#^1UdO_JWu)ErFT zVibXIdP;Y`diQViqa~e9`??W5>n@?^7KX!>ZZ2>_(VK@axaplL3iMH55?`s z2~1i>z|JvSb*LYmpz#`@-{S3wVXcH~$lRavS}|9AycyJVe}_Y2kk*HyXXv|^nZd8h zz}56^@3Rk(O6Dw(Q!mTKHQ(gOroFjzDDu)pbq90)8J_q@c)c0P^7ih6LzvKC$f*#4 z(vyi3lugqBeyL$B7C{)6Kl{+ZAGK++)P)HeSux))?x3naQ5aA5e*ac?;JHb;AQTnu zY&7+wn|lMw4%^(nsN7e+iL#?D2(vzOTMetszcf}wP;D#o*Oq{prI@e-5%wEu>XAOE zrngkBRzGLcZyr2kR{I^)iFT#Ox!-;fa_96arK0bjzx?Z`)b0klfTT=fl>!l^!)! zb@d~#4CyO^+-?e=7EXls7`52dscugE$`&?Fl;_=MZL(;6;&^3*vi40%kDhFcHICD> z;h9z)ixq$UxvIC}SH^Qc(b|#fs@2uhs>+4^8yvxoflYJ4M`Znc2lA$m!tzilobo}% zKmqp&WC#9aID&sNGyrNe?9s3yWm- z&o>WBf4~{(fb{E7L?&>sES`JpE6FhF;m1OB0O$76SZpUeUY)E%||s&3Fl=of=tfh>+Zd z&bStPt(SYZY$zn+`JzXm@4`{;JbL7Zxuoqh_ot%z+<3%{6*brLRVrqXei0=aL6oXT zOd(jS89(y>^vrGfNcab*-4h?7=V}zZTak$b!Rzg{xf3H+6u1q?b?*(kCEWEn>*ViExk23ZUn4j= zN(?5=9~w<^dKvYIoGNo2GlcRiZi#ac>SlSh@8TK4v+)Mr;RS?ogAQ{l)|puWBkg;g z%R~R@VX3~MO;^J;8@;imVTumFJ$bTlW8PPrW`qG`-M$B40h9Zf^TEz{%qE`sdDrlK zkGgJ_@2Bc|BkAcyPorqLmay^Gr-gbEVUg7yXMfflay(D|fS!tgn;`xH?+V0Ifs`&H za0V7DYcV=L%Ok`DgMWoopFq9fLl&b`4dwM8@(~V4g#{b!G=^y+ zAKK_5?nZP=PWS->^Uy{Cy{@ZNqwcc-Ax*ixWaHXa*xIWPcL8a2B!wtsIV7xA@ z`b+AfY&?G=d-^!xDxpk{T{t!KBK*E$@Tei|eRFwV@S&^BWG7}0FE^&YVIpfOT*ZB~ z)9SAf`jw4DN$_0_?X4jiHam^)lt>B%9aoz5PWzDRE;$+{tZ(8dbUQ)u>qDy!;ZM8+ z+Z>r{?>giEaoc|JXad}P01_clP!@(? zWtcNKA=IC2`dbM0F;>+4BHZ*OQ%C6k;73@rr`uZok(KC0&5%*QqYghgb8YQrLvz|! z`-6n;HlHU)rNmz zr*9s2@BcVHMNT76nOh>sua=NaToSN6sc zW{>Z!efP8SqS_?Pc|kVXJt)-%1f=^e6e*4AF~;u${t9)_NkhOtgR3jj&;_*AVt!M+ z?ZL5F$8Hs+247mb6K!GRH=D-II{x%Kw;*Ks>a}yo0b&Xd!zQK)^nsxqo?LaftrD1) z635r*RhI|l@5E@8lt0F$9HFP2{q#H1dU3C2Q`^Yu%A=O1Jl8W`_kLQ@e#Enkc&f(m zgS>+0coAM42wDCLABMyH!YTt^BBqBvq&p{qn;tbrk==CZR+E& zLuYw^irSaV<~WX())&f+#=iPt5J`QAZjfolQudk~M4C2lArU7 z*{dRU(dpgcKGnAbDw%AYepJW)jRYIWcaNaH= z3rPYy)?Axgp^&nr8lEe}idS~xCZcYZYj&MhxE^H0xZ zzhks72axy7`QM41DmDk7!qu2WW-7gb%#*8Qt3QaK@)G&fUk(6ynGsa!n@YE~_FoK; zfgB1s#O1tpTaYl~Dl=?lNGXQ4!(8&5(7l$7U&qq*XSk_(umd z_UO=ewX35a^~t(7>c|9G1V+u+2SHz=C^JJP{_A}-0E z?OSE%K5m})wm}koroH7sNyNi}rJ0N$)lpjU`C-ozG=qaR{|Y5AfD;4!LxTVM0B-v$ zMEFDjPLdTFK8y7FiRG|}$V$RcflqOlMcK4{VZq!!NF`dN_w%sL)yC<(rYwSZc%61$ z&{N1BF6H%>d-lNcI#D=|zm3>gjrj>ufjpw8}forim?Gqmg({j}{w$`h;IIeEkH2E?b=TcpRbQZLk`Q3&Ai9h=p`Nh@#qVgBDl=Xf<4b9*H#3PnY;jC$<0c5@e(p zjlRr0HulT2#KpvWY{GRSGPXECOF7*wtq0l5hd<4dV;Q-2+A`{_bUhW|yjd_Uy zVkkUWB#eQ`2`ur4;VVZ9228v{F*Pvz`Nz2iiV1oQ1@#1|fQViOB5XgaD!|c0?Ik0O zA@M7n$PyVgR8qOxh!1=2VE*1ZukDNQZ%cvHG#o8vwCllv`avS|4obEyl#5`)ANeG} zf5?1zq9MY-xa~Lxc>}(kw&RtJ#lgcT#`7`L*4aZ-k+*6U&rc~`ooR-PVCh?~5UlWO z{TRqc{h$5`!LDp0WEJre3W#mu!9FJ2;pusC4Sru6gBS@ts00%KE2P!WTt%I-t?^;@)X=3k*Nd2Gt&KC1%Qd}x*@Xo@0l_T`pVO4%>cm?{(yIf&-Trf@fh_$ug*8!1D)57XSlz{95eYZG4@W+DqY zhH`BSqx-eq?hR~CQxmiK+HSukrd1TXud-55}z&OhouC0I!IO5BHsK-JwQ_u${B z3H|~jcxv7-E7tahU)E%pvTYO9Cw#+wb(s&88~&PsZZ#I@snN4O%U_g8&GXxK3L&xO za0SZ~G60hQJuOhe9r;*3i>giECFQ!s_j-5yyHXpHc8+8cJQSikp+8-=Lhxlr!UTK4 z;8$VK!V1yL>%fzUuHmjfI(2sJ?@un)n>-zsk3aqM2J8WsLwQKs3>FM_T*S?VS)p3V zXsOkKNUx8xLQkXixI4b>Cq%3vN-g48_Wm7HU!`pNpd``pI2zOT8*-V0P^>_oGPlQI2-t$Z3W z$R*JYIuEL_`ZFuFTWW_J^qTAa6J1OVKJ=%>Jv@Ft+pbHnH)pCIvlDl9`Loxo_gqr7 z9O>t{Qre&Y7TRTioI;O6Kzq@B*bK{Smn?>xmZw;Z>6s3NyB)b0$hW6N5*Va_KJSuj zox~y{%42bH7%3MM3r^sRIqeVMF3>YpQ(!sA$`<%y7ocpG5e$rTFGBvDP+P@WsMNUy zqQMNPkK|k)llTu5`bMLDY&9<8p1-d1fPwL*gf{7jx;xS$ni(@9>E79 z^A$yzfF$&w07ncGFZD5MXxqd*$v|N)nri50HE*f#?|UrR#@@014|;p1t4xZ(zyvoQ6$^{`+?So?QE*w=w79W?#uc zbPH30l<0;>*}uZoQPrYU&AT0M)L{G8RiyKqz;d7|xxUUdr10$9HC%91e4KiqlnT=- zSbg|U6m{Z!rn^d1z?l1$D8C6o?1seXz*2Mp`FCxq;#awt_c>*!9?`GXmV=lKnSsLv z22aX~A)}owCv*>RU6Yefe|6?6u$=x1Wt|89Ap2PcT5c&dbzi==U%LEANaf(}66=Qe zXX%G-Xhk=Wynbv^g4>Cbf4tdp!3$;RRn8R1sp5^Gq&t7wG@j~QkbNOo`X=Rl!|#XR z8cBF7>Iehhv-9#KQYW;-^@_ivo4wU;j_`csv!gFLn|D)*U-DU)O)V&7ND%fu4X$xC z34_&fB1)1IP>dE?}5s@mH z5Zf)OzgBa>{VehYMjBQGKt#^NX2tq(!LEs9V|R%%e+yiO+Zl_SPVw6YKQc{toomoo zfjoHqvsupkKpmnaE`M#`paS_EQ6obysAWwq|Ob@}j_e`qa zfPMmM$Jd4sMb~O^v78Q$DQ~f1+sv1WoE(Hvr|acY_g+pWoI1;m3-80k5Qb27+&kr= zT;xuCBDL&!oQ)sk+Z~@t=#yAC+&SFs!GvsA7-?zwRx(_s0@;R;2q+Kxaa((ts3inD?3?B3}~Z*T9J^f5Vk zJ!jmx><)L4Bgf7hO@17IF{Y(V*Dimzg4U5Or^oIy@4l>%ocwxUZc8_QHk&afP{k$O z#szibB(gL*&p&6Evkow34z}qGd*{SI*i=5#$1!dmLsX7FvvI4aRF_#27fbH4le9yS z$Ob3I;OS`N2HIuV1h9+xGn%uI**z@1z-Z#+L48oJ#It+q5Y0ablAs%LDQ?ev;LbLl zIeq%3{lQl6?zh=%DD3kKJ3$Fe`YTQJ$gre zaXd8Lklq&RpN^3Bo9}PmMHsY3c1K=;Yp1WZKWf(*-_urt5_dlQDAPdZDgr zQQN@egSrFRs~-=X>QGn6H=ihkh@A=ZyT0%+g}|I=Hv42|oNmy1)kzyU+~_?GWpm@2 zn;H(LYmEI z((1$!mhk=7sXFn$CAkwzyd~b|{PgbIK`PtrkGu(XKX}&6OwTpuHx-EJXT4Toc_MSNRLa}=MtroP>K^UsFTjmJ_~8Rq_^J4KfC7rN9OW` z#3_{JYBbp86W&rgN5xk@mggWSx^IX1~L^B)SFt%XJ6vrw1h+ z9asB9h^0TDS)-_GsNQaS&|`=BbLRf>m~5rM=sZx-MqXy-T~Xe4&%UD#gcCX0%6F(| zVqpt|J~&D{1G8ijtQj_AIo+GUp~&M;8@@IXMyA4@aRyaHwQn3F0^trkSzDWBsA+TW zK2E_Do1VE{iLBYkNDb7?y@J*rr&rUb#Q!51bO}=}a}99rlqSlSO5uDK?wY3EqP1zU zhs0bY?uIIBMz>Rw0%_kTtoun*26Lh3y&5DvU0Rw;E;=VBTyb1iHiE3`xC(i0)SCj7 zTF-USl(v0Wj%bjf>Kg|&a<&{kfROv@4vJsbId|DRFG}z20@GCK!ujN0XN9v<7qnCI zblBy+{bKv=%hcV=bw?Mw?lBjSf?=~8MMl@>4h7cXIeWTrnBK9qqGY8wzj;HF=aCBs zWMi)3UcBwc)!( z<9I6WuIGJ!o0f)}WQ#_(J06(1M_!Pz67s>H4$=M?6g1`9u<&93YXqMv?a zjI$QhJ-iatJiq3u|Iu>5hS?*ucng75YhCI8GP5nG+G`AcM>SK7;P#|c>A(G+JuL3*hF8HvExZUiK z5ou#SJ5J4GrpJ0Er>1(E5iZ6?h~Tb`#on*NA52vJ*%@d4vCvU2a!Tm|k-j=vD%jx< z8ykL}Ud_Q90hts1*A&uuB2UAVxz9>*u=C7FtnUXq`?2b3ePVrV>PTF1@S)a3@yQDf zqn2;C-gZvBc+}cekzhyc97FyLrPutig3AzoLGBFX+FqW^s^E%M^(~s&JJZ>gl8D@3 z#Y;m*G~L^!w>rnUqq--u(Lo-%elPK(i`rs+r?Rpdv#pwXd+-N)@d^}AR>^_4(Y(XO ztUaWP%y)G*W|yINW;OSTRp)h^k2daoNKJpl@yI(7_oD0cxB7dfXLbr6v>8Wn35vkj z(^Ma44C4Fvu*t4dZOTb)m)u@TxYg!9z3#aCwq%qC;m%*7-NihlVqr8Ek5P* z2K~Jtl*s&oT;D~%7!?iEk)mt|L8-No@Dc-+hW{&6KwR;K0bUJ|3XgtP3XM z12_$%h{Hy2q$q zl@WF=bGbJ{J*$*aN=kKl&MISxc@)W(Jt``?Fmu}PgI2lV9%v*CQq>7VtED;qovIo= zv**bjP&wPfQYD#ni)=bn<8@N@#e8!p8??gH#4{`GB=t|0re%lMq#pFhefspm~V zJ%k~cNB)yW*vb1(qmtf`O+c&S4>aa820LmA-1KH`qZyS*q`!d_ej+cVP>X7!RIV|ym>A#7(D@zE=rw#=*!YI^Cs za)NbfWiBz}e3KU^EI7!J5of5wD)FF?tKMl+^46dDXQu69?r`hG+ocyHXQ3ZypXU1~ zd=P@&X;~R(X)aC!-6cku9_1%osQShGkK3;n8lL{NIpJco3_Bc{i)PM4EU*l_6*tpM zLGWCj3VJX~aeVC_Td~GZKk$wPEo$^+bCpAf4{e4xjI&6-S(A|&xx+n+Dy7oXAC&Sk zHa3}<B6+<$7q<>+$4=Z*dq70~p5gk(8>xIy$5{J*xwpbeFEdHAXEcZ-b=jn69o ztX z4je$v7^Nb2ww>QJ8)9d)t9xN^s^5L|=vkGl+R-1sos)z;8yGKq9I&!22K>V5>W8rs z--eg8&;Ugwc-_LY`_)xn$`>WBsX|IWXJJS!(zSOPMWrvNGrpIZxjKE4G8+%wOcWM5X>3c@Xg8N&Owwbh_5A^3XKj>cWSF2>C zHp^ta^hP3*2zWK}^X3o}&aDwr44!?jZjz^SQ0vLABh^N6 zhwb0@$6w8#u&~a55qw0gEw^{Q8{n|_H}jw4CBX`IRIS1I8fQEYbY^dB|2XTX^@gWX1}9wAy$jM`(tn)Z;rXrt zRFFIe6_R%b-IwSpQ@5IaK-hcB*y_anTec=?J^X!m6VNp4O1o_5S3h$~h|-)4sdoLF z*Dd;yh-yk>iodEJXK;UN-nl~rXXQ{&D8DLiHBu`C}QUYI&9u> zonA-jVWglMLpo{F5aSsCHNk{1P1%a&sjym684A;;Z1iD*@Y?`qaH$tXiIZV#!2N&3b!;M{-xtfTZ$Yp?4r~s80eV zh0DvLu^i;T-f!1@1C9bkhwomVkp5aQ{ru^l69VM zH0a(kY63nswF7kw?Cu*bQ4kF}ZghhAz~SE> zLv{jxQrb?lu#=zLZFmv<7XlP-KXj#J2Otv~a2O~q%Xo%6^QXt69r-Z`bbVaDIR4Y; zaPJpS`Lm0J{W}+$JUw?tFoIy^60Fe``43$;C43}^wL_60gRKn%*SCm>-v`f?Y<3c5 z2>y@;u~Vk7EVi4*ceqrs4#V)tbAo9`9byIcq#leW4ANx{1bfj;$q@GO z`K-NZ-RfolI2;-G0dc%x_}f(wlNPJ_O2Jb;UixNjVur?~^6}&6(7$@&@m_;7TzR;D zU^(Ugt8m-3Ng&QIK10<%v-3je1z^ksPn}{P7z>*yJ>AJ-neV9os^gp+eL3&p*WBo< zVWk@*{W+>^^<5j=lax%P_P?piQ5m{ytAoo0Us)vOb4+ecY_Bm}Yx7WIUsl|(!n=#4 zce}xX;o_Ohildh+M0K2;{?pd}C!l?aST-&H0z2-ELeWJqT1MU+Y*V)_+VEWJCD_4{ zP858v5~k%Gm`+SB2RKv=JS*E4Ru_2vK7uCzM&QawLvcO7z=IvXi+G1%OMIIP`U>9I z?t#_CC$wR9t@8}(%L>n71O=qwkXFA1eVG2Wc}3dn5TtFH35#xw`B?&4!H^~8<&Qij zLs>8**a|)749OEl=JvrOp2s`D&uQO_zYO^TBfS+YgTyWXcejrsZWM<RKj&Hp#AwxQPv2h2_ENUs&_8m~r31?V5A|wU}b!PD0kO=RH z4PH>{rV3=e$-;D_R0IPk>AylD{dLd>zzpi{Q9u0ARtA4!gqOtGz6T;!LV-QDFt}7! z0P1z`jA*j7mVfbaaav@IpIY3TM9vCOg;MTA5Bp(JRY%)-@&H)mSp?T(&nifUSXCP8 zAv~p>hG}UuJCQTR;pV%d z_}`DddL+4zS>tw~VeFEHk!1S&{qEgtoyO8L*qOsjpu zF8j>lVgiPH>zhtJ@ps{$C3eb~ZLauoVPP^{rEx8)wH$Zhuh6NF`QtM^%4XI!gnj*i zVax;T{>MFDkYxU$q6?iqQ7t_(+(FXSz3$}LnVzFrG_+i1=?Rj_lg^O}4=-)7vs1Cs-$ zCiH2~3sv|Jo5ye?9MKg6u#S!BC#U;Z6hyM=>4p59n&(qt%J~#N-2No2aa=jL_-WXM zCAX5_m1eI^y0#k#K50%!J&$i~RfUZq!L%E5dco^a!jkv+NSla?2j^mna$oDutFaVR z&d1>WciistWbasSx4>QM^J*SYI%`Bter#Qrw*%)rc#nVYs~GVrAUYh_sZX|i5Ax8z zS~pD3ysa}-Wb@Rbq~EsZ2FL{$Y29HTfNrIUc6g~H-s+6A#_kQ498YCuu5nqNK0+Gf}{2Xh(eJZ>@Rv!QlLG!t*~8!eB{$gR7h5zby?|?xy8af0quN@ z{x_><6H%H@RbSwE%T-{6zs4uo9^zSo@$g=EOI-_?C&OBwRY$Tt=$RTvk%Zn>8C8uQ zv61PH#y+u&qb~YH^4k&Afcb89v%zNGjO?uLb3?hSFC- z1@=&{9&zg;utX4pV!()=IW5q$8!Z)XG4gEeUN&n6oz`MA-6O9crkX!)-TpX+`d<31 zTixglP1x+XWLpxFa2Jor#U*48wr4Y3ZH3t=F=!wMmsy7Cz#N~m90W=Z0Q1V6W@n3D zAO~B*F)3>IGxlkNj6}K)mgybp0HqutP)0l`)**hLk-)%)4wCKnhlaFSTK+Vu^75 zl4dVd6%C)b9`ISjA*RArH_wQ`F<8su*+Eg^Ic(bEbs!L&XJc~+dho39Y}~jcuzm&E zJ;6n-!U&dm;=`5cxF0t-OXQv5>dLP_uAcGwt@1hMWHV{{+a|i!YaP9nFiWqkz6yj=EZr$t)HzT<#KdAMOp=>Dd!>U-^D&-bb2iQF))$4!5Tq4-+c#9Ucp|c3$d7 zy-|1PAW08C>mw!30q!-;hKE@AOF`+6vwG|a(`87Da>en&6ZNIq@?)+SU-^XeFo4UV z9cVJ9Mmv?DMeKAVNWsC(31S3M95*<_neR9>v_}|sCgQBQTDI3^2ZChTo;L}@hD`>)=qSa9USLj^B zL%W*MkcK9gfWvmK-mwdGXShKGqlvg&y6GesxJpM5cJRFFLCUSYP%(3Lr+@ z4ST(WFA(FoRmARV{-pm$+AeX=ML|G7dN-m10wN%yK>|?_ zkggy_q#OhUq=eoC0wjPGL3)Q20cnx|!iJP{_xas<-??}0ckawP^Ul40FcWq%yFB}O z)>_YJeb#5qa!j7_ui^^NvuPU3q<(Wuh<^b9-3c5#@?V`&nY1yRPi=q<3y%7i_DbL(SH~ASq%-(jcZ* zJK=Z|;r~Y;t%$@Wt?b=h;Q*1CM*wK4%JZvWmw5 znTm8jJowO$iflcR)W6O2gk-Gx?c$$B_~^Zx7n4XVT^r+H!Ps~27cK(VMc(3hY+Zhi zSjMQ37M#Mtjb=0m9_Sh{d?gX*Fk-f`;c*mOb8%jk;o_^2o6f85`x`AmEW$sNe!k?K zPmufjum1~w>?(ZRnwR&koKqAT0qqV%^@JO~)h)1A6aBMQHo1-iEz7KEPqO%n6L)GW zeO5U_7P~Gg_;(oP?YczJV^8LprWfR`-mnH|Zk=-l%YT{Y`beC@frjwq6E&(mL)(>+ zlKbD7cWyIiL|Nx#Z-*3IO|uqf1gUvkyZ@^S>l7WQZ{lQMGq|o3#LjJneDQ%X`r9wK z!Gq@lbjV8M5jC%12i$A;@R935(waM2=s#8(&|Ryv z!bom_*?wA@EQCp$cOTxZdMKJ7eV_19GvJxXQx)E2z?^6+N{frrDpx$%u{s%Cl1A61 z=~nZdd?6Q5K~3(nASvODb87*ipUMa3oY-)?bN>CEs_K5tAcGu+H9MHwZm_(wJNUJ; zZh|ffAG$+AVN=;$=Q}W0#vY2Ik_@E8@p#g~K#t;+W@Y8|fG)w0*h7$U)Lf|0t*cLKPFET&8;cfO?@)=DBwM1>K~94tz7I zapg_BUc@K=97rtc(f0*k!AR*A(&wUb;5mK;v%>CwL#xBBhlOBxzn`u?rPu(VEF05Y z@BF#~!6J7$NCg<^DfA=sJQ|l3Rh(wcjJQZEGSWool8P)s z0^N=T^rWzn5>sIJy#kV{rG`0~^VJtWSI0z>jG=`UnAOofIq97^v~P&%oyx14Y*u}< zCTX91(XV#ULA*kriOwm#7vyZoM1WmNCA9*19TORU-i}`is=O6yf4Aht_R80Zdv5_;`1xq*Ti5iF9EFW zubnDb)u7VU@L2ybn0IEvBD4Tw3NsyaIZdTh!N9|4P#`8S96uTtsYO!h+T~pFcfDnF zVUntYYavdxd!HzO&^o!JT}~G2Kg<^bkcD3sq!*f!%cZ||RDbz5Kt!e@MG+wsQ!s&8 zMcyUcDUm@DcatQI$fj7Rz{?_tHD6NZMQbk&l=DIHL-{kGv5M1koCAS-+%b&2O^y4 zAsG02J}(Yy$Vb>Y!gToDBu7>izj5nrnnAK@`U_VzL^zIM?3<<@Cdqdw>GP+XaU3Az`O)2aG=* zjc3|aKqlskH>b(jE_tQHTInWEPt5tYt-nDShEoE-3mOeoXXZ@Tm$(2Gy{@QkH2d2N%>mc^{fB1hVArC~ zn_idBN813e3cG_tHHJ#L3tqxVk0eVz{{jO=SLmFR&D0+ysM*9$rIDIg;*Rafj8%Oc z5_}D!eNh$_1D>y3%_Qz8v&Fufvtd;G>!m>{I3fRGcs~)j0y}hg3ZXehGJ(0dWwZ|x zw*Z^3z$153DTbgSC0z|%5V8>hxu>0mfL(8=H0^_y$2Ed%CkdS>C}LnrK(YdUZoAr- zJ-}`j2V2&ObjGNQd!MEc0)-T7t=iJAtRzB6L92gKNqjzzO*9yZ5D=l`z5{n6 z$YQvJ9vbPAU~d|Z=0c0%shAhZo#iFV=b(zUCEx3mdK(JC5(=<U{p+K<>I%_fo-1>Ao8fn2ph)z4_RbrkltT4f4 zFkShaBbdhmfYs+M)+mg<$sm6%M`xF>9r*X0^wiy{*W~tPl;pqj*xc_<1 z4RegS0$CcRN`T8(t{C(OvdB3D5}ID0g<+-3(*FYEpJ3oJC@5sw1v`1a5lRD#5q{)f zARU6f^K>Qnd*!)b^m9KN{lBYpNeaZ-HjMvC*17$)_APy+fP*h!sj*~uqB}16#|J3~ zr&GeQUd%ut_jfIH`fWE|t~RIhlkalzH-)|CaYV&c|39U4j@EDB zlf0#`gc(5QN^yGPY0OlIc~ZZvp*8V4vT)@V^jO;^kd_r@jn51g`g2^cdi3MY3Ry_Q za)#=UAaD79U85=ImIAN6XeyNjQlolJtOE+YLg)HWT=sTIAu@2gnfv7d#d7CP>^S{pZslktIZ?^COJH_u#27_JvX1_wQT~ z2+~c^bkH*v6ZOlTX;?3nSy3zs+};(9OxF{NYPZZJb$WFlgG-N~At}*AW)BYY4o&x( zePLhg66={|%Av0pE5ze5BA|Y3pW!@U`?Eq|=(~sxO`Pfk+V0Q)?qg2FBicnM{E;It zVIw_w3Y$qZ#?=pyU%>TaEY+V&dx|DGz57lW^1uF!_gM6K)aj5f22Wtl^@^C|6#xSY z(iPIa8eN{FPr{neZxofO#(&=k@g*hV&~d!s(71xL2NkU`J>4Z68Xm9=v^Tfe^9W=Z zvT8FcljN~^RGB%Q*>s{Gk&%*hI>W@+H?Z$17vw-rgeX zP*Dbn&L?)wyc#0n#^S`2((m0!YV>5Cb%hU3s@hkKm)wEhvNYH97VHFntNsz+c#crpsn1*%mstMI9!`V zg}0?efp{x_$E9G#$B!Ss71TXP9h~)M+voWz(!-u_V&X;`Ckmsx&(SJubw{A9zlpl% zc+J*xgOdp8CzV|kcX34D!^OHN?sBiyt9`22OMNV2Pfl@sB`seOwdmcR$w^2vy|rvr zRH)arH6y$WJ9V)56$AHOnkHH<@8IG7sE^@PNmCz(OH$4yO3B2SDh|s5-e^i8hiGgzZf9RTDHuCHV{|K7rsBuOl<)r;k=AaV+n$YkL|ntvBWO(>8g=S zqrRQ#Vp~&&U}Mpis6t((>vTrBuZfw!hxeO;e6Gi-4POLatvcC$**<$td=1UN+py3f zL!g*+rdU`Sn|*B^|4qD$Sn&UDmZTwKu#c=>AO3vG?IB`aZ{*(mn!BZ zy|4a`s3bZr6W;6(TP%IE9q>bA1o7Uv(fPuX%ms^vG9whw< zZuGUyG)iI3Gk?E9yzdYpKnm$Ugz~hr6#1)K@Jv0WxOs?SGyOue3o4u!l)iqD8rcts zU}gL2;w*owj@NAVTW2mKw=qh0guiBF@sjubcW-Zcv#T<&51Oa}1Grr=_{Xl3x-B}_ z^u_UAb44MsEBQmWo7gQ}HlL|Kj@{&*6MJBv!`S*MO+@w2AMKA6FaNQHzMPqt4gL!) zlL{UiIUP%Bw`e~p5?H&c>TpH7Z&%iz-5i|;ybfw`?J&;O7B22u-R;CTbyP_RbHeb( zYRmA%rIF4GlZ><8w<|LHI%OG?dTk5M;oC9_Eb>tI!#_3Iql#-W@GBvUesK<;LeEUty}9DaMwKs|l?Y@Lg?Ll+n)%EUPqR ze=Mj~(>cR)RGQIt-NADE`+k`?`vU<-2j;cDsjjZOH)Z8bB0pAa==UrQl=wC2r)|8* z=*uV@@C+3v^xtk`9I0vLQR7)O>19t?%;hbPkwNPj1XFAg*T?}eVA1^i2AyT1dW_JP zWtKxYa&3*ha{XPh?domki(iJ*KHfYH=%%cm3Rvvl-VZ0U_7f!XnlUYB=9kS_fwmE_ z^KMs!u#r#aw2$SA_t$3I-O|M}ojMPJ1g&=$-*HtzOOPx?U?moS#i)x@;_E6G#Ot;( zIv7xZAJLPB8*>Su|+FE0K(~^=@j(d`8BA?_L3lcX4eIAWe$$9g= zSIb5iLMM;EIm@ian#x%{Q%|!prQG5tO6@+D$8rnNPDAfjBk!T-f4I!`%+9LS&&6$U7Q`0o|FyWgr9>*4vznhyWwDc5?G;11Y^$w;R^nTWEGFqt9ol zCG9iC&+XLe!aKSaN`@@DY%yJE9H_L_#MQ$E$jY>m74SMcNXmJ?lY*qiR35hho%r4M zOZcxV5V-A-RYT&90*vf6a-FmBbA0x0RbZ%`mI{}@k;nFo4)eE3fq-J`GK3eIX%`Qr ziVsj+5Vkd>X%tZbB;7(uRucYwuE^I<#l*gwx{!?uKLLFB$wPg?Jg?HLArYGMF$-7O zK8Al+oJ|GOBCrAq3q2Y=0%ZBf#+%5zl*`-#J5q_QE)%7lUH+ zDwW%9zQB==_0|o$&PuzQZH}NsWLp-{1a`-JS0VW{K@;Ui$#|}eY^-Ue{#MCW|SN58u!}Z2B9=g z?=T$mgdp9O>m(^a%+0#o?e)hGr-1V@R_h^#%lM8~E9Kc&iNa3{S^KQCKmo z=BO_fkSX0^A)-a7H)!da&^RM;ptlk*H)QKS;Xp_8;a5_24WtC9LNQt@tR0QX`Bfz{ zpUzWEs!FaRAMc+X-#pIvWC!+j5X>UI z3=L#gdRf0N;5HJc4?<2?b)H9<&1eo?R-^%8C}0Ka+%ZOF zDTVo^&CN-<7N-hCS-^_v;AD=DgL6YTERl|VNzruOMloMWS8?|^P7-6qB!>%^?si@ZwqX; zL2PB6`w-h}tY=}i&xaeL#~!4#;SARXDa~IFc|M9aWOsaBvwnqTMN#d#B{jVaOuMLB z1ZYyO8s=D*$)_ELr~CE`KP1O-d57h@d3_ zXwmJeHP8^?V>|KKt7TH_W44Oc!>YUbUU~UGRG|gpNC)8+N#&3Qa3A-(qYd;Dsu+7E zRmZmzhcu@Ht9n0yFcobwC@l5o=CXWv)r;Rc$#>)obUcGf3NyL^Cpt@wbzcE+DGpn( z;DaB`Vv2p+(Yas}Ca7YXVl%q?5lD!gf2NCZJ? z->TrSB9P08j$8YorJ#@pb*?Anrv_JSrZ4!pJ^H<#F~+)S({k(%<@I)6VXb@o*S9_A zQHcUFlP5+GdC0-y^$)|s;-$3dl7x|#I1X!#JgBFgc99j_FFQBj;aF9Cl}oE!PYEmR z(|rS@Z+pn%ECKjJpMi~Qidokp4~80EfJ6zmg-z;0up=s%dwZR{xJQF%4!l2xF9x5} zSiY9+j=I!i@K{V4gFkPTwC={0eJ=t=FvXZbL0F$;qcZ1DkbFHKh2SUmW6&&sPyfuG zyG0mNnV9tiLV{fQ^KHez#hl2xc@^x?O;I_soM0a>amO(MSP2@pL8I7s{xjHdc|g^RY>O>$dWWwENR9!l_E?iB7FvYF`}iK`#R zPgkJNyJqbueMX3q4pGD**eQ6L^&9<0d_!GxDxKHuJL@`@E;qG(Kv@Xn>JN*!;;6BN{K{G;Rp)>d4A&{OhN2FP>HH()n z)r6VvPnhQhzQ$#ZjSHq+1!LV9aee{ce425?RatAvJYXmv7Ee3>#2uYVRl>mp_wMKo zAS_1#HUTaUuv)(p(&gh4DjsSu#Ph*NTrB54$>lfWsq8WA59iG}CBzML+a8CQN1_;l z_}vXVI#o0E`1A%iC2Ia*7{BR%t^VMD{vZ7*71#Xr5Aq}Q!!DpFM86(5CtFHQUEw`B z1dE(uCiIAoUZesus(FiUE!!--HI4qF0_e%ZJxMCtZ@n^gUx7lr?O`e9U8K$=PIZ&3 z7a3=t67^84raOlQ_kJ&s^P!t_bo9ir1$GTR<38gSxvRX1{sl9c*ExY4#8Hg!ItSLI zxw7x59ZrKO6HDYk;D^IR^vV&W3Pi}vz+R&$?u*e^Ml2w91G3g|e?#i~ zcP}}#yTV_h zI#`K7t0{!j3p!7%(w$AnPC;|Uf-7ue+GfeUvGFAJ{Od1bm`)XBx08_!!W@7QR$i{K z8L>r+oR-zaixM1cPw0ELYb!aj`DeEEiybog>UIORu@>;YZoLGzNl>OCk7R zNwIr%?a!F8AA*@YqJ~NETxADKQn`Xl@{o^~(|HPUk5*3? zgnvEEqy3Hc1&tb)1fYX!%0gMeDYp=Iv=1O~@^2S_WawSwOPEBv4#k4{0N5dh2TCBG z0APEmfX_fUzCw(p9je*pogNk#RyJ!9{M-|t48gSB$?`4VbQ;5kdfa!)84U6Fl{HaM zaR)U3?R6s!)Fj0m)GH%IywD378l&6WQh(>&ytkS=IsC&m|Y1MS#D^ifJ)o>IMR> zW9pT;2<};i6}`@MnX0psBD{C1Cih*VM480bDppyM||N&*SwHnMm|Tw6EKTxOf5*xN3CKSb@QfcP7fmewg5IlWT1_VEismzIfqh>X32 z<2qwXgwFF>6!ffc)1?rQNr)YK;!~pecdK4nO7jZRpglb1z3=QONDU~B2rnA`YwOHwj*QNO2z5RRkx@=JeLDTnhS4C3! zf_~qBS!60bvPZS3h&d^xvj*Z-09oXAEm0*N6ifwSTo}l3zcXQ^ssdUsHvdi@px2ko z=U8x!^t*_Vsq@xaC+?4j_hvY%&UMbi%{*2l(>p6B`O4c!EBg19(*{>5=7w0IR9KB2c^I!NsWa#lYhko0eD?{yr6s%0TSPnGGQ-f1EpT zigFv-?bvXc4K^=}pH3#Z^)E{TP`nB^HJG#>Z(s-tfWsYy6}2WOe+D>CpG2@;o>eyb zes|nYCwSI3eZ_6bFInP~xoIW6PycB96}aUhk=McQ1g4YwKeJ7ylqeByJfZlwx;R1h>*T=-E0^G}pwXhnrgwyo+0YPCQF1*yr;sM0 z-MHM~BO|6od`l>*+>KeW;@>b;*kHV&BbK+ppD1xl>5^v|@w_#U{8TV^&v=IUShChh z{~2;AH$3#<@wcK^7@)kDu1ijh5!dT=W^YcA1LAt&N!F6&SanH=*Hd&Okgiyj5i}Vj zej}wYZ_PmMO}`g^-8LFb*tbxP*uVfm#7KqCiljgyhm9Bk7u@JP zPJG%_iXa-gV+w&3iCez;=j&CMuS!;*NMN6<4qUW}qd)sCYN-DE$f9%dAbe=)!U?Dk z{Iz3T>#~Q%%}x+8TdT=G0<~a@!y`;B+B4^VKi#7EgoiJfoo|iF(Yrm9-uu38GlLXX z?c$^WM-0Bk$75Elo|0N_^`FtR!P=F?V(l>Z%EnN!`OJJQ_C22iutxP`It0KRJ z66+Kl6ot5nwJip%K|j@iM^g4nw!grZp`-oOx^y%}wiZ&2>_d;q(plC)6+0!0404Vc z2>pklY$pSm=kc8u-<++qR7;zD8F`{cm2LX1K;s8@@`@-5Yvh1cQgt#(3_s>*E8+~{ zoVy#Pe%1&C6}n^dL-PF4KOKxMw*Fy|I(u9&u+n%(JvHVIzn+O1ls6<%?*{7llYD5f zD`ckplLblMfuUDc1R}-D z7OxCYLO0HZq+N>&((97_TZ>kOLsRq6oXBm|0LYjB4JK~#&=Ba)0XS&o9zeJkW;Wm3 zQXi!fe}ww-uU<7owmXT;vvi+MiLkvl5`!>W)42u=drmvh&%X6<}bX2st)&p4bbi z`3bAn!4|~jtHJnzqOM2?P>K(HGoN3=9(nG^)2|)Y6cbCCE&F!u%v6cW?;_}$sVZBC zcr7vbPI1mngaw{?TME=w;!FpzJUFf9PhNO0j2Y@ZnlQftCW6@jX!m~Shc5_wvUf(9 zS74yl)Uby0@H-D}RI%^je8A_z(r%g0^F^CNW6m2@9HXI>tDrG`3<^oZfpK*GdKXAQ zyf+F<#GV|c{!Jfi<4pD^K>6VX=B>_S)a#+ix^DA+Gg-K}u#dMpCRTIK)pv)9>O*rP z2S5eQZdl4nJ+hw*)N}m;R7Z;WL->uP+!1$4LVY_C#0Wk*-;((u#-3ER;cGR*pgYOq^D7-Rdqeyg19@}!b{G>On{RydMt ze_3rX1j1iITGk^y6MEUg3qOIg&OTX%%6 z(GSt+%$`AvWulG6jj7%0^RMoLPVWI#6}SOc(lVot?;mq2KX3F(8C zz`s`Y0?&HZ><{Z6ao_{FfV@~zKUVx1f~3dALKfokY6xmK?a>5O^oMnw;%b5IXr5lX zo_iYe{-@IH^F0#>4PzCAqGO!(tP{Y3R<}cbux|=ju7+%$i8kV*-k9qA3)D7l10$GJ zNaP5p_7tkh%lPLKDP{g9-&=5{d_}( zDm8xL;w82-ttOB7y^JJ4)2s@%rvUXFaRuAGL}WCCuTy*j!o1z!T-k`43%oXoP$&XW zco^0$ATssK3f$T%N5YD7BW3>b4sXvEMPK5w#Z7!ibCSxN<{36{8({^6R3p2Upq{&N zCtRuRB2{qE4J;eZ1X3MvpuBJ!_+As*_56)8$Q&11W;Dh8TeS?;h0^v$)RdMQcs?la z{NVMvvK;I3K3Fg?3kZn+9s=VI0+JT6`RDM9MCCaC-~je#7CqUn;vR2?>fAxewAVeW z2eo>cZlK8Sh7%#i%viO^O{v6Kdsy{%vg@)@;K!gQvyVW1^gs&|V_+pDMT(AVX}b%)~#Yk0|d6m^+l%si2ItD&7q2Ey9`$NDhFn6kUY-xRHS` z43s4z@8W*fg1y0+F`W|46T4c0ub(YnfU$4Jha7sy|8^^mvz+-`&}m+|tQH<$d64Jm z@9**;XZ}p8JMAU<-U?u@wekk^>t{p&l~M#lXO=TrIjhJw%hj=v?ABloQ~EMEg!7(Y}uyDE&J#~7eghtvc@#MS%y#azD}SBv1?N2PIt z!jA>NQO}RIU#aL7Nm0Rmad%4w`EnYCFY&n(a)TNve1#d-`lB^^R&25UxcXZoVN;Rf zSo;z6#RV4jdR`LbcF_$wbTj%UeG+6Z)>wU>XWh(+`lVFO<~41VcsPKpb8{4Aa6$St z#-*wBmI)?4k>2ARRT0@r<5U;^SaYAm^DYZ=YJ@{G2ttRM#9fw@c;u zNWUe7N7IrEKwV;usS1#>tNy+$+%K;+HDlM zsCVU9KVJ$t=Zl4&)V%wL;YuX4FK#pjb{GiQ{lnnEe=R`{H8MKc(;ni=;MW#s82C7a zi}vjC?6*5D)Ro_TY*_gOm=S4-TUH4dcwH-e=`T%;0If=|DXS3VoqQY6*y)VcIJ#w z3uQLEN==E-L+ReWF10#uZiI8rx3*h3odHo13zK-lRSeH18h7fBoM~m8q*b#=c7jEW zxfclBoXDxxfuFgx{fLlU_PUeYke6r1L3w~jT+Bj2_eB`I9dsE}ig)_2eE;#2kq#;N zU+Ksdw2mDwxNHJ^;nBOBX|fE|Z_hb7O>e7m*}~UL_x34ZnEE%Q7QJIiuIPtIMv5Vj zpfb?qMXK#|H3E#L7=F=3NJps#V!i| z8Dn0Xo|ap#A28u7DY$_9a$-A`n@cpTYvug8oFaDqoZh>+V5IPHTjE=Aco$w_* zlpgT#KOH+%pd&$BOL_p_%$4xx;KBgF!YMAWsl&)f!aoexM}b%1^2(w?)_YZ`>iK;C zFsx0d{-J{+f7WCA8LKa=bn&lsceSg#cbgUM(4^rI0G#VJu4KgmEPnbb}gKI(V zU!^}=e(=!%twu%v4h+Z(ISOe;8S3xf`u{Qp7IdWN{~u%U;D0j)nJ(PiY5I(l3U$$a zdJIYAe#3Hs4`&~EJ4%R{*=lrmpO!QgpvS|=jNq`ToIpntV1Sna_^{urAphZ*52Az!&+Q`FLJKBW<`hd(S2QVu7ud8P!*T#s?)ZgWtmrkf4Jm z4Z^{f^wIS{9Ww;qc>#c=ia_bNC71qT_+bRz!Wj^J%Hi6t|AZdX_)pXIKhEKzITeuR z76(2}`acY-r~ao&d>NGAVns={z}iGUM3I;WSJQTAlEF z)4S`P4fG1B%^ea&%#GF{=8ouEi4UsTe6Lk2eBHOE1$Gx{o#^#y;i|y>3U{#J$+qhm z<#V*Wru#_xruOQcOLSl2XWwy1x3M#QUB`YqL5#Lw|_ZO@=08ZG2L}$Mm$~ z5a`)R-N+?SKer#52oXWvR}n*8CTW+D{d?|kkpe+Ff)Boc13u!mB-F!Y_$Q;W^CRK1 z3voPO$!hP=w59p(k&U|I;B^~*dKDK{3{BeJL;AtqT*oC9#L-1S>3k?5@W+vO>MdIc zpc9TCVh}ql0$v8^B6~YYqmdnq3SBGELT+#SXsP%lqed;}l*67_Jms&NNt>ogK$L%q^Hf+Q>hcSAvbuP4>LU_ttuhJ=p$sZm z^C1LJY=G7RTuXWq{C>=`*UN#jpK#>1`%2tiuF9m`J#zM@O?jM4zMfSZ_I^dHU1zGGINE-~DV+nZDvOoc!Lp;47v&+sniau8XzWf^|F-{T?s7z>ilSW zh?danhZ=u}kU4iT`B0)9{T%6u1{hFd3?zRdu?tb*`5~#Fjiizd98T20rV334Uh%y? z!2_#F`R-pHQ13^d)DKI=#wzu$&L;7d?-WI2WGcdMaCyD(c$|iVQwvks3uKtYathGd9FdX?{eJ8*v&qN-A9i^(pd{_Xr zyR<255=cB>qh5FSNNDa)FY8--r5&y0QOumk z=t$pCNKX@bc>^Ik-5CQrkO#5E*PR!Rz#6~i(rt{4SD4LVeS6(oVfpGcVhG3VDQE5F%B$?HS~L^z{*n0EJ}78lj3x6KNHfgm z$a(I>x7OvOuGTX~2-(kxDd?c7wufe2b1q z;(***OOmpJYK&q*k{Z$(656*vE*8ZtDmNqmHPTx&inTd&|1Wm)18@- za`)8RVUqY7gBx!KYFdUR-Sm%F&fIkr;z-5X^b$6%=~)S>#5lO|#g*8CmH!Q&{w`wr zv?@f6gzq1Q0{+B`51~4>ZKUbe&^DJwB)f1Wea7gNuS!F?ZG<+#RIz%W4PN@7Z_Xwj z#nw(sQpUznpoCj0EawE!q_6#&VR{(DrizPC)){se&PJA)+R?!Eg1x-L2|@-*ML?TWbc%o2UN@*`u0) z5s&e*Lf_PIeNtP_u$q9h6JOHc6HcXX3itd*tn8}dW6kUsW3Z0pGOM-?B-IMrC+|1y z%k}ioD7+Q-Nl4Hgn8l@UAzvyKF}5+{GK_izBTj<55ofY)Sx*Wl;;OM)AHHnD>|eU2 zmfZN~_m?J0&-Ufe<)1=kiI`{m7dvIhP4(5+lRmj|K&+a7c;01Uy7YK?-KJfY+wEy) z-*n*by0;;JRALRJ@u{ab{67J9*Xzd`zRf+zS)S6+T5M$;?d*6r@4pa-d7KvZKx$o~ zS%Bt({C8AZAf(9x?jThLusj!u&t=f<8mSEKGZhvG8=1)dYirlRMF7Eaw2rI*PRk;5 z=_`SUHIRukweR6n2qAC`_R>p#QQADyCb8Vg{)@LotZtUXNBfe?A!A|H-eln9sZZdt z4Q9G~y!^qJo;q`dwU(_OmCriy!6l~2wfKD7<^F_@2wv`Bc~2*NXA$QTm5h45#5DTFNYqk zeNgtu@Hz-Ou4dD~I#rlzm1jFuXuYy6xt1(%&OcFZGg9J0dHXY|xa|eVx_mpjgE`g# zP=pn($UzwCDKd&Kg9wWdJ>%(ae@2{6?|dQqH=46 z3n5+M=VU$QRbbOGUfR}rQ9L%&SDnk21F=Ji0N0d0)Efz0V(#$|j45a^jYWAEV2;u^ z!L0=SJpA5{W`QL2^2}qY6um|Whd;-eVWdyT&AW+?V}Hc_mt-BHzAHbH6HwN6{8)$4rF&($R6i|d>KJCdLBSaDlKP_>vNgGw z03QsU_eWKtSO8eLV)U`l_qGsahqK_b+x)!A=&O!20Ywuxnf9&TmHL7%F34t@f4(jt zLCWf#U#zQ~@Rz&*MBoi!_AMDqJioQrcI3mq#@<#n*eGTQPIB5W1dCOUBWI{YI$Jy? zC{n*UMFVWJ{f4GC{vO%g2?Lp@Fd$NPr#ts4eTv)%{SzDvCKu&%T5c)5P{qs))nwEh z97p6!Hi$eTqPi-$6KUR zNX%{C$hU2FSlctMcRD1i0~(M3>ZZLwj2~qkjFkd>-LBTL(j=2C+$gJWCtFK>>%?yZ zDNp>)g$WGb?46?CFfXI%GsQ35o3etxk(b=e{C+G-wGF3KcGdU5xTqXBHjA%ZrvRxQ z$+NZSJY`fR^*p{q2;hbYh;MrBurrAPeeG@m|1j8O3BJAK1~wCLyZYSs`RS$^$1Iy0 z!2uxw`kEnbi&y2~pJN}+6=hx$NW1QBYFivlO#&B1KR1-GN^G@mWJA%Sj zcVn+$=@%k_9}%HVLb(Xh~@=d zAOX5#N3r!AyVHdh@6`6_MSg+5P%@L0Faa5NO#UF1dB^Q`CY~-8qaW@leJ?2~sZf2^ z)Y#Ol$iyh@d2@*2#a~Y6!lx4S$2^!%ts}WRxj}KZMy8AavIUsoH@dL!D`e5*;Scx( zMjsk~Vf=TXl=I`#npCHTuNE$kFI-RXJ%4umf_&{c_OL9f8hRTXACn=H!UWwcFdBMn z3A;Jw-WVh-x*zI)H^||O`JjWsT~dahMTV=vlsx{6<=jJ*j@PHUA18{;!oiUaF{LjD zTbdK<+Bt-5#=2H>t+8RxSQ9IB94ktqhxWHQdDAOwZOd&YFm|ExW|L*>+H3SjfwL2b zCimDPhmn5?rp*PduDb6|9qJ_hG?t&dzP~ENN?yXRxv#`Qhm1{=Zo}Y;Rlp)m2DsJ zD|vK1SU76?#351;uJ~6(*H}$RO2|yd|9goi|6T%l{02tmMu5)w(@{#}3SHxl>dZe3 z+C^)%VCUO!h2~syi8x*3DJ0$jQ1Bi70`k~!bbGGZ(ZlPutn^{nscxGXDLgFd72^+{ zPb9;b|9)~9c>gQ^!~KINr~E%BpP{Q4t@Y88kq>;tU|{nNZcMcp-Y04{($wTaF7!Tf z?i@SUTo&#&<4fkA6{fpf*2j!a8=Q6A8jJ*&uU(hdC7lbvlRzR7*G- zyh8fg1Vt=z;50YV8}{lt_f-g~0wMCvfCtnK_B&c)yZVEw^l1ZBSDSwK`In^RkL`ei z?_$@-ws8{&9V%80NjLnxJn#F9J5Dz>k>&f@xlP{nB?#D`a&2&&41(X%Ecv&`aNPSW z#gaIT=Pz>`>klTjMc0x_`2X0X`x@GImVU?yR^eTLUw(U3H}y?O8^64HBdf>=GH>nR zq2qhQ_Z2opIqM=B@>*UNM^7ru^W@V?Da|&RMb_2!`?$a}RO7MKID>FJlnXw3#lIqa zZ46;u?7a2Dv%Nuay4hstb`)W8^zm??$Sp78#SAH#wj71JWWU)L4O{pv2h2=~mTkrh z0l(W-=EZ?S`VM82C62ko=R^9Tz9Tx%(!Lr+HnQsGXsH4@n!&;^eq`uRs_~aQ6}skD zmRMDZ9&FiESeYq5v@fycty_z(Ykv7J97-QHF5NyNJwPt$l1l#@aqk`u)%u2yD@l?j z$@wttD3zGXDaWbosKiuu6fu<|CMF?b%nBjI?2dNCBq0gOVVo!DN|_i;h&i>B!(>eu zi#hDy+vj_I|NQ;^{iC|B)n&|D>wTa1exB!k?z|+?@$LCiR%T0QW(UrDVj34WZn)Tl#5u&H+wnq2W-`vNwEV- zOKXynEK@^^)1S(~H6<-<6{|G?bsW(0jwLQlM$XQkki7{*OE;Z8019MZXFSTfm-$D3SMRV@>%&2iUV!}_>2R6E zn92}iEdPH#v>SY=&Hw#SkGELv11Mm_HEdu-q8vD-+h}kegq>;l-(@{er~Cb(#w7rS z6S?+z66#D--i-?A8D-)AZLk`j@lX=S3A_YBE%+p3e>~6^6?o4$CoIy{D|M#MR;^sUNS`EQpf7dJ@Mu6Lgsx+bDSq>n~G=y<+ zvQycMBilg*XCFnDX0RE&+@F#E$uYnWpQ^*lQuA~{-WB@?P&)YI6XM$1q6%xI61h}) z#Qz|ik`l7DK5x_s{+<{gx0&n*nmOkCEA)plBSZFs`ER%S zlQ;CYMYhW4J$Vx8sTX1VrL^0!CDQlL`|q0SR^X1?Psp0$SwV`$``5m{w$y4De2XsI_!cK8Z!^lv7gF=Jf9!Qe(LN!^6$$?j`c1!kT&q#3T@iNNglndV7DEyT zX6vbb1urJlC$yB;XurL9#lYwKUzOaqo7Iht<%#Y`KE=4C(!VLjQC!0(`+v&MPWoM5 zqqd`&oZ@e!A>-xhP`wdO_d~SPJc%JPYgJ;?D{E9R%W2?;qr z|08nMRtxIJLsuf|?L*lFi<@8G!pp-h*)A|MpKY>)N^CVj|WFC-GA}eywwxlI%ANpn+@N5bHCgko4 zsj>tx?-Rbr-eaqcXJ}$K*#K3!$wjz&nJIFBy;7Tk#0N@2VNn1GkRy8`%dC>B4 zMC0sgB*DjLNAUpD8OQ~dIkP?QAHIL`btCiVtf`rx{11u%H|#2U)sMY`8Xo0P1?Di1 z-4UZ1Pqsz2w0HYy_1oi%FV~K5XGV-Jm6r{Tdei!g2dcl!`akLo-L;_nLVw+r`+I9$ ze%&aLeWKUUy6Edc#sN}s&I`N_HUO_d?p{_D_=?v^{zQCXe^H2#aFDu5aw3F_Pi`~C z@lX_rbs&)#Ry@T(Cz%>(TiPirPfrVoUK+Jkr-xlig0Xc}_yBw3WkAA|s4mJt%dmV> zr|hAO!llP6=Oc+H5~A~%hXzSoE21;IJFa^_S=uw~_WbO~*{!^iV z&bi$X>yZZ>&6wk!Fe{VJDWDrzQrAsYnirNg7Fba^Uq1a?x??55!zfkz(rSk#rw@Od zV>zQaJ)JdRVKnU>^EI)SsH^dq8fx#9f;Yed&ecArr_Yjpek3M1bSZ_Ie7+KrFzm@G#g5BFWX)@L>BGHe>}^yK`U z+}iFp-|odkv@ThTYNh|Q=#q!gRmGk7VHR&tR+=B}#8XWE+1C{GbZYLhEjW{#V~=
*FJ zRKpNpxj21^9{4}MN!eDROM4?`<+LBBFA@lgu+tn3BnJkX)Hy&aXY;_qR%T8YP`o5Q z{SjlIJ^0|{`|wvgKSjP6nNltzEP98J7B5VK+dhb{h9sI^oZl?W5jCFTOg-Gl!3v_p zL6QrIWe_1;*mFdB-w|~tdiD@wlH>d?r2SxkCiMi_flcmh*P*qS9Ykb zM@?fjO^gu%l#y^-0@A63TN3sAe9FuOFC%8+P`|y$3q-j)Pen*iR%@egkZDPPIA~dD z4Nd`Jx6_ocUux{4F{TpGU1fSx2%D3}n{#gHMaED%<703>pL_?GBB~fMK z5heIO=X#0wPjoU}XN&aBt4O*wCJhQg$<@*WdBhDQi#{^iyPbz#e_2zfxvTQU7mDhX z*CW-_(;Dx$mKWIO=o?Q{5UZbf+hQSZh2qJU-!tylvA5$OcS0bs9>bQE1@=za)`m1C<-ZyxeH$KiFb^HS8ab? z{;jTa)&aAkTWaUc5l)#hY$Oim_;<52ZeX<;gRKj|C=oq8PadFFF=jy4wQ5>OYu9QD z;^P&)5r1DHI#Yt;&u$EEk#9<1|J6TZ8j040E{!mvL$@TlHB$dd*m23<=-KdEjj5&^ zKsp`>=McZ-0O_X;4&eHV+sJYQE$e~Gwt@5>m@KBQl5N)a>4;&s{Zlbw(a37ioW5>b zlqQ1lZXqS7Cutx|(5-ad$v!mHHfi8Pn=Ayx>E$}~V7Fwe?Sw>@*{o1g0sv!?_P%eh z%>oE8M1N;N(&bU$}M?X!>Q-bUZ}n6+ z#>a)XZk&ul17yu99@j#mz=Miv0IR+*+Q$`^N*T8SM_PgOC#;ybV3KM!Z%4U9-M~Bo zcV%#55y5O(1##Cr{Y?|Vs0xhxCtTIr&A zX%2}1@zBZRM#A#Mjc(XP;D9piU0!zMlId5LE%~lW|ED6n_f$jP10S~*Cb5uSX(5=C zU)KNMdSpn*nYZ{eLj{KSY^*?oP0-?bVpRSrO$mk@k{K1%0Py70+Z*clH5oLo{{R+AZI z^JXN9&mPqkl@BfCpi}%Tgg-O;%Zu|Rc6||UUPtPvxUK$KxVqYu4xI-hR~`W?p!G?C zFDLul=lvko!b|z(AjcgnMM+EM3VR>#C;WKo*Q;^S-M^lLt028Rrrm2(Tdg&nD0?~) zPwlyL&ty(lroc<@kU_U2ma5&b5f<&@S;Y%A89p1p5-Te%sOi8ztWM zRf2&tXfrFyBoRW*86S92l;djZ?LhREmN#KIQj^oopK-VG-uL&n^bzgxVb-^RnU;f! zYb%gLI4v7g3NzYzS#iGaKRG4m`v2sxi50Pgv$3cJ?Vm~x=5Ou$(VM29P-^27Y{aJd zd~N$1jvb530rYirPCXC-$E4EXBaDRK<8q7?I*Oz!+|ttxbki@<+M!fOUEzb6mtzc$ z9bReLz-aIpoGZ(E@nsu@N1)6w6*5bq)un+~{yjDl(xxfT1ZtExWCt}R0*@HEbO3v! zov4|}a4!1xasU>G71$IO1fa^9rPr-};1b z0v%oia*`rbDaGTb`7o-JVh{!j@t^09Am%ztt$8k!SF=(U+YyapsAEG573fJN zPKQuExg?grZMHr}%j=Id-4?iBn^V_Q*RpmI{xTA@> zR{3n_M|(w)7l=rp71eqUq?h`y#*#v_9qI1@2)YJ8eQySz03J%s{BCvspX)rRQj9qXTA(-Kj605%PP*$Pu*ga zv=+qK>fd+uQ&Hkxpg0iJ5QWXHGypTc!AmZpNTF9Zq)XC(UDD`5)LVYqh^ny1GsTOj zC)oi*cm5DArjSgwwp7Lv3JNJ{Pn!qM4`db;9J=)4>#Hc12_Y+6S2O{^|7d>q8? zfV<*NAg(Kt6-c`f6CQn}QN)x!-&&6Yy9-K~b$=|%*g14YuuWJ&srkXF&vAkq#=XZn ziRw)!zK;1!F1Hj$#uZHJxb+t9C)Cnd730fspQsgdxYqs#bxCF0KEBx6UH)s}Ob5Th zkQ%HA7ShE)Z^~CFU=qPD?Q$b;An8kK;4mxI!E}Mxi(LmEEf(3j%5g0cC!}=B>#9Vm$dHSp~VfK3^jXbF;}+SoPKxo5mXmxNAszUElX};l)n@#`xZ! zhXrQ+N+0jM=qrWgSd3XZ9)lPJj^M%F#InS}*z?ky;_&z1pn~gN*yaDNyIJY#02o359S4H?li1guI<}0*QjhiMLxervt^(l*}go{OAiyEXL~uV#-w^dccgd7K}IP zDEyqdPGZM%P!(($tXA>qqK-HntQoSHXsPlkbEr`Hkn_)B=Z!ly`_6)wAwx-|sFL50 z9ncAbvEA;>lnSV7#S(xlJ_Zi|$vqv2qkq>e4sZQWt~k`DbtnL0JY~C9VTskRju>s z>#v+?-FmYTAk(9qbkbhj+Gj>|Fo%LhDH%{$Bq40a4w%nx4~>J3}lv#Da+ zg=Dvn<(n?P%k+|`Jn#pE8^7OL2!<2M;8e^S7XL1T#<2}#b^PL5lSveSOx<01Veb+` zLHz1D(Pcg$wc$_c?6e+Q93%el{|#LEGOQQdYN)wt^c}-q#19g<{Kk7)jRth#EaBcB zfuc6!`r0$Ifl%$M+1{K^(h@+Y*)Jn;^-mL<3^+~c@`4B{TD>2N$2I=doN|;|k-D@6I~*=se-eodDwKGB zhB#nZySx%cX3ZgPUEZ|7IYH}r~C|j z=xUd*`F7jKaW&3X7#$8ExGIWK}e zDZK4l&J;AK1zj4jSTY1~i1Q1SO7L{H|vV+@Db@-yx8#-u3& zCjfAAuV)FK1{N<{=Ie#A-Yq!5`=%32;8B?p*aZr!|0gvaAT5G8R4i>aL88W)9i@q| zDZnFx&ci3CiP-DOHj-^Z)z`L|4vNa;n|htNsROSN@-La);j$~U)dF&tAfkEwGW%qI znY}y!eE`#s8|eH_u|deQreF9^?h9K~`Wd?9W+$qE@m;zVS_rcP1SeIY?%~=Yl4b;J zIiN5$h*xGC`!}{~=2AbmrgC8ZM>g-LO+b*g+_sz05j6Z@`XB6MTG(A`l{X+}8#vq8 zUxikHjiuc-x+I%9Ll6%lqiW2qkHoAIf4Q2$4EY87fQ6h2% zd$TD#-w!e5(r5mKnQaDUeG*rm!|FJb)^W%Fh0^Vj+Y9Pp_ht*7d8>xPheJR^?(!~7 zNa%&SOZZ;KDyTJ-Yyv=oWQRD2+=GYzdi)Hz3v48NqFl?!AH8dnxTV4=H0kgYA|{BEkKTQXAowjen|e@;<}*hI2dm_%t8xG!KNZuum~&o$|$TZSJt*>EG? z^e?=()Q&W%Bkd=0GUtxdYLbH_%Ca@@c?@J1Lof#uMKRL479*(DjijyF>fps=rSAIe zi0MVGGQO$lCnVmI=^|Zm@*QM!V)ux~!@^uE;---io0^u|8rpqV@iF2A&dBU}gACuj zyfiPr%wkH8yu!WsGTIYSrpLN^Xv;sQ$v?*Tm+yUDDxa`_WO$XqRhvSge`oe=67REn zYV@PzWuJw5(-7j-iyOAq-$pswSPAxG$GXCMukOryTvL8cox1}T+nYl8u_I)W9GLeTFoEOP|NkDx1ON8|0J8f9 zcK^xUZ2+AuuiUV=@4K9#V?u_zb1aKPm8eriBCw`GcxuHqoyiBsb`abyau*uU`12UI z*{dB@5eP3VMN0odhQ_UhEtxa}Q=c(iSJr%nM$J&(K(`w>+n5^!)KW#eoBYf?poW-iZ~_2h@|6>Et`KSL+f#+xFRDj)yEiK zO~#i55DVoCV*(W9)i--jC5*4z=6q|;j)pH&lzPGu+ z<_vqn;`bFnnF~u6-*6p5&--^HUc4^4I7V`z?|(J)*NZcbfN#NDPHywZvIbB^qN^la?od|2n3xqqMX=B3u|+=DBW&=!y1941bxJs z8#n`atCGK@MUIxiUbe(`;;lTr`+h_I%tzXhWwFQW>QZpv3Epb5Bii5X4CA3T5v)D4 zowM}%jZ}NCE_#_gs%19BM-^2RgV)7!0(C_n1F$Wgeo$q~4uFh-GF-<8+K)d9z>2dm zK10!-l;#$b@xs|BVecoj)g_$>TJ#AN-V%WS0+cdDufe{BzFW1wkIvzw2(aNVgDZig9GicEm;%xU^j=+Xy$>~Udnu^D3am>}8*Ml+J->L{Y@(8B78>&8&|Zu4_zRBmM_-b?JUv=BUkt-<2r`sy zTXv3}%D%qaMIvpBi(Asawr4;`j0XbdtHFvRqoJkHyzZsrf5k|edQq~Cx#7mr-Rs}# z68!45?VY};X5Lu%T~NYK%&!=gYOsXgS_MmaIQ95n!qF!adVGVW$!=CH&WLe7&xMS9 zi~W1Q1LbV&+Bbq6A*p@*j=P(zre^}*z_AyM~Khq@nsHW*KDuv zUK!qt#T=bjUcoqcn8D5bN;zJy-P&uT=Ht9IZ%vM!-{ohdt6@fI#o7}sH?*c(wdCH& zs6DO_ezO%F0M_+kF-;J&ra1gRxwHG;Dq>lQzv21!Fi{`kJ;I^l7HkBq`r)0>PDl~J zXE3uz8CB-v1ogn+bClyEQJcdfA>u8v0lF#__&(IpEI7{*rlv1EfQRViPF#KqTEj6H zx^W{v=+Sra3FRW6+5(fM>m?iF@;bq&#acj%P}n9dCm9N-0ZTs$#Rqh~(haf8*l z9;avn{%K=DGM^RFt-qhudRk(IMC^S(Zyzuaw3%g`{TBGYXBaN~r#bpl^9w#qv-yET z_hieQ9hIQg!w?5d*sF=Mq-8*{gpmTt0S^r<49W-oDo(AofnBO)fNZN~L073^btpR= zTx>6Hi}~2HD{_eWo*AmbKigWgwDCq5cdVEF8XJT~c4i5R*wvc1u$(9K*Z7%Em<9rf zWRq??c8x@zUoiq|(*U$;6#9$JWS?|?*5^-pd3QZ(h##=9lSYPAEcm$IzSump`B#~x zsflZ4CCidEuxp;VANvgYKlSm>*`X2O;Jrm&k{LFA_xH>Dq9`?=B7X|%a*md^_U_YL zFuGpRi39w$c(7GFMrHjP=qj3I6Hc@j*(+NuG>(_J@=cXREz$>)Q&GlklyzeW+2lgr zMqyVfFV0W4RO9O>`Z?;#G!5}O#tO`y7CZMG8?1J-J40te7lb#%^VY1oGqG=#9{(vr zKgHe60b4O$@LFF^=w3ep>!FrJHQE#Cx$ex}arJ1Y-&>@lSx(Pis>3q8PhC2pS&bQjV>k>;Q|6RAyc4JJkO=!zP=UdkYzHe{!Y=F`?>-o3X z^!VRT+NWhXf&?0bue;_7zG0)mzFzaixBK2}&G&B5Z{Bobzrz26KUxOc-+iulH>FTH z(PAd(-8Ye!+fq<=qkY}M-O+L{?;RMIlV5Qa_o;gQt=cAd#)V`j>etT0CadU?(W?v zGojY~HK(6SgHLp=Isb44O~dW&&O58W+O+G*C&`(dTW_+oA1vZrfGbtr3$NbWBTa>y z{yqw#V-oaigHqQ@+I6{vzXIi0pM=g>&8&atOV5?ss$WV=vN>|_!DwQkx4TuT`>V(Y z7k)m=d(@nRTcS>S0GT6TVY6fv+4{KgeYky~)}>)jLrpymJmng&#h!cO=Iz+Mw~Yr2 zzn3QFTc5NTJpD4nIe72Ah?ZS47JWT=w``R9rdS~4;p4|`nZW<@ouej_#6_n#s(%J9 z9%O8a!DeQQ;iTi%zJ(G=(4`lo&2-_`PlJW@)QUo8&LQFYyBo4~&BHcL>Xq!mt^m%= zsAP6kAm9^UkPWw}AZY$4e?TuTjN`g_@v>4Rr-Y^La|pWq8e;v?_8PLDbp$z3NEoX8 zG_ku*=X*_=m8NPFsS<&1y7S}j9bH)v>QmB+f1tPF+NL|#_FcMSd+BGRLs4px&k?AE z;GIk@n5^CN#)vkOSsbfSmXv1STX{%STH>EVqUasIWHwXEmR zDppz z-fkf_aaT1Jg@nIVos5~;5RLbB+`<&_Y5j$8`dJfQ|J`?gnuUx&NtXEA*f-Xb;nn!p7%$d5n!7JzCmVClf zysKr+L+QOkYVRCKo*_9WUOwD4RJb$TLxfX5y0(TG==s;b!Pnkjohz{5f5^8DFFtwl z&Sl=t7riH>;Tc8=_b#HOGJN%-N}n|4@{! zeeK@T`LZr}UyPPsfKHL(-VT4b^1b=TwkKhyuF@M?ETrY2twUKKjp}Z(5)x;8;ZaW* zeM@3o5rL_b?YG7UR_HA}Qy^zb})^nH2$;4ZhpXFxsN{NFwMAn0UQ{1&$h{?2M4;Q~>)4CI6`Xp1~&%cM}*wGZ3`r<8n zB0Pjw9gp_>`C&&vt{J`NSwsIRQ&TfM&h-?&A2<#w3%l-$wa9(=Dn=J&c#cP$StP>Z zwmf5m`-()4!;7ukAWi!yu8lc|y)v58`z98xF{yc-=FDu*hEgo2d$yN{K-HX^Q>b+n z^NSsfThukbHR|r*6(h=gLJC&vQ~^-JS4oL)S$la|vwgZdt*3qD z(gQpke>poKOL$WHDX%5K82C6xD@ksp_lAG&^B_SW92;y zAr#OYCH`Q;ZtNuV8hQYf0=@2vhiP2OEl2&!WE&*>`5DsH`yG3xWg5bWs%a&@347xq zPGhmqpqb~k|LZs*JL4lGcH2|IruQ3-Hk8r7D8Hp{f-a0wM=F4ttaumDPs@Vz9e0B? zwg%OuOuR#{F>cq#$~I8dBtiWZ3l8#!`YthBw4>ei?QqS^^N*$+jL+nF43&BM90-r_ zyX4d(`{cI@b`gZb9-K~g2WrD)F!i-&M@A?n&9=O79}U_h`v4D5joZV_{2Llaxal1R zx(0exv1f$d0gZjG!lag6X8%uz{rQ8L$|fcF5IL(TusQcDGw2sG_`BnMrWTgIUmGK zRvi71rz`KFnwlQgL!jA4e|fbrtYFsLrXqw*c$>LLuyxLgpMZE zy^Bj;iVz_{%Uzo@QcqVqCwvG$`6I{ck)cA@ajGJ>II+jrL(N0QOAV*uledQg5O1ps zHW-^>V27yk7{fVy##>Z65RFZ2u?@<|XOj*i>Ow~A9Kp{Lj{X~STcXCT&}EZ$3RwU` zS4rH0woH-@YndTsO$Qtw+Sk5zQz`q#Bbo|}XQIl1M%?Vo0p4s9^>ud#YB;5n4dbL+ zMt!6?_6J})(cehWGcxe;D(_f1-JxTgAyMIDlVnECz)V0wxW)q2!t^VaZgRodMfs(K zU#sp+FV~dK65$+os_3jV*HQlmwpQa|B$t3zl>soj3aH6jARhe38zFT-PxeDK(uk=B z`&!^ngCCbuk|lPL#1`coyLYDd&TR9cC2GdAJ7rk%dulB{9UH_>_p|5+qwoL8=^fxf z8{_t%~2J<;V`OPp?ouXEp$8}s2rW%(kn($qD@GWaLyx+z|YJP@01M!8w81( z5aZXF9h>3R;Y~}bVchb5IhnU@;Ac6}Y_{BDv@~|pfZ1%tdFHeF=BA*QHZaN*48_x7 zcY3nS41r*j$XjSu|B`e}7z;=rJXR+)9bc`&xFa)_oDmi{?K1hT)SnJdwGBnp`lJu< znwMJRUNZ&7^Z{ZS4m`osIDqw>GNpyP&*&=exBw z+WYpcy4k%sNiIU~oOnDzbDytGS08bO>IT98=PBM#_7EaiSemgG;{ zd!)+HuXb(rSv5=fK(P1dNu1YgNa4^s*>n0i(9HRFQQ#}=K92ZC!WVkD%fk|fp(bA` zjmWQWI{M2hxAaF$%olx!Ci8->yeLu5(NGnp1$qAoH6bY-CHt?poch;~ z$;Oz%Tg5YbC01%G;<}-i^@Hj*bK}<@77#f-vNf(kLojCe6l!$<+@|&9xAZFN433YB zzb7Fg{mZCM3Jd;*~*+OkXA3#3F0I5w>Kk8o8bnQG0K)N19>hckpSC!UuJ8 zGED-?F$u=e6>q8V5fri=JJT(!;H^#)R)`vl$yWzmew+VYuEm;dvVrcRF4#@!!?KaEI$G|`5 zu>>|^+>$B;R(1=NWGZ|Vcwo}fBp6}ZD84@}$d)Zo5U%(2;kZ9g{dFuW3aw&lZ~d|} zDm>M_gsXqKqddxHNsa3w*~Z@3KC#x(#O<00JIs=;eJ^zFLaSY>ds9#Qynr88 z<5EY-+mY*omQLD@mlwK+>|;wuEc$l+5s6**rZR&!D(xhH!oQxKxhvKupf#JE#JeRb zFr!sK;CH8<6B0WcrHWp{(3dhZmMPIP_h4^edZ)n_R!Fsvt{r>Bw6#VIHsySOL~I~E z_k3lB#?~X%fGsD&!HWVsk1|R_j!f;-t}5@-~ENP{Y@@%*C~TdiG;nKh}dg zN>O#?Q1lL&J!!S{QH$!A z>BVg8Zhc%=ttiV>XxQ%PIAke}8STurPBJUAw=0?cHB3O+yMZ0*|K;-E%6JXm15#{s zy2w+SNAeXPme@!unvTHT?t@Se{uX%^i>yPkMM}0c^QJ?b+6~qSw?wB}maRskPEU(u z>jw;*aT?LL;%J`mf~*iFdXO;wOHHBTE{=zv$pGK&0%)H50AGs?xYV81;z(w!lwlI- z>Q|bM@bSt>PMcNClQL7$eY976&AI-Ue@9^l#zkRb_xVrlKM7P&{3!5{F zf*)CLgglJyjZ#jAKa@MiryWS_mE&iczpJ>3B~X#AkVLIV^iya?{(2lJ zb-zPpL!p4OwJUI@491DKu{>(BrK#=3MSCTWcIESj;9BMq41oUqow{q6lG_KyB@U$nnCUP z7QT=oP=M7q-GVbPwF|$Jewm))4LtsC5sjcmI*DprxTI^Cgs0qvme@7_{{AGz54kzt%OwdHI*<)SV+?VY>?d z;gPO_9%g~7d`og3b#CcuG=pq+EhefHRlG28av0Cq=b$}M}05Y^hU8@a*H&_SyrhTSp^ zR+Bm(gF1V5O2cz`HmM0$^fgFFL~;23F!FrKNau@5nwQ3#vq7w(tk=&A1?A`dF-p5L zUdo7EBBwk3DwVA{i;~!6iJTnit7Rs9Sm;G56)MWs!~&MZ+HRrz@1c<*;4bkeSU5=} zE$Ne%wG1JfADR3Z?(PPI3@MIAghzSX-waxu;F(^MoGL*)yc-{}y>7gEp78POmCDm; zUF(0PO0SW0kU!vb;56mRg+Oy$fuwSYgH9Y@+h600YBx}LGYDGJXC`CZX_0ZUrDwWJ zk^85ING?}tw3vtU{ccgO7-70+UniV?xM7>|j1UCrHPU-BZ6BbCpVOij1UwcTHAfIi zhk;pQo2_3xkFjCYIF)o#MB%A;iCw#57H=<9nLQt}N_Gt|(cSmwn%Y`;B{!ZOXIr zTm`1ZN3u~rMu>?EzLpWC)2`O9j|hnWw%mFUfBul^_iqD-dyLv*GE0j);B*j?69o~q4$ltFko6_xNyMYsF9 zZF2F|hKtKdJm{EVvEvtMTm#wg$~ zDVlxEx^}4H&Yt&rI$fzRMtTCvqKRh{vPToBCt z=wlG*;Cz}X;6QqktwQ*4qO6RHL_?SS(#-)!t&pVbPEv6_sNqaLtJqTljR z+v3@Jw~e32yB04)&+)@FnUV=OQir8?$$xm0yroq7Md}K~g?IhFeU^cNu=}2)jyNOv}vc?&A?k5#rGyGaT$-k2o3)w&?#DH)l2}ST#nOe(L=w4bQ+#>FnJ9?`>kTx>`0g)?hnHmo5PX=5SdDTQI|aDYtO!afwT6`fSdPWV-3~@a z_E1+kmPK(CnE8WFmIGcIGPS?@%ZTeT>{Z*9cS!r=7gHqa%A!!|-?DYGQ7r6&|1!~q zM>XlgK-E96Tyg|q@+u4v)Umo|nBIokME?A!ue~Tb7?ax2+4aQ3cf0ij21K$5wU#@5Md9rUC zTvi)@-trEl5-ElLgufR;&o28J4)E%PTbni>tYwXK-49gxG=tNxc`^r`y-%G_jd$3V zl^4A<`UFLeAwOJdhtp+Bs$emFKva03wr+_W5u>BkTF32>BYbNliG$K_<+0Pev+h_B zH7%Pw?@oEed@tjdj#g~&_CB!IG&zxn7T{2)4+qp$_2<{s)jh)ZJ-RT{+r6u!(qZqB z_x3T_3I()N7n}Z*D|2UZ-vJ5ixpqYvwU|Tw2kK~<%}dN2!`cV5WD2_+`-<-=E~m!M zeJpr7Im=L=OKGPpq3toO^yx$a&@m8K%AmE&PF+iL^Rj=$_QMh*{g~JY$ND1Lq3((b zcD`f;Y7KWpk>cR24nU^{fMHP-ja(`xMGnz9Pk_c6$*n@-iD0;~Hj!v`B!$E7*gk)| z=@bvUE@-F^7X`&V8=dsBGA}G^?q~=mXpDS&?do6TcLj-+t^FM+rP54nFat53=)@*M zuLHaABO6hpSiUl%=z?5=S#R0OEjyz9`I;$_JwyY9a7t*F67}kbRe*_de*P#y=Tt|w zMinV?hweLgAzvYI+`kzmvyKi(T)Ab~V*{bLuI0pOG_0j2BMfafR$)9kHp+Bc8_|G_C%VN=#)!V^rYW z+Wgb6EZJ+@OM}K&=aTS6Q>p~7YzxhxXJ6lc*ZMcQxQ_Yd1F$&^`F3?m<36xlAIi?m z4JU|9a;=v8N9Nq>-n{h)w4#P@s=YRRGv9OMu#Rf{FS!*j7aOi;m6*Pn@^(xq+4}0B z^45WBUvpqnZ}sfx~!qK>cq|4`EnF($?~U`eCG!-ctLLKkFw@1tT>yWr_5Jn%xdS z`E(8GFPIHHsW|8nSFY)(WeW|a@|{ySW4`vT&&PvU7?C(m(dXWdNVd}0_?D*SzZjRo z{+)^mC=LmM7bQAh0isXXLsB??1D^)g-q8mB*3%NV0pDw=xL2?2{%%*7DvWxcIo1;dgZ;$ONk~jW24f~Uy5ISc0-;sOK z?kNCe-AhdD>c4wC-QY6Nhx(yg=p`a@4n`31?>cX*Z;|pJ$9;hzQGN?slyj?yD)>_) zKv8a?iD`#N7X&@IokbKxF=eVwB#S{nkqB{g5r@f@TCRXXsPKPcE}{n&{bOF#62zB# zA35}$jk>&8;S;JC7#HrMshYGBM@}#^b0EwIkp@(l1Sy>0ii*nNhE}f6gb{biBy-ic zNnB^Kv<>BCC*mK?JN4&Og)2Hy9RN z;qGQ|NKv1vLa9=;5y!qs>uXZ77Xrb@7@80=^ zt9j_3MA3#7NSs#)d-4s4w6I1re=B~^5W#>jpoHRH=+VTvGSM+h${hb-3u&NNQ}kv! ziy^N!@BcGO<}4;|)$eOhJm*&nXA}CDlYiLbUkK}MUSwhu!`uD9$9EQ`<13>CCM$5fQ?&Nb7(de9u>BDEu z1+u~?C@;qFOJZUjaScJ)hbrSwFclo9!e!7+zatnZ_T7X599Qxb^h4U{J}m0yx!#$; zF{446vH2FCu(K+d&lTrno|_cb&*s%G)0g@^;8gfA6fN4Q0pc0}zKimMr6(8Cz&AqS zYw8V5yrqG#v{?;*3jV{tHHT8Zy%QpG5KwrV94lcNE#bR)M)jOaP4iQ>;?1gWL8B=i z7pnR>O9?jzx?dE}I@SSp84RsS%~n_<+B(ZnLIJWX$D=|r;Q;>Dw_q}u&QvBy3+yYn z3=+~g6rjA__20eYl46k_EYqOUy@C@=z2i2nn61+zNM4uUwfz;1x4tCku3|Zod}F+n zu(WYQA^s2m#;bh?yK`F-nil?Jy3y);P{HrtWiGJ7OGfeZEscE@qJ6urFGN(fJ(Jz5LC;@a{4J_S zbc3hGLQBC2k?a|8kM7NB?uWD=2sQv12~QC&x*AN}>RYe>KwwgMdIZ}(e&k$51lpzH zZQuO2%(}{|$OWx2{JU!x@6=3#xq>T4Y=p&N%#4T-9O5Gd$KgOIqn#*?v;pv}o+N=3 zw}GV}jgO#A01>Ki);&^(YRyC(Q_t6Fa9!5(6K`B^t%S(j+McRwtw9dD>Nsu1IRzfp zpfDQcM^y1f$fIsChO1hssz^U3R=Rcat9Y9^HASQgUym?p-L|qa@<#Qn3r?ytZ(H9~ zf|1PGRi;;cRrXR-SI5ep-6u~0QNhU^#9OaiYn;EXT>w2&z>conEK35f`qM99yL zc%=|@;EEdTx>?o2$7L8C0n9?gu&IjEtiHvIy@sEr(lsn~OSaMH8Q%Q;^vz#3@_k;{ zF~fC1(S^y=6|4vMFICh^R-@j;N{RY3m4yYCQt%1pAhp#`&K^3Q#9}14gWNemr0h2B zu2Gxh#w8{o5yiKL>N%NZ&)tUIW`;5yT>M&Yv6OdxOIb28ZvRhAlQ>z5(hzOJ-w?i_ zPBIW9;!H{#z}&+{lawTsFGd;8I1OhS;S9-}j8lAG;|*#D4g}i>Z_l)zh&Zs&x6pGr z+IgG7Or1mju@H5;2aeP96x1YWZ*r|s@d$Z;(LOkbrvcxd&>0BcXO!a5a}+XZqprv4 z+Yj!3WVaGRloRN(ZMA6Je7ok`wW|JU*9yiAx_G53ZI$a*m3ScIi3$M$L5)>Z^H#hO z%;z5hPzHpYrKHR3J%kiqzF?MM4Er(3aha;^%{hK0!``ZnEj?RtI>Ubc&wG~!aoCHT z3mp7(t*ud8dSqRMg{5$nLDc$zhWDd65Fa7fD~u%i%B`P8s5i^wt>H*$l&M6r+$7L} zZMdVI6I`wUK{a) zO@%oDw?7yav>hHjTzc|yAayNqGM&slM;XrQ4D)K2i=x5k#`H5^ zzJP>jek|SEY}b#BY^jJwvU}>#U*ZS78Psp3KGeK!5pl-Np4SPE*&ouOA^~Fcf(HK5 zt280yRlt8@hpw1Ni5J($kKK_#r%$$1WoL*lfCNaV&EAld1C5-$}Na$~?|6WO3$WcX-&O z*FwfKh40r((LJJd)VQAmZ##D-d#TWRw9P(>pOvP-ZRa=tC8Psc$k{~7)Wcd+W9%ox9#)iu!kRyY21Ca*5G5OxOPT#Vf{Tm z6@&hBO#otg+7ZHD@aod6F1QDtT8|s}#vE)}(r_G`9tqOzs02X(-Es#Ss_R(oj%2H$ zm3_jf$^M2-QnY3SDB?0HobQWE@zJBFKXe7Y{(L+C-H7Wa;T`}Z4{S6j#)tN!ZWCc0 zbO$DJ6_6Hz*p97KnQ0S|Vzn@P61FaO8wF>_#${XS%MTgtug8ZEM26h# zd&A@60&RNB`hno>>7jC~g_RH3VGJ)+n6->et_S87>wu7{A&tnfKzP!DP7WE;+z#EV z(@tsLJ$rFt%pHFDOMfda?n+(nuROogJoG%6!aMcKXD?mi)YaE%5Awli<4GXFyH?-? zGojYW&X!ygCLPpXE;&>~Qk^o`qmWVxsuD?LN$WP0PUDY-Plhi7B#)By(8zC|h{bl~ zuEZ|o9{*(npy$F8eQC`WTpI>1 z-w7?@1oyZaXWJHh@nISFm+6&LCM(HqT=$Zfo%+0(n%ru@f+yGdKQ{@sfO6P$jtsYp z8B1oOQV`WbMl4o@gcleX=w5yZv~i9GU7;~Ql`o}W+f=jSf=(1!MFc4#554kE8#8Ph zdo_9qYr=OBwE_GWr;DkfPeatyeL#rg{l5uN$Q4bM_s~|C!pAJ~#!q*8Yv=+kO=E6z z{tLL_XcUy6K)GElys0MrXDiXK`rZ2HnF7?;HCP*A4e^F;Ae#{j(n*Rep^v;Cd4Ycv zM{TKJNvW2L)!YK*J!R!yUpdMhunu_LrS~h+_(i_+EuZWDMn`Nn@-N0YQTu{~=u6cV znV(xivu5(1{b4A7=ycDQl3>?Sk&Z2xN^OCH0&lG_+Q`DA4O1C1-#$r-AsnR7BhC&s zh97vrBB{fx5qqu|vaPG3I8qID%bev6kjo8;c-pH1zhJH`Ali@v-`5fp^rwKz*w0lNVrwJ-b2%^Zgmb%S|Q1l=h zYc0U^t*6u3)&GXFz3zU}5hr|0Jd!@XhwpC`NpI?mity_>cJ0}x=bnCKjTOT@)L_v3L?AjT(0=;f~&tg+gFqjqgs9_ zB`j#p;en1jl;T_f8BBpjwnU)tf!!MJN~)|W0t#-t@Bug)GGQqN{N|1@`pM=Ab*M^w z0Fl_d7n!^{bf7+JjZ`r*SygZl3gKJ;3G6+11-zOH8$nMT`<=pyn-AwMGU@XPKHQ=! zRT=EXmT@cRLH#9ie6s@gCu7)y9^@VDT6Xrgp8v}E?2yLVnlqf;wTT*|>oEjj0u_rM zT}K=>U?T(y00yuR^k&Ra9HU8UQ=+VHIu_Q7n^&K;Z!}}yboj7ca2YZKF#p*r^*{b#x{CmKfd?j~qN4#3 z7^ccIj&p=dWIN7pU}7X^EiIs)`+C(Fb-{XQFSIG7S+cRZs;Tjbx9YvBB4H+HQE9#a zt9t3@ncenxjsk)>wy+#E`5g6@IR6ton*~flvpy&gV@6!r6wV-^DVyUxfDqBm8g6y1 zDQM{Bd+i4@_)6ehe{oNq6W)8V zS9f>l<(x{F-Ql|{Ps3zM%~r3*LKpvZ@2(Coxb|w(QLV;-t2PnGc@uj49S!di4?1PknyDyhp~A%} z{(}Mt81q#iPLHVZntuwBX;ca7HL5u72+J|CSzaJRr}{3A9+p#>-i&*MyELi!l%*$a z)n}MwhB#m2C*?3Oe{;|%>8~C;!#VC;^S5O+&t$R z+PV9?`gHlp#!W89Tq@J~&HWRzJ3dcwvcTQh<8kO!w@}TE_CKGTt$yn-m&V-f;AABi zz;v@{T{+w;+MvMS>SH`okeT5N9kH&Y?~lzXcb>thB7KWoe8ar=x7rT*y;&~aK4{4O z(mC%4jk&JH9tHzazd7;l0|NH2!f|9Hf0JR>7P_)CKrgqkzG=Dtv`8g=Xc5Kx z1p<}q)=3H|+Im8y`RyZsLgL@7wKhvm9CwMghg)88J9|96ou!*%IoCljg~}h?jJx@i z+t=rew_vTWK~y<^htnrN5qe#G>U?d0d4@E*M$?I7qmcbh`loiwlG%wMqzX4f8fkG( zKTaJHTN0DvbWP`4W&E|-YuDWE?3uB-n>9)PgmzWb{fdIODxQ$3bttR zv?19S2g+Ewn1qR)gGDLV$o7y_2U&G4?Af>19H+toBa2(J3r>#-_NmrSx88Xz>8CB& zQpdANYW1R}`J&XWbA5NDH10qE#Fi#XTG=_tP^xu~wd0jA_erL=<)6hOP(4KD@w0mS(KRimmEfjepJEiHvJMITA&|Io{bof@)NM`}5_L8Xmv$3RN0e@usa5@8vgwn7{zgqkpA0>QV@OF5Pj6c*{Ndk;olVQ33=r<&yJggj6H|w7Hgk z3_dZ*cfQ`cjM)6D*eK$nbXWXKn*do1&-l`RV#mi2qV=Tz#CF{!wr%9PjNt4)+ylvn z@~;hg<^?@|`U1x~-?shF{5$X7GyLnVzYpBgNFEE; zHl?A?{%xHsw@NNj(H8A;{40?W&C5CPJg<>VFE|E0B)0qNYm1JVhpc(B>H2N1tmP|G zN5kH0)7O0X`;AnC_We0a=zes0$5&mmv!9wgKbNl#-?RJ^_YNC}v(Zbv(DHYWbL-#B z0gBL}uF7Y-k+QO;&uku4C=PD4yI}A8`LT&Z_}3P_c@n_9GS#>Y!Ez7%!ik=esWJpN z1;$cxG8T)AE+mI=NL^a*DJgnO5f>Nq&FQuS2d?jm$($JZ<^5Y$8JnVV_ek;&^{@eS zk$dOiQ5&BSjV{Fv(yiuS+MbD3Jk)rv?spvRKUl%}6RJ-YNiDzN#R;?ssx(b+S_hGJ zJ(oHOMwF+(D5DXR@)vY%9&cS)SrIjbQW8CD^ERleyvSC0#PNRRyya-8vcu^$k&96% zIma=Vv5|wRv(h;}D)udC^@>BMr%Eg;yIrpR%d=<=Sq0wfA965SRM$0 z*6kA+{@?HNo%DBo(FroIspmH^&BCmbt{?I9`acZvkw^3vl)LW>zHYv3dA)@HrQyEC z8CGsU{%mHz-#YVqFR)4{cJb=YcRou?>DyV-;~%~xwe$YeZvme2ov$mBr^+Dy`u6|3 zI3Q#Y5%>SQkG{%(KuP>7Rcrb)H3;vD#%8ip(&HK{nyXJAxlpdRu-(Dpj_OH!ZIzD_&z_}yUGsH_K@x~_ za#1IG_b=qXtBjx@dJ}bsH<%N5+QHJv?6#JP>8@by#4liO6K}vu`i`wBo(g}WmpNph z$RDAkS0bZVZXMMQuXUx`4gMjw*dfF7lgZ1f{|0=I{sp}2;hJYUOuvQ~rN{}+mBpc; zU$SeoM6TAPtFi%PVjE&8-);^&$JHgaJm<;@xM0Yc)h^?tz z72s+cqd%bjw17J)1(*n-%m2sQ1g5tlWj*rtT?#tssjUOaOH=9>Z}7~f-uL`E#E5)&$0GD4gN{94IsgCXYE}XrIWb^Z(o}&u zxN^JWp}hCnsbf=8D#&Dre*Z|`n&(qUFYYecfM`Z!-gnKWN+<;u$Axd-loe z2IQybDS&vo8&B4!od33qgS?GxtyoZI}I?_%f~A5m~s(#9YAnDq5i z2eZE*loEG0_^S!n3GU;eQY%}QK!!)Bn0D@b_n%lQaMj%P2a_-beP{* zUFM7jzs<4M>;ij=4$2u*b(-XnL;T<=Bs=>O7}rDmy=D5JSaBi&6JAtYpv{Y>9}4Tv0Wdn}YKd z3vDt0g~zSH@<6@FR1pdqa?I>)*K4o&BJXx!`bMUihjkVyd(WM1r)Y@7>1J~m4`dZL zUa-qFDO7o8wW$kx$K&az?Yr(uexEcmc=k!J45x^-wAeXy7 zyO;mZp%Hrk$~}53nAM=7+?Sy#fmS_arh4FQ*xlRu1~6ffK9{Of)A6*#<@BEVil(~w z_sP~sr9*q5XN7;|*IbK!EQP#l`rNFMsz!(#{+~}ko>=AxUp^67`U_`J;A7GS%Ro3b zF`Un5|6ZabJ+EwdpX#i~DfdcU)9kY&)n|+1j|HH=oPyI1+-!>E-l~HAtSc z{W9Mvrc?ZB*V6fQfqgYprUsqwT~Af%*sqUUCCuLc^;^Int&RIm{CC5Z|3sjE?R+{p zMW@_e?ocmDWLxs7J6>hWGMplV+*k(&Bt%G^RvvUoZFd&zj%tXK52T zEaLiUcOBQ=bgic`(RM=<_Uw^sMe+$Dep*ENLW32e0{J0c3tTBAcKt3d_dcK?@!N7x zg+}YN%xl#2ou#TTbYzQZAHMQKe0sZuL604|cwv{}VtDxkai~N8|JY<8u?HIw^{3;1 z`!V~ko4-rMy5Cnw%Ok|)9kdqLM#?81S3|V-*jbqWSXqqB7~PW_)m72|fA~9aVZ<6@ zkJ>-a!VpQieU!CZTYFdbpcMi4gPj`M`Mi7Yi16TlVi`Bsn&Z|Vr_BSOUBDV{yOIXh z|If1sp#O2uO`v412we34(+j!{(ZzSWg>k?0<~j}moj^E_L_9Q|g*W zHao`v|49YDeJ$~43_~Ql8<=Y`0GFMZMEqrk0Q*fK!moeTzMocRi*Mg@c+IR>ci@2L zl(OlM^YfqM-zfs^U->&|qC?gH$&L|4fyk3z7fV_;3p z|Gg#@^E@mi!d(GCMHWV+JMum+;MpM!6569bmaU9T{xOBTc=aLrOF-&VsZ=>-)TJ?m zN4j%jSEczV@xg>--Mc83vVYsqpLV44V8OLtCw6|)yj=Iir1ib*_(9TigxRYlDepqgit0Z%;VTMDeey3*Ad)~wKI7k>@X*8(SJxL3 zo^}VoQxna*JBW<|qW-J*dN4((yui~IJ?O=QoCTttP;xEUU-%{zC5<=CWyGeU!c02_ zZ5|wWWib&2!q6e>KUSz^`J?6@g~Zk2DT)zvz@kU1;=1*cnHB{fFn{Y_WrIy{L%8pw zn#YL+t*3NoT5Io?>|1NRJ^I7-({eBVIU7{#36249yy}FNBH_u0#61E+_5ZkpsjmW5 z^(BOx7o}v@m(}HKlk^E$>KdN(G=7)WS{vPm>zr%%{Ms&SEiO(~l-4@^CACs(-}d}% z4i4&@KP+jzK*V}08E|0oZD6)0%x183;MS7~&sTY!h)c8oD~1Z~$(9nfX#qLfumFs5 zVGhwSz(z55{;jR{<4p+?3+Y`Sf3rO$HID~AIDK=@0eE^1dZ&OEOaS+jBs~#Vw^|PN zH0?Q_J|m1^l<-uz^wU-i! zKmYF3%qVGm_{>(-dAy;;Ib`SOQk5Im&DOO1xVrS~c|(7&^yadNYoRxHYj>HPcRNPa zxTj(-?tx^RvJ1dN!Gr_1GSB#5t~7vTdkTfg&iZ!*cv)Tr;nM>m8?!~e^U{L!A&d7* zopwKFE#{3G;GA_4RyrNUF+*L1!>-LCs!*~X11?f%`eKY5*etecnkeLGXL zS-Z2zUU@miYqzSMc!)bxrT9@t%Kb&?*t#rMfcIJ@0bkq5;5y}CVQtVU#0-~CuEgshE%>IWwo%5&37Y#3Alyu*&ovKNkHl$hc3O*~h1@3AIxRv=37v4J3T@n%EC48e7G-tTQ@OqQ<6`<+jJ5A6Y zLV4$;c+p%)oiYZrKe)hl04aadtUe~V+b57&A8j*))GNmyC)13--5RlsT-SvKbwgXI zxe66`yX*knxsS8G-@m=?V`tl&UHx~M6Wh}-??|XGiu7U5zD|AYO~o!Af8{;+NZo8K z|Lm(rW?EnV6MHo$6o)fpE?j8C4Ntajq!_mUKt4X?c187J_uapf``EundPSWXt*kr2 zfymlaoxI)GJdW3*HpG?0^Ohg47lCt}rcKxYUU%U``07r+|B2N~3AWa;wdZM2C6HO) z$_bW>(cCC3u0h3wNoK`zmNhK!7L-$yqZldQx5t9ZT2{7<&7y7rJ^9mGE2p%CPM~(# zh65CAzWvl|C|D~bp?SR^xDwC^8{xs37nO`x;IrD8;61|w%F=lu-q|-Kqm!`ob5f{8~KADeX<#^f{TPgDZ#H@l z$nEhcVRkSj*4&dCDX?M!`mcslLwJuu!S1G1xh>Q6^u#3`R?lG~-0bA`4Uz4pyn8r2m9>XE<>ZV>>zKT>$t2lz^=dZ!c~4##95~> zQGfJ|jZ6Z-%?7(XaXYv7`r83-op)ajtjp9AcReV4gobs!1X~y`^u_)&Ko`jiyLn84 zZuF=(2&**KTv{?bU8_{jSuV`wjq413wwbwo`@ps#Gk=zK(Y`Gooj;&@^ykGvk}v55 z|0x%ZfXb+T4Dl^}eh}g_R|H$<93d1?3POx1u?H!wxq;TgXGnb_3oACm*kp*1ZZ5@! z`!Us;cIv8aIIxhMP+Sye*p+n37;4`?YAGX3tYN6#GM7zyCHl&!Y|ecHliB|elwRZd z=Z2_WK)lSRDW}tNUEhKcDn8`WPQm`H&s#xa7I@{cLy`duN`)8x^o1(ibb!$&@@SDihjFba}J%k}1L&;JRHt0afJtb_y z)v>9`iz0O(0A$yoSPO#B4T_Z3CMlL)QM8eaN4u(FHX#RVoLd0&LJp+ey;jLTFx__G zO)rSoz*k(hRivdEywj&q|FvjLbKj^`0#ckw6`KarRtIn`-7I)Igt%27VE=tqGfPV5 zjQi(Qr($a`TNsRp($lJi0Jr2VF@FvBG%AQ~e?w)dBv)S$S z^-AOc&B6mDxodM?rioh*1y4QbD(R9>&Xh5|P$E3hQ|g4f+jAb;Q&T!Kq5iGWtcc;e zx)NVg`s8+ypVWyyJx}W3a>{kybXik#R?!UC4NMvxS)Vy!CLODCNuZ8586ZgFu%e9! zCg=zKYT)X#G{FfdaS+0AMpe=R!T95Ro zJIyMsUcT$v=~GznwD*+Y59|aJ(8GxMW`wZGh#`rYwnV~RKraFzgLDJaX`<~j%{u^} zkP#`C=c1js@Unj!HvTTIr{$jJmLY=X*WdujR0_*)4^aWOoN(q`YZzG5Sgp__H^0dD zfvY~0@hwiUiIMJF!rWIt{N#)PG5KSVuyq!YgIJ{kaT3*u_lQ>g4FXGUJ#Gte)2xyz zIiXRzOh%`hDC?8$nOasT{a)WsFz1_4=f0!&(fb{(Zm0I~lO9{?VOJ9EWV_VfAa=bh zq@Z)dwH=Jy_FevcOSs{Wx`o^u7BZA;m#KN7&Bz6pY93>c z?LXh%C4FgbfNNAai+k27-7fI@NAO>5xgTr+${eC@DwgQU7=YyqFq(sjJ9z85t~ZwR=4PF5XhE*N)$n6<9nKwuKG-;;P&W&3e$L$B6Os2+0s85@a?G>Ox3UJqgN_BHEo5zQ7dsP{o1sQ&2ak>!;b(K@(?nS*LWC#^0-Lx_vQY>=Bg2*8E)ux-n;ih;^TBm6U*xwy$& z?gcJSPtIyE*!EHzLBE!vS4a+2!+Z)Vx!ng8ZdgAxRas_x2ZB6rg$Aa-&NbS*cfVux zqnES&zkU>4JY>IPU-xGJfFa`XO%sn@F6+RY$r$s;T=_3E=1;l}V)Tpclt-#7f)5@3 zXjydp@vTsQ)c5^%C`pX`C8_xQxE5B$=F}~eWfQKm6Yld}`#8ZF%KPo9gnrLCd(mNa z+z^^CF*89Oe{yeCWXU%A2X>J71TAv5q5QPDa_z(s-ByHpI*A%bl?QXP z2wM6TXIw)|{h4%It7H9d4pa*<=roGo2oO#keie(Yb}jo_^=g^F0m=|rIa^eh8HzF- zhkk^9-M=Ea-%s6GdxJ8|m+5&zaX<2P2QI`W+s?^laQdCK!-MBchY%OWWughLf$4vZ zDW!OUd9Ks)lWArdp0t;>$iiq%AuZ55}o3&AD-7u zu{mwnf06pzi+_^vb)=I6%C%B!@P5K4NHC#Fprh6`Z-r63HSh%}!=@K?lbl>nYAtyM z1!oITy*CV;#+`guH&j!j+sz+Oy!bKQ>psTV-MAPUlWFG4loJyK3e!=OMTdZkM=bRK z?V4C&0qQ1YlnAI8E6SXYLHQk@Sd>(1WnJn4yf!;NNKVsMMha%~s|ff?fd(o8b~Wa3}qP7eh6+2_~1A1XIONbjQh_*mV;tjn7_-fuKIXKUPZs&833 z$H3_lkavh28Apg~7#~wh5i2ld+=T zJ~9J&8opdI~-3)CQp%BIkAQM?vm8WBs7hme;M)Ygn)ff_u z1U$KPkp4E9ZkOQ($+XeQH@OuVt%qmLgA0Sk6&#wNt%uYTr13QVE%2zow)92+JEq<6 z9$YNbu@#}=24Yp}NwXn_uaMky~8$T zbvehnF1=A1M4%V#IUvlC#eNJ$VrlWX0n5Sf|9(E?kC58JXynz$l1V}2My z@zx1nRQJR-%MJ=$1DT5t2-^pPnygyu^Gdy5j@lVo?5LJG;mC!cJ^8g0eY)!>4R)mN zeC|WYB!v5{&PAXj2?y~Pg!xENt(4FaRsiJ|^Un63WX*pAy`>;fl;OrDS#Hxnv6Pak zBdnN=4&xgH|pH{UW|2}jzhp+7FGCMTlm+;OyePX|`pAVWOGz&Zt zT(?u0Bya`S5)*QagHKSKb47xDY_0FF|K;6en(NZZY06tJTC3 z@$J;$&~u}iUp18teqj@<-5m=Zi|Bp2x3*EOiL`6P>lg&Uyl_wIuOqafs+3xRx(x4TnWKgK#I(Xfscr!ydqE7PNW?p-oE01jYU;5T9dpluCiMZBU>~~ z+K6h6Xzvg!4`z?}NYmJ=ZTHKUEfN01ixdZ2h2uksJ$x(hjC6=s7e_&^-mEBm)od&< zgnzz*8=PU^Nf|9Gt`JCVs0kG6xmhtmetOzm#sk2;(PihP*J#Ajml+w)MY!~G+1$L7P==UVIIqH99umvU^w z7UZ^g^F}t>6g#(NUv{w$r}P2FBD!G96z?w=$P}#smjv5^PpFE39uu;hlt!YUD-?93iD7;%!VKQ5tXi2A1n|Xx{LxT3^cP1gps!zr&;C zuy1xzEb_`LUwWqAi(B7Ly_u~Vvo72);{8(S44x$#uPux+91mfU+DYG&L>rIr&k)9J z09fisi>3j$u2Vm?4}T(wDa`GlXciUCl}_sUeju!aPDd8Iqi>BwG*gXoJ09=X5A@o^ zInr$D2J07#MiAU{#P6LvWmpmdVyXFTD!ex&u2Bu}mt+A`#QSmIz&5NYz;wrN&(nh= zOMD3$FzOZTdZ|y~w300qE!b*U8WHXs?=zzDt3a>(asFI7?S=Umkg{5gLMVyAxS69! z2kf3RON-wxwWGMUi^ER{U#fsqrAP_>(^_xU%1{%8z|n7Jw}k}a{#<~=^L<>59#{Ly zG=_xLQr6`tCS;xI-B~jj>}MBoa&%3-FXTXX?_OMeFFcLk-6_x>K@pcC&{QpBg=IwC z@0oPnF@f)YVms6b0ip+}rJyEA@ZRDGJw^ZwKkeT>E>|rQC{~0xgs*UV+7k*VNipysN=aisp_O zz}u9Ty*_kdcbCtq=jRV^?9UafJF0^CtUvF=-$Us8HzXRn3fSG%c%#A^Fyo1h#7GeK z;uxLV5S1jL$h#YVBASVf#mjN$S~PbxaVzJVcMsg`5B?aOYd3eXk7CH&wd%zidJ$N7 z#n)u@U2St!-)-U>{cSkMqtMg?{FO<>Hdl+O7w2H4c>b;USy9#vpTxKi1>0$0=;csYHMgKbRRW*{D zl&)0_JD~!LZEH7Ak7bMLB;%nw1I=uszch(Dz-0Vrmu> zf|JNHuvL3h_!%RP$GLFd9GOGE_9;yd1BK!x@L>eU-_~d&@I`OBo^8WX+$V;7w}(i9+5tN8GpEhu4Pm;!^tCSLHY= zd`rREivC4`1%zqo+7tc4y0BFSs6FMsb{c7}^6@dQ^vk-K?rO~wAw+!`Af&ssfwv@# zz78Ci^E3u9?Tt82E^?$HgBFww&~)>Hdm&eJ^*5>~N(}a5^75JaW%%RVPSUxX^o!L4 z{Vi$ZK11I=9jvH*_wLF@qQdy@2PPAs<|27km`wF0ey`VuwO2Uc2NL~oAX}eAt+tx) z<(o`^XJ^^0Gfh~}9cp69gm+Rm86h5+~aR@w1yf;#*Vqpk{!W0~kmE@?3!}LlMYRc}nm;E~>Q-7@!YvSdB%G zrTS8mQ8N1l9>uUiJ5>`I%6?M5yqGef0<4AfW+6!Ecp8o=7@O_&aaSH}pI7~|ZB=gA zFuY)JXa9?=C?H7dsUHQhi8#&$zPXPJL$Jk0v~ir$8ft&W42OgPI!!dR1HN5hqZoY%VIK9E+XV`k10r- z{OPpu*%549#}iMw?X&veSEUg~)dmDFSRc?ta>IFvfLqy!+s^~4m;roS{B>b@P(QmT zK2N+JdSfYD4IH8(&VPz;z(OSu%;t=<_)YLrzO}%ycYpI&phiM(A+DdB(1)awk)h?*dgYPA zG9M=2rlCoT=HfY5Ucef^chYIzFe&uq{U+hytHVS?^4qNWOZ-qGZ3iF(V#JVZP|3~P zFrvO@C14tl+5=vJpjDv4m1CZ2t^oa`?*LQqpI9>9<24M_YE>5>EKwwVeoxc^p#fsc zal;<9*1{s*rjUBV`z-)59T#2j4gr=fCYMk2Bf-0DTtFM39OXwGsS<7c%fIJ}Yxt1u z*e;idlEK?E<>Ip)X_N;{I`NAVx=!~vqGTr#G{VyNT|9s@bX;V*2R(4#-+o5bTICYuyG zRDsAZLVXT;!t$v>Z-(!74>{ME$s^oi*Bf;jd@43-WAyxMU*+&7g*8NfAg0K%0QVBTXL$}b?*wW%2;YC6_U?7jD`d}k#Cyqdf`824Ar%jZD6ZyjWm^^NX?oqY!92 zCDnrrLA}e$$ZMRENFAR`g*hMyK>-LQJ?1|#(W4VrNO5ukyQSV9gF~}&g326=zrsMe zxMJtODaVK8SfOPru?GvoaRNTUFmJJ(Tyl8y7iq)HSDVekr4uSb*4p(z1n15%K|Jy@ zhVoaSbLPyS>-+CWB&3IlDSJ_r#ktQ@{}Tg_NJj2Q4igY3X*20yAcVar0CvPebjm6D zQsowl=2g_xf2D>7K{!^E>2+KS;FYflYzqvDrZdGjp+OJ{Fa0U z*3}hnqs*3_m%{fE1aJUVB@Ky(5YvuF{!yeB{dDldwmV|=k@Z9yb*Opw0~2Gi@=y134NIL zmIeYZ64MHl28w{Et&rnjnfhyRq_zn#l)wcvnS08x-~`C7OZ4;es;z`m@{ffV&4{*g zmxXQFdA-Frqo?GPz1oA3RDInh<6fViV*(Fh3=*tbA`;H$@4#<`rZ^y}mwY6A)4YYy zN6_Mm%1qkPajK3Sd-j!`U9GB(n!AT?8#WxdvJ)LMp_e)6^-XW7v~_FtI9Kn^jR~!* zrF?O|^K@8`U<;Z}oCk#mNh#P0Qe&;O>whO+1P-1tEXVuy4e!e?3-9d4%dpgJ)>|rx z`t7nRU1v&I(oYnu-wy>h*y^6;J2brX;gJAHw8bYv93RY=z@HuhL$!$Si<2QAP$?il z>EU3Y23AokNp4QnE194(M))`(G4KnDSa`uo!Mav8`&qREA83Tw;-+SM1W+QZ%sR>( zj>x!v)95(y1v>TNEVU*Mh;g$0fU>qJZiPnBg6aHSg41zmVWuF0Nitz!Vg!z|F{Puh z$p`v`;@hg4bd;jgoa$*3kvV5;-aW#au<9G>-dk|le$C=fprk}56ty6L{PSyYlwTlD z7OO6{Q^epoOqOT^$ipSRr3uu)@pX~wl@NSImj+Hi6OJG2h--w^Wk~VIh{f18f<71B z+F-D?HnYEGJb{GnJ>YP<8oJHvSp~<7q`0uma=WMvvu3yOmB4^+`IUbhZ^;F8^O^8U zk+-D*xz*AT4&YW@c%M3Y2_`d}6p=^DMsOYU*1$8e?+ei3FOzgb%P0j6ww4yhXS>>| zlZiyh#!Gw)B25oM*Imn}8e?X@RuWU8RvrN-7gvDHEK9u6)TZO014J zD;;5LW+=} zyqd|bNLIqMhWkaV`~fW3ySZ5aF~FSSyx`l~@V65_T5ii=7tu5>@j}obcB9tx#1eLX zog7!1v;+dHEm>Y4^5nU9o#8-NKO%e23(w+_>TKjlYziu7nN(wC=1Y>D+vg=10t7_F z8|dM1-aTO%>Lw8e00$Zhq?H^Jca*LFe-ZcQ;ZU~k|vSnh-gphSAMMx_U6A$>uOlMNhjXS-%D@tcqnu7B9#kl&v98W;c3AsT8wgShJmDx}##~((1Y?~8d zRbl-AsFX-2MPKeNUl7Lq0A+w;S-8)vOr}=y@~mbh3*7`)#}H22t2ET@1_+*rz=Y-5 zIfZkihXP@YuX< zhX9;K4SH!4Q5h4{Id6aX8>oe=Q)G?h5Z@NZztjz~#~1tl*1Zs5Sm05j+}4?CtHE`i~^fz5|~W8msn=uv#qooX2n*z4%A^uC=5O zm5s&m>Me8$tQ$RrxJK}aiYm#ipZswtA}H;#0$27K$F~oEgYaXJx%#{GHKq*(MZLv_ zLxIK6wx-ss$_L@4J~^sYwSA%X*1jggN8`p)e{%O_g*09!RVUf^>OQ@8>=>SPl7P;f z!D|EGFfveuD#q_20{??J|2vX(jy#gfdC4ZuiL=Rc(jBsQX)K(iAM4LQkwESk!Zuaws3;D~Q#b_dM+ zuU1<&b=E(4{%n$>gl{lJ2I7Z9nuxGEQQR<|WLqyO%m4l-Ot4N9yAyiE-^L>XNBL(j z00y8aQn6Bgx4BBWC)f%taH-lqa#YGceJUp@cfQQ^c|biOc)GIjK)WI^0aNhrh37)( z$YBbTGItHg&u?BSPMP0PO`h}0#q5zB)~AzO$uS4HS6Gj!X$ZKFA;{rD%kfpme1^v# zM81SRSZxW9*|6{5zHp*XKX%N0ja@D^EFVQKCOZ(a$XA@}%yDDrGF01GBx8^(tHUYe zWiKGa@C}E_H=enXQ_0(ELueF9DApb_W|5sXBp%ZUGP8VR7U^DSJ1U+p)w_ScvGWeQ z$iVkjS!Pv-rYo+_0sosWkBwdmLT6R_s;is!j-nDsmt24LH{J5#>3QusNh6o|cN1 znMcx|@PU;U6U^_xS9B1Xs#eHJ%G4J4Fp06+T$&J3nplAz27PsLq}xn=6(8lw=XAXE z6d*FQ29qq&hjOy&2!VLZEW+JocN6Q{KFt%xTI5v%jQ^d?x=<>CHDOa4$J{t`yfiG5 zej5SOkmz0w=OE;U5+;_uLTy-(MZF&O_7DQJKm#ZlFBV}NWAtTypxriU_%LZpBc{Rc zl-Yjw0iYU%q2Eflhm>5QCg65L zNvjzVgu9^Y+Mh517YvdP4pfd8*=ozToPxNQKYi{q7KKZCXPRVPN*i$_rCF3Fff$;} zAMDIIos9?(Y{&z1@)-~I-Rle6u?XI0#39gG*_K7-Tw#@zG9}}yQH}lz4n2C@oeG@P zg!+Yh7b4E{Ds!XWPWu;_-21Ir(W`5;k=g61uw{LAg~X8qm&4#2PX7tJOxVKJf%IwU zkywsFHKas`tByb)8G9ZQ%i5CB45t>Y{@SDRWo*f2^<7Z(8}8|xr87_}Q^henP%C+5 z>(5A+jzl|rnX`>I2`dOz2nSp_8)VXKC;RCIa_o4u$ZP0LTti*~*_V)nuMpyI2Q2qJ zm|TWQVyzXRhNj!cE#Jl-BTALG``t5|(>dBxESY}g!HE#L{s|A)(KYD|!DghNRU{)Y z8A&TfY~m4WkARK%DDO4W6M3gj4cyKTvSmtg_aG#oGFA;er+_WY_?+3IQo5zChS9!o zFGuAQtMerTl=^NzR9tFPFkNX9;y%4G7x(zJlYvQRRsvTR$$3En7jgj;Tx;dCVMEzC z1{Ki=bB-@?jd0LZyZ@!j)bN&%Y{x&K{$fb7p#z|)(Azw%2e3XY4qSeQBiyF0q9gaS zdDx#Tg9^Dpa>Ts@2SUDx4GlGH!lAJO=OQ<}+E_ZAr(MhVAF;r~{Rn6@GMIGQMAI=c z^vRP6{KB8u&l>IC`BnE5;*4hd>ITZ^RE|2&S9HjaI1H&*>^v5}Cd_#RhUtyH3;~;8 z=o+sOc@-6>ZuAlAf5F`bz4Y3!=eO`BySQ?<^SHKMb#SgRRF=yPM8$gOS0|sTu7na8 z&kqbi4||*VJ9^)Nu6tMd-~HZyIcLtlQ67iyzq1TicIEd_%h7YW06b2i=>sd&i*tnc z9C?X2WJi-s>$~@Xonv3j9{u-JiR6Jt`YF{)#)o9ua3%p(Gi8nD}86uGdyfr z8E8T@Vw@5O0TszPVYVM5vlXc}jvF9LbN%S>VGYhl$S-ii0V~LhuTb&7ASr}vrpbzO)dY5zt z^~z^BR>fb~js4DX=HN{Dt&GJZ1zAsd|W=*gdS3v7c?JbqYQM;dr?e zgkm4}N~W|fPUpiPb-n5$nw42f*KP}xPzSjO;1@x+8hk1r9Qhgo@xJgOkRN56WLz2t zZb<$e#3FK9Sorv`;)qq3ZUmfr4Dw@Q5L-cjrh#M9(+*Eq#w+-wLy_k`_Zm_5w7Q@E z=GVQg-B6yF1(p2?+qIv>=MngsHt2Zr$G}Fx+du_9fS63G5Tw$K*v88NP3nIb($K#Z zSRW?O^{(`FV{I5{If#gYN*UrBjUcdbFaJ{=JAg<7jRJAk?DH{Sg5ja(uPNb^Ww2kCC7f&nwV$MIJr6w$xeG51~21^^LLnAHY`#*!Kmozf% z^|){y+bd~5SLP*%L2okl7i}Pc`1`!2R_;t@g#PdOLGz5qfcrx|{=V+{!os*)josb= z&B%>kJ|Z<$2XSomNEjkJh#xXKxCCb#wxTPve*1w5`OYH&Mi|(=8_YmdvvhcnwgCE- z70?nIk=roo96S{H7CrUBF9I2h5SwxRyzHS_)g8DTx#7Nlqft30E^2djDZrK zx8x6vBUJ#W^wEoPE3Nkec>6*a-zc{xynMimrK=kk(bASX^Ndoh-e6Yr6`f}?IHJ2e zrh$7H^5SnZW@mC<0V#X**BSE$Iu7yIzUqk^#S0)bym8tf#TPD&(Fe!)F*^sgNsFHk zLf3UhT?4<#yLx}D5B^PQOnHaY3{Df{KmV|`b-jmiAyHI%mRPyUl}>0zSG2Vuhp3Fn zCPI=7RtgGdd(n{%`oM-@IhH0E%v6&SDoRtS5{T{7IU;P6IRAI$vwDZ-_3T>l!#V1N z2KAkl{iQ~6y)S#0{m<{ovOmQC2Epmmy??Bb@QZ^Xiyt|rpr;^saiA@1AQjTi>*p6T z_2ZoI6$-#{z(C)_dlD0}R?}9r2fn z*S5m1w~J<6i$5mo9g|uH1~arLKM{!d`d{+_=`-OilEW0v!XOePu9!5D@2bl~;Xvt; z90vHZP%I~&?M@|@x2sTU&(zxaxkt`9DLkCcAp7bBdyoThvV00v z>MtkS=2hMc#C~t$W~@71atPdumIW6f2$#I~cmcm&VLz3X zCF|MhN)1TC`7SmD47{B6aSY(bVUwBY0M z+qr>$%x9p#vo0InEbiNedgj=z%XPY4R7@n4kD#|sJFTZB7kNmCk#ub zr6WbaXz{|3B!f%!B-_Smxsk$`I z63&nm8ugR%&2(_DD|-E8<@Ni7-zJ7fFYnpKt3diA)6n1)FA$jr+7yZ?06Ua3rw25sC8N2e$VnAW?w+4X!56)@!aj` zk9ctIrS#sM}KI35Q;3yt)oqF2bsoPabxM^Kt zt3#;2)y-gmE#D4|rjCgS$93B5B*;owkdJuiZnC&0almGbVv+PV1v_-+oGQ$)Pra=P zKbwGm&>Ce}#n(!!g_%wk2eHaRFKB3Lt9(nFxF+E7WC#4orr@Bg+1f)?^7%H_@zKZt zB}8oYrPYQuBl%m)XOF^U|1W$lVRHG_PE^k9C}9mtny*b+=3}qdE(z_Z*L);+U*O8Q ztJx`D+1ar<39%k=jC9iBI#cmjpN0kgGk-!M#b%VYZRs~naCFy$?8!JGFQpsHorWE- z15$ELs-_+`mrnOCrsm0RH>ek4=E?~w@~r?z z34Coo5D-!NWovNro6erClc{gFs$KZ37wW%j#?-4C1WulgkB?fe%FCyp+PG|8^Yfwn zt$NzEG-1I_b&>ZLFP;vMYjkMzWM(i9Jel(JVO)z}AFkc&^omv(>AG*usX9H~E@SjV z4T?h+#5#Vd)n-U&e8;567O`9HnrnBb&@Tp@NT5(9PM>4DRHCxpE`HycdHuYash#$@ zf`o!&*)#h_+okP>T5t08ZjfpDhccvxF}D!{Tp0rWIXU`wttnP5pUO*Ueh;PfwrMa* zxx1CU2&Xea7)6SE){!x1*r@la{qp5XHM77c8Xj;THkB)@PdiGA342z$89ffIy0SeI z>1c_9XyXNC?lIPF7NB4FFn;J7CoT)KN(x!SgJ(#+T(4qhsALHUaaACE#$Y;YRz*_( zOz$MWicE)hA*VLy;%Oyqz-}P8!5R+-CU7td4|)cg9gB=!}N)8f4u25nm}xk@NdVD%`$w zPgx=K%I|^hdWyJLKyE7gPtdMhd9bZciT#?&dS@v^ho|7Qq1%kWm|=7aY8$5aOm8TD zD^>+GYicJa4vZ^yBUGCT+VUl(r(9DkClo(+pM6UpZuZ*NkT)m%aZE?-c(2j zSdC0sd?WG&zDx8N*ks*-ZdQEfRj)KL-I>nFw)CMqtqxt>XY?v>-^rM44V2X5eUGO1 zpEP{+=46t8Z+X_Es8c4r`i(aZ8Hzt?n_9_sYP)O|lbhUzA!q$kOmukpq`xCCzU4y8 zL{HHZ8vALgQ_^?V)8bRZX+EY7Y3Ap(51%W8x1f^ow7l>fZFbmT8kLT2e8W9P-n>GN zTer$6c+>I@vwx%oy?w<^g-XE7t(0zU%k_B=#Wv#=j7EgICO>4Yca&S`BzNyAEY|BQ zQ!Q2EkArF&{h>qY>|RbND=>BWX$4V)d$hWYmC#ZgNKXmIdUjh%`>-aPbM!0B5wTc* zOFd@kRv&fsvi{ob_TPuY#xwWi{GlFbFexxQ?M!ouh z*|X7{%Cxs_UiEpY-#X^`2jsTrIRhnzyvyw7USlzsP3tSfR6;`enn#q1b4|Z)*!7zD z@8c+=3*RK)Por55ylwWUXOFUx4XF5AWKnwHrXLtBdln*hOD0>8-kM1xZuLcrh0a++ zCBK@!La{~Dc=6h!3@eRO732@B&xLiL|4I};qVflI2*4HAg?X^@K&~8!HnTxF^uGwC z!%I3RJU;hWoVs@IHY1r7ZTuC7n?aBMs@m$fmt7!oIygPS%Cs=JbD!K!k*w=fd;M)8 zqwR*BhUnZ@ujG!9+r34}-{DDXajJh9$lio*>{j)VnOQp|A1|Y1Cw@2guxUkH>)>Ny zw76@&hDcKLQ zr3iW2b=BI@+IqO~R~T|rol5*bQxig}f8`lc*e|fq?>*YL`{EB#z!bfOCM ztYusQGAx8n_BNYPMJh~<;Ntx5gFYrjFecrn`s1)KRZ@4k z=tRJz+jHw#s$buJXTT#wvItY~=N&zJa?TEoJ@u z=UP*u$YGy`wxO$M0#uWVANlsTP^7)~t>iQJ&8x1cqx$Y(eDU_4)I2CaxSW=V*K_ssw7sgPpJblQo6*i^L=7 z=>j@pH$yHkH^-o-)v1k9R&^Yc_r#%|S*Da`A(?f)IIY3q+slO3bB({AoI2$5s9kE3 zm-w_R@5wdk1_pDExYz@^qTc~cyLcv?Kz7CB&V(?wp)-_QG#in~ zCdLM+xR3{pqmZ_C*J1{aht66d?R)(Fdj^K~e2RSb>DnVcpX-&im+QYH{5*2VHQp>k+XZ`YgZXJC3uDk=$c_rS^xcG5#ZJuJxm#gubQLpcuoD{lq{EJ*zZfd88 z=_pglyE{$TCd1*TMF`rj$xIW%>tVJ%$ucc$S4eCzFF$aVI0%HzZs8%|7kO zRP94!B@;inFPW1`5L(%Eo~TG$)NN0=xm*>p>&wnN9Z$w(`;Un^}r+InqNh4k^nC#rO-}@QEvYj;{_eCe*kcb6lVp1(~QJd(UP>_{KbeADok8;V)ZOJerc;2u9)rX3-X5qCqUnci zzqCF0w)+n&b6RAN-l*O4k8!kl(LJLp@XR-p1W)t}{wY8Jfp4sUQVJQ{bV)8dfzJck zn$2CRb@=Et7RlhHnAW+kf;ZCxFRlvzShB883~sz81X99rz}10~PFXcxmz-zH+wZ$MfN|JrV+bY^}Y9kibQ5cirrkWPtBv4fxD(WwRa zpXir}e;Ne>jcnpeuEBHW!c<_&H|uW-UR62R2=Ile)NH5UTu&PtySyh-5lX> ziV}C#Z3B+!EQ@|k;A6n3aJe80!~0(+Y;$`rs)jGJwwPHY6Q4HOj-3n*K3Jxa{ZJx= zntgUR<9o}*rzOP|uSYd9X|KzyA|suqO#U`8-T(Tu!unYoWEv5U-Ibwj8I^nYf%BSj z0W2nnM?|hoQ;g^N#@Cb|zrQYc$gjZ^AbompF4ME)pA9@yB_`600*?Jml}%Y`*tV5B z-7MIrz5FefkZ;qnd3PY>r!Mdbb;0_kDbw%C);n&pP*=wFW!mpR9~yWR}ohm0iQ(0X#*UwvHH;2Th##A22+;^&(03#SkG+{x?+vG7(4nWOuC`d*5i|A%B6`+VMz+*%x z2+m2AWQjJ~S}$n+-UFt8-&{h#RQ-v1PTwo`rZ@$dShl30;Eu^1K`{n{CFZKi zyesHtPU*VV6tetUQ^%5c$Y9Yp{HYfKptq*r5DK5&fb8^LFvu|Rwrc(x|kpC=Y zl9`mH=_T9A#<5*7@;7C9v=VFN*#}*0O2qvc`=4vqSGZ*jDV;wJ`M-WgnOaIzm3ATb z0Qiq2ZygxpiMjux4J6RUtM~?fH8F?k9b53^&Wc&U=u&Jil{KAXW2wb=ZJS;FjC;H; z^RIILcdfSRXVf5A$CUNi5IRAaB7-3{(oQCra~|K>I?3C=!`xF-)r%aG^C!#+ntG$` zqpPr*`Q)phr5k&VSztVR@0Eknm3vabTaymhsBPUDymdu(DYj3L`b*%`%7n81I$z^t z+nxB+$FDK9l+Kt53&Iv}Pv*qOe2rZyz}bmq%TPYiHliuPl6C*T1-?eSw)zMoztW}) zK!^KHdOR_aUN;cuC+mQEP&GV3@v*Zck7|T{$ea&ZMX)Y5{-zQWj%GMGE3$3EWO(Jr_ z#TE_jTU;d^>8(S-q+{$O=l@H^`2VM@9|`=hQO}Z^IxVU%Onl;*5;EO(DkwT7+^D7t zNV<}iCE;`wG;t|x@`dI9{8-NMKOW-^|L|k#GU#s9B`H~1bvxk3Lzm<>wPqdVuNnvQ zryp3K*IQhMhia>_2db&bx(fAKLswu_&#yqMXHMyKHNKfDS{eStWoJ1EZc^ML{N|FP zIyYvkWp~sc{k`rK3cTC~KznkL$JC!9AH%(4`4I)YWh=wkX-Xb0?(d81U!}T~Ob1yM zzi^R%mE};J+fWQ8i?l6~w>WJc%PY0#8slo-CxR`%Z5Z1wUpavdj zh^g^3k!myHm}^LFL_)YwH05M!$>oWsj%J_<#>Ab7MHI7l#{QobjrCd-g1Iz0)^aBY zv-jrV1ygRdWQoP~?10>TQk_c2P7)0FSshm=o(iKx{BIg2cx`%Qo{XNEoCGO>DhBR~ zZlp||olT*wDq2g3<-zK-W4q@CKTTw&hg_Xlbe>30S?R#V{`0e~%~IF#gHb3-VEGZs z!kG!?Lip_LpwjG2WX~EaDA7?!g2pVfy!FM(y48T<`oAcxJ3p65?Z7x#;M|M;6Xtve zI23b97iDq`AOIIshhIaebtPqg>IwaM%4B!kYb%pYFp9?JUP1P`7p5^e>`o_5N&Xf*hHK6*s4_TaDh*zJ?-8+Mm2OCiyVZ$>R>Op7C- zLIBrKURhiC`Cd^?VC-RAPTm3Y&{o5aV4bQA&HKS7d&g3qkN%9AP`LlS-JgwqqmE!8xdbN(*(2lncYBoD< z{-hO6(M+cZhu_3#2;DgbJJX!Mx^}Pr+HBLCdL`IR5i>K@FpZN|D97Xd$6f}**3Rgr zYnA|w=?)<=^9PdODBi4VC?%Z2!(=Xf;s!{EYGDZGZh6(40>S_ zuRS;A#g9kEi;4wmNUxq1^}25%xNOO!rgUvCopX2m%=!V1QN zZ8l%k6q6`06_RQ2IADu?cxGle2j{nu=h*d>B}}=0qH~Mz=G$Yv(Jn3BB4!rUOQK6A z8ryCjs5fwoUJbvxKcvHS%i70IW}0luofGuqn%ZMucBh43?b^(KJM%<{Iu@Hk`;Or( zn@&Y6)oWfMfaj`w88*UqGoklR;mE~aOX)emNK3ES^yrjqIOA*Qfqj3Zop9Fm{(hph z|Kg;XB}}9fRi=6$_=es1{r$+Po#C?t)07D*0ZkJeMoCdP`%)>Vq~K4OjVO78+usBg zw1JqEc%kdmxEYkr0*x;_mJLRSz4`mul(<@xx1%E+JL9#B%jdi@!1`PJ5rxbK6c1Rzf>Q9^Pe zJnw_7*5PU*Pv}2>eD?1@Is^EwnXbVa#~aSt$)v$nOyPwuM9Kf~aBz&x;A4u4^@DR;C z1jW)&_cDTZecjy_%|+7}UAkw{lYnAdR%#AQm7XZBr zVQjFDoAw%&HFP4oq?pJw+cNk`*m_)ryX}tryjx%D50bK)g5Qf3rx|=YenV<&=hiPq zvFH05D4aMdQ%8F3!d0_Hy~H+d#7KnX+GWLwFbbV=w#{fAM*jPp!~bV`&+k4K3{&b1 z>V5xJ&~#F*$fCJ=GTu@;?`ttM*@9C9-Q;CWoE&_|_YW=;#HS1WJVmN%tNc2yEOttZ zzk_uI?YMHkS?r;lwKEJP8UUprRRa#W9kzd4ophuG(uX({$yDQ-qZ;AEew-+%plI}K zka)>s)&>*av>-ndesHMTHe6L1m&g!pFMM73pnK18=JnLqDF;;IqrUz6#^_J#P&sA| z$9jgJnw#1Bbz)Mqi+Dx^SrLX@-|7y|`M+|(;sh?OI4Y0t`|>CZ{SPnjp2H{%wbpVC z@QQM_vxF1oYu(tQEp_rNg*e@t`dAbbCGDdw$Kn-LefJA`=SRBWiaqt?W|G&~9)$I2 zYuFS><^H#~T(h&`eZqqSzU)^a4>evX*-QM=Me2;}IfV?Q0v5ji>7l|`V@ExUrn_b) z9o+ZX%^?<@ivs{aKWF^c)wnK;eZ)8Z%_f!dStZZIy$YwDSiAeLte#&=3R}!BJ?>t;=6vU-K*--7`EN7vR;zTaRdNU6ikWcL>lgnlcxPc{^+LQY zQ3--nLG~0%PChR@-`gCK%RoxctlK7FEpkV`Miv1VxN=@b>Pw$nXT>_g3VnxDIF*ME zv9-mPE?%_VJ`s3r5~hs*pXKx~q78~r|0AMK%UPGN38H_t<9vlSWwm@fNjmF_`89a{ z{l^1ejSfD09(X){^(g6hevJ3)hyF)BZR4#w77xJBVPrttHvT>+0ItN<2GNNagcfv| z&aJ|pWo@*$YNdqkx%sw3#y4U!z~x@t^`ZQ}W#O(ZD)(iQV86-#{w=-!c8<1jOJhgM z@(%d-ZT>K%16yx^kUyhb@pC>`ukyL?;PxXz8`qzcG|wJRqrJZFa`lgcA3n5-TzMxT z7fnaqTY~B=mc$}59)uLAIO^5R;D@E{#k-!^8ijA_`I7rCV^Q;dxou3^hXcCXiD_Ha z#o0To>{FcAlQ$0IPpy<%KuA8hnYyx&i=UcvxMQ{O5ARR*%-{9No4>E*w+A&ZWV*)n zb-7G)4lTK(eHGGMd^|n@&9zK>D^eQ61+J>iK*`2< zV;q|m>SV#eBmh0s>W{aten>g@5yU4%^_6X2k6ZIEa|MuNZ7dMyiZ>*yW=!CQS&9 zXAJ$M@{ZF&J^@BNH)|-!lQHLXf*hmy(B<8ViksiPE4CTVJx14IaNukH_quHf-?#w! zw4H&*7~ZwwtY@4w$cl-+Co}Det5Il*gey;*hc|zGH8ULQTKBZ@D{J!Nvs3KyTbWts zSThIg_uPHUaXgBYKA}SH`f!YGa6<0EBl_dk0pSPVCN=H{<-E9hW;6M}H zgT#-2zsd_#19diAyClM3BAPkbFx0e1I1`-=f|WQG^!`ldLXx^LtMc6`vuy6@$M9qKRtKifvZe{SJ;qAQys!NovIjFBhr zK)o%#K77#0q`1Jj2~nYbKg_QFjIO!GtY5*=cTZ21-BUUFaBjb7wBR=zxmm}Nj)0$g zj-^IV&76BMBOn+{SZaZ}{C$=GZNrU|75D}fFv{y>`*!rI4?6T;k8} z`}RSDjO+J+>x+zo1`m&4+5AAD^OstE|B8s5X7brugOiE6SHIOi`FZq#i17Ve@4r~a z4%A(RfKJjlSMb98(6i`ew>Z<;{%Fsc6P8|rQx>YcSX3vT*$6Ut8Y&W0dC2|Gy#>Ag zbx9gfM&>EJ3eUBa6vE|>GX?uTMs*YU?|D&zzfv*^-Bk*(wQI`B{+EB!kj; z8>`4f#9H19QRex6^QgMtVX)h;b6&4%f$nS+)wd~*r%MYb1m28J#@Igjemdli>_O)I z!-)0m653_XVs( z3OkgNkhhf=MVKjdd@> z+jxgA^YBEdf4ih9#oDIr<=2rr)I(bg;%7|F^0%9&9f{vZK5*gUgF#K$altxv)jUjM zGt4K|$q~6ERWli#NI+wGTPas;BW#L%pCG4Kv7VqtGbhR^U$`qfB_+tg^mTP3XU*Zd~yCf=5gu(ZnlA2yhZH`~t9A~W+z|M-&59$jz zBAvbV^W)dnezBrHG0z=$Y_y8KES?UHAE~~r^z`+PnkrrAFTq=PW95oX=^c;Du;TpJ2!t!S)0NntZ_G(_dnHZyx4c( z_}6-sV2tTz)R_pXc;QmRWZV_ojua`TjAe`&Hz#*^#G0H(iID^L}Qy zsBC+&FQ-6@L}D2NyWt_Q8-C$>h$^8Y_;~6EIDzZLa-?Ur1|}*K8&N~gY$2E8amb57 zZ3P9G-dR5j;#Y{nerJyA2r6{k~#sJ>Z#vVAwuOb}`#i{K~`=jR?Jb(fn& z=yP>-Is!Vw9w-lUM0Lt{&NUz>pZb+RPOWH`o8-{5Cgt%leSlnE*v{R{(vK}~5=rU> z$&`OZUGDZat!v&|+?zJ)j

Opm{U4?QolVC@-qqZViv5;yOI!K+8EJxhI&P10CLz`?Kr{fA#^$}mRV0XaF zyJfQP8YlsxNe&q{+QXAWDWfy%R=@v*DFjyV44X}2=4}kehJC6Zzg`v9YsdRIAKU3S ztDWcesUBI0z6(;w7aG8W8L-h!_$`>46IIYNn!oUIc3@(y6zRaTCAz=gnZD3uq&$Sb zx+IQnigoD;EH7Fse*MW`=8T(Lluhk(JKNg6s3q0yH;3TOqETbaf-zmpS3$EcJ0_gg zX88kDwb~#M^agH(m`02wQ?dyJUNO(ku}HsjSt#1+WJY0_h1JO!WHMab7;_1qlC>o_ zGNi<#;`e%MI(ySRU(`VEx9k4eEcJY?PsApU18H4y*f-+zr~K(^e(Y`emoH}5J)V_L zWyRITIO`ilUFoDc_6F|sc7MRA`tT{<`MFE9?S*4IChmBc<6BM{T!6(~;3s39c2>f+&qCIGHihoJDEY+dkXm>OrR4;U#=YuA~M0 z9ElCepgDd#AcEeKDZ_h{P*MP)3yLiQRj1hB%D$?8goMHSzh~)DcKm~G(xn=5Z|K+| zY-_`1a!AE{dGfbj&VA?;6B$RX&}yP4aIzLsR_q0>p=+<9odKZ)d3*X?IGPQTkp-c9 znD(|(hEh37&Nhgl=jjT41|>L}OWx*0PW|V;<+bf6epd9+VEl~VpkFy&nrqB@W(}+u zg5t0*Ub;Lryj7Xf95@_#w7L#TWTQE;HSB?+NUxwGtoyU`SyTopc4ZEE)ZD6$z<>*Y zvKuQxEU{_u7RUS$NpG%yWua|5B*UrX-L17NfZCffh{|=!GdFp4>r?<5K|?2viY%0r z7b81dC8fMO@}?sK%HG&sd+BjRZ!n3gAO6yJSTFDS96xz~L2=8Qk%HfO8$q}c z?~;K0-cTPc)ujH!murmY&Fdo4Sexe)J! zEDuc62hV0pEBGDB&IDvbvXXa>Ipoho-OVv)o5b+Ph7H6(8b%jlF#K`_P^vUNB+O zE~B(JFCI3-U|%N~@@KZ`Ryhp{pp z*%MM@px^WOwywY{HNEgxW4rB|5x@f}?Z=`waJV+A zI$ziAd1Mn+x=!co#u4b-h~uX$WQ8A64q@)g*T`x=r+lsCbIFgPDZHdEUj<``3hiF_ ziIRX0wNj5)_U(QT4iPH~Oj5jLeH6T2S*vwnJCxoEFmX<_4U{}K7<$ZB=P;HS@K&OV z-|)h{<*$}*rP#CV^PNxMjZPiP;^j`)NwTWg@>aPL@i)a8TFx0E6 z=StJ+L}u%>ScsQ-GvaF07PKIy=p1W*9Q~7i@jMn;WC@pDt|4!B@#*pKF@OB{F(JXN z~46Rbuy-YVuAFcN8q!1c@Hm z>G;KTXMGr>b# z6jTFnaL5$h<){m-y|#T=m%MQ-z);tcg+Xbpu5!#I2p zp$Mg;`*gV`bQS+2=RUDo)&R025}sg0-~Wl8dPy+qC%6_GhO0=+1w^?HvRoP9KE=Nl z_@aC(V@nkB<138g0qkx-c{-$;7`<@2agdp#kNd5XI;XZgV zENZ9ZdUD|UN+lN`1lQ`zDJZZ?IQeK(vp`?AWb3O0zSUepkbeMjQ3%6BQbLf!#lLsd z_LaQ%FK<`rI2NX1@v4mU@Mm9yyz~tebJUkdixiBJxeEcDFbu`SSc2!hbI`jX>-k9 zj>@qUQv6p$&(aB7F|%w*PF^4K8euC0l9+xYWp?uN@qT*xOnh>!UJ>^a6h&WcU=QjJV2A&MZBuqOvc!tuwu2POxQc9tO5MW~^Fx!b=Kbna<(DVlOmt$TAr;r z!WP;;C^%G`;Pl>J1H||FA`8Iyr|@1OuM(16y_)os zF92i+bwhuoB`_aUi8_U6tpbt&TyiDqg8L!oF#VyWbAzRU*eL%O-oY~@d3mZRHY_Bl zUJbo1Ao8c@0$r9wvYQ+AXAJ%(Fv^t zbsrBIC_b4!E#CtuR86>DEXh>e3V#&i6nQAfBw?j=8`kdmL%e#&C6gcMNhUr?zgFqS zdsm-~!3>U{>?QbA9u1`q$uKB)ES1=3dSKErUX^PC@ZV#GE#uqRxagbvLy1xtyfewJ zNM*xki<;u=obxTO*)3t7A*!6rn++ji?+fhE6gXF9D3GmBBQ-80Q9lS10&2qmmQNgg zk$W97lO)vc27b88GP<6Y`#@$BUWU6pW3qW%!$kQw`*t^C=QQcM)qe5QU@;5d3rjsT z?!Jf97|u`B%RM-HRC(pLoPwF+^&NusmTAY;$Bx2q0l+wM06n$UWq?BT;dk_4Pol(1 zn<;5zsTDW<1oFqWM$IQj;VJw*m<*1ZLeodTMP1J7S;*~lzrNmlg29Kxfl5aK#2i!*|6#(V0*i7QcDaiZBy zoFK^4XLCG}l}i_Hd>UAS)nQV$K$owvZCi;$3(aIHZd8#jaeJ*ay}V*cA2J=}MDs_$ zSX*!nM6n8ge}5btqtlAs!gYT$a=MZ<9CiOAyIdNIbi#~N=LCK`o?{=%+x_J6T*>JI z6-^vQ5`C24S0_SZArk|xeeV4oMi5o8)4^|>F?8wh%um&5JiNJTpt6&+Wqjde^zNrp z&SQa#lT}qwi1xG3+F@&hG~4D>Up*89|9geq+c1ny!0BQvTJ4L0_V}acdeTBYTFO}T z`2ma$3YyKEmCoa5VNWp3mUY}Unj=z_!$>jMv-y}z8}_$xyFx#8)xNp9N08yh6|5ic z9v2@D>Z(0RRV=x*m%%x^A+yq1<-0_QFvT$OTLVnz@=x8DB0uXi0`0c?W7scicYj_> zM!{QOC)YP@u><*8RAO~bO<2CW_qb9|tx16g)*ABhK@_w0{R%^W(z^kwcuKHIu2`R zk{a6n!{1VxF#J{tvPcFsZ3@wSHRH%0N155NlFYT#d=B=j)UmPb;D$ zrQO`@EYErjzvHZCnB2G9ol)`1eY$%5x$b~+ThkZrBj;i+ztO=+y3sI)Jous@hKiEpv#k9bQex# z%JtWWae1&|yqJ9tTAM4(=`)}CTePg>)3{c;uKk=uR&v`J&>A4H0N*f3Rg|&)i_0by z1sy5!Jq(Xug_oz5vNhTU!gW1+9RRaxH?%W<*f;$6;GqGh2gBZ=6!-84y=4%}Zn>MK zs6Rg*SV;D#-nC~?C8x#_EVcZnrM?KEZe!~IL)^FjGx`7j>mW(29CKWSR1WLlP!3y% zS4q-3I>suM!(tUO%vR)lSfzMJOoZf=99F_G<5gbHhte*5C2F#MR-<= zcYcJfmM{Bf)t@3DcD3FFU!{Bo!;BFtbr{R{c6Jf@{i(}n)bY)#3u-*C#uUK-lw40|Nekg}|rnrJPc5dYu&2h*`h<>M)vB*=V!#`-X-mIqvN9KN)yRUI&{45x{7d9-+Q6ba+YC#Zjx zI8^rm@$4bl;E<)VjX*gqui&?T!;U6CL%YkNxun=Qw;YFPR2CV!13byAgR(&a+_~qz ztOzn`1~fiG1x|31leJ?eaxl=@-nEq0Lo&UYJ%KvM=*%k4e%=$!B%oamIh~?0PP-)x zC?TDK%%oi;It{wB) zQ2Z4J7KW@$o!$o)5=8+Xwm6CAWRrtKqv>^J?kP@8^GxIJrnzD>Aa)#i?-vz1LyD4?i~DeaBAe<0h%6g z56t0XaBo;t38JQV>iP53yB}N75fDX6NutbfkN+#z&!I6EB#xBBqJG2HX2VX&pTikH zF|{`-w4*cG^ITBiibQWENn04zx4Ce?5et+P5+Q_f9;vN3 zy>hB%$WoV~=Yw-BZG9D}X}vSpyiWcZA#}w_D2D;~T@aE}B7O|y%2!J8TmzJa1Os`U zVGL9?u36CzptD0rMsV26OQYyI-{_S?j>V&nHXWdzX$a0$ZZ6_SD|n_0+QwDb=3%`X ziGGgr<|S9Ny}(ksf{{<3YT7($)CVGCEO78R>X zd}_6~j93DEq{$kxf6(ij*r+i1p@N2{{$?9u7mu50A5m~=>`TD8OJ1M-gZq2s)9Y@V zRgV@G$q}2D+K~v5Go*0O{(R7m(urO@CMCe+J{s({ZC7~I`(#_F{#og>?e!y;Kz$8! z+que%IatIWPS8JDn-7;eT345hV&yy1$^ydgu)?L_$65j6JW-BQ0<8=~>$B`{nmWZF z8OsH=O<)v4X~w`9VkDw`)-Znf!BFUM@ zRVQB6tjaelOoNB!UgG)c8DdQ**0aX9`xbSQi9pIOPS zl>@Ra*;Wx!m;q^l-&)0@rekW3H@%Q}3^s;UNKQ!e(0VY~LaDKfL8m9N^+UCwn$^P8 zitG617-&8u+-$?3@P8g9%l^H^P#Y{EahR zFC4)u@wn|670DG~f;%YCda$vijiT9X0GsfE$v31)fgKy8dAa*pk$avwjyO1LjSQ0oC{7eS#F+3{u#t|Zp=q!f#e<(ybIew8Rb({{c%c? zvlJ*+tY61QNsK3YSAT&k$VdR6=hNf8n$*s~xuUA}OioDuUgvb$EB}U*C;Gf{oUgx)5qIDx8EOCNC%{0pb)U>o z_LZ?3t?e;Q*75R&ocfN%>4^!eL5rhlt@ywXZG8fnD5z&A{$*zYf8B$LeH52#jvY=nr3B6@r8eePS? z{is)x9T1zkh|-?n^a5bRB&qS3fRLj0b0ktT$$_1!l5_nEp#=8gEx3hyViOi}oGeFO z9QihhSF_i>i{b1db&2DKLxo-wy{tcBEAiBm!z3la6VdiR-2qohT3-V!vHp?Lv^xoYU{vf`T_uf*fAQz*kcmH3xX@}BnNt2JRrfNR= zy!(~*M|q%gT9}DjoubqnE4$*mkE?1zTZ}VAVFxHX=l8+!_h{ zz;IPm(#q8UUtBLa%nv$#u4e#8tekK4ZC^U4>fBXs7nh1=&44Wp;61g?bu0RmR%_q| z!{A`rmiD<587;VVbwT@EZC|QJxapwM(c1$faZHTDO#J}ziMKz1sN!=gM$2N}Vz20E zTt4{_@$|pMf+L|^DpwtNZ*+r78PS19$r1e~LODy!-V~a~g59duL}n*LZF^nApu`Jw z%@gAl$`XaPdZco0M{cFW@y%Pd6_~Ue`Hvg)&02Dm1Aotaz^E~9a1(u0U|a#QlUEXJ ze=+|spQ{3+1s!C4wv{r%2ejgUgp0~HXBvhHBwRkxw>>lK&RDLaM}sKYe_5llFyywM zZ@BVvgh7RMA?(QK#^By!m{kfy42xS+Stwc~4u@-A5WRT4EL7~>JbkD)iM$g&F+<)7 zu@fW#*X)l9x|+^2LASU+BrNDk6yH3my*e;^HsKYqAlkPbU-)%e=hU)sWN!-!wm=De zAsc>HTh)5mm&j{*+h9{^QwfWYP1eL9tSTIFv}2EzD%8#l2}C>MUVnTseapSLP(!+4 zu&pM`XDD>VtI5Mh(LAr?vQo1laQokB6=c&UQ-iOU`iFDw7K+rI0IqIDS)Y4cY$^?O zFller9kD?56yo{Hj>i-JieAlMIWuH$_tJ@n-)y`%mr#{o^G;1lfRM5cIMlB{fKNIt zGs8QFt z;DA#0AQGGh>~Hf}I(ZpEMFG_4SF{a8Dt1Jo@wz!nX$*F#{B^t}NFpZpW0XkP34$Ii z_Abt#Hd^Z<92ZR~pN^!qS0!T*vMm8_=uLGWhKog{$yVFBl*L>%mgmRnroryQ0IihD z&&^N6H5hUBn4+&m-wq+Us07k6UX>2fmx(?AxiX62s#YIs2snw&DZnLvHKeZ`7n#IK z980_cmsLI#`LubOR@hw}M41zA&Kh2Q+`4a%{YV{UKLZL>5N_jhffgA$McYI&2iWIG zmBOzw5tqdUXcwOS*x53Ru_0{K6rm5hoyI36%&9ROifj1ZTBi?vH>)*`MxIVSkY5*v zU%om8Om^}p(xX#{kOw3eJ0-^F1kKbEznQlnZoDNj+VrP00)_^G(G1dekoqSyK|(v< zOL;9yIW(afxrjOPxpGw5{+eEZ*kRQgnZuREHS<3s(`#1+ zU8s?ldmM$penXceO9rIxC=>aS*cRc{74a=84R{9-=fy31d@|QeuI@_hgI}B89x;iBWii-#rrQ_UmcL{bN8yAjkMePDF`EASikyBzO#< zWM2v=upJnVVQ0tTiMbe>iv2~Au2;PAyah@CjXb?g!54XSzF(WgVJ&-1S?}Gy^YN@$ z-oi!`H{sN14Ec)bA}(l|lJm^q>LNIMj^CSP1;%2y&7{KuFth&*kI(VwY2UyurVdyB zUSS~-B)eiFvjyyGH*dZex@ifMZbLE38#-Ho-@~jS9A7_jb~IqCLD0%+P};m8`HGY- z4Ke(2Nn9QB!R80c>4oKEL_S6v7%Hrzs52Euwuu~D(?VS8X%mN=`$GSBc{qs1tBNII zipN?@yna>(+WO=Ky}Cr~WzyEmdXTl4bP|G>>)0mSG7_d7)gEd6^p*F|)t!K-$rX=$ zxKiYAogG|Jz>KbfLtN>ZrmYcRteV$vfjiTjgsC?ixcW}^K&BUfQ>&^C($o)kg6&qW zO7=ouHM4PTbGko$wt1`ZOX4JZ@rAh-V1`lBi2)`m^`hJ~S=O~IYnLEiQxu<(61>&l zGU%$n@lB3Y7Z3@5oehEnUiH#f`QTtB)ZauEIQ!p{B#p25<@Q{CCg8uLAEf z)a>P!Q3@_k3oJ}_DTF6k-%9sSwbhu!MQ9tH<} zuZLYXK4E{moARhiqLCxWiY23EBec~L{6zPGOU6rf*gyxh_!pcUA2rX#zY>;M-6w_DqiMBt;%)kmJOIUA5A zhg>Z=ECnkQR0Z#HOm6qF7((wLT~D~cuG>-z4Av~z-VmXMkkGX;!_(!uLi~bPV(5n| zmDZAJ&Na`X$>d;rCjqe9X{NT<{}}&mM=M4HP{EG88@^!*Y`kU2e)MjMMS}BiMR2pC zY)4`VDzs*CXA5PcWL1c9<@@r{nSQuq(5+fYfy3QQ znJA}KC;Xb>abw3ff~hcWEwQ8{@{$3LMTy1K*u+%Gw&&U$6J3gYn%hRi@pr_b63Cl9 z@G=9@NC^+F)!k)(X~cFUp_J2b|AY%=MrvpE<-vy2!iH4}- z{VN>tT}g}t#mB{SxN*Wo4@*$k6hz+%GCT(i5UawRgF;TqzDu+P7zK$7go*)aGPZ0p z$yrc3@v(8CC>PHUc-WkHgI-oA-S)khr39n!*5g$oC~RYyCE+mHsj+# zWNW8HPiw^w(55CO>W(dp)e^0;KnzqyxeQ9wHD=eK@w5_bDJofJMdToqC61!r6);gekXs6-a5J9xI`C=4y(-@YYX5*?8_tiSQ0h?kq7X0a7xwDL< z8=3kBoUujcXivVKvz-ugj-K-IeU{iuw&BZ!xsBLc`nb_ifX8S}lN|<-Vg{`CIv|^p zH0$}Jw+--)1m2D;8?su`?ChfMN3$1A!zK-n#U6%_f4BYa8ByMUDxD3|dvKpI6Ml)3 z>-_gZFqpBPJY3(9!pZ~o$;$eMC+39qM=c81*mF61r|Hgwpc0SHD>`PkJXm1_)$%>9 z>idAi7_iS5r3}hM5~Du8ZpD`93+7-cqzLGOyMOb3I2^(Vw36!Pv`ITfsC#vIue6hh z1kSa{T6Q>k?XZdaB1VN6#gfTK+v2fW0k&7C>m$dLN~d+ADFuvQNx+MBkCYA^^W%_p zCasfsi1m^)(AUVPlL=Oe`7|%cCb_&a*pjM6M1pJ~@!V^obGulFo-jLG@uht3#$fjE zkKb$G(I5RQ*Rx-ya=fWeSNv4^RN_@&e>cw(n=rmR;o{r4Ln}L;@<99sVxsHg+C!W5 z8lK3uCgmS_$TG;?&D7g)d~TcoTb&m_7{ayT>aZ^9^un3q+7lpUQBsdhAzA{yGok)Nw@3ri=;o1$p0x%6Faas zRSrxOwTlkrtn0b>{$tm*`_=R{9Rr)xTBnJtX$STuJM@tNpGF@0fp}hcM+$b z{N3|;FlyIU3h~bC&j%(mV(#2oNBr4%&+g810o^Fm$40KK@7qJUHCy9bjK2M7U?|hL zg8Gqzf;X2pJ^y_xeB-M752M^npQpWhbb5`-MXK5Qt(hir_fCx7%l~%gSQuJwjZl#t zo@H`o&+!A(A+7eluMXO8lv5c`-kHDp|HFq$6btuzb<@X|?oyLtxexa;XeEEFS|B+N zu}yyRmEEC*k8_I}Tw)op#iPx6hHbqjeal^AlzL6{@Q!Wzp(=a1#5PIG!`OSPw69<7 z>N$SU@a}0rkKF2eMyx3TV)itVaFNOB9Sp6h@$nv_1yUzkZhAvn0$$~rDmbyLoJ z@$CJI4IG)3skxxx{Jm0QU!nE!aUODwF zcy3^Os?l!BKXc+v1{q2)eBJa_cJE{a-L`xuey$U#h7e(~M z%5LCQ5FK)K@SAKPL+mdq8g(l7&)YFz?)L_Ed2ObHNZLBkX!imJr>>`*)K{9s2%Ni* ztmn3wYl3Nb!)ylM0oC5e)U3|uj!v;{vRzp1nx5$|3T8rZ#m_l+>k7VpZGIGf>%ZCQ zC%dQn9K!;B$ihe}a2k&hM}sb4;N2H1vtCZ!x5Pfc$pJP>G|9H_aDX}EzDatJ^I!Nh zc9tf+AwDO+^Tpi!%XyCF;~(R9KFvr#9yBaixd!mCy=asT@GLf~ziXq`X_92G2sYAg zJdcsKb-(4_I#yBcKh_yO{}W^@BUuJ|%_(QnEpNOX+DHy6Tn4q#=v8sAfZEC6oNwpg zQb~%pMb!2so!&&t-t{EA;pXi`%nIIZh+yS$Wq8r9YI6X)pSkFI>iX%wOEwSHR0JGaMYe+6dGf5S2jDwH2Rx8K}q$XU5k!NIi{Vn4s4QVAy)hp((SG$3t^eN>!cMY-02yECJ zrP;Ezurn*bdaVe~VA7OGyI#)R?vB5CGCTKa8|I(m&><6TOb1u8xlFJm1mYxlk4(1M zyAD-ht=kK2MT0X8<$ev}n#WDTX7Z$7g`nSsM6s*37 zwvfJ;=_1lF>qu9it3SS*{c5(57{P3aDSTXGrfEZVfF8qFO+R{Uc;{?0l;03t08hc5~S1^WXzK#$Gg-1I-{99pW@8SSgxL+VOg zpJ~(@P+1Z5Vh!SvdWq z?gi`f6|#7AgB#3VOft9Z-p%G~-4Atk&ZV^P3&_l~fV$HQ`MOl~*4Ot!xX>}~=pc_K zRD;g9&^Fkgue{{Q?>21XpmPiTm(z>HU3Q~Vz0Q|`GL^=fh6Fs$D{#-H>1FR!(^pD! z3e%q6pNd}8XZBOhH1C#u#JvT)=j#Fb><46BlB%dq99uO?Pr3|M-M5Sr#pV9p2f#mJ z5j66m*l}V`qr;qZwDhnapP(5KIbOrVOS5$T+Vs)aehD)f!2?K+Y#8S=MH6qVYj zv5;0mWF}|vd4U&Ak(fS&6TbaD8~WjwV|hgV+sZ8Kr$pKIL5rKS*+`P_@nLdG_me?DZ6X5z!6ik$^6UM(EyldO^Yki!vc zv(z+uwS0)__*;lU!03cdQsiMu`(`+0!n%SVZPK3I@r>}w-(Vk<5CalDn_R!33J1gf z@g1h_EgDDJJu^#k7<+u>PUJ<)^}$HUnqc>o5~xMvE^iM9tCAQBuIwIg$W znbD^^evAvhXY`Cya=}Oj37w~b3w0+X>XfvA7$1`sY6^O7-MfJWWm5r4m?5IN4us+q zWdAH{e9Kx#(I(oplGTT-M!n{e&VTXpHi?zkX{83ySmE`qrF<8Id1mB|B74eb`h9z4 z9xZNs4PXNxj=YZYn1q1y;?DzvwDw;;Dkd%MICpl9dBFZ`=&}5{*AE*zv)*zRKWZI^DKD`ydT7V z--Q2^!k8nqL%sve>m-gDEYG#e9j`eyu^kCKyA+HbNk?Q<^L4sD+jbNXk?wv_cyKZF zP4<(9-1s`4oqyKZ`p2ILi>RU685jJip;|oTl2>}&;Ys_(+9Ow1J|wmZdg`AT|6{a} zy>m2X6|%cmqQQ_UK0^u%q1mO=g9{%V;o*rOgGpxJR1Mazn3{xM@AW6F$<%qkD(#%J zx1EcK7H9P(*#0cUxHuAg8Cn#~piLn{(zV*RqEnvi_!bNe2OAo^0JY(H$gjg(O}rDN zVFLu2>4M|mbVH*=)Q+uIxj5eSA2k|9KT=+j>|g}1>D)}a=Ys~ngzH#ECjnA}n7|~f z4e2`4y*GA66nJ9&mdixo%u|Eu6sTvu#TMIH#-%dq+!DQyIt&ipl00?|@7SC9_pAB)gv?mkXYAp%RPw1u&dHqY7Idec&~x?Pr1oZ}6T z0p2f*>yPKf8Ldbt#O47Y<>65q$itKxOYWvhv*6mYk%20EQ)rHlyuV|p_G9thz!K(? z7DlP?L7|de;q|C>b;jd`>)(H1JPoS-Y1U%z%VJa`+j|qn&ENC`gZ?c)Z_RM(>Pw3P zaVj9H;wXVit6c)=9#&7#!MT99ZNsdPAcv%r)ln6TUj42w%qu6Q3$P{yEtm~+fL^Li z)R|uPH&^a?&r`xA`Kb5XpH2z5wtSZXUiROdj^*%YHuE2$d6|;_%5B+av}GUW8Ui*3 z4EqVhnwdPSWP;L^D@9QTFhqnaRD3_;mzCp^Ic#7j7=>)>N-$B%DC`mwul>OCaivei!8 zJDn9wzzqL-OXRn2A?(yeR& z@iK5VilRu>kZjuduOl|ekDcrd`9BNRev)aiSIgaUa#k$bZTszQ$0zlT^}?o^8+#Kk zZ!y#qOAHv(hP@%&@nV;p>g{FiyuwVIwVg(%H-NS~%<;&@gd>U*eF}fVD6O9;iuR5Z zw9$Qtq!Gh&b=8f@OxJ-htK3Jtx1y_*Hhgj5vTyl^3HQcG^p1c>T^ri_$B1D$A(kX^ zJvaroVkTbYsl&Ym{>@w9GE21jP$i+Z!aQt6cv2t3bd}jgd8363N)>nJ&ONeJ$^|Qr z2QTaC9IJX-as6|4(5Xc6`ke{U2%kXV>~I?42rLpWkibuFgp79N$;&UO&lpP*qAO zO#^oGd=q5i-dJBZa=HIkqsR4c?#gzoyPmf~kn>>HCT|K*C;ve5+CeJ^Kb~6~H5s?5 z(GJP%{l6@xG#L`kXd58r&9e*?txHZ1;&_YAxdlWSR^73vR%fh(Q9Q-fy76vsVP)*9 zbA>ftWAKLLF{}XWr4U$%dPL_21M1{2#V)=atf(N=0-F8&36Uf7eQ-tQp)6Zm40-pI z&VxLS>RhAHoRj@^$I?cA|E!oda($KezKGHqMwuu;)>lz)Hm?Q?YDZp6ENjQ;G={9p zEk4ROKYt3!O0AUGZ14^mvOiix^u%nO`d1Di1FGQ=hv(Vx41g;d?1Fk?!Lh>^YkgGy zEl2*ZJSsg;;ja{ZcE>P{(E~9{c6kZUR_n|rw1-$>lNkh zt?C?WwfbWYAUI%Y8FLHHkSPuVh@l>pHjV~yRX3>|zs_)^4h4@)sR`7|9$Mz6qbk0+ zn6!@Qh)ZhDj4WW*vcg~Qo2K6y{a8lK!ilV_N8kLkYzyOV8y}GqR=38=s+DqK9IbQ!QR&W_Z!g?6RY*r=} zWH)hI;9BP3ooCpHdYMWbT9tNfe z2w9o2`MF>G!b!`+5-A8c^!USwHfMd1%o2VQIR<o1NHb&adVNX|>sgC)Cki$ku`7WZQsb*Wq-UXjFV+1WccF zzEtLlX`6wCW(^|2GVP@EUSG4U03KHZw(%KWh*(t0iI_!Q!DYhg10?+bLICF8+(MON;4(edusR?NqsoQvj0_$hl*4#|ee4-VU#3SMq(JAY;2oVz zY|KOA2dro=K@ugPreJCn5-cpEy6u?U4L6(BiEd!C3NM=S94KH4kjlhlrW2I@l$T4M z{t@KL#fp@FQ28f<>aHhMGWy;>kA9I({D|CZ7<^iB5_3sq!*i9>rhoo`_sD?Kx|@aa1V24gqZdQ22-ka{{4_u4pkMN z>&V;jW^j?3SXdB$S?R98Db}F&PQmFc1fQ% zJ4|I}Woc66(R<*+R?hda;vYJ}S)$PvgH=P8LC3!x+q~xslaGuQ1?=^)uV$?)DjW5> z@`FJQrb<+EK>w#Dd<4RzOqo90MYB&q_fFO#Y=H5d&zyOmD*ifr8&8;I(rEd|XN75ZyTsJ7eh-?n`FPeiCNESh{X>e>R5>NtjoP4kw ziS>PLS<0ZF5hGOnBkRhu>2ZtRZZ7HEcAFODXlFaGi_WF5ZfZ;i<+C?LPM?%ZYd!6>=%)FVi+jHIG5n6d8(KUO1=M?leAt;`RKq!Pz?*cYw~q?s$Ktxo(H1j#+kEMbCX`T5zVZ-`-Rp#kh((sF$-Z)>q3< zE)BnW?RcxNtg&Fzo1{xI1M4qdQR&WjPrH0IWH@Qkp0X7Q5fmhRGaYlu;7OZ+_0XUm02vAm@e z3-ci1Tn@9JIC+jfVsFe(>B2wA-dx0iW0^wU%9miFg;~*%#D%wVFu88-DMp;&qp)(8 z+#{2dzHVMeoS8^y??reK>8*KIeO9?^+R0lQD7(U>3Lb+cfE2spRj_3$ySuJaOi8py zRUDEZkL8ak933%x8S`WK#u>za*Aep<$wUfnMiB1HyypO}le}jL<4;fwXees_04@25 z$hD!S4yV0+K$?aKs1Utqs`R)UeUd9hUePp97t@wE73JcBk>ATU^()7?19_%WDu%bF zZn)8|05)JV2Yi0IY2KMe>%Dys<+6U^8)WVne*9pq$E>AYN}1c+A(#Fb-M?QnKP!1R z_$_9fv569lfK7118c>~JrA20BYtqgkdwevMa!7P7i!1-%cupw*YmuW|HJZqy0>Q1(&f#qC=bt~>eFDIJlG4c!ZOe>+ZkvabD@RTMo zlnvuEHahL5{EtDQjJ0wUZ-!j+W>0c2qlVjpyq9VFw5Kira-Jw@n~U2tqm^j*Vb~Ya ziV4MTR6hO#^XIzNXh4u%JHzbw(M>A_3>pKrLrplQ$@WrOcTiIsm4ZsSE-QAVXvhRG z2($v0Z)VBUTGBvipa~;Ahi}v*#(hX&vd4D~gpHPZU(*SGb_FEdy6Oh}NLlvDyOHPi zDBW3)cI1wepm^VDxfcDnka2UUJ{FK<6o@4)24;hyQalsAw=WE%g7-vM1!%r_Iqex- z;pdR{J-+nHzDApdAYonmNMzj0Pa<#kua`z`pFC@olWlBP2B)`Ev&MhWo=tohH7Rd> z0|@r>I`tN!#SkoKyuNGY8Nf^V+%9|cwxPuXmH8u<1bGm(*l;Ru7xhFE$}(qWZy3)# zbV?XnvwB6`1j-;~xV1pC4+?KZDoHHp_0mGw?m&=6<_(Ru%~W)tk?`G7_lCiWMrVE% zP@wClWlX~DG5wgy-MO)q7Za^UdJJN|CjJ|B4hYs65#QQDf}_tztQ!F}H3 zPsJDEv#Pm)p1tvNr1RpfV5=A)?w<%3u6jWVloo)w!Cc4ExH?2hS->fNoX90OeQ1E_ zDUE(5qeP0UC^yw$=evY|ny|`;DKEaHxOkn$>totIzwS-?`|Tb%@(&M^JX}(I(sGbD z=DETuE%(9OE(+(qTp)J3iX5`Uvqk2$nc}_vcM+wRruX?&R5z^HpB{0&dvyo>T`Kto zScc2wz0&>m2~1o0un{bs#mK?EBnBc5$bPAQ%C z9E(qgwtiGZ^g1}9y7Yr8v)E;Cc+J%@B(KD7Ab{`>d-gUtPEcLoT%asOMFHY|9mEAL}- z+|jk?xVHBFuNxlTYDw)=fRw=I4oaw)2e6^|9;`fpi^XVI>F>ZKfH=uS&{LD0!%WcChI|Mbwqi9 zmJR3L5J28Gku0I0?42UoeJlLr3L#OZ^V7PDk6Ja2x*f#}vYv0f0m7F$2@hzHM;e}2 zem62|9FWE27P~ba-?Hr;AZ`a$z+KZ7wZ@ATB1Wzuog1zlo!eN@)Wm9kp;j@PVQf^VP{ zh_P+1OFCwr*3XRRf99DCgyLsDP&b*xp{&ZHa=mBk(gJra+>X8zTw&SdWL%#OV*?`e za92o<;9_8sA3J4=hG;x5%ILINN?ZS?R`lVgk7hriuGBDjd;kyB{s$gUV>h$#dyd!k z&ytP?>9y_Lruw?}A^i)ORM6mUT;cu|Us4oA6@r#p9+1qFLa7Ox@H(yxK$oO!63&{T zjV0m3wU6+(dCrJUMD&mKJ0PuA=YyKsi&4>mqfSGli$xrCMxnpxXEtjx#jFMM8Us;7)l4*`%d2WXZEUr#4Qov4H*cN15-r&;P-c^D1f%0f~vi3PgT2zoVE=dk1 z&vIng`l+Suc%_%lDG}l1xe-L%!dj@~{*{9GxXDDTo$ z&i*6d=dWR99r#x+|MauGkdO2`j`X#+B|Z3`c(oi|wHeG>J!Vj* zXud-JIj)ud+xteRI8tPi+J1MJ5uH#(vK?BWB%-%(I;MH;5rd}>HNW<;9R0D?^!*)o z3XOiBapOCj1$OuZcAmQEc+NzXE)n7qGaU>ClPPn610(TV$0M#6P+U~T29X>fK!}C?Dz9stOq@z$)wO+ zEOUH&f0e-FmsK>v>kaMHaBbP&+9zG`uL73BHR+oVDjMzIM^{jg{A2`TH7KpeF%x6R z6tbz5M&YRrkOAo1YAFc;V+A-x9KmijhF77Di8{=-af^p8HZeW+l+cqF&F?^KgkV&~5U+zp6G}nHx#G8?;EV}fiWXhWU;=*f zK6t*&pIh5gMhUK3m-BMUmKq->#J2j_^;;<$u*$6vt4Yp-R_`cv!iAJBgvw7>;l|qw z|H{#+Ow{O#I7*s{wwjXdmc9b~G!Ps{Sv^DdF>4Z4^dvxZ@gq27BC6)qKL4}CO!sn` zI?02P*MryJ4$82>ZIJP7V|~q3vud^La3!M_bASZEPK6z^9*jz;i=#Unu%bVORFUn( zyJk)*Q0fGN;G=efpV($R>@>9d!n2f^`MlMwP7tnR^ z(er=h^cc`#Ds1SMW`#o%b;ZNd5|Va!KA;4L{m2ktVt};&c$RTIU6jz7ed*0t*o4*1 zEBidM+{Hu25FU_C`h&yp&H>Fv#J8h|ng%a7LP2pu9LBP$#2WfXrV0J+efT6kd#q)+ z?q18EH~Wi6O%)aY#Cjfb{-?ywVm5f#>G1n|4(krwc<-F!74esr&E4?3_4CiEJNW!@ z_bXZH9}UYkw+J|ld)&`{VmT4F6Pd7Vl^}EyVD;hocF?rr!J&ZfCq8EK8J#OA`57Ob zA*&$gb9mz{zC{w~IM;Z5nR6y;9dYjmsPOmR@LjS!-+ zmipOIjDda2h#`kY@*%hO;eLB(a<*GrkneHGjE(1;?>{ocy|8lpX+eOFpTuO{$oyY5 z^npfQfzZaaKa{c~qV~Pz6d~wZEl2uRW=qnLrl5hpW#+@5420Fe3Q7%0o9D7xe}9|j zvDY6bGes(8zJ&pOqnw|fYs!3P=;Fwrf6jKK1RFY8JYm7UA~l&xuJnI(UUttU`cRbk z-iVc5Vv+Nfsz!aNs*RId{?#=v^WY;_5K%bE%KJBJDA+;S4X)5$_or7jZk({iGZ9 zeE#bR8@x{WCKr2ar)`6H-~g@sQXA!SAul1NuFGjb>IM8}86vEp zyQrwm-fa)8dj=YzLEKjMKBN2CFO7$J)C4EK(E3dE%VkuO<vg(RHe@yzw(&fC%Fxpmfg|2i3!4e*2hTmzVtVJsZR`&?nfAD{fyTby$UxLqk zTeE6HZ*uQB8q2y~=OTbSc9VOX*9bf{P^?`j(g?OInshkx96nqrtS^$g=SUPO) z0Y*q~`)?K~DrZvje~PU+>$2AFHXlHsIa>?Z0dmWMTQx7-*{9UuuIIackFDr$lUVi^ zA#PG(#h3h%QmfU0g3TO-ixZfQ{yqnWgKuI2E1dbR)yVj{>kW8H0@!-(kpj$mV)oME z{qBz7yq()PZE}h&IlQj;5eIOR?`FLX7{IDWQkU)S6~35ur{w@f-QuJ{qriUC9@9Tm z@Z5g`9$b&5Nr0aMNJ3*PCM2^#^j@M*XB%1{_FExHc4LLn`_DE)Zn1MHV+hAOxQJE$ z+v*v~W(O@CKfy>GbP9OQ`B~qr0ply1p4gHzDgv!9BWXy;oyt)HPYkFuFH;gD?>^hY zHk-8%U(qE}nQXe2HQVz>0Y|6lRPonR_&jiR{35t1Alu>&A7+s3g+~A!wi!d z2X;#HX2~Ylv{-Vk@jX-$F9d=|2OB>6!|N|z0k@}?*q(X!vgdnmlb1riPSs~^`eZPT zu{iNn`$w8;zxOuTdbACBj6)D2R;&YPDzjk}t+cys>_SLu9BhNyqArdowaf}@3ej7fKY-eIi~qYJ-Pa$-z#sUI~{W1 z@CJKO6k-%F{vsk!8&RdozJP#Uo2CmG1Y_BEg)< zxoSq|l$Fi5-gUnc;kHZ%Fet8h^GpL4++_PN>D4w^lST7&jZR#7dzww=+iTqb8Xh5N(A5CTUlRZTDd zj+_xPM^10@#le}6TUvW}M=TooF~}3C-|omwR)&0byU6P!!M$7M1V{_TYZ(t6yPxm+ z+bG?s#lBA==$QJMRsSD86dd?fe^&W~u8hPg7;Pe$x9WxbEl9`ro;UCmGVkSvq+eJi zIdm!q>mij0v_)w4IxxF3O{NRM%A-U2tM(DMwqcOMB^I~Ic zZ})o2QOQ$nRbSUL4;bG5O2p&$i!rf3W3d(4TPYy)pTEProg${igQ( z%$%O?p|o+Q@QB-O_g`kL)mAi)*}m(ur_)CN_kVr$c(P^5`wsbI@T!(kV{Z4oy$Kg; zo?f`$y5ZM;+W#hvR`JBCPs}&1-L0|q?Hk?9V_RpBr0w{A`3&`m-j7DFOYmP^ zw1CM;^m`Ie^U>0E_uQj>Q%jjsX7vwGDZQu$p#uHGsa_MYOU}RUT~aw#@d{*k(7t@W zd}p0bmz)Z7i@t*Anc(}qUn&kyv4&z(ef2yphc3u&+{0)$TZ4DO7~_XY-#3lt_kO8y zgoNUEgHErxlAS}1HoP>%#dpsyMbMWph(&pkR@?fjN|O)oJ~R$pg~LjwZJ&Of?=8FJ z^JiWWeG9$WHCi8aHVb*kulz`bKt-?`_wR@EN5z1*9Uo|w5 z+NJvchih2V{o(sO&-V{_en_wThg;Y3zRvSFkMlf_qanPr-R_ww z_L%1{Y%+1_GGzr0D`cc`u<2bn_ZIJ#>-<{w162`IlMV9nU&YN zASKd)JlNM|C=o2$`pI;{qc;xa87sy~4pUWwJ>R|T`;z_NP1|o?Nn1hhUy=W$m1@4? zQakULP&3u68nSKS(mWvX$=O+6mRa9eIQ8qb^_-lb7hoA}{&eFfeWo9gW_9`tP0 zSNK&h2wGITJHZlgyUIN1B{1Y#R#0F2FG-GrVjt4aA$(sQA?EChw1gbyd1TN=D(83D!_6Ndi|oJ8}q-W=zuges;@2 zO*cDv;u(V5x2ZeiCmiDSvzjl0|41MKd;TaI=(OEg_l2?!zaBau)Dh|SBDWA|C>gT@ zJTki~TzVMtXs$bu8trO6o3HHbRrjnS-fh4zmac61&WrK5+A%Zxp3GQQXfW>AcdO|i zN%up@t-o!t$0pz~&=g+_C{}L3gEZ9QB=yO6;^5Jf3R*At_7MSc%1#y=E7vEEI%Qd@ zI(|x0J@--mdPmtYGyf5NRhp-X!NvAW{T%N8&Fz*PfC_XwP1 z?n#7{$W0t&CdE&?P2AS7hR5Z6W(@z4@VGu>^0Q$K!Eek=I-S+GhwqYMl)~D;$epr zP@xL#2i@)5>iTo-npQe)&0gnfW=gCRiSLJ5nhjt~d<9p8w?ff`+LW+H;svuQ>O=>Z zmkB7Kqzw|+SBJiUMbBn6gQ1$ejw6gUHZt^OIianbSk58H<8<7f8IStgy8NQ~QkY2z=y z-KgajxxpP~6V&{sPqQYH;io>bVhV@0?u@nLB6FymeZW(h*2>&2Lb<)WG39P=|G*&roRdm3481#Sro+Ui;b>#_?{58Fq~j<`i}%6tp1WDo01J)w6r+9!MPwen}Z!j zvs*USCXJt;2RnQACZQGal&~sg<2Z)9!;9$DQTOV|`(KiuB{acr;4eTQdv-yHz}Yq& z;z_d6Ao(k7f9~E;0TEe^D$RrT!HFIGSm9D1TRF3_VAFV#(NF_Af5wEKbx$`-Zl7_F z`#6hh6nsP8V&N|C(;WP=!!PsTVy>AuflGGKE{Fa|Fc$s3L1cF6!54GIZ-~Enb-;oro%lyW^V0e>yQ+{U8G{-5j;Dw>A0SfvJ^YnY zciHcKbol(?$tJV=+51b+%b(A1-Wk>i?xqU!ZNL`OV+soo_ zeB2j5cCo5j&d1-dvOE8o7&IiWcm>(4=XqHj`<*={hx8Q~pN1LNxBr%AAbSs@_}mBN zO9Die@ZM{=X3+m6HaB8;Xljhf9Hp8|8V+t&EFXDL?5G#_M?y6~e9S)eOp--vmnHwL z{Q>6f%Wd!Wp1&EXg~LDPN@KE7Wn|Iz5rKs`u3{yErPl;j5@d9X=WbT?`!-0iGE6P{ z1Mm1$DedDM#{%8L3j71EN41;7zO;72K1w`jgr8Rk$D4 zg#V!#SKPg$D}^RRR-lAS>baEa(g~&JSqZL^gzE{3ASKm}UWbbW(Wb-Bqz(WQwdn8; zvS%`kFG2l6gQI(JEvIVq`^GIfyLQ?3_SOUh{(G%J_w?FACHcb5Nm^|U-aM5SFb=sK zZ^AH@_R()ss8%ppcw8ygrMJ0k8oKKnITDWqCSH`7>&WH+rK0Y*UglJ{n!JwrHV3&< z=_u5%i6A8PHk=kosxTJ)o$h2BF-6HI5l{Y#;;@)ZNR!zfb}I~wyp(yg+@{pmY`@_Q zG+h+i$x$IzarJW;8JtC1x*OCT?PR%sA(H!LIN1C3bjZFNox6{8Yd<@^ zdmEhmG7a%-DhM~Lg9h;tapRJ%(sD&T!nPVt(|D*`9-qJC&a-Cu!h6lihtKY~b0m7V z*V>Nv$2UKeK*_tl2fEg%#hF0hjtS1kryb0SYSF3-5y-3kvX=12Y+XlQ4?R97h1Ig& zFI%tZNO!!tbbVl$IxJavk0`k~f%}ie8kyvpS4&l@lZsW2&vb_fKPPu;>tDZNy`{I| zN~^ZQuTE{>&2^S4HlIH>u_BcW?a}4*ig%eZ`schi<@oK-_x9Xz%VM2ZdE!y+e*h%D z+_6Ez`%3t!^?`^95u9@Ed*UAn-L$-^%?NRUl^_B{#cJ}(Pa-rY@u0I!@A23!=!xh1 z_6Hl{uw33!`!M z@FsA0)%(|&#U%onw*8p$xm#qXGgh0FW zeA|M<2_4~O0m;c5Jg~d^fcC8wqdKJog$QT`fR!ds)N6w^Jd0T{;JltGeo1w=uOYKK zn@NulYkyK6%>|l*@{K8DhRT9kua~}fl!ord2OA}Oa!g~5Mk27G{_mYMHhv4)wi226 z*3$(+&+4o2K0aH>aZh~M)$MN@XFl+K_F}d1F;>fzG5b)qs_*9|eVYA$?_quc)#2` zDT<(nOX9X8jlq_ayWX~$;53~F{zW(^8@^n#FvDivV(~!3U;s5Tog7}#_>bV{r_}k- zAN_7MiKFwn8bP|u3d|kEV#nW0^#GT8D0hxH5kIk;*qPC*ibjvR=9`=JNRHEHSHNSe z6sJ(#N5EJQi#9taG!n@V>TI=;j6otq2EEIu=%Z(BZP}QoCWGm)R^0gr*@?E5n=iHb zwL0Wpge(qohL=&8$}nu8_;hJ8z3j`xdDr@#?_V3cF?Z(MlZ382`yvNq9rkVc+Fhvo z?2km3O6hWW9YT14R0&eA832g9jVr58JsZ*w=hr_ac9~LJ(G=9{svO}B;^J2j=p^)_ z7OP)xT6WgEI27>Ppz&5OR{O`z{kKh913mA(_%#pQ(zOh8`fn#`JbCo*h4cI4%8Vz_ zb5h{8D#YMyd+OW=TJBEbOri%O&T(n34!uKk1+srldYV)`cs6o{qY;sf*goC+p7pqn zS`~HAVyomCtyM!oO?^(!ijgr>M6wioB-Vou_@Q#tABlZEk`oq9C`bd;zCvSWaSrb) zOLLaaLtS-#)Nq;C#dePyGYznAI!8I$&|BDWq4c381KxYv-c%H&L4kO*2m`rIzmujC ztpnfRC^#@ypZ~GivFLN@cm96L4L?Vx+Dneo*Wbv`UA?zh7ghYwj1OPpNWj+j7Ah!$-rLvk0vnPJJSEDDVd3U8RFPJoA2VzF4gW6fe- zyJ~BDb$droz}%4zOZFRu^S};h@ya!1Tw!A==IroV?ZW#0x?Vp?gkhmuV zTDoUnOWQ_q(VKAk9PHyjvIPDduj&yOvjIxzoi(IwfwC>=VEX1tMcUf)*orWhKHhX}!S7Cdw+_q^LIAOC1Z7dP z4y=w#SZP;A&r;b4*|D*&L-NhMg--HTq@ts*?rkl}#{nfA9 zvHef?I>`o{0#+mj@D|+S>o^h{s9*6)(0rrh2dZ!~hZ+qZ7=n*rCXGMZov)OWnWE?q z;GJJXp|({x(TETFRL@ez6)B^_VE&tbO5x$KDrVlQ1uVfNqRMZj&Gjse-rsl>K!D&T z*GyR-egawzURu+FvuCH0*!7izfhx6NP~phfEidEzvcb=HC%WmgFLK;!Fs#PfbkG0T zbAzL0=r`pG2cG{(P71SpPxXEnc#Kq3^bNjuC9G;h_>0Ig9Qq@n^jiAbNLLuj4vc-v^65LYWBS1t}1jC^w$`_*}=ti~dIdT?Ay?NC;VgPL)mn`!(hL6>hm z6U2jgVqzqz%IS|p82I?qz-a-k=S8mYB(b>y!?P}lQ8O4o?ggsAJ{;1cy7BTr9XQK_ zr`LH8T4$|Dzxegn6fDcfMj`izbm`m!nFosuh*CJ;4khRC;fC7GN(vwWn?++*K1uh$-AxCZ}4sO$$ zM^F)WtAM~w9xMh4q$8g&0LmP5G-By1_UBJ-qXbUx339!IXOHJIC~~~nU{s^8ugi)@ zelpjQk@d|};HRySe*6CE4M~okgH=uJ@cJ99O`tZA!_gtlS@pJE3U)C%gItb{t0J2X7>enc7;f3Vl z1&Q)k&ulF2-aExDoj=Z+*zI@Wf`Nat_L1+5(Po{ZpGEygzdJfJY~puz7mYT2+HbEw zZ=vn(`5eEawA5n5^_chAyPzVT-V1$zy_9l&25{)m!m4J}UH*|46qqQ`bolr&o%48 z-hKF~zIt8WF@SI;&s>uHM3g4Fjc#v3?&vX-0Uu2>Rf?hlxs2WwnerysRk7KV>E{x? z>q8k+b#_m@z1ef>wEKNDf2`_qdw1(6!xpn&2HndxX?fr7tcF#kWjh{7NlDrnzP@W+ zO*uaSH*2UhQ{-gEG6a-zKN0ezwu|H;oAA0`OiO81+{y8_k@|DZb<)-nw+Eq_RS;Mu(JvPP0xa_?LS-z7}NZ7c8G z*hoz?OJ>+i)`XmY;`J71s~dC!Zz}YBR63}poHU!2Rr~xz%!4m16SjfbHctm+D5g<6Wi?MY2qxFDPlV) zSMP3iih&q6cIVjGjKDGINs;CO6-+_32$lAnyQ{l${maYutDUr57}LwWz5>Suu|BZ{ z`}&VW&sj-v?KEQWTQBIHQ2?cJYCk}rrXby&D`}?<>kBG@Y-6hc3^RnkAkbC?)vTgW z7IpR`>UP({Lk8$L#ICQa@1+=ujQNtW_*3sOP&K*%2wtob3jAI3#wP9gPpV>?hi1#H zw~Wvd@Gj!_L=fv3T7n^{TlhDQA_L_ffrzj~97eaetOLZFCvc$Q<~=b)JuMr7MmR42 zr7r*_D7-OGChtYgS0JNBIt=_+2U6Jeji5Xz2xU)JSZm`xjN4I)=RfI;SQqHjqmpV4 zew{h zW+B`Nu|wpU<3*LndvMJ|xGg9tiaai4%0T97CvtxUedJpId>~@0SE_vwtjzO>EQ~K4 zJIFsg74l^jpPm_?H+*L`HK*{pqcvZ1_OcK|=v%Fxv*OcWsVSlV9hCHb@mp9Hf2KRMY=ohPi6E{u zBWB|d@X)j1T}N~rbZW717@W_eFJpI#PEv1Et1|nnZDvltbm&>GUkAF;>46F59C!VB z6cke+NTZ2fRL_e06Tp7_1#^IdF3nS;T(1C-(LBJc2=H$`Ffr@QQ<(3)eXh2$0xIAu z+SJuNHeT3QO(mb~XIG^3AItfY9ya|?yK|AdL+4YkpPG^wne93M#W$9HRKgd$>+nL83@PWAcvZjuzVf_g&?epRvv z)NbKV@SCu4gthcaY!q;WnRtq6ChmZDK&h7tX2^04H&x>)`Rk8*J32SmWvcV4sJYH( z^CA28Z4RDPMpf4X&j(=VW-z(X(++_JD_s8*i2gx|*7XyAt5IK-KnI9TdQr@>yg3k+ zHe`!mQsg^}oxpmbC0|pZ+AC7^=9s&4+myd3q^~q%qha0tctJ@(X?K`G9rdZ+3-^?r zeFHu|Wv*3mgPNipKz68rZ!B0R1{1d)%&5Ak$FmJsp#~Ho2%#f2MPYpvSSeaQ-jdgz zP|8Ph^d1JvMH5u`GH=_n%6Vrg@$8HXGp*@Qvid})He)6^!VCS&v8s0MMsJD*bpECe z|KzwUzTG*M{kF`4$<(x8!6pn{+#9C_zG(0Q#(L>H9rk7 zKR6*Q@>~HI5l7}-BgZkzv5!SJS$fLw=MdDaCa+%b95^%}q$dSw$_dmWXyFEAv4yZF zw&U6NUCU@WFB9YV%0oUCwLZ6ulC9T%zT$m#GaqzxE#~~dFyD}15Ij28t3MJSHjrE7 zr10n-g0vH%2T@@>r^u(BAHdtQF^@Ah4H#Of>bJsbyu5IOKN6!e6s>+02VVP^zUiQl zpBbN_&husAofl(mhAQVy_-kS8OLQ|ZX}`w?WgSK}yAXcX)o}rJr z|Gy-X4Q~&VhQq<#KXm+CTn>$6XA^Vbu`xsil+31%klIn@9&OogW?a+|n~++fjeTZU zS&jak$_K_?`ulU-p?IFq_CstdtWw`+DEZ+--vQooKg#=de|vXIdqa?N(ZtYqv8fvK z(dufbEzxmdHECqPMVI01oR>3@Nx~RpELGA1{-)u7KpIXWvQ+;_{Jjc}qG;y?EZxOh zfu#;{$d8ape97544wlr(je3Ij1PcRJtxS1sf|_PzXGCSA`nlAWahg5PB6@#+Iy9Z{ zr~2h8qi~->bk?&Eeyd66P!&i{D&F3q?{dd5_2DpAgtX;KU$%KVYg z=PkhM|3Uy4oL_=K%8FKGm%srj;uAnQ4!qyj1bOf+hQpn}KZ5EVuh&!!(G{vyY7Qpk00f{c=nO`a~XVT z{o(}V2Dk;m0|!_Q{>m)RBym(F*}hLe4}2xMqS3fr?LZ^nw?sCNi-}rAJzXw0s(!aW zSifyGeyL+j<75@zC;Gmkp_mS0Vh#CMBz5?p{~w9HDAE{UY44%rL$(OzE^HhdoPq68 zZ>>>n3L)>FPpurfr}O0>?DrdIKYZB_!fHu^&d6i*O7NNlzr+kgMHfs1MAT5pQ7AMc zot7&$Myzy0hLinkzkR9a`=+@1>EsOjI_)RhtWCUK|6eZDXZt(5I!XV(K$MnR&2jY@ zChz4P;?fR`Xbqs&ejHx(2|4hxz4}PaXRF}6j@De;Iqm+%necnW7HS4)-JwJZh&Gf8 z%1bUDQ%0I|m5jve7c=o#XoN)@MsZS;*;8hRKr~i$#vdGXq1i)nCEfe!p2isYfQ*e3 zt!f&*hAN>o?tCS_Qcs|klexzw-fgx0)^Gd5oYP8{KlFPXFy4_KZsR;VVsBNHDH!%H zB29I{+kNEV@L2GPD3V1_EJPX%gm{A@z$aML@6A+Y6zdtaQm-95f`UP^uCoBK-b>%p z*kv#Hy-w#BibRsR-i`wmb(Tows0+2dfl7wf`%mSMO!9Hn4!RYi%xg)5qs!IfNQW`c znzN@EHrDU*f|9H?MuLLMhK*)PQw9Iuy&8ji#XQCEu3;cuDo8Hhq&t-{O(g(=N^`}p zDaad8s1+X*TNsGl-p#^9F{J}gTh9!+C`Yu_rQ}8wd)KYR2F{(>Sczpjo6sy{Xstu( zE~W3hdvpu(9Gye*MB5_-y#rKV1ZWZhi|Yg!F)TU=ad}akp?Hu7s0>B+*R%)7tk*#L zp4pm}^Qq_t?$-ExX#Ec!T;f*fxpL2QXeIs0cvOBo=9CY{xw>y|dG6}(-{NelE9nUt zklZ`<;LXi^rXUk~!bL|B%k*X~!O3`p+726!iHxi1#gv0M4v@7g2Rao(1h@eh(OuLU zoa>oJ*Xlk+g2@zT_PeI8;jT=!m!Ct8GV!XV<-4& z(UAoYI3-|FTRzDu42<{K@P1RPp4p@hhJZyGo%td*v&f9dbAmS!d5Qv3oj3xi;XwGV zX3n2@f(KK`JD?(=AB63M<#^Nx(Jp=@{EK#GNVA6^Q-+zUR$IgKh`|n7@^{pwMsQT^ zFBmDmRp^82%+0(VBX%tVvLNC;(UZU|rOv`QP51)3ErGeRW$K|#m}E_HYZH+dNNO7) z?(p;h6OURv)uGmv+8Dj9-|<>d5$7P@Klht{2_sNd+J+w-`{XGeIB}T_rNCfV}p5E)ct>Y_$|xLlZ2ESpe``PbIg8ctqko*jV{#6G8+p zk3*=Ucfa)tRx|H?QX*2P989$~5!&z%6g5WX`#i|SrGRy;+`h`u;@L*x$;+>5Yp>w* zKNVNmFm#KsK67Dm|7Ya*U!tVm-zW*fCF?(GC8`56qR5t;lj8uytcX;p=ObFNBP4Eh z6GDm_X=W@L>2nJTW2vgJD;FYt0;R9(YC6risF1c#lkX0Ee_Q>CZ4tlzpw>^UB%vR{ zyF!8vqT3c2npeaTW}ZTQ!WT>#b#{Uu)ka-ohT^MmgInjYoDvceg+I?b6GY;~w$X1! zuGsMM9>oPS+~z6-%08(@d7dHT$;wO|$=;+rH@r3_**@shTj_*`@W#c+)SZ z^eaARUB1`79l1}5KHI3$t3~cZ|L=Jqs}6d^_CW$l;p%{yW$u*nx#XLn1>VYEi&d<8 zm%=oytCAM43{-|)S(Oe|)wiM-veQB5;ZkF!ik0bgx0;&NwP4sffAaFw&}!9l`m_-c z{xJWpVDdQi&B50k>Rr+>x`|n}FiQs#NX}3)c;wM)>v_a>Rg(_dHNJ5RZ5vq*m;TvV z^HPKz-L*d9x^4hd9(UjR!r%b-J~qt+^-Vd7Ut!!+igd5gFIBwJT^=4Dv9=S`F=ptY zB2wqV$Z1%1Rt!M12WiI)axG9~Q-M|ly?liTe?QkSuK9Kh9Vw6BQQKG*6nR~Ag6o4h z$;ZYt*!t||*TrLOc=l*gS9-pn{wzRlMn;2|_D=aI4eExD7(v+-7HIBM7uJ#U5( zT02{EWRN|{b?1u$Y2mTC(<_^gC}`I8?(JY+4*ngG4Nr}zFb=6&${&F<~pOKl4C;rSnNI zMFllux~d+nQ=KJ&S>x{x&s^W+=_CB+KAzZZA-D%Dx8u>b69sLt1w?5 z4u`@zHK7#A<1i1-ELsz7qsTu;!w%h&x@)TnV4ZQ=AwsVnW z&q52%om({y`zi-2Wb|$0ugus~rJ|NY{K_mYi?o|ud*sbc{m5Ah-D`dF=-%K~N~Sw| zgVNKPPVK?oCf(R0t~xRxPFKn|)vguyJ{;2-_TlPr4!K*8tUyoob-WC^ESCeh>mP^1pD~>#ds*@x|t zdrDRUak-XUPMZ~n3H?Qv`~OJX!agNz+a)LSH3+`9I$oqWtAc<0z@&-dO{ zb&~Dn=JQ#8T+#+8gonY!2detF)!94?m~$NO&{GME)X}=^YZ)A5A7oz!LLAHa_j=bu zT6ybV)w+IRjHi-PP0a81HPpHWrOYqE89pLR_6_vT2FK@~nu+`33GFz`;D6sEy^%i> zmPO?RFlO&Rp91v0fW|IzH~a~>anK^+V~~2&>Uc5yqUV>)7gr-%RZxTq8xf*M!=l)ooI>_nTqt_b%#dSkBJC`{Xys#WFn4U)6K@&Jsn=0Ice`LTukKf6W_})}+kgO6 z0NQL(6%GlCLOs-ci&4Ss_1rVbMYFO!=n$M|WpOzz)?&sH;Y;LSkm6oT&Gl)ds#<`arK?$+0Fc!n*= zE19gKd-amHP+o3~&uz}19&^tQ%+7mU`OISwWSD$$4oL(I-`6aF(nFJDgjyQvtO`SI z7H$`4fVltM02NPFY1joU81kTXuko^dK-MGHiWmHta0HL!kL7X5nU>XNyd7ugBJwDJH5XL({aWp_#+TvK!c z{Cq6ZQBwy37yt1{F)#`j%k6A6?Z$f@feQY|1}*bAYSn>d3Jucd9Z>%UoB+ zm!j|Ck(w~ko-vR~+)s2@4$7Nq=2)z>t+!5wX*fMU#M;#PWsN1ui0ius&g-B|Z-)$&GqA zmzx-%2Rt=-zBvzmVyd46${Dx1nDEBQ#9-IGtI?Ew?a{uA&WQAkX^6Y(L9ADnpF)S z6|I+cwx{Ulvu{%?$|-V6tayuO@##i!-4PRFkx8#`=@gK53SNSUSMoHL@&L!^aU>|xu~IZpU&t8X^^N& zanZ{@PAwGm$X_bAp$A5<7 z4Sl?ows=KO)r*^KJtZ%-&HeNaWx&$hWa}7l!tAYM9OkvRTktz5N#Bk=&8bZqWIs25 zzxGo-9gCh4GrWjq7{2mKbIGbjbsJT5o+d+Fe47ocyZjHsCV@kcr6-8gO&7`Vl&u!tKbO-f=KJh*c5gkJbSUxPUtyJa%y{1cbm1Y#G{AH~8YRu-Xl0M)B8#>Vi&kue3xY4( z2>d!RJ19rIS4`3b*5nu`8*0=X!)GNSFtlbLuQR+*+it<8?`xXRyWgv`j7Ji5D)9xJ zg5aGmf%MW^X^@r$2`KT)ofN+kUFJ!_GC1jz{O+%%97J>#Vyi2EtvBTWT2|wQPo5`o zJ?}@V%-t`(KO0l$+1Kwr@+q6sCe~(mr0?1z<50V2jlhZj^`4|CSy8jSc#tsl>n`5gOLn)gZm=$bdL?0P17a?w?s8411=XhOi8oW9I(C`KmOgyG?NF?vyN-bN7#p@KqUoh2(a1ga*LOEdx zrR*6M=2K<4r|?$1VJ%-agH<3tXFBBu_z=7*2ZuoOkr|suou)l^2iqyyr>kYYZ(=s$_1-t=hxK^WVO5%pgPC?^E6T8hi@}mh0}o5r1(UXwZ5abG_dY)xAYiM7CiM zm|4&!@&G;j_nYQ}9*CsyHvTSjh`TV16j+7V`1!OP#+ROUH#QBdaVj{DcBj5z7X?qupc%37 zW*MP8*oQ0w;SfmUNyeZ6!Dh;`00O@2f!m5?C-o7$VE`8PLdkqCr!%HFfEY#G+@SM-L)|{=;F%Vj zp7UjE_lAUwH2KXD zNe=ykM}svdnIgr?g+1V?U59(NIh-;d{Q(<^GYVNBs(s3)6}J<5h%$X+?WY1PjE!$? z>b?DMrh5k}Se(@0HA*s$NtHl~P=9AjNX!q(@vTjC!rQci2Legf>9T$SB zC6lE0og&rCLM!s`a_Ym3av-y#&$--LB5DOdWF{el1jS?v(pcngGc1J5ABpYA1E9)i z#@0-IJ#@2SX;H5Jq(w+>GE6u0X~oOZf+^*}YLA;Gsw%(1ml6Jn*u1xx zc#Fy~X3IVi?wy3Sp_ja1!Ly+T6fcxL6r~&33@|S4wBS`u6dDU%Q`XDdAfjc<*{JOzG~~|) zsGz02fGXrwp`Az!A{;Bug3|e>vuqyu} zaUmn{ylW<~QdP9yR)>>(N@Nu!;cupaLYa#g_P@k~cb>;|*(SQ?0a0WM|R?JEMX7yJB0xO#~>SRO)*JXRNf`YK;b`K54oymk~qD zmci1)6N{Y&Xib_G!4Q`z+CdWZ z@K0=?zHMa=V@e@y<^By%wcFMVum_P*Xlt)IJyqw-LR!=}XhHta+OmUGK#WN_Wf_oc=#?pGdGkyKSD@{D3jqllEJ4H9tvH96u z`6?dsHCVL!Z_*A0)zT8gR-7H;$+aap6Fwr!nbCT$`^G6#(+cLhq{SIy3gCUL6c+*C$ITAt z+&im{X=w#`DM-EWKykra=+x^BLT?Ukg|k^F>M3Q<{(_BJZ#)wrVzd2L&y_)>R@CLS zb6Sl;#6T<5d8Wy-@_0kjQ;mcj{Utg{J`rCNq+bM#*w;SVubYTIkWV2E*mbY{Be(l-Q?+Ucz<=mrksQgo~{A6Jp#5-cqi4QKhB<9=p@w4 zEq5-q2V}}m+=w*;h{;O?Sp8>iy`p#PnQ5aS2d!@Tp&*&JXG{3`PhamzOynLrujd3U-CnRor=*Qf(KEbVyoDT=mp-{De)31Kl*Cm9HL24%4iL0Hv#={dh z{}&8z{+jH_`nMB*t*xJm7rgk?)X89d{4|xAz6gCgCiAxHxS71f=8eZEk10j`BIoZy zKH_{e&}xVi32Iiw#ajYbIw7@`@sGjVe@0%4DR?Ml8Y}PcpX%E+uaZ-CAHlFC)Nb;R z5OXFwGkx?V^Q@i{I}0~cubzBJ3x_4>DTTj**gCn-B+Q%^4l+RH&rsPjmt%faEC=N2~ z>N2BqW{gX9^SpfR274PGYScc|%(!=k%3m;WDpMy#jaKh=)u}UCknzV042XKvGPFp3QScpHaL6Q?cjc;32Y&-n z#!6zYGPA`kP>BeLd zF1BT*4kqPJ>)%P2i%KzY!UXasX8nW&(Kd0O2ra}C+QtmTsiMoEU62G>1AhwuK09X@ z_!QJr7Zu2yi;4w%fSS2?FuV$a3@*F%=qHYja*wkUhIso9LA{3VYcLt86EZ!&h*3KL zf8wny?E+nds3_v38j*MGFVIZ_GnS7}w^EnnP|z;0H}~mU?G;O{0_xfyWg*w}C}voaU0|7C=dV8p3eVj4p2Q zLjxe#As0^A@C}NTi$JY~r6xh^vWUC^!d&JDD8PG%D$PCYK@&_*Z$Y={V`(zFKhLD| zscwVyJ7*`nK8P`O;#|=Kp&~ql;aSoc+3c?=ZY8)_wrsZW#`Jxh_qDp0=suAvdo-vM zup?$ZteK1}n{+W3(%O)+{Ed})-@Lj!2?5p@LRD{8j9P0uwoI(1{~xz%%d-&eu!p5y z@-Xn`Lp+O%&`r)L)*f=>lGk~!0F_`1zW1qe^i~W`zsYX9vNUGb)5J48F#ad{Ui-ygrsV^!sOgTOe z`I6Cc5h5*)&N(0N)^xK1uJplFrMrf5lGEwRo$POQPGrU+EF~0rgQ7njj{r|^Z!giC z7)h=`&t~zm&p^^yc)U2N2v)|C(GZ)5ZRvdj*`MdbkNA6>fsill{Mj1poQkRu=c|wR z)xl-KV0PsYimlR%oJfXcT*Ntc7T2kFiNn9{q`bJ5j)_9Z&*dZ?>Fi3f3TUi9zdx|m z%rfwPY0_o)|72$AU?{Hyrfb4jIl+S&@^4Lmh8w9_Uh&U@%RF81RbZ+t7>&i-c5&mUk%LrqAV%eSOc{LJ9ugjrff5b+#`P*Ya-+S_m+wY4dlE2S6ctxFrm*!+tW{Yn?U>ERPnT&hUJZL zY)9L+mOs+|;MhfU-T9?7%ROPtYUE5xQ~dl*yJH6>nM59-G8yVk)XJf`O7PB}i}R35 zo?}{l6jc$Zn}jkmE(&FQ%FDb-_+WK)4{{6sGS4Mjp)}9aghI__e3x-;4gS@vT3jAB z?z!l2<9tuoy&j8YxpvaG@(#of>R)xsjiAPrA#}2XV~Fn5EpQukJJB5-4X@?w&#+&;8 z<8Jo+9O$NeDbDuiA-fclOL2iNq6w3Gq=v?+PTQcNMIE8`-}&D==x>_9hOYuX1Oy_t zQFeMEB>+54;VwiXN-Im+#jfp)`C1+wSg?!2SRmBy3k? zwz{C&{LvYO#VN;xT6TVk@A9`FfTl*k?HJyrQE9GZ6Ae13*MyEHmk9}@b3y|gmZb>% zkkUHSgX1fx!({GHN`_(a+ttp;l_j#nc`;_D#hz((!BIs5osuYn`g+o)N#%sJ2U%04 zUSrC9#Ef3+0wbG+A^B2Nr6{}ccX7!y+U_+Qwp}^raWcW)wV7EV2M#S_hL#PT2A6~=@eG2^sZekj*T=Nk z&faAcJupMl8EzUV!7jfu3*4W&icIr+*(J<&_uccsE~98m#HW&k7Ctx~MEAOynaKQcs)RKG@&v%ENuWUiZypSJ({=jm&)sH|-)a95HXX zqJ4a{PQeRpdU*Lo>CZ>X+S~(6murHhAGh9|a`o5FEi$Q%RF6C4R_S-m-z;0d%kM;x zihkRK625DllVtQK-Z!RORGVm7xZeS0qP_WAZNzF{s_;njJ6xJ$k0xZxD-hi2HS1|Oq{XS;qZ^VxxroTi}hbnKnKVM@J(oW5i`DO{h>BM*1S`V`AOy)@}z=iO39+KhZ{5Q>#YJ$^GN zTP}#?-@@IR*V|V0igDkmICU4}x5x0hP`#&RN;mHp-Yt(?fA7IKGSWVoEC9}x2VZq%>h-P9mR>1v+4Mi8<1mS%6XUMl11qVT-Af9t#1E8SffnWmRcJ<6z7J_ zZbU^%;_aH5W>?(#F`(Ef4o zxrl|;Sx_>lnx% z3-7rwIJ7uYktpw)_&W2BL;v&KM5Edf9ojKG_oYzlSc|)?65dGnO-p}@g_T@f0Vyjo zNe!xo`4jfBYveV#1IAN zP#$vPYeVD@6FAP((nWd0KpJLQ{%!YY-OO8xowm9@P zsGyKCnMd0gU31mj>&^__h+*xGCxNg8#1SATvXO$XcU!Ba6_8>|%2q?SJ0z@o9L4F* z&eTmu?2XnhaK%zvC)0OySr&mT_w;v&TwUvzMO@Pe?mJB)CbrBSKe8|f#yPLP^7&cT zIuoBDA}yrh|MOf=wOpV0Qq-XY{OL&lw6wHac+wH-#vc0+iv!@IU$PHaqn z`aoI4OsMM{);XF74e(7Q=wPtBHV204W{vH%J5WuJbk8dK;D(l9<-W$@<9?#l2i`f- z9}YRzwr;|r0GL>03Iwn?SM%wkTaWf0gAo;ipiej*=PL?E1B0GC9F&-WP6!196{h=8 zUSUcF@0NnqBe-!`0!wp5)!~Zu*t*M$Rm4p5BoWu2%YOv}Qs^M6Fh*13kio3Si{KC- zRl0K;L%$5y0Ry)-K_(8AP?+f^>9%KZE-tPcUUuKmq(3nDOqyr*qR$O8jT`ARH*gd0 z*A;Kn`g;`oYGHBCF$Cq-6d4Fdrs@Rict0(eJl9nj-*%3^PGgWur}~QQKvx8)PD9r| z{$YF&GH)CJP4LAwOS`VQ&T2a*dyYRPOuDSCLa#NCE;R>lHZV*gh8eFzPMn zQ*@nNXXOzf9`hXk0MCiyqgyld=~5ldg&B!7A>&y6J#2)e0}@8oAY^~ATQwh*p+TYx zX@+s?9^2Y^2}-luW)t3j;ws@9&MxS^X3(v0f;9XO+u2R}?B5UB`qvLUFCZb5z^E5D z_C?G^z(-hcrYyb0m&!#Ma|G!%d5RGb@XH<&Vd~He-ylPktLdKG4!ElEK>QJ8aE~@e zhP6R#S3Uo#Ix#bLEihS>aS38vgO7ikYV;u9$IR?Tu+Mg=(lcX%PaZPGmPCUq#jtsac4Gz4xCU~0xi#QHZHU@@#OkgzGD zlZn4EiCDgW*zTj*XHgQ9Kv*2cbRUtc8CSw-wjK9u&~{4X@6bC%lf-gVlCy&W`s%^? ztF4daiPf6yT{3Cj4Q8Ei0_uxPAXn>_(gY$kG)?Ch;=}S}g}KiQJdF#ot_G5^guARE z5ef@ft*)P4u$|TQYi=FZPSjiW0J9REn1cLd<*pfXF{ISiQ-I#0Fw@4{^9Dnm-)r#H zjgA@obZL)v@<#N7Kgxo$t9BgK#STcrPAffbj4@5`If*e-9^7rEo%ccgRe|nEC;l1} z2<|?ic{-lmt46qPq@e3Cgi`!|lq_AIDnyZsX?2;$M~1pam)%C$>=m)jBTp)GA!oMY zCV!jsMZi3&9qF&9mNO=ry;%hnE0R1TgAF`IA1c~DL=Yy?WI-s=tzkWy0q51H0PNp2 zJjx>G;fp<2TA={PmZ5Gn(XKqhg4(h-ELPBwP3Srz9@4oHqj$QMHt-`SrHD)*OiC(^ zm$f1aR)qZGPc%&6#7uqWu02m(_$_hEf_N1S=>Q+qxf<->%A9FLk6^HIpJGF7n?elt zTc7KUi%h%wfgg8LFB5v&*8@+aCp`1&hbw|tWLDGD1AxW3L-k#^hdsvm#$X#X))C&c z{&`3IytgsK4j`e<#N^YyahZ-Hw6*G0J@H|0lm-Qq`;hg0t|N8j=C&iaJwD$fNH^;- znPFVmloHy`7fr$fY7d?Rh#=L1c8a6SYZJe<;BxQj5CE+sL_CJ+wGP@Eo#D{SjpK#m zG5KWE!(da}wAPH9eR%KbZx|F%>Is|4D&I*6;TqssT)#x+o$CDvp_Y`^#>X_F|NBg+~m2=Z852h&a(Efv*73voTe?B?UgBOjhSyO<{4Tax{z|?c!ihUIYp5 zHAddoqarb!qe2(_^S|ZTAat0&>MLLG^!U=-#;u?z26Q)7i zG4ZVPM~dU!sCl*2oqG*5Sd@>|r1=va`(y*=(FWVL3nrOLQmdHmvCh~X3Hwtnq zKs+tbP}TCaTNg`~=q2EzXAc3+tg_I|kT(f`U@3U_XVq4NMu6i0&x?=*g4q)<2C^c^ z^v3e*(ZCk#yo1eSO6BFBhvPL;zG@u#uGy-t0aT674nfoBmz_67aeBC?ArTz)LK4Y^ z2|bpd&x(Yj)I=NM4X}iy(!2R`hFn&~Cms7|c91`z{n!GLQ@cV8?7QMJ4uWNQvqz5Hs*-LKn6Js%?^p-B*UIh?=lqFkmR*AHlUiHr;M zu=(D{ffypT7thls!$jd~#$aTjL>3>?(1L0m>FewB$7^*!op5PHO>1EMlY1z9OIxj{ zK5&k=qDd{$(~!`7Gp$dIf!Ja0Mj#f&MHdS8Uh5q|bZ*2VM5MnkJ-mTcBtw(eS(4wp zgw(46HsfI$`j>yBKalHM1!Dw0v&5>R9BRY0H!N@tc3ehowW;5GdH$58?#9Nn>Qm={ zE9YaKU@C*DW96Qp&!}JbAk&K+_|kB`T-lb!)0!1s94$2gh!ravU5`R9@;KQ%nKKPX zT&>MGh9A4znyzT)*Lt1slK9eC6TYF;HPPFvlyNv+^jGff+bRzlM6wrfe!usgdfqBX z>_5+pP|rmYrY>f135c7bWI_ebR+pjo`xjZ8ob7VGt(=ZRNIK|@1)VU`uA zxI33ltvDN7pL8mOeK(5*QWo>%Il7YDlS-x-4a(x|W=PQA^mk`Uo(!f|u3OVu^jqvJ zq4vvh44o-}Zn zyX8nr(yiP-t@U~GG~1L>YZ_Na0BMM$RizCmmO;aM`wHhi z?qXOxp!)j6mQLwKh}JpL-& z;v1UBL}xTKm;J*w(=iIVB-#VbOr^94=)>-G~OisZ5&V33P%2Dd-XJH`ODmiV%ZQl(ld1a;Rgj z8@GCfx}X(J|G?GiZeg~=+Zt5gSjxTR;v=8@E_`UyV;&9EhiDz(JJiE_ic1G16&`Pg zF8|Q!ME_D+4o8oF3t9!?`*yfj{@UEn2G$eL4~2yvlIyH8s&}lY97he?jMQVFFZkwJ z1#1Pn?!2UEf>TuQf?29pcn&IN=I_`7Z?>O)kWxu3*gCQI7VYK~6C5F21w=V~+qKa# zO!*LsuJJ!?hSWOI^x~ve#mbgdyQ0juUc~71lIr1#aTnZ(@>|9weUYb9b@4kg;AjBP zJvo7l+IqK_jc`lEKiQolpkwj%PMsUm{qyLxbz1E8F*)mqqye39sW7l zt^FgG6t)M7qjpre1g3nkm)-%IU@<8KYx5EWD=pl?ByIQ_OX@u^fe>1#s7M+dC>j3 zjfzDIWZi&qk~NI2?;cuDW~eeF0R1{#3{2cDq56^xV%JDv^WN-sZFB~8lQI|evsHv_ zKO{o`GS>m>QQOgLC|}b0qp)>B#Smy5Tqc~fCuWpM5WfIgLePbaW!NAEl@pt{d+~ATL%+Lfs#Zo`>|nG0n$Ou|N?%#)I!VEsA-l#ca@JasFYEQbCa+CXiK@`h`ivk}PP$b8hAu# z7p<=iQO|$3oX1Wxj}Fo-#&%#IG`?JlkeCRRZlx|@GmB+g-rIHfRMp%F_Wtt^oBB+I z&o)B14a%CqSEJX?F|6r2z3A%T4m|M;8N0Sz!DI(HLJGsl9b31Ngc9aDG%CZ>3%JMCUsna*aslJC8|Ii%qL&o{fq`fQR_bb!awBHPGW6GSi>wG(Ar9d#ngCNtb{K7D9bxdZHPOn zW~7EcSdNWh+IkluV+Q+eu@`G?>-2z6>abJ*-okvkpLIBlx=k*QL0P_GUfZi{I~~z| zK4MUklj@rL*3*d-tWxp4EIn1aVV5?d)3T(#fVBESsh_|)H0;taGDDa>tnMg7OUW-? zJ-_TIDf)F-f7_RNv4a7;)G&!P1o_v6`-BDQ`L3?d0G)&CSkN|-&*Y^Klbk>hfQ#+j z;6-^-H#)=b4fTSd(Fp2L`)Sdr`4wZb?{ zwuHF3a8#4o-_#crc*^6BEy%vOS17MhljJOK^x^mQr0n6PJdEp@i~N;yW;b#Q4t0Aj z$bUNf^v1|f%bb%qyFSkbrw@oa;NlQq%KhIv5!-x#h|*r{GLJzE!wX|m+U3jS+ zIodIMk~;fby)eMrJIvp=*zld_qoFX}54m5d#Q6IO#E@f`=Z1>A%;_f~aS^A{9cR(N z07hn2G*M?d<{DzxssY;uP^~Jv&3RY#PNad!c}yM3P~6;+Rs%93D&jotrk=pvn3{=sYp)X8PS6}O8W_Fv2qJ#ot;>EWwm}HN+onzz(x-nY z*MH4K(7=#xn13;ntBWNwCfgL#tB<4UVaVa3vx??7n(JEXYfRpepLivPJTKN4J39$X z#0DD@Uth#9jy4baez;ZO}=sMs}U7uKI1}W4NmD2p1 zw=G)KO~E~oGMk9e|32A!w-IcgbF@wqNY|?fWyZxaKe{&3Go;+}&!Q#I(_Tye&XJEU ziP54j;g6sqCL;Enm-bn6#udjGyd2LTvdUZ*9y$cK>|1fY{#o;kMnAgxow>-XiQapf zVVqApMhlWZ*JM?dV7mOn6>2JEQ(RuSzH*gQApEdtorAu-Q+mf=O9_lDze_{pI7tn9p43E4iA*v_E4EYfwrT}c@3b4wS}TP%vVl}kutl%G|q@(L0#pdyQu=P=Q2r|4d^sH-$H97$Km0ar%_t(wBjbK^peif-`P<5W}7tA-m$ zdZaz^CUx1;R9lQI{%u23I=kw`qwj1XrO-s!0UQhynz=^u_Nvh6GF7>hZ4(w_%ilSf zxz%j-ip;ff*n>E_deQ_V;K7m{U&FPmYn9!rudfObwI9!tdm6eC_wZoMr*oB>?U%T) z&h87Zlup{D7>5)gj>5gQg%!jLjg@erxbvS;Cm@GSuw2)*pFez44bzh3C2uE_;T3R= zted^m4C{m;Wbr|9zEb<+pZrv7-cPlTswBg&QDQntON-M6#<*LaTg8~y<03tIGV^(D zepjPEPc#Uba9{jM?iuvf{zP7Pz8>K3Qv7vpr9n_I&AiRtOa71U6)zjx;~6X(#p{*O z+?UM_y7T7h?Way4_1zR9(N7_f=EN%sA>A%?anSXUH}Vx_`43xk6_Myp=_t4$DW`4X z6v9i~Y0}=_LQq88CFny3}hK;O^7{=GF|G?*?bR~7D)`V;^CobXu zSy^CJPnK5n_Kv+b|7CA4a|a6m8tW#RZe-zg<@+rdf}Y5P>!>2m)aXIr%(q`(H{=Fy z=2^bFt0KUy$1iZ5bXvP@Fh-YR#T$eUGN1a?(qFxzdYYkdQ?EE~i+)X`cDpH{O@Qnu z@BZ({Blc=VB}#58{li&FZ;aom$ogqNUn?Kmv80w6TWe zv$2_7sSkB*xTjpf9Qs4q%fUZT2HjZ2)IXR6ysJ4eYQCYH2Vof_ACpU(OR&naPFjPH zZA#VCgd)`j?61(kw7$+5#bPi&lo&)@mnJ;UV(J4YSrDNeK@bgQ@|%!@JBH#}>U0N+ zFVU+@@;FtXcWrLo3(CJNd7fSZK&hY&eNMlXW|*w#t+4UO)VY0D6x03)i~>{Jb7U@S z`?N^>))VJ*oO7}xYP>_rs}-hKxP#A@%OmSz>{E;O-@P@zs`;wULI_9X4^ z_)$_=%T5~%b%UxsOZ3pjrszptDtGV{oqZfkTDP_sS%+KCmpfTa6xBvqkE)dm-5!77 zGQP&tV07U_5Od~xoaVm1PG|t)Rh;N*i3G>fG$>OrYAYmLzu^PORZG&t83tZXe4^7o zOia)ROsR6cc@hbx_I;`6CsgQjPE?2FHnNqj>xR)w==oFA=&{kiSUc)@@$;zXtXC2K zQO_qc+uVl6rdmI;pJgz!vAgR04_jfCwS}3HT!}O*=*HHk$?Ns0 zgTIuuXD!9xVc#*b@`5*Y$jGmE$L(X-D3IgN^gmcSUIX2n&G`G33HZ9=9yDEcqsu&2 zH1qLVAYxi-tB+dTJCtyij<+ALD>nmZcvq=_bf$mCmxH)GD>1Q-!yZu$6_|=O8&_7< zk>`F^y5cU8fJ!VtcSydaBY=Z(1M2O*5rbLyNTwn~eTp7Sfpj4f5C?Exd%-4H(l$sT z#KR6Tov93)u{J0WQW*9PyE-3aEfcXJKQCsZGO`s(Z2~L(mzzv%wcI>vrRR z=JDs4>4tv+`|=*h?4ub1t9h&n6*z#< zCD%6&TeSg*C=@IhHs(Y$?41)sxSAjMOHTcV&ABphPKc>b&F_b%M@ycwI7*F*Mv-v>FdtUh_q8Hn+0VHlr zSp#?p^n5|v@x2U|Bp73hX?2|wVDYgA=W5D_x}f}ql(}T}0T=aX3O;UDo*tRJ#iK$X z#=I(A(e}aKMVIuc6($i6ji?q*s(tX>*aelQ|7H%ML7snZ7lLJS1Niv;y_PlBq;!cm zjn{2){Ioo!RqO>4G15ChPttc@Nc=YY*;h2a@M(OS4shYYp9wz}S)6yl?5etL^@gKB zj3>CsWc7CZnyfjIi_{Ubt95qvX2!N6SFb!tW;!jkiOESPFaWacPy|Gh(Cx=)_sW^k z4s<=fV}sbQPc?rE7o)X7r>`hSYcFY4gjuy~%jR32G!k7( zbvT?V3HHxrQ(%LtI!WQ z4~Klwg{#dxzkmEvM07=nOezF|sfPjAQ%9B+)CQC~*Vilf_yMIwZuT@VCsukY_Q=>< zv80XlVrsD^^-l9MdcI|#6&)07V2gvm1u-0@YJ7`%Jw9Ptv+ID-+CMUj_! zuyw_2r4*rBR(C@G^(LA@TQ&(Tjzr)1GJk*n3mNdw`}n@?m&3t!04Y5)AN3YFepp* zw;uk(?w!p9#J@8C*uQ`I?iPiK1tCc|Vzqd2b$#M-o&ha@#Wf5vI}wxE2J0T>>4Ns{ zHhH=^;~L$G)K>kMv$asPWM>|aa6=Hy+wlil)u@l=w&JP1vFr9^4vcJrU_8f%w{sqX zq4nuO4RE=q2sfcXMN!fpCZr}&x)lVnZoo~N#D|5RM+-=9On%Wha_~Bg=0-LcTHi-& zQ;unq8=bSJ&c#SmGovCTn0hraFn(mIF_ky^-D+@FeJy!|9}Jo&dP*ux{P8}em$~2F z&Nc0g?TYB1p6Xn?x}_VXj&&5{-pOKu>5nR5q$~X**AqmXW4Z4oR%jb*SU=XuWu! zCX-h+sV7I{_GfjYwD#Uc97bKDK?vXWFOueZd}Ghhe01lyQHC_Rj%_>GQ+R-m4chb4 z-Pd$b?viY|tN3RY%Sv~V=(jfvEYc*sTFg3B7~F{`LfT=%6-?DxE;>8I5H#6z?S3Z; zRCaM;4%&di55!rqsKmd(Q)suS$&FGv>J8LtwldGoeKqueKNFVT4+%QsBo{*&ZiBz^~TJ{x+>j(1X@Im`<{XbLrjp zWtY(xdg$il2utq45DdiiRSK)3@b zK&P&u=sZ!{u{Hsqn~<#ddm64bk4r<=x$#z`rnT6_&>UOnyNfL z1Y6pNJzOy%S?A*Tam>x6j_`+Wb&cby$tIn*`h7IpHsgU^l>WkuB$YbLM00(F+vojlBe*0I2SU!> zD1J&HRflBkPxoLvxbc(*rzMr#=$`B_<1lAmrawbSHdcNwW$}X0{z)sEfIzYXGx8(| zjI%%WOHZ9?L;WhZ^^*1|HgtFnr3i%Y><={7(yx03c&;j9lUQe#8vGsURU*!rhIF?u zjvVT31jZ^Hwp#;Wi#s~9p^cM@?>ZCC-jntXWRnGt)0JJQeQO0y@xv$!Qy){M%}(vi zSQnb`=!2hu{aztK>t;W~?=Nq)N$%e@N&O|$g3i=fHv!=N6?jigD2u%!gu8iM1ER`l zy_gaL_oh{nW8>3$gs=zoWW7}A8Iv}&3S5{=S+3QpQ6ttOfi-9&SKk~`$TtJOqH%7m zyyo+!++cyci&h5zxg@_Sh1&~H->>xK!Oj=Qmp;xlTq}A1uxqq~ym(kZH}CXO!gvt% zr5msHKrXeC&+jwn;IFwxkjbGu1!y7@~xSw*2O{q`-W zcVwxhSgg&pUdi|Jy}zSaJTJk!*PdmKqxs2utt>sH;Hov42yp;ebSi?6?qogUxN(&} zLn9ajwmbY<{B?CO&6QfgYt($SG;>S7L2x+mBlf zDtaZxV`F|JGy0S#dIWJE#~V^?i$f4u1E7WjGFJybQ+uAfyheI$X@lb@Aj2+>TDgqY znLkSj3nUhn_6D zlZWAm)S$p3+Z2h&V52cete%!FJ&(|{H7hul_bZ&w--ApJat{nEiI`K1>?F1(2T7l4 zT96xui#dE-{f;gH+@avDc={g(;2v~<6pq^l(Vp_79v)1y@6E#WaG?c|1;*6a7^ckK zU?{*3^tsL~ag%)H8NjsFx&Pp|1k4NNs%pZs|`* z1-e$LCFnOZVA<(Afx*S<1-fVW1U?i8J(J2mk63?2K}>gUkYi(i)Y9BKL2&?eV~i!( zU$lfjLaL)>&p051oCts-H2UX^;yuN%drwn-&eCTiXfA53c4B5s9T(T0_4U!Rry830 zUyDN450!U~jl`cC$Pg~Y+KOD@#Od$sr$t)TF5`=GTf|Jq_RKdc(k}cUe@z<+zMzfG z8lk0xe1s_%eSIh4e|sj#x1=J`fbHuP-<61&^xpc+QYFp#XT@?QeT(AvPi?sWKT>l3 zfx6QXC{~u^>Lsw7(biyrr=GmfD>A5y$stJJle6mk*r$2=HlGl?ucPo0^W%B?mXDY6 z&W~2&5Ku?`B2wk+41z^NbY%Ao@My%Ssnm##nK$)eYJN9+M$g1JG*xQWbxl;?KKcDx zqV(mTMk2ydP3dv+4eaufOZqniqS*Gi`t>OUpGuZ{A(LS9%w?9-R=Ca?q57;(v{8Rk z)%Dhekz)|WpNjp}LPs8cHqJcS%`j4tn8y;E~#UmtTW2D~H6!oYQjniYvKN z`;%NE91Tne0naE!`aDs~>%TQ$b1UmXcQznS^bh0E0wn!123>{}!=y!87s0Xj)Ly#5{P)Rj-h5JG zR;cBaQLg=>(9NyiD%bc%ZEfvB=^35BU$)D}Z{Lj<*a-#{*d-(7Wyy;daiY{4Mn&Mk zVI$SAw^KdpCckHP`cB(ZVxRs-Pp!<5VR34{Fr*X-o6yq&;>>lx2Wi&JrZ#lh1vbB( z<)KwPE?d4b01qx&5>4(K!-WfOI*bKfVfcJgUU&CdyNo>;aR_AvM#}PedpYdop)Qfn z6ww#Sl_ECuMH8Ua2J&HaI|9M+1PwL$C^UV$(+hgkv|!b@XxW-?MJPk4IbhbaOQwuk z-g(@7A_w}vZ~U2GNwBEfikaqeC6PUgb)MhTsX^2rf8jD-Z>t*}_nXuWj0HRwZN$S3 zE^1!G@K{4HK3)3Ke@-(g?9-_`XQvvX3il4a3YVd8YsK=73_NV(@3J75DS15oOq~+v z^(8dAj}9P<6Ey2T7z;-T4g3mK7EmB0`qLlys0f(wCk;_G6>|NRlr?%?R?l~_f=~jn zTgmhjB}_BwS9EPUHko;jf*|sfow`~OLPTaD-7Vh~7K?JJu*Ve?$5a+KHfNC))q8Y? zy@Jqp6;jOODd3uQa0)2#eG>A4hN&dwesibxx(HEZ>>B%_Ec00dA z8nKiclI(`-1gVcy4XeC$7zf`pV9bq}g{GHTZGTtX^}mbCL7-LkBMm7oX^R=8mx?|9 z@OxtEMMgvG~~!+fU?HC4&s~{n7pa1q7czuXl8Rl}HNjElL(4 zrsRG)O{HtB#JEk;g3t_uIx!DAIB$(n8+vzI#ax_8%JiG(JZFz*_#Sm1N%T!226Yd` zw(5kVU)y=sR+N-4Iqndzsm3X&e}q-PS;ca zZoc;4uxFJGeMq$8N0*!-#lI?EkC5~Ly?uE3*k`OQ0veBoiBBenHnxzBX8 zB&k{FwP%u~;ME2l+d&Ep1W!kRZTR0I-oXb5WA z(qy@a<*j!MO*dW4vmt_L4lLD4nSKKF|D^p(s6CZw1Oi}Jr>AXzcGGEo6c7*9Nb4}C z34pUsQoYwFib>E|JK4vT7k8lvt#{w9KI#KQZ*R{?H>jU8d|17+wXVRMs`0xR;Gv6q z=@F`|E*SM%WhAUtV_oF+66krw&+~x(+r{`g9=Yx|VOnx>ZbKr_scPxAJNDd*B`~h$ zEx7c}y&0F@-|HJLoiTLc3CTH6BN^@ZFAGHkck0ZH-tDfj zpWEE@1(p+_R`O~v`J50h>i@89vy@p%4ewra!~XwHhL#&+1>WDqe*OaK!q!=LBI1A?s7l1A zSs9>v=EH;*GBuj%vn(ZgV!i`io#IHfqZ2x2VWWYZbpw#@_;BwE^_HNb*`-V`j9YdeTb!w7dMlisILEMzSS^VsS7R%$k{b33EV1uXs~!rznJE z&Q0S$Xnn56ZN9v>*&Bz%J7bclb%k-CkX~{@XG0z-#mFfU$nvB{`+fb%DMu;qFY&*+ zQ?1#&<9hB+)jwX-vQVd9$oV z=<#56qv+Je5tV4m(|Px564cIW33@&0_j|>%*}Uz$;1nNm3}rvYg3`SRZAa+r?~&$K zRONLYDxRWS8I5vaTwg*T`vVp9n3bp=LpM0i_2kJ{LwwUYE?7Nyr*byIVwHvQ@#8sQ$whKUn(c!%K32fAMRiOev1%VNX<{~FwrBc zW&CL5#wrXx{Hl8mvoCt!tgU!ynZV)N_V0n!FNMuwP8RVCh!+b**(9mFaAADH6=E3q8qybq99T zWxAk)QeYOiVF-;WFx(`Nw%eg`l9Jg#d)AsJyGnowfPz{Gb#EI}-fDi=n*?^QErI6i z7_(|hvr0e-wn>fskr1U=W%00gP1yZO8YrAz3ALWN@ngs$_c=V1?6mfQ=5`B!a3dBl zO|^25RTFj4L|=*q5WB3rm^aWGl0W?oiJ{1Kc`I9w7GQ7D_6Bj1Nok&fsmslQS-9Ey z3_lNQua|CTx0qr?-FL77hSOHiDvoVN?Y12HFYl-*@b!#$Erdjby;vCSB|E2-ME5sF z!Hc_uTc!PPRjrCy38T;xq{q1^Q{%d`uk!9j=Ni|o7Q%AL7{SJd#2VC$^Z=r!iZ0I3 zA}O61^jHuUeRWHmpfmsTSb0ZNgfkq^l@wwoS)p+%B0B{ie$ZL zK?&;ynsyj4(*?s=aZrLX(+C|2V^ZD!S1;Ur?cDDR5h7@^2@~*c7NeY2rvJYAD}T30 zc>d0F*3D)OrsyaLSYB35sAjKXBN04$LvAHg4nqxF>Gb{U-)FuVs1{nF^!uO1O7nlC2iaYk8(Se7&hsw*amOEMhT2t&;#w}oS z^nt}H02b@rfBjVYy6+F-RRORou8|-IhqFfyb-}iGfy=@CkH^j2|F@%o$_2S3VicG{ zU9cqZB>?PMvHrdBRrfvKN<{B$0NZK~4)!l&h(vF!plP@8|G9j&JK;q$tcc?<+c&U* zcmHKR=l;+8I{V*NvSj6oPPxiW+>sTie;&!3v%;D ziCI}lsz>AI4a|8{4I$|)Z?zpEYU0){`T|LpYfG!19$UH6_O~W!E|MJ9>%9(*KzEmyIahQSj-AzfVBdLz75$l&$_&dT#4o!}J8_av`MZj# zb^bs;;Dui$|rn2U%ryZ&WPM&af{rF4ynSI13MBQvG3Ce@IRZjyZU!` zob0E`-6D}ovr>Vi-RLF6F2jc)ks&+}BD6&k0aA3)vN~L(0+8a!Yiin{%gfQ?!{>^% zgPgVB7xTd0${m}py*;Dz2}nzfIJDus$(@eJ0I9n1-jHj%vqJ(=3Nk=G+@ zIC|ZjsEwV+`EPd9bk{+EYOc4nup(>z?T@_He>uYXk!Xe!Lp`lYiRo)S?uIALKtV2v+3YwjsG3_$w40=p{Vgu^1{|p|U;i9lRlb1zmO*|lApe%J1~wX;Dwl%XhGz5y^uS@t!Lgl z9y{Lcd*UN(1ym*fZKcE9KEq=0)GJQ(lOTVCpi5g5e2;y#NA`?TVCy0Y$GN|Cvy{Ns0Eg4~ZavhI$-1O;J&dkQ5-1wS(kK39%*8OkPqE$Ep#n5}`5(5nXh{@ea~QFaZ$Az2 zo$9~PC2ECwW@FC^0T`)-=AJgHU4eM+_iDTBXSNsm&WeXIcVHMuUkR zbd-86_1DI2s#&}jRf;Uo5bIqQC=p;Rs$duB#0S@U>)Sk{u2=BhYl82zClCPr(y#X7 z>*QJi6+y;#YA zgqZ$>iP2q&#IGyb=?z<{A$HkiCA*`IyV${`ziyY=3z}TG7p6XAB|zvO=r5uqE1aW1 z)65a{zVS9clR9X>wrV}-XTvnFN#+%3ZDI`u$6QwmudPy(n z(jJOa4NM~hn8QXi8Grm$FVM8CkQZyU@RGCeRuqBs=;c1Y=u(*A!y+YWJlSCUnA!<=e}Al%e)# z`o~3IeGU*lZR28GsMS-B_TpOR={~0N;2$=vexy0!YpqC+)>{=l&F>#;uMsnadKo$z zpJ*bF?n<5{D-dnX9Fhrc(_Pi7jdme2!EwEC1JU1}cdLA2yF#tk_IP5~TgcdyWs->v ziXTm_;kjfuHdyK*?T7LiR|b?_vZ*JGn-HehU4#p!vU<401|I1gbqjQDJ^9mXH72!< zzyLVR7XM3`ZZ$~xYlX-<*w1?*zjw13Nolda1|?%W%oPgOoO9foDvvq~DGG18igeov zR2xh7Bp-Ws@#ZnVvG2vFElM3Fhup4 zqZ>~W;f{oLd>7e8!NJB^oQ5lDzDX1Cqub^6C_TOAi_>8K$p-De=x8*r6V)%6d1Qli zSOZvR0C%6ntbl<(Yc15YPDeGmEusVQbe1d8VS;s*sYEqh%R5dj&!`k^@C-x<(Mt^{ zQgu9hNSB*Z`@Daix8szyFhvK>{IxBzl%dba)jkR^I#Q0)n~?7a=8=EcwruF%7=ZWL zaXx}A;xoR^DYgtHK|{A|FZSrn@zc>)X-d%)E-oEkA(R~rolqx#a*`?Y&U05{x@B0+ zOYD_YeOs!DTYC9VD|rfX@(=E-!?A=DCt^_#&2_q^uUg6SDV*cHsG5A{eQCN?@;%;) znNKB6sbSc`G_BWcyVzf*z8>8D;cvSNg0qADRVc~T`bADXgMMc_T$<~XzJFIOSvqs_ zkYw=T*Eu=d?0wR_A2`l)N=HIun|--2W(Js+_7tyqh)sDsJX-DZ{H@^_?vOQ{_|4qc z%hyAS%{8H;f~@Er!haUxW^l}6-~WsMw}BIgeUoZbjJt8*=lzUnDpNm*B6|)S!Y(V5W zAlEQwpK!3vb4VqLAA#OxP7f6w5kAs>R#%@bYVH|wbwH&rkriSHbkmjT7LXhXQM%vB z2b&!?N@r593U4Gm{+h$*E~-XyYTUP+v?#$gc%GoO+K^(@{(Tpbeq>o3z1<1ugF5$| z#e^iYuOJjGAi2qhe|469n5VH1OW2`ZRkcr>lH9jqofpt?duy4%t7n-5z5I&; zoFb^Yfb(8o=-mU%r8aBkDfXc&(T_s7(xP4*_$gt2{KR@kyY%zkLb$sSa^b2L(5n=8 zTNr{weM$Smi<=XEquAIj;**^q|A042+6_}KdDCfg5Wyg!J0szA_sk3T-!1W~q;P5u zeew(CmV8TD(3RMWLTaBvU>v^&_JmWfoDB_FlC%q)dik4(=zMnR(DJcM%c7X&3*wM1 znfB{Vho3k8x;l7BSh`}L#1%g=Iq^WhFN+V>4}YyDrKnSqBHt!8aE%3hy--0n6kZmE zzIn%bQF!D@;jxmHLVbwD`9mGuY<_YVu@Y>@^NK}a7WN0kAOCuGq3<}&XfIwp;3X~Z z=c9REE%ry8y=~zTfw_?Dyw7_O^IWWB`9}f`U2X&1QH{6f*XrJU| zo=yo5wSXMl!zk~2^!>;~5fhHVLpwPsXOR-^OGYQ=rfTlz$ZGR)Xs(#SQg+yN+tO#} zc_aUwJ=@%Ta}}aV5!vZI&g&P0)Hq7q*@rk{wTASgk~Rjz+oyX%F)wK=p_)qp>>o8(LNtf2xuxhtMFw;TlRt1I zux$?K_viUzvI_#{e2%?);I^REA>21~gOoqeCw1nFz=Nc`ef#Qjk{$}rr}Y?w9z3>h zvG-D@?xEv+x8f*>V1LkXEY53m;0WhiQHA0+&-_!aO8@>I*e9&Zap*fmZRw^31e?p} zLlJ+r?+y}@65$BF{qRbN^a%Q%@masHz>dL?#k|HPZE?!jApU47!%JSja z=`E3M;qTv%j^(|S2uNExW&t@6C~wAg<6NZ48L->$?N5bX^i$9IEtSfiZxnfUdXf8> z#1urr!B6}Cy7*@5zKX2`U`V3nMRYQ`dLgO%`sR=?`uiABdMul%9Vc=DR;mvHt9^UT(C0}D z@f3TM=z&P_pSs4R+m9qmKMr2#qvY(4B=0v{XvWSzf>aTY`TUWS&f_?j^>gVpFO+fk z0`Db_YtNGNn2~Ih1NZl(UXYsReJtmyYa^b2fX$EdU6hwaWs`-%%aSFd!m zFL$iAOS|Qe{QLHOxi8WVr?Of3sC@m04Y@miYQ=xss}+1ah&9f0&tOvYN6-6MG->}{ zosd4=3&)gWzxUXrAHSc($0-7O*FLh#CGq+93d~-=AP!?n{h}m)|IH|m448~GJJ+lC zI)#j(8~*4c4IdD9)o(P8^u&>x}h z+z%q^deZ7E5@> zN_vFwzTn`Xc>vRw&X%_p!2cWaxI+qiDd!)yK;Fkx#&06?amExu7(RcWJ5N`0$w*lwUeh@K zr-%0*TUc%ZgRuX3ppYD_brq8(64?vUI!dEUs(jhn0D_3ZOFSK7do+n&{C0kyT#BJY zb(ZfIzfaF}Tu-oYQLpev;keLw_P&lC3`a}zDfU=VcF9LolFRBwzu9E3gbCgbl>36K z+h4G+P_vg=)%3tGAnEdl-8~39eEa5Ki=&VEppA8^n$sxOJQBE?@=#}Yq$s7Z{iws$ zu=ln@M;`F{%WO~2OK5&OHKd>R|1I{d2;&L;_SD^4)BC@9^RZkDyJWa?f55?M+PAmf z(tR7z7gxs6&=7`I3m8^00KtLffex%9 xqj)q7M$^D(8W>FjqiJ9?4UDFN(KIlc21e7sXc`zz1EXnRG!4)y4aon$2>?)}sf+*s literal 0 HcmV?d00001 diff --git a/ports/esp32/docs/board-photos/Olimex-ESP32-POE.jpg b/ports/esp32/docs/board-photos/Olimex-ESP32-POE.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91485b422151029c8b383cc973a972df339394ad GIT binary patch literal 10032 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 literal 0 HcmV?d00001 diff --git a/ports/esp32/extra_script.py b/ports/esp32/extra_script.py new file mode 100644 index 00000000..f7fa5899 --- /dev/null +++ b/ports/esp32/extra_script.py @@ -0,0 +1,120 @@ +# @file +# @brief Build-time BACnet source wiring for PlatformIO environments +# @author Kato Gangstad + +Import("env") + +from pathlib import Path + +PIOENV = env.get("PIOENV", "") +if PIOENV not in ( + "m5stamplc-mstp", + "m5stamplc-bip", + "esp32-poe-wifi-bip", + "esp32-poe-eth-bip", + "xiao-esp32c3-wifi-bip", + "m5stamplc-gateway-bip-mstp", +): + Return() + +project_dir = Path(env.subst("$PROJECT_DIR")).resolve() +bacnet_src_root = (project_dir / ".." / ".." / "src").resolve() + +bacnet_common_sources = [ + "bacnet/basic/binding/address.c", + "bacnet/basic/server/bacnet_device.c", + "bacnet/basic/object/ai.c", + "bacnet/basic/object/bi.c", + "bacnet/basic/object/bo.c", + "bacnet/basic/npdu/h_npdu.c", + "bacnet/basic/service/h_apdu.c", + "bacnet/basic/service/h_dcc.c", + "bacnet/basic/service/h_noserv.c", + "bacnet/basic/service/h_rd.c", + "bacnet/basic/service/h_rp.c", + "bacnet/basic/service/h_rpm.c", + "bacnet/basic/service/h_whohas.c", + "bacnet/basic/service/h_whois.c", + "bacnet/basic/service/h_wp.c", + "bacnet/basic/service/s_iam.c", + "bacnet/basic/service/s_ihave.c", + "bacnet/basic/sys/datetime_mstimer.c", + "bacnet/basic/sys/days.c", + "bacnet/basic/sys/dst.c", + "bacnet/basic/sys/debug.c", + "bacnet/basic/sys/ringbuf.c", + "bacnet/basic/sys/fifo.c", + "bacnet/basic/sys/mstimer.c", + "bacnet/basic/tsm/tsm.c", + "bacnet/abort.c", + "bacnet/bacaction.c", + "bacnet/bacaddr.c", + "bacnet/bacapp.c", + "bacnet/bacdcode.c", + "bacnet/bacdest.c", + "bacnet/bacdevobjpropref.c", + "bacnet/bacerror.c", + "bacnet/bacint.c", + "bacnet/bacreal.c", + "bacnet/bacstr.c", + "bacnet/datetime.c", + "bacnet/dcc.c", + "bacnet/hostnport.c", + "bacnet/iam.c", + "bacnet/ihave.c", + "bacnet/indtext.c", + "bacnet/memcopy.c", + "bacnet/npdu.c", + "bacnet/proplist.c", + "bacnet/rd.c", + "bacnet/reject.c", + "bacnet/rp.c", + "bacnet/rpm.c", + "bacnet/timestamp.c", + "bacnet/whohas.c", + "bacnet/whois.c", + "bacnet/wp.c", + "bacnet/cov.c", + "bacnet/basic/sys/keylist.c", +] + +bacnet_transport_sources = { + "m5stamplc-mstp": [ + "bacnet/datalink/cobs.c", + "bacnet/datalink/crc.c", + "bacnet/datalink/dlmstp.c", + "bacnet/datalink/mstp.c", + "bacnet/datalink/mstptext.c", + ], + "m5stamplc-bip": [ + "bacnet/datalink/bvlc.c", + ], + "esp32-poe-wifi-bip": [ + "bacnet/datalink/bvlc.c", + ], + "esp32-poe-eth-bip": [ + "bacnet/datalink/bvlc.c", + ], + "xiao-esp32c3-wifi-bip": [ + "bacnet/datalink/bvlc.c", + ], + "m5stamplc-gateway-bip-mstp": [ + "bacnet/datalink/bvlc.c", + "bacnet/datalink/cobs.c", + "bacnet/datalink/crc.c", + "bacnet/datalink/dlmstp.c", + "bacnet/datalink/mstp.c", + "bacnet/datalink/mstptext.c", + ], +} + +bacnet_sources = bacnet_common_sources + bacnet_transport_sources.get(PIOENV, []) + +env.Append(CPPPATH=[str(project_dir / "src"), str(bacnet_src_root)]) + +for rel in bacnet_sources: + env.BuildSources( + str(Path("$BUILD_DIR") / "bacnet"), + str(bacnet_src_root), + src_filter=f"+<{rel}>", + ) diff --git a/ports/esp32/lib/readme.txt b/ports/esp32/lib/readme.txt deleted file mode 100644 index dbadc3d6..00000000 --- a/ports/esp32/lib/readme.txt +++ /dev/null @@ -1,36 +0,0 @@ - -This directory is intended for the project specific (private) libraries. -PlatformIO will compile them to static libraries and link to executable file. - -The source code of each library should be placed in separate directory, like -"lib/private_lib/[here are source files]". - -For example, see how can be organized `Foo` and `Bar` libraries: - -|--lib -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| |--Foo -| | |- Foo.c -| | |- Foo.h -| |- readme.txt --> THIS FILE -|- platformio.ini -|--src - |- main.c - -Then in `src/main.c` you should use: - -#include -#include - -// rest H/C/CPP code - -PlatformIO will find your libraries automatically, configure preprocessor's -include paths and build them. - -More information about PlatformIO Library Dependency Finder -- http://docs.platformio.org/page/librarymanager/ldf.html diff --git a/ports/esp32/platformio.ini b/ports/esp32/platformio.ini index a150fc69..71b39297 100644 --- a/ports/esp32/platformio.ini +++ b/ports/esp32/platformio.ini @@ -6,14 +6,155 @@ ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples -; http://docs.platformio.org/page/projectconf.html +; https://docs.platformio.org/page/projectconf.html -[env:esp32thing] +[platformio] +default_envs = m5stamplc-mstp + +[wifi_common] +build_flags = + -DWIFI_SSID=\"REPLACE_WITH_WIFI_SSID\" + -DWIFI_PASS=\"REPLACE_WITH_WIFI_PASSWORD\" + +[bip_common] +build_flags = + -UBACDL_MSTP + -DBACDL_BIP + -DBACNET_IP_PORT=47808 + -DMAX_APDU=1476 + +[env] platform = espressif32 -board = esp32thing -framework = espidf +framework = arduino +monitor_speed = 115200 +upload_speed = 921600 +extra_scripts = pre:extra_script.py +lib_deps = + m5stack/M5StamPLC@^1.2.0 +build_unflags = + -std=gnu++11 +build_flags = + -std=gnu11 + -std=gnu++17 + -I src + -I ../../src + -DBACDL_MSTP + -DMAX_TSM_TRANSACTIONS=1 + -DPRINT_ENABLED=0 + -DBACNET_BIG_ENDIAN=0 + -DCRC_USE_TABLE + -DBACAPP_MINIMAL + -DBACAPP_TIMESTAMP + -DBACNET_STACK_DEPRECATED_DISABLE + -DBACNET_PROTOCOL_REVISION=16 + -DCONFIG_BACNET_BASIC_OBJECT_ANALOG_INPUT + -DCONFIG_BACNET_BASIC_OBJECT_BINARY_INPUT + -DCONFIG_BACNET_BASIC_OBJECT_BINARY_OUTPUT -upload_port = COM7 -upload_speed = 1152000 +[env:m5stamplc-mstp] +board = m5stamplc +build_flags = + ${env.build_flags} + -DMAX_APDU=480 +build_src_filter = + + + + + + + + + + +lib_deps = m5stack/M5StamPLC@^1.2.0 -monitor_baud = 115200 +[env:m5stamplc-bip] +board = m5stamplc +build_flags = + ${env.build_flags} + ${bip_common.build_flags} + ${wifi_common.build_flags} + -DUSE_M5STAMPLC_IO=1 +build_src_filter = + + + + + + + + + + + + + + +lib_deps = m5stack/M5StamPLC@^1.2.0 + +[env:esp32-poe-wifi-bip] +board = esp32-poe +build_flags = + ${env.build_flags} + ${bip_common.build_flags} + ${wifi_common.build_flags} + -DUSE_M5STAMPLC_IO=0 + -DUSE_ETH_INTERFACE=0 +build_src_filter = + + + + + + + + + + + + + + +lib_deps = + +[env:esp32-poe-eth-bip] +board = esp32-poe +build_flags = + ${env.build_flags} + ${bip_common.build_flags} + -DUSE_M5STAMPLC_IO=0 + -DUSE_ETH_INTERFACE=1 +build_src_filter = + + + + + + + + + + + + + + +lib_deps = + +[env:xiao-esp32c3-wifi-bip] +board = seeed_xiao_esp32c3 +build_flags = + ${env.build_flags} + ${bip_common.build_flags} + ${wifi_common.build_flags} + -DUSE_M5STAMPLC_IO=0 + -DUSE_ETH_INTERFACE=0 +build_src_filter = + + + + + + + + + + + + + + +lib_deps = + +[env:m5stamplc-gateway-bip-mstp] +board = m5stamplc +build_flags = + ${env.build_flags} + ${wifi_common.build_flags} + -DMAX_APDU=480 + -UBACDL_MSTP + -DBACDL_MSTP + -DBACDL_BIP + -DBACNET_IP_PORT=47808 + -DROUTER_BIP_NET=1 + -DROUTER_MSTP_NET=200 + -DROUTER_MSTP_MAC=2 +build_src_filter = + + + + + + + + + + + + + + + + + + +lib_deps = m5stack/M5StamPLC@^1.2.0 diff --git a/ports/esp32/readme.txt b/ports/esp32/readme.txt deleted file mode 100644 index 1ecce0f1..00000000 --- a/ports/esp32/readme.txt +++ /dev/null @@ -1,67 +0,0 @@ -Bacnet Server for Espressif ESP32 - Steve Karg Bacnet stack using PlatformIO open source ecosystem for IoT development on VSCode or Atom - F. Chaxel 2017 - -TODO list : - -(Install VSCode or Atom and add the PlatformIO extension) - -Edit platformio.ini to adjust board, Com Port, ... - -Goto lib/stack and copy the requested files from Steve code : - - all .h from include directory (not all required by it's simple) - - these .c files from src or demo/handlers - abort.c - address.c - apdu.c - bacaddr.c - bacapp.c - bacdcode.c - bacerror.c - bacint.c - bacreal.c - bacstr.c - bip.c - bvlc.c - cov.c - datetime.c - bacdevobjpropref.c - dcc.c - debug.c - h_cov.c - h_ucov.c - h_npdu.c - h_rp.c - h_rpm.c - h_whois.c - h_wp.c - iam.c - hostnport.c - lighting.c - memcopy.c - noserv.c - npdu.c - proplist.c - reject.c - rp.c - rpm.c - s_iam.c - tsm.c - whois.c - wp.c - -Modify - in config.h - MAX_TSM_TRANSACTIONS 255, set the value to 10 for instances - in main.c - wifi_config to fit your wifi network - BACNET_LED 5, set another IO number depending of your board - -A lot of Warning will be issued at compile time due to the redefinition of BIT macros. -Could be removes by placing a #ifndef #BIT0 .. #endif arround the BIT macro in bits.h, -and moving to the top of include list - #include "bacnet/datalink/datalink.h" in tsm.c, s_iam and in device.c - #include "bacport.h" in bip.c and in bip.h (redondant include in bip.c) - #include "bacnet/datalink/bvlc.h" in bvlc.c diff --git a/ports/esp32/src/.clang-format b/ports/esp32/src/.clang-format deleted file mode 100644 index 579a192a..00000000 --- a/ports/esp32/src/.clang-format +++ /dev/null @@ -1,7 +0,0 @@ ---- -# Disable formatting for now as there is external code. We should move external -# code to a separate directory and enable formatting for our code. -DisableFormat: true - -# DisableFormat will not disable include sorting with some versions. -SortIncludes: Never diff --git a/ports/esp32/src/ai.c b/ports/esp32/src/ai.c deleted file mode 100644 index 8e28fcf9..00000000 --- a/ports/esp32/src/ai.c +++ /dev/null @@ -1,1294 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2005 Steve Karg - * Copyright (C) 2011 Krzysztof Malorny - * - * SPDX-License-Identifier: MIT - * - *********************************************************************/ - -/* Analog Input Objects customize for your use */ - -#include -#include -#include - -#include "bacnet/bacdef.h" -#include "bacnet/bacdcode.h" -#include "bacnet/bacenum.h" -#include "bacnet/bactext.h" -#include "bacnet/config.h" /* the custom stuff */ -#include "bacnet/basic/object/device.h" -#include "bacnet/basic/services.h" -#include "bacnet/proplist.h" -#include "bacnet/timestamp.h" -#include "bacnet/basic/object/ai.h" - -#ifndef MAX_ANALOG_INPUTS -#define MAX_ANALOG_INPUTS 2 -#endif - -ANALOG_INPUT_DESCR AI_Descr[MAX_ANALOG_INPUTS]; - -/* These three arrays are used by the ReadPropertyMultiple handler */ -static const int32_t Properties_Required[] = { PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, - PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 }; - -static const int32_t Properties_Optional[] = { PROP_DESCRIPTION, PROP_RELIABILITY, - PROP_COV_INCREMENT, -#if defined(INTRINSIC_REPORTING) - PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, PROP_HIGH_LIMIT, PROP_LOW_LIMIT, - PROP_DEADBAND, PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS, - PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS, -#endif - -1 }; - -static const int32_t Properties_Proprietary[] = { 9997, 9998, 9999, -1 }; - -void Analog_Input_Property_Lists( - const int32_t **pRequired, const int32_t **pOptional, const int32_t **pProprietary) -{ - if (pRequired) - *pRequired = Properties_Required; - if (pOptional) - *pOptional = Properties_Optional; - if (pProprietary) - *pProprietary = Properties_Proprietary; - - return; -} - -void Analog_Input_Init(void) -{ - unsigned i; -#if defined(INTRINSIC_REPORTING) - unsigned j; -#endif - - for (i = 0; i < MAX_ANALOG_INPUTS; i++) { - AI_Descr[i].Present_Value = 0.0f; - AI_Descr[i].Out_Of_Service = false; - AI_Descr[i].Units = UNITS_PERCENT; - AI_Descr[i].Reliability = RELIABILITY_NO_FAULT_DETECTED; - AI_Descr[i].Prior_Value = 0.0f; - AI_Descr[i].COV_Increment = 1.0f; - AI_Descr[i].Changed = false; -#if defined(INTRINSIC_REPORTING) - AI_Descr[i].Event_State = EVENT_STATE_NORMAL; - /* notification class not connected */ - AI_Descr[i].Notification_Class = BACNET_MAX_INSTANCE; - /* initialize Event time stamps using wildcards - and set Acked_transitions */ - for (j = 0; j < MAX_BACNET_EVENT_TRANSITION; j++) { - datetime_wildcard_set(&AI_Descr[i].Event_Time_Stamps[j]); - AI_Descr[i].Acked_Transitions[j].bIsAcked = true; - } - - /* Set handler for GetEventInformation function */ - handler_get_event_information_set( - OBJECT_ANALOG_INPUT, Analog_Input_Event_Information); - /* Set handler for AcknowledgeAlarm function */ - handler_alarm_ack_set(OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Ack); - /* Set handler for GetAlarmSummary Service */ - handler_get_alarm_summary_set( - OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Summary); -#endif - } -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need validate that the */ -/* given instance exists */ -bool Analog_Input_Valid_Instance(uint32_t object_instance) -{ - unsigned int index; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) - return true; - - return false; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then count how many you have */ -unsigned Analog_Input_Count(void) -{ - return MAX_ANALOG_INPUTS; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need to return the instance */ -/* that correlates to the correct index */ -uint32_t Analog_Input_Index_To_Instance(unsigned index) -{ - return index; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need to return the index */ -/* that correlates to the correct instance number */ -unsigned Analog_Input_Instance_To_Index(uint32_t object_instance) -{ - unsigned index = MAX_ANALOG_INPUTS; - - if (object_instance < MAX_ANALOG_INPUTS) - index = object_instance; - - return index; -} - -float Analog_Input_Present_Value(uint32_t object_instance) -{ - float value = 0.0; - unsigned int index; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - value = AI_Descr[index].Present_Value; - } - - return value; -} - -static void Analog_Input_COV_Detect(unsigned int index, float value) -{ - float prior_value = 0.0; - float cov_increment = 0.0; - float cov_delta = 0.0; - - if (index < MAX_ANALOG_INPUTS) { - prior_value = AI_Descr[index].Prior_Value; - cov_increment = AI_Descr[index].COV_Increment; - if (prior_value > value) { - cov_delta = prior_value - value; - } else { - cov_delta = value - prior_value; - } - if (cov_delta >= cov_increment) { - AI_Descr[index].Changed = true; - AI_Descr[index].Prior_Value = value; - } - } -} - -void Analog_Input_Present_Value_Set(uint32_t object_instance, float value) -{ - unsigned int index = 0; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - Analog_Input_COV_Detect(index, value); - AI_Descr[index].Present_Value = value; - } -} - -bool Analog_Input_Object_Name( - uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) -{ - static char text[32] = ""; - unsigned int index; - bool status = false; - - if (object_instance == 0) - status = characterstring_init_ansi(object_name, "Internal Temperature"); - else if (object_instance == 1) - status = characterstring_init_ansi(object_name, "Magnetic field"); - else { - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - snprintf(text, sizeof(text), "ANALOG INPUT %lu", (unsigned long)index); - status = characterstring_init_ansi(object_name, text); - } - } - return status; -} - -bool Analog_Input_Change_Of_Value(uint32_t object_instance) -{ - unsigned index = 0; - bool changed = false; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - changed = AI_Descr[index].Changed; - } - - return changed; -} - -void Analog_Input_Change_Of_Value_Clear(uint32_t object_instance) -{ - unsigned index = 0; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - AI_Descr[index].Changed = false; - } -} - -/** - * For a given object instance-number, loads the value_list with the COV data. - * - * @param object_instance - object-instance number of the object - * @param value_list - list of COV data - * - * @return true if the value list is encoded - */ -bool Analog_Input_Encode_Value_List( - uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list) -{ - bool status = false; - - if (value_list) { - value_list->propertyIdentifier = PROP_PRESENT_VALUE; - value_list->propertyArrayIndex = BACNET_ARRAY_ALL; - value_list->value.context_specific = false; - value_list->value.tag = BACNET_APPLICATION_TAG_REAL; - value_list->value.type.Real = - Analog_Input_Present_Value(object_instance); - value_list->value.next = NULL; - value_list->priority = BACNET_NO_PRIORITY; - value_list = value_list->next; - } - if (value_list) { - value_list->propertyIdentifier = PROP_STATUS_FLAGS; - value_list->propertyArrayIndex = BACNET_ARRAY_ALL; - value_list->value.context_specific = false; - value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; - bitstring_init(&value_list->value.type.Bit_String); - bitstring_set_bit( - &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit( - &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, false); - bitstring_set_bit( - &value_list->value.type.Bit_String, STATUS_FLAG_OVERRIDDEN, false); - if (Analog_Input_Out_Of_Service(object_instance)) { - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, true); - } else { - bitstring_set_bit(&value_list->value.type.Bit_String, - STATUS_FLAG_OUT_OF_SERVICE, false); - } - value_list->value.next = NULL; - value_list->priority = BACNET_NO_PRIORITY; - value_list->next = NULL; - status = true; - } - - return status; -} - -float Analog_Input_COV_Increment(uint32_t object_instance) -{ - unsigned index = 0; - float value = 0; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - value = AI_Descr[index].COV_Increment; - } - - return value; -} - -void Analog_Input_COV_Increment_Set(uint32_t object_instance, float value) -{ - unsigned index = 0; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - AI_Descr[index].COV_Increment = value; - Analog_Input_COV_Detect(index, AI_Descr[index].Present_Value); - } -} - -bool Analog_Input_Out_Of_Service(uint32_t object_instance) -{ - unsigned index = 0; - bool value = false; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - value = AI_Descr[index].Out_Of_Service; - } - - return value; -} - -void Analog_Input_Out_Of_Service_Set(uint32_t object_instance, bool value) -{ - unsigned index = 0; - - index = Analog_Input_Instance_To_Index(object_instance); - if (index < MAX_ANALOG_INPUTS) { - /* BACnet Testing Observed Incident oi00104 - The Changed flag was not being set when a client wrote to the - Out-of-Service bit. Revealed by BACnet Test Client v1.8.16 ( - www.bac-test.com/bacnet-test-client-download ) BC 135.1: 8.2.1-A BC - 135.1: 8.2.2-A Any discussions can be directed to edward@bac-test.com - Please feel free to remove this comment when my changes accepted after - suitable time for review by all interested parties. Say 6 months -> - September 2016 */ - if (AI_Descr[index].Out_Of_Service != value) { - AI_Descr[index].Changed = true; - } - AI_Descr[index].Out_Of_Service = value; - } -} - -/* return apdu length, or BACNET_STATUS_ERROR on error */ -/* assumption - object already exists */ -int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) -{ - int apdu_len = 0; /* return value */ - BACNET_BIT_STRING bit_string; - BACNET_CHARACTER_STRING char_string; - ANALOG_INPUT_DESCR *CurrentAI; - unsigned object_index = 0; -#if defined(INTRINSIC_REPORTING) - unsigned i = 0; - int len = 0; -#endif - uint8_t *apdu = NULL; - - if ((rpdata == NULL) || (rpdata->application_data == NULL) || - (rpdata->application_data_len == 0)) { - return 0; - } - - object_index = Analog_Input_Instance_To_Index(rpdata->object_instance); - if (object_index < MAX_ANALOG_INPUTS) - CurrentAI = &AI_Descr[object_index]; - else - return BACNET_STATUS_ERROR; - - apdu = rpdata->application_data; - switch ((int)rpdata->object_property) { - case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id( - &apdu[0], OBJECT_ANALOG_INPUT, rpdata->object_instance); - break; - - case PROP_OBJECT_NAME: - case PROP_DESCRIPTION: - Analog_Input_Object_Name(rpdata->object_instance, &char_string); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - - case PROP_OBJECT_TYPE: - apdu_len = - encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); - break; - - case PROP_PRESENT_VALUE: - apdu_len = encode_application_real( - &apdu[0], Analog_Input_Present_Value(rpdata->object_instance)); - break; - - case PROP_STATUS_FLAGS: - bitstring_init(&bit_string); -#if defined(INTRINSIC_REPORTING) - bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, - CurrentAI->Event_State ? true : false); -#else - bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); -#endif - bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, - CurrentAI->Out_Of_Service); - - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - - case PROP_EVENT_STATE: -#if defined(INTRINSIC_REPORTING) - apdu_len = - encode_application_enumerated(&apdu[0], CurrentAI->Event_State); -#else - apdu_len = - encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); -#endif - break; - - case PROP_RELIABILITY: - apdu_len = - encode_application_enumerated(&apdu[0], CurrentAI->Reliability); - break; - - case PROP_OUT_OF_SERVICE: - apdu_len = - encode_application_boolean(&apdu[0], CurrentAI->Out_Of_Service); - break; - - case PROP_UNITS: - apdu_len = - encode_application_enumerated(&apdu[0], CurrentAI->Units); - break; - - case PROP_COV_INCREMENT: - apdu_len = - encode_application_real(&apdu[0], CurrentAI->COV_Increment); - break; - -#if defined(INTRINSIC_REPORTING) - case PROP_TIME_DELAY: - apdu_len = - encode_application_unsigned(&apdu[0], CurrentAI->Time_Delay); - break; - - case PROP_NOTIFICATION_CLASS: - apdu_len = encode_application_unsigned( - &apdu[0], CurrentAI->Notification_Class); - break; - - case PROP_HIGH_LIMIT: - apdu_len = encode_application_real(&apdu[0], CurrentAI->High_Limit); - break; - - case PROP_LOW_LIMIT: - apdu_len = encode_application_real(&apdu[0], CurrentAI->Low_Limit); - break; - - case PROP_DEADBAND: - apdu_len = encode_application_real(&apdu[0], CurrentAI->Deadband); - break; - - case PROP_LIMIT_ENABLE: - bitstring_init(&bit_string); - bitstring_set_bit(&bit_string, 0, - (CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true - : false); - bitstring_set_bit(&bit_string, 1, - (CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true - : false); - - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - - case PROP_EVENT_ENABLE: - bitstring_init(&bit_string); - bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, - (CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true - : false); - bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, - (CurrentAI->Event_Enable & EVENT_ENABLE_TO_FAULT) ? true - : false); - bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, - (CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true - : false); - - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - - case PROP_ACKED_TRANSITIONS: - bitstring_init(&bit_string); - bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, - CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked); - bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, - CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); - bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, - CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); - - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - - case PROP_NOTIFY_TYPE: - apdu_len = encode_application_enumerated( - &apdu[0], CurrentAI->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM); - break; - - case PROP_EVENT_TIME_STAMPS: - /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) - apdu_len = encode_application_unsigned( - &apdu[0], MAX_BACNET_EVENT_TRANSITION); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { - for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) { - len = encode_opening_tag( - &apdu[apdu_len], TIME_STAMP_DATETIME); - len += encode_application_date(&apdu[apdu_len + len], - &CurrentAI->Event_Time_Stamps[i].date); - len += encode_application_time(&apdu[apdu_len + len], - &CurrentAI->Event_Time_Stamps[i].time); - len += encode_closing_tag( - &apdu[apdu_len + len], TIME_STAMP_DATETIME); - - /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) - apdu_len += len; - else { - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - break; - } - } - } else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) { - apdu_len = - encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); - apdu_len += encode_application_date(&apdu[apdu_len], - &CurrentAI->Event_Time_Stamps[rpdata->array_index].date); - apdu_len += encode_application_time(&apdu[apdu_len], - &CurrentAI->Event_Time_Stamps[rpdata->array_index].time); - apdu_len += - encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); - } else { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; - apdu_len = BACNET_STATUS_ERROR; - } - break; -#endif - case 9997: - /* test case for real encoding-decoding real value correctly */ - apdu_len = encode_application_real(&apdu[0], 90.510F); - break; - case 9998: - /* test case for unsigned encoding-decoding unsigned value correctly - */ - apdu_len = encode_application_unsigned(&apdu[0], 90); - break; - case 9999: - /* test case for signed encoding-decoding negative value correctly - */ - apdu_len = encode_application_signed(&apdu[0], -200); - break; - default: - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = BACNET_STATUS_ERROR; - break; - } - /* only array properties can have array options */ - if ((apdu_len >= 0) && - (rpdata->object_property != PROP_EVENT_TIME_STAMPS) && - (rpdata->array_index != BACNET_ARRAY_ALL)) { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - apdu_len = BACNET_STATUS_ERROR; - } - - return apdu_len; -} - -/* returns true if successful */ -bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) -{ - bool status = false; /* return value */ - unsigned int object_index = 0; - int len = 0; - BACNET_APPLICATION_DATA_VALUE value = { 0 }; - ANALOG_INPUT_DESCR *CurrentAI; - - /* decode the some of the request */ - len = bacapp_decode_application_data( - wp_data->application_data, wp_data->application_data_len, &value); - /* FIXME: len < application_data_len: more data? */ - if (len < 0) { - /* error while decoding - a value larger than we can handle */ - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - return false; - } - /* only array properties can have array options */ - if ((wp_data->object_property != PROP_EVENT_TIME_STAMPS) && - (wp_data->array_index != BACNET_ARRAY_ALL)) { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - return false; - } - object_index = Analog_Input_Instance_To_Index(wp_data->object_instance); - if (object_index < MAX_ANALOG_INPUTS) { - CurrentAI = &AI_Descr[object_index]; - } else { - return false; - } - - switch ((int)wp_data->object_property) { - case PROP_PRESENT_VALUE: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_REAL); - if (status) { - if (CurrentAI->Out_Of_Service == true) { - Analog_Input_Present_Value_Set( - wp_data->object_instance, value.type.Real); - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - status = false; - } - } - break; - - case PROP_OUT_OF_SERVICE: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_BOOLEAN); - if (status) { - Analog_Input_Out_Of_Service_Set( - wp_data->object_instance, value.type.Boolean); - } - break; - - case PROP_UNITS: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_ENUMERATED); - if (status) { - CurrentAI->Units = value.type.Enumerated; - } - break; - - case PROP_COV_INCREMENT: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_REAL); - if (status) { - if (value.type.Real >= 0.0) { - Analog_Input_COV_Increment_Set( - wp_data->object_instance, value.type.Real); - } else { - status = false; - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - break; - -#if defined(INTRINSIC_REPORTING) - case PROP_TIME_DELAY: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - CurrentAI->Time_Delay = value.type.Unsigned_Int; - CurrentAI->Remaining_Time_Delay = CurrentAI->Time_Delay; - } - break; - - case PROP_NOTIFICATION_CLASS: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - CurrentAI->Notification_Class = value.type.Unsigned_Int; - } - break; - - case PROP_HIGH_LIMIT: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_REAL); - if (status) { - CurrentAI->High_Limit = value.type.Real; - } - break; - - case PROP_LOW_LIMIT: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_REAL); - if (status) { - CurrentAI->Low_Limit = value.type.Real; - } - break; - - case PROP_DEADBAND: - status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL, - &wp_data->error_class, &wp_data->error_code); - if (status) { - CurrentAI->Deadband = value.type.Real; - } - break; - - case PROP_LIMIT_ENABLE: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_BIT_STRING); - if (status) { - if (value.type.Bit_String.bits_used == 2) { - CurrentAI->Limit_Enable = value.type.Bit_String.value[0]; - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - status = false; - } - } - break; - - case PROP_EVENT_ENABLE: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_BIT_STRING); - if (status) { - if (value.type.Bit_String.bits_used == 3) { - CurrentAI->Event_Enable = value.type.Bit_String.value[0]; - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - status = false; - } - } - break; - - case PROP_NOTIFY_TYPE: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_ENUMERATED); - if (status) { - switch ((BACNET_NOTIFY_TYPE)value.type.Enumerated) { - case NOTIFY_EVENT: - CurrentAI->Notify_Type = 1; - break; - case NOTIFY_ALARM: - CurrentAI->Notify_Type = 0; - break; - default: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - status = false; - break; - } - } - break; -#endif - case PROP_OBJECT_IDENTIFIER: - case PROP_OBJECT_NAME: - case PROP_OBJECT_TYPE: - case PROP_STATUS_FLAGS: - case PROP_EVENT_STATE: - case PROP_DESCRIPTION: - case PROP_RELIABILITY: -#if defined(INTRINSIC_REPORTING) - case PROP_ACKED_TRANSITIONS: - case PROP_EVENT_TIME_STAMPS: -#endif - case 9997: - case 9998: - case 9999: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - break; - default: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - break; - } - - return status; -} - -void Analog_Input_Intrinsic_Reporting(uint32_t object_instance) -{ -#if defined(INTRINSIC_REPORTING) - BACNET_EVENT_NOTIFICATION_DATA event_data; - BACNET_CHARACTER_STRING msgText; - ANALOG_INPUT_DESCR *CurrentAI; - unsigned int object_index; - uint8_t FromState = 0; - uint8_t ToState; - float ExceededLimit = 0.0f; - float PresentVal = 0.0f; - bool SendNotify = false; - - object_index = Analog_Input_Instance_To_Index(object_instance); - if (object_index < MAX_ANALOG_INPUTS) - CurrentAI = &AI_Descr[object_index]; - else - return; - - /* check limits */ - if (!CurrentAI->Limit_Enable) - return; /* limits are not configured */ - - if (CurrentAI->Ack_notify_data.bSendAckNotify) { - /* clean bSendAckNotify flag */ - CurrentAI->Ack_notify_data.bSendAckNotify = false; - /* copy toState */ - ToState = CurrentAI->Ack_notify_data.EventState; - -#if PRINT_ENABLED - fprintf(stderr, "Send Acknotification for (%s,%d).\n", - bactext_object_type_name(OBJECT_ANALOG_INPUT), object_instance); -#endif /* PRINT_ENABLED */ - - characterstring_init_ansi(&msgText, "AckNotification"); - - /* Notify Type */ - event_data.notifyType = NOTIFY_ACK_NOTIFICATION; - - /* Send EventNotification. */ - SendNotify = true; - } else { - /* actual Present_Value */ - PresentVal = Analog_Input_Present_Value(object_instance); - FromState = CurrentAI->Event_State; - switch (CurrentAI->Event_State) { - case EVENT_STATE_NORMAL: - /* A TO-OFFNORMAL event is generated under these conditions: - (a) the Present_Value must exceed the High_Limit for a - minimum period of time, specified in the Time_Delay property, - and (b) the HighLimitEnable flag must be set in the - Limit_Enable property, and - (c) the TO-OFFNORMAL flag must be set in the Event_Enable - property. */ - if ((PresentVal > CurrentAI->High_Limit) && - ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == - EVENT_HIGH_LIMIT_ENABLE) && - ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) == - EVENT_ENABLE_TO_OFFNORMAL)) { - if (!CurrentAI->Remaining_Time_Delay) - CurrentAI->Event_State = EVENT_STATE_HIGH_LIMIT; - else - CurrentAI->Remaining_Time_Delay--; - break; - } - - /* A TO-OFFNORMAL event is generated under these conditions: - (a) the Present_Value must exceed the Low_Limit plus the - Deadband for a minimum period of time, specified in the - Time_Delay property, and (b) the LowLimitEnable flag must be - set in the Limit_Enable property, and - (c) the TO-NORMAL flag must be set in the Event_Enable - property. */ - if ((PresentVal < CurrentAI->Low_Limit) && - ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == - EVENT_LOW_LIMIT_ENABLE) && - ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) == - EVENT_ENABLE_TO_OFFNORMAL)) { - if (!CurrentAI->Remaining_Time_Delay) - CurrentAI->Event_State = EVENT_STATE_LOW_LIMIT; - else - CurrentAI->Remaining_Time_Delay--; - break; - } - /* value of the object is still in the same event state */ - CurrentAI->Remaining_Time_Delay = CurrentAI->Time_Delay; - break; - - case EVENT_STATE_HIGH_LIMIT: - /* Once exceeded, the Present_Value must fall below the - High_Limit minus the Deadband before a TO-NORMAL event is - generated under these conditions: (a) the Present_Value must - fall below the High_Limit minus the Deadband for a minimum - period of time, specified in the Time_Delay property, and (b) - the HighLimitEnable flag must be set in the Limit_Enable - property, and (c) the TO-NORMAL flag must be set in the - Event_Enable property. */ - if ((PresentVal < - CurrentAI->High_Limit - CurrentAI->Deadband) && - ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == - EVENT_HIGH_LIMIT_ENABLE) && - ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == - EVENT_ENABLE_TO_NORMAL)) { - if (!CurrentAI->Remaining_Time_Delay) - CurrentAI->Event_State = EVENT_STATE_NORMAL; - else - CurrentAI->Remaining_Time_Delay--; - break; - } - /* value of the object is still in the same event state */ - CurrentAI->Remaining_Time_Delay = CurrentAI->Time_Delay; - break; - - case EVENT_STATE_LOW_LIMIT: - /* Once the Present_Value has fallen below the Low_Limit, - the Present_Value must exceed the Low_Limit plus the Deadband - before a TO-NORMAL event is generated under these conditions: - (a) the Present_Value must exceed the Low_Limit plus the - Deadband for a minimum period of time, specified in the - Time_Delay property, and (b) the LowLimitEnable flag must be - set in the Limit_Enable property, and - (c) the TO-NORMAL flag must be set in the Event_Enable - property. */ - if ((PresentVal > CurrentAI->Low_Limit + CurrentAI->Deadband) && - ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == - EVENT_LOW_LIMIT_ENABLE) && - ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == - EVENT_ENABLE_TO_NORMAL)) { - if (!CurrentAI->Remaining_Time_Delay) - CurrentAI->Event_State = EVENT_STATE_NORMAL; - else - CurrentAI->Remaining_Time_Delay--; - break; - } - /* value of the object is still in the same event state */ - CurrentAI->Remaining_Time_Delay = CurrentAI->Time_Delay; - break; - - default: - return; /* shouldn't happen */ - } /* switch (FromState) */ - - ToState = CurrentAI->Event_State; - - if (FromState != ToState) { - /* Event_State has changed. - Need to fill only the basic parameters of this type of event. - Other parameters will be filled in common function. */ - - switch (ToState) { - case EVENT_STATE_HIGH_LIMIT: - ExceededLimit = CurrentAI->High_Limit; - characterstring_init_ansi(&msgText, "Goes to high limit"); - break; - - case EVENT_STATE_LOW_LIMIT: - ExceededLimit = CurrentAI->Low_Limit; - characterstring_init_ansi(&msgText, "Goes to low limit"); - break; - - case EVENT_STATE_NORMAL: - if (FromState == EVENT_STATE_HIGH_LIMIT) { - ExceededLimit = CurrentAI->High_Limit; - characterstring_init_ansi( - &msgText, "Back to normal state from high limit"); - } else { - ExceededLimit = CurrentAI->Low_Limit; - characterstring_init_ansi( - &msgText, "Back to normal state from low limit"); - } - break; - - default: - ExceededLimit = 0; - break; - } /* switch (ToState) */ - -#if PRINT_ENABLED - fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n", - bactext_object_type_name(OBJECT_ANALOG_INPUT), object_instance, - bactext_event_state_name(FromState), - bactext_event_state_name(ToState)); -#endif /* PRINT_ENABLED */ - - /* Notify Type */ - event_data.notifyType = CurrentAI->Notify_Type; - - /* Send EventNotification. */ - SendNotify = true; - } - } - - if (SendNotify) { - /* Event Object Identifier */ - event_data.eventObjectIdentifier.type = OBJECT_ANALOG_INPUT; - event_data.eventObjectIdentifier.instance = object_instance; - - /* Time Stamp */ - event_data.timeStamp.tag = TIME_STAMP_DATETIME; - Device_getCurrentDateTime(&event_data.timeStamp.value.dateTime); - - if (event_data.notifyType != NOTIFY_ACK_NOTIFICATION) { - /* fill Event_Time_Stamps */ - switch (ToState) { - case EVENT_STATE_HIGH_LIMIT: - case EVENT_STATE_LOW_LIMIT: - CurrentAI->Event_Time_Stamps[TRANSITION_TO_OFFNORMAL] = - event_data.timeStamp.value.dateTime; - break; - - case EVENT_STATE_FAULT: - CurrentAI->Event_Time_Stamps[TRANSITION_TO_FAULT] = - event_data.timeStamp.value.dateTime; - break; - - case EVENT_STATE_NORMAL: - CurrentAI->Event_Time_Stamps[TRANSITION_TO_NORMAL] = - event_data.timeStamp.value.dateTime; - break; - } - } - - /* Notification Class */ - event_data.notificationClass = CurrentAI->Notification_Class; - - /* Event Type */ - event_data.eventType = EVENT_OUT_OF_RANGE; - - /* Message Text */ - event_data.messageText = &msgText; - - /* Notify Type */ - /* filled before */ - - /* From State */ - if (event_data.notifyType != NOTIFY_ACK_NOTIFICATION) - event_data.fromState = FromState; - - /* To State */ - event_data.toState = CurrentAI->Event_State; - - /* Event Values */ - if (event_data.notifyType != NOTIFY_ACK_NOTIFICATION) { - /* Value that exceeded a limit. */ - event_data.notificationParams.outOfRange.exceedingValue = - PresentVal; - /* Status_Flags of the referenced object. */ - bitstring_init( - &event_data.notificationParams.outOfRange.statusFlags); - bitstring_set_bit( - &event_data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_IN_ALARM, CurrentAI->Event_State ? true : false); - bitstring_set_bit( - &event_data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_FAULT, false); - bitstring_set_bit( - &event_data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit( - &event_data.notificationParams.outOfRange.statusFlags, - STATUS_FLAG_OUT_OF_SERVICE, CurrentAI->Out_Of_Service); - /* Deadband used for limit checking. */ - event_data.notificationParams.outOfRange.deadband = - CurrentAI->Deadband; - /* Limit that was exceeded. */ - event_data.notificationParams.outOfRange.exceededLimit = - ExceededLimit; - } - - /* add data from notification class */ - Notification_Class_common_reporting_function(&event_data); - - /* Ack required */ - if ((event_data.notifyType != NOTIFY_ACK_NOTIFICATION) && - (event_data.ackRequired == true)) { - switch (event_data.toState) { - case EVENT_STATE_OFFNORMAL: - case EVENT_STATE_HIGH_LIMIT: - case EVENT_STATE_LOW_LIMIT: - CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked = false; - CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .Time_Stamp = event_data.timeStamp.value.dateTime; - break; - - case EVENT_STATE_FAULT: - CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked = - false; - CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT] - .Time_Stamp = event_data.timeStamp.value.dateTime; - break; - - case EVENT_STATE_NORMAL: - CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL] - .bIsAcked = false; - CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL] - .Time_Stamp = event_data.timeStamp.value.dateTime; - break; - } - } - } -#endif /* defined(INTRINSIC_REPORTING) */ -} - -#if defined(INTRINSIC_REPORTING) -int Analog_Input_Event_Information( - unsigned index, BACNET_GET_EVENT_INFORMATION_DATA *getevent_data) -{ - bool IsNotAckedTransitions; - bool IsActiveEvent; - int i; - - /* check index */ - if (index < MAX_ANALOG_INPUTS) { - /* Event_State not equal to NORMAL */ - IsActiveEvent = (AI_Descr[index].Event_State != EVENT_STATE_NORMAL); - - /* Acked_Transitions property, which has at least one of the bits - (TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */ - IsNotAckedTransitions = - (AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked == false) | - (AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked == - false) | - (AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked == - false); - } else - return -1; /* end of list */ - - if ((IsActiveEvent) || (IsNotAckedTransitions)) { - /* Object Identifier */ - getevent_data->objectIdentifier.type = OBJECT_ANALOG_INPUT; - getevent_data->objectIdentifier.instance = - Analog_Input_Index_To_Instance(index); - /* Event State */ - getevent_data->eventState = AI_Descr[index].Event_State; - /* Acknowledged Transitions */ - bitstring_init(&getevent_data->acknowledgedTransitions); - bitstring_set_bit(&getevent_data->acknowledgedTransitions, - TRANSITION_TO_OFFNORMAL, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked); - bitstring_set_bit(&getevent_data->acknowledgedTransitions, - TRANSITION_TO_FAULT, - AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); - bitstring_set_bit(&getevent_data->acknowledgedTransitions, - TRANSITION_TO_NORMAL, - AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); - /* Event Time Stamps */ - for (i = 0; i < 3; i++) { - getevent_data->eventTimeStamps[i].tag = TIME_STAMP_DATETIME; - getevent_data->eventTimeStamps[i].value.dateTime = - AI_Descr[index].Event_Time_Stamps[i]; - } - /* Notify Type */ - getevent_data->notifyType = AI_Descr[index].Notify_Type; - /* Event Enable */ - bitstring_init(&getevent_data->eventEnable); - bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, - (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true - : false); - bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT, - (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) ? true - : false); - bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL, - (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true - : false); - /* Event Priorities */ - Notification_Class_Get_Priorities( - AI_Descr[index].Notification_Class, getevent_data->eventPriorities); - - return 1; /* active event */ - } else - return 0; /* no active event at this index */ -} - -int Analog_Input_Alarm_Ack( - BACNET_ALARM_ACK_DATA *alarmack_data, BACNET_ERROR_CODE *error_code) -{ - ANALOG_INPUT_DESCR *CurrentAI; - unsigned int object_index; - - object_index = Analog_Input_Instance_To_Index( - alarmack_data->eventObjectIdentifier.instance); - - if (object_index < MAX_ANALOG_INPUTS) - CurrentAI = &AI_Descr[object_index]; - else { - *error_code = ERROR_CODE_UNKNOWN_OBJECT; - return -1; - } - - switch (alarmack_data->eventStateAcked) { - case EVENT_STATE_OFFNORMAL: - case EVENT_STATE_HIGH_LIMIT: - case EVENT_STATE_LOW_LIMIT: - if (CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked == false) { - if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) { - *error_code = ERROR_CODE_INVALID_TIME_STAMP; - return -1; - } - if (datetime_compare( - &CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .Time_Stamp, - &alarmack_data->eventTimeStamp.value.dateTime) > 0) { - *error_code = ERROR_CODE_INVALID_TIME_STAMP; - return -1; - } - - /* FIXME: Send ack notification */ - CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked = - true; - } else { - *error_code = ERROR_CODE_INVALID_EVENT_STATE; - return -1; - } - break; - - case EVENT_STATE_FAULT: - if (CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked == - false) { - if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) { - *error_code = ERROR_CODE_INVALID_TIME_STAMP; - return -1; - } - if (datetime_compare( - &CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT] - .Time_Stamp, - &alarmack_data->eventTimeStamp.value.dateTime) > 0) { - *error_code = ERROR_CODE_INVALID_TIME_STAMP; - return -1; - } - - /* FIXME: Send ack notification */ - CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked = - true; - } else { - *error_code = ERROR_CODE_INVALID_EVENT_STATE; - return -1; - } - break; - - case EVENT_STATE_NORMAL: - if (CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked == - false) { - if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) { - *error_code = ERROR_CODE_INVALID_TIME_STAMP; - return -1; - } - if (datetime_compare( - &CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL] - .Time_Stamp, - &alarmack_data->eventTimeStamp.value.dateTime) > 0) { - *error_code = ERROR_CODE_INVALID_TIME_STAMP; - return -1; - } - - /* FIXME: Send ack notification */ - CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked = - true; - } else { - *error_code = ERROR_CODE_INVALID_EVENT_STATE; - return -1; - } - break; - - default: - return -2; - } - CurrentAI->Ack_notify_data.bSendAckNotify = true; - CurrentAI->Ack_notify_data.EventState = alarmack_data->eventStateAcked; - - return 1; -} - -int Analog_Input_Alarm_Summary( - unsigned index, BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data) -{ - /* check index */ - if (index < MAX_ANALOG_INPUTS) { - /* Event_State is not equal to NORMAL and - Notify_Type property value is ALARM */ - if ((AI_Descr[index].Event_State != EVENT_STATE_NORMAL) && - (AI_Descr[index].Notify_Type == NOTIFY_ALARM)) { - /* Object Identifier */ - getalarm_data->objectIdentifier.type = OBJECT_ANALOG_INPUT; - getalarm_data->objectIdentifier.instance = - Analog_Input_Index_To_Instance(index); - /* Alarm State */ - getalarm_data->alarmState = AI_Descr[index].Event_State; - /* Acknowledged Transitions */ - bitstring_init(&getalarm_data->acknowledgedTransitions); - bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_OFFNORMAL, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_OFFNORMAL] - .bIsAcked); - bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_FAULT, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_FAULT] - .bIsAcked); - bitstring_set_bit(&getalarm_data->acknowledgedTransitions, - TRANSITION_TO_NORMAL, - AI_Descr[index] - .Acked_Transitions[TRANSITION_TO_NORMAL] - .bIsAcked); - - return 1; /* active alarm */ - } else - return 0; /* no active alarm at this index */ - } else - return -1; /* end of list */ -} -#endif /* defined(INTRINSIC_REPORTING) */ diff --git a/ports/esp32/src/ai.h b/ports/esp32/src/ai.h deleted file mode 100644 index d19628c3..00000000 --- a/ports/esp32/src/ai.h +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* Copyright (C) 2011 Krzysztof Malorny -* -* SPDX-License-Identifier: MIT -* -*********************************************************************/ -#ifndef AI_H -#define AI_H - -#include -#include -#include "bacnet/bacdef.h" -#include "bacnet/rp.h" -#include "bacnet/wp.h" -#if defined(INTRINSIC_REPORTING) -#include "bacnet/basic/object/nc.h" -#include "bacnet/getevent.h" -#include "bacnet/alarm_ack.h" -#include "bacnet/get_alarm_sum.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - typedef struct analog_input_descr { - unsigned Event_State:3; - float Present_Value; - BACNET_RELIABILITY Reliability; - bool Out_Of_Service; - uint8_t Units; - float Prior_Value; - float COV_Increment; - bool Changed; -#if defined(INTRINSIC_REPORTING) - uint32_t Time_Delay; - uint32_t Notification_Class; - float High_Limit; - float Low_Limit; - float Deadband; - unsigned Limit_Enable:2; - unsigned Event_Enable:3; - unsigned Notify_Type:1; - ACKED_INFO Acked_Transitions[MAX_BACNET_EVENT_TRANSITION]; - BACNET_DATE_TIME Event_Time_Stamps[MAX_BACNET_EVENT_TRANSITION]; - /* time to generate event notification */ - uint32_t Remaining_Time_Delay; - /* AckNotification informations */ - ACK_NOTIFICATION Ack_notify_data; -#endif - } ANALOG_INPUT_DESCR; - - void Analog_Input_Property_Lists( - const int32_t **pRequired, - const int32_t **pOptional, - const int32_t **pProprietary); - - bool Analog_Input_Valid_Instance( - uint32_t object_instance); - unsigned Analog_Input_Count( - void); - uint32_t Analog_Input_Index_To_Instance( - unsigned index); - unsigned Analog_Input_Instance_To_Index( - uint32_t instance); - bool Analog_Input_Object_Instance_Add( - uint32_t instance); - - bool Analog_Input_Object_Name( - uint32_t object_instance, - BACNET_CHARACTER_STRING * object_name); - bool Analog_Input_Name_Set( - uint32_t object_instance, - const char *new_name); - - const char *Analog_Input_Description( - uint32_t instance); - bool Analog_Input_Description_Set( - uint32_t instance, - const char *new_name); - - bool Analog_Input_Units_Set( - uint32_t instance, - uint16_t units); - uint16_t Analog_Input_Units( - uint32_t instance); - - int Analog_Input_Read_Property( - BACNET_READ_PROPERTY_DATA * rpdata); - bool Analog_Input_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data); - - float Analog_Input_Present_Value( - uint32_t object_instance); - void Analog_Input_Present_Value_Set( - uint32_t object_instance, - float value); - - bool Analog_Input_Out_Of_Service( - uint32_t object_instance); - void Analog_Input_Out_Of_Service_Set( - uint32_t object_instance, - bool oos_flag); - - bool Analog_Input_Change_Of_Value( - uint32_t instance); - void Analog_Input_Change_Of_Value_Clear( - uint32_t instance); - bool Analog_Input_Encode_Value_List( - uint32_t object_instance, - BACNET_PROPERTY_VALUE * value_list); - float Analog_Input_COV_Increment( - uint32_t instance); - void Analog_Input_COV_Increment_Set( - uint32_t instance, - float value); - - /* note: header of Intrinsic_Reporting function is required - even when INTRINSIC_REPORTING is not defined */ - void Analog_Input_Intrinsic_Reporting( - uint32_t object_instance); - -#if defined(INTRINSIC_REPORTING) - int Analog_Input_Event_Information( - unsigned index, - BACNET_GET_EVENT_INFORMATION_DATA * getevent_data); - - int Analog_Input_Alarm_Ack( - BACNET_ALARM_ACK_DATA * alarmack_data, - BACNET_ERROR_CODE * error_code); - - int Analog_Input_Alarm_Summary( - unsigned index, - BACNET_GET_ALARM_SUMMARY_DATA * getalarm_data); -#endif - - uint32_t Analog_Input_Create( - uint32_t object_instance); - bool Analog_Input_Delete( - uint32_t object_instance); - void Analog_Input_Cleanup( - void); - void Analog_Input_Init( - void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/esp32/src/bacnet_app.c b/ports/esp32/src/bacnet_app.c new file mode 100644 index 00000000..86169d9d --- /dev/null +++ b/ports/esp32/src/bacnet_app.c @@ -0,0 +1,365 @@ +/** + * @file + * @brief BACnet application glue for the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#include +#include + +#include "bacnet_app.h" +#include "mstimer_init.h" + +#if defined(BACDL_MSTP) +#include "dlenv.h" +#include "bacnet/datalink/datalink.h" +#elif defined(BACDL_BIP) +#include "bip.h" +#endif + +#include "bacnet/basic/binding/address.h" +#include "bacnet/basic/object/ai.h" +#include "bacnet/basic/object/bi.h" +#include "bacnet/basic/object/bo.h" +#include "bacnet/basic/object/device.h" +#include "bacnet/basic/services.h" +#include "bacnet/basic/tsm/tsm.h" +#include "bacnet/npdu.h" + +#ifndef BACNET_IP_PORT +#define BACNET_IP_PORT 47808 +#endif + +#if defined(BACDL_BIP) +static uint8_t PDUBuffer[BIP_MPDU_MAX]; +#else +static uint8_t PDUBuffer[MAX_MPDU + 16]; +#endif + +#define PLC_INPUT_COUNT 8 +#define PLC_RELAY_COUNT 4 +#define PLC_ANALOG_COUNT 2 + +#define PLC_AI_INSTANCE_TEMPERATURE 100 +#define PLC_AI_INSTANCE_FREE_HEAP_KB 101 + +static uint32_t Plc_Input_Instances[PLC_INPUT_COUNT]; +static uint32_t Plc_Relay_Instances[PLC_RELAY_COUNT]; +static uint32_t Plc_Analog_Instances[PLC_ANALOG_COUNT]; + +static const char *const Plc_Input_Names[PLC_INPUT_COUNT] = { + "PLC Input 1", "PLC Input 2", "PLC Input 3", "PLC Input 4", + "PLC Input 5", "PLC Input 6", "PLC Input 7", "PLC Input 8", +}; + +static const char *const Plc_Input_Descriptions[PLC_INPUT_COUNT] = { + "PLC Input 1", "PLC Input 2", "PLC Input 3", "PLC Input 4", + "PLC Input 5", "PLC Input 6", "PLC Input 7", "PLC Input 8", +}; + +static const char *const Plc_Relay_Names[PLC_RELAY_COUNT] = { + "PLC Relay 1", + "PLC Relay 2", + "PLC Relay 3", + "PLC Relay 4", +}; + +static const char *const Plc_Relay_Descriptions[PLC_RELAY_COUNT] = { + "PLC Relay 1", + "PLC Relay 2", + "PLC Relay 3", + "PLC Relay 4", +}; + +static const char *const Plc_Analog_Names[PLC_ANALOG_COUNT] = { + "PLC Temperature", + "Free Heap KB", +}; + +static const char *const Plc_Analog_Descriptions[PLC_ANALOG_COUNT] = { + "Internal PLC temperature in C", + "Free heap memory in kilobytes", +}; + +static object_functions_t My_Object_Table[] = { + { OBJECT_DEVICE, + NULL, + Device_Count, + Device_Index_To_Instance, + Device_Valid_Object_Instance_Number, + Device_Object_Name, + Device_Read_Property_Local, + Device_Write_Property_Local, + Device_Property_Lists, + DeviceGetRRInfo, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Device_Writable_Property_List }, + + { OBJECT_BINARY_INPUT, + Binary_Input_Init, + Binary_Input_Count, + Binary_Input_Index_To_Instance, + Binary_Input_Valid_Instance, + Binary_Input_Object_Name, + Binary_Input_Read_Property, + NULL, + Binary_Input_Property_Lists, + NULL, + NULL, + Binary_Input_Encode_Value_List, + Binary_Input_Change_Of_Value, + Binary_Input_Change_Of_Value_Clear, + NULL, + NULL, + NULL, + Binary_Input_Create, + Binary_Input_Delete, + NULL, + Binary_Input_Writable_Property_List }, + + { OBJECT_ANALOG_INPUT, + Analog_Input_Init, + Analog_Input_Count, + Analog_Input_Index_To_Instance, + Analog_Input_Valid_Instance, + Analog_Input_Object_Name, + Analog_Input_Read_Property, + Analog_Input_Write_Property, + Analog_Input_Property_Lists, + NULL, + NULL, + Analog_Input_Encode_Value_List, + Analog_Input_Change_Of_Value, + Analog_Input_Change_Of_Value_Clear, + Analog_Input_Intrinsic_Reporting, + NULL, + NULL, + Analog_Input_Create, + Analog_Input_Delete, + NULL, + Analog_Input_Writable_Property_List }, + + { OBJECT_BINARY_OUTPUT, + Binary_Output_Init, + Binary_Output_Count, + Binary_Output_Index_To_Instance, + Binary_Output_Valid_Instance, + Binary_Output_Object_Name, + Binary_Output_Read_Property, + Binary_Output_Write_Property, + Binary_Output_Property_Lists, + NULL, + NULL, + Binary_Output_Encode_Value_List, + Binary_Output_Change_Of_Value, + Binary_Output_Change_Of_Value_Clear, + NULL, + NULL, + NULL, + Binary_Output_Create, + Binary_Output_Delete, + NULL, + Binary_Output_Writable_Property_List }, + + { MAX_BACNET_OBJECT_TYPE, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL } +}; + +/** + * @brief Create and initialize the BACnet objects exposed by this port + */ +static void init_server_objects(void) +{ + uint32_t instance; + + Device_Init(My_Object_Table); + + for (uint8_t i = 0; i < PLC_INPUT_COUNT; i++) { + instance = Binary_Input_Create(i); + Plc_Input_Instances[i] = instance; + (void)Binary_Input_Name_Set(instance, Plc_Input_Names[i]); + (void)Binary_Input_Description_Set(instance, Plc_Input_Descriptions[i]); + } + + for (uint8_t i = 0; i < PLC_RELAY_COUNT; i++) { + instance = Binary_Output_Create(i); + Plc_Relay_Instances[i] = instance; + (void)Binary_Output_Name_Set(instance, Plc_Relay_Names[i]); + (void)Binary_Output_Description_Set( + instance, Plc_Relay_Descriptions[i]); + (void)Binary_Output_Present_Value_Set( + instance, BINARY_INACTIVE, BACNET_MAX_PRIORITY); + } + + Plc_Analog_Instances[0] = Analog_Input_Create(PLC_AI_INSTANCE_TEMPERATURE); + Plc_Analog_Instances[1] = Analog_Input_Create(PLC_AI_INSTANCE_FREE_HEAP_KB); + + (void)Analog_Input_Name_Set(Plc_Analog_Instances[0], Plc_Analog_Names[0]); + (void)Analog_Input_Description_Set( + Plc_Analog_Instances[0], Plc_Analog_Descriptions[0]); + (void)Analog_Input_Units_Set( + Plc_Analog_Instances[0], UNITS_DEGREES_CELSIUS); + + (void)Analog_Input_Name_Set(Plc_Analog_Instances[1], Plc_Analog_Names[1]); + (void)Analog_Input_Description_Set( + Plc_Analog_Instances[1], Plc_Analog_Descriptions[1]); + (void)Analog_Input_Units_Set(Plc_Analog_Instances[1], UNITS_NO_UNITS); +} + +/** + * @brief Initialize the BACnet application and selected datalink + */ +void bacnet_app_init(void) +{ + systimer_init(); + + address_init(); + Device_Set_Object_Instance_Number(12345); + init_server_objects(); + +#if defined(BACDL_MSTP) + if (!m5_dlenv_init(2)) { + for (;;) { } + } +#elif defined(BACDL_BIP) + if (!bip_init((uint16_t)BACNET_IP_PORT)) { + for (;;) { } + } +#endif + + apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); + apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); + apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property); + apdu_set_confirmed_handler( + SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, + handler_device_communication_control); + + Send_I_Am(&Handler_Transmit_Buffer[0]); +} + +/** + * @brief Process one BACnet polling cycle and advance timers + */ +void bacnet_app_tick(void) +{ + BACNET_ADDRESS src = { 0 }; + uint16_t pdu_len = 0; + +#if defined(BACDL_BIP) + pdu_len = bip_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); +#else + pdu_len = datalink_receive(&src, &PDUBuffer[0], MAX_MPDU, 0); +#endif + if (pdu_len) { + npdu_handler(&src, &PDUBuffer[0], pdu_len); + } + + tsm_timer_milliseconds(1); +} + +/** + * @brief Get the number of exposed PLC binary inputs + * @return number of binary inputs + */ +uint8_t bacnet_app_input_count(void) +{ + return PLC_INPUT_COUNT; +} + +/** + * @brief Get the number of exposed PLC relay outputs + * @return number of binary outputs + */ +uint8_t bacnet_app_relay_count(void) +{ + return PLC_RELAY_COUNT; +} + +/** + * @brief Update a BACnet binary input from PLC state + * @param index zero-based PLC input index + * @param active input state to publish + */ +void bacnet_app_input_set(uint8_t index, bool active) +{ + uint32_t instance; + + if (index >= PLC_INPUT_COUNT) { + return; + } + + instance = Plc_Input_Instances[index]; + + (void)Binary_Input_Present_Value_Set( + instance, active ? BINARY_ACTIVE : BINARY_INACTIVE); +} + +/** + * @brief Read the commanded state of a BACnet relay output + * @param index zero-based relay index + * @return true if the relay should be active + */ +bool bacnet_app_relay_get(uint8_t index) +{ + uint32_t instance; + + if (index >= PLC_RELAY_COUNT) { + return false; + } + + instance = Plc_Relay_Instances[index]; + + return (Binary_Output_Present_Value(instance) == BINARY_ACTIVE); +} + +/** + * @brief Update the analog input that reports PLC temperature + * @param value_celsius temperature in degrees Celsius + */ +void bacnet_app_temperature_set(float value_celsius) +{ + Analog_Input_Present_Value_Set(Plc_Analog_Instances[0], value_celsius); +} + +/** + * @brief Update the analog input that reports free heap memory + * @param value_kb free heap in kilobytes + */ +void bacnet_app_free_heap_kb_set(float value_kb) +{ + Analog_Input_Present_Value_Set(Plc_Analog_Instances[1], value_kb); +} diff --git a/ports/esp32/src/bacnet_app.h b/ports/esp32/src/bacnet_app.h new file mode 100644 index 00000000..3c7d8e0a --- /dev/null +++ b/ports/esp32/src/bacnet_app.h @@ -0,0 +1,69 @@ +/** + * @file + * @brief Public BACnet application hooks for the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#ifndef M5STAMPLC_BACNET_APP_H +#define M5STAMPLC_BACNET_APP_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the BACnet application and datalink bindings + */ +void bacnet_app_init(void); + +/** + * @brief Run one BACnet processing cycle + */ +void bacnet_app_tick(void); + +/** + * @brief Get the number of published PLC inputs + * @return number of PLC inputs + */ +uint8_t bacnet_app_input_count(void); + +/** + * @brief Get the number of published PLC relays + * @return number of PLC relays + */ +uint8_t bacnet_app_relay_count(void); + +/** + * @brief Push a PLC input state into the BACnet object model + * @param index zero-based input index + * @param active input state + */ +void bacnet_app_input_set(uint8_t index, bool active); + +/** + * @brief Read the requested state for a PLC relay + * @param index zero-based relay index + * @return true if the relay should be active + */ +bool bacnet_app_relay_get(uint8_t index); + +/** + * @brief Update the published PLC temperature value + * @param value_celsius temperature in degrees Celsius + */ +void bacnet_app_temperature_set(float value_celsius); + +/** + * @brief Update the published free heap value + * @param value_kb free heap in kilobytes + */ +void bacnet_app_free_heap_kb_set(float value_kb); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/esp32/src/bip.c b/ports/esp32/src/bip.c new file mode 100644 index 00000000..cbe80a42 --- /dev/null +++ b/ports/esp32/src/bip.c @@ -0,0 +1,350 @@ +/** + * @file + * @brief BACnet/IP datalink implementation for the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#include +#include +#include + +#include "bacnet/bacdcode.h" +#include "bacnet/bacint.h" +#include "bacnet/datalink/bvlc.h" + +#include "bip.h" +#include "bvlc.h" + +#if PRINT_ENABLED || DEBUG +#include +#endif + +#define MAX_SOCK_NUM 8 + +static uint8_t BIP_Socket = MAX_SOCK_NUM; +static uint16_t BIP_Port = 0; +static uint8_t BIP_Address[4] = { 0, 0, 0, 0 }; +static uint8_t BIP_Broadcast_Address[4] = { 0, 0, 0, 0 }; + +/** + * @brief Convert a 4-byte IP address into a uint32_t value + * @param bip_address pointer to the 4-byte address + * @return 32-bit packed address + */ +uint32_t convertBIP_Address2uint32(const uint8_t *bip_address) +{ + return ((uint32_t)bip_address[0] << 24) | ((uint32_t)bip_address[1] << 16) | + ((uint32_t)bip_address[2] << 8) | ((uint32_t)bip_address[3]); +} + +/** + * @brief Convert a uint32_t IP address into a 4-byte array + * @param ip packed IP address + * @param address destination buffer for the 4-byte address + */ +void convertUint32Address_2_uint8Address(uint32_t ip, uint8_t *address) +{ + address[0] = (uint8_t)(ip >> 24); + address[1] = (uint8_t)(ip >> 16); + address[2] = (uint8_t)(ip >> 8); + address[3] = (uint8_t)(ip >> 0); +} + +/** + * @brief Store the active socket identifier used by the BACnet/IP layer + * @param sock_fd socket identifier + */ +void bip_set_socket(uint8_t sock_fd) +{ + BIP_Socket = sock_fd; +} + +/** + * @brief Get the stored BACnet/IP socket identifier + * @return socket identifier + */ +uint8_t bip_socket(void) +{ + return BIP_Socket; +} + +/** + * @brief Check whether the BACnet/IP socket state is valid + * @return true if the stored socket identifier is valid + */ +bool bip_valid(void) +{ + return (BIP_Socket < MAX_SOCK_NUM); +} + +/** + * @brief Store the local IPv4 address used by BACnet/IP + * @param net_address pointer to the 4-byte local address + */ +void bip_set_addr(const uint8_t *net_address) +{ + uint8_t i; + + for (i = 0; i < 4; i++) { + BIP_Address[i] = net_address[i]; + } +} + +/** + * @brief Get the stored local IPv4 address + * @return pointer to the 4-byte local address + */ +uint8_t *bip_get_addr(void) +{ + return BIP_Address; +} + +/** + * @brief Store the broadcast IPv4 address used by BACnet/IP + * @param net_address pointer to the 4-byte broadcast address + */ +void bip_set_broadcast_addr(const uint8_t *net_address) +{ + uint8_t i; + + for (i = 0; i < 4; i++) { + BIP_Broadcast_Address[i] = net_address[i]; + } +} + +/** + * @brief Get the stored broadcast IPv4 address + * @return pointer to the 4-byte broadcast address + */ +uint8_t *bip_get_broadcast_addr(void) +{ + return BIP_Broadcast_Address; +} + +/** + * @brief Store the UDP port used by BACnet/IP + * @param port UDP port number + */ +void bip_set_port(uint16_t port) +{ + BIP_Port = port; +} + +/** + * @brief Get the UDP port used by BACnet/IP + * @return UDP port number + */ +uint16_t bip_get_port(void) +{ + return BIP_Port; +} + +/** + * @brief Decode a BACnet/IP MAC address into IPv4 address and port parts + * @param bac_addr source BACnet address + * @param address destination IPv4 address buffer + * @param port destination UDP port pointer + * @return number of bytes decoded from the MAC address + */ +static int bip_decode_bip_address( + const BACNET_ADDRESS *bac_addr, uint8_t *address, uint16_t *port) +{ + int len = 0; + + if (bac_addr) { + memcpy(address, &bac_addr->mac[0], 4); + memcpy(port, &bac_addr->mac[4], 2); + len = 6; + } + + return len; +} + +/** + * @brief Send a BACnet NPDU over BACnet/IP + * @param dest destination BACnet address + * @param npdu_data NPDU metadata + * @param pdu payload buffer + * @param pdu_len payload length in bytes + * @return number of bytes sent, or -1 on error + */ +int bip_send_pdu( + BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned pdu_len) +{ + uint8_t mtu[BIP_MPDU_MAX] = { 0 }; + int mtu_len = 0; + int bytes_sent = 0; + uint8_t address[] = { 0, 0, 0, 0 }; + uint16_t port = 0; + uint8_t i; + + (void)npdu_data; + + if (BIP_Socket >= MAX_SOCK_NUM) { + return -1; + } + + mtu[0] = BVLL_TYPE_BACNET_IP; + if ((dest->net == BACNET_BROADCAST_NETWORK) || + ((dest->net > 0) && (dest->len == 0)) || (dest->mac_len == 0)) { + for (i = 0; i < 4; i++) { + address[i] = BIP_Broadcast_Address[i]; + } + port = BIP_Port; + mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU; + } else if (dest->mac_len == 6) { + bip_decode_bip_address(dest, address, &port); + mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU; + } else { + return -1; + } + + mtu_len = 2; + mtu_len += encode_unsigned16(&mtu[mtu_len], (uint16_t)(pdu_len + 4)); + memcpy(&mtu[mtu_len], pdu, pdu_len); + mtu_len += (int)pdu_len; + + bytes_sent = bip_socket_send(address, port, mtu, (uint16_t)mtu_len); + + return bytes_sent; +} + +/** + * @brief Receive a BACnet/IP NPDU and strip BVLC framing + * @param src source BACnet address + * @param pdu receive buffer for NPDU data + * @param max_pdu receive buffer size + * @param timeout receive timeout in milliseconds + * @return NPDU length in bytes, or 0 if no valid frame was received + */ +uint16_t bip_receive( + BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout) +{ + int received_bytes = 0; + int max = 0; + uint16_t pdu_len = 0; + uint8_t src_addr[] = { 0, 0, 0, 0 }; + uint16_t src_port = 0; + uint16_t i = 0; + int function = 0; + + (void)timeout; + + if (BIP_Socket >= MAX_SOCK_NUM) { + return 0; + } + + received_bytes = bip_socket_receive(pdu, max_pdu, src_addr, &src_port); + if (received_bytes <= 0) { + return 0; + } + + if (pdu[0] != BVLL_TYPE_BACNET_IP) { + return 0; + } + + max = (int)max_pdu - received_bytes; + if (max > 0) { + if (max > 16) { + max = 16; + } + memset(&pdu[received_bytes], 0, (size_t)max); + } + + if (bvlc_for_non_bbmd(src_addr, &src_port, pdu, (uint16_t)received_bytes) > + 0) { + return 0; + } + + function = pico_bvlc_get_function_code(); + if ((function == BVLC_ORIGINAL_UNICAST_NPDU) || + (function == BVLC_ORIGINAL_BROADCAST_NPDU)) { + if ((convertBIP_Address2uint32(src_addr) == + convertBIP_Address2uint32(BIP_Address)) && + (src_port == BIP_Port)) { + pdu_len = 0; + } else { + src->mac_len = 6; + memcpy(&src->mac[0], &src_addr, 4); + memcpy(&src->mac[4], &src_port, 2); + (void)decode_unsigned16(&pdu[2], &pdu_len); + pdu_len -= 4; + if (pdu_len < max_pdu) { + for (i = 0; i < pdu_len; i++) { + pdu[i] = pdu[4 + i]; + } + } else { + pdu_len = 0; + } + } + } else if (function == BVLC_FORWARDED_NPDU) { + memcpy(&src_addr, &pdu[4], 4); + memcpy(&src_port, &pdu[8], 2); + if ((convertBIP_Address2uint32(src_addr) == + convertBIP_Address2uint32(BIP_Address)) && + (src_port == BIP_Port)) { + pdu_len = 0; + } else { + src->mac_len = 6; + memcpy(&src->mac[0], &src_addr, 4); + memcpy(&src->mac[4], &src_port, 2); + (void)decode_unsigned16(&pdu[2], &pdu_len); + pdu_len -= 10; + if (pdu_len < max_pdu) { + for (i = 0; i < pdu_len; i++) { + pdu[i] = pdu[10 + i]; + } + } else { + pdu_len = 0; + } + } + } + + return pdu_len; +} + +/** + * @brief Build the local BACnet/IP address structure + * @param my_address destination BACnet address + */ +void bip_get_my_address(BACNET_ADDRESS *my_address) +{ + if (my_address) { + my_address->mac_len = 6; + memcpy(&my_address->mac[0], &BIP_Address[0], 4); + memcpy(&my_address->mac[4], &BIP_Port, 2); + my_address->net = 0; + my_address->len = 0; + } +} + +/** + * @brief Build the BACnet/IP broadcast address structure + * @param dest destination BACnet address + */ +void bip_get_broadcast_address(BACNET_ADDRESS *dest) +{ + if (dest) { + dest->mac_len = 6; + memcpy(&dest->mac[0], &BIP_Broadcast_Address[0], 4); + memcpy(&dest->mac[4], &BIP_Port, 2); + dest->net = BACNET_BROADCAST_NETWORK; + dest->len = 0; + } +} + +/** + * @brief Send a raw BACnet/IP MPDU to a specific host and port + * @param dest destination IPv4 address and port + * @param mtu raw BVLC/NPDU buffer + * @param mtu_len buffer length in bytes + * @return number of bytes sent, or -1 on error + */ +int bip_send_mpdu( + const BACNET_IP_ADDRESS *dest, const uint8_t *mtu, uint16_t mtu_len) +{ + return bip_socket_send(dest->address, dest->port, mtu, mtu_len); +} diff --git a/ports/esp32/src/bip.h b/ports/esp32/src/bip.h new file mode 100644 index 00000000..4b68b7f4 --- /dev/null +++ b/ports/esp32/src/bip.h @@ -0,0 +1,226 @@ +/** + * @file + * @brief BACnet/IP datalink interface for the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#ifndef M5STAMPLC_BIP_H +#define M5STAMPLC_BIP_H + +#include +#include +#include + +#include "bacnet/bacdef.h" +#include "bacnet/npdu.h" +#include "bacnet/datalink/bvlc.h" + +#define BIP_HEADER_MAX (1 + 1 + 2) +#ifndef BIP_MPDU_MAX +#define BIP_MPDU_MAX (BIP_HEADER_MAX + MAX_PDU) +#endif + +#define BVLL_TYPE_BACNET_IP (0x81) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the UDP socket backend used by BACnet/IP + * @param port UDP port to bind + * @return true if the socket backend was initialized + */ +bool bip_socket_init(uint16_t port); + +/** + * @brief Send a raw UDP payload for BACnet/IP + * @param dest_addr destination IPv4 address + * @param dest_port destination UDP port + * @param mtu payload buffer + * @param mtu_len payload length + * @return number of bytes sent, or -1 on error + */ +int bip_socket_send( + const uint8_t *dest_addr, + uint16_t dest_port, + const uint8_t *mtu, + uint16_t mtu_len); +/** + * @brief Receive a raw UDP payload for BACnet/IP + * @param buf receive buffer + * @param buf_len receive buffer size + * @param src_addr source IPv4 address + * @param src_port source UDP port + * @return number of bytes received + */ +int bip_socket_receive( + uint8_t *buf, uint16_t buf_len, uint8_t *src_addr, uint16_t *src_port); + +/** + * @brief Close the UDP socket backend used by BACnet/IP + */ +void bip_socket_cleanup(void); + +/** + * @brief Read the current local IP address and subnet mask + * @param local_addr destination for the local IPv4 address + * @param netmask destination for the subnet mask + * @return true if the network information was available + */ +bool bip_get_local_network_info(uint8_t *local_addr, uint8_t *netmask); + +/** + * @brief Initialize the BACnet/IP datalink + * @param port UDP port to use + * @return true if initialization succeeded + */ +bool bip_init(uint16_t port); + +/** + * @brief Refresh the local and broadcast interface addresses + */ +void bip_set_interface(void); + +/** + * @brief Shut down the BACnet/IP datalink + */ +void bip_cleanup(void); + +/** + * @brief Convert a 4-byte address into a 32-bit value + * @param bip_address pointer to IPv4 address bytes + * @return packed address value + */ +uint32_t convertBIP_Address2uint32(const uint8_t *bip_address); + +/** + * @brief Convert a 32-bit address into a 4-byte array + * @param ip packed address value + * @param address destination buffer + */ +void convertUint32Address_2_uint8Address(uint32_t ip, uint8_t *address); + +/** + * @brief Store the current socket identifier + * @param sock_fd socket identifier + */ +void bip_set_socket(uint8_t sock_fd); + +/** + * @brief Get the current socket identifier + * @return socket identifier + */ +uint8_t bip_socket(void); + +/** + * @brief Check whether the BACnet/IP datalink is valid + * @return true if the datalink is ready to use + */ +bool bip_valid(void); + +/** + * @brief Build the broadcast BACnet/IP address + * @param dest destination address structure + */ +void bip_get_broadcast_address(BACNET_ADDRESS *dest); + +/** + * @brief Build the local BACnet/IP address + * @param my_address destination address structure + */ +void bip_get_my_address(BACNET_ADDRESS *my_address); + +/** + * @brief Send a BACnet NPDU over BACnet/IP + * @param dest destination BACnet address + * @param npdu_data NPDU metadata + * @param pdu payload buffer + * @param pdu_len payload length in bytes + * @return number of bytes sent, or -1 on error + */ +int bip_send_pdu( + BACNET_ADDRESS *dest, + BACNET_NPDU_DATA *npdu_data, + uint8_t *pdu, + unsigned pdu_len); + +/** + * @brief Send a raw BACnet/IP MPDU + * @param dest destination IP address and port + * @param mtu raw buffer to send + * @param mtu_len buffer length in bytes + * @return number of bytes sent, or -1 on error + */ +int bip_send_mpdu( + const BACNET_IP_ADDRESS *dest, const uint8_t *mtu, uint16_t mtu_len); + +/** + * @brief Receive a BACnet/IP NPDU + * @param src source BACnet address + * @param pdu receive buffer + * @param max_pdu receive buffer size + * @param timeout receive timeout in milliseconds + * @return number of NPDU bytes received + */ +uint16_t bip_receive( + BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout); + +/** + * @brief Store the UDP port used by BACnet/IP + * @param port UDP port number + */ +void bip_set_port(uint16_t port); + +/** + * @brief Get the UDP port used by BACnet/IP + * @return UDP port number + */ +uint16_t bip_get_port(void); + +/** + * @brief Store the local IPv4 address + * @param net_address pointer to the 4-byte address + */ +void bip_set_addr(const uint8_t *net_address); + +/** + * @brief Get the local IPv4 address + * @return pointer to the stored address + */ +uint8_t *bip_get_addr(void); + +/** + * @brief Store the IPv4 broadcast address + * @param net_address pointer to the 4-byte broadcast address + */ +void bip_set_broadcast_addr(const uint8_t *net_address); + +/** + * @brief Get the stored IPv4 broadcast address + * @return pointer to the stored broadcast address + */ +uint8_t *bip_get_broadcast_addr(void); + +/** + * @brief Resolve a host name into an address when supported + * @param host_name host name to resolve + * @return resolved address value, or 0 when unsupported + */ +long bip_getaddrbyname(const char *host_name); + +/** + * @brief Enable BACnet/IP debug behavior + */ +void bip_debug_enable(void); + +/** + * @brief Disable BACnet/IP debug behavior + */ +void bip_debug_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/esp32/src/bip_init.c b/ports/esp32/src/bip_init.c index f637094b..14ebb9dd 100644 --- a/ports/esp32/src/bip_init.c +++ b/ports/esp32/src/bip_init.c @@ -1,56 +1,96 @@ -// -// Copyleft F.Chaxel 2017 -// +/** + * @file + * @brief BACnet/IP initialization helpers for the PlatformIO ESP32 port + * @author Kato Gangstad + */ -#include "esp_log.h" -#include "esp_wifi.h" +#include +#include -#include "lwip/sockets.h" -#include "lwip/netdb.h" +#include "bip.h" -#include "bacnet/datalink/bip.h" +static bool BIP_Debug = false; -long bip_get_addr_by_name(const char *host_name) +/** + * @brief Enable BACnet/IP debug mode + */ +void bip_debug_enable(void) { + BIP_Debug = true; +} + +/** + * @brief Disable BACnet/IP debug mode + */ +void bip_debug_disable(void) +{ + BIP_Debug = false; +} + +/** + * @brief Resolve a host name into an address when supported + * @param host_name host name to resolve + * @return resolved address, or 0 when unsupported by this port + */ +long bip_getaddrbyname(const char *host_name) +{ + (void)host_name; return 0; } -void bip_set_interface(const char *ifname) +/** + * @brief Refresh the local and broadcast BACnet/IP addresses + */ +void bip_set_interface(void) { + uint8_t local_address[] = { 0, 0, 0, 0 }; + uint8_t broadcast_address[] = { 0, 0, 0, 0 }; + uint8_t netmask[] = { 0, 0, 0, 0 }; + uint8_t inverted_netmask[] = { 0, 0, 0, 0 }; + int i; + + if (!bip_get_local_network_info(local_address, netmask)) { + return; + } + + bip_set_addr(local_address); + + for (i = 0; i < 4; i++) { + inverted_netmask[i] = (uint8_t)~netmask[i]; + broadcast_address[i] = + (uint8_t)(local_address[i] | inverted_netmask[i]); + } + + bip_set_broadcast_addr(broadcast_address); } -void bip_cleanup(void) +/** + * @brief Initialize the BACnet/IP datalink for the selected UDP port + * @param port UDP port number + * @return true if initialization succeeded + */ +bool bip_init(uint16_t port) { - close(bip_socket()); - bip_set_socket(-1); -} + (void)BIP_Debug; -bool bip_init(char *ifname) -{ - tcpip_adapter_ip_info_t ip_info = { 0 }; + if (!bip_socket_init(port)) { + return false; + } - int value = 1; + bip_set_interface(); + bip_set_port(port); - tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info); - - bip_set_interface(ifname); - bip_set_port(0xBAC0U); - bip_set_addr(ip_info.ip.addr); - bip_set_broadcast_addr( - (ip_info.ip.addr & ip_info.netmask.addr) | (~ip_info.netmask.addr)); - - int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); - struct sockaddr_in saddr = { 0 }; - - saddr.sin_family = PF_INET; - saddr.sin_port = htons(0xBAC0U); - saddr.sin_addr.s_addr = htonl(INADDR_ANY); - bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)); - - setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&value, sizeof(value)); - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value)); - - bip_set_socket(sock); + bip_set_socket(0); return true; } + +/** + * @brief Shut down the BACnet/IP datalink + */ +void bip_cleanup(void) +{ + if (bip_valid()) { + bip_socket_cleanup(); + } +} diff --git a/ports/esp32/src/bip_socket.cpp b/ports/esp32/src/bip_socket.cpp new file mode 100644 index 00000000..01653874 --- /dev/null +++ b/ports/esp32/src/bip_socket.cpp @@ -0,0 +1,178 @@ +/** + * @file + * @brief UDP socket bridge used by BACnet/IP on the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#include +#include +#include +#if defined(USE_ETH_INTERFACE) && (USE_ETH_INTERFACE) +#include +#endif + +extern "C" { +#include "bip.h" +} + +static WiFiUDP BipUdp; +static bool BipSocketOpen = false; + +/** + * @brief Check whether the selected network interface is up + * @return true if the interface is connected + */ +static bool network_connected(void) +{ +#if defined(USE_ETH_INTERFACE) && (USE_ETH_INTERFACE) + return ETH.linkUp(); +#else + return (WiFi.status() == WL_CONNECTED); +#endif +} + +/** + * @brief Get the local IP address for the selected network interface + * @return local IP address + */ +static IPAddress network_local_ip(void) +{ +#if defined(USE_ETH_INTERFACE) && (USE_ETH_INTERFACE) + return ETH.localIP(); +#else + return WiFi.localIP(); +#endif +} + +/** + * @brief Get the subnet mask for the selected network interface + * @return subnet mask + */ +static IPAddress network_subnet_mask(void) +{ +#if defined(USE_ETH_INTERFACE) && (USE_ETH_INTERFACE) + return ETH.subnetMask(); +#else + return WiFi.subnetMask(); +#endif +} + +/** + * @brief Initialize the UDP socket used by BACnet/IP + * @param port UDP port to bind + * @return true if the socket was opened successfully + */ +extern "C" bool bip_socket_init(uint16_t port) +{ + if (!network_connected()) { + return false; + } + + BipUdp.stop(); + BipSocketOpen = (BipUdp.begin(port) == 1); + return BipSocketOpen; +} + +/** + * @brief Send a UDP packet for BACnet/IP + * @param dest_addr destination IPv4 address + * @param dest_port destination UDP port + * @param mtu payload buffer + * @param mtu_len payload length in bytes + * @return number of bytes sent, or -1 on error + */ +extern "C" int bip_socket_send( + const uint8_t *dest_addr, + uint16_t dest_port, + const uint8_t *mtu, + uint16_t mtu_len) +{ + if (!BipSocketOpen || !dest_addr || !mtu || (mtu_len == 0U)) { + return -1; + } + + IPAddress ip(dest_addr[0], dest_addr[1], dest_addr[2], dest_addr[3]); + if (!BipUdp.beginPacket(ip, dest_port)) { + return -1; + } + + size_t written = BipUdp.write(mtu, mtu_len); + if (!BipUdp.endPacket()) { + return -1; + } + + return (written == mtu_len) ? (int)written : -1; +} + +/** + * @brief Receive a UDP packet for BACnet/IP + * @param buf receive buffer + * @param buf_len receive buffer size + * @param src_addr source IPv4 address + * @param src_port source UDP port + * @return number of bytes received + */ +extern "C" int bip_socket_receive( + uint8_t *buf, uint16_t buf_len, uint8_t *src_addr, uint16_t *src_port) +{ + if (!BipSocketOpen || !buf || !src_addr || !src_port || (buf_len == 0U)) { + return 0; + } + + int packet_size = BipUdp.parsePacket(); + if (packet_size <= 0) { + return 0; + } + + IPAddress remote = BipUdp.remoteIP(); + src_addr[0] = remote[0]; + src_addr[1] = remote[1]; + src_addr[2] = remote[2]; + src_addr[3] = remote[3]; + *src_port = BipUdp.remotePort(); + + int to_read = packet_size; + if (to_read > (int)buf_len) { + to_read = (int)buf_len; + } + + int len = BipUdp.read(buf, to_read); + return (len > 0) ? len : 0; +} + +/** + * @brief Close the UDP socket used by BACnet/IP + */ +extern "C" void bip_socket_cleanup(void) +{ + BipUdp.stop(); + BipSocketOpen = false; +} + +/** + * @brief Get the local network address and subnet mask + * @param local_addr destination IPv4 address buffer + * @param netmask destination subnet mask buffer + * @return true if network information was available + */ +extern "C" bool +bip_get_local_network_info(uint8_t *local_addr, uint8_t *netmask) +{ + if (!local_addr || !netmask || !network_connected()) { + return false; + } + + IPAddress ip = network_local_ip(); + IPAddress mask = network_subnet_mask(); + local_addr[0] = ip[0]; + local_addr[1] = ip[1]; + local_addr[2] = ip[2]; + local_addr[3] = ip[3]; + + netmask[0] = mask[0]; + netmask[1] = mask[1]; + netmask[2] = mask[2]; + netmask[3] = mask[3]; + + return true; +} diff --git a/ports/esp32/src/bo.c b/ports/esp32/src/bo.c deleted file mode 100644 index 5b9b201f..00000000 --- a/ports/esp32/src/bo.c +++ /dev/null @@ -1,433 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2005 Steve Karg - * - * SPDX-License-Identifier: MIT - * - *********************************************************************/ - -/* Binary Output Objects - customize for your use */ - -#include -#include -#include -#include "bacnet/bacdef.h" -#include "bacnet/bacdcode.h" -#include "bacnet/bacenum.h" -#include "bacnet/bacapp.h" -#include "bacnet/config.h" /* the custom stuff */ -#include "bacnet/rp.h" -#include "bacnet/wp.h" -#include "bacnet/basic/object/bo.h" -#include "bacnet/basic/services.h" - -#ifndef MAX_BINARY_OUTPUTS -#define MAX_BINARY_OUTPUTS 1 -#endif - -/* When all the priorities are level null, the present value returns */ -/* the Relinquish Default value */ -#define RELINQUISH_DEFAULT BINARY_INACTIVE -/* Here is our Priority Array.*/ -static BACNET_BINARY_PV Binary_Output_Level[MAX_BINARY_OUTPUTS] - [BACNET_MAX_PRIORITY]; -/* Writable out-of-service allows others to play with our Present Value */ -/* without changing the physical output */ -static bool Out_Of_Service[MAX_BINARY_OUTPUTS]; - -/* These three arrays are used by the ReadPropertyMultiple handler */ -static const int32_t Binary_Output_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, - PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, PROP_PRIORITY_ARRAY, - PROP_RELINQUISH_DEFAULT, -1 }; - -static const int32_t Binary_Output_Properties_Optional[] = { PROP_DESCRIPTION, - PROP_ACTIVE_TEXT, PROP_INACTIVE_TEXT, -1 }; - -static const int32_t Binary_Output_Properties_Proprietary[] = { -1 }; - -void Binary_Output_Property_Lists( - const int32_t **pRequired, const int32_t **pOptional, const int32_t **pProprietary) -{ - if (pRequired) - *pRequired = Binary_Output_Properties_Required; - if (pOptional) - *pOptional = Binary_Output_Properties_Optional; - if (pProprietary) - *pProprietary = Binary_Output_Properties_Proprietary; - - return; -} - -void Binary_Output_Init(void) -{ - unsigned i, j; - static bool initialized = false; - - if (!initialized) { - initialized = true; - - /* initialize all the analog output priority arrays to NULL */ - for (i = 0; i < MAX_BINARY_OUTPUTS; i++) { - for (j = 0; j < BACNET_MAX_PRIORITY; j++) { - Binary_Output_Level[i][j] = BINARY_NULL; - } - } - } - - return; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need validate that the */ -/* given instance exists */ -bool Binary_Output_Valid_Instance(uint32_t object_instance) -{ - if (object_instance < MAX_BINARY_OUTPUTS) - return true; - - return false; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then count how many you have */ -unsigned Binary_Output_Count(void) -{ - return MAX_BINARY_OUTPUTS; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need to return the instance */ -/* that correlates to the correct index */ -uint32_t Binary_Output_Index_To_Instance(unsigned index) -{ - return index; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need to return the index */ -/* that correlates to the correct instance number */ -unsigned Binary_Output_Instance_To_Index(uint32_t object_instance) -{ - unsigned index = MAX_BINARY_OUTPUTS; - - if (object_instance < MAX_BINARY_OUTPUTS) - index = object_instance; - - return index; -} - -BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t object_instance) -{ - BACNET_BINARY_PV value = RELINQUISH_DEFAULT; - unsigned index = 0; - unsigned i = 0; - - index = Binary_Output_Instance_To_Index(object_instance); - if (index < MAX_BINARY_OUTPUTS) { - for (i = 0; i < BACNET_MAX_PRIORITY; i++) { - if (Binary_Output_Level[index][i] != BINARY_NULL) { - value = Binary_Output_Level[index][i]; - break; - } - } - } - - return value; -} - -bool Binary_Output_Out_Of_Service(uint32_t object_instance) -{ - bool value = false; - unsigned index = 0; - - index = Binary_Output_Instance_To_Index(object_instance); - if (index < MAX_BINARY_OUTPUTS) { - value = Out_Of_Service[index]; - } - - return value; -} - -/* note: the object name must be unique within this device */ - -bool Binary_Output_Object_Name( - uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) -{ - static char text[32] = ""; - bool status = false; - - if (object_instance == 0) - status = characterstring_init_ansi(object_name, "Led"); - else { - if (object_instance < MAX_BINARY_OUTPUTS) { - snprintf(text, sizeof(text), "BINARY OUTPUT %lu", - (unsigned long)object_instance); - status = characterstring_init_ansi(object_name, text); - } - } - return status; -} - -/* return apdu len, or BACNET_STATUS_ERROR on error */ -int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) -{ - int len = 0; - int apdu_len = 0; /* return value */ - BACNET_BIT_STRING bit_string; - BACNET_CHARACTER_STRING char_string; - BACNET_BINARY_PV present_value = BINARY_INACTIVE; - BACNET_POLARITY polarity = POLARITY_NORMAL; - unsigned object_index = 0; - unsigned i = 0; - bool state = false; - uint8_t *apdu = NULL; - - if ((rpdata == NULL) || (rpdata->application_data == NULL) || - (rpdata->application_data_len == 0)) { - return 0; - } - apdu = rpdata->application_data; - switch (rpdata->object_property) { - case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id( - &apdu[0], OBJECT_BINARY_OUTPUT, rpdata->object_instance); - break; - /* note: Name and Description don't have to be the same. - You could make Description writable and different */ - case PROP_OBJECT_NAME: - case PROP_DESCRIPTION: - Binary_Output_Object_Name(rpdata->object_instance, &char_string); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_OBJECT_TYPE: - apdu_len = - encode_application_enumerated(&apdu[0], OBJECT_BINARY_OUTPUT); - break; - case PROP_PRESENT_VALUE: - present_value = - Binary_Output_Present_Value(rpdata->object_instance); - apdu_len = encode_application_enumerated(&apdu[0], present_value); - break; - case PROP_STATUS_FLAGS: - /* note: see the details in the standard on how to use these */ - bitstring_init(&bit_string); - bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_EVENT_STATE: - /* note: see the details in the standard on how to use this */ - apdu_len = - encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); - break; - case PROP_OUT_OF_SERVICE: - object_index = - Binary_Output_Instance_To_Index(rpdata->object_instance); - state = Out_Of_Service[object_index]; - apdu_len = encode_application_boolean(&apdu[0], state); - break; - case PROP_POLARITY: - apdu_len = encode_application_enumerated(&apdu[0], polarity); - break; - case PROP_PRIORITY_ARRAY: - /* Array element zero is the number of elements in the array */ - if (rpdata->array_index == 0) - apdu_len = - encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { - object_index = - Binary_Output_Instance_To_Index(rpdata->object_instance); - for (i = 0; i < BACNET_MAX_PRIORITY; i++) { - /* FIXME: check if we have room before adding it to APDU */ - if (Binary_Output_Level[object_index][i] == BINARY_NULL) - len = encode_application_null(&apdu[apdu_len]); - else { - present_value = Binary_Output_Level[object_index][i]; - len = encode_application_enumerated( - &apdu[apdu_len], present_value); - } - /* add it if we have room */ - if ((apdu_len + len) < MAX_APDU) - apdu_len += len; - else { - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - break; - } - } - } else { - object_index = - Binary_Output_Instance_To_Index(rpdata->object_instance); - if (rpdata->array_index <= BACNET_MAX_PRIORITY) { - if (Binary_Output_Level[object_index][rpdata->array_index - - 1] == BINARY_NULL) - apdu_len = encode_application_null(&apdu[apdu_len]); - else { - present_value = - Binary_Output_Level[object_index] - [rpdata->array_index - 1]; - apdu_len = encode_application_enumerated( - &apdu[apdu_len], present_value); - } - } else { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; - apdu_len = BACNET_STATUS_ERROR; - } - } - - break; - case PROP_RELINQUISH_DEFAULT: - present_value = RELINQUISH_DEFAULT; - apdu_len = encode_application_enumerated(&apdu[0], present_value); - break; - case PROP_ACTIVE_TEXT: - characterstring_init_ansi(&char_string, "on"); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_INACTIVE_TEXT: - characterstring_init_ansi(&char_string, "off"); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - default: - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = BACNET_STATUS_ERROR; - break; - } - /* only array properties can have array options */ - if ((apdu_len >= 0) && (rpdata->object_property != PROP_PRIORITY_ARRAY) && - (rpdata->array_index != BACNET_ARRAY_ALL)) { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - apdu_len = BACNET_STATUS_ERROR; - } - - return apdu_len; -} - -/* returns true if successful */ -bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) -{ - bool status = false; /* return value */ - unsigned int object_index = 0; - unsigned int priority = 0; - BACNET_BINARY_PV level = BINARY_NULL; - int len = 0; - BACNET_APPLICATION_DATA_VALUE value = { 0 }; - - /* decode the some of the request */ - len = bacapp_decode_application_data( - wp_data->application_data, wp_data->application_data_len, &value); - /* FIXME: len < application_data_len: more data? */ - if (len < 0) { - /* error while decoding - a value larger than we can handle */ - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - return false; - } - if ((wp_data->object_property != PROP_PRIORITY_ARRAY) && - (wp_data->array_index != BACNET_ARRAY_ALL)) { - /* only array properties can have array options */ - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - return false; - } - switch (wp_data->object_property) { - case PROP_PRESENT_VALUE: - if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { - priority = wp_data->priority; - /* Command priority 6 is reserved for use by Minimum On/Off - algorithm and may not be used for other purposes in any - object. */ - if (priority && (priority <= BACNET_MAX_PRIORITY) && - (priority != 6 /* reserved */) && - (value.type.Enumerated <= MAX_BINARY_PV)) { - level = (BACNET_BINARY_PV)value.type.Enumerated; - object_index = Binary_Output_Instance_To_Index( - wp_data->object_instance); - priority--; - Binary_Output_Level[object_index][priority] = level; - /* Note: you could set the physical output here if we - are the highest priority. - However, if Out of Service is TRUE, then don't set the - physical output. This comment may apply to the - main loop (i.e. check out of service before changing - output) */ - status = true; - } else if (priority == 6) { - /* Command priority 6 is reserved for use by Minimum On/Off - algorithm and may not be used for other purposes in any - object. */ - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } else { - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_NULL); - if (status) { - level = BINARY_NULL; - object_index = Binary_Output_Instance_To_Index( - wp_data->object_instance); - priority = wp_data->priority; - if (priority && (priority <= BACNET_MAX_PRIORITY)) { - priority--; - Binary_Output_Level[object_index][priority] = level; - /* Note: you could set the physical output here to the - next highest priority, or to the relinquish default - if no priorities are set. However, if Out of Service - is TRUE, then don't set the physical output. This - comment may apply to the - main loop (i.e. check out of service before changing - output) */ - } else { - status = false; - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - } - break; - case PROP_OUT_OF_SERVICE: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_BOOLEAN); - if (status) { - object_index = - Binary_Output_Instance_To_Index(wp_data->object_instance); - Out_Of_Service[object_index] = value.type.Boolean; - } - break; - case PROP_OBJECT_IDENTIFIER: - case PROP_OBJECT_NAME: - case PROP_OBJECT_TYPE: - case PROP_STATUS_FLAGS: - case PROP_RELIABILITY: - case PROP_EVENT_STATE: - case PROP_POLARITY: - case PROP_PRIORITY_ARRAY: - case PROP_RELINQUISH_DEFAULT: - case PROP_ACTIVE_TEXT: - case PROP_INACTIVE_TEXT: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - break; - default: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - break; - } - - return status; -} diff --git a/ports/esp32/src/bo.h b/ports/esp32/src/bo.h deleted file mode 100644 index 82182db3..00000000 --- a/ports/esp32/src/bo.h +++ /dev/null @@ -1,118 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* SPDX-License-Identifier: MIT -* -*********************************************************************/ -#ifndef BO_H -#define BO_H - -#include -#include -#include "bacnet/bacdef.h" -#include "bacnet/bacerror.h" -#include "bacnet/rp.h" -#include "bacnet/wp.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void Binary_Output_Init( - void); - - void Binary_Output_Property_Lists( - const int32_t **pRequired, - const int32_t **pOptional, - const int32_t **pProprietary); - - bool Binary_Output_Valid_Instance( - uint32_t object_instance); - unsigned Binary_Output_Count( - void); - uint32_t Binary_Output_Index_To_Instance( - unsigned index); - unsigned Binary_Output_Instance_To_Index( - uint32_t instance); - bool Binary_Output_Object_Instance_Add( - uint32_t instance); - - bool Binary_Output_Object_Name( - uint32_t object_instance, - BACNET_CHARACTER_STRING * object_name); - bool Binary_Output_Name_Set( - uint32_t object_instance, - char *new_name); - - const char *Binary_Output_Description( - uint32_t instance); - bool Binary_Output_Description_Set( - uint32_t instance, - const char *new_name); - - const char *Binary_Output_Inactive_Text( - uint32_t instance); - bool Binary_Output_Inactive_Text_Set( - uint32_t instance, - char *new_name); - char *Binary_Output_Active_Text( - uint32_t instance); - bool Binary_Output_Active_Text_Set( - uint32_t instance, - char *new_name); - - BACNET_BINARY_PV Binary_Output_Present_Value( - uint32_t instance); - bool Binary_Output_Present_Value_Set( - uint32_t instance, - BACNET_BINARY_PV binary_value, - unsigned priority); - bool Binary_Output_Present_Value_Relinquish( - uint32_t instance, - unsigned priority); - unsigned Binary_Output_Present_Value_Priority( - uint32_t object_instance); - - BACNET_POLARITY Binary_Output_Polarity( - uint32_t instance); - bool Binary_Output_Polarity_Set( - uint32_t object_instance, - BACNET_POLARITY polarity); - - bool Binary_Output_Out_Of_Service( - uint32_t instance); - void Binary_Output_Out_Of_Service_Set( - uint32_t object_instance, - bool value); - - BACNET_BINARY_PV Binary_Output_Relinquish_Default( - uint32_t object_instance); - bool Binary_Output_Relinquish_Default_Set( - uint32_t object_instance, - BACNET_BINARY_PV value); - - bool Binary_Output_Encode_Value_List( - uint32_t object_instance, - BACNET_PROPERTY_VALUE * value_list); - bool Binary_Output_Change_Of_Value( - uint32_t instance); - void Binary_Output_Change_Of_Value_Clear( - uint32_t instance); - - int Binary_Output_Read_Property( - BACNET_READ_PROPERTY_DATA * rpdata); - bool Binary_Output_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data); - - uint32_t Binary_Output_Create( - uint32_t object_instance); - bool Binary_Output_Delete( - uint32_t object_instance); - void Binary_Output_Cleanup( - void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/ports/esp32/src/bvlc.c b/ports/esp32/src/bvlc.c new file mode 100644 index 00000000..5549786b --- /dev/null +++ b/ports/esp32/src/bvlc.c @@ -0,0 +1,164 @@ +/** + * @file + * @brief BACnet Virtual Link Control implementation for the PlatformIO ESP32 + * port + * @author Kato Gangstad + */ + +#include +#include +#include + +#include "bip.h" +#include "bvlc.h" +#include "bacnet/bacint.h" + +#define BVLC_RESULT 0 +#define BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE 1 +#define BVLC_READ_BROADCAST_DIST_TABLE 2 +#define BVLC_READ_BROADCAST_DIST_TABLE_ACK 3 +#define BVLC_FORWARDED_NPDU 4 +#define BVLC_REGISTER_FOREIGN_DEVICE 5 +#define BVLC_READ_FOREIGN_DEVICE_TABLE 6 +#define BVLC_READ_FOREIGN_DEVICE_TABLE_ACK 7 +#define BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY 8 +#define BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK 9 +#define BVLC_ORIGINAL_UNICAST_NPDU 10 +#define BVLC_ORIGINAL_BROADCAST_NPDU 11 +#define BVLC_SECURE_BVLL 12 + +#define BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK 0x0010 +#define BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK 0x0020 +#define BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK 0X0030 +#define BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK 0x0040 +#define BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK 0x0050 +#define BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK 0x0060 + +static BACNET_BVLC_RESULT BVLC_Result_Code = BVLC_RESULT_SUCCESSFUL_COMPLETION; +static BACNET_BVLC_FUNCTION BVLC_Function_Code = BVLC_RESULT; + +/** + * @brief Encode a BVLC result message + * @param pdu destination buffer, or NULL for length-only use + * @param result_code BVLC result code to encode + * @return encoded BVLC message length + */ +static int bvlc_encode_bvlc_result(uint8_t *pdu, BACNET_BVLC_RESULT result_code) +{ + if (pdu) { + pdu[0] = BVLL_TYPE_BACNET_IP; + pdu[1] = BVLC_RESULT; + encode_unsigned16(&pdu[2], 6); + encode_unsigned16(&pdu[4], (uint16_t)result_code); + } + + return 6; +} + +/** + * @brief Send a raw BVLC frame to the destination host + * @param dest_addr destination IPv4 address + * @param dest_port destination UDP port + * @param mtu raw BVLC frame buffer + * @param mtu_len frame length in bytes + * @return number of bytes sent, or -1 on error + */ +static int bvlc_send_mpdu( + const uint8_t *dest_addr, + const uint16_t *dest_port, + uint8_t *mtu, + uint16_t mtu_len) +{ + int bytes_sent = 0; + + if (!bip_valid()) { + return -1; + } + + bytes_sent = bip_socket_send(dest_addr, *dest_port, mtu, mtu_len); + + return bytes_sent; +} + +/** + * @brief Send a BVLC result response + * @param dest_addr destination IPv4 address + * @param dest_port destination UDP port + * @param result_code BVLC result code to report + */ +static void bvlc_send_result( + const uint8_t *dest_addr, + const uint16_t *dest_port, + BACNET_BVLC_RESULT result_code) +{ + uint8_t mtu[BIP_MPDU_MAX] = { 0 }; + uint16_t mtu_len = 0; + + mtu_len = (uint16_t)bvlc_encode_bvlc_result(&mtu[0], result_code); + bvlc_send_mpdu(dest_addr, dest_port, mtu, mtu_len); +} + +/** + * @brief Handle non-BBMD BVLC functions for this port + * @param addr source IPv4 address + * @param port source UDP port + * @param npdu received BVLC frame buffer + * @param received_bytes frame length in bytes + * @return non-zero when the frame was consumed by BVLC handling + */ +uint16_t bvlc_for_non_bbmd( + uint8_t *addr, uint16_t *port, uint8_t *npdu, uint16_t received_bytes) +{ + uint16_t result_code = 0; + + if (received_bytes >= 1) { + BVLC_Function_Code = npdu[1]; + switch (BVLC_Function_Code) { + case BVLC_RESULT: + if (received_bytes >= 6) { + (void)decode_unsigned16(&npdu[4], &result_code); + BVLC_Result_Code = (BACNET_BVLC_RESULT)result_code; + fprintf(stderr, "BVLC: Result Code=%d\n", BVLC_Result_Code); + result_code = 0; + } + break; + case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE: + result_code = + BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK; + break; + case BVLC_READ_BROADCAST_DIST_TABLE: + result_code = BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK; + break; + case BVLC_REGISTER_FOREIGN_DEVICE: + result_code = BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK; + break; + case BVLC_READ_FOREIGN_DEVICE_TABLE: + result_code = BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK; + break; + case BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY: + result_code = BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK; + break; + case BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK: + result_code = BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK; + break; + default: + break; + } + } + + if (result_code > 0) { + bvlc_send_result(addr, port, result_code); + fprintf(stderr, "BVLC: NAK code=%d\n", result_code); + } + + return result_code; +} + +/** + * @brief Get the last decoded BVLC function code + * @return BVLC function code + */ +BACNET_BVLC_FUNCTION pico_bvlc_get_function_code(void) +{ + return BVLC_Function_Code; +} diff --git a/ports/esp32/src/bvlc.h b/ports/esp32/src/bvlc.h new file mode 100644 index 00000000..239a00b2 --- /dev/null +++ b/ports/esp32/src/bvlc.h @@ -0,0 +1,46 @@ +/** + * @file + * @brief BACnet Virtual Link Control interfaces for the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#ifndef M5STAMPLC_BVLC_H +#define M5STAMPLC_BVLC_H + +#include + +#include "bacnet/datalink/bvlc.h" + +#define BACNET_BVLC_RESULT uint8_t +#define BACNET_BVLC_FUNCTION uint8_t + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BIP_MPDU_MAX +#define BIP_MPDU_MAX 1506 +#endif + +/** + * @brief Handle non-BBMD BVLC functions for a received frame + * @param addr source IPv4 address + * @param port source UDP port + * @param npdu received frame buffer + * @param received_bytes frame length in bytes + * @return non-zero when the frame was consumed by BVLC handling + */ +uint16_t bvlc_for_non_bbmd( + uint8_t *addr, uint16_t *port, uint8_t *npdu, uint16_t received_bytes); + +/** + * @brief Get the most recently decoded BVLC function code + * @return BVLC function code + */ +BACNET_BVLC_FUNCTION pico_bvlc_get_function_code(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/esp32/src/device.c b/ports/esp32/src/device.c deleted file mode 100644 index 2281d752..00000000 --- a/ports/esp32/src/device.c +++ /dev/null @@ -1,1753 +0,0 @@ -/************************************************************************** - * - * Copyright (C) 2005,2006,2009 Steve Karg - * - * SPDX-License-Identifier: MIT - * - *********************************************************************/ - -/** @file device.c Base "class" for handling all BACnet objects belonging - * to a BACnet device, as well as Device-specific properties. */ - -#include -#include -#include /* for memmove */ -#include /* for timezone, localtime */ -#include "bacnet/datalink/datalink.h" -#include "bacnet/bacdef.h" -#include "bacnet/bacdcode.h" -#include "bacnet/bacenum.h" -#include "bacnet/bacapp.h" -#include "bacnet/config.h" /* the custom stuff */ -#include "bacnet/apdu.h" -#include "bacnet/wp.h" /* WriteProperty handling */ -#include "bacnet/rp.h" /* ReadProperty handling */ -#include "bacnet/dcc.h" /* DeviceCommunicationControl handling */ -#include "bacnet/version.h" -#include "bacnet/basic/object/device.h" /* me */ -#include "bacnet/basic/services.h" -#include "../lib/stack/address.h" -/* os specfic includes */ -#include "bacnet/basic/sys/mstimer.h" -/* include the device object */ -#include "bacnet/basic/object/device.h" -#include "bacnet/basic/object/ai.h" -#include "bacnet/basic/object/bo.h" - -#if defined(INTRINSIC_REPORTING) -#include "bacnet/basic/object/nc.h" -#endif /* defined(INTRINSIC_REPORTING) */ -#include "bacnet/basic/object/bacfile.h" -#if defined(BAC_UCI) -#include "bacnet/basic/ucix/ucix.h" -#endif /* defined(BAC_UCI) */ - -/* Not included in time.h as specified by The Open Group */ -/* Difference from UTC and local standard time */ -long int timezone; - -/* local forward (semi-private) and external prototypes */ -int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata); -bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data); -extern int Routed_Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata); -extern bool Routed_Device_Write_Property_Local( - BACNET_WRITE_PROPERTY_DATA *wp_data); - -/* may be overridden by outside table */ -static object_functions_t *Object_Table; - -static object_functions_t My_Object_Table[] = { - { OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, - Device_Count, Device_Index_To_Instance, - Device_Valid_Object_Instance_Number, Device_Object_Name, - Device_Read_Property_Local, Device_Write_Property_Local, - Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */, - NULL /* Value_Lists */, NULL, NULL, NULL /* Intrinsic Reporting */ }, - { OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count, - Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, - Analog_Input_Object_Name, Analog_Input_Read_Property, - Analog_Input_Write_Property, Analog_Input_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, - Analog_Input_Encode_Value_List, Analog_Input_Change_Of_Value, - Analog_Input_Change_Of_Value_Clear, Analog_Input_Intrinsic_Reporting }, - { OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, - Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, - Binary_Output_Object_Name, Binary_Output_Read_Property, - Binary_Output_Write_Property, Binary_Output_Property_Lists, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */ }, - { MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, - NULL /* Index_To_Instance */, NULL /* Valid_Instance */, - NULL /* Object_Name */, NULL /* Read_Property */, - NULL /* Write_Property */, NULL /* Property_Lists */, - NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, - NULL /* COV */, NULL /* COV Clear */, - NULL /* Intrinsic Reporting */ } -}; -/** Glue function to let the Device object, when called by a handler, - * lookup which Object type needs to be invoked. - * @ingroup ObjHelpers - * @param Object_Type [in] The type of BACnet Object the handler wants to - * access. - * @return Pointer to the group of object helper functions that implement this - * type of Object. - */ -static struct object_functions *Device_Objects_Find_Functions( - BACNET_OBJECT_TYPE Object_Type) -{ - struct object_functions *pObject = NULL; - - pObject = Object_Table; - while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { - /* handle each object type */ - if (pObject->Object_Type == Object_Type) { - return (pObject); - } - pObject++; - } - - return (NULL); -} - -/** Try to find a rr_info_function helper function for the requested object - * type. - * @ingroup ObjIntf - * - * @param object_type [in] The type of BACnet Object the handler wants to - * access. - * @return Pointer to the object helper function that implements the - * ReadRangeInfo function, Object_RR_Info, for this type of Object on - * success, else a NULL pointer if the type of Object isn't supported - * or doesn't have a ReadRangeInfo function. - */ -rr_info_function Device_Objects_RR_Info(BACNET_OBJECT_TYPE object_type) -{ - struct object_functions *pObject = NULL; - - pObject = Device_Objects_Find_Functions(object_type); - return (pObject != NULL ? pObject->Object_RR_Info : NULL); -} - -/** For a given object type, returns the special property list. - * This function is used for ReadPropertyMultiple calls which want - * just Required, just Optional, or All properties. - * @ingroup ObjIntf - * - * @param object_type [in] The desired BACNET_OBJECT_TYPE whose properties - * are to be listed. - * @param pPropertyList [out] Reference to the structure which will, on return, - * list, separately, the Required, Optional, and Proprietary object - * properties with their counts. - */ -void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - struct special_property_list_t *pPropertyList) -{ - struct object_functions *pObject = NULL; - - (void)object_instance; - pPropertyList->Required.pList = NULL; - pPropertyList->Optional.pList = NULL; - pPropertyList->Proprietary.pList = NULL; - - /* If we can find an entry for the required object type - * and there is an Object_List_RPM fn ptr then call it - * to populate the pointers to the individual list counters. - */ - - pObject = Device_Objects_Find_Functions(object_type); - if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) { - pObject->Object_RPM_List(&pPropertyList->Required.pList, - &pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList); - } - - /* Fetch the counts if available otherwise zero them */ - pPropertyList->Required.count = pPropertyList->Required.pList == NULL - ? 0 - : property_list_count(pPropertyList->Required.pList); - - pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL - ? 0 - : property_list_count(pPropertyList->Optional.pList); - - pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL - ? 0 - : property_list_count(pPropertyList->Proprietary.pList); - - return; -} - -/** Commands a Device re-initialization, to a given state. - * The request's password must match for the operation to succeed. - * This implementation provides a framework, but doesn't - * actually *DO* anything. - * @note You could use a mix of states and passwords to multiple outcomes. - * @note You probably want to restart *after* the simple ack has been sent - * from the return handler, so just set a local flag here. - * @ingroup ObjIntf - * - * @param rd_data [in,out] The information from the RD request. - * On failure, the error class and code will be set. - * @return True if succeeds (password is correct), else False. - */ -bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data) -{ - bool status = false; - - if (characterstring_ansi_same(&rd_data->password, "Jesus")) { - switch (rd_data->state) { - case BACNET_REINIT_COLDSTART: - case BACNET_REINIT_WARMSTART: - dcc_set_status_duration(COMMUNICATION_ENABLE, 0); - break; - case BACNET_REINIT_STARTBACKUP: - break; - case BACNET_REINIT_ENDBACKUP: - break; - case BACNET_REINIT_STARTRESTORE: - break; - case BACNET_REINIT_ENDRESTORE: - break; - case BACNET_REINIT_ABORTRESTORE: - break; - default: - break; - } - /* Note: you could use a mix of state - and password to multiple things */ - /* note: you probably want to restart *after* the - simple ack has been sent from the return handler - so just set a flag from here */ - status = true; - } else { - rd_data->error_class = ERROR_CLASS_SECURITY; - rd_data->error_code = ERROR_CODE_PASSWORD_FAILURE; - } - - return status; -} - -/* These three arrays are used by the ReadPropertyMultiple handler */ -static const int32_t Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, - PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, - PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, - PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, - PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED, - PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST, - PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, - PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING, - PROP_DATABASE_REVISION, -1 }; - -static const int32_t Device_Properties_Optional[] = { -#if defined(BACDL_MSTP) - PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, -#endif - PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE, - PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS, -#if defined(BACNET_TIME_MASTER) - PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_TIME_SYNCHRONIZATION_INTERVAL, - PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET, -#endif - -1 -}; - -static const int32_t Device_Properties_Proprietary[] = { -1 }; - -void Device_Property_Lists( - const int32_t **pRequired, const int32_t **pOptional, const int32_t **pProprietary) -{ - if (pRequired) - *pRequired = Device_Properties_Required; - if (pOptional) - *pOptional = Device_Properties_Optional; - if (pProprietary) - *pProprietary = Device_Properties_Proprietary; - - return; -} - -/* note: you really only need to define variables for - properties that are writable or that may change. - The properties that are constant can be hard coded - into the read-property encoding. */ - -static uint32_t Object_Instance_Number = 260001; -static BACNET_CHARACTER_STRING My_Object_Name; -static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; -static char *Vendor_Name = BACNET_VENDOR_NAME; -static uint16_t Vendor_Identifier = BACNET_VENDOR_ID; -static char Model_Name[MAX_DEV_MOD_LEN + 1] = "ESP32"; -static char Application_Software_Version[MAX_DEV_VER_LEN + 1] = "1.0"; -static char Location[MAX_DEV_LOC_LEN + 1] = "FR"; -static char Description[MAX_DEV_DESC_LEN + 1] = - "EPS32 by F. Chaxel, Stack S. Karg"; -static char *BACnet_Version = "0.8.2"; -/* static uint8_t Protocol_Version = 1; - constant, not settable */ -/* static uint8_t Protocol_Revision = 4; - constant, not settable */ -/* Protocol_Services_Supported - dynamically generated */ -/* Protocol_Object_Types_Supported - in RP encoding */ -/* Object_List - dynamically generated */ -/* static BACNET_SEGMENTATION Segmentation_Supported = SEGMENTATION_NONE; */ -/* static uint8_t Max_Segments_Accepted = 0; */ -/* VT_Classes_Supported */ -/* Active_VT_Sessions */ -static BACNET_TIME Local_Time; /* rely on OS, if there is one */ -static BACNET_DATE Local_Date; /* rely on OS, if there is one */ -/* NOTE: BACnet UTC Offset is inverse of common practice. - If your UTC offset is -5hours of GMT, - then BACnet UTC offset is +5hours. - BACnet UTC offset is expressed in minutes. */ -static int32_t UTC_Offset = 5 * 60; -static bool Daylight_Savings_Status = false; /* rely on OS */ -#if defined(BACNET_TIME_MASTER) -static bool Align_Intervals; -static uint32_t Interval_Minutes; -static uint32_t Interval_Offset_Minutes; -/* Time_Synchronization_Recipients */ -#endif -/* List_Of_Session_Keys */ -/* Max_Master - rely on MS/TP subsystem, if there is one */ -/* Max_Info_Frames - rely on MS/TP subsystem, if there is one */ -/* Device_Address_Binding - required, but relies on binding cache */ -static uint32_t Database_Revision = 0; -/* Configuration_Files */ -/* Last_Restore_Time */ -/* Backup_Failure_Timeout */ -/* Active_COV_Subscriptions */ -/* Slave_Proxy_Enable */ -/* Manual_Slave_Address_Binding */ -/* Auto_Slave_Discovery */ -/* Slave_Address_Binding */ -/* Profile_Name */ - -unsigned Device_Count(void) -{ - return 1; -} - -uint32_t Device_Index_To_Instance(unsigned index) -{ - index = index; - return Object_Instance_Number; -} - -/* methods to manipulate the data */ - -/** Return the Object Instance number for our (single) Device Object. - * This is a key function, widely invoked by the handler code, since - * it provides "our" (ie, local) address. - * @ingroup ObjIntf - * @return The Instance number used in the BACNET_OBJECT_ID for the Device. - */ -uint32_t Device_Object_Instance_Number(void) -{ -#ifdef BAC_ROUTING - return Routed_Device_Object_Instance_Number(); -#else - return Object_Instance_Number; -#endif -} - -bool Device_Set_Object_Instance_Number(uint32_t object_id) -{ - bool status = true; /* return value */ - - if (object_id <= BACNET_MAX_INSTANCE) { - /* Make the change and update the database revision */ - Object_Instance_Number = object_id; - Device_Inc_Database_Revision(); - } else - status = false; - - return status; -} - -bool Device_Valid_Object_Instance_Number(uint32_t object_id) -{ - return (Object_Instance_Number == object_id); -} - -bool Device_Object_Name( - uint32_t object_instance, BACNET_CHARACTER_STRING *object_name) -{ - bool status = false; - - if (object_instance == Object_Instance_Number) { - status = characterstring_copy(object_name, &My_Object_Name); - } - - return status; -} - -bool Device_Set_Object_Name(const BACNET_CHARACTER_STRING *object_name) -{ - bool status = false; /*return value */ - - if (!characterstring_same(&My_Object_Name, object_name)) { - /* Make the change and update the database revision */ - status = characterstring_copy(&My_Object_Name, object_name); - Device_Inc_Database_Revision(); - } - - return status; -} - -bool Device_Object_Name_ANSI_Init(const char *value) -{ - return characterstring_init_ansi(&My_Object_Name, value); -} - -BACNET_DEVICE_STATUS Device_System_Status(void) -{ - return System_Status; -} - -int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local) -{ - int result = 0; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */ - - /* We limit the options available depending on whether the source is - * internal or external. */ - if (local) { - switch (status) { - case STATUS_OPERATIONAL: - case STATUS_OPERATIONAL_READ_ONLY: - case STATUS_DOWNLOAD_REQUIRED: - case STATUS_DOWNLOAD_IN_PROGRESS: - case STATUS_NON_OPERATIONAL: - System_Status = status; - break; - - /* Don't support backup at present so don't allow setting */ - case STATUS_BACKUP_IN_PROGRESS: - result = -2; - break; - - default: - result = -1; - break; - } - } else { - switch (status) { - /* Allow these for the moment as a way to easily alter - * overall device operation. The lack of password protection - * or other authentication makes allowing writes to this - * property a risky facility to provide. - */ - case STATUS_OPERATIONAL: - case STATUS_OPERATIONAL_READ_ONLY: - case STATUS_NON_OPERATIONAL: - System_Status = status; - break; - - /* Don't allow outsider set this - it should probably - * be set if the device config is incomplete or - * corrupted or perhaps after some sort of operator - * wipe operation. - */ - case STATUS_DOWNLOAD_REQUIRED: - /* Don't allow outsider set this - it should be set - * internally at the start of a multi packet download - * perhaps indirectly via PT or WF to a config file. - */ - case STATUS_DOWNLOAD_IN_PROGRESS: - /* Don't support backup at present so don't allow setting */ - case STATUS_BACKUP_IN_PROGRESS: - result = -2; - break; - - default: - result = -1; - break; - } - } - - return (result); -} - -const char *Device_Vendor_Name(void) -{ - return Vendor_Name; -} - -/** Returns the Vendor ID for this Device. - * See the assignments at - * http://www.bacnet.org/VendorID/BACnet%20Vendor%20IDs.htm - * @return The Vendor ID of this Device. - */ -uint16_t Device_Vendor_Identifier(void) -{ - return Vendor_Identifier; -} - -void Device_Set_Vendor_Identifier(uint16_t vendor_id) -{ - Vendor_Identifier = vendor_id; -} - -const char *Device_Model_Name(void) -{ - return Model_Name; -} - -bool Device_Set_Model_Name(const char *name, size_t length) -{ - bool status = false; /*return value */ - - if (length < sizeof(Model_Name)) { - memmove(Model_Name, name, length); - Model_Name[length] = 0; - status = true; - } - - return status; -} - -const char *Device_Firmware_Revision(void) -{ - return BACnet_Version; -} - -const char *Device_Application_Software_Version(void) -{ - return Application_Software_Version; -} - -bool Device_Set_Application_Software_Version(const char *name, size_t length) -{ - bool status = false; /*return value */ - - if (length < sizeof(Application_Software_Version)) { - memmove(Application_Software_Version, name, length); - Application_Software_Version[length] = 0; - status = true; - } - - return status; -} - -const char *Device_Description(void) -{ - return Description; -} - -bool Device_Set_Description(const char *name, size_t length) -{ - bool status = false; /*return value */ - - if (length < sizeof(Description)) { - memmove(Description, name, length); - Description[length] = 0; - status = true; - } - - return status; -} - -const char *Device_Location(void) -{ - return Location; -} - -bool Device_Set_Location(const char *name, size_t length) -{ - bool status = false; /*return value */ - - if (length < sizeof(Location)) { - memmove(Location, name, length); - Location[length] = 0; - status = true; - } - - return status; -} - -uint8_t Device_Protocol_Version(void) -{ - return BACNET_PROTOCOL_VERSION; -} - -uint8_t Device_Protocol_Revision(void) -{ - return BACNET_PROTOCOL_REVISION; -} - -BACNET_SEGMENTATION Device_Segmentation_Supported(void) -{ - return SEGMENTATION_NONE; -} - -uint32_t Device_Database_Revision(void) -{ - return Database_Revision; -} - -void Device_Set_Database_Revision(uint32_t revision) -{ - Database_Revision = revision; -} - -/* - * Shortcut for incrementing database revision as this is potentially - * the most common operation if changing object names and ids is - * implemented. - */ -void Device_Inc_Database_Revision(void) -{ - Database_Revision++; -} - -/** Get the total count of objects supported by this Device Object. - * @note Since many network clients depend on the object list - * for discovery, it must be consistent! - * @return The count of objects, for all supported Object types. - */ -unsigned Device_Object_List_Count(void) -{ - unsigned count = 0; /* number of objects */ - struct object_functions *pObject = NULL; - - /* initialize the default return values */ - pObject = Object_Table; - while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { - if (pObject->Object_Count) { - count += pObject->Object_Count(); - } - pObject++; - } - - return count; -} - -/** Lookup the Object at the given array index in the Device's Object List. - * Even though we don't keep a single linear array of objects in the Device, - * this method acts as though we do and works through a virtual, concatenated - * array of all of our object type arrays. - * - * @param array_index [in] The desired array index (1 to N) - * @param object_type [out] The object's type, if found. - * @param instance [out] The object's instance number, if found. - * @return True if found, else false. - */ -bool Device_Object_List_Identifier( - uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance) -{ - bool status = false; - uint32_t count = 0; - uint32_t object_index = 0; - uint32_t temp_index = 0; - struct object_functions *pObject = NULL; - - /* array index zero is length - so invalid */ - if (array_index == 0) { - return status; - } - object_index = array_index - 1; - /* initialize the default return values */ - pObject = Object_Table; - while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { - if (pObject->Object_Count) { - object_index -= count; - count = pObject->Object_Count(); - if (object_index < count) { - /* Use the iterator function if available otherwise - * look for the index to instance to get the ID */ - if (pObject->Object_Iterator) { - /* First find the first object */ - temp_index = pObject->Object_Iterator(~(unsigned)0); - /* Then step through the objects to find the nth */ - while (object_index != 0) { - temp_index = pObject->Object_Iterator(temp_index); - object_index--; - } - /* set the object_index up before falling through to next - * bit */ - object_index = temp_index; - } - if (pObject->Object_Index_To_Instance) { - *object_type = pObject->Object_Type; - *instance = pObject->Object_Index_To_Instance(object_index); - status = true; - break; - } - } - } - pObject++; - } - - return status; -} - -/** Determine if we have an object with the given object_name. - * If the object_type and object_instance pointers are not null, - * and the lookup succeeds, they will be given the resulting values. - * @param object_name [in] The desired Object Name to look for. - * @param object_type [out] The BACNET_OBJECT_TYPE of the matching Object. - * @param object_instance [out] The object instance number of the matching - * Object. - * @return True on success or else False if not found. - */ -bool Device_Valid_Object_Name(const BACNET_CHARACTER_STRING *object_name1, - BACNET_OBJECT_TYPE *object_type, - uint32_t *object_instance) -{ - bool found = false; - BACNET_OBJECT_TYPE type = OBJECT_NONE; - uint32_t instance; - uint32_t max_objects = 0, i = 0; - bool check_id = false; - BACNET_CHARACTER_STRING object_name2; - struct object_functions *pObject = NULL; - - max_objects = Device_Object_List_Count(); - for (i = 1; i <= max_objects; i++) { - check_id = Device_Object_List_Identifier(i, &type, &instance); - if (check_id) { - pObject = Device_Objects_Find_Functions(type); - if ((pObject != NULL) && (pObject->Object_Name != NULL) && - (pObject->Object_Name(instance, &object_name2) && - characterstring_same(object_name1, &object_name2))) { - found = true; - if (object_type) { - *object_type = type; - } - if (object_instance) { - *object_instance = instance; - } - break; - } - } - } - - return found; -} - -/** Determine if we have an object of this type and instance number. - * @param object_type [in] The desired BACNET_OBJECT_TYPE - * @param object_instance [in] The object instance number to be looked up. - * @return True if found, else False if no such Object in this device. - */ -bool Device_Valid_Object_Id( - BACNET_OBJECT_TYPE object_type, uint32_t object_instance) -{ - bool status = false; /* return value */ - struct object_functions *pObject = NULL; - - pObject = Device_Objects_Find_Functions(object_type); - if ((pObject != NULL) && (pObject->Object_Valid_Instance != NULL)) { - status = pObject->Object_Valid_Instance(object_instance); - } - - return status; -} - -/** Copy a child object's object_name value, given its ID. - * @param object_type [in] The BACNET_OBJECT_TYPE of the child Object. - * @param object_instance [in] The object instance number of the child Object. - * @param object_name [out] The Object Name found for this child Object. - * @return True on success or else False if not found. - */ -bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_CHARACTER_STRING *object_name) -{ - struct object_functions *pObject = NULL; - bool found = false; - - pObject = Device_Objects_Find_Functions(object_type); - if ((pObject != NULL) && (pObject->Object_Name != NULL)) { - found = pObject->Object_Name(object_instance, object_name); - } - - return found; -} - -static void Update_Current_Time(void) -{ - struct tm *tblock = NULL; -#if defined(_MSC_VER) - time_t tTemp; -#else - struct timeval tv; -#endif -/* -struct tm - -int tm_sec Seconds [0,60]. -int tm_min Minutes [0,59]. -int tm_hour Hour [0,23]. -int tm_mday Day of month [1,31]. -int tm_mon Month of year [0,11]. -int tm_year Years since 1900. -int tm_wday Day of week [0,6] (Sunday =0). -int tm_yday Day of year [0,365]. -int tm_isdst Daylight Savings flag. -*/ -#if defined(_MSC_VER) - time(&tTemp); - tblock = (struct tm *)localtime(&tTemp); -#else - if (gettimeofday(&tv, NULL) == 0) { - tblock = (struct tm *)localtime((const time_t *)&tv.tv_sec); - } -#endif - - if (tblock) { - datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900, - (uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday); -#if !defined(_MSC_VER) - datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, - (uint8_t)(tv.tv_usec / 10000)); -#else - datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, - (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0); -#endif - if (tblock->tm_isdst) { - Daylight_Savings_Status = true; - } else { - Daylight_Savings_Status = false; - } - /* note: timezone is declared in stdlib. */ - UTC_Offset = timezone / 60; - } else { - datetime_date_wildcard_set(&Local_Date); - datetime_time_wildcard_set(&Local_Time); - Daylight_Savings_Status = false; - } -} - -void Device_getCurrentDateTime(BACNET_DATE_TIME *DateTime) -{ - Update_Current_Time(); - - DateTime->date = Local_Date; - DateTime->time = Local_Time; -} - -int32_t Device_UTC_Offset(void) -{ - Update_Current_Time(); - - return UTC_Offset; -} - -void Device_UTC_Offset_Set(int16_t offset) -{ - UTC_Offset = offset; -} - -bool Device_Daylight_Savings_Status(void) -{ - return Daylight_Savings_Status; -} - -#if defined(BACNET_TIME_MASTER) -/** - * Sets the time sync interval in minutes - * - * @param flag - * This property, of type BOOLEAN, specifies whether (TRUE) - * or not (FALSE) clock-aligned periodic time synchronization is - * enabled. If periodic time synchronization is enabled and the - * time synchronization interval is a factor of (divides without - * remainder) an hour or day, then the beginning of the period - * specified for time synchronization shall be aligned to the hour or - * day, respectively. If this property is present, it shall be writable. - */ -bool Device_Align_Intervals_Set(bool flag) -{ - Align_Intervals = flag; - - return true; -} - -bool Device_Align_Intervals(void) -{ - return Align_Intervals; -} - -/** - * Sets the time sync interval in minutes - * - * @param minutes - * This property, of type Unsigned, specifies the periodic - * interval in minutes at which TimeSynchronization and - * UTCTimeSynchronization requests shall be sent. If this - * property has a value of zero, then periodic time synchronization is - * disabled. If this property is present, it shall be writable. - */ -bool Device_Time_Sync_Interval_Set(uint32_t minutes) -{ - Interval_Minutes = minutes; - - return true; -} - -uint32_t Device_Time_Sync_Interval(void) -{ - return Interval_Minutes; -} - -/** - * Sets the time sync interval offset value. - * - * @param minutes - * This property, of type Unsigned, specifies the offset in - * minutes from the beginning of the period specified for time - * synchronization until the actual time synchronization requests - * are sent. The offset used shall be the value of Interval_Offset - * modulo the value of Time_Synchronization_Interval; - * e.g., if Interval_Offset has the value 31 and - * Time_Synchronization_Interval is 30, the offset used shall be 1. - * Interval_Offset shall have no effect if Align_Intervals is - * FALSE. If this property is present, it shall be writable. - */ -bool Device_Interval_Offset_Set(uint32_t minutes) -{ - Interval_Offset_Minutes = minutes; - - return true; -} - -uint32_t Device_Interval_Offset(void) -{ - return Interval_Offset_Minutes; -} -#endif - -/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or - BACNET_STATUS_ABORT for abort message */ -int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata) -{ - int apdu_len = 0; /* return value */ - int len = 0; /* apdu len intermediate value */ - BACNET_BIT_STRING bit_string = { 0 }; - BACNET_CHARACTER_STRING char_string = { 0 }; - uint32_t i = 0; - BACNET_OBJECT_TYPE object_type = OBJECT_NONE; - uint32_t instance = 0; - uint32_t count = 0; - uint8_t *apdu = NULL; - struct object_functions *pObject = NULL; - bool found = false; - uint16_t apdu_max = 0; - - if ((rpdata == NULL) || (rpdata->application_data == NULL) || - (rpdata->application_data_len == 0)) { - return 0; - } - apdu = rpdata->application_data; - apdu_max = rpdata->application_data_len; - switch (rpdata->object_property) { - case PROP_OBJECT_IDENTIFIER: - apdu_len = encode_application_object_id( - &apdu[0], OBJECT_DEVICE, Object_Instance_Number); - break; - case PROP_OBJECT_NAME: - apdu_len = - encode_application_character_string(&apdu[0], &My_Object_Name); - break; - case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE); - break; - case PROP_DESCRIPTION: - characterstring_init_ansi(&char_string, Description); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_SYSTEM_STATUS: - apdu_len = encode_application_enumerated(&apdu[0], System_Status); - break; - case PROP_VENDOR_NAME: - characterstring_init_ansi(&char_string, Vendor_Name); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_VENDOR_IDENTIFIER: - apdu_len = encode_application_unsigned(&apdu[0], Vendor_Identifier); - break; - case PROP_MODEL_NAME: - characterstring_init_ansi(&char_string, Model_Name); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_FIRMWARE_REVISION: - characterstring_init_ansi(&char_string, BACnet_Version); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_APPLICATION_SOFTWARE_VERSION: - characterstring_init_ansi( - &char_string, Application_Software_Version); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_LOCATION: - characterstring_init_ansi(&char_string, Location); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_LOCAL_TIME: - Update_Current_Time(); - apdu_len = encode_application_time(&apdu[0], &Local_Time); - break; - case PROP_UTC_OFFSET: - Update_Current_Time(); - apdu_len = encode_application_signed(&apdu[0], UTC_Offset); - break; - case PROP_LOCAL_DATE: - Update_Current_Time(); - apdu_len = encode_application_date(&apdu[0], &Local_Date); - break; - case PROP_DAYLIGHT_SAVINGS_STATUS: - Update_Current_Time(); - apdu_len = - encode_application_boolean(&apdu[0], Daylight_Savings_Status); - break; - case PROP_PROTOCOL_VERSION: - apdu_len = encode_application_unsigned( - &apdu[0], Device_Protocol_Version()); - break; - case PROP_PROTOCOL_REVISION: - apdu_len = encode_application_unsigned( - &apdu[0], Device_Protocol_Revision()); - break; - case PROP_PROTOCOL_SERVICES_SUPPORTED: - /* Note: list of services that are executed, not initiated. */ - bitstring_init(&bit_string); - for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { - /* automatic lookup based on handlers set */ - bitstring_set_bit(&bit_string, (uint8_t)i, - apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); - } - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: - /* Note: this is the list of objects that can be in this device, - not a list of objects that this device can access */ - bitstring_init(&bit_string); - for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { - /* initialize all the object types to not-supported */ - bitstring_set_bit(&bit_string, (uint8_t)i, false); - } - /* set the object types with objects to supported */ - - pObject = Object_Table; - while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { - if ((pObject->Object_Count) && (pObject->Object_Count() > 0)) { - bitstring_set_bit(&bit_string, pObject->Object_Type, true); - } - pObject++; - } - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_OBJECT_LIST: - count = Device_Object_List_Count(); - /* Array element zero is the number of objects in the list */ - if (rpdata->array_index == 0) - apdu_len = encode_application_unsigned(&apdu[0], count); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. Note that more than likely you will have */ - /* to return an error if the number of encoded objects exceeds */ - /* your maximum APDU size. */ - else if (rpdata->array_index == BACNET_ARRAY_ALL) { - for (i = 1; i <= count; i++) { - found = Device_Object_List_Identifier( - i, &object_type, &instance); - if (found) { - len = encode_application_object_id( - &apdu[apdu_len], object_type, instance); - apdu_len += len; - /* assume next one is the same size as this one */ - /* can we all fit into the APDU? Don't check for last - * entry */ - if ((i != count) && (apdu_len + len) >= apdu_max) { - /* Abort response */ - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - break; - } - } else { - /* error: internal error? */ - rpdata->error_class = ERROR_CLASS_SERVICES; - rpdata->error_code = ERROR_CODE_OTHER; - apdu_len = BACNET_STATUS_ERROR; - break; - } - } - } else { - found = Device_Object_List_Identifier( - rpdata->array_index, &object_type, &instance); - if (found) { - apdu_len = encode_application_object_id( - &apdu[0], object_type, instance); - } else { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; - apdu_len = BACNET_STATUS_ERROR; - } - } - break; - case PROP_MAX_APDU_LENGTH_ACCEPTED: - apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); - break; - case PROP_SEGMENTATION_SUPPORTED: - apdu_len = encode_application_enumerated( - &apdu[0], Device_Segmentation_Supported()); - break; - case PROP_APDU_TIMEOUT: - apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout()); - break; - case PROP_NUMBER_OF_APDU_RETRIES: - apdu_len = encode_application_unsigned(&apdu[0], apdu_retries()); - break; - case PROP_DEVICE_ADDRESS_BINDING: - apdu_len = address_list_encode(&apdu[0], apdu_max); - break; - case PROP_DATABASE_REVISION: - apdu_len = encode_application_unsigned(&apdu[0], Database_Revision); - break; -#if defined(BACDL_MSTP) - case PROP_MAX_INFO_FRAMES: - apdu_len = - encode_application_unsigned(&apdu[0], dlmstp_max_info_frames()); - break; - case PROP_MAX_MASTER: - apdu_len = - encode_application_unsigned(&apdu[0], dlmstp_max_master()); - break; -#endif -#if defined(BACNET_TIME_MASTER) - case PROP_TIME_SYNCHRONIZATION_RECIPIENTS: - apdu_len = handler_timesync_encode_recipients(&apdu[0], MAX_APDU); - if (apdu_len < 0) { - rpdata->error_code = - ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - apdu_len = BACNET_STATUS_ABORT; - } - break; - case PROP_TIME_SYNCHRONIZATION_INTERVAL: - apdu_len = encode_application_unsigned( - &apdu[0], Device_Time_Sync_Interval()); - break; - case PROP_ALIGN_INTERVALS: - apdu_len = - encode_application_boolean(&apdu[0], Device_Align_Intervals()); - break; - case PROP_INTERVAL_OFFSET: - apdu_len = - encode_application_unsigned(&apdu[0], Device_Interval_Offset()); - break; -#endif - case PROP_ACTIVE_COV_SUBSCRIPTIONS: - apdu_len = handler_cov_encode_subscriptions(&apdu[0], apdu_max); - break; - default: - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = BACNET_STATUS_ERROR; - break; - } - /* only array properties can have array options */ - if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) && - (rpdata->array_index != BACNET_ARRAY_ALL)) { - rpdata->error_class = ERROR_CLASS_PROPERTY; - rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - apdu_len = BACNET_STATUS_ERROR; - } - - return apdu_len; -} - -/** Looks up the requested Object and Property, and encodes its Value in an - * APDU. - * @ingroup ObjIntf - * If the Object or Property can't be found, sets the error class and code. - * - * @param rpdata [in,out] Structure with the desired Object and Property info - * on entry, and APDU message on return. - * @return The length of the APDU on success, else BACNET_STATUS_ERROR - */ -int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) -{ - int apdu_len = BACNET_STATUS_ERROR; - struct object_functions *pObject = NULL; -#if (BACNET_PROTOCOL_REVISION >= 14) - struct special_property_list_t property_list; -#endif - - /* initialize the default return values */ - rpdata->error_class = ERROR_CLASS_OBJECT; - rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT; - pObject = Device_Objects_Find_Functions(rpdata->object_type); - if (pObject != NULL) { - if (pObject->Object_Valid_Instance && - pObject->Object_Valid_Instance(rpdata->object_instance)) { - if (pObject->Object_Read_Property) { -#if (BACNET_PROTOCOL_REVISION >= 14) - if ((int)rpdata->object_property == PROP_PROPERTY_LIST) { - Device_Objects_Property_List(rpdata->object_type, - rpdata->object_instance, &property_list); - apdu_len = property_list_encode(rpdata, - property_list.Required.pList, - property_list.Optional.pList, - property_list.Proprietary.pList); - } else -#endif - { - apdu_len = pObject->Object_Read_Property(rpdata); - } - } - } - } - - return apdu_len; -} - -/* returns true if successful */ -bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) -{ - bool status = false; /* return value */ - int len = 0; - BACNET_APPLICATION_DATA_VALUE value = { 0 }; - BACNET_OBJECT_TYPE object_type = OBJECT_NONE; - uint32_t object_instance = 0; - int temp; - - /* decode the some of the request */ - len = bacapp_decode_application_data( - wp_data->application_data, wp_data->application_data_len, &value); - if (len < 0) { - /* error while decoding - a value larger than we can handle */ - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - return false; - } - if ((wp_data->object_property != PROP_OBJECT_LIST) && - (wp_data->array_index != BACNET_ARRAY_ALL)) { - /* only array properties can have array options */ - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; - return false; - } - /* FIXME: len < application_data_len: more data? */ - switch (wp_data->object_property) { - case PROP_OBJECT_IDENTIFIER: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_OBJECT_ID); - if (status) { - if ((value.type.Object_Id.type == OBJECT_DEVICE) && - (Device_Set_Object_Instance_Number( - value.type.Object_Id.instance))) { - /* FIXME: we could send an I-Am broadcast to let the world - * know */ - } else { - status = false; - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - break; - case PROP_NUMBER_OF_APDU_RETRIES: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - /* FIXME: bounds check? */ - apdu_retries_set((uint8_t)value.type.Unsigned_Int); - } - break; - case PROP_APDU_TIMEOUT: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - /* FIXME: bounds check? */ - apdu_timeout_set((uint16_t)value.type.Unsigned_Int); - } - break; - case PROP_VENDOR_IDENTIFIER: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - /* FIXME: bounds check? */ - Device_Set_Vendor_Identifier((uint16_t)value.type.Unsigned_Int); - } - break; - case PROP_SYSTEM_STATUS: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_ENUMERATED); - if (status) { - temp = Device_Set_System_Status( - (BACNET_DEVICE_STATUS)value.type.Enumerated, false); - if (temp != 0) { - status = false; - wp_data->error_class = ERROR_CLASS_PROPERTY; - if (temp == -1) { - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } else { - wp_data->error_code = - ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED; - } - } - } - break; - case PROP_OBJECT_NAME: - status = write_property_string_valid(&wp_data, &value, - characterstring_capacity(&My_Object_Name)); - if (status) { - /* All the object names in a device must be unique */ - if (Device_Valid_Object_Name(&value.type.Character_String, - &object_type, &object_instance)) { - if ((object_type == wp_data->object_type) && - (object_instance == wp_data->object_instance)) { - /* writing same name to same object */ - status = true; - } else { - status = false; - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_DUPLICATE_NAME; - } - } else { - Device_Set_Object_Name(&value.type.Character_String); - } - } - break; - case PROP_LOCATION: - status = write_property_empty_string_valid(&wp_data, &value, - MAX_DEV_LOC_LEN); - if (status) { - Device_Set_Location( - characterstring_value(&value.type.Character_String), - characterstring_length(&value.type.Character_String)); - } - break; - - case PROP_DESCRIPTION: - status = write_property_empty_string_valid(&wp_data, &value, - MAX_DEV_DESC_LEN); - if (status) { - Device_Set_Description( - characterstring_value(&value.type.Character_String), - characterstring_length(&value.type.Character_String)); - } - break; - case PROP_MODEL_NAME: - status = write_property_empty_string_valid(&wp_data, &value, - MAX_DEV_MOD_LEN); - if (status) { - Device_Set_Model_Name( - characterstring_value(&value.type.Character_String), - characterstring_length(&value.type.Character_String)); - } - break; -#if defined(BACNET_TIME_MASTER) - case PROP_TIME_SYNCHRONIZATION_INTERVAL: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - if (value.type.Unsigned_Int < 65535) { - minutes = value.type.Unsigned_Int; - Device_Time_Sync_Interval_Set(minutes); - status = true; - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - break; - case PROP_ALIGN_INTERVALS: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_BOOLEAN); - if (status) { - Device_Align_Intervals_Set(value.type.Boolean); - status = true; - } - break; - case PROP_INTERVAL_OFFSET: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - if (value.type.Unsigned_Int < 65535) { - minutes = value.type.Unsigned_Int; - Device_Interval_Offset_Set(minutes); - status = true; - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - break; -#else - case PROP_TIME_SYNCHRONIZATION_INTERVAL: - case PROP_ALIGN_INTERVALS: - case PROP_INTERVAL_OFFSET: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - break; -#endif - case PROP_UTC_OFFSET: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_SIGNED_INT); - if (status) { - if ((value.type.Signed_Int < (12 * 60)) && - (value.type.Signed_Int > (-12 * 60))) { - Device_UTC_Offset_Set(value.type.Signed_Int); - status = true; - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - break; -#if defined(BACDL_MSTP) - case PROP_MAX_INFO_FRAMES: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - if (value.type.Unsigned_Int <= 255) { - dlmstp_set_max_info_frames( - (uint8_t)value.type.Unsigned_Int); - } else { - status = false; - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - break; - case PROP_MAX_MASTER: - status = write_property_type_valid(wp_data, &value, - BACNET_APPLICATION_TAG_UNSIGNED_INT); - if (status) { - if ((value.type.Unsigned_Int > 0) && - (value.type.Unsigned_Int <= 127)) { - dlmstp_set_max_master((uint8_t)value.type.Unsigned_Int); - } else { - status = false; - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; - } - } - break; -#else - case PROP_MAX_INFO_FRAMES: - case PROP_MAX_MASTER: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - break; -#endif - case PROP_OBJECT_TYPE: - case PROP_VENDOR_NAME: - case PROP_FIRMWARE_REVISION: - case PROP_APPLICATION_SOFTWARE_VERSION: - case PROP_LOCAL_TIME: - case PROP_LOCAL_DATE: - case PROP_DAYLIGHT_SAVINGS_STATUS: - case PROP_PROTOCOL_VERSION: - case PROP_PROTOCOL_REVISION: - case PROP_PROTOCOL_SERVICES_SUPPORTED: - case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: - case PROP_OBJECT_LIST: - case PROP_MAX_APDU_LENGTH_ACCEPTED: - case PROP_SEGMENTATION_SUPPORTED: - case PROP_DEVICE_ADDRESS_BINDING: - case PROP_DATABASE_REVISION: - case PROP_ACTIVE_COV_SUBSCRIPTIONS: -#if defined(BACNET_TIME_MASTER) - case PROP_TIME_SYNCHRONIZATION_RECIPIENTS: -#endif - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - break; - default: - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - break; - } - - return status; -} - -/** Looks up the requested Object and Property, and set the new Value in it, - * if allowed. - * If the Object or Property can't be found, sets the error class and code. - * @ingroup ObjIntf - * - * @param wp_data [in,out] Structure with the desired Object and Property info - * and new Value on entry, and APDU message on return. - * @return True on success, else False if there is an error. - */ -bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) -{ - bool status = false; /* Ever the pessamist! */ - struct object_functions *pObject = NULL; - - /* initialize the default return values */ - wp_data->error_class = ERROR_CLASS_OBJECT; - wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; - pObject = Device_Objects_Find_Functions(wp_data->object_type); - if (pObject != NULL) { - if (pObject->Object_Valid_Instance && - pObject->Object_Valid_Instance(wp_data->object_instance)) { - if (pObject->Object_Write_Property) { -#if (BACNET_PROTOCOL_REVISION >= 14) - if (wp_data->object_property == PROP_PROPERTY_LIST) { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - } else -#endif - { - status = pObject->Object_Write_Property(wp_data); - } - } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - } - } else { - wp_data->error_class = ERROR_CLASS_OBJECT; - wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; - } - } else { - wp_data->error_class = ERROR_CLASS_OBJECT; - wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT; - } - - return (status); -} - -/** Looks up the requested Object, and fills the Property Value list. - * If the Object or Property can't be found, returns false. - * @ingroup ObjHelpers - * @param [in] The object type to be looked up. - * @param [in] The object instance number to be looked up. - * @param [out] The value list - * @return True if the object instance supports this feature and value changed. - */ -bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_VALUE *value_list) -{ - bool status = false; /* Ever the pessamist! */ - struct object_functions *pObject = NULL; - - pObject = Device_Objects_Find_Functions(object_type); - if (pObject != NULL) { - if (pObject->Object_Valid_Instance && - pObject->Object_Valid_Instance(object_instance)) { - if (pObject->Object_Value_List) { - status = - pObject->Object_Value_List(object_instance, value_list); - } - } - } - - return (status); -} - -/** Checks the COV flag in the requested Object - * @ingroup ObjHelpers - * @param [in] The object type to be looked up. - * @param [in] The object instance to be looked up. - * @return True if the COV flag is set - */ -bool Device_COV(BACNET_OBJECT_TYPE object_type, uint32_t object_instance) -{ - bool status = false; /* Ever the pessamist! */ - struct object_functions *pObject = NULL; - - pObject = Device_Objects_Find_Functions(object_type); - if (pObject != NULL) { - if (pObject->Object_Valid_Instance && - pObject->Object_Valid_Instance(object_instance)) { - if (pObject->Object_COV) { - status = pObject->Object_COV(object_instance); - } - } - } - - return (status); -} - -/** Clears the COV flag in the requested Object - * @ingroup ObjHelpers - * @param [in] The object type to be looked up. - * @param [in] The object instance to be looked up. - */ -void Device_COV_Clear(BACNET_OBJECT_TYPE object_type, uint32_t object_instance) -{ - struct object_functions *pObject = NULL; - - pObject = Device_Objects_Find_Functions(object_type); - if (pObject != NULL) { - if (pObject->Object_Valid_Instance && - pObject->Object_Valid_Instance(object_instance)) { - if (pObject->Object_COV_Clear) { - pObject->Object_COV_Clear(object_instance); - } - } - } -} - -#if defined(INTRINSIC_REPORTING) -void Device_local_reporting(void) -{ - struct object_functions *pObject; - uint32_t objects_count; - uint32_t object_instance; - BACNET_OBJECT_TYPE object_type; - uint32_t idx; - - objects_count = Device_Object_List_Count(); - - /* loop for all objects */ - for (idx = 1; idx <= objects_count; idx++) { - Device_Object_List_Identifier(idx, &object_type, &object_instance); - - pObject = Device_Objects_Find_Functions(object_type); - if (pObject != NULL) { - if (pObject->Object_Valid_Instance && - pObject->Object_Valid_Instance(object_instance)) { - if (pObject->Object_Intrinsic_Reporting) { - pObject->Object_Intrinsic_Reporting(object_instance); - } - } - } - } -} -#endif - -/** Looks up the requested Object to see if the functionality is supported. - * @ingroup ObjHelpers - * @param [in] The object type to be looked up. - * @return True if the object instance supports this feature. - */ -bool Device_Value_List_Supported(BACNET_OBJECT_TYPE object_type) -{ - bool status = false; /* Ever the pessamist! */ - struct object_functions *pObject = NULL; - - pObject = Device_Objects_Find_Functions(object_type); - if (pObject != NULL) { - if (pObject->Object_Value_List) { - status = true; - } - } - - return (status); -} - -/** Initialize the Device Object. - Initialize the group of object helper functions for any supported Object. - Initialize each of the Device Object child Object instances. - * @ingroup ObjIntf - * @param object_table [in,out] array of structure with object functions. - * Each Child Object must provide some implementation of each of these - * functions in order to properly support the default handlers. - */ -void Device_Init(object_functions_t *object_table) -{ - struct object_functions *pObject = NULL; -#if defined(BAC_UCI) - const char *uciname; - struct uci_context *ctx; - fprintf(stderr, "Device_Init\n"); - ctx = ucix_init("bacnet_dev"); - if (!ctx) - fprintf(stderr, "Failed to load config file bacnet_dev\n"); - uciname = ucix_get_option(ctx, "bacnet_dev", "0", "Name"); - if (uciname != 0) { - characterstring_init_ansi(&My_Object_Name, uciname); - } else { -#endif /* defined(BAC_UCI) */ - characterstring_init_ansi(&My_Object_Name, "ESP32 SimpleServer"); -#if defined(BAC_UCI) - } - ucix_cleanup(ctx); -#endif /* defined(BAC_UCI) */ - - if (object_table) { - Object_Table = object_table; - } else { - Object_Table = &My_Object_Table[0]; - } - pObject = Object_Table; - while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { - if (pObject->Object_Init) { - pObject->Object_Init(); - } - pObject++; - } -} - -bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */ - RR_PROP_INFO *pInfo) -{ /* Where to put the response */ - bool status = false; /* return value */ - - switch (pRequest->object_property) { - case PROP_VT_CLASSES_SUPPORTED: - case PROP_ACTIVE_VT_SESSIONS: - case PROP_LIST_OF_SESSION_KEYS: - case PROP_TIME_SYNCHRONIZATION_RECIPIENTS: - case PROP_MANUAL_SLAVE_ADDRESS_BINDING: - case PROP_SLAVE_ADDRESS_BINDING: - case PROP_RESTART_NOTIFICATION_RECIPIENTS: - case PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS: - pInfo->RequestTypes = RR_BY_POSITION; - pRequest->error_class = ERROR_CLASS_PROPERTY; - pRequest->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - break; - - case PROP_DEVICE_ADDRESS_BINDING: - pInfo->RequestTypes = RR_BY_POSITION; - pInfo->Handler = rr_address_list_encode; - status = true; - break; - - case PROP_ACTIVE_COV_SUBSCRIPTIONS: - pInfo->RequestTypes = RR_BY_POSITION; - pRequest->error_class = ERROR_CLASS_PROPERTY; - pRequest->error_code = ERROR_CODE_UNKNOWN_PROPERTY; - break; - default: - pRequest->error_class = ERROR_CLASS_SERVICES; - pRequest->error_code = ERROR_CODE_PROPERTY_IS_NOT_A_LIST; - break; - } - - return status; -} - -#ifdef BAC_ROUTING -/**************************************************************************** - ************* BACnet Routing Functionality (Optional) ********************** - **************************************************************************** - * The supporting functions are located in gw_device.c, except for those - * that need access to local data in this file. - ****************************************************************************/ - -/** Initialize the first of our array of Devices with the main Device's - * information, and then swap out some of the Device object functions and - * replace with ones appropriate for routing. - * @ingroup ObjIntf - * @param first_object_instance Set the first (gateway) Device to this - instance number. - */ -void Routing_Device_Init(uint32_t first_object_instance) -{ - struct object_functions *pDevObject = NULL; - - /* Initialize with our preset strings */ - Add_Routed_Device(first_object_instance, &My_Object_Name, Description); - - /* Now substitute our routed versions of the main object functions. */ - pDevObject = Object_Table; - pDevObject->Object_Index_To_Instance = Routed_Device_Index_To_Instance; - pDevObject->Object_Valid_Instance = - Routed_Device_Valid_Object_Instance_Number; - pDevObject->Object_Name = Routed_Device_Name; - pDevObject->Object_Read_Property = Routed_Device_Read_Property_Local; - pDevObject->Object_Write_Property = Routed_Device_Write_Property_Local; -} - -#endif /* BAC_ROUTING */ diff --git a/ports/esp32/src/device.h b/ports/esp32/src/device.h deleted file mode 100644 index 90c8e804..00000000 --- a/ports/esp32/src/device.h +++ /dev/null @@ -1,461 +0,0 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* SPDX-License-Identifier: MIT -* -*********************************************************************/ - -/** @file device.h Defines functions for handling all BACnet objects belonging - * to a BACnet device, as well as Device-specific properties. */ - -#ifndef DEVICE_H -#define DEVICE_H - -#include -#include -#include "bacnet/bacdef.h" -#include "bacnet/bacenum.h" -#include "bacnet/wp.h" -#include "bacnet/rd.h" -#include "bacnet/rp.h" -#include "bacnet/rpm.h" -#include "bacnet/readrange.h" - -/** Called so a BACnet object can perform any necessary initialization. - * @ingroup ObjHelpers - */ -typedef void ( - *object_init_function) ( - void); - -/** Counts the number of objects of this type. - * @ingroup ObjHelpers - * @return Count of implemented objects of this type. - */ -typedef unsigned ( - *object_count_function) ( - void); - -/** Maps an object index position to its corresponding BACnet object instance number. - * @ingroup ObjHelpers - * @param index [in] The index of the object, in the array of objects of its type. - * @return The BACnet object instance number to be used in a BACNET_OBJECT_ID. - */ -typedef uint32_t( - *object_index_to_instance_function) - ( - unsigned index); - -/** Provides the BACnet Object_Name for a given object instance of this type. - * @ingroup ObjHelpers - * @param object_instance [in] The object instance number to be looked up. - * @param object_name [in,out] Pointer to a character_string structure that - * will hold a copy of the object name if this is a valid object_instance. - * @return True if the object_instance is valid and object_name has been - * filled with a copy of the Object's name. - */ -typedef bool( - *object_name_function) - ( - uint32_t object_instance, - BACNET_CHARACTER_STRING * object_name); - -/** Look in the table of objects of this type, and see if this is a valid - * instance number. - * @ingroup ObjHelpers - * @param [in] The object instance number to be looked up. - * @return True if the object instance refers to a valid object of this type. - */ -typedef bool( - *object_valid_instance_function) ( - uint32_t object_instance); - -/** Helper function to step through an array of objects and find either the - * first one or the next one of a given type. Used to step through an array - * of objects which is not necessarily contiguious for each type i.e. the - * index for the 'n'th object of a given type is not necessarily 'n'. - * @ingroup ObjHelpers - * @param [in] The index of the current object or a value of ~0 to indicate - * start at the beginning. - * @return The index of the next object of the required type or ~0 (all bits - * == 1) to indicate no more objects found. - */ -typedef unsigned ( - *object_iterate_function) ( - unsigned current_index); - -/** Look in the table of objects of this type, and get the COV Value List. - * @ingroup ObjHelpers - * @param [in] The object instance number to be looked up. - * @param [out] The value list - * @return True if the object instance supports this feature, and has changed. - */ -typedef bool( - *object_value_list_function) ( - uint32_t object_instance, - BACNET_PROPERTY_VALUE * value_list); - -/** Look in the table of objects for this instance to see if value changed. - * @ingroup ObjHelpers - * @param [in] The object instance number to be looked up. - * @return True if the object instance has changed. - */ -typedef bool( - *object_cov_function) ( - uint32_t object_instance); - -/** Look in the table of objects for this instance to clear the changed flag. - * @ingroup ObjHelpers - * @param [in] The object instance number to be looked up. - */ -typedef void ( - *object_cov_clear_function) ( - uint32_t object_instance); - -/** Intrinsic Reporting funcionality. - * @ingroup ObjHelpers - * @param [in] Object instance. - */ -typedef void ( - *object_intrinsic_reporting_function) ( - uint32_t object_instance); - - -/** Defines the group of object helper functions for any supported Object. - * @ingroup ObjHelpers - * Each Object must provide some implementation of each of these helpers - * in order to properly support the handlers. Eg, the ReadProperty handler - * handler_read_property() relies on the instance of Object_Read_Property - * for each Object type, or configure the function as NULL. - * In both appearance and operation, this group of functions acts like - * they are member functions of a C++ Object base class. - */ -typedef struct object_functions { - BACNET_OBJECT_TYPE Object_Type; - object_init_function Object_Init; - object_count_function Object_Count; - object_index_to_instance_function Object_Index_To_Instance; - object_valid_instance_function Object_Valid_Instance; - object_name_function Object_Name; - read_property_function Object_Read_Property; - write_property_function Object_Write_Property; - rpm_property_lists_function Object_RPM_List; - rr_info_function Object_RR_Info; - object_iterate_function Object_Iterator; - object_value_list_function Object_Value_List; - object_cov_function Object_COV; - object_cov_clear_function Object_COV_Clear; - object_intrinsic_reporting_function Object_Intrinsic_Reporting; -} object_functions_t; - -/* String Lengths - excluding any nul terminator */ -#define MAX_DEV_NAME_LEN 32 -#define MAX_DEV_LOC_LEN 64 -#define MAX_DEV_MOD_LEN 32 -#define MAX_DEV_VER_LEN 16 -#define MAX_DEV_DESC_LEN 64 - -/** Structure to define the Object Properties common to all Objects. */ -typedef struct commonBacObj_s { - - /** The BACnet type of this object (ie, what class is this object from?). - * This property, of type BACnetObjectType, indicates membership in a - * particular object type class. Each inherited class will be of one type. - */ - BACNET_OBJECT_TYPE mObject_Type; - - /** The instance number for this class instance. */ - uint32_t Object_Instance_Number; - - /** Object Name; must be unique. - * This property, of type CharacterString, shall represent a name for - * the object that is unique within the BACnet Device that maintains it. - */ - char Object_Name[MAX_DEV_NAME_LEN]; - -} COMMON_BAC_OBJECT; - - -/** Structure to define the Properties of Device Objects which distinguish - * one instance from another. - * This structure only defines fields for properties that are unique to - * a given Device object. The rest may be fixed in device.c or hard-coded - * into the read-property encoding. - * This may be useful for implementations which manage multiple Devices, - * eg, a Gateway. - */ -typedef struct devObj_s { - /** The BACnet Device Address for this device; ->len depends on DLL type. */ - BACNET_ADDRESS bacDevAddr; - - /** Structure for the Object Properties common to all Objects. */ - COMMON_BAC_OBJECT bacObj; - - /** Device Description. */ - char Description[MAX_DEV_DESC_LEN]; - - /** The upcounter that shows if the Device ID or object structure has changed. */ - uint32_t Database_Revision; -} DEVICE_OBJECT_DATA; - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void Device_Init( - object_functions_t * object_table); - - bool Device_Reinitialize( - BACNET_REINITIALIZE_DEVICE_DATA * rd_data); - bool Device_Reinitialize_State_Set(BACNET_REINITIALIZED_STATE state); - BACNET_REINITIALIZED_STATE Device_Reinitialized_State( - void); - - rr_info_function Device_Objects_RR_Info( - BACNET_OBJECT_TYPE object_type); - - void Device_getCurrentDateTime( - BACNET_DATE_TIME * DateTime); - - int32_t Device_UTC_Offset(void); - void Device_UTC_Offset_Set(int16_t offset); - - bool Device_Daylight_Savings_Status(void); - bool Device_Align_Intervals(void); - bool Device_Align_Intervals_Set(bool flag); - uint32_t Device_Time_Sync_Interval(void); - bool Device_Time_Sync_Interval_Set(uint32_t value); - uint32_t Device_Interval_Offset(void); - bool Device_Interval_Offset_Set(uint32_t value); - - void Device_Property_Lists( - const int32_t **pRequired, - const int32_t **pOptional, - const int32_t **pProprietary); - void Device_Objects_Property_List( - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - struct special_property_list_t *pPropertyList); - /* functions to support COV */ - bool Device_Encode_Value_List( - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_PROPERTY_VALUE * value_list); - bool Device_Value_List_Supported( - BACNET_OBJECT_TYPE object_type); - bool Device_COV( - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance); - void Device_COV_Clear( - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance); - - uint32_t Device_Object_Instance_Number( - void); - bool Device_Set_Object_Instance_Number( - uint32_t object_id); - bool Device_Valid_Object_Instance_Number( - uint32_t object_id); - unsigned Device_Object_List_Count( - void); - bool Device_Object_List_Identifier( - uint32_t array_index, - BACNET_OBJECT_TYPE *object_type, - uint32_t * instance); - - unsigned Device_Count( - void); - uint32_t Device_Index_To_Instance( - unsigned index); - - bool Device_Object_Name( - uint32_t object_instance, - BACNET_CHARACTER_STRING * object_name); - bool Device_Set_Object_Name( - const BACNET_CHARACTER_STRING * object_name); - /* Copy a child object name, given its ID. */ - bool Device_Object_Name_Copy( - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance, - BACNET_CHARACTER_STRING * object_name); - bool Device_Object_Name_ANSI_Init(const char * object_name); - char * Device_Object_Name_ANSI(void); - - BACNET_DEVICE_STATUS Device_System_Status( - void); - int Device_Set_System_Status( - BACNET_DEVICE_STATUS status, - bool local); - - const char *Device_Vendor_Name( - void); - - uint16_t Device_Vendor_Identifier( - void); - void Device_Set_Vendor_Identifier( - uint16_t vendor_id); - - const char *Device_Model_Name( - void); - bool Device_Set_Model_Name( - const char *name, - size_t length); - - const char *Device_Firmware_Revision( - void); - - const char *Device_Application_Software_Version( - void); - bool Device_Set_Application_Software_Version( - const char *name, - size_t length); - - const char *Device_Description( - void); - bool Device_Set_Description( - const char *name, - size_t length); - - const char *Device_Location( - void); - bool Device_Set_Location( - const char *name, - size_t length); - - /* some stack-centric constant values - no set methods */ - uint8_t Device_Protocol_Version( - void); - uint8_t Device_Protocol_Revision( - void); - BACNET_SEGMENTATION Device_Segmentation_Supported( - void); - - uint32_t Device_Database_Revision( - void); - void Device_Set_Database_Revision( - uint32_t revision); - void Device_Inc_Database_Revision( - void); - - bool Device_Valid_Object_Name( - const BACNET_CHARACTER_STRING * object_name, - BACNET_OBJECT_TYPE *object_type, - uint32_t * object_instance); - bool Device_Valid_Object_Id( - BACNET_OBJECT_TYPE object_type, - uint32_t object_instance); - - int Device_Read_Property( - BACNET_READ_PROPERTY_DATA * rpdata); - bool Device_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data); - - bool DeviceGetRRInfo( - BACNET_READ_RANGE_DATA * pRequest, /* Info on the request */ - RR_PROP_INFO * pInfo); /* Where to put the information */ - - int Device_Read_Property_Local( - BACNET_READ_PROPERTY_DATA * rpdata); - bool Device_Write_Property_Local( - BACNET_WRITE_PROPERTY_DATA * wp_data); - -#if defined(INTRINSIC_REPORTING) - void Device_local_reporting( - void); -#endif - -/* Prototypes for Routing functionality in the Device Object. - * Enable by defining BAC_ROUTING in config.h and including gw_device.c - * in the build (lib/Makefile). - */ - void Routing_Device_Init( - uint32_t first_object_instance); - - uint16_t Add_Routed_Device( - uint32_t Object_Instance, - const BACNET_CHARACTER_STRING * Object_Name, - const char *Description); - DEVICE_OBJECT_DATA *Get_Routed_Device_Object( - int idx); - BACNET_ADDRESS *Get_Routed_Device_Address( - int idx); - - void routed_get_my_address( - BACNET_ADDRESS * my_address); - - bool Routed_Device_Address_Lookup( - int idx, - uint8_t address_len, - const uint8_t * mac_adress); - bool Routed_Device_GetNext( - const BACNET_ADDRESS * dest, - const int32_t *DNET_list, - int *cursor); - bool Routed_Device_Is_Valid_Network( - uint16_t dest_net, - const int32_t *DNET_list); - - uint32_t Routed_Device_Index_To_Instance( - unsigned index); - bool Routed_Device_Valid_Object_Instance_Number( - uint32_t object_id); - bool Routed_Device_Name( - uint32_t object_instance, - BACNET_CHARACTER_STRING * object_name); - uint32_t Routed_Device_Object_Instance_Number( - void); - bool Routed_Device_Set_Object_Instance_Number( - uint32_t object_id); - bool Routed_Device_Set_Object_Name( - uint8_t encoding, - const char *value, - size_t length); - bool Routed_Device_Set_Description( - const char *name, - size_t length); - void Routed_Device_Inc_Database_Revision( - void); - int Routed_Device_Service_Approval( - BACNET_CONFIRMED_SERVICE service, - int service_argument, - uint8_t * apdu_buff, - uint8_t invoke_id); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -/** @defgroup ObjFrmwk Object Framework - * The modules in this section describe the BACnet-stack's framework for - * BACnet-defined Objects (Device, Analog Input, etc). There are two submodules - * to describe this arrangement: - * - The "object helper functions" which provide C++-like common functionality - * to all supported object types. - * - The interface between the implemented Objects and the BAC-stack services, - * specifically the handlers, which are mediated through function calls to - * the Device object. - */ -/** @defgroup ObjHelpers Object Helper Functions - * @ingroup ObjFrmwk - * This section describes the function templates for the helper functions that - * provide common object support. - */ -/** @defgroup ObjIntf Handler-to-Object Interface Functions - * @ingroup ObjFrmwk - * This section describes the fairly limited set of functions that link the - * BAC-stack handlers to the BACnet Object instances. All of these calls are - * situated in the Device Object, which "knows" how to reach its child Objects. - * - * Most of these calls have a common operation: - * -# Call Device_Objects_Find_Functions( for the desired Object_Type ) - * - Gets a pointer to the object_functions for this Type of Object. - * -# Call the Object's Object_Valid_Instance( for the desired object_instance ) - * to make sure there is such an instance. - * -# Call the Object helper function needed by the handler, - * eg Object_Read_Property() for the RP handler. - * - */ -#endif diff --git a/ports/esp32/src/dlenv.c b/ports/esp32/src/dlenv.c new file mode 100644 index 00000000..fd2abfa5 --- /dev/null +++ b/ports/esp32/src/dlenv.c @@ -0,0 +1,81 @@ +/** + * @file + * @brief BACnet MS/TP datalink environment setup for the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#include "dlenv.h" + +#include "bacnet/datalink/dlmstp.h" +#include "rs485.h" + +volatile struct mstp_port_struct_t MSTP_Port; + +static struct dlmstp_user_data_t MSTP_User_Data; +static uint8_t Input_Buffer[DLMSTP_MPDU_MAX]; +static uint8_t Output_Buffer[DLMSTP_MPDU_MAX]; + +static struct dlmstp_rs485_driver RS485_Driver = { + .init = rs485_init, + .send = rs485_bytes_send, + .read = rs485_byte_available, + .transmitting = rs485_rts_enabled, + .baud_rate = rs485_baud_rate, + .baud_rate_set = rs485_baud_rate_set, + .silence_milliseconds = rs485_silence_milliseconds, + .silence_reset = rs485_silence_reset +}; + +/** + * @brief Initialize the BACnet MS/TP datalink environment + * @param mac_address local MS/TP MAC address + * @return true if the datalink initialized successfully + */ +bool m5_dlenv_init(uint8_t mac_address) +{ + RS485_Driver.init(); + + MSTP_Port.Nmax_info_frames = BACNET_MSTP_MAX_INFO_FRAMES; + MSTP_Port.Nmax_master = BACNET_MSTP_MAX_MASTER; + + MSTP_Port.InputBuffer = Input_Buffer; + MSTP_Port.InputBufferSize = sizeof(Input_Buffer); + MSTP_Port.OutputBuffer = Output_Buffer; + MSTP_Port.OutputBufferSize = sizeof(Output_Buffer); + + MSTP_Port.ZeroConfigEnabled = false; + MSTP_Port.SlaveNodeEnabled = false; + MSTP_Port.CheckAutoBaud = false; + + MSTP_Zero_Config_UUID_Init((struct mstp_port_struct_t *)&MSTP_Port); + + MSTP_User_Data.RS485_Driver = &RS485_Driver; + MSTP_Port.UserData = &MSTP_User_Data; + + if (!dlmstp_init((char *)&MSTP_Port)) { + return false; + } + + dlmstp_set_mac_address(mac_address); + dlmstp_set_baud_rate(RS485_BAUD_RATE); + dlmstp_set_max_master(BACNET_MSTP_MAX_MASTER); + dlmstp_set_max_info_frames(BACNET_MSTP_MAX_INFO_FRAMES); + + return true; +} + +/** + * @brief Run any periodic MS/TP maintenance hooks + * @param seconds elapsed seconds since the last call + */ +void dlenv_maintenance_timer(uint16_t seconds) +{ + (void)seconds; +} + +/** + * @brief Shut down the MS/TP datalink environment + */ +void dlenv_cleanup(void) +{ +} diff --git a/ports/esp32/src/dlenv.h b/ports/esp32/src/dlenv.h new file mode 100644 index 00000000..f65d5426 --- /dev/null +++ b/ports/esp32/src/dlenv.h @@ -0,0 +1,48 @@ +/** + * @file + * @brief BACnet MS/TP datalink environment declarations for the PlatformIO + * ESP32 port + * @author Kato Gangstad + */ + +#ifndef M5STAMPLC_DLENV_H +#define M5STAMPLC_DLENV_H + +#include +#include + +#include "bacnet/bacdef.h" +#include "bacnet/datalink/dlenv.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/datalink/mstp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BACNET_MSTP_MAX_MASTER 127 +#define BACNET_MSTP_MAX_INFO_FRAMES 1 + +/** + * @brief Initialize the BACnet MS/TP datalink environment + * @param mac_address local MS/TP MAC address + * @return true if initialization succeeded + */ +bool m5_dlenv_init(uint8_t mac_address); + +/** + * @brief Run periodic MS/TP maintenance work + * @param seconds elapsed seconds since the last call + */ +void dlenv_maintenance_timer(uint16_t seconds); + +/** + * @brief Shut down the MS/TP datalink environment + */ +void dlenv_cleanup(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/esp32/src/main.c b/ports/esp32/src/main.c deleted file mode 100644 index 0c2f4e5a..00000000 --- a/ports/esp32/src/main.c +++ /dev/null @@ -1,218 +0,0 @@ -// -// Copyleft F.Chaxel 2017 -// - -#include "bacnet/config.h" -#include "bacnet/basic/tsm/tsm.h" -#include "bacnet/basic/services.h" - -#include "bacnet/basic/services.h" -#include "bacnet/datalink/datalink.h" -#include "bacnet/dcc.h" -#include "bacnet/basic/tsm/tsm.h" -// conflict filename address.h with another file in default include paths -#include "../lib/stack/address.h" -#include "bacnet/datalink/bip.h" - -#include "bacnet/basic/object/device.h" -#include "bacnet/basic/object/ai.h" -#include "bacnet/basic/object/bo.h" - -#include "esp_log.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "nvs_flash.h" - -#include "driver/gpio.h" - -#include "lwip/sockets.h" -#include "lwip/netdb.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" - -// hidden function not in any .h files -extern uint8_t temprature_sens_read(); -extern uint32_t hall_sens_read(); - -// Wifi params -wifi_config_t wifi_config = { - .sta = { - .ssid = "myWifi", - .password = "myPass", - }, -}; - -// GPIO 5 has a Led on Sparkfun ESP32 board -#define BACNET_LED 5 - -uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 }; - -/** Static receive buffer, initialized with zeros by the C Library Startup Code. */ - -uint8_t Rx_Buf[MAX_MPDU + 16 /* Add a little safety margin to the buffer, - * so that in the rare case, the message - * would be filled up to MAX_MPDU and some - * decoding functions would overrun, these - * decoding functions will just end up in - * a safe field of static zeros. */] = { 0 }; - -EventGroupHandle_t wifi_event_group; -const static int CONNECTED_BIT = BIT0; - -/* BACnet handler, stack init, IAm */ -void StartBACnet() -{ - /* we need to handle who-is to support dynamic device binding */ - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); - - /* set the handler for all the services we don't implement */ - /* It is required to send the proper reject message... */ - apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); - /* Set the handlers for any confirmed services that we support. */ - /* We must implement read property - it's required! */ - apdu_set_confirmed_handler( - SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); - apdu_set_confirmed_handler( - SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); - - apdu_set_confirmed_handler( - SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property); - apdu_set_confirmed_handler( - SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe); - - address_init(); - bip_init(NULL); - Send_I_Am(&Handler_Transmit_Buffer[0]); -} - -/* wifi events handler : start & stop bacnet with an event */ -esp_err_t wifi_event_handler(void *ctx, system_event_t *event) -{ - switch (event->event_id) { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - break; - case SYSTEM_EVENT_STA_CONNECTED: - break; - case SYSTEM_EVENT_STA_GOT_IP: - if (xEventGroupGetBits(wifi_event_group) != CONNECTED_BIT) { - xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); - StartBACnet(); - } - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - /* This is a workaround as ESP32 WiFi libs don't currently - auto-reassociate. */ - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, CONNECTED_BIT); - bip_cleanup(); - break; - default: - break; - } - return ESP_OK; -} - -/* tcpip & wifi station start */ - -void wifi_init_station(void) -{ - tcpip_adapter_init(); - wifi_event_group = xEventGroupCreate(); - esp_event_loop_init(wifi_event_handler, NULL); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - esp_wifi_init(&cfg); - - esp_wifi_set_storage(WIFI_STORAGE_RAM); - esp_wifi_set_mode(WIFI_MODE_STA); - - esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config); - - esp_wifi_start(); -} - -/* setup gpio & nv flash, call wifi init code */ -void setup() -{ - gpio_pad_select_gpio(BACNET_LED); - gpio_set_direction(BACNET_LED, GPIO_MODE_OUTPUT); - - gpio_set_level(BACNET_LED, 0); - - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - nvs_flash_erase(); - ret = nvs_flash_init(); - } - wifi_init_station(); -} - -/* Bacnet Task */ -void BACnetTask(void *pvParameters) -{ - uint16_t pdu_len = 0; - BACNET_ADDRESS src = { 0 }; - unsigned timeout = 1; - - // Init Bacnet objets dictionnary - Device_Init(NULL); - Device_Set_Object_Instance_Number(12); - - setup(); - - uint32_t tickcount = xTaskGetTickCount(); - - for (;;) { - vTaskDelay( - 10 / portTICK_PERIOD_MS); // could be remove to speed the code - - // do nothing if not connected to wifi - xEventGroupWaitBits( - wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - { - uint32_t newtick = xTaskGetTickCount(); - - // one second elapse at least (maybe much more if Wifi was - // deconnected for a long) - if ((newtick < tickcount) || - ((newtick - tickcount) >= configTICK_RATE_HZ)) { - tickcount = newtick; - dcc_timer_seconds(1); - bvlc_maintenance_timer(1); - handler_cov_timer_seconds(1); - tsm_timer_milliseconds(1000); - - // Read analog values from internal sensors - Analog_Input_Present_Value_Set(0, temprature_sens_read()); - Analog_Input_Present_Value_Set(1, hall_sens_read()); - } - - pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout); - if (pdu_len) { - npdu_handler(&src, &Rx_Buf[0], pdu_len); - - if (Binary_Output_Present_Value(0) == BINARY_ACTIVE) - gpio_set_level(BACNET_LED, 1); - else - gpio_set_level(BACNET_LED, 0); - } - - handler_cov_task(); - } - } -} -/* Entry point */ -void app_main() -{ - // Cannot run BACnet code here, the default stack size is to small : 4096 - // byte - xTaskCreate(BACnetTask, /* Function to implement the task */ - "BACnetTask", /* Name of the task */ - 10000, /* Stack size in words */ - NULL, /* Task input parameter */ - 20, /* Priority of the task */ - NULL); /* Task handle. */ -} diff --git a/ports/esp32/src/main.cpp b/ports/esp32/src/main.cpp new file mode 100644 index 00000000..3ea07585 --- /dev/null +++ b/ports/esp32/src/main.cpp @@ -0,0 +1,57 @@ +/** + * @file + * @brief BACnet MS/TP application entry point for M5StamPLC + * @author Kato Gangstad + */ + +#include +#include + +#ifndef PLC_INPUT_ACTIVE_LOW +#define PLC_INPUT_ACTIVE_LOW 0 +#endif + +extern "C" { +#include "bacnet_app.h" +} + +/** + * @brief Initialize the MS/TP application and PLC hardware + */ +void setup(void) +{ + Serial.begin(115200); + delay(100); + Serial.println("[BOOT] Mode: BACnet MS/TP"); + Serial.println("[BOOT] Init M5StamPLC..."); + M5StamPLC.begin(); + Serial.println("[BOOT] Init BACnet app..."); + bacnet_app_init(); + Serial.println("[BOOT] BACnet MS/TP ready"); +} + +/** + * @brief Run the main MS/TP application loop + */ +void loop(void) +{ + M5StamPLC.update(); + + for (uint8_t i = 0; i < bacnet_app_input_count(); i++) { + bool state = M5StamPLC.readPlcInput(i); +#if PLC_INPUT_ACTIVE_LOW + state = !state; +#endif + bacnet_app_input_set(i, state); + } + + for (uint8_t i = 0; i < bacnet_app_relay_count(); i++) { + M5StamPLC.writePlcRelay(i, bacnet_app_relay_get(i)); + } + + bacnet_app_temperature_set(M5StamPLC.getTemp()); + bacnet_app_free_heap_kb_set((float)ESP.getFreeHeap() / 1024.0f); + + bacnet_app_tick(); + delay(1); +} diff --git a/ports/esp32/src/main_bip.cpp b/ports/esp32/src/main_bip.cpp new file mode 100644 index 00000000..b6adc726 --- /dev/null +++ b/ports/esp32/src/main_bip.cpp @@ -0,0 +1,152 @@ +/** + * @file + * @brief BACnet/IP application entry point for ESP32 PlatformIO environments + * @author Kato Gangstad + */ + +#include +#include +#if !defined(USE_M5STAMPLC_IO) || (USE_M5STAMPLC_IO) +#include +#endif +#include +#if defined(USE_ETH_INTERFACE) && (USE_ETH_INTERFACE) +#include +#endif + +#ifndef PLC_INPUT_ACTIVE_LOW +#define PLC_INPUT_ACTIVE_LOW 0 +#endif + +#ifndef USE_M5STAMPLC_IO +#define USE_M5STAMPLC_IO 1 +#endif + +#ifndef USE_ETH_INTERFACE +#define USE_ETH_INTERFACE 0 +#endif + +#ifndef WIFI_SSID +#define WIFI_SSID "" +#endif + +#ifndef WIFI_PASS +#define WIFI_PASS "" +#endif + +#ifndef BACNET_IP_PORT +#define BACNET_IP_PORT 47808 +#endif + +extern "C" { +#include "bacnet_app.h" +} + +/** + * @brief Bring up the selected WiFi or Ethernet interface + */ +static void wifi_connect(void) +{ +#if USE_ETH_INTERFACE + Serial.println("[ETH] Starting Ethernet..."); + if (!ETH.begin()) { + Serial.println("[ETH] ETH.begin() failed"); + return; + } + + unsigned long start = millis(); + while (!ETH.linkUp() && ((millis() - start) < 15000UL)) { + delay(200); + Serial.print('.'); + } + Serial.println(); + + if (ETH.linkUp()) { + Serial.printf( + "[ETH] Link up. IP: %s\n", ETH.localIP().toString().c_str()); + } else { + Serial.println("[ETH] Link timeout"); + } +#else + if (strlen(WIFI_SSID) == 0) { + Serial.println("[WIFI] SSID not configured; skipping WiFi connect"); + return; + } + + Serial.printf("[WIFI] Connecting to SSID: %s\n", WIFI_SSID); + WiFi.mode(WIFI_STA); + WiFi.begin(WIFI_SSID, WIFI_PASS); + + unsigned long start = millis(); + while ((WiFi.status() != WL_CONNECTED) && ((millis() - start) < 15000UL)) { + delay(200); + Serial.print('.'); + } + + Serial.println(); + if (WiFi.status() == WL_CONNECTED) { + Serial.printf( + "[WIFI] Connected. IP: %s\n", WiFi.localIP().toString().c_str()); + } else { + Serial.printf( + "[WIFI] Connect timeout. status=%d\n", (int)WiFi.status()); + } +#endif +} + +/** + * @brief Initialize the BACnet/IP application and selected board profile + */ +void setup(void) +{ + Serial.begin(115200); + delay(100); + Serial.println("[BOOT] Mode: BACnet/IP"); + Serial.printf("[BOOT] BACnet UDP Port: %u\n", (unsigned)BACNET_IP_PORT); +#if USE_ETH_INTERFACE + Serial.println("[BOOT] Network: Ethernet"); +#else + Serial.println("[BOOT] Network: WiFi"); +#endif +#if USE_M5STAMPLC_IO + Serial.println("[BOOT] Board profile: M5StamPLC I/O enabled"); + M5StamPLC.begin(); +#else + Serial.println("[BOOT] Board profile: Generic/ESP32-PoE (M5 I/O disabled)"); +#endif + wifi_connect(); + Serial.println("[BOOT] Init BACnet app..."); + bacnet_app_init(); + Serial.println("[BOOT] BACnet/IP ready"); +} + +/** + * @brief Run the main BACnet/IP application loop + */ +void loop(void) +{ +#if USE_M5STAMPLC_IO + M5StamPLC.update(); + + for (uint8_t i = 0; i < bacnet_app_input_count(); i++) { + bool state = M5StamPLC.readPlcInput(i); +#if PLC_INPUT_ACTIVE_LOW + state = !state; +#endif + bacnet_app_input_set(i, state); + } + + for (uint8_t i = 0; i < bacnet_app_relay_count(); i++) { + M5StamPLC.writePlcRelay(i, bacnet_app_relay_get(i)); + } + + bacnet_app_temperature_set(M5StamPLC.getTemp()); + bacnet_app_free_heap_kb_set((float)ESP.getFreeHeap() / 1024.0f); +#else + bacnet_app_temperature_set(0.0f); + bacnet_app_free_heap_kb_set((float)ESP.getFreeHeap() / 1024.0f); +#endif + + bacnet_app_tick(); + delay(1); +} diff --git a/ports/esp32/src/main_gateway_router.cpp b/ports/esp32/src/main_gateway_router.cpp new file mode 100644 index 00000000..0123cd34 --- /dev/null +++ b/ports/esp32/src/main_gateway_router.cpp @@ -0,0 +1,332 @@ +/** + * @file + * @brief BACnet router entry point bridging BACnet/IP and BACnet MS/TP + * @author Kato Gangstad + */ + +#include +#include +#include +#include + +extern "C" { +#include "bacnet_app.h" +#include "bip.h" +#include "dlenv.h" +#include "bacnet/bacdcode.h" +#include "bacnet/npdu.h" +#include "bacnet/apdu.h" +#include "bacnet/datalink/dlmstp.h" +#include "bacnet/basic/npdu/h_npdu.h" +#include "bacnet/basic/tsm/tsm.h" +} + +#ifndef WIFI_SSID +#define WIFI_SSID "" +#endif + +#ifndef WIFI_PASS +#define WIFI_PASS "" +#endif + +#ifndef BACNET_IP_PORT +#define BACNET_IP_PORT 47808 +#endif + +#ifndef ROUTER_BIP_NET +#define ROUTER_BIP_NET 1 +#endif + +#ifndef ROUTER_MSTP_NET +#define ROUTER_MSTP_NET 200 +#endif + +#ifndef ROUTER_MSTP_MAC +#define ROUTER_MSTP_MAC 2 +#endif + +#ifndef PLC_INPUT_ACTIVE_LOW +#define PLC_INPUT_ACTIVE_LOW 0 +#endif + +#ifndef GATEWAY_MAX +#define GATEWAY_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +static uint8_t BipRxBuffer[BIP_MPDU_MAX]; +static uint8_t MstpRxBuffer[DLMSTP_MPDU_MAX]; +static uint8_t TxBuffer[GATEWAY_MAX(BIP_MPDU_MAX, DLMSTP_MPDU_MAX)]; + +/** + * @brief Connect the BACnet/IP side of the router to WiFi + */ +static void wifi_connect(void) +{ + if (strlen(WIFI_SSID) == 0) { + Serial.println("[WIFI] SSID not configured; skipping WiFi connect"); + return; + } + + Serial.printf("[WIFI] Connecting to SSID: %s\n", WIFI_SSID); + WiFi.mode(WIFI_STA); + WiFi.begin(WIFI_SSID, WIFI_PASS); + + unsigned long start = millis(); + while ((WiFi.status() != WL_CONNECTED) && ((millis() - start) < 15000UL)) { + delay(200); + Serial.print('.'); + } + Serial.println(); + + if (WiFi.status() == WL_CONNECTED) { + Serial.printf( + "[WIFI] Connected. IP: %s\n", WiFi.localIP().toString().c_str()); + } else { + Serial.printf( + "[WIFI] Connect timeout. status=%d\n", (int)WiFi.status()); + } +} + +/** + * @brief Send a BACnet router network message on the MS/TP segment + * @param type network layer message type + * @param dnet destination network number, or negative when omitted + * @return number of bytes sent, or a negative value on error + */ +static int +send_router_message_on_mstp(BACNET_NETWORK_MESSAGE_TYPE type, int dnet) +{ + BACNET_NPDU_DATA npdu_data = { 0 }; + BACNET_ADDRESS dest = { 0 }; + int pdu_len = 0; + + dest.mac_len = 0; + dest.net = BACNET_BROADCAST_NETWORK; + dest.len = 0; + + npdu_encode_npdu_network(&npdu_data, type, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(TxBuffer, &dest, NULL, &npdu_data); + if (dnet >= 0) { + pdu_len += encode_unsigned16(&TxBuffer[pdu_len], (uint16_t)dnet); + } + + return dlmstp_send_pdu(&dest, &npdu_data, TxBuffer, (unsigned)pdu_len); +} + +/** + * @brief Send a BACnet router network message on the BACnet/IP segment + * @param type network layer message type + * @param dnet destination network number, or negative when omitted + * @return number of bytes sent, or a negative value on error + */ +static int +send_router_message_on_bip(BACNET_NETWORK_MESSAGE_TYPE type, int dnet) +{ + BACNET_NPDU_DATA npdu_data = { 0 }; + BACNET_ADDRESS dest = { 0 }; + int pdu_len = 0; + + bip_get_broadcast_address(&dest); + + npdu_encode_npdu_network(&npdu_data, type, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(TxBuffer, &dest, NULL, &npdu_data); + if (dnet >= 0) { + pdu_len += encode_unsigned16(&TxBuffer[pdu_len], (uint16_t)dnet); + } + + return bip_send_pdu(&dest, &npdu_data, TxBuffer, (unsigned)pdu_len); +} + +/** + * @brief Check whether a received NPDU should be processed by the local device + * @param dest decoded destination address + * @return true if the packet targets the local device or broadcast + */ +static bool should_process_locally(const BACNET_ADDRESS *dest) +{ + return (dest->net == 0U) || (dest->net == BACNET_BROADCAST_NETWORK); +} + +/** + * @brief Route an NPDU between BACnet/IP and MS/TP segments + * @param from_bip true when the frame arrived from BACnet/IP + * @param src decoded source address + * @param pdu NPDU buffer to route + * @param pdu_len NPDU length in bytes + */ +static void +forward_pdu(bool from_bip, BACNET_ADDRESS *src, uint8_t *pdu, uint16_t pdu_len) +{ + BACNET_ADDRESS dest = { 0 }; + BACNET_ADDRESS routed_src = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; + int apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data); + if (apdu_offset <= 0) { + return; + } + + const uint16_t src_net = from_bip ? ROUTER_BIP_NET : ROUTER_MSTP_NET; + const uint16_t dst_net = from_bip ? ROUTER_MSTP_NET : ROUTER_BIP_NET; + + if (npdu_data.network_layer_message) { + if (npdu_data.network_message_type == + NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK) { + uint16_t requested = 0; + bool has_dnet = (pdu_len - apdu_offset) >= 2; + if (has_dnet) { + (void)decode_unsigned16(&pdu[apdu_offset], &requested); + } + if (!has_dnet || (requested == dst_net)) { + if (from_bip) { + send_router_message_on_bip( + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, dst_net); + } else { + send_router_message_on_mstp( + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, dst_net); + } + } + } + return; + } + + if ((dest.net != 0U) && (dest.net != BACNET_BROADCAST_NETWORK) && + (dest.net != dst_net)) { + return; + } + + if (npdu_data.hop_count > 0) { + npdu_data.hop_count--; + if (npdu_data.hop_count == 0) { + return; + } + } + + if (src->net != 0U) { + routed_src = *src; + } else { + memset(&routed_src, 0, sizeof(routed_src)); + routed_src.net = src_net; + routed_src.len = src->mac_len; + for (uint8_t i = 0; i < src->mac_len && i < MAX_MAC_LEN; i++) { + routed_src.adr[i] = src->mac[i]; + } + } + + BACNET_ADDRESS out_dest = { 0 }; + if (dest.net == BACNET_BROADCAST_NETWORK || + ((dest.net == dst_net) && (dest.len == 0))) { + out_dest.mac_len = 0; + out_dest.net = BACNET_BROADCAST_NETWORK; + out_dest.len = 0; + } else if ((dest.net == dst_net) && (dest.len > 0)) { + out_dest.mac_len = dest.len; + for (uint8_t i = 0; i < dest.len && i < MAX_MAC_LEN; i++) { + out_dest.mac[i] = dest.adr[i]; + } + out_dest.net = 0; + out_dest.len = 0; + } else { + out_dest = dest; + } + + int out_len = npdu_encode_pdu(TxBuffer, &out_dest, &routed_src, &npdu_data); + if (out_len <= 0) { + return; + } + + const uint16_t apdu_len = (uint16_t)(pdu_len - apdu_offset); + if ((out_len + (int)apdu_len) > (int)sizeof(TxBuffer)) { + return; + } + memcpy(&TxBuffer[out_len], &pdu[apdu_offset], apdu_len); + out_len += apdu_len; + + if (from_bip) { + (void)dlmstp_send_pdu( + &out_dest, &npdu_data, TxBuffer, (unsigned)out_len); + } else { + (void)bip_send_pdu(&out_dest, &npdu_data, TxBuffer, (unsigned)out_len); + } +} + +/** + * @brief Initialize the BACnet router and local device services + */ +void setup(void) +{ + Serial.begin(115200); + delay(100); + Serial.println("[BOOT] Mode: BACnet Gateway (Router + Local Device)"); + Serial.printf( + "[GATEWAY] BIP NET=%u MSTP NET=%u MSTP MAC=%u\n", + (unsigned)ROUTER_BIP_NET, (unsigned)ROUTER_MSTP_NET, + (unsigned)ROUTER_MSTP_MAC); + + M5StamPLC.begin(); + wifi_connect(); + + /* Local device + objects run on B/IP side (same logic as existing M5 app). + */ + bacnet_app_init(); + + if (!m5_dlenv_init((uint8_t)ROUTER_MSTP_MAC)) { + Serial.println("[GATEWAY] ERROR: MSTP init failed"); + for (;;) { + delay(1000); + } + } + + (void)send_router_message_on_bip( + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, ROUTER_MSTP_NET); + (void)send_router_message_on_mstp( + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, ROUTER_BIP_NET); + + Serial.println("[GATEWAY] Ready"); +} + +/** + * @brief Run the BACnet router main loop + */ +void loop(void) +{ + BACNET_ADDRESS src = { 0 }; + BACNET_ADDRESS dest = { 0 }; + BACNET_NPDU_DATA npdu_data = { 0 }; + uint16_t pdu_len = 0; + + M5StamPLC.update(); + + for (uint8_t i = 0; i < bacnet_app_input_count(); i++) { + bool state = M5StamPLC.readPlcInput(i); +#if PLC_INPUT_ACTIVE_LOW + state = !state; +#endif + bacnet_app_input_set(i, state); + } + + for (uint8_t i = 0; i < bacnet_app_relay_count(); i++) { + M5StamPLC.writePlcRelay(i, bacnet_app_relay_get(i)); + } + + bacnet_app_temperature_set(M5StamPLC.getTemp()); + bacnet_app_free_heap_kb_set((float)ESP.getFreeHeap() / 1024.0f); + + pdu_len = bip_receive(&src, BipRxBuffer, sizeof(BipRxBuffer), 0); + if (pdu_len > 0) { + int apdu_offset = + bacnet_npdu_decode(BipRxBuffer, pdu_len, &dest, &src, &npdu_data); + if ((apdu_offset > 0) && should_process_locally(&dest)) { + npdu_handler(&src, BipRxBuffer, pdu_len); + } + forward_pdu(true, &src, BipRxBuffer, pdu_len); + } + + pdu_len = dlmstp_receive(&src, MstpRxBuffer, sizeof(MstpRxBuffer), 0); + if (pdu_len > 0) { + forward_pdu(false, &src, MstpRxBuffer, pdu_len); + } + + tsm_timer_milliseconds(1); + + delay(1); +} diff --git a/ports/esp32/src/mstimer_init.c b/ports/esp32/src/mstimer_init.c new file mode 100644 index 00000000..a10269dc --- /dev/null +++ b/ports/esp32/src/mstimer_init.c @@ -0,0 +1,26 @@ +/** + * @file + * @brief BACnet millisecond timer hooks for the PlatformIO ESP32 port + * @author Kato Gangstad + */ + +#include "mstimer_init.h" + +#include "esp_timer.h" + +/** + * @brief Initialize the system timer services used by BACnet + */ +void systimer_init(void) +{ + /* esp_timer is available after runtime startup on ESP32. */ +} + +/** + * @brief Get the current millisecond tick count + * @return milliseconds since startup + */ +unsigned long mstimer_now(void) +{ + return (unsigned long)(esp_timer_get_time() / 1000ULL); +} diff --git a/ports/esp32/src/mstimer_init.h b/ports/esp32/src/mstimer_init.h new file mode 100644 index 00000000..55c5f9df --- /dev/null +++ b/ports/esp32/src/mstimer_init.h @@ -0,0 +1,32 @@ +/** + * @file + * @brief BACnet millisecond timer hook declarations for the PlatformIO ESP32 + * port + * @author Kato Gangstad + */ + +#ifndef M5STAMPLC_MSTIMER_INIT_H +#define M5STAMPLC_MSTIMER_INIT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize the system timer services used by BACnet + */ +void systimer_init(void); + +/** + * @brief Get the current millisecond tick count + * @return milliseconds since startup + */ +unsigned long mstimer_now(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/esp32/src/rs485.c b/ports/esp32/src/rs485.c new file mode 100644 index 00000000..7e89c81a --- /dev/null +++ b/ports/esp32/src/rs485.c @@ -0,0 +1,184 @@ +/** + * @file + * @brief RS485 UART driver used by BACnet MS/TP on ESP32 + * @author Kato Gangstad + */ + +#include "rs485.h" + +#include +#include + +/* UART_SCLK_DEFAULT was introduced in ESP-IDF v5.0. + Fall back to UART_SCLK_APB for older IDF/Arduino-ESP32 toolchains. */ +#ifndef UART_SCLK_DEFAULT +#define UART_SCLK_DEFAULT UART_SCLK_APB +#endif + +#include "bacnet/basic/sys/mstimer.h" + +static bool Rs485_RTS_Enabled; +static uint32_t Rs485_Baud_Rate = RS485_BAUD_RATE; +static volatile uint32_t Rs485_Bytes_Tx; +static volatile uint32_t Rs485_Bytes_Rx; +static struct mstimer Silence_Timer; + +/** + * @brief Initialize the RS485 UART peripheral for BACnet MS/TP + */ +void rs485_init(void) +{ + uart_config_t cfg = { .baud_rate = (int)Rs485_Baud_Rate, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_DEFAULT }; + + (void)uart_driver_delete(RS485_UART_NUM); + (void)uart_param_config(RS485_UART_NUM, &cfg); + (void)uart_set_pin( + RS485_UART_NUM, RS485_TX_PIN, RS485_RX_PIN, RS485_DIR_PIN, + UART_PIN_NO_CHANGE); + (void)uart_driver_install(RS485_UART_NUM, 1024, 0, 0, NULL, 0); + (void)uart_set_mode(RS485_UART_NUM, UART_MODE_RS485_HALF_DUPLEX); + + Rs485_RTS_Enabled = false; + Rs485_Bytes_Tx = 0; + Rs485_Bytes_Rx = 0; + rs485_silence_reset(); +} + +/** + * @brief Update the cached RS485 transmit-enable state + * @param enable true when transmit is active + */ +void rs485_rts_enable(bool enable) +{ + /* Hardware RS485 half-duplex mode drives DIR. Keep state for stack queries. + */ + Rs485_RTS_Enabled = enable; +} + +/** + * @brief Check whether the RS485 transmit-enable state is active + * @return true if transmit is active + */ +bool rs485_rts_enabled(void) +{ + return Rs485_RTS_Enabled; +} + +/** + * @brief Read one byte from the RS485 receive FIFO when available + * @param data_register destination for the received byte, or NULL to probe only + * @return true if at least one byte is available + */ +bool rs485_byte_available(uint8_t *data_register) +{ + size_t buffered = 0; + (void)uart_get_buffered_data_len(RS485_UART_NUM, &buffered); + if (buffered == 0U) { + return false; + } + if (!data_register) { + return true; + } + + if (uart_read_bytes(RS485_UART_NUM, data_register, 1, 0) == 1) { + Rs485_Bytes_Rx++; + rs485_silence_reset(); + return true; + } + + return false; +} + +/** + * @brief Report whether an RS485 receive error is pending + * @return true if a receive error is detected + */ +bool rs485_receive_error(void) +{ + /* In Arduino-ESP32 builds, low-level UART error queues are not always + * exposed. */ + return false; +} + +/** + * @brief Send a block of RS485 bytes + * @param buffer transmit buffer + * @param nbytes number of bytes to send + */ +void rs485_bytes_send(const uint8_t *buffer, uint16_t nbytes) +{ + if (!buffer || (nbytes == 0U)) { + return; + } + + rs485_rts_enable(true); + (void)uart_write_bytes(RS485_UART_NUM, (const char *)buffer, nbytes); + (void)uart_wait_tx_done(RS485_UART_NUM, pdMS_TO_TICKS(20)); + Rs485_Bytes_Tx += nbytes; + rs485_rts_enable(false); + rs485_silence_reset(); +} + +/** + * @brief Get the configured RS485 baud rate + * @return baud rate in bits per second + */ +uint32_t rs485_baud_rate(void) +{ + return Rs485_Baud_Rate; +} + +/** + * @brief Set the RS485 baud rate + * @param baud baud rate in bits per second + * @return true if the baud rate was applied + */ +bool rs485_baud_rate_set(uint32_t baud) +{ + if (baud == 0U) { + return false; + } + + Rs485_Baud_Rate = baud; + return (uart_set_baudrate(RS485_UART_NUM, (int)Rs485_Baud_Rate) == ESP_OK); +} + +/** + * @brief Get the elapsed silent time on the RS485 bus + * @return milliseconds since the last bus activity + */ +uint32_t rs485_silence_milliseconds(void) +{ + return mstimer_elapsed(&Silence_Timer); +} + +/** + * @brief Reset the RS485 silence timer + */ +void rs485_silence_reset(void) +{ + mstimer_set(&Silence_Timer, 0); +} + +/** + * @brief Get the number of transmitted RS485 bytes + * @return transmitted byte count + */ +uint32_t rs485_bytes_transmitted(void) +{ + return Rs485_Bytes_Tx; +} + +/** + * @brief Get the number of received RS485 bytes + * @return received byte count + */ +uint32_t rs485_bytes_received(void) +{ + return Rs485_Bytes_Rx; +} diff --git a/ports/esp32/src/rs485.h b/ports/esp32/src/rs485.h new file mode 100644 index 00000000..51d2276f --- /dev/null +++ b/ports/esp32/src/rs485.h @@ -0,0 +1,100 @@ +/** + * @file + * @brief RS485 UART driver declarations used by BACnet MS/TP on ESP32 + * @author Kato Gangstad + */ + +#ifndef M5STAMPLC_RS485_H +#define M5STAMPLC_RS485_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define RS485_UART_NUM UART_NUM_1 +#define RS485_BAUD_RATE 38400 +#define RS485_TX_PIN 0 +#define RS485_RX_PIN 39 +#define RS485_DIR_PIN 46 + +/** + * @brief Initialize the RS485 UART peripheral + */ +void rs485_init(void); + +/** + * @brief Update the cached RS485 transmit-enable state + * @param enable true when transmit is active + */ +void rs485_rts_enable(bool enable); + +/** + * @brief Check whether the RS485 transmit-enable state is active + * @return true if transmit is active + */ +bool rs485_rts_enabled(void); + +/** + * @brief Read one byte from the RS485 receive FIFO when available + * @param data_register destination for the received byte, or NULL to probe only + * @return true if a byte is available + */ +bool rs485_byte_available(uint8_t *data_register); + +/** + * @brief Report whether an RS485 receive error is pending + * @return true if a receive error is detected + */ +bool rs485_receive_error(void); + +/** + * @brief Send a block of RS485 bytes + * @param buffer transmit buffer + * @param nbytes number of bytes to send + */ +void rs485_bytes_send(const uint8_t *buffer, uint16_t nbytes); + +/** + * @brief Get the configured RS485 baud rate + * @return baud rate in bits per second + */ +uint32_t rs485_baud_rate(void); + +/** + * @brief Set the RS485 baud rate + * @param baud baud rate in bits per second + * @return true if the baud rate was applied + */ +bool rs485_baud_rate_set(uint32_t baud); + +/** + * @brief Get the elapsed silent time on the RS485 bus + * @return milliseconds since the last bus activity + */ +uint32_t rs485_silence_milliseconds(void); + +/** + * @brief Reset the RS485 silence timer + */ +void rs485_silence_reset(void); + +/** + * @brief Get the number of transmitted RS485 bytes + * @return transmitted byte count + */ +uint32_t rs485_bytes_transmitted(void); + +/** + * @brief Get the number of received RS485 bytes + * @return received byte count + */ +uint32_t rs485_bytes_received(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ports/esp32/src/sdkconfig.h b/ports/esp32/src/sdkconfig.h deleted file mode 100644 index 64ef778b..00000000 --- a/ports/esp32/src/sdkconfig.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * - * Automatically generated file; DO NOT EDIT. - * Espressif IoT Development Framework Configuration - * - */ -#define CONFIG_GATTC_ENABLE 1 -#define CONFIG_ESP32_PHY_MAX_TX_POWER 20 -#define CONFIG_PHY_ENABLED 1 -#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0 -#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16 -#define CONFIG_BLE_SMP_ENABLE 1 -#define CONFIG_IPC_TASK_STACK_SIZE 1024 -#define CONFIG_ESPTOOLPY_FLASHFREQ "40m" -#define CONFIG_NEWLIB_STDOUT_ADDCR 1 -#define CONFIG_TASK_WDT_CHECK_IDLE_TASK 1 -#define CONFIG_ESPTOOLPY_FLASHSIZE "2MB" -#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1 -#define CONFIG_ETHERNET 1 -#define CONFIG_INT_WDT 1 -#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1 -#define CONFIG_LOG_BOOTLOADER_LEVEL_INFO 1 -#define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1 -#define CONFIG_AWS_IOT_MQTT_PORT 8883 -#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1 -#define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10 -#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1 -#define CONFIG_BT_RESERVE_DRAM 0x10000 -#define CONFIG_ESP32_PANIC_PRINT_REBOOT 1 -#define CONFIG_CONSOLE_UART_BAUDRATE 115200 -#define CONFIG_LWIP_MAX_SOCKETS 10 -#define CONFIG_EMAC_TASK_PRIORITY 20 -#define CONFIG_TIMER_TASK_STACK_DEPTH 2048 -#define CONFIG_FATFS_CODEPAGE 1 -#define CONFIG_ESP32_DEFAULT_CPU_FREQ_160 1 -#define CONFIG_ULP_COPROC_RESERVE_MEM 0 -#define CONFIG_ESPTOOLPY_BAUD 115200 -#define CONFIG_INT_WDT_CHECK_CPU1 1 -#define CONFIG_FLASHMODE_DIO 1 -#define CONFIG_ESPTOOLPY_AFTER_RESET 1 -#define CONFIG_TOOLPREFIX "xtensa-esp32-elf-" -#define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1024 -#define CONFIG_ESP32_WIFI_AMPDU_ENABLED 1 -#define CONFIG_CONSOLE_UART_NUM 0 -#define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC 1 -#define CONFIG_ESPTOOLPY_BAUD_115200B 1 -#define CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX 0 -#define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS 1 -#define CONFIG_CONSOLE_UART_DEFAULT 1 -#define CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN 16384 -#define CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS 4 -#define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1 -#define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1 -#define CONFIG_BTDM_CONTROLLER_RUN_CPU 0 -#define CONFIG_TCPIP_TASK_STACK_SIZE 2560 -#define CONFIG_TASK_WDT 1 -#define CONFIG_MAIN_TASK_STACK_SIZE 4096 -#define CONFIG_TASK_WDT_TIMEOUT_S 5 -#define CONFIG_INT_WDT_TIMEOUT_MS 300 -#define CONFIG_ESPTOOLPY_FLASHMODE "dio" -#define CONFIG_BTC_TASK_STACK_SIZE 3072 -#define CONFIG_BLUEDROID_ENABLED 1 -#define CONFIG_ESPTOOLPY_BEFORE "default_reset" -#define CONFIG_LOG_DEFAULT_LEVEL 3 -#define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1 -#define CONFIG_TIMER_QUEUE_LENGTH 10 -#define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32 -#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20 -#define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 1024 -#define CONFIG_ESP32_WIFI_NVS_ENABLED 1 -#define CONFIG_AWS_IOT_SDK 1 -#define CONFIG_DMA_RX_BUF_NUM 10 -#define CONFIG_TCP_SYNMAXRTX 6 -#define CONFIG_PYTHON "python" -#define CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 1 -#define CONFIG_ESPTOOLPY_COMPRESSED 1 -#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv" -#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1 -#define CONFIG_PARTITION_TABLE_SINGLE_APP 1 -#define CONFIG_WIFI_ENABLED 1 -#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1 -#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE 4096 -#define CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 2000 -#define CONFIG_ESP32_APPTRACE_DEST_NONE 1 -#define CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET 0x10000 -#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32 -#define CONFIG_FATFS_CODEPAGE_ASCII 1 -#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 1 -#define CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ 160 -#define CONFIG_FREERTOS_HZ 100 -#define CONFIG_LOG_COLORS 1 -#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1 -#define CONFIG_FREERTOS_ASSERT_FAIL_ABORT 1 -#define CONFIG_ESP32_XTAL_FREQ 0 -#define CONFIG_MONITOR_BAUD_115200B 1 -#define CONFIG_LOG_BOOTLOADER_LEVEL 3 -#define CONFIG_SMP_ENABLE 1 -#define CONFIG_ESPTOOLPY_BEFORE_RESET 1 -#define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200 -#define CONFIG_ESP32_XTAL_FREQ_AUTO 1 -#define CONFIG_TCP_MAXRTX 12 -#define CONFIG_ESPTOOLPY_AFTER "hard_reset" -#define CONFIG_DMA_TX_BUF_NUM 10 -#define CONFIG_ESP32_DEBUG_OCDAWARE 1 -#define CONFIG_TIMER_TASK_PRIORITY 1 -#define CONFIG_BT_ENABLED 1 -#define CONFIG_MONITOR_BAUD 115200 -#define CONFIG_FREERTOS_CORETIMER_0 1 -#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv" -#define CONFIG_MBEDTLS_HAVE_TIME 1 -#define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1 -#define CONFIG_GATTS_ENABLE 1 -#define CONFIG_FREERTOS_ISR_STACKSIZE 1536 -#define CONFIG_OPENSSL_ASSERT_DO_NOTHING 1 -#define CONFIG_AWS_IOT_MQTT_HOST "" -#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE 32 -#define CONFIG_BT_ACL_CONNECTIONS 4 -#define CONFIG_FATFS_MAX_LFN 255 -#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1 -#define CONFIG_APP_OFFSET 0x10000 -#define CONFIG_MEMMAP_SMP 1 -#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1 -#define CONFIG_MONITOR_BAUD_OTHER_VAL 115200 -#define CONFIG_ESPTOOLPY_PORT "/dev/ttyUSB0" -#define CONFIG_OPTIMIZATION_LEVEL_RELEASE 1