AVSFSwB?ZebmF{h(46kP$
z+9~d9W|(SVHhn7K`Gh6IrD>q}KuI55rbg`02|-TYIHy2>+^Z6ZOd`hKCAYHv4{18u
zOs^O35AgsjZ^DcG!-5H*$7v^l-iG$hlyPz@4S^E^r3?=}wBMELe3uf*V1Am1^$aJV
z8neA|QimVbH`hc~&88>LlUN02C=BB(vnbF5PUC0R+J8YMXs!N{N(gSQ0PApeRpDbm
z*`kixW1#A+vPigiA`1g{y1T4lOf0dIt!)U_Vr0fme_x-V)h7tW?v{s3dj!-!*#7=6
z@k_&2wefoGca9XrfdGpjitrCn(>TAOAr<%X4HYur8yxFzSFX^Pdj9rklG@_1Z+
zoOX*AF2l+|(Y1(P+97wyU5W1dn-a#vP*9x8%+H6mcXv;O5+&6bkSt3AV3Cth9YW!!
z66nXs{^>787N@fVrGddJ7jOo)`g>&G-{pp>0A&2=#&jdGN>^Rzv0NIsLRHFX*#GpN
zk_z|`Jo(gX+>G+_I(R0BI+Y6Yd-#C6ffcRFFDQB`5YZSop98J65CH;N{ek)ihLstJ
zA*Kw2RTa<6~26A&@tZcRDbQ@3JPCJPhTbKqlfrt6e3H
zIqIe8!CKmKYJ}C^y}o8Zj1aB)5(?zf|Aah$*hVa6ZkycP++prFAwz*F&|YGxA!}1J
z6O*WAb;=^es)X9}uCSEig}_u`WCT5>2v-@Ooy8y>2{NGf!!FXs=A*GFMjU5BV
zA?10r$yG#T#75D^mXm(BI&c_gEw<_M3=KCa4Ou@z^)VlsT
zdnV^cDX`}MiBru={eQQU*cxQI-;BQMS|?3t#TxQT_!O@trDFv72#?G~$xJK{D
z1oGtGKHMPSVPnILn|#e2$$w3?DUlkhz9bD=Y`=1}T-Ogdpd#@X`y#!S)>1m$3sE>-Wd*6-VVk3;V=2s33
z{&uZS`oD7kXElX#JlZSC)
zY{-vM4G-eLY-3`<_~BS$a#dnJhiL^U1*RgV*56W5-WzKBm6CqgyG=LQk!!4iJtYP1
zO$=%(Veg2)fm+-(2jf4bW9l2$)VP$1I43^b{8Jd{Ds|ccCQYUPU@&8>C*OJLlVoRG
zb#yMEV%}Yzmx=((+z%yS9{-yv`z?nZ5+;#lkbWoY7j?vu>gbU7Tw4ws3)haQFZQ1U
zVf7ZYTHJ({vWKMie^{~*=@0iCmPCUKp5}LVbiu9&l2jD<-&><;qc%7bKYBE0?=q8Z
ztCV3^x#B&R%JUPUPQqK0XF#-Rkmz)3l!9gu^%RQ!AqX>y?NXL{yD5zy?I3l4k>g5ws1QJ)_|car)2?ckgKmNU`ctx
zO}l$}0*)(`Ad2=^Hulcp`T>ddQ#&9`g`Tz>X0FLCL`Al=^Pc`~xr+33GB79xl(LOk
zCjSzhEhOExhUk=`zPuqIvl^{omOlc1TWDxjF-Xx?)_l>Kz&4B+b`hRdzJ8c7ijh@&
z$ZG?&)fG6fk|=`%#`@{ba7Z;CTyqKLpXUS$)I<@9*XOAFN&q{j<_co6VF~oGM4I1
ziLI%DbK%zLX*MO$jy#Qq%aMWfoGzo$X@yupU@oLvOm^d)OGeT{t(F!sWye`R}V|G*Oke&RE%
zPy!SJE^>cfb+@D&)2s480FGNnoh*dO^7_FWUoBdMvW
z5^m`4q5qibAD^K-PW`uV61%Bpp06LP+j|qvpXznznx3-?ZGlwL;ZOd_g)HQ+DTx@`zH8z$erW{Zhi
z7Y8LyT^k*K{EYW!mkCnO)Kdild
z2@#tOowm4O%!Zae>N7f+7Ed?rS3gqMoT?&Y1Qui9-3VYci?chifEIn1vrxW$YZqX+
z%Y^Zd@E<;l#qbtE8sAGWx)+MQ@UR!n-a42{)=;e{(
z0UEQmB#@2`+a8pjcz=HC`?Zao=a{5Vsx?&pp`DJ24Q*2GuN!E|_6i2y
zHn5ql;Y3AB{71)V)kmG_?PVl-%K5g8hm&n|PaqSd`8Is5q-zKW1J=)J&lBxQcv6t|
zKb=E59k+nj>#%%r+QGwr%)#NTFZ63(v*U#e&nm_rxYcx#`_Fx~59KT(0MM>TVb94k
z0vE?0V(kML`~YXhPb+B0wm3nn{f0J%JysUx>8%oXKR=mUV%K}&mIFA^*pq2zwO_-RO
z1E}bb&bvNu?G5+-b`PdVt`D|!H_36
zAyxk6!zsU6`Mc#iSEjxzyH4nkK49eyb!q4)Lbs0Y?38Am7@X{15{G4E2@K6f4~lm1
ziMeljf|2@}4qgtvhhoyt5wn~zym8=(kPZ#dk2hD|5PuYiIGV?KDxuRSvnCDfo5=0`
zC-3e$oN0b}l`zkDGDHQm?2zps=5LL6)Q3+E#9H1y(8vMaW;}R%8{J|B8ntG-J2eIT
zQpp`5KDL;@uWHa>vm@EC1Ao!Q_1NU5PoRtOrkZlWt7W9_PGKOZ7mf7%aD9K?;#(rAGCPaj>LGfQdi}-;hh!$
z6=;^p1mz
z2*Tct6uUvUdcp1f75jfb4o0OxRH1u&hp{yG6tH2RrhjY0$4Vr((TXt|s5w}k$Yuk1
zNb`&V-=r&Mmvf3;dqit-QKUl>ocCQRBD{wJT!v(KU1!8Zo4}N~mM0=glC$Hs&y8jw%kLpC
zuj@oO!JdRMRy0!n!4ASn2R9P-IxaJe%YS9<1)hTF>M5RbFXszzbxNW=xFxMuY*a37
zzL5)yqhf?zqq&wSe?c5)BpWbG0eMaBJe(SILj9tAn*cFc`TCoL+oBZ0u~F<0mRigW
zHtQ?I9M0YH6U2TU(u&e6E0+{WS0#yfnc}(tE2G&(z|64brfY@Oc
z2pgXbUx
z=E=$;{b^U3Dk~~*FdS;ExPhgbXq+pMyUuwGq%hR=X3mUu*_^V9<@@G{-}QduJ_&-D
zS7dScD&?jqpUCvJW5^K$eyOy4(^zQL2SD#T?K_yk1iGCC`f?RS47~YI<{KRHW@c?;
zp1$!^{mn>^fQgK|Yx=v6gPow{oU@Y^{Q{-3XpIBs%P!iHB?ppmFM!i^B4fc7a4O~p
zmEP=UZ>a#!w)H+kwN)%y{hg)x>n&86?ocgbq#|zw^UDQyjK+!dTxGuDhGNmJFUn%cpE*}@3orq0-m-JZ}-n%P_S(g
z=d5$H9M=gg_7yeN7$Fl_BmBnwgl@&w@LAKhCO4NsQi;BWJo!^^oOa@1bGkCo^?rVv
zBZyd&an13(w*}J*HtX(UMA;Xm8*U$+E~u&>cnw;7Zn_5La?R;OXK)=UuyogK%SaAh
z%Y&u=kl-(;3+)mtGB%H6K7*?5ocWCP88*DC)AO>
zy;hN}gF)zcn>u2j66cM1Mug}|mRsS_qM}8nZg_hV2*uVP-ep`Fw0C~I8P9CL7SnQD
zL&KTl6Pq&v7~1B%A7N0mUS~XRV<1GG9M*U8W@=iB?){qMU(w{ax`p_#gO0#8fgMaw
z;2Zv|_=wJkDCCUa3tigO{pN1kgC5ZR{hlr(`R>Gju-emGcK#-C6w$_d9HmAJk{ywH
zS26ygXtHIu*}IoZXkprK?bNfua0%bpuS_pT?0G3}&Gu}i4r1dcf6e1H@K`szqm>a}
z9>ZQh{J8tUKSXBE+%&9=#|(ZP(I?EwsY0e1dR!-7j*pVzP1#(7J%Mw;Fl&GG`gdvi
z5__-fh_du@dQRy_T!||TPv?@CBRHkLzAvz|E%OTaR;74DEReQ1(t-X&~s|u2F9_HFY79_FqLH
ze1gFu;`M-uOTrm>)|6I(b}TtR?!-a1b?RoOS#||Q&KL^7vj8j0=k3kRzbn5vTjlw_
z#tR{PRC)`DTZ?$(InZ*-+pYqsT=ZC5_qm3cwMsLtFODw
z(9jZlUl8C&B?lgR*T){L&T!Y0wVzJ|_U0^JP*q^~K6(e}&U*Mn0mcI^o|H`#w_C@X
zjgCC7HwNRCJ95Na-f6LpTZ9UXtZ4O0D!Hc5J@!*`{K!~KjxI;M(82sOkfyy8WS}C&
z^%L8hNEXfPs8a+EwuarJ9tmY$wzw{j<9r`WRv|{si)Ckn*`Eh-AKyxfCiLXrmE~WQ
zVY%IUMUbJAR^)|qIDDlu*lBQ;i(EwT4sUs#s8#8OV1_+-g?sNqMS&dT)roob*F#FB
z@=8GcY-@(`sK-r~BVL1+W;Fe{Ocx0jq?KnanmZxbsIH-Ak4pL;@bOD1#6+4Q3S@Tj;s4T5VdRx)i;Z
zS{`clyXWnH|#A~?@zy5y8=SS
z3i86Eo?8afRZC85iW`v&sE9wYpuaa)GO7J
zA9{l?XQ>lmzn7Kp>FbR?|EMj){7>}fJtL@{$??h~Ks{rvI%BEWkM$M>eVbKEigffH
zB%y>i2;66bLFm|=tFX1A`3-h2|pj4d~hdO_BfWzkWO;Yw>iP_-pJ?GTfRl91}xe*F-;>ZXD2oMku$dVEwN)QmQbs->LsldU2|3hLL;RgZ1
ze<sN#`+yaw-sv`-3iX8y&dnmkD)oG11(qT^eMxhd|TUfCTx2{<8Yf8-+C!a|E3
zHFecFbX9etGIFfBPwc6j+UiBw?;?mkOH@BEH3kt8_8%?#wr9y3?PsKHwDO!Djekjz
z#iLG?l7}e!C<6Xe#KfP?Dc#;{%n*~2lao)Iilv@FprfP5^BVxcf0KWP5XOD^6AG_6
z9Q=9PIVlSM)!SF03@=yVnOwjZ(Io?NqQDm=UL)zgJQL&p>Q85JqO!G+(bipPS>|2o
zol-={+{s;Il2TnK3{#^h3V3V+e({jT-xnjV1dM)3TM-+NAyK;ND02ksvg?l3K
z0MPf#h`x`Tz=NS@HdRMU#a=|@DrWb1xFzw+Tqem7mg~&d6hJ~Gfmxv0^Z0bh@pOBj
zU79=zf5VWx#}GSgu61h0O1%uGs^$KR{X!hDSoe+}L@FX-=nkJ$KyX%&4i
zviDHg5&d2w%OcA=JM8Twgwgs$L5}kc1ep`G>~g2wGm>!1lC*%L*Fs69L^@h^LM1-3
zwyj=0B|g@Raj8+zAWB13*dFnb<($CpRJ>6KQ*DD&Kx!z4mH-JNy>0jvpNyY;4sXS-
z@Lo5NY$eyv;|f46BD$6s4L-zG&04ZN-Pr2e9NKG7XMD_`!)ulp=p}2E<10O14IEQ#
z?;AW@<8&W@a6?`nIC8yEcm@u@C0D^yRqS{6H&IZQX~aS-Om}+?Fc&zn8n*FCXr-L0
zIQj6>aA?C!@D*v?jpFYK&{>&ADTb-UQROz2&uzVQqy1ODZy1l%*
zy*fqGP;thU(-=7uJ#8RqSD2AAyviTaXx-s_l931;ZD!HY0+H|5ylGV*dQ%~0b)=rm
zY02-F-Wsk=4O3Zs6f_UX-_;l2B;r%;!4v!J3d^;p3c!3e7)>S&ai`_g0j3ynE4*lEYb)#xrBR6^%sKWn#=KziZ6Lcp!2@VnRj9TOkEP}!x6^F5>C6y(zJ{LfSkW(K;HjAAXqCyY*P)hkAWnKb?wb
z#RkfqhAgo>F-z+lzJqVxc9$RXD?vO-cZGy>G
zbeXQwbb&i2G3kUIn-^QbTaWG3a-{gdKbK&c%O4Fy*i)h^{D46XbS#d?Nr`v@-GsW>
z=4gC5^{Fdf?dI5%=AGVn94?sT<8oal0|Ungi%o{GO2=V_3W!@}`A{qVp<0KgJF}&3
z7F>4(TA@A>J-$DM&nI4uV!!^n?>)r%3q;hI_SSf$G8V6;2BE+70iPl@dFOf}>b#??
z#8Hy7Yk`?v#rf^*(tO^I%^}`H#f%J{KogeSH#@_X!FeG6do*P2W7UgW1!JALqpMTx
zhHa~&df@cD${5@17q|0Vv@EF{Ptg*evL=sD@no0n5HL>fRY2Sq<|2=uA*1}(&dMbX
z=VU`VuYA&|d0XlMMm=gaQMf`$BP9Z`q4QNK&_4QwPJC9^euh+?yk#~I56Tj~3q+fW1>%LV5y6xNYuEZKqYWEx1#D#2B9P;Y
z9PT&Xd{Dz~FL=7n${F{q_9s&T
zqNn35y%?c!vrC4$rcD-m|3D}*y5&cANDdMR)#KyyqpN0E33(}DwI|9H=21G?tn^PZ
z+6|#R>=ZOV3miO_+m0~Fr@4`I^V8CGHh=BDwT@;nm4b8|cc}MkmPlbS4JZ|PTY!l9
zjcsyZpUn&Qbhkso&=%QxwP&q`OQB6=EXICkGd&L7;XR7_v$UvMEXFV>qPw-ZF|YYT
zxsK1Pd7?8Pbt81bQ^3UP?jr!hwj_X7NNtU&a|MYX9i5ZMm0Jb3<#U5=
zXC??4jpc00{Hs*;+GT4h(_XlCW1pXScGu
zgXTg9lErzHD+d0|#5{YdQK5i3&RZ|HPGqMJd~
z{>70<62ezxo#`hwT2D@cK>J+ar39v@H87@|C389v1b
z64kMzmQM>AsUNrIQDH-9%oe-wLo*T(CW;{q-O-D?fSYOygzSBmeP<5T$9%Wp=l8QT
zDIIB!l={}v1p2+$4}HyuBRVq1)z*kr@0*atLbUEn=RCTQLl(gCMNnZ)*??oE3UvZa
zw#XLfoa<+FiBEp>{jUm6u=f1$AJx2bA)dI{;e%aQ9gP%lTgi
z<|^9GX|k>rUGM@jO*^{w#?F(iaAS}`PE&4@`YNLxlOuK=jaMYlR5wdg8k0k}eOF^N
zAFprV$q3BI=w)4l={B@iI-a*Xs4%UfYq(d0gmOSdBD2H`Mv029gpv~>SnsCo(#4KM
zg*iKR;7Y{HG&PF}y$gz0ABAF4V+ivchq6SwOvQ^}L*)Ry?%g%Tz?yjLX
zxXe`k!PO0*yotCU+k@?pjn5{YZ2g)Uwux_Duw8u$nah6`g-3Rek2E_{FdFbbwB)ip
zFi#+k?W=d?mIxS|yi?U?kjsd~HERPj^gdt@yiUnk3Hdm?bdKMTq#4#vc%Qd?VV*wP
z;qYN^KC0vibar8YO@rlWoC=Hq=a&fsB(kXq!q+#}Rogb=NG0?=b;5{DRy{G~{1kZs
zb#+A!Za6|c75>?#O~r-ZPbyLq6Kc?)=-N9^-ev80Jhm4m;|05Z5&m>$hpLgm7rqgv
zFKE?AoV@7IbtK2oSt=;2I7bKjoVgwfXi-)u5|?hh8qQ$)IP%I@(e>OcTFVXPTZ^5@
zf{$j`?Yx{JNdKz`$g0eI`V}U>T{I<`FjIEFj|^}(nk7XYt?t1%S~E4)k;;D{;a-<{
z(3%K_0Y6l6{9wqf#P8ruW^mDk>dOy~(K
z;Fwmb)%R+iRp@b(6kXMfoRaZccqHyw*sZ9#aH$cp;5aLW`AU`ai81O`iQD$_8M6k_
zA`ET9yhq6ogOIV)xG7>GQd`*!M>TWppVZg43g$Yj^F`Rngf53LAo(Q271RUZ)Q_z;
zVa<%H#d<2-9V&(%qz%_W8f8q`u(F;TR-P?D$E*TIQyALxmO@SqeHiZ(k41kWVI^`$
zi+yLVsC6aVgTKaC2UtzY`9g&m>{GZc`|&|Rj~1h+mBxd`7F$vlDhG75bj(V`FWCC)3)L4@?ocE90bE*nuG9c(`GNw&yc@(ssn)XYxt{O13AeSK
zo??|Z40fQ3YCZf9#8pV3kP4wh+d#=Q|DOB@+p4V16l>AGSa9%CvKPSd_ZgfeRM%&V
zE$ZK4s++;MozMv=(hbUd2%P;z-@lcXw-c!|=WL3RKpVC4aVW`G0wyigm)W)M>|6iz
zFd`x|D>-3C2SFH2AEVr*m?5}|o`$c-&
z+`zcQDfI+79tf_n^^zzs6=tltPOxf{w;$~tFGl1(yF|F831%oRR`cW7ow^SoE#xIn
z1KHM2{ODO6jI7*!Jmv|}srs|sB>gzJMn|;&9>?LO&pBi%l%Uj#sOL=L+*m8VGPand>^B@h=^C_mGSVp
z7D=|I3nKck<_MN8rd_$Qo1J2h``U+t(N<~*q5%g|#Ab%I-kPNwZiKF6kvU1>M&P1XQa|oycR?S$J#+0pn9s_-vKHxTtXLKt#Bc=
zw6y$0jm0$7&{|YPT@ARFDcoLCj*pLLoc%gvB2=KwT+?4n?DrCrRr133I$aRlwoZ&*={c;kcZaIr;fA(Fbo>ptYi6*vi_L5gbtY{j0@!>HdOD2pU*iDSAR|7d4r*h
zj_Zy;ZpYACCjp*BMTQ-qJmL7P>;|94el-S-1G1MM1Q+!M#!&gY(kFc6j{;2`LVF-`
z@=5#y#Tn)s1BzR~!jwxz1Xv$J1*!pAPD3JCuQwsH8Y(%N3HM@knY|bGEmWo0W*~D`
z%qcoMSc{>kg!G0WgBNT?vfDyIGT=eI1RI2s&Rnc+^h1ri)dgh^QTvvGIT$zKhlWe+
z3;m%`xf%Tz3syiKpwz7;j2KK=&w&bl0*vYTHPC?$$pVShP)};q2ns61=;qD@Z<#${
zqEr>`rs$hDPat@HwXt?TViLySj_Pp|Dddf$rKL^uK?rL<-TG?p7trU=&?sHt1%K{7
zHtwAUlhM_-1>X$!{P$($>
z6R5koS3&;?)Y#uZEt^#RPQR>vi-4Y1(Nm*t%FB7fcl|U6N34|~*o|r)f5ZtDE06QF
zrz?kYye}&dW89N020Uk=>r~mK=_=8T`c+rU+L0lq2F#K>^5oHs1l0Via^EbN6ropN
ze4^4)Q^|SgkyE;j0R{K}*r$a)z}Yny)M*@Rl!=K+
z;15J=DljT(V&wqk`N1s?wO;O}xUZ9Pm~1tMFdvr_g+Qcvh8&%Lfl9_zt;=7(ymIPk
z9I$8Qz*xC2%EvW!p>ffiD~Yo*cQ?LBiO1VlAsF7>S@hZzXuRhZp6@1j++BxDIgJYc
zXr3=FJFprYvx%!GKC?y%oSt*tbrUt8Aad@fKQ0zM2%4>!);8ff_V;in$Fmi2n+u
z1w67MB9~St1!h|v-YL2Br6#%v->{ppF+a!-To+L5z%uqcbpb}p1hB00!lYK-k(1{x
z&|N!`yY;;d*P5x2MdnnifA1%#lokv4LsvZpGb4B@|K&1k0N9tyAaj72=Q3Ydco64%
zP{|DqrSp5~#6Es}@0KMWnqv!jJE{e6$kO7j$9!=%!UMH+U_A~#zIB$IdEe$v=;NoA
z2KY~&aG1>@Z(M)*>0G#foIg)FyF7|uTF`*vvM3(`FC?GTh1P|S0@l$v)JXaQz&R)L
z>PP$4V)mKnEE8^Wk(oD?ajrXFfem*|cF}n12^~0Q9&oN9>pqwE0s+`e$1d6lIF$D3
zd{HI?WDY*n0YoS$Y>o_1NC^(1GR}NpbAop*FNc;;d_QzMt1E44;o4AION+n+0b1r4
zy{VN|q)iT=vPbEp2*-;{*#pghQX8>niKd%3;>LKqRxGTn!7N<(Hz5N!am$}Se}2Qk
z;ZGS}BqAn;qfuY^5-w$%y*6}i?WnEBfIthK=rOdqg7%rA$t#0rlm~?|LNd0@`Xw%|
zF76K`=Te;%r+P*-+uIC1OJhF(+EIFXdW^Fw(B(nP;K4r}e_W;4iIfCCprwU}h*le`
zBb$WwpbswtN%wm!iKtx9$>6heL^TfNq&x#u)m?iyoQs&(tjj3hBAnlr>xX%H@NA|@
zx$&Ey?)FI&YHGZ%5x%beb?D@ld_9uDLuZ|0@!i;P$6^1~92#$5Wmc-g&CJ~!xXNU;Y7YAzRtauJ6&f-yDYJR}2mX%OUhwy74MF$2UynU@
zN%qWirh~rs>jvbK>>ra%A#t{mAoB_GB}X`-EIPWdU}4$xC;`ZK>0~no4KMh*0f%fU
z8IfNbVUDwAq}N&QAxB3Dx3$0eleKWqCI10SyMMxRaDfCLU(?{O`wxH|{PcC+YWY^k
zmY0|3$jmN0n|dz?X1_YNQmkWUmqu2VFw*o;!=MS5%T;HLoLDmjN~)dANt<(v^Zfj`
zgJWY^@J2K*kV{bepFs}1z&fj(`Nzk`3`$;x$4bc}s9h(nqx5tGVuCmi!{vX&F`xkl
zyfR?j446>r1RgfhBAdQk=d88XS2ngHT#zRKYwO8O=#i%6Phvj(cbHwXe%T60@Kz|G
z2&>ul>igv>G#t?n4$q3UY#!g1w*9P5f)#3*5DV}(SAmxcY5fcfQ?U~M(OdQ=1&o}_
zKyXy-%yyz0U842DW}2vdQYeifq4CTDUki6(_@e`5N%8-vA>~5na@>_Yol(g@fEOyi
zoX&h4hX*wWqhy3b@#YOy%LG-=Wc@22vofJZd3xOy_!mC|xX{}3N(d==IgfU@;!zCq
zaWG!|E$K_xzaS_MoG3|Q2;r6*m|ktu{n+|fs3hPGVxHnbQfAK(n^ZB6;E@84a4*&%
zq;5ox5mRpT*lCvRwoAi8ci8DX%NqjyLFDIBjf5M~>j5gnk*!Sy%>C_&kMQP$9~Nz2
z_QV&wCo)!fzR&Z8+zv$T+V)`ynEIUqGnj$cj0R5sdq`EU%S;BTPEdV`q{L)${m9wc
z@EpWd{wGZB&Mo|ulrVPp_9md1u^AaFaHUFKs|y~3SCQ)W<^+e~4?!(TLJgSSEJ%(2OsbrNTSt6;QmtPTm!eGn}xbujzPL
z$Ae*^$CH7e3zIZ&V9;WW_t1mlvuz0I-N`cShrztOEr&Oum&(anB_zA>MMnolUltxD
zdsm`AbRSwYue|ISEI56@XHSb51Q;_fFW_I;oA%TO(Ke56#BkZFc2ocZCy#5;H#hKA
zgD}Y|b_2T(*~usMX4+n|2VZdZAbsU{+e}K=C%9Ge=FgBD0Rlf)B;WaW$mL=F_qM5C
z<<*&Hse}}I-QIVPcaq)+Qe~t6$kaCc^
z!)Aj`tzQd{$-#c5>ylUR-mGxN7T=Z;r6lT$t9+0OnoJBT^P^{K+SU^3&_!1aJT;UF
zLWNlx6a3!Q6dnacesWKJndaeJINc6|{i^F^|0-;mQ~NIUjfH_|+6$)1UsS7wRp?W|
z81{+|%$Fq*yc;_f6&A)D4gi7bjs1lg>8dc66QtfdJH^vV!u~O=bkO7+QbroG=tmIA
zd*^#RUR)m(?bW{cBCHyt*fsrUh6c4^j5Peh<%p(Ehl^$7uBJPSn|mI?mo+MWez-Ogne|?D^=4kDzPfL?7WsvG=6c>c
zE(bc>s1EBOP5CQUI%n*~K*y$FrbpzF4+lM;HL28z^boWz2;K_^wJJi|&wYS0sqmMU
ze`kD?JaxO2-#t?>Dx5s|4yx$O%}#0uWOeLB$ai!3kfwg}LBZj6bo4e)mTD)*pHiO-
z*=$E;MasnUkHOY=W!j^lsCBc34cn7@uh0EVd1$Dx_;D87Gb*B`-{8_yV3hEdK9u*q
zOUBcKkNv$5I@>6;r$5vN1s-Nw50mMPC6ufyP800Q4o!T1gGWLS49={&{#$`<;XiY<;G%NgP
zg|BwRBD>Xx^4QgwI#(n|vW@iG+7E+R2)iB0w!di&v-tK#XLo%#@Tq7hb9OEwRo=V$Xj
z>qUc?`4~y+E^he4+$~wJAEkc6r=W!5tDa^MO0EqRrhwgQ%&tIOu58R%>sQzzj!(&J
zq}TpWr~)!hL9Q0O+lc|<>utR%y?wf&HED?U^cdjU-IvRU-U6BN)RK*o)w|u{GxKNkiMa{`d*Wr1T-YDg#YSD5L@>_2Vskwp4Bmz-WIt-+>xJPVO+`AsayjmuXztnZ=e(O3CU|lB$8@ORi
zkxm}FlZAr)$;}CeyABwEZ>Nr?b@R8h`L9}8X}<3hoAp$V@H;%jFa0r~Y~y2UPEQ8N
z;og6d=+`T_evwlqnI#tjLFEj#)!&*BmUU}a)~B8AYar}f!vSEI%7GLjxo0lqQ$>+c$Q
zBn4a}Yg+EA4Q4m9G8-fz|k5aVD;l=vpoWs`z+1L
zt4@Sek$!5SBIHdM9`Pelv=wB7%D>z$5B$%o=zLTR3|6$Z$Mixr>-l1UTnx>N!xD$L
z0Hm4WbLVTTt6$rFi_)rT`%X0~jUT0@{6)%(S?s%zdeQECpXKNGc1LTmLt`UbU5TgX
zSL@yuoa^}2ID0^<8?iwjeGw>b3O+0DJrWzJjx+Am6ZRL>zIx&7F*Bq6+&HHB4*p>(
zlg`dug7uRQe0}5+y3x|;zoXn~dFq1{PTwB_iq>lM_BqPxN)in~6`+zYQTsZqbfx|+
zO}OP_js_v0$~L(BsVFFy*%pdlG7+ieJcK7-TdJ=*n<`>7RrQBQqMNs(oM-!dgLKw;Ym0XpzYLW%;4c0$
zxm^35T)Kjj%eS`O3Kh^yx;TIi(0pgGvLSG_6}F)1F?fQIxI2V_Od_L|bm4*cldBIU
zFP}I0C>xF-O6m#ci`lusHGn4D*;BXuWUIYw0tTh@oIfcsG1cbe9oGAqdE?-2T*V$8
zg95Gje`l6?hkr^_H2W}Fg7Q>}3*=y-7SqMnGB#xJ&xF(Yhl4|5g!8$1b_lBp0g&Nk
zJXG*_ce@WYhggO8>|+jsIB@O{$2$q`{0p6QC6T9rXHX8-iV0~74_Q%43#loSu%k4E@
zL7VYK{@VD^|G-x3)j9aYaIA1fxt3z=8nwhG~NT1pgmL
z3=fcMc3C^WA#UT;*+b)PmlnWtbx;lr|9^<NLSMz;F>E5ixYOI&8*{>m|3Y3`v6
zwMH2Jb-Xj>p@s$3P$&s4Uv53l`Uz!_n;$bXlMj85AnFaQ>{ZeWqXNK{DSk2X6G}&;
zYVR^TW){5eaL?cA3IsnH!TD=Tn)QNUit!sQz8wT?gPCt77FWQr9OIl3EIB*5?hZ-D
zQAtkk-+YrViUJ#!%8Ba_BgKj62-anRqR(_%LFox9Q$JHU+>C+K%G@~32uWZ6cGzBD7e*YVj8daEVJ;_BpE{+TQ7=USVlv$obkw$t?{3M;3cdUXkeIp}>fGbtTPhh=Eg10Jd;td78bgdUo_u-0B_|Vy@}za==E=~24O$9Ah!-b@nP)*RzG<=_!?UOb-MKd
zy^Z0973?j07K+yM6`ClgY_+&`l;{Vr;3yZ`h890nGP(4pC&BZ8E8K+mD+of=-bk&P
z?{%2qbG2<);2TByZfVJ|pTC(zYSjo{u`tC)-EjDTC&a<*60di6HNkUxtdv{GcBsMv
zKG;=N$QA(>nEsC>y9m1biIzpjZBj++>+8ZGuWPm3`M0@AJE_%($upX(x$7gZzGrUF
zza=m0nS57$l&-TnF^t||R<1Pb^|m~U14B{D?!6XYQ~WC{^?IB#l86z7JBUHF8-KQs
za$g&-!X;?I)ooiYytIFJS?`CbpQ@G2J@SUWq9x$I;_^#hQKE-od?kb@j0(KqsUi=&
z)U+tAFX4K~e;zcxq;dK7R|2$F2WI((oS2zdb0HgHyD2OtxIF0$_OPSvH}ANwKE5eZ&X;%v{&7>8Etyg3J#a9`}w`x3*)z#Rbm
zb_n*2mT>UOB$5tffl`0v)WQW_?Uq5up#>j@*`|J)4rVx>H?~<^snBWH3;l515iJ7?
zxcSuJ$xKgAzfpc~@VR1ab{1<%$h+W7Bff%=)mAc|Xkd@M4wd1Nu
zD0oO4VgO_;9a?1LnAOEB~AL56e#
zN?J-PXm#}=nt_=OV-#Kzd{*t=A-2c#r
z^1(Mq&l^G954EAQY~Z2?j!VR)#x}tcb}_cb7PN?gapm>VUI=%W1a6I=@YPd>;yX_C
zUs5D^t#%ZzkJ;9kUl;@S9h>+QvtFE`qQ+y6zEUe~xe1N~A2K2K>ahEl$vnLHUv
zPe|^AgM;fkxfo)qwS~yiEI~U_rnRq(N)c#9heySycMHJ
zKtwnOwp9Zko=P+3{65~!f&bc3w55OVn?m*han@de1>l9oL67sSpyeWKD|OHbvWT?#
zrp%LON*Gg)G@KIE=>VHQtO;=zy!=EaoO6t*!WH=*m&MN}U@{@?WXFIQrzp{Y05Q#*
z<6Sxzt0_#@)$%vB3jDTJgLkhNM
z?zeqqksg2@CmJi{)sJq^Lt4g0pS^ItjtNmrfS6mr_1~6=BC#?3jy|>8pV68P
zplM5R&ClCpF<)!}(qMLJiUFX6qs$G?Zy{HG*{7
z7~QoK{nzY!sM)LjTleKR-Tv5ncGe*|7x$aE9W!`r2MA(EtG~pEfuDTXn`CX_m!n6=K4`P?`Nmutz8?j
zlAO;gQh9kOwbp1o)-da;j
zYx`ub1(k~C*1%>T-ow2K@@s|V*%`DTfaL%)uvE{o@o9xS`rt<_Dq0*D5n)-^`IOR}
zm(htjUzQ9_s!ZqXtF5#3C&ax*C!gA(k<33A9{n!~*rfRDKXexwEN1!8k?u>|)pq&^
zcIMQB#(L-!O@~%4xnQ=qzK*O3rS-g4S+Vr@H(Hfu_Z?=vEOYEEC
zk}sZ^m#pB8F4cJ*>VVkH3uwE_JcwHCUd4&2l4d9*4i0-k7#kb6H&~`55u^S#0);g*
z#9#H5VXLJ86Oe8Q`rj)pf50OlI|eUhWN0*qN8I4B;ly4lCo>zM7f>l+*1;t3wib0uV!hX&dCt$A`)7ZhK+HF>l=
zb!;4t=aO?wdmOg#LfU(CR<9(I0OH~>)Q}3{YlUdo;rr9BD?k}~voHJW2cA4B2lCxS
zUM7z)3M->=x>dua@UP*w3qDqA~0GJ82C4oLrs|UsW@L1$0F}s-!F*Yg&^T+sPwEna_p2CCIV6tx!4K%!ErIP
z`&NX3C~B&GJlUU?umD?U%Jj)@)UxEBuYtTjVCTZCHP$&M^N)ECR^pPgcwuv|{BHbc
zZF>eV>pXOHMF*H`(@xw&HeARi*)>5V*#{%!e{4hjYS3|}iWVDF@M4|Ut^yj7!Qdk!
zoctKxvS7H9fZ;kU4*yMQ#y302(WaJgK)l7#XPu~-Pwk&YNp9HDz)rqXYk{{Q^w#eH
zy>r{jb!hg#0qfHf9ad?LmQ$pHx3%jzJH|Bk^NB*G#
z4Zb6x?Y2`U%DSDh0b|C2nyhH@&dpRR&kMTbJ2H{FqxIfK)`E1SeFZ6OwGv{MeqGa9
z`M1G^Pk^187d#uOYd8a=RI+w++ORd-Id!#@n*^Hw$lh&KagB(y3kA
zSLboQSuG4LbQ=p{*mAoIj-5f@X?e(ey58PW##s28{kW5#c?O+2`vk4qJ?3bl
zOvIog5i&DSaz6FQh~5l(&7kWWu$Qw^dH-nD9f{9b;|1ko{uu5rd!#VnO_!Q}6qg)W
zw8&NX0pnV(|5Mz;mW&gMQ#4JU?3t6#!Qty2qxlx+2gGQSme*9Ld)*3(@U}r;w`=(8
z&d<05$n1{r0AE=fwl8CdR4y`uW%W@-=pnJ%+g528dClMoj_(OIVV1gw#)x}x83x41
z=tz$Px~*}FlT!f#VKV8DR-7A
z>z=MgjfDg@5Z8&2bQz@?!g!4tWASW5uPqRGS#H$K3awwHpE_xLef3IShYypfyUl2pHnhpG0MY<
zCY^@c&eyRa0NBX9UvxJUSe11;KRq!(ir@@KO?3sZMHb%aZM8_=DWkJRd7-GGW`VrB
zowL>!u{au##b(|Glx$e@n{bs|#aPEroLa&}dHW8bfK_{2%wil@55QMwg|zD{a5y*HCgl&!Ul?<-yxSXRu6
zy)H^SAaeA~^KI~Wh(=BD$BOp(90y2Y7(_gK%t^?@z31N!nC*4W@*VkJm@3K_7H9n&
zLc!K-Xt^`(IkN0Z9D9Pju=)A@jv7&{wd0P~?6rbiYyA5v^<`91#na@%lAWC=vGz<)
z8Q{Km;8$>t_0EjR+sAZuQo+NJmm}j#Fwxdl29JAoZB^jd&Ya1d;u;C6{CHz9aIP!4
zjSI)!$+R1h9XhGniJ7SZcy$7P)8WWkpnJs+l0^S*Y=|ka)Vw>dh~>TV-gzVp6B^F&
z&=9qgw?j%uo3@nk__QVPzJt?b{mcpQlE&TEf3C+ie?IU+~;wJEq;^K!!fN-fU`TD_b{?c4s-GhVpJMo
z`?zCO9DId>;@^xUFfu*G%+@e?g|vPgVfXah)4JAES(-$4^&k(ykHZy?h1VQJ~
zjJba86+wrPes96V%kF&Ny^*Aj6SX*b5eZis$O_2v%!Q%Y~_n89TjQ8dgn|>FbN3>QzzP%
zRgc|FLf2v_xvT2KS&wZMH!dbuPEF(uFwo>Plz66Zr4_ZaU$JTRcle++dkeQD2E#<7
zj4C|OC_bX@@pH}#7F(~TaNmFvX#_Vt#C}5SR?G~br7O1cC`PDwNqXl|SX>6Z+%osx
zr9H2Wy8&f3dtgUv_qzS$>=(eg9@B5v{k>27>g5lR>Z~8r*++L${D)
z!}jvH7D~MdrxmBllSMGunUy0)>SPV{65i`&=UsBUAlsPgS7ZM{?hic!Zh@S+NIrIY
z?WV;1fZc;17x>p)0Oo&ek@G(vD6?21F5Iu%Ui^u5fZ*~-9fL{
zX$8iWCrQkV*B5u~T`0z}@6R2EjOuTW9i!=iO}Lsha5yJ;+8SfInUFGy{=E&iw!J$C
zhj7;1N@X0Ds7b?~`c^xQI7&5eeY_p$aX02qz9q44hCdn82B29dOnEct>^gA0=$5<8
z*FntJ&r1|@eg{amMT@v)d7>4psKR(kK8{8km`y5yX
z_XdxguL+zQDCI5Gl1K*cNWJTF{JwvlJjsKktHgBG{kc4l{8T)
zfBV^t51uQg|739r!={j>pHy9_g+b0)r|2!`iM-{`p(ZBy{=Ye|@C;jaq|*n*bOQ~3
Q`yE13R8FK^$ROyy0flhervLx|
literal 0
HcmV?d00001
diff --git a/bench/run.py b/bench/run.py
index 6abda3b..1fb061b 100644
--- a/bench/run.py
+++ b/bench/run.py
@@ -34,4 +34,6 @@ for f in files:
method = "ahash"
if "whash" in m:
method = "whash"
+ if "multi" in m:
+ method = "multi"
print("%s_%s,%s" % (f, method, t))
diff --git a/benchmark.cpp b/benchmark.cpp
index 6b95add..b5f7def 100644
--- a/benchmark.cpp
+++ b/benchmark.cpp
@@ -67,10 +67,28 @@ static void BM_ahash(benchmark::State &state) {
free(buf);
}
+static void BM_multi(benchmark::State &state) {
+
+ size_t size;
+ void *buf = load_test_file(&size);
+
+ multi_hash_t *m = multi_hash_create(state.range());
+
+ for (auto _ : state) {
+ multi_hash_file(filepath, m, state.range(), 4, 0);
+ }
+
+ multi_hash_destroy(m);
+
+ free(buf);
+}
+
+
BENCHMARK(BM_phash)->ArgName("size")->Arg(8);
BENCHMARK(BM_whash)->ArgName("size")->Arg(8);
BENCHMARK(BM_dhash)->ArgName("size")->Arg(8);
BENCHMARK(BM_ahash)->ArgName("size")->Arg(8);
+BENCHMARK(BM_multi)->ArgName("size")->Arg(8);
int main(int argc, char **argv) {
diff --git a/fastimagehash.cpp b/fastimagehash.cpp
index 08e1344..3cb2750 100644
--- a/fastimagehash.cpp
+++ b/fastimagehash.cpp
@@ -119,7 +119,7 @@ int ahash_mem(void *buf, uchar *out, size_t buf_len, int hash_size) {
uchar *pixel = im.ptr(0);
int endPixel = im.cols * im.rows;
- for (int i = 0; i <= endPixel; i++) {
+ for (int i = 0; i < endPixel; i++) {
set_bit_at(out, i, pixel[i] > avg);
}
return 0;
@@ -213,7 +213,7 @@ int whash_mem(void *buf, uchar *out, size_t buf_len, int hash_size, int img_scal
uchar *pixel = im.ptr(0);
const int endPixel = im.cols * im.rows;
- for (int i = 0; i <= endPixel; i++) {
+ for (int i = 0; i < endPixel; i++) {
data[i] = (double) pixel[i] / 255;
}
@@ -265,7 +265,7 @@ int phash_mem(void *buf, uchar *out, size_t buf_len, int hash_size, int highfreq
uchar *pixel = im.ptr(0);
int endPixel = im.cols * im.rows;
- for (int i = 0; i <= endPixel; i++) {
+ for (int i = 0; i < endPixel; i++) {
pixels[i] = (double) pixel[i] / 255;
}
@@ -302,3 +302,169 @@ int phash_mem(void *buf, uchar *out, size_t buf_len, int hash_size, int highfreq
return 0;
}
+multi_hash_t *multi_hash_create(int hash_size) {
+ auto multi_hash = (multi_hash_t *) malloc(sizeof(multi_hash_t));
+ auto data = (uchar *) malloc((hash_size + 1) * 4);
+
+ multi_hash->ahash = data;
+ multi_hash->phash = data + (hash_size + 1);
+ multi_hash->dhash = data + (hash_size + 1) * 2;
+ multi_hash->whash = data + (hash_size + 1) * 3;
+
+ return multi_hash;
+}
+
+void multi_hash_destroy(multi_hash_t *h) {
+ free(h->ahash);
+ free(h);
+}
+
+int multi_hash_file(const char *filepath, multi_hash_t *out, int hash_size,
+ int ph_highfreq_factor, int wh_img_scale) {
+
+ size_t size;
+ void *buf = load_file_in_mem(filepath, &size);
+
+ if (buf == nullptr) {
+ return FASTIMAGEHASH_ERR;
+ }
+
+ int ret = multi_hash_mem(buf, out, size, hash_size, ph_highfreq_factor, wh_img_scale);
+ free(buf);
+ return ret;
+}
+
+int multi_hash_mem(void *buf, multi_hash_t *out, size_t buf_len,
+ int hash_size, int ph_highfreq_factor, int wh_img_scale) {
+
+ Mat im;
+ try {
+ im = imdecode(Mat(1, buf_len, CV_8UC1, buf), IMREAD_GRAYSCALE);
+ } catch (Exception &e) {
+ return FASTIMAGEHASH_ERR;
+ }
+
+ Mat ahash_im;
+ Mat dhash_im;
+ Mat phash_im;
+ Mat whash_im;
+
+ int ph_img_scale = hash_size * ph_highfreq_factor;
+
+ if ((hash_size & (hash_size - 1)) != 0) {
+ throw std::invalid_argument("hash_size must be a power of two");
+ }
+
+ if (wh_img_scale != 0) {
+ if ((wh_img_scale & (wh_img_scale - 1)) != 0) {
+ throw std::invalid_argument("wh_img_scale must be a power of two");
+ }
+ } else {
+ int image_natural_scale = (int) pow(2, (int) log2(MIN(im.rows, im.cols)));
+ wh_img_scale = MAX(image_natural_scale, hash_size);
+ }
+
+ int ll_max_level = (int) log2(wh_img_scale);
+ int level = (int) log2(hash_size);
+
+ if (ll_max_level < level) {
+ throw std::invalid_argument("hash_size in a wrong range");
+ }
+
+ int dwt_level = ll_max_level - level;
+
+ try {
+ im = imdecode(Mat(1, buf_len, CV_8UC1, buf), IMREAD_GRAYSCALE);
+
+ resize(im, ahash_im, Size(hash_size, hash_size), 0, 0, INTER_AREA);
+ resize(im, dhash_im, Size(hash_size + 1, hash_size), 0, 0, INTER_AREA);
+ resize(im, whash_im, Size(wh_img_scale, wh_img_scale), 0, 0, INTER_AREA);
+ resize(im, phash_im, Size(ph_img_scale, ph_img_scale), 0, 0, INTER_AREA);
+
+ } catch (Exception &e) {
+ return FASTIMAGEHASH_ERR;
+ }
+
+ double *pixels = new double[MAX(ph_img_scale, wh_img_scale) * MAX(ph_img_scale, wh_img_scale)];
+
+ // ahash
+ double avg = mean(ahash_im).val[0];
+
+ uchar *pixel = ahash_im.ptr(0);
+ int endPixel = ahash_im.cols * ahash_im.rows;
+ for (int i = 0; i < endPixel; i++) {
+ set_bit_at(out->ahash, i, pixel[i] > avg);
+ }
+
+ //dhash
+ int offset = 0;
+ for (int i = 0; i < dhash_im.rows; ++i) {
+ pixel = dhash_im.ptr(i);
+
+ for (int j = 1; j < dhash_im.cols; ++j) {
+ set_bit_at(out->dhash, offset++, pixel[j] > pixel[j - 1]);
+ }
+ }
+
+ //phash
+ pixel = phash_im.ptr(0);
+ endPixel = phash_im.cols * phash_im.rows;
+ for (int i = 0; i < endPixel; i++) {
+ pixels[i] = (double) pixel[i] / 255;
+ }
+
+ double dct_out[ph_img_scale * ph_img_scale];
+ fftw_plan plan = fftw_plan_r2r_2d(
+ ph_img_scale, ph_img_scale,
+ pixels, dct_out,
+ FFTW_REDFT10, FFTW_REDFT10, // DCT-II
+ FFTW_ESTIMATE
+ );
+ fftw_execute(plan);
+ fftw_destroy_plan(plan);
+
+ double dct_lowfreq[hash_size * hash_size];
+ double sorted[hash_size * hash_size];
+
+ int ptr_low = 0;
+ int ptr = 0;
+ for (int i = 0; i < hash_size; ++i) {
+ for (int j = 0; j < hash_size; ++j) {
+ dct_lowfreq[ptr_low] = dct_out[ptr];
+ sorted[ptr_low] = dct_out[ptr];
+ ptr_low += 1;
+ ptr += 1;
+ }
+ ptr += (ph_img_scale - hash_size);
+ }
+
+ double med = median(sorted, hash_size * hash_size);
+
+ for (int i = 0; i < hash_size * hash_size; ++i) {
+ set_bit_at(out->phash, i, dct_lowfreq[i] > med);
+ }
+
+ //whash
+ pixel = whash_im.ptr(0);
+ endPixel = whash_im.cols * whash_im.rows;
+ for (int i = 0; i < endPixel; i++) {
+ pixels[i] = (double) pixel[i] / 255;
+ }
+
+ //TODO: haar option
+ wave_object w = wave_init("haar");
+ wt2_object wt = wt2_init(w, "dwt", wh_img_scale, wh_img_scale, dwt_level);
+
+ double *coeffs = dwt2(wt, pixels);
+
+ memcpy(sorted, coeffs, sizeof(double) * (hash_size * hash_size));
+
+ med = median(sorted, hash_size * hash_size);
+
+ for (int i = 0; i < hash_size * hash_size; ++i) {
+ set_bit_at(out->whash, i, coeffs[i] > med);
+ }
+
+ delete[] pixels;
+ return 0;
+}
diff --git a/fastimagehash.h b/fastimagehash.h
index b520921..0e767d6 100644
--- a/fastimagehash.h
+++ b/fastimagehash.h
@@ -8,10 +8,25 @@
typedef unsigned char uchar;
+typedef struct multi_hash {
+ uchar *ahash;
+ uchar *phash;
+ uchar *dhash;
+ uchar *whash;
+} multi_hash_t;
+
#ifdef __cplusplus
extern "C" {
#endif
+multi_hash_t *multi_hash_create(int hash_size);
+
+void multi_hash_destroy(multi_hash_t *h);
+
+int multi_hash_file(const char *filepath, multi_hash_t *out, int hash_size, int ph_highfreq_factor, int wh_img_scale);
+
+int multi_hash_mem(void *buf, multi_hash_t *out, size_t buf_len, int hash_size, int ph_highfreq_factor, int wh_img_scale);
+
void hash_to_hex_string_reversed(const uchar *h, char *out, int hash_size);
void hash_to_hex_string(const uchar *h, char *out, int hash_size);
diff --git a/imhash.c b/imhash.c
index aebc0e2..f748442 100644
--- a/imhash.c
+++ b/imhash.c
@@ -54,6 +54,18 @@ int main(int argc, char *argv[]) {
printf("%s\tw:%s\n", argv[i], hashstr);
}
}
+
+ multi_hash_t *m = multi_hash_create(8);
+ multi_hash_file(argv[i], m, 8, 4, 0);
+
+ hash_to_hex_string_reversed(m->phash, hashstr, 8);
+ printf("%s\tmp:%s\n", argv[i], hashstr);
+ hash_to_hex_string_reversed(m->ahash, hashstr, 8);
+ printf("%s\tma:%s\n", argv[i], hashstr);
+ hash_to_hex_string_reversed(m->dhash, hashstr, 8);
+ printf("%s\tmd:%s\n", argv[i], hashstr);
+ hash_to_hex_string_reversed(m->whash, hashstr, 8);
+ printf("%s\tmw:%s\n", argv[i], hashstr);
}
}
}
\ No newline at end of file