From 06324183c996be01b305bf4ae5ab0688585a2d14 Mon Sep 17 00:00:00 2001 From: Anirudh Date: Sat, 31 Jan 2026 03:25:29 +0530 Subject: [PATCH 1/5] added nhlomann json, cmake, vcpkg, yaml dependenices. crow server now runs, compiler.exe built --- .gitignore | 5 +++ src/compiler/CMakeLists.txt | 74 +++++++++++++++++++++++++++++++++++++ src/ui/electron/main.cjs | 2 +- 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/compiler/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 5b350f4..16d5d90 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,11 @@ src/ui/node_modules/ src/ui/electron/node_modules/ src/compiler/ast/ src/compiler/bad.json +src/compiler/build/ +src/compiler/compiler.pdb +src/compiler/yaml-cppd.dll +vcpkg/ .vscode/ *.exe node_modules/ +C:\Users\Admin\Desktop\simrun\src\compiler\compiler.exe \ No newline at end of file diff --git a/src/compiler/CMakeLists.txt b/src/compiler/CMakeLists.txt new file mode 100644 index 0000000..ecea795 --- /dev/null +++ b/src/compiler/CMakeLists.txt @@ -0,0 +1,74 @@ +cmake_minimum_required(VERSION 3.15) +project(compiler) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# --------------------------- +# Find packages (vcpkg CONFIG mode) +# --------------------------- +find_package(nlohmann_json CONFIG REQUIRED) +find_package(yaml-cpp CONFIG REQUIRED) +# Uncomment if this project also uses Crow +# find_package(Crow CONFIG REQUIRED) + +# --------------------------- +# Source files +# --------------------------- +set(SOURCES + src/server.cpp + src/compiler_driver.cpp + src/ir_parser.cpp + src/validator.cpp + src/profile_repository.cpp + src/profile_resolver.cpp + src/ir_serializer.cpp +) + +# --------------------------- +# Create executable +# --------------------------- +add_executable(compiler ${SOURCES}) +# Put the final .exe in the project source/compiler folder +set_target_properties(compiler PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}" + RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_SOURCE_DIR}" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_SOURCE_DIR}" + RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_SOURCE_DIR}" + RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_SOURCE_DIR}" +) + + +# --------------------------- +# Link libraries +# --------------------------- +target_link_libraries(compiler + PRIVATE + nlohmann_json::nlohmann_json + yaml-cpp + # Crow::Crow # Uncomment if using Crow +) + +# --------------------------- +# Include directories +# --------------------------- +target_include_directories(compiler + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +# --------------------------- +# Output directory +# --------------------------- +set_target_properties(compiler PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) + +# --------------------------- +# Compiler warnings +# --------------------------- +if(MSVC) + target_compile_options(compiler PRIVATE /W4) +else() + target_compile_options(compiler PRIVATE -Wall -Wextra -Wpedantic) +endif() diff --git a/src/ui/electron/main.cjs b/src/ui/electron/main.cjs index 6c984a3..c525a88 100644 --- a/src/ui/electron/main.cjs +++ b/src/ui/electron/main.cjs @@ -46,7 +46,7 @@ function postToCompiler(pathname, data) { const options = { hostname: '127.0.0.1', port: 18080, - path: pathname, + path: '/compile', method: 'POST', headers: { 'Content-Type': 'application/json', From 0eb5b8ed26dc549bf2c695cf921c471c6fed57a4 Mon Sep 17 00:00:00 2001 From: Anirudh Date: Sat, 31 Jan 2026 05:18:23 +0530 Subject: [PATCH 2/5] debugged, vite running on 5173, crow/compiler running on 8081 --- .gitignore | 2 +- HOWTO_RUN.txt | 51 +++++++++++++++++++ profiles/components/api/service/default.yaml | 6 --- profiles/components/cache/default.yaml | 5 -- profiles/components/database/default.yaml | 9 ---- profiles/networks/ethernet.yaml | 6 --- src/compiler/src/server.cpp | 2 +- src/compiler/yaml-cpp.dll | Bin 0 -> 254464 bytes src/ui/electron/main.cjs | 45 +++++++++------- src/ui/package.json | 2 +- src/ui/src/pages/Index.tsx | 23 ++++++++- src/ui/vite.config.ts | 2 +- 12 files changed, 104 insertions(+), 49 deletions(-) create mode 100644 HOWTO_RUN.txt delete mode 100644 profiles/components/api/service/default.yaml delete mode 100644 profiles/components/cache/default.yaml delete mode 100644 profiles/components/database/default.yaml delete mode 100644 profiles/networks/ethernet.yaml create mode 100644 src/compiler/yaml-cpp.dll diff --git a/.gitignore b/.gitignore index 16d5d90..1ab5018 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ vcpkg/ .vscode/ *.exe node_modules/ -C:\Users\Admin\Desktop\simrun\src\compiler\compiler.exe \ No newline at end of file +src\compiler\compiler.exe \ No newline at end of file diff --git a/HOWTO_RUN.txt b/HOWTO_RUN.txt new file mode 100644 index 0000000..509bb6e --- /dev/null +++ b/HOWTO_RUN.txt @@ -0,0 +1,51 @@ +How to run this project (Windows and Linux) + +Prerequisites (both): +- Git +- Node.js (16+) and npm +- CMake (3.18+) +- A C++ compiler/toolchain: Visual Studio (Windows) or gcc/clang + build-essential (Linux) +- vcpkg (if the project uses vcpkg to provide C++ dependencies) + +1) UI (Electron + Vite) + +Install dependencies (both): +- Open a terminal at the repo root +- cd src/ui +- npm install + +Development (live reload + Electron): +- npm run electron:dev + - This runs Vite dev server and launches Electron after the dev server is ready. + +Production build and run: +- npm run build +- npm run electron + - `npm run electron` launches Electron against the built files. + +2) C++ components (compiler / sim) + +Windows (Visual Studio generator): +- Open a Developer PowerShell or MSVC prompt +- cd src/compiler +- mkdir build && cd build +- cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=..\..\vcpkg\scripts\buildsystems\vcpkg.cmake .. +- cmake --build . --config Release +- Run the produced executable from the build output (e.g., `build\Release\.exe`). + +Linux (Makefile / Ninja): +- Open a terminal +- cd src/compiler +- mkdir build && cd build +- cmake -DCMAKE_BUILD_TYPE=Release .. +- cmake --build . -- -j$(nproc) +- Run the produced binary (e.g., `./`). + +Notes: +- If the project uses vcpkg, bootstrap vcpkg and install required packages, then use `-DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake` when calling `cmake`. +- Paths and executable names may vary by platform and CMake configuration; adjust the commands above to match the real CMake target and output location in your build. +- If you only want to run the UI and not rebuild C++ components, follow section (1) only. + +If you want, I can: +- Add a `README` section in `src/ui` with the same commands, +- Or create npm scripts to automate CMake build steps from the repo root. diff --git a/profiles/components/api/service/default.yaml b/profiles/components/api/service/default.yaml deleted file mode 100644 index d071a69..0000000 --- a/profiles/components/api/service/default.yaml +++ /dev/null @@ -1,6 +0,0 @@ -defaults: - dist_latency: lognormal - base_median_latency: 30 - base_variance_latency: 0.8 - max_concurrency: 100 - queue_capacity: 300 diff --git a/profiles/components/cache/default.yaml b/profiles/components/cache/default.yaml deleted file mode 100644 index 0592367..0000000 --- a/profiles/components/cache/default.yaml +++ /dev/null @@ -1,5 +0,0 @@ -defaults: - base_cache_hit_probability: 0.85 - base_cache_hit_latency: 0.2 - base_cache_miss_latency: 1.0 - max_concurrency: 500 diff --git a/profiles/components/database/default.yaml b/profiles/components/database/default.yaml deleted file mode 100644 index afa0a1f..0000000 --- a/profiles/components/database/default.yaml +++ /dev/null @@ -1,9 +0,0 @@ -defaults: - seek_model: lognormal - base_median_seek_ms: 5.0 - base_variance_seek_ms: 0.6 - max_iops: 4000 - bucket_capacity: 8000 - initial_tokens: 8000 - max_concurrency: 1500 - queue_capacity: 5000 diff --git a/profiles/networks/ethernet.yaml b/profiles/networks/ethernet.yaml deleted file mode 100644 index e7cfc3a..0000000 --- a/profiles/networks/ethernet.yaml +++ /dev/null @@ -1,6 +0,0 @@ -defaults: - base_median_latency: 1 - base_variance_latency: 0.5 - base_bandwidth_mbps: 1000 - base_packet_size_bytes: 1500 - queue_capacity: 2048 diff --git a/src/compiler/src/server.cpp b/src/compiler/src/server.cpp index 7bf48a3..4693159 100644 --- a/src/compiler/src/server.cpp +++ b/src/compiler/src/server.cpp @@ -40,5 +40,5 @@ int main() { }); - app.port(8080).run(); + app.port(8081).run(); } diff --git a/src/compiler/yaml-cpp.dll b/src/compiler/yaml-cpp.dll new file mode 100644 index 0000000000000000000000000000000000000000..d7458aba70f89759333cea484c888f9fecf95939 GIT binary patch literal 254464 zcmeFadwf*Y)&D=a41`OZpbiEt5;WFmP=jb24C)LJaz-Z@#S30RsTQpwNCMso1|-wd zX{q(v+SW^J``BvL`XJJ(0dx{XxoBIUv}$cDCq^r1a$J-TisrFt1{F zhdlDe7v*PgH& zQxz!)d}Bf&aOdp>fevLZDGa=&g5D|!EI3jT-oLWKKs60lvNk_(wjY=CZYI70c-^b{ zfrv}G`}K+Zzyls#Imt7@V;e8Oz7c54kGy)S?mg0%1p-r#z3v;AHeMPC9QJP#gEO$5 z_XE6h{zd3U$GXV^_a4QECm{Gx-gm3VW&cG2fwp63x(Q7ksjDIW={?d#j=gU7b<@ad zcmi+4`@mm%OLzIz*OE{?3cxEFZT|D%Kavv zm0Pf72jBYd{6Hf3XMoT%!3_XcB!cS%EeWm$Y7M>wkP5!QGXM?ic?-*xzjCn%77Y)Q zR-``(YzKd2kUmBjq<6ST9~QJEc)LM*FF-1I2TzZ>`v{7v2YCzMr5?Wdz;^ILgYOo? z;5*C3H(St>-~@wjIzTFT8BY)2l>|lSNUyeng?EUDHwJ764={LZ34^J>!88US75o}c z57VgxMOhthVc7DtThk+f?cm>l62Zd>gJB~;Yw%!zRPaEa9)_U=MN9ZMF3$uD(_|C#X!{<*iI_kW5`@2CyC6XfjA|&z2!LoZlZD2v~{WIYdBB@VUnfH3klq6yFV|(4eAJq{PEf@1`sMm=8iESOhHe z2sj3qO5du_iQthyso-Hez3j&lq?nJC3c2f@mp!F=E)?goiR4~9(LuW8= zG3&EmxWx*#gJq;l1V8zS$##&*whbT^?Bc0xY2IWDFM8Bu3k$Y`+n!RkzY~U12LMVp z0i}X};Hi9Dc&m0F@V0}iO#0UeLtPs{Yw%@&RPaTfO1_ad$%nqh+YUbDVq6J8`nyf~ zr2whmQ#_TvgE#5J>v-G2IR^dHgdyh|H}j)Fso>9f2CQUp$DR2BtL4Rt&TB8v54_U- zUq=2t>Gpu{2oLfPur;_yfRTT95fTHB5q@eWSnXEqWovS?^)cCI0;Gah@$_=fC8*qQ z@>#hBOa3u$CW03LK=}p$7}+2Q`3KY*tOZB~PvxmLED5c1F9 za{yAow|RQ_Ithx-kzQ>D3-1sQ?uP{h@Cu$Du2}?yYtzqM{tFhaSst!4fsubeiC{fp@LuNP9S4*Op2E{ZHG!ZiHj%eb zoZ_K478vCVjs$f6CL# z+{a{|SG=E>=?#*JvHv0o^3P;?*JRp~&9sf6C;zq+^yFXI$iF`l0X4zrT)`9+Ecpkf zZu0L{H(l|^d=S-wMfF0DfX9>%`KQl`;4gqu!H0NybU#jzVulWW*km6n82RU>{yqS$ zX92YaZwE*Pn|W&J+|66e`s^XMSi#6YQYL~o5+>V0Cfh84RPb9om2DnxvV|A@+++(2 zM*bn=6TxYOq12JUPXx~gN(Im6seIq$t=e778~JC_Pa;e)Z2+yo(*RPz@jR7$GH;R( zoyr^e=VBZOK>E8)`f7kw@OYj|Z}BF5xPdqF&!9hnFyvh0Wq5lD(|M66{*Yg&ZD<5>R2o?EXMQpy(Xw)mE_Z4)O5DfRTR&Z!KXk^*5Nt0HFWz^e~-DP?Xj27KSZIG1c@)VB{YV z`X6C1Yy?3613>@d>0ua3P_%^I9$YL~m>%;m?f#*u*CT*1e}^FCpTYGW0Qw(K57#z= z!nNtAF8>7!*DMd$dSK)q5c(fs_;s0!cO?+|A5RZeil8dChPP0h;-PpP82M*VJW3c8 z$GIpT07C!c>7jU-ps4wszJp4zP!)KnT7Z#%=&I;{gwg+adYNx0s7&AGtxRu_OpKiY zjQlg1t|E;7$J5I+i=eOn5%lCA%X;a5L_kgOIae?lSn>}{-Q-`ro38j{K8OIpB4D9M zz%js7`c{2L{{uq*v4HURWL0Q5heO1_ad$%nqh8~NvATnRw>yG{C~0O)@_mA-?w$XUl5 z`Df5SO&D^naWg*(g#O1<@^7i_%fAcvF8|Ps)dRjGJjg#l^gjWv{zpg*JVyAb*i#3Umuf z14jNCe7o;8_|9_ieIy9^XYe@y=zlyte4PYE=SZ)%f`xa8hj$e)^3ULXi7=S@8%)0k zK>y?EVS0g}C~M~}3|o+5s_8F)k$*twe}uuX5di%U0R4}rhvCNrMN8Q2!Nr1w=`jz} zEx_>U5kQzfR}k{g;JO+B{g0=IYZgJ_+Vn%0|AK{UmWS(1VB{YV`X6ENUgqK*2Za8| z(?d0Zpei+~i2t%nOfsg(Ng#O1<`M$|pwY!!#^3SB7M3`dQ0MP#c(EoTU`DETCA3Bvc z^3TOM4uJG`oAlKH=zlzw-r_BC8h9iB4EhrYL(VmB=A(ho|9DFNS&Mx6ckbThADXdx zz(C}b1I|wTGn|xMo!IFO{ za_D~mP`*K09r~XjRh9cO^m5 zInt}GVBsC&;f(5;(5KOpo!!eH14 zfc^)7{>Rh9FqEKZ3A;VGSgm#NnyfG~fDAmpFH^&SBFA5Rb0HiE*n=`NT5 zf`x0Ahig4B@(&38k1+hY%*DGB2>p+zhbl!-6}a+w-Z#R@A6irH%KPN&HzUKnM_v^ zM*rjKWtv6M*Z&B5@{f%l>3>8(P4GEaFd10#4@}+UU%i{I_+vhZ0Kp<)p+~?mz*PEH zeMbKSLjU9Gk#Hix%033P%39sRsejdKM7+9{~CvPYs>Hyv3}~e&7}>82Lv^ z^uIezwu4NzZ2;(hJe4iYn{44lcbjZs!N@;kJo+DDD0L+8(f@$Z|9C3j7T&7e2fUGg zCjIM#p{@-8{SN^BkEfDvkDxMy7M-dcNBY6wor5?UPz{o#? zub43S&T{b;2txiDd^-^-so;k^J$$TfW;0+0%( zczT%D5)@?{cngCzB~{aBfRTSdiQsPugJB~;Yw%HkRPbj!Jq(%$L`&H1!Nr1w=`jye z5}0~D0toXL2}1rETsH%xf^&F!xHKOK*QUiT{{;)zEDzVEz{o$KMDSw5;JwVnI|(Qi zoXFEdbuK|w>=NEWaf*lH6kz0^L2(jcP#ou?r~*m_D|vb-MiCS>zteY62^OjX57hy{ z$Uk(|L@-1+6&%RZ%RHE%G9AiWncg6o82g!#3mZ+QPY9>Xl;CB`Be5s{`VjQwAA8Hl zzkj*{Cit8ym<%lW2c~ZF@2_sU;*a?t0tAbIg&qOV0aNK)^*IrI28dzL(<4Ds2$dc> z7>gF!hYCjixv3unp!F=E*5KU$so-Ls8aj{g7PCJ4u3M~NFysFZ#a878Z>BL&hh9vk60~BY~d?UI~;6euJm-&E>7yY2HEpne@{LQ%oB` zYw!X9)J2|3KApE}Gm|&+&&4@<*&GI>? zSayf=lR8q`9oE9OrUPq7t+Ep1%gbsZ_YqQo-G-elP;pyQvn(?QN_vyzjFti%8-X%&SA&!7I9P8~iQrSynP$UgqSd(`hRies}ka4CzCHVoonJfZ zwYYs+Nt`B(C(bJ2kN5s`gE;LSPsFIp*ir@(3>sU;yUgz!Y9O^wi3P=_(R0ef;0yJGzUJXzhvnN0te|E}(4-pNX=p`$i%_#7GXXS1B zcb2l{R^rT3>RIM@yYAmr>FyOa@~Mh0NXeV5mQO-+Mp$+~E4?D88%4ct)M2%B(v5Zv zn>$?Hp=m7iw~uq>Qv0~l5WP0VV5OZdTq&vBj?^VCU?i`)!x_yzq{%CfoLyzO{>sDeeQFBR92OAp8E#e8((E#IUfR$<#H9*xAQ!l7MpS2&-lZ>X3(OQ=#4_mq!uJ6c-LG}bR}$3W1ptB^oh+&+ug*P8m# zh3QWDU4`n)@tTgN8YM1>+j;uTd;d|d)x)#l^_A;F!^Q^!(a@5jaiJxJ`Sr<2-bo!z z18C}4&HC%Mcyf$BU*RmGU!RZ%ITb6t_PE*`6z4_Hj-C@e*NCqM%cdW1s~zJXx{kp>UiQCFxXz>jNGYVLX4FhgB-fK z+=|<&QLm}t{=mXVF%iqwcY9~lelKSKyWajZK6+Y7==NXHtK!LHPNhGYdF-ar&>ZI7 zg3ywIRq62bTk``@Gq=a5!m6=+uV~(t4lVd^5G?;^p8=ilqrJRfOhMBG`=#YhNo!v# z-EJ-1-gs!Y%*{7frB80`uOvlo63w1|sm)`mPHyZIX+4g-F|wyqR?X~^&~2B(Mz;c$ zJ1wLsvskrLLw`4sF@!I*i^L=&2v`J|2U79mMdb}K`@*W2{jKVlJv$P!{~nzZy(D^Z z^r9&%>l0tCPh3&NAH5ZP8W2nfXTwrPguUD!6qQEu+cBn<%!}h2d_^o*w z?KFAdwB*2ryaLv9zk1aDr}=8f->miTLQ?^KHZiHB^}vI>257EeE;UFtnsDj}L{`fOYz|e`}PF=jFA$9pY;~U-S9eC;QbzwY+tzizr%vI#X!1v=_u$ zoV=zV8uD8HmDf1IYWXa$>B@a7wJxvatq}dJ@V3@yekxjUa@P?(^Y?9etH3H~Q=%16 zdPRFQ|KyVm3HHjEJ;=yq^>3@PgIT@As_B?J*h-vE7oZy=v-K@iSQO|QL<+-J`od~w zt(w6VUz0U)yL0s=%+;A0#Fzi*xBb+YPWm#!^$?BGIb&QEq5x4Qfm-4U{$8|z$v0+2 zq~r^F^gNcr$6~Zs48yXK+pLQ<$}S}9;-~%hMsq%l%g9Q z7fTkxCr#PQV=ZaJr@UD5D}AE&AK?$;#<{9KKaeUM73d5~T>UOHp~Lq|hH)x%Tb@3k zj7`hPXAVbAT@|uwR?i(~w4{~l+m$QgH9P0-N0A2^x!+-h#-cu*p66H}rPJ}m zH=)9@5>rZ1eBd95`WTwNY1zXp`*r6XRyR-tY2bHW1BxZj%ZsK8PYC#fnu_kJ(iM9u z-8&~Sh)?Ww-raCLj79=Ew{*#foJMiaGJE{9T5c!} zgzn5}*q(esKhykB=1M2aXqJD5q`193Ub&U#kJbEX_CTv(1+8Dy`H}?1?Jtv{dB^jW)FG69!o|AJL{CY3^#;Mw8krnOrMV zaeHShIk1m2>~zgW2gU5Q{$$_R#Dp}ijP1CpOJ0v=UM|w8Q&n7u{mO<8tOravIwC#@c zYm0MJTm+H@ZB2bz$Cp=hMRLFF@8vB=YBnO#I@00e6qSR17@1ARzA3WjJ&^~d0nryY z?GWhPVXBxVrR%!F{GSvBxagi7-!x?;}jH zkF@%wx9m(e&WNSgbS+nlT%XOJ4qxM@tw%GlUr&c8k{W(BMHZ_dE1NP?(Du5u?88H5NU~ZLE|L3%_1tFTU8+|F@v$N(V1^h)zD9b1(gWW zwYWx_S{kuhVV}Rlo$5?A48Jn#QJQLq5rM4d80On7`>Y}-Arct*j7nB^$O73;8j6~4 z91>_c+p_yN-#}n+Xjn7pC>WWEa@Ns&{g6Q8wpaq{23xj-WwbYV z18F1eTc$|f<|CD>P=71jnvOtjU70JSiA;>+uhL3pWbg$f^;8HtIS81zVcWf#(tk;y_xZ8TZ6oT@gOPBkO6QMQNmXrHLK z7L$$Z6Pl;#tBaXlK)6Bp*9*VBdYLL?*@rm)Ju*Mgd=ss(xhI3O=uQ94Q8miE0(M&V zyR3biZgjgN^{Zw{!up!2pYl-Q);P;ec~dGZdxvG8D%;#~#$dEHw0vAq%g(%}GRvl( ztJ5W!=z)r6QE#Ffik7K4M0$UbIuBAGa2wq3y^-9G>-E>Y%qR6IpWc+ReSG5S@>YX7 zPtwH9BeSnD(nRx!FSM}V5s6%!Q<@tYBNCmbzH+zbk^XAMWTNIT;)`qKln@65E^T<%9jNG&jlh&U{+;xBbLJR=EFxB^Kni2CCQ<6WQ z#7wE)d~yP4m`|Fnikf144l-Y)8>89sGKdb$K@`YE)CFsV=#ps58jRF_L->?vqIioW zi@VN?rPp>gm_F2F@_OP*v7^JEyuMFz8Y#43CW&40x*k#HsV1|TZQNpdn{ED-4mW^r zv9tD=oZ04bMRl8PYEWo66*zs z*FS8lJLb+}*&Ui2wi2^4vqGq(mI*1Zi~SxZJWU7fndxAsJ00w@l4s;OFaMM2AUOeR z1-Sp{+5tN>qdASIijQUvSeX$4n!~WdIg`-v8Bs>Q^g=b89-V7>j)(9e57GBLC3F|Em&rB|Som6FrIif+R>}qT=49|m6Jj2mzg&_!9q#xh zjiTgqaT!&u;+SC2Kem_n0iOOC=GeC*1J@x$}}tVY3p(t z+71T4c)6wh(xw?^!5McDqkir^K5$D5=ZBc|A#akY1Wk4}lYnd- zmW);&2bJo)JI<C)&42F+(|Lp8xgIxbzwRzstweqMsO_eM)*d8&{uaFOv;IhUKLz1# zC29|fv^EWkF4YNbHXgsN$YlLNPU09(7p~obJAv}_HOerc(T3~URhXHh4OdCuXqo2< zvxAI6kgVU~jLo3g;Gx;#qS@e~*^-MU1r6=B?WW0U*SalMiwXH0#^q{f4pSWi{+tg? zLya>dqaG#a3(UVp8Ot^QK7WPU=+_l;7q~XqKqFDT+AXQt4M>1k2L)&406+X>0k96dELFGqTAqp?@p(g5U4W&u$REMv|GznEfBg;h zh#!8{aP@mW^6aP`aSUHtUd)WzEI&VV2^yEpvsd{je$Jl#W%yY}vpGd?bmwOUO-4_0 z`FSB?27XE?P9=y?jFcb=FCu&eQ#3rCM6fk_a4LGp7x8qMbjM_HBaQIC$5~r78x@YP3C+DP((`jU_83NNKS&q__MsrP(X+`>+ zYrpgKIW$7_&fxDaQyr++nSNc9rx!VIV9{C3*TJSlN-G&xN|AM?_PDYH3+m(~Hb>5= za8my^Wf~pKwf{les1F(O(NK zl##`qy&JsQbLz8GiF3L(dBUN#L9%uPgI%-C)KEpRnf@kGTTy(w31Pab2-+qXDI<2V z8(T%}U2bedV&p!;5+eSt8fl ziD-q1;~Tz1I2=so`{u^+(iN-B?wFm*SghFir6XanB4+kLZG~rzRkBRc?{a09mXOu% zR-*6NlFGyH%nanck_bs;@;ns|T8Eaf zA@xZs=2rZgmKU*7EOKUa&uQ10%^lyMDRhW@B8Aqj!?5b2HmiAK7RZtJT67?aFCGK`P3&MJDgL}F^-Q1uv%cbJcNLx=N_^d;G3|71k|G|Uu>E&B`z=;wUx zLw(!G^1OQC`;A3PKIvFR4baAQKc`RsJc(GtYj=(A4>G?Od`=hWoxjdua>q#qS5D1z z?a%L@`Lc5)gFpDP=~rM@C;d%dHvK~`J*R(u`fUG~GYM81+WXJcu*g-#?>a=a;Xl0| zEBO^{S>#~}>I)~WM92(bZP}f{S1k81G{K&t>9uZiyX~!prbB3ISHF|v3mIfM=TYI7 zRJqrZj8*9AE!i1eEru(Z5sGgA7VS*G2C<9oF9-KZIHS++>8?y=?v1;ijoM*V?X@=w zdG>O4WaEjka)QnIm!)3`eL=8C-b^Mlo{T3X_H?%^M@5=CC(>9Lj+NA-3q zaL8UN(3L-Gv(?VpUKu8s3@W4A-E{ru5LMelythqPYl;$4&Bqi_eWw3r9Ljv6Y<(|q@3K&73b;LxTG4-VcZ_7U(hnZZtqp( z-!!l#-Cg99!7Fr)bGgdv*$O`W=bIwRO$7$|75M2p*$TKk9o~~>)BiLVx&ENrqcde1 z?IS%%oqbc|v~+l;9BFA4_*j$jUPA^su>S$#)mQj5+sv2N`b_#+h6b*=Bxsk|KQQ6`+=BGv&IBFYI*Ft>HmL zv!OfAt@IITlcg7j*i-OiR;y(Hb?4XDj6?ChHi;Pq-h$2Gqltb0F3jbw^K8r8J9FHM zqSRfU;vE?mU*qF-$KWsPpHDrvWqNYe zzOyYkF)REp>HOPk8sG9)!vhcDYIe$APKQS}(1GY{J@(yO@Rs%Ejq!|Omv@sHr%V6d zvzwn3_S-$%wJrPmGV`NAFpU{0PIdZAwj7~KVoB2eA{)@l%1GwyIMD0#o13~c>gaLb zQ-1gBCiC@s%|r-8%(CxUtS~;JEpLB*L(G%5ai8)ho-z3o&$KFQ;u(X%K4Ypdp3JW8 zOc&kf_aiFN;hbjB&7F#q^>qGbqVYtW`E1A%D9sL)&KX3>o5@{ycs{B_&hnY%_pdTI z>kK=<-LFCdro;a|(X2TS$Ze+talN)vuGQWjZ^lu3NN?UcPCpDHnQ7PbH*cxW1WHrU z6Fdd-d|Ut&r+F9$1|#wQZ|Tv##K_R^?5{@Zp&ig4U0Pu%N-~ZX_(i_lSY{Mr$$sao za+sukpFFR~IaPopILqJ(rEHpU)h5OX>8Co4AYTKl6tS9)#=*vMB-d-idHW!h-*d~$ z$ZwBdvN1TD4+{k3_G32XS33jyxm5e}Mz_r-Dw$abcooi!7s&CeW2q4O83T^qXXs)lV!8$ zqATMJL@VOGk++~tZkJDVS7%=7JY@JD=QZ$;xLUd}o(IN<%{?A4HD=?e_BJBf5$7%Y zRp(UmJ_mt1vBJ5n(^zyk7$_e*dqVC~Y(j;UKsVNCgBVR%m3^mN63()(sgB!o*kvSV zBs2a(73A>Z%;r{NLAfMW%-+x4>~fb*tGW0W?*%o8yT>ff9%ZjZ;W@piWmjI)P|HS) ztWNLmDnUJ5GUQT3P0nGo5yaQiIgQ|Ap@V;$8;|_bs#7l&ZZK@1!jnaD1HQ#_1s;MS zDQ3T@a{=)5!U*RAteAHu;G$e#ZVi#hIj$d}+5mIkCd_@V*be4jwZMKbQ4LeO zBd1+zH@GoLViUD2TKmNnWF0%vZ;Xr6#?&AV9-U)v;1q^yZ*b#GTj2L;;u?zJ`o(X$ zO#gBw3VD7kY@tuMmc$*}2fPs73_DYO-|?-t>=@sAD#8w7cnYbNL?&w2!XLtz5!X70{7cdUrqv%LBipZ;^)Rlf zO^tIl9pJ)T`Ju6Dh8r?Yx9ONoCIMj>(GC;J!f{e`d7V{b({(0W*EAm*hm8#fZd+D{R%Uvs} z4%zw3EdQOW@#S|Bs&Ym=>lY7^fn66cwsOP#GB`rLn~)^I-^P7;W0Z`X<2oraz@&Kv#p&CtW5STjzx z_HKPjH6KsK2K&Kz85=C3N9GOZeymbvbRbOqZOw?7I_oPLCl?80=WtfP48SRji`CAO zL&OW5H>&zNoT z$0$L)!(9_eHR1(Y=F6{@&t=}L=g%}v#`9E-(>dpDf5gP?znpU(Lc7(pX0ZO;Obg9q zXv<9s^X>v2?1?2VEXDgMmYD50@0iqc-6}2I-gE#G3=vJ^XgA4X2dnFPBQ}dbqMEL8 z3Um=P%2Gy78+Uq%R;&R!7mPZjI_{eZSaUliKJqsquf>3h5tU|o!qE40d9!)5m7zBL z+kUj+{1;WzDHpHQPMP*b%A6RMP&Q63Tf=7)@iaygZ#cR7lExFAI5V{!d5*`W1zrie zsAg!vHkHbb58k-_-5?BqHGG{NyCaScYdVccij5Hyq_TrFdj zx~tG(oX{M)PrrD<@~(n-0Y^tW8V8{)j<|HpkhvqQ^l~DaK6nDljJGZFDI(q1Tu>{% z#RkORwI_sh#+&Q3QjQaw{o(xap(Rz(=6^*!;ZyAkAB(jx-pxDnLboL}aMK-DyK#%b z;SZN@>=rJ9{jKCxdAY}VJ_{{6OBp!#HJ25%9K6}(ZqR;+yu;B3>0H&$wb*x3FVLT-4yLu5Y<Iw&2ySLjh``m8ie%21`ip{RW4M8!$6OeitFTRwE43k zbFY_Jtd2ovEL68HE~ywRc+HgVMRFeL<;HrmzV~@K5MC17^ucfQx<+?H&|6;91W}qG zH(UPkn}vT)T`YNKUJU<4&-`K}FNTSovC6j0(a_$V=6*7k9uuQ#i9+nAOICK4e})!N z-GO1mIUfHu<`bP4KBz#)GzwWSAd6)M$^J9ncQC1_1^4!SgZZAn*YD4m?*+Ynpa0&y z8s>KJurs>}0SUUxj20vrqQQQ!QH9t>EQu7_k%4AAu?$I2!Kq1lMwx`U?*~C5`tS;j zyCln(yw4eX6`G0Wzo>F^hT9!lbSA^UTICP7-55Py$%^vZ8Zv`QqP%geuc8fe>Ece3 zh=z@kjW6{xMMyTTbbjfmg5H;3<$TG?%&=Sdv0mY2PO}QxGke)q7U!qB^#|Ffk zYt)&%4TviOJvSiECPrNh98^PZEY= z*$f+sI_2<1R?1q}R2S0$ymj19R6@v{AmZetw)Id#6H-L`TQ$+5rarPW>P(qMad}Na z_5!&fg2Pj>1THr^rZbjb^XRQW3o@A%I60IsFLU;YGC*WUDMJzYmzdrVy^QH5f0c>VIj^_x=ws;Lx$Bn(vwq=dv%5|~XMNeJ-H*-0 zl$s-X1I!y1=PYb38>{x~wbkbjX&PzSGs^1iZ3d?fqHT<`lU+5Q!mH6+#xN_6G3VDXkB%*a<7L+9iDk1VTT8ES|Mjs(*A+Eh zY|db7@~nWAz_WTfhf%A=xH6Yn2@HdHldw&zeRtNCC0bM-#Z;@)5^_7#`uQrkDKToN z>L|u^typIwG#WU9@dOOcN^*~XkSJBP+xdUI53}e0<7SN%uW6fm)al7W7BYJt|JUUA zEfnZ|Irx8u&g<{v!T&RUYfMNqkn=eQ|KFF2Y^P%G!T&db_U+*R`=8|P?co0#)lxw? z_@C%j#!Wz9_Tc~N&v$EtJ=P0VaGur2R&U~TC_q@_8OhKZ*VVGSgVT_FtoP&7b|Qv7b^?~GpF&5+OMNMA3O=cmaP2+7SwOb!SNSVBG+Ud zt>B9rnW+5@AJL{{$V9uu9o#o zj$C|@J{*-}iNz{TbK?1xV~IuOGjR=+Q~yEqc~${|uJZATTV4=>?Vg|J+IZrY4YIJl zNvap3&j(3`b{!hTDT)|}iO*noL=hHsNCQ=(4vXszaN&lE==M}$h5T<6dQ~etaKWOUp*CIQpx;$(^>!a(!$Y$txdQs_aE(d~8Q3kChJ3A0_29 z`0{ACM9WIt@!w;%>l17|wz95m@k(`v54o{;b!hD~_cPH+BI*(6Q z=F=tMbVl+?dm=5j%H^B8&g$(6v~7no{UxEp%?;9>E_b`cr~LCscG5<5HBQC<)@dQb zmLDplYm)9S7sF{M3?F;6lRt0J`#T-()62k`KjaVXU$x+ElDq|vSw#MItf!>ca&YJE zI0n%gOx`U!^Fs@pXa>9ZB1|LP^j3JpWHKz%iBo_Mdtm+V)Y5Be9NTzL}0vT(m z{Ex8Tvz4~sYs6d0ldnFm0DH(WCsvWx+{e{?DwZk@otPXBS*D_mgA>KMEz%Wqe*I^a zuui*c`X(zgJ(d$jXxu_faW10Qu_ms=)!8wk zog2yO-m0%z-WaSsetTC~_l^alOY*t~I2C<#|5h|~CkHbTzauTlUIeLUe_)p#R}=d} zuBO75&Apl`wCGfg2j=Br|IQ24F4!Jg_$|}8Yn^5CqZSA1f9gC=Pl_kc`6=U?zouuh z)xY?sZta_XQ(y2#oV4Dj)%7*28>{Op*L&yhYca4ylMU1#7w{z=&7Y|H9phRD_K&5P zleXy%;f>o(NJGj{S=q{OrSe67<@++%?OFE`!ESXwrbpewz0`f~rKqP?BEN`b6g&~bcDI;^|wH+ z!N&xcJNK6pVn;1J1f_!wzp&t?Gp-FN%g+g?f)DV-BR}|zo3c3MrYsiR9{e%S#_O6c zPX&MIrTdMSZimX{ep|z^Dhn4031^r;jpZD>Is|@$cVb*Qm^S21S*CS-az{#+ulyuetLiVAV{gp=T``)!yg|dWn?W?N{3gO@K))mWn2h5n~ucU{NGlvL)%)x&NbfMb<^#aI^QnP5IEo89+!WhChuii;|YJ#}^;EBTeLb?ry>v|#!u)bb;P zVYLqEM4WejW)?xlU4X^UR_Di`g9)@U1ztrG^VL8%1GScpY9l5zexti;tIFB_7CBWOVYz$a zq9=1cuI0UmS;lU2?lLZ$uR2NI%x=sk=;6IODY>!QMli!qCjw^1?OU=QO4&u4Je0}| zDztqmz~s8#b5CNOAv3%)=8wjRh&K0vsi|3pWxcVp%PMIl1p$1dZVP@-9l+&7H_!W}iLc9q8(OX{D!9XT}RFw(*%wL~64YPU2w%^H}>) zZ<$KfzQ$M57~=d$mv`bXp$3>B=O@VR=N$J3j~NyJGiJzB>sRmPGNX39&kWb+{mb*> zqVmbEfvUx`1h_KR^dAY!G6{=_w@GsD-%KZUCi2edKAbA@Ie?I4t!wJ3BTTv72Ns-% za(}w(;FitOTlaw`!!EjdKWE+Rs6R_!d~WYKI>)sQ8L)?ITQ_&Aee5BT&=OosjOnfs z(_PDpk&GXPKLZ*5Xsf>2$gJSaCw7|^U4AuIYi=BcZp;?*@(SmkKZt!Shs^maZ~A-c zU#{}|fDp}pv6)wPx4XHVqyzM~M%PZCjg7l@y7|;$KAkfi;cZo} ztK~+a3!*I_yHhggXp~0fAueXW z6st^i9V(JT3l=Kh!p%)VzBk>(0!-iXN3~5%j^V24Pv%b7-9>{99+JG@IN8)RC=pSQ zwe#!d3)f7)-*^Da!Rht(i^e8LUA7#CtQT9@SKZv`)sHwgNgQi|YW!csaEWDCU#q>Z zWSP0nUH7SLPB6X3cgZz3TN>vnYqG3Fw=eI}M8??DfBS@N z6Ul;36Pa6EF~g{xR>2On({jV8=|!jvv4RTDi$JEby3LhVb8)TWSBTXi5VyG|nC6;5 zbMa}2>Sa%)xpv0vRaRw(Rns|lh6SGnLr7kuVdf=NhI1rm&h^r`S>gE6KGwZnI$wq`Mi}cmWThRQ zS$^1<{Kk{g;n|qS)Jn(6IvKu3kZw97e7*^9wQ9yq$6`Etx>fnHi62gUSIzcuGYgw4 zO+>^)!Q@J|lX6h(=b_-rOys0F-+Hws(f1qoligV!#cQ2TN74$F$-Ay@s#5yW(8wFF z3pbdb5;(g&;?~kio?mKK&b`zWW06RyW?(W(y! zEx~+?GS^MHlRl^f@aAIaw@v3+_T1@ckhDBK;G;QpAkpa)&V?E5uF5`5J=3 zF$3MN>2M{1&=Sh-SybkFP+i-HMT={#AiQs#v$%!eJi&lpajM&Rg zo1GUvlr>g@)bPihsX(^N8N+AS|Fps7jPtLzG%p$|d*BjHrvGWYxmP9o_ZPApGxrys zon7bo_ZLcV1ug@ znkzMZ=49zXY#FIuhUqot>a|4{JXr(Gfl-H$5QRR+fD$?eqbn#kA8$ALIq>4!5Ot&+hxIrZ-w@l~uDlbkFkTox`l; zgpviTSR~V~;}LFE&9`Dr_^H&1s!fCY{ramr~ zZJ$uWK1P6d=`h~h8gh6!@`B4oo+&|J&<5x2Fmt>Tq zQ{!M+2g0;zD|@S@*67(qjg2w}MJ)TK5_FndkIbZ(3vn80IuKn+$Dm7~#<>7eNH*_p z=CrBq>85%3B@lj_;q%Ub9<5e7RCzPM*fPL9Ud)fUP$!MLs!KXQ-HfT6o}pEjIf<*^ zVfn~)63&hnb5-vyj8irn#rgxLvz3ox z;hy|sfwm|A;BJP074WY#%Rl(toqwf!^6y|u^Z7?p=(jPx4F5)me{cNR@UIjeDr(eqY`UOEje4_eHp?#4lVGS};$aDDZj;ytTqgLto)0 zA=uwL+~47}ZWK*g3@qF{@2_s+HyXv8 zWmKKy6*p1Tm6|u>r?nFw5d4!gXRLL`Jgj3bCg&_LdL2n5Wo!_+ghH91)F`rO+`5X7pz>J)1*4Xhk|jaefJsJsEt$ z+&P1Jc9%K&ko!wmlIq9@r|D0iO3Xw)>&h?gzQAY8UCOX~EJdMn^AEcD|M>d_x>Kjj zd7h8-MJ2tk^GT)5mA|_fp)JcxoK|j%adp;e@eQt?q+;oCRePvBS^RcPk~OqI<_|^@ z-EtL1vocN|NFd@zVJ&}`J?jqZ@O4rBe2zVE{aE|J`7Q6}HBM~#1iOi}5t0@y8&1Ia z=&J^zMDAE~QCS7+mEV5ZTHcv&9ZqOmseV4lF6?M8Tx|3>RSdR+q)bR2-&Z6?1vE&! zUSjUgoB!ThV8h*D#$nzXd_nm-V$8YBU7D4-^j&p-&m>#Hq2N;8i!UuDp92rv!O>iO zYG?rm-@w8p{yjbo4=s3#Po|H{4}gg>d-x&Jib&PT$4d`3yQ++7Ip$T%F>k7sbdQ)g z;~(M5;HS$UPzksIOw}=I=cmUR>E|U`{(Uw6*+>nY@fz=4&r8ZL6bEMB&Tdgx%OTnM z>L2J63pa-reAm^}`=NW!fK=N!DqJOR>OLCCbn0|sw!;IPaHyO$V4+$QI4?pDi;4lrAM zViKT;5CPptDfKI~AgO3JX6Sj>oAZNy(@k~`cP9pE0*D9aY`^IyJOA}vuOFIOLai6` zTJQS*S?iUC)Ovl^%da*W{%$2TQjwP)E#ka0@wDjoH>i2FAU_}?JL># z`2puRvh8!ZE}Jt~ZPNlh7~9!#Ox7fkkp};vr(O&-mHqxrWVV8k4y(o~Te@GxQ|6znUM~CEn-#u5Ol%df@6g*Og zt=XHYVlqA43rAcpv@x6k+M9D;MBg%gcvkYn4G1{O99Wf!+`~EVA38;x3?5@r(jmG0 z`3X_cUaRJ$E=GPt(%~8%K61OHh%UO#NbFYu!5uhh?d)vUO#5Bs%6 zvk%l^v&xlL&C1YiH<8OK*xa>QJkS1O>M*>lO3g1r)@%$d(!f@8pi~buDy1yuQ?dH^7f?fD-V`^|3jRoeMqIkg;d2`o%H1~*lqAw^Z8m0_KCafwtkwltbR=bD$RF(+sd=Xco5QrMx3yy83s z&t7rRS#!KWSiidG4}OdXxU+t>Z=9#=BAc$wQnRy*xx#^au;WFhtvnr=8h1d|+#guz3*;HEPDB8q+$^lK!!4>BQ6~X9^Xr;rBM~Cy~*EIj41t(>(*x*cg z)lAkXfLe@!Qt}j3{v84?o{=6NmTMlKdvfqNr};?CoaxI?bD!J6=*~|6lW`;!K^aB* zD?(^e=gh}w(nZdiR*i#0v@SGx*No|z_pO(+dDW`ftrlZMMjw$c3$=YxT9WfV2o}B{ zT9B_1Xos4gl^TlGRTE$HvupqfXyz$CA_lpShDwH`OHETJ!{shl+-QzO8l3?l;Qs!?}hdDN6f<4LJK}K{PDN6JU-_cpCQ9GuXxLTLOgG})T5#a zad*B?1&gR;cz_65_R1IW>s~KK4!?rrR6E?lr!Jhi&oA;Ab|z>$&hi*`?_(ara(Ghg z^JIuxH^Y-=G)5sD0m2M>oyW~R4`z^c=hWgxQ2T!qys+M8{COpQ_xvhi)U53&)of&o&}3S5AWm`o9zM445Ia3LKgYQtj1g)%8tg)Lye&E z2WKbClYsN>y`(+MnENtme@j|3K6>sy$*hzaAFqyPd~9xl^=T; zv0kS-iB2`U!Ru5Tf1}bg3hk5`gih-aI$`%AHWDn(TWrC5wYpl%H<=uaP-UF`2rT~J zqh45VBfq@;Q&n`lZvDzM&#f2~tmKG3wRk`*C~;+&dR)X4WKB(eV_og!D=qe~0o8Sp zCS2;K6yf=n?eb;-ew#yK&S;S-fi)buTt4Wgcq6YYjfqk(LC*NQfsFdJn-Q+@$4E*} zFcRx}cvW|X$E(Pbpcb!k+NRWRo6zz6R42cBw$_m`s_Rts1_M?LM0d={v5=poPY;>< zGSj-qm;)K&bi{QEfXQZ$min}#Rr-Hns8RS6{(O06E(!7h-W(E*wp@S0fl=Gy5YqGX zm|8nh6>V{fLkq|jAe7g5QM85A{R?TXKuc#yV|BE$qw&yaO-E?q{X{L`u7lz`MOiZV zeZ4}p%U7DnMQ-HPQbIG4m${Ks{FK6Yg4T@(Yuz}}Wc1QZ^V68fpSvpbpE!Mx#a7{B zJIYTfY%yUw4s4BKld;@QGu%&OBG z)5f%P_G>&$rG`~17P{a%QgeAgu+4iv;k_TwI|qX&KYjaVa7;hvt{~{x{(gZj)Ymupf5%kp#gV=&#i41+gFX~jNZ>^+(3|95BM34 zCBY`btg@ z_8{-%M>mT_XweA9ty8f=`kv=((%vDUhi!uL{ds(X-~aiIY?O{USsAv?Oo%K6xaM4!mTbzQ%Q5wOA=`n~=+;ozeXPxmo*?v9N z4VU(ZTZg&ft68Xb4R*up1`^-j4L61iZd01`%~J(Xq_4$hJM^CP8BNlx@*b%6>3iq+ zFQV^f+$QeRcYVJseXn3^_UWt2q3;i77ifT4qB!lRd>(z7v9@mD-pASkLt$tElVXpt zcEMaV@#l@TBJOGM`cW}KzaRA@+-pDTWvn&5s6w=@v~OcgUhB^9pU)X<7rq4G+W%zf z&WtfM1<8>>(}_LD*yR$itdN|N6**( z@-g9FdD6?+x^$(>liaZt-g9j2-rLyv$KJ-)z5mIslOz5z${kP>nE0EC~S+AmK4{aSGekN%kKQf3Mb^zaYBynP~o@hFkcnSO3z;udWC-tgs$d; z_HvgWTV_bo>YM#>i52H3rpj6h7(Gt%XYc%Z@>o+N_%l}_pFgLaV4|Hni2P#yI0YVw zKX}1p`%?V*rqcGppAU|4>G-nzndcWi7=#)AT;sM_5B7L26s&fOzi%_t8*bKWVM?ndZQYPwt}NX+%_PJA0@v;Uj{hhj(WT&zo^z7={ zM`h19xxI`A&y05j?>$~ZjrRf0QI%vv9%nk_MjD6V)!3K8`xnB_He?w0mm zeXld$2bkHq^E8ZC*?C*~C#G`z2fa(yx0&^^^K_L^4#wBEd6~K`W}@$@e#^|H5n6bg z0lbguz=Zrp@#6(Az(l~_Z z(%Jg%Oy>ohxk@knqnFh;>!|(w)!{+@>To~jA4ib|kyJR!TZgmqTH`#A=95`R8K1xI zzb@h07klH+oklX|@TX~>$D5`(&CA?1_%*%pq%RdPJb7vvWs4`3x##10<2-h0 z^a1IE2Fg|UYr=dSLC z9J*k@S-zLF3C+_Pi)`o7jOna?xwrmWXe4n?d;CxO>$i4$Odb3z)!BQ0-LcgD?Dp3L zTZ3+Yg;Mp`h|qZBa|~gpUFr9&jZP5KJ^Jf@MMC7Q`}e88{sY;@$k2H9ZNNX)sP%2Y ziw)q7=N19IjOWuo_4u>>8L;i0KO4Ny;!mGF4N+r!G`}HTrbp{uA=9JpQ|^7^Rv-Co z?7^+K`Up{XZtboAyeJ|2e=6@PQ6x8Gc&N6f03~mQ3s(ypaHLTcD881 za@WI)nV*r&Ak}`9Y)rNlY3U4OXl1@Blci*gtUX+xAh%}O#z(25Yh=erhT9SOiiOfL zu;R~i#0ebs&A=E|{A@cp1?Jr2W}CWaw%zZkMew#shV%8+MYe@lk3!Mo`txILaqZVJ zSjXu7h7^g@r9&LA$B-5l&leckCOXX0cS`4O&W7}iTg4K(XI!{z&$wCgnUK-jIY@FN zgEYfyk*NKLSM_;MItLw2G=zrS1)OP$$2c0Atdn6fv`ESc^?vjuc&hCbN5&D?IGI@m zmieoNgN}cV{Y8)IUgaKO{(UNMkLU!^ISa}CeH84z82KSnd5*R+7&Xs%>9@+`vu))S zi@yOe{@*XWu-+`YIyFD}9mv#M`bn-6oW1QiGgRz;?O?U3?aiPU)=Su`Ge_>La%hdto^ zQCl+hnQ2_vCld|Kb5@zMH9X{NmTkvr`R?h+g>Ba(m$7-TQ|d~ko>o`r#t!ge|7mJu zHY(l5@jFRIA0Ds!c4ZO@EkHX8up8U5vn;ge7lgTo{pZ!{1kuov1$ifQAaw0J=MUr^ zD_Ea?TRpIe{^<^3;}5sm`NO|@L>%5T;zKm)Zdooh_bmJM1nCpzW|y3ZH_e?nIT6R| zzIh`#C^pK~NyWLm+SDEhyvyHg{uc0e7k`iN_Y8j>{1s4x|L_jv_3Q0lenDZdU%x(m zi;Dct#Jjitq+yRkFr8_I=~rg$JKlcPS$kyne)Xm_Q*CQ3Xmh30o}CCZUjO;f^oJ~b z7&A<6e>$rNd|d{9R-GGSqBedIkdQ-uPJi^$)1Md`-8LtiZ-~edDzt>1;B7hT_;Gt{Ie0SBdnM{L%jY3zOX=p~w|~-CZT?YNS{>LOgUn(bA8?j^KJ8j8d$_>|h09 z%11H;hZAh&vP3F;GUOQxd6N4n&GCNj#%4QQxQwaBX?sGw8HC0*e!N*A%Tk^({9f0) zf&4FEaQgmA6C5Mlvyngiq~QC@9}xQaFE;bSI{_7YnbA}RI3FVZyI%F}aK@tDtyP4po=KQ$O{Q9>5u{odQLT#u-Y;*eP7U0?ms_U>=e^&!b(-$lvM=!MZL)4> z>J_@}WX1Pp&@R`9-VEA@J7x~vqy2a6t^I#$n%rHBniJAq)!i1|5B_v-(bG5>=C|ks z!lp%^37$$&KPjswJtep999A-Q7bdqow?3ZJo}t@y5d2HG=~}QjqyCHAgSLn=veKHX zouv7ZOt*J#JJ0Q%vN&{W#%^^n&3Nn9Y%|_S*fira!Px{=7q#OhJ-Vmglzw#@oZ((| zOjFL8)`low6*Iagi@C@G zV=#?4FCFX}bl!nCy%}`Y5HEwyTIZ%WG3a2J^FU+YL3lw+$T<}(oez7!+rvyG2Wm4? zq?J#;iC~_;+doIP+Z>tr|Il_W@KF`lK*9z!5>U!oqsGQZ6d%Dr%|aIL$_9gq z#&=r$(b!szlI0;PiJM5a*Hx@qwY8O6-?f#h1+-NY(1e!+wJP{TtvYcP(OMd$vj6Xy zxp#L1fvWA_k74J|+&hmmXU?2C=gc{0a&b*dVKaVD1!L!w&-xxdQr-I>yVFDDwXZ&8 z-V}Q1RTq!o2{CSx$`(nD&iU{_(&~PBKe7ONd^EmZxzbc47C;C0v8PGOhp2y!em|ZO zMkkLDh=4Zs%Q$?mRXfk6BAT2j+`rbpyY$%F%@W^GV1c>5-&hCnedZs@#RpnADkg8s zOy)+7VHEVaMrLE2FvKPD&wdfO;%kz`cgve-XD&-VK0`R(cwO?b04L`0Y01aS;RfOp z1b0LqzAGpD-n+8+l8mZr#^M@M7_L-(g&K<*>}lg79}Q|eB*Nu@;am>D+$%P|8ix{M z0x*7@Bsc<$FO>uU8$XhSOFrB{1eJnKKUwBn4$(HjWop#r+JKt{E5dm7*8N(%>XLZZ zYCE08e**!i?>!NK4!u_v$`JMLAu?xr0qGDZck2y7F6~5iiGPy5U*>(DoU(?#`z2QY9tP9h0qY%b2pN6pgNf4Qe{s^X2Wx(^ygMA3* z6j{@v`20GX;J>LwW!?k9+>g(a1oJ$Q#6GK1cJ$U4!$bXqo`{|0Q-KTF{6;g=;h};F zl69EAsC66V|z|Ude=Q1_vo4-q4 z-LcoGl@FM)?}fUK+7orn-V=4*$?a=RU7tHBi5xn9Kr1`TZrp*a=yXx8uzwuW@x5YV zrP!yG$Z{_e0d=`{E*0s?Zrn#q7IFe(w#A3~pBAl8e1IPXB67SdkMI)$oclB0TUM%< z2qsWvx8q-OtsGjPS1Ztvicq55-Wci4!s$u#)dikxk7srPM=vJj$?sB!dKjwftoZfn zMh*lJwo^oGd!qbvP-I6&n5+Ak>xfzU%OSf7p57D6sU*>Sfh@HW?$G zH&x_3nQr$faF29msQNXHYDZS)un8jy;gf5)ZrEVUhPSLmqB~b?!|Q*GvSuqSdJk_< z5WuImIIAgeqFGEDbpm%`t^EkXB(4wymI>Qv=X}8}vS{EgFlGy>nbE-SIs^Bj;S4;} z8F)skP~K%{M1>Om7k+u4@g5%dQ10YBFE8UOcQ~1MkvXs{fWrVPj!pki`M6TC2*Y7+ zYolN}UN4<$TnM;!1N|#)EVXX2RC?L*4Ni;0I|BoO#&kF`>M=x0qPHdM`35xVs<(tj z{g@W$*$}-|!|Z!h@xEVUJ9zumKHI^Po<7?_#%q1HgCF9^$!rJZ`v8z#1RH;QzunD4yJ5Ac`E7lYGICXhI!8&;KJ|@XE^!G{qO(kCTx! zzMxmoB*hn;&7}tem7@!Ghss*8=0EcV??Y)AwU(}p0OC5{GcKBs+b@iHyHNEqmmSke zc9d@4{VmL*$jqGWB0WM;w>s^SbjF}uWnZirgENe}O+9y)!x+@0t+|jKg}=?B8~C~` zx_{nj7=zWLWWqFKP%9W5{heU22^Pssj#+Y(BYA0-`=mbJcJGr)=!sy7xlpP@#T$9i zlW5eCyn8qtFrSIS_4;a&BbafI=K2@;FYrno;oa|Z`+R@H9=~_rXJbff?}9zPFOiZi zltox1_fmX#g z2E9WGD@-jS_XgL~yibX|4&zfnb?$c{f&;w?j#0WjSlVHAB(g-#-O-z6J;??w|BbHJ zm*2Pw<82Ws4Ztl3madlTEcI5$_N-8>4x`QvxwH9#lJH9vtLBUh#&?`FUV%iHJD5AC>T59Wx5YVdR{i>GWEr2;y}X7K3YwHSeyVwall}o2_Jd{ zzeBCq)r{{oZ!2y44+8zcy5^ zsZ>dol&DrG&pwmeH4;NQ8T6U!=>A@Pv@c!d1`qcxT&$a2rKbHd!^5ST4?@us*OV5Hn};)>ZhwQs`H*hoqZ!vVgiCk< z?_26)gyeD=j0-^CmgAWMhLWx?g%se>Ur)C?-c8|;dWPyZnHcVX0mCsbiVKM)VBI=( zCD#kqsmAlowdd6Q%gj4^4f`Kf>E~Sgk=gFpnI$NYyc9JWBW3LVye+?Q=HDt^(`Wu! zd~!ePg^#F!`Jerxpcsp#O|*#fQxiR8nlsU>tE2c~l8N4m=WUtjtsLcG42VXvF?O)Hob?n(DC@UnyxF$()~OGH z`X*cIW(CfG@L;8R8|Ym0@*=Ct?~}7kW!vQtn|USC6V1pb+>)FM%ZeSj<4rRahgwmv zb#AWhWg@x;q65?`qOk8=3~)+f^N(=r`~2p#`j|b|P^zNniT$pj6Rp_%GPi<1?NY%m zJ<$SAjr)DDf}ZG-*!<(%it6`X5ht2G3`v*7=9jw_joy1jaKwA4NSDOsk8>+}<>!52 zv&+!nYW7f(E{V;rbSsMOy&_cKd#Fg4#O7O;Thqj}nnJPT_j|)k|KXu1I6RjflJGIC z#4e1PO`X`>q_0Nt2C9o<^J|ioZn>%NIKNG8waMBR|Hs;(D|)>B^i3DV=GVF7J$;wT zc9{Zr?>#_Hm&E2@W7eyaylJ=sHiNKwoMdn9ubzAyZnaEKAF&$+A5Ff;ZI+tF zLcdvX1x&FxH{q95_agPrF7F#JOjfV$Mp4*9xf~XBRlAlSD_)$eUfe<%x2U_8YcEe0 z0RbXoGwf;E;lT)OytlST+Ot-=shspa?%{jebt0wbUrxzINxzPGyjYD`b2Gz6d=uZ~ ziZqX|va$8p-nT|?>kKF&Y{3&g-j^=43O|e>vs*P(2@0>WqJeG%pKlAnbMBN){}A2s z9q`)Dm5$$#)K@y}oL`Z|A131STS>L~5A5`h@^m7Pl(T4znksr5NBEa(>M8fix>fWh zX=XYC%Ia>TWqw~QjM8sR?Ll#lyc3%-8=b*pd?B&V)L$o3Sv2q|9ZnRbb$B2h&P{bV z-|aBL9d++eq7hZ-(_qDFQT@r69Jth$MY?OqV5t#ds`t86+^(&1JsmnaeGXFT2jnSq zO%_X;^sbPP{vy1VYqHRCD-TAtd?P)*OVkK>0EwP|zbNgOyr`iWxDn~{!=#Ze-v&H? zN3tz&M`z%dDJ@LkM$uaD>t8N4a8|rgRhTZ{ujNq37#Z@7X=14UO%U$nbJg-QoYg&} zsjRmJO_$TdN9f@*nwN^6-zELq`hw}-BX-UwB%{d0m*sp&ijMxJGw_rPP^SA4r+bDK zoBoKp^G1Q_`8Yz|;hjCnA_N)J{zzK?j_k*bV0IBcv*aXXh>IbC?{>*iZ$nfl_QK`# zHe@&S%6kpHc+psx%$(aRe$Yn;h1jnj%*k64&wYuH+j2gVcna4`9T8neZ(!`9-j=tM zWA{GcBduoorPs0&yZ~dg@PqD3I1GTyVP;qfK;ddVU4FS**(lTH->1{RZyNf09rV{6 zr9uCn-Jo&oFyP?TlUCUm^-KE$$o{*5=L~hd`Yq)> z*U^1l^o;w?()4$(<{bxm*4TwYM!C_d$tMSe!z})BmmdTIBb@kKddtg5 z5Hipa2W)W(_-QoOxlm)*%&vtm@}1OEeYA))m$IdZP<}IcL84b9)vQFS>AF=-BZz&e zmz+keUdJh~LyvEg9=oq0f)V*0TIxB5v{$XzYS~dehEnW!+_0|64Z-b{xZS?^u+}BI&MzajUuv-P;ciIt2Z)FzmmhZ=9P=gD~7BKy>|D%Cl>3T z-eF+)c4Hy;zjlG&+u<#J`H{}%7x>7f{_ECtHVZ^k&th*|Wv>a?8^nN2ZbR?OzZs4B za^h|rNVp+PV6mT_Rvxg|sJFHx5@=K<%YneI-{HTTlk;!_XnlF-=G@y_&&gS%^&&bKzLzGklo{ zt+tQ(#9kBWLES2onj<#U`=I?UfiPAHJKU{?P=&pgliP&#_=kQS=M+5y(%xQR#pWDg z4*F-eu+9+(H3(BbRG;q}a_ym@P&94|x=Vc4;hgi2nbC|yF; zpzbq%tK_3yL`L@7NKbxRf28+isoqzk1e8|_c6p^d^~(30SN2T}|F~3Xo|L{M#vooX z1{o~>xO}_&#++|diseYd!2I36-z|^SfQl%&CUV2fg zw1`q>8s{V5)!0yks15`XZkEzWi=-ae(6W z>JQYHS`6T4XY)&Yr9XpU_5@Y;K!wH$*4L(0x-0$3+S8X%i8bmwXfn z(RFg0zaS%=Ey3x#u9NLU{*wa{ajMvF9$tbyk zc6Mlyz`zgW+GrLN7KVf%rh~`GGxT|uus~WdO9W(es$UXo zEYdr`yRewg@Hg`}WB^rmOY=ovf>T)?{={aS=z=UYWx=fB#3Cy(Zhy0JC}$nKD)KH! zR_U|w{Oetsm)X>ly=~J0?LCOLnYhz(|AIUL1?hyc>MV|W6H0=x`h3^Xlg+m{A4Zuq z!RMHy<*nit#iVS1d3LV1>NR_152`C&$$$D@8t2nIkH36s_5$Onf@IFsIa<4HujrYo zm%}xT0voD|osFa52X)xEZuLGA5_@B7`@Er?qkR;HKhT|~{UZINEp)9N@8odxhsxBisEK&N1lK^Bj9aCuUinOPm5EOMNyXMHp10qo;%C6G zAgb43#nggup4;4mA_YwwF?58<9mzBOZ|mBr}_{vw{EPd37Epx+-TMtqHjigh8A*R9?{^A+h$ zH13zR(ZJ!W@E^4cBq-LtX6PuKYj{cpDXbOTt<#$z3-Utl9-Y+d@m$W|QvN*XNKfGJ zM*ddt=d369zLAhF6Un3!G_>r`T{Of7L(s4q=PrVV4gYr0(8X}j3;qf(03eIgv(pM3 zn-hCzdG=txj$_z!p;RRPpzTcW()}|0J9(74;DbtFA-P1f(l4Gg+QaQT)C(N z`muq(fAZ(s;qjcw-y{6J%b%v#Nqwd!N(LX?_$ifIw<)Aa2crnGjMicXk`t=v@Lsn` z!1GtSB>xdi`dRP7*YsS!fNek!Gelz^kW+2{TNJzFhJ`A25-DY;>^9$LirJXnMAeA} zm+CqZ9Eq%C-M<;$;sjm~m97Y~!tqh6ta7a1+a+uX0$KhF*kHX2#X2k4@gZ+?tNY4i zE8FP463b(=#TgOA{kQT$0nXEF*Xm@~fc zhG6NxWH#x>B~CY-K0L3E(S3N%6s7tQztpm~SRL;}(Bjf%_U*2mB>vcwcjyizbO#2S z_AzOoed3|9WY6_kuppKUhe$2guob>Zl$wNp<_iA%w}z$lWUcZv^sW3bU-I4mnJ)cx^46To{-b# z&k4mYCrFgLIC1g3r^TC;A!hTjBSDj5la^rHz+KO(NTcE7g7zFKDR1jNW6aq>Ryl)_jsD(X3lH=QhFzbE1t>^{NMeYs~swfi{aN4sA-_8uhCgg%(Ha4{Bke2GjjA`GXT_82N)!e#EHOUUiHFKPhTVtn{&(6YmVbAYp zI+`!@iql^HJuhT>{tp)GkXjJ+$!x(^_$@m-b8OC^)@6DY1wCx^C?re@Q`ep z{#cS3Co?jB9LYrZ*V5R#t1~^`Nv;LrabObj*)LBlCmPsAI;UPI{bKa4744ZXjIeD03>-(Z6!iJsytL{B^w36x; zOk^5{>o!v{A5PSBYHY%}YbjMr=-K>7;PTX(umMk|bY>Wxi9bcr7pr)>jHk$WMKTe7 zK&x|Fw8JE^^#8}w3=ff!uP<(=w&nRK9%d3+O-|~#Q+kvi&!gbv^~H-wsSn_)p{V}l z`jSEH7X6+Ux~cdBQnc~W!SYz6{>q!64Whmcl2N8AKvXgy7-Zy+mu{6vmXwyO*wIe1 zR$c2R=c+j-X+jIAi}e$}owQV3Yq>l^ibVmpTWpP^`_o4BAC$uXN6|R zS_WOP3qN~4ZKj@Zmh1*QJ7a9lp)ymr6fgXW@d$PtlB5r~m|&baG8tPN1^nAJ_+NVT zV6xZC@b3_a#qu-nX7ciRMV9W%Qg8+j@rRP6MJJ5>XM?y|c!ZgVd^Di37MY>9#8`K?%?<@bS>)r~n#W!9idR{gD?Lp-Z1ypj~^QkMla6^;<(CxqfHxpl+BY5I&0}>({?z?4xC@ z*u&*D=42WwLO}b_V&Hu56$Z{n%2yxrkXo_3z}xWC$SY)1#K;?M^`f5X~6_W7S(^m#H%c^wI~NczTH1M@3dB&iE6k`qvBz7I{(`GPb)>FJKkO-~== zLp6b(#-E_*UU^!~Q)K)dBopC#jCQt6mU59<%GH&2&YzZvzOxKX-|tDG?>w$EaDr%_ z3*<%bV|vY3`|O-zQ!I+W14y<7_UR1liwQhDC_tMI9ILk~FGncuqb73;$lai}-y^xb zq?f4t`y{4mu9{|&)wiq3PHMRt@1!=WF;1#i`zKq3B#m;(Wd9KAR1G2dHm%(MptN!;t@ON)L?InR zp$8mnMuzOw)mU8{`El+_*4e&R^uS_2d{Asu?LT)WI#jmZ61imvn4SeOKCn2k+28!` zXl}SxMThydP$d3ca=Zu%b&jmrcmX*Bdz~DO3JGM9nc_$GaIRStw~uQI`}`dT4e%${ zh(O@!+{im8`v)N+l-B~SFE037e4xK8xj>n_t9PNCkWzo4SgRzP5|CviNOl_?DWS-yqbXGLOd5<&6)r@j) ze-~4p{`Z%`86Nq2p1-&G>jPg||86`bJO2|F+aAc$wJXdXkaIQ(x$7u9Wy%vmEdK}O ztB)_0H9MVTBK(qn$;?N8AShj@9=}^JBL9*}kNPF2Qr)d{HmZ-(mXZjWzGS&2*V3qu zI}CCAyX4A;B`R3rBrWxQH(9U7kYp*n!DSP5|4$7~>E>g#g$JR2yY|>XA$19q&%#DrBeNQ-E>iiwlW}a+@ui#~ zfXs2Z`lo{&Phqc^%CA*#I{B^t6ajI&6Q*abdd|szJ}>n?gz}G0_Dqcb+}B6l`-Ypu->g&aQ(aD~Qa$CQ>eOQml!OmE9ubQ<@Aiq%^pk456(9C%CM)mMw1E4dY zQZA2Pyu2nZU`M&^#Q~Bj;wv&Gp z_cz`AQHRre;WN&b!sw{M@~Btx@?vK})~P?3BryD)lUl6qa8m8+MklpdwK^$}nr~A1 zD>*o*2|%N#kSzeXy(<~NCL=Qb6_UVhh$#r(2Hc*#Si`MWRe%WsxA)|#sdI>_E?13r z$%r=l?V)4y%lO=T!?ot?gQeO@y4vBU+KY7oKrQ=?0qX7PRc%xkn<;pdy_|Vk`)da4 zGW_{}=7zS)r7dVvHRsoZO=`2c$4RxTUy@=t2TQMq(rez#|BZY$T^@Sk+~!Cl$n1CQ zssx)h*Vc3dLVHk11ky%G1qBp`0cB7Qoc}vE2RYSH7-W-3V9}MRF7CIofmkc`%GD{i z3C(|M7cD-iftzvSa;HS336U$yJ#$8g7mroyhwVrGYGd0GZIrj{(>di zPy?2l{v{x|aeY*;xle*p1iL0GFL2{`a|XX{xSqfrK@j_`i5r5^iOVTymjZrQ@k9RU z%hie8ueCRJ#78&%0};#_qWyp~n*z@y6xI^;mJ_B~ALkIn^ae{;xwrdf_kWzbVlg|p z%=Y;|#M*5s8(av99L8JQ>scC+XB))4AWa|X^7juH*U4$J`D4Ck{&UWG#2IF*Z0L6W zN34pzyHQedb3dK~7Muc?FCIoLJEl1RT3kqrLiwe}{uuqUZUOiAK~N;P|3ki2XY&wW z%F`M0w2Y_7c#C8r{9D85Hwgc};9<>g#+vAu7&@N%dt>O>0KY$lH2nTt82Sk$+X7d1 z2IhPGOYVB~I+kLMn)pk-nEgvy9&I9{OdU%`a^Y4NsGnnF3E_AY4ieV?i#yUwH>l%& zC8b;aOGZCBloyt$fAE4931rb3P7Dp?E>dsat}6lQpo9(TkLk4t<9{TLB$*iz4;*MR z9LE0yj)-cIWXbpC>eA6pvR2J-lXF$ANkZSJI;rKV%1LchCpoEJRpz9M)S*tQTpj47 zYSlhEW#8H+{nvc^50iX5=>Bc^_D_E;eEXZI%zE~xE?GeiKXp}c!LCQi&mVU1OpcPR zPwf%Ojs+%KDl~|Mdz3r`4C#B6oKN69bBrAHbFl0283wz);4rRs@SvqaAIQ_$7YTN~ zM$(lE1@tlUGelcRgya}`(t{eA%0Q-LNVWxz?F@|3$4KLirrP&}53s2%`?GSQ`f!=^ zIWO{gzz1UPd_WtVc2;sM5^VYaX@zV`Q#Cu~Y~~x(Xa^_LPn}ED9luCNy+!H?jZ+Ap z984=PxOD}uNu6I}2IFpYf?{h7&KZG|px6_VVGfp^%NYL%>T~dGC}!R|S*x<#hDf!qk7Fr^{Ndz^}jh-J`SJ0PThUJIap3Yu%}_!_h30XiJQ=_lO3zE|@_WV4(;iC0&-bB4dmw^OE_LwpCK4`wiq-y}@N*uwNYs8mF!*^DAE|SB z(D-?&JUzivWc&|F_Qg*>0yB-D%a1%sq?LiP&cLz#Am!QnrI7Nc_otAu`95O>y)=Iz zsWz*ivvQb0&&im(3o3OBpWyOL8&s3Q+9cwYX~OsA&0vSi@IdlLYCPNxJzwHAsqq%#hBUN+K6)~bu#Sf_q{4(RzegP!YBij~u&wzaG z0U;m!69_5#lqM2v{Ngb*mVYx3>H|(9vHtf9x^b!V&j7tE5GHY_aqI0*To}$0{FlR?2V^mVLecLO7JO>ZFZ3 ziwmUA=4Yj9E#F@tz4?gM3O?j#@{u}*-Wd7*qdeWn6Y_nM?n*IQ21BH;FWwA|HiSAb zOxA=cg_FpcZfJdreg%SkJOoE>2rSL7Amyx$M-LGNz!D+!@84vw`Ay8C-2;%L8yM*z z`iit7+50nfesW#hQoMnRgml-aWiU#zHb!U5uh|ZSQhRSnTO0YG3Hbj_EzWBA!SLj2 zIMYqeRZ~pT(G`q$pO#CnkJe9U4wN*l_xSr<9CfrS--?V5{Dt7@KhFYB#nMRjdH26v z@gwivUGU>qtnoeIM=uPv-s!uA(@w*W6EzO*jvtr(4E$Kbq7?jil8@A|^BnwmSe`E9 zDKdUB$^V2Ohj{zqN5Ih9Bz}CwiU&XJ{OsQ%V73q&=kFw|&DyWCve1);D1W`tOzq?B z^t&L+XU?qOkya##vPtLnizqjs+z>?BrWacZQ9b}2lSDLsF&w*kNwNgJ%2hd+hIO)5 z9qA_Ls_&YlgDCsCPa07M=%+r2^6UQvqP%spAj-PwAWF4C6wXrh95ViSw}Tega@zR| zS=xKRiA(+nP8AG+L8zC=&~1s~5s{CD&opb7vbQ7|&ZO4+0urN72#p^kbeP z;}0g82rqNaZJOW9fEj>_BYU)ShTSC$AIE4ozJa81Ky)nUxG`u1jLPo}F=)zv`VUmN z{dxf}$2LdYJ=aynX))QiVM~_5v9441o&lIjQ>tCPq>}5Yi6w03pAW6u6;eqx_9{5) z1s4OWyM(pgRlX^*z*ymVQWP6?wSHr*`ZegPQKepG?hCHP@+%es&e^pFoU?gNJ;g(R z0#jZ-Q_2Sc`^flHNG8J9K8nkDE#C!59FOcFWAg`5a!oUDd*tocsVy@8i{JCMx3!+p zicb7#9sO9>V2j!LU4F8gITnTZLu5+V*$(2Tm>{FM@RJgoIeyx1GmL;P{ zRHDlEagvrgge27;)ym-RfNt?deo$WD%!8Wqce7Yyg@xo%bb=H$%i@dW50-EK&-rG& z6g(^sJr8SycIHQ1A#r78IqQ^f3Lm{wK(<|7dZs`@tVzUP#N1l$K`xvUx$E!62*+`{ zDxx0k{)Bs=E3~vn{{dE>UR@VB&JCQGaSFu4{bJYpW zUoPg`t14pGrgRoZ*(=g?7QWcEj?Q9sA@z%fBVTMBk71?soX3oEiAj$Z!x)x`T-4Uj zC@fMr#k4$}zgG_ykY#4_|E~X~XQiiieXpNqPk;5Ly_YJ_a5paJxBvP42vQ;Q`I|HP zna{E5TcCVjq^|^N!7M2AY-2R=}efokFUg>C!>v$_)mwc%|+>xI8G9l7mv zG#s}kvm2f4CbE0xg8<2r3!IXfQu2fJ63ZzGNy+5&l4G5cW2FT9tyFCXIweI?vTu6H z0Hlfhpjxp~jznx{sdoXV)>I%=`(c)mN?v6YrWKqmHGr$ zUU?m2@?G8AQ9~6qB)a9x*2ID}J;yT!x`gflC-y6E)@v<`HwwV!MBOER^-#{*4G!T>UoRYD;Wm0{x&xFPjvR6wCuAb`xTu%I4%1W$$my>=cZ*>NcICd zJ3lS^2+4*8q{+OnH`(MUvg21b?Km$jZo@8q& z7s`G=*{pyEwD*nf_+jc7WY{lNiM>L%nkTd*R`@fgbWrkBQ@^@czLpKaYyg#JOGu}; zDSJ@IGP1|)E3=1IF7;L}d#bW&{pQD>iC=_!%gC1tyf-XloRv)l~h;Rz3KZ*%R&tGVlx-;jfK+IoR7Og5hM(wzBHgUDY%s zk+}~`(iigrta4g^<~pyX#pk|PZ((cI`BKEd4%GvzavSLTeYw1p98b@9D7_MSNY5Bj zAQ3D@>b|7dD`@<2U1|AkB{y+D)6{%XasbOXiU^5(J(MK)*%hCL#~3ny)dbRI_DYvu8{flB)K94`KGNL`ek4zM?nW`4C#PB3 z`w8t?GvZwMJ&63Y9m3d?$>zXpKsBFpzIh1?^z~-9$Sz~2uv7_EB=?5(vXsE9OPG5H z5Te&{|I_pd{zHh9rc7TZALG;hhKdJYs?P|Rx!_g>O_Xqb#q)$W1G0S_hgHD!iI6I_%!(GjW-zbpvoQ#V7Zt2CAql-gpWCh-$!X}7$AjgGXV#torRC(tTE74Ax=L>T!RqA!ladN1i#cTRG+ zy81p`9sA6;5p2BGtmQuwWtez**XI`TCJ&ThEZB%NxG`S<0PMoVIvS{+M4yHE)XiFN z020DdidMXmYYDTiUS#i|^cXNme5gi#CzOZYQ{Q^^R+rp+^orQb6RTzA@p0?xbH}Cj zPm8L`x#gMBhP1|=2odfu4eg9wf8rQ2!Hs9kTkkf0MT_*0fI`ASum!xU5w=_XjIV^V zL6j%5Y&$4}y|efMd8_%^CVpg1AKM;(LuNI_KZ^bxANTghEVmltgfm(9wYu)@>L}?^ zU;M=Bg`E1MfsJ^&*-Y)){oQ;O;i|n|kOa<9G*KI^vDKTs5jkO_pys<(>ZwixAg|=v z)tdnl@HsIZJ~R-UUSztW0aaZj!1-Okd;x3#ixsWjJnto|qI%;Mt;t@mLtHPf&XreX zvYB*QRm^t)G?nQNY^B$|Zm+{L7pdQiEkvr{?7h`n>38p}%jgDQtx|(@pRc))lHUIM ztNQKlKVUB8i)4R$b$_>B5tGT%*TvFqiq+^D`p{W#yZCFHDN|MH`fD>+{{F@$l6F}K zaQAW3w%Ik{0CxV~UEDLz@yW23R(>NlZ8u-TQlfu&!VY$9&Jh>Z&ApxikLL=SIHflj zX+O*=#jITA;!S7toPAiZL5ztpCBYkSPmsp&I*}IX$?>^7&QzNuID((PGm}@l?aK?Q z;JQOL{z&aj!HR9O@X%?|CI-gFi()~K$vMVIQ*sy8HFk)wB(8r@X zt7H##3~P9EvNJFIdJT>6&0=>vyHuAgTksf0o4b5-eK@{b69e7io69`Jb4SI6nKYWd>WlqP}#<XCbUYpAHZY+#;o2uihbFS1m_O>nVe}g1gT#ieN>T_u4jT(|%467Y2M4 z82j8D?-Tp$>XlW|0fzRVC(lqXe!+~2Z}`npp%uNXXx9e8dDWmh;%tm3IHSZf`*G?_ z=?bV_Ba>4r3j(I8PO!o_u8>8*knX(JM@!8=SZWtMZ1 zRq?WS;m>3k=n3bHvZB)pSW|wMq60nk48obt?C*QxQ)M#;FUs~l{(tOD$maqAUI!JS zMFIu%S&h1?F&gi{;Y(!qW_(x4If(F$dXNn7R2cHU!_)XL@>Teu&3X^Zd8p0dhtTfo z9L)|P87;xZgnIZG6n9HE%G~}|l25Cq9fySvsXQr8poz2EWtDVIF5o+2$4u5(GP7&o zVV<6&5o*}aMcNUXU*=ti)Su%GoBmhNB57UPlG*TmIpthi#E%Zy+J9AJ+Gj=w_WYgN z`!A=dfu5dc_g0?k>A7cb<%2xhjlmx4AMEM5Xm8&S@$^*ftvt`uQ@pqGd{0mI-pUW~ z^!y#*?y-M9#=p1n?=t?qm7mA>_f~$iC;p>7Hs0!qpR&io#h&<)sX~tbNer=bCZH2y zYEc%RM5=9aX6NKAkQo$4tqwSZ5xka7L>n~-?r>?5Y%RM?B3<7q|Iy-B87CG0y>pn5 zt*~3o%-;3-LYBIlg9>X?cxhJ7dUY&%D%UvSdTqq7PCbBExDT5!bu~#{x54kO zo4IICMTY0ZaT%Vo_*-{UhUYeZhm*I3-^cm$kI(Sj$ln~&FYtFFWoPj>ob;>w-p1d* z_`8aCmhpQrzxVRzDeU*Z48le8UzSstozw4ICUZdHz`|Tf4l>V!3k!!7=H(X_4)vOh z!UBGW6?*pBw{Sn9Yj{XPAD8mi`fzcB9OIimUL;d#=ajcN6sJ`nV0_<*Dh4NLf7ck( zx&io$!Rj?vX%%y9GtX6R_eyr4wf&mIaJ7-t*L17gBZWpW6ES%~%@fOic_o0%8Qo$l==CyW~X4sEbru3LowZY$UC_!l-0VK_ktB0ye%gU zU=boo^gcZ}=D%xP&YYZ>|H1gknEx4*UL7AA^KTe8$h+`b-Xz)aUUnA#K(I;X`|zsq zo{g}YUZ7JxKJhknUH41g6X98b$Gh+b(vcktyw|;y1KC^|*?cl^5C9wrm%~d4XT1w$ zHo1w{fX+SEM86{KP2Q#LZGnc)z~xdav>7z%&f$stLdnsPQi4 zpe7DAengbcMcg-o*~D(T%G@<$pG+Q6`}fJIFZ00FB?FF}JPTx1M|;4M zG)Sd}SESxO__yuOX1cZ~Ny}@4F(KCQsXOSMDx57v-y$ccP143=F zE#O@Yc-!<-XR9a$QsDJI-H`%p`fPN>^P1v57w&pafIDu%0u37OVCNDlQgQBAEDFW6 ztv9$PdC7U{mNFo@icCE<=CYyw@SD%hZ!eeGxpB-cv*S#6!#A(6MpyWKQ{jJ&Jej(- zt;d?~J>U%4d);Tq{g~86Wb`Z}&9n%RWLnz!ZPQPkt$!l@HKxU0*`e}^PtNYMRQk+w zM|_{Ac!4u<>2q$Djm~jra4T)9!@2as49eWLN`_k~T#(8$g?h>;m%QZkZspdLOfP!j zKGQ2Nee>B^ahXi-5|}cnGk2FdrDNZ`&P#Qj=Q(w{bK=~2HP;iqF_9Rl>&$iPY?FSa zQJrsrhN~}?fiEl51OKnlaK5hXVpCgk<$16BF{D`&#$8sQ_u5mWq`z3u$55~vjXXf= zhnoAn!v+MqCdpiLnPrk@l?~GQ+XnbMC&3ax1HIQBF17cegWhZNlP&h8h1Y$7er~rG zAN;96CRR9azOWfFjkEvE&^W8{)kyndF^23>f89r#E4&&DIo{P-IexxRvOqOz5a(~H z?`&P47$*(vJOSG2d6dp zbJ!|#P{FkxH>wX=g?yy4wm@5^c&;=V@c~<49Vd^}W@cpz&E?zZSB$H!T?9X*>d- zc)3k;M|i@+NO8hG#v0q;^G4z_1!N%4iDtH)QqTjJ!D5;0T zQr84oTAt1c1)iR>9nPiH|n23w&)De0p1x;7d%xtUT3f~nCL3{X^)#f}0K;eOW<<^MsQI5Vro^`u} z^(&F~g7^>w%0i=n$p(U-@OI52HiN7$x7aTj_3Qptu(hIg(51q`2Pw*B{OPk0? zvf{@B4Ek^J_DVejqG-twDi}ii0Q03(9w*SsNn=(6*o^2YO!P`4{^BqTP3YqiDE$cQ z#H$#r@w4ZT)YBI~9QhD_fp9Z6QsnjL42PlDq|C-TLu5i%0VJK`Q~d96Gf?gW`t=;3 zF`i(i@;hD=Pi&P{QBx4cH7DS}6NbU4#t(TW4BE;d@iS#g_fPr<$C)GX!B%O+_^djb zD{rMnAo#2Gt-z3=29CboUtnCF+O@e&^QjH{%F%Kx6Ydz%P7K*-Y-)k(#x#c^Jy}8l zVi)yTDGu#LRJ^<{%+!HcVwMdG^A6HB9?J{yS6fKBLJx>%!=@q(kqm(W- zrHu=okoi`%QbM*o;IR>3k+L$?CVendaUiipB5p-zF(D7@w~YT}pYxqtU9motc)BX} zy6dXU(`zG^|G;dipO5RcM`?sKr35v}jc1S9X1_&v8H6?z-l@A~YVJJT^yoj;Jln0g z)~$K8c2(*KBn?>R>B{H<4y&S-1v9%Ui!u;Lp>mGS@##+Nw4#62ATzC7@&Tkd1;@rc z3@vAr?f~k%`MLv)M!WgKSzgd4=wTq&ekFuWhbFGag5hcS+7A7~lVA6&0hSPxtPmT; zD?EE|#-oKtFN@dYDt#sQWJQ}K>5yK0;Q_&ldA?bfTFa-K|8jz3C*^uuxPOIEQT(j& zPx%vNJgTc8P>YC#;N!1EP%C?DLSo9yB|}{E@_#*#^%^YDNeEP>_izl9MRms!U7v#< zDUqE`7Ru9lp>+1UP-f+cZkmO%uPmL@AXS`3o~?6CDAbzoQAu)v@4CLz{24>m*r0F> zJle7k4_3VGZ5a+C1)p*U%jtI}eB~5h2%9&$h|F@m%0sH)<%ozk(K0s1N_Iz*HBERN z#;z?i_EO-p1%Oz%WRp|3a04X55J><|MFO@m4K@uk>CpVcWPhJxcC5qs-cU<|b2iZpw#V86*#MCkI+XGg z9^!|IsNNx!2lS0^Nj{slLoWp^t#B6!2>{E^buRPt6ZnW!xCHHRSWQ3N5!`BcJ5*Hs z$K$$9wg^1A6(}urF#aBMFn5&w1(9oC0_Mz@)(13y+%6*!m(wBqVodvvWB!c48Ds4) zI$m9L-@)?UEAmjI9&~U1)u`{A3nK`Qpm@2Ol(Sldf;$$ZmFjg%dV)*C1D@1~{3%9v znug<-lJ89BYh;@4ep4!rXjzWHG7z9w0OaIeXNqLYc=fJRhal#WE0U^kkWGURCZJ4{ zJ5lqVwVG2GD&Qx4RHyuJYOYT!pXCnF4}PMBGbo?A0Mv*(PA6E-Jd$8(WdXN}!=z`L za5UF)yKu3P;C5j={U;){hc!chr~<$U1ULzbtVVvg>I?cT#}?t6YH zhlHOOQ)?{eEVuG5fw2xUT&%aZJBynbnXG0PLbCt(B{VPX;yhAp18~r{#VVC>r`5Ky zI=?b(|K(pL`zIfyBR{=PL+nMXs%O9YbP~Dj1Cn={%X#CWo!|9H9Yy#+ttC)GY z0{zn7P$@BM6WPglwccv`9SNW;+SOif3lnZ;A%V7Zm4LLKiO6P)67DS-wANp3Zw+>Q zK>m6mn|10UOuz-~!N`YOLs`9CRS!n-sg1|>=&3;8orGY8N}GU?{V%JcE99NHwVG4G zLg7Z^4??|V0@flXF%xiVL8uf-@ylvCS-VfbR#)6r)Ss$*yl^aQ50b?(23Qk?m=THp z%#IJUt*o8GnF00rY;`~$0@nceMSm=0^8Eg1AbO$9!0EW$UZ<+Twmvg}wklWfQJ7d! zVX=0*GKA4birH8u{?zf*1VA#H$~}!3D991bd1Q->tSAs^=W9Ve4HA1ss*vAQ6Q(k$ z-D${e<$qMa$dPj$o^w+tU?X^r?Co9tJoBRu;F`kui^NH+ANL>rGEr}~`HQ0da_=yI zCAl@^)|y;-1jhb){=j+vTr1k##QXfTnV&`GM>D6<=EXc2iuvkjnK%9y4lSaKIp)Y2 zBnc5H2CTa9&ptlud515OWdb$BKR1m9ab63L7}FljwB%SEolw9Z7(*BtsSc-mk&m(( z$4j&qc?-_XiLe))$XiaMA=~uWzNv}E*oD+jMKJFcgMW;3BCcY)vRFp+o1H8D`~SW_ zMY>M6!QK0FwHE$4-R-A8eZQCfID3DyfiC+$ex+A6o-cHy4Es0gU|o!`Z2rv@oJBZ| zvNrj6Fpq$f9LT(+Cgkdwuo5>e1_Y{xgNAI^6*>}Bc*(9zM92=-Y1cB->iK?du=EA1 zqmN9b6feN#SA3tga!;6idT_->J3H_6^Res>gYh*FiS+Q!BD9o#c-;S)$kR~Kl zBMeQwW`7ce!=y+!`5J46MWBrH@@kS#v76+ITJ(&(ki1-Pj4nd=_wQs% zWd}LWZ^(19vOnsljnomx@Jibiiy=Gl*s%RYpz$iet5t0WVcz<|j>!5<5r~~4K9w;V zwsVPB+~qG2;))4NCDG(+1$B$8*z{T}a&?2Kqo&t#*s52Pr~we;Bt=*wC+b~o8fVmh z)VofqRyQ1w;lXIV?o>N_GXWAr|8qZjm$Vs+joNkrquSfVspGPQO~XbnQF!>7ysVL; zdpc8_-Gj>%g#juIOy;l&uYOzs-W&B@S{o zKP$Ly%rw}?F#k(4yh^E`+JU~%$n^gVy{yu!eiOPvq8*BFwgSR)WQOi-iJPeJT|(ta2E#I#-Ho3t}G&0Phd3{3`182~FQP_nG#26cJu2uVCec>!08J0O^pQ@qi0A$6e-2mb<0EwLr zD7Z{5BfkU+4=CP$%LT9osgghkJPWr`F)f$S zXVGc7Rj4_vu1Z6CBfVMSX#y>Y%7BP&T0tX{p}_(!MuLqB%?K*z9>^%0pOt>B6!`hn z2Y7i+f8zu86!#68$1?TzEeHoZ{#F*6Ky`yG+;WfLcK;WPwaQid>7BO(mf2vpaHA8ECJsfw2wNQV_dBS#594opO zF4nbBkLkSd@D=|0Mi?x2QjFrQtzRn79j10&Rq~(0A(1 zZF(+RGd~-89xpP2{^+#wROK??kq%5D_w>~@&R4wX{6|o_0UQ$BhDlEZBPa6|`6#pT zP%*`q=+WWhd+yh#lzslRZIwnAOH%U%^4k7r^$~T>H94@qx-^vfo_*jIMSU0 z9o(R9-?$S4kLZjd{vePuh+;FNjK6aJD*3bc!}5McEq`_Vaq^pDS;(lZiq9JJL(xO6 z$i&Lrp3ek@>@C64k40#h6j+T$hU9I@X5K@wa7M6nojwI>;gm?JN>^|Qn0+)tLSiO4 zqQP$U99QHxc7&qE3ZYUZ;=6LXo)ib3V8nszgB6`gao__qAODLZ4jd1gEgy;~5aVhq zmIo8_iaJzt-%~iT7@44Daej@w+nW+eX*&mhdhG8xCkW8Wy#mSk<)_5532-#Ak}C!$ z^9vYYcti|^wosOfzRMsy{L0rS|Y1JK26`3I?Y%gy4yrOQKv@!7@jJ@SKnPxSV%Ak=|@?t0=^wfwfKZda1jYfl}v8sZ%<- zdz~hiI!i>3b+w55s0 z!_sQPdcxF1-E&-}uu~6!uiY9i==AqyAPTCOQX&l4loAnbG|9wA2*>Am-$>4_BxHU$ zPPp;BoR!g|*Cmo+QOXTcAHF3B4OVRxc9e`0#Kc*8hfD~;Q8iPHJWO-+M0!0|bM*1S zdcxHA#J#i}Tc1~>r6;T^Xa`3&xxWOJu5>7i>6Y}zxKcv0N%zsbydahHR);S%b`VlE zdji;mM`fEG#p4&5>OlmG=h!-uqFO6S6&-s<02Z4gIWyg9EZ-{YBxUIx{o0c#&hH2-LeK__WktKbDXM)=dCj zB4@9}5u^x~QcJ|2D@_8XX$Youf?{Yf=`wXtk8DsP%jQG37kWKwR>dWPV^FkU3MEV% zjiu_IKzE|6Ta;+M+L*jz=jM-LYuMdfS{cIYTm>aTRuPkpE5iSai zt?{L-JvL(HA^DBUUp{MuSKIhkSDfziUW-kMCsaZFy`PfsN9LDgcyB;Wi@0PQmLM|7 z?%gZY+k;bKW%=bJ!bgTGrunWo42zP+?}luDNi`rFVMW93(eNsftH!3cvy2lpzMfYg zxxs{lRtDFZ7o>B9_Xej!B?Z~%RvD`dnrk>By<|?(&I?Pp~%;j95jHa#k-vA*<`&Zk9j>eJ#c2L{e6j^DoHlWcKHA)+y?F$9)U6C&V z=$M^g$(U{N96f7LerK(ETkxNRdnyZIBI2{#dC-Y^H!*<;;dtb2l_K6NXCUn|5CLzb z9l6#(Ej@6-Tq%CEV$(MZS$Z2%V;)&wgVbVfq7%%TP#=NKRTY8u#(~;uFaABhy+MQ+ zJ~`qIl_TE%B98aox_4yk4j!xn3P;8N_BnYjfjB3LtH7 zRom;>5Q5OS(ytN;^903|jFDtW5B&BjMk@Vj4C(=1ESrU#=eboK;-+)3qC+e>K|@zv zLvJ|tyN~P|TIkk+_?1t3FhSw_fXeL|O$xYZw6k=?+phsQw$dcv?t}8B0q#fKMVBt4 zzcO%pf=Thjk75V{h+;>~nIRN6uz{H7TfMh-2&3h{1);_%aynipfZ7#0B{LU&1Niup@HsIJKIQQV=@=EWDjlp6qUcMm z-V#hj(-6-d2(OhaEK0KunpI9r6p+wd^FZx={z`RXPLhKXdTZ#L(Ayeg}AFOJr@*8t9#jbZek8V-2*9Od;NNvNP7RpVYY4DoOqUQ_|#pD^0n1 zms{tkLq}S%%Zozx2?R$54uQ>_e5<1Wr?|3PRbDqDe3;}}V{3i021~ZgczkeIKncQW z+USwj8aD;xW$g2K@thRRv$TC4ib(dLa64pgl_7U;c^qIp<_e;Z3ea$0Z8Cp@zE!mxT<-=S|pa@1w-2=u&y7ea5!aD|Yf zHD=8mz4tX!kiKTJ{PsFoG|jXn>ulFWgN{-d#OTgG%Oxbs<@)}X%i&u8oFX7%FR>ST z5=gF>3R0S}{+Bz_*3ErJIte$G(qd|~hO(CKnX)p{6lGqOku2sdQUHC%as6$V$A_7DIOZ4 z^J!x~ZOkugLvjOMFo$H*jFq4Z34dABmxBq=o1iaU{xW9S)9Ei4nP`e0YJSfzt~z|u zk(l_w5Pt(-iZBSF@AoxO_7NXeq1c>)MB&(z(2t)bvD_hIG}0j)dMK;IDiy<6?016R z2^-V_D~0Qw;FP!4%c&cUd23ZRDo= z3y54~Z|_FfP|b-iYfZ3Xd*gU%H~@EMpN?%ulMKtdG$ROni2M?zPtnuM#tjY+MKy!& z?Zvj!k=UJHMo)tktHYcX1yqnwfF}M(kSq`(J&8#sk%EuIpKmfpF#z+q046t4c+6Pf zfEfv61ONgD0Fc#fRlI;f0UckfhOZD9;9j=N%96KUQBNVn!5q$y-4n+)thnebgP6I< zyEJ>~o(AxO9>5eC0Nm~se@h#HNJVtlMblS!~5JEmtymBwf%`@U#QKak6zB2 zN+j)@X%@seL1)QKdkP26u&0eXGA`1w=mHO9!-ZY&bJlN9i82Zf9c5>sA!7MK1)NlhV&*lgON0 zqBEnDr4UAbGJlvpR@*b-(od+a_}JU}3!2n6ph27KS-?!%#sSk8jX$zt7l68z+$C<| zCBa|a_~|H!2@!t7S{i4y(}u2JY<7|c+l)rq#yUWnh9F4OGCk6Q73l<{S4tz{-;a4+ zd*ndO)vaFFq}zZYet5OLUh~N;hV`nQ_N9CDeSHWBVaLG`o>w9{7H$-DucRW$*8bbb zBh5UCjJSQTGU7^^i~Y8HJk`0MImz!5AS5!RRYD^0zq@ zwUn%u9}tNi6Q*rO-%lv|4Kn-A1mvS$2u0_>v&;d;UmN@-0(zv<8zfx)!(zWL3h{1r z0hT6ukmrGQ$XaTJ{M5-Z5;m?9@}tM;_#3o1W9z_2R-&-V+_KHN=(J3aU@4!E+9>v; zkqS@vIP+R%qHvU(wZCQOEa4%+D#*ECa%TXPA;M+y+D>lSTJ{*Nu8xiSC-dvEDlRXY z1;G`8#eoA6qKAJJ&m8l5)4XC&P&5luel*C=8v$ASHS#XbfnJunYZ8So zO5Ks(MB@Zg%EU4IYt;=1Z5=8jB5wIGI_lPG42SO+;g5BnR!T{&&|*=Tt2g&UR*_DU z1wPEID<3nG6X()jgWvAKMDAuLvs^3%Mv5DSWbohG#kr7ofEsM2AUN;W5mCiW;Vkwr1!C$ zTdSmji3ObzQE7WRBhB(-UfE7#q3B;0Nrs*CyBe9uh^+chbpBjS>8kAKMB<1!784?} zJ+aSwpK?=KMxV;W4~wkTTKNa%6Ruw5(7``~8_sQ!MB#JHe260lgpPBExL)I3EtnEx z3FNFmMY{igRA)sWbNV*0Z{JLH`n?j}jMC{+A*~d6J#-?#X^o(QvE$2ek^!h~M-+{>@ zT0DYxt>^%|`(H0a-pS~AC)0i*vL>@~TUVwx@PfT2vYLB#UAf+>HTI^++5*zq-l|O@ z`zs9oaHfP^%+;X6Pw6J`PAu>)6yb+Be7#1zLJSx;pfN0h+@-%41_Qa=bI9XmdM?fp zHY)GvP;_d&9gn=99mW6=;z}W%`xoQcwlXt(+_sfPOq)HaUanrVUdX>ucLGve48Osc0Rp6CVa?wzt`g@9>KN_ySi^0~8aUHue$GlAgp!z>fTtI$_N zjjUYm^{U&@egdm9zrYHHBh4n7?87D7Rq03JtYbL?^qVjf>89kGObE}e4S?)HJzEj{ zrrM9?^s>xl^+%p)lD;<{4!vYRbf!UUI1rxP+(v%Lwq+f_plUj><|sLWU*&0Rv?70L zqQKMW*9GD_6h!CSjy-*QgS-Om>l`X8+Lo^qh0UNw=ftb{yIcwrg`1DWa~)D&T@Gnz z3khkM*oeY_`7oM1D{)Aa%8b0aOly6#nMk!}y6u%JOG~*iWrBR|x*_-DG7sIwDiuK` zE$js>gs=}tA|lTctP%HCh7>|6d}Cf5vl{vUoHTqjJUL*@L+WmCYMiWZSWolGQ9(87 zP@zITr{r24?+!?D1pRb?Gr}s}T+dfq0gi5%X44Ei9glh+$*`0Ei9IHbX&ZT3bty_A z6h)I0-5;sAB$(JNKf5sWEVE#of*LI&g{TXcD%O6KRK>29oGMB} z{Hi|+)r;9;!<;A#%C+It^t{L|QO;8{{Qrh=?Wv+}>9o)%;y-h!()X#E$u&g-BsUOilczxR z`dsO`zAn5~xDU7Yw!ZKL_Kl?9&>iU#)(~_BAIqsOv9{CAncVR-f2@ILZ{pO-wo{^7 zMu<{@WTl#ic8cT~Z2P+Cj!_b=Ieb`WmeH&Ts&Q`ZnrJjD`mscgul$wA@%;Fbspkg> zHJmE9z3n7RR4Gx&ghIG{V)L`olcWI5fj9lrW1)Y3eULUbaaPQUKlL0+SL(jSISt4N zRum;iulH+bJ{`0=1VV@eTK#giy_PJ%KSPSL-=30)U)9 zmdWzcoJr0@PP)$6jITV*?7MRCg9U3B#HkkqfR*f$vgF+Xt|?rgzunV?0?uyINV$An zpD6qRMzqrSgF@rUuMfrUm0nr)pXDcHKedscU?kxUc_)A1=bD!NXMt$28G)YcwKo8e z>eg+I(}gKJ{T|t3QSo#B;pDwa4Zv-6bu8~Yp=k96E$Y>1OS^Y41LzO>W?n+(a_VEI zM%_+_2vHLK>4s=vqqIMJVlZ|VyIH48F-y(G#@X1};Ner{!cUK$y?+Sk_c;S~iYz1qcTxiKY2}K;Pe`SNx2%z;?ama&@9EtNMZ3H*frTKMg7QG=Q0Ge zmzBri_2t4sje7N6T??t7;;&p|bh)}4AB{{76J^bqhI0G7{c4g=&`qI{Rne;b%ta5C z{gR-pzAv!-5W!cuL~@s;ge{3}7RZbtRv$Z(EbU6L0n`@=xL?li?qS30v5(^fWC@vsGCy!S=hb|J*= z!jf(@2czL+s1stN^%1SXXm;&ma)Wp(g9$S4x0-vo1aH0oVgZC_)A!cfKp2+Naq|W@ z)%gQl1X8%6u5If&)b}~B%upM46GgDVnBfpeAo@EXva{8B(ct@*QQTV0vea~G1|{QXTp+O8l(6m?tc)y#DetPO0(j?CqFuQudMfMaA>!>J9#)lj>D*p8Eku@*Wj`h3W*MKo9%r@t}QMqF~*Rwz@T)kX5Cx#R(ihYGEnv1G-TyRW16n_j?-dt;IqHj19EX zHDsK5lnr@00g}9dmI-{)`HIC3hkh|MMS>REH!mfrkoBFGaiL$5{FE&Vf>&ie)I@*w z_<+UNi2;YNAg~=Rq+vjLe2#=W$ZH=CWT$XNi7fWx6B!d!eujmUfc63=$aFZ>^zQ;E zzpnlkPUFqf_B09*OB77DaB}NCQLqUIFP{L|VF9oAAc}&Q1`fQ6(oVU+4zDX7&wDdi zWH4UPey@P;zgvtpNMxcDeyqn+!bl@{l1Uob=s>yGp-E{(tl9b>VI+ZeV6&AU`ZvOI zym^*mI)acripZTI5$QvKB`eo|nFhY2Az<`jE#VUYQ_X#W-O&nITKTwOTERel%zj{J3ye$Hd$Y}j6H9powStr-3L5D&TB5-^s5eOG^iI=OStl!~M)0r^ z8!m4LABfa&I#H#xk)EO2L<)y&t{K1{zE15>>oD{ec59d@*uZ3lM{JJlRChI9ys1g| zNOat#iv2qGN!6KTVPP+3D?)+Pi#_X?% zD-?6Pve&ZO8n?})Wt~F9EA4933%>E@Ec!K(>?u-aNA2a@%FTBEG}lV6x+VHWBGPMU zQ~UW^pMEf-M8V@K%A6etxk(gUuP52+Ah3T{dc?|U?DzQ+;V4nCvBYa`hq3^KtT}}@#LiC?-0Z(7vJKAF6M19y zOjV-bR6WP$S`3JfyUdqE)Yk*~(p{J6q7T4SKi!HJeDXW(2Np<}4cvVp7FIo|vNC?^ z)CyFBf#}zn5e~#@Fj?Wm+9bl(oJaS}CfF*=>olaNNDeviM|HD}CLh&tqF_3Z*sOcI}GpGQMOeIp-_5sUiz_zLZpaT499tYJO%8bVE3yYY%S&1oRuD&awG+9>&y| zUAOHiI)+rQ=rmYidlPiMQOD#~+g<;`17)_o=6)oRz@eX2iDtbB7DaZ(gVTlPuF0~u zMI|Y4p#IN*B~g%XyBBDX~-nLs7r*BD9?1;kUMJ=+cp@bx30jBuSGlfwLA zxtlhHF@?D+iE+C`@;rAZ~>Uev`uH+8=E?ZH0L4q*~t`5$ay(Nr@8p*c~olb*abn=Viq>P$dPz8pyavcQsz zb{*!e@M&|Tw_Ql>8G5Ho?~th?Nuev;*~+REdA3<@Q5LrpD(u?XD^W0X4@(3d6*?m) zu)pUTf%ZlEJ++Cz$!)mz8KFJDn-F|5nnP{O^;dKd+EMOp4Ak!@rGOPEsAD#p7{j(^ zlP*yi_=(P(G3*|7LF_yrmj-I=1BI4k3qa8t@F;ppl> zc*ILrxv7X%`43E*+TW$7Y(*H)yA{87+%zL zi`tME!&zN=iL*l15fnX8N90lT;PXJVDqu3@^-uySTd=pBgY~cMYQtrWppx)LS$#}3UzVZ#OES%K#(jiPG-4G>OJD&`Tgi2 z!zsbPI#ICeu5KhFox8~h(0{8|PGA&*=M#LiX2WN7e)2!8Ya3`Job>^rQ4$5SRTk1Y ztRnh^V3<)eSt{1WI#o*qc2@rthx`6qRo*=1uyRw`QhmbS3Eu~G!&ye_r&KQ^`>{5s zKL;k%aQlocl9aY={;vgHGTTuN`PczTOExt?Uy2Hzq;06gX~BUrUDlgm3$B{X0wEqH zzfbH-WoQ$F;vlT{j}rw2f(`M=z(mA>rdfxHR3O0wDmxMd3;AeGvv{Vrn6+;M4g76d z!$V$46#R?2DziRS!6IK)tYWXxKiPZWf*ikX@6$VeR;O~y&UZ3?hBb;iqmdQd<;1i{ zICfg@GDvEM8T)UoRf)TxV;SsM${abNeN)@2@m8tv zq2+=QYu)m2C%n=|S`02d3dl?r5$EXBp&6Cuj>@*TmBsVk*rf-EqdUneqP5b4RCt0i zg4kNK>QCCgORE~iFGP%jw7qvvb99&edTJqJZ3!+0oDC|(2XnAK&Epf`KUp$mTFk|g zA4WP$!0k0=pMMH;XAMKq7Yr-P>92sUVojaRZf$;Y*bEneakBKRMJa8V)eEmRoBybJ z`Dg07r(LbnJl);EhqUeh@Q<9Ilqar*zTd*_6+*hu+t%9(T^Yfbg}=HSDua;O&? z2U(_xGO?Y3y3#w5P3b6RscixJR^o3>#&ee>NTOvN{}oTKjahuUm@}5G8CTa7GM| zRWoy_?eUR7oOQFSQ%p22w2Ktmkkk}EyUVJ=l$`xXcXgu+J6L^|M#w^*$}oAb5E27P zonK8_k#mmN$6pTh#nes9C`>N^V@3tTL;k^`){P7<7-*;x1&T)?l$YgJM4Q3)qvcyC zOc(!{x=DC~M6PJ>k-czXEW#~KU#|UdD?7CaH(VwH4G3c*$Ejk&ZLu>brcm3vBh4g> zjkCpkmDSR_-M=0#2=SxzQ*N9^LW#jVWGt)ZKl5>``oG!9TXKpE7nxPysYUcLL2PZ~ zm6=}~POy1QkZO*pjLpUrH=6?yV<5GuFuRO&mHG)5t~GsS>p(t?k7XULt--_Z`P3Dl zyNQ^YgJl=?u5&O1k;gr+zTE2UV9rpUJalRX>YP3LrfIA~O=O9A&8{XqbF@!Fm&R%^ z_u^kkrb~Y9GL1KzH`>`QxF}WZ?rw@*;ffuZDz<`RUFKh!-k{bUL3TB(Ue2L=`8Z%N z^zgCKI}t1ZYPkM7EGP;zL~Z`ETuzz>>hI!VTe}kRX{-rP-q_J6agYEv69xD8c4HuU zpOWq?T*-dD$-ZK7JF|-tQl;ndTI%1&HDxa6RlGt13p9ZD)G|6ZTAQ6Y`=Vw&q{`nCC&9$l02HxCOaV@Y!Mm-+{I<7~VW8(Dq)|Z!0LyMQ zmm?N+I9H<(T@=H*1W6Jx&(Obro^j}T6EFzQ~`mzo!?R=0k!Da}tmy42@Ju!w^@#SGo zM3`K%&_VDnBhb*sxB8bOKXaprtadQ5QXPjPTg(tf1CP9vv5a9X?`bR{e=HLiOI5yE z^iFClJY7N+{#c$hXY=p?zEY;=;H?uu4(k#&=65lurXH&r)k zu6H&e+xpHXZcEh=R;$Y{D#_h_eyRDhNLeIj+QQD@oY8lyZE)f(@*zX&9s(96PdenJ zBEIyp5nrqVJ^iEu+6SF<=nVQY#cn^|s95o4j*bAYpQED;>}lWHSQ$T{X9bKk7)MIu%)>)vV;TFA<|XMBE?oYE6I6gUaurS0jWy zy0VCOk@soQ9zVBEi5rtUaHP*C2jOkb4!nh+Z4l}$1EwD%gnhq7?H$P}ft-r0_qpLR zSJ!ujW8?C5O=#Sm0)yY%F!15DE%y$jv%7mDW}2GobWq@uYf=XVlJc7N=YpHnmj~_P z9=VTeV(skW4kL+@g92Qi9%RVYFQWmtan{040L#D)^$maHlET*DS?KR#eJ2xh7+}Rx zhr(D)Nyk--zbSkwv`Rg<0WD{r!YFXReBs? zbzUv}7FG`VxaQo>@O8TK_i}<;gG6i1b+bWuQ38SoRAg~Q#TYunBeQpaJ%_Sn=Wt?W zV>o-22oScKDLI^_AiK^}OkviV?5wt_yjvvNtg*|`GKE*m%%Ww=ZKIhUz$SKZrYdSY zA-lOOXL}&%J5sE^mp7Kt);2%_ewhS}$B$r}5B~fGwOMDMWBpM-thvCg14SfYY0#-F z>Fx%ix(O|(HYCwN>-DFUSN zS<=G*sacy!*1{&(N3!ys$;#6p)}>~(Y7VotGlwI_6xIy%xBvHz6M)9#7x{<`{6tIW z!C5P!3K97dbK%trBp1LH zyDA2&*c6WS*@X0ioO}RSrnA+#Fo?)e@KeQ=xI&yRej=L}q9F*IM-exnCDPt8NlXQ{ zRWahJaKOKjU<(a(L}5N0+N;?s;ObVOClSFe~pB+jq~b7uRy%dLJ%Qi+hs zVbU94+a0toFZl9`Wh$vbj<)dyaIIHN3HqG1C7fsp58TW%9UQsYZuhXA0)%me=D8UX zeL0S-C@8V9MG;)SeOR2!-p7KWXud6*KK_Yz{PeKv_`hxF2W#lNs#y0!4~o^;@t@WH z?i1aO|0_HG_AhBa#SPc2X=fkSdHP?^uXPde+B-OKk(S@zA2>SEehn>k@>XTD{L9Cm zJ#_UC8sGDL)Zkn`vIOLKwYizK?8Lqe3JJ}j1xXXafo;XyZb*!f&-9{cDYH4Pd@PuL zEX9)u(A@!?HyQVi`gduU{&BJ=ofO`N>cWx24UzwD-_vgx0t%N-e=E4n zFmt>NjPbFEr3!YKan)9x_i|=%FK^DCI}FyaY5mRI85kRL z@;nOdC%S_h1*&#*Ar0{73@`7tLIF6t#RlRZ1;7IHey?otyu$^(Cdf^+bbpd)>qP!F z2i(u~vF5PN^bM!aCHhY{$M+ucuS znoLeKxg_bs+3!=u43;@_pZ6CPUdaPUS4+Bm2?MEH7Nr>m^1Q_qJCK@j+`n-LIfmyn z@qb|6FUd#+52%9osUTWJz zZ-lFEBoF2`TU`lBs>AWzxnk7Y!OISHaKhfR>=epgP7tO$nb-<~O<+mRP#zoWi*Mkm zxxV;DjU;)>>L!~<;GSyslwT^~{?oBt!F{=`yk>`Lj);=2%3#)><{znt$BXrCERu?#2SN126O0a!NKAgR21i{&#`q<9HBi`tte% zu56J~ZFk)vGMS3r(~P2Fw+jLVEqzH-_CW%D`sX7qYc_IP=lZFsg1_EqSC1D}*>K{S z)audF!3|{~OD5X6dit!3UYXsaroUEbkxF=8axp$=sbE)j)+ui)9u)r77ZopKu`RSE zbCzfOi!FqhYZo;)45&L5iIysBTht9%-kc_7mngB02lb^ax)E6|dmRC1n<}hCHAlT5 zih_iyUX`)GtCsTNm*>{>He2R!kG)+C4mC zYt8P-`x{mpGcC!iUlp^SFd#hS1tL~#)Li=eed60l9o6M1LSXKRS}P#q=}YuGp_fH7 z|F#t>O1YExrMtM31m^aqv?;PhtBw@1G=WTVyCdBfy@AbHV6%7>>#IqX3&E3%O^eTRt3K-xriW+F zxGZui3okQrKId-ByzHLCbAA?poL-NG4UzUD%ta_>&;(vREMt0sA`-1OAKqa#(7mkx zTt{DP$Agsgpq$A$B9T~O2H-u4w7%M$B7w)dF*%loQ>^kkxw30cNxvW3(F;c?zDxg6 zjb%nGz1U=RKFL}m4+<9rR&WvB>V<{iV-dmgz)Nsa($I8#49rz5_-N^cBw-SLt;8m> ze(t;K@@BIdE1s2zFjR_;|Be%Dymt~&iTR3{kC1hU<~l0usS1a4Cc~2UVdmA#QdIt* z$z-i*AxY--Z?S$xKI{nayLpt1^3Xo7i@~{X#4Dg`wMI5z3DZi%rZPn(*Uua*b|+Oa8pI z;aJrz72dB^eU*2uL#byfv!28s!|L#_ZQ_fgnHAo(fG|ZfkN5gCm3f)Ndj_ss018J6 zqO-Cgir0}Y1H}+-=8$CDkstk%_Yd%}R5~eK!iCAPnX6)<)gP4w@{iS}=%Lm!EWfeP z3yx}Tz(eo@sOIOQn$1}Lcut6F_KMBiox2}JG*_9q{Q)YWB@$H-%@ZrU4VB(`y{blh zRnyPXhozS|`cN_AKbBqwDjdDkIVqoBTKZ50y{s6*p>^j#H=V0&Tg}0L7yKrCZfWIc zM;kVz(MtblYZtn3#cp=;(3+&SyPqJ-tTC@I7IvOeOR&PJ0%q1aQb@RBMWm|3UjKFB z7+bGcYr{`XKE#Vq$Q99R^)|PoKlajF$lu13xz-}H zX4HNSd$s;<-=f4B)M@#C)gY1aEs%6A9nJj?z5g&U?cYOcjH)|Lp*z`e+LiwEgDbky zJGzg3)5l+3Rsim<19wZ9dJN-xe4WJIA~Z#H%jVE7Sh5yAQMatlJ)k|xXr7~o%;q`Q z=*MC6dG}F;>_d2efzAC_Ww3x@t3f!wzPS6O@m(%Ql@-5Uz_8IXbn^z0Tx0}`^$6=i z7~P*kCUd$C;%c3p=5DmvxdjDP7DlA&1$&XXVJ5VzmTd#EeFxD^tCSO+>qmFm3wUGd z`A_VmkJaJtTpnW`tzSF(f+QQD;Q^Hv|oUH!Zrs*K&v_N z_Kb{?`{^#@RbJPGH*l3``kM`(5FX6bT+p$H#`b>JGU)f_9l2nui-h* zv%3k*>!o>(=RM7X+3NvO*T+dhUBP+Z8@f^A_hR@Weo<8mM8Bkz4mBcnuOZnO`ekzn zm!EjmBJ+}s{n%zkjS%5o=Wk7?n11#kP+QqjAWhB*jiS$C<0&RVa*LX`pZc(fIGL6p zk2h5p`N^qfluK4EHp7%E;|gOi9jco-0 z#DSLb*7l;=hb*PQizx3lJzm4s8h*H+;QRc^!1q0y+Admeh1>~BoDIi}+G6iITtp>1Z7xSOt zU7>sru;YC?l$n#C5Wlw*$fhTK811520M7OcQZRlsnPmTClSv4NwukV6-3U}y6m|ok zW$hxJcmCCm|JDtF{d1O`z&=|YIoeV)fqlFlG4~1V7Oh)P0PI(Qx|)M?{sg|C9;iRl ze?C#qR|o2k_n$}Uc~YSMF#q{bJX~UybQ( z`JoYH_-fnf)S^idfQ!TN!{5)*MmCpz2j)F#(K_!-UYX|^V6^lDl1%Vje7OG@yEbOM z;b!e8!%{vj*g%(RcKE*7oOwRq<9WBdO3$AAn*-9_)Y5S-jooD%Tgm_U^v3fZAz?1I z4gHN|B2w-*vWMTuiX+n-IVsi17D6FVev}%y*l*-wRrVkcF5Z%9u$$vnCZe~AodGO1 zF$lAv6Iee_%U~`gL#r}8u@D&lGNon3B&k1E zmaCOz1{cVYzEtU>rT%F(Lq{TVT&&b-dON6QgwjtRxhM)eHi>F}qM|3BLyCL&TDkX_R6nI=ok%KIsgqArkE@ErU>5*nF<9}x&VAC= zxY^sNUz}5o7d*(RdppHL(8MyCFdbF%tW+-$!FXs9U)P!UutAgiZ^~KJ&AH*zBpWVaAA&`-B!hom-kxA%IuUBI{MIps zkoQ4leA=)o@2znB0r4@M{2r9Xw|}iR3vO~QFaM!FaY^$BfLtVJq^%=&3N-vf zucODnRp60ifSZr6)-zhbI?UFCgZ_b`#3 zjnQkU#5(C~0H0Hq&MW!YjdpAe#Iqs-p`R4Ny;v?gwk*V>FPmYIx2S=xd^K&pC571uA z=|`d?UkEeamc4o~cLZ%-@xcI|3Qg5{x^e;{(r71ZwfPG57D7pVtq@^A5LU15zlBH^ zn1^GDSj>w&n3L&JwDeh$6lQjP7LyPEjub7;>uotpesic_#{GG;w8^~jssOSn#W?7a z@Ri6z+CBB=X|Y*O9@vQ6JXOs%#}ICWXMAwh(QcXAJwUI>yujS>bC+6b8vRt8ndPT8 zn;M()Ca^{AyfGG;_*--sr@({F8Av{~_p293-vf1}y}UOe*5+d#?4%0r)k(NdNr(Hp zw`_+-)f8_~@r*&qP4M0+)Ol=ys$6a4B@WyhaN9|M?MDyKxtt;?n4hQe8)-gTdK$^^ z1oQdkQVZR#Fkfu0B&JOg=IhK@@^r#{lUWTCcEbGGFKKtFUIFvXW}kCis?GHGQ%g;6 zKefPQ*wpuiIpfJN=Fb-9d!t`4!xlN1PgUcyc}T&0Y7*wP=`gQ_{0rC96c1B@d0!R3 zZa*L9frb{^aiHCuFM)aT(;-`LWow|7XzA83ENIQQqVs&y-vV)4(C+hcI%qfXln&ad z4!wPJzMRI)B)zhrU3qpAw9EX|Qgff5T3~LssqYQiM;VEU|H+Q?$$yc4KsrfHKxO~_~vw&<|9wn0jnprP;7WH6l9%{HbEx+_PSUtJZcF(gger!+0sWG zB`gzY@1;!-OQuLIrSE#TBCXBu_RE_){PK+b;#HN1bxva5#5%>d()Xrifx*)@`TSEM zbyG2Vf+tPDm;~=^f0QEho{L~D-asbNsXiSJgkF>digR)!p1hn3M!(FR*5A4)axdn} zz%^G1X|i7KKu(vdP_pO%)Ubu&_3v{GDlk`_(e4)IL!VbPWcjDye!@Xq1uiWypHGBK z>$)C46z%$U98ap^#l7(Lz_T#xWqyf;%oG~Ljc z&3RUPGauuhIM|?beKjIsk<9W@V2iJ{3+;}(iInK~znPYfqgCDQ$;CAoBT+h5_ zv#+fql#9DuINrY}emBR(M-Ef%z4&rmybsE9>M#krf2kspDPxeENVSY*6SYA-h^=JPvE=1))k|C-DNivf+d-DJ+;^>&kaIWN1L%#&>$-A(3E zeCeFbLv6nQbute{a{GRh*$1I-jd>oJtuZC*x0%dN`;qse=|K=S^vkshT+(UjN!i!U z>#vE{o;1bUfl&_+B&sPUn$E0F-bK)Jp&_`01f<(y-OLiJ!vl4R(_U>@(}^Dk6_#1u z{OxDb1YTN{86k#o!hd*K{`B6Dh&UN*zgB=#hPUrYw0&V=IO{_4{v$jP$DzX< zJ&?CcbY#zrNWW!lJ2TALx2o6p=)^d|%}47GricadRh6;)S?jx6DMNCvvRH;UCc7*a z%*F&WCKo+x-(W840$lxgnXkvfs#th1e~zkZ{%t& zZ_F^9pToGb1^E`{Prt+PbK{SzZerufGM<{pV}WNN(yLk6CfBqNAKh04sVua%6YC#H zX5s|n?_N<9ShAwW=)y(1{wH46BfOq7+@tfS=UJGE9Ti#~8(@oPPXPXj@V=u9!|_pI z3%){GTpxi(8&W;6xiSreYz8a{^990v*m($q6%K^?(YG;=0MSH?s8yJvP9*XAa3GPZ zjkEDQN)E?*#W1EaYZ&#%Gov`4qu&=5-^CuQi5A#j9cq&Mt1({QKQ?D}ZmRr?Cr6_H z{lY_ww)wNnjM?}X=CqQ4D~u86JNJ){^Qksx(6}0d#v79e9-Z?GZQbGp!|YGqZzyFx z`L|F!@4dB*u8mcT(2=)L9|k~=JO0em4SJf%Q?&G2l8MMXwLOwL0`oY&PK9{~^I(2v zvkWAO6uOnxopNcAG1jQFA{d}U!&v-v{#ur#oL?IIRP-~ajxq(QM#t2~2uu!V7m&v(jg#v#qiw7Y3VwT&6V-}_5{k-5$6yR zv$%mcZ?ND#g5j1AFWrlDgwPsm%ukscK1Npqm@}a(0?bwc=5`*cV&}13WhNH>U#~1!!1EitYd7i~0360QOyT!=HF#^#JiEQl@RKa5%Mhx>*HT&hyQNXZ68q z17vbtOuo+j(^TXI`|R(Z4pmq7)+@@^n&`yqdQE^(>2wtnVp`{3QIS+=y{ zFspQq+vYpTL-)=N-Y(QITKk=NUhOKm{b>@R4 z^U=TumvPPq%IMn#YIrcW*^E<2k}(4?SgMqqxQ8@xUe1|si6+^X(C!m?YP1vB-0)|< z)2OCqf}1Jx_`aI4b<){r0_U~b2}~+^{F!yL-eXPLZ00@nKK&V>2@c2I^gPKCBTeN3 zv(%+DmG|1@51g|P`!G+}qmTno^_sH{C}%Whzfj{pfnYg6mGGDX)Ifc^f^X5%-AR4} zpbq(OI-vIBsT)8Yz^FlKb5l_lK%Hloz~*iN_2M(>fSM*W|4gt;0_ry>Bms53O9@c* zHu(bq_4>{LXYvgeP!~3nUV=tNfZ9!sf6W6zML*IA6>osDd?^>0ZW9*7^A@N`)Gsnt zAD-cXrLfLl3T<7M!qfHJE`@be^0AtFbyt5WM0P9lLPhePs(%5jBXmxneg#VqayK+n zp&>HM>Sp#kBhc^!O}JV7f(m9~$H@CoH9bfVqNV>OnTQ;J{~5r}lAcMxR?~6w0N-{Y zyU;=vxN&tFh>sxFBp)^)V4J&H^n%52mFq)MfK{Q5{=keI*q)BOZn8u?(#PjDqO!X~ zWj9i|RE0Abo&U}1kpuNe0vQA?n2B*f&B- zezWk7Q5eaK2QqQC5rs~-2F;kUhEX8kC19V&o4TKqPCFulyo6MajndbKCULmnbpSZ z8IJ5_(5tfOOtxWTMg1Zn^Ux=D-T?h3AM~5MaJI-b7N=62ZId|L{Jtr|dht#gqGgRL zFV@JWNzO~VxVbybR)C*jd;+k?K0{d|lf}-VAYJL-BT`f~94>p!;SiOo*yMb!0jY@2 za)C&Cj%v;>%2+1TxUMPalQ}%^!MD=5=AAs4A7k~1mi~_9_vM;ZQ_by2FWa+BQR2Tg zTgX@q`g}8!eDjkUbcga^JZ)e3T=Of0D)Y8pCCSNgRrUe88+0j=lf(U&wPuJ-{XoL< zcrVZ^ZysR59@s>B5=2Ie>1K7~FQPa;*Ua~4rLfDi{-LgOTJxD2{_>7e(T4&_9pu$> zR0;SARVfcFK@1#O6q#Q3gm@L_Lm(r4*d5O31HH)4s5vcE|7PT59}|lFHV1cU^QUQT zN=PaaI)rG?`LFF>rgPk@O_ty85Zc9fb&JJi*GPXg5>U${M&}1AN3)X-_3^Reh;Y`2 z_S~s|KF7neuKG>kN*ldlcqj2-KEoOiEgeG=Tv^TsW$VkMwISsy%RgBEuaS1o_$!PfFyy^Y&i=8;q_MPxo#ua9uG3{Wk1`?Xx4 z4fpuHr1AAB(U_U;q>jalj#UU#7 zue>BD;Kbc(^ADEi$ekkn{pp;!Gi$OKp3pa!O`Lg#Lxh4JD>uF2+Up$y`3@uvPLh=VJ>E~ANXi2v{nZBg& zCf_zodJt=#SN@XTUtQ_1SIH$k9TPPVEa{6~N=y12|7ES2Xj4CMNoPal%u&CzxO(Yh zq<_is7M4Bv8r@j0weBzJ@%~Iq>@pLpEsc*rsS`Hh-*}4tLPcNS**8oE>pn-@a)jN8 zc>PO;7X=;Qb6B+R`wkoS~*g$d%L|`*2>QIC+}o^`NdPV`Fs@_>lZm)A8z1*wNmXvZb}!({p#xETKU{Uu9{Bg zsMMm~KyK5D_Xh;)KFcigs`_&uZDb&!u!a#8s2uxwI22gY6j(yoAZ)$mfzXrXY;waL zIrdfE3<7Nh>hT!B^(#<+BEPy{`wA)vG@Qm0Woq^>vwLI4F=(AQ=~^=sOJ%TeM)4sE zHEg4GWwuw6o9Yf>zf$CqhmkBGnJQl77ykrDg>8#xB#TFiXfsk&|6JsdVEt#21Cm4> zOL@Tt96>tvRi6roUo|YTLOXmO0}b~AHSSf57u1u*HK>mMl9rT{!Oa70xdDmeI?t3X z#^mf6>3O#X@an-GmDRq}Ca|YFYue(c zgvs4~`SlLJ%-G?Vb9VS8yu&XC=}TF2NGDs7C85lPpw?$}y~2AnB`)oQE359si{N?P z+K%spNO*2W&1z>=yz5FJw%oo7G+f<-hx<{ya+N4Su@Z{6IP|%)rNR|vW+8>mWVUsz zh1=nv%>F`tI`t#mkK0_IqimV>8rf$e?_rf2!0Wol?CT8f`sGU1`pcv!PCT9VA@X*3 z2uJY|9A7dntBO{dzip zIN5;211O$Pfnqlw6g5A!Lu~bji01d1y5Zd9J70k~cA;N9)qG5F+sYwd$SqmD%C8); z_41zFr<2fScUwC!IjE`EY!h@QJ|>f^+NS-OM33-@7H7Mx;N+!k9UN7pwOyLC6}uKz z5|@@un&q85(XCsHrH(_hJki=x`S0qDX$Dn=W$Jby`*%B#yl)uCft};vRz8Ai9?!_O z1fr9rud{=o?}!x{?Z;@27-ZySly>>NQO{Gb?8!E?{Sak|7hL?jMUN)1#B7=1drVE# zdiot&AZaY(4f+TQZB(9zCR@L$D~=PbcCWS~ue10IdZ$(Ow=PwU@3yK7TvbETs(L_G znH4$}PldnwcW2)wb*V6MQg?mZ!&Ueahue~UJBJFL#YFanuG-WtzSPgQQplbID5}EA zUk3r~1us*&TyB+F$^AfFIcW8u<&FD8LP~&2Mp<(PpDrpMrhBjunVvDPT;izF7(RP> z0brNXR#wJ~TOQ4(ltiln)-W5}T}JL3s6U;&+%{GJbj_I+S$h?GxU8P}5*+<{30*Ew z4=UO5gl9}{$6C$pHEM@IR`@N2S=)IOFilz7lg%zHYwoE7Ls+WY*>S!spafD0$z^>K&R`h zGnTu_C;c`kjfeyCoreaNvntjA*I>sZk_O`iPqYa~@;2~edOYTYz@=si>xQ>~d;moM zPrb$Jy#FZ6zy?+fhlsUeR{v92i4)c{Co(o13Ku&kLwRZ4a;{w+6Pb0gtTS)0Ymmrv ziz+#eN}{D6NqF#qRHmaa)br6&O~WQ{=izx{_!yXXnq8WCN2ySOEp(78#EF`OvTa7y zGwTZK{eXn|h@M7E-yoTYoL#o~XZLe&fi}F4*m~Q_7GHJ$*)%lY+{Fu|Vc$Y@qssPt zG${aIbhJ%L06v=}m0$38!0>NWH5x&Ka_>b;=7D^t5sDX_z&k!&u1}9YV#^$>GJo{T zT&WL65AD}7+@$5Qb3OX^b0O(4n>oj=@t0tIag%*Rh!bnX2-_>V-1TxqB%oKz{?nXC(%X@K@g+2#-jGgtTfO) z8?j=0+*UBvpAj>PFDJ_>1J}8OEON`_@-5gs$`rH7Qr$~0aM+D{2y#7(Z8t$i;4s%Y z0Kj7I0OCUQ3@8AHy#*;7=WkmCe-#N?By;k54M)eV4jAtfbL`Bk&D!Gy42U^ykPbWE zt+uFoZ@K1B=yK%sNm6MiNFeJvKX*T~qxngaL8~Rt9Qxij%uxg2REHiv-@!k?z*7FM zxsaTZM+fS)Q87QlA#KO=ckiXHJVIpW{IzV|DqYmPM|hb&he0O0`#Jn|-4C0?-Apyx zGY#aEDe6egaqXP4Ab`j=gy&eg!c{G+P5g4(g)Wo(^fjtt`^k+LEN5758qXt=0qf5q zDE?#Un7U5merMTfd}~y48mF=|(gbS$P*l<%YeCfMq3F9PEpZI^(E3r}M3Lq}@rrfG zI3;sWySye^m95e% zZjlC)tG98T$Sy9k&J*Ru**c)++$YM5b9sx-r@R;$?9{>v(6G=vSjm8^;y45kZK{Z2 zcsv&80z@(ItYF0uf(5VmGDo2|A}NnDe8F%f!(f*YUhzhbV7=l{A{Du!;jEP^T^W0@ zxQ-kZ-q97_r9mo#BycKF|KXdVa6Kbl(S-{(hT9=@VVf9kuSDLch|N-e@yXB{N*oJp z&fxA9@1EjDwH@V__Or^)EIZ>YBAg94nn5@^m;7Jz(do}p^gqN0{F!LMH^v7%y=#2H zzaR3$;sfqK7C3k=G$26%*^PYGagd@nZ4(kuYp~;b7d=pc0ii)a8Z;pGsMiX^HPX!a zk(rK9MrN|%QYIfEP_MM1<2WcB_+9}4U#XQ?^#2zS@HcEF=bLj!%H?VjIFy_^`zzN* zwirLF^ja$8WrdYPkS?A}voAyYh*w1@qKt8|lXKfD;$fr2M$kRj!drgBZMXvESH;G+ zDOz5|s^G=|a0xYzZ=vSM6I~DJyLdE&r&yLq=!?Z4-wW!>+_1-H%nv#9|7< z^AvK!*d`v{`Km97t5>1c0Ded=9-f_)^@nw-5Tfuy!{LpXZdb;R!r={msFUTS##iD; z_yyP;?K=TIH_Y__frGPU-xP&!l)NUNzJeB4jkW^1V$+PyZ_Enh_X_mo|8e<&zPNWO zKp{SBf_-Bzxv;X15e^i~uA2+4>mT&#Y4qJG2r0L(^qC+;z{@-GUukl^?~Rn*Vx1l8 z|A{ZsVfZ4QP9haS{CRPW=u=ZxA~*F$Q(+=ki7&+SCXmZK#zO~eJa3Gi_Jp`bOGl7Q zL>{)RmEDG%hyDn&$A5q@GfRgYDAOwMW$H^s*+73qC9gk6B@f*zu?`_6Y~k4G3n>6O zC4zqsH=pT9#%s)Zi2Ih^r7w{0cwPpVm8F33%qM*?5}MfCVh0!6$X1J6Q#PU3+pNhc zZ@hS;*{_rVmdEacRcb3UJGb2X1^C!%Mk4HC#@J-_(`P$jpbs1Iakt{6{O-XT(8|#F{QL)DA7tl>#p6EzXuxg3ss!l1KE@Mf^5?|Aba{} zTb-qYXsh(+9%MOeehAtdP0?Xu)2*hh+7`bFpXW{7ED)%_u!rbit66S8)C^1Y(&El> zUiM~-JBz44aQ#*E%U-;fSF84}M(&n=t1_EG#xAa7r&w0E^{2S;M4LG0UC$nGW@CBm zJQq1Xv;a^p0+fpd%I44lhIsK(9r$jdFoNKD8#(9A-^H6NqF)E9xc(DeNnkoah%AC+ z>y}UH#ScV4ZZ1E3K}N?V+wH2(|2w!_@dR>@{>|pToxt3vm=iK=v?Wk6qIo*{mQBlc zqX#HhDg&cF{NeN}Fvd7Fq1K#^POrwA-A$kBp8B2uFll_=Gw$^mB{BGnXom z#|bWI1*CYZi?_93Ns?B%5FRbthw$h&WQ7fnb1Om_o72U1X@uS8biof>8Iu-kWsH@S zCwN}Lm8KIiwPW=umR)4qoQvOqFI_)Xr4#dCBeo`YyuTN(L)SDO_-^OFzpc(`(n>QE zrT|^ZX+YP*zTnsV2wTE|a-k@;MwGOC7p0)3`$qY4Wr)mGb*A-Xpc*fjKTJ|3&p*;8 z4#a=^SrG9WNNlw9Ws>Y;R}!GYr%lz+BrenPaxzz0=dfzLV!ohVyv%+Mc{(qRJXPC1 z>~WV`Z8LvFY)=LnSM03I?y)mYNApfmgX{11x29p!e6USc<(kKA3c^-vXYWv-uvMo` zU-u45hvP$M{xnr!$vgFSNbpDOIyAW6YHPS?+xuVAv3TCTdT|pkqNN3Hv=^t1R+RWu zBnC@~r-qjvbJPKoX6_fP)+xVg#ye%Z@$SFKjrZ?gcaAsjR(8E+_Ft33`tLz@?8#x3 zcQdT+10`&?I#;9SUt^YCY6m*&FAQ`if1nj=ay$?1zqbR;S@4uak`?@PK@wAzjwHWC z{a`mAK9byx{sSbr@CYACKC7d_)W0---~tRy`6Hf-8zBXFF1En}PJb-P0`NKAk_@^L zXt*8>uUjU1k4Bu`sc)h1PRKWd(bRATU*9st4W{RMXXQ&d#xiL&zdgqW8X{QEovT8B z#h^}>zLEQ4lN|F5E$0wLD-`hs$6O+M-XMzjHbp-7>CK%cy57z}WP|R4f!=VsedgQY z5uZDH^N?tl6D1)(=DSd8^UU@T8V*d5L6 zHeqo-L~vMRHlP}VI@rh)vzbg$hm8yx>VUamT1o0;kG;S(UNGWGO)_4^{epH@C)^^S zJtSR^Jr~=Hk9V4Xqc#w|ILuD!on~Lmyey7_uUGh`|8-1S>FL{)zQvWEm@NGUiVhzm z((oZ1t4)u`vdEwu0yj1>kvdZAiwGl_SgVn3Xkt|CT8H|+!PVv72ShKKTK1SG(myhE zUTv^(CTnj-@l;vMYA45L&f!fX8Rzr602RdyAxd+oE)&eTGFKs`kekdWV2#&`*5RfV zv8wvm% z8D`C=Zn4+1*acwZ%y_&`UrxM3UpAWy>=)vn*_s*o;1lPD!T-#O?;ekP1vXFE;v_gdN zL%cvu2^4ZD3Jr-wa(60QE+&tb3hBt|(AJv$&vas!Y@bd=fxn8%2H)GNi}}jE&!vqi z;q&DA!vDsznc*ke>b@Kj>9ZdWds+mRIGYHkMjBe_!_CiCD+m`Tx+UtwED zZEF8yL3Y`#fb3n!i6;MF`Y@FIuAblXXzRI2@8{Zj8c8NC`;+v##MQHh z>iLUb&(HOtg9j}8)uf>zhuELItMn!Q7u)m^zoW=yevvu)u#|^RtaJEwpmert&9c+2 zI6XlAfVLHKUXmIj zhV;B^^t$Sgw!ce$OMh2fWO&Zm%Y`J;tkV0Fc`&W?I9eJe36gvUlKATZ*(I`Ra!jk>b?0}!kdLN%A%pc& zPPcN*tZFhB+@`l})`4!J8A%??nklVqu zoPAnyT2{GeY)nhuSC3P6I;_cgvn3Crp!{Hd@@nRh&q+j>F!D!&Xvgs!7%Dx4NwN6_jzki-#LS4<8}Ys;Nn z5t#Lq{^Nw3Pt7K|?N2(iL*1SKvAg6h# zR!v9KxH-8o#Z_Vp;$Nm|+{@0KDy8WXzhWr&P+M>I5PCGJFzlkGWtiU>VX-%Jn0BTo zyPauJJJbF)-u7zKxG(i}YBwi@zt840ajx)S0>}Q)fBBo!!nC#UJ=8W$f0V%ZH!5Uv z`W3ZRfPCyuQzEOsJG}zF#n#RdH3d$_eW0YEyPR-2Jg^)W%~<-YxUipfcNJRc2}awhFvdW{EDPp6}$|0dZf zZ;|o$yl`@oGM!~JH7b)YZ%xwc+}~J8WC{{9e(oUgbA4FJ1HuUP9LS@sr&#ZIxAhc~ zOv+pDE#Y<30$a~rH&D-Eem$S)!__<>Z*3yYs#sxv@_MVLy?8 zYP>nYro5YT)q7E6|2&*+xl@ncy>N1D77!oGPKj|(nNK=;j+^*LAEFD-@E{LB5YpZv za)z7<($+!q`0ds~H5HwuvM+7$*Fm8EZeZZx{3!#o`17tt_yW~OOE(I}zA*ccUe^gy z@x1oy>CPu-yY4)u4@wDa#--0oz7*8}bkhTr8U1RKJQb^# zH?fGEU0{mI-Afp{+BAi2&l|$frb^Ea3el!E>^;7Yv4lrFE@JG0x7kHO-0VxSVP9HU z8NYZ6Az2Bel#megZpsLbjI${)cMkxkOYW!dTN#_4GIC*g3?UT~Fwb%YWViP^F2a@@ zj;=)%ve(#e>c~U;zuVH?)O=vnCPbV}bJecEDMs5=6`NjI6+ae{;omZ{6<XcZ2RF0c(C@yg#qIrGU6bnovFm&|Z*W1DU)!C5 zcIxz8M(<`#LU;(b3%|ZmRziP^?`!u?=YBe_nDGPLo~T(po{qwr)eN(iWWr(Z<|b7n zy5Y{)TRxR0$n8k$x6Nq3#Cdm(X=ks(VB%KpKB=gyDD5>k56aZGnQh2?3Bse2*m9!i^CDB4jT_O5q(s_y~1?3U=r`I(Vi!R#*sI+ueq{nG`h z$SoL(Vv}xDhAdVDjsxo|T|<@LT+LDE#TF~xVUDhMbA&hBdLA?%+-$)l^A>5-#Zrit2)!gB-J@*&7tM+kM8Dd z(-J#pGnuoL2^^D@Zvy{u-{g8r%^4OZF|CyKdB-O3-ypLy&)?f5h4WmxgY}v0D~SJM zD|05PcVSf9nxwcxU|5py$yv?@Z1vb5Bmea>SM3LXLXyA`g>6d4sIa`l;srbHX~oey z%}s9OQZO-DWQ>Z~>`d%C14R(o>Z=Ay_jaXM@8Op|h0-bZxBY&v%9qU?i{s|UeKDXS` zU*8+Pb$x4*n1d*4*SDpK-Ys^yd?(VFzP_LOQEGj6V*~zmxm|XGWS*szeIu>0N!>xP znL7}=hu}32q(RU(0OMrp8-O3oORhF&0PY5YJ2n6h8J`Bd?|cV>0`YWNZJXj+ZLhKi z3Ht`%S+Kb@F~b^ww_k0Y*q^5F^5uph0(7~?3$gai}+uoWO&%T*` zkqbuV2Xd?QKCM{sehcckY5b-&0h5583+vMKoIM z34i`ztLqevjykyu4iQ!R!XTn*IGti^E8#@eZsgUC%z?junDyHf-Zb$x&A}s5m~!s8 z6so|z9`fus9#u>-bU3WF(fW8;?w#)8u{7ulvq3fw<-1U^oieE+#``liQF8edZ7!xJ zHy8F*Et`w_;yQ}3znIUDBbX;+8NcB^f6{72GOO+W;xU_5i@q>*KhSEkbf+%Uca!t{ z{vMl+A(d_hr*_$FOiZJn-ERiB+ibia(+vIxQAWaTlg7hlqZVC58qe)!vjI09yHJC_ zu9zRr|LkKKsP6{0$m%EHp!N2v+z*0gwvM)hJBMCdg7k(7^9QOdTBkAC@r zBo8eiD%sG_96M_y40tTEpzLu?6FQcK!Ny3Vjz|af-zfbzF+BY5ViGk+dU?+-N^{5X zJ#F{m^yf>J@zObW5@1aCJMbI0egJ~EjUL<4+Z?$QW0ji+{#e6MjXa_1GHQCF0v_41 zi>w%->mfC|eS4%(O8Zr^mML;hIFmP(qD1_TS2=!9Rt}Ym_XGLRtX#pFfHU*$4Je%Q zMDEBpqwWWn<6MH#X^?C54RQ_m9cpz^qn;vB4HQeD(lkO?m3>2syU#4_ZH0 z$gv#tSYQdR6lIOp_Ey$>ZIsSu#3GAVg&y3Mlw{GRu}MvCLRy%PHslNIl-?X_0dNt+ zstIk1MZl`_8u1q;@^R8vG!dA-Cq}Y1JXM^pXp70jKHpqk+LF;RG5mx8$G_Q#se!o- zfKTG6HNN2$ivBju`1YYyH|?A$`roEHX&KK{TQAzCCFoU}vj@8_#XDR;I*2NgQ)O- zb`JftfvV&jx^axU=Yl)e!S}T8g{9x31Ue56gv6Y8@n29?E`=OLOV1{W3clql4i~bD z9$4sWknbj8ZnjzeKr*R8o~GAF*9ph-?z|Ejaz9i^RbHhJTSSuL1;>-Niy=bj+WBVr zzcjZJ&GSV=rkLaBP#)LM&)VDvk2BJ(ruG_5DjBAlS8{9;o9;hJQG1^mG&RO=>OQvJ zW*!fAp||ft*VAPirBnQAJNmRJ7raE>wGL?c_Po{`eG=6m*}u|j=fc8rh=e^aJsN0x1yWs`c({3lV5ciD=FJgLvCwo}UF6^p4#0%XwSiK=C)=KmXBQyzEer z1reS`bC)tdn#)TVVhQkeu>Po(DfnzCgXSg?+HCz~hg`|qdFm4A^te+I*F_^g&H=2xPgZM9a)Q3cOz|Z$MfuWrKR{E5* zLX>noJK>t*lX*SSk-i^ySw+DXk619;#ELqNer^mMN;)QPU|E@hY_B z6ULj?RUiavadlS&^=Fo#K4j&jG=GMr8C~e<%?p(MyOGpVZ4eF^t-jx^4y9AoDQR=_ zJ*etC)U(F4jk457G~=#JM)5y8INYde#o}jCbJ&ZEB1pLU5&Tp{R%GK_h-?OYM-*`) zlVwhVP)AEENkU|ML#Z6XUaDbYO7tA3oQd(s0d`8^t!)JYN zhRah*lAdvu==WwF&mYd_Com7TrCJZ*!HlyF7m=iI?{3wH>x%0%^260OjPUn@ z+3!^NL_M^hLr;=?)6Ta%eGBC!m+qhK?#s-ubSLL_ymqbUOK1=gGR(ETEOoToHTGto zIp2F^V@utAEwxVhcB-in?ow)MWd7wmJ2f><_!0unJzVRn)%A^<~uru3amRYwxG)l}2#7 zX9fa97iKUM@nem-@MspuwbbJa{H_;&v<52L6s!7?_->Z~l(skbj@A_UeMzq1AJC6a zuU0?au#yL20nQh@GWOPt$ew5hvjI)}+dUYjUh#rtMoljgOrG`fd4@Lv<{u6NnEM7A z9`T>wAFB6mIOjY8>aimlW)D8-0^bo^2r$C1C|D2>3kbbk)ILP*NbU}8;NlIP%TC=7 zg1)gWP+w)?bZ%xCU+5KEa>CwvdjV<__hta7z_oYKCt|J04Q<879JLsfaXIVLuQ47Q zdzd@kCo3Gkj73Hpd=IlvoC~A99-O&_zuTk@8D{37)RYw?>`mH$i(kcvt&#IFUj!|@<=c4d)lAWyg7Lmgqx zJaea2#fYaW1EV)p$<(gP@Y>5*;zOU-LENA_b@#pMr(EReRKH=fmFe*gZGU@)36{hk z{pAR2Pj`e>Z^osp`^~-R-W7Cs6&>ChVTUqlgRK-x_azLW=0|S)BD$M5BNzB1!@4tx z$&-a=TNAg>gS(ixci;^;nGFD<_G)v2#JAYR8!A@3nNyYZ-^$o|Ob0Vsk@b&oEc5~Q zfB)~ezok~V|MpSr#6zEhT-aUg8NoYEV7cgk2E?e(bO&}e2xp1k;g4C+{)RDkYt}zj z6-=i+(I_TFyJ3d)eXS+i5t9--kbP9KufKgF=!6SV*>vHeqKgH;vb zzv;9WZv-U1{%z~EKAEmBZsM)A-{&Cs&5iOT|KsdKn>uhU^)KriShxHdec*&D9gt4$ z)O@Y>hp&Yc_?dRBmfQEhbhVtM-~SJ_+?T(zb6SHrAGO?R+oD!2k6V2meMsu#uIOz!xv!5a+(|;fHu|`s zKN3$b_++b!Ngp>0!E}3kD3d+QNpIjp8$PNjz3U`Pxnq*NFlAN7qxnoa7OhCHN5m&O z4(8(Xg(PI7&Vrys7x)kM7IeEQz*=45Whj71;N~amxnzAO>P-5rA{NPOwY(TJ1WN}t z#oEEAPb`ICb_WT+xO9XGJheW_Y6uOu+o~X!&eAMFn=Ln3m7zyDh>d6Oc(T*?=1-GB z7v-RLVLqx}xBX&YDop?zu=?UU$_NL`8)xY4V^$Kf+F$j&oEHoE#VAm#dt`=>o-%zG zJ8ZcOndhw!A$R52i)5x&def#>W=*RVkLq%fOm))kFp;`U;Ss8EY&G|raFNVdO8a() zYAnVW9gbQxD%;y?xNvA^WY$v>=9&e~GK&X%GvX#~W&=%E3WFaSHGAVZ@4(M7`fCMtoF zfdUtnU`6O+_mu@9?EOjz7;bouST5e2g-Q$GkTT|^@J$bzHLl=MQg~W1JeVIDUEu`_ z!6jsypsb0s1kdKV=PFT9Jq}KL3`g%$TbYra!>epdJY;kYw~^kTeZ+_DJvgyBwvUKD z;4NW|Y++Zh(z6Sw(pym_Tkt2;$dDG=AAbPPFrW$?KL#d;!K|$dK7DJn+-%<2`fItLqk394d^s#JN`-%qs26`0P7%7zE~L`Ii+!Q3G$N;44q zW*@=1ju&%njT(4%c`R(7n)H-a9%H+yb05@V-<0zvu;j^=w$!1|rOGAYsTV7BVOh^r znF464boxtGaA=bc$8PTzo8bNtvFBUwiwd@k#h!UbT95ya z%i@NWYcjXHUu<7qvj^*XSzJF}c6YznC!Ik2;aTaG6@}v` z6j`I}iXx7y<{EZTOxd_1+nA|WIgfEswH2c8JF&BBGueKXhB+PT$^N_;j;-}WE-X}6U`{Jn%0fD))(>XDnQL(#Sop}TakcxC2FRHM|>HW`=U7MinrOywwg2E61Blp zRgTyZ3)K-Um;24I`k}+-1wv1iBKxYUVOXvf^2g27F7sk`YBk(=jY4*{S(%_BHf1)0 zzl(d52LimHI**0sd-OkE_ED5OKIZlUTG1^%1NAPkOJp}Yk3wQ=j{G1(DowmKS zzS{grbXNm#J1iR%Z9?Pr+e+WDsLQr8Fjrat)soL9LcZLoNpO=BvP7M}{~vMR0v}~@ z^*y`U-E215Yyt@+$YsHx0Rh(#HQZza32rn<#GpY@H;_Q0A*^A;MNxwZm1K!cEw*6Q zMoWFM^|jF#TcEZk5V;6SK&rt@jf(YIV>S9x1#kKOXJ($uCc)}gzu&jNooD9EoH=u5 z=FH5Q+w;V6-o;C@!_bm@sTelA!eb-&VFYUoy6Uh>0;+<^bF}vho(_LMPUV_V1gEQp z^gC%@j{Dqbw}+I%2?O$8Psu@WeYNHILWc$Kjzu-hO`yf(motdJhtdKh{p;JQ5g1=! z3jIF+9)vXFeE>_o#iS2AXU)7e;nk{mXc49{`P0uhN~^LC%RyNGOHNVaTu5;UAN>sq zr{inj^X)efLHr&%1=g7Sv>Jap#aC|mgyxm%@87i7hjAcGYp?Ip*T&FaDMRl=dqpF` zNP+gc7270m*p-4t(O%CWD5Aac(D?|>$I9vVZLjx#O$A~UmAug1Xs&nnX|0Eln%Y{Q zdY7u=yIN~rXf+xuX!LEXw5dFj-e165YcdiywpN5z%hq~1Z>%^)Pe_G| z^~&@3?IsB9y0jcC?)|HNQ{ji!xR4{v1%SS)_DpopT6@M?JsbU#JuhTQLo>!L2((~> zbU$p6?smT@Gh$gCndI|I-tJFrydy=B>2>!zFbN&WupOg3)_g(GtPjD{P1itVQRBv>fKcXu0; zCt{z1q}!`pfQ3(W3;+j*@wz%b2GBA)5d6xAb}psA|478}D;HlX#59c2Q_%R}iwGJU z`_Xt@&{(F?_!LVaG!*?-qwyO-<61lInaHG9h-e-y+HOSCM4LMz<)?)gf%W_h5Vp~NJ>(aQCMx^rTHorFiBJVK!n(p_u+y1bCO3o}*T; zz3}LMghw3=G&lyTz-Eeu3hWp!Dv)x8HIj%5 zeDZeSpng2cEm+;;73k)4WB;X9pob6&lyT9#0zdpv#3)dLShJzRFVkq87fEA3e>DXb z6rr998t>B)smA2TH5wjCBTb|6E;eL96)$tuqdg^}tvM;H0jzf2E@U_5e)DTsf^_8~ipNJ}wQ9gmj%L(nH z1xZjeb}?SQl&MV9(`X`kl6 z4)TdvvdV7wcVB9m{KIGDR73czk++wK`PGwYtu(7!|B;uAxb?$I*?2a1co~0*cWUuD z?}i%iN5>I1F5|}$_!na_C%dQw*{tWG`!;L@4g?biW_eBCiPzjv6&Hkt^zNx2vi{3c zpy_HXvQf#1gCVq}p2s&_8z}+9p6jH6UM!M|Ggtl2;Mi`4SShF6oImRp4Cq)#=BH`) zalSwm`ehH!jgbTU8g6>caN`55NKiTPDQ_{nypQx=lM+scOeyaHS+8CX7Mn3y%i?qn zAc$(v#gBoBvLQ-THis)j*>n&r-n=jqsbiYOPl};d58@>gge~=Mj4xiOUE&%kmBk!U z798aVA4dA-Mk1voQ>6fyvU*%PMn6K{tjoPcES>Y&+-8A zbs9N5Eb!AT_7TWY{uCa8Rv@Ca_jjnN7x2`-z%e-L-v0*S;~qB3FE)=uHwK_yR%c+r z=-1^4YaDSLvV(7-S(5My%uZ5!>ODvTFLkExN6z&tacNW}H{z{wpv5rXf#>Ix@I?z+j2Mw$YUkdN)44kG);or+d;f*GqY5!9%FZ4(#uYZB# z@N1l1q!r4w)V6+8dpgl|@0V0ITR=E!`!~IzP4`T{!Ho6L7kl3!vQ*Jnv~cHREx?Pp zpkF7O&dEMPWNSbc8zpWuca#Rw?}v=Om@g7shzcW`qy%M!eTbKXceT5_4+<+gKQsr2 z$9-5*KNu{@3t{=dcuxnb>$qA$TM=;C`Q=3m-N3U{XMK0_UYUH?8KdkTBz7rJvY>PQ zRGcGfvSwoCw|_B)w*o)1->O-x_gh-OfJNanP*pi ziBoJ`M~n&%t36|S*|4{&GjYbnv^6N$UHqo2qFL{fO@qiM?A4!x_so zrI$KTz6k%NuO20agUXzZ1h9b@E&FO`Vjt;zwC23peJOPIBQ@g7Q*-HSV(9rskHYs6 z=yN00(Ubof-VK^_L#3X)-gbOs-7~lGPAm!IjulSU&`F_8Dr3^6_&_mO3>2?Y$Q4uh zII+sN^S<}8=pU6g<#M~Lu9-7=DQ(E&q7`i+$c6DwF_VE(O^c(Lui(tG&#k;b>wEPp zygt0gzkW3q%vUEY#fvUze=*B74xJf4JqWFdQcO=JUeJ4E=ODj+i8n9wk+1&3ybw+c zKg`d|>2svze58CREd`|^Pa+y6R+)iaboyXQ;|h`;dd=on;G`+9QOr}aqVAuW+B1V(8~zLj zpCQB`6y?jS*0tev?%hFr7brI+QUjtb8qw0o??d=uMo3FUcQ;c^EEeyNi*qK(}i_0VHB-|9kjg+4?b;Lc*3d3MTny0X}qJJ#bcNBvrCh^+h8CVfx zcP|Le4s~G1ZsPh6N%n)uwO?AQ=b@&XI6>>)n@p^G72tIOeum(sfXf8@D8bhPE)no% zg6D)f)_;gIH7q!(_DfSRwfDe`Zvd@c4?Lg1TS0gu0cQ&MCW7&vqhz;$=K}UE!7CN9 zN8e@jEt!yz?fUER0~_AB3rn$T0bw>W`B-oAjVL8w?~zd9bLq8T_6B2k&I{n#duYQO zcfUWYhSv05b=|bl@lQ+k^I(Mq$JhST6dYdrPirt9uIjY?bCPJuta}t3C{@-y1P+YN ztlJ3(ly=sQg8+9WiPxtN+r^Kd;tg2n?x?lp4I|mZs18KPlGoTl9@h8sLU~@L3irjZ zpNHux?JG9pX1yAYX)T6BGgUvStI4?Sf%9e67xUL811Io{J)@Nq-rHglHd?50yv_DeB2%&ps+RgfNKjAhzPXfzYrOc*CFBxn zMsM<0SHV$_?cx2i!3x|^&~YetFrNmhF}cRln>>@E*WQ6ol{&$KJ~pF87Jx(Ctg-N~ zVb&8EIdb#wskk9|JHP3rlt0DSV)>vsqXvntOia5Q_hGV>>KICawzerl9@>Jaz?*RX zsCaAMpV`)J^VYmnGlO_vc~Q-KqiPPdZd`;|Gbt90!1Qt)H1?O3iR8ms&^OCz58hYv z-ptVHnnN{hpTt38Ol+mYTl0a-TXUqV+uf!NN{f!`;f#EQG!QaVkgYjV1FH0<>@4LN zl^i8TNmE*Fs)v^PAIOJyIel0VV;;-1Q{mRT$hkSek%8Sd{`Hk3&&5we1(__kyI*pGdUIr80_JKY2 zbmP4&t+#hZFIvIs!I-?J?54_4{75nUA*uo4=@{8iX(|yk#+qwQLh9$r%JM1pl=u0X^(scX*TTQ)^lbaU5&PBp{Zzx<7D|pr)R&Z1oDjW0 z3AIzeUl^Samm4CN9(lxo#7}G$)UHhe1?vUZqqk}tkx3R-=v=v-%0|AXa0E5wQPyeh zi`|N%Nl~8SR7w8OR`^Md0nZchUH;zQ=vyK;C3yEcQ}kDO4s@odnbR2P zOwmseqMs?ci{t&LXNvA}g5w`_rl{yjnoW+`PiKnOVHHX59YlZbUO?x0@?Dl#>9q=mWqKsh!;13|)p<0X8G|;^ zJ(FB(zJlvwa{ZOBFbwA32Xgq9(u5uf z!{P~^)5-tDY?5-DAG$INhY71);uDp(JdJK_c0%_J`Em@+<6~&;JFdLYF<;w<7)d+i zFxuhzW2Q;Gg=lsb20UNrg`g#`aTbmp&GtaufI^8vNfiXWHQzd_ZN0PO>TgZ()qY~C zzE@_BXOkGCLEdl_iB}`_AMPAX-BM`k38fjwtBlLdP&f0IAYn|5PvEdsP~M$2`|7K3 zR{=*|k$3OL3@i}Qq5{jMF9S@b<|pozOhlpO;FSP>kxl$=Vz>z5cvVvuJ{gygA6ktm z?dL1U&}DIc0U~sS-gQWGDOb+Mw2SuTU`HW*gyaXWdAX+*V)_i!HoQDh_{Qcn;so!sPP_xL6SZnmR_&qouh9D!>7W;; zGPIOI$a+WV!;){Y$WML zl92ekbi9kp#Tx+4l8zDw7?~}RCwjU5NX-frw=NCy8SF&!Z(zESUw*_)o8YOO+SAC&v}Fn&)S1%EQeN)qJL|9^OhCbJ4?#W|AwL39bDYTL(_Rp=D4D z(OZY>-k)-L=%lt!pU23rpNX}hgl?QSdrkQRD5xIjMDdo>xx67>j&C7iNgOG@qJ;Pg z({)&`HhwCwUqY+L%Vzj1Y%{3e0;KL58WhTit5GO*4}EGE`#Oe3g}K}0gT2Wsa;Qb6 zzG!GsT)&b_3FsQ-xl`&5L$eC%F|TQ}^VzV8blq%piQ*&T8%?f6%#P~OZSTi?1Nq-L zJ3TZQr{YJ}en{gT9!Z#xR*%5?Mv8LDXVf2Emqj`tve|fLx^gbOny8AvKiV>_7(ih9 z$qVnljU6`5U!K6`U<)sD>r3xBU5yMyAM9e6` zkE;$}fE5mUQ!jBi4jj5R=%3=+U@1X5w%6e^n_O!r1J6 zmhObey*GuYSC3V-n++L#o8c}!sWD+V~r0~3+g6kd&dGlc} zVxiFWlWyu&`sQOCr6envwpb7PcuwXX**SVN@`gIYYc|?Yq|Z~4=7kO_mt&I-`v6*r z4t@E@DbZhhsYDyWJ(cK1f)A}kWuB)}9{By?h&+>^518jKr~&lN^Tm{sADtV zbbs#iqtQI{%wB(PWM;=>07parkHzPinUvXPuuYlGfpTCJAD-D&SNF?k)xbMS{W4g{ zsm}uS?l_z>hwL9xx{gt=g&u0|C|Y+q$_K=U()hCZ`gZDpj7v{STRZwyG(`R`-Nw1S zO3zGa;rM>gizrZnHw{7#ddH5#f=BPzz5Mwsf8NcXyQY!+3y40|YkBTZ5^-3-D?#jDy%7ri*W(WH<8Pd#w94 zOmf_`LYGBL^Ozy%W1iRv!5n}m)5GrAD(i`6bkpuXk_vTisxW z-g=LLD*)1b5t0V4Fx~?}6G)U^x)L47OKo&1biJ`2YF8njz1vFn?UN?A_V`>+I~QRM zw)$hfkeH5j#O^QDxQB4I2f2z?#>7A-Q zpfV8xjMb?JTESB~&4oB0`>`2@#Z8JdNZBobXys`*x<4|+SAGp2B1|~=+AI=f2d_p$a&3-H?f|?LMN)1;WXFkTa>wi zqjVg`NCQ{<5UR`s4`7D4e3{@2IUJmXQk_g)($BELgI9(1qFb^)00dvX^$}PEk`3^` zVC}QshNp=$fa&TkIxnVtjymRbg{fNG&bin_UpmG5^iRI&#mjk?I8VZXe&kWIqF!7- zr68BF>YI1QQolbXJEgiX|AIZPKV6-K?i~9!M_qr)#)+-Cn*7GN7k%|fX?fF*22(;; z#N|(Gt8#>9*`qLVY^}n?Zclpm+o-P%$GBu9)!v@Q?j#v;Kn`uN&0H)~_KGrUIKkgb zH~AQ9Dz@&8>S*7+$&V~lI}x=Ue-0nka3W}_J60X1T!oGDhC|Bbu+$7grexnzJEIcF z=mSnvM=PhWYC~NOPPI6T;H|s{4@%4D%6WxvK#Ivdmlv7__`c{or}c|YOl`QNOPc6p z8l441Hu?68Q5}uW*#P!KD?nF}e6#RMhZkbGZ}9bwT?8*<+$0|NGWdq9B{*RM3MP1k zlA|b~wca`pp7l|@MHhi+Hvi%uUGxlDGZ8eq-eT%a{v5{&5%YPh1gHu9FTC`;b3V5t zxHtJ20&1tR>aqKykgeYCTvFW|lS2s1hBSf98jiOcc-^noPU{W+T}wUWtROW05jDEs z8nU)r4!GVzLYjvlHT6z@Li+Q1=3JRF*L~Rig?<>65r(fi4BCVdWWp z4EF3TN*O5OxKY~D&pSD(MHtbc#bH_cf;2VF3x(QOG!zrY>9YSUg{+rfk|-9JEo{=cWS{v5NLDKu?Jr^gV? z9fA(M{FL2aqVlXt2$t)Qt-MTW-cOwrItn%yD@PBsaWDmiF8ftE&v&a^xS!FhCJ!p( zu_8#D3GK(JN zctDWuzmzOzEi9#(cWc$-l&u2Yjqt@H{2U6u9pU?}&n+-9^eqfuJwfCB7QE2sA7?6= zL=am+wOI@c02qv}uICTrh>AuRQQ_p;5-;Z8#IM{tWRqwBGF$k-aEB9DwaTP;Xs>0Ogmc8(uQ*+8GXF zy8063_sE$t-wu)o@z`(uq>#!7ebON%6YNet=508lTm_fwkDba>Ko0Hg{*B-vKsiMOxKj;Qy_hJ^yJp?`=F2gbIb)-d!cA;p{+a`wi=5} z-S*z(E!3NIVj%Twc*9lq6p&G1q1WgH!*8(&j3BHoLOkkzZVb8}i)8$%YhzW5Ml*a}C^L zEktnEoBS@i48e7`ZSot$y_l@8K_z%elj2*0XwB+fjyxPZr@1#x`>jeh1~wdmL5CiK zQ1H>8DjwbL&Ea239jVb;O^NT%h8_dEJ{xZiv(5+G&=fI0llqH~PD{9zm#I%_O#b=v z2<9F$sDXy>rl*h_R2A<15<|GWQTtH>wyY1j9$WuuWw5kj{b%KsrFpSOLkbti_5XW$ zX=QcnD~-Nh*JGhG)i;fWvhMQjw|3AJpoW;Tz62-I?48kSGqGU$48P6Hf}>{y$QovC zIrB9t+`T%@w~Lw}37OCJo3@onIU(zNSd~EEjo0p3JK^k(hTjo5(6eWUKFtjs%?+KX z{U&;yH@h)Ans^L-mJ>SU+WlV4%2>oRBVIGmAy4a^JCQ%u==;+3SWf8J&NKkilyy8( zP6(G+tb@U&ueR&k{Z=Pj#KwMWG+fkxp>mwc#^HtCA0(|D1*A{*TNS`E=mebmt#9Co z?ThW8MRPZThP!INCW1H{>Q1vw#}&qZ0t{InMeJv~Y7f}= zTknID#@Tx7Cb+UcZ*vD1*B)^1w^jp$Fd$$hT)P;H>Hyz2z@2mML2&gA*qlqyw1d@` z@)XAGnYxFrds;7ncdc_8o@n}AZ|t{@gOj*LlwojoM*}Gl4%hB~3|$%LbM5Xy{absz zV8FHe-N7rb(CN+04jsyd2)Bh3#`fan1GVqi>a7=J8`rn~;5ckh`o6#`51j3Y>Z^DD z1=e)as#ss`JI@1rN)k+7iBr8O0wmNmcx4Q%i|1+w1bDAn2XpK_!^%~^P*3pH=m%WLML_&MQCsGw>TC^+J5NJOXGG? z;VP{VNa$>Mw`KOu4)j+FtzHq>oBSw{aXMN7ny>MJPVx^O!s<(J@=qxQbY|k1C-=ws zL<+{PMi#KqP7lz=h=<diHr`i28MInwCsH&9B%3-`?4xrGw0 zZAFj3Pu(kj0K>kJh=Cr?kJJj1F{;4keR6MdG-!r8N!>w^4>(?5V=j`!b?4sXFE2oJ zG<0uo@&|CD|8ruJ5wth@qLkgd)5A**QCM_L4%Ur(RlO1$IpFut6g_mPH~DvP^d>*Y z!2`QvEUc9}A=3R?$d5LJ&{<^365j+rlvMOCY9ud>!@&9CJd89?P~K4US&*)$QF+8M zIy1_wHJjj&^+B@gt+7BSOfTFnchP^5uw$Q%=3+bx+Y? zK$B_;Nx_kUk7(#dX=D=9f6jR9?TK5dl&9^jUJY@=`f)Dr>mg5^uiOM*eJ*5o1|XcL zy@=f7gqzNfb2yRUT&x;H8r!>#1SZ(1r?lYC5<;+br;X z(E;#n0--`cR=_4sFqxqD)z0`}4hjcbi^==Z5AX&HBxuAa+K15%LsI^T0E{t>&PKpt zszVG^KZ6_XMcSaJd_Y4~tvyZohj5rxI@W5Ai!zcc?2RJ^mlBZ~aj?1vL2II#01Fip z;a$7ej$7$f*yf{glZH$&*7Dgm4nKTQ!sB+qGRF0sB`#^a>aTa~V$?_P*b@F+%AY&= z^A`TB;Ll3_4De?ae+K#UF8<8oPl3M~O}KaL7x{Ase+vAK z+|AqPSZbfWV+H*hxK)0It?TQ(U6CRE!pDvWM>>wLv4I3SocVjP>EY#j`Pjt|<+^LT zOel0`ZK?ZPtnn2nO~1ng8>J2L(0+*Tq4*^@6H1s|(M0}Z_yAaYRKY}0Hw+gr7N{U8* zH}yNbns4l;Rw}C*?~p~0zXfYbEwg9rybZ`cDI z^s!SY+@gm+LE-D$YA72{Nk&T)_<4kX{BcP?)DR%VLRo*P-!%m1=&+yQOdT#FIIVAe z_v;^ulmODu1V?h9$%j^c)Sr9q885S@6f~7Q1~_-7U2?K%g^pEpz&->RE+W_+xKyNbDa3= zho7ZSxC%>t>vY&n@k^>SdVYd)G}xI4wLZKKor0(@=WS5U z!WBB4Nbn*Zew5&R9WEz$x(18>B2%L;Hda z@LJ;cum(4HsDIx48?F2j2(HuN9?I{w+qC?55WHE3TL`YxU}rt0SE1AQQ+SCMF2;*O z9d=WAjs`o!#Qy|6{%HzN)504%2~N^sUcVL{-a_H00vf+-2tKL9MFbz$;VgpNHQ2e8 z(tk3nmR~~=mB%(MydjI1mky`!^3q`Er#%09d>_%zd`vB0=g*)Thx7ID0L4$z!sU3W z(G&HPro+5`k~G+P5vBJv8mX-BJc2*c;a$@Jzp29~DE-44+#u@n(MbND)WV%Hg#VBZ zuZI>L-lW5M1h3QKM1m_cSk!l#svk8rK>SdjT6ztBo_`(gAlRbAJp`X>R{3jaBKV{Z zw-9_>hZ8V$3%5&H@1Lj}@r4>mI+W|*Q@bd&KTbO==7E?$7}d{_;wLamg3OD zL63aGg@4rKubJR9dFTe=#6dVo5BCrpJgDW57!4=k5QnHw(SNqTB4JIRO9^-V8sm`$ zd&3ovf2;)aQWVhxa6tjFO=)i^h?jT5&GCpoE=m<_(*&U^tXiC zQV+h)fwfN*%nV{l)wPJeTHYtyM1HjRs(x0c{N)|BatJ@v;756IeXa&&sKf4XYXqDX zZi#>k!U=}_*S4jEYpmEbl=@W=Zpn|2%KOwO8qDjX?qdyhQ+QB^2_L$214@DC$4lXx zukMqdP%iXYnqQf8H`o? zn+7k!!)Zsg@}eAuGj)BlmD*<}ZY~gI1AmY&sc(8B_5Gqq{<1{+*Q@Ch96sgH(k~$T z+dBG{f1mkXmeNG!WfVp#&&CGMZ=q~|XXnqWmEX=(L;0aUBmTtv>SKiTDL)Y&F4X0R z$~&B+!ybau^!)Jt@c0o~o>Jek$Z(Cn-8AfQ{jBlthW4U|yNNAQLzf%Fp)apZMgP3* zS89LbtS5N04sRv6PKTc$IH<$B2rkj#g9I1q@Ckx*bT~|KrVgJWI8BG?JE`F$9Zn_K zqQm0|KJ}o+?-YVh>Tn*x$8~ri!RW|A;nhtaMO44C2 zUltwa@^xy97N5)4Ngd|$bzFzJe6{Ov46lD3PUZEl!{d1U>+lp_|2mvUa8QRA5?rFg z(ua0wgazf6p8&^OBX_=;wzy!4Cy`bI11 zgF6r)%cq&(Z92@u+vU52Q9c1`&pR~Oxt`L0=q!aERG_kIEMHCI-JV;e;po2aFPyBA=skB zc?6%@tnt5);FCIBPVjLZUQ2Mh4%ZXBLx;B#yiJFnAb7J5uP6C@@(rzgyQsW_T6hB^ z`6$t0ULTpmRD9=JY@&uM^!NfFA1#vQzn;SL_3&n*pQO|C5_~dMrPokH>7Dwynt!pL zm!#2aXr}PvdN@ySn;xHspDb3>Z)hd@$91@w;C3D6>Fv;9=T_qPq1QEjItYK;Pz~nu zu}qnsLB2D!_L+(KLt_h~DK~;_gbD_EE+hVvbpCOQ3jL*)enUFJX*z7@_&Tf*KNcOP zgu>fWRQ{Y(GQj_vCsbI_+jhSwPXoWQ{nGq}_$9K+f8$PW1iz8^q`wkA^w-7%gn#FE z;~VEk+X;W}cjMb7{Vza&BjJzei;wc-`tJ^{KAc1T7G$X?Z9neDSuZ}_+dS~ z286@yH*4|{Ah<-M*We>KxJaev+%*L8OLTe%2`<#(69nhzaG2ms9X>;FnhwVd1)QYA zsRUbecpSl}nl%2W5PVXH^9Vk!!wU&+*Wq%4cj)k1g16~#J;9rGcq_qmI{XB|K^@*j zaET5dB)CwAPY|4=!D9ZNG(?o2CO`6(=W~6^OUDfQAo_bR%A5E19giWP(aGtb`l*(G zPXDA1hbg_|I(&xUb{&qP{&CBAEGPJ+4zDHnxDMA7+^)l03ErW@PY}FKhj$UYS%(i2 zT&Ke)2oCCSnBWo}K0|P!4#x}!oTJ031ZV2-ID*r3cnZNuI-EzaMTZv>d}@=Pe}Yfy z@LGb8Yj8su)mJ-Ut*zDE>1NeK@{6^=Mf1{UcN57#~ zbs??~pXRr<^w(Ie8aCh^&yWL4P|DiFy}fiNVFd2#&;^8Qklbgz2~Q+LXN1%r>VIoJ z>fg=lKM7CN_;tVw-vSbc4oouG8USf`dBzD8VH<%;lj_ho7ME90?;oPi*X)-(|7Dxc!incTO)! zkH3rJTXgs~F8}pfey0$8Qin|hAJ^f76u(`Ee@5^Q34@>1e*9eL1jdIi%JM&RZ(n}@ zN_cZ~7E0o>lMw;n_C=q>1TWxdJY*iqp){Rcf0*ZLE1 zSYs>j9m4rjUueWb6brXu{zRS64SRtz@Nd>*bWD-4Mbcg+?fa$ul(hFq z`%P*0NZaxo5#KHC%cOn1v@4~3kF+0>_A}BxAnkXh{jIcBZjUz!`i`Fo`wD5dNPF1* z!oN`34bna!ZO6|=_*K&0E$z>xowHel*Gc=Bw1+(){1;36F=;E(9{&pwev7o9l=fk1 zr~guf&yseN%*V?T{!rSMEdnn~+9lH7DebteBD_f2k4t-xwBsKX;q#^a3u(VD?cu)? z;eKg1OS?zfDG!P8I%)q^+HXob{$WX9+V@HOu(XpNk>S#2n*@A?%&$$_dwweX*GYS- zv_HR3`0tQ*K-!a}{b8dBe@xnbX{SkBk?HM|_T$q2iL{qWJ4f1Mq+KV=UzM}%lK)m| zzb@_IuSNPcX(vc~n6%TReTlTa(%vNPYo)EG)1#J?^ti8C(65oUiq|6HN2L9DpYW?5 z74hzpc7wDtq&-C1OQn5E#(!PfLFxaTgbzsjSRa1JOaIf--!0*MX|IxYg|rt-`&wyd zNIOT`)1^H`+G>73mh?~dNx$PlM(Z0)wf!5-9IokOt907$72zs;YNCkG5~Q6h?P1a$ zCG9k6kCV1a;6Jomj!1rGKA1<)Ur>2#<%-pn?$R|&N&~_26_qj_`_X~%(>n(CUtC<` zF0QI7UhA$bUG1(Yty~r)eVVN*T@qYTaFv-Wn+ zMH!PbFTUi`tSJ{`Frj~F@1J$lT!X=BejKYiTz3nomQbRn@M!v8-%R|c!fE0^h|-0~+; zZwWhv?UuGj+FofFNIM|yCTZ`KwpzgDm8*&?%1hjpD@sbIxr1fpE8WXc`BkMWt1E); zrBy4IyQ^0c2gUFYxXXj3RmCI-#Vg^nl7yggNvY;N!Hu9*jN>BDX6Ht2<)ypg0lHS_ldYBnzshVxBq=$|Fxwn*@~r0 z*%lcds225CAZ@RdC(kP3pYpb#)B11l)H;>@Nnpjwa>FQr>tC||us6nkDjd}Zw)BCq zpuvACKBf&3aC{$F#Zzq@IN?9M`j7v{O8Y`--ze>yrTt^|e_Ld^^=y{yL&|foc-d5v z;Ylm1mQBd;crvDnggsrNoST0w@KyamwcXo$sxA9_wf>7Mmz1qQKdiwO<;5$JMHNQ=S+J^F?Z()G%F;CfjQyo0?!~3c z(1(_+SW>;bv@(b|SZQDrCr%`bO`0@`+c&^Xb#@2LoiMnJ!Eh~w-Qk|eCcsc}x?%9T z6-M8ar^VTYx!16(=D~*SU$ugB(^m7S|{ipTdd0y0mPugYD zR_mv4y;N5&FAgp#L-8)FT2UQvQ~A@cS}%8uZ~90ZTybkD<*`pVjm>HhkI&u_e5n0J z%NIiKYWn!MO8?^Q#j}>oF3BmKv+VLRU*0Xt=T-))=3f&mtX^>K>g(1NtzCHg_2WTV z)uv+O?q;9-`FS?sMyh4T&YgDQ%&FeIRYn-T&rE+!uZmXHI1k zZn*J|JI_6D{OEO;oj+!**AH+0n>j$hgqeiQ*!j4!nz1Dzi2VcQpVOnQpYSB!$-C;i-OXwl=fn2S4n%Rw230}1A|K^Z1i*( z*m%WE#4lDtsyrn~Snc2N@_PPLVO)refd5nZQ}sKgP1JwN9$|Z={bSMRdRtj>RWZ7T zDxuA}SC>J7BIT^Ik`%78(lzeN>g9{+n;KgGQe9cT1ga*fOZ-=@&RY;IQ0iWyk|cz8 z@j3B#Yv}5w{-e1Y{nYYh?~45OTw&t#xU-FuH4^XNjg#y>L9gTA(EG8wJDB{k}%#qj{Mq7j>LbZB{P)y=BstaI3Uiq+KJ!1Jc&wi)#4M_)U3VlzUB|c`cW- z;*~Vqh~G(p*R?_L-TZT5yEhBFN!kU!5U{FOcReg%&x6ADKO*seE$qNAgyv+1dHo@H76f z`p$o9e;3mS=1Ld*)bO}I;m$sA&;B1*?$rKURX(5(k}k;fd0;tSzfo0LTp=ce6SUc7 zd1VRINOy2;fCOvH0l`626oHrB+{1Q1No-%>jxY zp!x@k7h{|&t;8zWid$)vTZ)z zTiDP&+^frjWmph#udH6Ww4C%O`jN7^Vkx!##mLWc(no=#uh*=3QRJ&h+S{eQQ`#NU zR-|n|B=EDOT_)`<(*Ci_V`;^T)ox@$B49Ff#H0;eCn7@-1GuvV2)3M$?L5c>u~Sn!`#Ah*&6vqFcPY z6m(1YxOf(PAtnPvAp+VeCzjlKy}GgbN*TdAIo8ZdXiPqPKT0DwwNBB2Zh2pnf7~iz zBa8gkcllcNr`T9eU4br8Y!)1k;`(#5v{gK>s&K0wKa%a;E7I#ru6c))BWd>yXaA4* z>6ec5i2Fxmd8&BZC4W1m-74(^((aHp;XgCt&T_KNFgL;Y6*Kd95~PRGxSa&kim=u` zVKj!9U?J`}!j8)@cn$a~`bhBWmv+}HqMWmyHRgj>UBu5=oICeMvCboAhCL=VxSvh< zJ;v~kNL-?!{z&%7?S&z_#-B0WF2pGS9qdUNQ6k(#wagH{5$+a(4SvQ5L{p_^N z{u0`wG?6mmb@sti<527#L)h7PFy@caAbQw~Q_1wR3EyW3FEY3Z+55u4YMO-C3LdgvLw^Kwwjb3+fgwBq_u2A9G>E23&BzC( zWBeKUNIww8T8VBS93wu}bEh#JddI)xh2j(Kf%+Fp&-gR)vk`eH0DbHM8&M+M#7~(a zyy<)LL$n9thtf0tjQkWK4_yey-m?)U!fgd~+7O<80{s=>?^8xZh|-`u(a%_Kl&vkyj;2siQ7V+eP@`NR04GzQ{}(l!2! zeAy31u>jJ+*$X2|gq!%oGxF1dIIRfB85<)?gquP-4dFd-_tgO?0?|@w8~bsh zZ~Un^E?liYS1 z!tGta{Q=_}r7@7)Qo6>Uk*_kuDMC6pYhy%-a8pRY5WW%azH?=YK(tia#&RM01N{j1 zfFZ2Y;3oVnpr`(f^jiAhsc8~!2jZl^gY?LpL`$V@OrO&?&{lEC zE9DTzKhVRO4+BP|lR{bz;hkqmpJ=JHjp-A8<4?sQzXHTbe;46o&hn!WuOYk$?t$c- zXsNV~>2vx9+A0otHBtUS4}1Rxj7TSiv>L)Y&yqgTQfV90C;G;pibH-Kl>he-PUb8> z3h^4ki{Kt8|3pirZA_ojH_%pb$SdJ6@(+4A3t+&AbW%vGA-ogrf!Y(%QfV90C;G;p zibH;0#7RGia5884QHa+NUPSIbYbX?zXsNV~>2vx9+Jr;<@znP;QT{;>d-ev5NGJ7k zt%mR(xWDfj2T`Il2I}W1UE@#Xo%~X;M&^AV{XfjveiTw<2oI2ZfO##^QfV8@h3Ff9 zDh~N|g6CF*W6!{d65%HNPD8k2a1$cYP=CgBiLUxffg`FWswV9pW|jo+EUaIr!>?{O z-h7|K*y}KP*Wuh2%)KxRiWr-J1Nv?p9J?LnD=d~fZ)PmRk8=PpzgW!JUto^F#FR32 z4onx!5S-~+2(ujKH!#n_9EGV_#@JIZ@57vdNhxD&Jj^kestU$7!#oai?Q)#kfN6kv z8t29K!h~^{>?@eTICoYEvjV0T#)LzJ$uLu3u7sJqfw3UWPhoxoGx{ftT@14j=2n;u z4bZb-K8JCHaP|#m4onfu9+;?2j17gE3Ns(31g0J43z*DC=tMAOFt@|J@GHh%gE{jM zW3dmT+^#UOdtt7hYhsVUw7}HjCGykoMu@pEOP1loHZY&Sn95A-x3`$s8JP52O{^T| zPMH6Jc>(6YauZ9dG_kvGH?ap`cHUuPnd=aKr-^+QGO~(YQ|NF;#{yy}h-;k`% zp1NoOPWrE0lwGpCymHa1C4pO)Em~Y%UQrUPDlJ{PNZm(UwC0k`iL0?;zhd>uiB+W) zTEL`03B-#3ym*qK-)Lcp1+tMi=Nc?s6HF`N`#Ee9#<=Uv(r-DW1~B;a!WMYTE7Lq4 z&bu22{)FEe*79Fwb}2dy0k18gc&r8e4*8Xr6bFmbE+#MRg|RHylRTa!OCi6Vfb9g& zo{!I}&CVvAu1LRp@>AgFfi3YCkYCEP5pl04KX-&*9;cTc>BsRr5q|j`5Bo_5Uh+Af zH^Q%gK1 zg#xc2!cX8~4~~xslY$j=w3;n4z-h#X8VBKN*NZr1v+JkD1)?l7D_EHqv5(mGd@7$h0v>hAm*Sn3&}r^wDH5mi8>zggYO& ziFTHl8P5{uJ9}cgVmhJ&Hvedf-|l4ALS$kp?zzD{gt{0_2^rwTp>{SDI72gI+0gle zyAlHl{%7trvs1uL{|1k!f0~&&z8THmOhdoquOM-F92;IThz&1HWWzHP*zo&PdWLi* zbqs1v2vGb?L`$E6M-IhzbfCflmL2Rw6wyeqv4j#kOUR672^n!+qpfCU4ceF=CH4qR zKB5qxM%d)CF;__pb7k6@Ykq9Nlx%0o!C01D;$X@6fLHSTL_y~idJ>#rE`@25bRuCe z&EUHZ{1iG^D;i}O=1ooq@%s7^-pSbhczyg#Np_Zm{3aDfvn14M zQbs}`qJD12I1HoJj{!Cfva>;`pFyafLG$Cg;sUXLUS6jhtmY2J-hf&2u_&)dnDQBk zljyRb{7{A&vAm8t5ik86JU)W4#QQOvO=`l!7GxRbMHZIG%O!z1?~m!Ca-n*S`vh^4 z@i+&@9N)7E&l#xH#8f*=Epf6`@S2+GV5wEfJdNpupNq$p9KV(D^MEh%{HYcwFA@#!B@c8$qzw& zVPl+B-k$Y(B!0>e&%YcGa}i5T220PFJyafb@VXxK(i`E}OyQ0K-k2R2jO@J#vbo!KtBC=@O(Bm5Up%${O?$nxy-W42At>Y zU7RlQa7^%E|IAFa%hD6!NP!VN)L3H7oC(ga#LYC~&H!LrimBhnB2N;h$cR%ca9$*w zG1Ny4XGx|Z%$SdjKzWSP{}~*=C4626Ci7HczcquNHTHJ%eU>e@MvSjw{ID~}d|M!q zk0mkOP37Ey=;aT|;!z5~^g(X$A2ZD}muTwxLNW@9xd{HI|QnQjD3 z>0EOiLM zi5w0PJlujYDTz5hvjqr;{6u>mh4wrW?Rf;+b4o;e-i~zApT=Vsj5&_7zdp*mz)ba; zm_Xxg0!ygUTL|UvO^WkA9-qNjc$}_GirHhI!0t1bSTOLXj*VeMO@ml$55|F3Yrx`< z@|e+wQ2TQK%gpWp{q%8gOoy>?8qJ)B{}wKsj$7Cx=J}S}%(jKZ3QIi4!Okg6X6GP( z=R7mCC%J2ItEzWYfJAyV9(6E+pJMZLVkq0}@Uf@Nw^%lz3q&7C`hXMTKpb;biScYZ z#eEu&ziM#>A1$`=$jeO@q^-(R0_NrAFsd9F;ncKfHmGC>#-?O8i1LlXr@Y2}F7uiU z$7mQ!d;z-43@r;!yV}*#fn$N5@)NY)JyMWDa3n6_{f$hrW%dT&@i;Z|Bg9sGW;8YG)mO#{LDf zMdC-m)TV>cye$;mi?%{WwihFu$aR)@=qyh3M{z9aexcXJeStDg#$z~)+0lfi>V^0( zH=8#zp-VdZ>5^WGlZVH(FrrRdxqLKRc9MLFK0)*|B$ENcUyDZ#jM+iO>o?Db9FC8L zu6Z6CZW@j;7`jl0I?{{!c@pTysGOgL;{;56JcGV*Ndg{|+<08;A(xk21>_3gVe_+z zah3;2Hd05Et~Chtp2!A0BXljQKg(&u_~Qg%`z!lfl=;pmibFd2EHR#@Bgj7y4|6_C zm3lno#|y8rJUr%6SUlGbKo)W`uznE$8rLuGgyTMn16^VR*+Q4dw#S!}F5xuW{$VMw z-D3$l)bUyLJs69r(5`}MMl>!LsB?lB!E7f#@ZJ~h7YB53uZ$gmG14LUEtnojr!Q=b zBlL9W=g@zX3!_c#C=&^U%TA`5@Xu4vFi}`C$*|+{WSG!tZPHLzz;z5jMur@|4*pPlYJw z2he6=a=sLFj4+Q^h_W!oLw(YC=0ThSm~}Fq5l$RL{TTW%^s{O|M&-}}-1HN8`~$|~ zsCf`G~^A&496H43#ZY-qXrx~>^$>ur~`+A!cs?ASuFY~b-qFI^AUyjPYd9v zhH(fUxboI|OAQ!keUO-GGfyRM0&x$UE#qw;vElZSj(1UZ(NQdVu~8-+Ebw29?SiQT zxzWSzZ1^b~8+y{o2DQgQCyM1^ClKC5;S9BfFv8dUP}}fhm`6v@BHVs{;K`7liQ3x9 z7_>J#+FLZ*nvD(17}AqCJcbR&hZTpHj7NVx4*m6cOr3M&e*@W|ImZGx9Gke#J>QlN zdE;{-KEDbO&RRS+z*ypY8nK+v3W4)OCrmRBv-F$)5dIT*Jj?N0b^J`=yDfZ-MEijr ztM`wuFm^M{bBMzG7R)=XXj9}@0&{@;d3o9U_(47maZ^W<9+C*zOJJ^NV)=NV`K@8R zm;nG|%)g?{BS|hqUkrWrRm}HcRNc@B8+AXDn>vuFLfrI5I39!%a@WjNf4`%d?X=8i zyUZAMRGAfeBgJi1;~s?LRV}Wc$8EM_+m~GqFmXVqc5H-&PUO;bq9WjEI#DqITLJr2mQm`s77A5L|$}$;%<68Dt^G(nNEYMF;_9}2c#n7%xa-yxXO1|A~)L_8e_^Hd`(qL04A{T$9Y!SHh6eAzj?7k))1%AW`~ z!p1nMqp`LHnQ@p#ab0~U;%IWx2Eg*Q-3f)wG{}PS&_-)c0X}Y^U*Kzs8FF1Mh;_(4 zjQuyvaha|W=4*vmOLAt2H8CMucGmL;ynCSqYaeF8YXmIIIq(z*-~LtyO_{R6Fg4z%v$M_jHSm&0MsH;cAmXPyrj z%Y{+Ld?PI88d$T2eg}TK)cNC+Ad&to9)BiUe7hO%n zHEV_9eu~Fwit8wV4$y4LHnS(9F!z`c%SM)@v5}eQvXL0q2lXU$#kXSBQua&fmMHc* z(n!Auj+=j9EkENkMbhMZ!2>ww)LpG)adzk zHvgoJ%{m^>W}q&u?M@az;Xezr4pB$b4j#f8!WqICa3aGoDD;bi`Z3a=c0@RDf-VfF zI}G{_=sG}`_EpILRhS;0rohu-q_6VO4|f3mjOn24Bhn>3qz^A9zLwA1Z^3BNzoEO( ze1L?|1=C~`?a>IE;%zKG)5+rJ^ZAW`bee^wp)Vsnu?ruAx!@8LYo~ZT?{OTS2fyQz z7KQ6Dcg}w>;LMHaH?oTL49Yt$hLs-HweXWaV9Y%D% zuKqVT-qdI{*?+=3=BphHON%UZC{&7L7QXKMwGrQH#~8BRjA~+{EySZOpgkDcLOM{= zFT&$8!gY8|CM?W)@$}jrXHQucBdXN@?5qnPWBC`1+P4|u#1RfQ0`tugh4E|z(il;d z+B39E?5Au}(|7<5+w1IhOC?J*tTjAI;m_jnXBcyQ)6XzldkXn7;&c$s2|P~1SmN1F zu@sVkhb@4G_iYv?=1(Ire;TgMpX@PmJWYh-Qkb}S52B2h)0GBV>~gE7auLC^9F=u<|Vb%e74j}XUc0*-kH<)_b_ za~t9PHy%e|;^MoI@A1S(>m@yKPGa{zj_Wvu@u*e2K~*it<)Y*a9djVig6jmo@)jWT8OIS@e>k84jPj* zX2^LdEOju}r}l{TvBOAuKI$O-Z*aT=gY|Zm55J{>eM#kDsGrk7NjJr+vea{*Do69h zIFo{)^wD^n4}-Cm>aT(onT7m}f&92N`SAheGfMkvIPQXpk8f4e&i=O<9JHOao9{MN(dMxCWTnPPX66W<2G#O8aa?Q))A~;sUB*iyt{louVSwJaz!HmY0 z;z)=aAAerLFqFi3gCIlv90X)>v;_i(Qy(=B6MGP56OtW`a3dV4gNnWP#Ia5`w*68z zHh2jeTXHcQo0-YRV(*amve4&9uQ>%;>EGZ{6AwqcS8f0A2w5!_);pq277MF~_YE!l z8JHW@ia6X|EE@MamdhAb4Ygu5q9hZQj9cs`R&1F?R=_|<&@47*+{CQbArsu5F`hKf zd6Uv-orjIb1j{7bBuI)U&J*uRm=zym9+Z$YX-H8@!mvrhQ%0UQoaQ^UrcL|ourq|- zrs@Bf2k|}hv#gn#2HV+StfLNwt~_|YtH;?T=L(>Q2_M!|u@8vi;d9S^ey9ioPU6To zHWK6XNQ~1X3!TuT0ap#{N$DEWO66VRLNPDLBM5^ve-wk)ksQSqo3}H+xmoV_#A2@I z(Dr+_sBs>pIGe@10eNbkVq*5GCT(5W2%CmD*bwMrLy)H-8C;9+(9RyTJ6O-9h>Q3K zK$2w12&ayw{pwlFWttwbH=CA#v61?LiEzwX$!Qujd4(>K8J1&o`|DYBzE#kS}wN~M{n(iZ)? z98GwyV|~EPZQCpXiU@*}He0EM;|>&KU6Z^HOHsg)jGc+B_bnb@P|XK2G= zz4@aq%yWvdPw9nkvH5Rig1u8|dETFN9-D5?L~+fs?{GXAw>bWys6pe*2}qNlKN^C$ zTr&EiBsTn5sG&y_9_EY8D7e(oScfRV+I;3JApV}ujAE+5C@<_le%%E3Mu`AWni1;*@1xRx~A2B=0j zA)0!zlbv6d0^Mgibf1g?_vi8v?fUSw%VfAHd<}5RZq02=t0le+7^3k zn^x^XtM>c7Ywt;Bl1aFEzNcTm&hz}&|J`e^%e(GtueJ6bj^L{7B?vVjwO^~`NatCM zN$p%;CbhFDDg9Em?u^SE`N^YG2HBI-QiI74sV58`ak}oWHWAci)I)tfWEU44U~1tk zMclc#wmz*V1d_cv58ppgxfa<}6?h!y+KzrsuI~hU#g6deuc-&!+(g&T)8fO!Z(R8D z{MIE->zTHVz4XpKrjO~nF1D%P0&hAx=;uw=w0QPQ3Z`lMWCmHE+#?Qg*Lf|^o7VGg zH@8$a!j8Qk7Y|{@U!!jqUCcfEli0KGr%qcKzi02FpUyrLVdi~y9cVfM{v4XM#*Ab=UMeKD? zXC3y6o^saVRfH6(*93#@=aFhex`Q<;o}Xzqjp(uq=yoIRgt+ATH{gI3SJ&%qekkj< zVjE*!eEpK^Jdi!m)H(jztY7hVo%Jg&JklF~ZPu??J9Cf3T;G$n`#f=Gzl`w~F!$hn zlNu-$$3|nG%==@{Q`~8ur#K{jY^Rb}z({r7Plud5PnF3=L;pdX@uTk=L?1Qid!4Ic z5|3?DI|LIb)K3&X90gB%CKOUIgYi%!89}6D>-2*`d^VY|{;N zxRS4P4088Hmje2$=?VL*&k5q!RE6xM47-{HoO=AVoiN>XuhnghIlGSY3Qy^Q_^;-0 zEO7;NT)9aD-&XmYp}Q{mAvPk?()$f_UfXZ4^3WVj-80aAV2AEyM3H?B#tndRrc>#Z zaeAELS#r?0KCBJQWL+Rn4P_ppXLQyYWDDN(Jmd+47eR7r;AVLgmymo~C8i-yb0k0A zF)aC7$6i%n$m4t;_UB}uTk`Kiyk&oa@i|}~CMN+MQ_Ou{a}D%d=5CW%10C0GzA|PI z^EJt@a}X{C<{qmpX?m;VS35>beuZ>?g`BNc7OhKp(nxDkd7O#R^QZ>;@_QLWDUwCZi@geX@P(yj>UZ?35oTe~+T}k#G7;&-sk0QyAMPb)4ym5X@%L z`2&P@VCXyxr8KD~<8d{YmZkd3S!3o2)VcPPBAsW$G6s`ZBQPcc&W7DXBEuLuk>Qlv z+1xC3yvvy~y`FOl>pAI^+sSI^Yn|&k%Owmy#@7Jr3=)P%3?Ig5H^moD+ekpm9rq{S zVWjM(7mqtz@&Mj^n=p)1L{)Pik2V%PH&&0`h!i?s+8p1IRnLHCoR7dh_Ii*zO^pl= zQX@+;)JXQuNB*^AKIN4)jFi(DyYZ9VA0Y#n>u}-Z5y{3kli6$|b{p&bi)ouq_6a)9 zZAc%=+9cnlRnLJ;yh_}$*S3i%Y9fBd;=j+tq=-F0pU>Lc2{*=^)eX{U?qk9M0#+EY z*U|H$a(-%=q*=#%k_z9+cnTV|AC%-7B;HQNU7Pcsz8!0r(k9dp%BT;=I}|MXP$I5>~@TKvf*@$V7;b1;@_|KW8u{CjVrO{PxcM49oK zvahP=kiL%fT=LS(gy}L+f>+76*lXPf2RU=iykyYgzR`2n`mD?266Z4*&jZSe*gVDq z%u^km=au%0oA)qshuT$EzsB!K{S~8Cj5aYMVzi6FrU9#jVz|U`i{TN&D~3;ufEXb$ z8pLQ6BP>QMhVeyO2Ko;=oxPwk*)ur7`s7on(pBy`B3!A5JrlZXRIrYOxm6v*E-LJh~GBx`xeIg zz|qfnAM+JA2DABbEI+a;PMosO%3Mdz@QEMCF#Mc|kq*eu*%WK?7&Y7A8N0uJp6JW- z1kV*YoJF2!K2M0hsp4-I#)aaqpD35?Vakj*H7J`kot){cDNT;+=Ylx>p7crABiskf zJ?^!RJn4=-`hjn)wWgAs@e7qjPyQOqfBBBA)K+utd%d{717oAOPxU-1E$CwvFlN(1j%6=E)-D$sz7hQ#s$Wp{ z$T?etBQI#ei?pBEYqM^|uPJ;eamYHvClW^myi4hPZBu0Z6jbenwXcePP zjEETRVkp!Y=M=*wh8u&Q+5e@eh9B~NB#7=a#9k+AS09R=pI|sgFqcmYt>8%Gq((|{ zTv&`YG1@Uw$1!;*b1YB3g|mkPc#fryPbI(QjLo2NvF{z675CnOj3tW+dZg6vD-d1) zuG9c3`lh#`yIvI^VJ@g`GO11HY(u5tq65>l-@4zRZopTb;x9RHi;MwZ*l8Nf{oC)f5+i2A}N}BD;J(B5wr0qO}7rv)x#)ZeTnb+E)z? zp30ndAoC;UNX%1)a^`wq#GH>_hxhE8F&+dlZ7!nAxlxZ|7u~w7ab2LD|wr z4W@q@qy}>aFm{gIMlg4ZZf_w(fRQR%`BG@-PZ^IfI51b#=LZKfH_zzUzevfXPZodu z5$1#ReqO1qQlyp^T9;ho6(9D03q-53Rc5BXK2z(A_jMoPLf2_VYMs%~>2wbmoIY&8 z&7EzRvv=M%Y-$VW>1?0edjeFTPV{VFyd5JM&!TdUFD@)ukLYH{+#)uCRDDM+C zbt{PWA92^>hHygrZ0beOlb&+#AV@!>Q_pz2PCetovh<9%W7-uPpQWdJk4?=2Q9a|X z#SLpHP6pK_AkkjF*slUlYaMxKKki!APQX6aS6DlazsI~ZdXG5deq21%nfPn+zKbq{ z&O1qE*K<~}>>S?fSWSOfVLn^6rM0F8`uI|;=erGA^esFLXWxVH-BC=K`uXVO#zioe zc62IhQ}sTft#9}3!e^6)+PyfQBps>lXf4NP?X;?@t#73vJ+V2@FhlF&;N}ygL$&oi zF{O==bfvcSeLY1i*QQ?4r=vTvf`8WB0O=CQJAD=X+a%edzS4>GPTG;!qhH+rPa|4|j;|Avp$r@Z|cR5Fn%go8j%A92ks4#vvdgK`Q z=xdFq#!WX~O?EGxn3FSPQr6_GDfm0nG1WVLgQs+Ag^_E|TbiFUdq_dn+^l)r+Pz@8 zcjLm+1r^4cr0g6PtdlG4#-)9-tBh=rlWp$NoyMGQFmpQAkF9dc&$jxG`3MbQU_U8^ zaUG=)*GDv(ecH6nGO%v@%+5obk&H0!j!ZDDUAnB)>+OtS z0o~KGktjRTvWbh7CgTU_zs8XFR%Ko2w2uB;=5Ej9B>QEIFMzXO<0kT7#^i<4fqQhG zt~EOM=WON>+p2Gb(w|OYsc^B8mOLfpN_HdN{RTU;`o-<7XOFg?UnU?-1CD;J4_SFD zd+Wa@Ph;nUi*b^D1%^2vY@i&*HHr}yqg9MHF(P8Li@`fo%=5%>iQyK*BZgNDpBMo# zLSi(C(I`e3gWsU@PvRRPBUM)LB9&FLKxO63S6Q~%-Nx>AR2qPf>`xI&&Z3a@nio}2 zW{ylbWVFmpp6(*=N~Il+llHq*+V8v4e08t#>8DTd2P39i>2$MG1r#U3!A9Scj zK9QlfqBbSXmhdLM>v$vi7b(k<&$Fj4PHX5_np&0|an2hsF@4BDS4P(0+l=J37ujsqGGKb!X7hV5FuT8)yb34acyP9A}q5JI7XFwem`UKIVWC&rMruB&p>wUa; z=<-J{QuREMupT#`Q+3|*URTKo^43M(4kvGU2g^!J=GYir#&VHzzxthHn4ITUX1Vn2 z*B9%zT>SbJZ#@i?7pw-I*I%7gfASH{yPNT<`=iGYJ_6~w-mbMzR}WjY(rnB&vl@mz z(<2y1#9iFiLtXU#J$5Ntn=!J*C`w9y)-Y@iwp={M)U+{1BOUITR2QeAJeVKoNBZ=3XEqA z$2X1SR~&1T4bB(J8vT(zgFH^~6XhA?8HC>ea~*bsF};B%*V*k^PZe!{mGnMqq~F2l zmz2hm)=-C9ns$5gLPr`SYIcg*cMPHLm`UG}N8gc4-!Y|I8pn*c)-BFKSO*5{GT7vp z9-_O|J;MmcLt)V&B8F2sVUOIBPPpwxZN9BdzdjGqmgLY^W~Y;s@w~AkC7aU@!;EqL zE;cg$Vjt``GS;B%;LXg=)Swyt`L4)N`nh4~dI7r5M%P*BI=!2&`%&*X$)ooWR=MqJ zj9FijrngCbk!Wqnx))n(4g~>ojIdvCG|*MOu1Bx6_9b>*jgsH7OJ5i>m(hLPIY|=E zTKh9eoiiJ|8K@by&AKw9uqDqjr%=f+r06Q>n0vI$RIX7{V8d%e@-{X_9)inWsXJSkR$^E>H zR-+Z38AP3sCv~}+Ch3@)yv~SSo6!;AAi6dadmTGgh9vxNVwhuPM5;}@7;3ZBA~9TI zxW({@;T6LtMnH^^7!6`HiV+s0Rg5+lj&mM}A3Cw56#^hHGHOpWoLtQlYlv7nWk58z~^l%%0RwbrwmSL!^|VN7@W9RmuSTODd~a%O6NnwPlDIk22_%S@=# zkQ~&IKI9C9dBE&v*BY}!WP)x2zKPNT)*7$r*@9MStueSvz2VrLJTIjx^;T7t%F4qW zd+Nxv*~}pHJL=|MRrDOnz>dAD4Mee-ywz*u_i*7{uKF8BntI46VS!d)zMDn8=zJf% zk7`}W^Y0?22Y4BQ|JduprBR&|lg2(=3=!oYLHYHmuc$K&BQy0G=6{@{9i!DZbsx$; z8}CTSGmte$D8Q?^e)3mCUCaf#+Z@J#SltJW!9?c~0$c)wGWEakKA zt5Q}6fXBYLTEVGcT7*4788^qTloOa47i z*i$6`UPky8;JZCk(B!bnHvUMEw&@NvJ(#S&JJp|XPG^tu^qS%ALnEiP4Qf3#Fwl33 z-lI=Bmp0rV<5XbuQ(IZvf0}k;W4g%uQ0@@}lhr`>=TBtaC}}a@+9>Ct9t^>`q%H0` z$y_^9E2;gUr~Xmyl>@I1gUIL$!?=i9;A>ZK9WrFUq=G9ha zsK0}KQN3fX^}b}DwJ#~_-h5vumGVdm(ifK)>dzo$GU=7{E$*YQFZA<gDE z^CNxcVtJR6b120eQvv3C_sN9chqWcvn!4OG*YG>vuafaNOkCMdVmuEV{oIt(I1h&7 z7mkUjVD)Pw=+}5YO7Lv|G2U3}<@_tcspl~#*L^K}maOlztq^mB`Q4ee0k5+yY=k&@ z-Y3a$IqK{fA5cnh&$=Fh$ex2?jXk1|PmF*VAu$@nXcQwXMynWYVnoDf7lWxWV~-dv zG2CK!#PEvY6C;2jac3l{j1}pT0fGKLr<>38k|#FouU=)S`@ja%nd+m@xAtR?>_l~P zjd{K`>h`C&`vcg6TVbo*^;xYxvWGgdGu)YL`2Hg}d7H^L!=~i>D4L1iCTC?Rzd`Jq z4PxJH5M?-M;wcf)RrJ#53%DP9wng-i#Q3h~dz9cT!j|8}8w@oKM6b<#O7lBE;)m9t zR&)P8kZ1X+K;8u|x2}JH{A|p9xqdF@ejhn^#yn5Hn~)wj*%!@|PjU0c*9}!oIKtL` zo7X&J&HH_{`ShG5l|I19_t}y-Gx3x<#kNQBYOk{Ov8g^QVCfrctoMQRI~=@AxsY#l z>C~C|VTt-XeIiG{!z%m7uJO^ko$Ryh_MER@iR-+9BsTlSek$MEPjFux%YSOgFE*a= zIBnHoIFaQ4uH+Z%F3`oD+?W4kkzcGkHwRF={ygWJsSco9*IyDAjo9x6?I0WUq<_?} z{Fj9MqVX2U#Ue4{fAZfU@{4sBxisF5T*-g1$S>Ai!$NHpXGGI6d0O{$NPYBSeg61v9QaFMo(Gotajrgu-L#OuZWXyTRsjF4Y! zdLy)zuD@vg-k2a>=@r7*C#oCr4Q2U7!nZ8An!r@}C9r zi^eDQFLI%_iZi0=DI?sjKS@tdbv<&o>AEq2Kgs_#?2ojrNl5Z7fB8lA)mcBw>}T~2 z%ZTcm;YqA-Pkl=?+jldQr#+uJRZUKXI2skgsJqQ8aK56rA(7J@Wu@t|+<;D)kcdlANJ8*GON)QsJ zop~E=%Dsv663Ei-BD;8aS17!jxB7tM9EA&n4jo-w)7p5BcyU*H2;pGG+RQ)1rgx>IXds< z8nl53Xb0*=bOP>L!US&Q2ndTDgh4yk?Z3qSW!(G+?q4O|UlHCu;(G(UNqpCta4#ht zAanz6-olQ24g-0&q7Ar~u|Re?d?Do@!teRGgB!7HU59?axtufu=M}iS5}9y(u)C0Y zatnHW1Ao-X_2h>KS^3Dr`Q#~O+=zWUVYW(~x1uZe8a7}Dhi@YdMZ~`XUAXVQoohJ6 zbpvP=dk_K6V#1q7UUA=Z2kGXz9l7x?WbDImEAY`?L!faDFR0OH^_|CV0$2v>!A9^` zkUrn8#)CzG_uSMy;0NG!@Db>{z^;~nD)1ff87R8Qu5JR`K#~{#U;qqblNZ|6au5XXfj*1uYAm=Agu!0$9ykOl7jsku{0#gN@EHX)64`@<9o>9&7|pfM0?C298TO5(#p_mEd}CKL~@p-~*tRaTE*`fGW@c9s}=y)Jyqq zAg~PF2zG&e;8T!&8UG6ht_6>PHt-3^xSV5ipd8!=ehNMSCoX485nK&6gEv9;73_L} zN^l$41zrRnfWB9fKOi4m0d4>fgH~_=dhKXn8A0t_tW zT^_In`~{q|k})0J3jPR&m!U7X1N{r>bIT^EBGxK zS;KZXxC6Wd{tnKpB@N(y@Cq0mr0#=jK?~rqSxo>%;7;&7_y~+xMOy$*fVaSx;NsP^ z74SJ&Tu&Z=--Etu?CNY#0`39oTF&Bwd%>&V&tSyY>}mse2TZ(Ou3o72X6x77QPV!&b=Dp{Stmp)j(QJmLS zeAhyqq@0RxH>#8Q&*@XtKy|9(4R|$Jou-DUp^DvDTH#x&QX)pxoWaHkF~S&)l~kyVY-^Zd?;7tshKKY%~G?~1*$;J zQFGOWYMz>}7O0E(FW8GY$Gk`_R!h`UbqQzDFXi2|%hhsqg}PD|DxWG+D^xL44L|$m zD^-~)=bIE)s|r=g@LbJzUa#SM7qxuTsZOm@t5v;P!@2vfsq57B>IU_76;f-}jp`<~ zPTj0-QQuJO)i>3x>RW1qx=r1#zO5S69qi@arS4YusC(6S)JAn5-@W@TQ<(?VL+WAG zs5Yt1YKv-8Th$|Kn`&0uS?k%UTGTGJn@L7kJ;wUz_xb+*6Y2-*hiZ>{Qaz=9q@GsK zs2{7Js8;o?dQSaRJ+EF+KT|(fdl__pp?;}eQZK7l)PJZp^(x<8`jy(JURQ6ZH`RXi z7M~#bPjx`Oquy2jr6TG*^=tJT^}hP8`knf{I;cKSe^CFeK2(2He^P%|?dmVA^?sy2 zR-dT9ssG^>;!o9Q>hJ1v^@aLU{e$ASv8-aZIc!O`WZMb06c!dzZGCNNwi9jrY$w^A zw*IyOwv%n?wo_~aZL9*@2H6JNPO}ZM4Yduk4Y#>$BWxpWr`s}ZXV{|uoiVPYqC(A> z;m#{6nOR-6ihtYSuj4(J=FXqz@mxGBH`kLpD{smCqMEBc6Fi>F4(D>IJH}PMzs6q* zs*3$x0z49D%c7CZF0bg-f1>*{GFKGUmKPV+25ZWzR(kT6%*ZS*E2=3B))bWoYd!g% z+F*&tvvfvgQAI^{aZ#|k2D^zK)4C&>bE^3FkzjAScX!dDwzsafY(-J=)xCL7#yE&jVd%NwOl{c&KLMsEhc{Wv>RaqVk`fFmN z%_Y)kmRFPK{-VmB@;o++6ND5O#jN^be<0YsK6a+S3ZX}bQKgQf9`qD;v{6Wo{x3$; znbtW~tBNYhOBPg@^xPbJaq|`EXobG0xTvD2OZj){BYJb$nW78*YZg=oXIIx%mBiPk zm^!Mv9ScyMaR9-vg(Qw>a^v`j4!sTb`AHEoXe^!SCsob9UWe8F215V5)(y7*IZ6hl>V!b z%25}SOf!=b_~^|3t~W2qF~bo1#cKlojvl|OLo=(rMKyGf@dek}4U`{wH_$zx*a-eF zwLepdo+9haw1xhav+Aux>l$`R&caz2%vx4>k+&niV%4$sDp0BtsJhDhTbJT3Z@r_sKY;-teWY@Ea9vzy);$fYc zdD2Ul(MzleyO@shcTb3qyl2;@4pp?#LisnQ1gSP%SmSWv>YAcJpyzga6vK5dA?he6 zB$`7mkxskgcK0b^{Qa1@T>Oo=iB|lrE|aMEn_VYSv3C>CZzl9KD~aCd+6ZET?B!PX zkvYa+qTw>;cK2~I=4Qgqc|s3;s%77cp4~bKv+R0rk}>M^*u>0m4%c=}SBI_L6Ao7w za}w1>X>BqgV9bu42aDV86|)z|F}1W8S8-Lg7k6FiZ!a#pR^}d^cCFb~qNClR*&F8M z_24WnZ+e+wC(6pMHLE8TyEli!xa>CROcZC*ZVDb@4LB9ZH^?Ju#L!wt%bd=)OJtEh;XuHhy@ntN~+m*}3_xEbq2GaG4T){vHS zIQM3Si+A1Q0N8sZhxHa0*CcbIf2r;jqEoOV8WBYc(kG$mD&RJ&Ok9A`fy9k7Tnoj! zJ~yuR6H+4y`0>o;fhByS=Rlif79C1&#nEQcNo99aVq8J zqC%J6GTudA?hO5~78`$FTo@h6%Ih*Fb=)Y3>f1fNrqXi`=U~a<92B0LXgrvd=V3uh z-|OE0$J~tR?_+G^`u7<7F8z7Tov!_N^i~gjY{%^`%OFwv?tN&NJ8^wx^j`NqGI}R* zM-{!>`wT$4%B`&}Us>geDSj$`?lSMJT>X&In&FZ3+i$3&Pw}&Q$iNjf{AGMD+Fs=Ua2C}HU zGEm|FD$>>w(($Bjk^dSi%a1K}GmEMuM;7>3SCm)zyOme8%a~bF&E1$ruVXW3bra3e zduDZIpf2d2&6t;0U0t!Ds4`J-tas)YE|8wlaxY_KFK(rO&i5BnN%D$n{gZNHb(oR4 z%3mxi$+P0tm1kMYNP5LtDspt3IodVJvvu#DUsoB3kM%fKxm&~(>+}38%d7IM zi@W7L4Ovp(;fB_AST|IM-rUTpDmhF{xHwEaxHwEK7xKs8i;GtFrbtiqEt=-4o=W^U z^1gGaeO6U%U5#JLVOBlMX0`F%U!Ixovn#4se+3;{!eEZE#m9$rYz;m>jE+7iQDODo zQ}+tOjRzb9_mrpHXWjU|h#ul85TmRX071^#*xTwGVl zYGJ%5c?graXztQktGH=KP!s2w272@{URqRHaWuZ>)aLt38CObTTiC_3qNB>3TIp+a zJvN7y*jxJHsh4|;%$>&Qm}E}9kE<*sXXn&fbGRO2rjFL>{ndo`=T#S#bT5fzQV>zi zj(C|~hZRj76LlS-jJRKASjRp%>e?$g)`Olh&_{3Qc02}OD$h3^vFF$Sf;wHYcy>*7Wz2)qacA{ck=CyIbX4MF54@w|>BXWh&2R=Q zEEDzW_xz$@ahWH6aVIag;CSYPF){ZTHocPU#hcx<*1=!fO^dInuj)PcBh*AU(wK#+ zvzM3)QuH)xh8~GJI{e!Bu1$|jGJaVPAakmM{*^UF6;{OYVh2q}m!k`D zeM0h&ku{2@wiKt$haGq$|G9Zl5TRLzm_K%{{tWEl+W?t7|HYf(ha;TyROwtod^m zFP^oqaDMKBIbN&Ew{xmWWTq2eT;1FRXrfpFK??MYUMZo$liOCz>+H`0Y_`CQrvwKGN8a#otABK_2jD za+IUipSToy)YMBm;CWvrsy$|N;ew7zK}H>gYo=t!k{r4z+Sal8T*CpmxRIxOm$4`) zjyeijo`<{oIPQij9mk?TQL+D`8Z%oLS9huSx{vP2*JR? z%E|50Ax2XtT}8K~sd!iOGsk30g&>LYdC@x)<{v^^aU>}8BSe3F-1n;S=@lb&fD zCQNf_aD^<1#TUKa7@3jTarlaLAirlx$K|TnvsmT>Mf9A8IUP(8q*QBC-w}omGBa~# z-cbizMP2OSY>19R-;a+c?u?wJ@WiwA%+*x2$1p9m6ND+c_ZDtlc|}R#>M|M6yKHdG zluf1R6Y4S57inO6LT+x+ot>lCDfD^ZZmlveSDsv?)fQJ*czQZm5M8P%Hph+L-059B z+{yZLVP#REu(teKzo&;BL{oEtFY2Mzf6bA4kmK6HLOkd-fWlz4#MW~}dNL>(d(`J2 zi}lIy;QwX}OuWf0$s|v2+r`>}RWpmb`RR4{H`c2@In`||RF-6=9+c=6eh+8H&2)R{ z2h2vX$l7XMAbLvO;#!71e`O%Jrm)r=$|Rx$?QhXnGY_tzRFUxHYRZip_&BxS+dW}i?psy~b>gtjN zy_|Wvpxk_?p_er4C&p-^-R9issCx`E8r}N^ippzx%40pxi_K)c;a?uN1!AtkiXPS$ zaCvQEiM5W~V=|&^y11>9V=r+>d7?Kf3yUf_d~Vi&=m2dtD>rY9aICtryx7BYfL>~0 z0isgggXtyCj$y|fI>q_nRkfa;EB!Sqd+z%v6iL6iY!~aa$1YD7W7LP_0fm9~F&VLl zVRi|5DqUXnYFQTV)+3sACQx15+jyt9Fao^pQmEf|Ss?ADvvaaE*8^~;qaHI+4^pvB z;g}j*4X66qy6B>cxzJ_RBFjlHikMp#;=pYF$Eb-so_0|rHc#Yub?~qQx0I3TGCJJ% zR1bBN($1?_AGXwbAF-t6neG2L_BllrN#WrpPF6E8Go!a=W=>7Cgg#E)*}y%eV2 zycUOtOR^dK@l8KvN}%J?Pu;y~mGD8fGgU#JuzK@;+@%xMG$>EEy~Pw&bOFslKj>OY z%G9=dx1qZPJ?)KuuGf8e=S>N$qpOI{uzQ;=$N1;vou23F(HVVh?*$;!hG@bpMa`uI zv;VGL&2+j;;;jCuW7DXY!yb~iy%ykC)Vg{vyVx|w6rME8x&ZTFe__wvyY5T$gYs&< zpwUx?e^qVfu(3$F>UB9j8X@mPo4@-Xva80hp~`OUv}<{ocelUKw?|^^evDlJyNqvj zy4$$PuJ&MeFvjjF?AAZd_YGtG9>8uR?m{u{KF7|5yGV??A)EQG4eos3=!_%12^sx* z`sLwAe#EC7Xbc-*uxXR)iEq=h_?^(Rp;$K_*rNvQw z_cfT|r`}=mT#LgN55Cj1Uu^NM7Vot<^)B=N0*jxr_-_{H-)-JsXYp$m55C8=Ut#fP ziw{~n`d;(?RTj5c{F24l-!bp!S=?Zy;}z@r4;DK%n(iiBTw?Jai_`8i?=Q3X5sRO* zxZnNe{e>3aYw_C_5BaWn-)C{7#qAbnJYe2mXYr3MK45Xb2d(fezTM)NEKaBX%Wt8@ zYJ+(_*Gg})#m{})w7<^cDHi|jcGLcGivt#qv-l6UnfEta?6Wx2;)7OvKePA|i*K>G z)Z%=LM_Rnj%KvCRYqs=nwfJp|gS1=uC0p#Yc(BEp7EiL+WAO%yms%W+r#+famc{Lj zX80kCqwd1i^+Ogv(&hdF+Q0m6u=rMsCt5tv;!=x0w*0?sanQ1V+PdCr@oQc59c|ek zvg}>f^*oDLSzKZ93X7LoJkjEOi>F#V(Bf!%|73;#ewX-fH)a$rtMFH?43-u8^~ods zKy;}b?bXLB`2II8s_TM<)un|sMO8e=bagQ-X+~XDaZ%mMvS6XVW4+IEr5`h1u+La2 zPp;+FwLD0$o~mz}Pk)S7YNdTfX+;s+kKG*<$o=U_GggyGRNuc#~SX{p-OZw~7(@&xrw{7yJZztPvG-gV5VWwEfB6{n7g_L0Ob zD=7ssJgfK25UP$Pgu=OcRFw=+^X)VI`XTNpHJQVcf*kXfa`+kLD6du@dl1tdGXlB> z9D5Mz0>U^xExhE#aVA7vO217K8%7q&@C^vQXhpnl67Rh zG<`kLtJz62>Sf41>H$;qi5W0wN;s_SA9FaCLZ>l1D&>TKN4+|V#7XwNPVSUdudXbr zT65H$qM0NaxxY^9T2dviP93ctQfZ`xWfKC2kdE1Zn(a7Rs9qR&QrDBxZj(T&k^XW_ z%JIbDoup4t(U8m;s(Jodzi}k3?OUXN*@~i)Lj6^#jw!HY?eWAqN5Y=L>{YM998>?L zD?dvoGRdoy{zsQmc`&AX(f!+2=`Xt9lNx55QOIiwEA@#$t7TiHTm4MEgC$;hBh6#> zbPpOciYitYtzi$QTDDR>@)}L?s$in&{b%$x(uyo6p8WhJh4WYFkv8bDKFlT00vwsm zjlCmt*9q7OOZz@s%ld^wb+%&$&m>=MprhnDrnaoS^w`49wUpHgK4#`A-yb`Sj%+($ zNa9H2(o)V>1wB^IOP7|%rljuc-PEyjJE~^x1^ThW@c zk4GI=%7v!oJ>32#F z)BGkbb$2v?T)y@=W5zkrk~-p4%luEjNuMhn?JC_KJIecrLy@sQpE~RJcMh>f^l&f_}c6D)%Y_iZ8Gh z78cjl@FmQcwJ*NPn!px~d2gXU$hTe5p|Cce-Fro2}elMO=KdwT^{E zyz(vELfYTeg*<8!Tc#?k)00%|IzvLnevqov^DZTM$CF1zm49^^UzzPJkr|4^a%JKT zyF&T!X$CHMA)n&Yuy* zx!{HL`f^Ul74gES)QiFzPL0+|Jl363mOteiYEm2h_5NZx92n@^;9DepM7GA6r>Fc6E8xSbUDH;V4UarGIS2gs~IGnoXjM3rdnh=CKaC zhEe7(3iNiL=2c!D>!3>vQbe_DNOxtdBlUq}p`YHO*1u@sCG#js8XJ$%yj@CL%Pqd9 zj+afl-5Ha7Nzv7Q-jd zx-~h)ZeDfu)pdc{RyoY73f9nWPnA1M%WHylMHNe`$jTD_Zon>Yims?zxzb<5;eYx3 zo%$?kNtM|MOFDXr*}5Vr^~0n^{$P){e@JNFn(AVIZEbbUY>qjiS2R?Qae+TL)9e~7 zH|ou##nC<_YNbMsi|hO~YrOuNQh5c2FY3;egG>GzmD@dpIVJoPV`sSZZZteB)gU{z zi*)HMrlRE5k^sL*D%X}@UMpE^I-Xa)qJ}Ta&ZH65@^`v2H!&N+qIuNm0%^w=&RV!& z*1WSPn*B+12jSoRub2Zglei!MRH1(-ScKQCZr|#eN@1MPd{1Evno)ZRQ+_&J4E_aN|IFCz_NWi3e^O^-Yq`i` z7hPLG?D+k=Kkmqie+&N?a=`lU<4`oJiJSjx?0siNua2HyzQXld={^b7{6*`!>~vVa zxR*?}^;$V=Of_MQaM#MkzE8f1A6(oGMEYZkJ;(J%(#- zQpBDkPZ(bJk6R~>xA)IdYc&#v-?4~qy?-Vy6QwKBcf-w46T6puDCP^D(Y)#@+_*1c zns3WSgH5PMbeq-O!jX;mqx)04j=&KTr86e{!<;PCTj#OC9WFfiW>~KW4>{JTcka6U z4_`+dz3F>ohZ;MA(n7D{^{#4cvG$s7^y;aEI>Jb#NBjXEQ}0CXW@Hx5sjgkYvDBk0 zk0Uw*YGqfVcncT$OW8AJ^C{*OS1;}pe^kEbbXo1*`YKd>!$_o0_s`iUuHUrd?%(+D zMQ_}9{ak;-^2S}45B~QUf7~AiNYshaW4(r&sC!E2p7>=KFQyku94_^xqvWFhdKdr6 zgU*VSNUucx6MlQ3Gnj<>=Cf_PklpXt{~5K4A)$N85BZd+?k{WOl9|vwJF)VSLcR;f z;ekAPjVQhj^_1^3GUI%Dx_&&)3?)9W#Q78-4u?{^DUjG-Z29!?CbpHgN9dn_Urk)X zN9I4V-=6YMUM-hn5|2YH#AGZv-Q z9#3b4|G!H-T>d3psl7vZx;h1U5T{>U$b*rGDV0AOc{uXvN(Ck$XCh}S_4q{OGm*zC zz%8H*IShYj$*%Fd#|p$g1V0A?$Prk%mAVeO75)Gm_@kluyA$w_ zEc|_-{$yyjPgE)$S-2m_Mix#7;>HI*1m@va_yAarES!8c@gjTS=fK^f1AK1|^%?s{ z_}4&m^PK~O4amZmpUd+&ZhUaTc}nfa-U~koB%D_GRUqyo@Lw#MKigKTzysI|uQ;FA z#*u}u2YZnl;P-&!A;*lAA2bk`@Ry(oSvY-~QhShv$AP`b!V4_>06cNJslNw)6fFNA z-j|1Sa+Uh{&xYcgyQ&F<|4JFbwmhXKf6C)LJWqfuTn2o|0eIL<3~WfEz#nd*ResBb3r79f*G;Ubao8-Q=Uh`Nn^1N;~e`&Rf} zuTn1TBe3maD;#)&C41m&fs}O!{`Nxhww-X`Pr(Lc{w7_G01~Df{=pK;9o<^tElbU` zgyC0#xQW2FORTuya&QnGgm;0xpBS2dgnR(G9Ui{Sbnk+{4kX_~@M)JS_5MfHN%$Hd z;fLT&mK=s(wd4qFyUdCgt^yKo0RAO-8o3SbbGhjz0B0_z-V?qXt^g8#0RFZmx5MXL zVcL7(1)!0#7G4gTk%jLBPa_LAfi`5}9Uy`nhCcujemnfDE6uhUf&UD|Uigec@)muB z&jMl54So(ghv5!?}jGe! z1VraBeBRY&f8v1$RZvFctqXn|NM8|wQ!A-Y*bBb}0?5Ljg7wH8dR4jAj2-CXg};3b z?SekA0d4})KZoJxEx8ST-;M~&&m35S7~v-&}Ryt0Wy$<&jQ)VjrG(kAZclZU$x{2 z{FgO^Bl&PGbsNaIBYgSSNDFx=yb6>_9}E8{s7DsQ>N>(i77l?%aRc8E!pOpnmc8%| zH!xKkT0c;PYux(P2_PhW@5!plGe*$1b6 z6P+1fgx7)+WZ|blJ#s5N|5mfkc;Rn-i~5N^4e+fSsPj_p@TS`spQsOEc>L{@9d11E z@4rpECY*No@dkh_e8L^{OUS~L!TZP__(wqMKr0-+ll}yI;rs5Q9g#n6@I7~%`ZU7( zfz*?BIP)G;cEet9-DlKKxCv}P7Jfpmkz3(UKt8hY*Y0K9L>B%ws6cLje+#5-w!>F^ z#|+;GuL1|DC&F97=g7imY-A3DU*QQL6Iu8G$U%<4=iFztLHJrw@OMM=i^z+Sg@@fw z*&(~&>wu&&1V07Dy>OrJQbx$aKCl5<_%k4L2K4}aCTJ&KFYI`T{6}`ecYz_ecRozm z-~r?i{4kI@(+KYe5^n^4veC3}g&Q{0H-1k3z*laeTqIt20}#Ir@M%q^4ldZel{qVJ zgzJIm77{xk?!)l;k63vES8ti9kaq2Z$L*jW#@-Ewzy@UDR^USx{u2;A+u_kWP1z0CgO?1u=0nH_ zkcHQ`5HE5A{3u|5M)SS9s2j+_VUUR|Jb$-Y$Gq@oK$qR4gaM>a79JU9oFYu&@sH78 zAqy`9W02dwr_|6VD2snkXW&UdbQazX_9?sO$B_>rx594#aU;Co2ecXNg%^VoWFNd{ z4|*bp;Cq0Ko5H^Yhp-nO^CbO<&93=o?_C zAB3|&8?x{sOBOB%?_(c;9WR*e-3hCo(Z&eh34aYpJ#2*|K=N7m%%7X?-SCpVro9ht z1>)ZQBD#Yd>Ulf-r(crqUs9jpcV8yG$PxH+kcJMzi~obVjV!zZxJ5U3(5uYBkX`W9 zU!eznJ#Zm-nszE&0`?*cKLrjT3(wz2yFeDc9Hija2Y>wy^dZa;`~Yw`bT8pmEa|0;Ytue4!}yU+8|BHG+n8H)u!#%PG&ix(fqD;N;3LtG+_#5DW!>;)@xyT-P4Ul>sf}gbHR`?@J zR_)A%fVgqPmsqk7e$bK|;h$S_8{FqFrh6xRlzRPd^j)OU{XaaXg92naQMLC|>SsT@=JP+Jex77k!gIh7WZ@8S zBMWc%oP5T81N`ilvW1CohM%SRZxNZ z2way+94Debd_UNLEc_#IH?r`)zBbj29D(0Xv#E&qg-iR})Jxb0;JrZBvfALG1MrLN zf^P(3-vIyKvTui2kxbWZ2Z_=-dWZo@P^_G<1W%1P_odHN>V) z8AkZHalzAFHZ=y>1N%qV)E>eKz$cw7cJ!7#aoJRPq@ivu-eFWa_wy7NCFkCvp z3_k!*J=>;Au=l|4=GfFmaSwk2q}>TmI0u- z1;07priS1?0?)gMazysRw*cKn;Cio3y^nnezW-wC?aAl~{}y=D?V6Jp+LRAjxBvu^ zg^NG~vhatX5m`8Skxe}9zSAoZgOZZN(7g_j4Z~$5O*PtC)xN0$F zfnVYEARSrwb}$B6_--&2*|&szUP@aSKwE&H0lFW6=U-yVUSS}8yYLI38TZ1!1WzNo zmf6(BmlF;;_~842gwqJ8EjRlCCwvnS`v%y4g(*AX)2^g{ARHf@RY*CCKJaItUBdU- z)SrN?546LBil`?%iwPHlb+{3J2W&)+z=KzqItxz$FJUk20}(lhpa@OQ%DPZ36OY&Zv$TJ zh3^6-$c^wWAbBqQ8*l)7;X!4j9a;EHkV5#vGe8Ei2QCH@ehB^)=;w%X@&QPF_P|?# z*tf!?t}^Z2u)TtQiSV89eL&`Hjqu~(I_!lHcP02yDx@Ti+j*$uA%GVTZ9SAgVs1Wv!jOp6O{0g}&Qc+NK{>kM>*%hwZ*s@*p65;pGpR`uO1IKql^m zzXX$!g>QYBx`NyQ&uYXEvKJn;iMWQ+x4`>>ltl!7aSQbi`v`1rGRrXp|2JsIz8(JX z5$gRgWZ1QxehFFl_h65>fhX;x-eB*6Hv`GHFkHKfx;mV80Y|_-WVIU^IFLP$QWroI zvhYUGf-L+tcpfpgq&B zdE5_3FX6l4aX&QY01fa~Ant`DAWWFTWA~7DWH&qu=w}4@R@$$Psw_lUAL9 zy_PII?kV~s$u~F*hKxYxAEEm*r2TaK!V7+5B%v1^s&h5 zXY_3^GlmjQ2wt;~`aKdEei6vpl<+~2j&8zlzE1fe3lDpPv>*#l2FsC!r-LA}a6VX% z?1i@g2~+q9P(gkQH@!(7A`AaFXharH+D~0Y7VZmPLKf~1BFHXyDvfmd2`0RAPA zwaqs8Q_EhxMO}CsKRmy?;6DOcA8Us{e}^`hO`g1KQx|?jTBsXd_*Z|U+_8_qs}3<| zI+Of?r+r4=V()>U`#bqIfjSJY`+~A|ljmPD<^pLuUf2huT?lUj1-KXf0QivG;oJT} zxuSCeyj8JJ%N}|d{$aAAf@A65;9sN|YX4cp1y`TUy6<@UQuvY~jC;8E!5<7|o`Rcp zc+GHA4#Ah4Zm5bexPcdE8ETKn@B`U~%0_O4A0EwGg~;%P@rGJAjx@qIW4^;R`_t zvalc2BMV;*8jyvr0Zqsu_+fD99J}V;4PLTimz8NsA2C zj4bR0k0T3@SM2B|xyI0_sFdO0Jh2#mc4<79!zohNMUtd9) zlE#oQkhBPYVackPaDar_2)_zspGf%h62hEp*Zc_bb;x1(&maX^_(DH*4_SD8Dfxyh zJRRgC3(o?Jk-hL2K-!vGX{b3s%38P_c+a(KURFlD$ifeUb;!a`f{n<+KLKH6;TOR3 z$Zhc7!9HZ+yUQ8tkcHd8A#nr01BM_AhpsYICbIBa;6ZMHmsX%B`R0Q^1_zKmm4@nH zMS8!WPk_${W3U&V4<;iEf32Ex4amYFP=YMH9t4qvo54EdFq|78U6McWh&n^PgnS+R zB#`pj3p-YsavFTDB~OO8fR^*<58*GtKID|ugb8GBmJiokvhZz|+yL*fWZ{=Bxea#L z8|Jzt>;n>xaL|&4cUy88K7Wm=+f;ZTNSk8Ue8{pF9&xSdCKJBWl6~-MAmP`;k6ZS_ zL%(LacfsGao_+)E1bYwsQ?L>F zdHBPx17zVdLuQ-x!T}(2!g~0`n~3jx+7$e?b>tE9b#NF+842HXGxZ1ib?_ljfGoW2 z7V1B8GyF>+`X7Q%{)QiNJ^75PS;|P#&Lhx=&cHK)q475G`h$Xke zf3jrXcMNqs&~D%dE!laWp~eEScf<27*$3Yel^-zFH-WfmhX+1r$}V`eC96j21`s!4 z_$^D0z@?Kxfz;1`o*(lnlmVf5op`+q3wHwhJ`UD&x#x2_ z)b&iCy8folsIRPW@n@E`eB^1`s0riTqg?(fz68oa-f5$jES^1f@+cRd0<9`3s^F7Z z(?+fF*N&Po{lwI%MYXm5$`uuBTm(>6J8e{5P1Tgz;xd0_QSDg%yRD|Wwz@PpmcO2w zQdCWJ1CHy)2Dvr3W^w)OWjJ-Wee+i6a&-1VHSGX#~oHnYcmSgaIovmh+tFAn^ zSUw#!ZB%JdMXi67YkWsIQ^)rl%hd64I!ztlkvP0h9Usj%F1i**qU$i@5arg`)Z7$q z+SAn9)YcSfI@r|Sbf`&fP1)+)>f2hjHL$f|>&C5(Tbs9rx9-{M+g7$Mu&sVuXxsX2 z4cj(uYupxTKG@veoU+}yJ!89Td-its_Q~5l+Y7dPw=di7+g`Rku)ThJX#4u@4cqr` zk8D4<-L)fohkM859iANpJG?uV?eOg=+Y#7Nzaz9`{f>qm8+SDBXxP}3`;J39)XtQh&Yc-MT|2XPx_3_AS+LW)bJo%K6IJJ;`Q*y(F2 zYYDW}w}e{Ow=}eDY-wz1ZV9*SY1!WrX*t-^-g2l#?Mm6@+?BD*wJUpU=cgQP-o{kFI~T z;n9tcHa^o+xQ+PJB4Q}d?qrahZl zH|^cjwrT&S$fm&N`pu!u>o+%S-nhAObMxl#<~^HRH}Botwt4^N$mWBa+czKDthS_V zac;@j;@XnE#j~Ygi+9ViExs*fTLN3^w}iH=-_o#UdXs&M#HLq`O=&>e9*|%>$v|a5;+2P!gu_JLk*t@fB=l-3Modw|qwWPE- zTQXW)E!i#ZmdP!i7Ac`UyIOZ;@Am92po}`pCuEh3lnL`gXb*YfBoBO~yOnyKL8<~< z+qSwM2|d#GNXE8h)Z*~AL))@R!}{iMa|GSp)Y|pi!)Q90dbyDrm_a>jKr1J)H&BxZ J_+RAre*l=IjKBZ@ literal 0 HcmV?d00001 diff --git a/src/ui/electron/main.cjs b/src/ui/electron/main.cjs index c525a88..fae30b8 100644 --- a/src/ui/electron/main.cjs +++ b/src/ui/electron/main.cjs @@ -8,8 +8,11 @@ let compilerProcess = null; function startCompiler() { const compilerPath = path.resolve(__dirname, '../../compiler/compiler.exe'); + console.log("Launching compiler at:", compilerPath); + compilerProcess = spawn(compilerPath, [], { - stdio: 'inherit' + stdio: 'inherit', + windowsHide: false }); compilerProcess.on('error', (err) => { @@ -21,6 +24,7 @@ function startCompiler() { }); } + function createWindow() { const win = new BrowserWindow({ width: 1200, @@ -30,7 +34,7 @@ function createWindow() { } }); - win.loadURL('http://localhost:8080'); + win.loadURL('http://localhost:5173'); } /* ---------------- IPC HANDLERS ---------------- */ @@ -39,13 +43,16 @@ ipcMain.handle('ping-electron', async () => { return 'Pong from Electron main process'; }); -function postToCompiler(pathname, data) { +function postToCompiler(data) { return new Promise((resolve, reject) => { const jsonData = JSON.stringify(data); + console.log("➡ Sending POST to http://127.0.0.1:8081/compile"); + console.log("Payload:", jsonData); + const options = { hostname: '127.0.0.1', - port: 18080, + port: 8081, path: '/compile', method: 'POST', headers: { @@ -55,46 +62,48 @@ function postToCompiler(pathname, data) { }; const req = http.request(options, (res) => { + console.log("⬅ Response status:", res.statusCode); + let body = ''; res.on('data', chunk => body += chunk); res.on('end', () => { + console.log("⬅ Raw response body:", body); try { resolve(JSON.parse(body)); - } catch (e) { - reject(e); + } catch { + resolve({ status: "error", raw: body }); } }); }); - req.on('error', reject); + req.on('error', (err) => { + console.error("HTTP request failed:", err.message); + reject(err); + }); + req.write(jsonData); req.end(); }); } + ipcMain.handle('simulate-project', async (_, projectJson) => { + console.log("IPC simulate-project received in Electron"); try { - const response = await postToCompiler('/api/v1/simulate', { - project: projectJson, - options: {} - }); - + const response = await postToCompiler(projectJson); return response; } catch (err) { + console.error("Compiler request failed:", err.message); return { status: "error", phase: "system", valid: false, - errors: [{ - code: "COMPILER_UNAVAILABLE", - message: "Compiler server not reachable" - }], - warnings: [], - results: null + errors: [{ message: "Compiler server not reachable" }] }; } }); + /* ---------------- APP LIFECYCLE ---------------- */ app.whenReady().then(() => { diff --git a/src/ui/package.json b/src/ui/package.json index 4e7d0a5..f509c72 100644 --- a/src/ui/package.json +++ b/src/ui/package.json @@ -11,7 +11,7 @@ "lint": "eslint .", "preview": "vite preview", "electron": "electron .", - "electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:8080 && electron .\"" + "electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:5173 && electron .\"" }, "dependencies": { "@fontsource/inter": "^5.2.8", diff --git a/src/ui/src/pages/Index.tsx b/src/ui/src/pages/Index.tsx index 9434503..a77563b 100644 --- a/src/ui/src/pages/Index.tsx +++ b/src/ui/src/pages/Index.tsx @@ -4,8 +4,12 @@ import { InspectorPanel } from '@/components/inspector/InspectorPanel'; import { CanvasHeader } from '@/components/header/CanvasHeader'; import { ConfigTabs } from '@/components/panels/ConfigTabs'; import { TooltipProvider } from '@/components/ui/tooltip'; +import { useState } from "react"; +import { toast } from "sonner"; const Index = () => { + const [simulationResult, setSimulationResult] = useState(null); + const handleRunSimulation = async () => { const projectJson = { test: "demo" // replace later with real canvas export @@ -13,8 +17,17 @@ const Index = () => { try { const result = await window.api.simulate(projectJson); - console.log("Simulation response:", result); + + if (!result) { + toast.error("No response from compiler"); + return; + } + + setSimulationResult(result); + toast.success("Simulation completed 🚀"); + } catch (err) { + toast.error("System error: Compiler not reachable"); console.error("Simulation failed:", err); } }; @@ -39,6 +52,14 @@ const Index = () => { + + {/* Simulation Result Overlay */} + {simulationResult && ( +
+

Simulation Output

+
{JSON.stringify(simulationResult, null, 2)}
+
+ )} ); diff --git a/src/ui/vite.config.ts b/src/ui/vite.config.ts index da25c6d..7ba85d8 100644 --- a/src/ui/vite.config.ts +++ b/src/ui/vite.config.ts @@ -7,7 +7,7 @@ import { componentTagger } from "lovable-tagger"; export default defineConfig(({ mode }) => ({ server: { host: "::", - port: 8080, + port: 5173, }, plugins: [react(), mode === "development" && componentTagger()].filter(Boolean), resolve: { From 48567a2f04f9a86e079d2b6c483f85926966cf47 Mon Sep 17 00:00:00 2001 From: Anirudh Date: Sat, 7 Feb 2026 00:26:58 +0530 Subject: [PATCH 3/5] working request resonse architecture --- src/ui/electron/main.cjs | 22 ++-- src/ui/src/lib/irSerializer.ts | 180 +++++++++++++++++++++++++++++++++ src/ui/src/pages/Index.tsx | 94 ++++++++++++++--- 3 files changed, 277 insertions(+), 19 deletions(-) create mode 100644 src/ui/src/lib/irSerializer.ts diff --git a/src/ui/electron/main.cjs b/src/ui/electron/main.cjs index fae30b8..33d4c64 100644 --- a/src/ui/electron/main.cjs +++ b/src/ui/electron/main.cjs @@ -7,12 +7,15 @@ let compilerProcess = null; function startCompiler() { const compilerPath = path.resolve(__dirname, '../../compiler/compiler.exe'); + const compilerDir = path.dirname(compilerPath); console.log("Launching compiler at:", compilerPath); + console.log("Working directory:", compilerDir); compilerProcess = spawn(compilerPath, [], { stdio: 'inherit', - windowsHide: false + windowsHide: true, + cwd: compilerDir // Set working directory to compiler folder }); compilerProcess.on('error', (err) => { @@ -47,8 +50,9 @@ function postToCompiler(data) { return new Promise((resolve, reject) => { const jsonData = JSON.stringify(data); - console.log("➡ Sending POST to http://127.0.0.1:8081/compile"); - console.log("Payload:", jsonData); + console.log("\n[Electron Main] ➡ Sending POST to http://127.0.0.1:8081/compile"); + console.log("[Electron Main] Request body:", JSON.stringify(data, null, 2)); + console.log("[Electron Main] Payload size:", jsonData.length, "bytes"); const options = { hostname: '127.0.0.1', @@ -62,22 +66,26 @@ function postToCompiler(data) { }; const req = http.request(options, (res) => { - console.log("⬅ Response status:", res.statusCode); + console.log("[Electron Main] ⬅ Response status:", res.statusCode); let body = ''; res.on('data', chunk => body += chunk); res.on('end', () => { - console.log("⬅ Raw response body:", body); + console.log("[Electron Main] ⬅ Response received"); + console.log("[Electron Main] Raw response body:", body); try { - resolve(JSON.parse(body)); + const parsed = JSON.parse(body); + console.log("[Electron Main] ✅ Response parsed successfully"); + resolve(parsed); } catch { + console.error("[Electron Main] ❌ Failed to parse response as JSON"); resolve({ status: "error", raw: body }); } }); }); req.on('error', (err) => { - console.error("HTTP request failed:", err.message); + console.error("[Electron Main] ❌ HTTP request failed:", err.message); reject(err); }); diff --git a/src/ui/src/lib/irSerializer.ts b/src/ui/src/lib/irSerializer.ts new file mode 100644 index 0000000..56d5efe --- /dev/null +++ b/src/ui/src/lib/irSerializer.ts @@ -0,0 +1,180 @@ +/** + * Serializes architecture canvas data to IR (Intermediate Representation) format + * that the compiler expects + */ + +import { SimulationExport } from '@/types/simulation'; + +export interface IRHeader { + ir_version: string; + engine_version: string; + seed: number; + time_unit: string; +} + +export interface ComponentConfig { + [key: string]: number | string | boolean | undefined; +} + +export interface Component { + id: number; + type: string; + config: ComponentConfig; +} + +export interface Link { + id: number; + from: number; + to: number; + config: ComponentConfig; +} + +export interface Context { + components: Component[]; + links: Link[]; +} + +export interface IR { + header: IRHeader; + context: Context; +} + +/** + * Convert SimulationExport from canvas to IR format expected by compiler + */ +export function serializeToIR(exportData: SimulationExport): IR { + // Build header + const header: IRHeader = { + ir_version: '1.0', + engine_version: 'simrun-0.1', + seed: 42, + time_unit: 'milliseconds', + }; + + // Build components - convert id from string to positive number + const components: Component[] = exportData.components.map((comp, index) => { + // Generate a positive numeric ID from the string ID + // Use a simple hash: just take last 8 digits if available, or use index + let numericId = 0; + + // Try to extract digits and use the last portion (more unique per component) + const digitsOnly = comp.id.replace(/\D/g, ''); + if (digitsOnly && digitsOnly.length > 0) { + // Take the last 8 characters to get a manageable number + const lastDigits = digitsOnly.slice(-8); + numericId = parseInt(lastDigits, 10); + } + + // If still invalid or 0, use index + 1 (always > 0) + if (!numericId || numericId <= 0 || Number.isNaN(numericId)) { + numericId = index + 1; + console.warn(`[irSerializer] Component "${comp.id}" → ID generated from index: ${numericId}`); + } else { + console.log(`[irSerializer] Component "${comp.id}" → numeric ID: ${numericId}`); + } + + // Build config based on component type + const config: ComponentConfig = {}; + + if (comp.parameters) { + const params = comp.parameters as any; + + switch (comp.type) { + case 'api': + case 'api/service': + config.dist_latency = 'lognormal'; + config.base_median_latency = params.processing_latency_ms || 30; + config.base_variance_latency = 0.8; + config.max_concurrency = params.max_concurrency || 100; + config.queue_capacity = 300; + break; + + case 'database': + config.max_iops = 3000; + config.base_seek_time = params.base_latency_ms || 4; + config.max_concurrency = params.max_concurrency || 1000; + config.queue_capacity = 3000; + break; + + case 'cache': + config.cache_hit_probability = params.hit_rate || 0.7; + config.cache_hit_latency = 0.3; + config.cache_miss_latency = 0.1; + break; + + default: + // Generic parameters + Object.assign(config, params); + } + } + + return { + id: numericId, + type: comp.type, + config, + }; + }); + + // Build links - convert ids to numbers + const links: Link[] = exportData.links.map((link, index) => { + // Extract numeric IDs from source and target + let fromId = 0; + let toId = 0; + + // Helper function to extract numeric ID + const extractNumericId = (nodeId: string): number => { + const digitsOnly = nodeId.replace(/\D/g, ''); + if (digitsOnly && digitsOnly.length > 0) { + const lastDigits = digitsOnly.slice(-8); + return parseInt(lastDigits, 10); + } + return 0; + }; + + fromId = extractNumericId(link.source); + toId = extractNumericId(link.target); + + // Fallback to component 1 if extraction failed + if (!fromId || fromId <= 0 || Number.isNaN(fromId)) { + console.warn(`[irSerializer] Link source "${link.source}" → using default: 1`); + fromId = 1; + } + + if (!toId || toId <= 0 || Number.isNaN(toId)) { + console.warn(`[irSerializer] Link target "${link.target}" → using default: 1`); + toId = 1; + } + + console.log(`[irSerializer] Link: "${link.source}" → "${link.target}" | IDs: ${fromId} → ${toId}`); + + const config: ComponentConfig = {}; + if (link.parameters) { + const params = link.parameters as any; + config.base_latency = params.latency_ms || 1; + config.base_bandwidth_mbps = params.bandwidth_limit || 1000; + config.packet_size_bytes = 1024; + } + + return { + id: index + 100, // Start link IDs from 100 to avoid collision with components + from: fromId, + to: toId, + config, + }; + }); + + return { + header, + context: { + components, + links, + }, + }; +} + +/** + * Wraps IR in the format expected by the compiler server + */ +export function wrapForCompiler(ir: IR): { project: IR } { + return { project: ir }; +} diff --git a/src/ui/src/pages/Index.tsx b/src/ui/src/pages/Index.tsx index a77563b..8bcf9b6 100644 --- a/src/ui/src/pages/Index.tsx +++ b/src/ui/src/pages/Index.tsx @@ -4,31 +4,101 @@ import { InspectorPanel } from '@/components/inspector/InspectorPanel'; import { CanvasHeader } from '@/components/header/CanvasHeader'; import { ConfigTabs } from '@/components/panels/ConfigTabs'; import { TooltipProvider } from '@/components/ui/tooltip'; +import { useArchitectureStore } from '@/store/architectureStore'; +import { useSimulationStore } from '@/store/simulationStore'; import { useState } from "react"; import { toast } from "sonner"; +import { serializeToIR, wrapForCompiler } from '@/lib/irSerializer'; +import { ComponentCategory } from '@/types/architecture'; +import { ComponentParameters, NetworkParameters, DEFAULT_DATABASE_PARAMS, DEFAULT_CACHE_PARAMS, DEFAULT_API_PARAMS, DEFAULT_NETWORK_PARAMS } from '@/types/simulation'; const Index = () => { const [simulationResult, setSimulationResult] = useState(null); + const { nodes, edges } = useArchitectureStore(); + const { routes, workload, faults } = useSimulationStore(); + + const getDefaultParams = (category: ComponentCategory): ComponentParameters => { + switch (category) { + case 'database': + return DEFAULT_DATABASE_PARAMS; + case 'cache': + return DEFAULT_CACHE_PARAMS; + case 'api': + return DEFAULT_API_PARAMS; + case 'network': + return DEFAULT_NETWORK_PARAMS; + default: + return DEFAULT_API_PARAMS; + } + }; const handleRunSimulation = async () => { - const projectJson = { - test: "demo" // replace later with real canvas export - }; + if (nodes.length === 0) { + toast.error("Please add components to the canvas"); + return; + } try { - const result = await window.api.simulate(projectJson); + // Build the architecture export from canvas state + const exportData = { + components: nodes.map((node) => ({ + id: node.id, + type: node.data.category as string, + profile: node.data.profile as string, + position: node.position, + label: node.data.label as string, + parameters: { + ...getDefaultParams(node.data.category as ComponentCategory), + ...(node.data.parameters as ComponentParameters), + }, + })), + links: edges.map((edge) => ({ + id: edge.id, + source: edge.source, + target: edge.target, + parameters: { + ...DEFAULT_NETWORK_PARAMS, + ...((edge.data?.parameters as NetworkParameters) || {}), + }, + })), + routes, + workload, + faults, + metadata: { + version: '1.0.0', + createdAt: new Date().toISOString(), + }, + }; - if (!result) { - toast.error("No response from compiler"); - return; - } + console.log("📤 [UI] Export data:", exportData); + console.log("📤 [UI] Components count:", exportData.components.length); - setSimulationResult(result); - toast.success("Simulation completed 🚀"); + // Serialize to IR format + const ir = serializeToIR(exportData); + console.log("📤 [UI] Serialized IR:", ir); + console.log("📤 [UI] IR Components:", ir.context.components); + + const compilerRequest = wrapForCompiler(ir); + console.log("📤 [UI] Final request to compiler:", compilerRequest); + toast.promise( + window.api.simulate(compilerRequest), + { + loading: 'Running simulation...', + success: (result) => { + console.log("📥 [UI] Response from compiler:", result); + setSimulationResult(result); + return 'Simulation completed 🚀'; + }, + error: (err) => { + console.error("📥 [UI] Error from compiler:", err); + return 'Compiler error - check console'; + } + } + ); } catch (err) { - toast.error("System error: Compiler not reachable"); - console.error("Simulation failed:", err); + console.error("❌ [UI] Failed to prepare simulation:", err); + toast.error("Failed to prepare simulation"); } }; From 07666fd9edb3aff3f24ffaab13b828b84b607eac Mon Sep 17 00:00:00 2001 From: Anirudh Date: Sat, 7 Feb 2026 00:29:36 +0530 Subject: [PATCH 4/5] updated working request response architecture ui shows the ir as the output if no errors, check console for logs --- src/compiler/final_ir.json | 27 +++++++++++++ src/compiler/src/compiler_driver.cpp | 23 ++++++++--- src/compiler/src/profile_repository.cpp | 53 +++++++++++++++++++++++-- src/compiler/src/server.cpp | 29 +++++++++++++- src/compiler/src/validator.cpp | 7 ++++ 5 files changed, 128 insertions(+), 11 deletions(-) create mode 100644 src/compiler/final_ir.json diff --git a/src/compiler/final_ir.json b/src/compiler/final_ir.json new file mode 100644 index 0000000..aab7965 --- /dev/null +++ b/src/compiler/final_ir.json @@ -0,0 +1,27 @@ +{ + "context": { + "components": [ + { + "config": { + "base_median_seek_ms": 5.0, + "base_seek_time": 10, + "base_variance_seek_ms": 0.6, + "bucket_capacity": 8000, + "initial_tokens": 8000, + "max_concurrency": 100, + "max_iops": 3000, + "queue_capacity": 3000, + "seek_model": "lognormal" + }, + "id": 54066296, + "type": "database" + } + ] + }, + "header": { + "engine_version": "simrun-0.1", + "ir_version": "1.0", + "seed": 42, + "time_unit": "milliseconds" + } +} \ No newline at end of file diff --git a/src/compiler/src/compiler_driver.cpp b/src/compiler/src/compiler_driver.cpp index 5af2057..3e04ec7 100644 --- a/src/compiler/src/compiler_driver.cpp +++ b/src/compiler/src/compiler_driver.cpp @@ -4,21 +4,32 @@ #include "profile_resolver.h" #include "ir_serializer.h" #include +#include +#include +namespace fs = std::filesystem; string compileIR(IR& ir) { - // 🔴 VALIDATION STAGE + // VALIDATION STAGE string err = validateIR(ir); if (!err.empty()) { throw runtime_error(err); // propagate to server } - // 🟢 PROFILE RESOLUTION - ProfileRepository repo( - "/home/ishita-tyagi/Desktop/Compiler-Simrun/profiles" - ); + // PROFILE RESOLUTION + std::cout << "📁 Current working directory: " << fs::current_path().string() << std::endl; + + string profilesPath = "./profiles"; + if (!fs::exists(profilesPath)) { + std::cerr << "❌ Profiles directory not found at: " << fs::absolute(profilesPath).string() << std::endl; + throw runtime_error("Profiles directory not found at: " + fs::absolute(profilesPath).string()); + } + + std::cout << "✅ Profiles directory found at: " << fs::absolute(profilesPath).string() << std::endl; + + ProfileRepository repo(profilesPath); ProfileResolver resolver(repo); resolver.resolve(ir); - return writeIRToJsonFile(ir, "/tmp/final_ir.json"); + return writeIRToJsonFile(ir, "./final_ir.json"); } diff --git a/src/compiler/src/profile_repository.cpp b/src/compiler/src/profile_repository.cpp index 21ff5fc..e1f5155 100644 --- a/src/compiler/src/profile_repository.cpp +++ b/src/compiler/src/profile_repository.cpp @@ -1,14 +1,61 @@ #include "profile_repository.h" +#include +#include +#include + +namespace fs = std::filesystem; ProfileRepository::ProfileRepository(const string& root) : root(root) {} YAML::Node ProfileRepository::getComponentProfile(const string& type) { - string path = root + "/components/" + type + "/default.yaml"; - return YAML::LoadFile(path); + string path; + + // Handle special cases for component types + if (type == "api" || type == "api/service") { + path = root + "/components/api/service/default.yaml"; + } else if (type == "database") { + path = root + "/components/database/default.yaml"; + } else if (type == "cache") { + path = root + "/components/cache/default.yaml"; + } else { + // Default to type/default.yaml + path = root + "/components/" + type + "/default.yaml"; + } + + std::cout << "📖 Loading component profile for type '" << type << "': " << path << std::endl; + + if (!fs::exists(path)) { + std::cerr << "❌ Profile file not found: " << path << std::endl; + throw std::runtime_error("bad file: " + path); + } + + try { + YAML::Node profile = YAML::LoadFile(path); + std::cout << "✅ Loaded profile successfully" << std::endl; + return profile; + } catch (const YAML::Exception& e) { + std::cerr << "❌ Error loading YAML: " << e.what() << std::endl; + throw std::runtime_error(string("YAML error in ") + path + ": " + e.what()); + } } YAML::Node ProfileRepository::getNetworkProfile(const string& type) { string path = root + "/networks/" + type + ".yaml"; - return YAML::LoadFile(path); + + std::cout << "📖 Loading network profile: " << path << std::endl; + + if (!fs::exists(path)) { + std::cerr << "❌ Profile file not found: " << path << std::endl; + throw std::runtime_error("bad file: " + path); + } + + try { + YAML::Node profile = YAML::LoadFile(path); + std::cout << "✅ Loaded profile successfully" << std::endl; + return profile; + } catch (const YAML::Exception& e) { + std::cerr << "❌ Error loading YAML: " << e.what() << std::endl; + throw std::runtime_error(string("YAML error in ") + path + ": " + e.what()); + } } diff --git a/src/compiler/src/server.cpp b/src/compiler/src/server.cpp index 4693159..7c4615d 100644 --- a/src/compiler/src/server.cpp +++ b/src/compiler/src/server.cpp @@ -1,17 +1,39 @@ #include #include #include +#include +#include #include "ir_parser.h" #include "compiler_driver.h" +using json = nlohmann::json; + int main() { crow::SimpleApp app; CROW_ROUTE(app, "/compile").methods("POST"_method) ([](const crow::request& req) { try { - IR ir = parseIR(req.body); + std::cout << "\n=== COMPILER REQUEST RECEIVED ===" << std::endl; + std::cout << "Raw body: " << req.body << std::endl; + + json requestBody = json::parse(req.body); + std::cout << "Parsed request successfully" << std::endl; + + string irJson = requestBody["project"].dump(); + std::cout << "Extracted project field: " << irJson << std::endl; + + IR ir = parseIR(irJson); + std::cout << "Parsed IR - Components count: " << ir.context.components.size() << std::endl; + std::cout << "Parsed IR - Links count: " << ir.context.links.size() << std::endl; + + for (size_t i = 0; i < ir.context.components.size(); i++) { + std::cout << " Component " << i << ": id=" << ir.context.components[i].id + << ", type=" << ir.context.components[i].type << std::endl; + } + string path = compileIR(ir); + std::cout << "✅ Compilation successful! Output: " << path << std::endl; ifstream in(path); stringstream ss; @@ -21,10 +43,12 @@ int main() { res.code = 200; res.set_header("Content-Type", "application/json"); res.body = ss.str(); + std::cout << "📤 Sending response (HTTP 200)" << std::endl; return res; } catch (const runtime_error& e) { - // ALIDATION / USER ERROR + // VALIDATION / USER ERROR + std::cerr << "❌ VALIDATION ERROR: " << e.what() << std::endl; return crow::response( 400, string("Validation error: ") + e.what() @@ -32,6 +56,7 @@ int main() { } catch (const exception& e) { // INTERNAL ERROR + std::cerr << "❌ INTERNAL ERROR: " << e.what() << std::endl; return crow::response( 500, string("Internal compiler error: ") + e.what() diff --git a/src/compiler/src/validator.cpp b/src/compiler/src/validator.cpp index c857c36..1c43d33 100644 --- a/src/compiler/src/validator.cpp +++ b/src/compiler/src/validator.cpp @@ -1,4 +1,5 @@ #include "validator.h" +#include string validateIR(const IR& ir) { @@ -7,12 +8,18 @@ string validateIR(const IR& ir) { } for (const auto& c : ir.context.components) { + std::cout << " Validating component: id=" << c.id << ", type=" << c.type << std::endl; + if (c.id <= 0) { + std::cerr << " ❌ Invalid component ID: " << c.id << " (must be > 0)" << std::endl; return "Component id must be positive"; } if (c.type.empty()) { + std::cerr << " ❌ Invalid component type (empty)" << std::endl; return "Component type cannot be empty"; } + + std::cout << " ✅ Component valid" << std::endl; } return ""; // empty = no errors From 295baca1564a8c9d4be29162166e312e88d729c6 Mon Sep 17 00:00:00 2001 From: Anirudh Date: Sun, 8 Feb 2026 10:36:33 +0530 Subject: [PATCH 5/5] updated ui + code readability + added How_to_run.txt --- HOWTO_RUN.txt | 258 ++++++++++++++---- src/compiler/final_ir.json | 2 +- src/compiler/src/compiler_driver.cpp | 6 +- src/compiler/src/profile_repository.cpp | 16 +- src/compiler/src/server.cpp | 8 +- src/compiler/src/validator.cpp | 6 +- src/ui/electron/main.cjs | 6 +- .../components/toolbar/ComponentToolbar.tsx | 8 +- src/ui/src/pages/Index.tsx | 62 ++++- 9 files changed, 282 insertions(+), 90 deletions(-) diff --git a/HOWTO_RUN.txt b/HOWTO_RUN.txt index 509bb6e..1e6c0b5 100644 --- a/HOWTO_RUN.txt +++ b/HOWTO_RUN.txt @@ -1,51 +1,207 @@ -How to run this project (Windows and Linux) - -Prerequisites (both): -- Git -- Node.js (16+) and npm -- CMake (3.18+) -- A C++ compiler/toolchain: Visual Studio (Windows) or gcc/clang + build-essential (Linux) -- vcpkg (if the project uses vcpkg to provide C++ dependencies) - -1) UI (Electron + Vite) - -Install dependencies (both): -- Open a terminal at the repo root -- cd src/ui -- npm install - -Development (live reload + Electron): -- npm run electron:dev - - This runs Vite dev server and launches Electron after the dev server is ready. - -Production build and run: -- npm run build -- npm run electron - - `npm run electron` launches Electron against the built files. - -2) C++ components (compiler / sim) - -Windows (Visual Studio generator): -- Open a Developer PowerShell or MSVC prompt -- cd src/compiler -- mkdir build && cd build -- cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=..\..\vcpkg\scripts\buildsystems\vcpkg.cmake .. -- cmake --build . --config Release -- Run the produced executable from the build output (e.g., `build\Release\.exe`). - -Linux (Makefile / Ninja): -- Open a terminal -- cd src/compiler -- mkdir build && cd build -- cmake -DCMAKE_BUILD_TYPE=Release .. -- cmake --build . -- -j$(nproc) -- Run the produced binary (e.g., `./`). - -Notes: -- If the project uses vcpkg, bootstrap vcpkg and install required packages, then use `-DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake` when calling `cmake`. -- Paths and executable names may vary by platform and CMake configuration; adjust the commands above to match the real CMake target and output location in your build. -- If you only want to run the UI and not rebuild C++ components, follow section (1) only. - -If you want, I can: -- Add a `README` section in `src/ui` with the same commands, -- Or create npm scripts to automate CMake build steps from the repo root. +=============================================================================== + SIMRUN - How to Run +=============================================================================== + +This project is a simulation system with: + - UI: React/TypeScript frontend with Electron desktop shell (Vite) + - Compiler: C++ backend for IR processing and compilation + +Follow the steps below for your platform. + +=============================================================================== + PREREQUISITES (BOTH PLATFORMS) +=============================================================================== + +1. Install Git + - Download from https://git-scm.com/ + +2. Install Node.js (v16 or higher) and npm + - Download from https://nodejs.org/ + - npm is included with Node.js + - Verify: `node --version` and `npm --version` + +3. Install CMake (v3.18+) + - Download from https://cmake.org/download/ + - Verify: `cmake --version` + +4. Install a C++ compiler + + WINDOWS: + - Visual Studio Community 2022 (free) + - Download from https://visualstudio.microsoft.com/downloads/ + - Install with "Desktop development with C++" workload + + LINUX: + - Ubuntu/Debian: `sudo apt-get install build-essential g++ cmake` + - Fedora: `sudo dnf install gcc g++ make cmake` + - Arch: `sudo pacman -S base-devel cmake` + +5. Bootstrap vcpkg (C++ dependency manager) + + WINDOWS (PowerShell): + - Open PowerShell and navigate to the repo root + - .\vcpkg\bootstrap-vcpkg.bat + + LINUX (Bash): + - Open terminal and navigate to the repo root + - ./vcpkg/bootstrap-vcpkg.sh + +=============================================================================== + OPTION 1: RUN UI ONLY (No C++ compilation) +=============================================================================== + +Great if you just want to develop the UI and don't need to rebuild the compiler. + +Steps (Both Windows & Linux): + +1. Navigate to UI directory + cd src/ui + +2. Install Node dependencies + npm install + +3. Start development server (with hot reload) + npm run electron:dev + + This will: + - Start the Vite dev server + - Launch the Electron app + - Auto-reload when you make changes + +4. Build for production (if needed) + npm run build + npm run electron + - Creates optimized build and launches Electron desktop app + +=============================================================================== + OPTION 2: FULL SETUP (UI + C++ Compiler) +=============================================================================== + +If you need to rebuild the C++ compiler component, follow this section. + +--- +WINDOWS (Visual Studio 2022 + CMake) +--- + +1. Open a "Developer PowerShell for VS 2022" (search in Windows Start menu) + +2. Navigate to the compiler directory + cd src\compiler + +3. Create build directory and configure with CMake + mkdir build + cd build + cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=..\..\vcpkg\scripts\buildsystems\vcpkg.cmake .. + +4. Build the project + cmake --build . --config Release + +5. The compiled executable will be in: + build\Release\ + +6. Now run the UI (from repo root) + cd ..\..\src\ui + npm install + npm run electron:dev + +--- +LINUX (CMake + GCC/Clang) +--- + +1. Open a terminal and navigate to the repo root + +2. Navigate to the compiler directory + cd src/compiler + +3. Create build directory and configure with CMake + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../vcpkg/scripts/buildsystems/vcpkg.cmake .. + +4. Build the project + cmake --build . -- -j$(nproc) + + (This uses all available CPU cores for faster compilation) + +5. The compiled binary will be in: + ./ + +6. Now run the UI (from repo root) + cd ../../src/ui + npm install + npm run electron:dev + +=============================================================================== + TROUBLESHOOTING +=============================================================================== + +Issue: CMake can't find dependencies + Solution: Make sure vcpkg is bootstrapped (see Prerequisites step 5) + Ensure you're using the correct path to vcpkg.cmake + +Issue: Cannot find C++ compiler + WINDOWS: Install Visual Studio 2022 with C++ workload + LINUX: Run `sudo apt-get install build-essential` (Ubuntu/Debian) + +Issue: npm install fails + Solution: Clear npm cache and retry + npm cache clean --force + rm -rf node_modules + npm install + +Issue: Electron won't start + Solution: Try running from the repo root in a new terminal + Make sure all npm packages installed successfully + Check console output for specific error messages + +Issue: Port 8081 already in use (compiler server) + Solution: Change the compiler port in src/compiler/src/server.cpp + Or stop the process using port 8081 + +=============================================================================== + PROJECT STRUCTURE +=============================================================================== + +simrun/ +├── src/ +│ ├── ui/ ← React/TypeScript frontend + Electron +│ ├── compiler/ ← C++ compiler backend +│ ├── sim/ ← C++ simulation engine +│ └── analysis/ ← Analysis tools +├── vcpkg/ ← C++ dependency manager +├── HOWTO_RUN.txt ← This file +└── README.md ← Project overview + +=============================================================================== + QUICK REFERENCE +=============================================================================== + +UI Development (Hot Reload): + cd src/ui + npm run electron:dev + +UI Production Build: + cd src/ui + npm run build + npm run electron + +Compiler Build (Windows): + cd src\compiler && mkdir build && cd build + cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=..\..\vcpkg\scripts\buildsystems\vcpkg.cmake .. + cmake --build . --config Release + +Compiler Build (Linux): + cd src/compiler && mkdir build && cd build + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../../vcpkg/scripts/buildsystems/vcpkg.cmake .. + cmake --build . -- -j$(nproc) + +=============================================================================== + GETTING HELP +=============================================================================== + +- Check README.md for project overview +- Check project issues/wiki on GitHub +- Review compiler logs: look for errors in cmake output +- Check browser console in Electron app (press Ctrl+Shift+I) + +=============================================================================== diff --git a/src/compiler/final_ir.json b/src/compiler/final_ir.json index aab7965..8108ae8 100644 --- a/src/compiler/final_ir.json +++ b/src/compiler/final_ir.json @@ -13,7 +13,7 @@ "queue_capacity": 3000, "seek_model": "lognormal" }, - "id": 54066296, + "id": 1631572, "type": "database" } ] diff --git a/src/compiler/src/compiler_driver.cpp b/src/compiler/src/compiler_driver.cpp index 3e04ec7..272424f 100644 --- a/src/compiler/src/compiler_driver.cpp +++ b/src/compiler/src/compiler_driver.cpp @@ -17,15 +17,15 @@ string compileIR(IR& ir) { } // PROFILE RESOLUTION - std::cout << "📁 Current working directory: " << fs::current_path().string() << std::endl; + std::cout << "Current working directory: " << fs::current_path().string() << std::endl; string profilesPath = "./profiles"; if (!fs::exists(profilesPath)) { - std::cerr << "❌ Profiles directory not found at: " << fs::absolute(profilesPath).string() << std::endl; + std::cerr << "Profiles directory not found at: " << fs::absolute(profilesPath).string() << std::endl; throw runtime_error("Profiles directory not found at: " + fs::absolute(profilesPath).string()); } - std::cout << "✅ Profiles directory found at: " << fs::absolute(profilesPath).string() << std::endl; + std::cout << "Profiles directory found at: " << fs::absolute(profilesPath).string() << std::endl; ProfileRepository repo(profilesPath); ProfileResolver resolver(repo); diff --git a/src/compiler/src/profile_repository.cpp b/src/compiler/src/profile_repository.cpp index e1f5155..bfed55b 100644 --- a/src/compiler/src/profile_repository.cpp +++ b/src/compiler/src/profile_repository.cpp @@ -23,19 +23,19 @@ YAML::Node ProfileRepository::getComponentProfile(const string& type) { path = root + "/components/" + type + "/default.yaml"; } - std::cout << "📖 Loading component profile for type '" << type << "': " << path << std::endl; + std::cout << "Loading component profile for type '" << type << "': " << path << std::endl; if (!fs::exists(path)) { - std::cerr << "❌ Profile file not found: " << path << std::endl; + std::cerr << "Profile file not found: " << path << std::endl; throw std::runtime_error("bad file: " + path); } try { YAML::Node profile = YAML::LoadFile(path); - std::cout << "✅ Loaded profile successfully" << std::endl; + std::cout << "Loaded profile successfully" << std::endl; return profile; } catch (const YAML::Exception& e) { - std::cerr << "❌ Error loading YAML: " << e.what() << std::endl; + std::cerr << "Error loading YAML: " << e.what() << std::endl; throw std::runtime_error(string("YAML error in ") + path + ": " + e.what()); } } @@ -43,19 +43,19 @@ YAML::Node ProfileRepository::getComponentProfile(const string& type) { YAML::Node ProfileRepository::getNetworkProfile(const string& type) { string path = root + "/networks/" + type + ".yaml"; - std::cout << "📖 Loading network profile: " << path << std::endl; + std::cout << "Loading network profile: " << path << std::endl; if (!fs::exists(path)) { - std::cerr << "❌ Profile file not found: " << path << std::endl; + std::cerr << "Profile file not found: " << path << std::endl; throw std::runtime_error("bad file: " + path); } try { YAML::Node profile = YAML::LoadFile(path); - std::cout << "✅ Loaded profile successfully" << std::endl; + std::cout << "Loaded profile successfully" << std::endl; return profile; } catch (const YAML::Exception& e) { - std::cerr << "❌ Error loading YAML: " << e.what() << std::endl; + std::cerr << "Error loading YAML: " << e.what() << std::endl; throw std::runtime_error(string("YAML error in ") + path + ": " + e.what()); } } diff --git a/src/compiler/src/server.cpp b/src/compiler/src/server.cpp index 7c4615d..d940c05 100644 --- a/src/compiler/src/server.cpp +++ b/src/compiler/src/server.cpp @@ -33,7 +33,7 @@ int main() { } string path = compileIR(ir); - std::cout << "✅ Compilation successful! Output: " << path << std::endl; + std::cout << "Compilation successful! Output: " << path << std::endl; ifstream in(path); stringstream ss; @@ -43,12 +43,12 @@ int main() { res.code = 200; res.set_header("Content-Type", "application/json"); res.body = ss.str(); - std::cout << "📤 Sending response (HTTP 200)" << std::endl; + std::cout << "Sending response (HTTP 200)" << std::endl; return res; } catch (const runtime_error& e) { // VALIDATION / USER ERROR - std::cerr << "❌ VALIDATION ERROR: " << e.what() << std::endl; + std::cerr << "VALIDATION ERROR: " << e.what() << std::endl; return crow::response( 400, string("Validation error: ") + e.what() @@ -56,7 +56,7 @@ int main() { } catch (const exception& e) { // INTERNAL ERROR - std::cerr << "❌ INTERNAL ERROR: " << e.what() << std::endl; + std::cerr << "INTERNAL ERROR: " << e.what() << std::endl; return crow::response( 500, string("Internal compiler error: ") + e.what() diff --git a/src/compiler/src/validator.cpp b/src/compiler/src/validator.cpp index 1c43d33..8d0097c 100644 --- a/src/compiler/src/validator.cpp +++ b/src/compiler/src/validator.cpp @@ -11,15 +11,15 @@ string validateIR(const IR& ir) { std::cout << " Validating component: id=" << c.id << ", type=" << c.type << std::endl; if (c.id <= 0) { - std::cerr << " ❌ Invalid component ID: " << c.id << " (must be > 0)" << std::endl; + std::cerr << " Invalid component ID: " << c.id << " (must be > 0)" << std::endl; return "Component id must be positive"; } if (c.type.empty()) { - std::cerr << " ❌ Invalid component type (empty)" << std::endl; + std::cerr << " Invalid component type (empty)" << std::endl; return "Component type cannot be empty"; } - std::cout << " ✅ Component valid" << std::endl; + std::cout << " Component valid" << std::endl; } return ""; // empty = no errors diff --git a/src/ui/electron/main.cjs b/src/ui/electron/main.cjs index 33d4c64..9af4fe3 100644 --- a/src/ui/electron/main.cjs +++ b/src/ui/electron/main.cjs @@ -75,17 +75,17 @@ function postToCompiler(data) { console.log("[Electron Main] Raw response body:", body); try { const parsed = JSON.parse(body); - console.log("[Electron Main] ✅ Response parsed successfully"); + console.log("[Electron Main] Response parsed successfully"); resolve(parsed); } catch { - console.error("[Electron Main] ❌ Failed to parse response as JSON"); + console.error("[Electron Main] Failed to parse response as JSON"); resolve({ status: "error", raw: body }); } }); }); req.on('error', (err) => { - console.error("[Electron Main] ❌ HTTP request failed:", err.message); + console.error("[Electron Main] HTTP request failed:", err.message); reject(err); }); diff --git a/src/ui/src/components/toolbar/ComponentToolbar.tsx b/src/ui/src/components/toolbar/ComponentToolbar.tsx index b084404..aba7a0e 100644 --- a/src/ui/src/components/toolbar/ComponentToolbar.tsx +++ b/src/ui/src/components/toolbar/ComponentToolbar.tsx @@ -14,10 +14,10 @@ interface ToolbarSectionProps { } const categoryIcons: Record = { - database: '💾', - cache: '⚡', - api: '🌐', - network: '🔗', + database: '', + cache: '', + api: '', + network: '', }; const categoryGradients: Record = { diff --git a/src/ui/src/pages/Index.tsx b/src/ui/src/pages/Index.tsx index 8bcf9b6..205cecb 100644 --- a/src/ui/src/pages/Index.tsx +++ b/src/ui/src/pages/Index.tsx @@ -14,6 +14,8 @@ import { ComponentParameters, NetworkParameters, DEFAULT_DATABASE_PARAMS, DEFAUL const Index = () => { const [simulationResult, setSimulationResult] = useState(null); + const [isOutputMinimized, setIsOutputMinimized] = useState(false); + const [isOutputClosed, setIsOutputClosed] = useState(false); const { nodes, edges } = useArchitectureStore(); const { routes, workload, faults } = useSimulationStore(); @@ -70,34 +72,36 @@ const Index = () => { }, }; - console.log("📤 [UI] Export data:", exportData); - console.log("📤 [UI] Components count:", exportData.components.length); + console.log("[UI] Export data:", exportData); + console.log("[UI] Components count:", exportData.components.length); // Serialize to IR format const ir = serializeToIR(exportData); - console.log("📤 [UI] Serialized IR:", ir); - console.log("📤 [UI] IR Components:", ir.context.components); + console.log("[UI] Serialized IR:", ir); + console.log("[UI] IR Components:", ir.context.components); const compilerRequest = wrapForCompiler(ir); - console.log("📤 [UI] Final request to compiler:", compilerRequest); + console.log("[UI] Final request to compiler:", compilerRequest); toast.promise( window.api.simulate(compilerRequest), { loading: 'Running simulation...', success: (result) => { - console.log("📥 [UI] Response from compiler:", result); + console.log("[UI] Response from compiler:", result); setSimulationResult(result); - return 'Simulation completed 🚀'; + setIsOutputClosed(false); + setIsOutputMinimized(false); + return 'Simulation completed'; }, error: (err) => { - console.error("📥 [UI] Error from compiler:", err); + console.error("[UI] Error from compiler:", err); return 'Compiler error - check console'; } } ); } catch (err) { - console.error("❌ [UI] Failed to prepare simulation:", err); + console.error("[UI] Failed to prepare simulation:", err); toast.error("Failed to prepare simulation"); } }; @@ -124,12 +128,44 @@ const Index = () => { {/* Simulation Result Overlay */} - {simulationResult && ( -
-

Simulation Output

-
{JSON.stringify(simulationResult, null, 2)}
+ {simulationResult && !isOutputClosed && ( +
+
+

Simulation Output

+
+ + +
+
+ {!isOutputMinimized && ( +
+
{JSON.stringify(simulationResult, null, 2)}
+
+ )}
)} + + {/* Floating button to reopen output */} + {simulationResult && isOutputClosed && ( + + )}
);