From 8bbd1374a5fa7be796997ffbfdbcfabb8814701f Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Tue, 25 Sep 2018 21:05:44 -0700 Subject: [PATCH 1/4] Documentation about grpc polling engines --- doc/grpc-polling-engines.md | 154 ++++++++++++++++++++++++++++++++++ doc/images/grpc-epoll1.png | Bin 0 -> 36205 bytes doc/images/grpc-epollex.png | Bin 0 -> 52651 bytes doc/images/grpc-ps-pss-fd.png | Bin 0 -> 24969 bytes doc/images/grpc-pss.png | Bin 0 -> 31518 bytes 5 files changed, 154 insertions(+) create mode 100644 doc/grpc-polling-engines.md create mode 100644 doc/images/grpc-epoll1.png create mode 100644 doc/images/grpc-epollex.png create mode 100644 doc/images/grpc-ps-pss-fd.png create mode 100644 doc/images/grpc-pss.png diff --git a/doc/grpc-polling-engines.md b/doc/grpc-polling-engines.md new file mode 100644 index 00000000000..65aa5225432 --- /dev/null +++ b/doc/grpc-polling-engines.md @@ -0,0 +1,154 @@ +# Polling Engines + +_Author: Sree Kuchibhotla (@sreecha) - Sep 2018_ + + +## Why do we need a 'polling engine' ? + +Polling engine component was created for the following reasons: + +- gRPC code deals with a bunch of file descriptors on which events like descriptor being readable/writable/error have to be monitored +- gRPC code knows the actions to perform when such events happen + - For example: + - `grpc_endpoint` code calls recvmsg call when the fd is readable and sendmsg call when the fd is writable + - ` tcp_client` connect code issues async connect and finishes creating the client once the fd is writable (i.e when the connect actually finished) +- gRPC needed some component that can "efficiently" to the above operations __using the threads provided by the applications (i.e not create any new threads)__. Also by "efficiently" we mean optimized for latency and throughput + + +## Polling Engine Implementations in gRPC +There are multiple polling engine implementations depending on the OS and the OS version. Fortunately all of them expose the same interface + +- Linux: + + - **epollex** (default but requires kernel version >= 4.5), + - epoll1 (If epollex is not available and glibc version >= 2.9) + - epollsig (if epollex, epoll1 are unavailable AND Kernel has epoll support) + - poll (if kernel NOT have epoll support) +- Mac: **poll** (default), poll-cv +- Windows: (no name) +- One-off polling engines: + - AppEngine platform: poll-cv (default) + - NodeJS : libuv polling engine implementation (requires different compile # defs) + +## Polling Engine Interface + +### Opaque Structures exposed by the polling engine +The following are the **Opaque** structures exposed by Polling Engine interface (NOTE: Different polling engine implementations have different definitions of these structures) + +- **grpc_fd:** Structure representing a file descriptor +- **grpc_pollset:** A set of one or more grpc_fds that are ‘polled’ for readable/writable/error events. One grpc_fd can be in multiple grpc_pollsets +- **grpc_pollset_worker:** Structure representing a ‘polling thread’ - more specifically, the thread that calls grpc_pollset_work() API +- **grpc_pollset_set:** A group of `grpc_fds`, `grpc_pollsets` and `grpc_pollset_sets` (yes, a `grpc_pollset_set` can contain other `grpc_pollset_sets`) + +### Polling engine API + +#### grpc_fd +- **grpc\_fd\_notify\_on\_[read|write|error]** + - Signature: `grpc_fd_notify_on_(grpc_fd* fd, grpc_closure* closure)` + - Register a closure to be called when the fd becomes readable/writable or has an error (In grpc parlance, we refer to this act as “arming the fd”) + - The closure is called exactly once per event. I.e once the fd becomes readable (or writable or error), the closure is fired and the fd is ‘unarmed’. To be notified again, the fd has to be armed again. + +- **grpc_fd_shutdown** + - Signature: `grpc_fd_shutdown(grpc_fd* fd)` + - Any current (or future) closures registered for readable/writable/error events are scheduled immediately with an error + +- **grpc_fd_orphan** + - Signature: `grpc_fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, char* reason)` + - Release the `grpc_fd` structure and call `on_done` closure when the operation is complete + - If `release_fd` is set to `nullptr`, then `close()` the underlying fd as well. If not, put the underlying fd in `release_fd` (and do not call `close()`) + - release_fd set to non-null in cases where the underlying fd is NOT owned by grpc core (like for example the fds used by C-Ares DNS resolver ) + +#### grpc_pollset + +- **grpc_pollset_add_fd ** + - Signature: `grpc_pollset_add_fd(grpc_pollset* ps, grpc_fd *fd)` + - Add fd to pollset + > **NOTE**: There is no `grpc_pollset_remove_fd`. This is because calling `grpc_fd_orphan()` will effectively remove the fd from all the pollsets it’s a part of + +- ** grpc_pollset_work ** + - Signature: `grpc_pollset_work(grpc_pollset* ps, grpc_pollset_worker** worker, grpc_millis deadline)` + > **NOTE**: `grpc_pollset_work()` requires the pollset mutex to be locked before calling it. Shortly after calling `grpc_pollset_work()`, the function populates the `*worker` pointer (among other things) and releases the mutex. Once `grpc_pollset_work()` returns, the `*worker` pointer is **invalid** and should not be used anymore. See the code in `completion_queue.cc` to see how this is used. + - Poll the fds in the pollset for events AND return when ONE of the following is true: + - Deadline expired + - Some fds in the pollset were found to be readable/writable/error and those associated closures were ‘scheduled’ (but not necessarily executed) + - worker is “kicked” (see grpc_pollset_kick for more details) + +- **grpc_pollset_kick** + - Signature: `grpc_pollset_kick(grpc_pollset* ps, grpc_pollset_worker* worker)` + - “Kick the worker” i.e Force the worker to return from grpc_pollset_work() + - If `worker == nullptr`, kick ANY worker active on that pollset + +#### grpc_pollset_set + +- **grpc\_pollset\_set\_[add|del]\_fd** + - Signature: `grpc_pollset_set_[add|del]_fd(grpc_pollset_set* pss, grpc_fd *fd)` +Add/Remove fd to the pollset_set + +- **grpc\_pollset\_set_[add|del]\_pollset** + - Signature: `grpc_pollset_set_[add|del]_pollset(grpc_pollset_set* pss, grpc_pollset* ps)` + - What does adding a pollset to a pollset_set mean ? + - It means that calling `grpc_pollset_work()` on the pollset will also poll all the fds in the pollset_set i.e semantically, it is similar to adding all the fds inside pollset_set to the pollset. + - This guarantee is no longer true once the pollset is removed from the pollset_set + +- **grpc\_pollset\_set_[add|del]\_pollset\_set** + - Signature: `grpc_pollset_set_[add|del]_pollset_set(grpc_pollset_set* bag, grpc_pollset_set* item)` + - Semantically, this is similar to adding all the fds in the ‘bag’ pollset_set to the ‘item’ pollset_set + + +#### Recap: + +__Relation between grpc_pollset_worker, grpc_pollset and grpc_fd:__ + +![image](images/grpc-ps-pss-fd.png) + +__grpc_pollset_set__ + +![image](images/grpc-pss.png) + + +## Polling Engine Implementations + +### epoll1 + +![image](images/grpc-epoll1.png) + +Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` + +- The logic to choose a designated poller is quite complicated. Pollsets are internally sharded into what are called `pollset_neighborhood` (a structure internal to `epoll1` polling engine implementation). `grpc_pollset_workers` that call `grpc_pollset_work` on a given pollset are all queued in a linked-list against the `grpc_pollset`. + +- There are as many neighborhoods as the number of cores. A pollset is put in a neighborhood based on the CPU core, the root worker thread (i.e the head of the linked-list of workers queued against the pollset). The whole idea here is that when choosing the next designated poller, we make a best-effort attempt to pick a worker that is NOT running on the same core. This way, we reduce the probability of the current thread being pre-empted by the CPU scheduler. + +- See `begin_worker()` function in `src/core/lib/iomgr/ev_epoll1_posix.cc` to see how a designated poller is chosen. Similarly `end_worker()` function is called by the worker that was just out of epoll_wait() and will have to choose a new designated poller) + + + +### epollex + +![image](images/grpc-epollex.png) + +Code at `src/core/lib/iomgr/ev_epollex_posix.cc` + +- FDs are added to multiple epollsets with EPOLLEXCLUSIVE flag. This prevents multiple worker threads from waking up from polling whenever the fd is readable/writable + +- A few conclusions: + + - If multiple pollsets are pointing to the same Pollable, then the pollable MUST be either empty or of type PO_FD (i.e single-fd) + - A multi-pollable has one-and-only-one incoming link from a Pollset + - The same FD can be in multiple pollables (even if one of the pollables is of type PO_FD) + - There cannot be two Pollables of type PO_FD for the same fd + +- Why do we need Pollalbe of type PO_FD and Empty pollable ? + - The main reason is the Sync client API + - We create one completion queue per call (therefore one pollset per call). If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a pollable (and hence an epollset). Thats a lot of epoll fd create/delete calls + - With these new types of pollables, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the sub-channel fd is added to the pollset, the pollset will point to the Pollable of type PO_FD containing just that fd (i.e + + +### Other polling engine implementations (poll and windows polling engine) +- **poll** polling engine: gRPC's `poll` polling engine is quite complicated. It uses the `poll()` function to do the polling (and hence it is for platforms like osx where epoll is not available) + - The implementation is further complicated by the fact that poll() is level triggered (just keep this in mind in case you wonder why the code at `src/core/lib/iomgr/ev_poll_posix.cc` is written a certain/seemingly complicated way :)) + +- **Polling engine on Windows**: Windows polling engine looks nothing like other polling engines + - Unlike the grpc polling engines for Unix systems (epollex, epoll1 and poll) Windows endpoint implementation and polling engine implementations are very closely tied together + - Windows endpoint read/write API implementations use the Windows IO API which require specifying an [I/O completion port](https://docs.microsoft.com/en-us/windows/desktop/fileio/i-o-completion-ports) + - In Windows polling engine’s grpc_pollset_work() implementation, ONE of the threads is chosen to wait on the I/O completion port while other threads wait on a condition variable (much like the turnstile polling in epollex/epoll1) + diff --git a/doc/images/grpc-epoll1.png b/doc/images/grpc-epoll1.png new file mode 100644 index 0000000000000000000000000000000000000000..3ab9a4c7d11b03eb137d173d841e94d16109d551 GIT binary patch literal 36205 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 PaQ6m!#=7|151##BP3-R2 literal 0 HcmV?d00001 diff --git a/doc/images/grpc-epollex.png b/doc/images/grpc-epollex.png new file mode 100644 index 0000000000000000000000000000000000000000..86dc0005b3e76a4c0edeeb04354e8328b39e568b GIT binary patch literal 52651 zcmdSA_dDF-w>FwYbV4H0y9p63h~A>t5K{CJJ$fBwv_$V+bfObwg6M|mCFB_t zWfPsA%tWl|zqqFc9ak*caF=-j%61HEcKCzVVvhhThJ4`?gL-`l*(xwze#Pbur+vqP*e+Z4{uOn}a=q zXi{$?siah)FkB@lAu&Inb>s(g&_~w%z`(#*F*5S|vLynUO9ffB+c7<(*OQrvk+#>P znD57pb6IYvCQOdos2Ik-J$LkM=$Fsv+*TG8GjHvOG4R=mBno6E`2XQgIIHa2H)vOj z@IDL<1ALU0^`8=V%&#s^{SXMmQ>evKtM{d|hP-^2{)mgi$g%=$rfR#)uS}MoQoHT# z-a~=7#O!A&A^kKWg_XG+SaUP&`jvkn1W1DyeLP>_E8}`{!z>P@Xj( zgLM!SVMU8=)9C!iK1kAf-#Ph*i(|Zg7cn&SSzlcI5{=#7(n{$I^1HI+3byaTV1^*u zBJ&~pYAGlHy87~&7ft0mpYN6e2G&Dq<7{P&I|8gf9Mb#Q+xQ;99e9OcNcz`oeZp3v zR`v9POYnv_dsK;Qs&>F- zg?X{cnB3ryGPMUEkM{RNu91_=UL}x6Z=$TiOCs2*m6ugJhyDb?$JaBGtd{?O=@YF9}05H*g(s1fyNi=JI;(yYa(D03!G)lo%m{XmnW5#+ zSKZp^f>GZabV*u^KIh?@wekkt7a0S1Gg}{c$NL3jpw-M$181O-3G?YuVak#cIeF8j z!5j$i$O~|$`z77cGmR=4g=t$d;gQ>>PQwWbwsH%vrO7bNa%X98<=nx8TbfbmKyK1R zl=}zd(^KEivRN;6W+ljA<=?6FTbo-#R4@22^bqTW_2L1i zsoT3In5Jg>h$p?3##YIZe+b!^ZAoCn(56XPQawFniru0)mmkl5e4zA&zoIq10fmDx z(EJ6!myUUrhw_&hSYz??G41CuH+F`#fVj@wT{$@^Xo+y zHq4_WqzFyH(;NN`8!BnvF-~86bDrdKc#+rSQF_za-fvP`$9$S!c$!<{<$d>%*^3u` z#8wq5GDpI)>yXqEuY$T86x={CUjE#l$;RtP9p;_SfT0`!dM2LKlUc#>t$m|A~zvH0k0eER{(qVZyB6Q3Yx)Mdhb~Z zOHLS@CIV0WDkeuA+1!276v;iQ=kn_`2ouov65X~2>%MOp`ZR{o9GPUoPmi`pW?-X* zUA+>m$MZresBgD0CN`lzx4ul|Bs^wMh)TrXrtTK+9?RxS(>NvpkD-J;^JwCqM=%Ph zP_=uwKE720A?SP!jXROLhJ@pr8Nk0VV=xpQNU!;G&xa|qaBf2_ZAlZ^R$?)@#Empv z?tiGX<0kVG*jwVV$Z{-bJqTbBfj@E@;Z=PX_Qg%zICJRedQDasV;D80ZmK)b+87*I(`lgI&I1YE~GBKsmB_vM@>A}J&I zE?aUl3loe>!KU#(uVf!y|uf~<$}s%q9@-Tc-K@@>gN{BbZb&- zoigv+^EK=ig~@)kM#ej{eDPqgBLijA3wHht%E$xG$87CdPG0jCT(v~|lnEmo>!k?E zgVD4}>^_ex1lVcc;WlFQUAK$G9*jQ~l=(!yWT20l=fj#^vD(NMQAI8%(v-|-0%-MW zn6Y@nvX0+Nx-*rsjt5rw^fAkkzfZH`NN6-^eI;TkFRlx9c4hg}mC0>8h2Q1T^0&Xq zA{iH+V!?^*p0%aIaY%(WTHl7<8oUd|qx>{IpR`Ijt$A{yE)1Wnd!k zwfK&Gs~ljVV%_y+>jns-Uda>1PQBWzc9jd4{ne^KvEED4_r~DJY>?6o$)I|-t_vmJ z>taolbm!?Gu-^IwJD1BWeT%>44#bbtr=`S5)k!Aky_Rq+(lpqBtp8QcQcdYZ>@$MW z2?|ABPsEPr5czey6ckJk1B)z)7aL5^dmzp`ekV&Ehl=`tho5(P7N_cm@7*((v^zYw zQgi(1vEFEJ?!?uVNqFO2DkRV3Q7L754|LvU;5{IyPz~JA+gKp7&boAuV|o)A~9UfQKtXkB)jm(3i)8Lv2y1Huz`D&4_9L^X>-!BdrfbacF@NjD%9y9n5EI2F~;(d`qv* z+HM@_=kiZLeEYz-!8*t2^Bo5%bD20hk`z0Vy(c9B#h@OgCa6@E!_48V{pw<`hvI9Z zahpHf?BBMldl(nc`%OxU1n^9@g&@*>Iyy^%F$NR+OH#Xwcvn0)|2Q9;)ZpZL`mfiy zxB5uG_ho(S{g-kG0{cNaIKX2{H`f;gQmq2DcOEXrDAzJE1~P=m$`Jrw2cv;fVZ&2H z=xlltg_dM)*m9u2|ZMlt01=|Z)X%#r3E6U=q)%b$@+9}4m+We713{K}Yq_d6+ z&&^pDA}_zZ=?g5J!o7hF56{f#)>I^{KwZ2(vWh+LOMVG^(d$p_e{}fa!IsZJJoj!J zzet=CP|17K1LiXim6!erqq2KwDZz)3)=qi(?dH@6y>j)B&SlGDaaGHSZz72RSMcdm z@Z{S!B#~e3w>FG>3}T^vVKwZq8OOVVF?q}# zK7ESEtno8J%*(r`K8mdV_Cid!2e*Y`HB&M|FaCS;4O9<*2K>qs%MH3hJ+hjMdGrXH z?W!wQQ<;~aFJsqo@}BP7V)%!?|CdBh&_(mLRrzL=z$)$Jxb(HsLH1cZdl6Q`e+GHj z7YLaCYmneTn){*JEZV&!p|^X9{^#?5_-6-RiJL3MH8(d8hK7bFMo5-HAnoqhwz!3% zjJGf=gqZ4{O4p(I=-g)b0~_M?&NQDnT29@!zDJ}p+%7PgAc zK4^GG@=W@#4ZmXr`HDX4xQL9Lzq>d()Oese1tFkXi&K)KpEqZK#estO zNx|(xKGIR*z=#Oqt(+~uCv^Vqfmj^#1F|93^$1COuF1B@+WjSVcuwj8J8BVi*La)&$0`o2S3-a^B4$bVk zqg@sFwoOOW-FWT9-xWmMI0h^IKgSTI1XS}9*ksZOf<*x~9FqAX%k0YUHe|oA7*}`< zQX?l=jnBsbA7 zOU&f1T`UvvOLZRj)E+i;C1{qncCeRuNY4x$=4Xj{QJw>{*1_U489aRsLDq{^5*otP zAYHqe+X!`k`Nc}R4!P+7tOYj>TR?g8^ zJcSigPaw1#bV;~82itEoY1lSqL3pzCPceI;@$Zc6NOK-3%$Bxz6zmoch_OYVF>qOU z1QW1xG`Gr)6SF|&yzZ|_QzhMTUGzvoulZL|~Hz4ntXF{&sU@q*|z25Apx>VQdUNLHcv%4WF2VLk?JTZ>uPm*x{f*nZO>AmK+ihQ0N4sBf5QzW($CXCq7%yaD{Yuxv^6`g8qad5#g4-5;3Ylr79@kk>xUzTqZv!i(UF5EA)Z(81L$;pei^b z5j*buWQNu#dB+`%*9d7pETm%j^BQg4v&E-fJ{mV|dvJ&J zPTOl0*OXu~lw9wMs0xIj$WgZEUdQa1IPKBQ{!8 zYcn##=4~GPJXsX8MkB;vDM`1_he}1Ol4#l7!?Q==99_C#KdI>3`iP>Z zq+6!;!`4GFYmyL;pB_M1@5y&4-FEe}Ki+$tVq5iC91zV{oG#K!K>x3UkS%fcpv$OUq8<=3)amWtu$Jeh=_CWT({oULu$E z(hCoZH6YL-WGm#Yu9Iq)w|QTz-KhH#^pLSat;>59=+mWtbiRYRUWIrAi`|%kGY8@j zt8N0J{fXR>(^lr0E9Jv<_}u{e2&)HHUgM;a1eeHNL(HuVeV-m8<$WY3_v_D)|B3kfY` zcXYK$O9m=5+Wf-tfk|Nat+>kNN!RP3xF<5+yD7P4pO@Wt9&^pK7bdzd1zeu!=4|m8 z9~nIzF>Le&^&SFGbC*ljB;6IVa&dbuSl9X%QESH+GboS3SL7sa>a}A|-hhh`4UudxiSl^H zCGg%uwZx4h1_^yKdmN&L7zf3?ZviR6A0H;6A1K^y+^+cgTTnKx1JX%LhNm#@o23=GSLXJ+Yt;bp$_dT)4si%89|1Up8n#(>wvT_Fg)>}>o zyQx>#iumj>&`~)v9k)S>qR-CGdQT6xxOjklqRS05ecwYsJ2x<=hgT@H*mYRKciP8DKvU9aCUm!vm zOh-$5wobi;5d&c71P_TqepQZqXDHnB`XTW5Ff_U+WWf_csH{d>jUSju`{%P>s;_{&yF# zTLz8Js~?S!R2!mOnhJ{ppjTl9(OZ?t;tP2J7&dfBB5>WH+0lCKiaTy!zn9-h6s8JO z&-={@X`d>42RwP?S@{aEftrO^$)1^B3QT(%ISk$0BEgLN!Y(;$cH$@>) z@X)D5KXdmKD|1FI+B&Imz*B<3#&a-Zr~ld3wZjvUB+u!qk<)-+wia147nzY$w(RSY z0Vuj=x2OXNd@=SSct@z3-G#!eQJ!G&AfyZ7eV=w1(x@$UMj4PKM%KxQ60OJxa8qQLrmy2 z@(H~wJRs1Tlfm6t5M}rABz>Uvm9AG6J)&L>VfiN30rtsJ>Yl(u!yMn$My{OjWEIypw8>|yHt{N7 zYDU{~hs&j|z6H9Y`4Lky{vB6IvMa$Eua_HbZ_0rjE3`IPLHN_yskcB-JW#@ZUQ(J4 zo&wM~k<3>qY#6?GsrUgRij>grFUf4S@W8gp6vWhUv z1rjO)BcBaR27O4XdkgcWfLtGWx>!K*j~&G%~m+I4!`6nCR8(^;<4G zqa9#T&OrSJ`ZV+);3Lc~lXx#bXzZ(o50UzlLwaP(F@YqMd5TAWWal~3WZE4CfEPKB zf$$c$n7}HRHs{CDuzKe_uDRHsy7gK)74LGq^3U2U4T*V)`Ot-lOUxjK)ZYtusud_# zTjVnkM{K=jkmGMbO7PSaHXXOH46C5!ja3`|-aMF_;B~5q^nNSXw%~pOFc=-UO*@eP z&O3okHSoKV5ALu=?`>6-aPX^jgTz*wFfY+^QV44eo@d8I^!kh7VNl&W{Y*6UeVhST zA@yA!=8;qZ&n-D{$VHHsqrlHzL1Z(L3iv#H#v_S+>$w`c zuUu*(x%UFVhq$H{RFcxs$98-eBQw%N9g%Hf8=S{v?8L9Z>;k6j7I)%}_#FuF%xvNe}2|3$EZ~$lt!m&LoBl)jVxCof_s%x{IIv<{3)a zBJizeGcew$T$8}B(nTW^)OMgx22K5Q)Ev4sXD>fFN}DuEH#1*3b1C2>7!u@2X?|$! z`74i6@?@po>if0zuF+BVO2^mQCb98QZ%(@7kow!IPLd7`A-nNtM=}TQ=SU*eaz^QO z`>Iu*+s3hH*?JY#%p}H2u&<%=_liQ6rJ=YF$E`DaTP>>eYH^EwmQx_&M;j%U` z;_q-|r>7jC3-w?m>Y5w)@ThE@xR6rtd zcS3#O=dAB#apvR#*E@x?&U+HvNrerK4liJICWcgOh3SPN?bTydT%pfXLwTvzv-P5H zea^8904$pZQ|CldiCaZwD#yjzS3Z#I{7mm%c$Q#Jo`~*k;N>3@ z{<8ljtDZOXuXQZB6%2<_i-s@74>b^qgCOrA%ha-s+-u+bX;dgbE0w1k>6G2E9&nRi*B_JBYj=2DPw$Ty56fY-OX}}Kh0D${EY8W zmvp2sGd!lPGO9=d09_zvBnBDsG$EcM6z4%rrezu4+trA?PdIGe9KB+czrX%uZjH+h zNC5xdcAGq&_MDaJj6be25O^5K3@_?_pCxlyrqvV*e1p7eh-y}^lQ~d%iuGUq?ScfDkW*%yqtc5k=4v9*MNbS zeDI#n!gKWxS&xHfrezewRrxURBCjglW~h_N(d1-V0<^T+^L_PXTi?ypj>VljD>0@@cE;5#6+4P4?~S1oVdjn{zDiF8I4gu{i z`3EP1!5zGl5p2e>?&32HIUK6Gn}v8-FCSpG<5(<2Xo~XJ>{(SrES&ywGcut5`)RX)M4ro zdO(8~*~I`1ju>>z$u(O3_2$dmswLkun^E%scxx%DZ52;wclmlTWxqhVC07+3GAv(~V(Wk8|BQ8Ob1aSQkCkcjh!)~GO(%cavxr`!B_Y<%3eeb4ZG4kA<<{!ZX zZ8P151Xl#gR;r6Db9Pdl)h)<-dCSC9yua84Zs(5k!b1NDN*o*klh8U3EVCpQRT#i~ z9f&Tbi!WSK#|xvE_d)^w*9C_Ume;8Bo;@cM-+M9Tc6~WD7ldE#hRsIVt{3~e`v7PM zg7zrtYyvwDS1=BMXSp3S*Ft2j8pSvJ*%q6ncDgC1#$Ic^6&kUoM~Se=u1o7XkY1jA zobXSLa+K{Go3_sJJz&J!gP3@AOtD>rwu_SWt$2}dxiUkUA9(qry(g!%mFdSXY1U)K z#P(A7d^;{l`|_%oMHww0>fnR33V^RtgJKu9{1C5wq8F$$k0c(h3!kxHt({n-+GSo{ zuQk4eAs_8>-7V^34+GwPqY?+RlgEPePe$Uui}4BvP9+rO{5h0m!LrR8;;BS%+i!B8 zWDCXjTFB9wd^#BsXf?6D54xYW2f%@q0l@?lI#rz#%--~3AoVXu#4)7R4O zA22R^1gkA|WRl->X>6t|eN`Z0c{nIO_gme%m{WY~5%;+BDtzxT;Ocd{gb1WA(V(xC zstBV=;`2)>VA9W{GmU?7Sso%Ad(`N_*gha8t#TbHmnt}g`}nj_*GJfa4?=YtcN}-s zrES3~c)?@tE){^{_Y=gP)&7&+Z~X|(pTs+Gnj<#oo*a=_MNMa z1OjZ>Hc%lDB2qxQL32)RL6dV3!4B{7O9L#QIwrySDIZ97vm#nn{X|eW!D8BZ!{*p5 zC+4@g!(b;|@BEF^T((iCizUn>jOURWxDG?O94CR2Jo;kpRnKkk+h0kA1rtL$>IHLE zKrJD<*JF`aBweaZGjqST>pM`nexJ|L#if;Dq>L52bDqo4dD0zQCFK>taAPqD91G9M zrC18(Rgdm|GWm|vnV!eh6e_fpZ;s8yP>KTD1{v^nbyZp)3(?p3t4H;`*5$-%;wny* zcbW|)eH{+2g?Bbm_JEc?aCd_5*}uwO!MO68DOTYR0~gE~k#)toKB5jfC}r^D=d^?^ zR)f$F@bB{8QMg`jdjuu4C2M%t_fyUs1#umc*x);Cg`R=hWGzF&$u)MD)7o@PzvneT z97(LARfPBN^klu*!^PIS7dh!?QgvsM`?w(@3x!mI6DR(#KI!5diEH1P^}DQiP7tXm zY#DCczuRd?t3?nY@7HzSfX#od3m=cNtLoco0s=t8_|o5IFyfLkS0sGTR8bQ?l||hc z@opNsm3^AuGhA!8^>zUrjkdFex^k8+fP^IVVnDYjIlN9j{!+yWZ|$Ao2Uz*DTWd~9 zy8D{CnQL`I+Vu+WYOFjnCpTz=pBlDrse|pH)5Jf!6-z2E8L$m~gmHY#{Z)1Bwo2>w z{mbnLim8?dBhg18UU~AoZom~jVc|q{=zGbIG39L5)rhNmpz@g*<2|@mc}l~Q8Z5J> zzE^xZ4ufpaZ4_XS)o>zDeA_V*Ro{!z(^*OVQT9uPuk#`gUwnw}C{Vn!It?Hf$n4gH zTO-8QDwccHiZb{qj17-N&1kb3!Xw^7Pqh-y4HG8v?V5K#ehR{uQo99l4kYDyPU>9bddI@Xy# zGlSBTysTKRn|a78|8$xMZlSxUa%Nc#fFB9x#8(i2NI#8NQDA2AWTd+aaJ$s#PRW*C z@Kv26r_uSwAj7UC;y7vdK8=yWnem_#mLUd*n8V1FM^dWTc997b(#}kJvb&V&IL}3d z3&QdHff^&@Zuy~i#8wj96d=^&&k-u+$aY7TTT3Qv1&e`dEPvmujV@A9IX~us>YB{%o;V?D-GQ_tG%aA z$+}q7o+MOiEQ}ppR7+W96Z#eVye}EG1d^%|DFALUUtJZJXVMqnL2wJIswi2;Pcl5DIJ=Oq)x!ng> zE&wHGUdlFPu)>P~(mu7EUiw|g6C{b?MA}A<&g*qXVzxGF;Ia-2)XKQ)eIG!sxYFiD z_%%&Y~k=>E}#H{c zZ2HU&;><4~$`OL@#EEV0RM6tZ#Hl>W%0>M)taph8%fd2|jSgV{t?k-4@#DQNF~=ly zFH!J*M$TL*Gvk`S?C#^}qgvUjRMOLU%X58=QLntQ98XB)XN!FE)X|LhBCRy-mgPzI zAZxGVb3i^0R$ykNW7}H?$9Y;r29SqKOH#Yek{__T6Veb;C~_VAB)!`nN5X|DrsQ}1 zQDrPJYq3OY=_n3#I5uoTWy8TtQg+w&=+LmRo&?1;!5v;g=A8^T}eaDrf8R z>YSN-J>6%^M7e(0A=sf{&dOX+pSlm;I3C^C@)nAS^oZ9g;G~7=W$^=*w~OVv)9d8< zc0O(ib##O--(tUIQRvUzfqvt-O>Ra65oKS_Y2Ow&su|V$tcn&@hCUhgG^_4)sK5xZ ziLcyOVhmNs%qjbA$umVNreXyRDNI$tovRe?EU~s0t#VgIrSY5N@p+vLOmBW}5baN{ zwl}!UH!wQYJ~}hZ&P!VI2>Zjz_7u1Y=Aj_D6|QN88<)(miyIgX&`6(_OhAK)NdllA zB*>1D?FC&w>t(;i(LMAPY&PiOwYh^(r$qIxNa{BUTFiL;QGZ;3(W3j0+n;78&4-20 z!bYwl?}`>*F}r(S{26yN3_#7>$&>nM62qsEh1$xcT-hhYxlB+b?~LL3x7SYB9N>@Q za&sp9Z_JoNrhA8!fx zLc~Q3VqJZrCx}l&RR7q^WwpQ?I<_kN9oks@<74oCIF(=xDUwP^pme^F(r$kxVlw@$ z>}OT*GS$!-WTd8uD4Z)+_7c(Dw$qF}9y}qIeZWo5Y#;Nfu8sKz06Or&?)z#D(*-lq zW$b?N7NTCsXU)jx4$cl4L$}in+ROuAtg}O@1D@TpWILdCa?Vnv{_=X$n;B9m#~MFH z6HHBkJGZ-feMgfT>s=VlXop`OOQ~lJACCFZ%77>ZlTfdi9aDsB@l9$Rg&qhBm9)7` zHM*?h#ecnj(+J<0Yd+fY_5pW2gk}?5C88;HzdhDWqp`R7#nDh{Y7~|}#_b5BE55jz zvo;RAJu2FnlW<#t0A2)4{@i+SkeTNV?xIBZmDcR}9F1y#WK}WJf2oVrFLVdQQ1hv; zSu=wP=uob?`CB<5g+AAV+K_|sY>o8ytB*oTM22`?sYRd>10oe+q4=cW`^jiL8!iOy zazaS#YH^9kw%_iY%)c&QhqA`Br`8s@Q!!@pXLiJV4qs-LL0AQ5=)2DOnvQv!!cNX) zn9YqRrsTtdIMd=jg*}hQ@k+-oxZ|0WVv!O!LC@&`3v=y2ZY)sQe+}f?CMc6)Tm*D& zaCQV~xqPsS8MCaI;tS>V`RnV<*y2}~Ots1L?x>Hxyw})O^$#D~gik-8)(7(rb@$i1 z;6f4KeOnxIAV9ODSrAN;I5*vd&?JxJOZ@qI4)kuLW z%RyLEhov?AP~DF?vP!WubW%7WO-lfaD-LSVEP4S5l4XHE4uA80D2<=3WV97(KHN)r zPdM4J>>O=9$&-?j&^l()zKU0e#Z#>Cm~k(Gggx zh5vf`$8)rfB>v(VmecPd)71*Vv{XNafBc9x+cDKswNL?LD1)Dy@8nmxsU${_&)lZ` zT&iIm(lh;5kD`BXbLgNi)#M%KXs5jD>(@1lS2RD75*}Z%r2D4hauUE;DY5Qbf%`ww z;~&eVdh|tNv*ssjK;AWktO>U8EKLqZ7crU?8MU7T4 z$N!Bc`gI7fqcZ5HHS@GlWZv|w&%YG08oA!E$tgx<nxt!kbV&z zqRKFm);FG^504R+Djvbfik}Nb#2j9%OV8Ky7T>Uad>^=*-SUtWt}zLh82(;+fKUEZjt@+ z$h32|_1?rr;<}q&jpO)(qsfb~#cO^y#vUPNPmSChJ(%4L=wZ#ll`;+k)jK*sb(?xq z<>kD?PN!u8rt-;rb6WGh#o|F$ET09pg7Mpc)1Q-3I%6BENvx<$(^y<>#KGsynOQ6f zC1h=)7PJ~#!6lQKoBwq{iBF@}@Vv@b$(oEiGRqy7g!mHV4;i^0dILgz!vA`Gak0e) zT}t9>)$suNP3wbfuP?7FMnug`d)IF!_IVAmiHMdr3-gdgP3cn?(8+518Ws;19*BiKu`XX>aV&x=s!V^>LeE$2rfxUPBvb5UA|46nT zWKry#JzqMej`rw>we;4xPnGMhK7Yv5r^#Fp;mzAd@av&{cnKsUPOD#89~;Yd*&(drORx7kUXidcRyS*~^hr0!;qM8+NJr9M|vR zbfnX`f`fX~@VZc1{|Ex^XbjrNUw_5lCx@V3j*z|UM{)T) zbzfrS>XD_fb1rrz6)TA%m4&TBuabo$N%@fS%%y&|Gfd_e)rF~)_~cCQ^-G7vj^>fK z?}V=Pvwi26Tc9nuG64;?SL3+{w&v5;;-HC~H)jVM0Z4YQnU|M#`ZJ@gMX08v7o~A* zXIHO>O|F3U<}9FSRClS0Q`RNd*Jft;P{#dQKU(KIh}tr#bCH)MGCaZ(OO%+;Qq9JW<7D(tZY6Op?u| zJ;SuJ2j$Zemzn!=guVo?Z<}aO;$lbhHvyEG^tgQ4jSv;aRbNJPPVz?A3#UA{=ZR3X1~|Cs(AlWMc%;X&?Hne~NK^^zlk`mq}9 z=anKhEG^@(n=H{;(uc>fLUe|rv#*E}OM10Pq>_p9h6!94p{Rz*?#R*dPaIcMk3B0; zP^5~_p7iWB(^u0TpF9(5(D2sq!XxS=`{ejgU2AJ2Z=3wA?nLHb36R1BkZD9 z;>>iM0`=IHyD)Y?o4Tk(1bby6elM^OSI}IMh9-Zr*eT3p^~sY)cVCyG=tbp>b@q8u zf3XCo0+)GHe+7R3fO?y3_hlSAGVvQ1%9>q%{cve}!jZ4_m;_Si;0LhSO#dBTIoYPvkmI&WBHroh~#@G6Dc&`$W)kM zPov1m#>Q$9Aoq0S%y{uUa!qXg*fG=LhjhB;;(k>A*dDL zD^)+M*dMS!N8!VI#(xrQq$R|5b zx_W5RcHt-Iy*SyHZ-GOxyF2+ni6E`Vt$>I~<2oNshQ4N2lX$AqmrA$6R7MmYthFFPM zc%|h22nYz+Ny!#lS=evtsc>$1nsFuq5y9<$Gb_C4)p0z}Fr+MOR8-)7F_oh^`32&&i@B`H4gY2gM;!p_}-KAQ6Z>mL=p!9{VlwlJrC zQ*3WPIcNt3;1ilxN}W^vTRD2dGW1(X-+uy1JQcZ0b=OeF!cw-kdASkVrv9#d2FiZl zb?#As`eIIg)A!qtFLy$DqBSKqm==HHed|e>QP6Ay8nrK1 zs@`j(q3U??cR45pFBif4OP9y5^E9ryr`q%D$!>P9W{LkNF`O4nmDsS~XS=$ptnm4f z>q4CW#x7slsC{)d!yHhi9IAg>RW=pcp1MVp!_SaU*tvI9ew`616k*!%*8pwhAcAX| z25hG4V!G5_R_gcXwS+$*QIPn9qLkXt5l8&NB#l1?EfhY%7E8U;Hi~`V7{zyB;D@5` zv8&n(_&28T3dG{|d~$oq_T5cG3I;~d`Va=%_N;34D1-`LsC8k^ha*WvhTvz;E*pQ4DzLHc$UKm$Z%_@15JMo2APm}WCqu=;=#ZOdl+0YVm4j}QxyS;P$jwg9q zYfC9^^txGL)0-Y{G?o(bH~T}AEUVyyo?URhp8XMUSGakLFTja!{TheKYxzr9-`80h zrwJHdvU@$9-084|eevD>V^-QbeY-7?`KXf-!!t(g=3RY74_|lF7z4p5N18tdm!Q!gLB)qMZCqkao{k{fUX~^M-oquOQY!yF$0b7GbGA)E`2b8hfz+p(=ao=0ACg$+vQ(-Y&HeVI%dgi&_DG$oFuG zPX+;EYM^b*IoNq5{rd+R^b@nQvlA?DQpMY~LNVIcvF6&bvPvbZPIxHBk=*E-SH$ZW|CwQodm@X(#Lbz01kxHD9?-wpkyo=_E)C?KwIM%|}D$#+gEX4Sw{%@d3s z{QaWVs0&i54RLd6*9prOU8)i+OBIWKJ|HIX3MF>jVEn|eLF_DyeN9QG1LR@oAobK0 z7WF?0^#8-vdxtgk1>M3ZDj-T#Kzc`|ccgB@4fGRzJK#1IVXG1nLV>+t(C4mfIi!}9ZME#FjUBr5p()H;K~z% z3yeb?X^-w?a-J*Sh26HnM1oz!YJiam^ zm8&1e3r(8c|4Yo8O@Q3x1PD{i9;!c!pxJu-X|!80@y+z)%6>Irb@r@K224};+WZpd zYJwr>IlYn*qnD-}t2DgH%sr)@yJF;&4R|M-(i|B$X^8Cpg=I@SfAEFB_XO7^oUunL zR_bys8x?(Z$?ZK|nET!2)HQbZ@+bkQ_?s7;apeI^@wJ=XaW$h6%uOiyWt`ZJ=Cz{d z5lmI;!UbWbhheGvceH*_d)F6JeM*ijGhD~A5 z)R%^<+d>HfvM)&8kR)+Oe|U502$0h*o8IMnTy~LF($CdpaU@A>ji1a*mI`u#M_?l1 z3x#m66XeSE+ZvO}QU0+UW=6G~?SfM>Sf?99Gn zZ)2nY=0Ge7%RT0V-$#Afyo{?avdIXLqSCMcH9n%YR@6wVUGa9nw0(j!bUL_q0Bk89 zDiR4PZ(q(pf@PhGud#u4@k#h7$CII8@*c~KZ1WH{xw(vf! zea3OfQ@rTWIsMrQTOj)Sr82=|@gFM1ml2sEV;>yn4AOLA1IAl-kpvr+lvAO9S)qm# zMNJf@Qi6B1_a)1@Nm#Hyjg~4VKsF}gt;1`rF7N!o!a%r}!?5-JU0os&Xnf70byE4& zUQ$sdaC#vLT}JE=E>~7FP>=;G@Bsgoc?qM`rE%SM%I&sZo%|HrHI*_cQYj5y{|l3o zqsV*d8o)B@_^u|&mA7+4>cQw7I)|MS;Er|)bk!&T;0blJD-BF0gsF`+b=P7RhNN%zsnD{<7S94D?#DlP z^k*u2bs$%4NWa}7UC-TYd{$c=$y>;z^z2iwAk_ms>Zwqr_+=9cu%uCIas`+!1CX`E z&lz|?P5b|}E{vp?KX+F6`W0@s)+Q2_>|v+=X+;yfZ*^{7l%)0uzB{(k{CDnH`VE%e ze}u%O<}QUawe6O|o=>05aH>{8?!H~gXLdHgd_JsokWj5BOqH_ru!+p7DT2>o`_2j%xl2=L2bgK{+(CBL=|1urrf6@uthe*da=?vWjKUv-jrYP^mED@Cjxte zWjMvXpGpcW#TCD)?&9${fDYDIBa)u+b-4bJ!fB#oJKfPK(F$Tc6h%^#Gt@kRQ=Bp1 zPuz{`d6`iY#-rWG5m2MhVV@tEyd{cc1^qG6lk-H2884QkQ4p_K1TG$4*OYxRq+wQ8 z#py4+1M?T&-%)M8=Z?~P_XWF=f}83Y93?KQ`0j+9YEr~1Oj-M7dVK`zNKdFMg*xZ; zJPFLo>SRnu>N(kWS5qZVXSY?S|G;luEGJ zQP#778lk#}-n`j`;<>>(LxR#sNd*}I6+&wAbyt~kd>j;3U6?uA#XYEMMF8%Eph8zyGaO)u~*@4QzhTNz4mhI@hml6@vY|GpIv45 z-@a#up&L(@<{zW6Ex zidoxiZnZ4;)ojxUIzz}-q8G2=Q}$YNzmFQfM7yG7D`6i9m~T8+;P+Y-A0T{lrcEo} zik$}tS+G;aPO^5fZ#NR1@ujo&Y$o&MsN=_{r}8v#HB(-QrIHXbH8WjUVv*-bSd=E- z5t5*QL9rCehB-iU^Yf@Sd_3VdCxBsd@lG$0znMHC0YeE9wynJaz!t?v0CjDm=|2Ky zsm8Ee(85xLILsyLBMp-#sfIo&!@KXOK7p)z*7*GJg0E{Dosal8sGs+x5{0rx>K@h+ z%UZk&U3wtx`>L>EyBiyL9TpyHZpA*_^(41TW36)CPLl#uX&~50?wgI)1dCNzL>ad zla2>2BmW32ciyMdZVvh6O-z4tdRx(<7rJvP4QJ$ob}BL6ZV zC@+_UC58en7rZ4JaJ*se^_XXZSnu88&&ks<7VL5@iNfgNLX&+Cf)V>AdgO_5L?!g1 zHAXV*VEjZ`{2j0LqeKudB6srZeh3)e(A*yCDz8FDTaM+$*iQixPimMHveDZ7(NR&& z)Zk28YbN?l2EG^LvLn4z-R4a=2Z@5}{&w7Q{+{$Y^YL6kocmyFH_NYZt#7*5&2>KF zm*V;V#rQLXQekk^D_~MJgUb?`h+b!`?kF+xbQWKaV(AtS4a+ z-XqP%!VP{&zD1d0)b~x1BbbpGOUxongYM zOYdym{tEdWJdN;N+7GGziv_aV!J`)uFrEg7S%7`$qD>RSLc?q~H~%_9_l+!RoUslifK+|oFEn=P>k-6*T9kVvfR8uDHu!{2h@({ zTcnz&JAzcq@8}15q`KQwG=|=MR0)X-P+~g$J7UKQZRC@l7yI44{;K%h$HIodYH{K! zeYGYg8+xC@@um`nKKY$@?Lh}E^phXj{bhY;c%#2om-Km?x=YV-0)&ZsF>zG|DrFeF zZEWrD*q=N!O#*zc%R9flw|YZ+a5fVBAv9*SJJw|H4Fsv&Bw*?siaUuaIF%sjS`vHp zkw#WP;^LksgJT-q(*i~vOhRtYK zJolrLnxcSr>SqngpbmelNBntqNB40U+HO)1Wm>JqkD*iISE(w99+PWjy?23ec;E!y zy$r7&_ATIq`pgQaQvL~m*!X0qLULZ$KW{vgt?qr0xcnD@B^(N2%wNBN3Soa|#8lM4 zU#y+fz-r(pL`gtluTpP2o?n2qvtTQ^@1y@Gr3%J2cT4#D3KrAC4?g#H3LUeLs{aGTmoeF4n53r&%QcHLuVq|X~kdnMgMLza7?Q? zs}5h&XewJ+5`PDDrMz&wGoHR9)$6P2* z*H8F7LJSm~lT{%Gs~;$|o~m0901M_he7c>5W7e7|>)%OUi`9*8|J&r6P4p6coEaPs z2dF>GM#LkMYP=GsXc@2Kc$cy71mlUIi1)`Hs#Ba{=d>*K44gkGIzE%ZMM>V7Aur&_ zK03}rqidPD1@B{rzTguf@OOyRoN5+1FA?{ z&q>37!$e?w&-pYVg;&yia^z1bQITawtbi)ya(G#`pTBiZY?fSd>meVNNb93zK~9(z zYnh_ADwjd%$ZS-O5K@PxkUD5qJ%X&5DGbe;B-|Fkw?VrcWB)>^-1(H$ZI`W=@sXMk za8ycCn9Sku`e#}d{~Tis+b?PEAiI?waE7-IkSK!lMnU^SfP=s`vyTp;8P~rhV$qk9 zH?4zF+fb~}u-7uG{YXasc=)DaGT}pU#4IP2c?1)%bwp3rEv>rm>X&tlyL)I+D$}ay z!9~076(4^{1duwXqBSqV)3s`(p%(MoyhPQK*+TYrIG`iG28td83+%I_Yg!K?|9>;J zDeEoELVy4ZRZ0R0mzABoS>czK5OA~%Y7`Tih^~u0(+t3Ow+ORbYX%ik=kVYdVgmgl zt$v-k5GU~xkyfsWnq6((yiZQcyrB&CZe+tWr;#8F-vOk2^Uf(2#7(d7ib5*(6D;vw z3fq(xExjjQddTu#MQL9a zwAex>C`o>+X2dAKV7KrUbDN}@kZLi*$i3?Oq}Ms?P@@?nVD*}jn8JzD{7@D$_yIlQ zZIiWO%gCNY_`FYt4G-W1r+*ZMnu%RX2(7IhM-?pbl!VjlYz~Qn`UD;vQ1_H)Yur*A zH*Y9`?I{dd>*icC-uVcE-4;y3ysgG#y9MjEG^YbS<)0{fp7)Mtpu38$LNo+pP8ch` zKYp(%?8EI&f{l*tZ)(!9#BW}C(EY{yM0GhO{G0}>deJ(73CxsWFKvA|VuoLL6hRW5VR}Ms*~(gYDDalRqcBLW~B#KmIr@U z10g&$XAB@78s5jfB*?Ho((O(QJuO_loxES?C+|R#>vg*?D<#7`YDrek-`$6djRtZ|N~l<kcp-Eso*bzDXdWx$dn) zK|r9X)*awJcNj} zjui03IU}6F;bS9Jim|>xJ=2r9R;8c@(HgSl+-3z37s0+V2u_h#5<}xlSMc*o9Dt*! z%UmA5^tDu{oj#0Qx+5Y#VfDWASI}X;=af|3a!0T^yTaS;=PLB2!P(Z2OW@Zl&V?Lq z08kD8M=)cu7Zy6C)v5tTE-dvj6xwQkix{fKsJfhfsCk5s`KbOa^j2J#)STe9sTu4u zY@K3v2U6almUtg-6(nZj6rP3>us*!G-{qefX6+&roCNn(<$Q~4iqm4W4TR;@n5|_N z6By?B$C^`mPpm3{7i=vm+tN}t!`{DRuo>ACk|muY`ptgiSrTZuovdrmNyi5KMCHWm ziD%6-wlYuJ#4{a$+x4q>bF_Ra&)kR`B3VNA_b9f z`dHC8@_qM;G=z?AkXwDaNuKT1YE)+AOV+XkJ3}WjBehCV70&xF&iwpNDLl8?`b#ZB zw-S8Pkp@)P(#nsm0&Z1Vrf4O2NInvzeRTFN+l67*ZFcx1f^l53R6{oM!e+hbFq(tuewZ7^- z7~oM%sCOxVxtYw`e{2+q!-2ZK|M5aFy6h{FJJ}k(aQEm}&$~%SU5}$j7|UIyHfieC z5AEk*`Zn*cf;Ud5^Fv7sdmH*DQdDM4WkzJcqhCZ$)Wgs|596VYQvg7>4P=x;*j=-n zH4=l1}mU72`X1Ql!`gZTHimg6x zE3X&o9^P8_#)=mF9YD06eH@*b*O`K$I#_p%2Hg9<0*O6|C-s7Ww zSkt%tuYmx%vmLP3=vwKmFhRF_O)UlRoV&@qbRp$bjKNBOVn)JgnUZ?$8x^#>+x62; zP?JhoXjU}6-!6OmexC#AfK{@+76l!Tzi!`r)XM&Aynj&L)v%W#pb*nPu-^g_wSjcc zC{5K(j5qm;59#MJUI=<$O+oIQRBld^epUz;{&JhfNcP=Dm7_~!m`oagp8#rKrOHSrPR zM{v04xe)xX`z`>%%&)b=p?GwpP>Ojq{8)CmEN!n?$+^)a1H*knLa^nn>_W- z_MgVy{Z>23{yS|%OQYDWs|6h67C6Nr8ZL9^8BG0Kbg(U|xpw=`Y24vzgRCys*(K0K zqdHYi-(5u{Q~RUYxe^A*9ss+vfy1iSI`T>YBs{N6JW?wjF!s1! zz@nWmal=M|YBGPLZj|;0V@u0k+dGh*F`?nw0UU?!qtS&&-^icDdrpmwN*TYyqN%Dd zb;1w`QR6`0%Ee(Cf2gFV3yvNSHMnC90?-x+8cc~%h*;b%_5=P@h1OgriCmXaoWQ5o zJMUY~))^kC0{tL>mb}-~Yz}tZ0*HZfi1uuEKVcsIEBr_t1~e~Nx>me;BRqI# zflV$x#k~S4LWRhAyble&a}M_FwZT~wl{YRi1r3cj(x4~$Of{W33!Ct7jHrbL;jB{5 zdQHYhAk7IU%Slcsc$F}Rb@J$T=N#v~CSY)6OwF2!2K)DEYSYCE67g{o^#me$PO)Zz ziQ87rg8k!=uZJ5;_h5$;qBbu}VmVZ{#^MgO4zg^1OW`LeZ`yG7cm~F`xo?XWECwGi zZIKYApuq|I%$Tt4d+q~0k_#FcDS~-++wwGtnq2?0IM;kM#g4C4ZNA$xxe<moT?}1 zcYcLR2XyCnt6(eJ-biD?z*~Z-7_;H$H06mydn@>@~RI~ffq@SlRFFQ*D=hlDp+gJUW+pg{nLU$+6#(IK_ zsonVssTs{&T07o;@O?>lHa9T&DHKNA4zzXmQYKg2jUmyaC$!c9!_2DB_LB1KHk{rU zKokjjYy@Z(w4nJ!LTbQ@d?&mRr7Qz14fF}${)h)nW^Jb-2#!PHD+wWPp4nNyO4xo) z+yXF7ARW-yHMSdFg~k4nsFh*8DPYK^f{&3<6~_Et#6L0W<%~q%nXex4=USQVCQ%?! zzp6&wI=&{+T~D3ndk`gVWy&f{1=sB4JX)r$9RD{x)&~ucaY>>_`0FOr?` zmMT{te~h=wpY1R?p!i;<4~*y%J*Rm%UlScK;kSJt9$9sBpL~Q3$!m#kPC2U4Bhade z(3c>=-L)F2-#V6Y@|P!@AZCq>V)0yRQUljDsB7P{BDy&+`G)KLU^rUQ(j|LD9Ho#1 z(zu&`YA+kWIT2k|$okylnWnJ-(VtHR+VmB{H1BKmVTmQ4V?`P(J7f4uY4WauvetUH zOr~9M>EJg-rCQ9$pi%oD@#le7+Vyr50HS*e@JNAj0JVP1AoX1I?C|e2QF%Pk-=cS& zGHU#>HQge24klo^R$ZaY?;m%nir){kU<`)65R9Rt`IFv%y6}{N2^5fo1@Ng7!yavz}s&Tds zN)X)4<_<&OA#$r%tEa+dcrkqZwT+#m2t%U;*(h21x!4!fVc)F}QRbXbKQ& z?1K*b>|rTjkY?o%-mUsowy3eP6vM~*Z;S4BlZT1B0qQPVq-ag=sx7YA_5rXy5-;co z1ct0;9TUsG+;{2vBQfOVRB+Z{LJ_jA2p+CWY>HoI4;QzFFBi9L&%vUVz{lVT=7bw! z=gNH?9p?&$30-$ENu)?oHNYakd(#dg%#VeA;+Tzeo4;TfdkT8qTA^*@+WzX_DOp|wbTF0URG)sw)rD<}DfpSlxw)_b zG8xQn5mFgklVbE3d3?k=`*H51umY)!t!zEu-q}`Wg=V^MCKW}ZsStq{c7YxzbTi;aD*ALXceTQA3RP!`ih!EEM`%Ufh=jh#~ z4eKjQ^pl!)c8&ng_%8qO$h7}T5+$DhX#7Pw{y+D118m=o^!_0rA3nKxqHbf`wywFK z%!HhVsoq6SFVNZw)jx7HWW=Ib=Wis*1!K{ULZ5?)Ka7J|q6#(E7TxYUho^WAM59sn zHpN(OKbs0Lwobg$i_n;;_kER{i=5A(FxjB<$RI}6-5!nCBp`oLS#z3M-Q&<;iD7Rq zsN^u(s-zd4n&yH8fuUZVBTQB&_8OPw+w>tLzX`k{UsUGoUcEnO{7V6e#{xhD+`bZ= z?4o_3*sTr#V?)at*X;7Cf%)zBvU-tr!=HzF4VVwhTk2ml%`=Og4%RhHeP|#z z`~HjV9@`^Ov7D({(gh~rQK{A6jhyB;C;m&?ySE$<7_lx4VQ?~vQb-&TcYus^Wy0?K z{Oi-iK(6;>)u>}>(AxVa3NyOfQO_U;NB0Xx4dhZ?V*Y+9{kHtTa%=2rH}aEnvsD}M z&gDhlnEv!`uI$|OeMBU6Mvv5Q2)rFt)6QGDRziu9#i8Gp9ATNtPsup@4i=N7ebflm zTfKk=2m9~I3BS``rNVg+3~Ow=ke+@soS2sR3-SIi!6hrRQFR}%MRHt?sq)l?=?BbekoF@CSM0gT>t z8{||rHf+1_{~H{>4ZI~HFHm#8qlKlH=Z6DDwhVeEy-$q{|5ljq@xwLXI^XdHl&abu zkmJp<-oCKePN8mA>@aP7&yH}PZV)P87&e0CG-DP}89(3!%Uy+@Z!Os=y7X?eAGbJA z1@Opk9bILtP`>DX5LU&iYg|u;I4vhT`qo?z_`6l=xUEh;)8Mnp zcK{PoDraC6=-q5wrhgtUoGhunain z6bP$gOM}KWQIB$WBVH3lR(d!Gme?0s`uj?sBbIkx=~GI{!9WmFcG;xK)tU!Gesc3TQ2MS zD{m;O6%XYEGu)4lyibFY_g9_7pPc%LAD{;tFyE>^{s%1l&ph|#XS5g~5+YsZV6(hf z{er5UWYp`7(B^Kkx9(Co)B7wL9|s6}^s@v1u2o(pV`^rMUg^NTdw#$uG$CRw0dVD- z?+bu%l5=NWN3M}IX*WJ9wCZH|ZsGEh^}m0W`^z=pAJP(%Z!ofonqUEEc{HN+_u*VdhXC$ii;*s(xp&h{T~1#uNv@@aKsI@0QKR6mnKQeDkHKgE~djnwHtg^$Dw*- z3@9aclcr0Ke4d%h;8wUR=<sr*Dsawg=8UJN$^_#QXsP6E%M0Bw{ zqtq4aaVN&MocJYsb5e5Ed%ztC$f(!;lnd`Enj>rh-zGKioMEyM7xbD@c#U;Ts1qrG z(i@Cj+=3#m12^&KEg}AjCHV<6rE4=#{UyU>Kdi#5W=i|3yJdXWLDfg6Q>q5j-VOX4 zZUhK*C^RD*ZFMg?c%${wA8d3$+%?@^_9!B#xl#bX`iX3b-kVzKKt-Um^Pk2BpqeKu zv!=SiFR1O@igi@MLAJqhj2dSzh$@(pKkn%O9nf{$>Iv!Xx26oPJhSrqg?A2!p{!f< zAG1SkrKt2iPm;b=@coZv4Par9Oe}<1s;dQ`e@*^rstM+AEo@bFOPqgC@pIT`M`LI? zeM1qfyA{nX_Y#-Cw=w~SXNmdIm;ssn)0SIS6C;lBp1{biB*Ocu?YW&C16uCf5C;ZFa0Kme| zubiB7%G zu^*4_d93D$|5D(CRvTuXUlknvm{9k{ccJ65Rt|VDS<1hNHTmC&wdDbHQ@W!3!C!#~ zTwcu~OE5tA|5-R76xBZPNbSa`$^cqaB=E(U`Iy2qjB=E=?`->ZPyh=Rmi(P{fR~6C z8`8H#6;&uMd%Z*xFgsw28(eWsU?2^kj55^QaLiAaqH03IO{lMfeEt68>B8+2AKCK` zZhGg({(~2cGOR&Ac%LDYyIMuupbgS${{lvXvHh&NtJVZ4lLLD@01>J-?u}fehA#l9 z|Brrx@D`BNpS+3>EL!;%Ifl9MgD+|a7$gyQ$DZ$V?Y!I z81s#_sR8<#6Q6}zR0QgGn@V_P8awndzqh0II&bfHDSC13U8clo>Cpdg8`U9AN6P3E z26mkZLj9Hvng#~0pUmoy@;^zx>zAne4kw^YSgQT13R$?Lf;J#!oZh!|aYqXd31lVu zn9X9{4fegJ2uS5vUqJx_mb7pvslF4JropybMs`;0Gne)HY4RY7al>Rq?|p&eoi7bx zCt5s8zGx|0oYRU`1T{2dqks~SdR@l`yB^i?RXkQv*{AR4;0xoai=dNtgO+kfe4oU7 zncw11g#bAr(IPeQ!lq%^5acchLsN09@5*8~i@2iYFjY!*4~u^Jt`cA)Fj_pXd{cv0 zy-tG-zxoC{UKeKn?Ne0JG`w*j=m)g%V0>(_$8_aWDEQiubwCs<7`1SRNkT_PdY$Lw zG`Y^~6*EQRtnmz-3|a<;3sxcc0Fp$m;QJwKMc_nxboLOuEOy`-DZUZWmjm z(<-vn3Yu-m@Ya#`kcniSeJ<+X-uBr?bBS+Z06iLrf7Xq{hQC$ES*9THkqhnT)d}H9o7ZrrQf<)~$iUvzFFJnsWm{o^yVDiBos1Xc>z3etg#B zkKV0#sT`!8lZmLmtM7}hf9kvR*Wmc~$o_F~lj1ANYz-|=QsC@ozwzI> zq@+llsCu2-3Qw=x_Fca1ejo5!`bx}O`G#*3y3VnztRFv%&oX;-;?X{sy(#sK zJ^dF6QGBYUpsL5MTesEN?%X8W5n*Qk6#ts=mRb$bjYJye_52bUr>~KdQd5z#q%+g)QBiZi6@Ol)pu{?SFQ? zSg`iFatRL9^EyyjmQoGk`&)Op6vKc2$Ns#sVJ19_O~PlsJft!S9#scz-WL z7(y9+^F1Q`-Xe<1AUMT&nrxv=uv=&vrFP zKn5ks1)XNSJz2agTI-Fwl6ZO>Pl?~=&obHZM;XikX^-%RAc z16-$2gZcS6i*0o|$Nq(#hu1t2(-(s5$mPAFy--KE)9b5lwkyw4AQ^B4f)8Y+PN(7? zUYZ)HltEBAC*=o0C7EOaX z`MrEtG@NJLX{zoOC3H3RK4pQ$6^va8vQ?igtos;`8Eh3zz?f&2xRpN2pfj5`v7XcU z#*n*ab7gXk`oO3ioiKGH3N&_-$cOo5J;*=uW!rB-)N+X44*@plv0D&T?Wc9#YwEqC zYJszWBYMl*k~Z!b-*W6&e~(+v_79=qQ1oId(){_B;>GDatPSjL;M>!&s4ge_q!NzJB={%W0%%KeNVqgy6qQCbgL1`w(`ePM9sY8UVdsnm-=-~11a*j(zD7B@?yXmNY~`2^!x z+S}Zlm=c9*mn7wa$X(MxoE83A>xX)!7mt+OavJY)36(~HOn!*`PPXrUjwZSCRio5h z5o^g6ZF+(Vz)iOd1+y_=e?EWF`!!@Tjev{q!t>Q(L*~Jl&8K>G^ZwHPQEn6sMbwFj zh}9;S_A9=9hLqzyU51T2cox@>ejZS$e4q0)r%2y{>y+?)!_m5_3!4%qv&N;6K3mrp$& zji``3P^J5YvMr%bWa@Gf*s+Ykj0{M>8|^=gskU>#shjdkLj^dLj;kkrDZF8E(UIL~ z)$YNkPB{`D1vkyfn+cy_;E3(52J8oQXuc7@;eA38mTzfpP(|Gh(ew#o6Mm23*V__# zWbk^hx%3}_2J1R2ZY4-vZu-Va#f@+jS9BGs026^9i2KxLv6DXhV8YhJt@5O0Hi+qx zBseQ&Jm}lWs}?MF8T0K{T5w!BRy9Z-Ugq{A29to}lx&N&s!FCkD>){|w1ROuHqVm}Pm(Q{9+;9$M~RZ^4LnLI*JM-lj(? zqH_!)F{mbA@|wtU+l>KHPI0jNL?t#WSfgC<6hWRq@){Ij>*m# zRqP`!Nt7W`YmV&>sR#oLFHPE4gC4~m&2g{x!Arf~^h-%6Lxco9&Dy&e`D;#0OYIIF z4Uh80hhHLcIeB8b{0sfg;wIC4fpMEfkfDxqgg9JoI0)sYg zqf9B3sW0NV!T^m~n{{rf3%w%*2L36vbhti(&urMkZG?jRqy@|!isBQr&9#+5&xwov zdSwB1S47Y7gE=-Y@LsLHnvuWCD&5@;h*H~KvzRg99Hy9$3^;P%V&Af zj&6PLf|?W$N!s?;4CQY@=7hS6yYrg4A7{Z#s#Eh(4_XsLLYK)pRLvcumDevmO3>3csG|qwjVsD|fb_W; z4cf1_|2R_pxdc~SKYT@!s-&JoMPZ&z0c}){(BtYDW!RVux@ zA2|zFiu}=8_hmRfGlMrc@}lIXP2dh56%VV9%O|h18Y|dS*{zQH4R5|tvVl@f1NhKU zK8v&1loz}UX5S0^)MrW{?T;@MGUB*Jx=_QAFYfYZrNMu@PMdaer%Q8*6I`}bQWpuL z6L8Xbte#>LJyBg(Z;D3c#GARz`c|hdl&ZYPcz&W3@W$%ufO*cr&6ku34!w0`jN3+;i<*?6&O@QZh9pj(K&^Y(B{@aGI}9$% zRHcyEZ6jeFoJhYz&I53;aXrG2*F=PVysR0SVMplzP8AXU@DPY(C4MFJ-pSvF8^ECk zu{2e|Khxzqe9@u=8Of&FpNi3FqKdF_N!k4DfDMOP0J{%Y+I>1+b|aF9wZhoQlRXL~ zr<;GHnv=+s1>DJ@&K}&UB)Urm>`!3o>MLe&Vf* zQ8Yr7yM5YV%6mGC8z>(C?WI1!&s5{i#fo*X6F=52dfAc?G}PV)c?#l zk7wE4e(9Md20L$!Dd}vA<2i9{OnQ+gkg%csrVHf?Tjlz~V<)@YfT%^J6zL_IgL9A) z6{a(#&iO{GW%FGb!M;#puefNd#zb39LnFU(&1+GT)-SRbAc2H{Y8R zog+IXf2_)#n(fLo ziFq!DZa4@LA6&c+QlV}MxXeto=Dx+l)3j4lQg{W_EVYDCD0Gs`Qp6UP|FG=3e#umZ z+|Lo6o%&-@^QZc6og#W3{5chAvUQKwK#XwWkFIx>M%PKl4BqcIbam|mbN0F2v-SRf z{qFXJyu9$vJltH^pg4!8jFVnO?HkTzX4$@HYS6UO*@rO*a^%MiNwjy!Y7huht3xjs zuQJt;A!>+7??2wj6!jas*A!I$`vq@4to$NJ(mugLMCu7x6A#s9C^aAUqDC1ayX|Yx zUKL=_uAUw~{RVW5UFeF{j!*GsI){sI%l=K$-z>@tFgqUi53EO;Dnq9AVMSM+wq`cC zai8qofwTJKQz#}qhiD}TBKu~cw!KpQ3ae37hyE=+UiP77cc0fF?{?*a62G&o(>qZ< z%427>EY-o67@#HjHuzf-8oBJ4+&A!2s9?^^%zW9-9fv1p&dT~F^AYKicc+WTRn1YP z?4)O=_pgBg<*`v3>@CS0P+?&ZQx6@gnccKp)-e~nTB?ygd--xCrM?}-N1S4zZro$H z`W#cQzcex6N9ibpNCVl7Xrg3Z)5im*e( zv$bvHrqUPt>ka3Uh|B5#%~O}Ufayf_ehea{p&a}8!J@-Gh$U=&TOVTop7$B&U}bt; zd;PZL&Uy05!uryw1036?qt2vJ^ZneVH1`hT1RLGV#a@l;!oSXWz9A}(9;!)7nK6k3 z(VA3dda6qNcz8gC7tZje;xNfJ&qSni&S$WCzG55QF(WWK-RL}Jqf1l&T0QUFc9;z6 z-Z-UXC=3hcyDR$PEv0#;DqF(C|2`kNoH|s`ZC1&nU;Rrh{%w!NOxf7(gX`X|#SCuq zBeA6c6U}SHp0-B6XC57@o8N7;?;T1p0AoW&LB;mM;F?=TkC$2g8HmxhUE ze=}Fy_*k(`QD^r?RNM>LyyVYpm8o3c%2S_Oq#ZLgxxgre#?{6H_A9n}g9tkkhL~^- zSG0BB<*hDT8V~N`MS}W%F$gVa!9V;A&2I=fyzBWp?5ES&Y^ir7==xMk%1@i~>2sC} zBIxijEoBd!j(hF&?65<5d?iAT)&ktEIA0JN=yzVTO9%8cH{{VBdl@e6CzH9ct`dlE zh`-jcQGC+pHg*|S`t}Rai@uf5RwEHT_@ptF(x}IKLB?9@1|I;HSsNuUZGb6ys+>uQ zU-tOT%C^*o*%i0m#K!(oTl72a2C{Kt`6I!1t6k$|pkV7=3~$IE7X3FXQmpodZtdKe zo-4J8O8#83C0rhS|dgmfM6kfsL#{u>~3Q<8T z0)fCro-nA3C^@MOr}5UHlPJb#mxXV;>)=jUW@UV`1o+MRthgM1*T8)_zb@VJ zYPHGyw2))0-c;5Hslt$P-`BF#kU*B^zw_H-IljyO);ianB})teTV@{Y*ZMT?0zm_$ zbwy=7dbC^x-9fItwC|KEL#KUq7I1aghJ2U%IG@b!4++u|&Cn-#-E^@yPrT;vF_Aip zM_iHyu~T(Lf@U9{US>()~fs1YnMclsr%+UJ$miYZI)1`rz z5ly7`Gn(9z_veYniKAuYjhyp?Qnxx2k2saem`q|3;XiHu=W||Bi0lSL|5D>>k!4A$ z#qq$t-k_XiVx#!1WZOX(3bA4x7rohjh5znkWTo+Y(Alq$XaW{|2#$1~iYkW=6u|8> z9r#CIMF~d`ERu7ffL1h)y;O!Ppl{-3zF%HmMkeuRRy&PPfdsW&*SMo|p-E?k$ zNmjhBHH@EB|1A}qLuT!hsDR*j%W6?bv8EN0GeojVgBage^(uc~9@rg*=Z|KPGML%5 zI~iQyE$K$DpF6*qu($H5>%$^J#y*a7sXlfx_W!LOkl66X%}S=l)zNk)LFCY}#$cRV z!A6<|LrVb**b3$^d9Rg1M)vrx#CTSmKd}48L;rKP^UUCfYyqQegVw~3hV;7wpCiY7 z`8jJcG39?rc>=`1=feyc3}zeqmVcugceHbjE$W=hlp!M(lEzRNL4PdT1ojw(>A*b{ zc80eb{|w(<3278{+EwmG^JUG7vy&6$Q^&pnJ5B!jsIoS+nTa+@JCwe@d^vD=B%dsF zPkel*38&s0$8`1X)m=OnGAM;>$!SdV$*kunOI4L6ji(|{Sj64;aXs+iijU# zclm9A__YHwAG^TleikFt2?C8s#{D8VjSF{dQQnW^<}by`p%YlVA6byUXyc=Rh8+K3 zTiu`Hr0BVn@+_KpcLx*@P2kH#z|xKhl0F-A#^zIMGYU!g2lw;4yM1Dls&U@%ul>6z zwc2=mJ7sI)xe9}RBv{Zr0?m&hDNk7N8Bxl^8@n^kt?PJLLs4w4EhmLRJ+Y*F@Pi^` z`KeRBQNBS496Bl+dKFC(*47$p3rD8s{b@zUp1V*&t9LSgUaga>bSuJpZ^Abd8F+*3 zaIfhQnZxJs`r&Prp?PQE0lePMhw_ zYW47cL!}5OJ8BKd{j!LPSlqCkf=z4TIz(($(nUD8CS%S-DuS78GKb!SlQ zW%swbT8n(6)VF2P)HtTAGHsH(ftHsG;umiZ(zmpBqIugmGmkSOyaOH!a#Pz5*Q&4A zFBnjc6H5(8^nN89Ua-&gd&K82Dq@XuxU)w_1pzVv85Hk5Rn#(nuHWBp8^Sx0)vKtM znqKXBP4r87jGv*&3r%K_j=zH+3r`-+|JUA||3mq<@xzriNm?Gfphuki!rA@Je z%=voieA?qfDWSCP>@E1^glchlH1n9 z!s*+QY$euy^C=JqkNl^?(*Nwb+S;++X9fyG_f2d>!Cv&BOBY*5!YCMY zmafMBXWyaPstLP@i4N4>1WTj~5%YdH)yv#t>dJJyMX~6LRmE9@N1cNwOuWw!m`1&q zf)?0wIdA|y30NWq$n0dIlp4swfBgGux1yW&m#OXj{eApW-Ol1W`>s?>zA|+Q_^R-^ zH8R<=N9l#=Xq|)YOlQjK6&m|koW==A6B0$_xmJ0hhmrmTTp(N7#L$b$0Feq$IidmrucVV_gTNi-;SZPeLc zz$<}k@UG~rqDVnc>X{ww&H`nH!0Da+GfAL*KID>UP><$(<-;B7fm-?%6r_0hjL$Cb zwwUHqkg{7pUAPr5cX#3rugb%3i)*ApY{7#yR2fu=p3dP~vJ1og**H1+*z3u>R3Z(yB5T_Lsn}|bdjW%EwM5s!|M-0>0J?e zkdCo)lTj~0b=7U$Y9IVMWT|DAOEvr>s`y?_@%#eOeK7q50V!8B9YqNhh^yJ)%nDr3 z+I|pjce|aX z?&FjD?_Og0qu5o$bH-sbv*Mr|sGb#M<`sVg#G632wu7HOKYBN%BDvsTFXs(sC)@lw zcsiaj)Y0ihd8Ww5H_Gq*Wa|V$Kcns6J~hHRpOG=!y7cmzizaK^QO#_h`%yK@93LmA zN#hsn71kGPg`q+w_G1B$&ALN89Zu|Rt)`ufEv`2qfsPSvU@aYEe~zHP&HH~zB*bfC zUDkI)ABLb@RIC>qAC4hiaIu8JnkJ)1jD;1%(wOY}DPbKR{!Xth?1hA}>_k74Hsr## zoJMKseXWqFmrnTc9kKd`KOLyWC(_8CE2||dS6{Bk0B>^LgDsU#*ma8-$V6Qbs|501 z77LywX7}&Kcl#<-UhtUxH}QAjcRoE$<@_`*di2ui88KB>iERDp06mS)!Cxc0pPFqa ziMX+5cz1SpzN#|CDu2J>`dhEYHwW5 zhGsS+#A7XPiq*-gtGVfkN15WQ&|E|J$_yTl3)T2&j)lH8^a9FtN?EWIs)bn-e1s8H zJ9ZzomT>-tR<3sxt9>oX@f_0Kz2b z)umK*D$@L4H8N}Ptl_Fg_QV|xGMPN#C+;|o;>{*= z?ua2+A zS^OP-)k&W}`bb7f^JHB^$mUIP{A#B{nvDxN#TX}__ETH@o6OkK4Xw4i;djV)qo50& znl_1HWQiGQG;kN_NcK($(F(vS4w@$&)TG3jrnglN_V~gAp`B%f_OvCg$&0~2v(3M5 zd$D|YB4blCn(Hp>SeEhRrz4JK$3Iqn7kcaG7!fvMbt^UdqefB6(m=e|o%{)QHtWKA zkRW%Gp3eL$8#D|T`$DIgn(;uofLZtW(vzYlcDAEVaPqK*Gxd1ZSy5JkqBBnDO<{wO zKPVB{19lKq!Xo7SmyDCt%s-~idPPMObf{l^FQiCl-DBGJSB6A(5w>U$b9Y!?_r4wJ zli+o#XZ;|tQNlii5;`ucbuhH4Q5HE8-;P&EANB)gW*VOvd?NPyh7y9a(St6vt?RQ= zt>dP?7mK1S&CT8Y{A`6ndZmLt#z!lP?vMYiH>J9v&j|0em1Dgn!@Kib`b>|*+hj$# zyMgIX#KL42ndWa^V=ZXiiE3h_1o~w+YbwcT?8{!aGJjr@(zbyO=(BF{vzw`=w2#ac zPd_mF-EbQMmop=Mth&>)w)i7_Gf+vW+Z$J}8>GaRTj+0du|6+TLAcS|TXVDvxnZ2k zhBtZtu??05M6h_z%&jg1h8$RVU$qYd~u*qjMrIU+HW@wuQ$#&>CHwa!j#mr9Wa$*V71H_ zBGx-;o>NijfYpxPZ8<-ywgG!}-~e2hz*Cqe>M4qVn+Fhojj7d(xt5PRgmoelV(xkD zYBYH$JzQ%Cr3FuW~x8#NOE* z1oK6cD7?C8QD8g!Vf9c#0-=1B^PFpfNYj+QRIHH-I^YM|92j%QATZ`}bw3MT{OfHZ zfCtMmdXKkL(lGl@3@dprTwKOj5^1p^DTq<#Vul5hgtyD90HQ*j95x%S3@v=Wez#Bh zX}&~sPUp~e9g*A=V_$K$9c$j&Vfyw)ZZ!NocQz10$12{glK^bcOCmptyeg^MmMBvBK!48;|4=D|9Y{Vv#&^VE^k@J;;=K$?+_a&Z&B|BI_7!{ zwE6Dpsy|)KcwQ;yyhncYvB+iDirJ+Y6UL_zGVN^|p#ixf0ufM24A}6NfJ``zn-@1B ze;c-?cII!>yo;b}&S-H0xA`@w<=8Iyi+e&|OTa#;e(48;)dWJsXDXt-BkaQq|IL08 zqsNviZmMfEo#xTD+7Qei)Y z*>-MYE5rt(P(aduSlgc9?z^cvSK16oS$E!3hq-n1qTMUqz^n$E6IpG+-Xzx0sJW`NB|Eb34cKxSy(fMQO%EFZG!!UsZ{XZ@Au#TarHPh+GKS#SdW)g31D8_7p%C| zBpG~+Q#Z$gL1)Gf--wBm;?ZnR)7Wn*6gU0|v9bvri+5g1sJdk>2KwDj#)J>0TP>Ec zz3_5xu;PF&(ghJ;0$FQv??R3yO zU$2~q*Vtmn?=?{r$+WKs;E+ul&#T605wjFyy}9#-p{q z7>%$?F_qVHi}lV{Qa1<1Tf=j=W`0AxPrBTcEK_xRvY6|VeN(cSg14HV=HX!D_L2~bk|YA20nx|p~ENCU+6_9@rX9M0j7bLGbReVXU*OAjkgb&bSWJ` zt=iS4sa856bEAs~+Le>deTo7t%)Y(Pla06F!jq1fK8cAe@eWA4F1e&(*~-~we#M?i zu+Ueh(q-KqmR_`)YdM#Z&hbqT50&*}iXGDPEt$tFFdCDp0T7R(=!g_A{s550LXkPd z#!G(1H>WvoL?kK*)!)QYgFtv!zAno6bk9y3D=ppG$xR0FeGWcP}G+XS6yCT zU)RkFAbc{9G%D(T?FL^?YylnkY+Ls-BS@&SiwIC_5oj&de>Ey?iQ<40FBo_rvqC-d za|9r!J_aj>tnnJl64C_4O?XULx?sk{cBk+R)uRbjN8Mg!&8FOhzq!4VV0`M-ip@*%iQ5B|Td#C|>jmj)zlvA7B96Mh5@YSK9ynt{U`JubGrbKTn6%KfrL05jf${zHFl|Z#F*d?ye@>a*C?H|-y z4#AzoAe^}GC7FLP*J$IK!vSgvVG>Kf&0reLREz%Bj9F-vsR*p7i_X z`YtvNI4=8&hI@SVY1#&72Rv$Jlbn|dGqklSt6;f^3Dc$=(8Qn;>+a~I#1oDP5>rX- z9h36Q7J=hB1l;FJ5r#Wi_AjOQ6LtEkZcQ!3y9zX8Zz24O@lxPRy zl8i*XEA9iXbddR8nM%OV$5S-4l?gXZWF=Q&6ysZVgW%&jo$Em6Ij^w!aojAZ*u{Xv zB!z?iQ1-B1pT<+YISjw^SrSPV9t!K7eBIpQB1cnwoY@-=R^s<`T~nSKBbBXjAzmx3 zM7o1&<03l_B={4FXW3Q2Z3h`nZ#em!W@W{ydz1I)hQzIsP~Z!XCNuJ*Sf(xl=l6x1<{{&wL!Q zn)3Ue4-`_=>@_K@C~+aV?H2jA{M@DHi44heeyOyi0iTC#l|@VPX-sHaSKV%v@kr0` zdp@UuQe09r|^TAQoIWRS?xJQR(b9evjVi>BEj!s63v`c-y=wKUTr+X_WaiM}~ZM z0lLO}aL}@x^9S*^_hn3+ThBW&DMK;j`U=fUF zj9QBCIg|H?5S8fpR2STVOP^Ya@UdElO7cXcrPNEEwZd@&y=T+Kdxoth=5vWZX90e^ znMi&tMmkV^Kgdg9dVGmgr6E%+P}r~y(B#(u>f9RerTfhTT>DL*9efen_J=~xaeaUO zz+T8^?Fl2h+fnV1rKpe>jh(gd!Ql{iQFb_``Vm}d&u!&%_%vvi+a3&qiI;Y;zzQo1 zh2ds2`Eim&*{8b9q=G8VykB!Ot{IoL-tMLTt`Xk4Lu^h|m}re`R~s^q3-E!r%m}xp zS#i8{GuJgk*l){uc$)Q|M*-y)=kvBnT>k#AOaeS?!VS$!G}IvG8wNJlVr6U~mK{%N zL9Mzan0w9y>YTch96>BwK;E!pUHs_kYCDr^$C$5}t%G{q!pIV{$(gQsG50FvCXXZ$ zXwMZD$EQ#HIc>5&QfJ#DJ3>;5aNE1XFJgEvyi=%G%Tdls6Suy~>7e+&C$MNL#VSEv zULw%w7)dR6@R_zJ7$ukI>e8>tsc$+|S#w_ul4?|Y1v zp64t5)zeph_SIOhrN)7XUEV?h57rv_pP>#89o5By-p7+wK7J~PQ48+Fr4Jp$dd_^6 ze0$s$cpX3;+t?$o4c1a`%05_~26*U6lQe)k+21V_?E8a0J{xXPUZWZCVFjN(NKjjn zXk+RuN(8u;z#o{DP1#@K*ElmlaBEmTAhfZN;=tqFQ^PL1@*_Q4aZd@5o%2e2U>c&+D80 zsKJq8zMdo(EX6PY&X#cfHgee25r}bcC<74-U*6|xQX$iGmid`mBH5ZNGS5U$A$j-6X^N9`9`O43nrhIzIU*7}0H@!~G8xgyS1n6GIDJV_3-=zVfw#G5^$ zi4|{>0D@GtJI#@(bZSkzg2U{ZO&iG;+c88XjV1nk?jb(-pw-}cZiP^!(?vX5&=euw z(ksfE)E=P_E8Z}nI{uY{5${v@5N}^lJMu#+Bjq7}e@-&RF_r ziA&EuIC+hQm=N_rnW3Z8=)>9M$km{2y@w~3@>O<9Dh^K10DwqNuw&3!k2TpRPr|ML zMhK+-Sg#R*s;I_MXwsgP#SjZI?(Z-&+o}^=dpz8UFWG3Zl&-RLCl}(rVAGOz{i5si z0rSR$|I*M)8WG~mJEHdHiWOwQNr|i=-u@zCwR4%n)HIev+{DmK%1On3il$!ZrCpPT zKxWG$Ca!Z`h;T(Pc+Y;6R8(SDAjdidoS~YyG}Lv{FWIA9CeZ#nincCBwEQXyM!jc7 zPct4ORsmLBR$jrmVRk3~90LswGh1SI!00a~d6!T#ryoS^z5R4vJb(ApUO z<^1BoQsTxv7hr`h;@Ljw8LCZ9{tj}lS94x0d=*`U_Yi}B(_X(@)JQVKqG?g>TezAiRofsi&+%VW%{>P-*4Nv%d!2vsUjZ^Hvtzf}3#&|2} z!+i8}2AA+Tm)l4o^xM+m0ceDt;qlt$#oABwMCvb**v-n$hMfne4tQwHOd8_{tLwx0 z0suxSR5@4;%J2Dx@~y8x#D=mz26b&`RVX1Ug$>lEJQ%yJMhO>Lw_?EVVh3b#YEjFe zW{5D6*aTt4N1TVhIcJ_=TU_i+o+K=(rlJ^8yXwV5_w-0>baMh_l7EH;8$9hcWJHs~%M`@FGGZNK&#L#F=N zDmP1?lX)drdhq4c|iAUA0G!# zvmf;@)N-bKqs@=`BEcC6ToZmKw>98)?4uePl_Jwqn^s8qBe@swEZ+Q!nhXaY>hIVM zwZ=oh$vW)7>b%xkVmO#yjv-!q?Vi_jf2yAfRA^N}-zi<`8rXxY)R(dB&@DZ-vV;>C zYo%a)UV}A-v;KgLxMzH6KTC<7cO&s2e{paAZkFm;A+0j7gHN-J{Di{Z;{p|%4|=U0 zq^H+&w27N6ve?+37Z8e;Ha&}q2Mh799tqbM`E*J~zC)U)<`JlD-DGCw8o!}rC)Rwi zA7B@Ms20&U9y^zPgIC{WB{Z)d18x|4vw4^QhB7lw?!#sIx!5Yl#=g>&jljSA+3PzC zJD*}GmKby}#7^iq*wn+Vd>^&rw5eybJb=pD_b7eI)jOZF=tGa9A~W6QzD3H>Hlp3q z$-RM?Ottgbm!guUTdS-bq$?rs! zsHvFx2h9iiNbXt>u3ogQALR_FpAU?!U$?rkuAh=LF&6cYQj~M_ z<8c97otu4yA$(XeXKU>^d^J(7AuKS-bxuqjHycR=iF5Z@?k^qi!E&|YR{$pxQ0Oz= z|MhgviXrSC*B_#Pkb#_a^SBC5%!K}32Dh@!7f|_hM`?47p9Qy?1~({ zZ_X6>s!S{5DInNtylw1P@898r;Fh;EpFb|3u6dzPhw)LJ7cKXhe5lR^T4sL9Cq?d_ z{(9JDU{e?j4sPt=^0}#iE`|mFvElT~pM=+c(wgkp2uyz`0+71WT)}7Woxv<<%27oD zWy^%jN1sE5Hjqhk^Vnmq7nR-24A0~Re|#yqujV$z{-~1dFT(za1<6?HcP&}umH@d&#hOYYn_d4b)}iF@WAHt-wLXxQJG#fhcjfn2Q(*+a zp&s@E93Ji;57ne#C!`$!Y09CL23TbVzc32W(McLWNz=9jjq1?Yfi1zz(KVxi14_hx zW@aYC(;GlTYaX_!U8_YMK`uawaHz%Qhnjv9DiIIc290y?z3v(-oQ4~Qq_>B!#Rb%@ z&CLASh;~u5|935)wHf#ZH$IwTlS);{6`N!`9Ff-g%p+f-yk4YeQz>PLJ+{DPaXZV5 zJ85(Swj{Ae7e5%(`!dQo!7^U9xpVkL;G_X0``IyYKBwxoZlxX~yZYmfLTiYi+UZ7f+3-&j@^BDZ9Qf1x#*;VLwfO%Wyi7 z0dcYN@hRRvzsB3cKzqya*Jg?KiXe=F^37MIpSRY6kSK8N^iqjl^xbm>bYsh^a!w)? ze}&Nld`VCin8}3EQ&rOT+whQIH6GsaXr~(my&qJd_a9TU86Qh$Rl?c62JJ86Ul4@F zQ1Lf43{njTh3#MKQOW@aPl-OJ^1Jlihvwn=ee!_-UsNS8bn{x-5YBo6^KM$z9XS;> zf1gckP^YyY_h9%7%yJ!^bJ4!YgKgz@wh*-x3#h47cmSBzK52Oc`gAu#ybi0gHv4nD z=^uUGySQV$7JtxY)8QKaE0E6y15|=ldr!N}^8K~jX?Df!?BVn(V93I13K=&~6Gl^J zzbpc%nXSm;b%e(fbAr}z4#Lcj4sJ`|J^oQA?>+lN^ySz>f$&5%CmEC}%&;|~GF}Y= z-zlGP6P=a0)!{OVx&?WT?AIs)U>IN$#JjAT;Yz*Y?jwDtE+t=I|6wtd8frA`)FvY< zQzGp_YftsVKKN)>Q#h!%VtG4_+zBCKMi#12Dq5EvaEVOgOvm(GRT zs%SVFO+0PZyq89y?>#q~F}cSl=ne6c8dR)?Sm>ZT-}f9XrxZqu|85<_Vss`ezy5d1 zEmmr90n_zwUz3XYe4XC7tUSj4en*Ip=E9FA1`#X+S6gryqiQx>{)rqtquNY`^K2I7 zUj+qz{WOEWzxiI1VeM(i%d!+zB`L|3HfDxqA#Cs^gEad0R>5sX0i2ZVw{uf$O;M$6 z@xuF2Yz&-c1l(wKaeBxD8KOY3$c2V&q&=lwDsCm3sfX)=%pp#t$cc`zcp6zAf~L zsWvxN^j#_TiN%W*!v;uQ7)8i)F)7*8e+~KeXw9782qW|-P8Y>Q{ZPcGN!iXj{7lzGyg&6-rt_>}a4Oth;l=CAa^q*e<3TSLAs z9u>1!B`pSNHQT`&#B(n7rk>E;s9xmGN^Z5cNxXUUR!UNDF_HcR5-ot;u^`#P9yOXu z<~gz(%pXAOz6K4^hnti3=M}mTc0D{)8Natz2#WXS?-CZ*4Qo+>_TkmF=-ZC-A`hoe z+-esJ>ca`r_OfTOc&XZ4Vt1B&_GIkn8K%N*++Yt*Z?yc{f}UT3$$rYa|Kzj&ma*BF zeM7V&ntlbcH13#s3h0B=_SR))XSSUg0>F=5W-KO&C+8g98w?gSVk>Z5M1ZH)YL{ILh#c9|Ba;bfi8meY4BJc9`g#CxdYRH!VSoUO>DtYX(jXO#;@|WZz*^>V{pdJBI5}@uO}NeDoHnR0 zHSnwf&1kJ1r&hweD`eBu5FBpj)^IB>Szdp9LC|Q1!;axPvt47u+wK>%t4B+)aaQuw z4Aia5VXvjbFCr?HWGl_ad5HG1$=IDyQ+OwA0>=qCLOr!VLA_cbnljzW*S~FyOE7MO z4aA7Vp`bauq~o&t1iXC->-mXevU8TE0-p2*ndqU{PL&WbL*+eo(|zapK5 z>Ug_7Oq(N61z?hBqn>|o^{@OK#q(ol6LB-M8@C0e#`C?}Je$H6&GF&lcNVA5Zg2}e z0bBlO3}kPSvUtii6Q z8DT+ZQd*KDI5q034jt?(0~!pKaS=8@>zNmHdAcI6UeBvNOo)SHIMZOz>w98IAES{} zEc9UbmZ8Oxs1m7MT548FMzC~{)2qvSqT=HfMz2H=IKy;juG|)Lj*LuY(dQQ9naOdO zRUnC3f=%ZG*!~Y-^7Sw!?Nvx|KLoDLTqx1uG-B0Iq{Y@2h&#zS@jT5gKZVD*dqhk21~^?w`iD?Bl^}t>y-CEPKy}^tQZCyxF06Oe2(_(JX^zcS!%qc)H4S6^6jC0_^0o! z$Fz)7c~Y`MQSfHbbe&3L)J?6|0_BTfuw$_#hpC;Gg~L+|t@KZ}!Y%_RP+<3PPMwUt zi|*k-vfNB&N|N*UBEvcl5)}WS|amx-6x4_#9rt3g%GO{d~$<;gyDcl)H6yi8Yxf08!O z8_2hkhFZIyF3YrW@jYq5OGO<}+ZC-#1OAb*oOre-whHuRt*{Rox&g=7!6^nHaH><6 z2lp9YaQ$ylkusFR=+zEfvZk*w|5b36p~V2^gHd&_bp905wIKEl ziTjt?;9-r|J;zCSq;!qF&T_j<<8f5=wb8xV@(kos2>bQhgq$g44<&G5k4M)G;E*>> z!!7CLM`L_mZ&=Jymh;>nF^khr!p9wAkyuyp@ZBL~oouagSkRri`6IQRn^37W%e$sUvl` zkk1iuW9{-yy@=&NZBxk>n>S5dyUWV@QYFf@ossdcx z($6&p{joh-=hnx;_W9((FEMv7GrgHFhV*U8mc|2pV~a%(PfI^Ft#aM6#Yw zFm9N9K5U;<;hXi0ii2((?iA4vzn#b@3+*KmzB1+$!DN(i?p3O52Z$Szn zgIE_IVhpRC?juLe{B>QX0oUcn{VUkFkiZR5*a_e@GX$=FlsD$$k&1yNbYKUf(8Vuh zkB8NxeYaSsyrQHiMDuQCDgc(TwbCeP^Xc=TmF!~qQ0p0OK=fp}o{=uxz z?Xx5bDVSzgKP`8;hd7`w&RUOb^;cS6tltcd0*?1kaiW*e$#_Tv~t)e|->YLwNb%K7g+y z9x(?dTANcHIz~K)?9X*&L~T>`>n^}(yZS6RAZP3u;`v729lHfin``!2(RI7>lJ^88 zSL^m3wH_O=F@dmpu!VVR7fXNM6Fk0G{YkB(GWdOr{EAWZD`u4aRYvOL!>DoL&&3iNCEC0PkO`Qjxtq*XOZ zU>ipl7rLN!no$vlKzRk`lof4cMAWo3bzM_V^u@er2O_cY(?eMu!r~HjcLG#iOXra) z69)yH#XNnC-Xech0I9)$j{-lG`ebtjh2Iw^%@?FVZ7Bx#ihQ~>*$ETsCOf{Mii$rT za@`SrPN5V!R`KYP=+N#sVt$`MZI#}J1x?#k_l6L z6s^PGrf^~X6mXI&uOoa6zAMxK$;JwqF{Va@(N3)D;oau&H>W@DREHq6E8`FGgPkor z#l5xigmfDS%k4zY|x1Z8mVtB)EbrS}IcRRl^uOKP^Gz+SRHROiH}E+pc7?_4tt zQI7u0HvI}?#b2s@vS#QBg8Ldq86}(ROW8&;V1vVLKVqiZyTA-yDh{^@VoXRCH#p8+ zVzKMeAR9qNoJ{la@}Kk&Zu2d<-6Gi=GXq-rZZsN= zH}WsTio56U35O*61l_*HBU$}9svTRxtgU^|>FG<=yIO1SRb?Qr^dl*lg?_dgL{>YT05bif*$(Wr)OdLIY7qoWy5J?-IiyB8(7v-k|KK@9| z|0t|uOB=MT&#Y)h3A_Kk_=#R*#GRovS!$AwYesDcH>1Y(4JSy?*wa&G;}t8^Y)5`S z6KmouOpIe8;W|b%RV`e`+Ax*CH3%>hm!Ba(3@55@*u&gb(3ptUUttz$EAT;V+(H+; zS93Vmg*&nq18eeqp(Zt)7AX#$Zp?zuVNOG!{7}E10j=>4DBqK?8T^aXvXj{2r=Jf7 zdv-+`)bl4|3oA#o-c}7GxdBiB%=r%Dlz_)6r115NmV%(Nn|YOhs*F2FZi?@WVI&^^=*2xJGTh^sOsKD*&kZpJ3%Y$nW5aAXFnXdGg5&-oJU_JrYt5SfZ-@)jly$fjp zZ6?-~Y|+9mCkj=PdzDnxUHI;#+OMtt_&8%#F-FUlt(jtQnOj5j%no|lb5Z z<0bLNa{Rt@RC{XJa|h=Cnrp3_9}mXdv%-suX}*5;EohYPTQZ7QjJBELT>ECENqGmJ!u*Wx> zU8)Tw?a)8+n6F;S9{Y4LsmNC9_j(G*!p4-pTKvDL=+Hw#R4SIsH`xH8gu}oD>kWXk z--uaH0Fum4EFqE>rz#(>_4y>{45C>o*AfwX_-b^TVJW*&6ZKjBYhH>9ZlAET{xn~UI~Lc4%Rtaq{FgJfKt zYhORbL&BZ*n(XR}Z0B6m);MnMv;G^6@!R-^d0>^{irdL1GVkuLJZ?FreKv{M#)fCh zGilY^37l$_d2g&IWQ^(ljOFv6ytPvEcA~{tRZr_;xFf%;-da1|#Qoi`)L?X~DE6tB z!t_|e`}BU4-dXcZuP(M`^l_x_gdrII8}K~OI(}K^0s|r)l1Un9Xa2GgnHuC_8*o;_ zUr?-!cNI9e%w@+Q8iE+|z*3-RFQV8sb1kg^M#q13IeTyZZ{j3r+{5cN6(;|EPw00% z^Bih*HEYw|X-k*3v6=Vb`9|8#5G`~>ikgYU>Ven$F#^!YVHNbcn8^XIVwjx9@}X-? zLr~))tHnpXB{8(@4}5GvA_U|?8h6s>@Atu|Fs%j4+QyUD3(WqU?|DS6ti$k>q~7`h zgaB9PzYpwf=jloe1Ul}74X)ql2(0l=+?po3jK|5_jJqM~gBHRmoF%o-H}~T(mW1uc z^6O&ep2mx1hSWpVQ#N4#@0bBU(1cAJj-||E2#9C%HdBIgE+FQCROuWeSNg#H%hifh z@==EDr{H(AxIJhJLZ4R68mQB$Wc-NSo_Zq)CLDdp0D18#d6uuwH3w2BHuF1kMAb)1 zMr4o+J98s`2N%kNUeZ7n`-JE{P0~Wgz1rPj)?53ke=Gl;00ItQ&==ZUK(61>uig)T z>{lx(YRWcVoxB+}X9)IWgd59{EKDbJt`NkmC6LakVr8hulgs6;feLaD4CDxD7Zb#p zicuh!oEOjrK>pd@S5)JGdj@|kWmgWA)mbu!<5|x47;5dxAUIV|162kO%MF^}fC`

g03@P*_{%Rr*y14+H`9T0G z@yOWabG@V1jl(rE%^YYY))*p*=ZH~?Zu?yn2^u5=0@oy;&p&aoO+2HnSDOF0Ivv zY3p@BwM$yqr&s4=9UE@}nRIVV%!{M7D?o}U zbL6@q&s+(YWOfb~WEyUFBMCDy@|555Ey=792$QOwwti6kpRylAsLs@S*geqDk3W~b zFSjFZFgdc4mJ{A29=Y7TT~F_eS4&YJEgFd~YBS}SsQbA?P}k2_10?!+QV&jF147P# zbuX<&fLvSAQSB#;i4UuPi9YxwEyMXNs;zHM;ydkgGiv0CmK2z$Z4#NA`KXXW%kzR> z12*Pw^!3hL^^(H~Sa+^1EbD3(V0uRHh#s?g5DQ8YpaosuJd#%}i-_8*6K|rxFjB^>3TTxYqwD z2>$uap<>~zcLxZ~*0z25Hy8r36NzTbPzmq*LrDLK0Xlx_|*#q2F6 zdyb(ChI6!Xnv#1H2#BOE3S{7*Yw zrvytrOcPA9u6LTap-$E#rF**R0_&sh_kGp%=lC}qaQ(IaiQ;QpdT*zKJbL8+|M&mB e75Hqtd2n=@_XDr>Q|zO|>1(L#s-aY^-u_=IgJW+1 literal 0 HcmV?d00001 diff --git a/doc/images/grpc-ps-pss-fd.png b/doc/images/grpc-ps-pss-fd.png new file mode 100644 index 0000000000000000000000000000000000000000..790af7f1bc12d94327bd3297cee296969a6cc1cb GIT binary patch literal 24969 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 literal 0 HcmV?d00001 From 6f278ca7614e70a425eaded3a9d7da428bef33c5 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 26 Sep 2018 10:53:43 -0700 Subject: [PATCH 2/4] Address review comments --- doc/grpc-polling-engines.md | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/doc/grpc-polling-engines.md b/doc/grpc-polling-engines.md index 65aa5225432..bebcb4ccc86 100644 --- a/doc/grpc-polling-engines.md +++ b/doc/grpc-polling-engines.md @@ -10,9 +10,9 @@ Polling engine component was created for the following reasons: - gRPC code deals with a bunch of file descriptors on which events like descriptor being readable/writable/error have to be monitored - gRPC code knows the actions to perform when such events happen - For example: - - `grpc_endpoint` code calls recvmsg call when the fd is readable and sendmsg call when the fd is writable - - ` tcp_client` connect code issues async connect and finishes creating the client once the fd is writable (i.e when the connect actually finished) -- gRPC needed some component that can "efficiently" to the above operations __using the threads provided by the applications (i.e not create any new threads)__. Also by "efficiently" we mean optimized for latency and throughput + - `grpc_endpoint` code calls `recvmsg` call when the fd is readable and `sendmsg` call when the fd is writable + - ` tcp_client` connect code issues async `connect` and finishes creating the client once the fd is writable (i.e when the `connect` actually finished) +- gRPC needed some component that can "efficiently" do the above operations __using the threads provided by the applications (i.e., not create any new threads)__. Also by "efficiently" we mean optimized for latency and throughput ## Polling Engine Implementations in gRPC @@ -20,15 +20,15 @@ There are multiple polling engine implementations depending on the OS and the OS - Linux: - - **epollex** (default but requires kernel version >= 4.5), - - epoll1 (If epollex is not available and glibc version >= 2.9) - - epollsig (if epollex, epoll1 are unavailable AND Kernel has epoll support) - - poll (if kernel NOT have epoll support) -- Mac: **poll** (default), poll-cv + - **`epollex`** (default but requires kernel version >= 4.5), + - `epoll1` (If `epollex` is not available and glibc version >= 2.9) + - `poll` (If kernel does not have epoll support) + - `poll-cv` (If explicitly configured) +- Mac: **`poll`** (default), `poll-cv` (If explicitly configured) - Windows: (no name) - One-off polling engines: - - AppEngine platform: poll-cv (default) - - NodeJS : libuv polling engine implementation (requires different compile # defs) + - AppEngine platform: **`poll-cv`** (default) + - NodeJS : `libuv` polling engine implementation (requires different compile `#define`s) ## Polling Engine Interface @@ -36,8 +36,8 @@ There are multiple polling engine implementations depending on the OS and the OS The following are the **Opaque** structures exposed by Polling Engine interface (NOTE: Different polling engine implementations have different definitions of these structures) - **grpc_fd:** Structure representing a file descriptor -- **grpc_pollset:** A set of one or more grpc_fds that are ‘polled’ for readable/writable/error events. One grpc_fd can be in multiple grpc_pollsets -- **grpc_pollset_worker:** Structure representing a ‘polling thread’ - more specifically, the thread that calls grpc_pollset_work() API +- **grpc_pollset:** A set of one or more grpc_fds that are ‘polled’ for readable/writable/error events. One grpc_fd can be in multiple `grpc_pollset`s +- **grpc_pollset_worker:** Structure representing a ‘polling thread’ - more specifically, the thread that calls `grpc_pollset_work()` API - **grpc_pollset_set:** A group of `grpc_fds`, `grpc_pollsets` and `grpc_pollset_sets` (yes, a `grpc_pollset_set` can contain other `grpc_pollset_sets`) ### Polling engine API @@ -45,7 +45,7 @@ The following are the **Opaque** structures exposed by Polling Engine interface #### grpc_fd - **grpc\_fd\_notify\_on\_[read|write|error]** - Signature: `grpc_fd_notify_on_(grpc_fd* fd, grpc_closure* closure)` - - Register a closure to be called when the fd becomes readable/writable or has an error (In grpc parlance, we refer to this act as “arming the fd”) + - Register a [closure](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/closure.h#L67) to be called when the fd becomes readable/writable or has an error (In grpc parlance, we refer to this act as “arming the fd”) - The closure is called exactly once per event. I.e once the fd becomes readable (or writable or error), the closure is fired and the fd is ‘unarmed’. To be notified again, the fd has to be armed again. - **grpc_fd_shutdown** @@ -56,7 +56,7 @@ The following are the **Opaque** structures exposed by Polling Engine interface - Signature: `grpc_fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd, char* reason)` - Release the `grpc_fd` structure and call `on_done` closure when the operation is complete - If `release_fd` is set to `nullptr`, then `close()` the underlying fd as well. If not, put the underlying fd in `release_fd` (and do not call `close()`) - - release_fd set to non-null in cases where the underlying fd is NOT owned by grpc core (like for example the fds used by C-Ares DNS resolver ) + - `release_fd` set to non-null in cases where the underlying fd is NOT owned by grpc core (like for example the fds used by C-Ares DNS resolver ) #### grpc_pollset @@ -68,10 +68,10 @@ The following are the **Opaque** structures exposed by Polling Engine interface - ** grpc_pollset_work ** - Signature: `grpc_pollset_work(grpc_pollset* ps, grpc_pollset_worker** worker, grpc_millis deadline)` > **NOTE**: `grpc_pollset_work()` requires the pollset mutex to be locked before calling it. Shortly after calling `grpc_pollset_work()`, the function populates the `*worker` pointer (among other things) and releases the mutex. Once `grpc_pollset_work()` returns, the `*worker` pointer is **invalid** and should not be used anymore. See the code in `completion_queue.cc` to see how this is used. - - Poll the fds in the pollset for events AND return when ONE of the following is true: + - Poll the fds in the pollset for events AND return when ANY of the following is true: - Deadline expired - Some fds in the pollset were found to be readable/writable/error and those associated closures were ‘scheduled’ (but not necessarily executed) - - worker is “kicked” (see grpc_pollset_kick for more details) + - worker is “kicked” (see `grpc_pollset_kick` for more details) - **grpc_pollset_kick** - Signature: `grpc_pollset_kick(grpc_pollset* ps, grpc_pollset_worker* worker)` @@ -82,7 +82,7 @@ The following are the **Opaque** structures exposed by Polling Engine interface - **grpc\_pollset\_set\_[add|del]\_fd** - Signature: `grpc_pollset_set_[add|del]_fd(grpc_pollset_set* pss, grpc_fd *fd)` -Add/Remove fd to the pollset_set +Add/Remove fd to the `grpc_pollset_set` - **grpc\_pollset\_set_[add|del]\_pollset** - Signature: `grpc_pollset_set_[add|del]_pollset(grpc_pollset_set* pss, grpc_pollset* ps)` @@ -114,12 +114,12 @@ __grpc_pollset_set__ Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` -- The logic to choose a designated poller is quite complicated. Pollsets are internally sharded into what are called `pollset_neighborhood` (a structure internal to `epoll1` polling engine implementation). `grpc_pollset_workers` that call `grpc_pollset_work` on a given pollset are all queued in a linked-list against the `grpc_pollset`. +- The logic to choose a designated poller is quite complicated. Pollsets are internally sharded into what are called `pollset_neighborhood` (a structure internal to `epoll1` polling engine implementation). `grpc_pollset_workers` that call `grpc_pollset_work` on a given pollset are all queued in a linked-list against the `grpc_pollset`. The head of the linked list is called "root worker" -- There are as many neighborhoods as the number of cores. A pollset is put in a neighborhood based on the CPU core, the root worker thread (i.e the head of the linked-list of workers queued against the pollset). The whole idea here is that when choosing the next designated poller, we make a best-effort attempt to pick a worker that is NOT running on the same core. This way, we reduce the probability of the current thread being pre-empted by the CPU scheduler. - -- See `begin_worker()` function in `src/core/lib/iomgr/ev_epoll1_posix.cc` to see how a designated poller is chosen. Similarly `end_worker()` function is called by the worker that was just out of epoll_wait() and will have to choose a new designated poller) +- There are as many neighborhoods as the number of cores. A pollset is put in a neighborhood based on the CPU core of the root worker thread. When picking the next designated poller, we always try to find another worker on the current pollset. If there are no more workers in the current pollset, a `pollset_neighborhood` listed is scanned to pick the next pollset and worker that could be the new designated poller. + - NOTE: There is room to tune this implementation. All we really need is good way to maintain a list of `grpc_pollset_workers` with a way to group them per-pollset (needed to implement `grpc_pollset_kick` semantics) and a way randomly select a new designated poller +- See [`begin_worker()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/ev_epoll1_linux.cc#L729) function to see how a designated poller is chosen. Similarly [`end_worker()`](https://github.com/grpc/grpc/blob/v1.15.1/src/core/lib/iomgr/ev_epoll1_linux.cc#L916) function is called by the worker that was just out of `epoll_wait()` and will have to choose a new designated poller) ### epollex @@ -130,17 +130,17 @@ Code at `src/core/lib/iomgr/ev_epollex_posix.cc` - FDs are added to multiple epollsets with EPOLLEXCLUSIVE flag. This prevents multiple worker threads from waking up from polling whenever the fd is readable/writable -- A few conclusions: +- A few observations: - - If multiple pollsets are pointing to the same Pollable, then the pollable MUST be either empty or of type PO_FD (i.e single-fd) - - A multi-pollable has one-and-only-one incoming link from a Pollset - - The same FD can be in multiple pollables (even if one of the pollables is of type PO_FD) - - There cannot be two Pollables of type PO_FD for the same fd + - If multiple pollsets are pointing to the same `Pollable`, then the `pollable` MUST be either empty or of type `PO_FD` (i.e single-fd) + - A multi-pollable has one-and-only-one incoming link from a pollset + - The same FD can be in multiple `Pollable`s (even if one of the `Pollable`s is of type PO_FD) + - There cannot be two `Pollable`s of type PO_FD for the same fd -- Why do we need Pollalbe of type PO_FD and Empty pollable ? +- Why do we need `Pollable` of type PO_FD and PO_EMTPY ? - The main reason is the Sync client API - - We create one completion queue per call (therefore one pollset per call). If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a pollable (and hence an epollset). Thats a lot of epoll fd create/delete calls - - With these new types of pollables, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the sub-channel fd is added to the pollset, the pollset will point to the Pollable of type PO_FD containing just that fd (i.e + - We create one new completion queue per call. If we didn’t have PO_EMPTY and PO_FD type pollables, then every call on a given channel will effectively have to create a `Pollable` and hence an epollset. This is because every completion queue automatically creates a pollset and the channel fd will have to be put in that pollset. This clearly requires an epollset to put that fd. Creating an epollset per call (even if we delete the epollset once the call is completed) would mean a lot of sys calls to create/delete epoll fds. This is clearly not a good idea. + - With these new types of `Pollable`s, all pollsets (corresponding to the new per-call completion queue) will initially point to PO_EMPTY global epollset. Then once the channel fd is added to the pollset, the pollset will point to the `Pollable` of type PO_FD containing just that fd (i.e it will reuse the existing `Pollable`). This way, the epoll fd creation/deletion churn is avoided. ### Other polling engine implementations (poll and windows polling engine) From 3c2c28e3fc3010e9fd5d6ac2ea257358463abe89 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Wed, 26 Sep 2018 10:57:20 -0700 Subject: [PATCH 3/4] Moved to under core --- doc/{ => core}/grpc-polling-engines.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename doc/{ => core}/grpc-polling-engines.md (98%) diff --git a/doc/grpc-polling-engines.md b/doc/core/grpc-polling-engines.md similarity index 98% rename from doc/grpc-polling-engines.md rename to doc/core/grpc-polling-engines.md index bebcb4ccc86..f273913b1e4 100644 --- a/doc/grpc-polling-engines.md +++ b/doc/core/grpc-polling-engines.md @@ -99,18 +99,18 @@ Add/Remove fd to the `grpc_pollset_set` __Relation between grpc_pollset_worker, grpc_pollset and grpc_fd:__ -![image](images/grpc-ps-pss-fd.png) +![image](../images/grpc-ps-pss-fd.png) __grpc_pollset_set__ -![image](images/grpc-pss.png) +![image](../images/grpc-pss.png) ## Polling Engine Implementations ### epoll1 -![image](images/grpc-epoll1.png) +![image](../images/grpc-epoll1.png) Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` @@ -124,7 +124,7 @@ Code at `src/core/lib/iomgr/ev_epoll1_posix.cc` ### epollex -![image](images/grpc-epollex.png) +![image](../images/grpc-epollex.png) Code at `src/core/lib/iomgr/ev_epollex_posix.cc` From 82b2e2977d5cd144c6e2350d55b6f928fd8f6ce7 Mon Sep 17 00:00:00 2001 From: Sree Kuchibhotla Date: Thu, 27 Sep 2018 11:17:27 -0700 Subject: [PATCH 4/4] generate_projects.sh --- tools/doxygen/Doxyfile.core | 1 + tools/doxygen/Doxyfile.core.internal | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index aa75bc68283..9f7c2c9140a 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -772,6 +772,7 @@ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ doc/core/grpc-error.md \ +doc/core/grpc-polling-engines.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 91860567339..2ce6412d2cf 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -772,6 +772,7 @@ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ doc/core/grpc-error.md \ +doc/core/grpc-polling-engines.md \ doc/core/moving-to-c++.md \ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \