From d1061beacabb2629e46e5e199ce6c70d76633c81 Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Tue, 5 Nov 2024 11:24:18 +0100 Subject: [PATCH 1/2] feat: query identity on-chain --- .papi/descriptors/.gitignore | 3 ++ .papi/descriptors/package.json | 24 +++++++++ .papi/metadata/polkadot_people.scale | Bin 0 -> 170296 bytes .papi/polkadot-api.json | 10 ++++ package.json | 4 +- pnpm-lock.yaml | 12 +++++ src/chain.state.ts | 2 +- src/identity.state.ts | 78 +++++++++++++++++++++++++++ src/utils/localStorageSubject.ts | 52 ++++++++++++++++++ whitelist.ts | 5 ++ 10 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 .papi/descriptors/.gitignore create mode 100644 .papi/descriptors/package.json create mode 100644 .papi/metadata/polkadot_people.scale create mode 100644 .papi/polkadot-api.json create mode 100644 src/identity.state.ts create mode 100644 src/utils/localStorageSubject.ts create mode 100644 whitelist.ts diff --git a/.papi/descriptors/.gitignore b/.papi/descriptors/.gitignore new file mode 100644 index 0000000..46d96ea --- /dev/null +++ b/.papi/descriptors/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!package.json \ No newline at end of file diff --git a/.papi/descriptors/package.json b/.papi/descriptors/package.json new file mode 100644 index 0000000..5b6b71f --- /dev/null +++ b/.papi/descriptors/package.json @@ -0,0 +1,24 @@ +{ + "version": "0.1.0-autogenerated.10165647742034513517", + "name": "@polkadot-api/descriptors", + "files": [ + "dist" + ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "module": "./dist/index.mjs", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + }, + "./package.json": "./package.json" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "browser": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "sideEffects": false, + "peerDependencies": { + "polkadot-api": "*" + } +} diff --git a/.papi/metadata/polkadot_people.scale b/.papi/metadata/polkadot_people.scale new file mode 100644 index 0000000000000000000000000000000000000000..7f58fb01e2b746ad22e630fa85daaf00c32b6f38 GIT binary patch literal 170296 zcmeFae`sXabvSNSpYON-?2g{M@BTRV+;h%7KYJqLA6$O`%2Q##(e?vTZ3lyX z@3jT1=!Yvj;%pKo*`$XrDoi#2Hr@8UFz$&UtT6M2IJk<#1Doy#{-I+JKdy)I z!GY6ugcs%8S8N{fNtPWBpaL*40h8s$K6hOaHCo)|UR#8d(V#EFY+GaMihReaP+^sW zK!_^S&w!bM2t{xx?CitpLEyh4yzHaN1DAKgDOOuOjskuS{{W~0OgsQnC(I(()PO3h z#1}8k1DF640Mq3;1>(5h_k+l^ov_cNcK7nO2v*eZt1b^i!`NjtD6^{P2R-iAn6V42 z?)OE&Bggmjlj$D!Y##Z+fLcJUTnqb+BjI$qQ8+FCZya8#zC=#|O1SoeM&$HFot5K{ z%mJ(Q1K&Srgw8Aa5!3Hly)2`Z1M}$#zh5iFDSjF`_;bpe?qG&J5r|XgEEdg8xD6GKBDZSLv_P{1< z+kv}Y{T}@`CB~{UUWmW{lG36t8CZU zWphwwll?9a#rXo8+{PckCIvR!WyUJ7YUKBwcKC3CRdLa~O8~p2TYcg8UD4?K?j3IX zk=~zKJw5y$*nD+|4!!~Vte>R>3k%d@Q8ixzfW>Vd@OGCwp8n=l_KkMji`_VEsN>n! zO%y>H>4t%+j%jGXC)le)$9kmwgRr(6a4+O-JObN%fB-e%4fZAVWt6^c^yTZ3P9B1l ztG?^vnb{Gppsoz~GAz|>ykxK1=M;GbEt{8&EI%ddgC8M~1aIvoRk z!jjGHsfQyInt{pfz&{=s@N>rcY9@VrGSc)ZFxPG2MKlFgNcwiv!;udz0qmD^%&jU1 zm?XqDkhV@;Mk4Qcq0`=p+ieks2Ak95x#4&R{w+4ENi_0A0OQlko+&s#8B3~T)waZu5(x}8#ieinY<72HA(0fIXmpoNPaK)*J@wEI1kx>Q?s>;` zg?-mf3}b)U%k>Zl-WRrI-Vi+=+(9^0L*dyX7#^Qhx;*U8v8mmKg*6^_VZ!KN_e|fr zKm^AOr~|Xh`+eaF+gjP{cLHvUJ&kK`4E4k2+FjAU(>N3X9$u4GTE6eX zIitJmnX&AI7R!^KETc~-VjlQ`8Fhsz$(^O+z>ble_*M;Th0pHTos{djM+7 zffIFmB68XWL~JqrQ?@9T#FHA+qZSp?1{|g1C>I2Ofg@ zp2rWlTQ62w%_c^S?%(**t5gz%m8Mud+tDk z5*W;05w3r<>3B{r?m4W4Yy$i}ep^d8cK1J^$S0Q35x z`psZ|#W{5F%w8G%kqCUm;o~eE#_b;~&2FIFdPDGbSJ(hBwdHT{0TLX5SIe&samitE zWt2r!n=f+Lu}J{G7JDQ*>_mQmog3fZ?F#cSd2b%524GOkS_sF67xyY`_Xa+{in13$cPs9-a7`#8o-hSu0XU!| zY?Ftke?X+H?Ryb-JYkzOk}0VxjbwV%spXE&Z^a4QJg|ig1>>tYAbqSzGjI6;GC-u1 znxOUrAGxX3T=9>*BOcgF?g(#)wr~z{sgra`t*~k2%OX!h=ZP~+PZOcg@YpAPRQ5*_8Lyk?m_j02vxIM>KGLTm+$S{7W zyG*BZB!bMKW*j9x}Wom@vLh zED1l<1Lzl`Y>B08l|t z8>kCl0G}AS)aDLB$=C&B9oYWVs%ImeE1f7quvxrw>l=EN)pi#al&lXxiyI?cm`6_3 zHACEc{MuCad&^vj!)U_~qf^GK@*Zj$@*}a*b8JKk>G_AkHjlb~n2bQ6^?dKbD|?9u@gopXmWQ&^!?C@>c@cyQH1q6rsJ91GyOOU@V0Hbei&LNv6cf7lu_&8 z_eNx!Qsj?38$0)cv7!5t@}#hZZPgSIcSKZT<)iLsXG+e3JXoL}u;_!7=-Ju_FuCytMSQbJVxXANM zfY;>szzM=AITq@ShobF!wti~;;F{xc*W^Jb#=EcSc(&8#kqD{7%!HD0QDb9GDeS!$ zfIndTfB-Jf6`_qS&w#Many@;Sl!?3Aq3Bo`>FdL<6Ld+Yq6(au}ciCj^p^XZ*9M4|28`Y#)gj%-<|I~pFt ztT~a{<{q-?K!hYTnJ$k+FhdlG9^A{0J#4%+47#M>Vc?nSf@m9KQQ`webBIYO(Z#l^ z>tPtqp!*oiL116-~#)@$j-73L9x`Q({!JE^pAtH#q*Z9pdAyga_Hy z^bHZV@nUe&copNxapT$IZsXaaH8NUtgCz5Nf%zjwbA$#<`Q9@3Jo)Qh`ujDbJJMgQ z`mxl-<6ipv^)d64N`0%k+vOy%oSi02j_EC;UaSq;b;J$a^lN_5rlaG#_K^Hh_QX;C z(WAy!NK(u7AeA%+*bnK9P!#t%!oIs$_xfbspiqqh?nGfV!n<);={aG0PKykZGqFN@SN*^HdNgdVqTd9y-N-IMoQJc@2ix}F0e z>bH`sSf4xcbRKp6=G~$E>9Va9lB3$;QP|WjZ;7LI?=W^f5#U7_HHl94@6WOo(#~hJ zZc6}$yCsgy+=udt5sJuK$v$7kwHgRnx;Ql)dqk!*BB{g6en!-Z;ACxNpWl$2?$izo zMt|8G?M*RBYkNx^t%%SGgngBJHeQl(*(f97vqn34nB4N-!gC<+nYf>-B{B*1xfWF| zgs1AYJ-Fg~w!!Kx-?JN%whkkZVYt|}>Zm<1v2D`Xd@?_RV(C;UPAQRRc!&w(mIQAy zTk~T+UZt(=qmF%SvWU8K z$LaU)g8Ao5d&76W*uztZB6UmT=|r}3)Y7zh915J=z_cCP^!!Nb9PWrg_`N`M@H!Zv z5}T}jL!bBfAfutcLwna-`DX!DS)VV@EApajNI9AU%s{ohwm7jl)u=%_#0r~LZ`M(z z2vB;KAsJDPNc)s%%FQi5!sYQu3be^JLf#+rH`H;RRv&f6n^}zzs*iB*@LFN^=-wN~ z9klM=eX(zr?ID$0Y6HuySaKNDhV+%LXpGjxU{gw60$_Y=*)!K}Y;KR$m2fk3S}san ziHh&;ll}8@P3_5XdyFcuIlUZ3qSucQ8>jp@YWqF$7TYER9m=&~w6JhpJ_azpw0bPs zG3t)#G<)X$)y>>ox$e!X;94uJ>XYXDE6m*R+jPeSR?l4UaxbQoI_YNwlf~N160n+9 zF*!Ix4Jw9&Yj|)}Dp_lLo;dD{b|mZ@BJ86by)XJw_kk?$NkJxjbWw8-=#ZpGPSzt2Yo#NBD3rmJr-kapQC>gWR^AgN zZnCx?yOOoEL>3%bjMPw4I%EWMhb%N`gyfQa_V_W{a8#3jk@SMQ?!eSb!uw~0hf4Y5 zBt}d*W2wosHYBifCg}HqLFY<)?*VRsl2T3b9pbJ@#xXh?uWP8_S;2EVdIZ+gS_GPZ zrMdmREaidn3-4hmnO#H^d`1Yl$!waT*7KOntK4;)zb|)7vQf`1Mxfz!=(CQbvCW#qhPtT;bUmR^GfnHVlB^`rvQbw(j@yi-AuF0kG+f1&RvEjj z%omzdEkUV#lc6CHxk-v`k}-^u6I8h4e#%LsNK7k z&?_5(ixkpL$J=D6IO82La?<;OICT6tbO$JABghb+B+{J@DGQbvabgE?Hkm^$bWp#= z)7?pCVd_bsK_ok}B<_ya*<_jmgh;y z4v$#U_d}HD1~(bq57J%KW`|<8w8n>mp~ocot_WLp0uLEqmwHfYk-2}Q+k={3e2Y4jzO}1*xJoJ}qL&VuLrxSf ztCCMtSZ%-EQy&AXwEZw*j8)YetYDyatd05@rNJNDn z(!JgfBP0#zJcOI(L}sn!2c9|vLfWxsaC=GpgJ!c^JJR1)*tyl)C6?fGUZ7T!%`f`l z(z9e@Puw7qHPID4p<4-s(`q~=+R}BYg%_~Ek2_tHd*9-5dM>XOU&GF_oSoC2T0*2ZPv*eq}1L;)J;~Yb}o!t zVLNchWKH6@I&h|cqz)1HB-?&f@6iaij(pRJEIYfJO{XJ$n{i2*jd`1)woGBYW-%~! zaUcAZt>kMxIXfkJBw&hs(~kr4mO~srK=-T2+Ep9_xvwMconKU@_TCG>KqlyjAf07G z3;vs7IKMiEF`wV{@pt&KXY#UUv*>b*TbCn7+dV#LiH5qxs1{?zu1CtZ?*nf}&}E$5 z^+HbW5{Ynfx-jux#I9|1=p~KVi8y)|l~3kVXXHq~Ml=F>aU}UoAYP6II{Dp|OOYiw z4yDf#etam*uJ54(7*eyx*>XZE(O(!z0m>PgxjA9heWyp=I8kU4L(6ij{oKlL==r_( zwg0;D9D7MkJY6=4(WsCikVr2uB;2^vyD;w1YUbvOz8wmh?|rtDr64M>zNraAB z^A957(R1k;)NM>iXR7SiUP z7X{=DtelAwQKSHN@@`kS0t35}mqnP>zpurv3kK}!zqkBo-8&RPE<`AK~YJOY$L2W@W(Iqi|WO7KplD<8CP6 zH(-97VgeKB{3gt9@t)XpLedpL6*d&5l32tg)E|Rw1cl>uUc!rM;&S{ypuT#HiZs55bxQTGpT0fYf<)8m6xB00jql5;kPpEkDAu zq&DY&!HU}Iort&ZP)G1#fUgW6$y8|62!sCWQ+*y_jHdEfmv<7!55CH#|4{ikhX7w4 z?ri#F`emjWo35;h038rY`xg!P8e3Zq+KV66{rtXp@%9ohDD7V|;0GfwFWp{(0+jZj zHsBveUOs($35rnKpEKZxBQNJ}FM$E2{bvmLmywsx++KnSDD8j5fFF&#{K#z#9W3qt zo&i4|dHH*{m*4>??av$VZzC_~Z!ck_-`4<&3;@0kUmpgMsX=6F0065^C((5Vd_#Ig z1L*ixjO8t{DNjU4esJeoY(;6`w&a6#dkI(xjXr6pFN1j<-h)QMkIdcedl{dgB18)? ztG<3-3@**y?c4GlG5DSu{L<`gDC)Dh?u8L*VGNLHWWeknV1OuhX;udOjS7~XfSP*o zycm>N)fHYR>MGo;U}SK1apzzfV;rt_9g0Di-ge`FV|ZE#!SH=nz2e(wqhggl52C+k zCjPz6g9u8n_y?}v;x2}jP}Haa-(k}UATes;8vy4j@U5)(^mj(Qr@uqq)89F9Z!=x8 z`t+3nt}b-Kp?GYlUKw2TgF7WQo4EV8M4-qXtI3DxF`ivM15*bJVwlbIamafdiZJyO z3bme%F&sDiw%_()0;(^`U+2JFMN7Mgdj^vtU&FE0em?;9D^Aq*9q+0i2q>k0VldWu zxU9#!5@Q&) zyN#S%p@YKw0>TI(E2!x)Fs}tN zBDKWIp5N2YCvB1bRe+V{XhZNY+75i=D~^9!^CGNm`hnQ(a_>y-4S*j26bnRS{t=*9 zq+dT&5yoGKe*q{?(6b)_6wlGG9|II0pkMz6P%P1}pOuG1v@!;jR?s|w5#RsL_R(<( zPjV1b{L3P~T3Q15cYwlwz<&&XU(d8v{jhJ%Y2kzf76USpHo&fuujrlPj>670Vz95& zu3Fww`p{gf0?d*5LmOu+>E*kgnyybUR_Oiz>40Km;`Tl2+Vi*2n5C z;R(!nz=J{d&SAi|_V>>MpggXR3OWL0KV~S=W~~1ch~Y9)y3Fd*uF|;Uc=kGDH5rrl zyyMxx_VK>v1VXK}!J|gc53^y46|@jA0)ETLr}j#0zV0S2E4%7N)G8LQn(DW3X$`8vBy}Qo?LU>2xGWTLXL-FLv=6~ zH%9uoD}sCg=2nlTK9?p?W))Nbk9Ks#y_}kVip?HS z5gMmqa0M>we)SnYxx>3I_Ys(r+oXj35}VUjMGEa6zis;H4KLu=VD?HpNL+eKQeAMK zu}Oj@uvtkr8ZO2ka>nWz@g060=W-Bx_D&r1-8h6vSlkg3f!0X&4-EJj!|Va-lsyXd z9T6>KxU=mX554>is1e%A8^>?rU)<^C@hnS!s*%&aBXZQEs&80I0C)^8??@egOQ<_Y z#t9}%JIRA0f#fi?{2#D}cSo`oBt60ZglPSr`G+x58G{i{`l=d{^(;$$YIGGB@;khWmqrJh^pCv! zNHchnN!=+w9P?3?q9Sthdx}mosth)LTNrHiV@}l2u}+$-{%^T=KVsx;pOk z3NAo>*>!lR_awU}3-=6Fl^H^HDq&)?GChJ67sj5j-vwZ7_?jcPMH_;_fC}2xDAqWc;uc^^aS{V6Y(9+pB3M|^ z3a%p5B}EKTTr%JSW1qi*N=~%bw-@C*d{s9$`EjNxYINqc=bE0x7$QCa@FdIL;b+*$ zC4Pp{Egt_fN|i6c1y@U5lG z0jQ2+0nae@TH5nsJfB%MDm6ERw*)!naJDZda|~lL%O=<)r6E(C2%fp;wU^}5=hKxx zi>Lk~gXdUT>Dz}{D=SZ_R6BSc6w_X2?2XaI>piAMa{VyB8^j()zuNcsX#rsQeOTaX z4x_#@f>2)}d|FSIpSyTfs#{WP0dRQ-9h8LA@syekbEoX!35i1yKmqU$4n=@X+10#F zH?fA0SFyR=#SDGt!C+JBWky1Q7e-KV%vA+WvD+oK>#PVk_MQxTC(y+Fb*E&mAU$*< zk)tdCm6sgXHsB^>)A)<{0g~FACv=-_RVgnM&6-?x-RlSAdCG0Z7O~?jUtv&Nc3sL> zi0TG)6j1qz{ix^Vu`FtAcQUDk>ZS;A`-HiVP9)_-LktK(z!QAR-6~jVde5W#hD>!r z8h%_yY9(L*f|c+rj(Cx=a_PlO1~`l@9$s2lpv+wa^bj@iFFtL+pW&;g^RJ3fdU1|+ zu68)Lu%JFL034=NYL{x1?~CNNdbU?Ephw)&|9@j%HZK{NYcvx8Y z+_10^kLxIr6j;f;>SMSrV&H(WIT|6k-2<4*EmRw}qg-Y`1~5qaouegckD%cmPPU!= zG0PcG{`iCrPqv(VoMj|%GMJR|&+>nf)ufz%cG_QLNU5CG;f}*{rFD*WOX^GN>o?==06EZQk~B)7NyluiS19436I)p?s2;R**2WdBvb!? z(RTB>{tOi~FT zL>b}><79|0pbYUv245W4!>A1LFu>F^dyoS6%y?~II+gu7FyKSo8#uq%~7!djs<)b-!yt=o4^A@X;uysZNJwQmJw zl^+Fg<+93xik`NVGn}+pb29SK_$&t3HCryfBQ7;AJ@b(!#<6vEFo^2g((#G^z}T8H z_DSOtWppxZ?1aW2`B0`g{wKyZ)HKxRq`a*(@k1HwP4NhRyB!CZY6aG1II4U{F`FWa z2BzQVFUP_%(N79}(8YyLAhX$0%h1FyP8B^UdQOA^9y~OuRzldN$arBk)g07}{Ge%p zvB%U?jJ%e)ZgnWO4s6pYY(~E~YjGG;6h2qcU~)b))^w7Cwt~0k|17YNO?PX2Yt270 zdvQC-FhC*dn6obObsk;9&t%`HR8o6op{&0CQddy29>ikRih5D`e&yC>6V5ncCJTt5 zECwnO4O)5v7o#x7K@_J(L6DT);2D-?*SE~|$b2gFUEvO%GOV=+qkofOf=!14bub}?+VbqGEOXf#Br{Nmh}ae02YNAMS7VoqKgQh1!nW4Z zWEZO*9UzG&nH$5e{Dju}yo3HQwm7b^>22N-(i4-;CcYav({q~SsE;sZKSmJ9+ih!pj%S>5Ry5O#~_#as5R>JCZ(VUP9GVL#SI)Ui$NT}6HstK&Dz2U3dUAEO7XN`Vh7pA5bLwG?}^7Kb8C-gJbEKFBL++<{KWJ^}F0EJ=N(>WAdm7O?8& zE0`~c{O&OOK89>dL0_#*v6Yb;8c^C}^eN(>&Y&T}B(0Z@Br;`@4wEn)+sZV&SW^SZ zk^WNh>AK0owIkuWIt>=F8f%^g(veFxFynjUhSo#ca!e@$c)seSnePO>=!i3hP%yrB zdUu#V17pr5l$n;%dI+5t~Ti;UrL#3L5CzYv?Ql|H{~qy&ooweavjG~Z5-oEuwBa+g)=TjGdRRiT5vsJu_*&%Dk^ z_B>N}GV*4cGBYV}e{`~@QYc`&ArlYk?=k_0GVMSo_N>c#>}495yOq=CFpViU`o7~u zKV_`HtN&QcR2R7B2aCH)OK{KgWybfGPoAsruq;793E5i%%KVP0|B~rzVSDnwZ2Bts z#Tc|J7;m1wGA-*{D|$DsV)P4ESEE&4qUCw`UtQ8fPi^jWKUo#pual$CTPK8=mj z3HBKE4EnGNlvuS(HRviV`v&sV9DdHqI!zhXei}VnlXFxiN~6YUlmU!yETcGjEVIVx z4Kdq(5Qui<4(gJ=CHF9^z8wcbmNdZ(@%=auBL{PA24O6scRZl_c)wtjH7f;>X;JIqm-n? zx5zhp{0^oHBBHEhy@MFjR9Q6w3uRuduxVSkC=y}Gt9%Knka=)tX+A1}>VNi(3}ZVxBb^`Uu43jd*oh_m@RE6~(5|X1jp)Ki{=5fN z`lc?)5H*BCT1pK|G3l~ue~3x(aAUy$Ql z+Zg*H>^dEwgd!w$6ao=Z@_cJv4=M|xosggWq%jM|cQRwD9Y0~nP}VW9){@;wQbC+B z>Y_||7Vtn{$mVZQ3bcR+B;Z03xmE&0f;tcHph$|w z0ki}m=Hs?7XhI_g^;Tx(Fm8>^zJkf=MxLI8F%K9&TgH@27xY0(M?_M~Ju`WMq#rR? zC9S3`=hj+gR*KHOFY_uH=TXido|r~yiBG3Y4lA<^&+gE_gV`|N2dJGdJvMH3CmeDO zupq4uBNq^L#rJTxGBB1Y*Aesx>fHL(J8NE5B8(&&7;IV<6pTjL?1RRu%O<*c5)n+A zrF(2$PC8S&cUpH3VVaH;y3_2XzNdyexrR{E#YBN6%`str8Pm!q{o|=ZQjMukWG4N2 z-8U5##jPAyqA2NMxO-L;$9+de>5k>$4;#3xxd}*JS)DGyGzqg8%Q`xuA7OI1B)?!Y z?YwENZDT!3ynAqW6$i!KCzDhaYWQe=z<8D|t8vn?`{>k&d4EF8g`_4;@}y7oqfmRG z6R_aHlzJqYDtB!=aC$r#XlUKXPJGZ{!;rwOAk`*nfp{>WVO7l)*Tq&2an)?j~3w30>vCu;IX06_BVJKsj|zeh>a{gTVk_eU$k{8({Hd1 z49jgVETG$L;;={8ow!P%I3(#GdJ3rASOo7Sd%7>*nG0 zlVgJms?HG-Iz%&VGkv0tYf?F34K|4?$8e^=<}j4!c`dMYo`U97X-KtJl2XYHg+a#n+RNuF zoFxUCQEJuYL2(^f{3MlUlVl29y~0nKW>6!mVrrO&6>FMSsgRfjuaeb8%%+PNJv*=tP&tKF3I7?V;}MZ z5$V%kM=0K8;+SJ5v(z$5rCefO#|a=en_lO<5oU1u4vz>OIj&S5lEac zrBEOzm4N(58sxF3vIFN~o~5KTD-Ctqf}3nbP!0gEqv?uT;)g@CdEMI)5%TLMR`xw` zI!GHF-&4~{>Jejw4cn0lP+5lf5u!85n~DCD5!9jG=MVkLWp5)wH6PBETo)?iJGPw5E!MMeb^U4gUYi% zTVS8q7J&{wq&n-1s?%)|(BDe{&lXOqsD63)YplQfTmdV>%LDUVff>8N>Pg~At{+YJ zbj^0z2A&(g(&704M%dC~6NqNkHirvNUMv^byh@QESA{|&wurE<;kdV?o(m3zJ?14W z7qUUNwULm>8ky2o$FD=$1vV(z7sfD_d;EC4z;=frC}mq%zc-jyQjk|hATFPz0H?oU zvp_Y*B{vNhmB_r(l90j>G}NfuT7;ZD3YSG=83}#+7pUcbRY#NhK zYQcT@rDnQbM|ZD{;kipe@{syc6VVSVyzhj21va(ZcfuD%8`wssqqEw9{%gL$!ojB054-A~G>@8uLhaMXTnvR*7Wx*LsEyb{H=bR8U6t$v zR>JBBVrW3k2vvCvMc0rL>e`$4Jc&r>#>5*WZ|h5*#*aez$Fczqf~S?YX365G9zRcO-$vc_pgcMoQgrvt2}Bp$@f9nSQo}y5eGbWDUl>rzZOt5 z{$nS0+9L!*~WkPBo6` zW}(V(2jV~k0*g*ikwYphft4Fn3U)ml0iZ?dmVO*y(ac%2R>_P?!iEXs`?#U1w#We` zTGD+~FRg%cpJA)8iLgbkgczB%xIEC`7i60Z?Rn52?h4jT*?CI(XjZk#R2)OLEskEg^V zjgH^o)QSq;xSuSrH&nX-?R^bOTD`EKR3v}kFJog2C%&(R49ybCY%cEg8@;g8AXL;e zbP=BtqinPWk=Bl&M)lNZ3hcFUXqd4*zb{z)nH)GPBhai6Fh6%9FmG*R`3y{P{~~v> zG^^u#D?H*QT)45tDo|l{ncKmE1il~5 zF=Gv6UcbJ7NXh=xp@BawoZX2rodxE3VN9@XH0Z zLT7kKM2l*=O8{TiM;k5S#x9!&gRU>|7k5YCZ3$&5frTFLhh0C~mtLff*TK|fVn;nj z(SO$Nz1--%+@`IZV=FldNls+!P5Df-I~g$0kT+A5Ds?W#zbvpfZXkix_a8Fr+#sca z<8`j8l#ReHJ6Yg*85lJq1PnjMf}G?>%jVPPn88vb^gYNaZY_bN~ z>qOP@3*FU;OHr4Jv1uYC(uwtNH96emsigBZN;-ds zk`De;_=f`ggE~!b7vLRy^iKu&r$VWjNDOVf)1;HxxE@E8@&H91H4CG(ZnJk7iabf; z*moF1?|7L>e4cHG{YDts3k!#6KTBB5KNre#VZXrxC+hY@2H=c)3C~9Nl3kn1=M0eeOAJQz?ND94|3lzTWThP)Mtg zya19}8?8mEZwu(Qr8!G-?ZOIwsL!Lz78&SU!ffg#HQ@=iOhGw#u@nafq8$yZEfWJ( z_L`qrv(|5Zf^1eoIu`c>hioEFPuBXuD$Q0ijBUSx6>c>BQRm)Zx{&fbo7*GOq|gW$ zXr;?5i8}k<%%6q-6e9v&b(=DcqtXyGsp@r4L?S>NB|^F7`!2>`9k{$h7r`SH%H;>N zmk8lhv5dMG&a}P(6)L2aNzv+11XOkyb<$cHZ0=CGNbE^pKBe;9_gt)!j?+Nj_WDF}EI6XcRVEx=Dt;gb8~Cot--KZO^e1|M{Q)gI> z;1@WzUl!n(r_60l%`LO6v(Jk-=85ba=TMj^!bA~WZQj9&oiE;1%QdR2Ha9TT&E@?* z`b|mC7)(X;7+X&5WBOdA=#@EhU59L4PDrXu-Bj82tnKZa3f684pWF0=v6*kt+- z&G3;>s#Ypx;~Epu#=tNKwZ4u= zcKep=w@eq)DXYTd$t0a{5oHO|*80dztZrWUu;oX~hum?g@DawSA?wmYq$)qE<|CD- znFXM1ltl8Op9(EsN-@#M^&~fvVa(ihq%KyN&Dl^-8f=ZsHp`BI6iKOSeJ&MSc*Fus9Ml-@q10M33Zt3YGSRYo2B z8c7VK6KIXf;}13PvT%INxWwP_3ueQttWm<)PI+U-iNUOw!jz}DFRdcKT5bX8)@@NmY11P zheB`^a-%e(3u~KxT5y>6P(`3^Mij8q{b*BOkrx&=9na~-y=^QUVK;AE@ErvC*(Bt~ zmhXuMdTfzvOY#xfrV*POo7zU)AWM<-IB+7fgQ8yI4yS@}l$?J>nEZ$b;sr+jB;<#n z%_=hV^Vq=*3(EP6fY_$G-Le$4DUQ25mh_8cMG^XO&=%w?$3G!0B4oG1vOVZjGBEwb z92HtH_n{A|LVq~WMRvh#Uawu8X_~b(UqDiQkK{)34r^ZbFusgXa7RSi)7K5LY`5xS zW{+JkFD7nWXrCpSHGR~JWtV0RPe@x2-4bmchZN%8Tybovm0wsuKO1z2xNMqD-)pGb zkZ8{QJq|;*9aC0p3#dVYM2%2HP0QRwXXIpd?~^OUBgOK*uB4d8fn&|lk&_AUkMqT& z#j&omXUQ}8SW%{iexjJ>hJLJ=#1FN&OZtXM3|9;5SLB~qL(iB}f3PZ0rjo}Po5vS2 z$l?IY-La}Xd{w3!1C|%zq3?x{7unPe`4iyrlSWLMuyXmDz>K?a`@i?BJ0 z2ie10GIqgO2R6M;ZW#w6XpnlYVGEA6@Tla?3q`iA3;Wp{zJDj~%Lq+2d5B)Nf5U3K z3k&KL0Zje94g-{av##@UOqFbfNaEbcC0`P29nJ#Ju;#c)H0Avf!w!%OG_M6hsIi)o zc?hZ_ECQmyfoKaXA!0qE-Re*UBZ3cydL(3ME#dk{)So~R84dp2O#*aCZy=e_S5=j2 zJu}o7r7^Um$7-RwEM@M1M@i^Q_^0*;7_XMvaXOx`n^H&+as=Lv{J@$&@PoE!=rOUx z6>+|kH{w3_sZioiHVS#|R0i3{q#oixD(Q&zXLWT6JD8}-}|^+eS5 zZA$}dR{y|Lc~@}NQqbxGFUH~oOHL#16Jk0#i(=Wf0}+r%q~eXKlMjkwc${Pq8hV71 zzqxc7PHr1noekwE(w&+K=3@5^-G7MQ)eh!@(Fv3|Lz#_g*Vy&MWx=<`iS9W$ zS)V~kLoE373uY6~QWG}`>5-~lmtd{hZ|f#X!5IK9n9GTxmK@E{>A>+4?R)NYH8W{I z)OCs~xKrsqQ;&s3$K=`6!07U@Zlc_)#eYeXllRgsN~@8 zO_O+Jx>)N{BK9a9udDk#;YBCr0rw&y%*cP!G!X=na1nP%rb2|ttRYIxSc{Sl$DXPr zCnMHQrdJ6c&ho>F@>emmIYe(($q;krO-8LDzR+M6xEN$aXRDQXzqJPDjqBHUt;_17 z-B6GXWxV@m*$Qgwb{7^BHoXMr%)U|_VHz^&*_a}-1<{2hYH1<8KPaYTefolo-jn#G zH&SktnuML)uL;0M+&Pr4+JtPfR;hU)2$hnpLN7Q>By@2$p{RN-bev+74x&5$k zSp5k`8pIr*URg1D zb7|IqY&mfQV6O;p?p+2qN3T#)i!lDQmCVG=8^Bx0C11TLgPo{)6kg4f!0S|l zvDCEYRd;xUeno_E-uQglA@a0W@)J?*n%2g;VmB)S+4>>{0kT;;8K0G9o`VzCqboGh|eCzJ!170k3wfR6*q;`C-q4DE} zKtWN2SikDUi_0FNG!`a&@ePpmD_7zr#imnMBkBsf zNX3g#M0lCyh}iYpOd>c&qwvV@IqlykQ6;@ai#|HUxUShu_*^qgQhRu2(-TKc6O$=9 zhmK8oof{?(FEZrq{fI8<>seUK^ieA8q96DuYK@ zlgzO(^hT>r%;gtYle$3dN0Y*_wG~F^kQN>Z$EJk46AdhL{eZSK@jjG6qB@Gibi7SQ z@FoFmpzpDy#G|w+Qe8A|YNZQNqFW= zg;@IsXwF8rR&&$wR$YfGOY0PiVbi)iOp(WDPMoN$vSk}{5Fm=`4VDS8RBkfO&~tDP zvw+Vg%sLenh=$3|5$Do%DO#;hhfd8Ty@2nPPHc?fI^$P=uELp2R)v`y@~cl&4QE;Z z5En)5Z4J#Met-!H?{69PxNl>$w4`%&)JrLnFih?qn7Yj*8&YzKXFE1;E0TxWFm*;! zfT!nyR1&oL()|Q^ryi(@-rqYSA{R5Be_;w{v^{0e~2|X`c$QX zn~~qY&|Hz+AtQE}p^MJo7y%qfMW0Muky3`-naT7nzZkP(sjrbRwIwmulYa~ySfu)? zC%tSmpcD*A9Q$3e@(Haz2>4M*T$HgCj4y;_L!U}3I$EIIZZ{^)z0gu$%?f0NJ+ZdD3SGM z`XL#ev>PJvIBij-nW@WR6wrnf>8Aw0d2uzjn?!!4g$k*Jy10+qQ#2%Hr6tqm*sXP<3quCRja1* zyQwd^T5qXuOqnB-w7tIET8LQ`*8^-{0_$;34B@TjD5T6Y3yI6l-B34DG-% zo+Mk!wQk(3%EqVDSxJhYWsH$p+vS}8)Aww6*qFiGNSJ0qPsl;bx3Be}lr9VDlOz}) z4i%%4%wuT5+q*;o*TXG8gWn%8E)aQFBu5J!(%PjnIE>#7z17(Raap={wRxh9{h;wM z4WL<_X2c4@PH2jkQ4^rVJM~!Oe!|Qyt1@bdZ4)ZSbL^_*dh&Xs)~f{#$?3D)U1n=f znUdt{5?IKV&Y<}FV^m*#ya*pBhkN*B5k7gcUsrucDukXF1EhPb!sCE{s>r^xxEu!@ zMgQqGX1ZHgpn}c2zVZWG?)SIjmg}^a78c|WfKL@GD`CHZxg*dWHf&&DQ(i zJ{r&ezBzXr;7^N5VH+`Q>@-xgNNyrBzyD`-wY+@iVT7dz)gotx@!`4DVchXD+fHdZ(Tn(A z(d6^yT@Xd0$@?Q2{@F>SAtMe>&MG3Vb4=hx6}Qp!k312CU8j%QW&hx0d4(BoZk;Hj zkQq&Z*P2_2`!0r93LDd-77RNTT1;ENL+D!7EuY9!(Rgdi$0sV$Un&WyP{33(WleAS zN^kJjgcl{QdqXWaL+cM zPbr(v7c(}WFCqu{R1v;hEUo1@3bMnnvg7&@hJWjfZ+}6Y;>*Pf{N?!JS19riQzAuy z5NHutBz7ijoiYULP`$&X3G1(ltgfG9?sfR9qRJ1Xl8C&+z<|HT*gE{D@D77-jvx0F z5A|=WWxt(S_P2{AI|=od*`JQvy}ry6vaf^eRT7UC5pl;20VeYi_PT5xo20}g-z~B^ z{Uv2A0X8RdIfV_nglfM?R;L1NLp5@0E)R#E!FNxa=I~%x)e8Wocj6FD)>xzs;B5rk zw~O$%Dkkuk4E}CB1kV!ZFq%93A5NR$qD+uLc{F55f0?a>a(a!Z8;B4s$=dQTkBY<5 z$CvR=*ApWz;GJUmmL!}S2;H?n{H%z9FIqEb^(N-Bu$Ajz3PpdHbbu8P~Ll*72cb}96 z&z%?otz{Xh5|+|c#G^Qwz2p5ZCG_`W&!$$G-sWD`&{XO`4dP^PrCnC-aB*^-Q4vMV zAt|N2RGyKE$fdzTb9^O@%UZkALro~l4q1cfUUD4yE~OAugX8)f%mYBaP2*e*ZbLh3(^3(U@Ao)a`0HtXw4z?we<3+Npn{%I*+!w6&sVQ?_tH#%%^Gu38`1--r)6v zIG{)~9d@0$)ymXFcU$z2?`6^XOGg9Vzi+xaey{E zCnA}dyCIXod}`f#iz(Z$HUYPV0-Gb%NfZ&O_6?=(QODCPHvH^f05c4M=KCW%{nHu9 zT2_pjzryVdq5>F?Bx>;#yfV~R<-Js{F&N(IALz*G7!%`DH4Bo$5^Y(Aok(R}LOW5W z(O2^n#Pdp*CCQf!1=4?w|4M?;wovba-b%~p;3G5>RqQu}qJciESUwIN-L(phynzJP z5g#I4I^^3hZsGkyql?m(w4BZvuJ-?2EZ0)OKyj1$3$X|W$lK#^C}^LRr?w@ziBTt%o?vYDa4z%Q z0Qh;ajDwU8FPTX zscw>lKeGe{m{PlrMONm+xGw@s)I_KQMSx%AK=aE{(EL(@2LCfk6=nc4Dr(x*DBw;M zN}>U*Ya$aqaQ!0ynA`J`C}fftn|odq#F$7?xdJ9=TL3$Gw<}!H_k$>TSp-=ER6n?e z&@rG(5YZ2%s#;y#VFIx7vZ@h%4s?QK-54H#IRfRDA6-Mq1WK^0GYXRvCT~a70L}wy z!Lgh$d5^YS0T05O?ntTy(HRjQg56c}bqqK8u}VvVwY;GW`zz#?Np4+x9%f}A`zSmN z(=-_V2_Jyko)`Erc}2koVRp~E0u@c2`HR`_ImR-A}Un#O}I`LJQHQ z(17y>`@Fg{Vql4Uhp+19CO^(JUBZl+I&GsqV$U%)zlpSxjuzGmz?zQdjj^%ar`#GJ zHslrcQ6qJ;d^mwsEu9snHI(JLzo8N+R?xln5re&!Sp|~mWcHZ2jiF@w< zNd?oH3{0P-p5JB_n8C50G~j|UhV||$tWOeE??k*KfK_hECt^pRSbaPI^egp5vp*!w z+w{las!UWOZ6Ton7Y(+UFk#BWiln)#hFJD&`Pp^XR-YhgzG!5*+x!UAnkSz148g4e z&l>QoL0s#ynim%T4n>6N`bxx{zRXx1nUj93c+WR)26|FKC@$(nlKL;tSMYMGB5L1eZ2yXXtYx%ROhk!JiLSQ|wwr6S-|j8e zW-uKVEJlhIH?UY=6jo$h^J(4ITWS2jY3-`AN5R;3Zgj%Sa0%G_fe>=o2G)|&ik!7a zn3fM@%%SWjy{5W8D&t8xk9T;gkA(rGj%2^`jRlXhr=B8XOkzVp`-A8Qf)u$6vIGy6 zLJ@Xj2o7l>o~NFI7uYp{UIsE?L)lWYBa%7+!-KibT2B@Tgs9d+H03Iq=ApnidDB1O z%<*h-Y&P>?P>w6AKow1o)CmUyv&Tp;4lK&(V7#F$-VoD^*i&n%e@#Y>yRQ5QZ7m*J z2t6V2qs0A-rewhk8Vi&wP8v>$8IDo2>>nh7HE8(2g(Yjj;njW4>!6m&dJ_9m(YzUv zh-@Kf_0nn>2@T79iQ?9!eZ{4?`{qZtIi`QAb7q=JYR{Tw&D?I%b_-7}A<654kCQ(r z1e-dMNkPYaxocwOG3nf!d}m==oMr~MWqfgp>x6eGjt?zD?=YHsaEWMBBM8XVecm)X z0s{@y`nZ>IrGNTTQ)-N4aI?Y@6}U=4+ZJuTnrHyMEUG#SCpq4_%Q~tk-m^VsUK&XQJrpNrP}cTm8=OkNnu6a zTU0|zK`X^EJX)BELOJ4T@}#|t6^3mx^Fq2s)SaBX>Te;9K~K>s^bbWKoKET%>K|km zxXDaYEfQyO;0KtdQI<4JOU$668|~+W>iDbYcrvGk_R3ImxPXP0Y}Yh1Q^=h&Yj1QF zSwJRhp{P~4KDC-t<`?-Gg0JV7a0?`jc+I0-)lknP00x?1R%Ud8837gd>`$0xvc{+@ zdIW|Hp=ersbV2Arl%m4I=vt^09RXTFR!=UOI)->4QPgh|mYA9F&T?i`^eT3iWzbEs zlPY~pZVP{Ans?tt4Jq9C+=}73d*ZfgZNtRjzq#&zb6v{n@&7v4{oXjPTSIE4EcO(_ zjG?tN@|1?ZT5dcgr8H4WE(KpO*w=DmIbI4DcTr4~7T2XD5EqL@EiD17VF3Usm!{S7 zistvFo|57WkfLaXIk8i&IHU4gLg5TuzAe~f%brROD8+IrfQ8qtK~7(8Q~fjF(s?9q9lIQwC6k4`SQ=;mzWdUt4%m>zz_I0(^&lK32QuCznU4n_pn-u$q=|>L8;-8FP zLwwMXqNU(LN#$qZp}tpvS!L(%q5mFcg!7`W=}&nMCb&^D$`&CLOI`BJ{cpju2+NVx zCYwQZ?r7pPUEBvXFL~v{M64tT+D?dKs&y=(8pbWTTN-}K3}vJ^e2N<3T;*A|9Ntlc zgsxwak5aL7Fu>x_(wPD$BL#5;YyvKfilj>4-0Psr0QybcKYYl^atKHDpV)U|YS;Ot z^up=Fn4K6+pU9l=h1P2lPO+DKa9@ympt{a(h?ir^k#_0{SM&4G_uIq7)Z@U3fZM;i zd07Kfx_^ZC4?glq)bP^hRGs)7_|QzNLai_dw1%Rrp_~EZm(2ge-rK-el2vzN_e%BD z>Oli)=mE8@F*Tqu((qKH?ooqAXvVE+X=s^Nx2C0r9-yOFdhbdqx?a_rs(LL64+$iY zg&4BN3o&>h1~0RQnAyx^%?7eV77|Fn3khr(+a!?n#KwU&-t}Z53o)$o`=4{~t$H8o zR?l?v+5P*$=-yX#>)fw%&pjXi(>jp(1mr#A=v?nXqvqK~@I3hAS9?wH`LRlr`cjq) z))~=%{my#*&U*dMsuJ4&R_*XK@2o#sy>1y$UBLW~SZ@TKB_ZdzmEzVXO&eE`{7JwA zT)rP@6jU1w?6S=x2$mLEjdR-bkaSl2OgTSoW=Ts|E+V%=hmC*=);-vRnhoVd-%pvrHA z@tPlM7h1v$qj(Z1J#gHEN3wn?PM-SZ?Mvfs#Zpt5*1**eXLN1Ztq^u7)v;r)H)Eii ze@eLUGv0j7EQ4PvDziE)gQP&Q21V_Wkpjx;S~wmY-No_19o0-6Kv<0@s`by?lsL7tb1-8Zfy2OUd)^41K z1s2`7N_JN>1nGGgV6~^fRk6F8>G}!`X;d{PO{@-qb+_xx73+>Ttz`v1w;0$=4_AF90@9k}(pMZv52Q-0!W`r`8?DiOO>Z2sr|^k=I$pav(|1DTyFEu{M5M3b?XsFBk0bIYN2SX z(nZSYaGO`^I2>AOvqb61QX^t&L^QZ6KN8nhk31&X+c zd!o7K&39P<#&f>g0JX^K-NnFfx-Q)vtRz_6(Z;WH7cuaxJk2OW9gL%lYvh&+L;M$Z zW#HH*gczIbxSMe!ExVO_nmab&kvgiKif@r?P2@H}qEvXuXm}o-6bjc=v$26V9Z`%b zp*s=`c4pae#k*fF`bb;SOpr^Aj4)b9l4oXVe~J5#aW9~7)7)?hVL*NP$f{z9@H(3) z`gvU1^wWM}zV-&6dD+opFkxVz*MjwR1v%O>dH^ATZ$7f7*_8fX&KAJ|Q zLHFV|_UsA2hy@D00C{Ne+gi@hL$?W;iJSzmD~fZk51bf!3lcmM4gZ;91vCaVEKybJhCjMOD4!H5#aoxB9Q?PEI3OqBc4khLkHq)keAV zUZ|qcv9YnTTM)6_H=G}xX9x^g3s_i%ns%}d*AB?b_Rb=mVHDJWm zz3BZ^1d7}xyXn%|-3h*iD$3Gn_ej|teK{#%5p_n0dblu_-IiM;-5I~*<^dT{&tiVjKS&Yb2xZja853j$rea*5xj+YkMq+OaL zci4MUnh`_LCr>d;pvjg+c_L~inIXKID6a=NATb*ZhGlzHDy$Ly+_kVzTpf6l^BlZ7 zVS`uCRqIY!V^u=F7aDrOcjOYF7vPp$_!$AU6y^FR{C-E5-*vd_cjOYHT{~WPgz!xq z_K|^(uM0;gM`nl|U&xt!3k7!zp%AGVI3lnul?zX|^`|jupaqDZcS1b~v7+T$dO$OO zRqK3GigRZ;N3fCebo6iMqdj7h;6@DQ#DD}+P6C9-vK*$L5HgH|oB%n#+batZ`~_F< zvK(l>WK#5sNpsa8Dy@#B1Gu878rhL@vIWCIIAY1PQ|$DBxr%o*M|pNT+mS%0@Etj< zgIPsMxYV#;%?4zd-HqvHU3cUtI~l(sh-yNfOV~+LyRxtP*(!W(bwA}GG$@NwZqCKc zwNTBoYi`R55PhO{BB?h{sVxmMbGo4-_+F|MJ%NHz*&zF4@I2Sf;HzoydS#;TC-4IT zK9KxHSMC!h(XwuKmU8H*no~fI(+~EG6NLwlhm=KUK#l}akOj!SWWLfy&4|sfsvp=d z%Ev?HYd|q^gP5FCX;noUTEh`#CW;b}T^kQL@>q_Ma&Hi3$Zt<;l^LSx^QD*IjpC$kzPJJh%?jM}S9a@J`^tQ# zn4I5c_gTGl261`l{+(f+1iXD8JWITGfv477h7DJ_% z5F8K_#BuvDt!XV?_W`@aI(oL4DBddjXfbvK>HW?sWS==Y##O!PF2!luyNxElMHYV28BD`&;&pAmwU30LGFK!-Uua z`M{i6LcGbmc?Zcfgcbo|<}Hpq*DlQHcrNi4NHK47#M|t@L2v zKY0o9rTx)%@nsi|Va1n{vy1qWN2^|T8j11yN_(&&~SWgQE3nBpG&&^V;+K`iOsyb((} zhoEE8UrH?L-uPYz2i8P4TiqPT4)>202{9IirBj-rF2^u3vpiU>S({W4;i!y-kG?HKE?>CDH z{+%y?j@X^||B`8nWHD!VIJ)PHC2rGPH#MSXH|#i9Fz6@az4gl?U|S(`#h#YkEv7Hr z*uieFam6-w`&OCqgsipz!OhfzXjRu2AmLshmUw@(ceVS*c%e8+(roL~VnocGjRLp~ z_@SAHk4fqNYBM4gy0{e=By2;CsW>2qBb9B%$%Ri!IdY2sg!ol1Xu5Xi+8qq!m&M4* zxOzd0)dxwsY~PW9Pl~G-RMNTNUnI(B>BmbpFvMAJI$s|p#74zUz@**33keL9*4e-q zxD@FYxQ*T3*GOue4ctao5r9Q5#x>>0iPr_$s&&KDAgwPJ?y|~O;zm$KwilNYwcK&! zyeR8C3jHL;MR_(1{M1Zj=hr+;cf${A)|}UWX~zUPQQcJ43#+WN*?ouJF2p-p!15mM zgo1sTpMcOXswHRnwNS!_Cen%?k#B!!3-fhJGJNABcY3H@}>hj*MSC{v8`$Wgp zWw7(=@{#td%lo@tT?!^8M`#sFkC>n>1jo)`s8$V>$RCl%UM=q~6{s=By4?E&v+fvJgt5pqtU2Pm@7W((6 zL~Z=2b6st04uyJ&hDb=BppxgE{zRWsAon)@^qosT-#6`j`=om~~O*A<;V(TdKGT~g86 z`s-fK#SWHqUD3Hq-i_;u&fP3N*A<=Wx}x)%Dmp*y43yK%-w2`&#D4W(oNTr0fA$jM z?q?zHe%=wE?`UIBVy~1^XQjG?X}|E$C9L{|r>@kXe~a9^L4RJ_gl0Jm>aGrp1)^G{ z+mA}uynR`@w%7)Vw8fX{8vC8gcqU$#Ws5$NSMHVgh&*PT678(D`Xf5xK6xeP`m<7& z$--kC3yYTe;{0C5M&HrSWf#aUcKObRV3IE`y{BM}?`YH*;)^|OU%{8Mz;`rw+3sG> z>fU|YjMcsUd)*E0`=vZcliB9q_mphypT49B+WPBWM9|_CYU#5$`d3#UliR9xQ^^z! z>;=-=ZR>@fI?U=_Iq*-AMZNoy`bn~=cc<_Q1kI1{$)Nt3UG3@J7-~Bo=w?VS>@;gb zFRte9*7L$!+HhWcXIGPX;Wf6F7vI{=PF{FPo5+iAT}$J5@jFk`EZ%j8-7drzox!Do zpr})m$BE9`IYrJ6HbiTJTr<`cK^6!(=o&w7A;d&623|;UqBEErQd~N;drlXbAo41yGPS{3@e=uQd@&+y08nq6VcoeqS-!a31cw z?gt?Uovu^7gLmR=M4*@$HtjDXdYwNgy!|2sTT?Cqj{DRpgltGz&8rlqwl%A&<9rP* z6^FlKtqDCh*y$~^OyQ8D%G>ZPrc96( z=1Xli5|!$_7ulvlymEjj`U17*jxUaRQ>S7bJkUU#vv`K{7$%m$;Q$j?Gsx`pb1M<+ zNVx0G=~Uh}2B9VfoC7p8mUarP=iy8P1aSwMO$xqALDV|*fWJbxOU=|f$4lrq{Dw|9 zGt0$pbjAuxiQJ0D<7QS|N;J(HV$bFiz@qA0N24d>t$X~?kE%*M(;<%GQYuTg7Awxg z7jH%Gs2_%7W|nDzF{BOy;RNZX<|6n=j%*i49`g1gZ#kUPQt>S3Q+DU*&tL>>!g9E$ zr6!RZea1Vf<0?+YnGLlNgU(?ZV+JTN*g9sJMHVH2R$OO-D~t~?8q5@Vqi`HM6=#bo z69=3zYCG?S4yI$g7ro!%{H4M8(PtZyR#+r;r7{mE&IOyF`Pt5QW(`~$`f8GnD7P9X zIwv|9XwA?3LQ894uvl&f7oxMN63=lKh(z}1D^RL=R@$sq6%Zm?jt+2^G($2%n{d?3 zC}{CEH9sJhqSH3(=rM7V^Vj-Uo|dvf7tyi5E&DU)!ZgxB=54n&ZF5JP=AY}#%eMAw zlmWx!FENA0OHYS;r96B&hyy~O?2q1zUV8c?sdyfSt&K}k8p*r`-LhR7>E+odogJZd z1YC%!alH|$Oo<`qL6SEpQanHI0{eu=2T6t8aVxHhnsuI$Al0B*-s8@|iE6Xn44dgH z<7h!wHpGAC2~)+@30?lG)4!y@Vxl=8XsV_fxhIYnBxDoymNkAbvfvsP=13luZtn*j_Q68QCK1U&PZHbMFF>i zroOx$Bx$xv=`C&LL8`RH!O%|&rA_5G{>qW>E2JJqGVX;ai_hM1WX2Fuc0mqe!~g1v zvjTVK&3@7u=(^N8mUjP0qWs2c17jnn%)GNB?c-9OXc_*~>oY4z2 z?k_6J@U)>c3&$Z8=~PEK?;90ZxI z8-nws56a<{>1mq%R=?t0(;+9f3rWfHj~n`ter!e68*u^vB27Ea7L_D%0@fLZI9M7< z-0(MiBn2aEIzM$ADyjPsP;vCLB$Flz53K;w1;F?aLQSQZy^-YPX8oNp$7vH_~ z_AOk3N6M#ST!bjqvJm|X5^T;0YuMW)r5RZz$Y?hr2k)h}AmI13ycdVHVaB@hhEBz3 zTuA55^btlZ!8dT|5GXnN9Kw;jAg(z*V zuLspYMHwek5+&yls9{|}ra3?ma++O@38wGPS&UVa1yK_zQ<9586%0auJM}7te+1#q z*+^52$r62oAEp$|1u~0YY8D>`K;m+;l>KzthEQ_?NK$lR#EJor=hGTf zfqiG03$Y-iPPA3ik_H#m zT#)MBF8ZCra#kZC5soR{4zV0IaA##I4Ne&1z|&24O|8d3E+sH#V4s3E#tYkn1o?eu zU`oq$&5T01JC4|)gKK_P-E`zZG@t&^kq;uE`Vy%!g*fpblubZ(!mHp>wIFTK-_(dF z9$EA$+c}C@z`zs6IBK4+wyUa9oiqxy5v|byFT*%<@f8n@0!l_CiW2~3;9PEB{nv`Pa==$gr*J8G09=bu)ldDg^W~8 z8Bar|YL$~+IzH*At2LDb7YRV3U(0(xlyabX_$3;dN0#J+z}~&o{*#km)B6v^8IFi7 zq;%@5n%hWKvld4?`btSjv1%&8JoCEY9jTWhL_DlI%mhY`w-mK)B*nG`UC4M!vesi- zNzEIRm$tzK(;uOw0YrI>rQV=3&!O+rV+b_ci|aXZa+wRT5?#B;mYL;CdJ zjH4L3J<@0U(ufggkxv=7(n#X%9m2}Zb)s}6G=TSGSUB}H&7juCT0jF@2LY4xeUuTG zo&hdo66DB;exniYfO0Umw7E8}DNe`q+Q7h6{B)IYKUTBNM5UW?SX(_@c~Bo8gwc=& z8wM&H;ET$ydEz@fL`y_y7F!MGZHJGb@gSw00h)7cAHq7*?oa%wQ#J&z`f0x$@l$=Xf3zf52!DKf znq$FrH16G3z$1HyJ~wBE1176=9gNM}m^6PrB(IAB5)*4tLVV^5_RN_$&Q{w`-(j4- zhsV4!XFH`5*d;=5h0C@Kwo#_WRK_CSti%rARloMl0~W9;3TL|77(^c}Lm zgdy!gfk9^%>o-X7{5ZCWIeiLg79ehQw(?YV;MLK7{}4{4vLs}w|FsPjH$t`Ah{Fqh zEzVYxW`z4+Yy9%e(DF{2sk$R>?U4`5RE6u)(`jSXZv?BGL9M2uRU_1|Lcv3T%BHF5 z>DEW4rwuE-VR{;nC%A*)zxT$;41cHWYM9Wwg%C4KzRu-oi1K@zra*HtnYh6#SAXFKIpkFkW%LBR_pD$Dr`B0u|2}qsQ5hNJKpD$WLBN zBJyt)XmG`Z*178Gc+!!dy_QrIzgD2*1!DLt>%tuIedpS)Nd2M0*GGlD@HwJXy0#p` zTrCUV9}@?ca3yxcjV1Y!YdQS%nZlQE6Yc^fu*h~Canm*Kx%pDz`$vQ*l?G;vi5u`6 zX|U0u4;@_Uc3bb4bL2p`ng$yY*lVEDcgZ`?*wVTQUavu@y;9jIPF>#+oAv)v-pY z;f}HwA*IN`Cm9JE%Enl0krGOqk!>m|+j_zJeyvt%_(>L2gNC13>z(b8Ha2)~)k@)l zP8bqoL2>VikDpO#Gb9BgP_HlgAtm&Pi8>=wsT%Y)%`j`ftsRo5M_=u}*tP1?R~vO{ zsG^OGG}~rmNxnVq23eZh=Zwhgnk92kj#w3s)$8qb<;>Lmoi()zQL_;TQMSJ%e?z-N zK?HcMYB(9@53mi=bFA4nlE}T3_;qLmfd6T$Jg4HdWAH> zmzoo80|-*9wA98UsF0~Y_ep#P+qHc@>D?g9-&~ICs#4Ak1a`~0qif`vr$^I|YF{Cj zS*?;J^}2P1Z2b)9{on`p#JXJ=sjv zAz9I5ziRjp3^#NWFXwKjaTLNr`9L#BNF%oCr!5Q)w%RM=rr1V>)rj4skascMaVv)_ zo_pFP8$K)J$XHFtc~Em~vM?Fj3v=lFG$RWTRP;F3%J^20k;2<7+w#|RIz2MY8%@47 zGr1Kb{b*MiV=HPu1eV6#%IVQ%_r)$91#ot)cwZQI&o(f=$fmT$KCYViGXfU(3`|5Tz=~%I;d6ZPHiAD%wz2S*8KR^0ixeUb=2U-tf#rRZg+F zw&PY7{cY&(wM1gpv{tOFDcDNj4!FHu)}g(*X(or}tw&_u!r>4oEDDsI&}k=Yq3t;gNv zEKd9lHLYg}zR2*`R`s%b(GTG!5xicxYjDQZ8Q8jyK2AnD3J*!w&HM{UF$GgombziE zuE>=DhhX81a$gK99-D^T+g$yNIcJWwZ|@(Im@$G?vkJaZ#Lw(5Q}k^Agvu1xr3A8Y zUzZYEk8dqj{z#>SFX#&nZ7D6ywV%ozH=d)p<$O;fLqSl;4bfIUXg>@`_%Qq#J^_FF z&aI#5vuUPEcN!~s4nCb5@Q4+}pOmt3sY|cerL5#y4W} zan!1x7Kt4>#?85%UlifyAH>Zx-1&_4oUkIDy;mZ56E2jT_FTIM{XAds$e+*7rMagX z9Y*IRt2h&vyku<`Z)0{w>}B&QG1OM~x$6uN0Zimnj$6@KrB#N0b9Z?hlCl=L8wEj{ zt8zj5D%ooHmz*J1j5*GVe6kZI{Ygeizp*qhq1C+$Jm>L9;Tdo2TB%G3{EOgsITla)Rm~>#K@wwws~CpIG&O3BU;6V9I6!L zWCJd>#uayMznN{uNdT`s-U*cQccS9gYE0=<^Z^rPST`v-a5{Y>lrpRqY(j4g4I1Mvtdad_1`5xG=8b87> z?W!UsMdcc|%^fhbdn0y)2Bce4p+W@A?vp>7Py6?!oG8w>kOylj^mhj3T!&s($dUPi zR#kV+j33XKoz4snkC@XnIKjm{l(=nCKrC*KJep7OP$|yn0ZayUX}2k*C8&~$yG23k zc$Apj$%hP(Zd`#6WO_i)GThP;~!Erm4`_87iVEZbnrF{Vf^_VkqrN zSyeNBCLCxRa#J4CMTZ5A*qS={dX>c91alqU1J`thdxk#@j0dAQZ|!2+6kmmzqm
Gr#L*b@>R2EPA!~zIT95^H{23+5L^D4x>XKgBc)lRnLz!!8E>hJDuHUT7DtM2 zfcKNHZ$YA?xMJf59Yj7kx(92a^4!~Qn+-$si1fFxIbjQHj%{8E<23VbyRFOwtm4}P zPo1Z5h@deoIVbLv%ME`kf^!$tM{cCHECq(CrrlXcpniQV*l0510{u{?7!se*TM+2OuJ5YG*4+je zJ=~^@;u;|>=Vej8Wt0n=f{KpbnVu$((#n`;%mzDg^F;}uHgL1ysFn)Z3mQqh=C6f2 z?(3RqcC1AUFv0rHYs7!WeG)J4s_>R$%eOpYzAb#AhsrK_OBOevLJXe`)wTG{0I~>y2Cp!jLxT zK{=daTdCx!iUqU+%r=!nn}k>MSa&f&ZR?P2otvg~>;oL948P_41`4#DEtna>LU^Ni zVj*XMSHg|xw#x&tsX{WI&~B%&;K?FaV5`t>TbjK-3p>?tKMKIgBQ6TuR||+){4VCh zyue!_FpBeeCwPXQ4I?WQg<@tvWE0cNNVkgsM`HRdeA%P+%+A&B-W_|l*s6|<$zt8G z=PsG8g`M>6u96UL1e&oW!3NBE;ZA2uW9S>N4c#>^7;Z>#KQIvG@ntz3WDK*Rq#S2$ zmy&KyZD&akr9qWh5_nA>8;#-GwK;LLWfz}{m#lC{QDK^~8LtztH<({r7Oa_dEZDD^ zN!!|t5fVdZFp~gwu+Wc zjq^xA1~;cRT_0NFI}xSGGKP+D*Q<@dwXDg`CHpZB8y&XUj_#rbI1=_V#LZ@^cB^D= zh0BP)1Dun%8gNuT&R3o20|M|f`r4YaU9>l=rlAGsv_iUabL#xkHvn5dQ*%&TID z5;C@xm8hpW+zQut97>+pUx){U2`e{hkr*&rkk(s`RXCWp6b|3?knHvxyJWPm=P1_b zWRy!f+Gr)z6Sq=?wbAkzXL5V9pxHCCVnUh7s92O-=n{JkF1I&f4}*j~Xz?#`DLtv> zXS3WfM^9(T?;CAcunUcpRG2ex_0|a8wH-TJW~Wjpw#LiQJ47L<-Ka$EG}UOZ*$rj_ ztJR#SPbmhi<+gfN^bc2Wie9IxS=$utL4$A!&eT8ph@K{lTjxY!x51vwN(xW--KLE* zGrFXx2vlwCQZwjhw98rC4iejRdaE3TKuF4v${5RNdc{z1?2ff0X$K6B64g@;Ze;wR zuEMl`XPl%{CI)xA+^dY(bk{|Q5yU!$iRVgoq&LI28r$8$y-ezlL1nnVe05ZYueZ1P zE-J$hTiG)Lu1FD?%nT5C(`Y(&73TS>Z10~i_2SiuM>^1=}K$iyD*53K$>e^Djy@f?&4eq6Ph^KH|vC$JD}4wvj+iGfYs! zLtvOpU(7WZGOn4QVzZ=lGVg^EKCD?M&_`c z`eqJ92{ZaXq7i#f+nS{T=wuReFe<1tTYX)#wxOl$kwk4UVBBMJ%JLYEWr!REtLsXA zK~Cs^JHAso$KIv0R=d7y8`FlnBJ(OP>WtNo72W18%TDil!*VSn1i!Oi8X{p4_w=i} z9GCcOSdMnp0T+qPfO?e7q6FBZ*}^%Ie8IPLvSdhOu4*26u$$iV+P3Od1;*-UMu`uU zRjtiUH^~wOO(xX1elv^58*!r<(k0nXr^Q62Qi)=Ct_Gp{_%a3KT9VSyF>gaIvqZ(XT@N~Iz`q?gaHnq{FUw{rzeX^$7ZketHu8SGd-rP0lzI|@0IkX=iq znJ2!N@2a9mYrRRj2-h%bSPzpQ$=uIBy}6HK7nm|CG2KS=!$;dk8@3|7M%quBVX*gg zW$|*l?9qWP`?GKO5S{Gcx>#D)m zBW4vOQ%Hbas+SnBB)NNf`i6VyEBw%Upc2tP{9z+xQTs(XQ?Gi<5*hL9O7Ve6KEON| z#h4$@qNbZ852Kz5F7Oco8f{;Jb68bLM0gYiQ4pF{Z%zZiP3Obj^uDd~w z*mLjwCHY!=n3!075*_Xq(jKjo1ojF|wb(!NaXq~)?1|V_x7*1zo5Dvf%a`myTJgj! z?Z*Sg{*nyJ4iVTC$EZLt%CZ6Lvf6HhEK(RDn7+``NV5?W4qzcVEFZGWHD+vH5v`)l z0?4F?Tdr*spq>&_Jh!S&aGwPa{#_eVpmmU4=I-LJ71tHO>qTf1_erresqb6SG5 z?7|R0kVT$&-&pq} z1}4=e_*Ut#;)(C=@wBTGekPP9_r^(8LyA|h%MtYHCmYHvPjlW}!);;Li#dc|5x_*> zzFvl*SW25~{c<2}uI6i4F+Bp|VYIjMu> z?3sr5>wXwiIU1xWN_0%dIWR?Y@~&z(?QCa2j@Z9<=afT)>AgKAhoMbvPC-QtS2RAU z2IWBWjw9k(gJ&h_=OedbJ=V1+jd5*@BU}MD0IY4r0PU0IYu-@dZ&e^MfaTU;7RG61 z>7>AZ-3En2S8`e^d9#EFoW%_n4{gG%m_J4u?wti$)ZyqXWUwHmweefN0RltUQL_KJ0EcNGSq|4XY|gh*#2tAd+-|5svV3#rQR`I@60c&>v1w5 z2evlj-KWzwQ=HHdi|q2jl57}=kLl^t>+9t4!x7!hMBOb8jNE9o80NcltW~x)W)Wszz1tqg4=Iab1_ZVGMOA3E`#U&2Sg& ztUCFem3m~^JdV^N&+cE8v)o~`h0I{EyiQ|jh^X+!QKZDw5%=V!qG17Pm900!@U5ni zGI$9r4W`1=8`OKPUg~PQfn;W@CVKZ0#6D-hFNo&)#hhN#0$cIT2g#?5f6}WdDlD3{ zX68n4nLaCd(D)g%TSykC9!BvNxbK?Ui4odQkU5Qjvs3T~Njz&GjrUM$T2#RNGK!hE<#`o(`{~XQSpv8zC~7n+7j29XItO z9$tIXnCE%b|-f_o)q)!BNzxTS==Q79aC z#H}SEdZ=*35o0AGdZ}=SBgRWYI8>N)#0eov^!HIm94-mbM}?O-;%G^TeN=d47%$I~1;L;ICER=+}kxO?tVzDH| zGr2VBi2F)HJc~<59dWiK#2}Ym;)t825C^#QQb*ih65`ohnsUVXk`T|~(w&a*OF|r^ z(vb;Ad`^g)xNz7JswBj7xpc%4K}m?`ap?|6)JsAPacR;K50r#B#HFK-XqJTd1unhB z5j!OzevwNrb;KJ=LJV_h$`NlW32`%*?sUXkN<#b+mF}2u#M??jJfBO49r2Em5H6RF zIKmO)7E!(@^e?EDt@y~%mr&IU#L)7lZ%Qu|Bd<`^s(-;$jEM5`roXb8C}pZ{6*T|7 zLSU*e`@NF>q`B{*KQZ&Yc%q-?y0=7sVy1ih=ugaZ?>_ny6WhC={=}^I-avn1N_(F{ ze_}p+2k1{sX77#kCuXwune->7vG-Z@CuXhp0R4$6>wPx;iTUb%4*iMw>Ai{m#N_lo zm;S`e^gfUN#I*Dd(Vv);-b3^!CZzWl=ugZ>?=RAyn2O$E`V;fedo%rsN$CA0`V%wI z`+WNIoh_~`pXTe!XqgcijPQfaK2hgeMdZ8lE)POEdJah#78g<$7mWJ#-FqF z=cBuW98a)=4*aK8BIMu@JN!7}Vytx%_*D9IB#{C2xqpVrT}W08Kc zBsV*g9NMQ{G5E?D6Zz?qoPFAGl{c(HZn)@YYI+*YVlRKJG%%?<)@%SN$$A=(obk7~ zlg@~}W=SCj1_5dSsIf%H4C#5{s6-VN3A&0ffxyT|$bX}aZPU(n|m(wqo zTMVM0-mK%WqU<6Q*v68SNgf?K*T8&zMz6%R~pObF0XoRz4Nm%_jCcHzO7$hy6g8 zNhw`+ceFF0Z7v5@DXc#LttDIjjyLtHB#t)nrf+b@C4w%IbDr>CEwqUJ2D;lqaQ+4A zUy$a_pFA6xq;&Z=o`H1DT^eTMkxb6O$mA^-8=YD7w>c}{N*tezx5R++CFs_SyOV~Y zE4rB4Rfb+*6NK@WH)*nrXGnD|kgcC^GC38+a?fFIzdhD1_~|^5Ir6hP;U!iJ{n% z5Z{1Q`9w*4i+cK3r6KWGSKQMlbx*%r=;@PfJ)I~mFBw`=HU<=0a7~b9hp@0u=A!-QO zVI$-yFK{90WHgV~-GU6NmJ897^nmDbzQBADOBD|kqO)4q4>>L|Sv9Xr$tSmWz-&aX zbBmm1-4TZ|QUXPI{rMR}@^b|t$IIa+|Dx37Bg3w;F?ZgG4NMk}6Y68UxQjG--b69> zQIwpUBpq{r8bB}Bu%&B?J(3aiX|j+3O3vSLRa*6-86`CsgwG&U8!AP|%-GgMpYx^S z0wTCm8<+?9Q_xNon3zOW37P@?7OsvwzWbcoakQAZey!#r9|`nZG!T1W1wW(>BKr>X z3E5{+(v7u+bs`hSH0vcGLP z_h&FZGk1@XXqA6p7tzi5`?q{vh*IB`iedZvn6us3mvgrLeYlklzP}`H>=UAAf1fze zR|Fv{^>o|=OFeY2y@}o&`f^Dex?)Oh)|A{@pycM3@7~ha@!ebc=)1St#M3<@hcwT&fMgOX}-juINC{cr|i9HWl<7wuY-`@=sn{rPMaemFD%UFOPtPo8LG{9p-DjfDnd7S52g#eVKa>BE*ykLx zH7wkD#}=ZCei+njz36vN=(<8n6S|7Kvfo*OSYusZ18&2c)K9ID|BJZ6Ifut|z$0;g z`W9U&7X4_)uI*Gj!};c-zm0p5tK&Z6b$d!BIPm-`E~##TYvRPiZN;0?QrGd&4=@`8 zPQx4#3vn`8*v&bYkqs;N&e>MATMYm+R80&z--DuyqRBHit|EW2 z#U9{{(#SBHrcFRxBlR+U!+zDy6>nd0zwRHp>abvzl5F>;G$?PHQFT|)*IWp$%-9u%VzYv8NCtA zaEa$Sk6@H+V|JYCN?)#Y^AzpxO_~>107xyK=WMsUUAT2o1RB_dc|#02@4>@pPo*&W zb$*o7s*j$Evw1dAibD?a$Q208^PdwG9Bh4%8etNv6@?~Pp3{t>NN^`rfJoSb1al`C z_sCs+vwib@3w?`yXZ!B&JKyK`iM#p+CyJWOQMH|^2q~%36@rypjpAq(@CmED=1v^n zRMiWo;^@^XiFrRe&I+{tv%5ESf}27*z152#eU3k$oqFv%?-Q$QM|6ZHDaxu8G4xckd9{Bk``GSYtY*B4EZ8gRsYeR5zv@rAgr zZ?K@_9;WOBL3KbSKK(AG<1W;>F{rb-ox_gkhlHYwN2u6iig!@4*AyqI=$PVBDwa&~ zB~O}&lnwrP4{V(W*!&6JtG=h`yU_dHu>`i5+o={sc0Oy4iq zGSl~qw#@Vm+cML4vnj*q)(;DurUz!Xe%Rnlndx(Fnd!U5mYKd6*fP`iLR)6~Mr@hs zyVaJNzF)Rwrtd|jJjwJS-xe+3Nv3bimYKfWY?6@};rteN$X8NXWndy6( zDZhm2o3Ul4?=D+r`tG)6rtep5ndv)b%S_*_Ei--h*fP_1+?JWXIa_A>=1uvfOy9k> z%=Eq7mYKd2w#@V`*fP`itG3May~386zLU1h^ex&l(|5|2nZDDeJjL`a*)r32pDi^u5xSnZ8%qGShd?mYKf$P5Dly@71=<^u5NGnZDQBGShe7 zmYKf)z?PZ5Ra<8IDz?n@`L@jTt=TfuR}~|MKQn=~yn-oIc?FZWo>wr98+ip2xtUim zl|f#?WWFx1U^*}46-;QDS1_e@TcMAVD6e2jvHMQ<~%zOlg`|Fr`^u z!IU=h3a0d8Ucr=Z*$REAZ08kB=}un3l)gT%U`l^2uV6|a%qy7EH{=ye>3^74Fs1)d zUcr>UF|S}s-()NF@$w(%6-?=Wl22(zoOlOzD4`S1_f2C$C^i-=Iwa}Q~Hj)f+_va^9rW)@8%Uu>2Kr}OzAuG3a0co^9rW)@8uOt z>AUg@ru5ymLLWK*MP9*_{#IVWl)fjgU`pScS1_f&omViWe?PBaO5c}PFs1L$E11&% zGOu7tf5%qn!{-Be1ylOLyn-qH-MoS+{RepkQ~II2f+>9{uV705VP3(M{$5_elzup` zU`jt?EA%n+U*#1{>F?(iOzB7S3a0eoyn-qHM|lNP`d{Z2Oz9(e1ylNHUcr?9H+cn9 z`j2geK9K$(uV6|)mRB&P|0J(qO8?uuf+_uYUcr=pBClXd|GT_`DgCE;1ylN1Ucr=p z(pKoB>A%k_n9_fiS1_fY$}5=CPv;d(>Hm;dFs1)vUcr=pCa+*hKbu!DrT>l2lc?DDYM|lNP`p0<%Q~D=)1ylOfyn-qH-}4Hl^#8CG z`i%NoUcr=pJ+EL&|IfUFDgBpu1ylN`c?DDYL|(y^{$F_oQ~GCl1ylOxc?DDY4O^kl zsK3Z7n9~0{uV6~QnO88S-^weP(tnj#Fr|N)S1_gD&MTPGzsf6^(tn*-Fs1*-R_HV8 zuk#9~^vS$}DgA%)3a0em<`qoock&9R^t*WlQ~Lkr6-?>B%PW}D@8uOt>Gy4gKBNA> zyn-qHo4kT4{Xt&Al>RWUU`qdeUcr?9tq^B-*L{>(_YomjeAH-ws!HoT9+U3M^z)+HKVFj4uRSo%4Ilc)+_eu_ctaY@Sigpkh;rI1x zue`d-e0T*A4CSg-am^74i~2{{qPZzKSdVK;^~u4-xTb_qmurZhll|^okP;v~G&=K) z4G+h$ps#;7$MIq9A_xsyy|4cS`J6?miqdAfnuc+fPArFUHrHeybof9`$bsfdCWUyQ ztA^>b@bJdHK#h+24Qqf+M~GpKUQPpCpcWCqMqqzJY=sbE&v7Nv$7bJC(wod?n0V zLAFEY5+VDCwQk-K@9vYv)Kz#MJ4O2@JL0{4@`NrFACW@5`|?zDYh0FT-tZC4EQAz8 z_cqCR(IXBnXFgmfgnN%)TT0@1T{vQHHmU|H%I*o0Y?HQ;D2ciG?M=U#X6YG~#?7Rv z;O{(iyqRWk-4Xq=zd0rLiHUps+M*xTkaBcK^ox_WK*K`50b;)xxyL6Pib}){LcDhm zUF$X|0~2hV<7_-ah?A${vk{CXs-`~&PtA5JdxUs@U;jkfSPjfNn=mVmBG84yA?Y9N zlkd7`B~fb8Z_Jn{*uVxzm9ndYFz*)PgME%`9_@EtArDFCm2yfr;vx9;~z!EWH^9_t~Gt2}Wf#M7Pjw=V(;y4ttyzXayxT?q!XDWxNn7+SHwsqst z%a7|^VU;b@w8Hs(A>vsV;^4`+>W4xKcYZrV{AGyY`&i2c`b1xG1APJ=ZrwnixI7)l zXub->fN{bhCQgEEXF{GV{IsNNg)~O2^l*>(pQ!W z@1F!L6{>|C0hXhWJV0j5#V1=>&8ItA&8L}n;6FW|?GvA+nV))hulRi5z$K1&cBMI~ zk3^FJ3b9oExkt?q%M5Z<49FptB}S#L6!Ks-^wYE=C(YZ(Q5JLzWq}_8Evw*}A-=c= zg5W$br!pjNCTBLJ8x@&%_+IlXBLq%j4=#eM=8i3?fO$%vl?})FqEd8%z=|5r4j;|M% z{u4|#s(S8p#1nl3$F{3=6Y#O>H-dB!$z#|VPspLkvr&NLYB0zuh)*?b)Kj(NaindA z+88gzNnQe{;_P@_Z!|M3J(pz6Y{8udxD;%|UxK!b&)sH{f^7wZ#x`+1Zlli-a z(LJ<}yqLb*WmJc2$qt5j4&usOvU8>x&9ASkYL+?&=aK1Iu82W-jA5#=ZaKC1_xt3g z*)Ys~UlnAVOL3Y}Afud8b;J+WRw-L_TG}T^NjyZ0$mWF@{1A~W`}fI;-UD_5&sFO) zqhnb9Q|ocE}-Fi4UI z>4$y0MX(%0_e`fbUbA0L`qixIhkE(X_Q)yS8(wk5Q~jM3`=TZXm;9Yn2)VB)?bS?^ zBmotN(HX>7GADR_owqpO4ZAEeOzM?pJ%f8~Gy#=v+ zdQ0dGz@tQyzVW!LA`Sa-L!^iw$Va?C6{`o}`^7_Yjq zF1;*QEhDphufKdY(vek{=Xzp%U;k@uI9L+YgDkkHQi@TUJRXOf|AJTYkeq2Yu+>)U zDoyASGBIiU>Zxr5$)E3MBv{zTF zaZMfGC*Q7j3KDVbtP)tm^mH!w9*=AITxhehtk&YKsD(t0;320rlX_!y3y=wQKe;d{ zD=lpn0-l5%!98{rm;3kjNEg>#7Ge*#?3SbZI(ExZo~fhz2C_yRUhr#iwu;<3L^wsz z^YD)5BR$pHoAwLXoh>WmTj2IL_h|P0tpc~dnVnznYM~HM+IZ^axUL-Y+$=Wl%{^j% z->yo82`w?{OV`BE@=ltmx+DA^*(kdAOi$Az#kj;78vUoDkjIX8 zB(6{)LTFM)obQzn>K6?Na>oldh&f)eak8v*{FftkdgX`on+OZTJ!&;IKX0l8`kHG3B6zR*S_n>-_Ydg4Y|vQULc0gW&xsW9r4+c?UT)M*7hN|aOhYYM?7A# z<8A_QIyy2Y4w6f}Bfejf4NVd`!goA+o3JpOjyT$9+cw^k9WNXa;-p@BQvdhFuyzfV z(&-Tcv$PGa;=eaK-=qu}gpOf?w2E;xDjnm& z2wVEr03t@bL9~|b2h4Z*LnA~Y#p+0>G&uRj%T1v39(U1iz^9lR&?%r8cQ=fy7YOlD zrQW2S05EN8e995dT@v?gt%`IhoXhmQg)n!t?l%C;o=+As6cF@w7E@3OULNy|R#FTO zf^=uUY#H4mks5THC*+}O1px1v+KtkTmJZ*+UFhDat)r8wz`;Sac6GB9K|w@Ldd7B@@x z)ajLZji{fgI=o(+5uN@FM#(VaSkj!ni@jRWslG#c{0(kI^Prl7bQMHFngvyg ziu5;>Yp~R4#c(_uT)HuD)CORHf^=ST3ggrbgN@B>yc$AZO7jr{0tqbUDRE+_ABebzaa#NiFf*(hC(-M3z#Wn2rY* zNlegZ%DIW)Wf~DZc9GiF=Y^CAkB#Ci2Us;}^|B<`*dPGjY_rLY(FD773^H~arOQ2W z(oZuj@11RIBt9%uhk6|0oRuyG!t%S7qPI2j+W`v}4%mpws9*?f?!?efGqd{LCb#Ks z67Zd>c`N!WwUzkn9Y@Znb-goi%q>cHC21-Q#TH(uPc%zKpGuhP8Z zNX2vS^}|%TqcyeeH^XcUtweF=Rq_w6BuEBp-le0p|NI`lsf7;Qg-j$lMkPTS1t1uq z`xVoyq2xp-DO2;?s@jA`VrkP)l@R+e(0n#q9g5q)Z)g$=fH~Tn4%v9Us@X}p1@C^` ztw6dbuvp*4)u}MzfP4m1;J~lftC}Zo?UCn(CJHh_dbH;oa&2)a1U%A1U-{;9{#O6H z=jDIrkdXT(p8XG&e(O2w{O=#iec}th_B;Q`JoL|`5azj8e&H=&HqZTqY->#J6LVun zr-6=xf5+%09Gzcsi5B;l^D`Go4Y5SiY0@+DPUL(kAug$@mT?$WZoX$ih#4Wo68+El zFmYBB`K@J^{A?(QFW!`uLud&O4vIlR%ihE?<@}k?L|sPItQ9-lIF?eI6sCXo>o5BCZ~V&qNj&rWGo@tg`G5KAX!Ei6zwI|pzvef81%JQvbN}=?OCR~& z4?9ALfBUxwAOHO`jr;L#{9W&x=lc z)!+NGC*!+sbws=0UoqSShz@eYwldeaXgPuz)9ffDaELcgkc;tSIB=+wQGw(12C z@eozHqaof*j%CFyxZstZ%b-YZkRHZqpy5!>WNMk{0wDbu<{S(_(-TCDd4bheN0!hg z^N1jG{j@>hVw95%wlu>#n0D#+h>mNyY`>>h=FUbMf3LQzHlR3{LiIReXhFIs{R}JG z{H~XOO{G;8)qFau5wxTitqmk{7b1b;zS%@sGP?^upVqQ6IGirMDYFB3ujF>ty;&R3h|B}M+^jf zxI(ny1QN6wz&|J_cl82BWzCOjTR|<`#AK5k2O^txo@|GFnB8nd{TODMr(BUp?+h4(IC$k<^vxE7%UAtBiQ~10KglnN-2^^Z>AS?HIC9O@q;K!y%nAJ zwpF1e#grq4?w42w1VKt{I7K9A69}qWG{CY5QY+B$aA>?1=62*5K*~Wr;Rv>1#9n#D zUDBOR-84qDpyrR1-Ivz@a8M8lNPXRi$9-IFI0_Ka{y;JaL&|W!l>`}ynh!|#HI->_ zkIMPikPA(srl+x5{S7rejikG)*rw6y1+|k-Pai)$H-BC)Q)-RPAoRstSTnc4{nAbq zjdol2SSZE_RKsRXvl=5t>5HT{cS>!wj<&#PA3QJJyjqVI_zVV^FP@ljtC%D?&StQw z#`StLq73pi46@Og;i+w!aD*jB*rI5K2AMaSCzNK8M*JiwOlE?WI9erC5gZ_LL4PgTxS=lRl) zL>S;I-ngciCH)`;aI30<8)&c>h5W7IjtfULM8j%s1kpD@?n1t@G6Kw`VF9?DcuR9Z zZCPbG70_0*Cg)GxS0Ta|<5!q>QcB>1dBZ zg;Kn~#}UI#>CQ%O+<>%eAVi`XEw0qubqXs8TZY<6_0|NO8m_8v04nT#y%9X0*b1XK z>C=TSP)xNJiZNBMsdQ|W%6armKSOsg+7wA#YgSb)gj7|-M>T6$gXVzf@Wcap(P&u|yd&FQ5XLB2j4o2sr7Kh(onSALX205C9M zn*p;NORtgho>`9BY{VXU z>)MT4*a*Ze?DT;KR-%;`rMt%JG<{BB59t+Yo-ez~+wjbOF7jnMhN*3U>8wG=;)lu; zA7y61Uj<}c8oT})luP*v&@s^7xiczM7yT$>dqog!(4YzNFn9tT63R^@zmaanq=JDu zO^+akOS4}#YJmDgw}%nJE;ZWAeDeT#M@ zNdjaIT4T|H4Xbw7d&kgEGQ4v~Qz^dKK{3#H{>7VoG#6H&P3A9Gm^@hGxk-D#@8=?%OYk-YP+_Q^I z-kS|{UD1aoT~f($BeI%R*00anT!%@@06XPdD&NsswlB&8=rq|4Nb^94g>Gp*PX5|J z6=KulP|g*X?RP!2(|T`!L!e47DtO^FSS5P;qDqnghKEsy74mtTTR4w66}(oLt*MP5 ziVBhq3rZNG0;fE8d~wP4mL=hj(3F3-~x9F^(ow>l?}Dnl%$Bt9@W~!CM|IvZ6&! zYoitiq`Rz?TUnwz`t&rCgK*nL2QHj?-qNC4Sim4n~z z6)kM<>Pr|hEy${R@c3i)@ zsW(M#R5GUJ;vL@IjN=QQys=j}lN#50NhLvCn{XS*QvlfYx6{DEvI}K{W!%`{}G zCl;l9k8=GjOc5LOnd{wq4uB3zFADqKG=*_ifmDYgc1?q-%|IC`QDx2C8Wy25EcJu`gzOD)b@2cU1jJhv$=Xt)xq+3jG|A^}%ia>8SE%WMzWZoRGIcwxOSe)S;R+vwWI0KL8jp)< zkj_ZTPv|E*U|nVznFrdwI40eSS%hZX%34d;ObKYiFOnVo-TMa?W?6XDmtg+b$*DZGZ(7dipmq60oK=fNrl*0D&=_8(aSR&^gb|8Ng zM+7{Tsz%4W?q39dhbApi>h)mwByntJStFgk{dP_>J{?)t60bnzj?S0hqhqSxY4ORAPXNgci$wVQERdpfipJb?zt ztMzcNBb?Bs3d~B!gbd%yLqku`;_0`#T$N8{$4hdtSH5}h1SK_75klAIR3lD8vKJ>MmtT8TWg^{B}&P3s!5P9z6+2s}Yo_Y7>XXa;D=Fhk*CuUE% zubw}1`WARqEv&mcanrpmQ8=4#xy#pxRoGERkfKY zhL41*V?9oM*wO7K@Z1ye7F@=-rCJQHAwNU22_RqHBuFnz^BW{8fNo^c^xeAux;Sy? z;$`jE<`wLgAe*eu`l6;>9kh#es$(LNUz1WKR8`7fhZ2?e?uN?TrcHbBc6Uu}`WFL` z6!4Ic;Rn6QVj2fe{Iz>eoMmy{4TDHcyK^yhfq}-&9>M-1PXM?8z^Dzkt2k1(z<-6d z{NUgbq*G&Um2rv5FNC}Wi&p`H7Ns?3m!0=DAnCenn}KaUB1lo4>Xq0MjzN73QfU^{ zNx}Fd-s|N>e_P+zbhig?)T>wn6X*RV9N~Od(*V$-L&Cqd-v5Z%!04jCt#`NfE%tZo z1&nDIgId#v9R{qjIG?+82kQhtyd>z#^Sw8S6NMmM9nvnl)b-DuQrp?RN>OwGJk7hS zHpG-Z=Cm`C6n-y!edODn%ISt;-LoIIG}P~uR_@0wbzSMCC)7SItKv(QqKg<=rxB~E z+!tI75(L?~SOtry;m$ampKGlHH7oO>a!1L66d^lIW2}s;B)iV= zu?&KFJao1qP{AI$g<Ry`Gg(kMpJ&$urt^@60kI^~jpljAo>1+oQ-s zSM_`Mbyw!Ss^|LC)6Xc23{Kbu8@%8J8)Q(x0VNPvg9C<5fP>gcadtoKe2`whS9SlMd+z!3JLiDGsoq*;@bwFJcaa!eK^~z^ ziMCK*n5wpZtLto*+zZ8&>fLvp&5X^RVnCB3MJZ;Jrg5RO-?%eS6+@SEr)kO{aqvsQnxIary=)eC zK1ZkIdmtBsXk_Fs+=b4*BBm6`6eo{}%L)&NYMn&#`DT*a60z4+7+8ok9~Iu0b$%K^ z%~mUk9eIR`TKELm&04o`Ult|OSzqwB(HmJ+he5U!1t&9UdQBlO^?cy4U}v>aJ#_*E zsA7}&W-5h0FAOX?=WbDoB>G(xDrMO9+478hx5p)Ryd+s8jW|n z$5rc>6)j=*iw)pQAOzn0Z~0Os-qJ+wh2d&Y?&PqMS?&X7s~P#gP+wN zBEVtcjt&bHZ*JNOg^}Cka3<%~1EarnE?bYKs1$~Wsf!|!jVKA4bn+mb1FLL&9ch8v zjkDd2jhpE~+f{O}BW+M#+Obm9cUb$49?qXF^3hQyk=5^;=d%MC%%+UNstdQMyf-Y= zO~R-pRxl2(hEf(A&}#Y4mHM67bl+}g1m+XSKR4NQYDZaGTP9l{+H7AWShtxw>F|CW zHcR2xgK)moMjM7M?C|uOT5*fA3WIM%LG(HWad)gBCl+JyYoJq#vWm|?*ObWZ!*~L> z57B|quQhl{5da#<7++uz;YjOO2nrtfRz==}q*xAY!omY~Smebt8@j3nC}89TJ`nAW z-OK1L@Q9|OtiD47sYGmegA-k&qjvn5P`oCidC|_RF!;@-C|J2HXH%aB!j7AcaS=@C z<{?}2=-1*O@L*HC{((2xi8lkgF5xP&L4HA>1WHaUuy`+i!6o48?#tJ}Ki)9c0cH~D z|47qxwGCASB|?eXw?iC6rSbcy;I1d%1vESW?ld=JEaC$f)-B-M`;yhY+kf;DR>t~%l~-^H-uX0P;!H}M2a^FTfqmc4)!p4(ayK#GkblM z;I`kh#^yj^j`(!=t)=jrLHO;ZUk>^(#)kaw%0L)dhEa#X?}+A%Wp_uWEl2@c8|b+} z3bZizy(RA-SbbyREhI{lQ_~vszp>~DR;K zAh7_lizg)xE{2rjz?=|0Pn#QSd@*X+*oXHB`0EL2EK;+06y-Ol&}=l7Hb3V7&UVXX~V)S&C~|B+RsP zap75q5(rV)o0!zw$@A@A>1g&ppmPE32)hPR)-eO-Vj@Y&vJD!9fGn*80RC@_w$ z-PazZLKm!JLaLaNgT!l!00Z*$@3g2vVkw=m^m7QpOH7tmHKRh|6?4DcOlL_euZvsB zX>{-zBQDc}cC(Ooy{qdZtc$XF3X=%~n$0Yo1BfG>3846j5=NpW)R>X%j;#}an~-it zj|-ezjkDrO68E`_ZKas+0~QD;)~5wD2o;W?nKot?VXZqhAMPPz1t?5Qx-d9|wjy*P zHmrSHo>Rk%*0cecN#+^pVbc$}n!;LK#xFQz2zRuGk1Y)Tcqs}_As!AlZIPd|sDHJ% zjTpE{sfbU2z=Xm1hX-!vi;@Rppk7AI$4F39g=PYA9{L#8L5#Y7P|&i0n-$)~R?N*| z=V}qeh||Qx_bvF$NvAdAyX^8u`H0F`nD&)ar`A0(^3xWBvaxWYV z@ZF|nFWcQa=e0ftCi%u?+eNj~D;0U{cz?E{n^uo{^xX$(Ch;CLwgTl7-*#&P67T?_ zaOK4EyGuX9P5MV91dkZ;dq#K=tIICXM!YWg@3yJv#QPyzdW#;1#pzT>jcLFY7WY~h zythOT{&^Ns4}$1%A~L~w|EvutfV^E^W7E!clWuQl#UU1x_KB46h_PMhesiT1W5b~AcErX{iX2D z)f+d{17*#AKK=ermV)4<1NI#x1|0()+)pirFsJgW>gvNX3vQ%&Y^a1WsVxfwSl zS4x??zQ8h1!fD27HsOi%)B|fcj2fe|n9cOsLWO5->KX!>>uhLa^W0uhP`s7npc2m7 zQ|Hg0KZ{*J4oB957MI|;Vhq+HF)j#6E3+L6PCquUB}ZLbhz4QozBl4vuhZI~dZ>*@ zs4Y%^xH}(ElyW<%`h6fnjYZh~K{ib%olDn~*fFar?gP!8%l{Zry!DP#myftjt`v{m|VUNj`(Qt?z|0fYiOIBT$K@1p?6%AwX*f)bNf2 zara9K2Y0Kdp`JfF@>Hi{q}pqV_^5U9AjTy3sH0$R(-{f{3GSVJV#X6DX|Q?G?CwD{ z6Js1jh6h=t@+%TaR$`nf^13W|!_~#GmdcK=}fO#C4-6K)VQ7Q+B?~oY`-7883rdMaRd)_3Sh#nmFyR|i@E?m{#3<53d8!O zcwkGhZ?zOtJ2nYJl^74X3#yLorRC@x!vwuxj@5Wjlz@__mHjMY4O#(3q^89eAlHCw zTCxKZWs-*p0t_a_1NJ%4t%m zmTXOm!Vg^ZGEDsJrb^CI@{bYchg1ndsouNwu~2YhvYF5kTBsU22k%{LDltzYIj4CF zZpf^bk)mufvT>Y^*YBib+ev(hY(^_-Xf`Fif*TmfSrm1!KGC>zRWM7l<9A|H5%2d&GPuw&;==D@26!}G!>j`;;J#4STDY!zO9#-b;FjGHhew` zqGd^t(!Rut#X;!Xs*Y|d-OL>orHc4=xB0mgV|878EQ*2^hM@VvtdDd>_;R!3ZowM4 zY)ao9IL$8n($FcuNPlnN>qDyg5ax zF!*>B1*;ZB;`iI_pb`a$#LXVDw@mFb$?hW~3|BrjzFN4}E}wvZji_3DkyIiHKO~Qq zWsP%+(#>>7W8Z<&l%*%e&qKC5gw>u3U#EQV)%G%@p%6vPoew5cE%}O?kZxwXF6QQ3 z@;=1!lGEGyFd~GbvBQ;Ua`}nw(!r}(eq8d3;bafgsaOZPF##Gqp80&?t5Vx zSix+#=SdTL4Aou~`jmw|YYjPxFCA(*IuYDNvmg9I&GIe~aQoKX;nXKC@nWWgvwqKf zW>V~=T@g^Dxzy;4{T4yFDC0{4A$r9QixO%F+c^CyjqF{~+eeg8o?hE2>OF15j!5zF zt>9t?&1U;{bk<$b1T&*`JBoj3kp7jdrx!A~VK#Pu;GJ^FJxt%F57QL=0p;jgTnF;m^$kWseVy5;wWD7KM- z6$KmPfRA;g!!9C3MU8!uO-Pi{v`=FZ%Di`6Q>E zo=_TRNX^`wHE+y;ps{PKcmPXnHna#V2!i)QZyFF81?R^zD6dMu41%zY3_&9CNrFCgJ_;*qGqp*)GtTPpXgD^O$CU7TQg5dEyR67ghYR1JK|u<9P&y2bTBAY zNAHCl$r2KJCq9KYsoJc(JP(b*dZQTo5xLq4{5pbpg+DJ&i;%DA4OmeDtsG~N z9Czlh-KPg?nYm%}TVp6=H`4=FtmyYwkXKnPe{R*<`;>9OvMFXQi){?jq3NB8n%tQcPQr~`Go@N-bbcP}IScBl$ZrTW`HI0bIN z#Ad=7?VP5dG|Nqsw-J3u3^u-?WGyjBS5FMW$AVw}^FLWT5zK;93W02^+3Qr-LY-U%x(@SkQ$$E^CwA!=Z!; zV+)D`{8TPvY&5Y+eEX=EWI=zj|H7}F2(B!_xK zCFD-gK?nKZ=k3+PVuybpwMl)0@Mlr@mtk~cC#{iJ2Vkp7wM{j=-~atj1}-6*DCRDI zpqG^OH32om;h!#d5&(y7D&QwvQeaU;-dTQkISL|pL}7cPt5nPxnmZVOiF91W;qr3$ zH{t3);l|IVl|6MO_@DpnLHBY(mLN37;K!CWM4TSZ9b>Eu2ixSh^|HG+p`lfH30uQ8f9n)vaLY(CE17Qqhc*mCj3-r zk_+b7_-8R*>!yhuxZspQ8@_QCnIe%vm;7JagCks9d&4B3db(}RM}4@r;tRTz5@LGl zO7Iu3khlL<8GB|wWF6rbLqrgB7*@cpi{k#F3mONXIBKOvG|7DGX`PZr`_a`pEA2UN z|8R@Qm5bNGW3t^GFqRCET?9Nu2)5SSu$gwoFB#hSq`zWRV09ZGhwm-BWYnSLq+U6V z)YL!*0LAeB@@Bh4`fuf$ke$-71I;6UHDM4pkq;Q$-2EcL1Cn!&?8Ksojn^&pk?P~l zBnlQFvU&H}flrUzVgr@nNqr0-n*o>~UvR;`NX90UczDDlBIM^l)_}Zd@}WFzrs)V? zO%9&vxXs#qJ3kwTA6X9nK0I}WNxK)1Sz*DxY};WZsC*6cPIWZNppfp z(&qFy9&Qg7opU3k(*byIfzl~!JmKx{`rOkc?bmv7O9hNq6+mtn1*v zszmr~TZxl=D7^pyinuSv5bSkCUQT>nW#C}&fk@tO+$pQ(+5 zADFGr-@1EFKpnSUH2>#~|I%GGGy(G@Vw!08k5AueX13(SP6Xdt7JEBoEPQ{?6-vMs zV#pKLkRuB0Ox5h1aR@#{EJ_A`xndCcixCa@C-2P^Xbd>e>_P3Z7w(eF#O}&yKrvml zv#gpOKMqyT=tL0NHa>Ny*{N=gdEq|ZJAC1u{Jyz*+^`8Og)0~9GGvhiCX&Yjh>gM} zlE;m#pjtsdw|mmfZQi-KtAD|6ti7W9URGi7tGy`bBRzF1@j9{q_#7cp-b_#z^mM~4 zZgw(weyIKu1%$Xs2^ZNb;pa5z+e{6cr4wgPS%Wnk_DveNhuOqT3y|Jf>Jb=#m~Y6* z#Y`*4j3JQQK=u29yENl6AcbkF1a{-IN~j$OB~R4ZUKB(>HCLT+rn`)gR)yL6oYI_b z316EF(QUIn-KulVO0j+l?uFechZcY_U^RANTe?zcX^_ZD9-o+Ja?T-z#$a!eRDtMXyG;f^$zdFv~;7DS2Y$2_M;%k?S@bt#!wQ$3Fd&(3Sxw))$P84@DR z?|DqKxWyf08tUbT^s{-V+0i5Fdo$H;q(~l#|z0D%=Jx=I4tF@i^2hNxwu#=g1g;S+tp`& zWP2i~J9Sp{RKHkGPdzrY6xX9pxD|e}F)Do^)X=Tc1%|AOXi--E{z<^xZYsE_nRe{2 z?M>r_T-AOxv4(j`495_CQIwJkjX1=KJ;>_$>!uh>+Q)%_ks)sWMl;$KWicK-!fLJ^ z%rY_G^!p$Dum#?A>_!qh3JPu#>#y^>tpok$ zTCabe-+adAw#usOy$kZhO(399nCoWm!kTM-Xg}L~7nvWqg zQH0zSV@@#gLn+s<&a!BInC9C%O*R>AH?tyNky5*;9J-fQdl&jxgx^~-YoBg?(SRFQ zFuo(SxIjcLlfSu){s2)_4dKuDPVlfYHsvosRa`_y-=XBp?jXS7**~ZLw{Ff-xv423 z>{x^G)+XIeVKX43yVB_kLuN@HnjTtD1o1Ex&}OnS7~Q1U&4&EseArA&LY34dmUZd& zVdq{q>3)&nCafBTk$v8|aF578kL1|^V-F0yLlT+l7S~+9Y|=WR#R6(NmlcEJVi7?I zgpXv=)jVH>VNoe|lc%7|$W9HcD48nE<O=E5T2*aW|Qg#4qD-`E9Lbt0% zVug6^A}%}$je)&^q}R!+A|MzuD>Q$`A|YZe31OgAgB|=tD4&orUEo zqiY@bZahk=Z)vlRNubBkY2r7Ni3z8eJp1)LL!K8niZz{S%Mhd?d7hV{9w!p3 z*6~nR%0BR6BO6B_7lAOr6cf)#(pe@e0i|wkU;tn$9{+%c!TO5avAJpM6eh)0Gu2PQ zZ}pwo9yMtI_6*7{Z)EGydDaqmQbfoUdx z65&aTAXKU#ML51g*kasBmLP|A_Jh-w5U^Yq659#1yOeeD?Y48&=O3ku%|i_aUt3yT zoZ|7ViPZy)LaCHqRp7+wb@XkwE1AR*-C@=wZi^DxVWh;AeU=4)3sm;dOZJYKrM%R$ zIBvG=Ujod2zHMCv#^?$Eao+n{uRk%UbSa(+*&qKq%kH?8kgRm1DIu_yjMWxCg!&{X ze4}**Sjs``J%XcocAw=pgl`JpmpG4j-PJUZ!xuEYXwN*4Qg%`-&dDcyDZb(IsJAn! zBA;gY+r8iHq245fJ@6C%Lpv#^D(L*c%wMFeeM&fGF;yljfc`9xFEP*Kw(GfCar~i= zm%rWngC2^tQHGQ)!YTGo(_X_%UhF0Ahks7bk%CRdsH)czWrhEi9J{M zL>Oh~y*3^7)Yf|i)qAO#xo;EYYRMiEtDwIg&Sf|;f(t|7X*?AiIIBAiCss%Tl zfaz2iV|Jzrrj5lAQWl38);R(U^&;rBc{6k(pC>&jW5k|h2uVA6;9yJC=s|oiI>P2d zsC7;A(bt7AoHzrMq!YVQ)F2M7bFslL;e z8f5$|lwZV-<#RJDDoMOa(@xC7e_%RC(?gfwpaCGRqa0g$y^cz-BA}ai^VWDw`Qh_L zdEb^$11=T%)iz>8Y}sC!55wrs%$+(dkyc_4VGCoeAyucR8}<@4os!3vA=v+wQ$+jiRZb%- z52;C-dc2-6L0G;U2Y>DvHpYe`MrmzxI?C@nclE|KZ=#wtJCkh4p~N>v7NP!&i*s6y zS?hn?Tm7cl-*hBii7{P(7P-1sgIWF1NV_D^lSJZL+0aX&**l^Pfi5FMqW}& z*-HrA1rc3P3(j_qZ=%!sXV8y+z#??+Wa;;aLY2~5dUjjKS**4XD7keZTF>HZ@m7a9 zYJ#q-v#h^H4QU%X$;xVTP|tg-6Px$n=>?ne%h=j&WnSF}-t7f9de9ZPN zo#VpVW?WJg4FDNeDYXB7@8tLVNlN`WYTrgk8{XCcg*Z5G{kM>!kPi-pMFo||ZxOx(g zq+4kcRLyCFVpbgKpX67cjvn?-{REld_bu*%)D1&`6C@yK%64+6i_N+|N**26f5fPy z*JK0i5Un!hv{FbCzm7-P_rkCl?S&SV7+pyKjJaAFbV6C)3EL(7o1Xa??vi?;gn%T_ zL5#UbUpnw%yI^2HsYyDmCNc9yqF$q9vY^1t*l+(jM?L7`jLGz+Waa`%d^ud)9^Cd0 zA`3nG$;kwl3IbUN9eba16)`}`tpN5wq*}3e2&(Z5#(0Z9Mxm{vP}nCICni4tUQHROvg2-_i!SgE&TugY;XB45(X= zrfF&iqnK(!dF3}Y+?9$taP9X4leiyHpjmcC zuQqx#y*c}d&2s)qlf$@vepJr4%O>Zgw{l7%BEGw5d2P`Getf z<&r$U?PB=e30Dt>)8C0c_E>b=zt#zsdE&bvNdyZwD(6TANno^Bm<15md4mc8!tSwa z8UUpv3bPEzWe3chxrS7C;NFlRzbw&=ZhcWBVi8~gXKH2E-1rCPU^oRd9(G z$EG!%*fBtZprb7CkvRBPXt2x7+rW4;DUi+-1~ibnv8xrxRog>^7}vF}m{IS6U&?w> zrH7oHo8($qCb6Xrx2CaM^cLi&@O1RcRznibFv`)TRlveaP4xL0`R)m2L$4Z_z8 zMqSdT;>RPssPzijQ`iP$30X4Jo#59n+M-PE8JjoL`1TDAfZZxoZiNVZMQ<`sx{=?g zcfwCR7Ja?FKoi#h@0bPQ_aiMiHx&W*(ySzs*s=8klrIN4cN)PCc3Zjq9B>T78vmpA z4J24}7y0_^u-=xueHlxTj*C{`JNH=sO{1@NtCOgv?-KrHMIHx|Kv|`Cv6&LRg+rw# zRAoitu@Mzfq=dA7+c`CKNVtN9iRysaJsyvvANw#jnpLF)D~j)m^Fgc&VnpnYa9y2? zYM@yi(9*I^)jsO~MpfkNpMLBKi^Te{fhQVEr*BERl|*njsrmPJZoPyl?9jF^dM0#s zt!g1WM$|`U|0As7eh&Lb`%DWtA?Y#IxyAh7X zz^ogu?b>=9Y2$1itz@Iik3AKwr@&faM37_Kxt2(|4^d0z(WTvUh&4HS2ptH+&is@~ zGDy3ZC9)+O@jz&B5_ZOKtTPw?yzZ5}u7}68>x-s0E~qZFYcn~f$vF6U zXl{WCGr!28A?uob_;L*-pZLqij$8I*arwA<15lPOSvE!`pgs36a{_~KkjXi#>I$Xf zwMJ9&IXk@6tp7V0{zx~KhF%oo&LXcd*u}-EftJfmDp9CaVob(^+ZvQ08a<(IKg%p5|Y{Sm+u7@po8f zq88)$yzJpNP_$KW^|AiT-Gk-KO#XnBB1pH6P+kkipDbxz(t*@* z!jekE=WEF#=ik_9xj=Hy4c}ZJhsdv_neScm*i_GwG*-kJzI?CFwI4@6q3j7HHO#Nb WD9s@p#Vqvh^FF|EdF$F^!9M|OIYeLp literal 0 HcmV?d00001 diff --git a/.papi/polkadot-api.json b/.papi/polkadot-api.json new file mode 100644 index 0000000..c39f9fe --- /dev/null +++ b/.papi/polkadot-api.json @@ -0,0 +1,10 @@ +{ + "version": 0, + "descriptorPath": ".papi/descriptors", + "entries": { + "polkadot_people": { + "chain": "polkadot_people", + "metadata": ".papi/metadata/polkadot_people.scale" + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index 4e1ddba..bb62f7f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "postinstall": "papi --whitelist whitelist.ts" }, "prettier": { "semi": false @@ -16,6 +17,7 @@ "@headlessui/react": "^2.2.0", "@ledgerhq/hw-transport-webusb": "^6.29.4", "@noble/hashes": "^1.5.0", + "@polkadot-api/descriptors": "file:.papi/descriptors", "@polkadot-api/ledger-signer": "^0.1.6", "@polkadot-api/metadata-builders": "^0.9.1", "@polkadot-api/observable-client": "^0.5.14", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 322ae01..f242b29 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,6 +28,9 @@ importers: '@noble/hashes': specifier: ^1.5.0 version: 1.5.0 + '@polkadot-api/descriptors': + specifier: file:.papi/descriptors + version: file:.papi/descriptors(polkadot-api@1.6.5(jiti@1.21.6)(postcss@8.4.47)(rxjs@7.8.1)(smoldot@2.0.30)(yaml@2.6.0)) '@polkadot-api/ledger-signer': specifier: ^0.1.6 version: 0.1.6(@ledgerhq/hw-transport@6.31.4) @@ -728,6 +731,11 @@ packages: '@polkadot-api/codegen@0.12.7': resolution: {integrity: sha512-V1DY+ij+hnsT8IMLteSxNJC3dB0259/T+27gS2mHhqGxIw8qKBQqoxa+mB9TvWuwPkKs3RFyRCgdrlsV1atHPw==} + '@polkadot-api/descriptors@file:.papi/descriptors': + resolution: {directory: .papi/descriptors, type: directory} + peerDependencies: + polkadot-api: '*' + '@polkadot-api/ink-contracts@0.1.2': resolution: {integrity: sha512-RB/BaP6VOfokVWHE5w1NDwP6Qv4tNGDZ9lJawmraL3M3nWG1GlyV+fQxammrQSTNwGvTAVO0it77j88X5uf/7w==} @@ -3278,6 +3286,10 @@ snapshots: '@polkadot-api/substrate-bindings': 0.9.3 '@polkadot-api/utils': 0.1.2 + '@polkadot-api/descriptors@file:.papi/descriptors(polkadot-api@1.6.5(jiti@1.21.6)(postcss@8.4.47)(rxjs@7.8.1)(smoldot@2.0.30)(yaml@2.6.0))': + dependencies: + polkadot-api: 1.6.5(jiti@1.21.6)(postcss@8.4.47)(rxjs@7.8.1)(smoldot@2.0.30)(yaml@2.6.0) + '@polkadot-api/ink-contracts@0.1.2': dependencies: '@polkadot-api/metadata-builders': 0.9.1 diff --git a/src/chain.state.ts b/src/chain.state.ts index 996c6ee..d7a537b 100644 --- a/src/chain.state.ts +++ b/src/chain.state.ts @@ -123,7 +123,7 @@ async function getMetadata(client: PolkadotClient): Promise { } let smoldot: Client | null = null -function getProvider(source: ChainSource) { +export function getProvider(source: ChainSource) { if (source.type === "websocket") { return withPolkadotSdkCompat(getWsProvider(source.value)) } diff --git a/src/identity.state.ts b/src/identity.state.ts new file mode 100644 index 0000000..c43be5e --- /dev/null +++ b/src/identity.state.ts @@ -0,0 +1,78 @@ +import { + IdentityData, + IdentityJudgement, + polkadot_people, +} from "@polkadot-api/descriptors" +import { chainSpec as relayChain } from "polkadot-api/chains/polkadot" +import { chainSpec } from "polkadot-api/chains/polkadot_people" +import { localStorageSubject } from "./utils/localStorageSubject" +import { Binary, createClient, SS58String } from "polkadot-api" +import { getProvider } from "./chain.state" +import { state } from "@react-rxjs/core" +import { filter, map, merge, take, tap } from "rxjs" + +interface Identity { + displayName: string + judgments: Array<{ + registrar: number + judgement: IdentityJudgement["type"] + }> +} + +const cache = localStorageSubject>( + "identity-cache", + JSON, + {}, +) + +const client = createClient( + getProvider({ + id: "polkadot_people", + type: "chainSpec", + value: { + chainSpec, + relayChain, + }, + }), +) +const typedApi = client.getTypedApi(polkadot_people) + +export const identity$ = state((address: SS58String) => { + const cached$ = cache.stream$.pipe( + take(1), + map((v) => v[address]), + filter((v) => !!v), + ) + const chain$ = typedApi.query.Identity.IdentityOf.watchValue(address).pipe( + map((res): Identity | null => + res + ? { + displayName: readIdentityData(res[0].info.display).asText(), + judgments: res[0].judgements.map(([registrar, judgement]) => ({ + registrar, + judgement: judgement.type, + })), + } + : null, + ), + tap((v) => + cache.setValue((c) => { + if (v) { + return { ...c, [address]: v } + } else { + delete c[address] + return c + } + }), + ), + ) + return merge(cached$, chain$) +}, null) + +const readIdentityData = (identityData: IdentityData): Binary => { + if (identityData.type === "None" || identityData.type === "Raw0") + return Binary.fromHex("") + if (identityData.type === "Raw1") + return Binary.fromBytes(new Uint8Array(identityData.value)) + return identityData.value +} diff --git a/src/utils/localStorageSubject.ts b/src/utils/localStorageSubject.ts new file mode 100644 index 0000000..c71adc1 --- /dev/null +++ b/src/utils/localStorageSubject.ts @@ -0,0 +1,52 @@ +import { BehaviorSubject, Observable } from "rxjs" + +interface Formatter { + parse: (value: string) => R + stringify: (value: string) => string +} +interface LocalStorageSubject { + ( + key: string, + formatter: Formatter, + ): { + stream$: Observable + setValue: (v: R | ((old: R) => R)) => void + clear: () => void + } + ( + key: string, + formatter: Formatter, + defaultValue: R, + ): { + stream$: Observable + setValue: (v: R | ((old: R) => R)) => void + clear: () => void + } +} +export const localStorageSubject: LocalStorageSubject = ( + key, + formatter, + defaultValue = null, +) => { + const subject = new BehaviorSubject(defaultValue) + try { + const value = localStorage.getItem(key) + subject.next(value ? formatter.parse(value) : defaultValue) + } catch (_) { + /* empty */ + } + + return { + stream$: subject.asObservable(), + setValue: (value) => { + const reducer = typeof value === "function" ? value : () => value + const newValue = (reducer as any)(subject.getValue()) + localStorage.setItem(key, formatter.stringify(newValue)) + subject.next(newValue) + }, + clear: () => { + localStorage.removeItem(key) + subject.next(defaultValue) + }, + } +} diff --git a/whitelist.ts b/whitelist.ts new file mode 100644 index 0000000..8188588 --- /dev/null +++ b/whitelist.ts @@ -0,0 +1,5 @@ +import { Polkadot_peopleWhitelistEntry } from "@polkadot-api/descriptors" + +export const whitelist: Polkadot_peopleWhitelistEntry[] = [ + "query.Identity.IdentityOf", +] From a348644175685bf1784e6d08a75faa95bf7daa0a Mon Sep 17 00:00:00 2001 From: Victor Oliva Date: Tue, 5 Nov 2024 15:25:23 +0100 Subject: [PATCH 2/2] add identity to account id picker and display --- src/codec-components/EditCodec/CAccountId.tsx | 61 ++++++++++++++-- src/components/AccountIdDisplay.tsx | 16 +++- src/components/Select.tsx | 2 +- src/identity.state.ts | 73 +++++++++---------- src/utils/localStorageSubject.ts | 3 + 5 files changed, 108 insertions(+), 47 deletions(-) diff --git a/src/codec-components/EditCodec/CAccountId.tsx b/src/codec-components/EditCodec/CAccountId.tsx index 39e5554..c059332 100644 --- a/src/codec-components/EditCodec/CAccountId.tsx +++ b/src/codec-components/EditCodec/CAccountId.tsx @@ -1,11 +1,12 @@ +import { PolkadotIdenticon } from "@/components/PolkadotIdenticon" +import { useSynchronizeInput } from "@/components/useSynchroniseInput" import { accountDetail$, accounts$, getAccountMapKey, getPublicKey, } from "@/extension-accounts.state" -import { PolkadotIdenticon } from "@/components/PolkadotIdenticon" -import { useSynchronizeInput } from "@/components/useSynchroniseInput" +import { identity$, isVerified } from "@/identity.state" import { EditAccountId, NOTIN } from "@codec-components" import { Combobox, @@ -18,17 +19,51 @@ import { getSs58AddressInfo, SS58String, } from "@polkadot-api/substrate-bindings" -import { useStateObservable } from "@react-rxjs/core" +import { state, useStateObservable } from "@react-rxjs/core" +import { combineKeys } from "@react-rxjs/utils" +import { CheckCircle } from "lucide-react" import { FC, useState } from "react" +import { map, switchMap, take } from "rxjs" import { twMerge } from "tailwind-merge" +const hintedAccounts$ = state( + combineKeys( + accounts$.pipe(map((accounts) => [...accounts.keys()])), + (account) => + accounts$.pipe( + map((v) => v.get(account)!), + take(1), + switchMap((details) => + identity$(details.address).pipe( + map((identity) => ({ + address: details.address, + name: identity?.displayName ?? details.name, + isVerified: isVerified(identity), + })), + ), + ), + ), + ).pipe(map((v) => new Map(v))), + new Map< + string, + { + address: string + name: string | undefined + isVerified: boolean | undefined + } + >(), +) + export const CAccountId: EditAccountId = ({ value, onValueChanged }) => { const [localInput, setLocalInput] = useSynchronizeInput( value, onValueChanged, parseValue, ) - const accounts = useStateObservable(accounts$) + const accounts = useStateObservable(hintedAccounts$) + const valueIdentity = useStateObservable( + identity$(value === NOTIN ? "" : value), + ) const [query, setQuery] = useState("") const queryInfo = getSs58AddressInfo(query) @@ -64,10 +99,12 @@ export const CAccountId: EditAccountId = ({ value, onValueChanged }) => { /> )} - accounts.get(getAccountMapKey(address))?.name ?? address + valueIdentity?.displayName ?? + accounts.get(getAccountMapKey(address))?.name ?? + address } onChange={(event) => setQuery(event.target.value)} /> @@ -103,6 +140,9 @@ const AccountOption: FC<{ account: string; publicKey: Uint8Array | null }> = ({ publicKey, }) => { const details = useStateObservable(accountDetail$(account)) + const identity = useStateObservable(identity$(account)) + + const name = identity?.displayName ?? details?.name return ( = ({ size={32} />
- {details?.name && {details.name}} + {name && ( + + {name} + {isVerified(identity) && ( + + )} + + )} {account} diff --git a/src/components/AccountIdDisplay.tsx b/src/components/AccountIdDisplay.tsx index 3507114..248485f 100644 --- a/src/components/AccountIdDisplay.tsx +++ b/src/components/AccountIdDisplay.tsx @@ -1,6 +1,8 @@ -import { accountDetail$, getPublicKey } from "@/extension-accounts.state" import { PolkadotIdenticon } from "@/components/PolkadotIdenticon" +import { accountDetail$, getPublicKey } from "@/extension-accounts.state" +import { identity$, isVerified } from "@/identity.state" import { useStateObservable } from "@react-rxjs/core" +import { CheckCircle } from "lucide-react" import { SS58String } from "polkadot-api" import { FC } from "react" import { twMerge } from "tailwind-merge" @@ -10,6 +12,9 @@ export const AccountIdDisplay: FC<{ className?: string }> = ({ value, className }) => { const details = useStateObservable(accountDetail$(value)) + const identity = useStateObservable(identity$(value)) + + const name = identity?.displayName ?? details?.name return (
@@ -19,7 +24,14 @@ export const AccountIdDisplay: FC<{ size={32} />
- {details?.name && {details.name}} + {name && ( + + {name} + {isVerified(identity) && ( + + )} + + )} {value} diff --git a/src/components/Select.tsx b/src/components/Select.tsx index cdf6d03..6e8284a 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -37,7 +37,7 @@ export const SearchableSelect = ({ >
options.find((_option) => _option.value === option)?.text ?? "" } diff --git a/src/identity.state.ts b/src/identity.state.ts index c43be5e..97f3141 100644 --- a/src/identity.state.ts +++ b/src/identity.state.ts @@ -3,21 +3,23 @@ import { IdentityJudgement, polkadot_people, } from "@polkadot-api/descriptors" +import { state } from "@react-rxjs/core" +import { Binary, createClient, SS58String } from "polkadot-api" import { chainSpec as relayChain } from "polkadot-api/chains/polkadot" import { chainSpec } from "polkadot-api/chains/polkadot_people" -import { localStorageSubject } from "./utils/localStorageSubject" -import { Binary, createClient, SS58String } from "polkadot-api" +import { catchError, map, of, tap } from "rxjs" import { getProvider } from "./chain.state" -import { state } from "@react-rxjs/core" -import { filter, map, merge, take, tap } from "rxjs" +import { localStorageSubject } from "./utils/localStorageSubject" -interface Identity { +export interface Identity { displayName: string judgments: Array<{ registrar: number judgement: IdentityJudgement["type"] }> } +export const isVerified = (identity: Identity | null) => + identity?.judgments.some((j) => j.judgement === "Reasonable") const cache = localStorageSubject>( "identity-cache", @@ -37,41 +39,38 @@ const client = createClient( ) const typedApi = client.getTypedApi(polkadot_people) -export const identity$ = state((address: SS58String) => { - const cached$ = cache.stream$.pipe( - take(1), - map((v) => v[address]), - filter((v) => !!v), - ) - const chain$ = typedApi.query.Identity.IdentityOf.watchValue(address).pipe( - map((res): Identity | null => - res - ? { - displayName: readIdentityData(res[0].info.display).asText(), - judgments: res[0].judgements.map(([registrar, judgement]) => ({ - registrar, - judgement: judgement.type, - })), - } - : null, - ), - tap((v) => - cache.setValue((c) => { - if (v) { - return { ...c, [address]: v } - } else { - delete c[address] - return c - } +export const identity$ = state( + (address: SS58String) => + typedApi.query.Identity.IdentityOf.watchValue(address).pipe( + map((res): Identity | null => { + const displayName = res && readIdentityData(res[0].info.display) + return displayName + ? { + displayName: displayName.asText(), + judgments: res[0].judgements.map(([registrar, judgement]) => ({ + registrar, + judgement: judgement.type, + })), + } + : null }), + tap((v) => + cache.setValue((c) => { + if (v) { + return { ...c, [address]: v } + } else { + delete c[address] + return c + } + }), + ), + catchError(() => of(null)), ), - ) - return merge(cached$, chain$) -}, null) + (address) => cache.getValue()[address] ?? null, +) -const readIdentityData = (identityData: IdentityData): Binary => { - if (identityData.type === "None" || identityData.type === "Raw0") - return Binary.fromHex("") +const readIdentityData = (identityData: IdentityData): Binary | null => { + if (identityData.type === "None" || identityData.type === "Raw0") return null if (identityData.type === "Raw1") return Binary.fromBytes(new Uint8Array(identityData.value)) return identityData.value diff --git a/src/utils/localStorageSubject.ts b/src/utils/localStorageSubject.ts index c71adc1..1661860 100644 --- a/src/utils/localStorageSubject.ts +++ b/src/utils/localStorageSubject.ts @@ -11,6 +11,7 @@ interface LocalStorageSubject { ): { stream$: Observable setValue: (v: R | ((old: R) => R)) => void + getValue: () => R | null clear: () => void } ( @@ -20,6 +21,7 @@ interface LocalStorageSubject { ): { stream$: Observable setValue: (v: R | ((old: R) => R)) => void + getValue: () => R clear: () => void } } @@ -44,6 +46,7 @@ export const localStorageSubject: LocalStorageSubject = ( localStorage.setItem(key, formatter.stringify(newValue)) subject.next(newValue) }, + getValue: () => subject.getValue(), clear: () => { localStorage.removeItem(key) subject.next(defaultValue)