From 684cf3c1d80be58964ec57526c81f02eb756cacd Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:09:39 +0200 Subject: [PATCH 01/31] Remove duplicate code --- cli/src/main.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 6503d14..8382d82 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -78,16 +78,6 @@ fn main() { return; } - // Get the filename and output format - let filename = matches.value_of("output"); - let format = matches.value_of("format").unwrap(); - - // Writing to PDF requires a filename - if format == "pdf" && filename.is_none() { - eprintln!("Need an output file name when writing to PDF"); - return; - } - // Number of t addresses to generate let t_addresses = matches.value_of("t_addresses").unwrap().parse::().unwrap(); From 61a74850901fbae6d68f5ea0ddc0552eaa3149c8 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:10:37 +0200 Subject: [PATCH 02/31] Remove testnet option from README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 7768869..add1ab3 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,6 @@ FLAGS: -h, --help Prints help information -n, --nohd Don't reuse HD keys. Normally, hushpaperwallet will use the same HD key to derive multiple addresses. This flag will use a new seed for each address - --testnet Generate Testnet addresses -V, --version Prints version information OPTIONS: From d9144b249c86b805ee870e8de7bbd2789dd5178c Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:11:25 +0200 Subject: [PATCH 03/31] Remove `mut` on paper.rs file --- lib/src/paper.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/paper.rs b/lib/src/paper.rs index 1d3fc06..b2fc625 100644 --- a/lib/src/paper.rs +++ b/lib/src/paper.rs @@ -30,7 +30,7 @@ impl ToBase58Check for [u8] { payload.extend_from_slice(self); payload.extend_from_slice(suffix); - let mut checksum = double_sha256(&payload); + let checksum = double_sha256(&payload); payload.append(&mut checksum[..4].to_vec()); payload.to_base58() } From 2677b0c1224411296fc7c11b652dc925597c86c0 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:12:00 +0200 Subject: [PATCH 04/31] Update gitignore file --- cli/.gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/.gitignore b/cli/.gitignore index 2dc46e2..b4f0619 100644 --- a/cli/.gitignore +++ b/cli/.gitignore @@ -1,3 +1,2 @@ .vscode -test_working.pdf target/ From ea5b7dc3514e8d4872ac53c4d13801bd35a69855 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:12:29 +0200 Subject: [PATCH 05/31] Del 'docs' folder --- docs/paperwallet.png | Bin 124572 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/paperwallet.png diff --git a/docs/paperwallet.png b/docs/paperwallet.png deleted file mode 100644 index 3b8039aca91304b46c78523ed1795c3bf5c0adb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124572 zcmZ_02RxSj9zTAgLX^=GGDA^WB_z8fJ2NvvR?8@4RT71aWMqZ1XDMWqon(uYWMn5~ zkNn=(bI$pl-+BFC|L45Ud5(48*L8ir-_Pg0K6ikoy3)3-%v(t$(l+HYiswiq3M&$c zd@t1&e22F`(ggq7Vxgj>NZKI&lUSA-j_*)kJ9FNNL^{Gv{Flu2xy%iGlhRpP?G)wU z7Dk5MoR)Gm3;5Pv=TipG3Rf>*wz}d>QgE~~ceb+RxM}Nb!=a?Crm25>`yLXBgQTn| zr{mf)8RurKKDM!8_UjZE&xdmzw5`7B`H=;?{KDic&BibGby@B`@8>c7zMFrQIn?if zf@Q(Ilyi#8Z6ar%dlq|n&%Mq4?O75z<)nXf&|R8sWTvRuts-|_azwhTIA>yAkHeQ< zh>3Q~-S-!We+_0P)@S(q>;Dtq>P`&&|M`N+L9_OsKl$e`|K|%@u>%+X`q(vdS+0m`|DTj=*&z3>&7U#=3kSOArTRqNqL2Z zHJ`JM(jBJ06&HDLl&k*Sx^3I3D!*-Hq^=y3yLjaYw_CT8okp50sxJ4I?DF#Rnp^w3 zzN&fd968Cj#F?7q_?47`!MaDu3ir2@e4?V5RO6+J)xVxqQK9kvyUh3Y#NK~DRR_(5 z=dNo@!uZL=(V(Oxu7HB$SHE*`aoyQYmBO%V*S(aK{rLrxlMX9yU%h%gL4!x~Pb$ zIYA~eDj`)Pp-pOJXy{s-$Hw2X>hp)+AByv-d&J)U^I@1Zd5yWH<^Fu>rRm{MEQaj= z*=n_Ke90M1-z-FE>gqoKxF=OTZYw)`0&`vQrDnFqxD%1_b=B307wdvu41*cCPyc9p zu0kStdU|>+P0PKwwnxy^H#~gD$qKJ^$t~NM6)6R3YimVn1_uW2?BG*xaS{*^_*Qo7 zP3_MI{{BAq?rkRh=&!mz`n~K##PZ6DMZ@ER$J8%QcIS&b4b%EG{Cw!(v+#?7o&8Z| zr99~!oy?l73}eTQsH;J9bIvP=?Al*!ixIoL^610r)8kh|o<0?DEW>r-vLl$qI627@ zWW1l8ugGy*p5@uPb*q7y6}G;g!Q=D0gqQ+X-bD#toSyt5N{Uz&eR|aP9G`hPPeVgP zONF<0HSSM2oY()+qYb5>-k-D17kRCh)X(GFcKSN13DW!CTMD-I(~@+G#`*X6eQa!OjM+{NRWH<@{`mb{qq#Z$q`;p;g2`99i=Fr^EG$SQ z7BL5(`1p8(ve;PG$#2Cw@W>TCJfv{(7cN}zIbu?B;d`muXkW#K{)dX_=)G~j-2bi> zcb^wkwz0EIx;|J-BAu$qt?)jadIQXr^B~$NfMphQB z=%uE|%8RSNE9$VBDn2|tA|OEXh+QT}Ph(nSE9q)qdBnlMyv>@V?$?)}){}&Ics3tA zc#w*UN>)~u6Da|7JHNfgM5q4w;H^NRZp|0QBY6_ShPNSc57C4 zc4$;oeQ|tjY~aw4rE$5(a^|N=S2wrTJ~1&d=V6uIf0qUyt;}D_%nIDbBKGdX2kHcA z&&t=Azlv`t{Bt_)7Pza)%KE7CcI)csSh78S{`~p-uV0_Wf9>gMlRK}hOs%B1>*mdy zk_S|jmHS6cOI;a)gM*I-;khaYUK*?oVx+VpPq01qJY%nyITts#y{D$0sp*lzDc}73 z{AFuOt3J=geZ$QOf{rKo`5(Mi#$TA**c=dBdv}{+X7G{BS=Py|uG2rrE@>Wh96Hne zUA2Wk>=P0f4kAHCR7S2s^k}hGk z6?6$g5)u*|zOwkEn3x#ncPj%mH1zT%^IEDCaRa{C>$v>33G_bN92vbejuk9OxL z8$RVDJsbBY4&r3?L) z_gXqSsv!aPT1K$&>qLW@c=@mrC@!xoRe0)zsX)XTtQ9ii*ml!+AM5va@H;ic4a7uI;~q=bUO9YW{M}bk7s{>lV{B}> zbFqZzc**gy<7E8&{F_K*vMbViL&SU7at^zDrx?zgTpToInAeRfh~V`Dm9eSKyxMD%VJ6&2MRkG#Cp{6ylr zzdsf8)cd=XtkJo-f)TrR?fSr)8WgmRPo}Ai&vrtSVgUAw~2bKxduwt`d1J?qj52IFHH`dh9^=%Pom= zT(sw%O0byvSVab{OkQVPHP^)7%N5 zw`>#7+=Mr{U~m8MJ{>z3A0OrW_wS=5oOsparOqci;!0whgi@bBZ~Y>nOl7S__O7mu z^2CivS=1mcW8=UF54NVfcwsS69pG$c3b5lx$FAP{*v8iOeRnq#I+ASU5fe-Ictazj zi+_eck$lh%E>!z7Op^VBaKyCr^hK>Yi5*iF#3U>~Rnp$p7H0cm5)by=M_ofher83Z*SZ<|A7M`XpG_ePTUA7DiY6M0WNs4qNk@fR{~61=7k=o9)(7t zc^;2{^pCi-bo^197M~Y!k00wKM~jrN;CzfUy2ih4|%&^;7&@|IX9gV@ru>}-=%>CmPG84d5RU%rr$;ttm~*U{^5KY7I^8=j`STk@3bdQoKQC~-|(v3 za=4?jb8HzPLBeap_fmYWadD;aaqqDH&%n3cnil`43tPWW8?`Z`;ux6r=p+(kiO z`nBbe1cRb$oRZF?KEKOXw{NWf_LdM;_gtBiyKzJ8d)ciz+grB<6-ZpC6@2%i`pxfM zUSI5MFU$3%S2yyuJsr#%fcj0I_H9w(+7H<#hr=Y|73X?7(zVBEQ_9Lty3ddEXiMUL z{9eDlQ8-@>gdKR5hTuBojLXZ*On6Ptew1@QNtbb*iLs9PS?$~De}PewTqZup%0=g~ zl1wYS)VygTb(NGTvkeOwSt_K=eJP*ymbg?+_g6iC!YL;93v zN|SyFI2GF#rR1c|-<`X5JxfgV5zx=MFhAbObj)riD=TZ>&EKZX>KCLGSY_7dc8q+( zdOF}itjvv7NgNjvO03wtm^OXk&3IW4T3~cLqxf`=-Qfs=8}=P>(AeuU(Um*+yJBOD zW^tDtfFYyHy~DiN9FES*OO`Rxo|4DhzUP@Mto`=h2p9NWDJX-k%Q%SB5o&nE{G+9? zuyCwkB^njuI*ahorQybC=hv1UX;09Rjf<|4J=}fxPDO>x{7j901@F+$p8>!2v@uCKAMo40??G4? zqm=733GlZXr%($UwZ8sLmT4LDt%b?=nfkdczzrZJWU@bLueQHX)6&t|uPv$jhx^-$ z%FFA|((k{+8Hmr^SdbDlri%ik;uo76M;eO?Cd6Q6LkyRS^UN%6ZXbwGbTqz zN6W2USlh{-LY17OoB!VRIjg;*uC9LUh?1hBui_#ZP`lj>_4@BT|2rU@s! z*2F<%tnP2$7bf9=+ey>5RmSd6FfwBK^5qMVj-0de(Z)}o(qrlGoO-yMD5uyT$&D(x z8C<0vhYubM5Dn+}fpc+2P3_+8+hojQ4reH73Fy?8LfsjDRC~V$lX(yNd$xKwuUg2H zCtDI7qm!l&1*AOML%ML~N-)qzbzL1d$Oavo)H{%nnT20QL&L+B@86T5qd8mq=9ZUI zHQ%77O*xaCmq+hQZ`aV<(6AMCjCj&$Q=}go#x7X~`FFP0f6g&^c+CE@EC3=U9h>jd zr$&Xgy7OfRq&Rkqm1?mwu(?vxwQQzvIM3h_qOGTAO(8H?(mMY3VBDh6ci|MI|Hl)Fee>o*|Bhu zXDyV2oBM84kuDl;rT^2Jvbdqt7X`N;*>=HhQgy)0c1gfia)mX%p3<*U}zKA*N0)F3(+N zK??J6eA&+PwbMiZP?vQkv{?3he(x^QZJ9X;RW@BUH zYs<4%*nHeLX@D0Lq%5-vHd9kmJi#iwtht2+d7`73nyZ+G&;)Vds7|jy+?$)UAa> zyAK;~0s>MzeY$P0IIg1UzHbJVARXP-t(A?@q7xlHLE@-!faBDOZQ_B?pYsq}QrwA~ zZPA~{4;(s_GOyja_xQi`uB`8l3zO%g7x+7#2;YUgp>pgsJuB;>cJ{G8?~R~x&(*V! z`+(9fa;isRrCK9r02%CBx07}Yng*t8r#7r59dwA2Wzx{lh?Vv<%u+SIOOcV0(UG9x zLbZB$<;fWhjgiI!1XKeS+L<{qFu-*~b9iu&f}Nc`fP(40%9Y>W%lfCLw&Mlp<@3OM z$Jv$Nf%Xg8v~UzRa5arvbjm#s2%u(UWW2UGWs;JbdJ*-u`^{B$JU(9(q$J%;y_S|1 zSu7SfjmBa(wGsbgK3cQbxVY=MvrU^e{Xpe}ezp(w08I4^B?rojv+Ncf!-=o2FS7vQ zUa+>_0;qD-u7e6CdQKWz+4H}dOXFRe@ZAIa{7FekHt- ztB2ik-~G0+kVp!Cw9j4|ZQs7#=1Tz&8eI^Y>dzN2F&x`6XW|0~<}{YO|f`yAAM@#Dw)y9WdX>%J8`gC8Bsc z`k+EpbaeD}OM+|_H{#VqmJeo9_dQ4`Kui8${JYX?#CQF%@`=gGNyRp)>jRs{y7Re} za&Z7H>w@=nj6_OB#l$>Vx}Ndin#?M&1~sQIB&tZraIF(KCESa@`}pos(!J>VUherZ z;QrMp;Jua!^!q32Qan67miV0%F#On(alEdC$5LLm5FNYp{xbJ@F05Fr5RM-Y&7LFs zAxGtef=RVKry-Ml{P=M_0A0%X7D~z;;2fbI$86hti%Lq)c^muEhb1Iv)CRFAxe&kh z_@MR~)Z3Yb1zzmeO(ZRSeLesgF0Y2|tm3lP&GBmBztp6pw6rs|kJvS~($Hic);2I; z8tcksw}t$wrK`&WI%kOm@}-wQbm)*}iPFmAZ^6$R=XLumaPCtJ-o2A`FDojF0$vP* zY#XK?CmBk;gEu5n&@2p_R%;#4_Uxgm;ZIM~zk@eLUt}YS9=$x3`CSnptGfkPeWA!P z?%H(rA!Gpmgi;Gi>m+@Br`*-!Xcg^}S&lTtV=4;CAqC~?)@9w@EKwu&~f$`qi znpdxmV(X^X&VV7+XMIIiw=>BrEoJpypWhQvc%?UH&|@BCq$4y9yv%E=uk%H@1@irDCRZq4uO&CzD+O`ZcKV^2{FbtPkPrsDAbEA&q*hIH$f8 z7Bxk09As?&%jQGMw=|h(Yr9SXIXewE-j0mi1I~GE>YGF$+sPPR)on5kkO!is(pkWx zOI#-We0)eHi!Ggyk%BU^F)Dc()sR?B#Z#v^A!Y)a*?i90>%KU3xYON|fNeEj zQ5|14eIV$>%JBmyP)A%;4I{l%X6c!j&MbzIeJj(@($Zo&apTa*JvSb#jJ5LxACiD97nZik$WpI$$bKL@U@k(<(gGIVQT8`Hb^?S z-XjkYyEmHl^x@WGr%TRL-ym)Q}Ki zyks1DRUlGVnKbPvv3c|6;4FSOH#g_>=g_sQ*Y^TZ?$Tl{E-u#8)}|n#q+M%kY;KMe zw|}0Kb41u1!gXxP&fw(I(pc_xFz_PPJUbSuaW(p8&<6YOGbtVW{<$Pv+05Z*vYS`} z%DGSo4;((cnWP#gxl3AFT4w=`ij#{gsn!-6Xh%c*7F*t#d&(**3RpVJ2To8TrWY4e zM{eA>LA8B5sE~(N51XJlHcJ3B(vK-`p`--&ae=-_`ac!ExMe$=)B&+?ShUu%TZ_zH z$x!RA^p@02$^Pr%(AFNO`ycP-e@wPM-g%4Vq_=NR^rq_S-)dk!X1D27&3IiRXa$Jx zGsWWR*%}ZsHtiRx44I3|e=a$ED+-NY9BaRS@s24Iu7MB<;#XHz25?MCK18R4PN!pS zZ~yVUbP;y>&OLi5NT`bhXy9j&@sctuwBr%`lyR#e<=4bhDK`-yOfnMCN)_Hl-AX^l z_&usTnalcKrK|w+tHj9ya^u z*#5KPfw@%wuMt_RpJF*>LxL+P!yvevH&Uj|Cq6o{F7vu{+OP=e5F(0k*SBjZ=U0n4 z+P}2tp}&9PYUUBsQYt<^K7N9{L2at8eF<{`NY5{xa`Wcv3(3?lELcnWCLlA93>}79 zf!#h=YF6O|0|!?!10OK|vS!3C0lk)$bDEm6PsJ{$9TF6zgLppo?cF;PR4kGY>_$LD z?Jv0%e;>eC+(Alw{`?-gP zP8P9|k#(&RemFyFqQ{Tx+ZCZbt28F0yk{VJtjrPCMbZd)74JYxdwY1)X%GNDZ}1-9 zCr_SKAKhF6p>UucO#A`%mt&7?Sk*X+#+k-UoagFNF}sd4`%TEk$H!x@;XEJB?dj>6 zZ2Hf_c!=ixe2BvQG^MoEc)TuDa2w|))YK4{8Tpe2L({p50HOGL?!x@a<=(zKtHH#* zh&9X~Rsd!#y74QJl`TkIXvi_(9!uo`TC?#fUzo+j!j3oBgEw zPMnbUC^s$8mGrLT@lI&5tIB4irPW(m|804ua5NZeAMDT+E5WEXV08ZcbxTOI;R2qJ z;{vQ!ru*+U^3G(65L{%I`^bUq(I1Fd;~X0%LH^$1pdBZ?k(w`jJyX9 z_~ZSC*tgM$j>dhXR+D zml;TwfG1p%9xJ;NZuu4J_i|3G!+9|$mmTn2xIGOPGC z4s4u!>rc#4QBefBo%o!sfX#X1SI;SzjlZi`4UCME)6%HGvF?V3GQ>-{k%M%>*rd@& zkiJ*o_%k^R9K>Q#7{{-FX=af1;t3bsje;kc{IC^b_x{QFR&<@>=g*(wFqSU8FpGkb zg8p@3ZE0roTd}AT@8#x+H>#@(zgo*ZZ|%q4?&xpNUHT@PRmS8p9|*H~LyCxjELFlp z8H9Dph>9qfs>i>XxB^a2PN*JmirKJYwdYT7CBarA-U!e<-=b!#udnZ!qkcQ~?75HT zFo@%1(~?Lgb@F6-Bg7xi)rHL@@IZ2Q881amO?t1DF+P$HNE|wPo?R!uqM~BU1mI4Q z$Fc|th#zQv%Mx1BOdY%TwVVX#&k#F`9Di-F?Mo#L83VHbOVFy{f5A=1{TerBOykHYofq5mSr1+vkU7Q{I zKzNn8lH%@j;Mx2_Rt-A?Y_IgZqDCLQTV5`myDIxx>_2(|`Wl zg@r&62!>@;JCM`c_h|McfoZ^(t4vW2zlQyr0vEZrcOSSU@rYi%di7&!Dj174J5EvX z+1}KYEq88t=ozFrz&AL#e$eH?r8Tv*Zi807`}8Th=SGCHHwDpADl01qv<;4(1VbPS zI?&Et#YVrae%&t^pB)qQ7?;)j3>-ZOok9HO6f3x5YqrsG!wNKI^e$~WlS zVBwJUS9xOfZ>M{ZLHS^;s4at$@Yf3g4!(GZyZ^*+xF_I4pjL=4GnD$ivT41;{nlk- zclJ$KJh4)4vu3y2pQolm?$jAtK{eHcAO~CHn(1li#DVyR1$LTEYtm-$l026QJ%{eR z+wE7k(6I&Hrl7O{MJ8m`k(x4oTU%SSDrRY~HGeSCCbn9fkaoG~3kl}XCB^$U?-tp7 zW#=YAGH{T*H*ZEtSx+e{`WtV+rEftcWmw#?gIDz(5<=JK$9306WH!i1;*ye;-@e8E zu^=bG@Qg?=KYrz#Kg5MW{MNa7R6z4fmnh+HA2NC!XexN{;Cml3ifLF2_&a$-mr$9i zpBy%tUYfb+vDkZ4CsL!BM3kzeTUJhvj`Zj>;9%FbSfR%GKYWmk_&zqFjA2grjw!c*fKOO3!>%!z-G(K?=c`EBqF`IGFir&8E z1~tW_DY~_Ig!!lqVFwaq75(4l>+8c_8|ydW_gg@IDP8f&nm05sIN-G6v0{!$f`fwt zaf`rei72cnlSCX0AYB+eD*YG#*x%j61}D6M*RNl@uCE+}2;wt6eGRo*Hs{jqtP+nE zngmJzz(C0Glq9&A_n%Cldln%S;o;%Y%_4MHt1s>9tp-^A{91yb44)Sbbx-2ZiQE2# znZxR4VZjvvKldMJKdJhpRU46VsyDf5XlTed2z;CD4(&1bPf4bGV}eXVxW2ZwHa|qJ z{(8uG>8eIXt51!TCgIhR=ph_7&EuDMfQ1qGvuU0%yQ)8Y2!Noh68I9WAq6S6bM41q zD3u%+L8joSLwATOSRtIC)|1)Mso%BV?< zY;5YUulA{1H^nMrW1a?7JLQb@g*qt&=d8^hnU)k7;hRV(5C?xtb{AdeCX;n^a^jhK zN+Eltul&=5^pEx}SoO~G?bNp#mgWSc7ikj~3{iKq^z?Ys)6-)o(8M;8B#<#tqao$L zehr;xU~Ej8)N;uml&qJfF_o^~FxR7PB%Jd0cO2lf@2KyDi%KSo@C|3z`r!kS;JK-N z+gZc{QMSV%Iu)-x`}ZbE%P|g{(gLfTCp3b<+{RyD-}Da;`&oT_Vm{uH&U*gJl_Pi% z^n3Qy z1^q>vrJ;WHhuWNyR71m>JZ zFO>z==6>_?CHxI)7|)8ig*L6^etv$)rsYOBcJ96tJ?gc-(%+qb@r@)6-cIpcuStE{Zd zI57tgZhB#%7LGtjbTopqBBkCNY?6|ah39g5DjOSVfye67w31ui-n_bEO!V*@zrP1z zueCpqKmo;$`#JfGjN?XgSe6S1lS55iT@_#wR`(7z;t}H_A1JikVq&|uY}vx~aX#ZM z-O_70lXE5nDw(zwL}5ll8GwFoP-wRcV$AenpEm&>5t_SKUq?-70vjV2c{5&u*f zSXv;Ht`Cz=kOKaE5AI5E!U<$L8UJuhtZ(xfEI2*Q&a>qGoSObk({O5z9py#)~q3TEw8p0r~`M!=%kuU(C zDcrBDuczWuj}2K8@rHr{MSw_NLi+JT0t|?a`E&Ft@V02WcPceXfch=-)!-0X6p(y*Lf_kdb6# zm$5$|6s}(vuB%9$rYwv3);DK$#&1JLdR`pCHQ+3MUvd=r;pfXD$sE>NPG~Z>G?=+$wE8}fC znK%iU2rY-Q?#=~WctpXFYt0dkfEIlc(hTBEA6vh?vfTk09S87zbd5==>-C_9c^(GZ zEx=L|U4-|B8Q1TH>*pU%g6)L~>eYCgG1GqQ%P1QScql(MLn( z@%{0Cc&5fJGFfOT7i?_<)>jv+T3Z>6yhOH*EB}i-P&-2@}F(1EjNX$$(J94(H zVi_2zA>&_1fk@I)5JIZQWr5x(R zP>lu?bT)*o9+*^8Ts!PXZJL%@&Ox>1pe|)JV&|waJKXwpH8m55hsZ9hugo)nq!#Mv z&p%iDrau5$Ug|!d(X&Sg^&huIgt3-D%7m|c6NlRL@Rc02C~-kOfJ9eN?0QE<>7N-i zP|wY+t^J@cG`ZY%`GnKeW)BbcG@cdPNq5CuXp#XY>F-jvBQoO)SJk-OV=rP>nmRhw zXb}B?{#jXvnpF2DfCJ4f&naBLyWO_F?O)wQ<=vglH1KHy5&z~mazuUH>%;hucFLjb zuAT-30Kia~L9>nF)>e8?R-e*&{Hr-XlyZ4@LFlhU$HV9X*a8ncJa=3}On|79vd_a$ z_5UPtIh6pvXPciNR!dtM5n!EKTmIw!-~qX2v6QTMJOE*F!yKWl_LfBanH7kAAp|%Q zE0aicDVHB;(1=r~Ry&Jb?oo^s1u{6Rnk?yCh3KaRfbkr{^6SnAtuytqe~gcxwL-Qn z%x1j8&I{FwSJ+cVM#gRv(U~ufulLpBX%TD_sVO4A3Oqkj9~2a1Yr@0JTUk@H8G*{% zI36)aZSUa8Av;0?rSUeHbSgWwVDzUCALPu(vSZ;}B+ZXWa3tY{(@Baw_-{8_EW;ded@` z0Njy0FyTu}eV-p*yDw?Vv*K_P!TgdNzqan#vu6_}Wqa_g^VED-YsN-r|Br zf^0f*U}5To!p2;znm(v+LU`mv@B*i?$v)cq>9=&W^dLg(tZzf;&k%F7|S@1(sv3VCiO+65KlfFu+gF6s7Y*YP63b!9?V0+5vp?Qb1b>HKkW!n8ph#FGC>%Yc z&x~ZKazqrYRl;-S=rX*|^k4w0{DJ~5Fo2x_$lhI6R8tEgalneM{_-UnAp?5S5WG_^ z>zd0B4mPEbSh|xPN&Z(&` zSnuJmhg+S&w?ANaen7OsA5ER09*7AzMr6KL8^E0*r04(a8K;^Va@1%*VW>Qy${4>0wx@J)aUtw%wXi?MKrdtoUI!Y9!|v?j zVjBxmRJyvW@0Op&EnSzB*WfTPM8Dg=4#;I=N(zCy$skWfq|+Zr-M$wa9(q?|4BgY9KTN7&i$v{xyiugJBvwGp{Y z2`?wRhtTH2!os**euTgVgUx-$-27Qb(SwH%mF4BhKQuIi9sC8gbawWq3fz0MY_!`W zg!`>pQmBU6161~YV*zN72J9XUJWQ_S9MG~e3&kQ*b6#KRJxdB{Y;0uidf(+hQNEsc zBxF9m|EnqFQy$3JIWJdb4cV8@&GR259E2hGkoyq}Lu7QS_ifGghH(|#gn+$wIvr6o z?bxkHA%jvT0{jcJYJELpWXLb8qVmvi<*{Ez2EX7ScS%V}hsO;UWJpFI7Ln5{;b5G~ zQGV%On~LN?th6UHwo0KzuyM4PV4j6vQC6pf4sYGQ3azMdVzvPDeUYH^FcITB0FqFL_UhH+G8dr z)>8}RuEXPM=cg|aWbVYoFq5=sbny!{*xX}o4h~tWf(~Fxv5whh74bVB3Bj0Ax^_+I zBpofSB4YhD<2eTT(lyre);*rrKP3QQ@tmMx`piq z5hTa|`rg{E5r8BrB%jcPT3)EJAW}DA)=Ft017ju7UGjhcKmUNZF&;Gm_rOBZdF7?gs>eD|M*<& zQk#LMxeNAKHI5|x-n{|Pm59DzVL~fZegw|=nX_jrv(CTFa~?Yvy79u>kv&bBjdt5M z$XEIT<(+@i^CbW8c%oy0!COJ=ec8vZ#s{*$T=`W zraKy+@sFom3c2o5tqLO;%DD=6nkN#oH8_yNGC9bm1*k}}9J8wq7y;4gP`rkuvC;xk zN_H_t8OzA3u{*8hQC$R3hh)ET1!(o|RpH>D6tUijDoIZV8-2+Q5CzSXU{*t+mBx3X;`9^!ZuvtN~cjjdd<2M^~BfIauPhnQr`Sh=>xg+Uj#wAONv5Mi-4(@!Qa;?f!%(BnY;8$Y|PHmt)+H@y|;*V)+Hg zqg|LAZJqn}{=M7)+Z)^V7v@MJA6#9x>x;RuPQG z@XD@pEAGvp%>5Xkjor>gFvIKXD=x;Ru38!2BW=EV?f(KSe#7K1IHKc7aI zEjxHiZPu_?bl85_1vhz)@*&1;9L?8&wFElbz|B^HxLNP3l zJDI`nS!GTZNPge%`vV%pTq(3cn3F!L=ARlH(*%#&TK^(TgvKaR6OB}`l9E!uY=(4` zuiNZUfZ`Weq2eQOlo|iv*cf61D`idMY{ag>i%Gis3>Ipz0~$jfTnCm%dF*>3VXDVr z@blUL1Mi6wPq{%OVj6$VU#YM6< zwwP5`RavdL{^99a=<_`^-;jFM%F>bpQ5_uL5hfmT&5L!7g=+tKnuUbzwy#p@U$z_L zHf7JCa-K(1=%$*crok9!I6KGEfTK3=h*@b58p88Ad^pJI7c%>yHk_{{i45m(<6dH- z2A94wbai>TA7~YxNT|Q|Z>2|U<}hE0sR|;iCia(*w~^Yr+_>Zd@N#pM9@j@^<>aKVHMG%zmMscr% z;|+VFe`JIb{}2$7Ys>`JDhM|*$uV-z$k6N0>}(!DG{G`3RC5~V>RWFw6udjw6bf)J zkWTK{vnRnlqVOu&J9JEp;U78TxXloj=^Y4R7I6GV0W9JQZ%esF%kapX5)F!09t`@R4j?cTAn&*aQR$)D|pG#-Qj69tG*W^1;>OO+WxYM9- zB%PcV1Sn7I=0spaixHHb>reJ>t?#o z^>_Iam?2@n4af>eNbJSRcVn!JIKH2;dh}qnil$7P*LA-+^g|1~hDnd^o}K|vCGl%N zNcgquVEXDZ<^MI`jN!&K#2mkR1R=L0J?|jx;h=0Gm1I4lzXMXj4G}6QCuhzLP5T}Y zBx3cC!Ug}Y8KvHrairqjy?fKs)9--vS`+0ckW`?=Sp~6{13#KUjE5L}z_i;BliY%Z z!-+f5$!}^dj!}{;q1-8;-h7kX2r^4 zXj=wsv>*2YF5a>j0ngLb)s+L2HQ2*3g44Q|dZ%$CMq>&(`+#9Uq$U zM^q$YERTwl$g*rAefacgm(eido#Z~>$~~V(=In4HVkLSfgiQVQGUkUOcY*xf~Y=&2JNlnvRYSz7HSbU;EJ< zxzRtl`dyrz>+x9vRGhweX-3Fy7MCxpp^J*UyL4{xnB|`kJsr}84clf9@m>*6bbl^9 zFSXf~m3jN5jEu9OfBZLDraxp#EgoX;#ke4@40mer^Nv_I-1oBG2tgAWW>N^s)dQ)A z(BP`wc7KWzzDwe0ZEZc~eg#v^){F@NWaJ>79KJumy<;bE!9;@9Yx(D%CKo7Ho3?Bj zKmvs^vVe$nK;`(SbmJl>uCFd!4knBH@#6xz%>{(==M2%^727tG5Hhv2wEO`fDRu&& ze5i22b|o}QTGZ-$7>|)~4SL>G~k#*#%HwPh@`wzK2UuOPj{?vQBa zdOz-yk-5Kom;k)f_X#E3n;P?3+;H(mr4J=K(p96T2qPkumXUF;7pUX?zebN(t0Z;Z zkjCwKeVGPB%uOytgw4pv>B%B8YXA08SWS?83UwX%^z=TwJ;I#A-6$ZrFC`^)ZEfi~ zY2(dKJt3b5j~-ESZu+;sQ}`MCfd*FN(aSxLBdx}M!&ATW_n7xz55g)zvWFnCa65$XDFj3Zfol_61o}xd3SZw% z#>I}OvTi>pv7;z=i`Xn@n)zC{v%Kkz$as~Te^v@H{BQc)x4?Zd;u$nkVa zywCX*tv@BlXiT#NbgRQbndMS%K!&`>YvK#Q!-L8di8!9ummF$Tj#?Nrqs#bghLHI9 z?TKwAKk!K$X_I5^sdG1hVU+YD5b9Dk=JOt^X8?+zNc+~u;}9$jD35rEJ-bw+{%fLei!8YnYe0UG&IQAXGq^2#Ad!$Q1IidAb;ux(1PDq+OX~}Hao?JLwy5-ScFCL9Vu5t^J#R?w znwqvFJRLiY!ZAHN3x8_QHFUj_5gO9}$KqPHxcu&T?y)h!ffdPw8xhBIQHls0JEc|4 zsq)WpLjzTvWOI7IdRsiBX^2MpsK3+h_3Yv(b9|~%mLHX%@bvtAc7z-e_sn;lu~09) zBX|Dn*$0Yz+2j*uVNs%&f~)1uW6B*HR*_P!@@@eZO1%^nIhn2(GsVH-`sN_oIs)6R zAS6oI?&sw_%lbI_=~E|XXty&+myl%9_4aRXz}A;=Lx4A2{D6ILNny2!=+Gs6`iw!T ztMGPqY1PQ>+t{R-z`u0(5MDtWs|A|v9~|UnRI2b=zhGnIj}HhM9UB8Rm3#3D)GZLa zDRe^j@H=Wk^1^(Ay4hJ|)6yPpzO5?)3WbOh7m5~^$QPvwdT?S+PB3yhK<2H_Pk1=r zZs5_xfR-G%H%PUe<=*@w=^w@Dr5<9&Z!_>Zz`#2sIGHQyUm#PJ_v#ff`Px4^O3)1G zD*=tKWN=k17LKddqGH0xL)K5RU=5MsHQojNvt ze|C8OUq;(~9dEmWS8|@CcRj|3pzmVket0~l?>a(`C{(?~9wt484nZPkS@}dzglU65 zB|3d~VtRT2l2wN5m8ZLr(xAlvK172#b7h<^<5+)=Y|$UP9i>pB_`(V;zep= zS`4yLIvdG(vYP>y!F6kw?By!2-b;yw@%F~zth zvoIwk^E+T5GCtdBu9j!6E7%M4*zIEPP`_NLZP=lw z^6Kox%N8_@C-Qm1>ZL~(mCBvGoGuNkTNilPl$kY)Hj6IC&tDOB8vgF2j(8sNQ3;?V z7t!RPkrfY2MLxfdk1d!6pdKKEylvY)&2NbY_Ry6H`?T+CspJ+?9`O-L2{P$N-EAYXo7Gy@@^%GOpbA}>W4(GbgY zaDb$Z>cnz`-=hrNd-?L^XlG`m@gfxe{)q{J@z2=;=d`th#-n3m_|d@?pUK}-EVS!X zz4DM}zB8!22*bv}m4H@^Bt=Wh6d+Z27F*5C`W$}g+c#w+6Nn)`Je&apGWI}ChxC+1 z55S%T3H5>2#GKOK9rFGtGXAK(58-F<=j3D0eeURNYmNde-%3it{P+N*(E)V9ftStF zJAl%}GBS^inBN#*`O_@J5;SCcW$u(y-Mg3)>yem3-Ya^^f~S>~9+Gd~>VGzZKLFs< zAD0n;%s?yj>CVSq9eS*G5>j6f9B@{nYx)z0=tmoHucmKYw)GF0Od_WYp#SY1zPz4!M3M?`fqPs4p)#j z`g#CQ5DoGH7F(d{Hjc$Zpcv+#!nYP2YKl9t<1vD69IkL1c{mjy(}p6RvybT^Plz>W zA1`&mhY0*E0lopu;lP;dt}1gQWnad^(__~{IP((`Y^;?K5`0*m!1wz zt4zrE24K)l>zVv!JgCGo-U!S-YqhBci&p)teSF^Muh6((LB`b^ELKmZ^i`SW$@M zr9KF*evl?6$^`Er2UB6+e{wHKLc}z7 zEyK|MIPeO*Bg3ULA+<42%Ub-VN+{PUN2_>ZV|2b+2@9>H`2H$J509_Cbyi&`v`RjD}PO%NFSl#b40jA(Ck z?fVKn|N8ImCzE9)zo%Thkd4kmjcJ`^nRv%@eWl&GpW}^SL~@CUv?cv2P&8$uu%C$O zycB3|;`FCzc){yarakY8E{7{-eJgl++$4WksZ7US{ayQ`!KpYLOMDW}t0h}1F87z$ z4cL;pR+of8XEqrb8NF2CsGx?Mu0vVeIx;yKc(c#5t3W;b^=s=B^Be7BkLDI%;Jq;E zPK;|YNjUC@+vt>C?v`(see%tNJ%aI>bppA;w+megheT_8N(`Nhoo-bOcODCmvll!5 zS^z33k-5O%=3jVE?$!up@h%kEr>x~>RAd}Z>JnTli>`w#RzQHqm~GFb0umfBD=%Fm z|C~T-54rM}g~Q2`cfF`YLRu9(wGPsXs^2=snRj2UL(=6s*0(rIM#&#?IgwVuWN-N) zrEw9~%@gSR25+v!8BgJ3zG9o}h?4(8P*_+i{}Tx3lkmxym3|jwRf<{h0a1Lzg?{~! z9#BnwmY`yk749*Cc|$~=P(yy;m540B|Do@8?8m?9Tdc*1A@q@_xQ@UBRXQUjLW=!6T@Y2EjG-{OmBi3WBbmXZjz&1wp;TqN9|v_2ImW~ z0q7xKID4=S>CX>oAxhGx&)91$5XdY3FJFEsOwtUlW9-Tl{rsEuPD=|@wvO-uu{~Fd z-aAoR!aN?b#p&U9zq`_0WD<}A1s2&Zx8>!W`&hO?dYXdYWnbv;JjXGh9cwAXSx$Pk zZwJT0Ykex$hQ4VEBXt{1Dw7Z!?F0THVF|KdKCPniD8dvP>0B?TJzB5$+Ks^m!hklo z5_4Etz>i8jIUv?I+i;XS<$Z>W)X|>hsj<9~D{doiRi2dh1a5|BF!uoMzMstEYrYhe zQ0Fj$REuqxs7;f@LsBhtaSkv6Y0zu-fOVSzvvy2fe9u5{@9y^YT>I0^Jwrpu<-5T& zA?_HD#Ls%Vgow37%e+>2vPV-RO8~|A8$(2ZL`SrXD$IxY`A-)3d3&oLF~ZO>PlWvZ zzT^*O8~=U~52F~@>Zc+=do)sw48`V=FT70p8UTCnxu>{J|9Q@nXWLCH58lglyGs1j zcxOM_T=g$;a-J-SW~C)12|ad8i_RsZ0BqQ7?2CSecMJ@81Du~}i@;!`qHN>3-bqg% zpJLOHY=-v^IDTkb#Rp7!uhl<;_Z4@?8S(mEzat%UvgqgIb zrzaAGyTvrB1k=KJc!b55+TXZw$l_DN%urT)RZs$`MUEkdtRty5t`L}bPqkx+4o2JT zHA4EYi9E8F60aWjuzA5M0l$^NC?d;RV7^rXkI5TolW=nKCx7tp@D%|V115Y{J?F@D z$7_=!)Ao2|$QVQ#5i8(94x?SGDL+tYPJ{m^L>mL!m^expG`a@Ag&e?Q__g+&SbMttMPy~iz{D|&RgvPEp$p5JvM{bTEg|`C5^vvmfPSaO8 zFfiI*vPd|XXblvDIM~@slm7l!oA0AHD}S_J6Z$lc-%!*Zd}oNM zv&b-}okDF~c(XyjAQEFULCvc1B@?HGz5CbTpy1y}+s6K%r`#uYF2?8Y*YLb65qXX$ zHPD*yJWPN+j$-;JMm1Pyg3v*;l27f0hlND4mcWCeS{hm?)(LReRJ+uZ^~4%-2MUo% zWb*7&)mPoUE)nI}xvxnBT%dhUzT%t9_;Ede77-VF2+#KfAhKFoesv z7Vun#RS~1)&GC4iLD0(sO+cmSd~%W;Lu+5xRw=XG)er66nAppzE%IOf3=(-2?ouGj zkZxalrl4^!Ji;n2$F{0FR8!~5(2c)G#+607-~{>Ca^stum-G(_!jKZp&yz|n*ZKVs zPoJhM28V?up3shwUk4nbD_h#c#Kg-9<1!y~ca)1_QkEXeWSN>yxz*rzQtOdAOW`UU?1i>88E#u{?i1hT&H4(;F!L z>2vZh!~oE|jB*tNSZV>8MnV5c*$%-vF)>U%Lq7OT$@u{H;zM6RPxpRs#m~dz(J#0e znAqgv1?U@aEpU&d-~6?~vk){?>Q{i+g2L*qC*~3J_&=ho)2uYcAdn{oMH1rxIv@*2 zWXhgL(|;et7M7^Lueq=N&VMdeQ=ji|^~s9eQQLWVKAP%4ENTPhllLeG+!wYQW?5!LiH0OVZY~gm5VOaX#pm1mHUVc z+nt7(M4iCkL7F_rhO0%FRn=1r#7TWEtpDxeItmDTUXWc;D5x1;ZbsB}^6FFtPnJ53 zOYI*K5n<*CaOdC9=;51os05r#GM5Q3!9ylNh&lrdtrG{Hw+M)qnKZtIhFeK-G3KwO zrnxM;PVog*2J-J{=Uo394mnqB3@2W`coBc4Pz=)YG)?J8;(QNw*<+ftUtj*^sV5F4 zf72Jok52EuPfRYgj?*=6@ac`VJMuC6IbvPoPBGje{4=qrHEeqbV0N_U`@RJQ9_!ZZ zJDASX?Q@Z;g;NG_CEFQP$C%^L5fqwsjiU1A9MzlaG~?Q}$1#GW5I>!G?bJv{0lkcP zr{6z*JYx{O2K*7>okBq?nHcZ4Xjq6|i~l1dU=r>1p2qPi+*AWQzY~b9>SFBx6+eRL zA#4o25hz@|oj8QsO1#)Q+5WvVTRFMi9KJt6eu%PqhA6WNl+iQ^KUBV5mBGqlQan7% zFjJx2M(kL=VufztZ$R)PD4Z+1Ma*d1B_zI?wxYRzj{i_ZxQrnOe!)m4>x0&@mMZ<* zysg>`j$9vZ4NZ22hqLK;x!HB16>O7E_bmW+&bVpc_A;Xg(UTXla0GvIrpEqZs#ebp}BT=H*l{ z)58hrRk&a$q;T?h9D?6=M>$V&(1Q1Fpb!-nz)Zm+%*XGbg{5@^;6FCC(-QqKPZWZo zz^r@1No8dPGLs&~@n>s!75@14-}|&!NIv&cm`PL`#`w`F3MnG1%08`QICl!I0d*bg zar9?|7TP^ZW|loY7eub0Z0m0|2Mq85Gf`GwnM`Rj%xr9HG65LojnznsSfSd0IyK&) z(fk0qi$kHxND|Q>5&+UuGe3l}P4e&fn;F@-jCYc_!E@8M&7*8%gZs%^B@jU#BwxP3 z`2|DK6>C@@ndl{JHFArK>oNyLMhYvqe`(O%*o6NLe=nF6Gqw&l)yKy&p=JFoDkAbI zENpgZgI9jOkAT}z;3myd69aLzs8Bi<)Sn%tb3`vCJ)5DI9Kk{<&nt@M%-k;khKbiu zW3a#f^TQj)r`X7Att)Kiw27<26~Rq)oXrLITQC(0T3C-gaT;nbG%giDkHBMvPRA>E zc4np`8~weeoAdlgSz>p~*ROn|LPmMnidn#|sI35QXb!Vu38ABXbvvj9vwQ8v!Z~iv zjJ{ONLQZLLAhA0ajF+|!5yXu+y(VLq8ETJiq6WWFC^=ij@*MvjwKuBrf6v-@>V>6P z&3IHo@bPtgIF@tu=Q5YMp+f;C7-yGZ7~W+YDq^r2z>}&*vhBFgX2{a|q216>LIH9wyf2*FGNgju8%f~QNmQ(5w#0@I! zAifY$rr=e}x<5T^Bg_02WxfG_In&djOTX3iVq? zp^h-!f4Be{2RPn3&Dc`GRS2Ov0v!?f>Xs5s&t3)E@V=A7E;*3V;;nD5+2#F314=&pm zkjG4K2*H(3hVRjy+grh$39bxctf8X-IJ!`YyXfA0{t+iMfS2p8OGrwN(a7bB&RY4u zZ`okZ+E?{R=hL&Z7dTSE_Bw3ac1$9Hf=!0TR<;{f!AIsWdF6|BWmwDHxO#1GY5N0izUVG3FxQksROP zUFB>6gN%pjMWFz#@qp-~g6MDw@?9P=r&#ENCY0E;@>ZH--Vn{`42{$=45QLBe`}>0 zC2wwomA_S6Ug+*k4K2^Xq|~_*cKDUlF>KEkCS2MLNYN6#n`^V3F@h? zISi?Pgj*N*S3;9VWWIE!>kU&68c0(>t~>rv>KB?QzI3&hrxJe=Nid4+%5Jn{oAi^AlaqV#z;7=Lc`oRDt>>Sn;oSl^7OQk< zRNR(aXU^&f>vZFSEK+7f=2V1194}bE`ONM4{ssXgvkG{DTnyEQ={u_#Zek~zC5p&{ zXH6SKtI8rk(7-T^o&t}!u0PY1N1#|C;pPnX_wVWa*3wcrdZ+5=xV=3=G4F}a z%?!S8F^I*K+aQYW`3U1S>q+KQ&RkA^=pcDpO^Mgb+yg5!YmS2^AD5RrnnuU*I;&P{ zE4rOK=SsXPK+GfX1%3J8QY=^OUKF=p?zpp+`yi9fal(M4VW#%*PU*i7EBXIa0}PLp z-~pXQVi2$Cg%DL^-8;M9hy5|`h@oY;ppp6`;AwDpe*#qwsKlU+ z%-ku@@Ij{gV*E^Xh%ZarnXQyk=X&sF68q?itPnPsIr^juXY%495e`5@hqQ-z8 zUOClpYN+J_5CeJ&BFV*(gG~wQ3jVbqN_QXR#9D|S4Szcd>s|k?t+>F$AI(7b!~ho% zItrLd%&e@YB1XU&AT8!*~-)pNnrtZES5ng36Cu z;8|!=v@&1>Orwz+$=~rkG3{|xDqvrBKbr2@G|4a8)!Tcq?$I<-F`-8PPro4WXM{>( z0*MO$c5!WItcyFnVYYbGNIM32!01RGRMl`GD844p(8!K9IIwc{>eXIl9N)ix2RAyn za~6FJ19(T2+W^bJUE8HUBjq&Bq?gQ2`GMB<%POVaLPAQ?!k11ZsJ+xEBGfpTwZBs4 z<>bWRFWwyiTW35Z@#lWD5j;HqZ6`;U|0itz_e=lNc>M3b^MC6X`XmWplnE=-C9tpzi;E?O$7#9L(k-0PMX+RP*KR5)efSHBmTn6x& zNvJgwn==r-XUn9)@xwmiMUYUUbz#XWN&l%!2K=>MH_6?&VGHrV^ zj2aG#*cy?`V4SRB7mU}r(OJ3Sm;RiwaKzmf%@Vk~U%h4m? zt&GS~UB5kwekJ2k z08`Bwc=r6TMn0PX6aGku;(VGjAaImJH{{!R^W-AKtPsDzfkSdc*yE269)WZ;nyK7!3w44b+e#- zZI_mAvqBZq6b%6uz7?s@617uPbauPlhU6%yeKmkAS)2{l0RU2}_)dcL!;l@D(E=+n zf7b#_+s?;Fehbi)sJJufigTF5JXd)xn=`q9EjebG!`E3!01FKm^20NWL63EzUgGfK zADFG?%q}>Blf=0BK)ID3_$+|!rK~rb;Vr_hAivH}dTSAvnFPq5iI=VcBT!12`tzq; zBsn-ZxMBhyi6)X97Z-;=o(`@NN&b2NS)q{bOTd}66B+n;9}t<-rH(0%OiWNg^k~jN zi!GW{03s2SY>1Mj!_NVYcojN43(@dK2vE9aF?)D^!k-79PFy@8R zvPP=kpo^Bcq~yiWx7U7sPMoONlbo8G+J8~!dVOwAj#+5qp9h*(UQ`eKR?b|Q&n=L_ z;ZIZ4PcyBMnpv#sxBK2YbrHe6tb)0J&om>;0r}RdjsysV-$6#Ucz?6Q=pLZhfE-5*?_EZMf zMrQ!k;dMQ(^SH6Jlo#(k_OtHnLc*kEI=~&>SWU?|!IMdo3zzsg{Tos(NlxM6p@|Nv z|J%I%x10M9aPa@m7p(qgK=NPA_NLPabW%&Pny(eI5~jK zVj)rmJ}W3uD=8=wH4yxJ;9Ko z5D7`Z3`7V-T~0woc^4tp%rXk<(3R-Oc#F14J9)r!DZm6p$<-S-f-4E~0#za9{l9W_ z-g*qxNiCi!4YkcZ^kr#n?q$zl2g;}QDx~7PO7>L~g0E)CV7f)NUga17DEs>DLR*}t zw|5cPse&~0%Ukj7d5a*+A3=6(x}J=y1`@*>TcXbM@bs*x7XcD}7d?ZS4E-@ukvqaF z#BSNq$O3d&rf=6nO_zA-#^6`(&Lda?^FPE91ZR!vi)cVZjDXYd48k8zqpK5ubXYCG zRJ(ZY; zdwO__z!kI}aXgHUm|6f^1Q9Fz1NPrd;6Wq=p&J{Ol4+{W2Mo&-*Os3?*r303I)X_H?UEuwf`1)zG+KOkYb2$8|C)DmE|8nlwQ$GIZ%jw zfhxCbhH$C?i?EkG6*2P~JWgPIGKFJ**@Cerv7iaYHw+z^D}sy)#l)jZJfhKjFqC1B z@+|B+DvC5~Juul|L&j5dDp**k9Tdb>NU~2Vfo>+wV8mq7Rqk(#olb3|wevWE)DUUI zLebL(`8U~MZKpba#u>mj#dK2jb7~7>Hk%o6Y-Zeh`MEWef~Cb<&8gK54Q%ih^fw{U z&$vuwluV(MF&Gil(6#J>Dnpf7AOH|Qd*RyfL&}p%Nydc*&7EcmXmv?yv~@%U#itrA z7xe4PEK@(RwaAo-5F;p_^<>xAftx9_-g^s}kePfTu0>Fl~>oMRAaJ|JEJlsQC$>S-MYjhN^?s3L>Y z{X3IPzK`$Py&F-Cg?Jdkx&VR=)|T*as3GfsPBd@l#0C|x6Vo(P!G0`JNsFBwg9lCJ z%ETP!qnHCJ?{NEZW;;*A29Ks_EPEQgPC#^4a`>M79g(>`5z^P95Mq;TQiIptf@#?< zwCy&hM-eZ*4gg_hUw2Z%vQd!ZAa)$ZNbKh2^};Y4>?Y)UkSA5$F?aAl0kj&hHI)O^ zAR8($&8~D@RY7Yy1$p_+PokjH#-+Y^!08oeMPDHnjocDI8bo_|FEFDVXijN@49HXm z)wRzkDxa5EuU=)MxFsbeVV3YST^PTHmQ+EAzdtu+~YAZT7p0QR`t0i;q|GYGIPfkvTF@m7tl>n_I zO)CY&LNh4^g)%Fdf^00e3hhNn&T4{EQ!_B3!9tVE_)Gf@ND(fOKgbs;^rHJUb#(V* z!_8K;mzhKt(owc?BLc|R6f~0YJ(kn@IxwGI(5Q#0>nT-v&>hTlQ2p6TZ1=I=-ML47Yo1%zFO4fuQ+7RWs=oqwh&*?xuI*{&=hXf=s23_?Z$x0OQHJaxIb%Q6tfBgou%+$)KREUwmv($bZ%6+ySN3#u72>HBNg z?q+2jLTAC(^h8ist+B49rKL~!Dbq3lQXdYrJKY25f}w~B{KVrm5?Fu+lGPpOQG4gy z+yeTo4`#0v3W$Ehr!PkGUgH;mojc{uY|4QJGVmP!(Qo;;4x!NPe)FR|1aIsh{GQYM z%#?y3;MFuZW#|dvn9|=`;~YWV^(wP$o?C_Uk#ky zn7l;BJ1=Cq3Ys|-gn-%hP3qlZd%1k*qF~>wXac=TRn0>4#VAr@Ps3ae+_{H{PCpQ= zG!I;-oJA{3#9N?~fJCiPIWay?%72RK!x}qK#HiE24B8sNpkfA2lmn!Z)0TMzA{e0@ORrOCH~ zdqj+3`t^6=ra zX#POA+(=Fdt_u$unX-fzpr-o~W827l_Unj2z<7UQ)K* zZg*z9Epgo znqjU=ca*RndtHFN^4C{K$+Yts!cajc_gX?9#@+B(2_SEnicf7ChJ3pDrVrcLHHQE7y6@wp8~dhXo~kEUn$LIxVMs5tu*Z!&RCfRC@-$~AUy-=Uo@78Z#m zEe&8WQVR${+60cFIkp8r)KpY^0AmQANs`%F@Y52MLa%JRP&Hr9&6^YTN^$aqwz0Ig zx63FLwhIBl;i-flz}sx)X7ILzq=&H%t~_1Z%(|_<=1wAd9>p-FW2J7;52&P#6u8cUrd*#&_9R|G21nVRJEi(`na_@|g+CuPsr! zgK%-r;jw?R$Ruvj(lcHE;2i8Ko7fC=0So86Q8WPk=YUJjdz>^n(}&sdOMaUPh+9|q zowF{E%<*7y^bzM@Qh-T|YM5-Th?u1Uw;wJG3TnKZw5%UAa?)+7k1r?RN6^ zhWD(1s-wz%k8`*Wbl3E5o%*FDh~h>UP?%{-Zm$X1ze9WS7|<<3Go8B*`*vc*A-}F- z@JkX3YTKR}{KXv*utTIoPa)H$_0MEU2{V4sVaIS_4kk|*Ly{BooZB=CaSma9TZ9th z4G<|p?0zVJzJK^Th(29&gnd`%eXX`8@vX;%yg1DwBOJ;29I_(iHn=1Fn_tL!7(~Ur z!o#H8MrC9Iyc~9q#513WoM?24Y5IE+uo-dJku*y{HMv7B;Kh3J_p6whRogDL7vyj8 zoW)OH8XLth%nO`9n%Vb=^u{ne^~O|VYt>eSLE7R)e7jN{+FeCpC~lu~LchcRu__1S zsp!;@l)e8v5}$gN<6_$5G&htrdME_tL9{gJ&tBQ6Qivp=!b#p|(;a+7I?8Z+q4fdz zdj+VPliK)jy&qc;E{VVuQy_b^_H;bEGT8T+eg(4EWt|VWw`38sPp@dd&;oRkWTO*r z5qvJ*z*OTPZE=XKK|;ksK%>#yw;UZS>Nq9y3qX?UGH~tMHDvcyoi?`57s(ZtIrxNh#Uc>>neaWhv8mC3la*qoO=$kG+~uU zFN~{G-UE;$HgnlIIo8bxW*?Ls?~W=ZY< zOOLncR3IOBeJ-}o2#LNc1VWO>>RJj1X|46@so@__DY&YzCu=2rmFdZC12Id--uOb+ zv8C9wg)G5# zkwI4=3KGqI#Mmy2dx{s4mEsL@(&k@pI&$;c!+~y~NeV_VLtjoQ*?O4ZDbZOag^Oo& zv7fo4qeG+U8YV`pCTNM}u(zPAxQviIzrV|>aEet7y$d#12S{0RYHBP%2tT30oS!OO zqT(~|Gc9Mr$cf;RUM*y+gEWTc?x>xY;WZcGY+cG#5z!XI zriSLqg>pD9`+h{yZqNK97?b%y?MZo$FV^9w96+_LFtJ(0)FUsvudmMoQEJp{Cq8=6 zqJ~7zru8c#^{=$$@h^Ei^z+mH(hIO0RMBH8!SE?u(IC79HzI94$T1jIr!fi`=4Nzc zeFpnjW0lG~+iow5Lw+dVX(G0th44Fy=(hQPo&lQ`u*sV3cDK`!0V|=JiA-1@(St42 zXccJPs2h@`3#Osd3ibQ>X&Na}Tc`+DY5)rTD=}&ko%MYci}H2!M#@j8cgRuxHw011 zCx$&>T86A0P>CtC*VsNx@a?zfgJ)BooqLH(5PhiWNM>B&lHJx-@zqB#`(;JB+JSMG ze9>Tg{;j4#mFGB*9Y|6gxVg5QT*N@=fRp-ZgWPK;G1uwxZFaF7$V5OB_c6zta9l=8 zA<3OCXLLk&7QEaGP?Rc-?ym9)_sBZv@)Kf@#OOqP{SOzwWj@G*=Hq}gtoG@|H*`o zi(@b0m>h)mk}5r0FC=!Q^=rq1$(0lH5z|c@JeQO;0rtdjciP`5NW1Bh3k=9h`a%yR zihPSD4(dAUsd(BZAKg}qJpI`jM&h@e^;-SmWwXY5@N&STUuA4;jNf=Qg*XC%6pQmu z@Q}7sdFt{@>V&v~c7Z<_rG*DNHoG#Cz%Qcn_qt@CHh@6@dl@7jZ=FPX@oEV>m5~$t z&@G;OQGf5JXk)TPWWPC5gzb5;5QPV!-!SUK4Fm%@rJzC-_w!hCY&(P6E{HzqskoiI zs{Hj8D_0Ujb6ZCoY?RC^DVTDUt47_adOm31atS5-rgIBf?JmUTt7{Y=!q@%fpBdo9!%cpSW zMXYdryk3K9%;$3J*8}j`75uG%0OB8MfvHdZiegA}E)WA712~MZ^A&ZLPweEtE5&Sw?<00iT^?}(Jz=zPQm?zu zdt6=*GE}_0=G7~W6(TXw{;{)ZiHz#qNK?m1|{d8@Py-y7)MWv;;q3_v-A3U!0y9G2rvRvvy z@1ZXHxmsc+4}cRT?EAL1ZK$HOw=xgnh!gfKvOVG75MY`VsmQyw*VdCY8z=zWvGf>C zGI6g^mRVrMv6KQHWX&+iU%A6|eqt;LX%gb=Of7s7$m_h~s%(?+bg&0WTXA=Wv(7V>4Z}oatg~Lw8ZVEsE`(5T85D|U= zp&@;?4LpBwuiN7N+;;W82f9r#v_L^!7SIvzqGka%-kTIx2o%%kqkLykG$OvQ{wp3K z1L!@PiInm|?Ep^oVmw~PEr(Tvo4_Fhx*Sjma!c^>=I{WRL!quna7PB_1fU6Onn$n; z2c*5lxWJ0Bl90=t1GLo5r}B(Kc?KAraNyp)y#=@1g$`!Dlq9msoI^hzS zEyIYC9=`&5F8OT-j$`8dVQ=C5U4-lB=x(Ob8KRP37hpqtzmPgOkYwS-auoF#Gn!~t zYwRP#Heo8}%!ILxg$#7q1A7M#h{)dYeUti$)EqR_t%VDdoLjbTCE{X^Ml^n?<@gll zDjz$)hV%{I(C4w|%WH27Ad+*yz`$ZX3OFTAQ~NYc25#r1cgJp4a!62x3*b1a;OUJI ze{YH3@nZO%3{Y1*aWb!M=2{)}<-<2AJK3y!6z2*^1cE68Xc-8-D&ulXW7qds1WB?G zhRlKSk%Ur|QQ`sACq#yGU}qDzetdo(P(sAxDxd}K4(6x4c=6&ani=AuiXw6a5-m<3 zDaYk!_QI7N=lMw``bib1KYF*;C|DYgu=!2g_-y#3B zC3&Ih^|+I6j_odZ{l4&MNl@Pn<CRu1?HCJ@4KHU= zgh5>_54^s=_wzcq&AuxEauq|kaJ8d&H8vWkY^z7PO3W!X?LX%h zvHK!KQb^*Zq#N8whW;j~T1hdBNy?~XRaosXSa(0r*FZZ~Se1q7Nr*U5{knnmBsF*E zSSe|~QHBa^-U)f(!t2338u5>!RU1JFge``KFqj(EFFMMUGo5q zEI-B}&@=pvt}LmsOaIaio1yzh{2-XJr78>fq&LIza6X$Vt2r*3$Iq|o*KV$ZXlrAF>p05GEOw_6|*||APdT*`xv9(bEW?tK2Ay|wy#is+nDRiHB!vCOsW2U2{ zTXq{3@^@8Rp1W#}J0BUMRJ_zzFd`Rl{M=oAF{jZZjKB9}^~y(EtXbK_ec` zL^|3swDR%vquR-OyC@z6%SROUK#y8klk5J} z8ftktgp2zSctOf`uMcdnKjY)9$QA4qVlMeA^!@6 zl_chtmX)oAv@>8#&pcC)2v&(QENLJIWX$kJ;KQtF50R39l|V%qq*Sx337gW1cZO=J(UFD$T9_R<(B}}40O4(f4-k2v zgjgZ*`UI|i*P9_g;pBq@cG*agb8yIR%>stV4zyi_wgV#xV!ePL26Z=ac&8MDTjJ9% zarXV~EzTEo>q$*_w8(ut(Fta`eknecTmxR0eEd60wmH z1%)`2rrQ_jg#X4dr=qFwH3Gq#2-(q$n3@U;wI# z#|v04ZQ{rn6j*C0@=c?J6f^oV@8V(Q(8UoN7DEL%(imrEXY~$zdhk=q%srLxh+~O_ zH%uE3BmKxH1>kFS6IT6Z_$LJjW9bv3hm>`%8@rDM>SDjPkiJ=1c${FC5%A?K2g&hO zv*j2p@>ng-&#-S8A1Mrpvw{@cadPI*x6NkY!F_COY&0J&Tw0tej7BW;Vy>M0-M$xx zrf^=3ISaTC5BL}zh*Y-UaekCaVXWm**JUruKyo`YQUZ7(!dM^mO5$6nnEfZ`zV0sB z%1bk-K-h6$J0MNOiz7BbV05tlvtJK-XIj%j`NY)JMxs`k56R5T)O@91=#pQzu^u3p z9Cl#&Y*qUEFP{)RtlmVvrAzw6mu z(M>lV<4F;7?0={YLOW|&lIzl<{JP{kS`({b=OyGi+wY_z0HwgEBT~Zt6om=d&n;0aIdS^KrRs|}FoGu}RsuR8f(J!0BcQR9qlx0zivNvjsXPa#nN?suoo`yx z!B1u2<$#w$b{LgxVTQ;N*qt5MphOIa)@)L=qIAVyOqF`FTTcpn$#lIS4` zwktS7t$pHJ$lc-R&H$q!O^pKyx(z0s8t4kLU7G95f@iqpPT zPlPz8)vj|(!=&9u|ed*u4b?ejQT1Ly7 z;JmZdIcC)^)!x~ST?rr|a+Qqqqgtl?Ko)R}Onpvf=>StVfinfO?j23qNJl7x(|_ zEPAXEC%7CNF;9`E*~GoK1%Rr`%TsJKdIe57J}tm_Fy*TJGxhNi_iOEvnFM zGz_7$S23^_SA~37cM5oNQczrb+y)Au8lHL>BD7c;f|_I|0XK814oVlzfkw;@8l-NG z_dUPK$Y@MDXI1U3hSKiz48%AivxlO$ zNzf(e$v!{SSY)FBULK~IpZk_U4!Y;S=5^rXJ=2MT`^H>PAE;vlFFJ;B#Af5oCU7C` zShRN&0MPV_%-Hpf81wGGY1D+wGqT0%It?3k2y~!AWQsr@(9UoZC zV0Z1QKF;Ft8&+GlY+)UkDCDyT(76IH1XCe)oV5qA1tjkKh=gRLy8OaQ!Q`ZuQ5=mC zdmTT7*;R%ugl)7*u27EyTic7s&d}MU2Q&o&y@n?lg?$^H!pYi(?Rt!)~=DyE=1|#SL;LXQVeo< z+E*=Ku4B-IN}lHYNYijaTtZ?`M}NV2B^!Ht&1xK;ckEpBMgBSyGO3KN53m_1A&B(( zd|-fhjY`&TDe`;^*0oTZF>yCE(^Cstw138FK+P(=R`$(+>q^n(196zidJXNHIrEP2RtJZk0_*|~E$vMNzuz5(3EDr`VTikkD~itzj;T*r+`n3f_Yc;J@N z?6I&(enjy3T!-d)rLC_pma!VA8o}x#h6~e#c5rWqF)LUt7|4ah+!0PwFW4nohw>z3 zP{VRh@=N>Iyvmjj@6_N|f{Tnd(mPau%fZ*Fs9QvN#!5B}k**1|;v!%=h{kMNGt@ ztu(Cv*A&BDtoO9hoAK7P3xz#Y14};v3M;=_ao>ZepBqh$x|7D>%K@p-W*q3h+}n#* z(3{u*`^5@R7F;@6+^#xMd<2d1Hi49-nO{#l!6~8l*86bDY~yksXC~q8007Eh_)W>jCpJJ{y44eJU8j{ChIl=Gx9{Eu&jJbodrlwWU&c}*)uCTun!T$ zl^Lqp!|?F%{(Y}>7Xr>d6tjQrj{8HkD>03m2YN*)D};|jMiyume%#w2U9NRx%wmp^ z)?i~LxU?<}SHJ60_5M!@`dPvcw;l1Sm7Zh79a2DN?|a2wKfMs@UR7|T$dWAb#8K$i zL5+n{w<|j(h#3BY>4r9BUx|z}76>_ZO1}oTNpYKgk?LA|kht!m!8}XaKcFj^#!4VQ zvEb>6r+B~g3(&PK=wgGti{+%HQE}#E_Oj3zPmY6+ZdWm9jY=3B-b2ZDhAgH*5u~Yb z!Wm?6(rj%%a%3y`T*QkNB?tq>OZ7aOMK=@{SO#>|<{_LQ=@Gcg(B7su@JV82F*a5C z4zKSYodveh%y-KdEuioN!$Wy%N3caAhP&AwL-b^a*5LrMge?7IH711rntMO80LUW@Y2-Oa+N5T0z5pX+2joij8rko0X= z(VvG|fb1OryBG<}I8A@*=wyQlF?dL!jP-@L&RJXg5!0O%vju0;bvMX7NYqH+iBbb+ zLsZgd4!?Sr%H-@E7lnvk8bnY$ooh$!P3!x`vvB^|++`KSA8IbXUBWhfsPI4sJ~pwb zFAi(N9?yWbEASDh#>?4j$1$enNx`75U)*MD*f0RFUz1Xj)O#{I>Z`cj;#HpCCGXnyva7ECBJMET(;1l=*FonSI&5WAi>I}jRrsTCZ)c+3 z-OR?uxySRY=ejp{__WR)xB4n+aqi?7^Verjs|e~at@XGcEx&?Um38@Xg%ux`@i@D< zPUnxkvkSkq_Ze@LbJWGi-r<_&P%Q9Bzj3j~u{PTV03h$q9XpP{vJ$@hB+lhdkrNpH zJKn);>&@6Q1;e`Qt2c?>k6PPwuw4Cul7}>$?mUqw;Kp95RNh5-@9Zx6C0RBPHsh`RuY*7gFKW-CJf1Fk53}Foy4A; z9dkIrwDpPQo1kgrs%vbF^?9@mBN}g!7o*d*a$H`#bhloSJ-2F}(&%@K4FpcP>|_MA zwP*J!wR8mY1UW7!?o_9ZfW?jJMjcaB^!f5O9*g4g8sS1(f8Tbn``z78rVQ+-KAOaYm9qJ+y(Y^1xvx=WG36P9_cld5JfGw|T%JECr8^z>hs4 zv>RKVEcCm%XCbh-;L-8Nc=s&8?t7?FaW}CQhnPD9V>SWyVUBeVh{y?p;Eb4K~@n0VZu&81$d>S zq-Gu7>)2mgRYg`{LhQH?vlhyGGA75s@BEi|)oYs6$hWjxO9tEwKVVPD5RYd=x#2k0@*j3nkBGVKV^6 zd*FMa{d(l@{~<$jpESmw=B-$4qImO+gP5lP*_8pg>8J6@A$_c{uRs5@LEw%ZS(Eq( zOWUxuMiBGjo?$Hd*bTo}l1Z>XqweWU?K<5~D)ZHb{RX8$QVV(;)4Zgb(11l?$uLeZ zcAXXh)~ExUa~_-&d!u0lLYQ}Mz&*#}OtODNk!6rJ(AP(r{7rCN06UG4CmEc}y6%tu+fe9vgZm@Md2h-CvzIPC!IsgEW8lI>t3=DkWLxt6iYk`^E z2J~HMSON%Vn=ySsmls|W*M1R^a|K5cMa}?d-NB13h37w~UsRTFY-@{@0!c-25(UN! zl>HiKU`tF^MmvdoVLO|$qnEZlNFyq;#YqhO@pF)*=@Di%9fRmG>vOC%l+JR1FP%TU!k@w6tL6+ZAwN9NwW0*n$ib^qP|!uQq(gdpYjnA`PZNL9X~h z;a%L*7))@+9iTW;6LLV{D3QI%@GLde50ikpPGXAMKaBN1AOn2PgAiz+v<4grz9^7k zKBJ=so;KV}PfQe~r;AqKn*PJRP1@;%AFA&&MYnLzv`pINu<)xtyb)Ad;@#UXNh>RR zunnV0qeK_zGT%c3*Ea$T4lBFPEOD-x^6PW`3|il*%L4$){@}uUI+7UXVv6M~ihaJ& zSnrUQj@$+s`Z{0~&uY^E03FzirIo;HmjCe|(sl@5#05p0_Ph+*^4Qqyev7vY3RynCxLu#BmVOHA}yt-lYU+r7r9QS|R(MLRn>C(|<4ZS;WOivcX{GD0cV zZUXF(B?>G0R{yi+8K5>4Wd1s5z=y>@j&SWg!vQI%G_hWk!?q=OEJyriT(P}&xS{D` zf4@aXf4^u&1noau0CKxdo;g#q@qbRlsmK2enxFi}mQ>-~AfF@UQ2tJx*K+D6LTZHe zB>l2wefG;-jW3;ahy#n*r$W-cKTvi`GvKL6Im0#~;yEjS9hpSUjCxO@a`ZfVY200f z%2SUWSYCWU@U{5U2hn+*6r9OqzlZuEy3EQ2U7U(X>T_q@Q)#wNkvMWwqb+2PN$Em?936&LYH!vyOrIs&J-`3=!1 z&Gw0jQIV*LHy^wSxWI6ET>ieoPY7rjOhq~iS1rc)tn%CI0mGslC~85pdk?MFb7bEe zUd!;0?~`trj=zwXFuSn6jNE3V6Oi1!5tv;@-t1B?Y`p(!r#LPixl!di^HXTuA7Wye z4py>+WSyKJi%q0e{etoR&C516Z>l7aM&hj;9mW4yLydIs#Sysoo<0^Ea4!5YP3a~( zn8lO?`1wuxnZz2NG~B@C>;SfvQDcXhQ)2S+BKWaC(mPC4TT}Do5ZvJrSIROn4=TEg z9XJp&=_yVBQ<{m_UR_Hoh=WO2OFS$r?3#f`n;jlNsLms(2EH(=Vf7h*93K9cYx?+O zjvs!fXL)%B9imv|6C}Ya_dGUMJ~i3%mM=CI_l^j*-Vj@9tw`pTf1lWhS@p)G#6*kx zea9oa@V5TsgQ(-f{YjM--#y}+#pTOF>03->xpXTKey^xsJjSv<3%fsdH8_m`9#)L> z^HWX^+3R&zpzZ;JR+Viwi!<`hqly+x6u*d|hpsHgvcXeN;Bvw9r2f;Vv!ei~OC6;I zPK|S06!2{rpO~<$c2W&B4(>pv`u8*84}N?9zQ_Omcl@DXyF--7wg^P6>g9Qw$fF3= z?fccRv}y%1^!>h!)!a)J1q-QdO|EQiOjyrX(S32W@GGy;jWHEgUlGi`wp*JDWT~wwkfD+(E zYbjjL-fk^>ywKUyw*z!mOBe!z#Er*B&jQRu2>&*AKjrp;8zy1 z91mOnu#2f2&u3|3;g4~C>e31)-{&hG`fnQDSPFKcb)Cd-pAi9?VM5?^G}F3mLISJR zI|`j<9#`mtwR>@jAN%ZH*hb@jOu$j6d8u^>gduD0%KRQJZD#M^^}JYN9ioUV1g*d9 zF_soFGgIwYyUK4Eobu zhJ?s4m^0426z51v02YKV9Fvv3tFs8?gwPC-Do3AcRsxAGh0PSn6VPD&1V<6<(WL$K zQBp9Pmj(O|o9y+#Ar&!QoSB(9XA8F1M{p3%o;^!}K|N`*QTqhiB&7T%HkxS6k3l^1 z458h+U}hzfY%pK=lPC9qzJ2`qbrVt$5h;LZxU)^$uqqV!@~@`r#9Sx@>_ot3LTg-FVbz+= zjBmM;Tdw1}6(CarkU$nVhTk*WwtG!tVj^)>D1Gt64hn4whQCk)72$cHYQ958yI7e5 z-^Ey4?9n1k4$QRQ*mj@N(bMCRkl2jbj=YOY!Phd?%k517=Lw|~Hvea#`rCK#pgeXj zpm`cuT(|`QBXGtcBP&Y*t%;M9(^>3yh28>krxmzRWf($Xvho*&Bd#PJekBT5rx46CI&r7STSgm}n3QA#-8xwA1nkYI!e=|Gt-TRP zl(>(hg~Dd;)myi2CExy=-|n3|32OlQa1lGu^rX<+D%T>5Zfa;~2svyM{bjKow%&k$ zWak(uV04gO)}%~|9TL>OnzPrjg_gM?`{72%0W70t2Khul^E#pxcB%z5??ua-?J&Z# zW$RX=uG#_#0D?8_b(T}GiZSe)0sVWRJ{~CG&J2swQ?Pg7uuaEuIAMDu#==(UEYx`@ za7|N$`1wEJGm=3ufSXTaaIHUV-_Ht3*~!cKDAXPToB`$b&hT~gD-3Q-WXB(1BL%$b z{=ov5rG*>h;bLjZwK&4HgwXvxx&)AUsGYUsQxQZOmAAx=Va6XZg>LxiU=ln)q4l-7 zxk7Bi{gDLme^3&jjRSemv(Xyn>DYQra5Nl&zSf-d)?5$EoY6kPJ8j>fjRe=g4e|ag z-1b>yhO=vqn-CTe-dA~L<-I$1=t$uV7P)7&H)8n?%y@vyyhlO$2@mPp1yvZsleIti z;!!Gf1q#oV0EJ2)sK2)B!*VT{;@f>T#Dy)vKUP&yp`c(Oo7CE!r=Etm%mqH&FDhCD z#QF~aGSMkG%mwTo!8X7uNTINXDA>}fV(d)Ui2Zq>f`puO+wWZr=x%Ces~9&OZQl=m zEfpf(YRnRk0OMc(+g55_1}Tj zY0aTVz}Shc;Td~CkYS}$EDzu9S`A%fbRo6#!3y}opt_8Dl^Pv=mtTP$54=i>UKb*^ zLu9^na|;{W3hYOly#)$q1Pwc_+#ftp@GUb00WkDD#))J{GG!lHvw0Aq4*W)WjAuoE zTY0ez6y4{A@I~+g#wv32^rx(kZ>r_U0`7&)bY$%d!G@2l->@O>JU43dg!6y{zJi%r zY>Ul5AIs6bM=WMBH+=X=j$7my_yAs*{yg1QR$6KswkqP!E~`XuFE8*q9?G>;qU1e? zRsajT&(z*`cV|HvkOuCId`(@QKez)Cc}_EG7n~8mcB7W@iFmK|4XYus1t|j0=`l!j zkHD~d3@nvkR2@S@N?-~9#jjMgw0QAWb|7q$z7b4{+m!7nWp=nRsbOC$xq=9X9%y4Y z(5J(Io)>>}ImHq8uKq2GmjEOLcYCU zP?5LL4kME(AF01UGe5Lgqr>1 z1&Ab`7&*ulicvBEt)b1}MU%o3aOCQb+g~^JN^Iy36-8sSlTtj}f=yZe!P*;bgo2Z5 zSo)Ij(ADzAU^sNn%1V*YD0IW5w&B%lcS>qepiX-Eq;c?*~BLT6P=8g}2G8!#wXE zgjfEEzWZzqt|q+X;bfNctbjjT;?UiL})dk^=FI6Bk%dCutK1enbR zzQktEJV5a^(q_^8hYkhTA6Z-abo=GjZ2xp+-OIaF^LMW6?(U9orgafM+Q-0f)R0vd zua5I42{4rLW4BS#6OnFDbzUEAw(lWEuP2`5yDa2>w4p)j%9fi74gbDw>=bMGW;cCK zjtjb-9Z25i0wkoQA}HH&`(N7|G5w{KI0QYT{J#j-x%8Vjye_ZMOyc2d2 zw6y$#3ID{zE=oDjsMXwV$ZQX6;70MU5Hyg5r0lgfrPr=LG^(n zActtIN`cB<8KB#)$&1=;GO~F0c*ww&b_Ut~`n+p@uPz|Njvqgc;=@@C#rRY@SF~t3 zE;8D3?DZOdk|8q>uB22oa~%V5T%EC=bu)0RtiZmVav0-y78c52JMURjq-AB9$EQx8K8e>x_VvO` zmn_(-iahe}%x_E39E-t;dF2DjM>u6WW;^}~8}Q@KklzMGqD^sEQ^r&x#RGzZEKCnUd zk;5K$WIoy98=rwhdLXZj?G9m*1-`J8-Ac>I`Bk~3{}NxP3=I_y`qw4CxtlVyf)M3q z+yr8skGg_H%JF$XAiz)nlEsN+%$h3@%$55Yw9TKctOD0NSi~u-1eXam= zM9QbjrguU?XkATih}9Gt(*62XAXwb-_FkL*)D^ZYz^C{3P)P59FOd(Xg-z#lC}Bux ziPd{Cr3oRIYoFHJQRS~rn z6?Xvj6Ji8t%pk9Fpx+=QT~zzbTec`Fy;!q$Z9+v0U}+mvyQHcID?}C-mtX0!;dd-# z7`i&#DvnhjD*qgzkfkx_Q+U@Pha(PeLeEiz81ouNzNL)EBOS}_Yk&k}5daI|<_Flq zNEF9|gI2%*OwiPy<8?H!XKu31=@-0ovl4r)2s0V2A!{Q&fywOc#R%2Y&`@d45;A7Y z@ZQSRZ!w8FyK2=c;<}C*iq*DL0ZPisacOr)eqeIg}~FxFk2;RIrm{ntoKCY zKm-jsM_?E5<$(IOt)0Nm5v)2ui-&{$)+4_GJEKi`GZi5%by)yl_Tal#!d!I^|#xQ8&BfG>EAX$y)h~d~VuM(Y4f+OC2(Cn4Ww{K&) z*De=c)wLum$*?%bfV%(0$+y@UwKL4V(i>IVK6`}4y55(GiL?+KOk_pVJ}#ADnJYnl zJnhZR&7VQ|KRyljK@*z4nb%C}K4aFiAQzC7t-D_f%lR+|2+XB@2Vs*W79`8@iiSa` zAEA4ag%P4q&~BZl>>;s`eXvk=ii?Ma8SCoks5pWP7@eBBSE~jkOo(PLNVLrA>goxS z+|iO|%V@tq2nn6~Xm2keCidiWCw@)<+VKFCnvZZ3>gHHN2F)&9c#I*4sC`r88IIt& z$8pJCAxh2`dFA?r`_M$3z#S+D$@S&Kw#TQMFE@sFTTz@ zuIIk*`#*bRBvNKZN<%3j*-?pvQe+g-kXedC=|Bicw9TZDLaCG^rL<)U6 z`EefSbzb-NxUc(<>v3Mk;ZVQd_xl;|_iMdZf_beJUk4-~v)OS{q)!TrAfV?xJL;>G z<1%2HT6+VW2A>$Er8QX0i@Tz&HqxrBxOgxqZCq&+blgzngF^sdUhw-ARaN&1$Z(;R zRS(HZP7j$|KfirbWUUP2%sT_nsW^Q2j0lh6caM4e{4}5s16g766zK+)Xx@eq|2UZN zitJmrW-VWuowVel-mKtf6;v;Nx8;CZ=SZX}fVGK5b0NVg{wX7~e;zIjG#bOP4*~r_a6L=2fV3$Fl>7#a50(rPu^MlV!%`{J;plH}hZ2r?ko?DL z6Owy*D%Xy;vr!OEl6!aj6-yVi0(+CUDvn>heEHNmN|LDHI+dB*tgsJHzJ8~u=s>~Z zH23(jCKoq1yOr&t3l1NC(=Bb}bd|3@-}MD2r+ptbFuh-jqVf3WCG@U_mtcCUw=G>e zulm+ZUUnA1h4Dk#-G?e7vO^rsn)KpdfZn{?_7uGN%(KXVfMSQz4mN=@&tb~2bzDyylf4bwX+HKScy{-Y!H z_tiJd4{E>s_08~8h%_CE7`3~-wduzQoTUDM`#?)IbP$g47VK;Cue(7w>gwvAN=cCi zQ!ERsqX|fok)HFw(|PTM)AeQU^Adm4gbT~i$Wf!FO_}0d+U>daTw&GcXo$e~`+LUJNh2=)yu{XNX!yE!s?I3rIEFxX{pnA~3N&v+bXJbC5$wc4ksc5;s6Q1?gs z9%wEKp=_XB-AQ&gVV&(MKaGHy<{}a1!3@Gn1`0-VIt>6&ASFza3m0#tGBVXaDap;R zY4)Gjo921LjnicEmw>PW+GyBYqZu>umBTiP40d5m097QLqbr(>-&U`Rh`Yask%5B8 z7DRw(r#$9Vp11mIWLtHk(*Ymbt=XPse~6)NWzAS$qPZG&@wf#2$UBB1M=C?-k}fN8Z?%?5Fmpz-py1 zJ4W&LP~)#pUL4Lg$L z!c&>kp*M$*m?X(G`7ekpY;SnCVqu%RuTg0wJPWk)qp}<}=L<~2* zG##Yvj#wVLTfPlP$}Z$j0_4MG=$Hkh1xtLTewUus5ld##)Ore=wVO9VUGm_!JzPhz&Ej?z@&d zIqkzdA?AOB(hwP=CeltSK9=VmD<~|~2Tlo1*(Tz-fcQgiHzB`@-%zE`^Vf1tZ|nLa zOCefh2+|TU=BUrU8Y-G;#>VFjr$(ecDQC?Ik%}$%i;2P~oZ4(#6ZJ$!!c{^;!4fXt z^rfxBu#*+nd;6qqG-QhDoD&nKQZ<{G6Ex9Af|eja|JT1RfKyjdTJ4~)u=nb??R&5L z23A(WIVnt96CLndu(PYslMzl9V%*BwoLr}_;!_h*bfxF;FXN=2{SpdRqE>TqH^DRt zSq|x3{$Hn7#;ib-){*|W|HLfQLuy z-J+!iZ~!hi_e4Z3zgx3hVT43DU}|QiaZNg|Ufo9es)nHT&SzLao~(M@wsA9Vfp7Ix zRh_MjP?DYas?0qR<@$leYchaR`P)^><(@{nnVLV2Vx{${-0zi^MsBgt zog;r*%8NF>Xye1A)gfiKgAuvhYnM1@?WT^AfcGXDZ2E!hoOTk_7Bkjf7!Evg5U+#E z#X;$b6WstcSK&cj_3-lGRpl3tPY)x;ri50Zx~eL(-U6&ofFj!JPOYh0XRLJY^}R;A z{$|H!UFsIaMrR=ABLH?ixw~YfrKb>NYRpM#431V*@6d5!C4Xj=kdTm1&5+NxR~en6 zb5gsw?(jmzuiLwArscVtmuH$$K%~|?uu4Zg4M0`#hQs%d^bvIrZ1}8 zKNtoxjOP5B_2T>WYCQ)Y+%&-jabwRw+tZ1lJKmR)5IJzx36Vpvy$!h<_32-HIa4@a?Y70F99-b>stDSk zqePnv@-TCxDQogkff%!Dj5$v7h2^KjV9BkQF;_YcenDy3R>Dlg$pv()+#W*&!o?=G z{WZj2V;_vm{GVu5&%n44b2>R2ITseTy-1M^*G(Snv69_vEI9<%c^Ka3FlS)`axMVg zo?vNr>XT7i?vwA^R|e?91*cr?r>Em(=<93W3vO}@xq56K$uWZN8O=-rR&CMUnW9ZOdd!*O1*ETigO7(~NaY_uk9j2|w z{bmak#MoU2%NZbD8<3!gkTM2ue7FWt&}NF?CdKKSCvea&x3%5DniDct+#0*V`Mg^` zw~*OHPS6;#`C9X^*^NS%qy;VC_x}2I>kdNY)bK$rCnW3usA9bNs*(CtLGkM|e)UEk zLR)_J!a`t6kf;cyt)u@sc(9vrdQm;B0K|Zpc+tP3S&3<%@?@8{Z9MY!PxvlnSt8Qi z1wI``S)8A?KuStV3_=ESwhMjewDnF$OOHiY*ZELaE{BB!?g~A6w1y)AdBBQIF7I2ne()G!f>7-9dWALvYcT5Y%*$hGqpP`ju)~hS zawj@uJbFELNmKC_%UT;eGajJl>Wx;BzOC(?Id}VNJymTqja~aM+HHbUADf$n#pnin zc~2ftNEz$y&ysGL<}Mo~tq!0uete^+>Hwp3(n>;c>zB}XUM0c+${0&)>v=s0}i=oT;sMKDb0xWiB=(Z^^gN?jNpzF2L% z9cwx<9XXKJfI(^ImKk22uTDTbMSTjq&Kamu&bV)Dk+=IVOpJIG)DnhOaDE^!|N zJ-_-VKz+(k8z*2KytF95a{l~7RFR_sOZmiSIKDxAUK}Yee_(`MrX_gX&FAGAiyhD< z*Sy!K43s^c9TK#1UiE(cVt?&oMK$+CbqHpEZ8lEylI2&HS_Rf84C*`KTJogAmBaXl z(+YOAXQ*cv_1T;-{HtA51%LnhJf*%97FjMzSm|4)w_4wqmzk$A9T5{1@fG%T>L8ZR8L0J@e)OX?>z?RL__5K}#;TXEE@O zPI(~N$^x&IY&$SQWze&RUPZTWGxJ7C>(cU@ySuD1VX{`#(+-mk--=$JZME~%$`hf5KkP z4%0SJ?|(oMo?!(Ch*=%)*wlFYi`3Wf2$kq1W$Mr+g*g~fi`DtFyna%W1 z=U*01^SwLT*No-Zd+^SYRz4HN5E77vEa~qmP5s}}s+m2mBhPk&hEb@DO)pf6hqoMO z#ZDdGb1L7s=MiY(Y2mMVElI~Xa^v$RNamE8l^v}QTisUV{O7H^$r=MM6} z)N|h(x!)6ie%?(REJ$Pj?)`PW2`buf?FR((4PpP)TF?6=e`Lf&Ar(WdsGDRY53rvJ z%J%jvMnd$4%y?p~cTJ7bf!J7e2Jn{D@G@6WL;ryTGodXc5~9U;Zk(5xwF3ttw;YJw zB?2BXSLfb!$8os8#mGv<;PLQI7~$GVPDMxW=G+dyO7;$na$@e?O_<5env8@J>f2^y zVl_iYugL9Uf1qOx9%7T0z3F39MHD@1>a%%NMbA!p1^E;!x0Ht3NnW$b=-AnYs>G6M^2tRIj63z zg2UmtR#pXp=7^eJNWJzA9{R+xcs_BVtiJ>xs5Yja>$t%wo9$bf)~8Q@tbB}Tn3v!A zEEmz8wVdU47e{DnhNv!{KVLEF4rj^va*O%%MSp{rbKbe3fjbcE z-K)I>dgjctJX(!O&$EiQTf`G6D|F}XfM$@CB20oxUBt_E4hj2z33E{9wp{vnmU3!2 zf>x?cZ=uXdUek%l1c;#rGm&svVEFzug!9 zQ3&f#26p|QGNdY-xGUcNYOgTA?znhSgEmIU&uDq&7zx#&`uOjyKi5HLr#<*KYw6uS z|B~}HL^Rr5j|XT#nADk+jDVTtDxdTAL&!m*Rn^qAp^c^NU5>yd#p{WAE9UFQoC7FB7^2aWL%)YXSD0B*llH_8-ITG2cer)1d~3E zb}_IOR|U1<$cd%`m$^(l+*0mv)O znX*`89|u+RF+S4V#%=R}-(^v}v^1vcfT+?Py#2~&4+slWnKx#{2*2OlOu2mWxAEs5 zEn?}v`D8V9YO9_@1}P~SzB2WD)7-mRPUx$Np)syQa(WL;Q6i>{hB|ccUUhOLjdS*i zE6X;|HaG7{%w$ohw1$zp^V96?wsfq~c|a10$AA|{x}kKHKwm}X(Hxy^yh<@(GC-8G zLTvprYDzM~`VS|3oSS~E#pOBO)|ztUjlLyk1`$fS6WgHCJ?}OKN`D+IsQt>DH*db( zI96LbCP3r&yYwNL0ybc_z$#$Y?*SJS)5g02MA%oGWas4x`)pBzNF||+Gz~;7Fe*7- zFb_#;&#pLh7fbBr%bc|AlbAJmG&gajPHz6vX2jTu69>>MMD4T~S^pnJPqDVJlv0O8 zqM_%(5^t9nI*CLcE-d}L~|C^$!3+I_G zJ~e(2f}Z2OK~y<-35poo0nsUu+)2P!sq0azxVzf`RV~Zu1hJA!FUGTnDJUP# z%|yL(2ond4PnSO0yC$_k7{#bCq2KUm&*>xLMQDzMr-LpnlTmP|HDwl9fosC`?ilyF zx>|q5zK(+y#&6!ZvFU|^+QsiJ#O2{cZ3hGOX5CSUR@}tisDW;E6 z{6Z+W%o{f()C0lwT~dGiRhcRt9&$1v5CfCm$hG$$I8mH|?0iU8KWbn+>PO6*l?I-C9ciLFsf;h&r|v%OL=~NYLg`fulo^-(78Gp`fa6}Z*SG*)_1P;z zIxZ(CxBpUnwE*_5fPd_F_6G&UybR$!jJ|`*Ktu&gypgYH-Cf7wZ}xaBnz&a(flqyN z4OgSdH7Cc=zs!ZT8n)RGltyTNB_f+_z|I>+Hsh*N?9i2++V97Wz2Y6oqfuH7)3tbN zeS6MfgGR59AWEXlKY=rnQ9|u+Zg;F#k*|R~a+^Cz3r@=RrxqEG!vDmHYe-xObNKww3JcqV z?RW+HZrfFqJ)(B23GJhx;E%RNq)&&AUfr7#FaZCRFi9W+vt3I{RO?`krTe%LKta0^ zN|47I+kjfq>D}hv%^uxAqK8t{^ODgYNiDV{&3)dh z4q=JT_lQF{Ho?Q}!_e0d!V%l`eW-mq34<_|OCIM}CAp8B&9h>UT=)P~^LC*gXM>n? z#%A*^K$5ely7PXW4d*AbfdC$oHm|LZ|k2%_vQT`irUN%`2O@P5v$DnE`%1c-J9}JW$vywgYU2 z6~4Q7w`WM9Pmwn5#1zRPZk|~mc7nVGr)~Xt@We?X#ac}P=*iA+s;`&k5HCsh+?ueu zT*GYX(h-&m*n!5V7WlY8Y0{E4ax2qd3Nuz&~Z>+j#) zmmw1MOH#`w6Tj-4Ie{x;eQR$d)IKMg2-?VQeZ=0up(n1_*52Ya|MYdp-DadIedn2( z4dKEsYGC^qcTFg8yHhycIwkmhRn=6^wHfT0j~PN06~H{y9oY>N*)6TT#r)#9QBJ4F zVyNvXN${w%k58jvk(Rt*LB1d{ewbkAxqy|RM$e!P4Pf;O9n?x5Qc(lUtTeQD^zv z)zt48fBEtt4l9@I3U+VhJaUtlsegWSWzPu&Hm5Re4cuD!Us87e#@QaWnnQS29b`kn zIQMS=b2+(@I*$aTw6=*xqK{S8=4O(<&b0UM{YGV~%>4oMY@OS6?tOea4TR2m;BAu= zadB(o+A5oxn4GaQG%!$EVv4?YgtCrKqUjE!@p^hC6M(#x)^k&s-RjYG;8O&W;c!?t zUoh9;NUCN1(*%ahE6sV(G*8z(arf@sMdQkFGn!^b0?XP>YJ)9mzrKyl$>6uu)n<_i z>7DCx{%@62PUwbrG6eTz@~Ercz1zoL5FFf>@89i`<eyi=m)mU?doJM?wPiZ+F3` z!lu>8^?FHU3^#$(I+ae)Q=~-gV&R~XQFPnCAhfF^N9seY9~9zW*f`pc&x3D zz9@8Xd@KrSr>)~*D@2>&o*0~wG^U$? zn~)WY6ww2n?=!dRt=d0&Ch9p*_|CUn{<^WPn7neiiw}vXa;+9=new#US<_Pa208JJp&KnQvD5MCp z2DGu6xt_CKh8CM_@k7Q*3P`|Vnnawn?Ut3Gzh)m_+Pysx{;umP?%)5fWbF1g;oJmG zB`P}N+O_Z>nS9f-ZuCpC0wDiaQGyy*1VIL4(%bKS_I^r~dS1s*7X)&JWmOsqL+!h>f9fr&tByA`8`{n7q@h`3UX3-Ir}& zDqD#^svEQB;gs8!26<(i)nP3UI8Bcf{7~^mV+UCF_A3QjpSnA2mIvWp_0L@oF?!z`f$)zW_6++bKt8f3!Su_%KLL zZs@CyMH?l1e`QJ!8a-N;kyG`=T&#+1Z!Gr3M)i?CGNW^3hR?(S683Y*?L1^1opwq4 zth`-RBxLPk9dgI`a0O9|`Tzlnty*+)o`FEU=$&uU*~Vi@@>P%#Rb~8*=Q9t-B}_rk{(RL%7DdvoAAfN5hYG`_mgw(4_%#>FU8Tl($20pNSo6IHJdoI_1A;s-~89OHwGU~ zady^%h~*&|PCnz~DU0n@w((S8)Tmzf`z`t1+{to~&)|hOq`zxU_}_$HdHE_O9ZvS$ zjC+WRTpw`@u9X8S=FvAEKVEE`)>kBolgBl7-IE)PFdgakZvL9b$z8eIZqlR3|Ijn| zrd0m3Rr&A6zP%?6o2YqF-T7aR;kwHGp97hxCMzs!@C*WzBTP|>n^1P~#KVcF%@=E} zLeR~`yw>~TI1&eVOb07EN19oEY>UXW_oDI=3NrJj?7j`o z&Y9p+&ae@40E%;KWTa>A_3GvOyWvnGUt3tgA`YTR^+iCtN!rsMRaDrr zT;#{Bk!KsitE;;y@3^HanY6Aa#jdnyp1XIKTcO!hG1%RdU(Y7%kcH?Zdc|l*zT3brz(8=2;F-NQ;w|X<;7zX>)sJjZfiz%K}qF z1lft7dM!a?j>3kV|0vM3r#eEmYby2Y)29=KQ~dFPQ*Gc*%+-}bCu})#t7*!K-;E`l z=>g}Yrdtj4*p}|UvTDF01cvs-Q$l6u39p9t6&;*Chpn5iz1TNj_o&+))+X!kHejO5 zS7Huw9Cz9SxZi&7a>#>osh8oLOMeJrv}F{atjV~N-@AqWJlPpUOkI&*qmb( zq#I9_90HHh+R>rx(3_#Ux}k$linx(gC1*Mn4vSZL=J?1P_K@kL zaj>3ReV7o-!SAlPqcDEc0m&c^q2RxNV;IGJHR6FLWIx31uEBC&YHNo`vUB4}jmmb; zv`ZVVoxuV2f2aP`Xr~^O(|9SUUtrt#L|Eq5-u)-IA38jV=n=MY&avz5Og~YN4dS*v zve;qx>9K8v4sGVQ0F>sEL!fS>UNh$||G-rGlcJ))8R;^8`k;&fJ0D)wVM*Rq6go(x z1`OSZLAA9vqgQ>#iSbmYo z&|6v`8A4u9&*uHUlU7Et5wy#x2aRK5BO@apZXYo9#PImQ)6*43GvIdOh*I)_3VNo! zeleSF$?UzFrl!M6huh&fFVLcv3Rp~Kn~lA_J-&Ph{UdJ#?d3Mfo(Ldm)6VtAy2soY?iHDIo)mG7cF~2>i*Z9 zC)syxE{bqS5r#yWRLxq~B`*utwh%F)_}a_>LbjilqZg*(Oto>_fejpu{aQZ@a_LD@zHvGxwXwvjyb_N*}erYu>EKa zE{W@-E8-(EwW#(54m`L;aFQg${x|Itj|q$L;9L_$|JW}IuYeU!BeEytJ?5*f^tW?C9Ea^igQJ`_+Qubzop{Yvi+*^ zFqL6J`jIAG?RU-43Qp)Ev$NoAAFJGLp=(yy?vC%Gy&_C&|D518L%Z1BUUzO~pXu^u z1$$)*7bX5&k}-MP$)=xA?migj-+9#QUt5lszdyF|`Ri*}->2WXzO>wjNq2JiP#>ml zR2IrIU{x1qeB_~@{1D`$)_b^YzSoOWW5mSwEcPxFZ8GV{k`|4LU6(qqr$`8+PHImn zB4{p-AJJ(6w@WK1+#UD1x9X_u!mclU8&O>BC#M;csR9sDJ;8Mg-Ps#3OJ8#2Y)(P9 zb?nk*7rFWe@$(J{W33As!qKydLJi_%L z!oP$e0Ozqg89{<24tx)ZG)r{?u-WqfGR)U4HQC(3M*d>cIl z^)^fTPiVKp;S2qc#EGaLWRI~H9X@behz~?u=9$xu8ogmzj5vgUH`mQ^eREGt6A;uC z?$sE(QzAf4c+4oAEZ!yg`ikg!zSH2bW3LvbtnVv^u+dUifdDW*;GVqZw{wq0AFS@vtxS#0n?z~%X)To}kkG{8)X5H&5$}5ngWvf?T_`WS&K5X7omuUy7 zsA~SDJv3WAVOqB#`cUx}cAE>znY3fI)OL_hJE&`K>o?Iw^ zhjk7oJ#$^>vlCODt>(_1nrKR&HBiDxWGu+z@D)*ba$-YSso77G|n&{|Vs&p`dKI3H{PeLDT(dF+~({ zXoEF1yR$I?E>Bt-J(p1w-}}9)4FxO{J5C+xc1rx<8RuHf*wcwW8}#QFSYN8y4^ce- z>bj-HA*eUue@*U1eONSvLb#Z`g`V5a+yW?C;T1Uhk=jkTyBtpU`wjKBbX}ugRbl^) zEh^M713o4bC(SIuDjQI-WDsD|G5#@n-lyo5U+uYAS?_v;R}%MZJ@;6J7Me z#F#o}?wL`P92%csQ5HU=l+y{0B&VVOaZ;B9BZbzex6nV{{Q&$nzI^xis%GS>_3Q8Y(5^YV(qi1nqD?GV7_PPDF)m|HET`Jri2CqLl`MS%~RXdY6S&CZW^`J#x#~bV%&#GOt%JOWF z@o(!-|9M^iyeGvp{Tbu!^mgn;6x4||Dbnv`Pqz&-$qic-^zQ9|K{-D(5VE_hF@Qtsn95e{>h?RVw_^Za+bFR}A*&KzljE3t^FGq4Opn>7rmv1&Ry#P3 z;))#h+mHfrsd|%H>|2xLZXN;gzQ0Lapf{Xd8eZH982T$ctj>A zsc7UVo>wf#M7g2?drwvR-$2_&uYIboV#r3Y&$`ig6(S#3mulWYg`pQ(RuB%Wyl(zjC+n;XI4;c z-h`P z=BuU}na8!l_!G_7h)|azJUHc!QYGzr!5h)ANf8yMEG4u|NukHqKZp%`aBcM1vE`03 z8L*8zN>wy9%R>#pRW3YLOxI@9MQiz8N^hL09M1H+9k*H%l)l4eSICG{gRj@#K4rqIcoz{+y~UZm&_QIJeQ!ubJ>uH0M*SuDf3{ly9s(}KL6aw+Jo;tt`JHIZMIBDpFF0g+GG};y z;SduWf@Nf&P$07?y8QgwoIi~xCx)P-s2kHu@zc1F&GJ=-o;@wnfB=LHi`Zd-_Md}l&S)A2l<^&1xEy@2mv@CueIaj!nh@= zB1VQ_{?=o4S(6$_K--|?6&3@@!@@>v)a_=d^XYsWG`mHO)anj6q53Ct2d zuNbIy!DbvZEz-LEbk(A5g5_~oj&D{7P4A?MI5+W4z&x3HB2V1nO6@)(4G0lOmbm($ zhK9w)#c8p0P|6J=$q0^RH|7pnT^>xgDb$)wcU`ds<%aluTfV*d3tW5!(lU86;Y03l zZp6cRe!4FI>~Ia%Hk=vL_=dvfiWXtR>nGGZ`?(_Vp!cRyYV)P~*cC_}dc8dW2^#6r z;n%)tx*e+9LwijiM|X*6`ox1{WXG|OO7x5JLJPt8!jU+@>Eu^HS&5t~7EPXIHPEfp z5YbkD6`ciwsMGKH65(&#k|vAfVtq;DIy^%5&8U9Wi_3Vb)Pe>s9AE$G`kvi~<0eW&p(LD`03dYO*ZuwchDlt(6sCF% zM8expUw;T9-DArZr!tkJ1dD`)hTaprEcgOa);Zway>Js%_v+pIF!Ha8y0hA02Ox$G zLE1{rr|)8{&*;@1B@p`lG=9TLIzV__b|Meymojfk8_=Ap@5&Zt{#G@|4zFQnEOIO4 z&^!-=uyWb5DbRl3;3bdHq5JIGB`pD1?JSqUwC!&X7OyYnm;jhOfQ0Nkx6ljHcMyDt zW&vR1LFh@KjUJLl?q}bfcffzM7pJC!HGcaQ#`6Fnv~92^R^}3s z(NU5F*Zlr!t&8u+=e8A=!6N~U4<`Prl&C7ApGR#{xl?D;#pg>Y^f{R9LrmmfQ5koW!zZ~n{&y9gh*41lCzacg0K^8$1R! z*H(u$es0J*Cc$NGX^+{G+7o#x}oprU*C4naw#rf`!DmLwt$I{t2!KIpUw5KD~^BW{j=|hDx{?RZY#aa1Y{0AgwEITjcp}=&TF+ zA1FMo^Xm2MBOxJjY;(eL+l{?9R!8Ry4SoD(tU}z3*}v3x1skic_f-jzPaXUx=}JS> zWoN5GsXjvZC2<9AR&Ba)=y%+#$DJe864(0%9Mx|+@Gx1naIx)+qZ&sN$da3jul-y? zf?3TO6FKUT*@b6}!*o=RDA^@VR@rKoC-?bDY8y^hA)-@KQWD^-K+USF-S zU3=6N$Pi73J-K;v=YZ~vwaTLR_2smxM%a=I196Cf+!DQzS&r8!Tq8}7>xEA6NGSZt zGWQ`UyYolHMtCWOF-~N-VDHWvXWwg@xq3#v5UdJT7F0uII_%qdOPE+GRm2^<*<|jz zI}4tj+*$>_2P53vMmiFGNff5ah={&B;UV( zH9LQHgs0(}$DLn}h_9X9g(gB;PHqo{)U1o@&j#UA8%j#Wij?a3CCCYq@?8ItvoDnu zH+(g8TQ#+^?ean=InfZhbq7?u`v%dFi)$bfvCbU6N;i>~=VXbsoPM22A`kSwGS+nY z@`#GdsQVTxJ3K(CV@S)p0NNtFkX+=<`wg@M$W$+k;jg+`R7~xL=R?B}3FpCeTee)w zUEz!zMtvQS$T&R^rPtMX2NO1nzBjiOy05+sXOY`PK1P|cY1cRIp!_>`de6VhUg?(}$03{I!k77QY%U>`aUGxn8Z<#Gz(lqBLJghx7q=FDlyU&Q=Nqv=SH{mn1d9y2Byfcfnb8~yiF(zP$7CB&?? zOTM2qt>Ay~Q&jK0bn7X~yuEJK}tTp&>cS3`m*;5tEw2Ih4lt32CB}Sw#ey zD=A3fxX&4W-BS{d&b~(v)>?4~g>5(DDhvISxNJ*|6g{_(j00 zvr$fpo*WR|sbM+O+~_z5fu)NrGmqlq96RRppW8HW)`2I7>QEVMwWybo%sx5ky5Z(R z*Hw!nT&B%?|>Tbo4J;5630W3&!|fQbWh% zX8j#xb9`jv8X21gvnO#6?8W~+Qz>nqI@9OjaqR}J_3Irv1o^1JN&0?)+@7v^UHBDVV+ICZ~qGYGiz@(Rv~D_{ zupl{2$)?J}GWN)4FVPYlEmphet)^<`w1a2MW1P2WQD=^nq`zCUF_|*l=j^?OjP((t zt0Y3Wf4ndm;Q7Pz3FPr*h1HzQP$n_8Y6cQKvQtMkWEwvR1` zuYarhJaMYhS9{wx|JDK=5#|u8P%-3}c3rTm5tM!(TRT>?3-|*+UedIFbOztA-&zl~ z^&Q%zC5iA4l*qg49%wutSiTFBhzQlC?#>e#!ZdW9?;PDWcks`Vm!t@d@S}WTvSL4x z7RUjxhvqcKU5ndr6g7`PU?iIA6PU**EX{i53*5@4uFa%`jN5)bCOK5r-^;m6+$E7E zTTSgOs4ZmgVx)0sc=(XPgIj@VKKZKMaB5E2)x?H08M8}V55y;3NNC1wW*M&pg1Ad0 zFihV?hH$Zt+shE}gG$a^5$rt@pAVqMg{Y?&myU-F?97XY$khi*TCJHXJC+B%>A)@S z2z*`V7F-%gVCOt5D=|Fm-TV%ae!@`WFhWWq5)CB%kE7-1s`S=Ax-swtRW!MXG}~ z?#|6Z3?FPbR-is#c2@_vZPjT58v~Thai0q+Ewg7Hh@!J9f`3t4$ zg{bQcXhBuq1pqUb!)6zPBvD?Vc3d7E-l`JpDu-5B;126X*U|V$ykQX+xTeB_0oP=Q z^`()@rott|QVU_g`7Xni8Ia5^jcIY{h!I^OOSYUBJIj`QhCxmVi-PW+gCXoEund3L#?LUGoe(%an2f*MkM)2A*!kc?>Zi_BU3Zqph3bj7Oc}cy3Bspe zSgpEBiqzxMH1W!{MdkV7DbEUU@OD^lxkX9{=cAWg%lE@uGGye)LlaLD=XFDBKx+60 z(X4b?8m~QT?~`7o4%vVQqFLEhIE3pQjfCmTCcu|v081jyk@N*MzjfB;$S$3ui^s05 zP<&YQ_ZUj56Je84-@Puu4c>9{zGa*+YZm-u2MG*i;X~?`FU0z%$q(w=*TogQWDgx> z{A+;GeP7pd8m6RFochrD%rz7fx!=Nok#ur5Zrb$9B#G;~27$iB`i+;$y9+j{E(Sx7 zbA4&70|_ggbrEJ@fr4%B5kxTAIJL@>Gr3t(&6fz@+4w%@bLXD2EVmwDdUDe3iJbmn zBR0{i9+zq&`Q|eH!jI=>MR!?=<3`o(6FqOWYT;M#A+);ZDm;WF7G;lFzup8?`1K&H z{l>5LvUS%u13=@#{DhBGC;I%yvJ;MJg>}bKC9Na^Fr&Fvid}q<*OHGa45Z`@FH_x` z)dixz=gHHjDqunsUFQIC$w-_mdpv>0H~`IsABbM*G?8}X_U7JSSKNCO>Ln2kglp{! zVGLJgxEme?H+%IMfhH?^~ z=OWWwDk=;)&ln!h5%ON>ko<^98cwD)p)CtvraDcYJh=iH^e@_bWa_Cte{;N=ZQ3+u zqWc%`^xuuE?bEG}n10%#2^ zRW^%lqm|~y#JL2*Ges!^p-uR3G3NxuO<1_js;oQfiIG2q?8am3)>6>MH>{XMp!F?H zAFmeB-_@**5VcFfcZ1aQ13o_O+(?$Z(!3dO8Zh-~>Sxhc0(BI_&>BkKAY69%%4w2+ z|9%jrlbPgGoME*PGNed6xR@Lnk{qfhgrluai7SzXcJA`!L&$h$391+npqT1^;S(VF z06rAu2VZi_bcA2gD3JniR1uq4jJ$e!(0?^xpRZC)B!bRuVIKSO$=gqGik#zin7?F6 z>=liGL%&Bvuk|UBEfs~gmZzbKD7>|5XCF{6u`jSJQQ3NB(ADsLA!RD1_ZzEu0y^&s zhcC7Xe6M)nZ`9_i&v<3O3G9RTu%wk)ays!FZ=B*^2|z6KWl6Mo^aUP_+OhC7x}DT! z>|@rEreR~CQ=<)QuOf4Cs`?w`dsH|KXOdEP>$hiOQGWvb&n8wN_6ut5GaOq%DZ<$& zUN@SN{POY;&gn;$FKEW6f6G!nz?V*fiT>3~w$BYBro;t)on15$3-ZR9C*YUF3y_{=9Wq~t#Xdu}TN3UkTid^O3U<9ga5#hnwdRLL8=J1NJ;P|4z>lfVw-0nms`F`+mBk*ij z+`d8Ip!64}iB-)CT>C67?5h}&ZSc>!n43EI^VN)BKl&xDdm5hOwrP{)_(5``xPR$J;oudiL5_tUhY&_gA zw(UGGMr(1hbyTI}c4r<0sj)F1x~L!>-$Uh^A|?f?KKE5QvasWb5b4yxCj-TRv)FCu zn=3cztiG^)|EkB~hx+lgLnjUGrSCE8z_tsH9!8MbZfS8 zy7AopbB0^*6Oc7uEq>Ogg~#9Iyd9h~GIe~1FcU)#$|Vme`p;{1b@RA4>=RIAs!q~U zF$=-;h;~Ck$A<3^Qc@aw#=I`BNbk83jr^4~(JjrYp-_2U`0Dzg028i!Cy9J$)`o-q5 z@I&9I6;>Ztva=}uWu(i%d%x^^Vvv0vv+23JyVAkpKg2NA)1={YG{bPEFtoAMJD{O4 zV&xIG5pDZ%Ru}5TUBc%MYa%E+O0Hoe9EBj^(2M9@+dC!px!IWEvoUkI%c3n?w)DN3 z{c7qOuXYvM?tR90?E7}Fijmv4vm>^@D?C?k%5Pk8t?;u=^s)Q*Kj}aIY*%6F=#_YX z>Fk#u?b2o2c%}^&v7Vr%s((aM;V;-94$aKjLzTRVC+$-Nu)n%uj;J|2-M2oi8WF@71?j<{UbDcw5s? z5hjFUti#qHSk}^i?cKYvcMD|pw#K(-KQ!+jTXpbD0=eo|XHEnO%P^NK*Wa!;U;?@ryFv#y>gAPwO8eGIZGfwI2av}4`ucNzTj7)VDSIY5*xPr$_?TCHGdDN7(4Bk! z0Wz%NX(Jl^xHWDbzJ74!d zxvKgl%V(c$s5VNr9mrcB+zDSsFx;F;4Z9|yUSAbEo?`Obr>93JqLLQl{v_UrTq%sN zj081K;~RhQfVM6=J_SC==2MIM@i)Q$Qn8?F@eor|N-gFk_FshL+sBV&$R^9;!xs`P z<{L~?C@dFS$=n+6^4(%AsAJ^TtzUns_@2m$b=59oEV;Vw_MS>6mFX6)e=h9meM@f@6jW6caeH-%JGX+>LplSSnUmg3`=j;ww-!e+O*>61PY(D5 zbn)tSmFX&ngxo_#H@)r0?~ac3_LoimrSf<;23e7#6 zGLJsUcvjX@bYVuzbH)9C ztHPvA%YO6mSX*eyusBnvoNRs{2g*XHURN38|Q!Tv=lHki;9ujs^Gr5ONMJ| z8nH%32YZ0F7u9;8>Vs~G9AizWNr)j(QL4*#8c`1Hb`o^1JNEy*=8-m<9D}+2L{bG3 zM#-0w_9@RojUUnWedY41p;)fx6|~#_`aepHs5+sypaicX=}H`Pj4KeW9y3(h0~EHE zym;|KjK%8fu)xai?(N$-I3#xhjtOxYX^X

DAQ<21ggwT&=4 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 S;&s+EygUyw+)MUHT=^F)|FR_j From 43ab8a16b34102b52e7a6ab9db09c8dbc0fc4f42 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:20:15 +0200 Subject: [PATCH 06/31] Add note in help of vanity option --- cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 8382d82..25b2824 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -37,7 +37,7 @@ fn main() { .help("Provide additional entropy to the random number generator. Any random string, containing 32-64 characters")) .arg(Arg::with_name("vanity_prefix") .long("vanity") - .help("Generate a vanity address with the given prefix") + .help("Generate a vanity address with the given prefix. Note that ['b', 'i', 'o', '1'] are not allowed in addresses.") .takes_value(true)) .arg(Arg::with_name("threads") .long("threads") From b9964ae0aa609efe4e4f0ccb6ea1669f8e8704a6 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:21:32 +0200 Subject: [PATCH 07/31] Add note for vanity option in README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index add1ab3..bf0fa4b 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,8 @@ OPTIONS: -t, --taddrs Numbe rof T addresses to generate [default: 0] --threads Number of threads to use for the vanity address generator. Set this to the number of CPUs you have [default: 1] - --vanity Generate a vanity address with the given prefix + --vanity Generate a vanity address with the given prefix. + Note that ['b', 'i', 'o', '1'] are not allowed in addresses. -z, --zaddrs Number of Z addresses (Sapling) to generate [default: 1] ARGS: From 62379075d5ad66ca68ef9702f9b97879f55017e1 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:34:09 +0200 Subject: [PATCH 08/31] Standardization of address names --- cli/src/main.rs | 12 ++++++------ lib/src/pdf.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 25b2824..d6fd44e 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -47,7 +47,7 @@ fn main() { .arg(Arg::with_name("t_addresses") .short("t") .long("taddrs") - .help("Numbe rof T addresses to generate") + .help("Number of t-addresses to generate") .takes_value(true) .default_value("0") .validator(|i:String| match i.parse::() { @@ -57,7 +57,7 @@ fn main() { .arg(Arg::with_name("z_addresses") .short("z") .long("zaddrs") - .help("Number of Z addresses (Sapling) to generate") + .help("Number of z-addresses (Sapling) to generate") .takes_value(true) .default_value("1") .validator(|i:String| match i.parse::() { @@ -86,19 +86,19 @@ fn main() { let addresses = if !matches.value_of("vanity_prefix").is_none() { if z_addresses != 1 { - eprintln!("Can only generate 1 zaddress in vanity mode. You specified {}", z_addresses); + eprintln!("Can only generate 1 z-address in vanity mode. You specified {}", z_addresses); return; } if t_addresses != 0 { - eprintln!("Can't generate vanity t-addressses yet"); + eprintln!("Can't generate vanity t-addresses yet"); return; } let num_threads = matches.value_of("threads").unwrap().parse::().unwrap(); let prefix = matches.value_of("vanity_prefix").unwrap().to_string(); - println!("Generating address starting with \"{}\"", prefix); + println!("Generating z-address starting with \"{}\"...", prefix); let addresses = match generate_vanity_wallet(num_threads, prefix) { Ok(w) => w, Err(e) => { @@ -126,7 +126,7 @@ fn main() { entropy.extend(matches.value_of("entropy").unwrap().as_bytes()); } - print!("Generating {} Sapling addresses and {} Transparent addresses...", z_addresses, t_addresses); + print!("Generating {} z-addresses and {} t-addresses...", z_addresses, t_addresses); io::stdout().flush().ok(); let addresses = generate_wallet(nohd, z_addresses, t_addresses, &entropy); println!("[OK]"); diff --git a/lib/src/pdf.rs b/lib/src/pdf.rs index 430904e..07fb244 100644 --- a/lib/src/pdf.rs +++ b/lib/src/pdf.rs @@ -156,7 +156,7 @@ fn add_address_to_page(current_layer: &PdfLayerReference, font: &IndirectFontRef // page_height top_margin vertical_padding position let ypos = 297.0 - 5.0 - 77.0 - (140.0 * pos as f64); - let title = if is_taddr {"T Address"} else {"HUSH Address"}; + let title = if is_taddr {"HUSH t-address"} else {"HUSH z-address"}; add_address_at(current_layer, font, font_bold, title, address, &scaledimg, finalsize, ypos); } From 48bce12eb48a03f215bb33d654c0f59d91bfbf31 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:46:47 +0200 Subject: [PATCH 09/31] Remove tests from papers.rs file --- lib/src/paper.rs | 232 ----------------------------------------------- 1 file changed, 232 deletions(-) diff --git a/lib/src/paper.rs b/lib/src/paper.rs index b2fc625..9728ae0 100644 --- a/lib/src/paper.rs +++ b/lib/src/paper.rs @@ -438,236 +438,4 @@ fn get_zaddress(seed: &[u8], index: u32) -> (String, String, String, json::JsonV let encoded_vk = Bech32::new(params().zviewkey_prefix.into(), c_v).expect("bech32 failed").to_string(); return (encoded, encoded_pk, encoded_vk, path); -} - - - - - - -// Tests -#[cfg(test)] -mod tests { - - /// Test the wallet generation and that it is generating the right number and type of addresses - #[test] - fn test_wallet_generation() { - use crate::paper::generate_wallet; - use std::collections::HashSet; - - // Mainnet wallet - let w = generate_wallet(false, 1, 0, &[]); - let j = json::parse(&w).unwrap(); - assert_eq!(j.len(), 1); - assert!(j[0]["address"].as_str().unwrap().starts_with("zs")); - assert!(j[0]["private_key"].as_str().unwrap().starts_with("secret-extended-key-main")); - assert_eq!(j[0]["seed"]["path"].as_str().unwrap(), "m/32'/133'/0'"); - - // Check if all the addresses are the same - let w = generate_wallet(false, 3, 0, &[]); - let j = json::parse(&w).unwrap(); - assert_eq!(j.len(), 3); - - let mut set1 = HashSet::new(); - let mut set2 = HashSet::new(); - for i in 0..3 { - assert!(j[i]["address"].as_str().unwrap().starts_with("ztestsapling")); - assert_eq!(j[i]["seed"]["path"].as_str().unwrap(), format!("m/32'/1'/{}'", i).as_str()); - - set1.insert(j[i]["address"].as_str().unwrap()); - set1.insert(j[i]["private_key"].as_str().unwrap()); - - set2.insert(j[i]["seed"]["HDSeed"].as_str().unwrap()); - } - - // There should be 3 + 3 distinct addresses and private keys - assert_eq!(set1.len(), 6); - // ...but only 1 seed - assert_eq!(set2.len(), 1); - } - - #[test] - fn test_z_encoding() { - use crate::paper::{encode_address, encode_privatekey}; - use zcash_primitives::zip32::ExtendedSpendingKey; - - let main_data = "[ - {'encoded' : '037d54cb810000008079a0d98ee64814bffe3f78e0b67363bdcdfd57b6a9a8f871615884ef79a001fdc59be1b24f5d75beed619d2eb3722a5f7f9d9c9e13f6c0218cd10bffe5ec0c0b21d65ad27ac913dfcd2d40425345d49c09e4fed60555a5f3346d76ed45906004f4c2cc6098f0780b9adaa0b1636976dcd8d6311812ef42f073d506ae19bbe4ff7501070410c512af68ed0141e146c69af666fe2efdeb804df33e3304ce07a0bb', 'address' : 'zs1ttwlzs7nnmdwmx7eag3k4szxzvsa82ttsakmux5zk0y9vcqp4jguecn5rqkjjdae2pgzcta4vkt', 'pk' : 'secret-extended-key-main1qd74fjupqqqqpqre5rvcaejgzjllu0mcuzm8xcaaeh740d4f4ru8zc2csnhhngqplhzehcdjfawht0hdvxwjavmj9f0hl8vuncfldspp3ngshll9asxqkgwkttf84jgnmlxj6szz2dzaf8qfunldvp245hengmtka4zeqcqy7npvccyc7puqhxk65zckx6tkmnvdvvgczth59urn65r2uxdmunlh2qg8qsgv2y40drkszs0pgmrf4anxlch0m6uqfhenuvcyecr6pwcvt7qwu'}, - {'encoded' : '03747bda750000008090dd234894f208a53bec30461e9a1abe6c9ecce833b2110132576d4b135dee0cd328312ba73ae04a05e79fd81ba7d57bb4bc0a9a7a7a11ca904b604f9be62f0ea011906ac33e3dbbc0983228ed3c334373873d6bc309054c24538c93c3677e0332c848dadbee9308fe0d37241aa6e34541e3837a272a4d08e30ac1470ef389c46370ae1ca72bb87488bcfa8cb26040604ef3dd8c2a8590e3f05ee771ba6d7e89', 'address' : 'zs1ttryt8fh0hu74upauprpglddcm3avmclnr2ywsxzhpqgchcd29xyqtvpqx7wktvx94cg6522ldy', 'pk' : 'secret-extended-key-main1qd68hkn4qqqqpqysm535398jpzjnhmpsgc0f5x47dj0ve6pnkggszvjhd493xh0wpnfjsvft5uawqjs9u70asxa864amf0q2nfa85yw2jp9kqnumuchsagq3jp4vx03ah0qfsv3ga57rxsmnsu7khscfq4xzg5uvj0pkwlsrxtyy3kkma6fs3lsdxujp4fhrg4q78qm6yu4y6z8rptq5wrhn38zxxu9wrjnjhwr53z704r9jvpqxqnhnmkxz4pvsu0c9aem3hfkhazgksps0h'} - ]"; - - let j = json::parse(&main_data.replace("'", "\"")).unwrap(); - for i in j.members() { - let e = hex::decode(i["encoded"].as_str().unwrap()).unwrap(); - let spk = ExtendedSpendingKey::read(&e[..]).unwrap(); - - assert_eq!(encode_address(&spk, false), i["address"]); - assert_eq!(encode_privatekey(&spk, false), i["pk"]); - } - - let test_data = "[ - {'encoded' : '03f577d7b800000080b9ae0ce9f44f7b3550e14f4662e91270b04b265ff4ba4546be72feef91b38d3397b3d25a79d67fa024a1b0d3f4d5143eff3e410c300bf615090dbdbddea6b70302bb8b73449cafa1ce1862bd4af31db2d468e39c451cfb026128ea3abe6b820ccb1b8e3a4e6faccef50f9f3c02a5cd55d9faebc4939d6d5f5271b8a66d73f443ec546c3cf583dccfed7994e856cd462a0a199cf6c89bdbe6b38c721dc07637ea', 'address' : 'ztestsapling1tsurvgycuy5me2nds2jpug806nr954ts3h3mf2de925qp8t9tyhvg0sfhe0qp3jf02vfxk3thn0', 'pk' : 'secret-extended-key-test1q06h04acqqqqpq9e4cxwnaz00v64pc20ge3wjynskp9jvhl5hfz5d0njlmhervudxwtm85j608t8lgpy5xcd8ax4zsl070jppscqhas4pyxmm0w756msxq4m3de5f890588psc4afte3mvk5dr3ec3gulvpxz28282lxhqsvevdcuwjwd7kvaag0nu7q9fwd2hvl467yjwwk6h6jwxu2vmtn73p7c4rv8n6c8hx0a4uef6zke4rz5zsennmv3x7mu6eccusacpmr06sjxk88k'}, - {'encoded' : '036b781dfd000000808956fba285802d5cebf5a24142c957877fa9a6182c57d24ab394e47eafc6c781750bcb2630ce11a90faf0e976d3898255a509e049d2332de9f332e254e91770ce45c085da9b55e108b5eaef45e68ab32bb9e461fe2356ea375258377044d190b1a630c1d1471d6cbc98b9e6dc779472a797d3cfcaf3dfbe5e878dbeae58e8a48347e48cf93de87f63aa3803556e9632e97a27374aef2988205ddcf69da12c95e', 'address' : 'ztestsapling1tscd2ap27tt4eg42m3k76ahg9gxgqf0lk8ls2tsxegkf7s050v9agccg0jg2s4ja4vkvccas270', 'pk' : 'secret-extended-key-test1qd4hs80aqqqqpqyf2ma69pvq94wwhadzg9pvj4u80756vxpv2lfy4vu5u3l2l3k8s96shjexxr8pr2g04u8fwmfcnqj455y7qjwjxvk7nuejuf2wj9mseezuppw6nd27zz94ath5te52kv4mnerplc34d63h2fvrwuzy6xgtrf3sc8g5w8tvhjvtnekuw7289fuh608u4u7lhe0g0rd74evw3fyrgljge7faaplk823cqd2ka93ja9azwd62au5csgzamnmfmgfvjhs68k0x5'}, - {'encoded' : '033d5066140000008099cfb65ab46e5a0e3f6891c1480fdb2f36f2fa02d75cfebb04e06513e4eaa148978f54f4e9fee05464a1574debae01ec1bd53c4c7ac4fd49414e4ab05b18a502c420031918f93c8756f054cdd134dabf36941b59f839761f2339b9d88a2d68073e53dce94d94c5118141179d1fb38f62705a3c1d27d2bb86bd0824cf72ac07d2095a13bd31975c706a7ec3e65310851363c658b76f3ac45484b4015ae93f0556', 'address' : 'ztestsapling1ts9afgw2k67qewv7wr08upf4wxe3m82u6fz432jpar7h48k60w4ksuereawhszsd0xvjyc5a5u0', 'pk' : 'secret-extended-key-test1qv74qes5qqqqpqyee7m94drwtg8r76y3c9yqlke0xme05qkhtnltkp8qv5f7f64pfztc7485a8lwq4ry59t5m6awq8kph4fuf3avfl2fg98y4vzmrzjs93pqqvv337fusat0q4xd6y6d40ekjsd4n7pewc0jxwdemz9z66q88efae62djnz3rq2pz7w3lvu0vfc950qaylfthp4apqjv7u4vqlfqjksnh5cewhrsdflv8ejnzzz3xc7xtzmk7wky2jztgq26ayls24srxx9hw'}, - {'encoded' : '03a19d13b700000080ff5f4ec78697bd786cb6dfe2e8cc57fd9cd4ad7f87bb9a92607cbf23122082e6c00e3eceb438a739738262e1ac3eabdb1d9c0a44b45b759939d159739b29880ba4437024a134269e16cd9a859f86854d5ea237e542f700805364a6d0515ac70a2fed943bef0430025c4d2895b780bbe08c659e37f3d60336c1cbc0bb17bb2488d7c6b55585b0743600826e333bd058b3fed68b02228efaa94b0f6eadf0fc7b68', 'address' : 'ztestsapling1ts8mqy2kvn7j3ktj9ean07tl0wktqnv6e5amrv92x2yenlx4hxc6tmktewc79mk0wlmkxh9fh4q', 'pk' : 'secret-extended-key-test1qwse6yahqqqqpq8lta8v0p5hh4uxedklut5vc4lann226lu8hwdfycruhu33ygyzumqqu0kwksu2wwtnsf3wrtp740d3m8q2gj69kave88g4juum9xyqhfzrwqj2zdpxnctvmx59n7rg2n275gm72shhqzq9xe9x6pg443c29lkegwl0qscqyhzd9z2m0q9muzxxt83h70tqxdkpe0qtk9amyjyd03442kzmqapkqzpxuvem6pvt8lkk3vpz9rh6499s7m4d7r78k6qa4j49t'} - ]"; - - let j = json::parse(&test_data.replace("'", "\"")).unwrap(); - for i in j.members() { - let e = hex::decode(i["encoded"].as_str().unwrap()).unwrap(); - let spk = ExtendedSpendingKey::read(&e[..]).unwrap(); - - assert_eq!(encode_address(&spk, true), i["address"]); - assert_eq!(encode_privatekey(&spk, true), i["pk"]); - } - } - - #[test] - fn test_entroy() { - use crate::paper::generate_wallet; - use crate::paper::generate_vanity_wallet; - - // Testnet wallet 1 - let w1 = generate_wallet(true, false, 1, 1, &[0; 32]); - let j1 = json::parse(&w1).unwrap(); - assert_eq!(j1.len(), 2); - - // Testnet wallet 2, same user_entropy - let w2 = generate_wallet(true, false, 1, 1, &[0; 32]); - let j2 = json::parse(&w2).unwrap(); - assert_eq!(j2.len(), 2); - - // Make sure that the two addresses are different - assert_ne!(j1[0]["address"].as_str().unwrap(), j2[0]["address"].as_str().unwrap()); - assert_ne!(j1[1]["address"].as_str().unwrap(), j2[1]["address"].as_str().unwrap()); - assert_ne!(j1[0]["private_key"].as_str().unwrap(), j2[0]["private_key"].as_str().unwrap()); - assert_ne!(j1[1]["private_key"].as_str().unwrap(), j2[1]["private_key"].as_str().unwrap()); - - // Test the vanity address generator returns different addresses for every run - let td1 = json::parse(&generate_vanity_wallet(false, 1, "te".to_string()).unwrap()).unwrap(); - let td2 = json::parse(&generate_vanity_wallet(false, 1, "te".to_string()).unwrap()).unwrap(); - assert!(td1[0]["address"].as_str().unwrap().starts_with("zs1te")); - assert!(td2[0]["address"].as_str().unwrap().starts_with("zs1te")); - - assert_ne!(td1[0]["address"].as_str().unwrap(), td2[0]["address"].as_str().unwrap()); - } - - #[test] - fn test_tandz_wallet_generation() { - use crate::paper::generate_wallet; - use std::collections::HashSet; - - // Testnet wallet - let w = generate_wallet(true, false, 1, 1, &[]); - let j = json::parse(&w).unwrap(); - assert_eq!(j.len(), 2); - - assert!(j[0]["address"].as_str().unwrap().starts_with("ztestsapling")); - assert!(j[0]["private_key"].as_str().unwrap().starts_with("secret-extended-key-test")); - assert_eq!(j[0]["seed"]["path"].as_str().unwrap(), "m/32'/1'/0'"); - - assert!(j[1]["address"].as_str().unwrap().starts_with("tm")); - let pk = j[1]["private_key"].as_str().unwrap(); - assert!(pk.starts_with("c") || pk.starts_with("9")); - - // Mainnet wallet - let w = generate_wallet(false, false, 1, 1, &[]); - let j = json::parse(&w).unwrap(); - assert_eq!(j.len(), 2); - - assert!(j[0]["address"].as_str().unwrap().starts_with("zs")); - assert!(j[0]["private_key"].as_str().unwrap().starts_with("secret-extended-key-main")); - assert_eq!(j[0]["seed"]["path"].as_str().unwrap(), "m/32'/133'/0'"); - - assert!(j[1]["address"].as_str().unwrap().starts_with("t1")); - let pk = j[1]["private_key"].as_str().unwrap(); - assert!(pk.starts_with("L") || pk.starts_with("K") || pk.starts_with("5")); - - // Check if all the addresses are the same - let w = generate_wallet(true, false, 3, 3, &[]); - let j = json::parse(&w).unwrap(); - assert_eq!(j.len(), 6); - - let mut set1 = HashSet::new(); - for i in 0..6 { - set1.insert(j[i]["address"].as_str().unwrap()); - set1.insert(j[i]["private_key"].as_str().unwrap()); - } - - // There should be 6 + 6 distinct addresses and private keys - assert_eq!(set1.len(), 12); - } - - - /// Test nohd address generation, which does not use the same sed. - #[test] - fn test_nohd() { - use crate::paper::generate_wallet; - use std::collections::HashSet; - - // Check if all the addresses use a different seed - let w = generate_wallet(true, 3, 0, &[]); - let j = json::parse(&w).unwrap(); - assert_eq!(j.len(), 3); - - let mut set1 = HashSet::new(); - let mut set2 = HashSet::new(); - for i in 0..3 { - assert!(j[i]["address"].as_str().unwrap().starts_with("ztestsapling")); - assert_eq!(j[i]["seed"]["path"].as_str().unwrap(), "m/32'/1'/0'"); // All of them should use the same path - - set1.insert(j[i]["address"].as_str().unwrap()); - set1.insert(j[i]["private_key"].as_str().unwrap()); - - set2.insert(j[i]["seed"]["HDSeed"].as_str().unwrap()); - } - - // There should be 3 + 3 distinct addresses and private keys - assert_eq!(set1.len(), 6); - // ...and 3 different seeds - assert_eq!(set2.len(), 3); - } - - /// Test the address derivation against the test data (see below) - fn test_address_derivation(testdata: &str) { - use crate::paper::gen_addresses_with_seed_as_json; - let td = json::parse(&testdata.replace("'", "\"")).unwrap(); - - for i in td.members() { - let seed = hex::decode(i["seed"].as_str().unwrap()).unwrap(); - let num = i["num"].as_u32().unwrap(); - - let addresses = gen_addresses_with_seed_as_json(num+1, 0, |child| (seed.clone(), child)); - - let j = json::parse(&addresses).unwrap(); - assert_eq!(j[num as usize]["address"], i["addr"]); - assert_eq!(j[num as usize]["private_key"], i["pk"]); - } - } - - #[test] - fn test_vanity() { - use crate::paper::generate_vanity_wallet; - - // Single thread - let td = json::parse(&generate_vanity_wallet(false, 1, "te".to_string()).unwrap()).unwrap(); - assert_eq!(td.len(), 1); - assert!(td[0]["address"].as_str().unwrap().starts_with("zs1te")); - - // Multi thread - let td = json::parse(&generate_vanity_wallet(false, 4, "tt".to_string()).unwrap()).unwrap(); - assert_eq!(td.len(), 1); - assert!(td[0]["address"].as_str().unwrap().starts_with("zs1tt")); - - // Testnet - let td = json::parse(&generate_vanity_wallet(true, 4, "ts".to_string()).unwrap()).unwrap(); - assert_eq!(td.len(), 1); - assert!(td[0]["address"].as_str().unwrap().starts_with("ztestsapling1ts")); - - // Test for invalid chars - generate_vanity_wallet(false, 1, "b".to_string()).expect_err("b is not allowed"); - generate_vanity_wallet(false, 1, "o".to_string()).expect_err("o is not allowed"); - generate_vanity_wallet(false, 1, "i".to_string()).expect_err("i is not allowed"); - generate_vanity_wallet(false, 1, "1".to_string()).expect_err("1 is not allowed"); - } } \ No newline at end of file From d85c5f0a8b0e8bfce81b2a36ebed0f011cca473f Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:47:36 +0200 Subject: [PATCH 10/31] Remove tests from pdf.rs file --- lib/src/pdf.rs | 86 +------------------------------------------------- 1 file changed, 1 insertion(+), 85 deletions(-) diff --git a/lib/src/pdf.rs b/lib/src/pdf.rs index 07fb244..c102adf 100644 --- a/lib/src/pdf.rs +++ b/lib/src/pdf.rs @@ -258,88 +258,4 @@ fn split_to_max(s: &str, max: usize, blocksize: usize) -> Vec { // Add spaces return ans; -} - -#[cfg(test)] -mod tests { - - #[test] - fn test_qrcode_scale() { - use array2d::Array2D; - use qrcode::QrCode; - use crate::pdf::qrcode_scaled; - - let testdata = "This is some testdata"; - let code = QrCode::new(testdata.as_bytes()).unwrap(); - let width = code.width(); - - let factor = 10; - let padding = 10; - - let (scaled, size) = qrcode_scaled(testdata, factor); - let scaled_size = (width * factor)+(2*padding); - - assert_eq!(size, scaled_size); - - // 3 bytes per pixel - let scaled_qrcode = Array2D::from_row_major(&scaled, scaled_size, scaled_size*3); - - for i in 0..scaled_size { - for j in 0..scaled_size { - // The padding should be white - if i < padding || i >= (width*factor) + padding || - j < padding || j >= (width*factor) + padding { - for px in 0..3 { - assert_eq!(scaled_qrcode[(i, j*3+px)], 255u8); - } - } else { - // Should match the QR code module - let module_i = (i-padding)/factor; - let module_j = (j-padding)/factor; - - // This should really be (i,j), but I think there's a bug in the qrcode - // module that is returning it the other way. - let color = if code[(module_j, module_i)] == qrcode::Color::Light { - // Light color is white - 255u8 - } else { - // Dark color is black - 0u8 - }; - - for px in 0..3 { - assert_eq!(scaled_qrcode[(i, j*3+px)], color); - } - } - } - } - } - - #[test] - fn test_split() { - use crate::pdf::split_to_max; - assert_eq!(split_to_max("a", 1, 1).join("\n"), "a\n"); - - // Test the address splitting using max/blocksize we'll know we use - let addr = "ztestsapling1w00pdjthkzmzgut4c3y7hu6q6c8ferjczyvc03xwu0rvdgtre8a25em5w3w6jxghvcar5jzehnn"; - assert_eq!(split_to_max(addr, 44, 8).join("\n"), "ztestsap ling1w00 pdjthkzm zgut4c3y 7hu6q6c8 ferj\nczyvc03x wu0rvdgt re8a25em 5w3w6jxg hvcar5jz ehnn\n"); - assert_eq!(split_to_max(addr, 44, 8).join(" ").replace(" ", ""), addr); - assert_eq!(split_to_max(addr, 42, 8).join(" ").replace(" ", ""), addr); - assert_eq!(split_to_max(addr, 39, 39).join(" ").replace(" ", ""), addr); - - // Test the PK splitting using max/blocksize we'll know we use - let pk = "secret-extended-key-test1qj7vst8eqqqqqqpu2w6r0p2ykewm95h3d28k7r7y87e9p4v5zhzd4hj2y57clsprjveg997vqk7ak9tr2pnyyxmfzyzs6dhtuflt3aea9srp08teskpqfy2dtm07n08z3dyra407xumf3fk9ds4x06rzur7mgfyu39krj2g28lsxsxtv7swzu0j9vw4qf8rn5z72ztgeqj6u5zehylqm75c7d3um9ds9zvek4tdyta7qhln5fkc0dks6qwmkvr48fvgucpc3542kmdc97uqzt"; - assert_eq!(split_to_max(pk, 44, 8).join(" ").replace(" ", ""), pk); - assert_eq!(split_to_max(pk, 45, 10).join(" ").replace(" ", ""), pk); - assert_eq!(split_to_max(pk, 45, 45).join(" ").replace(" ", ""), pk); - - // Test random combinations of block size and spaces to ensure that - // the string is always preserved - for m in 1..100 { - for b in 1..40 { - assert_eq!(split_to_max(addr, m, b).join(" ").replace(" ", ""), addr); - assert_eq!(split_to_max(pk, m, b).join(" ").replace(" ", ""), pk); - } - } - } -} +} \ No newline at end of file From 3aa39502c9cc3747f5ab309341e936fe34501f32 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 22:49:25 +0200 Subject: [PATCH 11/31] Modify entropy information --- cli/src/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index d6fd44e..bc7422b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -115,7 +115,8 @@ fn main() { // If the user hasn't specified any, read from the stdin if matches.value_of("entropy").is_none() { // Read from stdin - println!("Provide additional entropy for generating random numbers. Type in a string of random characters, press [ENTER] when done"); + println!("Provide additional entropy for generating random numbers. +Type in a string of random characters, press [ENTER] when done."); let mut buffer = String::new(); let stdin = io::stdin(); stdin.lock().read_line(&mut buffer).unwrap(); From c77b5a2d513b1dd02c5fa0b5924f5afda7a9bd22 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 23:07:13 +0200 Subject: [PATCH 12/31] Bump version to 0.1.2 --- cli/Cargo.toml | 2 +- cli/src/version.rs | 2 +- lib/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index cf980ff..d3da2bb 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hushpaperwallet" -version = "0.1.1" +version = "0.1.2" authors = [ "ZecWallet", "The Hush developers" diff --git a/cli/src/version.rs b/cli/src/version.rs index 8f526cc..21ce270 100644 --- a/cli/src/version.rs +++ b/cli/src/version.rs @@ -1 +1 @@ -pub fn version() -> &'static str { &"0.1.1" } +pub fn version() -> &'static str { &"0.1.2" } diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 82efadc..8b10d45 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hushpaperlib" -version = "0.1.1" +version = "0.1.2" authors = [ "ZecWallet", "The Hush developers" From 84f63ca22d58943f1705d59277975ca86228ed6d Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 23:08:22 +0200 Subject: [PATCH 13/31] Standardization of address names 2 --- lib/src/pdf.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/pdf.rs b/lib/src/pdf.rs index c102adf..53e7559 100644 --- a/lib/src/pdf.rs +++ b/lib/src/pdf.rs @@ -189,7 +189,7 @@ fn add_pk_to_page(current_layer: &PdfLayerReference, font: &IndirectFontRef, fon } // Add the address a second time below the private key - let title = if is_taddr {"T Address"} else {"HUSH Address"}; + let title = if is_taddr {"HUSH t-address"} else {"HUSH z-address"}; current_layer.use_text(title, 12, Mm(10.0), Mm(ypos-10.0), &font_bold); let strs = split_to_max(&address, 39, 39); // No spaces, so user can copy the address for i in 0..strs.len() { From a715ec37ccad7f967f9b61987dcbff7830da34a3 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 23:48:28 +0200 Subject: [PATCH 14/31] Update private key address prefix --- lib/src/paper.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/paper.rs b/lib/src/paper.rs index 9728ae0..d29a589 100644 --- a/lib/src/paper.rs +++ b/lib/src/paper.rs @@ -58,7 +58,7 @@ pub struct CoinParams { pub fn params() -> CoinParams { CoinParams { taddress_version : [0x1C, 0xB8], - tsecret_prefix : [0x80], + tsecret_prefix : [0xBC], zaddress_prefix : "zs".to_string(), zsecret_prefix : "secret-extended-key-main".to_string(), zviewkey_prefix : "zviews".to_string(), From a2d44d9dd6f9a6b175907028daffc269f9584372 Mon Sep 17 00:00:00 2001 From: gilardh Date: Sat, 24 Oct 2020 23:50:44 +0200 Subject: [PATCH 15/31] Update Copyright in LICENSE file --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index edb5b11..ee52c97 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2019 adityapk00 +Copyright (c) 2020 The Hush developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 1e8ee5eace2bf2e22c5d894c607e00d38fe8e9bb Mon Sep 17 00:00:00 2001 From: gilardh Date: Sun, 25 Oct 2020 00:19:40 +0200 Subject: [PATCH 16/31] Correction of the generation of the t-address --- lib/src/paper.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/paper.rs b/lib/src/paper.rs index d29a589..7d7a851 100644 --- a/lib/src/paper.rs +++ b/lib/src/paper.rs @@ -47,7 +47,7 @@ pub fn double_sha256(payload: &[u8]) -> Vec { /// to get these values. /// Usually these will be different for testnet and for mainnet. pub struct CoinParams { - pub taddress_version: [u8; 2], + pub taddress_version: [u8; 1], pub tsecret_prefix : [u8; 1], pub zaddress_prefix : String, pub zsecret_prefix : String, @@ -57,7 +57,7 @@ pub struct CoinParams { pub fn params() -> CoinParams { CoinParams { - taddress_version : [0x1C, 0xB8], + taddress_version : [0x3c], tsecret_prefix : [0xBC], zaddress_prefix : "zs".to_string(), zsecret_prefix : "secret-extended-key-main".to_string(), From f19069e2ba2c78d6bae61d7ab3b0be443dba3da4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 19 Nov 2020 22:10:39 -0500 Subject: [PATCH 17/31] update links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5e64782..747eee5 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ You can run it on an air-gapped computer to generate your shielded z-addresses, ![screenshot](hushpaperwallet.png?raw=true) # Download -hushpaperwallet is available as pre-built binaries from our [release page](https://github.com/MyHush/hushpaperwallet/releases). Download the zip file for your platform, extract it and run the `./hushpaperwallet` binary. +hushpaperwallet is available as pre-built binaries from our [release page](https://git.hush.is/hush/hushpaperwallet/releases). Download the zip file for your platform, extract it and run the `./hushpaperwallet` binary. # Generating wallets To generate a Hush paper wallet, simply run `./hushpaperwallet` @@ -38,7 +38,7 @@ hushpaperwallet is built with rust. To compile from source, you [install Rust](h Checkout the hushpaperwallet repository and build the CLI ``` -git clone https://github.com/MyHush/hushpaperwallet.git +git clone https://git.hush.is/hush/hushpaperwallet cd hushpaperwallet/cli cargo build --release ``` From 017a587f17315ed160312f64cad51b643e470095 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 27 Nov 2020 06:49:53 -0500 Subject: [PATCH 18/31] SDP, yeah you know me --- README.md | 39 ++++++++++--------- hushpaperwallet.png => SilentDragonPaper.png | Bin 2 files changed, 20 insertions(+), 19 deletions(-) rename hushpaperwallet.png => SilentDragonPaper.png (100%) diff --git a/README.md b/README.md index 747eee5..ffe8813 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -# hushpaperwallet +# SilentDragonPaper -hushpaperwallet is a paper wallet generator that can run completely offline. +SilentDragonPaper is a paper wallet generator that can run completely offline. You can run it on an air-gapped computer to generate your shielded z-addresses, which will allow you to keep your keys completely offline. *Example:* -![screenshot](hushpaperwallet.png?raw=true) +![screenshot](SilentDragonPaper.png?raw=true) # Download -hushpaperwallet is available as pre-built binaries from our [release page](https://git.hush.is/hush/hushpaperwallet/releases). Download the zip file for your platform, extract it and run the `./hushpaperwallet` binary. +SilentDragonPaper is available as pre-built binaries from our [release page](https://git.hush.is/hush/SilentDragonPaper/releases). Download the zip file for your platform, extract it and run the `./SilentDragonPaper` binary. # Generating wallets -To generate a Hush paper wallet, simply run `./hushpaperwallet` +To generate a Hush paper wallet, simply run `./SilentDragonPaper` You'll be asked to type some random characters that will add entropy to the random number generator. Run with `--help` to see all options @@ -20,10 +20,10 @@ You'll be asked to type some random characters that will add entropy to the rand To generate a Hush paper wallet and save it as a PDF, run ``` -./hushpaperwallet -z 3 --format pdf hushpaper-output.pdf +./SilentDragonPaper -z 3 --format pdf sdp.pdf ``` -This will generate 3 shielded z-addresses and their corresponding private keys, and save them in a PDF file called `hushpaper-output.pdf` +This will generate 3 shielded z-addresses and their corresponding private keys, and save them in a PDF file called `sdp.pdf` ## Vanity Addresses @@ -33,13 +33,13 @@ Note that generating vanity addresses with a prefix longer than 4-5 characters i # Compiling from Source -hushpaperwallet is built with rust. To compile from source, you [install Rust](https://www.rust-lang.org/tools/install). +SilentDragonPaper is built with rust. To compile from source, you [install Rust](https://www.rust-lang.org/tools/install). -Checkout the hushpaperwallet repository and build the CLI +Checkout the SilentDragonPaper repository and build the CLI ``` -git clone https://git.hush.is/hush/hushpaperwallet -cd hushpaperwallet/cli +git clone https://git.hush.is/hush/SilentDragonPaper +cd SilentDragonPaper/cli cargo build --release ``` @@ -49,30 +49,31 @@ The binary is available in the `target/release` folder. When generating paper wallets that will store large amounts of crypto, please take special care to ensure the keys are generated and kept completely offline. -1. `hushpaperwallet` supports ARMv8 (Raspberry Pi 3+). You can put one in a Faraday cage along with a printer, and print out the PDFs securely. -2. Please ensure you supply random entropy when you run `hushpaperwallet`. Your entropy is mixed in with system-provided entropy to generate keys +1. `SilentDragonPaper` supports ARMv8 (Raspberry Pi 3+). You can put one in a Faraday cage along with a printer, and print out the PDFs securely. +2. Please ensure you supply random entropy when you run `SilentDragonPaper`. Your entropy is mixed in with system-provided entropy to generate keys 3. If you can, run with `unshare`, which will disable all network interfaces to a process, providing you with an additional layer of safety. (See next section) 4. After you've generated the keys, you can tear off the Address potion of the wallet and take it to your online computer/phone to send the address funds. Please always keep the private key offline. 5. When you're ready to spend the cold storage keys, import the private key into a full node, then don't re-use the key again. ### Run without network -If you are running a newish version of Linux, you can be doubly sure that the process is not contacting the network by running hushpaperwallet without the network namespace. +If you are running a newish version of Linux, you can be doubly sure that the process is not contacting the network by running SilentDragonPaper without the network namespace. ``` -sudo unshare -n ./target/release/hushpaperwallet +sudo unshare -n ./target/release/SilentDragonPaper ``` `unshare -n` runs the process without a network interface which means you can be sure that your data is not being sent across the network. ## Help options + ``` USAGE: - hushpaperwallet [FLAGS] [OPTIONS] [output] + SilentDragonPaper [FLAGS] [OPTIONS] [output] FLAGS: -h, --help Prints help information - -n, --nohd Don't reuse HD keys. Normally, hushpaperwallet will use the same HD key to derive multiple + -n, --nohd Don't reuse HD keys. Normally, SilentDragonPaper will use the same HD key to derive multiple addresses. This flag will use a new seed for each address -V, --version Prints version information @@ -93,13 +94,13 @@ ARGS: ## Copyright -Released under the GNU Public License Version 3. +Released under the GNU Public License Version 3 or later. Copyright (c) 2019-2020 The Hush Developers Copyright (c) 2019 adityapk00 ## License -GPLv3. +GPLv3 or later. See [LICENSE] file for details. diff --git a/hushpaperwallet.png b/SilentDragonPaper.png similarity index 100% rename from hushpaperwallet.png rename to SilentDragonPaper.png From 805aa90130a1c73269f25853294b5b5d16f09998 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 27 Nov 2020 06:57:24 -0500 Subject: [PATCH 19/31] bump version and rebrand --- cli/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index d3da2bb..4db95e2 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "hushpaperwallet" -version = "0.1.2" +name = "SilentDragonPaper" +version = "0.2.0" authors = [ "ZecWallet", "The Hush developers" @@ -11,4 +11,4 @@ edition = "2018" clap = "2.33.0" hushpaperlib = { path = "../lib" } json = "0.11.14" -printpdf = "0.3.2" \ No newline at end of file +printpdf = "0.3.2" From 12c7d1ca04aaff7da966ccd950ddb707610c3cf3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 27 Nov 2020 06:57:42 -0500 Subject: [PATCH 20/31] Rename app in source code and error message --- cli/src/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index bc7422b..a188ee2 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -10,7 +10,7 @@ use std::io; use std::io::prelude::*; fn main() { - let matches = App::new("hushpaperwaller") + let matches = App::new("SilentDragonPaper") .version(version::version()) .about("A command line Hush paper wallet generator") .arg(Arg::with_name("format") @@ -24,7 +24,7 @@ fn main() { .arg(Arg::with_name("nohd") .short("n") .long("nohd") - .help("Don't reuse HD keys. Normally, hushpaperwallet will use the same HD key to derive multiple addresses. This flag will use a new seed for each address")) + .help("Don't reuse HD keys. Normally, SilentDragonPaper will use the same HD key to derive multiple addresses. This flag will use a new seed for each address")) .arg(Arg::with_name("output") .short("o") .long("output") @@ -155,4 +155,4 @@ Type in a string of random characters, press [ENTER] when done."); } }; } -} \ No newline at end of file +} From 998ae7c19fcf1e86d72365704f75404ac20dc45b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 6 Jan 2021 20:39:23 -0500 Subject: [PATCH 21/31] update --- cli/mkrelease.sh | 58 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/cli/mkrelease.sh b/cli/mkrelease.sh index 93c1580..64e96df 100755 --- a/cli/mkrelease.sh +++ b/cli/mkrelease.sh @@ -32,58 +32,58 @@ cargo clean cargo build --release # macOS -rm -rf target/macOS-hushpaperwallet-v$APP_VERSION -mkdir -p target/macOS-hushpaperwallet-v$APP_VERSION -cp target/release/hushpaperwallet target/macOS-hushpaperwallet-v$APP_VERSION/ +rm -rf target/macOS-silentdragonpaper-v$APP_VERSION +mkdir -p target/macOS-silentdragonpaper-v$APP_VERSION +cp target/release/silentdragonpaper target/macOS-silentdragonpaper-v$APP_VERSION/ # For Windows and Linux, build via docker -docker run --rm -v $(pwd)/..:/opt/hushpaperwallet rustbuild:latest bash -c "cd /opt/hushpaperwallet/cli && cargo build --release && cargo build --release --target x86_64-pc-windows-gnu && cargo build --release --target aarch64-unknown-linux-gnu" +docker run --rm -v $(pwd)/..:/opt/silentdragonpaper rustbuild:latest bash -c "cd /opt/silentdragonpaper/cli && cargo build --release && cargo build --release --target x86_64-pc-windows-gnu && cargo build --release --target aarch64-unknown-linux-gnu" # Now sign and zip the binaries -gpg --batch --output target/macOS-hushpaperwallet-v$APP_VERSION/hushpaperwallet.sig --detach-sig target/macOS-hushpaperwallet-v$APP_VERSION/hushpaperwallet +gpg --batch --output target/macOS-silentdragonpaper-v$APP_VERSION/silentdragonpaper.sig --detach-sig target/macOS-silentdragonpaper-v$APP_VERSION/silentdragonpaper cd target -cd macOS-hushpaperwallet-v$APP_VERSION -gsha256sum hushpaperwallet > sha256sum.txt +cd macOS-silentdragonpaper-v$APP_VERSION +gsha256sum silentdragonpaper > sha256sum.txt cd .. -zip -r macOS-hushpaperwallet-v$APP_VERSION.zip macOS-hushpaperwallet-v$APP_VERSION +zip -r macOS-silentdragonpaper-v$APP_VERSION.zip macOS-silentdragonpaper-v$APP_VERSION cd .. #Linux -rm -rf target/linux-hushpaperwallet-v$APP_VERSION -mkdir -p target/linux-hushpaperwallet-v$APP_VERSION -cp target/release/hushpaperwallet target/linux-hushpaperwallet-v$APP_VERSION/ -gpg --batch --output target/linux-hushpaperwallet-v$APP_VERSION/hushpaperwallet.sig --detach-sig target/linux-hushpaperwallet-v$APP_VERSION/hushpaperwallet +rm -rf target/linux-silentdragonpaper-v$APP_VERSION +mkdir -p target/linux-silentdragonpaper-v$APP_VERSION +cp target/release/silentdragonpaper target/linux-silentdragonpaper-v$APP_VERSION/ +gpg --batch --output target/linux-silentdragonpaper-v$APP_VERSION/silentdragonpaper.sig --detach-sig target/linux-silentdragonpaper-v$APP_VERSION/silentdragonpaper cd target -cd linux-hushpaperwallet-v$APP_VERSION -gsha256sum hushpaperwallet > sha256sum.txt +cd linux-silentdragonpaper-v$APP_VERSION +gsha256sum silentdragonpaper > sha256sum.txt cd .. -zip -r linux-hushpaperwallet-v$APP_VERSION.zip linux-hushpaperwallet-v$APP_VERSION +zip -r linux-silentdragonpaper-v$APP_VERSION.zip linux-silentdragonpaper-v$APP_VERSION cd .. #Windows -rm -rf target/Windows-hushpaperwallet-v$APP_VERSION -mkdir -p target/Windows-hushpaperwallet-v$APP_VERSION -cp target/x86_64-pc-windows-gnu/release/hushpaperwallet.exe target/Windows-hushpaperwallet-v$APP_VERSION/ -gpg --batch --output target/Windows-hushpaperwallet-v$APP_VERSION/hushpaperwallet.sig --detach-sig target/Windows-hushpaperwallet-v$APP_VERSION/hushpaperwallet.exe +rm -rf target/Windows-silentdragonpaper-v$APP_VERSION +mkdir -p target/Windows-silentdragonpaper-v$APP_VERSION +cp target/x86_64-pc-windows-gnu/release/silentdragonpaper.exe target/Windows-silentdragonpaper-v$APP_VERSION/ +gpg --batch --output target/Windows-silentdragonpaper-v$APP_VERSION/silentdragonpaper.sig --detach-sig target/Windows-silentdragonpaper-v$APP_VERSION/silentdragonpaper.exe cd target -cd Windows-hushpaperwallet-v$APP_VERSION -gsha256sum hushpaperwallet.exe > sha256sum.txt +cd Windows-silentdragonpaper-v$APP_VERSION +gsha256sum silentdragonpaper.exe > sha256sum.txt cd .. -zip -r Windows-hushpaperwallet-v$APP_VERSION.zip Windows-hushpaperwallet-v$APP_VERSION +zip -r Windows-silentdragonpaper-v$APP_VERSION.zip Windows-silentdragonpaper-v$APP_VERSION cd .. # aarch64 (armv8) -rm -rf target/aarch64-hushpaperwallet-v$APP_VERSION -mkdir -p target/aarch64-hushpaperwallet-v$APP_VERSION -cp target/aarch64-unknown-linux-gnu/release/hushpaperwallet target/aarch64-hushpaperwallet-v$APP_VERSION/ -gpg --batch --output target/aarch64-hushpaperwallet-v$APP_VERSION/hushpaperwallet.sig --detach-sig target/aarch64-hushpaperwallet-v$APP_VERSION/hushpaperwallet +rm -rf target/aarch64-silentdragonpaper-v$APP_VERSION +mkdir -p target/aarch64-silentdragonpaper-v$APP_VERSION +cp target/aarch64-unknown-linux-gnu/release/silentdragonpaper target/aarch64-silentdragonpaper-v$APP_VERSION/ +gpg --batch --output target/aarch64-silentdragonpaper-v$APP_VERSION/silentdragonpaper.sig --detach-sig target/aarch64-silentdragonpaper-v$APP_VERSION/silentdragonpaper cd target -cd aarch64-hushpaperwallet-v$APP_VERSION -gsha256sum hushpaperwallet > sha256sum.txt +cd aarch64-silentdragonpaper-v$APP_VERSION +gsha256sum silentdragonpaper > sha256sum.txt cd .. -zip -r aarch64-hushpaperwallet-v$APP_VERSION.zip aarch64-hushpaperwallet-v$APP_VERSION +zip -r aarch64-silentdragonpaper-v$APP_VERSION.zip aarch64-silentdragonpaper-v$APP_VERSION cd .. From 6ca5dc40111ab205557b40cccf45b0597e2746f4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 6 Jan 2021 20:43:30 -0500 Subject: [PATCH 22/31] add build script --- build.sh | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..3e14d11 --- /dev/null +++ b/build.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Copyright (c) 2016-2020 The Hush developers +# Distributed under the GPLv3 software license, see the accompanying +# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html + +set -eu -o pipefail +cd cli +cargo build --release From bd40b9d8b1a7d055f2ccef753b02e7fc90ff68a5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 6 Jan 2021 21:12:58 -0500 Subject: [PATCH 23/31] Various updates --- cli/Cargo.toml | 2 +- cli/src/main.rs | 6 +++--- lib/Cargo.toml | 10 +++++----- ui/qtlib/Cargo.toml | 2 +- ui/qtlib/src/lib.rs | 2 +- ui/src/about.ui | 10 ++++++---- ui/src/main.cpp | 9 ++++++--- ui/src/mainwindow.cpp | 14 ++++++-------- 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 4db95e2..cbad35c 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -9,6 +9,6 @@ edition = "2018" [dependencies] clap = "2.33.0" -hushpaperlib = { path = "../lib" } +silentdragonpaper = { path = "../lib" } json = "0.11.14" printpdf = "0.3.2" diff --git a/cli/src/main.rs b/cli/src/main.rs index a188ee2..510c320 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,11 +1,11 @@ extern crate clap; -extern crate hushpaperlib; +extern crate silentdragonpaperlib; mod version; use clap::{Arg, App}; -use hushpaperlib::paper::*; -use hushpaperlib::pdf; +use silentdragonpaperlib::paper::*; +use silentdragonpaperlib::pdf; use std::io; use std::io::prelude::*; diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 8b10d45..8530587 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "hushpaperlib" -version = "0.1.2" +name = "silentdragonpaper" +version = "0.2.0" authors = [ - "ZecWallet", - "The Hush developers" + "The Hush developers", + "ZecWallet" ] edition = "2018" @@ -14,7 +14,7 @@ default = ["printpdf"] rand = "0.5" hex = "0.3" bech32 = "0.6" -zcash_primitives = { git = "https://github.com/gilardh/librustzcash", rev = "5a48d179b8434a0318e7e19dda506e245a904092" } +zcash_primitives = { git = "https://git.hush.is/hush/librustzcash", rev = "5a48d179b8434a0318e7e19dda506e245a904092" } json = "0.11.14" qrcode = { version = "0.8", default-features = false } printpdf = { version = "0.3.2", optional = true } diff --git a/ui/qtlib/Cargo.toml b/ui/qtlib/Cargo.toml index 31cbe8f..b8a1ea4 100644 --- a/ui/qtlib/Cargo.toml +++ b/ui/qtlib/Cargo.toml @@ -10,4 +10,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" -hushpaperlib = { path = "../../lib" } \ No newline at end of file +silentdragonpaperlib = { path = "../../lib" } \ No newline at end of file diff --git a/ui/qtlib/src/lib.rs b/ui/qtlib/src/lib.rs index b0a9738..d2c552f 100644 --- a/ui/qtlib/src/lib.rs +++ b/ui/qtlib/src/lib.rs @@ -1,6 +1,6 @@ use libc::{c_char}; use std::ffi::{CStr, CString}; -use hushpaperlib::{pdf, paper}; +use silentdragonpaperlib::{pdf, paper}; /** * Call into rust to generate a paper wallet. Returns the paper wallet in JSON form. diff --git a/ui/src/about.ui b/ui/src/about.ui index cb49598..4bbfdd9 100644 --- a/ui/src/about.ui +++ b/ui/src/about.ui @@ -11,7 +11,7 @@ - About hushpaperwallet + About SilentDragonPaper @@ -42,7 +42,9 @@ - <html><head/><body><pre style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">MIT License</span></pre><pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br/></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Copyright (c) 2019 Aditya Kulkarni</span></pre><pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br/></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">Permission is hereby granted, free of charge, to any person obtaining a copy</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">of this software and associated documentation files (the &quot;Software&quot;), to deal</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">in the Software without restriction, including without limitation the rights</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">copies of the Software, and to permit persons to whom the Software is</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">furnished to do so, subject to the following conditions:</span></pre><pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br/></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">The above copyright notice and this permission notice shall be included in all</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">copies or substantial portions of the Software.</span></pre><pre style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'monospace';"><br/></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span></pre><pre style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE</span></pre><pre style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'monospace';">SOFTWARE.</span></pre></body></html> + +GPLv3 FREE SOFTWARE + Qt::RichText @@ -59,13 +61,13 @@ - hushpaperwallet + SilentDragonPaper - hushpaperwallet version 1.0(6 May 2009) + SilentDragonPaper diff --git a/ui/src/main.cpp b/ui/src/main.cpp index 8c5d264..2871fc9 100644 --- a/ui/src/main.cpp +++ b/ui/src/main.cpp @@ -1,3 +1,6 @@ +// Copyright (c) 2016-2020 The Hush developers +// Distributed under the GPLv3 software license, see the accompanying +// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #include "mainwindow.h" #include "version.h" #include @@ -7,8 +10,8 @@ int main(int argc, char *argv[]) QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QCoreApplication::setOrganizationDomain("hushwallet.co"); - QCoreApplication::setOrganizationName("hushpaperwallet"); + QCoreApplication::setOrganizationDomain("hush.is"); + QCoreApplication::setOrganizationName("Hush"); #ifdef Q_OS_LINUX QFontDatabase::addApplicationFont(":/fonts/res/Ubuntu-R.ttf"); @@ -18,7 +21,7 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); MainWindow w; - w.setWindowTitle(QString("hushpaperwallet ") + APP_VERSION); + w.setWindowTitle(QString("Extreme Privacy: SilentDragonPaper ") + APP_VERSION); w.show(); diff --git a/ui/src/mainwindow.cpp b/ui/src/mainwindow.cpp index 11d9560..7849e73 100644 --- a/ui/src/mainwindow.cpp +++ b/ui/src/mainwindow.cpp @@ -1,13 +1,13 @@ +// Copyright (c) 2016-2020 The Hush developers +// Distributed under the GPLv3 software license, see the accompanying +// file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html #include - #include "precompiled.h" - #include "mainwindow.h" #include "version.h" #include "ui_mainwindow.h" #include "ui_wallet.h" #include "ui_about.h" - #include "hushpaperrust.h" void SaveRestore(QDialog* d) { @@ -33,9 +33,7 @@ QString SplitIntoLines(QString s, int maxlen) { return ans.join("\n"); } -/** - * Add a wallet (address + pk) section to the given vertical layout - */ +// Add a wallet (address + pk) section to the given vertical layout void AddWallet(QString address, QString pk, QWidget* scroll) { Ui_WalletWidget w; auto g1 = new QGroupBox(scroll); @@ -172,7 +170,7 @@ MainWindow::MainWindow(QWidget *parent) : // Help site QObject::connect(ui->actionHelp_site, &QAction::triggered, [=]() { - QDesktopServices::openUrl(QUrl("https://docs.hushwallet.co/paper")); + QDesktopServices::openUrl(QUrl("https://faq.hush.is/sdp")); }); // About button @@ -180,7 +178,7 @@ MainWindow::MainWindow(QWidget *parent) : QDialog ad(this); Ui_AboutDialog d; d.setupUi(&ad); - d.lblVersion->setText(QString("hushpaperwallet ") + APP_VERSION + "(" + APP_BUILD_DATE + ")"); + d.lblVersion->setText(QString("SilentDragonPaper ") + APP_VERSION + "(" + APP_BUILD_DATE + ")"); SaveRestore(&ad); ad.exec(); From 65c2306b490b67f029667c949ace17460af40f1f Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 8 Jan 2021 04:34:53 -0500 Subject: [PATCH 24/31] Stuff --- lib/src/paper.rs | 4 ++-- lib/src/pdf.rs | 4 ++-- ui/mkdockerwinlinux.sh | 20 ++++++++++---------- ui/papersapling.pro | 12 ------------ ui/qtlib/Cargo.toml | 4 ++-- ui/qtlib/Makefile | 12 ++++++------ 6 files changed, 22 insertions(+), 34 deletions(-) diff --git a/lib/src/paper.rs b/lib/src/paper.rs index 7d7a851..f90a52f 100644 --- a/lib/src/paper.rs +++ b/lib/src/paper.rs @@ -43,7 +43,7 @@ pub fn double_sha256(payload: &[u8]) -> Vec { h2.to_vec() } -/// Parameters used to generate addresses and private keys. Look in chainparams.cpp (in zcashd/src) +/// Parameters used to generate addresses and private keys. Look in chainparams.cpp in hush3.git /// to get these values. /// Usually these will be different for testnet and for mainnet. pub struct CoinParams { @@ -438,4 +438,4 @@ fn get_zaddress(seed: &[u8], index: u32) -> (String, String, String, json::JsonV let encoded_vk = Bech32::new(params().zviewkey_prefix.into(), c_v).expect("bech32 failed").to_string(); return (encoded, encoded_pk, encoded_vk, path); -} \ No newline at end of file +} diff --git a/lib/src/pdf.rs b/lib/src/pdf.rs index 53e7559..883b323 100644 --- a/lib/src/pdf.rs +++ b/lib/src/pdf.rs @@ -16,7 +16,7 @@ use printpdf::*; * Save the list of wallets (address + private keys) to the given PDF file name. */ pub fn save_to_pdf(addresses: &str, filename: &str) -> Result<(), String> { - let (doc, page1, layer1) = PdfDocument::new("Hush Paper Wallet", Mm(210.0), Mm(297.0), "Layer 1"); + let (doc, page1, layer1) = PdfDocument::new("SilentDragonPaper Wallet", Mm(210.0), Mm(297.0), "Layer 1"); let font = doc.add_builtin_font(BuiltinFont::Courier).unwrap(); let font_bold = doc.add_builtin_font(BuiltinFont::CourierBold).unwrap(); @@ -258,4 +258,4 @@ fn split_to_max(s: &str, max: usize, blocksize: usize) -> Vec { // Add spaces return ans; -} \ No newline at end of file +} diff --git a/ui/mkdockerwinlinux.sh b/ui/mkdockerwinlinux.sh index 8edad98..d58e42e 100755 --- a/ui/mkdockerwinlinux.sh +++ b/ui/mkdockerwinlinux.sh @@ -29,30 +29,30 @@ if [ -z $APP_VERSION ]; then exit 1; fi -cd /opt/hushpaperwallet/ui +cd /opt/silentdragonpaper/ui source ~/.cargo/env # We need to run qmake before we run disclean /opt/Qt/5.11.2/static/bin/qmake papersapling.pro CONFIG+=release make distclean -rm -rf artifacts/linux-hushpaperwallet-v$APP_VERSION -mkdir -p artifacts/linux-hushpaperwallet-v$APP_VERSION +rm -rf artifacts/linux-silentdragonpaper-v$APP_VERSION +mkdir -p artifacts/linux-silentdragonpaper-v$APP_VERSION /opt/Qt/5.11.2/static/bin/qmake papersapling.pro CONFIG+=release make -j4 -strip hushpaperwalletui -cp hushpaperwalletui artifacts/linux-hushpaperwallet-v$APP_VERSION +strip silentdragonpaperui +cp silentdragonpaperui artifacts/linux-silentdragonpaper-v$APP_VERSION # Run qmake before distclean /opt/mxe/usr/bin/x86_64-w64-mingw32.static-qmake-qt5 papersapling.pro CONFIG+=release make distclean -rm -rf artifacts/Windows-hushpaperwallet-v$APP_VERSION -mkdir -p artifacts/Windows-hushpaperwallet-v$APP_VERSION +rm -rf artifacts/Windows-silentdragonpaper-v$APP_VERSION +mkdir -p artifacts/Windows-silentdragonpaper-v$APP_VERSION /opt/mxe/usr/bin/x86_64-w64-mingw32.static-qmake-qt5 papersapling.pro CONFIG+=release make -j4 -strip release/hushpaperwalletui.exe -cp release/hushpaperwalletui.exe artifacts/Windows-hushpaperwallet-v$APP_VERSION +strip release/silentdragonpaperui.exe +cp release/silentdragonpaperui.exe artifacts/Windows-silentdragonpaper-v$APP_VERSION # Cleanup before exiting -make distclean \ No newline at end of file +make distclean diff --git a/ui/papersapling.pro b/ui/papersapling.pro index 5ebc82a..61667c3 100644 --- a/ui/papersapling.pro +++ b/ui/papersapling.pro @@ -14,21 +14,9 @@ TEMPLATE = app MOC_DIR = bin OBJECTS_DIR = bin UI_DIR = src - - -# The following define makes your compiler emit warnings if you use -# any feature of Qt which has been marked as deprecated (the exact warnings -# depend on your compiler). Please consult the documentation of the -# deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS -# You can also make your code fail to compile if you use deprecated APIs. -# In order to do so, uncomment the following line. -# You can also select to disable deprecated APIs only up to a certain version of Qt. -#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 - CONFIG += c++14 - CONFIG += precompile_header PRECOMPILED_HEADER = src/precompiled.h diff --git a/ui/qtlib/Cargo.toml b/ui/qtlib/Cargo.toml index b8a1ea4..1e47ba3 100644 --- a/ui/qtlib/Cargo.toml +++ b/ui/qtlib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "qtlib" version = "0.1.0" -authors = ["ZecWallet"] +authors = ["The Hush Developers", "ZecWallet"] edition = "2018" [lib] @@ -10,4 +10,4 @@ crate-type = ["staticlib"] [dependencies] libc = "0.2.58" -silentdragonpaperlib = { path = "../../lib" } \ No newline at end of file +silentdragonpaperlib = { path = "../../lib" } diff --git a/ui/qtlib/Makefile b/ui/qtlib/Makefile index 992a8eb..fae8b6b 100644 --- a/ui/qtlib/Makefile +++ b/ui/qtlib/Makefile @@ -6,18 +6,18 @@ endif all: release -winrelease: target/x86_64-pc-windows-gnu/release/zecpaperrust.lib +winrelease: target/x86_64-pc-windows-gnu/release/silentdragonpaper.lib -target/x86_64-pc-windows-gnu/release/zecpaperrust.lib: src/lib.rs Cargo.toml +target/x86_64-pc-windows-gnu/release/silentdragonpaper.lib: src/lib.rs Cargo.toml cargo build --lib --release --target x86_64-pc-windows-gnu -release: target/release/zecpaperrust.$(EXT) -debug: target/debug/zecpaperrust.$(EXT) +release: target/release/silentdragonpaper.$(EXT) +debug: target/debug/silentdragonpaper.$(EXT) -target/release/zecpaperrust.$(EXT): src/lib.rs Cargo.toml +target/release/silentdragonpaper.$(EXT): src/lib.rs Cargo.toml cargo build --lib --release -target/debug/zecpaperrust.$(EXT): src/lib.rs Cargo.toml +target/debug/silentdragonpaper.$(EXT): src/lib.rs Cargo.toml cargo build --lib clean: From 777ee7f6c917a3e7b3d504aec2a67b0335fe8a7c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 8 Jan 2021 06:05:09 -0500 Subject: [PATCH 25/31] Pin our version of Rust to 1.37.0 in our build system, which mostly works --- build.sh | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 3e14d11..d63b8d7 100755 --- a/build.sh +++ b/build.sh @@ -4,5 +4,28 @@ # file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html set -eu -o pipefail -cd cli -cargo build --release + +# TODO: find elite Rust coders to update our shit +# to work on modern versions of rustc, lulz + +PREFIX=rust-1.37.0-x86_64-unknown-linux-gnu +FILE=$PREFIX.tar.gz + +if [ ! -f "$FILE" ]; then + wget https://static.rust-lang.org/dist/$FILE +fi + +#TODO: verify SHA256 +# cb573229bfd32928177c3835fdeb62d52da64806b844bc1095c6225b0665a1cb rust-1.37.0-x86_64-unknown-linux-gnu.tar.gz + +tar zxvpf $FILE +mkdir -p build +cd $PREFIX +./install.sh --prefix=$(pwd)/../build + +cd ../cli +PATH=$(pwd)/../build/bin/:$PATH +echo PATH=$PATH +cargo --version +rustc --version +../build/bin/cargo build --verbose --release From b8ee2896fda8922017543e56e8d46aa9cd860e97 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Mon, 11 Jan 2021 03:33:25 -0500 Subject: [PATCH 26/31] SDP is now working, so up-rev. README updated with two source code build methods and improved layout. Embedded rust updated to 1.48 --- AUTHORS | 1 + README.md | 60 ++++++++++++++++++++++++++++++---------------- build.sh | 6 ++--- cli/src/main.rs | 6 ++--- cli/src/version.rs | 2 +- lib/src/pdf.rs | 20 ++++++++-------- 6 files changed, 57 insertions(+), 38 deletions(-) diff --git a/AUTHORS b/AUTHORS index 0e91b7c..64cc5c6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,4 @@ # The Hush Developers Duke Leto https://github.com/leto +Jah Way https://git.hush.is/jahway603 https://github.com/jahway603 diff --git a/README.md b/README.md index ffe8813..d9f0067 100644 --- a/README.md +++ b/README.md @@ -8,42 +8,60 @@ You can run it on an air-gapped computer to generate your shielded z-addresses, ![screenshot](SilentDragonPaper.png?raw=true) -# Download -SilentDragonPaper is available as pre-built binaries from our [release page](https://git.hush.is/hush/SilentDragonPaper/releases). Download the zip file for your platform, extract it and run the `./SilentDragonPaper` binary. +## Download -# Generating wallets -To generate a Hush paper wallet, simply run `./SilentDragonPaper` +### Binary installation +SilentDragonPaper is available as pre-built binaries from our [release page](https://git.hush.is/hush/SilentDragonPaper/releases). Download the zip file for your platform, extract it and run the `./SilentDragonPaper` binary. -You'll be asked to type some random characters that will add entropy to the random number generator. Run with `--help` to see all options +### Source code installation +If you decide to compile from source, then first use git to get the source code as follows: + +``` +git clone https://git.hush.is/hush/SilentDragonPaper +``` + +Then choose one of these two source compilation options to build the SilentDragonPaper CLI. -## Saving as PDFs -To generate a Hush paper wallet and save it as a PDF, run +#### Option 1: Compile using system installed rust +SilentDragonPaper is built with rust. To compile from source, you [install Rust](https://www.rust-lang.org/tools/install). ``` -./SilentDragonPaper -z 3 --format pdf sdp.pdf +cd SilentDragonPaper/cli +cargo build --release ``` -This will generate 3 shielded z-addresses and their corresponding private keys, and save them in a PDF file called `sdp.pdf` +#### Option 2: Compile using "embedded" rust +Here we do need a system installed rust to compile. -## Vanity Addresses +``` +cd SilentDragonPaper/cli +./build.sh +``` -You can generate a "vanity address" (that is, an address starting with a given prefix) by specifying a `--vanity` argument with the prefix you want. +#### Compiled binary location +The binary is available in the `target/release` folder. -Note that generating vanity addresses with a prefix longer than 4-5 characters is computationally expensive. You can run it on multiple CPUs on your computer by specifying the `--threads` option. +## Usage Instructions -# Compiling from Source +### Generating wallets +To generate a Hush paper wallet, simply run `./SilentDragonPaper` or `./target/release/SilentDragonPaper` or `./cli/target/release/SilentDragonPaper` depending on method you used to install. -SilentDragonPaper is built with rust. To compile from source, you [install Rust](https://www.rust-lang.org/tools/install). +You'll be asked to type some random characters that will add entropy to the random number generator. Run with `--help` to see all options -Checkout the SilentDragonPaper repository and build the CLI +### Saving as PDFs +To generate a Hush paper wallet and save it as a PDF, run: ``` -git clone https://git.hush.is/hush/SilentDragonPaper -cd SilentDragonPaper/cli -cargo build --release +./SilentDragonPaper -z 3 --format pdf sdp.pdf ``` -The binary is available in the `target/release` folder. +This will generate 3 shielded z-addresses and their corresponding private keys, and save them in a PDF file called `sdp.pdf` + +### Vanity Addresses + +You can generate a "vanity address" (that is, an address starting with a given prefix) by specifying a `--vanity` argument with the prefix you want. + +Note that generating vanity addresses with a prefix longer than 4-5 characters is computationally expensive. You can run it on multiple CPUs on your computer by specifying the `--threads` option. ## Ensuring Security @@ -96,11 +114,11 @@ ARGS: Released under the GNU Public License Version 3 or later. -Copyright (c) 2019-2020 The Hush Developers +Copyright (c) 2019-2021 The Hush Developers Copyright (c) 2019 adityapk00 ## License GPLv3 or later. -See [LICENSE] file for details. +See [LICENSE](LICENSE) file for details. diff --git a/build.sh b/build.sh index d63b8d7..bb5f08d 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,5 @@ #!/bin/bash -# Copyright (c) 2016-2020 The Hush developers +# Copyright (c) 2016-2021 The Hush developers # Distributed under the GPLv3 software license, see the accompanying # file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html @@ -8,7 +8,7 @@ set -eu -o pipefail # TODO: find elite Rust coders to update our shit # to work on modern versions of rustc, lulz -PREFIX=rust-1.37.0-x86_64-unknown-linux-gnu +PREFIX=rust-1.48.0-x86_64-unknown-linux-gnu FILE=$PREFIX.tar.gz if [ ! -f "$FILE" ]; then @@ -16,7 +16,7 @@ if [ ! -f "$FILE" ]; then fi #TODO: verify SHA256 -# cb573229bfd32928177c3835fdeb62d52da64806b844bc1095c6225b0665a1cb rust-1.37.0-x86_64-unknown-linux-gnu.tar.gz +# 950420a35b2dd9091f1b93a9ccd5abc026ca7112e667f246b1deb79204e2038b rust-1.48.0-x86_64-unknown-linux-gnu.tar.gz tar zxvpf $FILE mkdir -p build diff --git a/cli/src/main.rs b/cli/src/main.rs index 510c320..564d21e 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,11 +1,11 @@ extern crate clap; -extern crate silentdragonpaperlib; +extern crate silentdragonpaper; mod version; use clap::{Arg, App}; -use silentdragonpaperlib::paper::*; -use silentdragonpaperlib::pdf; +use silentdragonpaper::paper::*; +use silentdragonpaper::pdf; use std::io; use std::io::prelude::*; diff --git a/cli/src/version.rs b/cli/src/version.rs index 21ce270..25ce646 100644 --- a/cli/src/version.rs +++ b/cli/src/version.rs @@ -1 +1 @@ -pub fn version() -> &'static str { &"0.1.2" } +pub fn version() -> &'static str { &"0.1.3" } diff --git a/lib/src/pdf.rs b/lib/src/pdf.rs index 883b323..7886fee 100644 --- a/lib/src/pdf.rs +++ b/lib/src/pdf.rs @@ -78,8 +78,8 @@ pub fn save_to_pdf(addresses: &str, filename: &str) -> Result<(), String> { current_layer.set_outline_thickness(2.0); // Set title - current_layer.use_text("Speak and Transact Freely", 32, Mm(19.0), Mm(277.0), &font_bold); - current_layer.use_text("Private Cryptocurrency and Messenger on Zero Knowledge Proof Encryption", 13, Mm(7.0), Mm(266.0), &font_bold); + current_layer.use_text("Speak and Transact Freely", 32f64, Mm(19.0), Mm(277.0), &font_bold); + current_layer.use_text("Private Cryptocurrency and Messenger on Zero Knowledge Proof Encryption", 13f64, Mm(7.0), Mm(266.0), &font_bold); // Draw lines current_layer.add_shape(line1); @@ -144,7 +144,7 @@ fn qrcode_scaled(data: &str, scalefactor: usize) -> (Vec, usize) { * Add a footer at the bottom of the page */ fn add_footer_to_page(current_layer: &PdfLayerReference, font: &IndirectFontRef, footer: &str) { - current_layer.use_text(footer, 10, Mm(5.0), Mm(5.0), &font); + current_layer.use_text(footer, 10f64, Mm(5.0), Mm(5.0), &font); } @@ -163,11 +163,11 @@ fn add_address_to_page(current_layer: &PdfLayerReference, font: &IndirectFontRef fn add_address_at(current_layer: &PdfLayerReference, font: &IndirectFontRef, font_bold: &IndirectFontRef, title: &str, address: &str, qrcode: &Vec, finalsize: usize, ypos: f64) { add_qrcode_image_to_page(current_layer, qrcode, finalsize, Mm(10.0), Mm(ypos)); - current_layer.use_text(title, 14, Mm(55.0), Mm(ypos+22.5), &font_bold); + current_layer.use_text(title, 14f64, Mm(55.0), Mm(ypos+22.5), &font_bold); let strs = split_to_max(&address, 39, 39); // No spaces, so user can copy the address for i in 0..strs.len() { - current_layer.use_text(strs[i].clone(), 12, Mm(55.0), Mm(ypos+15.0-((i*5) as f64)), &font); + current_layer.use_text(strs[i].clone(), 12f64, Mm(55.0), Mm(ypos+15.0-((i*5) as f64)), &font); } } @@ -182,23 +182,23 @@ fn add_pk_to_page(current_layer: &PdfLayerReference, font: &IndirectFontRef, fon add_qrcode_image_to_page(current_layer, &scaledimg, finalsize, Mm(145.0), Mm(ypos-17.5)); - current_layer.use_text("Private Key", 14, Mm(10.0), Mm(ypos+37.5), &font_bold); + current_layer.use_text("Private Key", 14f64, Mm(10.0), Mm(ypos+37.5), &font_bold); let strs = split_to_max(&pk, 45, 45); // No spaces, so user can copy the private key for i in 0..strs.len() { - current_layer.use_text(strs[i].clone(), 12, Mm(10.0), Mm(ypos+32.5-((i*5) as f64)), &font); + current_layer.use_text(strs[i].clone(), 12f64, Mm(10.0), Mm(ypos+32.5-((i*5) as f64)), &font); } // Add the address a second time below the private key let title = if is_taddr {"HUSH t-address"} else {"HUSH z-address"}; - current_layer.use_text(title, 12, Mm(10.0), Mm(ypos-10.0), &font_bold); + current_layer.use_text(title, 12f64, Mm(10.0), Mm(ypos-10.0), &font_bold); let strs = split_to_max(&address, 39, 39); // No spaces, so user can copy the address for i in 0..strs.len() { - current_layer.use_text(strs[i].clone(), 12, Mm(10.0), Mm(ypos-15.0-((i*5) as f64)), &font); + current_layer.use_text(strs[i].clone(), 12f64, Mm(10.0), Mm(ypos-15.0-((i*5) as f64)), &font); } // And add the seed too. if !seed.is_empty() { - current_layer.use_text(format!("HDSeed: {}, Path: {}", seed, path).as_str(), 8, Mm(10.0), Mm(ypos-35.0), &font); + current_layer.use_text(format!("HDSeed: {}, Path: {}", seed, path).as_str(), 8f64, Mm(10.0), Mm(ypos-35.0), &font); } } From b1f97d657b1f535912a02f7fa535909a971d8c12 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Mon, 11 Jan 2021 03:40:25 -0500 Subject: [PATCH 27/31] minor README.md changes --- README.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d9f0067..eb7c531 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,20 @@ # SilentDragonPaper +

+ + MyHushTeam's Twitter + + follow on Twitter + + follow on Mastodon + + MyHushTeam's Reddit +

+ SilentDragonPaper is a paper wallet generator that can run completely offline. You can run it on an air-gapped computer to generate your shielded z-addresses, which will allow you to keep your keys completely offline. @@ -110,11 +125,16 @@ ARGS: Name of output file. ``` +## Support + +For support join us on [Telegram Support](https://hush.is/telegram_support), or our [Main Telegram](https://hush.is/telegram) or tweet at [@MyHushTeam](https://twitter.com/MyHushTeam), or toot at our [Mastodon](https://fosstodon.org/@myhushteam), or [file an issue](https://git.hush.is/hush/SilentDragonPaper/issues). + ## Copyright -Released under the GNU Public License Version 3 or later. +Released under the [GNU Public License Version 3](https://www.gnu.org/licenses/gpl-3.0.en.html) or later. Copyright (c) 2019-2021 The Hush Developers + Copyright (c) 2019 adityapk00 ## License From 7d675f182489255b65c04d74be5afe1ddc135c86 Mon Sep 17 00:00:00 2001 From: jahway603 Date: Mon, 11 Jan 2021 03:43:51 -0500 Subject: [PATCH 28/31] other minor README.md changes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eb7c531..12dbb3f 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ cargo build --release ``` #### Option 2: Compile using "embedded" rust -Here we do need a system installed rust to compile. +Here we do not need a system installed rust to compile. The build.sh script pulls Rust version 1.48 down for us and builds with it. ``` cd SilentDragonPaper/cli @@ -54,7 +54,7 @@ cd SilentDragonPaper/cli ``` #### Compiled binary location -The binary is available in the `target/release` folder. +The completed binary is available in the `cli/target/release` folder. ## Usage Instructions From 7a65fc64cebab9a8e4dd805eb3caa0fdd5d7278d Mon Sep 17 00:00:00 2001 From: jahway603 Date: Mon, 11 Jan 2021 16:35:11 -0500 Subject: [PATCH 29/31] added sha256sum check for rust --- build.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index bb5f08d..e65b6ab 100755 --- a/build.sh +++ b/build.sh @@ -10,13 +10,23 @@ set -eu -o pipefail PREFIX=rust-1.48.0-x86_64-unknown-linux-gnu FILE=$PREFIX.tar.gz +SHA=950420a35b2dd9091f1b93a9ccd5abc026ca7112e667f246b1deb79204e2038b if [ ! -f "$FILE" ]; then wget https://static.rust-lang.org/dist/$FILE fi -#TODO: verify SHA256 -# 950420a35b2dd9091f1b93a9ccd5abc026ca7112e667f246b1deb79204e2038b rust-1.48.0-x86_64-unknown-linux-gnu.tar.gz +# Verify SHA256 of rust +echo "$SHA $FILE" | shasum -a 256 --check +# TWO SPACES or sadness sometimes: +# https://unix.stackexchange.com/questions/139891/why-does-verifying-sha256-checksum-with-sha256sum-fail-on-debian-and-work-on-u +echo "$SHA $FILE" | shasum -a 256 --check --status +if [ $? -ne 0 ]; then + FOUNDSHA=$(shasum -a 256 $FILE) + echo "SHA256 mismatch on $FILE!" + echo "$FOUNDSHA did not match $SHA . Aborting..." + exit 1 +fi tar zxvpf $FILE mkdir -p build From e32ca3fbd67863904133898db575671f85c5e232 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 27 Feb 2022 23:53:47 -0500 Subject: [PATCH 30/31] fix readme build instructions --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 12dbb3f..af58db6 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ git clone https://git.hush.is/hush/SilentDragonPaper Then choose one of these two source compilation options to build the SilentDragonPaper CLI. #### Option 1: Compile using system installed rust -SilentDragonPaper is built with rust. To compile from source, you [install Rust](https://www.rust-lang.org/tools/install). +SilentDragonPaper is built with Rust. To compile from source, you must [install Rust 1.48](https://www.rust-lang.org/tools/install). ``` cd SilentDragonPaper/cli @@ -46,10 +46,11 @@ cargo build --release ``` #### Option 2: Compile using "embedded" rust -Here we do not need a system installed rust to compile. The build.sh script pulls Rust version 1.48 down for us and builds with it. + +Here we do not need a system installed Rust to compile. The build.sh script pulls Rust version 1.48 down for us and builds with it. ``` -cd SilentDragonPaper/cli +cd SilentDragonPaper ./build.sh ``` From 921890b222020c32cda3604c20af109f93783d72 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 27 Feb 2022 23:55:03 -0500 Subject: [PATCH 31/31] Make instructions more useful --- README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index af58db6..24decab 100644 --- a/README.md +++ b/README.md @@ -37,23 +37,26 @@ git clone https://git.hush.is/hush/SilentDragonPaper Then choose one of these two source compilation options to build the SilentDragonPaper CLI. -#### Option 1: Compile using system installed rust -SilentDragonPaper is built with Rust. To compile from source, you must [install Rust 1.48](https://www.rust-lang.org/tools/install). +#### Recommended Option : Compile using "embedded" rust + +Here we do not need a system installed Rust to compile. The build.sh script pulls Rust version 1.48 down for us and builds with it. ``` -cd SilentDragonPaper/cli -cargo build --release +cd SilentDragonPaper +./build.sh ``` -#### Option 2: Compile using "embedded" rust +#### Advanced Option : Compile using system installed rust -Here we do not need a system installed Rust to compile. The build.sh script pulls Rust version 1.48 down for us and builds with it. +SilentDragonPaper is built with Rust. To compile from source, you must [install Rust 1.48](https://www.rust-lang.org/tools/install). +Older versions of Rust may work, newer versions will not. ``` -cd SilentDragonPaper -./build.sh +cd SilentDragonPaper/cli +cargo build --release ``` + #### Compiled binary location The completed binary is available in the `cli/target/release` folder.