From 6924a3d5f28cc76056f77b3f1aff05f80698648d Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Sun, 26 Sep 2021 21:23:41 -0400 Subject: [PATCH] Fix calculation of Drand round from Filecoin epochs --- api/api_full.go | 13 ++--- api/mocks/mock_full.go | 30 +++++------ api/proxy_gen.go | 26 +++++----- api/v0api/v1_wrapper.go | 4 ++ build/openrpc/full.json.gz | Bin 27057 -> 27057 bytes chain/beacon/beacon.go | 14 +++--- chain/beacon/drand/drand.go | 25 ++++++++- chain/beacon/drand/drand_test.go | 11 ++++ chain/beacon/mock.go | 4 +- chain/consensus/filcns/filecoin.go | 5 +- chain/rand/rand.go | 4 +- chain/stmgr/actors.go | 2 +- documentation/en/api-v1-unstable-methods.md | 53 +++++++++----------- miner/miner.go | 2 +- node/impl/full.go | 1 - node/impl/full/beacon.go | 36 ------------- node/impl/full/state.go | 20 ++++++++ 17 files changed, 135 insertions(+), 115 deletions(-) delete mode 100644 node/impl/full/beacon.go diff --git a/api/api_full.go b/api/api_full.go index 33b8113c2d4..284d12f5bbe 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -171,14 +171,6 @@ type FullNode interface { // ChainBlockstoreInfo returns some basic information about the blockstore ChainBlockstoreInfo(context.Context) (map[string]interface{}, error) //perm:read - // MethodGroup: Beacon - // The Beacon method group contains methods for interacting with the random beacon (DRAND) - - // BeaconGetEntry returns the beacon entry for the given filecoin epoch. If - // the entry has not yet been produced, the call will block until the entry - // becomes available - BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) //perm:read - // GasEstimateFeeCap estimates gas fee cap GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) //perm:read @@ -591,6 +583,11 @@ type FullNode interface { // StateGetRandomnessFromBeacon is used to sample the beacon for randomness. StateGetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) //perm:read + // StateGetBeaconEntry returns the beacon entry for the given filecoin epoch. If + // the entry has not yet been produced, the call will block until the entry + // becomes available + StateGetBeaconEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) //perm:read + // MethodGroup: Msig // The Msig methods are used to interact with multisig wallets on the // filecoin network diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 1cac309bf55..10f85c97364 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -91,21 +91,6 @@ func (mr *MockFullNodeMockRecorder) AuthVerify(arg0, arg1 interface{}) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthVerify", reflect.TypeOf((*MockFullNode)(nil).AuthVerify), arg0, arg1) } -// BeaconGetEntry mocks base method. -func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BeaconGetEntry", arg0, arg1) - ret0, _ := ret[0].(*types.BeaconEntry) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// BeaconGetEntry indicates an expected call of BeaconGetEntry. -func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1) -} - // ChainBlockstoreInfo mocks base method. func (m *MockFullNode) ChainBlockstoreInfo(arg0 context.Context) (map[string]interface{}, error) { m.ctrl.T.Helper() @@ -2406,6 +2391,21 @@ func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2) } +// StateGetBeaconEntry mocks base method. +func (m *MockFullNode) StateGetBeaconEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StateGetBeaconEntry", arg0, arg1) + ret0, _ := ret[0].(*types.BeaconEntry) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StateGetBeaconEntry indicates an expected call of StateGetBeaconEntry. +func (mr *MockFullNodeMockRecorder) StateGetBeaconEntry(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetBeaconEntry", reflect.TypeOf((*MockFullNode)(nil).StateGetBeaconEntry), arg0, arg1) +} + // StateGetRandomnessFromBeacon mocks base method. func (m *MockFullNode) StateGetRandomnessFromBeacon(arg0 context.Context, arg1 crypto.DomainSeparationTag, arg2 abi.ChainEpoch, arg3 []byte, arg4 types.TipSetKey) (abi.Randomness, error) { m.ctrl.T.Helper() diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 0834977ccec..93894dc9884 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -103,8 +103,6 @@ type FullNodeStruct struct { NetStruct Internal struct { - BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` - ChainBlockstoreInfo func(p0 context.Context) (map[string]interface{}, error) `perm:"read"` ChainCheckBlockstore func(p0 context.Context) error `perm:"admin"` @@ -353,6 +351,8 @@ type FullNodeStruct struct { StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"` + StateGetBeaconEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` + StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"` @@ -1088,17 +1088,6 @@ func (s *CommonStub) Version(p0 context.Context) (APIVersion, error) { return *new(APIVersion), ErrNotSupported } -func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { - if s.Internal.BeaconGetEntry == nil { - return nil, ErrNotSupported - } - return s.Internal.BeaconGetEntry(p0, p1) -} - -func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { - return nil, ErrNotSupported -} - func (s *FullNodeStruct) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) { if s.Internal.ChainBlockstoreInfo == nil { return *new(map[string]interface{}), ErrNotSupported @@ -2463,6 +2452,17 @@ func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2 return nil, ErrNotSupported } +func (s *FullNodeStruct) StateGetBeaconEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + if s.Internal.StateGetBeaconEntry == nil { + return nil, ErrNotSupported + } + return s.Internal.StateGetBeaconEntry(p0, p1) +} + +func (s *FullNodeStub) StateGetBeaconEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + return nil, ErrNotSupported +} + func (s *FullNodeStruct) StateGetRandomnessFromBeacon(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) { if s.Internal.StateGetRandomnessFromBeacon == nil { return *new(abi.Randomness), ErrNotSupported diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go index 769a280ab01..d6de6f416d9 100644 --- a/api/v0api/v1_wrapper.go +++ b/api/v0api/v1_wrapper.go @@ -352,4 +352,8 @@ func (w *WrapperV1Full) ClientQueryAsk(ctx context.Context, p peer.ID, miner add return a.Response, nil } +func (w *WrapperV1Full) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) { + return w.StateGetBeaconEntry(ctx, epoch) +} + var _ FullNode = &WrapperV1Full{} diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 29b397ad9b0f0018884c836fe8c6dc3e0f056dd1..e4ce4f4d343b2a8e52fc4d4045d2078e872400aa 100644 GIT binary patch delta 26277 zcmYIvQ*b6-xNdCQwr$(y#I}ve7u&XNXJXs7lZkDg`S-3p_HB@r+8|Kp>~`W5WFd7o62l0;9Db=1&-x@)L$hy3V#zEmp%)q=tb`| zQzpD%ra%|=d?&J=InO)3Vz^1ge1j;)S2wP3q$p4Ziooymp?{T> z0FrHv1Q1fwxLnT=K02F4HwNIWy3s3EVxnkHbTYoUwtT2Rh`$XQ;Xohg3X}$&wt%%4SrBE~}Uli6v;^!3lxn3bhjL&=m%cTvDeKW8Grkiopv-=(6SJ-_ah%15PmG zPptE8g*}khbs}-s=r%s5W+Wf=5Vni<)vo@)7^vzqwQ}zmt6fEFB?inGVo{+=mz{JBn z*Q2u!Y{dHZ@06>c(__8=sN)#&1K6He_yS;@`Jf?31xWA|nIdJH5gHIlm_M*cvVozn zU?^tQGa9tSb4!7L3yMS&6YeE%Kydv9VkN?8I%fg{P;s$pYIdhLx*!}+lKN5l=o zVcJa{`kN?r{U#8(fqAo{HGbj)kADRUL@Zo_Yg`{OOxKj{jdTi18h(By1e_9cbr^ly zdN2nT=?M@t(6S-^6t)4v?gD29dq*Cif5}PkqVh#zb~;77x7K+;h!l~_s#i!(4xf_^ zj<2k&lnb+TiRwxHK^u`mYF?gy#(%nAW#82(I8lgJ3W9h}Yi< zEgTd{WhjHX`+KG9-|`-UG9nz5-I5iMZIqQr!zB033AY%65l|x`}bgMf{F@$lxSkhQY~m&_P3X zbk?GMPGd-fAX5M%qCQP3Bni$V=a;{U#q>LSL_j8BpImUoSPvnWA0fb4OfVu7SOkz# zPy;ac{;EtttEY*to+NsKd>4~sg)YnRT$2982Srdqx%?!_o|d4#xx|H9S^Z36fM9q= zX!3x2WI4wnmCU^eTb*`Pd#1bq{~e+c;53z6s}1Zpl+fR35ph&pl5JyA!_CR0uV)9- z1b;jMz6b(c?VdkpP}#jdk00a6ua9>}yL)@^uV0_j$etf(a9utwPEMb9_^-ErKYf3; zvs@fMkuQTD7CFO49pVuC`^U=$0lQ$sMT&ceWw6SOlFtW8`GzY3d~aW;(+MOlPQKpX ze-9ErXOue7oI5h$15}tAHN823J=r4T)8HfG5*aBwPd=#-m*N)aY-H=~J}DuAC;Kka z9D)QB`Q44o^_3Qz?l}rw9$q9HT-Eyp4UtH%cswE3p>s`+CA=Wlb%GI$0O{R)F>`pM zE?;{=Tb+cL)RaNl$!4UUTwHttG@G}FPNzj@Zfpa*1ZJn9vlzDT2hZmmpFSe34ir0r zoevjR>)HBuSq%Uma0idIy-utRm!lBPcE1Zk6m0%aVl0GW=3>*J9L&NKM#u0k0!(e4 zn=tOPPGCiL)Qw+sBf6(b66&+mxcN2;jji6(2Kg_2`j- zzPP-X)Br~u*1`wwI7*zX9Zh23GHmZ>s#Pv7MCa)t=FUN#U$J-La&r;?*m zj~u#5{Y|JQ$vrMh3k%+(t9XycTcNXST3Y<+*zpiB{VJM^WTl)Hj(}AM%R4l_xBHgv z1BEOru7KnPJHRQRyhCusn*Xr2-l+6>@+dVKQ_}fEdVhN-*~7@Qrde2##z8A_b3c6A zQ_NjLld-HQU2N><DLsu4izA7UT z-hEwSyu0bK^^sCpFy<$*sy;`0&T77@l;CcEvt~7GdQyNesRo7(JR^5=$2RF0h82)j zO!Es{cS=b@G>i>0om?NUz!WPVjQ`}3n_No#QKp1vw(3yq!jlOKsEj?Hyr!-&iX1g; z%>(BR*yd=$Otm2IVnW;Mg0n3>iW&dX4gu1_SwiEY-6Q^M25hpf)25=DdD0GUxln#T z_-R?8mrobGc{v$cA`(|XNBHVCqXd8mfEu`x>HThcfqD;Pm9mXt5U|nU!S0T&lz5hY z6u#|}8^6`A{1x1l#Gw{kt2_h#u%mVTReZD^d zZsK2zg1n2#f{R?YZk&C22529Oul?VP#PK%MvoR(G8 zOLAmt74us0amx&MM#yeDb*YPkg8X-;+xskBmD11zL!axz5CTZvN36yh#Od zbd2@}V$KZD)Xn+RX#6gR+)8Nalz`3~`2ad2kGMan^+w1SciWn@ zQ#JPbmtz(fF))+_uzTaixHVSvo)PufDd%9!as>Kd2pQtJ1YG5%Au@?z-TYs)j@7Mj1S zt$04c;Usu2qSXE>By>(b~+Ud?)C>KEP&Ag7+~aHR&`wXhb)62WrH|| zIgnGRem2|vcm0OC{9NRf*w@-Yyg2n*DJ{T;CSD>-UikYY+++1mN8{6o&V#&I<}bz< zB(rRKWFhGyR2(l$6v%!MrXlUhAaoVXOi$3y8CRkLNV5^ew$5i(y01}p&AERcj^|sp z=nl5h>4Yp$2*5SieD7fKl~LJ&x?^q#cP^xKi9p}fSBHxaRbYXZg8L}l>5}>I*SHnf zpf<4Ur^qPat8go)H=0Y`^V(@28eT_z}tzpcS%_D=9UdJ&pp0C2j!ZtrETzS;y`rxC;7kxW%| zRa$Qao+eON&uXbsA4j07h;aLuPPZCpjtXBnSG=xIi1FS4cK=uF{**6zn5S2{my(S} zYg4cBle>BoafQ81d|IfKkzQ_ly5Hn}C`Q6fxeQn$m~fzvxA@`B%4a>Hu9vSRgwDNn z=qa0W0}uz=F=QEJN!5JQ-xmc64IIp;gsAQ-M1eaLb|%kMEomNoq?3|!ID(7oKX(%o z3IqHPecd#RVQ<^dc~|?Jlrhw*)gc@d>_ItuA`1^tphInIxT8TYLn9M9kGW;U6yM$@ zG>?l07s9{2Kt)r-XX4qiPuE`BR^2EVXTm;b0>l*}s1*fJTEk8Sq~7y#2Gl>!&mIm* zt%Aoyb)40_lcd=P0T%sYMZC~t3#h{i&GvSLF@8ml51jz}pSLT)pB{;upRlkS_ZRKQ z4*r!YkvGYlu|tNnjpEo)~tKrU>~w}O7*FB%rjrMlUoq+m>A(cJ7-$4UvB+mLR?+&Wt-yjF2n23L9YoKy?{J`g6bDSMUn&# zqP8g*Z=ZD$F2@Fi85MYroP7pUpGABSc9#SY2%yK>yo2+4qE$IMSfQ+M zhikEpS5Lnq%*<_pSn?)%;Et(k)iVT{0Y})c;twR`pW~B+)!P7=;wyE-L|VE@l`T<} z{|qG+Ks_IhOJy|mr*`a9lTa<3KRf=&y|GRN3?DcF((fA9LSk-h=|!jrb5eLJc}wy! zL$+qPC{Q=Fg^JPW7_<~48QSFGJNQF!Pulfb7ftRB|MtcE2;do#+;+=t)hb?)OS}1k zfm%2TKt(mNAanxUr_&v(#eR#4P8iNz3~Qa>-4BsSUu#s}Gvv8=IqmGU3E!{&!{l+5 zQ6&dv(z!jpF1RFdq(4*|ZCJ^&coI_4XW*&LoSd9(xsyK(9GovlfFEQD?NdfZSCO*F zSyUeSHWT54kJTFk@~x89wOJh-$#~I%l9wL%M9YnHx@&-kVdDgJe)Y;0$KLadqa%ca z>3!x<_SX&|KGceqGSz=VuH1J2axoI+Y-MQ1QU{s$m~NAaUGVC=MD1+~5rd)^$K|@* zH4gxBkSS#4e5)C5Sq-Tw-)b$N9zl-DZhG4cIdY+`nn&%kV%YF>X0oa*~Os#VOKi zTAIJ6+I?9??+t%rp#P&UWE5?1G6)zvYJhd_L&9p-o#T2&=oC#i?#p8up4>XeKf>zz zD2TUcd|st6xx}ry)#Zi!*Y_oI45(BcW_+4uxTbVMbn(W-I7Gp^bR-H*st62R`Ds~B z3sx#SGOPw)uZskgZtar|pRxV}@uliF6K3yo)$yw_Vake3ho!x3Rpcs#s=tXx(*Skm z#C9DFX~yK|G0IQq@~%*Ib?3@SU8u*b-&64rcJ*`6{=)I*-+NZtJPDLKnmva_jVI{+ z!^W#{Qc9;<6gce7$~Wq#Wxh-2u32q{f{mi z^ZzNaCSi-l)L^LCoina~F?Lx?_K>8UC~!Jb$MQDLRD;CByUtVZ*6Lr8fzqg0%YM9|C-ibB+#jBht=$JuR-rt*MC($jXxW@BK&;jSL z?x;_$-h!XW^8|d+%$VJCeMS6g)$)R(bm_cNzObW{3Yu{7+a$z8r+GxSy#rGq z=U~p5$!={DZY`TwL%Q%TpXoYP_LdhlueJPqP z?h+3XZ(BdBq0ks^@t6@#3aA=d+R072>-Xe-_#^>q688tV~EsClB1Fzphuyq4U!IRguP0`>tD1dW7A^%KwoNi~>t?pfdkaP~9? z*Y>nuYEL`~X(I~1BYn}JW#yrup2ldjH5P>8Ml$;!ocRiLMy+)aDlVC=bTj3Ml60pg z;AG_u&=th%K3Lc8i{4c4#g2WmYV09q@d})ATX$eLHjXQL)W=V}1hey@A8HPzQ@8c5 zeG33DvzXqiJ96Fk8-9g(dtfz>6-Ta;>oqFAcBJ@=(Lnfo81BsYh||<}9n72Nh0KhF zAspbb&{34Am*cRrCI=qy32phd*m_1rI`npxj5?F0img;75!*Dl(N0)kW1NGR)Y6Pk zuqmIQxsje7WY%d|5>QM8KAL@T3HhNht$hG7wr9sf=4@f7#+J_Y^lp}n=se=<>y#;} zCHgbhnHeM3kk`<}(G^;q_-hYn8*{tWO4B_EV+IpexTru?CW*cxV}Xb7##7C>)opIZ zoEzs5^w#BclPg`GHKh}_H>tts0zjH4<2 zBP@?|whjGpXUr{eW2{w4jBp!&hM#1}BLjJ@I^$0~S zWH*?&=cdN-1}O8HT`mB+!+Y~ks9Qs%a158PAvx!KQo51&ijHpJVnRR7G8eC0+pC^( z?x-(>M$YI%?xRzBk+Ax&dj{q57Lg&xM)(|lVF|N|Dho5YQg4rdL6;$bXjIu=gtxPQ z*=RBIq(Q}3sOlQUw8lw&6;C^#Y10(Wf*^Lf2m}QbFk^xwV2Fx^C$y568muvuop%kEUcM==?LTnWqALoZ`^DKDxdZYx+Thg$~}+wYT4 z!@mhXnFT-JtGy6|!e)tOcU+J2k32a0_;D<*gBGwHzny&CaKHJ9H#t#n^0wceo^2KC zUZ>Z3y93(*ytZ>3#!^om^r@`x+Xa;bg1BAQ2$mOnr2NkuSEq4ym=i@khi(0MZ(0fs z|KG?6DaIg7DA>k74304Jn?sn>p6*2m&(i({k#i`MIS_I4Tzj?3A1st+5&>Jd&LL{R zC=i(l1SM%ZLfXjM;mwUdOeXRz$Vk~{YVi(OjhY`LoX}MWH>=)O@)lo;aEzOFlpX{<1Ptn#h@pbW1%8U*#eBo889fMK zL73#CYnss-*$45_jo<6}2!L2cBj~E;uFY9>h!E0-C$gk*Ln2n-!z{7IUdT%5+CCet zOSp3x?TOJHmH!Dnje`FpwKlakJPqd@!8`!v167Y514>A$$zKao4-H-5r-+Zh`%4 z&qlMV{%FRRHr%4>IfL}goO!J-?+h-wW<7X{ZwuHdOO$~%dCmBCiVX)4kkpL?7*t!8 zoU?>_L$g<2Skvxy_p9#MrhcfL`wPoq9aL!3<$Pd)^XD!*J=Zsd3-GD zBi=sKt4!7$n<`j;=Ql^#$K{uWR~C|a1nxk4Q=YEM&ec^I-F8r{&p~>fyY9Xq8UhVd zI@qA1K{vNc6-$9hyZFooA;}q~x_T zRH~o(H16(Jwmx8J<*0mDCcM@&w~G8TAq9EDMu9gcP4a0GKdDBqk0%~}YY1Fetm2## zOOO>-g_gbBc7xunp7bt0J;jPfG^W%>rf7y@N2E_Mvz)s?#o2hS9U}v1%^J+1Ne^F& z1M4V}b?cHE6&LXOs9&Vj4tA;TKX5%^S7_C@Uo9@DR$QG)BqF_QisnxW<7Iw<$!TVP zb@sI~N*F`HZXk+F6;$DFnAzg7nbr0|T;ABM7$+|jTd|n3@B?$;u?{MJpIrcx{_rRS zkDgh#_D{~k{elE#hAszWPy9k8Tb1O7-23Hnp%$nLji^rERW7|sq?&mu`Xyr7q6q^I z($a5qe+8Zy27E*n^_CbXSZ`Id$JjhC+ocJ9`1IY=L(=3NWQhBuJeBDRL)w7jlXdYs zL>vwhbFEW_+wz;s#|KB5r()wW?d|u{q(jhbI^IHhxnUrA3jz}0kt#u_e>?<-`A*$G zP-aF=`Rc+kAC&CT@!T?^TM`+D887>gI>36u54XHoUVd=dhfG3%HO;B10Bdqqi-Lu_ zJ>@uBx1LPQ^rxZo-GCJ9l0xWyde0xhOa$&yT} zZd9&0Y@>+-py_zKW^jGs>bW9%`C24US4wF#o~X!MA^V#uBf)&rX1YEG=`3@FA%NJ9 z)|_g8RJyRziODr#8jbOy(w>A`vd`EI`@OEM_M}XxP8#T;zK6kl+0!8?V3+i?iu;$7 zW+VMyxOmERt}6uoT_l2i_q7LBimLpq?|DC&d)9$P0QTzKWA}G~Q6>%X!|8Ljlm^Pm zuQxa^s4$t}N70>N*e@kMF7Dkt1yVM2h%E9z27le0bT@0AFZ!6;;!NnH35~St2qRv9 zxDrSpFul|!TklN#lQG!3cgih{vaB3du&b{}#TMB{9kscPM;liEkciH2tr9Y`n@%@# zhR+Wsz$ZDpS03GP;8JsdM#MtX#Fs5pk$aUFxo1w~r~NW5n%yMZkr~lkNZ*NTG4Cc; z+%M2AgQPR!EZI^WBE(FBC)eMGlok5dD`aA+fnWHEEbr-ZmTldvK|)pWk<2?>*}`(g zuzwip1|a2_GAJI?t{bqs9@|D!Z}#r%Bcre*0rAo4l*vKh2SAD7x2L`gY0;4xqj2T6 zXSi{!(IhWVH+0;wj}U+48U#PkJpIr$O;M?O+IBPqN;ns?TDh?h1W5cui)bI_+q)L^ zQv}mqVk!M-pCqOU&jeKwhsu^T!6NR*>bB%ApSO!SV4qv1d z0W^#B&U8grGo;&*qSrjHG;W`}p>NURKp#^j&Wl_-EKdV6`q6__T&NX!h&MN&-`Y37 z19KPn+A%@x6#fNKvKdb7StsIw+-tBw^6_)of~DIkBMi?iKyXz~Ajy@qRmnaZDK4JF z;urRSoE_Y8nzViJva9sN0(*UzeI!pj0W$G*F*X0i{zQF@kK zyqPDabl)IGQ|1dACXFtAQZC$*F3Lr{#VO06Rm~Cp;6D{}HV>cj+I*to_ zU?l%N$Ivc1%XUZCj!+$T#pyzxvae_OH&s?@&yLMPYS3|sqUyAnG z5n5of3A0d2&KLrOXP5xapHiPy2-+W~ZT>Ox@_S)i1MZKg(K6K~B9@^6ps7ye36I5j z%#uDnft!62ILQM+ta8XAq_~3GoY=O<7nP}?E47ng8RL&(eH%BP?>qh3MHZEeU{6Po z6BAz7=y@_Ro=;GB%~e8usB=`$;{B?g6=qGjR;$b|s`v=q7!_F#G%@C{3%1e4k*0U) zDu{A~ZJb4=X!Db^m%hCvfW|gIPQ|&PxY$@efs%Sa;#W6L6;PE(ksypg%7-;*Q{>c2 z0ewa|FO*REM46{7_YhI~zqk&;2|1p^6fg75kgxKT!>V3wVq`8W8pNC^fA|{+`DT4J z`mt}pG9mfNWKK)MgSa_v^?71=Z@(`DiMU}blt+O!1KT9_;L8vez`e9)kPqSE6KjgK zvQt8)av!Mwo+1u^3|aj`DF*AIRQ5mxgw_DTqOlRqWekG_IU?7p{5LtZqU zI0f#C@JeIhU>_;7rGBxn@8cb2ACOj0baRh6bJYgEMA)-0 z;PS&y?Y1rZ5D-5Ucys4Uky3Vd8N72Uxq-p0)g^uk=PWn;5Hs)Sh%*d^uY&XX7z+37 z&bjzw#`Lhr9*K15iJ&eiHk~@Z?N;2QZaC;`VTbsY)?Dldh$jeRd|Z+k){OoIJ{Y2C zm|{xw5<;*||5N9FaqTt_tCfMGC!SGlcjFn$yx+;ofg+Dmi(#3iH>5pqiZY$sO6Ooh zaheKB0-(fXZbI?`nScK;Dq?w<=!<5csDEHs9V{OstQd!Bax6OFLGCOWn8gJD$TtmBBW2Y}ezIykk z%>D#2`+my1SqzGdjy#`2^c7}=Oscn+eNwNH)x&)%B(u|>=0w!J;P3TiIcIr~qq=x!MvmOQJ1S@QiAutiDp|m$b$SZ-&DoSASqPfhJvd|SrcssDtMJWJtIY7S@skRwd7Ollb}`i~5NV#JjiJ~FbiBefaWNnYvZJ!vc%i@=?xLGXB^Q?=!c`-uHq3l}~o?nFr>$M8T zcg4xh?ejo0%-f1xYEF14HkyyJ09PqjAtqhY;s-q8r@DIoK`1>FoF+ryV5S1NH^beR zl64d_VbxJQN6(OC%e*NkMa~s;Umg zcXHNUL%1`uN?_l9Wu9cmZm0vA5=Vw*UKRM4+mcUmusM1C6M}NBdB1-23aCklx*1RY!9-NPRWR@tnXAv71LKkRj#Ps>dG@fLXN&=!Ol9f@kg< z3hHSp7y2k{AE^}9<3CgSut=ZDa6>Tq5u4%{!y`-42aN9(!K9mu6?Pa_4U0HKaUU2S}c> zZdUf|ii&+8Kq9CV0ui_WBNFg}h91s|+HBoH)2#C8yqSUHtfqy#lvS5*KY!kZ@T~vj z3^(A$aV>|Z`XaWF8_)up@M0D{`F-y82(k>LU``T2PQi+%!A6N#0kg=TOU!;?pi?l%_%pmlo=#-5X7itIQDc zdqP2-VutI(f*AO&pU5b9*JM#EjSpZN(BG99{_W3ec39ZVbIDR(R=yz6;vrq`Hf_3P z>2{O~c*^-5T{Hdf;+6K>hfDZ|PiVnbg?zxD@?hHS{|tkAkaUaq#Ln#z_5Hy)0Ez{5 z%}3IuoH7tDo6d!pH2{A^;~N+KHb2sz_Z&Qy<>oD*udKU1NxVq2){?6=PPBK!8IJ+s zVcz>@q!V8DpCwWZd~smPdqeIb_LuMv3BLtMp8K6#gHYQrsS5qFff-y;558tIeFcQQ zR&l9%BV%N2&ogE~5Xm(J7ECp;bOSh9VmxFz018>kIyN9W$coE3cdJ}=&+3QIY=Q&2@eF50t^T2j+ zDjuYNJWTa5A8y^qWTepHz|crI>FjiN)qCo%3N<~eGL^ZZmiHzOt>kG_#mR2z9B7a4 zVJ%-RQ#2ruQJ*RB<17=nJ`$4TzUbhc-@mV`BbNYhVTWCd)*EuiPvpcn3ac_$PJqj| z=U3#;eO`pBy;xW()FpHnHv&+LIiaf;pCl;^y8B;5EUxN=CY+K$Jb|@`%X&it?$1w) zIg-L>TvmxI_+d`HsE+7fB>eZdyF|{J2H+B@L6YI**|LqC6c{7?Pa*>q6lri&kDH7Q ztFcADl}>Dzs}2(l4@?kc;?$g(QDT4!bQh5Lm-jF-kVo4Hb4A;HubWO>Wc>x5oCGj){$lH?Kn(-1bYMaX*4OZpKe|u z-YQw!_>XMZc;;}ArVwR(>KevX%@ls7tY{)>!o9;*9ac&U4g4m3T@HLB*lF!==yuM} z439UQF0PY*uy^*|{;E9_9F=%b?H2fk-Q!OH!l?jN#CaV;5wu5Yvz0$u(YxrgFWEu- zt6wy1yU|Cu&H)`YUYD@G#tFj?rfB2L;Bp@TEp1sWDPF4ZtAmHnH;aN<(td!DFEm z6ZK0xJ{%r{!~OK54F*SNyBn1)PGAqtV0?BV-ft_FR3R-xBN)Fi7QhRrXvzH=V7+nT zK&Q+J*OK9%TU#Xu2cm)i{@$AB%P;#ve;Z~j%hSrJI{Ju3KfzdfTH2{$9HK+j9d?aD zK&LP($6ivc%jdkKGToy6Xeak1YGseBf_40|bsV+%?=>Qe4ouvWrrs)+%)_75nv7Q8 zJ>4<}!%A`8t(}*02SPYE5kY9U1Oke?Z}P?Z7kvI%*3ul4=jalE2+x+CHQOSpO03#d zOvGif+6DA8zwzJe655Ny&xI6O6`5YrnFnpmcblY*FgVY!*X#RmD1m{#U&pXanq8Q? zI&Pd>EXm*D6Lo6tGE3-90nQ!Qh7S3x1Jj~CO7?v)abi0LPEzAwk}gL#v+d6ur@@Wu zL2=31#G!>3l`7DH!4l3q;=d>1j&$0jPDpT&Klnv!WcQFU-Pn;cNcYGr>6VE1OF+%+ z(huDZI-OZfg2_Hrrd07gA(Dzgee=OEC8L)-V|<*M=-JcKg$z?KW?Y8p|^+ ztIBY@XCv*}DB3JT*aWr0EBu5%lpLXJ(4R}*Rs5i7Jxag;F|`~gmOkY$cYb!uTu)a^ zZK}HpzjqOzzA7n-DwqDHZK1?4dCzS0)^|{z>U*8Sze+YVQSH|l=8}J1p`&@ao0skB zAeu(JUB03GD3)N2E%FQrgoAO)UAGGLDKUA~PDC?jRIVqPy@?9+QMbT5P64O-u(_l( zfP!=jbAcfN{;&R#j~ZwS4b6Y|>;=_LdsJ2v-r!T|65)$fVje%uaerOm$I|3358PT? zc;qI}qR`$5mUu?-kE{uxI^op+q|2SEIFWALAZ}dj(DjNE+4w|qfwHk&Qy}acGyJVA z>i`}J-z5@TxUEAv_{X|*r;rSZ?}udW07+GlN56SZGKL|>T~nn+2!z9DNpKV`{1Z=h z;EYKa8B=ldleEHlkXSKMTK%?aol++#Y^3OVf8k2?+FHC7L&zhiJ`>jglDQjUiv0|4 zU45D;$g`7UZnAxSl7>^isXNi73S|5Xc6lQV-KX6IKn?>%BSR?{?_a?GWyNu+a09;&IV%v8 zTEdf&5aOty0J`VwlWYJxwi7wUL3Sj4r{|SA?m+5R5KLTm``vlQm5%}%hk3?59jy#e z4yQHybPr*ip{?k<=6cyg!$7(7?$kL#RKTpig;t&FPo#a7LlXN>LktPykwiOEnuDRT ztfI)!Ze$zM${{{w!vwlLu21+lLXGq4N!9t_~myLcluXty?wjXRRf?77)Y!0cDd&h+flte$|$ut z793kUosEgV*l_k}VSQPN-fV17%QAMqKiV`j@OE|09|6xTLOs{}-AC5V#rPY-VbS7W zBu!Gcknrnhnm&%~>37`XShI4pXvM!yP9{&3LP&{iWYpRI8>SE2{l9{J*V8cDCMq`ZT%tH z=$kPrhmvnJjfju*$N*JAF`47Pfv8UEBntB6xJD^cz4m!?J@^-*Z|d9gh{;r+`VHyc z3b2NeQL(#>ZPq%`r!q+r(qZ-{pMy)fgC1@>vr~cpECC~;X|xyv9&Lw8`yb%Q$ZNeJ z%2K?}TQSVsKc%(nZs??pnX#Q7Qz6Dnc1{N?RXl|UQ z3oZspbJx3ffuz_{8sX|QkeT!e7}%Qdr=+VwHo%D&fAo^qMbW8ZdiE<7w`UrTbonqC zay1&4-n6sxh5>Kd1UY#nyYg%W0vm6Ey|Q z!~1YvnkU300(c&7!Rm?UxT}?dd4ZHBGN3wSSr!#IOO-dv$fK$6mqax|%?JxTQWyU_ zeB()dsB%>X*6~Qb%t~!_*QP(ZsSaSFs*Q_%R3&xrasj#_#EPa%n>C@q;;q;L2T8oJtK?gf!w6liOs^232{~Y%ApG+b>y*Mn!_)1 zK?jHo3Hg}5j%}X48}SYGGHD7IjMmUc&vV;Pt;xP#*?YPRJA0d8=iY#H-hcp)%-;Vg zv`$1PJAv7dS?HF{+ey`Yd|E}BTTLf;&doPoBFaCZ8 zSQNuFpH(~yts@y_)BDg!CIZMcP)*B(ohRYtZFE)N7$`0QnOwmISpt}c{uRY_S%yB6 z45y?^XgUDVm%rc$=%uss3mK+|^#WE^3Le;hy*V8$$gbZQSui*)_fFBAM^{)5BIncA zLx*W~vt%j9&djUk4-_$Ui^5bGoo1w154Pk3$P+e!V=k_^k=$U9HeOcn_EDT6OjB;r{b9MnR_0$EZxxFcl{JfylLAv}X*~E8~wA*3f=RnlZ~`j~1gx znckD4;)^TZ5lHM_ZAe><+f*w;8snRn5bS~}M_Mv&^C^!L>{1v+XdHxx1F>1cEaJ9@ zi2&WiXco9ZAX0HY;wpy_Rh2JH2oWr3(D(=$+&$w^25A*ER0ohRVOUpTt?;RWB6(lhqW z@TTSS4x>O6%bZb>lx_5m&k5av;Y4-20zi}Zw0}3BpKRg7hwz)NJ66JTv>qM2r#2K%%8X`@GIamq9=gN+A2tcKzCmc|iy4Vpz@+)Jm{L2>ib2Ph3( zBaP2%th31d`${bIz9Ew!4s>3d^ofN_>u<5@v z17sxQ-O)dZc84kUWQ%lOp^}d+iI1Vk&N%K2vBq4rT$cvlPqyhHvvr z?X(n(=lJqsq&Bl2{n8w@<)9>U?rTVxY0_!G^_Xrt+h!Bd*=};b1wTropSV)qLXD@W zu}Ik})}WGclgm_f+4{{Z#jk}ro9bKv)L^+^Zr@C#zPY@T21i3Qs$g6j2tQSxMa522 z*m|Y8eWA=Uq}iT>U26ldQq2;zu^@F>)cORcT6riS?DxfGbQ$dAFrdX7@vHVAjDCo4 zLwjvIlQw86HGYfq-b~7UG(8G0qT{OlF<$ad&gT~zU&i2V)H{+vN}Cpnb`PsX>l%`y zvV70)SMi20jx0}ZjOjgC0a2jJQOjicI0fp9_^ds+r{N(3n*0@0``4V%jxGhdHbDMF%}*ihWv z2za-M7=DRPtZ1Y>JNU?nl?MAwxHHq@OEdV>yGMlS zJxB6~UyzyB#O2{;8=X_U{kigQByJ1L8DBK-(KH)vTe#`ZeG3{4cO^{7QnDFso-x4) z#=V0288a2j)%JaG1~-Cf_zRg(nE>CK6r${ZrOXhY^Bqa z3tECue+iN32@id|@ikdRUv(zYIY>_ua61**co|Cz<*W^{rGWJRSI1jEMA7*F*NC)$ zAdN`J(%s$Nuyl8KgF{NQba!`$q@=Kfw8YYa(kUtNr$hmlFCP2+H5ws6^m2yBN@_C^x?xw~g z`_(yUsy(|3DB!=~ZYqw64@8n`(l1fEzD2cpV2rlgCeo1O;GX;*PXDq%DDR$YoLu&c zIpDeIOI0m^e3j|;>MiRV&w(UJk)?F?l%}faEiPiyyoQ2*Roj(gGM~~u^ zoP^%45ASpOezUs!T&xOnYAEBVQ=IG+WZzOj|B3^=Jsl3_ELs{5_ohQyi+eDjC()YJW3w14>SQtx+>7)-nWWI#fanasOS5JE0>N3?kU zh(5@pW}J{`!i&1z!1q)nZg%$KEXw;badzb%?%}uKwnY(;E3{u%W|7N#0G%k;f|6JF z&pCkaYbOr(<`-A!Jl8387d0t0949^%5y6k`G)(9PHagtUOQoUp5=cX^KTeXA6Hc#v zcH&{ZgLyJSaINQ)SKn5f+ZkBNuqF>xe0@u7K{D}cZv|QRtyWvV;#+;qF@_Nwl@8=B zrwm2w>nVgfY%d$F2Qkl0@Ras}eyab1EHQxPz2HR@!GpRH5vO@~VhX$jdAX9I?-xBRkKY9loFm(n8e8uU>VSiUUrlQD^rl1vZ|sB1U1 zY>$?+J64Ze9zN= zAysgcVr8S2CuvBI`5gt@?D?)K^3lvcMy((%^^ZkMN^0{14G|UOM+A{8h8x`I8-Fe2 zTVe#i`Nw)DbDuzInTlgBBk>K6mm7u*W(RN50@r|9Px_r#OpE;DAea36hKy%@pN9>- zj&v>XGYf}VLWMVBpTyifVOS!C;)iSYgO7VBUHUO!)TQ1PPiS+@3Jtw?GsDTc*!9r7 zxl3_^(_}N}sXKOdF&Je9RJTYr*zgkSLkoXqefCde%%y|w!t|u7$FeFnuX72X?0!oo zX!+VTx~|4~&8bVSncAMU(I=wI_>-aRNxm&0J9Prlf~>&R6_eq7ufZ!-2;2QzG7nJ^ z6?oeJYauTB`kQj{Ih4qRrYQitDH3s*(NI>GO_R;!Q08XyO{~55Vf@-U+GBDH>KRA# zas84b&@;X`0+VcLSSkE>a^`cm;NC=zo;2dTRW~E-ta%z!`*7iH3V%a(GGA<3N~tSw z#Nzb60#uf@pFOPMo*_-=X6ZT4@f$R%BX)rI z)?(ji?=&J(JhAMi`xO!(&x{R8CIZnHCdKh9l&)a0sSK(0Owt6Xc;wu8nRVY!F&Ql= zXUTpZQ~q-T`Q2I53KTNfa?ziLDQf|B6V0H$VoU?#&7~KFJAKqaGPOrjsAr(*!-JQm zyL*)yn|RGKO7*i545d1)y90Y}Lw6Y^yMl&i&@feFCD11E4QsIOBQUfRVz6Pf3=6pSbjB?-=!;>X6 zIvQFUl|7K>%?mRy3woN7P8Z22cJ7G2Q zHpl;yF0eviD(i5ZI5oEl^VOlq|LYh%;MAP1yY@;?mAe0Z!&lC}MB6dR;n^Xv8r`en zvqOAUcA&Br$lfjJ*5M=DO?6@D8Nop~_Kp2g&1&Pk9yy^IS0lh6rvz}y(o&^uN}fD) z<40$sTwCjv`{0;0t+GXkSgrGiM8?ps`nFWjkIz@~@$s#2iYnD{ktXgzhQ?*ayw3qa zOw!=5Gs(8n;lf-h$b4n-J))c|cp zrx_|#`OOz5GpV;$IjTc_#c_-SGa|dF+w* z{F}z!1+@)&@`I%^&@#l?r|Ud zq$~432^{AFh%-C8{$Y8W8()3!pCIk~uue$c;%Tk7OPN)!`;8N;|;4itr+&^(7ymvUA+Gp8R z6}(cjtv4Mugio3=AAFHMJ+vAPB&scCGA*8x-cDiDc6Mm;78 z%cblef*%vVhrhq^ZtwmWy@*@ab0|&v$(<$YVM)2lv{cvs-7lcf z<6KL|l$%2Idtj*gmJ5mLGx*Vr?nrwcBeYMdqohampDp7tw@p>%$Ltf2vxrw1v4o)Gu#whZUagxr~I8ZUf>pQ@oX2z;tY}X#K6=U8)Boqfdi2@UrLirD>mhz_`s}&$=}*VY<3Hlw7c$a5 z*t*T^*^Ad!P+t&meiQglI6!jKXibJpr5^Z4CPIXc%pshdx!iW(Eo!kd59GY2jA$zR z5-pw?Fai=o7)$bIW0zQE8)Uj0-0@6@_m&iSPWCXUBU9O=bSJ4>{c!pdqZ>*>lU7G4 z7ZaPsANStyddI9fN#k~ePqK4Id3Q0C$-y#(oK_YzTfCMN^UXF7dFYQVGP12@CLUI_ zTC11c#u$FCmvpyU`*hPs0+4jbcjrQE<94*Js?ueo^UNf;3T%PWEB@bTr{N{WH#+v2 zJus*Ahoq)S#?>+Z=THSbr0`~}^Ja}`&7_F2lz@bTzPM%)GWwnBJh$}aB0>iZ?3g)^ z^JsEEq}ZhKvc%MwJDlF9&nS}nW_@xpN}}MNiUf(O8;=H!dy@+m{9) zyvXko{<`>?{{Ch`Xxg`Y`!b$C{@RE^7gz{*zk;mvmumJT9W%}FiJ?HcPm&pwLFim( z;~v&%U!S&vwYixu)Y=`_Kk4xFy4I6)@AW1-{MrLMiTu)Z5bz>C zDZ7Guu5IAFIdCHQH3+%mZ0qJzuEY3=VC@?LnA7Az#a5_LqECd;dPk8|vZ0VRbfPCj4R)&6ng%0$?IL ztw0u(Xq*zxS03Iu$*l5~RB}bmJ6SvVxpoL^`FK2ES0l*OI3XiPv4y`b-{za-mnR#%)3|I8sv4S& z7gYM&3FyrUc7Rp&Q)mFyBAnw}62?EH2*@PTUzWnFgc)9sXJ{eV@W88Oa!mEornZ(+xA6hp~#xyT3ibmpkYz@pa~)#&JsgJ3#wKNeKJNb#~9@)#ruOXL-mh8OU6_A^@foq&)OI=SjG;7CDFD zm=VFU(a2#>yx$|#Ov=*9(A#h3T(m#pR<|iWkGactJP-S$gb|=wVqKq#@#}S8Y8h#5 zgZV-1l=o&;G@Da65rVv~Z0OWe!6xiIz9yR};~9(xtMKRkfk^r=0OonDGsD1gJS%q zzNW=xILTg;0qI7Qv4mloTnLFxz6nrVQ%q-aMIVF(%&XS}j5fbpT4>Izmy}GR3b*iW z08bx9=tK3<_ot$@_%GE?s;xx^coDQ*v?7HFzMN6e^W-S}|3tX=&aR0hC`gHwvxw*{ zS~C?$eW-OG$HrI(aMxM5J6q&h4s>Uy zNvpOiU?&SX3{H9r>BA4W|6ykjV4?r7- zIY{d~f=CP)Wy6XuBT$LkR5A_5rO>NP6%_x1D|qd!mrar_@wZn>`qB* zI0ZE(och1QNx|ng`v^T@=!Qe&GJw*LFN(={7QPCFaH5iI37xb!2*H;`F$+EtB+^Pj zVzZApGQY+ozdb~`DU}X+`pTowkP=s;Iig_Q^5hG=Jxvf-q?((b3+j{xS9M>t4ku$5 z!?RO^K?vxGDSxUbb(PRm=VwfHQP%z!UsRBh@z@Q!fEP=A;3LOU8+@w@EJ(=BbmgwP z^*7ONh`cYNE7hBeA*`*?Cz+tW<{Y#B=oi*hFul2m3Pz>F;Me+|a-RXV^DPA(y_foI zswvLYv};v3fymA3k>&J%R#bZl?pGzW2BJg?-L zxJ>{48?zbr1Y`8=9-=ON>@WYn5kbe++k=lUrMfmdZy5X5&vl8(LNA=8MtZFiQG?Dwgx#*3I*&de@x zQjAV+vXgb-t^qu5_07C`#1w6p+J$Fh+P&JOYJ74Gv-%v_3poB88i0;I3TE|%Jfyzr zu&lv}a8o;VZEddFFJKk_A^819$K)jYZZwUS^1KvLm;Y~Q&^LLfV}{=bsnonthxvb@ zZ}Z30p^M97JJlp~pi`gFer$}mlZ0unIgPUhCIF_pQ{lP?txcKWv&Ie(M0kLGBXJbV zGQW%h#iu`WPR#m`%{-1m!;b4gy~VgR@DXA?I@zKWI`l<&EH35$nqu&7D13+^STPLz zM*iXntLmCnhs{9>RI;Damv#bBA`km(Doc4UovlFY$xzJ>80|g8Pc$@w7OQ zw}Yp{UyiorD#g7>YqK|bKPsk1Cr$@!&=+*ZZJ!4V@{q(6lE}Xd0fj8V3{MqPF_6!$ z-5Oc$Wj8Biq3N$p*LB+O8NP}5I-jdsVXku4i-$J%r!Dcf&Gd?$0!(&5uGxw0;a=66 zI9iuYh@XhC!}uWFq|W|4Ce!sQN1JqX#c;XiJ(Oa}R8P9tb&Ve|%zdd}RB&c1NH<;qN7~+#^+{bXaq4Ya;BZ{HTJ{oNT zBL}#D-sTYwmS{S@;dhQ04c0lo`D~iKzi2(5_HOak-)BjNwn%VBE-fRe;}&;s*>P;P zy|(iPx>_Asl}8Lru)B0+%<+0Z(^Smosst?b7II95bkzE zs9VpYC#flIag&!XQBBLGJT+4#xUi@YMr(>q-?@vf;J@--R>w+bYSZ8k_3*a&6pYzf{li?Jxj@tllfuCm839yjRp!5R(PMR z*~r|E7c)`cQ=+CmxO3#PF&k;3+1WkssjfhY{bL4~la%=fXc5N)an^wR=gwhju~2(z z3lM>nbE*REm>Kw5dGd>6$UN(Kv6kk$lm;m^^V6W1RMjN$3Ea!{SB0`tyPrllbyZ^i zv!0qU`8VqCvDhA}wphEUmI=Jz0+Yi0F%RpSY`xSP$e>*?Pa>#Il;59H@hc$0Kq%LdVl0z5DuIy)0^qdYE&A6lhoawb-DFTqi4W7g<4Zqia4Cui z6(GMDz^zK<)#$RmHT6qXYJ@~Z216u7V6LbUh7uGRYPM52Xq{_(M@b(m(AQF*yIPj( z^G*a&Pu+=v3}whNW=F05x)B9^&cDBIW^p(Q^^Jtj`Xu(P_ufj&*!;6FqUypQC!n!?TwH;t2?f*KPJ^1nnJdw$K86#Ja(_lyM~4JNbJzK z}#f>;6|N>tUu<;7>ldZqd>@VH1QqoafxJ&q*oXJ{3PL>43&6kTbpJHe z_i*)@#a;4eZ6dMiK#I-5KdbMNObgS_2?H9vGioPU2Ajqt^s-H>cuU;~?xtm_aE=3f z*&Qj!Y58Rj+dq1nFPNZO5^@U~-$dv4(WFOZ4;NlTT5}_=Q9(g&zg%6(%PcM#FOnS5 zJU+>2TGhkSME}fLG;5#FjR6En=u(?&YyK=R-OFohDKAepug0Q!#yt3&(kJ%48m5=K zMzSw&@D;1C@1NKByt)_Jh$hpaQ47kN5(^USv?9Cv{G%RPdrF6gO$>Qxzh(p?6Cc3s zB-S3K>ui=+%>~`)@tx=U9Be%s^@1SUa9N>z3l;(=UbFnghPR>9sel*dM4;(BP4Eo) zGBRlLY6%^Es$5vEpD;w1oI>SIN&_4M!aBmcEor&aY{ra~)v)!i)Cdq?HAj@@bBJ2!fxur|d+P-v{?8Ymf4+1wee~xh8T*EbPolkX z&xDdIQB)c*k`iNis_QFWRP{lFwcvFIg^j9*w}F-nP-{gmvt1#$?^S->R?MR)BTB9O z z`!0%Zr{B>mb*@^x+>S6fc8q`*p8ikFhS9Ev=H?i&CZ)db3ds*mJwY+xs zd44u@p221LuAK8}CFw%xqmM-&Ik%Hi2PNRW{So;!% z4)s7L?xT=9Mq6X8~N3coG4EPLtg<9!X~kl`JG93SJDye?Izmg_fUMw=k?GF z&M9R)n<%$@$f@QDXwhq7uYwiS3=O2e9k#u|g$tM{8 zC)p7EE(^al=B;== zNuSf2B~ooB+KiMgF+dfPUi|%DpX1I5k8A`QsWO(yp@W&j!IM~j=O5!+jIl>o_ZTbn zGk-@`C%GOd`fT-m{bI71d#C1cg#sv>lAL#ivwJJ@tCkAfRZDM_G8FryvQ~Y0DPJ_) zs$me;u6!Kd^J_spl_93_OJMLXqTRG^pv&4_GN}ukJM5a?IM9 zi+{KzOViYycJ=#Scof%ni*}Hd6;U!Zl}!$CD{rjDL@&8zRgT|))J8#1UjY1x`eF9h zY~qB0sqf0+EOQPTW!yRUE{Y*V7WtsA8Y3tw;9KrxK`RRbbAS_0s&|o#KT2i~Ac@({ z7VH4uxq9qJGz^Y^Te-6Ck2UVq+NtfKSgKEYW~TG?o^+LVvc>gN8Fj!VVHOih3Rdx= z{fpWL=`h4Vgl|;I&dzBm7syk;I`r)el>nz@gc~@Rt&P-c{ykgBSL|+dd}D81{4%=H zcHN30x&7_K1z%fKdq0Z{jM`UMha%(#Ug&EyD%j&-r`3+`Vv`Ow8V#-Uc9lg=@-1`< zjGZ14$v875@L=QI-Ti}hu;v<;HVUYF@=`xteSdBL9Kg{}@BlYmK!fZ+kT5-`o!kl5 zBqvR4O`MtX(Uerj?RWTB_mxtGLD(A$#J0(!K4^oDm92rfTb>zq9^2~kDMTk-YvoH9 z9hZ&~Vx~^MzZyF&USylnCQDHWB#l|?8TSVFJCkn(TtVI$ zzgn(FDfRE@+YrK2PJxDy*}A7xSpZGegnLzJpPYa7!Y^qTc#YnI(gzkVITC;4RfTS4@> zKtl^KMH=8i0bWK)EijWlAdQk&eMfmJ0q+_34Je@g9Ij1$8aT9EeH9k=Sf$(2tj zADN>)>?1#bA7~$+Xl}qz#NIW*y+0t;6S9t?kMGR+^V7|igRnfE`1T1}kGXP}yXub; zre|v009Lporbxu=gDBjn3w*y5-X^p?*QDX12S0pSmelc=5pg#J@BmG*=7$d`#BqqP}^utHXD><&<9=?%j(--(KH*Bltcc#v+9_eDp{j$I8K< zXkh{mCourVCwNc-Fi(C~k<7@0iVs17QPMEX0 z|FuUwpVu#tU>$@?XdFk+YIzs+lOyC`uhh(^e7)8-kgm(qaS5f9{Mjr~ce3yk1{~bW OOJ$3NWV;3;-2Vd>;YEo6 delta 26249 zcmZ^qRa6~Kw5@RnuE93$?(Po3WkU$=7J|Dp?iSn$?(PuW-QC?i5S*L;-1B(vsE4k8 zs)z2eYOOiHSvv<=I|mt83_u1DQ(d7067CIn$ne6(`au#^2yahEIqIHr)ND81Sa8`L z(Sh3(_cMI4#<3!>Pp8VgircEaGfZ2&8Xu@)EwI~ocA!a8YCG}MiR=KHsYh~21s>*d zRLBT&0wLHf<`JqPtZwd@Pcj((V*WDM)&CBJ24Ba^gbiU}D2HqVir78{uY#x&1P=R= zP+J2ZC+v-sIYAi#Q^hI!FH}!=QzGzvkda4Dcua6!f#PQopP{`&y1#Zp$#$kr%L-@i z+DLXwqOpqRjS+6UJIeLzfL-D6NfQHMcMYS^A&n&8mL=X*;;#+S{RlxYh9H$I#QvZ? zh=K){5j+p)7(72<2_4=Z^h=%{4^{8h&Jgoiyy77z=3*5zv6p7JSDl8W3DL@o!c4`KQ7McCdU(tKJF?M0g|G zLwE`lA|8-MN2S;oW6oAE?4JHxorfL?&5SprM>kc1sSG4ZS+`l#Jlon!o9v=JxHg3b zQVj1H+FjdWet$oDH9Y+Jk)HeUzSIR5Ky&=!SYl*PFoP}yihPbg*dgU4_L(#7L^&KD zx{YO{X8rb?jQE}{EkYR{e{}<+TnlB!??(3bld!^a=_6cQ$@|-z7k8)gEADN}!K0=i z7Kt)b76ouR!n{B9Ky+B|j!e#34DyFaDDSaHm+3LIW8D)p_3C=(Pm3zAK!3xYad2dCLDOW$fGc7D8tTb|A<# zA){VHtV1NgnLVd-XAj-My=Uq)CR3!Ime}g#2?weXXBXJd@x^$!{^T@a{8;cQP5uEM zry`G;;e#?6u7M9a4L?*truH)-aH9H{^{m`iUU;s&bUoo%{9La+WPgtG(9|SjTpJP> zIm17}G!|{K`%%7B`;E~v_~hWvwC3{Sp=%$aKqlE0eFptT@>hS^1A+wkQdcS*S`C)M zC8fq z0jvIS9ovm6HX~~q6yxCy2!k1SXK)nh(gXy9W3401IqzMT6S$o{by2C>w=OIWxqCeK zSpB1(zfwQcPw3nZWDKmVE1mpdFITKOy#Z`)|w>=sZ@^fOP9>F z%#4~s8v4}$IdfgRq+x;W(Yeu65D+|!g;d7Kv1-Lc!+H60npS!1+lzo!KU_1=4I>rU z(PQdlz7HoP3WOfKe(`IR`?)UX%KzQW2=pC+Yb5MtJQhV3@^=zqdJf!Wu z072%k@f9BF&b{B-8oqjRfrh(KKkK4bQrja^u;IMCPDkup1Ql}#FB5)8MFgd}5)Nd8jPR-fd|i&PtGc>l(pUigj; zBiek5W86%1hhv?KvkfgkG-z^xcFl}A|9X&6cqU(r^&=FF}1>&E{J_fJ?R9K z%wyGCzS)-b0YaO&Xs@?1f+)VVqmtmwH8w&&8r31}lM8;2HV$-=-{U=?Vv9c-fj+sr zhty;?>NEbl!2PcPKgsf~LJwi7l8Qq}%YMpYm0cgqX@c9>^Mi~?q;@F~Cuf*$joFwE5CGpc_j-8dO_H2IG&|-^fFJ7UO61Mg5k}ZY z@QH`l9okm}aDv(N<%ho7)YSz6-tfY|`9!vWzlR_Y0Q0i_`e$P2W^GTx-v0LFnn&#B z80+!zM0|eiXU8KYZE7Q$vag7zQ^Bw_FYKuEq)kN#fH<0b z-%MgRe}8P`l22q5`aYj?Y<1R#@MA=*oBjIvU~M~=Qb{&74R`)e#qa3j_18C5Mm_K~ z8eYF_JL;yGYrxUhR@F_hhtIhZc;+n16r4jhx+0IHd$Dj{qa&m=W-AE9sHm~Aquj6V zpl3@@qUh@w8T_`Ldf1H4mX0Y&!ql7|r$i6Q1%AZd;M7T2=zIg6|SYeUUN-sQe9 zeJ)WBafS~XfAB_~r5Ca1L6lUs!oo6-2xpt*wvufL*6$*P$Lw!Bbt?Tg1P8Qdy z=hNyJnR*jPGXJHrQGP0o;zq^od%|ymu*#j@w$&|j<^)Qlh0bdv)cj?av5nuRS{S~k zmcFsKQXLHZT=!LTZ{|7B!_#N5olY1fOx|}*s1{@duHVkG43FtM(v{+7Y18d029>u9 zJ1HPZ!T|$c`wOF&+0pu3_zp94b(*gA2t}?ZnW*sZe$odNty^tJ_vZDN7}f>#ofuQ6 z&QZ@Wy{v+$&>smPeZm8B%Li*rYw9x`8D%wtDLz7@!m$7wItouN^|~JBHQH9U3cVH*Hed2`4%3iZh;6~&C=!3zkSOJmvqn5{U zhY^bu3lE;&!QF39x?uq0dcY3Waq_UW46!oqDLGkIqd8Wf z$2P+4DVB&gnpeY*6ZByv!JQZQ!L1kNuJ;peic5D6a-I5}Cc=gVY-?)FvU$tP$^~Bi zRBK5uxx$gsi-JNj!ws+%!FTP32In(d?hX?FXF?`9Hw~<3i*g9C%Zu&#B1USNY4r;V z-PD*Z?FP_>A5iK7R@}^QsD8tzRhn-^g>t&7aHCOi)n7(PeETHxlQ?(5G*WDYdCwhX z`jXZo>hMYw;XuFwzIDtSHc_9AHDog>XySzLa{sF2uJMFyc9~l@~js3XRN@#WLm9(6-q$N7B1hru^a(9R~vk!evrHPp@r;q z!G!?&mUQ##@MU6t`{#9PF@cdMB{klj}+9tYK+C zxW8U+n{ zqBqvhqQx;GNqh@=7?s)MAZgP?6)4kFoOv9z1Hi>fzd`H$KS z9M07ri2A}uac*$fZMT@BWJJ06Esvb<^7A?o%$zrH&bf4rp}6>4pHZiRV*f=cW&o4Z5y))fgoAI>-}A(9(mB`8`ou+&MK?k6#95)W zUypcB-5d+O&28OAZjWkyhWg2l618p)5sO8$xtw@H>YrMxy4 zlg)nZ`_#=ePOlkodMlSl9havzt{n|c@}qMxp2x9@ zZ#Q$~3}vlgiKyjq-yVfOa>^PT^$A>as91g0Qhvk-jxC`-DdoE1BS~V=#(n^5X8n6^ zTTryeSAy+V0m88>Y=9XG(Z@`pgBW!mq=?)y)8wm?)>^iv(!lx2=~cTBjpxzU1Iuag ze#ky~Ue28&FR-DV~ zItN`p?B1S<>sG2ymnNHDx$vyBMSdOAi#{*<)@t_e`V!7Oh2ypNz12IG;n}`lc39HE zV`pqIXN>=?0LTLsr0izZ!Y#&51EveyxC7`#lyG!iR-}&^r_;UDJo$9S0AU8;uL*T~ znnL_%1LY+~ATIYu8K<)zd{3*WQj=@bnRrU!ws&MWOZE79k!1WS_fG88cpuIOQNHDk z6}#Asqih!EtotxI#WJKO;YQ62H=P9Cv8m%&5TtM*0Q%R(LZQ3U?xJIr>V&kaw0tRjZ-OE!Fu{j7lHa&&<6(BNwOu;a*0(X2oWtd9G7gkPE*B{IwJ*5 z2_xPRur^S{zUvSb-FV`FO4M?8T#&?*%LucS71(yByD6kCs2HXe)e*Vq!yLp02? zEcfJp4fc{x7`~M5PnR>dU39Y#Is7cT_Vf3eXm)Ra3qB)~th0t2f=ob}TNtRfszDqdq&VysAX~oH_r`HBMGOBqa_G%yaL5>!ySKg( zA=lek^Hgbr4z`1K-*u2JZF&-lywK30$5YL@)z*6Yf^D65>Y^@-I02pmK4krF2Lj9g z%52xw=NpS$*&YQRZ{(fW*UTh`fL2 zmsr+Oalj)Niy!QrJ#E!WgoL@(<@-Uu!`w0GyZKEZ0EEcY@z*v^a!%92p$j?ztOQ}! zc-REl>=qKp;ZBjTM0t4r_dSqPL5HsvfYC4)H$$?>(M*(WrgoKHd)_ntk}k4NLK{C! zuWdDgKr%^6CVK@7!Ww7OSfeMJ*yZRK|1zI)AuE2({#=@zDb}(pDar#U%zYHH2lq(qkP_shPRn`%`?!Ep(9VkI^5Mnq3RSdy)}4a zMq<9kpi*)*_D6G>WS;By zA#oOV}%!`*|QjM!(?tCpE!1)2a==|F= z0vCljadoPd9Vra){YzwkhKY;C(XMOLiy&SK{~K_t-`!T#wK2%?c14!pA4`;?uhtQI ze$VIWLsi4V-uk_=@WNv9AOk-h{;a;F=3gadYc*4GteMUooy7kz%(`I?^^q(2T{ULJ zqBV2l9o&afb{p^RSG+v}aDcCoYY&X2a4sBDSj-&LL}!@xTKP9fO(2c^v5{sV$o7pf z9MZEK?Ry|Q)}s=X5^goqpH7Ez9#ksF^kNR&V6a0tD?PQC=itqQe=mO*jPeY?=XvYU zWBQ4ib&AB->CJ^?HRsZb&7f)*RaR}8C*ke`j!oasqRqLn2;sB@0)v$xkOMgH;FZT_ z!v$B`Ziz^egsKsktC-E)?wZz$yad;rv+}byn5U;6LIh;~Qmn#y*7Pi~G!ZJt%cDda z)?k`r+}qSfxJa6PDZ@{-^wgUPJ9NQERE?rUC;-XPv4*pZjpxS3+a%A+IVr1YzjfAD z)Po@k6iIU;_nm$M-puh+Qn!3qMsJk;h};24r%qx%lbKG3nH)#DDmnl2%3N}F19LCL z%Cb^x{MDXp@ToQjE=*t)QIfuTL8^_ zV^|#qvaf~4Hth4J=iuLo9bE!<)cAEn$G4kS<2>Y_6+Mgl>2E11)M(UZF&~Jpqb&37 zM^rCqO&niYusGlh?)7hI88nVQUx~f$KkJhPM_gUJ?$HZ5bagi7|2x*0x?)sU{~*X9 ze4ue<8!+e49V6=a9suhaA{bPSC6eLoj9B}jNlJLLAK-`=Mw8BUq~e0Q;Nn_>3U611 zvBS>gaC9BHPG6%s7hGt1@WcMS|K&`}fjMF5M0vh$U{u0z#35gvHdLPf{CCB^(rL2o zj57jw1oA~Whb*>9a9x=tZj55Zbg9E~9EWDE9^f{GY2r9X)Hqd&KgLof-9*ain1MS7_B3R+mb1|4@?bzR=(+q|6w}+9 zv9_LpsnC}1arQHdwe$=;FZbgR(@o#%(o!!m%?J8n*fz&lQiS>~V9-Giv24znRgF0k1r>lxdPx*F( zPsUhml&Zvs9JxY~DImbF`M^Tzm%aZ{7~sH*CKX;e!GwPn3~TXx#P|F{vEcA}+j$k{ zcslco+*WZ-{`GbqnZ;7h88<6#a9WTz{H2afXA(bs&Za@l6DdJ5Yky&doI55qS>M$t z{_JQp5-M;EQ+FRPY#%M_Q2aiRXC@70G>fXpvv$S8xNOK3qd!useZnTx0q-FG6X2{b zPW8owVI&kpO$WzaXNwSS#qP}kW%30&vQg8zxtdCAflMbTHp6}}3l87k|$6JvGRg#Cs!8#_isTC=uN_gVSI?NcX3r+BWp zVi?s&D%y!}t}N$SYEZIIa;?!nN2S`{&noVBv)m5l8wJDly#bawuQrr0b_Y2kp>m^g z@H}b6^cC5`t=d#N?}uEm6X1%P&(P14DA=UG65!k=|CPh0U6Tr$2i*xj!{{q^W&j%$ zG0t7u-xR4X&)=7m9w*)@3>7u1CNYgpCx#MPbNj{jXN!yV4gIB=-+I3*2V$h)pIdDZ zGr1=0nISRSh$MzioAD;F_{!r_oO@w4@_ub^Lpc#hWmHe0r>)q@tLjmXF9w^Zd8t#gU1kNc9pByLAhMBvkAdfzwN!TqS6D5S zqME2JcJ{QgiRhI%%I7dPUdh4r%}mj+`<18ab?d%)KeGm^+I}r|27Ft>u{`H28i|ur zgX&+lHl)aR(DI|O$ps9if9|bAx#M{&*au}x?26<}TSh$IAxEK$(j-7&C0&EJeWK+k zMRVEU8HqXmxG~b0!*nnx6roo0{@%Tg=wtYAa~pOu8rh~Gcx(C&`KM~PMo5K?eu)g5 z%Tw`EDsXr-WAZ|#MfOa@ScfTZ0bVx>V9zFzVjA-p6|urZ0}Jg9 z*Q!+CX9DLPc93d!5ew7x)FDw}$5-{Z z+qy%Tid-3W?N%rSIm-qJdNcRD+(;Z|If4pl>I@?Pu$kyXiCS>xzQ62v;szu7hpvlG zI-1p~N~eQd3}31!h}DnAitOG`-S5Xw+&f~Y0ba(vny5bZvnVqVbIlO!r^|K{OMAr~ zpr<^2Z`I>186j~2BA`eO9%HxPNp&=ttOI{!Ez9?n0AIxId~Mie{f}K(=dxd9&;+vn z`Z#F{9z|45C`85#?{yCz-8fq=hF=P$KUQV{{%>i+kYWz>Z3gUZ{6gVhSbpKS{o`P(>3l~$DT6^LZC!!jBjg>D{1g2p zN-fr)O75u5o`)kJ`qBp0kem~eqp-&#vRiA=<3PG*8M8@Aib{T4RnzSTq2R%Uc`HjH zDqepOS$6usY-_CQ^qw}61)6}@@=D*?cQo9AyaR$a2)ixv#`SMXhXsddUows#00hs7 z68bNWG{;%L+yZ<%VBS0l;8=KU;!%9!ik1HQd_cgdc;7a0i~SVMh{P@vG~~0xb~kod z{WUBWSkBN|ksD2=GShP)EgJsM<5eK)h0iRzVAqBbjh%aUEUv6)IqLMvUL1T<2}U^$ zs3h^IxL59sG*(RN(NrwLqiWnF1AIg9BC1q9_*bl;0|Q(RanCNI)v(-Z8&wx#pY5;M z<<J;Os~!@iTYrM5tTpO3K$jXlk_En$(@c70ds6(&wFj$X<*Po-|E{BWS zUX!a{C5xMp>AK`!OnnBu4`r^4^0{TpJ{T3_8UUJa-N%`gaI#OWGXN`kg5PLq#l5Jb zPofh<6<4zo6>rkD3b^+Npx6eNHY-VTiYs2;p+<{df`Xc0$1*L5Oe&*2p5p!LuSf_B zv7Vc|I(>8VXy(u_(gYAQYMiAk7U`mytggicksL z*#;?p(ola`6D_p0CaBt^V7pCgjmkh7`06{z{&R#*=;*l*c;aUD?TBAVINmqxQ9ZEq zvGeLO@Kv z%_>}RG55s-_(Ndufd!}CKQbdxoNM|vA+|xXOAW4{kgassBtD5KVS=Lrb0fbOxoc~= zV9D`8eP$S&20C1XL|{D?p;ANdUD(P8y$F$CiNy>iW+K|-ZP_gR1bh0e+>W0@t`VC1 zvUAw9VK@H7KB&j%U}R6WgcM!fqoK@cd`gpPK9a19uUQd zp5C1aa!Xm488Mt8_fPvP)Yne!temM96iBt2+MJb<*C0)4g&;_e>oU#e=FWL#^xYRk zcA9uM&NIm@uZn>(z4(p1fXM=b3`jL9rIazxNJsW2LB*gt5~9MF8F z=vV9xfPOV|s*x1VNlBoMBUj-irptTGep*>n8lKvC!2OeWIMRV<>9o6MxaZ90mZ2H~ zQ)4rM4smf^K&H?JR)kR(!CH>v7oqhZO();c;?iyw2}*>6kMpXZOPyHV+t$73$9_F1 z-xS~GiE%r5ionJB{FY9V)!NvW%yQ{xC*nyY6#A=#kef1;0@JpU}3v+bW z)mFhoWH>zDmO;e8)g#jq&ex8r5v}YYL>G_k)g1;!GrDo>(LH)qEu4s&P{THH3e0i< z#(Tp^d-0CS3X&e538FFeRkmaivp@*SbP=C`FK$m%NwKr5>e~Uvk!Pi}3>REcy+jt# zsbmAz%p|H0Z_`-$L^>huE$y>gZ+_|xGd^7T$twbn!|F28OXP&o3V#g8=69iCdJL(| zMH9{#!TCK~S*2Wo;7jZ__2Yk=p*p~cu^N_lt*jkZ6e6Gx|F-Vefl>>jOde$X33)Nb zfrd{MjX|gHQyGao{SoLkl?m3O^)sP^HqO%nY2|Vs)g$ASei%7hI6lHLwihczw)+GG z6@>M=^c+Loi#&}E+cs)2IKM{3(9dV06LG<5c$h4|QB?YHo)KPQlMlTVGY7zlFDgn6 zu6epu><+s9cIm01vmMa0d1!xq(p*q&mq+{dc#1ms@Ao4vR}cALWTuy3l<8S%%)qTs zuOZKPh2BRQ8^4}3KhBvtNY}D*4x~&tbxKo7@QdHsMnQrtJ*#*NI#7Mh<*#Ky*#|ZT zS)ivV81~DlK77pO3Rz$awM zh;9(ZrFgxrWim&|RXE$Zf=;Lh=;~Wr;Dft#^-Ji;%hna%; z^~sSpA;~ONg8Ml9!-9)D|M!GM;suIQ*w31HCS!ekb(XZo%U;g2v`!s2p_s>CSLh-I zrU7GV@|EUZ-#Uy3EmDX}tf zUPDe%pSCt?e_F=dH;S&ElTTtwr&vBTn0e@Mh&6-Ip9EUN(*B`0VTfp+gQ(pj_;-RF(5v9h)!PHImNFDQIyIGU%zkc+F*j@RXie1> z=<79=eJj3TZ&k_G#)CnENQ01{b)xP6t71&UotVHopiUsG7Y~Y0AM@rnhE>I66lK(0 znn1>gvu-lrSb(O+gB6Bm72n6reoA2Z$Ivj+o6Y|lb?R(U$MpC9V+jc;1|g7x`=eO* z5da1BHcD~QXTNyoyNL`jh5jK;wdO8}L)07FSg6y+zHg{peDe*XgZX1jnm9z$=R~fW z<@MjPUR`dNv@6fPBinLOp`MXhq=MUOh}V0#wR<&hk(y=El8-D<90T~k=Nh%@14=jo z;B(OMr2lVr^M7{!kxL8|8;*cK6?loA7*KhRrhyFhb}RP!{>%CnJ_xSJr~aD6rYL?} z6ai|S_g6whpeQF)s=FBDXQ*yTIP|g9T?f$)23#Tcp_#zwY&IdjN;n%EFOzvL$K_yF zVMP0LaXca=SKgIiR!!16RrN15cMD1h**uxl6ShYd@MI}jMZ$K%N~;9gX2{Gp3V<03 zN58gfz&8>?*v#aZlsaBy=!)}@CK`EL?xu|!RX6WHLm(2Dqf6x`{i}Ji1!MQNtCtre zyqPo9T;ig3K@(sQkO~Aq^ZUrThvX+tGgeBnXFsQ zQjb2o7ty&(O*6x}4>%4|ZtV)z|X@Z|nFr)g!Jh=-z*FtB?77^Mhhhk#|NV zK0F(7x-5S)pOTZoztSztkqZfK+=X^Acln=95~WW>?Cd_hBNhrzM0_3rZ?IH&f#YYE zL>u}*hFaQQ4+9~v)7jaFLvMmZFs-j{-+MQnk}BHVU&^ZwK`hn_{GyR21d-eaK+ZiN zHkjqY(9k2Kmw(8zt@&IZY(SqM`XxXsq4M%=|GD;?dpI=Lww?Q%|t;IQ+O*Z9Un38M6~* zg42@?i`7=)sRE)M_~WpfW=ZNW^oh=&HzIX(^&iKYBH0KNh+=P~dm>Jg&PK~K*@IX5 zEfY%eD~PP-SM4ZdiGaP_G}9mVnz+ie^RRgDkddTUBx%chgMRH*CV1|fDvVqEuxOLb zr=?p=xf#8c1i8~P1@Ba*e5d;wM?^t9m~h;t`TX`FW+h-`*IcYJ z)rGnuri5j30htt^9wCFQ6|%w`N7%pKRq#U4%mPQR9eqY_r!`dq5r?k}sFIs0Y|Jm^ zOEb{kTUg@jp&mL9Is#}l9QK+1d&nS*?LVg5QKyboNDxG1!|hT|3GbEan4l_C-#Dp?h~*{KfoQ3bW#go5m)$ z==yREZA(OPJ?c~p;#Fw>O>drB-LVw^%zyvaQ!46I6FfgQdK4h7D(R4Qv@o9Y$of72fqvx$9BVzQ;;PQ{?$_JN4jRgx8ogK~cyzb=&(Wdb9$8SfBats`}m9sn`+;Y`F zIXO$X?l_~q?B!p%Yuv1wQB6K_v?+|na5iAffCnm<9}dSRq`}Ydr>-oW+Fr0y^lqe@ zP14weZkB-sZw--OroOV)Vp%jyQ2ES zpt05Lk^%oPJ7L$drBeMhTL6y7a+3O$E#e&9mxcaq+n8PGulaCn;G}*dRNBIKNilV- zhIwP@Ih51!Uu)ougBMFPs?SdxE^CdR@ZSAosHwN*2TW2HGkl*~6~qa!+BsvM+_=|# zhv+rPZ|WK9FLeD#8)-Uec&bAKx6FPI{6uY@j@7wL!&$So=}i5;@)h_hm3?(NI^(hc zUriWaSRGH-QOtP~j8}HLu4HAuc!_u<{yh0hKS$WdgBHve`n-|(+>!uIbWm}2DH%G} z)tQX5hoIt?i*7QK#I2( zka>~@Vw+xp!awu+vvv*n*jG#l^o4~-yoXWxkrrT zLaB(7oxj#GB(GZ!zXQI|ec&o3_S3B!lv}XH53k`ROXpua!)YXm5Beqv#iN<;X>%Ib zVDx*`>a7Yzsjk=Lr^EgyOdHMhP3_+cb3LPtdy5-%9~{5?{@rpy!}3=uof1!|2Lg#7 z=&J9o62dP2m_k~^rP<(*TD&fX>?=Nauc{ZYWhed!&puRT?@h;GaKqSqD`--n`x2rZ z`us0`jR3+qX-!}^DwK#Mf}nMR4Tn6Sq}b*V{D(AF+r}^zT-g`IkIl`n9JE`fh7y`p zFJ3vxfAkfn0vy;Ji60R+t|CPXkJJxIiL^cQ1j5Ls?D%r^uyyU|e_r^1f=m z{Ho7?+$3v8g+*D_*wX+7eOf5 zeuRmC=nTY!mA~rwSC3X0%eC+Ts@(-ollthq65|$q13`_1mM>ZbFI0cc2+b66*M2B+ zt8?AOa}L;<>^94o;&7hhuGjwqH(_9(p2u(vtK3;Sn@@kVn9;srBpH;RCzddnLmxPA z^lXY+1Z9MJ=dSzV5QqQn+Kr3<6mvMdmE&|_JN?P59-f4bPXbwL30#N?gvi?oON>up z?0l`0-X+CDeHW0fmD@)n@Z!MEBHO1hWt}13FNL(Ui9ht(YI5bVkaFN$TjUW@UTSNN zUHmEg{$idk@rCJMR)IxdsV01ey(^FnYqe=>#7vcIMpK!`GY4m_JbgV6XZF>Qtmql` zLZXMNL326fRQ`#oVm%2H;A~sX%)iK`?|*3o@69)>Zz=f*-1~^k|2<2ODpNxvnk7Zo zJ1?kqG4qn2?|UC4dr0{Q(X<$~i>g~UYN>3mq-6!z3B^$z)*s2giX<76DxaahkYcX0 zwyr@zO7!fv(sK-&mYFLjAD}%!6wh;av%!D8oEZlXq9Xi(+d&rv>}7rS{b_hO&L{ko z5aOvQ|MagNk^QNP%V{DXyeyrhy8YjbM0@e`$oMK3>~eZU{KZ7NX{MvuC(1d+n6Pvo z>RnF5kAKii;jVPU7D>ZWhqiC1=;8ym1DvJlx+17|KzAIh>;nBCNElYIV?fqFGf35% zO4cpDAD#s4(rBR#zqk&vN20`^FeU^E2B7Ciab{0KP)&8<_e<*QGxCVi)S|nPnln>= ze{0d(V@y(9jQi@_$Q|dqGI=Y9l1|QeA))_4>tu=}`_{dE@}Q~sg_n+KD>r8P4^drk z;X`Q_R&S2@kMm|ldI8~)!BygI29xi%}+i1xoV!2O@eUyD;#yXCE+a+ ze3-0{1g%FlPE7a|^Ct)h>d&VtLX7k*m6fC;*vY~J%?@(iPS+kG2*1cI2y>{h@O#N> z@^qo;^JIz~7kQ=~wtG^^@L%#vDd`SVVM0pF`e6jgu)9;|`1Y3*epByJ%Al*?mhXOL z^kMe_(*JO$t3Zm_zvmh)CT{Y(h3+d8q*&dmfE36g=>-W*)`fOB_ZN=Jw5uX}y{T1LEx*LHfpdri zT`<3HV#|DY0w%#X)E{c6D8lV|A~i^tY+epWsDek(FX6&9^#0#8JI|^zmo(O+tP`Ah z`GDd>?}pc5l9`FpI;VEUlZyAU_aGL7`@?;Yu;2gq6As0tQ6R2%CWnx0sqx^_+TyYj zzuC-*g=gS=f26sm^Uv|IXf%?b49$G|v!9%&gZ?w}X3>qP_gosLSBTLKEIh5_NPu z>c-$>XlZN6)#>k?G}ym+)S>>I>YTnOrX8hiZ}7DAZEhGjsgCEpSbFZe>22mq;HYzM zBDbqlq=AyP-Tq2dn^s0E+348;pwi?g>H(WvoQ0x6*Y)fubwQ9!gJ~Ag4uVI-sisbT zf59?=yTyeoN7vO|0I=e`ub=V##doM=zrvSr>Z)F4ej`q9%12SW9T-B2F(uU|)8r$u zY?AzDs>}5&Ru{SwR<>%-Rn;5~{EPEBq+HlVU?|?{=4*@lw-L1?3kToNz>$TAvv0C5 z&rDEW)0_~M$HGd1bwsRg2JIxhx1Qk-MLq*9n3p!X=8!?`P>y}QtkAGW`}GA3O}R2V z-ST&D#Ox?Kl$fOJml0~=6h`DM>YEC282#fkJnd8Y)i^AxlpLgDZ? z-FSA!T)h_$OJhXxC4okO4|s!<)KRpm#zY{Uv#x*(p$z91rR{Rc)R%n67W7EY_n;QZ zZIn@3JYgX%To!VhFTtd&jIDmv->lNZe^IYR9Nlhci$md6{B@q)SIT66YHu%`kCD?& zdK?e4T(W+HEu#Z*8doPVib^NKUGS=cB_7+9!G39lu_6Q?B-Sl#DDXVCboyo{(A~xf zmMrY6VTf4}a++C?eZH~r_L6b~EO39_K{nk&z8{ z0s>sE7E^rtmRom0dG9EV%FcQvTfQW3P@zY%8n!7=?bDY;RNc&ftN12shLiG!_fc?+ z1W{|?tES02&H~HY8HyeWFzme(1%ZMTLF~i8%AC3sT|X)IJ^OxhL2`lo@{~DM1@irm zJ4Z)(*CL<;FZvZ@1OKLL#I+^5Z*5H*aK4zRnh|}51ft-V5B4wRm^(}4Oe!=T(Y^oW z((H^t*ALp?=`H6+huAjbnoWLxD&;B1h&AXGPS8jm8_>;|$l$C~fY1GUo*ZpBUY~>@ zLtFicd}_v)_7Hu#`k+x@{%%)xb1U!@0&NF@#1$ebn=I_jh{G`Ym9q1p@NkwCuqi9i zVRIdwQ1o_DJR+yn7?}LKhCqm~LlG@DU1*eK&L=}wy|(TF2fo~(^R*i^*UmM9T4=~0 zgj3t7Ijc8ck#I6KkNNtmilF@G$yCe;*L`wmL{a5ECYkl^53&}scGU|1iumRg6l-7l zk=n%5Jcg4bn>a>M+V8@H!9+ZPfN8|?zw3z--wZDVQaZw2TyqPtxZs%uIfxY#jub12 zyL$jxFTQ}*{5F|SY5+b_@QBm9DoMg~4@8X^EMZh2JhUHAyZWYAn*6cZ)DtyItXZ{! zWIc-N0_pp(cK!Yi8Hi_fbR{sXbPc-e*|d4uV-gQ#9oNs6wv5^H*rlHYbSI13)WO1M zeS7(0bW;!i&%D(CCoZ+PYO#K?3gmAQm7U(y|ExarYqA~L+*=z>N%J16Vjf_|eJ_7n zYWv2%0)%nQ8096g^AbdqGM?VD*ureUa|`wRYL@`ciklz)im}Kp)i_Z0|D*>|u?==difyp}qZzq@JLh|YZy!uAA-y;u>{R`#evGVp@K#db*_-y6+R zbn;fBLQvx8qP!Ub8|rFaJ}IP*m z@95vG)p=Ftv*0?*0@HfOf()%x!C=mckk1kc^$`4w8KwoRRRQxAR!)V=Gl*8e#&_$Q zhDvR-&y9sYmt}0v@QXBtd;(sd9eS5P?QI6tx?(o!4xs6Ti8R#Lu-H@~tLcb4#tx^D ztq_?oJ5ruD9nDG*@3`LnRlhbx?PEEW@CI)h%b7k+X08}ZbW3qPJ?!8P5U+mUJ^0EQ z$nuB`Swg%uPAg%Z5`D74&no>2z>zij4BC}!ek7Q6@7!RtQ{v{t2w(W$;YUN0T;rSj z^_836q3Y(sLZ`CE{QCI#+q8C=rwf=T+RQOWzOakjjA_^&Xdq?HeqH)pzp}ZLp|h61 z;s5*V*p-9Vj!=Nm4+8uj8_;;7PbM{`4UOQd65Qn%x_*lP(tbSxY*G3BW4=EtQrP}$RHu^A4Ck7#2#F}l(9-FXiP)IAo9+N2(AQ;88pH((%qGGz*e(;II z3G}bV$@%@b;T7%9ziUNjWe?kkvKxn0Mm$kx8jtFh!XrZ;fDsh~{08UJDsG10?I{W} zl0%Fnt7~JuSrh(G9q-tj2^V&0$L!d)opfy5wmP=mS8Vka+ji2it&VNmb~3r2d8g{F znwoF>C+zcBYaK^sX8s39IHWy6!v62ZmvaH%B;F@wpPMUhdTL3N?+0j1Fm}>a2N$p| zCHuMDC^Q%8S`2QrFqt@MdNQA*F`^Wl1)gCfdyd)9CfLIO6(l=|DpzfKmx^Y!{CF6w1KJ4~U35LDVzD*>GiXf)50Xh9~2@tUIY5+rEr2x$>vO7+sc#Ck< z_3wwGg_K%wp`H)5;JSz})C{ArlwAC}rpYMhf+`t~zi-ru<34;vQer(B2Kz2G*bgVl zWF;PDmEYk=d{RBwH0ZrFMxKn*;V6!o3w;pJo~*+4vJn5}(E&DQCiO9|e_F}wJIg^; zm@Mne>j8{|(Gy716cMn)r!GbM7<78BB6YL{`3(Wm8u9qPEU>_xc5>|?Q}!Vi(Lafl zL@@`{LKuhGP%lZB(kLJcBgeVtqYz$v6duyF0z)n#z2*6hUy1aeG+in2L4ip8#VXa} z+fb;J_nN44eQbsCzpPVZU{ycMSb+Ono#e8^x`4-bQ3O?Oq(hcHBdD6jjzZ;NKE&|a z`qXq))e**sAN0n#OSyMG0EIFbMB6_%WH5)Pz6K)~wXFnA*>^GQ2gi<0c2Tvj^?y`j zt83^@_d@s!5}%G37V1J7J+~mQ+P6R4(oy56B-Xy)5i=IozsIjX#B!R}3}nr8Qc_(! z046k*(9A~i{{7YaXG(7-PT{CQcngKt)0O+8FThwpdL&h*JyOpaW6HnN3|Jkq)5+5Nfa9)<^om(PBlSaR z+)v{3(lb^#JJb$%oRaH{VNZh&+p@~D+G#Sh<2;8g1~t7Q6+mxJNbKrHliDG)bL?SW zr0nfMlrKb~3bH8iwH|I71_@G_7NHq%$6Y$svuu5z*m`BN08yu%d`Etak~8B{LGv+} z`l_FSQo&*MOkR{ZX^7=(QbZPRu|mv+b2osxSUEvX!X1#6er8_u(>KiXLD++C12}JR zAyHvr2Mi~df3%p!&Z-?j1~xhHETbxyPCk;fLCzJgp~s?P|aI zqCK&Ui}6}4gHMp(2+?O?$v@F_iN60p&6$KXIkyu#f`;){fpb?CQy;Lt$g)InZgUbl zLQZfY9{^NGg9XpcLyQqj8SEya9W)%;scB&}$kr?UQeV}TdFY?(^V1yWFkfL&qVY{k zD>P6DE|#--D1kWZ-p&fRZ(kv7v#>zRTDvqBj_vqWmYLPMgh}+WE#bHPP>Z{y&UwkP zQKpUBh_&1Uetx8U$mvV7RqUt=Z?b`P)sr(y=@^g44QSwfWc+x4|Bm&lM~ zL;QPqU`X-gq_HJ1zMWEI=dd}YW3~RS^K$v2=a9UQ`O}k?Aa&FrzJm!@zrZq&jGmdr z1+tY7Ah@%7V79cZnN*8CHBVuiBUIEZhGRqPV!&Rcheby<>O8N1N{()QCAtVHAY|Y- z*a;X|^HL%YQEdxxAW5A4B`K{0m|aB{XJ?=@N^(hE^#LRR|fVMkV~ zak(iW7|+ly7MDE%tokV*;%S;9_aJz9=}FC$9M1bqAR;*fZ; zd9?t2)uDX~@=UOtF0}USZh-*%hY4Wb)mq1Ifea!jmZM3yXLE$3dfO)%r8aT1o}s;6 z5@AX`LS zf{WMzml=#PBjT^25z(YFxAviZ3vG?ZCJxCp)~m#Sccf_xd(PNKVlAycfA#^nEIC;{ zEO2TyliblQw`y0?DYuT-q0cYS-jq2K%c3RJvrI+%OcpIOOz31G!&_n2(hH(R2HzH4B3pugDeW}XNgI)8TSM_G@0HVf=1;bu3X*Vp_?$dm=#G{vMgv~1MD znKtQsb3O|z8%#QLBVF7>`oDmkCU0Ta5j=~^t)FG~K%G*aIc!S;%@=@awkoh+_{Xf3RMyLr$D4(=%wk zyPkpG#u_UmU2bB&6C4hry~(9Di>Q}KneXIuFTG>iSn^?)3$D{Pt+N0FOOikYR(Wpr z!MDAFHniue3(JCqPla7gw~^I1D`zzau_MJZc+<8e+a&A6D|*tS!ASy&GFQ0VL7ERJ z-tJDPEBaR=yP0MeBHoG(?TblkL!ye0fbIT`;(2V=XZx+aXWX)xOY4G^ZAyd&^LlNAE>w8|9&gGMN` zl8|0aK$z8yI~TuAkFZ*s^QpofvWCf;y{|mKo@c)?@aR+qln3X$Q>8n8i;h?w3TQk& zLQ#A*BU`&~7hdpArhL)B*Hn;~UqeKf(ICbe~jDS{jt$A!o;UI z-=ux?BLwt5z9!TX5UFASPiftK6oTz+tNc2TpPx8bQAit*(L3s2dyO=(A> z_#)9Eo4d6*mdU>!+Sd3vP4b-Nca1`0U;yAo$k4paAg) zp+X(Z=s_t98WRxrSx++>EyDG`bxjK*tQAsKq3jF)QwU#2)yG_Q07<31sgAE-*R@g8 z{x!djjY@AM1Cj+&8o$p(zk;X2JQoBJ{fF=C^#6o;yZJu}+VnyhCn5~l;!k9w9J*dw zNY@P656J(>zQG6!_7vKL`t!x8$2Z6ZtReD2> zCz?&Y?%kYp_aLiF&rj0q94Qc;gjD`&qrr$qm;Htdu87%VFqM@1!>NkQaPKkT{{UN& zg6F?Ft=ojBQ;yvepR9=NLOKuWlkSOk$X6Ou$_&h5@dkN9cLS%S7i0O-*qU-O8^o8-mSW?~geE!-A);{(g`4H~QC)Zp4nM<}0MlY=>?O zhvW9Bwd4NL2ZyhIs-PXAVo6lAc8-lp3prnJ7n!M6hy^U?e}+ZINUV-#e*tXXH?IfB z3zkpn)nL&r@7|-uogEwd@u;CNQE9;(4q(`0Zn_mO^A52Z0EWglp%iSDs%rVwFNUGH86M)wFldLTvHa$?Kuyw zXKrVf5q|cKYY1~Dp|61uvH?)He~N^;3JmM@W;xD}f65>vc(hNb2(l)7iQ{QcZS7Ew z`zv9B8EDWt(bgk-IZv@{q$n>Qk%{XyvQ47$qMORoiYR*{3ZRfr8L_Ceq61Y>0Qt>Z zNX9Vy|FA~GPlh9(=9Q@zeqXB7e$j0f>D$9X{ni?hTr-N8)k-4MvPlqD8V3y09kYof zM{1k1UtR6DuOO|-lMIRqc&hQu`0Uslj#yPUQLUY&n0{u(0ESCzpX?l=91t<_PquD* z{sD%Wd%jC)UrGE)oO6!YuBA_e^+>75lKE>41hlQM>H<-|VLD2TEbBT``%uOUdUS&% zUETa%mOe;KxNIJyCn;Pyae(;5HHVYa(}vJ}?+bx>C$Hu;Bm~pB?^SJTTs_TpMbmm$ z(3*$i8>0PI?*%W{QsSD27PxEETI!r)FQgZ7+2c=XJf-Ad_HMfd8{CKKamGBrcf?PF|C z!5tv9g(-U_cCNOI0P%`&Ep`D7ahI*WVhMZ4Dmt|v!TRo~+~Bs6f&=qI$^(qC{sp7Zq$87D+j&Yh}Ui}}fJRVR7PC%*jI;##{_N%4aE4=jiZ zT-Ro@0IuPKS%CK!llz5PF0>v`RfY13sBC~! z>wJnmG)jYqH-=V2riqin#n7?p`ttc?HE*ur>i&sU7^{{0dbEpld&&Kbs{)35_7ye) zXBjb=Um5;-0J-Q)PaS`@fddAa2%ostwa6^uzr3J^DY~84vqQQbfi(}G6_LT}fQo6g zr2VoaIyw@Q3vQj|B>uX>*Paf1Ce9Rd7ajho-(f%ArfAo3*pDPMWIMjlR4!8zF4o8% z$JE{+pCrmbm!Y^cCgWfcxgvkmz^eMFeM2h@Ffs^cz)j$?3ytS4-JnCF zZlr5WJ%UiPTnm5Cgv*w{m3*>uHNuUM!wQPJ#D}~e`98faGSZ9xoCZuI99m+#?yFIf zIQ?}6AX5_DboGqgtNZAql;$IWus~30pj_dpDeW~q^rPs6d7u@k2zHqfUcbZGZ2sr8 zm)9?TJ!f_Afc|xnnW#OT?x13V5vS#n=BYH?$6|>IJsP~B@A$_&%F3qsj&Lr0tRSoS z7nKFf>*?W?LOyj>mx3|?3&PN*qY6^=^EGa%LwyB zeLjdPuEd$mH*`&U$*-n3PXycgpI9{{SCDdPo;Lx$M`SiC^cDRs-H8r|X)ShNkRH&U zip2s|VhKZRdV`-p(}TY*lza(ON^tniJt~}cX(2f|zhz_G*&wBWAiBTEp5$svF>j)+ zcnIoi*_NWsv~cp4a=t>a*XGCxI}|7k|4?$2iPpD?xsiVmD;L0H>y_pzBKV@|aK`^J zY{@UdA^n?7ri>P9A}^^$EufFch73^h4)H|}i?rjD){@BpRUOHeq>ipliO=6}-4~>z z)FL9|-yDIS0;LQDc2vcZ5d5WW3-vXU%a1{_^$vI2f;})oY~@TC95gM{a(fzJLxKX0 z>_H&U1XTbfrH{R@@;t`$=F>VZ{)|OQNK=fC&DGr>#DB3~#@g<`I>MqQmjfu5Zo{+r zf5sXUn1S$4MT_*~G{th+5caf)r0XbkpFS`oBSpj7)rK$L9vMP7stVQCL#+<{VY2;&EgZK|v-4X(Cmr z1cMDnIi;Rfmx`WUoYz~6+(Ofc;P@{oI{I(~dJoc{_`yktI5!wNyA%)-pX;E#RHSQZZ*l=+z^yT^j z0R4_it$SRAVFKv}l4Kow%Axkpw!Otn_BHnX-BiEc%y&N;c)K^VCr&WBao(CWuie9> zrCtK$|37$NJ$-)Y=t!xq%?^G={HDJ-cKzD^?(~iBuZ5+zKmQ->zUZ9YpfurcxDXCU zB7ncG$G9zkJ3?AS`w&j0Q^_lNQ|cj@rZqg56>dGTHV4%KqFQ!>pvVEbzgIcamiE%V z_)8Vd5~`rgV4Nr^oO&Lilxho(EbskMjIw2Ul@I~?yU$@I45TAJSW-i5EBQ1&&9V8o z*AeVmoZ@D>rkNs=X}IMhgilQ#BjjXR2Mkcl{lM6ot{=B+m>;m?IAJHl@aRem*-$j< zdtYu^dfew$zAFg)%h_nEK)`Ij6F<{XgV%1|r%{_BKOdPwm0adq&bo^cq@H@v;<)CV zTvA$NCpgl`5Vqt_zxpE*^T+@4~F^qqinfE;%n~dibGg{eWMsfX!>XUc$Vn zke^)fYz%)B)>P55mT35l-wPPYfUTRgGG(dSG~n`V&)5r*Isk3$7or1>K{&jWH7*%1zm1YO;^?LH8{v7lIG z!R#$jB9@1~X7C9aaUnocS=wQL<9q1??ELrZ=@_U7jLTu%JO^#nwE{E{m2uRMz5Pjn z2)sutw2Bx<&lx|m8jV2;`4BeUI{|(pg>Sozm;()NhK;w_@0;4Ms8w2AT(PNpY^i*c zY+?0JAho79s%8}GIKP+DuE*YF6Xp@i-r=H&mz1>!rddsxP>yZ#$155XXs2}F^Vh$o zH8C?9Jq{r+I+Y2+R)DG|v7X?vzyi|7odN2W`10?H3;2x3hd6; zdoeKtG__{Bgh1=G(absuRWU-o0b@6gS5&!S zeO#-wD;I(FRgCePZ+!R~N}@MEqiIRK3TS^OL1egDq$$5rv_SQZ`OHFrn2}NmE$|HU z>}M*mbzSO8fWs<|0!d%&rQp-6H2`CZVgj z?AQdV60b&!eA@0@6))~Y+wc_|$@OBXc!%_3ONRHb0Nxv};=(ufV;Iw(GW(OAB2@D> zduTE^XLxZL{PrOuY_XK7&-9&vmrKlkB+U$Wsqe~$pJ%xjdjU;JQGOAUBh=>LHg_IW zN7b_S00!r%_F&x&u=k#yGZhoXbXetA50}+3av~nNe`uM=9Ij}_>Q>?l?6h4j5*pQ! zRC(Ex0j8U-Ohpdo@3IOd+*yycZmabVy105#a2(zWm>X{zx2tMgZr<*D==O!29Y48` z6hf# zUDTCdT7SRUL6$rf@nOZdX4WE?s>SQEC$`L4Xc04^F|xO80_93M{VO>(@u3ggYl%3! z?=#G=|GRP8A2Hes$y5QGT1mS}ZrDsqb^Bi>%9wJX*^}bim>jGo*sDck77jb?0#UmS zFa_g>;8I^v#JMirGQCs{L%u*Uu}W79u1t|#HtK2SdKM+TnjSe|Kol@C`Q!^H>ubpQ zuF$X=;vrZdO(BcUu=DiU;!8>k3f*|b${Qadl?{hl5F-e+ICm1+|Me=UmXoy=4{#}^`TrTk@-9w3ws~bWheb|}L-%pcnSW_4l6ODx7 zgCUt)KquA944nWAoy567w5&U&2*JtFiTet~ohg|q26niFU|VH@%HD~DR-NnuxB`5ibVx*aQH0FFdnabrC9=afgsSW`GgfXg?u+D9prkzqn%y^y$Z!b`8_1* zmJ@C}`Gl}qOu^I+L}hF{gjoeldjO8_I7Izh+q#1TQXTR4?GXZ$gKJROP(OusgJ@J} z912}0E_-jO(~O8vkU)t-e4BPq;aY=581tsnsnDHUofgSB6>wT;KHMzo^m*4jP}dJw zUt6LD7z^UYkM~$#-}&y&%=8x*A#V^NS$X|```nF}b_~3G!)2FFtyuz8aqi3Q%Ex;T za+8#kj%s_6>^T_nXu&;!2K&_4_xKWEGD5~CFQfWlJf^42H-=^HNMsN=6d$cA_}~6W z_{EOq$NSM z(k%_hoaM$OI$ET*smK5pgIClSQD({bLXQ@>2+>g{{9GIKh$K(QZ3I1kX|W>^7cA!| zw)Fv`yr0idxlvjKTC-}s@wA6ltR z!v3FbefDWQ8cDk}X9GW|$U84@m94p}lS?Jmq>--L19rbhh6Z#w(CMcG6%sAK>_dN+ zkJ+9!uq-&fwCFdWcm^XfHg3MG6?~*HY6to4b$4iITS#VjUvrmi1^tjGx_C^lnGP^n zH2kY#yXX%SfD|XZ>;JFhnlj?@EMP3D`klsOGN!5hd1Ea21Drlt?dp2}?}%dOUwy?%5XD7vlfDCveWyZ+9VC2!zVsqC z+N*gqog)}$E$yo_rJv5%UnI$$|BpB$ldkEOywPQV=T3 z($vj-)2l9S#4ZGs^PPyrt1uw=jE*fK>H-NY`JuUc#VNMqx*X8Qa3fpo(m4Ei6{Wsx zA5~TQ#&)t~4g!zXEZ+vn&Dm~1N<-ud&JRhmhR{?!(3yPtVZ`x&hSZpH7OxFtdube( zL%zb+tEpfFl}L-f`}N3@7ilPONxO9);KbKrU*L$RLxh&}SO7H7Ui-Mj;I02#Q4PMb z{H>^dzW7g3P0xyf>)+OFeu$hJ5$gUgL ztgvdYHFyMg<`)8dc#!s|8@R2Z{aop!t#d_LScLcHmN19cGL=OCgr#u$_k<3^{`|I8 zQ1=xC2N(xev&3lEj)W~&p6~v4y}K9Ra5}yBsp62<+)R-lz2{W7do*t_H&tmC)a6zk zX1zjrGtEpnVJuyMl{>swjD z<*DtW^~ClAYyim!Bw|TGj!bin_2IkOE#{!GbHcJC-$yLjMKTpBU84?6BK>-}C7z1J z*%%)uS_&FhTmvi6b9Uh{j z1A4f&-C#}6lby4r+^*H5I;7RbuBZ)F5WeIqT6;9ry$k>OKB({P&p*c$)_PATkKfJB z?Rx6F2#~zYgPtOXT52?DI5a-iOWUctwDzp94i@1(90<~u)MoG8Mhh?D_+4SllCi-{ zW@NAne_E$^v|^yu?6E2*T`1?qD!(Ey0Fw11OlPkslAC+3>lX@iIWWYqcWg#bT0~fd zgX?lNl#ri(a~}v=>8t5Hu2NE8h-}>>Gkbl7;=3DzEI~LouH3PPSK&e{HMBnvC!Sfl zR2(KtHS%rtS3BPE|CLX**x`|pe%xna)z+gV5vy4E%v z^FAk5GU~F+51t|={#k@SBF_T7gJpHa16D&{R*&GOXzBUenYNo~gt$z%s#Yju8$+MY zB=*yRkjpOo1*Kh}Ut1D0b*FOU>jm7wp=EAeZ*bDFN%MpDuuHbJUOQZk5n< zny1!`h0*)3Df@4Ze*KP`AK%*2D(lS5_qc+F{sgCAbqedfDDDnY*$N5*90ORO3&`C% z35E%PaH2Fd<(AGI2i0Od!In|?w4vc8NYX3DhcUuNOQq1V<`fwviQ<7cwNMlIyvay7 ztu*UD!OdezRWPk4fCozLR*W^Z9*o!W%^RES>F&cTDJOyD`6fp^y=r1rZs^`imEqBbJ@=^P3T@*czO zs)Gr}*bZrg=))a-tR8jJS5(k0Ol6>~SP3~fSo03*419EVf!WQTdZ1`M+)h+ZM>@FV zMQb2KDR@+<$$pXJEZ}9f|C1*zUX`<$OO~j4UT}?`V|)u~hRetCD>Llu#uS@r*7nj4 z)6zvIE?cf*^j1B?T!QxOavFUzhZ57}Q$$`8cx7OLzieBDFStBh?M=>M2s@qQ#3p_I zHmAd|d1(P`iSQXm!s%=826rdK#~7xRhlyKCpd4GgXDv+;1`wFVr>|7be)bYRY*D9v z?(e(UST@Q*cx&6bm8BHR`Y&fQP6p0`__*P#VKt1$Yh`E2_0#v6#oyz>1WWj9+|}aw zkV4^c;~)l-?6dZfR&Kz3a?krX9BdIu#wqCR^?H@5-1W^_o4Vjp)Tn6Hp;$>aMHp8> zH6PF^+n_bEs@J88Mq*Cok3b`;z~|j`oN^8H<-)RXG|o7A74SLSJ~Or{qcV43s~U`4 vqg0uJJ^4iB^71uU+9=m= network.Version13 { + if nv >= network.Version13 { sender, err = st.LookupID(m.From) if err != nil { return xerrors.Errorf("failed to lookup sender %s: %w", m.From, err) diff --git a/chain/rand/rand.go b/chain/rand/rand.go index 427648f2a85..529ba67328c 100644 --- a/chain/rand/rand.go +++ b/chain/rand/rand.go @@ -198,7 +198,9 @@ func (sr *stateRand) extractBeaconEntryForEpoch(ctx context.Context, filecoinEpo return nil, err } - round := sr.beacon.BeaconForEpoch(filecoinEpoch).MaxBeaconRoundForEpoch(filecoinEpoch) + nv := sr.networkVersionGetter(ctx, filecoinEpoch) + + round := sr.beacon.BeaconForEpoch(filecoinEpoch).MaxBeaconRoundForEpoch(nv, filecoinEpoch) for i := 0; i < 20; i++ { cbe := randTs.Blocks()[0].BeaconEntries diff --git a/chain/stmgr/actors.go b/chain/stmgr/actors.go index d824cc2f493..d8d121f02bc 100644 --- a/chain/stmgr/actors.go +++ b/chain/stmgr/actors.go @@ -317,7 +317,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule prev = &types.BeaconEntry{} } - entries, err := beacon.BeaconEntriesForBlock(ctx, bcs, round, ts.Height(), *prev) + entries, err := beacon.BeaconEntriesForBlock(ctx, bcs, sm.GetNetworkVersion(ctx, round), round, ts.Height(), *prev) if err != nil { return nil, err } diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 8a6c333c92a..5c1495f6693 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -8,8 +8,6 @@ * [Auth](#Auth) * [AuthNew](#AuthNew) * [AuthVerify](#AuthVerify) -* [Beacon](#Beacon) - * [BeaconGetEntry](#BeaconGetEntry) * [Chain](#Chain) * [ChainBlockstoreInfo](#ChainBlockstoreInfo) * [ChainCheckBlockstore](#ChainCheckBlockstore) @@ -175,6 +173,7 @@ * [StateDecodeParams](#StateDecodeParams) * [StateEncodeParams](#StateEncodeParams) * [StateGetActor](#StateGetActor) + * [StateGetBeaconEntry](#StateGetBeaconEntry) * [StateGetRandomnessFromBeacon](#StateGetRandomnessFromBeacon) * [StateGetRandomnessFromTickets](#StateGetRandomnessFromTickets) * [StateListActors](#StateListActors) @@ -340,33 +339,6 @@ Response: ] ``` -## Beacon -The Beacon method group contains methods for interacting with the random beacon (DRAND) - - -### BeaconGetEntry -BeaconGetEntry returns the beacon entry for the given filecoin epoch. If -the entry has not yet been produced, the call will block until the entry -becomes available - - -Perms: read - -Inputs: -```json -[ - 10101 -] -``` - -Response: -```json -{ - "Round": 42, - "Data": "Ynl0ZSBhcnJheQ==" -} -``` - ## Chain The Chain method group contains methods for interacting with the blockchain, but that do not require any form of state computation. @@ -5641,6 +5613,29 @@ Response: } ``` +### StateGetBeaconEntry +StateGetBeaconEntry returns the beacon entry for the given filecoin epoch. If +the entry has not yet been produced, the call will block until the entry +becomes available + + +Perms: read + +Inputs: +```json +[ + 10101 +] +``` + +Response: +```json +{ + "Round": 42, + "Data": "Ynl0ZSBhcnJheQ==" +} +``` + ### StateGetRandomnessFromBeacon StateGetRandomnessFromBeacon is used to sample the beacon for randomness. diff --git a/miner/miner.go b/miner/miner.go index d1f6fa2fe7d..6fbf159bf7e 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -260,7 +260,7 @@ minerLoop: } // just wait for the beacon entry to become available before we select our final mining base - _, err = m.api.BeaconGetEntry(ctx, prebase.TipSet.Height()+prebase.NullRounds+1) + _, err = m.api.StateGetBeaconEntry(ctx, prebase.TipSet.Height()+prebase.NullRounds+1) if err != nil { log.Errorf("failed getting beacon entry: %s", err) if !m.niceSleep(time.Second) { diff --git a/node/impl/full.go b/node/impl/full.go index a6f61c305ef..b66e647a1d4 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -35,7 +35,6 @@ type FullNodeAPI struct { full.MsigAPI full.WalletAPI full.SyncAPI - full.BeaconAPI DS dtypes.MetadataDS NetworkName dtypes.NetworkName diff --git a/node/impl/full/beacon.go b/node/impl/full/beacon.go deleted file mode 100644 index bc7232c272d..00000000000 --- a/node/impl/full/beacon.go +++ /dev/null @@ -1,36 +0,0 @@ -package full - -import ( - "context" - "fmt" - - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/beacon" - "github.com/filecoin-project/lotus/chain/types" - "go.uber.org/fx" -) - -type BeaconAPI struct { - fx.In - - Beacon beacon.Schedule -} - -func (a *BeaconAPI) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) { - b := a.Beacon.BeaconForEpoch(epoch) - rr := b.MaxBeaconRoundForEpoch(epoch) - e := b.Entry(ctx, rr) - - select { - case be, ok := <-e: - if !ok { - return nil, fmt.Errorf("beacon get returned no value") - } - if be.Err != nil { - return nil, be.Err - } - return &be.Entry, nil - case <-ctx.Done(): - return nil, ctx.Err() - } -} diff --git a/node/impl/full/state.go b/node/impl/full/state.go index 756d74e10ca..5247821a251 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "strconv" "github.com/libp2p/go-libp2p-core/peer" @@ -1457,3 +1458,22 @@ func (a *StateAPI) StateGetRandomnessFromBeacon(ctx context.Context, personaliza return a.StateManager.GetRandomnessFromBeacon(ctx, personalization, randEpoch, entropy, tsk) } + +func (a *StateAPI) StateGetBeaconEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) { + b := a.Beacon.BeaconForEpoch(epoch) + rr := b.MaxBeaconRoundForEpoch(a.StateManager.GetNetworkVersion(ctx, epoch), epoch) + e := b.Entry(ctx, rr) + + select { + case be, ok := <-e: + if !ok { + return nil, fmt.Errorf("beacon get returned no value") + } + if be.Err != nil { + return nil, be.Err + } + return &be.Entry, nil + case <-ctx.Done(): + return nil, ctx.Err() + } +}