From 3f08d564dbc0922abb826214579a813231e0cc9a Mon Sep 17 00:00:00 2001 From: mrz1836 Date: Thu, 23 Sep 2021 08:26:34 -0400 Subject: [PATCH 1/8] Moved files to github dir, not needed in root --- CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md | 0 CODE_STANDARDS.md => .github/CODE_STANDARDS.md | 2 +- CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 SECURITY.md => .github/SECURITY.md | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename CODE_OF_CONDUCT.md => .github/CODE_OF_CONDUCT.md (100%) rename CODE_STANDARDS.md => .github/CODE_STANDARDS.md (94%) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) rename SECURITY.md => .github/SECURITY.md (100%) diff --git a/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to .github/CODE_OF_CONDUCT.md diff --git a/CODE_STANDARDS.md b/.github/CODE_STANDARDS.md similarity index 94% rename from CODE_STANDARDS.md rename to .github/CODE_STANDARDS.md index 5f0b66b7..23153fb9 100644 --- a/CODE_STANDARDS.md +++ b/.github/CODE_STANDARDS.md @@ -16,7 +16,7 @@ View the [effective go](https://golang.org/doc/effective_go.html) standards docu ### *golangci-lint* specifications The package [golangci-lint](https://golangci-lint.run/usage/quick-start) runs several linters in one package/cmd. -View the active linters in the [configuration file](.golangci.yml). +View the active linters in the [configuration file](../.golangci.yml). Install via macOS: ```shell diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/SECURITY.md b/.github/SECURITY.md similarity index 100% rename from SECURITY.md rename to .github/SECURITY.md From bd8cb6c08f77bc82a1b5e266ce3a97cb342cd8ad Mon Sep 17 00:00:00 2001 From: mrz1836 Date: Thu, 23 Sep 2021 08:26:43 -0400 Subject: [PATCH 2/8] Updated bitcoin logo color --- .github/IMAGES/github-share-image.png | Bin 23764 -> 24449 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/.github/IMAGES/github-share-image.png b/.github/IMAGES/github-share-image.png index 7266fd887e00657214686f064adfaba8f109654a..e6dd44cd2797a52940f7ba68a4eca1dbe84ba496 100644 GIT binary patch literal 24449 zcmeEu zyVmgX55T7KvdMU7zcr zXf)|!QJbkHTjis>_uKUDL=d}D!VImU&TkpbUw=O-zU|qna=+)Kh!xKWIuUD=zz&mr z3E=(PlrwhVd*dS1zT|HW;1s_BySMh~fjAh^$0UDF8GT3;`f%XHk|ZW3PU8O!VEJ#s znhYQ-BO|jA_v9yfRUum)K!#qna|0j4$ZbKO-!F81(YLm;ZP1|GlvPbCUnB z0>ilk=M_4Ti>s5ZkPo|a&3)L_;xNQJp(@@M+214$ZvTaDe@W-OQEGL=d+90d6;~Bl z#L59Lm$J*H1#!sAw;>wn{+gt-h4cw)75F0-yCG-Hr}tY=@;kMTAQlPSe=W+E_w%Cr zt%}Lm9}!&>v9faKGXzZtg;rr2BtTB-HN?j$$4F?Y!at@|KpSACL|)MMl1BV9nHDFO z_|slNOX2&y{l$2Ay`hK#al>Ism+gEa;ZDhA{v$yHVu})%fI-49uie8b$0 zV#p*QG`xG8j=|k)bQgjJk}i-N;}PRg)h4ar+!iohkRu$r``Ip2al zE+RGS-Tg%s#+l0K-;_y19d6l@{E9+R+m1**mi0YKjsI*kSU|%dG=J(^ctiK2Py(=7 zQ7Q7*qXqo)LY#Z_SIjFt#c@Tm1=_#rJDsuAGGJx@u|yIoqYC62~uJ5d6{cOuVX^ z^Z?0kOeWSbk8b&T{pp`yddTfS9FB5-zt(kFb#th1PfyrM%egD_e+c;6H^#N{>Rh_+ z(s3?=ENMmqkfM?bq0TqTG5J>wvxrg=OYj_>rGG~Mmj7JV;y2{if-l1i_@qO4rMdVg z4|bSzgJ91sseJUiNe>U_H>pROL@8{e^8+6s{&qhmtoTW$rPoEuk1f4z0w((8m1@=m z)p32MkfR01*=&)bL0*mKF8cd-08?Qwyftv111}WbvsD-ZgqpuK-9m{Av~K#}_3zpJ zoRz%$3ThhQ&)^pq(chlpQia-;T9px`41Is{(}5bqLHgT<$2v%`Iz%(@x%Yl~g>{Gg zVcl6Dq#F{DVGqlGp4=3rQ8%iC$rEv>S)6YtH@bCdVY9pJ`rU^yo+n}U`JmOwoJ(H* z_p?1p=7!+aNhJn)3DY%C|Eg|Xz2xiehJY?bAa9IRccE#{W~WEZUPS{KmrWT%_tTJk zVnUf-O_;&cJqcg8Z-|x2Iu=ZDR%xkS4tEucwYI}lw`K!!bvP&w{YW{3A0K=)*PV~AkaxFdvWew=qbnID zrk}RXf14^t?2e)G^rU%R-WkNc!#WUalUkiQG)oK4g zd`S*R&6}&OiOIu-x~t2Z`8}0vT3yV@N;$cV?vFI8#=q>%MP*^hR4M{^#=X48Z<{M07gn4||Qq!#ebJc_# zYx_gmq6Cww+{GwnUfj^Cq6AJ?@S#!UeR4BA3p$TFR=U5;4xif<<;F4V}9p zI{Zr>PM9Fd@_E--wRM$1bK?`M+*rYUH6jKi!NwbAmtQ@>=GmDejApFLCYHO?>YO>^ za$k(^1pJe(yaFt4PwLR6DDa-<K8#ecz5XkSOU@%_#+)X4=)BXvEE)_bVf06oP?iXM?0jF?L+Nrpn_iQT! zqEjZ$?s9Ef> zJwZARikuFSL*6ylxsw)VJHMwC(zTdodS6=(ay{v|Ma<<)3F$PBEjRI^ZzQd1sWHD#wW@U#%XPuU7=huDKQC2Go4ls#!h5%lsO1h^$y+nzh z-sjU76w0w|FCjtf_}VW0sgl2I$B-g3z4en9v>+D{6~1e<2rfpa?MY8@bhe+C25)LY-5^} zIhKQ9+e2@3YO#MwCA~-j&5^YUD*#GsnGS(El6mObi&ba2uvev`W4(*4pwGHE7!Ord z^ELt%pfV$o9`vIrIOb;Nr0Z?nn9gZjO|?kK&dQ8IEZpzyRPI|1IxV($1j#6Xc^=;C77^;gzj$DnI=QHIYhU#`E*o~ixc0-3MaEGECO zEU-c4)#ow&%99m)zk61|U`hNFv*gkmvaqOtcfV-mQotTS);y1I7uaz|8qu5*Ld-A1(5}xT+ z{+dK?|BpE}6b_hDnSK zNs|2AW_Nd9>ityMPG60?o{p8+>|i{3`U{@t!LC%9dU>9T&Cx3OY*>W}Si!-L)2!4( z#&ww^RBU_`PM0RiP;RWH;d^E`A$5RJuMf}KjZda~18#X-dZnZ#M-mnY6l}uQN0qbC zK~9Cw0~=327aXUvan=pcGF=X@#Tg8WALX1h7W~EU25y(mcQ(A3D6rdW9_f55L{=)Y>WoCv ztl25S7{W9UjIA2BiCp$>TyDNoYS5Rriv6}cX6Q zbF#MidQ`Q!i21oD?8{LQVgtAh_+N1PgGNGLevI=2U5iiUpZB4YDXGP>zw=#8csIhq zCV7!-_WW;4$z0H=*~}Hn!q0G-e3Z#w(=-=bhaRrJ4*W9^lGy z3OF(V)Ra?hdNV~S&$Wy5-bEcAY8~s8?s4;KW+dQ=*SNUz>uxzfV|Z$C%?G^&ry*;# zxppKgTLM<1V!oAUIB{qj%9iT4QqF%m+cf;Vd@JF~t2+Wc3p03DswyhwbM2m@ih3<| zxNPKG`$>ThkHRST%^-663wAF$!WA5-bYq@5l_D`g_UUrVCi&F)aK`d-;< znH%hGRcdsh3pn!-8yLR0djd^GiW{=7<$#S^@4SEdpE3PtD71A*vmoN20qgqFDdjFV zP2T^$2-;Gd^1`T~mW!i!VnWMyR_2aX!1lTobNwG{D4L%%2GA7sAI$=AT?uFR*!t!f#m)ZZ(+UEd^IHq|B_ zL30HT*>j#y<~7i@nhKkUF#9+?3)nDfEh3fFAq7BM^fsYl@oY{FZvDEtb0bZ4pxart z1J-qs3S~aGqGZuQsczDpiy;&LqUCY6vS2Mh3Y*FzrX+|%4Lo)+r@UJ-s&xnLM%l&l z_!L}csj6xT3aP)|6S*uDU8(09x*oo(bGOxTI%k|w#3+o)w{wjCyz z*^-etZS|EK@o@`|irgqN?W;O>H2_(?>{UiOlXQrjTD%-A5+IJ4k;SM(u1+O)ZMwhl z2?{+%iv9VpOd~GWP&J)R%ms^uQpp6|^?Vk8+}L~%ZM&%}{d##GyquW!2`ret(?5Fo zEAjE_0?q~%5*@D=ba6~cy}Jp7A9{2FZgz{7V&vC3X7K&e_9cy9AoL z^-M|XluVGhn=UZ#2@PRqqFW?&Tt?`z%6R&kP3V!5JBn@sDedBCWbIG!D##1GL|DCQG z@-Y3ZXYYCE&t^-m4h{1k8s;QiX@7qEi_AkEaldxveSNEzGghvbWWcf~^hdP%@PazL zvVO-!I@qG;Dl9Pv>{R6I?%e69$G4>5FAQ|?yB+hjYaUjDZ>7Eei(uF_ItQ|;h)4vr za-Xyq7g?}W%|M%P$H+00wl;mDQMWhTiQrMqzjE~nb|nn;2|P0G;~uFJ!G0-iK7J{c z7Tk+m&TsTU11k6e4;k4g3Mb^0iYePX3hvXif;%mpk|&I$%HIhNR_Zb}CK8q3n;SEC zOPms`NN=UX>GycCcKckfUfXiJ)EtO!p5H$=&X(hQySP~>_q;3qF{^)z<5(zQ%(IM( z(5J6slzc4LxH!i1-mGBjzRZ%Z+`J511WxNvv1iF~yb7yyV3<9|CMc4HT9y|B1P%V4 zR|0_#J-k5W)UKgM?LlkqULpjos&d-x6tnzI_D-Mfp>>c($Ia*owwf<$V3nfP zu0!s1e&<_FpfnYHtuOg*#Zj8>c_KQC_xBo&s_8!e)w8;T<`+)4AL$N{pd33sH!{%m z9SjF0|E2nFIqVR+c`DYi_0;HXe=E-EY?oX4NdI~8a&vAQUcLpVu4k{0pU8GDpynd28)A2{69jr(PH+Iz@PQ-AFKie=q?MbqS6GeB^Cup=^ts#WMis5?j z{&`g`LV5lH7WUQbaFWLZSzDJZ`T(g+d_kP>s6PZ_H@bPH3M25L6L`W)K4yu{HKlUd zxfr$hB6K+WziK+tn%6OEjsxOAqoE9H33<_ZDVs6Xje#pjaq^JvlDl9P@A9-kV=DE_ z6Wd=Jo|ZOQU;p*(m}EKl5^SIe9sa6%6bSDwza5x=vw~mq`}#ezgd!2x)=oJBGw9r_^PKJ5 zME*ro?r;s@+Z30PAA1cRP58Il9mB>xqb<_l5Lhry5R5oup7`+csEe-!bNi#y`Wv6y z@{MgsVV1Z|N=xB2^$u9b0biZ!OMkpZ2KDQynt1Tn7OK9YqhgB8N{u&gC=;xhz^nIm zeGwbo99s)Aus1Avb04?|n*K%b$Pto zOaxP{$Lm@(_!`=;e6*?#wU5>a`nBHoFu+`49jz%v5tY9Z(st3RB;SlNa{{l|Ae!Zu3 zPlFUTD4LBi8im#aY|FOXxl~*(KdDO)!TPDB-~9`?&i{O#`W<#WT5I%~jzN6lbed38 zI7Z;gY$_1-upG<~7gppwQ=K-rr&f`Lh8ZIobSS1ua8tW0Ptz*a^cZ37Tjv{n3sOQe zI>I(oyv&wp@1MLLz7Y4+F%%XOS_en07>g8-hSu%ebMFMXn_Pen@Yhqs6AW+OA7Anm z=hl&0gE~?g$U8ErjI!tp1;ykBbxy|MC?g^0UzJyyTOn#hDv0+hIvfo zdU9-nNOg$B6-UlSVOC=T(EszwDMpUZm;+YXhf952u1B1oSH?q9XRPlFQ7LP~lrEG0 zE+6i{`u+JJc!tpo?efWm!T5~@ITK**NbqT zcO}O{%nEoqcyAh<*LD)VauD?pTIg3Kcy8}D{WL)1)NgRXw;Bg^v6{8LXpS=xtZy{H zhMjg|#Ihk0!BXY%R@80lJFrWZURb>6;`dOwyT}q`vk|!|M_?#pA`AVCyVjQ&@5;mA zaJNTM?$t|W^mHsfg+;5+2SL!{!}f2ya`pqCYu@_Z$GX$El@o~{TWnxzD{+gySIv?P zCO5cgKW`~3T>`ZJk}-6&-4HxDBF0qN5a9-8UDvv)5Xz~-vJNn`F(rJQm5YCoZ=AzR~*I02qKTxm)ou7 zy=K->L9ca8Cw3{O#l`cR&2t`olg1cb{9gs5_l}zdj<~^$lQ}AcAySr^oRQV*ueM)K zBF{lO1%nt2{?>8p0pr&#kNiJ)BH*Ot$cFhALP@-v+ z*{$Vmk6-6QtN{)RRyXb?zRzRzcz5{pl=kMzHK>q$6`aud2uMTZO)FyKB#5ThHQKR> zA$hmQH!rL+oUqoTe1AIqZ(MM)-WXl=RKvs9+5zd?hWX7S=yS-*-H*Ry~D{x8#yBOY8jW}9hMD-J^&~{xfNd=Na zrhK3E9lkQ!TPl7zoAT=6{Yv+5p9beIN6p#XHR&v_2Zx4^_+;+D8!?eA`fMYUyGe00 zE64^`SuE`+9Sgj#`6wxqRkx18{V$DqROMnk+OD&IBcrFuD^{wzy6YXd;R|C`n(}bI zh<-@`{?5}+pqXu}0eTj3-_nsMvw$l%3HrcI- z2Zy~!ErBb1za9p(%eo9b9IFWg=7Z7CnQ6bbCkvs>dObLXVpXE7I)P-?sQ>ujb=?mn|%kSkh48TDcjG? zfj@Y1vwei{I1bge6a?3YeJRtaKxfSK_P1F~;uU`}JoQWesq^#~QVNX=ZmX-xrF1mN^K-_-z{yq{oZRJW;m~BYI~d|J|3a zSMK5t^X@DqNZ&8DNcVi&OizZtD*~&1;!|qUr*ZCwmurW+WNIxRWuSURk1qTXhA*6U z)_yJ+8YPrsjp;#^HYsMt?E_J*`0FskR;Vky=3oX^E&F<|cP3Fsi0k`gDqzW*}O3X z@gzt${xpI_}WO@0&S1w)BgPRc4o z?w@{PO|=0k&m#3yrmW4bDFJ|A&uGd5ZT^7nTuEAnX$QZ?KT%Xe()OyrJ&Y3<{qan! zxwxyrqthnIBZ->yj~9GPLOBBYj+KHz*4nx;7Uj&l0i?YqxFLEfqEbT@(=BbQ5Pv(ciHk%+RlT-fo+IXypO z?k~J} zyxGFN;J@K*caB18tSDXOz@23>`g`v=mTsyrxL-H)E=VH`Wv-3jyIDhwJopye>E+tq z3iDqxbxx1e?61;hLWAO5FHzA^QKbWD2LfBd>Fj4aul#YMe2)(aE4kwYo1GVx$rbPx zxddiE73vyKi}gG?zJzhl%)*c}vNN|wTygNV8<6Shwsmk@h>w8M~9cgny47Mm%2pMM2Q_Fdw0e zK?9^Zj9RCv_UURLCM@@NS{l+#1plJ`_9vM~c*-@Dd*PJ9VfIrx!z5h3dJjfL1r^+U zVl#0(I~3nB$$&S|n7%R}!>5e-LQ~sDJ={r5@0B&R)=iwW!^6q8HkzyO^8L$?=fJ5w zoYVb6uj_+kr0NoshLeD|lt?+yeUB%DMEw}kTK-W`I2MLrirZ_ibs>2c0w>%MG&#Dj zN8*iMp3Rzs_>0UO*Nxn({^Mtynpa~7+aDRAB|`)bb4=ftb6som#YR#aFO@Mb?}>?tMqUOul45O2cMV}dl4TP=**>FjnAIcb(~~PE zC^nxZ>Gg(F-dC!Eq>4D%bBk+Kct#KX#Oe-os8B;`P`EGbNBw@^b3EoVVd%Toi`;5h zwNxq#mD3!6y1lYRkgmqK2|KDZPx#zhFWdR{syo^3M^5w8x?l(4=-1 zw1=mrsKGw$3#FV{T>cQ@-nF#TFcogzy2Ctt-VRc{+)QT6@uxW|`-AqK#cNi9tg?jE z^k;wgL+gPJuQk^jJyOrw*E5ac@W>q`-g1iQ7lS@CnHFO{fOmNwhcR7P4)uGh!waiXqBX zuxCn4tWQZp1^`L?w1BQJNBZ3i0fEY#&%Rzs81irY6;SG|T$}za8%22*N;}<9IotItt@ikNT%JDu(rdn< zj0KOMAa;aTdi@tyUrW)-0ublBs&Ps@Ulp57RW8Ojdmb}BL{VhNt16@HVs0uzABPX4 z;Z;p{h$lDJ(DYK8@vT(-3|oA&$3V=LAYA{ZvvV$ZVlehE=Ddl!4x!>giSW9EvTAMB zwhM{}D2x=%Q%u3xa&EX>p3qLk!jE3n9%1|tcogkDt1v%`Gle$_I#H8EZj05KaQy2f zQk9T)*>+DUlvqVS^}}$k&r|0tgr3X#klxf`W+#la0GdS#2Tiq|Sw{G{dA4Ap)q~XY zDNkkL&~*-+MjtdWb2BQZ!)>qmvwV*oo;ic_w_)G>{l5sLUVl?9xq?4&{Ah|X2PjX1 z!p&4I`h@^vm31x8nE@3riu=z})V*Kqp(1t(*j@np6TWHAT(1uiL_e(l)Pgs4_Qq4o zzb*TLuT8!NAz^XoIb_l#jO6D3JN@2>SNF=hIZzuOcgP}j#gbo*!Xw4TgeN8iKQLz? z7YH@PAD@@j$jp+2WANiwsO#PL$!SG0{5qeE9AH2tmNeG2!M|pnEzVD=gvKU*e0;DU zd-|=&Fp~yZ8o#@*xhjG7a#I=uj8fiSv$CzbuVnXrB%(o_V=&d31Tw>N*0S-=`1$vd zljNZU83kpI`yZ)*XtFhWEa7d@HzlzsqbJLZTTD zen;h(F$b+1rhmTU#n7497GZx|soi1?Tf{JlWAV<}=s{tH5EMim`BBdBLjK$wjsbr^ z=^Y4ltz0KFck$CcKmtS&@0(lSRKx2exsjM#18q+Bcd)rI%z5bxwMW2@Otj8QRRx8X zjWsT$;Jz}#^>c-}jDguvhqFN+&XigJuucQPoFW%s!IOh8SB8o$)EO>}D+`8izwtSm zR8stK>JAjk&*bXv#b3(sdnT|nuV27S0WBi2<-ynf5#WkOc<+xGDb!$I&794)EyV7J zuh4}=a}I%l>yHXyL2_=l=_t8ePq{mpoi!y8tv-Th2uNJ2>&)V%xvw@3fvU|6eN@Gi z40#5=F|T}*?6(%Rh7yS}$I68tFuJ`SfXypSJ9P6DId}N8AH7EuPY|R%P~&mL*!WD7 z(z=?A%=F{n^SpN$5Uh6?R?BSu@wnw&f5B78h6rQM=1hrOmb{0XP%mGdl)GTznLLJJg{%k zwSA2b6kys1{0uk)&P{qa?t5&HoO(55NVx74%k8|aeM+>2*5TIOKck2$0PD~2rElCv zMjr+3G%L`kwtd<=WZ=6B03t}=VejPLnV0okk#>`?hX3b=-r4kkbqzjlI`>;>iHL4s z?t(++*41*43ZA-45pJ!7{yS?OU95i;A56MCw79FMyxplZ4-UNl{5CiUuOED%cBea@ z&(058QDU5zT1^N$Y`ya$*>l<#`LUyebztiK6s>S!IeZ)=yMCaa^=DJpdP^%NcHdAl z@=9KT_C~ja+VpHGGUKij^fxZ3ILKSM8S=_IrQ+ti7}}6>(;EDB)!+N*!PGu-Lt8C4 zqMhFx^6FkL^pfsk^r2>Ua=x0h&o1CsLR3`0fx{qmd%hkh+W&=97^!rYr;QDkvvu9E zHKn3O!q$RvICJ5~zjNTif`LMPVUvs}@<+Lfd6~I<^DM(zL-Xq7+yU)Vp1$D{Reg{v zZK7inG~Z}28AAP9g6|WR7KLtQT!)@gim0+VN+qL0kx$~Y{h{byf{76fr~RNQbNV`1 z)_gattVK={?KorpZ&8;LeP`aJ-wr4N$$=7a0;i1&!NbkHEWt68XQs~kx4ralck6v8 z;OLD|2UvS!ye2x?Lph27voC?q82^4N>yrSzK9D_(!a1l~^yd2nLdV8vLLs?WkV0?E z^f8e4r6wpM5Lo+ZQs4OU1)~yFxUFSq={sd?;qJ@1q2sW+q@xv{`cq1HK-iD4bKwl9V6mo%$Z)BC*=_gO{q6E5)m-ZKiBQb zSQY2P&ct)u!uq-*C(H_~Le6)T?8}c$vyM4vP=@DdhefnDZ0W1L&hg|$L2)lYQ{diqeJQit)QfhygVKd(ASC7O0_8jas(56!rR)Pe0&_v*&AMQ)SZ~94(ps| znbM>zO2Z?7)y&XWe=|=#TPNM@jqLwVIzs!(6+T8Rc9x9UaZyI#5mrB{sv+=55`>`R zp1SU#mcF{QVKKVN-S$GtEk2)w!I*}2ni;^5S4oHC+l0i#^W28?fU&Lj95}B*po6&= zR>fL|EM_l(Hz#d3u>t3r!Lnqs)iW$W{7mHt2zt-NcZz0Jl8j@u-e*NGgzoHnvTS)i zYyyp;9Zj>g?!_69{qi^Qs}CISQwN*R3_-Wi3@FzX#0o>VXLj~9UvCvN@#&#QX?PM$ zW>&-LmzyC&_DSC!TCrhsqUuK46-NkZUywVwQ09^X73svpnTqyI-w@HYL`IvUF6L~4 zVz`B2=RUCHgTvQ>7m=rRZB|~xda-2*nts<$^)&7Gg{AJUzGaGRpF}1wqCthr5(ml@ z?Q14IwH~-s_Njk#Vrhw81U2*1By@tRYSQ}XgL7bQXX41iu3%Ln%$kUH_3p1vaeUUk z;?y5Nn{Lu2Zj&E|+fay2w}yf~3&*mFs>KbbHP!Ol?{;zPhYjuzkHI&IH>jXnU7sPt zmCmPxqU~#IYljCE2gQG4`c!fkEyFn5kKr_8Wbh*)%p^&2hD zbT|YR%YgHWhj)ZVme~LLaD76ap~n-n(;2k+hGAVkXj7hrLh0eyIXKF`rg6y%1mq#| zW`}#JjxmOjiJ7_KZokClsg`i=_Ph-QZu*!V zJQ9hzRNK=tSDYJ;yG6ro`9UY8kvxJg4qI4bD^tU&j@H6x{n(`@rwT8>M~KCMy5rjpqf|#?_KK=mvi}k+Z1zw2!P0Rlf%cFRCLd zaO#qAZ;Cb)_O}P2K0dNBGSb)$v4wb%-v?Kl$PC*#-Ax+|5jLMhM*Xr~A)Iz=7>*Rb zd>ya~349Pc@g-cWb%aj^-`52k!qJhNHPol7`9}Ygdg<@pH5bE8xasD@IMGQEqN!m$ zg2o=`j+tGWD3X*lgO3W5~n1CT^h-%VoGT;Up9 zj&L?2d95>y<(Ow{o{qdG6)gi=kHCY_j@*Wf&N2m?;;CJ zj|GqTLsBBQsA%)KU}*&50i|E2C3I_Zt1xz$8H&w|QJ zX9S3;Zxr~h0%i>+=h3x8^M;f-iJ)!^gS)Csd#p74A1K?v-KK1dX4N4e&4HZ){&*5B zF*P++<0?aJdeceigS_2wrHwS=>>J{0o9yi8?`^o)c}Y#(N!7(Har+tUe=PL#dLber z;^s6`qWSNnOChY1E)bMr>VB-gSXcj>7O=1%@@I4Z+Vvm zp=~U?S((A133a3%0hFmYD3a217mT z>k;JSV;4S~N%HlG75|2afyin0fEqi^T{DDK4TR{{{!-!*~pqSnGezdJA5+g?VG#4Zg8bTBwqyg zV{hgcE1r%=pDDHVwAOg5KSlRK1(Xtx)DLtg-A4@=Z3u$3X*FA@_9K4H@|Zf3EW8}W zy)~I`5M(U1-}Fp)_222tX?tMm5fJA;?x~;H71nG)#v)(6Cy7leFh@V&3G??RCIKp z{T9C7jq)>P_!YnRPQ}4pck)X&_>g#>SGUo25O;(ZHmI*9L3IXnHQ2Y3x#)LL(1RTwV#oukx${5*gzK#uZ{P7>f# zGa`RanHd?gt%shPm9T#d^vL9i@DOg<*tuzK+jU*N*gZaW+80mlAKy1;3h)1}w;rws z+B-Th_5eHaW^3+qI8m1oJNT3rh=UH4jYMaRB(ubv=QNH2n6-ae($bCuU-A?+&>UXJA$ z`+Bz42+Dw!ff>BHgS1%<%u9@LqR@BUcI|D@ZRUK1;I}q zRK}O`d&qr%!eFSohm@*tzVU=4uEW(R^yl#0scVEP1Mp#k^?kl*Qp@zXP!(}Ue;sSk z4rPDfnUmY9A5PDiM0*zB@iXs)FGs#Rq2=}OQjgvw4ML9=(2$E`;T$k$&mj3!S>Pp_ zaJ{^`KA%Dz7h0>KY`2Asjg22VgYP9t<9~vPj~yCnTrA4W|7`H{olsu{BA449SxakF zbU)DbtqTM{!dNI`RTAy^FkE;UfjknbR9e|kq<*`rD0e*D&=rNSRDSpLoG&LhIJ#(p zH>IGDh5nJRpv^}@)71aX?G!3p@yfN-u0{QJL&{gnj{(s1b0)!ccfQu<2u6vX^qW8@ zW}TP7f$)fmXjWYye!g2K!$YA&`~Av&m`Zq5LIQgmLZmJJgv&{+YWJ?ap-NupBk#@~ zzjOV@Xb!OX;o=v|24CIkX!*k=7oSl{{g)bpt)~)*pcl0jNJ6vbg}b^>-fnPMnM!=F z^PVRaev8P9sz3z6ACbE>Wb>UhL@_BkiPuQ<{>ju%n?l1SQIZ{!rM;lO4y~~CcZB!R zqD9D18p9b9EHpHzso!|=it0Si?rx3`Efu0VKMB4oyseYCa<^R;5$8o(-O`xzV{iG?{QP`HQ4L(s z!`t($sqOLg%2nX1!2MFH{u4Y>4&@S9Ls<@89qyI}xYGm9FA%Q>IGYJE`{5jq zNxyyfsE+66?+k zcCx#WC&NBm^8V)YK}@9g&Yf-R$?ZU_ay((B<&5Wc3Sr$1nW`0j@S#-Bpg@Ic&=prF zZQj2N2=Tkb;li`NJQ#ewm1R*;hz zSv@qCw;IkH^DFJs)Nra`R;;Uo@a%MwQ+(eO0jnXS^rA_{(+|CCf~sXCwjAbUWo~uO z9H)Vo0gd^mx(t2BO&^w;q%bNnAeJ}7)g1B6N&9B^U>a&2=Yzy>^Y)w5=eP|#j5Hl2 zj;7q$u^rh#DRZaHJRLAI@&gREM~0sZo~UMT{+Lf*boB%hX|}h1=!iWqAIeTFV+s=P zb!$CzYuv2lome2;x+A>j#(z#Dx$19AWq__ z-okM4ltAIP0)732dux57n)W252?!IJ?H}Q@9?sI@-wF#hnhUD`6&G#JRDYX2b?eBU zZ?B3mZl@tPDb4>5`e4aZeLa?#q~OVU@9W-oaO>LWhqJd&XKAs?t_j?!;Ll+gv{t3; zkoz|8|BTmLlcVLO_nof=FgVIHO@fta*XODFL$53dg>C?FgV0vauN4Ix??+v9f4MkP z<&$T#5J=RKv1xL21hw!ixOLyEoiyM0-=Svrwt}HowW!63# z2j&b_xMoX6jI{#v;_Pad)ns&0;IvPvnbq{=CC=X+V1U~tmZ@aQbQ5n|eD!mt&P^4W z0b`$r-#(g<9^u$A7XIt^p~E$?osfeb^f-cmm?}C`#8;r-6NeH}{8wky-j~YX{$vU1 zdaKyy?WKl}RpzW-_Qt2a6b1SUQv&@(e|6#6Fsv%{;fZr?1vYC(=%H2qy2-Sb&v% zVW2HXfREO4MKYr?{!YrhMm&MoIIzip8jZ60<>t_3p{2mnG9m+b`=Ibc06{U}M??9f zjE^?=T1c4Akmo^GUBUd2QJu=dQD!GWjE&u^H22-ZZ4#!u@cTnGY#N>CAN4r3jKKXp zF0*-|4dBumbTe(>m%tN&Rv=afn5 z5@+b?rt}KcG<$?G`;sGVtWCccf$jeyzy^;0gsd8^O~vuA(y87Pi+)VobPUAWIMB%~ zsiwj=rB-sO+~907|E0lx8jpHB5Jh>T(knDtKYr>nMvHst^QRL%e$0%3H;`X&~- zRc1C$FF^N1A{go$(pRPj3zI*B9B$sCm7OkGq6pYR)ac5x2jaw}j)%RqFW*f6y>e1^ zy`;GxElt@tzwPMg>cTM)(qW*>7Xbh;aR2vRfT!|VL5}F$gKqzxnn7vLaaLOu_zVuX z?Ozj_=`yY*K+lW$1*WkmT0elz{%n{zKK`xidE991HTii{*0$x1JRSS1lP*zRi`22H zei?LU6O^_NT9sPsp^0d}1I=fbx`E`wYsePg69@Q;cKGz<7CDt64Lm=Oo&K&PAVSO* z;!??B6q?>JjV}#Q)tGHpAQnVmTgZ{BS&|6t-bgk68qEeI-)iLv)5h7Q93i@q`@@Px zg5x}>V1MsxT9|JE&cki1d!t(UE;cou6wzC$5Hc(c64rrV4xfS1zvq(D-&XNzYQ~fl zhz`gW45l_MZ8MB7Pa7%Qzt7By{hL$Sr>d`$;zl(TqcWh_|DA$W!RQtAl_Y@RC*mqc zfHHnc2I%b2a(b&>^v@H592HW@!8xhJh`?4{G@g86&olSzcuPfDjmC#jPo~Z4&HnuG zoTQXKnRN_y0WP+ar6`fsEUlJOtsg01#ezDifo9j&=cTv^y2qbD^98ZvevjOn*x6d| z<5yb|nh&u{nAUfYE{9dt6qVH<6yn0^hC+nLJ8ZnU_Z&3pQ}f-JDT57f6{!)FV?7kw zLg`G@7ds>v8fTv!_#YY??;^a))epE;xcsgeWGh_&1Gk?yHQX!G%ilfoo-L=G0EbnS zzUo5~6RS_zh64Vs@sXWpFE4pZr~cIRAcOv4kITmrmv$Mq0YbFphT-gcgXEhI@sYAm z5f@C>vD8*YaXlsf%J^-clRe4&jBkv3_piDhP}3KC=AY~-F;~9S9C-o`d@iP$KJl_G zV)4zY9OrloJD8QKxXNU8$BqkXgBkJU`hIY3r)C1~xn}y|zF`;O{w}^KG+IQ6)C%K} zZ`7&@zs#%jj@jZ(ZcfnwHFW_F(#&H_dS-G9*qp{t+4@@H#QYEGltMQ{JEv}MkbPHd z0#sZ^7$I%fbBf*uRmp$;#LVhb$Ee1PlPZqhQjIiRaWHHvTn&duPXPL$li}?ue6Pk`F`C>^jETh;vfn z381Y_p{vu^Jn~ZG<-y-1Kk>1AKALgd50zkOa$&c7X1|^bJ`troD#GRfR5;=kLTI7> zVqINN1HU*$Y2jK6C9ZP?VXN_kUnOjUV;knKw{|urQc-Q$JxubLk9oPd59(u$!6Bbu z8b%TCweN~MZ2=IPimCdxaxqYo92HUDSfmws3?+3DRm%NbO}le zA`M4(w+P51jr0RbcODIbbV++~grt;kaKHiY^1i>{pLhG+-PxJX%+Ad2&Qc&pe2)AV zrpE-ObVtjlGqL#33F>x!>Xhovo2kruSs|N~hsx4P+}}Z8RHi6YenKIRkMc(7u}~Nj zyX}0I>VFsT0kR%L zLo`!Z&w;Mg+)CqyF!Yb(R+_TrK^cA|2&_dg3u8{e~+ zOK0b&2!yr^uD(qseK8{4K8S(K$$vWO{q&JtUb2~^(NqYaIJ8Z?95JN27!;{JJub9l z#laT<_$Ku)FVvLVvHsawq2RBQc#0hbo@R~{s^-wvVOHM-=u~=-SqeMkEdkOyeos0y z&gDTQeTfc?D>_+M?cYU5yz~3%dZ@W-jHDIB#&=8y|B@wTFXUxTwsi3X3?AHRm zIs`of2k6QeXT{rhs(O^uUCc`NFYg-KE~+|8KK;8PCC63QBDV~jBA?=Q4t33Xl&TPp zpSuG0*0Z_QzAg#Wp-Hm&Kwu^nSRy4h1cD@JvpZ zur#KWgXzQ3l$b#Z=p;TxN8dhc*VttHtXLEBk3~#iWg}fNXJj%39UEbs!`koi>3V&7 zbwxA@!lgCv%H=n+H&1Km!uVYgL`Bh zDG~O)BF(0NBnnSU`MUn5d9+RKG>W{k!d$RkU1P+BnH};h>5!5SVC z-Lt>Og}9;R^r3L3x7cgFAOyD`>mYZK^hrU+=~}^!{{(p!R^>&RVup6;AlkL=SQmS` zepY*(x*-GKH;p=>64WzCm0cNr>1V9KRVgy*dOjU(=kUzhMSHZU3SL%-7e~}wjQc&d z1G^NzP3asY+i;G&m;WgxC2&0bsws@y5StnqX;m*O4M}1nK6T!9$D2@6VjaYMgla^; zk_*FT%>TGU!_qqK#Hwf(GODkT<{e@M05UbX4@vov9M3-!<3O~-c?UXQQ8D@|wL2#v zc%0co$XJf+^P59IZfF+#;|se0j2}RJ%^@>0M7a+AHETqo>P8I;?2cJk-TB0} zSI%lXg+ZU?2=i5mvJ z>DYQ>VkK;vG0_C1}lB`GK5GUrB1iMGP2hG)_6ymq4(-y%#_-%S`U`hVDyHk zhoif7N%M%6-P)DbnoPDey>o9j|Da_hgDG~>VPc&qA0$9`R0{gm6yxb=gjo!h?bG4+|d3)RPe@-eMKJ4LCx$t*vvP^qo20{Rg1{c@LB zYZXEbR^0L&locG7*NWinqs(C+j|l=pOu9y^O$<(%%MPE%RW7Aa^##Yc)c=$6f=-ya zk{NZI+gnBSHso^6oir+#!eymY-Z4 z!RmL4U%d;E71wKdb}NIym?KuF?YVOC3~9H{osKceo#kP?iuZ z=T-!HEkS9v*z(NHGNR-F)^vObZhqYdR!9C()$#xcm49`>bLYi7)bY@7JKr;51DVWo z&N%Ex`XGNkXA5GoQ)dhk3gPfgZMPKhYJNb|ff$UKRk_iIHDkYeBwn9ejJrs`@r8|a zCB|IyUs7>@XR%ll-v=fal=S_S;0I;ab3LRy9Q#m{0^#st_K)SIuN~!K<3oSXA{LZ9 zRnLl7bAU)tq3aFDSocz&HeKzJme~!%`W0M@D8S{xn$>jL;;n2NT&tg`7VV&}R0QDB zCm|`m;j7~(Icq6E2uvpA8D;6wv^tbeTjphj^yf3emhdFBgiIn3*$5Dpu zV{&3`uz9`O$&25-JY`UNH%ND>+#%SD7E!fhY%vwO!U8=gM{>~Ivi7kXu=&(tuUaK$ zI^q_e@yWJ9A$_@zOAQ&G_7ch#Q!ZP<(#x7YyzFr@&a_#xwR>sgE%1wzp^n`5LWAj` zIi_+`DRE;3$*c0O61L|bn_(+Qh!90M;_X9&42q^qN498Pj+qg`%=3&eGou}&=*6F6 zi-|fNJz;(PYDd^2`l8)z;;-i+Ko5oEzfq8lV2Evoulm^G%U&$isY+q)zJhU{3q6H? zL0gZT-ETwN3J*^0%F0GqrKO4Zp6op13)_>KjmlBu=*7S!{c7R*+^zi~9i{Fus+O>kc~7T` zV+kC7e1DtJ>Oe8O2O!vRwxdhW3 zpD^V#ru7qFr$}QWmx0*Jtf@Dim#n588TU z=E^E8e(K;S4!miR5k4IgpUHW2N+hac{mwX?i&Z+T`W zyE>qT5^3E2f36%O28r7WoqTdMCK8c2H=r)BLefTl{zzn_OEOCSJ#AI%k^yA#tM8x! zX+HurEizr{nzsg;tzC%Y#r5?GvVM3?9#F%(+l2+n-0WfgoASW`$KL_)kX9byVq$rd zkK@PKcSPD?@&Qt+Fioy*Ati5!-K7Q6fWta4{#^vefJid0mSg@M_kkorqszoz3Iifs zLC=%c$BfG!$h3M}PP3)cOUN)v$?U$-lb@F8*^9*cKmTsGj9E4<4*YIIgbJ7|n{yj1 zE%0;bSElK77#~<#S9c}_1yvAd4Xqx`#gp_DRNG$WK9#Z^fubE9?rPSsg@=fn+l1|9 znPT%wt&hez9a*ErT|YHi*fa}McT4H5Bi?eiEO|EfewWG`<~DIIGG_@&q!rq_9xRiC zWNE95zhL|hZt^abo{IC#pr!Ntcp|X30RdhN_;1zS3~yJQVmR^8eGUO`Jh(2`C{&xz zJ9Q!()W>y%*Zl#+=rcuv*cW0ryf1&`)7RbAr;rr?8l3XYY{Mf_E9J+M^*)VVdW(B) zNGBD@B=Oq2rdB7z?OMyiz`{>LrM{{~rnmImsWFpqCkqMH+oV8MuC03>S9|Gr%j3B) zj?Aqd#UdTH`o`H2*YZiV7<0!kpOwXIgY);z59yY|g3w9G9F!nt`#{=Zh;ilu`P^Lw z5rv9Lw*b8(%uR4;*U7NKuduSqre3z;3K z@})iCV|=y-+k;*S>iA+z(AQNW3~ccfrkL;H>0uT&xayS*>`sP`+tuo4naizHbxS2T z!n|Em3%j}Tl~YxtY7HlutkX3sMnRb$=sm#^UAXyaZm%t>d{T6v<*^i9PwlKP#%DD) z{?`w=?#}wSXZz?L@7wsF;+y%bq76y-a{{k z@XI!TCStmr(=A&?!U*n*zqjjQf?o2h4qr&44oSq*ri> zs_pD%!qm38UbLAq7>Cdp*8qOFgv_^i5S zJj2VisPo4}++d_%#FRkL^V7?uR4i4I7h5eddYtDLge&L_qNJK8xebE0 zIdkxh2OLR~FR_?f3`zOTnqaQLXIj%6(S}pvI8*o|X=kC&_v>XztEmvE|0-54Fa%Xo zK}Bqqx}e)gYKr*1y*QV{v_4F>>D~=olZ*q?3Ro)RA^4a@A4zHo%sZ!ox~XhX!;aXP!>v!bxF;cxvxKUHL0`q1-a0x+M5Y%^$@-ps`!9EUhs4UnZu7WhFjgkX8Y;__p1(s`H@y5_I!}0 zj^XV?M=Z0A`ZKm|c^Z%eaWTCSTQ>+>GFt%S2t?w2stdzhXEvrLMjA8$9YuJprqNMd_&Ak+s7vDeflXusR!M;<8fM3K5q)J$GI zFa62?^#BxAsJOmPL$wRYL0F^Cm{H`{2oDb@mh)h1oVdW784OTW$79;DI00DJzga-by%v{Y1aiVDwk zv{azkP0xHwnQ|4pTkCJ2GH_q9T}Wj~war3c<>FZA{dqv&yP&U;5^uBjy^o*3NqGexE9{6!rP(>s{0c~MPIZDvE~tI|!G6ow zy$|B}Xye11%mLmHi6G=?FtUAtHGcLJ3*2Jsr!c*U*I{$Yu_Uejk3MEkL)t6<%LniQ zr^XF-?%-r1g$;1!aNoFst)u!J`e>5F&Q<$b&5}jkAO!chGU9KvUC(Y8RIy{agF~g&EWZxrbcQ65;xEK8UT}cLH z+Ag;zAHVw`uFy|8$N2CdbD1zrL64xJ-MbW)zwy zQ=Hir*)Euj#t=FkeXrhtOOggWs+u0UHbgR0T6p`_i_LL;ELpjqUdmgWuk0$p0H%JU6o5gZ zXZdB%HW#_svVz`D&Dsh;pR+JYVH`P?WEc|V)VZSKM*>K961HR)oht)_?q+>23^?<% z3cuF6x}P-aSmJ5;Q+F=o04zSIlDw37XCD$dTD5iy61@46$=yl$?evkpCt~LzyCJe_ zLKUPkb9u&S@DPh*pZ6p3Gz?NEi#2Wp#dq=tvs1)5j4)?Mwrd0~nseHH)r<%Y|?rIeBvyGq3nu&Jj<=dhK=>7yAH6R&D#B+ z99J%$`0}p1ETLNHw7_fiD7w=FY5FDSdgnv(YS<*m?%Pt7svdC!Fz1!~x_oys zEHt~R-S?1Zf>2r|`9UIYM|?jk&2s{1yZf;$xwX!kqg6hdL6GXHfTACBuetwGsPw4v z-0Fgo6G2wy`Q!HvCgsMroTeJoloVKq&f;WZXv_VhgRb%XU{ni_+LLafs*f?~XZ zOZgukDg-u=xh21!QvrByD8kA(Sc{tF7&xc{Fx|JPje|2I-&MG(XK*F63gbNTlzgbn`f z{-^OHF8@e(Sz z#NuC&!e4RyjviUN9Nx_>E^|@5>ONfH<^CQ0+Y@Xry2Sfktze`XKCK6z(h6dy`|I7S z(^NTs!v_)?+u!!t%fIalVnp)=>G|J2@+(C1>C3af{ePZPw*Bq?>nV=$-~K;C{&xZV zg9GV*6TrWS{1*lPV*vlc@h=ws#{mAXT>cLL{P$w|zX9++m-GJ$;Qu>C{r^|fPK|LY zC`d?csWK&50tp|U=7`iUYkXoaZdEw{vFSSH*ed>~)Y0AJC9=81=l=Vudqb*mPk86j zvDl%KX5{K;La#%9)QKdfrRjbk;Fwlow40_jGKQmdREwMcvZ9KV~T62(I8(&*~v4 zv&MSv=HBi_>Tu)Y7pSkEyNOYTQJ)hk898l18CxRlwVBGfa+-opovWF&8XUI51SmN`jf-N|V zIE#UawU%hQ+}3>ewq-~^t1uDN#hKsh!o{M3d;C8X&za5$*Z2iB_#)#nEwOp7Uwi!lp^x@Pa?b6Gj>W!y!T%uJj3Tj3h`B;B zO1S^-@>>7vle+L(c;_K6#UTo1+p2r~D04}-zQs3A{4fFD;|vjc!twH8cA;6rJt6hI zc?a)K`NYAH6z$eVvnV*ztwH23(3nN zkLtzdO@31K?QvDbUcPi%v=aNVo!~Xo%b2*;>3*k5Z6CCG+Bi?cr@i1mw}W64M*3L> z0pVZtB>DoX!*&OxkO@-wz;*7D+7E{%AX|^>AZJh*!QS9;6>Y*kcR|le{iDl-e)fhHfNj*Re-PnkAQ!%cAv7X>F!DMD-RID?zMr$HG|!jrPK2C zTGKBZI)pZj$c^lOv?Mt(^^cw%OkEHfSZ0slR9jY#@;3P%g^Rc_8rGD1aFjVzBUzMS zA*58Et3E`mo6VR!kd$`GtdB?RCi(p>cz)8LsDJh5xR&h6cXdxr)-rSOByB6SH6*g8 z9H1}22|ko(6m}rtFTPqg{UYI0mV#EZV5{aqPS6DU}Vd5os&PjE0T~ z;q#rMJY6#-zfuz`^c1MD(4L9d-Q3+Rp|9GdtzYxOINH;tkSZ%s5sOCml5k zCu#egeo$tJVWAmB58loRQ+PZ|N&j6Y$PErOz<@Hh*l|UTE;PT)e^*O@@cM89PKkj_ z$kT>FJ5T(HrQY{`Q<2K}B10ArCce$o|EGjf9wj_LaNB~T!aP?(ONP!2N zwmU%$G;In6%s*f}o%WeV;x{0i6ONp=T*svU8gzu&c%xKcbTf`{ z4J|?}l9i}8!xkjW$jiUG6$@&LHDtI0OPYxtUJ?f^EB>i;?wO7u<=iu9qTE~`(m7$O z{t-9*qdKp~^!;v@FU#%TM7GO{doR7XZK)qYMHvrME@X>-lvzH5)0LpkIGsJS*iQ*z zcw_>_RW*nJGA*DuHM!O8S+q4sPKH)$WZKnT%BrnrL3Ez}mO$H){$+V0X~XPLL;r4C z`;@Tx8WPT`L!gN@?2qpz^}QTx5#RApDx(Gv*(~6}d;Jo9%-{Li`iF;Osa;{S-6X|c zqB(?izf?9t1`+be1u8zeRHVqMM!Y#+F#Xj110E22P))qWH7#Jl(swCib%Lld%|)-b5)B%(mCPL*0gR;r^aoq&>J6bOZfF!*nj`E@K>2 z!|~}rniV&Np2q$7jU@S-yJPx_XQCjP`@qj(>1nz}ERb->8H10^I6P1{aD4g_8y(OV ze-HzY@{Sul0~Cm+oPL_s7-gRJZ34L|G}FrHj|RA@0_svYZ}R#NLbkF+ns{~jH1!>) zl$#@?z5k?0`s$d09g;QvaeTs5g zTDq~U@QK9L@&(qeGmDtIT4c0A={tkn;ei0*(&o*Ui(zvNo1X1 zo;%&hBr{_qQ8ku2BZ~@4;pH)R(fjkVqqxMhY9HO{0r<=&uTk024d31LuS$?1VhfL& zwP?(2F0%406$BPE(ao%Cg6n-MpeNL>mcW1m(7Q4MTZ!oxO6REJav`1MM$$8~u#3;^ zkoAbh+s`H%;Sx0|o1^qZ^wea5+15lyV+K;qd}G>v`>u@B?VY+xy}E^#sH*>FLFTepj5X6 zDtPEmj4ziw)(dg-xYAR~7+Z5Ug{rL3IISfvKxJ~9m)dyzlHGyF>mprblz2n}J@WQ4U#MyH^@7t{nSrR7$Oo$UT8ck%QH*YE~&Rh%2LK{tVoT;^M z%W+quM}N^paC7zl46}0^EZm6S_h;LaF(_QW^E^k;PM$4VsNP&ktw9uD&iUd{5{GcM z9Qivl$%c#@Pl@nKms{g0Tm2#Kgw!LnAj8a;N zB4eFAWe&aYk?in%5mfp)+@kVxNNhMZ_`7R#L{67IjKz-TC*4HEXHXg-3O!Ow+fwvH zez2d>4)%rm)wGwndG52e^hUj5SUj=S1q z2_V8+ei2nr-CvzHQD}}?P(A&)^yOiFg`7z&22N|5CR3Hhm#nPNQ%`(_nzR;HKwl`{ z%yAqgx9+ero|YdcGon=t-Bgf!yE3#NP|mG=XNRTZgS_7E5sB>^7StI2>x|zLdTQYv zPHPo(gK5A1B3)?oOh(Q*73R&QvT9|nY0FZ}WkNd+x~` zxW&rLImkKp$G)&k1Sg^&z`A&nAukkJtIshAqhsVVuo`oU9Fv3xMSzR!03=%thI8o4 z-<}K4uKBrsm>pokgv)7+KGSj=mU9dJak_@;(Tb#$D+`t1COT^Xas+Zzo~ zh|4G+?2e_Dj)1St^rQSD>RUTqs%MVl9Cz8=0L|4ciObgn9`}rTV@tX#F1Fu3k@DS| zoc1Zwr{faPv3I7Q7Da`#g5FhUTGIn#<9yGFvUhVd}QBc?y{aC&OPOo21BddYwZZ&S( z+%=+M)Z@J}?ERTr!%8W8Y$xqU8EC#}IJm@qcv-SpwQO`-zgR#O3-#5J; z7h&n#N`S`}mS`OWeabr)E~2C?c!_&@f*L+(N2+604yiN^G4PJb^a>d^pbKH_0|J3s z%Npmp1LTm_Hs`f`hOttQJ(}ZZg@rqHHK_r?)!C0vXqQXxoNFIFgsT=jlw9)^(06ch$gV?1nXFD(Ck(^_*pd z`5;iQZ}5smINdKq3^~F#2JjSYok8atN*4UDUf;ZPF^CJ-XtHC7e)1%!=%jCTpqV9e za$J%@WH<&)VRl*+47+b<&S+*D)9k=yQ<4!{z9&|>cPp&*Onm!qzdpwpah86~ZQ`<{)+52Jyuql>!en3*R^6`-AVLp{-}_-gije7S7efRj?U7 zM}uP~P8j1ee`gLo)}*aleJZ$QF)TtrG~=`>Nw|UaphxO8vhVgD;OU)G?&PsS{~sEV)IKTawtqtwPUk&cMILT;had(UqIOYCf`yrjw4v@ud5x%e! zFY3`Pc+agLg;-d?M+`XyrW8~i%hMohh%CuxUTE<&OON^F$gLTR(Oq(BpGY?GVjkJo zJNqQLebuh&hA1D@^x1#oJ@Zr`(n`_Z-F?l_Znvr?w*=J(kN(W5Ch%%pzo%@5tR0#E z%~<olm2Y>AYd3i!VQ}#YlayMchYU72s=k@&y?V^8p;x%@6)!WN z9g52-Z)Hz|9cm)<;D`8LYfnsoSri~Tf#_*jZNL*7tQ_mU&3S4HuprsH&Fj?9yoo(H z3&~k(mnP!6uB~dF@Bsl@7dry90PlrUCw(oFRL?}PT|M^{h+VjC)0C*U;)0>F?3=uJg0)8aqc|OTrG0ya$*wpKv0(99sUb&JvV?xwnvHWD;{=P zW=n38Z(=B<2)?*tW|yJSagwYeon+@mfyCaJ1sv3>NiNKME`s09zZ%;N)D9h{-(kwK za`ctM&9mNC_8GONTx8G_TeOqRC6g~pNonQx+pO`moa5pxXlRRW?>-Ck(Mu!pJRWgs z{?oIsuvXF1Hk?@8P34f-^2^8SqNn$37BTwN5Izpvc#Nzb6U7tu1H7icPBB8qQS7Cs zd2LUnujQ%76Q}ufq<+6ol(47Z;W=fh$YMF8tJt3LU44CHGVP&ERpm%Z!EWv-vo5@m z;(f^igLb^2OY*~xxNoUXO^yN$*TlU;hSlJ7Qs@a(U=-mfV*M|k>=ZX`{h&FR3( zbYc>p&GUmuD- z&nf~PqG!%p9JM^Twu*Rl8vRRCFbNX` z>4oPYJA;p(@Y6~Rt75)-FM&fs1D$xmfqv5k1PU0j^JOV!<_(HC)<>C}nMicN`hQolkEh`VX<3-p05cqG5!@8{rkI6s?$Rgs7bs z6%Epl4^}yK)?os%z;J6+$Pk=kD0mw`bRolOCoP;|zNv;@6Q=K=9%x1$o@FN&nDl+Q zM{=e6j$(hKZV-{t^CVCUten5GX7kOem=r7@XL05w1s?oWym8o zWHTDoYLj!YK~r0ePyB+}0I|ZQx%8JbZw_mC_|t};Yu1&vT9Z}K{Z0t(#&gM$@W!sA ze(N)}EDEGIUc-Puexh=087KTwH=%de>pc;DOW3T(r-OM5!m5Ldy0V#>rgu_-;nML{ z7fA&$v*ZI4C#KB;UP{!QU6d1VlD=JFoW{xeV!-)tN5WSvm#|-k;A@!Y}1Z|7gb^Ya9J= z4$-wDemb|pgVTB6h)y2|yrOKYBUv69*}f=HVqI9cvfoB}CuKasObE@Zj$NU^gl%F? zsRF9hr?}rwo(yN;V%pSJvKvnwKtJ(Il?lZhm?w0N4EI}({Hj_ZD3tl$^=+T&yUt)! zUkq6x0 z7DPGdW>%g;AR^%|LU-gRFeWF@RH?7ehBYp1yhJ@G@e(_s<#_=8hZO$ESp11!l@{Ff z7z;1-7WlqD67Gw9xHzDV;dH<0Tkh>Hfri0ocWnnaeKZdjH4c`of_&s3C)4D0HMglC zhJ9A+VYjEQ{4jGU?=zMYnR?YsG(_uGUgq`>Ft(CUC$~|I^<^5 zGO2hM2l)%qisJEIM#W@m@Otxf%Gv&u{N-VVt05-^Ia=-dT|y+jMiDfn&G&q}OLciU zB22yH!_Tf6x>sbl-!()7G63dBf{pGGI2HYL?GX@Zpyi&pYS;?(?avNbS8jX{;m_We zy0Cl$!{V**^@1a$F$}wVAQrwoi@2rS#>K#(>ULq91E6B&v)i!=8Fj~>{U8z`<^r!Bbgq=HTwle0nPFvr;K$O1`{i-8kYC zZl_bi=#Ki$vx=5|n0?rl1#Go;EHvI6wx)RFed)wI6k($}fc`n-tMy>k0<3cK-CM73 zo??o0uiG~XDxG;;LfGh2lWUgylfHvkV;JVV$_FM7&2sc%qw&<;A%+8V+g`z*zVCfg zc_FFQx9b-qMtWScq?i&CG>Mhpq(+LjVBPCg8>x|lH3f3m?w(ifo+=4Qi?G)zSCx>n z5D>QGh{fToR1oH=s;H9hpHK4T6WD9xsWL3;3ch%@FAJ2UgSiNT=KG;EklE%?Pvn^_ zz05aTBLceGt@7@$R|eX|W|)wn8}_1Oq}}-%{(y|STDm{I7ZTs6I!)_CgM5P4er`<$ z9(0dZ&bhczm%wgiIppNWV3?-WP`mDnrKx(bS-9US**rN}-V|I)J})QXwj{P?fanWcGk*vUvf9I9dS&ak$3#y- zFw@r}HiPfNmY|STTTApNU122YO6y0|2Y_a>P|r?R$;Hhm8UT9@W8OoVgn#IvVzXe$ z-{!)E(QD`GF^aapt2JlKP4_A7B`G-R$gAW7bcf4^^i59l=hM$#Hs61C4b2&vUY0Vk z7lrynHlxCb)0f%sp;qGfv<$*7b3!D_Z)hf$xcD7`FqXR3KF3#WW%$OxG1-?s?o@vM z73P}Ea~A{a#*;NndvBu~mLmShny}ZW=a~5>rh5Ltt-2C zAfe%t!^2Oe88yNyZ!(V&{Llgi$IpL%p-1&r&|HC!z93DX1?=dbI%iRZTtxuEIV8#- zDIK~luUStf)jS_xPw}ylkGPQ*Veav6kF7f(MaGbVyViE^qW) zpd@)5wB;fp)yaN=t!I8877~c#WWeuFlitb^h0$agd{F7BuZ#3%IqryN1xJR>rn(JT zz@N?rd_6v?V5Mo=C~}rnkK_5d`1HJ)o;89cUXEnqr-~jTm5|_S+)Gwtp)D)lu#~0{ zCikGo=rC1a`LThG^jddxb&C7slK=)aRSF9W&+R05E~ySh#OH;ZObsM-!Y(j!TRLmq zvNqT4PchIvpn@HdZ%C^JJ<5RXdvw@Q0;aU=Z)HY_$65}`>j(rq;-*Hj^0!JlCfXDb zY?=So)a=sqGJ2G>uR}%XZk2cIY*f*_486rIW;%5v@t{YabN4gQLX>~9j;;wAYapMK z36sf7OfuDp<{L-ZtN0msa5%_#FZa8FdFgTs+7QVImPc7%nV4-1ff`m|)(rZuLbN!4 zy2kI$_SxTXE9HXt5=N3icw*GLUzOE9NV%yjjSbGzSBjODc4_zPFnNU5Jb$63sq)G- zCH}K~mH%klNTtk+I8_Exs}M`5VE*PaVqZ@lqQ^NO5Lj>H(7z<=Sj_JkvpvdcGKN#7 zx$m)UGPhm_rpGvy2Eiu5u&|a%^esj}e5}v*2uA)`Uq8qJ(-kd=^yM}rSao?G9#)gv z5tZ6ShV#>JQ;hAWdB)0NRe}hnymP_`E>qBerjgw9DM1-Uz3_ZH1vv;-nX&D3hp8=E z&R}?%z+}U(;CH;-1$IazGzJo@N@%i?W?wq&gY<`bCP+qerlv zQ1by9iAU#4D@eGX)U0B<&xAvZOMdH$(U1r)W(AE7-~GChe9Sz_2bFy*JT`n6h4I_` z*l33=9Tt;{q{X79d;hq-9nl)$n-m?f7R}p!V|u;jY??(m@;eJ)K(MbarTR&Y4wJXp zb0)e(93GFaiW%<7?`DL8H7pt5#811wF1cm!yboB%o0M!En|qn^wh}t&^Gya&ndX&n zrSPT>Td1k5^Rz~q_E}p7ZQCGbsYpy|CV7*pe{$@?3KjHl_qmNKFEc ziI0#@t)w=J3hQlw;dabuDYUird2%?jfB=Qgde>BpfZ`*RruHMoaG?y9P=E+kVsD}a zgv)c*YlOd&`{96C`)ewH#>aNU2dVf>$He5y(p=rs2BhPUuMqjYU8H zk%QGgSlI22RQYPiD5_~H0(7KWx(TuxO|ckgz58VqVPDD9_2P4Wlqw_&!hCzQAUz1rx zY~LQqM4?bGRYpm$B7O1cf97%?_hCn4tY8t#NKYDrpyGFqwEKlPE^U>{Vh-QV$V5$5 zYkV4};hl5$fum4{ndT&++pAw>p7t`8a>k^)s4{?Tzmz!>{p87Qyo;pKs%!4|zZFdb zt36sjf}-^PBoS3(Nn`sb?lF>rgFlkjJ!>+KA55$JB_foZUNA{`Gk>giXotfxsdm6e zsXl9@qMAeY{JI(m>4@bS;lT^H{dw6f7bbhR7xAPu%eBTz%%2!E!|h+ST3^$MX$#!# zN5{hOI42_{sd81=k}~e*CW9)KBP-hs@+U#Lueec+w9!2H-%_$T4>6ThVN`b({#CtF#Z2@{`fr*&i1TQ@9G!ukPLHRBPHypzQSUrV5& z>}u}Y9)jlZ!yWkP;iufrxf+}-08*Pl7u_pS=!#1^Z}wdXzd_}n(pT&X-cGrL$!68D zq$CD79hHj3`agnr0*|o%X^z>zBz@lV#T4?6`*e^R&`pu%uC|`O)T@)RI+u>ZDiUXZhq*?g1Z#% zOv~;N4d8v<3UXKb!OxJNk-AQRNg9R`FZHAQwh>3SUHx-m=z>~&G^UV`^e?~7Kl*SY zDBAR%o{3wsR;6Tz+Bve;=C`V)_hyw+ClYBEH>P~{p@izuY^Tha;U|fyf+4waMPqxeMY|MkXUc^+xnsBv}>3-*S#3A9stZGyO&F7}+uV;y2 z+{#8;OXK}HuT%&5ZqY#`LG7X5r4eu^ZV{HwuGfzk1Wp<1JfU6rHQ5AOa~K& z?^&t8@{9}n8Wg;>2xr(AuK@*~@3Tqdv3Yi_T0z5ZUyJiw%mtrXA#}~qrrEh2-zRlh z_b>qyZ}=RTVKh6O|J{7?K=_RcY{pd_l7#=8-YXNMiR9*c9`ffpstQnTMhF zl1tmIhzt*M#X$pk68^jOMO$y5%)NX5wj})mFN^%K6^@ zoYcKa<$U-?@0)l|_afU|mx|g)EcfC=>dz9dc;B0{jbp)4kQVc#m4x7v!xX`FUkoMq zXLqaAghXG29{0~Y}qW3>zZOEGmrE!M@{yS7bR!DeG02lE2TH*@rDhbV+G-!t-U8 z^e1XPBN~@Y9mIDQN$nu(rB07JOy)xv$5c}wmVvxSvHaGIlo=uhujdYiVB(EYL=mG? zFa!RJI&pHcSLD`Lf_^-4YQxbyar(%wUsj7fb5Pp?k_DfIT^LlXi?H6()IKBFq&<~Q z^jQf(FW}L{^B)TBu+=9@NUO%Bkl*4yuHIW99bb8;XrudeEMjac>Be1FDBJYOFZl6J z=$t5k2>io*E38i%l+0{c`@+-0+7M4_xogCCWzwkJh=5L1Jlide+q9B9XlRhFu78*|DN`QE-X^~9#(KL z@X|Yk?2LVr?CW{idyH+nE{ij6sS!iK{V-CiD$dU9jeECXK+yzkwYpZGX>0jZ|1)!Q zn?K+ESVr(H{7*$Jq0ejL#a<)tuSuZNMa(d)c(G$Tfa9jSKld=>X;A&TF4#OdNdGe$ z93#$f|6~7KRrxu|8JZEzFZzQS52&P51XY$`>=wO)c{jhy8RgyX?I2U2->r4y_IpB~ zOEr&grT!5qHHrfpXU50Wh+5P77J|#h+^j`{&RI*S#d`1>kta>=f@o)1%OGud>}!+^W=(R(!e*=OwsJFa@FaR20D3`H;w-D5 zFDrDH(CbgMJ9r52l z;USZy+^F`4&zLbrQqChzcyx`2mO?5?1$g88WQ9y;#%!A-s{rq(c;T1 z{hDmdI>nDWJ7C4EgGW%+W+Ec(QlFl;E0ekgVP16oNN7izd=QH)$syic<`;Ly3Eve& zT~!dJAPLK^{A@(L_Mp?^^uQLTSDpkdZn$yYJ3W?Y?gYjGg9o2URpG4gbBc-I(~~4R z;a!Yai_ps>kIjjeuJ0mm623>{cVw*V`7e`bD-OqbFTDV2yCoTTXGS+SRT5j4MQ zvE%Z&jY?ujvo}{E0Q<4g3Ex-Ij5m7ww(H9K-s)+-oyH2$D=N&Y@ zGtohhaqs72Bk^`|%AK-bx}Sys7zM4vnNLw{9?P%YmZc$LDqX1l^B9HhLnUehCD8E- zNVrT1Y8K*DDCOvN((P*w6}lNm;z;+44IfOTFVBG^uDT8?3NW;Ti(Pv9oh&OtkPw)*KQW=sWIa1-&y5O4V{@g+%u1Z<8;2eM#q;Dgz{K38Q0f#5fk!{PAg zn3xc;?EK)h^~TPEtWlV55tSiGqk!9oFXnr9Lx`AzQ1B24P?cMPqAHYSt0OxxiP$Hd z`{RqqDlw~dCMtqo2|c2iva}J{K|tJW10+e5(=SQ8V0vX&@rC`1p5 zSWX!ghbQojXu5L=Tnz~PEgUWN_vXv)%*5*-6H7e>mvK6vNQknPts%=AOK5|^5V=uPm>AexYrVgv7rBvZy~b4SEDOEHL=}2Tw3@6Q#a{EM9pIuW;p~F- zy4Sm^NCHq@%HK0Ecl~8ommS8HDl-yl>SqXu(9LXqbW`Qz4s|lHK77*C5T3rB{lcvY zSibT<&Ca6DY#WICp4VyB+G#n8Pk%?C;}R=QMI2E#>+`9QIL$KgCAC2g&0n?6zO=Wb zib>Otf+S-|sn34Xo=?7O`p_(z$NC4ToLPz2*!{PVRHv34udc2}vbOXY&_NOkvixtg{5Q2Cy2p*~Zwg!upitFm9&|ij z?cvhe#<}~CGebtVU96+5%uV-agLhZQ+nX{46OHbNAm3jr$0Fdzj;GsW|MM#Fl}9#z z=U5k@$FTJ=fRTH6usw^FghipDT+%4+Q~d%KmJYX(~upX#kHdkLhn`N~T$ zyDb>3l3Wm0|2FPfBFESGTK}{B*a*~R+P;Vc;RPK7`GV13M8d-nHcW7hDYif|bVtvC z;A}HZeidEC%#IF+hmJi<$n_pF(vf>tnea0^7G?SmYFc8A{pm|tPkBneBM$J3i~aZ1 zvQ*!6d;Kw^xYO3sn&EA^8D{l8m8)dtZQ0VCKmH+3%KGW{3Vagka(+&6($fshYJL1bL=+J7;6y4E}qyyd9(@efvCD(&m++`I)d(&7J|jW1N+T#&JK9{wc`E zVw*Xjtzzql|25)N-HP@IXF4~^{Y>?&LEWs=w%0oN79;-PGISxk1(AfD&~4!AZ0O8w z8+n?5K$Rfbq`GcHsK->lj^pbW$nC}_qfhIs7~LI~u4E+9Rdjga$0B#kTHgNS103r8 z>4TfM2NO!H0Kha6vmFN4ysm1DxXQ|o#z){R=udlX`J<5EPwZ>t3KGRdTu;ZskDgqo z$x1ZGPYm3%ouwDcq>Hlgd-C!9F`-@b{$jrCD-q8_`-&+%V!G&*Dk<)Hd3=(kFNdz? z32b9X(kmN(gGGwa2GoukbIUcw%faO?1xNyNWqPqf?t zv4BtqK&r~#KOA|q`kbyy0L7~24w9I(>TVk>x9jgRw!Kd_S;03Q!I+BgZ>X~#4y>3S z0N`g=J4TNKB9U%AZe*h9vSnqH4cR%G_Bae6to?(PC2r5(q+t=7gfg16{+Hv16_enV zvjySQk7wrDe)Mi$sd)+Rt$(Aj$lD#nuahMq_M4J6xzZ__+|jEK!UQrqLs83LqV8TBYGZQc_OsGfIw z5R${JuJqNs?rz4b&ZTWk)~1tLvsf}=-;Y_NPbZ-wu0w?;#4(JHWQ$<}B%_gCqwp?# zCBgfX&PCr=L?J`Jd1dkU`))I>9uhs?)*;{=%XZT4>C46DMh5QjK^H{r7FKs{9rzDN zsr#|UxXW@LyOCvFp^m03u7VqnD4uvKOt6ap=U(MK&xgw+>gGF`B3?iBY;$x{G~2Aa5>6l}Cwz}`;zB7OCq&klZ-O9o$_zeK#9!@K@P&zh@K z_Iy)}JJ`w8)YN_`p0~VrB)lG}K(**)D8~V_mO?*Cj#Lg-ZKBazF&qiN)2QJ2D@Z8l zZSfy_FTSxKc=aOceTXe@(64G52B0Hldg&9De{`i>B-Z}eS3J)9_&;>=)$yLQog_JO zPOva~s%z>lqD=yo=IFSpQOcRK>yJV=-0nv{U6W9&CSASvCFf7#(a|Rp=p(fRmv-VR z;a#^s{&5aMPYyudFjwdC)r^mY8s_1o|Yn5<2KoKECblOlQ6pX})>KpQd~1UEm6= zl}xN0M}8BL<`!3--V1N$85(IkOiq4rM>cu8+gTw%6^p2-{13EX0A*qnHD}Pi*a&dZo$CWD>vXB>_=JYq4I;8 zUzM+mwirq`tg`_u{4}K*4_HBQH*XP6xBQVzIIqb5Y>UT?i=p3Vn+6&C%A*ou?QAv@)xg-W%9^}qvLzRnVAsT z9;&!Liu+KokqB<6MU~~`R&l2Ud$|nOz>#X=%FW>l$i3H2y*1~W9(?gc7}?!ZV5jnh zS0yj zdHS2-U~y5u!Fb#RKe$M!?1fW-w@VpI=xi(kyCf7U@ztulr!N(HV;;7jF0zU(e=w~* zd;vd!g=?zjUa-*@)wxpVEGwjAY|hVBtBX@sWM(WqN4?L!Oylh)0sW3By1p16%Imrg zAKyLxeVRa%^@~GbuySd^Ci~99LAJfHF!A=as>cu04eIv&Sm}7XK&CjvdvwT6xacG4 zxz1@4%ZusxH?0U^K3+OL2+%)C=ACMo!%C{oIkO%wvI9{`#R*QOMz`Lia`7f~DfYSM z{Ro2({w&^8y6?gV-}Zvvybdkl2y)sWjTV1g9~FWB2^FS6i{5B^+j^2XHXd!A39aOw zRBibt$5YW7)enHO;yC*}Cu?qO2z?C`d`49+lj|l_#%0!>`Ec6%1esjJwrK}44%l0O zgSVJ|ADE!$-z>-)_%QMcuhU~lGz`2|L_#u77p&=kx9cto`;i}c7Q~=S(gfv$b z2!+e!5cS`}TkKF~D_i4JmYB}JMj~BbNuAU7~K`2h{r-Plp6IK zgAlFS!ec5EmtroBco;fx+3pu92+*)KFGWH`;}~WIy9E~de4gD5uq#-xe#dk8Jp=g3 z1KJ8#U4FX>Y>&hIJVd{8acDd@`FSFjut@+n23`i$riWJ1^dAZdz_l5&3`S_S3UzRY zHkrvR6J=zbcdU!9zQm`UDr8&?We{PxEm`Px{}3O*Ci@AbSgWb?eizG1#RQ~TK|-=O ztMz?dzj>MPfl465CDlHXME^{GT#QFKGs$C9;mo^-Mfa?3R}5vyydx<Tb>2*i+U>jl|c%O99jd@(y`jAl@h8z4q#dIEWFmBdaL@m;MaZMlD9Quk% zWBRAxlKhp#WcgCk-e4?#l&k6G-}I%0;a2P@IXE)c4U~jAPAI*!ucI}B)8E4>EE{CN z*hh3WV2M4YM;5K710nOD+9SzL$L`Sm4*PRG5`rv`DC$?}hBn=)tzLT&ku_+uGnLA-zR z#pzV?y4S`dtM`Iix}(WCqfu9R#3HGuLLCc(7T=wJf6sm5n|-UR*`c5y*VVp?z)9=F2sQK-+$eR&-{*w3tRpO~O(GQ*9nPzl&9v-Nm?sT_^H zT9qBwF1kh8&gNDC$>BRZpmqJia!uVZQP>+$zprbu;n0r4%K*_+6 zW!{Ld=@^6>5T`iw_zx)yJ9lqv0t4&Be|A)%A2%*w0#7Y3!hMX+9)hf75^N>;Y`Qy` zz)w;{;1dlsH7!Nvi04w|emfhjZ%G%2iOVXt65}>(Jf`1JpcP-_t0#1G@7@g>ItSv9 z7$jdijRz6KYi&a|MdNyZqeipnH|iQU(|hlAn|z2|8}d!jwHKW|JTIw zoHAvJ4&zNiyLH_!hN>kbBqyt?&B1S~v>VV^Rv_DDzwHxkoX|VXyV4&!(Y4*v2kT9Y z&B+y8es(Z<5IoPS<*K(83W>w&}+fPw^udW8;{MH)WD)udpCdnTk};=N`9t( z(=;X0LeXVr+}$Ejq$L?~)cchs>p5XKWq3f#TJyE0seOU$*?LZOFBD!s95!yOnesM@ z*#?id1#&+9D7SbWKcyaauLMcPqz8B~e?Lp3V^j#C{PR+~w zd0O5Xa`4^`lgCg!U+xUp3M7!vhf_C|2IRRp&jV6yf=St_7ROID01k7Tu%5mB-_zWc z8d;okQ)7*CYImIdFjF3rG;a-mY#Db6{+F=Ze}#u-=4W((@Wd$6^SNYwo5b%U4WpYW zQl^3ARSOPXZyNZ24MpVF|B%r~)IDy}JM-L@y>qujKHc1w1o#=`x<_DlyII(lC(%7# z%ub>%pGx=M7ww#Nhi4o!-Oe*vanN?ur)7@90Gp}eL58toha3X>lZ_;;!wi+DubyQS9425+Ls0qS_CxjXnnU3R-K&Pr|aws6Gz z32gT(R5!^cs69-kEJ;!8OtW2EqCL!jt-`V$ z`2I#-eZPhT-BV*K=xy zoYnGc=Wyh@V5%bCk^%1me{qT6QrRqqkXE9ocE-8W0*#&)%J%PvhMBX zjciFM8xl!jzZha-IHvLIPftqn?Z7t@)pI4Wz-Qb7pVRoR+q_BJ}x#j zCYlpOH_Gh#Q20%xV;^H*H^G;QU*E!{pUx7F3A-awjU?}&LQ=qq))W`pI~=&S5rGwb?e#W9bavJ= z4727_ciMg8oq|sPhUb9evtv!K#mc?hISA(q006g`TQfL(duA31H8YVB-4zfvX=>Ay zJXDfz*R9&<6mTvb*R?{kjgOcw5K|NnW`6+yU>gc>)Fa)V=G`{AQzK8X&2Y3_&SwW7 z)0MzoabGF#d?aQX2R{pT`s=o?VF9zh003~yxfOm+k;rYdSGn-u#X}z-x%4%cmgOSq ztO_EMWUY(kvSY1|Wo4soZHq)rYF2~|b8je0y5gT6etRz1zmm=4j>phSx>jmxf4%;Q zjM-lR0NAbqtQzdL*()wV)a3GcdH+X!xrJb6GL*d9*%50S-e+yYAWEXFlm(dopQ)Bi zUCk}cE?s(^2(09dWg5@N&YYW_-D@%jQ$WPbzzfNd+lcS?RidnZ~#jj*IQej(SezV-;2cMH~7^xbhI zO~aVGe0u5HSSg$7*flD9n-45^_U{oe`wIX7+gX6`I_&5z7ojQ>@0>z4*wIld7GL_u zzs@BWi72@P0a4l0IQa&5y>4$%ad~j70RZ53aVrGIq<3Z2=8$ek`ztglciB`+mCGP#3_&P%&oG&IBNH>6cFUeL!=+Lh%}${?fDrv-bfL9VQw zqr29up{gyww6k}Yur|{*004mPCcwOv*YBh;Xs$SOCHY^LNuS4z$dr3r{;zy}(<8R5 zOUKjhBE7Rho+Xi-nlJF5wbw#ik|dkzN~RIU0`2XL(#H1J<@S61VW=+v0BmysHkqKC zcUGE1uCfVT;zG-qwf2{-v+FXs6BiuS(@VA!%T{1GNiHhDb z0cNJ;PPOfF95A=PlP8X=`FyRR2Nm6QdCOtnFXzRG|-A~Gj%jNOOvb*W@FsN#<&MXz{ zJ^RE+Xn&`7`*kV)?3IP82aomm-ZB_;%i`U5kB;>E@ks`EZsWam(}B}z_48*Fm~FfT zFna>{tpon9_?hLI32S+h*WW$5zhihODrZyR&g_M$+=ur@M`NBUxjNY4eedqbol{h9 zXufnI`RG94&4a-k6X41#;zxUKBI8lSkKNb4x#zky_vp^&merxtS^2jQbyfAHoC2V; zvb`KIqhGz4q7;iwZ;1d4!UuMT_jmY&!MBV&@RllV#w`Fh3>UMEYJP7#Gm}>P!q_?* zfV)9}e=w0vtEMcX>ECki+vb%Y>i2W?t*Nz8-&?@R**uph{)<-@-!T&0-|4Hg7q86Z zX0p}>T-;ecIus1LrN#$|d8CI20^c9cjz-;OCwgwtO2gtDXJ^#?*if+DUnAr9r(Rho z+LL_T3s%~}7T?~0#k|19b`Eu89+4j>Q8f99c-`_d{>DRHPF4SCD(4iQm+&1sLXIhPydb}j zOUor^WVz%0ge~+lk)|r?=4VY-a2aE{Z(L3f zgxyZ##ifY<$=e{_nDTb#YZsIMbY}UNk9O8;5S@mMw{G9Olqyy%-m5&0^X%u(B!2O5 z`+66cqMmvbTS+ZE=$kn$z}-2Ls26n*hrg8%z#$2$3`d8v3O zBULiqz9U@oyj(cnSSUE}b(;0CN2=`HvxYNqPRTp^7F#;7dW?!R~`S;qlnHZE*7K9QBTgg!fL-`& zDeVSs5OJ@lHR360npgMQWfqwwXT_66D z;6>u~P%aXG_Qc$pEV&Q%`OD(XFP!&*$_3`y%T-hE6m&drY`md-p=h#WoWT?ZHHh(=i;)>y`9@mwtjx881qP#qoX@x9&REh z(`vo2sd6LEf8oVQuB*C@!mqb%h1a_L>xQASN9+8aE}6X8;gum-RyhWcwUZn)KJ26| zv^y)Vk^jy=B&`INw^C{K3cR73sXPcjGOul}l;wft%4fNDR>>!Smfv@^;)*ISt*XFW zyho!5CfFJQ<{!uBCUQ{UE%v_TUma{43cI1ccQQ^({f*0M{!_25uY6^wj+8pjx}`OZ zb;MTvOv!lRTDB~fHRshDzrCgaS02Y1vi{7ecq>EJHP2NZnJgHr%_~*OA#dnYrCXh- z#~IMx=(~7l;#iN5Ysq|0k9Z_*%DK!`)=9m?I(NLXQ^nua;(YdPth8eN42Ha&ul(RO z?ez2om9tBwx9zWaM*2@il?rwp=_lUw|rXo%f}TIqEAQ)Jc))~hRdE^$0al>yH>={k|?_5s5v2&I2$%IQ(Ra4IWP{bqMvYWy+ zU?!^{>G9vN1~}&R$^C6ye)yrBsr1H&buRG6!eVY?rFrX&kdG}}6Aipu*7_*7GyHyO zxip?sG5)+I0(@?%@RbWG1O#m<9X{FdzNm^jpV2l?IY_5W&4hpbVHba8WrR^>W9=NL zD*lK!WZZ((9254)WPLGOfBSlzh@PH+as%h8Ofb1VKFEny8@z?fi`S3;w{B0Ly_)9N zl3ndlartTUN{OP`^svqaj#Y$BRc3;$s>5pUc&jR{vcOkti5-r(8@#e|mbdBLJpZKa zjJnS*Sy5~lf8KlnUdroVKA)rzhAqaKV}tj-OB}GZWRn}CaDhnI)%yF-qBJ1FaMoC;#_!D9aeG6D(%Ev!MSU898bntqlXLmUheJ*x!{;V4eL)4g(}3+kRyFy@`)Ci;x0;O& zK~J7Japu{t3amN~h#x{U^|^sZ7JH6~%tW zRtvccKYB)#q`INbgfJp@%%30vB6R@(0Dw&r;Mt3()qIl$bBqvgVM#Ps)`WRw(jQW= zI2Zr`0Jw1ho;-V^X?zubS~iM=n*4?PJ3OC!Q&&#_gQc5#w?uL+T|zwo0Khh&)hOun z{Iu+9A@;}Kr}n4!xAlizgb>)@O@>(;5uzFZ0N@@H;1;u7d42xhc(_M)ujDIUpCT0i z0000&>qF3y-a(;RbQKrfuAx!c?Je(=mn<1@YybcNz>N#=$o&r!A`($@dHpq4F7XEg zZJh_+_I?4o1poj50L^G=2%3v)-`@M9|37>8_8Z4p#&LY!!<={R^{x-QPTiEmZXL%- z+(1jKHX>?4ph^e-AXp=aOA=!BCJdue|HbJiE$oo_F4PXZA^(tXDt&@XEV?xOX8AV-{Zg=82UTY({gV zcmM!K6Tq!N6(Y_R?9cIdJ{q6s+=f9Z?fT*L$;FdjyC8Nx`E$8IeOj(F3Jn0jAOXCy z(=9EWF3g=slf;Iqv;iChcYk$%;~TP;9smHt2XH51y&!zpudv$`ce?<9LxB$UAW4m3 zZ4&?>fUyVYe*u61?k*pyl%+TT0C>y+>?#_zQL;xfGZ{@C0Du7QBG8J}phx_MNolAl z01&{BmJgKS_P`@zb2s){?-vu!0e}GRBJw2N+6cuiljZ<`0Pdk<^R?}O9fnLtWisLf zFaQw1-E>Aur^t-a30PSS00`h7m9j4V@2F&bMG*ji0Paa4)Qmun@@R%?0ssNri(_LR zi7^sNia<-IKmz~)+?{RL@}Xumj*+n8oAnri1^@!M2ew^vmB{l0o;e#F^_v94I99zSuBLq z0RRZ#K0GrS5WvG|jX(Rc5WAED00`hd!eh+WV?Our8KQ=cb0QZ|2LK>|`_Q>=_1RLC zkiP@h&~cWg8Gi-<0=R$6Qy~`v4=m8K5VE8;01&`^GR8!np2=_ubHM72`zl8O0{{Ws zul8~r&fFO57!M*b&Y2?P&j3IG51PW~iV<_62WWpoEzXxRlmY+<-~oeVD)wfxZb}o} zSKS=v`6ozU03d(|?tj~JpV_jyGo6-QVebT%YXp@5Wpko>KsSB zzBHkwAXgqOqm0ku8vsB6k2Hoa9?xbx zZW8>^^qr3Mh2xz41poqgq>N(%SN&iqSLgl=4-zQ(=5oRL|A;*RfB+s<2kf*?02ed< z#jnuhJ)r&l##7nYQx0c;0e}D=eFlqG2ER0yDP@=u{e>ho=Zn!wDW((vKmhMz23v2P zot%j^W35hmznz3;;*NzPKLu z=2qj^|NKv-o*dciDQ5JK&lZG`_U#~m0e}wpG4;Wdk^7UC$%*hNjzzb6-%$N%ne+t! zI^aFhNYh`wzj33|(9La`G-O&gLZ;GdxRE2(K`*qevP_%0v8|G-eUNBBRbHZl#Yz9W z&*a;00_h6?N60=}Ysu8AFD9!Wt^Qrqw`H1$wBgtQ7P{fZ>od>ZE-VO>9@zLz3pX!M zuDx$FSSIyW<14*XDiw{L$vx*d`F8S>z5qZ6{5Z48nCfQv)64Iz{^gz4v@E4}HiD+T ziNYjnv(K;1K6l_Us=fW`%x8a{zW%pVy5hclPnr!ch!0 zT)pxEpGyEBfOk=GVL8m^L~k>kMLUDXYd2$8x^lnwz{VIQoX}O-WV0Q_J-tLo8Ba_d zTRg|-5&#apy_^Ld#F>}h`dN8>ZM%Hyz2E;vyI$7}zIf`1!u-^&YI3`l+^E!VRGMp> zjdE>Ytl-gE*ef6ExiPnxbqkT33-m@X{lUMxY@B_e?S0R@`aLg-CyI0S*<26|0Egbb zm<4Ua=G|ZYyz<|ho#{yTZlYAOMVA)OE?xNc&R2DQzEf{rFE_7k*48$g*DH0; z>FKklFTO_T0ssNL2N}FozSXF1*Q*t=^NLs@{3zo`u@}a7bL~slDc#pBRvYPdGp!|Q zwPEhmlV)nl)ud_6?P}BR>g{S`|APIpZS*4ouhY)vg4XbO=!#Iwz?HF9u_r@U+J~MN zQTyRN3t2y~dA0vyt#YSc-KuX_oG%w#`$3q^*&XDw2ml1|;nB-ju5F;p+eznHwtFsS uT&?7ge-i+JBOSnlB{UHW0N8E+6JP)%y4A0GG=k{>0000 Date: Thu, 23 Sep 2021 08:27:00 -0400 Subject: [PATCH 3/8] Run tests on 1.17 now --- .github/workflows/run-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index c33eec9e..cb30fe73 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -12,7 +12,7 @@ jobs: golangci: strategy: matrix: - go-version: [1.15.x,1.16.x] + go-version: [1.15.x, 1.16.x, 1.17.x] os: [macos-latest, ubuntu-latest] name: lint runs-on: ${{ matrix.os }} @@ -26,7 +26,7 @@ jobs: build: strategy: matrix: - go-version: [ 1.14.x, 1.15.x, 1.16.x ] + go-version: [ 1.14.x, 1.15.x, 1.16.x, 1.17.x ] os: [ macos-latest, ubuntu-latest ] runs-on: ${{ matrix.os }} steps: From 3db5a874f7a05f5ec8f22aa44ec01a4d2fc5c778 Mon Sep 17 00:00:00 2001 From: mrz1836 Date: Thu, 23 Sep 2021 08:27:13 -0400 Subject: [PATCH 4/8] Check for the new 1.17 tests --- .github/mergify.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/mergify.yml b/.github/mergify.yml index 2bd8d480..4a379253 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -11,13 +11,16 @@ pull_request_rules: - check-success='build (1.14.x, ubuntu-latest)' - check-success='build (1.15.x, ubuntu-latest)' - check-success='build (1.16.x, ubuntu-latest)' + - check-success='build (1.17.x, ubuntu-latest)' - check-success='build (1.14.x, macos-latest)' - check-success='build (1.15.x, macos-latest)' - check-success='build (1.16.x, macos-latest)' + - check-success='build (1.17.x, macos-latest)' - check-success='lint (1.15.x, ubuntu-latest)' - check-success='lint (1.16.x, ubuntu-latest)' - check-success='lint (1.15.x, macos-latest)' - check-success='lint (1.16.x, macos-latest)' + - check-success='lint (1.17.x, macos-latest)' - check-success='Analyze (go)' - title~=^Bump [^\s]+ from ([\d]+)\..+ to \1\. actions: @@ -32,13 +35,16 @@ pull_request_rules: - check-success='build (1.14.x, ubuntu-latest)' - check-success='build (1.15.x, ubuntu-latest)' - check-success='build (1.16.x, ubuntu-latest)' + - check-success='build (1.17.x, ubuntu-latest)' - check-success='build (1.14.x, macos-latest)' - check-success='build (1.15.x, macos-latest)' - check-success='build (1.16.x, macos-latest)' + - check-success='build (1.17.x, macos-latest)' - check-success='lint (1.15.x, ubuntu-latest)' - check-success='lint (1.16.x, ubuntu-latest)' - check-success='lint (1.15.x, macos-latest)' - check-success='lint (1.16.x, macos-latest)' + - check-success='lint (1.17.x, macos-latest)' - check-success='Analyze (go)' - -title~=^Bump [^\s]+ from ([\d]+)\..+ to \1\. actions: @@ -56,13 +62,16 @@ pull_request_rules: - check-success='build (1.14.x, ubuntu-latest)' - check-success='build (1.15.x, ubuntu-latest)' - check-success='build (1.16.x, ubuntu-latest)' + - check-success='build (1.17.x, ubuntu-latest)' - check-success='build (1.14.x, macos-latest)' - check-success='build (1.15.x, macos-latest)' - check-success='build (1.16.x, macos-latest)' + - check-success='build (1.17.x, macos-latest)' - check-success='lint (1.15.x, ubuntu-latest)' - check-success='lint (1.16.x, ubuntu-latest)' - check-success='lint (1.15.x, macos-latest)' - check-success='lint (1.16.x, macos-latest)' + - check-success='lint (1.17.x, macos-latest)' - check-success='Analyze (go)' - label!=work-in-progress - -draft From 91515227a5ed4691a9310df9fe00803e15470688 Mon Sep 17 00:00:00 2001 From: mrz1836 Date: Thu, 23 Sep 2021 08:27:31 -0400 Subject: [PATCH 5/8] Minor fixes, file locations, added link --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dee212e7..e0df76f0 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ For more information around the technical aspects of Bitcoin, please see the upd - Full Featured Bitcoin Transactions - Auto-Fee Calculations for Change Address -- Bitcoin Transaction [Script](bscript/) Functionality +- Bitcoin Transaction [Script](bscript) Functionality - P2PKH (base58 addresses) - Data (OP_RETURN) - [BIP276](https://github.com/moneybutton/bips/blob/master/bip-0276.mediawiki) @@ -123,7 +123,7 @@ vet Run the Go vet application ## Examples & Tests All unit tests and [examples](examples) run via [Github Actions](https://github.com/libsv/go-bt/actions) and -uses [Go version 1.15.x](https://golang.org/doc/go1.15). View the [configuration file](.github/workflows/run-tests.yml). +uses [Go version 1.16.x](https://golang.org/doc/go1.16). View the [configuration file](.github/workflows/run-tests.yml). Run all tests (including integration tests) @@ -151,7 +151,7 @@ make bench ## Code Standards -Read more about this Go project's [code standards](CODE_STANDARDS.md). +Read more about this Go project's [code standards](.github/CODE_STANDARDS.md).
@@ -171,7 +171,7 @@ View the [examples](examples) ## Contributing -View the [contributing guidelines](CONTRIBUTING.md) and please follow the [code of conduct](CODE_OF_CONDUCT.md). +View the [contributing guidelines](.github/CONTRIBUTING.md) and please follow the [code of conduct](.github/CODE_OF_CONDUCT.md). ### How can I help? @@ -180,8 +180,10 @@ The most basic way to show your support is to star :star2: the project, or to ra You can also support this project by [becoming a sponsor on GitHub](https://github.com/sponsors/libsv) :clap: or by making a [**bitcoin donation**](https://gobitcoinsv.com/#sponsor) to ensure this journey continues indefinitely! :rocket: +[![Stars](https://img.shields.io/github/stars/libsv/go-bt?label=Please%20like%20us&style=social)](https://github.com/libsv/go-bt/stargazers) +
## License -![License](https://img.shields.io/github/license/libsv/go-bt.svg?style=flat&v=1) +[![License](https://img.shields.io/github/license/libsv/go-bt.svg?style=flat&v=1)](LICENSE) From 72fe7834b1244a7061e351b510ddc64e7a089d79 Mon Sep 17 00:00:00 2001 From: mrz1836 Date: Thu, 23 Sep 2021 08:47:04 -0400 Subject: [PATCH 6/8] Removed deprecated linter, cleaned up grammar --- .golangci.yml | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index f914cfc6..895af4ff 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,11 +3,11 @@ # options for analysis running run: - # default concurrency is a available CPU number + # default concurrency is an available CPU number concurrency: 4 # timeout for analysis, e.g. 30s, 5m, default is 1m - timeout: 1m + timeout: 4m # exit code when at least one issue was found, default is 1 issues-exit-code: 1 @@ -22,7 +22,7 @@ run: # which dirs to skip: issues from them won't be reported; # can use regexp here: generated.*, regexp is applied on full path; # default value is empty list, but default dirs are skipped independently - # from this option's value (see skip-dirs-use-default). + # of this option's value (see skip-dirs-use-default). # "/" will be replaced by current OS file path separator to properly work # on Windows. skip-dirs: @@ -192,14 +192,11 @@ linters-settings: # See the License for the specific language governing permissions and # limitations under the License. template-path: - # also as alternative of directive 'template' you may put the path to file with the template source + # also, as alternative of directive 'template' you may put the path to file with the template source goimports: # put imports beginning with prefix after 3rd-party packages; # it's a comma-separated list of prefixes local-prefixes: github.com/org/project - golint: - # minimal confidence for issues, default is 0.8 - min-confidence: 0.8 gomnd: settings: mnd: @@ -251,7 +248,7 @@ linters-settings: - bsv - bitcoin nakedret: - # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 + # make an issue if func has more lines of code than this setting, and it has naked returns; default is 30 max-func-lines: 30 prealloc: # XXX: we don't recommend using this linter before doing performance profiling. @@ -296,7 +293,7 @@ linters-settings: multi-func: false # Enforces newlines (or comments) after every multi-line function signature wsl: # If true append is only allowed to be cuddled if appending value is - # matching variables, fields or types on line above. Default is true. + # matching variables, fields or types on the line above. Default is true. strict-append: true # Allow calls and assignments to be cuddled as long as the lines have any # matching variables, fields or types. Default is true. @@ -314,7 +311,7 @@ linters-settings: # Allow leading comments to be separated with empty liens allow-separated-leading-comment: false gofumpt: - # Choose whether or not to use the extra rules that are disabled + # Choose whether to use the extra rules that are disabled # by default extra-rules: false @@ -336,7 +333,6 @@ linters: - govet - gosec - bodyclose - - golint - unconvert - dupl - misspell @@ -372,7 +368,7 @@ linters: issues: # List of regexps of issue texts to exclude, empty list by default. - # But independently from this option we use default exclude patterns, + # But independently of this option we use default exclude patterns, # it can be disabled by `exclude-use-default: false`. To list all # excluded by default patterns execute `golangci-lint run --help` exclude: @@ -408,7 +404,7 @@ issues: - lll source: "^//go:generate " - # Independently from option `exclude` we use default exclude patterns, + # Independently of option `exclude` we use default exclude patterns, # it can be disabled by this option. To list all # excluded by default patterns execute `golangci-lint run --help`. # Default value for this option is true. @@ -418,10 +414,6 @@ issues: # regular expressions become case sensitive. exclude-case-sensitive: false - # The list of ids of default excludes to include or disable. By default it's empty. - include: - - EXC0002 # disable excluding of issues about comments from golint - # Maximum issues count per one linter. Set to 0 to disable. Default is 50. max-issues-per-linter: 0 @@ -454,7 +446,7 @@ severity: default-severity: error # The default value is false. - # If set to true severity-rules regular expressions become case sensitive. + # If set to true severity-rules regular expressions become case-sensitive. case-sensitive: false # Default value is empty list. From 8b38c2b7f2ca6ebc753c3671a93b1902ca56b6df Mon Sep 17 00:00:00 2001 From: mrz1836 Date: Thu, 23 Sep 2021 08:47:21 -0400 Subject: [PATCH 7/8] Grammar, spelling errors, better keywords --- bscript/address.go | 14 +++++++------- bscript/bip276.go | 2 +- bscript/interpreter/doc.go | 2 +- bscript/interpreter/engine.go | 6 +++--- bscript/interpreter/engine_test.go | 2 +- bscript/interpreter/error.go | 10 +++++----- bscript/interpreter/opcodeparser.go | 4 ++-- bscript/interpreter/scriptnum.go | 10 +++++----- bscript/interpreter/thread.go | 18 +++++++++--------- bscript/script.go | 4 ++-- bscript/unlockingscript_test.go | 6 +++--- examples/create_tx/create_tx.go | 4 ++-- .../create_tx_with_opreturn.go | 4 ++-- fees.go | 6 +++--- fees_test.go | 18 +++++++++--------- input.go | 6 +++--- output.go | 4 ++-- sighash/flag.go | 8 +++++--- signaturehash.go | 6 +++--- tx.go | 2 ++ txchange.go | 4 ++-- txinput.go | 2 +- varint.go | 2 +- 23 files changed, 74 insertions(+), 70 deletions(-) diff --git a/bscript/address.go b/bscript/address.go index 4c0b759e..11d89347 100644 --- a/bscript/address.go +++ b/bscript/address.go @@ -16,8 +16,8 @@ const ( hashTestNetP2SH = 0xc4 ) -// An Address struct contains the address string as well as the hash160 hexstring of the public key. -// The address string will be human readable and specific to the network type, but the public key hash +// An Address struct contains the address string as well as the hash160 hex string of the public key. +// The address string will be human-readable and specific to the network type, but the public key hash // is useful because it stays the same regardless of the network type (mainnet, testnet). type Address struct { AddressString string @@ -62,7 +62,7 @@ func addressToPubKeyHashStr(address string) (string, error) { // NewAddressFromPublicKeyString takes a public key string and returns an Address struct pointer. // If mainnet parameter is true it will return a mainnet address (starting with a 1). -// Otherwise (mainnet is false) it will return a testnet address (starting with an m or n). +// Otherwise, (mainnet is false) it will return a testnet address (starting with an m or n). func NewAddressFromPublicKeyString(pubKey string, mainnet bool) (*Address, error) { pubKeyBytes, err := hex.DecodeString(pubKey) if err != nil { @@ -73,7 +73,7 @@ func NewAddressFromPublicKeyString(pubKey string, mainnet bool) (*Address, error // NewAddressFromPublicKeyHash takes a public key hash in bytes and returns an Address struct pointer. // If mainnet parameter is true it will return a mainnet address (starting with a 1). -// Otherwise (mainnet is false) it will return a testnet address (starting with an m or n). +// Otherwise, (mainnet is false) it will return a testnet address (starting with an m or n). func NewAddressFromPublicKeyHash(hash []byte, mainnet bool) (*Address, error) { // regtest := 111 @@ -83,7 +83,7 @@ func NewAddressFromPublicKeyHash(hash []byte, mainnet bool) (*Address, error) { if !mainnet { bb[0] = 111 } - // nolint: makezero // we need to setup the array with 1 + // nolint: makezero // we need to set up the array with 1 bb = append(bb, hash...) return &Address{ @@ -94,7 +94,7 @@ func NewAddressFromPublicKeyHash(hash []byte, mainnet bool) (*Address, error) { // NewAddressFromPublicKey takes a bec public key and returns an Address struct pointer. // If mainnet parameter is true it will return a mainnet address (starting with a 1). -// Otherwise (mainnet is false) it will return a testnet address (starting with an m or n). +// Otherwise, (mainnet is false) it will return a testnet address (starting with an m or n). func NewAddressFromPublicKey(pubKey *bec.PublicKey, mainnet bool) (*Address, error) { hash := crypto.Hash160(pubKey.SerialiseCompressed()) @@ -105,7 +105,7 @@ func NewAddressFromPublicKey(pubKey *bec.PublicKey, mainnet bool) (*Address, err if !mainnet { bb[0] = 111 } - // nolint: makezero // we need to setup the array with 1 + // nolint: makezero // we need to set up the array with 1 bb = append(bb, hash...) return &Address{ diff --git a/bscript/bip276.go b/bscript/bip276.go index 5e773ab5..ad910d68 100644 --- a/bscript/bip276.go +++ b/bscript/bip276.go @@ -10,7 +10,7 @@ import ( "github.com/libsv/go-bk/crypto" ) -// BIP276 proposes a scheme for encoding typed bitcoin related data in a user friendly way +// BIP276 proposes a scheme for encoding typed bitcoin related data in a user-friendly way // see https://github.com/moneybutton/bips/blob/master/bip-0276.mediawiki type BIP276 struct { Prefix string diff --git a/bscript/interpreter/doc.go b/bscript/interpreter/doc.go index b849f1f8..7316174a 100644 --- a/bscript/interpreter/doc.go +++ b/bscript/interpreter/doc.go @@ -25,7 +25,7 @@ to right and intentionally do not provide loops. The vast majority of Bitcoin scripts at the time of this writing are of several standard forms which consist of a spender providing a public key and a signature which proves the spender owns the associated private key. This information -is used to prove the the spender is authorized to perform the transaction. +is used to prove the spender is authorized to perform the transaction. One benefit of using a scripting language is added flexibility in specifying what conditions must be met in order to spend bitcoins. diff --git a/bscript/interpreter/engine.go b/bscript/interpreter/engine.go index e89cc367..bc04038b 100644 --- a/bscript/interpreter/engine.go +++ b/bscript/interpreter/engine.go @@ -49,10 +49,10 @@ const ( ScriptVerifyCleanStack // ScriptVerifyDERSignatures defines that signatures are required - // to compily with the DER format. + // to comply with the DER format. ScriptVerifyDERSignatures - // ScriptVerifyLowS defines that signtures are required to comply with + // ScriptVerifyLowS defines that signatures are required to comply with // the DER format and whose S value is <= order / 2. This is rule 5 // of BIP0062. ScriptVerifyLowS @@ -100,7 +100,7 @@ func (s *ScriptFlags) AddFlag(flag ScriptFlags) { *s |= flag } -// halforder is used to tame ECDSA malleability (see BIP0062). +// halfOrder is used to tame ECDSA malleability (see BIP0062). var halfOrder = new(big.Int).Rsh(bec.S256().N, 1) // Engine is the virtual machine that executes scripts. diff --git a/bscript/interpreter/engine_test.go b/bscript/interpreter/engine_test.go index 9fd1fb85..d3384a93 100644 --- a/bscript/interpreter/engine_test.go +++ b/bscript/interpreter/engine_test.go @@ -81,7 +81,7 @@ func TestBadPC(t *testing.T) { } } -// TestCheckErrorCondition tests the execute early test in CheckErrorCondition() +// TestCheckErrorCondition tests to execute early test in CheckErrorCondition() // since most code paths are tested elsewhere. func TestCheckErrorCondition(t *testing.T) { t.Parallel() diff --git a/bscript/interpreter/error.go b/bscript/interpreter/error.go index ffd54753..f9fc71b2 100644 --- a/bscript/interpreter/error.go +++ b/bscript/interpreter/error.go @@ -73,7 +73,7 @@ const ( // a script that has not finished executing. ErrScriptUnfinished - // ErrScriptDone is returned when an attempt to execute an opcode is + // ErrInvalidProgramCounter is returned when an attempt to execute an opcode is // made once all of them have already been executed. This can happen // due to things such as a second call to Execute or calling Step after // all opcodes have already been executed. @@ -99,7 +99,7 @@ const ( ErrStackOverflow // ErrInvalidPubKeyCount is returned when the number of public keys - // specified for a multsig is either negative or greater than + // specified for a multisig is either negative or greater than // MaxPubKeysPerMultiSig. ErrInvalidPubKeyCount @@ -150,7 +150,7 @@ const ( // true. ErrCheckSigVerify - // ErrCheckSigVerify is returned when OP_CHECKMULTISIGVERIFY is + // ErrCheckMultiSigVerify is returned when OP_CHECKMULTISIGVERIFY is // encountered in a script and the top item on the data stack does not // evaluate to true. ErrCheckMultiSigVerify @@ -290,7 +290,7 @@ const ( ErrPubKeyType // ErrCleanStack is returned when the ScriptVerifyCleanStack flag - // is set, and after evalution, the stack does not contain only a + // is set, and after evaluation, the stack does not contain only a // single element. ErrCleanStack @@ -426,7 +426,7 @@ func scriptError(c ErrorCode, desc string, fmtArgs ...interface{}) Error { return Error{ErrorCode: c, Description: fmt.Sprintf(desc, fmtArgs...)} } -// IsErrorCode returns whether or not the provided error is a script error with +// IsErrorCode returns whether the provided error is a script error with // the provided error code. func IsErrorCode(err error, c ErrorCode) bool { e := &Error{} diff --git a/bscript/interpreter/opcodeparser.go b/bscript/interpreter/opcodeparser.go index 6c20c79f..3cad2983 100644 --- a/bscript/interpreter/opcodeparser.go +++ b/bscript/interpreter/opcodeparser.go @@ -30,7 +30,7 @@ type ParsedOp struct { Data []byte } -// Name returns the human readible name for the current opcode +// Name returns the human readable name for the current opcode func (o *ParsedOp) Name() string { return o.Op.name } @@ -151,7 +151,7 @@ func (p *parser) Parse(s *bscript.Script) (ParsedScript, error) { return parsedOps, nil } -// unparseScript reversed the action of parseScript and returns the +// Unparse reversed the action of parseScript and returns the // parsedOpcodes as a list of bytes func (p *parser) Unparse(pscr ParsedScript) (*bscript.Script, error) { script := make(bscript.Script, 0, len(pscr)) diff --git a/bscript/interpreter/scriptnum.go b/bscript/interpreter/scriptnum.go index 1f7749ea..988e3a62 100644 --- a/bscript/interpreter/scriptnum.go +++ b/bscript/interpreter/scriptnum.go @@ -45,7 +45,7 @@ const ( // interpreting it as an integer, it provides the required behaviour. type scriptNum int64 -// checkMinimalDataEncoding returns whether or not the passed byte array adheres +// checkMinimalDataEncoding returns whether the passed byte array adheres // to the minimal encoding requirements. func checkMinimalDataEncoding(v []byte) error { if len(v) == 0 { @@ -135,7 +135,7 @@ func (n scriptNum) Bytes() []byte { // when the script number is higher than the max allowed int32, the max int32 // value is returned and vice versa for the minimum value. Note that this // behaviour is different from a simple int32 cast because that truncates -// and the consensus rules dictate numbers which are directly cast to ints +// and the consensus rules dictate numbers which are directly cast to integers // provide this behaviour. // // In practice, for most opcodes, the number should never be out of range since @@ -163,10 +163,10 @@ func (n scriptNum) Int64() int64 { // makeScriptNum interprets the passed serialised bytes as an encoded integer // and returns the result as a script number. // -// Since the consensus rules dictate that serialised bytes interpreted as ints +// Since the consensus rules dictate that serialised bytes interpreted as integers // are only allowed to be in the range determined by a maximum number of bytes, // on a per opcode basis, an error will be returned when the provided bytes -// would result in a number outside of that range. In particular, the range for +// would result in a number outside that range. In particular, the range for // the vast majority of opcodes dealing with numeric values are limited to 4 // bytes and therefore will pass that value to this function resulting in an // allowed range of [-2^31 + 1, 2^31 - 1]. @@ -188,7 +188,7 @@ func (n scriptNum) Int64() int64 { // See the Bytes function documentation for example encodings. func makeScriptNum(v []byte, requireMinimal bool, scriptNumLen int) (scriptNum, error) { // Interpreting data requires that it is not larger than - // the the passed scriptNumLen value. + // the passed scriptNumLen value. if len(v) > scriptNumLen { str := fmt.Sprintf("numeric value encoded as %x is %d bytes "+ "which exceeds the max allowed of %d", v, len(v), diff --git a/bscript/interpreter/thread.go b/bscript/interpreter/thread.go index eccb499f..78323bc7 100644 --- a/bscript/interpreter/thread.go +++ b/bscript/interpreter/thread.go @@ -55,7 +55,7 @@ func (t *thread) addFlag(flag ScriptFlags) { t.flags.AddFlag(flag) } -// isBranchExecuting returns whether or not the current conditional branch is +// isBranchExecuting returns whether the current conditional branch is // actively executing. For example, when the data stack has an OP_FALSE on it // and an OP_IF is encountered, the branch is inactive until an OP_ELSE or // OP_ENDIF is encountered. It properly handles nested conditionals. @@ -64,7 +64,7 @@ func (t *thread) isBranchExecuting() bool { } // executeOpcode performs execution on the passed opcode. It takes into account -// whether or not it is hidden by conditionals, but some rules still must be +// whether it is hidden by conditionals, but some rules still must be // tested in this case. func (t *thread) executeOpcode(pop ParsedOp) error { if len(pop.Data) > t.cfg.MaxScriptElementSize() { @@ -98,7 +98,7 @@ func (t *thread) executeOpcode(pop ParsedOp) error { "element size %d exceeds max allowed size %d", len(pop.Data), t.cfg.MaxScriptElementSize()) } - // Nothing left to do when this is not a conditional opcode and it is + // Nothing left to do when this is not a conditional opcode, and it is // not in an executing branch. if !t.isBranchExecuting() && !pop.IsConditional() { return nil @@ -136,7 +136,7 @@ func (t *thread) validPC() error { } // CheckErrorCondition returns nil if the running script has ended and was -// successful, leaving a a true boolean on the stack. An error otherwise, +// successful, leaving a true boolean on the stack. An error otherwise, // including if the script has not finished. func (t *thread) CheckErrorCondition(finalScript bool) error { if t.dstack.Depth() < 1 { @@ -389,7 +389,7 @@ func (t *thread) subScript() ParsedScript { return t.scripts[t.scriptIdx][t.lastCodeSep:] } -// checkHashTypeEncoding returns whether or not the passed hashtype adheres to +// checkHashTypeEncoding returns whether the passed hashtype adheres to // the strict encoding requirements if enabled. func (t *thread) checkHashTypeEncoding(shf sighash.Flag) error { if !t.hasFlag(ScriptVerifyStrictEncoding) { @@ -425,7 +425,7 @@ func (t *thread) checkHashTypeEncoding(shf sighash.Flag) error { return nil } -// checkPubKeyEncoding returns whether or not the passed public key adheres to +// checkPubKeyEncoding returns whether the passed public key adheres to // the strict encoding requirements if enabled. func (t *thread) checkPubKeyEncoding(pubKey []byte) error { if !t.hasFlag(ScriptVerifyStrictEncoding) { @@ -444,7 +444,7 @@ func (t *thread) checkPubKeyEncoding(pubKey []byte) error { return scriptError(ErrPubKeyType, "unsupported public key type") } -// checkSignatureEncoding returns whether or not the passed signature adheres to +// checkSignatureEncoding returns whether the passed signature adheres to // the strict encoding requirements if enabled. func (t *thread) checkSignatureEncoding(sig []byte) error { if !t.hasFlag(ScriptVerifyDERSignatures) && !t.hasFlag(ScriptVerifyLowS) && !t.hasFlag(ScriptVerifyStrictEncoding) { @@ -482,7 +482,7 @@ func (t *thread) checkSignatureEncoding(sig []byte) error { // maxSigLen is the maximum length of a DER encoded signature and is // when both R and S are 33 bytes each. It is 33 bytes because a // 256-bit integer requires 32 bytes and an additional leading null byte - // might required if the high bit is set in the value. + // might be required if the high bit is set in the value. // // 0x30 + <1-byte> + 0x02 + 0x21 + <33 bytes> + 0x2 + 0x21 + <33 bytes> maxSigLen = 72 @@ -622,7 +622,7 @@ func (t *thread) checkSignatureEncoding(sig []byte) error { func getStack(stack *stack) [][]byte { array := make([][]byte, stack.Depth()) for i := range array { - // PeekByteArry can't fail due to overflow, already checked + // PeekByteArray can't fail due to overflow, already checked array[len(array)-i-1], _ = stack.PeekByteArray(int32(i)) } return array diff --git a/bscript/script.go b/bscript/script.go index f8174dc5..5bde9a84 100644 --- a/bscript/script.go +++ b/bscript/script.go @@ -182,9 +182,9 @@ func (s *Script) AppendPushDataArray(d [][]byte) error { // AppendPushDataStrings takes an array of strings and appends their // UTF-8 encoding to the script with proper PUSHDATA prefixes -func (s *Script) AppendPushDataStrings(strs []string) error { +func (s *Script) AppendPushDataStrings(pushDataStrings []string) error { dataBytes := make([][]byte, 0) - for _, str := range strs { + for _, str := range pushDataStrings { strBytes := []byte(str) dataBytes = append(dataBytes, strBytes) } diff --git a/bscript/unlockingscript_test.go b/bscript/unlockingscript_test.go index a1672a32..73687486 100644 --- a/bscript/unlockingscript_test.go +++ b/bscript/unlockingscript_test.go @@ -11,12 +11,12 @@ func TestNewP2PKHUnlockingScript(t *testing.T) { t.Run("unlock script with valid pubkey", func(t *testing.T) { - wif, err := wif.DecodeWIF("KznvCNc6Yf4iztSThoMH6oHWzH9EgjfodKxmeuUGPq5DEX5maspS") + decodedWif, err := wif.DecodeWIF("KznvCNc6Yf4iztSThoMH6oHWzH9EgjfodKxmeuUGPq5DEX5maspS") assert.NoError(t, err) - assert.NotNil(t, wif) + assert.NotNil(t, decodedWif) var script *Script - script, err = NewP2PKHUnlockingScript(wif.SerialisePubKey(), []byte("some-signature"), 0) + script, err = NewP2PKHUnlockingScript(decodedWif.SerialisePubKey(), []byte("some-signature"), 0) assert.NoError(t, err) assert.NotNil(t, script) assert.Equal(t, "0f736f6d652d7369676e6174757265002102798913bc057b344de675dac34faafe3dc2f312c758cd9068209f810877306d66", script.String()) diff --git a/examples/create_tx/create_tx.go b/examples/create_tx/create_tx.go index ee11c689..b58c7864 100644 --- a/examples/create_tx/create_tx.go +++ b/examples/create_tx/create_tx.go @@ -20,9 +20,9 @@ func main() { _ = tx.PayToAddress("1NRoySJ9Lvby6DuE2UQYnyT67AASwNZxGb", 1000) - wif, _ := wif.DecodeWIF("KznvCNc6Yf4iztSThoMH6oHWzH9EgjfodKxmeuUGPq5DEX5maspS") + decodedWif, _ := wif.DecodeWIF("KznvCNc6Yf4iztSThoMH6oHWzH9EgjfodKxmeuUGPq5DEX5maspS") - if err := tx.SignAll(context.Background(), &bt.LocalSignerGetter{PrivateKey: wif.PrivKey}); err != nil { + if err := tx.SignAll(context.Background(), &bt.LocalSignerGetter{PrivateKey: decodedWif.PrivKey}); err != nil { log.Fatal(err.Error()) } log.Printf("tx: %s\n", tx) diff --git a/examples/create_tx_with_opreturn/create_tx_with_opreturn.go b/examples/create_tx_with_opreturn/create_tx_with_opreturn.go index b44c6630..1d31c75a 100644 --- a/examples/create_tx_with_opreturn/create_tx_with_opreturn.go +++ b/examples/create_tx_with_opreturn/create_tx_with_opreturn.go @@ -22,9 +22,9 @@ func main() { _ = tx.AddOpReturnOutput([]byte("You are using go-bt!")) - wif, _ := wif.DecodeWIF("L3VJH2hcRGYYG6YrbWGmsxQC1zyYixA82YjgEyrEUWDs4ALgk8Vu") + decodedWif, _ := wif.DecodeWIF("L3VJH2hcRGYYG6YrbWGmsxQC1zyYixA82YjgEyrEUWDs4ALgk8Vu") - err := tx.SignAll(context.Background(), &bt.LocalSignerGetter{PrivateKey: wif.PrivKey}) + err := tx.SignAll(context.Background(), &bt.LocalSignerGetter{PrivateKey: decodedWif.PrivKey}) if err != nil { log.Fatal(err.Error()) } diff --git a/fees.go b/fees.go index e5f53874..e57c48f5 100644 --- a/fees.go +++ b/fees.go @@ -34,7 +34,7 @@ const ( // FeeQuotes contains a list of miners and the current fees for each miner as well as their expiry. // -// This can be used when getting fees from multiple miners and you want to use the cheapest for example. +// This can be used when getting fees from multiple miners, and you want to use the cheapest for example. // // Usage setup should be calling NewFeeQuotes(minerName). type FeeQuotes struct { @@ -42,7 +42,7 @@ type FeeQuotes struct { quotes map[string]*FeeQuote } -// NewFeeQuotes will setup default feeQuotes for the minerName supplied, ie TAAL etc. +// NewFeeQuotes will set up default feeQuotes for the minerName supplied, ie TAAL etc. func NewFeeQuotes(minerName string) *FeeQuotes { return &FeeQuotes{ mu: sync.RWMutex{}, @@ -133,7 +133,7 @@ type FeeQuote struct { expiryTime time.Time } -// NewFeeQuote will setup and return a new FeeQuotes struct which +// NewFeeQuote will set up and return a new FeeQuotes struct which // contains default fees when initially setup. You would then pass this // data structure to a singleton struct via injection for reading. // If you are only getting quotes from one miner you can use this directly diff --git a/fees_test.go b/fees_test.go index cc03b818..f6bafab6 100644 --- a/fees_test.go +++ b/fees_test.go @@ -186,7 +186,7 @@ func TestFeeQuotes_AddMinerWithDefault(t *testing.T) { func TestFeeQuotes_AddMiner(t *testing.T) { tests := map[string]struct { fee *FeeQuote - minername string + minerName string }{ "adding a miner with custom fee should return custom fee": { fee: &FeeQuote{ @@ -203,7 +203,7 @@ func TestFeeQuotes_AddMiner(t *testing.T) { }, }, }, - minername: "test", + minerName: "test", }, "adding miners with custom fees should return correct fee": { fee: &FeeQuote{ mu: sync.RWMutex{}, @@ -230,14 +230,14 @@ func TestFeeQuotes_AddMiner(t *testing.T) { }, }, }, - minername: "test", + minerName: "test", }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - fq := NewFeeQuotes(test.minername) - fq.AddMiner(test.minername, test.fee) - q, err := fq.Quote(test.minername) + fq := NewFeeQuotes(test.minerName) + fq.AddMiner(test.minerName, test.fee) + q, err := fq.Quote(test.minerName) assert.NoError(t, err) assert.Equal(t, test.fee, q) }) @@ -522,7 +522,7 @@ func TestFeeQuotes_Fee(t *testing.T) { }, "feeType not found should return error": { fq: NewFeeQuotes("test"), minerName: "test", - feeType: "dontexist", + feeType: "does_not_exist", err: ErrFeeTypeNotFound, }, } @@ -593,7 +593,7 @@ func TestFeeQuote_MarshalUnmarshalJSON(t *testing.T) { }, "random key should error": { quote: &FeeQuote{ fees: map[FeeType]*Fee{ - "idunno": { + "randomKey": { FeeType: FeeTypeStandard, MiningFee: FeeUnit{ Satoshis: 100, @@ -605,7 +605,7 @@ func TestFeeQuote_MarshalUnmarshalJSON(t *testing.T) { }, }, }, - err: errors.New("unknown feetype supplied 'idunno'"), + err: errors.New("unknown feetype supplied 'randomKey'"), }, } for name, test := range tests { diff --git a/input.go b/input.go index 89670448..681322d9 100644 --- a/input.go +++ b/input.go @@ -12,9 +12,9 @@ import ( Field Description Size -------------------------------------------------------------------------------------------------------- Previous Transaction hash doubled SHA256-hashed of a (previous) to-be-used transaction 32 bytes -Previous Txout-index non negative integer indexing an output of the to-be-used 4 bytes +Previous Txout-index non-negative integer indexing an output of the to-be-used 4 bytes transaction -Txin-script length non negative integer VI = VarInt 1-9 bytes +Txin-script length non-negative integer VI = VarInt 1-9 bytes Txin-script / scriptSig Script -many bytes sequence_no normally 0xFFFFFFFF; irrelevant unless transaction's 4 bytes lock_time is > 0 @@ -36,7 +36,7 @@ type Input struct { SequenceNumber uint32 } -// inputJSON is used to covnert an input to and from json. +// inputJSON is used to convert an input to and from json. // Script is duplicated as we have our own name for unlockingScript // but want to be compatible with node json also. type inputJSON struct { diff --git a/output.go b/output.go index 4f1aef90..b31cf3a1 100644 --- a/output.go +++ b/output.go @@ -13,9 +13,9 @@ import ( General format (inside a block) of each output of a transaction - Txout Field Description Size ----------------------------------------------------------------------------------------------------- -value non negative integer giving the number of 8 bytes +value non-negative integer giving the number of 8 bytes Satoshis(BTC/10^8) to be transferred -Txout-script length non negative integer 1 - 9 bytes VI = VarInt +Txout-script length non-negative integer 1 - 9 bytes VI = VarInt Txout-script / scriptPubKey Script -many bytes (lockingScript) diff --git a/sighash/flag.go b/sighash/flag.go index 57861ee2..150934f0 100644 --- a/sighash/flag.go +++ b/sighash/flag.go @@ -12,17 +12,19 @@ const ( Single Flag = 0x3 AnyOneCanPay Flag = 0x80 - // Currently all BitCoin (SV) transactions require an additional SIGHASH flag (after UAHF) + // Currently, all BitCoin (SV) transactions require an additional SIGHASH flag (after UAHF) + AllForkID Flag = 0x1 | 0x40 NoneForkID Flag = 0x2 | 0x40 SingleForkID Flag = 0x3 | 0x40 AnyOneCanPayForkID Flag = 0x80 | 0x40 - // SigHashForkID is the replay protected signature hash flag + // ForkID is the replay protected signature hash flag // used by the Uahf hardfork. + ForkID Flag = 0x40 - // sigHashMask defines the number of bits of the hash type which is used + // Mask defines the number of bits of the hash type which is used // to identify which outputs are signed. Mask = 0x1f ) diff --git a/signaturehash.go b/signaturehash.go index e628efdb..49d32725 100644 --- a/signaturehash.go +++ b/signaturehash.go @@ -39,14 +39,14 @@ func (tx *Tx) CalcInputSignatureHash(inputNumber uint32, sigHashFlag sighash.Fla } // A bug in the original Satoshi client implementation means specifying - // an index that is out of range results in a signature hash of 1 (as a + // an index that is out of range results in a signature hash of 1 (as an // uint256 little endian). The original intent appeared to be to // indicate failure, but unfortunately, it was never checked and thus is // treated as the actual signature hash. This buggy behaviour is now // part of the consensus and a hard fork would be required to fix it. // // Due to this, if the tx signature returned matches this special case value, - // we skip thedouble hashing as to not interfere. + // we skip the double hashing as to not interfere. if bytes.Equal(defaultHex, buf) { return buf, nil } @@ -168,7 +168,7 @@ func (tx *Tx) CalcInputPreimageLegacy(inputNumber uint32, shf sighash.Flag) ([]b // corresponding output. // // A bug in the original Satoshi client implementation means specifying - // an index that is out of range results in a signature hash of 1 (as a + // an index that is out of range results in a signature hash of 1 (as an // uint256 little endian). The original intent appeared to be to // indicate failure, but unfortunately, it was never checked and thus is // treated as the actual signature hash. This buggy behaviour is now diff --git a/tx.go b/tx.go index 32d65262..7810a9b2 100644 --- a/tx.go +++ b/tx.go @@ -36,6 +36,8 @@ lock_time if non-zero and sequence numbers are < 0xFFFFFFFF: block height // Sentinel errors for transactions. var ( + + // ErrInvalidTxID is used for an invalid txID ErrInvalidTxID = errors.New("invalid TxID") ) diff --git a/txchange.go b/txchange.go index a2e28f38..8de97412 100644 --- a/txchange.go +++ b/txchange.go @@ -12,7 +12,7 @@ const ( ) // ChangeToAddress calculates the amount of fees needed to cover the transaction -// and adds the left over change in a new P2PKH output using the address provided. +// and adds the leftover change in a new P2PKH output using the address provided. func (tx *Tx) ChangeToAddress(addr string, f *FeeQuote) error { s, err := bscript.NewP2PKHFromAddress(addr) if err != nil { @@ -23,7 +23,7 @@ func (tx *Tx) ChangeToAddress(addr string, f *FeeQuote) error { } // Change calculates the amount of fees needed to cover the transaction -// and adds the left over change in a new output using the script provided. +// and adds the leftover change in a new output using the script provided. func (tx *Tx) Change(s *bscript.Script, f *FeeQuote) error { if _, _, err := tx.change(f, &changeOutput{ lockingScript: s, diff --git a/txinput.go b/txinput.go index 2f534793..6680a2f6 100644 --- a/txinput.go +++ b/txinput.go @@ -133,7 +133,7 @@ func (tx *Tx) FromUTXOs(utxos ...*UTXO) error { // as an input via tx.From(...), until it is estimated that inputs cover the outputs + fees. // // After completion, the receiver is ready for `Change(...)` to be called, and then be signed. -// Note, this function works under the assumption that receiver *bt.Tx alread has all the outputs +// Note, this function works under the assumption that receiver *bt.Tx already has all the outputs // which need covered. // // Example usage, for when working with a list: diff --git a/varint.go b/varint.go index 8108a156..d345f0b7 100644 --- a/varint.go +++ b/varint.go @@ -28,7 +28,7 @@ func VarInt(i uint64) []byte { } // DecodeVarInt takes a byte array in VarInt format and returns the -// decoded unsigned integer value of the length and it's size in bytes. +// decoded unsigned integer value of the length, and it's size in bytes. // See http://learnmeabitcoin.com/glossary/varint func DecodeVarInt(b []byte) (result uint64, size int) { switch b[0] { From aeef03207e7a24a231d0ca21847d8a71b13df7dd Mon Sep 17 00:00:00 2001 From: Jad Wahab Date: Thu, 23 Sep 2021 14:39:18 +0100 Subject: [PATCH 8/8] update readme --- README.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e0df76f0..e815c8d3 100644 --- a/README.md +++ b/README.md @@ -51,15 +51,16 @@ For more information around the technical aspects of Bitcoin, please see the upd ### Features -- Full Featured Bitcoin Transactions -- Auto-Fee Calculations for Change Address -- Bitcoin Transaction [Script](bscript) Functionality +- Full featured Bitcoin transactions and transaction manipulation/functionality +- Auto-fee calculations for change outputs +- Transaction fee calculation and related checks +- Interfaced signing/unlocking of transaction inputs for easy adaptation/custimisation and extendability for any use case +- Bitcoin Transaction [Script](bscript) functionality + - Bitcoin script engine ([interpreter](bscript/interpreter)) - P2PKH (base58 addresses) - Data (OP_RETURN) - [BIP276](https://github.com/moneybutton/bips/blob/master/bip-0276.mediawiki) -- Transaction Signing Extendability - #### Coming Soon! (18 monthsTM) - Complete SigHash Flag Capability @@ -161,14 +162,6 @@ View the [examples](examples)
-## Maintainers - -| [JH](https://github.com/HaddadJoe) | [JW](https://github.com/jadwahab) | [MrZ](https://github.com/mrz1836) | -|:---:|:---:|:---:| -| [JH](https://github.com/HaddadJoe)| [JW](https://github.com/jadwahab) | [MrZ](https://github.com/mrz1836) | - -
- ## Contributing View the [contributing guidelines](.github/CONTRIBUTING.md) and please follow the [code of conduct](.github/CODE_OF_CONDUCT.md).