From 7d3acb38f2b24d31e1e4f2fd3ad6a6b2e91548e1 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 20 May 2026 11:54:24 +0200 Subject: [PATCH 1/7] Component profiling --- docs/Profiling Component Paint.md | 228 ++++++ docs/images/yup_component_profiler.png | Bin 0 -> 422081 bytes examples/graphics/CMakeLists.txt | 1 + .../source/examples/PaintProfilerDemo.h | 714 ++++++++++++++++++ examples/graphics/source/main.cpp | 2 + modules/yup_gui/component/yup_Component.cpp | 211 +++++- modules/yup_gui/component/yup_Component.h | 74 +- modules/yup_gui/native/yup_Windowing_sdl2.cpp | 69 +- .../profiling/yup_PaintProfileSample.h | 157 ++++ .../profiling/yup_PaintProfileStats.cpp | 226 ++++++ .../yup_gui/profiling/yup_PaintProfileStats.h | 128 ++++ .../yup_gui/profiling/yup_PaintProfiler.cpp | 309 ++++++++ modules/yup_gui/profiling/yup_PaintProfiler.h | 256 +++++++ modules/yup_gui/yup_gui.cpp | 2 + modules/yup_gui/yup_gui.h | 26 +- .../bindings/yup_YupGui_bindings.cpp | 3 + tests/yup_gui/yup_Component.cpp | 13 +- tests/yup_gui/yup_PaintProfileStats.cpp | 447 +++++++++++ 18 files changed, 2839 insertions(+), 27 deletions(-) create mode 100644 docs/Profiling Component Paint.md create mode 100644 docs/images/yup_component_profiler.png create mode 100644 examples/graphics/source/examples/PaintProfilerDemo.h create mode 100644 modules/yup_gui/profiling/yup_PaintProfileSample.h create mode 100644 modules/yup_gui/profiling/yup_PaintProfileStats.cpp create mode 100644 modules/yup_gui/profiling/yup_PaintProfileStats.h create mode 100644 modules/yup_gui/profiling/yup_PaintProfiler.cpp create mode 100644 modules/yup_gui/profiling/yup_PaintProfiler.h create mode 100644 tests/yup_gui/yup_PaintProfileStats.cpp diff --git a/docs/Profiling Component Paint.md b/docs/Profiling Component Paint.md new file mode 100644 index 000000000..019385c2d --- /dev/null +++ b/docs/Profiling Component Paint.md @@ -0,0 +1,228 @@ +# Measuring Component Paint Speed + +This guide explains how to use YUP's built-in paint profiling system to measure the rendering cost of individual components and identify bottlenecks in your UI. + +## Overview + +YUP's `PaintProfiler` is a process-wide singleton that records per-component paint timings broken into four categories: + +| Category | Meaning | +|---|---| +| **self** | Time inside the component's own `paint()` callback | +| **children** | Time spent painting all direct and indirect children | +| **framework** | Time for framework bookkeeping (clip setup, transform, etc.) | +| **total** | Full elapsed time for the complete paint pass | + +Samples are stored in a per-component ring buffer (default capacity: 300 frames). Statistical summaries — min, max, mean, p50, p95, p99 — are computed on demand from the stored samples. + +--- + +## Step 1 — Enable the Build Flag + +Paint profiling is compiled out by default. Add the preprocessor definition to your target in CMake: + +```cmake +yup_standalone_app ( + TARGET_NAME MyApp + DEFINITIONS + YUP_ENABLE_COMPONENT_PAINT_PROFILING=1 + MODULES + yup::yup_gui + # ... other modules +) +``` + +Without this flag every profiling call is a no-op and produces no overhead in release builds. + +--- + +## Step 2 — Start a Session + +The recommended API is `PaintProfiler::startSession()`, which returns a `ScopedSession`. The session enables profiling on the entire component subtree rooted at the component you pass in, and disables it automatically when the handle is destroyed. + +```cpp +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + std::unique_ptr profileSession; +#endif + +// In your component constructor or initialisation: +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + profileSession = yup::PaintProfiler::getInstance().startSession (*this); +#endif +``` + +Guard every profiling call with `#if YUP_ENABLE_COMPONENT_PAINT_PROFILING` so the code compiles and runs correctly in builds without the flag. + +### Session options + +Pass a `PaintProfileOptions` struct to control the session's behaviour: + +```cpp +yup::PaintProfileOptions options; +options.sampleCapacity = 600; // retain 600 frames of history +options.minimumSampleMicros = 50.0; // discard samples shorter than 50 µs +options.includeBounds = true; // record component bounds per sample +options.includeRepaintArea = true; // record dirty rect per sample +options.includeInvisibleComponents = false; // should invisible components be included +options.recordSkippedSelfPaint = true; // track child-only cost even with no paint() + +profileSession = yup::PaintProfiler::getInstance().startSession (*this, options); +``` + +--- + +## Step 3 — Take Snapshots + +A `Snapshot` is an immutable, point-in-time view of every registered component's statistics. Call `createSnapshot()` on the session at whatever rate you need — a 10 Hz timer is typical for a dashboard display. + +```cpp +void timerCallback() override +{ +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + if (profileSession == nullptr || profileSession->isPaused()) + return; + + auto snap = profileSession->createSnapshot (yup::PaintProfileTimeKind::total, 32); + // use snap ... +#endif +} +``` + +`createSnapshot` accepts: +- **sortBy** — which time kind determines the descending sort order (default `total`). +- **histogramBuckets** — bucket count for the global frame histogram (default 32). + +The returned `Snapshot` contains: + +```cpp +struct Snapshot +{ + uint64 frameIndex; // frame counter at snapshot time + std::vector components; // one entry per registered component + PaintProfileSummary globalFrameTotal; // per-frame total across all components + PaintProfileHistogram globalFrameHistogram; +}; +``` + +Each `ComponentEntry` gives you: + +```cpp +struct ComponentEntry +{ + String name; // component title at snapshot time + PaintProfileStats* stats; // live pointer — may be stale after destruction + PaintProfileSummary self; + PaintProfileSummary children; + PaintProfileSummary framework; + PaintProfileSummary total; +}; +``` + +A `PaintProfileSummary` exposes: `lastMicros`, `minMicros`, `maxMicros`, `meanMicros`, `p50Micros`, `p95Micros`, `p99Micros`, and `sampleCount`. + +--- + +## Step 4 — Interpret the Data + +### Performance thresholds + +| Range | Meaning | +|---|---| +| < 500 µs | Normal — no action needed | +| 500 µs – 2 ms | Warm — worth investigating if sustained | +| > 2 ms | Hot — likely causing dropped frames at 60 Hz | + +At 60 Hz, the full frame budget is ~16.7 ms. A single component that consistently takes > 2 ms for its own paint is a significant contributor. + +### Reading a summary + +```cpp +const auto& entry = snap.components[0]; + +// Is the component itself expensive, or is it due to children? +double selfCost = entry.self.p95Micros; +double childrenCost = entry.children.p95Micros; + +// p95 is the most useful signal: it captures spikes while ignoring outliers +double worstNormal = entry.total.p95Micros; +``` + +Use **p95** as the primary signal. `maxMicros` is useful for catching spikes, but a single GC or OS event can inflate it. `meanMicros` smooths over spikes that matter. + +### Log a snapshot to the console + +```cpp +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING +auto snap = profileSession->createSnapshot (yup::PaintProfileTimeKind::total, 32); + +yup::Logger::outputDebugString ("Paint profile — frame " + yup::String (snap.frameIndex)); +yup::Logger::outputDebugString (yup::String::formatted ("%-30s %9s %9s %9s %9s", "Widget", "last", "mean", "p95", "max")); +for (const auto& entry : snap.components) +{ + yup::Logger::outputDebugString ( + yup::String::formatted ("%-30s %7.2f ms %7.2f ms %7.2f ms %7.2f ms", + entry.name.toRawUTF8(), + entry.total.lastMicros / 1000.0, + entry.total.meanMicros / 1000.0, + entry.total.p95Micros / 1000.0, + entry.total.maxMicros / 1000.0)); +} +#endif +``` + +--- + +## Step 5 — Inspect Raw Samples + +When you need more detail than aggregated statistics, pull the ring buffer directly: + +```cpp +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING +if (auto* stats = myComponent.getPaintProfileStats()) +{ + const auto samples = stats->copySamples(); // chronological order, oldest first + + for (const auto& s : samples) + { + // s.selfMicros, s.childrenMicros, s.frameworkMicros, s.totalMicros + // s.frameIndex, s.paintIndex + // s.componentBounds, s.repaintArea + // s.renderContinuous, s.selfPaintSkipped + } + + auto summary = stats->summarize (yup::PaintProfileTimeKind::total); + auto histogram = stats->createHistogram (yup::PaintProfileTimeKind::self, 32); +} +#endif +``` + +`copySamples()` returns samples in chronological order regardless of the ring-buffer write position. + +--- + +## Step 6 — Reset and Pause + +Clear accumulated history after a layout change or before a timed benchmark: + +```cpp +profileSession->reset(); // clears all ring buffers for this session's components +``` + +Temporarily suppress recording without destroying the session: + +```cpp +profileSession->setPaused (true); +// ... do something that should not be measured ... +profileSession->setPaused (false); +``` + +--- + +## Tips for Accurate Measurements + +- **Warm up first.** Discard the first second of data after a `reset()` — the JIT-equivalent effects (GPU shader compilation, OS scheduling) inflate early samples. +- **Isolate one change at a time.** Use `setPaused(true)` on the session while switching components so the history stays clean. +- **Prefer p95 over max.** A single OS preemption can produce a multi-millisecond outlier that distorts `maxMicros`. +- **Separate self from children.** A high `total` with a low `self` means the component's own paint is fine but its children are costly — recurse down the tree. +- **Check `renderContinuous`.** Samples with `renderContinuous = true` in the ring buffer indicate the component is requesting continuous repaints (animation loops). Every such component adds baseline CPU pressure even when nothing is animating visually. +- **Use `setOpaque(true)`.** Opaque components allow the renderer to skip painting the background beneath them. It is one of the cheapest paint optimisations available. diff --git a/docs/images/yup_component_profiler.png b/docs/images/yup_component_profiler.png new file mode 100644 index 0000000000000000000000000000000000000000..6710f31c65e40bc1a4867d8c1840e202b6bb418d GIT binary patch literal 422081 zcmb@ubwHHM*EmiI($ckrq=Izp(jW?=q)JJ5NG!c{g9t1wAWH};N_WT79g1}AQcHK| zZ|}X{`?>G?dB6YtmOq|(o|!o_bLN~gr-n!kH6>yKdIAg#3}WSHPhMhR;0|G6U^Cyv zMSt;NVU0sSaIEE3rAAz@P!c>NTa%6&jYh%2ukX7~JUcT?{Ntatv&A2^0N?5n+pg^Jf_Y0}ToN!_LP1 zPi;2V-?g|y+1P)Vv6=s9m=W8H#K6E3wtcPZrmLzVVeaI>XKLYOX2}O}0RPbdLkc2+ zE;?AcnX*6}>>XVtAkwUVwva%V|M<+$%JOFux3|))x~dv13QjJTEMj~Dd;+X81S~8p zQZ5!&5-*=9{_c)`lV-JXa|288^Lu)F@_7pLIk{N#3yO=2^9u;^3kmU}TkyJiIl7rb zcpY8Y{sQthoF|s9<}S8iH(Mu1mOtQ{nmM_20{$JmIx0mAo1Fio;^Iv=T=U4P5$`DBL|3eTm1X(njAs85P7|KuNUqdjrn(%5F zyWKf;NySl5aIje9$uZ;wl;T;RaK|Tbyzfh}R6em&9For}%GmdodRru2tt6b_*>urW zzD&pSw&)4B2D!2(B{nTw3T|uy<@M8Oscp>A$eqzo*yy-CysK7de?k8t#IGk$C{x`FT@!eawHN5DDWZ1JMKZi} zd_TDlBD2C#bg}v1APVf|?!{D6vdwcVB6e1rEyWmskBz{^Y^2;z>SjbYR_65glIea$ zXZpLPy3luG#5aH!Wn2Wj{~`aw{ebU9@*%i-deSE{_N8{A=K6sBe0vY+~X zQ$1~Ge;B{Cn;0K^S)a(Ip0?B-o98T*2orae0L5aZk0l>H*2|1ZiZ#Y*>n_F5H_~R3 zNl#IA)uWs^q2M$#AXA?@u&1xJHxe7P)HFC(Pkrb7RLZiy!WL2PH6@br)OkhLl(ma$ zKZ$qvYf%5H<){I5XYy@mB&|-zt7@rqT)w}6>D>JP4D6uxv5{CHzmzKp{V#J|(vxAB zLIjDjALh5wL;aTXGT~nA2MN_5)}0wcDY0Ah=#ZyJ<75&O~w>-2g)S53NW}l*%of_*cQ{Twiop| z-4SF{f{L&y5|J`lk;gOW7t48^Ay7)TQyOzKS>JlkI?dgb_z zPR1lTgyh8_cPlI>?1o2U8+MmF z94ad-%{qX8)njhhH-T<~TYA>Fad27qN=hR^006M~>hBR95|C1rtylph<#p z)9sH-{-)bIRX)>0gb?l z_b{-C-n;T#rPws{aeScNuLrK{94V7j)?90WW~q zmF@Tes{o)Q%;&^+YoBU$KV*IpRgns_{nRp?mHQ>`vGwiRb9Nv@azZ6bY*1pBBn=yn z1QbEnZD;VmR{ZC5OiY9^xaeWl6kKXb}L&G0{GM1#V zc^F^ZS5UOp&N!YNvs4;f)65-=ULPIEl=hj`W-xl+^*;yu`z^>DcP*^ncJ%AVWj3s1 z+Ck0#wN7-qY+fRhFugSqg=svO&q#UPg@+9`>rYP@tdxkgQ})NKxYRSj=Y%wTm9+{R zB8QZAD*qQ^vjZ`uT+Px0++kGrzI6WA$~1Vfdr#hfQh8(h0rcZ)JW6iAh+(d#PYnk4 z8OZ`U3sGUArvKnDG&gNOuWTK6_F&;1efMvo_zy@HQv^KddIOYr?+Y!OuGb`S6M8F} z-x}*{|FgEB4LUI4fSsAGD4l;@NOa9}+GW#Zx@rfQpkKYX|5a@W$BML=UzKgh+eU;ynHas^uLX6iLDL5k1?yx^yuI zp>8PSi_x<+Ni4s1R^D$N%35t&0junx`Gej<+g?pBGRq zejLktCQ$qd;>axHTRT9u7$ktLo<7TPW16vP*Uqx_5SUI1CiF8UU*?sMxez zY!nbXHTNNCc;75rywX3qJm}|7Ki-^3XK-r#0moOuyx5*^nkm$;8G_09O8V}wFRYcAZ=e@~XBHD(>pY^cCg6NL$fS)D|Tw_L&kzAS2Hr3L_1`Qy{ zFvkQucfMK#7PfRY&DkgLcGZLgBlz%rFH5BK>lA#w@=n=pb92aPPhk+6UeDpcla<;u{rIq*Vk%v1Ups~;pA(NtcDeQA% z@7c%}d7&JZTI9i zK~E4N-o!>q5qKqf!x1yqSCUpeZB2-{R)tv$gJ9*)h>tRT^FTnQ&rcvht+C{0Va4nd z=5FLX_AS`3^@Zfmlm`-qOf{N+b4`(Db{fjz=iQ0KPYMzA-pJSkhU+1;Og2>CmwItX z0a#%0tA*JE>Ww_6EO*XH53y520_R7VZ?g$k;Zn%wH*`uOb*B4aS z{7pv*b-T@%unH_SvO?~*4pGhrd!!W9;CzH45hhT-!fMb3Xi!Vnj?>%dbqGs*5Sv;K zNx-zm0GJ)|HyjWbglUA=Bp}%X*)TDk^jdL2USdx3_N56Vz(`c4PqDsbs6;8v`5=zU z>=Gv}rVyDxo!gK&sul$ENqxZ0V0L1$0yo9a16>GBGbaMZ}e*zk`;AVlh_T#qHHL{mY6&4MOvs{m^Cm2O+f^VwmP!NcYoVYgH5M@%Rq`vx_rebuMl-vSSmv=ZOO;~0Q_TX8 zVJ&*u`kb|}O+JuVmrSw1DXx24v0f!`iHHIO*2tCyaUkx&RqZNfXuGz0)x=CiS=yrb zn^O-$#zInzyuZ6v1_~GEG_2)B!4&RDwUxcQQMk=^su1e+0C9c7!`f=kXSTP!i{k#d zWZNH{Z6P(p~_>% z9{9$?Jz_i}0Jm;0o+Mm)Z{&`*ygCSI3Ov38aE1i7GHk*Fv+Uok_pgL7N3(%Q?@Maq zl}833vMIFplxt42f!NN`t>Q2AwdMKjTV*E+y%5+-^!hG=0fhsh88)QOix^H~ZPYzE zP9t!#u=+J)7p&YEd-z#vU64KeBo^Ej6d)D7Plch^%?u()C0HrM#cKKX@4EJa+|c-CPX7*h~avf*!~n3%%}lSbsj?;&076;vKfpRDDIU*w|f%SF{m z|9uuq(vDDBZ=2}N*z{mH_T3X8gQoXx7B>v3c9|z&C9bBrMPTDntX3viOcWaylQ@o) zJ830%O3GKsrjB&S@LVrhO8E~++`Bg-Ryslv)ZBZ=8tb6cg=4r31?RYh`@7sjSWyB? z?}As4#4NUv2XI0AC%18l_$%N?8Uct^dQ3HP#3u%T^0x>E@E$9^Te~_>*horT#7#Fu zj$TdS+>eqIGI)IZTgN_vVnV9zFi{3LS3gB-wUchLqruc^ z5`!2Z_YF6V@WzkNd_q3-JT)?ci|W&}>*9w`Cz^1i3LV@nX!)%t`L$zY(vaEQVDLvR zPTl3-ich>d{P97awY)d9vw|ZtWUnyFMGA#H|G0{M7L@~W>^#)b?AcIoKzz}XdiB#z zP%2<39XKpKp`dP%wU@vOu!RhLVf5aE-I2~_kWOra+QWU(1hJLMq$mFO(V&4l-5OX7 zdW+XTt*C$trg#^aF4XumEYeHmL;L>zq4 z%p(pjqcjYciE>R+e{!BQ(btA~33~;O#Kg3u91(k**}R+-4Dd~X*5)O@_Huuw-qSJj zzOstzXTr!DCeLna&Qeq#grSsz=kX_5SodAXv*1I*<7{IiX+CV&C%%hhKmxe>2e%M( z#W@;?(-;(a^W=dr zIA7{*t^0sft@`7D+%vymIz3KPjiFHB&ml*Q=l@gAl&xEc=VLwOL4 z`RFTM@+-!^VV{}k(h*`(!sS^w0rL(HE5IKa&DKq~l_#~PD3*XdNHs0He3mP68)ihy zWx-G#7&-(_xX;2&BFMxN3(%wWsl32H-os_;;*61=-5U)d1qjnJ+HWVI+GdUUUpPI5jJLCS}rr|OXLOZN@r8fK( zjGbls;9>3#4Fm83zB%DY=4;AtX5h%*@mWjK&?x_#;_n{bgK}G548vhZz8wsotlwlR zIeT|?RnTP$?mtTRyk_^Eclu*9&!dW8L9B8!tk=BaR-e;LnF+qURjd$v>QFc+sX#^|~n=o-&H$F67R0YZgD0g4)f;w(| zK9hKAkIOm0;4p}*gt2UHmZ?1}M*z)YT4OIGs18oCt}ok(jc2P<<^h{?>8do zT^AYTS4xRxr1{C7m?_=`_Eo#u^m|e@Ru`Q8<|TIy=fVxIgI=!Dnu*eF96<0gcu@#( z59`(@g^9aVg4pY5FEEz8T{~&XH0K9{C*tn4-;`yFIEr{47Q)-Xb`d`h%f+KOk`yPZ zbCgoMeoTt{U}>M#ulHf6CG{9mSAr8_zxrwC4P3q(+!dQKG#R;q{@*9=y87r}V+$h&#k#xCAdAKOmsZs)b z_tfl6Ern)O|1kM4Z_t~5x%oq}O#aeb+{{;H353IpU{)_m|a|`R3F341Klk()Ans$6Yer8z?a}-CJFq+>gPTk9^dcIam9m9dAw$ zGd5l1O%WCz9%rZE!`PxDoBlvmk7EKXfCTtuD}Jz(KNZrIip-+THiDt2F_3iXu~VU2 zD~^=gV-|*kjn^3w3>qpYA?k(G?dhhKZ}7b16cVN#EJ#iF2$ja~&=??YuG>C_%ffsni-Tc)dU{FW ze&Ebcq=MlHsgMe42e=;gyp1oPaWgFcX@Dj(pf&A1FFl$~qp&!y=-1Ox?;hp9vS6#4 z8{j{}oG8UxaBLUE;9>*icnI==ea&(x3U=VKjM!^03PltaG~o&~pw9MJ_8fE<~vQBpGt4}Q^co$^)puZLDZ<%PsgXiQ} ztZAzfiaB32n&F2NXhy7XkqC1?y6Jqu{IZ)aK%SkmZgi#dXx#U2+g@m74b7PJkmfd5 z6{id<2xnJ+55&LCRcGr6g2nkVsGde4G@-NeBNd!r6s1fIqnyNVBd>emyA`JAcsGak@H~K9{ZrwlGP!Q}Em- z7{+P1R&#gZbH00`1UsI$$pLfX)reE3yAe`V2(;Jd|MtCw*kM#8!(KR*y6*RoT^o5) z5Ix*k%!2EC`ASmwE5ggtL^cxO=^8&MZH+-Ybfx9x`8RB@WjV|Uu$czJ<=e1k7o(sq z9j;^dU!kM^%#dP=be{xOo51a`s?*ZkPVSp9j7f&eFM?Ix?)i zoubT>IV0-_?~f*2{@zG|xTg6}R8nt$3KM2Zm-XWobu2=d_@cW)wJ-0v`Xifx- z0M{a{2ziphhhc&EWV3Om2_LKL`=?2}Dd%*poGuV7Z85Z@F?#?VEr8gFm_Jx39tue( zsy5}Ig5j5GX#nRTx#>Nvz+`U*L?K$>hEjAlB}ZOB7)Tm_J}=?6(0+*RC#SD`@3twP z6pzWms{6xh&W-kUYQn*_85KsmmKt-SZn`elE!r<068kibf1r>-`#xO8J=NWeKVJ+=#Dc`UIHjOsf~qxgJka%{2^^G+k?>P5+PKuaOtg z$v?_!u8_Lz{lJ)FWMhz8O1Jx1?QctFK{(KwLdpjn6CjVdpI97E-bjgE2O;@Plm6wH z9_f7vn|oIM;UDj_mH;Bf?e%?C%Lmwxajk|kx0`K`&z52vv>3mIGc@M#-XbvGn;rld zV)hbn;(hKWFs0WO?oFa_3zCUg|Jn?T6!Tm+C|b+H-CHDXYW;xzTk+H1JMIU^C>DG={N8em+jWkc zjlrcLQ~%raiO|Ud?Z4f%aRS*;Vf+{Gzei(kg$**kn5(t>LMK$Z!cbkG8;GCQ7+AFH zmi&TA_@fRLwnSIH*~^vR)`CboM%FL32)f}Al|JP_g-oU^&Y_A* zBYB+dMM;4&r&h|>B|JNBUhV{M!~ZYutsEcr2B`nbQ(^s144Bod^LW08geu?sP=c?V zCu%4o<7@rK=rHYw;P|k_>%V-}+5NPEucEO4s_tq++>frRGKD##5Iw;Psv-Xud^8C? z!VdXZ^zHa>2l&529}oI509I!-gi}H;)s_VUGzNouA9@D%^EyBN{4GiU)%Z^*el`@X zp^Rzf(EZI<|HLUYM6s8-*_3qK$E-wmbr2SZnL>FV-CODwo{;49R>%B;^8AwhuTFo) zIOLSkPEYLwfw14+)PKSreR5v7LjEOd`NAmO7bz*{Z)84Hs@`jU90PM%sT!sKe?V(P zpTBPG{{ixQhI0LMJrcEu&lu8vgHzrlN5e`Tb?~ zf9+S2C0w#S)wLfVU)tb-s!rlmZGld~z@gt|-dj!n?wS=%`d9yW^#8}s^a%)9tPmFT zBdGq-CI5o}xh!D;o4t{bBtt7!OVW4FV2!p?D_Su-0ZECf?QH8pJY1n zdnWAjOf)gX^*J3ju_M)jZFjvY>IMDRMot176S-pXY*mSfa4pPzO~9YDxv?{b0v*RD z*QGyS{3En}BipbKL%ab2$aPB8WD@VJwSBGVrI$y4fUj^MfElD**+oG%FBp%|Ub~Ee;E%!4L1ZcWQj(>AZb4nPke|_&O}|?XQi5@~f`y43tjr5A&>3d-0vc zE0?sgvh|sSW6YE(U*Dd4Z?twT9~oXq2s+fRdRbv&H8%9{NMsaM3ij&bSS`g)yJh{x6veO77BKofJ;r+}1 zrVo}BOqV1}M&l&KFNL{}(pQ7Mq-BDby1Zi8`O-`GC@djsLnTXsy%zN96E!nNDn^&v zz5Qs{>{S*%YMZQmlZY=xAiam=-{5@ ztgJClbPSX9&@8xJa?o{H8bD3?nXhq=-t}y6&i$L$;fK`Ds1hOmmd0tAlvhr1V_Gz* z#o0DjF{bQ-F&f*B16``B#SW|0s~8fM^mKgK;m(##=il%{Epq5;G6g|3`Ubb&*?!}F z#W)l{x%hw4Kano3jTY@)gtOW+v8=q_DMd&or@?`SZx>7^Bj>@(-jc0Pk}z<;Q!U^R zx=LJL=@9ffmJp4dNi1R8#g=kI;TZ)+&ga}~PfC9EOU*dN)#tz+jUR&uU1qRKUU$^F zLl-jMNz~~@TLwEUy8FTpw*18~|@<2lFSfG}yQLc~dTeo9};{^rx6%qDo_?RCJGFnxz(({XN2 zvPEq~^wg}JuMTDM3Q)$sp=}nb^Rlf3XLLWDfbx-~*d11Vl3qjSYL7E$AAOf)&R)XZ z)%S|{p?h!DEa^RJSXOGzZwjE2j4gFdEE2^$i;ftX%=rv0)u;KO8pR8f10><#&a0T3 z#2!Z3x-{|vp0+1j_+#Xi90?T9w;Ph+Oh8?e*SRclY=}3Ide36}O)WTwxK<9BgJgJ$Qy|q(y62 zaout*WpRvXwCI1ZEx5gsGQB%syi&7!8Fm_EVgFp9w=kOd@Lc=(5b3$-OnkrBx}i^I z#Jn?Vg^1GM(vJoCg`0>O-w){Df7o`cwn)LLQbv-+GuU+MKVv^v-)dQ`cNpsaQB@d~ z74Y3_IX-JzYVQLWXxjF=L1Nq8sxL`zwQ53)!KB7%Vfm{zlJZUck#~reR)J1QDM_v9 z>aXvKYO7u-L;IFHK0yuL-p6A!gVR;&bypqn%Q@@J_QQ9(r^Hc@1kr&$O~`0}jbW5*HSj+lw3?|-8N51=nj@$iE64(SsAS1>Z(Mwy zDmDEg?z~v*P6-v$RR)@O8C3Y3idEQ+Evb<_3_2;PU5s&z>a*;hchFhj1){^cWh9*w z=@mmColbWA2JL6hg0E}(9J#y-DjYU`=~2s$Ju>!BNdr2?59-^Ll9PfeeU8?UzpU)6 zS#JBfoE8KqWtC22WCkm_kvhS)Umc1@eQ@72FA}8`w*|6&dT^H|=x*<~#0OlhIK(x; z`!8en8NS3*mDQd&Tkr)kAFh+h`0jR=`HXgDJemNePZd)*FV4OxLfQb!;jp2My3+S$nJ~%NK(RI zx}MOC++RGL3|>T79)hD(2El2s@Tw@Zx|eJcOt7u?jB=S)5u>=jxJRPHUX0TU{ARoC ze8^UjEth2ihV{pkER`KZx>eP463VFDkqOo1mFpscM6QNYuYoJvHV~d* zYB$c&9WZ{l&YJyB?bk90&sj_r)v8Ws#uK$k7s*$a=i7~CQ=V7PYZFb*R0B}^GebXU ztH<6+2E^>6I!eXVy`n=GZor0%eRxziKI^^NZ7{WmWGhVEP~4RA zZWXWMYq{dw^!o)GusW5*g662@0K# zz)RwBUg~w|joNxlas=6~;vLe%!<&Ckbz18q4?=s;GS;-aF!AP|8T&RkpkvSD@@Jpj zF^p{Xn#6GYjn{>^&)Vw>fZE&{0>Poo~O{5$^**;Ce*~< zhe+0Mc2{G{7!ay_gWPwZT{wKLFFYZqNO{eW_9;_NXW?`f}AyGGeUP7-$~TyLT#>aJqT-g9L3@$ zZ$h86mZ#q3m-mRj)7nA04$q}+kf?4;c(`2 zsa1^nJ1O2RsyLi=rAd8TTsOYTg_9LV*`4Ur0UIdCRd@gJODeec-xbmJTofa)|azgnHSZwG3zi_=er$=QVA54})% z)ZMYQp9*0Hp9_iu*dlc}xaH`~P2VPn z<{5RHdZu-y_EDr0osN(YyejR9R@d(KrsfkY&0HVl-Gki2KZ^8?A;YI?T&2_%6-m(g_YVdFnJ;OuMV2LMyT6Cqm zZZTc2&ID^5*kG^Fxq2e9x933EC=p39Ix&l(@Z>SApjoBi_Q_}c?Qkk5baGb(wAfhJ zdcMT|vg9+g0c1u3l`t#^wo^%$X!OZpy5~UC|p?0u%T0MT0lz$Ccn>_C^E?!o885InhL_e!FaT36y)M z`(2meSAWNHZlnB!!~%=4G_sRP+O|+LTF>3~5HdC1c89Ap+b7{EW#5Gg;XvFO(w&)_8S!8i;!_n}tvg(k zFZiV+0GlcjYxKc|O+KC=C8}z*#?_DdTLe{_xKMUqb%)*g3=*1(NGM_8+D*S!X~0)? z*%_G64tct4kHiWT$+$&s&eZ%czV7R`F&f*$z zn7NChxiciK{n0e4Yu9g=`TOMbO@0L<^a)e;ZVYgKr~FyU-c8#nP056^v!f5!`k1ks zroUtXmpKZZc#6}$-xNbr0t!*ALYOBdzG9(sCs+9zsrG_1B?zmC)>D(6E%~VeD1{BF zmIK3~u>0ZsFdjepH8rsV{uyzU%d4Dl*S8)zoJ$--jKUAa#JpDg;f9u+IE{BdYj>7p zKO8S;f|}*b;LU@EQSa;ojB;X}9`tg^65&44s~Fd~vg1C5`8@pB<^bVaAc+3!v7 zgu>qizGp!u6PJgCcH;=*cWGyD((LfSMx&3anrsfe?Sq&gok|mxdS^yP^M*?)l<>A{M5vmH1(CK`o1q#LG6wlcn@*Hf6$4n);Sa5U* z8c6LA9@g`yDSRs%U#U%GoJ3mzsa+pa9(IoFgK39T1>4mmNIbNVlZ?Vv_8GKES?=0G zI{EKInWn+NbbYT zBPq7T>%H^NxJMCy>izyIZ#tjJb;0j+vS@}$xzqHida!c23IC9$9+XoJW@9x3Ti2fA z?6J7QB8|8QPy`o(o9}hkE@57S4+ovf3$#3@9VWHEK279QttM%@FK--2GWu1uV#)by zyIJyXp&q2n^zj=SvS>Yo38Cz1f($wdUcFmdYuQh3R&y$v&U#E+(rYK2m|>$fO~~^3 z2=17?eu{z1_l$Q7WP5Tes0`0$cRN7&%wW@Fz2dBFy!9;V$-AB+avqt6p?RBl%&6BN zP6_ouH0<5Z!P%Q^M`==CE*jf3EwvL;dvI)dCJs1b7g2`J8m;1jf=t)o(R#0E0fjWG zY|}tpVmzFP&VDB2vDvm=)+G%4l-H?_V~}m?QSN4r?`&sMiV0*68}FocH`G*=3QOCz z>7efoiSw!KT7hc%c)e4WX)^sCP@&L;c$xM$fAX zzckc>{Q|&qi3a2kRsPv)O#dpWJGO%3MR8fdw2_$S+;Q^9MsrcG+U{I>5Q#6W`($g% zbeL_XFyxlxaN8+h-gi?!tD+^VqM);JGbuA#a^uA=TPjQ^N`L{yzcPxUdDonXE05_zJWaCApkQfg z-l4^Nfoij53)p*=VrJX&QP#12p3-R7FIV1ewEQ%F)|0?`U_<_- z8bMv>s15v0swyZ)y>h04;aY|Q7xm*GdA+ttr|XXXr0_JEZA z9Jrw9N7sDF&m~%;L3iBYo=BarUNS>@Y7__G&>?GUN8O>zBJKR+!&%c!8GGRS$RTmp zp=zfC=E?%U@iec)RY~i1bc(KB^Z8&&LsxOjjrS%zV;4pX8NE%j&aCF)nMn6++B6*U zx*Aa+op$;$ivVbP&hCfQQzaWL**8*MjjLfzef@bw;47)|1t+A zz#H)Rtn2Xb_LB>q)r?)=lnk5&3nuTi`>vy^z`A__n-LRqhCJD2M)t}Hz{9aVj1{0K zd)^y6z_4&;b!qsif9~A&*SGl9A4<$+w@g)PIWGp1ndJfEp@*kCai8UFj2FpA5;GMejh@M@N#*i=P>=C(S(9M(&?12yEia zIQm~LG1r~UUySPmjPukoDredqMA2yXn_+_C^@`$3zy(7EBgA$Zc8yMZmWiqYOg5wV ziz@{Ex48CaoC0Ef^vu!X(qn8m%7dZF+HQ<|j)h?&;_@xe)coxY>E!lNrm(uqdFaY6 zeU0JXP)3P(#NsP;>6NY%_lc&VzHGs_yZ-i+JYQp(q^&NGRENaFn=ybX_7@?tX9|btWaOD$ z-3+JZld2MsbgLwkr*O@G<2zSjCTaRa(~dVV92~v4LTP|%zMR{wz46&=#oIdG%{@ui zq0vR*0$3yM*D(Al%$d$jSuWdW1+=I*lct9#wF8^>+Lk<4#Nv+L^D{k@`-VbM9mRR|F zyjwLyEy!gLwy=T+JipY;f~v}N)!xMmu)!^A`z@aY_ZI0swG!kHCQCp9+X%}?HKHRW zmR{0{v7()?NFkmWopvX1vuh-vj@-Y_!LN@{hn;%3tc>Ih+1E#&Wip5hVjTZ%(cWVW zm>HD9=a*HDeMc3|1A`U=Kw>JKD@YyAPVu>`Ni^o?mgS6A%{d+^QzgYiU3alj)d%Kn ze%sUTxI-oP6~d=$l80R=3VZQ$#tVxglx0T_C@Y#gVU_bq!ji(LBQL*?m&fcqLm9}I{He6 zeOGTQQMI|a3x&an#3amxtHI`E`l4-QIC+~og-dqmiz6Pae(|nuaA#a`^RDP>=ojXO zLk=Sh-BObv*J`y4i9r|1X_srW!TeCk$};Dr@Hd&x{A?y+;}b16qNwPwkh^M)9pM%n z<0zTa1$%vKSj8s#T7*EX>`kicS@W(RGkED9RISkavW@2EM-zCj*mG_NX2YW+gMz@t z>1Nn+cFTx4>_ZcA&FL`9TWPe(mL!e9TX70I+fKKlD1pZex?jS?pp24M^Oy6d4PxVk z%FXGaOBDP-xcq4dv#)F^nFAuV)lR^Esi%E?)MiE(Z%kpF?lfPo{)imK61w#02ceDZ zPT-y0vj`BD(IouLu*th>%(mI9ox#zC-@+uBacj}^bjQ#`YhDB;b$e3NvJN$E%r1lM zhYe|lRU@{7Dqo%+;H@PSN~B!#apPboj4MnXI3_H4;b?OVUTQ;h315A;pi#nv z7yX%#MVU=_K+{aZ!E*0X^-kX}d_|T*73`fpo&}rkQKrq(>n{Z%R8DbKW}QtRYAp1h zRmN!fOe!9rWN+)G)uXGs;ZKX_-3F_HBYq z?Alt{uHf~3?GFt%Ca%WQBd5>`ZQa=1FK93Jx*?H;sRea!vdR0Sjqn3jCOMi4?AM2G zZ#pjJ+A`MW6@RL0W6yi!YeYQ3xxzIU>|(4CoW`47&Ocibk`&}aKK+R|Ta6ARMYHp* zV@JZMO|y+md-mSuDH7(tQ?w3>Zsz-dmT@?*pF)tdtq{!HPl+WZb$!+R2##9<^1I|y zJ$0^2LU|5Qvc1jMOYT@j68GcH%`@Hru+1U$xFq(`CRlY;rtE(ADra_{km$H`gH=LP z60V*@-{OB&8`HMjd&}-HX5;X+SJGOhxB*^g5@0x8460~(IMihuMt88rtRqR)DkP{J z&HEKi<{R@ryDhl2*-fyh^hFm{y=G~1ctxTD&isjsKErX)_Z;y6xMnGQO_RRsFN~l3 zQj>6~pb$unlQrl1+N~Ec`_u#L@N@cPm_PWl=?kGAcFDGMjY)gL1_{bd=93o#R(xFH z$S2AIfQ2IGp%*Sv_A}LEbRoMGrlKU;nTQ4SCBZprPcY21sz2u`;ozomKrTZ7nB{(< zVZ(T{SIbE8%lat^gufY=II!+&nbfJk^=z)xw8@Y|U`QN_&<#?!J49Icu8o@!)EC#~ z{Jz&qWy`z@g|-9d(EcMG{Nsa=8gX&8Lk*@7^QN=ZWRrtw{6p|8q7gIw9s+bQBgiR% zguNSk(sHxeg46~S=~eU{J3r{9EnIBVZ9Tt-IYd_o4L-bsX@KOw#wq;TR!5{ymx&hb z+B;&WDAmyA$z5mEb1)th*%LNOto8s0bPSehUQXzr z&F3s+e-gNTh-&|I*jO~N1Q6|sFn?c-@Hz$S< zZ|UNa`xpy5PvBly<@d9j%#qGRZT+ z3c)6404@W^6HxcpbERP2%gN)YAG(G74-+fAj|n8_ zb(XdDnqe^WF7Yw69@*dyDr9LuWjc+muwgGqhEPBO&VWkab3>`LF0XVR?b*atHY{tp z8|m|9KY1DQNdj`WY<=gy{}%w}Rk8kQ^y7+8=4AOQ-?u zw|r{*I#{{Y?;cW2>0`=qPzivsrI8n(pFG;BdRvf;pS*~cUvsAxmfyvhG8MERw?Hcl zplTObVmE&tY|1Jr%#FC?_T_$7!^o$kSmmcIKly73AH8SKM*K+^YdkENv!$72nt)VDsiFmVS;&Us$28w$G5YeABwk^4vtx- z7$O1AsW`-zW?I8Gl67u9D~CcIWydty+-DdW-Uc!U0%=+HVHUHY{G2wQQYHo`RJPsq zNX z!uRD0a!N0V3RJxwERswv3gRT8p0*hRu=OZE&yHmsvS7~8nT1gTXeX`6_I-BhW~M?; z$Pn;u0s#U9HtJQO$bF*ZR{02r6U14>($@F9wFdc6xEJ_afx0*t1{Z9@cHRlN<~A(^ zy#PG2p4ASM^kCT)of+^$*J(KbwwrgqR#m0s1J+MYdk zsQF3m0T(>#x_kSX?;a=_Vdo?<>F3wz!lu2#A2Bv>@Ffh;&FucS}fJIxo`QacPiLx!`c{G7gSlsg^<~)m_4lf}@N@>4cQ~)$I0xp;wXdWQUxF zP0+zzyVwEcvQoQAWNbprtIRX`E7?ogTNd2IFkl7jT^_eo-(T7D-u4O}2DGi}>mKU8 z9LUHc6@u@`&GuA=vzPB=#%ThXBjvmZ6vD)GQ2rzmS z)hoFi$inN2yhk>Jl8$uua_rh(Z}T5E$^uEE!y=jB@(1D69S)gvyz;=$E&ytWg2R83 z3zH1}1|7gt@B`Xj26B=Tkd8`tA8D1t?9NnljL!VvA_OF+GVwq#%&)OhRn{3o(ME=+BW&dX=eg zmO79AE->fsR0YO4&(wYW_~1kd5rQ=hR3k~Gw)xM?TwTXE+u8QZrAiuxud?XBRNWeN z_&XieOOh@Ia?xj6QG+k{cNq z%4*D#T!+VbBh52o9(*#}9bAg`cNt$CUaXQOWAiT?W9pgW7rm`#4Gh4Tms#^h-`+f3 z@4vDSv$>!nYc5)R;~%zQ*7LTlIS4{BVyI<{GJ74uLef+dc30y{S$}e{foK zsc4pocTFCcvb0<$AZfIuZYL4n-_Yk={XrlCtr-W;nNve4%8-- z)EUMztc1%-8~iIO!wsYB8pI~)>$KUly94kditPpi0`$VR?rYXtA(VJI&N@(qv!7IE$gUZpmA`I z`>Ou?DgpWso=LV`mK7p3A_}5-ksWb=%uC1&+QUs_!VC?G8?^#~t^7p^2F+VH#4}=A z!6V{cY=ta%O;PMJHG;?IIL*ml_k-Od`8`UlFYG zQHlTXvlh!nMiit{8PY%EFB#7m3_Iy`4~-T=4{lh*y~c)-^F{ZNu=W2~^PYCV$0FFp zxy!*}J4klN!F4Hi!ou3xeVgL`39sG~xzKf3hG8aFD#tMR)B`>6si2>q|959Q=@+@m zV!wKvuK7E(iniPEXT`_rsO@eWz3;K7Ao-$`b`5A_hO_Vcix$Fpyh)?x^y>Cd_&P!l zdn<#q&&cb$alBQx%IsTv%5NJ-%Qo8ie5GP2*6D+cpX~2@r8Bz_6Y`@z%SqG3{))Vo zIT(cObCkz8DwX47Y4*7Y{>Bce~aNov6`8GFVuUioA_Gm*>RqAoB- zGW3~V4)iLKUxX39#qk98ueS5@q2JSr^8Fxzq#4WY{UIV3@4T{vR>%sk6$uAU{a<8Q z#yUMcK%L=uHoJ|+T`#v+I>IF|oWXhA8L`ubPoCR>`RDYaqU~b!mZK*ALbF7Am3{Z4 zln-I^ocPQUEk_21YV8eG08OC7_a=r+;NYTn5Zl4JL*Oz@>E5emw4AoPi3e0mTkq*% zRWpiKAFc-^%ALB6GrD%e&w1)W-StV?_Z#-jwsKW#INP?!4nKH5ae-?N#rXLD#mDZb z$@70OC~ucj$~c#fB(`fv^jaWf;N&ofbkbt6E2N5&~7f*hwMpS zh7uK{wgG_LVe0;ZrKW-lnmlwy&gE?5{Zt`&M^oZ8ea6$}eJ=;au*YhXF#uF-ohLq9 zfiZt?V6)Wkid?ffbsrOaXSdG=W9HVc18-JwVc~nQPn=-Wy1~sDk_l500hiL71J{fa zR4Gdas87G8r-yY;Ao6(5?GIL_!Avut54 za6|)%dh`vM-U?)zu_Dz^hz4^W;GH+%Ly2EbxwD4+dJ;>QV=*@*uygfw(gdn+A?F)kz*gGO_z6;Z5b$^_=G&7`BwBN=iK}}vD)mV5bP)O z`ZI+Rfam{;6nIyZQ#Ibp=$8s|ri3r*8@e_&0MKaR-&m!!@pO5n9pc4z!#iu+%eQUn zTyP)Mmjn%3!(s@`>?isZ{KGq>>}peG&~AIv2fBb7CI!uV)9aNPVs6XI5*P<@!c1<|#!p3t5bc_8LffbpQdF(0&VEjzV-ATc zDLoplTC2`?hsUnWRx2qhKU>!!4Ig68A3OIbE{NbPl_bk`fCS!15L^vVDl?Ox*rw}m z<>%V@3V#HNqaaw7e(efp1%nY^I^wlsHhLXi|ch7J1vV_M`I-yW3JP6DKk&R|!{i-MpO_1OQHaO)6;m>*Ig7>mU=) zAfe(J4o8ZJKRJLolHZ}Wj5Y=l?*#b*vZb?6qAiU=HfSD$L6`#jc6>fQL%fgTeyj=+ zi!5VCF$J;w_k4rB8*`y7+luTUbD(65 z*HUIJ8{<= zk=h`^VVb2|TD6vOzyV^+Aj^@OwBz3|WrHAPRU9+=?C?Z4Z7dj~~vo750f!lz1X1Ktx5{WBEqV#>7&nIF(Z`DQDnofUu??b+7J zlTNSL*dou`G|@`+!a_AmVPdw%qQa?I-}{u#&U_khy#*}hr^?bZ#oc1{wGkO85X~%_ z#3}3v_>C&--f8HV2WGXB=FJgpUHnSWB;Pc zaU_Q^XZY$RTz)s1#=EyUyDRjG}r7?CU*WuHEkM9^U*_jLCH za8Z}LSKj?uv0i?~T%neFl>CMRz`~{uROc;lxUX%jkqCg6Z0h;F%4%mMP{?erm$Zki zf`b?8qZ_}7x8e4?stChA*Eq^rABgls3`WTo8>e%$i1~J)5b>kV#`xank!c(J6(m%x zg-I}s6C;5Het#mhnm`XsFhZMuG?b+r+3|A)8PMK4-aW@IRuAj>mN3BUKJB(8;msxj z&!(T#H&YivIH}u`N0DwvS6zQEU5gC6x6QZt6RZB2i)YH?EqC~E)<;-bo99{>VU!X4 zcd+fd4$Mj|KOv{B4-Ik$sG`^4KRQ^SX@MF$c{=!onL_npbwMY&8K6W=x!@5no7w7F zz~o$PVynD1h`sQW)+9-Y1kM*>XjWc(7TW2}KOsC4zjnA%-}Rxl(Cz0g4F@6;e;;Fm z?1ta>R~|&6N0g1p04}$wnE{HT1%*xBd&k73YK9oUVri*GY~Pbnvt_0SkU7MK-e1G! zwuvYB`vH+)^32yK=|b>oDcS2y;>~F;#yuolH;e9EL27WB!V*Jim}2PJx?o`pvg({v zKZvC>ab1)9-F|4S7E3#_PmF{jc`zuU&VzVL03Ry=mZuz4M~<4z(qC1jC?T2h>B$64 z5P&&nN5bYp%blu{15FsN5H-<9dg9D0hY*AvtFnc5YG_;$jlg{fTvT6KCAs_ap z-=E0|R!zAKf5$d^E4Uw72QRnyX(gCOWZ*QSI_yy+mGr-yrL;K=_127K3h8%1h9X7{ z?D7RoQTIuEwc=`Z#5RP#qZi2YMAj%Jg(Qf}eqn_W)M)#!TK8@^C@l8~uz^?_hdB~q zjLiD%& zh`P^p$jM0;?&O}!SPUf_sBFL(h~)@?z^xSck?6}Odvr2q?O5z$5e_D>o|g+Pam>+@7OI=-zxV-eO)v=wOK9?@rlTIj5Hy9@ zg%~&ThYA@IO3bXMfYmjR9(d*t57jKB*rxmT_Bf!pv1I5+${2b4-)r+xX)B&=g;AJ>$Sw-MR7KOnutBUth}$RGaDL=X|0ESU|}i z=*2I?yvZB;yaUZOsTjUCe4Oo(3WT||eSAls>j9u)8=8z7Wrk#T@7xYRG&zj#x>_Zp z)W6A$)d68y)(($e#8#Im!|-g-vV^!xaUWA7)MXI!FjbJM~C#^MAiY|KuZvhj0 ztO|~k>qBz4tmO@=6}_zp4NUaB3{39NOre5D zCJ(R2YtGLEp2Hi!<~$T`8~CnfXX8o%C5$?aOc9pWH8AjK^D?AaLe-vib@Q{)2+6+z zk*mu3uexluoansOeEBED?~%Qi4#wjZf0zYF=T5pvMC;0zOG(H$r6ZoQk(L^CB;x8^ zeww-ajKF~?12b^>P9~$k*t{1tPMr6L6P$-#+XlET$Xz#4jxbD5E?y)7#Au0^XdAT{ z)cjZS>B@gTmqbSNmq~Rvbf(~9P1!vkm!aknWQ3Eyj^`_c=~a|}7`Fr_2dMK@?xtCgrPD#(*b_kK zNRNNs4D8_r?Bax zP<)l?WO67lsdS<-;*(Itjw4GnRvML&P~Jq^IJJ~-DK$W zU+cci#z!;v2C5Dr#4SZXlk-?HgnaWT+r!mT67J{#xM&e+9?`3>J?SlP8?K&b#N7MM z{JuV{|Na}GehZ_`Qkg}C-~L$5yWfhi;7O0tVO_YKbXwDh5CDa7VQtDiy_F@<43P%xAMHuMMY8 zY`}EQr~UhLlCE)RZw*-L#3XE4&HT^>-scm?z4y}4oGz1cWDib z!;0j7pbxj0s)MnZIS&gxxN`A+o;GOF#!-4-M7cLJpFoF$S14%NF`BE;x)#Ic4J-+9P%ZVqEt@9(#-duUq7x}Pcm1~$TV$Uaqv zgSQtTF1rsdY!MHbdh&r=GnS%GQ?d?+At!?zoJX|0-MyLHd`oX2lnGrNK1ACKJ+&(- zjl*Rt1vO0(z)M}_-A_|0S%ElBKJLqbs_cc4S4vql10D8PA|a4XfyuKo_e{meb5phA z?0g*9wU?L`W;k=#k3d88LWT6q@XhsdRhNTrt%5DSnkshG|u);T8M*5 z5jPw445qTzB8gJcry0ZyB8A}USY00b4q&A8rX}-dRa}1x)h<4y=zLEGNcxxTBB0#X)_RLT2Y3fRO90KoiMDP_yrXZTBG~Xj);Amb5 zxOiBadJaP-I$DL4Ltk9NmatolrzuvECa)Xh69xA>*XI?8nF;(pj z%*U1Rucks^YjWdjO(Gz1V_9)CqPWurlT=wjRB1ctw{Zq)pjU!!Th7&;2Uu+&DapEW z*akj*q~%zs{u^?Wv5};2#Shaw#twHpNqS>+DOcZ@BqDs;?Fn>T?UTZ9lAc>EX0)=D z=3w6Gx#tbRZBwF(@hs@m9grw5$hxb5k&hKJWfkWL2bRP#=zsv5&O#-)-$3wdrZz%EVUG)5zslk& z(YrX$$YwztM)AORl@Dd%LU9PCi;9uSo2=iEC~J`d4ORX@HXuM5(Q*FE^p$n)^B|_g zo_Y^CgoZ3Vh5KlM$~eZ9x*mB}jGE`810yKzJvBj`5vTfG`iBxDAS)JNicIj_fO8HW z9dK-`+mR&z%PjH*D?d=q$$HlCu>NihSEq@o0W)GPu!HVhrZOibjYby=Xb zpTDTdH2)OSM=um}VJS`l%I6VnqD*flGL2P)X`FAy zwj7%h^fJ+mkHV}1^I_~9W!i0hFM{peYCpJfJm_@TmzLQLu=TSQaj+)<>Ae@|_?aR{ zi00=6)C9C<4v{;JZ)!jM*wCHK(u?z?gMH&9(aC}48>1KIq;5sfMPaggEA)^>;A3$~ zaKHO|au|c*{<|+>n4B>8Ih3sURejGXHL17cYwRHU%b(M{z%y+k9-Y}3_Iz)w;E(=Y zEhV1YAQCTX_{SJkoV^mLrkZridv|hk?H1i>Y@cz4YV$j^JaTQdUNdlrX@lJ2-Dk(J zfdQt3tuxhxw`j3OZ`F<)B-Ky9CS@oxq{Rq@l_Lcap%dXNFkh21`Y0z0$@)HTLRwoF z!9v1&*FVFVrP@HlbG0H(=vjj;6P7h*qZv=YAt0k?IOq| zV*8FrY2e2*>i=SsAU7C=3Za{C4wa+7aXn?G(e%FBa)An+t*U-^WRd>nJX)TN}H zt22!y6!FmAqMWTgQh}Ke9Zjb0T)0RZn??m3paV4iugZ0lN8Y1{`6DWPl8ikGKC_9F zG3bauH$fCYXd4U6KQ)Q8w0Ze_sN?-*wX5gKkTkf<(2|sLFfdUxLZ=^L|Me;{A3f}r z?4Udq7dk4K$8j-bYa zU>vR0+79wlJnQZ8Uz0K6rqeUCA>m9=9~p4M7u-Y+16LbfSqu4M9@mUhdb-wr#k~&$ z1%V)Rrvi#0@zczB{8XxUk)|dKr{Hj7eh%tQ_aN3NE(883Kb{sUV3%|Sx$;Akelx5F zU5Z^qzmM$-i|l6RqN0X2%r0z&egFa-L~pR^&gyAD)1_1f6@KOB(W!UjpQWftBgN~e zw25QYGt(}Z_pgxZ&^SrYY=jqx=d}IGb_{A@Ry9Lb4aWYQOnQaDyfT_&9lP?&5#)Ef ziL4RzhLKnqkG6&LInzf>LBKt@ItpYtastV0&XGI9i&?MaIF9z2+G z*FK_k#d&>1tC!f*-MIenx+~GPM07=f4d3f|9*(cSC8h7hJPsf(gn~M3?WTC4og#6u zU-+0C$}ZD(PUwqYr>RN$zUCdH`=N27o3x8mkS*ARTf8@D2jR+Be~Fg093QexjWQr| zZ!$qhZme7`Q;w{f@5MYAVIwh*h2-RP7kK)r$3dug4KirsBn$~D#ffaTQAyiMdG1K~ zRJ!-`{k0^3QVck=hogZ1AB#pa;{D=`nG~AUyaO6;j4)|Q*+A~xJIS4b(PQ>z%Y#8@=ndA+cs?)bfc1=TW_%0Th!p9EkVZN_oeE90hi!#G@ z$$8kUWbpg9iN204xZx4Et}7YO)75fv8m`Z+htp2q`w>;*YGU|ceI{(^N*^{n2NAc! z2*P+#rE4ZO8SQ7*G^h$>6fV;?H-SIIuBVZv@8L7t?Pw`3yzQ(Lw3Q)1GhF%e<5r32 z!q(aH)ouT`iO`N+(2wiyKmyj=&u2`HgAAQ?fYWrg*BmPpFmTL{qnV3RLufqgd{9@`k4Y6xiZlX1&CzWlFw!D22c%xwz$v|3JLmsU0&4z|{SJQ^s$ z?AIxhEBI*yP#ARmFK5|2TL9hcz|xHPO_cnRg8}WHEPHM<>2ov}o{!cA^ybt^)Gl7> zEN|U1Qe*-UW!TXfs+yRQ#z?@_!pXo05-P?J}2={0oSfuPf&I+Ag3d z#@c*T>6(>0R3Ks|o+BdR0JdTu&r5h@r*f$dXN3miFOpB{QJ5Rg4Q_?|f0|m4#673? zT^^zVqO_z!mx(~`DQPI%mS(;VRn20UiGdj^E`(r}4%oR%mdPw{(_6IJ3Ia^*)J?YNjI|Wjd5oPZJywz)ORlXRyM66Cimmsx zE!U6*_?YY;Y1xRG7zH#+LWPpM^CE;39??y4;@@^VBV>`HJua1!sv6Q{7-@?^`Nt*L zV|rM1m{ADa(B_&^J-l&>?s|2xTE29!OOt`bgyQUOR_j9iWC-;wPZb3HN@aKbb>nuN zY6U**eXqD*Qr2}4Fm*I66rDQwCYtAIH{o1g1#`r9&Y4+Y{x@!2aL-^uPkmV4zt+ER5?QVx_ zIP!cQ1n^JsSEC0HaTh>dCLjc;cLs2qhIfLV2>iK5)8ay_+BQ-YV*p(04=`G)mxn{N zM5_vKIn#vToERXWYJS_>rY~75U=nDO(}*RBY)13)zQ;J|$amx)HT26$3SXh2r*9;t zsg45?Z3Y=Hge4W7PY_&)8Pr{E5;_qXh#5KfWIhi_ma38|fIQdtH4URT^@k7w+bBmC z@7#3UEl8t6g@c|f{SseK5%ZcblahKbv}XMK=P1;>1b&R~+b&EYd07A6y^b}McakO{ zJQv0nGe2tRomQflF|RBhSg4x3KSKSMPI`!uNMs5lofI+X}` z3WMgNNRkw4ajUCe&Wd{BW;o}@`QDKhrB1q{kglQPW@DrU2RXPJ$1Om;eIssspVm>f zE+IoUr7b?VF#7Wi!xI^+c7TYLjSVZixjgt46m}&Qf$50mEN@oM2rTMWwJpCjU@| zd8V*~joBc7^jgz{OppLneX)Kk^yt@z6V86Y_A5$3bCIVy%{}Mlqj>bKa7mn1;@6a z;ZCco;1c>jgg?g_uxprQanmRtn6$}nqoDdGn%PlYO67ulcYGQsM&Mh zAGdJfJbVTmqxaqABI^jSb-%8DjsS1|X55MBclkuwTyrgryP*Q$PC#S6-_VR{o87l-K|tS>G7r52oH%|CFbC{QxfR z!613Lcurklm}^ASRQQPBR8u1(+Uc+Sy)a8twH*7f(@a)cB*Zd+I~Nsd2W%jd|}sq$3Ouqb=S@xn6oA zWkRUW1ZsabqXiphF+bapMDIRrU|_-ko&bUyFJ9kf&;tYO8r{mfPV%l$GD08j!i|rb zqQQIn$vqN{nD9hAtaUz;6ck%vabK#oj@k~ruf$73b6+*p`{tC7JD|h56HrZE(xcf` zk&pYiHGKtAZr%v{b&5f$?K$Y@NMzGQpk%eoX=pBmQ*#@ZuO?SU9XLy`debXd^m11A z+6<9QvDTwT>Q9oM1M)+OOR2F?gXm-5tSfUP%@(QX?3TuF;j;s<({3lnmR>W;64!T} zH0XV&=XvV#$LVq~iOJ(*3{gJ3NGA`@{K8!=`0{smeNXG7CP# zkNrkMFw-eN{vJUn_;kkZ+$eY`HA6q{h!xLI-|{=7HEX9~CrqQ-0Z>;6VM-}gZ6 zn$^mi^QUdP=^<46RJ)~z!rduZj}bkys^#Wwp7Tjc+fAkm!K~$<0hwWgVb#CkRd;<{cV8KH(v zFB_RGT1GR9MNIYjrttZ9=u;$f^MD;sIAI#)ou~mjL>o4F$fxAw&Tng|tW-t$2AnMp_saLw=^LOY|<%H^7xR&s-Qm^Lh(rt zNk-K!+>3%QP1Y6f-e;dz1A6u_q`WBu;UBd;#cDrGWWd>7NpgJ5fli z!|U~EHGy|BCDavV?oyMIyJfV5Is&GkrvK_1^I9}LPOBvvD~34-J8Kb6!z^|u8J4Of z=R39z_Bfwcwl=1@${h3u4Ogf0yVLs%AdTt4jAb;p4)-V{-er@em(WDz<%!ggUCcm}lVkTAFHFaJh4nMtP^r|o(9 zHi?+CEhRbZmp_w>B%q?#4S=cNcZ|@nm#yxR@`XhwnWxZ-9v{SQMYyWtXsEtBwuiQi zmIdBE;KDhy>X2ZmkaSC-IlJ@g-+#+%bl0)@3~$mghb8vguTA$uZ>N^oIG#4;Nr$;y zdoXd?v7fev$q>wkH>XZtz)&(&QzEn3?S9=rp{Le+$~x>8i8p0Xy-kgDOD3=pEnpp(0U{Y40DI_p}Hujs0d^hXd~-L zzE>F$A->A^!GvrF4P=pSsS$rk%#S?G8t&dq&ARd|7|xcFt@4W#^L?v)08eS08-8$` zd9ExeH7Glj-i z578GGO+Ku}`TNnXrPHt3XPW9fgfeSg1JgwK{0E05jPPu6=NGxmaTPo-q*V0?=BiGl zLDFWbUHyf+LJ5TK2E1X+JVKvE+NB)o?EeubBvt6>yrj1>_Xzsfk67dIXn9_iZO4~h zwm$S{;DBj-9X{&y?`+ZT{;(crd$m@lrjQ-}QMl2xB>8fwL4glfo8c_x5TmXsd3xTi zTCo;POzSg3IaJ6oL20uqK{{~8{LBI{II3tcfR9)-`C8}SYnJ^TX`J4_|4|iLHO(l) z9<}EtuZ@R0Jj0>f_&qp1SCHdKXH-e@&xMPJknI}*xXx!ZpyLl^S3pY{Ea^(`M2{`f zzT|$JkbrnAOB+*CYL!t!%!UNXw!l zdNY3rBhc;y_&FXl{4iA3ch{4-ww;|}`hQu$XFcan_%a$BFdT};DGFQy8pOT^eS<;x zuoVfk$5hV2dGhtp2 zn=rLF{yxv~=lpkT1&BcEz5dm&dJl^qN>Kac*CwCS$)sLWN(?qFpos2%UtoH-LNxsD zzPBRN{3#1GUuJCbkjfLLY8B*S<}(APM91L>&9NoEF%#@A^SVLnZajQhm9#c%5mj5# zMb)L@@0t4Ifj#xfVrm!VE~|Q3>vqkJH~j%sNsv?-rKIxJ%0?%zLu|wea8e(JLuOfz z4$RLo4d6g*k(;G%Sxd+)P=8SQz%riki~L+YwM>@VIc$t2$j z7NzjvQu(Wv61rhHz2zGMHVx(6c9@@RzBm1y3;w~v@y=r7q~lwzejI8M31VaL!?d2T z$RfrVAy%xYGn&jW%J!__KjA;~wgpY)^_yF^_9=Vy9|G60=F!2&OXOQn-%Y}4WDUro z!z}VPe}EG)Gn3n~(5?m-cvqCo)hCPv=e^N~k<+A&o6*xBE)L5V#y*QZv_*KXg;L!ATK;YtnVmUD%eY-Kb^=sU zy|7t$A}IHN2+%4LMq7^)dhUZQ#E27A87eva(Id;yXm$f~7F`(} z8;e!_OsQKEH~0j>+VcQ!(7>Uy-lflHTf@6M)R4vEMkd6d{ke}sS`%Ao+T5FQ=%pt! zDZzbc2*CrRTjkrSNrzKtb;-{KKDc*P2NM&2dfQo-?Gz9YX@P+&Y;HG<(L4K3ePkSE zebNNv;9{jJ^pwlzx0z6bE=TVPd0x9_Sf&?25y`7-MdCTJPrg%>X}k?nv<@?@_&C4s zO7mV!Dmzz1(a>Icd}kH9MV(h!`ggsg_L%wan0x-Pm|Uh^BdS8H2#Fu@--5;N+`HdA zo4wl7q&^Hdk~^PEuR7kuRIOYO7jbD6EN`h&Iw3JcQJV1DC}uSF`Hq&e-|q-n2%=s0 z{5xl~S#a!bdARH!sHA}@3KfwI;81?F<(=Uyg|9`|m~ANAVhPRf*R?ecmRondDVWwN z+TK41m$2cx-Tm9T(_tIRQXSplHgEbmTC3DM?*|M0>0#USRR;Uh^52GL`?HRYmoO3y zg*8e#!ju$~p5aeT&0-xa|y1^HZtcB9i(2R@9f1nRIsL#sml2 zRfy?azrN6Xyu&0D*0$!DRE7I0L(WTo{tu(FU|YxxRmZ1RP6XkXF8&fEvf;MLet$$P zHIyl*60k_ogVRSS-B+(HTk5bTmb!+xsYzU@6{PG!=p?s&`qdMR_t-22q#_y#tROTk zPSp}`*pG74oW7Q5h^Z|cIdBda@a-5Wi51qLt&g1lqDvj2C*K16ACq34;*Sv03X^F6H9$H!h;ZWJR2{uiS&(q++2~Nx4Tak$3iP~?~5=0E>wEVwhV49 zHh<7YP9}p~$oR*rzf!^4QGGQ&{&fC+Z#?@^0)gQ8H`;BMKQ0|=QiitUQp<;QCq+K^ zQ^sC-x#~y#@uK6y)ZJ7eY$2!Oy%N=JZx=y@Y~4jy$ZL5-Bov{av|s_Lt(qT(=mb4_ zYTI&eQJ+w@zbtm#!FLOc(?VW^Ebc6X9SW)xCYTF)Y^84Rj@r&`w4NL-FGD&k*JF2$wmE&Jnq{p4+p$3NoX`tU5P5mY?$Wj(qsB#P%;gD1TmE<8p)j z`?Tq&F*_m^)36_KY?cR;k6&sn#KN-saeDe5?!Mq*>c5tRZ(h3=QvY!Jpn8$jz{i2N zI(J>$%--7cIJ7R+0Xcc_@)W|Ogk5VYycxZM_?CW^E%SS5Z4!M+DdY+3`mQ!#@#Mqi z{$#KutUx@DTli%MSLyn^^u=|R^Cjy}ND1<;N=)tPP1}72Xz#(rSKMcM;hJ^C>%q33Pq@7q+hvh@yeCS&T@g(1 z$`;;X=2^;Q=QV2m#TRlj(X>86^VVwUcr8yAchMJ3q;TTF4JNy;2}}-oKEJn)1>F|2 zTk{uWr5tU`tlwH}@AC^|jv>WVn>q9Y*Z#xRDj%lWxG^mh=f0`hp zo&M_eQLaP&Be;Y{@eh~Ms3sWy3z@hIY%q=ON+_z^1XXsjr$Bl?&;D!Y#aZEpzABOU zI2FC1sBIw16fLmg`CpXDqRAW{@!bZmcXC#REe+{_lqj92qhhtM$&ia8gE)`={Emlj zl5TvW*G|?{^|c$nV}^k&P*|#P-XP}M6$YvB_Tq7TC~P5T@du#?tV zk?hywNZ{F-a?%1U|B$Yo^xtHv+5+$0MyCqjK=oRgkK7}h+4YnpH}mfWO~(ItIvWwQ zl{eOG$pVih0R(2r&a6N4a6I{b>0&fPCSh1|x4uF&D|s&QG;T@;I*h-q5B_;hY1_f~ zP49EMV!p>@mi}sfqTt7PCcEs4ZFId%E~MpVm-U9L;KLN>G^kmTC(&!3ePcpy=VR`2D=e&ppm9-;&@BAg~L%UN26SZKC^*$xDfefmd4I!X zS-aI0YCi^SVme4JX+5Omb9n<9FVTBV~+k~LyJ-sVDf?qM~gD_Gua0+tUT@{bDi-nf7+aP{9KmCyWL?ga}8q~UEy`|9xVx;Gzf9V3& zADY-#wfKQj>6SGqZT1mAD~d#F`r9q(A+}e?VZlR5n>rEFYk$x=eTN!kdUUGy^wnaC zfiBZaJJ&f--CU`sM?Nc4veU&IEG4gL`aB24SQn&e$4JCPkB}uhy~v z6Y~*Km3XIua4;Chy}>CQYZ5cvtfl*Wp7fvg@#muJ+0Vcbthzm2eweQoT!q-odW$S1zc0PiR*8 zWF5yK)Y;|q8g>01${x)ZO*Vx(Wy>8Fu~kSWVp2|t)sf$e;my6K^W2mj<%yz1;C==*uiTwms=v!7z$S~ltYxyk zNz>3L^ga$@Cf%*d&&&*RDifm#x#~cE{R!3BA$#InA!aKdCRE;eo$nT&e4SePOw@1S{K=QG@BUEP|;e3jgewm`{vT6l%ztiNy9?UR0Ws-9x`p<#J0 zXrQ}pfx9MDE$|?Y zodfwuqN1t=3!>2dIK3p`lGdu?-&vy8(16`6UPDA3)k zjQ?yp3ua0DMDY z&&Fy0>#`3}#G}4Xu3z$xM3^Wqi({UTnMQO&v$h{aK7GNk9o4=Noa!cJMe_BmdKXi?i;Yr^vZ0s1qbv;+@M|9`bMf za>AZO#5(5jlqE8*-inM4BR3vJ^5&Gl`gY7{b50}2x9-pBiR%qx$4Oh7kO9oxlbd1K zHgTy;NRY$N%p~=nm)Flbj?}lX<%XjDopjeaw>NYB#!CirO+G+&$KCc^cK5LDCK~0NLhz@d_DC6#CFE9lFc= zKPQu&nS+mx)8_&XplNnT%D&6_FAsJ*dLktY^x?hd8ku1^)UQBsW;7HDS7Bq>^^_{6 zW5dtFkgi_T+-wE17aNYX5b|qhkX6uXQw{IXvV84uck|$UW1& zj0Mog=U*7hH_QCi0Qk&cLJ@xFPJzM^F3A90xEXTN+@aw!WOe!|LCbchgA5R{C835* zeuST;PLz$%Vf>9X*Um=xXZs7djXq{+1rWYuEe+_z$crShysDw4BI1!lGpa|W7!cOc z7{85OjyZci`rX)X1JU}>zdsNYce`Ay+Cv~l{B1hs{RNs|m!A!MSr`kS0Z`>t?V7#L z-RoYtSq*2?@(R#T2QvTJ$(UJHtb`;jgT-l-60q~GB*Wh(mFa(9!q~A+0}FC1e#E=m z$T>_}UiCnu6paKV=1UD()b>PVc&0=Fzz;}qYH%owZL=me6c5mu7 z{POsEUUNJAi7;w@yOQnK8C-}}jGu0yO6d-#58GD75xkFKN!*&fx7=ihV=%z|{`^mU zDb-|$6et%!KpuvU+hLp3O&c$Fnf@f1;)lOgZiyS(KMj`H-RB;YY$?cXfCZ~(`wP15 z{w0Y4)bQQ&K^_fK=vg<35Q#%brlSrjSnv}A`Mi}H`diE1bzU6MX(u~vZx)0TE?@e9 zPZ>5{drhbB=``$TS7Z;cC|J|lcG}(Kn8FYrGU_#)urN}g{e`B+l}nHaello#p@NQB z#4ZUWElS;${&e0^;mU66;$+ll0;Gz7Z*@(@`p{O;t3P~7`ZsfBC_DsQ4#RUpZz7+0&`H?FDoclWOTM0d>Q{qME0wbyXN$jS14zpv8f$;)!ub__RtM&Qb;teZqw493P1 zT*^HbWNo6>3yd%Ba{l^3iq{QbxgqbSCp0s^ozH80-VTSXg;)a5qU7oN1imxrd@8pP zx{$M2H7ca&W_!NWza!pkWm#RH zJmr4otx=0vvgU!#ouaZ5GwlPk1Z__yM*@>h_RrLCz?A0GE2Cc`d=6Oc<=8KLUW$)r zQU36TvFg3>ksN`74zMgepJ3`uhe_!<#w(189Afn@gxp8q*kT6XG~CnM1J4sVg)EZv z+FZSCu@U}VtxGQfs4b6kxwkf-7!IuP+!%*|@1{`#^YXL4b6P&j@|)INHT?9~hGH!z z$lt{Cs%3YV>tv(y%!H$wFL<$1C8j=Y7ZxDUhv;1jJPH;2&PVW7cWdL^W?dkuFQ38> zNBAF*K7qzKjzxCdwxVM9Macx0d|uCG-Tv$h6nzULdx70diKb8b=2O>+)hF5N`>CXn zs%s9*G*^rbH@nWJEbK2{nNdz*{f)D3pUxjCHLT|hn@QeE8Rg>eWo_7WBO7LuWUF7A zea{vbE!wz(*mXBuZW8%o4~Kx4x>_y_M}!a6c_&I`VYN>o7ut=&{Yt9cF|*@ogf5=n0y3iA!cpeKK52RMDvT<`%LP5}5dl z3luyzH2fJNjm+QG-C#Va6~gQQL1=Jg{{5dTpS&vitB1aal)KPsWCAZNtldO%K9svQ z+TJeHhynZx6ypEk>#f3~exr6_l@jTa2Bo_@r5ow)?rvcS1q230xGh3R6*?peT_A(gP?9?_AE`{eH=ZnegkDZ%E#IAoWy zEQ>-a##d{R+P{Fth9$x@+q*K>8SX>#hu-fD$Jx-T>RF<;1kb$o`ipnrqhV;Kc(2s3 z-8q{QdF}AiN~0fM@)L7$r-c1T`nbD>(z24Kg&$5wES58gaLQZdJq2*e2KiD#9l4ar zh6ReE?_)4W9s6^o-JN;*NOi8N-|x%UG8*LG2oHX+xB_AN%j0|2GSB~ zNDEpzzV^B?rQ$3$J9edB!YDpR?@v7MpPcqS=KJ1#jAOpo+X=12*G&ky~{OLjHUeADG8o?f_RuO#$SjpsLI^^J)4M7|A0j^Fm$evf`Oc$b|X zg9H*SM2SW9d;BAIfYhdD|V00YD1rxm|o`0Qvk(~qRrGreQ9GCKSGW*7mq*wyS# z$Z_(Gk?TodE444$6VZqCIIC`T;Z4Jx2}{-vP6C&%n|9dgVw-p+nET`dZsdDN z5^5w?R6rTy;HNfFh7M=mquzDe#8*ok+YGHhaoOH6Nzi`eOCW;abNR}iu%<%7=#c;U z-xFHlYnGwWT2045p=V!@<|kaM#e?rj0!R6nvXQY-8rPl-KClE*$0!X;y<$66JL)lo z#@!iX4g2oqo?S^dVzc*mNdh{dAd)b|+^w+&4^)ntv>)z-(W&{YB3>V<-s}E09nnux zYLxyr{!Gw25t!(GUd(N*=Y8?-`5cfW3T^z`m!+xPjEQ&i*{Uld_1jFjPx9`)n<8ux zMm4eK4j;d+l8ETYhrS7Z>kIg`2-UWR;NeC3?YDHNp5)9YSZhie?* zrM5OECLevQK8Xz#o92m87K=Tn4;uzI>fl(&+)gJ=P>%4ZbLcEmb+S-myDR(MDls9e z#=0vTGF{Fojzq}e?*P;_&z7}`nWlaGHVVlR-Sm~+B%|i~26lZ)Jol@v%ampLea5pv zlgWOhoq?JYU7uf41{T%u*`wvVy>?@?jGtZ5s^bSL;YpEmDA00bCeaKbnczoIEfcTHS@P zQ<{Ip$*2) z`g?CJDy(OxR!Wzg%c*JhwX1%j9MY*O&JOo37;$~HOn8h z*ZVILvNPpiz}J7h*Vwwh`K2l?A3yx7@WP*GU+5~=f?LRI4#F>iw-W!>NF|JT7pO26 z0NSp}JWBo4rc2rfA%26xt5-M^aMBA@$kq4up^IGS7fgMnj=_2xTyZam4W&nY!xonp z)}8ctJ-%IF&U- zeG!w{7d3g5ggHX+SdHP9sHF*c!`y&HBPV9!xi7!8qWV6DWL3^Ka)QLY1&>4{Xw9#0 z_>Z60OQW7;0A8O9^0X*e4mg~PL&@w&QMDKMWqaw-vL)TbLt%^p=pUCTlCnS8R9B8T zZg#8i;2i$={0BBCs>Hh6(dy8KIU&C3zSR(&iQMB5fsjuUO3IDoW6>arseXnhgDD!M zjDSv1rfI)-O21yVeGND`HxqMh4^aRLtilGs;>vKmHS?oqZbts;Ri>fF35yu%yI!@v zwI$jX(;`ps7@Cw#pO_qb*^ey#RkcpOdv51-@%oDqeq+Gw!VB@MJMUbDF$|ENQD^*i z`EOq<2^Vgugu-vU9df-nWZZ{O%y*4Y^-_44YUtvI!w&d)5`Ce%gI!5_qJy~PC zSLkuCC(jI3#i?1I?)3@WJJY3t4sytQH@HH#UGy6I>ndkAPRwR|r`#NNf8eYb;C}+z zdbo|=ny!``RMh<{Cgkq!s~t&{5L->h{>DP{ny;9EEv$BAS$4<%qWZX*`IOqD>er4u zP{ju)XLP<(OYa;(I)@E(TxKGye8{}M4}~9ZUhl2@L?1y?UvkA3_=1cTkiRM1W74Ow z$Sj7ja4khsM#Dr4e$%5R;M;3GsVY)=Y&`7$BDnNevp&Kku2XO?UYjI~*qb$(K%tBS zi7v6JWEE&n`l?Z*ZuE(&H+B1I+d{vJx|ctiz!R*Zyx5bfVGL4b`*nsn->*o}O zg-{G*TS&!943apr9Vc5IF;B@V=2V*yb&8UJnR5>&nMsnsoL(0u&5yO6d5B{_-tQgOK$HH;M!Di3#3XP5)N)@dSLxLc3C|T3r=8_;1v}Z>t1@>o zJ4>4ntnnLcohr&Wu2LbmZcd|tRzKwfC@N_?%sP{i36wt^+k8G|<53Tk(caKZ;4#%e ziqiLTa3bpVwnU&XDk6aGm4ggz`RFa4z12(l^Jw9VO0n&X?3plH>u5m;10q!R_w*={W)Sv|GhwXYG;c^n+-wvsZrT-<&hHZ>^tr?Em4xG z86f1-!$pm)OaW}oALpUs2+Soq0MtjGbdPzSj_N6JoYu>BoW{+}Lq$B9wjG!MxezPu zjp^@UM~>bs8CgVf))kWaA|@t_R^#F$(&Y4D_e* zC*lB9i`mFE^7>na@U>fp0V;#VW<2l$%=hTMLJ-J%@#+VzE6T`ND)l2M&2wy6ejw}rTUuiIE$}o^7I<_Vo`C)>#s&4!oO}DJrL&oi9*|v;-?@^V1 zIA50L*Fy;F#wJY4wbv6mZD=$kWFh{Q5-m#p zh;h`8Ub=SMqm?fk2g&&xZSF^R_*B=#ZJ*ZMNfuNEdD#*-r%ZDfhZk?F&t>iqQRUD z1J7JX!v;C)6kkxAX%{E#lFJVC4n6EA!^P~)1M_$EA;%1-LWjQ0PU)Cw!A*Ak?~=v~ zQstR{n%!8J2r$-9cc$n# z0Ks~XzKm-lk!v6ehGWd+jX?87=gbXre9tqV59qlpwMM^uBpBI0g()EBCGhTtIl3Qb z|FaD*$uq6s&6g6T)28LklxE2m9$gg}3lw6Cp}<4*j!*l}L)s6*2;tpd?^#d0tP)br zmivlbn{t48E>|tlE3h#cwkDv?c3e-4$~yr?*8m{FzrPgSVVE5hDJr#L9;udZw2?!s zQ3hUx3tx=qgD8q%@gk6*B(xnYH@hJMZ6c#7Y-At2!i0RZujPEJSy4fZrSHHL!0m0j z$bpo*I@=LJ!G$l0o%;ILa?sYenS%`-QeQJg4;YfcAvC%)UmkC>UFp)fD-WmL*7kx) zdH^c+esehb3YyJq7#rF_%LRCdE8pl{>flra6Q6Q?3z{Rv(hak}cU(=h^wILiq84bR> zNbC?pYe|xq!Kh9NB0HL(N+#j^KKJQ^r+6K9xHXnA3FIT!Q#NuhZp#_QeVPE*Pc z-@{BHO;0zDfiS36fj}gcF^c+1C}}G*k#jfbbb#JvcF7bFiXh~)8U4^T$UGWc zw*tcDa#$?dKSIOu^bllr2LHEYp8eK)&U?%nqkbN1F(!J?PJ&Fx|KE)q^Q03LHh+U8 z$hz17Nd;a(J>AEI#6%J&%e=zX%e=pX zi>ij^&lH6!h?s)b)tVC!J750shHOcfn|9o0g?)Ss3uQWHLjT2PimpB{=d(e48Kf@v1kD5@Zpx&LjHc|CGNQJ{9jgVFaEk4)kv%Gq zdF5V3pUU@MoI@6`Ej6W`vG_on9_IPMB{~ZYoCb}d$f}zD_1Pp~Ug@MvTUa+FGBH;& z<%>bWcuesh+FIs7)l5TgyVl}#8SSP!SZ$6J{?@TU-9aG3Uy*?MoSmX@~@T4mHox{=`h zmO0QUW$!U~7OtV$AFN?+Bgrsr`c8pz(l>2SdYFXS0xm^U!w+W+=?7pCEu=p0ceC~- zjGXSEb&ADdQChy_O0&3;%W=7^BJSs0t$ltB?Oq<1M}C?MO^H^e0p&UnG4*?X&veBv zzkM&C6cxCGj!x%H%Zu(SO{LmVxb+Yr0&FPDUZ%hI|GHWhcaCH{k+`|J8IhHcDw){z z$4mz@`8l)O&+}-t`lc7nUOxlDmPZR)canaz+F$D354h+V{wZ=#%+K=~UGDy_aN8p& z8Qr*rF}}YxVeWdmc@gh<4#zP7@73pc?Nr()x>l@! zRGp_cR5+tJzbLWjHQb@J(@57}Xe6jioRl?Xywl;8YP{ky=|%^?D4hPye3Hjn_|l+u(DGrVI{x2a zk>X_5Gr3mHe^iJ(E4i>rtcW4}&WR~-2|+6qz>-3edpeb*V*va-9li7Ou? z|MUsLXaDYLquozhmS#c0&esI2OAPV`fHxUAB>MEA+bMBkJ@J6yFA=__F(IDkT3*%= zE1AK5C4RrY5AmsOek6dVJ#cP}gt6Kzw)yeonN@Wkc!ARk zobU#{&fYOdGIQ$sy+X(sO9PrX8#!!0Oo=c|&&FVoJ@x+E)OmES272MKCKGE>ARVb* zfmCYh-Yr?G1NyG=i`({FoMoga;SjaB8;-jx6Wt#DsJ+|^Zu@Zl$96VOQ5)GfpZ#!{Ez9%F&kChve`flpcKR(~wteI|p>_Vg_LblBGtClS& zHE6-WvP%yfA#|w!@O%qx>%#il48M~Jc$~4uMSLt(LPVGS`MB~T_#x52hX9#q?rW*< zf^E4BowLUzSHy|hW0%Sc)B zi>j@>t@X_=Y3c4C1?pHC5>^v#JTAM6D#&%{tU)S5dU`i$0hCt-GnvZ=ydQ$1>(_?T zc3A*5d_I>;STVfqY)JBbBoTV&;#gBYzBmaIgZNMNd*xOWk^maTM{I?G&}ai}1$73mir zsk-poMk$V@MyuV*Jynhyxn)~4(*x~Te%1I16PCD*e(+wGcgZ*jLHWZKADK-CARBx( zl2^ufn5IYc7|hOP(hH_XiMP_>!y;OadJQqI=sV>9m^xXg^_#UG zV+>}fW!?7H=44%Kjgf|uuqaJ@hjsC|I zL+!DYh#PwCh~DQ_p{p!{&@wS!vwpkM(9Z@>w{R!dm|QZEcuh@-&TOwRjATE0CVUp8 z`O{VI=j(LZX)+10^^tFC=kFvQE*PxyOj)wtjuO*-4uROKLFI(>FLxz=Xjbe}hgy%ZpPzYDWEX!r~_l>8SK%L-a>^9cxVt?K~pY_c@> z8D+XkPPbj7`m^396I+3eT;YZ>O-*e6!0!rDUmiv9*xmG{ighr$NsWTD&Qk~zd zd#n-6tvm=cVG^dQE(d^dTaFH`B*cqCm&REV^5@%LF7Ii+upsQEP=0Y4pCKTAyM)tm zcYV65>tY{m4&%PL2^wVL7xbFN5llD_A$%^vga!6s;%e6SYqc;T9c!`T7@9i`J95xv z-ra=x#SvCG4koy6B}qsUEzxR~2N~M53BWe@yv!bQ6EWRVQLN8nLQcmG&_Z>?ufk7x z>lwFbqat%NfXAjdrMhFw6+wJlZue=KzWwK}J?BD?_~o`;=g{hy$Yn+@?{mEBH7~*> zQCb0yI9YqNp0I1crgn+t?UE+tsL*w#>a-1i_)AZOW|80egxuF)UB@R>rJ#p$e?KA} z-96|0G(&#YlODRr4AuU<{0tvr&0RsHSgIpbAm3ImP8*b-oKKb&&e?w(p9F1iUE`JP zjDX!Bh?vdK4Lyh(ShUp4`~$#9dJv>8dugDo$)nb!p{1&Gc7ZRu1q$%qRVMQLdIwS5?`PY-qiSTn{i$+kp+_afT zA^x`Ss@^2_z}YxWl7~R=VlyDIDFuq(FgiH@(O{>OA_^$*WaJ zc#fiijNQg=q$#O9V97D=GvoWD*G0y2yQbVgYncUWXgoQ>Z7@tSZh^2?F> zSZ3G;N9yiX93C%tllDe6KPuRBMZfT~hVQp{s^8+pM0?JV>JLYEJ1Zfnj-d7vO$U%5 zlNa)m%OFg}!!fzha&zuLo}=HvhSL!1iE7y2$*;nqcYaXfuSMNFr8B8)<|Q^rM4GH- zJlm{WcYbl_-)2fYecSYfT#1>$_|wE~M5;(tYr&(bN6D~V-|BBUeQdrPZhRdD3iZWT zyGK-tD%%VSKRHMxB()DYnQ-1qe{}oPAD$vScDQSIh3Xb%8+LUl;!%k4G4F0j6|$#{ ztg7Q0Wht%PfTPaF%#~Yape)pDyc?gmiF}0g(Px6+Bo?=aD}0DYzVcbyDt3;!6VEd3 zk>DryTh>cHe{L5+{6z8%20K?Gv>!VFP(I$?{MAdIPL4(SsY;DHTtN(0rqXqNeYT)q z0LTlI_4+mPw+AVTh@0B_Ot<5<=FVLlXGh`)?7^Hp+gf-y*0u9HNXV6a(d9S9p`=No zJ0idkgp5r|XA=Yr*QD$JM#V+VZT>feKCbAKM%vMAk1$$cwzabWq4Kmv(e60!tR|j3 zEcYm-89?>;%5Z+4;GOxDztk9zNx#KTQ!Fl1E!HS~ zm@F#4zDD&$_%|p5^zoqNDN$Ef_WiRMd%ycR;dnRyQpjoCpKOYM_0Hr|{9{0*U1}i# za3x6q&-*Rg>Oef}{+Z*YRUfbGvMMAg#|-bE;)&qoiOvO|SF3F@Pu8?;wczDg#L#u( z)WfJilzb=okoMfiua4fryq;yzydhp|=98iIXIzLOWmM}=Uy*Vced;`rVGkcbjxyuHvMl(;VbS~H!4T-Q1mzs2)c?W7_<5s=|$*rDs# zf>hqjh9=OKk3%t1FEl;=lI58*ZZnYs0cGBMKAs``UTNDz54AIyeA{mG{c}c+Y1$1F zX`Am9$CekVJqfS@>)DfZ=5AtLb~3oTle!IY^mWq+GpbRK0de+rmRjh_{s z>P1PRhhXfLyj8M!oOy%07_4%-E+ljsec*x(1E5)2d)ma1GuhL@7udh;SbT834u?OF z1U%Tmt3_k2CNB7&0NfTpKg3%41gHy#z95Eln7g*~^O!}$M73@eY&-7|K%AlCgu?_$ zR;FIG2hC2p#8rL4KOP6x6P(okRJIGd6ELgMH@{B~7^K!4Pha@*DSpLtjy(Z*^I zfJ^q01Nb5ya^h_T0D52|L-Xn6;33dBGOqLo&V0e;YPElKk!)dDL|urhA7xnJ9dFI= zt3Ny~v%RF7EkD9X?nj}=$Dsn8EGk36CGmCLg1*$al7%boQj*`(TKt~1YvkCL#ZZF% z8|v{Q5}hLni0Gf2$nhM!mdM^}Xzo4tvQ|K`({jg6>~KJ@kf+n-3+Ajh7O17*eZUE(2+sS-i%++#$}%4!mF<$ za(<_P&@n^ivrEf>gKu6glw{uByGt1m<4U-8x_eb6uVfh4TfBmq?eUt+Z(i=pXV;pb zWtuA-1GueDe!n;-b6kX^^SlU!e1F>H;n-I1@0Zqnw64F;^L!d7N4xqU;X|D?bFud| z6Qx=-lEnQM$cIxb)ya_xn%8AJ{@`Jwn{4>uB74xH8*~oT1oDzMh>v-mF#AXBnP-o!PuI{@;pYu1p2G@1 zqrP7iD+EhVj(}etO7G5LPhLjiIthh+Jm3&{>bGJqmV4{2tG55~RivW=YN|Vts{99OBA%m1&kgfO8V&0t9>0fZaojVXVh5O0`cx5C_}Kh0u7TYtdlOr5+U3wRI_ z#A<27lJhajSfm;6Vp6G;H`JbitgD0q!#={>dh@(+X(u{1c1 zS`qK97U^;v9PbQ>BgQmMi27>0hnX7ip#;Vx+4Wezr~|Z|sluB0+NezM+9=MGxIa<# zoDX7GIqdzcoLOTz!+Qwvtv2V9>;x=+2Gbouw6tK4+49I8#m@2?;Udu=2HWIIGH9N(Y?i zaAya@@=e?@wH+O@AhS$#-;?C|%u2>YTk-e0j1tgy`Wj2_)QWit*4gq+ws2vdpHraf zCWNOL;pH7ba0>5L21{e1BE8D4pRp8ijc}{!VJ00umvJY}l~6v=r0JK||Mmow~NCMjvK^(uChP9OKuQ zla2*{U`xqTg#D9s{45+&@L#NQ7pFB1e?ql{HkL(DSBkVr@E2I9Pc%3lG zhwsa~XPKn8?aKSah6)M_w|&rjqrrru#)eh?lu#B1GqZZ_coeF`*bw2{Rfd}Es3Hm8IR-3k+49ltT5eVoKTfXQ@oqlwCG+&C3pkLz*T=Oo-YVlG!bNG((1>y!~b?RF1;j!fBoO4yjnBz8P041kuj4 zX)I7Q|74L?8p58U3zm42jc7VF!2RgnMjg3#^k5}HP^m59`e}{n1G@|KxuVq-JGGVu z+xEC7I{;Ut`6s5VdQW8lZlExk0qkSdH*k=0@msPr&46g9eAE^;L7s<+IT znQ(YAz}&?=ms%jH(W685DzdnW<+DXzDrMg#PNQtnnNL8W!U;_&AI9|bbTC9P4c2qf z8KI00e;bn2CEf{Nznkq?+>OO;I#uwy<6*!}kg}Ib9uLKJhpFQRY_DFdx_j=w#K(*; z;^%Q}*8}}@+|I;1X9_uEaWeAvdb)zskvLtdbHr-3wf-Y(#HiocD{GZh89B?yxZ#wh zFjnVC8m~8L8q?`_os2A(P@>HJQ0K7p*3H#_v+r}D{tqB00S`G9W61&dHqs0`8u$!`MP^;=?I7nFjx>IN>$E(;a;f%HK{ zlJ%A!E0@=PVm6R#KU-8KYUb3>Y@cQ7BRa9mc3Eh~BMpL}XJj2_K|Lmtcm@KY-v3T4 z&%OkUf`>ghdaKAT7IE&a{xLKB^ujnDG-a*1#kp4^Ncv&;7QhW~%KxiE0eV1O2+tJV zDkUpb3a-qfi@dg}DhI;*4~9)fyi&6y^{V4VY>gu2cuH<)r2EfN0MKxQFGumam@0iwV0bt?$3Nt{%YzH!Ee| zAJyR!*3X-6Y?msbsg5zS5^d-pQWoF!Hso}BP4%)ewd~gF{FZv+YzuBgMgwRZl&@CF ze1r6^$BX2I1`}P0fp8T4@MJFQJf#-I2Yul%Y`%@@^0^-eozKV+`44GB$|w&StQ&8Ybh2%Pi3;2y+9V zkN;g{+v(w~ja8cgCiG6@L{80eWvrldjw*PnMy=>2Pq&*9@dzuM*xquhwvS+jfS<<) z2|uktIf*Ykl_7uM_0!=csoUcqhXC|LiCR+%_s)(8;Cmj^KzZ)X4K73~MJelrSQlJ- z1)H3mayS*^Fcg;-HZuVbgPF!hLarb26rKWs94cv|6eZs&vB?S4XMB5n>j7oYt$ zgwHknOwwh4oVjKi?p$5opPJ!Qj(d?sl5$)BlyzLhsblO_svCyinCa4`VC_C*;$;+M zdJ-&VhHE?KU9HXQ0s8rR`{gq8S?q)u7tI2Z+0!|*B_yNE-XG(|kt-EPGaKeaAVkRdx_5fulj+>tiz8lF&DW6BA?3Ik^ zWGTHl2wE))x@6LmT-qk7>U`Cc;I*Fc>zlmAZ#}Mj7!ycps8}c}rr0QJ^eu9?)dsTQ z0GdX6alvnrwtp!lD&6{1nYn!}AGIhNIaZ)X>%6P9pQdIw79){V4ojpHc#fZcbc<-B7g8DvcLEAx8TW+n*{ATLo0xq!jA zP$H*gipu^o^Tf%uSw6#JpgQ`PiU|VvqbepogK~yHAaL;Are2FUZnHQEkf{0%Jc5M8 z8j@#5z$*FQme(#&`bV>o1E5Ux0Bz=%@?ra6v%h=aE7fI~ zct@l&0x32jqvUk-DXf-O5Ok--1ZqG5dW!!ad5fUklG-TBZfWrx*qY(qz^oU^WBtX$ zti@ZQN?bSX?4g?j5gn>Pb^rCp)xtqFGpi1xo+NBkfgYdn#%?J=?uvr8K@u5KlbQ>;P7GO-d6BE<-NaRK}ojT4h46oGe-24lP zU&d?rr|hbjUO_Di)+j=<$MXE#{VkJ*Au=QMaVmYTAKJVi{HI<2kgLt_@W|YJXlgeB*`~?}Kz+jHwS2^Hv&+Py#?m2{|ayNQUa` z2$}7aWC>>f125qH=Q{d$)&e2EPPetaF849DLCh%Ik`-${+%0 zT6`I}sVi0ncHpja%+u5-+dMDOksp1EAx6k##*9#E0*OPa)<-8?q3^KQWRQJ!(#lp@sHRaxPD|A^iD8fZ zFC#N*^saPn+-4&4??0NVS(Gn2sBjenLc8=Z0>Z(X_wF9d*@~bA^aUVchPs_1g6=B21(z#$2sUf7Am8=zUprw)}I9+nU@(@9d z)x0B4YPJ?3qS|w@JtGDuRSzn!n<)GDkp`Sl+1Lgw9uyoX#W}ON{&li5Cmk5g_QjqT zfnMi_h=Qp4wS0*Dct+~3!Z5VH(*OB22|as?19%m2LxRh&`UBik7aaF8t!sa_G9(3| zF)vy#L^Gs;S5x0U&X9ur#;X@?Z!_{+JicT+c2lT=h{}uzCQuuKVFEE#Z8#^tB_(wc znSccD8ycD0XC&q4*EXEEjoDn_5^h8?So)K6dEPuNerQ15TyvjtfB!Gkqxq*EiR6ie zD1U~OFy!hei}$Pnp&F-8V^d-n?Oxs);m2ozfd=ZzlQR-#luhcgj|XIrs(phP&qO1g zl~HHg0ymvXyL?-Mmsq5>k9;#HfgY%$cjFva@9uD{jGFt2P;Po~h&V9ad!x73l@t4Y`|jIyLz$hi$liDGdzan$g`syMdQ*5l z)OEpqifWWJB{oM;_wA1Mojl%UKGH$_=#SsL)Pi4umEG@n+m{*8WEt|?;jg=X7>Mfu zWU{!;`Zg^!()FkF2XZG8-0M(1VX*qSYr~GE0~;0mtP!RcJA9|xIhJ3SxIM@)tt(wC zv~t;f)uPYcWU&uqV|7(FV;0GDm?vYw8vV#=jD%Ty>em78G3cMA?T024STtg zS;r()*Ghs@CpAfA(!44p+I($>^wNR87hV)W2&14_J+4P}q-q!NqYGCx-bPnP$VJfF zHLk`8*mL_o0)fC2ypkcvj5GASzoi zC~QBmkgqFZhlTkeL`OjBH@fL?EI``H%ND@7pA&Sg&#*c^&*C@c<=`jav zc`w$%hH@=m&`{(mOj2Q0OZ>ks1YJ~)Vt|zO#`5QJA8JDsRbdtfxJSm$dNkkhO7XIct_nq>{BwkVEr8RPYLC__QK!SBnCHjFq&zqXbz*OS6 zrZ{~PN#dD8VUu0CruZE^KJKiHvNA=rP`>G+&+lSKr*OINHH6kkjaNNMV*TeWwqR;# zks~7j5!C~DP7jNV%hV66_C|!%dRp0#C{aV~s%I1VKE2DsCg(Z4S<>Hkn0Y!|?5>qW z@-8Hdbe;x3?@$EaPz2t4LV|EOa5OPRtf(`psGKC?L&x@>a%;@j0p=313-vT39BYkd z>&(hUxb(3vt~+RQJ93D zn*Ou@p_wL=Q*t_1s53f4^cWi#cARh+?M~t>pS!B#Mthk4>|j(A^>2txhE+zt=6-%# zKVyoe9T_1~Z?;ypcb`7uX8t=UgxU`I=2>14U*UISm_S4ANnPn2A$9D zbquST>Bj3OssNXGQeU`go|zH!ci#~4DCQ8zH{#<#uNbI}=D!ZTO3xuHN$_H9m%f%l zr0VQE)Iju77MANfGfDjdc_lU`;V0W-osz94f(Z5r36fnav*B~Q%6F5rAj5shAA9m% z#j(2RdQwKzZJCW>`8QZLXk49M<~3-vyl9NWt`#W`?^67+s1<+kpEP4hg7KnS1bbc$ z2x7lJzaPqI`81{#DO&Sf&%inBZXi4Cr0<`LUjX&WwagL%r3YT(k3G0cA(VxiF3cTB z{f*H*TpUBBZ;dQgda~~Yr?WWdAuN7lE~_nxu}8P~RgTArSEjE(&wZe)fj3r}jPuQA zIEt@rS~%yj4u8)98^`Cu|8n1Cvks|is$iuf8mL`kF4kF6SJ+mMb)A-1*P}dFWxf4M z``>}QMH45jl-KNxXriJ|>65ARgknuZK@vjJUKnTe1f?cff0#~BtH2&yS~RNYC=729 zKUs`X#E4hEF+DTE0kbyi{E6{ovB8uJs>D1{Bc=#f?PQ^AZo>dqBpEjgmxJ3+>B6ju z3_Y|>K0&o$VP~imQh4uBIAYKR6X4eJ07)yYG%~gk13)l#{(q9-xEYN1nn}|hXxD4r zoiH~D_I#H3Kw2c0bu)XHl!kigjYlWTqz%UU7yoXy%GN}JfgX;z29rHL=@+05{ySpY zJmPr&=o0x_6qo&Fn#KQV5^yrBeB|uD?L&>4d~}_0uB3S4GuWExrU;Z^);&7uE7eI1 znHf&t{7jyW)*n(E_BtPpIq=#jm4TG%cx`MXM+|YTNdokL)Y+x}-dUfB9dqu}xLRPi6@_K1iw^>LQ+GMt42Bq}%rdlyP=e z4zD;i66OvCT|%n`JNJq}Q2*j13MbSP#l6o%xfdxD2H|bVd_Qr1Q1Rwf!cd&fRmrD` zu2U0M;-1`9?o#notBh{n_;)l(F!bUjqDH?25kzVjwe(AaA}1*Wt+j=jz3CgO#iAS| zJ`}GSHklHqyG~uSDZY*((Ls^VjBqyI zYT_H^BQ@%d`g;vkKXjXEGdD>)MmWzF%3}&utsTuyl^fRAWpxk{1o0B~Z}NG{+_KFI z%J`^bM_}nGxazIk$FX2a5B+!Pzij1m=``BjOV$P6{n;ODO9!#``V(m=r z^2tn!HzLL~`#m`eUw65mnA%ud33`7wAXyl}vstl&^x|=lz!M=h{lSZ3ZUZRQktC4H z2EwMG!2k6EaNVt>srgXy9e=Q&`NU>bUP?O7NK}772;_Qq9~k9!*hf)wQ0a-boLn@9iZ}JT`vQETCLp)b$$1dRz3XVcl4cwPU?Q z4o!YPgMy1PY2us4Jw}WRb!9=F6ZIMyqde_4E#rc0VZPTo1EWS2NIvmU`7ty+0yipp zC`AtPhZ%YaoOdt^{B$KrS-KTx$d19BYEiY3ITmu~dA&H}KVsVfxUI48#@ z`$QNjs#FKZ5cXoqS6_43P{v|HDr3-5|Jun5cs{3Fg>tp=EpzarDe373>ujW>J6kH- z;D8NFbg(_o^5TE3RKw%$8aML*=Ekh@rt{tV?K)Ke+qyEwim7Si>gW2b3iB!xNK4Li zAI_cW6aSf^lfjteIJaPt@(ab;0Spl*IlWe1s-#aY{y*uehUm?!N&1Nb!N|zewTahV zI&&~-ob_@0Q|X}8h!x{$=TqUJJA5bdlqfjSWCiVFDs>PO#12JktG*zXez>P{6=MHR z@lXTXrDmZL*PRC&E3?C9q()m`99%!xKEOms-%VvYud?zT**iH-?0eHsvFHQuR0a0cD)$BXZMbbnDV44d( zzU73GX4!v(iJMy1z#(RCDBD*)`FSM%2LQRrvM7FUoHcTIH@Vuw{oQ?oC&Z!l!o`i* z(oM39UHjEj0GXJNo5u^tOzvOZdhcN7iauUxr@rTeOKQobsc68H8S|tZL`#^c3`4oa z&39}E%3;0Ur8TyRGEB|Q>fTU1nqs}6TJ6E#=*TkeAjN94YAqCgIuR_w&`e(=CoGK| z`Bn|L^4r61B8(&W;)yMcqdY-K_$&;`xFe|NbV`*OHePM^-#3$KrG~&}rG*@=bi( zW$vKybWx4dg8dEbQ;pM-`$`Cu)Sm>%?#^tan?7l|S%v{7yzi*Kl0ZxaV1aCJuIk!a z$*8knW<7X9ZigV@r@gYEYe&$9q4CpwBIRjvg96u5 zJ5fW52Ttha&lR1u+D_1A0`ICb_3!4oQ?fPDAen)3aZ3Wcr=9f5#>dR^9_JXC&%(!Y zS{TORsp@+(m-XzM__UkEj_A(RRZJYxz2VvQ8{IsImgrP`?OKfMvr8>HIusaW9R=TX zS|=4jcY3mMvMkf0Zmj(H%nrv%?_O0s=Ie?}MCN(9wDa5x`Y8=LX>SlRx`@%^VLfWp z6$Cw}{)6}4F(2{%?1eSLysglHp_gVs&X7>wqr1*syhsGC7-j2iY?O>=^$*7y+KrG2)=ni}QqNs8y9*mD#j-zUal8}b> zMk&{17%S-eBA#y6mq_W=Uo8kYQTyfGm38N1%!&^_!AeoSBR2BD!Lv~`O)?1?8$$Wfx6oNN?57&ql zdU)&>*vwQ3z*c}1bnB@>fxULJB<5&i2#h1 z9P)*q-)$D=%#$YF5PSb=&pGvdMra3!>k79co~^LhvyUzi%#@YK?HzTpqlzxnAHXmV zJ|#7kad_$_Ms6gyonws{MHTF^tN$#PObJkb;XcPqng~esl36Iqz=|vEG!vVY3 z-0d*eT+H(-E~v?+Ti^4kG#KO#8fJLiHLL{Fly8}5O48yIX~-_GAPz{0?tXb~lb^^s zJ1`3)@d^#LOtOR!#)sm967RifQw~&S!m%tVSw-14kX3J8=jy^aS;p4Ku+ehshm4bW8wBrVM*rh2!QwamM4kllwb&YDi zVi21Dt(|@JOKIdgcPvob)3sW0q3EY1E_*g)LN1B|5;ilIv7+=P4??0TWz5JJ3`WLS zmda`Fg4uVJ`&ha|@kL$Q~?Jtj` z#Er%GdDBvBuwn4>Nh}&+iyB2qJkAVEYx5;p#1;qHN!=Uy)K;x>4!wZb7pafm_?@SYj+zb+W)IgT zfWdb?h=1zz%QHrZWmo4yf&Vc5U{9+%348860d%ej6!fM4b^n7nsZSH`PIAP#)+VDaKYdb6i zZ-DABg&q#-5JjgwmPh3!?XG$(mg1~6ts5MK&PqpbZL6Ec9Br)V>A?wRWeDoJRjs+g z&uV2G&19WxhXchoEbd69p>RVW=5CFc-p^=?J}XRl4Aw`?D~K4hxRIiz?76jSy@>lb zUqqy^@%EbPADoSxZpb`R^0f1KS6KCV?ofJ|f3wP;5SXNuuoyCd-i?ox`@V0zM)*ej zPOghpm81=#!EuJ5PGAS_lP0ER8S813*;4v`IIv)%C-()vKkHljn{a=L1`?$tCZ6d? zhCuQt0tU(Jcw<8Ur1JyzCIzDhQ$WxT?lYqjSt3LR&n>)0OSc@2_}vApY4292N+S1J zIL1B&M>W@ZIXMlo+coxLENPConS_@`|q^h+{An&0;--O7D|4 zydIVOWh&h;{YK~Gn`Cz~xQ{%#&Yv<;WhiIKRn}FeRuAJnC}0~U=Sy~wF2Jx#e*Iw+ zu$YFGRX%*zZTR%I7I0b-YuD=+VawFFh9!Kd*L4_5z)QnwB?3JiQxre*uKO{=&ODoX zMp(g!FSm}`UDt=q&^PT;zh91xUUGXTC{gK6noN2DEBXFs2ggo+WbHnG6=9LM1SLVw zv+um?nW*)bC+Sv(LH@Uk@FT7o^ALXsqgVuwoSgrGL{ZOYf~?=zL}l7l4I0y>dBEGk zwPCpTCOF&m0g&SQ%|w#)C=*xOBktV zxGDgcA`yCW3oh$78%aVd^){R|$VQWz-FH{x>+nTcx9t6I`=2r#MZSyVyn;u%Mqa8y z!Z?Xz6hPhrwc>U@XgX403e1NHz;k!KI_3N=z>^$B9`S^&&~kzo*IVU$pcauD#qhzY zk(co-4`XGKNAzm$3(RtD>5PPKv5GqFOiyK5IMIa`keUj0b=<4?64_Fpw%r7--t%{H zMjr_6168$$$<#%ukS-zX7+m_eLj9(G9378cpioB8AMAZgmKi=bg*sRP`kU`r?I|yfQ%CH#Y zyKiWfj`6a@etvSEtnH_SKkh?EY+jT z)9j|=bSeDHk-|H(Q%Cpti7=(!+((X;@WT#sN4yk@BniG8^rP3|v6qHqg}HM?m(6hm z-)kxm%&mB?=QHGfmSyq*Clb$xk-ANQ*aDtS`Hst#w}wl{i}BPGX<~ZsBC{~sJWc^4 z_9F*?C)l6$Z8V|Xpif{w`)GEeidlKAq?)7Q8#rOCakiF53qZ>nCT z4<`uavIw2fsy)cfAe<1_3+Qcq;{n9HO12bfyrR3!Nlrd^HI&U=Zsft#j`cN48*H-xb)0WEn^cGZ)9G6secz>+<=_R@fXYn&Xv7;}^yNTR7tOYk82Ppw zeg^%89^6<0S~@w{UPE<-AG)h9J8;24l4mQ4@5z#3;cDz7xSbkD{SWcdTS&w27#Sv2 z{a+mIgrAKm)Y@Lp(OQK;D?Ig$JgMf26|$s?!_~&dm_Sq;n?2jVey)1DV*GeuFaf^j zT440uMSH?1oY^m$X0vBLNg!?wy1&mae*_Kfm9T}P&@&+xKC*vZ9Q4k;N`AiS8#i$K zKF31WE;@M){XAPFuUHm3p-2g;%QOd|G!9K+jiIWcyPJ*6XWg3W>naezt81_A$;Uh( zj8?ivA@#^gjc*+?D*AkZFcAXfcwW8M-f(tE|B!P{Gpkl(f0!JOkl zZ#!YTkP;tV_a=)Go(h56jO&7qk_m>uwfa-0Le|Js*D-!{oP2+$hMjTas*b`EJdjnE zdu^nFPyGRo^4}nBBY*jRjTxb^!R<8Qzrw~*ure+ujqu6VW@PR4GGIXj*Xw?To`2}3 zWauFI^L)`mk!GK7&MjQXZoB<_us}t6np)p_25dd)x|`l3%uRyYVN!?8S_It6{pUA4 zy<+sujGyg^qv|MSfpA*wwyJ|}Pn@h0=6!eRD~%9Z4)Kk*?-3RHG_O39-x?Sttts z!$j8d1l=EG!pHn}OeIGRMl4L_wGfYuuB$dt)yL}%_j3LVH!nZX4}g*YtUwCj2&`p| z4RaEmBsDJL>mb@s{TsFVU&J!r7%E18VY-gH509HjDg4Ggd@y{#vfZm2J6{_JU*KF8 zw)YcKBm=gRaE5=+vFAT3BapoKKZ!J-E>=$Q1f~Szv|*HR*_J4t$+f%bO>Hur3a{J2 zJ@D1``ls#KmXcgtpMOZRhl<2>`t=OXdSG}R9J zaN2v0T> z`$r{7zIxvgKfQE!;Z4u37ZGb;Qu3Q9d-kd%(>nD6jsd~v~J0EVOKGwnH zo#+f3_U}r5r-j4vl<3`)m0qNGtU)qc05S((%D72B?w6gWIKZ$Ka=GY%T6{bv#0G}0 zd{EDe#J&QM1mIX=I{p2v)NM)lD~#O~L?m5tK$)-kuZE+URNU3z3A|q=kuK;Z` z3&D)5R0x|jMH~P8V>4oc_7KOqi;o7SgBL~-iHNuY51T2>12Qsmg=baDdV`te>sE7) z-93FZ4_?E(ww9E$wTV_D6@I#o5_UiZ5cT9BjG$FqRf9d*$Os@H4m!i7p} z!uLB&`pL6}Yw}W0hc%(~*il*~ikW;E7^1NEE{IBen{+o74jPCr!CIM<+naRa|7f+= zvx~kEW(nULTTY7T^2t&@A2;%fq}&+teHoH_$+$Yb8q*jbRv>TUKJ(!^L=OYVq9NW? zHa0f$>@rfLN1!hKVI7SqHKqu7Tn=s?K4H`U!pmQLQ*8;-?|xV?8_&%OD*@rqoK#}_ zRyx1lCBn|zD=XUjy(`+}u-r(-7dB7}6lB`e3D2X4PNklU1S!; z3v?bS8oOT?40+G@vN;#SN2fXLCQ-mQ#nT@M6w}4<1O@JNZAk}=jlXx)=U}vF#DqM z2vRUR$X@x>X>M*jAdNzO7K}jgCdFm zIaEE_{j9k{IG&%CML1eHNY79D#@Tsr(8VP0+M*%$Vv8&O@#M9$a3yrtA5agfw9@|} zn#rSBqTL&4H(4qcfMajTUfjhePiR&+ford>}V- zym2v@)0@ni6NF6O{8`u~KEX(@>FXfEoS*&&SImk0_coeKnf$0T+oZvP>F0BLuIC1( z`6}~Q;-|+|!@y4tn3fnm*REbz0oMVa`6DU%=j!|A+++^&+C>*Ps1h zy|s4kGA{h`UD^ML(rJvps8l*_ic%uS_sjxOr_R#g6_qz2<5pY7r2d*k2dYvv2quss zn_`g8O3L%l?f)EiS1|i?bW~Ans97N& z7>d54NA{ADwb8GbTh660Ah7SK^2kH|p5D^t_)v(R`UdkIe22w4L3})x#y-mj6ST9f zSO6S|rasLXpCfSS5|-LvSfDoGEhk?DICTFeY^RI#DoSn2@KTvUe zC<6Z_;^Kdxx8|$I%1y9cen&wuC2OPuHjo12UXm)u`$2x2{EGdWf!aB(dTmW5rOzO1 z{g2EK0Ft&&(C1iy$Zbd;Il8pvxfAYrdT?Ez z9(Tk=C)oK>l11S&tCqFVMGWvhAQDqw{V}|>c)UHG1LkeG z|84h%luBRP1RPxWEjK!7LllqK!4xYlBje|*T2`gWwgnklJ&M^vs;3w&qJFZ%NGZi1_o#(Kb z@?zSX9sXokwJRQsWW442joYX-rc*kOJeM3^F2YnUTx~14abN)Hm!@^STs-;ummy|` zwF8|`kPXJhc!=3Rv|2=WHHNN@^docJv1#j+_4Ff%xb;Zj2(18M#_>#>PtVOx=2CQ= z%*J(q>e0{T-D2`zbizvo<~+NGA>}C5|E%1u9)cn?0$H=*z%6W);Pb=RIb_^~pw?Eu z058=~p0;Z4{_BwE`ni^45zmC|UWpIuy}cx%j{guFWgTgn9JtzZ1L- zM$eiQebbsd2Kl&1xy_zn9*;2X511J^vjrWc^T{gz&@56=r+t(#ucD_un+Yr*bKHa# z_5%Li%9aHt^SWvpG7xHI@4a^<`EoJne&fKFk9Ex5MPaev;`&r3)7wk#m13W!vS&3w zJ;t#jIrslep~~2f;$Qy!vza0`iK}fRh*NVbM#~GBo$#)Cssdem(7@OVUuCVVC*Xr%_)UU#Oc=G>c$Eed3cTqYcd*h4=;cK@!1iZf~Gpc$P?o}R4% zgm{%2rg>Dq@%g59ig%%Ub|2Q&b#K1bKKfStJ)x{Z_XrU-K=XG<`z;V8-Jh2Xx5hxz z$MyUOvRQ%_RI~d~p&-W*NmM!0A=R;C8zH2*{bjZEz+6`2n8@p4Abiwmpwglu%x@2; za;}l_^h}g=mLnX?ptt<*>2)bAFMF3sq7XRVm)bYr(nWeciqJ^)+oOJqFP4ni)S?E{roKQ>iwtfp+W_k3L-TmKF zrGIsc|2^rnDS(ae~N1bE<4VjRf(@2rCV-GC=s> z?--Ik`=GS-&&vQfTGJeH{r2-3Qo{ciNE`J(AngvqvwG)`@y>O(?A+G(2kp|>C6Z|a zN5|x_v299ndYie~UFu~SnsTKAo8qb@+`A)(x$^mM&$CTO=3=Mhwl7Z0tliDN+RCV> z%QlW3A#L^El>X>YtNCY>1vR5c?^>ik#<{!?nGH5F0?3un(Vs>s!bd;fRDDelu%kcp z7I#@mGG+iU5b1v!k%makm*FFCyifuE$ZveF&F7ijOOE%-nX2Y$^?1v$U>|lF>Sct- zoZbAF>COprsbHL5--u?M^AUGT)z~P^+ArTt#v+<2JIa-l(k>RFIa+?P(0d}Hd}Q!> z3tn8ib2i-C;x#=Q)}-F7B&3mXW25-Y>tkniudz&t3JTtlP zb6H16;f+B~>so!=(x&qKqtxi7$DeJh8k5eucjV=p334_<%K**7^&SqJ*TaX21;_XH z>5s3kDVAT4w#9sRh%y|6yqoacL0G7brh`__ysrL;UpR@bfUn0+xq3M=TGmr8b_1kC}%+Mq;$^y zY`&1(i1G`b6q##hX%pM{>fwC^^KmwqM2ZyDC_qu3;ZAXM_vCl;fzYE%p}vENr{e|} z&6XeQClXpCY^4*bXidz8`;_@cFlAhQKNW8K_WWrj5_E=nnlW$e9kEqnHi*A)dq%?M z1~x;1>A!3}v2Cf0k2j33#@za=EOub*n-qv*`c=;Ta?JN%pX1137R~uA8rO5*=kRoO z*A-4VcI(EW#QP%$B1rC{=#LA5FCza2Iz!Ui>v;1ts1UgKA>WwfVNnR{iIn@DM`c>o zm<0TQa+rZ#>L=Q<)h>ESaHFE#uVfgYP-bpdRJ(85vAMmNeORBwAX)b!4W;mlv_ige zC41nXx^qPz*t8}KW1?xvvCICH6L+)c%G`gXYPeDtRW!N=oq1%4B+ByWRjka4hdYF6hPo} zdK;9@&?vV1uLPoJG{0dSWY`vC>` ztNdg07Yy=R5vdbW^VLA?MeTptn&qdVQl7J&2+m6dM_l*z@?)a!eG56|2*&>P#K(F; zH39|N;SCgF3C4W?`6qx>g57_q1eD8Tj-k^1b{+KcF0()VsDss&N|V0_7rQ4_%wVnC z^H4}1VR+LvRTj<~xUcpfUjo_*;Yz=HA0hY-NqXBSABk1nerj~$+;a6m^Yop)?rJes zU=1!R8+H!$e+WTmktrQnb__#cEQo>^+Z{C_Qq{M#q&90Dd2Db3aDdEHWKnkz0+%=s zZfWCs{)5*fuoI1ES+85Qd(j5I>A*(2;^YR+){GFZJTi;#bKQu7Cb)Ar(iyC|zXZ!= zd*76Ps8*mI|BJ%4dggyc!YN+F@n%OUp@QM%K{z6q-s~7ws9;Sr^N)kP1z8LF)6t=k00O#69zkeFuQuwCiCyQ=Rw(O~Brc>a|`Ru=RQ#d~3P3gJ`{m~js`F*o%l z%dYKLehsRC-q*0oQE%(jH8=z2J24P}skZwDA!f;i$Eb9MZuaFswuFb!_G09%gT41! z;(Fc#fpGNYV4~i7!9ywvJBq0MEac}jQbwWh{?L_7(QO^N@eyU3%IkXMr%V?LF0@ag zydGl9-$}V*?Z0bX*EthD@OQ#3wFx*6k%}=s%uOOctqj8ut{Zl%CK~XbR_5UDQy$;1 zrws0(IUhc@bU_y*c^vF7?3eC&?l&Gw%mYAaj)KW2_ba#fH#a*5D3JRWGY>|tdZFX{ zA%6cVbQfU4^0r^)*Ra^3yHC9vr1f7viPG}?%Ha!Za}o*j0yXYBi>O9j*0GMQ7qVoI z(;VoBiSSs9)_g^EnQ#%^ne5LR8KNPDZ!$n-i{Bfkb*_4{x9Du>kRTja9;XNZP}dH1 z?5ewF9;z#iz=xF*UbJM$uLze6thUsXU8+C7ZRzA+XbIh#yK^X^&HcOCBiplZ2+XHmJjNS2FI;|>$;&_D|35E400nsv|+e{Zlf$7Vp9@y3M$ z2k0BSadkXA5^XgzG9vPqT9>iSq~9ZlRi)|KCFxmfB^?>786C?h9!0(LvzkWp-?Lh? z#SvHnuJ`LsWdykrvyhj)D)kE2&>d)(au4Z7_k)FUxCS;$UR(yuj9g%I8OjMw!}AT< zPZL?n{Ei0!b_b(y^Zp8~0w#i6yoL#9$ z?DMU}(V)KTkMhsU7cE1`p7+;nwSWw2-u(2?`6xIhChd#ux@G>3K9mdnX>Y8{hK(pI zvMq>iD6OwrR`!AAuxksYnCH}*W^i^ zR`iFzt5f`X`W6tihPEqzLQlo=h2~hz|1b ztccvrUBSuFQPxdj5O*5P_6uz4@C)6c3|EG;te7Ovf;?BaJr<=rOx{3Ca)&!D{A)<5 zS_v?F%kS#r*sIRNckpWT1eE!NKM}z^U{n>8Z6%LJ6DkV0+}aOh_kA;o?F$MxuD`B~ zGTy7^q``f%46I|oK>&Xwnc?bktfsHs!64N)!Hzh|lSAjkHZzgZQ2+IjM>f7@V+-+M z&mh5MQ%Os{IffWfid&iI9itl*H06EHZUkIp1;2u`|BtzHLcmJm<=W4*9JquF$8TZo7|W$-0t7xnsAsix+G7p zwHGWKh-TB<`9Dvlh!keC(GW$`d(KzvUDmWMt$k^eTX9e6?zx*knI~4*gtCA`p# z+gMR8!76FT)RpU7I6LzpB+bpkOU(29)%T8b;#xA`l7X8$02 z#+63iQ)T;r==qVvT$QUpROOw9a4YV3bPGD^>UsrUyLC!xX>*h|bD7+swFY7Crc&VB zzlo+gHFSlj#lvAia0%ZPU6@d5RLJO{E|Lwy0Z-ZVqq2tf406%$#d`i-SV?bhM$g(Z z(z#=zVQaQrmLUSww<4^M!zx&R(|W{Nm;@^{q9_KoQy6UeiL!&=rrsBSq?}%yD)}j5 zLb@naZ?do2Q-PacL;7l9IlzDk{}HRtY=d zi?9ri>Z=*jDq%QF>`i5->5N7LSEv0=^q(a~xxcR-v9fF?i;KGXc;!sF;=eCKlRt71 zMl|heA}t7b)*9}5CIEmzY}4(}!SP!TE>wkrJDRQ=Bn&p!cI>qOyA!Qbkk^rt1Y0xt zdijB3Ayn^mspc5cB1qEA0X8fd$|P3RugJDn27y8SZxCq=8(8*uKOn+uAfSkN1|ErZ z4~Az_U|=Pe4Ab;wnIfy-JATXX0^#*~pss5;6Z~RSIsbw;%doC6EbNEQ#Gg-y5x%d@ z;ysU}Gw5yGd*=2`t#Ba31aDJl_r{cH8PCyynHx6#avJ@1hzK;b`lbHZ(4z4Pn?rlbj%5L5FxwLR)loimEX1tniqZx;>Yk)@ zZ&?|9Bjy)j6fkwQ3GTdx?VoFwwonUrNRyuxXk#(fl5&4Xr&Pia`oSbUBPYnC*IbdjI_Me&~WhmW(Y zX?Z986N}RO20JfVTMXO>1jlD$#BBjNOQwZatoXN7Qr)Plt)nyZ9H2(qex1eEz7u5uKlxZGOw2-O zyrPGBsXgCbphDN!A+5veINI^fd2q6vwrnxY{dTAr(UZ>U+L`>;SBm0X-Z=F0^6w~% z>Y2%r4yLFNB|(XpEwabyfC=s_AqVd;iW-!-uPw)P!MI4bdo}cJr7Dqv7L#^hCm9#} zu*u^=U725G=O{xsB(*@OzRyuj0beP0bkG$evjoG9OIKgbeqG(4n-kdvPEL0id@{?zg5JxKH?eh4Gv6LWR;@E3HcOfB2b398 z@p08P@R5fwrC5s##i8U-!G8-kSv7wP3;$&g2K6J~PlWxhysVx1kAqXwhQQ|PyZ@=) z+$EX4G?XCN#CJ7_mY4z@{=)Z0D-^Tmmn-(R^_^$1B^RAXVqh(r@SFFs$5aCao*l;m zu(zAh7qBZvlilHlLfMXv{cNKiUa&VRV7*vcvVxxHIsp#Ta~*W_m}-j=4^lg_nYpoP`?(zpak)0x{$XJlMY+l)5)S$PFRB- zueWWs>)7Fn6zF0~zRcwA%->LND&5a1bre!sR<=<)!t!l+7_QoSa_ZZv`7%H%hNsQq zLVvhDg%^EXge34ZZCs*^I(DO0KA5o); zkZbG)I-w5Z)i&h9Som*E!vt|}+p-B;WZS#`aNSUlur*{OqKyn!BLLMIc85I3z&Nh){voMC)3^K+k8BXo(*H4_qPiYoAOgiyro2;E zVSXAbjP29$%C%*6C&fvlCFXfQPtrAR%_btSnYq(X1AJY7z;IZZU{4rA+HE!U*h$*q zbk794^d{iWoi)RKFM*NuBYh&4t&dqCPSOytO_CF;_q8Pk z-q8rQ6_)$^HzMdd-^dC*r~~5f7!nBo=qgJ5b*7j>n}FSmP7uIVLWi|QkN`9BOLt#{ z*`|6<>$?;t?{}b^GC`C6$dzFC4;MtAr>bgd=<`J?gKT2qY}nX8%8kk){n6frrVw5N zbJcVZ0mE4^YrwtPIr!yK5O9$YY~)3a1$%a0#hm}4i~?YJbsNGEZybHk)vzSp0(i@9 zlZjt)^;dfKR*vm7_pp7@H$Y#83U)t!SGQFU&i218srI=+LeqiBgt61l^bAxfY94y> zD3o+=qgg{|jRh*jeSG$gG7cw&OcW2)XdYZ>^8~zB6RT)a|{I zS{yses@yJfB$yaCYh*@A{{t61m6r5as4@Ff`yy|_hPrP+{*{EQ>Flsg^-%n(+8J0) z)6S3+Ij?Rnv<8V%k|tBpvI-sH0~0Y4`;LmUnUyKs0yk*RK8^1f7xp(0E;zK>kzB+J zi}>is=|+P2t6gpiyoEa9-F#tKfg8MTCrj4p}_;cHiFuJTIs*XBF4Y2^ICUP;$weMbv0H( z8UMxkkpWwT)wm^kETTTnge^w<`@6Jbx^0Fr4L%Q!0f%vYf6MK^hraU$m|c|yfH@kr z9{|FwY&|k%b>eZ_c!d$|u-2ZnjEq_N{euL9$?ZwHS7zCFvq2>%;dHUGVO>4F&4bBp z`-CEvkEB_{8-t?H=-ZBMr^@GNo?xO%@Uy$&M)Xdy$%fNXeFP!QE8Q74iE{b&tYVYH z$)9}V2yVv>quaDiBpya^Au)#eXFZ-%8JL4~VWqEm|4#a=OCFqyyQyUEi zzg>UGz(;c3OLsM1X=ZooMbEK3pcTD0^qMVW+59#Iy~sCNtWD)h(}=A(l%{yXsT2{U zAP?|!7AwD?P^b6LJStSqK|{tM4W*QhC6-Bb92b32u>Sfr5U|IlmXBnt`*FA5Hl)^6 z0L@D{B=qr+49920Gb_9D*3eV5D_}~1d2tEoED}?w0#TlJ@yj8*7jz;Ck^rg`opYxlN1?dL|vPio^ zS=U+*am8vUBCRm4BwQW!NJf@sO!}$&v$=W4EHsw1pK)ZstlA!So!D&V z>WXu+)&h@lvW)zAcM^!-e$nSglGDZ9^4lBnox^>BvOCK_b8a8kHbWRZ_v2>Q^ON5h z{UAxV1Y5Y)A<`sW8jtn4F~*AO`B~CEs`2Aes>y!nY_f%CCW3cpcNUkjiCDpW@RO$8nZ21@bm+RZf>>*0YQYYI6pNF%ixr7(U_59r zmUvpayJ~jO!PcdtEZmbVH}LOTh_}!iixsTARvwh%cL|+KuL)7OR4*Uz8(S1t#*pcF zt$6$&t_L;jmsrPs4SXi9@$?6K|xMDr9spE7z^94G% z4qv}yF%V5pn56UF-*M09h0%I&EX#M(=*5Q^bd>?=z3cR3MA|Csr4@0eL~1zN1m1R1 zzP8iGjQdF!H}#yaOW?bXoZzO;n;SNtYZ>Und_W&#fFt+`xw&=kEp(R^@}1pG%Eb80 z?mRvYMzG?se8(qqw_v7h=Cs2CeS$y&UB`vt2VyIbN+0)l1OAq({`x`wK{imrr+%Ge z?Od*TBk1LPmSs0GG%zJa>pFFf4d_Y&pnBR&ze_hi`%R9ymoY)e%?aOjw7S!0-2i?6 zhUqfS^!_LU)9TZ#g#ZH4Tc_P&X_YbRX3T5poO`ZYl2^e<=-(^!JbSD}ADO2|7YUwL z|CX^zT8{pV0Sux3%OsIO`qvAZa#aCO$tRHO@PXq>U-YWxC=?L$7Z-~5%Vdag8@*1a z%Wf~!TDrE4V#RIR${UfQ!X9<`6n!ZIjbgAhyiKV%>!{K%=BF)sTbv8^%PCafBT~?r zy?0(9@5K7MwmFeI*?hx$VO693BW542Q4lk`c_)*!JoD^cVqi80a?8UPbg@VXwLm6>mNdt*d zQcl<4r7EG_S%phZW^;o& z6%%u#l$Ms6%q?C)>pYL8^aC4-J<5$%hcvBar(~(zL=gQGiH33IW(^|;&xQI=pXhHD z2Q|>aDAA#9ue2{<976BsGe|}AH?+BxJNsDv$b#_N`Fy=Xv!@2#c`|C8`~=u0@`=Cj z-0~=Lp>TUUg!jWIxT0{q?@1LWL7Jw!hvQ^1O<&5|CZZV0w1xQY{iP?B`Q`b3G@TO% z{)^~7aEQ@|ZV|jtoGg33dOik=j6qZ$HZcQ2${LTbc;Q9vha9~)@L54{po=KcE+VVH zp*b(GHljezsrkvpoWnOh%HRWCGI+?EfLSkrpvbDYimI6bPzA4vjG_%}$11b}7+!y)(DV4n_Yx=j0U zr(T<(WdquwG}`QfYJ(qSlSE_T?cw0E=yrnJK0O%FDzGk9QiFihXV}ZbRGTLY{n^38 zApf%9JW;H^w}Cd55Y6XsyRSW4k>C5=O1}IIKDhsb%=-IEjcY!nI0ij)_w(DI7tK^` z-(!WC->_>%lZLfx|4CLf%tpd?>3B#o|LFbZ7~hI=lUk}@{?m#(Dya9nbdu}Mhgs5z z_RrDOWol!NU66t`4p#dD`+{*hHZ{v7@Ay{T%Xp#hH7;O`ru5p4SV&OcjV!<{gBsK( zpL}VTyX+DCd9uw=(Jk}H1^OrR@Xn>#u050aCZuE(b`W zh{M%&g2--}`6L@0;ZjTSGT7aDB|VCJmiGV%Ug=B%BK9y__53HUp7IaiSVji2etIUC zI~OZ2=O*`F0-h>;@h89KQ|o4SN3?sx-$`7=d*^oyimC;3rmTk@m6l0wlx7FQWIpTe zeu@aPw3Lstfk9rLv4=@Q8T+L!Y-n9{G@Dp_15&Fv2nviIU*$PM%_P@^ z`>XxSl{L3%Wv>ui#Ktw~fOans6nm*rKq>Bo_#1r#ovt2X)|f3=r2bSnZoPh6vF|qq~T7V@}7OZT6yXzxdFSc2JDfJo3+<8H8|^Nth9l2+Xw1(5D1qgKKc{aDVYP z+Oi>P3T$@&y-}!nEUck4@sZnVrHB7l@*QGa@0hJa=vUl5p0oCo+_dDf9|c9<)?wy# zBY>zE+LfNy8cYfph@<~!2O|&_R8U}jY>#d_| zubzM4+umXXa9G@WWfvLmL#1~+Z&?us8fIDG^|;c?UkgkZ6A6*$Zz)Ys1I1?tQvMc; zp??Mn`welPHwb=jBGE{w|>u8>w&38 zh7crhadJZ*8Z9>E;K$Qo3uJ=Iw!NQ>{LpHv@#n5_tWVQ&Y^~idgQ9E4v0w~4GXGQ- z|F?T%z~zpk=nZTnFwzex8{d0fp`VXulhk8Iw1kFf{y32vERF=fis-u{TEfa{sCF6o zB{n_SZ_#O(zRqh6()lP3;-VEsNg~&jIowIKI!{?kzROr&35g?J>5e-CP+8PZQe$Mo zdFK)o56U{t=O%unhvsMlt9{+tlMV89^;1`;jscVq%z*ombzy^ptYA#xos(&e7L#5r zKc>>&5ab@TMFxi=o+ar<`^E0EQG6D^Hk znnq6TZCFUxC?ywp?vNV)Zeh9l_FEy0Fnp&;B4KJ(_H3R5T{u6f~A~o*#u$-{ocGEhaPwPcW;5%ohMD|LI&>P-obRG`Y=xuX_h!F7g_Qpd&ps*E z9Wu}moTX<|h&`mBOOs0#YbwUJiQkq#+0t)+Hvl31oPYY(l!+#yveaMHkbAaXx1L_b zy;AB;LP01XDU0X9+AVeVtvBu>hD&xN-O*;#;o-B4WDDCaRA$Bq?W;3`cSrGE;q~Xd zYd>J)X!ZFZLvqGMM-qX>UWTAP%H?B+>!Yv6FT9u|(D%W;+# z4f?5_AFRKCLL&p~owv2pMEp7C4LlY@zUm2f8bN%3sbFhJfE`=(-rw|EM?-fsIh4z8 zPQz>5cP;vHm_eWDb{=T#tUp_U`WPxs3MAuPV5^Wb4C7)kIBt|TY9FIzsqUU2v~3hy zo~@Ie=C=gF@p>_iw!l_Q58+hV8r%OkpBdBUN1E?CTQLF6t6vm#Z=078p9`9&?QY~s z`MCeSc4~5M4{TGDHN!1;%$*Q)l+7 zIV$K0Ut<9JiBTMQ>WorKMm*YQ_V_a78Zd_D{4Dw5hM24{pHUE5`{LJSyWdo(QVTM? zJHalL(Z`<*Kh{SSC-6LuJ|Ssc<`XG*Y^WW~7Ga(&HKI4#ue_m+CExa@Y0AC7ZTy44 z8EW)bzE5y8yv&}^#c|&`b}U8NLxXl8a*&VL{dXoMRH^>oPX!6D_)Xd*o9&4XAvXv+ zx^EnsPTLzwklM3{H%2+?hlG-z=-P#5fuRH(nFkR3*@?F!enpSi{bJEX9FiZzQ@_aD zNX?qp%ol__iWlO!{@RSq8kK2;7AECiD3XNk8dH+<4gV6_*>m$_V{HD^co9gW5yp@~ zB17|S?}Ts6SvEUCQ80?VuvO28iwtq(`C&ds!oh(Im~V)2K&G0cRjz}Ys?UK52zgaK zMItw&;l_#ib&Qd`T=*R%N4a5V8(m1kUoR@#$iE3f^yy3tvtN@tdi84h;k+!=Y?Dfs zl@gDg;_^NA5Qy|Kh7|{q~LK$#--W6nZ?lYR>!04m+`04un9&h-{w{jId;R4(fbhCPT=W=~cO8a`f3YvR z9`}4LhsI_Q2hxG7AHG<$;vCP76M5i58W4E{@!KbHPTmzLE-M>+wjfQ)+gJpGh-vVR z*K1V(0Yj_8P~^U2Gt_R=y{Zj+OyF2UpW26coHE99(ZaF&E?pR5-r&v_@C=@|x7HT! zVWr*W$nH}3yS=MC;qs`mYO^u=Qe%qV{v!yuYJ?c+TQw`Lk4fJmcGT@(ozqtR;QTQz2SM+ z0cB$i;Ta^esKUjR?U~Srf5)@K=PsxQ=(I0H;Fv6gzw-)i!sBVL#^qr#LTcl!;_VUW zHePCFfW=~(a|Pb+j3$z8Jxby$+}X*68qKm#o|vtM_L(`vEWSg!b_$zcF zA9Psyy|-}<68q~YsBqXogN6GMCMjgN0>}!`ST+>CT*>G$ik@#mt13oq9+YvMwlgvd zO;w>+sz#ia3UEHW8ta|@&`{X(6EY!>r2_Xv+c+ImjIrnT)b*%@U7yFrhG{DQ_isE5 zav}TD4hIdex^fmGzz*9SWSDxlav-OZH+&#rAt!}tqpeeEpP$Uf%*^~x2=UvW-Gw#} zvJ)mfRu6c9@6L_DC{S~(E>GacTa|T+r=tBcYb<6C*lad%XL^jfzXohRg0b>&sN(^^VAD^ z>Hm^$nqm<2F}F~bZTTy%yjfsw6%pviIWeV1Kxq1xxpjSr8ClPGeE!zQe}AlE@Gh^h z>*)^j@`x^fv5GtG+r)R2WW3$;?ov7Evj{ABT#bQU#q_-@(tlEQvD&Jn&Y)JNdk?e^ z6fnVECwpC%AoO0Z*2J7wO(`XR#|F@BQ8Wn#;g52E!qd~TpW$8=Y?d(Yi(Q&dYlghb znjWZ9VNPBYI+t(rKLJf9gNo9^b)F=6bRA*^kwV=k&-1#!@8Z{&8?$yrg$ScdE$psp z;JYu@UcZq*`AH_~gUeH8G!A)dHfjJmRQa^ew$F;=9OXTi1O`r{Q=>=vY|X?7+GQ89 zpPv5e=$H%``zA3i^|;8$Fs?1Ec3Pl{_|zf|DD=Hrf?mKd>MuC0dZqOJr5GnLAnV&| zefh2T2a1(2DfuBQ=6J%?E%xqYy~#@|sX=)muq8&mw1R|#kY}vK;DMZm*HBMX*FTNF zHD%qrIT5t)te9s&oZiTx>mQno%ha1}9laf#SO&lQ_MkIU9%(V}`Sr5?$28{K>({DD zadN=Ofr!#QJi&U~u!Of-M8?f0^UMDaQ*RX&SJ!pjh7byZ6Ck*|ySuvv2`+^OclY4# z?gV!T?(Xi8;1b+j&gOZ)zqNB;7qrH%+H1`@dLNLEO7_LpyVCBB8qb)UOme<-Emir0 zs_HuM7&?yl{HJypl?5e%?|i8G!gJ&xi=HPh2UNeBeDp`%`WS7uY0NY<7c{gwr~yh! zv}ChDGN^INz!&LR0r`$XJ`8WUbIx>a*sn7bTBQ{g`#D$!JFgYk6f{5IzL;0TBP7I~;{>EsWcz7F*~KOoa}Mmq>S969boRtR?m zk)Jv0($$0g+dp(=iRcO*OUHQpHvg96>o<3H2TCgj^6hknyEvS z?IN>N`^{wI5>FO)T0M-hlATZPX!XcD{p|JEdT>F-=gQ1&#UG{rrs%|m?voAKurdfm z^hfcYuNrqyP4rGY_`0%cbFVVP=1e~<&RzNS^q;#m<3{5dw-NU-?mfr)5{+~xS&v{k zXVCFQ#i=dJrZPjACC&f?MvCwCX6DEV;LswfV19dQt3Ry3Dci7gGO^XLwxYly)Q|DM z3*+Zex5QSMowOn&rW=f+s7~75LFCRO?xx*gzUsS`G*~3KrP3^*?UFo2IwQemT zD-7Blu@UYq)Rj$hlS+?1`e=FyBXJyuz8nXNukgWM*|H?XQ^j1zGz1>bLQZq%0E9%1%4D(A7BO;tt@pe~8a5z}(DK2+V< z&X>s02}5Zl;$q>mZ0wWLFFO$|v+y_(Yf7fQjCeVDa&gcQu3NL=!HelNem&&V?d3L( zL^KW(i7pHNz&K}Wfax`i1jTZ*14NUOeh4Rn5>aV1utdC+qKeV{qW*g(PyoHEGs_*$Umq#4h?;u?z?xyR0x*6}4j6*82;k$)ms zl3+M962mXo^0@6+M)LO;Hg;wge@to#vd=XaG*2arOF|=wFLM054#*y!Bs_7KdcB{m z;Xul0esII`@*rnMK? zx(6xaR;Tz)*CasGW8c5@K2aQP9)KqnzlfaD?e6$5H+mq=9j_y?dDua%6ofKD5d7hE zpHac&wnr;>zx`Y+5c@JMi6uCZ_d9CF3h<=wopg05;%0*4!yburYV&Qy4G;Ee)@(A&ec^?fmIFX0ke&oQuVlayx?elsQycG|Y6^=@jGrP#ya0-DE zqFk9~jwR!AXoHnyU~Px-l!qqN>U9ax^8y$ z5qkCPOL)A@H@=82idEOsrzZo|g&6mC{D#r=JMGX(kj@}d#$^gFFKzOquJgz3px)s%d{3@aQ8v` z_>pcxiEqLo8_SGhLTCF@Eu+r9Sdb@uVFUM8VwGG)@XF+Ro_q|fb(H1YP&bL2F&S{s z*gB;?DXz!o*U|E2H!Bj{m{-*ivYi>wveo%WCYR!3rF(eKGHwOAH|))deW)>H)DN-!F;06}b05rm(yjzK2v!(m8~H>DE+#3=V4h#JJI#VHPB$k`U{s z**Oyg-CX?!;h~E`+rhA|pEpEA%R4`B7`aDldQxr|*q55EXaqX!o)d-{%@5Hyuj15u zVoHB}Z@-sXsx!_HoKkcOSy!~62qWdBC;JIBiuK8QkTK+UyXueaL}GABnqD^BV~oq# zb~YT4G=bNR>}kJOM&Z*;<*#1gR8KI#oUY~j&VJ>rBE;g&Ji%n{)lb<>W?Jgv>D1N< z5>7P~FcTM+L#`P2x=Uq2mIg1&m!x#Cxmz&y8#yo?Y62SzjZtWZ-TRT=u2Vcd$HvNE zU0?A&{0nk>K&DU_>A4iqB0%nS$-NR1nSX0FYwF>$hCqpq#9C= z@~aC&vBLenwXsYDE#p_%pvfDxV6eD(FM&XZsa+;SFavqeEP+)HAE&qnq@kTwln_Uk#Q|)6;1QEA zBqod9br(6UvK|EyXfRK7p9xyT7}o~oGGsz#pL4bm;UqT)?=HtJzawO`*_cNO@y5=I zo&r8f%zoriAO9iG3aepu4LQn^7(et0HVtFNP>W_oY8%<~|VyN#CJ{!myFRX1Ll7zQrC zh(e>}%BS#?=t>wV3B_d_h+3@D!+82}9ku+AgJOA%k9`fA!t{<+F2@-iCZOEJt%~#d zY(kKWQW9*Uiqj#3HOoi_4>}TIZ_NgymrW%U(m)t(ukM)qKj6zf9*mdTtogD>WYzhd zhx~bH^%PsS;DU3rOE@*Z6XZg_^2))pxIc5Ia5_=LSC#q)c(`;Qnr8X_p5)tZPT)vV zM~!7_5odK%#g2eJJ&fo%Q;`r0#6@S28vge~cl;jK19qrtWH9p3e0k;}3Gs`o!{~$Y zm;}N?)QR~Zjvnze823eQ>V)z4on}X~7)R5AhIv`(&-9(MYFmx_=d1shqc?oW#BEuy=34sb z(b2GY#N}em7lAbkkHpKkR5mI>F123Xx3L8+j_6Nt-1{r@mkI!V!jt~%gi>r|6_v&c zc|(P{3pQ7K$y~40AktZp1ePaXFljVdL&|k(!&>X(O*tklP}ba>HX}eJPsL5~c(e}* zvt`N(y_q9KP!eR`Ud*35)v(0^h8~%FnhWj`M(OmqnAXv_XCtSV3a~lVq%k1T#6JO1 zciuk~S)SC;eJhI&CKvAwy1FQ#E5lO_O1Kia0p!eG^Zy0T1UjI=V z$WqYPh)zIti2k1EV8f)En^#psr?0}|C5qVS&%A(Pd8uK21{Kl@W2-+9TZQm0Sb!$c zQ3+=j`G6R?Yl?65K6g3AFF`B^~qq3uw+$+a`bojDr?RfqBjiE$t()WGD`V#U_ED89BIegpV(D~n}$T-pJ za@QDMXWtn9KwG3_;Na6xp>D8f9)git5Eb4RwL=v{!Yn`S7xnFQY}qywK2)XhwSMS{ z0%P_nRA{Hz-yXsvJ{uH;SsN20;a#pS7$;-Xc)gYtj}1Tj4xqS9hKZtofL;z|&i0e0s%1GI?}Wa)pzl3Miajd7}IJ`yaRklZCnQ*%3K<_nVepT*=Nlxe(ydc81n1;QQtIevACm zJ;(;64pH~WYiVKXUj2}D@QodvD_xjNXSFxuk}zG&8-Az%BVU{QkqQEzWW<5q$MRH6 z6iz?hm-qKNo*S~t6;qN<_em07I1UgIDm`)P2$uh}e19am!+P%`xJkv%|17xwjTjRL z0{#@$U${6f%25a;6cTI?%4V=vaTww5GqUF1ALwx`*MipNU+R_D4A&8U(oALp%B6nz~1>+AB z``pkE3lwyhSKTthKC{fNWPBkI|F+52$HpmodYSZuxkU&qf2C(Nt>z;TNbRwVYQ(@{S`XPbmX$6ELAC68Som;`NF--u(}3o2B> zK-X9}>KRn&XvuED`|VeTm2bjaS<@BXRKVxkI$fVVwqgO01iD84@w#l|HO7?18lDUFrx6)j?~^%Y^s?# zg4kdo13z5v6jIl3|ge+@l1Ft}M)wPT}B)YGSy(Q_qN1eB&f)fucvnRk?e z%-2=cmOUJRK)R}MU>aToFg3LJah(#2s!H5867c@xY^Jxf#I4fW5zK*vE`|$ff#22+ z03i9nX@}Is&Y@r;bgD(L(ouQ;8vD3U@1)R#zlGDo=5bf2 zvK@3n87w-@j;z>Iix}WX*RvHYc8)QU$Gs@=FUau{vu#r+2+|eY1U3wu4)6?Q?7&A1 z`hYza3LdoGU6xVQ(}F`Sln?s0$M9k6vft+o^@p>yhyii4dq~n@)r6zaw;LVbAKVvqh z*8W2|(4LO(W`u&v6*rMQo9(uT3&aDLEm@XdkLwr!m2bK>{ZE6D<6p_TAApkdqm2O^ zfvV$JJC-E>#D81;3|(n#IAE)d-r(?=OB|Z|Pa#Hv zy;UGos2~*<5&zg#(`eBa z*)kc3yUTZggDnLSUgw-XQ_n7GZkp&ClA4PA3#tqYells_KzJ8$ysPL0|}&PbV(E`ZO=d;rIil>I-viV*(y1@S$)#xzsH ziF7Ai$rshRVvIhsay5N_;d~W`(;D%{f&%tdlxu4i*n8ZyP69*%?vTdtSd3>I?NQ4= zKdi%h7}Mp|X@WkZVBWnt>X%n%L>XkH?;Yf^*uI8H>P9$~;-HZeA`RxzHwfn5f0vH;eGpXOxNm@T#`M zb8uC7A{GL>Hd}vlM@Xr^qL){xL2VD?>b-ItUZ6s`^iNJs2!PkT6Q|>*VzRqfiDX=` zWCan68RqZvo`wGThS0mN=N^zdK?uA(xNzr!c_Q#L@wLV;w6R48-<0z6)L|^>dke}9 z$0aVlG#FnW{J7ua5C}NCu{8F11(M=0Xp;F7Nl}9Z z3qhYVaFOXob@z!!`YwD6KY6c|xlW(2A~em)*7@uG3s-wf1W*4IeaI}Y`!C3$x<(Zd zV{iFN(_akC2`}lMFl2Nu4W~6upVZb9cuD(pl?VNtS-oCuKOMMe!mH zN;Bp%G;6UsI>LgOQllD}3Be9OzhP9bD?az67L7!Wt>O%LBbuSrI4f9kT= zc548?{K#WZ2+3(8Wg2r757zdQ+;^D<8^dQE!VYK3DM10_`?x@iP@>q{o2s8$HZOdjV(JUmZy-6jaYlVXA5PbE zTS@Y+<7F28qlHXN*D|E~X}PLg5oiO#fRBDBw#Q4K5e=tC*hjwQeMm9SXa4h?&1#N2 zH;3!5(|W6{O3B6kd_UM|_tNF}vKdP8`jH}=7gBxMa-&7J-QBw7{g(xAZUZ>)}D;_}HHA;_AqcOd+Rh$k#~tFqFdZa_X6o9@kM(DVHr2Kdu@CnO?5 zGFl|KKAr#iy|1V~^BPmY8~%8?4oOq%#br&&^zi83|A>H=>E3vc`TJ_~mux-OR`vZL zskXcK6nQ3(i${m&)wo{JV#h7>J%BZQ2KMa??H5CX-nVr&-3mVLt?H)C_TI(x+F3w? z1eeoxsD-$WrYT=FWqTkp2*>)KHT@z~p$%I1Dow^uEo)fxmHLJMI2}!}&@1VgLyn4o zKa2cnra(sh-X`ss;ol4!{L(Z1bJIV`lVS%KDXPYPc7;EI-e8H!{fw-h@XeyS)i0fy z#?|L9+n(BZoZns=rf^|YF@@0FbhHV8p|z|r`-Hf%X5d9d{x@IhZ!#P4y0b1_rpA- zc?ota&qpI`{hzj(kA+ry?U|WU+ih$m&D^FsRKN@?L5?6eIy~5b z@~l3FTR9Y_cr(2zB$A9)I0zUN66Z}uhNauEj zTYYvwn2lw#;|V_y5UhVmqVxC+BqPvrBsP?Mqtq_Tzt?~|t}@>Yg!CR~BsSiI6OdRQ z_aJ_NET8m&Y`bf>5$CGgK+V4A-sXRt#+hnkp4%+)tjpf{U0>e?o^l3Qvj+pa5M1gAKVZjaOZ(uk{5U}y66;hsc-8oZg;?PO&`KaFCVQ%2VXMlFQ)i)sc9n0|DMLE?AVOR`=Wm3rluet3D z=OB^6ipOQYJgrZfMA$v-R{8b@M{j}o1N_K7((8H>v>mFR{j^$j-qJ?w+BhO<`e6mJ zZ_b7@ZezSFh=|7Xii(zvbZX`^PM)l`baS!_4LPx`VFPQ#pjppajF|*{6Vo?re4Z$P zB!ocoNoA{b|9qi9P*IjBNG8)3RXuz^Ai9&>`4(dPScpFZg_v!;Kcr zb-u@^q7w$HllUlfXo$4mCTOEa^}zF6cTkX?xtj7?349DB1}B4C4MIiF5_h;emmJFT zh{<$Wcx_r}e2Uo#i%o+mN3b>gAX&ga9{ms3IE={h8+r%XobCxoV{7Rhl5A_(Y33Fy zV+$Fro)M^`B>Eo$0?i`e9L>)eJp)#;vYp5bU?UdS^+|SqGAXOGsIkKzp;QkxCURcU$aaI?an4?``4C|F|k6RP`zJEHw2w>Ho!*mh%`sWx&g8GqE~6% z4*lOVk{?2?1e9~brdZyff5$&TlWBet;+wFTk*~Td+%@ZQdL_pyI%Iq;vMj zS}Ce^Je;G-#p8V3y|LE1fneh*aDBFpRN1tJPKnqOpvNR4nWwKbZN-=j!7Ydg}(?snPoicnXd@#u$*eSYC^uTP{| z?D-!a(JO-Vg8yF;+9J@KTMW54W9ja$?wB|XWRalAj zej`s0t@*T~NTVmu&se!7tWNCj%G6TJph)yHbo*Cj!`A@QGK0araYn}-O3wXKi;V(@ zjPxy5aTVo<%rXfTpDOu)i>_uPR)5r<^G}$6K0PalUNS#Pa0C z{t}SldMa!r5x!7N@Q20cx8D^cb;uhY5O!d{{k-39IwvTgP>mm86^GJdZuHSueA;$7 z{t&+!8z=o-DJ%eCZB;&nF-UzU1=c-cBbH?F+%7V*NqXO{=^zg{ANOOZUw~nJF2c`x z_WAFGbi2i)*?He#f|tkf_o&nWoyKL}RAhZr)=wnQ4Xfu6Nq3HUX#R6GZcIXh6*Je&hmrINa90rfAM;SW+oUngjfU*`U#cp5t`0B?;fxcr}Dd zoz~PN8K8nxn*&kJFjP&+>%>B!4_&4AA=3*aSO$wh%bBe%p{z(pJ)B-;e~Rzzic)3x z1VqI{qD9*ftvg@nb)CMFP)oo%*{EdgOjw|v#fB_?YsH*d)GT&{lkYP}@!Y5#d&Qa* zR~ktkAW>1oit)kcVe{YVC#KXd3`-V_HY#_ksjWi*qo?(N z&|P5Lf8nOTNizYAL=is&o(LsPsTIe}uADKBxMcmGGI+rm?SnJWL|S^<{VT(21TR+d zd4ub>q<_5(I6)tl8NG3sg`rkV?T#Y-b{WZklrxHxP@s~WpghKCp4R-d4ibwZV?t>I zdO;Bos!w-StBrd>#kkDy6U~>{DJ*A(E`)18j3);%Y_&B zy>*-2eMdLbHiR*+0CCNeH_!iOH$h`Earjc@*KXFD$v_!A5l(9H zB-k>#qoCP-Z}gsgd~>0K=Nu(d4`_%W7?9wQ_X9-E>Gxiqug`A1XuKlP1*C5|cc`zg zcP>{y>K5Bi!zB3%I%bNj+b*u|DF@dtTOSWD%9HiH4RSjBK-k<$F)fb5vL$8ugalWl zeaW@{fc6QN*?#Puy>j99R4ZcG>QM=bVL_fcVtsX_3dxRK@RDv-HjA7J5nN66M;vfTs7FSA$-k6?a{1%Cz62(; zqkB#^i^z;Gxc^myDlaccwD7T>Nj)ME>z_*-%fQgDJ;7|4kF0<{3a{jF)rZi?M(c{A>3ALKGi|zm|-Dh>8&zv&~0Xpc2!+Alf(XE0j&h=02!2c zFCI@i*64mC1OH=!|F3``gkZlmyzbSJTzQ?hk+FG6@vsZMDq7~>5=gz9*xJA9eHd{0 zstKazHX2L>=J4zOlz+{HOG|uyZ2P35cuwQR#m>kbl(DLs9^WJB(YOV7S=0F&vUwl+%5;DGhNF$; zeL$};$#*Cj=4#aEx3b(7hp6zG`lMVm?Nrd!)*;17P?$UX*+OD}TN=*|FW3f`;*?h8p zHSuU`8Nj7`#2BUIo><3|K2LQUtCX672l3xeG~jJny;!ZJS%E%hvaiz*^OQ7eIugdbjNY1GXe9kL&3oW+PG!lzkCA ztTLMCN)q?47TI4qU&nTPeZ2nt;Ymhw*~6wtqjU4Zh?E4{aWSDtZ=W-`TU&F5)7%b& zOa{{ukaVT@e|=x6@GWSn15K2ZxD@);N6CB<(WMwItU?x9Uit=t5G5cXub$WchzF|` z@*5bOYiqcnVDfJd*(XRfaK(HF_EHfE8XIjGMJel;WJEvs@{uhDv*@!FvmPEI>9G1a)Cx!;hN zV_C_2@#~`pe)Qs;{sTg+h}72mGulL1pQb;#8Qfcs6&}5Qy?hwzj1P!Qq-F) z3k&IH_FT|#mB}3ahh>&>KrSvO1_ixNiOhkoUYI(!w&V-J$`P^$nsu(!gB-uV7hrIr z>U2KkeOZ!vR#vGL=@{Ne(@Tpr&`!aKAZpAC%IIbQ5#C)diCc2ej75+FjqZ6btCmzY zhb5=cK5ZC(A0{}qq|@}SO3P}%Wp?u;e7aqJ)o5#v>u)cJoh}x@B;h>ThgV)_bAkt> zhpy2RPyGycU|#RZZ{@%)ARME!>kKykzq^Kb`xLSI1DQ;cL(Iu$@LN|ji6g$t0qabp zyC#$K%gy5XA)~tuCZDxJB_c5wFdM^zgmkGM-|;{ac>Ywb)tD-9=Dzs5_{pkmD_kvh zn&g-=_E^Dli|^ibK%lxUEluQopy64*?HNs=*?t>o}h1cvgWi1nPsbK)!=+0j)?4$ zm<#{#na}we@646t9je){%R(7Vt^)Eu?=y$VSgT__bC|SPdpHdKpJxQTNCCg!2Fp$! zZ;s&Jr*4o*)3`AN?b~>7-G274akJiHg9z^02f*zQbU&(Ry~~}}y8d!n<@egJ9OGRy z-K^MAGW`pavH4O9p54g>&m$~)^a$HW{tp~dC-F`5)-2~ug0l?N`xRyuZ-^>0nVUac z%1*sOzuP|oy!h^NtkhTmT#og@#xm6Kupub%RxnkOOA5kK6pTJt$}GJaJ-uZ8nd0)U z$61PM=XvQAq-B!N@+=k9>1_V2Px*$3tRgpPWB&)1yoHUJjN=x6`UO>RAy442d~@bk zQj`frljVU3fYKAKR0J*v42Gi^;bw)4TJ@n+3mL`^qVv^;KvgX|e-wZ)0z zZoTo$_aCeyq|fz1>~m!;aFs?J%YFk@S?!ILVB+%hfoIX{|4I1O)_^61@IY1^)@ys4 z#wLJmsmkop4Lv0lkQP+6<+g-{*(G}`l)MhA-mu7 z2%dLAoNpp^qB@_f1VHqy=Vy}ClvS||V*%RCk;))`FL&?g~JqZtw$DSR?}=+NDf8Ff;~dgW*}J(P83F7Iz&&ux~iFIm@j z8q+y!dgqfmY!rDaYzqYFiF_2aN=vZ^I+}mXKbDsQ%7*wm@QTYX1r!^{a-g}!N#iLQ zyN;!6QN!_`{+9~N6zYBnrlqyH9X^y*hUr-Jxl66bXQM;rhNjNnxYmJudVjXr#xqxa z_jgR1-n{pt>Dzt`c z*@>G_m8e_G zXS~F=^w~}E&u3rT%-UuLuN~Iy#Lsr}MCk|6h#5p9>$pcX$V^ruaQ0g4M>8C1hyP)U z^Ak@`vwf2n#zf1A#Q0H=BadcsG!W^^(1B-?=?D)p)+C zMYfWX$NQQRmoFk(sc&PLX>9?lU*0_JW=c5xOQb24-=vG~{>g8G<0y(CSo3-A_)qWU zK^X%`38bRTXvGMcr8aO?MeiU1GzfcRdLMWeDtbO(gQjg)XCk<{_;gtEAB^{%P)?P) zXvBaaX>4TS40DosVTE+man5+WzO* zd$EJE=4PyQ^M(L{T=FW(Gw5)4iKQCwpdWw2j+`s?>^1>amtb@~OQ;w8P41wmI2mkV zs;Y+4iHhk*g$8HM-LHw1`sC_WSP=;lXEOQMNsZc&Krb70rQ*uZwuViQio%}kH&22_ zEO?ByDnPlkMMCj%*D~Aym}-(lob1aP^=c!lFZt|L=*jRPuU$ur(e^lCMVzh?JAo1w zJBOy|lE#~p5%*Po?1kY^3ubQ#p{@WzZKvc`rzi0{l^bC|KiusIuN0LvugEr;&^U_{ z$K@e~!e%PLBy7fHpLxI_0Y2w50!8^qxtJyFw*{^cv-$@cSUH(Y>31o_9M-}(+99F? za?O#+SR9Ci2OX868ET?$I<2-Q_{YZ({y0*Gs&3bf9#car(L~mi@AyNk!{}~!ZpsY> zJwJC$;uoQ;xK9mT3EQF6e?}#iZOJo1>vUW;^q0QFa4Avvoafg^DvQAZmcK2$2xGqZggdoM(z z0RddlnigpLzDwH4u-r8QUYPTed3Oggf7^O>Pp(P0m}4x34@bUJAIp*Y|G5C}rOnE# z0_Yezha5IMbGwyH(SVx=tN8AA7W`O>TdY&bNW6ch0=2I2Ga|kc6kyBS`+x>DcJN|E zJ{?vQ(CX5Q0-t~ftXHD&x!@~YQM0{Jg=j})QLN+d^l$@qwu(Nl%SoP5@Oo|#BCX-9 z=c@CWu&Ss=`^V->beGrdUj(b=PQ$XgM{IZVnWzQ_=|Kfq-h4sNdmQ416CWXJqV>2G zBc~B}ybT&qHOa`h!0QC8m14?Vj6slBVXU)8?#(CGO1hvl>YD}L3AtIn7mAOP{QCH* zroEz$M>C~QrydCeJlxi6W;uzeZ!hbOJz?k*r5*IDw42>-Z}1NaJtEg;cK?T$T$`B= z8+ul*nLo=14Cg6Nv+j=QOk*xopgUE1G0Tz`ImJJ36PCvLaFQ~S>(Q>B|KlWh)mpjp zddEn!dNL;!Umcn!gkIUC2VovI$n;**wKinWariev$pwxG?jG)(jR^cMcua<4W3-<{ zLuI7p6OKs_`=n;6L;q zw?ZUU>&*m_7=Ps^7=-*s@;p(R1w4rs_ld4r9qAVqcY4_$Xa<50ZoNX)_X0SEtuk3X zta!!Q)Vj{l#>}3@0%}t6OV7?KIrCjIxCByce<;c=%oT@gbxdtkz;kQ(i@EA^yvQMs z;~w#Gp#Z_XrC{M6d(t381Yne()K~q1h(ZJjmxi_oj5!>huU?1?UFY`V?ybFDU_Q&} z>I?-v>1@LsZAZMltz3y|!u0=++2-`N9m|wTSR+3Gzb+KL$-eb-L_C*1`$fSw{c{+1 zN8FAgL;@n`;zCf=#t&xLr0GLu*etApA(O}K@v}T2h|mf5Xv0!Tz53gVN5I+Xpn4OR zw+x$YL@Utw5GuLr5hJPRkW8T`w0FWIH!jon_?a6l6=A?s0Hx|dg%7^r!45Ot#ONRA zR2Zb7kPKo-aiEyMDu+j+Jb`ztUbex8y4iYg>Fe`ew;#2tN#X1Q*1LZE{Ru$DrOVny zqoH!MNXy<99P0-HxE<^1TqO_rqA#8O9E;Z@6YN)waQ#L6|C5BIt>d}I-X>g{n-IQ| zg4O1p)Xv4?^$N-;xDA@698PESBih<5l_2!C+akJz9sb;16-ix4(c7teIuyPmqg!>n z-?lv;Y=R+8Q>jg=LIv22&dz?1kkHi#C&-2YI#T$#<3UPF4l3X^mbWjg~tm+>blUlmN zZ>3(i2_XaeXc16ZcpR2Y(YvCS6_Y5-=8FUY(MI2N?=xi!uus@%O*#C?@n((@<45&X z$mvvj2j9$L$2d73Y2d*5J{eCT-Wk4? zW^2^C2&?m!C?}+P7Te}X9b~IZh=vSv**Q;E!ZCONYP`6y&*+NBhcpYJ6Eo4FIr@im zp7lnI0i)dlZi*m*wy~P7k{`$YivC*`-~BQiP#v~BO(KEYnF|rfp!jRxERS)f=(}qK zkgc5YiPqPT@b_G0xB3X16^R>3GcB&#`wv40@j9!4O(x6V%0kWcmbBaWl=<=?U6ipE z!zxsJkf&tCybD3WzbwG*ELADg`7%UB-i4bBE9YAtku((#q^ygxWVGctG=nECOp96c zPEy1KbmyPgu~%?m_fHPbFu5|fLu*X8O&l(tjnqIzwznJk*JY2~AAgTBp5vf%4%-&( zU#H-ZdaGv{0&Bx`ZH;#06}fI4ix2cZ4=&L8L2R1{opqCJ^d+HBc}y`LXtCiRI#>2~ zY8^nm49W)wd1>YTuK5a*&w!MZxD^7A%NJ*Of307@3tX`((;qs9%c&@Vh^ll88q9$} zqW3}$%D$rR2=&pw@KSVoWs8!Z%&WY@)v?IxfWGmD1m6nWs26vfYYr&B48gtjj^}4y zF-7ypj?en^y6~NETqt&$Lar>Y);PR5o0af@65|zwc<%BuR}H2j>ZT{aYotF~^q^+%RWr53GGx##N0@4-$OEm7KSx)G1qiih5juKCiTBysqZI@ByZo za1}Qc8}|bk`UfQ#LRvB`xI{dYBlQkS9o-lIPJ9_Rb z>NOs#&l;h>u17!h%+u~~)I$65XG*0mvUSIY?JZF=>DcSW!8!&-SkE-d?B&2T(Okr> zlA1fygi>9k<8=OusXKOfEOjP!`7+kp0l2Qts~j&LO> zS^{jOJuCsMBsz&8)qcN;a5eu1Q#W}PDbsWoMF7@>)WVs=^AtpJ79-Z9I^xgT0O*fG z6!uEo6gcW9vel9dgBpp6UbLa1h%rzB?qA`vgi@HE!(d}-CYUf+PJUG?+4o>_+W|e< zw&&&QXMY*3A8B>n8m_b9HeKnw26#UbJmv=uDqs$Hl!}G-3Ho}jR4X1`0N3d zYrO3qZqB@MuXv<^62&>5A@tozz>CLSkDu4QJOK;tILk<6n#?V#%UI4jS4TGnwY3j) z+4(w5=V%P7U+fcYbRedtT#Lsb;!+)$LM0jx617Nn^TTEc(>9lHgZnVCS$UaL2`fl~ z`ACKOo~^|sHg2EXr54!Zxf#<7ot#{o$??)F@+>L^Sr#G4eWj1=LIAJbj?J6GR^o>K zI{V0!qtTw*jVAf04RO2KNmqjE^O-z+{q;I*aFKVc+z-#@&xi`TAYUH}#ZFiPXkI6# zMUL|R$C63zhnobSu&W!bbG!9#Z%~SU_k811+&5>6{MGQ-Q4NAuKkbV#l@KF;)3u$j zHQ=VLYHB$5&cT}fn}@afeKN)R8>9Z%CSc)`-7NJM!;B}$$%$@?{l?o2fFU2f#y@-` za31&@0#RtL!2RGxFT6OQ`cq@%CX(j!RYrh@)NRv^(LQTE>Nk>`%!r0fp*(Ln zl3OPuc1z+2i+wdu^@9S5+;SwtTXvDr0_dE!T6k=vM!{Lp#R>O%2T82C=qg`wvu=Ij zOF`#bbCL9w9IO+|if+1k;nBHHd!5Ps}6)A^<39AovVT_gQ zmA!(QM%k!r%UfdZ3=;&qXlF$t_5Tv`iJBIG=c(42S{NK;)u`wIW73XoR zwZ3bz7DqXdzLwn1Pt0)fpmro(7uU4+|6xQXGK$NXLU2E6cih|<^Zt$3Xn$|LdUDGf zUw1IGpF`w)z%S&z?5zNNl?>oY!P5%5m zPqA|r{lOjQ46W8Ta(@eOa+_XbnVaqa_=m3jimI5`@eh0nxv^_1#8y&AfKwjeapYXG zYw4#&=7nsI6eM=dJ?dOf8_|iwJpRe2COcoL#Nv-LQZM-92iQ7*Y{8Od8}kIRIDdu^ zF3WjL-#Az+6f1pTDDUB%A)<2Ynd&lXdj7I0ht=S)G{F8T@XD!@#Ph$aAQ{xK(96I` zm9(qv7~+($`U{&(@Q2HJ1M$W{rts(MQy)JMobn|}#JQqZUCAO91HitXIk&Ceg?RTZ zhZT5TJT$@jw0_eF6^9aIa#WD4AVZkAq(^y8<$G;y6Hup|IL=bd|4mLDO3gPR&Aw-Ws@M>|`4i2U?Ls{LE7XEMC# zc*mS)QLal9irCQVchaUU>CfNN7V#7>RF4WGP`*NBU`Kgo{+4=c+_kyiRdh7d@7d@3 zTF54}X6AuOC*OpUWS7~6`bkB~@_)(qIM!CuWO^ki$u5p~IdD@kv??X$H4=+`dbdj| zSCErd9nbU|m<2#WRNX16{qcnKK6h*7g}3@T%I>mv(}3f}JSFoOf(Csn`?WFDxyrep zN1AFf(N{AS5&f(?Wnp7MW_}JIGw;8wP&qd3-674Rf?>_Q#Sh|eN7UPH|3livf0_pO z>BAg;<7c+(D(A&#%Bir$OC{6hwf{Frx~rdsOKzq0aS10RdgUpri88o%3Vx01Ivu{A zgC!H z8B!q^IWCR#w0`8kpnZyZ;_UG41a;sOjkIhWsy3Ji!&626Is}-4L{kM(sFr_b-c>Ze z4gRFv8SBdy_||(=0jhD{vZtD*Y-*C+*OTmmWIohLvv{<9D>#B?>Mb@5CpE{5{0F{y zoomlU&o3fljLjhPvA7`)D}I|grOo@)e6BU9)ZwcxJW0b)GuJqMpWKXIOKOJg54+wK!3W)R>`gO2kGO~D$!_7 zE4z3QncGCKJ&1IaPD5pY?`qke)t$zLcIV@{5u5{2N}x8JZ|_^;^_Tez=E}SH!R63S zkf7AiD{t>qvXYJI*SykS0t^Ki&pI^~JyqV{ zXRrm2yt1;rFbu8QEKG;;S8%5SVEkV$MlaC0W*@Y}t5ihRShy!u{J7KDR59WZ-LmVrM-D!0C=jgHa0 z5JB$aP!ZwJQKM6e=i@gE%P6BTg!hMwOw90o$!% zVGfX0A8HdU+bh1ezJ2`4<^1D++!)mn0iSa%0Z+b%?|uz^K7uG-;_OV~lciBqLddnf zQEhEBQe5u*ul8*Zz(&CWG5XM zDe-*zSK65h^v2BtpWt-pdg*2Jentk=bD1QG?Xwm0$+-wGJ@jJGv0#C(7w|I{FXLsD z`yDcruW!tXAjccA#;5v-JIB?t+S8+=`uize=(yq?)sNi zmNMrj^nL`)6sbX*!Wz_s?AMo`~fDY@whfkqE#inD8`@PUD<@d zu(v)njKr|bdQV=PKqN!pf&(s8$@ozP?`e-{xX5bCLBz3J4LkX~|6#b8pE6SGhY^-$ zcGqozKatJq5K6f5)&i^XG?9+f)uG2NsE45PzX=R*TD&hEwn`vjbl}?3@3}ibvFx2V zhKva+){Bt1Y|L>nv2uo_B=Z>WN6e2oKZ3|haSbp=;UfxmsDUhX<2+`iI1xuZVwqGQ z#Vn<5Q(7jOJVo*67=)?)$t0&Z`Fm39n292xA>BHkK6Pvlry2v^i>29+7n7{!X6*g_ zPw!1lt6{CD9okM$SB}Ao974EXzb>rx#h|uwey!gtfORZ2R2uAW3-ie%1rD2+qA+~GQBWMg|8OFqb)Ve2}H#v#uw29ypceS#3Kz;5hbv z^;QpLZIpCMhN0Q5C@1-cG@dB>m0lOU@-s$+Qia;opU!Sz`N3c4u_hkh#d9CQX5090N&EZeewEoX*P_ zT~DkwamU03Cxh#xU506~+F>Qie-{{;Sw)G)-WY)ud9=oKS%cGa>MCkt^8w6wZ$CV{ zv60NxVHtx{;zjhZ3q7iC<`X$*FDS2H1f#8-g_k8FgPOPrPwa{Vi-#V(-y}t1&Dxyt zytO^Tu4^n%?wtnqz$ojwIU3e8TER>djSi!$LPKRWIx#Kj*f}&)`Yh*XJo`Gt*L+14 zmoE0DQ zuJ%O*r0*SjH#-SRork)=e|r~-jqfk_yRL03n%_7y0NYAkkr2j1fCWC=p4jT`g2npu z=iW|NSy>xPmG^OZ^@&~;B>Hrzc)H{J{NZ-yuLJsem$_t-Pmwm8YVpQ|QJ!}dL^iJM z@6tJQn$b~D|GLNNbOrRS)w{^Lo2H%Lr%xxoBo}a(Bu^*!l`EH2{N+yd zgAQ@GSSIZEq^jz7@hK~c&r0I%%yo|xpL;ZQSs{rjnRcERG4T0Y^$70JI16S(^m84( z!@M?P6=LxQ+JS_331JI%4oR;)jt;Bp?z^4YN6paIo{x7bP& zwQ;I{NFy%eMy4cXT!|FFT$#tww6-gU5wfXS6in)_J#I%eQit+3B=bNuu~a{N%OAvb z)(Aq+ft-`QAL^$8y_qM7#}pMnl3k|PfBv`iMA@HkQ2z`5Uk?3@qAxEi>}$5#KEyl$ zk+wcJwRt^t2;IS~T@mire9KXEkyTPaigP$W4Aa}>d|xw6{CXuLnCS`*IxA>~K}1b( zh%5qPpkr<x=$hGIU+p@hfKQ z^A#Kj?m`^GeFKFGPdQq>u^&4nys-hhxU_-v z)@A1U;FuD0s;ozW_^4!bUn zJ8>n@sqXr`(z!HSG6nI=zW$scW-r<5Ujpd{^#i#TQxdRn6oWI<>JX6A3 zu;43{&gL6k3gWJNbA?rrJ^ZFJ*zt*p*vZYgWkCP~JM0}0a% z{^N|crM$^(;$R?^Dc^0WW31k#~{ozAIroJb#Jp3W^XF}}OV!D+U zPMPx{z>##{6uyPb|JhJqNV*p)jD>I?o=twTYZbCwZ{j#rqz-oMcNP^$3uHXLCmCV& zAW$@kKyBUaQ}*zY$~)br2sBVh7)K^$3@Qx3b;6a3vzk+lvuJ+jAmZ_MH@6AHJ8R=| zPupodXs1o5<@_W=|HsS>KM;73XfM?%I?E1uCZ_a0RnOSG?~@hpgef&WU8AiXH~Jz0 znRnea{gZ#c7^il}!zG(5V0L9+TsXY%Ck;;*ckw-6?kisW;QXncIf z_fU(DLHobU*q5?o%3bB3A;O~1x4tes<=jM51_f+< zRNlMN_K#C<&H45ovYC*W)e1vUT35_fC-4F*a9-o+qS+2;$Gu5$W(A zF>Hn{PLYEmx}olh?g=1Z=C1RF=!ar`<`MUaUWpcn=5T|)tD>zjj6;mWyQ*%-&rrTL z?pOPeNTKG3ke+5d8KN3QLJiVe0v2m9jh|mR6ZuD$6kMvd{%ZE7fk1}QLmJDQ>)@vO z+*i+z4_2dgDHi3Yo94)!F_>5{*I`DL`~9gtt{|RvYM;8+3&c$N9+!dKf!-{&HCX$t z&)d`=p$oB4EBBZrF%dUOf|gXij`_O|ACCv57>O{ytO1vf41jaKYs z9*d106NkVO>vUm|v$K@5=~ZM1M4M29wwDHo7r?JnvTh zyu1}ykV8|J(T8+<8PAscELm_OSOtyZ`nr>;cs|hs;PLGqF{G~EvM)SY#d}tV>54GX zKT*Ibi-qSa*9D{Rxxnq~X0mnQ(D7=fym_oziVI}^fz8i3Z2bOBjRrGgz?)CWJ1LQx zwhTfJzrUTWac>2^dl+$Rc?}ai=gIKSmp5#nS8f}CvM@pvPhRD@o%`%c3A6(@4kXRU zA>{7DQdSzR)&UOPjA4ZQd8k4*^oNHEGplUe0Qt_Y{&s0^azo#zUZcqZd#9sXN4aRK zxq>_h=riuUqjFp;snUxWvo#Z!nkZJ%#W(-fZH=C9A92$1Yyu`o<6Pd%+Zbz8SHbO94<$J$>(*qQIC7Rhd#*r>`UBYFE)n`aLO+Er~kG+SH7q6^8 zA_2x^xBkz>=#S1r7;=A%Vrp4#6IxN}BS+-)m*kC!dx~pbiD)gMKnG6)KC#J*l|LpR z0;wHh+b`!EKR*=2q#Dwct*fvQ5mOklMe-^NF`8f&9iBv{#29yt|>&fUc_W4 zM3+8{2AL+Y*A|3WY`+ByhK*L6Yj&1<$ADT#P1JuD8xujqK2YrwgNhl+upYwvi-GHC zLIo9pcc+E-+L$%(nFEVM@12~L*r&{c=O5E3H%pmD03T;SNd&z zox*AY5NA$XgxZdbyy^9-rXYP{)%E4h_ zo0;0*CNn;v{#UWtnc$ciR6Qb$#L-|@ON4vWeEL}D9uX`+1rEei&zKA%-Qqy6Xs7EZ z`npKma>{-S9Fv8&ceQT27{v))IGG*U5jpH?M8ubG?6~*v z%Zmv`esCHO^~JlLfsp!+H*WK|mEj^Dl&&_!9jH{zJu$O#D(peieq7SIOvq>`(?M%0 zE8cyVB9`^1v8)}6kK1AWev`SwXPbuZ9je18@G+v2Xlx=rOS#Z-GeE>}&UwX}5~E@4 zKSvk&!8R|Cme*kL|*ChN=4|ScGg~0H0M5>6V$c+u2P0y$8xl&{QcV6v4rj{z6HQ9l*s`b5gN2|+ z4N1W#?e=)<$tJR)pR&4kQR1S$htUkml3n1}b?2h|pU<{_ixcj1GDQCsH&yKVMA+G4 z5fRfus%s2AYr zF{4qP5arzabS)Y~2&erPDlHtpt}ky?^@p|Kx7Q20x{wV!lp(!Jkb1+iRzts^ZewRCiWP#1Qc@40+E&$}O(uQdNiXv{;`4^0I+g?=hRf z*4uF3HraS_m#jYzW93o=)DT!EClAwnH4B1U zHoQoEwb$+p+kTJ@P!~z?${G;+P{I_P4si`MhAMYf;Hs#rp+rlHuj;=ONH3u4=?-7h zAxvj^YP50)bPHi7GIDy*l45OeX<+5zfaaHB(4vr=Yrn#o_p|!dRDW0u<}j9R3^oke zZR52?RWTu#H7gR*lE(^g1TkJCM{*4H=PEln^;#6Qk>zQY0*nW%kqITQx+p4F$72pf zC8uh!z;=Z!SrbunN^EgdB3+N`1Qv`4PRA;A&m0gpVQm6NCp7Cv7xMWoqjn#(2Sidm zCbh4&YM}Ss)oE3{C_@ZJH81EqWp&u^dhuF;CIi-w1=}P1RK?m}YhAtF*6rvcpqiqb zDuf11nBfE#6>Y~yBGF_iHPNO&h2QkHwL4m+k%OEEFTx#hG?AGSZDTytDE+m!%6#(9_{&WwcbvcO5P1RJ+7V5SPWx@Y$g7* z#Nt~U_9<~9>!*8AH*kOs%#m%oIuFnMwVUrh5%F9;;P}C;IYie6_=VMy(?qFrAxIB5 zR2#CQK#eQ{nPDx4&i(u*-tkx$Nwa3?ic6i%G{&*e!=bt8-RTey=lVlJ20TH8cV3!+ z;_6CSkcKN6(z9A`UkY8U)33B&bbwCL)~36RI19QSB7fBB`{F$z-o6D=GT}``=RyG< zh}>(W0YFt1DNs0w`%w3(LOgu6dq=>iof7Gf@~^$|{BYt~=eRV{9QhR(^wQ@ssxsB# z{@u>~K!T;*cv_Da1RgrQH6F?Cw+TTcQ+`wu`23{ z5ubRKEmY2z^xpLBmjVENG1b}N@H)O{70PMFK$Xn!mD=fu79<;2o%+~({+HFfAo@)I zwQ;5PjE@>6Mt|$UgFRDBh+U0Bx!#g|Ge^W)T$uIKAOYvZG&F&p6Gz(GlujrpLyg16 z9TMr+scKo>^GmZnlY+(IqejD!{Lk=2JXE57&sc-R3_3fmzxkkmF=b7%+;@h%GVVEL z(=oHn+dq|H=nty>ZxZE$gerY7*@SN16{Q#ioCquouu>%@a>t(w)-cb6?9co21w0Ia z1wGz#-}bWHBIy_KuYM8-3yy$rHEHdQ1FkxI$h+~V!_d9?S_(Tqn%33jWiSNOdZhXi9S2%}f zhd|MQYRaoyXu;o(p=7?(Tlnbb@utJ4_5SedSPg8Xa<2N9XW4aADle**)q_uh9)E(U zr0*{>S1nswyNg%pRqLprw>OXV9Y7l2bFLo3+A>%csh@N6N+aWC^u;?|M=nEn8UrSF zUDLDNWP05CVqAaLa|16K*1Z$6J369pFB8M7RwNjpx^4R|I{vs{ntHYz&Ihha#Qy0Jws%t zLbII?ZKG_l83vS#GbB)hC0Dj!>Cd(t{LsOfa(z~gYHS2u+1Wx16T!48O`hmER_HO~ zwF_-JKC_~RJt>qgNsB+MO0`=*>XuywdcRlA;X5vua(Q*)b2XVs!vtkX?r>8j9_hF;z>{`or^5P_gvnpOkj2R`ty}X)he3nXxjL& zS9|(VrxfZ(b)zP9?e$VI#;Zi)NXq`@w1uyqp(8?L-nXwrufsD>DXk+NXJ*}1 z$AD77T?F>XOkR?ardwwNeH{aJgb-ZvHT3F&d(;abYVVU1kQ`M0H-kW2RDj*3m0f<1 zpfdrI`~hxo3c8zRrmy%=Qshoh$Z2A)Q zK|F&5H5dOU0}^z?rFn!&{R|@@}DiO<=Ww)kEuPr`hFYQf}}?>aF-epUkY_ zIC??GHl^ULYKZq{iMGAF{v`IzGI3My^aLu z74Tid2-F^U%4UBzh8`kIuT#taF~@1xvtY5vwKywJGSS0<=HRQ$m%8I_r$#{~0RW|F14As?3laMJxR|E6w; z`MZ2z_=hMNwn;^NatIZI)Cm04bbIl}?ZKrWx&qmO@lW;HrId6B1B)VSq1ita(;6r zv9Yq|PFpVR9u@ifdaseZFsmLi3|-p z(KQ#0tqaPWvLyQM=GJ+<{BS#3*Z;KAEVvip>s(ra%W#+jl_O73jI&UeaW*6_-q9*= z7YuTl`fzfuP@6xPAIGQ*>0Y4xgx@`3iiP<-w>QV8Zq|T@z_f;2*@3QNnr4feU3OF= zd4O>pljbD$k(9-r9vTocB>RlI5aP=0a(pVxWL!Nf_(#zIssB1#W5%hl9g9d@0YXTO z1gxhfZZxiiqHT|3N2lf=64~Sp3K!{m621c~rGI>At+fv!5XGHlSpvjWqf=4HdCt0y z44gCoPv+DA4u}X=pBfnDzn{J1B5l?8xtpY-d3YO{ZH0H27QUOFmGhD1ta=8 zg*1H8hidc&Y2D&|`6{>Fc^5+)t3<1AYANWl%VY0o4<$wPz{+t)mVZRdzL?m%ME@T7H5Jd0mYy+ikPS60 zrf;4HSscfjJGE=ip5@I~6)?;-L6HvUno#~ZO|Y%$ocp`>C0MmkCy908Ho{C1%~$0Zbh~ng1NWft3G8*H6hk|j(8WPh|Rh%O>=}J%c&)P zcldfP$Ef`4jFJ&W>S(BbkM>U!KppbfY*004mGXMnK|dQQnerA>XvqG`aTYz_x9})W zPtQdU)#Ty>`}|MXNuuCrvZ^05;@;B9tq$zxM3SQI9Ui!UrbSIMa-+ud};b5J_jf?m$J!1wCEo;7>qpJNUTCP-5%hF5J z^qR|--(r(6wS@(XL@sK;!bOUEgYZqM!!)?{KGDm4HhXUyOB`ZM;?HAY86sJXw6V(U zdPOYN=x^w8C?Yih5NhR+oQ=%AS_etHg*pOFaJ2oIB!{yVe&FXfr}DR5CuWAA6EJoh zdRz!%f5DJA6i*b`?5`199#giq?L40U)nycLbTDd$x*QGLM}Gtd=5->U|LhIBlHCtA zxgXSruXj2DBLRrVRa7M-9e0apo_$jQpTP%5#UUf=WTx?S|G;?LU)l*-N5KATE9E}K z(VapNdgR`H&H-y6sZNMaRaX)=a5ocTbm`RREVr|EJvf-#Xtum>z{o=}o1 z$5)}z%_u3l3y;*8z(U}m++URyCwPyG6rUCCjs=<@i|yt{p3`CxWX0LJ&sH#QpaG~?@Ljfh+;G4kY+D&QYT3p5$#d_?vR>MeI$7A-SUIA9OLi?pw-goriz9=Q zhq4>)*gyFO>B;#0fB)~~doYkfNP4(d{qwo=pGcPH@ReS-!8f)zkJBq4 zhNAhYWo6E5??a6nO6Fv$!7bnYx8G-b)|V%ea6_bf{i8d5*x8i(8L#+vMkSFKcJB;F z&uek2$;xAnqLy8IcbSub9?Qz*$;rzlB=GlXGBsZk-quGvCA}t$R~7my$DVH)I6ikm zGM27IBhvjKDkZ_1jRrw637W>=rpXByow;4#_RLojn+hWk*d$8rRC(^Ud2VgED5o`Y zjhNeJRWuT$82W$;%Ie9FuG*^-se+1k^t%leB6mw8tJj&&uZ|cjqISMsH|`~S1wg#c z6V+VKL_~-5)wbXP&PY*~wE`K#qY_qj* zfeWmtYV#Y*k9CLOTQz{d~{kNzp*}MJ( z+UXt(hfwOih$MMlC-k)LfD=EZ>e+Z-8w{~Vps7A8tF9hB=)cfKt#>mpK2=F8A@w-A zGY80!zu4ePnUA1!@rt`qDHS|+A??f+Fd8k)>r^l2a!PbO$HT}YJsNR(;BygeNh%Ir zesEHu22>X(+ISdgBwUDi0e1Ml0UzuzVm&rqPxViQzcUcU(mBmO#I>V~zBIe=h%jyL z8ByuOvu9&tbgQiK#DwDfwL1BzHNVOMm5rS@Y44^aPe!(>YD9Kqvb%NHS*GW4>SxQz z@YWtZJ^*UHQ!^dE=ri`%QIUn-JJm3rkExF&Eif+Q*`ZrQc}%hUb*PyaXA|C(+_M?I z_kS;S5=jNW%}9h{2v9qZ7S1K`oxpMJ7 z0pWo>tyGKvjEN$7^LML0q)>WXLWP`&pW~r1?M3yP5q?u&er|me`Y2usekVxemZ#H4 zM`TSsX&k$WQOvG+%-e#i4$X}-TmJ_yBDz~ovm!{d0ed6jdj`4t5fY3#9WJ)~u4u25 z5Jem0{5n`VLV9p;hR02y8PESs^v(+_{!2G5aqz2RaQwX>1x+Sv(wR55p!ocP(Dr>I!=9; z%6j5|5pmJPd}ZaV8F@xHiT(<$E%SDR08x0vYg7W)bm1{e62%Lt7}4=MSirQm1pCI^ zaB?>ebU%BtLT-31qZs>SlEsVql*9S^)M;IZa+X7b7nE35+H5kh;fRk#VtDKNcc8~ayxaGVGilg*;G6f0F)F*oPuTG=&VcLOgYvGE^&mex$*&;0nOosOLllUv=>wN3d?L#?1-KAo&zC(>$Fb zH9%0L&W-l@rf24vgGu*V1pXlJeY20qrpgpB5(nB5C9t&A6^K{m2*9sq&8q$zlKFPY zKnFpe_Fpz`t4t%)2xx+t83<8Bf-GF()?{0WTSP< zY6k*tsk6sBv&%_>Ea6RtLMVTG`8_cVjSB}j`bL63%P93)u%w>ZEx(%(H2^X~q^`rzxZYA?bb4fL_*JVeiw zdnZw^wau_zNW?=H((2Q^uA9W=_p1*NehxKHKi7%u7xipRkB8msTtr9DC5-l##)3d` zarOs`Rpb$iRo#R<&VS{N1Ra&_D0CawHn}&-i5ITp^m#IVdx}L3K#>3rR z$xni>=eNK)s4le>y)Gs~HJWL(URaK`pq(UxUF#l5-kDuTRabBE&D3(JX+#ypLC?}H zU#m&&(W~=+mu?IrVw;(6Lr!)*t^C*1gJLnI6ed`U4Ts$krtT)i%zqtkdI;ES-nngk zKZsx#<(u7s&4>di{f=t(krDg2Aw{5M3vr>N?z`;=fJ^axCIw zv!VR+HE^`GgH6+r+w-sA`i=aq_w&O44B)94QiVN92nlA$9~JyB?DBX5Y|1aqjJPY* zfTuw$VX6%lZ<7_6`H`uHgMxGKZi`IBy5~L710Gz!t%<4Uz0@flTnEqvu`;vJlM3y> z9&lS77x%|q+fB11jc#uhbWAupOg;EH_D>1lihU@ zI;?oij{d@}V$3YuVCkJsd>t{?@c**_^blpQ4+Fh?PrnPLeTiqEEdDrY`Up|T54MQg zjq)<&q}*_KdHs?*=3d>JS2^n7Qy1ZbDdTW%#1#7dK2^kx17Pv!gY8Mh{!BzqO-*6x z=$%o{)mS%bYc3>$N|X`!8RTLTOvEYpP3N{@F$6{h@&Z3; zUW#!?dK9sIM1U0+DhBV$EadaA4xFEz0UdU4n=S`G6!&(g^R9IOT`KAd!GkE`sH8V^ zJtWoDv`Qg{aSBg8avvfPmI>LLl<`0I9jVd3{@<;(#{3bu?zv8hWeuEUF9OHIq^pQ=29y)3NCXVA|n^PZw zc#OnwdZC@?pQ9kl+^o`oE!qd+To`<@8T7i4t|FswUBoNoYRugLT>) zK2c$wt-oFR#~1G=x%!&Xf{MAQn&Qv@f_sJcwIQ&$2Fi)eiY_dhp^2DXBdpx}tf&tN z7kV4?)$QZtD*qL-@IdK>JvN5Y0_Yvu23RIj@O6woe&){o$n)~+?|0&!>q!HmAB0S8 z&cRC_e|b0je&VP{!0p0=f$-WsSzz-(GuGXeBY%EaVSFlrh`*uEN>ERKcRHb~F=8o- z?_r3^FR0~LK-V$r2Gu*}{R_mb((laZqKhNken&!^3sZ3)gOkDzmr?k5EYE4ln!Sd- zrREEmj=u0f=X?r)aV;cGxh7j`2KKCEf#;?!R%}vNr(x_ofGOc0X8g$epzG=-oBh-ey z;pNAE(GW&X=ep}-S$`g(lc*kY=OOu>xd+ZdrnaDxhB6LL^~S+mP{{W)qvrk?TELg| zvHhKG&5r*&mqzL(c8CsMXLJm~|J_r4R(}49cezMSgtXM^ zz?MXE>pd}FXXaVe$%b_7euo?)?}#;6!?Hb*UY^5}D9L|E8V*dY?j5;UDwOscZt3_g zJWkW|_2>k6S|FY9w!dl@MI$2^oIzmyoH+|()*5J`r zPy1<8(3n2FDSXG>)zeIcMB+2<-R@3Nm*6>Zkbjz!k(x0f!QA@*GoBByu4qx?g(q#x z${T;q-;EwlF#AU6}+f-6#45N6@Z);p)lmM-rX(Tvd9Ot7u{XE zP+txl zrD5=3=aPRKuLG=t-HN;gdH;qQ^Po0yOAYS$AoXw7d5zjA&DKkkMv}d?tS0hF;fBn> zVx+0G45N*HY1CDFMc#z`ny#xm9F=yu@ltN+RbppiZ;D?WNdAYDD6j*2t)_i4e?VIRLN;Qxav%}Lh1>UqS=c>C_bIp`q^{g=EG_&7aksvg>HE1#&l`Eo?L9=g# z@Ss?|NofAFN_J+#sO68tz>BZLV&KGSy&&3y1VgBNT_=Eq<4({D5@zO7PAwJD%!cte zr5A{@>(7Mk+<{(_{_Q_c2IAh>SQ(H+7ev{S5w9o1@X&EWq9@u*w2<&{PHb#H)X0?gm;@TS_W z_=a^Qj`^xKu|ll6s=^p?k%GEW6|kHKpUj-xMBEGv+0Z4Q@vW-=?=rAlZFu8IlnNkR zVoz6ZOHO7#IW<+S9dk?Q(HPm(|75UunF380ak{${Nhi7X~M2kbp7w4 z8)L}2MQ&jwCpOeOxq(rLpqBsJ=Z^Y~(u%9my@i>8AwAr-SI8N7 zP|=D3Eb>2CS`zaLP+h>kG`S-HRCq@}Kn8!c)fr0Q?xRLWMzziCt^X%*1IojuCrBlH zDx%nvE@}7qTRz<3bF>=9A1e}&!`rz-211j9qb+Ber>J1zXv#Ep zLP9ejPwmpVf2fP>XgA<<;1yk-P>+6=PA7F}Ac<_n+t25cqYQe(+26ET!Z+Y}Ph{Ef z=WvYR`R?G=U26%&(-a$54Apd~28&XTSv&83eO#BI9?U}ejZ%p^r0|@hUt_(d*gXdL zBQc)(w;xqsx+`>>K6`4B@_P3!E#fR*nv2QIehxkO{YrR00eu#xlxehr>X@as@&rM*ljt1NQ$MNH z>^{|$>$6jU=e5y_>HK3>}z8gAWRD<`+^9)9I zhQt*ZzM_S}FcCpl%)KAs>b#MD(u4|7ty7(HjKx(MytjFLasCUJ6thCeB%o~NZAvZ0 zJf<>42QUl+ucHK~LH104z`nm0sL#{1j-A+%*!q~v#P%sOD(;X!cyF>)X%2siQR2?{ z7WQ(>^0?sc5(bTKS|c=h{hEn>^_m2aSQxJ^R^NPM^cyFHJERwn?LXO8$C z0)HORVLF!PxUIAW^yWIVzNW!XvhpLt??YFAq@=7S4W-|>VKNA-R2We z_b|A!B>tmW5}&GKgIY#A$;DLgxQ`o}e4bOqr&mAeguf-w7+M{nx=%Xm{Bt~_zD=;z z`C|yvKZ@zoHxvke>pG6`mxR)%jPfdjiHTY@tk)CxX!=UgEmwp@$hmL{p!9Ay3{9z! zf?4_8T|DW+fv!d?^%|SgTuCGyorXf8a(dK@C`YwI3@LNL1b^=vYjQ0k$xy-)WQ6}r zpReEv{GwMN^0_*a63d|<9^b>Wn$mzX)!*d1fc(7xz0PJaluaC3Mw$rhlc>Ly`E6Oz zSJNsMU6*u5W}+WMEjj`K4M$$=LuP32Jur;4v@DU#9%GEZc|vb#Izb@=LFL z;U53@qEcO~T}j3`Txai%{qNsD=MD{?!|bsPK!41_SrQ%BGhy1Usz6Tm` z&dK*pFV5K&uCP zh#16#UMWow;ZvDlIwNVz-7rGgiv+v}aO%gB8bk=u>e{t4rs(;I%n!%Kc z+N{LN&Rj?Ja=Y{YG4+;FQN927x6%y~GPE=T(%m85jnWJ$-Q5yHN_Qg&C@tMFba!`m zH{8e1_jj-Le>zWQ);iZ*=Njuff} zW2<-%E$deNptjTte%%Y(3aBCgc}_CF_P7MM)FwXU&5FFhSHNxOWLVmonXr`)uwN9w zk>;V9q#6G!`w38-&44;^C%1DsETIG2NhVfO>7XjB0BbtMpj#$0XjSs$=OPD)fKnxn zj`H65oFQ}EkZMJP>5Nr+sM>;&ZB(~eT3%hK_+%pfyTWu5tuKxfT_RbTP^z0^W^itKR^n+N)5%VBs)F80`$q=u%J@6C!RrYg4^Xw zyhbr=FJW~1gG-Fq_LODw!SDP(=&shw#wVPVQ3*mjA=UHahkkoA&SYhG6+T=&@?-;B zSm2mv_1X~h7E zxaz8Iha<$x3gt3CC{~kPxkGJrEqCTojFZ8J7t|pgA=c0j6#*D=Fi#N&u_+cz78l$* z3{d=O8~~9b@d%AJEu^hmlJKF~aQ{m%v8QVzx%EKAemon8GQ>&pTukc1IU(~hkl-V??wP%S6cx8=@Z`V^F{J% z=%~+$PKE9AW%EEyqbGeNF)y|vphzcsIWu>6$x^3?v6^QZ1T^x=7g|*+^yY&ig&xU& zGOf2l#GSo>S#`A=8jTRrPmbn^IapwC7XFX6pmmsvSXoiyY$f`RV=xu4=WAbGaAdFKP zg0F8;1TEb~|AhVU99Zki4H}!CM@CJ`M(1?0LN-21SFPEoOUr34*#(agFrRBf)1Tiz zDpo@#?SIbS99NLg4(|zCLzaxdKXBMc)sw|fjKNsz(bn+3Dav_IG)BLomN>lBVm$+e z-eGd>kj8&>gU*7O_q6jy_k>y&Be}jhB>Bcex(UG)9Sv!XajfLz#cWgL4DSS~#1)=M z`rv7@ol+k6%ptQQ)OHhSgHss~h41>|(@E66ZcCh^<-3KAOP>1Y;c;^0O2+tA6SWW> z4KS>tHn|>Orpf!)bnb=0myX2o=k`kL7;Nj;|sdhu~^k^}=6zK% zdk-3z{ag(T?j?IlKvf@9;d&e_H1lu(C`4USKP)buk;%_N;@C%Z!}*xoA=UT=Y2+%3 z8%1paGNg~CRxDd>kIT#(1#_eB7uOw#WMF)2Cgp9Qa6#~8+=oV;-(K}UB?>fel4zat z-wR#krn9WRVv}htL^H6PV@kR!rgN~GZRq3c1jvY)Q7jNQX(IPX$CT+dI=@rYf2D4v zJqDjGSS|XKmh)lh6y7uRc5i1RY{rqC98;e-X1`6{aX%3REf8)CSA2YUBI$mEFz&2E z^9z^+0171u0`FM9W5OZ|^xpm2A%0qE=dHlxDID`o?U8W8@*X<_6||-ge4kk(WB;CU z)*O8ds{%MFNvCqk?||GNMGcFCFB3@9=%b2lQ>-~s25RRK0v%CjB>jw+Un~JN1*{fP z2^>>^5%}L=O^x83f7NqCu_47Dr-@%;*_bk=px9Jn;#Qy-!CNKrSdr&e=@28Fg*pC` z%q93p_1o`41r&73m!_qK7+)yAo<2wn?>mRgCYMO!+USskPV;16;CQ28=nQi3N~0>1oA|*&fT-)wk@}WO&5ddYS)yAz9qF&U|1R zUg?(RvR?4T_l~nms&QWJ;f$C4B&4CMwg#m1MOF|4jga;l2uwzXj@^MDmQqCYWBQr= zewITu`2??iNp|vRWq6Q7-PleyS_&lsj2wS^|1u_WV7^k0HFU+Qh;h;izrpT{&($!? zRe%YKUJHq<2wuL4%ZI)6nJ8FOalYDX1cG3y&+^HhBVIxL6X#cx%=fZU)&ye*34_dS zNWQmC=Jltk=K97h0Sc62T!o66N5TW+T3dLUf4+{y1OVmCYIw}-BcrhX`GlO-BgkQ4mKq z0vHxCd1H``9PQBFV7G;6HQpfYmh;B!hF%L;q9gvGrR@K9Y2;bIRR~OFX*^71|1|tt z6ZXsR1SSV${~x>xNde&1-PzD;$}i?yb;Ym+7D*!?*I+TmGmhb*|JA{6JZVRt>`&BB zkWVs9q$9)egH7S7%z01He*2N6VKuKl7o!(rtNv1s3IJ%nk~g}YuwzV@Bc_V>wBbfI zKpjmMKegkA;V#Nfx6ir`L6O4BZ5K~83Ai%Lzm@k9B+Bw6b}jQm2EdbbFcE&|FV_5L zGR+YPigSOVXB*3&L=`EAh>@4WJ;>UStA5e&NoX*@(#(VZoR&2};6UrZNEi#4{J4S$ zV$K0t3BvyMopk9)p<;IMn_06Uw`(;ovy?9`MI8fx+yfHpmPRn5oEgNA-Zl?py%M8` z-~cs5!Okq;On@;^G(cvjPCPdO_V$SJ4s z-g+`X@QlXAE)6z(MGpL;0gYGLCT_qFzr_h|E0q>@WNxk7YsOnCupV>Tk`^3OxN#a4 zj3)xZa$mPJ3=U_;Dbb_QvSEYkH3U7cEcW*IugUhMQLM=rE`=~iN0r2Yj~?mPo=6tf_P>(smNl;k$*xvloEzrReb156couGR+s z>9K8cxd<*tu(qYw-c@2@d+1}mNlZ$dd;qtKn;Rv zf_&b*k6b=G7w5D5yKV5)BYZ|FtHl2YgY4}+Zx&WkRgi|zW@OJ6@7RE{XYvQZxGR7a zCvxh|z#n1_Ece|WCItiU|KYo`_UtvvkG-A$W+p(y-bRXdvFNBjjUOkdrKeM3ftW!T zGh(sYsKf3qA%n;8{E#$QIj``A^BeHeFZ9#L4Y{i58}7_$+>&_9lJifZ4}(Mv#z*l5 zgkxcjH`nBT$=^o8nB=8nDAF?Eb1D+yKW}CsY(9TuCk2E87B2h!9E!ok@){-QY3xxb zl#Gq;{XE==@t}7~tq~q;TB^s+ZSDKh^|Y*9J5%xU@3&2Q+TLct>T2xGS#Q@*5ws&^)UF9T{X?U`SILHJYWeVC*4|DDr>4%wHJe0I zkp)EbJ5=7&`E2;x?|9KeE3_c=8O#XeEtwRtFmRq{Bsv_bj*8$upboSZRFQwq?YirO ziVJvXG(9mox{1{GbFv%u^puB|0Q<`Jm6i&t!I`y8v%LT^FBmu9Y?2~k!@OpyC{x@n za9Gqt_7x}<6-0+T$MfV9&4S$AZEXsPWp(N_Bo;j?WJ9ofnQ*LD|K*ANHB+V{v)pXpU+< zE)~63$II`>!)oXwYgzANP>0_4xuba<*Boy4ewd&y1G1-JZ0q9fRE1pteqa1PXSgN^C9QDOY zdizcKHNYXXEJKT2s0PY4%jWD;FT~E5?YpMWX8oRve1DZ{Wy9YtUFwugZi-lL9070p zZ9EMjI@P&G7ktLA>VtnAFT!X%fd20GoWFB#*(@RE3gfTXTv^)-y?5wZsE^j3cJppl z=u_jTF|WnF@#30HpBt2y2AO+jARDn=_+^v!Y&_|3?K1n7=4h@GQOh^Ws7LmZ5j3_{ zju0QbA14h7$TMxff2JwZd5VD1Na)}UK*@sr@z3W%c_>#FBjaPSGOKc)o`l*=&j0oS zCYCHr^J2DS>yFVQ%a%%A-Lj307srolLT}dVWe7qh#POpGoWMVq*urK6sxp`2ukb zb`1e!^K%OmFhCkLS0uTxGi6ITnyG-VHQ|i|85b(rb*v$_ru4sT6C&1Wv@4 zE;*#lzSZv;;q#p##gm2S;4eCg#7f@k-~+#kHEJvpINx{AM&h+Sr$~g&mttc-lw~26 zuwpTWRGU16-XAaL7`?Dy6%BS>&QIu+)$>o0TRzE5(WCBg}?Y|=`lT5@o@lIBJ__e zdHes6B?5OqMph7zgHRo1@cQ5Yq)4~^!#r@y{L?!@Ct*IHGcd11AAw23H4sJB8s+mZ zsP3KR#y>v`MEC7P1@eC5lFz-&nWx?vp~Vo01q*8~jCGDi1V_X5T2NhQfBdJh@$n81 z$+C$7anI!0FXo>@+nyKO+LPGkDvVH<+&5Q4D01CSm%T5e&N?vlW1a!)>c3Gjv}sg@ zQXDV;4|*c}63H7=xXx|z0W%TE@`2lQZ^OU+7}>;dURl7QqR`8yK%sgR6=f!I@_Z|d z_76K*14e^FZ81M|pZb+f`htq66Jh)RYtIlSc8#kvHkcmA9UY1ud?}6W@~uc3C3A;Q zTA03_zXT?UF%}y$eeMnYp_CdOz~C2(Ma_%;v)fK_pBT#&sG8>&{#t>PI|2LzGprgS z*_Xc7MDeb(O}htQmd)bsFSbo(N905fV8}KRC8~aE|7((fRd1!3r7Olj&vqwlb^S-g zILIl{E$vc#$~DbXZAig)cqjorby)Pi> z<$g(WARh6`#%Qz3%ekZt)QTjNPy5ec*8Vi!>Y3N$C$I)BhX|!o zM@})wmlVB%72EBG_Rqr#nm;6!)_O%Q;u`++$R&4DJS{#w@!dV^30I3}=eL;hB{p8A zXum9+er)Q6+sl_>q00QL($r=&Uz*;}F{#Dv$iBK(7jMP^;c`3C)g^brFI!6+@Notg z7Z(!%5j&)Q6X8?QAe8_H6|+tNC%KDtM#LmN|D%wtKOECqjSdhfMlIu-9&O(D*g1)O z@w7_ac;Iy*RAOF7xPxruf*8%*$Hmb>rO`Ul+@dwo}z3lU`fu%-do~{fsakoQ|i=D@~kl~ zHJ~OkVE#OmqSAFS-kdLEz*p;fim_XsINT$&*qqK=jX?I72f_7Z>Cic7mQR*j$WI?xvIOj5+ z!Nh>b>o79ECviTRx2B3T>93T6!C220@Hk&P-St_I4)=nfs#-uZ_Z5ZIU16Ja-egg7MNiDSj7pQYD_lNV5B z<0hfSl{eQZ1su4n# zc0AcFp%ZtkRQJQ+7uA!W8%$}aGEZhfGKp=#j4JS8|BjALKKFU?qOyd}$ChR%FFUjl zYtVoqj$29iWT-9chDL61Z~uI5PY^l|>xIZYtxQRF<%@}LLga9~(AebVPQk#JD&g*F zkg&8B<+`X?s%7D%kfvgwrNyl@Fy53G$K@GG{M@gw5dJ{!pq`{%;^yX7bQQ|tx+x$J z`YKb53U*1jxi=T#N4P30-%FzB&Yw$4;_{pLl;&1U^E1!0>d#>FUjFhsOC>}^GV+^w9I7JGkEdO!EZ`= zQOUa_#H`BhG*Spf_%;hauk`RMM9{+()0!_8Gd3+@EI1X=D5r?ZTx?*g8GX0UJ!jBm z=*tT+*sli=Pw3^E4GJP&@?#|t6#1=8B$F8l^Riy%*#sr#hHOGnj^l+%mOwhISCUbp zx^h^3U9qBYy*8kDX+dXg1A$p8jHD^_f0GTNYBU>FYQubHt&O<>)&WdP|zb z;0;UbU!jWL1v42vaz+b7yfkx>LX*2Yor$Gu^17Ci@$Z`I>_UScZy^p`P{$5ttAQ?1 zcf;f*gA+v>a|y9j?gzW(H42a9?#!W&8`N4L0woT=qV<6u8MUI$bwPf^S54q>`FN(l zfohbT$KoVbiMGn?F7+;Ghr;}xU!C>eC7S5p z1d#3Jh4af~b%`Q7I23hAUk8t5UQKIgo)aO-g$HUfA`2=;;@UgV2J8Lb*s!RS%?w}q zz+t;Q0We-}4IA*DoPA)ZNBz6#yEGYP?uR4M_UY@GVICXoSEW-!I)tC=#Z&w{R zK#EzmzeO}2Mj)Y23O;!C;AhML<^aH(uHAQ zZo!5sr1YI~*j?@EsSBU?~f|x%!^Xgm(%|gFPwCf3iu={i-t=G zo4QlJGdE_45*2Fw)Su8~ZJl5Oe2xOU9p21HvOyySzLFKTee5a~2XSf?mDNLwaZ zh8``gf6Db6U@w-=Bw1D131_QP4>1UiLxkz`{6Lz(@r1C~$yi)3Cj}Qm^FdvHON%XM zgZsBuIKCLKP2^qy0%d~}l=^O)2)qxqK{`9!5_3f&&F}z@NG5Q~y2__`+fAoUVuwB| zc7C^>HZ-w@ABk|D)>B*~hq2{#z}4?gG{1ti-oMA+eEeZwh0ws~z2@Iwr_j7kcDzMN z^zrYn@smj-I+yMI_xIl^wromn$i%s4Cg)WR$3)d}!g+U`V4xT4r+6uJZa^|Ki`9xi zO7)(z`!ytVJmO3;9;sxLf)PQjaP)g(vTgvwyjjXv=Jg0xPXCllhVGR%987>W#w@*PV*UhB@*(bpzm#dw- z4HQs$xsZYlS&{>HYE zJw!(b%n!D8r|j&K`WKg$b8RR4qQ;NvqHa@4I%XuIj)sI+CfYk5Ub2`yz(k);m1!Au z1L2H?o=i0-y*vy9Mn^*uV*w7Xbs7HWe+P3fwFPTtPlF*vnTI_MZ)q|s5gu4Zz=zrX z{UBN&CCe~*EaGW~e*M^j!t`4L;(4MxtH&xHN+Ts1K67zAGz0t)TZB z==6fwjhCo+8jdAEdYp)o3aJ=HEFO8CS++pH;`BSgjy3t$M}!T2d5GbT}muFW7%?exmrK(mc@ zs7EVw%cE;jyLBw#=Ln5}?L8tw7s-mS_hX0QMs$C7BbtV2M%YX_dLXM>)T{|4RkorVkCb;`todqq z;%vE3;Snzz%~l&M&V^b4q?;JK4iBguooeg^J(lFN)?=NZ_sM5l1j{Bu^_Z(|oA=^f zieTBz?$`}Pr8O#r3@Sr!4Rd4nts$3U#`tQ$ak@AqiICrY= z;t4l3rdfLEa@GzGQ0CFZt#Jm%D#Z0d=>g6dO0 z*YIqQzi@~C2IKP~SM$j)ug<$lcptqx^)-V}51}b5=p-yBzsHwWs@xbJz8N3t#;{Jc z`h)yuu8)1K^~zm3@8qNio`P(IT3xIV7aj!b>W)Rp-V30aQnD&u6`8+0D+}ckFT}Wt z_BOv$W(DHn7Cm#k*=|OeLd#Z2_r&>+UGT;@u?Kl#W+B^IP@z4h!+@;D|M4$8)95WO zx1t8-WHn?*2-+4em1_LZdG$wrG(_;q)LQ`Nn2W)$|09445WMk@FR|@xT{BP$8u>Wm3?^ zEsZC(sFg3HrZd-iQOZ|fz@gTNX`W|MA|rDHWVPwuys1DMTA9+qitA8oNApbT1}a*r zN!~oM*w!;PN+V=nL($? z_0uyWx(zVe2tAO{Bj1_G%)AfvNTcIS;h+!ylir#J?th0)q4gwrjS<=y-bB28inZw^ z;-to|C?2_*5gfFyGY!NCd6q2GqwXw~4A8p~`^HGdz{HE|L!-;TS2O#uGd8WMX4TJE znxZOYox{OqZvXjIxr?e6*?+5kb$?r1xyrHmT`G>0{In(!R(@)hN=HRrlNDT%x(~Um zy84}{++37S?Ges7ed=aNhmHLhF|Ex0_{#?ZpA>8rc zcf}L^q5edT0F;b;us^}VkMHRJ_3DKE##?nwO`Nz3Lv}OY4|H=+zn=1~xZeD)^EWB2 z_@+TL1V|Tem$mlm&?U*^SyPnt5x6zAI%lIZKxkTWTykg$pgwZgRN_Zo4t~0lvsJT# zxsc8nO2T31bpJ48ZCU3qV-Tg4xIe!J62S$7U4nF@m}%o-tgV{JL^0^f7tbx+Ivxwp ztw$+~9tN*X^u09Ue-423zTy*IO%&2U)3YGy)|%+nc}c_^I|KESG2PNIpFw%^{h9uQ zUc*(X12&&%&oj+2JE29sh=4uo_h7lC_TLRo_l4}~9hgmZ+{ZR0lPfp#Er0P0_X@de z?>bsldr(<-LF&YR@#a3z_Bnr({}5w%$Z+yAYss*H45|sV_*)c1U)}j431VIon#dL- z?@>Ld$)Bwz|1+^HvykIOuyi-lVmbTZsutUfMWg0xqbMyHfUYi$H-Nvi3nzZ?^b`^E zcG1yTe&~ylGF{kUF6~>KyKu$v9Y|VBF_xLF%_pTaPSPcOU-^9e(s!;td0EcDc8!l( z=2?^V_#88c6~_cOJ$2|OF{_Q3keGb-E%P2cOwZ2@hy%;Z_1|XsA1~;Ct4QK<-)nu$ z!iJSWv-l_Hka4U0`(K02NVbHY+&oz!WOARFY_npje#9puKK90tjU-6*#Y~uv`lM>N zj4IU&A!M>L+jE1_xwBT-TMetse=hyq#~QS6S|egVmMkeIfL(b$D_0n3cwXNygCiV6 z#Tl`XP#e9^ChvnMoSUK_5a*du+RR|@sc~XiuSQ+)!9DC!j(gs++6$*4h-&?x|og-I_T-;6_()#7L)wqT+(PRF0tv~ zyewYp*w+2FM4V=f84exPEG|&Sxi&A%qs7029jFJiT|(wi{Sd+>q2syWaYm@SDM2(=qY?0!`)_iEMBAsDi zUwI_0jW=6|RHeWq4c&&4xK-sh$oJI=cj@_AqJ?-NY|;37=r(bD16CTUUS|J$n(U>) z5T7)#A*dxg2=6w(hXZKa=~ZBA^^J_ri9 z%hwIQmaWG<+RORDQ;0r&F&m>D>-9q_i;xc}oGJ|h{WXtJ&LD% z4$AI)Cs8Hd6+UP$t<){4I{lLtnIB{mPAQ5f7KR`C87UuWCRdW2_XAd<7mBaOJp-lV zwq48*vhWT!6j7vqR_P^idQ$1@&46a<;ywT8 z$J#CeNVB!nd+p_E(u!nDn6h>XzaeKt^z? zOFOlxW^0@u0V?X=ATR!<7ooS5*KilVCUOCT*2SsYRbO)-5&~q3 z?b&QuM-=kI&G1jg?%215i1Op-mb3ypnXSYl^=B>uUuyBm#--!UIS@=JmwDiQKcx8V z#EfZ6vJzu*J!~G$hxZV7_N7F9nh_WB^dR0Dxr-$P&_S_)QAs63SW|nsUeq7~{F-Je z62t(qU$NIc&k$oCGwTE)xuGTazbxjypNQ?O{f9@(gR*SBn|wyN>{wI}P!g;ftX}a;eWgVD;Gbjvs z6CkP>DM+%3zV4q3;K0Z}HEK`PX-&<{tY8OoM_E9)@FexvH=@aAa^FyeR58f_K`4n6 zKJXtYAH#oUbc;{9z00QyQ2{Q8F3=Yul%;-m-EFk{?R1HK6Wx0T9}vn@;by=F9>{#9 z9|O-V`Z8$CjV=M+ZNwhVEe{kTCrH``ZYs(BW9JRxHnCDP``o?HIs&P^%Il17lIC8) zJeli^@k;0ULufXXin+nIy{WRy6WuB>}LD++D?BDV1E?bQTZ#-;Gc7 zfaMOp#e{Y5%%3k#=6ybG<@j6+7>gA)yrA6+`~#XDVGto#iAAD3mz$ z58A@QLQa`2JO>xoWBvaS7B@Uy$Np~?mX^VkQiRW~7VCxSLI_T~BY{ywb&^eMfQp}H zYL>gR)dvym^KZd^>fWniznz%e9tiJ5;C7&Xu&NF$Jy+W!2{cZqP+~FN)Rvj7_Ph^omwqW<a4u zep_6D=?T^!w(tM^k-z`6Aac3p4rvnj!568~sFg9lT2tJ2?sr!RgXf;T6Q*kPIfGDN z{Rt%#UVDfGt`#{E7mz?9N7{6KH{gA@W!Smof5DgeUu{t`M9^l7>Tx>0Wd`5|?kd`v zB2RvS*=~hZ>^aEfL*>B!5tO)oWIPa+0PVO+IXj5DYCap@=6FkGWN|$(dHafeV>6GW zF%LDbfh8N8Gg(0ucl>A*5@#%$oPx5>>nQPuIV=f%txgS&7%FA zM)wPgn=6!)Wi-{cswaps-)g#3;v<@!{dW1w-=^h!t+yvt`Y-h4?d!{_LB%)YN5H>M z%**RSArs(D#w4s5uzUt}%KUX~@2Q5eh5zNAoQ24(4;sA4zp+n{CbKD+NQipH{wJ9u zo%zj+sqbY&lr7?HDiAL`V#qjNvK97%pKtn={6(8P%Zn>JEppWu2w@1{*7R?|C7Z0z>2KBwV z=$9|Z-p5wiB7e&W{(mok&=|j`B%Y+GKi{g(*ti(tXTOeE#j8X5&#a6;@@{iIEf~h- z4|mJP`f^vMQH?b<_h2D(uXtf82jc8e$|&dR$5EMeOCw-!&zk8k8Wv#0b7s@Iak(nu zpIFzY*n+$(A>EQqHD{ zfAD(FBbLLGa1isI+R32h+B`8}&BG3)cKS7l5!1Nt0nBMApQ7epu*}O{9H( z3MkPY>Q0i@@8mo`BpZo97H7!f`*;0@m0IUS8ymzkVw&3xe&3=g=&@p<2v?Y zDdPzD?`}tYI^%N@*N#U&B(_l}c_ueyz3DR8c{wTlJ*`T={Ri z0E>QRNC1GB2;E(mzmnKCJKz9W5va0wU#fnB>-5!p zKPm9S60);k8AsBIP2CxyntO`rWLy5Fj21d#?5Q6DAL`lV>DN?g38Wh0AOU z;z$NBqVQcuxpwI5bK5JkzFw{0>pNW+d$fm#hxK`LgAn0|d?i8`MkXd>1By3M0Rlx; z+k?rDXLW!7W-9tX+6~ z4KJ_p!jpcSo}PYOfLBsoPsi!e8>@BZQG##ludG{Ow4~(BQbZ<%cfybN#FQyW{^cnR*1XfRRIaN2S482nX( z>jGVvFfL!CkyLb=n)N$e$pz_eR1y3iL(TpQV6xA4XKn#)KzwqUsfs|(N~;5#!|tXj z+EXEeQvUQ{puv6wIPI~ORU~-(-r_pD&sB5j3mx5d%9B=jC17d z5jPfYNNn>D|D+unU#a;eYEETkT@=0Jmp`?El*#G*u$sD#@V4_>Z+bCF0vjjIX~^89 z#q68G&<`?Cl2M|{n8%xr8InPeO2l1pWkp7sq~yRrG3{pOkFBuGp{rJ|4`Z!4a*-EH z!na+)+J+X`^$_##UOQ$~W*}2Det2R=weGQR?6T_Oq8vWa>_gmwHRN~FX5D>67|ZIlAuezC@0#^6 z9RwH~B!Rm%wdRsw(uv!f8!_>qy6b!fH1?@p4J|zspeW&9HvU>E`L>>beM;#Mv(LV5 z{bqDbI|QeQ;4<^{2{+5jmgun9WyZBpjHTLk8Q%V4>kIdo!^IW>pl`{n2GmaM_xtVb z%)aM3Iha2sB6d0+u1nVqUav#FU!X*%Fg~@`4Iyno4J=!u(Ijobn7(J2WB8*YM(fr~ zG*=&W|GJXcy7A!vSX=p7Z4s_LpX(8>_cp`oh0Iv%0R!L}6aV84380C+UbI!J zSvVO6Ub?${;)|KK%MUyPXYDw;&Z|DF66r7S`o8xrIf?1G(xZceoA=JQ%d72)Uj5$Y z1v3;+JSt1UR`DM>S$~8(uw8R558CX!IIl~;f^)i$qw3vhm{@u~onyW^NiNgHaH6MQ>u%K}=ArbO;O3>O3bZ!*UBYJ} zS%6e8sTS+@{8ROb2R0{ArsUoB{(78u`xbmUF3lZYy~VgUkMka=O*|4;r!p@@824zR zR7qN2PY<>={V1N8@k0jTXaC{!@(|!=H!vJK99`QL_8UX*`xyBk_ZH1FJ567r@G#3` z$5i*Z8eLW{;>*bE9hm{tP0feY_cC3|XtI!jlhGa*&S>~@)Gibrb;mddjI$|p7I1sc zD(tthV%dpe@)8LN$jJ^tjtI?tGhRLV60Vgjcr$ltG#q96ZDeo0C|ce1@t9i_v2{1$ z=?b`y)pT7}B6MPyI0j@igIi~y@oo=SygWXQ(d1VcqF*5mPPB@x4ef3=1MxDOD& zcA_b`Wrw$37v`i_I?U8*{vZoLO(Pxlmdjw2f~N!Z3=GlT(4E zNFt2UA}Dyrm`k z-POGpUW>ThZTz(K*J$l`a~^id``Pw$!PCC+%k7AP0izy->mQkcW;P%J)CHW$WO(NO zwP?I|PtZN19=VOB*w>z$?Okp{u(n1R>}k}`x8M%DgjM(k%C^Cg;gB?qQbQSqPc>87 zo1X~1`1l3${|r;-5-nYNAlp1uZiOAXuht3EO7-!fl!N=W!uR5zK@v@}No0Dpo3 zJ(*e{c#ULqa^p^VaWgSFSyWLG0}UPh{$Ot_PHv`i;cw}hT6W{~aZqhmenEM1f)*DR zvi`x*(MF;bkV}Pr7RA9W z;m#{-3&J<>=9FZx(W(g4EE-4QTM$az!TQS$zY=J3?O~7Re6P+g+g4p^(|Bgw6^u>; zRJL;a!30`lMRL`zTwk@#V_y%eTyrpGM#@&p=gW+U ztDF=D4nr2OS~rHeGn&6H>K56sK)z+j3k-h`GcgUsqO9`muVN<3hmu4kq5rA2+SL8J<~_M!WBP`Dp=(GfFgX zXYnfWm%NU5Uh|zan{ynaR~&V3j@grO`Up-B$gH4z&JDXPZ?ATJNM@zcVfRw$B4};9 zRIBSDipXd^?%NA%kzPVHBf;xlK66TdAOWi)$;U3tdpewiE*JFx(38?_2j;?l_xSv@ zc><`eB?+Gb2+I&uMx04~t@!i1lp3g~KP~y%x&Wl&u?p>q!9t$H%EVU-p3v8gmpkOL zv#Z!hpzuSt79Qf`Gc`psvAR!PYMRT>orMv-5jA ztoPi#H5$oKO}gC6AMK=!5kPf*Ds6i}gqC~=`BrFif!u-fHTMRnXp`?0YnAd>?AjOY zPT>!nN@!={3mbFa-&n2|XsB(m?~Zc6X;F)LT8Aa8pP>!d)$DG@*i3?v`^UQ@w>=-n zS2&t}vbDLZQ`Xenh!>2d#n*Etx2^OfLTo*0xqTNzUwNqwd)oSVcy{{wg0m8S0kp`J zOA{9@jROb2dfQPVb6BEn78Pl9^P1=8xb*6)*D3Ix7Ot#e(-k7_w=8F#K_@Z0>J)8D7zT31G}%4eB{ow*N#KXSIs7H~!{T*0 z-@DewZ?qQ4I6PCwr4j&QaEO8$UT>85`sWIa9jnwq;G@_Wvz z`uI>HPU^m;pmf3R$#@IO6?TT9$Vc_!uu@xATN1hD&VTu0RL$=$WzYQ{&tSB`(xmH0^Xu($*y1biUR zi~21a>isL~ZI3mJCYLN}-(eoK8-@M;K58ofDsC?|KgRkF^zt(a&A0f}Sy6>6?nDzb zDoxo&`WfASOJ`8Gh}g9crR9cW&y^tOLb!_MBK5dc_{HxF($sgP*0rD4sHiVQ7#J8_zk=Y11Z1?f z3YoxrbR5s#nIYKBN--9`X4;T|S)DDz+P3o>y(3A0ay$P)7B~OMsE%U(GXvRAVps$s za$HX@ubk3qoNzh0+yY}JMERxM4{r+bh|2ssCwT1-=2*S!<}Hgbf9JFk^M+@CY_|&& z)ZVHifZRaYX3U86Q@pog=xVo_hI$1B6Ed{*DlrLZ$F&$G=c}E!QM6q<==V;K|39YA zf-9~qTGkLW&;f!r4#B-~w~*i(EI0&rclQw7-95OwySux)J2Y@R=e|3}`vq)Z?e4i| z)mIhRkl_wMX~%7W!~M(KkIDZqRPqJm^8uyN6#os&4-`F6W1qf+YvHH1hcLZCMk29l zn-fv;Fn?1#DU47F1CoUkq2z9KZ*tTXUU@O<#3R8D@SgS7OlCWw*Xzl}C3bLa*)I_h z48FTrDF7*M1aPgF|KF{t{pCos@uWO*N5z^dyZB>+q_S2saCp`IqUSPs!UNFY4Q4!D zyyBRhXWYUPzGbA4l;gYl06}@ZBQNOP;Z!^0nS+LDxJdV+3A?_nNI`y-cUVbS$|b)! zYNtP{0B(T6c;QDFNRc7HhvZj;xVqiU6bE?nJ6|D))w19vyGVp zE?)lf56Km4R$jV7AFFVoHQ<;E;>8bZ3NF^r-`Y9u(t(9j4A(){-hOiV{-ADx_cx5h z@~_H(et*?czm5fHM`#P2vR8?&DyV=K{^NCths*OCHcil7MG$F#OyIE~B*$@Htk;}F zG<1uY=Hqb46wKYn;bigA=kUbt?qiC}YyS>E&x$tb+Gf+CzwDKJ<1J5Xb}bto$SJ8Q zlxZ6z&U*T|y$-{QR(SpC43vNYc=JlCSj@|HT&nU zKJ?oyW11{WLd}}Gmx%8(bdzkl1}=yPbn%KWpNodp24IWq0RvlRHOI$hnhNz;sy17a zKfS!wvEdt1^ltX$APvW2n%#Ex_Ig|0uB~``k5@A``=i_q<$wSBsrnxIHQCdF#OI3S zo*IqDB)L2uxjL8_eir&RHE~zETzyF5tUz!0Q5xxrs^)n2b=H{_61{=wsDyf3T=D!& zS1=J;G38cOLxfblZ-U5;k4Gqvf}27Rh12N>u88QGW#MMqNDfOT8qW%A`CJ%pt}ck zryR>PCdZ={tzsgxggU^x6zAeX24juY%m6qDLK_#FZ7opYNU}MK&2<2)q~#|?=Dj-Q zQjzf-wb*$QIkD+^*i~lpp~ma`el+LQHe|#20y$aY%rgPJyxQc<@Hu@zG#;gL%vd(B zDypdl;g%sC3w?b*Fy4Sf^>-MWz2RnuL5<5Vp3Ek!2nxSW5p#Y)Il&!`YdzB6t?c8w z!!U6GGnM=ai2Jw6JFVBMdTh=gKfjeOyI@VWG?}dQb7NsOemUlHaH_rO(Xqo#Rpzj( zLsk5KmL`y^qBxcIu?Kb!4dq?VKmPkM3*K%%a>HJ(l1hGk!ZyZ%+}QG`sMz#S-yt3o zD~n$uw~~HY1p8zt&cfQ=jrL8EWK;^$lQ>*l=s(key^y=x^Edt3zv+#wS=Si^fc{Gs zDsqkIbktlhr6@5y;`6Kth}-~T9BG`kpcow-@#oBNh4m0-y@oj+l(35WffGPr2_hZ) z6-q$-y9_Ax@#80QA~gDg_p3;OgAaHW7Oj->S)W354{nx6HgV(sX5sEB3A$0>#mnRM zS}K_0b3VgjSf*1eF7~*%P0E@D%pKL=3b47!VS08?hhP|2zO%N|(l8YT!xkt`hTS3o zf|b}~BXvn|SJQb9-o?thXue(ug(gDsqPQ!+C1q_)L6W}`a!#Y4r!}X1nbo7IFxv2K zcv^|&m-#+F89Y9IJ4`$1!4lE4BAqH;*cwZ`)!gO|esyIyJ> zraWnnKl8vVPECf%&=?Ahn=6WO02Nn;_}C2^(ICwFIO^^>qbIE zg2CQ&@K-jy0N_EB4}G%76Kqo~=2I9J)|V6iM_CK-IQ$LGzS4&Jn9cg)fwaWBSBErG*K-i3+)tq9^BA! z+167+^MeuqI1xwK`jiU{qo7bLB$Rvto@zdHaqNUF1d|PXAanc_yK}d-AaEO)u|>Y$60>bd1gkPBZB2O`qcm>3=3hcrrY}CsQ_~P(%VAcocbM2kw+EvK=!jGzTKfk|o6G|NZ35 zk+f?P8~y8-ZmmA38OxZX?Wy8q%S{UK`ZM7`kHG|Tc_p0Z&>FV5ZRmD^|7;mOL0|g# zU06YX(~Ikr5?AfT% zZ^*V{?0l&7Lg})_VV~F;+-GjUW1d8?X0c!QiIRI+nx7`b&iLO_L(zBWTNCS2>AONy zDe5{EdSP;$9!WBQ{J4YTW*I(K8lO@!0rC$A7QZ`e$u6fId*tY6-Qj9&N;k;vD`-B_ zoV?j2c#=P#36+vBi{2OBCy$omdw5I+c3^ydNuHuZL`4cp!9Aj+1TDCpws{h6rJ1 z{MByE^+avq9Edy-t|e(nDm+LXG6kU2xSM`90NhUGI_2f4FqJBN-x6*n7aZXKB8wQIq|~(uerc*QuD%_AW+Rg+H;OAq02Ay&6>jg#X5VNpIG6EFfz+yU_4z;WT{yu zDxMcc-T58mPr?@VLd^#!q767!BuUZ^J7$N>E(YgljEQlST6+dS?VQNOQ>=XJ^$*~w zm4Eq8%hY%YA+L9^lhsyx>g2fHz&K@XjphnXf40}kt4Sdqv1uxS$k2C;WtH>A`P*X= zd9S_T_;kM+qxu_96Jw$qZTT7^J7XM?m#&5EhJEe9@FHul zIq3`CgOgCTtv7t5O}nq{S9veL3kXq#`{IWO@anTSw9CLMD?&-4)dN?08<0W_#2ebD zzbUcdTp3v7E-~r1xaQ3+A#Q?rM>TfmP;sh&&ORxd22^mQmsIhPh?tMF+?b!A)Pl9}GknxVf$e#B5zxD_zj0u=qVfQF<;>lxtj3_A`>g?%HJwPVm1sOBBs zD|{p4bp2y9bk0FTyx zvJR!7vs0^ht_c6wL1+Lmgp2@X7{p@xbd>5H)GUsEWGsb@t# zROd2pp@zNwBJUqJ%0+mA6H8YM6OKbvd==6mK3#hIlD7E32x(&iCTtt8PaDc>E5qI3 zFa_Bc%Gslp6&412&j!NL&Y}vWm6(*HqI%4#}-XWgQ zVe1o{oD3)%LG?jo+HPOgZ4j~QmvlZi%oIGlSrN;6&s*QDkZsNc97op#eGpF=e~0Z$ z_xMm9CS?;?awAW6n0DAzLs30`X=&L{xW-uTfsRS{qM$b=nO4~q>A(>jVQIdj#aZWh zOlaiMpBHUmG2qJgBaqd$$IpmIsNf*~Y(de;Fo-jV@l0ERGEt9&0Vp15Et}9J$aTY2 zJL}~?kZr8Ww6AmEv9azo+EH-*@(g;XJ!nC_7j`-uLGt#1(mk>Vnhg16G(!W+y#Uon z)maU$P|sJS?&E0|hZjTvM11>=_R&9~lxmKOm(2zo-d=w1ML4)kr05U#z^10IR-o(zsd zvcWQXre%kDoz8Px@q*v@4I)_uy6fBd0~GEbF7B__eoxHT69T`D(hbWF9ff!e{&mIH zg%{#n=KlE#GQi2UEc1`j$oRxPUfA{sxww7~KOlietjahY6>Cusw&kavMiW93EdM1L{J~PQ`&hmnZ5?%ddhkNwNvO$WLTCUQs8zbO|rHO)w2$*xbv#-vno$a z#rW5jlpsBy(>$_>JKZxCf}PKY*7)CenN0#kmhAsDdduDg+l#(fUO>}sjF&9G+)r{* zYvuEw1GlTk+t&hYEsQptz-doz@q4%DR4cPCF&AO9AuoK*8%BYeGur;s>V0Z3?`!?Ey(W;7S|AfX=A76o4VO9-1XiGp!S%P< zW@)9?uI7N`$=a*&BK+z4!qQvsr&wu9T@K_}pL+iw*;tzqn!?-Zcr23UmFoU;@oiWucMZ8W)swoOtO9E=6=9b_1 zvVU16>7J*tLia00AVs01IrML(&>ptTmG#&yXMBFoC7YYuKO2A?`W0Z)t3h9e{IdHAX#`Z_Nil+8!26?db#F)LAt4P51_Vm$LB@ z78hNw&-npe=qB-aL&=8d=MAY0!(`1M-`ig#_G<*MF4Cgsrz&ZE9YF&uqBxyJ9M^w| z=!D}J2bt>#Bkf+xFe{ko!l*hQO}<_K8|*r?8;+7|wq?=vK_Wt7;Nb!l@GlrrRSvme zzGSrc|J}k`fUS@&Pu8RR$NeMZ-?X)WDL-G~@O{BDbIUaFn%GE^{c=e>W`a z@`W7hl~sh7rqMs45&cq11p2E!xqx&%>=;15v>zPmcaUlmH!pduw~=Z?FFm#Jb*KK! zJ)+dwC3Tp5PU|_tpUC7#PH+59DihmC=Qnu}>(>>0Z2|YTg>co#pNUdFS(_tyJx0=B zCIuz(b$jUJ@=P$@J+(ro?bILSr=P(kx6~#Dd;c~9un;vDeGdf&Q?K>0ztabo>O3h5 z_9=Xi0&A5<5am8TTngVzrQGM(aD)VPL(TcJjIh#u#eP!BIcQ+@4V7D0DF%3-wg|6u zT3{1)fp_-Uwn9#??>}{>Nq>L#SL!ChPyc7<1&cjhnjIiTA%~KWbk6itr-R=%yDFTO z0vA3Ea9KBRFGa?fPG_<2|A{i)GR>@62ChTufH|2FybKX|q}*ykO9XLSX#n5R%X8%b!({B5d1PIG-; z+-p6_#wBk3J7T{kIh;*Qf32y%%d7^Zu}`~E=@@}Ujr(Lt_C!7rcc90yq}#m=Hv)<5 zT{I$?5NSfXXL{@_WZPPmkgoJxY?6=#a%iii+~6M>8>H@z_l9=LbJ(p;rzMKNT3Q&K z!!kP%C6M>_R#+GZcESHBx2U+G!T0~R#Oe|z=M5ve(k+G@7Cy!S)ae-FlZfM0-1rgU zn~3K1Vq>`UwxHunhAE^GN;i3_=-I_X&By?!?yKm1PQaE?F>r=>vL;mq$T@<-X)1Cv zDQ6r&#{ejqI7dWE{1E!cYs_&OInOSdi56BH412qcoe*bI(hpIG(yWE7r~{XBUyz1L z)zmYA{81v!pTrrNB(*Jcj`}KgDZ*MvnDl^@9Kv46$f3G4@MG9aT1YUjo|p6Xk@}OT zu7@XA?^60ihk5VO_VeTr)d^*flINqTzCS7M>F8lFwI4XjAev3b-pQ;GRo!sED4L?9>Nq*@gxXE|9>n%( zo;)Oj38UCGFtF`x)?(HtU@J@m9v7d>-`kKVv{A3-%8#ptm;sU;sQQe~S9GV>#zUr= zuvR5Hq+~Yf73y!}1+{roLrZ(n?DgzCfv55r!FR+rB?168TSJwO@E#Y$zx1GQ5_ziz zSNOAJYvXWC`afibnQf_fL3()|1x?nH_F=9=q0r=>Q-`Sn+LhnqR*O5+eVKG@F;QW$ zfxKSD;T1TJUq)a%ZqazyK1!Rs79mU6K#qRw95yi16rLM$o3t8siB1orU~*+1y3(gM z5u&qD}jZM!FF^4Hp@|M>>^jTiOI(h}^EzDj8Z2W%<_zy`wc z`2k<^G8n5?5r}e`C6HkC3iUki?(SKlYeFS;yQyRcXU23p<6IHO3B=O>?AD`$xj7;>r zan8CkO4o>^lJu~&1He;(h zmflk)t}2-@@LqLLf3rQ3%DLkc+?%9SaN-Gp7;oWYWjPETk_7;H-JFFZt8#&f28~hz zCDQ|ibREaz;x_n-n{%JVa%E_CR8h7~;zw#ze*hL61A6mDISVmMirI~t!+ie9ctJ9qaALO_3MU%Zz zcj%Y40=NAlk_IzMtx?@kRdkEa_b6?PED znL{rsbXc;k*zD{>6x>O$Dnxv1kwg9 z{*%vLj#7ucSnR!TPYe87j<%gSO68Efj^4hm;$Oc;a8YHXd8-#iOeN)9=k@=_fIfJNB~;u{%J`F+AAq z&dHx60MVthB0Mu6N^^Q7r+zgT*wU)+|hC;);2Ni%7Ps+&i0|_G(b6`rzR0G zNvd=sXCrAY8fEK)P{I{ZPYm< z*8zLcS~F3GY}9@oKhagJXuP%1;l=e6PVn`J|8ni(jR4{zSzAC|vRg95>48{VKTuEv z{&SkT92X~Mm6r>M2GKvxH?$+UKM?srJgdTwoAdmZ+wta0{rIYS?mgdO*TQjhd&wGib44)DSf9H@2?vV&lb(QF?BXW6epW68}IoQ z9@Uvj%JDt>V+%qG3ec^O+bCQ%o8pqvNG)ElywzQ>D+c3Y13qJ|^<81*54UFVS1q#< z1K+Mn&c}|{siF)%(*#El%|?6ZP$A^V=~r6yeKV5R%eK>$`ELnmMHQRJ!gU_|?JO)M z*I@JSQqyHV_tR>MmHEzCa%RI_q&wuhq6Ym=C)L%`UqWfZ@&tT`AD;w0W9WwePgws48ogzNZR_awmmlX`+(lnCO=gBVC8MuVT#gxWue zUJJzq)K_h(-dp0qgj5a5k#ukz7gIrUe2J5~!x`F4o2;nGRM=4Nyhlyr0<~ z0^*jp2;!4$Lcu^C`-|QK=Pf%v(7pw@@1Jb2P8Gu|vcb{1sOz!K@OZb?7JGirvECnD zZ{>O+OHC0{litPwPifS2sC5+bdiX%_V6>vgA()>4NAyTu;Jc*7!8 zFp$c~dCR|*xP$tq5opnyuuXh@^4Uu**6M;l1Z3rYCb+sjW4!oukVAo`JURWletSNC zR-uxKW}s#uR^*@GZ#m3Umr5U{KX8#?W`UY{n&?ZwzE|@Vi*?rrO~ZQF{c)X6e~f)(jw~Cj-WD7%-F7v{ywWo1e$V_qV@(CT6rv zP^1w==%4#fM64I6{Y_?lJaP5t)y1<;2L!!XJbEgV$kBj79G=1HJ4Uh<3p z#z$#Ih}U}^Df9J|5YjKCKe@g>)PA-8pp9ZaU#j~qW4Jl`PiSVS`~E$U;O9C7KS*LG z!)d>-o3PjAp>MRLWA#rZ`0pb&td=9Woo3JI8W&!)$46V3xPgI(VU6%IJ$Xwz7_45f z*;JZZ>G2_U4&KZ^8Kl8V2w8uAfblgYq+Bw?BE4+c5r(NiDC|YZ02{8V78jlujMe{DZzw)QhdAgtA}Vzs z9OD)}^hYNWarpbN40cEKupFo}h&MYYnwMsvH$AFn15h1aeiKCVdeA=4z0N$^54C;} zN_pCjktC7RDX@3H%Wlgj&3689A{eZIEsz%PTn?k3iV=|U@R>i4psP{w3sjI8+yhIcD zIbc;c63LAg;Af(~h_H;QvY{VEREmlX!hfXF&I+&3ohi<5l2|+Cxlh_{^wiZUH5b=m z2F~|btMW;Q@i#M(Qel%dv0nP67yQvNjr`=yC)7>EFAM1|F4@S)iTU9izZBNWXTs(A z0Ywig$*&$=9c=PPNL65+F&y58(BwMl(^%X12`Q#gbRi8)tqDkVXDE-22a`BeT)G6AmGL4Slt{OTQM*tS1 zb}N+X2mqR?$T*2g!LA0eO32z2s)VKteSGA$}Z}`=!LK$hSj9(IH6H-{A(K z75|eU+`5B$y9W(?f<{)I@>3CGq8R?U1?Yzn-+6hf9Si^f=!WDAd)viAz%J~@r~NVJ zlCS>tu$C0#Cgn2(qj^UoLOJcGJxYA3%!T~7y9Dh+b4HTgEoNmqFPb%n-;Tey{5pc7m>PKPhMcal831{ zz*Q+ulMZl9wud(>b+S!OB<`w5W+*Z+22U39pYth&{z;z5Z>_aPh4^BqmfYis;A2kAPU2v;zg_q(xzJq&0%oo8rF z16X`I!S9ce);$n>g&Kmd#5Ss*VL$d#35-J5JwJ=Gzbh@2^Qi|q%_&2Ax7u$TtZ>VI zz8rYJ3GD8VZ&v^R5X;i}h1Y{IaC5QW@tX8U689{V<$}2BPQN3NFZN<|XZz!;2+zqD zE6p!|<~o_gYifK6IsDO|XHA#gSdGV*c=uDOR?A`Avji?X;m*DS8ugkz0!GINbE?Dv z_|{;y=WSeS`m|3iPW+H8J{!VG$&rqyR3>5JE{k=PD~QeIU%$}^IpxvbRpUy-1<2#B z#QWf0qN}Z8efcco1Yqgx_Wl~VbMTR|`J(-z8&da#+6ult0eZYqDk+U_ovG8vyF9Gv z1PgmSm{EpjK>r&NaNFRIW>_-b3nCMaiX~_pQ{%jhZJB^Q%9~!_B5VLEDiO?rW?of# zvz{wJW&DTz;$7F(aNGkF#jdp?Px~~>$c6NG?%1#WEqvgPc-AZUIGaZ?j7~B79F1>< zS5IA#y0Qd^_knZ+vFH3LxbeXrQxZ!1>ZuJRGV#i-K3nxES`G-xXUT3wk*5v0YVxb< zFOwgC{ZD!P1(5vV8^7VYyL4&ZD;^)a*YRVY>mYvvw?#He#|sI4j#6zkzsY*}>V#R& z3+I)|h`yC|%+>Z>iLXb*9{cn&mersAK!3XJ?CKRI0}IeUo$;~t_RgVaO3V5>IIiSp zWfF`@EmF9jiD6?K85|Q-!gWg|_2q03-E{LMq3LY~n|k(qDC*Et!Dkvn2=C>m%H~)s zPfSz6{7k91aAZm(I2m*%p{>cy;sX;UhT5wT+1{=Vaj1~9K4lx{*l|&Rt_+63C>J1w z=Kb6Aeu>5jq=JBte-^P>06powdwoGI26|w9-5x>%m{E;NH0=+Uq(g4m9WcZ8}o@$_GVYLD!iyBLw*tFs0ckg7%A`R zY5MV}#+^S7(_tRSEyD~3n;~UFgX(-a-%o~4W!46(F83jykl!ulrNBAba_L&4e5U%y z;AX#M3sQ`M1GcK7D_?~2ereE&c=}jtGR0?NX6C!UuVPj4&UZ69lEy$o^NSlYZWsc7 z5NzraSni1XvZfr|P7T$FB|?D@#X5Wi!98-il@}@~CXjx*j(ge}k^vFC?BL$ZItC|k zGIE2zA<)-jyceyX?oYXU-!S%>rlhw|WWdOxc+5^e(?Ax3Wd zqH^utu62{-;_qn!S_e)-zFq&}mD32TEa@MwvnOaaTix#LoFlx?%)J4SdIN0E&Vm(V z4@Fiz=UebVSYi^O!zd$0LH{2Ni`y(+3pjGdC<}Fb-_|BMeS*XtpgS{VA_usU~Br_AMqYmgl}wk?*W zdEnx`<&hIJ!Jiw54Q+Fdy)Fdl;7b=VNea+pmNFv_hx23(G9#wu3VW7;aulXLFhZ)1 zG#vOd)aW{H_`&R&-1!?#Iw!XDRhNmi?nMOpvTW{e2nSmbiy>Gmc;rft{!wPmS#@Vg zQ7F^10(y6R@CI(m!;Kb3ttUhG-0^jv2~7q52xfbR^Vh5MCt@M)e$Ps%x^1`jEIBPq`eN zotr!lM*`z=pXS^a_0UnV!|(a6^tu|e#uZkXpGMpEK~4Za@O5hh;xXLa?`$34wQ4Pq5*q}VATV2jnTH0xj`&ONAme)^Rl#Qx?=7;&c`CC@Ci;2_vE+OE851K|GIfUS6g`TbU2aU3BndnX829N<-wx(+Eg&QrIxC?da3N? zg$$<_>Vl>{t`dZC^nBolht# zxa}o<9kO*bL6)nHMDyiZffrfLSS6StwRZ&hKe?8UTP;N2qU z=F1}GmgiXX2%Z_n(~^N%n>0_$koVyMw%69FFyJx&NMF(n>3L?z8%1!!con;p)xYM;FBr?zY^Rw=f69+y;{ z_ddYAp*Wp~X;md4ZOrlj^-e>LUFe{ z34WJv=VES^45mE-Niry3S}UhE;CIN3@G?e+AR+cnGsGzx&*Fx%(|rs;A3Ui)2hQWQ zC?^>$vv&^Yt&9Ojd1EA}tE(12W2DgY;^Y-~)}?~(Vr31l9tp!UY+;O5%1IszEKDHN z*{pVCDSfKJzu|>r(Ib^&l<=N_;=cnvnQ_GzSsm?A)s2{cv_f7Q4upAA`P75R+)tO* zD;?;8iE5DB39LYkL5|&c>i5|l7L5flxiFhCS^NVSAP}#UE(ALu-+e{3&V`ME`9=}K z3?ge(9RIRH{q%#Wgd}B%Gk2D-;rS=Nev2$7tDBdnJ=^!yPbjw{YgHm(QVnA)Y>~Zg z3i*fc)5Sx$4bDByHnd-(ATo{un(LK%Ll&8Yl=hG;S;7^oPt z?9vd-SHhR$G>lPM(ijW;=Li`&=kXIhj4A8K-`y^5k9W~_Yz4KY09s~U6?X6T6Tz{A z@$RZMUT)p_sp(z(fm;Dms&GkcARamA)$b-_E74!KtDBNy?TkHS!Zp=)y1;iBqy*cK zINMGB3mf*b0TKvHhXcfW{(?YuP2!VdJRA3VyT;S%(9OFANL||b6SVi++eL>jA-AV4 zBS(1WXtFCo+O!6bnRMj@tyY0<`5uf`j%u z73E$D+QEArfe>OWmge_0%~40dTu8kUI9BjU3I$uoaZdD}cX>K)eE?@d%+cL7Y}&Vy z14wg|6UrDM_~^f~bYV(2SD9Ci`sP|@nOBBe0Vx|n;q!hPan|>_6hO%e9Fj0n%UNBz zO@|~fu&^cpV0QY1`n@p>)OC6*liLyOC}6GPi!?nsdpjCzRwA867g;`Q1#3kbs`YaY zxGPPUbl@Y~Z7EWincq^6y?s>G=btg`Si3pq0|$F8cctaN5%!23PbRlMGm5U};Lb?^ zM0|xA)|h?_lftHtynGkrd7ap8t)Egs4gZMGX=7w&K#NNJL2wy9*PHW2qo3QJfF7kA zl0OM7jVHpu;d_gBT2%w;LSJ1)(R&SKR`p*EEG+8q}lqtVf1wSjf0@clnbmp zEe-Nx8@dA6@H=u$&gsi-po!=k^|!w~qimHUY_L0CcUrxfL>OUXewA>gh?7SP_csNK z_vosd_Gu>hm&`nVAT&;ce|}k0COjV_d*Y+?lr^rMCTC)b^f%JPy+`ov=@FS!_l~&B zPTdW%KiC`{ign?eSdnDR?NoE+_BM&1SyC*_dOKA+9GJ7!gJ#L0P44jPwd~tlJp5a)JDa%ryj=B^wSd=O71Qy( zo0HMok$Fl#bmVaZJRJS%7nkf6flc)J4F|><&4C@&h_0KDunmutf+$UH0Ct0!Q_Z<= zs;~nqSJ2aUFu*u6;_SRFb=k{D|9RMTk%Ym319O=7k4{It4`|xs2uXfa3ica}HrVXd z7&2+$HR6D(FB5fd-AvR{MguY&tx3;+=(xsc;Z#MnVf!WB@wH1I`__9K)$aHsvc!qM zXa&3(d0{9mL-t@L( zsFhN`FM|W|daTC!?Ujg;NdwooKs0+ri2Np7FR*H)K*+qY^65!s(`S_QV;7d)E>_>4LkRd z8-WnU*>8E->|fifpXUn-D>#Ho+Xph*bsRkWn8J>7t4rdD6q0n#gt1+5zwiY9+gOU2 zoAW|ajBtp&9&u3$Yz_A(@_uy+t{=`XPXuCBhgIZ$P}Hed_b=YUy!@h*5V9=go!}Vf zy`OCP@6wH;YQ6T4Eb8>JLVY2E%cpjMyf&}M5R6*H-Tk1*Dy#`f+1s3L?8>PYNu zV^|n(=S^DM3+S2qGwUn9*7N3)#rpky>|GaFRd)e|%;(uMK0#9y3_-!CAr-ngKYiUf z6Li14jin+%EtjgTZur=(g`oV~?y!=`8ApNplMOLMtr7Bo4m<K${`M9*Xi$6*}K5LHI7D{ z6h@!uZd%aasLM9|;(Izxdvr6QTR$Vb9@C-`)AtC2rL?B*U+C1Qmp>K!{${Z8HoREl zgIDEas`L+BqQpbc`DX~?eMl#_ob~uY_4<)p7Z5F6!m*JaIs?hy&MB{juusNIK{%<*h>7P+kN~5NFZsrMYvx(5MZ=T9eW!8>{E!!}(f}OF z(75waDri6gyVWL&@)@5|mg-0aYm9J7`dv}i65gsoJY-$CUkuEcgRrWmHr^7C#>vNp z*al=f89;rlj4!Ut12B3_)K%W|r@FlK*EDvY?pEnfLNvXfbNW65xKFN?zwQF%+e)#= z2?e`-YyVQPd-zW+O+|Fo@M!1HPcQcBgya-E56~kWnJcC}%T-3u@`u%U`dbJArBN^= ziy>%-3A_Fa(l3wxzQx?#-kwRPFwC?(UEH$U+}R-EksWta$0bH07)I$5K{vK-8mw^J z0hWv;gSjJaVVJ>?G{6ADh!+1NZxnJdn6LwqzBg16X=qRh22=`1pIJ^Mx=cl$fUiC_ozNM75#N9Hni; z^kAHSaztbBIHlNm*R?#zG@^NPVnWvvU541pwR>HlFFLB9 zrEOyO4|yE(hs&!4@M`LAs3Ww$qgy(x@ym_jJUP9H#zINZg}k+! z6~q@{LK0WsEHEqye@X~)FHzlk)_^Vd!RuYbd@V0Q7|Q~aDhT0HbL`KdK%Zu4RfC~# z4ZhE+{`BwKQi2}k(%@VbHQYg}QO7I5Nf};8WJ$MxhFRf2i>C;m_=)jfEMsW)HAVi5 z_Kj(TOmf!D37G zT>UH>$1=drlnnaGaJD7ExDr5PK?+eoFd>$F2)r$JC4?j)&Bk;NbLzuzyy0E^6{CN_ z0Lf;6BbU&vFJ+>AGSBc>ar!j$cia&Msru&!$S%gF{cU_Fb&$w+rnJECOrAhj@4(u2BY-x$kZo9A4? zv%hmL+dUrCADO

ZV^Q`zgSBBm5xz)c!ygUboG1Eq4bB=9v{_q;c7&s2$erCxLG` zB9y)TSfEQn?;`7>o-9IB8bNo7dM7N*{Tx8Cj29`uV(My;Gd|*$PUUVIpE4v6o{BVZ zq^n=uKeWqw z8d?I`;+6YI{78n}L5yVnrK$|-PKQFf%8{|>URUN_{uLE@EFWodL^6*R$A#P7PXP2< zezlK#hJ?C9pWw_0Vmnx^^hU!Tx{3`HKE!phKH^^FIRY&^Fe}v)BR|vWr6vsNcRf@c z6F*rtEV_N}E81Xp0i(nJ`D^1okd>Cyjwa4UTh=eXY5#7f3wI16Ff~MUnLLi#@pk)>tt0w#%JFQC8LbR#q@R zyg%3u9AwCSb{4dLaDs~BiDa*EtdGyVtLs@-HjI?Qrr+B=-vUXLY1IeXP6WZT697-Kf3(V=#6C`&9P7zEc%iN@C12 zkeOQvAWNc38S_d>&g< z*$F61xH@tH!auxuN0wJ5UL!dza{N@1T5VYFjLQJni|~FT(W_ODy?&e$Bv;EpOp4ZB zZ&!d_HZwjQU_pu~M%BY+(jKK7H+lK)=$_g~2g#LvgFW5IbVUW)#!2A9Q**>148T@OwQ8Ix$6$EXv~bKB4y)sK$+aJDsJTbJb?uosJ84}+ca@l1 zOG{+(KiNK%m#_a|2UHS}#bLU($9?jm`=o&5GvG z8FLXy6sfw}*5dJPF82@U4hSyp-UO)7))4&hJ6p5=+SfA)_1q8DMXo_7F@P2(hYBM) zTuf|ttE^6SS1}TtTZ59+R~O1=O$cN za~{WFBI>MWRI{URkphZh(9ueSwF@DvATk%&Ub9zi{pU|;r^?edKwrgm{S18gKqyyf z3NXO`PdbDs5ND5AlF2Tg+i52EOC=(jzPrez+>Gd$ZKb&9$M9k>ebB$PmHVRIQzoiX zD{jQmY>oeF0eZV2KsNg4eTbEAMo+*Rt9aK~?F_x7d5~o&f&f(zZ^bw~nIUDA&igup z&D4w4=0o08eOT>qSiSo0kx%_(B;zx!e973Q*iT($6?1!50$vXwV-h>^yjBfv^U8|u zLjA#$r$)Z=jjr&S5apHok_#wa5zekU7&wzCPc&wVbKfWPw|3c`!cNzcgQcjNaRvAW& zJ#|BZFo8-3SgR(`Nw?PZU{8*nVin>$*}`v&J6d9axXN}IUq^e>KT%d`vmRD~gm~3o zu%RQr|HNyE_cG4ici8F+LdKWQ0WS|q8;{D@ywWDRA;R{k#~Q17x(hjd$dOq%1bsdN zvXSxodx;6d&^t=oL}dF?D&r8bA=WzYasPUX(uDAU3HTLEYKf~Jr9`=NVhuB503_7o z)+1_52`tg$>=!8&9ctducLz=n0vR0v=y3^o2>awpm@kGc&?9dzHgdHrm#?`DH%{Kf zF$)Rsl-AdNYcGhVVhTx=1}=rg#UAKgTY&V=`b+5lAk6ld0mxDRA6y+IjHNGhDBtu$ zy84m5D3+toFOm6(d@rdnmM{s_&fE!qty#bDM8okA-d=pRmrFRjKz>TT)`Xmy?lCfq{J3T+s^1?PIOH_rj$@MH6Yr4eG=v{_VxkF)$aI{+BtiOnDUbcJMfG0_T zoeZlk4!3Aq(To&Ihp0JQP5%GG)LRC%!L?nurC4!?;6;kNyA~@BEzsf~io3hJyA&(# z?rCs$cXxLQaPqw0IWy-^X7VeUWM}7=wXVhQx{o@V#gC(*?}Sy+b^Qw{;EF#^#{Z%6 z?%=WhVJR5yB)}TvJV3hG?OSCnLfHU08@eg@B8}Wpps=SeZjV*QCL zN!Ll(WN%mE{|t41<2dU-2%vW$a2_mlM{Oe?3f-f3kt2Z^8S%v*j$otyig^D2+;sC$ zH=P~Pifs_MO5;$VmEfC(K0Fny_hj3FDP6l;J;+wba`lSsyN*3dYJJtklW_7z6COi# zSN4sw;5)(Y+GK?02^PT1i(<6>6h%ibHjM#srsWl;;Y{NV9lGAc{H{}aYUOo?Rnh`6 z>u=7@{(Hi^HJzygl=McnWDQwelA4Th8Fx5673e~7KpFWA`p@(y9JIl_#O4WhXt<$X zUW#$43ifaE5Mlil<8trxnfF5CD8teKa7Nu)m0e9WkV-L-Milq*E%Zg2BoTQ*iKM*T zzJhHI6m_ptU}dwopZs!NEwmY9K2we%{*+9<-}Ilmj4LP2O=zJLqt4+*>rX(&9nhTJ ziNuTay1a~{x&c{WYMc=MZ=8PkdmQpv;S(Fm*{Q7%8fy;_V02Tojibx?v(Z#+Z$wOY0&z zUO|}_?&A7KIOloZE`BerE1{HDk#TMCeLkdkFVe4K#5M*lQ}9b`$8zx zrR&d&<*I*|Q}Fd)>D{jGtuF9X@;N`m`0&XN_W3vbxLmi2-b+(fB6U5lYtRj?l`-iw2kO^QNkX z8D{~yAeMu57iC0GPM)F=n9LUj=q|s6@~HT_|qkAp4HtbmaL_I8buJBtv%3lyH32^P( z!>f7gpu5h)<3khS zWRWe#W{9{jEJCzF|0Tu^M}z^1E~T|Qy~{@vcsFC6?`lyiv$$978(g$brvnc|*^40P z4U5ZEpzJ|&j}} z*(wFAqBa}a?b`!OUlBC#&yV{cmRT1o3$ah69S!BKq6i;6rl+o@qrrcszqTt+ z+#AVgz~V4j0C;)hpWVu*TW7RxyE93)Y2J^W2ba2)jmqV3=!r^Y7wfNu13Y=<9>BTw z%whe5Yp||2TRk87P036Jj#ky_DM4C}aFC23`yJWmC#Xp-Fv&N4q&;@$<@@g(_t7GIvo5v-?Uv zI6S~!AtRV71jpY;SB&Pk?8uBJ`tG)U)*PQ*CVVNUP)qMLQQpa&{+QNM+1e=V^Ia zhdHYuuD&-S0%k#fJ)$?QURi1DhmF`aay{QysglZ0%oG+~{?d=;^^T64{ZEdYnzSc| z`r5p!bu}MF*g#A;e386|^cC{A>td@e#VX~c^#4u4M`uk2Z0Gh;Z374&F{s+wmh)N` zJ)J-1;j>iuKRvMvDq{s7RIR8Gi$T_S_ulAa0}6k<;k8G_Y#PbkM^ei@Y*y-|R-{(bt(> z!~F*BfMd%?e=pcRir>Ala_mC@2}`wH!QAg=&?>G>QEJ$C6Cpn zHKM-nHHF(tUomBRrax~?GC+u`lP*l7v4sd({=n@_<(>_JtxZ7isuRc%Hb1i#ydvjv znG!23ye^1aIPSH>>XhQVjETW1kST`_F9mE|i-LHeN2y-MeKhGPLyd(}t(cp#L{XUU zoFDlS(TXp{N%mjmIL}z`vMtWNgA<>6yUm2{>_?rv9UB0z*?*s$$Dc^e=w{{;hL=i7 za&N{t@q~zBJOV|{d4V9nxZzw%xi*6$ zFtiDjA%AW4oJc&k(h+S&olnL8Cyc06UuG$fyopkd4_>P#^~=Oh>OuA5)e`NhZ({I8 zAUQhq4^jyJ-$P5D|@U zUksVD1-*xrv_1(nG&a_pmX*PGAh%$+mdRQ5{bYcI`7jF(y>3;Y+{O#Z&>jpliJ%D! zfSM&wu;~?2vc5hmd|>o_$Y{NRgL)aAvUKX)JlG;=U6ip>S@`OV)b=_*SCwy(eG#B22Vm*nRg`N8Kz ziLYwZVZfTddV90^@g{pePPvPqqi#l2i2z9c3G||F^H<_W)*>cP6r}=UX?Bq-t=1@JJSk@tjFekXvSn~`;_d~5aqBQ@q-&huWCdx25hpiz*e1T%)6YuJk z5-Pb0)m-Xeu3t|6D*_H`fVE_GK5L9#SXF?6p{e-jcfmg~JjE*j8UX~FcSYXzX({rd z>i+;ZPPNu$$Lx6hV$azYSypUyXWuuamW>lx85n}~R_VoQm%Ev0X+z1Gpn2!V+YKTj zu3hkl1v7o7!8MiQ!W}u;iD)Qh2a==+0}fZN;0xB$AnWL}Nlrdg#t1X;%fXm`b(c3B z16zp;W7T)hYaNvDMsJbj3|qck_Mbwqohd7O;Yh3@3kaMrWwf(@$KnY2G^s)pe7|f(=k)PnF!lTCGZkDD)5gI&rLr2=*Dl#oiO!iTLxD{Fs zwj|am0RE6zeV#D&%%-I(U?UR58ek(wJ~ZT15+N=|g3=tcP`d!I5;FfO?)~kR+SS1$ zX-zYVaTBsFG9XQg?6n0lGQ4N0zG5yk07GVWwx0$^J5RzouOi5n_D5hWbpBpC>i_2 z97JZ}hzkA_7Y&MLb@so1gk8J_PYzn%OLJn{JT9&cgbfLO5gQ^piY~{SdT)onekDtT z>$k5Nc+)fj#2c}Nit+Sr!@rq~d_rKMO9StRTLz)q0ZjS4(vCd^?C*%z0j>>PH^=Pg zas2)q$n(+6^m^MPVf};d)(KzOU3`j3yQ%Ftk`P;a92qFzb2kZ#u*@0h??|_5aJfjY zbb=HQWkvqNnl6JNG6|Kt>g0yu-#1$U8vMb-MS;=kz!r`oI4I)b-3$tKa>$23qdrJou-d%hY{&?I)^VS*FU$hh7WK}_*h9oNJqgNXGpnJ=>wXTll z_2znFncL}$NmgzdLPCh2a zh`W~8Gn6h3u6Ktk@4Qfqi~Vb;Co3g36k|s8TfZy!x}9KB@(-x!?pX#cFz^)+BuI$G zS77InxOgh3lc?B!LpWNjXFKALMReR;I2J^sfiyVj;mS}5*2@z*m)t5 z@vzJjAre7{3Xjt&^k$u+|EEibF)jT+IlOh`??h=M)y0=?2v;t(wV~U_4VZkHoQ#1IK&DyiX0QIz5|k3 z;d!unHn@?mJ+*7uLgW0$*t;=a5!kQgR=#Sld~TlllLxm;&zX=gcfhvm;% znL17L%z8vV7a}e8n~0hF6_e*#+fZmGtZDPov2vHQr~0!3_72{Q!$+fCO`e)<0^(1t zb?ySYlHPQ=X}th&J1Db&LaL zGI@bDVO>B=cdX*@(AZvT@5yHb#KB8agrwV-a;NNQq2Ta)!F`tBtFma=+@*=zYUu`> zedap=wglS$rqI8N9`&58!DsA1z0%rVwQiuJyS$9^_A^F~S`HcY5r@Dr9l4M6+#m zyWDJFO=|j8NS^ZS9+XtKAMrSZ(Q=xf#DUUw3Ft*mRrA@Sp8;E zbR5p_PBtH5^H{LEY|w2|teW0;K}3%6RSrlzWM22!xJ5rUAm(7YuLStL%`!|7{AoO6 z7tUVwfPP!^8vC!rs>hKlP453N2!Mg3ck>J352sLG+t%`raeK|5zrG}Vz>-4nXX8N# zL=yQ2FwZ(4ckTD{emk8oXM5Xt@@=}ZS2D=Nu!_m5|I`mh;eaV2flXID_wCnT#pOAl zAKWvXb2mjBvn$yT_nm7Cx!LHTs;Xz_yF#Bes=b47f~BwK+eALxX}vep^zRCo$CG7|OuGYN@}SekhO?T?JIUvrZZ(LotV7-%&4 zK=DMXftWz5{cI%emTOB(Yvu~AI^5&t?YAXaEHp+DN)Yty8hTPD0*O%3whq6p^gEvz ze0SznC@b|R3?$BnwgNaanZ_w2|B#7bK6t2kXB%2t&3on!%B* zT`8(O=HrHTr?oPh>(7C$Z;+>np8n`YLca8?nLm2)@+nNAD>j}Vd|p;gHuFOFdvKH? z!hT+-#y2C6B!8myt2SzzU=Z_Q-*3FDys=YzUqor- zsOFMmG&G$D|E!PcJt)I_9IIolG3@!h8e%VCv)4i*9ZeLt5o+akwsP{=Zti&CgM3IF z-|#D%W*XQ&&`J2mH8)Y!O@af*bT#)qG>2IxrXm0eX(swZK(I}{hW>AZ+sQCDJ`NWb z(~wt0lOe|e7jv#XlzQz(tBRdsA@z)?EW2ZHm|^c)Rw)3O>_N1FdnS7$#nZXitxfMv-D`MtiCIJ(D=TR2h3|vovt( zmtA~_{-;kuYQIctKW)XMoWbl%4zg$(%j7cFmBZ7I;kUjT@lFUeRYKJ;VuYiqxS*Hp zz%+v%#K~DGjP2NJ*gw=Gc%Ky|Tro|-y&7;xgm2dGMiKKOoRPsypQ|-j z);}Ng_;MeFjvwoy-i@r{NwQL(#Kro2vuUgelZw>ak-1S<;*V@b(r$0Eq!||wxGzRO z#}K?+G1)=94UDua@0-}9UY1I{3iW|~snu=d!!qlZX$UT8nR5@+O#1Qfrg8mS;}I9Wk-}YH_O_RL0NL_S`-X_m99@Q*opI3#4?Gd=w2C@@Wm8dDpCWtk*O&wc+%qFa&C8vjZGb%FKjq%?u9c+df#{>4;+47GR z?emL(vWb)0fmn9YF<%>+soo&M$p_7!+g!wDkV~|>f0Vt*!BOexJ?mp<*lw1V4}79ch#a| z9B=26A+p^B6(pu~t@PiOEL~if9M9-_b+-JrvpK#!9E^3X+cD@90Y>d6uI*8N!T zWLs=AMPbsfgKM%~InI`?sd`W&j|G@BKVmeEnC{CmnmB+b8A!kPFNB87HMI$7fy|f{ zL=Ak?+#gBSp+$f#J}2ytZ=VW{F{8T05oDaaG3V`{tLHSrSiKa$krMQztaX)cK6|Zm zL)o*TU-8jW)!1=Tc`}6r`sv04VQ!v$Aw3otC(*^xuohG915Kecgg+K3Jv{W{&dp0_X_u8v3J}gz|9_ZwC2*y6}Zvpl~B4XTNXs(yc zV(ZL$mD6w%68Jd#kXde{%eyvO`5&pPP!!|z`5uo=*Aq+2MHlhbZer}#5Ah^^i)lBT zNR2$}m3?b=Bf4A%W1K$4mX~uGg``;XKf)L}-Yzgg533T4q6=`@@(BS5iPQx;IV`XZ z`SE(_kZl6q+RaGTH{3Yo$z$1T?qBpzP{;JRsp$I?#%4wRKKO3oeMl_;qWkR1C2TB> z=A+|H+@-Z>F?TZD%RWF7-6P3w8^k% zAJuVJYn1MmlMA4^rZ&tP`x^70A<_Z`<1EI@zqMVelgj2SN^BH72Dw%* zeRS8mdQ9&;=%0EKX50NPkHZ;k>N|_> zbBvU+?ix+Uh0{e`jolU}OimN9(3eru2Xi<5Q>Ao)ZzKW8u#O|9T$8o=I)%l1<=f0| zCem#-*Ru@xtuG={OfMgR>I}{8hQPj$wcP>|@oye5ENTkQABU8Ln;<(0;;}cDVw5kEvzv5lRME~XCIWXJA4U=Fcpww9i24TKE`8W z?eC9j!UIGie(RkLH(;=9kCRjqLMxgOL2laVoeOKiE=s~6A2Hw z!)Cw2u_m6c@}DxcW3|ib)o%7eV)8!wi%R1#5w=Ak8Pz#^!Qw0uyr4!Aak_<=FrdqtWw_2W0K!K+rAvBMx2XEYqUB+*amCY%cKf%x|5`hH- z@w|jGMo`b&PE_4C{b}8~F%*@!xEnV^^G|Bfl%=Smri}+;LUv+Bk*iv^e*bq4F&Jh|Pw-Vg;IviG733bHa(6$!Ps^Wp{69l$~ZHKX|HeEYq$n-F}hR z`1eEem5I&%`IcxsA)e#B>qRwdbq$cDn8C#|uZhp%^=Vw_=H@W+#I1cmDl(^=*RNQ-DGgt`W3(cHlo+iDF~5|$GWluJ-$QI7S` z;kb9aYtQMH|CRH7pO=|tCcfZGAB~38x=rI-Ro7DEa*8%9rvYbN`TOtwMg(Kac%@-s zdugI4f1}!m1PW@eN$%uP)j)PF0X50G7^V{?dkZS}q)kCK^?iPJm|p|BwKt5`_(em& z3f6BQ`rtvh(Unvy4p)qOMSZ%z913k%h^YWS)GoL8m1G^DLQApSHPuuS*XYLt>}}rl z52MMet!`KVbI~D$>)uE!N){#74(K8)V1+em=VTF3?vaMs;r2CQ>t{d+0UC`w&J*jm znt0sF%Y3k`@$~i=W_~qZXB{x9o;bSjky8$zR+`Vn=N|vB`Ni}gr33x`4gFR zHyYvaru`ytCOwm-no12>=mGFXl6QGSw!Ul#T zYV0d|y1$CxydVae1*fYHR7`U?91a?XBYwVo0H?6(!(Vi@CzZQtFSrYxt}MiWsCCAk zGI?$NXO!QW242fZ{_tMFwOsYDY+Vh!BQzWb)8LzYJ`F|Bda5hKuyO8mje+?(vHwc8$jFF?Dt`LO<-gtTGHjd=WfFzO5_1`dfaWjkhfh?EQMG; zQRQ9goUM_!ur=hTG>M-?Wl;-vkTaPsG~%-F%1~5?n0IVQaVY9j8xF6^p*!v?3 zwd%Faj;^W-spXzA*f(_CJOc?2S)22wbC00YKdV8<-gInVr7%f4WTQ4%#go%yul|tZ zcGO4`?`*rPW-q|IG6h%j8@}v=lcmEStT}}o>Vx`yb&v{9Z?ysj4o6S|G7+tb-1U~r zw}%k*p18dpF$ig`?)h&ktYmm@#k4}*3G7DR&7e)ib{sb-!qAYDm2Yp zxwuw%E*S>T>!AavQRRo-2s0=sRnH^vWTuRZ&|yz$-now(lF??ut9UsEEs0KD{$B6V z%uy^QJv^UWT>qYc+BStdu7_8wPF8GLd5lH|$hyU<-pa2O(TW5oGZ|fpGCh%9<#f_s z@SulPi7rTnm8y4;BM^;!-TUjo?&0lZgK7kzhxO=uBl$TS>kO9F+IV=i_JPLX;L602 zV2{^^r1!=$HqcFhPui;iVC?d$61#n+&tJ6ziMi$iOsJWJ9mUPaG4oD%l+P~*ZG?>%qw}_t@YLMXB-ssLleQ0PUWif z3hzpJ9Hf2mYpp~m8Q8%<8ui+()f4rxK$Tf}^r-hY?kL{QX5VlVc3v4Jv8{Etm!?8N zM!|V+I%4-}qA0>EB6_!6y=jfvp3J38)1923K@jlq(Ux*))QU6lAGLI<%HFDB0)^ZUU`%;?xx4 zop7TL`s~82H=QF{bl;<1iRZqDpt{dv_ukpY6yQ2n*$krV3=XL$l2t@1b=g zmdH)IZFc~CwWqZM>CHcSOO4Hek{1}opvH!v4b0ojM6sMf%2hd9QtQ3GgM^>#WyqR)O>y;#@OGBDE8+qqO+YV zYrGt@eG_ewI`V?hd7?ok-gQu@q)|^=@`p2ioudnm*1znfZtTk0rn((Ds@-dXJh*N4 z+!$@7mdKmiAp$qM39920<9@q~!LtTB&XHgApJU}|(fWTh7atr1wx4gh_MH-J6-uyM zria*EJs7FgxiWL}-@ld)HO3M}=@xLQ53L@NvHiUpTD`;FXn0j}!0qQwTYdSQw9#pN z^_IEP`%|RKCfH2Zk^6^X&^8e?9Em`Jtqi=#jhr!ELd!lrlUe`IFb4P7ucU4!q2PA~ z?C0c-;N9R_S?zqWuT-DoXQ6+JpW=gK%4TsO0`6F8n`dr3#>2*Y6iHgQ z2Vb)TkS`iaYOoWcKcDY&`E9oEoA6V#F&ZK3;Sxx_1b6hHM4P<`XIqf?EL;Ro ztI1GKG^zrUM^X_J4JwEtIEp_A)R{nxW6}Zq;US7Ram(GtbhNyqMb0O=E<4fyelwxj z(Q6t6p#q1!)W-X=VGwlI@k#Z+2X>B>^51nf;@cMVbbEYmwRM$WEB^jhkoF=^SQgbp zXJwawD}y>VliiJ%>_TKZ$kZdw*qtFnPGKUSM@E|cz;&kNSJd6Btpf;&A7Bw~2iVP* zuP5#A7OK|#w1rswTmR#uLc4wJs2@xHMT(89{o%AwD~4&P-PBg-M8NBPCNea44qxaU z!dPQA<^fUq#p!ElF_Kc*Arb9Y7;3RnFK73KC~qk4NBR8CFk!szt*TsoZT(>~ixK?8 ziY*b8UqjHNZOh!BZ1|v+k>j#_bvdM*gA5J&VygaHkNgUE2adoiH|&q1&yv&*Q~SK} zGOWoGQtkU%Z}|2kcBLw>Uz0cRT33O6jcj_5mp zEt3ZM4@yJM+ZPt69{(M;N40xl(+(dZ1usQSn_E3TkzqEr|BnTLUJUM?W31{hId^y% z+pep5v6vz4cV1+y)#gqJudSl5W`dL5mIy?0re90j>>JBwi>*4$S5l#TIz?EGM=FJj zBtUen%WHUKz80ChEC*}tX!T_mVbn;PfQH_NzT^~(OkU-)iA5Pp3=Ah5eTOi#I1UX3 zudob!Ya%(7J73H*$p*ldES4pP=cU$^4W*2h!4J#TU^Uj<#U3abIq?jP)JADsjs$+r z!(d8>SEjy^7vZuSR9Vllhuprp8y!pPSkEsn4+mz2blz*5j554!iP(8nj~bx5a&^cd za*mp6tD<@rgg3=hkny4yjSHZrfbJN$&e!K)H1Im?cI5K$90oT(*W8ISgaO%L77sN4 z{weuBSrR}H{N|w3KHJQW?o&C89CeYX(FmlZMQtKfkx1-&i(q|A`Khvb@PcFYJs44@ z!7#DuEN*he*7uXhL+g#5^SG^hdy{H`w3zjo#`<~mZ%>C(AHe9|YmO&bAPNf~&S9o% zxklxVZF+DCo6CZ3Y&Sud9ZXeFUghR`0Mw$`18w%<hWNOZI13Ij=cOFHudpW}hK}#_hT}&@J_7XwYrBR%cqCY{=Z;1nqN#WE(>5#$x zF*p0V0UIV{m!Og3%3Aa27o86AcfZX9fg{OC!hU>}M{~jSMVK z%+DeGee3H7d{zQbs4e$x0G2quiJ#6W*DJ*wt5);n; za1`$?=Bg0BYQcu=Q-7z7lw#qf9;o`1-R~*$R&ZQ-VxLp8_oa` zJIU^@(Eub*ZpIQse3}RUE5%5Xu7z$A5e*4=vMa}NA(t@A3qkYmfe2`%z;1)mAF>b8iO_!IA9PvZr}5Wnv4)?H znA42QYF+0*K^?}sAWEZpYTg-}_q=R8kRN9{*ZKtwueLVo0gfwXgm$HeXrb3 z)>H*$ig+WxsT88ork`D8rnfD{WDxWdDKwx>@T`~#pv}&Q>}brVb6biwSszYP;D_|n zWHSOKYH=lHS{S7SM+8#IV2L(n4ZclWuX5X1TZet;IB1e>lHETstpVl}%OpOX_4gC} zYv2Hp((hS)RTREB*ig~o{- zWu}w*f%vGrWHW}9@2f$I$_F2eEJw;LyK||@#TrBrH(PeAU!klZ@4Kfw@;Q_W_UE($ zIusf^g>?RX71QNa%6|H6~B%wPHuXy<*O`;*^g2v-x??Dp<=Onsr|y) zqvHNJG4nb#0Ea{;GafZ!2bdp9#MuJ&S8`2M&5-= z9$qKpZjWO=KF&;#L`a8?;D#E9k}8?*|B*xGz8#XFyUz=Pq~zZo_WrcAL|KQO>cm{f z+Oke|eUW^S+J75lp+befSf>X8+N$gB*p95)Tu7yR|^u+3$xzzMc_HOdQ83}_T>5V3-5Tu>;77lz_o;C93Zw-q0sj#?<3Y&Z#oGYYgJQJ zlo}s0$Jg0;ooma~-s0(PsTss8B3x?Czd4_Oe6@bfg6Cn9EhR#qJeU3Du*&RI1^p7R zcdiA&)nRSUGtdI2MSIXQ{G0IqCTmw0m-Q!Azxmq3ASu6blK_aE&>F(7t; zvYs3HTT~zch3UIdP*hTIFEaSpINw>;KF+d0tFFzHO-ftt?^X6Cf5}~ zLk+QYBc};$f5AbAEMZ?5flwyM{|a)&|F@#4AQE11GMwa60&HlI@d1jd-U_haMtKqL<}|nPX8xIb>g=7T#=Tx+3H?I`A8T|8@4_*nC~N(W zEWRjc#V&p35<{S^M`SIhXXWmZX)O{Rv!7N)qAfEM!f$5D$TTvKxI{a?tJvvHzg4S=7ms>hJi_^i^nwZjh&SSbao0Nz~z>|}KgwKjx zYH?K#EUSr<{)OX1K#!EbfWrm(l_u69nE!iGSC~#tUg`5>WJ#~t76GeN&S!9BR!JBa z0nHDzP&;!bW`066Alv~gRalb1&m|3s{O%SB?jNGT*y=I#xLjSyfA{{q18^oH!MEo# z1poCxsyj6Qp64tL#)gyKa85w|17$jyv3lKEB0FpqMBNTOgGe0T(}->@K0!Z_3?gDf z9K~zHwCyy$o$jnRx@SKp)PUqq4r5v2sayYofI+mzaI2(0N-nChD!)?keTk9^PX2_~ z04-U=uxe)?@i?4ScY~_%I^e11#1z>`Ap;9oU}AwzSBooaN~X6+5kPv=%8{`j09cWB zWi+fK!#w^2l=X)NR?oMXu^#Z(0-_X1FTK*1sMLBdzT_*o{*t`3A?vJThcrJrckykq zH(#@L74b^9aLaT!3D&;-IKvHwy|vF_{dB?h!|W^xpumtn5?6P)yZ!)phd3%>-v*|N#IHpg}Z?U(HyV^a;f5;K(XJnG`KrR zSk3{I>6%cll>8Ks4F^xJtLJxl1}qhPyH$#V4j`H&{Ak*(fX;O8RF>wkULU~@u2D!9SVcM zmqY&7L0LNNnY=bZSC5^=89(a{p_|Nq$6q2Tec~?)Zv{2Av3ustKQM!C0K@+VQB&U? ze!$+ka}P}meLL5|msQ{ZDV-O(;kjN}%dtO-bAIsQkI?E;F0kLR-WqI-zR^ww=0~yR z>6%?f#oR`7;<$Buj*`k8wQ=BTa>jAYGOI!1lOKUMMTp4s*Lmf&(7^!klG0>9kn*(M z_j%?$_oDE1nSxhdJoruY{!d^mmQig&ecL63u5^*Z<;&#$)!g{&=@@KLY}22 zdg2IW#HwKe4G$2j|M}T-=1xqi)_Cp-PMQw_4|zR4a#i%$cKx^y@ZT{Po7w*{Ip2YZ zpqK;Ce3zN$J|Y0%xRC{}sbhF*u!a~SW`B73m0>WD0KbaB-Euc4V>p{tFO-ch0#~3) zi|ouQ`k^59#%b+(+FQlB`zcHRWm_0H5loW$q^;LRz}}V3x)ytN15l?m?TT<2k9Wz5 zaJly*Y9)zNVAWrkfCzim2sdN{cpMGs*7bg)eG3ckL zFO~Q34bWVVeF6V?=Vm4^%(58a)RpBB>*(8+<@@;=w(U6e+S_w z_7o8MYZ;B?#@1Yo=N#oBCy=j*_Q^#fH=A>+s}&gwQk^%(^S_#( zwBnv8dW&6${0%q8dMnkU2vlrJBAsV<1A%WzZOh(t&uA}A!x!2|&CaYFv0ZVUqRpUJ z)Em8}V)9ch2qkKc2i;05&e`e3N~`&u=i!KCp6{IraMf>vz0WfU2IoGosLgq@&60Rw zsl6VZh}Q>B^5G9O3$5MoA=DOJ6R6z%^4zKNKCaH@bwA)XYUTYJZZIlKp6Fr&uGKW{ z&$%>Q(UjaMV&{M6tHwCN7l~T+9)8FkFgUS{wO?Hwu%o;_IIRbL>A3&-8wI}*nd$G%top=BZbZ6sg(FxzS)iPPN-4g zM!fFx0$(g^QGoN^?_}rt2F^65&{#_)Al9xze(%ouDa-s)jWZSU1Ec zlGD-=15ZB@Xh!XxvvL{yFku;5I@RhKcyVvXVk9H|hUQ+I7%0mvu?7IE<6B@%Hv++dlds}PKLr)tAm zGTC-Mtmnti<}(wWG+P_L9wr?q+HIkDWqsxpn5m)Ur8*xx)nOO+?twuLA0EP+sj(!O zwONLf3_NPotmR2K!?*W*s2<)4u_$R{5FK> zlX^ScX{nuc=L+rD1Pt)3{@iA_BVQv%U!SPGrZZR2ZxR$*a+6k zTP+0-&o&;`B8VnG$Q^4BbZ*FZegKjIOpKdVy+nlmlyFlvn{nuVbg7aMEY8n#&6vKk>oYm)#n}tbSlM| zsm{?j3aZWg$Szo4$WCl4oi?dDuLoq*ybH~?>xuXAvS*Zhn$+_&9crg$b$dP%%*`|8 z9Zj>RBk_6E(E`0mp2*0lrpsBllQ-FI;ncX=I;!EBKXtgje-L!F30%;->Hh=gb0jYs zG(i52qBLEZvP5_VRY9Q_DG7gq5~h?1O=%>Lt*-NBx~a443!J~Pui;oR_4&}BR2Y9I zf3xiO>051ee6s&uR#%~4semsObMWPYkY9d;2=&ie!g$a=SV&&GEWcs5goyD&SO<&0 zpe}iC72GI(8=pt* zDn)g&dBqYj{rX&hV4gl$)yr-IWDX&1mBA@H0x&8-2u?}p!AP&P@xCB-v$J^vU4NOF ziR`H#X%3|U)0BpjH%inHGns1n6AeXDnjw|UKULbS57x|Mmxq7eh?{KJ4{?ZqXViSa zk?_we-r4mAZThMluHB5Q`jx=9#I_%J$LppCgKw!eSNK_JenyGQWA$r^l?av=QVgpV>ea>ctR*RQd4co{f*H=?5zwiFR#)h=Dp$W+~+VA|fxfrBU z4qje%?udwPk|>m`P%Y@M^=as?#L|St4$<(RhFjSLQ@JI?YE-Dc6pAk0E?X*tp^Wgc z67r;Y)algWA_e{r&THh(-Q+m43l!wlTVFTn?FK0Z3Ve39S`W^Rvk}lq0=&k8{)-(a z?fv2XieFO7|4B0oI#qaHct>5Pml;OA{f@x3zye(gU4?>}8M<=aS!N6pXnYnOJc@Y1 z9zfpo_yQE;q43#o`7+e7a;;n;A|xbn(*WEV$(EV_G)b7u&tm@QdK{**iOD~PO=an- zP{H!WxQPxrUG&6uh8~|m)6s=b2`pZ&ga|(=Mw#=qej$J3PxxS1mTdh+B5trKJYqK& zOfA2ax`eECjyV)r-qhQ28V?91DKAU@#Hh7|2hrtRUbpkqC9Qb7q>8ogWs7=KsdwXo z&df7798UrL+LhAXEq~gIEdfhxs4A^=OYaKm>ttu}nub4r<5kK1CWBbf0 zc4HdHEShmhSHE?(XhxX^`%&v-$r1=gb^m@WL4f2KTe?d#!a{pLGt>93rP2D|~*~C)yCL z(QNEH8lubyQ4>EpScwl!tEOZ=^g zOv#}+b2hHlW(r$Ix5sGC5K)IH0X`}ZLTYl;xl6$qXO{vSsT@XDO^ytQ!Xek00E3Y) zGDcIPAb>b{6)sK}bO7fOh_Hg;tt_hRo30c?D9?iJ|J~V_Y)J&E1oV?1%Q2b;OX$z$ z9Xvo`(8M`~uSPZPFyZi>Z}bj|^_@D(DhYGN2U4*Ldpv}b7D+9!@yEwBe$71}o4rS3 zp&C|>wuDB5@V*_&i9Z~~y5>{Bp?qW$g39WLrvZmZ^1d%vPdCR(r)*j28<+4h@n<=}b%Upuuha)l9iu7Z!B?}m-HI%_ux z#_V|;>X&s^;^{!Yw*(UZpc$RDT{nz>NvtbBNue)1hBTaly1qo(mqAxx>GEgXCAW@k zWk-)^btO#vSo=hrq&2rVVNC9i$oxwLo%8#0gmWn`;TXc#3i4XtTTR{6B+!*PbIB;I z(NvWPR;k&qy2s_>xxy=IKt-Rl)MEagD}o||bnoc6&L_S-XF zSl~r6x-O(vwMBr<=>RWP-v)Kowr?T5)baLXKIss9jarIk!B}lD3{PpZ`~%)b>s7n| zx_L_mqlJaV`C-Z5`U-tgN%JYw=8Nru&Ee+dAFM-JKP;vM@Ci&xgsN+*tg(PmJ9`3= z-6Vc`r|Wqa-c-0)s*{;EVPWJB3U94xMU^$Oy3G&<$n(`g9r+CZMbDZL{94i_a->f* z^lZbGk&@Vsf4#6dR)r4@;8ZjAmW$?8ni;}Q(Sl*{ z(b^wz$nt^i(O}pKKGZ-Z_-+HPU_IhB2D#Omj()&@`wzazq(bKi&f5Z)8xWD{)P9sABk(X>D;aTw~c5w@=}{tMKyIs7eZ; z*PUkBWZWH8&ja?Z2Z43wOZBX5P7!-g^vvaEey6$}Lc$Q(AxeAUqz(jnuJ5hSOwIq9 z{hMUu;eEDp4vkD%>ypErBU!g0Qquc)cc)l1#hn$RHPONKWW04;){u^%KdBfE1gY-Zz_Me zamk56F+02jL(+@)N%VEae^q7%pwpuCW`{xow2DGYGRTC`&VG8Z9FnI)ivGDK!D2wo zFx@L&;U-c0pXShHzqgXbVXvH64UiGp5cag8CoSF7>=nDW1IqzYyoau|4Bgd!H1gMP8hWzj8X_xL@ zZ-Oo?CwOYQL@l%s1aB|*vp2>p*oDuKB~49nPP5UsV&Ny|(>j zwpp8gpXhO6Dy%hv7ERIjn!sYpf$4S49_yPg`=9wRR<1iM+>-_^7g}#mnbyotWDNXA zkUrIMo_{?#0OU@Q!H%Z^xH9|J=0nf7yACD+B_(M;ZdZp7?pPMnxi9BWdNl5ce}hn~ zqAG3o9bOfe{NQG+FmOCp9@_jv6IskY6ZQ;I*zyXZY1M9>jB{4(KhY=u$Ps0D?8k8@ z4Q;oscQ~oe#E_e45r&*~r?bofwx4wLr*R)b;tLK+=LR$VK2*aH=+-ugTdmaDBwL*= zg4rx?aujK{rx8^!i9P|YQM+??y$irDBR#EbN8|&_OB-T$TLLU+nOwA=ERSZOv|m|j zN_4hLt!rktYzMMP3I)`*h60kz(r@jL07kG@Z^9*)m)a8KmS8+PqrHPMGL%O95799m zABz7QB)ZLa2o#U~((=wiiApEy*-DU9ST{sq;+M%f#yA&v4~176N&5%OazItPatxfG?E)p*D11{;S?{-fFLwKZyyViMXm zgJw1y1}`F0jvKp1-jpa_=%Y3K@DyR;!e!foVPk^3vgwaxUzb-4XP~9ZfrdSjtaY~F z09_M{Xw%<t**u#=k&(UV; z$6ffmLe_tu26<>ib3aC(2`g4(Eo^Wf;aMhOU5iyA(~EY&-%j)?yE|8s)nXkR?lzb? zqN6cEK>oxJE!@ZRA%Ou{)aQZJz;@X_hJu1c24_1Zm;n#ahDT)`-N=JPbTvNrsT_gU zc)ZV>ygk6Qm&9Wr=R1|HV0qiE*gJb=d-3iaxNV`?>SY0gzMbj{_Y>KYR?GEvt8oq@ zUtn*KnN{aUW{73lUmQ~>*onY=&Fw(^&5MB-Mzx;6<)8QY#M`qV``v29Cc><>q6#(H zXl2AqU9l;;+ilH$_ilogPdiTI=j+z?rD|B-7>7*k=5ZCJsmrzIzL}1^NEbqxBmC>OaX)R z^AtR%X-0is?vD$%0JnQ5o*O!YrQ~*CvY6x>eyF)ep5AmH#C#Qrt5q;!%L1TU#Wgux z-lpRY-$H$U#(jk6An+Y3T*)5X&>HV?Ok-RnZCd(Lfx^u9`XTgB zk>((cJlfY5;$j&P4k_ig^9#!P&%Q~3mVnLWMrPi5g2Ps>Hld8$t&Z@PNGkmasP4|L zK{l5NDFx6&0wr`X0hv4me{+46BHX(YYU=7S9n4og>rqJW(&3>*eTja!K?my=W+f6= zw**@DFD`o1ZaXfO4D);uX#OVZWCWawCVMeG)$PVun*8?$h(ZVcVo>*LEV8aRhG_Ft zTax8TSR8gck0iuWAC&S%E6vIu=qL4i06gH_^6i$caWlXybR(2hQV7iEN)#J`8IB`| zF}4Mk)O>mB@PsinrTD3_=CDffPyc>tqCC8Bc(h8d#OFd?gWy$HRrmEqs{;ZE#2`8k z=8rPkBWP=W$_u4R&Q~cssH56jh`fXu*LLCa|Y^e%|NpY;X5@Qfq$O8A6+E zc#CpRrLcYjzL5_D>{`mmU~`|;%w(3YH$^-!fbPf2A>Al0Y43_z*;7rF^hBaidr4PU z+$+C!(E{3yiPJS)a@(?Z>k1|DusO?sKPT+1n4sbDQ1>H7x_0_-l3#j5l;m+7rwsh` zFQ>1IY-%_zr0QAVd1}nyXE+wQioHGF#vjtXt)^?vXGzfG?ZR}PCCG~+Mesjw*P=EZPUu1f`N}h{53FZnv|3i@D-FzSMeIe314RkCkIQ ztNYD@4Q@qJ%@T)8WNZ_kQNJ|K2IxEYqXo}DXx2F!q0BsH!M@wo29{ma1*yoCX?CCM z-*}`)B{Mu=0ZJ%A8Rkl(0SS-irv_V(ijjL#gOS_KT*3X5Ilz8|mTV+@*W2TBCwu72 zdb5hP`{s*L0CinmK0jDb%Xg}FZVmLXk;i#&_`GI!9$9P$=@KAb%+LMnFx2E)N$00# z5bG1lB14Q@`~!xcsBX784Fw5qhulR7ok)|SuSUk7o2);osQmeZb|1#(`U$%$4p+(h z+XJ*HDgGfIk{y$iC}Bcb9}cQN(G{k?!L}_*AjZFbHY5|$tAUOwROa~zuURUCI}!5o zlZR06DG*XGskk#1)B%(_zAvA7p>c1I1H#NMwik`*B`<5Y*~S(%7%jpzaq>C6vq+BT z*ak-Hv$0QIvI03UL^zVLQ~l0YOxIel4(n&TD^W4ME_PC&ihx0zThK=m`r|8_65eh$%cqi10>~pOq3A(Ncw9 zPbA}`M3_w|8h(?#!S$lSLIPUPS*vuXMFaN-&)2K8RL2pzyN!7Mj$I6OX|4?~r(<6MUJzLd)YS^%{i#g?J~9@mX>QDv!CN4wSQgHiW8?bGnrg#l~T?MlOH z-JPv#h>{3$g7*!6UoxGGut63#l%auj8|Ki_5293AfIS}Nm93-6pK^dKmIA_LcZ{v$ z0n$xo7FImI)C*Xxsm87YaKmxi984Q6YTy0E2pd?GpzfE?!Vfp zZR`U(MQ+}qHE3iWc3{!@v-|$|T94mc<{athcae`U5N@N%PrQ0z-|;q2uUV`*7<{e=E+wlBuXf(z>~XeY-@D zC4N9Vr^C8?M;&_R5HT}}K0L6T=rh>F(C2x6Va1Xc`I>074f6fvXx?d3=WOe6-)-#$95?F=mu$D%hi%NK$U z+uOU$@}Nn9zcbRVcOJ0~P8UC4jfU6Vt~k(kl9-mlZwt5n5<*~H~tpEkBaBjJMh&VNiTevg($V!)Ni z)+PV&rM0mM&7sjv?)synmqf^6k?_^5bQRAm$}SL-a~MqneD#P%+WG&h&_$a{xZ8)2 zK~ueP?wP9gx^)HGLd&C{dS|D!^;^VT_2U+uRBf321{RgSgz5?Gd26M&26uEDC@)Wi zw!b_=ma!iB6V?8`-wb@F1KE%y@92nML?j6?@4MhKrFDI}sTqvI{$4f=$CMM%TUlLN z5;!)A0gTj2#`8}ah$K>-i4k#G@o#6h9iavXvytG58mn7%x~Wh--o8b0 z{M0ocjf_MUdjDWt*YvY+G9HSlJy#BIUVpoTNRTs-*nGQ2dEBsQpZmS|q3u(_hGeb| z%UgTzv$5X03RE|R0;oU%nW&OX?x(ivdsr8-96$m5z8>?EY+*OSGeW6;)%`A~@nkBd zwRm?cgx4R2g1Vh*T|_@r`ciwoVkKT6UcgDRADo8Ucm@pwgZ zW@ND(tE&;V(UT3m^R0uTf)Th&&1pz}=)`J54?ri;rG!E0aVhY#sK`BTH(*3u zcoTGGYR^DFp;L6Ta;=T!rWZ)NsmUsl7L+?6nD=@12q|qB*Fd`IaV7N=@?yAJJvz~T z7dM1?qz(bgWTFwiy_ZX4{dDCK1K_O6U>FSD~~jGnSiqGHAv~9_W9Ika9c6|6S>*S%a%oe>+bzsIXxP&~S&2(~O2CQ;39$3!KmQ!G#m`dN?2&T^Np zn;0xL+v9BxQNH<{TEPJZUjn3^aGZV=_nB5Ac~XO zLd(X%fI02zIfl4u^`@D{x&NLtObVix*!bUTl2Y#=N{+$l^uAR13qacKvy~-t=OO2= z3pR-x^{L34D&?}YQKySje>*MV4`WIEasr?r`ZA2YdKRHn`CW;3*ipp}vX?(J6J{yD zA+nO}F4H+Uiw&f8e}L-U;_FMxMs7~+`UDm2_NTZ6q{As-uiJq_TqF%ntX#?tCBOWk zN_p|6Pryx1D&P~D9knBFNepAX#^;LaM)Cehab30Foyyo#z=`b#5J2R%1=!vwgwah` z_$;m~{KBCDNy7L&w?L!!_iAvM6p@WRRt7%R#QtQXtplP3Ndg(AQfNb(UOta(IHYe} zBI9#SS@~z7h@ybvAUW+NJcOQhiXUIF334TRZ~L4=yDq189Tn9S!yqWDp8^$e03nzT zKv@!I``hRLv~J{%ML|1x-S2KCuYIn~9;NgNt_pov3xw+k*N>n;*y+XS>nX!Unl>8% z^V4*U9^y|Q9@p$&9D*Jdm$>h^aLvu`FGnneVxbF*aiI#*93aZcTH;4E-EZh};{7d5 zOuVB=1FtZxvUo`RG?$5N20vOI1~hj_SOGRpXj%==uM7dEnBhb(H6j3j9dIRTWfe9DyG$dEeflyXGB)66%CEAYL?DumVVNg&Pe$s zO`@i}Lqf$BU1W7LawAt=8jj~Jy0?K$9Xe+_J)ZmrYn<`Or|`Qeqzrg)FNU{$`$A{0 zoUbA;3!l|IG+@fq)Z~svaR4~r&P%$dZ162s!I0;EY+1Vr$=@|RX1{g zP-1|{VfxV%60D_QrU5;j*lC&OjBtp)`n7#`Ri;ewH^+`DK zcKXZb(oWZ?s6Dq7+TD*HT9J>5)VpMQtwRjOMwM=F+C$dbl^ipQFY{%kOiLOnOCj4y zo`4d;GK{WgpcW)SyZ7E)LZfNbPHM8js!%r7(+ZXrW}&XKwQgpeOC<)ms}BA&xJKTSZ9SX?CdYw%-sJG#pvVnVw+M8_mqjdf-Bh z0BiSPz2-cJ=miUMh=N*t8C#5ru|-alL64Wj+}Am=j%S^Vym-wW%bm&cj}t$eWeFyMg8-9gU27W*ztj&29w6RO=<1kKROO` z^b%v~?!<1dS6H1sP?jGo@^G;b8S*9afje`_gPQlt(_If8RYy3DgtWf$pm$N6b8KR@ zrQxOAztsQ1k@$E2KRB}B-U*Osr!)__tFf*Lm+)L328L1M6qiTtKm-;&3K8WKweB_? zu{i%VgEJ%y)7a4_BI`d_cd`_-U{lX|V8)UQqDV_}BQZ?V0KIi8v9S+=Y6RXQDFinP z6tEtGv+-0b)39^e$C&WRVv^ilAt{_Xs;ceO0uJAjaZ&0qi-Itom+9DL;XTq`$OQ8Z zz0i|&SDCuSK85Y<=GhQ)i{}D%|1)Y&_N38YdH{S~L zFA8$m(ud(}GBo>6kE0i1W=O)1g4AD*&M?qTRw8u8B1ni1uPUz`G|37uvVPboXmaXb zl~7p5C4ODGGq+Mq^V?1i%(I}LT+JAwhLk+oQ;pjfwa1P<$m7ZnAkTaDu5*6hjn(rJ z_4)|;h}QkKKXf@QKa=a-(3V3-xIcbVufTOV$X{xGkoA$*No&Mnl5GH%fAhS@sO$Af zx(9i!1B#*b{2Q=n=VM3AeDAtyaoO51%`7Zdo%A8!t^@IScWTF*JBdUJYf?jc?ke*H z7X~oreezOVigSr{h;OEQnACa=tEq7Vx;+ zWzhNrY~(U}z|&FEe2^nlBlGoP;o>N$^n5pL+;(XaK3GgR9hKdE$16}UK%)rVw!sa_ zWqUv^1HVi~v?ERMw0tOU+FLlE5;p5x+(X}^qI$~rO@uH6dSe<5o3T^SEekNs7%E`X zUn^$(9;u5lbsgIq*~etzH@t5TXmQl)QV$s}D3(2q46F;a!M3E6rek#dO z-(KFzLwk0Jtlr2gEN(Z5$_^MQ$;HPK3U<`~LF^0`DcnrLIFx>~p>_EN0F5nI4MO_Nysq$@54`t;QQ5wweHc-tZOUnEa-2{tQXfPVIVB^vIc@==YK1$7 zdIvYz?i+HU(jFgGm6ifQ*%NC}teUTY|jUo}Y-z&Qefa>3AJ^k5i;kT74ukqv$ zY|eUko@XnT$IO#AAX#ZMs7Cj(9p}LKl<1$`k5@sya5aX3C)Y_nW@m+^N*#XM(MIdJ z*5w!q#1Rrl==bsJP}{Ce7!%|Y4i$NanT17VsEGyLtHM@ZZ-wA*j;J{AL(iga%ha2Z z-pQ8~&omZ)JkM6@8_QG;mjnNMjrljTL^uv&1#MU!%N< zO1Q(CbBRezE>LZC#bk3Lca!%ugGhq)zfUUIVCfqM<@SlI+Ef=V7k!Oehr3kwpd=pW zi3~P%n)aM!zPG>p3VN=V%HPJdy7BIP$5P%)R{Ll8JY6T0-v^LsZC~I4W*y(C z@t0>f^O5O8x_cr)fLkbVx zAGSxi-YzaBlB|uc+B1~;?r#7a0K;O@!CZ}6Cz4YS`3a)jrQ}X)G9sNF>JbSWb}a1D zdyPtO3eQ>j@RLw5OX^6gu{zK;5~Y(2qx4s2Jg_Qw|IkI-JJTe*93q!)B$RL^RvPd; zK0jhJFlf@$Oovj09sfvu+7jsc+g8REg^@P;6;@Jx=*N0MZ~(9x(yL}`7_lBh$!S{O z*R1=!%h0$rmM#%)XpNVvxsKM7=_uCxt*0^TVzl7v%KB7D_!s{DXa!eB(24 zd%|6hEd_2*xnpTT`@@z-%ik6x13!jEa6Zko#NDD_oNbP|JAPkIGV?bt)Qe7IwUbb9 zQcUtzhOYM5rY+>l8TV6P$4PWqyP$GHL2RP44>MI!>8WV(&!!R`1FTU0+1h&r@LZk% zLWk`^7874jg}-$j#iargf}3~Fw;S|lXkL547jnUPj%s4M^;%r2ZUIEcBsBbLEHcq< z!X&y)2wg!8Y?mVSRXzhh5XoP{p@#82Cys0q4f(8gsb9^7hoUUMn2$i37WD?(LWGs0 z2uUYL_=wV@daU>V$R%(HdYDR6z6RXB11pMPFsSJfTdW}t!o<>DuxjdKqV>};ZM0D9D=ScV-#j?`14!YvZQLmpZOmMc-bZHd^}*QVcx`@mysLMV(zf3 z<}P%%gZ=EAAhKDpP`}4V>fayy!!P*g>ts#oPcBG+7Ew_O#YTyPHIwIHtQKO!W&n(u z96?ly35RF~93>rnC}DL2ubkf`)e5Vkm-u3$e?ov5#9#)8)7RhVPzC@}o zG6=flU_gzGpX{cPKg{c^0FUiPKI?+wAm$=AfeSN zQ3$;Nbt{RFX!SZrXtmzzLX3x^;8NqAS<5vcO#ZoCYPaJ@UR=s3Y(o+`i>R_Bs(I~T zPbT`9fKmJ*4a1@YQbr#UxP&EC009uWNvneRHw8K4rjZL>sPxa6q7PPl$z!`Ks@iHr zj&xvx4b7x~p>0^XBZR+D8jEIHGKJwvO`X6jz=X97oM?U{o>vN>Nz-x$+%wvlvKOo} zzM}jIh6xcXuK)tr@o9(j5%4J0=B>XW%C#VE$U(H0}>qS zstkB)U*S2Mn1s!|lwCK7)zpbt4$LYR+J7dGZLpH7hxG}m!{(UtMapWwSL8{4HOnFS zDx5*-COf$bw?wWRR+Eb|GzyTdS9Q9JNfAOw2=(*=RH=1n38|vUl)On$;#U!OnVAB@ z$^(jE#`@=1vK$~ij{3m9!Z!9|t~AQ$f2`^Ec=Jc`5BxnKpjSXQL;EY%Ap)!^he`Fi zAU>7P*rrs=@v&%gao1T2M(D+q^XH7)5$hg89#i^}K1;sbGWZd7jH9{~k<~Aq?n4A7 zHoD=06B?o8I4VQW)iY2x(MN$LQ8Vgu%BCv52|4Zw!HG z#z%K>c9Vmck-IqX;}R=N@oAWUxgnl&s4;#Dk-qvx+79hMw3rBurdAbb`1$`#n|hBC z@w=aMa9CEYzq=qokN4897YRf_a&g*GpO*6{AtGDWf&W=H=`a|LaTYJx`#OW6q?rp| zU6oh9O5QuSIN#xKOI@&Bka3`1ge1KJ?1?}QosBq?wazTHEN9+)F~~mgCn=fEM=qtF zWVNS7f!u)QU+F95PlXPPMipxV0vfh~*sEs)uG- zI5Yf)gisbpoK53^;nLmSM)&LO?-l6se5UQT@+6AUq1s}=wRxVd5&3DLM($P(_{lQI zu&RNB;z)jN1o=mtmg7jb3fWEM|ClXa+E!Q1d)fs+4vVx+y;MagfF(f+IBUJ#oJ zqk))+9o>P>li*Q7+Pj@!SZ}>G(77k`U4&8YNIg@73C(~Tvp3T@J9WY4+SOkC&xEP) z$$BC{Dl^_E+zB`~w_HJ3S$F>|L>S<(1y^*caGl4I&M-Ih+RKA~a)i4QXq;wYyEtJV zUy&X0%TqVf!h(`hCS#cArIJ_6kB=qr#~EJ_7iY;VirUn8lyFAh9g5no zj&IEIere{&Hhk%4gwM39F@<~-lay@Su!?{^k5th8kI7$11t0zzqc zRQ}RIJ9Uk|A)oa$GL|wEn(`OjVKhL%yLCzHHJVMYb(*@Ct383p*J}!{uh?Q!r6x(k zWH1>L{ngOZhuaZ@ov?25_~TpArl4;WlU%6Wf6&&x=-i^?1x+lRW^{1tRY=m7>Y|A6@bL}HLWf0(ac$`1?lXU_?B(h_TiLg`Q|61A!*A8w^HcqW@o(YG zqYhMqFUR<6PfAdZcCe2?OY0ezUZS+q#<0OK)4ucDBG1W_x!#p49kyrKwq!^OWBX(X zL*8@3g&*`}ZRi$*jmP#dW?|wj?FSEtY7;J5i-sWd5tC*tc(%6)V++7~4SU7Xo`#+^Nm8Jky$ZUSZ|2 zjoR(Rl)~FP6k)<}F4}6XK=Wga`PWnd1n$)MJaxp6-3@r-a$!!&oHWvJS$S0$-vX6> zoWZqaLY?HU8-OMGIiIrAIPbdt;?~;I5N08rw8C6Xj;~o5?~{Ho*4-8|uh=um?3+d! z2~q-l9vvgJm4l@a_KE(c$XUAV{9q$&m02xH0?5*#IO$JN=AaWwR!7aj1_(Vp&ug6yMIyuSCup zL+$Z6dg_Lm4Fo)xGU6xh4h!X(t(BnWg?e32o>5koGh_dJxVXs{+?VPH9HVVb= zzrm~%N`<^nXTJ3oixE2wiy37WiRm6hwP$=QlSIp=gxW zwk+%ZOQHDNT&iVJ$Pt&%E%x&u56?FB7p?FAu2$31iFafwbfO{arD3s}IxeeO+kNU^ z=!C%SMP152Tll`xtsj%D{$Kh;({@`Nq`p)9B)?M?(5y6v0w%E#Ifs-hUfJSEfcr9j zzq*j+VuM8MvW=wN;8J&I_;*r77*Pk6vf|#rJ#mO_N(Z%S2-`yr1%8(`$EF#cc|R9T z2gtMeX{q&q&v)2g6s zj6`i2WOBAvQfWGjB*)=UX+jU{b!@xK?Uiq@+S`u-F>2!e^Yh&j#VTPA*4f7$8mk{Y zuIAokp@0E_9CgjbKuV@P&8sp=9!RfW9-!k8HYs@@I;ce@ge8{PW;UysWrM4b&)L4h zd8aSf!X=xGo^veGsr+Z8!`&Fle))n@XBGs3Qpd=oaNH`QL16ukXN`zM;h#V)t#z`^ zY)frgpl)qR`NDnwK>B|`*T0nLuOqlJ#Mzj=V#dJBn>On~dUC`Ht#zF@Sw7Ly=HA#q z4Gsa549sc<^6o7EWBeXM!0@j9hoLT2TmJljBsUfRM=TU$LAw_QK4W#29dlre-S4o&iy)ujypqM6ut;ro9aqu$5 z?$ulAk29v`v40~3Eo9jEtR$llOzqvcGoDx8+j~XhY;8l?CmzMrk#q5f>(G)00p?=` zD)XUjR>Vdbp0)DkO@d-_(wt##a8QakGr>W|&{<(~->->9dBo-&IT+j55hFZp+2KS|p|C1qnA~32L)fi|xDo%cnVX}*RHK|v-T?a4GhL+Zzm2f-n<#&Ksja8|i z@&odob!|?3f2Oj

$Q|3gpz`6VWSv5)xQjR+e7>t*jJhJR5^uFg6YmXdqh%>0^nd zPM#N2amfkg4DmIa6}kEczedt}ByU&RpMc$|#Nc(~ye+YPQ=b?tBkxKjU9d+&iA{FV zxUih5`ZDc0qBsC26H_22Nw2Ugs zvRRs0DhSmWbu{KsGC-!OfMa)yx4k0gdt$E3eZ&C8e&9DJ96axgGoW?F@II1zT4T2ZHD{Ld7JcH~abo+ppfU zogU_yGcMaW_uc9@;!iA!{>I@p+S4S&VnSZF7EJ*HZBF7f&WPk|LiLRN=IFNiK)`J@l>-Z z(;Cqyf=`@BM>#~SN_k_0nIKDU#s1oQsq zPdyFgRCB*z&Jg-5SfA<(mp;M%BonJdc8tlJP*Bv7D!U2Ah9aJZhzcB-Ad6X14~e2) zmm_AaUV{I>91ae;NO`P$JvvNFIuqLq)1@|+kve2RlFFYuYPw8OZ0VyfNOV5<%u~Lp z^nj& zx&k278{LD@F0dWb5+?1rBQ6o4s~C3(jwVqCg5hw~16}VGdw0EngY^|=aVj^3vo#61 z&==y(_m`E-*OvZL)|JYS$+)=pFPs24b^ech^gLfrIY5`1uXvM@Ej0DnW+)0 zzsq*W*@MGqK$sYcUuUHZO9Y1Dvl3JFg6nPKhcL2z{M+Sw-_7c!}CH_UPRe^CA)+Br~+A8PA@B)vo`w)z6ZiG(KObEmx0Re((3fU!aFW zjd5JJqn?6#Xsf9gEhVes12(``_QB1*=PiF@7!sQ1_eX&*X%r9AnlhIWvfT+^4N|8d zh2^!?)z8zt<18v61qLwaDWn~L)%5ucAa-=P!VXj&EXA%!sULt$rq~v_%0h~w_me&;jCQb|o zLQ`1L8cev*ajn$4$M8(*a31BMst;B$@TX=H6`r@dzYyaE1X#6nR=Uci8`I$Ux{v`@ z`}Pw4TtQJ)lrzqEH+IW~#YR`9K$q!T$pqLXX=7rV?e53EPa)7r`&YRBv5KmfTa)U` z$IjZ&lc&D=9%=iEC1s(8(-W|dU+_K`W>)>-88NtbJBYAt=|(kmTKgc`5L1DQbp#K^tsv~BUuHW|c5xtSUb zMs_KCLXKv-szfxcr9P4XLlzQAX|+LoC{# zy9+1i5lOM&XmNCoG2pkJQ`z((p%M=}2qKAO*gAzBrXg3vvJ= zjvv|xuP=b9YtI&L8t=1h0$Ac4d3_un9X=$`3Ray1l0HWsni&6kum3K?q-;KRd^kx^ ze>kD`NMJp>aGckq*?h5g`(7+w?!K|P%Pb+UYn^Xow?A8jZw#x zqp=7xYbQIYO@{n?9bLbupQoPoiA+>R$rj0>_&DyZ-fJbqPC=&v}FGv{gk# z1#Y|GWI)V(t-8-OBHZE%iJoXirD^vC0(m!E;?zie%J3R)xf_v*6EEO{jKnV@!Rg8b znq>*KB@m7aw${x`cAS%6kjFl4&b~w&;8E!R+7=~ILS#;(j{Tpq<>ARZ^pzR)WVtGX zh5=>wCD%}WC6Vm(R|WiIS^6Y0L2I|;o<{3NxOgd>k4JBxI2{&g zm`rp{*8qK;K8FGA@#bj60{A!lRsalOgU7b+hPCSXCTVp!G_Y})sKg#Y@jUj`AHy!utnM&hm35mId zVoeBr+W7MB`D#L+HzzKJDY9Y;z6QVq(`o=roTzijXhP33z7g0olEdJ<-kR%n>3N{W zY&72)Pq&iU?om)0FUPgOBeHe3s2AZCACH-e*cx<`DO&R%a=oaDk!+G;akN-9$MrW_ z(PvNJ9LqPRk@NIV1Ur6UwvcbpO(X49I3xO3=8U{OGNBQ`y7;4#q5CRyK_ z_(ZJo#FRby!vPwe*P7y5hTC&8sUP_wqE{LFXKTW*e4itc9M!=vfBOx66dFqDB-~Rl z_KNda(N2@TWQaSic`5Mc;qHJ)oxc3=i9OGT>fJm>GHkf5N8#~$H6WnoMI zk)Zsg5!(l>$O-0b0;Kv?I1Z_|xWv{zG*==uVAF?o|7C9h)@cs~v*` zw2m;{RsGc2ICheZZeJE0tiCVA!BLOk$h zE44oPLdw|BM(~SwWeR4A21CUJ)v-Nn?|XN+Sz>oHJ2o>#w^eqTyB6NMY1RJrPI7PJ zPzi`(mQS;}Kb#Re1slyg_>^Np-5XtyO(#)6 z#06;tm#-TCZ`QtDyz@E9qEEp{%iHzLJ+uLX{G;RA4M-~0 z0$zVg;DmXi6+KsSCl2UQOS^3`DYvzHPr0#gc**H>dc9hm)G2j$dcQcg$Xw3R zR6G|I#V_cgcGRXF%qhLmP68pfMXeYHk(zuLWcM}6x3=xp8@z4Xn7%|z*1Bs#S z8n=QekCA_+?sT~hul;fE?BcMsFjQ8Y(pvb|7&QI6oflrZsJalJfjROUx%W~kyV5JaF16NCO+G@ z{H`6Y%}uTx*h6`2Z%07|=*Dl3^jdS^u)?>Dw!06Nxy6@(($W(k4oZqn5cel?F~Y!& z&ddxd=;)6!Z^7B?&E+8|9W1no4oVvK8WNrf7+)~RV93RBwSRmeLqs%z07)DU%``o6 z?yoj0?9Z1x9m+elE!;e|`FPm(oTZ<)0Dq_Ccv@D=|8bMjRWUr6)88KckAljgt&m5X zd2L8@Ug=n(CR~LewmmVo;8K_ql8H(_#?8V(vGJsj{~VKm3JdFbL+_ zk6?_^B3n76o!jk-RQYJIQ)4kv^#ex@D_xwC(+7hF4Iok>L9EEMTd`MN!RA3RRsK?P z3g%*UQL!Wm)m18g8ASsEwWxn|8#GCn0Zd377`Lxu_!u)3n>rEsZTpFciEG14DJx1R zc7V5gE8}JJ_k>?&PK06C1AZ9V@I(?bf~J!WIoHEZO)QiP47!CDn_fTo?`;^u#rDkt zTc_H(3#OEL8C)=85M`j&I@SWW(fDbl$&6uS$snu~K+FJHxU0ZE zY>LhxN_w9N&u4L~y`(n=DTh@=V4F*lLDb4-V?A8?g}XqSc*&T^+3V980s`hS9Ph&r z+a}TLCTV*>*dLa69#G9%J0japhk$Jl=G$u_f+m2QD#D+#2lC9`0IlLrP!P0 zEjYV=oHH*1PKWLRo?F4xofqMB+I)pXL3U&EG~i{>wjX-z@_aFUhdyj3z@TY5$orUM zL3_|fG5lZSu8GNGb40B%t$;?J@E;tf1#dgH+gYZJ9tZa z>bUTeBR|P$@VxYNy7&1}?TvkVQ(L{`zU+Mn%=W@xl^P64FCU zOAjz~Bi)E}hjd6cN=tXAba!`mw{&-dbezref8X=zeB%pi&6>UEzOU<-LWUV1TnC5` zS!g@cFm>7F);m;EgVySGhzsD&)0o4aX=Qpaw0~kSVRrflMWJ}T*N;vtSdf(bO?CS1 zDGQEfUXk-IsRtCCM9I7zJQ6rj!f)R2!9PKAn=(H%7)rUY&ru{jK$l4jKUo#<=qk%m z_o*)j{N^sX0NNyz0Wrp=(>JzqeKCV*S6h++YD2AhyDqHQwcU;GZYz9EvlKCh1mb~P zntH|U6j4jV@jSj=e?m=@aWhbp2Oy@HBVI}$vqjd;^e5s*mW%9lh#O)~)aG$McT%m{ zv^?$^tgt^aMyFyq6{(Do>2Ih!fP}M{+Bhgsi83nlSY^%WOZg&pipok5^R{sEBEKW2 z`JXxK!eN2fYWGYf6w50DFAN#qom8+UCx|84G@ILg0e;KjG?#iypKB07WJ#EJdWfkS zJDVn_^azK6JC%CWRQd1E=lRzxF4^;S-w5VU(UUz(pBUAv5LBbJI~>vYt~uD#&M!X^ z0a_cM-Cg~OY0SSy%;JQ$9|;{M2!JZ2RbSDw-gbVS_a;Xx_S?mpa$NP{#4i~@TfxRQ zg6!DjA$+?J{l`YDIC+f0^2fF%vWiwIkaQ+8{)H^qxWv3-iKmG+r^{86F89AL`rrtZ3oyV~%T`P^)PCzpkxQYC4-5NEqNh8E>Db|J-{0NL`$+(J|am{NCMSv~T$?HB(y%Y8N%~5kUY8cstIi!WQzZ=szIf`PaWATg}CFm%EMrjdkC(-w#v^S$$mI zP{Yo`${Qh{=e8dQh&`_*InO(uT`WXdUWm>(p-g%Di_2eFdCxntgI)##Yg=25OBC^} zUhk5|J;Lg_mz~#eQoptRqV~h|kEJQWY7Zo=67bk2&xeuKd%cL@pw!SSgP#PEMz)Fp zmUP`+=l9|GY)JK)PgtoAQ z#=K6-p?^$3M(wEJ>V$aUJa(mIe$YZs(z@tV4|Z;4P9K@` zaStr4dXS>1aTO^4+s?1)tRlQPpamw%;RFkt?7+ZCE?15HvyR4&aNoj=ZT>{buS9C8 z-YvEoiQY6HX2gpyAl(CkjEV0>+4lP&^hqk1(AkfWNsRs6mYU!ZEF5nBFR0@v25Cp` zokX`kPX59mfvHA(~mIrXFh7z)Ncn%TR86OKTgh>%Ir4g(y8y7g@;M~CoB@MaSQ zRZ+;(#%-!TyW4ouq$*E_y04$Q#1HwQ3;itPuu2kJbW~(UsogQWdB19J$u&_C&mRWp zvAHaLdj5B9RsS5=F{Sf*UVbHf$FP_l=exydJKM)u#g9_)pJX|Js8ua|&Tz^;1cG0~0PX!=oitp33sZ%QufOIj~yXlP6O>AZU*YuxW zl-BA^xT?d0xF2O%W>^c+yQ}KL2Gm_8~y?TxVl>JA?T_h;woNmJbR&N*(STm4&y36 zjV{wN<^AesI(C@sle>^pGf5rFvPqcAYJ97s$vyM)WYNGp zG`KotLmUfQ|5>fdp3nI?JiIX75YPb(BD$54GWt{ye;@L+9?PSIV!|9Xt<1?)$`H)I zK&k)=u{ZaUL8U^2r3Nyyb2KOd9$I*CCXxD=Y0PJ3Ur9@~w61R?lgKDkaqxEHcDcc$ zY6Q`WwO_Uzx%)gp$3e7%A7WxZsp^dchrotz2Na1CsAJ~=2C7tNvR*Hh{0>h3uT+0z zky)Wt{YT9I2C`Xdw6B80LDp8H>q)|~NLB?yR#@t?#=yO*NbuDCdap%GO$SG^OIM#j zKk5H|4mF%6mfUk!3bv-cmRZ%1I#CjK%tb>3I9%T4&f7u9}@RKx#y?AIt4H;ZAAP z$KiAVABhr4gCG_ZsnrvwHs(vyktnf?@5?l+Pd$<~Nab6(wFF_$Xn$OBJl{aeK>c~w zEn4CBuec@Hc&krk`Se5wF0w=-+{&yZJC5i2lsfsF%R%n!#9~t~bm~={>M8=s^L|nT z#_nDN_VU)mR28+BZEskG$Nh)U=AHOvz*PK1{ItV_)>UH`gSUl%z?$2(Saes4-ufkM zb^00z2;gYbwIV3v#{ZC@?G)zEW0JQ*Lo;d$&Mn2KoHbfsw6O6`V$FvtHO@i&nhbe9 zv60RAc~kuwNNo*V>VkKNssg^oY@JH-eDE1B*Q!LAXAN8Ycb5qQqs8^}SKkK(C}NVa%4FVB2fDaaKKjyj zt|H~hp5sfG8-mW zzbA{EbaJ6nX&G7iG<1SqI7XafIF_pZ^ior6F@HhJswuwbdbPX028fXV=E?4Q^B*i$ z=wm)&)PJeVg~%pOQ1suN@T3(1MGBoy_wF5-^7PI_7R=o%)?L{+qvgq?-9VD;?e59m zHCHcMMA5qYD1NoIc1>D70|Ac{r0)P(#}zw*C;2+JR9v;pqqhtGS*G%g7zm}z4H^oX=huIts(O6xFl zX>;@RAO}k>^7aaRF8*P)QQux(_kgF^C0{`+?k)4hBFCJtyhTJgxBb1(`>P9*np8ww zt#gv3C3c`1`#NHO>_2*iGV*MGBhX5oF{rKswnnjkHvVB(Zw#ngSnpI9Gso|X|iU3>FBs`nUq zJt3WWEF&VUHd5$niiYA|b{1R<#l*iXP(N2XC8@e>vl(ASV_s3WmymH|KQ*n9tWJ_7 zrQtHU4kFU0unDMH)#<}rJEcgnrn^XLH2QCaFuEGYC91E8ehF_t80YLrM0q+NlI-w1 zQPj!lE~g8x+~Q6lJcyW#qsk{(vlmN@%I+8OES5r7G!y3*V=bc;;|S{Gi#OJC<4cmy zLUPZ!I$Av2=)IWqMJL>U5QIp`WSz`C2~ws^LXblWQK^SZE_gYi!MO(=@b?Z2BsUN< zv4bB~VHTqctPPo;I2||q9*UI9<7JE$Yf~ZF9#cJ_(&dX;+xK3P;c;~H=NSw!dlb(( z!%d*Kx2GocU8Lhu-N_Fs1taa!-1`Sr3o$gGR!Ajw#%I|O60_a0G%Mapk?$8yHC0o@ zcApokIyoN=1O{=Ms1|}MZ*EZGg_nw^be|@A(%>)?mIn5Q1?TubOFiul3m4Xuw8Tn% zW+=oxmEvP!D1>d#)xf9R0hwM4aXCHc;;zOo5lp@S*vV8u4UUnu&Mitn7n=s~eHep1 z!8_u1I#$IbcwzQsWT)9Spf= zb%$y@de2;@55`M7Lo`vciToa4FLd9(7#peDeatTLnvBhMHKnDq~ z#Grf3d-D^?E(hn$c1zKY0cOL&8XPKKbD({2{-r86O(0Zxg+g%=9MW71T%unILB>Y-z!BtC)_xZ`-q;@}k2 zLWN{gnr~eM6-ZzOCeKJVb~-`FFGjxJUaXO9|IH!?^_}m{6XTkplU9Lx2tnij*(^$2 zA_;m<=Y};5UpF+=BlGP(+wIx1-5QWM|8of=mdQ9NpIPQ<5Xmg>r&RDqNAVaLr2F+e z$&egJ;b|xJi%lmoN>?&_tFhptB>bik#B&`|U@c~t4u|-Q}zonC{d4f`rotRlVqA#{>5C1R= zC`(X6;lorL@V5Lmuqlb{99gjEmq}y8Wv{pPnG0(m!qgvx@GeQeOH+sSTCk@Ple0{^ zF-I;$-v2>;4DGK^1dSN-s?Ku^i+7a89U|M|=Li+x*Rx{^CL%JHPFxWSGj>l!qg$d0 z{SHY~i#arAgOft8Rx{56)+?z>t*j1-T4EYs%@SrXQH;k*j?-PB&`^x#^@{&bW8U>5 zR)UuJcSD%DLas_J#Kp@b7Xd%(N010K_F!p|wla6)bHIJ59g$?Wo$r>-Ay(kXfp@3K z$!@0LLSZ<(H-cv5Q?sJ#VW99bc4IgG+JWNPOz(nxdv657V5HP$*>;=mz%=m7A{Uvn zWC?0ccFYSvkzX#VG=7>4#p$(2e%K%;#!6x#QTgo$N4{R096K-T z9i=cy$**Sas$=&R`yXZ`jtPZ|frl-1!{xsi!#_YZY9G4B3UX3{8^UQz3j(r0YRo;w z`!@baHGsMfjaA>N3D?z+jle}uF;>WzVB}OO?5Z!dL!DBFmEFVkLYdxO+O`WGfK7sRn|wE?7pwJ%=t*UdXh9XgW~tc-R`Io-L`q~rXTi8!S@p}KmJ&=TDl(UfZA{MCwR>XE!|J`L9Ol| zLK8VroLa77GsNZ6V48KbI~OLaaReV9lqaU^VEV>*-f?r3`-aPw>pgb=aos2h#_WE_h z?q)A>nydBYrC6`8(&Wd(KXETO&nsOck_Vk6glg0meBCV$UKc)@pVb%D|29(ehZOgz ziAy6^P-9Sakh=pSz+Q};SjplMfhTmt0g9|J0=h3e$Rr$iVzO&6POX=O5H^nPeRcOQ z{QuoV2=^lg}P025T8BMasNSu{f^QEuM_k`BlXSR)zb=>+YSFjn?B0*@v@H>F|4*G zhu~6EoS@gu@gnMyt{Wj0kqe=<{VJknMhpD22i;MOm((edCJhzlgTh0LK26^tGpOFB zL|niG*2`MUiTvS)k#Ws0Rj&3q$Saz!TP)PCbez5y#QQNIA`M|FS6#U~-ZL+f+oH4HW4|88<^24#zt<{C%&O5- zY}1aKMugKi!m-m+XImQa^$BdE72iIw?&ptPY()?dX;qXZ82kzD8q=iGJEq{j%`H=SeBF^A z3xt1InD7yQHY<#L*cfR{yC?#mxTM_7#P#``?cTtG^_f9pqKcMju;76c3BgHc;?Ts@LJ%g zzJg5DrAai)$8K%8bW$?TNEDQRIB8H8Y&mHMy6y1ghSI+5hmW0t03uaGUrAhRp7YyV z>PLdJrBj3lB71%6IMLk2H)>0r^WTyJD^Mx7ZlHJNY*yoXO*=x2Ho8KIk6bG^EM@c= z&bW{;Q=ht8?FpVUV^jPkSfZ5XKlbCm3E&8FI6e&6rI7`DII%k1IDDBtr!vi0LtY_w z`{OLm0ZNrQo&t`~EuF)QMbXzcvM><{JJlZM(NkMD z>1W-(`qDR-KR~jjN$_Aeou*~|bQ}pf9FPC*oq_HwmT)kxUCeDO9Q6d7`jN#8l_27| z*8d^qsi)1V`z4hVd2tujx2%oWkm+HrRg>xZkNojofX;s3ZBSJP&&0UZ%EY`K>osXu zvrcEC8Ibfs`egYt-jaoRuFna+4vBDj zTNLy<4R{vyI(3AJ%rG+Pw+vmv>&~ohB?yoOdpSYB_;R&q?|%{y|D#(fv}|4FrQ=%} z>P05+$-rsmuia>YVuyG4_r*iCK=a}6pr^qJRp`OE6MmpjlhWOCV++ABLpr!lU~v2w z4`D`Fb}UrePH{)8T4CM;P1Kr=+0!Kxv}GixH|5WidoWDq>;n5Wk3cCJoS=TT88)7& zMvIHBWK9{Uv8@FWf=>fIL|BxulhX*Kf8z)Ihywy>x8x6CT9{<^RDJQxzp2Kok@ls% zWl$F_5E?8OF5~%Ba#_uLR}`AK;oY*K$6$)tw@&K~xhS<1c{CIs8l^_}Y>+$oPV>9- z%cQcy#IL&ITCO!wHq^jk2G%k4CfVpHdhJIPRNs=vS4tU>@f;H>6pq@;xU68Y-@#(%Ba}0dm4pfUCCUr=>#4xX5Pg?_@4!N2bRuKjq z?(>AhPCbtJK;kAkM)0jCTaN=kX8;!i_HV4E;UTs8m6ZUW zY^E1$t&4fiOT$cbXE#O@4{PqwWs{tu&PAIx)RmNT67_WycNdE?^CV=A3Oy#y$K$si zfwm0fg6XN2yHfE7+CichyOVw)oLs_5RiUKD6bI%qoKYYeL#wcNnC4D4rNJm4@+1{{ z3?ZRI@gg^dbtc1`?N_1&LfwMn#z)^{>vuWJE*FA@jnQN9`r8u36iK7KB9xcS+}6sw zbhD#UF#AZm2Ss+ddgZ9P24edlLFH~5hI-rqFaFkt8xuQ5yt3GdEav%R$=xx=z$xi} zvQ!tqanXX|56NO}cJAhi+5qkrBCtV%v;~0qF^U zy;&N$@xI(RI6H1wiC`YHn};%IR%CpK{#3zLzhDF%rf@n8k(-j0j#2pK=8x%~KC9kj7(WQ?|NZ^Uhju%yM}$c|534|@##f!Zb}tJ+m3~nELRM?h zlh(#j_2c_lXLSvY4dP1vd|#`ZtH5RH=ur9FJACiP%sEwMmtQ$$H{Tw_8V2V*cv9S{ z!C;g?K`GXq+Q*5K*At0P|8brn%7F;j5z7LSM+QG$*yA?lb&Bk>&=fWx)7R26aTNwX zAV%8mVUjYpRWkj?mCO)vi%#$|1s{BU@SiA{)7$oyWMabi%Ec8TDIhi*5FAw))Z*mc%jCWfQ~*MZ@hLJc}K>Gx1ML zn)2BAGU`xqWilKSt=6tC06-tw5A~jErABDCJ_By*7XEz!%G4(b09e+N35_!CQa=W7 z(t$o0i|EA-lRp2>zfDc*p2H(BR0yDmdmk1!LzBZLUViA`Oi1%V^uD23M8IF_Lvn$5 zM#vnt`eO%fyXaN%=Nk#HH^Y+Xg;l{KGuDG(Us`zv1oYSG^EuhGS&lT`j|Wal!DDTw z!q}HM&`RL zB)$s0^$vM#$+$L2N$~3D&aBzC`xgQbv#S@-@o+jm_vLh z`}QJwT&}rf(`05kXq;Hk#qzMsDO(K89#%62Dv1m+%lOIBgqc2{A4J&p{kUS%`o5?( zKsWnQ{H*0qcQ_s$!w^ABNYD^I4H1l_N4$lkcA}Fh*o?*e4?mrA?YdHT--CW8#>Eoo zQSr%Wr(UNa1XScfYeDjDHOs)X0G282jzMgVN`sV#y720|XV$Mpx>##epN(PD3;aC_b z8K%N*)f))1(azGIVog$!@&h8MgUTVOznQtBTVmL7$n^f4?zF+mWADWWPz&MqzQ}b~Z5Bjr{Y+G~qGr#k1z%>iNqo*C|XF9?Gmq@pn~`K=N=DE z7{aAp9A56I2>!~V{_y%Z0whBvj$97f{FC-@ou-?Wz=Fq=x^L7;05sE7hFDV@XriYa zjulI7nENKsXWaFEVx5tRs+d~*4a`1N*W!{5yDKHEe~za2BIi626&!lBhG*>v4SJse z1%tI3u^abWR>)9*zNno_{V_B733a@br%FS%grXMRFfh8XeGT!`;`Xk*oX^*ji2MD2 zT*VRiIv$>pF=xu?F<4)0due56Bxd2?R1LxFSRa|%qeNKG|HqSfe)K8M0JT&`Bu^XY z0Qr>JnQR`P@eQh3Fxee2E>_YWD zrkkR^ieI_R9%NRFDzjUO0EoM*9?H`cElI>=N!|k{z_sZhUtbZ&H_XyKJb? z^9%8aUd5YK)K=S;%PjHR&k16ZJk~_cB`ct=XJ`ybUqoRsD%^G}L7kosQeUa7B8^U4 zZMRpM^cf|>%7yZI6tC?GXVCnsuGPm;z)zRaE6I zPxh4e%oteCeGB{?YIQBdBI$Y&oseoo7otSlUpr14REVqNq4ljvtGgUd$&9C%OxO0+ z@D)n)hjV(0dQat5_9u?PUUZ6nN81v7?s%geRn{_3&}(qD)RmbSlEnpzunFO#T2z=P z=pcmrn+g_rT8e8lZiYn`+WDX#8g?Arr%P{%nToov_#7wpM3*Ddj+A$$478Y~aZeA8 zn6jRg2UhfpLpk!{J*HDrP$)V!5X%V>I=#m*dLTzV~Cgs=q?uB%Wc{S_P4+DDoepzYO37VLQ-(ibwj6`2_ zr{B9HvcAnDGer8lboDKXg8F*)RfK48C^dDL!JmeDb|`?k1j@|Y1;ZF9K*)hPGIQsd znOvGCg2?e#rfwJc#KMWhRRXBCHt_owBU7dUALRKzr)F7xES^qNugIqOrz_$PPSe|!{N51G*D~ic*w=^hz0MX_dwqcDb2-wCcnhMZ3sO_(v^S<0 z&yha)F9P}Xx&0Nj{b}dcNC}9&q4&5-c|{hu>zsd6d*kMpX^ACOK#1i<1RS_5{2A@oeb zZlAAX0)S>8gl9!%f&k$?)wqg3xt5;(|4~8t$}UM#@n3)Z2;Up>v3{I4!?A?|Oh1Htj-&7v>~2UXxttoBIE=09^Z^ z@N4oRXgCqPkd89WEj1@(7B@A*c=;4|JUN~dqc?fLI^grr+onv=@-H4_^ofzzK?Wqw zD?kmIOEf}Fw8?y#)7@l*7s?wAlJk|QRJhvi`_4dAGtiHgfeetyC=FyM=4B6~HZKUO zy3f)&h)!p%!wr@Ze8!b!^E#UFDI8lk)h>yWf^uT1iI#WwhsEXHRo^4v*}1&mmzHYU zVr-CUg|Q0s-M+ZM_)f;-GS~T-b2>uJ z<#7)tu6_%Ve@sF9FF+R;CuEt;GlWtt+ZGzIx8pA}Y zV0o_Zh`hJUA>l!}ZH;YX$!xwCW^_VCf5K#Zp(tV6?v&Z({r*;FsB!rr5iHM&nW$uC zn0H?tYW`iTT;oOmxfSG_PB(D|-!#5M@-vH3Ccdx=LPzSl8LCFgK13AUscdZ-kEvbT1R)uW#KK=t2~xDpU#~Z(_y(}JUO{3= z#nE5Rk9r5hk{4p{pz|+wQnf7sRpM^UwbcQ zxo}}KA$j?mH1Z+iuw2QSXVH>`@|cP7<_#+ANr-3ws;K*D+ML{b2?g9QbYuGq;g}|n zk^zCM?swyfyNSWFS^bw;%O^FOFJlKb)A0@S zSw_a@e{;h>pih{7EZd5AH|}}8_jrz%-L7vxfr)znAKJ!8ISYK&?E+v{Pw?X+n z&=ZO`tv8uP4s<>-B8Qmu;>&iN)GZ+}J_2 zo503?z%_M3s6;Lv?#DXrL2WJRMq*tg9**Ec%9ROTQeywTpI(;NO29!PNarL5C(m~;j(ftOIj zTb#1y!y?^Gd4Y{m<)07JAM_utXFnLJa43~p zSiZw&Md`3jQ>|m5gb6tE(wA|CR4#jxf(+^+Hn|8DrVN-Hj4ET|K^SCLsNewwG=vq& z$gTvl<9WTD?6*3qtce=_NVnotxzOrF6pSxr10D#YhuOhAu(|(I#N1+K@=xLR#(|B)LT8KfG}&p+iJ(1}VjqeU7-(RKaBURz@oA%3J-4>6xVu=u+L< ze#CxQc!^G*!E$TvE>WQOOhx<(1Cm#agtKc z(&_O*$r!4NRQs`evU1q0!G_)t+)IkUUNMvTmxAR7YUyPML4Qro9{akC0ohC4-N39P ztbV}QK&SQdxm+JG%$%Qh%Xg$XGk#Y+cy_MIGJkpEbEWH#k>~fOj(<(e4QSX3~(!Ln!wY$E(A3oNo@)hcq`0a70z>N67{-zx~Khk~m?$6m$TaUON zTy($NfbS$&Yv8D3GkhA>eSx&>@!9k$|M?jnV!HjIOU7mzY?p9eUQ5bhOfT4JY z^2n~ue_+CAge1bX=WO&awr{4c; z`|h9eBpyd3m)}`?M9tX!2q~$mN`3tS{wgeg9 z!7}0b0Eubk^#M-*Snr(=9R!XL zvGU{}iRDMGyWCMfysX#*=x>_OQqob1g)w%|jzvh(id>|Yvb((}Fi;7S`Gql21(s%z zpVti+VB;qdQyU9k0K>ZY;{2e8a*f_#+MQ_gAQ^&>`EGdVLQjD!NzZ}OFb7Z?B7|6m zJ^dc02}In58XAg9)V~gA<#pS9UDQD*UalY`!QW8_jL?O(07664`!z`TWIf!|-y4Y< zXvXUO+`vi>4Z{;48Y7D+)iZ0-li_-Xr<`~P*%3<6t9*j8;VHTf^!UUE0;i>=31X_= zWLllHJ+556W%>%Z6m!s0;|<628Ix`#spQiG+G(Ixl$24k?%2kU(Ka_b8#7NP3D!xN z8|xzlP)aSxxu5y$()+jldFlQzO$hTRP1IHg3;~#b zEW~v%aU2sjAvi>1#iMQiN;5iae!3GW9H-g#@u(k@1|FlmEi@im1Ok4*LPO9p6ueri z>LyZ*Noi8Q=EYRL+q4}`(%H}NL}e2qQ9N}_T3JW$H3tj@RojDSHeOc(wjbtb&gEaP zE2Hxu>CxfhB%T;LUalxM84tNkp24bHvky7ylLo9ox8`xKO|2S-1a6VuC7udQ7b$VL zvf$Yd&iIV9o#kS{QVe?Deng#F7*1SJH9g>SD$IGg>HKBIz?Q2xrI%@doFkX2EKmIlq%Iee~ zscxyypySCVKGI4Kdh)HA;HC^NF>!W0(R@i zBj#H%F6JJafQRu-%{yXCRJhZlfWS$GQV1^41$$x|*&PF7+pHj({7f9yXr7E`9K&&F z>Nblzc*x#CKB9ry(>kn%8soz+iUpG8NhAo}TIxxJr&|Vy&q&~Mz*imU@_Z6#2wTb5 zKbR7id`}{#A_Fxy5${sNrlYC~kt@-ep7MxBt=dX743F&P6uSL>ch|obQT&tYBL2sJ zK0cSNv>#Wa&Ru}}%CirjN7|9cXUM1o&G`IAR}K%`Q5*Y06B*w$M7S!5%9FAA*j&d7 zD7MiGak4Spmu4#6R94X!ipp3A;G|d){FNO`ymGkM5e~XJN|Fm{aOTn z39b8VB)1%Q|CNw+wS@Q&w#f*{3(VwF_hmjEQ2`ZmmQ*R0^y(ojw5gJs8pS>sJMpWxT(Z$Wkl%SUC044d79# z2;U0l!7z2iBdRG1{hxx`3x4)+wp>V4lSgiW&j;<5gBug$QeUKyNF~I=<{Pb2@~5af zv8Fjt=Ivq_h?!6+7QE$Y7kb z5~^i=Y3ADy9RHI@uS=s_{eLE;1=YDc5wF4tj}vB@Roz7=4^*(nrDI#HKv=$4AN_0rmH)_{bjs zQP@E?0&Wu~vnbQdLU|X0IACwzRP{wSFHVyICO&kG?BHg##~w?a7GO`E93VtewxxzE zWIBcIS%RO^0{V5{jy*^cbwp3#0V-3&cZI1qB|V3Ekr~=0338;UaMl>3*d7Y;&|zhk zzPMD(JV9HI0F~4~d^MY)Ha8QZoBn*gKnZ9Y6)Y@!LbspeoPc$NtbeLqA_mdtKt_^F z&+l`@G}Pgf12nyv%gv~TJjIjQFmGqtU6$$g_K+|~Vl8NJ38iArbZ$+qOOThUYS;(vFqYBUKQh&?yU`0aE zFCH37FCP9RmM4JZgGV*a#`A!YH{oeYgW0ZikqQ3`CG=)#P-6`gUO13c!9Bj$t4(yd z^m`O3f=JnN7jkn1_Hq^b^sgxivmF~b&a4^LPnK^w4j+=uPSlNwZMG)k+WSq%E*4pt zIDV|$HB%-$feWjp;DJV{m-)<#VI~phB5l$FgmA zoXa+0AcP^On)5CJTP}W*mK8~k+oe}s@55XQ$=m|!@LmK!cXrwR0h@k=!8CynntI-nlA zJ}{MR-{$rn(f_zRHwN72f5G;<4rRQcuYhTOF9K>b-P6QU%1SPp7iWF%XQ#=WPhlvB4pEILCcF5nz*#im9Py%WD1fA=jP)Pzbxwhu6!m`PbXO`aXzkk5tAR;gg@%)UbiRMp_sT$xdSqqb z`G=FDp;HtzJO%%(X-n0j*vp|F>-70kIKu1~cgrZM1VV{!&fwzI!2zPi=mqL7aVD`Q z6$hQ1(sTzhG+RqCuVU^b#cO^b`U9G2taViSw++D7st~7zjHT7gCX5Y~J8J7D=+1q?chs-`w7Dnkd6b;~Y|oTLE1)At6n4f48NF57 z=ZKsjW*(uaZzfAqj}!ZRiq{Da6Cz?BEMJCVVsIr-DA{$+iplwfHMYWhTHv2jABg4UT4m}VmTf9{zXG{806=4{*Pb^2-O2V(SQGcVvqO9Gm zqF2lKIGDy9hb-ML|8KB(=TfT2nBj^URA+MFo9xoBP8QS_;sZN8d15H4C-POwcG}po z`TP4Jvyo}NXvUK7E7uov1cl%#A*g9U0WA^@y?O1OHw}5hiTv81gLGc}Cz*tnCx8M_ z=|)bJXo$YqAE{40`lP?I+2(&eR$`y93%hg(WgXlimpnHhhM`_4>l`pX$h%-Q{!7vB zpfiMR2g?-Xe6#)S*G4HmGlBK&Z!@GXWqoMwPE;W?Ai(Y*4Ag}u3c{z~ZM0e0jNfn@ z28O16Vr_!}F>!rXk;D4`9Q7b2r~(B2xkyR73LOGB9k{G6z z`PE8pv=EatR$MoZYco@MQS!7N#k76B|MUqO9;4L~m!kX(0ED(l2W}gxS7~LPSdC2Z z({&}wW`LGq@{a!1Hpv&ae&fcA+e!1JgQ1URq;sHTnd^Zd2@b}0K=4E^^*g03^TbZ? z7adJP#O@Pz^-nw-oZ1nUMuaAip( zT9xIBM=*1Ob1Vw$yZrsR;x<2?$Zu2jm+R}X(b$@hYzInVy%Z4B213J=N1ggTe&qZs zhSE3kJMl(G$H+1-Mdk7x_ur;YdWN%}g&^Zzb?UaQ5g7zhsJr&ooWIqDUj!POuzV?n z()bb#5Tcdk&TG~xsmq36K2_FT4kaa)U4jfPTth2cVSV2_ZH}~W%G^L{%Fi_h0yC_Z zR^(M*xu69Ynjb-OFht&yo9bv`@6&Z*_0EAg{LkZwS_8>9mQ8UmS9%!#us+%PzOzn1+ z@5>cjO#t2-$EzfZRAnZ^?8{CWAfU|r z^FHtCPn+pQGZsn7$$^WRDUe{Oqapl= z#i= zjCVE4hN>piH7DjM{hv^ns=sId4UY<-WJ4au=R!=Z;2R2YxO41f zmT9l~LMi@W=wP<}(YR+|WnzqKyTW(PFos|4cR>v~QFf4SkYaD%!98Sa>S)m8*mslo z;Hl{*h859@kc1B;H{v?z(G5^92ODdV7Z^dYdmHnf1jm zb^M+JGG5ad*=JD#ow4L=od;n6)$mJ8w8ElT>(y$Ox2(lNhU!ShkZI^W7|kW}?j-Hp<%c@TZD-O4t!MVl>@) zCZ0_;U9hFv-#$YfEk4~5fiF6?^cT)o5^pQ7&;m9LsXFSgBRckz-1P7q*EG>$Ve1D{qqL z1j7I#oq@>n9a-0rLHygDZLBFQH8`$Ch4C za)}Ndl@kyH3QJF8nk8P3YnO$WE<>>0qSk`drObl2C#%6REQrff-c<9EY?b!9Bk}L! zk5nhCHQ23PlFf&|ZN5wL-0Pe@PTjlIFVIS;?kNXfHum}g%L2_l$c9>}Nwp<4tbFQA zVX_8lC&MK=`vQN^(?bmPG5Z*v*}^T6^$OU+Vc|SlL~eT=iqkyS=zGn;yXh;fD92%_;B|4TiF1v7!l=#cC%>!nb6Xe4Z zVI$PciNF3>;r}15-YP1tu8G=BfZ!6`AwdHKXxuFX*Wm8%F2OyxySux)LvRc3H16(l zHt%=-^N(?E`l3f)_1L>st*SYnc|eibV0xSnbM!IrNBZ^@ierlc(j3%qmm4?R(M4RL=V=ED5Q++J`)Jafesl7>13g9UbjM-P-e4WlrMicCfelOIl~X8Ln*IRkl)-9m&rG5uQ23 zCp;hvl1E+`k6tmXt|Jq!$2lGdk42wHhSk<$l$Mm=S%o{)`>Sg(gv+f{6ZqMcwJ1yT zTM2Wt&Q+&Q*Y@@!9s_g6L#O#^rz+Ar3n(r=r|u~hjJ$Q#)&=XF`4gi7RMu`O+ey5~ z8dIP2k@36R9M+{7rQXie0$wLV)haITQKzg{XLQ9cW zcg{IxXR>uwUF=idioo1zUnv|{BDZOG@e=vihVfW!S$urtzSAk*&HJdVJEfBukQGs}TNCdu0~0 zKRdyL)Tni7-&<2ZyM4Glb1Tf@Y~RCtkF3fBN~P;dFV4 z{PKedPXO3XwiN3<#K(qE<{-nAdCB;Vc@h0<719e%3yt`2mKCvV7C|LGM9k;k>Jnl9 zHL$;hE+N&t%8RL7h>J$i4gTaEH3w=h_RPbe<%*ROOv08R3L9pS%?^h4{jHm@h}Y8w zo5h(UD(Dc|vL<6}M*V)CcwKjReo zg8wq$bQqkbhv&$L4u}UNVdD1TEm&A3By|+{6%8W$bZ8j4Bf24uP^1P-LAiqwU(t2; z5|ntaU=XTRDfJQbjXzPe9|?Nt^_0eqjqp$zRh62jBw3n(qiL8o9Pq?T80E*K`9m@Ba9%ch?qc^q5F;{-q6 z-b><&39fM#YNxI6^#io??}{x^V(0g5fvsw|`wmV~B5#y!p>C~~%al!aH=yz&t@SDX z4v7JF$ked=o1-!q=zNG=@Dl=CRFsiKy_kWe&KrMlR05-@n~c>0gB1to1LOg^vDJ6V z(rKL-b*w_>0}}K`X&nV@PwY=fm-_DBMw*rRKl zjD?Uz^hEiP=vZxGWvak2L<>wD$v{9rF^!2sG>NMxdv3B)5*V$GHAo(~%!3^G| zY_2)976iN)QL!d@Q9ol~`{&WXG2zEv#lqHa`D|*e_u+b7S`)c3!r~+RZU=67d;t9ef}qqhGKSGIC2>CG070zIP??jh6*sG3b~=W}^((7@pf zWrO<_+L`Zs6I^&i)&b8qw`#PNS&5Z+ea$uW#NJ<;TZeTnqyiG607X zj?O;xgRKbR!tDHE^f9)%`3qPYT)3+)7BKY<|7RHWDamDy!l)5o%wUN6Tf(UXiN-i9 z7QT`OLdKP*sG0kp(3`nH%zbtS50ac>(Rdcp71(NDxRiH^&iG@P18`<^XrV=k53Am_ z2G3Q-S3f%--n|&-P{@W5se*23z|`VKX2ER7p#P^64sXo1=;(fRlNrj*lX4nd4^2$n zcp`d6M0K^SbjSf&s1B9|1?R|?L%lAa2!t6!zKz1=78))`S+@!^3@dBa8J8S!ngt7r zLC<7DXvW#k2h#P|jReE&GCa`*+l<0uqNPiPsi=5J$eU>y#(|^$J%XNGJrX<*Sq8Hs z@hXCO-a!@|?PXzC*8dr|3+j{hg;zdxdSN!+Z(7eGYA!C9qLyKc-ksI|Myb53vHLIh zf!bL2hD;e4f>h>lH6zhJBc=cTTl8hufVY?dw=g>OpHoph9MQMr1?!jz=+0kIu_pLcsV|Bxd4tUBR;d|%|huNG)Zwx9dyJ>lodT#+i8wgzHaM(Cax zp0}_Qd#Cdw=D!j@EHJ!#@uGv@~&s8{z$^6W@CB%6^;99^y>V5)57<( z=)5t2Zym(<_Fx6Kc@5xxH)*Xo@NO6MS)UJ;I}wid#?u3K5OjO|ZEfCOPt~}7A=<7b;SKCbRjBGUTX%T#PHj}fS<2~=Umg3Yl%zgKjD6+Pm{zD4j{g0sR z^eVd{^eC@vddU6E$L-!p2!WXSjlW29Sof?|UMIOE*X>?%3>uLLo}uF1*X})3hW>F; zDQy;>D#YhZLzdaoG)MZXSI%#0LH=vlFn4$59U2Yw&uME%t>;G;g*G5K1e&z7scmH_ z#K&guZ!x?OwR?oncrn?gy1ed($e)Jubx86X`5elTQLQzDfRBSQs4yBOvr)h!db@nUq1 z%*3YkSN|h(#v4^x=Q!9FswVO`(K(O^jxOvE)_qzg4-Dniqpx`r@hQK z-1`F=dPFk`8GYNdx<==zYZfjQ!Xruh_ zWRZ9rbBT5;?-NtC;*sI>flAT{cAVFj^-g%;!RNDY>j&?w*iZPPcrtC?TXZy+o$Jp`upy4hwOjlBD}6#TOd|T zM_cG+>)xk-_#3tvgd+IvdbWO%=$_2aPNG=~(^DIKD5;b)pC*k!Yt5NFJfrfd0Z zW8)?8R=aH)#Y%k8%SFA3M<$&U7Z9}>+@Dxi`h?PV#8^I!Sy%MT8en%1QPS_uYSyWR zhAjaW3U1w7ASGRUp}{f;JP1hTH{zAGoGG@ydsCE)4xV{=@c?*W7M}<{fIR*dqZ~YS zh{Fj~AFPT5+`-aGR_nE4!#U#Nq`G}};SX)MOPu#-Zygv7R;!!)+I9P|D)oo6Hi}am zd+r~k0Sz*s%Ci(0In2E0OvzF5izX?euWg7v2~v9m3eA=Z*Xw;Q;k-1rEo$YDr`J2L zk6v$2wE*W$G6_Tkc5_qtc|i|OSE{vKS%6n>us~q&OV5f=)6`r&?k;)ch3c0y2 znQWrB)dp}xJ}0R*h!v$N5-InyIweLne3+&KMbI-cH-a6ieyvMKdSguyuNN{W4~hL- z!p}y!BmG9371zj&G2~}##c@@a^H8KzCVstZ#v^S~d-fEX(H-svSb`x&$Jo8o!|KuG zo;21{Z!C!JTat)$uZpBsVos>`VmJ&&-&7g@fNNmCEcKPbaAlhD;eBJ!%B+1X+U%c) z@sm=+dJ$v5u&(U+8Lr?lxuN{I09G1qsxLi6n^|Bu{5$ne@d)!w0YF>8mH9;#Naon` zFqI;{U!nkRE0g*2aQt*~I%yquRg|CT0Q9Re_T14oL zy@w$qUsZP;`ggL_a<$Vu02+}nx?7dLJxylm73#IBsv$gLG#b&UY?6fd`}Qi9to64c zycYY1VfDD>g+w!7mslZk)6i`1IvC30o=2l`DQ2Gmzpvl+z93I4MBH5GcCrCMrM9P$ zzx`Mk%NT2aSZwz6+Vn5V^!8}BE^Qpw^1-C1Yic+hm3QvI)d3)Mc;1WP%B~5oSIrfO zGm56umSq>k5g6Wcs|?v?0CEKea{|%n(9FR%4-;NA{{(2}-Wis?=bNNW$5)weWbWsF zXWhXSfB^a`QybcOt(iH>IHi9lMb4Y1vMo54`1Ra$T&4(y=$>Yhn2=e(=6Wh<3oCBI z#`Bwpjmq|M6k=tXkg~$cJFPUUb10UwhKQq1`u}R6$6Y7^0=q|WtTqad1EDmYmp`SZ zso_$r%o?(_OD`P%vX7R_CicDL^4AKD2lxuTXD6W-F?6dZ(}&BwO$qHsY1qP{c0j^M zJ-Q5K>HK?)#cQBby=fl+u=()5;50IL_$wz%r?Lh#n&$`i%6MM7@1LGFNYOaW0cIqX zOd2CuK^yA#n@vGcw*(`7ha7N^!f}>R_n2by4nf+D)C`4kX$v(C@Soo0q!JyrwD`)g zt?&oKQe_*;Y!y5ypE^mXI4KgY{{+iYQ=xLpi&M+Yfq6l5I^58J(^k?B(o~I+NMJ&3PlID1po>#~UJk3t`g7A7L2s^@R3MtfqTfFfJGt&7%hV zx6G%07(#v;%AUhecHufOw7ght1`yW*M<9UtU-{ggI&&)k_9vL<1K@^GWc%O3L- z&|ueg)=|0c}0XyNR~0Ze&Po}x;f<+pZ}Gk`M4 zxhLU~x4?Q~xg6WZH0}apvEBj6dkYAB$4(jUJ<8Q|CM05SX3qmjiy{3fKlSvT+MZgjW~$PXePZ->Zxt6PHfOu!bBX$H%2TVUlP)_PAvH z0Y4&|N&JGM@(bMSQ77GQiQx!Q?Pq)1?v?8U`HepGNS~{5rZd5JEwipB?7&YE5z5Jg zsJfk)=Xo%eAj$~}w+$crQJH-8Uk3P@cS=- zlj+d-oY3mc2%p`!c%=9$ip#D7E`Z)>#NIrQv zpKBz70VtA%`fNkYwm6uvZR*zTLF*%Tsq4>_l?HA1TQohGF{m|+RJhJN%#%$VFW1gp zCynbccPm#>FozMSF)#bMGCd>om76E>#J~5g7hbi}T-=ssI)1I_e8GoYy04e>058qW z00!TCH7VmAX|Qp-P2na9y(IY~75#ExO4`a+B4@aNe`MAl=@L(t#_~V;KRts`6Lr=< zC~Oa`ey}K-E#N&hXnX?IAKGKJUID&BmOZY5GKE!+gRRfj#XWz78P$GPUoFoDMY|vg zZ<({CM{A$$$SM5E%Z%?1fN1ypsRR;Kz-tGK-2auS~ z)JNRVn0YEJ6%s?SC>!96q~b^y)9A|-&k-2#rNXd26%D*3Z$W&?csW_CPXguT8Zr;H zJ|JV+<_0@N=Glkw2@# zUH)RRI5UrrrS8c1pPKVxcUJyY&&ehIMt{iL-(eF(-$1QzX_-{ zH)Dw3?!8=Q=cn`Q`m?9>m->bd{D2UXOC>8!O(O}B(n5tn&NR>w7>*+}`^vfV2~(r} ziZ_YT5N-ItC)K(G{q1z?3b<)N2F94rZ8vF9(TIzz9CyC)HubNqoj)Go1J~QL4NTj@ zw3u~jJagr|R(2|Uy8h~Kt>k!~GoToll)C&Odbde~L%?SdITmP)Yh1%)Id+foc20jE z(WdUIxa;+H*Vse*wRgZTiG4fj#ixPBV?TSa=R^X$JIO+Fnt5{(oB0giiDEOF^y@r; zK5Zm6t%a>6k1;#-Q_9=qbz zRyDM$sese9liu~>XkIo9ue&l4+vgWN~B z|JUSw(hi`%^CYl20 zMzmflIK*Wi*WlnK(iFyR8KW?(9LwqLA&}Fv%fk6E^}_j~87uvh2*1l>AX+a`Le76t z4*z|m#X*ot*)L&{=Q7CZar1Hkh?A*bWAy-l3WE-T<9^EXRhrpJ)tX)8Cajx4@1CnC z!F44|Q44@lKHp~hj8&>!yyKu{njBYqY|y+Z`nKoorhA?6{`^nO45$fB<^*U4i_&Mi z1MUUTmGi(&;0WJdWUi>t_3Hvioz54v`>$^vcRYxt%AN47PW4x<2|z^1-&oUzcDIJG zrhJOMxhd)fAV3MKL!>;p^nlQkZOz3^uJ^0*fG*>9+wf`BHV}?f*@qbu>b)i-JSav< z7^Lp3rAcxPi1d2a+$K;!gO|wz2<5U|cPq8;gx;OI;3)%;l+sYO97&n@C*}m8IYsFL zx>U$S4ZC<{8mZT@^j5C<8FTsCLpE`e6 z`*@?d?}7CXnSGvUL$u>3QOe6n;?}%Kty8GKp{T>}gPb1*v#}(n?k$QQUy5=K^ze%% z-p64~E$}sqKwv4^0 z(b%tOQI=uE)WqbSL>$SgaF1V>pvNS!4jM)K%%hNCxM!li&g=($L}DX_d78AsO!N(2 zg0ZW*s}@t`fcm4Km-ZJ~S(*b;TZK@4tXvR?gaEeMOQu_8+pzcFsEBO@OcCQl%Af+1 z=@f3lbAGQyd*iEkh zn_$2>{{{b@1ib;@M8%ygjF~sGWJP50)5%_N&+kx@r#>6gf?3rW9R7xIG-v6*YNL1n zG>1oZCI*j#A1-LXSzdC~^VCBP<`oZ2X|B6mn}PUrfq<&8`|&2#=4ilNJS@xk%;P{J z(>Kz6o7v^Cc+ciXBa(gLi-%2;I;jFdRk0~ zrtt4x&Y%%XvjiT@?7#KN_!mx9`U~~og)(e_wpfDpY<6u1@>`VIIgJH3q_z%a#aYz~ z32gmT54%=jrQ>C>UP8z(rp5CHgmQ!YGh6+kW0k*jdqbj+gsjeEn8U=wLX&g5**nGc zPkJqm^-vQ~cAzxN_lLDkWp!owLvT+2GD~uB1)6F4t@ma8H#9ZoyLp0%0h=Tq#O zpx*^6ot_X5rWTkP-2g8vM7t8RUd`wE_685!j~>9A#kfTj2`T^yoG}`tnd%ckT?>r- zF@E^UzH_p^(rmxka#Ydl93}hZW#jeW_~ZAYVOt> z9xpHuxYb=!(-i_j{I%Z>JHsq%x3d*l42A=3&CDt<%(@mRi!jVurlrHd=%#H}RiBes z%%Ll9^B5M`@!ogVyg;hlQ`sy4e}c(vYjsP^ZFq+}D>KQPuPDZ*=Ip1ON5Fyf3N+62 zylSD0r-IYXTXd$~C?BOz&gw5-+9sUO%kPRjgdZ<*j7|XTv$J{RH(Zq%r4FxsLE{bT z^RqkkD4X_m#>0ADzg7z#dJ&z51R(RgNt%l}>EF;-IkaahV~>&{#D9`gtdoKoZP3)z z_HIC`OxWZxSXwThw&ol2|6u`KEK-UTg%H*J?ZJ~U-e$Z1{oPUS-E^*$!W(r@T{zTM zC+KH8;F!W+q71}eN*^_T?XoV3>{BM+s?b|8C83}U+vtx1i1&V9Bm4w!_}6@4cG5QV zg9#xAE!L-p#ZAAOe{L| zr`(|kKJpec&|Ji-aD;DglcGLbN2w{8#wk@eL1kK^?Av##!6H4T{Y+VlO|*k*Q>CBr zY%BeF_IvHTqAc%8W>mF@rp%L`)|XItwt_-UD`CZyyCBp&S6nsFlo7>PSU02P8;eDq zVy>dDf&Fo+(evW!DpFlI{>zZxXbj4FF<5Lz-am3+4)?E_d(7=0TB0t>&$k1B` zDIT3!#j%$LOO~o3@i(b#)}J2D34k}3d#yw_m|hE*>P66uHw00f-w{TZSHV*1IA1sg zD4-<@#+nLonQ;B96TI~ytUNifY6bA*kbs^G8nS+zf4V8+DX+V48H1J{;H9v>=LoHh z(ELY|C+YvRIvc@3;B`kGQNhyP{>AaTb!;aR|cW zH>|!zdOY{1Z2nnwFg8(DmmL!l&^fNpD~knMdwt@9vJGEFc&)Ysu}qIIRD*0K`2@rR zlgND`tej$u;aq4yGaoTvudb zkoUQQPoHBt=5e{MasYDzWRps`K4U;^DrASYUmMVD~ zN|ZpT5YTej{l6Q`niPuVTS`lqkM%q4xCdc0wAI{U#1E_DG*iB9>0iJF0{G&ovy=;J z!@G7RNU5ok$rCD9jH2>8Ne2SvKzxj&_R0p`+vmS{;0JYCJ~Vt__TFJ-lNio5)|3Ev zlo#*Ip<1-w5n_RZzc+}1HldMQ8{yIDSZ%*ZG5%8{G;dvS?AyG~Game}Tsr~5q&|}z>0A{*DyUGy zut^P5DBE7k$EM+!3yd)30b2d*1|_lFY)ti4 z)Lm5$8{4vFC(hsjGKII&59$i9#L^}Ap%z69ejXwUagTBUa9LChX#^-s>Sdty$y4`telYe_!H0^pjU%U=k>tVE17%ZFmvns{ zy%V3;X$wDU%RyUFRS6~ z7|Vb$MMwYOqSCnj1UJv^IzeDO-~JXcuf!_jG%LY3gj0!~NrTS=8M~IryMLz?ULsKN zzzZaC(qlN9X2jT<+OgmiHv*DL;vu3%Z`m<_Y;a%*!EARTNWIuSWAhz3Mfn((Z2;FROw+7 zCZsM50!iMeOQsM5@if$yF+bVuEQNlJ?|3jPiHA|@5fDE`+TQ=Op#)t=xj*enfvlzt zaG0FF*PW~kEn{DP;g7u^h?`(H6*2|_LojiUjaM$K+W`E~|BbFGH~F%d;v4*=?m2YU)1A4>GZ5<}Y}<$%LSbU`9hszXfi+-C)fP%j>hwB^2UzZOr4#AD1iptnPdD zd1zvmzp!2hmP?gL>ed=5gT5vJ$$9u=gm-Oqm~-R|Dm{GI{! zLH}~4Hyw`j8+*0|6Zqw?Y!)uJc|e|-q*<>2R2FVmdO^RH0Aw@>Kt?}9J-;2d!*~-a zyVAd&RQz6yuPaqlua7tI+gaO&?_q^P#LgD7^7%86jN3sRoc+%eDu^|zdPz~e456!Ubef|es@afc9wR@rTvh8 zHky{4n~cjBEHK|;2`|Cvrlu9(a|#BTcAHMlFG3_Ycr3hf@AFN;QEGX>9ZI)C zK|e9t7+m4~v;9QWSDJNl5R|pq(`cSL$M*q=X03R-TxJ!9iT=ma=c}cw%%DTp!P)Fi zqdO|lQBS1#XiBT@ZvH;Lp4!|RQh1`)S-lV+{q3_xkY`2Hz|75;!)Z?<&r{SSr(N+n zkM9mvYDn@a6M+n|1!|rd3+<=_lF5Od<3Sbk=gUs_|E}_yC8j2L_V<1zwVgZcb4}-5 z_Q`wA|JvRaN@{qn>6)mmRA8;Qc7ZiY^Qz~>t|z%;;yGQOoCpkEFF(<8Lt)l=o8&0| z^W^9>=rMFsX64V!BSKvT^0oaVuC;#&0~q5h7CST8 zbFQcQ1YgG;`~!!r95o_0Q=c+7lW9-z?v*fPPwXl|pumy-n()k@Ds;kI>u_R@hnfhw zC9=CZF*C@tP#anB#lz;le^7Uz*;=V(XyOr}?Un4b7{%6HfEcg1(#G8IwXUKW!AQ%= zkJ?(*1Djc^Vusslc~WLesNUnyb6fgpu|qfhGIkh+@9o>be7-D?6@-JHyA*@xsSEUr z*$+PB?%>tbEa)c}h{x4>FUpKd7~SbMd4;rF!XsJB$A~(CyKd#I+kXhz#4p^hm-hR6 z_&O$8#K@iJIFAolh9b+q!}2jX6PBW$pd;PZD4mGq%2Hktr@5^jlC~L#WF8S3uJ@>M zq>aoli{SFfl4N6JMt8w&%yKJJ|JdzvKf@~?ap*S8R!^A@+$ z%!mm43MW++y~&p$4w-3=B$AU~_^)AGRHsv_MG!fTM=VEcxnfM?LfH9~oMdtwD2&Sk zA|wjGhhQ*(Nu>>gVyh>a<9SEx%gl`T3Qh}Eq}C>Jac=to3SiIC6|;SOoDcjKGWJN< z;ke$}blz*^ETBnF*cX=jd3Q=gB3$3mU{4&24&p#Y!AbinVx1w*so-YyJ!JYG=7-wkZ4h5#R%X+U z1!d-xOrOKaY5&7U?qP(|guu1^l%Fimrx)%Oly<3E*%{ez`%KTGWF;j1-Rw-ieaeQB ztjrfMwC=|KmuuF@DbFn$->1|w-){Z=y$eqqGtbX~zk@KmCJF8rn+@t~NCj8e%v0;i zmnKGcwe~f(ZZIF_$~=ygOf}b9gF!9az0b!>F+PX8l=Ychu(^(oogtod?ocHI%7S;< zy!+bs9~5NDeMh4`|BlXk-rimd&MJ6UUk&n~O?q?cQ}YexW~Td1ig-3`5<$E3xkbig zqI|^qac91bVi%kmL0;Y(^iXU$%WLDsxIeME%U9G;!q@JAa#M)i$n)KbiCVZWQ*9ny z?QD$~N9`H(sQPJ@_Fv{c<;`9+?_cIw{;^TB{V|;tX#xB_{jwbTYa`>6y$^^)MAM!P zV4|nrSr0@w+ze3dBA|j)J-TPnhm86`lsH?aDVQlU32 z)Gy$gs2_n-_7_?0DJd|j=^@_{{bKfVo0zWdx2LITsSz;}K8CE9#M3AT3S)QOUeE^A z=OxuqDcz$|^su8sFZcfmj?#D)GPO-C^!v@={2@SoP6rA9`&Oc`Cw#Z6k;j)UwozvV zURtf`7<5DZk0W?3(m}UA$(%0wJ<<;H&E5@}Z6yvl;(eiHT4YJF&YWjxXG7jU)ekBJZ>Yy z2I;Ww25*9#%i8BM^tERu&@pt->LO+V?dqD%>(#yKZp|&bgGgKC5NQ{PzG*rvx$8}! zy|0|2S^mS26=7K*L8v4OiYUnKXzE!#7t8`anoH{lT%oBiQrCI^vUR?^G%=1fyuLou zmoPYzM~^xa$3ekmMAs|N{~&x7YZ!Oq%069nbSamZM>!4OooH`Ll8~>18yOIRERG3Y zeCtH+;)kJADy*Ybt-;~F@4o9QZ+w*yN2AdTN&om>XoP!Yp4r%XkYJRLDZ2aMadr7e z1%y>8dq8|-ZGS+LM#U7dc6*nxgndG9Wh$RLb}7Ooc0>~;G(OY*spj2a=6td5r?CFc zI9{CnjXI{KYqgPJ1C#F51rmE8rWc=mT8z-K2Mv}_63+rsL4pwqudLP4U*uO_W6EqjsqvDuMSs6mml!^s&!Ib&X9Hd6Vq4ybi7d68!{#Y`J ztS%phmFUk%f6WN7*<6U#w}MYmGuQA~BIgTLC*~(BDGsgS*)V5v}fIj9>nO7=kX&q?%0ejm=bt?Vu~?Fmz|OU0J6@T?yX7)vG- zDdYA?a_CmZ`uQ3Ir;U7QztLyJabStk!pl=y0yx=0evWG&vQx68Yn5`*5)h~cQFNdl zim65`FSniXHfTaWpmo!pO^%ivtmaEq^y2<_D$9-GshA5X(hp(ld34;|pv`jplVM^e z=tKb?Nz;}MFOsQ$yVia4yXohq-)SSLx+;*^_H&9Xy{$2H9CYr*341=;()Fn8DJ%r5YI#4J3q4J@amj@Igk#%cVy#h zPH~7^X7kIX-NM-$( z-$T5#fhf}?wnC>R8kT$g+r=auf#II4BL0XEe!fy}hBSuUCGH%(efK9wH{ZC*Xs`p1 zP12a~56_>BV4P0;=bfyO9=r3xEMn#X$A%`B& zzqg$Uorb-Fp(!=9v;Y1?Y*siD^3M;Nw@-t~2xeERYWlSMXlZ4XSc-jHR( z!8DFgSe-*P%Ab$Y6Q*#PoBq-Mp3abn44k4r+`T7vN?+4H4fAl)J=H@`JWnUgVMON2 zP^<2Ny01DCu8*wZ^oWG(O+IVE1>L*xn|B;Rno|mE-<)d1Do6uvV5%-JgiupmjyEp1 z`azw21V%k(DrZp3>O>=gjFCKP1y3S3;bJRiinF1`Wiwn8XZ#O&oHB+8C(9K(J>9$t z@x8OPrV4c;4rTZD^e-q!5^S8#@22XRD4v!`QykHdQ&I@Os2L+;5Ao&+z_?cHvPiC^ zas+1bT^7>I9$Zk;Ds3vb+9C0ugE9VA`(tsUpZSkj*YU9mKiQP!5=J;Xb=||EduMRw zax|Ki15WlIakm154TXrwflmq`vT^%(t8I}(JH5}A$F_QP<-00pM>zqX%5sS3eF{@5C@Co5h=zaU<#B|I z*U_*PadQP;0TJ&|E+%5!j_ql44m=OK1}*U=n2LK^*3OXrjJ#*8(A9?qeKJ>Fru{A{ zWt}U#waLv7L8<0r{K4s4TgNGzJ9Sn(oz6+da0xnP(D9N1J{Y(-;5Z=$0ya)EoI+oc zVjU3#yZH|0JBv7-CNAa@ReY_T!qBu=ImWNo4#4bNW%t`3|zA%meL z!HrYWs_x=0(K^C$l@`SI$@Yla^X!I8h)LXr)C7D^lI!LoYk#o&sb7nldQ;ELa-_R&#Q~}GY^_QXg6Q#Ews7fbH6=HRC&F9?X38R9v+TlGpm@`vpp0G8qWllRN7dr z7`t>8+3)3;ohM&5Gp<$cyjTysult4gf=g|{lQ$=?N0V0t$$(RPRwz(p8zZ z{19GFvPQNm2HNzK%o|AqVRyD=!@f5nBrpV)2)_t8`9(^$SA-y{qV#{R!2Lnx*Vx67 za{b}S5uSij=1WfdC!PxO^e3I@-;JbSpHmmvoH#yy7k_UQy#MPKT*RkM(GU}p&D3%< zysL|<7=7x2iU|k$F7$%c3MUyF&mh^At$c%2dw_IfLbW8m`};OY*AQ#Up`HNT$aX1P zr6(9X2|R525cB;E0&aD&jAZzC2l^1|2c}Gq1Guy)guD(PFe!la^i+&omA|Y#z|s6M z0kaS*73~TVK~7pMZcu-8E0#4P+CX(=rwLT{F{oA#vytMgC+V?_hgJ3}GAsMHn&jsB zRys7q+>u%h>Kg{por37iy)oTwvrDZ_fe$Z6DojVmUHh3oz+J^ssWJFUz_<1ZzzApd zHg?>6q8kvOAyJT#8K7puZE>AoV+yQn-W@xSe7mPosVf4kid-AC)~=B54YzE_@i~;!OW3lZOsC{=SWX-T>AY6 zOr;+n0>U*jFZ?zHNFw0@(w%jm(DM90h*P$Xi%2T-xL}0ArZPn7-e@erZ+-Ua7-uG$#H*cgtsc4DyBU<5t5U;=3RVFLmb zgF0B!^N1_eO|~!JsXAi->WG8~e$p=sD!Z>%u{vl^-?oqiY+op%(f4$CkHE*2tB8Wx zXhUqFUnv8hzHSPkfi((9E!P*wW%FRN=csgX=znJk{f*aYazs02@7OqiC9bvDNZS81 zblUj+>s&RBn-4QYB{GzTGnDY(vu6}V2+s^|m_|w2pn@MBy@Yr0er)>( zEH<8+7{dCsAQc^lZ<)EgdqW5`Z*huq0?(vJ3wWDLgzRw|#jrmL+4N zBxi#!kJ~DAkSts(^1!11-$$d^bCPZxSJIluJ!u$^Fxxb2!u&-fGMv)**{;%T#v0r= zP|}SoBkzV55^M=6`^y(-+wLE@0@v~;{$JR`;U2;Gs|KB?Ese#LEuQzi+9f5+)}82? z6i;+*H{~=J2Ni?u0YTI^%-FO^9xq34A4MXG_VfTBjBAzkxPQH2}L^YdP( zFHixA6eVRou6o?vd1C>Qs(S6zseE1)(?T-Yjt&kbj5W&5AsnZvCD)$&#o5+gPkfty zqxJo_6sbKPcCdRm_R=C`Do#dAN-?&Lyst9xRW<4Xa2N|62}{WWgYC>eW_(r)mu@e) z%j!W-ADK)|s7St!amJ1cs}gL9mL#lvmo|FM7TBd_l-|u=kus<0uwdh!!v3=W>C#CpmR4OpjdKTsF0|ii!%lQp$@k>k1DwkBt~@Dq=#! zbK8?k6<^!>@;FL;e#Q#&Bm=cjbRO!hhyu^-2TLXE&jp;&WYMwYD%i5z&8)RJ#)tO& zNPVf5#uKI<{N$)Z-Ub>Hpy(cnGN7nwH`pXZ@&CHt!*dlT#P{Y-J}fn{uUnk1=gQNw$F_E=@4Iy8mWiKeAO%-&qP{Uwz!1Z3Un z1&$C`jQCVH+3CpMebrz;Vy`1MVjd5`y%+DfO;GBug%h0jMY{>;Sd4I!q(Kr6FA>~a z%LwGRLR_tr@wNTFunGH`5`#*FQg)6-b4$qeRml3B_EYwlOr9)xut z?&>RFf_}4*VFF)Bop;=6=4L>XbXv8Z6rS(rntQlM!E%IPI&A5Lr(31BmuCDW0OG3yRQeFsbpkDJub1t`*Q zH`<+-scCMf2mCV9r)%vK^i08p87(Mlw+)e9rIn|CK$uqVKzL+Vabbl*CI52|w$*@B ztj^)Tp^_8YM)x6R{5f7)&qk}&V3}kO)kW_kttyK}5|`cNa8=f+Bk8l|z0QlX`I6Id zt~bI=)|Ws$;_En5!CpihKF>5Y_BP;8;rDvuPYAQ45nY0Lh*-A+CqBtcfB;x=;Me?DMNIzYA_Z%uTZc0)528iAhH+f5f^K z6xz;baEvW&ci4v)^78+Or?U);s(quqG)M^u3<9F0ATe}-R6mEt7_47x)TE!Tt59|GXrmDdSWE|x zQf{l8yoDzyzkU@&j|R=?)Le@i``oI4VT@;H3c~PZrqge=d|}QeDvd!qL)}&??*0{v z?nP!p0V&QQL_&V1U~aCYZ5_wZZ0F9?PDEOMPudnehZ-KSP(pg)-nE0m_SIxpG{#Gt z)o?FV*sQCwAMB%(7^t~2ZPsYP#j~@Xoba)1;k^N&cG8RC;IvcHOxbsR?hZ-Atf4P( z8iIj)c2zBK32xH*GbJMfR`W+R8{qP&l}lq8V7<#p>~Aa18IJBWWGEm-wxaqay&pYc zHxbT&F5@FF?_|&)uG`2{sS4W-ystJ5$*OV)^f)9XoErTh7Nm80FHP}7x8;f<^|tA3 zNcNQTw{XyP$1{sB5pA|yCY|@<68~etfEL@mPwGWj=+ZUAFJdu6=dz}!Nak-Eq}&71oz5U<%z5C^7n|(a;KNE}Fy#57p)= zY*&~jxqj!%jPpR$HlJ8%ez0MvVef#tyT~?w1zi#|I|}xajq_PseF*nf-K{j{@<_zG z(udjL3bqrUkxK8(LRo+8H>v^TEQ31nHv@;Rr`_P#P{G94yew5$vR=9ApF{McO}W%5 z5H>`+xZ68^64x={u-j)yfsYzV%4>nY z5v1K7)AoWECgF!c9sY?Son$gbn=#+{6<|$(T+VrqN~vH9euJbX3qo&~+X(bJ*4Yxd zkch|Zsg6{rVG(D%>zu*J=*Bydk^yEEL0Mu*KKP?MY=@)oqm4&+=}1r?F?NUIW5S9u zcnQqbuSdgc8~h;h#$2w!;C(vs&<_x%wqowm=+e+RVa-hmx z+k<;PManEx)Ov0t@h}a+x86loKis^gl+8S9J!a$2Au(&Het&VdUMnaD%crRA!&jfK zKEkSpnL7h&P%l*$fFYBr&aLj-Une0bwFTa~yj?T0&?Wt&VD0684eQUt-Q577#IZ=d z6FWJDND}>MH~$e>s!^Pdl>?zoQ7`3@djEm^rt=MNjBmyTdEMr)VgS&99rRKVpZk4i zQt`eVv?{^CP1)rEb9qxWhf6-h4453(^q((1h0q@IHLR^$Jgm-ubsL>@A6ULtuzQ_! zNqLt_C!QLf)jp5fK`PpZUGEQ{QLX2Mkc96h$@hvl!bx^H!br8&fJS$^YCVx6+nm0u zP8s+%`*>?15#H`)5yzh*@0o7xiE40><1dG?h7e8+=8GZ?khs&llfgHC!Qo5Ppt>)3bRX<45%rK!gYP>3NwzDe z>&|kRCb(1*tGxSs9>``KGd(kld^BCDTQj*CG81N|T#s&C_n>CqLt}x=7r^aj9-Wtr zU`bn<5&a!=mGN( zNYcNp*@15Fak5B!wiOt&aPQbumY9G1 zdvbpPs5xO&J-@7Y*1w#Yi&1>)N@hlNL_`3VqV&^op`FHsdqdtQSwQpXsmW)a&W2gQ z5?0S~6<$O_cay?Ui8{VZ86FSBovfg@J#>B$%;yu_=RM=wj`g|^CwP2#no*O!rpo;>{mmX~=gk!cF9xivr>Bik4OZ8F7)} zM(^b#zc)%sTkKzUkuqL>RD$(oQ*rh5*I^#;;k2B@ox#}O0V9;z4N6Sa}h zQLkBp8jaFTp#(ePxnufPmCcO!Ag9Y_YeMLw<5kDJS4^liM&QGnCj#?S!rxqhS-!7X z#}2Lag8BXgmYh%HhvG7iiBsbmDg$pe0e-%wThn(Kt|nyG_*}A^G>HR&eaav9{X6wY zI(|{0ETfcee6G52aq3@eF^W0o)mjgqT$j^oea9MlJiujn`tbnC$(my--jMiAiIiOR z3L6eHE_Gl$@Vu*y3dA5^8B}7?-Gp6Jv($cM^{r#2t40nWD zc`G`gvxHS}3Lw_LgR)%gqQ0;*c0TyqLZRp75aQvu9VMj(k1;kcECye#brCh*AF19@ zF9GbTTf*Jd6z?`;kg|d%7I0er-n{AWxk+xC%WP?pnoV<*snOb?G&Dg=D1bJxzN^KZ z^S+zD7%j-e-O;x7xpvi8tq9tXmxeSlRTKa#U%x2_-}1Z-{#yWKwJVAmP9oOZUIJI3 z7y5s1=1$IrD~ctQwZJ*Ym#XlfPK)=KEvt_X@vCF(-yE`Kaqj)Z$8Fc1XKN zU2OmNT^G8E+aYHHVRYb+d_E-{`6fnmVhQH`;cqo?>jAMTDZqaJo-SiE#6mK8+6<{v zFe9jDU8edo=tGckt%;749COCBCXeiVQ?##%u0-=jjJer44iPPB6R}|>4FM^W)Q{gb z8j0N(H-z)UO~ogqub^&OCMFr5!M?q%X$OtLUIkR{=pQ%Xd^+Z5znjEH9UKRFXy*#6 zukb@>Gdq)bCm3B@xaBafiM`R2?ztKv#eaGJeQL4*O8a5 z3KUdTDA!3rsEk*UnM;G-&B3IF9#fzYpw1$3Oinm(!&f>Szm5_$?DZ5_|w1YWj|_|5~o5EFVI8r*w|>#1cYB*XN?fr z_R90}#M;Wk477-L2Um7HP3H8Uxx9k+BW6oh78h~M{VO-Z`QLt3>{)i-wylIb)=Vt7 zzJi>F+|M?|79ud2c|G4hhpy&nVP3o(aM@2+b} zsB(lbJUDXs)&3-wra;CYW>a0QBjZDT!?bFj{1eXi-9+0~QcBXXm%u>0>UU`MpncKV z64+I!^&Fn@71$MUeZMNk{r3gOYxgGF1p}%j zO-A|-Y^ggyzS15h@K4BIoG&V_J^F6y8LPJf`BR!?73ELFkzL<-rDQ8pHsa!|Zw1LU zW$Ek95-W>uq>&}+p3LdD$E)jM*iHh1;6*%nbhF(KVu$zlXu*5;W+uj!NpPAccv9ps zYK_+|{T_X5bF&sEySW0@+mHE3Odz%TDWgobE7_8cp}s}0UR|G#r~a3LIZsapr>n7H z@!mo=Ox#C%<>did4>2}UNBoE`$2fXba_6RV!V^OW10SN`@!?KJUTGf+&f9aqhl`); z_091)I18rPze%Z+2TI?nuUrPvDbYmIk}CmQ&V#AOWoqnA?2O z&~rzUh-(6_o0Q`d7QdH}Us?BMln=o-WWWyJ<3zp5aCeXbq85HxrE_m?y(l}wKccQm ziYHqg!267TQ)e`}$sPi<5!+u+ttSjKLjOBX_NzMH28Q4s=W_;Ord=e8)Kz4r=zxaY z5VPt4E+ywcdHQOv4LoL(oEOGQM{5Db$fuNhNWQ6&>~v|iOC7{GM-YV6G-k%aix?kc6UoGSqPyp@6rW;~Ci_?!Ht;GE)rCbo6Ub^n{hJdo|NSB84xJ;q z823R65%UiRIJ76kdM>xsLh>*5FMdp8vVwXWz_oEQc<_+P{Ym0GU%UKkG!(1jpV-jb zEcN2qYv(qYKU%(HFV$erl2slXS+V#HdMpmnNb8$A_7IC$R!X-v>Few3l7i9h5KR>d zJ#@@%4C8OLQnN~ewz>X9n>!I)rhNNacU!L?Ps4`cmf@_HbCe=q>{zan&KwudCqB@1 z1n$eK$N@(BvZP`Xi4M<^oI4K$Zn9M)WMiCKKAO_-@v~w?TjA$bs@#qtwN|Xg_3#L9 z;(WI@2H{~zS&Ea!n2U7_m_&B~vNBA)JDRMgBT2SQC&WxeYFe2Svmo=5Yg?4m2sF}p z=>1M|eE)E5C~FBVGF9mBB=QqtFBP%^6De0b2JGG_*(2%epn zJ@#+X6oMO#)sGZJ`gGr){cza62#ncV4c|v`?kfpPM2v4A~{jHNA zUWjaL{lS8n^BlwiNQ%~$eY6Ccq0*jNqkUM%D8zy8{jk#c|I`el5qmnaR*gP2sO#q$ zv{ricec3_9?$&7gKg;gm?*|%>GZ;mpp0Uyw@CD<*&}Q%n>)S6sFcy`KT|TbPWf37z zIy>-V1rD=vp?caXGKV%TvL-g&%#0r7(^~LX5`PzH(Ich19n}_=M&3rs(HOZ}2F#NM z4FAaBusT-?}`K!&Km6m;^-$hbiLW~U=F>bBQwIwexkS6VMqU>uGIn9$`2Go0{Weg6? zcV-9YDdoGBsh^s@?)(Ck%nu=(Y4xemcAltwopxLD%bjM69CkP{0(7a*iZt9Cx}dvs z_2G0~u+tS|W*@tY*a~};sGem%Ma{L{;yvim8;m#remh}Tp^MK1&2r2UyY(kwXMAjX z(PNv&S4XtPq*E9=A0A>xj&?0&Us`LHaBei7Ve{%^lmV#qMEbWcSr3N6pK2rZWzBvr z=IGy5(f{V9i6l29ri`>L2VSD6dBlCWOygJ9-!OXgY2bC-@)*Yr7_n1*f{#fk95gA^ z?{yrlu&CqI82o}$abnqtdC4ivOaoR8@wxp*C1peD!bb59qJ#HdB57h#hpk$5>B?Zx z4o7Bx>?}AiuFqZW`&FWn075e3JK$JK;VSW%!-z6Yd`Fxr@?b()x;m6LaaN5TvlC^o zoGj%k5BTJl&nJ4bJOa9BYJMvtZ;kNQQ5-MG87r7D!uZ)HlVmBmyU9vEXAfIN8c7;; zp!e7~o_62H-W){tsKiOI;XdHciaU(SPoeRmY&5X_fvB)_^@hVMNdcG0@C!KNwlY0x zEM#3_?S(%NJls(H+cpyy4PFdB^lYIk6uAdIhjh3)WwumFBxcv1?sO80{E*Hwg~8Hs zgT=wDf#tNtEwbKk-)4aExh{e#r*Wne z{Mc}>`aH|5+k~gtRxon8st()UYYr3q-3lqxE)h-lzMh_O_L6K78%dDP;H-OdV#yty zt?a(?(S5=vn?T{f9b-?=2LtQssxyj7k%2t7@)5w)p8!mqKfRg4wplVyJ3~~PrOB0lc2 zKziA+Kvsf+>rM*2-ul zzCYJu^7)JO#V6`Wth@x?wAy{azJji5EFhdR?#CKq1)IMT?!1xolE1E%Pc*1L_Hk7_xo8Q2*B0G9aAB zm|&D?Ky8|?Y(9v6bpCu@*)VZj;M-^-wH*K8^}Q2et(`{R1LIuAq~jQU^V50$n91Bk zCigK8=^&Wnt!23UXFVIv--TFPdvDngjR!$yfg>SH0JlJrQzu04`fpB%(s^UhPXVhO8(();ksQX+}g#M6(MWKd9$dPwN3T5# z+YshZm+!Im+rg{3wRtpjMSAq4gef!*FM-J*0|A+By;0l z9V`Z@n6U5xp~FZHPnnNgGeT(rT!iqOFwUGFGG<2>XpuGOlzTLE6q}vYaK#U0Vrd$i zKV7@x>Xh8ji8vskH!bXUbaoStRqU(?7X!^dpH1d_*U5}Y&uE6SiYb>V zxJ@LlMb#rs=Gx}4@2tStgFkQ1YJ~ZrUu-l2Vde$%yNj;QZq+Y>O)ow8?lSFQpu%)L zlq7=3FUtA=8LlR_y7uC2=L?Ty>rA_m7g#O`7e>t;rms+o(Xu*j6+i-P$Vuh@A6=hb z#GQDk{L>cWTybSXshy#+yHeKpZo1TV)P{Csx>%ql3hXnHIQsK+h#ODxK50P?q`OiV zFqIA<;x&?Whbv(aW=Y}GaJ4y+vvZNcbia1;qo9@B*`W?O?mJ%H`-PBIpt{pvAkq%N z)K7Na-SMKLYEAYtoSid+I;-2^10v`C;2GHmnBqB=jQ+SnHQ{6LbkvsK{lX*u0`VCE zYa1z&PjlROdPX2-uZbRID5UTEwOVw}J=oYeYwJkR`$foG-(m;V3Gab(Co95>w}(M; z1a}Kx!p=J&h2>>_tn%|gV)Ge|Q5i_^DqQ|ay0aSWYYiy~&RbHy730U9Z82~n$AYi4JDRkfY!<~pmSqQ7R^G;?ipW-gnGVI!-K9763$*_q?_095;tb8&`zd`*w)~ zzN`6z`8e#mXBk+!#JL#HMT48?OT0JU9f8!{Oi`C)y&bbfEP_l}M>z&$FFjA5#f?=YLY zGjHyJ)w#C5+i5=|aAhSlz48@yBMH}o8!K0ew=dWVf7H21TGb%6TGOwns3>rHoF8}R z-Yg~Ei!9w^t^B45VUH<%lqYpKS=7jJ0XAF3gO_=Z9(6*g#1ci-i4{U@(_3C0ir&oA zP|jx08YY8P?|wkkx*h1crGm$#fZK(r!_&TwdPNBFzHnumJRU#IT1854+x7JhC z#>+nyTfK3zro2$IqRY|23xuboY?GAcA7R#_a|;eB$UUZ&m^OMgc{G3n96y0*UdRpS z!f^nsH^$v~orBg!rfX|)=G?xD3POT%p-Qj-{BsDIeJzuC)h~XLT8CdD{1}1vItR-R z+Pao_9U{gGN?(HM0Rx$+cPR9OEB@vw=zfqmXbu3ns&-D;Pp!)CTOcjjGSn{JT_LJA zrigZB|A28fh9b+>GAen+v_l_v{*gpp<+f@iO%dUAW~WA_XUA|819GP9B31&Z0oAmS zt(-y7_AhfkE(voU+RC1K_pt{QtI5!I%X*{^+kEUR6PcUKOsbj~P~z*H#9;fNVFyD$ zv*Heao5*$frhykqnJQXCG>!lZ-Kk^Rr*QN-)dWV-E-A?pX(%ReJb9Y3xXT7)bv&9M zyE2JK61OG@%oigYF+ElwwfQvDVUBCipW!nJlieY)5j;9yA@B{=z4P%-i{Ga*He15+ z3~z#i{GUsp2)O?M;)2rHYA| zFFo0Rx1^L>i_6pTn|O?jYojAk`)~>x!N9Br3Z&7+e&=U0#ZP8K0d2Tls$4|59ae0BfcM(|zH2 z`hQ&jzU1iCj8ELwV`Lh&&cBE3e7=*{9e}KWpLlKrh4*lF zzIF=_B9`A8jm2&dP7gbqOdm&MQF9Cb?iVuuJUOK(0F??EmmvF|t&QGiXAwIM>*`(Am`^lC2zb@7BF(y z)R%YphJ$TH;-XWrHrBb#dt~x{A&gZty&>deq>o&)FhQ+73#sWQ-!xtbfVs(jsQ3`> zY_;W}r&E3^^f{zuhRmKsmwGc)KfX3>7_Fl|aB75AZ+RJ|TpIjDevzs9ouO=APFA5l zU^f;FNkb%ocD&z1o(@wsXW6h&9Vot0sCo>&>WB6&9d87LL~xI`7?M}mZM>3BTSEqy zR3)bKdD`}?CF^K0* zqVK9Pe5(&CK0N7bxtG0}s8tuiEkA=6KjLM&lWH)A`FhQS|7h2pef6_)#g(s9Fn`4u zV{%lI+2lxTbJWmhwHsPL=86ZRXoTswCTAIN(_(^58gF`m<*@~fS$-^(k=XTihc2f^ z<2q+@+h{)|*Ly8^)#$tgbQon%*Y!HbZqq~=2qOIBv!Wr`;~~2g1*W#89|WYX%$Kl? z%cXi8OWUQp5SYdr-j$X|QqyeyXe{j-Qu{v?2Kcss#wud?^&HriH64*( z|0a7iK#%^DpZG(q9fOoHB1eAk%Cr-C7d{fhn&1EPWTl(03TLlD&mxfT;eDGIo3?K<~P_=F}H-_Kz{vCb<{!qTY0^ zwI>G0KC4U#4RlCQRdlgFjVfZ1LbW>$6v_CA~OW*%&VDWPXoY9tl9LkY6h=V$O6)$wO)t-23WrG)& z8Tgk`MO>k5jiq->1Hl}}@NGe<#&HG>O7Pp*?Ex8+ugrr`<k4rbDe*dfa&NP6R%E{5ZdUSR3*b;DsljCR zX!SUp9jon;vlvdVjx053*@!-e`C*RztTOKJq>3o@CDwDJFT~3G*0ecpaJ+(aGORE3 zsuYB(0{at#kcjiYSF$hKZ~C+i z_Wz`v)MWfcdwx3B4+J_2@c_b|LLJ?O@k9sGL#o!Ps;-NQEBt^ARHsYs94S;AjJ;Ni z{ta65jx01x?~;vYL=OJ_&nQwz-TAtx_k5RUKPj>8)+66BbkVfUWmszWyN;HD%Zc+1 zhMw72X%GMfvLy<*sImx#DmD2%&4$*Be3^ZMYp}BV zJCZqkxxK*6S3BvqX54SOkI_T85oWX)m7Olocf}JMCPhi>@P0v?US|2#OF}LF5^FDq znFw#d=RK+)pu!GNPz=_Oc@);@e$)h~!jqT8PDFtudos-%jVF0pV>g6NYwH03w|Mt zN{G8Z$Mo)p20K)#rG8fD8ZHQd0rgh@#~~_Fqf9`YH#9|D(yaQaj{)WUcsy)k08d`+ zdQz_!gWEh1&C?ItFX9QrWy^I@)NnhF*nf$ER0|NJk|tdZsSUZQ+&TvSK3yW+6XZ`; z6hzr#(ZdST#_7cD@BwLEx4jvxsG=$i{YwE}o5i zE{G;biB}YNvJ3TGy;so5ywlF?3nZXxhB;;2JKg+gXz!G-nsPR7FQ7AyOOi7-_LtVW zw=Q>Q_j)?_K?)(_6tT8OdzhqXLwMTF5HdE*W~(tD?=>PCtc6J*Zn;m?# zf{sbd1zQ!Ut0*avUqYr~p=do}CFM#c%CR(bzdDdCtjNI0c)Fnb0d)a9N~ET{qLV*Z ziaFE}-h48zw{MmEri-W0CcTwlG|9y3^c29Mnmi@lexZA`XIVKcsC#5c{e{ZH!eW9t z?fyjIFGlanZW#bPbKIqmYi=xOA`}ju9gErIe)?S_;K}@^GQgLbBW8&fS|f}4vJyB)D6)8VYjO~EGjR8bDf`qb_8SIZBE%k0G7wxM zz!RdQYnL_?vcOG>Bpned)>K$R@PMG32AR!o9C|quUiot~>VjeQK(>a* z>*g0;8PN-Q$$JAw51+?NyPm#wA2r2=$Wrr+N4uLnbvtFnK8M`Xqy*KezR@2Pd%Po9 z#`U&K7=STf0j_7R)f!FZMZzJs0>T%M$*OP1zO+&ZdMvZxY$q`5BHP-MPb|34^uMNz z`Un9qJG8sIJJ{;eA==PuEe_9q{_-IYhT8h?#hl-J+9yRh$=NNi)asY9e!|Bxoi1a# zVwWHscRDuSiM6;or`k4-M#3(-EyJT-Ka`pIhsKpvp2X(Euq}*OHB1-F^n)KQ|fb9@=tA; zB+|f?`FBNM9@}iuoH!u)3AV#gELggs*P`tjRe~Ei72ncvI|ioRB;p=7Q+cF0zp4;JK9}-tyzZ; z;YCfWY`plXRMo)?h6vJ-ftZ74&RSq58RV1^D%Rg%y zWyQitKqeG|k40y-)60e6FaE>!0RW8KOU~R#LY5Ci%T&ys7#jrfW>V`lYu?Q46Lg%# z+3g}e9Cpt&Ku-L9%D(j~!+LO^vDC^uX+KH^?Y4dy*rc?>spV!k9$$- z^eikbmDxUXJ-VC0l)>2cgEZS+qugkURiH{Gj73*w1>tJBMM)+|B`m!=(mKhpvMxZm|&gWQG-)e<*D zQ^b$0(q7yA`aeC7A32$|p0x=70{qEM?JoCBiE78=Axm+9^P8Ajd$(!%4Bsb63dKLe z9Gd=h<$RvORG6VYLg8PwJFZIjK|`in_i(lj{GDheKmRt>a_3M!s_AL(VHOXxQyBs8 zX_)$Ex#a62$%{g~;EzJd~3D3&xW_+tr%B5vZCw%%4V zaO03fE=;%1lj!_(6i`Ek)IVR2OG3LnkBOR) zV=59XfuwDO!4KwzJ>j9@F+<#q@lZ+an_AnXiQOr7Vj@`oR7IReB|C)v;-{9Jvcrjy z$=6t?f`>;(!A1RGxvxC|O@#d4gQNkKZ5$eRlGCcv+;~`A=FJX1&ql5MJG4En$g^>C znfO0_x+ov+MQw^0`V$aTZfTp}kDml6zH~EOwsrTw7INXj9&?}8Hk_Qw+w(LhKeYYT ziHT)I;*(7@Q25pFy$&<4RrV-&h$H&2FN62>2?~FBQiDALqj(FQTq^pw@Du6fYh4Jh zBD7+Oh*^p?7CX<#Cj`idPs3-4N#i07vKRBdLfsuOLi@kiplS=a>cyhUXMbhZa}#a? zE1kI|38RT1j5r(fe(Y9D7v=nHQTnA!@+1V})Ma~x3NJak;N~0+BT3W`3TjDWo1`nFt51Yfymu9l! zzokRYq$7=>5JvDhCHAQx@&abuXS9hDDc9o_^Ey}4&t~m+wm_SEyVl(w3PJKa{b!d9 zeKR^gRuh|Sb)9sNJ^TmBc0XWTqXmxk!aq?brEBR@#Qnsg!! z9P3!(nuq2oAc{1wZ{5|W;J44zOHudd*CrQes6$8PH@&tqaIehip|7(^&O$XHhWqS zvR9=9j?kW_&|7N%ke_EQC^-XEiSE{XWa&4m|wSj!uY;fo7s%iI_&%(^-Xe$Mv(39GAB*}dev@b#_@c*sGAflug77{M2lD741H#%<7cffKQw}C=^NX@7nK3x= znCm3;gV@&^CcTm3Xa^go^9(m5WR4|KYY%f%vLy*U?~*a(%(YBT8`hYO{%kq&KySYt zrJ&zwb{S8iU4fwQV5D=m?c(3e6kNoZp!N{|K~L>EW|+z*YC{~G?+-|GT}iUP+b!r0 z<8If!70sV2*&fM%WN+Ge{D}dFu{@tq6_zM6ZQwDi(KgHH&5V9(vM=afaXJS=BZ`UK zc3iC&Q#h(;!0&`-{cPP}q5Uj&&nG=44q1nkjgMD8{&m*RF94!GZC!%>>j0cb|6!`J z2^Lra0}$69ctpjy0Pgp@Mgt0@0U{5X<5~6VuD`B6xPO4QqTO8)8u1_(?0QVk)18!KED5O~wVf<~ zZqAyM8twiMS+QkB^BbR$mE|B@u!nEx3mG&7K~H=`i}ybSUJfR)xiF-9KuPR}EDMV6 z%qi~e-0tQ&{PZ5KzRs9ki@X-yN4JXo^NxQxHWN4SBVXEgL?kALQaJ;^e{wgLBF2nk zBYRprS%IGpA^s)?7&%X!V`>W<-(}i&jC(~inL(ZMR0_LyStljsnUj-KtNgiSDXGeB z?GvWZZ+2i3Sz`>iS)6-9S~*WwT<`7-%tTo<+)&CA!dC0LIfc)NYS`IP^n7izCEd+L zsTpQz=-|ElfBZd=8MdA!Fv1l$`5?q}^+DifEeGK5Pb%W&gpF}%MSQ2O)qO6XVKLTq zCuMezp9KlUXQ5K4Wz+#!8~!a{G|-ty-j4Ksy!LOeGbbAT%php#zLiuF@#WL0bp%0l zgXgv0%?8~w&QZ&;A*! zeh5Ce&d-DyLzu559Ftyn<`b*@-2R~gPa^nn7U_65ghl?cqj++@3v70lII~sCBhAn` z&xUxH3JM9 zQ~ly`w{a+npIgKGH;l8o8P80Vx-mkznM&LZF{x1Kwilf0qs9($o&s_=~Ss&KFCwWlz|krIb> zxUm4~U?q$xn@PVuES|G1N!2LhRzOsE+EIInpqmHk7n z=7!GaOwaASsB zCO?$1i{f9klgz{=V+YE4#i>uDoz<5+O6L^Z7G>x>pWaijI@o>Xm&G2A$Qb+kOyZxFUvRrs_K~{^6t)Y0pVMtXXq&2Pau<3yOTg`pXS%C%FHsZ3 zS$%#IE;&w~{P=Fy#leK{u?UW|7aZLJu*jbjQ|jvLdlY@{A+;b0O*7lm!2~Dz)zG+9@fTPEJSHT0C4#kDGI5&yhjyrZav3sS%HV z@N_DV$TJw}-)17e2=4=LkooEt_`%I7vlscg@_*+!or7w1Oz_&7%=}n{;DV>|Z0H)c zFYD%6uI_mG!5TEE*9^%WORPA?UU5?7E)iBpYGLXfo#OGOjCV9U9o0}tdp z%b40k4S?&T16%8CDOR)n1WUR_4Ffe`IZQf=?s%vU(UXKU9V)}(t)Bt^e;MO0wVPfD zg0dVH**G72k=MCZ?f=;g@ATu2KR%`6>lAz+>Se;O;bQ9EbB;S83+EYHCZbBZH3?^B z-XcrWAH=7WYjZ6bs7S9GC&ji5|29G|lPi~zX?Tx$@ z90^d0*#Ti;fI_(bN&ZCZ*CWuihSB;`eI(L3AylbFt!!SCyBvf~4Xea4SjrFL4i=|h zBx$O_qg4B3oZOvS3{%24vWhw$A!fy)dcS=08Z&K)20nDSjSyMoGA~;K;5{ZW zbMG?uv_E#mBz*fn%hO`wl?S^(aa9tQVKkC+4+CTE%aIReNPmFer8E0pfm@R5? zyU+KXFC`fT$lf`jM3g(TE@Zx*qAf1^D_*K&*Wi=Z%FF*Z|UyR&7}~oy@+qKbUtAhGwT`(@mL; zrx&HSTG^B~7#pUtK^jBcVFS{{ho7Nph7-Kwc`&z^-r&AcC- z=W8vsRcd53N!Y$%ooW}?sx=NPj$dB8(s!9brdKH#pSGopEv0QA_LIPn1-Gcl`{y|X z&`zh%1J4MPdgz>w1*)7D>u=gLkFz*2sbOxd_cc_)PSwo-|3LKoAg}21$f!uxbo^na zEyd8?^uu5OtEmJ1q06ZI@XUj?%h53jj#zi+StTAnpQideSz@@bMH9lew#$+xgSh6G zNbZL3=H?^5?s%<-LX8h37uUH09rWUzSpASp=Kf-g4=J z#)4TulW3npIXt|sZUAJ6-G!wAN*OtyQ1IvJdZ;{J$H+9>n!@Xp5mWQ8-Q;!$eDzw6 zl?dbKSF~xBxI1PR9;D_G8)vNreP4;gq#vB+L^Gz(8!Ds4ThVVeb(ysafk1Os>RYcp zo1Pxr&Z?e6t5ch&YzZ(%hJfegruy21@8gqubRgDkw%s25?eq{uGq2s=gW%)G&!j-~ z6J+!AmHybzK?1`+sZC((6`jP%i5C}4_1kZ?QBwXq;oRNtq{zHXBS!{apE#lV5g3ZX zEH4Wr9$$Y`nGoQ`tHE%Cu`-`)cG`t%7HdtQ;j`ZM{-^F7!eJkv-}Jo9z_SR{h%rp zbD&!h@}MvybZI_x0~t@BoB2rUPBOO{J<8f@tHbA4UrLKFr@D|*PA6B&-1c|lXbQ>wYaAtZ`mO`-t(x48z%Gi zM!Va!a{Ls89<#Ruu_|AsNh<^x~#-jtw;@8 zk(YSux~!tk7aauV`9?;N?m(yYsiN1c(@_g(3PFP8@PTQ=VyTOxjmUE1?@Rr_4LXC^ z?ijS#@qsK<4G~)31fWOH0_Vf`zvbY!=#=%}-0;I)YJ1LP)w;XqGJw3T!p}g>unEVL zceOAIrr08Xo}=9_qGuN<1V^l8#j_Db?Dq!}9L(l2hboDj#Ka>f72ochZIJB^<`m|e z4VezSApS%96k`=iy~V0ue`Mu95i#}e(IL1(DfDe7X?R#Bp_)Sc{ha^2WTwBqFz!E>_0MA;*0Qr!XkrMm1=4 z<3Q+NZ52LLx~`!dHnM)MX3+~=yEMn=c3-SEN#!Y2$^RGkzbtW=C8bIRl&0VYb|&pE ziKBS3Q&{8-3y%RWSVGeo~b^}%xB@;WzJ{@bh5m^qm8Zj2{vZ2wDIFG^bLZ<|Q{ z5NeFzI;x$Vg)<7@9II8x}gcCg4OD_IKdeC;E20-`0C<>S}_bvH%(r$^eG^{sr z)dSOFv5+|RE?Y6d;)IO!y(3@cQOLVb>|CXg1o%cbm%S{_Z-@H_j$d;2i~XH3Z15R> zb8HxDY^KdK*Qr4c{M$|HttKze4y2iiXhxS*`Yy@&azAV_pE&>dRtpofuu*ndcGE|Y z5v>~~Xuz5@#I#s6>b{@fgG4z~9F8XaB8)6WhR-U@&l}G(WO6+&1C!BnFBxoi;>0{3 zE?@Kiyyd;YKP)0N=_QUA+yBXP6${HI3uyU@3{`^s_*oPpUr)$8MX}whH@14DU_hUf zqne5)jX@US24ff`2pT@R&rbURxbh>$xdQhS*&v$$lKkX|eKJkIV%bc~hI4PEHx*xa z$RGWlai3bAOt4X~6th?7s3yCyMsr0m*1P{#YiS=dFH#4 z5A_u(;b}MwzabO|6EsyaEe5d0Z#ZfrfL6Zwuiq)jI_VM$+6yi}RYNgPw9kin;>46X zDmf4x91@+irSE?3(@|~UF`djAlZM$@oRjavhY5T(9DWz|ErlRo>AdL^KOEku?gvt_ z%nb?t#40#2jtiPDxA;e6)T+r&0Ni7Gr`SD(F;*!6kJ*!M$^s=0AuNr5LlNpAZQRL5(OvoPKi;u< zT%Lmq@kteTjoqG^c=!DetJk;7?9 zL2v4=%GX{{x%;9mueRZOr(HO(+`}WS|5BH!1ck}X31D*bHmL>ycM^8(3)`Q+EVNvO z*tMS+b=qG<%zvDt#h7Y*YYua+Xf!@!>HW6hw1radr9iWEV$4l?@POt@|HQ{Q;u#+FTSWv%!oZP@QY? z(g^^zGxxW>!XgSn?6>(Rg?A+i`Wzt_vNHN<_|&g>Xf)*Q7Yf_B%xCZZRV?Psw9+^t zqP<;|lihIFzXJfx%x_vu6ZQ21?&vqsyEG4zk`_JonLOfkZNSG^X8BjRwH&iQc5fdh zrkaMX8hm&&9vNi#o>5^;@Zji(mHxp7TehhZ!^1rSaJBKxvvnX=3zwk=kxYlztQDUm z;ms~2&yCIq zYGQ=N?BJmc*j$&PvLV9eb{@2S8lfm@m&yej52|}+&w_R3zb9TvSwNXYzDc*3=8H@8 zf&VnS{4R7yeFj0s6Va*RHU3!GhpAjE64`ucdKGR-zPMafKHH?ZCA+W?!GjI2f1LPL zrXAssS~kOfuJ|S6(=arOU^jMhHr4NVtU_Hr@ffr(23ew1iqNBAo)xrv#>OzyaG~t| z)>j}P?Wq5b#WopsbD5G)7-whu-V`yzfHzA>aXCMMFhQ+f+?gxyhNc1wxrzj{1gOsB zugU%^gxjktLdsf;yQ-Ee4=Pe9C@d?ws9aU1W~cn;=a&@R;QFPzQq10TnAu2x#^oc2 zkuX0MVew42doqG2Q>nZyuvql;`I^#p>;@!Lskpt|;*ni)&*F>kn-Kt0*YA;Oi{bgN zbO(&{LGUdPO39pZ^p5+6%Y)mq-$v^EfPXeZ&_ClgOzji)86rhdLI3J=na=EnJ=FYQ zU_SxR9GGcvEI5S>ga7M|Xy(tq=}+d+oW~o4x`$bNOU0XUV(nPOpDau63l%xvig)cf zo|uW>H|ZMHe*~CpB+Q3J@I%Lz&AW3XvMsG~oO3gukx2p%KCAxPKMGlSzc99P0xHT- zdvCNeEquE6raV%Sk9-R66|Kw-?V-%*aI{fDrUxoz=7 z?jytuo$>Aq2&Svg&I}p<`~Ft+rwzxI^Nolp2z82GWi!qB&5(kNa^!(LZvaeIZ{R~L z_By`nS5KzOHSWcQ0viVyR=ldYCp#J=+gq7MSCuAKCA`hb6zog$tgV}@;mGwmGrZ^} z?m_ULv+xp^dCa*E=Ob#+{bDWZgW{TJh2bdmbh00mEw)FaG(P$D`TosA;In%k3G3w_ zbOI~;mq>?*c2_QgCBw{#)HJrKOe|(KKET8n%N`B%=*>>*sb4mhXuq-$3P+_s*^{f~ z@?$^O*x0dOrhpc0`SGDaRo}CU_g=5fnE1u~q1LBGfvL<9-6caGVq4u(o?aG1J9gJ> zT}M0i%;8#5}}93E;kH3P$MyZ34vH!o$R5i+emDbuWWg{ zd(qGQyFv|v=^Q4kkIJ#EJ*VGiP$c=#NY4iPPgA0|ATM(el_I?53HqoST|@cf0ILGBta6`u^`$Og|3i$=AHKXW4z<3#oaLmb3LLOT`Uqe_nYyQy zJ6+Z;VM8?nLUt!f=h=A7?!AS!aK$QTTBD*Weqj70s9rejS1cS-Ix z@ZDgX$1>}l_??HUfnAdL!AD7!#MN zm7YqlWs6zWBxV>MQn9G~N$nz0#^T6yO$^ zsSy5Iwxe)>TCO-~K-tQG{6#iJv+xG1aIF;Bb_KgZ+rPu@pZcnix{}HL*FuAO40fXx zcp_~5GZzO_n^N%B4-QC%%7pOooe)wppIkvcg^!Q0{F^)`+`*Q2c!zGBc1rO3>#iD3 z*4-5F1?!2-V?zYi6Er_$O2NP!GcxT2e@m8qjZhuLm=MvTTJfFBkPE5c1<>Cc3wja4 zupC|?k|(JvDdyb#%@dU&k^|eZ^|ui#6~P5)vtDwF=;?-k6l@!lFm{W zIAQ4~h6u+{IMO{y3?q#(M2a(RQuyb?iCDOS)qxGy%pfe8GfP$Cjahw*QzIvR6hY&l z&-FL!?Xlwwoj;`Lk`37Y;gG|BP-%05v0a;RN8bhHgg)W5e|}LU4fzm`WS6UQ)Y;Li zLn@BE?w*?!cLT;PoW~?-N*fmuP^x%`HU9^;qJXKQakFZ#>zx_zm0njmJxChd{=;c9 zT$WLyOGh*52f`)7n#1l?mz%?iwOP_yL5Z>C(^b;0$qz?&Uv81~Jcv0N(l zyL40x7v`gNMRoZ{{Vx?8?)y9-LJv8@knWHhv(ihcG?o)<#l3JhT}lTtBSJySE!Qcq zHzE@zSj^Mw>C=0N<%wVLqti#C?+ZFioW-Mr==;yoM_D`JEBfoh;(zvIdlQrl;yZt z@!T;=S`{(+&>dRA1U@Pg(B%oS9`uhh_d5x}Ywb97%NEvIy*9u01*e=iYJ{ogdcQhyU}Xm4duXFdPexBKr0Puwsaly=vWF_&j~ zGD>8q+R%#|*gQK&(jC!*)ITKauQVbv=E;}Q&3hc#;E0UXFRTe3DdA07m2Y7zh|ZuQSK1qnU~z`yCQDu7WO0+UL`f9-VXD+2#Rzl7 z1m?G1*^xMGHZDrH8t!s4ZeS}Rn^pRzD1-=*tHrL zNbz6cpnu30dTwZE#6Q62Fab8oV4qxE0L$e%&y&1*3e2m_zco3X_YQ3~VGV2B+jehr zZzPtg_K~eXOQ!H}UHPFpNgo{caeL<~v8j6-8#f&Zflz5LYw{mqJtVxl6NDY7Vmbw% zx{Bud#R$DawL6PH;*Q-JCO2iF4;EFeP!_5N5XpLGKCrrK2C2i5NFXyI(heZX4%*2X z#1Hy2Giw^QVy3=FEDZlmZtx#pF1bS=7sUWKr&9-|jhC1MV&eE~-->I8mXeBl=Isg! z8?%gD;M-s_Df|IE37`sg3}rapY)3_@7kN(0YV(Wn^z!q}pHh10wAe&Em@d z_l;sibxF}i24j_g#RRU<`U*|2ZLrbPe; zIg=moe}M!@;znA24sH%~#mb~Nb|?i3pDmbeqlIPHL0M*gKXMzzfoqIzepC9)>zC4A3> zgz&Rzpx)RfzSTcwe%<3j$l~y$kKyn8Zl7B0h(rHvp+}L$jN>&FG;!{G;Myat{oOhO zOk?I1H_CS!%kJ}{Tc3LCwc?(cb=$g|zETg1#1@^W6cIcZ(FEPvtIlBn0N%q{hQecvs6yv z)N)jf<$aZFHXewmwGDno;~n-NCb zaVzc7hF>@+$Pobi%&pJI-fTsCU(p%(z$tw)9PMvn+4|Kwq105z60GjngBUt7@8Nfg z_+Fo)1yD~%IQ?B>@gPGioleM5plMa!X_|*4Ubki?B#RLBSc(eZ{G|4G+_p5q@4+Tb z^)L)@s*MOogbm!q#~kEM>n1~KUZd>|c8s&yA-=#wLhaMXw#P-PVRT%>4X-HXgfNoS z16l){YSy+&n^g2+3bS-b0#4$ek4($}7pj7XuN-ws)k^2_lac7LG^k<$-zUD-=|xj8 zx3R`-pS%*iKo`Em(F8ID=NFv=h+K)t61zICs?D#)a_&OUb&q&miK`&Ne;|y zoZp2R@3myMJgHypEp8}KD}yihrE6IP;aKAJq0-09@pwq@r7ZT;EaRT>_sHz)U3BI6 zej&t&yFhBzb)yH7y56Qf`TJy{eE#Lw>*3l?{n)+2%Cu3M*Ub>6Rd3Qz59Chi7#Mib zVC@h;L4xXvFN0@fg_xuCXEQAS7DxNR7!xo&H0{b$3Q1$2tI7%j7)eAEqf9sf}J*fxS}u} z%Da+vu?h?^b!=3?a68=I!Ld3;eaeI*4pTLXSBnGDs1z6?8jxW zf3RMpUQypzI-QRJivNA7L!qWjzJt^Wq663~{3S-%>$&>4T9Nwjqh~08#iQU|?r_N; zo$W7r)tQcii+hQX))ZJ=EG;uBhN~l&sO^~T-h2opuq*r?yLHVQP&+BNI9VVoaCL0= zid(LA+uXVEdQ>|}=yBegI8u%Z`Sa_>VY8l@6ZCv&wYMt->2kiGA7jift$1J|avIKd z-c7$v`M5JYpFl02A;|=J!Y|itn<*JhBXcpIcj!Cb(>e7(hEdK$Wkb<#-IT-e8`zTy zxP{=rnkN}v7kIz5`5yK}kEWPcgr2XQrWO~a8&*6T-06@DqOg|pzH2#wD!EuYWzv#n z#2ODPoJMv|Q#cOOKqF;@E^}{d-JM9h54D6iZTn5{!f1&5F7Gt^7?Sm@W(%BVp_WaH zrl}fJ^YaEfS(8;d7HkTJ0P7b^9h4F8qsmTFP+kJZk_9u+r_?@#B{AnqPhUt`fH4Cn z=*4Zp@+D!S4{MU~kfQS(FTC3A5LBHyvz!H~q?#!swpz--dXtI?zA1t$^V>+N#p3?z z`q5~+=}(#)Ify}RR2<;|clVENXI5Xh_>e}|GEJ|j%} zvw<>OPo`K;)uq+YKg)4VI#-fLJHOD6T_*c8y!8P34f8c-L$kaV} zk~{D{xo#lWvNH=zNNrgp4VO;zuY$=xL^pbw_*b^(oyOYwD>HH?P zzl>f)Tr8F1`ysT%Se)Z$=2|IGF_qO{q#Zge5AW!>=MWKPOoi)Bm*R7TowoTJHw6#m zr;uk4_l(l*R!7B^p|zq6u}xuZprHmbcQ9dB6>2fw1I?F2WteyL1EeLCMDxR#l|Mv^ z0MriXc69m`aj1_8^Y954p5P25W$0X_K1^(-hwJtEH*A0`4ujkR>sTtPB7yhSZFl4P z;dSh|iUc5?X1G@0AKjGz<*Rg%cT+j4Ym%#ok00MF{{t+=&o*oi{>pO*e>gV209%zKfDZb03t>=y8XcrNMR=K`s1>6qRCev+V<9yt>{$d5Ctnt==FeulZHB<#@o!J{W4n;cHSohI(k=5$D}?AE(_xEt-1N(s8|xA?)@2Asgale zMB93XHI0M5RzW^G2_r9$xUt;~X3AsQ|A@vPxi1k^k&lc=&8^^5VR`*S0cFhuCuQWgz zexpy+937YQXyVy#HC#*TX<;TSXTe+y{hbi*?r?wYRM^>giw+?Up+tq?gL7*qaJIPg z7n6P7>aqh>^yqah^AWt+Ox`oSw1|o;*LmRgRa!GPU6OBlOqTX8C9i(2xh0w>jnL~e z-`IGJxUc5JquH5Rar(W=6>*m!OVQ$BJd~d9(#=4Gwa@6|*dMDmQ3}j$Ze2MJr9fj( zHN8-ocWu99o3tMjKo|Gjf)KGg?Kp!xb|ralmyp5E=NlpR`)Q=x*KV-0xS*m!?%?*x zYBd0DA@OF}RelBRhI`AC{0bORwhx0VT)SxMBW@W-q-jmg%xaq8C!=K7M6>21C@pUo z+cqP`?;8YJGK=Cp()t*;_hY1sxm=F8rl?2gI!`nVV`;uVuO=qbP*P|=zi7##gb+6i z*$HOq>uPvB9^bm9S100I)HZK_Zp)X}%cHNjBU|=76{VgDA@-PBgiHrzx7KLaV+xf6 zo#vqp3oIYD?dCV|D}<&ma;nsMPmFnt?Notp`W@v($VL;41WpbHIUmNRFH&Db|9}M> z$p*Yx}-m!hpMox~K_}tFVkD zhVZXd&Tu6<`OCn2>eu?JSrv};qBIWoe?7%6F$!Z#C+KVMil4=pk^*iPcJA16J z0U|Z|OcYFHW*ExDI?O&IZNaM(4)PKwzHbUcld>-(QcXob6BS88UeJP_1S7%W=0Jh< z5{Fo>zd5Mv?rkzhjoI|j#kvXMs|UQt&SlVB3>&z-7>z~&$io5a%9~Vi1QPz$R_F-~ z^hbORo|oUte7#5hPBUR~9`+0QV$q};V`gy?VS~S^vb7q#HI$kg#T)o?>w`-(_pfpX zE!Y&_kL1H3o935?#ow?kJ}uL6x!mLq*r}y@8E_tlTC3mqPFvya*1Xeh=8Q7l4q07O zMoqZ%b4!MUZ$z;u469p>FNyEF(!Mq^NN3Ey+Kb4P+1fL>wod^|(;l&`Ib7EQRr6W? zfm-Z6_%Z=YL=L9n1gTE&qv6dMu3P{ zQ5h2HlzWonYA;u*QjnhrZ@CILo;k z_fP$p?WO|`#(iJFc@m;s;n&KER?_IS=SXKkNUFANYO^GNJlm>5fM5k>f~phDDj2m} z&ycegJtdY&m#yzD#dxb4`ES}f>TS6^20@-3m!4Tk{~9fpVZqROu)F4=tR3$#KMwT; zLj&R1Yy3#S2b^oayjZo0!P51Yr`^8$y6_OZtkx5TQaya*O__`jv8z0MXC2Ggt?%%}rE4<4V|BF;JpZg)D6d|9=Z}JJNd2f;MQ92fTIpHZ%-txK9 zz0dAcInWE{9D#lD2R};Vc>|GLS6b9b=a1UPd(eQZnj@tRp|x)5KQO4Jr^4UZeiK+T zQ*6j_p#i=1)SXW1_Wj$#5G0RA$^IwkTOO3cI}E`>G(al*<9I6|;Le4|B#U^7hbJk; zQgYz6C%KD)rZ)&jk0gzo3?=xpR26!CWI=UwskN6ch7@6Y&5z=cMo~dgU}k&upl@PU z1kmY2podD+z?K0?rtZJPN!~TUctdx>FG=6l68Z+!!c8#}i@tn@^Fi^{Q4uZ7yC={v z7#LvWTLmlEri#C`=v@W#T2v#kycIxW@|#V4OD&ZE*M@%rcfu~Ny#{fBV|f8jL@MLQ zSes(so-az(fdereaWB;UCbozSzfsKy6sQ_yjc+RIP{jBrZcIm#k5y~Gzd*a6I?L&t z3N6kqE>6&U&qTe??-A4T5sKJlMn5w|)8yie!W#T~pV11f3P9fZ8C4{D;^RoU`-Gk` zl=yZ(ks?NR755$FVS4(i6Foy5@^XE9_cMg)60m@+S!EbM9~ce}#pANoYTF1WxZ{dh z8BIkp8;7m-=#XD6lhdyD-uBwhpPdL1^1>HFyz~a)ERk5Ov=Z(AmagD{T|XCc1@ zwS31w@Rfw%g)QfpIz~n{GH!;2ZlC3IOyPua#Sp#PwkxW7*$F)E;I7$gMz+&Y^}`pj4LX!y>H!y{X( zh5H*o)8s^*=Vx$#0Yt0M|2=H+=P#89xIyC~o`gD*W@fUAHABDg1iI2jqYEU) za53D?iGGV?$C{B!E+PEnR0cQi@olDPnTc?Tfn{*yotKk4H5K3>p_-WYc-) zJE_wfNjd9RL0StgiyBw3%?Udo63afKhQcPN-Cx#fW!iY&*-Z7u6f%Zs0-k_F7p_4C zNZfl0`HFI_2EoOt3a&6eQ*Q&s&w6xqh_YDJ)&r1Bt|5N+_}-K1Avx2{qo!S5Ys}mV zjdk^%Fm1qZX-Smx5!}w!b<~zi@mr-7e)k-S*0ntyP1tNnZ zR4Set;1!bjVJ^*hU^n%*JO9^;b}v*}f#qw8+KGCDbAaYghg!fF1*;UAHg8PX9Z0yu z@K6eUa)N8<7o_IAj?uau}i5LI%ACa7>E%)hiQKc?7=hpD2)-rwq;-no$oA2Xtm4wmZ70i zFBWQCyUnGTv>UjX+|Pk?l^9hlvGlmC=ZrZ=^3r+-tx$%XKR`4{BAz^ts?3ebTKFCe z$2Yd?N-kyvgGYT$b*-31Z?pIXQaNsix`h{GV}}2C9VCNcW@$WS$Mbkub3xiM2Ypd}o@%39F|O%CG7IDLe)z@1L6u46L8`;mzn z5rcNVMt~FvH|E3II(OZ`#)t=&kbaNh6Ml8CkuA|u+=^m;(a^er>$&q9$)*RftSl2G zA}{6U6HO1_=1?w8Zq1008x`#kWtm6@DkT|V^l(uRLKHP|a}5rFg|(y+-8Sa`T`g5&LLu{c`USt04od(= zRkA#|e0vvIYrPnJICd)4$%<~+Eou#qb#e}ogwC*-3t~3Ji#E;E^!g%4p_u_>cx9NMS#jvv92Ca zjN50^W&^+<`OnjeylK(&OmQ#oEIR5+VQS2XNC+3#p#s;L&8F68q;)1dqZnQV0Y-9Z z8^z_pdGFa1rQGiiC+Lqu8?3aCLQE!!FBadYr0l6Vn5Buz8=BCf>-B(EB_#0?^A5ndG@ro87 za${ztHh}e~l;v_=)_xA1S*jQFRFHjnqJ9D4T@@7A;mjm&jHs9^af@A+>P$`0ul6EG}5fpW}Gh z(h`o<;p_M4;#V}~JDUzM*$~^}yX*FrK`s-a^X>rrI6~Q@v#(s%Mgv%tj_iPubOi7(18OhDeD=nvfz=Ma$_*jTS^c|BKT=q8Cti@PsJ{VP* z2v|L-8~l9}@Ko^2{LL>r>lzchJaTYv!qw48O<83M5F>Yh?_WqUGh02a+LZj8CcldX z@jSI;V%rX@i4LsT9Wdh)f?Kc6PF=UrP<$VOf>4d*9tH^>Q95AUfb;mHtZXDM@zrFD zD)4hcshi?i#4Y-L*W&cyxsl3QDG(mjbu^y!S89>OzeWgNf@9b(SV0!vR5>`}n^DsA z`58zG@!MlQ{o0Ccuq8-!OU^SaK#xBpvN8Jw4VsRs?x3LyF@Hee{c!JXU5`=$msSRb!bcm;BDem&t!AUs6Lq5f@$Iprff@vQ=ML-+DC~X3%qf zKf-@eTjX^c&wd%IEbHF8u{sX!Ucre!ZHqD`^vL;K>9yv{Zu1)Sbc)?ut}#jK{57l@JFpZMvEEo_}dMbWHg9%Wh_^;odmLJ1e{a(d>)x@^WSc6kbZvKyQT zPPLdO7t1dlXVH%Ca*wt}=ZU-=7f++F8Z=@D(9hj~=WfD#U$_&Od#i|WqH(|k(6A(& z;R%!>jObmNF}DiP-lvq-F_tMF7v!C1#+1fO&{W+tWz;1);jT8;F5srgs*4g|$Vq~D ztZo#{Z zS8GLMwA21C+C*KCrwDeJ%Dd}Jmu+$vRX>!QH1#h1*&=>7G&@~BO)qS4UV>pn+RWP;=J^%cmb#d3k63|8)I`^ zW!Qm)1;2NRn(^s8-TVC=bj=p6i5l5lqjLn0muiQ_T$gHhm@Mw5^%XqRAVH}#a}ugE z#;SEd#L-CvBbWB}Yrc~Euet%}R(5ey-J+w;EKs6b=($z!1YSehrR*ncr`??m=0+#C z4|^h(x+^lzPL+kDh(uF0&CwpNM|l!5 zUoeDDLal{9U$o>_pP#N2JxOv6Q9wLdGD7lCpJOsYlx4<@a%c_~FWvBWsf`XtKR}$> zCYH2{jjRzKYmxyj%^AG)JKSn^JKQZYX>F+w#ZE{QNyjbbmv8LeoL^UX5-0ZEOp^Mj zFAiDyc3B_U& zkpDm(b%{7Z5^2^@g%i08&2MAx7jy=jtmA;Q@j2x z;7PAd_MuTZDZn&a{X{s_OgkzVRg-zz`FvTi#zLHz@za|>V|HTAH0qKn>{6|X2y1~@ zKNEV=8WiT!or})AV-T<(#N8rmJuzok;X)uox!T_}ZsBzOJ&b2CMpnKs&DNtm(cCO5 zcH}41VQzbRMfT`-!o>x_gZYe0mruKvt|UV_+@1*BcK1F4n7eLKR;pQ6=68GvZIb6<}n=FBmAi3~K0NvDl!*Z@A=6 zaX#uP;To-7Qe_q*Phr1Tv>`3;N)Jx7ygUB!N8c|G;`9ZtVYnE9elQH{NUt7X!0236 z)oy7xvsd+?xnH&>Rx#ZaIP92*7hs)J7tckRUJ(V7EKM8o)9okA)Dq%=y7!U%C`d8+@j9 zu^Ew4wQ^V+Y%H&j#D|w#{}??=#Bu@E2C#rqi)YRYU+xxZ+nbb{VUCA@&jRrFCLk*H ze(KRHCBz4rflR3*SG~1Oq&9wT9njB?PbtF_uqTg^TG{=Oh+P#Nm`?4SgSN-FejZ6} z)*@Ocsn;Di_=q^%H6P9b1>#-M{_vJ0_UwSmA{`$R(jM zsQk!fr#zb(vq^veB7$wc1?$ArK405Snb`5r3FCC6Nq$52gjnRSRDVpx-vTU9N>m*R zFBr{puu(gt$4PJi9;J=&UPatUd#cOD?1*7WpVrkmo>X_J{{p4>G_Ksyj|hF;9yx@Q zmXrEtycrvTC}kmx6^(@g_4Y!~BXnup#|vU5<*3AX{$&Y&RE{*+Al)YNR@zaU6R6R?J~t1=zn5f5G=ArED`bD_E-~5*O91Z(9a@*!uUVEWW`42A#T!`~-ZJ zlE{FPCFcq@VM=kjlb%~9P-+g(FoFq1P5Z_CQq6`_=kqA&d}6v+Xk(Kw20djlbFw@y z-g1*Rt2|GUbF7>bGO`ION{|qZvVt`Q@aRI0K{kLv=zp%vCJ|P&FSWbv8Ffp_3OLOR z)21VwmZW5xToJqF6i~D>f!zt+@3tm3@aI{vW6U_r^{H@%**j(1vO(~=gcN>K@n^mX z7ZIg0krxQ;T>?F=rDITyx_8+Ue(fb;k?QdZGdxMYEZC(eMj^sYY94S0^x-&93ry^E zhki3D=Zi9iq!}K#szz_*XzzMef-`KZwyrGyzqCRL-6{6g+jrr%dvkA|sFAsGb^4f& zJKbhXl`1g+M$qMz9yDBbUtPB z4xkx&{(9O>FyC;C{)Y}7)8BHJ{vL{oT2 zoVFB>XZ(Ugf3N}d^Lxug@P_SpzPVwN_9L~|G;@O5x}2znz}@tmjgb;y!RVLc1Y;fE zM}T-YhbCJk1{=O1@&3G4CCga_XIq!d2?8_P7(O^%CCNStQ(o-6yxCF|QAG>n#5jaM zPmD)`aGcTz2Xzq(-MLJ)jAeD<+^yj_NW<%un;V0ZQ!el~(9~u9Ew|*9 zr}bAN&ppVKPlhR(N|wHkn12N;UCG&_0+K&CAb5bu%8XuPlq!C&>i;N`V8uFYm%|5F zu1dzfMbBPxzToIV-qH9FuoQTK%Od-Qj|IICeTym&0ovi^7xGi@AJPZQIl_!fScE}U zV23O(>@&>90R0|q@teRmWfBTce|0(O{$#-V2ec=%Ag!qO-_asu=+sI4nQ~yI&Q`W~ ze?cT&mCZP(ycmCf;5<&Eo=2_b-7X!w%zS+-R9 zRp1o?4*`n{Wd%29Q{iB9;9-ohZ=&zT!l#uFH9u->4J6;O!LD3iy2OR-8L9tLMfqO# z!H^|MSQ48FjUtl%7asg0Ew)9fwpuR*zcaPpAw56L&TcWoT(6MHXwa4Pznm?Mn;@BBO53J zsbv>ZR;~)V_p$3 z1hG;7I3osaH|(~nzol1e0nthPa`+N3KBH{k8P;W=n9-8Y;yYo{>s{%1PeZqooJrpFNd?B3pgE2*8C^dpW)NM+Cjq(H&BFz)ZlIF=S>Lzeodkq z6qbhzM@Iaj>tniDbNw#U=4{$%)mxTU`5d`<7!Y@=8tE(YtR$y4{89LZq}NM;feaE51bz)Om5_{+MqtD;zm}K22TWLzs{6os8wjI$9qKn zg=&CAWFuoA_N1ft3j}~OEiaKUR3nnizrQaJop@*hN*$PC?3>D$8vF-+WhF))*XCAw zsgF_hp$KH}rl-PNeqW|;iR6E+TMBZnBZZtm$dQJvx2Rr_IKE}~4?z?a2Rs+m_-m{h z6k`^U97BwU$V99SxJqYV5#>UZ)$uK@W0e)_^UE#Z6f@4I9^fp=FcLb~(wY z)jy)2nNL^L$3x?c%Fl{Vz-)4P@}P_7t9}aUy)c@Lf`7Z0&3nVAulD7AJ}=Hs(a6mG z=CnDuskf;a0dI-2BxU`hbVmgr;mcl`YK;fjt`ZsuMUg)d%9*8K^HdVk!=jDgdG6Te zIPXl(QJ&pgYo}ja!^DNRZKpcor?6Z$NKNdKkd5?nun{YMSj-5F1%4!|eZE;dgU*w+ zI=Faa7SyJD-#qTGc)pr*Y6zYADes-WzPwIM$_pjx2P>OXL$GM%vQB+o51nt9Z&OE3 zFUN!yt!4Ba2kN>J2Nu<1Me)Jv?pi;t38%Nx0c`k1cDu{wz}}h2Y}0#stQF!P^{hPb zJ=)Gdnj!Vwj`j`0sS#e~gDB#Y$e#+-RzLn1Q*RX&WuU%qqqMXL3@t6)-5{l;lyrBO zbV9xb(NL7WRV8Y>Lw`!mw8rrg z5APy7V%SUPc5B0L^Io|q$JeQYBSP-A#MT0Bcq*>3*dfRKM zcFjFyc@nDH9cv=tn9=1T;nc`zJPMT9ZsQ)So6g#*`gev#uK7hRWFev?D0R`yo5D$5XCuA(*YFs2j$`4)`DnY**ouwC48@ znY1cBGX064c9N}On*9%9To+`%-GsrqpGXQkOZ+;5e**GOCxCW(p|+>(X~z+6ogKzi zZ(;9i)eHb5TS%AX((_f|F`M{$sWjXAcp}ww!jstge4H_6x}B;)Za@P zfyeb9;8z#lhE=X0&HV)S%8yvn(y|YerI)~=Kv|ggsGR<|<@SWl>0s+Cw&!}3Qo|Ze zV*c>2c_W5LPi8IGZJT`)!6vXFS$Q(qp$)sI#7C7XzFrq`QpOm@w^TpRO?*MNthuMe z(5(d|#%2-0m-E*#!Iw?WePG%02UCs@Rg}Z1pPG;S^*kznCQmxapH#6lVKw!)9s(-w z5!Au)ajuQmW$zW^t3AoG$0gyw+|tjw*8Ig5MH+zN=Nk{b_49q|;{57tG_8wl@(W5W`|2kIr_^_pAZUx3r$%%p^Xy)`M%%^cZXNOn+6W8Rvb+N9N#!9hnD*oyyZp~Gd( zH%RK`Xs2kdsy8=Ld$&2+4p=Y)yJhG3oh^^kmf5kzl^bDT8%UANq(|#^x1M4;%D*bD zVa=Tm)Dn#3l+@ylmf@%MH9WirLR(d1y{;LQHe}O3JwNTXrPqH>>HjBsbGLHaYRmyC zYdjF2biCgd%tT_iL%TGeKJ~hNpUmx$?5c0I+&H@rKUz>+Fx2`&u!~w2 zr9dY)6Ei0VM?XcSLNxzR7Psi)w5fWjdkh>{oje|Umr5F_Byy51Nz=tjj+9e}IbtCb z7b81;Grngf29_?lAcn<3$MpFCon_7<>Gv+)h;HDz^sFF;cRE+5Gi{(j?M8`aJ!kuAz+E%zmfF% zy{p>1e{FWjYd8VXA{|PqLII-Yl2yvI53k~7knU4}k`aL8Rk#|DOz$n5=Ur^pw(0oY z`LXy~8HOX`4>Lnw5hV_NV+;T=@HXCU6jct(lmvN*=d*#jBB$&*IPq|Uo)|Ltf&O~u z$v_nR*jXR-hE&n}Ul04InX@`Nqh&b!k(bXl!-wCt`-j8{qmd_jea_r#P9j(k`R7p8i zRr|4JyuFfB#Lo6)6m0(|d~z(Et4Jb{)9s3lEVmKWeA`s8;yZ+!^bABBQTOO1LR2nDb|F8q?Fb$$a>g1eAIMO1zflV6$ zhEeN=T++YER?WUkeM=q^1q&MAS{Mq#L1SAl3(VogvqL<}#J>SAxy$;}7--^Ev7#hi ziWVfMfjVD%GbE9lJY6`zQkCxXx%2nFw(~#~tHN&E6x-9oeJ=xxpL!15(qWC|b z#nkAqaI?w0vm%0~g0{BR#)MQfK3n1i=T-ip(^x0RRLdvcr?Y1n_fLxN*_rcds;>@p zbVSkkuMh}bw>qBi`dEi-_;X8!=@D1Og5VVY0s>8bB6*68 znH=@`G>Pm+^=qcJ1o;a>sjdd8l(8ssb zN|%jQRn@lZMl(C#fajj!brs+@*E_yM$CbP^3I4FKOv55i-^NlB_F&3{m4-(WF2;vU z0ajVJ{<1VxDQ7K(v0Bz8UTqu$tM3S-6OG_WH^cq?w<(isetk@`Nzl)p>n=260kSat zK7=6onp?Xg9;PV0G7)gaVbAMViC~eAhLm zG;XARAuhbEsRC!Cu1E0QC$uJNfvLTPWG96a2S)!7@^6`qkX&2(Ao$ zlL;9QQ-ToHxRcgLz8F>ffxvPCqcx+Kr-foV`3@j~qwR8}z;L^d)ZkZ-?Py^&tlI^?K>XYz4iPryJ~OP)5tG z>+G{{|Ir?bZgF>U+FEIdGL6YFo*I)SuQyt4!lfIVxz*|Ka=M|^76w)MD9eF&dHMtu zHJ<|s%dfa2;>&+THlVR3Fl|Ji{wTRGamiJY`4KMRqaYI@Z>(<;??6FpyJqw=Jv$xU z+4Qr&nXnggIFrYp!G`Rh`cBk>Pun>qU{{<_nE)x?!=BIG@ZXc|KKx>k@(XSHY+#0t zFn$K;6eyH8?avn+PJ=oVUl@8!ElGQt_C~mazwY2k1ZP5crwdo#Fkrs_=q<4{HsXId zmh@I&bH;4pLD%p#nH?-_N`s6aqaIE#4txKYQcok~*sZcJttIye0|4>hUzbg(U3T4W z@cm}~(A{3waYj$yrH!SXTXFU8WkCQO{iD3%J z{MPpnH=FqW!EeVb4VYBeo#3~qoM-xF57!+fLRH#PazqF`=*Fo2>p$<|JQ1tBf3p;r)jN#ex@xdpH`Vgo3?PJ{V35DQx0fi*R6it zA-K7h(I`;40rQ^`nLU5k*BwscjyA1YAM5&cj?1sgeQEjWZVA7Zol4DmhRNo)o&oMx zPF3rg_i_=~mv}uMo7rBk!Fru63wjB7P0vhU^^r(zrDV|0Kzd4Pe(k9rg zSX^#X1ih}tu{bNV04N#>G3GeZtTpw3MER%bfuij?$=5OM>7RdUMBH^p8u{7Od{v`N zdm4Bu*|7q7vsQ{DqUBZX65*&RP9cAy_Aou80mPSLcXUv6W|x!*25kxUUJPJ$ySRZH zqJ*LvC!ATAu$Nsb8{j7XosZUdul;XH*d=SJOOpV0sX?b!^hp+@inULBLG(=yHK#NC z3&Ba$5d?;5qCSB1(4(N<8XAg|8o49xYw)ob1~eaRd+oMSisf805$iCHX&}n<^5k?n z`VRRae@%>C_H8P>!EAd8c4fZ(WT!L`-RZ~HUbCmO`peOgnf&=9bxg0*WJ`=pqBFBm zBvA2Y{;&owm-C&WAu8Sbh2rv4xTW^nU<;0vc)@OxrcpUmfJN>k)$IUrr@z7^!!uo_ zL_PK~in0DXV@ra-)4KEJX`*MwNy}{{o6Smu<*E9m#o0_qVcYw&}z6UrE66&oUSpA1&HudYbJ5pTxivr@<&@3~M6oFHAP)b?B z;bg{3@O(Z0nvduH>C1^?&qz)rLsr%33vVy@>0|{c2eV3F0Uqk9%r<*uC|`|Y?~1EN z)>g+JQFm2|-#jawp!&IejlmBO+JA0=D_5E<&%Voo_iM{O88J7%FR}B|V?lmC)!$Xm z+h>B=ee#sx%7$kBZu3dtSgxCZ7qI=%mVOOSr(v{nHtOvqHc_S(Tq^ozf9@0$@tN*i zo9chBxVg$1CYRNF{vJluQ480gGo~8QauYIdO(N9H5}^{X{uj z#N4Cr8ILn4#_a?1t!~#G(4C+V{H}$Xl6w3t+MpKEGRcT?mi6kV;n@)@Aq*{E@%LZ+ z22C)%tMApXG|{vNIBo~|stJ*>>H4%p6Tlif51Plt_U?(Ll(B3$jy>N|dOS#}8-IgY zPFUFPi?YIavXwz6x@84(ID;j9j6K9Ob@$gSIe?rYJxz;J#+f6(*WZMTf14Hm%sQzn zv79<>C>_oO_%RSiHgO@~dS=E!!Un+*`Wer_5ur2fRF&5Day|(_Cb=J0=rZ71`=bNbg1-0$G{F5};h(o0ZYtBbNTnlfjOlRR!(<QbE$X00dkfm$|`5ssaBN5C^y2S=tKxE*tbXYOVKb~Jb-mmCQ*C)ADof{~Wt;~~7qvgc_ zRxC4emuA^&gj~`PbI-+oLFQkf^@a$4zc_E|)m#ib;@&Z0KTO9v91+nKwn_F7FnK&; zvqMc|IX%7#Uu5{B+WKT(+hFbVCQlsftRblKsW(gxtElDl1ZkBnG~OcP5ZbuM1^~)J zR!4h&Y&p*w!$Tz$Y`Qfp&{&1mR*+=yxhi*0UQb9W7>6x4g!>P?ba<#f;T={X(r$n; zaNx19)WNHb2PZkeHDBK-`5^VX7TQ{PEjA7_5yoF zfSyytXW>^5ZBSfNW90^z_F?-;%<-|WL!vh??boOcr{^%yGOU+ViC;Kb%1NI$WZ3;e z7OP%GYQF5Wwt7`X$1e|k{60TS^OU{pMk=?{hq1sG%TYnnhDqT)Z=0*7O-AMIl37wr z9DI1Ztl22Tdd|qJxpyf)XxzuHXi@+tF5mWcJmvndHWpne*UOpz`O#Hn6c}k_1h^lD z6Huj6X`2XrnT2a&o>@*42&Y7!XX=%?{Pv_Cj|c9q9kqf}_w^MYd3HPh`*u#YJXsuu zkpCz<~z+#4^lI$D>cVbALUveBe$E`?f(a{ z%1bjTTffKZSb_onv%Dgy<1=*Q1MC%Ys3~9$`~EW>Dm>;b`z=1hVA3o3$4i}7iR5sm zX5#M30+T6t&cQ9e+Na#gI2>%w=XQDXZE4(%LS?%6tLlcLE?L)w17_LnkW$U`>VYLj zoI@)c5!WCGL4UKVe7#JLuy_?BKftY~jnY#MSqR7D<=N+9WzEBG*H6Vn{lJ76+#yU{ z92*fMo%^2ho=)kVK@Ih1Z1WL-rFf#$#iD%JwVt5rv&k;kLSW9!;+d+WyI5O#2hR@j z;ngY1_TbtEs22i*L7ED&A_>{%%o z>6OcKH)Po>vA}F?QdqvBI>AOY)X1Z&YhKAf)2;?nV?Hn!OxB-uHv`w ze<#$4lALgen!hO3H{}1j@Q)B$8fyS{;uBv=;o*YWjw(?c+A7Ml4S(@&?M`jJCUKmT zo%CA#mi#o^@EhM~9&N$T4?{NLWAgS_o;9+3HuX*OE`%vR-q?(A+g35F>U$aZR-*e9 zbDP9Mqf7^v)l6lJQZpBT)nSrB%Df6>wv>DG6U@^_S7bz~D;I5NWdzT6nYlOe7r{-tT|6r9r zUQ(qcT5oqd%XU{bfDW0IW_e6fUy4CIJytx97n%zQn~xI3HYu#(H#894D+s}0Cei-f zvj)m^C*em8q|L-h8IZr(QJZ1jVpudj3|2VL?vr`@vNOHLsleLb6N_>RcMD=t$h_7% z2d_lY9dk*0f<=U$^Qpy?4aBtNm4t$VLhVM@_miQgKpzT7U7!Z8X|fq$jUUs14uMBS z6FkoK8zQ8_&4&!_=W79^G{~FC4EBAOw5x$E*itQm#JI~k{Iku$&FUvl+6{bDfvaoH zJ+7JkGAKR7Dt>>s;0RJ1W<$*wQrx+#c;{>m0@a`;K9U}N?oWjJ%kXFvn7Zu@IU=E9 zuX6~q$vEuwAq;y^`x0c_UuPbnvYv}4OQWZewpvoV7{8PHX>wa zk)M1K+TE6g8`Lrw2e7t;0BieIQTw|6)b!v5>2FR|*bJXNyv))y)B#=_dx`r6K-@06 zvi+JsR(~DJFg@DBWwU;`sXou8fNR>WZIZvO%$;g8?DcQjks;3O)T`$ z$|i<PPy_5oUuN zF6a4-#@bZLGRAx87J>WODfSY-hXmBItNx7Kb5`ffa7O!7t+b(z(y6K^*Mr6S2+AV> z_R|`%6O@bnB^dlae0iPgKa?=_y3GMTj`+*6GygEx7GYlV#fpX5L)IzS08>YfW7~+J zlP*FyVmqu7l=$3c7n^aBRCUDWlKqV)QEyVuZfObSWIe7!!DD=Wcxy@RYFcAro6s}<%$R?} zbM2mV+R5h4X1KL? z)pSqISHCn!m>&5{v03j#R7-7aIr((WS8a$bJUx6{aNE7NOC7y%Arg81xI2kvpV~Wi zB>8~)e^~&!ug2=n`Ky!F&@1{!NnD%faSd!~mnt*ZgE)38L}r&N8`8ZFaEY*+U0_$Q zQDweBD*U0)Za$oibIpE-uP+0(Q=1C|aeZ;ctGXL1TvNUn4zJ{%&T|kRPz}8U~U3_FJY{~Hd5CQnq4Ds2^k>0zs_99-eLZ1 zpv_js4%rct=N$}R!{CstJAgdjufSpV?6At(QXRxkg zf+*s^Lk_g;6j*0WZBgIq&WSVZiKr3O-CR1oblWuf*$nvA3=eS4;`9UPsL!lUDYK^J zO2#KK?p8xN!N|Dh;w2$LuVif|ff*BjGWJRFt?YD|{3^R(s_Vjl)Dc!`thA^|#mZ{D zV~Lt((>qhF6E@8$Kb>$b6yq|;ScE&?hQ}ym)#qkT=pi5L6| z_tYz&AkK*$mTt9)rYBZY%z1vCI2@Dhva^c4{-_6P%MvZTjz4CvWDn-&OgIvHEN8`9 zo}a-K2P+L>4?U=3?GM5SX^Udd8farXrSA?>oT*WYjpp;b@F318C>L_QPHl}zrYple zH$C}oe+^a$qs!z%%bX@1NnS#&xsj+=y`a!MkCiqnMtW z5gSYOf2b;^pP!7?Sx;5)jtqy2o~K6bepxRIFBfr6VmtKOrh2@tt)_c;4mg`l)}~dv z`Uv`+UFW%L<5&?b%K076zc3K&h6*1XuDv*LkDv@qJ_tlys^c9I{y9l}MNdjvJqy;pgC8i_J&8UNWfsmyGy4kxW;x!cs3>WfqIrg z=z+70gW)*0Bh4l&qT=YWa(Jq4vSx}q`dPDclRK!_filvBGjjKj>_XS|@VSYvjKe)K z1iUGyZ2?!{yaI}d?Tu+mJ6PTRz}mxa@n~wx&^tf+ti6%i!R5Tpb-(ADov1RR)urRk z4CldaQ2(7z<>RO(k?8si*n}Xze-T7RFuZ+kh-^RmT-}AcJ(7pRmA|v{m2i{GMkki5 zEM!A-R)T*~!tTaCm5|_Zj?e{}LKY|iJ9D`S->p}%YaMwcKG5kmAv%0<-lB|9Lb%&%;sw19$|0#$~|MS0k(IF4e9NnhH!Btl%=|7tmop}Hzi*F z8fH*fJ)!#Q&6b|RH4^P+T3Ui9U2|^15%yb7IEmfJQXzE{R^J+SUl)YrR8{NWI8Oed zvU2Wgb$U3hSpFO_(xr9sytqJEKPlMP0UY4fF2cPjZjPbf#cb;V1t!5htQh?(!l1l0 zA{-GMI`%U%l~Lm?83cGS-Rz&dd9dkzMl}T%dzeqiJBGIluyi`Cn{0gP>4O~rW+XY; zMnFV}Sl#adgUoeRhON78DGPb+p|a4XUoUVIVjX3qr|PVnir+>d&2cNsb<|i&$}~iN zYuTd}Ib)qJ!pb}}#rHARc+&4nlDur9eAfu797sD`~GUsE>y6FIr)e~24Qqu_wIiUlrL~C?w{tjOZ;xCo0y-@7RIl7qO=O&J5`cP~H=Re6 zZTxhY#!I#z_~h3mL!>iX!&#iuZ=>olI&3l2I^B%h_9umsfTJV-19q{(<-s6;I!}@b z#-NVJu>D>57ubz&`gF2+Pt4FK$VVqIeqjg@qyBjMFSLURFeM zTx2fTa~K+w#oQh1zg&@BZ9W!p+a4@~YqktqM4k$K=l)Ds$nk=3$oqcv2iKTBxQh1p zivD}$Isk2M0D6aqNh1 zEI#E~&XRd69_KVEp`EBx0RI>>rX1c*$8qHve?J%`Pq-SDX*ad}?mP?WA_@UNEj3$R zc42i2()JFMa#b5s;fybz_1iFC4TpqI>A~B85!UR-K_IR(mM^b`40^md#Q{Zl zr5ccQl7RH2-^zyw()7chXnI^25wJ9sWU4@TZEnr_?6g{sI&)ic!>PE+P@3^c6OV-& zZA1eo%K-M0p(_;5Z#?LV3)Fp(r|sZfuw?Ye9fpXEI)HaV0RG+VcK+TPK1>bOqurc2 zD@yt4Uw&2;QFHhq)4NZhqQa<{o60E|`s~a>B1Cb227F**af@L(FPJFB0+?iXq53f3 zcLel*6qQb5F#|Dwdf@G!Y9qv-GKC#g1K!DtM_L9VDyI?pO?Asb`a5)3A^D>Zk4uaM zhJG?TVVMuxB+~o687g0!GyDpMOsm-NT7X&LN% z{wri_Je?eBPXRfL2Bc^O7)u%6=cWJaRYJb9wxr$mt)B5@@Dsux; znQDtpB#yf9&lkH1@H@D@U04TA%qnZ-u@g!9*+3mmw^z{Tyr(B~7wR71?dA^1@Bt7i z@rRoFC{9;byRPxX;`{Vcm}~!LCB3y1{3$64-lgKz9;(M9lz9opD$xrD2rH)T=?UQ@M@zFi8Y$nA5Pm)X1tWfmdd` zQQqF%{rS*ZRv5e82}>M0)Y1L<41yKyLHrY969A!+ya%j8X>G)X}vj-JRS4-cQ zjvLz^6H&|Tts+#9ne+4SHGi4W-AAl&Dc#OGRb!N-zlz4H-}g2Ca*SvOvQ3tNHf6gu z)UxjX&D{zwUwe{IeOlsnjzf1Ypz@cxM>s!>Pz)t*pxEjr4#2O<;C-6Fv{v;BphG#w zKVs6y550F%{o4IxUXM@c(B?9>+>Eqthy3)UFZZ8#reY&COqpS(a(hJPpxGewyo7TN zt$F5l2)*$alW-y+_5|)=0@kC4B&f-U6h3zUw8+@?TrZF;Hs3M^Iz(3wct-|h0DnsK zjx=zB!FG|mp|=~MP&&PT>faLv=X|nT`+A0l0t!#3qYR+}wmq^L^(6Zy&%=nCrO48W z?J8ukyDrgvguq_+^Ylbf9t=qrvr2)hr{z`jpBX&z>?vSk!9Tg_xV1cH_-IEh24 zxr>rvyZ2;E3Sx0Seu{VC;UpWZ9ljY(w?nA3I(AF(9q$oZ`?%r%w}XpN+%%WSp-s8I zs5dGI_`x;Z`Ko?k*$uJi*P(Y*ep5qA0vL0&Bru%!4@Ns-962n6Olt5q72YA!g{E0I z1XxtBI2QX6Nm$cnFXi-dP?>btB8yo}!;Hd)t2bd|yNNW?i#tjzxjI6(?fJ#U4hxf4 z2IK7ieCJmPqkfq4d%r6VF4m_(-j~$BW-tfrduL#7r*shz@EoN9W}wZ!tIP=*ZvkQH zP#nWQe=9a+iU%5tOCY?XxtzNRfjV`H%xxa`8w_}_n#0?LW>1VgN`qx@DF)jc6T322 z^%lbor<<&_MO`*iflC3##c+NJhfd4IpTcW&(4?bqEaFB*5S8>pX!Pc*e@yx^F!B#1R>s?djY?52n|2xdwMjBuqt%E5w_H&aF3^l`x2z;f$g zC9ONROR&qgj0AaQ_4h5sm;tih@`9)uB@vSFh(i@GM!?4WQ zL%UGoUHusCT*Q{ph+sGS^Da0VJ#vEkSZ|EQehx!2E7rC`JLFS>6sqx`5+7L%=w?zM zV-aG0^9E(Nf8F5)P&A>pwLo<@w!uD7kC7?(yl+Q5)b|#heDx2BagriYGo|xs1Lsv% z@UEk~+I0N6p;i>tm5k8q?j4)m#!TL;4Ck^i5Yj~#B-)|c_TcJvRFS`@+SZuN(0pd$ zILyvD8P2(4EdbGA0HXeocm7#_6d!s$GD*x%{?+ge?me}3Zo*E7^Rg2IznG+Ksu)%NPn$bY}3lYF9Fv-FnR zVCJ^QZVSjU=DL+7*~3D^K31X`W`@^1`m`d!QKXGe;da7a|${B(JsB=wk4?FMMe+`}p9J)aO9 z>I%GdwY{6YVO*NXOqKgE3`E%Lu`mvCiw1?Iznmk#agx^%`e34pI?hm&B<}*I&#I?$ zobAAPuk4_!)~Dvox=w1G%fp={%F|G0dxI|nt|-P_(VW>f3g8XDFzOwKMr9QuPMH^T zrtq~dmO1v|K;CY`@`Z-7bd`YMQ~K%sxGo_Nm{V?_{?ifiw36h#gb+_l zq=7E>0;=@ibQZK7z;GRPKV9N(RMWip9^=UN}!Ucsw zsbH$_c+K;*>zx{Lte2z;SZcvi7`TrMq4gLb_%O`GbpuzHk1{6tp8O~#tegYJ^Prbu z)_F^sKt( zZIF8Tnk~;^@n~)uKgIYh5WSOxO}z-_^ys?dzg-I8us-6j`uLW(yOD53&Ze7DovU@h zEKjd$w0`@hC;SH>2NqoW5Cha)V8c7&PjzYdaAlTf>3O`-%ho$5!R<*7{+whf4(xDs z@|#Y*d<+h<0ct$O&|smiL2IY{&Ct>X|7up4VW`6eQ3IJIs(#e&&2NK`IQ|j!yInO| zxal2j8PL~ne%|4Gj?so;k=2G2wIo&*hZ9?7bVxEJ{R`6^fM>wVa;LkfpH_tq?Uq(s zufMXfW^vZ{=^#~G?4;q)F5g1^9R%#=plwO z*_^o&{qkB^4ISEf6&)@oR*ZCqrgpwkJhFS{0n8laSi}VNp&NQC$%)@lN}5bnkKarV zt1XmSlAs_v$_?YhAEL{*ezKBKo<60H;745G2y(9aVkgPdE78JnG+|myArOXcsTwAw zUz$nP;iE>q!B41ZD<8p^iNK7@`B4ja9_dn=+9YAzm8*ep?S#7NOMj%p*-{Swb%NFx zYoJLS?0q=Yr8MN^JrsXj#k28`(NBs1xfUXa!Bq$#k$J(#vYL4A&Q zNk!B}|H^7C&593GsesNSFNdI5qPg@pXvO^b3v{bG(Lw)mtek*oj76oLG1~pb8UE^B zR>?%Qnc|+{>*f206KBS6hP6xp2tRTNSq-E`JGmyya3px*S4-u?;h^$bdjAhH zm*}~0Uv>YO=CWbe5YC!3$mLvh4MgA@J>c*oF07pe8kH_AO@WF`Ud)f`n0Wvzi^~j< zopMNwm-iBIluwzX;^pnPuv4YNsDl~jM^PC_ODl*Z%5dU7*tH~myUaCR?z#9dfC)Yx zkzHi3z*^5s(pp`pHB<}ZF#G{oqo?8F&4%i^VVa^CD4BA=M)sq%{?P+k)X1NCG2mIG z^|l^;=A*ifkv#dlD!}_+^XlFOG|@AkO1&sioSbB462i|)|0`y}!JfT{Fz|KR{E8x| zMsHM?HpsVj?|?Ek{#sH;?$w+r`haUOx$pbddmGWs{93S4cP!T?G5T6)9Z|(89&KAOShO zVp!rAlmdY{y$4Ya1BBlO6=lgHN|S%qX=htHY)`%Fh2W>}oHeV-KlcLXcQZWb<2YSJHm1 zxJpd!0y@XA$ia^~14W$e98I&9`lkPeR0D};Opsx*?}q>{(T}fFHVF`Ux?=sV=Nmz+JJ!f#_?c=wkLRkN$)W&=VxC|3`VAuv5Q8Pd9EiQ4!Lg@ zG@lfSx?X9z#0Dy|ARW-dUzoc zlQ{k2#e*euOx2#A(v}K|dV9dF3AFiyw|}qsu2`%lO7iqwSqBUX_zdp;%K?8SCI@`X z6UWdz9rJGlN-^#jTl#|Neva`{lIp{d@O-vyK&gm6HdQ8TLkzFM484k^NOgjfC0*`ms z`lR?XGp1{$`qmFF%uta0bBJTW7ihkaz}=S#<%;+sU=~Ab(Jty0?H zVOf^aJQqV`H+8YP~LDJdYK7joP1Fn0}h8LnVfUfv*1rNSsq1 zE`Rx5x%De<^@h&juzGSuxU8*prCIxGh*eM~g~RDGHo;-z9%?y7J}#eM$KxE!Kutdd zaH9CHyD|1*V9$6`^?dB$~W;5xmAwRR+rpLCjvCv027Ljg0xWt;FOlC-%`+3UR}F;VY>sMEm;OzFYUsu#NMx(l6PjG85O*QhGK}tfaBbl zjCCS*v-<)GVv63b^3h>HOIGf;R1njlg#gjobWi*wwAU0q8RpLO#*L13 z{-6@bmntTB1O13gCM577hI2f#Zz)zcUifu8jO#laKTzyfD7r5T)bfZbj9#?!)mGCN z_&eR^-~?KM7TFc%r68%AuY)doN_Jwhj`wXDH&(6tctEx*6f+;bzcZn z9AJJl<6+74s)XMECn{LY>9EAv^%=YoDOq*P+24|4)9RNo^u+gk>+K!p{r$+xt7e~~ zA2UWs`9moIq3Za1or$Yo9MO|ls}RK#KQ8oTn|%aU+-F2Yd4 z^E1Dig63UtSh82yVJ;VVBbm&*{}T~VbCGZDR#>0^y}5&IaxdV$_zBiH51o4C{G&l7 z#7H#Q?kL;7fys9T1|IU&d18+m0c|P&1J7Lv%H4x~q%68G@8|H)1bE9nn;(JfzWEuSw-Xz&OT;{2aN%s8$xL7;E#FmT}yPv?Vk#c=j`BBksKgWI%C+@9^~1YF2rJ>dJb=?*PfE*^0M z=Mgl=Z@0ieVQpzmkeucB0AE+aDQM8^(k|%kb%#mp@0kvhv30H04Z#-Y5Bvwl)*Trp z7tRU>qeoIo06?iDV}+ZO z=tL?mt2itltl5yw1zL%`V7K0FES)F1S1<2 zYG(xkC?2;&omC&HXv1tBa?hhMx8L|)zn=a3TXl1woAih)^a`{W00V+O_x^-~kWZ_+ zWyUfubhtar(ofvr1zyh|=5d`sN+4!ptxJ0mSYeCJp8)$9U68Bmb6m@mQe7mr7LN0P zvP!}j+nR?gNeMj8JfQDxy>my`ph1HNmjeuX{w%=O<`GCMrqrNO5;hR#_;`jorl1V0rt^{&{-v=YL9!G zDl zj2k~mm!6Uc6h<$)i%s;3e%4QQmzfAbO81&ewdfTV{aj2thAom>c}DvBzGULv60F`k zX@#E!qr0&7IC{9aNpcSdnI3}$b^Kc)g%H>D+`43BpwB|3M8nh`jM zyk{|;&d zV?=&!%#V1t$`^9CIc5c;gA3xZL!eLfD=e}2jn&Q9PfYix#z)j^rAXx$d$XX=WCgH9180^d92W%aN-%36vN-q z76p8EGrfMF?dL6HPgquuF^zv$cu({a{X!^ic^lEtmOat;D{{#RJ`?mC|F#U4YU;i# zBO?T+j%5&4J|dugiM&iJZnkA!U?x4)i0m+w);cpMQow(vY*h$N;0~eXJls8HI0$I| z`k>xmkHY`@^qst|gwm?%w3YQWZ>qH5{lGt4x4udHy5$=Sp6$3u{8uy{Q^Bf`UqBbc zpG?Ylf22X@K3EjWDQEKjFqZ;VI<+SE;~IQG9K-)lHUO;5K+$(#GHG&&Z*s99%5BK- zJgw8xYkBdq*!CRdO?Kq$cw8fxbAP!iRJWS$T}fNufq*g(@}L142Z(^8o6}st{$_66 z%O3PZCyQM*dVD=83QSKq$$MNmaer(Dc8rD3$6CsdQv$cC zyy?GN**$9l%T$i5MoX)1cO>#JD4&sZ?%oq;lzATa?*L^T?8L8kyF+r`Zu~8`M}F1! zPXrB@bkvqHj$3DoQ`3JdOC4PH;o7*}+#y`hEpv1(W_T$Ma><*KNgg82|HJIQs9k<87 zS|i37)|v3kC(qP(R>Mg5rKx5s38^>rhYRPvXx|PZcjyf!yL|)wy2>^uh_`4!Au`=@ zkBwS`;|rfei~EmMt$Hy}qjlv=wPvrecXZ{AtsAt9;(tS`M+17I^*&fpa|cigSTCIQ z)SA0W*E?8$TJcd{>Kkd;VxHRZl+`l@_ZC1g_J04SFK_cr78i3BOlvi!Y5@m|JC zx0#dOo=^PRR(m`b6oEyN_nw;Z<`XkbuoD={@8r+>dTPqEAge$A_V2-$RPYA5^KE=! zM*Yj)kf%*5+!*v7XFRLWelh~wgNOSxlV*jUS7vc*zMQ6!yLDC%zU^yjTWs;aTs;eo zhY14DmnAk@-<%6mjao0$7zc88?=nWk8et8?JzW2!iyGZb7<73zEV}327$X-6hhaYcNt$5RmSMkt3wLySwr1 z{hxC_?c?@rzvtO~UH27tJ4WWqcO!y-H>lg`JbEY`JDe|$90F993wj!;A6KotwdXB1 ze?I+`@p%=xP^O~)_uJFN{C|B~nU<+($e<4wg&U0Of6ottOP@kkA}O90l|PoPQz(@M z8d@X;%|5!|T*%HYc}N%^H*75L3c*jAPQ7+oXIeHWEnde6x_TKP!Pe4thRcY+$}N1y z^38G5O{SaA1e^7@{Ikpx-(ckEr`^9zntC*Dt+V`jc12=UPCwv@bD*Mnc*xK_;}&ic zI?DPD~9a+~euJ*YW}vYjh#I}ke1Vaho&pWO@O zgn`Z3hMPqf5z)Lp0&@P2V@=;ilOvnz(0Zu8DZarC=@ybS1rYZG$vdD;#so^-mPI(M z`ib0Ps(ipb~OeJtluO5z{eCe=g!&Ct2NLoG?MLd(B@ z(?`p=*XneiT=!-Ry-K+(Su4U$Mnt1ADkhMIpL}EX@&IFTU;H-+ojPNO=68Gv-%PAs zr8#6g#v)AR>p0XAZnby5kH)(}T;GU+1$EZPc3Vb0T3lnyau`UJR_$szuQL<1N9I}x zXUmxA*`v(%*vQ1~8b@DNU@ApBT_st6gt4v0Qj@u%UhnPZhG1ATg_6xNoU|QwFPNtM z1hbOb*gL$#g9+l=M|m`9iLb23{rap65H5#vFy$`V+ePNYWH_ftFcg!wWK_8!D{v0( zKbyyp8Y;?0=ltdNS9nVeI!N%(m;vvDFQ(o6w*Lrr@$RX2&62p6b40)0Xe^E2;O2LS za4@x*X!BISsbkTGORg>nqX-*wGhV142YzLT<0l5A#G7zO8Kb(<1lriSrA(R3z67%8 zzTpEFtNDd{^t?aIwD4WrPG5IF-=JU_D18SQBDYHVhrqnK^vH0Mh+RNBzlM=pF{u;4 zLa<(gt^gDS++z2ih+HrqhJKtC+p;HW`|w{$+Pb*{vSgeG8G$%e@@u+rBTgDOMWpQ( zm#gRgqb8Ia+%)I0(u&CP;ShKX?+>H)AI?7JwZA*}+g;&tLG}(tL@&adJPBht<=J$r z`hOc5%yvGd-^M3B+W*&J%4D~{rI8V&)52!Z1l1t}!Hd-ee6H;Yije<|j&D6aXdg2l zKxPz1c3^{t=H>opPJwoRlfFi^7|zw-UF@VZ%=(-ZoZl)K2DeUv1IYlK+{>`&U)>$6 zt6DLl_ZFkN7?}03*gH4(vxeqys@vZok-E0!BG2OYeX(DJMYIjhgL=)UKUP=06!#mL zFn`{=sQv>hpZ&I-`L*Su&VFp{o^~R@sC{X;6EAa?X5DNUXy{H;#h0Om?#FRKS)(|e9dI6kMU?xQO9hML{@9d4DYWAc>vTsvg+-s#W||pKuQIrn2fg*znZ~{i}7p2 zT2q{pW}KF&@CP>fvXlMNZL01r7H*08A}>8?94Ub<@gH1}P#B2xJ~7%PZ)!R`BcnMK z6*Ab_yu&Ii70|z~*8M{~?D_|k!XFK2uvt&EL4>E2y~7nwx~q|ernKv_s={zA95S#* z%0199!3gNBQis=s59f2fK@Mm7UMf<*fJeD&JsQKaT?7@v2=$X&Y+ia%G9b_h1YTt$x_0D_FS}VAa|EB``bSKN7`o|{)zxpKE z4F9uT%JlG#+9pRcVrXwYUf0KZk|}SnF$=hGEx*w2zxv#_=iS>p-VnPY*Z+^n+B&Q` zV*kK$Zix>rH&i}QTtwO~R2omna#)@u7c3G$r7aerp(iRyF3X}aH=*iB2;ZVeRM-h9 zBj~>Tj83g;3RYE;#=&JzBUoeXkmY($-vPEL7+#sT$)5LY~2GGI}8#x_Y(iRu9k_UFztDl`LV6IA5S%RGq`EDx>_GTyM+RHDyi6D zi3LkyfGxKT;n(C3GSKyf(RfoV92$d2p*FbLc_`PgU1ulxdSUccgv0iW0ve~1F zTPVFKv(B+vkItks6A!@SnyUn&`tzsAe-hn8z4#!3>r!?bp#fpT+XKi7)l?-m@o zFRv+8+46F_si+5+)X|g%gnmpLx9sr)h_;6ObL=`xNJFAuc9-;d2Jt(y0`34Fb_&2h z*LP6{Y{_3gC!h&l4`R8R1QUiTo8k%NNbw1L?__d9Ib)Ecnku#{ zZ%d>??}J%pgbrB19o28P?0HM{aMnVPVgaW@oqc$sq2VuX^$aYvUo&7Emr=e$) z>X(q6w|bXyia(@N>B1FeCTVc0{YDE!^j3*pnA>K^=!{vK!OfUxXNYx! zu{Zz=#L|(kfj~gJwWW?@r_Ry2`)R6EIg#+;xHN_yb0eU4)&$iQpH=SyC%cRz3C*1^ zj_{NqE%-&SxQIbR8m&LA?BlP~t|xY`GA{+Eu%`Kq0vn|6YcO+>|J$B?FXcI`>s5hL zTf<8FiX`Z*2aA6ht`?(qKHoAQ-lnSq?)O<+UVm~IQiB<(mN7b)x4m2zBy^3=g?BGE zalsQJM(0IcQ9`)fYGUF--c9jeRGLhMn}Wt!D)yxfSa4zny5twviqF2tW^1G<+%}9P zje0?)^l;g|ph+?zf@g_$Kiiko*Ob40?~6-YR$sB~GpWTd{8@Kro-w19@)B|F@@tWu zzhl>gM{>%zWfTY?I>elp{q3zbE6?@Y8>bdLm$f1!Q-C`I*HwHgsVJ?1f)j-<^BtOC zXJ@iVQ^On={0281c~AyFnpm=#%rd$~fkTJy%`l#Qghae(%S+?*HB|d-_f(*2ns_$ta<^eX`4GC)^a>IBTI9Tu4amWqELmnfI@Rg3}w>7E6+Y-M) za6Ohb1Xs~FR_+!_n7TLzD^t@tIFaLBtn%}ig|@Gfr-1;0qK)B>7ZG=VRPB3$_EXD| zK#|NMVaQF<#iO@jAF^stXoBwe=i@n4eZ6TzVZPEf=*uUohSJ#v>^}IPO#7knNNAFT zE)MeQKa|I4&xngT)!P}LT1sbnJ< zu2TEWSBw)jUNXvy+Q7g|Tg1ZjXNn97b#Me#2Rn80pANQEb6qPV_aF0gdRoI-I_tr_Z>p@C_qqtpl3lw-QH?7o#Tt~(t#{XAjgKy!^F zEXw{AmgiAo{J)ctSYdJG7C3hUksu_tDR1s)6Mt6HYs(ts6qm-$v9WLXFx@ z!|;Q!&e}YTQ!pyVKYG{DXW|C&6Ku$AR^xExMw-spmu~{_- zpq{%JRbM%I*HgCc_|~`Lx%%5PN#OB|WEm=7$^9tmEQ1ZFtSp(6P&iAi?lkFf2x7-p z`Ik4YsaKs`ncjR&50kN{axB+MboiX%VAEl7>2h^N3S;aW_f`Muv2iop1y-r%37WV% z+_^BaE=0`AcxJc$!|osTGN16Phgz^3n3#_k+1ABn^I9ZkN8Ru*WHlIxYkMs0&`h*% ztMPtv5%lT3KwL+cB3?Xrokm&42*MC}&u})OOGa}~$FMoag(>q`(zdR76#sHY2~wcM zOnf%B-fiRkyYo9nckvm=-&7VG?(BDs{dWGwIJ?+UX@? zkqMeRDVPDu{#llxVHk)|y#OiyHlE8wQ`_-Mr4|EE18z0Dl4N6x z6E4!Sg303X6FnU@j)h+8MGtgBND7b?Ol8=92%9kJQj?SrH9rJQafro{FP%LO0b`hMX`V47MnapH@h0&_>#C~Cs6Zfmno3)~{0fkqCcT&&`lfIbzgZs34JQR4ws zdw-Nprij#nF|OaHhdC~ia3O2_9Q{#gkh+Iq>(ptqAU^{KGPtUb$33gXegNJp zIXVX(y*uJ=`ZEfiLq3Y4-R%16UNg~+2Waj&_IMgvZ{~A{FvO}ca`bW5vEba#DjVuZ z{F~5pn&Zr)fb=`!7Hk%0SsJQZM0Yjeb_f)GZswEI>jhG5NQST3|L)s*i#jb6m}?*7 zwpT8N;e4L3q1llu@|XnDg)nt1bMX zgJTE(oi+bC+}Qc4IUWf8%1D@B&Ef&HS0+AoZrC+}lcJTGx;V~+4TmOEIbof*YT&Lk>i2(5mWm1(kpZiu{ z?3wVM4(H4@p8J?L1k7Ga@XHJPGu+>wFpFpzg56fS-SsW(%pSCsEr&cDAJ|FgpJ&fI zjuxMz-qPQ~@>~C99hq;S2+p4Sv1vRl+7CZV6ux1sdSW?u=`|~K7~z{}HyJyebr8N2 zMBv0_Pk1m(-0bm++@gg%QqZhmSm37RBDyzsa1NNo)XW{X(9M}^-`JAzb${UG?Oq78 zatUp8^%qyY1xgCo=~&s#yE8wmJ|B6CInM`7lbV9P8KW*Ie!8Vi|#TUo)*QGE);lrMs@iD$UVMF z%p}D6?K9Wf{cJS!Y9wPKtrr^+h{vV6d11%Zc=zpiYP9T|P468!gZl4x=_WTVEmzWBc zoQmt5dh8k)7_`3<69__+)R!bm)a>4y^vnK<^}-!dbGb!y?D_;xL7GIR^|><+F-arc z*-!#UxAL%HcbnP!1Rh*UGL)MzDbR#E222jKON@z{#}InPmkB52)_t-$SO z^uttXvKjVuArr1{n^=nBF#^;7S`pPSueraP%e9Uvs!$fU6rWN72ex@QwunohSB4!P;J3`c;@7FdAvMwq&b(O+$2s11ePGSc2Z+V8J? z6S#6H42&$Q-jT3f7HVK$*0rk5W=)1G)`9`|EhSIiCB0n)qFA@1b!)LWi)@#s^skzp zi_3JKU-g7dH1WkZlwL?bRC&@mVt;*PfecPP{*Q~QUc!)!p%8xPdc%~gF*pYhXyJ$^ zRO-8BG}0USNMfGudSAH-F(zp0fximlv@L zhQw0);(u?~xRCH8oi7?Ou97T#5xT#XP2to47K-bJw?#qg!ztm#uzC1G%H-A=F^C6I(+&9K064MW-I0 zRN5?OQ?&FiJTRX9|J=LSyfng}DZK{lzDB!mRB3OtV%|$NZF2;-H;|B8M2bK3HbN?! zNAYn2c(*rWCurd}YNVX+P$p2Tf`vR}QZbt@og?>G_4{m=NkU)lc_Pq&M<(g#L*=QS zYCau1LYyyODA@$OT6V^rznC*rue8_km`@~hEK(bd5jI4{x%5&pupJal6un=WACy4? zvfmPBkil!Ox10=8JD>|m(%ttazrAf#Zn$(8JI`oWW$c&;%gVeK(VbBZ)t%+BcOx&N zpvO+Bgd6nRf-ur^LeGeb17S#J+oh3*EeOq51($%^x{h@9wJsn+LWG8e87;U;!};w* z8P9#j-*KYEb4<&#T#cy+Si-rQ8oK8Gf0&Bc#GqJUi^EKc#Dhy{i`zcEfJ+GI1%3HC z{pgGoXOhnNazm-v*DyHZT+gcKKh&N7s+4Nu&7TlaoPS)yj7DP^u+(%y6bN84DnSCITFe6$`Q_04FyH)Ajq_MPF;9<=*#;_;~rPvjU6ga7QNss5mEQL|^ zWOZSmq!^m>8yX94G>piru7#s5mru%`xcl>{Pxuhr8!rsm5n8l0Ln+lbjX4TYlgWZj zuM$*wY;exkUF5EoEB6hH60OY0fL|>-=ll6s1tL{9R4IfnXmkaeXFRQ;rp-`=0}ZIT zW9)ntZIQuIAs{%?&u^}nFIk?-#&=B*T{U%lxxwi-IS_<^tV%UiW4ob4`(?HoB)wJJY`L%w8#>AZvQwgXaN|fU6vzyU(OT0o?bpO9M_4Lo;A3l}*(EbS6E<2-k_5q5kit8SSBfTMAl;bRw=6p*&NVVW>MdDYP>c&I z)oVKx>9tx5X65t#>~rU&L;+z=W=c{7d<$TC8GLON4IbQFe!z(eE{55CP+g@uJO917 zQI7qjb^>9ipztE?hn-q?n9h9+M!mq(+$bEQxPgh{_r9AdP0o`lbc-{WpGV zpv5+n8?hxnMTEAI=qv?kHHI|pb3ZZ~O#j&*(_e|D`N;}6iPd{b1B{04pE^?%Fj!o2 zUA2VE2!)MogU+IyzXMNOUbKJ1hOORN{jlnC=*MPZMBy3GQvHz%GKnKqBN-2Y28u+N zA*E!Up4m~r)5QbN*tCwv^Oh0`j*6|B2mRA7W^PfwIC|KCfITWCb>c^}svN)r2p!u| z1%-b!?Ah0`-N$Hh`7jLq&`0T(Kw?7IL(HDiY^pTQE3ODkp=H`~!R3tJlDAzi23V8{ zih%Qk$EOE*rh}ji9>z)pXy2>2UVc}-dZ&1i)Zyu9P8;r2oBU>~$4+O)-L}+NQ^`vI z^+wMS^c|#RN*X#n1hd@ovibf|Z;t;Y`1M)~+yV~`@{|FQM^&22hGx8GSKF}W9?8At zGHy@Yu$x51utg2#z>cNS>ZL&f@gUhBPIY^7uc9_r^l>IWI72nd-ua^*2UUx zWryKeo;X4n5L$U<`e=RPH1oWe-_Q+qeLc}Otp-RFCUY$*8ijGJoNTo~MmHX@3dNW; zu7v|iL``epB;5;9=Rd9hI2$eN8Kr-dn$DXhJ z>oxH|9&b9Pz})}hA-*zQ#Rpjm;%NFeDvZ`12(S?6(X}Anw<8tLv6GG0Tu`*+F9=;o zPj-|@yhemXE%S8IxhXVP`RcLKtCfg{E6c00FMMpfkloHU;|yK!wH@`OJ^HGQPZg-Y zwDa~11>TrLWeSRtc0CyEYQu1@;=mX(kj|HP%N+%2(=dO}b-16V#g}PuWdBo3YhH4S z4SSpQX$$GE&b*^=_&NDx_&(WIOs50 zjMEGyogv#`BW{2ako7b3q^kptc3NDWqbOBJI$yNp^>)E(W($#fO0Pv?<`Cg2t08#G zN?}X>qa@JkIC7l6lSnuYvF-2YtZdeJJ?aC)bG||}V9_Qt(Q76`g`ZNo!<`?4IbvRD{DsA7 zz*XPG%vlqdmOMK?;tdv(-6_CKyDtrSm)}csPyF(Wn}67~=^LZ*DES7{j@@g46j~38 z#H8M3hU=U7<{yrB=EFf(*Y=L7gfNZFoA_IaFSm#Y1jVp?L)I`D=A251yypfwtZqM}*O zq(CA#0;!-?uk%vpk}D#Q_k1D0?z={%91?Wwqw*iM5O9;o@w#H-G0S$$1u-5z2&WX?<_udQDrE5p$_OMa9Hdm^!{b`o;IPO_KmSan7CCze4)SS41&FyI$0S2} zsUZL+CAh<(BU7S;$bG8Z#=?c2smq|~7LgV_4eip7JyL~WKAI}Ac#zo`b&ZGEA-_4m zi4D)OeD1ZC;kpbd8aYW}lcC4u8_bW$-t4N!0g`BPER0E}tt76h@=8WFZ50OTPd@DZ zpA}I}|F#h2O+cm8Ntn=CH5L;S7N)H#HnJk7XqK7+E0@o3cX5o*XQ4n&;kL8=r#g9&Y@xu?#oz1iV!20M#IN6-xZH}XJw zF*KnB89jkHFJ)m~VyCiX5`~qq&V_2resH79Uk<|UiCOJws+q9|ewsUdLe^d2);i)w z>q_>9>xQj{jTk=a+YaEiG_`jH@bJ$LNjDuMyk$?hBI*)waa9p8o#EJ}Hr|F5FfF$H zd)k4v-$vcQJlZbam{+u>d~%w-jZn$3SiYa0DAb3l<$uxe^i7tp%BvBFbImegEtds-@&Pq2MC9B8E|b$| zRo@2aE>e(9*ewrB4&0+&BPhUiCb2>mtr{CZR9;;4_GB~+bt(}B6h&qZxUdPe zs^etb>3YA=5MEndb`PdiB^deSNUHhjjGb&;LmaZIhS{rzEzxR3i`+m!1ZP&6iaw+4zk;&wWKy?Qp9p{5}v6G3}W zMu)}U;wpXzY{Gkr)4z1bzfW>AD2|=EY99sGMn=>(D?p(9QWL_AW=1)I-u&OvKm|xo zC_f`My^Vxblj{%Wgsa;{L*#IV!L1OW9-K>QdA5eWq~4Rbkid6Hbv`6Ww^ zzcFP(Ki^Ft+8=ol!27+0kFW9?X3AQK9GgIaPH%t!{M|qnpdkyfHFt5`pGSY*!jIJS zyh`=ZGf(V1f`2N|OxIMhfL7xc2GmpY1-^OPr~=ca>KZ!QEeG!jn>P-sl>aGmhI#c6 za^mN5+ZWmYbWqBZ+!u~?3)=&7{#uv%o{6V`M2?8JE1vg9ha-uHkd+n(hz~|yKkqh~ z|A}I-*RtzYsd}!##cno@#zOtinXrb0uO?Gr$l{DNpJT5a2DA@=^x2p#3Y>MHtr6a_ zV+snd%?pHu_(eOy=y@w!v89(yuf;R>t`%v|6ZmFCeLyv1$6~lWk_m3RMP@^^-WXbw za4ar8-evzYadv6mr=h|w@oV)KLlZmRzq2YruDSahL~z{Ql^k%>&vY|frXXnQTMtx| zHnMjd0Rmw~(hZKHf3vjjOQ?7Cx}!{m*Nh~5FR`FXBY`#`WmyI{cIE5DraTxauRG+T)!OJGrgV>C+n=6ci(ap?QQ&#Yz>uKb=OKOYRSYcSv3+Xqkbl7>QB~7XzasYQ%^u@L2CQYGrY1sGC zYoX)0)3`$ClBSkVV<7;mYZ~3Dc-4QX$X>JDbAf4+|=F2U>NpZws{mOEc z$@SdmGi33YxqOADtM9f>OCJmdnR>~_=4A6PC2>ayLYOA$y5D56OG>aK$$YWFFV700n< z(dWd0Wx9>IvcTr$Q^3Q*XnwQco;%_^eo%TF0sHJ!gS6Df1VB8Niw&CH(d_=t1Fq2e z{x}|1%0VebFc1=t-RCi9-KgQ({d zM3yn!y8C{08I0&(-y%$YHA4$sxPEP<_r9W30QRrBFeaBa(m2tm zutC=R_c%;y)MQhiJptKT_lj8RnmS+9Yz*j{)pvZ#Fty*V=JjtT9w|!2#EFF7Rh!3c zfEqriv%1ROCZiO$F?zh*-l?fR#=v&6FmW>he>Om`SyGqgUHCFVE(jvCY;>AF|BlXy zYao>VnM(uHwmhFZhAjHiaBD`qNxGqJ{rn;-hRCuVIds4QyUtmn z=w~#0wSt+W-QHiB?OCvqyhn!L^3}WfAM>&vn~y98;VT?=5|3+w!$>3Y{;ss1ha-Q0};nsFz2mT|;)bDj{$v~*st{M3#IeQ0jq{v>y~+nq|*HgOK77D+u{vJCd9^V-er+Z`{=?#KmeADiGgM@ZJc2wW!4l$^{_!mVa);xK7lCo{;T4VNK>$?bhyKF;wb!%J5$U<7J< zT%bJf!|ZFl^%z;1Gpq$gFiPIzPdhr&5bfJ5of=@snKA1rpNYZHY`BZ$dDIEkYkN+M zi*$y<;wdPF5@DtWmdO0#II$ZXD!3t6`OFq4pju*G-xANX#~hyg7~k1e%Fp?7>MZ@>%R2(b2$!P?(T+gM zC3p@JVsF5IZGbnJeDgb7Z0@X-JtvP0i!uJGg9ipnuH7{%YM z#f|Sg^{5VOR4`KO$Sx3nfnA&tv%uVh;n;Cx~fAT#}6+TgIw|NltIyp?9de{8A58L=-5# z27i3Kgo-0EcC0t8-hKG$x`D;x2=93&_sbo(9w9&BJSuXb8UDgXYf7p*Z_mv2uLgCt zoG!@vkvv3@&&xrNiBou20;A7Z9{!O?zs_;V7aL3Pep!v~X>nxI<7Q&4;Jqr%r!<7AlxwE#R=Mcq02iBes2}@-5iw?%ZrE7p%Gg z^gOI&-l8tudGoFAK(M`$_Ycz+uf%%7N)-Iyc9?es>`5Q9LMHST%L}wO+_^e?_6}wV zu2=-q^h$yrw~f`$`#$^pcgH|NC7y31c7%ZN+OC`y9Jy21TH-~C^gkHIJ8}GPg=)k=OeU^EdrjHm}FFZp0eh{Psi=>D&ateC5 zsCrm>GY_tzTFz)-v(4~-`NPtk$is0nh>o_jTF#;Q)jor`@Z$g`J#o)EU0>9oF6m#! z)2K66Ji(-O=YFc%;EPDgN#i%iLQFOMlfU*Lz_uYEIiSV(1!kAM)oQ;sU!L)6{I1!{&ulFvQu$>V? z(Q1rK*YdK74qCY>nBj2B%)b&p`^n$WF&Un^!Lce+`4)yE+fdqX#g91+g$KBdsHK}u z)|PO;XO6)47p?w+|5406K?l9S^^4O|vBh0RF2M3Etaks8sFI0VBt2`L(upG_S97|a;Ts0DUrcI~d!sje&Llt!|&1gRnSTT`eX zqIItJ|HR9hOo1iYNzX7%!xfU_ZHPiVCl}Npg!-i)eu`SYemAD5Eep{ISN`6G!S}k? zDvmdWi^9k6SgY-$_ouv;2?*D-J)dlY9O5+7Qe+Rr=arwA_^S_NWT+3vhxLmX8xD@G zAU4VH10G2=sEiKm~^%>4BsOBm_A0Rr)85-ZpiUKB~lc8J!iq$l){D3_u3jo zkhYx~xfU&AZramRR$P{_XZDv;xJzw&CdGFf;9~fZvmd)s<{a0z9^qW{)5pS)K`!d1 zOjp0U1mK68&6C$l9-J4o6;IR`?awoF+sLBEW>@WbaIvY%u9=ojVF#+%k?M9iRT*%piLlW1@ch zFaEStT%)|j`q+zQnhSr&y6$`>P6r2(3m6?qa*8t$Fu7ybWLwwULnsy~TJOC%WXHF^t@K@bj%SscRJ3mw2 zJ?u{NE*np{kFPx&!*)ACtP*#d*4^aBa+Ge+#;p`RgoVVz$@vMgujSPqM~BYzw1LM` zi0y(xtjhwe^7QhlPPg!E3?WEp(4p!qP{nV*dpiizpZO&A9R&ps(k=~-@17mvs5Y}N zzA%|8spZ+;h6T_A7cQDt#H_P!T7rl9XBOG)GM{<1`u>6*xJk}sVIt8B!FYxWuo4TX z-NHRWfw^^7^kMEp?-SBt=g?HWZxAXN$6v4>EtrC=Z~PZ_93$FE;jtLMjbx=lY$x|0 zZe1UBw!)~NMK7-Fvt?k5?Fn+f;D^TINrVe37WMX-?GH=T0?7H!smjW4+3SS=k*bUO zY4_cp1HS`X9x;>o=qDT4YjIFMFpbqIm6v%b95FC*f?Oh}Sx{D$W)zYXiRiCiu=xC* z^xe5WUpfK05cKY%kP4siVx}KNg>+u8lE)7*M^lkxBnh8Ubr@POFw5D->?wt>9=vZH zppzEO#_Lo6Ma*Rjc7x2K03^o0bb^Y%kuA>AuC<3QpRoH|0HdGLvKu6u17HZcqz%xRgx*E^es8SN3z z^ph0^qT1;C;f7o%FLeE=OE4zjkkv7>8~IptTecS*`BlY# z<4nZ++}PdVlBhe14dh@$7bjixGDL%%OEq3w9XHz0SrFYtm(4YK>;c>3Rwm8W>>g!3 zu{J%GaN8pX*2?X(()+R8qAia^rZVml39abGs<;XWp1`qX9Ppp75@>ANsS*KS7c%Ja zxewn=e-WySe$~yrudWz#?UEIu;MfP2OL+ZxLcIwIaBwEw4(W92*E!$-2{=c(<4>q+ zvD}@qiKTvmh-wC$XkHyq!;aUTZ4jdGfPv>eK&5xU?cFfNEshEN0!h^gqkZdMtxu(G zeeqo%bIOH_tu%?wS@B7eWv{@EJ$sH=RYS?RG%?J1zAHz9A#sLTLM)WJwLjJ}sd=b) z*v?m*%%S8g(+rZ>JZ=fL3l|ui#eFV1AfL(ipLWzUXgX!;1o_h7iKR@dssa8e@*=iK0#fmGAq5C zs<3B1q^#h@lq$Zw>3QseN2Gf_)J){pT1@8kgTdjpb)A?qKI##f zI#49)eC+V=`tvJTf>}oJFWEqNMJRV4(ogLzFmBA5kBq&^-R8}{Td6t=fte2zR-pOo zv$S)@3J%!56KMbUfb_aC@4(t0nk%4DoX;qB$IoH^5yEMu6>Xg+aE^`W4wn(HMA57> zBu7DG^~!&NsjPJ5;y_zWK+B6{mGUN||oP#TAFYPo(HeGn}-`8fK;2`Y+9Np9_V zY92H?EnumtJGrT+@#y^`JA#40cr!S8-&s7dYJyz1KM~RS^Q)ee+bf7u*b`xy=uHwZ zcL4u5bQ%wx++wX`++l6cp?1-k%T5;*xsxT;r=Wy?Y%MraV#LtO7A-mAwq{wLit~ck zn>3knW3Yrxa;LVwNDN8&){Fjd{*FEB>#1hQ*N33nw>S`myD*ns@8)mt-2iOROaELD zCFViHDT6YOO;8R0W5@a(-g4qYu5fIxpNWuq3sG4wlo9LOtBb^*{}9b5Q`S|%@4uE_ zsl%Gz!pa(l(t?lA$Q?sUE9JL{(f2?uY1waj}VVo5p~5#1@WhB(1=!4 z68@LphL3CRBwrx!;}{{g6w<`En-xWjOchCkD=CMT z)=Ay+2X!A&-*54bC6Ic2dmA2|UKAEd)P3Q?kMJiu zI4uN>Iz)5)Pf(~_EjqkwUqhR0EnN3S{~9IX|8feim=th^Ctq<{+E||n_P%_Mqo=r` zSa13G+bFJ4SpWe=v(5&^I#9f;F^h7_#$s>`cb`>s4_8`H_Z8OxT_%Oni2EJrtt2)( zwLL8T=hgg=LH%vm3gSrT?H_#4N5u2SF8m3vHT7`Hb^O`Z>)+gbE%_%7D(Qx`=9SjP z|NN8V4?}IX_Dy@*=39eX+sM+gtd`Fa4*{par3j=ivk2+-nHivT^qs+B7SFP-+WI+i zq#{~5sP8)d4>|$z3AxLY@D5u=<~G50<9$_j|FFQccXEjFe{DFFI&D-^Z^$0$wazbR z_PfP6JXBa}EPl~8un@n@z4^POXOS*)+@QT|1}}|XA%nv#9&uZ9Y45+B7b1Okw!a&F zc0^VrJvv(dww#8H3hGb0`JWFsuq-KibiZl;`CPq;U;1d+eRUxC>iT>r!1PuvrA6H9 z4R64IzD-uf=<`CS8Ts2+onSE)dOoAjol{uw-Vb&$GBFG|8XE9GI5fT*OSE7N&0>nB z%Two&p*)fq(x?4U6XQJF0LecP#JB$d?)G}qzAU>I zQnBJl8y_d~eUb(Z1#1S4LNI(FIjdx4_DB#D_MR5SZIQ*Vi;{Js3iA)my_}mvm?>9< zGijP$a&R}?Chb=_cJkNe&x`on48H}AtwY@EdHay+cRelmI$6WSZP}90XTk&Xxa4p8 zwtZ0(Er4FDXL{MDT?`=VYTJvAVq>`)6&C}P#Xc5nG~op2rZD6x5`&j;ne!yJCQ_mk z-OGa4Uij`zAwW`YhWp4Vtc8n_fZ4iqJB#`wSMlnIi7F_v85#Uy@D{dr>*gLuR<=V^ zlZ>HD?I~ImGl1nr%c-R;RtR1+>+!TX?l;XOMaacBJ7(=S68bMdl=WwR0pFV>^l90k z!|?m9qM8ROgwFPcsk#^Am5jedT9zXXBd0CRNlA%8YGfG;ZU+6mZA@FBfnWQ>mA}D& zxB1lFL1G50f(4}|%~q6)3b-;#JcS8)QMfrFsd}RDkGg|98E+WXRy7yg-h7{85a=qP zfKcJOLPkG=h&O7tjpcK8LNL1koP8e(qykw~4RP1aFl?Og5_2N|E5AOuOn$z3W zdTZ*u`4X!7Ejh(G2N-6(#lW32Y%+><&2 z;PD}=0ANJy2HZ9RGkT0&QFBLf28lNXv|471-UkNT-PCQPj~5dEisoEKd#l!ZJuWTp zhb`I|oKrZB%#WK6#2YY6e4yYYT$WWkdy!M1UL#*JtlcakxvOXv>tu| z|FqE=ff7-WE$LC7c9J1_zdMs=ku~>@c+f-adHJMOV*WBO%vGe1`W=^!P#YXfD8kGay?Tiy;se4cod0;8 zc7`Dy?=CjWm5+Uf^qyxAYi9_&sMnCqntjTN9B$w&CQ1cLXUpHy{$ax>5owY*t4*L@ z0~|C9w`o1940&Hr?+WsPYta>+l23X^W>6Z*<2 z4ey8pb8imA^?H zHx$E)MFi!jRc>f+6UfML&5C6WHk8YK)9!8n#Fr}w=xn&mD==sFe9ljrUNUO=)I7Py zIz(~^{@gUne`B;`GG&#$9hf^4tP%YOY5k)M4rJUf6 z?90mL}EtjIrmo1-s@wo7h;o7#_!&|$<8YCW+!uIy_b#u1wW|d-kC+04w zc^oJXV?EseB##DpvP>1I^^T?Ef+ktvXP8bOl+5JiO8%cv)!gMT_wizG`A9s4p);48 zuxvGFShL>DRa*DRw!wGT!T7|mHR}Bu9rp9aq&gXII2Qat9~|2^*|5nC8qqk|llP|6 zrtx}P^Cjxu%g`>&JNg$DzdhH;&R3tWr*z~d&O>QW1(rtCy)+I##sgYX?#6kfFNbDG9PQ58wMpfOC1P{C2{I$_0Z--4+)&CE%1xNT(&Z zYU0y~uwzQbyMeouL(ws>gak&Q)#Z-kHH9LE=Dp&Eo1_frHE)Cc7>->|V#{#N5K40# z2LIp|mXFRgB*d39{9Z;zkijfgBVcqA6c<-b!xy6iG|90&JbZ~iITZ>SHpEBs_|{hd7dfa_%vK8kF<5Km?W zimY1@C5r5pE8c(RKjxlUqkJ^Z5%ZSP-mjFEz=LwOt&lx(toA_z%MZ$|{O1fGm`rWL zxcW0KZ8|Gz-<#q&r*0Okj`Z2_6!!a7g*1x^oRZxqIMdZ(IL~*xBA@vGhpn@WiZbl} zwTggBDX0uEfGDA&gdia;3L*^>(jC${Lk$AbrP2&3(hbsGGjw+iFbqS(&@sSyc;Ek7 z>zuRBVl6+g_~!H6&%O7)uHT+KsC+z|i7sk}_W!OQb(r{|;4zD7hcx1J@q?(N z8c+=4;cqG57rfjM*SiKY7BM7t-*^$?vxwW(Kkg66l1mXn1^t;hvwbBR+(4IdoXhSG z22BiaJX0S_1>v-;mZ4$m%Sm*GVMrx9UUbl&k@-)?+gzfEZ=Vf5@0D}ieqW;i`>J3i z*I`;wwruy^VLPqpq15d+KW_vr3Ux1M1n!Btd(*IwLTOg0la&)CP@kata&t+dQS(kx zaML7cr1iUS3>t15?;ylzUem`K+F@M0v1&?hCXUTfcx8mxJJB{re_4mWbovgIxlOA6 zabONdE)kfMCar#aE+tyt*vYd`<+varh`I}It4C_ni;CW07(wi=Oj%^sx)gej8ctU@ z*-M(ILha89AQh(f>{1R@TErtGeM7TY^f+tH))AF84hR%~ly+vGG*IQm6AXCuf&ZmsA61h~NO%Bfq5;DgW8VhfbhLgvfspDG*E?D?4h$d5VOluQ$4M= zm3Eqee!A<9^s~&cm1KS>Jr|H$RI&z^i#f6BmQ?`%SF*W|$Z_Jr`;kM?j^v)LMu>f| zoTf^h!O2pGM*_enNJRd|NUzQt10!LZN^7@Tl0??3&Lp%QU>%o7mlrv4q2~s=Oi(64 zb)_j3ml2SYMb0c^G^@MkCB2b?KFYb=q-*}*1n1S85qTLqZ&No7uR+0xhaFsM@T+^d z*$kP-lKXSvTbYUBJoq!(2MTjXB~Elksne!IL?AZRfEt_(sSj`iEVeRn z^bKvH9r{TeKS_968-A~X#*K+)*<~?qpV$SnJ42(_OkVMJf#00`J?Ysq9>V&(t(&Zf zolpGJN&3~6d1qb>CrQ`b3KOKmopNQ9cH~sq`+MBOrsr&vPeMEIa-~oQYu41#8jNy; z;gq${uWyont4WN?KjO`BD!S*~+j;Sw;FIbx976`~y3xU4@UDfv%iH^!@!kauf!WHzx=5AY7%k;X})bE0|5)_+M7l9oGAKg`2K#~o;s z^>^Kejft_I$28cFt&T(Q9%oMC4F0;7Uw(k&TqNY_7?pBr-W|Nk6P z6V2^jx6o_z@|#(|u8G;}Y2<$tQb$y!8bw0##X$U24+ZxOf6*HPE8xFFI&P`G8{(MFhf2o>D){xy9@AfFS)z6~7!wHp50})b zdC?3}zVbVjKPr{IW5ArDcCI(RTcJtk(BvV=>uS^Zn{^ z(XpI;X!G{8vi)?$%S`XaGYq;Qb;FiXm5J!-~1UBPbzc=F4$wuJdgbi7;bQLJ~46FFupITsomOZS%D{c1vieXUpV@f z9x z9H&rj)Y0qpL=o=vCDeA%D9N2Rj1lI4;wL$;1o@&UgnCWr`AlP8UU!PWZmNw z)Ol`pb&+Zl%PBTF>xSk0Yq`>!uo7>qkhK#fS>}eIGfy<@pY7O1OabY$5~#Q4!wxZ` z6vUN79(JL}itK!B#Zv<1#JHUMDK3d!!>m7U%<;cV#@u7A&UwZ7ke7(Fa)jS$Xw!L; zf(juZD=;D2_snq^xU7XRndV7eA9?W$zQRH|?{p#nFYEvnO&bOo7h$1`lP)6Tv8O=P4War#rQDN`cQ@X_fe4%p5*8r^ zO&`um#Hw_01WxcjmOE`&oF5^>9pifN#H&LvY4=~pFA9Wy?o+qH8H1Fm?w;ccaek+2 zTEdR)AakAU@Q6`_GrmDJl6<1~ZbzcjDq6Hax1WObA zXd)ZKW90qnL{0b#@Ig5!SLBTtyV$+vxtUzgjOg>7#XYjh3sHoQIgVn7YefC>M~Z`0 zZzUTfJ{_YG-#9fQcXdW@hJ^9Rp%_MbBQBYEY+87EjCVxK{p{9QtgpJ)%#dMBJaWYb z(+ZfDv4cAqjfOnc|Bqb?HHha+SzV~#`+Rz{t&-S6(g^cb{aD1Gp1_E4>a$qNYE#sV zU1|JGORCT$@i(?!*Vk0v;0tz?o>wCOO50#%N#``)h5zilf*2+$t|HgIHjQ3BY>>7* z1w2#oQ<+GrnZ|+vIsH*{qDr#FwYuZ4Vvygd2Q_b+8@I|vNNuKNVEtT@R<4OHmIro# zXo`(BEcfb3qtSCqpkc+$r2G|Q_cqx|L;B^Wj`R0iRMt&03b7GDxDkD0TmAgB4UfEB zL6>;i>d=~Um~CC%g6%oMCXd7Cc$>(dbL>TLMqCr5=-@)V3wt~8#+s4d<}3-G63){a z>C~xtF^jA|xS1J8h9H<#m<8uFu2AlTRwy?nJeApb{>P%^TEe%)?{@dBvHV%aqD?mL zE&V>3a%G&kaQdYj!i^j0yL(2k&-Y~O=#QEA{VLbZ=7vq|;Ztw+J}hsx)r_%F?`{Zt z-@mWCf%#p-7mem;D~Ab}*?5;yhO7E5?xph^dr>N4=QY0gzkVf{`DqjE;Axj=LD~tk z-kIG7Tb&K*vEKmY47stf#02v|x^@(W5|}V}z&b2J2;!5#ZwGO@IMn!jksi3s!RVR%PwTm&%99^jP<%^{ef3zy7mOEO$So`VfDCs4+&8 zPlM`4cIQlr-N&XzZ6kAgSIbP#N6t&DR8ht{Z_CXG-g<1;=$AMkAb&+J4u}8%7JeIf zsFu$V)mJU(v@#_0FK!sy|2@HVScdJpla_F_KtEuS7m}*#J?G+0R;>4yD&-? z+hQYo-E}t&3k&fi>c88L^7?$lW+y)Pubve6EZN9U&km*p4J0p`?g26&#KzFbNhut6 z$7~pB#*83<%`9bB9bqOxiyUz%c>;J})@7e_NpLoQzjtSn$Ry(q*u3!UuDZE8lItMh z2VC0aozNVldtA3qt$1TI$vJ}hoLdK5ew~n}wQuFU+RV6V43Dov6>RVXHvB5Opf{Bx;<6bYyFjBQe00yBee1$19FC|PFu?eWqjBz=%bx$EuRgeV=K(o)kXmrr7>7qG!pdu~Da0cB@+5-DgseAg1dT{p zh;N=s5*ybVt$h4%2qD;N2zdYRG z)zEYEnW}XmdE(K*Kp;Yt_~z&JHCz7hXgAsT`woN9W{L3{cbL_xG!cnKlvTO+myB-! zV?S?V+jyD{kSF`t9VTOjwBuEq^tvJnk%Q;^gObN^fcyLu_^Dq^rTXe}1{0xg3&pUb z3~XyK=4NPw%Sts`&v3lJt+h9?g8j<%PhY!!wBYIU45FI*&GbjI#Z5OxKZZ55`E4y+ zol;DuAC<@?J!~V~a;j+%V)Ypc?S7K|PV^wbM9mopJ+L9eINuqGraq*A{t^@ye6W3D zBF-v_BnHyFwjG!MA?XqHmca;JZ6M6tILcd(?Ol8Y2r`Q3s{pOvmQ%2OqNGz-`%F$d%pKM)@OfK~#!Eq_xAg`v(@=^Fd(lwR zU-=jFu-kD7fQw>85W%oW!^<2%#dC_|`im*-x{>WIp+t zd4v_+OMho@a37TRjVr|$OnS%lod07e^_R&X^0(TFMm0V;q*4?y`Mh`=_tHNN0J12N zX_kb42peqghfplvCId@i+Tq5YtBc-cmQrE?SeITWQ7@v4OxMN--<@E*&rrdYQLNul zKCCVhd-3nz#D1lVe4U+^K0Eh^C{OE&4J1d*YVrrcTMP@b1wduVspl5>rR^wGxd!2W zz9g?){Nm=Pr2~+5Zh5^_h!ddq>aMJRh&RJaNkLvqD%9p%e*2vI62DZd(C19f`nGan zKFlYnI^XC7SK%3WBuO!+ol$TS(V3Q=s;3CoQ%nG6lwI|BOmzhBVZcgROe7he2Z*m@|_Irh{FT zDKR&tpuZw+Ju9bhEaPUr<*asb7kk4wXNNv9I}5m4jgiO2@x5%X3F=#L$_4^S>A&if zzFp=grosVO_z{-?@lDR|>tgOp#1#!RVjv@!Mi63BDDqT&MTm{h3j3t8h{wpY9;sVR zZa~gk>BX_x%Gg@_gHiTl{?RnJ>D99Jmt}))+IJd~-YO~&q7G;h#AvXHZh(J{;&JL6eM8xO3a1fKv+k+~7@Ysy^anSI-bp|9|nL(l^ZE zFNoYo*B=QMa=X++9dgp{uhnJ#^l3RIX|E2@;uh$;W>4?|6+L}_3LJdb-awQ3f)Yr z>_2zmrMF*&^L~B*X@8kkWA#zshsj!JDJOAMrgf5Eq9cF*+*-nfaaycTl1s8*uG$-k zcXg#l+4mrG@kpSq&%L5f2zxfAev)D!@p9(?mrscXB29HgMI?h&^UX086sl|0ONxakBCpX-jaC1PsG}c!O>>(iCSL*0w zz1?Z)v-Yq_P3Ycsh}&mlR@SDQkayHyOTX^EX*7yzOR@GlAz30ndq`(sR2KE74 z-`DRvloTHMRfe<)NVSw4U7Q9V)#zY$=Zs$k@^|w_oNn{re3o~qXavcIIJ6imdY;kd zhBFR5e*?OAb|TQ1JK&|g#4*9VbtC2sdLCu05AAj^8PH=(>4?AZD1uQhE0m1E;``oGw7l+%FS-(J+C zt*Vdbb3d)>7ZE!z(b61_iJ}*VPRqYIxgoQLDAgC?d)XjA8*me3?of8Wz`T!7Hg~31^?J%Q*-#!uM)sxb;69%5Bplg`kW4etO zGoj!JY>SLr?$9kvTNJGS%O9~uqsiOp=nJ}Np}t% zaqD{+^C_4lX&OV$hxR?p;U41RBM_Wd$7HHndHe3q1W_+=xLNl#Pg=;}UC>kwv$M3y z2zw|3VW3UfhQkhj;(F<~9}RAI&ewrPjo)vxr<*Cf3w)iv*Zv*Akj(HZKG%$qC<+8w z+zXkT?j(Kqkyb07^H~|d=|4{ipiMC6hL2LT3ZX;?djkO7> zepyiShe?p~%QgTxm^rXGY0PbqxDVMK_P1=eK-`a18*&~PC*@W+Hq)ztC;dQ=16;s= zG0a3n>Re@~A8lp}cKFfKT;yA6+_MT-XRGw)d!MBFe6~NJVeTC?i(9&u!jB^f-3wl9 z3#by<^uO`2bOwETBV5x=MFN#4y?Te`f(8Y-de^aMw=W z!YergulvjwpDa27eZ^%6SW-b@d^3 z0&Tn0r}rOLeb{LpJVN#+7U1(aBO1{KXN0a}dB{HC+S~Jtj^7S8{YoE}=Culh0&bDwzOL+UcXachVPsyr(s`|MCC!igZ4(~z*0D<41CoS$se}-Svzvv6eL))T}=V-O}8S21f^*#-@H=9SGuj@*ES{{!{fg;-N178 zeqJe~2UQKrYgA+p7?O;ScprxKr>j{~d6<#Rpqf^nq}3}hX+gj!-5m<4=%ycQNMzppx_&BT-)mafGt0N8ljIfDL*qm%|uk0L>m0sHcXo4@gBeL@ww^EOC&SMlwd zr875zaF~U>W+PAE(LR!DCLL~ytLO@Hez#rytWQ~*UMlh=-m<8EkJbrTT*A`AcsA$( zG=oJgfu!vn;`n0ki}DqA{Zl)qt%@=ISG4XCmy0VMoG_+_YIky7yn8EtH&85t)5z); z&EzgF(mSZ}zNo?Fc@rnM{@E~FUuK-1C2ZF(mFYuwx%rNn-rnzwwbtqR6~MlOOI&I4 zeQ2#12aAvu5X$@Z0|5=yy|eV5yEj)dIYk0sAM3jC>l%Fd$-)QY3rtCs1&v8g^bJrOga*-6=oi5-ghhe|IbvW1a*pkM^nRgK- zG>kwr`G!y8@qeh3KSc)3X7&m7pTJ+S^(P3LhB;l(&fk$-h;@7~XWs(avfsN;rNgX| z>;nHd&v@*g)O!b*`W9YvEpi;xsN$b;n#j13KLe&AxAdklaVx(9-N~Qfr$bq}!!#3V z00FNua1GQ%1E8AKw4x$w+9@tVHbOB&pIzNxYH8kk~lO@e3s@A|n;R4;UQjgyU(krr{%VW@@0U> z{Uwcvi^an=HM!OH-1Nf#xAQDKU6sCyFxr-IzumXrcRqjY>Vyt&%HllZ z6+k(BNw}hR;mB_h@z)5dV+-;33UJ zYVAVWdw=MPXct&cB9>Be;+SW;N*B1a_#@_M3&}JL24vWNT}nIKhZ@ zC%l}^tZsH)CY-7Jil`e<8gQAoxS#)pA#2B^s;lX|L64E$eP?b6(|T;&=Eg@RSJ63xZ0dFuSCcls&-wI z!rMUgSW%zTH=kNx9f~wlg(1Ztu70E!A(LUVcc;DwgQ=XB_!(50shvBxEv)#_aVBh0 z4etXcx<)tGe-2B1tl&|pa-d%Oo&_dt7Sj5Vs_F|jl4=E#Y0HRbuCLQ+y|a!;=uLmi z?R!eJs+!TQ4^>X8gDd`oIsIHFM?U^W!laYea>A4moE!fG;qD<7B#}B)QN}Sy^szk+ zd;#S+bRvBCj|D+?i#z>gyMRF&37ry%c9uy_#xqytIq-4!1#^F+P1RamDXFgu`>^+n z4pSQLI4=Q-9ij?88MU1hNeIFO0erb!?Y*y+f2}OfoNGT8Mi&q&yt?r9fHrLODLM`zFT85Fu4y3HBrR&~1YlZU?^Ao@j=#WW0U4u`!qlnWIB%Rn*q%_N(v0Cf zZJZE21PONfF;!|jh;I|ahn^l}H$8`&0n0;P_~`Dh^u4Z7+o)Ftb~wt)#s_Pz@iw7j z{Qh(2ExwfJt-J09@C@N2re;FxKuR4O`4mS5SUQEXf8e!O(Iz4=nK^*7LJP%4BMM|gLvk8+i6gQ6p_5! zD!mn=UtL6?#|!hTixiJI&R*d7iRS)jt-ck6o1rCe&C&NM0!UKWjLx~dF;AZzH!;A7 z20I{=;gwLS_|J~&U$lDE+DmR1uv2pCMcmHV17^}M3{7;AuU;zEzwkYJB=U@X%&Ma7 zK@^69td08{({$=@)mD=eVLhlaW4>Eh;5)g*IHNDLQR(5tbE7$u80QvdHwYcBqI*2ONu1Ww@83Hr=pDA}` z*1FlRW^`buipx024(vG461@?%at(uCYocVR!lM=brig9v8C&&YJ@&n?{8=K$IwmK| zKd~w2+$dqLl4QPxOL+#eu5jQNwm=L;k{Pft(V;Yfe*%U_Z`{^@OkDrY5_Pd{s^Si) z(ax_85pPa-vlB~R`{zcijnyHWKVcW(sQUI@F@>JkEf#nKu$!DrMeGXSW2w3&^I|{M z>*(vZqS|#W{fX9ae%L_$+1O5+rl%Z(2lRYP?9Bk|NJeF)Zpv%`_P8O)i_fN8#0=m` z0rFHz5TV=OtX{vH{0Ez?G3huc!M>~ldad$l_FIDBvB3ycEgMx@mN#lCgbGg1KV2Jh^q z+G8zHxzEhsEeG{&)sUZeFm7T*wX3i~u{-a=V2tv{!|$BslIhVDBZAup^`E^8R)mQQ zPl5aVb)4bHi~Q6bu;9q*1Ii=3j;Z>-@V1m6wXWi`u^1!?vggxja-x-Y!D({K$T%+{ zwcnxK4JVP#eFr_tM*^R3sCr1uN5*yjhW6KhHt(wG>M0mXjgdEf8dX2FemOJEzbL6+@2+=ej^_GF`a!)T=- zXKe7HWLQv~S~}pj8K&rVw|=sIZ0!7M<)}QL;d;yua3ahXT}naJB~gxVswLI__l*A; zWK6UWd)-RFMi4u8utcM|r`N9M_Yw(5AeAuOlDJ(2Sj6N6r*#7`5+)L_Iq7|I5E^4* zR4?|{QC#>l%UoI?$xF%4#)ks>0coepB;n#UTc+DUoKDTaL~$%-GU(B#gg@ z7gt-vDopNx0?cEU$h^9(N_W==2>#fUpRPv`o3!5xtf6`ackqPVw@XUr*ic+m zWr{vux_F-5949LnzZaxeI6~_Djl6N!Us0((MH~|61vlDfGh($(Y}n8>AL$vXN~qhe z<+S&SlXpqB-%P#^D2RPM5HEI?5!t;mEG>2hYlE2W5ouMavg-}xzbeHu?xOQ_bf9@&-4eW0T41l&y?`` zKisrsdY18AeV0KLtZ^pE=9TDvkC*NDB#jEh?&LbOP{YN(F3Gti{w1q=WJNA{pY-*U zziz!EYNQ^W8#z`VW@wE&&DZ>8%NnH(815RCu*o3#Tbh$O&oHwy>3i#Z!Y15hVz$a< z`tKC>r9d0uyBTP}+etKdzrA_$hmE=*6YBys7CGe?ui!x4i36_V`Ikz-2B>Y!bKuQd z&J+>s3BjO zeU;UW-{P9ZMl~sZ!QmSp;8=f|q4sd4W6<@8IIP=Aa6UOUi2xMUnr3qZ@_qd7ra=?z zi;smim@up=%-PNR>8zV7IOo<2M&93`VzOwp`hW^f?3iYxk_JdO7QL0Z(mb96ruC^! z%9Y35u5C80_&K)v(b_VjfpeY|E(JHQf9%E?w!=%egnX+aB-X0D{fUZn5n9|!qpl0r z;bhaEc-s#NSv1D#?I)`C0t)~wV>xuKIjR>N_W}Hv@l6tnL`|X147cRJV#+C`0AxFR zg(y#jFoHlok(@`rqN+=?FQgexZ`JUu+Sm!{;*FzDhn$jj?dlwbLC2%l!g%ypcG}M)uTF~G4u+P_P_^A8ed=T|0#Ud!!|NKk;;ENY}Y?>nwcBXB1?F>Jd~D^6q@w+ zMSz2sFB6b+p+nKAr{Dqd;I7uw_%7i+%3w!a*B%oj612!e-M-2a77%ZXTN0bC7x|*3 zugkEzG=R8g{aqpz$PJ}J`=8IWE(ojEEJYqBn3O{mlBBtd6uEA%Q?f1;5jN#kmqY&f z^mQgrlZz5NmI1>A69;MNSg~8+ctx`8KenXoEc|a?b|ss!`WKL)3cHW__dI@4Sd&AU z{;p35H#eV<8z(wtGY1D=Qov3S4;WthzY5#cW|#=p>bKP7=X#N_ zw{&rsX!bud!yC~{nGfN2mB@*f7Z=g*||YHx0Pr**f94$!Gu11Hx&E6%{pSoG|E9;liM#=zf#vfDZGsgMb&e- z(67^a2tgmIxf8IysS7!4kh~tEfVotr2Ud^$Sct-oPwX>%vYn?qH>UgWO?|veamO|ot{_cVp-DfFDG?ery?=* zU+!>_4~@e%*}Gl52=g=&>q&)o+=ykY#STYluQ#9#=s@OPU+Q{o9_H&EzNw)K-}zg6 zd8RKFTvA#@GPE*_*pc->onPv^e^`q-SVdf{HMleK*X@Xky)=GB3j}PqtpJ;MW${Z$ zl`NIg*iDBI4&J-O-nN(CNAtYvW%@xHlgh(|&58y1aXHhtTGeA0tMmR_7Zp?BJgZmQXW)Bt;7z>D6D}fV?z_xCe*Q4a zlLL|P3BIacDM8 ze|)#ysrc|=NWl7#zjBjYeI}B9r}aQ*3YuwEa2~JyEw1CA(Y70UiCg5~fuR;dW)T13 zN@=JN@i({iVGfStE|2{1>Ks84G)*0SX zT8xT(`^R?iS>GbK4f6~5` zI0S@;(Ah$JZjeT#;=3kDCv>aqsxh%mG@|kjn|%tCGlZhEQ9;1a)Tt9z@)DY z`vU@)mNf10W#yogcd`$|wmX;07JRE?P92C0z*7v};rk(WR4O)dR5yQExd;@xx@Fww zac!wrr{>RCi#>Ndj!A*Y0oe+=$om~W`)iCB85E>Vr|_#nnDk^5KJKc{mPp_GBHsmX zg5Pu64bjkHhYvRKd2U%jNSiKZ7%gjopzY&sNS$sG8Y=vZJZS?ciUvrb2g^X)lzQ1A z{|ae8p(_Tie8yMAvi=FJL4gQ$*Ymv6Nu?3c1qskQ)?@3BCJ3{8W^FXU@I~A8iwW0{ zmGrKNo!pJb9$YS6>YS*mD#Q@VFX1=puCYjsAmU(Im%@zgLz5dLVzv;er#SB-n#V2X zV6wFP?YqX?*zKW!lM-nb0fa1uymwV7J<;Uy%D7h?KKVvZIlt=6tG5q+dQOca5tJrT zxLi-fawpIYEyZ#(rOAlIq>*?Fv%1Hr2@?@zisZ5xym@V0blb0wQ`q-cplv{DFb-W8 zAW~0!1gCvYaP{4Mh+U)R%^V?Tfs~HPLH7o0jz_w>}TUDb= zcI(w@q^Jn~-22Mzz@u;X&L`2Mp=`C+vBR+)mJd~3lXLjrbJLpwA_8LEcXbG? zd*r>(@2%T7u_;EOC~|mUzdHD!YeO-I{puj~^7u?wZ}Q*8#MPPiFw4f#OcM`&-0p&N zUhQJL!TYcnW_1#Hwd>VJ5Al?4A|bnB{n>DT69U6tjmqj3g}Yt%YdkS zxv@hJl-yU^O`-Q|z0a$}z!-(h5Ui;#%ueI7s0Wq&*L=nH0=OZ7^_$|deWmJ)Wp@0( zG3jKo2*+rZcF1p+(n4qby2*d31+oYz}@ zEZIQN*}Vd2Wg$-M#fq!E(Bf!Hqxk!RyXy!D*>m*d8CPAv+#j`rA$3DZjvNoJJyH;h z+2?`xy+`eyDyN0JBW=a|3>U zYE`XvKGX7l zE|R2jdN%t=h=RQ3M3t_9300$0ob8RYonD>+P*L?#M;l<`iY^oZT&MT_xii;;VOf1% z;gf}D(}-f~Cg?0edwimP<&pa_ErTw$RQc0O^CX9W)h6p|{GP0u7~dM+;c!fY+~Zh} z1^x&XPG^5oR1wJF{sG;+<^FZl$7?0QoY>l;7wH7QxeVG)YEM=b{we0V`{7?%Z1I4{ zyjz=TobI2!IK8u0Wd(hYEm@4GP-R9Vs@I4P>3?_&tFQ&_vnrx%yt?oRAmOYx_;J%t zlf5LpQ+6m(_}rbVy&u!tTnmcdx7C#!KTNWQMKX9*ZcjdTN1Xv&=DW+E1vAH_*wiaw zw}CxcH_kmHx1^odZEX~B8_TkKjxnCZE0Om?0k*7TcRA`D?j(K()yz$ z_F{U-BXsDyU52$RxNWpp=ShBx*eyCoPG}2B0FWKybb^ayjNbX-)%SfOhtq4V2SiJ6 z=hg#v*(wST|E_JJ#ZZuL+Cjlki~S}J&r&O2=DhUuIKCj zadSSgKO=bj{ik1N%=vbmSfd@|-QrT8+0y)Z-Lp&YU+eq*LK^dQI?Odk=m*j6yYs$Q z?dZsfE6wd;S zFLDaAi6l;jB$@Ve!4KLVGTjF+83dd<%7eT$WVy^VCi~T?i8N65@uC^6(D#D1b+QK; zLPjCbw0n%Ntx-wyQ-8; z-n*42h|hHN+&jG6p7Tt}yeCf?08HC1OwjQ0{!=pxKhyN=-Z&SBiHvNv9pNkiMoFC% z)MK+Z-XwbCF55d?usD(97;1UVV_Bn+i<~&=0W)QatkL>vwj`z~@kksHF~~u>#|f4f zp$DytPYt8F;d$8>(~tRlEIT%HLhU4`Q|?0kboPvvz`N@b3n%$M(jvsg1@Z>(%0&si zj4lh88P@{sXftM&(hx7&TjPuP%|m5{Y_fx|2qEkJ5kIE4&(&VtSvw7^T69cB4u({(1# z~C?SH_^|`zK zxlM7a8BL2rM-nr73h+7AIXw9y%*W`#QSmnNy{K^9(oyLWF74EiuEfo*A)HLp`qg6R ze#C`KSJVjnytWg_0SW@)wWoBa0e?goWD_Z zUWlHCqjvS_DLO?uQ0!tvY{J2Mv;L?;jN71`4CzN9`kc;OOZRL77M^hFev_3G)UNr3$H46_NB_F- zR+|qnxP>&wJ+@AikU#yikKk`KoUA)uUj#Pwg7l7SC%QLA2=;<@IOV6?rRI*CnxMD7 zw*{!%_>Iyv6KQTWv%cIXq|1e&H)}WaIOvj!$K}U2ioKH~yfExX4S8aRs&+BbtorGm z^^0U;FBJ7oj_k3?sQiRUM-hXnuPyLuV{79^k-dQC?CZ7jUhp*C>)PW6|Cgm=0g?_2w^&kReS4_>KJ-`1ud|1XHHJi$>*`2 zQ#<#a#y8+cD--U{mb-rGqOG0aQ&&QU@%D~Nt1?wD5n6s9%e|!}8$TOTjm9xB)|yw*G8l2MkW*hPt1PthunXlBcRg0`OEPZ zmD^g2Kupe=(Bz*Kncl7`3#S8Uo}*S68xDo$(Rzvq6b!bcB*?Y5zKQm-Vc9Kuiw~Kn3Pjl25h~+Svfk!x1c(gZ8 zw!Cx#8^0p=NM8vNi&!1(>1_%Jo4Tz9FVwW^Qc%Mes*tu6E6(xR3@{Ha5zoH(1fLOq zp98(1of4u3f^}fZ{8OlJm~rLFJkNlzY~#k^sXMX<6Q|Gj=LQ`;aL9*wimmjyBYT02 zP1tGL)u|)#0NU|*Iv-xR5xCs`;~+YRj+RlDDU- z>~?l1yf4(;C|fBGii(cwv2m>Y{Uy1lPGZMAx^(71aaFNC@h7}IHqe!LoNE)+q(85L z=A0e&k?$AU!8Zz1p1RI4*R5sI5nCr2M(7{rX^?vFv3VE4zjxA~l;(!>xF4ibTuA)V z02>EGe`0~rDq}1eMzXEZ%L9WOw|mIZR7_{+akR;B+2eiMaPs$F_bH`f4UqVgy%g|r zg#;c1nZ?P^;aiiViOCmoMPD4JT;W4qRJVXDdQccW=xEz(Z5NnXDep|TCr6!}nqO^t zkM?j+f5yJ`P#AclPx4JUf?EXZLXl-=SzBD|z~@?&C7!f)RwBYoy5LB;2B*glf21-t z7P;4~>2p`KQwcmniI}oj|4OFnX%Pvs^uv_R29ulq-di+=4+T&nHHpF+E5A2ZI85*m zoAwfN!czPOL_pdOJxixb) zs-VL9L1l;5jmv0Mwv7$LNC?tcD^XZOUPM8eeIr+5T z3YeX@PGAaML^dC9I!z65D7 zT2;rD*_{-NyLFS`sp{mOdm@PV9_S1t%V0X=98wuo% ze!{|9mQ#2N7zNgmZ|{xA?%kQ7c~hdDatK{$9yx;|@DAdcv$IaMJPRXLY~$)@?o$k5 z$ke<;)0&Oo{r|jZ8?DwxDdU)#wJhRP#{I($=TMswT<`254?Y4?ueoGZk5+b`lJnZrP#x33w^lGfQO| zoV>Da4*)6)IQTbAoOZP4COsB>7%6}-(5hwIaw`+3#m~6o@{D6BbaM`91%4j$uPd_; ze87MVCx`^Kn{{?j>+^b|>8jR@85|}a^L^XR>6o#*%9`K$A2Hw1kLtfn;9LSV#%q`N&mZzfbdsw$oREHV*PEBs-F{6#v_2decz6&H+qsHZV{%u_pIz%8@u*7^e^B3FtN_0&} zR!#3b7fGsC&DgeyZl@}WT|^`N$@=MRPqeuyfR;ag5eUpmS|O`$mLlg{FG(Q0#GNU7 z=!eU5gR3Q9qAWV-L#j})zzDQ*gmh$LQ#>Qyz6jST?@3{KnIL`%{qzq9qn~Y=ub9}T z>lZx-H$-ja>tE!FX6b~RHdWg#9yT2}H2s0MogZzDc_MXC5R_MKdSKm3iDdu**kBvT z&BNwiRgc_v0Z)SS>5-;5WU|ra!s#xCbA}$mKfCMd=Il}H+kOh&X#nbYn&n-AF`%ad z*+`BO#=eShwrQ)bPtL84Yzp^-LHZ_$wikXeTzPQy1ZvI+Xy+jMIqLFa2x~V8&=EqR zvGZY3{+gEQV$;8W*u$S1vII41mEEBFGm3xk+LJo+%{r6RnS~!FkxO?L13@;sowW>i z=y*;tc#+94FX@7MUw^R3_`??QC_bt=Ikjy;v1KPOz5>JP=1>nLGPu2aeWFVT38waN zum=}K!xb9i3HntrI-!+8U*#2l!DIGouZz_X)M`FjVbdZ%NYHTFO`|2gQe3L=K6%@N zzf%RVJw|B_tmyMZkp2CL#{uZ)+MuhItex=CiP}c@kgUQeQ2X#Z@awJkWP3)=BbBB0 zfA7jNiv zrXB5@RE0&diuOF~nW-vgqVfASt)BWMei%N6*MkB+`7+yM%|&*qz~9}ax|KLuep~9o z_sy>t_`B}H0S@hs?V)Qe#Ni7M=}fEPz0Sr|atPeBK->5lvbX&{oB3pH%bXGp%U0r- z8YMql2sbV-B0G=o>b#(yA^u`}S>Zy|T$nnYh+vSDw`Dtg9rB>@$iP)aPN*wR-X8L9 zSyxmVs|VZK{e65%vIRSFVx-}yS@hEKUM9J6fexY0gw&fb#%-bVN9^iX!)yW6|BJo% z3}-uj`-a=9s@kPR5pC_7v1ig&OIxc-)m|y8_KX>|sgY`p5TmL_Yu6?Xir9%&qqf-8 ziXa4c`oFI0IPN$1ald({|)d&*W%vg)2?x}6Dh94Y3YPOI8TV`z%8>iz=CM{(sxaGMFc z#r1`t(02dd?sFjjh(c8^V|>sPwBG8(X&WgpqEu^)9&b!>#CS7KN`rwN6uUlCxCjn;* zol#n_o@D~Ck{D*aQQ1t2n_tNBTd6SH;s{ts#4)mOHo?ZdW+K}RpfEedlc8b(tX8xG z%pJLJA)Cqf*FivcRppSnkczteuJU z@DTj)^%a~6y+oR+2Z&$E-?6JZn(}rJGtpZ>c)j_KGH+`Tx?}HPw|u$;wGAR{&UdST z6f&E)eQvG5VhNdA{Ma}FY@lnJ68bq_)g25t_cdQYxhfuY!K3o@)C#0E7m4RBR8R(X z^n!RBki?f!h(7#1zc7aOQiSby?Oa|6Qs-Q0TbLE-d#R9fHWj#9^|5Z-dgd4r%vgvD zUX0^S^O{%dStp|Wr;(dwPP@V_n!Lfz^>bl#QCboW zhP-((IwH=$D1;QW7jnB<%4p8CzL{Ao&!}RTUVdli za@e7n<%*;_NNQHx8CRJi9dw3}3y-JY!rHbYC4+KZpHBx73iq-1RBtkKpJKPkWiuxG zQ3@za1?*=EVvt?P0#+k5Wk+ELj(0%R&}Cma*4fe4*h*a>AKuTyBP z9sO8hQTtwie^}e@KM3{%D2x>;3s>DMQdQnF3SJZh%yuVa_ewUKD>PNuL@*dFGRkA` z`+P>0u?eh%Q;i$8U6GI{I8zM(91>N&S9Avq>wv|{ps&a`6g6@=R>V%bQ?hqVEahc@T<*va0D1!U0@S_evhtem5QFLufFu=I$!0}Sfc+N9MU zi*DsXK8^(N3!lcqA}%N0(PB=Y5{X}Z9(#%P<0TJ|c)RMy@dP}-wV*%knV)uLtVaCF z{h7PP?Mn)q`CUFW!2m|xh$}>y?{dYcq}ikwPrQrd+vHQ za1tau>Lg&3UiZzg@T?C=n9h`;YtLnl=FspDZ~ZI3v9CH7FLww^Ne>^GCQ+}?MpR2# zex=KE+VEymiJUc3eF6r!XkT)nR#y>jP(4Ba{SUgrcjY4CexZ}5_UfoFQ`GUpHHCgt zazIlsf~SIW1)n)5@Jmn%WUoMt|1=%`<;6E|e$o>MbsPtuc)7y3+09Rp+&>QjuF)$m zuC_k<++|37A|&5@g+xKgXw6HW#^UZK_7+DcYc9D~O^<7{I-W|%%)Pwtz6UZWFMZrq z?gcB249?yVdIUbZdpxKaBF5e~wr2I5AZZhdg#YF&`f8ioM+wuXezP?$e+bmd^2f;~BIE;^-Y7C#-EvL$X`A}F;@iHFRG z^jodF4ATGW&ed`GrVP2!j=s~i*q zFqQL1GD1;pV_jJSOgy}ae?cJbpUdiPyQf2kn}hR5a=g5{+{!?1znv~AbAp5YN#KuG z@4pTuXFNx*dB5}4^N|8p8LeGk_T^5#YlU_`QLVekdd#v?bG?u|`q4pUu+@mqc}v|p zU>42xWsQYod6g*-0@%vAkB1iC0m16K!nCUN$Ae z4e~XVXN{z3_aF6$T|07rw4i!Wk=zE1CA9s49y!j>W$4ihJvt4gncJ{J{8X9mbf|$n zXqx4riprk}B!9diHfaXGV-uvgu{BRDZ?;s>qOeRM zR*w(=P6|QK%*&vm^MQSdJsP*=-#DxHoH4I;vCNAHg&3gq)lWz#Li>1$JNx(($;!}o z3DnLlxx69q5lye%qp!5_21@>IVTfx3Vp2IX;_*k8KC0xfn^ox zk%w{P#=m%M6y0gqwq)Bv6BwOuEk#dggXZ{u1rCf}g#FbVW&Ac9a(>#F9?`T|ksG0D zWy{LOz0fpJ0Pu=!DsdMYABo~8w_IUzz9Y{ac)0bupF4;$(%h~bj2(v^wejA=RD3-0 z3_2bT$%iJ|P_ZG6c4BEr_JQW9+;fSVN1o=ED$KJc4ikr8Z792sZ0iH*Pmdm0ojx&d zJ1ZM#H~&dq8tcIfH8fs~F)!gU0O1E?KeX{UA8l1qGJ~Hf%zhAUJ}%xKPLRtK9rq5} zdunofsYOF_%lxv#_~(wSxbfE|JY7KN7q;Q)(EHaNJovFYKYb75ot;{icp zT7+F9hC;?IgFfiSPwogy0hd28U)5QNcvF1?Xp_hixE$^M8dXAPfH9{qxG+|op9fw~ zX6bT71Ew_0TBqNWYbk{60OpNsY8c(hxA?;7CLbFzcXd5->J4ABE2CHd`>V{hb_*L( z+v`v@vIIsEoZ9s*<)}34WD6zXmkSPp@R!|0?OV%Zvi!79#OTbB_^}oH6cwA^klVb{ zoi|e5&ZtdMzpru^6&+Y#%Y7Do{<%gP<@ri6PH;)B;D#Ri6#^i!0018(N_0Q>HLsOT z(C@9iX%dOnu{Ir4G_8;ptL{&u2#ijo{M-gu9XqabFI~J*#v|7VV(6*ii&B1GyMLK@ zZ@`HqvZAnjSZe`k;`-!>lWyc8oPy$V@3pe5`VzHmKORD+%82$9dgxuVaFW0ZaXaY2#MTHNprr;V`dF3n zzi==wBYSkFf4Us8tF++aU-n5sbo8v5|1d&@CfnTuw1(y6T@iMhHYX_sts95{;Jiy= zy-ADx-VD4&ln<5zIM|vlhV!-KIl;tl%|i@#P-Cq;azVIo72IZv(rcO-_T5wFlb~2& z7bT?*H^+Eqsxk`C4x3-`X`83WT*u^_^RCVMM@EYt9OaRp)@X-!u zbg*FDpK*u%xg9hfE9L4pu{sV#v;RX`9D3{rS(a#woj+R3tnb*U-g`ddv^68XEeG#B zOc+UfcJwJGlztW|sBNh=7FZunj|5T5Ps2=lbQ8KFDKY^`z=5q4>^vQ-txo>r3^0_I z2Q3v-0W_6-+HqCX)tcFEi3tW%37z-}he{I%=oTkD7H@T&Z#B?RrD>V{*H4#Yoij~D zV;>?z&lOw|M{dD0gq)6nKSS@@sx!dr$UkRKK47Wkm3On8&veCCy9i9deKd>56ztKC zu({-UI8jVIX?qLJd=NHv0X9=agIBBwjZHA)R+uHHHSWG|!dA4#Cg}8WdbYd0vr*p^ zcO%K2V!=1On{S6}Cfz-txQ8ZPzgj+ao%z=`Gs;Ynt|sohF&tmAS=s#Je>5=B)_ao`$qwC-_tulHbsFE~80-M1 zQWuOsc(2faM{*eHFMUmTj)}C2+H^;3U^i<67+-Zbc4>gqLwur#HbwYx@;bk}ehGi}C)h$5jx(|o2+&&Acc^#_r2 z5GUR7(Op?>7MeAE1KY4KPt|0v5H7AZjTC>$yFMzcWFVGjN`pCh7NVj2bsl(QjBN|p zxuh#a>U*frbN~7%&y-!Qrf9 zha3U+-MTeu>2qZzxDClybm(g=EI+%!*OPO{WPI-{&G1LHl;g3SW)kTYB#*}6lgjU7 zd5V>e0)D!g|v~k^-a$!S|_$wqA7@?fRgON-*R#A zn??Whq#66!xVuZj&3>76i&SZ#P~KRw!8cUyv5Om=k>P^|LW7p0<6Z#Z;AcFv)VYF zpPe=~gz4O@KIPG9$5%$o-GnkMoUGjB6|tYHxqMy`+f4;EN>I4<*M}D_)?RQI9mk*) z&hRr?GH#a39b`>2%NL&@H1my`@iX1A2Xvw}Ji3~3lR~PquF$yv#<$q**jd3&rNe4DsdIWgkgJ@oRI7F1JXx=73qaTwE9o+$nRGQ$WF<0_KyS zBcT_;Q?9c$8YzP7%qCb1z?`NURPfgi~ak zSgua8xEi2}f>}1$K}@to0h$&v_U8o=-zN9yP7g8+0u)C-&5-rh{Bq3+|ybMb{2M_)_q&N$s_6HvNVx!}BnDDt?ZE|+&bOjmH7cKXj&YkYFR zvLM#Pf&HZ$a$WV+T$%6DOyBRTv(kc!brNdp9Lc}K6JbtWqPD1V9kqHFv7lE6TQd9# z`N7(N!Kx$9slj?6M8nG?M^BvvO#IHZliEiECkD#{^8?K5=Wnu?YS zIBpoY9T@U>+q)G)pA)bya+)Z<$TNFx%$T|b z)*%57T=KXfV0PRH{Er_!w5GK=hm;QeX6gL#AsCHg1pgy2qO8ar&85hwaW>TH!M>X7 zNSscOQ~9(4YQq97u5{*%5@ja%;uFB7goD*Q_GCVVeZpJ&>hX%2J6R5j z6|r$mKe4I=`soNXo)OPUi0V|oE12mpE?YX$p%m8tz`1YQdpO~XN1C$)xRmST&;TEf z*4vh_zt<}{EM#j9+ZCon*heXK55e`u*vpZshlRwxyx5Dq{y|LBB+oj^oo8ey8(jIE_>b}8%~n_jO2nC5XG0;8=*4Y5efNs-b;FFEPymeS$< zza0&?xv}!)N~9o3<{+A*m$0{9bM>M}7O`nQOGn>QnyH&_Y^5$84pg?a<>o~vP5s8p zt*8P~%SVIjcL=nUe8c1I!UnL>!2Yk}f^EPjKJ+1IQhv!OE$4`@E@J&T(Bz38{s z-MMrZT1URIyX4s#P+*xU8KVFFyDr{p&UtV!+~g|+;07ExY?Q@4$ZDpD>lA2wm~>ZW z($lh}nl`$3vzWVe_iYN76an*5or1q4Rbk9X-Jp1GkauSkBdEUf3az}}jaw%LrAIe3#fuKjCwr;TaDLUry^rZp84GQ?8B-61Dfw>nauX&e)U%~o>| zhQ_cq7BIF)^aFMhsZe<^N)TH2m9!v@yGV0{WIG%fGNy)G9R^H5tNVaqE-x_ZCTKd+nHDiuS?ifwW`RC zRavcQjc6jHcM~SPVRxeYRmr)x0H0ztgA%vj$@CvFsxDsihJ-UswOB2Rc{0q(L^a*6 zyc4bTD5!>N*P6fr9oqF9M$UYN-U)Nr_R+iK>AhHNQzc7tY7i8BFy8ZluR>m>fRnSd`djKFzXXi zZ9}`&Lg4&nrx@-UZY({azx7+k_F4Fz#cN7|D0pbo->&}u)@FL@&&`0AWLW&uTOOs; zYLBqC+SvsoFcxlDe)%WlX-ik(mqH7%pXDGhGNR;oJK_cOvaO&_DO|Oe#sOXAJD#yG zCp;y4MY8Fr)$*o%hr5^D8HjGI)zct7aqaNQ6P`O4+nV|Yn37ocCOXa!aFPb_UDMXF zILhLnfFnwtM~Riaq%ddn6%}{KFgjE7m~6@(p}n!Meue`kdt-&Zxp8!_&1KcuC9_4i zWS?BjB2=nUA)+0(Y9THbGutM%_7~{Iu(Rofzc~@O)87q~*r^~1tbtV@;kY7&-cn43 zV7BsRSzv`49!M5CU*z3b=8+ez3_UPwCc=p-qxHENz15Ryay;GAiC8(|D5X+TD*uZ6m{5=HUnM@5j zrF$_Ecryp;IGsswn;^IOC-PaDos!)2?jkKi!f&Qe`rytNh%2I24KMrg$_u~C(Yo^B zgD&14i#%v>e*MuxWz}fN5xIrxuoo9hS<)Dd{KS6?2QG7Yk;pYnoW=bl>#2q&{l|;zp$`cx#)OhWbs{aBo;2J{aau5>FoFIC)RjAcdt>youp* z=^L%rQW_ksqJ`0IaWvs{y7|02$DPQ&))blRBelPXK)FSYZ7~BaO<>V zDpIK#CJxyIDJa0U4*OcA5f!P_Nk;QvHX6acAHRG!zh6C$t1Goet!FE6t8tW9)onps zyZy9f?1fM_;)CdU1Tw0j0oHKXq;jb_Em_>+J z>xjx@-RHw~WL1?{DHv1I-pLm{g3O;)Fd5_&A)wqz;~{ohv<=D1@64T9$9ec8J;hGz z|Nra%H-8^WXW#UKy}y3Ki^W1F)>r(BzjABA3Be^*`-&rGr%DoT28sE+hyT~>qRG(U z3+C#7d;rJJee!}H)AgDXM!Uu#sy}YdGQ}{+^hgGGPI$oPmbnLttpaZ6pIbMN_gzgp zR^xh>$MiRseXRK?eNz@jap1E2E&l8weETF6kSIlM z0&1(Z#o)svs6Zn;vbG}LkKUUkPaSN<8cwF`G?E$#{gK}ZG5RK?H#vlCsb26Hk%M5k zSODe$6J;sE9H?dfpK@x*^^M9ukshDrn=jZ@XBof@3iCU2-UoA(Ah8dKw-s5|Yq8o8 z!^j3b2BTv%+n2`v9M-!iA-v(1~Z)n^EJ$Ez~W#ugKQ9#T7G~Yf-g!Nrsd&gkGSw=@>t1L z{6uH6B^t11o7Kg932A!0tuni|^M`J}WwuY^lJP$4e_wO`=X!kNtPkuJ(J(lCU_6=* z`LC}joiCFiiBbvye*nG8UVXh)*h+4dmD$XYK9*$-y-A3PL!!U`s8T9qg^VP?m3~dF zItGeu^Z_Mt%AKB@nIT?hKurXfnu~4vtNKwbnsQuFPJ&>=E`nGHs#SxnCCJFdzA>cB zyiQde3QCL|3K`&<5|kCDC*`KqxrfP!y}&EyZC@BpI$8&G&L1>?IMtBD`(OuYfk4_Nwe8drA7k_os^3_o=po%#e6OpJFJnSXlSuoB>m!YExm949=K`; z!CA_4^FM@o&A-Pj&PspLC6J^uW*~b|+g+D#od;5m&}C+3gvU~do}%09Pc#0Bof*g9 zc&WNO7WRtV>fF98nT#CDLj`uQ?L8g2jcfWdB!hXl08&3WjhAt$(iZt()#Q=JNkMZ=8X!7$L^<|b!=VI#X(yMN zeaDRNcvPB8k$_V1AlGE3j2m#l=gQYVm5P`jqqoirK>N#Fu8;0Aj#mziROxAq)Swt9 zuERAE=@MWpdIG(4wSHG~foAGANid3V(SL(*lz!fBun-;Wb=FVn^zj9qU#D6lBgS(4 zPl@G1T}c64e1r`>7`m^#*<33KR^bLa&9Vy7`#om0SjAHd_|ZWG))*xCyOoOsOq)dH zD1V$m;r_t5i92;!-R7?t8uxpQ?uq%_NrP2ESUln>;ylXPS1o?>c}(hI*2`6z-qm7> zR*1Hr&9mKoo4dT#`t4%&lpmx;(GrRHz3=UjHv2M0JD2jr1dL+J?F*}3BE#=t3Upy+ zXLjiK1m)!Ap^4kRIvlt-lEI(#U#s>}9aR!Af|9IdJDB8#?s3~|{V|tMV}L=GDXlJG zm$n=0@ibmZITVdWRxE^T#kEGsI8~)L)>9(54^w_uv-vx;GM*W)ajMhL;U#TmL!C~6 ztNflVT{_$PCWxVx17<+3Y|fX_;QPvI*8Lqt4iNTzy7jTUC`DAc@{@WgVxC>F!4wJc z`(D^RBr@@kHJn)u%E#nT%`0rQO7=$ns|1c-hi zhO+mbZQZayw@qr@#Vb-_;zYcYGcCt|t4Q&&Yb1Q_gtEgfkEa430Eu&dxwfR+Cb@#r zIRDhoZ$^0A8f+@ss&hRSp6{V;wf(y|`Gu{c9^-Wb>Fs-&=8=fc7pqx~d-vlb@-}5m zhH0lb=z`AFEdWlzAG4mSwmvE(R<(b)$ch$39MAFk@ONniO(sWqs% z-+#aw9h=wQL}dBIjE8|i1SVHXeJPVl8#nT`g@Dfew*0b<_3U~IpJW++biSpKj-o_d z5aB57#(B_LzL#(oUmx7CfFP2)Opx?QJ4zqpef8;Z{dxun%0cq@ zk7ZLWkNl5lhrol&^9I!tBy4W3jIcp_S3S_4*?G9k!rxLrh4733mY|dem0wc5%+a~Y z{GMNH#J3Cd)ewybrH8tK_Qz=*&XG--vyWL0{@L1J7s{jMEi?Dzp|m3yez+;(D|PwU zf#>|mUce_6j=76f|2oPvn=gfvv9zulllunGW@*xbRDNZaQ;s}`dvXcKQk(mu&fnfs zb2#sH>F9OLcU&{bcgp|vPG9Xv;O|qliw24dE-n}IV9)*kBk@6{zK-r>+r2C%-y@~a zw5#}-1m9Me^tysB*EU=zllJb_GnDiR@~Exp7sTkk4Rj@eti1=fP zHS|Y51^-0=K1GAqcIcneXvEI@9XrkKzZ#ZPeO)^1&F^3RNz7eQ5!<+{Jeflp+m9gu zS9o!g-i-Y#yq@i;GTD-jJe6`08*wSID!pa?r+2`yb-*0%99%PrT;(N}rQVf5B6H

@h)naf?G6ucy=Pf@g*yy_Feze^syX+kkbcfFM!-BSMyNDi{%j1GX0OJ$5bn? zUT~aC$oMSD39qp5zib*&H<=0jfLZ9)%6nnzuB73tNbl46f<4p@h`kalvG2?X;k~Dl z!*cudHq-#x84>CB(Q4i7qe@Ukd4vIa?s1e7r5q*ijt4a%l3bD<8U)p{*(={@P&y;E zf4U`XT>FJa_s@OK$v`@7oHYAMhOLB)64!oln^CKlUAAg7wd7)2$R%Ca{ednfM=$N- zH(j`^tbQq9(q@HcNAS+hxA1t{+G{XTjs&^(sRiiuJVMFWhrPENSS=Rgmkf11w6ls% ze`QYU`^(Kg7i*GQPmAUMs~>5UIwN)~?v+`vWS=*zL-zM^{g=(OEf^Bs~56#A5x2RAxnSqPjO#ZB%@8&5~5VflnM_%BKeDb8Ih5 zu}5_&@Cnj&yM3sU@|b3uD79XgYKhk8Q(7Vhp0nC+s)y3@dz4 z_ynlyMI)&M9p`U*P52w`n(>q!y-mLn;hId{c@(3m&7Ybd#M3?bysu^!z6Sl~DF4Ax z^wWtwSJl#zZ+EHtQ6+4=jyXFb&1-L%u3Z=L&)vvE`AWK~aDr|vMp)1R|CfTF^Z zR=^ZihR@2)lt|h*oTY1cota?2*4)AI){3`X$M*WuZ-_AzHbcs=B!v}TLidV(Ps*`! z)L4OsWxibh{_iDiL7NpaUxE>~yji3iVddW)WY>(F^su@weJ8(qSLwVZ{Irk6{^OAW zrJOAjaHEv1cz48=^vMlj$4All51qu~wWmQDjQemO{Y3wIr`39VU(11txtL~izU`|Y zmDNn~6j_&{XMD5M6U<9dAbr;?#pcWs_4)3f_W@z&JJIsSuJi^NF-*tBHA<8l zwwP+z_I$gRj;azqns>SLbnfB4(D8Q}2*?4Qx~u4Kn+G6P8|ZawQQBk#i=>)=8bmQo zqLZ)OY+-3}Z^M6ZqGZtxsQ1Jdqitz^*5mn=^CLu%kakQy9_X9(S+T%zCj;40hV>is zV~|md1&C%h(_&$YNmkPAGTkTJUfYP^-f!B)V^sqG<;?`-HKe~5-q11&DFgy$&9(eFjg#C-0=*KGN6si+diW%-G+N#yq)!s;wx(KpII^twop204 z6)wetfOrSNt^RLscjS+#|yu+Cc>%x!oHycb1IyCFw(G}6+j-w1{0n64v z$?FO(74fynDY}+M!^0_1SH34|-}{Hzpz%)ESRuaT_dGEguzLta4K5b-t;`_Ss)PoU z`7%WKEqfQzWSdq-cn3NA(o_Rk9BZ=tNYC}k`tu_u*-{nvWhvzM1LHjov2wIdbI@$6 zRKUlK(SmG7`cqSf?zMbfUYQdkk-&YwzDB?Kp${j0On(NgmhBU_+LB*vti__n@S z|Hk}>0DW#HOi-yqSw0N5a>_=z)kgV!``k^!rQP`xvvgVTZDxyDu@Hu8N!P8KIx-g= z9?zcexu{)HXV7?m=-$>8e0x_q#>?f#`WN}~!ipQ_M2gYyv*UIAL!+&)SsS4!SPmzk zS6IPwEsu+u{$3(wXH(|Isn}YxvKPACbjg9IK*i$y4%%X&pb?QUq<7J)#^{R5*4sr#k>#i}&BR?bz^l9fNu*+-fM+zt)e8MGt_vpjd;7q4xSpImmma$$4g%2nz0m zzgT%wZ!Eg!y5xwanVgzVyy+kRDU#B^9@hZ>c=^c$;~wx^AgEdsJ%9hHe`;i@H2X*K z-_qF0f0*6l8S%Ng6zBoRjra`Y90JTT_o@nxF8!_8&id zR$(X5NeTHqF2$air+VJ{`u*-kav{&kg(mZ-YSl86LLoBeB848H5A0fi<^IeN)n>{` zpGP}B604CjV z`lAB#m(@}a9N0DPqZaHrUG#AoQcvXnT(zS-A3RX>5d%{?sOf7#DTki%^A3il@wB6B z^blW&*{@_^oW4Gz&>JTm1U304%5eE}%Ofius1A%%j~D7<*1Kww(3FkZNH6S0nW;28 zGTP4QE-o){TO~9BECZxExGBD>Zm(JC&W@T^vV|%Q7QU?NWBqGw;NGKfjdXal^WfG^ zOm7Jt-p3U>-8uE+FR&ERB!w8J*f9O#-dw7cBl zg&@=TXEFRv794kQA**_HyN+H%HswlBC4t5P3luZe^1JO`DSdpS6vbm{rxj%_@#l&> zH@ZCGY0*s#VIX>KGCsVFyc2BF1?&REk4+BcA()>tVKznrG(QGfnX%TWYVf1}&T;Io zPTSXqYu{=TD4Gs*W_JIH*UqHm0zkJX@?H2D0oz3sHy>_sjucL$(hM-nlP9K?>ia#) z%hVa|Ke)?zH+7cQ$Y)fQ_$TG%qX(xkInm`~$Cv=^vSgDZ9tZPw z$FO|i2x`Se`K~`)^beTk_Vmn>SGa~G)LKCcxvITI4$~a$PQymAA|Pj)SIJEIoopy( z8DeNq{KT%P@9kSI;*lm%P0|41y=z~s&Nf1&;~LtNDQ!eSAr)0#dg((wYMJ!rOsaFm zCPtVSxaU9U{eO5T?bhC~sS%|j_Z1==iOZ{XsbF=$2&5;`SqE?W)LWiY7}jJuvos~% zx-Hy^Bso>ZJ6fvJnCMau`r0TlOXo6#J1TrHtCug{`1PFkS)kXv+=+hiq4l$G#C`2R zdwJD@=%!Q$ieExU%>r@x?S=v$l%V7s+OO`UG?xvOloI}ef_in)ejT>M6S;%^$aSJOsLAS8)i_X|DAV#;wEvzrl$qdVI>{v_~RBr!r}%_Fdt z$6?0WsNDE~_p2sk|6X#h?R%ya((Yx+0D)|Y_#-;@yZ??d?Ueu;&&*TzMd%L`L=2UEiS-hq{dtn85b=Kc z1yhcftWvu9FT=rr@P6q`N)AaGo>BHAuBqQ0oyUcAc$OktEqV2Xc%iYUO@8*a)^|sC z8K>G{!&Z@(uaVw^B5Qf&#&sUg3*{Fi%lRmx$q@(nkLK%#wllcJIL*ZX48%@!!o(8# zkr>b!Kz>r1?H#}LqB+eJfX{a#zIO1Remd#|*x2Q(2^a#VYMolX^^Z?0`~4|v$w$bf z+`ps~KC=Flf*lhBzbyeR8;$gQQ^&Gi|6HyFfL{~~@jx0zw)0av{nkv?{_7?g|KGgH zdg}!+I&tq-5Rd%kE#?3Z?d}AZ@_LV($pege`vQ`cbulJuR1oHOqNXeG^A^RAvZ0ks zveZv0nvNH)VtDlr_b1uJE_*R$RB72tS6LU2$<|RkIb)X!G z=B}>};;w=PdXS=^lvl_rPh=m=Exo%Ok$Y;ap|<$=8D*&8Sf4PTAuhVHLtSOcYFHL= zr~iBY&#OMGuinZ7S4pfYn(y2#R}fc6d%CBd?`8k~5*lv7k@;%=&H7r)bDEx10DQtw z?eTDJg?zlh$omO>_B2whgP&TZfZMI`F#(65YpAWt43quPckUy%&9mPk1fiF;CMZX^ zc>G~0QsiB&sg3ZE&j^r@u4I~2kLh{t*b5q0h__ta zc!^$l{CW}G!RL_Y7a(O1F@<*~qcLA&&zu&2aHl24UaANskq~cJF;+1l!(Ey#EHw$e+HE-EXMA6^v?VEAaiJ_wrQ zNl}2I?ToQ2#TQe1bDr4Zvji>OQP;b_S{v@<6A_w4t$B8F{gU6IJEx9FBdxZmty^*A zF2L7D`95-C?Bvh)69kgNjz#7bYCj*q@IR*f{c`!_irr8s#*viSj0dx6=3H@l*5B`% zIE>0pn-scfc%cox2FciBvabo|9!oJKZ`6*J^)Y8K;`G zzP;0<@sP2ay6;JKQcJIGro#+Aa%w&)VUJBC&`j{7A2;8Y#Bis=6&>@yo#{6W&}g;5 zU+npI(g?MX883}*(TzIJY&F@RS}ukUp*0zN7G9Wa$e6X}8sCrdEKsR2IIo9G%Uf2x z+|W|~vTLm}0aU6rxr9@GcFtF-1Y_pcTqwdky`@lnDwvj=Z!V}tyLKWB36?XfK~I2` zv`cOYeVg@zAO&_x^7g?)83ZtMhT?aRkBao};$8W~esUnFOQ_x^3oo`pE?zP%mGpSi za8nxVp(UX<)_x4~bo-xo;x82L&L?uZwO8^d3fMWLFg~Sj%d-T>ARJjHZJ9h=wV^~j z8!nqZI$#hOWvKO!;*d0e&^6=xihI_j?w#+4alR^e%Og(zru=2Tm87|l)U|g(p|tXL z!ig@lcxPE+NmM1%;$x$82h>37N`7<`V_$&Z1b1^bdzKCu7n)`Vd^}UynW& zRb`Lruj;^4_9lm}b$|Q4FV>rN9M7L$P9bKD7SfJ`5)~S>Hq^JG6$K?Edbi(BrPMy7 zwD#FeDMtza6{@nGJqg;nxhsm&;pXVji*b$E57wdg6y-K+eNOXCrTmj6xR!NYE!$uF z6Fa*$E1u26-`Cc(UqL!prSnU$G|6Xv#C#Y8r-T%JMRF7t(ed3*!w!b+(lY$@daU>5 zw#`Pk41j{FyRYT?iS^%b`W5e_Sv(Z&>QX25z?%g_Pi@C%HfZ|eMypY`0{&wJm2%dg zgF?y6=sS`o#@Sc+{e7fG-+F5CsWl}0d8iaid$BYs)KD=DAP-q%tqt7;LJ4;tj^7Rs z_({c(zn}HNK|aiMYBn;f+Tw^pFHX{PId}_LS&;)GfXG{ZOWVR#up(-}Y=}IdGv?>4 z42j?Ah@Xkex8jj<1$JnkdalSi9t2odx7y3`N!^Fb|2i>X$^I*(dwpV4ORcD%OyCAu z25t3`(y($Bkd?c=6g-?f=Py?du92I<-s{gc^r`t*VtC6$GX%DNwxP}nYDVi@H+)g2>$(ipHHMb~zTI;2`=GJ?)bv^3)i* z64(8HK??I@1^eYlBrHbj$(NqBc_EHf%wQ~~{_hQ6Efh)|T)BiN8(*T7n2FCp!gTR) zf7dPUvQjsM;cIMnE5$TW-vO3-ta++PKRSF0)W&;y z|Hb61LttHruMKz64Z^DWdQ>G#L4H?v0o}#1^p}BB=}%q_M^3d%#yLiA4oPIA2j567 zxX2OfWxg{F-zT}cDJl!3&}y?y+!f5&82r@0W|x2cbmFc(Th*cC>pl~w%oEFz+@GmQ z-%_L=ycrt3&f$X9>@-d^!Pzr6-8zT?SCYrW$0MHaY_9dUy=N;r!p7`$&B z2c$u)lr+*Qbg!)c10_O^C)UemiXYa+=@t9eLuq9e!Q_-w_3yL-FJB_G=XjwLJ$lo2 zl~Q^Q;3*KXPGQLLI2Zq~&k6Z87xK{X7Z;4Q}uW^Vkw1(qA!5EJW6^3xXWz3b#%gkZC48x>n(J;eMoTXeDy%tg$0^jG6~m7jp%IY-6WVwJIkKRf87^-sm|;xKNo(}kZO5OH6D5SATcZZ^`N7I z!;icB49wjzZ0m$xb!Vh!`p>Jg%T#2>RFoqM|DyD*l2@+29IRqOiNf;JJKvANNtbpH9riwSe{5Oc zBQC{%<-*8Kt zp17_!NnVKy#akkQSMzEmY7Qigr`G{?1b7~)frolt=O;J49kfwA32S(^G}%5C{nA>~ z3oD4v?kUB7j5klZXvk?l+Rm{5ToqcF7VY|}){2Iu#NIf~94ouZ!h2|3wjN%S8XnL2 zS%m8Cl^cKNP<#MAWy>+$(k)h`ssD3%6W_1U7bXOLe?%%DGmI7xl2!?ZJ=292b{2J( zrgs>@D9>w_-vB+l9Q;Ip7**Vkd>NC`BZeyQInP{)GC)&K`DOWhj2eeXA~%gi6Hp_dQCLdfj_FqVdvAZYN|>AVZ50rzXL= zR}lLbMf8f$d|80bR(gTpB6TBI(2VRp_!CfpLX2IQ8(x@AMHVw^B{JiSGt{=uWf_V@VK=J#^!MeW8B08R|BuAeUu_ z;kFKBPzdlAYua{X@_JP|;dj&6npw~!!08RrwoHluQ2mqnIJ(&uZ+T^g-9bXe0j`n- zG4_%_s4Dd&eLoWOZRp`sh2MxFsn(Jl57EpueD@x!<1!3t=%bNaCJ4}!r(%G9M93Mx zP{7-I`Ha(w6A+P5Qj1%fR6qmVR~*^%T(+^QU$fxNO65<->j=4U71Je0PWBqJ!{#)X z*D>0f*$*H7c=$Z}TTAAT4>^24gJpt3OqIi8KAHgQnH;nY*X8x>IgGY$nC_?&A%A5c z>>Bsw&O>((I-9tZdP!nfPc%*9SE-r4gs(-xHchyA&K=C&3@pKQs9hyIYEWs~_cn9! z4`zXU2j4{X%bWZM&2c_L_stoH7-|||F55X$Qa16d$L6?*1QWz_kru@H!|bXdr$X4v z6P`iy_Ls&phHjtVG@FL_Lrt4r!43A(G>&R2GVSb6-E;#bEM7DnC#HA+o#Zc3BUG*A zP8x-X#&~ANu{-sVjb_pbjpJd}(Fm$%SuEWlyDBELV#$%}-l2*4E;6c}ZVB+bgR@*M zIU)5DiWqRUEoXmPaqDlrLYTGFmBi>-lsHN7aAx8)TjO_GMEoDp^c^wyXP5qMS&6#8 zcgMx3w%UZlRr-a!I^M%UM@{~QUS`?)(QR_LkPTCMb5bAl&mEEd8i(J1EQQ)Uh8N%Q znfYa;OG!U9V_lmW5^|2j2gVav`FYe-R?#%I{<2D=M;+EC;LYq1J}V2UKJ3gjwSs?T zW&0;WrBc5dH=o-4Lrwql%SujLA87RSvk5YgvX1;TjYklGS{?9KqHfjG*CHC1iDarM zSUlb*_qnoo6&1^!>LiWTG8eSGxJ(=^@~ zkEWJs@1-Dd-!niY7CJ;-ICNr($x1UFpc_*5)E|0nK!lrB6xRfF=l>YMMpN1T9Xo{B z{^^(@WDV_8QdlFJ;J&ioTedRL=YEm)4=f%^+0ysfqQ_&tPk6Pqfc$OvCwc8LUM|z! zU5{RPDdl>0DG10!vnacz@u@D{62J4^i-yCl@&%t&5ecPTTYO0WFZsqOl{OSs1qq|%A-TZxqJ2eTrE8vtkKwi~GqE}a9$r!usXxZmSk2{Rv;1po;uG8Zvu zEbe-XyPYX=W3e`1qkpi|AQL0f_R)r1+||xdQslyWf0N3;szDnyA{9_h({?TKPA|Ox5fGyoZl24fj~UNYj3DbKu~l z&4&@9R`+opdeZ`oGPKHMEvWCav+>Op{AfJ4`<>&KCVLG2(*ub_{g0}iGe4~U0F4bO z?ar5X!yUqe+;vYRU%7us{V2k!Yd{?+s7}?C)81pSIjVc0plcT< z>)x7HqV6g?Lc?7A_M4{?l}c5Oc^FC1TM|9S8-AnP?P?I()B)oS zk*-%f*ewToFX1VabH%(Gu_fPWimdMa^u7^?u$X0fbI%$I`O(yG38`#y z>>S3$9}!o)6lSQm2ntR^%(>>_6Dv-{0|89>Fi*MEw<5v969b&gq zH4ibuRj?wwBcqPSXy3G?JCAn{xjRb4+$Ta-tXr4K-SW+w7p`1ay{b%=rFw8;EgRD< z`LGi_0y6fvcAUX-#H=p=!Pe-lFCDk?9PRjj^2Qe$Wu)w7Rt=K!hf;XT#7;`v9^Cky zxpTg-Ze$TThC-Z@FmA9UT#2w24kbC3P=GHhgfp|Oz+>fRo;{Fc~w0P zb!591IZ`=zQhA@-B>GUNB&YjiWL(q418B7gbL-vbI$p+)!!*xhu2TJgX1$J&y^7JA zHJibFL7Z#7;l;v4x46fb-K>n|MK0-k2Tc&?=LaiuGTxjF{qu=;Ro;qxMVxmPN6aX3 zOFd5;-R3QR-N4hAsbjsd>wWNNG`kynfG_TmiHw}a;_+NzH>%-I;{uhvk~l%EokXuT zb!&s6dfZk3@f=3dAe#%XZbEdLqIWr zMXEiRMySRjY~E-%@veZKe?{8@vmbGoSJW~OD6(p`b$Ynprhuz$owVo+??hD`&}WWS z+v}b-(!VAD>aRF8*5j{m(A7HT+hwr3L=G;=&qMqz}7o@32k!0@eiEt^o+FXW;m z-1c!S8{Gh;$NGsxV)Cr$sRkGr8{47Dui$Dd&Rzdycza}7PLCad-1?O|CxMu9iMXYG$O zb0fwD#31)4 ze+-=np{m<5@?f8~XWCMI7TPhfY+)B1u%eyx{f{WAbg>UiFg_IZqqThsj@YIQA^h3y z2QSGhWIYv4)syqXSsgU+rp%SDDPyUAdhFR>mHSWy@`{jcqkE5KHx|M11uF*(jL2P0 zM#pW=MOt?fQEkYQ)3gzDv$WLH5&ifY?NOx^_T&L&ca8r&(^yN|i_GE)o9I9?>r!8RFtbjorRBs2AGbTb5DzF|u(W zABOF}2uXaj`RiTkZ%AP6S9%9?3gp>jhXDmE2{1Y6o|FE92akH@yE}Raj%P70|5U-{ zR3mmYHTA+k+~- zq>tizH_`D_Rf3n5wt|`_D3eJo@`m|Z(DWTsn=WA~XyqSEfiMg?m!~1^{L@_I$8LHx zSB_9OKwwp!*zc~ZtlA!0oW)G85Q*t`H@<9WjQn)xGu>b%;9eN>*G}{nx%wgxf(i31 zdF9(;Ep?`JDUsduwhzy_+8$sey<4fF}wNI;<@8xH|0gZa7_RSolODrWD3W<1~^Zg zjhik%h(}OKj5U#B-8z0|W0Vz`a#!zh+5w8{D!WgA*|KmUPD!F z7U+W~@qq_vP2RUQNzEd(05)GeHO<~` zBT^Wn+6k#aRmlg>IxoJE&G7zO^YgoD&|4~JdQcFkC^`L1R%v(Ou=m!9so3f@h5K6G zwrf)7zD8N>YkyLG^eF*PKstbpT$R=}9Zfc2F4#gR7L@YUL3?n)puX8VHz2x~A&)H4~3)6~G+`LVloXR#3fmkd!U^+YQOvA#vy7w*7%xZxL&%1t zsa@ZG8>4jF-G7H(HjVdK3)*cY4%?3t6g$Q@1#8tbs3FWtfL51x_8O6O`9ZP3)Ss}D zPh2Il6zkda{RGP^DT&S->~{D+dPdLBtwq0x^NuW`ulA2MP6c5b&u3l)z zhWxcgQnJ&J2G?lG;%;95B~m~@Wfak5Lj@gO~K8nXE>C*84>Ry z&iG29LUKN==~yLte=s<+MNP$y>YgYP46e7=vwXJoHi%XP^N3jke(g)hAhE zBFQo$8d0ykuy9K$hd_zP^WlWDy*#|(R=j?TLgm>g0kCe({$*1$;nUI)mB_(aqPJMsh4K3fhHO4J4CK(QAE9$to?wPuGHp!@}=Tx*PBVoMCau{2icu@nldXyg9eq z2U_|D2mejex)BpBUR3}1Y>4eK=1za9i+k-5Q>plTrqb)FmA}QEM)q&E6O2z zrpqAoHj`3d$ROa}uhi>-d`}2{-^zH&CgAp=G3eR+R@y#!ad7X1@{itjlh*Y+3_rSG z?6-JivLby!iRwrB(P6-V66{(94MvCWsX%F7n|}nzVu%sj^|7G`O%}h=v-+x&!z6<|riX3@CvBKVgRXn7%r$N0`xcEaI%(F66m;Au=FtZ|T!^cWiorYhW z@C*Hq=b9Za)yUgloybH!5#`Ma-s6}M6PA`p>6i-YLs5l|Myh#`3i8LVMVy+5W0y)4 zfPUBH9lHfBp^?)QfymS$UTS@NmjP+XAoBqUk?r#ZdU>B3U$N#F{f=xHGe-1^``~$6 zvLB5qMQfPO+r4(aO&vl&B7_=C<{?4Z>^GS7mxj3i<~?LrT4C931Qs@~W!#TErCiI` z#erH}lrH6EUu}pQb$4AHKj4%KEE`6)pXU2h@Bz%g*nE{a4gR5zg-m1h{dS{EYtujP zPaRcvvH%g@G@tzW@o9ErzsT{`v}d}0zx$lQ&bi7?%_u3K|EKL|1ZITN$QX7rDrr_& zv^`e3JHxQi4S!{#e0$A`L^B;q1{K8onV>lS%0?yO3B&yMhP$kE!`=_Qyn`VQ zyA78}=YVq%Gvmnq%p|_s)?dlMXAF;2`ZM#h<(ioHf}4TQa)XR__`S$=cRTE67xV{?{_TvI}^UyIOLE>AXaG3nLu3+Y$DMc~&G(Mf&Ocr}R=}ztUSi|-V74?OHfst3+%g+&y0&eOY!|uu$Ld;w$p;) z2u%s5NY&la(^4#?l&D$0Yyy^Dd`3~JO*?U6sjr~>Vjx)R)W8C`SG(PsZT}~EG5Tl&_ERT` zX{R{Hm8m&QsE8)y!shI50_psN#=}-DBes(yx7_-SpwZ>JANQh6_d+4EwwXD4Xxd65lMHVQ0~-QGK#j%yQk(Sh}vLoXM7JZQWsF0)R$ zg`HA!D5ld-R2Y%%nk`dHnl%JseI$BY{aVxk8C$O%wl@^{8Rdi;jN44DWAwI!yk0zF zG?nsT#N-R5cAIuwCWh)tO8ug5QR}|glcK2+ps}f`7+qeP-?r2i>&p#)e=&g%I;v{8 z`h#yr2YOdUqVFDIFQs6*^}CL9KG@4b=gcD=$u-qR#O9eoeU<0iIiG65oYxVeBjri& z=X~lc{!}ueFI-!$_+FTQ@w(uGoRkN4Z#N4sTgS}>QN5ZEUJw|A%}7=mD+P+It$omS z%9V_mw0#aU5=*w?uRGzRLt3k1`3I6zKId{?BU^{ZP@Dj-2ayfB%YHGc2abXC{{QG>}gm{&6-TAT2RS#|JXL1=L)?0zu{v%8XxsMDC3AlojAg~5# z^I4BbwmRjk#gseb6q-FvOrRUk*iBJB*1s_>ae8Mo$$I|=8FE))m&^%qOqi@>X8~SD zzIkv1vQMn9{WS7|4&>U$=SGh(v`qZ;R0+B^L)spe!wivq+&bH_h<4${^z4_cJ;5NO zsO@wVgb~8B`r;*PyUA;kSF8J{)VXi8Fvg;y3e|(&dRh{g6EnKOJQO`=`mzW%?_B6f zusrRH!X>Fo^RkM9(@Helz{mNj;OwL4_533hJM39rix2iF^7KM+hiGPUCq4Yt#bv?6 z5$~Wj&#s-rGa-c;Z?p~XzH5tjS*fWZU6U|fVAGq5jmL2^qIRp-<071&*LtYvc?Hjn zMri}=KTbSnabco+#6oa|7c)RYk?lBDeaqiX2_@zKaS1}U2s$^!@!4Fn$*(q_9JS`L ztS3BKnmn1Yz%{jN-CTsoXt#e8KxuAN^pX{)wm0H&7saKj$TxT}5$j#lXLj93; z5X=&6Ir@~mqBY~G(%^kFp>$e>{E)pjP(GYmOs|MmE6wa{n{CeI)iSGu_Em=(SNbh$ z$%Pk38e~r@`~uR3JK>IePia+$dvwJNqV@~Cs|rKl*=aBRoYC`l@GnzUj4U-+!AYQW zTMG&vOH1;rtLSQvcITXE_BBU)K_SD4%niu74{6Vb-oVSQ{V7W!DCLDUWXQ9|tvOe% zSGeSHx~AB=*4b+7v5l9bvQaSd7*2%&iGXGgne6> z*+4R*)ydo;9n&Ae`i(1cY~D^eg*9->AB8>?`t?pQW$PkB)JY+H`l;03&q0^$-Q&KG zUL8S=ge4XU+{edIvLc3+(Mhq)_GG825C(+~*+C*L7N*aoDe$Z08S%5Bb9Wp;i}o_4 zJ0e~e`#}#z;j23}Y_?fzkWf6UG-q|;-KS-W1o_}+v=p4=l9&!!(L$yc*I0Z--YBxM zg1=R4`ng;X9GTIE3++VnuH2`6rQBw&OE9q@UK8H^L&wVk%)@39)SCYa#ItWmy&uw) zv37$iv2yl4gHIADVdsabz5X)IGuF>4L98`?r#+~UHROY;$up>>|D38KTjul{9p^ai zBrThLs_m9_mfS04qg*dGMmByIfh<82XZTLo6)LXR0&*6!;tXqu^#KW5%8GIXS;j~JLiOG*@YqH zaAV9AFK9sLp=h)_;HI_-EtJ_2AoVRoVJc8 zyyN>EM@9|(;K#02E-|-z6YF7D(I+UrKt#&0vIz4mD7YrI;ZGzAQ}Cc4q=zBy?My0ujorJcWJ%7L5C#!YDxqyc91sRTkN(~+19T_T0<71 zLRgpzuQUA+*qt5AnM!N^6D8aubP*l->E!dJbVyhw#o6uSg7Cb#d`X+j)>c zU>c0!@A-f1V`my~LausFn_G)_kz0@HM|OKK&%cK0w*Ch7+|1|HboF^OpMw82t=_jR z|A?s8r|B^ChW$5%k<463Or`c)#UL3nn$wrr_H}W3PsrisOrykeEt$kq8!T+)uRx^W zO!wk#o{0Rb0Gtz^#5WMPaPyNft8;fqoi{%~B>Dz;Y+B}KSonh>ZnwE#Lp>b#eF^!G zf6u()p?P=^O+u<_Fn&{iX6I9P(QAHM2BJO#o$w9jOJV;^TB;MR0l^Z%U44A$%X`lV z~tmB2GdidH1xI=i$gUO^ybQ^M%&JZQJ$b#+m9?pUW>?< z>8ONMEAoqIirVC$8Y{BF<|;qX{Xz=6K@bo^+Qz#_KwM3pKUaUB8e~UV^VS1z6kl!b9h0d&h(MHtLyPysLE71fAxr_OME< zs!U7)WV{ouaJQV0zkR`h{w&l&EJ*_X9ZL0~BV zTz6{r8(Ok~3AkXM@2%E;9KN(Pf8_r?%>Oyrj(#Eh{eody@DRU=OQB1X;{tCfTI4B$sbrlEnt^1H=&iSX{QM_cGG5yxQ1sJL)r0s~S-OLl* zdb|`hS55d}xkZp{Z_DIntZ~8!2Nyz&J`*XZPFXglS4Be%{>);QQ10h@+2~Wh@a#z8 z?uhf}WN#n6L8b27CZhM47GfFilaIa=$0c`}$;2$Cj40`6xqaSAZPUL>4k*}Vzx#d; z%I~5^`A}BI5AA#~q{9yy7+6(hMj#M#0F+2?E7wjyn8gfBwu#G|avu`N1Jsexe+6ZEEX&|)Y^6P*6+>=RQy@VuxKbG)L%5?P(_oq(C za>ukywMgSZB{yKJ48@Y7_JgB62&|^T5_tt^qq@`GLLXG9A zsMdeJ`2S<8&j_SK+lr|zD|nezGn+ykZJ(?M5=xO`>$B&)7Vp{B(1|tmX0|*f7u|ML z(_$Rp2J;zDsOcKzoh8CE3DxzkO|tS-ydfzg zb_4_!cIMO1+@*pBT;QO~o*=zJS-qfsJm@8TX4(-rFwNEH^*BRI5AJg={27r2l4-jE z?Jbsp{mYN ztv5r}v@`@MNz`wXu%g-0wHuf3c-lGsx?tB~-m4pfg7Y0Lf$Qew2uP$e`KeEMy=Y<0 z|JU#S=lH$F2!tT1>Wobak5p5}M?ScYeY*P0ln8(uVlw-KJLO>vWcD*Mip3$djo*Uw2n=?t=Q&s40RXFsM(a8Z*r zG0(O8!k}#3?gAkeGqig`O*~sZ=H*}wHxkIRF*0GHOfIY`wX!X$of2`j#NnJqW+~yf z#7c#&E>7(*+D~+=i?==^gBw7Hg^ zw4}(O1C`_S+_-=~7^V8_p0(`;nR1&Jw+J!o=*t{-F4gJlt&Xm~)$|SfE&}S3P`1Cx z<{YVBj`~Gb?!2Y46U|LROaJaRvccY1?{MWeL@nx+ENR1^(s8V1e#uG~7GUWQn2to% zoL9`1;CGzv6YZl``&lnDODKj@n}NJ62o3`^QNPF^$YaFYjE zBO5D$KyI{O$>PWpu@1Rvu<|}HD9Av*5^22uIC2xBr`al)o`=hsQs#dC%rKH0N=iLw zlThku5OWW3-@@`by^}wD>^|xLZ3(5@^WZE}e+usT4$%xvW5)p2tFz`AbPu9> z#%bEab?2G@EtjwSNB$+&;YahNjoNWH1xAq{DDyd`9ab^Ev*q3Gm1=N=NHvpFs^wxcoerrSV-t@!AcAivm zleXem6fyJzlNYm@qU;jO2OG@e@NPMwH~|XIbIb-x+$XDv6 z^d)ieo~WhNmw1usToW5IL@U6h`F(uoYadKlD|x`HzBNPyfTj+}!PZ~&>RFaPj}1Xn zt7w>BNeRQx`1S$vj@PAUW|9a-OomY?WOSa_4T4LiEb?>ZLqFn%}hp8{O<}a{K zbX5M$TDe-(Oi@V*;$|jkAHflk+~bd^doRC~8oRCpar1-Zdip(eo;Kbt%zgaPad=1( zh&#t>p7Xuv0(N~r()riG86hJU_x6w9+KJeF#=*JXDI6$B&RTO?VasgjAZkAHH!w0{ zJAg^(8ctFhq67Qy@mq^#urpOC`Xp0q?_EFU(_gPbpl=V}XgMqQ~mtCQ*bkW?6BNL+r_S$*kt8^lV88QE)~8hVn+!Auw6=B5W{$nd?}`|`<@+P%z}oj zmG7D;)55*A)R8F7w9+jG7siB%h;Hgj^XS%SgmEp@%#~nIcR527Eh6>ZSD0}vwEE3R z4VeHwlM~a&WKA|N>*o?CKh?Wpk8!m;LSD2xOfQBCTqca?>fG3w3G#X98Cq(HF6LWh zvlkXjaoCIDvi~e)u24GIg@}!hU;%4r{0RCWWZ{0h{t{Bb%WlaQxJc3r~6v5-?w;gNIgG!f7%_l-3r4bDJ7NnQsiGnjuOyAz7Q$ z|6;R|EC8IKm9p%MVFS`#qKQM&8H5@T&M2(@-0~|TmD>IBm+hM)GYyHu9m4DSi5B|D zdd7|zl=6F;}-RRRvPrl%d(#Twp{u){Q8YZ;ILMpf&6maNyB4(zt5rG&2QA0 zpf2c)`Lh;(!Y_}4`i)828N?&G0LXhCQq-78q7=wQ80?Y-VuFZnQAO-4FfkYr$nqZX zff7er#f%297Wdx*^kC;~o7GS9{IgId`m^HGB)Ho0&5t`D`${gZVg@zWYgr_e*%D7W zFYcBKqL-&F82-%_s6KT#St_#YDJ>Y&%#(C`n?SK%Dn9FUHI=%+Vya+oQORU>KhDS#)$TXY;uS>BaXm21L7N)o)H(6z6oi`*^zHBp0-pMr>pO;_bQq2bER?SXAP@mGktY@wFOAqwt-b@G>?7f$1*Xt-4r9zkBYeDnag?+Gk zy?RjXHSIFuG@n=|?)&hYOhQtx40WMVLKoISJ)$U;^(8XpSpL(mU>c|lC3-HA9(_D~ zFkd~~x?xJNw!&KmjhA(uEFtV5^s5I25&JUK7cf=;F^(U8vHv1wWmxg!Tc}80P<{x3 z`)mGrJy|!9&gL2jy~6`53=;WBljxM=4$J~gx3*=)P@AWQCQ$qu-<`OWhq7?~i#L!; zY+DVjv>MZ-j0@89xF)4L>!xBy*sr;jSn6UHndmiKaM*SSGzb6w_{5>Hb3`bb5&e>W zbF34l3Z#}Mo6D?_bds(kBFAzYs}qomzSfJz%7oZHYOn>FS(>E_L@PxwoisrY#1#=Y zHytWyP6UE&6-w}NGPU;rUx>vQ$R^`sYcc!{GjP)0gx`-{vE82mWx)o70FEaF@hP$zn;Y#i1~6C%?FcMFM*iIO~_dNh!>9E z%%@e5E-l`+68xHcq9pY*m5nQkevr^J3EB+Xru@1g>UuQ@R#`6(>7|S$w>I(u?A%7_LKJ(^SG_aIu=>VlrK5Q5 zM{#`#e==#KrwgfA(>wz&U3dpIjNC>uW1S*kJfhjB8s2jKhl_ocX*w9uRG2ij;c_dJ zF#zNcKm2;SU@*fgjKQC(uA(DJq%rwsf}x+{tFc@cBL!|nMDkxo!gz(8U!O02Smg;O zn87Io3^;>~Y&TY-#A^d-4bg-Q96(th2}Z=Gy7q|wR{KrrE&UXl+TAI_`!0rsgO75y zj92a}%PU90&g>;fUxCWzwfRjA#O;D^&#BnRR=aOMDR=2m#{VyJ?7x}V|6U=tD6G)=FAiFtAWZRetQq@7cJ6W)iBGZ5;gW$A&)B z+NjV&5AktzrkPD-M+j>N%Xi-dIff{tW7Qat6wiH5R4y6;;r3WA?sseA_*^t_3vw2n z+f{-Btu3gAf~LLi%Zh_skUyD@iPcScytq1xzjPZJTb(t^TGQma2#~UkuHHB;bfH(4 z60({BS1;Ri`o1;`QU%K7cN>SSD+AEpOSvrb50eJZ+r#_!mHP#`D~(e}2GpNM@}xoU zSlc$({ms`Zay+=o{BZPDqK&nWA!X^nVSmaKOS?(U>BvjssA>4>6;jl zjs5 zvrK=BuWS{5*Pnv_gPJAR=#}3><>3v#vnMwA???=(luqt!!XLPW|66jAuClPyMJuTv z@h&fcwt`n$)LqnELdr~|P_zDpYSDNSSef;MP9dghB1oqUR(zf5FS}4c=I#cp=ozW0 zh-vz5l%V5xG*#Wu-c-b0B&H!)Ua~*31Ts556_9J$0IG)u@F{J60sH-Om)~PFT>4sy zhCS#q&6da}wI{g)aZjnh2w3^czp zg=b+}jDOlybjM^U6>WEd%WE5c-Do)#nfN{WvM7_GaM~QbM~bj9Y|34Ka^?VBs(&T}J|DT#3?D%gqh5uVupuzsGW>RKgf2IS zjP=TjyyH#hlneq3#^ql|Tcqvx?cQb%vkPXy$^C8UH#?GP_)3v0I0Dht((C4C`d z&0>8{IPPz8&B2IhCxq68UHL8rg^*8E)ZLVIN5^gv6-rqMT5fAs_$qDhUL!vHU)=R2 zAptcvO6Be!%{*~4S)jUfTC@oT$W5J~lc44e7XM(BfQ6>cQicd1huFJ5nd_-8*uZZjZmfPJjthCK+(_xW$c>%k-vE36H^TL_)B^U8;$Cu zg%{tE#1cIvcDR?@DA4%_+_vG_3&;>^JJd}lDvn|D0lqrE>Vg>VI&HP>|5kGP^dj;M z!W_ibN_&=i>CQMe0ksd6dt=ZoLnf>UrMa45%dW53-E@B~a^RQz4C8MxlNy0Dx=TFR z@Hk=&vSW&ht~3CgY>D^d;5KqYRY$vs-f}{CraJvLBv!ocvo?92l^79F?32(F9yv&U z)h0b^&_79;yi=^K1S~aoj$IgS(W5B5o)F9Wa7ufH3bZDI`mQ9c?2Xl3{lfYF|0rW* z+-`cguoi*Y<@qs`32^Pt0q_xoD)EI;*hqRWJ}%dQOMKYg^QGj6dX#8NKD`!x^)ovu z9&c6*)Y`gUJ-0;2{AR8l&& z?JunD1Vz^@3oCg!w2_PGLkA{-z4Ivf_;+6G$=KbIEFd!E5vMA*eDubv3a0uQxTxn- zOeaAsgm+71)x|UVZL=)FMtt*L!J)q`Ivu0e8;H4U36{MeYc5Zx z6CHBswQAGpIns)h6$&}~j3(Z4TXGvX{-U<56T(j`_7DHy;Ag<4!zMnSn9ATKKUOMb zc}es0CiIhtZ3A$s^fei^g(shPj%5~i?gSfe{v=*kxv!lX%Ruo#yu3b{t7qC%YG&e< z^2@t%c^<)R#l{x*t!(0gYHI5M7pl*P(;bhh>_9=qxd^V|+>&q3W0U(F zdZCXd!<}bVZ8lZBq?>8NySWwsI>H&Zy*p>l=IrXo&4;Vem1FOKrMI!W{H0FoMC__KR zXwSlph&sZiGD~0kxfo)Z6MBdN;l>w{BOBOm(nuIL?huPISrYDi$$R~sB{)A4mkM>s zGkR?#2;0IIzs_aBbtd2wi;}Gj9+hY{YL5D{jYG={9|&MYB;=KmDj7+_w?NKGb~|%S zx{JoQIlIbh&gTL!XRb+7!X&=~E z?=Rn?A}-4lKfOK(Z8K|0S@>owWCehcL9TgkCgFbJuNYgDCdON=B}%);JT(~Ws!9p@ z+@VtBo0#_`YnOW^rBSL%o28J(Q1uziz!E&SpknzJYPpmpC#H^4wHkI_AlZ4Wg*#}f zVOH{b6VJ{=`U5}l|M2ymVNI=V^rr%XC>;+aR7F9LN=+z+B3%Unibs(a1ci`D4TNGq z5e1PhD7`C1dX-+J_fDwNixO&R0g-v)Iq&>uu8WzEevl74dq4ZW*ZQrs;}!IUj`QVY zSW0(i0tB4qThAFzkb4fpVjzXqYc{m?K9z2)P7QB(nrzOWf1ugVA42iu53PYGkL`S; zUD=Scrsxp)%VEeYV(l@i;hJ%a^6s>K@2{J)iN88E@BC^T@Zx-h z@gY@Z2w&_=(T-26vaAF<4etk1d3w5s9p?rDLVS{b^Sxj=MX$44$_%ZSKpvRhOn1#! z`b&Gt>LL5QH^5XH2=toW82ClS`jJbA!6zKdv~x_4d(`J?083|q+Lv$3mUsH&zAu5p zE>D;wnX;A`+u$uG^-E`yj2u>v#)zI%3l^#uO>qm(ecW8P4B@|?<7GeH8LaLt$Ad#J z5|J)Z;AwWdGdpK7lMk6w30+4-&KHbs?8Q6W?RsLUH~^`hQAIEWKGRc{$M8PWwE-Y4 z?aXP9M>;-s8ev~L3psI2laq0L*KKp(JdpWlr_sOXn7^($h8uYC%|1`;PH7Vp&az%M z<;QQA8$toD9B9F>*56biwQMu$HLQ~!I^kS~?isxpS1&7Q^xOjssUi4n`&HA-Skc_0~fGsf{q|>uSW3Y3+SP zqknvY@^AM)p(08!a^DjeRV?RbkifqBIg4^o{a%@__eYxzYyx{vmO~K?r8qz+ZdxFP z1B_}WzZwVgX*a1ZFrwOU#Y~}p+gF<&dXBWqUh%wgifOi7I-#%j2BzxbD)Z!n7%Dn* z9Gb+9n-ZFP|A;y-#rXNyN23=d%U}8Y+8tD$>-)!qmDc$s2heW!HeE*BZXbG#j11)X z^ppz#gT@hG=Z>GP9C-9 zDYKuJ(EisW#M9OsNh8cq-9fvcv$XH%0|v}jKSjOb!ed;jbx9Rp1&2N3I*=H3LM`LMYPvLr= zS$acLlw*D(4K5C)zO?F}`^)GHIHx1I>Dzb)uiV0kVc!g_ePX3-wnVgEHf!)s#khzoJ9@8@%&v^XeniL*p>j z9Vwj)L&&s8*v^Qp$x_-1ywQ#xyQ$5YPuNc9E@O9w=f&Rm=~zi^%_~T5zUdr46gF1Gd>Suq0(%6)oor3c>l# zifux+7N7jX4h5X`hl!y^FPk8!x#Y>7hHZZ)aamY(i40UGHOq9KYsG9>Fn+jB7PmOc zz%c!q%k<&X{~)rt_xv0w6kndAJZOlgq^%b7SuODU_#8fJtnq9*;%@%OsQI|dOgcUO z+(B6PbJ3&3Y}*cbkZYjKL(k?T%DQ+xJ$n_x}E_*`}c@|0(qSy_lXE9|r_G4UIG-r-F;Z zKOa0}rv0N^1kiZhLyik+Qn(9@!^~wbQwi{(>xbcSPlKNCVYnye3$)jKQ6j+Lcmj@$ zryaYU{B?a^>^*Vnu2kMJ|I7l`BQ3Gw@z&n=hLdT*X33w}A(cBquIa4{wg)$EKL09v5uvb>}M}V@&j6y!a42ckV3cVX;e;`IAWn}AFawpcThP{ ziyw@3E>9bIYE_DokEMH&4x_m3U}*T20c>=KGH^f7PVfZI{@<(={5DJQSK6G^?DL1u z2;TdI9S-DMi~26n3XZ~U=l%EhX3OTDuglJ>Xw-HYp1se@HWS~pV6igZ&sBZB{0DH_ z?v!a;ttcZ>LKetN7{xGo$n&g?*Cv4iXd}bz%}`64bNQ;Gp&F{w(!aiI_Qw4_z1>BW z0BR)Mh~Qw~rNcGpgkspA zAxz}G=o6RJ*b#MdsH;ouyLAqtXLimr4w=vhr_f8f;kdA#Lj?xQ-RIli$RjZp*B9+a z_Zr@1{gfDsT&WDX8Fk$IZt{I?(LaS6>C8bkczLHb4Ig>8%_9hDFX49okKgO=u^65r z{7l|83RWDJ%INn_cUcZVsXpBsBA+QznJ+Z5d%E5BZ+NvV^KZR_)w971svagJXLA_F zUe}^@ec^phH!X18A5ru7#WEsWeQ6>f1ur2Z3@IlANAml-bs$C5B!M9=Q5W(z=ZW*^ zEX@NM(*xa&IP@K+*y!Ob_|b2FXU)T>jMj-_xlXa}WkXQ*Ufn}Z)Qq8ebPT_M4T8F2 z+=~x-HR2kDj#OcsQ2f-Ie>P=FBz5iZ+$5$K!_!S+^b=LrZ!BHCB?rbJZsd)Dv-o*v ztb|KTw+jiYxCYiIS5sC@-5!?=jr}x zYMHJ(u{-skxoFTN?|NY1KLY6o3;tmweaPGeA}=ysf*3UJz!=cv)=KICXAh&NRCQ&# zp;#N!Z>dDq3jJ!dUFNE5Ot8pJ`4{GgmZn7~kr@shBaauc=Mfe7rxC;evDkju4oGEM z-SUmf9k1N!CJ0RicC!7ezGniN0 zpYg1dRV}MdkgYD8vj+YY*zdg-Yino?^u%i?@E4SEhZXaAl7l6Nh}!4bt5Bap+?~rT z$--?SNl|-hIPuqMP*m9d{&V8FVAL=5=7A=$bA@+H%5rAi<-5~Uj)NwxX~2iW9{+5% zeXSU_S)V8Gr;^F@w+L|HiO)WzXh;VrASdXQs7Q4XIzA+N6x#Z}ID#zy*~?&Xkq^hj z`9#F+d_+CrhrghoP`z!h{k5g`Inud`fH>bhbHz4W57xP?I_C+6?ISuuNPqW(Wkape z?}pybiTg3n-&2xM$GASufP8~{m3PrOF0Q9#1+o1Lt4_i};Ty@rW=G@yP+63yHV((DXIY)=4l3JzdKh!11!&z7M8zm z=L^L-4(_}4?sgH42!kKy4X&LmP;W67;Js`{yln8Pw2c(K`I{rA1+J^ z5UbuSHk``Cg{!A^{isp;lJu9L*u$V-X{EJ@h4L|uC? zq70pz$=2G!!29E@31&f-YT16BZgEZbl3ke{ZKE!gu z3m&Ojge^qAK-0ng{e!~}m0)=Zq#Xg|H0R0F)qP;)JG}G&f}#RevPeRzb-`D_ud_3w zJ7Agk>2gK3!m{1i4Ec$2p_Axw*iF#^7xF5)<;Ul^tAVuN3kV7QXQhxTIgeH0J?RRz zr}&s;Jtowg5!*=tss1iELJ+cyU=w-!nb2r14i4X_4%!Xv=&wv6T644iGw!VbQ(aNo z)O(WFSJ{lR(dm?d9|4uU>jLA#$vBRKACbDV)FFOCz{fi>m$u$U%dy;Zy@-$?YN%Ul zdD8UUEfuN8zlK{;sh6qYVGG&R9derv$x)7<$+NC56WQ2mODRHj+@oU!h&1-o$XK12 zc+AJm6BWNi7RCcj-BE*!4_4c}<(z}aRi|_W^gHvtyl~Zs*#`7XSy~+<*@rNy95_-W zBX+*!on*gsc2b!U#?0cNhAu~d*etRWrmjbw!n+o%1-X1h*>UuPx&=%o1 zJTo(%!cN{A4fpT;9Rl+{G|!aP&`WU;Gp|drNV4R5xAUsG>2L0{#B?58A$WS(pg>Yn zzYE|cbw_}2kF0>;XQLmy|`<_9Q zTJuzOVzFmmy{O*lqoIzH;?o3!_@~~7pSVNkZQs$ub=Uc%4MVeZPIe zDy{v}^T#56Q$-JAWX%t_1LHn$DT~s(T~>zE;||M>7%hplu?!IbwAzYejra@g>25J5 z-#AU_?g9#Rb^(ICD#gZNtH{n@rvFh{{?|*f1>%rcUGyrFRsPmO#wfmx>Ge>#e%}I7 zL8sxA$0>m0D>w9um&YM^>6Xdc28(9Ta{T_-bcvWY zqSJ=+zNBig0uxgVb1lMBe*}mWdS*5bb%bKtnI40{xaZO5DjM1uioh$c=IlM=w z%wU}UY|Ce{N`S1IgB0T~`2y!pF^8hji{B}nUpWLa*%z|c*QEgL<$A>ID|~>kiOUlj zV&w;{QCc@au+g?^Cl1ma+dXogHzSYi8^18{s9D<=soEh0y9JBZLtu0 zj#2Jt$_1On7b&R(cCMn?jNKVUO&wI>eN*8et%OnQ$KP?UgFqsl}Dt_+!rOv;3_p zuMww5y~sZl$!Otu((HzMuUIsXg+$PsEy`F}5!lQpre5KNaARWO zPa>#i9EQo5o;!DE5`SQ>gY^!$aF}*L{e+o+tzNIi=*&(VlU1{)XRM8@CEbP{V4c2i zhto!fcFv39;##7>o>;#+GrH!Njax?=Tbq9g#dC-T8xvUJTTiiFK)18lGoSczWA|g- z-OA>)K{GfPPwXcywhz%IFBT)EECf@ye+GUpuv+a>1F0;uv5;|>;2Gi*DC&3a+`-8T z6M*%;J^ZXVK=<5$DW;!d0a1?)(%{ovFECPRp=S0QTkleFGqOD*^7=Y3RMNKdLeo43 z)SB3$%cLb_oQsM=#X_F0#&9!6cDP6^qBzh{0bXx6OsuNLQ7_pds%UU6)q&{232S;5 zaa4daq+U0fIBtk5qj|+?_1oL+h5e^~OI1@GVooik(Zp@|bC7(}z08WMy_`paHBb@d^<$Vf zE=lcRt1_;+IwdcpHfxU6VE1H`9?9r&VjV9dwZ8jxO3W_bn2+@h;2U^tTx*hkQk6ci zmD?C4lX7?E!Pz7q()S)3o#!0C+#w0pX+Z4dVSRh#Z_dc|t<;(jDJX*_(ye7xv=R!BrUpPHPspUps*cLuvjS~;56=GAHggN6|ERS>`IW`y~P?J z`{ilM)jt0F7y36tx5y{(pOKa=fJ^1ZvG_Kj(eI2Y7E{xxvgq~QZdmY!&cK2cp}Ld& z{jhGdtdVnh)j+F=^Z}oX`TGmp++i~*yE&||`AWFj0vlv}>4Q=7>?3i3*?YJkTHj>G z{#H)J-cLnG5XRLY&v13uTMS;?NsU$NNgR1AhORCK1n^BgcKg=#PL$&|{MB1v$S*W@ zU*xv_=rGr(d)?dh?RjSf=W0EvjX>KAEJmpy7$+XJhNz=m=kMzvRIgo4iF)tvk9|L( zgc7TARkYAMxAeeb2)ndg?5rwsEc841@#gvr@q($_w@-9dHqH-K6F!qO?so(In^tBy zi1xRXb+6CHPP^>L-U%ezRla{;Id`a`k-gB7GQNQj9ReZM$HIsx-^f`O39~PK0>xwn zf`r>4$QkC#SwVf;Cq}g^FMIk-bbPiMrx@>*jjLMZZ^gPakk_Au3AhV!Y+UmmSIm6Xp%XWo%<{9C#+@;UlaUUIu zQp&EgUv%a>3p2ailTL5zpwH2qpU|85ySF+O`_UiW#hW5r@S$g^skrnV@g{FnC-L7G zTC7le`~u;E2H^f4)|koUN!eOj0p@Sz$efR&+h)HO}7 z+=o5f_t7I6+8`Rm(?)|SkHo0U@-&%UhuJgD+kb4q;WUKSyl1-yyYz;j(>)7GPCZru z#nJ<5F7-L}cpLj=VABVN0GpmCx>-74`i&-9%5_3~DDt`D-L8u#be<3Uj59{GFa^56 z#gVh(xK(Q$fb=xwo0#a78t*hy-eDgm{LThy8^BuL?Eh39^DPaT=EwMR&kV0Sx6Omt zNQhYF`jVG5@94d^*N5JU#i@4+;agLIGz9h+*iD>*8<3BrfUiQsG;FdM`-obyv?02c zds&>RIN(MWpBDc}6O9 zGwDaZ^-bzc!R%;Zb_+?Tj(=4-v=ople>jwY*fFHX(ZX*=U*{DZzA zj~OV`ASCc2?bI6SK4>+nROx3QsoNH=S6uUXd@ ziKER^L|0>)xw58373`9({|C>%rEC~0K&%!6VzmtLMMLGl44v&$ay*?Wct6g)@&ybw zRXuc`Jiz40>di@%1W1Y~a<^QVqqeI?2^2aI5+Cn+mQ*fEy)S379tZiD3P@eSumQ8P zkP~0?EO4uS{I=UorlLACbW=>ERif|2%eNDDg&Pc4REM#gu)AIKo#9wBtGE>rlcBFmnL34?TjcQni(j`RjH$8K@} zc~Ii0Z_iuRg;u`Q@+``2g31xFbQ|@uky1owmu(UB( zOqDJc7PO)iDQIxc&7-OV&Ne5zp{iY%Ko>7I;?K zCn9uu>;<$^lf|YT+n3d`vvjtfH2c{hw@nr?w%{U`v;OT%9~eGhZlTce?29Edb7H{Z zmA~kGhC&gz9f>p`<#;8iwyVT4dVT7oqhH4=TCqh=e|Gj;s_7CYwgt6c%r6nLVZs9a z(R5CRrby~u%qPml6CYgpU(g=to9uVluWzYFlSgYVXl~GMB*rP=Oj!f+YfVn%Fc!WD zSiEm6a$GX5nL@N`OIyx8ju8k7rqlO8ETrixq}iwx9;mcFqs`3ar&Ed`c?DXzCl#T! zvtlnSp2nH>zhvIF#y^FSlbrN64>J!16=e)Hy3)t)-F^ z_7l)sU28T0?i{c3^O2C#C@xs^Sn@}Tb_kTuA8 ze2n+T8dvZp2R?d0y$G#C8_}#I=GBP z>RrgV_`Ry*2H?!o<9G*+fI04ea2!nwRfh*$)4nrI5EmTTfvIF6XXa^3=r|#%RhfwP$(R zpP!_>GSU2_zbz>^O0QtVi^Ju8%)+3z@m$8S4#HHrZh6n zx`km``F-VdraEMz1UiYISJAKZutdSF0KO0l7gO(A7Huw`A@Mymmk5(N_7$}sl(^?4 z;XwjDT=tTsuUB%fwKT69BxI>LNcEuy)c^c+r7v*(_xAdx1tnw|AYpQZ!~&zpS1Tz8 zabTaJk*O?`o_M=B%!UKjf2t&~{@=xa{dlys8+P@Md_32^^ysl0zyEp^9(>%r>~Z=c zGB%s})0VxcZd}h#(v4#9ZY#EeSk(^?_Xe`$S^@?`^`M5##M?i+EnTz!AK04I*g!Wqec)m1?LX?YKs_HP3JC1+Hsba3Q`I*1_p zPQW52YgRj|-eNQedSzK+a4{$=veGiJ2}F}5nn%xMj#y{H4hPC(Xl0n1JgsDJuP=?X zAltfF9DcY9jH?AgWyL@}%zzz?Kkm>B|B07JS*KRr4%G4Y2v(SS`x62zquKVNp)O3~ zi>Ti@!tefC!6)7}p*yX(c`CZp(?L>r{oJ(zlFuUs9+mB3o#K}1#LKi&S)j8CWbL^T zGVYPOP)4AM((Cx}p;zbSIljJmeG1y8p3yaHv07zdiE+Mv%xw08pOTH4^9vVH38vHX z;Gg$JQ{Hu9qtCjZaV6NaXz`vy27fr>Ov9g$NCR`%HJO+m<6;;%mRU4G!lP-uF_sy* zp#G-tV|wee605y^;$_{1wm-+fiwnr~$#d}Ayh8`+oy#!UNQE}hLRuC~DdK?zx<3Ps zO(;u8)<2w`Hk@HDz7qKS1&TD-gNRHZG{Np~IwluiDbP=t=j~{{>n0WiQbQ{P z!mj5?Iea}@oTNvfNAkZ*+iFZ#`tncAUKhIf-8?b!Cg-&{9!Tt~)t=2HKZO6eI@9xnl1%;QZ6z#24TCBlyTcjbOPrqmhI%Nmc^1aAeT_v6TkD znW$F%rNEcSSbGXl{d$`5f0L)3Myx~5^TYdV%X+#Lfc4LXR4Fpf&eac`)5iYS>gLj> ziE#Qaz(NY3Kxq^G#7$Vt3WT|g5F5B)ME*W&o=c4pX=E}ja=zI{MD=#*6Mrp7JJveC z=eyj}ZhT;mu=uUQ=xAO1boRD&muUmWv_)OeODs%EJ%v={j2;QnN;)36w+7qeHatCxPo@d=I}2#cVh>b{^1sBh}j*H^+7E}0Rx!{ zcNlG$|MFs=E6++Mw|v)zdb2Fgf5kCtXeyjs^~7?iRb7bF`S?;#O%`sQqg4|RowKKd z9)0B<%@Cr+GSRJn3wq^o%iEc=O0Nwi{)@05NfJSb5(DtF+Yn(qqiF&lgPr7>f9bMi zlpUu8iLlxuV}GbxXf-@^(13UouAlG}4(j2&8r{>DbrkWidMAQ-2AvPD|<(_0sQg7H9C@BdZ%B3AwF?@j#>!r$g{h3{rk?2SVfz@Rv)_dg=RnwEk ze4%nUp?7cFx2h6mo?l0A!|_T(&)>$G(xy2i`(Hw%qw4*AjF=;(Ulp1M-8NB-l!)t!q8L_ddL8qi$q;-OTcJp5F*#1>7+!30>O zDCK0Am`18-y)bo=*F^>;iIilPEXqxX-?)3sd7Y}Xh8BXb zCe%l-gtsr;!f9s3Ra<}SuG8W@JQ+!$C>-!h-cDahAwJZG=HDkmz=tVd;*eHf{4PHI zYQ+f_a4q+)=l|Zp%cWhitlu?fw9RKv(5(8ryz0CDCIS^(er}`{@@el*(l^5!+Z8#5 z4`T>0CPkt;2`_e_gAgviHvRL*^1{HwGv( zAE{WNww~((#i~+0nmn=%mTY_RX}#M4+5GCIAE!yN%lXXykDe>f&f@H9n5aL4DadhaUinFV?WiGg$ZN$V&Nc`HzOeLH{;=rtC@a>fC)WxPA~ zg@=mpcg&8qF$^q)8E+US!7A)43EcqGS;YgHp{@pXrkg?zJral3q>QUPT8q)e9IJzT zZuj{|g-Z>PEXzJ|=O%TL1p@f|rrbYjJc$LqINIziN!ZRul+uP;e(5asbgnA)q;JRY z1nlm>uOtJ`SJ3wUZNnQOJuR0q_Y*sTDosWDKbHSlR(3DT@6VWHpW^EV-tvKLv)MwG z=mNXjUB)A6j=c7bQ*?l|2($p^e+sqEiC~*J1Ns_9o ztm3&X81>0hkdVdI7Q-OWPvV^^&wA4loEh--)CDF>bKmE*$)Toyb-AHVD#w8H5;xYR!^#JlN zak2j3Z~TdBd3cUxNnz8di(|RidXgKc=_SeG&%+;4>tc6uEkK-rZPO8|$Qj*VrUz|P zHLAaq;w4Kd{}CwccNMg%k-nXmL1qQfMx*;N6~_1Q6U*+V-k9o7gzdqhfi(p%(sg){ zax}~z?i;>daoyL2l_ZV(Y$SP9dR49T;8duu1TWi4$lA1Y8I-fZ?%g{Km~5>)-G)lt z^LU7Z)~UA>5I(H`Zq#61%XP4?pZIUcu;UYqXleeFeWr=d(4gwP|I3ROwAd*MTR{(9 zKD`YKuy_y6<1N?Mhp?#E3BQjA)Ui_IDI7(qmm2BjzsWmtC5LGRU)xn|V@s8X5I;Gw z2~q11zaOud%{iQDdz@dYP4(3@mK@VYb1UJX?1KmbY$9+DBj9+90>m(;jkj`Nb~K#U zl%tr<0hAsoBzkL}z*6@`vU#$p4L+UyIlr*)o0uJC1 z0kb#JT5VA$nH&E~8mieDE6ZVhS=*c^^clERA8GNgaX9FEuU`hpaG2+;{BA1aEl2Ej zU0~PMl@T(^d+QnEXKalUTvuHur109Ct}`&RCF;%wXkJQE<*3Syqy!o0-7e5m1Q>dq z)YaeD35t-NeXdxSc#5PvY!kvT7{D)<|g`nL$bIPHX#bv2#udD%?A1 zuh(g|?y{eX>CxVx!AU~i2Gm5R){80B#tJoq-nGCvD{DjtlM%i%2P;XCczy3!2dbXl zxKfrRkghB9;c36m!jJo_ZT%w7bABIn*B59KWS3fdB&4mQweKUpoVSAbmXvc3T2!Y+ z{U$j?M}ptQq}nr!G6?csR~!YY+^UGe?GJhNbs+5-;nRf{|F7Vt#V@^%x})oMcFHr zKIB6+d`2)q-J{2x>-D>Jcs>aX-+lhos6$S&AQOlg@C1~2S4&q8?KW}(gKBp8xyDZw^XM z(Y~1~v_~~n-mULQrgo$Tau3u@$XvCk9{q8k?9}$`@AfXg*roo1%6iQ)6Sq66wk_fK z(tkkc8G#_^X;KzH;d)Ms&b*4;^Bf9`X{GW{n{&J#H&gBJC6{}$^>&Sj4+&7>IruQZ#f14Y@}n=~>J=+1?U8ls)_{8OC+}_B)UZ0<7YCQ zsC(hY6ql4I!OhwDxRJxVw$Z;Z>>}A(KOT`Z7sSN}NunkzWJ z2=%?>nJd+vHj=KUC-&_#JBnbS$w$gTR2E+n^Yaxy zOE|lHm7Z2NVm6JkJ}YN6e7KAxAcb;m6la9pv|4^^qX6!fK?d1HO558R|($Sc)fy+9U@NRA_**{S`&+^iq{_U!%{ zXiForFXwZUbqC(gMThQ7g^M+K#pvbcyD7(w8TzM<*Idh^_?c7o$GfxT_dwvr^LkiS=!S5#pM9zDT% zry%C!2A60rL@!(+fngG?Ej{Bp^1Gl%=j)#3PlQGFoC;M>Q6Ri!Iq6RYG8fKR3VetA zzwmzlY)pFRpl|2m^X0ClS^L&Xlz!kju@M7Bd_qH@rt(+RP<@AwgGS+~4qtH9kUx|YrH2Vo+)6J>wLN9C^fNpRlOR%A3CY56VhYsl9TqM`bYJ|qbj;;y^o-}0a6sT zDincYL$i_dqBz8)V&%Hr0;;Qc7l0_GsMZw+_Ot3@5jrN zmBU>i>4R4HxNkHG>x9t{G((@<@<3(ATvFiAl;HXC%RYw`403j+$#S@WrpE-C6Hxvz zW}%}ha!GXUb_rez@+(69o{aGmt<_QlclGiw4!V)gN}JQTjmH+9sApM2U8>OxoM}xG zR`si9FEM7&7g{#%;3SR#j4U6STpZWJANpwx;x>NP8768N2x81Yk( z5#_t-+#)mke9^!8yi0VHs4-FDQLi8j^g5To9es+fNB!ZfR-A@ZwDn_VEs3p>!I9o@ zJ;CuoHHRe7JhBcj zf7FOB@vs7--UzkLTf8e1@YHd(%fzkkbI^XD4iiw`C>`G^l$g!>DTIIXzGSpNBRPKf z+|`kJWAdN9P9)mX)~H{*@ajeesThX8owis6gS_2-%(w}2POIkPq_FmW{~(@O=U|1g zKapcb#;YUBqVKtoT9D@6RbVa^e{CmJq;oAb5dQ8{%H zRRJ;N90ww{_YJD$tEXa7Xb?~IJy8V9D>7FwRJL>M);wwH>~`=@sMZrMSTCFWrzl52 zeM2MfG;qQuM>TPG1wkYDQuZxvd}8b1nmr4p3kajorrRXZsy{6oMY-PA22u6Tjrwb@ zEoIKH!v>*E>W6mOliCvCZ*g6Ye50;WsO`3;m%yAV+u)6azP0>yLBh8|ngBBmUgSPj zAW{mf-SL+?DX1Iw>!v#qzf^cd={{(|gz;?3$OPmb&7UQ&Iskk^ke~gkZ}-NFFJ5GH z_n!MLkjGj7>sRk(FNaPu!2inXtCGH~5AQ-={(T2LheJsGj{yp>hu zQ{8Fy=&QJLjxRjIn#zK&9O9|DAq<#ezr|zS&lhwQh0QhiX1q#9O12`NVthpXiQP0y z&rQGa1^p4Sm#g_Pt8e<86)Eou1)K+U;^Na4AoLJ}iq+th&~n_Fx6S<*O)s0|p4=Nw zub{AFWkp7B1L*+Dx~WsC7yXkkuf-bjoUDhzM=ghjw`qg$P7Ic!u7c_%NM?aIW)jus zEK<9_#Sl?qO;^T)`y&hi!)iQb9}h_cLOmddUx)4;6YxE}>C=;{d6u zbNI1TRvRQJ4|Qz)qKLvq*K!ZzZ5Y{%iyAJ)0#BcBqD8SVtoOu6hZnK5i+_&Yl4$um z_Momj>*SE-(RYJy9Vp>+(2yc^DNmN@d-m;oUhBuYdGXvIh%4H6PJ{)Cw!F5?>164! z=O;tXki?Rw1`bRB0#N&Fi?EGBAM@#TRUnUI_q#!M-Sefc9;rd3De0AOk zf4(YsIV|Vce7xBqEN~$mq?P|ogEB6R4~?Op=@>AATpBURwFmH)#J&U$y2AnaqQ5|f z?*G(3-%$9pfo3-?QYVTh+`^XA3Maf3b9B1{R_C?&beM9IMgr1(B}{ObGcI)jYG~F! z(9JyFxx-`Gi(vT@ULO7XmQ<`d(SG)kOw?fU80|*sXqfUW=C!-zS%kVnVq65QC1;XO zP;E82X|57Q7Ek%H>jC2UDlE`)UM9Y+?>+be+7qxZlN)bT+|;V4)Y=eKLrOIq2L0-1 zweu@7{a&fVy=a$3u~?l!lc}@%`0QXgJ6ZDfGT{@yu}1#5j(^nWQXSR-<>PiZ8mbtv zt{`7Mx6*k$YX4C~*4u$aZ-g`rSf0vn}xdQ$c7H^reVpO5n@*oqqSm zSI^!36G2V*G6@U9Fb(2rYCnEQ&e7lJ~-Xs+@EtiKRmI_a#(YL6N(DgU^7pg6&c?Nk7!60T` z#6C|7v22rD{{XW0d_Pa&^Z+rzO3mGTQRuNoVMiw@+z8PHpH3eT9&OF@hxYEhKeY1Y zdIn6^yL$AU#x8#9Z}G~py~WJ$7t14s3=Vf|w(q9?HS*T_oQe2fS;L}ZcP&Q^{|Wqm z)Q$gdxv15>l&Bli`YXt{=Xa$JpBn@qS6nhFv$5#A|HkeqonMqSHg~@-j=g6KD-yjU z?qNyS^#(vd;*0T=MUApRbK?LEU$AjfqNZinol%gfb0TYA6_Uj{Ur@bn4^4AUlhA() zf~Z+u%`*A4ldW9?e9f6(Pb=Opbf2rBc}b zl|Znz7mI7aU*NPuDbAer(!iZSQ}}GqB;jmtS0Q6I5ovzdcY2gNL#J>2@MLOY+=+XX z$U!Zp8h+`VwyI8uYDKO9NvWrUp!n^qxj)`Z{z*h+yQR2?_*eyn9)1&P#1-}~^Eh!w zKocaMqZYcEo125)D2kA%v*kThz%D2~c6Zip>wP!BZ(*os1MKiBkJ||){}1|eyfrG+ ziUS}$(*;tCHrrXbHq}&PqjfM>pSW3}y7}VKEl_$Qs~=-JkxjfP&=v;DO)8KNVnF8J zCviKMs5qaw^K$KH{m@x4I^CD9+7rFj|JLT)^$<-Ds!qTj*m%WttDoxpwjcHzX+D&c z($u-WNImqS*e_bp>9&cLPxRwkqK^hu{dscl-Lvmn*1*ZHG+PM$vP3KF@FogR&0PCh z9G>r8cmWv`Z8!0&DOSRkm?GRJm()5aCL4r*+$#)qIHWYo%-sHq^=C$~@kjkb7MRc{ zPs1DOQQcc9JxA_!y0_xet z&G^*OnhtjHLC&b>rOEB5KJ}cWvTjanYBlIZ1Kwq)0(klGiE7j*LK9LvQlx8EpBh^- zKI@|K67KUwfL`a-RLed49E=Hdmcx$s^2L1Mk$ymkVNfKnQX|AXs?zHA<8m>NU7FG(6#`Af-XL>|<)fCrmZXWvyfjFG~V~Rtv;M&oN*i5jH*(pIO-w<1VNA zLMxmjzI0w*&|XcCIn-;FJRao$V|Zz`da@I}QKtr6<5tVT89Uz{Ff(3AWP2X+L08zpV-ugjQeL zCb?BPP`)aGm&>~pA5MG3?)jc~c%$?p6vKPns-V4N4|D=%&Tod(Zr)AsbCx8=7R!5t zW>gCI0VS_5YFKG^!_M=W9z9&YdgxWa6KLH4!AFE6 zEaI-X(BU6u7;ng!Z}Pj{5Gf;<>3z(-yZ4wTH5(E$)=K+YewfrhC!tl2zxe{Zc&wtg zQaz-ue;R=f5%=A~S4{qsZ6(Zg z?oHpCehjj8w@7;1eQ7z1M>p@g>0z7gP?=@bkR;`56Num&Y0c_p3D^zf@Kbacu}^?3 zOExZqFVN~7>B2OSBI3Gj8o@AOiY0%m?AjvPe)JY2ajK{z6$RY!{zDqhLqoP0VC}+N zMBmv(nB>N_2nJdK@jyg$MxS1E4DStV0a5U#Q?2XC1M6zxPc*!DIN^XO`JYF@=ra+h zN4KH|q50UOw#!0uWN2e8mh4Y4X~*JRQo)mu8%& z!{xxHR6&1OtSyKUIa*(}@JL$VfOlptvV$@mO?PlW0v2=_fbHM=1uH;TjGR9BE*gO% zG?FmH%7gk5t+o{5^{0#3`&IwwPa3&cGM372LGFsKCj?dg6N6^{*|k_<3Re;3>$rS zjW*@MOiYU&p49$?hFbYCXB|b2xEufX;!aaA(!Z^xZWB)Kd8T8!yhHLRc zdloZ6@*Y%IH&LQ0lsNY`El3*z=FAQE>AvNtVnbKX=lV+Seh(rg0*?5`XzQ@Ur$t1;$TM<~+%^mD$7hwiId zSfl&*3~z9tYagZG73z4pm16pdY$N^b{QPCQs>3$&Wve1m2`$w&njP^qBt_i-d^jwU zv}!z%5*INt?aX4qt^5Rf2tR{;|2waLEldL|`O>)j8Fz!K6JdMc5j5u-wQy2Y&hiO< zboEzHRt73>&kKt?2apbj@<{B@rrXljcudLw(JNh%WOotN0uN8lk^cW{f&U0DM|Jv3 z8T$P1$v;T0i9>XEJuiTAF3+THU57s^x-u%MaOAHmW_hnY6>#e_`1?`uJ@4Fvv)*FQGW zip*X9^HDD1i~59%a~|uzYi0D4Gzp*GobcEcy{oF z@QT05l4$GwrFsX=FR7VpV<5cqN>@d|Avx~jrmV}>lQO3*>cHqJ>1HOYy~BiB7sIp= zv1haqT+>+b_o1ZY%&%;AeyBM-rwhm~V0yWH5Rs2%0;@sZEhO571 ze@19h`F+ZfQt2$_gPqTzf~UJ>Gbi~d^7qXR2VVa4sp;{WPRuuYTzS+uqiozCxuB?B zv~BS`yn>j#e1biAh+Zt&!26@*?d14<5MXItXM}>5@Iq=}rAyVbN7iORG`k@IXBPd+1(IWk4?Am)05~07AXms0qSBCL;!h7O91a zj|l6gHt%(wrmk=n6iVdEbrU@4KIMbPBxOpD$lH$p6Q%9*=mc&(_skoAmz4w)LffwP z>_BdJgsVd1u0d*XD6eicqMRQF(N}VFVuRGBkS@U8<3}4j9qv#IgRe0dQ?0Q_+)Vk( zEytJF|9`Rd=HXEP-}`u_sANlp$r2?g4A~7P5tS^VWF3)xCzE9mlYL8;kua9V&e(S& zS+nnZ#=eeq24nv{d%eG}&*%O9{`#lua`i`7kLPjDeeU}{=XB2H-Ys2bB?tcuZ4Sep zN3{-#BozXy5z(K_bTfb{0e~-zGNCaGs-KqFW%>sMc*_fGtlE7?;s3EZIw)h_!%C#cPq+l&8NxIwNYEI845(3-YZO<9QcfssDBHN!q0Z zpj!R7n7IruFYGfRc)5lV;)0*}n(lI^jE6-KztjFaW+<-+Nw=Cbawd1AVo> z6mY~Mjq}^T>*N~N*FiRbsgH&_ux0iE(8aeWu%+Qiu`2=^@QKwhc<6 z>`c6Z1+$j=@c-O**-81&fhTLgc?pO7}hkMk_b$Wa!6-ZFH=5YONI@>UC z;7$*-z}MA-$0j3|(xD+x-$1%sN#9Dpj`q})Zb|GyxZmxy^%`rXHd|em6sQn z9&VE+N1K&Zt$`X8HJOt#miNX?G|rfnuLFyh$v-#kcQSl0@g?64o~0IT9S*5TT)Z%F zVGt;C6Qk^&ChpewjHDz&_R8NH+U`F~`d>-cjl>>PF#_lc?ImE+0c}&@@nqGOddSxH#b*U_s4-RDopw zcfdtyH_7p5=VwUi<~7JEVDT?dt-B5}r_n(44|^%sY}vL$kF^9u;>HA%?m}IS_B8Ug zJ}C-NC0?prrZ4Yrwt0LTcHQE~@*mvwN3;PtT#{N?O5(@%cRW3W?X}?r9S0w5F>gd7 zun?v9e^11TOJ9~KK=RChT7EH4Xx?h=QYk(?(!I+ScPj-LF)WV+mLucj#}YbR5_>~0 zin+%*i`Z&27BnP)C(TqMLnmVPEJRC2F-hja?I5*S;l<8Rp#S$=*&qIZaDnw4vw&}?zSie&Hz@%#-Z0-- zlw5Qh#&)??eb_4>p6~yCC|SMd)-@VW5h!2MHZ0U>h;!la0f(pQqhLqV_YI=)S97A1 zUwXzS{$L$}XCHzh7+PKt?iv1a5s1X;k3G%`niVsdM03<0yEU3 zr9W;6r76zyAt=DnlyD!H334lEiR6J&Fw6nZoqB2SyX1gkWB*=KgHd|TG=1C%IFhTN`_cz^*v3@FUIe&Js>Fcr4WMH)2VKNGm9h!|$SHFMsN%y&I z0<&nIea|)CU&{>*OFk7^`ZT1sv7()Sl}7+D91&m^;N z%D+c>+$kZIn^tOEW;poWl?j-u_%K}b;C*{8cQZG3O4Q+7ZViQYU zK77V@V&fJ>v_or!?kCYp9vUt1K^AlC>^hmP`iy4y`&NnTM*Fj(^(!AxZj#kg8Q`U+Z|dpvam!&rR6Mh`*FLU>v^fF8fU!_nBnJklX2I*u+#k$>jy3F%v+E z4z#Bt5w;M&!@IBng$jj*hsH|Q*I-hdIvw0rT3y9AhOvEb5c_v15q_er>wE$&gj*=% zlq7+?0uvhka16lt@rE_|F)@z_i70cpY@meZ0kulM@ueu{_`Qly#j>*X?)IxyRm5Z2 z=OzUq7G=aO@^e9H>XneaC<~;+s$O_StX#Nqb8*&kmuq`4`}2}n%ST-SIj**YsDR?w z1$8~O7LIVx+W=dUtJo*SC9biQ1jPykfby8Qzd+DY?4%i)uCm_C#dHUPnF)FL`eDKS zC3?UakXi4pfIQHMxFSd6|0(@kJg0d}SMu5LrOT@ys>Foov9fpH<*3i{#ZAvgre)#f z&6vU|*Azyci2OD~55#L2y&O?^Zq0Ess9rRR?f)P7cQ$*jIv6I{&NZlgpFjKRx!aFu z^VjZ1v9i1nHvjZQlj!Lc!8e3bi7PZM^+@Y4-(ws#1WaU9G_M5F@y1|H z;xAU$f|`bn%&jkL8Y`kThUBSQ+lv|k_>@)HU~7-?gM@{h!+{KFX{UDJ@3HpOtHedG zW#x49n(lsyM0084viq^FKJ%Tq{2^r_9_jBQgb~o(>Zlw|qY!y4D<$FGk-j4NVem}w z^V0Q3!{ylsj8KKb(89x^s|eyt&t*hc-#vlm+E zJ3oweQi;^qy!({PR+-cuN10Fwue$3*f3uhGahSn#X4M261rh5TdseL8$34{&)jpK+ zVZiqVkN^%9!tC|pzH<+KFm$D!-^m&k_s&{h>qdOj{9}Fao>fi4 zyoZ#|JT%S1e)eGJ%8p~C3sdj=5T0TG3$r7WIhALteXxvOX%TH{FVN(bqV533$Axc1 zmz2nwdUsy&PDxKBR85BnjN(lN8 zYEzs=5g+SZUfhZK3~TNsbQJsQKk*0wz07*dS zYn{Y&(u|%Xx*u4^DzUqj#O0i#nubroco!rOz(GQQqypNzSyh+M9xcl$ALpsqRtEbM>Xz5&nnR)JX9A3*f{SG`I&+P$- za>WTeP5I>O`5Kd{l*5VQRGC4!Dsy^t&n!~}$aYS=@}B~tgOwGCAGf$^zjW)1;jZM9 zoRbi}xX^&eL4{T6H(7h1_YFOI{3ZE}uZqIkZcxtCR?_QI7}V2rvC@EI$LY)1vY=WB zHUS1WL+6j~El~?QCrQL?zELBwZB)tNBXlVpF6F;u)%=wnmH zFFDco7gM8Td1ELM3AvXFqw4B^I}LBy95V(%w^qKgVew6k2=2bjV^-48aQP>TXQX_95C=& zV=LQm3581woTb^`8F}(}ynU}o@<&4LkC)CA@S?<#P8EVtLQ>-Abh_QeBI~hQYTF#C zpBjm9d7$nI-YH@3nL4oDb1JFdS-;hYX=jQppg`)i+Br$ynPVQy+4`ag38&oKIih@a z!7siQ7j6+9^^{_Pu~%FrQCUGziY{{=h#^Fu|;`JYh7y8-CL zCvNl@9u4>SXs0zE*qF~2;^|BOUU_loKpWX0Uh=9td+e5m7$nt)S#4;5!tHtU9!A9J z79C-eCqJ7zuyUS)5KM#9*ni(ChPqfCNNN0Pi>$xm)1*TP<`COyC4H@1jY?uA zNLwCYPdZR4P;!yB8pnxHoezp6e%xvQ0J^#}LfS1q+9vrApSCO$aYx*QDMskplYX9) zGA5O}qg~k7q`kKsf}U&W1M7ZsuM_)3+4U${D|h0zNwM04SJ-d3#c}V?QC{1clO_kb zSKFzBJBMo*%w46|(lTlmvEO75siAHM2d6uF=^tWHPT&JF(+l*mhoN-sVt>-ZN}cqgn$;0F`& zrT!gwtBz%y0fUXzZqWnxEifiN0~iQfGRm=rksUdtJP#H(C# z*gb?gAAEprYx=EMS0=tVUBT8kAEcii!yG#1RvVxTZv7Dae*QA#^cUR=4swmT8f^0r z>Up4zKcHyB-^{=sn7{;&5B5Cna!VX%oo+$R(fHj{M7P3e#;7oUkA-!0HbO?sb6Wdk zmn+L-u8tg4XYPKib}~U?!*6@`J3~pw?bJ9mGZG(y#Z80;H-ODj{G3 za#$E)5Z8Km!$xq0Axy}o`qE>UCT(Ev{!)8yXuz7?K%P8pgC6o_kVWX*ah14;3|VF5 zt^xd3l}|c;b7;u^1HE1y)guC1pZqy`OfcLoS!a@iPjmL5^qPsq@Sigoq|to;Pr9pb zMsv1qP>gMfEJ-E@6-7x#7F8E6nqS$WJxx`h6S4jqm^^d!pTP2PV+LeRuT4zAo)dp} z#=u=qjqR-Fs=K5p@KI{YSW1JDtQb89fUBa@n}j$d3V6q9PwHNd?_WC~BC+zU%e|{S zOHM!<)hwN&SO{q=C#R%@MF>&lsWFSuDCrKzlAZ;{`+glZUOvo>@H`=f!`xa(x1pOR zO@!GaE`rHvR7AqbsQB@>W!PyyN8AZONi-cry*+Ii_FN@VL-%5rug~+8Edc@5v{w@! z`eH-d>&t3&-P(2i4D`wY1(+Y4V+Momm7emnY_BG5&jF>e4Z1MIBeUGQ3_e+|(=oJ> z5vyIxs}ngk-mmNPB8EV%+($ng^^o*r_x<{Z5%aM7;HF8z;{de#EU6kdBOIK!o#MKz zIf9t8Kl;3kY;P~}-si{b32@9a*?ET^(GTBQ^xjp`$L$7q2VY@9j8c5as#JipD(!RWW2C?PNa#aaL@LCr&BnU2)8~te z_GnZ-QM0YTtWp^#3_LZprJd)uy2fO^p|qZt%(7sl>a3$BKoX9PP{WePH#k}7xYzh~ z(58w3vXzs4pJ6}2?m39hA`!85`H$}n8;4tzReU~H;^4O~u6YkT;9|EIaMpnKL1412 z7mi<{_c!J$-X?wLgp-(V49PNdj*(6A*xGHC_VfUvlps~)E2dt3x~0Pq>dKtY;#nT^ z!RfhKS$VwX($=m1@9d+`(ySdQ-HpF!a+DyipxJ^QPqDCX#0Z6ry$xt)G7jeW#Ww!@ z`>ix6k2`pYd?7-=P#k>pmwqK*XYT6^4B`)=o!vj;HrtdQJUzV zkbC>UgqQY&wHOKRo%>wgG+~UPB5l9@5Q1`4(d6CVN)n9H*zc1pM_!xub(R>H z3GT|aUn znBupxgHv88mc9^VM^BQ7_R}bP{J~zGbt*~|e?T*T;k9Jb3DNsl?FA5Hcy;|DO+Crr zbS51jSs6Z**;!UgoYXgruiY!2%&}lcFPZ+n*-jp=%RhpeaZi@Vcw0ph!JZ`FTrc*o zvh&5>L{bOrG<3Q91Osh6u{_%=aeth%Q(A4~p!9>9n!su99q_}V22gOuMKY>(-9g|O zC7p{Z|q27@5r8mmLIPNjB}C-1+- z#|R26AB@AqYKh3YXJ5mCj%v(MlRbG_mgpx^Sk=5fZK z;+``~FJQ!1-a#$e)mj+0`xmU0{e~p2lf*msH4RBm(S_>@#R(e+GuV+SSP1G#k(lcE zaAOwY-n&A6%vdpliqM@|jP$Rrl+vKREJ^kfV&mAMNbh98jWdW(H$}2mXhd8qbT)#B zQVKjp8-=zybt;{GP+aP1%?b+zV}P4(-whgjY3+Jwp-)hhy=~K~{g3d! zKpmBjhj5SM_jwWnu`>@__@FdRAYpU%iJ$85Yba)X^UgcCy8sP*u2_V)p;2>G4U?%| znuQ5^&T||Z^ivy>Czf+g2bfe~2LZAHFjdc)jN|5I>`9Y-!pX9@*B(g{M*7w7j6OX( z&(kp}eY^s$HF4iE_vCZlXF6Rn?N>V`-%N*+`@l(t+i0&N(oN{}?Q|^pHd_4nkmGQ4 z21&kdMe=~_p7LUq(j#1ZiRs||mF};T$LlTWJTd6Y9_?V9r~CX~joE=bjL6*|P%}l5 z(S7^{FIIbOONz3em*48kAmBL2`5bSLy^ryp`=k>N5@9){?x46`t-w>tdW35KT0SP% zt6i9(Ia3g%NAnslzew=6Jv#)Y9cpuxdd` zJWIpQPG>UBm3r2#CRoxVjSIxOIv)z?%GVJ>C7P>o5$5E}VGVYbUi>=8zsxQTjXvnn z-^fc1aLQ1$i!zeaMtSpxkpJH5gVRgMLd)Sszkz1gOa-RUhz_J98XzH&OK-Vvm@pG?27 z_c1l{YU%s@0?>o~3jR*uq8dCdB1TxPu?kBMJ2`!5MBAt>WMG1k&GrSq>$c`h_1T({ zAI*x7IN=A!d1W2F8=;FqPjD?li5uQt?xbfCFS<`#7gf=uacH>rPr~VOHC{;OP_lcj z;$;8y_;G;6nPnFmG`?x#EbVZDFK zcDR(fU!msCS$F=h?qmUKKF&b`aCF_lgN+2k9ZzhELi;IdcWBvC&AWTq*=r*s_EdPS zGuLxF3N3Qn+U|`wz-=6*7z44-Ybbx<2R={TEQJl=$P-P{e;f>jD@7*lMT(2?h>Hbt#8o~R+qb7b%XX7(_#0Z z^@?b8%p!8~!-3qv=_tHY4oGDBN$&!DQEstU7sd^~Wp3@B2nc*~bfi1Wapfz) zHh*gek)5bFV6&MQ(h?Zpgeg2~U)&D=a6Co||4@r;Tv*(~AJi-tGI@&Z$p{8~ejhP* zAZ-z!=lX$kI)*=?>W_kLV<3tjMSfnGvlBI5z&M!TE9(V&tH4hW74YrBYiSr@9b}gfr|t3$_B{IKTa_Fn-x1NE;zAX-Eu(pDQ?nGGK8)6#R8JU#B0eRh-rb>TDYj0V`|4buk)Sx zWDClgm{)f&v<&=F_OO!tb@;WV`yR(h^s)i$z;9%Kb8y~cOm~hhj*`w3_4ahz+Bf^{TgsNkwc7YBjLsP48)BB6E()HdFy(0EW zJ+g;(ortw~kMv2nxavmtX$uRB&fx?XzDRq{v`be(&+|iJbGh;Mq2I=AzXzg+<7E+3 z&D4c{{DGdgwR@NIBvv-Q1Kf459gN*G4|I? z!$J{OpD0W~faIvQOH(eJS^)6zq2Y5`{;w)un&8QlV^Jb0-gj-|Podc}Nwgjk+Ci_L zTct-}BKy&a@wNg@XfkU1j=<4F)2@Ka*0k3kCP~r$XP)H(9Bk9xt!np?vp7Bo!m4OM zJwL&bpQ%u>A^{^OAj%auXtZcGh2DpRY&g+ccX8tk2+teor0}BftB^SaKmI2*BC%n8 zgmtM@M;lLeSxt7+YT#W+r4Tp-R%?V0w$n!+%xciiq@FsY~FA~ZceyY9onOUVLtY!f z@$?YamlIz&W{jBg+Vy5zySm)o2B;O?`p`6g)}*{}@8+$y;;0Oqg3Zb8tT){GxV;oQR-1;8_l?0CvN2?17AQiJndoc09YdPC z0Si6hX)N&pA$AwzSNHNK2dy$4Pd-hQ1UvwW-rQxHJ5+W7rK31EWU|(65G%vzFayn) zK2{GJv^XCUYeUmi7HaPn_PQwPFLcjd#G|P9V@+)w!78l*$(VV4=?5Y(7Ppg$k9!v{CU&gelm!#AVjX_0p!L+&X(~LNU_<}kCUx#Lt0dd zTg4K~mCgpgJh^g%-i^G01xs~~-sGg!NV!bMZI*K-qABQ5555`dr~*%#%l0ZCpRRc> zRqFuXk1wUU-CR#N-+Y|bs;gDU=6$1#s!4n2nJUVlr#8lnhkt!rwJYa*n9M0Jx>2TQ zXnKMCG-&x=i;%DS=G}xxH%pbkAX*C&&*}NYHRdyxOW&Bp-N2&URK(GhQ{*1sj)E%MTn zp7R@hWu4(Qzdu<}p*`Ca3}+2vO?OfVPtT8(G*d(JO2*eSt=LzG>r3N-XS(Dl*-qQY zqVtV`CN5N4h{HbGqV4q#)U{&cl3L%#eRq4&)Um8cdwGA%x(kv zYBS{I$3YXre^O4*s*6iU3(*%e=XYQWjQ*S!1c)6~IYj5pJ=oh(f3fX>Z`I=Yiw^90 zi{8ueE?v5)rMpBD$ESJ8ue9yttm|!h110kMLFThR-msN*7tZ=1+FxxK(a!CEa^p9D z{3O>d+h@yogLCet|JeRU9`Nm0n4S8nNq;S=ls^YjKU7gmd5!hYgO!5dG(#3`&-nzRg|z3WQ|EMSaiT`i!&HaKT_t zZuW!C`0Q63t7L!{X0uq79Az%oo(0x**rnDx$UrZY1gWrVXwTPXtz;NGve7B` z`hQIg|C5TRe7J%49O6(=7C2JZWq*o^Ml!l7Vl)oE*Sw%`tiY8hvQhSHmWHC7ScKW0 zKE>;&Cc2MMfY@RA?cfuK7=gA8zeKqPHFB~}vmE>!XkLEwEXUREXP`L^=V6?B+6W8c zrb5uGHsh*;TSf2B;(+LL61dw~7X6$;7ML9*=x$$a0n8B|uzMGV5@o1dbR}NLr#{KW zq+l3^^~I?;;hS8=7wS4foG@y<*O_{Kn-_i}tN(GUSh3m!+5~#@4zdz@2R2uPVBq@c2MLt`nn(zlaZ{{O!LQS1f)} z)KC`ik|+!rCx&7AEuiIAbxR*yN9x6Iz7Un@J zm4jW8u1gu>%we6}4b(N~rGmumScwIv9Ud4L2x%bm^bE{tL^GZ&KhG5|MTPN1Q6d6m z=9R6lL69NgJVsQ*z6D4o_LQA!{ckqrU{v+|O(088jq$O>bRV!PkjGZ@NBHZ=@|aw1 z-of}_Kx2zc=Fx^QrHf*1~^bI#mx8A2iw117y8C z2&SUwtn=;>P*Y9ykcU;?CcB6)KZ$-OWui*^GjRC`4cIOi3oJ8|1ci*W{f+Knmp#{F zn9wUP1htH<3%dm7v^uEm?i--8k}rlcOCMTw&zM#enXodC$6qyN>E^iKR2J(^s!9Sc0po?8GVr zKf0*QaynaXmWq1p8@A;0DKz&k-gFWhO4t4H1(M73$FLx>SkS+}ln}A?YE_^JD=re; z{t~x<6X0`5qEs=UJQ?;PFIg|Jhr7v_YBv;u#Qw=1p=>m|;jHEr=R94^hJ| ziu{^3F&`LCRn zr}(8Vqb$sf390oLauD%{zZS{MdDZiDU#x%4)tZq?K_nAeK54SEmfGCqmO!D$sPl~z zB8T&2x03eM+abH_=`7ZcDn-it7p!~wf3WoCCmx5*CY@G$jG(KJrOyhi(WmVDZp{$yKw2?o>7IEw3r3tZ7@{_> zH)H*$dJ!u_!Cl1;mug-#BL>Ez_x%%M?sj|tSFe(@U6?AN`t{-+`F19gw?Fkx414U~ zsO`W;Yp<=QA>P8A*N0evptC$2Z%t%p7G8`GI&{JM5Bru4(K#sNX+$g}0X9JH+w_5< zK+@ZiS%<7cW3ed%Hu^^puqyxm-(J5F#F82XN>Z!v$iTIUv%M}3!V&v#}6OqyI*U?l!uEBjOaH@ z7Kq-)_cnZy!@o9t(!Gv}u3R1-%ByOA1YZ`n96pNZoqP4K3+>-b0X*^q)46e;B(rp4 zRHiguu{G)m{dtQEppngC57p_b4PwzsjHsd~9U#g3oUlgOT#!O!+!eflIq_xKM zZ-Cg<$0ibPJD-^~fDBt+gS9=I5ge&ROq;&cdq)i!N3^%jBtbD+xPkclZI}poP-5}q zgBFpnjf7Z%gHuLL;*B%9qq=0=Xg;m>3J5Aa!O`kG^TC-8$jay9r+*9;GWLe{vL6jW zL6UGkNsk-qvvc};e&$AYc8OOKMHGg=A&{R|b`G>eaRT8!<(ZskSC2^y5l2=lyV0i)Cgb!xzsG6hv-;UyToE zR<2yGbd}|bcOUp;y>+N zBY#ocGDBi(z4ie4beePi8A4t^7RQJ4DGkCsULBq|)GqM&K?YenyZmOcmi{?xsA(z# zm^)K6hQ39&m(urLiws3+j52f*#`$khrP$ctAi4`tDvC&S6e6jzKe%rO?Hf(J!RI(S zfOU;USJefIeIA3B*vA$I{`q8{(xr!9p*)yGKI*9^n;i3Iw`f}%apPZg`@h+C9~DOy@c zyk%Z}g0g{A%=V4ZK^NrKBU#7@Ck$eKupHMiMskgROG~~+Ia5fE2R0Y-;r{plV{1By z?6@DQqlFcMtuFB0ss|=*;1l)Az*ksQF|Z1Ve1$;Kgc?GIiUS#lM;Fk$Rp<3weXypv zw_yz1HiW~UZnl6wFUfVL;G-h#Q@1#CDqBjCNaWyuV-Oz8-R;`Ykd|}fLgqFt2Zo(A z6w7$R9vOPEC%jXYT(-d-8}k+?1MxI^_Z#p~&WwuA&5Taw6jqW-RlUNk?>z5Ru^Bo= zzj$BDSA73B#>bdt_Uo&A_f^J}2Iq(WmQL!)kXEzmglJP??tsXXP(8&>nr#kcm4JHgomu zhgiy)&l9htb&>kyvbP;ReS~@I-0D_VzD0E`lO(He%{fVHh@cl$bs$@l9TMAe0S4ce zo@RZ6K&@&!R*t(c0ch|ZuC?j+VazSBQd+LU)2GKpNaZf;+gt;ix`L!kp{gv)sTshj zLP-oylw+)L%_K`nDgjSOA<#0MEIFGxAvRyu*U19Duf-_#nPC+P%0Z8*GZy{_zd`&L z+#}Wv@+jjuOYXkW5@@8Qv(MI}w=x(S=JIvk+vS@x=#x|g^>!N@Zo85693A1({ z_rMp;LI>X{g@fDfeR$v`uTt$0@FtQ?oa%0aY#d9My%$yckC zZKYfulM9d_vvy9RL#Z7t@dUxiCu|L{_rFXJPdI5(9vZzlNhr6XTVq92Obj2>iKdwh zD6Ho(bS`na`$;ObSQvD-EckCl-6)sPWrSq5ocuij+%4Fjv5_8#d%LM==5{MaBS}Ts zlB3L7iS30h3(veMI67E(ixb28MxB+EBCoI<^)T6z>iz?GwAt(NnUB5`{18Mz-9WU>TY>Una44!Yd4x@GHh6=wTI?;*I_BfPU*n%+owj!7Rs0d2 zH`>lLa%ng|bL&+?dz{WsqD`yho=X_3MNwNZGMyqGBE#AQ4D;uvHMcL`>6C9`a#l11 zieDuKj)HgOA@ajoG))q>wo;tI{&N>Yb<+#n(>P5WUQfXz4bwo;P#KnzrL?0 zj{`yLQPMNO!OM~C!6K>EEU)jvEIodcHfBGl{4g_sYrg7ehVBngh;^NtIxmv9p$OWX z9+P~A+`q`=`nC59O5*#c1R2~oAvjVLLdOg%U8l`gF>Q%M+6vGyRl{3H7OJ)0@vpu4 zzyPnn*6xIWO1<2ECpLX3Dem}3w>SRaaGam7^0i;A+cX3)fat|bMIP2UN#AVPwUT(< zaCgj6q~UB<8Ves9!xBmf7UZyR1q}V>qW^2H1bo(t7{{GDLl~3A>?y&INW7) zEE?(|s`mOqB_Q{eX`2w))?7iMZ}n!2i(7^~sCS;JYQXC%3<5kD@|?yA(ypb&kXGHl z0b|IYrfw^x{>bQlcQk44ms+}dn>-=-?t7z}-R|$5vb|j?4e+4aCfx@3L-y% za7?7E+*}b|xFj0`;X{)V6MAxK3y*eP)~2urJ(?WGzDE=HH)3d_ zGPhJ;yqx_iuhJNvA$Q0?vyxbq1h^UKB3$Z5eI>v7_635#90L+?e=;j1Gia{H@$tGs z>Nj~DsbDbnpjNy{Tm80p9%k8AWzO`aLjU?VR$oRsF%ygSf_Ys_Eg&bf(Wlj0Jccl9 zl|Q_)eP`QTj@>N8!FJbPV98vkd@Xq;*d<_hc(t`lbA50`a>I1EGO*ULEzhjR?@8f_m9?0K={NLQ4_ zh$YoyZnmArLB#3sDoTBoWdTnBfx14;0#pp%uEv1qHq_8PI3*LNko@zlMGa@N8brwWNiIan6l#QQZa2tTYP* z+^q&zR)~CDxY?%Y6$!5`vI+6{9V)0bMb@g#OB7n3=|jKb*?)2AT-e0jYVi&?I|H$4 z_hkwuQP%T5blJ`#vsFZdOG}{)&Nf3&y1ES29`9YkUDYz4cP8UY8L$dWzrCE~h6j%~ zS;hXXYi_(%ur<@+mK2YPs7m7~FfVL@lMBB5cM3+QGw)^E2v+Ina@UAE0 z#+dsCq^%uw_mpWW^6hx5cpl`$MPXhJ5%}g+UlT8%) zR`i+~fJE{qu|Jp~`Up$e#Wy#8BYwqKn#dODxA{}NP(qr_O)-w!<%RFNs{S9AbF@7_ zQN*JVwc8FHL{2)b1qHM_IC(MBG%t?^S+HX~?2ZRK0`(;^J4r^oum00K?^(G|qzM5j zmkZikrafEKKo2NSx|RiJ{S1E#haS{|z?8sW`qy@Qv;UO%KDqV>G2D*bi;)TUoL!12 z7l~!&v%Q6yRC1cgZck`rFYVumoSj_KK>tPlpnKpG#$bT7u{xCAHyW+E0P0H+@{@bpM&nCjGWQGe>_^tF;CF zDva85x(^cstlcZNQN}&t@46D2Z zC`r@F{k>NfDB|aV=^HOxphd3ZH`};k9^B(uhe}^8YA9?RJ2i8`56233+328rq`47M zDzjabxwiW7d<$*LuSr<{)R~P4L=MR0vy}#og=7B4;3Fp^TX3}(^89TrZenrBAH(_$ zc3;$@gXNy%?n*(!&VygzRMuTw8cVQtg)6 z;s2m@;Q`=${Y-tcWZ?{L-#5)))@A|l$B6m!&j?RPw}Sw~*!!-Qg8~z^`<|Ww}AZi^k>i1k2|hz*K}W_(wjQBB4-TwJD$giF}U&Taf8H;x}$k zVHBCB+NZ1mu#*KgmWdYja|&i_Z80%-cxlaA8JMVPSQ10Nr+uIvqZV|_tTa8?E~;Gz zI7f=eb}a$Y_VdKkV@y3&{Zvw$ANU8VR7?e)mPnOo@D8g$UN=@EkAM6s$wb!!b!oDu zFcDtKoGx`}0lnX7qKNkjyb@-v71^#rNMQq`fwtQGld=NEUA4TK5PrOaw@{D0jq*;J z8HroG^%(9@J??>CSCC;>L&6{7u4KYKMAh0B-(dL!3LY{Rw&E)%Uv2)D5lCr^E*0x8 zLKY56IrY}+niO(h2Mo(;$6bBHdwRinastK?V{&^fLVM;Y4 zp_4Y!o8?Q6Q^t(OAumGoG)IMv9(VGv(gTL&GBW^#DPbKqIV;g3e}sq7+@jPHRoj;RTn&Xs%H@!fxq)TWw2=)Q=F1zy9cRvGroi@Og~Jn zm+yW{PyxH*#6t;#uKUS}H!bFRP^sY#K^9^cSvQ&!WFB~k(n99?R2!IN0fqP~(CU5e zbdPwn8X|>Ln-Ul-V19)15Op%qi+>C$Gn+VU5q&?tj-LK$*W6QOoXgf1Ef;=hhrqt= zzBTqo^q-*3{ZwJgQzhnsGanK(@3vDwn&hzCpWWH@;bVu{c;l&rnAR;AWz1v{j|+4D z-39RXH;!R4CnsB;x%V58p3&-+X|&1rp|-KXq+fEXmNRrQeLNU|+0=H9Wm{9O?MP1e zW4=@gq~@@)fUM=Fz2}7h?+z~r0sg0+c zno<#xY_^}slM>6txP@j!m`g^*Q$q9u&xr(ODhq;STniTH@PzK2V6>baUZjn%O&qq- z$}t=B5C56fdj>oA_hKlt}Mx43U%>2HqAQRwOhlGZX* zF8i72dvqR9^X8=Qto$Q;JV6px{!#n|wL}^wM5k5mdsMpOcE^0?e$2(8^Uk_u*;#WP zN~N+K=fi?zcn|Yl8h&}=YRO@&w)al?FCbZ(;bLx$gq~Z^Tt?q^w>`hNJCYW)Aj`Xj zei_PI_8^Qkp_M2VL(Q>sE$h9FRoh59@Adw!PEk$(I3xq(9J{e}K#KUxRQzB#bDH9Z zOQ#rFG&9z_m}OnogK7`4}T7uX%k}qkdemG8cm?yN4fclQ6jCT zyMFpshW_BT7+H)Kp^>(RpcTJ)kSE(XY_Lt^sMA&6^dT&yK(87)aRHKaW;KNGd=A~1 z1a^PS?d8kG-Gx8NdCM<;T>8-~+-K^kF@vxXIbd~^2o-aJ3Dv%U*ZK2GdsQYG)UA{$eg%sUUF{=2(A05eDP=t=DjPf`9$?4=1+a$^z0E<_$1G$3-&G|^Lc#&sz zZ12wXjiUP9QY~A9oZ33kTN4q48acpZFggUx6MNbGgU>Mx9vZt>WKNUs9jZsH9{=4w zB;W%?_XG8%9|3e9lcOo9-Bd+IBIQjnLbNgC#jaa}v|@LXkW|e(^$33SPkF>sme$Hd zkvt%luc0o&kOp(6y@t4PeQCI~k4p*z$MpSq{_R)JMukYG>--jgsw&o9U;3+{{T7RT z9ssAg&cJMsjHpDX8U_LB)MFSsHtgI{;T6+ttaNyO@nNnU+}u&p%p6=jgF%oGw;`Cq zia0>>F8UFSU{J*ALlD{c6 zB*2AKr|_XOv)Alr^RQ;z!(}YL&d=p!>ZY>_CpIMnT%fd5qIsXW@{l&PFvJlXX&bR) z91;sP8{Ms%&*lD`4}c3GCptWmZK&>%&bQG;skd1MNjDf~z6@x)Hp0a&E%-WMt@wth zi*LOuS-mpUMiK=uH1Hp#$`p=)wK-&6g55#UQ)B;xK~`o&_gki~$W^lckl9D@SWrQ+ z=^d$Y>qKweYu4 z>$`(jy}o$sCwJ=d(B64vVtw`bJfhQ7IJ>7%AnJQW+42 z8bU-sMM6MP7#O;HU?c_df85DXqW|z4WX)Jy*4b0&ntAZYN5KaIrCuTF782FvPx|4lpGz zJMT&?|8Tow6bbUOR2GGeS4S&xEi4;C2j1b3m5#S}o zPkV6G)5HB@8=qG6r2z=D;{)UvbG7Ow-EUQ%PBJ|Ga66O0mQ|~QWYXyI1MYmGLGeG? z5uJ|cOZuGN8MgwCJe+Q>C=nju)wr!xH8Da5yTWtZ zEa?R!Zb>AHgEtf*(P7xd5co_!Fr3Dml6K-fVEW|&jYUsgiV}iE2#7U`na9Me{Hm9( zWSPCvOBq(+r44gO5FUhHxGnzPcVZM%!UvNNovRC|G z&dKFb#`l;>*PDKOV|5GS2v9i2quTf2Ub91Yd0%J=-yc_WAAW(5uQnQhe|0pM!U+Gp zB%JpsQ9I3gS|VmELn&i}mP^8+kL>R20lQ~Ztaoz8%_PZDgUkqn{h~J-WRgllOk$R4 z)whBw8slBmu(ArI2l|BFTQK3(QTn!evwtjFP>gkz#PIvKZ^<@!$=O}T>B^gB?^@(` zLcF!#ufGEIxZ2wEbX!!+=q&Kbmu^xZ45Osfp8$2-kVxY)2}?p6qx}2}-1$wKl!&$M zN-3g^i~rypOZVO^RulB9hbd`KciPte7?tin-Dw2DN6_Gl%Yrb~z*nzp83c>*Y#-5M zLTew^$56SIUsx3p9d=ctXcS^DU}rzXHKV?!gdX%|tep%E-sT$^bZ|T#daIb3JEfLR z4qr%^r9y;EBs4lPb@qrO9Ta4?ZF}J=YAe)7xq13sal!*mhn5z$sBKm;iPvaX)5#JW z%yoQ+H7uMbY?UL$EJ<)K41c7md^o*|gt51+{B8D7Bq2hf5R^D&?&)xdrn~0qE%O2C z_3S1xXXXC5B7d`#NSf6$_^l_-gjD;>76_tQlxl?xRiOcH$Kjigyct*B2e3V>U|#KP zzQHCOPD71qT4X~Yqs1XD!*lid!=o98dI;B1x)b}jP-YOaqG1-&PNZ16pM&sCd*2cd z4t(rZU_L?!(vm{Rbz2?e!pI*+9Y=Adb$?FFxVUtirN`w{EHtPgzp0{oRk()|f{$ai zWfesRn${Zr(YW8~ETqb-i6M)sA$qAPrm`2eSr=|f zLV5X;W^FXK^Os$V>oge7co{#c;7;1a=a$M-CXy!QIW0mo+lSS5BLT9Tr3Edj=ps z``9WV<)#R}Uxo;C>N^+-JW0c>2APW_lDyFpRkDvpC#lJ?c^qpC%I`A`=r!EU;dlgV#-a z9NudKLczO|mea!eqxK{MZK(A0GH!O_;rD}2YYmIi7%Lli^GVM)c*aF@B9Kvj+kB}- z>jFqOcGwt_itu*U05L>kMosk~ujCiQ*y&RVOhd-Usi)ql2AbMFG(^b*3Q4Cqrsi3C zLB$^(QDM=1#vQI8{;-eF)~}bDTA_|US`_k+6&SP({q2mtA(23zmy~%9FBGePRfqZC zgfgs;iKc>^Y)AL5B;g8tUeC5y4wPDI7I7F>9nr)T`IRO*wE^O@bg4>Tzn}i#QqEQi zSVsPU@Gb22{F15}AFB+S7Dq#ikeC);${Jx_Y=_`4DH{f6?b=UP`h)4YOEY@)eid65 zt1joU^wE=1>dmj+x@m;I9?SKWs#vm4jf0&+7RfH#n=qc6QPxvA+L)eJ^m1hmGw6aY zm@dqO1&U#ALId{h@qTa2GU&P-_!&J(ALmiQ>?TWef;!OlCQM~iq2KOp*1R{67ryQZ z2%#253$qLGcAN{dbMLj@;`JYvL%xux6}NsL?xZ@sac;2X=FYxpaq_Y$Lvxa?mH=_( zvZ}z#Z{bd<@>tCO&^4WS= z7oLp5)CyCN^geAdjN?rnp+~Ebh{;%586%-59dn zxTzNJN`AF0P<`TX8tSR=Fd55$vFz+9xyt0%$Yu0aAy%Q7?2wqBJaQv^G^lTa8`V)U za7%-muF8k-55PH_y5=ZgPBo6+7;&n+lux{&dsBIC|LEoLeFmhn>=2C5!GE3j05f#Z zRgnyfW|q!*c0jxt6)6#U)3sjb2^=E(kDIEO;6m+jhj*%_&CtgFMH$xK8NOy}7F$h7 zlIdI@Q1yt8{fD$i*nv$X6egyxi3xu=dj=m3dBEA5nDLP}(|4UN%-SCveM@w!tZqd> z@&!grguV2V&4SXe>ShavL8&WW{7cz0iM;<|{^(+*^Fq*>3a5tL9w+H!m~#JoW67vi zcu5iQ&gxoKZo$x-7j{f$&EDga(T0T;hWXVjZi|1Fs0g2#r8jY6cy{9pMAiL>xVWrr zyfOQvw+(&gKe7ie((@M!m}jE}^IajCBstYsg_5WD0+RqiyxB9#CB&dn=Fer9Y>)Fz zJ-UPvLJcq!*o&7XOJkU}b#U^dn{`|Z)}#C&0%E{O@yX$-BJ^Q>`%Tc(_At$gGXlx| ze}T?~A&wl#CV#lowED4T@q2$TbO5p3L*Q3GJB0PgvkF{L^Y;2?uXEjeU_15K~R8H9s2_YB+vi{w3x017UAlYz%-1Wl=dTONMiA9QfF)CRRj z`G(&9x$g*-`>x>wUQ!LSh^v=XE?^cgJyn6Ev2JHJ#|!E(ayG?2$hgJ%QSPy3|I2N3 z+De&sjVi*IITz)vZ5S7#2TE1ZQypx}2yRl0;%VCc=agLODuw8g@W07Xob)f9|0Z(X zu7f7Zo*=E9_*4C2ig3|^l9V6 z8l&*f4W#ABNEW}rT}dEh|0wf3h%2F>A^uWTJt8R3K0+h_WmA5VB%CrkMlc+wRwSiE6^~IR{^{A;Ij4%9p z`8d2)cVwprORQghlata+b|LZf3RMLbpm^AQkVCVtlR{nY(azG37`G>84PW*DsY7RM z@|Q7rLg5Sq6%*>M@BSdgd;Ty{EAI1;5QRU)ht63>oXUJnhp7qktpOS6yoxh|q%eNl z{TSI5MP{g>foK$K4uUpy&8X4{f{o05X3+}oCtpFCE#AZI^)N$VmdJXPbD@}auHAps zr$W%zAAJCow6;6B86FiL1Oc6MHY$QF#Wx!jiuN@|gZo7+zNHeO;7N>tO{KkOt|l^# z4qo0Fl-vnm>cCuYk7DxU9k;=DI(NRP4i|8RE2)stH){a2;Wd#ms`kU2zbFJ>^~r}B zv{PpVN&kO{KYcfw*m}|$cYz6!aqvBreM9)BYLeVo*e!FwdVnr0km_HJyd4N)7bFZy zETzMu!sN0N5(avMau|oSg++i2!0U7n5TUpQ#-b&X_`S|Wh4^#I2X^w-hi3=>+^8Iv zsEqaPb&L@g8vUE^fac8U{iabTAA|Q#x|6X9&jDKxVBjn-LB1(K5hqi7{%C!L?O4?5 zbke2VdlD*@l1($(^IDl^fex{f&#a@aE?Fx}I5WEGamn-!=5(ihTzez^eiQFOA^bT9 zx+2Hp2ixzv|yNz;W$a8A*->q!K=ZyD4yX#Kn=L+B&W!OS6Q|-kHSjMv#aYM5F$5cBsWf zAr-0XJ&cD;J@mveBU*s3L`R-C4m}`p7=s64dGkASrxi_4>PtNmPb6gmpCm)Q5;rM| zX-9@v31vH%^2rD*HI8P<$n^nJUN1$;&hLcOSN;3=An7Ty&Ymqc z-tIYMivO0@(ZN|y#Io)(2=rR~;(7F4#$FQ3L#ILJ_Bw%)CV<TY7sAHlDQ1~NjmBu2~JH&(^Kw4ZlSF4q2&=scuPBVZyaru+mC2D9!R0pF$ z{gF;!xWHJ2hq2X3spM$zt>6}lTNUT@$1>Nxp}(u9JfqScH+O}HAd945Un)i;``3(` zFz+YB@T=YUIQ&HPt*CagffeLh z=kR0b6P1Y0TU$A35M$IdUzMqcX|nzoPPhy7C|J7iz>?7`pRrwY$CnEIfiQx8xSkr& z_>-a{iyu_AbBUf|Yx;4HU6-k{-xQ?n)$w-*9?A`YsayQJ+LPm{C(O_1ES8;Kdqr~_3nRL6Zl&;NXS`n(xCPc?!57pQ$_O8 za*7zGWacZxBl`HeAQ6$*g=sgW8ky`BA2AGX$FdYRV3=tZ1kj@hh+nK8n0IB4IeAdX z*Cqu5LkFT3MV7R{s_t_6YVUVPdSFut)cnS|QG(_b{X)VbogN*&wR=VsDj%rc5uf#c zT9UUkp#g80$~!eFqdcp{joJ=1nBohB;*=SW#s?ByVJrh@m)Dri;&Y$m&dh=BIy15} zw$h4RCe1;#@5ZySH|SrhCwQ(}T3y9*&zY6MKZeU*R;;qIcTo}_2}pE)^hFNNz)lrt zUQbSWvD2)x#iLl$^P0ot_J=mW_mpWj$4E^7ffi?QYts=D@ilH0u;bD@0wPtRs>D5u z6(Kb=Th&f!H7io_<{s*_#W97x__V?|w6M$xtljlO(rtU%ID5LwMgy@3xJ5 zxk_1=(e2(W1wYORHh9>r7Q#z{-9j$R-bk6d(hDN8Vhx~8YiDsn;a9*KI-2LL-G9jW zkBp@tZ4cXXsNY3mkdp|{M;=M4-b5%d2@Z`3j)wB<${+F(N1`I#oT%Aew90q(^MeOX zj_MFC7GlRL0+F9A2=FKI_MbaZ`S zr+s574ux1f^FBSc1D*oFB51{sAz$BR16s(Bv1RW3tSJ?0IKJ*r!$9RrocY~{K72>G zgV}vcZC^%st9%j`b>&vh<0F-CV2-$l8C*OVl$?3kX*qG86@ne<)jW-Pd zg|H!|Yt?cZh+da!?$qDmov#X~AphV9MD4!$6lOhnOBTVYmZL5-b<%Qft`?zzMNDbX zuy^(~z(P>miL0$eHIsP zhta9&k~K??i1wFxu$uHhYbtx!+Et$Y$3Gf2hZh5M{_2dQ;Q^tlqeEow&Q76A8h<>W z%5gP~4L@2Ex9qWqmK)nUiT1Pe5vk21#MTDa?G$)~av*2IXuIr|gX>qWhhC^d-g+^7h*SumQYZ*mR?*34ayN02*p zymX(EYPA>KM!4sGjMcSFdJ01|!9c`On%=7w4eCSjxM7(G^n5186Dqh21et&@EehBE zEpw_oktgC!<00+6AfE|V71lh1t|_j8`!k+cFdbW*Jq0H4knl|U?sTzv^MJrR`dx!$ zR-&Vr@>Qc>UuouVRQ2V#CEQ#2i@?N|^}^Ypa{HMj{O*5%T_D9w3IyxBPDBd9L0w$L2`xzP2}tq{n(`~$IDq=An_LHPc><0?OVF=OkB8+HQg~6 z{rg9?n}vbxqOJy&bT@vtB4DFrSi8VtGxXTV(Ha{nouWW!RarIn100VdPupzm>6OP& zQPauLZY#eJ{-0sqH=&gqARL76b@#9i)qg#Tk?0}FcD~R!{yNov*!h!Qa#Y>5)o5&@ z43(GHy&h8(o-O%8=jgxee4SP2eDFCzzVMGVti6lYdlUBZeIb0#0#wBoCFn??%bUrgYaQ?F!(8 zmU*rwfWCFv>_gTUzx7v9b5F64GO%WyI+!ol;@?wAo+sb8%@|sj#(`k1_$weba>+*y zU7>%%!+T|$1@rz}U0kG;>A9tn%U8{vSQ(Gr8jHN&C3RpN_NLc+6UJ?s(R<{pgCPGh zHrkY}3%HuepT=p0#u#-+4sCw$=A0OsQ7CrzM2dl?b$oLC*b^q`yT(Tc%yHn-Lk3em zpaRuMxu2QZmGy?>B#(IR^YzH(=(+aV6K-tiFlj z1k&G*{pi0LjcmW2XL7Z}L(Xh_=8Kc5wL;DSQ;Zm&7cL8aHTfW-y~P8ISmA0=7FFlP zgxP)Zs`N__mP|AAOO)*z1KKoRhvocy^rIqvh#yFc@tnOc4)p3|AwaLrS#cXhvb^{+ zSGQPF$m_={{QQwTk5!2K699aWZo!kpZ6Lgwkm{p|Lcp&92RSnPxhDlGi};Y@5Xii| zxDw;)7yH}-A<0Z|EdS9_E64Y1gMca)q6Z$i*6kWS<3HYfk*L`jp@fQncJfcQ!UQ7K zSk?vGS$d+^xAQ2bYqQsTDTT&6uV^V~Te1GXxOyjP!Xh7OEN%ei=6pDVrba-C43uHv zybBbk4IKrFwJUMP5E_E$h;Tht|budl0= z#4u=AS^zgVgTRQ`*K?eXiArS{1Jo(t<~Jx%=@l2IXH#0ZEs7pi`|OS|F&U(}nSsSS z^%`aYj=**VG?jTk_WE2ok}MVtX!HM4@ga@?g0Hy52Q1MFh!j@A&gK~kINz_UolK}= z-T0yiv=BMDpnZO8vIIg`%>ER#_iZc5c`pZ?+a%|G4YHd4iKjCxPP*7_Q)Sc9K4>G* zwA7651JUA2`|;Zn4{t#{+u&Dd02jF8Lk$hDBF#8HC%wP^#4(maJ!1*jRwZ+e({rU@2Qgvl$I{E)~ZP`%%~2MO@U z{F8>lCB#NfE}zuRSmaHcM+HO?~I@x6VTh{Kn`rufT?JisKxa1}Z}^zb0b>zAdga19b6c04`q@wwf(f`z7&o(TKUO*F0Grv($PSAb9g?arLs7{><+BC7%cnVPiRO+2nZjN$Ei@YA4T$3z*$?`h&LyG& zIi2TGTAoO8T)KzomzRUkZ%WBS>*ORak=ArDd?(JhTq@$Ya=~}o&^%=F6*hSE8IfhA z29<{Yok_#5eK+q}Ss8{nxFLT1KX%TS%$>R*Op%402Gd;$a_Xc1^>a?pO}7(Hp@TNg z@$TX{JZ-yM6#oEGWQ1mhMrH2T<_lVsFMFO-qV~n^f*b=t1pALe-F=6=%Gz{OP8dD4 zBotZaa;o%L9S)fXLj0FlfK7Bfir-{h>7mRsOs;-fc;PL*tlsmFs0}_4UQ90A)Mx)q zZ6?7!g98EVNlN>8L0(|M2af|M2ZQY}Em2P13=w4vBClHk81*z|Bwcqt8U?Z?}t3 zo3T+Bq!DAj7L-ry7=3I+K3GuZw!%#G0>kTVLgTkD8enE~GPGJ7d^j>1Rey${8?Eqh z`+^$d4quTcy_J>SV@b5H>$I_OuA&z0EMm+Id5fh)$j0s@E`L9*^+ZUuw_ig??W8Z$ z%DuaQTy`vC+spR91(k24ml8N?9^+zpx}-rN>CahDpLO}Dw;ZDb_qozm13gSV#qosh z&0OZ2`H?)cX>?nU%QTbK2HpD^bK4P;**;Oa(*nh53OQr*B-7HOQliflldcS~^~R~u zTLdDo{%qP$6&mbHP2qNDULY1)81}^d zVrbek>-0vY;kPuK+yE8`A4;dETWw`5)|F@e)Q#&2>f1Qb&uhBjEjJ^hFGnTy)suWq z*N2p_&O;UOjf~1ZgMY;d*z6y703p*8=SKz|bwX8h%0Cqj6Si;Nzp{c{BUB+@>q9`d zO!m)4O8LW)*c1cc zdeZr`|1Dg9KITa$* zT)gQSYaTVvE)3`haS=6Ex0c|Y$BaGcGWHEYeY#ymu#^JgjQ>S)v&M<78z9I48mjyw z44Lw8Mgl0DhiW$05ItPHS7=CL-%zg#TlwLTc&%BjpN|4mGo8g!0oLf)+^U6@rq!39 zxLVaG*SV9ZY9HDcL8c`Tj4JW`)1f(Enbwa;`tGa;eq#)ovB`!kFU$05e1NA25`g&QcTC$-`2Qc5ie}Ni(Rwo?MHba40b5 zlS1yiC5fdh5-@2NNZitW@k+n#g~g(rIyVVkzSWPK`p9Z0%jjm!s^Ch+GW71rPC>y> ztitH$zYxSUoE~IghW-s#SL3AtZmTf`M_o&1o;>Cje+g%D-jvtC@D_+v^u0p71E4Wc zMKzu|6yW5_&yi?&2PaOuj+8zIEI&}pr3AO799WCC&z^5gF8|^~U+@AU0^!psZUesO zIr|W1T>6aYeH@d;pZW2BnhH6R2qsOQvkp!^7Yk{YAS$G6g`&)Fu?Vo}kmP z!FImcc7FmZz8J%%0jZwI)@U#~8-89vvGuFqZf9-e4_J0@=S00l{g2Pa1GY?kr;Y9l zFp(p`0JZ@Y=fhv-90Kqmku-HrMH_Pl0VV7&g}XWvor7a@qYT*oH7wG*bISOMHa z^!@~&L-}{Xgo>#*t{Pb$UN(@NhK!xpltuU93}pKxKc_dQYcQbWhZc69&N=c*uP(>Z zkZU$hdw|Kr8#z%TdgmWN)H~2r<*ptMjH~a@Pn7yKWY#eOoqOGv{h7kBzq|tF^JgGB zF?75?|9MOky)Ba|9^LmjW2cjZvMHcP6YU>oEs|9{(cxLTxx{JTqHRXXmxz_?^r)jo zzkmrC@@^WXMWS01|1~3F(7co2bD~e*`<7<7>oK&$WY6*1v=!!-_m;mD30WTRtRUqt zm9=Qt`4ZhoKH3-oGFQ`)P+yAz`^5*CEU=xN+ID^Wrr?lvV7b@$H6HCgF$sVdSdKiP znogsXFb}Y{eh_E?q0wT8y}Jn&E#9q9+Ve5Csvh?ibxi^m0__^%P9;+CA3J&`1viEZ zZ?AvZUBdbc_K&SE)aH$q1)g3eh}kr#+7u1HR5LM^|9FreyQWUHDm2;*jhYf2o{QQu zxnbmqD@kI0dv**2s3f|%0U$$y8`Cxam1&r$H(U}Y6$QItWf77!k}OmK-`&*b{2TUL zzW&FLHkYO@9SiaF$Xs!3HHw$4zEssfw++(r}q1(nRsBwei7cu zvE%*UUpkWPnj%hOqAyzy&2dXb{f7_1XY|4*)lb?lrt+O0CGLl3&)W+NwmT1rhSL?i zq|hXje3-RY=LlWs6N+!-4^J0uR3e579;mgsY>+!=#Q3Y?A3H~q&)EW#5?ht1>+=A} zR;HG4%a5;Xql53fXA?{Y}(Yztv-_d&@Es88W3N3U|Za zQnJ{<8q5dW0~$4*k`-a&f4@6rNzybohG#4f7Dc~g{(SffEa7>=yuTR!)Hu0f zXn~*QqxdiOJw4#kX^IMnS8(jHI8cRN{PmW(L)3w-o2*tNLYq;|{W(T#=|2f6z%dI< z10xa}*nRs7PVDTt^;Z`CQ^$b6EEU?7?7<8ir6{tmpw@2G<{E134OVhAhFd1&dE2gQ z;J!4EL8v)IO=Q|*mN3em4Inhh{*%MD?71;S6~NC+_eqK~&DdBG=t7|gyfhh2OgJF9 z>i=(s-lHjKov}PrcRb-Ran0<-s*@*qyR8R4;ngq8T19#b^6ds$iu0(E!DE}1WjZEk zZ4XY^fx<(xcEhTW;&9pQl||A16DsK^<1g{V00V26Taw46Vc~`!MSG{3;?`Qj{>E0^ zB-v!Wyf0IomkJGoEL9*+(r^I{Ge>-5%_|M7b7r&bxghf^GLAZ5Xcd`e<_#`2mQNH_ zwaV9av0U(bK_55e4|09M~1WQ!J2k7@AM+Y ztr#+Y1zjuayeblPrAuv;gYFPfZWg=&4D~sRzG>x4;I>=gQPhj)HQ9)h#!(%*VY5-4P2oQi@*XyB%52AA5y%RWR%w=dI|YmF72F4 zGC39H^5#3qW89hZ#B%^aKG^egzYS#74dw)N1zX^y%EU0FYwg@l%fN3R?Bvm8d+vv_ z^aN%^{P}4+<~RdR07Ws*qrReen@2LHgILSN4hQFpS1td#7>dQiohP63wevL+?{nsZ zs**Oy$j_yq!kMah*CmB+rcjz4T%y3T{LJaB)O?@yS9d%)H@ZJATuQcdZ$_bY&*177!z>GlLD7)gqQm60uBya z29&-f=ubdp>LyFj4fSt)TK-+Ft>*~7ln_LZc-^XGS7E!J2k82J#u-@@@CI0}4+0;z zWfHTz08>6lAZVEJ!TVsUfQfkk#Cl~M*Mko|g!piTN~hZC{#9TRAPvyyJ-OB14GBeS zO9jtym~5BJtARC|t7j^;z5W^gcVcd2|KbW4o%71igr@Inw~UotVES^Zx#W=g{D`$uh*#`aW|> z89m@mNpT?_aB!m$Q$6scD z{?lpOvwYxZ>UEyv7-~63z#3Ku_yWu_T=_mNc#x02BV9HrleS^YHSHs}GcQ~Zb5)#s z5LkRyf#moE2lD#$C~pcaPwT3r-;us!;#AA*&;hi>z4L-fVg_$ZO<%rVrFm~~|8l2D z{T|%BG_RUocAUNJYHe3&5~$)y1ehhb;koi2X?b;P+ym(@IH z|5okoloIaX%h<(2ij^Gjh_dfDjz#gdc+0Rm2^!y|)nRa^xt3{rXae+^telt$rC>InC?O5pSxIlk9X+`(J3&bfoL zx7TAUntCa{fwMKAv1j6k2R}jlEHynKAVn3(tS6nvGC;Z#A%I`cEsvm&D|grC4emPr zy6|lMTLj2b{WE~*+;UgvRMBg6WQ+0VZgJ}j5UdxG-%BxF%)h_(; zbl2&vE$bnqYQnrNox2F6v8_)y9E2OWe>xY)B-f*Iq*B2!O?_Eu_&(E|TGOAsK-q8} zW8j_INcR@;itST(y9BKq=@FMcm}7E6s`Rt9i7Qm#!-pS$#U#tcE#k37?t#wK*@`7= zrV@{G(TuZK`fA&62Cwf;DdYUK4JTV;>c@~>Xl)7#T-7=aT_I$_Y0ngfK*6d5F zXpp)Eq`N`ncfF}q$S`0#7`XpEfrjod0Va<=H{HYJgdG|K=_B3%8ms&!PF6BG{|;t$ z6ZU0npGoL;G|1jBS!jLKKR%+rHtW)P~AFfl|5DcO?GSf27XIlq=f z0qFJru1E|3i94gi<4`{egJg!I-TZYnar3fLfy3nKf%U+10baLwP8hV!1p7e4J=!#0Dexmf1qQpN#(|iRdNuMVk0S4lLnDK^VDmcwO z;CX*szK9$lS&aEGAD!z(RaUIKES?)=SGlmM-@ic5{kp(^Lqfrz(WMVLr%-&w>d+MB zddQQDXBvrG)~O#E`u>vLVmZXvQz3BFCr$9N1V(CQ8(m0^4J&!_5%uzEUPn|%!Q@+o_b~GZ#A+u@k~%J=T}jJR+%S#x*S<}< zXQ=(%%jB*9EQ{x(^uoeUMrr)@z7oC>WdWp4k4f+xhgFI*hbD0*xq7hQk>e(+_x z29PTJ4-IdqVK9XGLSFGmJR0eD3XV;y?2`5=Q`(Ea^->atmR)(^FXs3^yZ8U`%fQ2;@rv~ zPCg`U$s*0`ply}Gn|jyoI+gb71CZ0Ls`Sf>zXdiUq(*mMCP`^ExY`$d%QNuU zG?e(uZN_r-kLYouy(m?TFOFtm^KFTw>9qo;q3bYl&FO>;NrtNu!@xRXf8}O(^$n`V z*|A<|M;e~C=Mozb*qX{02$XXLj(CJCDX^}Fq?YFugys2*w0}>1Mkehjosnq#-IU%HRZMj%DpZy60RwO4 z#ptCTFURRnWR>MQq&$GgXG?hn>}TiyHV@sYd@F&`cDUu-60>79#CV{Ev*4>vQ6#qi zwKwDc)AA}OEJ}6iuzc3 z4!?juW*&Rp-ap}#JRon*kNF&jBtg}T5*MND!%TAuMP3E*hc)tG2bfF)^HkmP1YYAX97kQ;*W#2zDjM)+AkRpiXLMVV}7dgC#njm>jOgU%m z8?E^pJh3$!mZvmOT!F4xB{%LGOo1GTD*ob>m-~?AZQQ%Z()3aOE1{3m>uP)TrHd3} zryq;BW##QA#T4y&InzlI$&l3$4v8(+|N9?S;uZMl6)s)TH zUhE$BNSqz6T}AAk6GbStz1Ds5#&6YOXVSyZW}wCK>U(uiA6*t@Rb-PP_0kWEvXUa_ zZqs#$Mteumj0CP&pg)aNw3XGTB(!JSnV&?LheVv#B3pbWURTkBZq!bpx zr&IwoIkU9`%`fIWHWLW&h+qWY3s(VF3BfZ6-ldD-X<)#{FVAg4n?ERDb8yG!CW*cx zYu3=eHN7J*sk%shGU$Yq6wEfzB#*M2u``6=RT1lE6HwhQE%AfGmI82~7F==U>jlYF zeEaR$-=RG8PS0Y@sP|*Xk_8uJQnWnpp(4dsV~W@_j)v{y(Y6v|ydL<~DnE{~=z5LW zfPo2RCS$NR?j51T^XV-1%FJ`cFq*N)f-9#Y^m$BqkUUYeXEyl=w6{x7VyLW7G*+*c ztB)8#14`?2LFlL^>pq>;Gv9Tluj7tyUuJ2*M|XWN`hm{ULN-az<`+>JsRi#-#|8DN zyh^W@5(IOT8(&XxrtQ{tG4)?G|Ag(B!$Z-lCfLDSp`mUXU~u=&YPlt#-Fr}RJCFa( zG=VX6ylv{s|J$?QzCZ8jBY z7Pyrj$Dh70emdNeszV_yWSy@ekXZWPEC59*h)L&jg>Zo%4o};)pe>vw^Kgy*)P)a3 zA(UxzK~-(IV!O9Or%byRk_RJBZ;zXsf##Lq6OE)jk&U{*r#PXw7I||gvw&VM_G%nmcl9t?Mmn`#I$R<;{CP=s>P(;QtEY0JvmPyxX z{Upct&`?0-^P*=|qZ0Vb4LVFV8G4=PgXf|bka`-uYyJgPC#V!-b z7(rF_Mjt`fDaaK%LT&EwTYnm-(@R`xTt!ohuM=NXuuhi^3U9gaLQ1BL{`P7d&d@8L zEA@Wi7Di~eE%68s{d6`5=D^^@8+94R5n;0D^>=Y>)SU{-$*HhB zJMRULyier6Xukyc;|1nhMn0Z`+n+kmuORt?c3T#suJK#*TDcQ$pD2PUN0mCoaAvRUQf2cDVy}uVb{Vk;XgWD4EA(q0Gb~vNn znrTP6V=XGjmfQ4^{R%r}S)_gZ#cc7fbz~~e8PG~i@4{)9M}DFZyRfRBu6C^AQ(qX; zleL?EG;$%qBkG@}&6E7j$AX_Jv@=)Qum3E!zPxr8vs^Ca)LJdS-7~iK!iNxxcU-_^ z4{B4aCdhn|NY40a%w(>LVTd|yM$QZW>G)O@b+3e01Aqd*pdBZ-FE?UT=Fw9hlsb`U z<2M0$3RXWfSjYDztJ3~0+y7U&sg0{`qBjwXjTbBPwst$U$oWk4k>)LyouEjIrzLcq z;>ig=LdgtDBoyegBqLT?R)>{IPhWpIef^2%qPyCUkPAarZcU1B=LuvV2Bs4u$1j3YJ zdUw_r{E^06m0qW-)VGa>CCLy+GpDVRK39L@U&Up9bR23`Ns4{w38_g@8)~F>k`SSk z8&q)Yc%@A|-m@Ci^NqT*^o~$VI@MQg1F*{#39dNzk9fz3Z^tjz&2;FYp;$5o7k7Le{ zXzdOQe=DXJ+^LW2bN141>XN{eugi5z1@%uX_+uu1x!KtSHE_1Huc8=Soow{G>i2mO zPOlb5toY|k)&*f(64UeRn<*5Q`muD{GK*WiB~sZ(@n8B|P2PNWzL`g(pu@S91$|R5 z#*`5I(12QpHqdwPhGJWp{`A>m3*9att*Opz)qjBSO$Cm2?r=tN*7W#wRLF2vM7Pii z>do((=wKKRMyAO5Iqi~x&b8KWj;Wr{`PCHJ2LfDIpi%IMDD%_^9u2iG6=fWW!_R(S zU%fvg=bT&T#`&8CzMU*bpeUiETF!Fp;Edk(;%Hx*2w(K)hefZbvcUR_nNjl%oa2k% zvI8BzXRZ8C&+)&9cVqnggsWX@cM`Jg^rh#;18PCd@EL>cMe6axA1~(16CybU1Sgrl zLNGC@_9MA=r^7edsQIV$A=`uAMcZ+NWvB=SDq#Q7vx<$tu9#1LT=RD24*k7xwcncV zHxR7B-J_cl&WQ^LF-9x25CU`ZbpD zHe8k|6YApVn}buI<`#m98PA&H2|WV63BR;x_>6w*2}(1=UrDB4c>0LmoCkBI^EvL7 z$jI+8Z~=e6w37bVo@JO`X>0dlxF7yy*BpP+*UfdS;R{s3$4*K8Yuo!5GT#^8y8yq< z!S`Sgt+;4}lua%Ro|W>2RPhU5-!Tt`$1~t7+DnYQPhK{kx{bLjnOt>Fk?n5 z$#Y$GC57anxr+ix zOBt{{ZoARn1cgRw!8N0gcrs)R$6UL+?cFyFRdy0qD^Fz|m_=|A-S~5;kb=mbE_TWv-HRWtS%*4BHN|0*r@W`PlmWDu- zUy(57Y;{JWqFa>(8R$mp!i^3dTsXE{uJ*QF!uUpRx+N!#c2`)wv>9-f`To-=klzM+ zo9nye0!1afLbD+z3w@J$to4kGoagZFQD2}w)UCuq%3rkX`0)Hz&r9y)yH{N+f|ZzM zraNTN#g;0AyZ@gC`abPJ&RO1Sk#Q-XzJ^qBx7;fY znrJ(hzQ*k2Lj;#FFId!8h}CJ*7=t2b6dhHee?^EksRfq7y%3zdWH0xL8XL9137`zj93%FOY+MrajA{g zzYEV-n2HDZOR2xuGnU;3ok*2%@BukE;k>w9BfBB7RBgNl(`xo>bNJFJ!t*6VP&1&cD9L; zbuo=Lr9MJm?9cJC*z8LAH-qLgTvc-9S4X3}VOpZ5kpeuNg4kr}i# zAG#=`TV&^N>_-(Dq+w@2sKy8|iWbh>a|AD=+O?wgM=DAd&ca_To`DH)G{zD_{LPg| zKhCJjTz+fJn$_-IvW!wFBmbw5|1Je|;&pwB{pz0 z-+(&qwOw`dhmR<*dd5&KK3@SY58ewrePi&a&xwzxyLo&Vs(k&YCb?@{6X>DA?AKX^ zUA%f>?!wTF##WPSj~db8cij||w}mUN*hG4pa=Oj&6zI`E)VvyHslV2b$+La*CTTQ&JK|!3>L1gT-0v@XBUwfg9uE(h2+DBqNXCG3H!b#^3cKiC zcRSaQ9F2jApW!VauTar;Hf0>~g`1iz@|Q@(+T<&tn(0T4ENq{nZKx)26y+jRo_!~U zp$G4Tr(O$s|7!8hB0^Tr9`g6=&bb;MVVkj!}_oeRjiD|?P_?4lHQAF3rG$NzcsTbTNC%G-`^>;Ek=HFqiP}$$$ z95e4L^q@3t$ zV>3q;vCiKScSNNNniJ&&N!Jj!6pAM_uwzSGe7(Vj`P!L616b)-y3PZya^5xeHvgV^ z)m+Y_oa;&zd8#wUhKL+|8$8hE8rA0^{?p{wL_1|5W4Vap#=Ycv-qLMg|2VWH+ET@E z=xX%6KMuckVVHa1CljvaLlV^Ehr1d^e%MhK{n^Iow`B4m!GiUm(k;!x!}W;}L*vgJ z><#L`=W~oz+`lr=bG@Ut_e#T%@@T^s9s7NdD6^2;zRUya)B(4l#jkSN!!56v7h+Ym zJ!0FS35Ubw37@mw;Y)t87pEVh8?A$Wl)wri@P5>l%@T%GolsLH*t59eDSk^1WV2um zj|QA!pin>dO#*1&3`7McQ)dM`_G(UCLnkkG5A`U03Vt>5QeZ!x;agta$drM%&Ow1E zqisjqgZ7jLtvbo!1^Y>k<~w1FxqmCXHn&1>B1IS0Ssom6tFfw=3_yndAG+Q%tf{u^ z)>cutEr5s$gr=gP^pZ#kMMOa9N^c1oN+2L55=sJyh$tPE7CJ~%dan_rgf2Z4=}jSY z2!#4A?&sP2+j}3rzvb}9%3AZ9bIfy$iyHg~vYWa*=v%n=j9V|14!u?y=2t4CeR80y zF1Dk7wFke>?_0a+yVv~@J;xZy1}~Wb|4`=DhISD(F$+sqXJ>F8^z#xfBFHlsB++?z z*MO4W(_(w6k$KIPVAl0HGA}=>9QeQN7H)Q)pQx+~dx z7z21$zzloidN}RQ*n8r>3;wmbGP*_b1t0Sbu4oBm!KGUf3kv-BL;H9hR0WF;JEXqg zRZ7MSzMdGr!8aK$7G^z`wwx41SHKSk(bk1~gliby4neNV`aof{D1zm#)qYKhpD9_N zfO&2fr$l*Iw`)K`tS(jeEI%6>5z-WGb**GrGBh!S#Bku1poPuk2@hsv_A=P8+qIBV z6Nl&W!yNsM(tVwfxJ!pwAC}Fm%8!^%y}U5cq&s7j4hy90^*Y}V^?20P)tn|hM*4rW zxs$5<-S@$IlX3W0dAE(eEZNwH*^H@lAh&Mzp?kKl-Q^G|ZZ+$9C0Q+W9`beUh(JLc zM<+7HrY?D9xUwy@rhEK#e0fcWddb?Iv(C~cej%JI z(4ACGwys*8*2>g%svc!bh@LOY<1Tdahr1FXxwS%Xux>4~5AuFtaQxsoF0J-F`R!^e zNQz+X7}{CRAQI3-MPK?kKNm>;&|Z9SwuEPid`CxHqgnT!#gI(#p9WM(+tBB2+b#kCSczAI$H&ka zo}uWa?B|(n$eUt4i-4;Y-OL}Z7TO@ zWfASlUVVFWEwdBnKAn!RRgSH~0TH_`1CWu4IqT7)Tz1G4+jwzyAnUw& zqp~?~-wXQt{;1n;fxhH~oyC?rn{PmKZ@f_BEkTfd=LF&iq`CZ34Q@xUpKE6mK3i6U z$^AARK-Ysmx4Q-s9=;}bS8<1J~$mS-dE9p2{oJ)&$8a2!i;@iTLIyx|_F8zrRfirrvt-u1&vvb(S57 zBXp1u3vm@-TxF~u52l)6#DI?O9D!$jNx}c;eN9S`K9_qLS4Y|fv~f_pOGJCLqh~!`HHqqT<5$&7+n1Ub zUOa%Z?tUDZn61j6GA;6M_R=-gF#z8n<+GAy0DENY-dEZ)lDs`yIlzbwZ?Qf?>VYvP zuM3F zJwAS+>&>lkW$n-|ghDs#-n`=vsMkshsMyQtz|7jR;m(0r0unF#CZOqeyKCYTuppu& z&_2{T5>G^nSu$9dyXw)a#HjM!@tKERM2HN6f>AS@ypzr^lfVsF(SWK(tuh<*S2rLp|7Uuz+dV zy%hGlpz2{hv7`>=kVeq&iy&DYO`n+y-Ge8FSLGaFsfG^Q%K)kK zz53_Dc^9FgSyoo#KIsBI2j+!-_nD!0TZh;>-R_Gn2r~3rN++S#s=6o@1D5MZpX(RL zdtcCx8}{?<{8?rcG2R~ht7!c4WPkDp&8P6Rt?%|{&-Z&N87{2BAh&Qr6NE7h%q3qk zM9e|xg$CGkpQYRAif)g+-#JbMWVaN`$m1ddFk}bJ}YXX`1iOjN-s|_jEzN-=>Z-4VLt)zTkgqzE9 zb$q#(#Eyu6iLiz3TZJ_X@v8;bDiti#xVO|h_%@$@YI@rJJLQ|ZI$00QJJQHt=Y0u! z>B7=E%nYGeQ_bZlZRq)tv3ccfYN##189>g`?D=0Xf2Ir-LDd~p1dtIa7-hdcQ5=~L zIwZF^d|NM-HsrZnpB~Vb3VO{|eOw`V81uvn^r>w zuf20M38deLv<@cv<^T77@88L7viwTL&a{RWv@Af=iz~gCv!E(k_U+Te7f*81`|5_y zY0inp#D}`Zi(%oLqA~BxSFrA7e{ zRb(U^D8m@XP$g}nRSWtT^dr91sxHQ5&5l^vjSytHWTk`xu3t>N- z0@e=R>9;Ov^VX!aYT5J{rYd6CCO!rKTH|h#oDyGwo7#Pt7q4y%J#Ex|W5PLK^t#H- z@7`yXeH9G)4?XnL;2ahYzaset^}N&QA@?qdCfSL~UZUSGTmg5VK5_~i@3WsEoWoF* z0E}ZOb~tYHqBkg9P1#SvY2vxUAg~uC0rx80|CVZuh8PHumY=~tnipqA4J4NRy_dM| zdpxOCg|oOBmU8flKS1eM@9~&~=k9_+zX)SKv=e@8jeR{QafY)`TuRhiMX9SlAgU{x z6ikEAvQBHPTs+8q1-j0S6vwnQ+4e`*yaL=8)Ek*av;u<@^(>oel`R*;>YHqNqf1xg zRg8a(ckJY^_+Nm3XA$Ktyh_f_1iy5oCFtl*KV;W<%r7AnF$QDKsXqd(OCS5<@?rbz z)$2vx)p^8>8yt_=1}{P)YyS+ojx}Fu&ImVQ z-!p=jx5b*v?qU#a(*odTy1CoS?CVBQ|M8WS^kNc}*#1fAqHufBku_nyDYbn)H z*5}KqfZ~@43IQ&mcBNlVchG(=KiK6J^1*eqwM|KVW{I}?curyO`_W$h@#?XM+aJe$ zYg4!J;A$&Q6tQxZ(p*z>Z&&*INTIwQ%4@7|4c{Sk8{@dZXKUZ(bGZHeczg9|ul#rq zKId}l)w4y>xOFe{4WBLBl^(NZ*w1QCmpiy*@*KIlgzV4%u~hw%-nPL8R|3) zxd-np7#4y=2h4BZ!3!Cq9W`ATAhd&oly@ZxMsU!yX`uH(`+d%vFy^7((B3>_bJX8d zsE3nBK3|==%IvkH_HM{9R%Rjkf|bl3Vw4+RY^Pu*6*eWWp8{`+x|@PP(*ZA?zhce+ zCxfiXWcI<-vjx;2a`3!kwd+d6(c!h%)W2% zgom{4o#CLc&3+}Ze;~1b#ofRhQT*ll8YjF(OUyA>{9}QHfLZr0?j0~gL((!+>jmAf z=kbl0mle2qqeDLTu=X>J716vIBY)&&N)ch_+-qpPpOoGPL8&PFRaX3_5#7>uk=5;oMx%C_V{KieoZQkU+@FlV_}b;Nzk9$uz?e}z;KqA(<<03Mub})Ag@x9XrW=Q(8~Tk>57it0%D z<>fPjuWx3B9ZLQn5h&@kLHJd_7X3K0`VK#R_4GcU1 zH5Wh)8LMc`R*O7INeFAbIS{gU4~! zPo9&3cwrm6e#@6SpGJJW467VRzDa=Nh85R$#!baO>Kk4)$zw8Ya3xmhhpfh_CGLBS zz5H7(Q3M{fJ?C#^?^cY6cE&gGcj_(1d6Yeeh0gy{o9tA>v>r$hgH-_Ss?a(HxJfgh zaI<;KNWia7woH4I@H&6<>7dT-%i8vIkjnw{x<-B%STd>WxQL4bkpWSmz`Nav3xi>3 zv0qDk8c@fY7|Z=hKas|Fm%{wEUlh=i;~()X28arBK-qm^#YW-s1lF425UQSr zrSp{6rnIJg>o3XYj4uvUm`|&S4JcF}i#N%&4m2Be3+9^C>g}a`a(&k$jm(SP(hRfTlCWhBX_tnKTZ~B9XE5dN8 z@TAr_94oC;1nsP_w5g`QV~!$pvY}C_usa<0CVs)UB>+T>PO#%J{QxRo)q~DtEo<8F zO|k%GWU2^X>Uw<~d9~rAbQ` z5=n0Q%tXI{Hk6-nzWW0iN(Sddxf*ELZ9f)1&^4SJq2HGkihV)YJi4KBCFECmzj{t# zZP~Rhja_`~xsab8?n+P?y41!f$odcLp$}dpS_&{e-|d?m*DeT`jHg!-OJ;<$+pVB% zy9<|_uA8)3e*uYp0Tr9~+!%1J#f)W8hl6e)+Q2vT`ocoKfjZe7oH$qGxNT2aH?J%n z8X^*o^CYn!2V3mduF1W9$g85T7gZz4G+Kb^M@9d2<9;64xbrf8J}9V^!!K>#Rrmr3 zUW~SDIv%pG=m^#vo>^0nfbU~-FXpaFs}^kHX>nQF3rjcY=ZmSHfvd9R$vR^)l{jyC z`0T@;XV1Lp=Z`509X>QKtmn?ZXoj`##~)(E*a%vs?7VXS6?m{a#`zuRykE*a^jRi zXGWmX1hv_zgPvz?Uj0($6}$e>>In~)!)91U^<%`3yS4KniBs!C;wtAVfdQ6x>O~F< zSbmU+d1M{m!)&`X$+aNJNwHpvLPc>-HZL*iiqo$ge&oHD>w8v2xddz+r3!jXccrwp zEM0sQYI>DH<%^y0`iM5vjDB|rSJ{B^zAz~D(yrOp zzg$9F6WL;W+lGx5`u5w#BL++xNL;aRwqZ_~d(jACcG1OKZ8ME};R}MWKqf>xS|$7f zIgMA#`QlBny7|}KQ%ZKG5V-|dHK1c$cc*trdHe%)4xSt|f1a>ko4urbvn@bi`Qv8Q*lH;4r!R`>J<0*M1 z5qtD;La}2S;eRMBS7GtWjEVi3V<+S!kW!JinO1P=(hD=88Xf!z1EF^5uq0YJX7f7w z&jT))Ua(RKGv*97Ur|`k(As3tnNjl-W3)^La2-fk0A!^=4$u-l>>h3JbPx;sVs0+9 z5rQDIKpigLe~#n96s(>Fs&Y*647)i={4_-~`NMEe{6w?ccS-one)IT&orQpF>=B&EqBaDY{G&z4C5^*)cAae8yF}h7a{7U zp3;x)h3MZNC(~A15`s_O_wQn-*)bzkVs}dXF$Rwe0!iMQpR%LI+T;pTjjvDS|8etc zE`6yPbPHyRibt4&f?qi@6RXDm()b-;Is?!p^-Af4WI&{ynqnB$rwO3MS|`%27aw*J zaTNm#-uwxiUZ-d~D><(u?RjeZk(;A73H%^S7WB<(0A)2xoY!!XHh=BT0cX|40)A~X zDOdVUmzme#qWpUK}tk^ zvwR6%scXr2&5vA21bF-vHZB2BFuLD)(3-erInah2phOL}eC0$wV`8wdM+%T~*sjr! zm`PN!{O1HMG46joY&qKV-8X7%C+~2M=bK_yY-2(DBln57{lR8%R%e@&Ut{=WzC)M} z-s^Hm`E}=QD!VHs)5lR`_1@nqc>wd>8mWuo{R@`fMv;62`qPS49W~jp+GNWSPFhF# zp6I?7u{RoA=XG4UmtI>)%QAKGyX&2 z9%&|l#?o4r!`aL%dRY2lKJ;{bePHTg{AA&ZJ^zF&geLjt3RimWx^ZC zt^@hyIz4~_Pqohmi`Y$jsbb$A{kB1tY+HJ4x3Inue;z+t7*JH05J)?==qpSa%T}-= z?o-UNNH9lHSHUMhGiQER=W2L`c3$8z?Q^`&g64KOIe7Gv;S zEu;RTDS?vvA-B}p5PV+-TtOy71o{JM(_j+ApB%CsM+M-^qnAA!WMKP4`PX-><`Ru6 z^91m24g~#0992oTB_`mf;z9b2_{!`IUA@?SsS;ZS`_E;n_^($p-CZ!b1X;Nq{RSblYQ- zuX+7LQXpsl@8$w|(rMuxA}C&r!b=I38Oi3DHUIEPs* zT*Y!2y4Mwsuo;Q+Y=Chu>7+CtRDA@cT!A2odBz!d!yF?M{*t$#CB`43vj)dq4B+Ve z^m+WRqcUNtT6u$vI939B|Cy7ljf++1_`ZomRP)CNN|n~bg-1^J?Ych>2<2dE#H3Qo+0EOi&KQ{gEJy!Drc8WOqfpF#d{jrKs}TCH=G_a-v5h1A^(=s z5)iX}H=SsVw$O0!`Z4zm7~T>1?3BPzTWWYS=T>4(7OTMGj59_`ky)VhPZ;iG6@fKA z!J?#(>$HH*@bXE+-t1i2&H`(GveKf3u>Nw8QndBM&mT!#z6UZGH5u(r?`La-f7mZEB%JqWy3@qJ06h|51!LfUbh=WCihYX++iG)?H-L zrJhhyaAF`WPY3x@XMsUaa_3W`G3&sy5!fi6zf#*i_d@me^5erU+Xn(jZbVwXcx22s z`|XVahd*yCqVosmI)Q6`z;=$Gd99#e(`!(7Qr2!;(IcoE*qyWUEaqB=jU+fO>&d2X zWE-UKi*fcqyRooi1wO03s*-W?RKEa_y!lO_7k6^@hwM8kG%p|S5^~W_hZ8T734djO zl2j*Wn~V>3SAff%vy>BMjemw!>MiQ!9ldFwM35dk2=d&?kakSRro1&f(<#-zhPec_ zea$;r9oEp)hPpiBi+hZINjKg7Ydiei!e#);gjj-m?1wX#zeYF>wc+cIU(g+%S#@4t zTK2kG4U|8bDc9wSyAx^A3IG1H-mZMwI)HBS<1=?*wUqCnj=p0{`7ajG(K` zEnAm^q>XOrT@5zN#(7gPM__slYux?AXQ~-DpTN(;2 z$Nlmf{Cq81N}#9ZPy%d5k8N3%r z8zAnG+3XDeDm8vNs|AbCr9-296J^T%wmfpgxF0I&^7LD`6RO2ivSf! zAoRGkXf}1}t@02i<3%%GKqJ}po2Xh}m zLlYWr>NGVm!MWI-&!R35dsx!rM(nPMb8FeyB>=)EQS3>qz_R-qe=mHBpf@MJ4rtJG4P9PQmW#)OFPjvr$Z3Znah#h?f-@f4Gun9ol znjbh19A8SGoVzpNIhJddXUXvk8Xvy-2#v|;1IGnAl2hbUd<8Pc)E1U{{?vQv7lu7+ zu0Le9uMPc6csgfIs}M_SnpmbQEQsq(xcg8ow2O}uu=3*=<359#nWW!vF?*jh{}tfQ zcONgiYx-Y2ceh<|NpQ)$09`~I>e#Y!L~8j*YX5_3ZEQww80P(xT@MumqagyG#fEEm zO~_$Rdvt-duJEL}QAABD=g~PZh7>a+Uo{Ip<=N?!78hXk-7L%|s7TbL<$G{CI$Pk> z18OnNy&bR8-$;me?)_-Sm-_KsgWi`Z@h=vWiH|^a_kOj(h%N?N8}*~E!HW=&+C`c! z?dN@YLg5|3Egnt61XDgSE=F0}{{x%~hby<3vuSr%W~}gKJNC^7OpyNo za$?&y;DHvjZifIKLUg5A@WPQOT)=i9HiV#iSe~0emN~T6vxookRm`&O+VW z_asm5VdHW6N=i?3$QH^}Anuoloj8U{K5TLS(^QKS=pH@2B4(9_Ku*=J-rVZ_E4Y|_ z_GOLK%)Kos0qxiWqxO^IfI07#gO`egksfOMQIg#e>074UL)ZD;v%LLlcMHgaVtxu|)F{ z$sIh5%R^L-{@6N&7T^Zs&gGd<{3o}as;0oaiA!F~~vVdd$=YUo5^ zhBFj4mqDbVri>DmZe%Ew;1~%mTBS&Q{~AK9FZ_9h#hgaWx$C7v;?TnHkmVuR=rdG? z?KFPwp0PiFoa&agGIsINKCyvmqOOR>(V|E;#8Ir$#_Jr(wx zg*aui!PV_`DyGaQEJv(_IH9z+aq0UfoxZ<5?b?&4y^rml4AAjN&IpwC-$2MH<&jF&#J_7}sPxiWp8vMUWW`Nt|_j-{xT`4@ zBz3rHannPMW+_L0OvWPwK_ta>`2;!^tny=V+(Zl2^&W1j)Ar21A86Db#=rJjq71ki zRKRKJEW|H}b0JD@H`r@RP)@Xo;3c;Sgk(DcyyN{7-Vw2!6QQq57?QAlu05?zsoHxF z$uQI|bZs+$4OmzrFD$!v{?10e>rCk&C&M%EIZZ9;?ObVoi*a?R$WM*kd4g)}(2A-< z@?$6<;)53jwL>OUi~Lf&okd&k&==?P;`Gn->AQ-rPoNZKvYGplIao0O?HwuG(OfP~ zAFv!B59^W?8H&(5EyKCIB8nNaoEggJ2r3qXXU+jk3P)3l=3 zp^@h*+hmG65uGKg63({@rOB>}P-{@R0kI`1ty3#fB6C~%? zvKwprF1o5&`Odx(Hh|Ni^9sa$MD85M-z!Jy{opD<0~Am{aB^RRk2l;JX{xwsRs2%j zPr|rX#ehE7zWj5pKs}252x_gN%D6ApZYOOFp5EzlMRG%rh}M=!mh8qsMwPk4c2PGgy~b@cE^u``aUD&CDJCqT>6U zIzh{Jv-P;_QcgBe7YNzT0rj}u;!S_Nvjr1!@&SO`lRD6MKp@7JJ8fv>v z47KCEC-|=%ebJ|mH?A(A4&#~UR}WHpa~13Ie%yiiO(}ULj8+o;uWOk($u~ro&s6-f z3=rYZ(47MnU;`aHw5~h7V?rT!U#t6@E6?l}>CP2JUh51jEt3?$AplKoPk2zR3!a@_ zprjcuaqP3U>a*l-pG4+^^V)FBCCm1ibHnLssb>9+_0t!NT*ZunC{B<<9_*uqCJ^VG zOU`MEtSRxI@E>d9o{7De;u=f<_)NI(3^W*G%9r-!KA#;fN4^bjs>66+(X>a1!{X!a%H z*;b`4+BpDf;_1NDvS2naOO6WDqajDhk5r6BD9L}!PN+B-n z$+o4-x;|4@-?@^S>PrP|0YG=opnk+IC<9k#(Y7E0jw5{9guLgvKhYf-;C_MH;m3>T zO`5#(Qx{ZDTO<9sHcEnFT;>-LOBp`#28L$Y?z7m@*>H6JC2Fh<~eLj4ehs4DcEQ27LMKvrSOFxB=iy0bc21y zFNm~w`c9Z0!#x4eYI-kvTS}_fV?e9pGUF^UqxB%%pqY%u_(sm~gYBga2NIgsS_G>4J=CLJ)OM3aUqG?0~AQY?V3W zr?$b2)A6IwWWNeol3~x?0Tdyu8C{LH23F^jlNic5hb^tp+RSfJaxexq9QPG|$4+!F zy`XwB(Yiy1;vW@o1*;-Upqtsk2XY2q$Z6fqUG5D1Gb0us*Hi{>y<%1-vFdB;-oCjJ zi4t9ee9{~qw8oKw{^^eU+Qh)x24+=O{-hkBF;PXi$*IxT{}k{~?+ohEye{6)s4d5f z{!p>zyXrIaK{_>?Nx~-gONkl(LC%-UzfT|}GBD>pG_qtQx<7;~0-UTqa1KDyG(3eNM#e}wR?w^G0*bw69 zXA8V8ju2%LLPgA{!m)KLY=oCT9gSm(K6I>2 zK>l*gT|dQ=d2h8-a(5h|8khK{-n}N_3fx`sKKUHxf$j^#3d&6F6T+XLfY)Ym#J2LM z$0wM`+M0M=2#CJTZuz-gYQzw+roL-rsJuwYMb@bkj5S>?iBO-P`pRo9xl>W`1YGCl zz{MUN+qx4riSWFL7gRdo5EhJP{GeqLIac`R^m3_(5CPpAeHwo1;mJIiQdnveQhq@2 zTM_`%+CO4l@}lpu3=$aBZ-5c#^Q0#{mh%L%alM~cCHyyoZaGuM?zBeVLO|E@^Jhs4)NH*(9YbRo z(Q)pUO{MK|1`gJ+e;)8SpDc3&zHPj%A$8wHQsi;+UnZKSAd^a^=Y+L~odE^Ej>K8! zD5kJk^u9jq&SWpu#q8+8f4C26mUiKBH-pU%F21-bM_{k}N_&PfuW4wp0sCKB0GJ9% z;>sKMR21BT8wKp%0j~<}w0j)T89CAa+Rj?ndB2g;Yn!(=*74{ZSGUT{HlgkGd}VWU z+9~_1?vDvC?JKPdif2whkO}ks*s@xN4-UrzQFC?0a@8{c4icq8NmAj+udmPwgIHVt zV1UREK0iix7U1lOSRxn9uy3$mGvEBqmgJnCVofaVj_Z?8flj9+>fX!uH5#123zB4I z40Ql$(|G)-d0*+J?Hs)K_P(2OrC~9(@qV7&bvTM~^&Ypa1&!fQ$lX-IBZyDjB@H$1 zGH1ErsBy&3;r-FS+VLFuE+<`xw-VBh-!jTc=OX|9B+h;6cTAL{Z7L1Iz2`nxm7lvc za8ofty8jeZnEOper5zPdJN?+pgP!Y4`xUw+fIV4PhHCMc-Id>ym~I(-t)i$qg*|%M zijF1P_K~olS@BOKNWV)nlhZJG_u;*+*kF!f>T~SoAm|ZEzUJ=H+g0gmh5sTTS0)s( z$DejGUN#)Yl>NN+6_*ywV7lYo1#!2i5tc<|eu-EzU1*wJ6E$RXcU94|2F)f~y=OXU zEm7~pi~S0@QQbTp`~}4l4(dX&FzPrdLLW8&FgHRaoB7|5VGLPi^Q`)*^(&B1*uql5 z=Z+bQabJAzwTBK&j{B&ctg?Qeej_1m2u7kEiFxPwOG8Nz&pv12Twa6NB@iFqHn~d0 zL)mZ7ZtPj0ja;U5Ie18nRD0bxUu?YH-F8(vTW)3Hd&Pa{va!*>EM2}w)J+8yA2!UM zP5zmx$3U+?tLINw7NFbxZ&ZXXeVp}ZvMa&DzE2)wabP7fbC>SKQL2shR+|~7mTuv{ z;fT+d3pq0*Tr;Hq8z!PJA4dzn+bNdD*4N)fvb`|~=E}dfE=1NWK?mhGcMMS*(kZro z@`!=W3ueP^0Q`9|^G>EM{-;4|GY~bBdMJ>I3CAV_3h9Lh`$~*ARP$dZCaCPtyD}0m zxCyoI(GQGzULQ;?$|Q5Ls97Gdg~)Yl?zVApido{8HAZ`X7qX<0oQ0nvv@(>z)_^64 zh{^**vH1`fg61t40Zq=V(&LnVG1hq6XH<^#h`E9{H7i`3=izMpiH+fT%9KX+6o_5 z)J#9}+L=&(HL3U!mGhBiC2h4m^SbS~zi4xloM!?63NU4~Dw9sfgMaQ=yJPv72WW|v zc0lZmiQ=LenIKSx7%;~UC#G|Nji6|aQcqT~WgX>z#Z9_DJl3o2wo-~G!|!l5W?t$2 zg@EO2o${fDTAy3D<`7yKqSokA!X11-A?y@|;-DdOBRW<4$I7dlh^>-`uxe{yg(m)NQ%;&(7Qfax@02OMhN$igss zM`X6BDOh9%aOg=gaNH1)n?6w&vSmwZ(ob{$`)7`g46va}7DbSRlQaH(zP)wJx15_R zlS?@IIv{gr@Q++45!Y^Zmu~XP>O>&Gfe001XGTQGots|79lAX%RX6sPej0lN?Fk67 zNd~)g1{27ltTvy))F(oC&urN91@nF5A?8g^>?4OU(ok&KH52U<0)*Z=%e&&ye-IET z-v3CHA^wxygU`02X=mGQ2YH0IPKAp7rtw6n03Bm@*8e6zN=TFKS4;O3Nb+yLPE~At zwN5GqHSW)=;#pR5L1|H_grdjgKFw`!jf!D}LX6I=e67I^de_mvZn0d>NCLq)Ve@+j zt=dr=dgs#BRT$Y0xH;<(hb~AYWr7vuyGTm- z_aYoEP~o;yF2c66UrxWkP-UC)UI02i&P*2Ox36_werQIEd0nU`SP2js8r9Z&0MxF4 zXfFSy->mc!cwLh2EcWs36opQPetRlkpKKfaW zmw8&g7bki=%ywV8v*@#PAxsJsWKaF!w+v$bwu|tWZvI9)jTph}H+0F28 zVK_1;KSz&lrfkSY-vZ@E4rA)Ut874Vq}QJDNOlFWj+U(4kXv)rpMmKi%_O)(KeAsA zYgBXSZ_(Z6>=e~h2$0*(xAJYTg}gROnm2WieLi$;w|T!QPceszrdD~eXwKk8`YVhNjnn8N%tUGh_Xe5OI|6t@<+FN}CziS(Ey}|l0_|Nxaaex`!(HK^ z>dJ1MwuB&~-Av|=zZ^GmcBJpiM^}C%usjdUL2Su%rN=(Oa**sg6$ciTp@Sa>hN8NP zYKI;=ew`N|v=D)lP%3tr$@MsKXjWlQF01^2Qh^$UW;{Nn-rt2q8~p3QjD=i&+@ z;~v2vI2`*i2nIFDtIZN=FO-V~E5#?-59?%6(oSF?6EiXO57V1$zXjmfY!K$~)&Q5}|JnJ+hYwzrhPL@0-G$ny zQW6FZUJ*h8p?FGRLK;AX83vPo+!+jaodwvws8wpI_Il1N*tY&MlYVL$MZ ztp3q%yeOUtPJgK zFN3fR>ch^PEFoUao^>p6OxyVe6PqM7;3fqDIKn*udn~eube*QpI>9|EyfR15z>A68 zQ%i{2a;8W`;!)~|?y%Mgqj2zryB3@@JQ0u)H*bo-~O5s3ehQouA zw&5CYq6Kq?uZ4s#AWSe6e5ARuA5(5DxwWjne7VUXU|g@$%Y9iDG+-x9K$p0F$1RPN zpPk+XGSh;0wt<;np{Ma_bM0jBKO2X3BqKht;}hil(f^3N13X{6pZq!WJ?*b2NS|N^ zZL=_P?S^^5x^7O_gj#=vk_!NYNZG%9ov>&s0u>yoq$WM+7g%Z3l+cs;atH1%S)+kGazhV zSXx3`ii2_*O!VSPg9Zg5v+%E^)iAE(2_Nzs1Yh8{I<|%O{Pr@lENtFd(QcL8%&Kqc zhem57=MQZ`W#a}H-P#xDY=?ftWVGt}NeGSiGiW^Njwpv<2Sh=6GykwciqePw5B|fL z=`bY0k~R)`UQQ2oH-*cPdB3wXjOK}4@u!ydF`&Br`O0fkE^CQTUxSRZ@3{px8+0ry zQIbeEeO9xvf2}ePCVPX5J?`2tAgNDWm73B4)k>9KSLqsHHn<6tarH+BXLIGtdTph4 z1wbDn=ev`p{J#A<1-0so$-q#Ybu5%by?lXK@0*wgmgX5RX$&6@NI0W$XXC5nfp((i z5AMS|Vi$oR819Z8F$|D_ODk*x5<+^@RJXO?s{F+!{~V3|WnTQHulCDa8lH(RfX6wT zQE1F$Z>h>^E%o3#v#E)sx# zX%b~>|HH63qr0TU4MzJb;%QwhOu~~NKlSRa1k@0s#HcWb@42s%?zJCz4|xFx;Wn$D zVp{%Y7o20DTs%FIe|5w-%0T32<6v*HX7B5}19hJ@{N6IZYK{(J;J{TtAqj%ClrKPP zYknGUJ6rytS+QUyN&eAi+o;IZ+VWd0!RMDEco!wm_fM~=a*$;51O{Er)Cs)bclMQe z{uKSivQ6-NurV#@jZ30~qGR|s-nMZbG^(YCI_oDs&VB)8le88Y05DE~PXRjbq|Xij z$0zR%sqH-c^GJdLQp4Gx1xl`L@{jhjUxSBGqd0*?qmyvU9ltJ8FA(*DB+eBNOZUHL zEK>KG<@MZcbJZo>bQJVgEk4>@JlJIn4kzd0`FT+uSkk=9{VXzXQ5zriW@O+hULJ@x&7 z)ADtH!RfYxc4ryi!{l_5{(8{ zfIu!1j|exTU9VRFsr1wuCOoJZ0D4wDzr5e}9DKI?SbUvPwlU<|ub>I(s$}eTW%FL( z@@MeJq&;o&>wkkdvWTcVF0Iz7K*)pinr#0iXdayljAgvbMiKG8&9$~zQM127>b|ty z?Ea6qN_*nIXPPR>;+$Z>);HVfcPq~4Uvl#LT&*Xc70Grk`{^9BuTh*ckBOq?`7w^P z!CR*L0+0y5I_T`c z!v&7GJRk2zb-p@c%|6HwM)@B)%`WY8w=Qh-KVeKUS@eyQkERW1b7z&+_;Jvw^@Qd- zbz|@OT1UXGL9^0VfIcL@;Bgxam>Q)pJs^(4z8Y%|+}V2i_o^-#_w8o&R*W`X$t$_O zhyZCDti&X$;_*yOdlHdlqvvosk0#$EP=xU16&cLsBErp|(A;D)ETU~I8{JmAI&^M- zTha+>4}dagE7-=(YG|p(^BlefgKez2>GF>+@{7o9h*1sD-6K{;~fFujedH< zZSGiE%6UU2dV0SEubis~@gmpCQjSV-k7p{*5`aj%ZvkF-7Q0)*XHIQg053>0bIzrt z7t_cG(~>3uddGaK{9U4l@gt93ZtCMmc0g)<*l?0*w;y`xr<989W#Tz_=xXO7woCbS zXUxn}Rq9RV+WrXxF zZE*|T)^&LPnav*%W;UD|JsUNg3{oSO)D{{~ev+wzS5Z)@A%tE;nhFRAB25ShJ@iP2AR-_Tnn-U7NRi%q4TRo%?*XKD zLi0O3&#d{@yyN`JVl951`<#96eYGub|6W@J?4^}wxZCSTiIg=ef7RHnujXY*+agppN~0KR0}xr!?`t6u|Tu zFN%>fJ#G6znm{lCJUC?dx#_t?+3g?yjXmlCH|!vU)5^5=Jm2TsUGlsd>J%U)FI&g_ z6k09Hn(zYce?t=xs7>ZeU0inMi~|D3bQ0ajxJPBzuZXarrVn3bUfQ#%b}oexsY`FR z)5?YKoHK~$2Eo-~ixoFVcgK*8d1w78u|`XdHz%r;9z}&W=(=Vm>jap&QQK5RRnZE_%B1x|1|;k`b!|GDlO^?H(=#_^6g_TKtK|D^ zgFS=nrNaP|R4QMsB8Lph^xLNjZi-QRK@ z&uA}ORtciX@Y~ZbgI10jxX!OkC#?lxiP+ZKd+hJE6M8^VU#iulI)MxG1KIKk-`TlJ z&s9jVHaj__kK~Ic<<&@b_tNnN=%6V*6?yx+HI#j2P6lea)TBKa{gNu5g$2GC``*h+ zX0B{po6QPPnxXd7tJ3W^f2uaq9K1gt7rK7d51j{R>dqfmxr7crATB*Z`fTO$s_OJ% zS4N#@!kK>AzNb_#i+6h!eNCjmwuBkoY5x73NXm(9<}-0O>D~r6#y14&OqsC*>|WXa z+nUx4I;^>-W{JuAPIQlFHE&0*(6^@OA0MJGMQkyCikF=@)9J~Mej968br8&Pv8CIy z%>*5dnxzGB8o-}6Y6rNI4NW;{bUrC~3T>24SK+iU)mN62@#n-|bi4AhA%l+CNY$OS z2tJou6L`kE^_pW-VX`5YoU%T`-cXGL;UM;JgkHh5ac3I>1y+f|lk9|jD*R!R^<0nBnlY}|9m9b2sY6L-skq!^YVwM%YaE@vd(Nlu;3#qX;ZRtd zcuHT|aJ}Md6lp;x-?Z7mm;gIdAyP~tRa1?pcc3jE5SitvAd}lVJxHYiWGpc+D}I7m z`Dn0+@<(Dtn_Xe(Pt>}Dug_OfeqDU$xO*tdo%vGdOx}Pl?H$E6#kM~MjoPTCSUb7D z!C{Xtl>i$1JWtUJJ5tO0!&zOab@!cQ(0jGRjJuXw(`|{8(Uc)%lgr`%tD}rw{%DKGE`d-NOfRlOqPtl_)sBqG}wlws&``LCB{wb9AZ z4=NhXrAw^P{P3qrmIC$myN_bSMPB|jik^n5lsJq1vKg8!>I-Ny+-?r0PJbmOq}o^F ztJ1FO8ex-yIMsCQZE;fJASL5D=4C-C8a-BAUsBhezj zO5AVUC-yX{TsQ47xv8;n&!}?hc(S-UVS3FG0)d1~ooQfEGJ}crln|HMh6%YYQtlR@ zbdBRqKpR@kR@0-F*8~-7fo^3h%(eO8hHFzD^Zee;3T;=VktZMX!SqW^8C$X|~?gFHcz0xor zpS-4lbg^KM*X*V~>_n->wclPF%e0VZ1F&7;Ar32h*5Yv4wSe1O;e1ghlRC@%+TE^r z3Pvo)-q~lNF@<*-DVk4ri!+r;FL3vL7q7?;VD%9&40CCw)=SI8?!1I4%D`MN)ORmq zT&D(K8gX6++3Eh(X(@7*S`TQ|r-&EBj|yWlwv}Jrak{i{G3Q**t8ndgRB^}g3lf`T z;0zd((XWNw*;VE!df&D=ZTh@Qy;iEmcPvOc1qhGa;s}v#Ul!v@cWiZ@qO3!$D&2Fo z_k@t*w7|ZAQUR!5TFYVdiWZ%uZa>VmfBz8b0{tST$J6dO32e`ds?^K6o#Ku61~3BjJ=#wH2d{{3Gm;GM9ye&&?;vF7SY1?D-43nku8#WzTdysE%mSip|rFGfotCvel*120^IX3>>w&P)trpjNx#PL5~vTF zY*Xe|%)k6lJK8BLsAUs6#L)$$Z)!tFLM+lzVoy=bsJ=b0gHy(Wh9z76% z%!)Wzwz?~J1aSZCB2V=Y?|`if>oV0o$0h9%j_(ogX0&_8$L2~7<1;-fvhDs{h-kHA zL`_b+1Wja}(!W36{DjS)ivbo)$B)Dq&=K#EimU zQnjit{`wKHW}j#GXvu`y_}HXr7mynLR<$?pkKEhdiy}2f_WuStetFtAiy!S;QI80* zLXwK#D7$dSM%kK7wjJB*XyRlUB5}u-dn4X31JM5>GB+s>Ny}?=W z;f#ujzdhg3f076*#Z9)UQbj$ow|{%M+7Abk;aNT{cryQ4n6by#QPzwPqhur67iZpQ z;yT}wA1b@trW|!rnma^vYKx|&Z+7tQWF|FtjsV(T)Fu#_J2^>{pJcL(1}uUIE`ta_ zqai;buQfS3Ck_balmOg)=`7b>lX^?6S6b)t!+9nXM0LaI2l8yQdlUuX=T^L}fZ;lS z$C3>`rsfgTOZH84Fj->NwkFVC6Vc>=by%k4?%Iq=ER7i{4GKB+)O5ZACDB)W;DfW@ zbw=INh85Y4Lrcedo6l6aAyYPSOh5+2XGTCzhdW!0)+Y`J9x&}KiA!p~@{s?RwzJ-d zIEQ&_A*5nf*~cK|Z)3h$qyMzx+6H9z(-{lio1Ro;yIsxFDY`ss`VQ7=Xhpt}1=zJq zbtzr+ROp8q19MCUEfAFoefF+;j0VG8e+(@$3nt44{`ScI&wK1`>o&^dF=UB&%yu7u zd}(%<;->xLmTJKiV@*;HH@mQ5K|!S#qnBzm;KO$lI6`Wro6Rp9Nt z%Jn*0N6=nd)TGJuQnf_f1ij0+O;6E$RYL+xb!pQLmp%gAp==7d2qfAq#gA^Z+EdCpc_lUcn1 zqt%P`4bfjpKzT2uuENd5jaDUtc;vI+TTqgBehqn+1U2%dE6ZMN&WybJl&(tY^$jga zd9G2#Z@@g`=UwB!S72mI30#mxNv^LvRSc??kx977!BvB6F92MN%%x|xI#6h%snBA> zVHDN&m2uc%#Lgo7RCIY+v;cagvGwdsyCoHIRL&^j33+_|nP3g{187b^Fq(>2M)9wJ z*1_$oda-d5_qN@4{%lBkG0WcIh9bzLxBx6w7YAd_j27X^$Hem z2gjLtv^iS)R9@n`(~$!w*RqgPyB4C+9zUz^8&6yNf;G>-N-FHkQzOpaBKr(m61{4kY>bHPP;I1(D zzVFogFdSTr`fWy6*xB^p7)C18x<`yl64WtS0l3}iDwf0CQdu%8e~mQ#2=DF`3rGmt zV>qtYOzVG<&av77?Kq*BYG-vc{m`h~(|%0#t+r)~jnwn_J9bPMphhvy0aIRnvn z>%2bW8xiUC>sIu?3wKNxevLGCI^&Oxet9ITl4q(dS6_3v$x?sJz3=Y!9?JOV*kDk? zFb&673z4(gsG;AtKo$H|QbB+1Gk51}sxUGe=k4)V4rvUGU}nZD1#Lori(5&9bwRxda%N1hLGz08nrA zkhW{iy2t`hIjW`yBA<{Gm6!Q0PNBJ?;xbU1UO-5!CfvuRvOYWc+CdISr&g-6r>i?f z1#RKFz(mYu;#xTCaLk?Ruu~D3vsloDiLM!?3U)dCJ6K_09T{a9kUVf_)+0Tj?|0$b z-sb8)TD|v!BllqvH(Zpj5dq`&zT0`!z>mFuF%j?IKJtJZ@tuoz(VS)seslbcHus7* zL_bpyz+h#sh4*FpDD6%|h5Itkfm(DMLrrdMYY&dnD`g49CPDbguZJU zo$z{Lp7fR2U}>U|(+q^E{6IWS%*{HC{`<&mJ zX&p_^44rRvSe8ZhVWFG7fl{PjMi!)mi?V=(z7w^bZ;Trm^+Q1M_V(usbZc}8C3FK` z3qauV0a#{nsF5%lbH^U=(HD~SLfY9F0nZ@8)mUF#v0T{cB@DI>bB&YLMU z0zLM!`eCAMwp(P)+km}Kcw<4(4@Q8EzC*69eJ->pzPx)@2vaFoO#>D|`ZInSjE;lf zU)zZ$GLnQ~e{UBJ!8=jWYek%I&mk4m3kCB19a!3^_SsAQ|?`R+lIKmYk%gc%FPJ^m>@-^Iq9EC5`!I zs#jveQFI8WUmnDm{mt(JeV4bsGdjG;wvo(y4FnAU`-Ji@Ln2@emsZDTcqv0t7y&-i z1~m=H9PE#;Rj85FFwPB|ibB<2CjdGO|1fX6`0$HU8c>BG4X8+(hafhm3kI0Mxahi` zh}{03k}FUXI8g;F1%j4ulGKFzaE}&?c~y_oT|TyCNb$&dwqpn6flqMXrrf#t^gfLP zW!;JmU=?q8Q|mBF`>A8*@$NG<%KK#{wl_6R%3MHFca2J+5N z<_WAFR=?FZKIOU*c}-S=8qncFzctYnLcc|E7pnJUDilWp9bRKvVNmNQQsW~*?<^(0 zN~5-Qw(!+~(tMr4GD__wi)GI6pLJ1Dq*<$cZNYas=ddKOXYdZYRy3PFv zux@L*rYU^h)eLL3v6c&4+q7d~*{qfQD$m&WhVoX5_tSqCgS6`B_E~QNzLi;zljcViK0N9cbDC5 z79b!c3|SujJ|&L>p_lS*Jw{xlAMTwdI*8R&GVRU@B6I0R^0N<~%ZcPuO6u1)*4zcu z$=h#p>Yu1S3+wtP;VrRG9W!OX1rjl#|T@o7v4GfsMDZVc4NzT4QN8`V_N z7I9n~;)^mHDLU{N2r2>sK$QkV~2J)v~ZiYxp)sz&G2b($&*Eq1-W{L6?0SjU?M9bh|$ zJbP!WTLF-q5`=0C#}~hP?@&Py?zDe*mKRa5<*0t}x6dI#X?hT-O&>y1RnC-dWYHLq zkckCbBDKnC?wnk%=xawa(D_k%X60;s2ibqZ!55{NgH5AdOUIjRV_0tq5m+Q_F5Z}5y%vmk2ejS7V zv9-Fh1(+pr(l=!~kgEnzDbcUcqGcs9<2O%TIBSC68Kb~&4ri!Ci&Al}y|P4V|5h#K=( zjSOzzjreE%rA+Wc<}50fSs-3`N4Qtob%Ey->+;EYR-948kF8kLIk^GMsN}<8e24T= z`6`}{Y4Yg61J-~~tc2&ERLMv0=K-d@!LvOe`T4pF)tVsig#gLWb=CA_hBwjQg%+PP z0BL0|mX$}E6dl`Jt8~+0E z>i+`pl|~v;9h1G$Kz8Kbx|_B(4wF4H;$dV)28%MmEU${?ICd_PKN7ys#8;{X1V^^P z+9+iCocDyWur}eL)f|sY4*+ zqBMjOWtGYmW49aJ7Fa>XH-FZTjJE?#{Hp?j#z7!{WRQa+S#!4n7zsyGQ?2J|w;Vosp z=4t!6S#*Gxy65P|y8Oma>n>BUyv6munJg0|?}>|zH5OBRI6GRIO8OJ(c@xmYlc``z zliwt~EYlJUmXH7$^~G3l?v)xJC7#E#gnLt|F#~4%wYk~{-L+QTf*t;=2t8!_(xOJr zdvPSE%G^%6$+*7Ah7WzU?hHHqo%5YPqJynWWX#dW+5rE(GB~|{<~1e$)y>oXl6}{z z$aZpj;mLD*%OE6xDBY>f9{|%?TxpWoNrVukqdx*!-uWrTMIV5e5cXq-eWe9#+0de|Fr#Pzj@ zuj)#NuwOBu`#hut(18f;+%X{Qv%V`^^bm03s~Nha8;bCc{8rffYH7MH_6?=Ze7>?x8wG$zV@W)G|WVWN;AKq9f7N}|JIJ&=pT_{Z^{uw(iXO*{o z(6+k%+vtL)PZ4CyX)$QC4T5Q)$ccoAY}U$qawX{8U+5%d+`8lORwLDVGw z^JgQ%qu(FO^@oLGd{h@I3=(&p>7mpv-?C=!0L=9P)lwF`0jA0xZ37(!eU(Qecwuk6 z8VA0RAAis0Sz%K?rd_hU|MIaS9cb}-dyoJ1!?B%Uv!7CV{Of}1-czt42wBOtZGZ^9 z|L=?3h3i`1)NL=}Dg`kQ)`fqHdE>ZGHbwPy?{zqvcJh!C`LGKMDku5OxC!+LEr+_% z_RS2Q^&QEPw@-_b0B#d!ixc#Nz|@F9kL$eGO#GKM_nR7CyuqWyMQu`zIvLcH43fv^dItxH(n zsM<8pk()*3s=TVK0u%iSEyg?(MW=o1m^P}wXnO3AziEcffNW>vBveSE1Y6R<>LMXxg|33bJT$ahYV9 zKd;VZbzH6q(yXbx%UdaW9qHsmSHp&e4>A%meh%lblC!#PScx-0T!l$wixSMEL()s{ zc+RGfnQqA!65-lBam-7XBtHB8Zn&T6=*RPATPM9N)UQxBk&^r!y}oQVNmLz3)a|xI z4}&$+EhA9}{u;rB6rNrK3I3sr7;0~+F%7A?#(H6Wdb|uq3MAym)2{F=4#DkNM>p## z7gO+kesp@Z5xkn1uh!;c>kGnLbC>5pQa>%wK+TWo)~ez~Jo6I1L@*d7 zK3EqV02xjD=;@};L2x6*5&h%u2X8io5pfJ=^s;X&z>i7&JP_ai$Io;Xuk~7El)3P+ zWg+Zd93S2-Fxu8biZJK(98r>vCJskxOI+`B=={9A_hBwiJb4*0YE8cq z(fnvAB@)@|thgSlLA!ovh>sWj?M%nbc^mO8S|b3CmBhTl7|wh68~RFnU>+NWP3Cd4U^@1d&1*0eMa+PqnY`f6Iy{2h#Xs|s zLQM^P4q2#vpwsqI&oHXi+UpC;8=|IBT}hADx}sj@0Gb}rY=98#Bd~eQ_+8Qp|J9Oy zy-9OCFzRkzg6~YNDtmZAQy4^-hpMp$>_x+qC_gdO)(Y1%so9IL2@Mk|W5KA1$ZuW{ z8hWDp)rQsFY23R8sTT0}*Zdu6c9mc#x!7y6qn1zRue3>g>WAkiKi@y@?%LsTO&h0# z%{P!anSZ6kHq|u+M0Uy-nEp9>Wb1ohj^{X%kICCK@HJBGDh@S6x*kb`%fU?u_J5B} zz`u|2VY6vkv1}I^AX(?F2`fTW3f)uin-ahOtxE>ewdjlZXiT-@1cs6^IqYiZd5g4D zA&-0^3#(aEWLw9XMWzWdYC+MdDH5fJ%1+`Z2+ukzQ7)Dz3a)1Et0(u97Riceb>Bpa z)4VuxYm1Yns1W{7!_#wN1rP4Pl#gHZ!-J^Vw*BV#oLR z#~=+(X6>tD*9+MC==v&5%9?tfeKl`dFfX7)6D%ck~(Ffg@yX(T?cMB2C zjg@3QiS+y+Yd2ILLqe z<>R6h;A2zUH89UK-mJ*>LRA)it)(^iBtqYoE;Q4WsdxXn)5j?ny}~-mjy^ivVCc+( z3Rt_KqX_|WnB4I&3tV^GNAkE)Xs_<)=v6(5+b;qRr#({hMn|KW70+ud3kWZpLQrLH z*zQT|M{As*|*F zz=m;V66esgqF27_O>ZbNMKHV()KQD=x(aoj^jJQi;hoF;j_R%3bY5UcW^~k)HJ8CF zEqx*DJYBLY-k0rv+oo&GH)!U6Q;LXx@Ad3eeJMwQI@Sy1b>DhTT@A4mwx z_%Scjaa4SwG5c{B9L!tE*2WAX$Sc`QR`{H&G{d-=f5h^ zbQO>FoPU7@P1%N`cG3n%>O5{*vX@~jFW1V}y!=`prT%fPBr!^lF?{h1YIiK-?B!WN@b_F>=PaArai# zbqdB!kQ~Cs?;HP+&t@gZ&lobaDz8xx_DWGsNfa-jQ{Ps+At&3;zC4`_Uo>m-$L&a3 z**e}+<~9lElu6c+8GMQ`;zPb@OCPb0sB?XT`5CC99x+W~o8{y=$rY~pa;Q$oo6^&G zb~H+SQ`!b%G(P0)x+de3g>8d_6RZ+;@^d<*QgK~y16QrC%xgg9x)bl!B!ekTk^!q!a@6b)TNaBhK#7Il@ zI&NTv!zhykUVg${MneNKW1Lo>WMTqY;dZQ%D zE1?i!2e@75#gwim9NEZe$$1TjOebCKp~p6)+&b5wFy0mUHWpu%vMJ}T6^oU@>2*9`>;>S7qtP=Qd5nS`n=F6{AkfL^ScI zpF#W6fx3lu*rtsDu)9U^$!N`qZ&cfb3mjfAr6tucdnq4AX|^GIh5A@Y;m94QMDULU z6d1=nRM6-L@w`q{BMV$3aX51vS@(_A2 zBkZK@KxGlZY24L~#1@t7K_4(3&tyIxs}AfrfV_&CHWa@)?a-`!x+)QBB9PS-|6!n< zOe$*t=x*HrIB+~f=ui#Gt!pLeS+I(L2DJt(cfXN}h zIkRp*>sCLo`s~{>#>v|i%;+k`($rQaMOX&~?2*yVMBTN_af}Kz-YUTV!u<7M#*pXP zkhzUMS_V@;ib)M54pFB-Tk0n0y{$~N=J1F3)a8eIpR&?IDL6R1S0G@Y2#`^SRG|9t zK>dbo%K#!)hk4$|iIzC5QGx(*rv;hugM+3p51tc~Az8Qm?8M2aNy_LjIr^3hT(Kk! z7mE2n4$V=(Klz9xL@<3%?GgHH^#UjFi2(J&vuzyK#B=l78D8i&+l69VtOY3M7$o?V zP#|q3?+Q76^K8}x$jT9wsGY^mjE*Z@)Jl}xpndvXP)=2e`>@kW-Zta-494uC*Z7{( zs0Qfu*SDnC6x8k?mwD5wH(`c%p5+^`nK);M$lep;MyoR=%$FxcE z{h+UR9HFp^O$~&(RBENDua*gjZH-{30!KTTHszKs5hK z@!vm@V*}tMM#ew<-X7zxvT9y1(5GKkTrLD|b0+;Gd@((xT<>ay#`YXs0c0M0pkWXs z%Jg|gYCFDg-X9#pcYZE}U_GA*n>0ycWOU6v4DnGz)E^B7DPLj!`<7?Wyq!*oZcwfVv<8YRlifhQV0J{=1 zI|wfmZtA9C9#x8zCI8Qf`rpY7 zO8OcIid18#pQt{L?PUNbz!P!%r%HF%j>lmLFKxA&D!7 za%#w%CUa`f>+8+r-=?SgRt>=^AJp5GFBXikOOzlU%PuWCofjR@`jV0|oo;YJ_oH{A zqLHM*w%Tl7K?3f4%}-5Gqa6g5fYSVe*XyYyF{1dQ0Dg08%N*aBC1kt!DMw!v?mi61`XLwh6P8k!U&Ax4< zua=Vs8>V>D>&GJQjxJtwWQt*qIM;NgB=1#aDewi9l2iO2^Rgc4dGro{|L~JGE^4xZ zU_nK(+DP0qmRTtH8CKDVV*UV)HHsJJSr80>T;1h$ z%7KDtFg`LeVwj1gWcz`A()yP1of+d75>&cl&TEROt+MU1eYSF~|A{F5*IyeU9x-~c zZl__9g&ihSPOT{)#<-B~qi+*M>br+MPdD|g6L^F=B(eWMN1&RtB{GRYrFZhd{CpI0 zSNoinNyGvI-*1C~63HU#&_9h5>xv=yMON8;BR`}Ig5SJEkxWq*4b-U$5Mj^J^t?qy zGc)Y)n$>)9svm8r>(h;Zk{xSk>;U!WsHoC_hfv))e$2#L$K6z3&3`<*A%7nuUN}R# z5)q2>jsSVDl!*<7>ruI;f!2P_VF>qlJtZ@hSggc&@t?Ct;*V#f7Rq=Eneo`7^rj&u zxdlk)Hl2}%SS#hC(T+a3+{28s@#j-bCRyuswxVPu@#CSLKMSv64K{Mn`wcMLZZMRS z7p$w&_vV33keJO~1*j$Qdv7XPqLtHu7$mmgcWBeE_x}sl0}f%+kjHw* zzaU7?r?peR!aZ%gx$%i-GXUz5zi8?bPvKehS!KqyFg&HlQhyP>_fs8snw5@`)yHfS z6x?&)r@_eWTF7ubQ5^T7o>{DhBN! zF>X|+-v}?kxVCFGJ>_##qu;*WacGV+IA~C5icth#XxytP6o4#jPr+*kA9ha4Ilw+pAi%pTQJP9m+niy%jE?5M{`BQoxpZ?Z&UPr>` z7eBrTt8cJ^Hun`omu!nf=Ba0H5gB)agtL)_{~{n^hL>=69t6JFM?y->yi1VmfsacD zp7r&r3E5;{Pnx)CPI0*~R$VMsQQ{aHoEWRmN(O*R`b}DGV*AvZpTV}&`uhXj7ZSE7 zQ`O2820HawpZxN$&HSRldfyKzy2_y&>Cc)%&I{nrnn z40;aZtv)+$A%Dpbk4X3p2O92Urg9=}%sNb#8C=N>r_d9Q(ut|)b7u1T;e4}i9trUl z@tHbR&WH+X+X@8;jaZU-ELbtVCau}p7!BKdq0r!?U~POltU-$*m;LgbDfnxWj$-s) zh5m3**L#7<(@1a%fmFs7xZG2j=9&Nl2=T6n_aQXGYq@i5TD*`^&Pk$faiw-Mf4=&npEK24;OVceI@7b({P-2g@dT>=u zk#%ubI&fOFJIK7ZeifgY_nlBN1%>AMM)x$Kh>2exfwS%l*3tKa%~H>z$kn%u-RUhq>V5+4&OM;uA8(!ME?Klqy|zfWtu zBQsU~!_lMDSOF?)JT6Pc0#X5ol_tT^Ld%C&&`=Zu@&%p({baJ_#9}f2*?N;+XkZ(SIb`s}! z1&pW0w}|LG{yv5T7f1btIFelFxN=}(A&h#u=jy0>qNU3@Km@%2ci#_sg^%}}YY9y~)ZPp-;7(ZmCiQL; zE7{1HxuVB`jj1Rzl%-39IW^xHH{tunx0f-az=(S4xToy_K9vVjxB8pFKjc~fq0LQ* ztnl^Ynddd%F5h{!ayaS}5S_}l<*)I`|34AybJS>(i9`Tsf{OFqBA%>Sg!(gDzVpq7 zJqHE2UBU{PFY1)Iz5xIs=03BPH#K_%reexph={I(%huB&uZY(d7RFb4B6p&- zA2xjC!#wt`-((P_L>}4=G9uegOBdQtWWll7O#nSb5~zV+!+`Lnbo zIbXT;vGA+K+ETZH?p;HkkUz*%(WL+ztSNe4cQF#=Knto5QaEwdXp5>-pFfS9Ar31s z;mSs0HF39C*qM`x%E^>ojnyo|4PN2zLB$+C?J4&)nE;HBr-@XmORXvAfgoM?zc@uH z0cc4(JmA;02C0(RBf}btLmCUi?uKQOr8RNS3bB0Rlju|ZvOJaGJ)rGw*=bh#YGR)! z{&nV{i*e_e0qXZ?yHXK_R@GlYRm4Yd=~m-Nv4urUXTQGnR2)AKMN3{@Q_9<9x)r~W zNgSkO#x!$L|1j5$+qz|Ov%8u(w(#V&Qwv;+bl#ZZslb)(y89i0Kk}45>gx(SnSSxtpuzzBuctVd4)qrsQ>n)9(ubPP5yy#f`k^WQ4?X;(3gRDPIU zwdt|NVOh7kC;GutM2t&JT%)5>x(#mr4eN~x-0Z47JXuGNsBS^DGF;N0q3pUEckO&a zo{aD!W-!=2*G$@5&`8ae!NelkEWK=>vC$!hC}3~VpNmx;AG0iEa7gSHCqOm?Ck@(K z$s#R`3|rmE|CHyazvqF1rLB4ov;9bea4G)(mzc)J*J2_+4Y>X6#a@)q{1jptr> zQ2qYMwwnU~=9N(>HAU)&)#VD%uV}EKyS~r{6-|OZ20V$HTs96w z$M;e!g@s&HM0~KXNZ&3%7}-J9u`}3|pVGZz4TGZ~Zmg4&(4SjEJFd_8<+e2ss*P&9 zK0-uqUBa>qGZ zr2l$Unv=x3>65*csPRX-_TruuHq+10%k6bBvz<{S1^hXPLm3&i7{|Kuk)h{>n6X#) zv0d*;ViChiBrM|do`V}>v#)oyBa22HFB=C(lvWU$Hrc6yMEOm5CXd9lVmie#5@I+H zrt5h@-rT>4X#%!3?D(#4l-NbZpUB@+vYV&5jR0Sq)Pae2Q*IN|NZF>#-XAu*2L)0vebrMChJV7p`DJho z6hAH>@R&`1>4rtsn#fOhvJKiAfoY=Z7=ENo4fi!z8)Pj^?lz2`Uh9oh03G-D%Yd`l zysk-#en-b?PWWt96;JU+U)<~?F*Og}KouJrT$e)aj2wtB-W6j8qkpdLWQajnXJ2a% zPr81nqZi$>ip}EgAvGF(U2_5=>`SX<{FS{CgIXWXVg>x1cev;kMr+_H4|OFi44v)C&zojP!7y0_0Hpw~3FA}Sj{7xyWFnH&P1-dRPX;i{ z)t&7Z8}b+qT-mG9uYv=6eCt|ZYf@8$3X_2TXU9MFl92gl`uTleajDR8c!5`bz>y_VQxEdJ=`C|r$TPrpPNE9Gzx;%vjHsB(UQp+e1Y!TtXnxpN{Fu{QFVia_gurKQv}gv{cE^!T8PH2-Yd|?m^tG zP`58eYm{nke`RYbjY%o=Vr^!ekz8Zz`vVTis!Y|&znj?ekrS1#3O008PX%>b;IfD7 zFHbm~KoZy=;M&=fVDH-Aw;6TJNsf^PVKy$Fm&}0g@;s zU+LEBJ#q(oMH?|3z|s&V-SI~{SH z9{kL^_knsDVw9=qudn#wS*uURE$>s&oQ`oB74RH7m6Oan>&P*|;U0;^HEjOs0nGJv z3plii6p0l+jknx?#Ptiy>|gdaDL+wRxT`kT=t3&%F7N$c{MY-V`-H#0)6eFGB04oP z5~9pVahgiw|JRm4B9t7w^#{8(1#D@(z z@P3Tb8SmMxH5-Zc)nu->+9ZxUkHAZ`f4;=F%Kdd9UaWg|)JPkFUeVvowV)rWZi#|RlGGlV2k<6PvaiFpSAs?0>G9Mxr_`Si zb{Or1lT0Tdb)g^D7LaHJOXbk=Bt^0}`(KvdZh{L_oq&<|Qq;m#3#S}ZL zBktJ-$?Hl;4-k38g6u6|mSC-sj%f_J(UP)5@_yQf$5U_GEvoJ?JgA$OJEX>A#w_a& ziu5ZC2Sp9jH$GZV6jBa%n+Oq$US+GzW$pxVNlyml#j|v%WCp2G&I!KTr$=0+2Jq64 z!i@@~R8vi{R~`*LXxGKg92vW4`30VnXe{l!OGi&=aj~yx8J_8p`Gbi+&{4z+k%(-+F#q&gU;HYG{&dh zKdl}c-l$rW&5H>qe}ccq{2AiY>iVUkQMh4OR14#h-TN&t6smvXO!txJ>_*T`Id>x4 z_SYy9oPTIgonYl=Td6J$QWSH1@yZrz@cGUsyGu^jq#(~Fx^T&*@|EpyOim5}g?7@p zQ=aJR)clTLW7MMRJlY#F`bW#r;gf08I#;(cl-c1wzBM}TzfoqX1BSfl<<0;ty}T~` zh@3@~G-(A_-z`ZSDg=71e^lOQlfC=kZs~2H?0~${ekUN13k!P@{vQnDesnMC$)q2^ zSejkI`Rr5&0Bt7$DE@4oOgs(2Ee#(-?mJz7(C+&973U~s-|^!mrDv!KpD10V1QpJs zNZq-VawN1klK;MUv!}#0bVyNP~*MpGIYd87r@b=+5}S^2;> ztiat{U-kGlcNbrx^IvCPy-Os_+0;b$nm-%tMhPAPtHq}Qy9#FvEM&~C%EA^kyMsaw zbINm$6u)^`wB!~~stKd6?mOS61#G(aqtQ3Bz76&4xW!I$ZH>2EAD9j?4y_hs)(9L{ zCiA#H9S@2RLduQ5B;DEG(Z@>9h?{FVkRx|WFqVy2=fG1C==ZQ8AVFz16*~}+YnPX( zlE6)0Ig7taxBBuOpJt2xWtjN`i7!uh@d^^yAwFrauFMk!5~2R0T7+0O{QBs0L*`!X zAZ|B;^|r&OdUXn@%GaJ%#S+&IAMk?*^$J06Mu=U>w4mem;wrj#V=j=nh49LGv!d(w zecmAt^|D6E*`~MyvkSIZ#^~7px60}}_^^`p#TkBN3;*VEu;Rg@`$UBsGibBUM;z-5 z7GC5kaO#35f^_Bn+`}w)KgL-ZSya2N^Flv#Zm13#S#Q+T{COi%XN9ns6ef$>i_v6E zxDMSmUO!oU?@fc3uG}nd8y})=-zi1vCO!tFAboP1;@)Nc4-8KpZ`A$R$pU8wqmcl0 zg)=*(O&Fv^t=9tZ{VBmG1J%Br)#pLf6Sfqaw$ITM3NgwKpwHw^>jj*2jm zP-yI10iqMuz>)E11kY>O+kr6J8PsgFu+SIp*I^uKxdU{@2BBCUg?erSw&Q}e~s zyA6l?S_G93{qBO3)q2oWNWe%%8KBhj-!6=^!ZZzd&3q%1(ssjjS&?mI_1Zr=u}>+T z%$2hpOj{;ND6upmcl0|{gY*`(+O_uLlS@V$+9aK|^P!!l2q$z0YMy^yao(9$tjUQ; zgYac5-u8+xyI0QypC7I0Oe%IcytKf(92}3o*YS#t9FPz5uh%p@#C4)Y0|l6buAzIL z5i3d;n!_rMb>XFJ>xDkFHYQuxTKPy9x<+47PwFo_`8X~qvDl*G&FzkZ7ZRUjG&B;A zuNWX>hDJD8vYIn1-y0pXOYMx%h5er6-Lrqt-1)}6lZ3hWQ9U%h%Y&$!PRy>N)YqV} zU`wNO?1tj)k?XhHv6*N*>;&B5QtQpUyQi~nzh5dNIrTm6)~&3lAndc8x-MGZhOvmx zA9o(b_I%P+Xzx2euR?K1E$r$;i_FSM1Md7dinfqw6TM;8m7~6%cN~qy70<~NH3qf; z?lH^)h!(<}HMbU5Z?TD#_hAC3%k`K+`pB^i_nGT}J(HO@JV><{Fnu^zK2$F<_XFt; zukjuwBf!NqbCbiAt7Z1QyQuPI_Ud7j{h@HX{;+`5zn)-UrjcEF- zbwW(&)0HFtaV{jyXrJ!d^sKrwE^G(t!O=}UyU2HxhoF`GS|z^8qK30%`sPkVJKyAX z60Bu2=4Hun!RUY^vDo@Mw?jRvL;xgMxz^99HHtvFraiN)iZ;A6-ld8xpcWn!o{=s| zs5Tpqsu%6H)gNwlT5c#nI(J0ANm?o$pEfCQkp?X#B(Gyc_Q!m&)UP1lUS8J0U%t{5 z=Ie@~J};`jvg)CD?D_NNc#>ybpyh%J+C90m@l3s zP5O7*aEA}}qz1Bk|GHbmAqSPH%bKK_=BRD}gXI@~`u=h{M%S+($lK7ytGr;L8Q6Je zBwQ4Uhl!(X;9fCbWi8}ESZ+_Y2G_e077Hl#3K^Gxmx;%R_b9xUO6{FPVfm_QFY9Cplv2@85FFhPsMp`RjDg3Wh!|+RC==Xs(9Qd zqmZ|AHId*tci|tvw7eDOltLUGR+ZOe#=y7k^F;_o*qjwp?FOm~ zA5{)r2rh4TYfa#R_Dvj6;PaWk6zhnD=MP%;XMdsA7CZ|Yb>r2#Xx$D}m@xfywPAQ| z4K3-8g_?CjhEDMP$;Br1mfqoR~5FPJJTo#wc4hC6#EL z$6TEi!pOht_7&9uOKQC_y!ob2I;pOU-j&?j03f_LZe!)hR*!2F*C|iqLn8Elb(_a8 zWFhJm>+=MHjE$h936H-GF6CtLbB5CeoMpPf{V8+Atze-a`_hh$(8GdsvCBe)DoK>j zAm4fN_76R)R2L*2ldoLl9n zTdyE=e|$Rl_T=&gY`Ih)n9znU#p!sR$^JvvCjJ1tSs1ps{Cads<63D8BA%Mw)H z|Hq3ecO#ncmh{fz=&Qf+xK+nkFN3>)R?e}fzN|;t)U#{5?sY)&l6N~ z*UWV?<8k#kcH(vXl0%mV{T;_@0hM|2uzx!djc|rTy{EVBulm8O(pB zeX%y^X5ob^B*n@w8bOzfUMrhsi4c5(jDyB6Ej9xPkx&j@h*(iEtk5kicC`x&-OfV% z((3!n^ajk_-Q!Q#J1sl$cpzi#4AelC7NvyRRwt%!hA_(kB>3Mpx%oCSoyA?GbU&n< zjw`a8Sg((W+MYGsMN&u?P^0x0IYx-s0fBGHoVy!V=hOjYfUBrkJ4j+SXf&(=0E^8B zwQ-G_Z2hZZB5b!j70mJqi)B{oub5XznF+F`qUV==OzOrk*=*dvXIbheLS4sx)(qY~ z{8O%?TGT}ZD|{%e14f}9&(P9qr|z}r?-!S)gIkHG?hUkEFAd5xh2782iuT$afuR-=Ip zP#iLx_?j`3PPYoFSxX7N7rw=f6;Lk;)TQnZ*|LA_X6kKU)}UU3AjPQNNziO6)WZ!l zQY49FoSETnc?Lw_)nxVQOQ-_R%N041kie zncz$LP6ukYgYC-FIXfXqE3}~+^w`e^I+Q2i)!)~O#0E1`uR+Jm&gMG#N;P1{h#0X& zEiVK5d+c8;Cn2f?8AT;){j|IK3*m}!0FOtxbJ&EnO z^+kepH!=Nv0ofz@pRdrv9T&K_1D^+e7_3&~+4cW^^Ic&QCO|%eeZkfbp25-E=S9_ukjd5514nQ@$ZwQ zGP%i@PL*l7WU!t2bgFHuf%~e9VN}o-2*?%b^;YYAj#ZKfvwwi92eZG*ym9NxS`$AB zj~_%00b?)BrflD96y;JTsN+^6n~zA_1~e@E4-8y!>&8$}jTv#`ynn5mP|k<7rfwCE zS)jI%kJlmD3ts^@5WT0Gr-Z r)T=Qf0Jz0EFs@Ph{%nK(); + const float cx = bounds.getCenterX(); + const float cy = bounds.getCenterY(); + const float r = std::min (bounds.getWidth(), bounds.getHeight()) * 0.4f; + + yup::Path path; + for (int i = 0; i <= 120; ++i) + { + const float angle = (float) i / 120.0f * yup::MathConstants::twoPi + phase; + const float radius = r * (0.5f + 0.5f * std::sin (angle * 3.0f + phase)); + const float px = cx + radius * std::cos (angle); + const float py = cy + radius * std::sin (angle); + if (i == 0) + path.startNewSubPath (px, py); + else + path.lineTo (px, py); + } + path.closeSubPath(); + + g.setFillColor (yup::Color (0xff4a90d9).withAlpha (0.6f)); + g.fillPath (path); + g.setStrokeColor (yup::Color (0xff80c0ff)); + g.setStrokeWidth (1.5f + strokePhase); + g.strokePath (path); + } + + void timerCallback() override + { + phase += 0.03f; + strokePhase = 0.5f + 0.5f * std::sin (phase * 0.7f); + repaint(); + } + +private: + float phase = 0.0f; + float strokePhase = 0.0f; +}; + +//============================================================================== + +class TextGradientWidget : public yup::Component + , public yup::Timer +{ +public: + TextGradientWidget() + { + setTitle ("Text Gradient"); + auto theme = yup::ApplicationTheme::getGlobalTheme(); + font = theme->getDefaultFont(); + startTimerHz (30); + } + + ~TextGradientWidget() override + { + stopTimer(); + } + + void paint (yup::Graphics& g) override + { + const auto bounds = getLocalBounds().to(); + g.setFillColor (yup::Color (0xff2d1b4e)); + g.fillAll(); + + const float t = phase; + g.setFillColor (yup::Color (0xff9b59b6).withAlpha (0.4f + 0.3f * std::sin (t))); + g.fillRect (bounds.reduced (8.0f)); + + g.setFillColor (yup::Colors::white); + g.fillFittedText ("TextGradient", font, bounds, yup::Justification::center); + } + + void timerCallback() override + { + phase += 0.05f; + repaint(); + } + +private: + float phase = 0.0f; + yup::Font font; +}; + +//============================================================================== + +class NestedWidgetGrid : public yup::Component +{ + class GridCell : public yup::Component + { + public: + explicit GridCell (yup::Color color, int index) + : cellColor (color) + { + setTitle ("Grid Cell " + yup::String (index)); + setOpaque (true); + } + + void paint (yup::Graphics& g) override + { + g.setFillColor (cellColor); + g.fillAll(); + } + + private: + yup::Color cellColor; + }; + +public: + NestedWidgetGrid() + { + setTitle ("Nested Widget Grid"); + for (int i = 0; i < 16; ++i) + { + const float hue = (float) i / 16.0f; + cells.push_back (std::make_unique (yup::Color::fromHSL (hue, 0.7f, 0.5f, 1.0f), i)); + addAndMakeVisible (cells.back().get()); + } + } + + void paint (yup::Graphics& g) override + { + g.setFillColor (yup::Color (0xff1c1c2e)); + g.fillAll(); + } + + void resized() override + { + const auto bounds = getLocalBounds().to(); + const int cols = 4, rows = 4; + const float cellW = bounds.getWidth() / (float) cols; + const float cellH = bounds.getHeight() / (float) rows; + + for (int i = 0; i < (int) cells.size(); ++i) + { + const int col = i % cols; + const int row = i / cols; + cells[i]->setBounds ({ col * cellW, row * cellH, cellW, cellH }); + } + } + +private: + std::vector> cells; +}; + +//============================================================================== + +class ProfilerDashboard : public yup::Component +{ +public: + ProfilerDashboard() + { + setTitle ("Profiler Dashboard"); + auto theme = yup::ApplicationTheme::getGlobalTheme(); + font = theme->getDefaultFont(); + } + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + void setSnapshot (const yup::PaintProfiler::Snapshot& newSnapshot, int selectedIndex) + { + snapshot = newSnapshot; + selectedRow = selectedIndex; + repaint(); + } +#endif + + int getSelectedRow() const { return selectedRow; } + + void paint (yup::Graphics& g) override + { + const auto bounds = getLocalBounds().to(); + if (bounds.isEmpty()) + return; + + g.setFillColor (yup::Color (0xff1a1a2e)); + g.fillAll(); + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + const float divX = bounds.getWidth() * 0.60f; + drawTable (g, bounds.withWidth (divX)); + drawRightPanel (g, bounds.withX (divX + 4.0f).withWidth (bounds.getWidth() - divX - 4.0f)); +#else + g.setFillColor (yup::Colors::lightgray); + g.fillFittedText ("Paint profiling not enabled (build with YUP_ENABLE_COMPONENT_PAINT_PROFILING=1)", + font, + bounds, + yup::Justification::center); +#endif + } + + void mouseDown (const yup::MouseEvent& event) override + { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + const float divX = getLocalBounds().to().getWidth() * 0.60f; + if (event.getPosition().getX() >= divX) + return; + + const float headerH = 24.0f; + const float rowH = 20.0f; + const int row = (int) ((event.getPosition().getY() - headerH) / rowH); + if (row >= 0 && row < (int) snapshot.components.size()) + selectedRow = row; + repaint(); +#endif + } + +private: +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + + static constexpr float kMaxColW = 62.0f; + static constexpr float kAvgColW = 62.0f; + static constexpr float kHeaderH = 24.0f; + static constexpr float kRowH = 20.0f; + + void drawTable (yup::Graphics& g, yup::Rectangle area) + { + if (area.isEmpty()) + return; + + const float histColW = area.getWidth() - kMaxColW - kAvgColW; + + auto header = area.removeFromTop (kHeaderH); + g.setFillColor (yup::Color (0xff252545)); + g.fillRect (header); + g.setFillColor (yup::Color (0xffaaaacc)); + + const float nameW = histColW * 0.42f; + + auto hdrCopy = header.reduced (2, 0); + g.fillFittedText ("Widget", font, hdrCopy.removeFromLeft (nameW), yup::Justification::centerLeft); + g.fillFittedText ("max", font, hdrCopy.removeFromLeft (kMaxColW), yup::Justification::centerLeft); + g.fillFittedText ("avg", font, hdrCopy.removeFromLeft (kAvgColW), yup::Justification::centerLeft); + g.fillFittedText ("history (green=self / blue=children)", font, hdrCopy, yup::Justification::centerLeft); + + for (int i = 0; i < (int) snapshot.components.size(); ++i) + { + if (area.isEmpty()) + break; + + const auto& entry = snapshot.components[i]; + auto row = area.removeFromTop (kRowH); + + const bool isSelected = (i == selectedRow); + const bool isHot = entry.total.maxMicros > 2000.0; + const bool isWarm = ! isHot && entry.total.maxMicros > 500.0; + + g.setFillColor (isSelected ? yup::Color (0xff353565) + : isHot ? yup::Color (0xff3a1010) + : isWarm ? yup::Color (0xff3a2a10) + : yup::Color (0xff1e1e38)); + g.fillRect (row); + + g.setFillColor (isHot ? yup::Color (0xffff6060) + : isWarm ? yup::Color (0xffffcc44) + : yup::Colors::white); + + auto r = row.reduced (2, 0); + g.fillFittedText (entry.name, font, r.removeFromLeft (nameW), yup::Justification::centerLeft); + g.fillFittedText (formatMicros (entry.total.maxMicros), font, r.removeFromLeft (kMaxColW), yup::Justification::centerLeft); + g.fillFittedText (formatMicros (entry.total.meanMicros), font, r.removeFromLeft (kAvgColW), yup::Justification::centerLeft); + + drawSparkline (g, r, entry.stats); + } + } + + void drawSparkline (yup::Graphics& g, yup::Rectangle area, const yup::PaintProfileStats* stats) + { + if (area.isEmpty() || stats == nullptr || stats->getSampleCount() == 0) + return; + + const auto allSamples = stats->copySamples(); + const int n = std::min ((int) allSamples.size(), 80); + const int start = (int) allSamples.size() - n; + + const float barW = area.getWidth() / (float) n; + const float maxUs = 2000.0f; + + for (int i = 0; i < n; ++i) + { + const auto& sample = allSamples[(std::size_t) (start + i)]; + const double totalUs = sample.totalMicros; + const double selfUs = sample.selfMicros; + + const float ratio = std::min (1.0f, (float) (totalUs / maxUs)); + const float totalH = std::max (2.0f, area.getHeight() * ratio); + + const float selfFrac = totalUs > 0.0 ? (float) (selfUs / totalUs) : 1.0f; + const float selfH = std::max (1.0f, totalH * selfFrac); + const float childH = totalH - selfH; + + const float x = area.getX() + i * barW; + const float bW = std::max (1.0f, barW - 0.5f); + + // Self portion (bottom) — green normally, amber/red when hot + g.setFillColor (totalUs > 2000.0 ? yup::Color (0xffcc2222) + : totalUs > 500.0 ? yup::Color (0xffbb8800) + : yup::Color (0xff33aa44)); + g.fillRect ({ x, area.getBottom() - selfH, bW, selfH }); + + // Children portion (above self) — blue normally, amber/red when hot + if (childH > 0.5f) + { + g.setFillColor (totalUs > 2000.0 ? yup::Color (0xffff6666) + : totalUs > 500.0 ? yup::Color (0xffffcc44) + : yup::Color (0xff4488cc)); + g.fillRect ({ x, area.getBottom() - totalH, bW, childH }); + } + } + } + + void drawRightPanel (yup::Graphics& g, yup::Rectangle area) + { + if (area.isEmpty()) + return; + + const float histH = (area.getHeight() - 6.0f) * 0.48f; + + auto globalArea = area.removeFromTop (histH); + drawHistogramPanel (g, globalArea, "Global frame total", snapshot.globalFrameHistogram, -1.0); + + area.removeFromTop (6.0f); + + if (selectedRow >= 0 && selectedRow < (int) snapshot.components.size()) + { + const auto& entry = snapshot.components[selectedRow]; + yup::PaintProfileHistogram selHisto; + if (entry.stats != nullptr) + selHisto = entry.stats->createHistogram (yup::PaintProfileTimeKind::total, 32); + + auto selArea = area.removeFromTop (histH); + drawHistogramPanel (g, selArea, entry.name + " total", selHisto, entry.total.p95Micros); + + area.removeFromTop (4.0f); + g.setFillColor (yup::Color (0xff888899)); + g.fillFittedText ( + yup::String::formatted ("self %.0f children %.0f fw %.0f total %.0f us [p95 %.0f]", + entry.self.lastMicros, + entry.children.lastMicros, + entry.framework.lastMicros, + entry.total.lastMicros, + entry.total.p95Micros), + font, + area.reduced (4, 0), + yup::Justification::topLeft); + } + else + { + auto selArea = area.removeFromTop (histH); + drawHistogramPanel (g, selArea, "Click a row to inspect", {}, -1.0); + } + } + + void drawHistogramPanel (yup::Graphics& g, + yup::Rectangle area, + const yup::String& label, + const yup::PaintProfileHistogram& histo, + double p95Micros) + { + if (area.isEmpty()) + return; + + g.setFillColor (yup::Color (0xff161628)); + g.fillRect (area); + + const float labelH = 15.0f; + auto labelArea = area.removeFromTop (labelH); + g.setFillColor (yup::Color (0xff8888bb)); + g.fillFittedText (label, font, labelArea.reduced (3, 0), yup::Justification::centerLeft); + + const float axisH = 13.0f; + auto axisArea = area.removeFromBottom (axisH); + + if (histo.buckets.empty() || histo.rangeMaxMicros <= 0.0) + return; + + int maxCount = 0; + for (int c : histo.buckets) + maxCount = std::max (maxCount, c); + if (maxCount == 0) + return; + + const int numBuckets = (int) histo.buckets.size(); + const float barW = area.getWidth() / (float) numBuckets; + const double usPerBucket = histo.rangeMaxMicros / numBuckets; + + for (int i = 0; i < numBuckets; ++i) + { + const float ratio = (float) histo.buckets[i] / (float) maxCount; + if (ratio <= 0.0f) + continue; + + const double bucketMidUs = (i + 0.5) * usPerBucket; + const yup::Color barColor = bucketMidUs > 2000.0 ? yup::Color (0xffcc3333) + : bucketMidUs > 500.0 ? yup::Color (0xffcc8800) + : yup::Color (0xff33aa44); + + const float barH = area.getHeight() * ratio; + g.setFillColor (barColor); + g.fillRect ({ area.getX() + i * barW, + area.getBottom() - barH, + std::max (1.0f, barW - 0.5f), + barH }); + } + + auto drawThreshold = [&] (double thresholdUs, yup::Color color) + { + if (thresholdUs >= histo.rangeMaxMicros) + return; + const float x = area.getX() + area.getWidth() * (float) (thresholdUs / histo.rangeMaxMicros); + g.setFillColor (color.withAlpha (0.55f)); + g.fillRect ({ x - 0.5f, area.getY(), 1.0f, area.getHeight() }); + }; + + drawThreshold (500.0, yup::Color (0xffffff00)); + drawThreshold (2000.0, yup::Color (0xffff4444)); + + if (p95Micros > 0.0 && p95Micros < histo.rangeMaxMicros) + { + const float x = area.getX() + area.getWidth() * (float) (p95Micros / histo.rangeMaxMicros); + g.setFillColor (yup::Color (0xffffffff).withAlpha (0.7f)); + g.fillRect ({ x - 0.5f, area.getY(), 1.0f, area.getHeight() }); + } + + g.setFillColor (yup::Color (0xff666688)); + g.fillFittedText ("0", font, axisArea.removeFromLeft (28.0f), yup::Justification::centerLeft); + + const float pos500 = area.getWidth() * (float) (500.0 / histo.rangeMaxMicros); + if (pos500 > 30.0f && pos500 < area.getWidth() - 30.0f) + { + g.setFillColor (yup::Color (0xffaaaa44)); + g.fillFittedText (L"500µs", font, { area.getX() + pos500 - 18.0f, axisArea.getY(), 36.0f, axisH }, yup::Justification::center); + } + + const float pos2ms = area.getWidth() * (float) (2000.0 / histo.rangeMaxMicros); + if (pos2ms > 30.0f && pos2ms < area.getWidth() - 30.0f) + { + g.setFillColor (yup::Color (0xffcc5555)); + g.fillFittedText ("2ms", font, { area.getX() + pos2ms - 16.0f, axisArea.getY(), 32.0f, axisH }, yup::Justification::center); + } + + g.setFillColor (yup::Color (0xff666688)); + g.fillFittedText (formatMicros (histo.rangeMaxMicros), font, axisArea.removeFromRight (52.0f), yup::Justification::centerRight); + } + + static yup::String formatMicros (double micros) + { + if (micros >= 1000.0) + return yup::String::formatted ("%.2f ms", micros / 1000.0); + return yup::String::formatted ("%.0f us", micros); + } + + yup::PaintProfiler::Snapshot snapshot; +#endif + + int selectedRow = -1; + yup::Font font; +}; + +//============================================================================== + +class ProfilerWindow : public yup::DocumentWindow +{ +public: + explicit ProfilerWindow (std::function onClose) + : yup::DocumentWindow ( + yup::ComponentNative::Options() + .withResizableWindow (true) + .withRenderContinuous (false), + yup::Color (0xff1a1a2e)) + , closeCallback (std::move (onClose)) + { + setTitle ("Paint Profiler"); + dashboard = std::make_unique(); + addAndMakeVisible (dashboard.get()); + } + + void resized() override + { + dashboard->setBounds (getLocalBounds()); + } + + void userTriedToCloseWindow() override + { + if (closeCallback != nullptr) + yup::MessageManager::callAsync (closeCallback); + } + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + void updateSnapshot (const yup::PaintProfiler::Snapshot& snap) + { + dashboard->setSnapshot (snap, dashboard->getSelectedRow()); + } +#endif + +private: + std::unique_ptr dashboard; + std::function closeCallback; +}; + +//============================================================================== + +class PaintProfilerDemo : public yup::Component + , public yup::Timer +{ +public: + PaintProfilerDemo() + { + setTitle ("Paint Profiler Demo"); + setWantsKeyboardFocus (true); + + opaqueWidget = std::make_unique(); + addAndMakeVisible (opaqueWidget.get()); + + pathWidget = std::make_unique(); + addAndMakeVisible (pathWidget.get()); + + textWidget = std::make_unique(); + addAndMakeVisible (textWidget.get()); + + nestedGrid = std::make_unique(); + addAndMakeVisible (nestedGrid.get()); + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + paintProfileSession = yup::PaintProfiler::getInstance().startSession (*this); +#endif + + startTimerHz (10); + } + + ~PaintProfilerDemo() override + { + stopTimer(); + profilerWindow.reset(); + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + paintProfileSession.reset(); +#endif + } + + void paint (yup::Graphics& g) override + { + g.setFillColor (findColor (yup::DocumentWindow::Style::backgroundColorId) + .value_or (yup::Color (0xff282840))); + g.fillAll(); + } + + void resized() override + { + const auto bounds = getLocalBounds().to(); + const float widgetW = bounds.getWidth() / 2.0f; + const float widgetH = bounds.getHeight() / 2.0f; + + opaqueWidget->setBounds ({ 0.0f, 0.0f, widgetW, widgetH }); + pathWidget->setBounds ({ widgetW, 0.0f, widgetW, widgetH }); + textWidget->setBounds ({ 0.0f, widgetH, widgetW, widgetH }); + nestedGrid->setBounds ({ widgetW, widgetH, widgetW, widgetH }); + } + + void timerCallback() override + { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + if (paintProfileSession == nullptr || paintProfileSession->isPaused()) + return; + + if (profilerWindow == nullptr || ! profilerWindow->isVisible()) + return; + + auto snap = paintProfileSession->createSnapshot (yup::PaintProfileTimeKind::total, 32); + profilerWindow->updateSnapshot (snap); +#endif + } + + void keyDown (const yup::KeyPress& keys, const yup::Point& position) override + { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + if (keys.getKey() == yup::KeyPress::textPKey) + { + toggleProfilerWindow(); + } + else if (keys.getKey() == yup::KeyPress::textRKey) + { + if (paintProfileSession != nullptr) + paintProfileSession->reset(); + } + else if (keys.getKey() == yup::KeyPress::textLKey) + { + logSnapshot(); + } +#endif + } + +private: + void toggleProfilerWindow() + { + if (profilerWindow == nullptr) + { + profilerWindow = std::make_unique ([this] + { + profilerWindow.reset(); + }); + profilerWindow->centreWithSize ({ 920, 520 }); + profilerWindow->setVisible (true); + profilerWindow->toFront (true); + } + else + { + profilerWindow.reset(); + } + } + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + void logSnapshot() + { + if (paintProfileSession == nullptr) + return; + + auto snap = paintProfileSession->createSnapshot (yup::PaintProfileTimeKind::total, 32); + + yup::Logger::outputDebugString ("Paint profile snapshot frame=" + yup::String (snap.frameIndex)); + yup::Logger::outputDebugString (yup::String::formatted ("%-30s %9s %9s %9s %9s", + "Widget", + "last", + "mean", + "p95", + "max")); + + for (const auto& entry : snap.components) + { + yup::Logger::outputDebugString (yup::String::formatted ("%-30s %8.2f ms %8.2f ms %8.2f ms %8.2f ms", + entry.name.toRawUTF8(), + entry.total.lastMicros / 1000.0, + entry.total.meanMicros / 1000.0, + entry.total.p95Micros / 1000.0, + entry.total.maxMicros / 1000.0)); + } + + yup::String globalBuckets = "Global frame histogram total/us buckets:"; + for (int c : snap.globalFrameHistogram.buckets) + globalBuckets += " " + yup::String (c); + yup::Logger::outputDebugString (globalBuckets); + } +#endif + + std::unique_ptr opaqueWidget; + std::unique_ptr pathWidget; + std::unique_ptr textWidget; + std::unique_ptr nestedGrid; + std::unique_ptr profilerWindow; + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + std::unique_ptr paintProfileSession; +#endif +}; diff --git a/examples/graphics/source/main.cpp b/examples/graphics/source/main.cpp index a943ca89a..339185015 100644 --- a/examples/graphics/source/main.cpp +++ b/examples/graphics/source/main.cpp @@ -55,6 +55,7 @@ #include "examples/TextEditor.h" #include "examples/VariableFonts.h" #include "examples/Widgets.h" +#include "examples/PaintProfilerDemo.h" #if YUP_MODULE_AVAILABLE_yup_python #include "examples/Python.h" #endif @@ -161,6 +162,7 @@ class CustomWindow jassert (artboard.loadArtboard()); }); registerDemo ("SVG", counter++); + registerDemo ("Paint Profiler", counter++); #if YUP_MODULE_AVAILABLE_yup_python registerDemo ("Python", counter++); #endif diff --git a/modules/yup_gui/component/yup_Component.cpp b/modules/yup_gui/component/yup_Component.cpp index 297238206..2a22232f1 100644 --- a/modules/yup_gui/component/yup_Component.cpp +++ b/modules/yup_gui/component/yup_Component.cpp @@ -37,6 +37,10 @@ Component::Component (StringRef componentID) Component::~Component() { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + setPaintProfilingEnabled (false); +#endif + if (options.onDesktop) removeFromDesktop(); @@ -902,6 +906,21 @@ void Component::setWantsKeyboardFocus (bool wantsFocus) options.wantsKeyboardFocus = wantsFocus; } +bool Component::getWantsKeyboardFocus() const +{ + return options.wantsKeyboardFocus; +} + +void Component::setClickingGrabFocus (bool shouldGrabFocus) +{ + options.clickingDoesNotGrabFocus = ! shouldGrabFocus; +} + +bool Component::getClickingGrabFocus() const +{ + return ! options.clickingDoesNotGrabFocus; +} + void Component::takeKeyboardFocus() { if (! options.wantsKeyboardFocus) @@ -937,6 +956,20 @@ void Component::focusLost() {} //============================================================================== +void Component::handleKeyboardFocusFromClick() +{ + for (auto* component = this; component != nullptr; component = component->parentComponent) + { + if (component->options.wantsKeyboardFocus && ! component->options.clickingDoesNotGrabFocus) + { + component->takeKeyboardFocus(); + return; + } + } +} + +//============================================================================== + NamedValueSet& Component::getProperties() { return properties; @@ -1123,6 +1156,141 @@ bool Component::hasOpaqueChildCoveringArea (const Rectangle& area) return false; } +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + +//============================================================================== + +void Component::setPaintProfilingEnabled (bool shouldBeEnabled, PaintProfileOptions options) +{ + if (shouldBeEnabled) + { + if (paintProfileStats == nullptr + || paintProfileStats->getCapacity() != options.sampleCapacity) + { + paintProfileStats = std::make_unique (options); + } + PaintProfiler::getInstance().registerComponent (*this, *paintProfileStats); + } + else + { + PaintProfiler::getInstance().deregisterComponent (*this); + paintProfileStats.reset(); + } +} + +bool Component::isPaintProfilingEnabled() const +{ + return paintProfileStats != nullptr; +} + +void Component::resetPaintProfiling() +{ + if (paintProfileStats != nullptr) + paintProfileStats->reset(); +} + +PaintProfileStats* Component::getPaintProfileStats() +{ + return paintProfileStats.get(); +} + +const PaintProfileStats* Component::getPaintProfileStats() const +{ + return paintProfileStats.get(); +} + +String Component::getPaintProfileName() const +{ + if (componentTitle.isNotEmpty()) + return componentTitle; + + if (componentID.isNotEmpty()) + return componentID; + + return "Component"; +} + +//============================================================================== + +struct PaintProfileScopeEntry +{ + double childrenMicros = 0.0; +}; + +thread_local std::vector paintProfileScopeStack; +static std::atomic globalPaintIndexCounter { 0 }; + +class PaintProfileScope +{ +public: + PaintProfileScope (Component& component, + const Rectangle& repaintArea, + bool renderContinuous, + uint64 frameIndex) + : component (component) + , sample() + , totalStartMicros (ticksToMicros (Time::getHighResolutionTicks())) + , selfStartMicros (0.0) + { + sample.frameIndex = frameIndex; + sample.paintIndex = globalPaintIndexCounter.fetch_add (1, std::memory_order_relaxed); + sample.repaintArea = repaintArea; + sample.componentBounds = component.getBoundsRelativeToTopLevelComponent().to(); + sample.renderContinuous = renderContinuous; + + paintProfileScopeStack.push_back ({}); + } + + ~PaintProfileScope() + { + const double totalEndMicros = ticksToMicros (Time::getHighResolutionTicks()); + sample.totalMicros = totalEndMicros - totalStartMicros; + sample.childrenMicros = paintProfileScopeStack.back().childrenMicros; + paintProfileScopeStack.pop_back(); + + sample.frameworkMicros = std::max (0.0, + sample.totalMicros + - sample.selfMicros + - sample.childrenMicros); + + if (auto* stats = component.getPaintProfileStats()) + stats->recordSample (sample); + + if (! paintProfileScopeStack.empty()) + paintProfileScopeStack.back().childrenMicros += sample.totalMicros; + } + + void beginSelf() + { + selfStartMicros = ticksToMicros (Time::getHighResolutionTicks()); + } + + void endSelf() + { + sample.selfMicros += ticksToMicros (Time::getHighResolutionTicks()) - selfStartMicros; + } + + void markSelfPaintSkipped() + { + sample.selfPaintSkipped = true; + } + +private: + static double ticksToMicros (int64 ticks) + { + return Time::highResolutionTicksToSeconds (ticks) * 1.0e6; + } + + Component& component; + PaintProfileSample sample; + double totalStartMicros; + double selfStartMicros; + + YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaintProfileScope) +}; + +#endif // YUP_ENABLE_COMPONENT_PAINT_PROFILING + //============================================================================== void Component::internalRefreshDisplay (double lastFrameTimeSeconds) @@ -1174,6 +1342,15 @@ void Component::internalPaint (Graphics& g, const Rectangle& repaintArea, options.isRepainting = true; { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + const bool profilingActive = PaintProfiler::getInstance().isEnabled() && paintProfileStats != nullptr; + + const auto frameIndex = PaintProfiler::getInstance().getCurrentFrameIndex(); + PaintProfileScope profileScope (*this, repaintArea, renderContinuous, frameIndex); +#else + constexpr bool profilingActive = false; +#endif + const auto globalState = g.saveState(); g.setOpacity (opacity); @@ -1191,18 +1368,41 @@ void Component::internalPaint (Graphics& g, const Rectangle& repaintArea, { const auto paintState = g.saveState(); - paint (g); + if (profilingActive) + { + YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.beginSelf();) + paint (g); + YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.endSelf();) + } + else + { + paint (g); + } + } + else + { + if (profilingActive) + YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.markSelfPaintSkipped();) } for (auto child : children) child->internalPaint (g, boundsToRedraw, renderContinuous); - paintOverChildren (g); + if (profilingActive) + { + YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.beginSelf();) + paintOverChildren (g); + YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.endSelf();) + } + else + { + paintOverChildren (g); + } } options.isRepainting = false; -#if YUP_ENABLE_COMPONENT_REPAINT_DEBUGGING +#if YUP_ENABLE_COMPONENT_PAINT_DEBUGGING g.setFillColor (debugColor); g.setOpacity (0.2f); g.fillAll(); @@ -1264,6 +1464,11 @@ void Component::internalMouseDown (const MouseEvent& event) auto bailOutChecker = BailOutChecker (this); + handleKeyboardFocusFromClick(); + + if (bailOutChecker.shouldBailOut()) + return; + mouseDown (event); if (bailOutChecker.shouldBailOut()) diff --git a/modules/yup_gui/component/yup_Component.h b/modules/yup_gui/component/yup_Component.h index 938f2d04f..e925051d9 100644 --- a/modules/yup_gui/component/yup_Component.h +++ b/modules/yup_gui/component/yup_Component.h @@ -746,6 +746,32 @@ class YUP_API Component : public MouseListener */ void setWantsKeyboardFocus (bool wantsFocus); + /** + Check whether this component wants keyboard focus. + + @return True if this component wants keyboard focus, false otherwise. + */ + bool getWantsKeyboardFocus() const; + + /** + Set whether clicking this component can make it grab keyboard focus. + + When a component is clicked, focus handling walks from the clicked + component up through its parents until it finds a component that both + wants keyboard focus and has this flag enabled. This is enabled by + default. + + @param shouldGrabFocus True if mouse clicks can grab keyboard focus. + */ + void setClickingGrabFocus (bool shouldGrabFocus); + + /** + Check whether clicking this component can make it grab keyboard focus. + + @return True if mouse clicks can grab keyboard focus. + */ + bool getClickingGrabFocus() const; + /** Take the focus. */ @@ -1152,6 +1178,45 @@ class YUP_API Component : public MouseListener */ std::optional findStyleProperty (const Identifier& propertyId) const; +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + //============================================================================== + /** Enables or disables paint profiling for this component. + + When enabling, a PaintProfileStats instance is created (if not already present) + and the component is registered with PaintProfiler. Existing samples are + preserved when re-enabling with the same capacity. + + When disabling, the component is deregistered from PaintProfiler and the + stats object is destroyed. + + @param shouldBeEnabled Pass true to enable, false to disable. + @param options Controls the ring buffer capacity and recording behaviour. + */ + void setPaintProfilingEnabled (bool shouldBeEnabled, + PaintProfileOptions options = {}); + + /** Returns true if paint profiling is currently enabled for this component. */ + bool isPaintProfilingEnabled() const; + + /** Clears all paint profile samples recorded for this component. */ + void resetPaintProfiling(); + + /** Returns a pointer to this component's PaintProfileStats, or nullptr if + profiling is not enabled. */ + PaintProfileStats* getPaintProfileStats(); + + /** Returns a const pointer to this component's PaintProfileStats, or nullptr + if profiling is not enabled. */ + const PaintProfileStats* getPaintProfileStats() const; + + /** Returns the display name used for this component in profiling snapshots. + + Prefers (in order): a non-empty component title, a non-empty component ID, + the demangled type name if available, then falls back to "Component". + */ + String getPaintProfileName() const; +#endif + //============================================================================== /** A bail out checker for the component. */ class BailOutChecker @@ -1233,6 +1298,8 @@ class YUP_API Component : public MouseListener void internalAttachedToNative(); void internalDetachedFromNative(); + void handleKeyboardFocusFromClick(); + void updateMouseCursor(); bool hasOpaqueChildCoveringArea (const Rectangle& area); @@ -1266,6 +1333,7 @@ class YUP_API Component : public MouseListener bool isTransparent : 1; bool unclippedRendering : 1; bool wantsKeyboardFocus : 1; + bool clickingDoesNotGrabFocus : 1; bool isRepainting : 1; bool blockSelfMouseEvents : 1; bool blockChildrenMouseEvents : 1; @@ -1277,11 +1345,15 @@ class YUP_API Component : public MouseListener Options options; }; -#if YUP_ENABLE_COMPONENT_REPAINT_DEBUGGING +#if YUP_ENABLE_COMPONENT_PAINT_DEBUGGING Color debugColor = Color::opaqueRandom(); int counter = 2; #endif +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + std::unique_ptr paintProfileStats; +#endif + YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Component) }; diff --git a/modules/yup_gui/native/yup_Windowing_sdl2.cpp b/modules/yup_gui/native/yup_Windowing_sdl2.cpp index 4b0421ba8..cfd90aa2b 100644 --- a/modules/yup_gui/native/yup_Windowing_sdl2.cpp +++ b/modules/yup_gui/native/yup_Windowing_sdl2.cpp @@ -369,10 +369,29 @@ float SDL2ComponentNative::getOpacity() const void SDL2ComponentNative::setFocusedComponent (Component* comp) { + const auto focusNativeWindowIfNeeded = [&] + { + if (window != nullptr && isVisible() && lastComponentFocused != nullptr) + { + SDL_RaiseWindow (window); + + focusNativeWindow (getNativeHandle()); + + SDL_SetWindowInputFocus (window); + } + }; + + if (lastComponentFocused == comp) + { + focusNativeWindowIfNeeded(); + return; + } + auto compBailOut = Component::BailOutChecker (comp); // Check if we need to stop text input for the previously focused component Component* previousComponent = lastComponentFocused.get(); + WeakReference previousComponentWeak (previousComponent); bool previousWantsTextInput = previousComponent != nullptr && dynamic_cast (previousComponent) != nullptr; if (lastComponentFocused != nullptr) @@ -386,7 +405,14 @@ void SDL2ComponentNative::setFocusedComponent (Component* comp) } if (compBailOut.shouldBailOut()) + { + lastComponentFocused = nullptr; + + if (previousWantsTextInput && previousComponentWeak.get() != nullptr) + stopTextInput (*previousComponentWeak.get()); + return; + } lastComponentFocused = comp; @@ -395,8 +421,8 @@ void SDL2ComponentNative::setFocusedComponent (Component* comp) bool newWantsTextInput = newComponent != nullptr && dynamic_cast (newComponent) != nullptr; // Stop text input if the previous component had it but the new one doesn't - if (previousWantsTextInput && ! newWantsTextInput && previousComponent != nullptr) - stopTextInput (*previousComponent); + if (previousWantsTextInput && ! newWantsTextInput && previousComponentWeak.get() != nullptr) + stopTextInput (*previousComponentWeak.get()); if (lastComponentFocused != nullptr) { @@ -408,14 +434,7 @@ void SDL2ComponentNative::setFocusedComponent (Component* comp) lastComponentFocused->repaint(); } - if (window != nullptr && isVisible() && lastComponentFocused != nullptr) - { - SDL_RaiseWindow (window); - - focusNativeWindow (getNativeHandle()); - - SDL_SetWindowInputFocus (window); - } + focusNativeWindowIfNeeded(); } Component* SDL2ComponentNative::getFocusedComponent() const @@ -705,17 +724,27 @@ void SDL2ComponentNative::renderContext() context->begin (frameDescriptor); } - // Repaint components hierarchy - if (renderer != nullptr) { - const auto dpiScale = getScaleDpi(); +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + PaintProfiler::getInstance().beginFrame(); + const auto endFrameGuard = ErasedScopeGuard ([&] + { + PaintProfiler::getInstance().endFrame(); + }); +#endif - for (auto& repaintArea : currentRepaintAreas) + // Repaint components hierarchy + if (renderer != nullptr) { - YUP_PROFILE_NAMED_INTERNAL_TRACE (InternalPaint); + const auto dpiScale = getScaleDpi(); - Graphics g (*context, *renderer, dpiScale); - component.internalPaint (g, repaintArea, renderContinuous); + for (auto& repaintArea : currentRepaintAreas) + { + YUP_PROFILE_NAMED_INTERNAL_TRACE (InternalPaint); + + Graphics g (*context, *renderer, dpiScale); + component.internalPaint (g, repaintArea, renderContinuous); + } } } @@ -1366,6 +1395,8 @@ void SDL2ComponentNative::handleEvent (SDL_Event* event) case SDL_KEYDOWN: { + YUP_WINDOWING_LOG ("SDL_KEYDOWN " << event->key.keysym.sym << " " << event->key.keysym.scancode); + auto cursorPosition = getCursorPosition(); auto modifiers = toKeyModifiers (event->key.keysym.mod); @@ -1377,6 +1408,8 @@ void SDL2ComponentNative::handleEvent (SDL_Event* event) case SDL_KEYUP: { + YUP_WINDOWING_LOG ("SDL_KEYUP " << event->key.keysym.sym << " " << event->key.keysym.scancode); + auto cursorPosition = getCursorPosition(); auto modifiers = toKeyModifiers (event->key.keysym.mod); @@ -1388,7 +1421,7 @@ void SDL2ComponentNative::handleEvent (SDL_Event* event) case SDL_TEXTINPUT: { - YUP_WINDOWING_LOG ("SDL_TEXTINPUT"); + YUP_WINDOWING_LOG ("SDL_TEXTINPUT " << String::fromUTF8 (event->text.text)); // auto cursorPosition = getCursorPosition(); // auto modifiers = toKeyModifiers (getKeyModifiers()); diff --git a/modules/yup_gui/profiling/yup_PaintProfileSample.h b/modules/yup_gui/profiling/yup_PaintProfileSample.h new file mode 100644 index 000000000..8aeee7d74 --- /dev/null +++ b/modules/yup_gui/profiling/yup_PaintProfileSample.h @@ -0,0 +1,157 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== + +/** Identifies which time contribution to extract from a PaintProfileSample. */ +enum class PaintProfileTimeKind +{ + /** Time spent executing the component's own paint callback. */ + self, + + /** Time spent painting all direct and indirect children. */ + children, + + /** Time spent in framework bookkeeping around the paint call. */ + framework, + + /** Total elapsed time for the full paint pass of this component. */ + total +}; + +//============================================================================== + +/** Controls the behaviour and storage policy of a PaintProfileStats instance. */ +struct PaintProfileOptions +{ + /** Maximum number of samples retained in the ring buffer. */ + int sampleCapacity = 300; + + /** Samples whose totalMicros is below this threshold are discarded. + Set to 0.0 to record every sample. */ + double minimumSampleMicros = 0.0; + + /** When true, each sample stores the component bounds at paint time. */ + bool includeBounds = true; + + /** When true, each sample stores the dirty region that triggered the repaint. */ + bool includeRepaintArea = true; + + /** When true, samples are recorded even for components whose isVisible() returns false. */ + bool includeInvisibleComponents = false; + + /** When true, a sample is recorded even when the component's own paint was skipped + (e.g. because it has no paint implementation), so that child-only costs are tracked. */ + bool recordSkippedSelfPaint = true; +}; + +//============================================================================== + +/** A single timing snapshot captured during one paint pass of a component. */ +struct PaintProfileSample +{ + /** Monotonically increasing index of the display frame in which this sample was taken. */ + uint64 frameIndex = 0; + + /** Monotonically increasing index of the paint call within the current frame. */ + uint64 paintIndex = 0; + + /** Microseconds spent inside the component's own paint callback. */ + double selfMicros = 0.0; + + /** Microseconds spent painting all children of this component. */ + double childrenMicros = 0.0; + + /** Microseconds consumed by framework bookkeeping (transform setup, clip, etc.). */ + double frameworkMicros = 0.0; + + /** Total microseconds from the start to the end of the full paint pass. */ + double totalMicros = 0.0; + + /** Axis-aligned bounding rectangle of the component in its parent's coordinate space. */ + Rectangle componentBounds; + + /** The dirty region that triggered this repaint, in the component's local coordinate space. */ + Rectangle repaintArea; + + /** True when the component requested a continuous repaint (e.g. animation loop). */ + bool renderContinuous = false; + + /** True when the component's own paint callback was skipped for this sample. */ + bool selfPaintSkipped = false; +}; + +//============================================================================== + +/** Statistical summary computed over a collection of PaintProfileSample values + for a single PaintProfileTimeKind field. */ +struct PaintProfileSummary +{ + /** Number of samples included in this summary. */ + int sampleCount = 0; + + /** Value from the most recently recorded sample. */ + double lastMicros = 0.0; + + /** Minimum observed value across all samples. */ + double minMicros = 0.0; + + /** Maximum observed value across all samples. */ + double maxMicros = 0.0; + + /** Arithmetic mean of all sample values. */ + double meanMicros = 0.0; + + /** 50th-percentile (median) value. */ + double p50Micros = 0.0; + + /** 95th-percentile value. */ + double p95Micros = 0.0; + + /** 99th-percentile value. */ + double p99Micros = 0.0; +}; + +//============================================================================== + +/** A linear histogram of sample values for a single PaintProfileTimeKind field. + + The range [rangeMinMicros, rangeMaxMicros] is divided into buckets.size() equal-width + buckets. Each bucket stores the count of samples whose value falls within that interval. + Values above rangeMaxMicros are clamped into the last bucket. +*/ +struct PaintProfileHistogram +{ + /** Lower bound of the histogram range in microseconds (always 0.0). */ + double rangeMinMicros = 0.0; + + /** Upper bound of the histogram range in microseconds. */ + double rangeMaxMicros = 0.0; + + /** Per-bucket sample counts. buckets[i] covers the sub-range + [rangeMinMicros + i*width, rangeMinMicros + (i+1)*width). */ + std::vector buckets; +}; + +} // namespace yup diff --git a/modules/yup_gui/profiling/yup_PaintProfileStats.cpp b/modules/yup_gui/profiling/yup_PaintProfileStats.cpp new file mode 100644 index 000000000..6a7094fca --- /dev/null +++ b/modules/yup_gui/profiling/yup_PaintProfileStats.cpp @@ -0,0 +1,226 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== + +namespace +{ + +double extractTime (const PaintProfileSample& sample, PaintProfileTimeKind kind) +{ + switch (kind) + { + case PaintProfileTimeKind::self: + return sample.selfMicros; + case PaintProfileTimeKind::children: + return sample.childrenMicros; + case PaintProfileTimeKind::framework: + return sample.frameworkMicros; + case PaintProfileTimeKind::total: + return sample.totalMicros; + } + + return sample.totalMicros; +} + +double percentileFromSorted (const std::vector& sorted, double p) +{ + if (sorted.empty()) + return 0.0; + + const int n = static_cast (sorted.size()); + const int index = std::max (0, static_cast (std::ceil (p / 100.0 * n)) - 1); + return sorted[static_cast (index)]; +} + +} // namespace + +//============================================================================== + +PaintProfileStats::PaintProfileStats (PaintProfileOptions options) + : options (options) +{ + samples.resize (static_cast (options.sampleCapacity)); + nextSample = 0; + sampleCount = 0; +} + +//============================================================================== + +void PaintProfileStats::recordSample (const PaintProfileSample& sample) +{ + if (options.minimumSampleMicros > 0.0 && sample.totalMicros < options.minimumSampleMicros) + return; + + samples[static_cast (nextSample)] = sample; + nextSample = (nextSample + 1) % options.sampleCapacity; + sampleCount = std::min (sampleCount + 1, options.sampleCapacity); +} + +void PaintProfileStats::reset() +{ + nextSample = 0; + sampleCount = 0; +} + +//============================================================================== + +int PaintProfileStats::getSampleCount() const +{ + return sampleCount; +} + +int PaintProfileStats::getCapacity() const +{ + return options.sampleCapacity; +} + +PaintProfileOptions PaintProfileStats::getOptions() const +{ + return options; +} + +//============================================================================== + +std::vector PaintProfileStats::copySamples() const +{ + std::vector result; + result.reserve (static_cast (sampleCount)); + + if (sampleCount < options.sampleCapacity) + { + for (int i = 0; i < sampleCount; ++i) + result.push_back (samples[static_cast (i)]); + } + else + { + for (int i = 0; i < options.sampleCapacity; ++i) + { + const int index = (nextSample + i) % options.sampleCapacity; + result.push_back (samples[static_cast (index)]); + } + } + + return result; +} + +PaintProfileSample PaintProfileStats::getLastSample() const +{ + if (sampleCount == 0) + return {}; + + const int index = (nextSample - 1 + options.sampleCapacity) % options.sampleCapacity; + return samples[static_cast (index)]; +} + +//============================================================================== + +PaintProfileSummary PaintProfileStats::summarize (PaintProfileTimeKind kind) const +{ + const auto all = copySamples(); + + PaintProfileSummary summary; + summary.sampleCount = static_cast (all.size()); + + if (all.empty()) + return summary; + + std::vector values; + values.reserve (all.size()); + + double sum = 0.0; + double minVal = std::numeric_limits::max(); + double maxVal = std::numeric_limits::lowest(); + + for (const auto& s : all) + { + const double v = extractTime (s, kind); + values.push_back (v); + sum += v; + minVal = std::min (minVal, v); + maxVal = std::max (maxVal, v); + } + + summary.lastMicros = values.back(); + summary.minMicros = minVal; + summary.maxMicros = maxVal; + summary.meanMicros = sum / static_cast (values.size()); + + std::vector sorted = values; + std::sort (sorted.begin(), sorted.end()); + + summary.p50Micros = percentileFromSorted (sorted, 50.0); + summary.p95Micros = percentileFromSorted (sorted, 95.0); + summary.p99Micros = percentileFromSorted (sorted, 99.0); + + return summary; +} + +PaintProfileHistogram PaintProfileStats::createHistogram (PaintProfileTimeKind kind, int numBuckets) const +{ + jassert (numBuckets >= 1); + numBuckets = std::max (1, numBuckets); + + const auto all = copySamples(); + + PaintProfileHistogram histogram; + histogram.rangeMinMicros = 0.0; + histogram.buckets.assign (static_cast (numBuckets), 0); + + if (all.empty()) + { + histogram.rangeMaxMicros = 100.0; + return histogram; + } + + std::vector values; + values.reserve (all.size()); + + double maxObserved = 0.0; + for (const auto& s : all) + { + const double v = extractTime (s, kind); + values.push_back (v); + maxObserved = std::max (maxObserved, v); + } + + std::vector sorted = values; + std::sort (sorted.begin(), sorted.end()); + const double p99 = percentileFromSorted (sorted, 99.0); + + histogram.rangeMaxMicros = std::max ({ p99 * 1.25, maxObserved, 100.0 }); + + const double bucketWidth = histogram.rangeMaxMicros / static_cast (numBuckets); + + for (const double v : values) + { + int bucket = static_cast (v / bucketWidth); + bucket = std::min (bucket, numBuckets - 1); + ++histogram.buckets[static_cast (bucket)]; + } + + return histogram; +} + +} // namespace yup diff --git a/modules/yup_gui/profiling/yup_PaintProfileStats.h b/modules/yup_gui/profiling/yup_PaintProfileStats.h new file mode 100644 index 000000000..d6e52d092 --- /dev/null +++ b/modules/yup_gui/profiling/yup_PaintProfileStats.h @@ -0,0 +1,128 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== + +/** Collects and analyses PaintProfileSample records for a single component. + + Samples are stored in a fixed-capacity ring buffer whose size is determined by + PaintProfileOptions::sampleCapacity. Once full, the oldest sample is silently + overwritten by each new arrival. + + All query methods are const and operate on a snapshot of the ring buffer, so + they are safe to call from any thread as long as no concurrent writes are in + progress. If concurrent access is required, the caller is responsible for + external synchronisation. +*/ +class PaintProfileStats +{ +public: + //============================================================================== + + /** Constructs a PaintProfileStats with the given options. + + @param options Controls capacity, filtering thresholds, and recording behaviour. + Defaults to a PaintProfileOptions with sampleCapacity = 300. + */ + explicit PaintProfileStats (PaintProfileOptions options = {}); + + //============================================================================== + + /** Records a new paint sample. + + If PaintProfileOptions::minimumSampleMicros is greater than zero and + sample.totalMicros is below that threshold, the sample is silently discarded. + Otherwise the sample overwrites the oldest entry in the ring buffer. + + @param sample The sample to store. + */ + void recordSample (const PaintProfileSample& sample); + + /** Clears all stored samples and resets internal counters to zero. + + The configured PaintProfileOptions are preserved; only the sample data is cleared. + */ + void reset(); + + //============================================================================== + + /** Returns the number of valid samples currently stored (at most getCapacity()). */ + int getSampleCount() const; + + /** Returns the maximum number of samples that can be stored concurrently. */ + int getCapacity() const; + + /** Returns the PaintProfileOptions that were supplied at construction time. */ + PaintProfileOptions getOptions() const; + + //============================================================================== + + /** Returns a copy of all valid samples in chronological order (oldest first). + + If fewer samples than the capacity have been recorded, only the recorded + samples are returned. Once the buffer is full, iteration wraps correctly + around the ring so that chronological order is preserved. + + @returns A vector containing getSampleCount() samples. + */ + std::vector copySamples() const; + + /** Returns the most recently recorded sample. + + @returns The last sample, or a default-constructed PaintProfileSample if + no samples have been recorded yet. + */ + PaintProfileSample getLastSample() const; + + //============================================================================== + + /** Computes a statistical summary for the specified time field across all stored samples. + + @param kind Selects which time field (self, children, framework, or total) + is used when computing the statistics. + @returns A PaintProfileSummary populated with min, max, mean, and percentile values. + */ + PaintProfileSummary summarize (PaintProfileTimeKind kind) const; + + /** Builds a linear frequency histogram for the specified time field. + + The histogram range is derived automatically from the data: the upper bound is + max(p99 * 1.25, maxObserved, 100.0) microseconds, and the range is divided into + numBuckets equal-width buckets starting from 0. Values above the upper bound are + clamped into the last bucket. + + @param kind Selects which time field is histogrammed. + @param numBuckets Number of equal-width buckets to create. Must be >= 1. + @returns A PaintProfileHistogram with buckets.size() == numBuckets. + */ + PaintProfileHistogram createHistogram (PaintProfileTimeKind kind, int numBuckets) const; + +private: + std::vector samples; + PaintProfileOptions options; + int nextSample = 0; + int sampleCount = 0; +}; + +} // namespace yup diff --git a/modules/yup_gui/profiling/yup_PaintProfiler.cpp b/modules/yup_gui/profiling/yup_PaintProfiler.cpp new file mode 100644 index 000000000..93b670714 --- /dev/null +++ b/modules/yup_gui/profiling/yup_PaintProfiler.cpp @@ -0,0 +1,309 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== +// PaintProfiler +//============================================================================== + +PaintProfiler::PaintProfiler() + : globalFrameStats (std::make_unique (PaintProfileOptions {})) +{ +} + +PaintProfiler::~PaintProfiler() = default; + +//============================================================================== + +PaintProfiler& PaintProfiler::getInstance() +{ + static PaintProfiler instance; + return instance; +} + +//============================================================================== + +void PaintProfiler::setEnabled (bool shouldBeEnabled) +{ + enabled = shouldBeEnabled; +} + +bool PaintProfiler::isEnabled() const +{ + return enabled; +} + +//============================================================================== + +void PaintProfiler::beginFrame() +{ + ++currentFrameIndex; + globalPaintIndex.store (0, std::memory_order_relaxed); + frameStartMicros = Time::highResolutionTicksToSeconds (Time::getHighResolutionTicks()) * 1.0e6; +} + +void PaintProfiler::endFrame() +{ + const double endMicros = Time::highResolutionTicksToSeconds (Time::getHighResolutionTicks()) * 1.0e6; + + PaintProfileSample sample; + sample.frameIndex = currentFrameIndex; + sample.totalMicros = endMicros - frameStartMicros; + globalFrameStats->recordSample (sample); +} + +//============================================================================== + +void PaintProfiler::registerComponent (Component& component, PaintProfileStats& stats) +{ + const ScopedLock sl (registryLock); + + registry.erase (std::remove_if (registry.begin(), registry.end(), [&] (const auto& entry) + { + return entry.first == &component; + }), + registry.end()); + + registry.emplace_back (&component, &stats); +} + +void PaintProfiler::deregisterComponent (const Component& component) +{ + const ScopedLock sl (registryLock); + + registry.erase (std::remove_if (registry.begin(), registry.end(), [&] (const auto& entry) + { + return entry.first == &component; + }), + registry.end()); +} + +//============================================================================== + +void PaintProfiler::enableSubtree (Component& root, PaintProfileOptions options) +{ + root.setPaintProfilingEnabled (true, options); + + for (int i = 0; i < root.getNumChildComponents(); ++i) + { + if (auto* child = root.getChildComponent (i)) + enableSubtree (*child, options); + } +} + +void PaintProfiler::disableSubtree (Component& root) +{ + root.setPaintProfilingEnabled (false); + + for (int i = 0; i < root.getNumChildComponents(); ++i) + { + if (auto* child = root.getChildComponent (i)) + disableSubtree (*child); + } +} + +void PaintProfiler::resetSubtree (Component& root) +{ + { + const ScopedLock sl (registryLock); + + for (auto& [component, stats] : registry) + { + if (component == &root) + { + stats->reset(); + break; + } + } + } + + for (int i = 0; i < root.getNumChildComponents(); ++i) + { + if (auto* child = root.getChildComponent (i)) + resetSubtree (*child); + } +} + +void PaintProfiler::resetAll() +{ + const ScopedLock sl (registryLock); + + for (auto& [component, stats] : registry) + stats->reset(); + + globalFrameStats->reset(); +} + +//============================================================================== + +std::unique_ptr PaintProfiler::startSession (Component& root, + PaintProfileOptions options) +{ + return std::unique_ptr (new ScopedSession (*this, root, options)); +} + +//============================================================================== + +PaintProfiler::Snapshot PaintProfiler::createSnapshot (PaintProfileTimeKind sortBy, + int histogramBuckets) const +{ + std::vector> registryCopy; + + { + const ScopedLock sl (registryLock); + registryCopy = registry; + } + + Snapshot snapshot; + snapshot.frameIndex = currentFrameIndex; + snapshot.components.reserve (registryCopy.size()); + + for (auto& [component, stats] : registryCopy) + { + ComponentEntry entry; + entry.component = component; + entry.name = component->getPaintProfileName(); + entry.stats = stats; + entry.self = stats->summarize (PaintProfileTimeKind::self); + entry.children = stats->summarize (PaintProfileTimeKind::children); + entry.framework = stats->summarize (PaintProfileTimeKind::framework); + entry.total = stats->summarize (PaintProfileTimeKind::total); + + snapshot.components.push_back (std::move (entry)); + } + + std::sort (snapshot.components.begin(), snapshot.components.end(), [sortBy] (const ComponentEntry& a, const ComponentEntry& b) + { + auto getP95 = [sortBy] (const ComponentEntry& entry) -> double + { + switch (sortBy) + { + case PaintProfileTimeKind::self: + return entry.self.p95Micros; + case PaintProfileTimeKind::children: + return entry.children.p95Micros; + case PaintProfileTimeKind::framework: + return entry.framework.p95Micros; + case PaintProfileTimeKind::total: + return entry.total.p95Micros; + default: + return entry.total.p95Micros; + } + }; + + return getP95 (a) > getP95 (b); + }); + + snapshot.globalFrameTotal = globalFrameStats->summarize (PaintProfileTimeKind::total); + snapshot.globalFrameHistogram = globalFrameStats->createHistogram (PaintProfileTimeKind::total, histogramBuckets); + + return snapshot; +} + +PaintProfileHistogram PaintProfiler::createHistogramForComponent (const Component& component, + PaintProfileTimeKind kind, + int histogramBuckets) const +{ + PaintProfileStats* found = nullptr; + + { + const ScopedLock sl (registryLock); + + for (auto& [comp, stats] : registry) + { + if (comp == &component) + { + found = stats; + break; + } + } + } + + if (found == nullptr) + return {}; + + return found->createHistogram (kind, histogramBuckets); +} + +//============================================================================== +// PaintProfiler::ScopedSession +//============================================================================== + +PaintProfiler::ScopedSession::ScopedSession (PaintProfiler& profilerRef, + Component& rootComponent, + PaintProfileOptions sessionOptions) + : profiler (profilerRef) + , root (&rootComponent) + , options (sessionOptions) +{ + profiler.enableSubtree (rootComponent, sessionOptions); + + // Walk the same subtree to capture weak references for later cleanup. + std::function collectComponents = [&] (Component& component) + { + enabledComponents.emplace_back (&component); + + for (int i = 0; i < component.getNumChildComponents(); ++i) + { + if (auto* child = component.getChildComponent (i)) + collectComponents (*child); + } + }; + + collectComponents (rootComponent); +} + +PaintProfiler::ScopedSession::~ScopedSession() +{ + for (auto& weakComponent : enabledComponents) + { + if (auto* component = weakComponent.get()) + component->setPaintProfilingEnabled (false); + } +} + +//============================================================================== + +void PaintProfiler::ScopedSession::setPaused (bool shouldBePaused) +{ + paused = shouldBePaused; +} + +bool PaintProfiler::ScopedSession::isPaused() const +{ + return paused; +} + +void PaintProfiler::ScopedSession::reset() +{ + if (auto* rootComponent = root.get()) + profiler.resetSubtree (*rootComponent); +} + +PaintProfiler::Snapshot PaintProfiler::ScopedSession::createSnapshot (PaintProfileTimeKind sortBy, + int histogramBuckets) const +{ + return profiler.createSnapshot (sortBy, histogramBuckets); +} + +} // namespace yup diff --git a/modules/yup_gui/profiling/yup_PaintProfiler.h b/modules/yup_gui/profiling/yup_PaintProfiler.h new file mode 100644 index 000000000..d514a4061 --- /dev/null +++ b/modules/yup_gui/profiling/yup_PaintProfiler.h @@ -0,0 +1,256 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== + +/** Process-wide singleton that coordinates paint profiling across all components. + + PaintProfiler maintains a registry of components that have profiling enabled, + provides frame-level bookkeeping (beginFrame / endFrame), and exposes snapshot + and histogram queries over the collected data. + + The recommended entry point for callers is startSession(), which returns a + RAII ScopedSession handle that enables profiling on a component subtree and + automatically disables it when the handle is destroyed. +*/ +class PaintProfiler +{ +public: + //============================================================================== + + /** A record describing one profiled component within a snapshot. */ + struct ComponentEntry + { + /** Pointer to the profiled component (may be stale after the snapshot is taken). */ + Component* component = nullptr; + + /** Display name of the component at snapshot time. */ + String name; + + /** Pointer to the stats object owned by the component (may be stale). */ + PaintProfileStats* stats = nullptr; + + /** Statistical summary for the component's own paint time. */ + PaintProfileSummary self; + + /** Statistical summary for the time spent painting this component's children. */ + PaintProfileSummary children; + + /** Statistical summary for framework bookkeeping time. */ + PaintProfileSummary framework; + + /** Statistical summary for the total paint time. */ + PaintProfileSummary total; + }; + + //============================================================================== + + /** An immutable snapshot of all currently profiled components. */ + struct Snapshot + { + /** Monotonically increasing index of the frame at which this snapshot was taken. */ + uint64 frameIndex = 0; + + /** One entry per registered component, sorted by the requested PaintProfileTimeKind. */ + std::vector components; + + /** Summary of global per-frame timing derived from globalFrameStats. */ + PaintProfileSummary globalFrameTotal; + + /** Histogram of global per-frame timing. */ + PaintProfileHistogram globalFrameHistogram; + }; + + //============================================================================== + + /** + RAII handle for a profiling session over a component subtree. + + Created by PaintProfiler::startSession(). The destructor disables profiling + for the same components that were enabled at construction time. + */ + class ScopedSession + { + public: + /** Destructor disables profiling for all components enabled by this session. */ + ~ScopedSession(); + + /** Pauses or resumes sample recording for this session. + + When paused, the profiler global enabled state is not changed; instead + the session records the paused state so that reset() and createSnapshot() + reflect a quiescent view. + + @param shouldBePaused Pass true to pause, false to resume. + */ + void setPaused (bool shouldBePaused); + + /** Returns true if this session is currently paused. */ + bool isPaused() const; + + /** Clears all samples collected by this session's components. */ + void reset(); + + /** Creates an immutable snapshot of the current profiling state. + + @param sortBy Which time kind to use when sorting components in the snapshot. + @param histogramBuckets Number of buckets to use for the global frame histogram. + @returns An immutable Snapshot of the current profiling state. + */ + Snapshot createSnapshot (PaintProfileTimeKind sortBy = PaintProfileTimeKind::total, + int histogramBuckets = 32) const; + + private: + friend class PaintProfiler; + + ScopedSession (PaintProfiler& profiler, + Component& root, + PaintProfileOptions options); + + PaintProfiler& profiler; + WeakReference root; + PaintProfileOptions options; + bool paused = false; + std::vector> enabledComponents; + + YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedSession) + }; + + //============================================================================== + + /** Returns the process-wide singleton instance. */ + static PaintProfiler& getInstance(); + + //============================================================================== + + /** Enables or disables global profiling. + + When disabled, no new samples are recorded but all per-component state and + the registry are preserved. + + @param shouldBeEnabled Pass true to enable, false to disable. + */ + void setEnabled (bool shouldBeEnabled); + + /** Returns true when global profiling is enabled. */ + bool isEnabled() const; + + //============================================================================== + + /** Enables profiling on the subtree rooted at root and returns an RAII handle. + + The handle's destructor will disable profiling for each component that was + enabled by this call, regardless of the current global enabled state. + + @param root The root component of the subtree to profile. + @param options Options forwarded to each component's PaintProfileStats. + @returns A unique_ptr to a ScopedSession that disables profiling on destruction. + */ + std::unique_ptr startSession (Component& root, + PaintProfileOptions options = {}); + + /** Recursively enables profiling for root and all its current children. + + @param root The root component of the subtree. + @param options Options forwarded to each component's PaintProfileStats. + */ + void enableSubtree (Component& root, PaintProfileOptions options = {}); + + /** Recursively disables profiling for root and all its current children. + + @param root The root component of the subtree. + */ + void disableSubtree (Component& root); + + /** Recursively resets all samples for root and all its current children. + + @param root The root component of the subtree. + */ + void resetSubtree (Component& root); + + /** Resets all samples for every registered component. */ + void resetAll(); + + //============================================================================== + + /** Creates an immutable snapshot of all registered components. + + @param sortBy Which time kind determines the sort order (descending by p95). + @param histogramBuckets Number of buckets for the global frame histogram. + @returns An immutable Snapshot populated with all currently registered components. + */ + Snapshot createSnapshot (PaintProfileTimeKind sortBy = PaintProfileTimeKind::total, + int histogramBuckets = 32) const; + + /** Creates a histogram for a specific component. + + @param component The component whose samples should be histogrammed. + @param kind Which time field to histogram. + @param histogramBuckets Number of equal-width buckets. + @returns A PaintProfileHistogram, or a default-constructed one if the component + is not registered. + */ + PaintProfileHistogram createHistogramForComponent (const Component& component, + PaintProfileTimeKind kind, + int histogramBuckets = 32) const; + + //============================================================================== + + /** Called by the native renderer before processing repaint areas. + + Increments the frame counter and resets the per-frame paint index. + */ + void beginFrame(); + + /** Called by the native renderer after all repaint areas have been processed. */ + void endFrame(); + + /** Returns the current frame index for use in sample construction. */ + uint64 getCurrentFrameIndex() const noexcept { return currentFrameIndex; } + +private: + friend class Component; + + /** Called by Component::setPaintProfilingEnabled to register a component. */ + void registerComponent (Component& component, PaintProfileStats& stats); + + /** Called by Component::setPaintProfilingEnabled to deregister a component. */ + void deregisterComponent (const Component& component); + + mutable CriticalSection registryLock; + std::vector> registry; + + std::unique_ptr globalFrameStats; + uint64 currentFrameIndex = 0; + std::atomic globalPaintIndex { 0 }; + double frameStartMicros = 0.0; + bool enabled = true; + + PaintProfiler(); + ~PaintProfiler(); + + YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaintProfiler) +}; + +} // namespace yup diff --git a/modules/yup_gui/yup_gui.cpp b/modules/yup_gui/yup_gui.cpp index 060aa6c53..c905dbcca 100644 --- a/modules/yup_gui/yup_gui.cpp +++ b/modules/yup_gui/yup_gui.cpp @@ -133,6 +133,8 @@ #include "clipboard/yup_SystemClipboard.cpp" #include "component/yup_ComponentNative.cpp" #include "component/yup_Component.cpp" +#include "profiling/yup_PaintProfileStats.cpp" +#include "profiling/yup_PaintProfiler.cpp" #include "menus/yup_PopupMenu.cpp" #include "buttons/yup_Button.cpp" #include "buttons/yup_TextButton.cpp" diff --git a/modules/yup_gui/yup_gui.h b/modules/yup_gui/yup_gui.h index 9a2de2d1b..309f4ceb3 100644 --- a/modules/yup_gui/yup_gui.h +++ b/modules/yup_gui/yup_gui.h @@ -52,12 +52,12 @@ #include //============================================================================== -/** Config: YUP_ENABLE_COMPONENT_REPAINT_DEBUGGING +/** Config: YUP_ENABLE_COMPONENT_PAINT_DEBUGGING Enable repaint debugging for components. */ -#ifndef YUP_ENABLE_COMPONENT_REPAINT_DEBUGGING -#define YUP_ENABLE_COMPONENT_REPAINT_DEBUGGING 0 +#ifndef YUP_ENABLE_COMPONENT_PAINT_DEBUGGING +#define YUP_ENABLE_COMPONENT_PAINT_DEBUGGING 0 #endif //============================================================================== @@ -69,6 +69,23 @@ #define YUP_ENABLE_WINDOWING_EVENT_LOGGING 1 #endif +//============================================================================== +/** Config: YUP_ENABLE_COMPONENT_PAINT_PROFILING + + Enable YUP component paint profiling. +*/ +#ifndef YUP_ENABLE_COMPONENT_PAINT_PROFILING +#define YUP_ENABLE_COMPONENT_PAINT_PROFILING 0 +#endif + +//============================================================================== + +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING +#define YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED(CODE) CODE +#else +#define YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED(CODE) +#endif + //============================================================================== #include @@ -87,9 +104,12 @@ #include "clipboard/yup_SystemClipboard.h" #include "desktop/yup_Screen.h" #include "desktop/yup_Desktop.h" +#include "profiling/yup_PaintProfileSample.h" +#include "profiling/yup_PaintProfileStats.h" #include "component/yup_ComponentNative.h" #include "component/yup_ComponentStyle.h" #include "component/yup_Component.h" +#include "profiling/yup_PaintProfiler.h" #include "menus/yup_PopupMenu.h" #include "buttons/yup_Button.h" #include "buttons/yup_TextButton.h" diff --git a/modules/yup_python/bindings/yup_YupGui_bindings.cpp b/modules/yup_python/bindings/yup_YupGui_bindings.cpp index e1ac2df3f..87d03bd0c 100644 --- a/modules/yup_python/bindings/yup_YupGui_bindings.cpp +++ b/modules/yup_python/bindings/yup_YupGui_bindings.cpp @@ -353,6 +353,9 @@ void registerYupGuiBindings (py::module_& m) // Keyboard focus .def ("setWantsKeyboardFocus", &Component::setWantsKeyboardFocus) + .def ("getWantsKeyboardFocus", &Component::getWantsKeyboardFocus) + .def ("setClickingGrabFocus", &Component::setClickingGrabFocus) + .def ("getClickingGrabFocus", &Component::getClickingGrabFocus) .def ("takeKeyboardFocus", &Component::takeKeyboardFocus) .def ("leaveKeyboardFocus", &Component::leaveKeyboardFocus) .def ("hasKeyboardFocus", &Component::hasKeyboardFocus) diff --git a/tests/yup_gui/yup_Component.cpp b/tests/yup_gui/yup_Component.cpp index 374ebb6ea..26a5338a2 100644 --- a/tests/yup_gui/yup_Component.cpp +++ b/tests/yup_gui/yup_Component.cpp @@ -813,7 +813,6 @@ TEST_F (ComponentTest, HitTesting) // ============================================================================= -/* TEST_F (ComponentTest, KeyboardFocus) { // Test default focus behavior @@ -825,7 +824,17 @@ TEST_F (ComponentTest, KeyboardFocus) child->setWantsKeyboardFocus (false); EXPECT_FALSE (child->getWantsKeyboardFocus()); } -*/ + +TEST_F (ComponentTest, ClickingGrabFocus) +{ + EXPECT_TRUE (child->getClickingGrabFocus()); + + child->setClickingGrabFocus (false); + EXPECT_FALSE (child->getClickingGrabFocus()); + + child->setClickingGrabFocus (true); + EXPECT_TRUE (child->getClickingGrabFocus()); +} // ============================================================================= diff --git a/tests/yup_gui/yup_PaintProfileStats.cpp b/tests/yup_gui/yup_PaintProfileStats.cpp new file mode 100644 index 000000000..301b9f16b --- /dev/null +++ b/tests/yup_gui/yup_PaintProfileStats.cpp @@ -0,0 +1,447 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include + +#include + +using namespace yup; + +namespace +{ + +PaintProfileSample makeSample (double totalMicros, + double selfMicros = 0.0, + double childrenMicros = 0.0) +{ + PaintProfileSample s; + s.totalMicros = totalMicros; + s.selfMicros = selfMicros; + s.childrenMicros = childrenMicros; + s.frameworkMicros = totalMicros - selfMicros - childrenMicros; + return s; +} + +} // namespace + +TEST (PaintProfileStatsTests, InitialStateIsEmpty) +{ + PaintProfileStats stats; + EXPECT_EQ (0, stats.getSampleCount()); + EXPECT_EQ (300, stats.getCapacity()); + EXPECT_EQ (0, stats.getLastSample().totalMicros); +} + +TEST (PaintProfileStatsTests, CapacityFromOptions) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 50; + PaintProfileStats stats (opts); + EXPECT_EQ (50, stats.getCapacity()); +} + +TEST (PaintProfileStatsTests, OptionsPreserved) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 100; + opts.minimumSampleMicros = 5.0; + opts.includeBounds = false; + PaintProfileStats stats (opts); + auto stored = stats.getOptions(); + EXPECT_EQ (100, stored.sampleCapacity); + EXPECT_DOUBLE_EQ (5.0, stored.minimumSampleMicros); + EXPECT_FALSE (stored.includeBounds); +} + +TEST (PaintProfileStatsTests, RecordingBelowCapacity) +{ + PaintProfileStats stats; + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + + EXPECT_EQ (3, stats.getSampleCount()); + + auto samples = stats.copySamples(); + ASSERT_EQ (3u, samples.size()); + EXPECT_DOUBLE_EQ (10.0, samples[0].totalMicros); + EXPECT_DOUBLE_EQ (20.0, samples[1].totalMicros); + EXPECT_DOUBLE_EQ (30.0, samples[2].totalMicros); +} + +TEST (PaintProfileStatsTests, LastSampleReturnsNewest) +{ + PaintProfileStats stats; + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + + EXPECT_DOUBLE_EQ (30.0, stats.getLastSample().totalMicros); +} + +TEST (PaintProfileStatsTests, RingBufferWrapsAtCapacity) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 5; + PaintProfileStats stats (opts); + + for (int i = 1; i <= 10; ++i) + stats.recordSample (makeSample (static_cast (i) * 10.0)); + + EXPECT_EQ (5, stats.getSampleCount()); + + auto samples = stats.copySamples(); + ASSERT_EQ (5u, samples.size()); + EXPECT_DOUBLE_EQ (60.0, samples[0].totalMicros); + EXPECT_DOUBLE_EQ (70.0, samples[1].totalMicros); + EXPECT_DOUBLE_EQ (80.0, samples[2].totalMicros); + EXPECT_DOUBLE_EQ (90.0, samples[3].totalMicros); + EXPECT_DOUBLE_EQ (100.0, samples[4].totalMicros); +} + +TEST (PaintProfileStatsTests, LastSampleAfterWrapping) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 3; + PaintProfileStats stats (opts); + + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + stats.recordSample (makeSample (40.0)); + stats.recordSample (makeSample (50.0)); + + EXPECT_DOUBLE_EQ (50.0, stats.getLastSample().totalMicros); +} + +TEST (PaintProfileStatsTests, ResetClearsSamples) +{ + PaintProfileStats stats; + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + + stats.reset(); + + EXPECT_EQ (0, stats.getSampleCount()); + EXPECT_EQ (300, stats.getCapacity()); + EXPECT_EQ (0, stats.getLastSample().totalMicros); +} + +TEST (PaintProfileStatsTests, ResetDoesNotChangeCapacity) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 50; + PaintProfileStats stats (opts); + stats.recordSample (makeSample (10.0)); + + stats.reset(); + + EXPECT_EQ (50, stats.getCapacity()); +} + +TEST (PaintProfileStatsTests, MinimumSampleThresholdFilters) +{ + PaintProfileOptions opts; + opts.minimumSampleMicros = 100.0; + PaintProfileStats stats (opts); + + stats.recordSample (makeSample (50.0)); + EXPECT_EQ (0, stats.getSampleCount()); + + stats.recordSample (makeSample (100.0)); + EXPECT_EQ (1, stats.getSampleCount()); + + stats.recordSample (makeSample (200.0)); + EXPECT_EQ (2, stats.getSampleCount()); + + stats.recordSample (makeSample (99.9)); + EXPECT_EQ (2, stats.getSampleCount()); +} + +TEST (PaintProfileStatsTests, SummarizeEmptyStatsReturnsZeros) +{ + PaintProfileStats stats; + + auto summary = stats.summarize (PaintProfileTimeKind::total); + + EXPECT_EQ (0, summary.sampleCount); + EXPECT_DOUBLE_EQ (0.0, summary.lastMicros); + EXPECT_DOUBLE_EQ (0.0, summary.minMicros); + EXPECT_DOUBLE_EQ (0.0, summary.maxMicros); + EXPECT_DOUBLE_EQ (0.0, summary.meanMicros); + EXPECT_DOUBLE_EQ (0.0, summary.p50Micros); + EXPECT_DOUBLE_EQ (0.0, summary.p95Micros); + EXPECT_DOUBLE_EQ (0.0, summary.p99Micros); +} + +TEST (PaintProfileStatsTests, SummarizeTotalMicros) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + stats.recordSample (makeSample (40.0)); + stats.recordSample (makeSample (50.0)); + + auto summary = stats.summarize (PaintProfileTimeKind::total); + + EXPECT_EQ (5, summary.sampleCount); + EXPECT_DOUBLE_EQ (50.0, summary.lastMicros); + EXPECT_DOUBLE_EQ (10.0, summary.minMicros); + EXPECT_DOUBLE_EQ (50.0, summary.maxMicros); + EXPECT_DOUBLE_EQ (30.0, summary.meanMicros); + EXPECT_DOUBLE_EQ (30.0, summary.p50Micros); + EXPECT_DOUBLE_EQ (50.0, summary.p95Micros); + EXPECT_DOUBLE_EQ (50.0, summary.p99Micros); +} + +TEST (PaintProfileStatsTests, SummarizeSelfMicros) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (100.0, 10.0, 50.0)); + stats.recordSample (makeSample (100.0, 20.0, 50.0)); + stats.recordSample (makeSample (100.0, 30.0, 50.0)); + stats.recordSample (makeSample (100.0, 40.0, 50.0)); + stats.recordSample (makeSample (100.0, 50.0, 50.0)); + + auto summary = stats.summarize (PaintProfileTimeKind::self); + + EXPECT_EQ (5, summary.sampleCount); + EXPECT_DOUBLE_EQ (50.0, summary.lastMicros); + EXPECT_DOUBLE_EQ (10.0, summary.minMicros); + EXPECT_DOUBLE_EQ (50.0, summary.maxMicros); + EXPECT_DOUBLE_EQ (30.0, summary.meanMicros); +} + +TEST (PaintProfileStatsTests, SummarizeChildrenMicros) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (100.0, 40.0, 10.0)); + stats.recordSample (makeSample (100.0, 40.0, 20.0)); + stats.recordSample (makeSample (100.0, 40.0, 30.0)); + stats.recordSample (makeSample (100.0, 40.0, 40.0)); + stats.recordSample (makeSample (100.0, 40.0, 50.0)); + + auto summary = stats.summarize (PaintProfileTimeKind::children); + + EXPECT_EQ (5, summary.sampleCount); + EXPECT_DOUBLE_EQ (50.0, summary.lastMicros); + EXPECT_DOUBLE_EQ (10.0, summary.minMicros); + EXPECT_DOUBLE_EQ (50.0, summary.maxMicros); + EXPECT_DOUBLE_EQ (30.0, summary.meanMicros); +} + +TEST (PaintProfileStatsTests, SummarizeFrameworkMicros) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (100.0, 50.0, 50.0)); + stats.recordSample (makeSample (100.0, 50.0, 40.0)); + stats.recordSample (makeSample (100.0, 50.0, 30.0)); + stats.recordSample (makeSample (100.0, 50.0, 20.0)); + stats.recordSample (makeSample (100.0, 50.0, 10.0)); + + auto summary = stats.summarize (PaintProfileTimeKind::framework); + + EXPECT_EQ (5, summary.sampleCount); + EXPECT_DOUBLE_EQ (40.0, summary.lastMicros); + EXPECT_DOUBLE_EQ (0.0, summary.minMicros); + EXPECT_DOUBLE_EQ (40.0, summary.maxMicros); +} + +TEST (PaintProfileStatsTests, CreateHistogramEmpty) +{ + PaintProfileStats stats; + + auto histogram = stats.createHistogram (PaintProfileTimeKind::total, 10); + + EXPECT_DOUBLE_EQ (0.0, histogram.rangeMinMicros); + EXPECT_DOUBLE_EQ (100.0, histogram.rangeMaxMicros); + ASSERT_EQ (10u, histogram.buckets.size()); + for (int count : histogram.buckets) + EXPECT_EQ (0, count); +} + +TEST (PaintProfileStatsTests, CreateHistogramCoversSamples) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + stats.recordSample (makeSample (40.0)); + stats.recordSample (makeSample (50.0)); + stats.recordSample (makeSample (60.0)); + stats.recordSample (makeSample (70.0)); + stats.recordSample (makeSample (80.0)); + stats.recordSample (makeSample (90.0)); + stats.recordSample (makeSample (100.0)); + + auto histogram = stats.createHistogram (PaintProfileTimeKind::total, 10); + + EXPECT_DOUBLE_EQ (0.0, histogram.rangeMinMicros); + EXPECT_GT (histogram.rangeMaxMicros, 0.0); + ASSERT_EQ (10u, histogram.buckets.size()); + + int totalCount = 0; + for (int count : histogram.buckets) + totalCount += count; + EXPECT_EQ (10, totalCount); +} + +TEST (PaintProfileStatsTests, CreateHistogramWithSelfMicros) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (100.0, 10.0, 40.0)); + stats.recordSample (makeSample (100.0, 20.0, 40.0)); + stats.recordSample (makeSample (100.0, 30.0, 40.0)); + stats.recordSample (makeSample (100.0, 40.0, 40.0)); + stats.recordSample (makeSample (100.0, 50.0, 40.0)); + + auto histogram = stats.createHistogram (PaintProfileTimeKind::self, 5); + + ASSERT_EQ (5u, histogram.buckets.size()); + int totalCount = 0; + for (int count : histogram.buckets) + totalCount += count; + EXPECT_EQ (5, totalCount); +} + +TEST (PaintProfileStatsTests, CopySamplesOrderAfterWrapping) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 3; + PaintProfileStats stats (opts); + + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + stats.recordSample (makeSample (40.0)); + stats.recordSample (makeSample (50.0)); + stats.recordSample (makeSample (60.0)); + + auto samples = stats.copySamples(); + + ASSERT_EQ (3u, samples.size()); + EXPECT_DOUBLE_EQ (40.0, samples[0].totalMicros); + EXPECT_DOUBLE_EQ (50.0, samples[1].totalMicros); + EXPECT_DOUBLE_EQ (60.0, samples[2].totalMicros); +} + +TEST (PaintProfileStatsTests, SingleSampleStatistics) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (42.0)); + + auto summary = stats.summarize (PaintProfileTimeKind::total); + + EXPECT_EQ (1, summary.sampleCount); + EXPECT_DOUBLE_EQ (42.0, summary.lastMicros); + EXPECT_DOUBLE_EQ (42.0, summary.minMicros); + EXPECT_DOUBLE_EQ (42.0, summary.maxMicros); + EXPECT_DOUBLE_EQ (42.0, summary.meanMicros); + EXPECT_DOUBLE_EQ (42.0, summary.p50Micros); + EXPECT_DOUBLE_EQ (42.0, summary.p95Micros); + EXPECT_DOUBLE_EQ (42.0, summary.p99Micros); +} + +TEST (PaintProfileStatsTests, ResetAfterWrapping) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 2; + PaintProfileStats stats (opts); + + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + + stats.reset(); + + EXPECT_EQ (0, stats.getSampleCount()); + auto samples = stats.copySamples(); + EXPECT_TRUE (samples.empty()); +} + +TEST (PaintProfileStatsTests, MinimumThresholdZeroRecordsAll) +{ + PaintProfileOptions opts; + opts.minimumSampleMicros = 0.0; + PaintProfileStats stats (opts); + + stats.recordSample (makeSample (0.0)); + stats.recordSample (makeSample (0.001)); + stats.recordSample (makeSample (1000.0)); + + EXPECT_EQ (3, stats.getSampleCount()); +} + +TEST (PaintProfileStatsTests, HistogramBucketCountMatches) +{ + PaintProfileStats stats; + + for (int i = 1; i <= 50; ++i) + stats.recordSample (makeSample (static_cast (i))); + + auto hist5 = stats.createHistogram (PaintProfileTimeKind::total, 5); + auto hist20 = stats.createHistogram (PaintProfileTimeKind::total, 20); + + EXPECT_EQ (5u, hist5.buckets.size()); + EXPECT_EQ (20u, hist20.buckets.size()); +} + +TEST (PaintProfileStatsTests, SummarizePercentileOrdering) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + stats.recordSample (makeSample (30.0)); + stats.recordSample (makeSample (40.0)); + stats.recordSample (makeSample (50.0)); + + auto summary = stats.summarize (PaintProfileTimeKind::total); + + EXPECT_LE (summary.minMicros, summary.p50Micros); + EXPECT_LE (summary.p50Micros, summary.p95Micros); + EXPECT_LE (summary.p95Micros, summary.p99Micros); + EXPECT_LE (summary.p99Micros, summary.maxMicros); +} + +TEST (PaintProfileStatsTests, CopySamplesDoesNotModifyState) +{ + PaintProfileStats stats; + + stats.recordSample (makeSample (10.0)); + stats.recordSample (makeSample (20.0)); + + auto first = stats.copySamples(); + auto second = stats.copySamples(); + + ASSERT_EQ (first.size(), second.size()); + for (size_t i = 0; i < first.size(); ++i) + EXPECT_DOUBLE_EQ (first[i].totalMicros, second[i].totalMicros); +} From 0af9eb97248c93545f68e7223f111aede9e26643 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 20 May 2026 12:23:32 +0200 Subject: [PATCH 2/7] Fix compilation --- modules/yup_gui/component/yup_Component.cpp | 2 ++ modules/yup_gui/profiling/yup_PaintProfiler.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/modules/yup_gui/component/yup_Component.cpp b/modules/yup_gui/component/yup_Component.cpp index 2a22232f1..8f61b7ed5 100644 --- a/modules/yup_gui/component/yup_Component.cpp +++ b/modules/yup_gui/component/yup_Component.cpp @@ -1382,7 +1382,9 @@ void Component::internalPaint (Graphics& g, const Rectangle& repaintArea, else { if (profilingActive) + { YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.markSelfPaintSkipped();) + } } for (auto child : children) diff --git a/modules/yup_gui/profiling/yup_PaintProfiler.cpp b/modules/yup_gui/profiling/yup_PaintProfiler.cpp index 93b670714..edf28f1dd 100644 --- a/modules/yup_gui/profiling/yup_PaintProfiler.cpp +++ b/modules/yup_gui/profiling/yup_PaintProfiler.cpp @@ -102,7 +102,9 @@ void PaintProfiler::deregisterComponent (const Component& component) void PaintProfiler::enableSubtree (Component& root, PaintProfileOptions options) { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING root.setPaintProfilingEnabled (true, options); +#endif for (int i = 0; i < root.getNumChildComponents(); ++i) { @@ -113,7 +115,9 @@ void PaintProfiler::enableSubtree (Component& root, PaintProfileOptions options) void PaintProfiler::disableSubtree (Component& root) { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING root.setPaintProfilingEnabled (false); +#endif for (int i = 0; i < root.getNumChildComponents(); ++i) { @@ -182,7 +186,11 @@ PaintProfiler::Snapshot PaintProfiler::createSnapshot (PaintProfileTimeKind sort { ComponentEntry entry; entry.component = component; +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING entry.name = component->getPaintProfileName(); +#else + entry.name = component->getTitle(); +#endif entry.stats = stats; entry.self = stats->summarize (PaintProfileTimeKind::self); entry.children = stats->summarize (PaintProfileTimeKind::children); @@ -275,11 +283,13 @@ PaintProfiler::ScopedSession::ScopedSession (PaintProfiler& profilerRef, PaintProfiler::ScopedSession::~ScopedSession() { +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING for (auto& weakComponent : enabledComponents) { if (auto* component = weakComponent.get()) component->setPaintProfilingEnabled (false); } +#endif } //============================================================================== From eb5febc83952c4ef91d7e467197b25a7c4a4888e Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 20 May 2026 12:31:02 +0200 Subject: [PATCH 3/7] More fixes --- .../yup_gui/profiling/yup_PaintProfiler.cpp | 10 --------- modules/yup_gui/yup_gui.cpp | 9 ++++++-- modules/yup_gui/yup_gui.h | 21 ++++++++++++------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/yup_gui/profiling/yup_PaintProfiler.cpp b/modules/yup_gui/profiling/yup_PaintProfiler.cpp index edf28f1dd..93b670714 100644 --- a/modules/yup_gui/profiling/yup_PaintProfiler.cpp +++ b/modules/yup_gui/profiling/yup_PaintProfiler.cpp @@ -102,9 +102,7 @@ void PaintProfiler::deregisterComponent (const Component& component) void PaintProfiler::enableSubtree (Component& root, PaintProfileOptions options) { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING root.setPaintProfilingEnabled (true, options); -#endif for (int i = 0; i < root.getNumChildComponents(); ++i) { @@ -115,9 +113,7 @@ void PaintProfiler::enableSubtree (Component& root, PaintProfileOptions options) void PaintProfiler::disableSubtree (Component& root) { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING root.setPaintProfilingEnabled (false); -#endif for (int i = 0; i < root.getNumChildComponents(); ++i) { @@ -186,11 +182,7 @@ PaintProfiler::Snapshot PaintProfiler::createSnapshot (PaintProfileTimeKind sort { ComponentEntry entry; entry.component = component; -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING entry.name = component->getPaintProfileName(); -#else - entry.name = component->getTitle(); -#endif entry.stats = stats; entry.self = stats->summarize (PaintProfileTimeKind::self); entry.children = stats->summarize (PaintProfileTimeKind::children); @@ -283,13 +275,11 @@ PaintProfiler::ScopedSession::ScopedSession (PaintProfiler& profilerRef, PaintProfiler::ScopedSession::~ScopedSession() { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING for (auto& weakComponent : enabledComponents) { if (auto* component = weakComponent.get()) component->setPaintProfilingEnabled (false); } -#endif } //============================================================================== diff --git a/modules/yup_gui/yup_gui.cpp b/modules/yup_gui/yup_gui.cpp index c905dbcca..e5cd93222 100644 --- a/modules/yup_gui/yup_gui.cpp +++ b/modules/yup_gui/yup_gui.cpp @@ -125,6 +125,13 @@ //============================================================================== +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING +#include "profiling/yup_PaintProfileStats.cpp" +#include "profiling/yup_PaintProfiler.cpp" +#endif + +//============================================================================== + #include "application/yup_Application.cpp" #include "desktop/yup_Desktop.cpp" #include "keyboard/yup_TextInputTarget.cpp" @@ -133,8 +140,6 @@ #include "clipboard/yup_SystemClipboard.cpp" #include "component/yup_ComponentNative.cpp" #include "component/yup_Component.cpp" -#include "profiling/yup_PaintProfileStats.cpp" -#include "profiling/yup_PaintProfiler.cpp" #include "menus/yup_PopupMenu.cpp" #include "buttons/yup_Button.cpp" #include "buttons/yup_TextButton.cpp" diff --git a/modules/yup_gui/yup_gui.h b/modules/yup_gui/yup_gui.h index 309f4ceb3..382c145dc 100644 --- a/modules/yup_gui/yup_gui.h +++ b/modules/yup_gui/yup_gui.h @@ -80,19 +80,21 @@ //============================================================================== +#include +#include + +//============================================================================== + #if YUP_ENABLE_COMPONENT_PAINT_PROFILING #define YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED(CODE) CODE +#include "profiling/yup_PaintProfileSample.h" +#include "profiling/yup_PaintProfileStats.h" #else #define YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED(CODE) #endif //============================================================================== -#include -#include - -//============================================================================== - #include "application/yup_Application.h" #include "keyboard/yup_KeyModifiers.h" #include "keyboard/yup_KeyPress.h" @@ -104,12 +106,9 @@ #include "clipboard/yup_SystemClipboard.h" #include "desktop/yup_Screen.h" #include "desktop/yup_Desktop.h" -#include "profiling/yup_PaintProfileSample.h" -#include "profiling/yup_PaintProfileStats.h" #include "component/yup_ComponentNative.h" #include "component/yup_ComponentStyle.h" #include "component/yup_Component.h" -#include "profiling/yup_PaintProfiler.h" #include "menus/yup_PopupMenu.h" #include "buttons/yup_Button.h" #include "buttons/yup_TextButton.h" @@ -131,6 +130,12 @@ //============================================================================== +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING +#include "profiling/yup_PaintProfiler.h" +#endif + +//============================================================================== + #include "native/yup_WindowingHelpers.h" //============================================================================== From c055690d790a63f7a8b3efc3eb972105be1ba895 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 20 May 2026 13:05:48 +0200 Subject: [PATCH 4/7] More tests --- modules/yup_gui/component/yup_Component.cpp | 23 +- modules/yup_gui/component/yup_Component.h | 3 + .../profiling/yup_PaintProfileSample.h | 15 + tests/CMakeLists.txt | 1 + tests/yup_gui.cpp | 1 + tests/yup_gui/yup_PaintProfiler.cpp | 557 ++++++++++++++++++ 6 files changed, 586 insertions(+), 14 deletions(-) create mode 100644 tests/yup_gui/yup_PaintProfiler.cpp diff --git a/modules/yup_gui/component/yup_Component.cpp b/modules/yup_gui/component/yup_Component.cpp index 8f61b7ed5..2583cb671 100644 --- a/modules/yup_gui/component/yup_Component.cpp +++ b/modules/yup_gui/component/yup_Component.cpp @@ -1210,15 +1210,10 @@ String Component::getPaintProfileName() const return "Component"; } -//============================================================================== +thread_local std::vector Component::paintProfileScopeStack {}; +std::atomic Component::globalPaintIndexCounter { 0 }; -struct PaintProfileScopeEntry -{ - double childrenMicros = 0.0; -}; - -thread_local std::vector paintProfileScopeStack; -static std::atomic globalPaintIndexCounter { 0 }; +//============================================================================== class PaintProfileScope { @@ -1233,20 +1228,20 @@ class PaintProfileScope , selfStartMicros (0.0) { sample.frameIndex = frameIndex; - sample.paintIndex = globalPaintIndexCounter.fetch_add (1, std::memory_order_relaxed); + sample.paintIndex = Component::globalPaintIndexCounter.fetch_add (1, std::memory_order_relaxed); sample.repaintArea = repaintArea; sample.componentBounds = component.getBoundsRelativeToTopLevelComponent().to(); sample.renderContinuous = renderContinuous; - paintProfileScopeStack.push_back ({}); + Component::paintProfileScopeStack.push_back ({}); } ~PaintProfileScope() { const double totalEndMicros = ticksToMicros (Time::getHighResolutionTicks()); sample.totalMicros = totalEndMicros - totalStartMicros; - sample.childrenMicros = paintProfileScopeStack.back().childrenMicros; - paintProfileScopeStack.pop_back(); + sample.childrenMicros = Component::paintProfileScopeStack.back().childrenMicros; + Component::paintProfileScopeStack.pop_back(); sample.frameworkMicros = std::max (0.0, sample.totalMicros @@ -1256,8 +1251,8 @@ class PaintProfileScope if (auto* stats = component.getPaintProfileStats()) stats->recordSample (sample); - if (! paintProfileScopeStack.empty()) - paintProfileScopeStack.back().childrenMicros += sample.totalMicros; + if (! Component::paintProfileScopeStack.empty()) + Component::paintProfileScopeStack.back().childrenMicros += sample.totalMicros; } void beginSelf() diff --git a/modules/yup_gui/component/yup_Component.h b/modules/yup_gui/component/yup_Component.h index e925051d9..8c7a0862f 100644 --- a/modules/yup_gui/component/yup_Component.h +++ b/modules/yup_gui/component/yup_Component.h @@ -1351,7 +1351,10 @@ class YUP_API Component : public MouseListener #endif #if YUP_ENABLE_COMPONENT_PAINT_PROFILING + friend class PaintProfileScope; std::unique_ptr paintProfileStats; + static thread_local std::vector paintProfileScopeStack; + static std::atomic globalPaintIndexCounter; #endif YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Component) diff --git a/modules/yup_gui/profiling/yup_PaintProfileSample.h b/modules/yup_gui/profiling/yup_PaintProfileSample.h index 8aeee7d74..494a4b8a4 100644 --- a/modules/yup_gui/profiling/yup_PaintProfileSample.h +++ b/modules/yup_gui/profiling/yup_PaintProfileSample.h @@ -135,6 +135,21 @@ struct PaintProfileSummary //============================================================================== +/** A struct used to track the cumulative child time of nested paint calls in the current call stack. + + This is stored in a thread_local stack in Component, and each PaintProfileScope pushes a new entry on + construction and pops it on destruction. The self time of a scope is accumulated separately, and the total + time of the scope is added to the parent's childrenMicros when the scope ends, so that the sum of selfMicros + and childrenMicros for a parent scope equals the total time spent in that subtree of the paint call graph. +*/ +struct PaintProfileScopeEntry +{ + /** Cumulative time spent in child paint calls for the current scope. */ + double childrenMicros = 0.0; +}; + +//============================================================================== + /** A linear histogram of sample values for a single PaintProfileTimeKind field. The range [rangeMinMicros, rangeMaxMicros] is divided into buckets.size() equal-width diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2faad6c3b..bb42fddef 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -123,6 +123,7 @@ yup_standalone_app ( TARGET_CONSOLE ${target_console} DEFINITIONS YUP_USE_CURL=0 + YUP_ENABLE_COMPONENT_PAINT_PROFILING=1 YUP_MODAL_LOOPS_PERMITTED=1 PRELOAD_FILES ${target_preloaded} diff --git a/tests/yup_gui.cpp b/tests/yup_gui.cpp index 5467ea7a0..78c0b8b96 100644 --- a/tests/yup_gui.cpp +++ b/tests/yup_gui.cpp @@ -26,6 +26,7 @@ #include "yup_gui/yup_FileChooser.cpp" #include "yup_gui/yup_Label.cpp" #include "yup_gui/yup_ListBox.cpp" +#include "yup_gui/yup_PaintProfiler.cpp" #include "yup_gui/yup_PopupMenu.cpp" #include "yup_gui/yup_ProgressBar.cpp" #include "yup_gui/yup_ScrollBar.cpp" diff --git a/tests/yup_gui/yup_PaintProfiler.cpp b/tests/yup_gui/yup_PaintProfiler.cpp new file mode 100644 index 000000000..5489d4d20 --- /dev/null +++ b/tests/yup_gui/yup_PaintProfiler.cpp @@ -0,0 +1,557 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +#include + +#include + +using namespace yup; + +namespace +{ + +PaintProfileSample makeSample (double totalMicros, + double selfMicros = 0.0, + double childrenMicros = 0.0) +{ + PaintProfileSample s; + s.totalMicros = totalMicros; + s.selfMicros = selfMicros; + s.childrenMicros = childrenMicros; + s.frameworkMicros = totalMicros - selfMicros - childrenMicros; + return s; +} + +} // namespace + +// ============================================================================= +// Component profiling API tests +// ============================================================================= + +TEST (ComponentProfilingTests, ProfilingDisabledByDefault) +{ + Component comp; + + EXPECT_FALSE (comp.isPaintProfilingEnabled()); + EXPECT_EQ (nullptr, comp.getPaintProfileStats()); +} + +TEST (ComponentProfilingTests, EnableProfilingCreatesStats) +{ + Component comp; + comp.setPaintProfilingEnabled (true); + + EXPECT_TRUE (comp.isPaintProfilingEnabled()); + EXPECT_NE (nullptr, comp.getPaintProfileStats()); +} + +TEST (ComponentProfilingTests, DisableProfilingClearsStats) +{ + Component comp; + comp.setPaintProfilingEnabled (true); + comp.setPaintProfilingEnabled (false); + + EXPECT_FALSE (comp.isPaintProfilingEnabled()); + EXPECT_EQ (nullptr, comp.getPaintProfileStats()); +} + +TEST (ComponentProfilingTests, ReEnableProfilingAfterDisable) +{ + Component comp; + comp.setPaintProfilingEnabled (true); + comp.setPaintProfilingEnabled (false); + comp.setPaintProfilingEnabled (true); + + EXPECT_TRUE (comp.isPaintProfilingEnabled()); + EXPECT_NE (nullptr, comp.getPaintProfileStats()); +} + +TEST (ComponentProfilingTests, ResetProfilingClearsSamples) +{ + Component comp; + comp.setPaintProfilingEnabled (true); + + auto* stats = comp.getPaintProfileStats(); + stats->recordSample (makeSample (10.0)); + stats->recordSample (makeSample (20.0)); + ASSERT_EQ (2, stats->getSampleCount()); + + comp.resetPaintProfiling(); + + EXPECT_EQ (0, comp.getPaintProfileStats()->getSampleCount()); + EXPECT_TRUE (comp.isPaintProfilingEnabled()); +} + +TEST (ComponentProfilingTests, ResetProfilingOnDisabledComponentIsNoOp) +{ + Component comp; + + EXPECT_NO_FATAL_FAILURE (comp.resetPaintProfiling()); + EXPECT_EQ (nullptr, comp.getPaintProfileStats()); +} + +TEST (ComponentProfilingTests, OptionsPreservedOnEnable) +{ + PaintProfileOptions opts; + opts.sampleCapacity = 50; + opts.minimumSampleMicros = 5.0; + opts.includeBounds = false; + + Component comp; + comp.setPaintProfilingEnabled (true, opts); + + auto* stats = comp.getPaintProfileStats(); + ASSERT_NE (nullptr, stats); + + auto stored = stats->getOptions(); + EXPECT_EQ (50, stored.sampleCapacity); + EXPECT_DOUBLE_EQ (5.0, stored.minimumSampleMicros); + EXPECT_FALSE (stored.includeBounds); +} + +TEST (ComponentProfilingTests, GetPaintProfileNameFromTitle) +{ + Component comp; + comp.setTitle ("MyComponent"); + + EXPECT_EQ ("MyComponent", comp.getPaintProfileName()); +} + +TEST (ComponentProfilingTests, GetPaintProfileNameFromID) +{ + Component comp ("myID"); + + EXPECT_EQ ("myID", comp.getPaintProfileName()); +} + +TEST (ComponentProfilingTests, GetPaintProfileNameFallback) +{ + Component comp; + + EXPECT_EQ ("Component", comp.getPaintProfileName()); +} + +TEST (ComponentProfilingTests, GetPaintProfileNamePrefersTitle) +{ + Component comp ("myID"); + comp.setTitle ("MyTitle"); + + EXPECT_EQ ("MyTitle", comp.getPaintProfileName()); +} + +// ============================================================================= +// PaintProfiler singleton tests +// ============================================================================= + +class PaintProfilerFixture : public ::testing::Test +{ +protected: + void SetUp() override + { + profiler = &PaintProfiler::getInstance(); + profiler->setEnabled (true); + profiler->resetAll(); + } + + PaintProfiler* profiler = nullptr; +}; + +TEST_F (PaintProfilerFixture, SingletonReturnsSameInstance) +{ + EXPECT_EQ (&PaintProfiler::getInstance(), &PaintProfiler::getInstance()); +} + +TEST_F (PaintProfilerFixture, IsEnabledAfterSetupReset) +{ + EXPECT_TRUE (profiler->isEnabled()); +} + +TEST_F (PaintProfilerFixture, SetEnabledFalseDisables) +{ + profiler->setEnabled (false); + + EXPECT_FALSE (profiler->isEnabled()); +} + +TEST_F (PaintProfilerFixture, SetEnabledTrueRenables) +{ + profiler->setEnabled (false); + profiler->setEnabled (true); + + EXPECT_TRUE (profiler->isEnabled()); +} + +TEST_F (PaintProfilerFixture, EnableSubtreeEnablesRoot) +{ + Component root; + + profiler->enableSubtree (root); + + EXPECT_TRUE (root.isPaintProfilingEnabled()); + EXPECT_NE (nullptr, root.getPaintProfileStats()); +} + +TEST_F (PaintProfilerFixture, EnableSubtreeEnablesChildren) +{ + Component root; + Component child; + root.addChildComponent (child); + + profiler->enableSubtree (root); + + EXPECT_TRUE (root.isPaintProfilingEnabled()); + EXPECT_TRUE (child.isPaintProfilingEnabled()); +} + +TEST_F (PaintProfilerFixture, EnableSubtreeEnablesDeepHierarchy) +{ + Component root; + Component mid; + Component leaf; + root.addChildComponent (mid); + mid.addChildComponent (leaf); + + profiler->enableSubtree (root); + + EXPECT_TRUE (root.isPaintProfilingEnabled()); + EXPECT_TRUE (mid.isPaintProfilingEnabled()); + EXPECT_TRUE (leaf.isPaintProfilingEnabled()); +} + +TEST_F (PaintProfilerFixture, DisableSubtreeDisablesRootAndChildren) +{ + Component root; + Component child; + root.addChildComponent (child); + + profiler->enableSubtree (root); + profiler->disableSubtree (root); + + EXPECT_FALSE (root.isPaintProfilingEnabled()); + EXPECT_FALSE (child.isPaintProfilingEnabled()); +} + +TEST_F (PaintProfilerFixture, ResetSubtreeResetsRootStats) +{ + Component root; + profiler->enableSubtree (root); + + auto* stats = root.getPaintProfileStats(); + stats->recordSample (makeSample (10.0)); + stats->recordSample (makeSample (20.0)); + ASSERT_EQ (2, stats->getSampleCount()); + + profiler->resetSubtree (root); + + EXPECT_EQ (0, root.getPaintProfileStats()->getSampleCount()); +} + +TEST_F (PaintProfilerFixture, ResetSubtreeResetsChildStats) +{ + Component root; + Component child; + root.addChildComponent (child); + profiler->enableSubtree (root); + + child.getPaintProfileStats()->recordSample (makeSample (15.0)); + ASSERT_EQ (1, child.getPaintProfileStats()->getSampleCount()); + + profiler->resetSubtree (root); + + EXPECT_EQ (0, child.getPaintProfileStats()->getSampleCount()); +} + +TEST_F (PaintProfilerFixture, ResetAllClearsAllRegisteredStats) +{ + Component comp1; + Component comp2; + profiler->enableSubtree (comp1); + profiler->enableSubtree (comp2); + + comp1.getPaintProfileStats()->recordSample (makeSample (10.0)); + comp2.getPaintProfileStats()->recordSample (makeSample (20.0)); + + profiler->resetAll(); + + EXPECT_EQ (0, comp1.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (0, comp2.getPaintProfileStats()->getSampleCount()); +} + +TEST_F (PaintProfilerFixture, SnapshotEmptyWithNoRegisteredComponents) +{ + auto snapshot = profiler->createSnapshot(); + + EXPECT_TRUE (snapshot.components.empty()); +} + +TEST_F (PaintProfilerFixture, SnapshotContainsRegisteredComponents) +{ + Component comp1 ("comp1"); + Component comp2 ("comp2"); + profiler->enableSubtree (comp1); + profiler->enableSubtree (comp2); + + auto snapshot = profiler->createSnapshot(); + + EXPECT_EQ (2u, snapshot.components.size()); +} + +TEST_F (PaintProfilerFixture, SnapshotHasComponentNames) +{ + Component comp ("named"); + profiler->enableSubtree (comp); + + auto snapshot = profiler->createSnapshot(); + + ASSERT_EQ (1u, snapshot.components.size()); + EXPECT_EQ ("named", snapshot.components[0].name); +} + +TEST_F (PaintProfilerFixture, SnapshotSortedByP95TotalDescending) +{ + Component slow; + Component fast; + profiler->enableSubtree (slow); + profiler->enableSubtree (fast); + + for (int i = 0; i < 5; ++i) + slow.getPaintProfileStats()->recordSample (makeSample (100.0)); + + for (int i = 0; i < 5; ++i) + fast.getPaintProfileStats()->recordSample (makeSample (10.0)); + + auto snapshot = profiler->createSnapshot (PaintProfileTimeKind::total); + + ASSERT_EQ (2u, snapshot.components.size()); + EXPECT_GE (snapshot.components[0].total.p95Micros, snapshot.components[1].total.p95Micros); +} + +TEST_F (PaintProfilerFixture, SnapshotSortedByP95SelfDescending) +{ + Component highSelf; + Component lowSelf; + profiler->enableSubtree (highSelf); + profiler->enableSubtree (lowSelf); + + for (int i = 0; i < 5; ++i) + highSelf.getPaintProfileStats()->recordSample (makeSample (100.0, 80.0, 10.0)); + + for (int i = 0; i < 5; ++i) + lowSelf.getPaintProfileStats()->recordSample (makeSample (100.0, 10.0, 80.0)); + + auto snapshot = profiler->createSnapshot (PaintProfileTimeKind::self); + + ASSERT_EQ (2u, snapshot.components.size()); + EXPECT_GE (snapshot.components[0].self.p95Micros, snapshot.components[1].self.p95Micros); +} + +TEST_F (PaintProfilerFixture, SnapshotSortedByP95ChildrenDescending) +{ + Component highChildren; + Component lowChildren; + profiler->enableSubtree (highChildren); + profiler->enableSubtree (lowChildren); + + for (int i = 0; i < 5; ++i) + highChildren.getPaintProfileStats()->recordSample (makeSample (100.0, 10.0, 80.0)); + + for (int i = 0; i < 5; ++i) + lowChildren.getPaintProfileStats()->recordSample (makeSample (100.0, 80.0, 10.0)); + + auto snapshot = profiler->createSnapshot (PaintProfileTimeKind::children); + + ASSERT_EQ (2u, snapshot.components.size()); + EXPECT_GE (snapshot.components[0].children.p95Micros, snapshot.components[1].children.p95Micros); +} + +TEST_F (PaintProfilerFixture, SnapshotContainsComponentPointers) +{ + Component comp; + profiler->enableSubtree (comp); + + auto snapshot = profiler->createSnapshot(); + + ASSERT_EQ (1u, snapshot.components.size()); + EXPECT_EQ (&comp, snapshot.components[0].component); +} + +TEST_F (PaintProfilerFixture, SnapshotHasFrameIndex) +{ + profiler->beginFrame(); + uint64 expectedFrameIndex = profiler->getCurrentFrameIndex(); + + Component comp; + profiler->enableSubtree (comp); + + auto snapshot = profiler->createSnapshot(); + + EXPECT_EQ (expectedFrameIndex, snapshot.frameIndex); +} + +TEST_F (PaintProfilerFixture, HistogramForUnregisteredComponentIsDefault) +{ + Component comp; + + auto histogram = profiler->createHistogramForComponent (comp, PaintProfileTimeKind::total, 10); + + EXPECT_DOUBLE_EQ (0.0, histogram.rangeMinMicros); + EXPECT_DOUBLE_EQ (0.0, histogram.rangeMaxMicros); + EXPECT_TRUE (histogram.buckets.empty()); +} + +TEST_F (PaintProfilerFixture, HistogramForRegisteredComponentContainsAllSamples) +{ + Component comp; + profiler->enableSubtree (comp); + + auto* stats = comp.getPaintProfileStats(); + for (int i = 1; i <= 5; ++i) + stats->recordSample (makeSample (static_cast (i) * 10.0)); + + auto histogram = profiler->createHistogramForComponent (comp, PaintProfileTimeKind::total, 5); + + ASSERT_EQ (5u, histogram.buckets.size()); + + int total = 0; + for (int count : histogram.buckets) + total += count; + + EXPECT_EQ (5, total); +} + +TEST_F (PaintProfilerFixture, StartSessionEnablesRootAndChildren) +{ + Component root; + Component child; + root.addChildComponent (child); + + auto session = profiler->startSession (root); + + EXPECT_TRUE (root.isPaintProfilingEnabled()); + EXPECT_TRUE (child.isPaintProfilingEnabled()); +} + +TEST_F (PaintProfilerFixture, ScopedSessionDestructorDisablesProfiling) +{ + Component root; + + { + auto session = profiler->startSession (root); + EXPECT_TRUE (root.isPaintProfilingEnabled()); + } + + EXPECT_FALSE (root.isPaintProfilingEnabled()); +} + +TEST_F (PaintProfilerFixture, ScopedSessionDestructorDisablesChildren) +{ + Component root; + Component child; + root.addChildComponent (child); + + { + auto session = profiler->startSession (root); + EXPECT_TRUE (child.isPaintProfilingEnabled()); + } + + EXPECT_FALSE (child.isPaintProfilingEnabled()); +} + +TEST_F (PaintProfilerFixture, ScopedSessionInitiallyNotPaused) +{ + Component root; + auto session = profiler->startSession (root); + + EXPECT_FALSE (session->isPaused()); +} + +TEST_F (PaintProfilerFixture, ScopedSessionPauseAndResume) +{ + Component root; + auto session = profiler->startSession (root); + + session->setPaused (true); + EXPECT_TRUE (session->isPaused()); + + session->setPaused (false); + EXPECT_FALSE (session->isPaused()); +} + +TEST_F (PaintProfilerFixture, ScopedSessionResetClearsStats) +{ + Component root; + auto session = profiler->startSession (root); + + auto* stats = root.getPaintProfileStats(); + stats->recordSample (makeSample (10.0)); + stats->recordSample (makeSample (20.0)); + ASSERT_EQ (2, stats->getSampleCount()); + + session->reset(); + + EXPECT_EQ (0, root.getPaintProfileStats()->getSampleCount()); +} + +TEST_F (PaintProfilerFixture, ScopedSessionCreateSnapshotReflectsRegisteredComponents) +{ + Component root ("root"); + auto session = profiler->startSession (root); + + auto snapshot = session->createSnapshot(); + + ASSERT_EQ (1u, snapshot.components.size()); + EXPECT_EQ ("root", snapshot.components[0].name); +} + +TEST_F (PaintProfilerFixture, BeginFrameIncrementsFrameIndex) +{ + uint64 before = profiler->getCurrentFrameIndex(); + profiler->beginFrame(); + uint64 after = profiler->getCurrentFrameIndex(); + + EXPECT_EQ (before + 1, after); +} + +TEST_F (PaintProfilerFixture, EndFrameRecordsGlobalFrameSample) +{ + profiler->beginFrame(); + profiler->endFrame(); + + auto snapshot = profiler->createSnapshot(); + + EXPECT_EQ (1, snapshot.globalFrameTotal.sampleCount); + EXPECT_GE (snapshot.globalFrameTotal.lastMicros, 0.0); +} + +TEST_F (PaintProfilerFixture, MultipleFramesAccumulateGlobalStats) +{ + constexpr int frameCount = 5; + + for (int i = 0; i < frameCount; ++i) + { + profiler->beginFrame(); + profiler->endFrame(); + } + + auto snapshot = profiler->createSnapshot(); + + EXPECT_EQ (frameCount, snapshot.globalFrameTotal.sampleCount); +} From 312cef01eb258813699592bd1ea9a36c48d032dc Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 20 May 2026 15:23:58 +0200 Subject: [PATCH 5/7] Fix profile tests --- modules/yup_gui/component/yup_Component.cpp | 23 ++- modules/yup_gui/component/yup_Component.h | 1 + tests/yup_gui/yup_PaintProfiler.cpp | 180 ++++++++++++++++++++ 3 files changed, 196 insertions(+), 8 deletions(-) diff --git a/modules/yup_gui/component/yup_Component.cpp b/modules/yup_gui/component/yup_Component.cpp index 2583cb671..2e9d39434 100644 --- a/modules/yup_gui/component/yup_Component.cpp +++ b/modules/yup_gui/component/yup_Component.cpp @@ -1169,6 +1169,7 @@ void Component::setPaintProfilingEnabled (bool shouldBeEnabled, PaintProfileOpti { paintProfileStats = std::make_unique (options); } + PaintProfiler::getInstance().registerComponent (*this, *paintProfileStats); } else @@ -1221,11 +1222,13 @@ class PaintProfileScope PaintProfileScope (Component& component, const Rectangle& repaintArea, bool renderContinuous, - uint64 frameIndex) + uint64 frameIndex, + bool profilingActive) : component (component) , sample() , totalStartMicros (ticksToMicros (Time::getHighResolutionTicks())) , selfStartMicros (0.0) + , profilingActive (profilingActive) { sample.frameIndex = frameIndex; sample.paintIndex = Component::globalPaintIndexCounter.fetch_add (1, std::memory_order_relaxed); @@ -1243,13 +1246,16 @@ class PaintProfileScope sample.childrenMicros = Component::paintProfileScopeStack.back().childrenMicros; Component::paintProfileScopeStack.pop_back(); - sample.frameworkMicros = std::max (0.0, - sample.totalMicros - - sample.selfMicros - - sample.childrenMicros); + if (profilingActive) + { + sample.frameworkMicros = std::max (0.0, + sample.totalMicros + - sample.selfMicros + - sample.childrenMicros); - if (auto* stats = component.getPaintProfileStats()) - stats->recordSample (sample); + if (auto* stats = component.getPaintProfileStats()) + stats->recordSample (sample); + } if (! Component::paintProfileScopeStack.empty()) Component::paintProfileScopeStack.back().childrenMicros += sample.totalMicros; @@ -1280,6 +1286,7 @@ class PaintProfileScope PaintProfileSample sample; double totalStartMicros; double selfStartMicros; + bool profilingActive; YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaintProfileScope) }; @@ -1341,7 +1348,7 @@ void Component::internalPaint (Graphics& g, const Rectangle& repaintArea, const bool profilingActive = PaintProfiler::getInstance().isEnabled() && paintProfileStats != nullptr; const auto frameIndex = PaintProfiler::getInstance().getCurrentFrameIndex(); - PaintProfileScope profileScope (*this, repaintArea, renderContinuous, frameIndex); + PaintProfileScope profileScope (*this, repaintArea, renderContinuous, frameIndex, profilingActive); #else constexpr bool profilingActive = false; #endif diff --git a/modules/yup_gui/component/yup_Component.h b/modules/yup_gui/component/yup_Component.h index 8c7a0862f..54911acec 100644 --- a/modules/yup_gui/component/yup_Component.h +++ b/modules/yup_gui/component/yup_Component.h @@ -1352,6 +1352,7 @@ class YUP_API Component : public MouseListener #if YUP_ENABLE_COMPONENT_PAINT_PROFILING friend class PaintProfileScope; + friend class ComponentPaintProfileTestHelper; std::unique_ptr paintProfileStats; static thread_local std::vector paintProfileScopeStack; static std::atomic globalPaintIndexCounter; diff --git a/tests/yup_gui/yup_PaintProfiler.cpp b/tests/yup_gui/yup_PaintProfiler.cpp index 5489d4d20..f2b4923de 100644 --- a/tests/yup_gui/yup_PaintProfiler.cpp +++ b/tests/yup_gui/yup_PaintProfiler.cpp @@ -25,6 +25,8 @@ using namespace yup; +#if YUP_ENABLE_COMPONENT_PAINT_PROFILING + namespace { @@ -555,3 +557,181 @@ TEST_F (PaintProfilerFixture, MultipleFramesAccumulateGlobalStats) EXPECT_EQ (frameCount, snapshot.globalFrameTotal.sampleCount); } + +// ============================================================================= +// PaintProfileScope integration tests — exercises Component::internalPaint +// ============================================================================= + +namespace yup +{ + +class ComponentPaintProfileTestHelper +{ +public: + static void triggerPaint (Component& comp, + Graphics& g, + const Rectangle& repaintArea, + bool renderContinuous = false) + { + comp.internalPaint (g, repaintArea, renderContinuous); + } +}; + +} // namespace yup + +namespace +{ + +class PaintableComponent : public yup::Component +{ +public: + PaintableComponent() = default; + + void paint (yup::Graphics&) override {} +}; + +} // namespace + +class PaintProfileScopeFixture : public ::testing::Test +{ +protected: + void SetUp() override + { + GraphicsContext::Options opts; + opts.allowHeadlessRendering = true; + context = GraphicsContext::createContext (GraphicsContext::Api::Headless, opts); + renderer = context->makeRenderer (200, 200); + + profiler = &PaintProfiler::getInstance(); + profiler->setEnabled (true); + profiler->resetAll(); + } + + void TearDown() override + { + profiler->setEnabled (false); + profiler->resetAll(); + } + + std::unique_ptr context; + std::unique_ptr renderer; + PaintProfiler* profiler = nullptr; +}; + +TEST_F (PaintProfileScopeFixture, RecordsSampleAfterPaint) +{ + PaintableComponent comp; + comp.setBounds (0, 0, 100, 100); + comp.setVisible (true); + comp.setPaintProfilingEnabled (true); + + Graphics g (*context, *renderer, 1.0f); + ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + + EXPECT_EQ (1, comp.getPaintProfileStats()->getSampleCount()); +} + +TEST_F (PaintProfileScopeFixture, NoSampleWhenProfilerDisabled) +{ + profiler->setEnabled (false); + + PaintableComponent comp; + comp.setBounds (0, 0, 100, 100); + comp.setVisible (true); + comp.setPaintProfilingEnabled (true); + + Graphics g (*context, *renderer, 1.0f); + ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + + EXPECT_EQ (0, comp.getPaintProfileStats()->getSampleCount()); +} + +TEST_F (PaintProfileScopeFixture, NoStatsWhenComponentProfilingNotEnabled) +{ + PaintableComponent comp; + comp.setBounds (0, 0, 100, 100); + comp.setVisible (true); + + Graphics g (*context, *renderer, 1.0f); + ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + + EXPECT_EQ (nullptr, comp.getPaintProfileStats()); +} + +TEST_F (PaintProfileScopeFixture, SampleHasNonNegativeTotalTime) +{ + PaintableComponent comp; + comp.setBounds (0, 0, 100, 100); + comp.setVisible (true); + comp.setPaintProfilingEnabled (true); + + Graphics g (*context, *renderer, 1.0f); + ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + + auto* stats = comp.getPaintProfileStats(); + ASSERT_EQ (1, stats->getSampleCount()); + EXPECT_GE (stats->getLastSample().totalMicros, 0.0); +} + +TEST_F (PaintProfileScopeFixture, SelfPaintSkippedWhenOpaqueChildCoversArea) +{ + PaintableComponent parent; + parent.setBounds (0, 0, 100, 100); + parent.setVisible (true); + parent.setOpaque (true); + parent.setPaintProfilingEnabled (true); + + PaintableComponent child; + child.setBounds (0, 0, 100, 100); + child.setVisible (true); + child.setOpaque (true); + parent.addChildComponent (child); + + Graphics g (*context, *renderer, 1.0f); + ComponentPaintProfileTestHelper::triggerPaint (parent, g, parent.getBounds()); + + auto* stats = parent.getPaintProfileStats(); + ASSERT_EQ (1, stats->getSampleCount()); + EXPECT_TRUE (stats->getLastSample().selfPaintSkipped); +} + +TEST_F (PaintProfileScopeFixture, ChildTimeContributesToParentChildrenMicros) +{ + PaintableComponent parent; + parent.setBounds (0, 0, 100, 100); + parent.setVisible (true); + parent.setPaintProfilingEnabled (true); + + PaintableComponent child; + child.setBounds (0, 0, 50, 50); + child.setVisible (true); + child.setPaintProfilingEnabled (true); + parent.addChildComponent (child); + + Graphics g (*context, *renderer, 1.0f); + ComponentPaintProfileTestHelper::triggerPaint (parent, g, parent.getBounds()); + + auto* parentStats = parent.getPaintProfileStats(); + ASSERT_EQ (1, parentStats->getSampleCount()); + EXPECT_GE (parentStats->getLastSample().childrenMicros, 0.0); + EXPECT_GE (parentStats->getLastSample().totalMicros, parentStats->getLastSample().childrenMicros); +} + +TEST_F (PaintProfileScopeFixture, MultiplePaintsAccumulateSamples) +{ + PaintableComponent comp; + comp.setBounds (0, 0, 100, 100); + comp.setVisible (true); + comp.setPaintProfilingEnabled (true); + + constexpr int paintCount = 5; + for (int i = 0; i < paintCount; ++i) + { + Graphics g (*context, *renderer, 1.0f); + ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + } + + EXPECT_EQ (paintCount, comp.getPaintProfileStats()->getSampleCount()); +} + +#endif From d32623bc43205b8108eee4567f1848b43e173a03 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Thu, 21 May 2026 17:19:23 +0200 Subject: [PATCH 6/7] Fix architecture of the profiler --- examples/graphics/CMakeLists.txt | 1 - .../source/examples/PaintProfilerDemo.h | 31 -- modules/yup_gui/component/yup_Component.cpp | 270 ++++++---------- modules/yup_gui/component/yup_Component.h | 84 +++-- .../yup_gui/component/yup_ComponentListener.h | 70 +++++ .../component/yup_ComponentPaintMetrics.h | 61 ++++ modules/yup_gui/native/yup_Windowing_sdl2.cpp | 40 ++- .../profiling/yup_PaintProfileSample.h | 23 +- .../yup_gui/profiling/yup_PaintProfiler.cpp | 260 +++++++++++++--- modules/yup_gui/profiling/yup_PaintProfiler.h | 70 +++-- modules/yup_gui/yup_gui.cpp | 2 - modules/yup_gui/yup_gui.h | 19 +- tests/CMakeLists.txt | 1 - tests/yup_gui/yup_PaintProfiler.cpp | 287 ++++++++++++------ 14 files changed, 757 insertions(+), 462 deletions(-) create mode 100644 modules/yup_gui/component/yup_ComponentListener.h create mode 100644 modules/yup_gui/component/yup_ComponentPaintMetrics.h diff --git a/examples/graphics/CMakeLists.txt b/examples/graphics/CMakeLists.txt index 28bf1dd0b..ff70a6a15 100644 --- a/examples/graphics/CMakeLists.txt +++ b/examples/graphics/CMakeLists.txt @@ -62,7 +62,6 @@ yup_standalone_app ( TARGET_APP_NAMESPACE "org.yup" DEFINITIONS YUP_EXAMPLE_GRAPHICS_RIVE_FILE="${rive_file}" - YUP_ENABLE_COMPONENT_PAINT_PROFILING=1 ${additional_definitions} PRELOAD_FILES "${CMAKE_CURRENT_LIST_DIR}/${rive_file}@${rive_file}" diff --git a/examples/graphics/source/examples/PaintProfilerDemo.h b/examples/graphics/source/examples/PaintProfilerDemo.h index 7c0bb9245..4e383ead2 100644 --- a/examples/graphics/source/examples/PaintProfilerDemo.h +++ b/examples/graphics/source/examples/PaintProfilerDemo.h @@ -216,14 +216,12 @@ class ProfilerDashboard : public yup::Component font = theme->getDefaultFont(); } -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING void setSnapshot (const yup::PaintProfiler::Snapshot& newSnapshot, int selectedIndex) { snapshot = newSnapshot; selectedRow = selectedIndex; repaint(); } -#endif int getSelectedRow() const { return selectedRow; } @@ -236,22 +234,13 @@ class ProfilerDashboard : public yup::Component g.setFillColor (yup::Color (0xff1a1a2e)); g.fillAll(); -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING const float divX = bounds.getWidth() * 0.60f; drawTable (g, bounds.withWidth (divX)); drawRightPanel (g, bounds.withX (divX + 4.0f).withWidth (bounds.getWidth() - divX - 4.0f)); -#else - g.setFillColor (yup::Colors::lightgray); - g.fillFittedText ("Paint profiling not enabled (build with YUP_ENABLE_COMPONENT_PAINT_PROFILING=1)", - font, - bounds, - yup::Justification::center); -#endif } void mouseDown (const yup::MouseEvent& event) override { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING const float divX = getLocalBounds().to().getWidth() * 0.60f; if (event.getPosition().getX() >= divX) return; @@ -262,12 +251,9 @@ class ProfilerDashboard : public yup::Component if (row >= 0 && row < (int) snapshot.components.size()) selectedRow = row; repaint(); -#endif } private: -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - static constexpr float kMaxColW = 62.0f; static constexpr float kAvgColW = 62.0f; static constexpr float kHeaderH = 24.0f; @@ -511,7 +497,6 @@ class ProfilerDashboard : public yup::Component } yup::PaintProfiler::Snapshot snapshot; -#endif int selectedRow = -1; yup::Font font; @@ -546,12 +531,10 @@ class ProfilerWindow : public yup::DocumentWindow yup::MessageManager::callAsync (closeCallback); } -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING void updateSnapshot (const yup::PaintProfiler::Snapshot& snap) { dashboard->setSnapshot (snap, dashboard->getSelectedRow()); } -#endif private: std::unique_ptr dashboard; @@ -581,9 +564,7 @@ class PaintProfilerDemo : public yup::Component nestedGrid = std::make_unique(); addAndMakeVisible (nestedGrid.get()); -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING paintProfileSession = yup::PaintProfiler::getInstance().startSession (*this); -#endif startTimerHz (10); } @@ -592,10 +573,7 @@ class PaintProfilerDemo : public yup::Component { stopTimer(); profilerWindow.reset(); - -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING paintProfileSession.reset(); -#endif } void paint (yup::Graphics& g) override @@ -619,7 +597,6 @@ class PaintProfilerDemo : public yup::Component void timerCallback() override { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING if (paintProfileSession == nullptr || paintProfileSession->isPaused()) return; @@ -628,12 +605,10 @@ class PaintProfilerDemo : public yup::Component auto snap = paintProfileSession->createSnapshot (yup::PaintProfileTimeKind::total, 32); profilerWindow->updateSnapshot (snap); -#endif } void keyDown (const yup::KeyPress& keys, const yup::Point& position) override { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING if (keys.getKey() == yup::KeyPress::textPKey) { toggleProfilerWindow(); @@ -647,7 +622,6 @@ class PaintProfilerDemo : public yup::Component { logSnapshot(); } -#endif } private: @@ -669,7 +643,6 @@ class PaintProfilerDemo : public yup::Component } } -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING void logSnapshot() { if (paintProfileSession == nullptr) @@ -700,15 +673,11 @@ class PaintProfilerDemo : public yup::Component globalBuckets += " " + yup::String (c); yup::Logger::outputDebugString (globalBuckets); } -#endif std::unique_ptr opaqueWidget; std::unique_ptr pathWidget; std::unique_ptr textWidget; std::unique_ptr nestedGrid; std::unique_ptr profilerWindow; - -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING std::unique_ptr paintProfileSession; -#endif }; diff --git a/modules/yup_gui/component/yup_Component.cpp b/modules/yup_gui/component/yup_Component.cpp index 2e9d39434..fc4deccfe 100644 --- a/modules/yup_gui/component/yup_Component.cpp +++ b/modules/yup_gui/component/yup_Component.cpp @@ -37,9 +37,7 @@ Component::Component (StringRef componentID) Component::~Component() { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - setPaintProfilingEnabled (false); -#endif + componentListeners.call (&ComponentListener::componentBeingDeleted, *this); if (options.onDesktop) removeFromDesktop(); @@ -162,7 +160,7 @@ void Component::setPosition (const Point& newPosition) if (options.onDesktop && native != nullptr) native->setPosition (newPosition.to()); - moved(); + sendMoved(); } float Component::getX() const @@ -207,7 +205,7 @@ void Component::setTopLeft (const Point& newTopLeft) if (options.onDesktop && native != nullptr) native->setPosition (newTopLeft.to()); - moved(); + sendMoved(); } Point Component::getBottomLeft() const @@ -222,7 +220,7 @@ void Component::setBottomLeft (const Point& newBottomLeft) if (options.onDesktop && native != nullptr) native->setPosition (newBottomLeft.translated (0.0f, -getHeight()).to()); - moved(); + sendMoved(); } Point Component::getTopRight() const @@ -237,7 +235,7 @@ void Component::setTopRight (const Point& newTopRight) if (options.onDesktop && native != nullptr) native->setPosition (newTopRight.translated (-getWidth(), 0.0f).to()); - moved(); + sendMoved(); } Point Component::getBottomRight() const @@ -252,7 +250,7 @@ void Component::setBottomRight (const Point& newBottomRight) if (options.onDesktop && native != nullptr) native->setPosition (newBottomRight.translated (-getWidth(), -getHeight()).to()); - moved(); + sendMoved(); } Point Component::getCenter() const @@ -267,7 +265,7 @@ void Component::setCenter (const Point& newCenter) if (options.onDesktop && native != nullptr) native->setPosition (newCenter.translated (-getWidth() / 2.0f, -getHeight() / 2.0f).to()); - moved(); + sendMoved(); } float Component::getCenterX() const @@ -285,7 +283,7 @@ void Component::setCenterX (float newCenterX) native->setPosition (newCenter.translated (-getWidth() / 2.0f, 0.0f).to()); } - moved(); + sendMoved(); } float Component::getCenterY() const @@ -303,11 +301,21 @@ void Component::setCenterY (float newCenterY) native->setPosition (newCenter.translated (0.0f, -getHeight() / 2.0f).to()); } - moved(); + sendMoved(); } void Component::moved() {} +void Component::sendMoved() +{ + moved(); + + componentListeners.call ([this] (ComponentListener& listener) + { + listener.componentMoved (*this); + }); +} + //============================================================================== void Component::setSize (float width, float height) @@ -324,7 +332,7 @@ void Component::setSize (const Size& newSize) if (options.onDesktop && native != nullptr) native->setSize (newSize.to()); - resized(); + sendResized(); repaint (areaToRepaint); } @@ -365,12 +373,12 @@ void Component::setBounds (const Rectangle& newBounds) auto bailOutChecker = BailOutChecker (this); - resized(); + sendResized(); if (bailOutChecker.shouldBailOut()) return; - moved(); + sendMoved(); } Rectangle Component::getBounds() const @@ -411,6 +419,16 @@ float Component::proportionOfHeight (float proportion) const void Component::resized() {} +void Component::sendResized() +{ + resized(); + + componentListeners.call ([this] (ComponentListener& listener) + { + listener.componentResized (*this); + }); +} + //============================================================================== void Component::setTransform (const AffineTransform& newTransform) @@ -515,6 +533,16 @@ bool Component::isRenderingUnclipped() const return options.unclippedRendering; } +void Component::setPaintProfilingDisabled (bool shouldBeDisabled) +{ + options.paintProfilingDisabled = shouldBeDisabled; +} + +bool Component::isPaintProfilingDisabled() const +{ + return options.paintProfilingDisabled; +} + void Component::repaint() { repaint (getLocalBounds()); @@ -1047,6 +1075,18 @@ void Component::removeMouseListener (MouseListener* listener) //============================================================================== +void Component::addComponentListener (ComponentListener* listener) +{ + componentListeners.add (listener); +} + +void Component::removeComponentListener (ComponentListener* listener) +{ + componentListeners.remove (listener); +} + +//============================================================================== + void Component::setStyle (ComponentStyle::Ptr newStyle) { if (style == newStyle) @@ -1156,145 +1196,6 @@ bool Component::hasOpaqueChildCoveringArea (const Rectangle& area) return false; } -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - -//============================================================================== - -void Component::setPaintProfilingEnabled (bool shouldBeEnabled, PaintProfileOptions options) -{ - if (shouldBeEnabled) - { - if (paintProfileStats == nullptr - || paintProfileStats->getCapacity() != options.sampleCapacity) - { - paintProfileStats = std::make_unique (options); - } - - PaintProfiler::getInstance().registerComponent (*this, *paintProfileStats); - } - else - { - PaintProfiler::getInstance().deregisterComponent (*this); - paintProfileStats.reset(); - } -} - -bool Component::isPaintProfilingEnabled() const -{ - return paintProfileStats != nullptr; -} - -void Component::resetPaintProfiling() -{ - if (paintProfileStats != nullptr) - paintProfileStats->reset(); -} - -PaintProfileStats* Component::getPaintProfileStats() -{ - return paintProfileStats.get(); -} - -const PaintProfileStats* Component::getPaintProfileStats() const -{ - return paintProfileStats.get(); -} - -String Component::getPaintProfileName() const -{ - if (componentTitle.isNotEmpty()) - return componentTitle; - - if (componentID.isNotEmpty()) - return componentID; - - return "Component"; -} - -thread_local std::vector Component::paintProfileScopeStack {}; -std::atomic Component::globalPaintIndexCounter { 0 }; - -//============================================================================== - -class PaintProfileScope -{ -public: - PaintProfileScope (Component& component, - const Rectangle& repaintArea, - bool renderContinuous, - uint64 frameIndex, - bool profilingActive) - : component (component) - , sample() - , totalStartMicros (ticksToMicros (Time::getHighResolutionTicks())) - , selfStartMicros (0.0) - , profilingActive (profilingActive) - { - sample.frameIndex = frameIndex; - sample.paintIndex = Component::globalPaintIndexCounter.fetch_add (1, std::memory_order_relaxed); - sample.repaintArea = repaintArea; - sample.componentBounds = component.getBoundsRelativeToTopLevelComponent().to(); - sample.renderContinuous = renderContinuous; - - Component::paintProfileScopeStack.push_back ({}); - } - - ~PaintProfileScope() - { - const double totalEndMicros = ticksToMicros (Time::getHighResolutionTicks()); - sample.totalMicros = totalEndMicros - totalStartMicros; - sample.childrenMicros = Component::paintProfileScopeStack.back().childrenMicros; - Component::paintProfileScopeStack.pop_back(); - - if (profilingActive) - { - sample.frameworkMicros = std::max (0.0, - sample.totalMicros - - sample.selfMicros - - sample.childrenMicros); - - if (auto* stats = component.getPaintProfileStats()) - stats->recordSample (sample); - } - - if (! Component::paintProfileScopeStack.empty()) - Component::paintProfileScopeStack.back().childrenMicros += sample.totalMicros; - } - - void beginSelf() - { - selfStartMicros = ticksToMicros (Time::getHighResolutionTicks()); - } - - void endSelf() - { - sample.selfMicros += ticksToMicros (Time::getHighResolutionTicks()) - selfStartMicros; - } - - void markSelfPaintSkipped() - { - sample.selfPaintSkipped = true; - } - -private: - static double ticksToMicros (int64 ticks) - { - return Time::highResolutionTicksToSeconds (ticks) * 1.0e6; - } - - Component& component; - PaintProfileSample sample; - double totalStartMicros; - double selfStartMicros; - bool profilingActive; - - YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaintProfileScope) -}; - -#endif // YUP_ENABLE_COMPONENT_PAINT_PROFILING - -//============================================================================== - void Component::internalRefreshDisplay (double lastFrameTimeSeconds) { refreshDisplay (lastFrameTimeSeconds); @@ -1344,14 +1245,19 @@ void Component::internalPaint (Graphics& g, const Rectangle& repaintArea, options.isRepainting = true; { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - const bool profilingActive = PaintProfiler::getInstance().isEnabled() && paintProfileStats != nullptr; + const bool shouldMeasurePaint = ! options.paintProfilingDisabled && ! componentListeners.isEmpty(); - const auto frameIndex = PaintProfiler::getInstance().getCurrentFrameIndex(); - PaintProfileScope profileScope (*this, repaintArea, renderContinuous, frameIndex, profilingActive); -#else - constexpr bool profilingActive = false; -#endif + ComponentPaintMetrics metrics; + int64 totalStartTicks = 0; + int64 selfStartTicks = 0; + + if (shouldMeasurePaint) + { + totalStartTicks = Time::getHighResolutionTicks(); + metrics.repaintArea = repaintArea; + metrics.componentBounds = bounds.to(); + metrics.renderContinuous = renderContinuous; + } const auto globalState = g.saveState(); @@ -1370,11 +1276,13 @@ void Component::internalPaint (Graphics& g, const Rectangle& repaintArea, { const auto paintState = g.saveState(); - if (profilingActive) + if (shouldMeasurePaint) { - YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.beginSelf();) + selfStartTicks = Time::getHighResolutionTicks(); + paint (g); - YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.endSelf();) + + metrics.selfTicks += Time::getHighResolutionTicks() - selfStartTicks; } else { @@ -1383,23 +1291,35 @@ void Component::internalPaint (Graphics& g, const Rectangle& repaintArea, } else { - if (profilingActive) - { - YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.markSelfPaintSkipped();) - } + if (shouldMeasurePaint) + metrics.selfPaintSkipped = true; } - for (auto child : children) - child->internalPaint (g, boundsToRedraw, renderContinuous); - - if (profilingActive) + if (shouldMeasurePaint) { - YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.beginSelf();) + const int64 childrenStartTicks = Time::getHighResolutionTicks(); + + for (auto child : children) + child->internalPaint (g, boundsToRedraw, renderContinuous); + + metrics.childrenTicks += Time::getHighResolutionTicks() - childrenStartTicks; + + selfStartTicks = Time::getHighResolutionTicks(); + paintOverChildren (g); - YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED (profileScope.endSelf();) + + const int64 selfEndTicks = Time::getHighResolutionTicks(); + + metrics.selfTicks += selfEndTicks - selfStartTicks; + metrics.totalTicks = selfEndTicks - totalStartTicks; + + componentListeners.call (&ComponentListener::componentPaintCompleted, *this, metrics); } else { + for (auto child : children) + child->internalPaint (g, boundsToRedraw, renderContinuous); + paintOverChildren (g); } } @@ -1608,7 +1528,7 @@ void Component::internalResized (int width, int height) { boundsInParent = boundsInParent.withSize (Size (width, height).to()); - resized(); + sendResized(); } //============================================================================== @@ -1617,7 +1537,7 @@ void Component::internalMoved (int xpos, int ypos) { boundsInParent = boundsInParent.withPosition (Point (xpos, ypos).to()); - moved(); + sendMoved(); } //============================================================================== diff --git a/modules/yup_gui/component/yup_Component.h b/modules/yup_gui/component/yup_Component.h index 54911acec..e421741a8 100644 --- a/modules/yup_gui/component/yup_Component.h +++ b/modules/yup_gui/component/yup_Component.h @@ -246,7 +246,18 @@ class YUP_API Component : public MouseListener */ void setBottomRight (const Point& newBottomRight); + /** + Get the center position of the component relative to its parent. + + @return The center position of the component relative to its parent. + */ Point getCenter() const; + + /** + Set the center position of the component relative to its parent. + + @param newCenter The new center position of the component relative to its parent. + */ void setCenter (const Point& newCenter); /** @@ -611,6 +622,19 @@ class YUP_API Component : public MouseListener */ bool isRenderingUnclipped() const; + //============================================================================== + /** Enables or disables paint measurement suppression for this component. + + When suppression is enabled, component paint listeners will not receive + paint measurement callbacks for this component, even if they request paint + measurements. + */ + void setPaintProfilingDisabled (bool shouldBeDisabled); + + /** Returns true if paint measurement is suppressed for this component. */ + bool isPaintProfilingDisabled() const; + + //============================================================================== /** Repaint the component. */ @@ -1087,6 +1111,12 @@ class YUP_API Component : public MouseListener */ void removeMouseListener (MouseListener* listener); + /** Add a component listener to this component. */ + void addComponentListener (ComponentListener* listener); + + /** Remove a component listener from this component. */ + void removeComponentListener (ComponentListener* listener); + //============================================================================== /** Called when a key is pressed. @@ -1178,45 +1208,6 @@ class YUP_API Component : public MouseListener */ std::optional findStyleProperty (const Identifier& propertyId) const; -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - //============================================================================== - /** Enables or disables paint profiling for this component. - - When enabling, a PaintProfileStats instance is created (if not already present) - and the component is registered with PaintProfiler. Existing samples are - preserved when re-enabling with the same capacity. - - When disabling, the component is deregistered from PaintProfiler and the - stats object is destroyed. - - @param shouldBeEnabled Pass true to enable, false to disable. - @param options Controls the ring buffer capacity and recording behaviour. - */ - void setPaintProfilingEnabled (bool shouldBeEnabled, - PaintProfileOptions options = {}); - - /** Returns true if paint profiling is currently enabled for this component. */ - bool isPaintProfilingEnabled() const; - - /** Clears all paint profile samples recorded for this component. */ - void resetPaintProfiling(); - - /** Returns a pointer to this component's PaintProfileStats, or nullptr if - profiling is not enabled. */ - PaintProfileStats* getPaintProfileStats(); - - /** Returns a const pointer to this component's PaintProfileStats, or nullptr - if profiling is not enabled. */ - const PaintProfileStats* getPaintProfileStats() const; - - /** Returns the display name used for this component in profiling snapshots. - - Prefers (in order): a non-empty component title, a non-empty component ID, - the demangled type name if available, then falls back to "Component". - */ - String getPaintProfileName() const; -#endif - //============================================================================== /** A bail out checker for the component. */ class BailOutChecker @@ -1302,12 +1293,17 @@ class YUP_API Component : public MouseListener void updateMouseCursor(); + void sendMoved(); + void sendResized(); + bool hasOpaqueChildCoveringArea (const Rectangle& area); friend class ComponentNative; + friend class ComponentTestHelper; friend class SDL2ComponentNative; friend class WeakReference; + using ComponentListenerList = ListenerList>>; using MouseListenerList = ListenerList>>; String componentID, componentTitle; @@ -1318,6 +1314,7 @@ class YUP_API Component : public MouseListener ComponentNative::Ptr native; WeakReference::Master masterReference; MouseListenerList mouseListeners; + ComponentListenerList componentListeners; ComponentStyle::Ptr style; NamedValueSet properties; MouseCursor mouseCursor; @@ -1337,6 +1334,7 @@ class YUP_API Component : public MouseListener bool isRepainting : 1; bool blockSelfMouseEvents : 1; bool blockChildrenMouseEvents : 1; + bool paintProfilingDisabled : 1; }; union @@ -1350,14 +1348,6 @@ class YUP_API Component : public MouseListener int counter = 2; #endif -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - friend class PaintProfileScope; - friend class ComponentPaintProfileTestHelper; - std::unique_ptr paintProfileStats; - static thread_local std::vector paintProfileScopeStack; - static std::atomic globalPaintIndexCounter; -#endif - YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Component) }; diff --git a/modules/yup_gui/component/yup_ComponentListener.h b/modules/yup_gui/component/yup_ComponentListener.h new file mode 100644 index 000000000..dd7575b5c --- /dev/null +++ b/modules/yup_gui/component/yup_ComponentListener.h @@ -0,0 +1,70 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== + +class Component; + +//============================================================================== + +/** A base class for receiving component lifecycle and paint measurement events. */ +class YUP_API ComponentListener +{ +public: + /** Destructor. */ + virtual ~ComponentListener() = default; + + /** Called when a component's position changes. */ + virtual void componentMoved (Component& component) + { + ignoreUnused (component); + } + + /** Called when a component's size changes. */ + virtual void componentResized (Component& component) + { + ignoreUnused (component); + } + + /** Called when a component is about to be deleted. */ + virtual void componentBeingDeleted (Component& component) + { + ignoreUnused (component); + } + + /** Called after a component paint pass completes with measured paint data. + + Timing fields in measurement contain raw high-resolution tick counts. Listeners + that need wall-clock units are responsible for converting them. + */ + virtual void componentPaintCompleted (Component& component, const ComponentPaintMetrics& metrics) + { + ignoreUnused (component, metrics); + } + +private: + YUP_DECLARE_WEAK_REFERENCEABLE (ComponentListener) +}; + +} // namespace yup diff --git a/modules/yup_gui/component/yup_ComponentPaintMetrics.h b/modules/yup_gui/component/yup_ComponentPaintMetrics.h new file mode 100644 index 000000000..f8502a0da --- /dev/null +++ b/modules/yup_gui/component/yup_ComponentPaintMetrics.h @@ -0,0 +1,61 @@ +/* + ============================================================================== + + This file is part of the YUP library. + Copyright (c) 2026 - kunitoki@gmail.com + + YUP is an open source library subject to open-source licensing. + + The code included in this file is provided under the terms of the ISC license + http://www.isc.org/downloads/software-support-policy/isc-license. Permission + to use, copy, modify, and/or distribute this software for any purpose with or + without fee is hereby granted provided that the above copyright notice and + this permission notice appear in all copies. + + YUP IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER + EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE + DISCLAIMED. + + ============================================================================== +*/ + +namespace yup +{ + +//============================================================================== + +/** A single timing snapshot captured during one paint pass of a component. + + ComponentPaintMetrics captures the time spent in different phases of a component's paint + operation, as well as contextual information about the paint event (bounds, dirty region, + etc.). These snapshots are emitted to ComponentListeners after each paint pass, and are + aggregated into PaintProfileStats for longer-term storage and analysis. +*/ +struct ComponentPaintMetrics +{ + /** Ticks spent inside the component's own paint callback. */ + int64 selfTicks = 0; + + /** Ticks spent painting all children of this component. */ + int64 childrenTicks = 0; + + /** Ticks consumed by framework bookkeeping (transform setup, clip, etc.). */ + int64 frameworkTicks = 0; + + /** Total ticks from the start to the end of the full paint pass. */ + int64 totalTicks = 0; + + /** Axis-aligned bounding rectangle of the component in its parent's coordinate space. */ + Rectangle componentBounds; + + /** The dirty region that triggered this repaint, in the component's local coordinate space. */ + Rectangle repaintArea; + + /** True when the component requested a continuous repaint (e.g. animation loop). */ + bool renderContinuous = false; + + /** True when the component's own paint callback was skipped for this sample. */ + bool selfPaintSkipped = false; +}; + +} // namespace yup diff --git a/modules/yup_gui/native/yup_Windowing_sdl2.cpp b/modules/yup_gui/native/yup_Windowing_sdl2.cpp index cfd90aa2b..e9a2614b8 100644 --- a/modules/yup_gui/native/yup_Windowing_sdl2.cpp +++ b/modules/yup_gui/native/yup_Windowing_sdl2.cpp @@ -725,26 +725,36 @@ void SDL2ComponentNative::renderContext() } { -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - PaintProfiler::getInstance().beginFrame(); - const auto endFrameGuard = ErasedScopeGuard ([&] + const auto repaintComponents = [&] { - PaintProfiler::getInstance().endFrame(); - }); -#endif + // Repaint components hierarchy + if (renderer != nullptr) + { + const auto dpiScale = getScaleDpi(); - // Repaint components hierarchy - if (renderer != nullptr) - { - const auto dpiScale = getScaleDpi(); + for (auto& repaintArea : currentRepaintAreas) + { + YUP_PROFILE_NAMED_INTERNAL_TRACE (InternalPaint); + + Graphics g (*context, *renderer, dpiScale); + component.internalPaint (g, repaintArea, renderContinuous); + } + } + }; - for (auto& repaintArea : currentRepaintAreas) + if (PaintProfiler::hasRegisteredComponents() && PaintProfiler::getInstance().isEnabled()) + { + PaintProfiler::getInstance().beginFrame(); + const auto endFrameGuard = ErasedScopeGuard ([&] { - YUP_PROFILE_NAMED_INTERNAL_TRACE (InternalPaint); + PaintProfiler::getInstance().endFrame(); + }); - Graphics g (*context, *renderer, dpiScale); - component.internalPaint (g, repaintArea, renderContinuous); - } + repaintComponents(); + } + else + { + repaintComponents(); } } diff --git a/modules/yup_gui/profiling/yup_PaintProfileSample.h b/modules/yup_gui/profiling/yup_PaintProfileSample.h index 494a4b8a4..14da91c38 100644 --- a/modules/yup_gui/profiling/yup_PaintProfileSample.h +++ b/modules/yup_gui/profiling/yup_PaintProfileSample.h @@ -78,16 +78,16 @@ struct PaintProfileSample uint64 paintIndex = 0; /** Microseconds spent inside the component's own paint callback. */ - double selfMicros = 0.0; + double selfMicros = 0; /** Microseconds spent painting all children of this component. */ - double childrenMicros = 0.0; + double childrenMicros = 0; /** Microseconds consumed by framework bookkeeping (transform setup, clip, etc.). */ - double frameworkMicros = 0.0; + double frameworkMicros = 0; /** Total microseconds from the start to the end of the full paint pass. */ - double totalMicros = 0.0; + double totalMicros = 0; /** Axis-aligned bounding rectangle of the component in its parent's coordinate space. */ Rectangle componentBounds; @@ -135,21 +135,6 @@ struct PaintProfileSummary //============================================================================== -/** A struct used to track the cumulative child time of nested paint calls in the current call stack. - - This is stored in a thread_local stack in Component, and each PaintProfileScope pushes a new entry on - construction and pops it on destruction. The self time of a scope is accumulated separately, and the total - time of the scope is added to the parent's childrenMicros when the scope ends, so that the sum of selfMicros - and childrenMicros for a parent scope equals the total time spent in that subtree of the paint call graph. -*/ -struct PaintProfileScopeEntry -{ - /** Cumulative time spent in child paint calls for the current scope. */ - double childrenMicros = 0.0; -}; - -//============================================================================== - /** A linear histogram of sample values for a single PaintProfileTimeKind field. The range [rangeMinMicros, rangeMaxMicros] is divided into buckets.size() equal-width diff --git a/modules/yup_gui/profiling/yup_PaintProfiler.cpp b/modules/yup_gui/profiling/yup_PaintProfiler.cpp index 93b670714..25aeccdc4 100644 --- a/modules/yup_gui/profiling/yup_PaintProfiler.cpp +++ b/modules/yup_gui/profiling/yup_PaintProfiler.cpp @@ -22,8 +22,31 @@ namespace yup { +namespace +{ + +double ticksToMicros (double ticks) +{ + return Time::highResolutionTicksToSeconds (static_cast (ticks)) * 1.0e6; +} + +String getComponentPaintProfileName (const Component& component) +{ + if (component.getTitle().isNotEmpty()) + return component.getTitle(); + + if (component.getComponentID().isNotEmpty()) + return component.getComponentID(); + + return "Component"; +} + +} // namespace + //============================================================================== -// PaintProfiler + +std::atomic PaintProfiler::registeredComponentCount { 0 }; + //============================================================================== PaintProfiler::PaintProfiler() @@ -41,16 +64,58 @@ PaintProfiler& PaintProfiler::getInstance() return instance; } +bool PaintProfiler::hasRegisteredComponents() noexcept +{ + return registeredComponentCount.load (std::memory_order_relaxed) > 0; +} + +void PaintProfiler::removeExpiredRegistryEntries() const +{ + const auto previousSize = registry.size(); + + std::erase_if (registry, [] (const auto& entry) + { + return entry.component.get() == nullptr; + }); + + const auto removedCount = previousSize - registry.size(); + + if (removedCount > 0) + registeredComponentCount.fetch_sub (static_cast (removedCount), std::memory_order_release); +} + //============================================================================== void PaintProfiler::setEnabled (bool shouldBeEnabled) { - enabled = shouldBeEnabled; + enabled.store (shouldBeEnabled, std::memory_order_release); + + const ScopedLock sl (registryLock); + + removeExpiredRegistryEntries(); + + for (auto& entry : registry) + { + auto* component = entry.component.get(); + + if (component == nullptr) + continue; + + if (shouldBeEnabled) + component->addComponentListener (this); + else + component->removeComponentListener (this); + } } bool PaintProfiler::isEnabled() const { - return enabled; + return enabled.load (std::memory_order_acquire); +} + +bool PaintProfiler::isActive() const noexcept +{ + return isEnabled() && hasRegisteredComponents(); } //============================================================================== @@ -59,12 +124,12 @@ void PaintProfiler::beginFrame() { ++currentFrameIndex; globalPaintIndex.store (0, std::memory_order_relaxed); - frameStartMicros = Time::highResolutionTicksToSeconds (Time::getHighResolutionTicks()) * 1.0e6; + frameStartMicros = ticksToMicros (Time::getHighResolutionTicks()); } void PaintProfiler::endFrame() { - const double endMicros = Time::highResolutionTicksToSeconds (Time::getHighResolutionTicks()) * 1.0e6; + const double endMicros = ticksToMicros (Time::getHighResolutionTicks()); PaintProfileSample sample; sample.frameIndex = currentFrameIndex; @@ -74,35 +139,101 @@ void PaintProfiler::endFrame() //============================================================================== -void PaintProfiler::registerComponent (Component& component, PaintProfileStats& stats) +void PaintProfiler::enableComponent (Component& component, PaintProfileOptions options) { + bool registeredNewComponent = false; + const ScopedLock sl (registryLock); - registry.erase (std::remove_if (registry.begin(), registry.end(), [&] (const auto& entry) + removeExpiredRegistryEntries(); + + auto existing = std::find_if (registry.begin(), registry.end(), [&] (const auto& entry) + { + return entry.component.get() == &component; + }); + + if (existing != registry.end()) { - return entry.first == &component; - }), - registry.end()); + if (existing->stats == nullptr || existing->stats->getCapacity() != options.sampleCapacity) + existing->stats = std::make_unique (options); + + if (isEnabled()) + component.addComponentListener (this); + + return; + } - registry.emplace_back (&component, &stats); + registry.push_back ({ WeakReference (&component), std::make_unique (options) }); + registeredNewComponent = true; + + if (isEnabled()) + component.addComponentListener (this); + + if (registeredNewComponent) + registeredComponentCount.fetch_add (1, std::memory_order_release); } -void PaintProfiler::deregisterComponent (const Component& component) +void PaintProfiler::disableComponent (Component& component) { + bool removedComponent = false; + const ScopedLock sl (registryLock); - registry.erase (std::remove_if (registry.begin(), registry.end(), [&] (const auto& entry) + removeExpiredRegistryEntries(); + + const auto previousSize = registry.size(); + + std::erase_if (registry, [&] (const auto& entry) { - return entry.first == &component; - }), - registry.end()); + return entry.component.get() == &component; + }); + + removedComponent = registry.size() != previousSize; + + if (removedComponent) + component.removeComponentListener (this); + + if (removedComponent) + registeredComponentCount.fetch_sub (1, std::memory_order_release); +} + +bool PaintProfiler::isComponentEnabled (const Component& component) const +{ + const ScopedLock sl (registryLock); + + removeExpiredRegistryEntries(); + + return std::any_of (registry.begin(), registry.end(), [&] (const auto& entry) + { + return entry.component.get() == &component; + }); +} + +void PaintProfiler::resetComponent (Component& component) +{ + if (auto* stats = getStatsForComponent (component)) + stats->reset(); +} + +PaintProfileStats* PaintProfiler::getStatsForComponent (const Component& component) const +{ + const ScopedLock sl (registryLock); + + removeExpiredRegistryEntries(); + + auto found = std::find_if (registry.begin(), registry.end(), [&] (const auto& entry) + { + return entry.component.get() == &component; + }); + + return found != registry.end() ? found->stats.get() : nullptr; } //============================================================================== void PaintProfiler::enableSubtree (Component& root, PaintProfileOptions options) { - root.setPaintProfilingEnabled (true, options); + enableComponent (root, options); for (int i = 0; i < root.getNumChildComponents(); ++i) { @@ -113,7 +244,7 @@ void PaintProfiler::enableSubtree (Component& root, PaintProfileOptions options) void PaintProfiler::disableSubtree (Component& root) { - root.setPaintProfilingEnabled (false); + disableComponent (root); for (int i = 0; i < root.getNumChildComponents(); ++i) { @@ -127,11 +258,13 @@ void PaintProfiler::resetSubtree (Component& root) { const ScopedLock sl (registryLock); - for (auto& [component, stats] : registry) + removeExpiredRegistryEntries(); + + for (auto& entry : registry) { - if (component == &root) + if (entry.component.get() == &root) { - stats->reset(); + entry.stats->reset(); break; } } @@ -148,30 +281,38 @@ void PaintProfiler::resetAll() { const ScopedLock sl (registryLock); - for (auto& [component, stats] : registry) - stats->reset(); + removeExpiredRegistryEntries(); + + for (auto& entry : registry) + entry.stats->reset(); globalFrameStats->reset(); } //============================================================================== -std::unique_ptr PaintProfiler::startSession (Component& root, - PaintProfileOptions options) +std::unique_ptr PaintProfiler::startSession (Component& root, PaintProfileOptions options) { return std::unique_ptr (new ScopedSession (*this, root, options)); } //============================================================================== -PaintProfiler::Snapshot PaintProfiler::createSnapshot (PaintProfileTimeKind sortBy, - int histogramBuckets) const +PaintProfiler::Snapshot PaintProfiler::createSnapshot (PaintProfileTimeKind sortBy, int histogramBuckets) const { std::vector> registryCopy; { const ScopedLock sl (registryLock); - registryCopy = registry; + + removeExpiredRegistryEntries(); + + registryCopy.reserve (registry.size()); + for (auto& entry : registry) + { + if (auto* component = entry.component.get()) + registryCopy.emplace_back (component, entry.stats.get()); + } } Snapshot snapshot; @@ -182,7 +323,7 @@ PaintProfiler::Snapshot PaintProfiler::createSnapshot (PaintProfileTimeKind sort { ComponentEntry entry; entry.component = component; - entry.name = component->getPaintProfileName(); + entry.name = getComponentPaintProfileName (*component); entry.stats = stats; entry.self = stats->summarize (PaintProfileTimeKind::self); entry.children = stats->summarize (PaintProfileTimeKind::children); @@ -200,12 +341,16 @@ PaintProfiler::Snapshot PaintProfiler::createSnapshot (PaintProfileTimeKind sort { case PaintProfileTimeKind::self: return entry.self.p95Micros; + case PaintProfileTimeKind::children: return entry.children.p95Micros; + case PaintProfileTimeKind::framework: return entry.framework.p95Micros; + case PaintProfileTimeKind::total: return entry.total.p95Micros; + default: return entry.total.p95Micros; } @@ -229,11 +374,13 @@ PaintProfileHistogram PaintProfiler::createHistogramForComponent (const Componen { const ScopedLock sl (registryLock); - for (auto& [comp, stats] : registry) + removeExpiredRegistryEntries(); + + for (auto& entry : registry) { - if (comp == &component) + if (entry.component.get() == &component) { - found = stats; + found = entry.stats.get(); break; } } @@ -245,8 +392,47 @@ PaintProfileHistogram PaintProfiler::createHistogramForComponent (const Componen return found->createHistogram (kind, histogramBuckets); } -//============================================================================== -// PaintProfiler::ScopedSession +void PaintProfiler::componentBeingDeleted (Component& component) +{ + bool removedComponent = false; + + const ScopedLock sl (registryLock); + + const auto previousSize = registry.size(); + + std::erase_if (registry, [&] (const auto& entry) + { + return entry.component.get() == &component; + }); + + removedComponent = registry.size() != previousSize; + + if (removedComponent) + registeredComponentCount.fetch_sub (1, std::memory_order_release); +} + +void PaintProfiler::componentPaintCompleted (Component& component, const ComponentPaintMetrics& metrics) +{ + if (! isEnabled()) + return; + + if (auto* stats = getStatsForComponent (component)) + { + PaintProfileSample sample; + sample.frameIndex = currentFrameIndex; + sample.paintIndex = globalPaintIndex.fetch_add (1, std::memory_order_relaxed); + sample.selfMicros = ticksToMicros (static_cast (metrics.selfTicks)); + sample.childrenMicros = ticksToMicros (static_cast (metrics.childrenTicks)); + sample.totalMicros = ticksToMicros (static_cast (metrics.totalTicks)); + sample.frameworkMicros = jmax (0.0, sample.totalMicros - sample.selfMicros - sample.childrenMicros); + sample.componentBounds = metrics.componentBounds; + sample.repaintArea = metrics.repaintArea; + sample.renderContinuous = metrics.renderContinuous; + sample.selfPaintSkipped = metrics.selfPaintSkipped; + stats->recordSample (sample); + } +} + //============================================================================== PaintProfiler::ScopedSession::ScopedSession (PaintProfiler& profilerRef, @@ -258,7 +444,6 @@ PaintProfiler::ScopedSession::ScopedSession (PaintProfiler& profilerRef, { profiler.enableSubtree (rootComponent, sessionOptions); - // Walk the same subtree to capture weak references for later cleanup. std::function collectComponents = [&] (Component& component) { enabledComponents.emplace_back (&component); @@ -278,7 +463,7 @@ PaintProfiler::ScopedSession::~ScopedSession() for (auto& weakComponent : enabledComponents) { if (auto* component = weakComponent.get()) - component->setPaintProfilingEnabled (false); + profiler.disableComponent (*component); } } @@ -300,8 +485,7 @@ void PaintProfiler::ScopedSession::reset() profiler.resetSubtree (*rootComponent); } -PaintProfiler::Snapshot PaintProfiler::ScopedSession::createSnapshot (PaintProfileTimeKind sortBy, - int histogramBuckets) const +PaintProfiler::Snapshot PaintProfiler::ScopedSession::createSnapshot (PaintProfileTimeKind sortBy, int histogramBuckets) const { return profiler.createSnapshot (sortBy, histogramBuckets); } diff --git a/modules/yup_gui/profiling/yup_PaintProfiler.h b/modules/yup_gui/profiling/yup_PaintProfiler.h index d514a4061..748cdb8b6 100644 --- a/modules/yup_gui/profiling/yup_PaintProfiler.h +++ b/modules/yup_gui/profiling/yup_PaintProfiler.h @@ -34,7 +34,7 @@ namespace yup RAII ScopedSession handle that enables profiling on a component subtree and automatically disables it when the handle is destroyed. */ -class PaintProfiler +class PaintProfiler : private ComponentListener { public: //============================================================================== @@ -43,12 +43,12 @@ class PaintProfiler struct ComponentEntry { /** Pointer to the profiled component (may be stale after the snapshot is taken). */ - Component* component = nullptr; + WeakReference component; /** Display name of the component at snapshot time. */ String name; - /** Pointer to the stats object owned by the component (may be stale). */ + /** Pointer to the stats object owned by PaintProfiler (may be stale). */ PaintProfileStats* stats = nullptr; /** Statistical summary for the component's own paint time. */ @@ -124,15 +124,13 @@ class PaintProfiler private: friend class PaintProfiler; - ScopedSession (PaintProfiler& profiler, - Component& root, - PaintProfileOptions options); + ScopedSession (PaintProfiler& profiler, Component& root, PaintProfileOptions options); PaintProfiler& profiler; WeakReference root; PaintProfileOptions options; - bool paused = false; std::vector> enabledComponents; + bool paused = false; YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScopedSession) }; @@ -142,6 +140,13 @@ class PaintProfiler /** Returns the process-wide singleton instance. */ static PaintProfiler& getInstance(); + /** Returns true if any component is currently registered for paint profiling. + + This is a cheap process-wide check intended for hot paths that need to avoid + constructing the PaintProfiler singleton unless there is profiling work to do. + */ + static bool hasRegisteredComponents() noexcept; + //============================================================================== /** Enables or disables global profiling. @@ -156,6 +161,9 @@ class PaintProfiler /** Returns true when global profiling is enabled. */ bool isEnabled() const; + /** Returns true when at least one registered component can collect samples. */ + bool isActive() const noexcept; + //============================================================================== /** Enables profiling on the subtree rooted at root and returns an RAII handle. @@ -164,16 +172,30 @@ class PaintProfiler enabled by this call, regardless of the current global enabled state. @param root The root component of the subtree to profile. - @param options Options forwarded to each component's PaintProfileStats. + @param options Options used for each profiler-owned PaintProfileStats. @returns A unique_ptr to a ScopedSession that disables profiling on destruction. */ - std::unique_ptr startSession (Component& root, - PaintProfileOptions options = {}); + std::unique_ptr startSession (Component& root, PaintProfileOptions options = {}); + + /** Enables profiling for a single component. */ + void enableComponent (Component& component, PaintProfileOptions options = {}); + + /** Disables profiling for a single component. */ + void disableComponent (Component& component); + + /** Returns true if profiling is enabled for a single component. */ + bool isComponentEnabled (const Component& component) const; + + /** Clears all paint profile samples recorded for a single component. */ + void resetComponent (Component& component); + + /** Returns profiler-owned stats for a single component, or nullptr if disabled. */ + PaintProfileStats* getStatsForComponent (const Component& component) const; /** Recursively enables profiling for root and all its current children. @param root The root component of the subtree. - @param options Options forwarded to each component's PaintProfileStats. + @param options Options used for each profiler-owned PaintProfileStats. */ void enableSubtree (Component& root, PaintProfileOptions options = {}); @@ -230,25 +252,29 @@ class PaintProfiler uint64 getCurrentFrameIndex() const noexcept { return currentFrameIndex; } private: - friend class Component; + PaintProfiler(); + ~PaintProfiler(); + + void componentBeingDeleted (Component& component) override; + void componentPaintCompleted (Component& component, const ComponentPaintMetrics& metrics) override; - /** Called by Component::setPaintProfilingEnabled to register a component. */ - void registerComponent (Component& component, PaintProfileStats& stats); + void removeExpiredRegistryEntries() const; - /** Called by Component::setPaintProfilingEnabled to deregister a component. */ - void deregisterComponent (const Component& component); + struct RegistryEntry + { + WeakReference component; + std::unique_ptr stats; + }; mutable CriticalSection registryLock; - std::vector> registry; + mutable std::vector registry; std::unique_ptr globalFrameStats; uint64 currentFrameIndex = 0; - std::atomic globalPaintIndex { 0 }; double frameStartMicros = 0.0; - bool enabled = true; - - PaintProfiler(); - ~PaintProfiler(); + std::atomic globalPaintIndex { 0 }; + std::atomic enabled { true }; + static std::atomic registeredComponentCount; YUP_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PaintProfiler) }; diff --git a/modules/yup_gui/yup_gui.cpp b/modules/yup_gui/yup_gui.cpp index e5cd93222..455387792 100644 --- a/modules/yup_gui/yup_gui.cpp +++ b/modules/yup_gui/yup_gui.cpp @@ -125,10 +125,8 @@ //============================================================================== -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING #include "profiling/yup_PaintProfileStats.cpp" #include "profiling/yup_PaintProfiler.cpp" -#endif //============================================================================== diff --git a/modules/yup_gui/yup_gui.h b/modules/yup_gui/yup_gui.h index 382c145dc..f132fd527 100644 --- a/modules/yup_gui/yup_gui.h +++ b/modules/yup_gui/yup_gui.h @@ -69,29 +69,16 @@ #define YUP_ENABLE_WINDOWING_EVENT_LOGGING 1 #endif -//============================================================================== -/** Config: YUP_ENABLE_COMPONENT_PAINT_PROFILING - - Enable YUP component paint profiling. -*/ -#ifndef YUP_ENABLE_COMPONENT_PAINT_PROFILING -#define YUP_ENABLE_COMPONENT_PAINT_PROFILING 0 -#endif - //============================================================================== +#include #include #include //============================================================================== -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING -#define YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED(CODE) CODE #include "profiling/yup_PaintProfileSample.h" #include "profiling/yup_PaintProfileStats.h" -#else -#define YUP_IF_COMPONENT_PAINT_PROFILING_ENABLED(CODE) -#endif //============================================================================== @@ -108,6 +95,8 @@ #include "desktop/yup_Desktop.h" #include "component/yup_ComponentNative.h" #include "component/yup_ComponentStyle.h" +#include "component/yup_ComponentPaintMetrics.h" +#include "component/yup_ComponentListener.h" #include "component/yup_Component.h" #include "menus/yup_PopupMenu.h" #include "buttons/yup_Button.h" @@ -130,9 +119,7 @@ //============================================================================== -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING #include "profiling/yup_PaintProfiler.h" -#endif //============================================================================== diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bb42fddef..2faad6c3b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -123,7 +123,6 @@ yup_standalone_app ( TARGET_CONSOLE ${target_console} DEFINITIONS YUP_USE_CURL=0 - YUP_ENABLE_COMPONENT_PAINT_PROFILING=1 YUP_MODAL_LOOPS_PERMITTED=1 PRELOAD_FILES ${target_preloaded} diff --git a/tests/yup_gui/yup_PaintProfiler.cpp b/tests/yup_gui/yup_PaintProfiler.cpp index f2b4923de..5d544083c 100644 --- a/tests/yup_gui/yup_PaintProfiler.cpp +++ b/tests/yup_gui/yup_PaintProfiler.cpp @@ -25,8 +25,6 @@ using namespace yup; -#if YUP_ENABLE_COMPONENT_PAINT_PROFILING - namespace { @@ -52,62 +50,62 @@ TEST (ComponentProfilingTests, ProfilingDisabledByDefault) { Component comp; - EXPECT_FALSE (comp.isPaintProfilingEnabled()); - EXPECT_EQ (nullptr, comp.getPaintProfileStats()); + EXPECT_FALSE (PaintProfiler::getInstance().isComponentEnabled (comp)); + EXPECT_EQ (nullptr, PaintProfiler::getInstance().getStatsForComponent (comp)); } TEST (ComponentProfilingTests, EnableProfilingCreatesStats) { Component comp; - comp.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (comp); - EXPECT_TRUE (comp.isPaintProfilingEnabled()); - EXPECT_NE (nullptr, comp.getPaintProfileStats()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (comp)); + EXPECT_NE (nullptr, PaintProfiler::getInstance().getStatsForComponent (comp)); } TEST (ComponentProfilingTests, DisableProfilingClearsStats) { Component comp; - comp.setPaintProfilingEnabled (true); - comp.setPaintProfilingEnabled (false); + PaintProfiler::getInstance().enableComponent (comp); + PaintProfiler::getInstance().disableComponent (comp); - EXPECT_FALSE (comp.isPaintProfilingEnabled()); - EXPECT_EQ (nullptr, comp.getPaintProfileStats()); + EXPECT_FALSE (PaintProfiler::getInstance().isComponentEnabled (comp)); + EXPECT_EQ (nullptr, PaintProfiler::getInstance().getStatsForComponent (comp)); } TEST (ComponentProfilingTests, ReEnableProfilingAfterDisable) { Component comp; - comp.setPaintProfilingEnabled (true); - comp.setPaintProfilingEnabled (false); - comp.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (comp); + PaintProfiler::getInstance().disableComponent (comp); + PaintProfiler::getInstance().enableComponent (comp); - EXPECT_TRUE (comp.isPaintProfilingEnabled()); - EXPECT_NE (nullptr, comp.getPaintProfileStats()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (comp)); + EXPECT_NE (nullptr, PaintProfiler::getInstance().getStatsForComponent (comp)); } TEST (ComponentProfilingTests, ResetProfilingClearsSamples) { Component comp; - comp.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (comp); - auto* stats = comp.getPaintProfileStats(); + auto* stats = PaintProfiler::getInstance().getStatsForComponent (comp); stats->recordSample (makeSample (10.0)); stats->recordSample (makeSample (20.0)); ASSERT_EQ (2, stats->getSampleCount()); - comp.resetPaintProfiling(); + PaintProfiler::getInstance().resetComponent (comp); - EXPECT_EQ (0, comp.getPaintProfileStats()->getSampleCount()); - EXPECT_TRUE (comp.isPaintProfilingEnabled()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (comp)->getSampleCount()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (comp)); } TEST (ComponentProfilingTests, ResetProfilingOnDisabledComponentIsNoOp) { Component comp; - EXPECT_NO_FATAL_FAILURE (comp.resetPaintProfiling()); - EXPECT_EQ (nullptr, comp.getPaintProfileStats()); + EXPECT_NO_FATAL_FAILURE (PaintProfiler::getInstance().resetComponent (comp)); + EXPECT_EQ (nullptr, PaintProfiler::getInstance().getStatsForComponent (comp)); } TEST (ComponentProfilingTests, OptionsPreservedOnEnable) @@ -118,9 +116,9 @@ TEST (ComponentProfilingTests, OptionsPreservedOnEnable) opts.includeBounds = false; Component comp; - comp.setPaintProfilingEnabled (true, opts); + PaintProfiler::getInstance().enableComponent (comp, opts); - auto* stats = comp.getPaintProfileStats(); + auto* stats = PaintProfiler::getInstance().getStatsForComponent (comp); ASSERT_NE (nullptr, stats); auto stored = stats->getOptions(); @@ -131,32 +129,65 @@ TEST (ComponentProfilingTests, OptionsPreservedOnEnable) TEST (ComponentProfilingTests, GetPaintProfileNameFromTitle) { + auto& profiler = PaintProfiler::getInstance(); Component comp; comp.setTitle ("MyComponent"); + profiler.enableComponent (comp); + + auto snapshot = profiler.createSnapshot(); - EXPECT_EQ ("MyComponent", comp.getPaintProfileName()); + ASSERT_EQ (1u, snapshot.components.size()); + EXPECT_EQ ("MyComponent", snapshot.components[0].name); } TEST (ComponentProfilingTests, GetPaintProfileNameFromID) { + auto& profiler = PaintProfiler::getInstance(); Component comp ("myID"); + profiler.enableComponent (comp); + + auto snapshot = profiler.createSnapshot(); - EXPECT_EQ ("myID", comp.getPaintProfileName()); + ASSERT_EQ (1u, snapshot.components.size()); + EXPECT_EQ ("myID", snapshot.components[0].name); } TEST (ComponentProfilingTests, GetPaintProfileNameFallback) { + auto& profiler = PaintProfiler::getInstance(); Component comp; + profiler.enableComponent (comp); + + auto snapshot = profiler.createSnapshot(); - EXPECT_EQ ("Component", comp.getPaintProfileName()); + ASSERT_EQ (1u, snapshot.components.size()); + EXPECT_EQ ("Component", snapshot.components[0].name); } TEST (ComponentProfilingTests, GetPaintProfileNamePrefersTitle) { + auto& profiler = PaintProfiler::getInstance(); Component comp ("myID"); comp.setTitle ("MyTitle"); + profiler.enableComponent (comp); + + auto snapshot = profiler.createSnapshot(); - EXPECT_EQ ("MyTitle", comp.getPaintProfileName()); + ASSERT_EQ (1u, snapshot.components.size()); + EXPECT_EQ ("MyTitle", snapshot.components[0].name); +} + +TEST (ComponentProfilingTests, PaintProfilingCanBeDisabledPerComponent) +{ + Component comp; + + EXPECT_FALSE (comp.isPaintProfilingDisabled()); + + comp.setPaintProfilingDisabled (true); + EXPECT_TRUE (comp.isPaintProfilingDisabled()); + + comp.setPaintProfilingDisabled (false); + EXPECT_FALSE (comp.isPaintProfilingDisabled()); } // ============================================================================= @@ -207,8 +238,8 @@ TEST_F (PaintProfilerFixture, EnableSubtreeEnablesRoot) profiler->enableSubtree (root); - EXPECT_TRUE (root.isPaintProfilingEnabled()); - EXPECT_NE (nullptr, root.getPaintProfileStats()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (root)); + EXPECT_NE (nullptr, PaintProfiler::getInstance().getStatsForComponent (root)); } TEST_F (PaintProfilerFixture, EnableSubtreeEnablesChildren) @@ -219,8 +250,8 @@ TEST_F (PaintProfilerFixture, EnableSubtreeEnablesChildren) profiler->enableSubtree (root); - EXPECT_TRUE (root.isPaintProfilingEnabled()); - EXPECT_TRUE (child.isPaintProfilingEnabled()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (root)); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (child)); } TEST_F (PaintProfilerFixture, EnableSubtreeEnablesDeepHierarchy) @@ -233,9 +264,41 @@ TEST_F (PaintProfilerFixture, EnableSubtreeEnablesDeepHierarchy) profiler->enableSubtree (root); - EXPECT_TRUE (root.isPaintProfilingEnabled()); - EXPECT_TRUE (mid.isPaintProfilingEnabled()); - EXPECT_TRUE (leaf.isPaintProfilingEnabled()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (root)); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (mid)); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (leaf)); +} + +TEST_F (PaintProfilerFixture, DeletedEnabledComponentIsRemovedFromRegistry) +{ + auto comp = std::make_unique(); + profiler->enableComponent (*comp); + + EXPECT_TRUE (PaintProfiler::hasRegisteredComponents()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (*comp)); + + comp.reset(); + + EXPECT_FALSE (PaintProfiler::hasRegisteredComponents()); + EXPECT_TRUE (profiler->createSnapshot().components.empty()); +} + +TEST_F (PaintProfilerFixture, DeletedComponentWhileProfilerDisabledIsPrunedFromRegistry) +{ + profiler->setEnabled (false); + + auto comp = std::make_unique(); + profiler->enableComponent (*comp); + + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (*comp)); + + comp.reset(); + profiler->setEnabled (true); + + Component addressReuseProbe; + EXPECT_FALSE (PaintProfiler::getInstance().isComponentEnabled (addressReuseProbe)); + EXPECT_TRUE (profiler->createSnapshot().components.empty()); + EXPECT_FALSE (PaintProfiler::hasRegisteredComponents()); } TEST_F (PaintProfilerFixture, DisableSubtreeDisablesRootAndChildren) @@ -247,8 +310,8 @@ TEST_F (PaintProfilerFixture, DisableSubtreeDisablesRootAndChildren) profiler->enableSubtree (root); profiler->disableSubtree (root); - EXPECT_FALSE (root.isPaintProfilingEnabled()); - EXPECT_FALSE (child.isPaintProfilingEnabled()); + EXPECT_FALSE (PaintProfiler::getInstance().isComponentEnabled (root)); + EXPECT_FALSE (PaintProfiler::getInstance().isComponentEnabled (child)); } TEST_F (PaintProfilerFixture, ResetSubtreeResetsRootStats) @@ -256,14 +319,14 @@ TEST_F (PaintProfilerFixture, ResetSubtreeResetsRootStats) Component root; profiler->enableSubtree (root); - auto* stats = root.getPaintProfileStats(); + auto* stats = PaintProfiler::getInstance().getStatsForComponent (root); stats->recordSample (makeSample (10.0)); stats->recordSample (makeSample (20.0)); ASSERT_EQ (2, stats->getSampleCount()); profiler->resetSubtree (root); - EXPECT_EQ (0, root.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (root)->getSampleCount()); } TEST_F (PaintProfilerFixture, ResetSubtreeResetsChildStats) @@ -273,12 +336,12 @@ TEST_F (PaintProfilerFixture, ResetSubtreeResetsChildStats) root.addChildComponent (child); profiler->enableSubtree (root); - child.getPaintProfileStats()->recordSample (makeSample (15.0)); - ASSERT_EQ (1, child.getPaintProfileStats()->getSampleCount()); + PaintProfiler::getInstance().getStatsForComponent (child)->recordSample (makeSample (15.0)); + ASSERT_EQ (1, PaintProfiler::getInstance().getStatsForComponent (child)->getSampleCount()); profiler->resetSubtree (root); - EXPECT_EQ (0, child.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (child)->getSampleCount()); } TEST_F (PaintProfilerFixture, ResetAllClearsAllRegisteredStats) @@ -288,13 +351,13 @@ TEST_F (PaintProfilerFixture, ResetAllClearsAllRegisteredStats) profiler->enableSubtree (comp1); profiler->enableSubtree (comp2); - comp1.getPaintProfileStats()->recordSample (makeSample (10.0)); - comp2.getPaintProfileStats()->recordSample (makeSample (20.0)); + PaintProfiler::getInstance().getStatsForComponent (comp1)->recordSample (makeSample (10.0)); + PaintProfiler::getInstance().getStatsForComponent (comp2)->recordSample (makeSample (20.0)); profiler->resetAll(); - EXPECT_EQ (0, comp1.getPaintProfileStats()->getSampleCount()); - EXPECT_EQ (0, comp2.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (comp1)->getSampleCount()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (comp2)->getSampleCount()); } TEST_F (PaintProfilerFixture, SnapshotEmptyWithNoRegisteredComponents) @@ -335,10 +398,10 @@ TEST_F (PaintProfilerFixture, SnapshotSortedByP95TotalDescending) profiler->enableSubtree (fast); for (int i = 0; i < 5; ++i) - slow.getPaintProfileStats()->recordSample (makeSample (100.0)); + PaintProfiler::getInstance().getStatsForComponent (slow)->recordSample (makeSample (100.0)); for (int i = 0; i < 5; ++i) - fast.getPaintProfileStats()->recordSample (makeSample (10.0)); + PaintProfiler::getInstance().getStatsForComponent (fast)->recordSample (makeSample (10.0)); auto snapshot = profiler->createSnapshot (PaintProfileTimeKind::total); @@ -354,10 +417,10 @@ TEST_F (PaintProfilerFixture, SnapshotSortedByP95SelfDescending) profiler->enableSubtree (lowSelf); for (int i = 0; i < 5; ++i) - highSelf.getPaintProfileStats()->recordSample (makeSample (100.0, 80.0, 10.0)); + PaintProfiler::getInstance().getStatsForComponent (highSelf)->recordSample (makeSample (100.0, 80.0, 10.0)); for (int i = 0; i < 5; ++i) - lowSelf.getPaintProfileStats()->recordSample (makeSample (100.0, 10.0, 80.0)); + PaintProfiler::getInstance().getStatsForComponent (lowSelf)->recordSample (makeSample (100.0, 10.0, 80.0)); auto snapshot = profiler->createSnapshot (PaintProfileTimeKind::self); @@ -373,10 +436,10 @@ TEST_F (PaintProfilerFixture, SnapshotSortedByP95ChildrenDescending) profiler->enableSubtree (lowChildren); for (int i = 0; i < 5; ++i) - highChildren.getPaintProfileStats()->recordSample (makeSample (100.0, 10.0, 80.0)); + PaintProfiler::getInstance().getStatsForComponent (highChildren)->recordSample (makeSample (100.0, 10.0, 80.0)); for (int i = 0; i < 5; ++i) - lowChildren.getPaintProfileStats()->recordSample (makeSample (100.0, 80.0, 10.0)); + PaintProfiler::getInstance().getStatsForComponent (lowChildren)->recordSample (makeSample (100.0, 80.0, 10.0)); auto snapshot = profiler->createSnapshot (PaintProfileTimeKind::children); @@ -424,7 +487,7 @@ TEST_F (PaintProfilerFixture, HistogramForRegisteredComponentContainsAllSamples) Component comp; profiler->enableSubtree (comp); - auto* stats = comp.getPaintProfileStats(); + auto* stats = PaintProfiler::getInstance().getStatsForComponent (comp); for (int i = 1; i <= 5; ++i) stats->recordSample (makeSample (static_cast (i) * 10.0)); @@ -447,8 +510,8 @@ TEST_F (PaintProfilerFixture, StartSessionEnablesRootAndChildren) auto session = profiler->startSession (root); - EXPECT_TRUE (root.isPaintProfilingEnabled()); - EXPECT_TRUE (child.isPaintProfilingEnabled()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (root)); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (child)); } TEST_F (PaintProfilerFixture, ScopedSessionDestructorDisablesProfiling) @@ -457,10 +520,10 @@ TEST_F (PaintProfilerFixture, ScopedSessionDestructorDisablesProfiling) { auto session = profiler->startSession (root); - EXPECT_TRUE (root.isPaintProfilingEnabled()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (root)); } - EXPECT_FALSE (root.isPaintProfilingEnabled()); + EXPECT_FALSE (PaintProfiler::getInstance().isComponentEnabled (root)); } TEST_F (PaintProfilerFixture, ScopedSessionDestructorDisablesChildren) @@ -471,10 +534,10 @@ TEST_F (PaintProfilerFixture, ScopedSessionDestructorDisablesChildren) { auto session = profiler->startSession (root); - EXPECT_TRUE (child.isPaintProfilingEnabled()); + EXPECT_TRUE (PaintProfiler::getInstance().isComponentEnabled (child)); } - EXPECT_FALSE (child.isPaintProfilingEnabled()); + EXPECT_FALSE (PaintProfiler::getInstance().isComponentEnabled (child)); } TEST_F (PaintProfilerFixture, ScopedSessionInitiallyNotPaused) @@ -502,14 +565,14 @@ TEST_F (PaintProfilerFixture, ScopedSessionResetClearsStats) Component root; auto session = profiler->startSession (root); - auto* stats = root.getPaintProfileStats(); + auto* stats = PaintProfiler::getInstance().getStatsForComponent (root); stats->recordSample (makeSample (10.0)); stats->recordSample (makeSample (20.0)); ASSERT_EQ (2, stats->getSampleCount()); session->reset(); - EXPECT_EQ (0, root.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (root)->getSampleCount()); } TEST_F (PaintProfilerFixture, ScopedSessionCreateSnapshotReflectsRegisteredComponents) @@ -559,13 +622,13 @@ TEST_F (PaintProfilerFixture, MultipleFramesAccumulateGlobalStats) } // ============================================================================= -// PaintProfileScope integration tests — exercises Component::internalPaint +// Paint profiling integration tests — exercises Component::internalPaint // ============================================================================= namespace yup { -class ComponentPaintProfileTestHelper +class ComponentTestHelper { public: static void triggerPaint (Component& comp, @@ -592,7 +655,7 @@ class PaintableComponent : public yup::Component } // namespace -class PaintProfileScopeFixture : public ::testing::Test +class ComponentPaintProfilingFixture : public ::testing::Test { protected: void SetUp() override @@ -618,68 +681,82 @@ class PaintProfileScopeFixture : public ::testing::Test PaintProfiler* profiler = nullptr; }; -TEST_F (PaintProfileScopeFixture, RecordsSampleAfterPaint) +TEST_F (ComponentPaintProfilingFixture, RecordsSampleAfterPaint) { PaintableComponent comp; comp.setBounds (0, 0, 100, 100); comp.setVisible (true); - comp.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (comp); Graphics g (*context, *renderer, 1.0f); - ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + ComponentTestHelper::triggerPaint (comp, g, comp.getBounds()); - EXPECT_EQ (1, comp.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (1, PaintProfiler::getInstance().getStatsForComponent (comp)->getSampleCount()); } -TEST_F (PaintProfileScopeFixture, NoSampleWhenProfilerDisabled) +TEST_F (ComponentPaintProfilingFixture, NoSampleWhenProfilerDisabled) { profiler->setEnabled (false); PaintableComponent comp; comp.setBounds (0, 0, 100, 100); comp.setVisible (true); - comp.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (comp); Graphics g (*context, *renderer, 1.0f); - ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + ComponentTestHelper::triggerPaint (comp, g, comp.getBounds()); - EXPECT_EQ (0, comp.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (comp)->getSampleCount()); } -TEST_F (PaintProfileScopeFixture, NoStatsWhenComponentProfilingNotEnabled) +TEST_F (ComponentPaintProfilingFixture, NoSampleWhenComponentPaintProfilingDisabled) { PaintableComponent comp; comp.setBounds (0, 0, 100, 100); comp.setVisible (true); + comp.setPaintProfilingDisabled (true); + PaintProfiler::getInstance().enableComponent (comp); Graphics g (*context, *renderer, 1.0f); - ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + ComponentTestHelper::triggerPaint (comp, g, comp.getBounds()); - EXPECT_EQ (nullptr, comp.getPaintProfileStats()); + EXPECT_EQ (0, PaintProfiler::getInstance().getStatsForComponent (comp)->getSampleCount()); } -TEST_F (PaintProfileScopeFixture, SampleHasNonNegativeTotalTime) +TEST_F (ComponentPaintProfilingFixture, NoStatsWhenComponentProfilingNotEnabled) { PaintableComponent comp; comp.setBounds (0, 0, 100, 100); comp.setVisible (true); - comp.setPaintProfilingEnabled (true); Graphics g (*context, *renderer, 1.0f); - ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + ComponentTestHelper::triggerPaint (comp, g, comp.getBounds()); + + EXPECT_EQ (nullptr, PaintProfiler::getInstance().getStatsForComponent (comp)); +} - auto* stats = comp.getPaintProfileStats(); +TEST_F (ComponentPaintProfilingFixture, SampleHasNonNegativeTotalTime) +{ + PaintableComponent comp; + comp.setBounds (0, 0, 100, 100); + comp.setVisible (true); + PaintProfiler::getInstance().enableComponent (comp); + + Graphics g (*context, *renderer, 1.0f); + ComponentTestHelper::triggerPaint (comp, g, comp.getBounds()); + + auto* stats = PaintProfiler::getInstance().getStatsForComponent (comp); ASSERT_EQ (1, stats->getSampleCount()); EXPECT_GE (stats->getLastSample().totalMicros, 0.0); } -TEST_F (PaintProfileScopeFixture, SelfPaintSkippedWhenOpaqueChildCoversArea) +TEST_F (ComponentPaintProfilingFixture, SelfPaintSkippedWhenOpaqueChildCoversArea) { PaintableComponent parent; parent.setBounds (0, 0, 100, 100); parent.setVisible (true); parent.setOpaque (true); - parent.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (parent); PaintableComponent child; child.setBounds (0, 0, 100, 100); @@ -688,50 +765,70 @@ TEST_F (PaintProfileScopeFixture, SelfPaintSkippedWhenOpaqueChildCoversArea) parent.addChildComponent (child); Graphics g (*context, *renderer, 1.0f); - ComponentPaintProfileTestHelper::triggerPaint (parent, g, parent.getBounds()); + ComponentTestHelper::triggerPaint (parent, g, parent.getBounds()); - auto* stats = parent.getPaintProfileStats(); + auto* stats = PaintProfiler::getInstance().getStatsForComponent (parent); ASSERT_EQ (1, stats->getSampleCount()); EXPECT_TRUE (stats->getLastSample().selfPaintSkipped); } -TEST_F (PaintProfileScopeFixture, ChildTimeContributesToParentChildrenMicros) +TEST_F (ComponentPaintProfilingFixture, ChildTimeContributesToParentChildrenMicros) { PaintableComponent parent; parent.setBounds (0, 0, 100, 100); parent.setVisible (true); - parent.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (parent); PaintableComponent child; child.setBounds (0, 0, 50, 50); child.setVisible (true); - child.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (child); parent.addChildComponent (child); Graphics g (*context, *renderer, 1.0f); - ComponentPaintProfileTestHelper::triggerPaint (parent, g, parent.getBounds()); + ComponentTestHelper::triggerPaint (parent, g, parent.getBounds()); - auto* parentStats = parent.getPaintProfileStats(); + auto* parentStats = PaintProfiler::getInstance().getStatsForComponent (parent); ASSERT_EQ (1, parentStats->getSampleCount()); EXPECT_GE (parentStats->getLastSample().childrenMicros, 0.0); EXPECT_GE (parentStats->getLastSample().totalMicros, parentStats->getLastSample().childrenMicros); } -TEST_F (PaintProfileScopeFixture, MultiplePaintsAccumulateSamples) +TEST_F (ComponentPaintProfilingFixture, UnprofiledChildTimeContributesToProfiledParentChildrenMicros) +{ + PaintableComponent parent; + parent.setBounds (0, 0, 100, 100); + parent.setVisible (true); + PaintProfiler::getInstance().enableComponent (parent); + + PaintableComponent child; + child.setBounds (0, 0, 50, 50); + child.setVisible (true); + parent.addChildComponent (child); + + Graphics g (*context, *renderer, 1.0f); + ComponentTestHelper::triggerPaint (parent, g, parent.getBounds()); + + auto* parentStats = PaintProfiler::getInstance().getStatsForComponent (parent); + ASSERT_EQ (1, parentStats->getSampleCount()); + EXPECT_EQ (nullptr, PaintProfiler::getInstance().getStatsForComponent (child)); + EXPECT_GE (parentStats->getLastSample().childrenMicros, 0.0); + EXPECT_GE (parentStats->getLastSample().totalMicros, parentStats->getLastSample().childrenMicros); +} + +TEST_F (ComponentPaintProfilingFixture, MultiplePaintsAccumulateSamples) { PaintableComponent comp; comp.setBounds (0, 0, 100, 100); comp.setVisible (true); - comp.setPaintProfilingEnabled (true); + PaintProfiler::getInstance().enableComponent (comp); constexpr int paintCount = 5; for (int i = 0; i < paintCount; ++i) { Graphics g (*context, *renderer, 1.0f); - ComponentPaintProfileTestHelper::triggerPaint (comp, g, comp.getBounds()); + ComponentTestHelper::triggerPaint (comp, g, comp.getBounds()); } - EXPECT_EQ (paintCount, comp.getPaintProfileStats()->getSampleCount()); + EXPECT_EQ (paintCount, PaintProfiler::getInstance().getStatsForComponent (comp)->getSampleCount()); } - -#endif From 911fbdff4f1c56cd1142cca81bcb67432a746e44 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Thu, 21 May 2026 17:23:19 +0200 Subject: [PATCH 7/7] More component tests --- tests/yup_gui/yup_Component.cpp | 126 ++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/tests/yup_gui/yup_Component.cpp b/tests/yup_gui/yup_Component.cpp index 26a5338a2..9b7d6ccfd 100644 --- a/tests/yup_gui/yup_Component.cpp +++ b/tests/yup_gui/yup_Component.cpp @@ -167,6 +167,35 @@ class ComponentMock : public Component void transformChanged() override { transformChangedCalled = true; } }; +class RecordingComponentListener : public ComponentListener +{ +public: + void componentMoved (Component& component) override + { + ++movedCount; + lastMovedComponent = &component; + } + + void componentResized (Component& component) override + { + ++resizedCount; + lastResizedComponent = &component; + } + + void componentBeingDeleted (Component& component) override + { + ++deletedCount; + lastDeletedComponent = &component; + } + + int movedCount = 0; + int resizedCount = 0; + int deletedCount = 0; + Component* lastMovedComponent = nullptr; + Component* lastResizedComponent = nullptr; + Component* lastDeletedComponent = nullptr; +}; + } // namespace // ============================================================================= @@ -1164,6 +1193,103 @@ TEST_F (ComponentMockTest, MouseListenerMethods) mockComponent->removeMouseListener (listener.get()); } +TEST_F (ComponentMockTest, ComponentListenerReceivesMovedCallback) +{ + RecordingComponentListener listener; + mockComponent->addComponentListener (&listener); + + mockComponent->setPosition ({ 10.0f, 20.0f }); + + EXPECT_EQ (1, listener.movedCount); + EXPECT_EQ (static_cast (mockComponent.get()), listener.lastMovedComponent); + EXPECT_EQ (0, listener.resizedCount); +} + +TEST_F (ComponentMockTest, ComponentListenerReceivesResizedCallback) +{ + RecordingComponentListener listener; + mockComponent->addComponentListener (&listener); + + mockComponent->setSize ({ 100.0f, 80.0f }); + + EXPECT_EQ (1, listener.resizedCount); + EXPECT_EQ (static_cast (mockComponent.get()), listener.lastResizedComponent); + EXPECT_EQ (0, listener.movedCount); +} + +TEST_F (ComponentMockTest, ComponentListenerReceivesMovedAndResizedFromSetBounds) +{ + RecordingComponentListener listener; + mockComponent->addComponentListener (&listener); + + mockComponent->setBounds (5.0f, 10.0f, 150.0f, 120.0f); + + EXPECT_EQ (1, listener.movedCount); + EXPECT_EQ (1, listener.resizedCount); + EXPECT_EQ (static_cast (mockComponent.get()), listener.lastMovedComponent); + EXPECT_EQ (static_cast (mockComponent.get()), listener.lastResizedComponent); +} + +TEST_F (ComponentMockTest, RemovingComponentListenerStopsCallbacks) +{ + RecordingComponentListener listener; + mockComponent->addComponentListener (&listener); + mockComponent->removeComponentListener (&listener); + + mockComponent->setPosition ({ 10.0f, 20.0f }); + mockComponent->setSize ({ 100.0f, 80.0f }); + + EXPECT_EQ (0, listener.movedCount); + EXPECT_EQ (0, listener.resizedCount); +} + +TEST_F (ComponentMockTest, ComponentListenerIsOnlyAddedOnce) +{ + RecordingComponentListener listener; + mockComponent->addComponentListener (&listener); + mockComponent->addComponentListener (&listener); + + mockComponent->setPosition ({ 10.0f, 20.0f }); + + EXPECT_EQ (1, listener.movedCount); +} + +TEST_F (ComponentMockTest, DestroyedComponentListenerIsSkipped) +{ + auto listener = std::make_unique(); + mockComponent->addComponentListener (listener.get()); + + listener.reset(); + + const Point newPosition (10.0f, 20.0f); + EXPECT_NO_FATAL_FAILURE (mockComponent->setPosition (newPosition)); +} + +TEST_F (ComponentMockTest, ComponentListenerReceivesBeingDeletedCallback) +{ + RecordingComponentListener listener; + auto component = std::make_unique ("delete-notified"); + component->addComponentListener (&listener); + + auto* componentAddress = static_cast (component.get()); + component.reset(); + + EXPECT_EQ (1, listener.deletedCount); + EXPECT_EQ (componentAddress, listener.lastDeletedComponent); +} + +TEST_F (ComponentMockTest, RemovedComponentListenerDoesNotReceiveBeingDeletedCallback) +{ + RecordingComponentListener listener; + auto component = std::make_unique ("delete-notified"); + component->addComponentListener (&listener); + component->removeComponentListener (&listener); + + component.reset(); + + EXPECT_EQ (0, listener.deletedCount); +} + TEST_F (ComponentMockTest, StyleMethods) { // Test default style