From 2b46938c45ed111cdf06575378d76536810f5b9b Mon Sep 17 00:00:00 2001 From: 0xneves Date: Thu, 5 Feb 2026 20:34:47 -0300 Subject: [PATCH 01/22] refactor: first wp text changes --- src/popup/screens/OnboardingScreen.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/popup/screens/OnboardingScreen.tsx b/src/popup/screens/OnboardingScreen.tsx index c28dbe9..a6b2b5d 100644 --- a/src/popup/screens/OnboardingScreen.tsx +++ b/src/popup/screens/OnboardingScreen.tsx @@ -74,10 +74,7 @@ function OnboardingScreen({ vaultData, onVaultUpdate, onComplete, onImport }: On
🦆

Welcome to Quack!

- Encrypt your messages anywhere on the web with post-quantum security. -

-

- YouTube comments, Twitter DMs, Reddit posts — encrypted so only your friends can read them. + Encrypt your messages anywhere with post-quantum security - X, YouTube, Reddit, DMs, no platform switching required.

From e2c53b5d54f38bf0824bb85db5cbfec30ab2ee23 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Thu, 5 Feb 2026 21:40:12 -0300 Subject: [PATCH 02/22] feat: setup screen revamp --- public/svg/logo-quack-green.svg | 1 + public/svg/logo-quack-orange.png | Bin 0 -> 177248 bytes public/svg/logo-quack-white.svg | 1 + src/popup/App.tsx | 32 ++++++- src/popup/screens/OnboardingScreen.tsx | 12 +-- src/popup/screens/SetupScreen.tsx | 124 +++++++++++++++++++++++-- 6 files changed, 146 insertions(+), 24 deletions(-) create mode 100644 public/svg/logo-quack-green.svg create mode 100644 public/svg/logo-quack-orange.png create mode 100644 public/svg/logo-quack-white.svg diff --git a/public/svg/logo-quack-green.svg b/public/svg/logo-quack-green.svg new file mode 100644 index 0000000..af00028 --- /dev/null +++ b/public/svg/logo-quack-green.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/svg/logo-quack-orange.png b/public/svg/logo-quack-orange.png new file mode 100644 index 0000000000000000000000000000000000000000..88c6574db3260ba034376bf6eacf0ceb4cefb5eb GIT binary patch literal 177248 zcmeFZcT`l_(l&mOLGGx)jE<579Bn{FXvsM^n3|{{L2?cf1)2s)?QoS*k~T?@q<{>P zCFeGQEg2+8RzPwPkQ}}`-Oh~O`@Y}${rg+%TeF-co_%WXs(PyGsoF>HT++C}w1;C4 zf*?$|i)XbEgs}zv^{?IVCvj4*yb*-qsr?mw4}Ent8A}%@A#*Di3u_@SCs%lmAaaUc zuI82w)*eSJtZnU`<&Vx))EqrxZzX?JPh9=9x~sCao&CidZr0j2G_F|QaIloNI;yC! zN6t$I1UOlHm>=*4gu4UxuILkJ@>7xXNI$1Oh>bAS&eIW{VY;mX^kz7Qu>$2*L_McW-A8 zb1y+>_hYCCnvAp7?v`%$t{(O-&PPz0<`yn^5BZ}<;rWrjPUhtLw{U0ouiAqhuwLe_ zSYe^l*l!oR+PQeRxZAn>FR%Rl_`hDXviy4!SG=1e_54V!1jHtNa zX;GQer~h89?qX$c!1Dk7NdLT~?BeL+ z2B!lpM5(9!=Mhd>`I4K9jlCm0bJx1?+Y#J3WeH(v2?;?FAz|uT)N?YI?7gfV_0QUa z+uZ?`=+<8q|L5`5|Mf9-e{Bdz*n}n&^{))h$=udj&)&+z?i+dkJW;cDw*Bu%sHYt9 zXlUp-+k^FN|{qJXJxE+zRvXrqzz3k#f{h1bk+Sb=;Khb`4 zv{%5HJ0H=ucl0zrqGs;wY%hmJ;}ZUy8j`f1{(4Cc`yVppsKAxEXzvcYc>mwFp-MY) zgbG_3b4yf9`J=9GE>?I;Yb&avaAew3cNZHEg1MXZ8CyWC{LwQuHuhi-?<1l@r-f)v z{(C9G&YJ46@9_H#BC-Fo7XNi>nwsAvCwPzcXOQ$Ddt(1ipYX%q3E0{hkm?5M^&0V| z1cK1rv?SDGaw<)a7+YZ6maGwneV)4f@?|;wR6vNh#er6@&Uc z_4O0=Hh167`8C9JA1J%!eW&W9{P@2gV2Hu?eE<4r`^V+jEw6du;{qHbJ^>516xE!g z1u8#=>S(2&7&=sRyyL+Bh{ya^R>xzvc6#;XrKdA>OBjS&8MlT&?1 z;?}IYFUtq~+Ean<{y;kEIit1R2ik4Pk-pJ4p-%qjdhx0|f(RW$f6;lRDS9Hv5d?Sk z%oVTr>3+jJYr>hijlqEJF?@EE##mdztO?V<_WW+taOZ;tDcdKr*D_yl<%t~kuBgXk zu7qgEGY+Na_FQsxf6wvrPy28h6M>`D|E!~|b$z}|h zD5)T`@kHzGBX=)Znm97INHRS#eX}}~m9I>QB5u1;6!>{4C1SYOFfDS}=bptCMpT^C z1$0-&M|0P33t1Q!6}KfL)AV->856Tj3D%dm%WSXjy#13IUFo`e-#CJd{W&*z2jil# zK<~5gJ8x1_Lf_iOj6l_ukuTg2E_0#lh6LDJ=#ZwiExm-ABa|IAw{7m4&6p?r#e?!} zUFox*rxJgpoiMKz6=?ftZn6a9?LeCAYhH;x++UvN%#;hil~O*BN5z?0QpG6^c9@fr z)E3@i+5^3sTNxrsLYtE0j@1(yY-oyfwmnM-VLkdV)p7fPEhcJ{s(LUjqb4K=lIY<1=s?-~!zUryCC>&msYB@e^Jq%mt3I_@d9P z?;Brcx9Viea){FK=Ti%iaZIhw(5vDv@$%2O~c-m(AL3z`Y@o`b2$ z22&L`>`4zvMxEuOO79llzn^VNuTPdM$G_#E2_)Y>4f{HP`NSyoBoExR;rKwEgbZHuxBev{6T}NZalh*(@&3u z*Bejro{F{>RuHN1E|o8Tim%&EGah-5FuEn6bcKKI3x?mY&HO?5Dt8`VVsjX1utUnvK( z4Lg6MD5?_(+is^1%jM(uY`mbw`WP92aH^;}GX>mYo2hLPkgE5z5!aGJ_hd6$Y-KgBbuvr(};R8L*hPQXXE>&5SQkb0zS zkL_#bsqyoDzJ!C|Gqh`>?nDi zO-Kwi1Jpf+4I!x#*yyM4_a?qI|Wb4)8f~m4zv*KB7BL(4Unu# z@OyFW(Xvk}WC<}^+ymveqAaPI!z>Nb0nuhXhg*Fi6X#zFt}?%*AlchrR`qV7wDUxk z98H?QOOSTBv^tZQ(t$Hc8hKnR?JLhq(A1o+B%J1uE5q+`sH5qjh3dih6#N#kd4n|P z03MYVmoCOTBrxaNalPoF0jmWCpVUu&dW<;#Qxpf%v{=)JQ=!UN^S=Lwtdc?7_ICSoVWhE@<((fc0I==5$ckrUH^*#ju1wk*u#Sg zxsh(TsY6}}4Pi}jaMo^ZKfMxCasS%7e*3ft~;HAg`!Z8qh&Zv-j~xa->2fij2;D;J1in$TrMss zXB+A>r|eBH31JS+{lijCB8axCQL5}mBt8oDpL;~50)-*eU0>woVr>c79JNw8!`CE} zbsDVVTDzX3aEkH;R}HwS&uqFq$H|i*pB3rmKXpidKUG!YL36-i^`q)caf%!zGs01_ z$($kb^N>q=U5PE!*la^H94${rqc-tU0-Fd@LUD;b<+nPtuB~lA+ER=@<81{Jf2K*S zMb+(kN5IFA*pe#65^WpHPOfc2dAI=Op+|;6Hbc?G((q<%3pO zX{fM8%s0i&smSi;2fz%OE*bZ$EbPUZL|U~-1&NDF%T$y(hvr=Cr*oiH_B=+|Rf&{3 zH%Z`ytZ)pFRDGURZ9qaMU?D_``BtDARhpElhS4taZAfrZ6fCbd*g@jud}XUF)Yrs& zRz2km68C6_qXT!C1%5H!dXA}y9`S;8^=1Y;*W4(b&L>8H?-V4`mL-7>X7pc-<)cTy zCLQIs8gg{UZD*-E8I~-`bAr=AGA~LlSzI?#tXfE_;8x9Q~Uwh$57z>2lnT6lu+DXMe*#J@@ zIc}=LAY$_@$yDuGhZJLVqE9-1u?uI&RJ&mi!V*V4r~XwiqQ0e{9?wHGMx6V1*;@Eo zc`my8c<4+qn>ABCOpJn*L=>kvE@IP&bb0u&lmL_n!wW(DnyMmp{kx_GQc#+g=K;pf zgKVQ9ot`Tb;0S@E2NiY}t+0GhVd(GJr1HEaH3->w&$y&5(vhe~03S`Yq zGT{8BDT@Xrnr$Uow`x=$^WNz|vJa^L$ngGmJ)WckAsx&4=4T2DXMymIGjZy3U4Ao9!@aa}e z#9`-n`o@s(24`;Pa1?@B2dP%MhY}C8E*&FPic@M_`ghfvd3Y`GqeT{zk!?sUvPLmT zWU>M?^L7%7_|{x-CQ(+MQjF0m{oGZyzMq$b(;~A$-CAmbA;&@OB$Fm9)>ko-eBN3R zV!DC2ts$rpuhSxf0bZQ-)B`%8JF9{k7>erb4x2>N%{0B+fxYP!y(`gL+@0kNL;lpz z)W3`>a`Z0>Z{NR5!1~gmf(ThcFRAhb(8{TrJU6KUpjtTad6B(IomyfC zB-xndmJ$7fG;tytE%Zu&sv3TZVMOVcn4DKSUtO_tcKe5e*~&;0EwgbzAyGQ!r-xN@ zGbTBJ%gWjRDX(PiHG`D(q?omjIZt#@WZed2xsum&qA|@X3r{c?ILF969Epnl8>_!h zM3DA@&eMUK7;ooTtTSX-cw-9Ho$+r%570UAF8f1Lcz6T1j>>yLdLD}gueTE^2KETf zwuCp#xFEKNkiLM9wY{XxX3Usm)6Gzk2k%%k!<-UKRj$`Dni*H|Q#!1xS1(Qd1TX00 z!ED{OpeHZr>1#W6sQZewzJj!T{-P$d7X#%CW=VZfBd>8e*u~cwox-RdPtgd`T+d;S z*t7!h$4WHO?H=WU8j^IpNUj>chpe!^g=vQM=@6v|LOuyrA}fqntp6J&A(i;O^VTZW zQn15VVCxViTN_z!O()6aHn0Y?$ov2==!OEqmoE)=;7BoiYje2Uq3*=onRft<-boKH z>#3iJe#=iV#9IYc@4-kbpwY$Aw{wrdn1z~rj;f5 ze}U|*U68HhF8b*;t1c*#HoZ0-Z$*j7iTT&9zL*%rozFIe!^Ds(F%-OYb!jesAG~r( zlz)wG=nR~nC&DOc>!Dr4*%^AB6-5`_~rw z++j)jhaVPkCJ#m=-}+vEN;PWX(Agu1@2%?07{0O-6l<{Q^6jzEZ4ckp={8J6ry#;O zLWn?3)LhJrR*gU#NGuy)j1&00uabmtPVw}o?mu^2jfqGp2#VHff`sI%G<(raJr=wD zC)Lr1(Xxb@sJL+s10Y6cf4jakleUP}cP)0JURb zb!HH$QicK;&D&HF3{dRvU#kO#?g-+E12H4-t*gBPs1E3M0gchdZccMy3a0@M(7lLL zlr3A7Ok>^-?>vDpj?c#XH#BmB%V-);v%-Nmp;@?($<#)3G1DGJ!XPl{2W9<+Tp)j9sOlM7*-7R8xd0th)!W5B18 z$V@&D7`=ya!7XfoJ->*Qn=KT#u0`0s$`{Y`cD}gqSj2P*au;NYTqz18+RVvZbaNtg z@k!@iXU=;v*)*OI5p1h@QN#(@FOBol|XUgFnVG z;dq)+3uIwpf5gZ^oCySh4`&JNK@NmEZ#Dxx5ARw=yuy81dqa9h(zmVUt`>4OE)iTD zUP5)TJM_wC*-OS%r(ilD1ZQx3qE&AT?Lg9rz=d&u1XEwEl?iA}i~2E$da}WIg^cRL z0yIIX067U`3ad?pY=H6Yz&X2wT`g~1#+L4Fm(d(70S?Zptj^T?v{cZ<^B#^|-zO_y z?bmCj1s(ej$@eu!mIV7ZXxBFF04}+<|Bwped5zJf&pq|^zMo%H zQ{sFmq+PUUOo|;5#Cbv{_dWI~4lwAI`YLLmI%g(etIB{o2J1sH@0Bbj{O$D5y9Th>QO`vicjLR-ASmI0~tkSPD zlLy!%10KKxY0&yobvAyFlBJ7ETNKnYszvXiN74e`l`v9^(S!)h!>Y{2&CYIim`QnA zKnkk;F7u+RPx|Ryz?EaLsvl$V_K9t%@@tjg*U+_I1g?-7~Qf zg@Zl7K@Q-Mh(hd0C^oTQu8-ZgqnzIC$Ia^`2S_JA)NquDpyMKbTF-Ij^*%>RQW3E; zq;IL6-~5~uf_kOUjZmq$K> zTnF-PNUYIoADd|FnbGy&Fh$A~X|oH~*IS*=;E6ljTb>u`mWtm?-oL6(8iRB)LyfTR zeUKiQjew*@0w6RBo$2(?TT88)w)f9qqqM3s&=*Rv6oH7!rwyztg<+85%&H*YN}UEW zfrCMj;yXCQ1Z_qT5Ov1e2<*vw-B80cbi0*$qAV<&Xd?%$8GV=<(#VTiX(TgcWOm|C zLJeEUZp~{6yYes!Nh7y#{wWQt=>~NWlX?CS1Jjw+nJlVqexy0DO5S4)^)RP?gY=gI zzzI*?A5?d9ip47QqIH<~1w|=zC)v19IFkgc3IN1gPE)ZeZ?Az>GzF=Sgkics<#2cv zge#!J%c?U6qftDd!ZmIO)w=MQO8HrkE(6ASfh7HtakCUa0UscCP%tpw_N42>hlxd3 zN^Z|_@x=P6p0G|wZRBlAvITOpMK!9v6Bu>*>|h5!S~G?r%Cah+r}}%jIZka-=L&G5 zS&T7B65MuWiVe=Bi^75t1{S&`Q^*BpCMaT4i!@f^ zOxNwjYZ{-}y;kttZaxyqfa>^d4EE&Wxk0K$J0PhKWkE0SSLcOncZ`s-4JRFe)-V%! zmp)+hKwV>+y8fVU)5XCKOOz8_1!}U|bDmYhg`JCovz4y8M;>Q#e?%N;O3C%TpsOm3 zoyqi*6$T`uh>>y(t5_4=5GNZq$Dl;D>y4|V>!<@f97tneoMD=L4Uk`*18C4h(Euca z9GhA2VWakf?cfy^X%v7z_J5Oc$qQhbd7br~PK@IH5!MJtaoFMTzS_WWjW8FND6KG1 zUtg;xpjAk7A5Bswr0GZ0m?^YWV(d19AxT7~2t~8D`3GW=q;xr6wVwl>R+!!C z|DNa`mb3hkd>dL69<=Fs33zjL1qVRiE#`fGQwW(?@>irRg7gWh^uwq48xaY$!46>F zZlp126_Z0hc&8|GnTl12QK&g$;|ggE@+S+`Jg%-_9!{XG0XXOe>frD#oo2ewhkHy} zoft)n0`JNaK<3DbMR*tWcL0*^eT5mL8WQwD{VG%E|I- zK)gfN+%?LCVbPA;em%Bb^ExVmNr{l5m4Q^E0XkA0Il_y}5mTfiG1h4>U?6@KG|NGOvM^KxIH?E>JN#;aUNwp&0&|7wrNN z{p;V3#rKl;e3x{+=0RhDoViKuh`z`XVF(y~p1+3UuZNY8rdNJAlh_d*2$^&$c*daQ zNV#wh+g*i6^W7-+vmhL9Xii`)wy$@-($ZT;F(IQ2wBeQZXEF7zdHxP?v( zivxJzhCs^mL3K^XF0Ho|@PNR_|Dd_HFyYMm4d!444IeJ2u}#-m}(^>4K0f zpoXNBI~ep}3!w<(txJ;RmF|&ZB&uKec7BfNzTu*JfQQN?h8n;~(NJd&;0EGH7|{Uu zJe$Bh=wAn{rd8$#v)4v3BfOw+1vSE0AV=h-&elwBuHpPoP}abtL#E$!`*{}Mk=$xX z(d7LQ0D>qSWFY{^T_Q3tNrl$`9i|8p^qw+VT+B$Qb+uFnwP@!8O-GyXAe_Gl1&fJ= z6hUOX0@Nn_Gd71-jo&1k4!v?~R*1;Lx}`Y9qx7PU^?K9+rB{J37>n7WCfD~P*yYgmDL>d&?M<$ zyrI*Wb?SqPk(VDLfiS|{CO{3+C`zn|ey)QftDQ;jDD!vW%mS00m}bGn*LBq6I35L? z(m`MHS8q6IeW>TJZvl|J!CF>L7w*}RT$sJ&J)Tt)fi~KO>gsMWz=j`;RxoRiFfM9t zsn=oJ{oupea7j3DoD-BhaL3*CnRxCt#V)kim}vtvmM;%>M4-@!g=k2=RW81{`1$_( z6qOUb@U!kaez*1L*%Dx12-5unD*n3$5ovj6rnO@O<<<4XD9V8k;!gq{uB>ceHFZQ= z#Jna5I3G|Qy<~djZb~=gZ>>N3V0O08Sj8LWio}D74lOs^N7J)A(!D9h}h}z#nNaM|Hb8bqLYF_T5OIeD^!rn{@!J z8wgs&jaUQGECL&4-PMk;G%V?ypgCjqThf~+1me*f(}U=R#-9+ud3S4B)m_*VC99v| z8Oa=8+N2yvNK^-)qY`4lJHnSsBt8CE$c;oD$?qlyx_yjPlD|UD7W&rca=4?08&*G3 z1lZfm7^XL9xN%=rk81u1-#WnQR%M_qz)%cHz5%dBH(OwzbZ`HfS4JRzp$47)ftuKnTd+d`b%&EMH$dC; zKui~(x6}S+3kG7K?!s&6A{048CbbRHk*qu6yk+GLtaH>hB5xWjY6`6GuSOBcoA~S6 z-H-r_eIhDPQZj+KYoZK|Xbmj?VjBS;Ig*avT%5Gs#(TI3?6oUHG7uh~_$mYbpA=eP0xoomP7Ib!=HgfRe`MR|d=!)T*({@YOl zSp;mv2_*9oN=;J0(ZmA1zi$sdUvNcyrl9A6s@YEs0|Ur-=*_HX1Y8IX7xFfS8nW`_mM5W8Sqa{|Bad^EDRych6j`LC{C7sk8=SdVr zFz80ic+|q0oO29QG7Z25j}+AwDuF;fqdNEuoCdwG{p%`h7c!mu_wBuZ4PCcG5^mvl zz>f(PKY<^AIFP3cgC5eRKB)`y-X3E3@I9b8gfMKJ{I8TkfHg>!0hN@k z#a35AWoWgYQRVYf1W1)nAZ#R@(bUBXTcklV7lzrL>Uj4?$J2HFI^SfJu1RH`=33op2> z=WJJ??P7H8354ucL4e^+G4MVheXpG?bdh6m!ycjBwl zHUz0);64SC_k-kgnA^BL#_vV)Zk!L|F9~DTOgt3sPuGowxR9XyGin%v$pm`w8-sy> z=egFu3&|=j7rn7E^6|Z8L<34$@>eiuJn~S-B(9L*$XaMuASX%5#gyeiM$F>_2i&Ca z8rG?t2*V=F&Bo~E|KB;+6(%L*HehLam@fXc0W`+ePozBO2coHZV)R!)U}xVPzqdd1 ziT$X@hSb1gX|2ElWBK8heg-^7mdX6~>H=~2F6+ATp=W|wl@pqE-=Q1aK3?VkH%8mf zU0uC_W-`rxLwx6z_KhpS)n*;epO2y%5dujLc{o;0`8-q7h4VWPqcf)Yo76H>MKx(P z^!6=4!~gCQk%vy-n4f7r4THtGq2pr*w8YFu!D((zRg_1Ku#zf|Qm-(8HZ6JSwBLoe>uRtL^egE6C$~p2q@y(M4qb8157%c7-5ayoa2Uh&X6l=z|p z^ZTi*k50WT*FVH--F&0C--FN6p*J=pA*-vA%g`mFiMimjNzcp^E9ltDH$URF>i6HIj5=2^*n{eyD$HuQ|=AaW*#6xlS zI5OM)LP(Lc)JxjFfO`aa7a@v&(EGhB<aFbu6B>w zlC~vrHNX1bhHbcQcDXCOkCzOwEv^7w!rdNOsMqbB>{v}?jHM1EZH;`-y*c! z65~Am-ipl)-mUwoJAKr1@h=KIziD^8YLKmc40X)AV3PlHwWfFvlw}~v1*er5lW!SU zV<+ZR*ST;RRA=T4og2va(vD`glmL4WxyAYI+tivi1!$m=VWjs+t^@T67uU;E`HfLu zdT<_iK!|8u`~7pn1Jsx1gDo3@OJDUV1js0b8+4D>k*YVJ2i&CYF*`b8AQQ(US-m3M zbpmO5sWGu7*uPTB4CY5#2H2A6&I}tR7fs8bM<@1Z^SAuFc3~hRK??Vl-hXW{zliv5ItvdJ!sygy8bj3TZ&?Z zyzzVWylku4`h(PN)GMVfD(mM&rQIns6fctzu5qos6~4zNTvXTNQqAk6LBUmF6AoW2 zw?+wv{v=EOe0 zu*V$;NPzvtwg5C{5u}7-_iI0iN4R?BI`{+;R9%0Tnj1%nZKDnmh()hK7gxZSQX7P7 z9Z8F-OR0Odm3whl@TO)N81^D*TdR$=VWfebwofNBfF%%2#uK%~PvR!@1L}xTKeMD) zY^khPPBBAx+MjPjH&Jw_s$%8@h?Hr8{1UySh+F5uFoeP94goS;EJs{4s~ z9D$u`PE4@yI^n7M6j}c^XZ1{aF;v(Pg^~YI?~MTQb>XiY9fFNQ!2*oDTREwwuIL*G zA;d+9KV{8&m_6(>9dTJ0J5dv{ly2izTOLMLNJOrS4#}At$z|BFw*Mk8EXN2*)Vny3 zb22^GsVLhm2||L*GD6zM;sR`Tns1)zLNBZl-Q5B$HzlrQ+Svcn?c&0DN@62XKI!ao zm0bSy=$`D$$&EQ1uxdyRa8y0>dRr9DH;NzQQ?U;yu{$HwTt)6TCo&g4G7#Tz!E6m~ z*_RPgYkU_j?7TDC=a=y3tK$3Vp2_=ruQzK?K0W}loX;vx%pTdBMChkOR(~{&TCx_E zZl~pzp(gNT&!y}*zYA>rWt}U0Q>g}u_Gz?*4W%SdOb>2GZ*}39TxW9KzuE_gP zFQc#NmH;<8Bu?KvbIo|AHxg&#C>9jpd_R8DBLFkDU>b=_~@$EGU)KJk#jer9=nEXv%nAsIEk<|+%R z+K$h*se%eYR|iO0PN}+$yDj#T1JAWvD-U<;+6Q zl-p7S67z1WjVEYG*mklNbU@}9;x~$3QiUYYOskot(h$>}89D`nkxLz%TWc2s@+%aJ znsZHV%Cqj4(YZ6DWqOUV?Tx~?_g%d?f6z%^IMEy1PpWZ{Tf7Y6OPpG_#MRjI*&d=L zl~Q4l_wY|0QO&kqQmxCTj&5(zT|H$}&8*A1^`f3K%=i@2L{Q>Dqw8te$Mu_H?)AaR24R|@zCMkM}$7LCxnD1`+@^!p$&$HcEyUcBO znO|->sd>f7|Y6x&K-Nn}0Rx#9y2)5*WQp@7C=g z$ZXqpg>5KTcxYFTQg)oveGe@XA#+gl0V|g2Q?a_Ezzn3eDlFMIVtln*` z2i{nUOIExg&2bS1OlXoS&5_1MfHO>K8D?Gqb;h4M1p%if0;;R#p7luRR~`EAr(}d(HsS2DN_6*e&6%pp$(Oq>gSP!|g124* z$GBnHa1R9_Q$pK@Vfoy3E;OGkiR>OHT7vBen5`+0&9<(K0kF~I*r_Q zN5yfw6qw0Pwo8^{?r3<)r*QwL~mw&ZqO{#phJBB{I1^KV50XR zqiN;O)Dqo~1}XHf6HgU4XTK`yd6=*$&!ukZBdF;Z&AWV)+$Eor3Fni!efb!BBa7F~ zmB^`I5OUB{)pbVFc8gk*KJ9q9P{E`i)ztuX$!_Ry6qYbLyd*!PA3KF-KIS8`&qG4h zQ9!f)gIHUs@PaV`TwEy3>5^4B!vDMg&3lqx)NwTsz(O<+-=Kr@-8T@g=S_$zbWY1* z_genA{OE<~c~0HQIIgE3*nKc}rqvRAFq+eT=E*-(HJ;()Q1fK;YhBEd1$p>0ZLGjY zOlcgZoQo!J;~*}ew5_Z0;{thHsZ5zv($+QWxZK~;B^&ihV)0c@?kmr}#mLee@S>}r zK5NzfY|X@bzmz-EA${+-1fz$;(Q(Zw@?^;}7hjylVebGlZe z?vcoe(Y4D#|0Rdy$ZN$ReL3cp0_ zt7OrsiF#7?H9lJvnm;6=ZlLGe$xUs}{Uk4EIaYf+SlY7CT70g3Cgf}US|>&x!=*BY znEUubwM|enYvO;nSpKlQ}YV3Vy}eV$Nmyem{h$KT2Fiu@y4X_z{5`&Rf_XP&(WwO-~HU+C=-_;R$X$kj)@M@?F&gY6$k46 ziCWyocSF_^hq$ZZoe*%q*F3NEvOirS+coK5MM-3$Pk3ul5ufgPI&`MgR(FRENEA`W zvM|!IX~pN!3J%SwhRbk7idvHqjjVV;*pWG&>WG@QUB<0s_Zw#yGabU#JxaV<;j>(6 z-P}DP^=?#7@TFY7;p0myh;_#<# z<92lFj!X8OgB7RcvDfy^cD~tjp>qX#yG-i@@{Jp`drj}m1XictojM68eE4G*zt0Oi z+DD8Ze*L28eX@J5I6V5>t~B9$fQp$D?$j#eP>8of6BMjb@8lxEWfAbA;aP! zM^!$oil1+_x!B<9w!`w3U&hsV^Ruf9533vt<$T%f4ES8Wdt<8g)7mY|&rckmvlUSA zEXdFWE}zVNALl2&+d(Eb&g_R~7Xm{fe;1cNebKe(i!y@tfm4SlhoEwu8Ej|n;w?R< z-rRi*XEj)VfYUakpM#-iS_b~XfF$b<` zamNm5H%12wf%IhU{JTHva|ReX3CqP`hLb9%!yS1}3URgzsh2Wcw{Hx4{iM}GyDbaz zKKN1Yfv9eYg?G$XEM#ZBRk#Sd5TcOvURfvK~U0hwFZKl(+nlp=%J1QOuvQs`X26twB6MN)> zXXvYQ{kz~B(B#F}FQerBd1;*&X|3$z{1Rs)9qy&%T3Z3BSVK*`Ui=MOxXO0{W9?X( z%At22d6Bi^%X`v<$xr@6IYVaS5^I{m^=xO4?Cs|Q&-h_}A42!PiIO|to5WpXcYUERyTb#ZMwAIgVqNG;q0GWvb| z3e&GN^Tu8%rJu|ZM#7kf6GST_hzcl9%wtYK%-D`vBtMfpMhD}&4fLD8Pg)p~st zVaE#?c`@ORLV&d-GLkYq{gdOA?#?6(w}_FX=BAYktWCHcdx7ss9HZVTz&0{&5r308 zD=|qoXkRn$#M{ae(eU7y;Y-kUo-y33;=rAQo%pa$%B?RTSq<*>fWaLW1i7-{MEfq*wWuo+oB z&*mq6UPwr}yjxsdTqQ5xNYtLc+n(53I(5iH%)u)B!lNczG$C>B{b!G8@fGheJ{*tGJ8xY+y!1Kb^2j|cL^Qa8#v*56EkI13dz5Q9! zWcfld%fXn?*4e$&ix7s;hCSBpM41aY~$jW|V^iF@|+48~b7^sTpUT-cO z2-WpI4b8U*G~ctJhncG3VTG1ePrv6m%a>Wtw>7J*59?I3z+Nq_`heMFV3U8OmKYPV zQcnr7K;n~qrTfs%(6ed9Lo5{HBL8Z1H{&kT6)L%swE4D2C#s&S7dqUhr`TuE`HG`| z0SobF!U;S&x_}-xYqw|5C}e;8pQL;b9FZ zJ;w&|tT4{`wYrQH_9-UBmK&WH3Y`+K4-Q%u&xuasHmdJc;YfUNttsb&JXnbs_5ytH zD-<7`j6lX9zW!}NkHVEoj`bTa@ISf+aU|wnAiZfC$xw$_X5Gzk9hjU_v#0@#aRN<- zo(iNlqb`?*kwX_ z6CJV0^^4mS`A$j9Y|Oi{;~xr0Ku=&JN%9^r(7UIx_m|=dZET~Z@Be#wzVrD<1zi5r zA+v+O)S|TKwcLq7xuTToe>$PGV*Ft1rE=LfzlAaFYUvP)H#vjEZ2k2ufd6P8Wt1Ot zi&^v#hDlvbe2SS9HX#o9UMJj;sssmaXq_t;pMEo`nsssm4q;_l_>0BL#b0H55{PT&F>T+_OTTPgtSE5lg2H+xr8T|8&1< zQ7?Dm0_h?P+p%URekd&FYuDUu%Zz4&gW90%7_GqHz0B*3zQ8PIdNm%~Ywoq}hy8<2 z22^r2cKpEHmu4W&8R?-bUzlBX-zg;Ymvs3Qn9mV?JX=>hpv7=Z>=x6U*}9p_gmyvW zRwmOmTrOGr*e!R%ppe{ud{2d!o$2t<0?DrrUmxzR+4knum4Z5h9QLdmH2uXIwr-pE#5a6VTw>hU|vy-X>$ZhL%qig{mPo~(VPZZbXL zk#3_L?gA#X%=!8wMZuM@r5MffSwx2X%y!!2@T6N}w0UB;;N?Gkj4#k3Ez5GE5zdrm z_GY<{fMw^pkG|d?=Wm|JWM1wP)`M%P=RLd2ShwqEd6fPMD%lDLX8#uG9(>+Cn1pdao7@|c zs#yz#eUWFY$||4~E50~sA0NAOwlZVkF%M%i8YC?4pQjf}niKUC@5y}pSNdgKxN6T7 z%^&=zKVSgn6yae+8Y_QYL@r=0VL6y6+%r_pFfQadup*Xl-cv}^iC1-+{$?&6%A88~ zJ6-f-^nNva0qF@V(oGK&n(?3et<_#JrCLO|W7DbYXRwZvEHqnvXgAGIs-7-SF}9*j zn||d!j_Ah9AB1@X&M^}!7}R!gxHd0kACgS?VXIZ3RcRr$`!bW#L%?UdiKY2WvBL;@j=X4`A=-8?_-|Ljot|@c;_6t%gGbc6ZzVL z!1JlrOY6zPeD3|bl1mQW%I4`A^l~q=Pjc;dW95#0aE;r83#|}^dlS1EXB+lfcx@jL zYPiv?_ZWIkJ^lb!#3Qb>(5B9!-7f!xy)J3`bqhML;Pk%6NG(NaVX|~E-Fj^?HQY#G zWvSy7ps!`~$1)DRS|C-q0W<#Xs>i0!5Gw}mKVTaLNKZq|03B{zLaBJ~)5VYkPEMgu zA+3j?5B5(6DjfPP6~_Mp<47xjcAyVnA+L z*ZoQxaVq*?p`XRmwXiAlFYF|9<=v8X-SF?nD^)n0dKhjLD+vQD&vcmeNLs81YbBNH zN|x*H3>|!bz#OuWV?A^~8b_f7QL~Wb=Bh;94|Z?URhhH=t)n0u5ve_=wB1J4Cg5|gnO z|AMdh^c`ke=fq9plLRW(Y=ff;uLHqorCy~BaX>~m)bTX7b;CBvz4)WkAHF`zJ^?KRk zOIVayGvMG36s*6f&$GMlF@)~z)Fk)*){OIvcjd1-R(My)B9b=$HRoiZL$ZXh3t_bn zpD9>2`~hG{NXyqxg!c2ieRgq~^HpV4(rx}Hanz9(g2b#2ag;I?T`Ruab|Rl)#5nJD zx9jzmmBN?cSx+-oU(I%$mF?m?U7!~{s~jFM*cn&gJ3R(BcaLc|cL^VQIzA4yNG56y2SKxEcpfSFijD1$ky>VQsW3JzP-n zmVM|U!8`e`uQ0}bcH z4MPjBYKud019di2o`isFaDTBYdFEW2c=#!a&_fT~(!kF#yG;2{=4Y>@Ehkc0(n08U zh|FdO#hZkDMYuDjKerD_cS$2XK}EWC1CF!R5{3&3I&U$425pkG34RXrgwD=wc%_oE z(^K-Mcc{~LxK?VhZ@84%($e?1wGUczv0Cms^u}-6+UgHfoM6V+OpJ;vBSe;t%Dh#h zQib;ia)J|eTyjMij%1vgY3tqK+<3^uy|Df3S59$*jpq=;^H{f$`<~cLc?zd@ZBr-{ zt9z|oFqo>pwrMRf>`8uAG`~bWI*pm)h7vDZ7|{eoc|CCv4YEf?}fBf#1Z@=Ak zU<7CAH05;5`&0SZa)LqaP;}l9dVfS*Gw@Cm5yd*yKQpEGh6r!v_#j!?=d0uvm$z%5 z742)zwWQ86($EjC5HbU>2}u|rW~7SV*an*1GeN;2VB{ytQ&`!)4)Z_Kt0FV0|HE)rpZEMCOv?ZK zTvcb3j_7lJGYp%GX8!!{)fM+#YE3Z9hKR^X0q@2vJ)H_O*}t~@u9)dHQFszcEu@S8 znAC3e?IH@bsYuxRRK3}W1gi?v8DtJKKJ@uy^LEUr#N$D(nwoe(FE!!ibpo01f(sn< z2CRH`T%0!Fx9U(NhFN@V!vz;p595x?o9%-Oq2!3yFDIO9_AAVl)06uJR4X=@r$W2p z@Ee72WRJ6L%Ft%gXpg=s3|V>LZjJuNPFC(ayegK1>-e%&zBNFP*@o2*%|W@J?x-)m zgB%1*XbeQiY-ZANgY^d>dl?AsVlvGff($wIM2RH^VL8I5>5!F% zznL52YO9uZ{7e3=+pWJTm%Hkarr)1#$v9P94;-SsJIv?&{V6Sk94go>mISw_E@BT9 z(3C?zv@A9?x~9CriFaU698CMlAe1ye;BE{BL4(6T;e;E`F}!hg=zVZ+(4J;CUB_MH z2KCfRQ}1nX+uNe#?4wyc(4bYE$;TS@@GIv-h3TPF?u+|pcV!jHT(`4dnf75|G0P2Oh5FS@qy3$Gpva?vTBEXV zYD5^i@K-+jV@8B-sC+u(cuTB`g&~XqBhSMa(D*iDcJLq!Fndi#6o+MgAYO?s#;;a{ zR)wD1IMF3&+@R7UCEQUtPNn1ed!Yd1fZ3|Z@Y<(L9okI&mcGH)@Hc9?aYr{y61$~T zXF89!*uWi6i__yr9)x?hvOF0MUn`p4eB}2fCEHs5Q+XQW<^tey>Z{?&lb9jDq@Q0d z7I)}N@RW(Tm~b@AXaL`Aq5Iet$3^YDQ=z7?Dx)>U3GQkBq~80;%>FiIZZcAY zZK|dYCHFQOU8~xL(a?2V*;F+55_K#=150M8U?1H?ml5Mor+)0nJ8Q*(;zy-6A?wg6 zD-ndZ&ShvCWpWy42F%}`mNoyg;2&c9QsOl-Km7Lm=hoV?TiTRQFx7{&$enCh<#TOq zbTK_TX@8P!*}~PYyy}bo&9Fqc+9^vdAa#~GKhK`htgkw@H5vi+Bbia~MxuP&zdfH| zi*V81Gv>+WsDUJW-Fdkhu^i2E(=rU>e4PeWFppd5sDHf(G2izsYsic9vS6*6b+_;u zxNb8w5aDgHVwLaLgnsbzK;>%O1=fe>gB#~+teS7#)X=f0co)-iQ|uYbjYNx>`|!Di zIpb7%t`4bnQye?bO-P{kpf~J+wzsxqYH#$1GN0H~P1W@$)FNmm4wn=1nYxW3sdFkf z-r@Jo{#y{P(crR&D@PUD&&Q+evRpysk-XOT(mhoVU(1|24*w*Gb>#`4*Wp_UIm$#0 z-NNY?&;7o<%(hl9b$-sWIRPjQrlGV0rW~kjxbw5_;wp8gee@6_%mLLCSv~E^H;)$! zowhK&_J7!V>wqZJ?|pa>6<0)7kPrk`0TC(b4hsYXM5I%Y?igw)*F~gt5Re)`y1Rx{ z1Vm!!VSu4Kh8`N;dtmpo?)Uxqzw6T9q^PBA$FlWx8k7 zc3dN-K|CVF%%9gR4%{>#!9q8F^x$F?FNg<2!!iIr2hs}I0Z7gp{;uxe<8)etTS8AP zG-GTNWzWDF3pYkff;#54$N`BL_H_OK;kI*GD=6cGq`5#YI8iC<@V$yY6%;B}ccTI* znIJrt5?kAPOv`LWHtoSDJk0lUS%5JSh*Ao)Ef~0A~uzYH&h#ugQkK7VvE(tzpy8fN)d!>r0dtI68Q=N`Z1(#mf8C0Pqz9r}VtA zhc+oCK#`?Q!AxLB@pq};cabenDnEo~Gd%~- zf&5zT((euaX=WY^U3JZo#eKjA=Fsws{E#aEj%dN2IHgElDBu!#++#`LphnwIP7AKQMgZ=BF-+`X<7w&w17#)&P-c>0 z2C2)|J77FvrF)9FPF|Hl(r#c`>v-7JBP0(>;tps$0BPxoQx2TkzO7YoAk+UX=`O!O3$;1$XKU&b;O7|R&TGUVNJ&9pmhjlECL7avHzzsy zkLn-@qGLXYjk;PjU)pN5tA4AT#6_|dz4wcuQq23Xw3 zP;NcB(%pS+)+|Ukyte;lqyP{utW2mA>%ugRt3R`q*TV-L$JA!Ut~U(nB75BP^|Ce3 zuOo3pcGEpoGpq5Ub%&>x+JToW3&7Udcm@v?U?+x^kXL13?0MR5`;sSz17E+eOZ5>! zN(K1`?+J)hSO`?yl`n1{OmR$dEBSs;rA^5(^C0w1-6DJa0or;M1sm$bvJL z`0)NOT9$D|qrtZJnFJ9%u0)2^IIAQ|-2HQjwmmrdqH}dG@DW4YS~?F9>AgQXXR`8M z2YUaphT)@`H#3-K2o^St;WY!yQU;z|hM(Vw<>^F4-sJBZ{=2SmCa_jF8C}CJM}Hr4 z9BKGZu>sPM!0(~DIJHTZve&$0Sdx(6I7WaUOEaLxnT zEGTIb&hjy#m6G1{AE!fu{)P(|Lq|CM*um$e>s#qFtm4iVhDUm;^ViT^7WBSiAWnWc zjg#YcyfSi{AWnjsTm>jh9^W2A43#I--j|JM{tYsJ3vWEX^q6kg%+Tt9;}njN`R5#l zqawPO1$nj-T^ary?a|^?sXy{eDb*O(t4PZG51AMtD|dQaLC9k|3txWDqnWEYBXYna zq$Pf8YuGr`PX4tuP>R#Z5o`^9y1xr`a!W9Tzr^oaHc$^~QKIvyNy6(eBX=zUQ7uh) zAP-*o%*oz>HM$^%R0h2FanCUL2<=lTuD!||0yz}?e~G#IJbH=CzoDO?f_C<_ov*kY)c(J#Ir72&x%e(WYq33!})qwK4HiguPw!AI?j5D2NTzNg6L_bZV zgRl0)EVN&>()K?*P9`7|hDcC;DBc@A#6l2oy9$@?CPjN#uGPAWV68$XB(G`w^*_am zkQ_2hWq}mZ;0&P?Ca<`-#3fQTI*%luIZ8%Pd7MTs5yXMCr&u7In;?*l`L-fRy%Vxo z$}!PH+m^4Hwj?wf&snGCR=5gu^29$CG9_*P+>sCK!u;&vW*8b9tnVwlf^rm>;sDt% zz-uvTj;?M&tN!+^ggqW!K^2|jZudZ`Po6s42nMtH za}O*#8n;=q>ZX@A;#n{;4d`xx;$ROe^l9O6CjZeJJ7ZFDy)y$&0k{U0ON=g2zbICY za*Ut03RB;nU1f1lE5W|*fkKe}-K}lMa)7Dx6O=bP5OTtASWtOR>R{(}^x>~Vmy7;m zUv+IihYM2Ikd~}x#>Cf7J~__Nn@i&VpMDj%^RSZRZ-GzjI@8l+4nT;KQcEc2tc_<_ zk|k@Pg_SCYwdWuWMAhSj&?6oPl5IBpaRWMO>0XlBnNs5vCMebSt87IoHu{SW;Rb3M zNDzyUcHqZVOIKYI|K}+I`y*d${so{t%}H9CTuEDRq7KxYB=ht;sry3@_Y8)#Obw6k$~0KekL zS~#0fyIQs2sfoeD+=metDx4awpa9T75^&r@BWKjev%Pq5HWJ1_h2a=+20X3+cv^rd zu>RJ#;7#RZDoy z8la>j_kPu`s9n+|fpQf_C_2ityz&bR(*zkd_kuaF)>QwOz4;Bl0M>jBuiFp&k``WN_W)fC7Xnr%o-@m|9q5~JDb*1i zzOzs%l0s&k^l!D4P=PYo1jf0)rCM?7U1L^m&#?85nb!jKHWHh_@td1xRx9Ca;hSQ| zMSlHN|IshXZQ5)O=C3(CBR4+5#Ek&@y^bq7OE9w;xa_htIjcL%4GyzE9mPo?#v?eiAO} z7{=yEVSbaRMLAwRY-(Lz*-4_vdAWD-v6D^9&pVhN$oWdh`KN!f$o&2X-rGK@Vlf+* z=y9t%>h7O|+51^D2Og|~NPBPSd7&KKi4-b@U*3kJ$!j2yT+legD?0Kdh%e+HFMv!Q zrVrnlfYkm$PPG#ozXNnA&aeggh2+KqMSY4!XU?Fxzl#KqfK7&OVA`Dms5!t$L8=p| zgx<;^@luJ?j|Ng$Z0t^mhQL@Ugb5<;&(JTe-AM5*}m#mf+n|_W` zu5#IYc10%s{^r5eBxW|#rMkogeb$ztikY@XWJfW!k*;};vqZ!Lt1 z3Ncgc5x#0)Hb-p8cKKrh&#bNHt>P3!#-JnHbF$;Zs+hc2hCVRv-^#1P9@xf9))j7k zTlg74QEhFc>JLXmY+X3D^)@6J`-REk|6GEUrYo53qYQTNsDXab}vvod+;Ros()mKbqxkX?$u}c5qYJ z#O%F2n9ZhKKw~50qr>jYwg@J6KO7{5GL+DoGVn z@<5pl{v#^bV>lvw`TZ#vPRHcznKo@U^V92RjCZz=JR`5)G0V~iRbA?FUA>P2B0{R! zXHIat0PyQSr`?UWLQ7D>V0G%$Rd}%&wNjO896%kVl;s;Rk;^VspHWUtgWTj!I(EC~ zNoYc5CzB_K4LYahzlgc5yqMXZ3ZRz#9%h@VGG#)UR!~gBj`F=JML#hgHYaCdICEHQbZ- z_1ynxAz$1Z4*ncSp4yyplv{$dw$Hztw&f0c6xCbXeDSqtAou!MygJx! zV?U`+8cp~pAR(ms^Q^$c6hO~mK?@G2ALxVt{iY3hf7MA=eGy*aleInFT8`r0x{SuX zuF<=*wzmRThT;pj(dri5RbdXAgH*l`fmD>%k7-X27>)NewQDY>q^4`41Pg>clf1$k z%MC18r0>0(%XB8qx>4ueI4s%qQSvlal-^c*#xE%$X)hpo@)f(;<_4nGGXIwUAkv4{dafbFG?3Fl6b<3vCn}gzRnJ;E(*#$nSD4g9eWbj7^2h6LJ01vi$D-UEbup+WAh2f=;|E2AC0-#R>TKO-$arOUnMhxBzaYGf#{ zcfPJp$3ymNcZb!(ZO-0IaDcdL*({F+AGiJ;IQ+o@`UZ}tH~jcJl*D1q2AM7`ISw0I zMuO7yIDWaQ0ln_^dTwZ=yySO`DoSk>O0}5S>R~>aoN5!Iy?{(p2j_FlceUfigB}X- zdXk<-HeXyCPU}Dp95%xNvg-hV#&NVK-%Wju)D1mbX^U=yH}4beHB|05L5Asj1O^A(H!FFtfqn;T zHD{txrtZkG3^wkj%7B8{GLpEGM*hZaPYkoDWYcGNYy?9|N=t)y@lS8g8&jB98IN)YpChXdd$_&lKSB>eR~~QrJTk4D z^HZ@R$xf$XDwAtO#FfnQ|AT8uKA-ayvRmvrZ(!piShSfBdU2qm? zy!NC`gZZ6%i;nvK;?pr%htHk9?T%8T*|!%bV>UR}mjRQoA1l z&W*fw%|zc<_7BFAmeQI}YPe2$j@o?2mUKnN5o9m;r&QoU89`xCMi0lCKWPd!AM}d(6 zr}d0+UBdY@cam6VspTjVqv^c!UT_aXZ&gel#@CM^ z!}dQIcPdK`XiAkrllbb9T>5nTI!nl`AZiH{a=GN%7a_LK+X0NCGs&+A6j&q`HlpSb zP^>C>ZW(6cC{3SVxWpXna+sGRzz5>9IA9N2mkF=2XD4q6#S(G8OU`$ZqtLcvJO>%q zx>X*q4=dixK*8efWmQete&x?;qnT}=KyzP+)TeQ7G&eh>+7`NBpU`=~`Y`bL=S0SS zTjYds`RzGikW+(V6h#eN00ZQhwUq-5unuiAJS>bz5+A)*8o+fVC8D%4^3{9OK3Wma z3w)lB_~HA_cNCn@GDvbDTVi8wsvJM>0Zn9nO|NL9y*AEAlI&uk9nnq4rATU{t+5H-}5 zT7=!p!ZW##(U%Q;XY%UMQA+%bAKjgzeC4=0GxAm=omEPaOQmPZ*H(Su`y=c^=Bj1j z5@M)G*jpuF^JA@ch%NlPt5T07%4FYE^`Ykr&+3USF< zEaH3li+1y)z30r$Yf1K8?#Vkor7Y~UCb7G>LhUOZxx5dK+!P*BkXt~;CWBJH76k&E z2*K6&2S`^Lzy_a_XJaJ;#8r>hLdDJHx(GP~#BZ_CN~P2{Nx1rBcxe+Yc70L9T5xAF zYXo7qtMjV2435@s`zd?f!xaaM;;K15;-J3x@PuA>tm3@~YOvAKqJVl+=w7p{>4&Kj z#WK+A|2`l{IMjRqX_pnLXx>(Ukkava`l3xLgxD*D0Ile=O$D5;?_=xwbb;bNIjD@f zZI+J~%eAcSUk_XY#t$&g_nKs#QtWuWf&u<#1-qd1T-CW3hmfef5~$ zT47}`exMrX*l2Lci-G5{Yu)Dxeg7X}o`}ielbcfTjJUnzN!2MBIZ`?64#0|a8pmU zbIh(3-|f1LRwYZn$)jYj`S3&@eXHLnuS{2E%qo6PVb$vcJ6f<|>^yJd2$2d7YIY zU1@*Z;SVR&9J>BM(8k?eaXqaH09?=~9BM@hT`195pV~7w{PmSyLZ4|Sn{0Vc|EryC zw_(o9+l9EJS0z2x=0}>o$JVX;r2GcHg7oWTamahChfL({dwJDm2QB=?a*Z-`@WCPD z`0bYD0Xk+BRI~Os;8c2xpSKhouMOV#v)0vNbp#{O56mlm7dOIN?kM>F?G|-ldf4p+ zmgP%bkvdJzeZP96vM+3BX$D}Q6}dwcwUS*C`W)YfUWef3Y&QIB=MKTkpdz4iH{#Lp zAIqdGk)@keGczQi6Sc>-?fVEqUhc_TzQ&)h-6+R{43|Xk5R@{B684 z%SSGn&2ly-%r(?q7yX$(qj$!__DS19coXtfAW^hvOmmuz!tsLXDA=r$u8gC`8F*+!BJn%f08>h z6|P1O)g0ZAA(_3LTp*aQOZO7Pk9W8}@5Gxp1K2g=MID@&Rng}LacUl=+a~QV&|DQx zdwL!_SvzgI1bx`=BAy&-tray!LWS<1zNq#*vpxh@t%P&0yLCuyvhjYu5n+mNxOxzCRuE+1Ng#x8fm+R zc8y5DACQO`i{7$CGsx7^|B?yyzv|6*J@E9c(0|V?$;ocGqUpZpVs~(IJO*c@dC?2k zH9%LJ%6m>mH=EJiPE4`NZl^OD3wIJr{I1dDB}98c$K)BMH(oflm4}0ouTFSY>YVcpGAgd3 zVAdmVnJAM;hs*KYajwHLD$Jj}e{w$)(NL0R=x*V<6N_KIf#&MyP(DChoqGgJ`CK7S zG2Aa&KY^Od|E?H;HJF#4;k(^Na9(U4P|vQg>A6Cb=FJIPv~adX!9-&5ggBp{>IF$K z(Y%(Wa7n6Jm+aq%6?CPR+CWkxD~eWk<5)(4r28BjM?Hrr?5JV1O3l)rMDGpVAg_?B zu_nmqAR=JMf-=bE>r$EF8e+;sbP5!v2LZ@prR>SQLI~ugZfAw&0c?2~yHbwcDJvQ% zFwaXrX~Mam)O$1g{2bVCdQSPsf9pGsG@oveS3edr!1ZMs$QM^v`i*TGS?mKE5lumBgxCX4xaWyN@-Hf}de_EyT8vvFR!s`IShyq7f zR-g-ko4@P8Ciqq?KD>jJ+q1&*WvkVqk#(@?ycY$j zqdN7}U6VdufFPb(=elA6v;+cZ0WIxlC`s4nU&CUlSRAw*BfJk=*1Ng*%H*Y1yQZ`w z7B&-MXag&ak9jxjNmqeC{MnN~r^)U0FnH_ti#RQ-5J`#)$j{$nG(%Q;L~;|U27yb2 zlI%K&Pe`k6I!*4E2I3y>uTn}Y>zDkfw++EjIkUjYSOY=uiLfXl7rs@udq6V6j~b-6 z-tVPvwuk|4U74IBg$+-)B(`cTPK&p|2de5g4zJ&|KU8(JHX~bQkLxOVJA;<0@bQTt z%p;NtOW2TPV1Mk2q#ZV<7%r7RD z3~n;PISSY(qlQ(3f8y_r&f|5j2TBu>i-}A)c}1X!0XxYo%|(1WIIumcrHzP;ZTLX7 z6~=jBY~94r4kk3!u$f*q<+V0n2KP8vwTaQS3#op?Y1iVC8pBv6YVP8Ui!%fT`SW5C zkAUGd-nc% z%Bpn8A3fvDZe3@AyXeHzki2~Ii=ZaJHdcW?s9w>3iCARcT-oGVr^|Rm>%nGOph$Cbu?NXDJuO!k~4B)yz^HbR>m606i)<25zBBe z!|iHP%zpx7lB)KwL0{ZkNsPsUG%qZ;oS_vU5|pX9F5uyh`ti2|Ba-~N`eu^p&Sv&GINI~^$Poc?|bh=XArL50aU!+ssw zB$IA%o5|%pv0ybq9*!aOy5n4LqyTJ&_{qLff4@Bn*k!&}m!}DE63kQgoE*%!@6-=7 zmH0aa2YZVj=&C3)nZF;sw_Fxqz`WPhNxfMv8MyL(6+7H0`M|uCe?A29X?hF?%dk%k zxVp*%l@}Z}V{AzHMa)eC4z89j1gI@bB}hTB>T*(lYktI#=VRX*5cKm!0pi2UFHpTY zXvvDAwcz1R`{Ne3loq{!B&pI1n6fcXr&+P#stOj+j{NRTCu@;9Zz5Uqn*my9^BuuM zmO*+TjX%9NvIxsJ$X%9PAN|(iL+TOu*)rfK({TMN0B*NFQ1 zo@*kR13Aqb&q3-!S26V7SXW<_4BNInGH1l<^4PJ$L~Q{hDU%b!pZh&b=5xmjl>7+8 z`szDI-GevAdM89m)tYL!uA5Yg&E?E#jIBI5t_Cs+iguG>%o)G?t&=o^!>v?-q2UWX zQ`}wevyK)WP;TN30+5!$dK3i?#U92*$=9=CrxXMI4bs46VpCO(#VswB2R#I#*ahoC zvpja7^J*-bJRrRC>H}{b?Pp^rk#c6RP}P7X>OOjySo^}uTg5ZRqxe~7@yQz(m=3dA zJu;?}Sp=JNKd@Nmg)!(2N7_KEI&TPloaNb>_Bww-XQaKs-^4|J(8gJ2x z5H6_p(hHxDn9R_!)95wlzve5VR6^+uXp4pY^>kK zP5Cp0s_-sw*Tlx&REbg$yTv#Fxml>wAC3FX3pkL^L!L7r%+2?a%k+{7<-bpFeTbbu zsws=zv-TZyU9aUhz6U%T67>Q?CC*APd?^^UCeu-KDk}%JECYOh?rgIXtaHE%W{chA z6?4QGn&&B3gCuZ7oLP6l3Wd)#jI68iVA&*rtqlB;5zzk_G?ni6C+xWar;owWBE5f$ zLe^CR#q4X(OeH%506HMUngQ|`e|q(Fw9S+bvT}|?QsE$SHDC+xQ7;c$2lUbihnoop zL=U!nd9I=mq#xb?4NqCMaxx*aRk?IkAm7RCi{XgorM&)JLcHsc04gB(mj_xntQHCs z=$sgcN|AfT+HR&p%Z@-rs;m_$Wz*nPs<3D5P|njv*n;@jObe~TWv40fn~k9kcc!(` z3>ID)=7&@faw)?4ZV-soEa>$GKiWlj;V1(zJz$(Z{~1gr`sWZxLLqAjPIa|>eTgfB zr9zUGcIxF{N|c5rQfBh2sUNZSF3i>Um5Y_6XO*V}h@b4e+?_6p8&yVwgg%ybcqhxk z|1_}`07DNm0i$@GkhYXe;rlwfGCL(P#ZkdoX1u#0_SaHJJ3IDnz(%w zC60DJ=J$OOUoEu?MP7a2ycdZk4d+f3n*^`)oHF+z;BPV=Ku^d!1V%l`Sm)30Y&-`a z%a98|jM0hc5F0M8UD8PBv1RNiEk#LDO>e!|*^=C=2OjY16JtA2Ifz9)G@Ar#`$L{k z{Zl&YO128iqfmuLOvyj!xgno>=iK7+UjS3*tvVe2_3P;J3piTVq;CnC$@na?U03DA z;J{2OEGf#z278EK)p;>GOL#|h4FUu%d^zP00tHceD}TlwJOBr5aiA}LXZKm_vIE$# z4$jLf3lppud$NmoT`GP+JAX@F6s@$~uA>xw@&LB5k&B)}UdWq5GbMOfdho)25`NZ- znq?cnPx@(jD@hc{pZ$dDF2pSz9&=oRu62g<0nqEx%3ZN&GhovHh#QiCr#(8tgZ8Nu zV|O22-(9=P=m}BkVQEYvQ<(;6GX;xq=hIgF*{R|ggF<3kKwtq=37a}hl3smMep?3I%+dVY~4#o>hRY;UVtNd4Rgh6@nx`) zR%rdu<(?4CLE>mIqcir+fT?M_eO*EU&}kqqm2NLo|NZVo=g#+UNGs?}iJfbxZOyfm zhW1Mfk3>X$SEhjIeBgCWu5PRw9kZpnNEfkHx|Dtgemw2V<*JLOvhc7sY?HiSW;8l~ zX$6!cAQ1I+dC)6%n!I%cP|asX(ddytDy26~OK?9+UvaoWxV~rCT8!P){)iiqfOqiF z7pnaA22Ad%SpgO>VX6&3kAzcK;GZ5Qs z06N@V_>}4cUM`z$Yo(Q{)-syciV#D0e*Q-oyE}Toea~93dV6Q6H;$C?g!@54(Y|kD zjMVi#ojI`A4r859>45rYdM4;dXbFZKYy zOMvn0T>`#>5<21c%ukIIC~(rAi<{?r==MId2dvUBoI(yi_%qq%AgX(LYta-l%Tiz- zq8h!#{nXqpR`$&33o00p zO8XSJ&}p?yW)tZ2Frd?y%J1I-?{8J`E7Ish%waIcI2&}c;6h!fbunU;`yh7}cpx!H{+Eq#{wy?ta)&qCO@-#=%$->5CR?W z+Efpfpa=4v8IDT8V_3aitv~dBc0bYCIbQm>mJ4Md8cCLxx>l@v4kAF(`G63&`W>Wx z#|;4!1j|ZvX)Bb}ujzGJHV>9^*Rvh8CYzZ8DJJ0!V%Z9g2IG2$q1SMuCj#BBxOOGq zz@@9>%Cy=Cu;Fx`eOaJSLLfV~{UFR#o^866#@e`n1lPMc8B)G~X-t>imo9`}k-%`B zhk$sMnFn5`D9M}_A)Ic#X(rw1EI`3wGFrD-zl0>tn;NR&svn*QEU>4G!-DWYDud7kn=k9B zWO&yWw7q+f6u`QdANO2+Cd0SD+ckR{3cMt^fmI3T&F9P334kWmW9LdRhA@7^A8DJL z(mREMiCU9S^5gvO7_*Xr@(A~-bwI`hv{K^+!hwBMDRXrMS!r}N1PI&c__!1(+E=FKIR-2`!Vo$4zWe10@cOFS>7y6 z3+yH@9rWJ~?QKkan3C)&JU&=(h+Mi@`mXcGbuV3m52@uMJ#S*d)_M(9@k9PLqfq)T zmcJu)GZ+HvHU(ql0>=3yDXr7mXR(Gb5N0#URgF~0d0NZu8C%2h7&-?kSUm^8Tmam+ z$=#_(6IN)lhFURc^QerN&Ptq&wH6|EhWxl>)gx$QWu0d=c+zlKpPeVQ{LoRFbiDjH z008yiH3IzY0Otj+nG|rvzG(lxD~2@_3@%ur1_q!oL~oh$*y+U8mH9x+b91nEn-WFv zk|xenF`vbE^?kslu^OV>;ohRBnIxENQ8MO;^MFYW94~~8_Zk*0&_`>9UL6T|-s616 zn+E|Pgn`7_n#DUDfW@}CRVU0V{k1DVokI7JqO{S@(;`=+!bf z+lD;)mj){BWUL1VZGWaI%tZN)MunHH%F3-R6b$~O9Hj-kJXyX}&rQ8{RC!>n&aK+2ttr8dng~ToOtO{5vNJ1*$IYJK=Z; zyo-TXm|At#%p*Z}^rj@tq)>QxuVHAbgDj_n70cinHy5}P;;6f-zg^5BcRSV4%L9}BTYk1y*!Db2|tse}`!m2oRU+e?b3KGgzl77^u?koF( z5FhM+$l>R+&jRc+2(VEP4N$ZxSJCGtEEU zFq@mP&y|&SN&qX!<>fS%aU16i`V+_V*Y8j;&GExGz=ab?KT97ABgMy`17Z|?MvMYv zHO+E{gF(oRLgF57e&$-T5ao~O2}*Z*)j8sV^_xX&-oKDWI&)AZI}Ur%cjF{4`p;d% zm4Z+FZB{PhkKVCJp3%in;P;d2A#hz!uoixxLOTRQz8v5N)ew$#332|eh?SwrJKo+? zvAG2qy;4galg|wMzOOGGv!cml$`}&yt2iU8@zKv|@;Z^&STWKIo7;*jU&Flwbw$KX z!7cNuRzaQyswtrQ>E4JIm=rrFlfp0N(d5fg0=!k{EzAfNLd1%8{XK7w&8M^E_@TT9 z%H)cC`NLf!qsV#le0o1Caful=0>Hncq}N!|NnYh372lLD;iox@tGGAQuHz$3JhpaN zr}CtR4g6t+27SV#_G&;(?D+b3+G#BQGATPZ=)wVhXkx3WBL&kj!HNeq_XyB%XllU_ zP_X}T>0;7Q*yt9Co^X<2hzlK0N4EGJ?%CzhM12c#pDk2RPb)n@CYDfzq486q9SY#K zu5sGE_*u`%BEXDIt*0GpP4uG=z|!%*e+2WI>2W!j?OyJSox!C4L%2%QQ_wZ8gr(E} z%>M|UU0f!#<|u^!+~ZZX-x3udYB-a`aiYdE`^EP_In4&F-#?cZJWT3mxZ(!D8Vl}! z`C`}m|C9U|r~IA#`%S6&6cD~CH$?j>6eN+cW3g8wbTeOCxgLe3jvrMxgKawU&=HgD zuyQHQe_`eOyk{q9DimB`hX8;}!vNvIIDbGNyW%_bHp|mvMxC%k0_RYJm^$2YTBvnT zEqQJS(zANGqz;9T$mE#ea5hL>x|Bqn&-J;DaL_kIDX9(>lt_kOb!xJsBTo)pr4QXm z?wMNW<;^S+ZQtGKAXcQ@G-W;t0n!N|uoo}R?-s5`3jhKqQ^NNz)yz~8TC!=w=j+DQ zm3j#D_DCJP{LsrhDM`QhT(o~Lg!f8p-}Z%Yu92d<8rOTDU<_)R}3v9+;0clZS&H`nT$EhfnT}V98Nptae z*FSGTX0Ko5T9`8LFY5dKsq_+;Aa%HY}gi&L6u+a2jkV`r2>aCZ-kRxio--Tca?9!%VXU)LH2<%e>%tU`U#5k z4tZLxtX!|SJGS6yPjPx1*U)>Ux8JQ^3b%18#xY`w8~?J+blc}FHD3FMzL%z00v_rd%RankJ(Ki@{Hsp142;5~*-PGLh5*XCcg?{9UDBwB;DezdL}K7`Y2|qc zI~qINW`>QlY}CM6oYU~Hku3GpMtXx2WI6LfJSx1jANX?G{B%BZIm-&fqFtKKSDbJs ziD{IYc4~g5V=iNB8mX67z2dXD6uH;t48C@A(D@eW)c9~>u+9Kh<3qRfhrt_!(Whge z8Hr_q5>A*;mIOUb!XwMt0C(d7WdePv&$eR{a0Z4Oodad8AS&#GA>w61C7^}7!y0LG z8%<`xkTXnWRxTy9{r+uyeh&ZfGP-tzi9wzQj5g?ZSVP8~tf9}1p^ab^zRnzOjIkgN zHB^AXZGruBkoaHlx{|WaJmVs)goa5A@X1%u^3v)?z$f!uu@^YgV~Rf~rC4^ndd%+}CeDCwFia7aleU~=d+G79YIS}zkz;$z|q zI`XR_nzJ15P!twAq*)@w48dlpz3ypFi(*sa(~a@@uM^h853ANsdR04RX%_Z9K> za{s2b6cg}KWH#&w45}U)ak$~aLFOt$LA(_OT)Vq)A7JN)c;#e?uCB+xF%ux$<6^?> zXp*H3SA>|&X^@$cQyWX#h75tN-DcTZnr<*ix+r$;-CtUIZSYbbyu-;Q|NCA3x%~U> ziS(=WH>Ye|1j2~X?KS37$9*xK4{bJH*=2n^?w))}Nb5&=W$bOom@U)5=k6B%Po7LF zJ1+`*g^?jBXP)jZrse6inYPUqflJ&;2L5$R=aO899=7@Y9&BYA7pgBj5@sGUblG-d z^``Q-L|Bm?vZ&$holN_Iq2(V+CtHD#+Fy*#5`CWlVyYVKy_*Pa(=|yV%AV zj^=O9?1j>FT>+m7_`X#dtrnwD^Ov6Mm*%o(%!d?lp|)BbXj>A>BYT60-&j?~gZQjmi%pY@Q6{3pb3(#c3)mMUS-X=1R zd&tTsbM4RB&!zb8zDN_$eI+P10x-F4CIxn)URPT3Il3Lp$;dOH0uQFUK)glGFN%<0 zSzsrubH)E+!7jDXiWSO0w}OvAYt5pzFo4#YOdgRH-VITum|F(QauT(%A)uY52olel zy%(&|1XZf0yFDNGI_G;0d554;{qtI0_Ikyak6>fZzVAqoLCdJ>sv^Z(2Ec<$Y3=S; zAPAX{9}N0G&hF5ftyQ?1tBt6uG!=-WGcaZfWtL>`WIG=}&+%H5@U_1mM7{cr8fy{V z?Nv1?mSW|F%6x7S>|^39wJ%rjlKNBuqSR^mx^(P)(%45Ga8LGChIzYmfh=L*Jsk=7 zTA1nLCW>W=5fesB#J`FGvZ)DmJD%R{Y1(&F!mCrkcs%0>1Rrz2CM4w0Uyrk zMKfx}LGe(GxtAe5faqO|MA~cttb)AJBXf{j5$m8Gbg8TCGSmLAW<(y_iy+meC8^5R zFW|b`Pc6rQ;H_6L3kDH5DIcIT!!V02!NJkbCpaf5rN$=?ibHfZ1DL2427N$@Em=ww z4_4G3B*_60t__r$$ZFX+in?5cTs5?AkebViOR5*QLuHlr5E*yJ7*96p?jDz6BR3ve zdC-!oL)Va5`;9jg#e#}>_s3Yg-O38c08Z~WLTaHk1f0%ZX&1D&j$PmaGk9n;=?xWo=u6xV9;(#i*Lq4L!k?&#dr)HCOdjh|z0 zcl%zyt8@J%0)20WFQ?lv@v1>t+TBamPW2_U{#M~BU(DOe7Ts+uXHo%t z=>&<2&(MQP#hU@Dy*u+iBF**PILphua?$oK=K+l6E!VeOxr|h6qRjWaw5oND6vcwU zy8FnZ`j?-81sK0cymbe-sis-Lv?dZrU(d5vn8TS)8>+A0Ya$O=4sQq8!pc6+>+xCIlhWe(a@4XeVHQ408Ylpm zF1Fz~d1KSw>PQDX)8Q?V=O*kc6awMAnnD?U1RYo`U4jo7tG{2F=x^&;(UmO;<_IVb z*eoiiBS>zLV3UOt)M!GBJQV9TdV+9{*0EEEs;|=5c3}mu9k*qYE}VB9E~acLGSQA= z&<#p(4_<@2!zI?A-RTB@V7FL89x)vw|9&cvl5JqOf0V-BkyE?8{f;(;1<{+|FR`%v z{yr}`dI(oLC*k{hsOfJHi2I>ddvzzDVv$UOWZB4iSf~6wJ2xdk6V-du=CAqeQdOyg zUwP+0^o_BV*Xn*Z2!^Vs_-<>BljwyiJFhKYcj^ghKY%bmhUjbFU!Tl_jH-q$T?7AA zJ=SMs$l_>s-VxQbx{zE`t-8zgf+xPnjOhBaias%PcMElCPKRPZ-`8XVLD0qj;8JM} z?)H}rXU;9xJKv_##osF=5341l)4!({4!XbUY;XmV<^D{&|ZIHylas^s>2S<5xeWWzDV zF2k=yERR_j4)RDw=1;tCuRTiJt4$^yg6hz4Y1io{IHDhjF@`GMk}@n0rXYO0wu7HR z%AMv~5kK-++#k33CbmNKG}nr-E^=JIKRi$(TbyV*ns}u6?qzA7d_f5pCqMSdGMJkifpDxnJ>e!5mH z30|W?6OH?Yyywp3&x#g#aRAmkzZshM;O)Z2FVWj~UV7k@^ZCM9-#iuDrzaQbuE$dC zDmV*@CAi(rDS1-a?PREV`OSsUtV)O!c~aR3nhiYs%idQaPqJ9ro%4R-afFYSfAly} z+Vn|jbLm2q)wSUHM@RY-v!=m)MaOn!oQ#c15B(a?-;NF5b+123UAXjxBhsZ0lbRC! z8TW@LMuvF#xn=JSDh`J5-~*NPc=G>`tgnuW@(tQv8bv7ykrEJ)mM#f#0cmMz=`LA9 z8fg(wIs{~C5Rir?C8VTTI#q-PDd~Ri#ozm#@0^$8f3n=q%v>{bO+5Gdn~)P_i~-Pj z{bIK4X0*x_k8BX)GZtVEJ;n^IEPr$T1fxG8%|fNPUq)frBp+3t!X*G0ws*E?LUSK%!K7%s< zc(G=ba)SsM2w_+|>~EmVBRKzLUon%3QGIz;#Z!x5vX)pRb&9oi=0m{Lo#V8Uk&V93 z<$Kmsp|qfNb|0bueWK+n?u20aJ!PZZ3D<~d{5qtE)_`_2*8a@i69~x|2^5+r`yyOT z&r$zp0xIs6Qs+T@u*C92Ueq{DE!>#a)fFqS5UqR_`WO03kc{HN^`w`{#5-u^>pL_4 zBHiyFU+P*pipl#(bakJTCUx0v-+OoJM(NKodoe7~k9a4ZL^g?4-vJ{)M;aqh!eRTK z&U#jiIa@?AjmU%N(;`TAO(~)y@UXP#^2tJ0c=~Pcrea3ICYN=ZAb; z?DPA2QaX2qE1is@LpvRU4>(;?I>xOO;B>`WRX7djhN=#N^Sty9N?BWW+6GCt!qjdb zm9&IC5PBBmG-d?VGBG4*ruM#I1riS=GQ&jPYea!)W7Oj!huswzHC(P0ysEeOns>!_ zKiu?EwoItTpj0xvg{#9ps8h@z!cAb5IaQxZ=^MXv0^c-3U~S z#(NoSgL_DDOY`zz#gjza!L@^=P!jaPi;{juF(t2y?3x<-1ExrAfbC%nOwoJ~T>|~J z8EZp7Cr0`?RISW4^Xy=_2zp2FKBcAU72_SFEuV*p{i2^^Isua}jSvyC zl4UvlK(Ao^1NFXS#J=-sw>IZ*oo^?r{vriRgQ>(=p%C=%TWuZ5dx`IF^95hb=ab@}x21rCPcCpm&sSMIwag#n$1m4|AnGJxOwn;ieZ`#;;fd}K zspAuyLeKhtlrash+`O%b(t}6|%|As)K+5j)ePpclLm+CN*+Xwt<=*DK0On{fEve=& z;&V+7AH=37i*!5TFF3H9PFjUX)Tbj`>qULqVb~)j%~j=Jp5hAt1f@m6pq*Tslq#O% zVhq?CyCH5z*&$~|15f<my@JL7`b7$B~scz8`5xn+_bH_{0v!TmKfyVPrc<&$4K7nd+#HjYwWVdf=G$k<~G#r9!BOM;i306LL7ZO^# ztzl-$W}F^Tn07v$ZZ(wZ1hPF3569yv_>QOf>># zxEdmTUKvm`+?8LwFfv&b<59hq38lHvfICVmMn)9Nj>=BvbeA^E7nD+racM37h#9=R zn6+xw!i;(=NjE?VEkLor8$=SvzTSy1v+OO_cQ81h>2H4*Gh;HnU6Mc>7RC3Nx;gHA zEn?Is-&{w~aru&uXT3gt`dkcRg6Gl)BSPn>W}SoP{@mnJtS_B_ny8oFNU-tS{rvc* z^uVUBO)lwaWcGr~>?lLxw$s>T17R7~(syfC5_Q3o_+5vuAT?#h3`v@01bi7-M-BHk z&WtzF%*$xmnXABG;A4(axhvcZvUrU0zYJWx{7upNNc)%FzTz&LrxXub-!tr&G3bj@ zWN5){`wyq(T^Qa6Gd5^qtTRCI>#v(=#etd0ov5{7K+uw|2^x3JW4bOehWG5cOyDtW zV>ZY^x-!ZaFZ4eU43YQG=c!*Nzv{77-8cX_Ms;?yAUc#};EA&a^rj@<8cUZEUU$3l zujE#q&gSqAIEoH4Q_Nobfc~u<4+~>0k~MHBa&1psPp*^$_sd$J z44ZFJsj3a^{)Ic=Bl$&3D{$N5^L@~1WsS8Svsug!pCBZ=T`!MmRH?=GM7s@WpcvH6`&h6x8BP2`vvJ{QD?tFgYH!T+M(5N z7Y%m2S)b~x2lsnXO9z9P57#G)T4SX=Dq-~z-~V9)y(K7IEWvf#J0rmc&l6}A!LDS` zk>tGTsj5P0ISL~{;>oWsDb;-^O14tR~ybL<f$A)_ zbk1l@0{t+ZTyrITo%O8st418O5;VD9)96u^-g82hriyrM^A`IWcfj%2QoJW zESHaab3>t@a(R;gGE#e^~1!GHi`d?N?zwuPWP|; zjMS`%xZKlbTDI1WDKvQ}yJHJs7OT@*>U_5XS)wR|LYeR5@R_u_pMJJ?jWS@ziN3lR zM6ntYT(KIsNUx;m2w3SJinb1hmjSF1?#VL?Kg&-q9_i@T7BJ3P&1#L~ zVip^VOd&gF_ex*_cKkph*tnw3)ljo|@f5-V$}JM@Li%dKA}MO>=c-C_0gCvaUeHx32 zF4e4pmm5yzovu7H4cL3%r{}R*-d3tj(*3PMrt|dl@{Lr&#FNJEsu7;<bH|! zLjj!?ANH`ii8?4Ci-OnuQOg;$5M1v3G{$YCgp7CLVKc%-|6-hPUveK%cKF$;i$z{N zz)s3m7B8`hh#>a19>>4~0f)H~!EfWU6XCaW{MkWhUIxjGT2FPJ6WTN&Rl()v`Ki7y zn0H`qT@ad=uyae`IqmB;uNNQH)hA(iMxt!koUC?>dyoID4v}AM%!E{W37vj)nBjWb z9XUSm6fZL3=f~6m9%P#pWGH>8gd$BSYi$m_*_hRL45XWn+DHF^<$I)k68EFAju$ z7+w0XGf6J%e`Wb5abqb9!od#(&nYBipm_p}6*qXQ@9yP{(nhI$To*5s>hzcZR z8f4Fz`#2iTCR)DhN@{ZY2^79l$=oO&r$Hy_$XnhS}m zIKz@^6lpOuOFv`w@Izwg+ZV6>NlxxqcQSRW_N6O_Ki_<=Ut)4B9I4Fs6^BI7jy-+s zC+*47oqjG;r7ery%GqtCUVTwLicr()uWZvJQFj^pTbL>TIH}gg`rgO@`y<{hcdTR1 zdL;-6@`lnnszvqUXSOk|3M=pW)QcNSRuF|TN6H)qxXfCHdiS5{5>VviiI>srPjkvX zA#tT~6``(ZIZ$q?&%NRArYw@5uAC0oVHDoS7vD=4okQ&n9^z)Ngcr+WEk63^rW?Rb zpVu8Ww%%|WfI{8x|5(q7@*e-`XM_+Z>3&a~DDkNEz07^@IFe>v{Ax7OEoL@Sm=_-> zb81=rG;56rW$)mMB8WZTLY&tW!ttWH2#mO>Boa9yfn_6Vts_=1BhD-B;+eqr0YcPkFqe6mbFe%1B8jCF2LUM(@Q!mUtP^3}i0? zYyYMI@0KWJ3->+R@B$_pH=3`-bj^BxbLWQ&c>UNNjXeWkJ zAt$$rxTM7XxG;NXG&ZyzA7?f3){zyq9Nm(+|3Lv&>!sx^D$Yd#IS|LsDLFc?CdIRY zYv8wRes))%BpDjWG>LBcOyzH0EvcImaFO~v6aTT^w$!c+K9sgQwU5%Dux%AWrYsCX zF$t2LaF}Blyjs=>Ie&}B;pkX#sk&5ky-9|>{kVB;w9|M`o2V9CbiL5A78~y|2y;TC zq=(;Vn-9J+(ZDB5s1X+u0T*u5Pax`JT)I!7hWj-Z`z>z#aN;mVORPMw;$lExQhAJoFH(|pyABah8#=qQ&9PTK~DR; zT06*T)AQ<{bSwJdG(Kop`^+2!clgZ==00L))>jc82scz0c#tE;f$jB;jYK`tXpHWV z(4u`{QL1xuZet+*G%EJ$V94q$v@n_$kqcGQ)Hl#K?{-k-1Qn49y14ijCb|BWjY;UJ- zBvGM%8?--2cK*0A7L%0a#1b8a8kEs$18+9w!A5{5WX+THX6HFXj~|M)ovC(&eNT+W zW*v*3f-09Tt6r#XlV|ax5hHe7zJa0wz85Xm>9^&U9SpXE&nUWLZZ_Rc#`e{T0r#F7 z&WFOZXX8TRe;ek5%Bywq(|^xuTEiHA)Hem3+|@!83AyJ1` z62GTj1R{K&D}5r47>kT>l8OGftqRq$eN0KaZKC0|WpFm{GC`S%qGK;DEZtjda`axU ztaT|xCA}iXEc%8!f7kWP!Q3rxjIT#TFa@;?^@$3Z&xDKiWBr_L*`HJP%7;R9%GU5W z^h1c@hnJW2XSNyr3_6svNE2?JA5-yFCz5#w#*j1R>rNVy)PJg&a~tbDALyRIM03Ya zGCgYC4^qUMz8I8yIDqkxg+2pu6amJ+EMduu7u9mqQsj~=Dq?{MRV-jGQ=Jd!Zg?tj zdtGdd%hJm7-hNmGMooXkfl|JC;osZV(6w;ERv+PkC&84-M>J}p^avi#rbk8wB_lNx z>#4R;9ea}uq0*k_eB9VAkWbV9vKQC#&HbCayjwRQS$M-vKz}yeGzM8ThMzn*|4gVT z5Ov7hcSID${d&uo_-?(4I0CKqVr`B4uQ#5Jc$+FpHe9_!+9JZs25sD2c0f|=FN_Y& zH&FgSx;a3#d4}P!dK2CcBhuzJcstiho8;8_+mTkR^`1nv*Eyq#(7w+hxwN9e;&D6NYF1VJd)78u+c z;wj=lJlxPY}OO7K$P*JtW8a>XOomj@tglWU5mURB?HUpXXUdf7BD; zysx+Fb%*SPS5mh=_2pnF4-DdNQ$1XtrJNNi-oIQ7czwS|!sI*nZWYlUa;(Rm>wgk( z!yq63%UzrGcp5kd*!exq6mSnj_<-wGBQv& znyv$dB0DRF&oe9F9G~cCT)(4u=buv6Wlt_1Bzmeu9fla2A@VeC1bxe|KI9}IQXP70 zJSL%~=g~qIw%UGoC_I0X7y>WjI8qjy@C)AyMV7X!)x+2Qb%ZvPvVTJBvHb{Xlo+)X z$=>YTyY1Wi4|g>`+iEfAX14uF+YCT=nxy%A#lf$3?u(rz%nViLFE8)~(wvHQvPrqr z*(t*7?fg1hiq-P#l=pOWy>LZt?3V7tzXVvQH(90VnKpo5ah{_-Cm zptUZ5D%*ZVreH(74nJ0AW<*c4t4|83IViy+QZ8z+THcG@N)}LxWPknT2yoD=gNA3E z>n{G1y2hOqgI0UAiW{qtKmRe80TF3o2eY{<$T@#tHJUGhes5!;uEg|g(b*66Tlhis zsC@nR9B(c7iV0-y+W|K!G|tWO{)(4GsY?4XA)GLyW=7>``1NEpj#|K8EedSB=m)V= z{m{DEFJrAFr?wh3W%BUm)=lWckRC?~C-GWlm4fFucYc6buu*(1=w_d^rwJ|lsIHXD zU5$|B9VvHnD*avcDGMQvkf%8^6uPp4m_Qzxi(Jpd?OX$$ra;~u!Z-#*jIr4IUMd+K zJxW(z%wRud;}a!>evgOYHc7mU6shP{GczNc?*nF07VXaLqL7xaO~2`E8hc+ZD&O1k zM(O3R=xMH2H*^06t`P@Bf&L8)o(yO>u2Z=F6vW0wf9V0; zeIz{tYhpeQqwx7;Li(w{O=DDc zUx%Jp=Il;930R$P6^W;HROi5OSu(&Rq4XPw_P%PM;-wCI)0m1Zs^|I`dC?bJPjZ}qt zK1I5g)3-g@ISPvC>#5yu$Rxb*a?_8+57HTvICx-I((K44XorqJnI{Y}=gSjQ70!=o z^-5K`$LsCI-}nW%?m4vZ=9lx%Ym`*W9p;Vws7O}rugN#)c^7>Y&acUs@dy;f^7hfF zKcBBSI)eOHKdq!~z0T7!SzYuir*+)-f=?y(ond53y!Md8VuHk^Y+WZnAz#JmPe6@B zkQdhA^!29#aFZ9~C7Ej*qXbQN!$JbB5k(6jiq)MoH3M;L=w_N$IcMZJ_34{3&uB6a z$(=VpvwD@v7Pu-dVaM(B+bPp$K`Wu;ym*fT{ON9Bu#(8DiRA_OdMFCma53hm7dClh z5q3qIy*u()tGvMgG`TUNSzB}QOftZ)amU;PtiJ^u*B^RjMvB&UsVJ2tI4anbS}qWk zkF5?py`JCqw-M=ufs9Q8@x)sCSq&A46}T5SB{5o_xnYN70;Yqo|HyyV+(#kHM}?GS zAQnVF^3Y?-jBQ#DmPNkj=et{XbapLtgg}7s7;tqzt#ZzoKFKN@ip|YIOv2P8D!5>E z0_$VbA4LrJaXjx9GqF}aZyZ7-kTLwNX^aXQ*#n9<@>A^XvmC-vI5H;wRz|5t!L4 z9V~MQ;eVKhA^{WCogLZ9*8IXnb4RIq8P11m@$rv0i;MqW-iCbUc*%Iusc|@$xj8q6V2ck#LV6 zBvB}35|PW2TdbVgLbG@!BPG6S{^ir}6AeU0@r$p!D`hn2mbrx!mF+)@d&~S0_tP;3 z#n$ghpVopZ4}q?E`oi2wS^A3+RJ+mStk_DDv*2l2yxn1${Ljp8BXUJKEVLGD?}lWJ zw3+;;M_iysP?KKJ2F3y&4PQ_GyT8!FEl3{q@-{>=+r)B4^Q*_?H+}T9ZT}Q_?ozJr zd4L2(^qkwU9?AOY9EA^HX#3*Azhgc-5b5Fv<)Y})8Xf3n2_<=S*#_{Q*decKxO!Ud zT8Ky&#A)g?rDw3sH9R15MsW?ULl##Vr-eFVIBiA1mGH+F1n(UbH{{P9D6szGYo zh3^!;w_cBhE}EEcbUp@&WAqTpTX}w_u`EIcsrIUdM4R=6sXGA7toH*TC zf207p>HyJOo1V?x<4O9$^i1wqo^%}`)X^}`xwyBe19WR}?JwC=nwBfk)drqzcLO>J zE1t5@L{#nga`gPyg;_ZQ>j@YxE#SM#!s-eq1%q$Fw+B5qY03FEclD;v*;|YxdMXJ; zR&1(h|LYZhmm25o-ETO1RrieSOBXJUNQAr;wiYFc5+=O1#;2#>&|hZaUXK1F8O&f+ z=pASvVZ0=2tHO-5*)o)G9bYWUbb4kcs>?pfSc>3Z#$anBHwBw5iuT_>rjVc2HZOhm zUk#i+opQCW*T-Go%oKC&2MQb_Iz4=oaBt=CPt6d~7q=_7N@0B2Dij5Kw0V{HVU7W# z@l#GSvC#E4hp*kwUghsJmT-B+JVX)AXS;bHjuFW+}fiN9EQQee5Q&}fZ#NE%i$OgdSRREHy9wuzsgR1^B@(Vf~Znp>%x zjCZQP6|Kfbc7Wj-`xqDOpnBre@rp&8<--ywjGZ7);MGZLdqHyei$%*shX~1C*j@iU zo4!g5?Z?47+LfWHKUx~$hb9+ah%YbeqTqMKS_xmqgY6!$pQH!|C{*Zf6UL4c@DZ(E zfi!+^d9_9l8tQ(P$>%541#dRXqHEAFuk;EesGWRw6Hl81(_nP%*GyTOaRXXE;wsN#g zUpU=_Tml67luz^FOItpJ;~{&_&dm~&=t~ni{8vMi{1qD2BWgAfVXlwdm-A;oxFP2Y zb#CjiExO0>(bHh7e)JTOof2=&5`yfj@r_$8hXDm%mj_XbKni8S&m7y^M?DSjOEjkt{4W!AR8H z*44e%;l4|?x6$zdMu+#&0AO!>8rt^~kYfyAuwp}^O~{i^#7%XpuAD|4l+X@KJ0BrS z4mxGp_wdj>pG18=vPKZ)9(C4%p2DTZWcLeCJlG4p|0v^$J0}=F1aNOIxblpH*wnsq zc`9$L;lbIiLan4?8*Nbbdfr^@vS14XB$RHy8I{uBz2g;hw#_sU#p zfy}p;yLU!<=pU1j5oB`@9!yH2`>UT%zLzLzHegCt3cadW3?D+Nq|WwJpgmTLSwxyA zHX1ZRdT1D`7m>xa<#d{Ocs~1zlV26bRJ0oYwis&M`Z5o60-9m048tRfrAhnlVd)s9 z%16UrVso5zYrQ8-Z2JwCl9)U2a;E5!-E?qW8h|5-2}Jp%zckGrkl z@Pe=K5D_D3Cl>ZQUzj8eY~31LDMUWwB)}un+9`#)UC9nJkU=Wf-UCv^n*xMlny3xfi-1MD^F}VOq zL_Fk5v%2{M?3AGuwa7`J1g5T9N^%l5h*0iQ;UX{#h%n|Nk20H74t6_h7V|yNMJ#dO zh|L%l``xm@I}gjN43#;)L~a>+l2%~&YCHEeSxTl~3y%YY2ipWuSjV3LpxN=Fl@+C2 z2V9PODjAUJ5kFZVO+m7{4tyMwY|-dI3cRD`Mv#SdNsFnvbG?yb2AIQ?JBu*AF>8}u z(|YZ|w*2iL+;j7t+!aiI>8xBo`m#r z5^Vy);nhhWj9jo>HgZlPgGbA?9%L_%9EfWwtr> zNetDsF9|}g>AzJxRdRs#rHUfl)x+(Lmy< z;N16_%k_HWSbG`bmkFpdW?MI~>&W>RPKlZ?N{+@7`Kkxi8`N9`9pLQ4Uw#eMcb71( zbq|Hy$MMGV8Gq@SKI4E0H7*ekvKiqSbZ@j`WCF57sm-q3tiYTmxmr3$fKANkvgHCfrdj}JP zrZ%)@^H+7vGkaz9VlX4)DUpY!zVlsLe0nzrzjoNIixB2eaE_?;@c>VEh&HkoV@XkrO$(;R1R-qjJgL5VT(+3xus zX*%2S@y<*{0IIwx_g3H;fV9mGYZmFK&5 zB@%dG_VZT|X$uSZkh<*8oBJobPh7lIwQ4wvtk1-dNnk8r(W2@n5x#1X`M$u)Vi1M{ zesd)B!H;^|-cQ~P6eHnam%edCE|upv8+D73?}66MZDZ30X8&mqh}3vG-vu)mtpb?6 z1&KHkBx2IG41oK!zp^xb4z4EkmdL_UM-}g8;x)c`=ze7rPcjA8)HGh&jMOCQ+ReC}4cK1o*8tvZx>Gc`G;EY-H?$U3Wjih(pUdU(lKCo2Q5d@!TSq3 zwv>-QlFe;~01?WqB_Xt4$EHHImL(#Ag%>{&eAI zkw07?B3*}Yc1VDm?~jr4`n^OwKW=;5#U8I<8ch5w-H8#QFKWWQ_w=#NwH<7@ISFz) z{Mg543h5rrYY=@)gH{k@=krGtzOy2b^k2ah=G?Q?#X2rqNKi;PL7>gB7X!@DfFoT3 zOpOVN{#`v&@#=xEufy}(T{-n6(hZsIEbLKt#wG$MmK0$CfyFmv+BR%Pgb9yAiJldm z&{@$Pu*l{TC-}t3L0M!sW&AJR(+awvY9K9n!j@*ZWh!XV!91KN1D!(zl8yf~gT3&G`m)iRL$0&Cm4ENsvy_ zzR9nsHjlXdc{?@aJZd2!@-9LW?Q^|=9AN@-qyZ5Iy+iJBwcfZtua z`63m!+0;RL^OeIz94bYBELlctZyFnp7>?)uPFSO#i6Vq-gI6#Y5-L=}(SgQ@i*UGn zw6i`L+a(-D2tUmpnfgR$P$4qc0DE@e!}}Sl&9S}EX~nl;j%XL15kVy2Fr9rNS@~S{ z9`$$!&{D5W4(ARH3_e2{aOGOIv6Z@Q?mMWk7a z{l-F@E|(5Iw86Sd<}jA3yfwd#r~W}hNf*2~Py&MM4G1;xStQ@=s5Kq}`5S3&_v%Ty zvAx2rR42w_fo#&!Dx8Y3Yr-^w+%ZE3K(TvK>(^F$T1Ll5^s+G(Ovay%6d^Pc%w#Fvb4Z z=nxr;7a!g}DzYS@w1@26u!Q#~?5(_#>Wuvt_!8f2EX|BytO!3qn&%r7k384!dA_^c zXQzJaDcMcUE{74}3>j@{EU&$Yi5TW$Q`hnB4VBa(pr31u19deJVYmS5tj!O`@R!^* zmItKn@Pem{FZEtHAR-HAGE!XroI3eJ@oCNA&^gso0N5$;+7OZf~&(FyouiFy7 z3gVvgj=j_C#XH6(fX9^DJ2&ay>wO}u6!6+}?P`~TN)^wTb6u;0(VU(2U$s*HO=`{) zR4ZA6wAbKeGYs;#^rr)Bokq1TG(X zQQ>D=N(S*WPKdmFoem_spYMY%D|abzNWJ^5^2h!9P1Z##k_eIyjT35=vLcBb*mEj@ zgPQt3lkA~2TW?S5fb7A5Fo7TLP^^89su37O{a_eTsxDD&Coso9TK)}AVn}p3|5RWI z4WvwdqieD4WbQ94e4Zpc3YV(Q%@mr~L{WG#5Irf!Y>?sh?e4LcVo_rF#Z&%ej#aX3 zezC!{Z}O{FOV1PU`Sd>Woewo1;Ha3Ao!8B5d&cOI8EC3?Ficp2_5v=XsSAduo)-_M z-QweD@-foF?U&(b`W<#hU848o@4f$ru7U8vsEux1q!wRUmcYD5?`fQv9U_Q(Gt8;= zu3N~N_tipN`)Q9||LY$=XHE_THCs$RvLE{j!JWA5xU3ra`J50x*`Gl?0pvW>2+^%- zZwUao7W7i0RFh!59zFq0_2-=)ANjAT+ac9zCFg|PiuQ|uy$w|8w@6!F|GElD^l~tCwpB?H} zLVWc=*?@%M1Kf>-;*Vh9 zODTb4DzDbLHKmYiZt;Suf8pXr=n<#n#?Wu8^XDiHRt+4z#z#B$HeTSR3drJUI-l7&=DfdS>{uAql$?z zATIGTtI9`Om~0^qQDNuCT7~`7Ef;2wb?XCmSZ1dWBA+*#+wi3f4r0Fz-cO6?z&&m| z(B1zmn-_&~EZofI*8DFtCc6?Gi2@AjU`&}Jf_olxPq3afjxWGS`$MF^frj0Hk^Ix0 z_vXuD{{XP^i7Zpx3rbNb%IkpWs=m5>{$A>RKUBqY*xqR1aFdchb?ii{UaGnUA{@m_q7`|5JmN0K<0 z`y~kIeBI4#W*y`GKb30{YQUWf<+=XYX&NZkrA%bK$q~?H(uJ3xh34ZWx#+K(8T{#q z+a=5?vXRw4$Ucx2RGeS)&7k|fofpvfZSZA?>3mB6(l_#NdRZKpAMimIK;S5B5=a}h zTYcNLY_5ch{6yKI4~apsgSX4FNoo0Uz-wLC`J3-m+L-snnsohG?LONWZ~i;MUf%^G zunt+0V0U&HWqSy97@Or<{Sb>2N-f3`wQ5zB7QDYMpt-ZVTtl)5lcy5Es8@6D;}p8a z+X2YE4JVMntnQ~;dm+PJTS7ICVCz7nUb_4h?PoyPp?R*?hy#NKwB6ZRyT28WV1&Xn zHU;L*+CfrzL!UPINw=5$)v~x;pPNA$6PsC9YnKQ8aYU90QbxAN zb3H1C&lYC~tC@}er5KtAuY(R-GRXZ3*SUW{cy=^Cm|z^8`w=DDjH4>W*Mh?=5wu3<_K$V)L8 zg|SE_uEfd;;wQE@>h@G#e%1<9y{?R!^PhtA3ng6x{cV4OcWC5^2a>_yR$PeK$w;vH z2bk4A!509`1AY?E)tBfW5&o}+Ono0=egRg09R%Q6g7X@x^Ts_Aa~#h^(f;<8h2*Ty zXLIeyUo?x_F6F!0s>ri)3(XToNiF)>x>kLn!E)#}-#@*BN=d1448(hst%b(vF6d0r zDurtWFvg@qpvt=7<>`;dSJRDqBE5sBEk}#1AN3m%h(;?D??XRtxisy2(YaLPEF@o} z9?4;1Bz=8?Thqqi>bprT9{Kawc=5qt|ASq}Hf*y;Ep$~Pff%zdUJk)WY$k20h9zg@ zzQ5CIp776Hy=3T33bEQ;_gB^STL}1C*tniE!l}KgJGA{STyM=F~Z`6ye+_P@vm?)2MBEk}07q>!`a;3;gRJQQ%u+wkM4q0q4#$OEH zHa#3F<4UBoidu@qI zDi^mFMPHg2SGH{uVwE1uW4Dzjvjoo%qEfC8&KhMi68kcf^jGvKa61WA?W*&+mJ+Sh4E7|}l8k!6$Hwdjia%!@*?u-M;R-38W>RzSpAdo@ z7czn{PHq2Ce`jXCh}$N7$@;D7eS+1N+8w3etKZtL|T??4j1vYDzF`^lE{`2-LgY5(TC zBmHfJr2Bz|puJq5W$oSXg}ru0^fQTXeLXwBb1N)*bl{Y^VL$?HyC4_)PJd}3AL*?r zzt_rpI8+C;`ZvsfR7Ghhd_KW+kz@VV;jcixh`xr`l{jps+COwN)!<9riIZ(@-aN@< z;Nz&h(?k9StEcZ%YPE>>bDd_al^#K;$`5ewwpRwI!2KKDCy z|B=U@(=(PMrB9Y-evco%rOV4Ok7`sa{nB!A>${I|c#%(7!sU_AH+zbQZmzd^`D3+@fN-TBd5SXIF{vD8}iZT-$r*x#^)9d2vNJ9`wF zG&+3Vx@VqvueB`AsYzo@zU%z4tmy<`yTeOyz7Va*q@N8yqk?Tlht0CEL(fnJjaMrFzU z8wJ!tu|j=`yZRk`&svFpBHx~c8nI2te#|0LI>iz;T*}-9F2;8EQ|kz~0_9l@L_^^y z$GsnpB`!2``bN}A?PYZ*0Nml^{|~sbcj~4nnL2Z1+*%-S*-F@m(q58gDP8p}z^N)xor4~+MLjOd)ls>;VR8#!&+1R<4=!}W&|jlW1r8=D7+Ti$ zO!k58rLFBu9C&z`#2((wF$Pc*>;DHey?;=fn9q|)*O|4hvOUV(P69WL@DLZgu{Lfj zbC!xX?925(+l>5mK_B}^(Ee@o?kE%pELEb|oSoJBU|O&BMcRgm;wkMS2{`p&_st(| zpldf~qt!;N4DbSAmhBfo>;K&aXm*mZ>;6WnU5oFDS^P)yc7yJd* z6JVAaH_mbEi%ilb=$k*PcTFnNS^u#8E@o^C#I{^k$I&a)I`qfdfcj5bj;Mo?Q40$r z`*Z(YhPUho_S~u-owaXl_nqflmWBP~!QY$s2DzZWfak{e@?%M1{$yABJsT{J_eZlN zsXn6@yN(D#OcY=9Ql4ovqXm3ZBSc@?YJt;pB`onU<`GPGk=MEkKACIh?o|3XUJQ6$ zDp@7V-r2VDgYCv5^+vniXMVW?wzR?f!Y*-_DBRV!?B(ZO;}`P6hR2gF;5I$!jUSnh z;tp^BmQjdR(%%xrp}n8#Qjo+`Nkr}q`@qY7yoC{17l%LR7Ig}5h^tp)0oM(Rx~NKd zpN1}VRou9KlQv$(VTCAvOT znOG53VS*PRqjq|NYcr)w9?9+La@JCozM$DmHgq`3<=KpJ)HhiFb+Bn&`N+94E5MV{ z{rH==<=MHJd$pl@0sXUW1>OEzL+M)q^~>$@zSmmsfLxG2ZNVBY`)GAE<5OD}yER=s zQ`Tqc-cYX%38dKlYw@LDR07}w046jg(`j?Qdgk&`#;Xcn+M37Z$^}I1);EE~+7UkBSIAI3vtyqlmsNwRQZUJlC2$~i~ZzRpOH|ZUI*-jFk zeZ*0SWK_)_3VBsSV^o#>lczZ&9$BSw$g!9Nt? z{7C-0Tpq-7driwzw8fXSoA%XRdAtM^7-3!7N`Edhusm`DS{fhYSND0|fhc!ba7~Rw zzzWbTB2dTt-7A7s#Qa8*e0Xr1%IVhYfm1z};&JL0elbiS|6<$Y_=|6N?ceLl%9D~k zDf{mv4yLe`ry6i@rILSX@jJziyOaWGqq@%Jg0Ovv-{MPdE>zapmh?uy)m%l8_Q+R2 zBRo{IX6@hoJ_QP}66K}iP8d&ZBm;3V|6%;ZRuHmwYJP?8aGp_t05NWvBPKswK(#Sj zVD*2f*M-03>OnQ!i$t$zLD5SLW~ZQliD|rE2j$ zJ3Gf1DZTl_MNe2|;;UQ4C$7z@rnAu!pH`+-Do0=cz|zkX7Lkza4B)1Ht@I}MQ;rjc zMGPAWKpET7lrj1++&+0aYK(1je;yk$wwV|CGTF_0@EYL+1l9+LW~`Dw7rh~8ABNsr z&I>K?orq&>%%*SrU+T2U|E$&5GG`$}$aayI_5l-$2gH_FXno&r5%UOaaeh=MJLhole%`du9njU6`68+N{qbL2ucK@!_lMywkXFV&8~cQp{|{Mj z9oOXhwvSIyc`FLOMY>c-|*UX-`82kah&IUT_O4ns*gtS_y1J2k#=yN+sW5FCzM|ywany< zdXl3(YNyuH#JLxYA2xk`-)H3WA$H3Ql$6I8ArK!mHko?~uvl=)ONe@>T=i2MnC1St zltjrc!fhq00LfFqG_expnGOuj7!5IU2vjAhg2;L zCk0FmBY3onmBscxvc1_Rh_%(jJrnEfRB%B}cJ;QOOFb$Fq??dwo_|9Imxv> zC#FXIbGq0V)h%Qs-p8JrztqjGA#JrH7P!$s3xa3y?EgZj<>-TsTZM#ao$!RC)=h9l)VM&%l8?SL zF0#aeoiN=vFuqrgWe>RzdG4*rv+2R-Gxhh)q1=^L^ZX{no(ccF{o43NGuyh1EZWjW zY?HNpvz946568i4svw6h`vx7hLWvuA8T_RiPF{qOU<=-Lbcvzn=iQUQKJuD_Ab!Fj z2VF~(oD9XGt`lWbz4#udlG~m8Ae$J78c8IG7p-o9Pvao{uHggq3-2dK;tmG_IWdXI zB_j)w2!kh{Sk))f?85o|T*upSPd7ek-NkW0>!-zuGEQ)i^%bfMMa3f!!CN z3eQ{KydiIRumxLXGe~Ey(b-l2Cz#B<^7N!y?aiSwy%XJUJ1qg}U%B$a-&@;4+~Nu^ zFL1Qn`_|h(!G=3m+Qv)lmqta@c38-#b}We1e{`ZBscxUJ?ioHBeDN~?XRn$B6Jk1d zB=lYg$0Bez+-@|@ZbhT!m%_xKzD4%)gXId^WsZMaHX~`zAnRc-a)@qHfjdD{Se6b`#HE+yr zkZc*Ii0@9D8to+~Y&d*~IeMyz^ZRy(&%{lfziZ9owZF?I(k=t&bRMduHaTCXn;o@#W8gid?4oRzmf0|6&)WgG4Q=pd4oy0|rls&aX^3Vs>`v#Bt- z;-&<#Jg2VLlM_9RJ%MZEX}68*JwmZHuuoXwTD}qsi-E$AX)j(p<+Vik#%43l z$HEa6+6~T6OYcYOC2R>wn*Jn_OPE+5=Q;A`(3*z>xfr?hf-g@>NhzB2-+t-G+Ra|g-a@( zUcvSkBQv(b@poJ4r`|Nmh)7Uv^6c-yd3D~p6&Y6b2^%PP(MkA6rvHbb_8|1SgA2J1 zYgvS{PcmH6z`vl9a%{2%FRJoPb`>Tl?Zc@@J6bm<>F#IJfr^qDJIq;Lq$l?FM1FyV zJ^IpvHylNdA$E4C5aC{DvmCPqx{D%zkal*;D*CLC|Hy@IO(VV-Pl@j@bUw)+|JYvH zi?h3fdSq$4Y>T(Af~%0kBuy>nxgij?OoGK%Ai#J*{mkd&M+un%^XbN8ZW(Z+k2pJrI8uPET?LTei%V6Gkn!uKpD(?Kve7QnDB6xM!L^Jg@up)8kt~1k#7? zUYC_mw8#UNAgdlZVQ-s_F{-Ak62{0C%H!sbBfV6p z1}4XfO>QD~T-e_z3WhdDLksb~sXD7~@>RC^6UnNMC?XH!Taw0!)5)DUowUYf`@Q5G z?}fR&oo{;q(`EJZ6f3&lNISiyUeO(aOCcirc9{51s`A#2N86K>IKWBAU9LA_#@qYU zNZ~9(6^Gu2U}1e!Q}Z;RLkjVq)Qm^VN(S2#hccAT?i~SeUq<@~@~X9>(zn@r<9|Q_ zF9=RbNF7|-aR!t)?H_Eu=Uzx9qHTmz25aVmFFW!ROc5{oM!bfKKQm?`&uZKB2dQJ@ zUGOBmDE+Xw&!=)u9%d94H%(Yjf*wa)2Pc{m^0Ac5Aj+PvmN~$k=R22Yb|UV`<<0Cc zXZZpjgDjP>C)q3{OMyKB2wj((cD&I&PTyi`3Q<*pz1uZZaB0zx;pH|Vjqv|ROnDsH zMAPvvSL!&1G zUIH+7HffrTwS*gMU%Rn#P3|xMEX&VqIFtd9-0OsR`Hp*#AtHlHT?Z&{ri?W}#wEN+ zOZgp|Lxr_@`emEE*@IS}9laF|c2AP&GVFe4CEz4ysTM~cx^4F*czK>a3@B}6%X>P7 zl2XTtWp6c2iL%tq$@HADv;*@Q;Wsoh=hbiEKl@u;&{}|=T@?=G~!TlSY#`Z@Z_WA6?|15ze(;L_P>ZQQk{xI0{#z;aMtpyAZh0wkn@|IBh%nr>|Ljqn z>OTg*n2TKktN4*EHq%@=|9CTDDE-*Hl;I4r!ub=Z{jrF^y=QQT8$-b$EQ5nIa|@qb zh}k`8-OXDkJ#aiP?U;WuH#z-nk7MG3jAtoeTb^M3O^lYj)U z(o96Bm*Er%cdrBHHUd`@7=3&*zR4T$vyU#fnJ+;;6E>&ne)&tgf1s?3IB#;0)m%6w|m)nz-4TYmdz8sK9!`H^#mR+ z9y(y{RnjIv(;?*wA8w3^Ihwr0Ftz%hA7#m;*`u}(()6U->2+cGyiaK`<~0^B6zenp z59BV&&)VRl)8f|?mHZ%UAgu6U$_1LBxi)fS`n8cwLqF<{Q}#!FYvNkkONZEaa{V2h zKlx!)mC-DjP8p#O8)e4zElq9K1K>+9$6OsQ+b0p(A@`g_J#s+xaSdPGCs&_f*u10* zVU6mI-sOrO?#~XbByaT;oCD|qSS0gRt$=(P;tG`d+ zGP4N@qd8G-^DsiZ{R%fjmNaI>QJAR)F9eL3JM8TxRM^!DLaQG}*2&GGm!?4hhor4| z!pGX8Iz-HwMUvTo-tkkZrIPXxR^yTmOU|lQVIsc4b8kJ?5=cLZ#aPe{|s=B zj2lZ~1M%~RQ_{AY_L2F#CULi&5P6w6^A8p67wIxikZqu;OzOR+2N(NlaN{#KW^VO{h;n8CaXZR;3!pR`%uPI>7iQaq$r(QmwpsA zNfUhG8nXrT)hCN&$2q9+_E}K)C6hS}vzgSTDE$0zLUJ77A=i@I$pnDe`h8Q?F)C6% z=#!GdTYIc%c(h7u)*)iQm-AXIY@4ulGiSXsF1cvx`jQgZq5ODNQX`AdtrNyO^(ALo z5Cm#Z!d6j@)~?iZ{;lQ4h4;>!aYNLAgFxz=9o#Ko;um41e-Yu#PQa9YSj6dFaO72y zo3itn#Tvh|ysL>ljk^7MQ7Yq3Az{2H@Y=9~bbc#HC}hdbI^5}2vJ(xF@oN;)%(hwt z_~VcF0A`8^^KF;`GSa`=_&lnZLwJcPJ%e|on)6PP$(Lw!uw%qwOe&F8yvGk(T{C;y zZgjnGA-!-@gM9m`ps&i6vFk@?c^n3&S0^mlqhQJSl6f%X~0`T z+jF=$HDw&|`D$F2$qh>6zv3J^$oI`*rmbPXa)qgSw|;bPw@Nb$_jqpw)0QY28fERzpNWJ4~3=gxEFMEjq+3gRnJ zU2gnyw8w*yDT2&djdBgNMcwR!DRMNWA>&Rk$y`gmB$0g-=tqZhl~ql=c>>&CdjJ~D zm`d4sa4yXJl~M@HvjA8Yx0i*A*pDf`o&ve0baC=l#K-DF9ffQ8voe$#rE2JE?DH2+ zD4>`O#Sl}05NiOPyManI6PdscC`@m^{&a_gJO#0IOr_sdRBpM)urCDiiaqbEDZC zp%$JkXI&dWTZ~c=ewr-e3E-rl`*%RT&$ihB8g_C6*~9Y?%WyDgrZ# zeWBCJw8*1oN#Fgyogf-e8t%!+Nd4>Vsmc3Ss;ir>X-$44+P8La+HAyve3`2nKc=ML ze$Q8G_cigV`WT8E(Q%1kG~^WI+eOFLQ=|{X;H23}Agb;VSh6VZ6jiX4I}mi7j&^|& z>+jmtDR+IJ|0}nTaq^n&;T5`hnll&TY1)A1Ik0g9rP_*qCh_@IqppYzMvaupBJ|va z5faRV)**fdHmp*s>w>q#E}S+r7M;dQxK)|_%P6>xrGNx;oK#F;$GsCfDk`iiBRxJF zTOu~kK10Zit4g~+GRr^36uX=Dl5ejfJEiCG09jbc#8!^yjeu69h}r+spgGwLJ27b~ zc5i6dNg1w4R;ZmGiHrcjs09?m0fT}FGiJf4&f2$#JWEyAm@NzJ^G`X{t*0RUVOJU{ zdWRdoo8Cw7BjDmDGyejCEHy3y`FZb|4&5lP(~+bUg|<&ef$Y8X#S~t7T%#~s zmLFgHi&h3WpGg_gqE+W17Du7V?GrUzca)P|mOV|*srO`@a%h*EuJPezK1-3gvP`wh zyGZJyGAESicriUm1R!^@gOpO^f&iKXTj-u;)S z%Uj_Wghoq}Kg|)z5IvKv5?p>oIo#Z`2@16F{}gD?lL9?68KK|3`g7&f-)7bBx?7is zY}0eAg|ht?ryK2StZd)we3|*oiX5$)xbQNR48NLyI^0ff0rf{3+XM&35`(FtyXtuF z6i2#ZtG@4auMC@8>8$~A_#XZ?u&?b8MbKvs9we1hx)9b&UC%W!e9>`RUQCN?o9PVR z-d*NWiXCoXE|KM0irkOu3T3lcOHU>5a+2yiiTu7nIp}Hk)2e<%{;aZtyiY-H-1xo%qH~_B8{*m06 zGTpg^KbqftJ!4!&9<~aT3w5ShMf3SBmf_Pao>r!abyCk?<1VNA8zEv-lhyhceY(gr^)5GN^F*fjhGU|Qz zp4Z%ap|CMga~GJn`FiMRQjz*l(AuXjr5^DeKpJ?)`LAq20FR(mJb+BT4k{!m(29yD zf~(++%_gT!8`N&IrP~dzj(#gRA)YdMeFPgY`Sfjzr7#gYvU2~gmEAY1({N9H0`Ip8 z=p$CxE&((9#DS0W{d&F7KNw)V(bz@|? z-ycXKu+5E#S4r8(laQNHtDIe#kf(igzbt`fCxaKC8t)aQ*XaN719f;Pq4M^%I}be7 z<;DuajqoyOmz;Ib!vL=qp6ru$s#d1I0)jon)fprW%cWqsO4y5u9)S3QeeO#A>*}s4 zd;*u&78DNB;x26fXcZjVCSc)fVF@nhUb^YgrFTovP)>Ro{O~Pa91398L2{KXz8UX! z6=cymZaLxn_V!IXoz+@8aG8BTf;VH95C^#UWTx9sbZ4Yd$iMakA|&m=2I6*)wE3}v zaql<3zk9+gtfe%4bT2D#;B?Dd8W2{Rlb?`7#!Q1tV5#hzIDRob*_D&cx`L53CSt;A z`qKPR*jEfC5w1->X=anLgX|$opvR7R(rW5j%zm;{B7^crY<3$)Axle6WyYAGngUzU zn$&&lV)}W&!)QcqhWy*taP)vJEdTv&l%xqTgc7>HTP~}7({6$jpuV>wC0|oS9n1<6 z)4KuFEU|+G{~y(V4i_j7W{2b!msltVp=LNT zM7FFOzF|1MlXOiq)Lip%2IW%fVzzRp!k^Y_asQ|Qo1y6z1`*a)b zm>-h1Up)1pR)6JJp~$)Lx~O3SexbL(q9pYZahDw7ldUUf$kK~x!v?fQube|B!!xSr ziS>KH+M<830C{O##cgD2Jf$+>B)$`c`XcK#=qyxn{OUYR2k+8Y<&^E0;|qqdY83K5 z5cTT6EQ^~vAa5p|J+=aKkuHjyrmi99yiXr83=hrL0wYRSR=u5dJ!-0P*{mJ@Q=)8i2M$Fw#m9p!oCTz%`G3g=FDu)>bc`Q4VYas$S# z%iF-K?}-KMzpWy51*K^%p`p`!f>}?Cy}LQ`k2)$tD~R-&^NbpxEM+!ZCV<2;fQUKQ z^SJcH(`rHo&u1e^GZj@TBqvGJ<@FQe{J=&0=zkMv z^?zmdlG`gzwu~ULUE<|!exFL4kq$iCWgbo=Z78-^M2s}h$q&ag9tCE>n%D9vzU6rw zUWka#NbuAGwZnn%k=!g?CR3PusXv~z;(+llK(&_Z{Qy#^Ma2ujLaiT|y=BflEZ{B^DZt$_BVfU5Vidr}2= zZXkTr@_W}<-=&4O@f$jp`91250QJ?RP8FSjnmrv9cp8$)cw%ccH9t*ssu;pdbk^Lw z>ZhDYVY`c{Qn_6&pc)mQVa;-)O}xf=jP)bnEov?Y9VQkB{uV|JVsRgdALB0@Y$rD8H?8 z`C2>H;7V3ZAkXg%hZtG7EQ28;fEB0)-kEMW1<^hM))vYy-N-O!Ug#tW&cTvJy5p+knO69?oy{YA~^Ru=~ zdMEktdE-&W!(RQ5eWX=;I@*PfHp6Lw1)UHrR!H&nPoXR98hWeop2A?KqG~nK43p2V zQg({LF_}U z{{+_!dRlis05*Pgd;^EM8%hmY7E@D}w^H>j6bdb)?9j~Qt^!0vqu^3`<9PqyD7L#| z#Bhiwo{gW~t96f9@5CT!fY4&kxouyrq-vzNLrwlYi?}TlvMQMfotm=Frho_Om3l_X zJG`XK5Ur-;g$)^k?wq|FZ+lBmZ~ihl#m&G1i3WCRLVc%Rd5ReDj|n%m7krRlnihm4 zcmE$~7PLkL69yPEbQRI9M~cdMm~D)7)Ipm}q0Z4)ndc*WRtHL3%dxrE56T0ofK7MM z|83K$-#@YiEH>VDST`1?_-AA&<{My22eO;x^Ik8iq-IO#vc=w~`JN;Fl$;vpHRm{_9 z6uXjYcK3|*3g#;xa+G>MP2W$aU=t8;ABrvROss6wy(WNrW&7n%9=Q%BQco#N1^lY} zg@_S~=UVz@o~k}M@O%+1hUhEYRSoi6cZP#O!shVT;I*nQGa8ysGB8;UEup|(!m6fa ztnnE#<0bUxeX~eVJcgD$6?C;OqnFK5)FW|15K{pQiEXm@#XpdA02V z=k6b=0Jky{Scn+d&FW85^bGdT0gStxiH|bDB=2OVC%AXJqX~9jC|2#y>bvrv(k>~I z28Y{nPtkCy;Kckp-i{Tf@m@54G;zIP9B-n(*t~y(2^KC|6}@d67+z{X$g9r9J5B zwUPhU#Zsx`PqbxA@I_Fj%a1vYpV9c3D5&w_B1eg$-->e1qx+%^uqd4@Lt>nKyNf1| zxKrmRz(R{}EjzHPa>L$`UA$ka$ZH4Pm*l93Fam1Y9iyZ#$1@MX=+~{5KHA`NwUFI> znFf`%?#(pxcOI@oS^#|K$lx?TtmQlm=e2u3s6p=wooCsAXAD2XMy4i+soUkdAg0oF zaUdh~XokO~=yez(>ypc?$A|CUw=w&MG~0=o=db7z?e7A})NAy=YFW-JFuW@O05Dng z1Z#9b4%1=A=Wx&nHSTMB{>Cx%9Qi#I)|y=h;D_aF@6|Se z#XvGl$rP*C^N2eRR94M@v@FA2O@@CAcfwmJb7tkZ?P%jY5+b6k-Rj zUq*&w$Ig+ndrXP;^&4@!XG3PCg87_AFER6N^Oa3TO+@*|G!jFo3dz#z^XtzxLw^1A z>OjOy`RA6nYf5Whpc!`V?~YwAG1TJ4Vh=q{b3b6>9sGa`Tz*L9$6TFzrS7C5X|K>L zg~EI08haon2lvI>)M5v!6-K{URD81zsD{{!js3cAqbtL;zSPz2uY_g?{%~TeP4dg2 znO0vNF*U04NUpFdFG1FqDsjBxY*`i2Qr398qWu%e3o2PwZro)5p1R?&B z&5M0nR%A-VSOnM+Bv-LE@QqSeUso+}KpreJ$8Uj)^o-0?QlsLTGu2{lU!ecR%)nGj znJ3oPaZ5(Rc83)q`cq-;V{P$W_&&>akSesZd9?2CXkBKpGck3iYF1vsmS|T`36vO?_iNEn$4KDI=u0}hU11JmNvGd z2bZa6Lld~lJ^Z?kqN8Q*pp@I```lAv&i5qeFM)I?)>?b?V9VaJqL(a(+S4@sX>uX# zaM0-huV|NA5|@xq<aFEgST8C~2t`NGL4*HkXTQOdzL+ ziYVIo*>g+cgB<+;KDhi6gV(jGRR)Z}m09DQE**B-#I>#FoC5Ggo?BcSn-$uL^@wcI z7PCvpb_0Mjfh;0u@*2qeh%`-5hcZXQrrbo@oxT$|hu5yO&P?M#rBG<_iJa(eK%aux zYaq-9zNd$yPI@Hva#?hSV>@Gy`r|tC0;+##v=|do6?6_aD$hqQQoM`$mikz0=j>VA z_r#CX9`Ca=?mTP_BQH1Az5jKu2dsDSBD+xNm;d{?nVCm&;e&5h$thwrV;&7sM5kaM z*evee9fr^C6j_xgDZ;6CJ*CR~&zlGQ|I}Pw^V8I+X5!933rzktJQe#XOk#>1j@aLRb3R|U)7!hn zv>NQGpOcMc{N}u-#+mw1V5+5ssd?mqq}CE+dea+KoBEyYT^0b`FYErd#D}}Az=zYq zKEFOo&bAn*!c%ozJsnE^u`f`SMz?$Btm7NSZFk6_%PAa%mj?s&Kse#ww$v^DG}=IR zywU}rXk-P15PrGcF-O|}$>Xff#yq$1fvg*lTcATZKc{A8avs*3pc4RmCy$+dbDFz* zPvHh%UBBBMrR3@1Q95S0A#F-B-$|lir>UAe{NlTq5AwS4L*czh&>C_h{P3xnl8QJX zR_nX9DChY{IVq>sQ}kG(VwiP1l2x8}LM14bkl+gY!!Q#use1gn`i*}d{$BlD`(xL~6gE6jm9x5(@o$Mcb zw%4`*lJ9ivmVhoI^=HAKX6t9_qFu=!Bsjw-#mfD*hUTPPb@@Myk>#{tE~yENcj^Cx zkNgn=)qfo}XfaAUTDs8j!9SzvzP)l+^lh>|q~Ix`LF$if}@N zfI&D*KBJg{M5qonTh%MJK(W)7*3~1hI>i)i#ZqWD_Ppo!&FV5sJ3&Gz)!_N{eJ-TV ztXyXfrXw*G`1aaE6*dh#d{z^;9V!gU*3#4cO^GSGf071d66KG?n#K_b;o?y?e=lC(FQ zt2s2}w;On47CWAOz2RXytH&|;Gp&=y%Y*QH`4>uZsGRsjpW|oF&~Ui9`28DyK5Znu z3{P5;$)Pxy29S`2%s|ovkQ7^EF`5$i^@3>Mtw(&OTuG~73Qv7b4-EROf6dHucjEul zMV^NUe&X&gPvmb^dU1UnudY`}>Qm4zXxRPyfwt0~<&waDyRvTe@%J>GR9r|>C_!)g zL7O~mc%yCEi=t8yoail4TAw%pJ-zwTuUwz0ycw=a`KKB@h0MuQ@Ku%6g3u38(HUH| zFfT~iH!t8i$HkqpoyabZhQb;0K$=mSx@9GlPuL?a6zIR+TeV1CBmMVjP1E zoV&jPr=h$X2NdUSKA0lq22*uAIft*geO@duQJ_s$uY0RIQc~9Ipk4K3Z|ZHc9%CXH zMiJ2uB3W+i9OLiVzR~?X;w@=F_gN+o?-DmQL9c`lXoqDM_?7SST@>18L!Xj=8WI*X zBXb(kZ!{-+FQ_S7!C_~fUf}zSP`^=4hKA!=J-<&TCK}Gi;EL;hp;UtKBdv2vg$VMf zN0a=Ki^=i#@;BCuYqkdx+K3{L31KO^vJjT$tQ0l;qvjtoz$DMFC;`zujL=5P{q^KJYTVZC39Afn*F4Tx#pg zvByGe>+^HN zx;U*yKYm0cm^FcnE80(XC?d2+7`*@+1Na56wmUZN#<2pmi9HX3x&K{}kcF(yelv>p zVq`!1hCuahR9zIXFa5Nj26|M4x9)II!N^!aa%t2+3L7(f2zu!Wx8)jj$Dcd|jN;Q= zH5rPIo6N|}+@jXRP_ShEXg0Mz>-rxJY96>16fwHQoK=3Y0Lm zN4?!?Uzm@~&q6X=)JIGSaB42rmQBOEygiyx@e2MLjJr#{EJc&s!w_!-D|D3p~V6sNoTb zru=-!QVF9#0`|C`2jIMc6=s8-Tq11yOT^oy7;z&>7Pmi2u05BIQTUlB`m~MyiQoR&WlZvtcitz|dWi-MgDwSq5P%Kh5F%BEqJSu)36*v^3AruiLC5vzflTw3$;p#&YXzofb_YdxSxsKI3N5 zT|^!C;m`OmhB^T1xwK4Z`Z>f1U;??5a;L~>?>Q>_IZt4Nx0Mb3ahn+~;QD#UH*Mym zwG5l$(MOb!Yu}INM`~)FJ|}26LA9MLVN*WyW&(%dczR3zg9(k=A;dq=Y!;6OFYT$N zAIGKlEF?2|VPhY^Xmb)6x@d@^hJKZYDwO8Td76P>h;w|%-BXB+xu(FFT_c zs>_S$iLXrMB6P?mNzW$yIZX5Dtv~`C#SpX||NARG{zrj?uwhQAkxq}7>Vuy6 zEgPtbOa31n6aI~82FT3oibDuuPonrSnv`@P@qW)+sR!s$;>JMA0Z9CZCW)z52wWn9-T=_T0rf`g5tYjGGUcBNSk z%u+(rUL8_G`<8)y?nBP{$Mco@)-GdSsxQ+7aLRr#&coA~+u+0dVLq)OG4F5`7ZYcX z;G+b}wvFKhx4Yd2Bzg>hwH5D;yZl`R(3k$c|6VNKnuMy;Y3dlc$ay&H$zN=kN+|V> zd{n!XsnF&1P{wHY-q(#i3*4Bru_U;k4^LztV12mN-X-%u#fDQxT=FAVo{!Wc=pO4m* z*ITF3NEZYg}ntT+7Zt{4=uP?Gt>2;vP2jhGk|Bh%!v? zzN?1O0>=-&nqOJJRCNP8bMp46YBM_x3qwQR2C*cM;+rFCT4~OQ13DREzoYG6#OlGHuY(FI3+l+ZMwy6$|A=6-YSN(pb1(kIg7&*2qXU`a0o@71+mxo&Tm}tZ`8@dQpW|Wpj~{FG(0(TTM|pyDeK5eG z>}l9GuT>l*k0fTNn887^JBt{ze}#{vhT97u#!9NtCgV%e7l67)-@2HsI{4T5A~iWH zigynutIft>!e-UUv=PL{5wRC`0T{t=Fq6i+j&-ifSBpne4<;;#d8|ZPi)}UGi(bd0m8jD~@E!RA|H9UVXc@G}m?Ees_bo?p$f{)_(om zr(zg>D-}3=?#TDB>Skl?(#gh;Q3f#y?D**-rgwcRZJRu7oR?spL@D&swbaEcm`iEd z|0dZrkj7Wp>Kjv(o(AN$Iescykn&jEi-2%60AiDx>}b$uFM*>ak{xYrYgKq+JZLh0m!fIVJWf5$SZv6`T!+R`w#CXPa_Fw7 zcR-li?-rztbVoXr*c>(eVZLD*7DjjwVPMBsRb8tI%@=|a<0=M$w?9*BEy7;|Fn^^Y zueoaPdpDzlxgjjc?Y9QfBxcFb1Xu3bkbnZ~r5^}6N_h%mtE4Q)DAbf&X^6%mWvFi}*#^S@m~u9rN#zL?`-Ox-?umx0 z|KU~p>u*{+hXnWe$X5-%v1rVkfliZx`Tm@MZhc^s9%|z^eV!02su_O-kaPHu2V2Z@ zsfb}A9RcHcX|4s$*ew^R&g+@N#*MjXteJyB$|h&G;Dw|CDVps3I8{L7Lgaxdd_qxSL3)vqRH zQ8lj67vz*KiFIKQbQVDT@VW|OYTmLHHRQE31I8!*&H@;_cV8#VTyDVA#2fOl@@Zd& z_5FOU6Sh)7S^E~3UR0MZAuwl!ng4q9-Ew$a<`oE_><5*#I&p1ZvvcuRm*HGkU~b_t z9rsW?BPi5X!SafywKla@!uVs@;Mf>;+W{+J@G&5?!p_mMe(}jd3V?#1#m-t@Su&Np zE6OKVTmP>T$zlm(EG&iXs&zeOx<8~=$ou~LFZaDdJXLwilTv)7p8e}C3GHd2E}7*! zmRyI?*(gxVqpI{+pHEUi5+9`fdF_*t{nkvGRdb{|uZQmuic7+@I{P9yn?-7a3!uviMGn7b^VDGi?K-BZSx#y!^%Dfk>%71l9+U=F6 z@D(qEbh_I$E{D{;2JKYydz&pd_BT<(M91z*&FqzRxedSm-3+!B-&Yl{(a1+e8pLMGcQ# z3Y0ZK&1!6*%6ag0XYCm%opJ;A68uhgY}L8q#Eqt>PebJn}moUD?xcktrY+bP-$vzDq`BA1KuF-jux;&*AIK52h zvvSL_r!`h!icZ-$`qK2Fu7W0hEuhTce90a~=&aP*qw)(?fBfyLYHqCE73cI^sjjxU z>)^!G>Yc7sNOg6h7^%BlwQ|r}Jkljrs^X?TPq zb*bE!TK3HYr9DYur&SnsAk^`b)aLP2+}Q6r&NrtcFa}?k%DRWs&2KuC0|50@tyPx{ zpdvNfr&Psc6Zc+ZC!kjEUU8x$=ASXS;Ux4N`?6&Yq?TY^DpCuJSfh|Pz%loX>o-!| z4_8Z{O(nwQj#@_?wLh62cW~?(O^f07{UCSGJuUk4If&R$4H9}Suyy%`b?~ikazHvh za){p=Q}CfyFAa4!0VW7N=D`tr9{V|THzb7YF z%?R~BYFxvna0ukXIfb!*C978PP%NOP&Udw&b}Ade*b=MJOvip(9GyiOEz(4~=X)|- zvpA;?toR??ENfL&7@n;VOU~%Ts+?yDnJhZz5@Woic1oj{DBkF*xB zx6&#I@$T0*?@$R`@{Gj;Nk2v?+=Q9<( zuP;XMUY_qBQ?bn}J4s9}C?*)f&+uATl?D-clle+_qx}!~tFpy!V&sK!^d|g`lks6V znH!XlalLlx{sfCbM^$ETtotp|boyR=SR0oNuI{Yzd-B@qB1sf<#9(qEjdARIU5p5H z(qx*3r-^1Y-yGS@xIGZir5M=eMb)1_Rb9}yQ6x3shha;zo^Lq{#-CFO`z58tj&8U_y&dMEgem-9 zOl7$~GQH^T)Gz6?$_pM)Nl;8=Krv|n%VrzpDLnF;gqX$DiSE==)Y_NhsaZ>SopYvt z7)V1b3qaj`4}c@tySNmvOc+T5p_eHZsjJP>6S@euz$b;f>1@wJMA*t2MHPH{ex05k z1>8XT(N5djmnbvk8N&sYv4-nIz+pEyKUjZk*tNqlO-heqo5a<%QDpx0#kN4gBc7Ayxb!~@yift8w z6s;Mym{;W}bAL{{%IrHeS)_f`^TMLfcY3v)^YdR9H*ZppcwULW%qn4lHsK~zAfj7;r)qtS&mN*sMXSu!xA#OuGF)^dDi4q!|1K*Q7}ZJd7KDD{JLDy(umlcwbo$+A-*{30cH_t2l1ZS9F8FAUjwHtk-f=CmQVRo!)Qv}(w zZx`HYuzAWA=|KsZIa7c5wiKhgtT}u*eOAoic)So{{)J-j_rcx(lR_ZYI(3r(%sj5& zruM^s>6fFDnuK3&=cG7k1ikj}6!@>FoPYBP-}-jp)+rqxxDMEXR_Cd{fW zjZbWA%Sn6m4C+O$6tK@0Qw$il$-xvc9=Y;gWY(WiB5{W!u?SCp?GpX=*k02?R_IaHUtDx_qnN1e8qTt*fAzPY^jF4DDDr3b-cx(^i7;MhK;vV zY{j^rtvBu#Je_AewhAp-O7^T&k(2C|MYgcC2J6JKaNyindVt^JPulGe`SqCobkVNt zl}7lt%EnZ`z#US@X1W}&F|jTO`-`GW|4Q1mDk=%%w4BkYMd`Ec1UNU=5kR9+9rsd@ zuT{b#IWiS;vjF$|u`BK$Xt)gB3C7c_qX0}}Aiuj0Kd>=3n8QAK`IsoTukPF{8a>yf z!mS#9S2*J7?EGGH%OuVo!lQs&Ax1`8yH~ptIjX`|_xl%4) z-7l=#!D$%9UJAhQiSZPMjyKic;wym%_gaT<4KNHF9PVw9&Orq+a>z6}$*K7Dxb&uX zvDfoT#}yqFolM`(y#B@ApoRvt|0qe2&J)lN@FDZUd4b#iqi)%wvirTLY(MVS6mKbe zmw`9`py%Mn@H+YqnfPVW9^j&iFlj_;Q+W5sb>p7EqYF+OFJ`}3XI`pzckpaYKz^Bw zJ#jQszm`pAGbGD%({P>@0e!dIkB9-~+=uV837}#;G~ws5p*{lArM86Q*<)=BFRT;qZlBN( z6SLj!?DD0yYB5=@V5J&U+HFFa_oUZ_+#h=}NC1_z07{buxwZd%%vNSx4d|%Sc@7k$ zf(ss~xsuKy< z)ay*Hih#7%{Ptm)cNG4rdJ==$I3Ncl zAh}zUAD}lz{GQgY4`YlDuGfv37-fFfopqUiZi4eSQ$7XBO^E9NI5Db*>;zcWFXJR$ zw@!YRY^(Umi<}J(Mx63?>ChfZihI0bivy?ujJX6ZO@bVJcG3;oFWVOF`XXq(T5VSp z*YlYR_sYEAf(KyY#2rV&5(Mdv$Ku1v$x$Gq+KuRJc?JIPFLcwiTAk8qc--uKRqM#} z9~Y?Kl6Qfde&;OjDV8fWospW^5_8t zw&MMxLlrWBjLa4=gR3WuI(qC{f1T(|ovk}d=w9X9Sy^rM{B2YluIXV0_>J)kI}YQ! zmwVzqdSby)n^OzTILWDTB917SJ)hAUYRqlA8S>T3Bbwlu87uKXLg98QYMrIpPK(;A z{Kx-C)>p?x*>znHAfO;Eosv@0(xD&-2#6wGN=Sp!jiQ7!NOwqw#LzLQgft^LGK6#t zA>H2@yx;eJ-skgQem~EgbJkva?X~xHU9N+nJsxi3jiQhHP(O-$UGeju7q)&?!)qol zm*?kYh~1M>2E9Ab9KH#uPpH8-$y7OczaF`Is}oUIKq|~u-R+8xFis=bSo%<1_5v7$ zu@>qYHI3Z1It}2WU~IPb&1W-exi+{@1s<2zJvd+eKvq^)u`N_?0C^m7C*gd6J~<+@ zUSLLKnt$*$(pd^~P-d^6o4X$XwxH3W{pRYAGVOb_p27_diFl7|{O$8IVphIqf{w=WXdlZzpzMWQ;=yJ;Nc*JSy zWMt{$@m*~9OaohJp>2)d`Ex(@8{Uanvzp(Cj@^B%T>X5;ll)`yBI|R&$7OteLMt+S z-29DOK-T+)Hwoo3zxzD+tnTA{mHt)OvX9?}%s$9rXbi#?YR#+qbjFBS%Wg0;;T3!M zl&iI->l6A+NOL4<9n+9x&Xf`mrg+8m+Sa`_*w)>>{Fk&%PgCs(+Bor+58t>*M!PgA zwgk&=_nr-;x}Em2{zNq{bH1+-FKC!^)E?FO^OCdUO}nD&at6yZ7>R<$PMZbw9M%(p z(VS29nXkbwxMW*pE0?r<@Y&)XeJSp;s>;RkK@tw&aJg6203h~wQbx0lU~(e)An1}z z)N#t7&x`$ag-Avo(7?Wl8nxy6ox>=(l<-lJon*C!RR0>5pUzoJ(n?Pa&gh?9-#GC1 zwH9e~QFe)3r>J=gYm#p{#uiNbl;V_~H>h$FP0baBPNm7w^&I_k?S0;?=Pf|~2##%! zMTwrP8o6iXqO&MH*Y<`yJ}!8--Wvb{ND?P4W9`0<5kM<9>t$x!gnqg>KjLV5{cPdV z5<}|qkNjd;L`=guLb9qKb=o5I(srre>48U&T+I$Lar{)9Cv;%0gCqkc+BBlGZE;g4 zoNXpAFG~5Oo|;PottM8%(YS-7NmK<=(TttG@VKNTyROF-H#Pw1mla`WubfdMy0_W`tH*{LE$h!0JJA>hG~O zyN$txcMCJ-+SWCDJCr&p6;fTjjSd(?t%~cGcE3UnXKQ^gj_6O%#s;bqsgw6`*bVfV z=zA*>Za&)W)4Nk~Iib%7Z{jCPvq&Xpi$`jzVSTXwBUMhV8r6hO$cKGTCeg=L^r<_0 zV%yX*B2SATt}Gt;?1sa~(uN6F{MaR6%)MF?OxbG0foz*28;?DaiNPn@dQi+H(hG=t+RAADkZzB0`t=YkQTSsSmNw!ECPrOZ#_qx6 zdvW-mRtF}gz`@O^E~LKf`=aZ6On`URYZz>*Xdk^tD5Pb)C2$o+Kba4h5A`5Gtf%YWS=YK^~RLUieK-eQ8SCf66}> zsz1N4<_I;`7-PLK12s3M>#{aCrPHYHiH`|-bm>?f1hP|()HudZ^RjgaWw@rBpN25a{81ZI_S&NQUTDWmE;d}T^E{4K#3&KWh11t=Rzlaew$wYe zeL(xCz+d#oPtzFY=R8}_Y+YP(zTnjB+6NIUdx`A**zMJZunkMsWI1rpHo zhwi$N&Jp!EFKEzzDQ$a*Y!I?|T(^F!uRbL&O7)}=L}wGYV6*sckm3o5Ebpo6uQh&) zx6JcC)DE1CU3EvktC)m~=tM`^9k{9@z-jyQ7*FmU>oH%67SRw}5%I+G zE$6v1Qu)Vyg*hdw{_&WZc!yIj!qur9bPDBo4F3v=4Nz~ z$Tzg3w5gF$t!(Lc#Y+=^4i{xZnyYqDqM40F`47qFE-T6vIZUWXJKY$X@1ML*n1{%2 zf{Qe1^wtBa&)1oq#04PSWwQXR0dZ<}@clk!d{OowyCV85`As5qnY~Bc4@;ldhD z>6UnCuuahEIcKj^%!Y2TbTA-0fJyMUEW^-ezH~Dw7feFaTU1%oE}NiIeaiWUbz*dt zs|6PkDWYEDgGqUOVxak8-e9VWZ20{9L_o?$3m(ko+jBF1z1$3vX8^}t;ZSWHbXAfJ zEn92i2u#;rq5~b67vGa%4tm1B^nvRXP-F_VVnY1(26zX#FL$3~yrV2rR=4lSILAcK zDo6W>z$iD5yOz0{r6me^K@pq>~|p{;(}n;W^SOwU28R80w#DQ)4(;i-LI3{&J$pV^MZ98`bOP|=V*9~#V-2~j~&!~ z3}xW@50S&^!G{Ir1a|sDPVmhHmt4j7Eolj50M!T7*xDEMJcAtl)Q%r- z?XIxCQPzZmYx=v|T_0sy;D+-WaAhn>;K)hjy$ERSbd_uBIX=(>4X2ja6yU7qnk^-A z^cVly+*NN}G_HO+uKLAlgRSYKM_MRU6=9sRX#G=g}61vN1S#NYI<)wgYn*nVcAXX*D;88gS3=^l>Vb2xb^azrO#`cNT=uws{6nk2XtflErY$uSEE%(R)(RJREebV zCg|8iJB%jS-)%wECEJC*cHdszfdCtzv@1i&obT!^tUY zE!ah8dH6b?KOOX9z4c}1VeBc(u|i8WpRuNG^R{plcxeuVqbCWA=1zF`_B4$WTkM{v zGNZ7(h5BzSr^m6UpH9rD0{uQo<(6Y3=agfSi~lUtwlZY2y3ejejrE8&H|B=F+|w1n zQ_<@GOq9H1B^vxDHrA_NQj5MT{)eUMWpDP)J9gN|IajW?=80Z8g^X37UseDMKAlC4 zc4aVe&l&i~dF1QaN?iAi1)UASByKp6yG6o)C!Td9;?X>@y8Fwdav!<>GG|LhbXeE^ zrvdo_R@`g!Eq(pI*6a9W)?`WI8ofnk9+C1%8a0Yq+5Nxr+fzaysC{R7i2P` z#%&HH10y;?(pB(h1w&)ckPV|f*d>OqvgS8F?J+2ir({>T(qm;wf42Oa2x(b)-I2rA z#k|$~a?)ZtPiMj5-M=^gs~>+Em}5+nUd}sCm6A)#EWqe546gOO7|kFMJP(x~YXcTC0iVr-uWJP)0=jCdVxIR4J_|~ja^Qw$X1nx^sW(~o65JzGz78}Rs4OYPB zGYv}C{*K;_W6p~NrAh~MyXH~w-*FEzNvXuV3)ALfn|)%YA!+}23qImM0Tq$3gV zKKU1I*x$fpKW_to?h}B`+nM%v{yF=!41{F6fV9f z$6chhgou$?DEsrR&H!HBl)!=Ysm{yOA7*7j%<_(n=CCs=4S>k9|2^CUS85Ksx5a-7 zMwH|VssxR4MYfEAPZh9G6kNOCnt6J!=$o^0O6l{j6-KL|hY4DAdIVNAUO_oWis0a^ z9x7k5S~me7$OO!P2{A+qTA#^EgLRn9KIsk7XS^`qdV|EQp%mJ>;r=;lEq{XR4VaZt zvdwY08~PIY8%;wzjAsu^C)WF$Hk0n|YZtaP=2>ebTi~H9+yGY2zxHPzrc+J^=W0o8 zE$F3m0Qu6FCd@F``UDQfCSsXBLjB#@3RNwERgvX88S|C_+29c=EuA^~U|a;^#7Yes zyjikdL9CmO*g)W)_SV*}^-da^=(sb>&enmR;kecLNy%B-)1%0%#1wCo>tp$O{U&Rt z23yO|oAGtPC*W^+dh8@Bl{Cq@sx?lpJoK?9Z63Pvj5k?sPZL*$o=ZU{DDD5X- z5KirW(KB+isawAT%yuw(B4{guKHZ_o);4K}sn=gbE5Gg9RDV8{ZDR{s1}4XeDb4SA9j{FuP}{Yy_vh4T*r)Xt6Tw^#=pl(*vc z$c3~B0f&eQSkq_GDtoi0FEp}Q6ONpXj$YLSE2e-5dGRfOIjOhZHRYxcP}Q5+Oq*d$ z=TT3>fY1fvcG;n-_$;e^jgX;dhq-X8)p@>hVH3~DF6m;>M`6xY-gieuzZ!4{TWgeu zH?bPM3hEhiy%{hc*Qe1QWqK^a%e{F&lcM?$7!hLJeT7da`}1R86|Q1)7>Kt3+y3q} zZO7z&bWTZMw3n^PuZ!-R^SotX)M}msUZ4X8*eyqMhu0eL<_XH5ML&9_dh#}Jv{uUy z9nm|=i;!~xTSHvd7y)?m0~bBhjR=6ofmcfr+I_{pwhk$#s(#urP>)7bK3{0WlWW{a z-Am9bA-TFTC#2Eq`Ga#XlQXirnG+XR&u1v6FNO+lg6pwKb?d}6o9PwcTfK81idZy06hTkprq}?dxl=n@ux#3 zPDnv|_B8_EosatS9|}Ch(UrC-9(k4R^KQdp7e2a|UJqksIMB}_H-m|r02b9<2r|*- z$~0!3-erB&AQj(0rxeTR(VVv{+B0N~ouF?G5B8(3Ykl1%2QaaPbf)U^ zYLBfPdsTjAltN&_-Pp9F>E4lf3Vzo^YBgi_G-59%Z^mJIXxmB!_1@Yo(jBdNF)W5wtOrSS^_bcH~A_utV| z>`+k+c$+eM5Kd?EslaG&IdI@lA--kn0m9uU5*F&Wy&gS9y5dJW<&!5{5QTeCIs%s1 z@R%qq7v28?SmH;eBiz8I>;P>X)FftZgwPrs?k_|rPkXm%-&%(b7JZ=P+xdfLVc5-( zf7|Fxuy<-i~Lle!MqdcOzL!X8Vw=y(Yi zn4rshSm;`B7cEZXZ*nx)QMbeGT-sl$3H`w(^)#^pwLNm%GVX>H8OVQNc)2+L?bmyr z)7a(m(Ol!oUWwFPj?VO$c}B&!E3v{-NqW4YeBPGbR^JRnhxhoLkr;VDD>ha9wPi{k zmfM2wuarE*8n$mOa7L@nsne#>*GK#I=l44`rrlG}4VU@xI-2D^q0lo>A4BLgOIy!y zu$u=v!#}e5>cLO@pCqqegD6d0TVmLw7KskyNGgRj z*!p`u+1gI8EJ~T_N`c?~RHoY4XmXKsoaJRFee|AttPF6p3C0EF^jX(A55;a0S$eTW ze6&BKwkZ289dG)~y#FD%%ST>&<$Gm-@5a*nj9?&^BEM5fR(demQ00oFuUcrUKyv;h zwS4`D`*L;pv-~NAGSc!^F1vKWFcbjbwwRuOSflf+o+O8H&PSh5+0LPPj>*}A1(=vW zdGj?a`yg3RH>>U-?*O-`rzD=3CdEgx1! z+&wC_4w{zxjnfB`zif+B&i(;8dY}WyP5HO(iC()8sf7kz@t)e2G9FSwhm}omN@O3{Rz{}>vNXgDxdc)mf3-~Q0HPSBHnlya zU-Imfea+Ei4$P&2gprE(Z(loFe_6G0I^iRFet#FRgEIJ@m!_=|ZeG0ONL!X9&m*@A zU~*|tC|XWpu}pUuxFrQjGTbX!R|A8=H{>J*fb86j6_dCLdHOQ%rLB(R0M|OlR%fP7 z3;YC8BE_w~4%k(L1Kq~v<*N00LYQdGV;u(A6$Ee`$WY4Pc^Pmsm|_S7P;r-;B2{Hw#ej1epqWa)ZhzX5;kM zAZi`x?2jlzFYmpL{HiSx(CX9dm&M&Wg2sf`cQhu_tZVz^es9WDh_a`oPLp{pP7- zJ$oWa*BFM}yXH;F*Yiu~9ciy(_wjDqM2w5Jjizjt&TWE_<#+YjGTvXr7X-%mtyxh+ z?p0~aLZ7I0;w)t4+Y1G|?7ACfd2x+j7h5Y+!6k}mf;NhEl_T6g11f=@Qs);LLsjkX z6CJWTc*tlvuKaAHMb|cvXM7(uMs@oWp^}CLkhZze*iB#>71$Sv4T2v(0A}$?4zub= z%oYZ>2nPkK+ySrii+t_o@jWwI6#-I#l%qD^v3b)TeIsJ8(GB^_%F32w^K>VM&Pro9 zedzwzpHgU{3h?mnbY#E`@guKP^pgiZnY`rQU~Ua{M=vuvGYbUHWNdB2CXDQ1Wls}# zd%bxE=sv(k@O_#r=Inl@{H(CZ(41|=g=u}!mm;>`l}eunMuF3rOyz9{UrSqmc5C;{ zRIAe3)iS(4Z+~1Rp-{@=3a2i);PnmIeLX zvpF>7mv;1xW~fWY`HX)rqW$iGTUQNR-9-s34;pt>uf)8qyX+)Aq|4p7+RMBpUNxUH1$RRx)q47rjA%>TUEpBzCUs{`gzPQos$@}sxZ zN4C+WJj%J4_v%DD)$VB*jp=i9x}{@EeGp5nQ6H2}|wSUuF2OCOgwG&qiABZk?@V2;9lUm4IDsXS*4Y z08)HSg`sI(<_Kjvr{BS~fLiVH$&;!<9DoT?0nl0h*T1Jq0B;$RJLO*rz`IO^oUc2vf2Z&)*8A(btP4*aC z-buBz9aZk*9cO&MIml)W#*y3HK69XP*uoApY1#JLVRDNcb zHDjqfiaOmMYb1olfCs6z@c90OBi9GZs&!;<#G9D>8n_0-A66tYkYjxh-a3sUBDl$46q}{61c*TR_M|fw3Na7%Hnv* zO=cx>Nv z3A~xb^&Hz9^pYSjGCf<=$HCMSbE)X0`_)kGutvr8ag)X6?@i#%OG7srolD~J>#J_1 zuXM#uTL<;jH4fPM%Yq}_UR zXgw8jjyfF$Xk*(pvw_p$ytflfLu?xrJWf`zuM#=Szmqo83;H0C6{f!~nX1YFk>w+N z?p52^Y1^P4BG3j?zok?!E3$cii>b9>a<}OL_aqhw;+jmblF3C$6P(s-$dxQwUGbFN zM0H=_1E2SA)XU;M>h;<9^WbDqF3H?T>v8-?>lOUHmvtkh{V18I5Ir|OL^`=v4?9O{B0+6h*VhKOW z=0-lVPUgj3Z}%j{5`ZXuWANB0-+Km1fF$aS%G@veypI!XkZe0E?@;BWk(x^hsEOPTrz2}1a2;Y?GQjj~(@s#` zi_+B!CnQEzHE=Zh(k>p<)V7)Op>vD1MHw{Fw|%55_w9E&XJaq`FbE3xe+B@63rMP% zySC-^Btv}M70>CNL)@Oavg|#1i}C~cU-N`}1zplB^u>IX6)S|lM**x|68Hs|W!-d6 zCXht0btL%HJ8h;dDo4>zQZkiY_{I?^tx1PcXDI#6^XL|~T#oL)ZW-)`gbqB4^&E%_ zbW=3)J;7dqfK(For#<^|dNG+Xl~bFG6vc%y7bIquGoXscnTEtOo=;7D5{{B@LBI^| zw|faj^mj71)cPh-z&UR{E(0&4Q+w&B0Sbbszv64K$$_<_j`ci(nrq929+Qp`(4He` z%hSo4cta8f|h!ECkZiSUE1$%rTGph+Z$Xx?orOZ;)bYB?nJA6Z`6QdrZZ z$SdrbbIh%Z7#Hx^m#npFM+3NoneVlOB;XP@V_Z_eCCJ*2P8r?U3@`I62mk#Kn6?DJ ztCU$UxNWm=9H1-YXr@j=%3970K0GkFy(M9x^8R%xB@eZ&?-HKuJm?2OOcfXYPWJs? zqhalMpXdK+54@ti92^rX&WaK!`i^t*0GrN!|E?Venw6liZ~-nt?01HhbvR0O3GobH zocFa6mP_&52Q}ptrs%2=qWr3CqnHojCCLDs#+G(HAdcV6p)jB2NcEg*jDgl3&-7Xk*WgH_py2_jo5O3uC=y! zw(}T(oFT?AcK5ELyQku-hPz-2*7~81!^EoN@v+f;OOpYq2y=!kEIG$nHy-Hnf8=xM8|65XhEo>0&t}C0eA?pV1+BR$Z zT2G0RoY{8Y+X~i3)uxC>^$_muE%;Ojnc&yt=vIiC)$9+?5Kf?F+^U6^w*PqGpFU3z zX4YSf(U!hv;5u=h#w!`lL7=OE$}xb0C-ahM_J{0#>ENr!e@ZgL$Ee`|A}+H3tkucr z92&iT_q(N?s1^6YX0 z>FHtU?lygVIQ9A7ttWS!OkfYqZFBG4)i3I>Z~Em{GMbT`*DG|dODN+9>+6W$eX&Ds zlGA3Akt|)d8+Q&o=(>_w8R}39pLmLzc%zx0Gj}}v{?%v-;~nI6<#X~U&kryD;NFjU z`RrCgu>`a^b9wmZt?QU3MGrAu2c_HAB@(v1dBBI=ZQR&u9!>|FIgS(FE{<-4Y{$hO zs9Oa;*`0;>QV4P$%3?mUc7Jkg9`>ib`%^V`z-QzGh5i78RfXyop*z~p(}e4!2wnw+ z{jWsCbW)CtUh7GyDD$#1*pvgJDR#Huz>qgtmxqBs-0cHbudP%f{>4df*w54iJjajh zVD-k^6o`nBQ#!H3?9K(OBP@t4pS7c$WDpJGB~$u`$34E(Fh^VWC!P^%23wJob`A|B zn$P>~K5OtQo2FX4Rf;4<=1Z?_S%;-8*GPth*dP}*#ZM8M%U^%oU%!u~R}~#)5xzr2 zNEs;PsT9jApk#BTazA@vKA4e#?|g6B-XVjGgoFfncY#h$)rw5vC4y6dJQiykFTfgEDHC zz$~Q}4n9b~qHec-3&H$4q;yFAc5&8iNE>AKxw1DlipoZcE^F`s`yv8Tjv=L9GfahL z*gxrw_qIb#l=P03iaFThJlQep)rg44 z0~7nCJ026YHp^A*3Ni+3CoxZ7`{G79aG-C2JLUyzPT-dw|DSA{5#m_0wvda*@QmTe z>`qO|iubmL?2D~9vk$=u$eNkrR1ILvbd!NgAK9pnS9kgLrxrdP9f(5ED=6p(aeVgI zsdFwqt%3^hR}~{N+ioR&ZPLLLq*Itu;4wsLT-xVGN1eyT^CIAF>VVnt}2#dpErj7n^acd?b+d5(rFo%@N!Y%PQ z!(er!lt+N21mSD&o&!RnxqIgmKXkdqcO^YeU09Mg73vK!y|cCKPLx0#*^&FAOWT^i z)AYHW%NmNY^4qNIO|bo(2J0K{w>P#0@<(`#akt504;rEJg{?aumU%3mZVEvTY}}tL z9^sgs#|`i^(bgD*gg6MY*bD5r+!a^{C(!>Ff;2LgA3|tS1Ykua+FRugT}>-Lasz5? zM3DnjWONPMdm85Ut07%A&u-Af!{$!+V233Y!~+|WP3^M>SBF5B7l;%zae92!%| znLt2hOpUvyWY8KJ?n?D1<%Zi3GYB(+S4;deL#!S>Qv`g@!3t za(Cc+Z)0FJ9rGkzRa^(2m}X8Urz?9V7tv*x#8;=FX!_$hYYq!>gNfva!jDprwrjKQ zY$!GBt|z_#3WNX(l#sI;H{9pOt*ppzp3BCN<|pzBBKDTtzBbC31`YA*5jLI%){fon zZYVl zaI^z1Ac@yt2wl;f7>h$=(T!pJm5)D{HQ!KVHlh>bgwFiwCMBf#GxGkZfZmq_@1Ff*i5cEnu_T$WqS0~7mUII)=<)_A;lR|NgU+J!1 z@XUrQo_yRG1w>8YOr$d@m!$)~bK_S{UFU-Yo{gu0j8sysQ>hnmZK!Ppel!kMKGvTS zY~r4O^8#={ts|^)oJubnnQKvOo3H$-;Yk z4w4SyzYtE>L|HbsNUWEa{vdB*2J46;_F%v!_z4PJdnCAaa>!*Oxb`RknCXCL9aVQV zI^*mvPAq*}q-XCcb18mBBD$i7ppnW$-d6x027b6OEpE*??ToPQC0}@f%FuuFqDuID z`Ux=rpJrF>(w;3xe*Vs-kH6nZlc+A;RTg+2#)kDsp_+KI5d4O`>$C0{XR&!LFHltQ zE^zUH2S5z)ff#5Ezt11-N_ebTYYk|KH+;vk7C!!lJAG~VUmhGu3&)5ws*G%%o`1X- z)nh655}^j|5zS9((1$IqMyH1>y%KrIhmFx%?Ob}~J>$4*DT_Y+wcgt#s6hK28ZnXT z*O1GbFh>H#XI z^-s@2LV7|BR<%rG1^hK^ze^Q>(~l@y$^Ehw?z>{ZLFfKbr8b}SCk9yPl5SlOn*yIcG%93C7 zQr>C|7Y>b3)~Y1WVqI z9RbM~!yB^ksU~rlFnbLE5WRLVIU;V^jV0__e`v#l)M(eJ6d`m-^;TvmSZ>>HwC&Ze*7~BE6M6T$t4Ccz#|I7kJ+VOlOPw41!B?hNI3SlgZ@pVEi*T{$1 zJfeUB5&AK&7*cow&H(ZFi^OVX z<$KzX3VX_LF}&^?C{3@pz6qQkvxI1(*c+P)&6+7iKb=rK>_5=(&U|!@L~6#FRDKK-G=_qUGgUoJs4+Qlvcot58nAWg7pPAoFeEfFV0S zg1@^fW_}y2u))mZsQ^;BVhheJ2PTAAJf1 zs>+3O4Q>3hu0Q6HE6|d>egU@U zdK~!OG+>)K2sE}Eb@&8qfrN;U4L@!&U|I465~8^DztxodsOk0u+;oPF`|MQViz_>kO^!k+aXh#wedR6)@GjLaVFlt@SvxM z@FczMAhN&b%T*oi4B^dIBM!ALARhe!^g3t23@BR4=;bpbvG%aL^9*qVaJLJeoVfjD z6Mrq@=#F_7^fqK=AbgzW+wj1;!RmUAZJ~eya&{$lEMU-t#fF$tabeFEseYMUGA54$ z&qm5av#Ui`j(?v#9jWYb|90!2g|U7~MASaI$;^!=ttoMcEcUGIBLw~@gB3zCIg>1a zTQV3WI$jn(zBxjC+U18Rq4QJ%vMRoHw2BzMnSD~rtch4gcqoEMTH=t5sC1-rk8E}C zG&bB`#6U3=t0g4CcT3KF4|(wzaEW=ByE4Q#Tlj_}Lv?R)|Gnp7x)4KoW-sgnJ2;41 ztY8d4*M|fs;uBWFAxe-bFK+~xjBI8hL}ctywA>TTAsPz8+yKiTs(GDVExtOE+z)fZ zC+SxwhS4>c)B9DAbKX?bH-Jn(epnrMJyn&@o`-!~Dvc^IWxx!nwq#oqo2 zq!4GFu=L-Z9{wv&N7q zNeo05hG^+=@dnvh&<3>gXglGLdrfo!N;)as*uY&%kotPXSP`&5m5ZP?7_8`@*(`t1`(**(a+9#HZ z`erLj+7iAAm(0X+jgFG?Fi;>pePs))xinBmm(d` z{ZhsOl@D2aLR8MT+j`e}(5g#V!npem*rPozKjy`0o*oxA6-~DUwwyLvSBenM1Dm5_ zPFn(5%(Ao-cjLk!3Mr^KHo2mqf+=V_+|tB z6*=VOlfFI#h7QhlBf+rLIdwpVGD5P99v%YDH4a=RFXU3LDR8Y<3w(O(&wv-mlHf8s zg{$LRCtNz2bt{bIy>cA3=VHfZHBp2)inF-a2{Y=5T3q`Ml&Z$GA(3um!-hOz*c@#& z*;;s$9#5JUfBv&uyvWh8v2MYTZB~YyV@`~tafsi2`1EsBlHykkuVhfQfyB-Mcwcrh z$A@2V(GJHH?IDN={t{%oyTw0g;iK*KQ$OZT3t%Pvrocku|4+~;;NRw7DvH0z2u{3a zpg=sndCc=SvC<^`TQ+EQv16Rk1ehe&h!)ZRy#9CBMuev5P5+#zfx0)FI*xBLG20MM zsW@uaTHxrgpJ|hP2ZqAh!`6Twj_FQ>ThjLKkK@hb+=w(Ap!G{@iJ}y;HbnEBsDy^U z@j7Dq=8?jwslhLxmDZ-10y43-gJTaq_VBt!VC@M4Hj0BpJ8ZKDD9)7t&i}h~W7Ig=wDa1_~hmaK5a_mL>mhL=X^|cbH z!P3X8h|vt>w~E*ZvfZT-AO4zt4Jh-Ar)YDiNQo{hQImb~;&#C0L$Jj-0oZ7BOTnzc z;1z-y=b?(j$cFa@s}X~rB;qa}l3ZLqc4?YZUY!|5rLDEv+20H=g>T+2zNgeT;$Fes z(su7fEtXS__fpv3WsSlby-5h9LnSW!!V7~ous}gPZH$Wc`i9{}4RqP%&DkhWkNHt! z2}QdeoGNCFpur-z*1;qAghRa`r-(wt%8>W>`>Af7 zaHP*;ERdkVyVO~>rwGznPraM3^j1QlVK|1m5!B1wRdV{F1_O59^QO?k19Xw?@4j0# z`+|hE#Z`YF;~ zp#iT5{RY8 z0WtpoXn_Q2s%Vfa)>F3EIrJ}b;Jn}`Gno0WL7L(DpNI2^bZc*TtPa1unxUw7qEd*EM>f@)cKQ0nl zHMup{PdwsrH@tgwyfOVkNT)3LW}bXga3RUWOT3we+P!IM)RJ}9PTRrXlv2z&JmjE& zM9r$TD=Z$61Y}}vXR@NO5dzS6AUt~Wrj#H)poooNF^SEXYpy1dQvl*5WD|gNpN9gE zkS`Kf3NMo8fg6pPBcpSqrA$@gEuRJxu%4!?!aHY^X!ARBx4J=9(Az4hH6N2 zHiy3;XyUP4@2NMO0P%>T{jw>dsBLvfEK(9;uLvl1q?*+-~ zm?xzsTLk8j1*DDF+EGO^pXLZx1>5|o!}ak?vyV1)Pv!-1+U3T?S7<#A(Xd(Ss_h$I zq_>PUScS6vMNcXy${?oyEk#1C4oF`(uYQi`DB-E}ZuS`A=L zJ9GWF4iU+bu-x8`W!l|S@ejP7U^PA>_|Jkb3<`!RLhqY@24x`G3eNUC(N>QV z^l}ambbH5)8=H!%TjCy*DmwZL4eR5}?KQ(@MoI7SS%JT%CcQhf%>3y)o7R%Ef*-}l zZsSz)`~J+~)U!863_3C#f2n3E``<2t+JY?R5vQ{Es~Y*940d3@Y}f0;x5ZBe_IU5v#^aN7=2_>0qSF7eRa&)~Y`7@G+kByIhwUBh z_aHtp%ToXB5Srjb`IXQylA}0-Iba5NJ1q7fsK$)qBUl&Y<3kK7pkO2TOk#6^W$g#K z4e|za@iifesNdfP*eqRDuN_*A3kT}n5vvhnup8dY>U8qd8fbMJX>fWoV_<)OnyXR3OnSCD_|zNCUG<}8Q3P==rRa9 z;L@NeFy)&(CGf%N8(X6Tk4)w!L~w!i z+8ALb0FS%d`K8iv4^PE`_+T!^arms0VwU_i9_1(LQ6SO()HEQYcPvKKD}8FV9*PYJ zI5fm2)i!zKu#}J9aMUIP+tm6{nDj4R8LR)*>Lc$Xv5u4>{%mOR+(&`CLJry@VUU{u zKhD%WlSa>4J6<&bQAdJi*Eq|UdLS$pYYRKJY;Mr{8GUY|$@p|(gd8Z^>>cZbb#tK@ zn2Tk54c?K>xNH1)Z?~P}@Zst{bMh0Fn7wY*cEl}(xNKmfMTZP3dU6)h@>P(t4i^$- zmsc!+L)9nl9ro649HitNn|W=oKp%wNuTGJTGzAshc<2ThIi^ zP7NvCsR8;?l{V}Z*$XGhVwJ0er5P7`W$TJnopOvqf? zoQWRDMg_+Qnph#K1!iK~zpA-<{4(lm!?w$3QLM+ZT}Q&JxTn&U61aQjY@ZE$ zgV0@Z%|k}V&lNVIrh#s1Wi~gk8F@b9HgmUNT*K&#Q5~BT^-ljflm`Ow5eP)9doLrY zFaC7?E;7HSVOuxEv4gHAb0jET51DDaNSlMyweY<#q&Tbxe;zITU38jgHpvZl*rVOc z(GIcn5J0q%8y$hMmM=X?K~L@irOmE#N>8g{0K9rie5tE0`Q{MP;D)8wfZ3ynlbKpl{ni9iEQ4~2b zoF&`_3!1`zbxj*tmtdk!?P(Z9p~k?^U^oHtPW)j}}<}K*OyvSj_prA@20ozjsXDS|WsooTL9a6ruQ4Z`D zV&JA)qC1X0dZY&SVS)4iK*rXZKnO?do~diw^m_Q=KRq7>h4`vFq-p1WI^hc6+gT92 z!jgXh+IfRLIwa$rh5axHLsA@=I;7$eLI@%7&zg*oi_f5;;B@}(Pkh?0F()y@GB6UH zznAT;_qn`+w{g8wN0FZ7#grO)=5~p{UdVwCh*oJg1&0)R-K^!oKX5SElx2EHh@wfM zy#kF^942V(e1&HIB)o0oV!kP=`^Z66m`82Qc|xnta1Fj6OGSqm_8_7^iW zr2iW0HgbUw<}X@o$)DCCR2W0W$OkU+rqQTOm%G&6zE`Ub_8oy2)c08a zQZY%sL+@lKRgN4E562iF?A;k}L}ojWFObNQ0=c08HMci#+QVO0DXYbnX{sLhXVL#L z)zfx}<2CpKDA`cy6PsZ&GRwFI$mf0O9 z1{l0}E+l}x)h|mqD4{a5%NEHd0E1Yj*9h~zs?ed2JjFyCGl`(; z@Nv@9L=a_M$(=8LKNGb#cWVA~U9W>}7JY1q%d1zEa^HAoAnT%k6p=TbsgpZ~7yl^e z1CrcSf19WQ@1NMJubej=iIF;~)EFLKizRCIZzBM*Uu6{XOoOFJpmAE7d6!=QpSBk) z%9;98bV=%ERXjiT<2O%avJ&CpeCk$B^`T{UEOv>`;nkG&l?8_fD4jB1JV|BKEdU-= zXPQ0ofL$CWP1=CAMU%yLd})kjC`yZv3lhp8Ec7R8BkVH60{PUO6yWT@5#4D$2QjNP zU(mg7wGzFVI}eBYD&yI=2((rNck)I}c-^gK$4_@&^1UCs`%nGFT5rfpFl|g+LPAvI zv!=VLzRhKtX=$eRz@v!9>iL<6K1oIQm%M>QxzlmJ9Ttn+#BS)Zyi!G_ zubXEOwA59#fTk0Uo%7J(5S^t7t?Z_`S=ik>a=VIIru%TRl z_f~@1Y<~F(*-~>U+M^SVDaI!4Cf3#HH1R##@2P@S!-6THanfE&WCkiKj_{g0o^>PF zfAk~4{x$xadqocaDaR`bdrD( zlo~Odp$zDhk!WuVY)Sr8VCSdSO)3`TA;+mYwCpjd+Ww5d^2G}q+RYmW&b1{;gf^szgozDEb^_Of72Sp7pV@(S)!NuH*GNZLhbkVx%1Q5PoL zPvET@1J5p2I&F=*y!gj6=LkGy`R3ZUa8f{SYQ=a=*6jZmT9jC0lR+iG!?AZ-H~XYI zR0kZ61KNKS^3!-&HT0${o(@vCtv&Ogs1%7+ku)a8O@T{mjBodV^o;|?1CtipoCLkD z#>uvSRR@rGX{%cAN^jS_GQ)I^%}tJZlew!d(v6Y3z`kE)a86&bn@uJBbjIQdu#`Kc z!AGBR>_cd_l*GNuuI={;b152t&vcmkhCwTk3}B}do-Sanb9!0ywc^i=aUR8vxJyX% z)mRS6Oz3Hp+6cxp+|PZmGbm9YQ=R(G3z_@Ou(+zT#oycXc0ifCJ3@#=zPLKSNo3VE zy?&T<)t)nk=g3R`MGY$R?1 zTqMDh*11np%U^i!2dI0!{5DX{$wuLT5-{Gy%h?SKnZ*RRl%~@A%aAB&?aQKv@IO)TR&BrSyAba%~IfjGZqE*Te>Q$R?gbi{_-9| z<+5FT>N6TB;lmI2&xb7Xqc1_TiRDqV37BmbwXA+)Ce(iYuTT+#Y_LC#L5h9w?JVJs zcSag|M>Fa!A_7=7bQmV1h<$XfjzXTGX1fE~8O=c-%_XgDYg0LzKWzr>#HD|Cny)Aqxu8`u>k5g zo`Lp4d-y0+>Kf>P8Fv*H1GAmx;{QP$<9tPufH+<)+zT*&Sy%JksY=Kz9rVh=k9t2A zrSvjVeMZpmp>Dfd?Kspb-tRf9{dX?_CH@b8FswtI)d>g_?U5WO zp~VotF65#@6r#9b9E%WIgX6*&@Xpd)ybbm1=E8S-TJVwT&(Lb)V;?zYh<0 z^~OtFA#HY}Q%%BL8uvrI+$kaJxOpfHEl*n@I^iXJY1EHdA!veb;EUM9X|RS_-5h`l zInH;QBj4W6URSPa%yKwPw0L5^EwX9+f3y)%2D&7F^-F}p&NkvVsBEAwbaIs z>IzD$M%&g8ZWx!4up|Eq&|`&|b!H>l5hW^pM45~b#S9%p8_Q-7##vjv z2$nw0L#Vu>wC}p8iOo73bR( z)0M^HE9$pIRR9DWUT6@3S`AaAtMqH4`M6yy4Ay~ur!PhKCyE>bS?rm$bbn{RJ;*qz z99GN@y(fGRZ{6FBD|@TJFr?TK4F0A_v`E_MJ5gH}R=}FmYx#ceT+p<{JyI2Q^@6rC zn|e?MNV=*2nVaRyCMGHlKF3`E|r&g-U}lokq;{VbWXUw*~3bl(}}X? zSIoKFM0t!OFyvD78|v5DM|CZm5JkhqJO@5&A1U;Giq2Ry*G*Sy9A5Dfm4|^ToY6fe zdcWEy<6X@S^G<^hol!r)T~L^G0r@(j(jt`#gk<6&@;MaWcGnBdanO;M(d8IG)IP5d zzuQzs(rb;~;`%drieL!Ye!5k;=f{?$zbBKpJ~+_|BE_p$2y!ggLts8<=46HQCo83v zW9f~01C}!(KnF69PiOG(+{WA>r zmxK*z7x>X1i*Tn3o&(VIY}A+ac6*q!xp<8|*nRy0nP7`&RgQ|US$rBU$nfQ*HaLO-yKF+Xa(XGlmp%oM738Np@ z4na}&yHfVn#!<_!zURkQo%@h=n4iWL!beB32Spo$&}cb->w=|Ki=PDcgU_FuCU1no zKWQxMNMfB9O;Hf=q4dWpAZvi@4|KTCI)&8Y0h(~c{*&f_FVAoR$K&$irOlwHy_f<} zR$k}03`NxFLW&5Z*ZJ}~xBqG}D(R8X?W1CB-nI5=BQ-<+iMPX-<<6&gb{ z4})gMd+Zy?JM2u}pQVroTJjSo%-iXoRPer=WS z&Bn&Am?J0Vc1Bj#^}VBmxr(dKw(Y5Nt-0Tn48+17}RoFPN$;6haIGDJLE~D+- z@DTaMtI@VjEcnP?L;TNaBs=C%RKo7O-=yL_(*0kz$U84>beQLYmzl!X7dWk-#*d1h z;rQEu`k34mRIYN~;KP{&i8D#&7mm}un(?JKrAP6@dATOseHB~VV=HVw?D^_;ejkA_ zM@HPm(Q)CDT9mcR%)H!fyz+{J0L#5gfzP);PIT_oaCk+R`&Dk&Rm{5SUcQNE+d6V$ zZbrv$e@W7EujYa%HV&5X0Z#-69hR_rtft2Zs|cRKoW3fTRk2kKaov)IUVBXf&zfBs zNBO>xE>4m&YvLHuYb!qraz9-^qZZ?nk6u2pPCgi(_!&(=zPjR|yyNg<8lk~oZEMqc zh$E%Evqst;X)&W-MBPGm>Q-KWuSC~T1|ekm>)R9a$(4(^t4S%fYr|Jc1M3UTB*1nl zJw2cwRuR6zADM4JP4Oo6=+h6gaJaRG4wm=aE4r}PyWe4kuk zpEhmB_@9Py0!!~`T74sHb0fS`tjiVKYkYWx6&z3Zoe)<$YZtpmF7WqSeyq0!72iZ> z{Pwra_Jm&Q(NJNPw!9^aUZJvvJ3$2AE9>?3LtJ0x5BsC)sIQ!9sI3r|s^?IgzhSKS zR^rjqpk#q)30}%iLUgLBm^4aw{kyAYL>JE4DLD;pjejFZO8^BA9f;D{llcIwm_YV_ z3$nkAD5jwd`WX!f9&tvUCfI98ynxhMRNr)eQdNta?u=)+^R;4Q)xvv(N~5IFLWGyg zdnCBr!p5%I*$!uG=kn%Exm%5)xiHQ5ajDp$yzpTBl0PLuBXAJY5f($yVtKAL7I0*6 z1_Emw!Zf4W9wXPvObv}LyVyCI3y&Ao{&L^6Xwsq@oan5Y-Tz4yTX|`ewEu+;enIhk zPeDHQouKzt_pbXbrf-jZd*pE%(J_DA?k8c*82vGI;1>B1FYog~0|>&JPZzm|={R2H z^gVbVv&G~Y$*^?3RD1!e9$vPI4jaLmjDg6(^WER}`*2wCsnH?~nxwc8_4HH|+1-oO z?CNCtxY3l%GNwt_qgedjvP-9&O)NF&BKk}>y2+wKQYqYyheYX<)oqAw9Nu{Kiir(b zwe3uun&>5Z-#k!$)d1()i&&fuW8|q~5M5P}MU%NzOX22;oap57XT8u*%NlshKff?8 zoy(H`OWvB1)+mOu79rGPED>VJ>qqM=VOPbL7R>4O2$96L_R-y)9SivT)xbkA)&%PIM8ypX)2XT5@iXuh)v8KLI%_54*|i z8}^Sk5NOut$e|ERcYrL^pZgCveI)ng??|`t5+WTm!yKM&2sVSw1n?Oy#j^}|0_cLW z_sylNjto|DOPw0Y`?p)`d07iJr6X|P^k;n7>bOnoCj6q)jv-0X=2Sxf>?GLC_v~0# z`PFmStJf_pGeih=gUrr#2U=gCMbX=2mY!cK3-YxdLEiXe3c|jjNx2Mt+dC|70(Y`)+}^nBXVl@ke!p;|*dnm(T34i$ z=$$K1NyTCvpjols?_U!8CgyKF;&DC*S686NpRxhI=#yl|iB}P7w;7H-)y)Y}Rz4N+ z3AnxZG1JE7`<(&*Kng>g%K@d;ma|kfv1h)kVcJY^cbE~8K0DJ}*?_5OVIL%j#;-5N znd}NdNk;Q6Ge4H4^aRP9)Jbysp)Qm}Ie+}6lNS?B+zI7au1cWrI!Fo4Ahpeq`|cqF za1lyxIj(OQ$1OK}Ho`zqvrA-mE1iu#@VhvFh_4DQC#S%!q~NKOGa`6!AI}z=Wl6fR z_hga7iepbwWP?p$>r&?t_kelO;sy^gGEANAxF%p-$MgEd%;XiM?C3Zy%jVIMP(S~? zKYT-xCm-8Mtw&p4AY~jbMISCD7;6ujyX8x9@hT6b=e@A%qsTxVz=cBaI6um4ltxg% z^tL{(8Wr?yIkt=2e85LC(PAP1?M@&EV&F3#snmBA31KHTNbt;C@r@L-b36943k> zj{If_bmKNn;1_ygylbaSx6)dR=nZSlzFD&wohLMuP}E_>N^xc*tbb2^CneSD-e+uU zc1xP=0|HNcrR0o@xW8^Whc2z^apV-T#M??sNN`P0vAuXlQNoo$_ZxAL8s4pPkh%(R z1ha!${jw+M;v@OgJtknB9MNISNFJgJvT=%G7JZBF?+!}t&x}_{NZR9Q6Ybf| zH&8CG9XZTdnPcXLK5r6ke#d?W()}wFaw06J%=sScdQdWjevFV5VLkoOesv-Nt3aN| zKjx+36S@#lD;EJT>yyNvnI(Jj5;e~t}zEPt44?QFSlkmncRs7X*%v~4; z*qRu8eRiToAm&wuY2f|V)MfeIpI>YQ1m(lzJWEXYOmE_~FycG|b^X;3u03N!xDAI529o4eA4QBw$49!P4W}O zP~eBqFvJI&C<%I~vD2RgHFEjJpS*27zBy}nUd!iUB7vLg9aRl zglRrxFF9VesSZve89hRB8q4V%A75VrUV$W!Kc)8d7qVaIh0Vnp{Q-*tn)05&a*N~XVv$`jR zePn=82F-^(%a^mxHz#%_pkCuj(qLLwlOD$W=I9nM+u97|Z!9%^hD-+J`f%da zzJ2}_{xKc4^@Rpm$YSi~zGu6C!byC>5`6uTsDE3CGCaue%HY6DNT>c&HWnOn}^@*p>q11yS&=`3FHG7SD8O zu!Fam%J*Ib-@H6}=_;MvA#MZlrY2>4AJLU0A25g_WHcc5UY*FA&QNvd_1pQo9c%Tw zFBUGHme56{-y~h2Y&%7N?#IoD&R29iL``=zO7&g=gH6?Bq9csSFmqJ&*QDq-!4}caeU0WZdJ; zKR%Jae6vqWuU`P+j+JnW>%6gEsooLCF13?0#Gz(K-II4Ak*`3L(N&T(AAfjm`s=#iy)C1%o~AKABd%YYo(WvFrx?Q z-8z0omE`FUU&L9*i)eiTjfMH}Fc+nKswGiSxOXfA3ZC!sROY0PF5YeSPR?)tgA@L# z|L5MD?^0uCj<-2#qDdRnW8SW#T?^NhV2T2z_?6hDBO_VGC{xCNe;ENh8>(gK`EV%dYY(1J+EB5Hb;P%NYpt#-jAyboH9RHxEQjY zGQ?5Yf;vggA!?;tdH)-`>0<)?=Ud!b8}V^|d&IDSrxDlrXs%ruSe}cZohrOECPB83 z^|zXVIK-7rvyExjcrBBEHY^Y{n%X}OjQN;|u#n?f08#_5(kl2lrJ zSjhMX6B(Q_tIsn*2icQvQd-(ye^JO2FL*&QL#fF|R+sXLRuHN2{Z&+N{(e~q^Zpy< zn4-bUtq89fIR3@tj|7#=jk~eID9(_|FDQJ^h|TlTA~Ea{bDF-038Bx^EQKDNs#UfP zIj}$bs;c$js*;Y)b(6O%iw=WA2qOJhYd`Kb?j;iqv4_$-VM83ZVdoTjp5v3Y(W`t6 z`(E&XX^0v#ykJ(H{Bb5;6>*Bq{7kTNn~yu6gWHNfT%vO@X9!;37H!?BNzv&zHvHV| zH*y!HHA;>@`n{)`9~n+#2c_Yo>~%#m?Xt(KHTkeaH5MNTC3mdCbAL{$b(hh_MlA;I zsFUMG5Ba8_8S;&FXrpHs9z-vm@uo)-dD#SPiv%g1-l(=EGw=o@?NO z*U-wWxvmpzeoN9$I$Cl3G1}=|wL-&_yL-`Co;7#Hg%SFV+d+54&tQk+;iC)^butxY9Ay?9#!eutol!P~ z_Hp6HWmOMMv9E^4a|KQ=Qw83u^9<+J=CN94 z#m%RU{gt1m)^PV*_Tzl7d9#^u{|TYNoq3UUspp+ zePDW4=gqoWv3?P}vL5M+!-5eY+9c@6G$l`@SFN1rWJJN^|!^iPeRJ zFNykfmdoMat1Z1;{Q3jd{DvSli1td;??0|n-Kl{qu+DrVXE88+d4KQGzPt4M-s{{1 z`ihH7O72?f#adcbLl?9?a6OsHo$mDwMn`bOYNp@%Ul(Ab#YtrhX?@{AhrS1n*lvz)yK3nL7rYiIVH0y>D|q|#AU`41Oebu>OL&Laha@fZ6=2VdOR(7vl05ym6H zSPw%eT3h%KIl9PGhlMGJ@Mw*Ra%xe1w&qra2d=32tK8}2-h+eM8L?7D9!J@8;Emfw`QT0N#$3A8H`R#s3={qB zs1VKgBD^Z1&s)Q$+2gNLu0i+}$`iLX1P}DnWE^F>0V57flm}$4o@p#D{pbqgk32UG za_wz91XlHKyc1U7b(CRTsyfx4{O(6(6%VcL7*^ucQY0n^FkwP~k@7!b$n|i1eBsyy zo;sFWa!L+jUe-?Q9x0T~Or$0%|JMofE`bxk*~i19VT)k*Q2%8B01~NhPJ?+$Nl2AB zPJ8wBcbUc?v1{YG$~jZbzxzmqlnUo|!DUQLbi&t@ArcIrP9h~S;D*vwN)&l+w6>JE z>HPfmwp!{|n;WKGTd4GJst7_ccu_cixz9WFah`(mmw!M|<5ykJaR~?m>#eTRR*4C`R}%ig!b)UqKK;= zs9mXNLfaX&q@bw1!ap5vp(#`w0z!$GdeT(!n%L!Nc$XUC&aaGV-g@op^C2uDk8$n+ zoPkAg;Y$X)T<`%x{Uaav3Cpi8pC0OylnypA%{VAXd5|uzsz7}sP9}XLu1=T`@A+~V zxG=USUP0pXJn`SPzM8(8&;3&X2yWjUyrN1?&=o7iM)oo^jUEN@S6z&Uw?&d-FPovs zp9hJ|AvNC&_nU0UCKKDb^K_ZSaqLM@n7)usaW=Iro0FcSzb@Ecr|q!%)ExW8;e?bQ$0@CB}6LS_fv z(HG5D&4^ZMVQzeb8O`b0e4c@c_T9RUn<3q*k=b}HSW#@3yP02|eBqovydrjMD~sHB z9zF@;$*l4@jn~}fjk|k>d%aUo5;c8o?bmdCo*}pe!H0a6MA*o+st@yh;lqqKtmAC` zh@_oIe?|$ygpTY0Ea$gh3_l#+?KxZkTVyB>iHyzK!OVZ`Qk|CAXyQ6Ja7#_(C5d*S zZ^FB9D_nIc=3(2>@*6xyd7&8c!Vw%t$vBJ3;%qF1^4<>mkR_YC-dy!bX~j(}vAR#t zn;xmKeeWS!OFh^cRk9ei^(zcsgrk1j3utTy!a=kq1bXfY~onHjLnjXs;T4rJz zb&x?m*kBi~81P%LoropR`62(~s-_D(JEEtMym!XqeWEH_&D;x;um5$2(#E5Ecv4Qj zB4!*;R`8*jd`~O<+l&Eimr+i*|C#YAie|6E-ZSG%%0|hHjFUp&hE$V7r%sS|Y3HQq zv{A?=I8tLHCIkQpReHp$tTQ^^l=3hL3GtV(<$hVV)S7>`MIY0z4DXjGcyOiD-cfp68a7l8nd2>IoG~9*-s{9x}?F(nJw;18!&&!Ck zgqY&P_^6Gtj{~DWs_-k$ohj6QWk`b>!_sYMk=p47qg27%ND$z}XQ7t;KIRj??y&H9MfaZ8BhmQkRoUmXo zN^VZVx8A7snylF36kyMpQBDZZkQ2#mtK9XQ!e!u&yWXv%lDoYN_L$?x6)GIU9--}k zISb+cMyC({a2dqwi<6Uy)31rfo&*k5f@hxZ4R@B*n)0RJetr6HuUL1z)r{1hn&q6j zM(;KR>?Dgc+h?kBl91W18lH<&$)hx%>i?p9$V?{I;yO0U>^R|sqry_QGj~U?ZV*7a zlA~xq(;6SfB-DW-{cm*g2{&-5Qj$tnT0nQB;#=x95Z24H^-1xsi9bgj@VNiJA{`t{ z{Wg8zPo>Fa2o8_f$kG^s0z5n#vi!(`h&%DuLMt1=F(SJ@2n8aDVo#+=!T zA}b)x>3?7O5h6I2u9BNvPx{)Yo*W1cqUI1Bs7jsWzHh(ZX$s|!lYDab#rv1Nrg0a3 zsB~5;t=t%tLkd`qNm5%(?SsR=9K(EFko!7bfgDrhDPpOrRyc>RW`+L76kZR$z`O6* zllyASaWPv&wKvHF6K=RTN@EhGDsJhJDpzPFU_DQzUn>mzdUdK<)kIkEYUCZ>@KF2U zhzA)WOn%~5ERt4QY~KxhVN5hre@+cR8!?fy=4#dv3mDzL-@_-rw(H{Ib}Yo>>oLU zVRCCh5_m`G`nGGK0lZp`SZf1g&G{s@14pqRdM91Jf^KY#DM!{kC;i@_bG$H^Gr}f+ z#F-9!RnRks#}2Y5h$juVq0B~h@G3u5d6sHO)r zitQP&@L=h&@gMozQP<*Q$FT7crcpluo)O;qVo-)3UUW90;8I%IMt`0Fer94Eu4M@0cy5VYZAYXN6+#)XLapLqTpn2I5KTMv7j0&a_8EXE z=?8vEE43rta#3`oK$((xw^LDn1v8sK*$BSI_RjG#A9+WhVw+azMeDH>+)=-u=J*>p zk&v2bd$6MK{XX^yL|Fs;l71}f%wQccuxI=ROQz1KBK^%c=8D#Ah; zGXIDNCgveK)tfhf-tYAPl_@mZuXBsw{g7jcJSB1+odFDPOf`FW)z$iX;hgp$t7vg7 zC?}dXZfy>ic*u>#5LYc@#oXoTR=H|U1MiDY7O6_tv!EyD0vIsEbv-3v6Ry%4sHx#C zjdzk$q4p?rDatf%3Ej;&F}RfHf|O*&zt&nfIli*f53uugv3_Vm%W56CW1%J^cW8&y zFw8AA;q&VsUDdq#)X);ZBhV_XUUs+>1NEY@Fl9R64K)z%f@=Bp? zrI7VN19tK>k_XTr<18U7zTx|6Vf7{X2}(KQg&z%`{2jT@Fp1|xVvzj__N??7OTh9E z?;c4K&34hr-Zq6Qvd)2DLrCbBBY^g{o>K~}%XbH3%r>AM+zrPK#nQi6$AF?rTKBBKSyx)!);*&qM{1#v?mS$8&jGiUS zEt{tU^;gQ~7{UAnG8lKv4B9bauqONPI=UY2{>c7I;N%VIExIwVU0oAr<#yW#jSI;c z`491Xz14p#^sqMnpoB0K(~%uo=f0dj-)1GD)FNbpMbM=o%0}ic*E0e3TvCnB+8Vw8 z9bV1HFHoLaj2Trq{d+s}vX)$1T%L=kgF^XEwyj<~fcr^o#QKT;%+gLZHz(Q^od z$&*`q(~-5W78CZe8DtcNZ(jWA@l5dK+`^o&^z%i=L@l*!Ak1q|z~m1)z~no@zx`Ws4?Gt;6XSEY zbH!yrxWfk0Ca%8s9jk%EJhi*1UckRL81xHe8NKit-kFsNh0{zkN_P1M6|n>+1p38= zRSZo5Ql2ix3_^g5HbFT?0Kfb#T)V}l2&c1YA_$oYPe0@zKPa9|xYo z7$ug-(w^8e+EYG-iT2KoRH1FoaFyexYy;ZNYi}TCwNr;3<${-(Tu{J&EM>E4?z#u` zX7COUWs;#w{M~A+zHXH&wefozozuwf-KdgGjv;3{A1$LMH0#ehU{9^ zRtcBPJMv_U)w`*8fyuB*(_$b{NU8tJd9SN}ZDWucS~)=2s<}xXFDN`?A#Gr3KZY|o z&E!|7Sv+?NSP#{1Rm%Op+yWU;28?hWO~OjpPaDyP=FXDau4BZ$!Gjsse%h2*eD zZJzsbM)j(E%C?zOnWnO1WfGx$%Hn#*;*~S%m!dqxd-C4Lb$^JVz=0d%gd6jCyG{iz zz~Yx{)X|2kuRI42X?q4lXJ?kAp93hnyJ+q=70;LG*Oz;c^e)N+CK;G0)U%@J*FM2e z8~_d0`ETTWLYKRHgcgEjsv1odU9z?|ZY0q3-Ty~w7=B(#>8Br;+t00$$&?q?uasxv zcFwf8R7MM)IF)jinSVJaE|5Gud=7`A1*ydxR7;7|4wfiR<~7ROT(tC|l`zF*Rk>gF z%{oQNc9otovDxvdLry6F9l^=F8%vD3evuKvt0aO?Jw;wet{Z0Fpc8>s+MOw0W ze!gt>x50F=iNUz(4PxD)oPMWJlM3bD`=wdVl}R18YG^a1*j%M82KT6{l=)KouY0ra zn&2u>{u=7eqQkNe0}$Z(bl1~Eis>o%CESlD*i7GoRZZ{4P+ofUL|2qC zyhmBTZ>8##3HN{*zqEao_Ml>EmU?B5Vr9`S`iG&0I>FZWWpUQheH|o=nNkeApqoQJ|ZA^aIUso#ay zA>&M^!?FaEfR1Uv5i^|KbzseVKL4g~A;852Wv!*oH8xh&ePQee|4CKm0kd)S^X5Eq zidXN3`+ty8!wJvI3(`+jnI!2At;APb$su+``!fo%0Rp!*0DGl~54i|jr zl%cQ9NL83~dFddzao!!TAnih8`5VCKFn0nd^kl7^QmwJ^)x)MdfvzgXth5SqdO@4z zl5JYsRBh`?XV;0llcc_Y55iW}d0!PV@JcMlYMfq!!Nr z=J0*3*{ZFmMWT||-}){ezxfOeoOm`Sm_7 zL@U`C$NV*xa{%01Qz&Mz%VaH-U0D8f4v+@F{ZT<@b=yLiJ~~{x_C%tzYBrgjU#0fr zuc$L!cYwZxujj9QB4s}fgX>>{-ss92FXOSOwNQR5$V@&nY+N;Rz;S1%&%?6cWwPoN zYomJh)U5%NbEbLf;jEGUT6reo=g|C>+jd3_wJE93pIKsZ$q(cm2!MJJnH=f&b3oCe zFwPByN{nnF4{@cXnBB8h(>2{Iyu=mDSX~#4^lRw~pJS_DF_abo^EnW~ASa|11t>SrzA%hJd>Vo}fAMJ@5G;vIroEF8X;sEDz8PMqN_b5|22S@Ybd9=}> zn01qS&^5o8<~;3+*;$dy3oMc0dCH|j>Zs~vm)N2dEp>iF_o&jJ4RpslvI<+L#=us& zcP3^|!ck!aTi2$j^|Eh?pzFh!eGY*Av)5VTI1!gh9H#2YVJey5e;-K@4~|l;>KUJ> zX2sKy%Z=CNntsS38AHUqCHGMc3p_iNXRw8{7C8v~~72YZn&Kw~A zn_fPDv2N>ER>Xs75rGn}tXs=il%(t*%M+n&EZ&0|z^57GoWx~3hm)Z2>6R4}XH&K0 z2mSm`XGhfoO{C(4U%$#c*;)lSn4g>YV@4eoISdC!tW*EXJ^y2j+ydK)bw0u_qUb1^~dP zm;I+J?6BvI{yScL>+K_9Vibfw;0Ny~Le|%|^)jIr0v;A}uIR>9(*R5vdvKc4sq=|) zak0=Cf0%aquXvE|XsxOH=9r|D_~3XXLYQX#y=>Lo`m^#f2TL1Kqnvj`9n4KxcN-yl zO!J;H5w5v4;RQBbAF@7zIih%|@LUh~9$`q;EZ1GSe|N5p>*`cD8D>j{(?hDh^ibwG zo9G9eh!JfEKJRh>cFiXC4>jfMH649P`jWqvEq8Etx1ah%l}3)U4q++1JjZLLEJ-F6 zCeHAp9cCqqtbX7L73Uv!^)&27L+1CIp-DtTDif=`e~TUsaSn;J;{9!_pyUzzXK%D8 zC;WBWANCcRQ`41ITZws&x8`;q;a82LQ?`qn-hu#xb0 z?kwqN@#M!9X6GZ(M5WTwjIOYhUn}37JIi!x^i55=W_Po?++fy58RLCS(pN4fUJCSw z>xyVPv&nir@>Ea?haY=^C|695Q}w*r!97h!-P!QP7^TIb09%HAg`sg8~Fp(c!j+?;h)GpfOt6Q1%=Arv<}oiurPG zztpA0r@3iEGD*HrQCY9QQOIPHDrg`Zs(%_iQ9X|0C2&2J@|N@I+&l=@rGqas>m zRI-Pk=2mHK-R5LP$EvHhy7$1Y299^-Dn-hC>N%rP?)22Qu7_Sb;74n8+Eu$bbn#U8 z;Czh$Lz5CEGVqw2YB9>73`$d!T^^z9K=e~%FqsvpQMeK-BVBb*_F5lp_{R;$$i!+5 z-(J(8&CMTXoxK)$E*-_nz0yelv(sQdUky{ghJU*9EHq;frGq1dN%f^aT>ucF%B7JG zs30fVM&EqH&5+pwTI8&34mlugs1g&wbSbL=nR~{2Dh|PTrO`24iS(T?&up{g>|$$S z8yT=vP! zfh^T*(qAV^k*T!^OK29&W#d27cVnw(Vn09FkaUuqCsLDnLKwt&> z1;EE8$ePv~b1-n<>x`0KyRZmlovrm(;HE|ai!{h9(tYXv7+Sb&?pOXPPob`gDQyEq ztGvV8e*=xhO4wH}I}C33{9>}LNBwWKm=ctlV>yN^+K82;No&>e&FTCVZ>XFLYhB1z zMp@M6Z7@@gInU7xkK2DmWm?inVJh_`lV)N?xsCf_DIc=D~-u>ART>|lM-3NeX|n|iVkit!W$4|tKo;0 zp6TjXq{P!~tcF*8lTY?#_QgxD$ojV)?(Ax__y~b|1FnaR2bF$pXE2KWBTT!Ldl~%; zG(75~SfHx$Z?S>tS2;*%n_G(#wP~+y?^2obXkBxEt(n)WP8sC^^i|Pz6h{|#^;DtH zEa#KR6jK{^f-X*Sv$^nJGS-nP4Jg^_sLbeYs{}$~+JueeH*K~mT38M0(Fs8tFAc`s zW1!UN!Hiab7+rk=@>t?O92&}=K1M1LC9<;OYfU+Z`060akb@}GY5pq~2VvD?{H-08 zx3lM1>z@<;pv^gdner5KFVBjYbRFnA6^d(xb?-h4PF3MpPacMpT!lIg^wq%cw}B>u z{{eodgO-(83EL8=hA%3Cp{W|a(|zjJ`3j4_>+z1lm*fqJ>N)cR{X7kIIi3MmOBSbR zhX&RbPuqn+LDRi`CmGGO;&yL$o0fim0zQGrKCDoY0cj#7rT+F-9c?umG1B()l(!S^-C_PjRLP@EA7XWxLnG+qh{a5Dnlm#P&MTlf#&K~AH zkI>Jxcevv8KK?@4eHQVj=V_zXx8|BZPs=Q1Xcxi1TKWH8`P;fL(K+0 z5r$9v6JhMVLD9_giol!eBv=Y0hckn6hSCTqH+4*CO9=PM@ugXWo%q`yV|F#mxdVn` zn&U5?Is=hoB)1K8Bc$Loqp^NCJ=EB)G%ztqIScBrxIxnvtTPOe?7tFz)G6tQrZ&0< zeO(`#?wD0g3db#|1X8%hTSn zBSW_aNiE6ozK`0-5J0Cuj9yn4AF3vhHs6rQ|J%Bqj zEclUyznu5>H{h+dG^LkM`W;`WJJCwk*pF(JzK<*=$NUJUGe39_)8^0b<)tKm6vlJp zNDZIiVT>T=-0?btQj`!EbW#0!as1V1*QJf(7Rd*J zUH!=|o?5hObJ>!DmO)}j!QU2wDM;5qb@M#G`H+6U6+_oChK;m>;`(pjRJ(~yGvx?vW29I{RZof)0S3t^!6zr{bEGKro5b-^bGgfOSzIE|>2H2LsC7exIv zbUFwNs%~pMYdz2br~<^(kX2E?T||Vu&Q-UkUidg#o18T^(pLzve+vT+Ps2Pfu)MEF z7zr7;1C}Q{oCeknGoK$MkMgH}dcHl#;AU=O%smSRK?Pig5ey=oVIL-NA?Es33qpKk z+tAHX7$eC%_r1L1#V2s0dIM)5%%aKB0UPI;kF4SREf!3?`$#DXM^}>j-<~HkRJ*jZ zx@>w|FhHz|=2HzZAogIEA(sXagQyD37;Ja?h4|ER<}t=gB}3j)?($9%zDaSMITbtX)u+qr@#paY@=> z* z8gssv`oUAJ zz^aW^E|VScYDwGZu1Ib+(*{6Cr791(osEQFG1vtyMwC0-jSK97vwnB#cX7LoV44J>Rp9v|l2bXR=SftO8t!JqyosektZ+&7Snr#Th;E^1>rtZlQ@T^K2$(ovtU!g3-8=br!l=`nPC zffY1V3pgh2eXgu`pRgf9a)9$M8J902h$RZo!MrND&asG6FmZOm)cy

W*jl^+Kc_ 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 O1b0^b@66K{_x}%p4Gf+D literal 0 HcmV?d00001 diff --git a/public/svg/logo-quack-white.svg b/public/svg/logo-quack-white.svg new file mode 100644 index 0000000..b87eaf5 --- /dev/null +++ b/public/svg/logo-quack-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/popup/App.tsx b/src/popup/App.tsx index a2bbe2b..e255850 100644 --- a/src/popup/App.tsx +++ b/src/popup/App.tsx @@ -175,8 +175,33 @@ function App() { setScreen('import'); } - function handleImportFresh() { - setScreen('import-fresh'); + async function handleSetupAndImport(password: string) { + const setupId = Math.random().toString(36).substring(7); + console.log(`🎬 [handleSetupAndImport:${setupId}] START`); + + try { + console.log(`🎬 [handleSetupAndImport:${setupId}] Creating vault...`); + await createVault(password); + + console.log(`🎬 [handleSetupAndImport:${setupId}] Setting master password in state`); + setMasterPassword(password); + + const emptyVault: VaultData = { keys: [], groups: [] }; + console.log(`🎬 [handleSetupAndImport:${setupId}] Setting empty vault in state`); + setVaultData(emptyVault); + + console.log(`🎬 [handleSetupAndImport:${setupId}] Marking vault unlocked`); + await markVaultUnlocked(); + + console.log(`🎬 [handleSetupAndImport:${setupId}] Caching in background...`); + await cacheVaultInBackground(emptyVault, password); + + console.log(`🎬 [handleSetupAndImport:${setupId}] SUCCESS - going to import-fresh`); + setScreen('import-fresh'); + } catch (error) { + console.error(`🎬 [handleSetupAndImport:${setupId}] FAILED:`, error); + alert('Failed to create vault. Please try again.'); + } } function handleBackToDashboard() { @@ -248,7 +273,7 @@ function App() { } if (screen === 'setup') { - return ; + return ; } if (screen === 'login') { @@ -279,7 +304,6 @@ function App() { vaultData={vaultData} onVaultUpdate={handleVaultUpdate} onComplete={handleOnboardingComplete} - onImport={handleImportFresh} /> ); } diff --git a/src/popup/screens/OnboardingScreen.tsx b/src/popup/screens/OnboardingScreen.tsx index a6b2b5d..c8be90f 100644 --- a/src/popup/screens/OnboardingScreen.tsx +++ b/src/popup/screens/OnboardingScreen.tsx @@ -6,12 +6,11 @@ interface OnboardingScreenProps { vaultData: VaultData; onVaultUpdate: (vault: VaultData) => void; onComplete: () => void; - onImport?: () => void; } type Step = 'welcome' | 'generate-identity' | 'share-key' | 'complete'; -function OnboardingScreen({ vaultData, onVaultUpdate, onComplete, onImport }: OnboardingScreenProps) { +function OnboardingScreen({ vaultData, onVaultUpdate, onComplete }: OnboardingScreenProps) { const [step, setStep] = useState('welcome'); const [identityName, setIdentityName] = useState('Personal'); const [isGenerating, setIsGenerating] = useState(false); @@ -101,15 +100,6 @@ function OnboardingScreen({ vaultData, onVaultUpdate, onComplete, onImport }: On > Let's Get Started → - - {onImport && ( - - )}

); diff --git a/src/popup/screens/SetupScreen.tsx b/src/popup/screens/SetupScreen.tsx index 0618af5..0142c03 100644 --- a/src/popup/screens/SetupScreen.tsx +++ b/src/popup/screens/SetupScreen.tsx @@ -2,9 +2,13 @@ import { useState } from 'react'; interface SetupScreenProps { onSetup: (password: string) => void; + onSetupAndImport?: (password: string) => void; } -function SetupScreen({ onSetup }: SetupScreenProps) { +type Step = 'welcome' | 'password'; + +function SetupScreen({ onSetup, onSetupAndImport }: SetupScreenProps) { + const [step, setStep] = useState('welcome'); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [error, setError] = useState(''); @@ -26,17 +30,98 @@ function SetupScreen({ onSetup }: SetupScreenProps) { onSetup(password); } + // ============================================================================ + // STEP: Welcome Splash + // ============================================================================ + if (step === 'welcome') { + return ( +
+
+ {/* Animated Logo - cycles through 3 colors */} +
+ + + Quack Logo +
+ + {/* Title */} +

+ Welcome to the +

+

+ Quack Nation! +

+ + {/* Start Button */} + +
+ + {/* CSS for logo color cycling animation + Timeline (6 phases, each ~16.67%): + 0-16.67%: Green 100% + 16.67-33.33%: Green↓ Orange↑ (crossfade, meet at 50%/50%) + 33.33-50%: Orange 100% + 50-66.67%: Orange↓ White↑ (crossfade) + 66.67-83.33%: White 100% + 83.33-100%: White↓ Green↑ (crossfade) + */} + +
+ ); + } + + // ============================================================================ + // STEP: Password Setup + // ============================================================================ return (
-
-
🦆
-

- Welcome to Quack! +
+

+ Create Master Password

-

- Create a master password to secure your encryption keys -

@@ -51,6 +136,7 @@ function SetupScreen({ onSetup }: SetupScreenProps) { className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-quack-500 focus:border-transparent outline-none" placeholder="Enter master password" required + autoFocus />

@@ -80,7 +166,6 @@ function SetupScreen({ onSetup }: SetupScreenProps) {

⚠️ Important

Your master password cannot be recovered if lost. - All encryption keys will be permanently inaccessible.

@@ -92,6 +177,27 @@ function SetupScreen({ onSetup }: SetupScreenProps) { > Create Vault + + {onSetupAndImport && ( + + )} From 9544a88cfa2acdbb70523b9d103316ef7527d087 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Thu, 5 Feb 2026 22:01:53 -0300 Subject: [PATCH 03/22] refactor: send user to setup if not completed --- src/popup/App.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/popup/App.tsx b/src/popup/App.tsx index e255850..2e3f937 100644 --- a/src/popup/App.tsx +++ b/src/popup/App.tsx @@ -53,6 +53,15 @@ function App() { console.log(`🚀 [initialize:${initId}] Cached vault - keys: ${vault.keys?.length}, groups: ${vault.groups?.length}`); console.log(`🚀 [initialize:${initId}] Cached group IDs:`, vault.groups?.map(g => ({ id: g.id, name: g.name }))); setVaultData(vault); + + // Check if user has completed onboarding (has at least one personal key) + const hasPersonalKey = vault.keys?.some(k => k.type === 'personal') ?? false; + if (!hasPersonalKey) { + console.log(`🚀 [initialize:${initId}] No personal key found, going to onboarding`); + setScreen('onboarding'); + return; + } + setScreen('dashboard'); return; } else { @@ -120,6 +129,14 @@ function App() { console.log(`🔐 [handleLogin:${loginId}] Caching in background...`); await cacheVaultInBackground(data, password); + // Check if user has completed onboarding (has at least one personal key) + const hasPersonalKey = data.keys?.some(k => k.type === 'personal') ?? false; + if (!hasPersonalKey) { + console.log(`🔐 [handleLogin:${loginId}] SUCCESS - no personal key, going to onboarding`); + setScreen('onboarding'); + return; + } + console.log(`🔐 [handleLogin:${loginId}] SUCCESS - going to dashboard`); setScreen('dashboard'); } catch (error) { From 62278cd1caa09eeff6f8a8aca6c96675a19765d6 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Thu, 5 Feb 2026 22:54:20 -0300 Subject: [PATCH 04/22] fix: removing scroll from setup second screen --- src/popup/screens/OnboardingScreen.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/popup/screens/OnboardingScreen.tsx b/src/popup/screens/OnboardingScreen.tsx index 0ba29a3..bd57cb0 100644 --- a/src/popup/screens/OnboardingScreen.tsx +++ b/src/popup/screens/OnboardingScreen.tsx @@ -117,8 +117,7 @@ function OnboardingScreen({ vaultData, onVaultUpdate, onComplete }: OnboardingSc Generate Your Identity

- Your identity is a cryptographic keypair. The private key stays on your device — - only the public key gets shared. + Your identity is a cryptographic keypair. The private key stays on your device and the public key is shared.

From b1a86ed9727bc02c125b6f51585449e5ddac6917 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Thu, 5 Feb 2026 23:40:33 -0300 Subject: [PATCH 05/22] refactor: removing scroll from identiy creation screen --- src/popup/screens/OnboardingScreen.tsx | 48 +++++++++++++++++--------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/src/popup/screens/OnboardingScreen.tsx b/src/popup/screens/OnboardingScreen.tsx index bd57cb0..243c8ee 100644 --- a/src/popup/screens/OnboardingScreen.tsx +++ b/src/popup/screens/OnboardingScreen.tsx @@ -16,6 +16,16 @@ function OnboardingScreen({ vaultData, onVaultUpdate, onComplete }: OnboardingSc const [isGenerating, setIsGenerating] = useState(false); const [generatedKeyString, setGeneratedKeyString] = useState(null); const [copySuccess, setCopySuccess] = useState(false); + const [funnyMessage] = useState(() => { + const messages = [ + "...yeah, it's massive. Just copy it! 🦆", + "...it keeps going. Quantum-safe keys are thicc.", + "...wow, still reading? Just hit copy already!", + "...your future self will thank you for this chonker.", + "...size matters when fighting quantum computers. 🔐", + ]; + return messages[Math.floor(Math.random() * messages.length)]; + }); async function handleGenerateIdentity() { const genId = Math.random().toString(36).substring(7); @@ -173,46 +183,50 @@ function OnboardingScreen({ vaultData, onVaultUpdate, onComplete }: OnboardingSc return (
-
+

Identity Created!

-

- Share your public key with friends so they can invite you to encrypted groups. +

+ Share this key so friends can invite you to groups.

- +
+ + +

- {generatedKeyString} + {generatedKeyString?.substring(0, 115)}... +

+

+ {funnyMessage}

{/* Info box */} -
+

💡 How to share: Send this key to friends via a secure channel (Signal, in-person, etc.). They'll add you as a contact and can then invite you to encrypted groups.

- -
); From 50ea823944744ae6c3a1dead37d66dbbbc501716 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Thu, 5 Feb 2026 23:43:40 -0300 Subject: [PATCH 06/22] refactor: removing scroll from you are ready page --- src/popup/screens/OnboardingScreen.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/popup/screens/OnboardingScreen.tsx b/src/popup/screens/OnboardingScreen.tsx index 243c8ee..58caa4f 100644 --- a/src/popup/screens/OnboardingScreen.tsx +++ b/src/popup/screens/OnboardingScreen.tsx @@ -242,8 +242,7 @@ function OnboardingScreen({ vaultData, onVaultUpdate, onComplete }: OnboardingSc
🎉

You're Ready!

- Your identity is set up. Now you can create groups, invite friends, - and start encrypting messages anywhere on the web. + Create groups, invite friends, and start encrypting messages anywhere on the web.

@@ -267,7 +266,7 @@ function OnboardingScreen({ vaultData, onVaultUpdate, onComplete }: OnboardingSc ✍️

Ready to encrypt?

-

Type Quack:// anywhere!

+

Type quack: anywhere!

From 0597019edcc6ab076f7fe13eb9382f3abf16f4e3 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Thu, 5 Feb 2026 23:53:30 -0300 Subject: [PATCH 07/22] refactor: removed duplicated buttons on tab cards --- src/popup/screens/DashboardScreen.tsx | 32 +++------------------------ 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/src/popup/screens/DashboardScreen.tsx b/src/popup/screens/DashboardScreen.tsx index 70090da..fae373f 100644 --- a/src/popup/screens/DashboardScreen.tsx +++ b/src/popup/screens/DashboardScreen.tsx @@ -447,23 +447,9 @@ function DashboardScreen({ vaultData, onVaultUpdate, onLock, onCompose, onDecryp
👥

No groups yet

-

+

Create a group to start sharing encrypted messages, or join an existing group with an invitation.

-
- - -
) : (
@@ -517,15 +503,9 @@ function DashboardScreen({ vaultData, onVaultUpdate, onLock, onCompose, onDecryp
🔑

No identity yet

-

+

Generate your identity key so others can invite you to groups securely.

-
) : (
@@ -576,15 +556,9 @@ function DashboardScreen({ vaultData, onVaultUpdate, onLock, onCompose, onDecryp
📇

No contacts yet

-

+

Add contacts by importing their public key (Quack://KEY:...) so you can invite them to groups.

-
) : (
From ed5cc9efb4f9e632d48927b76c7bbbea5018ff38 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 00:26:24 -0300 Subject: [PATCH 08/22] refactor: removing width expansion on scroll --- src/popup/index.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/popup/index.css b/src/popup/index.css index eac7188..d797992 100644 --- a/src/popup/index.css +++ b/src/popup/index.css @@ -11,12 +11,14 @@ html, body { width: 100%; height: 100%; + min-height: 600px; + overflow-y: overlay; } body { width: 100%; min-width: 360px; - min-height: 500px; + min-height: 600px; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -25,7 +27,7 @@ body { #root { width: 100%; height: 100%; - min-height: 100%; + min-height: 600px; } @keyframes fadeIn { From 44c49d21450341b1396089e01ce165ac027eed83 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 00:46:52 -0300 Subject: [PATCH 09/22] refactor: adding quack logo svg --- src/popup/screens/DashboardScreen.tsx | 6 +++++- src/popup/screens/LoginScreen.tsx | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/popup/screens/DashboardScreen.tsx b/src/popup/screens/DashboardScreen.tsx index fae373f..0f634d1 100644 --- a/src/popup/screens/DashboardScreen.tsx +++ b/src/popup/screens/DashboardScreen.tsx @@ -325,7 +325,11 @@ function DashboardScreen({ vaultData, onVaultUpdate, onLock, onCompose, onDecryp
- 🦆 + Quack

Quack

diff --git a/src/popup/screens/LoginScreen.tsx b/src/popup/screens/LoginScreen.tsx index 323b425..c219627 100644 --- a/src/popup/screens/LoginScreen.tsx +++ b/src/popup/screens/LoginScreen.tsx @@ -16,7 +16,11 @@ function LoginScreen({ onLogin }: LoginScreenProps) {
-
🦆
+ Quack

Quack

From 3e92a02add948039775f5e5c7cdff26a71b699ce Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 00:51:09 -0300 Subject: [PATCH 10/22] refactor: changing icons on top-right dashboard --- public/manifest.json | 2 +- public/svg/gear-svgrepo-com.svg | 5 +++++ public/svg/lock-hashtag-svgrepo-com.svg | 4 ++++ public/svg/sidebar-svgrepo-com.svg | 4 ++++ src/popup/screens/DashboardScreen.tsx | 8 ++++---- 5 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 public/svg/gear-svgrepo-com.svg create mode 100644 public/svg/lock-hashtag-svgrepo-com.svg create mode 100644 public/svg/sidebar-svgrepo-com.svg diff --git a/public/manifest.json b/public/manifest.json index 42db733..e08edeb 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -1,6 +1,6 @@ { "manifest_version": 3, - "name": "Quack - Universal Web Encryption", + "name": "Quack!", "version": "0.1.0", "description": "Encrypt your messages anywhere on the web with post-quantum cryptography", "icons": { diff --git a/public/svg/gear-svgrepo-com.svg b/public/svg/gear-svgrepo-com.svg new file mode 100644 index 0000000..c681696 --- /dev/null +++ b/public/svg/gear-svgrepo-com.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/public/svg/lock-hashtag-svgrepo-com.svg b/public/svg/lock-hashtag-svgrepo-com.svg new file mode 100644 index 0000000..7918727 --- /dev/null +++ b/public/svg/lock-hashtag-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/svg/sidebar-svgrepo-com.svg b/public/svg/sidebar-svgrepo-com.svg new file mode 100644 index 0000000..58aa482 --- /dev/null +++ b/public/svg/sidebar-svgrepo-com.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/popup/screens/DashboardScreen.tsx b/src/popup/screens/DashboardScreen.tsx index 0f634d1..5e19ac2 100644 --- a/src/popup/screens/DashboardScreen.tsx +++ b/src/popup/screens/DashboardScreen.tsx @@ -342,21 +342,21 @@ function DashboardScreen({ vaultData, onVaultUpdate, onLock, onCompose, onDecryp className="text-gray-500 hover:text-gray-700 font-medium" title="Open Side Panel" > - 📑 + Side Panel {onSettings && ( )}
From eedccceb65dfb737882fd4600633bfa8d6561b0a Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 01:16:04 -0300 Subject: [PATCH 11/22] refactor: adding heart to group icons --- src/popup/screens/ConnectFlowScreen.tsx | 3 +-- src/popup/screens/DashboardScreen.tsx | 4 +--- src/utils/constants.ts | 3 +++ 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/popup/screens/ConnectFlowScreen.tsx b/src/popup/screens/ConnectFlowScreen.tsx index 6887cc2..206a4ea 100644 --- a/src/popup/screens/ConnectFlowScreen.tsx +++ b/src/popup/screens/ConnectFlowScreen.tsx @@ -11,6 +11,7 @@ import { getPersonalKeys } from '@/storage/vault'; import { createGroupInvitation } from '@/crypto/group'; +import { GROUP_EMOJIS } from '@/utils/constants'; interface ConnectFlowScreenProps { vaultData: VaultData; @@ -22,8 +23,6 @@ type Mode = 'choose' | 'alice' | 'bob'; type AliceStep = 'share-key' | 'add-contact' | 'create-group' | 'invite' | 'done'; type BobStep = 'add-contact' | 'share-key' | 'wait-invite' | 'done'; -const GROUP_EMOJIS = ['🦆', '🔐', '👥', '🏠', '💼', '🎮', '🎵', '📚', '🌟', '💬', '🔒', '🛡️']; - function ConnectFlowScreen({ vaultData, onVaultUpdate, onBack }: ConnectFlowScreenProps) { const [mode, setMode] = useState('choose'); diff --git a/src/popup/screens/DashboardScreen.tsx b/src/popup/screens/DashboardScreen.tsx index 5e19ac2..226a76b 100644 --- a/src/popup/screens/DashboardScreen.tsx +++ b/src/popup/screens/DashboardScreen.tsx @@ -20,6 +20,7 @@ import { } from '@/storage/vault'; import { createGroupInvitation, parseInvitation, acceptInvitation } from '@/crypto/group'; import { formatDate } from '@/utils/helpers'; +import { GROUP_EMOJIS } from '@/utils/constants'; interface DashboardScreenProps { vaultData: VaultData; @@ -34,9 +35,6 @@ interface DashboardScreenProps { type TabType = 'identity' | 'contacts' | 'groups'; type ModalType = 'newIdentity' | 'addContact' | 'keyDetails' | 'newGroup' | 'groupDetails' | 'inviteToGroup' | 'joinGroup' | null; -// Common emoji options for groups -const GROUP_EMOJIS = ['🦆', '🔐', '👥', '🏠', '💼', '🎮', '🎵', '📚', '🌟', '💬', '🔒', '🛡️']; - function DashboardScreen({ vaultData, onVaultUpdate, onLock, onCompose, onDecrypt, onConnect, onSettings }: DashboardScreenProps) { const [activeTab, setActiveTab] = useState('groups'); const [modal, setModal] = useState(null); diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 1cab5bf..4ea40ba 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -32,6 +32,9 @@ export const MAX_AUTO_DECRYPTS = 10; export const AUTO_LOCK_TIMEOUT = 15; // minutes export const NOTIFICATION_DURATION = 3000; // ms +// Group emoji options for group creation +export const GROUP_EMOJIS = ['🦆', '❤️', '👥', '🏠', '💼', '🎮', '🎵', '📚', '🌟', '💬', '🔒', '🛡️']; + // Storage Keys export const STORAGE_KEYS = { // New separated storage (v3) From 0431e55f27dd70284ebf5085be596de777f53ee3 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 01:29:02 -0300 Subject: [PATCH 12/22] refactor: removing useless tips and small text changes --- src/popup/screens/DashboardScreen.tsx | 2 +- src/popup/screens/ManualDecryptScreen.tsx | 8 +------- src/popup/screens/SecureComposeScreen.tsx | 22 ---------------------- 3 files changed, 2 insertions(+), 30 deletions(-) diff --git a/src/popup/screens/DashboardScreen.tsx b/src/popup/screens/DashboardScreen.tsx index 226a76b..3e5be56 100644 --- a/src/popup/screens/DashboardScreen.tsx +++ b/src/popup/screens/DashboardScreen.tsx @@ -379,7 +379,7 @@ function DashboardScreen({ vaultData, onVaultUpdate, onLock, onCompose, onDecryp onClick={onConnect} className="w-full bg-blue-100 hover:bg-blue-200 text-blue-700 font-bold py-2 px-4 rounded-lg transition duration-200" > - 🤝 Connect with Someone + 🤝 Need help connecting? )}
diff --git a/src/popup/screens/ManualDecryptScreen.tsx b/src/popup/screens/ManualDecryptScreen.tsx index 7b16ab5..c5082d3 100644 --- a/src/popup/screens/ManualDecryptScreen.tsx +++ b/src/popup/screens/ManualDecryptScreen.tsx @@ -85,12 +85,6 @@ function ManualDecryptScreen({ vaultData, onBack }: ManualDecryptScreenProps) {
-
-

- Paste an encrypted message (Quack://...) to decrypt it with your groups or identity key. -

-
-
)} diff --git a/src/popup/screens/SecureComposeScreen.tsx b/src/popup/screens/SecureComposeScreen.tsx index 3c7c021..0bc1761 100644 --- a/src/popup/screens/SecureComposeScreen.tsx +++ b/src/popup/screens/SecureComposeScreen.tsx @@ -118,13 +118,6 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) {
- -
-

- 💡 Tip: Paste this encrypted message anywhere (Twitter, Discord, Email...). - Only members of {selectedGroup.emoji || '👥'} {selectedGroup.name} can decrypt it. -

-
); @@ -145,13 +138,6 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) {
-
-

- 🔒 Protected: Your message is composed in an isolated environment, - safe from page analytics and keyloggers. -

-
- {/* Group selector */}
- - {/* Post-quantum badge */} -
- - 🛡️ Post-Quantum Secure - - Group keys are shared via ML-KEM-768 -
); From b59b6827119c15ffe5b534fc05e67af80aeeb612 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 01:36:00 -0300 Subject: [PATCH 13/22] refactor: adding animation on the copy buttom upon encrypting --- src/popup/screens/SecureComposeScreen.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/popup/screens/SecureComposeScreen.tsx b/src/popup/screens/SecureComposeScreen.tsx index 0bc1761..7cad81a 100644 --- a/src/popup/screens/SecureComposeScreen.tsx +++ b/src/popup/screens/SecureComposeScreen.tsx @@ -14,6 +14,7 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) { const [isEncrypting, setIsEncrypting] = useState(false); const [encrypted, setEncrypted] = useState(null); const [selectedGroup, setSelectedGroup] = useState(null); + const [copySuccess, setCopySuccess] = useState(false); const groups = getGroups(vaultData); @@ -63,6 +64,12 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) { setSelectedGroup(null); } + async function copyToClipboard(text: string) { + await navigator.clipboard.writeText(text); + setCopySuccess(true); + setTimeout(() => setCopySuccess(false), 2000); + } + // Success screen after encryption if (encrypted && selectedGroup) { return ( @@ -87,7 +94,7 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) {

Encrypted to group: {selectedGroup.emoji || '👥'} {selectedGroup.name}

-

+

Copied to clipboard

@@ -99,10 +106,10 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) {
+
+ 🦆 + Encrypt +
+
-
+
-
-
Key
- -
-
- - +
+
+ Group +
+
diff --git a/public/overlay-encrypt.js b/public/overlay-encrypt.js index dc635a4..7faca19 100644 --- a/public/overlay-encrypt.js +++ b/public/overlay-encrypt.js @@ -3,40 +3,44 @@ const encryptText = document.getElementById('encrypt-text'); const encryptKey = document.getElementById('encrypt-key'); const title = document.getElementById('bubble-title'); - const keyRow = document.querySelector('.row'); - const buttonsRow = document.querySelector('.buttons'); + const keyRow = document.getElementById('key-row'); + const statusEl = document.getElementById('encrypt-status'); const submitBtn = document.getElementById('encrypt-submit'); const cancelBtn = document.getElementById('encrypt-cancel'); let port = null; + let currentCipher = ''; const state = { dragging: false }; - const statusEl = document.createElement('div'); - statusEl.className = 'status'; - statusEl.id = 'encrypt-status'; - buttonsRow?.after(statusEl); - function showStatus(msg, kind = 'info') { statusEl.textContent = msg || ''; - statusEl.classList.toggle('error', kind === 'error'); + statusEl.className = 'status'; + if (msg) { + statusEl.classList.add('visible'); + if (kind === 'error') statusEl.classList.add('error'); + if (kind === 'success') statusEl.classList.add('success'); + } requestResize(); } + function hideStatus() { + statusEl.textContent = ''; + statusEl.className = 'status'; + } + function resetUI() { + currentCipher = ''; encryptText.readOnly = false; encryptText.value = ''; - showStatus(''); + hideStatus(); if (keyRow) keyRow.style.display = ''; if (submitBtn) { submitBtn.style.display = ''; - submitBtn.textContent = 'Duck it'; + submitBtn.textContent = '🦆 Duck it'; + submitBtn.className = 'btn btn-primary'; } if (cancelBtn) { cancelBtn.textContent = 'Dismiss'; - cancelBtn.style.flex = '1'; - } - if (buttonsRow) { - buttonsRow.style.flexDirection = ''; } } @@ -54,19 +58,23 @@ hideBubble(); } - function setKeys(keys) { + function setGroups(groups) { encryptKey.innerHTML = ''; - if (!keys || !keys.length) { + if (!groups || !groups.length) { const opt = document.createElement('option'); opt.value = ''; - opt.textContent = 'No keys available'; + opt.textContent = 'No groups available'; encryptKey.appendChild(opt); encryptKey.disabled = true; } else { - keys.forEach((k) => { + groups.forEach((g) => { const opt = document.createElement('option'); - opt.value = k.id; - opt.textContent = k.name || 'Unnamed key'; + opt.value = g.id; + const emoji = g.emoji ? g.emoji + ' ' : ''; + const fp = g.shortFingerprint ? ` (${g.shortFingerprint})` : ''; + let name = g.name || 'Unnamed group'; + if (name.length > 18) name = name.substring(0, 18) + '...'; + opt.textContent = `${emoji}${name}${fp}`; encryptKey.appendChild(opt); }); encryptKey.disabled = false; @@ -95,16 +103,27 @@ } } + function showCopiedEffect() { + if (!submitBtn) return; + submitBtn.textContent = '✅ Copied!'; + submitBtn.classList.add('copied'); + setTimeout(() => { + submitBtn.textContent = '📋 Copy Again'; + submitBtn.classList.remove('copied'); + }, 1500); + } + async function handlePortMessage(event) { const data = event.data; if (!data || data.quackOverlay !== true) return; switch (data.type) { case 'open-encrypt': { - title.textContent = 'Quack'; + title.textContent = 'Encrypt'; resetUI(); - setKeys(data.keys || []); + setGroups(data.groups || []); encryptText.value = data.prefill || ''; showBubble(); + encryptText.focus(); requestResize(); break; } @@ -115,19 +134,31 @@ return; } if (data.cipher) { + currentCipher = data.cipher; encryptText.readOnly = true; encryptText.value = data.cipher; - showStatus('Encrypted message copied to clipboard!', 'info'); + + // Hide group selector if (keyRow) keyRow.style.display = 'none'; - if (submitBtn) submitBtn.style.display = 'none'; - if (cancelBtn) { - cancelBtn.textContent = 'Dismiss'; - cancelBtn.style.flex = '1'; - } + + // Auto-copy and show status const copied = await copyCipher(data.cipher); - if (!copied) { + if (copied) { + showStatus('Copied to clipboard!', 'success'); + } else { showStatus('Encrypted but copy failed. Copy manually.', 'error'); } + + // Switch footer: Copy Again (orange, left) | Close (gray, right) + if (submitBtn) { + submitBtn.textContent = '📋 Copy Again'; + submitBtn.className = 'btn btn-primary'; + submitBtn.style.display = ''; + } + if (cancelBtn) { + cancelBtn.textContent = '✕ Close'; + } + requestResize(); } break; @@ -157,14 +188,32 @@ }); } + // Auto-resize iframe when textarea is manually resized by the user + if (encryptText && typeof ResizeObserver !== 'undefined') { + new ResizeObserver(() => requestResize()).observe(encryptText); + } + document.getElementById('close-btn')?.addEventListener('click', closeBubble); - submitBtn?.addEventListener('click', () => { + submitBtn?.addEventListener('click', async () => { + // If cipher is ready, this is the Copy button + if (currentCipher) { + const copied = await copyCipher(currentCipher); + if (copied) { + showCopiedEffect(); + showStatus('Copied to clipboard!', 'success'); + } else { + showStatus('Copy failed. Try selecting the text manually.', 'error'); + } + return; + } + + // Otherwise, encrypt port?.postMessage({ quackOverlay: true, type: 'encrypt-request', plaintext: encryptText.value || '', - keyId: encryptKey.value, + groupId: encryptKey.value, }); }); @@ -176,8 +225,11 @@ } }); + // Drag support const dragHandle = document.getElementById('drag-handle'); - dragHandle?.addEventListener('mousedown', () => { + dragHandle?.addEventListener('mousedown', (e) => { + // Don't start drag if clicking on close button or interactive elements + if (e.target.closest('.close-btn')) return; state.dragging = true; port?.postMessage({ quackOverlay: true, type: 'drag-start' }); }); diff --git a/src/content/input-detector.ts b/src/content/input-detector.ts index 385f276..dad4f22 100644 --- a/src/content/input-detector.ts +++ b/src/content/input-detector.ts @@ -1,26 +1,25 @@ /** * Content Script Input Detection * - * Detects Quack:// triggers in input fields, tracks editables, and shows encrypt prompts. + * Detects Quack triggers in input fields and shows "Start a secure message?" prompt. + * All triggers (Quack://, Quack:, quack:, ___) use the same UX flow: + * 1. User types a trigger pattern + * 2. "Start a secure message?" prompt appears + * 3. Clicking "Yes" opens the encrypt bubble */ import { debounce, getElementValue } from '@/utils/helpers'; -import { getEditableRoot, getTriggerAnchorRect, positionCard } from './utils'; -import { showNotification, showSecureComposePrompt } from './notifications'; +import { getEditableRoot, getTriggerAnchorRect } from './utils'; +import { showSecureComposePrompt } from './notifications'; import { updateInlineHighlight } from './inline-highlight'; import { openEncryptBubble, isEncryptOverlayActive, setEncryptOverlayCloseCallback } from './overlay-manager'; -// Encrypt trigger patterns: Quack: or quack: or ___ (but not Quack://) -const ENCRYPT_TRIGGER_PATTERNS = /(Quack:|quack:|___)(?!\/\/)/g; +// Unified trigger pattern: Quack://, Quack:, quack:, or ___ +const TRIGGER_PATTERN = /(?:Quack:\/\/|Quack:|quack:|___)/g; // State let activeEditable: HTMLElement | null = null; let activeObserver: MutationObserver | null = null; -let encryptPromptEl: HTMLElement | null = null; -let encryptPromptCleanup: (() => void) | null = null; -let encryptTriggerToken: string | null = null; -let encryptTriggerIndex: number | null = null; -let encryptTriggerEditable: HTMLElement | null = null; /** * Set the active editable element and observe mutations @@ -47,118 +46,26 @@ function setActiveEditable(el: HTMLElement | null): void { } /** - * Find encrypt trigger in text (last occurrence of Quack: or quack: or ___) + * Find the last trigger match in the text */ -function findEncryptTrigger(value: string): { token: string; index: number } | null { - const regex = new RegExp(ENCRYPT_TRIGGER_PATTERNS); +function findTrigger(value: string): { token: string; index: number } | null { + const regex = new RegExp(TRIGGER_PATTERN); let match: RegExpExecArray | null = null; let current: RegExpExecArray | null; while ((current = regex.exec(value)) !== null) { match = current; } if (!match) return null; - return { token: match[1], index: match.index }; + return { token: match[0], index: match.index }; } /** - * Clear the encrypt prompt + * Open the encrypt bubble at the given anchor position */ -export function clearEncryptPrompt(): void { - if (encryptPromptEl) { - encryptPromptEl.remove(); - } - encryptPromptEl = null; - encryptTriggerEditable = null; - encryptTriggerIndex = null; - encryptTriggerToken = null; - if (encryptPromptCleanup) { - encryptPromptCleanup(); - encryptPromptCleanup = null; - } -} - -/** - * Show the encrypt prompt card - */ -function showEncryptPrompt( - editable: HTMLElement, - token: string, - index: number, - anchorRect: DOMRect | null -): void { - if (isEncryptOverlayActive()) return; - const anchor = anchorRect || editable.getBoundingClientRect(); - - if ( - encryptPromptEl && - encryptTriggerEditable === editable && - encryptTriggerIndex === index && - encryptTriggerToken === token - ) { - positionCard(anchor, encryptPromptEl); - return; - } - - clearEncryptPrompt(); - - const card = document.createElement('div'); - card.className = 'quack-selection-card'; - card.innerHTML = ` - - - `; - - const handleOutside = (evt: PointerEvent) => { - const target = evt.target as Node | null; - if (target && card.contains(target)) return; - clearEncryptPrompt(); - }; - - const handleKeydown = (evt: KeyboardEvent) => { - if (evt.key === 'Escape') { - clearEncryptPrompt(); - } - }; - - document.addEventListener('pointerdown', handleOutside, true); - document.addEventListener('keydown', handleKeydown, true); - - encryptPromptCleanup = () => { - document.removeEventListener('pointerdown', handleOutside, true); - document.removeEventListener('keydown', handleKeydown, true); - }; - - card.querySelector('.quack-card-primary')?.addEventListener('click', () => { - clearEncryptPrompt(); - openEncryptBubble('', anchor, editable).catch(err => { - console.error('Encrypt overlay error', err); - }); - }); - - card.querySelector('.quack-card-secondary')?.addEventListener('click', () => { - clearEncryptPrompt(); - }); - - encryptPromptEl = card; - encryptTriggerEditable = editable; - encryptTriggerIndex = index; - encryptTriggerToken = token; - document.body.appendChild(card); - positionCard(anchor, card); -} - -/** - * Open secure compose (triggered by Quack://) - */ -function openSecureCompose(): void { - chrome.runtime.sendMessage({ - type: 'OPEN_SECURE_COMPOSE', - payload: { - url: window.location.href, - } +function handleEncryptYes(editable: HTMLElement, anchor: DOMRect): void { + openEncryptBubble('', anchor, editable).catch(err => { + console.error('Encrypt overlay error', err); }); - - showNotification('Click the Quack extension icon to compose securely'); } /** @@ -172,18 +79,28 @@ function handleInputUpdate(event: Event): void { setActiveEditable(editable); const value = getElementValue(editable); - // Check for Quack:// trigger (secure compose) - if (value.endsWith('Quack://')) { - showSecureComposePrompt(editable, openSecureCompose, () => {}); - } + // Don't show prompt if encrypt overlay is already open + if (isEncryptOverlayActive()) return; - // Check for encrypt trigger (Quack: or quack: or ___) - const encryptMatch = findEncryptTrigger(value); - if (encryptMatch && !isEncryptOverlayActive()) { - const anchorRect = getTriggerAnchorRect(editable, encryptMatch.index, encryptMatch.token.length); - showEncryptPrompt(editable, encryptMatch.token, encryptMatch.index, anchorRect); - } else if (!encryptMatch) { - clearEncryptPrompt(); + // Check for any trigger pattern + const triggerMatch = findTrigger(value); + if (triggerMatch) { + // Don't re-show if the prompt is already visible in the DOM + const existingPrompt = document.querySelector('.quack-secure-prompt'); + if (existingPrompt) return; + + const anchorRect = getTriggerAnchorRect(editable, triggerMatch.index, triggerMatch.token.length); + const anchor = anchorRect || editable.getBoundingClientRect(); + + showSecureComposePrompt( + editable, + () => handleEncryptYes(editable, anchor), + () => {} // "No" clicked — prompt removes itself, next trigger will work + ); + } else { + // Trigger text was deleted — dismiss the prompt immediately + const existingPrompt = document.querySelector('.quack-secure-prompt'); + if (existingPrompt) existingPrompt.remove(); } // Update inline highlights @@ -218,5 +135,8 @@ export function setupInputDetection(): void { }); } -// Register callback to clear encrypt prompt when overlay closes -setEncryptOverlayCloseCallback(clearEncryptPrompt); +// Clear any lingering prompt when encrypt overlay closes +setEncryptOverlayCloseCallback(() => { + const prompt = document.querySelector('.quack-secure-prompt'); + if (prompt) prompt.remove(); +}); diff --git a/src/content/notifications.ts b/src/content/notifications.ts index dfbfd12..1c8b2e9 100644 --- a/src/content/notifications.ts +++ b/src/content/notifications.ts @@ -145,8 +145,8 @@ export function showSecureComposePrompt( onNo(); }); - // Auto-dismiss after 10 seconds - setTimeout(() => prompt.remove(), 10000); + // Auto-dismiss after 1.5 seconds of inactivity + setTimeout(() => prompt.remove(), 2000); } /** diff --git a/src/content/overlay-manager.ts b/src/content/overlay-manager.ts index 1e037c1..f2c611f 100644 --- a/src/content/overlay-manager.ts +++ b/src/content/overlay-manager.ts @@ -10,7 +10,7 @@ import { isLockedError, requestUnlock, sendMessageSafe } from './utils'; // Overlay dimensions const OVERLAY_WIDTH = 340; const OVERLAY_HEIGHT = 260; -const OVERLAY_MAX_HEIGHT = 420; +const OVERLAY_MAX_HEIGHT = 520; const OVERLAY_MIN_HEIGHT = 180; const OVERLAY_MARGIN = 12; @@ -144,7 +144,7 @@ function handleOverlayPortMessage(kind: OverlayKind, event: MessageEvent): void break; } case 'encrypt-request': { - handleOverlayEncryptRequest(data.plaintext ?? '', data.keyId); + handleOverlayEncryptRequest(data.plaintext ?? '', data.groupId); break; } case 'drag-start': { @@ -301,16 +301,16 @@ function setupEncryptOverlayDismiss(): void { }; } -async function handleOverlayEncryptRequest(plaintext: string, keyId: string): Promise { - if (!keyId) { - sendOverlayMessage('encrypt', { type: 'encrypt-result', error: 'No key selected' }); +async function handleOverlayEncryptRequest(plaintext: string, groupId: string): Promise { + if (!groupId) { + sendOverlayMessage('encrypt', { type: 'encrypt-result', error: 'No group selected' }); return; } try { const resp = await sendMessageSafe({ type: 'ENCRYPT_MESSAGE', - payload: { plaintext, keyId }, + payload: { plaintext, groupId }, }); if (isLockedError(resp?.error)) { @@ -390,10 +390,10 @@ export async function openEncryptBubble( ): Promise { encryptOverlayActive = true; - const keyResponse = await sendMessageSafe({ type: 'GET_KEYS' }); - const keys = keyResponse.keys || []; + const groupResponse = await sendMessageSafe({ type: 'GET_GROUPS' }); + const groups = groupResponse.groups || []; - if (!keys.length) { + if (!groups.length) { encryptOverlayActive = false; requestUnlock(); return; @@ -401,5 +401,5 @@ export async function openEncryptBubble( await showOverlay('encrypt', anchor || editable.getBoundingClientRect()); setupEncryptOverlayDismiss(); - sendOverlayMessage('encrypt', { quackOverlay: true, type: 'open-encrypt', keys, prefill }); + sendOverlayMessage('encrypt', { quackOverlay: true, type: 'open-encrypt', groups, prefill }); } diff --git a/src/content/secure-display.ts b/src/content/secure-display.ts index 3086897..a8256d3 100644 --- a/src/content/secure-display.ts +++ b/src/content/secure-display.ts @@ -34,6 +34,8 @@ interface BubbleState { frame: HTMLIFrameElement; cipherId: string; port: MessagePort | null; + dragging: boolean; + position: { top: number; left: number }; } // ============================================================================ @@ -141,6 +143,8 @@ function createBubble(cipher: DetectedCipher): BubbleState | null { frame, cipherId: cipher.id, port: null, + dragging: false, + position: { ...pos }, }; frame.onload = () => { @@ -153,6 +157,29 @@ function createBubble(cipher: DetectedCipher): BubbleState | null { closeBubble(cipher.id); } else if (data?.type === 'copy' && typeof data.text === 'string') { navigator.clipboard?.writeText(data.text).catch(console.error); + } else if (data?.type === 'drag-start') { + state.dragging = true; + } else if (data?.type === 'drag-end') { + state.dragging = false; + } else if (data?.type === 'drag-move' && state.dragging) { + const deltaX = data.deltaX ?? 0; + const deltaY = data.deltaY ?? 0; + const viewportW = window.innerWidth; + const viewportH = window.innerHeight; + const frameW = state.frame.offsetWidth || BUBBLE_WIDTH; + const frameH = state.frame.offsetHeight || BUBBLE_HEIGHT; + + state.position.left = Math.min( + Math.max(BUBBLE_MARGIN, state.position.left + deltaX), + viewportW - frameW - BUBBLE_MARGIN + ); + state.position.top = Math.min( + Math.max(BUBBLE_MARGIN, state.position.top + deltaY), + viewportH - frameH - BUBBLE_MARGIN + ); + + state.frame.style.left = `${state.position.left}px`; + state.frame.style.top = `${state.position.top}px`; } }; From 8d8bbc66c931391b1d7a64e1d28e4a0782dbae5e Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 19:32:39 -0300 Subject: [PATCH 21/22] fix: missing error in missing decryption key --- src/content/secure-display.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/content/secure-display.ts b/src/content/secure-display.ts index a8256d3..c3dd50d 100644 --- a/src/content/secure-display.ts +++ b/src/content/secure-display.ts @@ -15,6 +15,7 @@ import { QUACK_MSG_REGEX, MAX_AUTO_DECRYPTS } from '@/utils/constants'; import { sendMessageSafe, isWithinEditable, positionCard } from './utils'; +import { showNotification } from './notifications'; // ============================================================================ // Types @@ -305,10 +306,14 @@ function showSelectionCard(encrypted: string, selectionRect: DOMRect): void { tempEl.style.cssText = `position:fixed;left:${selectionRect.left}px;top:${selectionRect.top}px;`; document.body.appendChild(tempEl); - await decryptCipher(encrypted, tempEl); + const success = await decryptCipher(encrypted, tempEl); tempEl.remove(); hideSelectionCard(); + + if (!success) { + showNotification('🔒 You don\'t have the key to decrypt this message'); + } }); copyBtn?.addEventListener('click', async (e) => { From 1d651ad8e99870ee26182c576da713115df28ec8 Mon Sep 17 00:00:00 2001 From: 0xneves Date: Fri, 6 Feb 2026 20:55:25 -0300 Subject: [PATCH 22/22] feat: stealth mode --- public/overlay-encrypt.js | 106 ++++++++- src/background/service-worker.ts | 56 ++--- src/content/overlay-manager.ts | 21 +- src/crypto/group.ts | 251 +++++++++++++++++++++- src/crypto/message.ts | 56 ++++- src/popup/screens/SecureComposeScreen.tsx | 166 ++++++++++---- src/popup/screens/SettingsScreen.tsx | 35 +++ src/types/index.ts | 14 ++ src/utils/constants.ts | 7 +- 9 files changed, 604 insertions(+), 108 deletions(-) diff --git a/public/overlay-encrypt.js b/public/overlay-encrypt.js index 7faca19..b48d5b5 100644 --- a/public/overlay-encrypt.js +++ b/public/overlay-encrypt.js @@ -10,7 +10,38 @@ let port = null; let currentCipher = ''; + let stealthMode = false; const state = { dragging: false }; + + // Create stealth mode toggle (inserted dynamically) + function createStealthRow() { + const existing = document.getElementById('stealth-row'); + if (existing) return existing; + + const stealthRow = document.createElement('div'); + stealthRow.id = 'stealth-row'; + stealthRow.className = 'form-row'; + stealthRow.style.cssText = 'display: flex; align-items: center; gap: 6px; margin: 4px 0 2px 0;'; + + const checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.id = 'stealth-checkbox'; + checkbox.style.cssText = 'cursor: pointer; width: 14px; height: 14px;'; + checkbox.checked = stealthMode; + checkbox.addEventListener('change', (e) => { + stealthMode = e.target.checked; + }); + + const label = document.createElement('label'); + label.htmlFor = 'stealth-checkbox'; + label.style.cssText = 'cursor: pointer; font-size: 13px; font-weight: 500; color: #374151; margin-left: 2px;'; + label.textContent = ' 🥷 Stealth Mode'; + + stealthRow.appendChild(checkbox); + stealthRow.appendChild(label); + + return stealthRow; + } function showStatus(msg, kind = 'info') { statusEl.textContent = msg || ''; @@ -30,10 +61,21 @@ function resetUI() { currentCipher = ''; + stealthMode = false; encryptText.readOnly = false; encryptText.value = ''; hideStatus(); - if (keyRow) keyRow.style.display = ''; + if (keyRow) { + keyRow.style.display = ''; + // Add stealth toggle after key row + const stealthRow = createStealthRow(); + if (stealthRow.parentElement !== keyRow.parentElement) { + keyRow.parentElement.insertBefore(stealthRow, keyRow.nextSibling); + } + stealthRow.style.display = ''; + const checkbox = document.getElementById('stealth-checkbox'); + if (checkbox) checkbox.checked = false; + } if (submitBtn) { submitBtn.style.display = ''; submitBtn.textContent = '🦆 Duck it'; @@ -58,27 +100,65 @@ hideBubble(); } - function setGroups(groups) { + function setTargets(personalKeys, groups) { encryptKey.innerHTML = ''; - if (!groups || !groups.length) { + + const hasIdentities = personalKeys && personalKeys.length > 0; + const hasGroups = groups && groups.length > 0; + + if (!hasIdentities && !hasGroups) { const opt = document.createElement('option'); opt.value = ''; - opt.textContent = 'No groups available'; + opt.textContent = 'No encryption targets available'; encryptKey.appendChild(opt); encryptKey.disabled = true; - } else { + return; + } + + // Add placeholder + const placeholder = document.createElement('option'); + placeholder.value = ''; + placeholder.textContent = 'Select target...'; + encryptKey.appendChild(placeholder); + + // Add identities first (personal encryption) + if (hasIdentities) { + const identitySeparator = document.createElement('option'); + identitySeparator.disabled = true; + identitySeparator.textContent = '── Identities (Personal) ──'; + encryptKey.appendChild(identitySeparator); + + personalKeys.forEach((k) => { + const opt = document.createElement('option'); + opt.value = k.id; + const fp = k.shortFingerprint ? ` (${k.shortFingerprint})` : ''; + let name = k.name || 'Unnamed identity'; + if (name.length > 16) name = name.substring(0, 16) + '...'; + opt.textContent = `🔑 ${name}${fp}`; + encryptKey.appendChild(opt); + }); + } + + // Add groups (shared encryption) + if (hasGroups) { + const groupSeparator = document.createElement('option'); + groupSeparator.disabled = true; + groupSeparator.textContent = '── Groups (Shared) ──'; + encryptKey.appendChild(groupSeparator); + groups.forEach((g) => { const opt = document.createElement('option'); opt.value = g.id; - const emoji = g.emoji ? g.emoji + ' ' : ''; + const emoji = g.emoji ? g.emoji + ' ' : '👥 '; const fp = g.shortFingerprint ? ` (${g.shortFingerprint})` : ''; let name = g.name || 'Unnamed group'; - if (name.length > 18) name = name.substring(0, 18) + '...'; + if (name.length > 16) name = name.substring(0, 16) + '...'; opt.textContent = `${emoji}${name}${fp}`; encryptKey.appendChild(opt); }); - encryptKey.disabled = false; } + + encryptKey.disabled = false; } async function copyCipher(text) { @@ -120,7 +200,7 @@ case 'open-encrypt': { title.textContent = 'Encrypt'; resetUI(); - setGroups(data.groups || []); + setTargets(data.personalKeys || [], data.groups || []); encryptText.value = data.prefill || ''; showBubble(); encryptText.focus(); @@ -138,13 +218,16 @@ encryptText.readOnly = true; encryptText.value = data.cipher; - // Hide group selector + // Hide group selector and stealth toggle if (keyRow) keyRow.style.display = 'none'; + const stealthRow = document.getElementById('stealth-row'); + if (stealthRow) stealthRow.style.display = 'none'; // Auto-copy and show status const copied = await copyCipher(data.cipher); + const stealthLabel = data.stealth ? ' (🥷 stealth)' : ''; if (copied) { - showStatus('Copied to clipboard!', 'success'); + showStatus(`Copied to clipboard!${stealthLabel}`, 'success'); } else { showStatus('Encrypted but copy failed. Copy manually.', 'error'); } @@ -214,6 +297,7 @@ type: 'encrypt-request', plaintext: encryptText.value || '', groupId: encryptKey.value, + stealth: stealthMode, }); }); diff --git a/src/background/service-worker.ts b/src/background/service-worker.ts index b8522e1..b09588f 100644 --- a/src/background/service-worker.ts +++ b/src/background/service-worker.ts @@ -12,7 +12,6 @@ import type { Message, VaultData, - ContactKey, EncryptMessagePayload, DecryptMessagePayload, ImportKeyPayload, @@ -39,13 +38,14 @@ import { parseKeyString, exportPublicKey } from '@/storage/vault'; -import { getSession, shouldAutoLock, markVaultLocked, updateLastActivity, migrateSessionToMemoryOnly } from '@/storage/settings'; +import { getSettings, getSession, shouldAutoLock, markVaultLocked, updateLastActivity, migrateSessionToMemoryOnly } from '@/storage/settings'; import { - encryptGroupMessage, + encryptGroupMessage, + encryptPersonalMessage, decryptMessage, createGroupInvitation, tryAcceptInvitation, - encryptToContact // Legacy support + encryptToContact // Legacy support for contacts } from '@/crypto/message'; // In-memory vault data (cleared when service worker restarts) @@ -403,8 +403,11 @@ async function handleLeaveGroup(payload: { groupId: string }) { } /** - * Encrypt message to a group (primary method) - * Falls back to legacy contact encryption if keyId provided instead of groupId + * Encrypt message to a group or personal key + * - Groups: AES-256-GCM with shared key + * - Personal keys: AES-256-GCM with derived key (same size as groups) + * - Contacts: Legacy Kyber-based encryption + * - Stealth mode: Omit fingerprint for privacy (requires brute-force decrypt) */ async function handleEncryptMessage(payload: EncryptMessagePayload) { if (!(await ensureUnlocked())) { @@ -414,33 +417,29 @@ async function handleEncryptMessage(payload: EncryptMessagePayload) { throw new Error('Vault is locked'); } - const { plaintext, groupId } = payload; + const { plaintext, groupId, stealth = false } = payload; - // Try as group first (new method) + // Try as group first const group = getGroupById(groupId, cachedVaultData); if (group) { - const encrypted = await encryptGroupMessage(plaintext, group); - return { encrypted, groupName: group.name }; + const encrypted = await encryptGroupMessage(plaintext, group, stealth); + return { encrypted, groupName: group.name, stealth }; } - // Fallback: try as key ID (legacy contact encryption) + // Try as key ID (personal key or contact) const key = getKeyById(groupId, cachedVaultData); if (key) { - // Legacy: encrypt to contact - const contactKey: ContactKey = isContactKey(key) - ? key - : { - id: key.id, - name: key.name, - type: 'contact' as const, - publicKey: key.publicKey, - fingerprint: key.fingerprint, - shortFingerprint: key.shortFingerprint, - createdAt: key.createdAt - }; + // Personal key: use derived AES (same compact format as groups) + if (isPersonalKey(key)) { + const encrypted = await encryptPersonalMessage(plaintext, key, stealth); + return { encrypted, keyName: key.name, stealth }; + } - const encrypted = await encryptToContact(plaintext, contactKey); - return { encrypted, keyName: key.name }; + // Contact key: use legacy Kyber-based encryption (stealth not supported for Kyber) + if (isContactKey(key)) { + const encrypted = await encryptToContact(plaintext, key); + return { encrypted, keyName: key.name }; + } } throw new Error('Group or key not found'); @@ -448,6 +447,7 @@ async function handleEncryptMessage(payload: EncryptMessagePayload) { /** * Decrypt message using groups (primary) or personal keys (legacy) + * Stealth messages require brute-force decryption (controlled by settings) */ async function handleDecryptMessage(payload: DecryptMessagePayload) { if (!(await ensureUnlocked())) { @@ -461,8 +461,12 @@ async function handleDecryptMessage(payload: DecryptMessagePayload) { const groups = getGroups(cachedVaultData); const personalKeys = getPersonalKeys(cachedVaultData); + // Check if stealth decryption is enabled in settings + const settings = await getSettings(); + const stealthEnabled = settings.stealthDecryption ?? true; + // Try to decrypt with groups and personal keys - const result = await decryptMessage(encryptedMessage, groups, personalKeys); + const result = await decryptMessage(encryptedMessage, groups, personalKeys, stealthEnabled); if (result) { if (result.groupId) { diff --git a/src/content/overlay-manager.ts b/src/content/overlay-manager.ts index f2c611f..2e1c35a 100644 --- a/src/content/overlay-manager.ts +++ b/src/content/overlay-manager.ts @@ -144,7 +144,7 @@ function handleOverlayPortMessage(kind: OverlayKind, event: MessageEvent): void break; } case 'encrypt-request': { - handleOverlayEncryptRequest(data.plaintext ?? '', data.groupId); + handleOverlayEncryptRequest(data.plaintext ?? '', data.groupId, data.stealth ?? false); break; } case 'drag-start': { @@ -301,16 +301,16 @@ function setupEncryptOverlayDismiss(): void { }; } -async function handleOverlayEncryptRequest(plaintext: string, groupId: string): Promise { +async function handleOverlayEncryptRequest(plaintext: string, groupId: string, stealth: boolean): Promise { if (!groupId) { - sendOverlayMessage('encrypt', { type: 'encrypt-result', error: 'No group selected' }); + sendOverlayMessage('encrypt', { type: 'encrypt-result', error: 'No target selected' }); return; } try { const resp = await sendMessageSafe({ type: 'ENCRYPT_MESSAGE', - payload: { plaintext, groupId }, + payload: { plaintext, groupId, stealth }, }); if (isLockedError(resp?.error)) { @@ -323,7 +323,7 @@ async function handleOverlayEncryptRequest(plaintext: string, groupId: string): const cipher = resp.encrypted.startsWith(QUACK_PREFIX) ? resp.encrypted : `${QUACK_PREFIX}${resp.encrypted}`; - sendOverlayMessage('encrypt', { quackOverlay: true, type: 'encrypt-result', cipher }); + sendOverlayMessage('encrypt', { quackOverlay: true, type: 'encrypt-result', cipher, stealth: resp.stealth }); } else { sendOverlayMessage('encrypt', { quackOverlay: true, type: 'encrypt-result', error: 'Encryption failed' }); } @@ -390,10 +390,13 @@ export async function openEncryptBubble( ): Promise { encryptOverlayActive = true; - const groupResponse = await sendMessageSafe({ type: 'GET_GROUPS' }); - const groups = groupResponse.groups || []; + // Fetch both groups and personal keys for encryption targets + const keysResponse = await sendMessageSafe({ type: 'GET_KEYS' }); + const groups = keysResponse.groups || []; + const personalKeys = keysResponse.personal || []; - if (!groups.length) { + // Need at least one encryption target (identity or group) + if (!groups.length && !personalKeys.length) { encryptOverlayActive = false; requestUnlock(); return; @@ -401,5 +404,5 @@ export async function openEncryptBubble( await showOverlay('encrypt', anchor || editable.getBoundingClientRect()); setupEncryptOverlayDismiss(); - sendOverlayMessage('encrypt', { quackOverlay: true, type: 'open-encrypt', groups, prefill }); + sendOverlayMessage('encrypt', { quackOverlay: true, type: 'open-encrypt', groups, personalKeys, prefill }); } diff --git a/src/crypto/group.ts b/src/crypto/group.ts index a762977..b594537 100644 --- a/src/crypto/group.ts +++ b/src/crypto/group.ts @@ -12,6 +12,7 @@ import type { ContactKey, PersonalKey, GroupMessage, + StealthMessage, GroupInvitation, InvitationPayload } from '@/types'; @@ -19,7 +20,9 @@ import type { const AES_KEY_BYTES = 32; // AES-256 const AES_IV_BYTES = 12; // GCM standard const GROUP_MESSAGE_PREFIX = 'Quack://'; +const STEALTH_MESSAGE_PREFIX = 'Quack://_:'; // Stealth mode - no fingerprint const INVITATION_PREFIX = 'Quack://INV:'; +const PERSONAL_AES_CONTEXT = 'quack-personal-aes-v1'; // Domain separation for key derivation // ============================================================================ // Group Key Generation @@ -34,6 +37,28 @@ export async function generateGroupKey(): Promise { return base64Encode(keyBytes); } +/** + * Derive a personal AES-256 key from a Kyber secret key + * Uses SHA-256 with domain separation for deterministic key derivation + * @param secretKeyBase64 Kyber secret key (base64) + * @returns Base64 encoded AES-256 key + */ +export async function derivePersonalAesKey(secretKeyBase64: string): Promise { + const secretKeyBytes = base64Decode(secretKeyBase64); + const contextBytes = new TextEncoder().encode(PERSONAL_AES_CONTEXT); + + // Concatenate secret key + context for domain separation + const combined = new Uint8Array(secretKeyBytes.length + contextBytes.length); + combined.set(secretKeyBytes, 0); + combined.set(contextBytes, secretKeyBytes.length); + + // SHA-256 hash → first 32 bytes = AES-256 key + const hashBuffer = await crypto.subtle.digest('SHA-256', combined.buffer as ArrayBuffer); + const aesKeyBytes = new Uint8Array(hashBuffer).slice(0, AES_KEY_BYTES); + + return base64Encode(aesKeyBytes); +} + /** * Generate fingerprint from AES key * Uses SHA-256 hash, returns first 16 bytes as hex with colons @@ -98,15 +123,18 @@ async function importAESKeyForDecrypt(aesKeyBase64: string): Promise /** * Encrypt a message to a group - * Format: Quack://[group_short_fingerprint]:[iv_b64]:[ciphertext_b64] + * Normal format: Quack://[group_short_fingerprint]:[iv_b64]:[ciphertext_b64] + * Stealth format: Quack://_:[iv_b64]:[ciphertext_b64] (no fingerprint) * * @param plaintext Message to encrypt * @param group The group to encrypt to + * @param stealth If true, omit fingerprint (requires brute-force decryption) * @returns Encrypted message string */ export async function encryptGroupMessage( plaintext: string, - group: QuackGroup + group: QuackGroup, + stealth: boolean = false ): Promise { // Import AES key const aesKey = await importAESKeyForEncrypt(group.aesKey); @@ -123,7 +151,12 @@ export async function encryptGroupMessage( ); const ciphertext = new Uint8Array(encryptedBuffer); - // Format: Quack://[fingerprint]:[iv]:[ciphertext] + // Format depends on stealth mode + if (stealth) { + // Stealth: Quack://_:[iv]:[ciphertext] (no fingerprint) + return `${STEALTH_MESSAGE_PREFIX}${base64Encode(iv)}:${base64Encode(ciphertext)}`; + } + // Normal: Quack://[fingerprint]:[iv]:[ciphertext] return `${GROUP_MESSAGE_PREFIX}${group.shortFingerprint}:${base64Encode(iv)}:${base64Encode(ciphertext)}`; } @@ -205,6 +238,211 @@ export async function decryptWithGroups( return null; } +// ============================================================================ +// Stealth Message Parsing & Decryption +// ============================================================================ + +/** + * Check if a message string is in stealth format + * Stealth format: Quack://_:[iv_b64]:[ciphertext_b64] + */ +export function isStealthMessage(messageString: string): boolean { + return messageString.startsWith(STEALTH_MESSAGE_PREFIX); +} + +/** + * Parse a stealth encrypted message string + * Expected format: Quack://_:[base64]:[base64] + */ +export function parseStealthMessage(messageString: string): StealthMessage | null { + // Match: Quack://_:base64:base64 + const match = messageString.match( + /^Quack:\/\/_:([A-Za-z0-9+/=]+):([A-Za-z0-9+/=]+)$/ + ); + + if (!match) return null; + + return { + iv: match[1], + ciphertext: match[2] + }; +} + +/** + * Try to decrypt a stealth message with a single AES key + * @param message Parsed stealth message + * @param aesKey Base64-encoded AES key to try + * @returns Decrypted plaintext or null if failed + */ +async function tryDecryptStealth( + message: StealthMessage, + aesKey: string +): Promise { + try { + const key = await importAESKeyForDecrypt(aesKey); + const iv = base64Decode(message.iv); + const ciphertext = base64Decode(message.ciphertext); + + const decryptedBuffer = await crypto.subtle.decrypt( + { name: 'AES-GCM', iv: iv.buffer as ArrayBuffer }, + key, + ciphertext.buffer as ArrayBuffer + ); + + return new TextDecoder().decode(decryptedBuffer); + } catch { + // AES-GCM decryption will fail with wrong key (auth tag mismatch) + return null; + } +} + +/** + * Brute-force decrypt a stealth message by trying all groups and personal keys + * @param messageString The Quack://_: message string + * @param groups All groups to try + * @param personalKeys All personal keys to try + * @returns Decrypted result with source info, or null + */ +export async function decryptStealthMessage( + messageString: string, + groups: QuackGroup[], + personalKeys: PersonalKey[] +): Promise<{ plaintext: string; groupId?: string; keyId?: string } | null> { + const parsed = parseStealthMessage(messageString); + if (!parsed) return null; + + // Try all groups + for (const group of groups) { + const plaintext = await tryDecryptStealth(parsed, group.aesKey); + if (plaintext !== null) { + return { plaintext, groupId: group.id }; + } + } + + // Try all personal keys (using derived AES keys) + for (const key of personalKeys) { + const derivedAesKey = await derivePersonalAesKey(key.secretKey); + const plaintext = await tryDecryptStealth(parsed, derivedAesKey); + if (plaintext !== null) { + return { plaintext, keyId: key.id }; + } + } + + return null; +} + +// ============================================================================ +// Personal Key Encryption (Self-Encryption using derived AES) +// ============================================================================ + +/** + * Encrypt a message to a personal key (self-encryption) + * Uses AES-256-GCM with a key derived from the Kyber secret key + * Normal format: Quack://[personal_short_fingerprint]:[iv_b64]:[ciphertext_b64] + * Stealth format: Quack://_:[iv_b64]:[ciphertext_b64] (no fingerprint) + * + * @param plaintext Message to encrypt + * @param personalKey The personal key to encrypt to + * @param stealth If true, omit fingerprint (requires brute-force decryption) + * @returns Encrypted message string + */ +export async function encryptPersonalMessage( + plaintext: string, + personalKey: PersonalKey, + stealth: boolean = false +): Promise { + // Derive AES key from secret key + const derivedAesKey = await derivePersonalAesKey(personalKey.secretKey); + const aesKey = await importAESKeyForEncrypt(derivedAesKey); + + // Generate random IV + const iv = crypto.getRandomValues(new Uint8Array(AES_IV_BYTES)); + + // Encrypt with AES-GCM + const encoded = new TextEncoder().encode(plaintext); + const encryptedBuffer = await crypto.subtle.encrypt( + { name: 'AES-GCM', iv }, + aesKey, + encoded + ); + const ciphertext = new Uint8Array(encryptedBuffer); + + // Format depends on stealth mode + if (stealth) { + // Stealth: Quack://_:[iv]:[ciphertext] (no fingerprint) + return `${STEALTH_MESSAGE_PREFIX}${base64Encode(iv)}:${base64Encode(ciphertext)}`; + } + // Normal: Quack://[fingerprint]:[iv]:[ciphertext] + // Personal key shortFingerprint has colons (4C:F2:2C:10), must strip them for message format + const compactFingerprint = personalKey.shortFingerprint.replace(/:/g, ''); + return `${GROUP_MESSAGE_PREFIX}${compactFingerprint}:${base64Encode(iv)}:${base64Encode(ciphertext)}`; +} + +/** + * Decrypt a message using a personal key's derived AES key + * @param message Parsed message (same format as group message) + * @param personalKey The personal key (must match fingerprint) + * @returns Decrypted plaintext or null if failed + */ +export async function decryptPersonalMessage( + message: GroupMessage, + personalKey: PersonalKey +): Promise { + // Verify fingerprint match + // Personal key shortFingerprint has colons (4C:F2:2C:10), message has none (4CF22C10) + const compactFingerprint = personalKey.shortFingerprint.replace(/:/g, ''); + if (message.groupFingerprint !== compactFingerprint) { + return null; + } + + try { + // Derive AES key from secret key + const derivedAesKey = await derivePersonalAesKey(personalKey.secretKey); + const aesKey = await importAESKeyForDecrypt(derivedAesKey); + const iv = base64Decode(message.iv); + const ciphertext = base64Decode(message.ciphertext); + + const decryptedBuffer = await crypto.subtle.decrypt( + { name: 'AES-GCM', iv: iv.buffer as ArrayBuffer }, + aesKey, + ciphertext.buffer as ArrayBuffer + ); + + return new TextDecoder().decode(decryptedBuffer); + } catch (error) { + console.error('Personal key decryption failed:', error); + return null; + } +} + +/** + * Try to decrypt a message string with multiple personal keys + * @param messageString The Quack:// message string + * @param personalKeys All personal keys to try + * @returns Decrypted result with key info, or null + */ +export async function decryptWithPersonalKeys( + messageString: string, + personalKeys: PersonalKey[] +): Promise<{ plaintext: string; personalKey: PersonalKey } | null> { + const parsed = parseGroupMessage(messageString); + if (!parsed) return null; + + // Find matching personal key by fingerprint + // Personal key shortFingerprint has colons (4C:F2:2C:10), message has none (4CF22C10) + for (const key of personalKeys) { + const compactFingerprint = key.shortFingerprint.replace(/:/g, ''); + if (compactFingerprint === parsed.groupFingerprint) { + const plaintext = await decryptPersonalMessage(parsed, key); + if (plaintext !== null) { + return { plaintext, personalKey: key }; + } + } + } + + return null; +} + // ============================================================================ // Group Invitation (Secure Key Sharing via Kyber) // ============================================================================ @@ -380,16 +618,17 @@ export function isInvitation(text: string): boolean { } /** - * Extract all Quack strings from text (messages, invitations, keys) + * Extract all Quack strings from text (messages, invitations, keys, stealth) */ export function extractQuackStrings(text: string): string[] { - // Match group messages, invitations, and key shares - const regex = /Quack:\/\/(?:INV:|KEY:)?[A-Za-z0-9+/=:]+/g; + // Match group messages, stealth messages, invitations, and key shares + const regex = /Quack:\/\/(?:INV:|KEY:|_:)?[A-Za-z0-9+/=:]+/g; const matches = text.match(regex) || []; // Filter to only valid formats return matches.filter(m => isGroupMessage(m) || + isStealthMessage(m) || isInvitation(m) || /^Quack:\/\/KEY:[A-Za-z0-9+/=]+$/.test(m) ); diff --git a/src/crypto/message.ts b/src/crypto/message.ts index 7531c5a..c0a6650 100644 --- a/src/crypto/message.ts +++ b/src/crypto/message.ts @@ -15,7 +15,10 @@ import { encapsulate, decapsulate } from './kyber'; import { encryptGroupMessage, decryptWithGroups, + decryptWithPersonalKeys, isGroupMessage, + isStealthMessage, + decryptStealthMessage, isInvitation, extractQuackStrings as extractQuackStringsFromGroup } from './group'; @@ -34,9 +37,13 @@ const KEY_PREFIX = 'Quack://KEY:'; // Re-export group functions for external use export { encryptGroupMessage, + encryptPersonalMessage, decryptWithGroups, + decryptWithPersonalKeys, parseGroupMessage, isGroupMessage, + isStealthMessage, + decryptStealthMessage, createGroupInvitation, parseInvitation, acceptInvitation, @@ -61,23 +68,54 @@ export async function encryptMessage( } /** - * Decrypt a message using available groups - * Tries each group until one works + * Decrypt a message using available groups and personal keys + * Tries groups first, then personal keys with derived AES, then stealth mode, then legacy format + * + * @param messageString The encrypted message + * @param groups All available groups + * @param personalKeys All available personal keys + * @param stealthEnabled If true, try brute-force decryption for stealth messages (default: true) */ export async function decryptMessage( messageString: string, groups: QuackGroup[], - personalKeys?: PersonalKey[] + personalKeys?: PersonalKey[], + stealthEnabled: boolean = true ): Promise<{ plaintext: string; groupId?: string; keyId?: string } | null> { - // Try group message first (new format) + // Try stealth message format (Quack://_:[iv]:[ciphertext]) - requires brute force + if (isStealthMessage(messageString)) { + if (stealthEnabled) { + const stealthResult = await decryptStealthMessage( + messageString, + groups, + personalKeys || [] + ); + if (stealthResult) { + return stealthResult; + } + } + // Stealth message but decryption disabled or failed + return null; + } + + // Try group message format (Quack://[fingerprint]:[iv]:[ciphertext]) if (isGroupMessage(messageString)) { - const result = await decryptWithGroups(messageString, groups); - if (result) { - return { plaintext: result.plaintext, groupId: result.group.id }; + // Try groups first + const groupResult = await decryptWithGroups(messageString, groups); + if (groupResult) { + return { plaintext: groupResult.plaintext, groupId: groupResult.group.id }; + } + + // Try personal keys with derived AES (same format, different fingerprint source) + if (personalKeys && personalKeys.length > 0) { + const personalResult = await decryptWithPersonalKeys(messageString, personalKeys); + if (personalResult) { + return { plaintext: personalResult.plaintext, keyId: personalResult.personalKey.id }; + } } } - // Try legacy 1-to-1 format (backwards compatibility) + // Try legacy 1-to-1 Kyber format (backwards compatibility) if (messageString.startsWith(LEGACY_MESSAGE_PREFIX) && personalKeys) { const result = await decryptLegacyMessage(messageString, personalKeys); if (result) { @@ -220,7 +258,7 @@ export async function decryptLegacyMessage( * Check if a string looks like a Quack encrypted message (any format) */ export function isQuackMessage(text: string): boolean { - return isGroupMessage(text) || text.startsWith(LEGACY_MESSAGE_PREFIX); + return isGroupMessage(text) || isStealthMessage(text) || text.startsWith(LEGACY_MESSAGE_PREFIX); } /** diff --git a/src/popup/screens/SecureComposeScreen.tsx b/src/popup/screens/SecureComposeScreen.tsx index 7cad81a..921e9c0 100644 --- a/src/popup/screens/SecureComposeScreen.tsx +++ b/src/popup/screens/SecureComposeScreen.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; -import type { VaultData, QuackGroup } from '@/types'; -import { getGroups } from '@/storage/vault'; -import { encryptGroupMessage } from '@/crypto/group'; +import type { VaultData } from '@/types'; +import { getGroups, getPersonalKeys } from '@/storage/vault'; +import { encryptGroupMessage, encryptPersonalMessage } from '@/crypto/group'; interface SecureComposeScreenProps { vaultData: VaultData; @@ -10,13 +10,18 @@ interface SecureComposeScreenProps { function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) { const [message, setMessage] = useState(''); - const [selectedGroupId, setSelectedGroupId] = useState(''); + const [selectedTargetId, setSelectedTargetId] = useState(''); const [isEncrypting, setIsEncrypting] = useState(false); const [encrypted, setEncrypted] = useState(null); - const [selectedGroup, setSelectedGroup] = useState(null); + const [selectedTarget, setSelectedTarget] = useState<{ name: string; emoji?: string; type: 'group' | 'identity'; stealth?: boolean } | null>(null); const [copySuccess, setCopySuccess] = useState(false); + const [stealthMode, setStealthMode] = useState(false); const groups = getGroups(vaultData); + const personalKeys = getPersonalKeys(vaultData); + + // Check if selected target is an identity or group + const isIdentitySelected = personalKeys.some(k => k.id === selectedTargetId); async function handleEncrypt() { if (!message.trim()) { @@ -24,23 +29,36 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) { return; } - if (!selectedGroupId) { - alert('Please select a group'); + if (!selectedTargetId) { + alert('Please select an identity or group'); return; } setIsEncrypting(true); try { - // Find the selected group - const group = groups.find(g => g.id === selectedGroupId); - if (!group) throw new Error('Group not found'); + let encryptedMessage: string; + let targetInfo: { name: string; emoji?: string; type: 'group' | 'identity'; stealth?: boolean }; - // Encrypt to the group - const encryptedMessage = await encryptGroupMessage(message, group); + if (isIdentitySelected) { + // Encrypt to personal identity (self-encryption using derived AES) + const identity = personalKeys.find(k => k.id === selectedTargetId); + if (!identity) throw new Error('Identity not found'); + + // Use encryptPersonalMessage with derived AES key (same size as group messages) + encryptedMessage = await encryptPersonalMessage(message, identity, stealthMode); + targetInfo = { name: identity.name, type: 'identity', stealth: stealthMode }; + } else { + // Encrypt to group + const group = groups.find(g => g.id === selectedTargetId); + if (!group) throw new Error('Group not found'); + + encryptedMessage = await encryptGroupMessage(message, group, stealthMode); + targetInfo = { name: group.name, emoji: group.emoji, type: 'group', stealth: stealthMode }; + } setEncrypted(encryptedMessage); - setSelectedGroup(group); + setSelectedTarget(targetInfo); // Copy to clipboard await navigator.clipboard.writeText(encryptedMessage); @@ -61,7 +79,7 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) { function handleNew() { setMessage(''); setEncrypted(null); - setSelectedGroup(null); + setSelectedTarget(null); } async function copyToClipboard(text: string) { @@ -71,7 +89,7 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) { } // Success screen after encryption - if (encrypted && selectedGroup) { + if (encrypted && selectedTarget) { return (
@@ -92,8 +110,13 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) { Message Encrypted!

- Encrypted to group: {selectedGroup.emoji || '👥'} {selectedGroup.name} + Encrypted to {selectedTarget.type === 'identity' ? 'identity' : 'group'}: {selectedTarget.type === 'identity' ? '🔑' : (selectedTarget.emoji || '👥')} {selectedTarget.name}

+ {selectedTarget.stealth && ( +

+ 🥷 Stealth mode enabled +

+ )}

Copied to clipboard

@@ -145,51 +168,80 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) {
- {/* Group selector */} + {/* Target selector (identities + groups) */}
- {groups.length > 0 ? ( + {(personalKeys.length > 0 || groups.length > 0) ? ( ) : (

- ⚠️ No groups yet! + ⚠️ No encryption targets!

- Create a group first, then you can encrypt messages to share with its members. + Create an identity or a group first to encrypt messages.

)}
- {/* Selected group info */} - {selectedGroupId && ( -
+ {/* Selected target info */} + {selectedTargetId && ( +
{(() => { - const group = groups.find(g => g.id === selectedGroupId); - if (!group) return null; - return ( -
- {group.emoji || '👥'} -
-

{group.name}

-

{group.shortFingerprint}

+ if (isIdentitySelected) { + const identity = personalKeys.find(k => k.id === selectedTargetId); + if (!identity) return null; + return ( +
+ 🔑 +
+

{identity.name}

+

{identity.shortFingerprint}

+
-
- ); + ); + } else { + const group = groups.find(g => g.id === selectedTargetId); + if (!group) return null; + return ( +
+ {group.emoji || '👥'} +
+

{group.name}

+

{group.shortFingerprint}

+
+
+ ); + } })()}
)} @@ -212,10 +264,29 @@ function SecureComposeScreen({ vaultData, onBack }: SecureComposeScreenProps) {

+ {/* Stealth mode toggle */} +
+ setStealthMode(e.target.checked)} + className="mt-1 w-4 h-4 text-purple-600 border-gray-300 rounded focus:ring-purple-500" + /> + +
+ {/* Encrypt button */} {/* Info box */} -
+

- How it works: Your message is encrypted using AES-256-GCM with the - group's shared key. Anyone in the group can decrypt it — nobody else can. + How it works: {stealthMode + ? 'Stealth mode removes the recipient fingerprint from the encrypted message. Observers cannot tell who can decrypt it, but the recipient must try all their keys to decrypt (slightly slower).' + : isIdentitySelected + ? 'Your message is encrypted using your identity\'s public key. Only you can decrypt it with your private key — perfect for personal notes and secrets.' + : 'Your message is encrypted using AES-256-GCM with the group\'s shared key. Anyone in the group can decrypt it — nobody else can.'}

diff --git a/src/popup/screens/SettingsScreen.tsx b/src/popup/screens/SettingsScreen.tsx index 681f0ff..43cabaf 100644 --- a/src/popup/screens/SettingsScreen.tsx +++ b/src/popup/screens/SettingsScreen.tsx @@ -24,12 +24,14 @@ function SettingsScreen({ vaultData, onBack, onImport }: SettingsScreenProps) { const [exportError, setExportError] = useState(null); const [exportSuccess, setExportSuccess] = useState(false); const [autoLockTimeout, setAutoLockTimeout] = useState(15); + const [stealthDecryption, setStealthDecryption] = useState(true); const [settingsLoaded, setSettingsLoaded] = useState(false); // Load current settings on mount useEffect(() => { getSettings().then(settings => { setAutoLockTimeout(settings.autoLockTimeout); + setStealthDecryption(settings.stealthDecryption ?? true); setSettingsLoaded(true); }); }, []); @@ -39,6 +41,11 @@ function SettingsScreen({ vaultData, onBack, onImport }: SettingsScreenProps) { await saveSettings({ autoLockTimeout: value }); } + async function handleStealthDecryptionChange(value: boolean) { + setStealthDecryption(value); + await saveSettings({ stealthDecryption: value }); + } + // Stats const personalKeys = vaultData.keys.filter(k => k.type === 'personal').length; const contacts = vaultData.keys.filter(k => k.type === 'contact').length; @@ -212,6 +219,34 @@ function SettingsScreen({ vaultData, onBack, onImport }: SettingsScreenProps) { : 'Vault stays unlocked until you lock manually or close the browser.'}

+ + {/* Stealth Decryption Toggle */} +
+
+

🥷 Stealth Decryption

+ + {settingsLoaded && ( + + )} +
+ +

+ {stealthDecryption + ? 'Stealth messages (hidden recipient) will be decrypted by trying all your keys. Slightly slower but provides maximum privacy.' + : 'Stealth messages will be ignored. Enable to decrypt messages where the sender hid the recipient fingerprint.'} +

+
{/* Export/Import Section */} diff --git a/src/types/index.ts b/src/types/index.ts index 05d5eae..ee53cd0 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -127,6 +127,7 @@ export interface AppSettings { showNotifications: boolean; maxAutoDecrypts: number; // Default: 10 debugMode: boolean; // Show debug info + stealthDecryption: boolean; // Try all keys for stealth messages (no fingerprint) } export interface SessionData { @@ -151,6 +152,18 @@ export interface GroupMessage { ciphertext: string; // AES-GCM encrypted message (base64) } +/** + * Stealth encrypted message format: + * Quack://_:[iv_b64]:[ciphertext_b64] + * + * No fingerprint - requires brute-force decryption with all keys. + * Hides message recipient from observers. + */ +export interface StealthMessage { + iv: string; // AES-GCM IV (base64) + ciphertext: string; // AES-GCM encrypted message (base64) +} + /** * Group invitation format (secure key delivery): * Quack://INV:[recipient_short_fingerprint]:[kyber_ciphertext_b64]:[encrypted_group_data_b64] @@ -257,6 +270,7 @@ export interface Message { export interface EncryptMessagePayload { plaintext: string; groupId: string; // Now encrypts to a GROUP, not a contact + stealth?: boolean; // If true, omit fingerprint (requires brute-force decrypt) } export interface DecryptMessagePayload { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 4ea40ba..913a118 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -4,18 +4,22 @@ // Message Format Constants // Group format: Quack://[group_fp]:[iv]:[ciphertext] +// Stealth format: Quack://_:[iv]:[ciphertext] (no fingerprint, try all keys) // Legacy format: Quack://MSG:[fingerprint]:[kyber_ct]:[aes_data]:[iv] // Key format: Quack://KEY:[public_key_base64] // Invitation format: Quack://INV:[recipient_fp]:[kyber_ct]:[encrypted_group_data] export const QUACK_PREFIX = 'Quack://'; +export const QUACK_STEALTH_PREFIX = 'Quack://_:'; export const QUACK_MSG_PREFIX = 'Quack://MSG:'; export const QUACK_KEY_PREFIX = 'Quack://KEY:'; export const QUACK_INV_PREFIX = 'Quack://INV:'; // Group message: Quack://[8-char-hex]:[base64]:[base64] export const QUACK_GROUP_REGEX = /Quack:\/\/[A-Fa-f0-9]{8}:[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+/g; +// Stealth message: Quack://_:[base64]:[base64] (no fingerprint) +export const QUACK_STEALTH_REGEX = /Quack:\/\/_:[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+/g; // Legacy 1-to-1: Quack://MSG:[8-char]:[kyber_ct]:[aes_data]:[iv] -export const QUACK_MSG_REGEX = /Quack:\/\/(?:MSG:)?[A-Fa-f0-9]{8}:[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+(?::[A-Za-z0-9+/=]+)?/g; +export const QUACK_MSG_REGEX = /Quack:\/\/(?:MSG:|_:)?(?:[A-Fa-f0-9]{8}:)?[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+(?::[A-Za-z0-9+/=]+)?/g; export const QUACK_KEY_REGEX = /Quack:\/\/KEY:[A-Za-z0-9+/=]+/g; export const QUACK_INV_REGEX = /Quack:\/\/INV:[A-Fa-f0-9]{8}:[A-Za-z0-9+/=]+:[A-Za-z0-9+/=]+/g; // Legacy format for backward compatibility @@ -56,6 +60,7 @@ export const DEFAULT_SETTINGS = { showNotifications: true, maxAutoDecrypts: MAX_AUTO_DECRYPTS, debugMode: false, + stealthDecryption: true, // Try all keys for stealth messages (default: enabled) }; // Extension Colors (matching Tailwind theme)