From 13ad4741c45a6aa2696390ec6a7c644700e6e9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Denooz?= Date: Wed, 7 Oct 2026 09:56:19 +0200 Subject: [PATCH 1/6] feat(stamps): add visual stamps with text rendering and bundled fonts Add stamps.py: the Stamp model (text or image, page / first / last / every-page target), the bundled font registry, Pillow text rendering with font, colour and size, freehand stroke rasterising, the --signatures JSON loader and apply_stamps(), which paints the stamps into an incremental writer at their exact size. Six OFL fonts ship in fonts/ with their licences. --- fonts/Caveat.ttf | Bin 0 -> 403648 bytes fonts/DancingScript.ttf | Bin 0 -> 133636 bytes fonts/GreatVibes-Regular.ttf | Bin 0 -> 457588 bytes fonts/Lato-Regular.ttf | Bin 0 -> 656568 bytes fonts/LibreBaskerville.ttf | Bin 0 -> 171900 bytes fonts/Sacramento-Regular.ttf | Bin 0 -> 79696 bytes fonts/licenses/OFL-caveat.txt | 93 ++ fonts/licenses/OFL-dancingscript.txt | 93 ++ fonts/licenses/OFL-greatvibes.txt | 93 ++ fonts/licenses/OFL-lato.txt | 93 ++ fonts/licenses/OFL-librebaskerville.txt | 93 ++ fonts/licenses/OFL-sacramento.txt | 93 ++ stamps.py | 696 +++++++++++++ test_stamps.py | 1218 +++++++++++++++++++++++ 14 files changed, 2472 insertions(+) create mode 100644 fonts/Caveat.ttf create mode 100644 fonts/DancingScript.ttf create mode 100644 fonts/GreatVibes-Regular.ttf create mode 100644 fonts/Lato-Regular.ttf create mode 100644 fonts/LibreBaskerville.ttf create mode 100644 fonts/Sacramento-Regular.ttf create mode 100644 fonts/licenses/OFL-caveat.txt create mode 100644 fonts/licenses/OFL-dancingscript.txt create mode 100644 fonts/licenses/OFL-greatvibes.txt create mode 100644 fonts/licenses/OFL-lato.txt create mode 100644 fonts/licenses/OFL-librebaskerville.txt create mode 100644 fonts/licenses/OFL-sacramento.txt create mode 100644 stamps.py create mode 100644 test_stamps.py diff --git a/fonts/Caveat.ttf b/fonts/Caveat.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f84acf2ce2d1b3329b194749530dbaec047e6df6 GIT binary patch literal 403648 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⁣YsmL8P*_#Bp@Rnl^Sdg04 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%0AMS0`Kr>>-yS$Az>iYugs-$EZ{VKvR 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 literal 0 HcmV?d00001 diff --git a/fonts/DancingScript.ttf b/fonts/DancingScript.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9f521e7fb357ec9ea9820ebd36a9d7b1f72f2935 GIT binary patch literal 133636 zcmdSC2b^R@wJ=_FZ|9tI&N-*ase8iC%+AbC4m&%`CN{Adc9&&=B_mlRC_X`gf&tNo z2~{`j z`P%7H?-%Xed~`qaKJqO7Jk)oc zwR!Kh-lHn$+mmo#@VEW@4jq2vROfFI`l$>dtz!SdZTrs@Ty+UN58sgxC<#rY-pQv< zwQf?j{}r+93jje+sxi5bem-;OLsj+Z-|#g&LU#ew<^I8Q>@BCEF7K~Zb(PQ8(3Wa9 z$%VOyK;ZA)@RkSRN%E%Ee?0ik!+*xtAwJZ)k^zj-Fn7hvD1*MaS{0$&5jwvc?$=@K z$JSTSBM800)NmNY8KA&>$$dP+JPsEZV)4h}8xL9^ufEKzAT47+2Igv1!mn2UjDLlC znFxH}iHi8U)o1Vrs?Ra&k%MWiewKLy>R*5o%s!-Nlt{xoh`dY>QZc6LKk*+>h4~sX zGe?n`y%MfBL3uwiGUrr(hyT6$JifB}I_|5!fuF9vf=8>b;!^ctd`a~s{4=1ypQ~@6 zXR6)!%fQJmA(pwc`g8mQyn8P^b6NGn_8qpm}K>j_%ssWUsV5&e_efxNuxB-pbc=gGX*q*dDR!OsQLhY5bePqs{Q~y zT74b;7>UqNkOV!2Fr$FaKSBZg8{|Xhp^MO8pwXHA1IVZ z2%j{UU8qR-hTRThM|kJ|wA6TweF}Ju@LN-1b@08d`dOX<_>b^lz1)b#*>$z=gfIU; zF02zI@SDg<=K+}u%?0KKnHy`$W|(giD287|ZDh_saX01;nLqzSh0MX`LgylxkN;JH zc}nIgov+_OA@=_2t;{a~pZ`vIH=O^A=cp_o^5FkbVVu?HNujca$eZRuWDhCNR9|5Y zH916N(f>rb8-=JGA~LPH{2b&Ek#Vnrj3aW6TwkeO$!8A!WaA!u$KP+jx%)q@b|WZ6 zKH{sY&kz~OmFj6626_G%eE%a{iOj5mOd?lOzEypO`FQO!k)>(}XrrcJ2 zm5Ej#X8fS{o(3KF=jv-~%B%4GpVc>60qC{Ykc52<`gA_piH&GC=#*Z(1r6dLn!s{Y z#+vHo%okCXIfdfPC(tCm3>{`t=q~gs3Ng1KFsRY#P)-Jz8jhGZ;==OJMiH* zQ5M_bnu06ne^MADGJtN(ft_JszJMkfEsV`G)!#DrL*K5bs)4uEOcd^ofer8;&}-X~ zfcY7;dm&2j?gSg)6Hw-=KVr^9KA3gx`@fyTqhN?e-ey(SK3T+Pn%`S##Zbw39 z9F5TuM^|GpTEZ+m&x3Lv8o+m=0Q)3Lpzji!r}`!MBZBKQaJ9qrc>;wi*u~YK)XMMR zdN&keSF&)u7YcnEu5Utl5Xw3z&{p*dC}2-kr=jeDG71H_t9lyB{qVdNuJDfP*PuKK zrT&f^;Pczs{}*kK!2G%ywS&zuhlk-xFnSv4==Ejz{4;tF;TF_R>s8@;FFFP^g@29r zlJ^r_n#&_ZzOZLfnvlxGa)o|F+bklss1EV?pN8w@=mL;iKs_W!Nz{V6(E?gQ$I(fA z5?_mNz<1zJ;qT$!;TIVz6KAqak(p;6X1>XMoB27*V`Z$8)v#99$A;Jhn`ZNlOC0~^ z_=ij9vbY>Bk1OCxxmsOi*J0NkuDe_xaoy|sgzM9;2VGxueaUTbdpvxP#-sO`J%gSV z&$c(1Y8CJxn7B|1wW1!hh&H2h(d`tI+wuMQQT#mq1O6uyVNx|r9s^8%!Xj1xn5Y30 zFB_;~asgm+yG!dbxoj>M#iXT%$(^oy0F#fo9so?f;ClESm~4Fm1T1q3{}pf%0A0Td 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¨-pVm&f+N(&34d3^iP=))L6b>5c)wHv2&PX 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

Ci3GeM!E0^e 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 w-9m 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

{e2O2{s7^`lE9GCT@J zbQ6gfelE83=;=t}l2{XPmpe@5oM<9OzpYFQuRP>-uALj35-Hv6D9!uI`SZszD&qN# z5oxifrPk~z`3)|s{xs67@ETcb7)Y?FZr!>BZ@ntHp+gNqYc8RAUcdMn{H73EuI$UFCl&&c_x%|H%u| zB4OSg839`V)YyllmgovkenaB$*e>2TvhYcndaS&>?$Cu!j4hHFY=XPAXVfm8Gj5kg zg6yCD8na8$JBC&qBQ&X;IDmh@bn(IkQF$S_`Gf;Q>#*^53frNK*j`ir8sDj>`JnGa zA!-jsqv(K#M(2ZlC&PM=mF?)3f{bVItJJ?9>b)R;4@A*LZsbeYewL1Eit!y;+<94K z8$z-jJ-3)>AN|3IWG6ZRSxl=`nhr!dqgjdL6{4N&xU?&z^|*V+$aYvB;}k(qwvWAu z3HNYJu`J!`WPL&DPIIHwR2~Y-_t!S`EENc#ZH;8|J-;v{-(MTbyP%jRY7&D2{vinX z;#i|~ynyE}a+pCNt`R5iRXz$^tb;emvuQ+IBynoFQdDs${8tV0%HVV5*v|uFKhi*l zLWz>u?}AK$v&I1)s!%X*BY~=Fhzo_B4i{6Qq;0Qrp_^SulqWtcom!~?Iact=P|8<6 zn63}xT;ozu7|BC$H(>(=e+)95%x+6b^Cek*NuG3)A}r)FLYf6JM`xDhz<7{0u%u#; zdPYu)1>3=l>0pSy*idRnfuI}Xb5SWpu8w);lt5-uX-2g0OwqPL^@+yDN9G*+_nF=W zFY)0|lq_OFN|rdI9A(4q7gl6UOZEn`9GSDWO>N)Vma?WdeQH8!YqUL4Av`hTmSxl8 zYJYX0Y~7r~Kd>^XCn6L)5B3y_#2GjP z_OaWfRuOc8>|UnOA<3-5v%iFx_?wiaSfKdi;wf3FH5BjTJ7S0zA;zpl zJec~bgls@UNrcS5^h6Ry;O<5_Ev!yD0)PvJOa%L|`Vs!X7fWxPm)_uuhdy}H5gX1= zHpl9;F=oC_8z23Zp$~+pqtaIX=A*O4REK%!qlA2iBR@e1H^yH23EqTwl};;bF(wv= zbVZwWplhT-i6TjEQsgu&7K4_pn?x?rm*{i3>E%aTH9=!0Odey|m=TxCGc7M07EgXNu-%{C7Jz zv@b;yj?ohZCPak3Y0Ja`e}LbWt@!@Guld>6?^|7QVd_Kwek?Qsp+C+or1#uC!2hq5 z*1N@TOBWuX(XjDgA3^V6JjkF#+Ylb1W=T}x6QsX|x}o*MTri))Nt+m!0{cHG2CT4o zWuF4v7i2)IC^7S5~-ud@$ zpkdu~qXLcQzNLF*1Bnq(f0P}-?uI@f9B^<$f$_m^jZ~fOZm6Dqd9CP!%}IU|%Stra>tItS4YFd+9!ci6l@Ulx5&tL>v0WE_H)2 zGypJ4O?7T|Mw&Y@J{H}DBk=XwB&{mM6$*D`xbA2aSt#Km2~EHY-cWiJXm>c(1Ugq9 zE?Iu(+=chAtq=dUamnL;#E1kMIhZ(7ewTUq8<)GwMXOL)2VgX48 z`yV(M|ARTW3kWj zxb02PIE7xp`ixE9k1o zRzJ@7<7H4v41;$$>w@G$@_}!%ZIigA5l01g2>b6DeDuG(`wbTdl zJX&$a2?`t`F7kJ2ne@Bomv{hLjPH6HuJyfqd`O0#la49_c$av>*T5KiK}RIzNZzs^ zfV2rlL=uAQ)x-1)Wa<@5E4Ot)>~qZej=6r+0<+lX*eh`o$rv5=1>lwK2oO<1Jh~sk zVotOrlkd#SLHe;fVc2g_21?dEwjvn&AltaAuP!;{M|}R{HD@+g1kGVr!-kncV#swN zSwMUKw2Jx*L|o}F$!ki!eP~H>M+6r^77BhbuU=jy65+C1O+NARx;KWMB`n8?7ZcK{ zj|X)abZWE~RfNzLz$gLdKLGQKyd|17fO)x5mKSs?snnq5g~D;Nyr?tjXsxPP_a1Dp zUyf3$q`jnf5d8Qj|G!tN)zJH^SK{&5cc1f#x;;c+k9YIsUYiWL9y`be@KEUN9DnNC=RX zaXcX_Wt1Gl{>XqY1w~KHCCiUP#jUFkzxY}Hjzf1(J^I=6i#xya?|XLq{QfyAgWV+l zm1(=Gr8BGYQ%vzjVe*0p)>M#M6ZVzN%#T`lLHgs1$I#NYzwOj}Ct`sw+5e-1ldTEK z306DS0{b@)c&`$yUk=%5S+E4WFgw710uLB}&l;stR-yw_!FCqIu)!6BJDTM)swl!b zQcn;hEI`gT6l!ExE?{h7I3mg|%-r?W4Fw%{zPY+_-(Z>ypY@dpiBT z_CtNA!j1gCp$_o{oduZXK>y+Ct6$tz7gszrw@s(e7$P%KV&1-?vUov#%5Y`5uj92oa(sLR$_(E?O9Ou}f9 z|Zf>Q>#V@pL)|X%a%U7Yg#z}>3zKNrNxV1 zl3)!>m*^+RxZ5_qw5z6O*Gn6Z4xHUuS-JJ>fUu|kHR;0#ACx}4uzdLiUJs%W{cHWQ zOi|ddCgJ4oFlU%x*O-3DyKyd6IET;x3{kQQ$r25EQ~-gKKlOJCb6*VF<`kb5I1loK zoAGQLqLDvjnZoC_2!Ig!2EWS)Ny=TN!vz7UEznp!6s^^Ea9S-J0fI6())U4*a&hn( zT=IJNj){Z#ue^&=FNkta_{B`d+w69Gk{$hj7}rFk*_E7ZWZ`0z+cSkXnmWTRj>`f3 za#SWO-0!N+t>A~#0w>-tU)J~o5ba7>@VUJu|jreHo@gp9I*j|!Ai zm^b*QNb*7cERdB5DVW#_t*3$XtvY2`D|Py!B4KlL!`Yf^{x6q)9Te7KGpej1>tf!W065M%ljX z-_6)QJ3X~+$1MJo)V23JH&@o}ePh?}jtcWKrw>%uuAGvpRDIr8vF_nT3m@HFEl@HP zW4ZjX@?DI@$QARw&pQCdBuoos*prZI!KA9;H!6_rS1VAxOM)9D0|1*5K-|S@^~u${ z{aPuCd!7?rja*lDU%yoJIbG#l*|Pk4(o-MlEMIlYeMr2f-eix zXkk;D`fCD5R{wUVb>C_|2Oao?2VZ7Wu-oDf60CDpg{<@P6iuHMP|%Thfv$ zI|}%fdnezTb@oE{yy*)A>rXG}dtytCV7>T_)xGPMxytiX(EAwM0LvT$efJjPu(e!M zpdNZ#nS*x}sACP0OAz5UuL9Zk0JaQ~7EyA6X+G#c>JW-&xL9zbmaBsC%3LVv#ol0&yJ0@lu|F70(YFSsQ%W>j{V&^>GKXRoVlsleSh4fnFZO? zOA-=O65~4Sn+q1~ncDwQM#ftYme0tGR$wYB@>6uNkcFHRG03Md4_RD&pf&;hDbirS zU><-PMO2RPqtryVHx#`{kn?RQRT~}h%HpzU4v?y1qB5jPsWss>Cm@zrJcX>=d&lp( z@?Ep0{bVn_>&o7BdxBb+Uw8WUiC%5RBN?fK2R@~Bz5E&C>%YYL&g1&z5|0F0ND*Om zDpe20SBXP`LtvaOqBD>>!6jJl;1x1KTkvApTg>CYS>*Ouy)2?NYRyd(IE~C=9p2lj z^R&o2XEfc=kv*X!Y4H{&&1uBecE<|~>u=5K*w>wtHf!fB@x=*!%ZtwxPw`u5a~Gt5 zMU3t3bC>_6_F@iv+!9&Ox<|IN0^1qZIn4k}657hc)8M_@RV)xavg>8_=;OS^(vKzr z!y6xf4GQXol1dbDWU&3vxmN47#%CXG+SZXB^wKQeB6mgw@TH-*%^W#aXK-pbMe5AlZc%c8TYQ`;@N2!k)#(R%cUyY~M0 zj+VSd#}?R(D={=Chdx%^iM2}NK9|)H3PbTRXwnGTtVE!hIS()|sW}3ME-#2{++IOX2MSgOH&ni2 zyOeG5u+0+5q<*i?c;?Zj8|Gw7S;~{AFU_Vyz;=l&=caE*sB5@zuMk5=)wz{kYK;%p`HjH;fC6PZms$^?84RuA13TUcf z6Nbv-2w-AY^rx@ceMjr!mk!PJH7=_{>kMbz&F8nA{8dYOI9M=prr$89b={O?|E$do zf4kUm)9keDuD!Eb*R*CEG{!Ka{<}C5j^Y&$E-4%6YP6dxn%gs)Z(UM0dvcRa=kmIe z%co}+Oe>5znAzNuQwlBO%1GC#!-z$PVroZ~-^ZTIq&)`{`+1p%*Ga$2Q7E#z!6cwi zcK|H|Bok#4MX>fyV0=?d4kUoXAiRlg!J!NV8?i4b-J1_IC9oU_O^*8#^41*k7czYd zi(}NyNHvD;lLJ`Sy`56PGErbAmq{T$D-3!qOkk8xjrDd2(1!%g1W~{5GgH1X-Jk?| z&+l?&IK!pO6AJGW-y5;t?F7`jMnq5m9{;rBEY`uvm2gu7Q*x4oFj%AHz!7$ipmdy! zZ*filp^J%u5mORVGN~vt1I>uy<6`ab!NGp-aC0dp%PbOM&rWVH`)R1FI^jD>t&8b!X z&;KFCAPD!YCDU$6Gz|3_W5th$rkXSCW|u)YiEQ8zh`J2;2EPPI;F?%E=YN2ugHLZB zkENsX9ARmGYreylJH6y*KV5pb-Q(}tH%Hof?%Wf<{`D?rc9l1&!XG2u!@rv|b7e`* z+8J4*a_9E#JMSe~or$roXZ0Qvv97^g9v;JI8Bs9sK+|XjQRlS62yy{b&q?gUsx}` zSlt0FuEt0ZUSgGnEC?6Nyb&2^A*zrxfW*7XJvdRrw;+l>{%U0V6him7FJg`DD0Yl9 zW=4^i52VZ#J4V8DG?>ogEobdMsg+C!O~-O@Vw{wiHBdKeZ&!BNvfE~Q(5{im6LX~A z8<#t)!tD-p6jrpx4T>M{m5wI)%GN%*Y~9yxsteQUtrn{x!mLY~y>CJ14NVEjR*6=K z=b{l?-j1Kj2}?IAZXzt5^D0=na<04}&z~t{>5{I%(uuHY5jG+y9V4Y04W$E1ZxBjX zh{DuisFqo^J=VUW$)9U@J$vrrrxs;2*k6yx^>5|1jw-(=-!6T6z>ymMQ(JlJ?5En= z(taAA<~SgIYR~uhs~peWBF%8b^7G;n_>vZ>i2t_FBfXvw$Dd9wKqvHMewWiOz3OuF zFGwge4A`C0jmcTzhJtkIk5~`dQ>PURFb{5uu>+<`0!EGatXcv88+i{(*ot#y$&THN zje;NnUOFm-g&cW_P>2jskKi0oCa6&O$dKvSFMSr3$A+AbO7B82%-_ZXc*N*-2N)Uttu2w z;F?%eLx#=SN1__UtVGL$e=s}%Xb}WwYk|cg*qkD3i@#KN+EnJ*ymD}G<>uH7!=N_D zvHy=2jK9(zlgO92la%4zTm6_!dqc*G!E@&ZUwNfFwcPeodB*Jp$=Dz? zmmVJmtJ=A0)y{9ZU3@^EaM}fItT7ntH!;>Y!kIWH#>@>5Gl?*BNh6rK;8G(-M2kIU zXy0T*%bvUPtn@Pf$^7YQKQm-t<9-&E9~u{}asNKHGslgI_9e->E3k4-*~9$OSUJTJ zY`pJEj=@3x-NE3Q;eR1{#E+$Z{toCG>@gVB=kT3ixeg=^?ic3dFo-glV>8L6V&-W8fjs!D<#R0{oFtUw|&R_(b3w|Ku z*NTaNr{VOfCdWV^MzcjuOW~ z-kKYIDZWJD%aVLDzKjS%bLGZe}3nTaRa&3fO)k+K4oAWNgTL^ z5*?NijGAnW^K)gS8Wus$$|iB3JxaL(qefbXnF%sT%^Z~OVSK(K0|IL~k^+|%VVb`K zq;@~wD?Rz7&7%2CWBNsyHR2)ZNnRI}WOf68(BRZbj{>8n;omdprQNYkK436OG13~u zbhsGcBo<-3<1lKFrvDK}O}Pl$;nKa*%VL=H9{=aF!C{EY_w5^s5m!Q-;yb5dj&ksw zQN-zE)ldtJMv9X=(diqkbK`JvAYZbBWRcQsAq*cS(fQHPG(`^W!d-uQvUiYx1);Cy zpH4L8-L#HxmA=<7Gr{2Czr*DDRM_Ji@%_;p`i4Z=%mfLRQ|QPUQWzg&M68P;E7?|+ z@o3Rpw3Xm!Eb@RYtD;r~W8i3j$%z}!PHWvfWyjpy!M2&3CwEZoGXJzq_dl-*akZOh0af)M@;Og0LY zazFt745l8G8hHdPaFj?YFw_xS;dy)q%+9 zp-wStCi+$P)Mc4$;W@6kO9u-3p5Du3Th4-V#BgoH31!9Y&d@b$nl2^wyq`w&(dxs7U&gWoXj4t5!*o=?t* z{Ed`i0$((j?e`|fBCQl@j6m}%B$smeTuLs5n*K5ynmHpQ_Gyr)al~{HDnp*+XUs1N z8qtv+`;43B_{aL4=5X&{GdlNob#85pm)!vPR%F3CeFhfm4HxMU@!W!>Qqohhc2&$WDk;0~pDcI1Z<#5(w$ZU}|Dyq06NB!O=(8os(V- z_gBy8?D4ndCDv7!=O$}~J-1LmMqGMc`t$2sYoeU1qiVLk&PSgoY0i8w>4^Aqyh9?l zk!^-6?_b|Fs{b|(;&R?uM9Vn?*J5mW!VAkrX)gQ^k}r%$fB`8!LS7` z{yb;?fjOzQq40n?+>?^gTo@BS|AM zNXlra*(fb3ZhR9;@}*%VNt#Le1&;Y2dGB~N8CuuV%2<j2yx6vmk}2zZYLnuXpS zc`((eclU6fR96%{>=95T0nMoLmXHs!5(_f%1OiUht(?S0gVGX)~S*1QfeMN zY);birS?dZoiETQnGds#C_ETb8#i=kL?kLim&Z+x8R`~4HQ9&W&&|EvEA_u8%c?mJ8~;>tM}BE(~GK(o?<3uJ~wsgr4a)itU@_%v}&_2DLUEP0bx9 z7W2O6uI?$@aYy7(U1BE`*3vUO>npcBvr1NJ!oyV8SOg$PNjnMK-aLNHtKM`@@k~^UGfwNlyTv6^cC5oY{bFqu52xFg6S5 zr!m;9kw1^aX2}toFN)0?do`weI5UJj5K1G->Vk5gV=f=YX610%aJH_8&ANu~l}5AV zB|-)}rF5!uS6%6dnKhq}IAUS9jGenH9kQF^LJrw_m;*GYD6eIHb0Xoh>{r2Ojd%wP zpOrEyk{NOx2?EO8+K~5104?z!PmURKiS!9CNWXm2Hfq>E;Z@SmsFCt-?c^VY?-&|t z$4-n>;M#!aeO-ATn5Z&d2pCd{u^T2Kfulm*OOl}$@kRuWV)$-t#3*Nlv1f??2;zsPlXD9c3~ak|P(rO9SrQYy&pC~ZM8 zAl4IrSs$`{GZwQ%N{?g_;Twjb9b!VxI^ukrJin;0ry*6?r!_r$ddXo|?zzX{+nOxJ=mG*sqHTQ!{mLyKg^ob(NVqY!i@vx4^68m60$Gu zE1r^NT|a_e;yEjLC;tF_P|MvI(0U-#av{dZ3#5!cdaVT^Olq7h)SZuDm!KX-lG#MO zsSwp7Dm*ctf~Xd#C(zZem(4Z6owAY%?ld0t!O%`1rV8bCSZ;L$?u05OFnWxcF2x&! z>uT6GH_uT#C$MHsQG0oUvv5XX$&BJ8z22nr6+N_O?!oSCb81cY1?woZ6QN?xUPx_S z*O*hC61ld_@bg>qO``^f~t(h?%cSF(mYe%>zNh4$kEUk>|i@|&eNE?9Kt)f z;OU@3>Kb^b#0l|E0F%%pAjfb8-szfC5Qkz;@o9K+-`==m&6>iFGFR}0ll9?|+Tj;Y zpPbvXDip%@H_e^+6{||~jIlfB-7U)+?(&Dqe?xv}b3Y3b5M2RkqOeQ|)#PUEb3r>| z96oCFbpW}+(W7&EC5~$Jb@KD*h+g|Tdfs&|!K2v0q_P||_e+MqV@)0gT7@7X~*gpp^f28~_<~f!7hdj?Q z2(Uq1!lz}RDp(M7#wh1AGRIfHW@LV^e$B|-Ui}*RIYjYw^=s%kfrKlDI~v^;oO}7K zr*bJW!Yc@EB${V}6A(-yRCL3pT|V=K+*F=XhG`VfoNl~fPHxaEqRGw*_)MsY23WJt zU0+pVA3RSJemLZq$@3gnJR?5@(d4=5mp@im6yTxbEzt= zD{yKIGYiF3#w#pkphw$y;nt>xTQ6)X@9%7kP1hyc^eJU+#VuRgGR{4*Xa8?ZX8x1q zU3V@mnsVzm)~tQy)@G|a%TW`lHK?PbO!>VB+h09@(+0C)0mgv5!sU+?wbnQ!tu(9B=+vXR|>&CBGcFl{D zx3%r^hs4t=s5rUior8V-3g$EIi(#&Sc=@uJt8urCwydv$xeDF!A7ZYqdix0GDve8{ za1}W*6JoAd7kAfqS+00xRP6-l(%{2PB*w>C(kqD(9Z z-2;XaUTDLesA(o>&b4oZ#LdahOm`;(I)h(EG_)jlmr(`)MPqhcX7s!G zeITJMTTm&hN(ElkQmX(pVyju;!V-9qb44M*rGls?YQr29CaYA+#b6Ht>vz}y`o{5L z+)5NAi=xnnXy?dGGH1!FkS0#!gMGy0u0QI69P$VN>?~mz z6G|jwy}Tl@Ck4QI3R~RG-W7Jg)8I6$ZrRrE-?c*In%>-J;+@uNtG78Rl8>=gIp&{S zUfgoqn>R%8PFqzZdf>$tISuqT)}|W^0w@L#kM-ucmrmbYj2#mGG~DCr<{Rc%KEku>*`MBU=!2KGMcr+Vdj&bUW9GQu*qd`Zw0e^> z-f;1}t~4J3FOv65fT^|vA6v!!Sxy94-I&iRxO}A`pWq72VOTT;j!N)ze(dKsF(j`u zfI|bDKS*PU1`tGT*#3f=n+=yTO>re6cZ{lP!rQRi;mN5uU`Z*7CS=iXE}dP#T3Vd=TL-OJWZujh=Mu3@ z`Kpt1I%91LUB>#Bgc7^(*J$0UKIyo^5|3^u`WcJY1Sw<;7nU!WiS_aNy+k3i`L#ps zdf{6(=kdjB4It3t>f!QM05fW$np0XiieIUS7mcb1dvMS+41wEAad}82Tw())eVulS@sg@GE~uvmtoOZgaA%{2xl z=kgkDlqsB`(~UY_qel6jhQla^r6j^>om^NLq$F{2$s?(*Dl5s#fOxYfdl1kIXA;gz zwXJSe;EH+0@9-O4`Q@VA;u?hh=qWwY4@2b%V)Q{dF7`QNc2cbHu+AD2 zd8st9!XJC#!i8Ad;er(pt!&vcuQqD3Bhz9|$*s<)m>)>s&k29JwZI&EQ`3qJrMlVR zv>VoH6LV`b&n%{oPjo%Jb+Wf+PF|*7VRvS_EvYRlYwkk4t_wQkSD1GZQcMpySi4gQ&Ec^&;E=CAR?JTV#85VJMpcCwq^HkBI1P(qdf}YMLz;bPO)BluRlv zDlEv)@w194uP2$RG2>#K(Kf3&620N|kyew@h7NhW%bp8KgxSbK2XK-6$6O`am&>)P z6oe;JoQNXjsiGZf$7jfeSrz-G?@sxPN)(@Zf652YYUhO4&&1ldov_D8NWYZ!+<*4$ z*;xCHcST1V`7D0mfit2Slr%Ag_U|sf`DVfI$g};f?`F)%&>xLv{agLF0)c+XTH$to4J?0RlrofVxzv z7OKG2?oPxTg9{U#OU+2@>C_+q!E`Fa<(|rgu4o=%_B5V%8}NVmHCfLldoKU+z4sZU zV*WeI)Tx_h-Y9%_bJ*l<&#k}l+~LD~{ zso1e==pEsO!X-yLn|Cj5G+TW`Z=?uZly&F{FxiPZEfPh=8L^%id$cR3E*tgfzM}N1 zaJ?%URWLo2rJPEh)%!gMllfn%XfL@ zqYv5u8<6!Z0Y35*dZ?>fr5~pLHtMN-ja{cQYNT(cel_)(XZ;$JMr+p``9rGoKm6}+ zj#FDT8mn4VrSh6s`#(;8|4!-E6W>26{gzj!{yNrvc>Qs-be+#HTqb&=d-3B^e!+Z2 za`b`quZfEuS^Re9KuO8!48G_Q`gv_>>Do;E+_yQYD=Vuj>35G5M8*w0Ds<3)iywgy z;opk3N>fEajs8P0bh*X&9#Gu}y)EkO$%=c33lad{FVne;8;6oT1O6pzEg z$C4{|KIU;7q*MTJ*Pj3JkIy%FGA#VBEoli44-Lh}AcZ|Q%4-JI#Uz_m99kvZepFaL zv_H}=#5pWO=iTO`T9-o}pW<1JFP1RLQ5JMr1zrMj6}6lKZ-l67q#tD89r7yFAu^VW zHO0iRW~QcOtI|r1g(67cD)W=`l~BPIm^gUJ!tVih`VF5L75V9T=}){<`ct&&Us5Kq z&PnG_ZasPOWUI-i**)|#{(p{dJ$~{y{uH*Izw7jA(i7#<<6#LHTRN~yGr1u-FE<_7 zbIQw22b^;_FPD!PKj_7lzyeeVnw2mfxK2_k7_nN-Gjc}yT6KY@(OtAGEs9sxr$mgi>9nA%cTQ&OCrmEuiGbVOMq0b5Du z(`D@j;u3&Dz=z?2&me=UDOp9~^TGlW*Gx{A@yM~up8+aHA4bTuCxV&~AAsSz#e}Cn zKa%WAdE~d!r~4&ebkDAg!{K?keUHY@n*8&g7w+2Va#^?j`AkJeb3ff|=d>!zx#;=3AL^QUpglU?*?;)4_NJBY^=FhP`@SxH3U-Z8U+(KrzxaYs z>h}*VT>FTB#>t=V-u;_Xb0C@1}1cVkYxKsPM%w5fK41@jhB0v2TC3@VMI&cg{{A9S3n zuS-nG6tyx344`IIRZ4S0P8Q**%8`o+w)&v(4l)iPEuxFO22rgedK_NZ5|dTob|zUg z_T=nnM^=)xK4)5jzq>Ird-~F%Nqti?Y@WQhw5jEuGKoo{ByD_SY7y-f??d z(~cFL-pZP@y*cye&CROWwrZ}Mzh64#74E_NDqwkViZwVBYDg?AkXSu|E~7zE=xKTs zTu->#B=Vq$!kHC&fClEmv_cqh5=3-zWK+UiSg36d14JM<$B!bgG*sU+Thc}PMK-I# zbs9aY{?M;D$xKs+WR=J3vYH`*Tvk)iz9Rgd8VFkQYh@t?bCQWpd#)HjxKGNw^`;ZC zQU(9IKBr|_?X9ACGfwWFJ3Jr0b?dof_{9f){*T1l#Z~ccLyUg2^uImJzALEm8#Ara zui^5#<9i-@L24EaJ)3*@sZTyka(*6S3e_y85a8MaZEmpt{LCsFm3MzFt!UL#! z;?X7^mFR1*6NI&JZeV_C)C)0tay23x3_8IOZT&o`Hgy4Az@1@oJCe$b%+(?99mTyo z3!r#p&z)@+kckFecSv8j>+mbQBExqRUv?RA6RQTd)#UZ;ZxiU!oy)?LkBHXf!%f1 z40cV?v_BqLGq^Pnol%zb<0yVo#++2iFJ9i0G&hjiT;w7GhPn04Ws7fVY+09{+BGRU z#oXDo$(mi>lDl*v7!xCOb7w8eUwC*mLNMMD>cnos)|e9hfPsMx?`l17WMO?Re`*%i;onR>@;|%QeC@zobJF59Pn%=^V%hTYCr5}fx1T>~j(a_# zvlda0IG;~@@t%l;>_irpf{cs;=cXHHA&d(k_A!h5SHMsMF#sM#-b1dtFaLENDR1CCnkC8w%G5BD3MCxK1Kb%X3Av4PMTk9PDh9f4RO z@PgrIUF89RvM+ZpGh2eOtyPSaDY~+9R@=ki!Cxj2MttBqr4^s;s{u{o*fY8w@IgdN%*lkZ+iN!DA~fE1>-^mH!j`TlcQrTfda`S1 zkFcd>PfuZC&z_c{J&@YRK~D66q7Xl+5im#(q~JVLG!%X-DR#aG)m}^1VU~pGNps2)o)G_e!^^j#>!9A)tbLj@-HkLrbAp2n@P}Xf$E|tc#^!Lnil@;b zZiWY5{vRP$We|>H&qT4A=J+=H4op7JO)(j1WeF0dGJN)`Dj>vez~{oC6fUNy9>P8L zfCWw-^_AnerT7o^S|(;TV@HcA8&nVddx_=*eGlEkzDLQ$1)LME=bA#9^ z#9sWT;ubbe`c8~fz8??3j)0L(J7u_;y}TcAcfJc>KI9ZTrErA_L#FSi_r#c$9N|BM zN1C=;=wu7za*v#99%lpe*@jCGZxD`dP~39ypZHsOzSz4fxuk##_p-&pU$9vNnXmu<$3KCDF+PJ&U&CKzMDg<|Bw=zi!?V?nsA$>ta z7{o${)^?-~a3^}I@_Y`{BeYu*=~!Sp_fB|^d?meZ@Bm%qN(OZV92kRXONMarrJS^^ z*HP=$P}el_ebggq!8jZVqOc&(koi39uRs|4ct(^`tdcz7Z41uu3Foc{hGUW zY2EUt^1yNWYVV091+dq`Y)LU%lQle}E;EXuIPC=;RbMabtxfjSEv%T_R~0|`);D&F zw_O_Ox~(TCyXUrU`nluK!h#b=#dqcTFNb_ytULw3Xh$F%4a!9!k$fLQwoywpggCI5 zd6bwS71fC#fgt2l6a!u9p~5NSIKdU@N+@43(O-schs#b`FgNG+`pm=KE*ZmXu-mDu zZ6Rx95_QGm*Eaw5{CxxEDeZgbJG_xvR4f(Mr<$fdB0VM3mM0`C^ZK9I((}Lo8auQZ z%{tLPbxF~>!=;ui;Xy3^Icd3qc+36Vi5Jp2zyxTk5q>8L!A&%BAOl97Ms`ZNTusO7 z4YAckF^A>JOap111hErCUOQ_6*$2y7`^-t4M^MWwCF${i(# z{&r?Gx%%qP+j{e~X@y#&H9Vy@+o_E%?yTYucWuoxXUT-?Jhu?Of)c($HPsg;Lb9-` z1$tF@1&9h^$yn1#mKn?wo3lLTEU!`>oraXjsCWRQJio%|hpB|@A6rqXSX2KsBgc=u z+;e$82NuXu;%R6K+(MQTQ|%rTDLTBYGF(SvKA5Is+?8z z6`Q*!<<8ySH20?YHN}NBa{_C(hAjKCm3Pl;+teN?EU4?Mp0zkGry?;nHQuH%TEZ}T z^d|lbnUXe-TfnX2fDkmL{7~?Q(U+m#%WC1d z+VZ@dR9~Xg(qL^s;LOaM!&pOKmat%9A9Czjn>Y%U$%dLbM_c!D?ApJ5HJ-B|^+SWs_ zuiyCQ(HZlel^$I2#*_ON9Wzn>ehn z$&_Mop{yCbmgVf;XgSZ=MO=zHspb5W>64HoC^SZfiT0xIhO_7Sv*JgW!o`oYc2BG> z(iWcG;E&?f(q~vdp1VovSN=Ni*JSL(LRQM!$F0Osc6#! zHlZ7Vb@6%VGKOSFOTNB$dKQEGJLM*0b-%4kB zWku|~ovrSo{c{)J7;CL-TaYt#+w9E2B@5D9OWkLCyQ&7jUUF$+|6L0JC`M?;O6t&} zO|8v#;LieY%I<8KQ#*TUS5a$jRPKU9bA>%aTQ+WqFP&3LKW*MrS1x>rNtgkA@{7Pd zCUHCD9AreK35w7S?gMx#h>JJ_ktT3pMM8RqK2#83iSm^WNcYg$5;{@$EC}dsDYu~x z#D)Hn$|}(4nUp9@n9v2otZaxOg6teplwyIQ7)b$(m@ri!i%f8Vn8X*)&U>J8=B*0~ zPCgp#Gx0i;O$Tqsl2kdTVBkUV+HSVTB_L%FzhuM3@^$G=R6wjs- zUxb|*Z#1HnU#qdDwwl8KsXkA#+ZE%$I3xIoaBA(0;Hwf= zk&9D;TMt|bh~&bd0!!2wJ&l=#eL^H1(9@-pQoOGC7zcDUs_e$=YFS{9RE|T8Ls!cZ z9^pIE)nB*A`lfDZX;?Qc4QT(~?#7IS(pmYn3+l2gF{YHb>Ah>p<{ev7l-V?Y(fp>& zs5CJ8l%&|qM!m2nw!xRuR+o`l-&0i9UYX_dq)+m>OH%DI?igpQGs6{`Hg$Df$*hV@ zuP3WKEiT&)g6y;?rz=5`(;aN)y^X4=hEHW61 z4m5P+7B0&S=Qo{^-j?1zj6h3W!-9m#Z8qDix`YJ{b(W#$_@7ECbe=Y#Rx8~Ws#SM|zP62&5HibathxpYA(G~T$>c&|cKxbmFM5&JH?NuE zxr_f)Z%_-Stm%R5dA`QAGyLk@7x&J4aAQr~jc5D2Z(m-Y9+|ab@aBx}0*^md$8Rg> zxw)lvM`up<%+-N!y{ViL25Zza$!Aqhy77$z^H(?QJiBb!i?>Y4>DYSvgEODulYX>b ztujPKVlSgVjd&l^(-gM}>S?B(p{Y^yL`*?UVEDg~rWWs$P7SU}FAiyH8#MLiLB31u zyx5{R8zyUNU3OK9iGN;#M+w|;nOd*>gma>wF1qz%6Ulu9$g!RcaZRxhfp1MuPxl1F zRb=B(G!U{QQ&DJPejp|@6Mr@++R6s*edSjhH~#9Cdk4x!|2(;<@3v>&T(RQKXKw2& z8vV0y5*Ob`7vDGTMqGP4U3xw3`7c_4hQJ8IgYr5DGZBOek|>LvQWc`NQcmezL?&c7<{P!BK9YVX{Y(0@^xMWN{$G-@stGR@jSy@C zD@>v}I(PYfbs_wj0`B(b?L-_8mydd4XAeV#P!Y=Ov?$0@ASta=AW}%UM?wdItXHcY zMbS%C-LjD-Sb9=20{Zf3gAYjGzhA@XQRq~cQK0!YtzT~PW+ z{gL}H258KH3M`hz5UuLMnIArJ@c*7z7$%*+aDlJX_doN02af)sjWCa<>}ea@=bzfz zsuPY3^=n#hcxYZ(&$N0V|BT_^Uc9E~%%{g$L(+Y>|Ko{yy)$I6W98N}tB-Dad1uXV z@LvFmo>Q)ckF0^!45nWY;;Q&YI15nfNF4RR*@$kE8{v{)L~WIWkcTkb0=zX;EwRB- z86{qh(&czLH_LVLx#FfHI=c@49uYU+?MTqPd+&=U-&H3@-!060N%(+Y8q=7T))XV1 z7&164LebD&!s4NCN5)_@=y?sR;|(^hM8c?GT5!w&EE|p}mfl!R2 zQeGMJGj5EGsPn3046X&@_TRh8Sb0%$U$`Jd@$uIfGe&+Fa8@0{qZoTM+C=yf6!Qt1^smR%%-hyB zbV>Qx(51E;yJ}*@M`AM5Qlg?#(lTTCzRy35iR7Own4D%3hgJ)>38u8k1yUPwi+`&h zXigP{8-{KcQ>UzIAX&uLNAoz=C!8zgz<7Xn4C8@Q4P(m_#$Hm>F>Z|rkC~T?(;&Yr ztGE6lFUx~)gPj=639eU0vv*dpclP3)&)prJs2+J|VR~jmso#8(-uY$Q?Bb!v5frJy zdq4gK-utju;Mqk8 z7XhHHM3Ri7hUJ8!Vuo)5OR$7>YGDpL7%e8(i5M~$+r&XM>M6cPCPdZM?}wBL-3}u! z^kX=%bXPoyL|$P0lW--zP_JX4@8Fmwe&+CqC<0dg1)rnsg!n{LrywR3KgsVEs2qL( zP-AO{=SASOVS=`o3)gYsv$+X|7J5*aT&!s8?dh03Yi8?|#(LHbz~#wFGLR0-gtr+A zN01Xm!3eTuug#3l@GB&b-HGHQK($dIgPa72v=lzVRp5(G%_#D&d1z_&@mtH67uWVT zdef$_Z@hv>-$Xq6tIpg|y{xNXPKCRC>q}eRg_$YV)wbMOm9?94t2^>+LYOHcM_L|} zY}X=Skr3#q+^{XuTh~=o+Fg}65#j#w)0wu)SxYNs+_|n6MHjQ8y-tJHnO&O_ZZ&Fg z1R=S*rN^~d&~+a05ksbM`&Foh$Jy+<{IIH2`4JZn92nRrjUYJ|;US~_3ydua@WO|K z5T&FF`Bc2nnwgTBPMsT*WylY+0?3P}iGe?aIpr}gYSLc>52wH%GpcQ9r6m5K=bn`% zB`fdlvDT!dR$CX`yRx)&)x8U>)hQ`e!mim5{C=OMAv3eyvj3e2+uKjQv)@vmkC55id(cTI9#zw}MS%L19KKuU8{VA3@MmGj?zT3WoGb^^!LVB1}dhA|-{00IEirM6Ze0>*3@=#UwNtd4oYdYpyUv*g%P> z(QDNDf&czt9f5?^tNNEMUbvvAdtS%vnbVsZDl1BglWj>pYht9^Xr|50HmJ(#M&&1L z&|E$b6JN*{f{H- z!ZrSs%v68AHMJ_^O;~z!LYCgnoo`Q{_V&(QZykcA_v&6|>7{64=_Qb*_m$V5TYoD1 znE%v^yFAOu=YBa;a8398 z)ldwh%|O_J-QbG)6lWuoe>0#3n1j3waM8wC9E8{<4%9Qz3`~)Pk_|RX+UGDSljG(4M!CG^03CN_7ws zD9^2jt^63`yVaaGkW}D_Kym;{1OyF7@eks{YOX5XlM%%TrsSv-vN{l(u#!cHP|{b3 zj1p#=(fNgbCP@p)n#tPpD7TrTQd(BkEsZdTSFKMrXBP)tIzz;Yz_KZ+8)KuE%};G8 zh~F3!9h2Xfk=`=Nr8ns{${>fv&^;dqqKY#JO=`Ovl^uRq&bnu7V7U|`q zf0>igzjb#dzZHLat@5TDR%N6u-Fb3u#k}hD2$PfE@gRCPX?lrwn#m@}7n$oXqUi8qW2Ffu3wK@ z<>b<78l5A~;cHq|x2tL0)YLFbye%9y3ZO)aDL6}NcuN!eouIxTBt7%(P{CxCUrGy& zkLe=6lTH*;Z_Fkc<8}&zJz*BDIkHE1Y@a;l;n96I8t1A0`&99^ea}nJKJ^rT>+c`NXtNuW1NL#F#hBM(g3bJU zWCsc8mB=anA$|m3tcddmGIITxIOMwFZsI^wA{XyPd|M+kYWG%>yUE(nGY_l+8kD*3 z!|tYgVt+Hv93PGLFp<#-<`;&(C*HEp7N=eok(fToo5m|n3%u7iDLpY_nL5t8|DZj; zW_Gc3vto_3ySTl!z%HDP@+Ku&tw~AVs5dU%5*5MQQ}Pf>l*;)Fye>8`Mfz(*6hEb4 zW~o~RSZux0UD{R;TJkJlkHSSeU3A{g{AR{?qg)+{z@1U{NE6slDDPfkhN3mAADfqhnn$*-9 z|J7f$#aC>R%CM9TXe|(YT`ZYHS|B={tfZ~sj^`-cgQy;Z(Buvvkdy*<>p$ndBIDn3)%zyEv<6 zZJR%KQd_aB(Ni#^IBwhawQCC*mDTjZ(h!wZ?*932^;w*{70Pg=-DcWK6D#4B)4{rN!et4=+_QQcPk%RH{f2_fEy>M|=|B3-iQRJ7z+m$}iO)o3A#nmvwJ?!M=|!<&`mah$*V?pGWsIY8L0c<$!u;U1(u z!e`t(xT1gX=9#FI_j|)<-uxW-+#RqFUse7cK6eVYQdkr6xi!j0_}r8DFa!DAyW?MFnnKQq*+4kLQJiZ{ECP$;Bn)h>iWrm;|n!Ij`bzg@qNMMBc5GVVxOIc>qdc3CQPaUWRG$<2;!*m|5e76uMucIsW*gZlAw14-ctL1$C3c_Q zR8z6}%-ZFrE3!18|4GW9QbheoQm3q_Nl1^4RMmhwS0~m5`;F9A1a#pb{$UMA4)^3z zWT6I;1@z5}?&v}NnWy@N&} zH=(qYa-l7~w532x2mO~qp|`i~ZMiL_w@_mF{r=7)*|MWJfw%YndEeekWa*6OJZJpQ zZ+?F{6e2;|-svkoQ&eVsCva5Onw*{QbojH9le7E|XMT1vJD8l6?{wy8CMRdoXIApW z6JpcEi;CXqr{DZeX93kNaL)S9RzkHR39IogFKS-LyW~KU*?KYqYCE#u(krFGA6%3W zqbP{G0fK^I>l7`t*(2}?4|!q=`Ohd{s+O~rs4cLC@Okv*GNG&_x5ihK<3Z%6E#mVC zhzDy#@gIHVTrZhsvzSBWTI!iJtHNvax-qZM5FC8K4j!0Vidy`h+Lp|-eyWK_PEPT#uSaYsK?*Ap(*|9 z@B5pJ0O{`Rv|0i~yPNPRbsXgwN7qTl!)lA+d z2rMT{I#3Q`0hW;xX6enA`8#hOIq!-2xmu^qQZ#RE$By$;kc0DrmK(OLyl!KVkdsHQ ztTGsUTiNmOzn7iYarMpK*0oJbF9{AdZS3+lS9h4L>7MlddAnW>HP!8YV0`4kgPkpP z?YXDsY2i2aVQu+icMe_9gUC!f+yIipfAa0SFdeOuCY;NhQqaOB7bKYsW?8~*+={rwaCExqTiZ7*BZ zSyZ%mUuXMxe?d}4LE2X=fy^6v7c_c;KKr8PrbXhdS2Nw|okkw0b`*U8b;|$#Rk6oA ze``nU-lc((C41+W4h{?yhyR?BD&E(-D7C1;)45~-69#!bIpsrnwkeSAi}##4+Z0KUeCjqO(!KH8sC)Aa?^77R&75QN zOAmbN=afp%#%nX@bMoV_k9tNPm!flx{U2S^=vf&j#EW&yMV%2x#sJR;ozY;_L17v_ zGDe+ZT#DdcS!0k#OnOm)$`mo}v1ey+aBRn>4TI|k*E^CUrzqiHaf%oW0F^LTk+naeyztLv)D(s7h-E8> zPns2odC0`;gnJ8l$)h&{=$GXYNW55n@{k7(Dw)i3y{=SM4A4Lf$c^|7ks5&54fxv4 z^q(fvEK=0~fmCem+_$8-Xwmq*PB_T>`^MZ>Z&KjG&ZW2RY3n?Ea>w?^4j?fU+iot; z{^HS+#pA8>cl8&PFWFJwzI$=8cq*kBY0_(Vd}-sz1BW`>FFHBC`ltKZACloXi17*Q z@E&>aT_BmRLud{))POg^o2Z`BP#TLO*YIxRQENQPXS>`>Azdxa<)v8}wmf^D`c}F) zZ)J_VUDQho`IJ?LlUtq)~~yBchjCjc^xAS-CJ6-vRb!vH;i=T$#?l$ zmsOOn>?kbkSXo}NtkpO1L*ElutiEY$ZSB^ZR$uXiui)Oj{g-d7tJ`>a|K58s4~npC z^1qe;Qtpk&KkX2Qzp64~6x=01`lAa^r`O`*qYID11Ge=55>tT(IR|QiqK`sS3g@bh ziqwXCaBPReN2v6)+O%_`S1KMbs|9=%%tHfyf3DX@Vin<$%@(V)Q=t{aw>60|a1*lx zu-P@mA6G8j6PmYou&iuw@4U9XLuHqzm$&BThRV{@%R;%it>x+Br3RPt@F&05r`wJI zNetCVTV6J}r)}Q8!E&{FOPR}6*21gH%>$RNC@WiW>A=vjm1Sisj}5i1tWQg;U)kES zqBa!~qU@jwHNh4S9Hoj!2ZoMQ#p6S*tLoCy>Q=S3ET@VH`o`Hh7`~sK51mtj;3lsK z94*elgP+9#9;PMPtOiutk_j`;p#UMtY9arz0IUoaDF#xCr0@G=jb3vB{*!-d^%T3( ziaj=)r#Q`3?6HRL7c+_nm#(a=T)A|xc;Y?zZTgkhDxq44p#-hzmX3;DnhlbcA>LCu zD(D{<*fY{m&T>+Dhx9qIotNJqw|ooQS83LuJv@2iv|omexkI^C$YYO*tMHC_?B2=0 ziqA7GdqAT2W<5B7XT;~Ho`+dd7Dnn5mMqo(8?S$#MB%Bk>r?-SlskFZDatknoR)`;9#q)FyJ;Pu%-wNm^#&QoA5JD?KE)D z)o3^!2t?^XOp7>_U`8v@0>`1x?cKd~^V-!hG{O8Yr3otTMb!S5DgN)%3~3X{N^{$u zp|Y|ekQJ2*ft*CiN=teAzmBZ5oSp1I9}^Da{Br(4^CWKgvO+0f@gfDJ^1??5_m+k2 zQb7EN@(g?ivVi*5A*>0lv@k?&BIsL^fr6_U2STaJ8BhQs0bl`fRs*L3{Tj&QIsne< zbQ`q2Rh8~+0|K&|8!J1iItuf%1MUDYw9@Q0eU>2$4mLWbQ&D2cfKbTnL9Qy)Xu0C7 z6f7Qo^8z|nbxDr07PB>u?7?E6zo4|Vpf1N!=ugrObR_HBlmugD&*9p2oqm7ky4sp` z9r^hk>w@j)Evu+lc3yki`O5-MP^Xzaqzo2V< zP0dJGK|$9@P0e~_OX?3S-8XOEK59pwO9MD+pos^?P2x5&j68PTupvW6XOFFj%IHst zo256zKccMXw6crE&B_zvADIRees;T^tctxL4}mVWg2{eL?e!`2isxO0vUhmdJjBq= zEJHi-_wo?vA8$wPSvl%JDr1jPdy=rG`;m0KF7F3*=ds!|)IERzj(ene7;C?2_E=wM z_0rd5FWzy%Y40&t*+KTP46qfnTM2$FX5K)Tzl7`W7UiqpVp3!8MX(Ridl3jiP;l8y z2GmiK>0S(201J28mH1N1{*>2dQ&q8nZ3*8r@g2o~8u1iCJO3h;;MrE8iu`4&$j6zu zN3J9#7MLpsFcfG>SK?yWE~?CM4xo=Y4gfL3%U+tg#lrD+l#k|3=?Tx@YfWs%SYc(bfuv};!6oLiT zf&#A=3T;A>1?FxOcN>k87N-RWyvQF^rTXayBBl$iUAZnNGpt>7+4^Anf%`{C?my5T zTz_IwSeKc@zOweV?e*&)`|CB=eDLT<{r20|-aVS`WltxzY`SLEw!3%K)a+p23e zwIqhSz3HQmIM<$dWW&WjyLD*j)}LLx;gJ(-osSS5A>2X2k<-ZgKA`XL&zDQ^ZW{SK zE%Ay7*Oi|_xg^vIU7`80@QP+e_=-r~DhS5mq{IZtXxtcuTa;zFR<4DwN=11oQiuY{ z-R*TC-${-o$wC*aTXL%idt|f$q%*XnC1TJT1zhy_uwSiSs7>n`M{bsYzF6VVN>W|; zl@=CY&n76jzRO#l%t%r6e;!zr;7HU+9pP6xG^H8+gI`Eb)#!fM^7{lOC+~}$N>S#* z0TvkO&u}YU(s=kA?B$*eSNI$5{Mzua34zgUdH9apEOsw`VDr0ywYV|U6JE}~>dOe< z!T0gv$z<6C%s~y?`WKp`(Mh}Xmi#+>-}WYbFT)%yRqjK?*mf*76WZ|oUCfzBs0~%8 zF#(QmQ;9LxPv<0{pdttJ{>OHR}4QY@@a=T5y-+_iDvrts^mbkn|#l0Vfp@qJ%Qwmak# zt1ammF2=hE<0Y*6e`)T7UlFt=>j|Hv+zCrh&z*pI+l1#{rQCr%}Oy7U$*Y|z* z>057Q2R>m+0`T&$xH$ZGw(G><@aNau%+d01-^gxy{UyxXa$vu#0l(WJjE0b5LX;?$ zC5LG>)!=UdL@7e)Ap({O(ymso8;98;0l7nv0su@47*xFmaWE0X0|>iL$Ahu98+tqD zw}hIT2*fkTo8zT$)Fk3Yt#SQ-iJFj8gcBwx{F%vPQMn~lwK4z(J>aXXstkIUzv|fb zm0upa^zH5vi^Gyw*0-~7#m)N`S;Zr+l!-5cgo#xM*3~EV?!JC_*}mR#yU}iJ==keR zM}KV*Q&`;l>7~C}UCg z@7foD*wl&leZ&rcpnOE6<|jq&cm4n}Q;aVkfdIV^BJ*Qb;>-9ioIy$0KWUSmRvN%} z*?|bXFx1x-G9rA%VK+c3EcKy==!FqZ?gj=g>q71%#CpJ(0OOV@>_jPkT?JACUPutO z3%%|08jwt*Am0OTXRanw@0&bH^qQrKn-aG?UZ1B=wI=u*hw5F8=dG$MU47+h{J!+_ z75O@gIl)uWR(igiT@lL3sr0!_qDjdruFH0p;qMGf;k=E#^AD`4*Zk}k#=+*s#H0*g zj+R}JRM@_yziw<gx3}9+NcQNUeUX*V~&{vu8K*;XTf)N>nSAkPG zCZ#(a>ccK|i($^l`2eM`yNtv5hulm&m8XcALaaT(_>6IgG;)1Am)e+D?8kHKmPf(Z z^DJo=m(~EpBGn-fNV|N><4vla|Ny)SQvwiP-`7<#3mToI7#)5MD5{g^bugSXXuB^nJ6eIC{J z+AXR}M<)Dd1#KSbDK?)j9hya}p-%;FPRZWzqWkGi4io(^`Z#n#6QKjCF z^-ReuY%JJ6#%@Kbnp;<8HD!wpr?xaLzD2aA<(xNo^WL_LcKCHhhui0NeE#C|=UFoj zT`{25T{~`GGxQ+dqXq9V0h(eF5Q!jYIRv(D9bIRjCF`ayS@n9w@A0zz@GI7MBdG>6L6r?}ZxhEpQ8~gIAs8qpY;u}TAOP4cMB#Izvo)2t zM&;&b&o6NXYI-1TbpYU2G;g=ulIhq$GknPdvu5~c_;c(iX8EyIjiGD#1kPV_&}+>o zoIT4${O8mw1`_FgiCPPCI_6l_6wV8U;HfT&dTE3*)==^q=;)Cn9Je;lYZJ*|biqQR4WNDUh5!G(XD0qp{}1*IF}7FLKSqr0 ze|IdzJyZLS25_~Ddaos}_SO3TpbB@^Yl<=!c7D`J_e{e%-!tI3hH=l_h_eFNrD!5-Jh_d4l2@rFLksfLYZ(|5>6vW33O_u1%sDNdRWEAH2JXQh1Ylm`&e4Qj=9Z68bIItVZ z3j>&45|amGN@bbA{$$oiZg2EIjttDP;J_XeI*0V@@TFe}A7}f&zz(nv!n@ctC)hRN zU9>lju|eqxDIL37D|mn(qk4saVBk_EnUA^_7$FXGSDGl^@G+_A)Eo34d+P-I-f=n? zqHsIpmD{9+0@*EBg_gsHBUzD#MJ$7%ztjVRBzQmE*LW|G0(6ZG;cz>Vk#A%vo=#{l z^i?K%kgW7W;1DV+3iEwA>A{R(iX$-r@lr14LPjh=VnJ3%qH>asNLHlO4I~_rYAW9E z;#=ueg>GG{duLtQ`qj$|GAfI*bs6p*%@ylc59iNOCjL3W>d@~hDg>xif;Gjs12(DL ztnjxIY)<{I;zInLU{inf5%vxfjzL@Zg!BpY73)-tQ8!+giJJhK0fYbrZ@C^<2r-o) z$575~)M8DuQAgY}M->&n&MH{>`qDo<;Uj^pXuUyim7CmWf&nCD5N}<|#=;AC9v(Zz z8kdH*v!8A~wDnE#hG$Ov;SVRCIsW$Be67ePc@qqWzaa0QCk~r1hz+G5pBxH~dVXsO;l8_Nfi^S(?X8=m8u)|0i z;iitkHK{${BfdG2$Fh?BcDp~BeS`Wxeq6j+XHpcC?$x{4hHf?rb(1K39nbgze?}rb z19=Q6FU=XBfnnzoN?KlS)z|3}{4vjZN*w;=a66uGPj~pXyIxH+;3+>Qbr$jl-6Y+E z_c!7FaS!4BsS8RCLVZa0V3gmm6{VyU*~0V1Ro&sEcfN~hP?8Mq+{O1gWHRX;88#vy z(H&74t4yRyh7T1npun0ziAKUXQjs{JAcOLr9P25e@>DHAT7qO~05u;|FLaiUz(N5; zOiq*&X(J$%P!C3m&vaBQ#+hF(9XoZQbS!%AF$MpABK!awI>A83C2%=~+pSvh6wb*U5xrRwn^VqY zj~)MyYMbqNN_zeevm7_wk!Js)Gb8_a&}O~U=KR4AQfyzsepn`~7Td(-*blURXT0|4 z6h!Vkzi32h@sJL(^>3xB|FdW&hyn(AJ76QFU@UZMcEntfVX^Cq1yNI$&ZD^N4JFaj zD5x4#C&xqG2BW=UDVGfDrgNg#(vcY#-wI$ccc zzyi>;P=YKE=OB6JJahLXD5TS_d*ydxFoV!VVtKp@Cj z*v^u?aY_|Nle`HuiA&#Y5={BsRe&=HQP}{qXt$jwj4J_LSubRki%!X z6mp=6q`2bx4w&_#>JEaL;2IB16C{pEf~;mn`BYa zon%SNw)l$@okmwdQ%TuCC{OG#*>@O9JoSl*Hk;;MLwfPN3V&~14r?;mHW&)hN{w2* z*^GRC;LkrVHi`#u&z1`fq1t?JHZ+C>*fRh|A#Muz(qM_nksd@}#xVvX9h-UqptWhm zw3Ag01i6JrGd4$*5L3yS;Xev2IIe|YE1J9N%O-QzR%yiK#1ef`Z!pUpTHUB+_-4p& zP0!X_%()5>X!6%E-)t-_~cHLZJV~BbwzD(bw{DJz+~H_^`sRgId$R3 z#l%FD5!<^3n|rFiKaiZPsvuhWvKof#3)?Dv<}$rmXSAi~X9w%weme;CDl z^RYs?HcxrFTT$#O_O{yd2i757qM}sWybE>y{G&wUp!0_f?oGi>I{s9y$AlKO_@@@Tzo8WqDgnb+5D#KL$u^N8oU1Mb^qunfQp!nSSe& z0{9m`2mDe80S~a+<}Tg$f1p9GM0TiEf64iE2b!9mK6Fsq!Uk#^_C3*1`S8e&kJ-zO zKiLj53KNPaKNiQa2F9K?2R9x;|BfGi8?;janm+ zNRN`VQpmX*mWX7sMX1X{bRw#kf^4dRj7G#&W256oe<28lILc@s3fUoW*;jdsdkq!c zYwPB3br&Oo!(dG>aJMc=Wcp;wpV_-s%QLP^bBZ&qMw71EyQi~x{rp0GcN=SGuQYG$ z%&RU5;0m@{1{S3o?fPUxX1dY#kTu1stE{f`cW(~WXX>rwp~ZxT$>Yo}g>dI;o=hOQ z&k7TX16pFvas-i276jvgiV`HptLX`adTQ`TNd+6-^zt&BQ|sOPhl?-z;~tOBZeR8? z@2?j9CC}&&vEDue$df0gMhjdMDAB*d`>X8^g}Q5}`?K41o;`oO=;A-@^&*ag`h#91 z2%oi4%_>PNzkuz+Y`(KRmMZEl>==f%ge<}J`%O3`#aQgTcqJ1wP-y_lSNwM?01nrx7`J>V2 z&**=x^hdEl`7Y+?-{U^NQ?iMjns1~0ZINis60<~tbw>mVzq&wmi*Nxb~Wli_&flbPZu`v=-%|4(L;&!_mzWF~hH;d;aH z)xzH0&g}?Lim!j=wlpjU^9Y_qKmA@xg-_d2yq1Gs<58H~+l4 zJ~2MB%cKm@r&N@KKB?t1d}wz{e-caNUX+7A#Vx-c<@cZ*^eImNE5%ab18FhJzZ)%| z(f_dcjPM~Z2Yrgu|89)GN`3|HzXy{LAODQ@jpEnDHOif!KcHW6p1%?8E0kNwr#No^ zJt*(y?eD`SdV2qD=)aYh-ygSq8rl!j{IUmdbDuuH1885%%O8x6Z^rl+p?o1Pe<)fm z#`-WXLjOIy{Nc%oIOAK0_Pu<3ppR;~6x)6f?OS;HqtW@B(f?X07xYoU{Nnt?8Go19 zFLo(ml;ixw>3^fR5bf(w{{86u%;>)r&mW=Zr}vX_e&W2}VwA7s<*!8d z?~M7I?*B)V;W+K*qy0hN{?%yzGv=oVqaEYpdo4Qt8U5FZ^O=>?|JUR8UypJdFaL4e z@gbH*{4IQCeezzgGg?;14v0r0p65q6m6U{qlO4)0l^;O!R}P_gW=vv$` zgG=4bPAC<+5=7D}$UIyZ%6Jh@10u8_f@*3Jdf_fnlIzV%Pfa1gnVA*xCwFSe6(Efv zbjAzFL&A`cm?5exc~wBL@ph}-@u~qDDT6^(=?9mHGnfS=%s2TDnsWsQM@|w!?bx;55!~g!(;Nbbo+dQV= z-YXs&zZF_~*9SurmEi|`MNImc%~7)a=nyL^`K9T@Q=hD^efs}=`2H`4hW0OS_n2z- zUir|@Tf;vH|HlVIcs;=^q)xu3{8M=xJfIV{nk>P~@fJ$qTO5SveX}qR3YPx~RkWlc zkxZ)#7NL2KX_8TBZUQE`q8NdEo##^waz$aT#0-G~QOnBnMU7Sm-3DoeOYjgQQs)#)NO+2wtQYFQ2njv^rr!X-H*0O5rV^@<~vK zWY*MVXAdmy?yRY=fg?yMOwHNeY;PJw-5fJ%17>M^;T`JDMLu8!|1rC^$_j;&g#VZ~ zFQ7oHl#BmZRnRU$vt-48(kwL;Qx;wI&23wry>juQE1%u6?YXNKvDY{0&SS@x^=)ED z0$0~F+x@EoH`ebSUOpOrYm;_g_`+oiHii!cuBs3J`To_FH`MPLUcO;o%h(MA12^mp zg?3&)IB>&Qi}>wr-@J0sqAS0-ZR@l2`K+`o(#?tu;a_joo)^AwSnZ}E{HLjIm=`7N z*zf}N(cygRYP#zi1Vpu*eQ&%GDr#xWNCoECyjE8l{BUVsAZnvJ4~gQS7A`FCAyq+D zd44Y9cQuhc;nNvJ1&MZKM47L{N^{%a8TUed+}iQ?z&ZAewNIn9kF)NkIO}c=NM4AF zdAUv{PqF7#fzkx6S}7=bt;oj$YZgj!t6OuQdp-^!l&Ir}KQq>??rOU3U@ z_r!aYOtFneH>2?l!;!|%Wl#Kq{UbaOX2fJuvlnOH zD*%}VM~`cWmr{s7S3xhMU>fLB^`|3gXs0vZf#6B$RqIbIS#n~1RrK?!3%6AbHe_cv z3|4KsP@Y_PVzjn)^u)r2myOocj9#|z{Nvu%)%EqOTfE0Gl*!3ccKH$MPs&?@RxJ7i zT(0_?@o+75A$MSOQ|!4es_Gz3wWPR@5h^S{Jn5amSN4uqVS} z7R85dUN-Pht+UgbgaK%Z5K*#N@|K+N5=d&muSJNzy2x zQ^c!+0MO|w!yzXVqUj!Hg1O9gT(=V7DHH}U@C8_5G@>l6)N8kUOMh|G6Sv>~#7*)^ zo3}U(zd`X;nwD1VwVeuw``D9_*T7s(;yqTtpVTP0Lzy!i3E+0C>iJ_#D$`FCSN!nX zue|c@ABta@SSfyGuXuRkA}k(*-;col2WxYBe^`|{`eXld*~2GJJbW2@EnLQ4+r+*V zCY=)eiNgEX$GGFugj;yRlaq*9fg`z#KC$jVu%MIx>Chf-;JK3|xKK)?Jrr5Xw=&|w zpg$*+4liU>5$T91|Kp6h*ep|3L)lZcL|W!Gvnun{s%DHVO-QrY-MP6DclGGDA_rvB z>A;%{>%u;cf}1EQ#)LAryToOB{fXmmP63=Gr4%*$*CNmt0-7icg>O+(;OlD^I$41l z;+f*apgW;DtuaH1Ed-ek${DSq0MG+Pa@-=!30=K~Pt&S#4& zjK|@2pia@;O~z(7p%~N(K?CSyjRMczIi5B~(WO%l3)O#7iw_Q!Ehw^T90>^pzQLuZgRvyGe09fC{?o)rx|JT~hYqW5|n}yuguQ-n{jbeKS#8R_s}@cHSi~9vXk)>P5{pSo0;}TjU?% z#?%Qd!p}p7D)5L%&j)8ibrH*vqmG?I6st1*OuA47gpxJX!C|k6GI=>{NXLOhIypwf z|1cgV3`RhmbYw7ynS36PJ?)d71yv!1YSMB!rGR(d+Qy4-NS3}ELFK9aT;rC<4|ld) z_}I=Bx9tK->;da1-MO`Cf1Z#a5tK*jIrPjPl!_WdK2x~p-| z{o4!D*IvD*6rMbmmMG8 zf>ou(MFpPh441>^p}CIaVxoZlXq-%p2HMQy|LdVej~*CR{X9MA(IZkNJ{#CpwfGA= zLz|bEw)m~(>%Xvm{O%f_?<%KuNqx=Ypews+S3S{OU}1O}_KI6+L;a<*qDW%xXkomoV>ZCjTxE z;!deYw4xvI?sPyHm*lEo<;uYJ_2sGNQgQj_r!MU)=-tws)tvcgb{g9g zSU%5JIlQm6b>DEMZ{Bc#?M};nB(piQd2??;-=!yw?FS#+*mHd6A{fhtQ?g#tH?6s_ z9nP74|H2CvwO_cVN&iw-%CMq17wtUOv+==$?bw!}6ITg>bR*`#0Bc%xD3HZq!UWfY zUm=r?fU0xkgpEC5K;T1yxHn+mQlJOyDS`obP!UHt9?NOL`16oCihGv2qj8;1_O;-W z8rSw6mx!xwEwca4n4YohAy%^C^Q((4*y*;57FYQ^|DwV0-4p-qW&O#C;T_W73wpP< zY`Hnh=HX-9I{A00LwXB5QJ%0|rC)X-!ihyz2K8uRdLApl5sFht&gLO2)|}Rtj*@zS zuwcVa6AA&D_s@nxAayitytJd^=!V9|4M#gVF5TF4GAqyqkbppDW&juiZJ513T>RXD zhK2*rU3~bP^!d%hn~(QrW%VE59QnjJ8Emft`?d52B%!XSO$xSMH0hcRDgtmH!Z>9& z#G7%a4OeK!&rwI_;gAvK1QB47;e9a!BZaYF$H17JhBiX$zHajG;(O9hV52M*E<9=H z%&t1MsVF5LXatwRMil{MCEW&GiY8dEGgKHOMl=<+ae(bbdQfN|QDc;WmRs=Z#a?%+ z6MF~Q7*z-nSRPgXN}?6kxCkPuIrg6UgUb#1~GI@T`fE*aR@(Q)2DNzal{sIYfibMw~T!sa7GZT?!M-pi@=w+)G} z_cWvjd`_n?klxS}ejww5C9T_f^7DJPwJy0JBXehO&DsvXzhiAp?@rp!;2p&GF^7f1 zK**Saz2k>x9Z!Nmr_q6<%J~T*BB)MD!^u?<+Zv9#pfeQjF!eJ)7m@HX-D*L4p+Z)` z{Yi*2y6NU&6iGw87nxSc2uhc{Sxh9PZ1M4o?1_D53)6cVic)*(%NH0ETUQzCm+owA z+1X#5Ti2EIg1a^2evfN=qXmh9b8_2S=lNRO8|%wWj?QfzIr&|io2yqYS>XSf!Gx`W z_gap<@jT8*iSVURVvzz6a%8$voD9(gkt-q>cw$JwOHhi4fKj<9t~$cujj)~w7RElI zb8`-r#|WR%JJqQMqtIY_qn$^(L@n$YgVmqo@OwR60wtp_nd2ifLOf_5B}F8brwQyR z9Wia5)h&LpH27|IdLU)~jxJwd`GL;jMeTJd)yXc4+h6UYnM=-VDy$Ff=w&ZSm--4` zQ8a~p+go}sS`na}vkOujsSamxOMXs$QA%nyd!Nq}(ULc@{&m9PkRbsMF-V>zMQ>4f z4`GdEiPDL4qKm1C(C+QrVU_mC9F@jstI%1+h5!>3?JUv-N--7s9E+o+agpU7oxktJtWq<<=JD z27T7iJ)`S7>jV9Xiq2$D7N4i>;%{43xpvH%x^-F8jzuND_O-QMlgXJ-ke``W5X|VB z&kiGfXmd+rwGsKmB#d7a*5aR+F;59NDcvWLWQij^()*`Sxh#M_fcy~e&G*kJ(GEwH zWK31zL94@GEAr?1xS!k%KrCzZnXu@Xej3f{WOCveK;>e<-@-?LA{`eY4)4+g;_1ZM zP=GnPHe|#RmZ70iPd#mRC%9J$w3A+Pl;0#+bubXFkP~Yt@19Z2OF#vYg8>;uG~h50 zyaJaE^sW#UWEML7s*?j8b`Y;!${57pk0d$#f#^%NY(?aO#U)$VSHH@}SW!waBfNRN z+5X2r+AS-^O%u0c?r?~J6(hcaF((VP>WQ>qy5Vd)fOL&7NMfyp2~oNjB`%E?b{_`LJ+UHgtu8Con-TrkHJr9 zp0t?A*PVNLz@I7;PH!b5*3V)!nzL+%+%%n>7;Nr!W)>)~=-l?o@hvN|_2~w0@akK? z*g^JZ^d;^=Up}Q0eQT9Upr6tC8D+c0#Zn8#r4@81wIH}6d`oieiUt3TviHNu{J-~h z?H*^V@elQNx4d5*(bOUk5su`T=@NOPn4o+OR*6u^fLj>GjER@H^ za^+$8IYzMKIGqj<-UfctxFw`SXKFw$TiCM8WiyP+-l%Kx~GZj5)v=NposSMtVwSY9{um27A+0mAqux*K5mK3#~05sA7Jw$^8r6u`VyTFy7p8Yx&Tl18u@!_Hef=KBC|orXn0%N z4*XBr4r$ZH>RiB&nN(N-k~Y5PwO|eud0wj?{D5=u(`(K z&4KY$hL_&|D!l(2n&&}B%7xw0g`cJ*Ij90k0#8g0T(C5NnAJiF4m-{We`Ojj5f?A2 ziF@X*1-U6DC8a#2+?!+ZQm#vbHvNpW=k$#ps0hZRNbLG}d*9hD#(QaTN%TOJ_Sa@- zcr%vrJ#e4AO}vxSu5@8N*Iq?Pn2SDvp@VHtDlM!NsMyrDpFRUL1IokW~O`B z>~y%&9O=$<5INe*s-a>Qk+Z5hne79uOX0MxHZei=d3~pdOl@kJP4aYhmJY(j8u=P- z<7;S#47_6o_07TJf%?W-gb-Nksc0Jb3A!G>4PFuHW1o;%cH0sHNksx|hY1K%mNUX15ai1I1b&e*$W0xFE{QAlGRh>T>xaDdnyew*#dQQ zrI2Py-8F@f&T%tPunR6P3=&5Ur4$PqTfhSy3-jGsPCJyzbipAXc=Ups4HkDA!oR;| z3_EKl+Y^(lK+WCo5hXZqs`(x8OLnrni#32^-aIRN!|ZGh81DbxyLtJ$sh96r-|ea$ z2CHkVl_i|ZyMYjfzjIFSrsmvu9>`wBLW?k_u3PrhB@R3}tdbVe528~MYoG@#d?C4B z_~KMSA?hrpI+~TJuhk$=1JXG+HB?p<_{l(kP*Ia!3pOE@r6P_AalFAe_rDZ5Y|$8o z+3PIIUE+?kl2*UBp}O4BCGJcsZOzMRs4jajCXK}zvUq6LFP(Mn!uOti5Bz_QHx+it zuZoWf;t?iTfXuH^1Um=; ziFHH;1KcbF9R)2CyS8t0OZp+Rr?#-L)?+@D-m*o$vaoA?&|QmUDE?Y^aD7)Hf6k`x z1#D>Y8OYM$8I8DPEO_oL~0pW8ybwX5*;uJqv07HoC3jcP(}wUj4NbW zgz*5G<5bO;_l{~18tc4r(N*mz$hIbD7o^B{El+UyU3CHe0kC*zvzVZj4`aM1FkU|t zQCJty#Wh?%OX>z>yJ3PgImt`{rQn2jF<&0D?5(P3l1Z%aLWLyy3VVC{SMF@9A6>R+ zU`5r%`!90jmMbX^PoBrI!|CyRoR=TWuggioYn0%QIS09B1Ey$}T!Wufxd!hX=Mwo8 za?Pia^){R?>)|I=)}w)(fsg()vYrr_{EKp-Lio&@ClRw)R)~BUS|;UL5q=CJAxhMWhF%g`8id&RfIE^ z;!O5hy$L1*JOjvt;OD7&aTdH>EsT#Q(Mo3{<~y79og1e9h2`>^`r(GmLlsTU<%cp6 z|-rQV%FtdJGGeBPtRx~%EZvF5--#S0jr*UajLsL^j z)zU_fCMovYsgGj6#r_>`i2WA(w{#-*TkPN1QrJ@q!dK~nn)3yhPz%hCab(STNcf)c zp6F2#2g*Upw7Rv>M8URis$~}Ob)P6(-eZY!8#8FWhP2m%b)r5&-~ABNbzaT%9j*{> zV?6gZ<_^dc7IPz(tMC4sDHf}AMIqquii zqQ;UqA{eY@QEvcbEz(G>FeZySU22bzkdT%@N_xtQx=PR*1*6)xagM&N%&a%>iT4CS zZ#L*hlHodmu1zN63Z$Qoc?bzaK+HX-hX@IJLxO(ir+k(PB=uZhW5yHUTxDWL)5uxg zN(bqBIOKo$;h~|o-}?DafAI3d-+TCb&wk_XyY9H<(jylg7#bfMA02V!`wEL(IX2{o zV-AWBMJ{*JN@?&nxY1yfFb1C-^cKuGv!kv0Y>OyG#={Ci|#V0JGR)6#D`at#X@{^48t47@Z{em86sm46%m8TV&42! zGzgPC@fV$9j(L_P-Jeohmr~rCKhZcf@>#7C6y-Ml#%6kBS>uuEh4V~!VLnervnD}_ z%u}eWsL_^F=Hm0DeJxsqF|rv&AN>>XJvwVbiQ1!tnV;%WyfHx?qO8YkOplOgmMAX03PfUhu#;efhK8R~jnLj;aLHhH z3w9_rY!-f`t%6i{ut&JXJ9OG4pELY+vftJ$Hi>o3Hh{srTb7~GnKP|`N6NP~PrNws z68+3FbJD_Pa_cAGk}K-R0=B}G@NcX-Tcg-G@lumbpUg7K@&aS^r~Wg^Yh_tfGV!8V zPbJ~^00(q|s%QU1oDi4G*9bPkP=M&o!EbpgFuHo_wN=alXMU1IOe368!MWjl)bnUb z_!EAzVpAdzC<7}s+S1`81JZ)7T8q<}?(q3-Rq1VG{ls4@!fU`?{Wfq{4X`#OgX%X@ zY^x6-Q2^Ub&>`QlL2uXt?^viZA-#=glYkztTLEx+-AGR&BL9KZzrqNRRm2u2CK>@$ zMi>DYOGQa>M!GA_W=%{^1k+$N8)4}IEr&0O1=Fvl6!EFpWT_$$o}0+zn^&cJ#YAj+ z2-oF~G;Tn=@a!T#UUETS&K+Me?|u2@y`5XyJtwZ+|H!Ut_q+}B?zpq<@Us_anaj}{ zzL;H1pSSwj*VK+34kxg`g%jkBVJG`TI7Rk14+SnbPq{@7u06h_YTdv*d*(gIR@}I~ z{#(|J_mx}ju#&=_+i=*Qw97CrZ6RR#z~aTa0lFlr2AGf;+m0*>>##7~sAC834ZH-> z1`>J=d2fh9AEDG(X?+;%G8|_X?*4!JR^86<$r84IXPxHOZ`JPn$3Jwz9d!Z=+sJOj zpV=8of+hplJ}^;<-9Y(?eQwlfMHV1c#KCh>I|ele{H#UY7eL2>VF=L#Zf8mOvWR9`@I*UU_2Ghd5@+i0#S^52>#AnOL`27Z^} z*${CJ;r_$i(`;Pn&G!eZ{PXhX(H7!KH)9-x$b_FaOLZfiVbsdE&+4!BT-;o2>Klkp zM18oTK3%hXxuoNBzPLE`-U+yY>Ow&sS+qbtN$3~YI6!C={2_@%E4bZaT<%ST4|s;l zoS&Ev%|?R5riE)4ps6xNM7zV|IAA%`%gUYMcT06CE|+1i^yrB>UQ50s{LgwL;a`uH z6-}&0vI2R|*T6}St{?K{3iCqb;RxkEj(@in>j-Zc7O}%&HL;MA6kW*TA|}+=7IhSN zsJ#x?VKHunY>Ej0@;JabAwP3+DHFLwF{!69 zO|l&ITW_fE?yMhb7%D09S!{WFN+;|9K2u~$G+H~s98e$te0oY?OrLgSQGs?iIN_Nl zOS&T24rVg3KTzMf4t^|Pt#b=%b8Q-9an^$5^6o8gom*HiFx0Wc*Rd(oxOGX;z`S!z zoOHe<8j_6FjV;Zcz3ecX-<1(8NXyJGNN}1=-rBY8zLG^dnwD)%b&jpAT-D~Msg+Xa zp2b)iLH;Ba!m$v!h=bQsEo!9S^XU~G6l)+|B4Ppn@-J>g;3MdmhONV%)2>9+9z`64 z@@7>;-JS7j4u`T*xW|bv$61k5L4GG-NT56hHv+#CBj}+Xn~@G3!n868PZywH71c}B=9o;ehTRO<$?zNE=)^56E#$9aUN3K%d$y*} zV+qioK0%UV+(BUC33dc~EaI6~0^b|5e2jyMg%w{*90{rYM7pwh@-FUTq(dGK-MEgV zUz+5zx8gfDrWJw7oxRn}XPrZX8IK`xGr6p^siCyHtlNupOnz^Yfqb44yZDsOirYbPbg{!-lP&=%5e=Mi7Dq!SxcaGrvGOi!0O z*BX;QJ_*Gdpsi~tIjQQJAN36+z^0(}4EtK{&Z+a;9sc?pa;hJ^?e^@-q;Hj1BOz&b z*9C*6#a$~)a#}LKLSK*A(uH{dl9BGe&xo-K>4Ps67>WT zpj#)}X1XG%UrUI*j{EyUE0D=!6!)%?)cZMNgMdqR^!ld!2eI49cSaUv zanHgu)hF52*H1pll^$;ZKFRNfnhSfkHaBnUEewU0^pp&o*U_$g`;gkYa*%w;tel5+n-*ZX-3oIPABgPGkr` zn&$J>>n2ngw}C*>5DJ4kH8n%V0M&CGw*hYk7tvs~-`_s3dQotZzsg_bNFgD?NG#J? zgoGJP^qB~q=Do8@45#jh;j`!3pl1~y*pW}ih{x_rl0th!U5-S+-4pS{nHM#?iSYr$ zv>Tfh9+FH81vuO%DP1}kql|PjWQ)Rl0=hQ4%&xRltD0fbW}Gc!xMKy5GtHH?FnktVNLC>|jk;xDTm9kIZx)i_wsY)@(Ch!N5 zqP$CeT@l2Su8z9F`oW^wA^@$GmraW)CQkp(NlZDXouwQ)Cz<6`?4-`MyUtO5kqSTS z{MJE5Ix0LENLnNn_0Vjh%MQTo&LL@D}xTeG<-h4Qe+TB%Ozig;$w0pF^v%b@jstQdB&@_Dp zq3N8KPCoXjC8+S1V~)dI%lKKODQ5q4YdTH4Nw&%nLc-S2rYwY@Y9jJg0%$GLI5JAq zf_#p`PS~VH#4H%b%}j4njF9y8!a7`jVl>p$m+Rz`Q)NYN$QN?vIFaus-8EZ+N<6a! zb#4=X%jx3ODbqR5Y+TVw-0h8A%%K(}>L++B{;dITGaAQ@QR(b6^?|!H+6T#MpQ#V9 z)6qWYvj0qdOpPPdI(sSv%#*02(@zt!bJm1FZ8jydMmvE-h|ut+#?sQ>?#5+J%Sszc z8ywDvXvnk2o}*}(doEXU^HY$yxQQCgk2 z=^U5p+(lQm?$fQXJw{1RXLaVx;S#~Ic<5_cAC(8s`VVFOTK-!0L(t!tdRXNN_SOx zxKG$3{3B%SY=P~aB6MjdlU!Vb8%oyi#tp{9j)8zKVmFe2hAgpQLx8d{EiA)Dg!I!Y zBNAa_=5CJ`Q3*QQQIw5|+Ynqg(oliMEA;rCGn+$a1OF4^f83X3J|Ve(33B$`8Zy*_%P)jRa_Tz43=6v5P)b4c zHz2u^1fUE_!cimfUHwxFiWQw*SExF+1q4;Smgzy|;-*E$++2l!@OU_kUSrL3eo42BMf;X2&~_qL&-_3Q;JMFx+UUR-_a*FY#f);}LePc&~Jl`#(_LGIfkF=3$IWvAO99BA$T#ryBmFN_O=b!Ki0@WM3XB>>|** zp2ET&`s^y)m0DPv?XD|KO)ac*XV(^{ieH{C?k+6s9<6iZSJZN6tF(;&-R6 zQ{GxXctL)1A%);#{FU;382_)~pWGHQ02Bn)aQuTSU3J&Ts!_ZxIWmd-RbqT-XxeEE zqR>Bl(vzG+J~S3Q48Ry(qRl{0ZMg986}`88;q!0(XZP`oE^LzjlAN1q9b9qU-AOJF zI3@mm*GfN7UILet9m>#?juMXqyG0WQWHvli>`l)1aQ_?%0f5~V{zqg<3P?YA>p#1W zU38$S;lSa`dvE*v=arYxahlh9wKX?0d5~sD6eync9nCLy2}6o$mBFO=GDg_}1A_ zt?Li}#;jq<4r92?l97{K*x#7r&T}Wzp9}e){5>efa>TCBQQo(V`(DK z0lFmOVz>tm=_zMD2brqz9F2_B<$4|^L-=wq9po9wD5=k}JO64* zLP!9fgLwD-nkuPJ=MeLRhk=>+OPGzG!F%c+7uaLJQ~};aAw^Rq-m7!)cm8x^LA0fl z(lzHXO5FA{x7YIC#rCws@V~DUOD2A-a~K@q_Z2hC3ZK}5+h9A+!S^)};vAF+t?+r^ zvE5nN=J1QaULR2dzha}j`9bi_s4?RlphZl)H%>uwV^u&6<%^B`=GH41TBbM9RNVL3 z;=ay&I&M9C;8(n3V?^Ya#ggfFrXV5^U8KzVj(J*#J@`E4iFhoYM~=r{fJi`Kkl|oA z2s@^NRIswr2Ml4{Hk3zhHd@u}05-l^TF*Y_i6{6rs+l#c*~1KfNby~gun2qSRqYQW zV{KR0)CNWoqgw^%4BS8z?X`t`5Yx{59+XD(oL@zueP4{2M29^uGdVdk&+f?2N@ib9 z&h$H?!*=*HlP4aaU8r5@$fFt0Lv$Y1&UeoG{?jcukE?Ia89%Q%8TAOwFEjsV4l5#B|%mzXx#&zi0Cl!zqB$^8qZU z*kjX{hu`HS$xt-?Gf(e_siiT=pBG=$JdL^a2@6%VA)=$92|!dCao5-n8feueeo7F5 zOR@2@3x-2>8Jy6xY8&+7o|LECTDzh%@o>e38B4~ zu++D|`t|{nLvyhLY*4LovDRT!o|z5(iVR3hXHZTk1_l3*4|#N;+zXfo|jaGPG3UIUK}OQlT>|CORdZc0wRFV2#9UO7QuTi#Rr^viGLB0V;4o~PWZh;@nS>18#840Qbt+s zV?Pn1AT@|$i3B%nDgCdRQc_Z)l<|T3SqPn6n=#RNKXTX@ckiD5_kO*_h&$s1t3pfc zO~jCaZvy@aY+e(rd~f(i($a8#5BnMIB__NVegHSGOUM**Lmn6A8}@6JV`ZZ~sKHT& zHX|`5P!foFRlqtCheN!o8j8VX+&pj$ELlmgWjX`FgzSJXp=M=EPI_f$abQ(ex~Tt& zPOlA>rxbZ?u8fK{U*5cm^bBXKq9eRz&R z3h`r&S@a1H&4(l?yfC>0d5v|CGxpekdS9{dpC_-AUCJ+U{(zf9;glRV2Ya7!PE?QA zr8^stH&1zaDnd*+$LFbM%k1?T3*_@`+1aDjnW-AP%ZYWoak5G}D!+jKEO6LXFJiVu zZHjY%unKA~o-%t>f_oXy(a_w`oB)a19GR0v8i&-V>*ja3 z{|t2~ruuEod#Lk}P=pKx8sX$rKXs9Q`ZW%m!93J?{7lc9{2S`L%AfV%Ys*Ud zSexdw|2Dz=clBSa#whmSvsxse2WC3 zvpgcy*F_orX*3&7!E<8DXK*>3+Xu`ExP7470Ju97Armt>eeT#5pTpr7{~6J3!k6=C z?b9)C*n+*ZKf%|FZ)zWpthE*E7&)`ppH_7pg&z5z(j6MgajF%X)m)QYumU|=N0%lg zUEpuX@m=_@Q#>wUv_+|J_~~iE-j3Vd?(UHmpL&G;(_FRhequGSc6W!z#PyRmLw?Xa ziKQzmR48I0D6W6|ovxd1eEgkvx^BB|y523k9vqT^Jw-V=onq>ZH+8-9c6jWz+q&O* z2mSqKA}ksvpHu7ce9Sxqf{oqQ{r214;kRx??Jn#{^TdQ0{C}u>4*;pEs}KC$S7v5s zw$1L&&i38eUf2T5?gC30x-==GG)1}vq^eP|pg}Ak#4c)xh$R*ju%Qwa)L1@ai^jzG zrC8GQY19}aJ8%BKbMAX@$}VLg-}nFjO>}q9yZxSf@9D=X2lfo@p}Cq4wd1$rZ@(So zemDM>TX35yubOr0tmqGc&4?W--3MtMu$LNy1TsDbJAu$TSkOe#!K^1MDIPxV-(&$r z2PgiJVd`Ej>o}pdZX9J67*|(&LI>`$=EjbW#^!eO_w}Ru6&CgzU0*k%qPV2w62Nu z0qEvWV%O(f%j(k0%typK`bII~T-iT5TZ*O(x+h6gvYKDZ+4zXSYWOc~2mBnpv zecApL1gIx~yp9*ekgSeBVQm}6oadvrn>(yyh2*G`Gr|jWQt7lq6JrE zG^by>2(^I@Tl7=Z6$n{Ld0NnTC9e|51rV2~(ICjBhlMZ&6qZ2M&1{stA|i5`+a_ZUDkAo-9R5AUP217o~tNxlcpX2=S)ulZm*30`w`W%$uf( zWyVh^WkDPrJIcK2B(Y4c#}(@Jt_9q0L%5bgHZb9h^GlPLw;Sdxlvox8CzeH=kTD2^ zOrWP}et*IRq#BEmN1-6UiAL3wPk9wSw(h&Iey#et@i2}>5d!Jbo+@(*k06f1nmD+^ z$lj*D9ywq284sJkIrkA1yj?HTKXjc8T!DX2iU$cJ@VbzfBm4QBm7PUWP*H{GiB;GQ zL;ujMyxIKe&5)bEv10$Hvk&pj;ijDT@N|^4va3a z`u*M!>o!Nf(0^k*pt#hL2Wf}%cWXR-;?7StLY8Zw*MKl3iJmn*t46s~yJZU_nyhP`3mtA^$roa|`ae^_r$oalzP8>Y}7PE9P|Vv^1pC8h7P=4|x}4 zdgd+LaPYl^q$}D(U3Z~-Id9iY%zK0oGQdDElmRPLl4%M=x#$Ohl|H@<7ciog;fLPs zt3g&i6q%q6iy#BkEhO!i{VO@bDzgx&lU6G&RrPwYTpo{YnhEC%THIE91+lnP7gyZE z2}i0L?n}+06eN@LdupJ2cThhQK{7%aF+4nM=#as@_<_o*Tr!-Atv@L(J=i{L_@u+`nl_Ji z4*D7JKtD9r;;yby`pc+NX}GT}5fozDAmlsfMgYL3(|duBcrXqf@jY3bBNmhVEIy={ z7?4$3kKkTXuoSE>%`#FTf`XU{@rm#ke@*+OfN=hsWkNPfAD zLH1i|W!;HJqfaAWQ8{8QRU=b541JYd(Rpbj&dGr=tHb z+EBhxxmvE4w;lm#QrVsY@hasXKqtax3R8j8j?C{W%zK~`LMRO~!*b7pLKetPstbtv z1;ua<*B_=J(x}POKxY&N-Q$PkucERxliY)?z&QSYCcrA^m|oVjt@sy!El z2Q1G@^QL;6rmh%1@bppD(?Vrp`$5CldV;?)KU(j2RhaNnan9t%? zmoN-I#0XmK@pyb5Ul#E!l$VEO-!w4LRc(v(k!JXSIZPjU@F)7TySt`nyTqS&?BMnO z9@;NP`xWH<3H7!i;4ul&H?9>GXH{xNh}lb-1%oMGRAh6iC@=SCg({J09ZpWg4I%^q z9nx*XR|PQ#uu#yeVR6Wh03-(g9@2}=jbq08{`l6H@gR<&&O#&hnf2=+$&=xsv5C-&LzuZN{9AL-Akl)<~ zDzuINi=^>oN$o-?;1zVubFY(0&U_6Zo>z$>AU ze#Rmh<^uUxx4j6qQ&OypjNQQ8Vlc4?DNX_0?E=_+Rz2eTtf!EP$)9Op&s!@x5ERUj zi9vEo(z4g4j@!Yhm?rc|cOey1bNR^DtDbPuFlEf1Lg(%RbCWs`W6V<~Bg!Pax$v6O z`NF8A;A#;^Kec^;X;l0HR5-{^I(;}os%n3q^;A_TVN@)+V_9xG5CqX4o*g;v=G4Nb zP^cxzc{O_+{9fDIN3IxMV3slcm7Cp7ElU8?CP2ffgA(btw$ug27S*L^sP;C`!5dUt^MtNM?;3` z*L!^HJ-+Pq*}?;Q7->3zEXp^VYmL#y zBY@);L;080`z0Ll)^-~&I`BQ(9)^Pq(`OpDD>Y)5_y~u9@(ka>d1ysK9@#n3Z;g{= zIkgQf*Pz_j>hmc7fJRSh3b>c}yuDPuwa4-gsox!<{Inj+KTM=zkL{1|vHT;d*+co6 z7|(FyE}ExG5}6wDfRfGQe@KIbzFYfLerAv5AJI~KC_ftI&%&EQ?O)05Kd4l4`;TbF zvV1~b;n^s^)+!I%Bh-5cya%o4!x}}MNnTGXzoy6Xk7zYLls^^a6VmD}G5({gJ6 z5mibts<4G;}h^d*-BWMFA4ZEyaRmCa>h7TlF0OQ{3M)7Peu(4o)LZtR-Qc+ z1%+gngj8hMkU;}#1Ca0$)gY40fgo(h$)d8|{^?{q)={x_l6^iu_YS3W4Mn zl_y-eZ_T;;)}L^~`hDlF*>~j$>U*W9w$55Kvi-J$k1bg8jL^4j6UH-3W^Vs@V|H~( zcE7q{Nlu!PZm4gpf9Lv1ldgYf{rY#WKk>xt-#xf7SUh<|``jvH#eU)0wq2yXxNO;r z=2zQqjy(6h3}0zgpSNa%+=lWkV6$v{N_WR71myMDeK z|Lp$-{@JlZyuRtuP3pkNEBIml3f-fBC>W9Bbt@$8!^1<<@t_t%tOwH*kX2UdG##X= zTNevKrY>amG;Saz3f!ZSu`?Uq(S}4^cr#K zr^VcSlX1^iHDTq%TW-4PmWeATREe&V(^_XP8r^=@{pSxGb?IX(Ry=me$o9oI%*n1P z%jsKhVV(GH_U8HhUwizC*ZVKn(sdPM-09WEq^q7i_j~)V9zXu-{oh-+jJNpqs;KzYsP@5p`fg|quMsVVNE<*LglPD=&Vi!9|5IUC6r zmz>T^B=jVPsqW$$(pLul3 zxGTrc9Ci8LHEUnrGI_%2Q>*n|`s}__29;@BexD-GKhoC_UwI1F{Q%ZI9q-DW;oQyv zs@KyeS5+}M#VAZCc`}iLw2DosKG1Ce#a=kSU5K$BO{!Fkg9`_;;XW@vK$#s(}=fh!V~0VIF%xFB#S9;=F5S? z#?cFu8|-OG6H}Xt?Q}8bWS(8^%}mT;8t_}Inj75X_hD7zlbY%|bZzPf@2grHpTATT zd3a@w>pwFZ8s(Y6(fSm3el=bloCjsU*b;eLQVfx|tuyoe=oi|X#x*!I8?byh70NdJ z6iT~!pVol;_*8g90#L~_ZNHc`p@MAYR9M3dc@BtBZzA)r*=H@imdhAniY=ALUizBM(|24jYS@Ll*DT#Jtl5*9o>AF0X~2ZllWOWGoil3q z^o}ZIIo&*TYIX!=B-){J__>@z98IA3Y)hC=ee8Ak1RX-{jG`+p=w9c~fy7F}5 zTw&&J-Uklh0c8xGyLwXb9Ob#gcJ%Jt#VRD9yDB<&fg_*07=P3)mM)k+%bQlyQZwm>ch_%t_xgz$Wqr#L)sD}=^yrs#kKyfs z^n%_e<&my8<@?n2rgf(Jq0AY$>#EgV-*K7fx82H|4w(h*OEr#xeCIYrc3bb&w=!GB^WsM1$G8&)DfQw_oOb-w_bFLKBMKT39d~^nHA!czAwi2CjJgdK=OCs+Yob| zwiDLH)Q~EF4>wC?b^t)FW40 zkz9=wZSBdu0rx=-;O0s071_vRa@Rs==#qwMSA=pz)e+UZTYXAT2|f%j45gN@El&Z} z<=iszlIWfzdkFh!@VgWL($@?b@zdpaMMe+1aL<~4Gizfx$?cTbcvmtqD%vLv7*FrY z#N{K0Paja374&ImPMtVr1KyD5H=dZ8u_Q5d{J!CcPfl;jb+fED1tu)YKoGJK;}Q4} z+#C)R7l8;$M~;^IG{p1iz-lo8OKaIgQKq0DfHK7cL8s3HrrS~kLxkdXYqQ7!aLEJ& z7WXYeB!h4t@-l}rrhES3YFfoveu*&*Xz$%GFAo(@9H}Tn#zH?+PAK0LVK~OG(QdmY{I`F5BVh}f&VFMk{7Us za#o(6*FJOjX_uR?*i^qsmNMY{Ad_-01&*g7)6FDNAUXQ{@Sr?M^V<+Ru6X`xh7=ROE~G158@jo`k+~(w-Z0$*MGn3`zs_9HXY$~R(_dZPm3Q82 za~I4Vv9j5??c56=^RNEtoX7euJY(6Q$ChuraNW}Cl(YexPF-?YQSRtd=J%U&$&982 z;{9FUTU$DK&frC*jc+v+*IjhM*ddeiSKn4<{z#0kEjCw)*E5T9(;|OVmHIX3Z7mgx ztIixfbM^d=DgEB8hK6&%W8Y;yp!;+;^Lqak4y1$q6N5`(#Z-njwWU#Y!F0gk zvJC}!D?D)OK(G~rQO0J1!S=zzCnmyKMu+B1#Ic;Ps{lI*F8e4d;hK__!r-#ImG}7& zzax>Ahg{6AgI&vloN{1W|Lm;FEO6Q6=^W#-iNtleYiz>Ey0YR=6-5XX>B{}rO&vDiRr{cw`>Mrp>uMG5C|o>RGuFPp@}*p@9CAKu_CxWP1vayy zOf}p%W)pVRVkPODx7#-YtKGnqpO99+G6mtai1~mZ5z!YR_g%<#-gC$giQlG0$WtZT zukBuzPl~L7`@t!X*N(iWg^tiv$<1>Wyg9Mg4?SRuGW)eO_VL5vF{`FLr`$)pJ8cQ* zA@GP;evqmN6B{S$z`;q}6)2DIY}vH9tTUMA%1duAZ<)~9oSl-DV(&&Eh`g=V<(QSV zq&QdC>d!ncJ>$y!)S`~5{qNUwDdRBA2gQSiycfl*xv(pZ{t|D+e%yO4%I)%9&h}s* zT3|W{CR?uz$!!P&swP7%OM{B;E78Nc)gNZvl9w!;-rUIR1zl++>CvTutwlg$X+VD* zX2D*sop$LdEtC3WyK>Xg>Z?zlk+4#G{At!o1v1s!rfrzl=FgrKOv^ZP=}%(Ibdz{N zE)!y1Lk0oaM6NLuFc?)gF4#!HaFB) z`2Dq65DT$H2<$KLsVyFN+5iAW0;&a4OtO4PShkp+Ld$KsV)O-<$1Tl8nYs7XX#xLi zm|gxlVF8EsEvhRCc+!0n8~Sdz6k;#NC;d;^Ib#E2U`DpN<8t$5XDROv4@I^BKjtfx zGjZn6*ZzqZ!KZ{zYN9y!B>^zF1(>r28wHr`l3x+*77Z5>be32X2nuC7v6O6Tf%_0X zN3)^nM~dx!eX}bAxezesRI|MWS)0%lL3-JW01eY7MUCK-X1Sum6A}g(+WBd|FEfkN zGKz9DF3D>i+fp~F;uEz#Vx*>uKt(}DNq*+FCGC@1>QAhEG4fmWbM1lb$~5yim&cbI z$|dPxuHSrjhOJ%qV-VUYc7Mi3oPihDc!&02JeUc{LHvRsYl$7ap5tQ0S}@OOdH(} z1)DnF3*#f$$!Nw(Wa2asOWU;^_S=fGa02`)T(}t(WPuD19n#sirMVGJ)cNZ>Lq4*m z2Z<2OX3sW>xcCc%gN4O#7q8K(Yar>-Tonf4bvy)~y@#mW_4*m*u5%2JVffr@wd}Nh zWv&a-JbH?;N(-bdd~<={b9ssj17GjXh2cgrX#SyU!ye_9GIMo)Q!v<+FK$fFC^47! ztIO?^FSexnBWLG{M@q^vOa12byiL~MrDcBpo9h)ca=ja<-im&8fyO-M*USl`A^M!; z*Z%!G$*=wUcMjex#`h-v4t}lscXOqhhUf=daGWMY_5l^qW_K9QBL6zB~( z`+9e$MfE@rK8jnryCkB?x#q3vf#^0Rlls6t0Ye;Mpt>5574D3Q{s!p`f%}f^9nukM zoh=^J1C~XD;n6S7E`Uvgc`Ms17+xI~3*ghy_NC^X>fO-?Af2uZBQFb?`|~qSUPfs9 zm{K2_clMC_5PhvMUsRvOJo1&3ChV#Poq|NCuu{iM5=)4!vab5b39}RPWs;+)(PO?$ zVUAaOOqcz(BIzT2fginrUuQ2S3{e6~n#&EE#2iMr1uxtq-S&A#(@0IZ2 zLEyntzym}Kq0L99Dws7(FPWGClbkN&9nFR!0p`TB5))vaIj&*+{8;|W`Quq$6M4*) zqE2$3saA_FOc&Bv%=(woZ}OM6Os5UL9d8?_g73uJY1}980OLM+2N3lf`Llj?^he-a z-85Q2$nRr5+Dk}{L}rg<;m40ZUPArqgBQ@h=E|$YlUL!5dfqhD`O&8}w=i*+oFm_; zf1l&rHMheAacOi9#sRC7f1hdHMQ1wScbGz57~PNWuvYr_)zmzY#vrb+9dP+O)EPQ(EfAm-=0PS7xv@P~R{e(#QiEELOieL){cPcS81< z_Okw!+5Ys7EZAt27gU#euQ9epE>|zZ9()h_^Vf7Yh7e)LD^6?^8mZY5AZs;VTSk!Qp zl@u4|lQBnnn$H6l&N5M!=#D6vcMy`c8Wt1H6@Ra75LcB9nAGgc@$O0SdnT*bmJT?v zDLc3)Q|s)*=T}uDqqGc7pGAk+P#YubTr`LB=ojkKt`^MUV#0OUq3nmZD}032T~9C) zM5B>~`bP5$yhCo~!LHw7hNu@wb$O$z8__D2hisUs>Kmgsa=C|XSmXA;5S z*GDOjts8P&yS@G>x7(c$*rN_CR&JLAYj(=*c3_kBN20eF*P!lW4y?b+6MfqCC%_(e zV8iv>qdzj%0``Oh>+8ymKI-}suqPeZRQ;{!7WksOm8TroELU6fD%Uo^_Byb+`ljd= zJddXx*eLXS2Yh1P$}Ki+#<$TMT_#|yHq6{??uh0?Kjs!=BWywh+;|JH zIj|jZ8=u(aB9EH)M8m)>xACcjA@|mr=zU_7UIY3DzULI5$VaD#e9xDY4(f2e=fC#% zFP@?<&1@{28YrvM!zC5ycc^(o^lrRMZdbn3?@;qrz_4$wfCHOr-Wk0D^aM_<1DkBV z2;X%o7j$4#&F`XHU^nA7KDJ?II+B|G9d@X0V?Z2iDPa2m8|c7V^p(hvw-c~IHZ1b0 zzS4YvVVw@l!Chmp1KXl6iEiRPhB&Z`0K1T3Lmk*TfIaSd9(@dRU{?dz*6~=v4(tNJ z&SlsL2X+o%vhHvj*7dEvD*7>xZ)6X!Q8p~X=ZO0qZNtpB%nPE=A!oGP7-xcy#6LpW z4*ug!;E+$L4Oe*~W#xo=5X-?S6kg1vtCzm2NZ1+5VrNj;^7sW7v%Y5+xflKl-19wo|EX&>M$rJ5@@3lK zr~Zo#CBd$b;YdmC!?InS!*>&?4`dnEV3Q=qli(+A-N^};Ln+XzcLdwiIX^J(oo6q0 z^I~hQ(H8F`M{z>@q!h{q0{R~8A}BCQ1slJa$gNc&849#YBD5N$VCLQYI#6DeV_r8; zj1&ztWc}&)!HthvY(MI*=JK4ptW5Rlk&(|-AB-+y{iRcX z6xi#q{iQ4EiFirfi7MLMgMmV;x3MBfv(nD{C{yIx>|?8XEuUHJ1+QN!aSXl`PmlPC)*bv59o%+MBB<~gv|!7> zptfNj*$fVfmg};2weu6&_fh*tf&U43bPKh;!qE6K>!)5wEw42^<}!U8tq;_6y}fTF z9^G)2eLcR=H*z;tg4_BJ;n8QVn*97~m$~ICoY#8Z**7Ei2a1XU+ADp#KG8Cviv3UZ zN1O0RPgT(BZ?Gug{xox0cAo5SzxYaA5ZB*v<1H>!tGCJ6eC)c~@_tbEb;DoOUGZ}} zPQ10cS@X%)3mo3udw&ly^7dPUN?k{-JhDcYqbpmAe=l4YyCRy&ho!e!_}fW z!%sUCeoKEAO=GR*^b)VyAcy4p=?5D>qb55IcU9MKwUey2EWCmo2@Dp_7oIWse1R=f zBr$Thd+8ISwy>bqFt=k)GBq{(fy^)tPg@ z0#B`8rbBa!UHRMlLD|LZPZ1+Ge$BiJVrqd&b~XmM#EKQUIbOvJAqlCu@#s4jt2x?g ze(_h-x@@}C$i~=L^%8&l?ixe^oAZP3=84(Vmj3jw7l{^FAIP?Ny;Di<1{u0Tb0$$h zsY;3^QYG3%)QDhvYlz9&FU{@q#A=aUB$3DPn?GA5MhibABysJh(;B1^(T0fHKu{Le z#;9d1G~6e64J!O8vU!_ce&2jfb`YbP4f7A&2T{(v9v04^kMu+KfkV)}51Z~hV7?tW*fg-YS)3xqO5}P!xIvT>?Q8Q& zd{5i_jHG>$9>($umS=z{fFy3oCQ_MQ@|SpRBDHiwx{nCd-nM^uj;Y!qRA+3+lSC@x zZ|~+1>m!k?VXmp5#wJ*A-cXdw#46Lly`?dN{1#X|4N>ijew|3KA1kd|gPqE(Bs z1+fRsVi<2L)2e5`F{O%?dR}wAPlRgk+fJZU?=)|j zCst-irn{fILJUFEseYSIJzjnX+}VXA%tb_+6Ypf*rN_(f(0gyO2GwE!t%}BUYIcTt z&4@@u>&JBJf2KeC-B0ANG^SH!e}8~mHPNYdf5(Wk{5&&%h4(*^zalzS_Vv=&l1{bz zItHBOetP1s#3h{vstou0=s=eob96HtFe+FnT zv_$TvfyVPA^lmaA-4nreBtq4q+2J|B2*rdd5$-Krrrt65`1>J5>ds)POsL9!KGiZn zsPfxj^9Yg_==Gdzq_yTWL?HGDt_~(vWnTxxS0Gjs`jT`M%LRH`zrz!(iHsEpR@u!B zeKw#(c&bIj$ln-sASV~L9p`pfv3HD=QK&P{`FD;mvPXnW6eb))C&`2 zBxy&WS<@76jApF>QQ0~aS-FX5jhfpp1SB)q_K|ejRy<`;g+^xPCH;mdrRL-I}Rn#`+=Jn5N+nlkb~9vpR~ST)mM$ za91|v8k^H`_4TUxq1{)Ea_tw1a9=Swu)Ti0=nKzX(!8EGKe76XQLhWlH15hKU$KVA z!V3}oWb;CxG!}!#VR;zZ;x@@-JZ6FcXqwuuC_uhg?!a5WJHa zXP@pQk}^EUq05u${=@J^#Jf~Fd=W`~ZN`Ym zXmCbj#0={SgSdBtI-?bMV7Gs)d>7#X$mST|MI`eEn5Y7i3D1(-XTJWBcoySZY)uv8 z*;D4jVs&}ICTUAI1euzRZ~y3cyIA{)e38^vS$9c46|7e_6Sc?B7ZC-%_}7WF_fgY) zNiuxMd<;I}L>Wj`Or;o4TPi79QpZHK`ApCDnkVYsR|+d|F~)mEI0sn@g~ z5gjCGwOEE?_*fJAF#XB|y_u#jB>L5UJCB2=?9O;e`c*OxU0Oeze*F*hMOd21bV>SE z_64PuO~2ZG9T)wY$Z&yvmEFAfPf5SpeH<(OYBetvS+eP^HvQUbU64h;{tk8*+EsFQ=2d8jm(wkS0XDd8-;(G zyJZg!_4?anQJ`h`ic3X>?B6HiZ8nka5pyPN@vfW&++v23-fKO zuNdW;(e)|!WmB%l*cTHQ@$-7a{8084qg>m&Ozz5}Tzh{v`GHSFx7z%WrkaaJsuv{4 zG^CF85Hx{7&u zyKOJM`6-9MU1-ScH{VaV+rbplL24LjL{H)S^}LU$*-<)tM@U|5w|iWC)>r0T=po0_ zY^m1}pEb(Q`h2^6Np~G-KVd)AjrXx^aHMuCrzl2dL%BuW#At21FG;^1sW0$!PG8A< zkJNJI6xjw`{Z#0l}!`deH;&O1$r1goGebD84xiHot8}pC%1pJyp`mAtbLES0<2~uKoG6H=X*f2 zCg_78#a+zguWZYbXF$FrZHW#cGwjZUNQQ?_1Ei>bVqOtBKp{%`$GqE~I6;K+1c z_dX<}(~YT;)GGB6RkZm`to|qZi7`|yVkpf;QmV{db{witI(X&qd!_b1y(n7JO#EWm#5iP`zeyknzSWz-hf zBg^BGw8WIyC9A_tyh%fxV*sVl*jpSLiNA zlY&1#Cfu@l9`PLOfY^S^=Jk(>CN&IZdc@gu>k&8R}hh$e-%H<2b^ znm2)+a;Mo;>3fmO(Xh|UWGV309`|wKZ4xhqGq;uWBH2kcw?|Dc#_%Y1&(dVfKbg;9 zHefXz>eNzVWlQQbHlL$DBTir4a45z{IRas@Q9Ln=JjMEf7VZ@ewI%U2exF8B4!;Z<-j(*Zu_MWPh;7iQ5cYzne3r8IYbD9 zALtYdc)OVj-k^T~QVHvIobA&r5;-PG0dLT5CgS%$(taYxBq?8TOhoj?+P8h04!J%F z7Jx+dlA?=-FS#Yl0uU50m?b)6hyk$KG^6>hneaF!U%EN)!bJ4QIpl>YBHu>uQ$6r0 zMSf4paUW&xRsREd^vYe`5bMMuW#8I$mnc*mQ&7cTfTOx%Qc$)H?8*Y z_aFK1|FDmzC`asq$BYM57c!EOpJ^Y&z$@2YM?B?+6h+3s6LB%{L`c0&`zOW7Q(ovP zMxL2st~FnY-UT1Um%DxkOd=oDp8Vu`@~7*;@6PPOKM%fr-TnBw`TJonLh9b=e`#Bl z0;ONL8T7t}jHlhB1R%jE64?dfbEk8zXeVScg@1C~@y#!67v9=2LkHwr4!m_^hIH5t zyzsVFI*hQySH`MJv{6pv;XKfes0ep@~H8TXvkd**n2k2RLon=PoftA z_L+n!qU%HBAIc5x3V05KM+9Tb`9gtkCxg=^CKb8A&`BE9`y(SRvn#@sr&S9D*#nJ@Izki8xnf;zeunw# zbD?toCh>3MOMy$a)SLTbOcU+?3hU8^c6|!9%jXHsmFf%xCZY4BibRd%1!GT!dMu^boSmXAqaf#sK%VRxbCVtJ zxDUU)<|?5ssbiX`H}|ENXu7zQ{aR=AGrb6R@3Y3D1N`D3CbRR zdp7;VwIKeqDcrxGHfkAl?C@!N|A=cUbqr53G83aB97K$Gv>8UMhi%+uZa5q0 ziT~3|FBKCL&lBQ3VP8WF%qFoUP>}wY2N0uZqFSJD5)_^&5WE;|{SD*GKwCZ~pK>Zm z+J?iAqq*c`1jNjsme!eyIt-2J8`CnbJ1-DKJ9lGDFFWn<8N#?I%K~C1B_1ETl|r4S zei=>jCd^L_8~v}#Nc)nfhqg|_m~^yNNax!+Ke*{s#7>ec*YgRI)3r~KP6NI57W8qk zJ@=(&qqE)CxbM3!BTX*DBaZ|FJcs4zw~G74JsV8n^CSCZr+K+$g-Stdbt`EOvl9=J z)iEEW)+*Y;OK1eQ+Oyn)j+ZWVwlgi`{`+~(fglZl?&7KX+UT9Gb(Ceb>lB$=HnJ4? zVL28?^sw1w`3<7_TdewHWS-Z^9lfl7r|U}eKkzvEm-WNP(EnV$3G=@XXA3bsqMU6O zIKPvDZ+vQz(Iq<#laJS!qKa&8T=D_y}+^crKo=yk;oWPBUYlr8>@f-q5bGQ!${eoE? zNP0YS>H%sJ4b(@2rdrhJSkrxFKI9iCW4AH9X`n@;T8_4~= z_RuW_Wu6U@OE$R5^KVgyyrkx+V+%&tOl^-m6Zu;~j+kxUmsNzmo$(nD%kcp_{uXVC zegLWq4^;F6-ekn<#vY6~+*tE@tOec1>N@0DAL(JN1vejQtmdu8D9#1MxF9|gS+O~| zi|sWQ@5QgZ`$rD^7YTcHmjnN00{qVo{KI&-$H77IkqxKuxNTgkQ5e^V%8nnGr^IRR zH+DV3={WfB65w`wZt-yfJl6lGHk|vnaj`~WTukoY8J}C(ZP(*7W$ig`Cg3*6dqhm4 z?{e=&I_mU%J>i`#z5TYD&@j(dKKh;h}`T(j6CF8l~KGyilG^6RJ^Y`$U{XekV%<1UYVT^ zD1?agp4Ht7#+8{B&R3Mm@{;1B!h*a&jz7Z<*e z)28vi5O+Sr2lU{5d^|^#oU+<*e<1DBo+*xwMyY@FC`-R6dFz z4his~7W@H%yPkL285S*yYk!{uA1L9`8Qe|`9=6&Un*<+mi1vpkw7=77e~<;IyJeIS zgLlT4clF}_H7`IrlqZbu24kE+7D>WihTH2#x#kJS5!Fb3kIqf{&g&QVeO%IaUdOoa z572jKJ!=eJ&)9dXe|!Bv1=0Ls-=j0Q{n&S2-?;B%lfLsh$9+%kpVvF~UEbY@@r89U z(J#WU$UBqobk~!@bPvl_)}y8h1ZutDQjc4{yU2A(mT_esL{QfLOm zdI#3J{(?8dKqlW4!xMz?xJiqS!z5IMTgI*FgK8$nL!?NUZk%bwwy&4OzdoQ6S5>d^sV%`p8KaOsd?r&3s)b(=MD`ecN5@pIK7sx29j-a^i9KXAt!*# zwQvGOnRm|tCM`lffC8Z)%5hU;LqWg7e)&Ov24fHs4~X3I8y z7(d;5PoFYxC49u4hBEZ7D_`)P_LTWuJly!$g3m=hoHRb8Zq9MPQ~ZF-OE}RL68@;T zqeuAe1US9RD9`Wm?ffoN&MWyYBPWuTd#8^wIy{0x*K2r^k@*~c3wSbD;(Qp02)Z1E zEHmt!m`conL?J{eCu^#T3-faEz8Xp&(Z@}P8Y(SL6DI8Zu7}89q~DvFI%(#?J-2u5 zS#X3*MWQzCq$R7D?icBIA37%yPIoP6j8i~k_>{1+C7jpZ0%Btz=Iuigk*a)%MoU3y zP~JPr7t(~w5BWh5Fr6rMff;K08f4yyr6EKv7ZOoH5>FW*Q31KSR`*!Txo#2x6Oe#MEDzo~EI z=fFH#3{J)4F za}hHa=SoRYrV3p~&CO^-Fs_<(_%`Mf?jv$;0>scLdM;&a8c3&GD9A43^LRZzFESx3 z9-lyBlav&`udw-EuZovXRhK0O)s;QdJxEUVx^FyV7-Xe zJLSZ2V}}i?s-u8+@G3tq4^`ge<``MYzk|1rLd@o{n)ddFou$VZzG zTBJSP8bTfnyn!yff-W7GkIJV7ArxU+2E~UJk$I(#(Cj&(+7P7Og$*J{b?Fr$yl_aC z?d}h;H~l_TMF{`ugs|<#^-G>H4{nS6Sp`vq^w_UZ`fP;iJeg8y|2a9NyZXj<^V@xA z7+cTyiTUmJ^>6=R;=%0`x4hjoI6l(5Tu1LEc*l9Yu#SD8!?4yj1y-mIe3S7FCO{Fj z6=OT#nMz0*79Q+ImObm8rv$A?d!kcUl$MgH{COFzVf*3;C?%+;o* zckxtt+Uo7A)$9KMH(t3PdIQr3KE~^Zl#lKGNPzE5fD_#y%Rj38J+6EVzB?Z7`qC-? zWCEOcIoZzMcsR?_B>b5KIGr=V>6}3-MRI|7`h(~v1d>DvNY8*dNXn?sr&9rCogn($ zFi6j)^id!{Ln$9;QwO8bQ02xU07}rmdV}b?PFn+QZd2slZQH;JFk^t;fT{W`#=}Yt z>fXtt_?x+#C1W%SDH#Kp>9|9VgJ^7P9MEIMkHdAeAnj zZM9TrjX18o{TI?GT5;{`ahJM1F86%O!8Z$pD(+H`N1KH(_lVs-!O5wFj1-08zA&kP zX%MKs!&U+U@@0%VadGZ}dh~cwocqurBizT3GUQfYK17UrbEb`~>K<{3Aomi5w<%im zjp&W~cPu+|A%^|M;nWg8y%s*?|FPv}bs*D?HAq1PmRu9cd@xWTWL1@OC-LLLOM}!u z6yqP#XUNYIEA&(rde`D2KQg58q2o+J9k_I1!yj^o+9c76^T))hXbpsfSigGp$Ktfe zeoU+Dx=x}>ztPsD5j7f#K5c$r9u$AQ^EUC(!5!NQrhxREtUsk?K{ht}HWP=_!DCOZ zgBRDv;maTgUZd<3Rmz9BQ}_;&IUqh{Q6t_T;{0K)5@-VoKVoylkDDS5+k$)3@nj@3o zLn1dZyeSDjRKlap3@5puY-gYe!UydPPJ)N6cKRg2M_BD3dbr+<81QHZB0og0HzB9P zI7e}LlDo?GJIzxGF5fekX~SW87JKvS`Myr$*Koh`N0wIr*Bp5T$r(m+88W*-<_EEp z+mvv+vnBkQ1US9(fCGOIh=&v3dHglkTx*Pk-JxCgWjydS&g8y!C$u@(DZf+P9V^dr zN;!tTR(ZUyMwrK(VU2kue)7A{c~X2zO}LUIPf#q(XRDJ2JPke36&$DrK_Z<*B?saX zlGwRNqN~y0D9{zvN(LH*zRk=}qACv8cRu&sot8MNzG-h0=DJ&8u5!--r+vU0@II{Q zwhy=)X+2~aey1@LyDrlqa{ZpP+cfWtFYn3~OQ}4a55VbsaCsx{d?di*&PM{=Iv?g{ zYKP_SvYlb_e9*Z;c{(=|9(QgM;Bn_B0dAd}ZtV}Z+Q)gq{?U2D{>7cAq1-Q>C)sbO zd5T;g$nWFU%^0UL{zhvUZm&a)TnCcd%kSpMr0={Qao?MgzVo`oecw#qo%MlUg2o^F z9&P6O_Buf?k@(#lob;X7D^}m^lk}a}E$(}A|Ga*&@31^k#NABS`uW^F6kW&b1&O74 za~yo9ghzi1_^EtOsk}>hbR&KMp9sE)=~oGV+=71u_-w{Y34c<;Ngty2<9k5D_gdvY z2Yd|kA`26@$hG=?%akDt^{%6 zfdeRj@glPj%98Gt+N1ODN<9B4)8p8C=m$y@vTmb(T*>|P*aprkL@w~A}|d`tLeS1~;LA=V{+-FI8-)d6@a)8|~?xXXekt)sEsf`4tkr9wsF%=@wE zm5H>9HSbqF<7F8Iv|98rNSa&`D#_&^Ca8HJ`Y=4ji zuTO$^nkb2V>lNPi23LAj7W5?E_*};ILS-Fi{(S<)OXQ;?n7Rb%&>^I`fF;zH*U8h{|-1o;66%Q=(2eN9Xe}A_2 z2v7)wY98{=UWuGlLEP@=%V~H^Aa;ZNmYGQV56MH)EQ=tEb0G`^bO5WtS}lxmjht<^ zBL1_@KyvJ7i%&$USz)ig&W|}+61#MG5hTy1gV+YBV%bo*RlT>TdHwE+)R6zY)YS9* zq0~!0ze{}HZIY`}a<0qDx-KV0&=ZAy$9&a$v6n$*n%qg6DD5PE!pzs&N#Yra?ts-I z$r(e$4(B=SFnzPRUVNJMB+W#3<$*r$X(m07y@$bCv1#-1Kl|GoDP>`^!WC~3)eY*H_aT#hv(Itg@aGv9w~f1tcf&#^pv1Xs$4&MbEH zoH$7fVc()T#Aa2<@2@Fyxe4jZo75VlvE@`b7!vH4rR@pS;?VpU%|FgA%*k+@SvgJ3 zGxzTwSKX8?{yV2n**%fpa_hF2Y!ABe#7J+cX*lZpy*BDdz1rg+PXd90vi zn)$7jW8E#lU0AeUGr!FezEgy(x!oE+H^`jqIe!-qhn!o&Z-=7#Q*MWBk6p^nYwhxD zHKet{ok(za1}XR9C(?nU{5M#mG^H_IuOkDp5H3~B=L1K{ZI#(5CS$3S=O6#$!SzrD z37@rXaDUOh>H7KJz5CyKYsU_CGw;kM6aDbs+#266^sML?@N^S!rWI&BH4={T?!6g* za=q{3>p>4o<7GJl!C|kEs|*acrwPq~909p`Ve|mi3$8`d_Q+B54GB$)qT~j0vfRkq zs~CR28!i_#`c{88iGlWM*U$HhFOnq%J9Zdb4|*eCCrSzUzIJ`UV<}dCz**UzNaNF8 zNIx+yoFYoq7I5)>jr{EzhIT4sL2);Bsr-nPiOx6D5-Es?Ad7{I<4f>%IBFy)L2+v% zNJDW^Fp!;<>XlRU#HQH&xV7P+(L9aQdpK+dL4Wv$voir2=DP^HRyWi!;H3p83vRNa$ZF!Bz4G@C| zlXd94f)x7{Z;tEQ2N94eC)ixn95lVI2e%XyrHRi|gYafZ6Msl8E?`IN;y_D&*Sf|= zZGBtgK_vL{2D>)r^)D=J%hOf`A#6UXF~+lh_894^{l6L`tuGGjwS0E-FlN{RsnCTv zaN;2WCmvFjwtSAvp7-Wf+5=gJct{lwk*o{;lWb)3x$aKU1OG|=E}^lrDRLIb}$8BG=}CxG-v3^EMrQqRpH0oN)i1ZQoDvbH)9;3?1|R zWX-i!=?M2PP0%dT`A7OUn!8N$3bCG|)Yep2=I3E`XdOHxe)EGS>Anu#HH$qh%$doz z*P&PHTQl)Si;-nmUae5|+dPE()vZssh z(96^_O-uM=-sC=q??Z|2ON=Pv#@y&Xj8FI+7xFoHNPyu(`DFOc1b9C1P?mpG+z>0z z{I`TZo&f*SDgR^woOFS*{N8vt^WPHwOah$rKob4}!GXg(PWaVigHJ349d6Nlup_bb z;r*3~wY9aCI^E%{1~0F4>||_hcsUu?koP@NH%nDS?H)Ev5%wv+v3iPPlU4 z8q$T6>ieq$OP3xHY1_Apv=^5xd(r%A`}%jUKk>xt-(A1{o$Dt}y8a!kWAr+#@5e0X zD`Xq0znT5J+0`Fn4zQK7<^Y14=fLDN>8}4z=Ri5&k&BXKue|oSSFVrkIm-|v{5^4F z9GvX!CHxl&dq_G%3IAmRoOFf~{$V_vb%qlDkqxKuFkMP;vbQH(z&nyKt{9H)=I{3W799~gO8ZR+}~jjUwELCC8 zx;Ub%Q&_<1u3Q zhjU(yyX?K=`-a{z-cw_H0-WSwa!+v|V8Y~!Kzqx+0FEz$yqk6CI z3vVJBQL;gfbDt4ig7#7NfVdveI3EM2%+C_ql|Bx!G1xv1JOMeO)Jecb)skg*kGnUqt zW$LnxF(&SM$ifyT!G}a1XZVRp@SzeOoy>5OVaav|njtQKY7#tbwKFjZKEi5e6~jrk zCEFP!+lii(1n)GL#_kQ4)pB{c_q;DR(i;U@o@jW`ngUXPqFzfHjvkp zrYqV)uvXHL4gy$R@1svlg-8lUK@t;kz@)JPga36DkWwE{i6G~S?%6SuZ<>RKS zX7hY-qO_p;9535lk@34a%LBf3$pl=Mi(HVcRN_y-$r8J#DzezDaB*gakak*7j%S22 zk#Z3B{A`WwBflDH7vCV*8arW2*idVwwJk5b6t^)izG!dF?>GHEes8oJH!;;O=RVJ# zyD?DtDbv>Ecr7C=#PBFxDN}}o2f@z(++aZvb{_e8s;+6|ub@FvxsY~y4ss-`_J(F= z!0fCrqb##5RON!~9ekj~C=$lhbZCrME_cvf1HKWAg4Q@<6k%3&g@4I;rx1R9@7z<* zT`_JBQ0$YMbte&qY3iL5#dm~d>t7$ZdBQ`P7NW(*>BV^hy$-uL3=9qlMbZMeBs zle83-cPTHQhacERZXa~)FlA`CbC?hY1kSL|!6)D%q(y{(`f?mZV-6%PAPp^p`j9$t zNN0U*MX0EtqMT8Xt>>9y08Q(XGE7+Hl2p7zXR&zyCRba3Nh)YJr35nkO{3?J9=>p7 zdFTAKm#>}Q8D9I?>P??c9pDM3r-kaz+{CV%5<-LoS4~&4kEpCm(XS7CE-LKv2?6o#F+iOaD^GbB1^PD!z4|vh(8M9zz&#@b{AsxjqW%xx z25fvVKBYpr;wWw3O32a5m<5c2MXkFBd$%fEz~8+fsN|T9TP7w^p;Ta;WZ{+qo8v=U zxbZ4LsHt9g2*aBeS{<{cM=6XYMZp`Q?oNIOu%<=9naMh^vMg)=lw%hU2I{8^Pb&<+&PP9WB8 zg`agXg7%fI*xUi_fcc%c-CVNY+(PDS2rk{MXZpy3ZI%9wdAnE=c{egZ>^Dy)++Q|seiskNy+ydG0%y5Aa5Il+qzp^O z1H~Jx#~oaSB^OqLy$0BFoJ8lDY&mWrTsL`+gT-CRG8_x7lLa=I$-U9fjRJlzsxdb5 z;UCTOPKNJHfYaS7%Refn#LBa*LBbzTfPd+fe=-41vIbdxZ#zCgtS^fpPJowQ9z84q{KJ>)6@?>i(;qN816Pwp=yB%I1;(@3<`B+b}cp%JM%K980 zh}VpD5)^$sy@a;60~~CCuM`PkA&e}E48!#!{bYc!LaDE-tu8Fc$xcs&>Lg#} zdu-Exs7_d|(4<0_;0H@BAg@gDc~E~hYt#JJ{gZEeZ~glBZkoKmb^di?V=_|TK6u$J zv$Zq2wqE?+9W!U%@!rMw{r1_nEE^JuB*`UhJZIhz^G9Th4PuHs$8qnG#Q8UzHM-7P zBNr~JQHIEJt*H3AxTQf;S@0zXL6WZ9Ko?|LCO-(#-xc+G3Q!JNm%-_4r+fgF!G z9~Q*(J-HcAn^nPdb#|UV@>Y6K{hj)BdRpW_AYV;Q_eZ82b{zRE--hW7j{^_v|K2#T zSG*p)mi2Nim48XRi1QobGQ1BcgFEs`Mf&}#Sj*q=J~zmHRzBc;ONQ@EfYUz9@{d}+ z99*8;m+&VEjx}O9_9}<;9;wiW;XxQr%6^bBto`Uy?$@N=!!NhT(R_6Z^_>HeuO2KY z@re_%N_@T|zZjcRmj9628F^Xl)aK^rM1Ec|q_lKMh1%#R79KK*FK9k27sWV$SAUD# znr#0h$CNx)teA>7?Kg~XJO{jizlp5{pB*{3$K&VBa!OhLJ>`?Q^7Jmq@_Q4?(>n|} z;k@$uyuIHV0hRb%$ zUvYV|FO=;Mid@6xKT3jkM!qJvwN{6k3*E)sj`EDP-`EBHBkXr}@_vKlWMi@h?6-^c zJF)$?PNe!)Y`cqnxfNopCzQ0?LrXeG$<4;t+R)b;#@#+>oA|_cc+3(`I4a@070k{l zPwNjjum7(T*B|)GbuoUsB=8{eb$_<(KFP-`|_+dl;m z)$75f?uJ*f8=jmn=Z5DsZ1lYgNif3?eGH0ZM6$U-j21CF{HdA^`7%f3m&70w(# z?u0Qp*%f&;RW-Gl+(19QdT$u- zyqEi`9>X^Fdeh{3K`t;4#wXT(h|f-rTSvCJ+Xp3jVexgj z6#q<*Zp7U<-`b;*%5>$PaO(JxYKkx6x*G^rdCzLENb#w@lpgLppYPCj-jLqa?Y2W% z(@&ZcgeeOhi+uFe=Iu_ep)M_m|+5+yTY^^GK*9^ISEQyidK} z9JPO;Uh+Y1?sb2U-z3@_zK5Q7Ew#?i8NwY-ofTG7V^0z3Lq{m7UQb%;nb=u+kd{05 zj!#MR`qCC2&BG*xH6y7dZ>neI@iY}4d#tS_@BFNA?&))9&X_zY;c%w^Cl03+#=_>n zl>vKF)*0BZ9)yc^Ji=ql6RGKZoOSCF8KI_aSr_Mh4q$wwk9_bwQjAPkr zOWHvD8K__>yQGoY5Hlm`=pVzwsos*?XJnto(F0qHf}wzKMX+&XLlgcg43_75=NBQVXHd)le9C!aX}1ZQ85>4CMSNY<9h z@ZZ%n6!!$Wz3gLpX2r|drS-vJT}f6}NnJ2lUz+{mag(t|HOt%+_2!#wSZ1@DWHaJnwNPeNmK8#>kyCR zy4Y?@pV1?{2D!l9Z`D5$@i!QcTx%hHn|j+TLFWGz>>J?Na?x|3>IT4 z7%VWIF$SxDQWdz!_fUnARaIlmRrvpV%_)R;x1Nw@OH#B|h-!(L$ z=Hm@bDbD_`p-a#~-x;7Sk#i^DJ~DI4`wo-cM9H(JqCc@8o=ZzCAtwNM*kvu8KQeFT zjPkUCyfB<2!bjg?Q*;<&bCI5-MW{ZI<|;doB(lj1YDX&Op3`42ZyG%YZ7sH-i`DdhP235OS&PEF-43RBDY=bR~z|; zmrBx_)etQg&6zdO*WTLHP*W8O7Uui1G937PdzstpuVI>#Ct~|_PtG=tlM_FuOrfYW zRfIAG+;0Op63HT4ky_KHt}p3Z-O;ysR<-4^OP|`+v~5Y(=x{akYbW;}{8X_0iwBq9 zx}!HUcj87<{etrbXRYt6$aHzk4Z&5T=eJ(?)z18tJ1^>)wQpJ7&>ab?w-tkX7S~lR z9GksI4Ry?`UbVPvc=s^-!IH(>*RI|kx#a1ws=~F`t*t|G44bvDvZvg;_dx&Z&fL)K z^XK*+Sl?r6zVJ|}I^=b6y0`^(jvVSK&_yGsms8T)0uJ4(0S?_N93((rw?MaQfJ3)R zjuSHA#|SQENF6LRa-6tMRueL>AgMxa4ysfI;WmS`d?Uw8Q#?U>zWj(^Yn}s5b1h6z zctbVe*brw%Ib=~}!Xb}BuoIm35M|&SY&K6x(nmw5ZJm^nPfVvyGC`R~Y53BNk&uIr zk`JY6Pw7|q#BdxXyaV1B$?%kw1;e%BvQqLa4wFQIges61%obcdHQKTy_zA(2xV?{= ziNY-8xYoiVO`n*3+dbD^zUoLvNj6}dhxt#hF8x#^8Eh$|2S)`f8WX$k9Tgs>0Z0I!!|N&eYr~B4XAge z+`#z;>>HQvhdP-Tdt5H?EEZ}S_TrU0ixeDS?Vhr$$x31y)* z)8#H}ThKYOZ$U-%f(vF2F7F6uWoI-8mv1@0W7ES2XAWHarTse}9w<(}11N)zjNGE! zwr#hrUVqz`mg4ea&tO$|Mb_+VUcPMa*KUIHoMk4<_!|DOzXV>76JBHZCK*}4PjP%R zfo~Jiuu3~4b{*4XZXmWx?kJiYnn19ITPU41F&1iM_<^3bS%|P{6R0$s;YD*ss61oL zogPs{Ta&+bcC^+bBC{Xc-wr?4kRL8Xh4@@b^h%jKPoK9HBu3IB z*!~$NdX2xZ2SJe{(QA3A3ISD6zjH~R=Xuo}`gLZ{1%9s(_+uhIZU}mgSNYD07NRXr zX7i$J6Nqc!^<76v%zv}3n`o?gb;SiF*FWMb_cVYiokf0SkAujoXS90N<`{i7)cwYv z$JP!#x1Xpi)Agi3H#*@g_Cy>RUOI<4jd7akj&#InCJhy|$B3oXG+!eDgfahjkO1w2 z=zSXBX^!(9z*mAF{eYiK9f0GWc|Lv+9Cz9{9I+MmWx;$MAxpw*e?eM~82a_FVX}VXaXNq=12{s>? zd&@ngL!0|nU)6Eq{BnEd;G-9;x^-K7@7TlJH(b*?Y+zd6JQxfV(~P!PzdU-&y6VOA zOpksr5WaNb<{4MMd}!>{txE(7>`Rz?lr39Wz~sv)m6R3vc}V*PyePMcQF$B@4r0wm7cbNO!|ir=ySu%WWuaiWvb>brP!pCyO>qdP zSezD5;%cxJ$tUr?Da&)hxEx1M8V}>%~2WPRAi0FYW@?bmFxjTjm)MZz6V5(5ev^ zsYsLWcU0~B8fdW``SM6Ex!H7(@AqXKFBA*c!{Luh52l1aNpSE1(f$~+2iD=Vx%*@r zl`POsmR2kNP;3^scS8z@ z=Y8qO+`&tZ?_PJ`-bhyN#5$#6`GL7Jw#;tuWM?!O_yf1w%jflQ(1If8Bz<{g3UcF4%nQriS9OVvq8&fk(j306whYGlu`;3HYb`tyq_n32?f93ixvg zaJnZ8_zMYel8*%Z6v43{__#RhXdQP8sR-%##j26}iC8sl!LS*$1%rEjK5hl4Zy2H_ zg7a6>;#gyM!_zI!S**pGpgxZ4bhMrV*K|fAo1}(2oROb1tQp0Vah$RrNDmp{umQBRS7vBPCjb;>LRAES9l8+1z8W(Vxi@D=!<3I!3cR?DDS@pVQW$Lz*i+@@#(x zTqkta1=XP4!ks1*JJc{bfybACyCJ3KUmx>bz5)f3GpcRe}I_`%ghs~1V*ntf|hsSOm`MA$y z*z6gj&NJ8tB9{5@?FmbgADKbZu{kVbA9p^quxlbElC*5;{E-=hDfgD^Ojj4@SK{89 z#@2o|%RObYr8BXg$Q@f|t7lu_zZ(-)ge{5H4? zX~I$CjIO3*s7xhBIFlFmB)%Bw)CWT{a+}#|n{H67uU1_KV}i%x3IP7v+u2@UR}n5P zLAtjrd~o6wz+0~fH9(ThfwWL*OT5I^^v@eVy>}qp9iX{r@w#ozSt(1q=<7Ifvu)A! zU%O=LU0|@RqdZ#~NKwrN$TmrZu<<*f(^K$4ZbZ>O7Rl*mr~?UuuoV`fP!2NuG*-(N zRafgZOC&@h^M}evgN%}p`xOT-8)=rwr9d_2R3x3#$fO>e;=t2WXEVCFnq3 zS4Tr#RYkD4ATQu|qxu+PVGv|NRmfOt1-!tZ#v{!inIEW(4vamT?O#_d3wwV|{U;3k zSgQTU-;hfR*k!#-a1mp*dwqJFjNVJx}egE{J|TSVFh2LAsdD`w>)t1GBz+1FcBgEB;*l4rV65 z4=%T>*BkFn2KaScp2r01+AXNKC-x5PAg6x^ zq;GiVzx(!EZMgk%?U+vP)7^e2zG=AqS_tpa@5S#|P*>x=#N+1>y{zT=CtQP%smGA@ zu1MO5;GN@s=waLgaKqa;3$9p;nInU9G9v_%gl6rENHz;e4m@4IS(ZlKh$*nxRLeF> z=a1MssI)jc!@jUu`O&j$1a5d4j&(Rm#vD3h`xyP~N$dxHocdHU>`r@z^DL%>wRbx8 z8G-GUk+1QZRm+zyoIi6$Ur%Ryb7OU7c2RawK_2krFY}d&LIM=00Gq!kC4ih9UT%~% zTRt9394r_-Z~lTEg9V3NrCl{OU8SxuOT%Jrcl|so1s~;mBD5gz){QT(g-ofbh|a+@thy;BqIVt{t?EIe?(Du z(a@yY6C=l)LG#U$UU_2rSHUK@a*|iAXw+ZA07z%T)~Wo?w7~> z`42X&yJGRoE_E=+l+(U?aKn*_ibM^rvcU=6@w~08uG`QE9TMqon!s~ERH?r23;~<8eni6;zWH(WIp}*y?MnVD?+ZKv-ppf5IGp`}{Vj&y z4|uL60e@R>&+$w7$N`@gzt16I!le;MmIoMcu4|(kjznj$uO89p&wPN>*?d8Nro9^8zGo@b z;e;R4u2l4Aei!sNAUzt%s$r@%z-(#`Guv#;A(0a~(P3+*TXwh@?!FnkAPqSUgAUDR zo*;!XaAW1x*e$Zjw0*=$rx(xk&`c0KLlu-Qr|Cg|iC>H`nE_mkdb+zhQIDp%A?z=)z5)|qrIGlo7Q5VcdK$^b^SNMf$9;eJlz0{%8^ zWdi;^OHhaNHQbqI4WE-BgbNwOTNRMwtEdcDGIef##ET!+geP#l5ihhSE{_WNkJ6Oz z6&AmyUgH09@(}dVEeX=#rHblmLT5=IsrTP>#1Y?;XFwH(O{%dyK@VyjkIN3nG=O8=|4x-) zyFvkAMU@fEfv_wmZoN3E8Plw?I4!sUi7Hw7k-pf=XlB7Bo2BU`<@;+Qp)%MdcVDpU z{7oCnHk55xw`Rs*S4U%gNl~^B8L!;T?TY6W(@frQv@>yUY7v#;_50j#tLBHa0BaeO z$oCVO7P)t|_JjLeBnPpw|7>5{S+IBKuDykwOW8%$b2gs0tGRPdXzm5WbN4N(K3ToL zv}@bVOXm!fl=f^!b|vIQy5viH_B^_~W8>1gw#;B-$;k4q?YAr++Sjn%a7hrMt$!$L zAF120d-sOAk@ljApM>l49JtivEov+6smaZ295U4o1#Rx3#lsh`toQip0%hS$lP$Y> z_3Xh*Hg(kwZ)qFZQS6)1mEF)#omqX;`r(UL)E5@~qv2K|Y--wid>S6Yx_B@CRe?ZzRCUrY71SPk@umDBw>fz{xfz;LmCBmC?JDe^#mgjhrsOAw7bh zX(LZQ2m?lBcqHi-+Z}eKcd; zu{{Ix+GjXj1*HYmBinmFQQlqQopIzJF4^_v8y3wTSQP&B6nYZtM06w8?-Z>c=t*0@ z82kmkuH^TDbv2p!x;`M5C^K1seA!)o%o0j*|L%#VZck1SScS0F!9r?(|t!Wpbs zCcF>gYei|TKGs@&%%wTol^{Fy|HEZ!GXI#kR4?Xqxm5NGy7VkylD&ufBf-6xd{Lpw zrC14i;7EQzZb?ZGxE?tPMm|jBZ%pSY%E}|qh+IM>$-a)lA$E^AGq@)cxrl8Wu~Lx& zk=|6qr_dhgOz{@ZOclkF=^fJ0=)X^SpJv}1d*9*U+k&fhG)8s?eb9%_KD$0BDTVeK zq)Re>Q7w8KiuIl+HibPJ^30Ep;2%6UbV^g(Ua=sl2?0!K2H_yyevfH9$sVa7JtNUEAD? z9y#|682U~l1OH;8o?!7co7<-4y9qw|G_~h>fJFOeCutle&4RA;$MDf= zqKYP@=gjm_9=|#tD#M_d0aqv`f`mqinwE;|qAYS4?jAw81ImC0bATFG2car1YzI`m zl;16r8yodN@DZoXhu)B1_=szs_0UlWS9?z=ZDCTX3pX%$|GCQ!uc#eAZ|9;Lx~tM8 zMl2gwcF$Vcan7wPCoYw**?)Nc;6!%HEQvr0&RfJx81V_;)MJFVNn|wTcq^2)KFcvi zo(05wN|5v%^p8A6!*k@>$+=RU4=|7GMGw#MyF+s(6 z+EDHn1%C%34{oRLK5^bIeD{fa?>)i7(KnS~~P-&a1=ejy$;`NmnmR=SFXq{|$5YO7+r1!r8nMxF?23?4Q@Ag2Iy& z82A+72yAd-6;7{7?V$om-5&m~dQ%I$h%F#$Z3yElSay8`s5Tuz(rT7hmT|}QBs;F= zGmLmSs)uEWhhyg?BamIJg~UC1!VvJLwj?3+Z(FsHHz52|dQ=;5`72EH6UdEQE^V8n zd+Otp=WyJkQiYr&;P@8k>bP-M#ui3nD_Q@&2GN+6L2^jPJXN;e(-VmGbxR@_}2Pz9( zs>2cg!oOqkhk*OknK~S`^#uIqfLrh#`ggye!M_8zU9|rTefM*MucqstH2CZRuHWJK zV?UVO&S_M~livSvt^YScyQRu|G_ITLFej6Aboj<^U=B0QKiB3~0o;F*!Avflq&_sg zf48RhcVhf^(4RvJMv7n_hu(%M5^0Y?*xei;Rn{i+y@4>RRsAzlrqWle;+%1dhL; z<5*TS9L&WS-;dKAo8;dmqX_v?wwv$S3TYJz&|&^yo{eCh`PifU=qLeo$uf8jYzR2; zq(ZGy9!-5yQX}&EbW2iMDQa4KCGRYeMLd23l*we!mV!%_%)VfLNqas_raNukz5#n>g#H2kg79`Y}J0B!zOu|*G?)LEnS%K zId;iNj~+9dXc*8*A~VLA@sarGpWc^*iF@ujai8g=flUJ~A>T*QsGNWf7CoZTlRWt} z)^wX#Q|5@RsnfWoEqqPuV{6)oH5FdKv1Lzg(#e}p1a{gcqL;vQO++trIG?7M1QJX& z7b@16K!RE$^1h@0lIRc>YuS`lm~vVUl+3zdey}~?DqH_PI>f$`OTp{BQkjGt{P_sN zq|GG{wE=V ztE&uI@or;3>}?Vcc>f<5;p$ry%|SdEu{yILW;RphEs{j+c}N#n2^}tlZtH*8c;q%c zuA+!sq}vz;0|a;A$f1gjq{H8qT7!rzV$i_;t}s8Sol|e_gxl6r;Tf_?~)(0-MvEp|a`06L;JJd+28-M&-{OksqFb zt`+Ng2^{7dw1S)uv}d|nj-4*Ge1ay@_kz32zBGyb0X7N4Iy`4zlZ zg83!LTv$JNRLQ)+FQ!Q=tzZK~Zy`x3WG*&E=9+ba-D238+;v7h^}&F8YD)MRXmSQ{ zREarwrM5^jPA^1&skp9eF`JN^*)H}SAqst)->{_?UQX(FlO zYq6dq0Eq#3`b~b@MCK`cg?8_}WoNm~*?IH&?S~7pXRX}Qy!i4}_2WCX)-LJ|jc?sJ zG}fTJ7v3>z^}a0~i(7MAw%)d$u9g>FTHL#?mwvnC;GDh*2yhw=tH0&3+PeTC8~IBH zIO%%@{FDwy&T8O5hrW%qxFF*xR_vK6%xB6PC9h*t zPGmx|bn9fB`a2WpOFE^y1uGcs~}mKbw4o0 z)?g*Tc4$+}>v)~a?I^84Akq?4O>M`|Z7@NeED8D+tu53AW!e5vHer%iKGW$o33oi7 z5vfo(Wmn*e)}~OVOXfww4EZfi$p*yvXRX-Wyp~)X5A8oRzF=pGnGLpnAAe>?$BdrZJ}n+l!VhJK(k zyI1T<(*4ByhwkS-S}K0d1J3j7pBJ%v!54!}wNO+iEpQ30Mk-R)!`lv;F)&U9yU{)p znz1nzYg-m;!tZaI{wJv!bO)ZAEZQAHchH}}pv)GmA{y)}VEJs1}9gMTuZq9~+TlT&WR_ts0N1g~*~3S_HE$d>t$*k7WSJE0(id#PX> z+qqn#z^{q4FT|2{sS~n4@tF#!OTdgwCe64_F5W4dL#>Z%FU~$hN~L{+qa2eSL;3VI z5f6T=m+H%bL-H=OBQ-!cr8AkXUlhDX!?WquWQOrwu302}x?(uKE`dYz>MBK`a<`7) zD0nQV`{+^iCo0ub7WB8>1YQq00yzLod3-VK{7Ee?UbH7UKM2|J;7NGY zqfo0*e!*c3))un~7@z{~kQ61PS|JjodSiN-cHB5m-);}X#X8sTV^VWdV|}PJKi3C! zqquR}xKjYRw`&fc@WbgS+V|N`rde{8DBjG#Q zw++O}t@b8$`1(^99sJt$^X6UuwSyO(x_`h1^i?Job>Gi{#*i_?C%2pLIRw4ih#dFaPR^?F7^hk1#U1L-?Zi1`DK^m zyOqr+BpT6Y=2gU|LEkjknjSZCy7`ybTz{8hu8YLYI}n?2X?(&#I(||<2@y%a-y`X3 zcmcluEng${0rDB;aX!p(5B_Z29~2WS;6K35A>SKXlY0?&DfUONbknn)mC(WHTcpO0 zoOzagDK>zWZxma?Mmgiwe7h94KsI4gOK(dLZJM%#O(QDwO@k+Fn#91ncu?y!1i`*D zO%Ut!)PigpDYHtOCVxUaNyA|cd_}H#wz)=DEjkXXC6mRp4|W|3%!A-H7K_GfQlaon z8*>ci6aL^M*jZnTax?~(!kbegF=}LcmTYDV68FX!ww==w?9(RMHV;2Qe zaqMOoS26N2-s8I>NK3JF$>N1GhbZ`>t|oDBI8S>VYv=Ttq*R{fpnl_Q0zao;4|C6% zg?th}C;rd%nnBbonJwLZ5{cEU`gUrdY-FHtECtV5MyQ8q3e+PNm9~LMSr#`*pTQdl ze~G_=@H0aH>{&C1IuQ4gi2Bnrb%TgR8ipx(fu*dS-d zWuD_)UQmGd$AR~m&_{WoXXuKw=QG?mQ6mPnPZ_pPAQ|<7w?Ks8etyspAP!_bM0r&D zMto#Ba;8I93wso=#LcZRBxom;;Wh+Hy5z(X+{)^Sm*xJ6@jLI)B}Mi-UVM8-`#BGe z^^yolB4zgl_if24D>RheHhu3CA3gibw={wAqZ@hA?M-3p;%lGZOR^-%mV2JPb_r5# zmsRTpw{>}&=TGMHglScRoI&?SA^V*&!ei|zukvHat4wh_BpVtsE64i&vEGMzO+p_} z#Nan2z$reEkBRs|gUrL@0|op#Bb@t_3;66rIPM$*-j@iE_1~WWr`k)ReODTIBoQ9# zXD9)lB!lXBP^q4^=)WhSeL6XvVyJj~SxIOglgAN5CGayc`HZQ9+Z;*x4*i-0Ek3`q zKZe*=6iSxD(v=a13n2Knpx!d>O_ZK59|~Ymml%m>NW}uG4$`%>kXNnGOVcEzH;EL3 zVQ_n;OhL=>PV^QyPi;YOWw;y_X7gexBG#!ZhqS_)~*tMEc zg~97|!!<2*2c-;=Umm@cl7n5cX!DG#C@gRPD{v_%JJ00Rtud^W*+<*C1_vG5<>Arwp7w?B*3i%PXfWg zirf|nW1&Q(3jK*FD5@ZELs7_7EQYIq;U)=H>6+6lYSK5ynYjZuKZ7w^B-Lw<dt?ck}iGdyUw! zJUahG^8*(oFq=DnH|sMaPsQ*;d_lHkXE0)A!m zQu$lF78SL(NMGj(vKg{jOY*O=ze=R%#m=ys8IwH7CkoB_$ni>0G(oHyg#M7VKlHs+ zfb7+<0>SHbi_kfWdnt%+8}zTDkCJ#BP~`TwauTdZw1aXIT70By9ZPBo4$sw?dP}gT z42ldy_^L1NyNF;*qDzu^EOE0Kbc`s>xw7%*b4q#wPIHc{y|i(pr@{M~&y3%B=k~&E zlTy9o6E62Pxful=OIqiP084f%J74f_j$@KV1ddN>IKCLRLjx{hb3{B6aL?f?>A9$V zx%3>`ljjaaE0Jz@5#ouz30&8)YJqE)j_U&9{VBAx1m!4>L1`6?P`HKW6F{s4nvtKV zz8s|qi+~{Dwa^$Od5VgGDEo8bQlx856R6W;jnltHGU+;;<2*LGRbS79_YA8U8_e(; z`E_IvYYL}b-83=Ee5Ko_tn|q#dgUq09YIJhs^(ekGkG*letmCgbw@>ENmc*4!S0<)8V5Q+!H%n~ zRBG*NFXOchHCzF=0*A*5huB*)V1M#)y`+GDJ)3X~8#>_}I^kXk)t7aw%ENf1z=}R5 z!H!MHBwH*P4Mar^k4SVF$DrAKmKgka2s?ZHXy4B1iujQD_ERyO+-<}Odz)}VxI+6X zGh)wq`*P{Y3*nX`ow{ndWc`xNjxXnKj#@jP`B}YR^)_R_sy-g-;hLX16dPJGD#ka^S-`L8#_KSs4#A+D%qn`+*zd&BG=p2YqL~ZI%BX8`HVv0QsQwGOqbF~=3*o}7=kd2+m{YH<6gHY2a=iG zKNQUfPrrF9r|$TsB=efpI?c`T&cxY1v zS>!pjA1CBxaE6BuSRHT!+NzD-C%*`IALZL1qVZI~nXa#>5FRELw?LbAPzf%|ndAb$#v&tD=GhpK46%i+a}^SeDM^HEi=-*QQ2_M=sb-?NrN68f78s*3z5PS-j=TxaP|k%sC} z=9L%7yS%J;*~q=XGOs<98rd~X(a#$WK?`&Pk0amz zJ-}HF4C>cMd}esL)cOz!DwRV_EP+>|o>QWZPPu&&EcN>k#7=QARA1S$p9FAu4Tz8% z`_1dY+ji0Yza~w4$~h*fNPL3RQEv^h%?g)=pjWJfgi%;SdDjhe$^BbE#4*|wEKBoo z3H>aN8RuSdYnk{UPLcIj&f0KM;H%`{!hZGTFS8h$5pG z?gdpEouNkVIs9xo0)Rz*SzamV5Af|=_Tq5qaSdLDIzJY!mpKAn109vTT+k)pInZ;5 zq*m#Th^vNK&G`uW2bTdy5f}ef2{G4pGq3Myv0E*>;gv__B*wVefg&<^HXq=a_yZZD zx5YS1=NZ3CE@9|^>vB=KIzQ5$_EihU1XJ50%pOTEg3n|kmqQ~s4RWSH8%!R8aPl(p z557i8WZr>g)eWJ%FrcaH#Kd0`7Rx~A@>l-dK-t`XK-nB)95qcEm1na~VkyTBgsu4w zfUlU|<#nCJ`kjiepQ`e^lUTp!4C`m-u_Xl%8tZE4c2Zc7pO>2xK)wp$$>L5OJ0SvSPDiMo7Uk`vV2U>$ zIC1pobj13A>8n~$90kDffRm5@B7$>j(^7488DtT$X2gTP9NfM6tN`HQ1i~%wp@2Xr22P>gU|)-y+X7oL!dnSYw{S5k(yhL%|9P zhkd(gOMFZaN5U&uhb)R&sR(m606htJ_l(6UogU4mADg6Gjm2kXj*i$=s8SqjoQz_*DUw54 zk7#rwn@2tMGw%WOA~g*0dLk6g?0eI9fMIC@iUSOvW;6A5EOo)6g$qU^lllsoDSOC_s}uryLCCFP@0n2O7Ct>9)5uTsiBaE2CBEP73y~To#qT@YB;C z7-@GR>zR6r2;OfwN2Rz#K_jQ)G-A1k#~BJ5dCov1m+>>?8crkQL?c>1=YvMHexw%+ z{SfWw@Z)+v(eGIf3fiPI1i8Ro{vZhF)0a8Tah@;oT8c9SZRrfbm~@6vTX7GHw*ifQ zj-MekFT^C8-VtX=yg%a^Vwum+khQEh;+V(GnSE7q{16%P;8r0qw}gyD+A-pd9V0NP z>&J+TZrhn_vRG#3cDSO`N#e92Lqq&1nf-Bk;->+1XIt+?6+?cY%$(X0hNTIpndU7i zXE(JQ(0Bur)~;E-YUT1Ji;?bm=HNh27pfAbIb!^0dBmLIX7IF_S0x=jZ{C06&O1NO zhPeOC52e%W44hPSZzf(hAG9`G`bEUi#!Rj%)C7wiR;_O4bUF9oEEmTWH2E^p58=4V zup-%|Jciy?(jSPV#Rn4#qV++B`XG=(-J@5*rW!( z3c9@4_&Iqk)|&j4@8`TL8U7@}aqbEDF=Q2}lnz8tpj5SFt2lLa(IrTJgox6{Er$FE zah~y8B5Y~vVfW!Tm`FHv8-C$X6t*6#wu?KbN|Xh&EH?+E1>iZ4FrOR>Mu%f1-87Jr z43YM9Lu~KxOgT-I*HDzpHT1~&%MP!s5$P0WPB|$Mt{%Q%-kOeWx2}}0ow#KGp^+i^ zH;HkLz^V9V@@Eh@I+=hYvd0Mca|v*|BMA5l3Gjc5!M`j$7{m2jd~HPgmlE1j9DGv$ zh;evLc~9>LKC}*7Yy8e4`Z;dwpZmOUIDBLbYj6I!)<4b->D%Jm zpy$R|b{#k7*Y&xWRwwlFKVtATTHVsCpx=$n9p@H&xc@dueag@OZBo9 zXA;jgqC1&Fb% zmySMLk`&ERDq3+KN=>;dhftBlT2f?_xKyTY3?`tr z1?SB`{tOC%2^;H%Qi16d8#*zEhI)aPF=JcurZ#5Kh(4_)%$T~V;|VlC!a6Rw?TzCM zzDNR>M-urVe31k^0MD2|sT7lNJvuN;<4CYV{RBXVf8u+Q!`a(fJa9JX{ExtWg><2? zW7tV8NkP#(9$5QBiNyo+@^QG0dzqbSypS76V~4X?@dX% zd)P4D69>YxL!sGW`Q}U*qJfJb5F_)m5WI`#K!4q*oYlO=pZ~|7AvU00WiLPy?|vluM8L&vapgOrpLYeI_5Hoe8NIqNAED!(XaV0ZG!L#{y%F<* z)o%-a&_3dD`hEdFxfO8C8~eyqiFr3k*NT1QY^*HJg=>-?v1a%ibOZM*vdI;RZ9+^< zf##HSQNn8heUf=55{9Ol$Dd7Y2=a@uEFNauBsBpwC{h`wFyoZ=wDbtGAqhb82HQ0~ z2AMT!vrU82=!L+YKl+&RKHqmY;rmF2yOrZK8U7@}vF`-@nB;^1Br4SwzzF6-T5>J9 z1XC3x1>(si;BqZ;$?TBkOA@s8!E8U?@|K1uv4jm$SPkV0Hb^?R>b$7 zRlo5f4ZoubqITM~OfFFmO1mQ=(X`TXpir}C_ ztv%|~ln@=F<^duBDCC;Lxlmdb?iDEJh=~FYo&UHE_-ju5+)Qk+da^m0RKlDx^y~n&|&WZAyhMl2I`QL9&WY7E?aL&)= zYstTXz1^yP8{&!$aP=*MgKu@?{67I&ER_yv=f5953^0R{-&+LQUj9d%W0m00*9^(z zZb09g%(LLYrp3&rXqv#a?0%0Q_Wv@%j;h;%$uF7iN`1hQhAAYt2j-L$$qZ^Dq$7$W z?(_8t^>H;E&F2`Sb*xryVsEOSMcRNy>3b2o18bN|icUzI z(ln5#DDI5qhfTS;-lc2T4i^=#EvX32*c#~`om*92QV!+e?`fW}{S_t4^b6%EMyCiKVJ8N025qX`;F&{CsjWSk8xox0p>zt}`%n8VD#Tt0{8ib_rh`SWkda(vf$|Bo@wrL9? z7@1_O1ui7yayiN~)rh^y>sixYO>VR^xe;yA|?$LQwc>$=n2}f9eIRoo&g@x|mNfdp7v@90C3|2QJ(@_}q8-k|D?Jw2x zS4fIkMr;+_jZ-u?Qb3N)2CYhst(vmlWo0@Y7}Q#3i`RuDcOKnEXKF!ecAqQ1s-UgU zs+fm+i)w?pj!bKrzqPYFzkS23iqgUL-A&7SgBc#v{}-q(_V#uxTsRl|F{2?j=(U#3 z-Z8Uvf#DN>({#Z=j_6SO^#JXw&fMLUHc8LlBOpiy}~)qwHF z_aG|jh|EWNxgD_n0Nc;9b1ECJIdZ7Zm9^m9b)`XbgUeRk6e#MseYlX(p98!s$9sXpK#bxXZje zCgm;4TeM)LqpiL+T$Yoa=|;f01LjX2@=6|Rg7;COFSAaDZnc|r$ zL`e$0Fa=j`SQ~2V>g($2Ua0IF3Hfq6XGUfoDyXv;w~y4g^IbX3!>fmzOCuY4dscQ8 zRG0e#C83JC;*OEpU{9{;k-D<-y1MdEee@^USqP7E6lE1w*2+($L7_y6y!#4BB@1|E(hN$!gvZsTyhdFK3w5T0t>wRaKI}vomd*vBP~dt z4h9>GT(72AkBYqM7WE zPh=KmJDu5unVzC-Cpmq~lOM_dD!qrfW#X>4Ibw&2&Ll2F;!w?occB6mCq!5peiLPk z1zz$aLHq`hmggxpv{(hcM}i@OUU;I;;=+I*eP@=1&CpC}B}0URGt$MzrwvA){Z>}R zKz(VEDrb1h3qI-0F3R*^{tdxkBW5p^_SNOtXW7lgm9iB3j?%_P47CjF*^F<GXFwA^1OkbCcL_Ai|V{dE2S$Dr%}?Z0+*aniD@SgY;)k{f|*TC1DQGNn^vtq zygb}?sIoe*!FOmuj#*tEtZl7rsXKQgk?)qKM*7jvoEwNU8vXECQCP{)kF!?HD$+3}F5si{S zEVD(FQULi)iv7jY%_V-oO`T1okEYYlD#EicAIt;u!hB|hqYG9nTefoLvSlQS%hEFW zH*%x;S=^sO(u)yC?CzvrwuAigL{sBJskl6e8wUsS2xyYs;|+0C)54?s?eT^?c|(#S z;tkXGXlRqJGm-#!%yfz?TvEt1HUz}2*Rx52?`%W>q@!eM7nj~~g{$q$IkX^OHRa{; z3tUOzg7O9k@B9LnANYa%G?nZUdzIY;Jo%+NBN=`buCq~QNrc7&*tE$0s zXqZHe?#9l{%^tPBGWv>ac4vw2!yS%2k3G^RHAHILaDzj-S?pmv)UIndT@W$?AVt4p zyVQlkbrm$SW;^GSmM%&eVnINp^`_W$^Dfn4v-$HwfwJl_RwJC>wxFeLb8(UC&dBiR zhYM;e$^kCVZ5nQDUtOp+SuH3|Tbz@f>-7a&tIG%K@N>8kr?V@V{2W>( zq*3IJAUJPF(zu8p0%uOZPp&!3~*G=C;5aynaGH)VfzUG%p(d6^mgfoy!oeB2c?;m;M2kX=6; z%YaN8SPO=^pa>{2(ot?>5lg|<(3(SoIlV)JoVg&^Vkw#5Ry~B1zqY2NBUe2(@j;+E zSXtOQw}uTzpRI4s&t(@1da&Va%ElZ#5^~BTmH}zl3B~)l{(F?sY2=YIgB}wF^C=;u z#WUK&eRoHZmVX|i0gZ+^j2t(`;WSK`htmA{QIBN<;)oTqy2-%t$r8Dgm1BJ1E;c?!2A!;;2}tCjAWMt%S*X*^qV!^y$1saaT+Y}m9{ZUa zlW>2^=H`=l%BD{Oc0imTRlq?u(Fr0yQqW1Z>IQAktm4YdW?E8cga(LHv@JAY+2sG|ir(Qj;Rv*x>4 zABnW+-vs6`1N~=7`H>t*mRMNyFZLbOpq|NDjc;svm#1wzsGsF8=f{?|J2(Uw(Sgk&@EJa~~XgW$d9Hjitrvv8Z(T zwWG_;(a*At=H*9UJ1k2Th0&Rt?>etrRqp?2tJ;0uU7Oig3M-IX`yVm4U#L$)$NK#V z@?rg5bm!!cgn!ZGkF;7DV`%dS^$SuD<*?3!$(wbSLDI%ahdUH0CU=gQp)`j4f-e)* zOVGBvCRAMwBV{g`Yt5lx8|KZ`P&|HF4)}u@n@Lv+#Om(eAKLgRV)P54)DCnPTi2~jw z;L$si;1R7KcnKu5A4=2zpw|E6yglXq5&d^-aCpuekKUQ|oa4*z{FVeU#h>&1mPb{}t@Jw4f%H4+YQl>KC%kaD z+L;F4mj>Q%g!Atg{R|l4oIV7+D-Ar720mnj8~PtK!qa{i(Ty0lC!syr#09)J0Zz7W z4o6-tBYw!{F5oZd@aRF)QJ#lH^fQlrLg16&e7_OALgjF*LkzD;&pBRcozlF|@tgcS zh6m6Y%_sSJ4Bw!$(>&*RpXPmz|K#U}@%cI=Kj*o+#P@fn9A96T3YD+Rl=t=ZiQ`XS zrxla$Dl7PU{}A78mVQSiY(d8YPIS!S>g+V|zBKUu1UT(e(N9+zcq9#cC;?9UE!8~f z`$hjfTKg>I(aPZ8^<(i}d+-D2Y8BuiXzz=pTb|9fl9P#MI15mEaMLD4{!(&{}5+2jN((pL(ZR3-K7x~4SqH;ody{K3M?AG!cqz)pL7gyHch%<#y zP;c=KUE@PT)ite4FAdE8(gl=U91cW373K5fw-(Nu8z^76Y-9uF6X$Cva6oHFIKWvY z;grJKCd2#4Pb3ArUwSYO=QJw%86Y3ESbJJq0q;uaKMs#bM^m;Rk{*e}4gC)$^iOMU zSi{)3wB};m9_i=tez>ovfcH|~Io|%DDTC(-;r*!d_5&R{obwif;|!zuBXTd@bB?EJ zo^yO9KaYJE@fPy!OYUFC6Y-W*R)(QD9Xs-V!3e0=ZM4_c`aB zcJz$3EoGz$C~^m3Er>4{|)dkrytSJ zfapgO{S#dZc$e1yUwJ=qctq>xS4r@pH2n`wM)2kSFrq<7wsDHyeX9>8V zDMR~iZT?++K1AE1pB`=8mpGhgTEKg?{!ei@$ub;{I)wsnuW>lZG6Mbr!9mN<;EW-k z-E!%RLMP@ZvB5@yI6N~sk?DVdrpWJ=T&+Ty7rqGvb#OODLJL7=;&;&h4o?5PtV2@M zJ%*-8>nEC$`GtrT_bl%EA!=?4venvXq*pG5VIn9m4{4;wbI9PD4Gjjayf6=t&Mg+L z!+$Y-cc8m^!9cye_t@r_O~O?efLr}a0~pIAI}+1x-yPRoL}wWAGnRV&J(zpgA( zrHT9YT{F5?eqf?-;au>RD}Wyl=eutKUnI-j&goXbiGBpUOM_nt-~P8aFZmB@4_RBB zR{~D{j{<%&0Zu$dz<-|rr+vZU;P=LU;&A;u6#d8H{l@m3-b6nGMmU!h1-vT_Jdy@J zWP}^~A2h-_J&XQlq=C;g!VUe*GQti0bfKJ4%Cvt17K3NIYt_xoUI-lQ-;1*bGAciRll9}=}#`%$yk3sDGF&zI| zTRfhea3xQ49M)9^W`BreC`~~ibRy*V7sxhSTsRS+7*QIx9^KYbGiO8djCr5`>?gN8 zxIePwu7A1u^H=@gjzujSu3B8@%*@=nqj~EmHy>oZ7aZHT=&DU^D>grT&-|;O*>UN& zZ(q!!&$GE~@l9VHTl>J(=LF~a8!RoSE?;`{xxM%ZhT3G0tJgz^(;)pQl2MDqluRZK zuWs_8>JGUhT+hst)*{udD6%RHrfdact}h74Q!_YPJ5Tb)!Av_eQDtRMmXO? zqMrdHobPo3?@9xYq=63^;fDSPjc~q4MgQGt;5}@Y;d^P1iuS#Fd+0eHP(>+gftJqMlhwb=U^u!SRQJ6Y#RxjhOK7Y`Jp z5}?HBu*nf(?{YGU=S0bN7P`nTp20H6;uS`MFRlO$dYJAk8|2Bq{gapWrpqgBfN6QO&{XKd=~-7px8n&i8>&b@W{=mTTD>ak)K;(MkZ7e-{8|ewQJ#`!NXJT!hPuGw6Pq8-7>TTrb6UJ)b z-}}D!URH&linMX^PwLMR4`GM3xk^H{R-R!N_5q0c$i@K=Nt3B%1WmbrUaLAkknM0t zQm{C?Dp2L{JNzCu-nEz6EU2|z1ak{cmx_AW&A<^^vne~v?~~1@P-$5?7BQ>6jFnp# zT|K_*g7K>sS>=qyS3Q0HdB?9@lEMCZKT}`azWv4Mhxgwf{fK^pzW?@%Uc7SV%qw5K z=#H@ymkthIdSXnzcGoM>cOQBv`tHj+cfQP=4?V=3uj~TWER*k=e$Llzg1(QnNchee z{C?nu!=>jXXq{tlT2BFg)(E%c#o%Al;Ojvz2WXwi;>Fkb7y3Gz7n$Ed`Y{XO6_Uq9 zIvCIa`x}4Wh5SapqP0N^PtXDA&N>A*2<~&2b=GQB74&ZEme2;K+7m*esHr*{N1mm~!dW z%QY+)N%ORQ)uGD=TH?K+N6y-IAiH^4@0+jGj$ZhW=WJdP zY|hBes_I=e(6Oqwb>G zE+5AJqFi}&_3D)DHml8UMU)F1yi}Cbu!45_{p# z#_i%FY5^%Fxs)sxD%FxLpR#1F=eJ}O)RhJsGaNZ)SM5mU+;jR1KF$*QvR79Q)CSzn zz+Cv*t=!lDm9z_rJ;V2aiu^vDN0_CPnhbc$N?GIFKUJg`B6xaK9i; zK-|h&Dg}c%6~f0ud>OZ>Qydh(@Qd8&dR(aKFArJF(Fd)09-k-Q8ogJwK6D!b$XIV6 z%M)Pj&N8p^*N?37Lj|*nChm4;Wx3^@MRN)!HYtDg1SbAi-_lkqXXaoxa=e2Vz5%>D zq>4xxEdQ|nvn|{TY@DA%a*#5NJ6{s&gZN(y{#D)>kLHb!v;QE}vY$lDmG`2%*iqmS znnmRx-Ic zaN;bO{1cl4Sedj6pNx>7G(G5)b`<*Ie9t?O2;tdn~`_?Nu;QlGE1K98QFHGS9h z(Lb>(m7jnPI!Z~t>Xvfl{}l3-{GXcr{UYUAwn_aP^r_}?Rbq`b-g-E~h|8~>O?Tjz zs*3{iBkgX*niqEXid_z`^6Z??+xEJyitaeA zL?323>I5VKFX?v~3K%f91AZo%GC2yjctW?_bdx&q*GFlcqYo=%Xj{(aKpAaeb7T^9 znREpze4mhSLmxR2tS$ET3W6gNRbmUYj^M>{h1&eVYw~SZ@^@}gZd6}FSd}8xjU2DV z`QV`UG$$9XYEJBC%`@?iZlR7$8R!UHB>Hp3Hwp1xI-Q@d3U3+3_tEb@cktlf^PaRB zY3P4^2IGab@qYaGjrU*teS6qf*)jQ7@afgpauux?+;}CnsIpA9fGCpo*`7dETTyW* z1cJ)W;-a>yfV?F3S9?_;P}Po?FH^eN=S}CN?U#rxso%@+X1rhYq`a2guSuFS`A73| z^(n~)UDsS`we+Wmy$~A*Nzizzn_N&<2hu_#=b4PmY%9ixj~9qn#zh zC=|&S5umF{ET(_8<>y@S;jirl-mBR|4r@o6*ohFRiIJIUSDNa92&^ zlJ1hy-o^DDbAlPl-`cibziip{Tif)Xw_LKbZAEWMN$-lbotLPWW@LSEwKG$>#Max< z-7$K@lBG9{cC=LwT5MVVtkS_vy}g?TOLGhD6Te-2{kE>IZPzbee8aZR&TTg=zUaEp z(8ivgjf0_UK|@ES-zfJY3sV+&t;+#kOCDnI6;q249*cTJJY4&vuMT-eee9Gk^P>+G zbEZ%JnmtoByB$Bb=Ve~OJ~hlfdDxSSXj>-z0sZ|M{Soi>$kd;o?72Cc@MX&17>@3~A~VnabBEjP@cqJ`>p4uk8+Tmug_a)hM(AR32YZTL z4=AsT7P}uOw|OFMn*zNb_Rsv}P0^3}mwFrN8Ft6iv5^1dLUR~rHP;Oz|H+;FeE8ht zAI$fXK7iql%I7)E-^HO2n`d&HCs?{R1$sZ2=gQRmn189a!8}(?ZG(B<%jb#t;7oa& zf#0AN)u#L@ml1wNaL8a^NC|&D0S-MEoG%n=#KHT0nx20+Gh~5TsOVLmCZq>!- ziTO~z_sj4@ViV(*Yvl!2ilo!|^prD~az0Fqo9_K^yVVH+7VnsC@&fbiXZDWycJa>H zkHZ$5{p|aeZ($sgDYRq#JYA+>kSW;WE3UA7D@yV|o-a1t!@h5xKkdAIGAbW<7hxbkQ$Xoav zEmC154{wruLLIO*=!^uN)V#*d>akE{%&XUK+L#z@X3FulShGg(7C&6O6aT}OEE)ocTI#}sCy2795 zdhPeYYR?Os{l)ITS@Ht@UpQUwiGOjASZumk{=WGz*EUjol&++ap}~@+P4vz1_-9gi zSwS9UXGTRcKl59-12TLUTKL@^ij@|el-{J%lHI=glKG{Fvg?OiTZikj50%cpq|{qd zlM|>e$;v9J4&>C7cuhCg%-h-#?5ad9o~~fW)_FDTP!3|tQQtHtr-pvgeMpv8Kq&dP z<&U%yaj;OEQipiiJnoVv~$8s$fY`L0+ye>^ zS4~YS3OovqEEj9{R{ab zaJM)vP%Xv&u;%9FSP){;)YsS2)xBbY`af(gHAA%(RMh7)HrQO(zc{k+&LQ+!ZCW5Z zq3ZcxKc;CLjcK+Ol>Z+w=Km$Q^{KD2_d!EBQc)z|P0X6&rog~y_lR4eFU;u&rE_$m z;Z7|I)g7>~lM9x2ceV8OHJRMIIt8HkGG`;qxf z3)uUhpB$+mlAD==S{sJ=Xoy;b(%y`?mTA~bS}VvMY2GSAZ@7XL0Av|Pu_Vr`bD<1 zJv#X4fzNRq8TtW^zH~UOBt0O9oc~GQn*df-oc;gjoZL10p4@~aH~YRob_fs_A%U=OvI!vx$%T-F zB&@Q!P{j?GxV6S(L9nRD(yR6EEXH+*Is9IxxNg6GfJuPqZ%H7ixGMDwXZ zQjK%61#`z{)=YDn<*3-GG3BCsuaM7A^?a~2 z{oxU92R?H=j1s3N8J2_6rqo2F6ebD#+brxBancrMrgze$P@Y|qHz+wW*lzN-&rE2q z9yWJq+_p{SW5`7|JEzrTj-6YuOvt7pJ?|c>oUc8AJ(VDhocLf0&Kp7#8++2dWm_iZ z<%C;b->HreuuuNNnto^RhC>7R1IDjLpn0E6dI+EhR(7EbdbI7438C2%o12!|5k( zi-3JPRl@yxitE(t^E7(~KM}^*M=EwdsJx=>rm+zEOPB>QlP&~#pzy<9|gFAQP7ZVx&6W)JS&p$<)`6y9$^e7s_(H3DPCLxg$+I1n;7g$0OD{}|jhw%gk z5c|<6tB)r-g_I(tut1-{$6|G)*?TlwpA4`pw^Rh?LmDFsBl)1b5<7To=HQ9Zj){Xa z#}1C&oRXTHyg4N)HDy9X@svUb-%=fgQ;H)ZatF(WSrHLgh4SFs2)*ogdw7S0h=@L6 zLiZ8;rAUEj0rb5Hm7)4wq_qDg;hFh$U;~{fTGwLbm6HwY<$ET$zmh}l!HJ+q-gd^v zXz3}YFzah+rxjTb-bPa^D+Ahxh{7mVo5&}R9_@4|%RP5}*ed@HTFc!pD=%t~N-+`( z!kAB$LPNx~v%auR9HJeTjh|`80qtT(gc4P?IB=t_GAU)VlH#niZ3tXE9+pSf zOq@6^kqz5JvLfTtb7gsA;A<`_!VW>DF{{PBQ^4|9aDe z8*i$<@y6<#Zk%9w!~5x`o3JS;@13S~N}Z+rd*8k3Ch@L$E*J0r|H^#jG}AVM3%(@9 ziauRXf;!gGxF|kz=n53ZMn1}vkk}B1zG;`?kiMNV!dMuo3pxS%n`IsmRZucKIem0NOskxh95uLPcv8mbyqFboI=RSc<}Ve_TKwndYq>2dJ*zM| zo$2CMc~EjxdUjz_#>ni*6*9A_vNYBFYvpz8dMR0AHaso{$AO^FDAxthT0kGI11;#EZ%4DWU0%UJ13Jk6sB%C=Ol}(R{=(QEbO4jl!=h zyw%F&N0rVGwZ^WgObzaWihNmNFJNiFmp*rVqkJQKFs_nWeJf%x8>bz^BaexC5yX(FlrrB979p z9TB=gA4xC)x-25f6%huAcGVOWCl7MF6WxLQ=a%=mKME=c+_YrLMb-$$6`ShoMcvAm zocu(2S-X!mV~jD67(@fi{|j}K4x^eTQE$s>7xAp{kKW&l+?jAT+H_{Z!wjRFU_-^p zr6Xivfhfzj)owNNa$onWUm0ZR^3-cSuB2EW#|CE3R~GXIdIP7V?3>WlHNmp?eVV9h z3fF7eprlwT&i34`w@xrGcz?o;H?n>}`myPK1B>=pAA--q?$?J8i)i=tH8U=yCOjnC zh|M5;Kthosj6j+4o*~nRCMFJ@J|u70uslmpeCee8{7I$p7gUs%R)|XY#&n&$$5KSP zq78#XERUfL6J511XYmryQUAEqP1l{4x}N_33f+n{(fkE%(e>DSnbJZ-+6c=(z==kn zEU))Wafz6t;>ZTNLVRpE)M%#^mTvKFpf`kGG9o-R#Tk#AEi)qX9B#HVoLh>5caOQw z_|VXJ<~;HCwa>nAN@}O0Xi7=(lp;q*>XZvD7er+ygoY+$MnxM}IWA}N^2*%m;<&it z>fFlZlSP9?xlAjS*DaBHxd!?L&q?$D7QvFlP4KZ8P5%D4@&n{`O(L(5_9VZui))gkpHKJu0 zJVUe+GX`6JA{vGZyoyX7q_@FzzdYYE+0#axBL{E#VW*|PA-AF;*PFcAZ&-iwCGpT+ zW4d3-{;_Gxr=@)=?WZUHFXx-f-6p@v7`Q;1RT)u`pPiEEM2#KM;UWGutJT<~k|u^B zeDritN`H45-G7%V6;2j!$MvWqE^6cS(gAx~A5IiU_Ak>y$o^Q7+a%gT@PEahj7bQBx-7+C3KGI$8>y&S_SCQ~2 zsZ<(QIi{H1-l?*gsP$G~tVKG0lU!$4FkL;-syJ%M5gmYgpm1g=&kla2bJ-GCHm-PLSlM4VNBBYiYt&)Q!8kpvno;x#)O59E=a4$ zj*7~zNGli}7BTGcNlOFOt(|=F!8*lf~vLF*FwMGJA6R&xRqwqBa7c z>1!cb-JUj5P7cEwW-6_@b6!}0^*nXe+;D&ESZj>?k*JW}a!pjoqdG07sY`DU(iRzz#smh{LMSbKlIW5{Qr%3G1FaS%hs0APL13h;BO&> z6+97ks6VEkaR{UCYzgHnH8sb3S05j#3JHChG)xSn?aPtl;})JFOByxjlBNk z-}koWzvK>azv_O?9r99s>s$LzxSxp38kxCfc5UtKHJKx`BK5TkmQY)^wUWaj5fAOsC+ak@2 zd7t0UlD_AC;2!&aBJIyTy|RgZGP7I z#DHM?t=KFVgZYJ*Qy&vD#VMvXy(7ce$_$BvRea2xt)iHi`NUZ7dlpm8c$Sxh%g7#@ zn#AGgx?|Ls0A=@wcORmOabt0z&9AieR~?Oy-qU^8{k2`!Ufc7D{`tPzuIsL~j;`*Q zniZc@oD)BL-t~8SJ{Wr4Y1(1)GruPdlG+TK!=XitU5%lka9uT^M+RRK`baei%EY+> z4Pq<3zE)K{hFkZH!t_097K^)#q8OpInbSzhJ4;DCw4YH9^K*juqMZ0y^ZP#hr}BNK zB^#ZYi{7SHCL4-7aH3LZE3v`{s;AiflU_o9YKpSv3H3a&|E<>i7v)3D2Ia|zUdnGn zJuQFJ)pOR8C9@3m6#Q|yqiq((tA0|+V;mMy#j=1OJ6H{g(g&;YoT(y)tNd9Hi1F#k z;~OlOxIeNH4bi%3$u==IrK>i-A-`e$75U^#XFr$13_0S!5AV4Yo`XMJmYU?Gvz@Ww zV{Eh)yTwmEW25hgjmEqYslf?x@dZ)Gr?iSS|3$$}Cnb%_9XTOpWYeVTn53AP zk{P2!&*F##f16Pb(_HxtOP*eiQI#XU z=X{O6^3d;z8D<~m>{03||J$W8C!AWE%5?XK154wWgrw|u_9M7(P2dYQ%fCSJ6oyEYm8D4r__E~k#V7(QjbXXmRc|Oe|Wvs zn~76yTS4C(B(bwgO#7S}JRLFn;o#{UM{FS(ADSm42zROI|2!*C_P1}%j*rXEj*HK> zUge%DKX_AIR#sd>76y$X)teR*EB%m815q2firriU7uS7@1A??m(vQu=5`0P~yL2Ns3sVL*t8o4UtT2%#sc zF+N%7j+Ua6BhtM4z`PwdF53QZFY>W*egS4%?C9Lo^7QbIl+;1_5!O51L;ZXcW0PXo z_$nv5_oZh?N66!Z{nA9+dCZbV%EVLd&tF8iKowYmz(Cya+(Hbl+y8SSENN#D;RuI_ ze?1RG|Mxn&ktX7Mr(vKISDINUq(u0>#1cyEjzyGQ-<3gwB#x0fBfht1y@7YRf!BK= zKVtT^+k+$GBg;#N4T(vJ2xhT=V(Q}jtcj(Gab+_~3MVC4M_NTJ@5y7w)%XVm_-5xM zBvi~P8!~Go7Ad)l{_S;iCQTwP>sjbyz`)1=%dgK;5(Klu=ATQY`I$Z{i81b%mE#;h zrI4k6Z$9ceFMmgW<1ZzNGY}K0Y5gp&Fj_(%alC|n2$!gPSs7T}9Ep__fcGc-97kde zw4cR{W3jv~G%LEGEI%_TFT7o-qdj(9!Gwi_3afI`iXyDJ5h3FzPZ}BHP;4jL{CqPL z($=*W&aO;}3jYEjGwhk~=#vDUm6gNKK_|5?>$T3Tjj)gPxZ1KZ<)2Kg`N8j@_CJNE ztWz@g$QpJ31Lwog%zpp*FdxT^$Px`}dunP-K}1J~wKF9H*NlOQ5n-SGsPt~R^HlHACjDK=wVEY*6{jIYy z@&eBfG^HiE56I625avdfR-jW`@Ezzn+@Gh&j(U^p#0RnTRIj>!G(+=SWH=|to1s`- z@c)N0j>7g?ZOfJtr3T|%kOa@UAYvai3xdTogBhFDEG_OkA4H!T#9t|X^WiSO)><*Z zHqXInDJ{^So;tTOj1v(0&jU%66OCOlOdv5d8*Uu%AkG8nJAhMPswvCED|76D)f^l- zY|Wa8P~Sjb&WZO|BBCqIZ;T!Goxguxz?$$Yr+*O{ZYK1Hby#?Wkd0B;NUJRmP>zDi zTz|YptPedGflw+dmu9nx<}9s`7tIr>-i>BK2M!? zzDa^OW z@1)c?@5FOjnG&$VKghh$Y@KEf@>_cA^(zAW_-3oNhcsPp?g_Bn780<@7V!ByHrr1_ zgW5yiH263QJ_f+Y7zuxOU*4FpG>500b@D%?z_d8P-W3wC(S8aA=-$7q>^{;k^ET!0 z*1H&*MoHNcF-kCm#o0LY2x2)D|BGc!`XmarT?YT@E3!*vYwBs+-A>>B_RIP5rUmX} zp)AFT%n(a$G9p=u6Dt2%EV}WoWf6;TtV#3T7cH0;l@T8j5}(0(9I<;ZQ%*hYhNvs( zHQANFTR5;*ru&L^Qg=+KNKa%SIKpvki6JiN1tMf6rjm5#b-^*C# z;?pk^>2lN=VP8&Lxqlp)nBQ@_NVrQ+7YXy73wY4|nnxC*J)$7bJnhCgWMUw_n5Fay zEWm;M0UM?IWa6JlwJGh#QhgSg7)Y~FyMHSli+!LQ*$4VC`&5Qad{9JF73-a_6vb35 z^Q^3B;JmrY2plJ35ntPYALW|4yTen$jh!3=xAW@3F-lK_JJZ9{#twg+jxUe+L>qV7;lYXT9l}>(DHFZ!*@QNguG@)Yr4# zbl`Jsw~F;@<^`-OdtWrLKQ6t~*Q*gwrGLGeSu9s8^{iLZ_K6j4#(K4}WO3`Qu#Pwh zMcQH0FsnmJQwU?kUWkXJyLF!G_lff~MB;?|d}8dSQ+=#*@!^1b+FLQGW0Y;4i)Bh+ z70&`!0_ufCWaMWU+o9t1c(|fAjYCW$ql~zaM&LoQ21;gfR_tF@W?uB0)g^OpdST^+ z?du!UYkWg2ejIpLI;CmU>}~T4GS0uc@eVevZ$CNLXSZLtPlt(EdDB-ue$lx2@~MTh z{7kmM(7cS;qVrdeDqm8SIXyTrSibo7s*qGp0~f+L+kK_E-DKt5t`So2#0SN;4F4QV z??Hh=EJYY{@zvt}%0dY7NHXslXZ49A`8@NaKJ^proLQ~6aqNm>je*!Blul%sr4#k% z;m7wrp2XvMlHJGVV<*hsxnCo)OkXCILnOP&W;*i))JsG&_naa{JiPvwM1bPJilM0? zDH$oLscA{RzH!-1xr-$jM%cU3zU^DdNya?2XGOAD+RvGG?3?L}j~C^WIJmRw>YI~C zFCISU;!d<8Cf4DJ0FI{yXw29BCPr9CMpo(Vw&0+kfGM=MwC4Ge>>Z*ri>yIS4`JY3wBx_f@Z&Lnj-X-NqFB>xNO9Un`gLzGgBkEvES8d$R~E!QLV>s7}ZLr+2(lEq{-S*&em zeSu@+`kt@M#~#H5@j;bNe+A*tV^$LFss9b36}dTKiK(d}{F5TI!U$>QiNhp3gAs^+ zvN$|WRJtx1OhIr0Gbd2ImN9+P?1D)-VV1}M|LnAxb8fli%sZy?>Dv|;hlEXv3J7dm ze)5y8?m5#hTT-gu2x?j`Kf4uvR>RM);O8*uW6wUr0@-GbV{Z=9?%{)<_ZGoTIVz!m zcv<2BzIj=iDjFkJZ&|I&C;G|0zCPmkzIy#MIci4_#?Zz*uTeiaxOUk3CoAyvtZ(V3 zH;PG1@lIu-L?}?Z&9|-ZHKKr?C9i>R!Cukk4wHzHnwk!S1*iRCvgaU=0sQ3Xx8 zQ2{~ordCY7bdgaTFyB-?ux?Hag;;t3I<$849a6G%^=^VT3Ll3N4>cNbzmc#6d`B{En=7e-~lv&-lIX{WE{^zDmQrJ2@-HFpEYINZAut7I*cCz5@U`j#NpS z*VJ0#didh%qK0c1KGJZ*lKh-$tE_Wbhg~M~!l4OMkBP3qxR%L}9&+Z8Dr;b)Qe0O`K$k1%Tf2n%*l> z4zrmM!$_9k!}mQ(xx9}GmVDo%eW`x$Q{Dtc565;~sLy6MeN0+%mf`Up$R(Qaeh%tB zF|kAY4-G%9^)jm}! zvU7vZ!>23#h`pdB(n0m{Fv;6I>Cveex04oH=zI&93CnT3uDOZcc&wr{tu?0;sC&(k?v;7jn@3MM&Uv z*ZGGjdyyX>sSz43g$7?%ZlsFX-kis(pZhA>C7Fp6Z*1=={jt5Lnpsmq1Vbq$Nkkd) z3-b%@i|s8)(*t_Ln23-F(Qz@|W$YrcSYaaF8UggzrWM8qR8(EI{Jim%W2=^qiXT4u zhUBqzmF|N+T4;PmWPb5$iv056lJflK*uwF-g|niPHj7=GP_5`Re+A9{@QvsMG>-cA zwkcw`r+2wirJBUF#1xaAQ!$JT6R9GC7*az}qkhXw$xpqf( zn6B?Ecjk#(l=(%%3+$A^f3<0 z(#^G`tT%Xb`i>7eU#|z9@SbpJ1*(LL*ZmTUV zuDfc^ysdc|cAQ#?nL`pwW{*fr9yzBdZ%q8WfFQHtels&w55Ks53E>wj18si3VS%=k z(H9IIQ9C9%IPjuCJs^S3mzQlc z9pNML7sdzgoiEjdC8qbw0lhsNUi8^W-J&X#SH)M%s~A)qN8~IeFwj0IqI}qP(~ZOH z&Py}f!n4Euf~;ew$s#Wy2YbkCknlzN%XCbA<527qdCEjK3Mx~X5erF8OLdC6VOs{? zUlDlI2f>dD6Sjs=9%?Ekeh)dr9QHp242oEDBr?hwbz;3E%KjJMn5gW_FE>~C2Al{E zaKAPvz(3Lbt3ZyQ2=sIRUe{NHj!@_@>yj@rrnNVM5*REuOXiRe6TD)7tO!aH>YjDE z$_?>i-Yln$g#OsG&C8XqG(^}ySM{4lhS?q zV^fETY28vW{pYiJozFYLiD5}WJ&LlfDKyOfR!E>V*!G4k9D1qcm*W%NjR^_zEg{Z8 z_h1^nV0T+`N?1yWd`+-LXjY$0MMy-?V?(Z@Oqobcit6Y02q_{YI>c<(gMh=!ff2Ha z?GvKBJU%4Ck7ib0R}~WKCvQ*`k*{x{{GQ0MTG?w0bjOD#2g{Fm+K`p-;hb$hf@d;K zJ!{*qw{d5*{n+gC%!yT16YJ|IEFYJYJbrmq{pBY2_~Apxy4`Y1@`%}m#d9l@-J&9m zHtgqm{!S6sEl!sxX4pKg4bO10Ppm{xhOp3(AV0gO{~16-1bsk0V{1dQ^uEX5nA6m4hjIe?$`(thcV-ur=quv;7^V(tP~nt;$k8Zp}iU z?aC9p?~Tu1vuEf^?2nNmh}VzeR5 zKFMez{il@=g+rpk^jR(;#>3dwJ>YAhsqn*%xBFOqd@MfQ8$Rkxvt5WI#N=zf%H#;i z2#qpdW%e~O@Vn5*VF>x>zES@EQNHd7IO?7ek{%I}9wOiGPv7mH5u6$xo*FE^LGzz{ z{-&6Skz|*M%?W>vpxQ23V!K3D1Kgh|PjPP2&8NLs>faEXYCp}`_jqmig5QllqPPVPQ4dD)$k7`WRU89M2b z{+#-Al%)pKaygH^FZ%vcvF|68>=>kobydce7BO~X;6cUsh_!2dtC+-71NWEeyYtw8 z?s5Cbc?BgU1)0^QPG@O#runk6+?=wRB05gi*dei^tpD1)NBG>JgjqVIM6t$11g;eG z1DlR|CG|nPLs2b8xWnk=v`l?g>MVw>?gonrN$$-XSK!DPx2QCxth6v9#TMl6 zNXkhVT^*5ERkYc3Nl@Xa$ypWihdXWIiHvTR6O$?m60Po+$%k_oX*o@QGvBAA z`Rs&6oVj)K{!`C?$Hz+iF4Nz{nK9xSGsFT0c?|-R3&l!%M`$JFa=aswPJ?;LmlbmJLM-OM=c<6cDpvR!o z8q#CjW?EEoAA50AO;w8Y{g4i#%$=@AvHnfR+LP^z0~ldV>Hp3nmC*}=RK zN~5Fymn=qVsT>`lH<^i|L*`I}!VpVr(x8rmCwiZG#>f23&F=GJobp2D%9EX(1h7@v ztio>2IQ!Z>R_Enw1}|kM9JsHaU!>pPkcn`H8(yEBPJ7iQhjfnU+1Rn7fwU*q^m;n4aqFSefkqSzB&)|aE# z5q$2PTl>7adhDR$bHB>g85`}u8ML?hu!(IhQHLaPILhGs%=DC`c#f_KV28V8OVJNV zIo&7hwQ5TW6OBWhL>K2BOIxf1T*F@^kEtEL<%UqX)^qkrLF>r*T`Ma?9m?H4`7>5k zjj0`%9~|XZm^9zjR_c0aYt`WV{sU9wt4B0W%>3ykCubUGp5#QuRCM0coHc0iH5cSF zYz(c;7?vJ3e)|g-FT7*aQ=aotM14=fhx(#8w}R!GLZ=>;F4g5g#H5bV@8i|c@9VOv z9W{;j$uX~Eq}ga}VPSO(qm@Q|TNh1bJ#B}h?_g1!SUw`+9y_B3{8kw&+R%2-Z{9`0 z3wTKOnF@#f$uUZbWawkIaNKT$-jxz>k??e$5o+?zlBi5)*qFgeY)NF6GmL1o(Walz z3y95#9a^Yg;<92$M&{TZw@(hXMwGtJku8_P?_Ed!-dJd?4^m`y+l7S&2ik2`ixeeC z=^ac`po#I`2)0;8>akswwCtLRQx>$09aew-w3+jZx2)S7nL60=)5xUsq{tOfNf}8| z+c#zoO%c8n@-=ORPnVIe9)C~IWsyEI7ss_k6|2PUv%ah6{W{wgR6#1m<6j1N~Ui>hBMBNl2gA*!! zvB~+vrlhqtDhS0^s352wu$Dtq5D!s7r{16YXk1ba43yabB;*?$1t-^h`x5O3p5wI68AYAu#lMT1q`V23?hB(iKAXf-WAM&$CWp zh6NiW_1`k65ta4hsWDx7HfnTw{vG*5+uW!fvPqUtX`3q{(`vp}xl_K29rT=EAm1f+ z(DTeHCRgtQ<9Ev_uCkP@U2plV`E6;Goa5O$UXi6J*7CCG zi0}}6j)|hpXSOB$l-p+Gwr7j{5XoYf>=vd;OtPuNSGL<5CfdvlmvyH{i}9I#(pKwI z-GNxIZ$=mAloX!wrsV6(5()9P&~xE1;ayx?XS_N@f0cv#+E0D|2VccRIrA+mc~C3F zG&m(^-B@E$hH$Ho8aZreNJvIRc6f3`qMw*L_HJr67S9I>cZ5%Y*pm|kvSnh!F+nDl zpBke${anuQ$SC}MA-WI7^l8O;Gd9o4;c)Eg&81O!gu#i+LgSS@vg?g$D9S|s`V2hNuQ z0~`Fs>_-*}jPxeJ0t0_jpnu&DCKMDDFh>dq2%0ZaoDxfGVvxW@)Bjl#)LCA%zJa!- zdBMDz2^B+&i-r{BcuMAXAz4*rWmQ?h-)5x9;i>6G;&XEP&XA|0i(*LOEGbg!RX>WGYul%LBgE6aL1Iwd7KH_0(5FW!B1WKdFE zcz9e=P^7#gZ;&G?SNtdkx8B=6Y*_oft=)-JmaMOtuxUYY@q$egYSu5AlGuI8o43rE zam$;RbeAufTRS{w>C%N&+1XVKmoCj2UORU|Icmv&@vJsLBJ}^BQA1}Vin>`p3f%y>!!9g z*S6FJ6n_ToHeexhL#R~TGdkD(C+MPYH-e|u5nIjYiKc^ z_B@c|oZZmg;c9Jh4$d3gmtjX;yQ{6UBd^2NoY&gkm_KD)O(toQ^z??tRn4{SL-L?~ z7=+gh6L)hxx5a0u(jW1rYdk7ST%21_MyTRp&H=@0=8dIL-=UZ5jI>-G&RS<@du@Hg zirV(&&eo;pWEKoMI~Px9s?NDl^|dRUGuPC%*SFR+IR)=Ww|2T(os(V5Tbn!Uni^K? zMbWeGsD+X3E|GOx!_wNi2Itb+6|UxW&iaN9S7Qr2cC{D`UbSKcyr!fDdXf!mI~(Bs zS$;1R)jp@Ty`y$b?vh$jO`f#c&y)e9Mx84fAj6q7L(d~gWJz&d9Zl3rbtf!xHFP*( zeqC*Q!_rmFP`9KOnS$7kR>Y#M6;e7~wc>}m)|REsuDVWFOQW-`-PPLe>g462PFJV1 zqp5XObG@^pp<#t{S$}OU1wxU%8jm;+GbIKuFj5A-$sZUVOEE0eM3i{b0+dx*Ie7t;i}{Lw)WPx)^_Tn zr6b2l-kq*GA#~8b+STD&(%j(X_^P(HhW0ubnB#18t!~h3p}C>6v!Q)yYx{~0qoQ23 z?arp!_7$xy>x^n?ZfF#o$#af^ab(;f6sOa*f>Z>V9nB35%em>P_2$;r<<1qg%i(Xs zYF9mc&|g9j#E05WT`inzYCF7j*jL{|5GX*yYM9muXB(RYkLz1Wsin2kxwN&pxpfUB zQ6;O|1%qJ}0%LHaqhWg06tTl7vo5H$&ZP|v&7ww85yW~$ zXHyRRcEKvWgq`iJ{MOOgzN)TsRXg&~-YUvMVLNM=xSCy^25W?zx321FY3QI%s#}C8 z7m8-8D92M~UG7C$8`~RdJE@R98PCx5N@Uj5(A*}-_+cH()FrlcHF8i`P*9NVY;0cF z)iXl@qQ@$I74MN3dUb(FKMskNm6vGa(g&SSlqa-s>&+SSxX zt&qc|yd}z7hk!LU{7_@dA%c%zwXD|Z_y-xPAGp_B%l z2GydJjnF9g+78$A^cpB;Ntwa%8a{bTn5*-o|7q`igIE3cPp5Zas@^&-rj84wGX38Y z@^GG`wgg>*yG!-58|CuWmpA`&)8&E(PErt@Z|7Q1X;OU@7h6Md1viL)i z+AnjXpioGbQ<{k+iW;eh$~s*hy>dUAJDs{LI60WZg$@X<=+vKTKvun6aq^qD^c|#S zNTiStZ>fdsE#;Rwu1@{a3Vv<+NXdS3#%H0U_6h-WKr5OJ#$! z7Mg@?iO{P6pQJY{J69KGy<>NQBn60TltI+ZSw_YZM5;}jir>NFeN5ZXHf+4q(s zsgFvdb_M^MJo-{iX$&b6t&HHSkV+@K6SXAxD0Il+ouF69ZHtGq9Xx5Y7NXrTxFTv$ zJY~EgB)Ww(nz>uY6M|Qbq~1o_LhHr9;;zVfDEGxTr%qj~p0D7q;E<4Rr?irL;t8XD zG9+Krew&9@(T0h#uF+c~(fX{?-|nxaCFEJ}X?Km96g9I-&vgyIiL#2P>&Zu?D@rR` z>Hd-$G&k~li(XEz1`4_a_s*TSNK3R=hGYpDT+e6Go(Zim+Rr*Y#}4iaehEGryb?W& z$l1^jQD)J88s!%E>U7FQ`Uc-ub5EqPgzth|r^@Im-V{30uIC~6D^e3>5Ct8)yqe9T?Irs4;ZCnfzMy-$dKDoOcCvqOEXIgF;6K=47-8-aDf86*^|L z!lK@UE{d8Lshqog@U{p>4T!vqeopXA$dBmxy>cwtID@7ZK8gGU7lm%LlAqD02tyhqKlU_4IzC}I*<)njO1x$Q;-8_1!P{KWk;+wlyZ z6_kkj^QI*@*bMbvp8hlXF=35)+gQO9QC6o^h}9teviaPo)7SGirNx#Epq*#cSSuLGz;E}7S8xSUauiT*S(TZjcq)NCj>8qdBdMq&tIMY%Wl$^`< zJNp|#KSZ4wH6hvsudR6Y=YM<-KhCyh6_EJPou`K@H@*z~mzg!@VuEzXuBz z%9<&~)U9i8mNFQ+E|*FeNwqMZ(I?t@TFk2x{8uESe`6!vfNvbMGvJ#zUCFk*p}j>K za^}CnPbHO|`7a5}B6ZSX)*CM&3vuzGZkKMA?vq*h%1duGu04zNaoupGalLY=alLhyalOxCT%SB)TwmF( z=Z*)J?mel*THYI-m;y)k3&Bce_;}|5m|-f=ep%#9zU41)mOnZpgcZlM631?o{R#T~KsE;R}T?h_nh%6vc>l zc{{wQvNBx!iQkKM6un^FFFR0PDJUpET3I!8^3Y3$ULxKb`qc2XBQG0%fX}z`PM-H# zSyj2Z@}A1KNBNH`8Pzmu`*}O6o~pj9=8Z}9lb)FR{Pa6!-Ee-)`7_VI@%(q^wa+h_ zzwLsQ3&vegzhv!V%aXNAUZ^|K;Jfs<%c7e?o5s5KFN*Jjt zwq4M6&#F&XCawB(-2>|$Sha-D&FyLJRh=KM`c(XNe#l*Z*}Pn(d!;qU$lPz zhL{VtT)2C~YZo5f5VP^XhUSe2Hbw*S@6CL_Zo~5%Z{F~le&+yJ@tgQ%srYr1|E7C4 z9lF?k>CtVkUGe@^N3T3^)zPcBUt_yw+cl31?8v+QueYmrm+gAvo=&9I7t|xOOQkDm z9sVSJgrxsn`ds>jbVx3c9*|4rq0(1!g*;w5B3H9mSmRja8nNV=KSkOr`EaU*Nt|q< z{aOmso|7WAFQgRh4^pc3yp*9mE@f(em$J2orDfV9(njsDv`IT8U8cPvUCuhSE3}uS z=e6HUFYx}$+Golr?OEkKFaylf9#)#P12KDZ%!}ME{n7d}>2+(j_PO=vnr8hqzdy?FyZQYwX*7Gi1FgT|nJ0MW zzxn=Ko_msfe#di9^W5)w?iubs%X5F=xj*vUb9{e?{NI&cwDw3J64!mAb)OV%eP7yR z{XqKI`XRA@KhnOjek=u94`|O>4{FcZBDLp40rMqke(ywiU zwLja2Xa{UlwLjRVf$3l-m<{HD^TAxuraf+33EH*4+d4oeSOr#tHDH7Gux%sQ1U7>$ zV5{V`UBvZba0$2+Yy&?5mq|so%jMy=?Q)sz3h8p&l~S7RDk;HsHNRb>J#5d{zOYvS z>d}4)*PFD%_MO^C_BXUw>~Dg-+MD*b!8_nx&;#BB`@qNAOZLBm{ooUD0DKM(f-k_A z;4AGV-#BTjZ@jd@H$jT?b!wmaCh|Q=y4E+D?-_i~wOpdTEmv#T$TPHeUXusm#und zQm~W}=;>5cO5yS-AgGxp`N}hxXPm|L|BRxOrk_f_=cFpg!;??p$zgbMkn(><`43V) zm9l-NJg7ZG`M#uVZ<>CpeMPxGvvZz|eK37`Aa8w%O%*BCYpOh(eO<(R=dF);>ua9; zh$kcM2~vvPDP`LerD%JS;m!Cj!D5Fk`z+4clDGSw6Ek+?Jx2;XqcwG1uZW^ z%j?kcozkcsBh>>sE!S#qK+lWN^QJjoJ7(So-q(&q zlf$df`7xzbX{*Df_1b=F@;m5#os_>K<&UBHb=%#NzwJHk9s3|D!XBr6Lm6TzLl9*M zf_{rVO-iH;30N?S_8O_)B-LssN%=lf{1fy~l*_b3ayb~M-7O!|-j@%9ueDFf?Hh7? zkKAr2x7*0=J=@*d8|3yjxy6y&JLHy3Zc*eG1;@qW#T|M$_XA)s9k* z<8bIJQv8$@KPAPZaOE(meriw9G*V!9ie!byHV_D6!5|O^oFG#>!upDLr96-i3bfCp z!P;K-x9^n-K@lhhC7@J$hrRvpNabLt_MSA1dlg_f=kAOEBS9q?1xAB0U@SNfj059A z6{rRiz(i03CV|Od3YZF}f$3ldmKHxC7h??gDp%UEmks9`H+WFYo^f82a{+3I3Wowa?7q;CI?V^V8s2 z?EsQ?$owLoUji?KR{-ZQnS0R35464JPqcT;2eti{WbHFc3P{u5wH(*>T9>1r&0qy+ z0qx)}a5vZmegW5=vE8h_Yr6&93cA2;U?;d8 z{0wx1JHVabE^s&41%3hU0lx(B)&_5F_ksJt1K_{FgWw_XFxU+q1CN8>fG5Cjwa;u% zf~UaK+Fsl5!871l@F(!R_Kxk(;05p(@Dg~L`>%jk!E4}eU=Mg5yaC<@?|^qf4|osk z1MdUs&-Nks82laV2cH0B)ph`U4i0JuZC`?~z#(uLd<~9(qu?8G415c|1IK|1dcg^B z61ahe)gS>GD8L7pfEie58?C?w>>vOHf*=q~UlamDK^QuC7=`x1;aoE7!F2&k)RTc0;9oLa2}u! zvsZ%&U?QjilfYy!1xy9g0R63frnc8U3(N*{!1-VcF+yHI@=!G4p)~h8^9oqZ{@|z^}oh06npzCwBD2j-J@j6Z?OI--0K> zQ`&y}@4(aG_uv`uEcgTXBlr_|9{d@+0R9603SI;+ftSH6;8pM%*aKb%Z(#qt3HH*< zz75_1?}8ri9@qyykQDoe;A8smzk~hY6L0{04i17Zz?a}Fa76pqeiVEIj)8B%ciP8T zx}W(T(2n_j4i17Zz?a~tw%7L?a14A4z5~a#{k|&b1t-8sZNDFF0X_`TV;eo8ruP({ zmR+>qx@I8pc#(!`Z_#H8+xQ@M%xBmy!n*i|eqbNg#k(Hs;v3qv574PkdGjRta{}8$ z!3G?vJ;s~g(Tl!-<@^Sg^BdTM0Um4l8?5DQQoEXz-X`DO*ja;VagJd548>OQ$J+73 z+R4G%8HbdAj?C95>#vJJk(5-7i!bx3qU_r%TA$cp0-1$tcmOQ zQ#TdrY6NwR6Pp+(HZewQVvN|t7_o^lViRM;CdP<67$feW_u5JCwUgd!C%xBBdas@I zUOO2h?qH0#gE8U`#)vx@7w%wOxPx)w4#tH$7#Hr)OK+o;y0n~AQU+S@U%{gu-uQ~z zIqb3C4`99T#WsBj>-|m2c)Ioe7LxSRkF?%DzZ z;)B#5h4xWM{4QZr%Zsq4niy?7$SCMBZ6EaRh2Fy+>pW0cM0(ypdJafgcyh9}d!-!447rRz@<2W)01Lq)uo%>WC7=#4 zs={_vv0YVcR~6e;#dcM(T~%yX728$Cc2%)gRqRz2TUEt2Rk1gFu{V3A?b>l{%oB34 zKCXIJ9;*FD9tJA4Kgy%PICN#2c7PJUNlkr)-Wd~W921}9d6 zwO}3C0Jdr;usv05&J);~Dt4xdop}OVQ8itweG1p!5?sS>RMD|RNbw=;MirZ|7n@MU zCRFi0?ZNxB2k+A!yia@ZKJCH#v$C^2(;mD|d+<8#!RxdKuhSm9 zPJ8e=?ZNA`2d~o}yiR-YI_<&hv$C^2(;hrVd+^Hq3a`wsY~!?E z+jvj~s=-81115pVU<#P3J&CqGiMBn7wmpfqJ&CqGiMBn7w!MM2y@9qJK-&(WZ3ob{ z18Ca;wC#XxJ>HrN!3OPKwC-NC?q0O+UbOCBwC-NC?q0O+UbOCB+qK$jw(G$4;HTh5 za1*#$Q?WNy>`fJWQ^np?u{TxQ?cisi8{7fz1b2bE!7lI%a1Zz;xEK5i+z0Ll4}kvy zNH+GSioK~~Z>rdvD)y#|y{Tevs@R(<_NI!xsbZh0*k>yCnTma;VxOtlXDarYiVdb> zgQ?hHDmIvk4W?p)sn}pDHkgVHrecGs^cO1qg^CTPVuPvJU@A74iVddHhp5gQ?hHDmIvk4W?p)sn}pD zHkgVHrecGs*kCF)n2HUiVuPvJU@A74iVdb>gQ?g>Dt3{IU8G_csn|s-c9Du*q+%DT z*hMOKk&0cU+Mm*Tu`7D9D|)djda)~du`7D9D|)djda)~du`7D9D|)djda)~du`7D9 zD|)djda)~du`7D9D|)djda)~du`7D*A85zzAA%$FsYk&#;28K8e5akj7Eo!Szoeh< zrJwJmpYNrg@1>vb#T(J@Q8}|su4I%s3XDVBr_pQ9(7r+Azdc9WydSMS@FP4cM%(Nl z=i~Ttj?hjEn3xsw5lJF!*P1GxA5N_ z$A5Di|IKmyH^=ec9JhX>9mjuj9GN+RCGb~#9+8xi+7~v4XroC4H*Cg_uo>UMCR%%c+SSpdBHGH^X!YCi*W7}?=0>=4F)jZK z@?!ipwfJo6Ks{cqL)s1aaIVLPa}BwUC)X5m4aas69;4eC|88RZy9s?AiLO?mtL5lw zHM*LHu9l#iOdUUfM-7G;jXECnJWL%fc*e#ZETMFa0 zbjEFIjL{+(qa|Z8-NYCznK4>2W3&|8m)d5=Uz-_!ZDuUB30*BmR}<0EVT_wn7%!z^ zVdbHJkI{RT;af_FOHQn^_m=0!unLtR%Y_4;_ z`CzVg3*M$~yiMJBo4V<#r{irBt2O(j$fYf!H(o?*l3EKJIskPBF zFT#s7A1~5;yh!u$BFz`lhZm_EFH#p?q%OQjU3ihY@FI2LMe4$f)P)zR3olX^UZgI1 zbr-$5i@Bc-c#*c!ySFm`vz{J)hDVBjgA_j|kJc`d#~`s|xt_;$9Dd{p+D^F!^h@_) zr2DWg-TSp3JWw_C{H{|ZeJpcE6TvjF2y|#Qc%f>r02a~vFTw-Wg$Jq&D_{mzz;s(ztTs|T-F4_>bxyk0$cy?XF^_2BjD!Ryt7 z*Q*DwR}WsV9=u*Xc)fb?diCJ->cQ*PgV(DEuU8LVuO7T!J$Su(@Ot&&_3FXv)q~fo z2d`HTUaua!UOjlddhmMn;PvXk>(ztTs|T-FkKTISLhE$47VKx-?*?~(JHbEFqWu@o zKL{QI4};y{G4MF}4R``Pt=06ke9!XvPvCj*XYc~}3wQ~LR`C_C16#&De19Fh0p14h zfOEB$AM)GB;O}5RKrZlT)!@;p!J}1!N2~jk7WJ^U3y;<=JX*W(XzjwIwF{3{Hy*8S zJX+m&w7T(Vb>q?M#-r7ZN2{Aw_?Es_Sk|UvF-_N7V-r_1uxOL@mf6PD4nzwb$TbN3 zn3j61wg~HH5!THjteZtxH;b@t7Gd2i!n#?6b+ZWTW)arSBCMN5ST~FG)_s;%qqp#L zxQbSOF4uWrK3D`6gLAd~jr`UGTwobk4w}IV&;r(ibznW9ZNQRRgeA2|?=ddsdI`7` zYy+YPxt!~EaD_I%uQ$1x&$JtOnC9bQnvaKRJ|3p|c$m8IFm>5)0k?uKa2wbOZU;XD z-Qefo4sa*93)~HMfnR`oz%K#q3m&E}JWO49n7Z&Vb>U&^!o$>shp7t>Qx_hlE<8+K zc$m8IFm>T!>asr$egmEW{|$Z%o&-;6E-XP8mY@qu(1j)F!V+|03A(TZU08xHEI}8R zpbJaTg(c|15_Dk+y08RYSb{DrK^K;w3ro<2CFsHubTQAmfqB*qc$l{0VcLp^X)7M4 zt$3KW;$hl~hiNO;Vk_2SEAy@EnQvXseCvAVTh}w+x}N#g^~|@fXTEhk^R4UcUx6dq z4AEm_RnEYwoPkw21FLcdR^=k!9&IN*`Rl$1v>xBj!9nl^_!1n|YD5o@r>O={Qw^S` z8Z1zkuL^p>32;(#`JtmkH8QNUze)9s+8dZBS&y|@s=Y=p^eH`r@Fl&2?Ih;!gvBO& zN&B!(KJ@sKda*@h-T(5qXMDbqzBZ85t|z6(Ny&w^_A&k3N2It#uEsi>CIv7@8p0fD zApP5OSZ{y9di#R@?F;(1c>1*8VZA+x^(L%QLB$@ZxEv~4q2e(8$U!I(-ua7^+a#7+y{9eZ?^_!IXO-lVSrB<=Q zk70u!q4Z+5@IFd^BlhrL!ED<6n9i|I*9keB77Oq2E~T zX5z6dl`6g`)elJZ!+$tcvFhP7X#4^izktR+K;wJR_#COdNNPu*@jd7}27Sk%>wV~Y zAA0^v^5gE;-2ED=zc4>5MZ%*{_!0&mLhKn*usv5=3_qgm+i6Lkz^fj`THjV_IH3zh zfRUgQi~^&<7%&!`hxdIP7!RsIHJHHtiCk;AP6Cs`6fhOgVzTopfW0aKtUn1Lra}NK zFarp^7C^|)0M?oYNb|saumCWokrsnmutZwMDz{~s{b(KJNm*0QZ1jN&zO;1e?P_k+jiV41Om?nxB>eL=Bl=1TXRVW$+4k6&#i3 zSyH4{QG2%Ea(xm!1rAC9wlBd~;1D=W4Sx-2#cfByH{clezXjic<3I(y-~>1c-1HK` zQmZ`#gn}>tZT1KdB`vc%KnxfJ;((Bz1g=hy2$Dc5@Jdt;pM_NAa}|Ar<~egbiu1APE*~Jd&Dr46J2p z$B)|a`$4^F!b_myB~bAas1klb3BMp-0#zCV@D1W6Q1KF|cnMUz1S(zv6)%CxniLf; zfr^(v#Y>>#B~bAasCWrfyaXy<0u?WTikCpeOQ7N)t=vQSlqcWON z@eir^hg9b0RYo%^qZyUajLK+6Wi+EQno$|esElS*Ml&j-8I{qD%4kNVuTil^zr`B; z7K`&EEY6RxIFDg*9>d~1hQ)adi}M&3=P@kKV_2NWusDxlaUR3sJW4-u6pQmH7Uxkc z&ZAhIM`;lheHGC&^u8~{k*Cpi8`|!Nwu?1nR_c8}?c{#i$*<{8da3g%Xj{4MF)7IQ z9(~6ksT9e#A^F)zele1tisTm{^%H4F$Juk}b8@Apka&Ol63GYY9q;=VGl{~N=WT(% z)O#c+^SBvUYq`=`o({nJDv;u6@#1Ll;%M>24hZxNt8_Wn4zL~zVL&RhK5?`@akM^h zv^;UNJaM!rakMCLv=VW)Tcto+i8xw`I9iD~ndP-+Xci{uekhByI$Z#MJ z4%EYe1~{-44qQl^=11-N>72;nD(Wkr>tLx6j#%J`1&&zYhy{*V;D`l|Sm1~Sj#%J` z1&&zYhy{*V;E2V35x&r?q!73=4%w)sk6c2G%Q|3iB2;i!5fo6wij@P$&-dP#o%^I24NKlVbs+np&x1VCtkcn6fV*r7fh?N=g@zl50Ti zFXqi$DVR4)PkVC#Z>I6)B;K6Nn=amL9PnlqrH!MsHd3fKLl3OHHBb-yh|X1joxTVx z2BPP0;%Z1lED{lmM4X~c=s_$J5sO5`A`!7jL@W{!i$ugC4YBA!01^?4M8qNyu}DNL z5)q3;#3B)~NJK0W5eq+qD9bM>%SNc0OIa3EmW%;qxsMu;rN(2a@mOj+mKu+x#$&1R zSZX|$8jq#MW2y02YCM)2kEOSpV|5yj+Kyfn^3mxcy;>kZs2Zo;}$wR39 z#iVozDRq$2Hd1OHQ2X`Jny2eP*=cVsz~Y#K zXQ00&|6z;VisgTR-un~Y`i%bRfTw>tfpz~^dWHTm!Jowp75(~01JeJJr=Dj&)lw;W z;9Y1nYLwbU{)W;UR_kk@U&l5$KpG;qUUKVYB%DBRc+kF6Z?l3(?><@)g_SYOSbzPG zmgXqqi)6I?LdF*k_~BrD;Xo4{j4vFFFC2_79MI%ITasxZlaY{Q#uv$qFOnHwI2d0f zGrn*zzHrcXIv8I#7+*LTUpN?FI2d0z7+*LTUpN?FI2d0z7+*LTUpN?FI2d0z7+*Nh z!wb>F3(><1(Zki~;cE17HJn98EgSt z!A0O=a0$2+Tt+D`|NpqV6Y#jox_|g5la?e?Dyu#g5s+QV(jurlBKsnU$R;9XQBh^&%$YOy{r!D^+kNiij%4?^%Jbe}v^?ZS5$EOdkV{3Kx5z^t6nS1< z_T}IX(dX6jkUPpwmXDkgOd1^3GlM6}&JLatojh4~Ztyd?$lY?0yG1H<=k(dCI%zqBqQV`Bjh9_jV-A4Ss zH9r|kf5y_Ev6b^gQ60euIm!q*$_P2i2sz4La+JN~D0|6K_L8IQB}W+{M;ReU86ig* zAx9Y@M;ReU86ig*Ax9ZO%f`~Ov9xR~EgMVA#?rE}wCo02b^|TDftKAs%Whzmr5xo3 zOuvCu-oPqvpbR(AvMpKffu3*4QEs4Rr5t4}EgMVA#?rE}v}`Ob8%xW^(z3C%Y%DDs zOUuU6vaz&mEG-*bb*h-4l&9Pu++H=_;{^B({1%>oCxPu$Jq^#mv+x`|5ANz*^#V+U zNiZ3vz>8oms?0^z%kT=k3crUxz-#b2xay>88cc^7@Fx5bX2L9(4RhcvXb`EcfR(`k z@~8vkQ3uGQ4vV{Gtr5^K-t0$$(#Gk7t-5A?RQ94U?2-TC`k5o^3w^mP{R6V)hs;&pDM<>j*yf0>j@aRd>s5j>j{2_J$Gd7W>m4;qukL2G zTaMcOm!lpj&OZwN(a|pq*IGlj_P_a-Rla4_-+W7HB;NN8HO_mPBmdrcC!F`Y&U=yb zu64wkt#zc5l4qTFse)CiBQ18c#aru0-Ol;fswnrX$UYFRa>V(L7?ZQ)9d)XsE_Bp6 zj=I26mpJNTM}6ODq#ZTwsHN&upV8=Wi2z7c*3H^EqczXfiE+u&y~4t@^5fM3F|;C8r6 zrSNXoUfkm<$a~ePhIi2I2oH{3`&dI5Ba_XF% zIwz;j$*FU4>YSW9C#TNIsdIAboSZr*r_RZ#b8_mOoH{3`&gl^Ls^RupQ`M_O*sGS? zTQvlR!o70t``~_f0Q?qRu|8d~K3%asU9mo0v7D}0PFF0aE0)t0%jt^cbj5PIVmV#0 zoUT|-S1hM1meUo>>5Aoa#d5l0IbE@wu2@c2ET=1$(-q6m-+h@a3x#|H^aU1 zh5Lge#2E*PGxil{93{>;L!9wBamGpFjL(TPP7-JABhL7y3dk5S#>HZc3&a>lh%rtP zW1J$!xKxa>Pvq)gl(=G)xMGwza62(YDd!j^rWhqg7$rs+B}O<|jBv7%7%2|eR~#@( z{xORGAI1NV;{S(MCggeB^F2Gjj<6H>EZ;rK=#4abBaPljqc?Kv=#4abr7BD53cis> zZ=}&Hts5F?^hO%Jkw$N%(Hm*>M)KXG`0i1B_b9%56yH6H?;gc>kK(&W@!g~N?ooXA zD873X-#v=&9>r(>Ctp{|*H!X$m3&<#UsuW3Rq}O}d|f49SIO5^QnF?G5N3w;=S!n8 z_?Q2!s?rWyfA9aPs`T-{sVZ$lZ~t0V`e;1=_y6;k99yl+HP|$~)InH6!;4fbPQ?=R zyOcF_)9>z*|M1(E$O|qFKK~CsvC1b_|C3KdTqAC^EYI>so@JWvD0#pwU5YJNB{n;L zXDOrb9j(5@wKqPI_KD>_5%-C|tm5A4Q8GU9p-=SsgdU}Lzvuir9k-ON#;Rc zDU_lu?|gso*vqz_O{vc|-LdO^YKc$P`c#Ww+cM}a-wZnk&!)5rz16YTc~_lxHGbp_ zN?y68tjv|~Ck9KxnL#`}KBx(21ht+o-~3dN2p4tERIgkKDr`JwmudTZ)}mdz7_4>ms=v_hNrtqb=L(w=8F zzZ+zIXM1=+klWm9oQ~Byyh-oyR%@%jXl?Zut*t)MO3M?i!aB$*tkcU*@OYxflfp}^ z!n)Whtc%Nk7tSnyA-ueN;^t?|CxvC@lf$FRr*585{t~?GZ?D4Zo1eAv=~647F17OM zhgLrQX2@M0@3y+hby`C=Zhm%X@8*p|H-$4R4hxTWb^h_Lsz1KstKst%r@_}eKOMgA z`5ADg=V!s$a1ML}&V_HndH(-faK7hb-~!Jtgo`}?NjS6e2?vI?l?Qt~#N#L! z?fIdwaPzZOM_5&IfyWEs$8h!Lc~w8zytL{X&#(3Ty3L8I>pj0=^Rv-i!kN)s;nP+f z>;}8T9$tUO#kJ10!+#mhY=4|xHa9H%q{&o}`?S04i+_9b?2giGTg3q1k z`AKlH&wa(`PT5=?Jr%whmPbzucZz<^^V2>5x)l;bIg-hUj@O`)xegK!jR{XGPl7$8 z*LZ#{To>#dy*}7GdV}XTde2XTQ=_i^iryTa5FH!VMsEq1L~jjeL~jd@j*iu1HnR4WqV1IR2CJ-8UhREr zs7A9j0`L3W2j0^PZPsP3(}_-do^j)_%D!y1@X>IJRl#S|zi+^~ z;bX4(c}%|Y7z=M<;cLoWUCX-PEq~eLtMGc*!I}#!xiGi_W{r$vqugLq*uv6USXv89 zYhh_EEUky7wXn1vme#}4T3A|(JtA(jzr#(HKi6abg~z)*-Us)?171G}3q@E*SUK$q z>8cCi$8a_L1g?Q=;X1e;ZU{S~hgelU3P!`B@HwzgNR*F?ejdI6Uj(a7qOSRmehH3* zFT+uAG#mrR!f|jsoB$_+Tq$}odX z&3e+TC(U}&tS8NS(yS-VdeW>X&3e+TC(U}&tS8NS(yS-VdeW>X&3e+TC(U}&tS8NS z(yV6_>)FJ5Hbt+7pTIS6EnElJ!wqmF{1k2itI}D|Cf2iw^=yjX2EUNi{t|u#x5FJE z^JO*bS!aht-slAQ4g40KfG6Q8 zcp9F8XW=<`9)1Tez(kk?lVJ+H2vgxDco|-SS7Bz@!eU+*k1l2@ao5W)WeL?D6Ifm+ zCo5UX3OUtE&zr1DUc)+?{q22N3mF#Cu7|m0e}=!g!VA-T`LVQXe*SW07oU{klTv(A zici|WCvD)9QhZX1PujpIZQzqqd{T-}O7Tf4J}Jc~rTC;2pR|Eb+Q28J_@oq{w1H3B zz$c|xz&n*cwR6hP!*$rd4*S<(|GLUYOL}K7hWBW~Dw@zp6DH7v>{d;vqX`fDrCFNL z<=3{+gf_o;DNUF`6S}r)!XNzdb$)r8CbZFnHkvSjCbZIoHY2f?CM1omW^x$uI5V_DQp^L%?=)o$ZR7Vfm=)nwn&_)m1=s_DV-^I&!(S;RsVZ~Nm=%Nd4 zbYT@;SVb3B(S=oXVHI82Ko?fgg$;CJ16^1}7giaSYw5yuTXo^Ozte^5=)!e$p>3-! zw9$n&y3j@!+UPg;u)IN*7w`LMvTp zr3PDlPH=2Kn-so>X4Ni~V6nrvzOHg41KNOdg?n<3ti*>F`KIS7LK8)3^=ORa7-uO#iV~z)`7&1C%KI;4<;z(4GFHBf zl`muE%UJm`R=$jtFJtA)Sb2h#Cs=ucl_ywvf|Vy&d4iQESb2h#Cs=ucl_ywvf|Vy& zd4iQESb2h#Cs=ucl_ywvf|Vy&d4iQESb2h#Cs=tKD{o`vZLGYFmAA3-Hdfxo%G+3Z z8!OMS@(e4_u<{Hm&#>|gE6=d<3@gvD@(e4_u<{Hm&#>|gE6=d<3@gvD@(e4_u<{Hm z&#>|gE6=d<3@dNKirrax(^f0*XXQ<-ylIP-2W70h32S!8nzL|oS61G{%A0U>TO94f z(e0w+L=r!TUxdq9`*PO4oV71!?aNvFa@M|_wJ&Gw%USz!*1nvzFK6w`S^ILb`*PO4oV6!edy=&$S$mSTCs})vwI^A7lC>vUdy=&$S$mSTCs})vwI^A7lC>vU zdy=&$S$mSTCs})vwI^A7lC`JA&RxSE=G$)&2{elY8d-i)B(R)CY+wo9ETM-b^k9EK zTYHKHbYp)v_IGb(e*xqBv3x)@5SRHbmH94}`KDyPDVgq{cW+uIE?$Z0IV>+=c|n9w z@^7_69#gMhV_i?Lz0wW~8!HZnQ{k_XLZe8b@gtE!qe!7qq|hi*XcQ?liWC|}3XLC$ z6dFYejUR~=8u`SzB87MO#n%R-g@ltLb4iJ*=jO)oK&HY7@Qc5xr^Y7o6@5WVUSz4S6pFXQwwPA}v1GEOh! z^fFE_?(JinFUy%=7^@FIriF+7jqdHPn0;qx@EpANl6hc^AUI1l^EMj626N{Kw#Kc}q?8U@hOzg$PUQF!8#9mD7#l&7r{GY_n z8~1l^EMj626N{Kw#Ka;d7BR7iiA78-Vqy^!i z)X4r^8_QXD^aWSX{B>uMX}rNS-eA_&3jflT(W;d>6> zbNHUa_Z+_G@O?eLugCZG_`V+B*W>$od|!|6>+yX(#capZcHHX2tv=l9!>vBt>cg!* z-0H)vKHTcVtv=l9!>vBt>cg!*-0H)vKHTcVtv=l9!>vBt>cg!*-0H(EJH(jVKgdgZ z26@#a8(Je`Tg!*Hh3}Z(d0YEJc~yvYst~1>6nUecH|M3!Nfyr*s7!89iP&KNJ4>81 z_i3?qk661$tlcBl?h$MEh_!pf+C5_J9`c3|r_R|Y{g!$hT7hFLJug{F)1dxt#IaJPsid`O zzov9$P0p{F?^pc!%9@h3bkp6Q(%IWvdATvD6O$xe+f^@;ZE%D}Ioe8V>{2q?RlaeJ z{deAHO&`eTTA|I~*U9P9o@eB3a#pIIlBYePSF=v8_Jm%|y0Vk(wtA{c&S`LNFwD2c zsr@3~{3`Y?qVS6-{314VIR-Dn;6)g`h+;3I*o!FkB8t6;VlSfDizxOYioJ+pFQV8< z3{GNj5`&W%oW$TH1}8B%iNQ$>PGWEpgOeDX#NZ?bCowpQ!AT5GVsH|JlNg-D;3Nho zF*u3ANeoV6Z~=o07+k>M0tOc_xPZY03@%`B!TfJB|C`MJCiB0^{BJVO3yzsdY>GXI;*|0eUl$^36J|C`MJCiB0^{BJVb?oFO*(0Z-7x6EyJz zO*}ypPte2@H1PyYJV6sr(8Loo@dQmgK@(5V#1k~}1Wi0a6Hm~@6EyJzO{_J=T2rhw z#adIWHN{#}tTn}2Q>-<`T2rhw#adIWHN{#}tTn}2Q>-<`T2rhw#adIWHN{#}tTn}2 zOZnA72Hd#Y;k~LGOs330H>$bF8R?;}^W<9}j zQF%S4ZqeZu?|znz^k8!j9bSvk8H~88l%$~oyO=iMyD}4 zjnQe0PGfZXU)1EaGH&pr@=eLrFVv)Qb>ZBSYCfph3Mfs8msY z3j>}sYpc!L8Z(wQW2H*fGc>5wT}qp|_pzfCT_(+7Y31H>EQ$T4ntYs@Isr}ze?pHI z(4z%ruNF^gvFJXU{t!)nh(0yZr!;+f%S@)tWZF!o&1Bk4rp;v9Os36b+DxX+WZF!o z&1Bk4rp;v9Os37`zstLBq)i)X(?;5~kv46lO&e*`M%uKIHf^L$y|k&9Huch`UfR@4 zn|f(eFKz0jO}(_Kmp1j%re50AOPhLWQ!j1mrA@uGsh2kO(xzV8)JvOsX;Uw4>ZK|F zo86l{w&k%ck8OEu%VS#}+w$0!$F@AS<*_Y~ZFy|VV_P2E^4ONgwmi1wu`Q2nd2GvL zTOQl;*p{a$3kH4YhuF3T+e-b+9xN+G1RYqm2Fr?A)`eZoSk;43J=m1Qrqb%i@mNz@ zTN1~bW!O^6%I&_4!<~-ShP&O4n58n49chCjbyJxRoZXTMZOMX4dqU2kFz?9w-;wvv zq%bqLMtY@{C5wE+vcarqstE5T_-HmH6T-zjF8-^TO(#|9q$-_MrIV_3Qk71s(n(c1 zsY)kR>7**1RHc)ubW)X0s?teSI;l!0Rq3QEom8chs&rD7PO8#LRXV9kCspaBD&4r) zjf>s5*o}+bxY&)0-MH9|i`^o<4ys~LYa=#b4hlxCWbLIWzt?CLjMM<@E=Bu&EPKEl z^!>T|YeWW&!~m-tV3h-+hI3iwfYB)RX9rm30LvU;nFB0yfMpJ_%mJ1;z%mC|<^ana zFd73!W58$(7>xm=F<>+XjK+Y`7%&b|8qcLDK28_ml(HJlq14d)OXbc#Q z0i!WsGzN^ufYBH*8Uwub`8@T3JoVu`^npC|k-YQyywZKV^SQk8mw4sFc;%Da6KA*C7Ac(nBmU^FyPP#ixEF^ub@a)P_@A_*ANs_tL#CtSnXSKOE$ay`TSv zH*113jMo2@I|ZXvFj@tpRWMowqg60k1*26kS_Pw3Fj@tpRWMowqg60k1*26kS_Pw3 zFj@tpRWMowqg60k1*26kS_Pw3z@2{F>BpUZ-08=ie%$HDoqpWu#~qcz;2a~muMr(( zME5nKpEsiC7|}b7=ov=za3gxK5j~pM>Y^iEbfk-pbkUJ6I?_c)y68w39qFPYU38?2 zj&#wHE;`ahN4n@p7ai%MBVBZ)i;i^BkuEyYMMt{mNS8H@rCw+~uT$!Dlw$8KF-4cz z`Di@x!QiYMCu2PUPO+BwRM~?LE-Nq9bnDGj#w`6mi5dPqeZ~KmN0c&e(64GLN>OBKe(J?`YpC!V^HfiJ>S<3s zORA?k^>nA6?$pzrdb(3jck1a*J>99NJN0y@p6*yxrEBx==?wiVD!hgYuVE!wR+42U zSyqx|C0SOIWhGfwl4T`XR+42USyqx|C0SOIWhGfwl4T`XR+42USyqx|C0SOIWhGfw zk~ODw<|s+Uo7|0O?cn~YD|ymVXQPyrmiBvi&q&YP>QPHM^}t~DXR%MzQ@v94rL>M{ zrRc7jAO5FTPxxd(x3g5cX;J}NBeLI8x2g5XMLs#l_s$Uyz9X-H$M=`69e>XEzw7&F z`u?|R=Nxh1B5~j%M=Mo@vT8Zm;K4zT)eZWpMR-=v<`;_@O0~~E-!@n6a}&-rQs)G| z)!~qjVEbgSeKOd-=pEp?5E*Qr47N`O+b4tVlfm}MVEbgSeKOcS8El^n zwoeAzCxh*i!S><*YW!b~|EuwTHU6*0|JC@v8vj@0|7!eSjsL6he>MKE#{bp$zZ(Bn z>Uyc8(@qab`ug3q?_`e$eSL6SBS3sAlHBIVEx^y_%kBg-YwzQhK3m<#%u?HVZ zSD?(p$Hn;gHa?cFt?9yqZaf^o!!364fg`PSq%KF=z%Gi|UAn4h+1B{9v^F{Zkt3{j zgbl&31N#&No2`N#<~u(oPu`BgZSP!m@VF!F1Up+TttVb)bxhfRc>PHj!A^F8PkFv8 zd>VH1x!pbP;XJJ|EwfK^*_e`v_JBJ-gl7a?%GtQ=Tq+L zo$>_`S4&$8D?D!u!*a25xvoLE_@;avr1knU9<$I6x$y1s4v(FXhl2jUovF&ZRCL!v zxA$-Gx<`%H^&{nCp7LI`x=qmMd4HHKAMp4maQ#Sm=$<@5*gvE!TsvE1t+Fx0&| zwh41XD*P=PW`_*(HmtBzjEc~4~;;XU;a+j-mcWXadV;S!ObbZ@?5{>U}t}+GdtM}urXz>FwYk9Vx?K|%+HY#R@KtB`cG=FZE8gEK(^28X@;7nqEpt>B-s#(C`-Xns zP-YCf96jdf(;TtJ5$jcvx>=~JiTvIkN6R=`H)~nyXeBn+I$|ka$g$djBX4r#O_;pi z(Tf;V@O!(4oDlX7ImtJEO~=+M4Zl0-n@jucriR$%%I{z2_xC!3HO`>J8RQ0k!!W<$ zdEfeb-#XWCsMz`&UiiD;FsEuS_ej{=4jm8LA!^HSnBh0n`VC1}d3T35I#S$kSmz5SGD>2i7RS`yP{?%SJZsM6*W8gO>_O8pZPr- z&0&+@@|@qY#BVug$iqQJY0ce`$AWGAo-_TPE6wLB^Z7ILc>_kDXFk8|2HTj&>oLx5CeHk3Xa1HmpX|2Dy&!nY}2qj{TMR_XT)b1mVvdMU$UJ2~a{YI!@TC+-M4!On8~kE@Y? z!ubYvl_) zuMVe`*QpGw@VYT-AJILlwJ+nlH*&O&O~xV>Ql9!kGtfrn~a& za2Az(jY|HWO19!qD-N|%$yO@aO(najWH$zM<5V}5?52`MmRz8cMJidOk_9T+jc46d zvOp#2hvy5!^;EJA=Qc!N3x5}V9o}H=v%vy)%mTG6;BF3Y*W+zBrR;aLYlwM6Rf<1`iQ8e~_O8>}Kb*qaUgPge{iKy< zeS;a_V5Vb3jtjOmV(+=qbfqgzS5~+SoHPE=883^D2p2o!w+8LG%8{4h^oNeR+)=ZR zx(wGk*;bTo?d}t8!Dm=T%=a($&Q9;__0AI0Cwu2wj4a(B?r+y0zo};M7C0A7TZ?6_ z7?3sVE6w`*X1&pDPcqZ>X1U$DmS*;^Yn8tjzHJ8Ibj}55P;|asuCd*snN7ZVo%8JQ z?dyy{j+S&f+G+DFdLH+Dc#w+4{htlrSFWxr1ixuDHr~@o` zfCUe*-~mVPXTdEjILm?uSnvSL9bmZwEO&s_4v1OqWwisWc0jDMiRBKk+yQ6x8`e9( zdItur_aKiL#Bxhl2dB!8G+$rVjXlca(H=`3wX==gH@xTE@I`sUYx0KISZ_DWy^H1E z#cB(z_O9|p#&I#!!U}(D1XV6pJHToOSnU9-ZDF+otagCa4v2B?Ww`?^cYx&%h;Qy? zxhusr_lj#aiEB2o;sI7Xz=8)@@PJrm6DuBIy#uUwfc364cPm-#04p6}p#!XQfEAXm zpneU%USo+_7TC)Ids$#FtGkQU6%YY zEU23Wb+eu+tY-@AnZkOeMCa-r%vTAESuwu=7Rv~icpZoLpc-mmx&BtdBkRHK8SZ%f zCt4Yy!$Wlqw-q-GhmvN0bhiKb3_tae8Q$=b8J_Z&87|GPI-uFza^2vOX7tN???-t& z+T$s_%@%)Nn%$Sp?jOzWAIhEUqDYN*LS=?Y2 zH~fQH-0(NE_+MwQ%j~^u_Fgtyw^e<@%>1L-S}3B)*atNWMd*U{;T*Fx&n(R|OY_Xq zJhPM;oTYy}GaCkHrquoYjM=z?{q@qa(romzna4_s!;)VzlBIr2slW0fkM`#^5~X{8 zUPDWs#rY3e`)Yjbq9q&X$R?KG$@15+{L=l9>UoCJJwM0zWnbqBIw`>bCFrMn1!~Zb z8@C4svhr1|ynfKiN5~|0fjz`3pW)y4SGyTGs4qRvs*bvq&ZKlrQK>T8#>(nhRyAv? zmMyH7Ev#l$wdSLmFZ{q6=2%Uwv&{2%A2`D{XZXG|Y#y|fbl6<^IT7OfB5HSUGqx*@ z?Mh?2(%7!V^m>G?;QTh8I8;(ni~v2*fv z=C+g_>@O=HWskzcF?CDl=xOI#=UjV+e9iuD{N_i_vB^2k!S%jDueXy=m*%9`5uS5| zcO0SQac=U|VvI)~EkAOE!O<{Y}5L(w^W;2hREhYuWSaJLfY zu+}-OSMmC@(w<@rw_Kq;81Z^Xmv?jo`x(PctR%xqK4cy5`Tpgsqja6%0>6Jg4_xZz z#%OemM#qfD3yxIcP^nH^XLRS%={TK^v!DzMdXELY$8tU>-w?jXQa*5=rE{BQd}gth z4_V3w|HO_nEG5HIK4dAq=5-4%X0qRf?02D&`KSC~n+w_F!oTN9+3`Vz)xVYSG58eh z3ZDl0v@Uy*651c%{WMgzttUT zQV*J`7BpKes2KG7|3A6PA~a@^@Cd4Xds!8I+}7RQhQl5#XrJ&|%=d+$_4eg<{<)m$}PWKOkmX=QwG1Yd$u-HF82&9XZisX>aLM-4X7q zUY`kP``h{MX(6VMd>=0J{BoZu?PT+4IKBL-@QU(h!s}hZQLT5{#HU_cKF{;{9%JFv zeCxG*>k)kG5h_DJRvG#+AA3Z(tLw^>-j@qsHm@&J#u=1xhPi#YyoZNzF9GWKGIe}e zB=js^=7*dt*ZvBe8djV41I+uUhuT4B=xVP&giUgeuLirhfBJqEU-x)MaB#(W9>3-F z1s*T-`bzKlAzTGN0xO;?tah%j+PUJl-t*V{r0-Vo=li5T=f37I_;OB$POvk496ka60iT2sunXX4C4N@oXXS3N zJK$;MXJAj*3-*S6U|-k|_J_~H0WgyO{PjNVtKFyl`pQwk?XIk;t~^u@_c@P;!5OZ# zI}=LR+?@^Qz`5{EI1j!B=ZAHbW57!EN-NPTFM^BV+wdK5H|NSr;CtY1;+2=e58yJu zy~-=#O86mM1wVox!`0#Cl|O-N!bdBwh3nvYxB+ei_g|=V|Aori;Ab!ner^xaUwHf_ z{0iKQ!QIC$cK5N1|G~ZB_uG0e_={Z|aj{(XyLNP$X-AitRV%|pRSH%?6RZYTh1t<1 zQPmnwuWEyJkcJFop&fG20iBSC0u-SO)~kVSxflGsgZF~}ulIq!ckn*&AH4_sOsn)~ zh3|<8-xCwQCnkJPOn8K-{8{%fsE&%4q8-o)c_@T+(IRxgdgu=8hMf?O8s^&AVZRTr z_$T*|zhc-7|L6Yk!)DqeV-}6NmEujHcz>jHEtD=#>1I%_G{t&}T1}u<6DY|H3NnLg zJV7ZYP>Bgt;!P?sf#q(`a(7|5+q2v~Snl>LcNdnsJI9rJpD_bl{! zRq!d+_eRC)U~$Eo;OngKQ><@R#o8cV(c*Qh{j3iR?yfv2n1K0rWBzY2eFCOW!1M{2 zJ^|AwVEP11pMdETFnt0>wqRrnM&>axkCAzd%wuF8Bl8$J10!c(+c76exT3VjOWN#b&3?h`KVkMiIqbEv zJ%_y>Tr%v9aO1FPLDevK|1kScnEmbSg}S%B1om-%)4$I8^sTc##jHPW)*mm&BH&&??%=BX~&J@|xG5;ZdEW#NT!6xhtG4nwTw`m~BV5ZQ0f6 zf7iELC;N}SecNCkeU+gq+Ocq=^Dj96f>CaF&R06;kNZ^8IVYWS()qeagHQZCSgNX4 zJ$Tj7d}~q`8?C%GDWz-eGDfV{yv}#jpQso&nBRAd+;ZRW$kvWhsY3UA-}HO)n)7Wh z`?iZKe;O|KjobOgcYNbJzVV&PM_m(mLU=~`s7!HBa;Y4>xb-yb(3=W6S!xzFAf-k}m@Sj$5eaYXB1nZye z@7fty|7?HPPW!ud+TXR){;r+&ckQ&lYp4BPJMHhxnsdXG1#4&4Ypg_~fkW87kvZiU<6XW&Y^z?F9Pf^83e3BQ8d;SL$u zop6uO+=uUr!$(w_@>KglcG2Pb_iV7-_iWkYXayT-rRKF(!@cG@jaIAS+S$xfE8><0 ztFhvJuh&xh7N7aRdA35E6%8s#R>e)^0iMH>()AkER>n=kmfz~!KdW>9toSw`{K>k( zP(8d#OgcOx37_sQh9Iq2XS-0EaP)oRkEVmst!Y${cOe1`N&s6S3GjQ zO4-F8FAK^d*SdqNxr<iE-jxLzF<}B z3sxFVEPoYVhk4!?3nEq;JS!H@m#@^*Ou=feKd>)NE40BnNIPD}qw8YJOMBM1?nb9; zv7Y5(J*kQMOSlHB}~-UTs&k54AnQ<1}gk58vba=Fn>E)weKr%DxBu^>2L;|vhJM!T1H#vbj`VmSMLH<_ zcNaUt9>$&aFz&R6ai=|uJBPa7LyqCf^x%_2*V4^&_=3CQR;wz{x3XcP+#_$r=0t1v z7RW*J+u+Yw^Vr2MW#er}T91MrRC>RZg!sp;HI6QnxZ}#B|otcU+!V&PF z@Fh4Bz6?jf(QphL3&+9nZ~~kNJZZ(r@D(^UoF^B$Ma|?9QPez9)LgZbpQ)WZD2kdZ zih4>EwLuj1peX7=QPhK?sCnutx2UT;B8r+Pikhpw@-y|72SrhH^^G6aH-5O{JKp=< z@XCry;Cta!6<3CNIaOXxm6ucHPsLM>Qc)IL~if77R zs&G%}isyo7RZjErs=T}^FR#kWtMc-yyu2zu7_m+B`RP7C!{^@&URJ-ETrtxzW;w=e z&*wPKTOQx`zIVLuUGJOcee?Y-=6wsiZ=vV4!H?8&=2tY8O|Dp7_Le%%Y;~MBE8Z`g zTCuilmO9Rxs;EC!%b8Wt9zMWJJy6kMb;@vc7=A~-m6vbjC%FDO%@~ymlD=**5%eV6Kt-O3IFW<_`xAO9>eC6J-59|y3ffZ)*t-O3I zUpX@Pb>)F&H&z~0c7Nr;!JUwR^AgCUU{$Q_XVlS`^zdTAMk$zEj$5F!c*`xJOj_dbMQR;4qkwX!Jh8d{)fuRFa=(OsqhlK46nee@O$_J zyaunsG?)%E;7!-x{n6u0m<6-pop561yD$&tgZRY?>4}w#U~%|DK8%42 z;6k_vE{1Qzci_8r=D5V;_u%_*Df|E~gUjIxxDtK{SHX`!+*2j)vD$rN)iuC>TJ1j3 zYWIm&yHB*rYofa+PprC0?tQbzvCfZQbqD3e)~_sf7v;t7(OFmZOOL;T+u;tl6Yhq4 z+~-q=t?E9wA5{Bf2h;5tKi!`3)9o2Q-JbE&tJJvc8Q*Tt_;!27x7#zm-JbF7_Ka`0 zXMDRogsud?T+Bd-wyq2Cu^#Fb$@|40sd%2s2?8%!WDe7R=ubw0beHtSQm zr@Ok^?bBsPMRzMZM{W6>=pL@o`b^oe(LKw~R9`+LYESj(KEb8-1IkAC^WOcv_p{!6 zfcK8{{|9>SLEd|?=ZAzZL`T7BI21kyhr!|Sc@V?94()}g7~XYgFSrivh3Jv+WjG3s zhGXDZI1Y}76W~NR2~LKuz$xKtu4H)4l?<=BlHoO1GQ1W&9lj1{z?pEC-2~4DYXDqR z+v=LyR@c$_$ z(bW=5Ke89m(&)8bUuQkc^H zIKS!V@C%)rU&628b`bBoYN9%N7u*f^z`bxE+z$`HgYXbM43EIC;ZYcGZS(~A4g40K zfG6Q8cp9F8XW=<`9)1Tez(kk?lVJ+H2vgxDco|-SS7D~rf3xflHyh@_TQJ|+$Cy2u z7Qo_gzI9}ats`3;eGjUk2A1Po!egEPZ?yWR-EqXEYFl}=t-RV+KDr^C80~=%L44*8 z+!Nh_yE@tjI_K`dUF{Cs)x#bR7Yutfm@@1Sk&0ojMRwHB2#389#D+~Pt5o9()wl9i zdd{-abK)@m#hw1X9eiA6U|*Giebg(WyxyVeMmwoXRH`|gqvlYm4Q(sy->&RI`D;f0 znvuU| z^fspIYvko;nX+`4)z_FPC(Gz-Of+Lh%FQxzvy8sRM175`?|H{a} zGUbz9TQ)ZwC(p|0hm2DZxlcc2oD~mG>xVq8A2LlpWSV}+)AFyAQX5>H_IZ#G^)1t!ipbE=_@|dhVCaWgZCXdO= zW3uv?tUM+wkIBkoGV+y-JS8JXX%V|;#O@ifdq(V@5xZx^?isOrMr@uDn`gx48L@dr zY@QLDXT;_iadAdmoDmmi#KjqLaYkI65f^8~#TjvNMjs+0F3yOHGveZmxHuy&&WMXM z;^K_BI3q63h>J7g;*7XBBQDN}i!F3yOHGveZmxHzK^k?=VicaGc80INic=x`pF(3&-gej?*n1r&~DA%7U!ELss7*tM8E2cgX5HWc3}g z`VLurhpfIsR^K73?~v7Z$m%;}^&PVM4q1JNtiD55-yy5-kkxm{>N{lh9meT9jMH~` zUfBcwXP(d3}eg^c}9!ceqO5;VONHtL&=SqYHVJzQa}e4p-?rT&3@D zmA=DODq;&^WEE!2g)O0VH6y$1J5_FZ`>KoPoNJ#@nc=z$MmBe(;}W}5zn-U zXIjKFE#jFL@l1<&rbRr{BA#gx&$NhVTEsIg;+YolOpAD?MLg3Yo@o)!w1{U~#4|18 znHKR(i+H9*JkuhcX%Ww~=%-B6Pno8l64y_O>!-x^Q{wt5as8CIeo93>~l;<(E*dpcVR!u40 zU406*m_jAG|J#n~_pAr~KdpWGH?D7zmCK5^b|DW5#_K>%mJM&i>hDlbuH8~k4i2*l z;>%V+e9g*J@ z&Q8z&k7p;Mr@H;$%}%8?DiM|c|GTqO_y;}8s=?XWA-KYIVOLt^d!zM@H;WAHfygEn z54kRUd+5&L+g1MwUxFjy%WxDN4adN-aGcMVm1W#DDF_PX2kh{}J?9;^?SJm}r6Z3# z|EN8V`o%F*j+uK*@|c!mipOj|_Q+#TKlZX?A2@cxv2%}o|JZfM7LVKQxV?`%{kW@- zyXUyZ<2E0^|5rb8*45|#_B$_MHt)yDo9?-K$E)Yubk9!?zOnVE7yY#Lrsz$V-E_}Q z12>;~^LaO4^T^d>r`>wZFQ+_m^)F{V{PI0b4`2H5%a82%$kpRd8-Lm(4UZoA=oOES zd-Q?v+mAoaUnY&8Grnegal$swUpHar31>a=!zXTga`6+tdSdRA!IOtRdCZfKJh}ME z{4?X8s(fnQ(>p(X)-&Utp73<)naXF5dS;w|zkO!PGc%rvJ(GC;yeYxtC!fFc`RksK zKi~SoniqN}ZZkPKap#E#PyEWnb0?iNamK`}C*JmA&BTW$K0R^D#2Hh9iLr@mCiYI+ zanc@>4w&@C$qOf)H0iuamrlBF(gTy8oHTV(Y*Njn#z`%c1}1-O@~)E)oqWvX(fg92k4$-X%Bxcr zPf1Pbn9}j$HZSh+;-N1d^Wy0*UiRVxFHU)}#=oYik*T}-cfi!crk+1_+|);=zC3l- z)Y#PasRJ*4;-w>BI`^gTy>#146JDD8QsYbOUfS@=HotFrJ@v+rY0pl(0=E21&Dj2r zx6K?f`+RqGJ-qCUvNM99?5wi0%=$TH=UDB1u50zn%PuVYb}*#u`(>9}-F$7?E%v#) zv+Pc5r|&L%AozIMy0UEWsWNwkbZ^pQBgeYy*zu7QWd~o0oECgGa(d+S;NZv^ku!rs zB4BUa4@pO1Ve;-1uzOCsM7z8LvIq^Dl|L0Ump@bfOz?jB?{wzYmQO8zIapWz zYWb@{w*2+-*Ms)*8RavBT=_#Xod%gsgG{GErqdwPX^`nO$aETX>4xjl4cDbh>C&Zi z=~B9MFg)GQ-vmJv0}h?-?Y%`&298Bw#0s98qTEF)@`5jD$*nq@@IGNNV~QL~JwSw_?> zBWjirHOq*aWkk&~qGlOUvy7-&M${}LYSy7E$o+PAS21@9hs&+O{vliiKY|}S$E)Ed zaE;e?Fx0Ip>ej8&ty`sAw@SBemCUMHW|fjzrDRqqnN><=m6BPdWL7DeRZ3=+l3AsK zJNWuL;Vx?_?$)WkSBGwi@vMR6cG{@3lB~23s)~&c-7=Zh3Yk`;Oe?NKw?c=mDC0`# z(lzPM#dPOl;)X=9PA@#|dB%Nxwshv=GO-5TxE*9-2^m;}%&Sf(u2Uzjs1sMzi7V>B ztcACs-ikVJMV+@|*>2Y9@9uGr!CeAkI&Vdtx1y{quJcyZc`J%d8g$-@I&a0Y zExQE7bl!?OZcAiw@6hQ)*-e8h)j9@Os@?0_lyyFnacuVvk;yg4;=V46YhYWu%D+#Q z%{4^Mg7bsnvblz>-L{x++alezVq|PMU&pN|vrEbBQo3!mvb&1NopSiQyyu~CRpi$m zAGNmq$?#p-UbAekS+>_K+iRBXHOuyzWqZxCy=K{7vuv+fwwIFar6P8UkG$gZ_Oo@r z(lwFS!X=T{!-bJI{B4>QbJKm_jBvTTzb%XW(dTA5pIKoc;<~KJ9G`j1%7VGp%)jfs zF~?fqxvME7i)g`Ok4qpfj$7(;?}ZB@iEwqKE?gN&`g=XB2+oT%26shP2G2$8s1sT3 z`&pu3D;LtijS<%dM{>Tu!~b>q-n{n~eYVSauJ@U4j~hJpIPQnA5qiU>$UtyG zFnX8o|?!r)R<=zk&3foxIU*WL|qSo^a^Z(nr&T6p! z2cO+hHoTML?Ciatu!`b8+}q`oUXQTz#V)#lySgU&)7Jg(;acZCy$5&7_tCku8*BMF zuJibYtD?RY&M!aT)vCV>8)Vp}{d!`u?6|IGto&7Y9p?GJSg?(Zxrz5WJHBLi}lg?#q$S{v5yI%S$a4MYU_33a1oaO)BhgR1zHiW+DS}q^z`tzZ? zhqXgL6D}OOr!M1O_Jw)db!qRw{NUK3F`dY2&ud^A)WULD9X9Avep;6@Hq>sdL$kr2 zLv?F)E0emFYji7Pvj2vm8$E6c8@36;#5QGNe49vc_BQ1nhlH)$3=M0x(Q(zqEN-)p z_ox!+WX3A43>#Dm8dM4zR0DhCZJ2MsC*4Jro>DhCZJ2Ms!E2dW%2s2nt?95kpL zG^iXjs2nt?95kpLG^iXjs2nt?95kpLG^iXjs2nt?95kpLG^iXjs2nt?95kpLG^iXj z46f2S*yEp9>WudMQ1~1i23H5eb<>9HrVZCk8?Ku+TsLjFZrX6U#Z=w2;ks$Vb<>9H zrVZCk8?Ku+T-R*4uGw&1v+Z@wQo3d-U9*&~SxVO|rE8YbHB0H5rF6|wx@IX|vy`q` zO4lr2mSxVO|rE8YbHB0H5r7G!5rCm~W%~HB%DP6Oau31XgELHissQC@Mi%j!; zI?Mq3QRtkdbk0&bXDOYtl+Ia9=Pagk7SlP4>72!M&SE-eF`ctTI%kV?&KBvMEvkG^ z#i82YYdl}(u@;s?0_q?M_0Rw-z#VRM&tke~G2OG6?pbVW_bjG+7Slb8>7K=O&tke~ zG2OG6?paLtET(%F(>;sno-I?^Xja*1R@rD)*=SbTXja*1R@rD)*=SbTXja*1R@rD) z*=SbTXja*1R@rD)*=SbTXs+BGHdonyLx-%OLsrlsE9j8Ls_bJ>wJi*XkHL1ZlXZN% z1fSF~J5%LHRaImL4w(g|9yQfZC z(cM^g)lDnvrWJM5in?jVDto`{s1sH0ZYQ7h`G6|2sIv*8@) z$o6&BV!CQEUA365T1;0hrmGgyRg3AW#i}lXi{abw9oW)Ui|MMxbk$8iza)ndA8FO8GV!CQEUA365T1;0hrmGgy zRV(VM6?N5$x@tvTwW6+CQCF>~t5(!iE9$Bhb=8WxYDHbO{j2T`S5@5y_k(+X>#D8N zRa>R2wn|rRm9E+oZEDy0&YQi)2bM5R=sQYuj?m8g_TR7xc(r4p4=iAt$N zrBtF)Dp4twsFX@nN+l|#5|vVkN~uJpRH9NkYe}88q|RDWXDz9-meg5G>Z~Po){;7F zt990rI%`RtwWQ8kQfDoxvzF9ZOX{p8b=HzPYe}88q|REhs!m5T>Cv5&RJsx>U5Tnj z&sVyp*eXQTu9d1?D^)vgZJt`60%4%My>)vgZJt`60% z4%My>)vgZJt`60%4%My>-MNvvX$y7J7V4%g)JClZJ}=3Lfy25x@ik_(-!Kc zE!0h0sGGJ>H*KMA+QR5ja5NkP$HH-NJe&Y0!bxy4d<9OiYsIPXRX7d42B*W<;S6vk zuj<y3f;67x@jwP(^f<;f{WqX@E!OrTms*N z@580=1Go$>hb!Pp_@O&{Ughye?gsK>k5|J_;2O9Vu7m602DlM^3OB*cFcxlsTj4g) zMb=HL(@m?>O{>#QtBc+Vcfs9o58Mm)!Ts<6SZAu6R;Qa*r<+!%n^vcrRu_FNd{;*; zuA>&$QH$%S#dXx;I%;tpwYZL2Tt_XgqZZdui|eSxb=2ZIYH=O4xQ<#}M=h?S7S~aW z>!`(b)Z#j7aUHd|j#@lAGi=aN+d)Td2OYH?bkuf;&a*qmd{{WRr^y-}wW5w%F}f7q zgKDUOWl#(5extiq)Lm=RUE8c`*`R9KplaEmYT2M_*`T`?(_M?{uEliMV!CTF-L<6d zT2gl{sk@fcT}uvoFkCq7k>IdlzYfkD_E<1_n0rd7Y&Hy29o1E<)m4iP<9mi#bv5K0 z)_txFhQLs31uJBJmGCk6gskUN9(RRL!yd4wzwHJ4%UDLjL9&^H;Sd<@3fV*9b8r|O z4xa~m@yaac$Smi`Ea%HCXUi;S%Pebyqu^*b29AZ};CMIzPK1--WcUi40;j@P;WYRf zoDN@yGr-l`GRs<-Wv$GzR%Tf%v#ga_*2*kvWtO!v%UYRbt<17kX4x*Y{CeF5|Mxxa=}6yNt^&XUi^U%PwcjF5|MxIkL;R>@p_1jL9xzvdft4vQ~DvRCc*k zcDYn`xm0$!RCc*kcDYn`xm0$!RCc*kcDYb?xlnewPT%WvbQHvd`JF z&)Kri#j?+Zvd`JF&zZ8%(tY3Fwxd(&isl*_=*MNCOUrn1S!j(cG%gFRm4(J-p>bJg z+*;6tOmv}4G%gd3myPhgUEoum?+TxW-K^u>-Qymxr{{Zl+#B|BmHECN_k;c6vv2^6 zbi4z-?;y_)hHI_;yv}QPbu7C<1@T5Zh5S@DY>ZVC^JQb5!!0W9?pvm^xU%eSJ5SuB z2YIh^y-!xVr4Lyndz~$NU0CKi3+qHzmaUha9V`2?6REyrF;cp!+71aa+i%NkYh<>2 z$ZRi?+1AKxOIKMJWw$%XZfhc!c)n#l>1-M9oQUfMWw~)#?krhuT$a03mb=ut(mI*$ zd|B?UvfMe5ySam-)_;`F6;Bt7X0mBi3F<-tqcf$BlWtK$g4EaTm$%7kgad?{UXn>T~Zw zwG0~{Bg_0f;k|W!N78eAlnq}Y8@_cg8%`OkRld)DjI!dGtawqR**U%Mm}`Aci_d-_ z>uxm$ZN@1bd?n(}#Sv?IWy~oV^FkT(J2K{({}*@n0^itO-+5o2WSFr-lT0AomV`?o z6oztXfuZ4+P#VY*niB5KQW6OFOSuFnVWH116ll3*Xxc((2$aGUdZR7d7SK!#Baf|- z#yTU*vSSzQ8D-=%(mC>xWMhwHv)=ddIPAc}mOg#DeV*sV>xb=(EXk72|MUHQ{{Qno zn;mn)F0?&H$8)i}imo}UYtHJLkLa3po=XB5q zb&hur2Ix4EZlLjH_hXwG%b^Ye71=llI#>H`1W zdT3pA@vIAde;-}(eRbLQ^ZotZ#{+bxb}-XT=XKLZ&vLHUSr4)^!h`+$Lv-K|^?N_- z{vPJ*!+pKPe|v#{d!gU6FRBjvfDZeB4!fkoF6yweI_wc0c2ADZ;x(mAQ1G?@5y6%Ft!zG<}LFZl2c^}ew7j)h^o%e-0@2t+dpz|)A zz1==D_fR|hx1o)aF1(-%FX_Tdy6}=Nyr2s&=)w!S@T@L8s|(NS!kfDA(X&6Z5$VJi zx3dzu@q@bYtZw|9y76J%_)*>XQQi2j=*AzY8$YTWKdKu)svAG58$YTWx0`F`Lfv>) zH@;sden2NasuLg8iD$PP?{woO-FQ|vUeb*p){PJA#;?&8cQeUsYH8{@0ZK znyo9Iv95S##|xFK7+P06V_osgj+grPm#JU({k7^p`TphVH+=sJU$0Zw`~H=7On8;L zVdE&{P}=b(^=9=JWd~fwp~N_p7>5$$P+}ZPj6;cWC@~Ht#-YSGyvCVcPh=gQu%qbQ z@FUJHJDPdtjdwp~nTY%DnDzat)jL09w_O>7kti_|B}SseNR$|f5+hM!Bub3L zZbqWSNR$|f5+hM!Bub1#iIFHV5+z2W#7LAFi4r4GVkAn8M2V3oF%l(4qQpp)7>N=i zQDP)Yj6`TXLy3_HojVj-*HB_4N{mE_ktprF!j+z$tuSKemFhpL=c=pJ^VF}ZtJPaG zyO@hz%*8I|Vi$9a%Uooc zi!5`IWiGPJMV7hP&s^+hF7`7Q`__kTx6MxEOU`%F0xi|J=(h8EOU`%F0#x;mbu6>7g^>a%Uooci!5`IWiGN?=Hlp1 z-4}atl)X60UL0jFj#ZmU+D0^{~y*SEV9Az(#vKL3$i=*ttQTE~}dvTP# zXtEbg_M*vNG}((Rd(mVsn(RfBy=bx*P4?oK*o&WIFMf%+*uh*pfVsFob8(5?!M^V- zxb$qr%eKr#k-7L2=Hije#RHg&M=}>hXD{w%FYY&ZnKS8r*_w)HDc4bCFbWJtfx##+ z7zGBSz+e;@i~@sEU@!^{MuEX7Fc<{}qrhNf8H_B0k!3Kl3`Um0$TApN1|!R0WEqSs zgOO!0vJ6I+!N^)6_i*civkXR-!N@WgSq3A^U}PDLEQ66{FtQ9rmchs}7+D4*%V1;~ zj4XqZWiYY~MwY?IG8kC~BgfW2BW}WR2hr{gHd2G3JgYp z!6*#6b})-kU@;!XVvMjDBP_-Ui!s7tjIbCZEXD|nF~VYuuoxpO#t4g1WHE{?Mv=uR zvKU1cqsU_X8jDe6F^Vikk;N#o7)2JN$YK;(j3SFsWHE{?Mv=uRvKU1cqsU?uS&Sl! zQDiZSEJl&VD6$wu7Nf{w6j_WSi&11TiY!Kv#VE2EMHZvTViZ}7B8xG~VvMpFqb$ZK zi!sV#jItP`EXF8{5wIAeEXF8{G0I|$vKXT*#wd$1%3_SN7^5u4D2p-5VvMpFhgghJ z7Nf#qjItP`EXEj%QDQMlEJlgND6tqN7Nf*sl&mGLT1#9Vtf{*g51EVAsIVFpR-?jd zR9KA)t5IP!Dy&9@)u^x<6;`9dYE)Q_3ae2Wvr9MUfiJzW%&=jC!nH^d6@kuYN(< zyNf;9&z|gOPxiAX``MHI?8$!iWIubdpFP>np6q8&_OmDZ*^~Y3$$s`^KYOyDJ=xEm z>}OB*vnTu6ll|<;Fnco0o(!`m!|cg0dos+P46`T0?8z{Dl4noy>`9(I$+IVU_9V}q zo{X|5qwL8jdos$NjIt-A z?8!ISlVSE`m^~S0Plnl(VfJL0JsDw0*^^=RWSBh}W>1FMlVSE` zm^~S0Plnl(VfJL0JsDpQh)pT5DWh!4_t=yYn^Iy^N^DArO)0S{ zSvDohrexWaESr*LQ%2d8Q8s0iO&MiVM%k1sn{ox4@&-2Lf#=vcno%j9b9$$p604H# zik&;>fZO3Bt1@x+HLOa+szj{HQC6kOs#IB(sExD>-H*$E-{?^Gb_`~$~3bw&8$o_E7Q!%G_x|ztV}a2 z)6B{=vog)BOfxIf%!-*%#UnB+)6B{=vog)B#LUW7tjZ@Q(eDy&L{RjIHl6;>t3 zs^nOe9IH}cRSvN#6;|ait8$oCIn1gYW>uzHl}T1*l2w^xRVG=LNmgYt^Iz2m)Cbk? zs1LCiA68b}vntc9N|gC1d-5^g=Y4uo#U)Zj#a6!D&wq5fmJ!gs)Vdc#H!?2m4sC}!m1>!$}Fpr zuI8R$RU$?uVN_-qm5#LlRW>EZrj!QS{=2hH*_7EWn^N7fDG8gh$fmrUO{uae7qKbV zvME(IrLtvH&Sg`oTP7vPq#R;W+DuA?Njb=*RG5@WCS{UInPyUsFe&$AQVuaG9VTUZ z+g=vp7C*ZNI+JpgNttF+MwygpCS{sQnPyU^nUrZJWtvHuW>Th^lxZeqnn{^tQYM*{ z5|c8@q*R!cbPd5clagmra!kr0CS{CCIl`nAnUp+}GQPEjAl_O-kT5BeOiGDKX)`Ga zlaj6_C^0GHOiGzac{Y<$W>P9lN^aZfwFC#ZOv+IvrNE?&GbxiyN`*JmvnT zDB}!DgF!jWpi~%?!qz&3BMi#78I*$z$~c2^gh44XC%;a)>>tuqQ{@lf&#ui9NY{eZnF3Bwe3SWlzfN zNsc`^!k*;VlN@`JV^6B=$qx3U#h$d-lf+tuDtj`^p3I(gm;08E*pmu-QejWhGp{S` zNrgSBoE5oW>4-h4uqPGvB*&hV*^@GRQf5ygYZl7v$vAs5&Yo1*lM(i0ggvQj*^>%; zQejWV*^>%;a)dp(fIZ2beU_iSw(Lp7o}^dA$Zgq^3VTvzPpa%ml|8AjCzZ2*O2QK)-v3mJ(*@trrDEe_GFqp znPyL_?8yVzlN@_;h&?&Po|M>=BkW0T%bujyX3DWA)vdJ*huM>tpRtx9U{A{INrgSB zvL`L}B*&ga>`BC)MC?h#o`BC)MC?h#o`9e9sj??k_N2<5RN0d%ds1aj zs_aRXJ*l!MRraLHp1hJh`33gm@$AV(?8z?n?Y#iX>DlopfHVp3X6N{dNpF)1x3Q-WKxPuN|8w^GATtSrO2cd znUo@vQe;w!OiFRfq!gKyB9l^NQi@DUkx3~sDMcow$fOjRlp>Q-WKxP-CZ))v6q%GF zlTzF=DMcow$fOjRlp>RoV^VTVN{&g%F)2AFCC8-Xn3O|I${{A@5R-C2BRde2BrkzR2F)2AFCC8-X zn3Nool4DYGOiGSP$uTK8CZ)VH-k4@m5+-GuNttF+rkRv!CS{sQnPyU^nUrZJWtvHu zW>Th^lxZeqnn{^vQl^=dX(nZwNr{=1m`RD5l$c4$F)1;V5;G|=lM*v2F_ZE{CgtHw z%9EIsom(d5ep_om(krZ_Cgo{N$|I}+sW2&@Wl}C-Qtr#7T*9POn3P8_DHk#+k7H6Q zOiG1GsW2%OCZ)`zRG5?slTu+)Dojd+NvSX?6(*&^q*R!cGLuqaQgTd6j!DTeDLE!3 z$E4(#lpK?iV^VTVN{&g%F)2AFCC8-Xn3P8_DLE!3$E4(#lpK?iV^VTVN{&g%F)2AF zCC8-Xn3Nool4DYGOiGSP$uTK8CMCzDq!OiIM0 zL`+J=q|7iWGfc`1lQP4k%rGf4Ov((CGQ*_IFex)k$_$h8LwndWDbq~KG?OyTq)am@ z(@e@VlQPAmJdjCgGbwE*rOl+YnUpq@(q>ZHOiG(cX)`HpCZ)}!w3(DPlhS5V+DuBD zNog}FZ6>A7q>L~rBTUK&lQP1jj4&x9Ov(t8GQy;cFexKU$_SG(!laBaDI-kE2$M3x zq>L~rBTUK&lQP1jj4&x9Ov(t8GQy;cFexKUN}fr{Gbwo{CC{YfnUp+}l4nx#OiG?f z37C|CNeP&gfJq6Mlz>SIn3RA?37C|CNeP&gfJq6Mlz>SIn3RA?37C|CNeP&gfJq6M zlz>SIn3RA?37C|CNqG>H5-=&FOiI9{1WZc6qy$V#z@!9BO2DK9OiI9{1WZc6qy$V# zz@!9BO2DK9OiI9{1WZc6qy$V#z@!9BO2DK9OiI9{1WZc6qy$V#z@!9BO2DK9OiI9{ z1WZc6q@?Rm#+Z~bCS{CC8Dmn$n3ORlWsFG~V^YSLlrbh{j7b?|QpT8+F(ze9f2??L(Yb zhyAyLDyk!DT$NOyjw(A8Few!#Wt>S_Wm2k4N|i~eGAUIirOKq_n3Nool4DYGOiGSP zDKRM}CZ)url$ewflaganp2?)VmPxsYNlBQL3X_tY^G#Pl!%ZgT2$PayQVuaGGXo!F zQuZ<_dzq9MvL`n(BX=?*cQPY)G9v|Mq`-`rc~VbQPg1T1#f%(eMh-F~hnbNAGg7eU z*AzQ3ZfCp;Scn1(QD7m`bsY!UhaWy;Aa8g0g2ydyuDdwK5X>?JOU%G`GvBdxq^8@y z%kP?ZWdI5czyaO=cbysdd-mG8*W>-N(tnfii*@4(+J02X(;5w|z*L_YvQpUNL`AS9)BBQ_$gj_bf@}EJ;PDQ_$%Y zbUKBz#y4)()!d@1x#g_y`abdBPT3>2r`GJzlyL=tZRTEgD0`XcA_}^Qf-a(CdiN7Gl7o_;TQv6;iey&#qX8k_e$}5rTD#4{9Y;k z&!zZV%z^He;`d7Nd!_ijQv6;iey&#qX8k_e$}5rTD#4{9Y-3uN1#mir*{6 z@0H^BO7VN8_;GWfU!V5a^rhtPP)ECsBsxPW9seS6t)R)y))Ss)rP=BfZ zO8vF^s`?xCx9acIe^Y<2{z3ht`nvjt`liaNZ*3H$%z~6zkTMHWWMV7(a?LJ@aa>{? zml($-#&Lv_~3o)0(x=gXQaf7rNm3jx7|xhyr-4I_mdJYkr1C`$H@yN z#HUM!7f5miNv8DkmL%ITtSj6NOFa( zBv+8geySC^62N7sok#6FYUfcqkJ@?E&ZBl7wezT*N9{an=TSS4+IiH@qjny(^QfIi z?L2DdQ9F;?dDPCMb{@6!sGUdcJZjIP_AF}8qV_Cm&!YA$YR{tfENai9=`Rmi$2Mdg z8+!fQUd=V{8dsH#E}9h3q<|&`G%27-0Tqs;LID*HW}aNcD8thodVxwW!Sqn-o<$?ZaUA8ZtORLwmFjtBi>_;cuz2D zr8~llXU;vXBbJw^q=QAsv}2MM?drspY})lwBLVgU3|Ku z)cHQ`=lHaz>*9CQv}{(PVKxBA3C&L_7i?>|DmPkeG7>D}7%Z~E$_d))nh`_*|{ z<}BChJX>wg{6gkl{`WBF`agW*FYE&I7nw)$_>amw!cH)Mka@J#t$M1=?`0lr9w8oh z8b|&NWtMNiEFb@Uoclh`Z6CL*$sahsbl0{U)T_DH*ZKKPzW-2W_qGpP-R3;E?N8YF z)^^t#a{hmF$8P)WK3e^}dW?FkdYpQ^`UUliYL9xd`XzO#dWw3gdYXE=dWO18U9O&~ zepx+B{ffFmJzG6TU9VorExk%LIi%RClV98T?9S(_7pfPlm#CMjm#MdI{Kd|bKPg)Cbk?s1K~@uT@L)~-=$iYVu-5*ZXW6Oee%`fV@7l0;E%t65@D3dCsvq!| z4g1T6{bj@cvSEMOu)l2BUpDM7i~VJ>XMVslKj4`k@XQZ*<_A3U1D^Q-&-{RAejxL^ zQs+LYbDz}tR;lxyl4eKJ>`0m&NwXtqb|lS?qe(mtyjALXtCaIj3Fn>CL`RzFNE01tq9a9gq=@5E#BnL&xD;_*f;cWgbR>w5 z1ksToIub-jg6K#P9SNc%Idmk4j^xmh96IUvCOLE@hmPdXksLabLq~GxNDdvzp(8nT zq=t^vkdB3e#=-{}3-4hpyoa&xe#XB08uxy~xOXwqcaXk=^c|${AbkhvJ4oL_`VP8x z(7l819b;q%-8<;sLH7>2chJ3q?j3aRpnC`1JLuj)_YS&ukh_E29S){rd_515I*8Ok zqz)o=5UGPi$1~fv$nsuPIXdvsjc+4L-G9B(>SNdJb?vNg4@e~D*gDQ=ztVoSFK}k9 z>(Fifbcdf7{B&~jr@OCr*|LAtm9G2Dl@9Qv16NxGZD(V*J?gfT#-FnBr#$c)*X6qr z=hD^Dr>`ZI41L#lb++G*+&aA~U*Z;#YYua-{!4l_&BX67`u#<}AG>PX9{tFrc4>IZ z=C#=V!6S9tGQCz_I!pLxce!r!g|6FtfjtWb{l@TsRUZRZd<@)>dCb|L%>2yRx2QkNoHH~h zxeU6uvCPMvk^c$5u}9x`g*ECg@b`IVwm%^=xc!N4GvrnyZgsv}-N&t_-0ItIb^0BB zab~Am-qS7bIk0AwS}{tk7@?MoiHR{WF(xh|*;3|F_WE)LrhYlnFGu?2DDyZ;>G673 z*N-rgHH~CVBU#f()-;kejbu$DS<@)iG>SE?BxqYn(6*AGZ6!fFV-3BP1Z^t`+Ex;@ ztt4n?oPn2d2A-7!Z7T`dRuZ(WBxqYn(6*AGZ6!h5N`khP1Z^t`+Ex;@tt4n$Nzk^E zplu~VJM$9tQuQ+R>*`wdpVZ6kypx`%@e1Exr>MiOw{r+3k+tl0r{0{$qqwnA8`**nt?z`1*srRUx{F^iItUBms-lyKLep~%t z>c6P}sy?7TsD4L%$ZP#!^$}N9{5_wSkNWyCpZGmKPuAq7@2io&Y4+US)ajY>>aAvs z-=^Ln8F(IMz>{t7@$-N7)#I4~@0tOR^!_!ZXl}ETLI1yi7-^E|Z@blPKcoKGfB(F% zf1VErQ2FG?{>Qp}PRvn0hVNij=O%+k)A?8{}Z zJy~E%7MPL+reuLBSzt;Qn34siWPvGJU`oFq>Gvc3ex%=z^!t&1Khp0<`u#}1AL;cY zy?&(EkM#PHUO&?7M|%B8uOI34BfWm4*N^o2kzPO2>qmP1NUtC1^&>rgwAl@O-PdoZ zZ>s$p?VShI9qL=I8Srg&Q03H^%B#bwpzK(M&P{Y~qH`0So9Ns`=O#Kg(YcAvO>}Oe za}%AL=-fo-COS9KxrxqAbZ(+^6P=sr+(hRlIycd|iOx;4Mr|`jZ8Jt~Ge&JQMr|`j zZ8Jt~Ge&JQMr|`jZ8Jt~Ge&JQMr|`jZ8Jt~Ge&JQMr|`jZEm2(4b-@S8aGhm25Q_u zjT@+O13$bj_sq4p=R50lm%2dROZof`Ua0P??ynx8SoA>_eUL>TWYGs7tXTBHhbs1b zkUbw{&Ij4@LAHGGvFh>a7u6Hg6V;QH<9P5=^%V6~Wjq`-9u680?O4>dV^Q0VMd{hd zi5aNG3{+zFDKYz$n0-pjJ|$+K60=W<*{5XCXLitMcJKx2h5p7DsTZr4sF$jjsb5#u zs#mD%)b%Ru^j@WIP_I_6QLk06Q?FNVP;XRkQg2poQNN|$qof0~NQqgb#0*km1}QOv zl$b$E%pfIZkPXX?x9E6Uhp)~IXNsB6}!Yu2c1)~IXN zsB6}!Yu2c1)~IXNsB6}!Yu2c1)~IXNsB6}!Yu2c1)~IXNs5^K--LbJ~)@X6?Tk6}& zp8IBv76(VvAvLD*>aZ%PqB^3+RY?Wvs4A-oWuJbtMTE z)l`v+RZA_ZL|Gj&xU9aXR@ACGFe33a{ zls20KQwZNg_$I-J9s%ME54TH_^R`?oD)WqI(nFo9Ny|_a?eG(Y=Z8O>}RfdlTK8=-x#4Cb~D# zy@~EkbZ?@26WyEW-bD8%x;N3iiSA8wucP}(bnl^i58Zp{-b42uy7$n%hweRe@1c7S z-FxWXL-!uK_t3qE?jgE|=pLeb58Zp{-az*ry2t1qqkD|*F}nBAy@~D-x<}|9p?iex z5xPg{9-(`L?h(32=-xs14!S4S6!y_QLH7=#hlt)m^b(?%5WR=!Jwy)?y@BXGMDHPb z578q;j}X0s=ygPIAbJPUV?=KtdV=UZMDHPb2hp2|-bC~!qBjw}iRev4Zz6gV(VK|g zMDz&JBSb%m=sgtgp?DL;n<(Bx@g|BlQM`%bO%!jUc!=T+6z`yT55;>Z9-(-MrcE?$ zqG=ONn`qiZ(o<^jG{4$#wZ%2XpEvUipD4!qiBqxF^a}08lz~8qA`lbC>o<^jG{4$#wZ%2 zXpEvUipD4!qiDSI>&gmU6pc}|hoU_c?V)Ihq9KZgC>o+@h@uS?ZJ=laMH?vEK+zCI zLlg~BG(^!5MMD$~Q8Yx+5Jf{24N){i(GW#L6b(@{M9~mMLlg~BG(^!5MMD$~Q8Yx+ zCWnK`B(K?ErWY|wK>?axalkECQcKsx~esb`9*LK>aE=aHOqnhoU_c?V)H7MSCdPL(v|J_E5BkqCFJtp=b|9dnnpN(H@HSP_&1lJrwPs zXb(kuDB45O9*Xu*w1=WS6z!pC4@G+@+C$MEiuO>nhoU_c?V)H7MSCb3qG*VsA&Q15 z8lq^3q9KZgC>o+@h@v5ihA0}MXo#XAiiRi}qG*VsA&Q158lq^3q9KZgC>o+@h@v5i z_E5BkqCFJtp=b|9dnnpN(H@HSP_&1lJrs>mG)B=FMPn3=Q8Y%;7)4_gjZrj0(FjE& z6pc_cLeU6CBNUBLG(yn`MI#iAP&7i(2t^|ljZic~(FjE&6pc_cLeU6CBNUBLG(yn` zMI#iAP&7i(2t^|ljZic~(FjE&6pc_cLeU6CBNXkRXa_|*DB3~M4vKbAw1c7@6z!mB z2Sqz5+Ck9{igr-6gQ6W2?VxA}MLQ_kLD3G1c2G1y(ZqU-zV#M;>n-}$TlB5B=v!~m zx89Fv$eJK)f~*O$Cdir~Yl5r^vL?vdLDmkkc96A$tQ}OSyC~b;>Z6zS(KV#4W_-%g_9WV#MB9^S zo1krswlUhqXd9z#jJ7e_#%LR(ZH%@t+Qw+Rgtkj)yM(q&XuE{AOK7`iC zOP^$KPTQo*T+#4yb=p(SZuQqO8b@ec-F7XCN)D)8-6kaa|0?cBt15_1d9cJJf53dhJlJ9qP41y>_VA4)xlh zUOUulhkET$uN~^OL%nvW*ADgCptu& z7WIefkJP8sr|ma>tNM)kV|APQth!x&PJLc|LD>ghdN?UPoRl6;N)IQchm+F7N$KIF z^l(yoI4M1xlpan>4=1IElhVUU>EWdGa8i0WDLtH&9!^RRC#8o(dPt;)M0$v&hgf=u zrH5F0h^2>EdWfZmSbB)1hgf=urH5F0h^2>EdWfZmSbB)1hgf=urH5F0h^2>EdWfZm zSbB)1hgf=urH5F0h^2>EdWfZmSbB)1hgf=8k{*_%hb8G@NqSh49+sqsCFx;FdRUSk zmZXOz>0wEFSdt!=q=zNxVM%&ek{*_%hhx&iG3nu$^l(giI3_(DlOB#q4=w4TB|WsH zhnDovk{(*pLrZ!{q=!U$u(Ox)xt1Oh>0wcNSd<UE z9u}pCMd@KtdRUYm7Nv(p>0wcNNTi2EdPt;)M0!Z1heUcvq=!U$NTi2EdPt;)M0!Z1 zheUcUE9u}pCMd@KtdRUYm7Nv(p>0wcNSd<=O=^>ULV(B549%AVs zmL6j1A(kFu=^>ULV(B549%AVsmL6j1A(kFu=^>ULV(B549%AVsmL6j1A(kFu=^>UL zV(DQ~dRUYm7Nv(p>0wcNSd<7g$@^reTs^w5_c z`qD#Rdgx0Jed(buJ@loAzVy(S9{SQlUwY_E4}IyOFFo|7hraaCmmd1kLtlF6OAmeN zp)Wo3rH8)s(3c+i(nDW*=t~cM>7g$@^reTs^w5_c`qD!rJw(z&Bt1mZLnJ*!(nBOY zMAAbfJw(z&Bt1mZLnJ*!(nBOYMAAbfJw(z&Bt1mZLnJ*!(!-kcu%-tO_28kTur4XA zOA70f!n&leE-9=_3hR=>x}>l!DXdEhv7``73bCXROA4{15K9W_HA`YiA(j+kNgk`y9IA(9m0fsr4v=`9K1C)xB!0*EAl=nR`4NC1HZ5J&)l1Q197fdmjp z0D%M$NC1HZ5J&)l1Q197fdmjp0D%M$NC1HZ5J&)l1Q197fdmjp0D%M$NC1HZ5J&)l z1Q197fdmjp0KrxQh$MiP1kjQIS`t7@0%%D9EeW6{0kkB5mITm}09q12O9E&~04)ii zB>|ji(_0ciO9F@_fR+Sc=Tjv!>$gMwc1r>XB!H>}P?Z3x5%P#t)pd5|ZuAXmCVq?IY``VsV>9FTYhZm>TtLn#Hs zh~Gl|7UHLNJwp5z;0PS07AE14J_5s=lXdj?` zYStsPkI}w`_ARupqJ0zf{yoie3-wy4*ZK+OIYPY%^&-@ZP%lEge{1s`pk9D_0qO;) z7oc8%dI9PMs28AKfO-My1*jLGUVwT5>IJA5pkDCLP%lEg2=yY=i%>5@y$JOp)N7$$ z3-wy4*FwD(>a|d>g?cU2YoT5X^;)RcLcJF1wNS5xdM(szpa|d>g?cU2YoT5X^;)RcLcJF1 zwNS5xdM(szpQzy%ih5PltD;^N^{S{>MZGHO zRZ*{sdR5e`qFxpCs;E~*y(;QeQLl=6Rn)7ZUKRDKs8>b3D(Y2HuZntA)T^Ri74@p9 zS4F)T^^X~Qt%(HstSv~VCA{G!ay;934B90>BC?bv`;wU1HBH}0_jw0eH zB90M*F-F8_;1D7<^u!H4abv3|uIq{G zdg8jCxUMIz>xt`n;sr!pK*R+^tm}#Edg3x7mJzXxh-E}9BVrj5%ZOM;#4;k55wVPj zWkf6^Vi^(3h*(C%G9s1{v5bgiL@Xm>84=5fSVqJ$B9;-cjEH4KEF)qW5zB~JM#STK z;)NgSi4#Oj5HUf-1QC<1o;aOfzPl$rbAGw5C$4ASrcTcS0^o?VtP&F z1}ZL~;vHx7!Rhsp%cxjJ#WE_EQL&7QWmGJqVi^_7s8~kD2~?aw#f7vF-t2v!uu(z9 z3M!USv5bldDwa{PjEZGcETdu>73-+DutmjmzB%oICs47DiVeMBLoe9S3pVtE4ZUDP zFWArvHuQoGy^wY z)IX}Pt8b`psvqtJ>w3YuUa+ngtm_5qdcg%$TtLMIR9ryC1yro-1?zgjx?ZrZ7p&_A z>w3YuUa+ngtm_5qdcnG0u&x)Z>jmq2!Ma|st{1H91?zgjx?ZrZ7p&_A>w3YuUa+ng zETdu>70aktM#VBJmQk^cie*$Rqhc8q%cxjJ#WE_EQL&7QWmGJqVi^^W>jjVN1&`|m zkLv}G>jjVN1&`|m7f^8l6&Fx(0TmZeaRC(<{x`i~f{F<$Ca9R8VuFeZDki9ypkjiG z2`VP2n4n^UiU}$vsF+}0u?7vaRL=5P;mkkCs1($6(>+}0u?7vaRL=5 zP;mkkCs1($6(>+}0u?7vaRL=5P;mkkCs1($6(>+}0u?7vaRL=5P;mkkCs1($6(>+} z0u?7vaRL=5P;uhlkctOU@gOQrq2d%OPNCuyDo&x|6e>=k;sPozpyC~l1$*6&E)9#3m{>QL%}N zX`lF$OmPbpTd3GN!xaB}Q!%~nO6yuDVM5#FUCZZJ&6zDK4Yp zF;vW>;y5an&*&3J^oi5@#G*d2f{e@h#AAqf+7|!MJ~1`Jt)I{*mJxBD8EzqBdCLs9 z5OMsBKC%2SAmZJ9Vrqu(?i24s#5>O*V%jJEI3lK2xP^$R6+W|1j1jSkh)qOnB4QH} zn~2y%#3mv(5wVGgO+;)WViOUYh}cBLCL%Twv5AOHL~J5r6A_z;*hIu8A~q4RiHJ=^ zY$9S45u1qEM8qZ{p4lhmi38cePUUkSl;Rre_C^D zRl8l!`sP(nI!mHs&-K{I+%Pi7+g@$H?8ADEzj2=HKW;4kV6JRLuDLifV8#D-XXX5y zd)Tea1Uh^7KDx91fb(Gno|gHQ0q4UEJj2&#XRfg(``4|>{+Kn{ziUnQfOXhs*~$An z`%azbQSS06UF)*nZ(a5$t;@dITIv^DOa0>QBO7zd;bG2C*zL^3bpMKbdZy0c&kR|QeZIPnXZmng z085|otE~gxgG5*Oo1bq_@)y{Z>qV^Lt2a(NY!WQtwsY+gRCY9qlP0tB!QlQ@ZM@t&TdB9a_5SP<9xT9r_$|UvBtm_br>!Nl)pd?~)t( zI_bW=u(h9)?|^U8f*xz8)tbkH>&bWI0c(?QpC(4o8#$_t^q5XuXoyin6Y z*L2V|9du0xUDH9=bkH>&bWI0c(?QpC&@~-&O$S}mLDzK9H63(K2VK)a*L2V|9du0x zUDH9=bkH>&bWI06t%Lqo?}78rbkKL{pzqQ_-=%}TO9y?I4*D(~^j$jWKCj&8mHWJM zpI7el%6(qBuY>OEp!+)Lz7D#tgYN5~`#R{p4!W;{?(3lYI_SO*y03%o>!ABO=)MlR zuY>OM%6(qB&nx$N7Z*m=$a0?rh~5Opldqlnhv_AgRbeIYdYwf4!Wj;uIZp_I_QX3j(FvWSB`k) zh*ypVt=r_4BVIY;l_Op`8vLlN_A&Kw^$F!z)Iqm&&@CNwO9$Q3K~L$Rr*zO$I_N1K z^pp;IN(ViqgPzhsPwAkibkI{e=qVlaln#1I2R)^Op3*^2>7b`{&{I0-DIN5b4th!l zJ*9)5(m_w@pr>@uQ#$A=9rTnAdP)a9rGuW*K~L$Rr*zO$I_N1K^pp;IN(ViqgRb++ zbzZs7E7y7DI+?7>GO^CNuX z(%qB(F7ptpxtbn%8I^l7#Jy#RN68TPmLVP`Lp)iAxJ-t)UWWKhtBRUd6E!{ZNsoNe zBQMJjH^>jKlOJxBA1;$0F7s?oTH(^P!lh}2OVbLM=FShO531i$A5tGS@A9CH4bN`- z=DBn=>za-^EA5y^yvQRy#3Nqp-Y;)Y@nuQxtjrBM_dOez`#kLPNXdY6!8YF!YZE-*d5OADxo6|Qd6mE6RsM!EA@^*2$WI^j(?{J`d+T?do90pP;ZaZd`(9<1 z;Ez1&OJt2@pUThqt>5se{70Y4zxOQO?A*Tr@7Q+l*r0c8yJz$_1J`Z*srM%5y&3V| z+{Y*PW}nB9b+694WU($;tV2u_jrpNfv8f zxpm26U9wpB3a)zv*CmT}uj0C7u`XGxOBU;r#kyp%?v-7aEY>B9b;)8~vRIca)+LK| z$zolySeGo;C5v^*Vx1*eL;W?>U-K@kc^B4De+~85?j8xe;_Ilnj+*PJx$f0pN6mHb zz&dKKqvkqluA}C!`Von(L^!j+*PJxsICasJV`s>!`Von(L1G zbtCk;cWd1Uy>5hFH$tx)jn@V~ZUyY^R>0n#x!1;f?M1z2FX}ZbVSA4Go|Ui*&No@L z61HgUywgh9IXy>7&r#BIl=K{-cRujW2j2O>J0E!G1Mhs`oiBOkOWyhPn$m%HJza+~ z;hitb{GrSrB0wnfFUb50j=Ke!e?jJ7koiNIf8KEz%KV|sKQHso%lz{`F@aA^;1d(b z{PUT2`1cz<#yfrgF3<1X>bKN;l(pM(d??3~AL zj-S7I=H`U)ES)_Idu^r>keE z%hcuSnd+C-v(&FB`=wa@dArr0w_E*ryValXwfghDJFjr0JX<|SU8$a{u2RoazpAcQ z*5q3u+OtBmXN73b3en!qm#UYkx0(fen|k}ksuiNEJ8x9)RPR#nRyWx%^S$anTWR_} z^?vo+>I3S7>UY$K)Q8n4QUCYVEy~%eJO4<1N`2ZnCicM9)0B*%C1YsG7+Nxhmh?0w zJxxhZQ!<{G^fV=7YDrI1($kdmG$rF}$@p3_zLt!yCF5(!_*&A_l=L(uJxxhZQ_|Cv z^fVwD@qdE5oZv1eaA1PFoZv1ej7nvrQrW0fHY$~kN@b%`*{D?3i-dZSP%jed zMMAwus22(KA`5zv1-;0EUSt7B7Nmp)qu7F8WI->opch%ti!A6x7W5(udXWXa$bw#E zL7G_5i-dZSP%jedMMAwus22(KBB5R+)Qg0Akx(xZ>P14mNT?SH^&<0nk$Jtyyk2A; zr{?t{^Lmkay~w;?WL_^auNRrui_Ggq=8dX>Q8h5C21eDus2Uhm1EXqSR1J)(fl)Ou zss={Yz^ED+RRg1HU{no^s)128FscSd)xfA47*zwKYG70ijH-cAH883MdXag($h=-; z9xLbdBJ+BYdA-QIUSu9S=k+4lL(EX=^FR;KpsabI8t%VgHxHE>Rfd%JGI;gPyU1NAE+);4^|Jwl%G|PWXm2U z6*!9=SMs=$$CW&;)TMR2_4RkK(%i%+xo zRL7=SEUNKOE&geRe_G+6R`{nC{%M7OTH&8o_@@>AX@!4U!L1qGn&F=!{;7>$$2q77 z!=}9YN4)wIUi}FSo58Rd3_CWkuyG2vX0|bNz_S*>tZEBG}fZG8{BrueD|x9Yf6$E_*Os%7;@%j%Do)gLXZKU!9Qw5dopc>h0=_>Pu>$`ZM)q^%eE! zs<|MD=_rg>N)C4^;~t8dY<}Kb+vjsYy1v%qk5-$mwLCl z$r&2&RiE_z@2gwXAF4l6pHiRR$m41rSM#`<$JIQp=5aNTt9e|_<7ysP^SGMF)p=aa z<7ysP^SGMF)jY1|aW#*td0froY93efxSGe+Jg(+(HIJ)#T+QQZ9#`wQTF2FNl}l^q zqDoX-byQa^sb%#&wW3zlDb-VbwWik9_tk&rdCuoOcBu>0y_C-*zSZ&V1iqcXw-fkw z0^e%*_I-Rifo~`9?F7D^z_%0lwuWyf@a+V?oxryfy3PT7tK(Z8-|F~Q$G1AZ)$y&4 zZ*_dD<69ly>iAa2w>rMn@og60X7Ozn-)8Y`7T;#^Z5H2V@og60X7Ozn-)8Y`7IS7X zXBKm2F=rNYW-(_Lb7nDT7IS7XXBKm22fdGjpH{c3&!|6Ex2eyn+tugP=hdI6FQ`9N zUsPXG`_!MQFRQO8$2GUL!fmZ^TPxhw3b(bwZLM%yE8Nx!x3$7;t#Df_+|~-WwKDj1 z^$qn+l~w!I0dvVBHMX&0yUO*3Dqu z4A#wH-3+%Caa$3$)ixK_HW$`57uGfx);1T`HW${$!{c~(++0}1aYYzPrG$byLC^ybx(VAPkVGvdp6C)Q~bB5s;B8{ zp01vuE>oAQXR2RT&r-jlu29cb>;odsA>te&&LQF)BF-V=93svk;v6E*A>te&&LQF) zBF-V=93svk;@qYY`E_4)L5Mh~gS%P>_hb}&3F_UtX-eMY>zmbE)Ngu@Z&hzoZ};e{I% z2-(mj?lxk-$%uWG5&NqD#U_2ufBU@pf=bQO7ky3b(mr4ROnq7XB-8X&|MoZPZ`I$a ze^CFZzOKHZzNxXW)s-#k5b=1F=)!pW5()X#on(}p4{ge8R z`mRci*1WIBl)qc|vs?GGTlceD_p@8~vs?GGTlceD_p=)<=FnmeE#}Z-4lU-;Vh%0l z&|(fP=FnmeE#}Z-4lU-;Vh%0l&|(fP=2C;Ei@JK#q7C@EO{F&NY+tvldu%*e7xiRa z)RTW;*v|F+dFr1tZO_`c)rfzq5&u>r{;iwl?YX{QrJkpLRb8!qO+8<|K&58xMH{)yEiS}%Y02u-L<~HLS3h>SE;#sm9ICbSF6)sNYiW zQ8y`{d33oIU2a8}9J<_!F1Mn~t>|(qy4->;x1!6fI+|;AG^fqrCw%XC(9v9@qq#;$ zbB&JX8U$(}Py>M)2-HBJ1_Ct@sDVHY1Zp5q1A!U{)IgvH0yPk*fj|ueY9LSpff@+Z zK%fQ!H4vzQKn(M)2-HBJ1_Ct@sDVJQL7>|Z z=r#np4S{Y$pxY4WHUzp2fo?;f+cu47!PlZXqQ+H81?s3Os|hu!s><441gaxYh(I9% zg$NWPP>4Vw0;L_<-FwL_AkYE=Eg;YW0xclW0s<`{&;kN2AkYE=eGP%WfFNk+jMVx%r2xoS=wLS-OK1r zjG_~Ih?AT7|L*Lb=5{$f&2~S?MQH|-c{2C6-l1o`L(jdXws6Wlep6@k9pnEI=DTB7 zAhE`wXO`k&?)6UNU92NGZhb?~z23Qf-q&Lry&Z02jYH2Ghu)6wu|~gS7ln&Az2%Y3 zd5{mf=N~r@GVrgS2f609wlBNcZO?td^DdZW zd7yEr;aGpDS7pik!{C-#{}0Ui5VL-7R{b$vrE?vR$1^X>JTCKke?uel3SX~N*Q-}% zUXXc}xe}9Aj`bPB*-`}J@o_V|d0Do`b37KmLo|yTXJqiEZ+|?({UH!JX zt52A_`fYPpuNb&8v(Mbbr%~@csP|55U_LPL^2{F%{D!(A^W}k8XWoi-E9NHjfSK2C zdz*TXx>bE9^ZK)I%)Dy*z10&kUo@}vMSGOKVEc0B+Iu`K^ZK3p)d6)!=JkW;t6k~> zbuV>qb)mX%<^_ZIR}WARR2Qj>)q~W7)kD-n)x*^#>gUv>)z7QPs>iEebU#l}PgGA* zd(@@oC!V67s-C8vuAZSTQ|8q=!y-zTDi2(X5dx#Q5nD3p}3rJSVX%sVz%t%aYfs4Y<2j+6YYBW zB&lW(XML#^Mo&>swZG`o%$_~n*Jt>88E0_0y247NEA8(2{Ehwo%CGw?(=$ir2VU+~ z`wex2o?ZHqZqogUVyUJf)vQW2t5VIXRI@78tV%VjQq8JVvntiBN;Rv_d%Sx+>#Fp! zD!HsmE~|R`Rmo*la#@v7mL-&B31wMAS=Li7>nWG@l*@X`WeH_jLRpqjmL-&BpFr(D)kF6$|m^_0sJ%CdyAETJq*D9aMcvV^iMp)5-%%aXyW zWUwk3tV#x}lEJEEuqqj>N(QTv!K!4iDjBRw2CI_6s${S#8LUbMtCGR0WUy*<|L6BH zIqn)ZHRVixqkC+0kB#oJ(LFZ0$42+q=pGy0W21X)bZ;2l8%Fnr(Y;}GZy4PhnR^;F zzU3WD*Ns)ZTTSm!=ySg2bG~L=eULFJwyW~4p*u6@IST%Ab8pr3(|gEDxsS`rpKz|w z6U|P#>Wg=O(S7~7cR$^Gbbop)@BU%;nICvHd(?K{9o04Neb^kU@!Gq(-zw$(#=ZWK z^X5IqZ<)j1#$#Q&vFhFyJ&W{_1LNn9{+D!?`Gngnc(jT~yVE0_^av+C!jj*qISMcJ zDSS%$iOk&B$aRsC>;9WZVLG>b*zX**@^70@{iSB^Uz2%)UAZ4NaE0Ahuk<{hZzt3j zncHnU3hbifUb|k8bvsKx%+Ase^9V;WqdKgv4y&uf>guq%I;^e^tE!5s@xEic?-=hp#`})(zGJ-a81FmA`;PIxW4!Me?>ol(j`6-@yzdzAJI4Et z@xEic?-=hp#`})(zGJ-a81FmA`;PIxW4!Me?>ol(j`6-@yzdzA>#SCEP+bJ=X5OZ5 z^xWR-zkkGTD!+?NA9ajA$-DSW$LzCIdQP<64hHOW;9dNVuBK~Vs;h%JWe)0;?&Or? zxa%11JBIs?;l5+I?-=eohWn1;zGJxW816fU)16CJIJ&;$H(guScl`DpzkSDV-|^em zd31Fir*s=#iN7oHcP0L=#NUDH_ zcU<=!*L}xz-*Me{T=yNjjWg( zS&`~jB=D{T-j%?+5_nev@0wHSO5j}yyeolsCGf5U-bMVb1m2avyApU;0`E%TT?xD^ zfp;bFt_0qdz`GK7R|4-!;9Uv4D}i^7FH6$nlJvMPJ+4cS>(b-8^tdiPu1k;W#+9yd zrE6U28dti;m9BB6Yh39XSGvZPu5qP1^xe%}4!V+IS2FBMhF!_9D+QiP9lq5H&(A#1 zarZpO(Q|dmj_}O6#*2neS$baK9ma|||Mi3;@r1FW?Nc_pbrh%LMA!H*Z+w_{to>Ey ze80KqH(T!cQ3Fr5Kk{XnD+VrC&-QOuI-Z}Od9+9Sd5`v3_jH$gT5{wrr6Z1eIBdMz zW?j&w&hFo{x#HsQJ%07>k-)8MZe2@n?Kp4wjT4(=#gto&d4@se-hTgYjd_cn$%JQe z)T92D`#9ki|Kt|m@i$mO<7|;vdsH^j{k7a*%XoLn-xBy+0%P4NV_o9@Z?j|bwvBgq zMt6_G>Av0n{3x96_q_Pej(+K?l)p9te$@#0RnKz5vmAB*C0BEJoZX;bp{`TcXD*Tq zha|%R$#5w14t0}v>wo5*MTu@mq8pOvh9tTniEc=u8XhRa(kc2iQp$$oB zLlWAMgf=9h4M}K2655c2HYA}9NoYe7+R)&C%{*%GhnD6 z6FurfJ?ewbc*JXr|JP^!(+}PHfpYc5nGgGooBYO${l+^y&!?a9TOS+zSmvG{>mo_- zy3Ci{!;6089xinc?{g1ta}O_Z56^WEPdwuu{)@lrVeaJ~?&X1Y} zc!Ybn)IB`eJ-qvjdpO76e2KsLeD`qq=HLA2AG(K&GcWYpPxaeB=eN_V+T8srztpGh z`pgS{9>FJjK@p=)`z-> z2W+zR?hI|;9%g&%S^XdxkNA8Z+59Qp=epph%H~gFemdZ%Lz_RP`@-Mhr_s!xU}}V^ z5vE3%8ewXLsS&0|8EZ{3HNw;gQzJ}`Fg3!|2vZ|WjW9LB)Cf}}OpP!#!qf;;BTS7j zHNw;gQzJ}`Fg3!|2vZ|Wjqo#K855QnSaXI3zNz>8@8FgC*2XuDl+*t`VOB20@gEyA=2(;`fZFfGEg2-6}=i!d$1v$MEhL-W|ic zV|aH=j{dQ`{cL_F(?pq4Vtn(b^r{P4KjktP%E<|4%wWa{W*owdFKxZ+o43G>0%jC2 zqvn{bW5x;0h%uupBcH^LZ{x`YB8?={NFt3S(nKOnB+^78jU>{DZ(oxN)7^I>sW8gCO*yCDCw0{)bj3ZVd`_ux zMEZ-QzexH^xau_tFp&Tg32;TSYe{dB^p;3(k@OZxZ;|vCNpF$#7D;c3^p;3(iS(98 zZ;A94NpF$#7D;cB^cG2Pk@OZxZ;|vCNpF$#7D;dE6^$b4Et1|M=`E7pBIzxX-XiHO zlHMZeEt1|M=`G?}*Lc=7t5w!`)-|4WZSZWhUH$LQv~%Q3WRXM`No0{k7D;50L>5V8 zkwg|rWRXM`No0{k7D;50L>5V8kwg|rWRXM`No0{k7D;50L>5V8kwg|rWa*08bnmHE ziEP!UaK)!^#iww^r*OrmaK)!^#iww^r*OrmaK)!^g^PN(eLz;l3ouay_U!H=6^rrr~mov@20`T=A-TNXkYSZ>2Z|q*pyzuWcq*k zm-Kn0XM(jh|K)(+xx??InKM0BkNB6rAFXSt=!1psWIg zfR;rOMF9~|kxc}OECPyx>;zE2B7)Vjgr$Nk1(Z#+RS?0lwa}J?Ht9OGZ9-cJX*!wC zOlHy~O(wDPyuOnZ3h3|e|NNilIp;Z#r{~>SGBe-rz4v`T>%E`r(_!x{EM7Ytl{Z{F ztT44{f7)R0%=fwQESI|Cx56L_{t&DFKSHSpI*h_=@FTBU_OqAJ0Up&;1jm2kS z&n+o_?-Add;%ZZT?}KPlc-M!z&u_TT@$U1q;uXU&4X-%27_qv?H}Ce%yS*EZV5Zoz zYkcDv-#E7TjnKCb?__q-yS~z=uk@=Ud}eE(*|K;C|L{A@{AHOtSm5)aT%2G0b|@DI zM>SmO{OR}GFt2!}iGJk{L!W&AZ!GY^Pc{^P zy%-rN`X0F=1NZjrFZlLxzWp`t47UGG8M4LYlV$wExe{8+gO@%M|b zLZ-L+OndQnLLL=;55Kd-x8C%vaDCL!Ni*I_6@MpuC*;CB?=1Ds;J4rKZm1PDzl+z4 zBh+Dp24j;>weqRry@vhc-NCyLzxPJ*j>4J#0Y}4mS+rK(zrW%MJ??L*YtMG=dBr^l zH@LzLIB`%nASOrHvS=uMw` z#rI$Fsafy$R&gJG@jKxhf7N$h^_@`eEbyJBz7zMIaPQ;N;ys7g4B0Z@UltDC&7jt9 z@RyKrgUng$S+e-Mn|o2=jM{X^VQ+^mo?rabJXfFR>hoMZoaIHSG<5aiUWNC^Kis{r z&i6u@ePWTXo5ncYr8zjpArG5}?sQ&}$>C?-DqiVsR~nqBgP#d^NrdeT*%|g=ym+OM z!C`MN@=javN+Gw3z2&pv9)*SevaI-vFZjh5+mM9c(T$ z!oL({jO&E6CmiqD#qTfj{lRrAA^cb^KRkrU`^rp zAhB_M&|Ww-NEQy#f{X0fm?GBs)5w8NH#-Q911D5F*|FZqj#oR`@oFbK);rm;-pP(v zJK6DSCp%spIR(BAr^0vOG=D!G&hUIZoawn!03&BPF>T+%;^_WxKw)ughr-`tqhUwS zcY>W^jMuw(+!c0%-M!ue_JmKvUf$aq_JOfp`@PtHP;G_$-}J}}dSq%4uC;V7bFj$% z8~eBPN>Yz3bRuz!URkPFGC{MI5N{W54O9>cR$Ec=4v3otEoRAk*2K3$oA0glnD9Gd z(7`$q?2y9M#_C#QeXZV_?sVbRWzQ5E%Kiv{@_ZURC%UtWg}b4!T5nF(n^X1XRK2-U zZ?4pvQ}yOly}43vuGE`T_2yK)IaO~?)tgiG=2X2oRd24;n=AF^RJ}P>Z?4pvEA{5o z=t(LpU0Zl1I-$@QbzVaB=N_H)6?Nu9)VX2NJG{OV?p3YmO}WU=^BvCg_+7XZE`!U# zegG%3uCBZa><6fQFsh~2fv5M;R$#Wo`R?05AY295&i^I zVVX$YjNmQ0cRo3@s4xkeo3Qx_bNnuheifsq2FppO6@|Z==fA+}=@`AhTz?#+>o7Wj z(ep8S0!B|T?|*~UQ?PmhR$pWOugC03m_6D2UoR^DfT;KbWxp>pV)g{go{!n{F?#}L zPr&R604pb89ztek|Eldy6UR!+joNmw}vD<@&)B&?i-m6Nb?5>`&a%1Kx`2`eXIr(^wete=kc)3JU! z)=$U!=~zD<>!)M=bgZ9`_4BcQ3f51-`YBjH1?#6^{S>U9g7s6dehSu4!TKp!KLzWj zVEq)VpMv#Muzm{GPr>>rSU(x-Cu99&te=eald*m>)=$Rz$yh%b>nCIVWUQZz^^>uF zGS*MV`pH;78S5uw{ba14jP;YTelpfi#`?*z>4ip7c+pr)pM%-`Wc4zvZY?r;4Qb!b zS~-y)ak8j4kJf4dCnuO2y}r?FZe+}jF4Dfkw>wDqF7qL09(0%o9r)jY|7pDM#`6yR z?!fO3{O-W%4!rEZ$qtaIy<0yKu4#C%bU6%eZtKmu}ap^WL-NvO`gmtO^dG*HQ?|Lv#A2!m53+cm!^5u>4 z<&E@W=#7RRY-p)2<2}XgPI#N<9UQ?FIkdtEHkSMkv7<7PG`_S5ifgWR%~qqAGI}Ya zmvZg*j9x#9wT#4CW)xFKF=Z4}Mlod+Q${gm6jMeqWfW6JF=Z4}Mlod+Q${gm6jMeq zWfa#L#dSt;ol#t86xSKWbw+WWQCw#f*BQliMsb}{TxS&58O3!*ah*|IXB5{N#dSt; zol#t86xSKWbw+WWQCw#f*BQliMyTHi^&6pnBh+t%`i)S(5$ZQW{YI$Y2=yDGek0Ux zg!+w8zY*#;Lj6Xl-w5>^p?)LOZ-n}dP`?rCH$wep&9dM@Cwun=vUowiK9s2o3ZfUK zMyt|{87>1og0;C7Ut(+d>uq3L7|DwLq{r=e*P}dc4^_@B-2p!3`DoY?b~0`|dmO{s z-PQBmJl`Gm@O)2?pN74R{@xz*jF@cNsDmF35KH2=y^@OWaOz5FDfSF5J{ltOE{2nHKJ$;MAtq}A|LA*iCK z&=FBpB62pI17u5d6pVw%3Jasp!{6X#m`z_c!ZKI^=1XM^^mpZvaF*xSz)wA&0C%d4 z@uph%@38U`R$8}17IM&O)%9-*ZLw#qM^KwSrmtf!!z=JAyauxh@5E-q9H=iWiM{1< zE;K+R%!ftf@?wum3i070)5Bk7o9t3j;bht2_RwruxDm7Zjs9dKoi@^cG{YB(4u|V! z{;-+6&WH|QQ8v5qXxVa6))GBAOr+rmJ?ShXJ)736ZF=-=JsA4^S<&M0qQ&2eoNrIU zopQNv;<{>?TGekQ-z~vpoWBUq|LRVjbSDek$q#Y-E*!7M@oF5eE*ZJ;K^*@)j>mAk z8po?ksy5zNvIBg|^U<&)?6fh34 zZM+ZftBuOh_+DN9&5hr|_i7_^5WZI%otw)~^0|}Yl)}#C-}ZQO;U>1>jper%ZY`f! zxE1eX6`74Gqc$e8u5e7$302X@Hm33XYk0m_^kvUyZ%joSVHvEji@&{4QW@Krs@yH8 zs@z?6@5n-R)6-T@P>cgf!Z0aL1`?0AHn;s)E`?0AH zoBFV+6`T67sSlf;!KOZJ>LV@tF-ffr>sIXLvmUL}dbG4T^PV+l#cIW6_V|>kX<`m7 zDSOjnU7?56>?xaDc)M&KEcE=nLLWBuVN)MA^^;WPqtU7wy=b>>nH8{NxOb5=*NP7(ypJh>%)LP(yku^ z`Z1sn1Nw}9uaSSz$iHahUo`SB8u=GVwl0#bi)8B}*}6!!9!%)NfB_8X!+<^v=)-_M z4CupvRt)Gf>Rm>CfJEyTRejUCtRPrb`kS(g%l8~MX4shFsjcrH_M^yQ(HkpwAAZL0 z)bP}H_kQB&EynnF{D^(GyLS+~UO3|JT`%1F{%yWA^7&7mvE9Af%^y`hs(kdAQD53| zpHa7Mzs>fCZU3X~Q`@ITA5qm-wN2GSRc$+r-r?vS?jL=Ge`9v|$EQy5Z%X)l5PO!7 zp15cEj{Ep`&W?BNw0-z**UU~w?{u+$xB7Sgm?w9=aM#Rk(LHwBW3N5V@bAJsF4^PS zJ?8FNzUQfXHhg;5^M-x;8=r0(_xwRe9K7(5ScpSrf9}vjPdL2#$T3IO9C`ndzdL%& z(bY$P`J2yuv*DYozL`C~^!VuUTOL31_#KWPbNrsi?|b~g#~*h5@h4q>*-@uH z%s(S>ZuR#*ao(`=K6l=6=QW)FrSl&@|M4rHyI{KuCSLHu1+y<${Nwl~rI(y?$sLzQ zFFpR!3orfMWk+4U&*h)H{OHTix%`UDZ@c`t%U`*C?&Zrb&tLJmD{j5w(JP+2@`{iB z>$@HxUS+rYk_aBc&%b) za7)FkiaEi=ipGjX!K8|n74HVM6>Sx3gUJ=`6`A0^itdVh@Nh+8*s$RD!?ql@W$?#g zyAInk_|veyVST}~k+G3ug6AT~MZOa(3=Rs`v%kBnQ0%rYqBqz%=!1efD#NV+9AQn& zR^pB$MIApWrnp_9P*Np#u>kNaK*QXR-Hg5|Rt{*u#7!x@g&I!guud_N>{R`5% zgl^86o3kt5v4Z0_h38|>2HVA+gTFe{U92-E!(c8JNZa}5+|r<0t72NUjaEgpYA3DQ zNvnRRRaIK`XRUfot4g$HxYi6GYRwi}^Y~C}wi#;8wpz23)@-Xa+iJ~DS~6Tqh7Yx5 zxRwmplHpqNidIClVzgF_){4lwxVuhj1&*g9LuN^ETf*fy{&Y)40o^0+;G3P!_@u#>Uc+2fePMEYPFeUP9J67<0h z^g)6?NNDA~^g)6?NU$zC>4a%?LV^`h$AYM1IV@l~EMPIuC|g`;XDQEMMWk2}DRMtS z?kC9o1i7Ce_Y>rPg4|D#`xD9i1i7Ce_Y>s)G;)6;xqmOYe=oT|k=(z5+`oa`PmuQs z@;*V{C&>F7$om9&|0Y>KjjT_Q^$D_m8d;xUA zG#0`_7Q#Xn!u0ZqB1mcbnKOlHEaMrh;Tf#q8LZ(Mtl`i~NV5{stYKC{VH*7~jeeL$ zKTM+^rqK`6@UExQDe81Yf{vI*M@*w55_Cku2);~5+(Sp)Lr2_0N8Ce4+(REEaIl*` zNYDof`XE6cBi`!R=|#isf?@5>pda3(AEx0dUKKg|0Y4)}UT)%~ z*;V8mo_&;4MLuof(1GlW=h+ss*cO+uEly)woQ6wz+?aq5Nxym*8+siZI$WQA7JJ|a z?18h`13zF>Phk^W!X~(~57e;->evIbjQs>-J;4}H zFvdw^oTS&+(CcfAZPFdrR~%UQM#VveW9jA7^xuH~dq)2~qyL`Kf6wT@XXx1H>DcG# z*yrik=jqs4`Yoxiex)*$ItJ!&)a=M;-CO#pT?-dz;Vt~nj8l$3q{XcTVS9?ZCs>mIS{sxiqAc|+bh-_oL0B znWWwrcfS+KH(CoW!P0%rk)OE3@0bf07p>z}g*tb6xVzlR{+jSEdkYT+eb6sTSCHGP zlz|-X&PNn(bH`Ij!y3}ChBT~k_j{0rHKbvUxWXRd3VV=>HKbw-P#Z zq-hOldK+n4Lz>o*rZuE#4M|!=;k7){v|<7;--;T0??9K!Vngpfx0D4GCI< zF*lK*HKgZc65&nUo`W@KV$JwqcapP&wvUk#BT0#oSTl{L-x_27f-y6PG<}q&j}}M# zfWkBEl^9!PxEVi^b{|f=4>#LK((F-uzn4aj;`mFn`L?wAwzT=SwE1wnUXRz?;B==u zeq+cUiP7XSd~R`fY1UN146Bf>-jakJfxBB-alM!P`~ih$N!WH0b_F}5i;dC6+nQZ| zMDPh$Yal6Ckd!MT=eyFKG|-#ob5)_hr7PqU0+6$ox$(=zPs)xt!9!|GfAtN zq}5E)YUaO?@nQ5Q^pl>W`@|QuYJD;4Gw2DgHNU%xQJ=whUYLjP@ar3bYeCoZa0hD&Ej^mxV>y`A!{bLo5}5F za(huXraY#BBuy4|d9 zFV{Qe!yw|l;a-2O&~0XSo7vrFcDtF~Zf1uO!?c;5HnYPhVb<(To4ws;Y`59kZMJrs zt)a}$o2_}XHE*`2&DONpnl@Y0W^3APP2+pJ*&1r1wAq?ATieanP$RX9l&m+-4;kl& zjPpar`61){kXhU=N|F^N$&&Y3GrHZ3Za1Ub&FFSBy4|?HY(}@!0~zB#$BgbaqqAmo z+PND&GShsc($`%XcLdBJl_F6 z%%|=lK0S+1-J9_#y&0cg*o;r}@u_==PyZ-Jsb4Mhmdz0_agH}jBv&S8A&%MqFF5wf zM>zH@jj=h$x^e7TQM(s$>{%R3<5;@Lv0fHUAB0@%FU;MHZ|Nbvg;vZ0oa^3&CUYxYkWetfeK^(h_T<*NMA)-0tqiwQgMN#&CV2 z&A8T$Yu%f1Ern|@;@T`+n}ut$aBUW@&3ZrjJjl6MaPAeHoBMA#mmcEW{2|MzyJ#7G zG{*ZqOt?#2_a~&lA!4sDd?fbzQ+C0PVXRee?O%*#hH=a=h8e~$#VsS7$0j$$C0A_h z(bAG3%V>1vH5)sIVveVh@73=5`)0*)@5c={j~PCUt2Hd6i7cauX2-vZNRK1?#*uyF z+<61u9)`DD;_W!{Z=8tqLJ{eOcsq_997hh06Oqp0?KpDqI1%YCyd6gljw1&T$J=q_ z;5a=HMx@7)gX74-n22-^Z^!ACzRh~&6xPyRdL>+KbqZ_g6xPzYtfg~@BGeZRMW`>* zYuB=ru3;%%#WI@68k&gXEXCNt~gSq8*_L)jw~HVmL7xG$B0Vj zM5Pzv^|+y^^thp@^thp@^thp@bWT({7mlu|bdJUJa~4w=mHs7*>5=k@9)DGM#2naC zbUJ4aoM{f6X%3wEAvQd=apRD!97d`)id5%Bs&gXMIdkEtB12*ubMLd{$ig_0>Rgd6 zKlOY93`VL?H7AZSCyq5Ijx{HaH7AZWCyp($X_koe?80H@!(l~cy;V4i3_gSm4kOj$ z$l!5Bwk`JfL8SUBviO5YHLsy)S#8O(8qKmAjd`JE^-0q5Ut3ny?A}4^YD?DD2-ekT z*3}5s)d<$rXt9&%`xaIO3u_pBU}PzzHeBa=H=EL(gzFS=<=jHLkYeX)Ata z@w0=Te@_ca==%5EeF+}EN{5G;z*q6^RlFPY1Vwl8?8Tzp7-sy68NQ%|etwUBevf{B zk51l{#e0dYY{Z`~{K?@@0(TPRW|+x)kB)wij((4heveN6H`%(Op4pVG8?r@lVKy$z z#)a9qFdG+U7ki9HSnREpa$Bnky>#t+^lYR3g(Fx{Va|4>oxyv_nO1w0OVyHeF&7!; zA;TP`+#`Fmm<#laZNU~SwO{(iuS0u?y&0Z@7-wJpg?-t?zRa;NFJrB(syMK4R>eWM zx2o_1*Zbf6mTL|azqzez{lc|+-Q8oZH`Dc=cfIT6|H75v;i}0x*Syf3H<{PH?tX*$ zyTRSJx`*@J!+DXlg_ZhM+*Z4LuwV@atnI<#e0;Cd6D zH{o{^ZZE>^MXs}Wh~MD~*KjSx5}a;gYj)84O}N{Ht4(xz6P`BVWfLAY(brA%brTuY zL`F5y*G+7~CVD!|n&o+BSvob$-ZqIAZ@S;XRu$Kkf9yVY^{Mqn;Togxs!_PrD7UzK0<5zq9YG@(V`?Z(++Dm@zCBOEPUwg@~iKXjz@p8VE+K8eE&(L>IyZ;QHhP!9O z6~T*e^Y(B?8RHa&_hZ7~9Q>Vch1FkP^sN_tt7G$Tm34~LkNl55nG3cEKOIV2vG$^r z4W(ygf>dpXEaadw7-2U;I0{?2+b|wJ$i(yz6W95bs9zc8SB8<*!`yX~yY9oxcm3k9 zVCSLndv|F3!d+W08^800Vv6St#T2jei^cs3#_wF?cY*P{;QjH-75-#4{b^_%-__&q z>gjil-5JL2488rh-hNzfKd!eQ*V~Wl?RSmaND^T$tT>=3h332Z0{ymW2XApDzAG*? zW__f>Mm@hilnQ>i-Y?f{ODJjcK{#i6^g`a8=`m+|uwlTw>G5mx%#R*S7;s+$?rXq2 z=`l}w%#$ATq{lqzF;9BTlOFS=$2{pVPeN<2$2{pVPkPLg9_`3$M_xPf+L70eymo~7 z!5$J|(~j+9v1G6Uc5(f=d(64VR56~h#yy5CU7^LRePiiRi^G`h60Phm|7LNN)@$Kn zEnMu|Z~OKu#W@;E?!C0M)30pM(oQYy)Y32$@NcUbXnm*FcWQm7d9czvSg98}^+Km! z=+q0HdZAMdoqC~DFLdgKPQB2n7drJqr(WpP3!QqQxISNp;_G$d!M`^nv^=ZjSuM|Mc{coItq=X|totd>4!w}o z3t7F8)eBj@kkt!Wy^z%lS#qaaYqQ1N)7?eQb`Z%C&YoinwZ=c(c@gdwnQLTkHJY~= z&07K+^e}w5`%)*`{fBXi1-{KsFWLk<8|O9V<@%zn_7;76i%%{zx3~An`(>cR%vk7M zkFbwrFVWVUc^19A;H=0}#^-zedY8!329c$3O;_S09&sbjqJ?MCw3$a7=Ml$0;t_Wa zdBo`=$3zi^A}pJG#OcjE;UPM;*$Nh^F&__MO+5w%ch8nla$Pz4s)l& z-03iPI?SC89&pzBtE}i+MlK*D7m$$)$P7hcT6h30JbQy=g@=P~`%dI_f(_7X1#KVXJ?~csWx(S<>A65$u>{JX94ZRulnnD2fvEXYNuI_$ zAI{d^l#|-Zu9uN=5Y=q;e^F(k%vqPBq{%X8U6wiP5-T1qd)ebF@G6A4sTm$;!t3Cq ziDIs5PT|R7zUnRSH9(`)=kq--068W0{6N`KkN<#WKD!*O3@%&cb*GbGz9MgRBzzUV zM&2I-$H6xXkDKf575am%K46rm8Rcn4d0OQAg(Ta3AY$Er#G3zzvpyrv?~E)4dqv2F zWF!IqbOy~RCsR0`BYLpsUjTVA40)0q%fy@jV?-Y|q7TRZT6jJ7yw`sNeG$_aF@0gA zpE1(U80lw>^fNJi5Sv+8%B~-9vd(%QO@)=r!$~mJk4cFRz5JA3epfGt=ihzk#27u? zqc?lPICR+(ns>Q%hQo0D2xqz+Wewudh2>iQB)z$mHJ#K0>+LlP_hl7#YVmGo$OF9S z?!(w@mc^P2B@nyTibr?R=`M2a;IHnWCAh_3mSEHdOj?aetFdSai8L2Wda-1QZ-mjf zdE`!=h(?`=MxAdzMDB#Ep&H1YIuVUJ`JTtgoyWvPR9k*IUqpsxB5ZViSd)x=cy6(O{x1Z@jY2ir!R?2)Rj4X zsf=_dYwAQM>O>~$STJ2=O`XU@oybHTU0F-kbdfcEWK9=Yvzp#qEizFjGEpb$_BdHn zCo)k-hprZxsH074$(lN{rcP8Mv{S;BPPL+KkCQcZ7`Oxjmtf!$a;Hv|w@#F|j`pdg zeQIf*T2Y4v+NTyXH(=%x%xuEUCd_QY$|V@L1ml*FL4PBI{zeA&O5**rGv2)=2;)nTl9^nHiE@6g5$ZA_B0Npdzx&L+v(q;_r4t_`m9zmi*_3>lIY;k*y$ zdN{X>_tNAZn%qMV3+^55`?qxtSaUh|ll4pQnS1Y=d+%v;vA%&{eb=vcTB9?P?EEA- z8s<8x%(optt!!5b*LdVysaI=PX>F_4wrXvY*0y5e8Z8ce!qPaDDVdI0a6H@4#trI$Y+Ylgr@>5o)K_M6ZIY zp$4vj>kCguZ-5)&XK*w80&am@;g^M{)p{H0Ztf}V3ChG2%Aumr9ME||#2(NnRC>;0 z2!?z71Z)9YdVhq+t-Qar$8BI+YnDcO{3L8=ht(*L+d~!X0H5-m(Xb=z8=?|x!Fc2EWT!vT8jGu9e?7Oag4 z4g?lxa4;NVH}mJ<^KfY4mEa5BI}E*u`!Pns% z@J%=#z6B?My}#%lnaJA<(m~;(X3)jI<^v_RS(|I_7^Kb&^ z;iy-$JeUAC!Oy|jIDxZq0%zj{x4MU4!bCL?e&zMAjmcnL$TcNxw9Hx>Il;mYcc`RE zw+v0!A?A}Mr*f=gHDyY_Qh2TOC>2h>>hYMuJd8fL^y^+9?^L)Gg0ZD1dM?(5;g^*< z%dzxqug~>2=QoyKP?({@YaH`0EB#@izVt`lzX+V&SbCZBjt0+3no)X{6MnB%CHuPK zIZ17$+EuDu>gcQ~y~QsMn9d@8I|FIM^$r z#!jmADR>(G0MGc{Kf>Sav^K*kM#4^oc*P8RX=Z|b&K0wRtt;jflIriI)Za;|zmrmb zCsnZsR>~)>_W5_<-NKBDHlJHtc%x#SM`t7t+qIA!wp*cXSa>$mo`vPZ`dA`k#m@GH z{h%85hXdd<@L3T5i`aGTe2P_(&x7695xcJ=hk=Uj5f$B?PqE7R6sw$1u_~gXdqhR| zh>Gscr&twH(LJJ~dqhR|$hq*nLUZIi(D#uG*>^t#eIL1~FgJ2B{1`5QE8t4+Uj9KH-+fg^xF5j_g{6wV4sM85{dz_IXku(r`zA&IE=sscwo%>LMs;T!)tzlr zceYX8*+z9|8`Yg{RCl&f-PuNUXB(q`hQGkG@SIh3FL-7R-ftFdr6pe<3V_#jpgdi&b@LM)V)h1kLa^tb|pt8r}gi zE7}6Bum;*-EzkqeB&-AVXQOJ*sxOvOUn~{Pfr?h@i>1^TOQ|oGQeP~kzF10qv6T8^ zsc0VhVF3OK8^yr3Qpx;(JTuISqW}Ff!+KO299H=spBW~m{NXdh+EmzYQ(?bNh5a@a z_S>AP(pLEm_$C|=_GDF_04Ku9a7tlD<+tHf_zs)~r^6XA9?phy;9U3~oCiEm)ud*q zCN)DfsTrzC%}`BhhH6qXRFj&an$!%{q-LllHA6M28I{+;PvCmjy8&*3pTo`Y3%CVt zgq^P0*Y*Z|fPtLWAoTW-f; z()x~dkOFH?Vj1YLN-hgI=!EsqRhSX$2J668|C*ut*Nj-7-G+JShXMF!p^+7T>G0d- zMDKvV7m~y2xZ&o%%I|xqgK`3JqaET4Jg!%jslqP9*@Z{MO1dKUWk>AGjvNPH z54MVYBiJGGP0x>qZ+U%!9StXXeiEDvr+^HpY8*M$IC7EGeCBlDIm7euaHiMa^_{ak zKVMaj2fThTcslY>Fg^0H=Tkg?B=~#edC&jm`3v5EF*qvncdw^={gS`E?Dea`7Lgg= zo9VsRedZ1C&GLG-*K>U4O|P4SPetAi{u)^s)JL2|6It!`JHbnlcZ0c+7Oz`_Z6fOm z_eS>(eihv>xIenT#{+`jMo%i-7QI%@m75A1qZ5N2qQ5HHE&A({9ix+iOQW|1TSjjW zDq=eZSH)EJjO}dK#x9=k8vG)*o9BCZzPI=H@qAy;_w#;ru$57GVYrCd@V}I7KioR1 z;m-x<4;NP${(MkA{6(3na5SFyA4cOrqmldXXat}5$Y_*DZ!c{8zkM{eG#am(3-#v0 zpUs8ExVkPf6>k>?pT(KSqub%ZNgi(s&WcWC^{`moNz(3|J=D}u;m}wvGqVzA)(pS& zgkQR=WVmR|Z0mEy8H{JbcrG)$mYH44B44-D*}4p~Ynj=#Os$)a$O&+w=O=+mUuM@b zvul~zwan~V7CFt|Plq!+9}g-pL{wlfyOz1*SKR5%?(!yVe$|~u-D%vN#@%T=dT+6^ z@jS92M>gctu-%Bd{ExkaE#|sNfS#PUZZ>w2vt66WW zS#PUZZ>w2vt65pitgL2M)KXT|QdZPbR@72f)KXT|QdZPbR@72f)KYUoHB|A0xOhTb z>>w^akP{DxiwDHT1LEQUan)Sn!F=e4Fh5i&8`H)YJPM9=`p0p>m-&(L(r*M?^CJ)D zN5)G}g0l=h|1lW{4B3aA8ei?ZR~|AcYay0Elt8!OnwDauCr+bDnAzOb-t zwA`qBD3d!Y+a2~Oyjga7;SH5u;v%VWYZ)`vGG;_m<5s_SSpD81ni&_(jF%tBr`x%( zh>sT+v5c$u5+7D>&EQ4+fQ#YBa0y%rm%|nCI6MJQ!c*`x`~jYUsli#1w}O2lbA#&0 zyr3%55L9B~k0XmbUjoa6T_a6F72hDvH;D5M;(UWR-yqI6i1Q8Ne1o`(GjYrvBVroo zC&c*)aehLapAhFK#Q6zvenOm|5a%bv`3Z4;LY$uv=O@JZ32}ZxoSzWqC&c*)aehKv z1)I1EHc1t1;wsoARj^5_U=vrtCN7c}=SRfxZ(3}JV2ny7@z?^fwxq{(kb*R1?2y0D zI*XT#?;)a28BwQ|B8@VLNl|QyxddjxYvx^|{?(PkFvi!(N_S)od1~i?x7^ z6b3B_7W!K^(2lY?Ic%C&5*3B36t!prE1Yq@1G5_OzC)BEjbZ=5uoE$?5yM85ehcGH z2)==3jab%bZgiBM=Djo23P0QH^Sr*Gcz%3Fq#|3ov9PGLfLSHjQ>yw^8D^D31z8)WJs?J>6H)4s4jEC0jHp9K)FC74 zkP&srh&p6M9WtU08BvFfs6!@l6nqt&7a{795p~Frgc*`BLlS04!VF26Aqg`iVTL5k zkc1hMFhde%NWu(Bm>~%>Bw>am%#ef`k}yLOW=O&eNtlr<$jB9BL^LuY8YvNtaDRQu zY-}_e8_mW>v$4@^EY@W*8yn5WMzgWeY-}_e8_mW>v$4@^Y#f@6)n?!%f_sfP$Ms^ zMqXByGFz;z^pbi)FT*SFD$JCdUSMBql9jya(6}BBGidre8X*Q@I z2PIj2NRoAsWN(vX#}Dbstw^zB-`AC)6f?r1&LqLIw0tPJ){tClNv^ph*Bd0)GLmZ< z$+e8+T1#>*Be@z#uGdMf29j$Y$u*DUT10X!Be|B6Tn!}Ge3I)QBv%K?wTR?eMslqo zxt5V!b4ji^$u;MFy*it&RT-M(>L9r~hV*L_$<_1`{W`y>Uk4@ECLQ}8$(1F!vLsiQ zmHt1lBhF+;j3v1~Lvrm$ zat$ZBE@DUQM{?~)a_vHL?HpNQr*~7Z-+yRN?E3$ZJ&_)=C(6h zxSq7R0d9n!!34M|c$kFAk}z2kCQHI(Nti4NlOFY3B3Vs zgrC6#xCwp^H^VRB7WlP_T(?*H?F<VL;wzK;CCS z-e*AGXF%R(K;CCS-e*AGXF%R(K;EZc-lt!-dcF+({E8Xsvdn}=m=6nJAz1q;Z__UZ zIv@r*AO<=h209=HIv@r*AO<=h209=HIv@r*AO<=h209=HIv@r*AO<=h209=HIv@r* zApX`b{?;%4)-V3nFaFjq{?=cq4x0E|zxZ2!r8;QhZ~fwL{gvvVRjPwlsSaADI%t*Z zpjE1aCjQnh{?;%4)?cX(TBSN@;&1(xe+H)yiof-Xzx9j1^^3pti@)`Yzx9j1^^3pt zi@)`Yzx9j1^^3pti@)`Yf%R3kfW3cWTkFNP){AYe7u#Adwza-ki8nkyU^y-}sY$%4 z=JX&tGbL}+f>w#bmhdSU4LgE$4Z+@iVL#_RR>S_lj*;C>$nGX&cN4O^3EAC*>~2Cv zca@B8LPj@%?akQUjP1?X-i+o zj!x#g98`{#S#2-94z35+GlRO!pw?2-(kyB%y;nB&xBm73sOoA)HJee*W>m8o)oeyJ zn^DbXRI?e?Y(_PkQO#ylml@UNjEki6mfkDZZ!)Uw6(eCrq1o(eu9zh&$}%v^n$5Ci zv#i-HYc|W8D^^;eED9@Y+9qS#E@Rqm=5-D06Jfci(8I>>VdM9(@q5_zJrO65v+a8# zP9A65_pt4I*!Dea`yLvvhppbjR_|e}_psG_*y=rO^&Yl*5Bt1_ecr=9?_r!#?j}fA`2nt(T2jFB`R9 zHfp_W)Oy*d^)g9s%Ot%mlk~Ps(%UjgZ$}@7Dewq93crKj!{hJ-JPA+1)9?p)2L1?t zf~hbK{tSPCXW=<`0bYc^!*qBFoLd`JS0VZu%%p2xhc`eK5SgTetWiSNC?RW*kC9YL|5=L1MWo1gGl_@ex$;usJr$TR~ zRVkHYU>DdGR2r$=6ZQg;kIMZ(G#m@Z!PmihTp6Wy8Krg^rFI#mb{VC18Krg^rG$)9LPjYeqm+& zyNpu1j8eOdQoD>&yNpu1j8eOdQoD>&d*!d;zCssm)kRx%(N$riQA7PZM1waFH> z$riQA7PZM1waFH>$riQA7PZM1waFH>RnCV6un-o(Vu-_1P%XW38CU}*Ta=J3O2`%^ zWQ!8AMG4uW1WlQxDYKQWKDP$iU@atJ9i$))8R&rZR;gLhMx(aUsI4?=D~;MJQ`FAt z?BRR%@I8C@o;`fe@JyJ5tWZK$C?PA9kQGYE3bn}!waE&#$qKc}3JsnD5biAtSK+@^ zK6qllobt({Wa0TB`>6Br!5JLkJ74zBNh*Jwqw>d@#m}7Ro%6hNxpywHGV$2LAB+FL zRs8?C;{Sgs{{PqF|MkWH|7P{#(N@nM>kQ}cJAd+9N83GftetFoskTrp9ygqST+2VM zeG@dfW42IAo~@p76p zPLsxI(zuh2>a2-cACR=cwQwB_R%fZTYPYszD>mmy6;ihISY^k}4j?XSMPR&StoQcy z$Qogf?!%VZhdsIv`?H$;SzU63RgXu((S=7!jce<>%Jz zv9?fWtz(x}iE-L5&KIub3)k|6Yx%;peBoNYa4lcBmM>h(7p~<4-^~ZEa4jFWmJeLZ2d?D<*Ya2I=C9t(U#;b@ zp2S~0iNE@7Yhbb~w!i54f(;zN5e3|EHwIj-yC1^?kH#Lj&io{C}-=A(xOjnI!o0Vx}%(-JIWcl zqnx2T${D(&oWMHD8M>pKp*zYMx}%(-JIWclqnx2T${D(&oS{4Fzh{|?Wc>Fm^Z%Y@ z{;{*nOYY*CtmT=k<(1?EwKc>hH`s-e7uR3IOUdz4a=etB7-dTQv0nVKUi`6M{IOpA zv0nVKUi`6M{IOpAv0nVKUi`6M{IOpAv0nVKUi`6M{IOpAv0nVKUi`6M{IOpAv0nVK zUi`6M{IOpAv0nVKUi`6M{IOpAv0nVKUi`6M{IQcCCt*9;*BZs#*}#DBJsw0@y2@b z#(MF_dhy13@y2@b#(MF_dhy13@y2@b#s=}m1~JBz7-LF|v0jX^UW_q}FV>4M){8IJ zi!auTFV>4Ic8Dvc#T8THiVeJ~wY;jeysEXlsLkvm!=ceI8Vmg9xxcwsqSSdJH#&uGuWySikVtrY$zN}bZN~|v>)|V3NONsTR z#QIWVeJQcNlvrO%tS=?jmlEqsiS?z#`ch(jX|cYvSYKMKFD=%W7VArk^`*u7(qesS zvA(oeUs|j$E!LM7e@lzMrN!UU;%{m3x3u_MTKp|7{+1ShON+my#oy9Atprai!P83c zv=Y3m1TQPW%S!OF61=QL<$Z;Q%KPEB@Blmr55dDQ1s;J%;W79f{2m^MC*VnV3Z8~P zfH@^b*C0mMAV$|9M%N%l*C0mMAV$|9M%N%l*C0mMAV$|9M%N%l*C0mMAV$|9M%N%l z*C0mMAV$|9M%N)m*C9sNAx76BM%N)m*C9sNAx76BM%N)m*C9sNAx76BM%N)m*C9sN zAx76BM%N)m*C9sNAx76BM%N)m7oG*Dab%?!n1c$IRt5}*(HRbv5M7L#cHf#HCC}2 zt5}Uyti~!5hiq%+Ed0VhYY`Ge)Ukbh#{M35pp9be^(f2+6K&03W zv-LoY9=KW${6-Hvq6fyhhp~EKtR5Jv2gd4wvF_zOEj&RBE-Bu@XuEoQ?BMOO*0RHz zg_Z88L%uR6+WE2i3f4OI+L_ril)KA_B)?xfp+ZiqVl})Yx8^f;0`}Mm*kdEtks(*>i?6)X1}e5(5V>rT{St*QVT=2uT0!f&6rYW$A&w8FJO<{UO3Rof^or} zsy!ZT^}w+z4u5OoyH*N(rsQ0a-Sgml&o6)uZ9GOk^Mb-G<5Vf%d5rdMkgHr<{`10T z%YR+?e))aQyg#sTh!p_`%2OT_TUGd?D}Kd$<=ytHQ)0ibL@X)UwE=`cp`In!tR@4j=p#r{K1=wM16FS604P zR=!tOUY$hP5yrso1^dxqPdoKL4SN+HV-3H?626Z0n-`}~iqj{>>67C0Npbq5IDJx_ zJ}pk47N<{((I>^|lPu*HmU0VAxrL?N!cuNwDYvkcTUg31EaeuKatlkjg{9oWQf^@> zx3H93SjsId|BVJWw;lv`NJEiC00mU0VAxrL?N!cuOL zA4sv3^DN~&OF7R{&a;&BEaf~)InPqgvy}5J>_sZ_~vbe7+J=^02eBBE@|Dngr3VGIdUY;T;PmyMY=UL%-R(PHj z-pUGZm9t2fI<=hjJ&X07XMN{c-YqQe7M6Dl%e#f;-NN#2VR^T(yjxh_EiCUAmUk=5 zyH(C2#rn>hJu6t?c{Aq$Gv@)8cneFsg(aS6iMO!CTUg>PEb$hWcuU2~La#hWxKBFG zDi8NZ=UL@>R(Y#@N4PJ!SGK=bw!c@lzgM=uH}W_<0Z+nH@HG4Zo+#6_saJ7 z%J%ol_V>#6_saJ7%J%ol_V>#6_saJ7%J%ol_V-5dU$(zjw!c@lzgM=uSGK=bw!b&J zJL~~_!lz*`*c9!5ww+ekcJdk?<25|SYj};< z@EWh-HD1GOyoT3!4X^PQuH!9S$6L6Lw{RVA;X2;Jb-ab^cnjC@7OrEl=UMD|7JFXK zBq?W-lru@nnIz>)lJX^K`I5AJNm{-nEmxA3D@n?gB;`tyawSQ*lB8ToQm!N^SCSO< zOv;fY{DJi*> zlw3+m9wjA@l9ERW_nqc>4tbtKp68I~Iplc`d7eX_=aA<)Wqq*M>B;|UNay?0To}@faQl2NtOUd(6^1PHhFD1`Q$@5b3yp%jICC^LA^HTD>lspfl zl?T$w18L=fwDLe&c_6JkkX9Z@D-WcV2hz#|Y2|^m@<3X7Agw%*Rvt(z52Td`(#ivA z<$<*FKw5bqtvrxc9!M(>q?HHK$^&WTfwb~KT6rL?Jdjo%NGlJdl?T$w18L=fwDLe& zc_6JkkX9Z@k_VFHfh2h#Ngha&2a@E0BzYi79!Qc0lH`FTc_2w1NRkJV;(5&CdCcN@%;I^>;(5&CVdPmF@5Yja-q<=wK^iikvSExh5L1OP7FHo#4_zw# zbVCoQMIe`!LhD-rdU?ByL5h*bXx>*j_PE9cWqfAZ}GzP+iA?eg*xvOlZ@WhZI*w^S$c>vX`T znvN~@45=kk5}y3PcQ0zZ!8%E^{ZhD&a8sS6_2s9?b`RA`imWYk`Q|#OVXb%l3imVI zqt!lsWxe~G=l(M8Z=w4O*Uc7J#+JRPn$@eYTvfah6^T?yQXMR(I#_SHIp!W4-Qybf z7vn)s`#|+y4*F1>VbEfu>-g zb+wE67fb9-jI)N9vPYL$9mpGIZ@1)mR` z%3)VSQ!vl21{HbTY0903XH$2$%dETX4c;z1>MjS|Wrw@$aF^k^)Sd3`U-~Dk|K74E z+3B14C6NQw4Lb;qgRk4;tn#iE`%PBtH(9aYWyOA%75hzA>^E7l-(-~z$bWL`u6Gv|?1Mq98gt2VS~7n2kVNs91WD~Ikktb_IsvStxWcD-Ln`-QY$ zNV}I_bAADfae;g3joH28*B&bNNqDw)qkHEMvV%|dtKYWvXUNYEO5XRgKgp)v@8=V>OIwXy zo^qDipFB>3=Sc6HwP>&+{j&0jg=NK-ty0Ha^@R%SNA1FGwmY^tx*d##ed&^FkNbN( z06ydSXW^v6mC*@SG2Nsx&d)tg^mrTG4tIEcC#X_e`FZO=&-5q<<0SPpm6yTga0Ofm zSHaa#qw>T4*78}?9{UV@7OWqQSw9-Hel%wNXpB^deGWbk){(}nBaK-{8nccx_9d{6 zG-e%X%sSGTb)>N)!CKOowWKj?Nu8wL9y=T4N`GIu5au z+|McSZ8#Oa1E<01AV(7$584&euGm>{Hk8W+Q* zU}sLu&Yaj4a3x#?S3?b41J}ZJ@DuncTn{(EjlgS;@tR}2<`}Ozb}Rf6Cc>}4di2;N zu)aNZJKOU-;>*&fn_EZO+_kVfZ}!^wz_6erfB=27hPk*S1b< zv(q+b{@Y)9$u%$D=I(8>BRB4p8C||pX7Jz6$87#@%*A7#@e7;X-QcwbuTlKpCw4vH z!~e$29y5EFkG=ch&un@Xes=SJ#qVWzo4@PtivK*@{lJg@+w&KL|8{?1)3ZH)G4|B4 zr|vmzpTC5Uga7tz_|O0Cx6OXrRByG}zs}E|^4Z^f_BZ3o2mc*-bog)6t8wLnuRr+z z;L!*FB>d-G-(iu{B9{h1xknv=$AaD_Co* z*hO30siVnLvVg+WI@!xz2U{ z$@L|ZWafR}=YE#&_qm_@xt~^=ubJlCM)PeqZ(AQp(1;E6;Kuao&N|vJN&9W3{W@sB zjkI42?U$lpTPWBhZP!fOZ8e`;L*FeKI8(0tr$GDxowt?F3uotR&2QQVI|+!k+d5dx zfcak1d@pIfmo(q>-Ym-%FbBCC&G`%=fy?_mbv&N%Os=`Cig|FKND)G~Y{_?{%5) zb(!xa&G(Y#dtK&xUFLg9dN5(Wx0xmk^F_7OgsW)6cABuACTyn(SJ8y4Xu_>DVJl6z zl_uOu6KO%LKAMG z3AfOMTWG>9G~pJSa0^Yig(mEx3A<>*E}F25ChVdKyJ*5Lny`x|?4k*~Xu>X*E}F25ChVdKyJ*5Lny`x|+)NYhpb0nAgqvx?%{1X=ns75s zxS1y0OcQRV33ue)965?6+({E|rU^IGgm2M=n`y$$xlV4(wKs`2Owxu)+Av8QCTYVY zZJ4ADleA%yHcZlnN!l<;8zyPPByE_a4U@ECk~U1zhDq8mNgJkU!xU|pq775DVTv|P z(S|A7Fhv`tXu}k3n4%3+v|)-iOwooZ+Au{Mrf9=4E--GV{$n_kp2)H%w31*Gyjg2hpx37aJ`>Ji%qw7$9(qX)WhZr#@1Z#{S%k=(~UjMpY8J>haRPPJV{aB-yRajRT;2A#@ z{6dVtKUn8!mI=>rI?wr_9nJ^s;P-q??Y*h?-c)sjr0to9pLTQ8Dw4Xf3% zS~08Dv053cg^~LswTr<-HwrU*y<9_eYK&^s~rBI}GydFvxR--5%ZW zUhnbw`otKYDDL;peR|*NKBL@c#2)wA$EWu5siFNoRj3tg&FIEPt)NaTsL$xd^|a#J zj7|)FgX^?}CM}^wOIS}2>LZbIcRDbw1s|sg|L8=)`y$2ebeuaKqa_Sf^8?kqv(44; zUQdARy^0!t&q79@h7ru0Ph(j`g(V{XR8x zmo?Aw3W6THkx7Ewsm{c3G(3Jx99d8xi}#)8l%$`f!%$ zq_dsbcd=)mJ#nPphv%7(64O!$qrEPIVkn_? z#`s=pHQ*qxWqP1t!gI}AXqet}&9~Apz2};TXG6wmnDAWlu%Cu&EA7?>+O1P;w@$G= zEUi7ao%Y)9?Y#2_x~1=V=iBI(zGqR#>6UGD%T~H&E8UW$Tei_HEp$r@-O_XJ`P;#q zJ|}Rs&@18D=NoC2IIYrq3RjX=Nzy8DT4fHcvgavWae5?9i^S7CzRjNBEp$g;9kSWj z@`s>??x>+VYUqxdDBh<#;&exx?ugSJak?XJbZenE+Ubq(?DIIi5vMnL&OX04s5atl zqBoNCMhCsoL2q=>8y)mU2R#vM}nP?jM9CwN)>$JCGhtoZF+FP;G-inoxqoC(>kAgy^zFe?Wx zD1)kdVT4vQh3^d2e$iQ<#J6E|*0ms_X~6DNE)t@$Hi*h<5|y<vUS|^ffgGj3Iq=_z(REeC!<$xRy zN5GMA6gbl-=V&+vj)lo^Je&X@f)n8+I2oqEDR3&B2B*Ur;LI(19Nx6Y;Z1uS-n7Tz z&79A`zZtoeW0$l&5v%{#Be>2I#dS8&L(y~LJUAaNfD7Rw_?q$XMwkZE;U;k6yZsqE z?9bQ{z0Z4o3ird$;OFoQcraLLPsU1nGFIA?vC^K5mG)$;jQ$RO4-dh^@CZB##$0Z!_GGNICu5~O87u9{SZPnjN_#R^M*j@6;8}PM{sMo67vOI&2l}5LkPzXO z5aE>&;gt~Kl@QI9h>F6Cio%Pog4ba+RKpsmg*u4CI#>_&;9Nh^TnW)!3DH~$(OikB zoEM_G5~8^hqPY^Hxe~GW&+y+Y(yCdcRkKK|=3N{!#_LirqZMh@EYhku%{zzq?#w2U zR?Q-W(yB?MRg*}oCXrT6BCVQ4 zT5S+%wLzrS29Z`9L|SbSX|+M5)drDP8$?=d5NWkRq}2wIRvScGZ4had5NVYVX_XLZ zm57Np6={_aX_XLZl@Mu_5NVYVX_cVv5+bbRNlVEHS zY1I{b8vX>&z@K3jJPXgkf5B{c9{vKNY(!dhiL~kxY1Jjts!OC*mq@Fw*h?aw=EDMb z85Y7T@GATr7DENR21}q4s$eNBgXORSR>CS+4b`v)qpgJ+%vB3@5QlZJ9z@pI>#;GG z03HhwSFJG~3lUeXBCc9RT(ye0YK`$!h`4GMan&l~YVXljA`V4XB}7&wL{=q4RwYDM ztrJi!A7H6Fa9}y*WzO2KK z$T$9IFq`Le_P{?{C4buYXW+SDwpH;(R>c<$x-)ow&<}#=&8tT9n$ET&KGTZ$Oe^9u zt%%RGB0kf6YpE6SndV$e&AFCZ5ua&Ad?wH4Y+lXTyqdFlHD~i`&gRve&8s<^S93P6 z=4@Wg*}R&wc{S(pYR==;oX4v!tmW0L z<<+d^)vV>!tmW0L<<+d`)vV{$tmoCN=hdv|)vV{$tmoCN=hdv|)vV{$tmoCN=hdv| z)vV{$tmoCN=hdv|)vV{$tmoCN=hdv|)vV{$tmoCN=ha+qHd4x~xjy%X$k5!cnumVP z>l&z~7wLxh_~_ zwRyMvv1_vrVNtr$LP#qc-!KnJed zj_2m$xE1&@ItR`9y5-gR5O>$ZB= zt(K+ZIequhI-Fm^3Zg@ z&nnZxKC4V?d1$&bt4y_F`?8wUZ6&Fjy}I|Zl2pCNO45satR!{w$h^oCvw|n)#eOSD zJu62W-?MTwKnvTwVzh!6W(6-yH!sY_^omiqLKLnJg)2js_`Tf}yf9&_>=@h@tl@>} z=7njo8q{Jns6`#VZ561SCnm)clj4a<@x-KfV!C-^x_M%{d1AVGV!C-^y4Ck~o|v~X zD?i;lG2MMuel}?bNuHP$JTX-~F;zSuQxxcH{VIQ z9gHkH{a-S7{z;uIDx_91O`*S`IK+|z~_Q|%J;{V?~f_pZx8yu zxZ5B2epm3AxPcl9IA7erVN~z}BhEA<&NL&=G$YQ-Mx2+8IMa+c(~LMT8*yGX;!HE* zOf%w4GvZ7$;!HE*Of%w4Gvd5##Ch3>GtG!I&4}}|5$9zi&NK>p0foJQ!d^gOFQBkj zQP>M8>{S%@Dhhi6g}s2n&KEmy7?qt*W#?1b`BZj3m7Pyz=Tq7FRCYd+IMrTGwdYgq`BZy8)jol0FQ(eZQSJFu zdp^}ZoN6zj+ViRQe5!po)m~1u=Tq(ZRC_+vK7ncpO0`d=+NVpf;RQpt_eJa&Hm1>_#wNItmr&8@xsrIQ<`&6oZ zD%C!fYM)BAPo>(YQteZz_Ni3+RI2@Cu?Y24``uJ~zR~|6s{L-N{cfs#IMrTGwcjlk zK|FutT(Jl>RQs7!`wFW4HO%lAs{NGQ+k?Sk5e8H56R7tI)cXYLeFF79fqI`ny-%Rt zCs6MbsP_rf`vmI!8tVNT>U{$BK7o3lK)p|(-X~D+6R7tB>b-z^FQDEFsP_Wuy?}Zz zpxz6p_X6s@fO;>W-V3Pr0_wehdM}{f3#j)3>b-z^FQDEFsP_Wuy?}Zzpxz6p_XX7Z zoiz4haS4Y-4#f&TvRXD5GyKhp*$V7%Gj@0w(+$l!B=|VCE5vsDTRr=aemz!?q>RtP zcwfVIQEWG5(8a-h81HyYcY#szrl@^uM#!^`kmni^#~KlfjD`!Wx|JFQOR!*((eEo* zaJUsNfd(y#cCE|N#&v+{`C7TX?N z8(N;9V|ZlW43E6dx*J$G%t)SK-Bm{8=FB{!j@80F>>;Ow^Ne~=mB_3Rz3nNoBB!Xk z7czSDR&_PR)$Vtt7hLH}#{Z4R{{~mQT~4*AHK~29N$qP*YKVGUq~0pkTbp`oQ*R~e zZN7S&r`|$k6h6gjb$6Gi_)kxI&f(SqA(!ELnQ zHd=5SEx3&q+{O~aSmJS(c$_63XNkvI;UOjOQ0kv6@rg>jR*6R`@qU?BRj9;ADDBxw zTdcHUX6PCveMTu?io8KTETSD=q#e2AbMW*WJUs_b&%x7k@bnx! zJqJ(E!P9f_^c*}r2T#wz({u3j96Y@iPp`$(Yw`42JiQiAuf@}A@$_0ey%tZe#?!0u z^lCi48c(mr)2s3HYCOFfPp`()tMT+|JiQuEug24>@$_muy&6xi#?!0u^lCi48c(mr z)2s3HYCOFfPp>pP8-u4;;^|yGJseN3#M3MB^dLNa0G?iH<~9aTf6UCS5Kphf)5(l? zErzEj;^_`N-GQg)kEiG3>G^niKAxVBr|0A8`FMIho}Q1V=i}-5czQmb zo{y*Ji>K$}>A84%E}ou?r|077xp;amo}P=R=i=$PczQ0Lo{OjF;_10~ zdM=)xi>K$}>A84%E}ou?r|077xp;amo?e8fR~U=i#CvRu?1Q79!OgR9^8!1~Vz~LY zIC&-xegNmrvBNYMukMFaQ#f@YPMwWM6X`3AHtIZY#Mx}bNtso?Z2a9~TwQNmU2l{b zW@PC$vLw?Z%bk%zBg?OhES*M{wMLa!j2y=rC3YGiPBucc85#C77Vc|gI5N#QpXDF8 zC3rb~w~re0o;B9(bl1;e=%2gu6;@xjyX)_bbypkf{%Wjy-dH!)s2|&7)SqSSd&JYd z;^|(^jQaN)|L*aWKlPOBJ>7$z?mSO-M#w#(cf!cO$dkq~_k)=GK@4y`);<~wT!ytz z#{{3Us&*ufN*M!hH3r^l47}ACcq=yelyUH8Y;X-WxCk435<^e6@^zY0S7G4?F~c>+ z$XjBu;8g7J$qYNpF;4Ew8fC0;AZvU$!wjFZk~9?qpM!lTSQ+||ar5t3;&Nl>E5^?I zvBasy&tJq|3O*luE%+L?c#`#A#k}W4rkj`DoSBo&GOj*rOnumxdb=_8JI2&|ji(!p zrN1_oUSkfn+5GFL=3jp>hF)*n{DJYZ$ap!+czM}Bv$%2dcJruD8#k}%wWhK0gq;5K zq9x`))?7njBGSUHX0+JHAX&bjC|G@`K&Rr(HPlijBGSUK5L9@G)6WWBO8s4CmS2j zF(w{wOgzUpc$9H)igEB0#=nz|f9DwYjyLX|W2`&M8252w+~`#n`+y!yu)cRpbZ z`Jpl7hsKMm!{(Jc9(IF)hhfN$d>7*g!hYsm^ z)${*RPY*r5=T&j;(C7Mntr?pBn$$6LMbE2}FYo>u`cBCUqZ&(I7&dnDe*V8|->>X< z^Zv^YC_muN1DZ#Cq~wJWzZtn>)Rm(?KgzpCbrcR6J$%>KS;e`~^!$u4L8eQ%;{UW@maQ+#z<}{i^@pdw&Yw)%UCC6QvIwcynms z1Ft;r%Lm?k;F5#N4_cP_`p!Wwgs;j5l@BUg0#nMvS3e0~9~?P2Qa&a8|KR-&9)CpR zAyW>y=FqbaJLK?5hu<*%hvTb`Xq-6g$U&1%nsm}pg-2a^T?< zI`j3D<9~8|`L3U?_R~*}Uvk2r6UOfPI>#2c+7l!H%Gb$vet@q9C-3of>H|~uJN1Eo z=j*iOsed``kkgJiExE_nsi*zC?{Ctzdh_Z3%Gb=(Up%Aa-}@5Hw_o&u=&O-PbWya@ zI^ELf+Q{T+O;nz)=*C!{*-$v=nHD=lez|*Mhs6$y+#4G&zuZq^M;jj=h#f1B;LlZ)ROJfg2o{jw?mXM*(nI>7M80po2mYiKrWSYg(% z0{hK2Yglg9umTHKV!=i%xWKHT+N_}?>rD8F_`>tW@jVjMW4{Gv4J)wUZ_OH-%^I4` z8djJ!tQhzlPqCdPgX}87hzFZ3tT0=sH(RJTTc|f%s5e`v$7bzj3-uVS9iz3IE!3MW z)SE4=Fk9GYwy?r%VTIYk3bTb3W(zCK7FL)otT0eKmDojn%5LS~XUyrtYh$`)ce~joqrL`)caG8p~BBeUH&FKt)O`bW-$30rQ1=bg zeFJshK;1V`_YKs219jg(-8WG84b*)Db>BeUH&FKt)O`bW-$30rQ1=a3wie4Cie+na zZ;&74tC7K2wie6Qitm00%jRR*S}c1gmi-czJs8W@V%b_On~!Dluxt@^-%Q;%Q}@fM z`{mUAa_W9Lb-$dtUryaGr|y?i_sgmK<<$Lh%)A^kFQ@L8Q}@fM`{mUAa_W9Lwq8!% zS5x=Z)O|H|UrpUtQ}@->eRb~d;P>zl`~e<@N8nL-3?7F+!V~Z$%!H@lY4{U71ApUL zT&Las?{M}Ra*+;^i*$%wq(jmkm@oSNWw;J*gj?WlGXuM%vU)Og1oF>y$$B4^f38c` z`>2TFBk7S6dgNewAoZla7QlY%;TddpqHY@mPZlLe*9 z9X4crD)>j%)o`r{_&x2|bB7)7u%q7{!c&_*?pd$%tl#piH}e-AA_m%7s+oG+YsM9G z#%-QBon1vnrDQbB#WegqcIlt1C49=>TrK@;x##J6bG7U)f0%o6nf0gF?Ce~og~@B- zsoGegjRoHH*UkRg;I9p?y-ms6w4NPW&kj%brqaHdcP2L2^OJA*WSAkU&L`_KpWO5> zeeylIrQCD<-akp7f3VC{|6OLM{uZcLj#lMJC`Tewj^tjS=HJWt`LCUFagQ39$fr0- zYY*Gy$y$5ZHc#>W?8s!jV4Rk9h?aGUmUW5eTj7L@VS2$Zy`Uh|MqAWYi@q*;*~u1P zh47S%p1!{4Nf)L1dTFMw|7#~*e8AH!^uTae)%|8%J*BKu%BWH{DPfb64OOym@568< z8?I#Qlq^rl@|0}&drH>RzTeg!-_G>Do~!R??iS`l+pfR$=0aPpW&c^du2QcrtJlS$ z-SoFEtIqFQC)sA5i1mX9;Q0I zZK3((a`VUqN*h($^o|xK%+bag)mx)_3v)HSE#L4(W`ZX~{~8$@U2oP`6q#%$xUZSu z;d~nt%>)lN6P!T(ok#nfCAaWFatpsi^&JrVY-FH3$7jp;RFuwj)zP~HgYSES{ZyZZ zYv42RMd-s#dTmA}rjq%wR_q79X3LnXMP1Xq;ciV|E=f*(qv4@R4 z!4V}mq69~j;D{0&QGz2%a72mcza#VPr+M}%p8ZRnyT~)2>6vqJNC^%p!679$qy&eQ z;E)m=Qi4NDa7YObDZwEnIHUxJl;DsOIg}^H?v9L!Iju!`FR_QF&(phWxce{0Vg>G+ z@2>mz-c?!u-|J*wb&}-{;qJRJ?l8(73inbcS^erHM@wkcDw{lO*jrmOwf>GCQpNrv zGI-#2kIS!xztP^p{C~S@#(OK2Hrziv(O%(6R@BZ7W@_hsGkGo1u3yrwU&4`-jVjKY z$#ULI)>#z8#d70a3YSNU`d(K_cE_EaslAkGFJ;|V6vJ-cv_xQRE&aJI1_N-?Vxvq~|m6thY(s}!?J zF{>1_N^#_JmdIs^T$adXiCp>9hsvKmRQ~j#GSCl=d;z}b_g{wV;6}Iw?xwQuNn56z zWsYK*5iC>2G9y@~j8%@*UM6WTCulE|Sf`YA%2}tJbxvZPzU&)n+FaJjWu08s$z`2f z*2!g^T-G^+bq+C}4rQHO*2!g^T-M2Dom|$*Wu08s$z`2f*2#^H)SpK|ArwI|lt52E z4?q%lhGSjlIG6~NU^09NPK1--WS9b{z^QN=oX$3( zRb#9gW7Qa|##nU(tJ>iVpNB8N7ybUra2?zTx4_->;yu*CMAn-W8N;gMSam3?j$_rK ztQzibEN9h&S@mF6oxrMPtXjsZ$Fb_jJ=$E1Rb#9gW7Qa|##lARsxekQnpKZx)e)>3 zW7Qa|##lARsxelLv1*J}W2_ou)flUeVAT<cGC1QTh_4FX`Kh(svl<4!Q17#Qq1n z!!UOkQnBWfM-C?9V6taI|+WvjU_PyUB>nP*s#K`fkUhL{6uD-9U zm$-U3k_>nCeO*1r)$?7w%+(KY^#fe3%=4DfHd|?%WNbv_j97v5Da#_iwmvl@c4Q=) zTcK4A{~&Frw=KAGo2!m+)fuk(c~>0~(Z(X9wdT=U^JuMkwALKenxk5CRBMiE%~7p+ zwAMUYYaSiB5pIFIwbtX5$4*z}Jw|yCP~MPN4p82ZSB5F`Daw47GJiyw&sOGqW$xvb zOZ(QDF=DjVJX&iWtu>FL)oj4z06zm zFPE`RKOL(42P^-<{YH#DwJ_9`a$RZ9cV~NdcE5KINcXRDaaB2V z>&Cv8@Atmbw2J~gu0W3~(BlfUfdXxyKpQB~y9)HK-qG+hZD6P}4OONQp5#PrV2GzV zQ5zVd4TK}&FlF0M*^XB4N2~V{%GOUW>RAPPR)L;Xpl226Sp|Alfu2>M+$Si>3F>RRwxgfnHUhR~6`01$tG1URBVyH0rKE?>8ffH9WCvcw*P^#IE6qUBeT*h9`CnPwX0A*i~XH2C(Ku z?>)W9ocR6E_4)Tt0veLO$EA_O_2RyxS^A`;|Mp({X3@e~v~cKB)r?d<09 ze}0u={jPE;AJ64R*MH{I;E<$+qm%iLv>=KKz8r7LesA2JIOOoN$1J_cdy>-(cW$25p2APuddG3U*QFLm3M6m zJBOZ-MeLl;+wQqvW8Vt)eN*ph!U9cc@0L?B#9ky>;zjm-k$t;)D#NoCzn=k z)wCiAy~F9eh}3eA{TtbTC;Nw<^a@Y#n!7*c?tjnRJ+#^?_7Bfq*p{*XM)nVLnOC}N zCHsdyM|+L*<({nW<~HvBXMCKCi*uFfPxM&0($kxtW*?k91Sb!{$ptfJ;m|U>y|CFx9E;abpt}C3xb9}P3k14*N;`_Ny&~OTc zE57QAVSfB@L`+}7{-7=P2W_!GXiID>SYcBmJe|uT&?F^dhtRn=rk?pG%e^- zdhs}lYp6DPk(P6jIlv@(u*B?X5^X<;wx2}XUrpPGC+JP0?I&S_NxUqRX!}XD{Uq9c zlG)QFUhYY>{UlzNNwobWR$JbC%0Qpf{IbI`v7ysOJm2MJd%frUg*z7BikxhuGmjJp ze?a6^I1NsRGvG}4Fq{Qv!#Qv+d<4#e^Wg%x5H5m`!o_e2Tnd-LW_Le?A4QH(Q{&Xs zjcV$ctchx7lDY6nk*R9xXf-ueO&zVKj#g90s;QG%RNlfWJ^_J}cf;Gum3HgE*{%^-vERAORcg4R9{DQ!Gw^0uy))J`LBvXW)y_vu0EtxzX$Qt{Ih^5tf?~ zmYWfln-P|q5tf?~mYW5ZM<0yrV%nY&I46)n{vD^%?+zheY46)n{vD^%?+zheY46)n{vD^%? z+zheY46z)4oyey@mQR0wjC5ssWvs7X|7%Ja`t`%pVSD}h{buRrz3=OjSIT1Ns}5Dl zUB38ez}xeF{`g`wToRe7q_->SCzbSbN_tqIl0KuPAIMMdgxJHB@Iywo{{H$)jYA`i zLnDnt;fb*$jYC;V9s29TQuq4n_goKre_#76>2;ZZ)yF^LlA$GnUk^YoFtz4VbheI!pG$K%F~DP^r1X`C{G_cTpt>t4`s8=c`Wc5zN5b5Ns;|nCED?r$Yq}95>Io3r};{s zb{(Gcd!Va?TJ^NFZHw5ph;4lqzkQbX{&UdNMq?S`Qd(#%nCZiGC>s8r{Nl^<})nzS(@N;&||l88M_r` z>{iHbg?q7EA-ff_TOqp@vRfg$6|!3)yNzSFLZ?NCt38EmSIBmSY*)y3g=|;Ic7<$L z$aaNnH;(PbvE4YfJ2zvy>)7r-PyT(j`z71m#CGG@Zd}H8<1)4z$96ZcT_M{QvRxtD z6|!9++ZD21A=?$QT_M{QvRxtD6|!9++ZD219-EzM_3<;2tM_P+q4(%Jp5j}c;tEd@ zjxwkB+RZw#cmAZbZ@wPNmC#CA7bT4&Ms!mGPNvS$1RVStDq*R@hs*lp>gXuNRQuR@)K1$U` zsro2YAEoM}RDG1Hk5YATmy(BV_ef85rsqG+^H1&b{QIzXDSMZ)cPV?9vUe$am$G*$ zdzZ3zDSMZ)cPV?9vUe$a+p(%Y+-;qlXP@ORPoK2j+Zqd%@;{Yw&z9FO*Uf+%w6^zY zdFfX7D>;wtX$dC$0Cit{y$}^apNLKaPx5y2)uC%~prm>M&dBF4EWb z*Vp#X^tJsneJwjvui5G~doT5xt;E^tHCw%AtJiGxnyp^5^|f#%Ka8u%RKn{n~vI zwI;sE6Wrkmrg?%p_h@O?`s9)6F)PZBQFe^F%4zJF&yIGE8{0qcdygK8X6zVc$LL<{ z7-h#OJ4V?t%8pTXjIv{t9rM{S%8pTXjIv{>z@qFJWydHxM%gjSj!|~ZXUBYY%xA|h zWb8OWDZZo>Us8%Ylwt-u=Cfl@^u&1Id+ZqI6hDp~qwE-E$0$2S*)htFQFe^7W0W1E z>=u?^?_tkRvFA8XaacLiuqP4~VlIPCYYt=betZuXS9o^qn6Jl9j6<0*gC=PAQD z;SaQ$qjV=^#+Ttrc-ecnu>VR~zmdhW?3&GBgb7scr{S8&N$h-$7FVvtm1kO9d8WmU z%vfur7B_M)EpB&Iz*O)Z#|6XvlG=SxfvfpLSo?>T9pCZ-27iU&Cma5_6O>ky||DCp_bgp7E4E zwfsHTEllg;Bl>-^Byzb=o$OPG`BdK#`Qv<=yU)B0y?5cN>neV)y`Om-#%^!n>kA{6 zmt@|ZUZd@eZwNiN{7x4~KA&}IWI9jB*ZSSzpP#Cm&!4%1r)V_~a+&nO4Yzt3CZIVaoSUdm1+~`$(-{E@c zSnbRTXM2q2!ZqJCN)O;E>nYLmGWyJu(Py5gdEV1hyZ&pgzrv>ze58rAXZ){0Te@W7 z^Y8xTzw(J8o_#&v_`|%a4N4vEDeiY4<=BrO{843TQI=L^dB+~<&~v)?Plnb^dBSb) z`^mniIfQ=SH~Lt%=QM}D@7Vi!57*iYdWZ91y5vrOQ10{x?FrqiE;h-^m2mz`!uc-= z<+?^zu5MYmQnGR-)hZ98MYFG&W8)(qi~7eYmtNO z36NbYCA-$LoJqkiW!L(p>{`E+Rcno$F>BDBzC)%=}S^V_WEC#~l1v}bK=dWZHpzF?=3THO!xye2c5F1A?V-(tU7 zyH)-zR{7iPRZCjw@5uDDHmmw=R`s{op}oV({?0y`Ew)(U-!kyIV2g}a;VGwEWVCu) zDdt6Q)@N@Io>h`YC3#j!cArvwkDu>_MOF|_kd^Ez->o@{3fLklV2h}LEusRphzi&u zDqxGKfGwf|wulPo5EalNDxgDDK!>P+4p9Leq5?WZ1$2lC=nxgqAu6ClR6vKQfDTas z9ijp{Lnf+dI~7?^wINW9{~iwc9(^ zZtqyTy<_e6j>=>L&QRd zh=mRj3mqaBIz%jVh*;`Jc~yTf&^kd?x#ZPPA0(^q^b zqJ|@CIHHClYB-{XBWgIJh9hb?qJ|@CIHHClYB+K(d<4#e^Wg%x5H5m`0#1%x0++&N za5-29i(CO$!pGqg@JYA|WYd+aKNYzZZi5+cJA50y1K)-3!5#1eCBBOVeh z+QF#|(XHTAhUhlf4xO+A-h!Rb1>NvAyaWG$cV+Z(u9M?S4D99-L4g+bBooCTN5vXoby?gf`d$?dmbAJ=f|5oArQ3`+eJY z)oP{|dF_ny-nCwu*aoj~i2q4maC)jG5}wt*B)yJrZ7_X4 z`)k(SKFE_yqz-#_2K}P9 z^;NOU!qDFA66TbBCmm7I?k_L<%N&1MC|YVb{d0icJc4E(Me`QI;q5C+Nv6YV4mL8WIJY|jY zZS|zvl`lN!vPSuqXKFCi_e(s}e9si_4qNAGx0^374D)J4uF4va^@Oj~ppW%@4Y+>5 zUk3iB=PUfpLA8T^GU&NM3kK~Nv}175;KK$VKllw_OVa=UaPX|2S7l!r+?_orJ2(5v zoE^D`WWLVIy=K?fGcs)Se67yy{d#xbbM`%FRN<)ca#u_n^}|sQj(X|6Uxh0Usy(Q- z?3%K#_*zg_Teh+MBjwkZ&y+nNH+NQUbtIDehFRIz+;zF@Bja*gbN>-JH1Ev3Gb1PG z-JN%DWJ=zBc|VPumiM!~UqsHxdnRvQ|EDa_N2;l>v)2+e zwTR7r!)8xumEqpc#cJwob~AdV=jE4al`FK$rAqZxY!OB^hdWJ2V2l0L+)HY0hFW_| zOO30sKd7^VJ>u&xzCka?Pt`-3F_krbDoRU z$(8ElVYPaPR{OLT``g^rk!-DXx;f3o=C~g;r+rkJZ&BuX%KVb6+^M|lmG>UyJ;SqH zkmj}J+UHB*IHsJ#crJzq-}CqI9Iktn|2M|wx72K-cWv~pO~sKk@gMt598vxJjYhH-@*1_bk!;`QLEfB;f}5Ed8YLI{XNelLqOVdl=cN_sU7NW zMc7i)&$m00|DXGh2C&-Qo_<++FXq;3 z*~7`B@*6(JgXK-BRIa7GOv|YyIpOrk)q3GJ?6d(pZC2NRGZOvMlf1~5o3g$xzU`La z$*jABS6z9VGhlyadbE$;;Uo37O#j==jKQqen!ZiyjsEMRY>skI`eSd0Z0QX#`ji{dQzP^apZe z-j#K7^oLo;M}HK#D{6%!iHrBDdv!{rRCki%_>zlW!5F7>Ja{H&JRAW>!ci~*j)r64SU3(Q!ldBOIg@=q9!`J{!HIAZoD5Uo6gU-5 zgVW&*I1@e$XTjNU4txa8lWFICxWMZR;Ucd;3Kx5Q30w-7!R7EVxB{H+Vw|rx&Oc+E zf5tdpZ=A0;&OgJ$^k*KXKj(bL>(46N=Rhu6=Zt+_%ecu|V_%Pc)Lw~;;S#tME`yK3 z6>ued9BvM_M85%YC`P{t-wIxh-U_$D47eS>9jxPdc{Tc7_#WH=cf$AK2mbbBxEt>A z^S$sB`5vE@8Rj{d6Kr$B?=~m=Zp)nqFFC3A?w~X89tu3%kJDj%{W+d##WStO*{9`; zZ5C6P?dyI1YE&8Eec^7R$-(D+_Rl{1l+S)0M}_gY;a2K{ zJrXyC=X~xn$cdDAf1wD80otjZ*dhV`T4elA8k5^a<;6th#dwUvtj%{@Wx5Cd zO*YD(l~&_z;k(=?+8a5X^;7Sxa{k{8=l{)!90f-Q)1Cb{-PwQBBger+m;^H9MUICP z;6y*41SdNw!MvUSALWii!~BugKW5pxuJ(Y)_R+cz{> zKK-k*&h-7mzMmC*!~UUD>>oNsZC9!7Cbiv^)f`OEY6)H(aAPoifai4%;cRCR&gS=M z;`eA8@a^E`0e1%99q;jjJtP!J#R2Y47Bfk)vncpUx+Pr#Ef z)3u(W@z_mX-uva{y?<9;-ube4E&!)m@{h#%N8yj~blE;!7CZ~j!C&C7@B;h|=D-5?e;F3SE3gtH?9!<(So(FAOSP0$EUpuVE5uo;q0|8!y~zfqjuD9&#b=QoP;8^!sJ z;`~N&exo?QQJmi>&TkZtcEj874*Ub&g&_E@Y^UFiWx)U#2!miSWXp@415t=Um?wJ( z423hD0QO<9hUF~1*)pKcc9!1k*!ge)TnHDzN8w_)6fToD`*QdgTme_Y$Kez3N%%Be z1D}DL3p5U_I2shG0o7 z0UNz<6Es2-w8Ca^7AgPTI{v$L{CDeO+k%&4+o2P7z+13WF5x$1FkTm&lDj>aE-UVI z=k85+?%s6g?oH3_3SP|ZhPUAz_($+!o_?0Koub-AQEj58IwObBwlZl`Q*TpK%^0Q) z!?ak%T!>Q3M^BBWh$^t1(vD6G8I^+ z0?SljnF=gZfn_SNOa+#yz%mtBrUJ`UV3`UmQ-NhFuuKJ(slYN7Sf&EYRA8A3EK`AH zDzHoimZ`up64c~$9!uQ|~ zkS7r{B{5S4W~#+ZFJPvHm}x0i>BK5YsX_Qj5krnn<(Q=l<_9YcoSv3i89_q4R4}`H&MfzsNqf2@Fr?_6E(bv8s0<= zZ=!}bQNx?4;Z4-=CTe&SHN1%$-b4*=qJ}q7tedFRP71X%dPA@|`c?QEkJgPa4W`3Q z@O8Mw8sInKTR}5b+Dw%;Q>D$6Xfq|+Oo=vAqRo_OGuCXwnr&FK4QsYx%{HvrhBe!; zW*gRQ!TGW*gRQ!gX1{383pey~4iqcQ&K*hv1vQBVj)Pz)t7 z21?;TI0z1gv2X~Cha=!9I2yuS9LK>#m;_=-VjqGN;UqX2robt1Dx3zV!YZ4<6RUS(^-iqbiPbx?dM8%z#Oj?`y%Vc< zV)ag}-ig&av3e&~@5JhzSiKXgcVhKUtlo*$JF$8vR`0~>omjmEtG8hF@LY-(tlomv zTd;ZyR&T-TEm*w;tG8hFMy%e5)f=&TBUW$3>Wx^v5vw<1^+v2-h1ILDdKFf$!s=C6 zy$Y*WVf8AkUWL`GuzD3%ufpn8SiK6XS7G%ktX_rHtFU?%RQz|13aeLP^(w4hh1ILDdKFf$!s=C6y$Y*WVf7?dPh#~XR!?H}Bvwyi z^(0nLV)Z0ePh#~XR!?H}Bvwyi^(0nLV)Z0ePh#~XR!?H}Bvwyi^$M(Bfz@T?26=X| zdM#G3#p<I<>@Lae?Jt1rar3$gk_tiBMdFU0B#vHC)+z7(r3#p+A3 z`ckaE6ss@A>Ma<(6Qg%x^iGW4iP1YTdJ>~2F?tfCCoy^wqwm-iU-cim;;TORDw2$p z_7z@gC)(vAYr{RE^UaiAHB$W9M9!_ z3-k4V-0In5yl|)R!d)0?es>#B+{gID!z}REnaBOk9POKYE7SQ_rt^nP=MSmi52@e} zna&?Foj;_4Kcs>`WIBJybpDX({2|l%L#FeGOy>`o&L2|2A5y^|GMztUI)6w7e@F#? z$aGnYS4A`DkjcUSyd3<`%fa9GJhA8ZI8W?(IryKKga3Is_@Ce7JhA8H;NNwg*nk0M z^z$OdxrlKtVtk8?h9W42QaF_V@dz{DBjG5pr* z9t-mtuBXXrXtElbtd1tDqsi)MvO1cqjwY+4$?9mbI-0DGCaa^#>S(e$nyii{tE0*4 zXtFw*td1tDqsi)MvO1cqjwY+4$?9mbI-0DGCaa^#>S(e$nyii{tE0*4XtFw*Y%NVz zOOv(GWGysV3r*HaleN-htupYp(`Bu6Su0)ElF?-?bXm(Dx~zsStD(zkGP9ROo7N^S^>9R(;Yy(}^ zOqX@gWeK`$V^*V>ux4IEIkE?wNn4!<7sIFF23qW^aAQzIqt#_JT1!Tw#c8xSjkb|S zTgyk>L8sNxX&dRZIGt8UrzPmL7CNnkPTNSQ)zN8nbXpyqR!67R(P?#bS{qev4LKzrPo^MwHA7*%!& zPWWr`IvF%(bXyDE7N^^4a;^(@KdT`6E05Pr^)^13yQ#-za{L z4ugGRKiD6JLjjC}LeR#e+IUnOkCwm~(AJ{|!a-05i5Q914fQaquaxS}jhi z#c8!Ttrn-%;axS}jhi#c8!T ztrn-%;AEl#V&X|*`57N^zXv|5~2i_>axS}jhi#c8!Ttrn-%;zr|t8Jv!HqvSvX*H)c1RK*@tyP@MW=KLCY=P}g#O#C} z@D}WZE@uXG!`tu<{3B?j-|8a&H_q7(RozIcuAHhna91{!|G8{7*;eJ&Sb^JQy*y=A zdu!Hkkt|2z*>HXL6|deBb@sn;LeD>sJs(O#ZL~ffuFJnCI^C|4!{wq1_xFYwjKlp$ zVTQZw<#;a4J2PFLo*e=;kpVdmg)vLfC3(XmBO>D?k>H)6EtnR_Ulu$Nyc#?e+!Nd% ztPYy|{wJ_CxG|XNduvb^{4iJ>%nJTa75@wWg3Uonp00>1Xw6nZ{0kcVw$=9}B!X>0 zlJ6`1FEFF`&JKUC^IInm`rcu!g3+=b?_vt-u3C{gPDHb((|0Y|B+%3-}RZ%FWB!9KEd)}Y36T> zGT#@b?frc4OSYWd^Skh!;j7&((z`KgHwXZ{_m-Eqk`8dt?o5X_==t$#-@h9OZb!?7PeW>(W)#}nU-AdTJzKIVcSeC zXT}aczY+eW=N~I{r>%n5+@UJ`ZNP7m9(U4p9JbHix(SxKcX!y|)8*f!Rfw$U--9#P z?RKVdc&&Zlj^NVt>z@Qi1?7Hj=OqaL)*cM8-y{-zJGdmcILLQSdnCv+x{eOc3oZQM_Tip>-5uNzeol?8@b%^N^InGsZVEo* z%2SOVH#<8%68zfew;@;<_9wmI!SuBr@cQ+h{;D6%4xaM!j?DA#2!57scdcPLf_p>j zV3V1_&x5af`g^ta-#cM468z0yJA2z(PaARuZN$|cN#Enu;N^6^bp=LGzwh!%y+~_) zG;l&}`gca6%w5xcKmEI&{2W+$0%E#*}1aO2$Z%BuO&HG-VoN8e@!UWYm~4GLj@oQb|%tl7x^XNxJv{UEh6= zdoNct^XvEfpY=J{GN9wuh_1Le2e_2WJ`zka|_3Lc^ z>KAuL^LGyRw9`n!Uqhh-GnE6lfp!tHiQOq_sn{SJG=3aB3_?x-kJRlx5 zKQWJsznf*2A)d1QmMd0SK`SBFS{bWYY_v+O67jxuzIB1vXoS1493T?n>~EVXaHnx@lg6 znl@0=i1{{eKz-||?@^#XH*XQr9E-Y7qV8`4KOP!jPy-BVfB_Bov+$Yo&4uuJeH7YY zQX5QagGp^LsSOsiVZX4<1JDT@I&m2EGxJN~n8%?X7WKn~emKIkTxf|!Epe$OF15s^ zmIRn8XBjbY1b-^12x@uj)U#wjWzNgj`u{FK4UZ7Va#>UomYrEm6 z_L24x<^}d>dk_tme7zbA<34|kS)Pr8<1=R z2KBz7J`!s^#Py%+SiMFct>bR!WA(9U8@FQphqyjo9}j*4)~_@5JM}y9_K>^vyU{+U zARfB5K2@KJ^3(Kbkk8a-Vh!lu=)ZyF0jzU}wIdM6AJ>1c{~oz>v7();FT{Fwrv9Y< zq|l8)2I|fjjX3|XahGuy-ursDaX07`V+x}G?=kKXjg6_sRPgs2_lm~81XcqG`=0Tw zQmZ-no)enyW#4PyRX?5dz3+P;E9!jY`$!~w`+fVdN=1EteG&AlwFBb*hFBNR^ndC9 z5?;2d|E|OSyAJwqysw9CyO6Cq$yS|YTTPn#&_frnO%|}FCE3!FY-vfhu5;MB&SC3{ zvUNq-x}t1d23wcEO6#h{)+O1xBwJTQwyuWOL)KhT&zff~0bOb>2VH@+HR9GP>p83n z^n&#Q=sLWwGGT4BHiEulZGq%%ytOiC?XsXD);{ZF(EV8b&$SL>{XW+!w|!XO%x~Mm zhj&_rK_gg~BW|a$GKXeou}Xqw*Mjw{*$rU-Voe9EIiTTPmrX&NV+B8rZ@kp_#>=?f z7ONbD?XGz5WsvW^4C1|)mxJ$XUxoF7er(?eI@TTsI^Mn=@;mK&K<|Y`9klPWXW(5v zGx46xv+$lw%$V3K?dM^2zhG|y-E6-Bx&>?TW$d@G>R#4Yq-_azs1N$9@$=%0i++_{E5 zkg}$ZW3>1_zRh4O?ZI~*w%#eXJiAYgO3w7bxE`_W7_)3CKM!N&4>0cA z1q%mr2pE3>4aQjZGaPLzEC*UxXFLvO;W37}4ByYoAES-JJ?XeHD`PNZsX`MB~0JSr?^Sjfk5=C$7V+ACEt8dYQek1;Yl zhF>+NRW`;)&HkRl;i5W&zbLs%J+^z z?o-?w)RFh$U7&r4GT(4dx#ydt7^|bK$FEX6wm!lP=*bW4)phujr zU)}$4d}u2l#4(jVzzQn=El{to%KLalF~YweHYnyYK;OdE?=7E)H@Qw*xNdtdfG#aXb=9eI>xK`&WAQ1K6yWG1mcI)4rtYUh`Y82 zeZ$kZFBO()#hIWV=qYyco~mOkh9(?WJ%aj_PX=a~*Ym?fiC#f%0!OOIf1jn)F}}oI z#J@g?l1QE~yVR=I{6~2l!uh z<6i9pW`h{#lPD37h6pNUhrh_{c%ov@_scK#I3DK!?(!kr_v(m|j`ao5lSy|^Buk4MFDjyuM1+;I!X5o0-y7>9Ah%i=cQs~Am;=Qv^l#}RjM z95E5&h$3+(M-X>$1TopX)x1^QZGL5bC8k&bDiMkk`K;-7XS=gzs^_z2spqri;`w})mQYV-t+skHYfaUYS!``iYf)=mYOP7F#TslF{aVyoi&`6^*1FVMNv#cY^oy0+pt}xrH$>fa zsk;g4u0`Fotfw&AG^no{^;PF+Q|D+?RvB#?)LnzRYjCt_aJ1=z27d`#^f=a#_E}#+ zn=Ot!{Tz9k9C?}?dEzZ_7lFvZ_#1E+|lShRs9v@rj<0HpiNtcHf@I1Y=(Ahj&^L0cC3$ftfU-*UEv9O3IS!|Orw#hUt(iAPy6fM#eaVCovsiZ|JfisN-0;JGI zi`bGyY{??FWYJ!g#Fi{#OBS&ui`bF{Y-um{Qr2ve)@+gplSS0gLzOI|jvk&QY2`{< zxsrI2MLfx(#p}@GbX3!O}6+0|+qn^rP(f7pV=eTgD{rQpE_jKqghpE8stBqo-WPeXAMyqeb8dX-tF^p|1#=GCs z!A~B>n?23nH=OHR#{DOE{12J(mgU!0-K9K@xyz@Z6F)2OUACb7cV!1Krf*l?v%IHB zlz&xrTiKiC2CTm3SP{fIOmlA6ByR$@_&0rsfq~zse#6v{^3#A zRFv;h@vH37iHa|Kue@oc9a{cNp6^zm5Eb^VSH62OW4r|fHABoAA}iYc=Go;NI|B0_tXq zlBhO&`UhHznctc}oOA!8ro6l+ROWs2Gf??2RF6Og)LEn6(ryunciHqZ$qz*r`H|csE|&Y`0nuF^l2}nv9+97mUh*sX zl_-^8%df?y5<>*h+mMDKE;BANE)tg;y^LO>uW!3=yST!4z;{6O^L_67T>QvfY%Ui4 z%}wU(;!5))bC0;n{M!6lT`iMbJUuT4vns+JVzskn;yGuz^NiTw zJnK9wHaX8Z&x_Zcb$Gw^7H6ZgQM{?vR^z?A_6&Dc^3EE#vxjkiKST11BS@zB9LW+# zk!^pXS55On%J|iHX_@ zvbI93Et|C!L~TX!M&6hfM~&hggIEV7sU@+dM+&tVW-Z29iz(J(3bj}W@7cPj%OvYE zin=@-do@ChrdXpX)@YhFnm~;%6}J4B{FeyIWvE>rYInIX<-bwK4(fO%=ri&e;g_pW z-#*m$3*gtG)@{`K%iuRktj#N5k*|P%RlW-THE4sM+Tf!$*wBVuA|*eBPDG#+ABmXU z1I>s-Gd>30FZYY6JOC|8P)icjk|?z#N-c>}OQO`02(=_cElE>LB()?=EwQL2Hnqg2 zme|x1+xdZWnb4d*&=noJG92^&?~c>j*G68dCQp90V)yq(8c1FecttHRW(IJHXo8vLED))XHItO_o6BU$1jB!5MF zRhra-n$!xq^Cgg#uaE-Nni^Z91zJpiMhk9jy-Z<}3|wh@ocGqh_3~)zj)hUS9*orZvzSzzd)uw8YWQL5p{^ z##&?a3aZ^lw5D29NSbTS;hn8K1ze&k#Y9y!qAJBiRWzb1Nunw`Jq5zVR&;s_go&_7 zA}o>!iy{9a{{k&pBo~1$mWx4`$R(gk|60hE(7bcxYPnhjl@N486(MUcopGOb0 zR<4EQ1!!S2xn8~`8dDbwsejGnCb>yuZB5^`M0Z!G9t@fsU%as-FB5D~#8XpUKZe5j64$B%jNpqQ3k>qP5Fo@=MWB z9+$_#tNtu2PoO_@WSJ~O8P%&f20CV}Zmt_TyaQAZ=NLZ2kN2OMh6#ydI3jDfh6{No zqZ8Ke>2CB80pkY-)}=Fg8a=^ZVq79>Q`a4%)F?&C-bQcGKE~xZ!WG69pvni~Eczgv zMIVF^eGsDbK?u>rd97FmL~a^(5%Ot$%~AvDUyd zXRWmsYj(YCy$t?M>rK$NthYe-T6^KQ?${1!%1+_U0~tGmS^fH0GtaS$uxei1Ze}+F z?P7OBvJZ;{o(4V8 zdM7#X<6x`y+H(uG=T>aPP0)r{ie}C#XO(ElmfVyr*BH#zN!$0(G%zOS5^Ssw1ZNydyaE#kg z3k$*D4GVA~yd`eU@AIGh)-+~S`(sVGY9ClB2bE=3{e!V*mGLHQ!I}B|yxjB1#qn0= zbN-WGtOHWR2iG#Jx)?qQPnA#0%Mh{34`e@9xC&5>gFps`mJd~8+`lzgMa!FQUkFW5 zcobo~=>pTJKT-V!*%!{vSP z`)kP5b_tI7CfY152eoe=g*r1LmOsP)?3don71{)>>}iFL~@{)cYq&QuV`oG{}=6B4UA> zu~+`q6_Rf1w|qEhMJs`gd1t=;A&S2?^Y)??P&s^>=4%u^>d6nwH#xakfYLX6<Dg#ofK4nMC zeI8d6MJzhxMf9jI}CujZV8p z(ylRR*GSqm2G8o_S$#aKpEJiMXO1n-9NYAOc6c2wuOqFhB~}57m=zxf%h1|6_oFKi1YRhIAf3Z`5~n_OWy!iWFgwCieYF@uk{x6T0ft2 z@_3IhQhUzH1KmMt$2s{Z=j0vE$p<(m?{H4OE9c~O`mq@FOYcsvmF}FMcj%GcowM`- z`m1#3T)oA)`mUU-??R81&YZD7n=|%}Ib+|EGxq0k#=e7i5vd8SWgn3kKTw&ic(=O3 zxOx%exs z%s-%3HKWb^1L{^Y+RSySTeYcMwWwRQsav(ETLsju0_s*%>Q)2lRtxHuL*433@A`A; zq0oTd_2<$RsL+TDq=*Zohzq2M3$!IJP@lL!E8+t6i3@~@3tUKCpgwVdMr>&% z#04aAfks3GS`iVrkcfb4f$(}DB2Y?1-~u87r9=dZhzOJt5r`2HC}LY}NJO9w5rHBi z0sSB9I{>P)bCgH4%YQA_6%g0x=>2r9=eU5D|zG5y%h`C?yuqiYP!U z+W)ZrVgHxX{x7BdAEW&rqi2Uf6rcxDfF48vE+z`ljVQpyL;~9K@tQNR()ZNv{xx zm`IG6NQxdJ4n0Hy#7AQE6A92y#35D^BUTcl&xk{x5r?=*jGiM7Jx99IbEGRhM|AqC z8AMfL^dB*Zt(-+vrPRK_z5wr~R(MJ&BOtod53M`>(7Myp#KT!q#93nWI&p}$q=>e} z=z-!8b19{lT6ZEZrSw(nPG7a|^iQ$qpJLHJr3<~(I@3$7GriP0(_`gqdaN`iYSV^( zD;?>#avl+!mh@gZk2p?C`ml5$n&TsO>nC>mLt?i-BzD`2*ljOoqH`yZU4{7cB;u1K zg4@=4%6UpOA>xxI;?syIPbpEJ3yAX6A<9!ql&6#^Pivw)r9^oO={47#&*lO?n;Y=i z+=9<$htKBDM1MNDkGYTGttn5sOFc#W~)9N?F8an27;mJ6Qb$fzic|JzR<7yG|G>wkAPc+%{L zy{TfF)M^@^Lfel6kD&$i-yQLr_VSQI_y%E?DG{sxb0KZrr0(29-m8R3P>eGst z`EAhc>F`JSUiDj@t@2Z`Dg>-Y?^9`Qqm5Hq5qH0j5&3KL<-VU^V2FG0-=D^JE8;}3 zUM{#h^T(z?+S6Q};7+_t0MSw9zXd&jbv@MY@BU}C1!NaU7w+#2#H?Utrjy=fF`hrG zC|7G(fcb$3^Vd}Kufn~cJ-dLv;r(amt+(Qzoj`gNSNZ44RZD8#yHX0jBehmW6-Z*y_4_5u0D8d|tlpW``qtY)O+ z|Kh4}C9mVzyBW2J725IS-3|VeJhEMR1;}|FC0RwR1*PlWMzEgWeO=D#i9OEF@ z(b>!zUV?3`sZx2iO73(_w=(a4lS415TIKubBNgiYKKd)=oAZtSH~-D`e79Djp2cWm z@LR^UdH39<27izhDe?(#Q?_dzbIZ38(`fzueJF4i0ZTj^$VvU#^T#hhx+Hh*uEe zeARr-e8=2ozH4qb-!pfZ@0&Z#56oTWhvshcgymDV7Obl#R#RA4&8-&7y0Xd;Ki$r5 zZ(nG4ushnF?2DYIFsJzcZB6}W#LVMg3(1*n zjdR+D`v1bG?tt(!mfoZVYte$WXu;aFU>#bpHZ52O_h+Sus(XYLFT5FSWs3%V$9=~| zlrz{aZB7^W4KWwqJT~pjpt^@5gu6He@~P%j(AjvyRS5TR9(deG^|mW>E$A!eYoPC# zyFpKwCop&IvwWb+7LDQ#wE`_eq`HZFa}j2nm8B8oOs~e7UISQNePVTWiPbfL$A@2d zt4-7geisCn z&L`4l6KS)Ew55o&Swz|_B5iRZZ8niMi%8qKMB2I%Y4Z_jlSJBlMA{^gwu_0hbtcBv znTVQBM6Es%wH#5jbBLnVCyI6sqkRgArPXJ&Pa&gy3W=-LC$4r5V}9xpS1Tf}R-Z9H zg+$kih_2Hf9qWv)QLKWuMZN zeM$@VCM_5TRmcdaLLy=HiG+1v1XLkop9&fER7fN&NhHjs=ZuGkrHO}iBp%jtStIM7!Obo0p`=c;1u)4&+8Zb)ATeqV=d#E&fsJ2AH>N8@hkP%abjF>89#8e?8 zrV5FZ)n~+1AtR;=88KDJh^azGOcfGEJBujVS&Wz}G}Ssyg*PZ3eKBI0cUB5eU;YyqNcHqo_? zMAU4eXf{zao5-0>Y|JJqb}l`RS`izw=yBAF9!IT+leH&KX3_7cBk?esNLWWAVKy-^ zi|Cg{1j`_5WfHG4iBz>CQgtDbsy0Nb+7PMgK%}Yzk*ZEasxBZ>brF%O2z`@ce2TOs zUgZ$4%Fsi}rH9ga#I7u2R~oUaB(W=t*p)@>Dn;zdB6j8ZAf8XusyX!3ycQ)R?GMny6JVQ7fCzv*vuBHDR<^Ay$o=r<$!b#9oFqu`a-fXBWnfd*BQ4 zHr6-%2&12E*nSaS7B7|Kogx?)Jwy9;2S(LzW5l-gyNyV{`>0K=GDR_^BqSM(Id zibr9yU_D)UZEV8UOW)m(3ig1C2*MmN;!}2%pASEeuPW9!-39I?g*M>7ehJ?!oH36^ zdC?FRSAa7ruBNC7uS9iP-Uut3oP+Y0U@eo{@F5wa){FE$xDt2;lwYpaA{2PL7x=m5 zm#VzH9Z!Br`C$GI!dUrEjF_*$5l57F!zu~Auny=dl~?tH|G2&aH8LwurbjFDxhlr| zDi#s0Kz*wEg}@qlfiktm=F_;xf1xdU2TJ{#>r9+#OY#VLQt1JbmsI}dXYg_NbHE|` zVP%jX;i#S9)iV_9_jOSvl^xFCUx9}$<9)C$;}dF~h>ERC;SX>LugAnOuFm_EROB{9 z&I9FF5)pw16k?bjQaM#EZrn-aK&JA4=jCAykSfXYzkG^hU-j+kTfi)^imQ^L58R*kk;#{-ilLp^OQvc& z=aIh1?_a~OhP6g^!ixI}HktDOuLpansa&8e3fL2iVK1z~T=^zg0Pu{*_#IyC7>Vm@ z?5#%FYV3@$?iape7!#grooBVS+FI=}uDcbZv^z0In`+%_O|$N^rdz*Mqcn`s{-nlZ z7>%vLDC|v)yY^zF)kTe=FoL?t9%|y%}DI zBUG1TP?uxS0LP#~jzI$)g9bSU4RH(_;uti{F=&Ki&sc zyd^c&r7hl&ws?lNc$~JlkG6Q6ws>>e;_)hRD$Qw&7gNi#w8fj#7H>*hJWjoDOj|ro zTij1uJWgA@DQ)pMZE-}YoQzY6vu$Ln#Hsjci^pk;pG{l5C2jGuX^Xd{E$+}3kJA>9 z(-x1@7OxtoQj4~DE!yIZi0?I{Mc#<`UNc(ZwP|x}Y=>U7N`hElOSZ`(w#jp8bC=N0 z_Pk7NTGB0PNte*BEumf8k``?VE!q-Vv?a7?Te9^A*m_;spoO$S3u%28vJHn$Yr|%h z7?+~&5aW`h#Tll>8K=b=ro|bi#d#K6dz`Jkh^^g=bSYwM_aa^5Z0&Kj_AFa_jIBLJ zi?a?b&IYtN&!fe89xcw=v^Zxb#a#eY=3)%NOtsJBvSrM{QX7Nzt4X_ob5mC|3WnOpD+#4()63IXln+|i0EXd z&5Y=3o@Ew`Zmx8t=;Qibzqs7BU0d{Z@ex1(mR*ifXlSPg6#d@dD^-kz)bcEC!$w_%O3+mSB98`@`Jjj3yUAIm%WAk=&kG>$7wffH;db} zXSHX=c%Ywnt2uDbTf`k$0c@ODN*}*v`W;v`_bGVv-7A*s_v!bE75WT)hIm?kP=8RY zgrzL3|+q2idlN!}!m z%Uk3v;wyQ(yj`3C(mG#!E&nS2s`*qeuKDHT@^Q_S|CImKEX2ZopxLU=)6O>nMnG$0 zM2(nsfsr(lT00|cWVH51fl;7!FwQdSX&sH02Hx3jTxfLAdZJ(Ksr5qt*IWCM(bwp! z4ODX)+SO|9Uu}>t>&t3C_SN>))du?-_!?-}`L6U`sSQ=L8QS$&6>Y6H3@GFdZ3K|V zkF=4#y}te0D4>l;wJ~ZYNE@rB543UqkUyl|rf^1WJXT0+sNJso?zD-(9Iw#s1kN~C zTLj$jX>Bbq!Q;AvIUQH;0Hkk@UTQsT&DFPCf42UizmE~yzw|>`KkX^~2-Z(~PRAQv zt=ILhtv9SK(y_K$Z^?l5j`h9_!2|6>nY8v;2V@%lW`?Yd_0S4seY>7rPnMuRYbeiC zYoN(CSOcx4ya4N-wUHgwio5b+_?ulUOW|*JiR^9v&@Po&b=U4MudoN$s3nXKua;Na zgYBVmkUh*EC$Cf9WpXV1$|lKi_TBc~ay-1tekpHWcG)N*Dy^NiZgeCJuC7=7pSMi2Cw>y1mCmz|A<@+;eH z^j5xPMql7@Ul>=wbL@n1t=rY@YFzJL>0W6Ja|gNuji0*LxYroN-Rs=zj2qlx?l5D7 zdxLv}@iX^k_h#cpceFd&xXJycJHr_1-tYd_7zMxZ$BeN+@s=Co)JV^`U14^{9YE_| zGA6n&yDuA)#PvdGSj|FPc*^hmitX?6i`5>qrB%wW0Kd9oTOB)p48{L9-&3#czd455 z=kZg{pTFj+*Sij7Hl9*0e?A}|TGj6kZ0EnQU^Upt>g#T;{A$M_Q{Tf?WEFhAY<@rf zRxNi-Xk|AUgF#37_JH0-`kwzoD`gD7Y5!A&JHdL zF0&g3*SoXqCc!PiJ;C+P)Zjt8Rq(joCKL<*!#P;sbrs7Gj2XmVtX-8E1cnq&8j zl-RxPe)d2}M}^jgHZW~<9|`RWjSB9xuR-g+(HT?9lQDK$@4V_3;f`!|2RK_olLL=C z+kz$GR^e6=2X|?!vokc**%R0wS>POmKk0E-xc=~TH{ixXlT~svky>sYw<-2D2zQh_)}7!^cBcggg{Mcx z1Q)q8-C2>H?wmkRcb@x5aHYFA(#hQw-W=Y6JG|Uo6c53~t%2y_k34IT-X1$u@HLyrV{M~(!p3G~BvAil=}!-DGrHwH@r6N8Nc zqXXjt69ZEM(*ySh9tu1hm>*aeS{rygur#nDusXCMur9DMR195uJg^yh+cq*Lv>5ky zN4RTXcVK^bN8m7yR~B3uIuSI&9U?nJbxuv;(V;p)=TvD;+rdapQY8zQh0Ac16jCj; zuH&K3!Fo)Mf?g^KHVc+S`UKlnq)w4N(57y|A*ZB1!Cq*Sr%LnNgM$5;HwaXHPo~I9 z#YbibhgVJEx1qBm(Zb$7Qwoj@zm1xxp2l$7qt$b2-Wn4e6C978L!}wPsrY(nHhPf< z@KtGUZ~=5?QE-V$`Kv*TtGKe@%HW#Fmg*_EKKN>IeRWx6OL+IGlA5=%?-rz;NZW!t zLxJEP^i`)M_7keFICzpffLhlYlR2IG4&L5KT>20&I#TA5F7L}ZLg=yAq|yN1RhO{kEt zKZzWSY>R9QolvxD3QY^mjI0Tr@N&Xky}Zz@(45e`&?6@k@|hNct_?lGKHlr;H-wf~ z+saE<@ma7bluujnJlGZ5PO7+lp+ljgNckh52v3RZjO+~O6wRlw9=5`vaH6`@%MBNz zbfKcv67E5`;mOo0+(h-c6{$_QL%8d=rk>$`NWDq>g$ITQMjAyLg|AVxY6=fyx)D#< zap8&KDdFki`%g;`g&+P8)BNzM2|ew9kRA_zTf%cAyy82g)%mvi9e>w_H{zMHIa2Fn z`5ow`_gAFD;bY;lh!Jrj>XVApVycHb+ALBMX&dPj>2@;pisVzDh?n|Dyfi2>Br-fQ z5}G|eG6~P%8IcDfvm+^e3dhQB;3~^k<67 zi^vx%s%=*1()%f@{fLqm$bZfXr2V^#w|zji>xMmf<~-&r@<2CH+bNLfVb;VTx*B zkbjc&V$#bLmEC#X%gJ{p_3i-mM>b*ZjY@9RW$uNF>buA{ro1I3-c`M?c+LCo|5AL} z9~702qVT8!HA*O+r@7=4ej^A^GVs_a933?aY9Lqrzo#S zdX}R44@vo7bZUimHzmDDSr@w3`tG5ml$3W^r?%_wQ9@lZc$f64l-x@?igYCDO{618 z2Pmrjl|1WO^Xl|dC6Nu7+lcgC((ROYP*lH#lHH_(NEecRt*CC1Kb!OuMa5_2W8}G) zI7A8WiTH>-uUzaW-<aA3FHmswbi8mAgx6@R8gI+ z29u=f$Z^sra}P5&Nq!CKCQ4Y3I%`Vus$@eYmuyXv_eb)d>b<$w^W3XDd7FGIQkK-c z`xBsqJ&X||{}t)OilT2<*LgGPgOqr!@6VJhS5*50BbB7DDXQ%x@9FSW zikG}j*@N;Sq_--n`N<2?#-!(xwjlLtll3V3DT%g#@=HkBezm2PdsiML|2tAo54*4= z+pqM_!aFPrDUXnzuc+_GiW)3q@ES0?&>HsytL8(O;`)XD3;iAZUHo1B-TdACJ^VlL z_w--s|J3xEF0ATK?nSVxrvu5q3`l+}Ao=G5y>CJE{(PeMZSc;QUhsMAi`0%7KIRLM zIsnNZ0<3;0-qUe0aQg{(3&@>F1MxPF8OZ+w()D67(lGHj(occpZvxi88OZ$@%)Y*d zRTAFEJnNleFXmaNii1e^5xt*|xziS65wZFW!0Pt`OK+|>7q96p^_F6j-db-1Ed3(= zk3i8E$vd_4R%iqi2>j~iAf6=&Fje3v+HI@|mMfS`Wu zAFQxb|7eAp`hTHNQ~wx+k@{~@7^#0O@Q<76+qa@j#c#47wg*@HYVhy?E>|8^v}~lJ+Fj*O`DZ1^1)Jrz zC+|-#OgWq0l4g$ptx;(u>opf>ZIGfwA-O-~;Kc>7xa?OfJ(T+$1(E(-Uc9v^aB3aCWG3 zYD^MH4R8fm@0t0T$1|%ln=`vJWmzYJ(kL2nEkLT9riq(Hq7I(5R z)hiT;3<0*6$@NgSbaG;3Zm2l5EVdg~bn8(2+<;thsB>~*s7GW0Y~;S#mEn!K5$Q+L zkK|6|#^xsEW=02R7lj7o<`v|!>kAeZ-Qch@lt~2c2<)KxoZbEC5 zyF(iiV?&#=+p=r$ANGW{7PLuB4iBVdyDxTQ=ukMJtlHQ^VLi1ZZ@nh!q$Wj|nc$7OdaJ1)AspbhS9y?BYTWd z6_H7a9+9bu*2;n_7^iHwbZ6LY3*rYoOD?sb;KqWU1;ZjMqk}6gy3`TabhPLq#|v_) z@llaI9`#29(O5JSt%Fn)Z6946EsnN`w$AJa-#O7f+9O(;9vkf&9gvF^Ow5kQe`ywd zB$kLC&5qADN<9!A9McoUnQ_@Y(V@{1(S6ZT(Xr791%>eCrdvq6$aVUB;dLpLBtXL>JBReUU zh@ln63R9`<@L0p_?A+Q|lUS32iMXDTu~wPsu{N;|v975}@se22SnpWB_K#HJMFV$);y#~zA39Gf3o7<)XnG*cE^Q7}E#E4Dhe zF19f-Ikq|Wc5Fv%cWi&`aO_yDEVU$86gT2dJQ7b8w8`~|*NWGRH;Ok)?TMGf+r~S^ zyTyCO`^5Xl2gQfPhi6u#Qt^@TG4b(^m(n zGchYMCowPaNMdo~iDbXT^2Dmd+QbHE`+&rz#8%ZeB}XT=CmW_$C3dCiCHAF;=S1RA zW<}y?;)F^`J-H&&A!()iCPSGO$wV@jEKEM08-dh0*)TUb*(8bfm~4~mP%uB)HQ6)S zJJ~NeFnLY3Bsna3Bm2HSnckU1_IPG`a&*DM)S6RMa$IUna$;(I6?r9J$(^=emGWz_ z_bCZag2Acv$tg(F@hrJN`B3uVagScm^ry+tqTstsTkDlE;zS(Y-AWx4i9MHOGgpG+x( z(jw$mNviKZV{$5T^1o*)8Nss?pLA)eR;pgAUb++snv-gj9>p{w)htzlr)t|&C!}r_ z*Ho11MGjY!>XYi98dUI5^_1(88j0_aN~z*g!z;JHiA#;-)sIh&PmRG>UHep|8Kml0 zr3aX1=jPydw#TOyq!y*-rsih16$~W5D7!7S^0c(12FWtYl-9g@GHt;~!Al2I`LqYz z&MI4bQu(Ax97!ElDOZ|0p2kvQ=^~^6sp7n?V#@rGs}V?EuB2Ydr0bmIi_1 zx2AWcx8v)jed$B#qv;dr6B#{YRZJ4#JV*&7^n;m(7=KhtnI;7bGfgtBDy53Ay6xp; z+CbVy(W(h!Gu%JWu9=>>4Y>`O-q}WqBK70;u*|^Bu*{8_Ye5XSSy+WvTMO}YR`R8!t265|8#6nQHj};$x;wKU>2TJ_8kuAGmMQME z15xk8Fq#`(Fb*T0DM-@`?nfW`Fk0}!g2xM% z;#sx2U|qpRSnKo4t^$1wYeWFOR92Lfw576?zo~d*Cgoj~MEhD%BcLRD5lf!K+^LHC zHBwq;;#0+oPr26xir3bYzfSS;LzcXf@|zUZ7f^l?X=6(MN~&|OMdbUD-c89~(qp7= zE2?X zT>c~3N%3-@qMBEC6PSC5@~c>W9VLHOyfi3DleXtx3B_yoP!i%^eJS}T_bO+Z2NV_a zD1VhD&nAsg{xRjnipt?iB5$DNMbaSY9Lj&8sJ5DtR}`;%XXmwPe`KzAwar=P3rZek zN$QDyHF=%%r>czX%rd1O{3*+MaY}D?+nV5q{B#$lCDxzqi*ZBD_(r0%8SF4FI7~s9`(WG`%}JM zQJtEmvo+~IVQvBCKW3RS@}H6aJ*lTr^%XC8h1%DYvlVC`k>^=7){*ubO4^X#si@dX z{zg(i>1@&|q?eGgMQGG>?LH;Z&!W5zX=75}Nv%Ea;X|ZDSn^s$#c@hrBK2C(xs)Fv zWnByQFoGH=mQ&8QFCHPkQBm1MQH`xtXT4|-QNlJQ?q^A_-n&um=}9}vk5RIgv@0ds zNU3|;^^|+ZucNM0r{3z%E4jQ(QNvVJzm1f=mL%2R=l`;~*FMq*NsCC?GssTl7pr}> z@jSxcl*IUOQ9qw&bv>n!;+>61z>Tkr^@$gksGKO*nl0qTs-`=F0ia{WW@JDHU2U3&f1)s&23 z8S1=#JC8Pi@~0{9Lf%I?TeM!6=W5E_66Rh*%IlPl;x+ykZ7SvLd3643$@U_rabLDI zotiH-O85*iZc}?1K1!$+I$NCVq9l?%o3>T)+Cr8oA@B95yg&L=N@DO_273k{^~7LF zeGadR`Xi}t`Xp6e{))$0!Lxh+i+556DBqyu;vo5-lkyH|&B&)oTc|P`doZz*JddnV zAM~lJj9yIInz=K1Os_Zlit-eX^A2-&E2>8+_xj!mikGjj%nwP~pJ>l0UU)})nftaR zjgYn?)fCko?#1@2&r`fUS5Zk`mQpg2^k<~(Tl6VvUumt}fPbhc~V zYke2-j7>;cclt%#%X|8>?Ms~!_Lf?PC0Sou2g<$coJGE#qLRI|UdHSB6D8jD&*i=+ zSn`D8jT@Q!2}>4|)+P1&L$4P4t1?=Kd$Bd?qf{Ba4kcdS(ucfvXG)ptJ&$&HJahlz zQ6({4#Tzbj@1=Ys`I|hRl-H&YAkVg@?N_|^u}4*TZ9n&FNS^INW6vNPaId#m@=50I zCcmBKXOUjPGUt)9Wocepqdw@=1Z@!aVvE)eaxbrE8>)C2QdHyJ)9NW+u$>CFGA%|4 z^-~;TN#1jvJ*3835Z*uH-4OgQT63Q9fGRI9RJ?5MQA)htshN`K&6Gqxmz2GM zm0WM?@uV|Jy*|)jt~YYKLdj)JNo15f+pqQ+k9?RV8*yK@BkA=>Qc1KmEc0v9HIzI@ z+MkqdO7parnk?AcYrGF)gW5~{f%~$hh}q;mC!y2_qE8rRH zvgDVF>hnpnib~d_Y)JlG(nh3bd%W6L@2z;fH;?08XDdp&Q*xQ&wb7*PRrE#Ni#?Uj zqv@VLe?d8GR`1Cpct$s7*4^na$`9G5`S5$kKly^xc$iG9nidVHt z@p>oHj-)=))ugW}s_i6Sps1jB=~t28%-j*=`5e@|K8p82@;=BODp&U4KN_NVeF*tm z$y3t=uSah|iFa?iDqieURO7$UFJW$+^w+%d*O~h=X%k9*LwY|YwOLXsDn6j3J0)zJ zns*%5g}j{CLp_m&EYpCJ2zibw4ezQfCGq`OQA3bEqp0M4z|3+doNJUe7xTpyW7Pzs z)Iy9>OPD62)M}d<#HZC`d|G|?IYf&!ch@3XtR?nLV~*Ly+Fwzu_SIOtD*s@rNXE%n zn`{x@U-t^$UWfM^B8D-IxWt)G0iwkOqPzs6yDGmbqCWps@~S-I8-)5IuA!QI2e#E$ z9ZQv0{F(O4m&un?W%K0`1A+G;3Pb_pg&&B0F!04YL^Qk+1n(sjTCG#Q^{}nJjri5d ze`yTHTxnB9%che~CjFFD_njlOuMd+RC*7rJneMw3@&ly1Np~oUqapr5o3HlO7J;S_ zMb`tV6f^Y$Fo)k7+np)#q*z6rc`A1>=IyoeGPQ5{4;2-wNLNzw7t&dz&y#j0?W8DH zuTwODXlhMAYHR?1En*nY@i+E2^*8so^q=cL&wsxE0)IQiGG%&8<-8vv&}~4IcBk|yFS-+E!S~_ZrF{v2{+|7aGSc# z-4^b-?s@QcXydkXJGd9SJ>5y}-R@L(n)|4`$X)5Kf~Ky8RuA}(ydZ|a3qtunbff=6 zfBHXM4gZH<;k^-0B7K|BgNjwWkKPWC(%a!BcsuMv{9v;RZ-)~2IkeW#N1WhAh(LTx z|E)e(Yo`B2|EtypZxdLkwbK{ryS4WE9@$X4MP4MkXiMeAvZwZxyi{JQJtHrZ{j^oG zzZ|Hom4oCU?Ik%_4%Rlv8|01J%W|X~sl6sg$x+%S`3w0A?R7a;j@35HadN!&27D); z(6%bC3GER5B~+~66?%XAOWbH2G!E)F8D&P9K9ar@H`8}wl&_1gt3D216RY&`@S1pD zzXM(q@9UFPe4l;~eJAdv@5Ha@JMkdBCjLTyiG?bfPk&TJ^XXeuG@pJ*Mf1rL70oAy zA)4=i97}JCE3vXwz!*$#ifidjF^1k0x6+$p9K9)Sqc_E!^ro1lyeW*2u`2tQ#%C(t z&DRj|Zkv7Qsn|5%JIb@dw@rCg_zo%G3E!tGzRY(*c}@7r;5G3Qg1`||=C=^JDzpXP z@}2Q5`QNtx_nrU1w_ML`4X|FteNF|{qQF|`xdjJP3`-WEC<*r8&E(nW#8 zky_CSj2kk7PB0QT63gLLlY&>x;PlX7t!NQqdm6FCBf+VOiT8@OkI#)RN94;;72%Q)>B)#p5~0@VI`JWizA41Iq^BjOWjY|jC6+jv znTR^>g{iBVj9@|3N@B3`w?VB92zAa(Opazu%2wnf{v@$A(pE*FBsYdOMIT8G3XO=A zghoZ%N1BDks;dh3OdN%G%_E4Lo2{ZsLbDVbHzCz6Mi zPYu)B@G+Fw5ZaXK8QPjS8k+(ii+P?uO?X_gtBMnW_tQws<(8yX{K<*19^IE*2%nMJ zxEC9hk4_+$kw)nrk!GnOhWO_N#>ogAGOofF#+KN@(_pam$6pOfCD{ArRK zQE!V;Cht#!TpVpf^n~)OiEfYYNwiPTiS9}s%X`+qH=|8V&n%54;9-N#2j9c7Tp|`L zjE{*mj5SH@i?#B6YCL}$Y}1z}c4NF=Y&897M#rWkb^6g%c+w=tDPJ1QCAW?(jjc!? zj*m~4C3{03SEt4(ubK*DJb#*mA3hl?;@whxG7l$)o|;ly z5<}y?PLJqJhWuY7hAosp)&b4R7&6={s};K}6T<15mn%tEyGsqsap zqzB?N(9fSL&2P_z*N@`oR($jFMeqXxpXmTEpeiXn7JbUH%*6EAGo|>l^jP=?RZlCq z?a}HvHE*p{UPpKusk9~jD!yLYi6@itJyOZ@KY|C6O8Kink63YK34bDh`SEH=c_$@e z)n%FK>B*-`YTm}ab&!gYitz1=r{aXu5}pZ6%IhhgO5yjUYOpVSpcJpXpay@ZG=Qa) zevPP-M&Zdj7HM)tngGwKJgOmh?mP4+ymm{*bG z<*!OSL0>Fxp)7o|5}VL^knl|3o*I+bjLDcMYvm>7aix5$9#1Y!&8RrXYW^xet98kBsXg$tcsRMA^f2j0 zY-8L4x|tqT@S+0GJe8kM$zzbhvns#s{VLBY}Pp=`ZvUbZ;qqg_K7SED7TS6<6^;ikrMq9YH(h+lJ$OtazCvT|)Y@ zqT+MfBE)|*M(4;|l||l)R#-_89qXr29x& z3)P}F>lnA;p9+;L`?1V+-i<4H2NV^f5)x6w|5kyl0H*WVDU` zB9GITbf%&eQ9g`J^5Q#DgOF>pNJo-JNoSL8S68n6hSwic5--YA8^r%LQAy;z|F63% z0k5jM)@$v%&pqed0~A6C5|R)QGC)9PwGW&{1Z0STT16xz%puSuAYhb1Kud+9GSBl2 zg3Obkwbb@u0bAdDPQ2&$A!?6FZyeh(uS4fEilUXs|O_HVX+Ss z{FV5~`ls^a{6u_q%G(>oK3D9`1b->`xcJWzd!k@1!H$9-2>#Jv;BK-1RWMGlszLs5 zvFC_g-tt~!58NjHO$D3C+dqk2)?Hb81Wyp3VM5Qh4Ms@QN~=(90((+mQMYv=z`z>>Ugg++nT$Gr7ihU+N{(9I}V^{G832S4( zH|4G0CM%0wS}Due!hQ{kG%Aacg)7aUUe+`pnrW3}W{Fdf_?~a++E+g4|L1K^=bs70)=|{elbD*W9 z>&rSf61y!Z;}7;6OxrkN@G{cRH%rKt@>cqws$_h4nP8rv^zjG@Y1t#=jq-M*#6Ml^ z($l%O*!|H!xF+r+KJxA08OE*}3a0yZNnNC?l{P-5GS*`ExrHx{oli)yMamzyrPZmA zTUSHhd+3#GnG!aGG$tSl*toOeKa*(K86gfii3T^?pN zC4Enu4p|hRGom1mI`l2*J&=~?Wf$c`>RKZVUA#!KFl^kv6+<;B8Fy+mfW-H$koUd^ zGTxbx?e0l^DIfRQ7ZbG9KA3q|vXKbK@2Vgb2a?0_R1ex-n_<`UUdV($h~3g`NOup0 zJh!=z!-P|~fmIh6;Eul&FPHGFy zu-zbco(pZV1vG+2mxQ*kQ(YN*<4L$lEFHVzH$#g3F1jBYWPgEO+TMt@5WBZyNKF$|Z1(kr47;RLM8mFeJrE0T!9r~S*s?z}t&CGRCE|Z#re~ibvN0hr?lsh-l zZM76PZd%01lZ-K~F=7c4SxZaI6TS&O;o=`OnmzD7cql9$xb65TcX&R``}L9U9rHCP z%{SgVSyArQk#1K-xw}WXw@11|aba%IB{VF|jr2lCBi&xpFgL<`W24;1Bi$9cMY;Dy zx+{j~5AjvpANjsguPFBcaVxaX7@xwG+m@KqBSS*7nxULV3ywqEP4Pp;)b-7(y?irv zp>I|@7WwPy;q3+A=IRr|-W&JKNO#TK!rUlF&CyZrBT?>mqughr+$W>lerd|uZ%xzQ z{C1(}4SeHs`4siFYP#vcn9zs8v|#;UMzB$^ajhmf+8Wt%7$3j|D%$8Ll%p z%XJ!Ox=vnln#&4)8vHEycRLQJxhml#mpR*2!LDM**j4RVyPAF28S6H1Q{AS}2^)Y; zdl#zgD|uCI4Gs1Q!Sm2y-vpZLZ-pk<+o7qxz1PXh^tySEcs;yqFW2kq4e$neL%c$7 zm^adU(i;s8_7kAF{#9tK{{zaC4IU(i`dIN+Vz5fE=69S}yCZm4@ZRq|v-Zp2$8v7% zEKa4F6KUo=S`9niu4yOOiFT5G&>8L4aO2&ZLKo#cntvM2KZ{n=OT}q4a~AEN=g>NO zUA(T)V*4oc*ycdjZGUL89SmKzL%k7Ru{TQ2sZA_9pH_*qbH6*;>Eg~nnKZ_`$DJ&9 zrnECN_ApMADeylnaRzM-t)rJ{BWDZ4ztI!*6#cw@ zLBFV{>S=nCp25%Xv;1qG$iLy|^empFXY*wKEl=U+`2~KFr|O|RO%LPgdb0klbs}^m zbPVaXgtq?Gv=-WaHqa)VeA`AlXcz6JS8?OW-MDGwUfeL!9;0hV?!=wB3up3!oW)%+ z+VDfnm*DIW(*#q zQ-|^O^W!vS{QelD;=^y5+aRve*i6jk?^?uZV(9>?RR&(082z|Rtk)`!jB%7PckoRD z9hd^Bn+>4!)zHANB{QCP#J?Z!)z#7l3-c(xB(-G(d(6knb7qrMLhVvZY598>y}Ca_@Rf&9`pUZ+M2$6oh0GQ`Eb~id)-n> z1~=I~;=zgS>r|>b;K_SLJ^ij*YIVV1^}OU6a2?W9SXD^0s_8%I-|PMQuzpLwp%3Xl z>OblK)Ccsdyqs6?N?ygQc@3|_?&E9vclvexrv9@&2=0G9a+HWZ{$odUGlH3M$IMJj z&6zK=LYf=EIKHai!W`)8#x;Mm?2K5tmBfEF@fq#``70ZV6jpf>aL)U<{yQ(ly66}B zYkfk0sZZ)t`ZJ!vGkF%z<~f)r&F6)@h!^t`eOiB|&+t56a8)JqQIuC@uhr}Hdi@f3myP;my$N+3034gp5b^XMbFYpFgsQFCZ*^l+)vNd^YnbZfb;d7a&wIf^&-6( zsR^&;^HYd1h#X;k4|y4kTof>7M3R1jq@Sdh>eb-agi3me-c*`0N;M~fQla#@J`-^x&0n~1-q}3ACzo%8Ks0yB~%K}Qvt+MoWv#)~XMdqmAs2&6&+udlAzW38 zkvgf0yuU38%KdW0US-_`Hw_w@(*i2mOz`h5@;#<>5g-`4*{a}dW7^N*gK4Gt)XFRqKR z(ySI4$+4>7yQ*QGqy|=*lPDQ$Ky|R@lY(}cjuqPmSf6f)^^+#D&f6O6!H;3y*9WWA zd04w0jG0jp*0+aYg?j>Yj{ce^Lg(mn!vB|Z782ghrDcW9jAW)@TG}>9$(T6;S`|v* ze+4?1d&v`+jH!>_I!JRz0h9d#5oyGL+2)^vAMYq zH;|UyK8jzneXuN6^kVoBO3##jrC9BC_7;1qz0KZX@3eQ>yX`%Z>4f4#iJ_!Wtx#>; zA9G`Zg%7|4l;d_&ss?MUHZIYM?ME319;g7GJ(-g3v+j2 zB)d0UGqSds73s zS26>&Ii4B{ZEiw6uA`eloBebvYU?m{5UO;tKes=pN9+ss1?uitjzy26&f=(t(5a`~ zCEHJ^)!%95w4wn{rjtnno#D=K%0oSlr9nc!ABv@>8|OQoi$Fxef!MV=VSQ7Z4abJ!Y^v1V#YhzAe+;yCDV%Ag3#Y}N7h?%NZ ziJ9hnD`vWLUd#q+rI;CNg_sR7>r^P+9l+Mu)mJECJ75k@C@7S!E3l8X7uXm3_lo*i ze+CZ32?IsN)?wh2Y9VIXr*N7

!ump=_U%Ldm`W#$)AJp;TW26LE?`p+s$fwQ%}C zp)_rQwQ)K?p(H1P_0%F@igOy6s+I!NoUefC&M9C6wFH=<76ThvZvvY*{{a5nItcs^ z>kx2;>^F8t-t)kF7Gu}(Iq=tW!9}md%KUEJpnCxN3f`xq*oQn#=g@kB*o}-q`$^)u zTpul{CH5unLL2Ic74wJvRzy#OTE(FEdNF$;R^!fr?71;>)f!{+DR-watweX5F|jN0 zl9&muSz|1A6WxtsCb^r%tmVEeX0p3U%-Zf2G3&Tn#Y}Oxi<#=~5Hro)C1$$2Tg(i1 zkC+W{b_4b2&Ik5Fe=+qp2AGSJ6R0P(+SHH>M9x-#M)B?fV1kR9L!J!9lUzgVTCSmN zvTLYZ+g%2%<1PoLxGRCF?kZrKy9Suwpc>V@>NRhS^5;=+bbGr4@4Kpm)dO z{EBH+&4K-J?gaTkIE@{QQd@7>%vzhq8I)4LCWxUI<_!ubLTX^8>@UzIf&Q+01m+pO z#M|a=@HTocdz)~x;1+MIYrC%NxIwp~Tgm+yPMI)%^(ao_yn}lWK2{UJ?~HNAg5N3Q z>&@-kkZvcJUF8N`?OJYi{3^(Q0h)15VT|%FpBmmN;h;!3D8nHIaUZGwJF`=4Y`Qdc adHZ(BTZNev*8X&ls2nqVA4NVRa`gZB#}q{X literal 0 HcmV?d00001 diff --git a/fonts/LibreBaskerville.ttf b/fonts/LibreBaskerville.ttf new file mode 100644 index 0000000000000000000000000000000000000000..eae4eba83203138da3a3a7603b598b7ebc5a5238 GIT binary patch literal 171900 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�f;_0_XTBX!fXN4Pm^7wj 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

t8D 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 T`4{%t0?z_57a7Niy{Ob5cECL` literal 0 HcmV?d00001 diff --git a/fonts/Sacramento-Regular.ttf b/fonts/Sacramento-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cfd2eabc8699f40b4af3fcd82425c2e434377cd4 GIT binary patch literal 79696 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 HgfagCjBv*~ literal 0 HcmV?d00001 diff --git a/fonts/licenses/OFL-caveat.txt b/fonts/licenses/OFL-caveat.txt new file mode 100644 index 0000000..6e5220c --- /dev/null +++ b/fonts/licenses/OFL-caveat.txt @@ -0,0 +1,93 @@ +Copyright 2014 The Caveat Project Authors (https://github.com/googlefonts/caveat) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/licenses/OFL-dancingscript.txt b/fonts/licenses/OFL-dancingscript.txt new file mode 100644 index 0000000..07ff8df --- /dev/null +++ b/fonts/licenses/OFL-dancingscript.txt @@ -0,0 +1,93 @@ +Copyright 2016 The Dancing Script Project Authors (https://github.com/googlefonts/DancingScript), with Reserved Font Name 'Dancing Script'. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/licenses/OFL-greatvibes.txt b/fonts/licenses/OFL-greatvibes.txt new file mode 100644 index 0000000..7002592 --- /dev/null +++ b/fonts/licenses/OFL-greatvibes.txt @@ -0,0 +1,93 @@ +Copyright 2015 The Great Vibes Pro Project Authors (https://github.com/googlefonts/great-vibes) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/fonts/licenses/OFL-lato.txt b/fonts/licenses/OFL-lato.txt new file mode 100644 index 0000000..98383e3 --- /dev/null +++ b/fonts/licenses/OFL-lato.txt @@ -0,0 +1,93 @@ +Copyright (c) 2010-2014 by tyPoland Lukasz Dziedzic (team@latofonts.com) with Reserved Font Name "Lato" + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/licenses/OFL-librebaskerville.txt b/fonts/licenses/OFL-librebaskerville.txt new file mode 100644 index 0000000..92b1e6c --- /dev/null +++ b/fonts/licenses/OFL-librebaskerville.txt @@ -0,0 +1,93 @@ +Copyright 2012 The Libre Baskerville Project Authors (https://github.com/impallari/Libre-Baskerville) with Reserved Font Name Libre Baskerville. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/licenses/OFL-sacramento.txt b/fonts/licenses/OFL-sacramento.txt new file mode 100644 index 0000000..ab66add --- /dev/null +++ b/fonts/licenses/OFL-sacramento.txt @@ -0,0 +1,93 @@ +Copyright (c) 2012, Brian J. Bonislawsky DBA Astigmatic (AOETI) (astigma@astigmatic.com), with Reserved Font Names 'Sacramento' + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/stamps.py b/stamps.py new file mode 100644 index 0000000..022054c --- /dev/null +++ b/stamps.py @@ -0,0 +1,696 @@ +"""Visual signatures ("stamps") for Cachet: model, fonts, rendering, JSON, PDF. + +A visual signature is a text or an image stamped onto one or more pages. It +is NOT a cryptographic signature: in beid/azure mode the stamps are applied +into the same incremental writer BEFORE the document is signed; in image mode +they are the whole job. + +Design notes (deliberate choices): + +- A text is a raster. It is rendered with Pillow into a tightly cropped RGBA + image at 300 dpi (flat colour, anti-aliased alpha mask) and then goes + through exactly the same pipeline as an image (one image XObject painted + at its exact float size, no border). No font is embedded, no shaping + library needed. +- The text layout is pinned to ``ImageFont.Layout.BASIC`` so sizes do not + depend on raqm being installed (identical on every OS and in CI). +- Memory is bounded: a text (or a freehand drawing) is measured first and + refused above ``MAX_TEXT_PIXELS`` before anything is allocated; an image is + downsampled to ``IMAGE_MAX_DPI`` of its target width before it is embedded. +- ``stamp_content`` is THE single source of pixels + size for both the PDF + and the GUI preview, so what is previewed is what gets stamped. +- Every failure raises ``StampError`` (a ``ValueError``): messages are + English, lower-case first word, no trailing period. + +This module must stay importable without tkinter, customtkinter, pypdfium2, +the GUI or the core (``sign_pdfs_beid`` is the CLI entry script: importing it +from here would load it twice). +""" + +from __future__ import annotations + +import dataclasses +import datetime +import json +import math +import os +import re +import sys +import uuid +from pathlib import Path + +from PIL import Image, ImageDraw, ImageFont, ImageOps, UnidentifiedImageError + +from pyhanko.pdf_utils import generic, images +from pyhanko.sign.fields import enumerate_sig_fields + + +class StampError(ValueError): + """Any failure of this module (bad stamp, font, image, JSON, page target).""" + + +KINDS = ("text", "image") +PAGE_ANCHORS = ("first", "last") +DEFAULT_FONT = "great-vibes" +DEFAULT_COLOR = "#1A2B8C" +DEFAULT_FONT_SIZE = 24.0 +DEFAULT_IMAGE_WIDTH_PT = 150.0 +TEXT_DPI = 300 +MAX_FONT_SIZE = 400.0 +MAX_WIDTH_PT = 5000.0 +MAX_TEXT_LEN = 2000 +MAX_TEXT_PIXELS = 40_000_000 # pixel budget of one rendered text (before cropping) +IMAGE_MAX_DPI = 600 # image stamps are downsampled to this, for their width_pt +DATE_FORMAT = "%d/%m/%Y" +BUNDLED_FONTS = { # id -> (display name, file name); dict order = menu order + "great-vibes": ("Great Vibes", "GreatVibes-Regular.ttf"), + "dancing-script": ("Dancing Script", "DancingScript.ttf"), + "caveat": ("Caveat", "Caveat.ttf"), + "sacramento": ("Sacramento", "Sacramento-Regular.ttf"), + "lato": ("Lato", "Lato-Regular.ttf"), + "libre-baskerville": ("Libre Baskerville", "LibreBaskerville.ttf"), +} + +# Image modes pyHanko embeds as they are; anything else is converted to RGBA. +_NATIVE_IMAGE_MODES = ("RGB", "RGBA", "L", "LA") + + +# --------------------------------------------------------------------------- +# Fonts and assets +# --------------------------------------------------------------------------- + +def _expanduser(path: Path) -> Path: + """``~`` expanded; a ``~user`` that does not exist is left as written + (pathlib raises ``RuntimeError`` for it).""" + try: + return path.expanduser() + except RuntimeError: + return path + + +def _is_file(path) -> bool: + """``Path.is_file`` that never raises (over-long names, embedded NULs).""" + try: + return Path(path).is_file() + except (OSError, ValueError): + return False + + +def asset_path(name: str) -> Path: + """Path of a bundled asset: next to this module in a checkout, under + ``sys._MEIPASS`` in the frozen binaries (GUI and CLI alike).""" + return Path(getattr(sys, "_MEIPASS", Path(__file__).resolve().parent)) / name + + +def font_choices() -> list[tuple[str, str]]: + """``[(id, display name), ...]`` of the bundled fonts, in menu order.""" + return [(font_id, name) for font_id, (name, _) in BUNDLED_FONTS.items()] + + +def resolve_font(font: str) -> Path: + """Font file of a bundled id (case-insensitive) or of a user ``.ttf/.otf`` + path. The result is an existing file.""" + font_id = font.strip().lower() + if font_id in BUNDLED_FONTS: + path = asset_path("fonts") / BUNDLED_FONTS[font_id][1] + if not _is_file(path): + raise StampError(f"bundled font file missing: {path}") + return path + path = _expanduser(Path(font)) + if not _is_file(path): + raise StampError( + f"unknown font {font!r} (expected one of {', '.join(BUNDLED_FONTS)}, " + "or the path of a .ttf/.otf file)") + return path + + +# --------------------------------------------------------------------------- +# Text and stroke rendering +# --------------------------------------------------------------------------- + +def _normalise_newlines(text: str) -> str: + return text.replace("\r\n", "\n").replace("\r", "\n") + + +def resolve_text(text: str, *, filename: str = "", date: datetime.date | None = None) -> str: + """Normalise the newlines and replace the two placeholders: ``{date}`` + (dd/mm/YYYY) and ``{filename}``. Plain ``str.replace`` — never + ``str.format`` — so every other brace is left untouched. ``{date}`` goes + first: a file name that itself contains ``{date}`` is not re-expanded.""" + day = (date or datetime.date.today()).strftime(DATE_FORMAT) + return _normalise_newlines(text).replace("{date}", day).replace("{filename}", filename) + + +def _parse_color(color: str) -> tuple[int, int, int]: + m = re.fullmatch(r"#([0-9A-Fa-f]{6})", color) if isinstance(color, str) else None + if m is None: + raise StampError(f"bad color {color!r} (expected #RRGGBB)") + return tuple(int(m.group(1)[i:i + 2], 16) for i in (0, 2, 4)) + + +def _ink_image(mask: Image.Image, rgb: tuple[int, int, int]) -> Image.Image: + """RGBA image whose RGB plane is the flat colour and whose alpha is the + (anti-aliased) ink mask.""" + img = Image.new("RGBA", mask.size, rgb + (0,)) + img.putalpha(mask) + return img + + +def text_layout(text: str, font: str, font_size: float) -> tuple: + """Measure a text WITHOUT rasterising it and enforce the pixel budget. + + Returns ``(font_obj, spacing, (l, t), pad, (w_px, h_px))``. ``text`` must + already be newline-normalised. Shared by ``render_text_image`` and + ``validate_stamp``.""" + px = max(1, round(font_size * TEXT_DPI / 72)) + spacing = round(px * 0.2) + # Measuring is inside the try as well: FreeType opens a damaged font file + # and only fails (OSError) on the first glyph it has to load. + try: + fnt = ImageFont.truetype(str(resolve_font(font)), px, layout_engine=ImageFont.Layout.BASIC) + # A 1x1 probe: measuring allocates nothing proportional to the text. + probe = ImageDraw.Draw(Image.new("L", (1, 1))) + l, t, r, b = probe.multiline_textbbox((0, 0), text, font=fnt, spacing=spacing) + except OSError as exc: + raise StampError(f"cannot load font {font!r}: {exc}") from None + pad = max(2, round(px * 0.25)) + size = (int(r - l) + 2 * pad, int(b - t) + 2 * pad) + if size[0] * size[1] > MAX_TEXT_PIXELS: # BEFORE any allocation + raise StampError("text is too large to render (reduce the font size or the text length)") + return fnt, spacing, (l, t), pad, size + + +def render_text_image(text: str, font: str, font_size: float, color: str) -> Image.Image: + """Render a (multi-line) text into a tightly cropped RGBA image: flat + colour, anti-aliased alpha. Never allocates more than ``MAX_TEXT_PIXELS`` + mask pixels (the uncropped mask is the only large allocation).""" + rgb = _parse_color(color) + text = _normalise_newlines(text) + fnt, spacing, (l, t), pad, size = text_layout(text, font, font_size) + mask = Image.new("L", size, 0) + try: + ImageDraw.Draw(mask).multiline_text( + (pad - l, pad - t), text, font=fnt, fill=255, spacing=spacing) + except OSError as exc: # FreeType failing on a glyph + raise StampError(f"cannot load font {font!r}: {exc}") from None + bbox = mask.getbbox() + if bbox is None: + raise StampError("text is empty") + return _ink_image(mask.crop(bbox), rgb) + + +def render_strokes_image(strokes, color: str, *, width: float = 3.0, scale: int = 4) -> Image.Image: + """Rasterise freehand strokes into a tightly cropped transparent RGBA + image, ``scale`` times the canvas size (supersampling). + + ``strokes``: a list of strokes, each a list of ``(x, y)`` floats in canvas + pixels. Every point also gets a filled disc of diameter ``width``: round + caps, and a one-point stroke draws a dot.""" + rgb = _parse_color(color) + points = [(float(x), float(y)) for stroke in strokes for x, y in stroke] + if not points: + raise StampError("nothing was drawn") + # Origin moved to the strokes' own bounding box (plus the pen width), so + # points dragged outside the canvas (negative coordinates) are kept. + x0 = min(x for x, _ in points) - width + y0 = min(y for _, y in points) - width + w = (max(x for x, _ in points) + width - x0) * scale + h = (max(y for _, y in points) + width - y0) * scale + # Same budget as a text, checked BEFORE the allocation: the mask covers + # the whole bounding box, and a drag can leave the canvas by a screen. + if not w * h <= MAX_TEXT_PIXELS: # (also true for NaN / inf) + raise StampError("drawing is too large") + mask = Image.new("L", (max(1, math.ceil(w)), max(1, math.ceil(h))), 0) + draw = ImageDraw.Draw(mask) + pen = max(1, round(width * scale)) + radius = width * scale / 2 + for stroke in strokes: + scaled = [((float(x) - x0) * scale, (float(y) - y0) * scale) for x, y in stroke] + if len(scaled) > 1: + draw.line(scaled, fill=255, width=pen, joint="curve") + for cx, cy in scaled: + draw.ellipse((cx - radius, cy - radius, cx + radius, cy + radius), fill=255) + return _ink_image(mask.crop(mask.getbbox()), rgb) + + +# --------------------------------------------------------------------------- +# Images +# --------------------------------------------------------------------------- + +def load_image(path) -> Image.Image: + """Load an image, normalised once: EXIF orientation applied, any mode + pyHanko cannot embed (palette, CMYK, 1-bit, …) converted to RGBA. The + file handle is closed on return.""" + try: + with Image.open(path) as im: + im.load() + out = ImageOps.exif_transpose(im) + if out.mode not in _NATIVE_IMAGE_MODES: + return out.convert("RGBA") + return out.copy() + # Deliberately broad: on a damaged file Pillow's decoders raise far more + # than OSError / ValueError / DecompressionBombError — SyntaxError (broken + # PNG chunk, bad EXIF block), NotImplementedError (exotic DDS), + # MemoryError (absurd declared size). All mean "not a usable image". + except Exception as exc: + # The text of these two repeats the path: keep the reason alone. + if isinstance(exc, UnidentifiedImageError): + reason = "not a recognised image file" + else: + reason = getattr(exc, "strerror", None) or exc # OSError: its reason + raise StampError(f"cannot read image {path}: {reason}") from None + + +# --------------------------------------------------------------------------- +# Model +# --------------------------------------------------------------------------- + +def _unknown_kind(kind) -> StampError: + return StampError(f"unknown kind {kind!r} (expected {'|'.join(KINDS)})") + + +def _unknown_anchor(anchor) -> StampError: + return StampError(f"unknown page_anchor {anchor!r} (expected {'|'.join(PAGE_ANCHORS)})") + + +@dataclasses.dataclass(frozen=True) +class Stamp: + """One visual signature: its content and (once placed) where it goes. + + The field order is part of the contract.""" + kind: str = "image" # "text" | "image" + text: str = "" + font: str = DEFAULT_FONT # bundled id or path + color: str = DEFAULT_COLOR # "#RRGGBB" + font_size: float = DEFAULT_FONT_SIZE # pt (text) + image_path: Path | None = None # (image) + width_pt: float = DEFAULT_IMAGE_WIDTH_PT # pt (image) + page: int | None = None # 1-based } exactly one of the three + page_anchor: str | None = None # "first" | "last" } once the stamp is placed + all_pages: bool = False # } + x: float | None = None + y: float | None = None + + def _target_count(self) -> int: + return (self.page is not None) + (self.page_anchor is not None) + bool(self.all_pages) + + @property + def is_placed(self) -> bool: + """A position and exactly one page target.""" + return self.x is not None and self.y is not None and self._target_count() == 1 + + def page_indexes(self, n_pages: int) -> list[int]: + """0-based indexes of the pages this stamp lands on, for a document + of ``n_pages`` pages.""" + if n_pages < 1: + raise StampError("the document has no page") + if self.all_pages: + return list(range(n_pages)) + if self.page_anchor is not None: + if self.page_anchor not in PAGE_ANCHORS: + raise _unknown_anchor(self.page_anchor) + return [0 if self.page_anchor == "first" else n_pages - 1] + if self.page is None: + raise StampError("the signature has no page target") + if not 1 <= self.page <= n_pages: + raise StampError( + f"page {self.page} out of range (the document has {n_pages} page(s))") + return [self.page - 1] + + def target_label(self) -> str: + if self.all_pages: + return "all pages" + if self.page_anchor is not None: + return f"{self.page_anchor} page" + if self.page is not None: + return f"page {self.page}" + return "unplaced" + + def describe(self) -> str: + """One-line summary, e.g. ``text last page @ (360, 120)``.""" + if self.x is None or self.y is None: + return f"{self.kind} unplaced" + return f"{self.kind} {self.target_label()} @ ({self.x:.0f}, {self.y:.0f})" + + def content_label(self) -> str: + """Short label of the content: the first non-empty line of a text (in + double quotes, truncated to 30 characters), or the image file name.""" + if self.kind == "text": + first = next((ln.strip() for ln in self.text.splitlines() if ln.strip()), "") + if len(first) > 30: + first = first[:30] + "…" + return f'"{first}"' + return Path(self.image_path).name if self.image_path else "?" + + def to_dict(self, *, base_dir=None) -> dict: + """JSON form (the ``--signatures`` schema). Only the keys of the kind + and the placement keys that are set are emitted. An image that is a + DIRECT child of ``base_dir`` is written as its bare file name, any + other one as an absolute path.""" + out: dict = {"kind": self.kind} + if self.kind == "text": + out.update(text=self.text, font=self.font, color=self.color, + font_size=self.font_size) + else: + if self.image_path is not None: + out["image_path"] = self._image_path_for(base_dir) + out["width_pt"] = self.width_pt + if self.page is not None: + out["page"] = self.page + if self.page_anchor is not None: + out["page_anchor"] = self.page_anchor + if self.all_pages: + out["all_pages"] = True + if self.x is not None: + out["x"] = self.x + if self.y is not None: + out["y"] = self.y + return out + + def _image_path_for(self, base_dir) -> str: + if base_dir is not None: + # RESOLVED paths only: pathlib's relative_to/is_relative_to are + # lexical, so base_dir/../../x would count as "inside" base_dir. + # ValueError: a NUL or a lone surrogate in the path (hand-edited + # profile) — such a file is nowhere, so it is not in base_dir. + try: + resolved = Path(self.image_path).resolve() + if resolved.parent == Path(base_dir).resolve(): + return resolved.name + except (OSError, RuntimeError, ValueError): + pass + return os.path.abspath(self.image_path) + + @classmethod + def from_dict(cls, data, *, base_dir=None) -> "Stamp": + """Type-check and build a stamp from its JSON form. Does NOT call + ``validate_stamp``. Unknown keys are ignored, missing keys take the + defaults. A relative ``image_path`` (or font path) is joined to + ``base_dir`` as written — the result may point outside ``base_dir`` + and nothing here treats it as owned by that directory.""" + if not isinstance(data, dict): + raise StampError("expected an object") + if "kind" not in data: + raise StampError("missing 'kind'") + + def string(key): + value = data[key] + if not isinstance(value, str): + raise StampError(f"'{key}' must be a string") + return value + + def number(key): + value = data[key] + if isinstance(value, bool) or not isinstance(value, (int, float)): + raise StampError(f"'{key}' must be a number") + try: + return float(value) + except OverflowError: # an integer too large for a float + raise StampError(f"'{key}' must be a number") from None + + def under_base(path: Path) -> Path: + path = _expanduser(path) + if base_dir is not None and not path.is_absolute(): + return Path(base_dir) / path + return path + + fields: dict = {"kind": string("kind")} + for key in ("text", "color", "page_anchor"): + if key in data: + fields[key] = string(key) + if "font" in data: + font = string("font") + # A bundled id stays an id; so does any font when there is no + # base_dir (resolve_font expands and checks the path later). A + # bare word that is no file there stays as typed too: it is a + # mistyped id, to be reported as such, not as a path. + if (base_dir is not None and font.strip() + and font.strip().lower() not in BUNDLED_FONTS): + joined = under_base(Path(font)) + bare_word = Path(font).name == font and not Path(font).suffix + if not bare_word or _is_file(joined): + font = str(joined) + fields["font"] = font + if "image_path" in data: + fields["image_path"] = under_base(Path(string("image_path"))) + for key in ("font_size", "width_pt", "x", "y"): + if key in data: + fields[key] = number(key) + if "page" in data: + page = data["page"] + if isinstance(page, bool) or not isinstance(page, int): + raise StampError("'page' must be an integer") + fields["page"] = page + if "all_pages" in data: + if not isinstance(data["all_pages"], bool): + raise StampError("'all_pages' must be true or false") + fields["all_pages"] = data["all_pages"] + return cls(**fields) + + +# --------------------------------------------------------------------------- +# Validation +# --------------------------------------------------------------------------- + +def _in_range(value, maximum: float) -> bool: + return math.isfinite(value) and 0 < value <= maximum + + +def _validate_content(stamp: Stamp) -> None: + if stamp.kind not in KINDS: + raise _unknown_kind(stamp.kind) + if stamp.kind == "text": + if not stamp.text.strip(): + raise StampError("text is empty") + if len(stamp.text) > MAX_TEXT_LEN: + raise StampError(f"text is too long (max {MAX_TEXT_LEN} characters)") + _parse_color(stamp.color) + if not _in_range(stamp.font_size, MAX_FONT_SIZE): + raise StampError( + f"font_size must be greater than 0 and at most {MAX_FONT_SIZE:g}") + # Probe only (font + pixel budget): nothing is rasterised here. + text_layout(_normalise_newlines(stamp.text), stamp.font, stamp.font_size) + else: + if stamp.image_path is None: + raise StampError("image_path is required") + if not _is_file(stamp.image_path): + raise StampError(f"image not found: {stamp.image_path}") + if not _in_range(stamp.width_pt, MAX_WIDTH_PT): + raise StampError( + f"width_pt must be greater than 0 and at most {MAX_WIDTH_PT:g}") + + +def validate_placement(stamp: Stamp) -> None: + """Placement rules alone (page target + position), whatever the content. + + Lets a caller judge a saved placement even when the content is + temporarily unusable (image or font file missing).""" + if stamp._target_count() != 1: + raise StampError("give exactly one page target: page, page_anchor or all_pages") + if stamp.page is not None and stamp.page < 1: + raise StampError("page must be an integer >= 1") + if stamp.page_anchor is not None and stamp.page_anchor not in PAGE_ANCHORS: + raise _unknown_anchor(stamp.page_anchor) + if stamp.x is None or stamp.y is None: + raise StampError("x and y are required") + if not (math.isfinite(stamp.x) and math.isfinite(stamp.y)): + raise StampError("x and y must be finite numbers") + + +def validate_stamp(stamp: Stamp, *, placed: bool = True) -> None: + """Raise ``StampError`` on the first broken rule: content first (kind, + text/colour/size/font/pixel budget or image/width), then — unless + ``placed=False`` (a library entry not placed yet) — the placement.""" + _validate_content(stamp) + if placed: + validate_placement(stamp) + + +# --------------------------------------------------------------------------- +# Content (pixels + size) and JSON file +# --------------------------------------------------------------------------- + +def content_key(stamp: Stamp, *, filename: str = "", date: datetime.date | None = None) -> tuple: + """Hashable identity of a stamp's rendered content (placement excluded).""" + if stamp.kind == "text": + return ("text", resolve_text(stamp.text, filename=filename, date=date), + stamp.font, float(stamp.font_size), stamp.color.upper()) + return ("image", str(stamp.image_path), float(stamp.width_pt)) + + +def stamp_content(stamp: Stamp, *, filename: str = "", date: datetime.date | None = None, + cache: dict | None = None) -> tuple[Image.Image, tuple[float, float]]: + """Pixels and size in points of a stamp — THE single source for both the + PDF and the GUI preview. + + ``cache`` (a plain dict owned by the caller) is read and written under + ``content_key(...)``, except that a text using ``{filename}`` is never + written to it: one entry per document would grow without bound over a + batch.""" + if stamp.kind not in KINDS: + raise _unknown_kind(stamp.kind) + if stamp.kind == "image" and stamp.image_path is None: + raise StampError("image_path is required") + key = content_key(stamp, filename=filename, date=date) + if cache is not None and key in cache: + return cache[key] + if stamp.kind == "text": + img = render_text_image(key[1], stamp.font, stamp.font_size, stamp.color) + size = (img.width * 72 / TEXT_DPI, img.height * 72 / TEXT_DPI) + cacheable = "{filename}" not in stamp.text + else: + img = load_image(stamp.image_path) + # Size from the aspect of the full-resolution image, then cap the + # embedded bitmap: a 12 MP photo stamped 150 pt wide is 1250 px. + size = (float(stamp.width_pt), stamp.width_pt * img.height / img.width) + max_w = max(1, math.ceil(stamp.width_pt * IMAGE_MAX_DPI / 72)) + if img.width > max_w: + img = img.resize( + (max_w, max(1, round(img.height * max_w / img.width))), Image.LANCZOS) + cacheable = True + if cache is not None and cacheable: + cache[key] = (img, size) + return img, size + + +def load_stamps_file(path) -> list[Stamp]: + """Read a ``--signatures`` file: a UTF-8 JSON list of visual signatures + (same schema as the profile's entries). Entries with ``"enabled": false`` + are skipped; every other one is validated (placement included).""" + # Encoding pinned (never the platform default); utf-8-sig also swallows + # the BOM that PowerShell 5 writes. + try: + raw = Path(path).read_text(encoding="utf-8-sig") + except UnicodeDecodeError: # a ValueError, not an OSError + raise StampError(f"{path}: not valid UTF-8") from None + except OSError as exc: + raise StampError(f"cannot read signatures file {path}: {exc}") from None + try: + data = json.loads(raw) + except (ValueError, RecursionError) as exc: # deep nesting -> RecursionError + raise StampError(f"invalid JSON in {path}: {exc}") from None + if not isinstance(data, list): + raise StampError(f"{path}: expected a JSON list of signatures") + name = Path(path).name + base_dir = Path(path).resolve().parent + stamp_list: list[Stamp] = [] + for i, entry in enumerate(data, 1): + try: + if isinstance(entry, dict) and "enabled" in entry: + if not isinstance(entry["enabled"], bool): + raise StampError("'enabled' must be true or false") + if not entry["enabled"]: + continue + stamp = Stamp.from_dict(entry, base_dir=base_dir) + validate_stamp(stamp) + except StampError as exc: + raise StampError(f"{name}: signature #{i}: {exc}") from None + stamp_list.append(stamp) + return stamp_list + + +# --------------------------------------------------------------------------- +# PDF +# --------------------------------------------------------------------------- + +def page_count(writer) -> int: + """Number of pages of the document behind ``writer`` (does not dirty it).""" + return int(writer.root["/Pages"]["/Count"]) + + +def page_mediabox(writer, page_index: int) -> list[float]: + """MediaBox of page `page_index` (0-based, -1 = last), with inheritance + from the page tree.""" + page_ref, _ = writer.find_page_for_modification(page_index) + node = page_ref.get_object() + for _ in range(50): + if "/MediaBox" in node: + mb = node.raw_get("/MediaBox").get_object() + return [ + float(v.get_object() if hasattr(v, "get_object") else v) for v in mb + ] + parent = node.get("/Parent") + if parent is None: + break + node = parent.get_object() + return [0.0, 0.0, 595.276, 841.89] + + +def _pdf_number(value: float) -> bytes: + """A number for a content stream: fixed notation (``%g`` may emit an + exponent, which PDF does not allow), without trailing zeros.""" + return (b"%.4f" % value).rstrip(b"0").rstrip(b".") + + +def existing_signature_count(writer) -> int: + """Signatures and document timestamps the INPUT already carries + (0 = unsigned). Reads the previous revision only: it neither parses the + CMS nor dirties the writer.""" + return sum(1 for _ in enumerate_sig_fields(writer.prev, filled_status=True)) + + +def apply_stamps(writer, stamp_list, *, filename: str = "", + date: datetime.date | None = None, cache: dict | None = None) -> None: + """Stamp every element of ``stamp_list`` into ``writer`` (and nothing + else: the caller writes or signs it). + + Two passes: pages and content are resolved for ALL stamps before the + first write, so a bad stamp never leaves a half-stamped writer for the + caller to sign. A low-level primitive: it stamps whatever it is given, + including an already signed document (see ``existing_signature_count``).""" + day = date or datetime.date.today() + n = page_count(writer) + resolved = [] + for stamp in stamp_list: + if not stamp.is_placed: + raise StampError("the signature is not placed") + pages = stamp.page_indexes(n) # range errors BEFORE touching the writer + img, size = stamp_content(stamp, filename=filename, date=day, cache=cache) + resolved.append((stamp, pages, img, size)) + + def add_content(page_index: int, data: bytes, **kwargs) -> None: + writer.add_stream_to_page( + page_index, writer.add_object(generic.StreamObject(stream_data=data)), **kwargs) + + owned: set[int] = set() # pages whose /Contents is theirs alone + for stamp, pages, img, (w, h) in resolved: + # ONE image XObject per stamp, painted on N pages (alpha -> /SMask by + # pyHanko). The image is painted directly, not through a pyHanko + # stamp: an image fills the unit square, so the matrix carries the + # exact float size, whereas a stamp box is truncated to whole points + # (and cannot be under 1 pt). + image_ref = images.pil_image(img, writer) + for p in pages: + page_ref, _ = writer.find_page_for_modification(p) + page_obj = page_ref.get_object() + if "/Contents" not in page_obj: # blank page: /Contents is optional + page_obj["/Contents"] = writer.add_object(generic.StreamObject(stream_data=b"")) + elif p not in owned: + contents = page_obj.raw_get("/Contents") + if (isinstance(contents, generic.IndirectObject) + and isinstance(contents.get_object(), generic.ArrayObject)): + # pyHanko appends to an indirect array in place, and + # another page may point at the same one: give this page + # its own copy, or the stamp would land on that page too. + page_obj["/Contents"] = generic.ArrayObject(contents.get_object()) + owned.add(p) + # Always: a /Contents or /Resources that pyHanko sets on the page + # is not written unless the page itself is marked (the stamp + # would be invisible). + writer.mark_update(page_ref) + mb = page_mediabox(writer, p) # per-page origin + # A fresh name per page: several pages may share one /Resources. + name = "/Stamp" + uuid.uuid4().hex + # The existing content is wrapped in q/Q so that a transformation + # it leaves behind cannot move or scale the stamp. + add_content(p, b"q", prepend=True) + add_content(p, b"Q") + add_content( + p, + b"q %s 0 0 %s %s %s cm %s Do Q" % ( + _pdf_number(w), _pdf_number(h), + _pdf_number(mb[0] + stamp.x), _pdf_number(mb[1] + stamp.y), + name.encode("ascii")), + resources=generic.DictionaryObject({ + generic.pdf_name("/XObject"): generic.DictionaryObject( + {generic.pdf_name(name): image_ref})})) diff --git a/test_stamps.py b/test_stamps.py new file mode 100644 index 0000000..46a6e7a --- /dev/null +++ b/test_stamps.py @@ -0,0 +1,1218 @@ +#!/usr/bin/env python3 +"""Headless tests for stamps.py (visual signatures: text, images, strokes). + +No card, no network, no display. Text sizes are never asserted pixel-exact +(font hinting differs between FreeType builds): ratios, bounding boxes and +colours only. +Run with: ./venv/bin/python -m unittest -v test_stamps +""" + +import dataclasses +import datetime +import gc +import io +import json +import re +import shutil +import struct +import subprocess +import sys +import unittest +import warnings +from pathlib import Path +from unittest import mock + +from PIL import Image, ImageFont + +from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter +from pyhanko.pdf_utils.reader import PdfFileReader +from pyhanko.sign.fields import SigFieldSpec, append_signature_field, enumerate_sig_fields + +import sign_pdfs_beid as core +import stamps +from stamps import Stamp, StampError +from test_sign_pdfs_beid import TmpCase, make_pdf, make_png, pdf_stream, write_pdf_objects + +DAY = datetime.date(2026, 10, 7) +INK = (26, 43, 140) # stamps.DEFAULT_COLOR + + +def strip_page_contents(pdf_path, page_index) -> Path: + """Writes a sibling of `pdf_path` whose page `page_index` (0-based) has no + /Contents entry — the "blank page" some producers emit (/Contents is + optional in PDF). Returns the new path.""" + src = Path(pdf_path) + with src.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + page_ref, _ = writer.find_page_for_modification(page_index) + del page_ref.get_object()["/Contents"] + writer.mark_update(page_ref) + out = io.BytesIO() + writer.write(out) + dst = src.with_name(f"{src.stem}_nocontents.pdf") + dst.write_bytes(out.getvalue()) + return dst + + +def damaged_font(path) -> Path: + """Writes a copy of a bundled font whose `glyf` table is overwritten with + 0xFF: FreeType (2.13) still OPENS it, then fails on the first glyph it has + to load (every glyph is an invalid composite). Returns the path.""" + data = bytearray(stamps.resolve_font("lato").read_bytes()) + for i in range(struct.unpack(">H", data[4:6])[0]): # table directory + tag, _, offset, length = struct.unpack(">4sIII", data[12 + 16 * i:28 + 16 * i]) + if tag == b"glyf": + data[offset:offset + length] = b"\xff" * length + Path(path).write_bytes(bytes(data)) + return Path(path) + + +def damaged_png(path) -> Path: + """Writes a PNG whose IDAT chunk declares a length of 0: Pillow identifies + it, then raises a SyntaxError (not an OSError) while decoding.""" + data = bytearray(make_png(path).read_bytes()) + pos = data.index(b"IDAT") + data[pos - 4:pos] = struct.pack(">I", 0) + Path(path).write_bytes(bytes(data)) + return Path(path) + + +def pdf_pages(pdf_path) -> list: + """Page dictionaries of a (flat page tree) PDF made by make_pdf.""" + reader = PdfFileReader(io.BytesIO(Path(pdf_path).read_bytes()), strict=False) + return [kid.get_object() for kid in reader.root["/Pages"]["/Kids"]] + + +def page_xobjects(page) -> dict: + """{resource name: object id} of the XObjects of a page dictionary.""" + # [] dereferences indirect objects; dict.get() would hand back the reference + if "/Resources" not in page or "/XObject" not in page["/Resources"]: + return {} + xobjects = page["/Resources"]["/XObject"] + return {name: xobjects.raw_get(name).idnum for name in xobjects} + + +def near(pixel, rgb, tol=40) -> bool: + return all(abs(a - b) <= tol for a, b in zip(pixel[:3], rgb)) + + +class StampCase(TmpCase): + """TmpCase + cleanup + a helper that stamps a PDF and returns the output.""" + + def setUp(self): + super().setUp() + self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True) + + def stamped(self, pdf, stamp_list, **kwargs) -> Path: + pdf = Path(pdf) + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + stamps.apply_stamps(writer, stamp_list, **kwargs) + out = io.BytesIO() + writer.write(out) + dst = pdf.with_name(f"{pdf.stem}_out.pdf") + dst.write_bytes(out.getvalue()) + return dst + + +class FontRegistry(StampCase): + def test_six_bundled_fonts_resolve_and_load(self): + self.assertEqual(len(stamps.BUNDLED_FONTS), 6) + self.assertEqual([fid for fid, _ in stamps.font_choices()], list(stamps.BUNDLED_FONTS)) + self.assertIn(stamps.DEFAULT_FONT, stamps.BUNDLED_FONTS) + for font_id, name in stamps.font_choices(): + with self.subTest(font=font_id): + path = stamps.resolve_font(font_id) + self.assertTrue(path.is_file(), path) + self.assertTrue(name) + ImageFont.truetype(str(path), 40) # raises if not a font + img = stamps.render_text_image("Jane Doe", font_id, 24, "#000000") + self.assertGreater(img.width, img.height) + + def test_ids_are_case_insensitive(self): + self.assertEqual(stamps.resolve_font(" Great-Vibes "), stamps.resolve_font("great-vibes")) + self.assertEqual(stamps.resolve_font("LATO"), stamps.resolve_font("lato")) + + def test_unknown_font_raises(self): + with self.assertRaises(StampError) as cm: + stamps.resolve_font("comic-sans") + msg = str(cm.exception) + self.assertTrue(msg.startswith("unknown font 'comic-sans'"), msg) + for font_id in stamps.BUNDLED_FONTS: + self.assertIn(font_id, msg) + with self.assertRaises(StampError): + stamps.resolve_font(str(self.p("missing.ttf"))) + with self.assertRaises(StampError): + stamps.resolve_font("") + + def test_user_font_path_accepted(self): + mine = self.p("mine.ttf") + shutil.copy(stamps.resolve_font("lato"), mine) + self.assertEqual(stamps.resolve_font(str(mine)), mine) + user = stamps.render_text_image("Jane", str(mine), 24, "#000000") + bundled = stamps.render_text_image("Jane", "lato", 24, "#000000") + self.assertEqual(user.size, bundled.size) + + def test_asset_path_honours_meipass(self): + here = Path(stamps.__file__).resolve().parent + self.assertEqual(stamps.asset_path("fonts"), here / "fonts") + with mock.patch.object(sys, "_MEIPASS", str(self.tmp), create=True): + self.assertEqual(stamps.asset_path("fonts"), self.tmp / "fonts") + # the frozen layout is what resolve_font looks at + with self.assertRaises(StampError) as cm: + stamps.resolve_font("lato") + self.assertTrue(str(cm.exception).startswith("bundled font file missing: ")) + (self.tmp / "fonts").mkdir() + shutil.copy(here / "fonts" / "Lato-Regular.ttf", self.tmp / "fonts") + self.assertEqual(stamps.resolve_font("lato"), + self.tmp / "fonts" / "Lato-Regular.ttf") + + def test_licences_ship_with_fonts(self): + licences = stamps.asset_path("fonts") / "licenses" + self.assertEqual(len(list(licences.glob("OFL-*.txt"))), len(stamps.BUNDLED_FONTS)) + for font_id in stamps.BUNDLED_FONTS: + lic = licences / f"OFL-{font_id.replace('-', '')}.txt" + self.assertTrue(lic.is_file(), lic) + self.assertIn("SIL OPEN FONT LICENSE", lic.read_text(encoding="utf-8").upper()) + + +class TextRendering(StampCase): + def render(self, text="Jane Doe", font="great-vibes", size=24, color="#1A2B8C", **kw): + return stamps.render_text_image(text, font, size, color, **kw) + + def test_rgba_tight_crop_flat_colour(self): + img = self.render() + self.assertEqual(img.mode, "RGBA") + # tight on the four sides: the ink reaches every edge + self.assertEqual(img.getchannel("A").getbbox(), (0, 0) + img.size) + # the RGB plane is the flat colour, transparent pixels included + self.assertEqual(img.convert("RGB").getcolors(), [(img.width * img.height, INK)]) + + def test_alpha_is_antialiased(self): + levels = sum(1 for count in self.render().getchannel("A").histogram() if count) + self.assertGreater(levels, 16) + + def test_size_scales_with_font_size(self): + small, big = self.render(size=24), self.render(size=48) + self.assertAlmostEqual(big.height / small.height, 2.0, delta=0.16) + self.assertAlmostEqual(big.width / small.width, 2.0, delta=0.16) + + def test_multiline_is_taller(self): + one, two = self.render("Jane Doe"), self.render("Jane Doe\nJane Doe") + self.assertGreater(two.height, one.height * 1.6) + self.assertAlmostEqual(two.width, one.width, delta=one.width * 0.05) + + def test_blank_text_raises(self): + for text in ("", " ", "\n"): + with self.subTest(text=text): + with self.assertRaises(StampError) as cm: + self.render(text) + self.assertEqual(str(cm.exception), "text is empty") + + def test_bad_colour_raises(self): + for color in ("blue", "#12345", "#GGGGGG", "1A2B8C", "#1A2B8CFF", "", None): + with self.subTest(color=color): + with self.assertRaises(StampError) as cm: + self.render(color=color) + self.assertEqual(str(cm.exception), f"bad color {color!r} (expected #RRGGBB)") + self.assertEqual(self.render(color="#ff0000").convert("RGB").getpixel((0, 0)), + (255, 0, 0)) + + def test_deterministic(self): + a, b = self.render("Jane Doe\n07/10/2026"), self.render("Jane Doe\n07/10/2026") + self.assertEqual(a.size, b.size) + self.assertEqual(a.tobytes(), b.tobytes()) + + def test_dpi_sets_point_size(self): + stamp = Stamp(kind="text", text="Jane Doe", font_size=24) + img, (w_pt, h_pt) = stamps.stamp_content(stamp) + self.assertEqual((w_pt, h_pt), (img.width * 72 / 300, img.height * 72 / 300)) + # a 24 pt text is a few tens of points high, whatever the raster size + self.assertTrue(12 < h_pt < 60, h_pt) + + def test_oversized_text_raises_stamp_error(self): + real_new = Image.new + for text in ("W" * 2000, "a" * 300): + with self.subTest(chars=len(text)): + with mock.patch.object(stamps.Image, "new", side_effect=real_new) as spy: + with self.assertRaises(StampError) as cm: + stamps.render_text_image(text, "lato", 400, "#000000") + self.assertIn("too large", str(cm.exception)) + # refused BEFORE any allocation: only the 1x1 probe was requested + sizes = [tuple(call.args[1]) for call in spy.call_args_list] + self.assertEqual(sizes, [(1, 1)]) + + def test_budget_boundary_typical_sizes_pass(self): + self.assertGreater(self.render("Jane Doe", size=400).height, 1000) + three = self.render("Jane Doe\nRead and approved\n07/10/2026", size=72) + self.assertGreater(three.height, 600) + + def test_validate_stamp_refuses_oversized_text(self): + for placed in (True, False): + with self.subTest(placed=placed): + stamp = Stamp(kind="text", text="W" * 2000, font="lato", font_size=400, + page=1, x=0.0, y=0.0) + real_new = Image.new + with mock.patch.object(stamps.Image, "new", side_effect=real_new) as spy: + with self.assertRaises(StampError) as cm: + stamps.validate_stamp(stamp, placed=placed) + self.assertIn("too large", str(cm.exception)) + self.assertEqual([tuple(c.args[1]) for c in spy.call_args_list], [(1, 1)]) + + def test_validation_never_rasterises(self): + stamp = Stamp(kind="text", text="Jane Doe", page=1, x=0.0, y=0.0) + real_new = Image.new + with mock.patch.object(stamps.Image, "new", side_effect=real_new) as spy: + stamps.validate_stamp(stamp) + self.assertEqual([tuple(c.args[1]) for c in spy.call_args_list], [(1, 1)]) + + def test_damaged_font_raises_stamp_error(self): + # A font file FreeType opens but cannot use fails while MEASURING, with + # an OSError: it must surface as the "cannot load font" StampError + # (validate_stamp runs on every profile load, which never raises). + font = damaged_font(self.p("damaged.ttf")) + message = f"cannot load font {str(font)!r}: " + stamp = Stamp(kind="text", text="Jane Doe", font=str(font), page=1, x=0.0, y=0.0) + for placed in (True, False): + with self.assertRaises(StampError) as cm: + stamps.validate_stamp(stamp, placed=placed) + self.assertTrue(str(cm.exception).startswith(message), str(cm.exception)) + with self.assertRaises(StampError) as cm: + stamps.stamp_content(stamp) + self.assertTrue(str(cm.exception).startswith(message), str(cm.exception)) + # same contract when FreeType only fails while DRAWING + with mock.patch.object(stamps.ImageDraw.ImageDraw, "multiline_text", + side_effect=OSError("raster overflow")): + with self.assertRaises(StampError) as cm: + self.render(font="lato") + self.assertEqual(str(cm.exception), "cannot load font 'lato': raster overflow") + + +class Placeholders(unittest.TestCase): + def test_date_and_filename_replaced(self): + out = stamps.resolve_text("Signed {date} on {filename}", filename="contract", date=DAY) + self.assertEqual(out, "Signed 07/10/2026 on contract") + today = datetime.date.today().strftime("%d/%m/%Y") + self.assertEqual(stamps.resolve_text("{date}"), today) + + def test_other_braces_untouched(self): + self.assertEqual(stamps.resolve_text("{x} {} {{date}}", date=DAY), "{x} {} {07/10/2026}") + self.assertEqual(stamps.resolve_text("{0} {Date} {file name}", date=DAY), + "{0} {Date} {file name}") + + def test_filename_containing_placeholder_not_reexpanded(self): + out = stamps.resolve_text("{filename} / {date}", filename="{date}_{filename}", date=DAY) + self.assertEqual(out, "{date}_{filename} / 07/10/2026") + + def test_newlines_normalised(self): + self.assertEqual(stamps.resolve_text("a\r\nb\rc\nd", date=DAY), "a\nb\nc\nd") + + +class ImageLoading(StampCase): + def test_palette_transparency_preserved(self): + path = self.p("pal.png") + im = Image.new("P", (4, 4), 0) + im.putpalette([255, 0, 0, 0, 255, 0] + [0] * 762) + im.putpixel((1, 1), 1) + im.save(path, transparency=0) + with Image.open(path) as check: + self.assertEqual(check.mode, "P") + out = stamps.load_image(path) + self.assertEqual(out.mode, "RGBA") + self.assertEqual(out.getpixel((0, 0))[3], 0) + self.assertEqual(out.getpixel((1, 1)), (0, 255, 0, 255)) + + def test_cmyk_and_bilevel_converted(self): + cmyk = self.p("cmyk.jpg") + Image.new("CMYK", (30, 20), (0, 255, 255, 0)).save(cmyk) + bilevel = self.p("bw.png") + Image.new("1", (30, 20), 1).save(bilevel) + for path in (cmyk, bilevel): + with self.subTest(path=path.name): + out = stamps.load_image(path) + self.assertEqual(out.mode, "RGBA") + self.assertEqual(out.size, (30, 20)) + # and it really goes into a PDF (was a bare NotImplementedError) + pdf = make_pdf(self.p(f"{path.stem}.pdf"), [(595, 842)]) + out_pdf = self.stamped(pdf, [Stamp(kind="image", image_path=path, + page=1, x=10.0, y=10.0)]) + self.assertEqual(len(page_xobjects(pdf_pages(out_pdf)[0])), 1) + + def test_rgb_kept(self): + for mode, name in (("RGB", "a.jpg"), ("RGBA", "a.png"), ("L", "l.png"), ("LA", "la.png")): + with self.subTest(mode=mode): + path = self.p(name) + Image.new(mode, (30, 20)).save(path) + self.assertEqual(stamps.load_image(path).mode, mode) + + def test_exif_orientation_applied(self): + path = self.p("rot.jpg") + exif = Image.Exif() + exif[0x0112] = 6 # rotate 90° clockwise to display + Image.new("RGB", (40, 20), (200, 0, 0)).save(path, exif=exif) + with Image.open(path) as raw: + self.assertEqual(raw.size, (40, 20)) + self.assertEqual(stamps.load_image(path).size, (20, 40)) + # the stamp's size follows the NORMALISED image + _, size = stamps.stamp_content(Stamp(kind="image", image_path=path, width_pt=100)) + self.assertEqual(size, (100.0, 200.0)) + + def test_unreadable_raises_stamp_error(self): + text = self.p("not_an_image.png") + text.write_text("hello", encoding="utf-8") + truncated = self.p("truncated.png") + truncated.write_bytes(make_png(self.p("ok.png")).read_bytes()[:40]) + broken = damaged_png(self.p("broken_chunk.png")) # a SyntaxError inside Pillow + for path in (text, truncated, broken, self.p("missing.png"), self.tmp): + with self.subTest(path=path.name): + with self.assertRaises(StampError) as cm: + stamps.load_image(path) + self.assertTrue(str(cm.exception).startswith(f"cannot read image {path}: ")) + self.assertEqual(str(cm.exception).count(str(path)), 1) # not repeated + # Pillow's decoders raise more than OSError/ValueError on damaged files + ok = make_png(self.p("ok.png")) + for exc in (SyntaxError("bad EXIF"), NotImplementedError("pixel format"), MemoryError()): + with self.subTest(exc=type(exc).__name__): + with mock.patch.object(stamps.ImageOps, "exif_transpose", side_effect=exc): + with self.assertRaises(StampError) as cm: + stamps.load_image(ok) + self.assertTrue(str(cm.exception).startswith(f"cannot read image {ok}: ")) + + def test_file_handle_closed(self): + path = make_png(self.p("sig.png")) + with warnings.catch_warnings(): + warnings.simplefilter("error", ResourceWarning) + img = stamps.load_image(path) + gc.collect() + moved = self.p("moved.png") + path.rename(moved) # fails on Windows if still open + moved.unlink() + self.assertEqual(img.getpixel((0, 0)), (255, 0, 0, 128)) # pixels are in memory + + def test_large_image_downsampled_to_600_dpi(self): + path = make_png(self.p("big.png"), size=(3000, 1200)) + img, size = stamps.stamp_content(Stamp(kind="image", image_path=path, width_pt=150)) + self.assertEqual(img.size, (1250, 500)) + self.assertEqual(size, (150.0, 60.0)) + self.assertEqual(img.mode, "RGBA") + + def test_small_image_not_resampled(self): + path = make_png(self.p("small.png"), size=(300, 120)) + img, size = stamps.stamp_content(Stamp(kind="image", image_path=path, width_pt=150)) + self.assertEqual(img.size, (300, 120)) + self.assertEqual(size, (150.0, 60.0)) + + def test_missing_image_path_raises(self): + with self.assertRaises(StampError) as cm: + stamps.stamp_content(Stamp(kind="image")) + self.assertEqual(str(cm.exception), "image_path is required") + + +class StampModel(StampCase): + def test_roundtrip_text(self): + stamp = Stamp(kind="text", text="Jane Doe\nRead and approved, {date}", font="caveat", + color="#AA0000", font_size=18.0, page_anchor="last", x=360.0, y=120.5) + data = json.loads(json.dumps(stamp.to_dict())) + self.assertEqual(data, { + "kind": "text", "text": "Jane Doe\nRead and approved, {date}", "font": "caveat", + "color": "#AA0000", "font_size": 18.0, "page_anchor": "last", "x": 360.0, "y": 120.5}) + self.assertEqual(Stamp.from_dict(data), stamp) + # unplaced: no placement key at all; "every page" is the only flag kept + self.assertEqual(set(Stamp(kind="text", text="x").to_dict()), + {"kind", "text", "font", "color", "font_size"}) + paraphe = Stamp(kind="text", text="JD", all_pages=True) + self.assertIs(paraphe.to_dict()["all_pages"], True) + self.assertEqual(Stamp.from_dict(paraphe.to_dict()), paraphe) + + def test_roundtrip_image_relative_to_base_dir(self): + base = self.p("store") + base.mkdir() + png = make_png(base / "sig.png") + stamp = Stamp(kind="image", image_path=png, width_pt=120.0, page=2, x=60.0, y=700.0) + data = stamp.to_dict(base_dir=base) + self.assertEqual(data, {"kind": "image", "image_path": "sig.png", "width_pt": 120.0, + "page": 2, "x": 60.0, "y": 700.0}) + self.assertEqual(Stamp.from_dict(json.loads(json.dumps(data)), base_dir=base), stamp) + + def test_image_outside_base_dir_is_absolute(self): + base = self.p("store") + (base / "sub").mkdir(parents=True) + outside = make_png(self.p("elsewhere.png")) + nested = make_png(base / "sub" / "deep.png") + for png in (outside, nested): # only a DIRECT child is relative + data = Stamp(kind="image", image_path=png).to_dict(base_dir=base) + self.assertEqual(data["image_path"], str(png)) + self.assertEqual(Stamp(kind="image", image_path=outside).to_dict()["image_path"], + str(outside)) + # an absolute path is taken as it is, whatever the base dir + loaded = Stamp.from_dict({"kind": "image", "image_path": str(outside)}, base_dir=base) + self.assertEqual(loaded.image_path, outside) + + def test_traversal_path_is_not_relative(self): + base = self.p("store") + base.mkdir() + make_png(self.p("x.png")) + data = Stamp(kind="image", image_path=base / ".." / "x.png").to_dict(base_dir=base) + self.assertTrue(Path(data["image_path"]).is_absolute(), data) + self.assertEqual(Path(data["image_path"]), self.p("x.png")) + # and the other way round: a relative entry is joined as written + loaded = Stamp.from_dict({"kind": "image", "image_path": "../x.png"}, base_dir=base) + self.assertEqual(loaded.image_path, base / ".." / "x.png") + + def test_unknown_keys_ignored(self): + stamp = Stamp.from_dict({"kind": "text", "text": "x", "id": "abc", "label": "L", + "placed_on": [595, 842], "enabled": True, "zzz": {"a": 1}}) + self.assertEqual(stamp, Stamp(kind="text", text="x")) + # missing keys take the dataclass defaults + self.assertEqual((stamp.font, stamp.color, stamp.font_size, stamp.width_pt), + ("great-vibes", "#1A2B8C", 24.0, 150.0)) + + def test_numbers_stored_as_float(self): + stamp = Stamp.from_dict({"kind": "text", "text": "x", "font_size": 12, "width_pt": 80, + "page": 3, "x": 10, "y": 20}) + for value in (stamp.font_size, stamp.width_pt, stamp.x, stamp.y): + self.assertIs(type(value), float) + self.assertIs(type(stamp.page), int) + + def test_relative_font_resolved_against_base_dir(self): + base = self.p("cfg") + base.mkdir() + shutil.copy(stamps.resolve_font("lato"), base / "mine.ttf") + stamp = Stamp.from_dict({"kind": "text", "text": "x", "font": "mine.ttf"}, base_dir=base) + self.assertEqual(stamp.font, str(base / "mine.ttf")) + stamps.validate_stamp(stamp, placed=False) + # a bundled id is never turned into a path + bundled = Stamp.from_dict({"kind": "text", "text": "x", "font": "Caveat"}, base_dir=base) + self.assertEqual(bundled.font, "Caveat") + + def test_font_untouched_without_base_dir(self): + for font in ("./mine.ttf", "~/fonts/mine.ttf", "mine.ttf"): + stamp = Stamp.from_dict({"kind": "text", "text": "x", "font": font}) + self.assertEqual(stamp.font, font) + self.assertEqual(Stamp.from_dict(stamp.to_dict()), stamp) + + def test_hostile_paths_raise_stamp_error_only(self): + # pathlib raises RuntimeError for an unknown ~user and OSError for an + # over-long name: neither may escape as itself. + long_name = "x" * 5000 + rows = [ + ({"kind": "image", "image_path": "~no_such_user_zz/sig.png"}, "image not found: "), + ({"kind": "image", "image_path": long_name + ".png"}, "image not found: "), + ({"kind": "image", "image_path": "a\x00b.png"}, "image not found: "), + ({"kind": "image", "image_path": "\ud800.png"}, "image not found: "), + ({"kind": "text", "text": "x", "font": "~no_such_user_zz/f.ttf"}, "unknown font "), + ({"kind": "text", "text": "x", "font": long_name}, "unknown font "), + ({"kind": "text", "text": "x", "font": "a\x00b"}, "unknown font "), + ({"kind": "text", "text": "x", "font": "\ud800.ttf"}, "unknown font "), + ] + for base_dir in (None, self.tmp): + for data, prefix in rows: + with self.subTest(base_dir=base_dir, data=ascii(data)[:60]): + stamp = Stamp.from_dict(data, base_dir=base_dir) + with self.assertRaises(StampError) as cm: + stamps.validate_stamp(stamp, placed=False) + self.assertTrue(str(cm.exception).startswith(prefix), + ascii(str(cm.exception))[:80]) + # and it still serialises (a profile holding it must save): + # a NUL / lone surrogate makes Path.resolve raise ValueError + out = stamp.to_dict(base_dir=self.tmp) + self.assertEqual("image_path" in out, stamp.kind == "image") + with self.assertRaises(StampError): + stamps.load_image(long_name) + + def test_from_dict_type_errors(self): + cases = [([], "expected an object"), ("x", "expected an object"), + (None, "expected an object"), ({}, "missing 'kind'")] + for key in ("kind", "text", "font", "color", "image_path", "page_anchor"): + cases.append(({"kind": "text", key: 5}, f"'{key}' must be a string")) + cases.append(({"kind": "text", key: None}, f"'{key}' must be a string")) + for key in ("font_size", "width_pt", "x", "y"): + cases.append(({"kind": "text", key: "1"}, f"'{key}' must be a number")) + cases.append(({"kind": "text", key: 10 ** 400}, f"'{key}' must be a number")) + for bad in (1.5, "1", None): + cases.append(({"kind": "text", "page": bad}, "'page' must be an integer")) + for bad in (1, "true", None): + cases.append(({"kind": "text", "all_pages": bad}, "'all_pages' must be true or false")) + for data, message in cases: + with self.subTest(data=data): + with self.assertRaises(StampError) as cm: + Stamp.from_dict(data) + self.assertEqual(str(cm.exception), message) + + def test_bool_is_not_a_number(self): + for key in ("font_size", "width_pt", "x", "y"): + with self.subTest(key=key): + with self.assertRaises(StampError) as cm: + Stamp.from_dict({"kind": "text", key: True}) + self.assertEqual(str(cm.exception), f"'{key}' must be a number") + with self.assertRaises(StampError) as cm: + Stamp.from_dict({"kind": "text", "page": True}) + self.assertEqual(str(cm.exception), "'page' must be an integer") + + def test_validate_rules(self): + png = make_png(self.p("sig.png")) + not_a_font = self.p("fake.ttf") + not_a_font.write_text("not a font", encoding="utf-8") + text = dict(kind="text", text="Jane", page=1, x=0.0, y=0.0) + image = dict(kind="image", image_path=png, page=1, x=0.0, y=0.0) + nan, inf = float("nan"), float("inf") + size_msg = "font_size must be greater than 0 and at most 400" + width_msg = "width_pt must be greater than 0 and at most 5000" + target_msg = "give exactly one page target: page, page_anchor or all_pages" + rows = [ + # content rules, in the order they are checked + (dict(text, kind="sticker"), "unknown kind 'sticker' (expected text|image)"), + (dict(text, text=" \n "), "text is empty"), + (dict(text, text="a" * 2001), "text is too long (max 2000 characters)"), + (dict(text, color="blue"), "bad color 'blue' (expected #RRGGBB)"), + (dict(text, font_size=0.0), size_msg), + (dict(text, font_size=-3.0), size_msg), + (dict(text, font_size=400.5), size_msg), + (dict(text, font_size=nan), size_msg), + (dict(text, font_size=inf), size_msg), + (dict(text, font="comic-sans"), "unknown font 'comic-sans'"), + (dict(text, font=str(not_a_font)), f"cannot load font {str(not_a_font)!r}: "), + (dict(text, text="W" * 2000, font="lato", font_size=400.0), + "text is too large to render (reduce the font size or the text length)"), + (dict(image, image_path=None), "image_path is required"), + (dict(image, image_path=self.p("gone.png")), f"image not found: {self.p('gone.png')}"), + (dict(image, width_pt=0.0), width_msg), + (dict(image, width_pt=-1.0), width_msg), + (dict(image, width_pt=5000.5), width_msg), + (dict(image, width_pt=nan), width_msg), + # placement rules + (dict(text, page=None), target_msg), + (dict(text, page_anchor="last"), target_msg), + (dict(text, all_pages=True), target_msg), + (dict(image, page=None, page_anchor="first", all_pages=True), target_msg), + (dict(text, page=0), "page must be an integer >= 1"), + (dict(text, page=None, page_anchor="middle"), + "unknown page_anchor 'middle' (expected first|last)"), + (dict(text, x=None), "x and y are required"), + (dict(image, y=None), "x and y are required"), + (dict(text, x=nan), "x and y must be finite numbers"), + (dict(image, y=inf), "x and y must be finite numbers"), + # content is checked before placement + (dict(text, text="", page=None), "text is empty"), + ] + for kwargs, message in rows: + with self.subTest(message=message, kwargs={k: str(v)[:20] for k, v in kwargs.items()}): + with self.assertRaises(StampError) as cm: + stamps.validate_stamp(Stamp(**kwargs)) + if message.endswith(("'", ": ")): # open-ended messages + self.assertTrue(str(cm.exception).startswith(message), str(cm.exception)) + else: + self.assertEqual(str(cm.exception), message) + valid = [text, image, dict(text, font_size=400.0, text="J"), dict(image, width_pt=5000.0), + dict(text, page=None, page_anchor="first"), dict(image, page=None, all_pages=True), + dict(text, text="a" * 2000, font="lato", font_size=6.0), dict(text, x=-5.0, y=1e6)] + for kwargs in valid: + with self.subTest(valid={k: str(v)[:20] for k, v in kwargs.items()}): + stamps.validate_stamp(Stamp(**kwargs)) + + def test_bundled_font_missing_is_reported(self): + stamp = Stamp(kind="text", text="Jane", font="lato", page=1, x=0.0, y=0.0) + with mock.patch.object(sys, "_MEIPASS", str(self.tmp), create=True): + with self.assertRaises(StampError) as cm: + stamps.validate_stamp(stamp) + self.assertTrue(str(cm.exception).startswith("bundled font file missing: ")) + + def test_validate_unplaced_content_only(self): + unplaced = Stamp(kind="text", text="Jane") + stamps.validate_stamp(unplaced, placed=False) + with self.assertRaises(StampError): + stamps.validate_stamp(unplaced) + half = Stamp(kind="image", image_path=make_png(self.p("s.png")), page=1, x=3.0) + stamps.validate_stamp(half, placed=False) + with self.assertRaises(StampError): + stamps.validate_stamp(half) + with self.assertRaises(StampError) as cm: # content rules still run + stamps.validate_stamp(Stamp(kind="text", text=""), placed=False) + self.assertEqual(str(cm.exception), "text is empty") + + def test_validate_placement_ignores_content(self): + # a saved placement stays judgeable while its image file is missing + gone = Stamp(kind="image", image_path=self.p("gone.png"), page=2, x=1.0, y=2.0) + stamps.validate_placement(gone) + with self.assertRaises(StampError) as cm: + stamps.validate_placement(dataclasses.replace(gone, y=None)) + self.assertEqual(str(cm.exception), "x and y are required") + + def test_page_indexes(self): + self.assertEqual(Stamp(page=1).page_indexes(3), [0]) + self.assertEqual(Stamp(page=3).page_indexes(3), [2]) + self.assertEqual(Stamp(page_anchor="first").page_indexes(3), [0]) + self.assertEqual(Stamp(page_anchor="last").page_indexes(3), [2]) + self.assertEqual(Stamp(page_anchor="last").page_indexes(1), [0]) + self.assertEqual(Stamp(all_pages=True).page_indexes(3), [0, 1, 2]) + for page in (0, 4, -1): + with self.subTest(page=page): + with self.assertRaises(StampError) as cm: + Stamp(page=page).page_indexes(3) + self.assertEqual(str(cm.exception), + f"page {page} out of range (the document has 3 page(s))") + with self.assertRaises(StampError) as cm: + Stamp().page_indexes(3) + self.assertEqual(str(cm.exception), "the signature has no page target") + with self.assertRaises(StampError) as cm: + Stamp(page=1).page_indexes(0) + self.assertEqual(str(cm.exception), "the document has no page") + with self.assertRaises(StampError): + Stamp(page_anchor="middle").page_indexes(3) + + def test_describe_and_labels(self): + text = Stamp(kind="text", text="\n Jane Doe \nRead and approved", page_anchor="last", + x=360.4, y=119.6) + self.assertTrue(text.is_placed) + self.assertEqual(text.target_label(), "last page") + self.assertEqual(text.describe(), "text last page @ (360, 120)") + self.assertEqual(text.content_label(), '"Jane Doe"') + image = Stamp(kind="image", image_path=Path("/x/y/stamp.png"), page=2, x=1.0, y=2.0) + self.assertEqual(image.describe(), "image page 2 @ (1, 2)") + self.assertEqual(image.content_label(), "stamp.png") + self.assertEqual(Stamp(kind="image").content_label(), "?") + self.assertEqual(Stamp(kind="text", text="JD", all_pages=True, x=540.0, y=20.0).describe(), + "text all pages @ (540, 20)") + self.assertEqual(Stamp(kind="text", page_anchor="first").target_label(), "first page") + unplaced = Stamp(kind="text", text="x") + self.assertFalse(unplaced.is_placed) + self.assertEqual(unplaced.target_label(), "unplaced") + self.assertEqual(unplaced.describe(), "text unplaced") + long = Stamp(kind="text", text="A" * 31) + self.assertEqual(long.content_label(), '"' + "A" * 30 + '…"') + self.assertEqual(Stamp(kind="text", text="A" * 30).content_label(), '"' + "A" * 30 + '"') + # placed needs a position AND exactly one target + self.assertFalse(Stamp(page=1, x=1.0).is_placed) + self.assertFalse(Stamp(x=1.0, y=1.0).is_placed) + self.assertFalse(Stamp(page=1, all_pages=True, x=1.0, y=1.0).is_placed) + + def test_content_key(self): + a = Stamp(kind="text", text="{filename} {date}", color="#aa00ff", page=1, x=1.0, y=2.0) + b = Stamp(kind="text", text="{filename} {date}", color="#AA00FF", all_pages=True) + key = stamps.content_key(a, filename="doc", date=DAY) + self.assertEqual(key, ("text", "doc 07/10/2026", "great-vibes", 24.0, "#AA00FF")) + self.assertEqual(key, stamps.content_key(b, filename="doc", date=DAY)) # placement excluded + self.assertNotEqual(key, stamps.content_key(a, filename="other", date=DAY)) + img = Stamp(kind="image", image_path=Path("/x/s.png"), width_pt=80) + self.assertEqual(stamps.content_key(img), ("image", "/x/s.png", 80.0)) + hash(key) + + +class SignaturesFile(StampCase): + def write(self, entries, name="sigs.json", encoding="utf-8") -> Path: + path = self.p(name) + path.write_text(json.dumps(entries), encoding=encoding) + return path + + def assert_rejected(self, path, fragment): + with self.assertRaises(StampError) as cm: + stamps.load_stamps_file(path) + self.assertIn(fragment, str(cm.exception)) + return str(cm.exception) + + def test_load_list(self): + make_png(self.p("stamp.png")) + path = self.write([ + {"kind": "text", "text": "Jane Doe\nRead and approved, {date}", + "font": "great-vibes", "color": "#1A2B8C", "font_size": 24, + "page_anchor": "last", "x": 360, "y": 120}, + {"kind": "text", "text": "JD", "font": "caveat", "font_size": 14, + "all_pages": True, "x": 540, "y": 20}, + {"kind": "image", "image_path": "stamp.png", "width_pt": 120, + "page": 1, "x": 60, "y": 700}, + ]) + loaded = stamps.load_stamps_file(path) + self.assertEqual([s.describe() for s in loaded], [ + "text last page @ (360, 120)", "text all pages @ (540, 20)", + "image page 1 @ (60, 700)"]) + self.assertTrue(all(s.is_placed for s in loaded)) + self.assertEqual(loaded[0].text, "Jane Doe\nRead and approved, {date}") + self.assertEqual(stamps.load_stamps_file(self.write([], name="empty.json")), []) + + def test_relative_image_resolved_against_file_dir(self): + sub = self.p("conf") + sub.mkdir() + png = make_png(sub / "stamp.png") + (sub / "sigs.json").write_text(json.dumps( + [{"kind": "image", "image_path": "stamp.png", "page": 1, "x": 0, "y": 0}]), + encoding="utf-8") + loaded = stamps.load_stamps_file(sub / "sigs.json") # cwd is NOT sub + self.assertEqual(loaded[0].image_path, png) + + def test_disabled_entries_skipped(self): + path = self.write([ + {"kind": "text", "text": "kept", "page": 1, "x": 0, "y": 0, "enabled": True}, + # skipped BEFORE validation: it may even be invalid + {"kind": "text", "text": "", "enabled": False}, + {"kind": "text", "text": "also kept", "page": 1, "x": 0, "y": 0}, + ]) + self.assertEqual([s.text for s in stamps.load_stamps_file(path)], ["kept", "also kept"]) + bad = self.write([{"kind": "text", "text": "x", "page": 1, "x": 0, "y": 0, + "enabled": "no"}], name="bad.json") + msg = self.assert_rejected(bad, "'enabled' must be true or false") + self.assertEqual(msg, "bad.json: signature #1: 'enabled' must be true or false") + + def test_profile_extras_ignored(self): + path = self.write([{"id": "3f9a1c0b77de", "label": "Jane Doe", "enabled": True, + "kind": "text", "text": "Jane Doe", "font": "great-vibes", + "color": "#1A2B8C", "font_size": 24.0, + "page": 2, "x": 360.0, "y": 120.0, "placed_on": [595.0, 842.0]}]) + self.assertEqual(stamps.load_stamps_file(path), + [Stamp(kind="text", text="Jane Doe", page=2, x=360.0, y=120.0)]) + + def test_not_a_list_rejected(self): + for value in ({"kind": "text"}, "x", 3, None): + with self.subTest(value=value): + path = self.write(value) + msg = self.assert_rejected(path, "expected a JSON list of signatures") + self.assertEqual(msg, f"{path}: expected a JSON list of signatures") + + def test_bad_json_rejected(self): + path = self.p("bad.json") + path.write_text("[{", encoding="utf-8") + msg = self.assert_rejected(path, "invalid JSON") + self.assertTrue(msg.startswith(f"invalid JSON in {path}: "), msg) + + def test_missing_file_rejected(self): + path = self.p("nope.json") + msg = self.assert_rejected(path, "cannot read signatures file") + self.assertTrue(msg.startswith(f"cannot read signatures file {path}: "), msg) + + def test_error_names_file_and_entry_number(self): + ok = {"kind": "text", "text": "x", "page": 1, "x": 0, "y": 0} + cases = [ + ([ok, {"kind": "text", "text": "x", "x": 0, "y": 0}], + "sigs.json: signature #2: give exactly one page target: " + "page, page_anchor or all_pages"), + ([ok, ok, {"kind": "image", "page": 1, "x": 0, "y": 0}], + "sigs.json: signature #3: image_path is required"), + ([{"text": "x"}], "sigs.json: signature #1: missing 'kind'"), + ([ok, "nope"], "sigs.json: signature #2: expected an object"), + ([{"kind": "text", "text": "x", "page": "1", "x": 0, "y": 0}], + "sigs.json: signature #1: 'page' must be an integer"), + ] + for entries, message in cases: + with self.subTest(message=message): + self.assertEqual(self.assert_rejected(self.write(entries), "signature #"), message) + + def test_unknown_font_id_reported_as_typed(self): + entry = {"kind": "text", "text": "x", "page": 1, "x": 0, "y": 0} + msg = self.assert_rejected(self.write([dict(entry, font="latoo")]), "unknown font") + # the id as typed (not joined to the folder of the JSON file) + the valid ids + self.assertTrue(msg.startswith("sigs.json: signature #1: unknown font 'latoo' "), msg) + self.assertNotIn(str(self.tmp), msg) + for font_id in stamps.BUNDLED_FONTS: + self.assertIn(font_id, msg) + # a relative PATH is still looked up next to the JSON file, and says where + msg = self.assert_rejected(self.write([dict(entry, font="sub/mine.ttf")]), "unknown font") + self.assertIn(str(self.p("sub") / "mine.ttf"), msg) + shutil.copy(stamps.resolve_font("lato"), self.p("mine")) # a bare-word font file + loaded = stamps.load_stamps_file(self.write([dict(entry, font="mine")])) + self.assertEqual(loaded[0].font, str(self.p("mine"))) + + def test_utf8_bom_accepted(self): + path = self.write([{"kind": "text", "text": "Sébastien", "page": 1, "x": 0, "y": 0}], + encoding="utf-8-sig") + self.assertTrue(path.read_bytes().startswith(b"\xef\xbb\xbf")) + self.assertEqual(stamps.load_stamps_file(path)[0].text, "Sébastien") + + def test_non_ascii_text_roundtrip(self): + path = self.p("sigs.json") + path.write_bytes(json.dumps( + [{"kind": "text", "text": "Sébastien — Ünï", "page": 1, "x": 0, "y": 0}], + ensure_ascii=False).encode("utf-8")) + self.assertIn("Sébastien".encode("utf-8"), path.read_bytes()) + self.assertEqual(stamps.load_stamps_file(path)[0].text, "Sébastien — Ünï") + + def test_not_utf8_rejected(self): + path = self.p("latin1.json") + path.write_bytes(b'[{"text": "S\xe9b"}]') + self.assertEqual(self.assert_rejected(path, "not valid UTF-8"), + f"{path}: not valid UTF-8") + + def test_deeply_nested_json_rejected(self): + path = self.p("deep.json") + path.write_text("[" * 200000, encoding="utf-8") + msg = self.assert_rejected(path, "invalid JSON") # a StampError, no RecursionError + self.assertTrue(msg.startswith("invalid JSON"), msg[:80]) + + def test_nan_coordinates_rejected(self): + path = self.p("nan.json") + path.write_text('[{"kind": "text", "text": "x", "page": 1, "x": NaN, "y": 0}]', + encoding="utf-8") + self.assertEqual(self.assert_rejected(path, "finite"), + "nan.json: signature #1: x and y must be finite numbers") + + +class ApplyStamps(StampCase): + def text(self, **kwargs): + return Stamp(kind="text", text="Jane Doe", **kwargs) + + def counts(self, pdf): + return [len(page_xobjects(page)) for page in pdf_pages(pdf)] + + def test_one_xobject_per_target_page(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)] * 3) + png = make_png(self.p("sig.png")) + out = self.stamped(pdf, [ + self.text(page=1, x=50.0, y=50.0), + Stamp(kind="image", image_path=png, page=1, x=300.0, y=50.0), + self.text(page=3, x=50.0, y=50.0), + ]) + self.assertEqual(self.counts(out), [2, 0, 1]) + self.assertEqual(self.counts(pdf), [0, 0, 0]) # the input is untouched + + def test_all_pages_single_image(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)] * 5) + out = self.stamped(pdf, [self.text(all_pages=True, x=540.0, y=20.0)]) + xobjects = [page_xobjects(page) for page in pdf_pages(out)] + self.assertEqual([len(x) for x in xobjects], [1] * 5) + # ONE image XObject shared by the five pages (not five copies) + self.assertEqual(len({ref for x in xobjects for ref in x.values()}), 1) + + def test_pages_sharing_one_resources_dictionary(self): + # two pages pointing at the SAME indirect /Resources: each page needs + # its own XObject name (pyHanko refuses a duplicate name) + page = b"<>" + pdf = write_pdf_objects(self.p("shared.pdf"), [ + b"<>", + b"<>", + page % 4, pdf_stream(b"q Q\n"), page % 6, pdf_stream(b"q Q\n"), + b"<>"]) + out = self.stamped(pdf, [self.text(all_pages=True, x=100.0, y=100.0)]) + xobjects = [page_xobjects(p) for p in pdf_pages(out)] + self.assertEqual(xobjects[0], xobjects[1]) # the shared dictionary + self.assertEqual(len(xobjects[0]), 2) # one name per page... + self.assertEqual(len(set(xobjects[0].values())), 1) # ...for one image + + def test_indirect_contents_array_with_direct_resources(self): + # /Contents -> an indirect ARRAY: pyHanko then updates the array only, + # so the /Resources it adds to the page must be written explicitly + for label, resources in (("direct", b"/Resources<>"), ("absent", b"")): + with self.subTest(resources=label): + pdf = write_pdf_objects(self.p(f"{label}.pdf"), [ + b"<>", + b"<>", + b"<>", + b"[5 0 R]", pdf_stream(b"q Q\n")]) + out = self.stamped(pdf, [self.text(page=1, x=100.0, y=100.0)]) + page = pdf_pages(out)[0] + (name,) = page_xobjects(page) # the XObject reached the file + data = b" ".join(part.get_object().data for part in page["/Contents"]) + self.assertIn(name.encode() + b" Do", data) + + def test_pages_sharing_one_contents_array(self): + # two pages pointing at the SAME indirect /Contents array: a stamp + # for page 1 must not reach page 2 (pyHanko appends to it in place) + page = b"<>" + for label, resources in (("own", b"/Resources<>"), + ("shared", b"/Resources 6 0 R")): + with self.subTest(resources=label): + pdf = write_pdf_objects(self.p(f"{label}.pdf"), [ + b"<>", + b"<>", + page % resources, b"[5 0 R]", pdf_stream(b"q Q\n"), + b"<>", page % resources]) + out = self.stamped(pdf, [self.text(page=1, x=100.0, y=100.0), + self.text(page=1, x=100.0, y=300.0)]) + painted = [b" ".join(part.get_object().data for part in page["/Contents"]) + .count(b" Do") for page in pdf_pages(out)] + self.assertEqual(painted, [2, 0]) + + def test_anchor_last_on_shorter_document(self): + last = self.text(page_anchor="last", x=50.0, y=50.0) + first = self.text(page_anchor="first", x=50.0, y=50.0) + one = make_pdf(self.p("one.pdf"), [(595, 842)]) + three = make_pdf(self.p("three.pdf"), [(595, 842)] * 3) + self.assertEqual(self.counts(self.stamped(one, [last])), [1]) + self.assertEqual(self.counts(self.stamped(three, [last])), [0, 0, 1]) + self.assertEqual(self.counts(self.stamped(three, [first])), [1, 0, 0]) + self.assertEqual(self.counts(self.stamped(one, [first, last])), [2]) + + def test_page_out_of_range_before_any_write(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)] * 2) + good = self.text(page=1, x=50.0, y=50.0) + bad = self.text(page=5, x=50.0, y=50.0) + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + with self.assertRaises(StampError) as cm: + stamps.apply_stamps(writer, [good, bad]) + self.assertEqual(str(cm.exception), + "page 5 out of range (the document has 2 page(s))") + out = io.BytesIO() + writer.write(out) + # the valid FIRST stamp was not applied either: nothing half-stamped + after = self.p("after.pdf") + after.write_bytes(out.getvalue()) + self.assertEqual(self.counts(after), [0, 0]) + + def test_unreadable_image_before_any_write(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)]) + broken = self.p("broken.png") + broken.write_text("nope", encoding="utf-8") + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + with self.assertRaises(StampError): + stamps.apply_stamps(writer, [ + self.text(page=1, x=50.0, y=50.0), + Stamp(kind="image", image_path=broken, page=1, x=0.0, y=0.0)]) + out = io.BytesIO() + writer.write(out) + after = self.p("after.pdf") + after.write_bytes(out.getvalue()) + self.assertEqual(self.counts(after), [0]) + + def test_unplaced_raises(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)]) + for stamp in (self.text(), self.text(page=1), self.text(x=1.0, y=1.0), + self.text(page=1, page_anchor="last", x=1.0, y=1.0)): + with self.subTest(stamp=stamp.describe()): + with self.assertRaises(StampError) as cm: + self.stamped(pdf, [stamp]) + self.assertEqual(str(cm.exception), "the signature is not placed") + + def test_empty_list_is_a_noop(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)]) + self.assertEqual(self.counts(self.stamped(pdf, [])), [0]) + + def test_page_without_contents_is_stamped(self): + pdf = strip_page_contents(make_pdf(self.p("a.pdf"), [(595, 842)] * 2), 1) + before = pdf_pages(pdf) + self.assertIn("/Contents", before[0]) + self.assertNotIn("/Contents", before[1]) # the fixture really is blank + out = self.stamped(pdf, [self.text(all_pages=True, x=100.0, y=100.0)]) + pages = pdf_pages(out) + self.assertIn("/Contents", pages[1]) + self.assertEqual(self.counts(out), [1, 1]) + img = core.render_page_image(out, 1, 595) # 1 px per point + if img is not None: # pypdfium2 / pdftoppm available + box = img.crop((100, 842 - 160, 300, 842 - 100)) + self.assertTrue(any(near(px, INK) for _, px in box.getcolors(100000))) + + def test_existing_signature_count_zero_for_unsigned(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)] * 2) + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + self.assertEqual(stamps.existing_signature_count(writer), 0) + # read-only: stamps applied afterwards still work, count unchanged + stamps.apply_stamps(writer, [self.text(page=1, x=10.0, y=10.0)]) + self.assertEqual(stamps.existing_signature_count(writer), 0) + + def test_empty_signature_field_is_not_a_signature(self): + # a form prepared for signing: the field exists but nothing is signed + pdf = make_pdf(self.p("a.pdf"), [(595, 842)]) + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + append_signature_field( + writer, SigFieldSpec("ToBeSigned", on_page=0, box=(10, 10, 110, 60))) + out = io.BytesIO() + writer.write(out) + prepared = self.p("prepared.pdf") + prepared.write_bytes(out.getvalue()) + with prepared.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + self.assertEqual(len(list(enumerate_sig_fields(writer.prev))), 1) # the fixture + self.assertEqual(stamps.existing_signature_count(writer), 0) + + def test_page_count_and_mediabox(self): + pdf = make_pdf(self.p("a.pdf"), [(200, 300), (400, 500), (612, 792)]) + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + self.assertEqual(stamps.page_count(writer), 3) + self.assertEqual(stamps.page_mediabox(writer, 0), [0.0, 0.0, 200.0, 300.0]) + self.assertEqual(stamps.page_mediabox(writer, -1), [0.0, 0.0, 612.0, 792.0]) + + def test_static_content_cached_once(self): + cache: dict = {} + stamp = Stamp(kind="text", text="Jane Doe, {date}", page=1, x=50.0, y=50.0) + with mock.patch.object(stamps, "render_text_image", + wraps=stamps.render_text_image) as spy: + for name in ("a", "b", "c"): + pdf = make_pdf(self.p(f"{name}.pdf"), [(595, 842)]) + out = self.stamped(pdf, [stamp], filename=name, date=DAY, cache=cache) + self.assertEqual(self.counts(out), [1]) + self.assertEqual(spy.call_count, 1) + self.assertEqual(list(cache), [stamps.content_key(stamp, date=DAY)]) + + def test_image_content_cached_once(self): + cache: dict = {} + stamp = Stamp(kind="image", image_path=make_png(self.p("s.png")), all_pages=True, + x=5.0, y=5.0) + with mock.patch.object(stamps, "load_image", wraps=stamps.load_image) as spy: + for name in ("a", "b"): + self.stamped(make_pdf(self.p(f"{name}.pdf"), [(595, 842)] * 2), [stamp], + filename=name, cache=cache) + self.assertEqual(spy.call_count, 1) + + def test_filename_text_not_cached(self): + cache: dict = {} + stamp = Stamp(kind="text", text="Ref {filename}", page=1, x=50.0, y=50.0) + with mock.patch.object(stamps, "render_text_image", + wraps=stamps.render_text_image) as spy: + for name in ("a", "b", "c"): + pdf = make_pdf(self.p(f"{name}.pdf"), [(595, 842)]) + self.stamped(pdf, [stamp], filename=name, date=DAY, cache=cache) + self.assertEqual(spy.call_count, 3) + self.assertEqual([call.args[0] for call in spy.call_args_list], + ["Ref a", "Ref b", "Ref c"]) + self.assertEqual(cache, {}) # no growth over the batch + + def paint_matrix(self, pdf, page_index=0) -> list[float]: + """[w, h, x, y] of the only stamp painted on a page: the operands of + its ``w 0 0 h x y cm`` matrix.""" + contents = pdf_pages(pdf)[page_index]["/Contents"] + data = b" ".join(part.get_object().data for part in contents) + (found,) = re.findall(rb"q (\S+) 0 0 (\S+) (\S+) (\S+) cm /Stamp\w+ Do Q", data) + return [float(v) for v in found] + + def test_float_coordinates_accepted(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)]) + out = self.stamped(pdf, [self.text(page=1, x=100.5, y=200.25)]) + self.assertEqual(self.paint_matrix(out)[2:], [100.5, 200.25]) # not rounded to integers + + def test_stamped_size_is_the_content_size(self): + # the size is NOT truncated to whole points (a pyHanko stamp box would + # be): what is previewed is what gets stamped, down to under 1 pt + thin = self.p("rule.png") + Image.new("RGB", (2000, 1), (0, 0, 0)).save(thin) + for stamp in ( + Stamp(kind="text", text="JD", font="lato", font_size=8, page=1, x=100.0, y=400.0), + Stamp(kind="text", text="__________", font="lato", font_size=12, + page=1, x=100.0, y=400.0), + Stamp(kind="image", image_path=thin, width_pt=150.0, page=1, x=100.0, y=400.0)): + with self.subTest(stamp=stamp.content_label()): + _, (w, h) = stamps.stamp_content(stamp) + self.assertNotEqual((w, h), (int(w), int(h))) # a fractional size + pdf = make_pdf(self.p("a.pdf"), [(595, 842)]) + matrix = self.paint_matrix(self.stamped(pdf, [stamp])) + self.assertAlmostEqual(matrix[0], w, places=3) + self.assertAlmostEqual(matrix[1], h, places=3) + self.assertEqual(matrix[2:], [100.0, 400.0]) + self.assertLess(h, 1.0) # the rule: under 1 pt high + + def test_position_is_relative_to_the_mediabox_origin(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)], origin=(100, 200)) + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + self.assertEqual(stamps.page_mediabox(writer, 0), [100.0, 200.0, 695.0, 1042.0]) + out = self.stamped(pdf, [self.text(page=1, x=50.0, y=60.0)]) + self.assertEqual(self.paint_matrix(out)[2:], [150.0, 260.0]) + + def test_mediabox_inherited_from_the_page_tree(self): + # the page has no /MediaBox of its own: the one of /Pages applies + pdf = write_pdf_objects(self.p("inherited.pdf"), [ + b"<>", + b"<>", + b"<>>>", + pdf_stream(b"q Q\n")]) + with pdf.open("rb") as inf: + writer = IncrementalPdfFileWriter(inf, strict=False) + self.assertEqual(stamps.page_mediabox(writer, 0), [10.0, 20.0, 410.0, 620.0]) + out = self.stamped(pdf, [self.text(page=1, x=50.0, y=60.0)]) + self.assertEqual(self.paint_matrix(out)[2:], [60.0, 80.0]) + + def test_rendered_pixels(self): + pdf = make_pdf(self.p("a.pdf"), [(595, 842)]) + # 200x100 px: left half opaque red, right half fully transparent + png = self.p("half.png") + im = Image.new("RGBA", (200, 100), (0, 0, 0, 0)) + im.paste((255, 0, 0, 255), (0, 0, 100, 100)) + im.save(png) + stamp_text = self.text(page=1, x=300.0, y=400.0) + _, (tw, th) = stamps.stamp_content(stamp_text) + # 30x15 px, fewer pixels than its 200x100 pt box: it must be ENLARGED + small = self.p("small.png") + Image.new("RGB", (30, 15), (0, 0, 255)).save(small) + out = self.stamped(pdf, [ + Stamp(kind="image", image_path=png, width_pt=100.0, page=1, x=100.0, y=100.0), + stamp_text, + Stamp(kind="image", image_path=small, width_pt=200.0, page=1, x=100.0, y=600.0)]) + img = core.render_page_image(out, 0, 595) # 1 px per point, y downwards + if img is None: + self.skipTest("no PDF renderer available (pypdfium2 / pdftoppm)") + white = (255, 255, 255) + # image: 100x50 pt box at (100, 100) -> rows 692..742 + self.assertTrue(near(img.getpixel((125, 842 - 125)), (255, 0, 0))) # opaque half + self.assertTrue(near(img.getpixel((175, 842 - 125)), white, 6)) # page shows through + self.assertTrue(near(img.getpixel((125, 842 - 170)), white, 6)) # above the box + self.assertTrue(near(img.getpixel((80, 842 - 125)), white, 6)) # left of the box + # text: ink inside its own box, in the chosen colour; none just outside + box = img.crop((300, round(842 - 400 - th), round(300 + tw), 842 - 400)) + self.assertTrue(any(near(px, INK) for _, px in box.getcolors(100000))) + margin = img.crop((300, round(842 - 400 - th) - 40, round(300 + tw), + round(842 - 400 - th) - 4)) + self.assertTrue(all(near(px, white, 6) for _, px in margin.getcolors(100000))) + # the small image fills its whole box (both corners), not its natural 30x15 pt + self.assertTrue(near(img.getpixel((105, 842 - 605)), (0, 0, 255))) + self.assertTrue(near(img.getpixel((295, 842 - 695)), (0, 0, 255))) + # no frame around either element + self.assertTrue(near(img.getpixel((199, 842 - 125)), white, 6)) # right edge + self.assertTrue(near(img.getpixel((175, 842 - 149)), white, 6)) # top edge + self.assertTrue(near(img.getpixel((101, 842 - 125)), (255, 0, 0))) # left edge: the image + + +class StrokeRendering(unittest.TestCase): + def test_strokes_give_transparent_rgba(self): + strokes = [[(10, 10), (60, 40), (110, 10)], [(10, 50), (110, 50)]] + img = stamps.render_strokes_image(strokes, "#0000FF", width=3.0, scale=4) + self.assertEqual(img.mode, "RGBA") + self.assertEqual(img.convert("RGB").getcolors(), [(img.width * img.height, (0, 0, 255))]) + alpha = img.getchannel("A") + self.assertEqual(alpha.getbbox(), (0, 0) + img.size) # tightly cropped + self.assertEqual(alpha.getpixel((img.width // 2, 2)), 0) # between the strokes + self.assertEqual(alpha.getpixel((img.width // 2, img.height - 6)), 255) # on the line + # scale x (bounding box of the points + the pen width) + self.assertAlmostEqual(img.width, 4 * (100 + 3), delta=8) + self.assertAlmostEqual(img.height, 4 * (40 + 3), delta=8) + double = stamps.render_strokes_image(strokes, "#0000FF", width=3.0, scale=8) + self.assertAlmostEqual(double.width / img.width, 2.0, delta=0.1) + + def test_single_point_stroke_draws_a_dot(self): + img = stamps.render_strokes_image([[(50, 50)]], "#000000", width=3.0, scale=4) + self.assertAlmostEqual(img.width, 12, delta=3) + self.assertAlmostEqual(img.height, 12, delta=3) + self.assertEqual(img.getchannel("A").getpixel((img.width // 2, img.height // 2)), 255) + # points outside the canvas (negative coordinates) are kept + off = stamps.render_strokes_image([[(-20, -5), (30, 10)]], "#000000") + self.assertAlmostEqual(off.width, 4 * (50 + 3), delta=8) + + def test_empty_raises(self): + for strokes in ([], [[]], [[], []]): + with self.subTest(strokes=strokes): + with self.assertRaises(StampError) as cm: + stamps.render_strokes_image(strokes, "#000000") + self.assertEqual(str(cm.exception), "nothing was drawn") + with self.assertRaises(StampError) as cm: + stamps.render_strokes_image([[(1, 1)]], "black") + self.assertEqual(str(cm.exception), "bad color 'black' (expected #RRGGBB)") + + def test_oversized_drawing_raises_stamp_error(self): + # two points a few screens apart: the mask would be gigapixels + real_new = Image.new + for strokes in ([[(0, 0), (30000, 30000)]], [[(0, 0)], [(1e9, 5)]], + [[(0, 0), (float("inf"), 5)]]): + with self.subTest(strokes=strokes): + with mock.patch.object(stamps.Image, "new", side_effect=real_new) as spy: + with self.assertRaises(StampError) as cm: + stamps.render_strokes_image(strokes, "#000000") + self.assertEqual(str(cm.exception), "drawing is too large") + spy.assert_not_called() # refused BEFORE any allocation + # a large canvas crossed corner to corner still renders + img = stamps.render_strokes_image([[(0, 0), (1000, 600)]], "#000000", scale=4) + self.assertGreater(img.width, 3900) + + +class HeadlessImportNewModules(unittest.TestCase): + def test_import_without_tkinter_or_pdfium(self): + code = ("import stamps, profile_store, sys; " + "print([m for m in ('tkinter', 'customtkinter', 'pypdfium2', " + "'sign_pdfs_beid', 'gui', 'i18n') if m in sys.modules])") + out = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, + cwd=str(Path(__file__).parent)) + self.assertEqual(out.returncode, 0, out.stderr) + self.assertEqual(out.stdout.strip(), "[]") + + +if __name__ == "__main__": + unittest.main() From af8e4aa817419559421902b3ec7dbb7177e8ee02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Denooz?= Date: Wed, 7 Oct 2026 09:56:19 +0200 Subject: [PATCH 2/6] feat(profile): persist signatures and settings in the user folder Add profile_store.py: profile.json under the user config dir (tolerant load, atomic save, unreadable files set aside as .bak) and a content-addressed store for imported and drawn signature images under the user data dir. No PIN, token or credential is ever written. CACHET_CONFIG_DIR / CACHET_DATA_DIR override both locations. --- profile_store.py | 470 +++++++++++++++++++++ test_profile_store.py | 933 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1403 insertions(+) create mode 100644 profile_store.py create mode 100644 test_profile_store.py diff --git a/profile_store.py b/profile_store.py new file mode 100644 index 0000000..56fd983 --- /dev/null +++ b/profile_store.py @@ -0,0 +1,470 @@ +"""User profile and signature image store for the Cachet GUI. + +What is persisted, in the user folder, so nothing has to be reconfigured at +the next start: + +- ``/profile.json`` — the signature library (content + last + placement of each visual signature) and the wizard settings (language, + mode, PAdES level, output folder, azure vault URL / auth method / + trust-anchors path, beID vignette placement); +- ``/signatures/`` — a copy of every imported or drawn image, under + a content-addressed name, so a moved original does not break a signature. + +NEVER persisted: PIN, tokens, any credential, the azure key name, the +signed-in UPN, the template, the input files. Everything is stored +UNENCRYPTED. + +Design notes (deliberate choices): + +- Directories: explicit argument > ``CACHET_CONFIG_DIR`` / ``CACHET_DATA_DIR`` + > ``platformdirs``. Tests must always pass explicit temp dirs (or set the + env vars) — never touch the real user profile. +- ``load()`` never raises: a missing file gives defaults, a corrupt or + other-version file is moved aside as ``profile.json.bak`` (so a later save + cannot destroy it silently), a bad entry is skipped and the others kept. + A profile that could neither be read nor moved aside stays in place, and + ``save()`` then refuses to overwrite it until a later ``load()`` succeeds. +- Writes are atomic (temp file in the same directory + ``os.replace``). +- The only code that deletes anything is ``remove_signature``, for the one + stored image of the one signature being deleted, and only when + ``is_store_file`` says the file belongs to the store. There is no sweep of + unreferenced images: the data dir may serve another profile, and a + ``.bak`` still references its images. + +This module must stay importable without tkinter. It is used by the GUI only: +the core/CLI never reads the profile (headless runs stay deterministic). +""" + +from __future__ import annotations + +import dataclasses +import hashlib +import io +import json +import math +import os +import re +import tempfile +import uuid +from pathlib import Path + +import stamps as stamplib + +PROFILE_VERSION = 1 +APP_NAME = "Cachet" +PROFILE_FILENAME = "profile.json" +SIGNATURES_DIRNAME = "signatures" +ENV_CONFIG_DIR = "CACHET_CONFIG_DIR" +ENV_DATA_DIR = "CACHET_DATA_DIR" + +MAX_LABEL_LEN = 80 +_IMAGE_EXTENSIONS = (".png", ".jpg", ".jpeg", ".gif", ".bmp", ".webp", ".tif", ".tiff") +# Names import_image / store_image produce: 32 hex digits of the sha256 + extension. +_STORE_NAME_RE = re.compile(r"[0-9a-f]{32}\.[a-z0-9]+") +_ID_RE = re.compile(r"[0-9a-f]{12}") +# validate_stamp messages meaning "the content is fine but its file is not +# there (any more)": such an entry is kept, the GUI shows it as unusable. +_MISSING_FILE_PREFIXES = ( + "image not found", "unknown font", "bundled font file missing", "cannot load font") +_SETTING_KEYS = ( + "language", "mode", "pades_level", "output_dir", + "azure_vault_url", "azure_auth", "azure_trust_anchors") + + +# --------------------------------------------------------------------------- +# Directories and ids +# --------------------------------------------------------------------------- + +def _resolve_dir(explicit, env_name: str, kind: str) -> Path: + if explicit is not None: + return Path(explicit) + env = os.environ.get(env_name) + if env: + return Path(env) + import platformdirs # lazy: only the default location needs it + + return Path(getattr(platformdirs, f"user_{kind}_dir")(APP_NAME, appauthor=False)) + + +def resolve_config_dir(explicit=None) -> Path: + """Directory of ``profile.json``: ``explicit`` > ``CACHET_CONFIG_DIR`` > + the platform's user config dir. Never creates it.""" + return _resolve_dir(explicit, ENV_CONFIG_DIR, "config") + + +def resolve_data_dir(explicit=None) -> Path: + """Directory holding ``signatures/``: ``explicit`` > ``CACHET_DATA_DIR`` > + the platform's user data dir. Never creates it.""" + return _resolve_dir(explicit, ENV_DATA_DIR, "data") + + +def new_id() -> str: + return uuid.uuid4().hex[:12] + + +def is_valid_id(value) -> bool: + """12 lower-case hex digits — so the reserved GUI element id + ``"vignette"`` can never be a signature id.""" + return isinstance(value, str) and _ID_RE.fullmatch(value) is not None + + +# --------------------------------------------------------------------------- +# Placement rules (pure) +# --------------------------------------------------------------------------- + +def page_placement_applies(page, placed_on, template_dims, anchor=None) -> bool: + """Is a placement saved for the 1-based ``page`` in force on this + template? Only when that page exists, is the anchor page (if an anchor + applies) and has EXACTLY the ``(w, h)`` the element was placed on.""" + if page is None or placed_on is None or not template_dims: + return False + n = len(template_dims) + idx = page - 1 + if not 0 <= idx < n: + return False + if anchor is not None and idx != (0 if anchor == "first" else n - 1): + return False + return tuple(placed_on) == tuple(template_dims[idx]) + + +def stamp_placement_applies(stamp, placed_on, template_dims, anchor=None) -> bool: + """Full rule for a ``Stamp``: numbered page, first/last anchor or every + page (then any page of the template may match, or the anchor page when + the batch is forced onto one).""" + if stamp.x is None or stamp.y is None or placed_on is None or not template_dims: + return False + n = len(template_dims) + dims = [tuple(d) for d in template_dims] + po = tuple(placed_on) + if stamp.all_pages: + if anchor is not None: # forced onto the anchor page + return po == dims[0 if anchor == "first" else n - 1] + return po in dims + if stamp.page_anchor is not None: + page = 1 if stamp.page_anchor == "first" else n + else: + page = stamp.page + return page_placement_applies(page, placed_on, template_dims, anchor) + + +# --------------------------------------------------------------------------- +# Model +# --------------------------------------------------------------------------- + +@dataclasses.dataclass +class Placement: # vignette placement + page: int + x: float + y: float + placed_on: tuple[float, float] + + +@dataclasses.dataclass +class Settings: # None = "never set by the user" -> env/defaults apply + language: str | None = None + mode: str | None = None + pades_level: str | None = None + output_dir: str | None = None + azure_vault_url: str | None = None + azure_auth: str | None = None + azure_trust_anchors: str | None = None + vignette: Placement | None = None + + +@dataclasses.dataclass +class Signature: # one library entry + id: str + label: str + stamp: stamplib.Stamp # content + last placement (page target, x, y) + enabled: bool = True + placed_on: tuple[float, float] | None = None # (w, h) of the page it was placed on + + +@dataclasses.dataclass +class Profile: + settings: Settings = dataclasses.field(default_factory=Settings) + signatures: list[Signature] = dataclasses.field(default_factory=list) + + +# --------------------------------------------------------------------------- +# Tolerant parsing helpers (never raise) +# --------------------------------------------------------------------------- + +def _finite(value) -> float | None: + """``value`` as a finite float, else None. A bool is never a number.""" + if isinstance(value, bool) or not isinstance(value, (int, float)): + return None + try: + number = float(value) + except OverflowError: # an integer too large for a float + return None + return number if math.isfinite(number) else None + + +def _finite_pair(value) -> tuple[float, float] | None: + if not isinstance(value, (list, tuple)) or len(value) != 2: + return None + w, h = _finite(value[0]), _finite(value[1]) + return None if w is None or h is None else (w, h) + + +def _parse_vignette(data) -> Placement | None: + if not isinstance(data, dict): + return None + page = data.get("page") + x, y = _finite(data.get("x")), _finite(data.get("y")) + placed_on = _finite_pair(data.get("placed_on")) + if isinstance(page, bool) or not isinstance(page, int) or page < 1: + return None + if x is None or y is None or placed_on is None: + return None + return Placement(page=page, x=x, y=y, placed_on=placed_on) + + +def _parse_settings(data) -> Settings: + if not isinstance(data, dict): + return Settings() + settings = Settings() + for key in _SETTING_KEYS: + if isinstance(data.get(key), str): + setattr(settings, key, data[key]) + settings.vignette = _parse_vignette(data.get("vignette")) + return settings + + +def _resolved(path) -> Path | None: + try: + return Path(path).resolve() + except (OSError, RuntimeError, ValueError): + return None + + +# --------------------------------------------------------------------------- +# Store +# --------------------------------------------------------------------------- + +def _atomic_write(path: Path, data: bytes) -> None: + """Write ``data`` to ``path`` through a temp file in the same directory + + ``os.replace``: a crash mid-write never leaves a truncated file. The file + is created 0600 on POSIX (``mkstemp``).""" + path.parent.mkdir(parents=True, exist_ok=True) + fd, tmp = tempfile.mkstemp(dir=str(path.parent), suffix=".tmp") + try: + with os.fdopen(fd, "wb") as fh: + fh.write(data) + os.replace(tmp, path) + except OSError: + try: + os.unlink(tmp) + except OSError: + pass + raise + + +class ProfileStore: + """Reads and writes one user profile and its image store.""" + + def __init__(self, config_dir=None, data_dir=None): + # Resolved ONCE (the env is read here). Nothing is created on disk. + self.config_dir = resolve_config_dir(config_dir) + self.data_dir = resolve_data_dir(data_dir) + # True while the profile on disk was neither read nor moved aside: + # saving the (empty) in-memory profile would destroy it. + self._keep_file = False + + @property + def profile_path(self) -> Path: + return self.config_dir / PROFILE_FILENAME + + @property + def signatures_dir(self) -> Path: + return self.data_dir / SIGNATURES_DIRNAME + + # -- profile ------------------------------------------------------------ + + def load(self) -> Profile: + """Tolerant load: never raises. See the module docstring.""" + self._keep_file = False + # utf-8-sig: a BOM added by an editor (or PowerShell 5) is not corruption. + try: + raw = self.profile_path.read_text(encoding="utf-8-sig") + except FileNotFoundError: + return Profile() + except OSError: + self._keep_file = True # unreadable: left alone + return Profile() + except ValueError: # UnicodeDecodeError + return self._set_aside() + try: + data = json.loads(raw) + except (ValueError, RecursionError): # bad JSON / pathological nesting + return self._set_aside() + if not isinstance(data, dict): + return self._set_aside() + version = data.get("version") + if isinstance(version, bool) or not isinstance(version, int): + return self._set_aside() + if version != PROFILE_VERSION: + return self._set_aside() # e.g. written by a newer Cachet + + profile = Profile(settings=_parse_settings(data.get("settings"))) + entries = data.get("signatures") + used_ids: set[str] = set() + for entry in entries if isinstance(entries, list) else []: + sig = self._parse_signature(entry, used_ids) + if sig is not None: + used_ids.add(sig.id) + profile.signatures.append(sig) + return profile + + def _set_aside(self) -> Profile: + """Move an unusable profile to ``profile.json.bak`` and start afresh.""" + try: + os.replace(self.profile_path, self.profile_path.with_name(PROFILE_FILENAME + ".bak")) + except OSError: + self._keep_file = True # still in place: not to be overwritten + return Profile() + + def _parse_signature(self, entry, used_ids: set[str]) -> Signature | None: + """One library entry, or None when it has to be skipped.""" + if not isinstance(entry, dict): + return None + try: + stamp = stamplib.Stamp.from_dict(entry, base_dir=self.signatures_dir) + except stamplib.StampError: + return None + try: + stamplib.validate_stamp(stamp, placed=False) + except stamplib.StampError as exc: + # Malformed content is dropped; a missing image/font file is kept + # (shown as unusable, the user can delete it). + if not str(exc).startswith(_MISSING_FILE_PREFIXES): + return None + + placed_on = None + try: + stamplib.validate_placement(stamp) + placed_on = _finite_pair(entry.get("placed_on")) + except stamplib.StampError: + # Unplaced, or an incomplete/invalid placement: cleared. The one + # exception is an unplaced signature that remembers "every page". + remembers_all_pages = ( + stamp.all_pages and stamp.page is None and stamp.page_anchor is None + and stamp.x is None and stamp.y is None) + if not remembers_all_pages: + stamp = dataclasses.replace( + stamp, page=None, page_anchor=None, all_pages=False, x=None, y=None) + + sig_id = entry.get("id") + if not is_valid_id(sig_id) or sig_id in used_ids: + sig_id = new_id() + while sig_id in used_ids: + sig_id = new_id() + label = entry.get("label") + if not isinstance(label, str) or not label.strip(): + label = stamp.content_label() + if stamp.kind == "text": + label = label[1:-1] # without the quotes + enabled = entry.get("enabled") + return Signature( + id=sig_id, label=label[:MAX_LABEL_LEN], stamp=stamp, + enabled=enabled if isinstance(enabled, bool) else True, + placed_on=placed_on) + + def _payload(self, profile: Profile) -> dict: + settings: dict = {} + for key in _SETTING_KEYS: + value = getattr(profile.settings, key) + if value is not None: + settings[key] = value + v = profile.settings.vignette + if v is not None: + settings["vignette"] = { + "page": v.page, "x": v.x, "y": v.y, "placed_on": list(v.placed_on)} + signatures = [] + for sig in profile.signatures: + entry = {"id": sig.id, "label": sig.label, "enabled": sig.enabled} + entry.update(sig.stamp.to_dict(base_dir=self.signatures_dir)) + if sig.placed_on is not None: + entry["placed_on"] = list(sig.placed_on) + signatures.append(entry) + return {"version": PROFILE_VERSION, "settings": settings, "signatures": signatures} + + def save(self, profile: Profile) -> None: + """Atomic write of ``profile.json`` (UTF-8, no BOM). Raises ``OSError`` + — also when the last ``load()`` had to leave an unusable file in place.""" + if self._keep_file: + raise OSError(f"{self.profile_path} could not be read and is left untouched") + text = json.dumps(self._payload(profile), ensure_ascii=False, indent=2) + # A lone surrogate (a folder name that is not valid UTF-8, a "\ud800" + # typed into the file) cannot be encoded: backslashreplace writes it + # as \udXXX, which is precisely its JSON escape — the file stays valid + # UTF-8, loads back identically, and save never raises a ValueError. + _atomic_write(self.profile_path, text.encode("utf-8", errors="backslashreplace")) + + # -- image store -------------------------------------------------------- + + def _store_bytes(self, data: bytes, ext: str) -> Path: + """Content-addressed write: the same bytes always land in the same + file, which is left untouched when it already exists.""" + target = self.signatures_dir / f"{hashlib.sha256(data).hexdigest()[:32]}{ext}" + if not target.exists(): + _atomic_write(target, data) + return target + + def import_image(self, source) -> Path: + """Copy an image file into the store and return the stored path. + ``StampError`` if it is not a readable image (nothing is written), + ``OSError`` if the copy cannot be written.""" + source = Path(source) + stamplib.load_image(source) # validate first + ext = source.suffix.lower() + return self._store_bytes( + source.read_bytes(), ext if ext in _IMAGE_EXTENSIONS else ".img") + + def store_image(self, image) -> Path: + """Store a PIL image (a drawn signature) as a PNG; returns its path.""" + buf = io.BytesIO() + image.save(buf, format="PNG") + return self._store_bytes(buf.getvalue(), ".png") + + def is_store_file(self, path) -> bool: + """THE predicate for "this file belongs to the image store": not a + symlink, a DIRECT child of ``signatures_dir`` by RESOLVED paths + (pathlib's ``is_relative_to`` is lexical: ``dir/../../x`` would count + as inside), and a content-addressed name.""" + try: + path = Path(path) + if path.is_symlink(): + return False + resolved = path.resolve() + return (resolved.parent == self.signatures_dir.resolve() + and _STORE_NAME_RE.fullmatch(resolved.name) is not None) + except (OSError, RuntimeError, ValueError): + return False + + def remove_signature(self, profile: Profile, sig_id: str) -> None: + """Remove a library entry (no-op if absent) and, when it was an image + living in the store that no REMAINING signature references, its file. + Anything that is not a store file is never unlinked. Does NOT save.""" + for index, sig in enumerate(profile.signatures): + if sig.id == sig_id: + break + else: + return + del profile.signatures[index] + path = sig.stamp.image_path + if sig.stamp.kind != "image" or path is None or not self.is_store_file(path): + return + target = _resolved(path) + if target is None: + return + for other in profile.signatures: + other_path = other.stamp.image_path + if (other.stamp.kind == "image" and other_path is not None + and _resolved(other_path) == target): + return # still in use + try: + target.unlink() + except OSError: + pass diff --git a/test_profile_store.py b/test_profile_store.py new file mode 100644 index 0000000..7416cce --- /dev/null +++ b/test_profile_store.py @@ -0,0 +1,933 @@ +#!/usr/bin/env python3 +"""Headless tests for profile_store.py (user profile + signature image store). + +Every test works in its own TemporaryDirectory with EXPLICIT directories: +nothing here may read or write the real user profile. +Run with: ./venv/bin/python -m unittest -v test_profile_store +""" + +import dataclasses +import hashlib +import json +import os +import tempfile +import unittest +from pathlib import Path +from unittest import mock + +from PIL import Image + +import profile_store +import stamps as stamplib +from profile_store import Placement, Profile, ProfileStore, Settings, Signature +from stamps import Stamp +from test_sign_pdfs_beid import make_png +from test_stamps import damaged_font + +A4 = (595.0, 842.0) +LETTER = (612.0, 792.0) +SETTING_KEYS = {"language", "mode", "pades_level", "output_dir", "azure_vault_url", + "azure_auth", "azure_trust_anchors", "vignette"} + + +class StoreCase(unittest.TestCase): + def setUp(self): + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + self.tmp = Path(tmp.name) + self.store = ProfileStore(config_dir=self.tmp / "cfg", data_dir=self.tmp / "data") + + def write_profile(self, content) -> Path: + """Put `content` (bytes, text or a JSON-able object) in place of profile.json.""" + path = self.store.profile_path + path.parent.mkdir(parents=True, exist_ok=True) + if isinstance(content, bytes): + path.write_bytes(content) + else: + path.write_text(content if isinstance(content, str) else json.dumps(content), + encoding="utf-8") + return path + + def load_signatures(self, entries) -> list: + self.write_profile({"version": 1, "signatures": entries}) + return self.store.load().signatures + + def assert_set_aside(self, original: bytes): + """The unusable file went to profile.json.bak, byte for byte.""" + bak = self.store.profile_path.with_name("profile.json.bak") + self.assertFalse(self.store.profile_path.exists()) + self.assertEqual(bak.read_bytes(), original) + + def text_entry(self, **extra) -> dict: + return {"kind": "text", "text": "Jane Doe", **extra} + + +class Dirs(unittest.TestCase): + def setUp(self): + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + self.tmp = Path(tmp.name) + + def env(self, **values): + """os.environ without the two override variables, plus `values`.""" + patcher = mock.patch.dict(os.environ, values) + patcher.start() + self.addCleanup(patcher.stop) + for name in (profile_store.ENV_CONFIG_DIR, profile_store.ENV_DATA_DIR): + if name not in values: + os.environ.pop(name, None) + + def test_env_override(self): + self.env(CACHET_CONFIG_DIR=str(self.tmp / "c"), CACHET_DATA_DIR=str(self.tmp / "d")) + self.assertEqual(profile_store.resolve_config_dir(), self.tmp / "c") + self.assertEqual(profile_store.resolve_data_dir(), self.tmp / "d") + + def test_explicit_argument_beats_env(self): + self.env(CACHET_CONFIG_DIR=str(self.tmp / "c"), CACHET_DATA_DIR=str(self.tmp / "d")) + self.assertEqual(profile_store.resolve_config_dir(self.tmp / "x"), self.tmp / "x") + self.assertEqual(profile_store.resolve_data_dir(str(self.tmp / "y")), self.tmp / "y") + + def test_default_uses_platformdirs(self): + import platformdirs + + self.env(CACHET_CONFIG_DIR="", CACHET_DATA_DIR="") # empty = not set + with mock.patch.object(platformdirs, "user_config_dir", + return_value=str(self.tmp / "pc")) as cfg, \ + mock.patch.object(platformdirs, "user_data_dir", + return_value=str(self.tmp / "pd")) as data: + self.assertEqual(profile_store.resolve_config_dir(), self.tmp / "pc") + self.assertEqual(profile_store.resolve_data_dir(), self.tmp / "pd") + store = ProfileStore() + cfg.assert_called_with("Cachet", appauthor=False) + data.assert_called_with("Cachet", appauthor=False) + self.assertEqual((store.config_dir, store.data_dir), (self.tmp / "pc", self.tmp / "pd")) + self.assertEqual(list(self.tmp.iterdir()), []) # nothing created on disk + + def test_constructor_creates_nothing(self): + store = ProfileStore(config_dir=self.tmp / "cfg", data_dir=self.tmp / "data") + self.assertEqual(store.profile_path, self.tmp / "cfg" / "profile.json") + self.assertEqual(store.signatures_dir, self.tmp / "data" / "signatures") + self.assertEqual(store.load(), Profile()) # loading creates nothing either + self.assertEqual(list(self.tmp.iterdir()), []) + + def test_default_constructor_reads_env(self): + # Regression: parameters named config_dir/data_dir must not shadow the + # module-level resolvers (hence their resolve_ prefix). + self.env(CACHET_CONFIG_DIR=str(self.tmp / "c"), CACHET_DATA_DIR=str(self.tmp / "d")) + store = ProfileStore() + self.assertEqual((store.config_dir, store.data_dir), (self.tmp / "c", self.tmp / "d")) + # resolved ONCE: a later change of the environment does not move the store + os.environ[profile_store.ENV_CONFIG_DIR] = str(self.tmp / "other") + self.assertEqual(store.config_dir, self.tmp / "c") + + def test_constructor_keywords(self): + self.env(CACHET_CONFIG_DIR=str(self.tmp / "c"), CACHET_DATA_DIR=str(self.tmp / "d")) + store = ProfileStore(config_dir=self.tmp / "a", data_dir=self.tmp / "b") + self.assertEqual((store.config_dir, store.data_dir), (self.tmp / "a", self.tmp / "b")) + mixed = ProfileStore(data_dir=self.tmp / "b") + self.assertEqual((mixed.config_dir, mixed.data_dir), (self.tmp / "c", self.tmp / "b")) + + def test_ids(self): + ids = {profile_store.new_id() for _ in range(50)} + self.assertEqual(len(ids), 50) + self.assertTrue(all(profile_store.is_valid_id(i) for i in ids)) + for bad in ("vignette", "", "0123456789a", "0123456789abc", "0123456789AB", + "0123456789ag", 123456789012, None, b"0123456789ab"): + with self.subTest(bad=bad): + self.assertFalse(profile_store.is_valid_id(bad)) + + +class LoadSave(StoreCase): + def full_profile(self) -> Profile: + stored = self.store.store_image(Image.new("RGBA", (40, 20), (0, 0, 255, 200))) + return Profile( + settings=Settings( + language="fr", mode="azure", pades_level="b-lt", output_dir="/home/jane/signed", + azure_vault_url="https://myorg-sign.vault.azure.net", azure_auth="interactive", + azure_trust_anchors="/home/jane/ca-chain.pem", + vignette=Placement(page=2, x=380.0, y=60.5, placed_on=A4)), + signatures=[ + Signature(id="3f9a1c0b77de", label="Sébastien", placed_on=A4, stamp=Stamp( + kind="text", text="Sébastien\nRead and approved, {date}", font="caveat", + color="#AA0000", font_size=18.0, page=2, x=360.0, y=120.25)), + Signature(id="b20c55e19a04", label="Initials", placed_on=LETTER, stamp=Stamp( + kind="image", image_path=stored, width_pt=60.0, all_pages=True, + x=540.0, y=20.0)), + Signature(id="77aa01f3c2d9", label="Company stamp", enabled=False, stamp=Stamp( + kind="image", image_path=stored, width_pt=150.0)), + ]) + + def test_missing_file_gives_defaults(self): + profile = self.store.load() + self.assertEqual(profile, Profile()) + self.assertEqual(profile.signatures, []) + self.assertTrue(all(v is None for v in dataclasses.asdict(profile.settings).values())) + self.assertFalse(self.store.config_dir.exists()) + + def test_roundtrip(self): + profile = self.full_profile() + self.store.save(profile) + first = self.store.profile_path.read_bytes() + loaded = self.store.load() + self.assertEqual(loaded, profile) + self.assertIsInstance(loaded.signatures[0].placed_on, tuple) + self.assertIsInstance(loaded.settings.vignette.placed_on, tuple) + # save -> load -> save is stable, and a fresh store reads the same thing + self.store.save(loaded) + self.assertEqual(self.store.profile_path.read_bytes(), first) + again = ProfileStore(config_dir=self.store.config_dir, data_dir=self.store.data_dir) + self.assertEqual(again.load(), profile) + self.assertFalse(self.store.profile_path.with_name("profile.json.bak").exists()) + + def test_saved_json_shape(self): + self.store.save(self.full_profile()) + raw = self.store.profile_path.read_bytes() + self.assertFalse(raw.startswith(b"\xef\xbb\xbf")) # UTF-8, no BOM + self.assertIn("Sébastien".encode("utf-8"), raw) # not \u-escaped + data = json.loads(raw.decode("utf-8")) + self.assertEqual(set(data), {"version", "settings", "signatures"}) + self.assertEqual(data["version"], 1) + self.assertEqual(set(data["settings"]), SETTING_KEYS) + self.assertEqual(data["settings"]["vignette"], + {"page": 2, "x": 380.0, "y": 60.5, "placed_on": [595.0, 842.0]}) + + def keys(node): + if isinstance(node, dict): + for key, value in node.items(): + yield key + yield from keys(value) + elif isinstance(node, list): + for value in node: + yield from keys(value) + + for key in keys(data): + for banned in ("pin", "token", "password", "secret", "key_name", "upn"): + self.assertNotIn(banned, key.lower()) + text, image, unplaced = data["signatures"] + self.assertEqual(text, { + "id": "3f9a1c0b77de", "label": "Sébastien", "enabled": True, "kind": "text", + "text": "Sébastien\nRead and approved, {date}", "font": "caveat", "color": "#AA0000", + "font_size": 18.0, "page": 2, "x": 360.0, "y": 120.25, "placed_on": [595.0, 842.0]}) + # a stored image is written as its bare, content-addressed file name + self.assertRegex(image["image_path"], r"^[0-9a-f]{32}\.png$") + self.assertEqual(set(image), {"id", "label", "enabled", "kind", "image_path", "width_pt", + "all_pages", "x", "y", "placed_on"}) + self.assertEqual(set(unplaced), {"id", "label", "enabled", "kind", "image_path", + "width_pt"}) + # only the settings that were set are written + self.store.save(Profile(settings=Settings(language="nl"))) + self.assertEqual(json.loads(self.store.profile_path.read_text(encoding="utf-8")), + {"version": 1, "settings": {"language": "nl"}, "signatures": []}) + + def test_external_image_written_absolute(self): + outside = make_png(self.tmp / "elsewhere.png") + self.store.save(Profile(signatures=[Signature( + id="0123456789ab", label="x", stamp=Stamp(kind="image", image_path=outside))])) + data = json.loads(self.store.profile_path.read_text(encoding="utf-8")) + self.assertEqual(data["signatures"][0]["image_path"], str(outside)) + self.assertEqual(self.store.load().signatures[0].stamp.image_path, outside) + + def test_corrupt_json_moved_to_bak(self): + original = b'{"version": 1, "signatures": [' + self.write_profile(original) + self.assertEqual(self.store.load(), Profile()) + self.assert_set_aside(original) + # a second corrupt file replaces the older .bak + self.write_profile(b"again{") + self.assertEqual(self.store.load(), Profile()) + self.assert_set_aside(b"again{") + + def test_non_object_top_level_is_corrupt(self): + for content in ("[]", '"x"', "3", "null"): + with self.subTest(content=content): + self.write_profile(content) + self.assertEqual(self.store.load(), Profile()) + self.assert_set_aside(content.encode()) + + def test_missing_version_is_corrupt(self): + for content in ({"settings": {"language": "fr"}}, {"version": "1"}, {"version": 1.0}, + {"version": None}): + with self.subTest(content=content): + path = self.write_profile(content) + original = path.read_bytes() + self.assertEqual(self.store.load(), Profile()) + self.assert_set_aside(original) + + def test_unknown_version_moved_to_bak(self): + path = self.write_profile({"version": 2, "settings": {"language": "fr"}, + "signatures": [self.text_entry()]}) + original = path.read_bytes() + self.assertEqual(self.store.load(), Profile()) + self.assert_set_aside(original) + # so a later save cannot destroy the newer profile + self.store.save(Profile(settings=Settings(language="en"))) + self.assert_bak_kept(original) + + def assert_bak_kept(self, original: bytes): + self.assertEqual(self.store.profile_path.with_name("profile.json.bak").read_bytes(), + original) + self.assertTrue(self.store.profile_path.exists()) + + def test_bad_entry_skipped_others_kept(self): + sigs = self.load_signatures([ + self.text_entry(label="first"), + "not an object", + None, + {"text": "no kind"}, + {"kind": "sticker", "text": "x"}, + {"kind": "text", "text": " "}, + {"kind": "text", "text": "x", "font_size": "big"}, + {"kind": "text", "text": "x", "font_size": 0}, + {"kind": "text", "text": "x", "color": "blue"}, + {"kind": "image"}, + {"kind": "image", "image_path": 5}, + self.text_entry(label="last"), + ]) + self.assertEqual([s.label for s in sigs], ["first", "last"]) + self.assertTrue(self.store.profile_path.exists()) # not set aside + + def test_missing_image_entry_kept(self): + name = "9c1185a5c5e9fc54612808977ee8f548.png" + sigs = self.load_signatures([ + {"kind": "image", "image_path": name, "width_pt": 60, "label": "Initials", + "page": 2, "x": 540, "y": 20, "placed_on": [595, 842]}, + {"kind": "text", "text": "Jane", "font": "/nowhere/mine.ttf", + "all_pages": True, "x": 1, "y": 2, "placed_on": [595, 842]}, + ]) + self.assertEqual(len(sigs), 2) # unusable, but deletable + image, text = sigs + self.assertEqual(image.stamp.image_path, self.store.signatures_dir / name) + self.assertEqual(text.stamp.font, "/nowhere/mine.ttf") + with self.assertRaises(stamplib.StampError): + stamplib.validate_stamp(image.stamp, placed=False) + # the content is unusable NOW; its valid placement is not thrown away + self.assertEqual((image.stamp.page, image.stamp.x, image.stamp.y), (2, 540.0, 20.0)) + self.assertEqual(image.placed_on, A4) + self.assertTrue(text.stamp.all_pages) + self.assertEqual(text.placed_on, A4) + # save -> load is an identity for it as well + before = self.store.load() + self.store.save(before) + self.assertEqual(self.store.load(), before) + + def test_half_placement_cleared(self): + sigs = self.load_signatures([ + self.text_entry(page=1, x=10, placed_on=[595, 842]), # x without y + self.text_entry(page=1, page_anchor="last", x=1, y=2), # two targets + self.text_entry(page=3, placed_on=[595, 842]), # no position + self.text_entry(page=0, x=1, y=2), # page < 1 + self.text_entry(page_anchor="middle", x=1, y=2), # unknown anchor + self.text_entry(x=1, y=2, placed_on=[595, 842]), # no target + self.text_entry(all_pages=True, x=1), # all pages, half + self.text_entry(), # never placed + ]) + self.assertEqual(len(sigs), 8) + for sig in sigs: + with self.subTest(sig=sig): + self.assertEqual(sig.stamp, Stamp(kind="text", text="Jane Doe")) + self.assertFalse(sig.stamp.is_placed) + self.assertIsNone(sig.placed_on) + + def test_wrong_typed_settings_dropped(self): + self.write_profile({"version": 1, "settings": { + "language": 5, "mode": ["beid"], "pades_level": "b-t", "output_dir": None, + "azure_vault_url": {"a": 1}, "azure_auth": True, "azure_trust_anchors": 1.5, + "vignette": "bottom", "unknown": "ignored"}}) + self.assertEqual(self.store.load().settings, Settings(pades_level="b-t")) + for settings in ("x", [], 3, None): + with self.subTest(settings=settings): + self.write_profile({"version": 1, "settings": settings, "signatures": "nope"}) + self.assertEqual(self.store.load(), Profile()) + self.assertTrue(self.store.profile_path.exists()) # tolerated, not corrupt + + def test_duplicate_and_missing_ids_regenerated(self): + sigs = self.load_signatures([ + self.text_entry(id="0123456789ab"), + self.text_entry(id="0123456789ab"), + self.text_entry(), + self.text_entry(id="aaaaaaaaaaaa"), + ]) + ids = [s.id for s in sigs] + self.assertEqual((ids[0], ids[3]), ("0123456789ab", "aaaaaaaaaaaa")) # first one wins + self.assertEqual(len(set(ids)), 4) + self.assertTrue(all(profile_store.is_valid_id(i) for i in ids)) + + def test_save_is_atomic(self): + self.store.save(Profile(settings=Settings(language="fr"))) + before = self.store.profile_path.read_bytes() + with mock.patch("profile_store.os.replace", side_effect=OSError("disk full")): + with self.assertRaises(OSError): + self.store.save(Profile(settings=Settings(language="de"))) + self.assertEqual(self.store.profile_path.read_bytes(), before) + self.assertEqual([p.name for p in self.store.config_dir.iterdir()], ["profile.json"]) + self.assertEqual(self.store.load().settings.language, "fr") + + def test_save_creates_parent_dirs(self): + store = ProfileStore(config_dir=self.tmp / "a" / "b" / "cfg", data_dir=self.tmp / "data") + store.save(Profile(settings=Settings(mode="image"))) + self.assertEqual(store.load().settings.mode, "image") + self.assertFalse((self.tmp / "data").exists()) # only what is needed + + @unittest.skipUnless(os.name == "posix", "POSIX file modes") + def test_file_mode_0600(self): + self.store.save(Profile(settings=Settings(language="fr"))) + self.assertEqual(self.store.profile_path.stat().st_mode & 0o777, 0o600) + self.store.save(Profile(settings=Settings(language="nl"))) # replacing keeps it private + self.assertEqual(self.store.profile_path.stat().st_mode & 0o777, 0o600) + stored = self.store.store_image(Image.new("RGBA", (4, 4))) + self.assertEqual(stored.stat().st_mode & 0o777, 0o600) + + def test_load_never_raises_on_unreadable(self): + self.store.profile_path.mkdir(parents=True) # a directory in its place + self.assertEqual(self.store.load(), Profile()) + self.assertTrue(self.store.profile_path.is_dir()) # left alone + self.assertEqual([p.name for p in self.store.config_dir.iterdir()], ["profile.json"]) + + def test_save_refused_after_unreadable_load(self): + # readable again later (a transient I/O error, a file owned by another + # user): saving the EMPTY profile that load() fell back to would + # destroy the library + self.store.save(Profile(signatures=[ + Signature(id="0123456789ab", label="Jane", stamp=Stamp(kind="text", text="Jane"))])) + before = self.store.profile_path.read_bytes() + with mock.patch.object(Path, "read_text", side_effect=PermissionError(13, "denied")): + profile = self.store.load() + self.assertEqual(profile, Profile()) + profile.settings.language = "fr" + with self.assertRaises(OSError): + self.store.save(profile) + self.assertEqual(self.store.profile_path.read_bytes(), before) + self.assertEqual([p.name for p in self.store.config_dir.iterdir()], ["profile.json"]) + # the next successful load lifts the refusal + profile = self.store.load() + self.assertEqual([sig.label for sig in profile.signatures], ["Jane"]) + profile.settings.language = "fr" + self.store.save(profile) + self.assertEqual(self.store.load().settings.language, "fr") + + def test_save_refused_when_set_aside_failed(self): + newer = json.dumps({"version": 2, "signatures": [{"future": True}]}).encode() + self.write_profile(newer) + bak = self.store.profile_path.with_name("profile.json.bak") + (bak / "keep").mkdir(parents=True) # the .bak slot is unusable + self.assertEqual(self.store.load(), Profile()) + self.assertEqual(self.store.profile_path.read_bytes(), newer) # still in place + with self.assertRaises(OSError): + self.store.save(Profile(settings=Settings(language="fr"))) + self.assertEqual(self.store.profile_path.read_bytes(), newer) + + def test_utf8_bom_is_not_corruption(self): + self.store.save(Profile(settings=Settings(language="nl"), signatures=[ + Signature(id="0123456789ab", label="Jane", stamp=Stamp(kind="text", text="Jane"))])) + path = self.store.profile_path + path.write_bytes(b"\xef\xbb\xbf" + path.read_bytes()) # e.g. PowerShell 5 + profile = self.store.load() + self.assertEqual(profile.settings.language, "nl") + self.assertEqual([sig.label for sig in profile.signatures], ["Jane"]) + self.assertEqual([p.name for p in self.store.config_dir.iterdir()], ["profile.json"]) + self.store.save(profile) # written back without it + self.assertFalse(path.read_bytes().startswith(b"\xef\xbb\xbf")) + + def test_binary_garbage_is_corrupt(self): + garbage = b"\xff\xfe\x00garbage" + self.write_profile(garbage) + self.assertEqual(self.store.load(), Profile()) + self.assert_set_aside(garbage) + + def test_deeply_nested_json_is_corrupt(self): + deep = "[" * 200000 + self.write_profile(deep) + self.assertEqual(self.store.load(), Profile()) # no RecursionError + self.assert_set_aside(deep.encode()) + + def test_bool_version_is_corrupt(self): + path = self.write_profile('{"version": true, "settings": {"language": "fr"}}') + original = path.read_bytes() + self.assertEqual(self.store.load(), Profile()) + self.assert_set_aside(original) + + def test_bad_id_types_regenerated(self): + bad_ids = [5, "vignette", "XYZ", "0123456789AB", None, ["a"], ""] + sigs = self.load_signatures( + [self.text_entry(id=bad) for bad in bad_ids] + [self.text_entry(id="0a1b2c3d4e5f")]) + self.assertEqual(len(sigs), len(bad_ids) + 1) + for sig, bad in zip(sigs, bad_ids): + with self.subTest(bad=bad): + self.assertNotEqual(sig.id, bad) + self.assertTrue(profile_store.is_valid_id(sig.id)) + self.assertEqual(sigs[-1].id, "0a1b2c3d4e5f") + self.assertEqual(len({s.id for s in sigs}), len(sigs)) + + def test_bad_label_replaced_and_long_label_truncated(self): + stored = self.store.store_image(Image.new("RGBA", (4, 4))) + sigs = self.load_signatures([ + self.text_entry(label=5), + self.text_entry(label=" "), + self.text_entry(), + {"kind": "text", "text": '"quoted"', "label": None}, + {"kind": "image", "image_path": stored.name, "label": ["x"]}, + self.text_entry(label="L" * 300), + {"kind": "text", "text": "T" * 200}, + self.text_entry(label=" Kept as typed "), + ]) + self.assertEqual([s.label for s in sigs[:5]], + ["Jane Doe", "Jane Doe", "Jane Doe", '"quoted"', stored.name]) + self.assertEqual(sigs[5].label, "L" * 80) + self.assertEqual(sigs[6].label, "T" * 30 + "…") + self.assertEqual(sigs[7].label, " Kept as typed ") + + def test_non_finite_placement_cleared(self): + self.write_profile( + '{"version": 1, "signatures": [' + '{"kind": "text", "text": "a", "page": 1, "x": NaN, "y": 2, "placed_on": [595, 842]},' + '{"kind": "text", "text": "b", "page": 1, "x": 1, "y": Infinity},' + '{"kind": "text", "text": "c", "all_pages": true, "x": -Infinity, "y": 2},' + '{"kind": "text", "text": "d", "page": 1, "x": 1e999, "y": 2}]}') + sigs = self.store.load().signatures + self.assertEqual([s.stamp.text for s in sigs], ["a", "b", "c", "d"]) # all kept + for sig in sigs: + self.assertEqual(sig.stamp, Stamp(kind="text", text=sig.stamp.text)) + self.assertIsNone(sig.placed_on) + + def test_huge_integers_never_raise(self): + huge = "1" + "0" * 400 # too large for a float + self.write_profile( + '{"version": 1, "settings": {"vignette": {"page": 1, "x": %s, "y": 2, ' + '"placed_on": [595, 842]}}, "signatures": [' + '{"kind": "text", "text": "a", "page": 1, "x": %s, "y": 2},' + '{"kind": "text", "text": "b", "page": %s, "x": 1, "y": 2, "placed_on": [%s, 842]},' + '{"kind": "text", "text": "c", "page": 1, "x": 1, "y": 2, "placed_on": [595, 842]}]}' + % (huge, huge, huge, huge)) + profile = self.store.load() + self.assertIsNone(profile.settings.vignette) + # a: not a number -> skipped; b: kept, its placed_on dropped; c: untouched + self.assertEqual([s.stamp.text for s in profile.signatures], ["b", "c"]) + self.assertIsNone(profile.signatures[0].placed_on) + self.assertEqual(profile.signatures[1].placed_on, A4) + self.assertFalse(profile_store.stamp_placement_applies( + profile.signatures[0].stamp, A4, [A4])) + self.store.save(profile) # still serialisable + + def test_hostile_paths_never_raise(self): + # an unknown ~user (RuntimeError in pathlib) and an over-long name + # (OSError): both are just files that are not there + # a NUL or a lone surrogate (ValueError in Path.resolve) must not make + # the NEXT save raise either + sigs = self.load_signatures([ + {"kind": "image", "image_path": "~no_such_user_zz/sig.png"}, + {"kind": "image", "image_path": "x" * 5000 + ".png"}, + {"kind": "image", "image_path": "a\x00b.png"}, + {"kind": "image", "image_path": "\ud800.png"}, + {"kind": "text", "text": "a", "font": "~no_such_user_zz/f.ttf"}, + {"kind": "text", "text": "b", "font": "x" * 5000}, + {"kind": "text", "text": "c", "font": "\ud800\x00.ttf"}, + self.text_entry(label="fine"), + ]) + self.assertEqual(len(sigs), 8) # kept, unusable + profile = Profile(signatures=list(sigs)) + self.store.save(profile) + self.assertEqual(self.store.load(), profile) + for sig in sigs[:4]: + self.assertFalse(self.store.is_store_file(sig.stamp.image_path)) + self.store.remove_signature(profile, sig.id) # deletable, harmlessly + self.assertEqual(len(profile.signatures), 4) + + def test_damaged_font_entry_kept(self): + # a font file FreeType opens but fails on (OSError while measuring): + # load must not raise; the entry is kept like any unusable font + font = damaged_font(self.tmp / "damaged.ttf") + sigs = self.load_signatures([ + self.text_entry(label="before"), + self.text_entry(label="damaged", font=str(font), page=1, x=1, y=2, + placed_on=[595, 842]), + self.text_entry(label="after"), + ]) + self.assertEqual([s.label for s in sigs], ["before", "damaged", "after"]) + self.assertEqual(sigs[1].stamp.font, str(font)) + self.assertEqual(sigs[1].placed_on, A4) # placement not thrown away + with self.assertRaises(stamplib.StampError) as cm: + stamplib.validate_stamp(sigs[1].stamp, placed=False) + self.assertTrue(str(cm.exception).startswith("cannot load font ")) + + def test_lone_surrogate_roundtrips(self): + # e.g. an output folder whose name is not valid UTF-8 (surrogateescape), + # or a "\ud800" escape typed into the file: save must not raise a + # ValueError, and the file must stay loadable UTF-8. + self.write_profile('{"version": 1, "settings": {"output_dir": "/data/caf\\udce9"}, ' + '"signatures": [{"kind": "text", "text": "J\\ud800D \\\\ é", ' + '"label": "L\\udfff", "id": "0123456789ab"}]}') + profile = self.store.load() + self.assertEqual(profile.settings.output_dir, "/data/caf\udce9") + self.assertEqual(profile.signatures[0].stamp.text, "J\ud800D \\ é") + self.store.save(profile) + raw = self.store.profile_path.read_bytes() + raw.decode("utf-8") # valid UTF-8 + self.assertIn("é".encode("utf-8"), raw) # the rest is not escaped + self.assertEqual(self.store.load(), profile) + self.assertFalse(self.store.profile_path.with_name("profile.json.bak").exists()) + + def test_bad_placed_on_dropped_placement_kept(self): + bad_values = ["x", [595], [595, "842"], [595, 842, 1], [True, 842], None, {"w": 1}] + entries = [self.text_entry(page=2, x=10, y=20, placed_on=bad) for bad in bad_values] + self.write_profile(json.dumps({"version": 1, "signatures": entries})[:-2] + + ', {"kind": "text", "text": "Jane Doe", "page": 2, "x": 10, ' + '"y": 20, "placed_on": [NaN, 842]}]}') + sigs = self.store.load().signatures + self.assertEqual(len(sigs), len(bad_values) + 1) + for sig in sigs: + self.assertEqual(sig.stamp, Stamp(kind="text", text="Jane Doe", page=2, x=10.0, y=20.0)) + self.assertIsNone(sig.placed_on) # simply not in force + good = self.load_signatures([self.text_entry(page=2, x=10, y=20, placed_on=[595, 842])]) + self.assertEqual(good[0].placed_on, A4) + + def test_all_pages_without_position_roundtrips(self): + profile = Profile(signatures=[Signature( + id="0123456789ab", label="Initials", stamp=Stamp(kind="text", text="JD", + all_pages=True))]) + self.store.save(profile) + loaded = self.store.load() + self.assertEqual(loaded, profile) + stamp = loaded.signatures[0].stamp + self.assertTrue(stamp.all_pages) + self.assertIsNone(stamp.x) + self.assertIsNone(stamp.y) + + def test_oversized_text_entry_skipped(self): + sigs = self.load_signatures([ + self.text_entry(label="before"), + {"kind": "text", "text": "W" * 2000, "font": "lato", "font_size": 400}, + self.text_entry(label="after"), + ]) + self.assertEqual([s.label for s in sigs], ["before", "after"]) + + def test_non_finite_vignette_dropped(self): + good = '{"page": 2, "x": 380, "y": 60, "placed_on": [595, 842]}' + self.write_profile('{"version": 1, "settings": {"vignette": %s}}' % good) + self.assertEqual(self.store.load().settings.vignette, + Placement(page=2, x=380.0, y=60.0, placed_on=A4)) + for bad in ('{"page": 2, "x": NaN, "y": 60, "placed_on": [595, 842]}', + '{"page": 2, "x": 380, "y": Infinity, "placed_on": [595, 842]}', + '{"page": 2, "x": 380, "y": 60, "placed_on": [NaN, 842]}', + '{"page": 2, "x": 380, "y": 60, "placed_on": [595]}', + '{"page": 2, "x": 380, "y": 60}', + '{"page": 0, "x": 380, "y": 60, "placed_on": [595, 842]}', + '{"page": true, "x": 380, "y": 60, "placed_on": [595, 842]}', + '{"page": 2.0, "x": 380, "y": 60, "placed_on": [595, 842]}', + '{"page": 2, "x": true, "y": 60, "placed_on": [595, 842]}', + '{"page": 2, "x": "380", "y": 60, "placed_on": [595, 842]}', + '{"x": 380, "y": 60, "placed_on": [595, 842]}', + '[2, 380, 60]', '"bottom-right"'): + with self.subTest(vignette=bad): + self.write_profile( + '{"version": 1, "settings": {"language": "fr", "vignette": %s}}' % bad) + settings = self.store.load().settings + self.assertIsNone(settings.vignette) + self.assertEqual(settings.language, "fr") # the rest is kept + + def test_incomplete_vignette_cannot_be_built(self): + # save() writes a vignette as it is: a partial one must not exist at all + with self.assertRaises(TypeError): + Placement(page=1, x=5.0) + + +class ImageStore(StoreCase): + def image_sig(self, path, sig_id="0123456789ab") -> Signature: + return Signature(id=sig_id, label="img", stamp=Stamp(kind="image", image_path=path)) + + def stored(self, color=(0, 0, 255, 255)) -> Path: + return self.store.store_image(Image.new("RGBA", (8, 8), color)) + + def test_import_is_content_addressed(self): + src = make_png(self.tmp / "My Signature.PNG") + stored = self.store.import_image(src) + digest = hashlib.sha256(src.read_bytes()).hexdigest() + self.assertEqual(stored, self.store.signatures_dir / f"{digest[:32]}.png") + self.assertEqual(stored.read_bytes(), src.read_bytes()) + self.assertTrue(self.store.is_store_file(stored)) + # the same bytes under another name: one file, left untouched + mtime = stored.stat().st_mtime_ns + copy = self.tmp / "copy.png" + copy.write_bytes(src.read_bytes()) + self.assertEqual(self.store.import_image(copy), stored) + self.assertEqual(stored.stat().st_mtime_ns, mtime) + self.assertEqual(len(list(self.store.signatures_dir.iterdir())), 1) + # other content -> another file; an exotic extension becomes .img + other = self.tmp / "scan.jfif" + Image.new("RGB", (5, 5), (9, 9, 9)).save(other, format="JPEG") + second = self.store.import_image(other) + self.assertEqual(second.suffix, ".img") + self.assertTrue(self.store.is_store_file(second)) + self.assertEqual(stamplib.load_image(second).size, (5, 5)) + self.assertEqual(len(list(self.store.signatures_dir.iterdir())), 2) + + def test_import_survives_moved_original(self): + src = make_png(self.tmp / "sig.png", size=(30, 10)) + stored = self.store.import_image(src) + src.unlink() + self.assertEqual(stamplib.load_image(stored).size, (30, 10)) + stamplib.validate_stamp(Stamp(kind="image", image_path=stored), placed=False) + + def test_import_rejects_non_image(self): + fake = self.tmp / "fake.png" + fake.write_text("not an image", encoding="utf-8") + for source in (fake, self.tmp / "missing.png"): + with self.subTest(source=source.name): + with self.assertRaises(stamplib.StampError): + self.store.import_image(source) + self.assertFalse(self.store.signatures_dir.exists()) # not even created + self.assertFalse(self.store.data_dir.exists()) + + def test_import_write_failure_is_oserror(self): + src = make_png(self.tmp / "sig.png") + self.store.data_dir.write_text("a file where the data dir should be", encoding="utf-8") + with self.assertRaises(OSError) as cm: + self.store.import_image(src) + self.assertNotIsInstance(cm.exception, stamplib.StampError) + + def test_store_image_writes_png_with_alpha(self): + drawn = stamplib.render_strokes_image([[(5, 5), (40, 20)]], "#102030") + stored = self.store.store_image(drawn) + self.assertRegex(stored.name, r"^[0-9a-f]{32}\.png$") + self.assertEqual(stored.parent, self.store.signatures_dir) + self.assertEqual(stored.read_bytes()[:8], b"\x89PNG\r\n\x1a\n") + back = stamplib.load_image(stored) + self.assertEqual((back.mode, back.size), ("RGBA", drawn.size)) + self.assertEqual(back.tobytes(), drawn.tobytes()) # alpha included + self.assertEqual(self.store.store_image(drawn), stored) # same pixels, same file + self.assertEqual(len(list(self.store.signatures_dir.iterdir())), 1) + + def test_remove_signature_deletes_unreferenced_file(self): + stored = self.stored() + profile = Profile(signatures=[ + self.image_sig(stored), + Signature(id="aaaaaaaaaaaa", label="t", stamp=Stamp(kind="text", text="x"))]) + self.store.remove_signature(profile, "0123456789ab") + self.assertEqual([s.id for s in profile.signatures], ["aaaaaaaaaaaa"]) + self.assertFalse(stored.exists()) + self.assertFalse(self.store.profile_path.exists()) # does NOT save + # removing a text signature touches no file; a missing file is ignored + self.store.remove_signature(profile, "aaaaaaaaaaaa") + self.assertEqual(profile.signatures, []) + gone = Profile(signatures=[self.image_sig(stored)]) + self.store.remove_signature(gone, "0123456789ab") + self.assertEqual(gone.signatures, []) + + def test_remove_keeps_file_shared_by_another_signature(self): + stored = self.stored() + profile = Profile(signatures=[self.image_sig(stored, "0123456789ab"), + self.image_sig(stored, "aaaaaaaaaaaa")]) + self.store.remove_signature(profile, "0123456789ab") + self.assertTrue(stored.exists()) + self.store.remove_signature(profile, "aaaaaaaaaaaa") # the last reference + self.assertFalse(stored.exists()) + + def test_remove_never_deletes_outside_store(self): + outside = make_png(self.tmp / "original.png") + lookalike = make_png(self.tmp / ("a" * 32 + ".png")) # right name, wrong place + profile = Profile(signatures=[self.image_sig(outside, "0123456789ab"), + self.image_sig(lookalike, "aaaaaaaaaaaa")]) + self.store.remove_signature(profile, "0123456789ab") + self.store.remove_signature(profile, "aaaaaaaaaaaa") + self.assertEqual(profile.signatures, []) + self.assertTrue(outside.exists()) + self.assertTrue(lookalike.exists()) + + def test_remove_never_follows_traversal(self): + self.stored() # signatures/ exists + plain = make_png(self.store.data_dir / "outside.png") + lookalike = make_png(self.store.data_dir / ("b" * 32 + ".png")) + sigs = self.load_signatures([ + {"kind": "image", "image_path": "../outside.png", "id": "0123456789ab"}, + {"kind": "image", "image_path": f"../{lookalike.name}", "id": "aaaaaaaaaaaa"}, + ]) + self.assertEqual(len(sigs), 2) # the files exist: usable + self.assertEqual(sigs[0].stamp.image_path, + self.store.signatures_dir / ".." / "outside.png") + profile = Profile(signatures=list(sigs)) + for sig_id in ("0123456789ab", "aaaaaaaaaaaa"): + self.assertFalse(self.store.is_store_file(profile.signatures[0].stamp.image_path)) + self.store.remove_signature(profile, sig_id) + self.assertEqual(profile.signatures, []) + self.assertTrue(plain.exists()) + self.assertTrue(lookalike.exists()) + # and saving such an entry never writes it as a store-relative name + self.store.save(Profile(signatures=sigs)) + saved = json.loads(self.store.profile_path.read_text(encoding="utf-8")) + self.assertEqual([e["image_path"] for e in saved["signatures"]], + [str(plain), str(lookalike)]) + + @unittest.skipUnless(os.name == "posix", "symlinks") + def test_remove_ignores_symlink(self): + self.stored() + secret = make_png(self.tmp / "secret.png") + link = self.store.signatures_dir / ("c" * 32 + ".png") # a correctly named link + link.symlink_to(secret) + self.assertFalse(self.store.is_store_file(link)) + profile = Profile(signatures=[self.image_sig(link)]) + self.store.remove_signature(profile, "0123456789ab") + self.assertEqual(profile.signatures, []) + self.assertTrue(secret.exists()) + self.assertTrue(link.is_symlink()) # nothing was unlinked + # a link to a REAL store file is not a store file either: deleting the + # signature that points at the link must not delete the link's target + stored = self.stored() + alias = self.store.signatures_dir / ("d" * 32 + ".png") + alias.symlink_to(stored) + profile = Profile(signatures=[self.image_sig(alias)]) + self.store.remove_signature(profile, "0123456789ab") + self.assertTrue(stored.exists()) + self.assertTrue(alias.is_symlink()) + + def test_remove_ignores_foreign_name_in_store(self): + self.stored() + mine = make_png(self.store.signatures_dir / "mine.png") + profile = Profile(signatures=[self.image_sig(mine)]) + self.store.remove_signature(profile, "0123456789ab") + self.assertEqual(profile.signatures, []) + self.assertTrue(mine.exists()) + + def test_is_store_file_rules(self): + stored = self.stored() + sig_dir = self.store.signatures_dir + name = "d" * 32 + ".png" + (sig_dir / "sub").mkdir() + rows = [ + (stored, True), + (str(stored), True), + (sig_dir / "sub" / ".." / stored.name, True), # resolves INTO the store + (sig_dir / name, True), # the name decides + (sig_dir / ".." / name, False), # traversal out of the store + (sig_dir / ".." / ".." / name, False), + (make_png(self.tmp / name), False), # absolute path elsewhere + (make_png(sig_dir / "mine.png"), False), # foreign name + (make_png(sig_dir / ("D" * 32 + ".png")), False), # upper-case hex + (make_png(sig_dir / ("d" * 31 + ".png")), False), # too short + (make_png(sig_dir / ("d" * 32 + ".PNG")), False), # upper-case extension + (make_png(sig_dir / "sub" / name), False), # sub-directory of the store + (sig_dir, False), + (Path(name), False), # relative to the cwd + ] + if os.name == "posix": + link = sig_dir / ("e" * 32 + ".png") + link.symlink_to(stored) # even to a real store file + rows.append((link, False)) + for path, expected in rows: + with self.subTest(path=str(path)): + self.assertIs(self.store.is_store_file(path), expected) + + def test_shared_file_compared_by_resolved_path(self): + stored = self.stored() + alias = self.store.signatures_dir / ".." / "signatures" / stored.name + self.assertNotEqual(alias, stored) # different spelling… + self.assertEqual(alias.resolve(), stored.resolve()) # …same file + profile = Profile(signatures=[self.image_sig(stored, "0123456789ab"), + self.image_sig(alias, "aaaaaaaaaaaa")]) + self.store.remove_signature(profile, "0123456789ab") + self.assertTrue(stored.exists()) # still referenced + self.store.remove_signature(profile, "aaaaaaaaaaaa") + self.assertFalse(stored.exists()) + + def test_remove_unknown_id_is_noop(self): + stored = self.stored() + profile = Profile(signatures=[self.image_sig(stored)]) + for sig_id in ("ffffffffffff", "vignette", None): + self.store.remove_signature(profile, sig_id) + self.assertEqual(len(profile.signatures), 1) + self.assertTrue(stored.exists()) + + def test_no_sweep_of_unreferenced_files(self): + orphan = self.stored((1, 2, 3, 255)) + used = self.stored((4, 5, 6, 255)) + profile = Profile(signatures=[self.image_sig(used)]) + self.store.save(profile) + self.store.load() + self.store.remove_signature(profile, "0123456789ab") + self.assertTrue(orphan.exists()) # never listed, never swept + self.assertFalse(used.exists()) + + +class PlacementRule(unittest.TestCase): + def placed(self, **kwargs) -> Stamp: + return Stamp(kind="text", text="x", x=10.0, y=20.0, **kwargs) + + def test_numbered_page_same_size_applies(self): + dims = [A4, LETTER] + self.assertTrue(profile_store.stamp_placement_applies(self.placed(page=1), A4, dims)) + self.assertTrue(profile_store.stamp_placement_applies(self.placed(page=2), LETTER, dims)) + # lists (as read from JSON) compare like tuples + self.assertTrue(profile_store.stamp_placement_applies( + self.placed(page=1), [595.0, 842.0], [[595.0, 842.0]])) + + def test_different_size_does_not_apply(self): + dims = [A4, LETTER] + self.assertFalse(profile_store.stamp_placement_applies(self.placed(page=2), A4, dims)) + # EXACT equality, no tolerance + self.assertFalse(profile_store.stamp_placement_applies( + self.placed(page=1), (595.0, 842.001), dims)) + + def test_page_beyond_template_does_not_apply(self): + self.assertFalse(profile_store.stamp_placement_applies(self.placed(page=3), A4, [A4, A4])) + self.assertFalse(profile_store.stamp_placement_applies(self.placed(page=0), A4, [A4, A4])) + self.assertFalse(profile_store.stamp_placement_applies(self.placed(page=1), A4, [])) + self.assertFalse(profile_store.stamp_placement_applies(self.placed(page=1), A4, None)) + + def test_unplaced_does_not_apply(self): + dims = [A4] + unplaced = Stamp(kind="text", text="x") + self.assertFalse(profile_store.stamp_placement_applies(unplaced, A4, dims)) + self.assertFalse(profile_store.stamp_placement_applies( + Stamp(kind="text", text="x", page=1, x=1.0), A4, dims)) # no y + self.assertFalse(profile_store.stamp_placement_applies( + Stamp(kind="text", text="x", x=1.0, y=1.0), A4, dims)) # no target + self.assertFalse(profile_store.stamp_placement_applies(self.placed(page=1), None, dims)) + self.assertFalse(profile_store.stamp_placement_applies( + Stamp(kind="text", text="x", all_pages=True), A4, dims)) # remembers the flag only + + def test_all_pages_applies_if_any_page_matches(self): + stamp = self.placed(all_pages=True) + self.assertTrue(profile_store.stamp_placement_applies(stamp, LETTER, [A4, LETTER, A4])) + self.assertFalse(profile_store.stamp_placement_applies(stamp, LETTER, [A4, A4])) + + def test_anchor_requires_anchor_page(self): + dims = [A4, A4] + stamp = self.placed(page=1) + self.assertFalse(profile_store.stamp_placement_applies(stamp, A4, dims, anchor="last")) + self.assertTrue(profile_store.stamp_placement_applies(stamp, A4, dims, anchor="first")) + self.assertTrue(profile_store.stamp_placement_applies( + self.placed(page=2), A4, dims, anchor="last")) + # a one-page template: page 1 is both the first and the last page + self.assertTrue(profile_store.stamp_placement_applies(stamp, A4, [A4], anchor="last")) + + def test_all_pages_under_anchor_needs_anchor_page_size(self): + stamp = self.placed(all_pages=True) + dims = [A4, LETTER] + self.assertTrue(profile_store.stamp_placement_applies(stamp, A4, dims, anchor="first")) + self.assertFalse(profile_store.stamp_placement_applies(stamp, A4, dims, anchor="last")) + self.assertTrue(profile_store.stamp_placement_applies(stamp, LETTER, dims, anchor="last")) + + def test_stamp_with_page_anchor_maps_to_template_page(self): + dims = [A4, LETTER, LETTER] + last, first = self.placed(page_anchor="last"), self.placed(page_anchor="first") + self.assertTrue(profile_store.stamp_placement_applies(last, LETTER, dims)) + self.assertFalse(profile_store.stamp_placement_applies(last, A4, dims)) + self.assertTrue(profile_store.stamp_placement_applies(first, A4, dims)) + self.assertTrue(profile_store.stamp_placement_applies(last, LETTER, dims, anchor="last")) + self.assertFalse(profile_store.stamp_placement_applies(last, LETTER, dims, anchor="first")) + + def test_vignette_rule(self): + dims = [A4, LETTER] + applies = profile_store.page_placement_applies + self.assertTrue(applies(1, A4, dims)) + self.assertTrue(applies(2, LETTER, dims)) + self.assertFalse(applies(2, A4, dims)) + self.assertFalse(applies(3, A4, dims)) + self.assertFalse(applies(None, A4, dims)) + self.assertFalse(applies(1, None, dims)) + self.assertFalse(applies(1, A4, [])) + self.assertFalse(applies(1, A4, dims, anchor="last")) + self.assertTrue(applies(2, LETTER, dims, anchor="last")) + self.assertTrue(applies(1, A4, dims, anchor="first")) + + +if __name__ == "__main__": + unittest.main() From e9ad6d4bcd1ebfd5d59f516b841ed70f8d794d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Denooz?= Date: Wed, 7 Oct 2026 09:56:19 +0200 Subject: [PATCH 3/6] feat: sign with text and several visual signatures per document Core: RunConfig.stamps carries any number of text / image stamps. In beid and azure mode they are applied in the same incremental writer before the cryptographic signature; image mode applies them alone. Template validation accepts a page-count mismatch only when every element is anchored on the first or last page. Stamping an already signed input is refused in beid/azure and flagged in image mode. CLI: --text, --font, --color, --font-size and --signatures ; existing invocations are unchanged. GUI: step 6 becomes a multi-element editor (add text, add image, draw, edit, delete, per-element placement with a to-scale preview). The signature library, placements and wizard settings are reloaded at startup. Report tables stretch their detail column. Bump the version to 1.4.0. --- gui.py | 1515 ++++++++++++++++++---- i18n.py | 1122 ++++++++++++---- i18n_docs.py | 311 ++++- sign_pdfs_beid.py | 424 ++++-- test_azure.py | 98 +- test_sign_pdfs_beid.py | 2804 +++++++++++++++++++++++++++++++++++++++- 6 files changed, 5634 insertions(+), 640 deletions(-) diff --git a/gui.py b/gui.py index da6b570..fe9b457 100644 --- a/gui.py +++ b/gui.py @@ -23,10 +23,19 @@ The 8 steps: template → documents → validation → output folder → signature type (+ localized "Full documentation" popup ending with source links) → -placement (page preview + click, an explicit target-page field and — when -page counts differ — the first/last-page selector mirrored from validation) -→ signing (summary, green "insert your eID card" reminder, progress) → -results report (+ "Open output folder"). +placement (a multi-element editor: the list of elements — the crypto +vignette in beid/azure plus the user's library of visual signatures (text, +image, drawing — added and edited through three small non-blocking +dialogs), each with an enabled checkbox — beside the page preview, +which shows every element to scale; select an element, click to place it; +an explicit target-page field and — when page counts differ — the +first/last-page selector mirrored from validation) → signing (summary, +green "insert your eID card" reminder, progress) → results report (+ "Open +output folder"). + +The signature library, each element's last placement and the wizard +settings live in the user profile (`profile_store.py`): loaded at start, +saved on every change, reloaded — never wiped — by Cancel/Finish. Threading rule (do not regress): tkinter is NOT thread-safe. The batch runs on a worker thread that never touches widgets — it only pushes onto a @@ -36,19 +45,22 @@ from __future__ import annotations +import dataclasses +import datetime import os import queue -import sys import threading import webbrowser from pathlib import Path -from tkinter import filedialog, font as tkfont, ttk +from tkinter import colorchooser, filedialog, font as tkfont, ttk import customtkinter as ctk from PIL import Image, ImageTk import i18n +import profile_store import sign_pdfs_beid as core +import stamps as stamplib from i18n import tr _FRAME_MAX_W = 360 # minimum size of the page preview frame (px) @@ -78,13 +90,27 @@ _COL_CARD_BG = ("#e3f3e6", "#1e3a26") # step-7 "insert your eID card" box _COL_CARD_FG = ("#1d4d2a", "#bfe3c6") _COL_LINK = ("#1a5fb4", "#78aeed") # documentation links (light, dark) +_COL_SELECTED = ("#d6e9f8", "#27425c") # step-6 list: selected element row + +VIGNETTE_ID = "vignette" # element id of the crypto vignette; never a signature id + # (profile_store.is_valid_id only accepts 12 hex digits) +_ELEMENTS_PANEL_W = 290 # step-6 left column (element list), px +_ELEMENTS_INNER_W = 270 # width of the widgets inside that column, px +_PREVIEW_MAX_PX = 1200 # long side of a cached element preview, px +_SCALED_CACHE_MAX = 64 # entries of the per-size preview cache +_MAX_PAGE_DIGITS = 9 # target-page field: anything longer is not a page number +_TABLE_CELL_PAD = 16 # room a table cell needs around its text, px +_DRAW_W, _DRAW_H = 620, 240 # freehand dialog: drawing canvas, px +_DRAW_PEN = 3 # pen width on that canvas, px +_DRAW_SCALE = 4 # supersampling of the stored drawing +_DRAW_PT_PER_PX = 0.4 # width on the page of a drawing, per canvas px def _asset_path(name: str) -> Path: """Path of a bundled asset (e.g. the logo): next to this file in a checkout, under the PyInstaller extraction dir (``sys._MEIPASS``) in the frozen binary — cachet.spec ships it in ``gui_datas``.""" - return Path(getattr(sys, "_MEIPASS", Path(__file__).resolve().parent)) / name + return stamplib.asset_path(name) _logo_pil = None # cached PIL image; False = tried and failed @@ -128,6 +154,23 @@ def _alive(widget) -> bool: return False +def _elide(text: str, max_px: int, font) -> str: + """``text`` if it fits ``max_px`` in ``font``, else its longest prefix + that fits with a trailing "…" — a long user label never widens a panel.""" + if font.measure(text) <= max_px: + return text + for end in range(len(text) - 1, 0, -1): + if font.measure(text[:end] + "…") <= max_px: + return text[:end] + "…" + return "…" + + +def _text_on(color: str) -> str: + """Black or white, whichever reads better on a ``#RRGGBB`` background.""" + r, g, b = (int(color[i:i + 2], 16) for i in (1, 3, 5)) + return "#000000" if (299 * r + 587 * g + 114 * b) / 1000 > 140 else "#ffffff" + + def _bold_tag(box) -> None: """(Re)define the "bold" text tag on a CTkTextbox. ``CTkTextbox.tag_config`` refuses ``font`` (its scaling guard), so the tag goes on the inner @@ -164,7 +207,7 @@ def _fill_textbox(box, text: str) -> None: class CachetApp(ctk.CTk): """Main window: landing page + 8-step wizard.""" - def __init__(self, args): + def __init__(self, args, store=None): super().__init__() self._apply_title() self.geometry("1180x950") @@ -177,28 +220,48 @@ def __init__(self, args): # NOTE: only radio/option-menu widgets get tk variables — their CTk # classes detach the variable trace in destroy(). CTkEntry (5.2.2) # does NOT, so entry-backed state is kept as plain strings instead - # (self.azure_vault / self.azure_key / self.page_text) and synced via - # key bindings; a shared StringVar would fire dead-widget callbacks - # after every step rebuild. + # (self.azure_vault / self.azure_key / self.page_text, and the + # editor-dialog fields, read with .get() when the dialog is applied) + # and synced via key bindings; a shared StringVar would fire + # dead-widget callbacks after every step rebuild. self.mode_var = ctk.StringVar(value="beid") self.pades_level_var = ctk.StringVar(value="b-lta") self.azure_auth_var = ctk.StringVar(value="interactive") # GUI default self._running = False # batch in progress self._azure_login_q: queue.Queue | None = None self._result_q: queue.Queue | None = None - self._canvas_img = None # PhotoImage ref (placeholder) + self._canvas_imgs: list = [] # PhotoImage refs (elements) self._bg_img = None # PhotoImage ref (page render) self._page_img_cache: dict = {} # (template, page) -> PIL image self._last_win_size = None self._stepper_btns: list[ctk.CTkButton] = [] self.step_index = 0 self.canvas = None + # User profile: the signature library + the wizard settings, + # loaded by _reset_state() and saved on every change. Tests inject a + # store; the default one reads CACHET_CONFIG_DIR / CACHET_DATA_DIR, + # else the platform's user folders. + self.store = store if store is not None else profile_store.ProfileStore() + self.profile = profile_store.Profile() + self._loading = False # _reset_state applying the profile + self._profile_error: str | None = None # last save failure (_save_profile) + self._element_notice: str | None = None # last element operation refused + # content_key -> (PIL thumbnail, (w_pt, h_pt)), or -> the error + # message (str) of content that cannot be rendered + self._preview_cache: dict = {} + self._scaled_cache: dict = {} # (content_key, w_px, h_px) -> PIL + self._dialog = None # the single editor dialog + self._dialog_state: dict = {} + self._blank_img = None # 1×1 CTkImage: "no preview" + self.selected_id: str | None = None # VIGNETTE_ID or a signature id self._reset_state() - # Config edits invalidate a previous run + refresh the stepper. + # Config edits invalidate a previous run + refresh the stepper, and + # are persisted (never while _reset_state applies the profile). self.mode_var.trace_add("write", lambda *_: self._on_config_edit()) self.pades_level_var.trace_add("write", lambda *_: self._on_config_edit()) + self.azure_auth_var.trace_add("write", lambda *_: self._on_azure_auth_edit()) self._screen = ctk.CTkFrame(self, fg_color="transparent") self._screen.pack(fill="both", expand=True) @@ -210,42 +273,66 @@ def _apply_title(self) -> None: self.title(tr("app.title", version=core.__version__)) def _reset_state(self) -> None: - """Back to a blank wizard (fresh Start, Cancel, or Finish).""" + """Back to a blank wizard (fresh Start, Cancel, or Finish). Only the + SESSION is reset (template, files, validation, results); the + signature library and the saved settings are reloaded from the user + profile, never wiped.""" self._close_docs_popup() # it belongs to the old wizard + self._close_dialog() self.template_path: Path | None = None self.template_dims: list[tuple[float, float]] = [] self.template_error: str | None = None self.input_paths: list[Path] = [] self.validation_results = None # list[ValidationResult] | None self.valid_paths: list[Path] = [] - self.output_dir: Path | None = None - self.image_path: Path | None = None self.cur_page = 0 # 0-based, preview only - self.place_page: int | None = None # 1-based target page - self.place_x: float | None = None - self.place_y: float | None = None self.page_text = "" # target-page field content + self.selected_id = None + self._element_notice = None + self._preview_cache.clear() + self._scaled_cache.clear() # Page anchor (validation step): when some files' page count differs # from the template, `anchor_choice` decides whether EVERY file is # signed on its own first or last page (default: last, matching the # historical vignette position). Inactive while all counts match. self.anchor_choice = "last" self.count_mismatch = False - self.azure_vault = os.environ.get( - core.ENV_AZURE_VAULT_URL, "https://login.live.com") - self.azure_key = os.environ.get(core.ENV_AZURE_KEY_NAME, "") - self.azure_anchors_path: Path | None = ( - Path(p) if (p := os.environ.get(core.ENV_AZURE_TRUST_ANCHORS)) else None - ) - self.azure_user_upn: str | None = None self.run_rows: list = [] # DocResult, streamed self.run_results: list | None = None # DocResult list once done self.run_error: str | None = None # batch-level failure self._page_img_cache.clear() self.step_index = 0 - self.mode_var.set("beid") - self.pades_level_var.set("b-lta") - self.azure_auth_var.set("interactive") + # Settings precedence: saved user choice > CACHET_AZURE_* env > + # built-in default. The tk-variable traces fire below: _loading keeps + # them from writing these very values back as "user edits". + self._loading = True + try: + self.profile = self.store.load() + s = self.profile.settings + # os.path.isdir / exists, not pathlib: they are False on ANY + # error, whereas Path.is_dir() / exists() raise for an unreachable + # share, a permission problem or an over-long name — and a saved + # path must never keep the application from starting. + self.output_dir: Path | None = ( + Path(s.output_dir) if s.output_dir and os.path.isdir(s.output_dir) + else None) + self.azure_vault = s.azure_vault_url or os.environ.get( + core.ENV_AZURE_VAULT_URL, "https://login.live.com") + self.azure_key = os.environ.get(core.ENV_AZURE_KEY_NAME, "") + saved = s.azure_trust_anchors + env = os.environ.get(core.ENV_AZURE_TRUST_ANCHORS) + self.azure_anchors_path: Path | None = ( + Path(saved) if saved and os.path.exists(saved) + else (Path(env) if env else None)) + self.azure_user_upn: str | None = None + self.mode_var.set(s.mode if s.mode in ("beid", "azure", "image") else "beid") + self.pades_level_var.set( + s.pades_level if s.pades_level in core.PADES_LEVELS else "b-lta") + self.azure_auth_var.set( + s.azure_auth if s.azure_auth in core.AZURE_AUTH_METHODS + else "interactive") + finally: + self._loading = False def _invalidate_run(self) -> None: self.run_rows = [] @@ -253,11 +340,153 @@ def _invalidate_run(self) -> None: self.run_error = None def _on_config_edit(self) -> None: - if self._running: + if self._running or self._loading: return + s = self.profile.settings + s.mode = self.mode_var.get() + s.pades_level = self.pades_level_var.get() + self._save_profile() self._invalidate_run() self._refresh_chrome() + def _on_azure_auth_edit(self) -> None: + if self._loading: + return + self.profile.settings.azure_auth = self.azure_auth_var.get() + self._save_profile() + + def _save_profile(self) -> None: + """Persist the library + settings. Never raises: a failure is kept + in `_profile_error` and shown on the placement step. Main thread + only (the batch worker never calls it).""" + if self._loading: + return + try: + self.store.save(self.profile) + self._profile_error = None + except OSError as exc: + self._profile_error = str(exc) or exc.__class__.__name__ + + # ------------------------------------------- elements (read-only helpers) + def _sig(self, sig_id): + """The library signature with that id, or None.""" + for sig in self.profile.signatures: + if sig.id == sig_id: + return sig + return None + + def _enabled_signatures(self) -> list: + return [s for s in self.profile.signatures if s.enabled] + + def _has_vignette(self) -> bool: + return self.mode_var.get() in ("beid", "azure") + + def _element_ids(self) -> list[str]: + """Step-6 elements, in list order: the vignette (beid/azure), then + the whole library (enabled or not).""" + return (([VIGNETTE_ID] if self._has_vignette() else []) + + [s.id for s in self.profile.signatures]) + + def _sig_placed(self, sig) -> bool: + """True while the signature's saved placement is IN FORCE for the + current template and anchor (placements are never destroyed).""" + return profile_store.stamp_placement_applies( + sig.stamp, sig.placed_on, self.template_dims, self._page_anchor()) + + def _vignette_placed(self) -> bool: + v = self.profile.settings.vignette + return v is not None and profile_store.page_placement_applies( + v.page, v.placed_on, self.template_dims, self._page_anchor()) + + def _sample_filename(self) -> str: + """File stem the previews substitute for {filename}.""" + if self.valid_paths: + return self.valid_paths[0].stem + if self.template_path: + return self.template_path.stem + return "document" + + def _content_key(self, sig) -> tuple: + return stamplib.content_key(sig.stamp, filename=self._sample_filename(), + date=datetime.date.today()) + + def _content_entry(self, sig): + """Cached preview of a signature's content: `(thumbnail, (w_pt, + h_pt))`, or the error message (str) when it cannot be rendered. Runs + inside _refresh_chrome on every navigation, so it never raises and + never renders the same failing content twice.""" + key = self._content_key(sig) + if key not in self._preview_cache: + try: + img, size_pt = stamplib.stamp_content( + sig.stamp, filename=self._sample_filename(), + date=datetime.date.today()) + thumb = img.convert("RGBA") # a copy, whatever the mode + thumb.thumbnail((_PREVIEW_MAX_PX, _PREVIEW_MAX_PX)) + self._preview_cache[key] = (thumb, size_pt) + except Exception as exc: # noqa: BLE001 - MemoryError, bomb guard, … + self._preview_cache[key] = str(exc) or type(exc).__name__ + return self._preview_cache[key] + + def _content(self, sig): + """`(thumbnail, (w_pt, h_pt))` of a signature, or None when unusable.""" + entry = self._content_entry(sig) + return None if isinstance(entry, str) else entry + + def _sig_error(self, sig) -> str | None: + """Why a signature cannot be used (missing image/font, …), or None.""" + entry = self._content_entry(sig) + return entry if isinstance(entry, str) else None + + def _element_size_pt(self, element_id) -> tuple[float, float]: + """Size (pt) of an element on the previewed page: a 3:1 vignette box + of width page/5, or the signature's real content size.""" + if element_id == VIGNETTE_ID: + return core.vignette_size_pt(self.template_dims[self.cur_page][0]) + sig = self._sig(element_id) + content = self._content(sig) if sig else None + return content[1] if content else (150.0, 50.0) + + def _element_page(self, element_id) -> int | None: + """1-based TEMPLATE page an element sits on when its placement is in + force on one single page, else None (unplaced, every page, unknown).""" + if element_id == VIGNETTE_ID: + return self.profile.settings.vignette.page if self._vignette_placed() else None + sig = self._sig(element_id) + if sig is None or not self._sig_placed(sig) or sig.stamp.all_pages: + return None + if sig.stamp.page_anchor is not None: + return 1 if sig.stamp.page_anchor == "first" else len(self.template_dims) + return sig.stamp.page + + def _ensure_selection(self) -> bool: + """Re-pick the selected element when the current one no longer + exists (mode change, deletion, fresh wizard). True if it re-picked.""" + if self.selected_id in self._element_ids(): + return False + if self._has_vignette(): + self.selected_id = VIGNETTE_ID + else: + sigs = self.profile.signatures + todo = [s for s in sigs if s.enabled and not self._sig_placed(s)] + first = todo[0] if todo else (sigs[0] if sigs else None) + self.selected_id = first.id if first else None + self._sync_page_to_selection() + return True + + def _sync_page_to_selection(self) -> None: + """Target-page field + preview page follow the selected element. No + drawing. The ONLY place that derives `page_text` from an element.""" + if self._page_anchor(): + self._set_page_entry("") # field disabled; cur_page is locked by _draw_page + return + page = self._element_page(self.selected_id) + if page is None: + self._set_page_entry("") # unplaced / every page / nothing selected + else: + self.cur_page = page - 1 + self._set_page_entry(str(page)) + # ============================================================= CHROME def _build_top_bar(self, parent, *, lang_command): """Top bar shared by the landing page and the wizard: the brand @@ -297,6 +526,7 @@ def _build_top_bar(self, parent, *, lang_command): # ============================================================ LANDING def _clear_screen(self) -> None: + self._close_dialog() for w in self._screen.winfo_children(): w.destroy() self._stepper_btns = [] @@ -336,19 +566,27 @@ def _language_code(display_name: str) -> str | None: return code return None + def _persist_language(self, code: str) -> None: + if self.profile.settings.language != code: + self.profile.settings.language = code + self._save_profile() + def _on_language_change(self, display_name: str) -> None: code = self._language_code(display_name) if code: i18n.set_language(code) + self._persist_language(code) self._apply_title() self._close_docs_popup() # its text is language-bound + self._close_dialog() self._show_landing() # re-render the landing texts def _on_wizard_language_change(self, display_name: str) -> None: """Language switch from inside the wizard. Widgets are disposable and - all state lives on the app, so the chrome and the current step are - simply rebuilt in place — nothing the user entered is lost. Ignored - while a batch runs (the menu is disabled then anyway).""" + all state lives on the app (the library and the placements on the + profile), so the chrome and the current step are simply rebuilt in + place — nothing the user entered is lost. Ignored while a batch runs + (the menu is disabled then anyway).""" code = self._language_code(display_name) if self._running or code is None: return @@ -356,6 +594,8 @@ def _on_wizard_language_change(self, display_name: str) -> None: i18n.set_language(code) self._apply_title() self._close_docs_popup() # its text is language-bound + self._persist_language(code) + self._close_dialog() # language-bound too step = self.step_index self._build_wizard() self._goto_step(step) # the current step is always re-enterable @@ -435,6 +675,7 @@ def _first_incomplete(self) -> int: return len(_STEP_KEYS) def _goto_step(self, idx: int) -> None: + self._close_dialog() # it edits the step being left if self._running or not self._stepper_btns: return idx = max(0, min(len(_STEP_KEYS) - 1, idx)) @@ -474,32 +715,45 @@ def _finish(self) -> None: def _cancel_wizard(self) -> None: if self._running: return + + def do_cancel(): + self._reset_state() + self._show_landing() + + self._confirm_modal(tr("cancel.title"), tr("cancel.body"), + tr("cancel.confirm"), tr("cancel.keep"), + on_confirm=do_cancel) + + def _confirm_modal(self, title, body, confirm_text, keep_text, on_confirm): + """Small confirmation window (Cancel wizard, Delete signature): the + red button destroys it then calls ``on_confirm``; the other one just + closes it. The button row stays the window's LAST child.""" win = ctk.CTkToplevel(self) - win.title(tr("cancel.title")) + win.title(title) win.geometry("480x190") win.transient(self) win.resizable(False, False) - ctk.CTkLabel(win, text=tr("cancel.title"), + ctk.CTkLabel(win, text=title, font=ctk.CTkFont(size=15, weight="bold") ).pack(anchor="w", padx=18, pady=(16, 4)) - ctk.CTkLabel(win, text=tr("cancel.body"), justify="left", + ctk.CTkLabel(win, text=body, justify="left", wraplength=440).pack(anchor="w", padx=18) row = ctk.CTkFrame(win, fg_color="transparent") row.pack(side="bottom", fill="x", padx=18, pady=14) - def do_cancel(): + def do_confirm(): win.destroy() - self._reset_state() - self._show_landing() + on_confirm() - ctk.CTkButton(row, text=tr("cancel.confirm"), width=150, + ctk.CTkButton(row, text=confirm_text, width=150, fg_color=_COL_ERROR, hover_color=("#c96a6a", "#8a4444"), - command=do_cancel).pack(side="right", padx=(8, 0)) - ctk.CTkButton(row, text=tr("cancel.keep"), width=150, + command=do_confirm).pack(side="right", padx=(8, 0)) + ctk.CTkButton(row, text=keep_text, width=150, fg_color="transparent", border_width=1, text_color=("gray20", "gray80"), command=win.destroy).pack(side="right") win.after(80, lambda: _alive(win) and win.grab_set()) + return win # ------------------------------------------- completion / error state def _mode_error(self) -> str | None: @@ -513,20 +767,38 @@ def _mode_error(self) -> str | None: return None def _page_entry_error(self) -> str | None: - if self._page_anchor(): + if not self.template_dims or self._page_anchor(): return None # field disabled: the anchor fixes the page raw = self.page_text.strip() - if raw and (not raw.isdigit() or int(raw) < 1): + if not raw: + return None + # len: int() raises on a pasted number of several thousand digits + if not raw.isdecimal() or len(raw) > _MAX_PAGE_DIGITS or int(raw) < 1: return tr("place.page_invalid") + if int(raw) > len(self.template_dims): + # blocking: it could only give "page out of range" for + # every accepted document + return tr("place.page_beyond", page=int(raw), + total=len(self.template_dims)) return None def _place_error(self) -> str | None: + """First problem of the placement step, or None. beid/azure with no + enabled signature is complete without a click (default vignette); + disabled signatures never block.""" err = self._page_entry_error() if err: return err - if self.mode_var.get() == "image" and ( - self.image_path is None or self.place_x is None): - return tr("place.image_missing") + enabled = self._enabled_signatures() + for sig in enabled: + broken = self._sig_error(sig) + if broken: + return tr("place.el_broken", name=sig.label, error=broken) + if self.mode_var.get() == "image" and not enabled: + return tr("place.need_signature") + for sig in enabled: + if not self._sig_placed(sig): + return tr("place.unplaced", name=sig.label) return None def _step_complete(self, idx: int) -> bool: @@ -626,19 +898,41 @@ def _refresh_chrome(self) -> None: # ------------------------------------------------------------ tables def _make_table(self, parent, columns: list[tuple[str, int]], height: int): - """ttk table; ``columns`` = [(localized heading, width px), …].""" + """ttk table; ``columns`` = [(localized heading, width px), …]. The + last column takes the remaining width (it follows the window); a + horizontal scrollbar shows up while its text is wider than that + (see ``_fill_table``).""" names = [c[0] for c in columns] table = ttk.Treeview(parent, columns=names, show="headings", height=height) for name, width in columns: table.heading(name, text=name) - table.column(name, width=width, anchor="w") + table.column(name, width=width, anchor="w", stretch=False) + table.column(names[-1], stretch=True) + table.heading(names[-1], anchor="w") # stays in view when scrolled to table.pack(fill="x", pady=4, padx=8) + xbar = ttk.Scrollbar(parent, orient="horizontal", command=table.xview) + + def on_xscroll(first, last) -> None: + xbar.set(first, last) + if float(first) <= 0 and float(last) >= 1: # everything is visible + xbar.pack_forget() + else: + xbar.pack(fill="x", padx=8, after=table) + + table.configure(xscrollcommand=on_xscroll) return table @staticmethod - def _clear(table) -> None: - for item in table.get_children(): - table.delete(item) + def _fill_table(table, rows) -> None: + """Replace the rows of a table. Its last column is never narrower + than its longest text: what the window cannot show is scrolled to.""" + table.delete(*table.get_children()) + for row in rows: + table.insert("", "end", values=row) + font = tkfont.Font(font=ttk.Style().lookup("Treeview", "font")) + need = max((font.measure(row[-1]) for row in rows), default=0) + _TABLE_CELL_PAD + # width too: ttk then re-fits the column to the space that is left + table.column(table["columns"][-1], width=need, minwidth=need) # ===================================================== step 1: template def _build_step_template(self, parent) -> None: @@ -676,11 +970,17 @@ def _pick_template(self) -> None: except Exception as exc: # noqa: BLE001 self.template_dims = [] self.template_error = str(exc) - # A new template invalidates validation, placement and results. + # A new template invalidates validation and results. No saved + # placement is destroyed: each one is in force again whenever the + # template page has the size it was placed on (_sig_placed). self.validation_results = None self.valid_paths = [] self.cur_page = 0 - self._reset_position() + self.page_text = "" # a stale page number would block step 6 + self.selected_id = None + self._element_notice = None + self._preview_cache.clear() # {filename} sample may change + self._scaled_cache.clear() self._invalidate_run() self._update_template_label() self._refresh_chrome() @@ -805,30 +1105,26 @@ def count_differs(p) -> bool: def _sync_anchor_page(self) -> None: """Lock the placement preview onto the template page that will carry - the signature (first/last) while the anchor selector applies; a - position clicked on another page no longer matches, so it is dropped. - The manual target page is cleared too — `page` and `page_anchor` are - mutually exclusive.""" + the elements (first/last) while the anchor selector applies. The + manual target page is cleared — `page` and `page_anchor` are mutually + exclusive. No position is dropped: an element placed on another + template page simply reads "not placed" under this anchor (the + placement predicates take the anchor) and comes back with it.""" anchor = self._page_anchor() if not anchor or not self.template_dims: return - target = 0 if anchor == "first" else len(self.template_dims) - 1 - self.cur_page = target - if self.place_page is not None and self.place_page != target + 1: - self.place_page = self.place_x = self.place_y = None + self.cur_page = 0 if anchor == "first" else len(self.template_dims) - 1 self._set_page_entry("") + self._refresh_elements() self._update_place_labels() self._draw_page() def _update_validation_widgets(self) -> None: if _alive(getattr(self, "valid_table", None)): - self._clear(self.valid_table) - for r in self.validation_results or []: - self.valid_table.insert( - "", "end", - values=(r.path.name, - tr("val.ok") if r.ok else tr("val.rejected"), - r.reason or "—")) + self._fill_table(self.valid_table, [ + (r.path.name, tr("val.ok") if r.ok else tr("val.rejected"), + r.reason or "—") + for r in self.validation_results or []]) if _alive(getattr(self, "val_status_lbl", None)): if self.validation_results is None: self.val_status_lbl.configure(text="") @@ -861,6 +1157,8 @@ def _pick_output(self) -> None: if not path: return self.output_dir = Path(path) + self.profile.settings.output_dir = str(self.output_dir) + self._save_profile() self._invalidate_run() if _alive(getattr(self, "output_lbl", None)): self.output_lbl.configure(text=str(self.output_dir)) @@ -886,6 +1184,7 @@ def hint(container, key, **pack_kw): value=value, command=self._on_mode_change ).pack(anchor="w", padx=8, pady=(8, 0)) hint(box, hint_key, pady=(2, 4)) + hint(box, "mode.stamps_hint", pady=(6, 4)) lrow = ctk.CTkFrame(box, fg_color="transparent") lrow.pack(fill="x", padx=8, pady=(8, 0)) @@ -955,9 +1254,14 @@ def _on_mode_change(self) -> None: def _on_azure_entry_edit(self) -> None: if _alive(getattr(self, "azure_vault_entry", None)): - self.azure_vault = self.azure_vault_entry.get() + new = self.azure_vault_entry.get() + # Persist only a real edit: a mere focus-out must not turn + # the env/default value into a saved user choice. + if new != self.azure_vault: + self.azure_vault = new + self.profile.settings.azure_vault_url = new.strip() or None if _alive(getattr(self, "azure_key_entry", None)): - self.azure_key = self.azure_key_entry.get() + self.azure_key = self.azure_key_entry.get() # never persisted self._on_config_edit() def _refresh_azure_visibility(self) -> None: @@ -1019,6 +1323,8 @@ def _pick_azure_anchors(self) -> None: if not path: return self.azure_anchors_path = Path(path) + self.profile.settings.azure_trust_anchors = path + self._save_profile() if _alive(getattr(self, "azure_anchors_lbl", None)): self.azure_anchors_lbl.configure(text=path) self._invalidate_run() @@ -1104,16 +1410,9 @@ def _build_step_place(self, parent) -> None: font=ctk.CTkFont(size=11)).pack(fill="x") self._update_place_anchor_widgets() - self.image_row = ctk.CTkFrame(parent, fg_color="transparent") - if self.mode_var.get() == "image": # image picker: image mode only - self.image_row.pack(fill="x", pady=(10, 0), padx=8) - ctk.CTkButton(self.image_row, text=tr("place.image_choose"), width=200, - command=self._pick_image).pack(side="left") - self.image_lbl = ctk.CTkLabel( - self.image_row, - text=self.image_path.name if self.image_path else tr("common.none")) - self.image_lbl.pack(side="left", padx=12) - + # Page navigation, at FULL width above the editor: it needs up to + # ~650 px in the longest language, more than the preview column has + # beside the element list. nav = ctk.CTkFrame(parent, fg_color="transparent") nav.pack(fill="x", pady=6, padx=8) ctk.CTkLabel(nav, text=tr("place.page")).pack(side="left") @@ -1121,12 +1420,6 @@ def _build_step_place(self, parent) -> None: self.page_entry.insert(0, self.page_text) self.page_entry.bind("", lambda _e: self._on_page_entry_change()) self.page_entry.pack(side="left", padx=(6, 16)) - # packed before the page buttons so it keeps its space when the - # locked-preview label makes the row tight - ctk.CTkButton(nav, text=tr("place.reset"), width=150, - fg_color="transparent", border_width=1, - text_color=("gray20", "gray80"), - command=self._reset_position).pack(side="right") self.page_prev_btn = ctk.CTkButton(nav, text=tr("place.prev"), width=140, command=lambda: self._turn_page(-1)) self.page_prev_btn.pack(side="left") @@ -1145,23 +1438,83 @@ def _build_step_place(self, parent) -> None: self.page_prev_btn.pack_forget() self.page_next_btn.pack_forget() - info = ctk.CTkFrame(parent, fg_color="transparent") - info.pack(fill="x", padx=8) - self.pos_lbl = ctk.CTkLabel(info, text="", anchor="w", justify="left", - wraplength=380) - self.pos_lbl.pack(side="left") - self.place_warn_lbl = ctk.CTkLabel(info, text="", anchor="w", justify="left", - wraplength=300, + # Editor: the element list on the left, the page preview on the right. + self.editor_row = ctk.CTkFrame(parent, fg_color="transparent") + self.editor_row.pack(fill="x", padx=8, pady=(4, 0)) + + # Left column. Its width is bounded by its children: each one is at + # most _ELEMENTS_INNER_W wide (a CTkButton GROWS with its label, so + # the add buttons are stacked, never side by side). + panel = self.elements_panel = ctk.CTkFrame(self.editor_row) + panel.pack(side="left", anchor="n", padx=(0, 10)) + ctk.CTkLabel(panel, text=tr("place.elements_title"), anchor="w", + font=ctk.CTkFont(size=13, weight="bold") + ).pack(anchor="w", padx=10, pady=(8, 2)) + self.add_text_btn = ctk.CTkButton( + panel, text=tr("sig.add_text"), width=_ELEMENTS_INNER_W, + command=self._open_text_dialog) + self.add_image_btn = ctk.CTkButton( + panel, text=tr("sig.add_image"), width=_ELEMENTS_INNER_W, + command=self._pick_image_signature) + self.draw_btn = ctk.CTkButton( + panel, text=tr("sig.draw"), width=_ELEMENTS_INNER_W, + command=self._open_draw_dialog) + for btn in (self.add_text_btn, self.add_image_btn, self.draw_btn): + btn.pack(padx=10, pady=2) + # A plain frame, not a CTkScrollableFrame (nesting one inside the + # step's own scrollable area double-scrolls). _refresh_elements() + # always leaves a child in it: an empty CTkFrame keeps 200×200. + self.elements_list = ctk.CTkFrame(panel, fg_color="transparent", height=1) + self.elements_list.pack(fill="x", padx=10, pady=(8, 4)) + actions = ctk.CTkFrame(panel, fg_color="transparent") + actions.pack(anchor="w", padx=10, pady=2) + self.edit_btn = ctk.CTkButton(actions, text=tr("sig.edit"), width=130, + command=self._edit_selected) + self.edit_btn.pack(side="left", padx=(0, 6)) + self.delete_btn = ctk.CTkButton( + actions, text=tr("sig.delete"), width=130, + fg_color="transparent", border_width=1, + text_color=("gray20", "gray80"), command=self._delete_selected) + self.delete_btn.pack(side="left") + self.all_pages_chk = ctk.CTkCheckBox( + panel, text=tr("place.all_pages"), command=self._toggle_all_pages) + self.all_pages_chk.pack(anchor="w", padx=10, pady=(8, 4)) + self.reset_btn = ctk.CTkButton( + panel, text=tr("place.reset"), width=_ELEMENTS_INNER_W, + fg_color="transparent", border_width=1, + text_color=("gray20", "gray80"), + command=self._reset_selected_position) + self.reset_btn.pack(padx=10, pady=2) + ctk.CTkLabel(panel, text=tr("place.storage_note"), justify="left", + anchor="w", wraplength=_ELEMENTS_INNER_W, + text_color=("gray25", "gray70"), + font=ctk.CTkFont(size=11) + ).pack(anchor="w", padx=10, pady=(6, 8)) + + # Right column: position of the selected element, problems, preview. + self.preview_col = ctk.CTkFrame(self.editor_row, fg_color="transparent") + self.preview_col.pack(side="left", anchor="n") + self.pos_lbl = ctk.CTkLabel(self.preview_col, text="", anchor="w", + justify="left", wraplength=320) + self.pos_lbl.pack(anchor="w") + self.place_warn_lbl = ctk.CTkLabel(self.preview_col, text="", anchor="w", + justify="left", wraplength=320, text_color=("#b3261e", "#e08a8a")) - self.place_warn_lbl.pack(side="left", padx=16) + self.place_warn_lbl.pack(anchor="w") - # tkinter Canvas: background = rendered template page, click = position. + # tkinter Canvas: background = rendered template page; a click places + # the SELECTED element (selection is made in the list only). import tkinter as tk - self.canvas = tk.Canvas(parent, width=_FRAME_MAX_W, height=_FRAME_MAX_H, - bg="#d9d9d9", highlightthickness=1, - highlightbackground="#888") - self.canvas.pack(pady=6, padx=8) + self.canvas = tk.Canvas(self.preview_col, width=_FRAME_MAX_W, + height=_FRAME_MAX_H, bg="#d9d9d9", + highlightthickness=1, highlightbackground="#888") + self.canvas.pack(pady=6) self.canvas.bind("", self._on_canvas_click) + # Before the first draw: a restored element is shown on its own page, + # with its page number in the field. + self._ensure_selection() + self._sync_page_to_selection() + self._refresh_elements() self._update_place_labels() self._draw_page() @@ -1175,20 +1528,642 @@ def _update_place_anchor_widgets(self) -> None: "place.anchor_status", ok=len(self.valid_paths), total=len(self.validation_results or []))) - def _pick_image(self) -> None: - path = filedialog.askopenfilename( - title=tr("place.image_choose"), - filetypes=[("Images", "*.png *.jpg *.jpeg *.gif *.bmp")]) - if not path: + # ---------------------------------------------------- step 6: element list + def _element_status(self, element_id) -> str: + """Second line of an element's row: where it stands.""" + anchor = self._page_anchor() + if element_id == VIGNETTE_ID: + if self._vignette_placed(): + return tr("place.st_page", page=self.profile.settings.vignette.page) + return tr("place.st_default") + sig = self._sig(element_id) + if self._sig_error(sig): + return tr("place.st_error") + if not self._sig_placed(sig): + return tr("place.st_unplaced") + if anchor: + return tr(f"anchor.{anchor}_page") + if sig.stamp.all_pages: + return tr("place.st_all") + return tr("place.st_page", page=self._element_page(element_id)) + + def _refresh_elements(self) -> None: + """Rebuild the element rows (vignette + library) and sync the action + widgets with the selection.""" + if not _alive(getattr(self, "elements_list", None)): return - self.image_path = Path(path) - if _alive(getattr(self, "image_lbl", None)): - self.image_lbl.configure(text=self.image_path.name) - self._invalidate_run() + for w in self.elements_list.winfo_children(): + w.destroy() + self._element_rows: dict = {} # id -> row frame + self._element_labels: dict = {} # id -> (name label, status label) + self._element_checks: dict = {} # signature id -> enabled checkbox + ids = self._element_ids() + if not ids: # image mode, empty library + ctk.CTkLabel(self.elements_list, text=tr("place.list_empty"), + justify="left", anchor="w", + wraplength=_ELEMENTS_INNER_W, + text_color=("gray25", "gray70")).pack(anchor="w") + name_font = ctk.CTkFont(size=13) + for eid in ids: + sig = self._sig(eid) + row = ctk.CTkFrame( + self.elements_list, + fg_color=_COL_SELECTED if eid == self.selected_id else "transparent") + row.pack(fill="x", pady=1) + if sig is not None: + chk = ctk.CTkCheckBox(row, text="", width=24, + command=lambda i=eid: self._toggle_enabled(i)) + if sig.enabled: + chk.select() + chk.pack(side="left", padx=(4, 0)) + self._element_checks[eid] = chk + else: # the vignette cannot be disabled + ctk.CTkFrame(row, fg_color="transparent", width=24, height=24 + ).pack(side="left", padx=(4, 0)) + # Two stacked labels, not a two-line button: CTkButton has no + # `justify` and centres the second line. + col = ctk.CTkFrame(row, fg_color="transparent") + col.pack(side="left", fill="x", expand=True, padx=(4, 0)) + name = ctk.CTkLabel( + col, anchor="w", cursor="hand2", font=name_font, + text=_elide(tr("place.el_vignette") if sig is None else sig.label, + _ELEMENTS_INNER_W - 50, name_font)) + name.pack(anchor="w") + status = ctk.CTkLabel(col, anchor="w", cursor="hand2", height=16, + text=self._element_status(eid), + text_color="gray50", font=ctk.CTkFont(size=11)) + status.pack(anchor="w") + for w in (row, col, name, status): + w.bind("", lambda _e, i=eid: self._select(i)) + self._element_rows[eid] = row + self._element_labels[eid] = (name, status) + + sig = self._sig(self.selected_id) + anchor = self._page_anchor() + for btn in (self.edit_btn, self.delete_btn): + btn.configure(state="normal" if sig else "disabled") + self.reset_btn.configure( + state="normal" if self.selected_id in ids else "disabled") + # select()/deselect() never call `command` and work while disabled + if sig and sig.stamp.all_pages: + self.all_pages_chk.select() + else: + self.all_pages_chk.deselect() + self.all_pages_chk.configure( + state="normal" if sig and not anchor else "disabled") + + def _refresh_place(self) -> None: + """List, labels, preview and stepper after an element changed. Every + part is a no-op while step 6 is not built.""" + self._refresh_elements() self._update_place_labels() self._draw_page() self._refresh_chrome() + def _commit_elements(self) -> None: + """End of every library/placement mutation: persist, drop the + results of a previous run, refresh the step.""" + self._save_profile() + self._invalidate_run() + self._refresh_place() + + # ----------------------------------------------- step 6: element operations + def _select(self, element_id) -> None: + self._element_notice = None + self.selected_id = element_id + self._sync_page_to_selection() # preview + page field follow it + self._refresh_place() + + def _add_signature(self, stamp, label: str): + """Append a signature to the library and select it. Safe to call + while step 6 is not built.""" + self._element_notice = None + sig = profile_store.Signature(id=profile_store.new_id(), + label=label[:profile_store.MAX_LABEL_LEN], stamp=stamp) + self.profile.signatures.append(sig) + self.selected_id = sig.id + self._sync_page_to_selection() + self._commit_elements() + return sig + + def _add_image_signature(self, path, label=None): + """Copy an image into the user's signature store and add it as an + image signature. When it cannot be read or stored NOTHING is added + (no fallback to the original file) and the reason is shown.""" + self._element_notice = None + try: + stored = self.store.import_image(Path(path)) + except stamplib.StampError as exc: # not an image + self._element_notice = tr("sig.err_image", error=exc) + except OSError as exc: # the data dir cannot be written + self._element_notice = tr("sig.err_store", error=exc) + else: + return self._add_signature( + stamplib.Stamp(kind="image", image_path=stored), + label or Path(path).stem) + self._update_place_labels() + return None + + def _pick_image_signature(self) -> None: + path = filedialog.askopenfilename( + title=tr("sig.add_image"), + filetypes=[("Images", "*.png *.jpg *.jpeg *.gif *.bmp *.webp")]) + if path: + self._add_image_signature(path) + + def _toggle_enabled(self, sig_id) -> None: + sig = self._sig(sig_id) + if sig is None: + return + self._element_notice = None + sig.enabled = not sig.enabled # the model decides; the list re-syncs + self._commit_elements() + + def _toggle_all_pages(self) -> None: + """"On every page" for the selected signature. The direction comes + from the MODEL, never from the checkbox (the list re-syncs it).""" + sig = self._sig(self.selected_id) + if sig is None or self._page_anchor(): + return + self._element_notice = None + if not sig.stamp.all_pages: + sig.stamp = dataclasses.replace(sig.stamp, all_pages=True, + page=None, page_anchor=None) + else: # back onto the previewed page + # _sig_placed, not "has coordinates": a placement saved for + # another page size must stay unplaced until the user clicks. + placed = self._sig_placed(sig) + sig.stamp = dataclasses.replace( + sig.stamp, all_pages=False, + page=(self.cur_page + 1) if placed else None) + if placed: + sig.placed_on = tuple(self.template_dims[self.cur_page]) + self._sync_page_to_selection() + self._commit_elements() + + def _reset_selected_position(self) -> None: + """Forget the selected element's position (the vignette goes back to + its default corner; a signature keeps its "every page" flag).""" + self._element_notice = None + if self.selected_id == VIGNETTE_ID: + self.profile.settings.vignette = None + else: + sig = self._sig(self.selected_id) + if sig is None: + return + sig.stamp = dataclasses.replace(sig.stamp, page=None, page_anchor=None, + x=None, y=None) + sig.placed_on = None + self._sync_page_to_selection() # empties the field + self._commit_elements() + + def _edit_selected(self) -> None: + sig = self._sig(self.selected_id) + if sig is None: + return + if sig.stamp.kind == "text": + self._open_text_dialog(sig) + else: + self._open_image_dialog(sig) + + def _delete_selected(self) -> None: + sig = self._sig(self.selected_id) + if sig is None: + return + self._confirm_modal( + tr("sig.delete_title"), tr("sig.delete_body", name=sig.label), + tr("sig.delete_confirm"), tr("sig.delete_keep"), + on_confirm=lambda: self._delete_signature(sig.id)) + + def _delete_signature(self, sig_id) -> None: + """Remove a signature from the library, with its stored image when + no other signature uses it (profile_store decides).""" + self._element_notice = None + self.store.remove_signature(self.profile, sig_id) + self._preview_cache.clear() + self._scaled_cache.clear() + self.selected_id = None + self._ensure_selection() # re-picks + re-syncs the page field + self._commit_elements() + + def _close_dialog(self) -> None: + """Close the editor dialog, if any (step change, reset, language).""" + if _alive(self._dialog): + self._dialog.destroy() + self._dialog = None + self._dialog_state = {} + + # ------------------------------------------------- step 6: editor dialogs + # One non-blocking window at a time (self._dialog), closed by any step + # change, reset or language switch. Its fields are plain widgets read + # with .get() — no tk variable (see __init__); the non-widget values + # (font, colour, strokes) live in self._dialog_state. + def _open_dialog(self, title: str, geometry: str): + """Open the editor dialog (any previous one is closed first). No + wait_window: the handlers do the work, so tests can drive them.""" + self._close_dialog() + win = ctk.CTkToplevel(self) + win.title(title) + win.geometry(geometry) + win.transient(self) + win.resizable(False, False) + win.protocol("WM_DELETE_WINDOW", self._close_dialog) # same as Cancel + self._dialog = win + win.after(80, lambda: _alive(win) and win.grab_set()) + return win + + def _dialog_footer(self, win, on_save, *, wrap: int) -> None: + """Last row of every dialog (Cancel / Save) with the red error label + above it. Packed FIRST, from the bottom: whatever the content needs, + the buttons stay inside the fixed-size window.""" + row = ctk.CTkFrame(win, fg_color="transparent") + row.pack(side="bottom", fill="x", padx=18, pady=(4, 14)) + self.dlg_save_btn = ctk.CTkButton(row, text=tr("sig.save"), width=150, + command=on_save) + self.dlg_save_btn.pack(side="right", padx=(8, 0)) + self.dlg_cancel_btn = ctk.CTkButton( + row, text=tr("sig.cancel"), width=150, + fg_color="transparent", border_width=1, + text_color=("gray20", "gray80"), command=self._close_dialog) + self.dlg_cancel_btn.pack(side="right") + self.dlg_error_lbl = ctk.CTkLabel(win, text="", anchor="w", justify="left", + wraplength=wrap, + text_color=("#b3261e", "#e08a8a")) + self.dlg_error_lbl.pack(side="bottom", fill="x", padx=18) + + def _dialog_error(self, message: str) -> None: + if _alive(getattr(self, "dlg_error_lbl", None)): + self.dlg_error_lbl.configure(text=message) + + @staticmethod + def _dialog_number(raw: str, maximum: float) -> float | None: + """A dialog field as a number in (0, maximum] (decimal comma + accepted), or None.""" + try: + value = float(raw.strip().replace(",", ".")) + except ValueError: + return None + return value if 0 < value <= maximum else None # (NaN fails both) + + def _blank_ctk_image(self): + """1×1 transparent image standing for "no preview", created once per + app (a CTkImage binds to the root that first renders it).""" + if self._blank_img is None: + pil = Image.new("RGBA", (1, 1), (0, 0, 0, 0)) + self._blank_img = ctk.CTkImage(light_image=pil, dark_image=pil, size=(1, 1)) + return self._blank_img + + def _preview_box(self, win, height: int): + """White box holding the dialog's preview label (starts blank).""" + frame = ctk.CTkFrame(win, height=height, fg_color="white") + frame.pack(fill="x", padx=18) + frame.pack_propagate(False) # fixed height, whatever it shows + self.dlg_preview_lbl = ctk.CTkLabel(frame, text="") + self.dlg_preview_lbl.pack(expand=True) + self._set_dialog_preview(None) + + def _set_dialog_preview(self, img, fit=(1, 1), max_zoom: float = 1.0) -> None: + """Show a PIL image in the dialog's preview label, scaled down to fit + ``fit`` and never enlarged beyond ``max_zoom``; None shows nothing. + Each preview is a FRESH CTkImage pinned on the label, and "nothing" + is the blank image — never ``image=None``: with it CustomTkinter + 5.2.2 leaves the previous picture on screen, and once its last + reference is gone the next configure raises TclError.""" + if img is None: + shown = self._blank_ctk_image() + else: + zoom = min(fit[0] / img.width, fit[1] / img.height, max_zoom) + size = (max(1, round(img.width * zoom)), max(1, round(img.height * zoom))) + small = img.copy() + small.thumbnail((size[0] * 2, size[1] * 2)) # HiDPI headroom, cheap rescale + shown = ctk.CTkImage(light_image=small, dark_image=small, size=size) + self.dlg_preview_lbl.configure(image=shown) + self.dlg_preview_lbl._cachet_img = shown # noqa: SLF001 - keep-alive ref + + def _paint_color_button(self) -> None: + color = self._dialog_state["color"] + self.dlg_color_btn.configure(text=color, fg_color=color, hover_color=color, + text_color=_text_on(color)) + + def _pick_dialog_color(self) -> None: + """Colour of the text / of the drawing, through the native chooser.""" + state = self._dialog_state + _rgb, hexv = colorchooser.askcolor( + color=state["color"], parent=self._dialog, title=tr("sig.color_title")) + if not _alive(self._dialog) or not hexv: # closed meanwhile, or cancelled + return + state["color"] = hexv.upper() + self._paint_color_button() + if state["kind"] == "draw": # the strokes already on screen + self.dlg_draw_canvas.itemconfigure("all", fill=state["color"]) + else: + self._update_text_preview() + + # --- text signature (add / edit) + @staticmethod + def _font_display(font: str) -> str: + """Menu text of a font: a bundled font's name, a custom file's name.""" + bundled = stamplib.BUNDLED_FONTS.get(font.strip().lower()) + return bundled[0] if bundled else Path(font).name + + def _open_text_dialog(self, sig=None) -> None: + """Add (``sig`` None) or edit a text signature: text, font, size and + colour, with a live preview rendered by the stamping code itself.""" + win = self._open_dialog( + tr("sig.text_title_edit" if sig else "sig.text_title_add"), "560x600") + stamp = sig.stamp if sig else stamplib.Stamp(kind="text") + self._dialog_state = {"kind": "text", "sig_id": sig.id if sig else None, + "font": stamp.font, "color": stamp.color.upper()} + self._dialog_footer(win, self._apply_text_dialog, wrap=520) + gray = {"text_color": ("gray25", "gray70"), "font": ctk.CTkFont(size=11)} + + ctk.CTkLabel(win, text=tr("sig.name")).pack(anchor="w", padx=18, pady=(12, 0)) + self.dlg_name_entry = ctk.CTkEntry(win) + if sig: + self.dlg_name_entry.insert(0, sig.label) + self.dlg_name_entry.pack(fill="x", padx=18) + ctk.CTkLabel(win, text=tr("sig.text")).pack(anchor="w", padx=18, pady=(6, 0)) + # wrap="none": the stamp breaks lines only at real newlines, so the + # box must not wrap visually (a long line would look like several + # and be stamped as one, wider than the page). It scrolls instead. + self.dlg_text_box = ctk.CTkTextbox(win, height=90, wrap="none") + self.dlg_text_box.insert("1.0", stamp.text) + self.dlg_text_box.pack(fill="x", padx=18) + # no kwargs: {date} and {filename} are shown literally + ctk.CTkLabel(win, text=tr("sig.text_hint"), justify="left", anchor="w", + wraplength=520, **gray).pack(anchor="w", padx=18, pady=(2, 4)) + + row = ctk.CTkFrame(win, fg_color="transparent") + row.pack(fill="x", padx=18, pady=2) + ctk.CTkLabel(row, text=tr("sig.font")).pack(side="left") + self.dlg_font_menu = ctk.CTkOptionMenu( + row, width=240, + values=[name for _id, name in stamplib.font_choices()] + + [tr("sig.font_custom")], + command=self._on_dialog_font) + self.dlg_font_menu.set(self._font_display(stamp.font)) + self.dlg_font_menu.pack(side="left", padx=8) + + row = ctk.CTkFrame(win, fg_color="transparent") + row.pack(fill="x", padx=18, pady=2) + ctk.CTkLabel(row, text=tr("sig.size")).pack(side="left") + self.dlg_size_entry = ctk.CTkEntry(row, width=70, justify="center") + self.dlg_size_entry.insert(0, f"{stamp.font_size:g}") + self.dlg_size_entry.pack(side="left", padx=(8, 18)) + ctk.CTkLabel(row, text=tr("sig.color")).pack(side="left") + self.dlg_color_btn = ctk.CTkButton(row, width=110, + command=self._pick_dialog_color) + self.dlg_color_btn.pack(side="left", padx=8) + self._paint_color_button() + + ctk.CTkLabel(win, text=tr("sig.preview")).pack(anchor="w", padx=18, pady=(6, 0)) + self._preview_box(win, 130) + self.dlg_size_lbl = ctk.CTkLabel(win, text="", height=18, **gray) + self.dlg_size_lbl.pack(anchor="w", padx=18) + for widget in (self.dlg_text_box, self.dlg_size_entry): + for seq in ("", ""): + widget.bind(seq, self._on_text_dialog_edit) + self._update_text_preview() + + def _on_text_dialog_edit(self, _event=None) -> None: + """The user typed (or pasted) in the text dialog.""" + self._dialog_state["edited"] = True + self._update_text_preview() + + def _on_dialog_font(self, display: str) -> None: + state = self._dialog_state + if display == tr("sig.font_custom"): + path = filedialog.askopenfilename( + parent=self._dialog, title=tr("sig.font_custom"), + filetypes=[("Fonts", "*.ttf *.otf")]) + if not _alive(self._dialog): # closed while the picker was open + return + if path: + state["font"] = path + # shows the file's name — or, cancelled, the font still in use + self.dlg_font_menu.set(self._font_display(state["font"])) + else: + state["font"] = next( + (fid for fid, name in stamplib.font_choices() if name == display), + state["font"]) + self._update_text_preview() + + def _dialog_text_stamp(self): + """``(stamp, None)`` from the text dialog's fields, or ``(None, + message)`` when the text is empty or the size is not usable.""" + text = self.dlg_text_box.get("1.0", "end-1c") + if not text.strip(): + return None, tr("sig.err_text_empty") + size = self._dialog_number(self.dlg_size_entry.get(), stamplib.MAX_FONT_SIZE) + if size is None: + return None, tr("sig.err_size", max=int(stamplib.MAX_FONT_SIZE)) + state = self._dialog_state + return stamplib.Stamp(kind="text", text=text, font=state["font"], + color=state["color"], font_size=size), None + + def _update_text_preview(self) -> None: + """Render the text as it will be stamped (same code as the PDF), on + every change. An oversized text is refused by the pixel budget in + milliseconds, so typing can never freeze the window; whatever goes + wrong becomes the dialog's message, never a traceback in a Tk + callback.""" + if not _alive(self._dialog) or self._dialog_state.get("kind") != "text": + return + stamp, error = self._dialog_text_stamp() + content = None + if stamp is not None: + try: + content = stamplib.stamp_content( + stamp, filename=self._sample_filename()) + except Exception as exc: # noqa: BLE001 - MemoryError, font, budget, … + error = tr("sig.err_render", error=str(exc) or type(exc).__name__) + elif (not self._dialog_state.get("edited") + and not self.dlg_text_box.get("1.0", "end-1c").strip()): + # A dialog just opened on an empty text: no reproach before the + # user has typed anything or tried to save. + error = None + self._dialog_error(error or "") + if content is None: + self._set_dialog_preview(None) + self.dlg_size_lbl.configure(text="") + return + img, (w_pt, h_pt) = content + # at most 1.5 screen px per point: a small text is not blown up, and + # the size line below tells how large it really is on the page + self._set_dialog_preview(img, fit=(500, 120), + max_zoom=1.5 * 72 / stamplib.TEXT_DPI) + self.dlg_size_lbl.configure( + text=tr("sig.preview_size", w=round(w_pt), h=round(h_pt))) + + def _apply_text_dialog(self) -> None: + """Save of the text dialog. On an error the dialog stays open with + the message; an oversized text is refused here for good (never added + to the library, never saved).""" + if not _alive(self._dialog) or self._dialog_state.get("kind") != "text": + return + self._dialog_state["edited"] = True # from now on, errors stay visible + stamp, error = self._dialog_text_stamp() + if stamp is not None: + try: + stamplib.validate_stamp(stamp, placed=False) + except stamplib.StampError as exc: + error = tr("sig.err_render", error=exc) + if error: + self._dialog_error(error) + return + first_line = next(ln.strip() for ln in stamp.text.splitlines() if ln.strip()) + label = (self.dlg_name_entry.get().strip() + or first_line[:40])[:profile_store.MAX_LABEL_LEN] + sig = self._sig(self._dialog_state["sig_id"]) + if sig is None: + self._add_signature(stamp, label) + else: # placement and placed_on are KEPT + sig.stamp = dataclasses.replace( + sig.stamp, text=stamp.text, font=stamp.font, color=stamp.color, + font_size=stamp.font_size) + sig.label = label + self._content_changed() + self._close_dialog() + + def _content_changed(self) -> None: + """A signature's content was edited: its cached previews are stale.""" + self._element_notice = None + self._preview_cache.clear() + self._scaled_cache.clear() + self._commit_elements() + + # --- freehand drawing (add) + def _open_draw_dialog(self) -> None: + """Draw a signature by hand. The strokes are the model — the canvas + is only their on-screen echo — and stamps.render_strokes_image turns + them into a transparent PNG kept in the user's signature store.""" + import tkinter as tk + win = self._open_dialog(tr("sig.draw_title"), "660x420") + self._dialog_state = {"kind": "draw", "sig_id": None, + "color": stamplib.DEFAULT_COLOR, "strokes": []} + self._dialog_footer(win, self._apply_draw_dialog, wrap=620) + ctk.CTkLabel(win, text=tr("sig.draw_hint"), justify="left", anchor="w", + wraplength=620, text_color=("gray25", "gray70"), + font=ctk.CTkFont(size=11) + ).pack(anchor="w", padx=18, pady=(12, 4)) + self.dlg_draw_canvas = tk.Canvas( + win, width=_DRAW_W, height=_DRAW_H, bg="white", highlightthickness=1, + highlightbackground="#888", cursor="pencil") + self.dlg_draw_canvas.pack(padx=18) + self.dlg_draw_canvas.bind("", self._draw_start) + self.dlg_draw_canvas.bind("", self._draw_move) + row = ctk.CTkFrame(win, fg_color="transparent") + row.pack(fill="x", padx=18, pady=(6, 2)) + self.dlg_color_btn = ctk.CTkButton(row, width=110, + command=self._pick_dialog_color) + self.dlg_color_btn.pack(side="left") + self._paint_color_button() + self.dlg_clear_btn = ctk.CTkButton( + row, text=tr("sig.draw_clear"), width=110, + fg_color="transparent", border_width=1, + text_color=("gray20", "gray80"), command=self._draw_clear) + self.dlg_clear_btn.pack(side="left", padx=8) + + @staticmethod + def _draw_point(event) -> tuple[float, float]: + """Pointer position, clamped to the drawing canvas: a drag goes on + outside it, and far-away points would only inflate the raster.""" + return (min(max(event.x, 0), _DRAW_W), min(max(event.y, 0), _DRAW_H)) + + def _draw_start(self, event) -> None: + state = self._dialog_state + if state.get("kind") != "draw": + return + self._dialog_error("") # "draw something first" is answered + x, y = self._draw_point(event) + state["strokes"].append([(x, y)]) + r = _DRAW_PEN / 2 # a click alone leaves a dot + self.dlg_draw_canvas.create_oval(x - r, y - r, x + r, y + r, + fill=state["color"], outline="") + + def _draw_move(self, event) -> None: + state = self._dialog_state + if not state.get("strokes"): # motion without a press + return + x, y = self._draw_point(event) + px, py = state["strokes"][-1][-1] + state["strokes"][-1].append((x, y)) + self.dlg_draw_canvas.create_line(px, py, x, y, width=_DRAW_PEN, + capstyle="round", fill=state["color"]) + + def _draw_clear(self) -> None: + if self._dialog_state.get("kind") != "draw": + return + self._dialog_state["strokes"] = [] + self.dlg_draw_canvas.delete("all") + self._dialog_error("") + + def _apply_draw_dialog(self) -> None: + """Save of the drawing dialog: rasterise, store, add as an image + signature. Nothing is added when the drawing is empty or cannot be + stored; the dialog then stays open with the reason.""" + state = self._dialog_state + if not _alive(self._dialog) or state.get("kind") != "draw": + return + if not any(state["strokes"]): + self._dialog_error(tr("sig.err_draw_empty")) + return + try: + img = stamplib.render_strokes_image( + state["strokes"], state["color"], width=_DRAW_PEN, scale=_DRAW_SCALE) + except stamplib.StampError: # the pixel budget + self._dialog_error(tr("sig.err_draw_too_large")) + return + try: + stored = self.store.store_image(img) + except OSError as exc: # the data dir cannot be written + self._dialog_error(tr("sig.err_store", error=exc)) + return + width_pt = min(240.0, max(30.0, round( + img.width / _DRAW_SCALE * _DRAW_PT_PER_PX, 1))) + self._add_signature( + stamplib.Stamp(kind="image", image_path=stored, width_pt=width_pt), + tr("sig.drawn_label")) + self._close_dialog() + + # --- image signature (edit only: a new one comes from the file picker) + def _open_image_dialog(self, sig) -> None: + """Edit an image signature: its name and its width on the page.""" + win = self._open_dialog(tr("sig.image_title"), "480x380") + self._dialog_state = {"kind": "image", "sig_id": sig.id} + self._dialog_footer(win, self._apply_image_dialog, wrap=440) + ctk.CTkLabel(win, text=tr("sig.name")).pack(anchor="w", padx=18, pady=(12, 0)) + self.dlg_name_entry = ctk.CTkEntry(win) + self.dlg_name_entry.insert(0, sig.label) + self.dlg_name_entry.pack(fill="x", padx=18) + row = ctk.CTkFrame(win, fg_color="transparent") + row.pack(fill="x", padx=18, pady=(6, 8)) + ctk.CTkLabel(row, text=tr("sig.width")).pack(side="left") + self.dlg_width_entry = ctk.CTkEntry(row, width=80, justify="center") + self.dlg_width_entry.insert(0, f"{sig.stamp.width_pt:g}") + self.dlg_width_entry.pack(side="left", padx=8) + self._preview_box(win, 170) + content = self._content(sig) + if content is None: # missing / unreadable file + self._dialog_error(tr("sig.err_image", error=self._sig_error(sig))) + else: + self._set_dialog_preview(content[0], fit=(420, 160)) + + def _apply_image_dialog(self) -> None: + if not _alive(self._dialog) or self._dialog_state.get("kind") != "image": + return + sig = self._sig(self._dialog_state["sig_id"]) + width = self._dialog_number(self.dlg_width_entry.get(), stamplib.MAX_WIDTH_PT) + if width is None: + self._dialog_error(tr("sig.err_width", max=int(stamplib.MAX_WIDTH_PT))) + return + if sig is not None: + sig.stamp = dataclasses.replace(sig.stamp, width_pt=width) + sig.label = (self.dlg_name_entry.get().strip() + or sig.label)[:profile_store.MAX_LABEL_LEN] + self._content_changed() + self._close_dialog() + def _set_page_entry(self, text: str) -> None: """Programmatic update of the target-page field (click, reset).""" self.page_text = text @@ -1196,63 +2171,65 @@ def _set_page_entry(self, text: str) -> None: self.page_entry.delete(0, "end") self.page_entry.insert(0, text) - def _reset_position(self) -> None: - self.place_page = self.place_x = self.place_y = None - self._set_page_entry("") - self._invalidate_run() - self._update_place_labels() - self._draw_page() - self._refresh_chrome() - def _on_page_entry_change(self) -> None: - """Manual target-page field: lets the signature go to a page other - than the previewed one (e.g. documents whose page of interest differs - from the template). Follows the preview when in range; warns when - beyond the template.""" - if self._running: + """Manual target-page field: a valid page number moves the SELECTED + element (when it is placed on a numbered page) to that page and the + preview follows. A number beyond the template blocks the step.""" + if self._running or self._page_anchor(): return if _alive(getattr(self, "page_entry", None)): self.page_text = self.page_entry.get() raw = self.page_text.strip() - if raw.isdigit() and int(raw) >= 1: + if (raw.isdecimal() and len(raw) <= _MAX_PAGE_DIGITS + and 1 <= int(raw) <= len(self.template_dims)): v = int(raw) - if self.place_x is not None: - self.place_page = v - if self.template_dims and 1 <= v <= len(self.template_dims) \ - and self.cur_page != v - 1: - self.cur_page = v - 1 - self._draw_page() + dims = tuple(self.template_dims[v - 1]) + sig = self._sig(self.selected_id) + if self.selected_id == VIGNETTE_ID and self._vignette_placed(): + vignette = self.profile.settings.vignette + vignette.page, vignette.placed_on = v, dims + self._save_profile() + elif sig and self._sig_placed(sig) and not sig.stamp.all_pages: + sig.stamp = dataclasses.replace(sig.stamp, page=v, page_anchor=None) + sig.placed_on = dims + self._save_profile() + self.cur_page = v - 1 self._invalidate_run() - self._update_place_labels() - self._refresh_chrome() + self._refresh_place() - def _update_place_labels(self) -> None: + def _position_text(self) -> str: + """Position line of the SELECTED element.""" anchor = self._page_anchor() - if _alive(getattr(self, "pos_lbl", None)): - if self.place_x is not None: - if anchor: - text = tr("place.pos_anchor", - anchor=tr(f"anchor.{anchor}_page"), - x=f"{self.place_x:.0f}", y=f"{self.place_y:.0f}") - else: - text = tr("place.pos", page=self.place_page, - x=f"{self.place_x:.0f}", y=f"{self.place_y:.0f}") - elif self.mode_var.get() in ("beid", "azure"): - text = (tr("place.pos_default_anchor", + all_pages = False + if self.selected_id == VIGNETTE_ID: + if not self._vignette_placed(): + return (tr("place.pos_default_anchor", anchor=tr(f"anchor.{anchor}_page")) if anchor else tr("place.pos_default")) - else: - text = tr("place.pos_none") - self.pos_lbl.configure(text=text) + vignette = self.profile.settings.vignette + x, y, page = vignette.x, vignette.y, vignette.page + else: + sig = self._sig(self.selected_id) + if sig is None: + return tr("place.select_hint") + if not self._sig_placed(sig): + return tr("place.pos_none") + x, y, page = sig.stamp.x, sig.stamp.y, self._element_page(sig.id) + all_pages = sig.stamp.all_pages + xy = {"x": f"{x:.0f}", "y": f"{y:.0f}"} + if anchor: + return tr("place.pos_anchor", anchor=tr(f"anchor.{anchor}_page"), **xy) + if all_pages: + return tr("place.pos_all", **xy) + return tr("place.pos", page=page, **xy) + + def _update_place_labels(self) -> None: + if _alive(getattr(self, "pos_lbl", None)): + self.pos_lbl.configure(text=self._position_text()) if _alive(getattr(self, "place_warn_lbl", None)): - warn = self._page_entry_error() or "" - if not warn and not anchor and self.place_page and self.template_dims \ - and self.place_page > len(self.template_dims): - warn = tr("place.page_beyond", page=self.place_page, - total=len(self.template_dims)) - if not warn and self.mode_var.get() == "image" and ( - self.image_path is None or self.place_x is None): - warn = tr("place.image_missing") + warn = self._element_notice or self._place_error() or "" + if not warn and self._profile_error: + warn = tr("place.save_failed", error=self._profile_error) self.place_warn_lbl.configure(text=warn) def _turn_page(self, delta: int) -> None: @@ -1263,7 +2240,7 @@ def _turn_page(self, delta: int) -> None: def _canvas_target_size(self) -> tuple[int, int]: """Target canvas size, derived from the window (grows/shrinks with it).""" - w = max(320, self.winfo_width() - _HELP_PANEL_W - 160) + w = max(320, self.winfo_width() - _HELP_PANEL_W - _ELEMENTS_PANEL_W - 170) h = max(260, int(self.winfo_height() * 0.45)) return w, h @@ -1287,6 +2264,7 @@ def _draw_page(self) -> None: cw, ch = self._canvas_target_size() self.canvas.configure(width=cw, height=ch) self.canvas.delete("all") + self._canvas_imgs = [] # keep-alive refs, per draw pw, ph = self.template_dims[self.cur_page] fw, fh = core.fit_frame(pw, ph, cw, ch) ox, oy = (cw - fw) / 2, (ch - fh) / 2 @@ -1308,50 +2286,133 @@ def _draw_page(self) -> None: anchor=tr(f"anchor.{anchor}_page")) self.page_lbl.configure(text=label) self._frame_geom = (fw, fh, ox, oy) - if self.place_page == self.cur_page + 1 and self.place_x is not None: - self._draw_placeholder(self.place_x, self.place_y) + self._draw_elements() def _on_canvas_click(self, event) -> None: + """A click PLACES the selected element: the clicked point becomes its + lower-left corner on the previewed page (no hit-testing — selection + is made in the list only).""" if not self.template_dims or not hasattr(self, "_frame_geom"): return fw, fh, ox, oy = self._frame_geom cx, cy = event.x - ox, event.y - oy if not (0 <= cx <= fw and 0 <= cy <= fh): return + self._element_notice = None + self._ensure_selection() + if self.selected_id is None: # nothing to place yet + self._update_place_labels() + return pw, ph = self.template_dims[self.cur_page] x, y = core.frame_click_to_pdf_xy(pw, ph, fw, fh, cx, cy) - self.place_page, self.place_x, self.place_y = self.cur_page + 1, x, y - if self._page_anchor() is None: - self._set_page_entry(str(self.place_page)) # click -> target page - self._invalidate_run() - self._update_place_labels() - self._draw_page() - self._refresh_chrome() - - def _placeholder_size_pt(self) -> tuple[float, float]: - """Placeholder size (pt): actual image in image mode, otherwise a 3:1 - vignette box of width page/5 of the current page (beid/azure).""" - pw = self.template_dims[self.cur_page][0] - if self.mode_var.get() == "image" and self.image_path: - return core.image_size_pt(self.image_path) - return core.vignette_size_pt(pw) - - def _draw_placeholder(self, x, y) -> None: + page = self.cur_page + 1 # the anchor page while locked + dims = tuple(self.template_dims[self.cur_page]) + all_pages = False + if self.selected_id == VIGNETTE_ID: + self.profile.settings.vignette = profile_store.Placement( + page=page, x=x, y=y, placed_on=dims) + else: + sig = self._sig(self.selected_id) + all_pages = sig.stamp.all_pages # kept: only x/y move + sig.stamp = dataclasses.replace( + sig.stamp, x=x, y=y, page_anchor=None, + page=None if all_pages else page) + sig.placed_on = dims + if self._page_anchor() is None and not all_pages: + self._set_page_entry(str(page)) # click -> target page + self._commit_elements() + + def _sig_on_preview(self, sig) -> bool: + """True if the signature's placement is in force AND lands on the + previewed page (under an anchor the preview is locked on the one + page every element goes to).""" + if not self._sig_placed(sig): + return False + return bool(self._page_anchor()) or ( + self.cur_page in sig.stamp.page_indexes(len(self.template_dims))) + + def _vignette_on_preview(self) -> bool: + if not self._has_vignette(): + return False + if self._vignette_placed(): + return self.profile.settings.vignette.page == self.cur_page + 1 + # default corner box: the anchor page (the preview is locked on it), + # else the template's LAST page + return bool(self._page_anchor()) or self.cur_page == len(self.template_dims) - 1 + + def _draw_elements(self) -> None: + """Every element shown on the previewed page, to scale: the enabled + signatures in library order, then the vignette; the selected element + last, so it is never hidden under another one.""" + shown = [s.id for s in self.profile.signatures + if s.enabled and self._sig_on_preview(s)] + if self._vignette_on_preview(): + shown.append(VIGNETTE_ID) + selected = self._sig(self.selected_id) + if self.selected_id in shown: + shown.remove(self.selected_id) + shown.append(self.selected_id) + elif selected and not selected.enabled and self._sig_on_preview(selected): + # an unticked signature is drawn only while selected (outline + # only), so the user sees where a click put it + shown.append(self.selected_id) + for element_id in shown: + self._draw_element(element_id) + + def _scaled_preview(self, sig, thumb, w: int, h: int): + """The cached thumbnail resized for the canvas, itself cached per + size: a window resize rescales, it never re-renders the content.""" + key = (self._content_key(sig), w, h) + if key not in self._scaled_cache: + if len(self._scaled_cache) > _SCALED_CACHE_MAX: + self._scaled_cache.clear() + self._scaled_cache[key] = thumb.resize((w, h), Image.LANCZOS) + return self._scaled_cache[key] + + def _draw_element(self, element_id) -> None: fw, fh, ox, oy = self._frame_geom pw, ph = self.template_dims[self.cur_page] - iw, ih = self._placeholder_size_pt() - left, top, w, h = core.pdf_rect_to_frame_rect(pw, ph, fw, fh, x, y, iw, ih) + selected = element_id == self.selected_id + sig = self._sig(element_id) + if sig is not None: + rect = (sig.stamp.x, sig.stamp.y, *self._element_size_pt(element_id)) + elif self._vignette_placed(): + vignette = self.profile.settings.vignette + rect = (vignette.x, vignette.y, *self._element_size_pt(VIGNETTE_ID)) + else: + rect = core.default_vignette_rect(pw, ph) + left, top, w, h = core.pdf_rect_to_frame_rect(pw, ph, fw, fh, *rect) left, top = left + ox, top + oy - if self.mode_var.get() == "image" and self.image_path: - try: - im = Image.open(self.image_path).convert("RGBA") - im = im.resize((max(1, int(w)), max(1, int(h)))) - self._canvas_img = ImageTk.PhotoImage(im) - self.canvas.create_image(left, top, anchor="nw", image=self._canvas_img) - except Exception: # noqa: BLE001 - pass - self.canvas.create_rectangle(left, top, left + w, top + h, - outline="#c00", width=2) + box = (left, top, left + w, top + h) + tags = ("element", f"el:{element_id}") # (a bare all-digit id would read as an item id) + # selected: solid red; others: thin blue dashes + outline = ({"outline": "#c00", "width": 2} if selected + else {"outline": "#3B8ED0", "width": 1, "dash": (3, 2)}) + gray = {"outline": "#777", "width": 2 if selected else 1, "dash": (4, 3)} + if sig is None: # vignette: a labelled box + if self._vignette_placed(): + outline.pop("dash", None) # placed -> solid outline + else: + outline = gray # default position -> gray dashes + self.canvas.create_text( + left + w / 2, top + h / 2, text=tr("place.el_vignette_short"), + font=("", 9), fill="#555", tags=tags) + elif not sig.enabled: + outline = gray # selected but unticked: outline only + else: + content = self._content(sig) + if content is None: # unusable: red box + warning sign + outline = {"outline": "#c00", "width": 2 if selected else 1} + self.canvas.create_text(left + w / 2, top + h / 2, text="⚠", + fill="#c00", tags=tags) + else: + scaled = self._scaled_preview(sig, content[0], + max(1, int(w)), max(1, int(h))) + photo = ImageTk.PhotoImage(scaled, master=self.canvas) + self._canvas_imgs.append(photo) # Tk only keeps a name + self.canvas.create_image(left, top, anchor="nw", image=photo, + tags=tags) + self.canvas.create_rectangle(*box, tags=tags, **outline) def _on_resize(self, event) -> None: # the canvas follows the window size, keeping the page proportions @@ -1376,20 +2437,33 @@ def _build_step_run(self, parent) -> None: if mode in ("beid", "azure"): lines.append(tr("run.summary_level", level=self.pades_level_var.get())) anchor = self._page_anchor() - if self.place_x is not None: + anchor_name = tr(f"anchor.{anchor}_page") if anchor else None + + def placed_phrase(page, x, y, all_pages=False) -> str: + xy = {"x": f"{x:.0f}", "y": f"{y:.0f}"} if anchor: - place = tr("run.place_custom_anchor", - anchor=tr(f"anchor.{anchor}_page"), - x=f"{self.place_x:.0f}", y=f"{self.place_y:.0f}") + return tr("run.place_custom_anchor", anchor=anchor_name, **xy) + if all_pages: + return tr("run.place_all", **xy) + return tr("run.place_custom", page=page, **xy) + + if mode in ("beid", "azure"): + if self._vignette_placed(): + v = self.profile.settings.vignette + place = placed_phrase(v.page, v.x, v.y) + elif anchor: + place = tr("run.place_default_anchor", anchor=anchor_name) else: - place = tr("run.place_custom", page=self.place_page, - x=f"{self.place_x:.0f}", y=f"{self.place_y:.0f}") - elif anchor: - place = tr("run.place_default_anchor", - anchor=tr(f"anchor.{anchor}_page")) - else: - place = tr("run.place_default") - lines.append(tr("run.summary_place", place=place)) + place = tr("run.place_default") + lines.append(tr("run.summary_place", place=place)) + enabled = self._enabled_signatures() + if enabled: + lines.append(tr("run.summary_stamps", count=len(enabled))) + for sig in enabled: + place = (placed_phrase(self._element_page(sig.id), sig.stamp.x, + sig.stamp.y, sig.stamp.all_pages) + if self._sig_placed(sig) else tr("place.st_unplaced")) + lines.append(tr("run.stamp_line", name=sig.label, place=place)) if anchor: lines.append(tr(f"run.summary_anchor_{anchor}")) lines.append(tr("run.summary_output", output=self.output_dir)) @@ -1451,13 +2525,21 @@ def _show_card_box(self) -> None: def _launch(self) -> None: if self._running or not self.valid_paths or not self.output_dir: return - # beid/azure: a click places the vignette; without a click, default - # placement (bottom-right, last page). place_* are None in that case - # and process_batch derives the placement from them. With the - # validation-step anchor active, the page is resolved PER DOCUMENT - # (first/last) instead of the fixed clicked page — page and - # page_anchor are mutually exclusive. + # Visual signatures: every ENABLED library entry, in list order. + # page/x/y/page_anchor carry the VIGNETTE placement + # only (beid/azure; all None in image mode): a placed vignette, or + # None -> default corner box (bottom-right, last page). With the + # validation-step anchor active, every element is resolved PER + # DOCUMENT on its first/last page instead of a fixed page — `page` + # and `page_anchor` stay mutually exclusive. anchor = self._page_anchor() + crypto = self._has_vignette() + v = self.profile.settings.vignette if (crypto and self._vignette_placed()) else None + stamp_list = [ + dataclasses.replace(s.stamp, page=None, all_pages=False, page_anchor=anchor) + if anchor else s.stamp + for s in self._enabled_signatures() + ] cfg = core.RunConfig( inputs=list(self.valid_paths), output=self.output_dir, @@ -1465,11 +2547,11 @@ def _launch(self) -> None: template=self.template_path, pades_level=self.pades_level_var.get(), lib=self.default_lib, - image_path=self.image_path, - page=None if anchor else self.place_page, - page_anchor=anchor, - x=self.place_x, - y=self.place_y, + stamps=stamp_list, + page=None if (anchor or v is None) else v.page, + page_anchor=anchor if crypto else None, + x=v.x if v else None, + y=v.y if v else None, # azure settings (ignored by the other modes). The worker batch # reuses the credential cached by "Sign in with Microsoft"; if # the user skipped it, the login happens on the worker thread. @@ -1579,11 +2661,9 @@ def _build_step_results(self, parent) -> None: (tr("res.col_detail"), 360)], height=12, ) - for r in results: - self.summary_table.insert( - "", "end", - values=(r.path.name, tr("res.ok") if r.ok else tr("res.fail"), - r.detail)) + self._fill_table(self.summary_table, [ + (r.path.name, tr("res.ok") if r.ok else tr("res.fail"), r.detail) + for r in results]) row = ctk.CTkFrame(parent, fg_color="transparent") row.pack(fill="x", padx=8, pady=(6, 4)) self.open_folder_btn = ctk.CTkButton( @@ -1612,7 +2692,10 @@ def _open_output_folder(self) -> None: def launch_gui(args) -> int: """Entry point called by `sign_pdfs_beid.py --gui`.""" ctk.set_appearance_mode("system") - i18n.set_language(i18n.system_language()) - app = CachetApp(args) + # Language: the user's saved choice, else the system's. + store = profile_store.ProfileStore() + lang = store.load().settings.language + i18n.set_language(lang if lang in i18n.LANGUAGES else i18n.system_language()) + app = CachetApp(args, store=store) app.mainloop() return 0 diff --git a/i18n.py b/i18n.py index 843387f..c510a62 100644 --- a/i18n.py +++ b/i18n.py @@ -167,24 +167,29 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "your Belgian eID card (a qualified signature, legally equal to a " "handwritten one), with your personal certificate in Azure Key Vault " "(an advanced signature — one Microsoft sign-in for the whole " - "batch), or stamp a simple image with no legal value. A template " - "guarantees that every document receives its signature at exactly " - "the same spot.\n\nThis assistant guides you through eight steps: " - "choose a template, the documents and an output folder, validate " - "the batch, pick and place the signature, then sign and review the " - "report." + "batch), or add visual signatures with no legal value — typed " + "text, images or a drawing, one or several per document. A " + "template guarantees that every document receives each element at " + "exactly the same spot. Your signatures and preferences are " + "remembered for next time.\n\nThis assistant guides you through " + "eight steps: choose a template, the documents and an output " + "folder, validate the batch, pick the signature type, place the " + "elements, then sign and review the report." ), "fr": ( "Cachet signe tout un lot de documents PDF en une seule fois. " "Signez avec votre carte eID belge (signature qualifiée, " "juridiquement équivalente à une signature manuscrite), avec votre " "certificat personnel dans Azure Key Vault (signature avancée — " - "une seule connexion Microsoft pour tout le lot), ou apposez une " - "simple image sans valeur juridique. Un modèle garantit que chaque " - "document reçoit sa signature exactement au même endroit.\n\nCet " - "assistant vous guide en huit étapes : choix du modèle, des " - "documents et du dossier de sortie, validation du lot, choix et " - "positionnement de la signature, puis signature et rapport final." + "une seule connexion Microsoft pour tout le lot), ou ajoutez des " + "signatures visuelles sans valeur juridique — texte saisi, images " + "ou dessin, une ou plusieurs par document. Un modèle garantit que " + "chaque document reçoit chaque élément exactement au même endroit. " + "Vos signatures et vos préférences sont mémorisées pour la " + "prochaine fois.\n\nCet assistant vous guide en huit étapes : " + "choix du modèle, des documents et du dossier de sortie, " + "validation du lot, choix du type de signature, positionnement " + "des éléments, puis signature et rapport final." ), "nl": ( "Cachet ondertekent een hele reeks PDF-documenten in één keer. " @@ -192,12 +197,15 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "handtekening, juridisch gelijkwaardig aan een handgeschreven " "handtekening), met uw persoonlijke certificaat in Azure Key Vault " "(een geavanceerde handtekening — één Microsoft-aanmelding voor de " - "hele reeks), of plaats een eenvoudige afbeelding zonder juridische " - "waarde. Een sjabloon garandeert dat elk document zijn handtekening " - "op exact dezelfde plek krijgt.\n\nDeze assistent begeleidt u in " - "acht stappen: kies een sjabloon, de documenten en een uitvoermap, " - "valideer de reeks, kies en plaats de handtekening, onderteken en " - "bekijk het rapport." + "hele reeks), of voeg visuele handtekeningen zonder juridische " + "waarde toe — getypte tekst, afbeeldingen of een tekening, één of " + "meerdere per document. Een sjabloon garandeert dat elk document " + "elk element op exact dezelfde plek krijgt. Uw handtekeningen en " + "voorkeuren worden onthouden voor de volgende keer.\n\nDeze " + "assistent begeleidt u in acht stappen: kies een sjabloon, de " + "documenten en een uitvoermap, valideer de reeks, kies het " + "handtekeningtype, plaats de elementen, onderteken en bekijk het " + "rapport." ), "de": ( "Cachet signiert einen ganzen Stapel PDF-Dokumente in einem " @@ -205,37 +213,44 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "qualifizierte Signatur, rechtlich der handschriftlichen " "Unterschrift gleichgestellt), mit Ihrem persönlichen Zertifikat " "in Azure Key Vault (eine fortgeschrittene Signatur — eine einzige " - "Microsoft-Anmeldung für den ganzen Stapel), oder stempeln Sie ein " - "einfaches Bild ohne Rechtswert auf. Eine Vorlage stellt sicher, " - "dass jedes Dokument seine Signatur an genau derselben Stelle " - "erhält.\n\nDieser Assistent führt Sie durch acht Schritte: " - "Vorlage, Dokumente und Ausgabeordner wählen, Stapel prüfen, " - "Signatur wählen und platzieren, dann signieren und den Bericht " - "prüfen." + "Microsoft-Anmeldung für den ganzen Stapel), oder fügen Sie " + "visuelle Signaturen ohne Rechtswert hinzu — getippten Text, " + "Bilder oder eine Zeichnung, eine oder mehrere pro Dokument. Eine " + "Vorlage stellt sicher, dass jedes Dokument jedes Element an genau " + "derselben Stelle erhält. Ihre Signaturen und Einstellungen werden " + "für das nächste Mal gespeichert.\n\nDieser Assistent führt Sie " + "durch acht Schritte: Vorlage, Dokumente und Ausgabeordner wählen, " + "Stapel prüfen, Signaturtyp wählen, Elemente platzieren, dann " + "signieren und den Bericht prüfen." ), "es": ( "Cachet firma un lote completo de documentos PDF de una sola vez. " "Firme con su tarjeta eID belga (firma cualificada, legalmente " "equivalente a la manuscrita), con su certificado personal en " "Azure Key Vault (firma avanzada — un solo inicio de sesión de " - "Microsoft para todo el lote), o estampe una simple imagen sin " - "valor legal. Una plantilla garantiza que cada documento reciba su " - "firma exactamente en el mismo lugar.\n\nEste asistente le guía en " + "Microsoft para todo el lote), o añada firmas visuales sin valor " + "legal — texto escrito, imágenes o un dibujo, una o varias por " + "documento. Una plantilla garantiza que cada documento reciba cada " + "elemento exactamente en el mismo lugar. Sus firmas y preferencias " + "se recuerdan para la próxima vez.\n\nEste asistente le guía en " "ocho pasos: elegir la plantilla, los documentos y la carpeta de " - "salida, validar el lote, elegir y colocar la firma y, por último, " - "firmar y revisar el informe." + "salida, validar el lote, elegir el tipo de firma, colocar los " + "elementos y, por último, firmar y revisar el informe." ), "pt": ( "O Cachet assina um lote inteiro de documentos PDF de uma só vez. " "Assine com o seu cartão eID belga (assinatura qualificada, " "juridicamente equivalente à manuscrita), com o seu certificado " "pessoal no Azure Key Vault (assinatura avançada — um único início " - "de sessão Microsoft para todo o lote), ou aplique uma simples " - "imagem sem valor legal. Um modelo garante que cada documento " - "recebe a assinatura exatamente no mesmo sítio.\n\nEste assistente " - "guia-o em oito passos: escolher o modelo, os documentos e a pasta " - "de saída, validar o lote, escolher e posicionar a assinatura e, " - "por fim, assinar e rever o relatório." + "de sessão Microsoft para todo o lote), ou adicione assinaturas " + "visuais sem valor legal — texto escrito, imagens ou um desenho, " + "uma ou várias por documento. Um modelo garante que cada documento " + "recebe cada elemento exatamente no mesmo sítio. As suas " + "assinaturas e preferências ficam guardadas para a próxima " + "vez.\n\nEste assistente guia-o em oito passos: escolher o modelo, " + "os documentos e a pasta de saída, validar o lote, escolher o tipo " + "de assinatura, posicionar os elementos e, por fim, assinar e " + "rever o relatório." ), }, "landing.language_label": { @@ -330,33 +345,37 @@ def split_markup(text: str) -> list[tuple[str, bool]]: }, "cancel.body": { "en": ( - "This discards everything entered so far — selected files, " - "settings and results — and returns to the welcome screen." + "This discards the current session — template, selected files, " + "validation and results — and returns to the welcome screen. Your " + "saved signatures and preferences are kept." ), "fr": ( - "Cela efface tout ce qui a été saisi jusqu'ici — fichiers " - "sélectionnés, réglages et résultats — et revient à l'écran " - "d'accueil." + "Cela efface la session en cours — modèle, fichiers sélectionnés, " + "validation et résultats — et revient à l'écran d'accueil. Vos " + "signatures enregistrées et vos préférences sont conservées." ), "nl": ( - "Hiermee wordt alles gewist wat u tot nu toe hebt ingevoerd — " - "geselecteerde bestanden, instellingen en resultaten — en keert u " - "terug naar het welkomstscherm." + "Hiermee wordt de huidige sessie gewist — sjabloon, geselecteerde " + "bestanden, validatie en resultaten — en keert u terug naar het " + "welkomstscherm. Uw opgeslagen handtekeningen en voorkeuren " + "blijven behouden." ), "de": ( - "Dadurch werden alle bisherigen Eingaben verworfen — ausgewählte " - "Dateien, Einstellungen und Ergebnisse — und Sie kehren zum " - "Startbildschirm zurück." + "Dadurch wird die aktuelle Sitzung verworfen — Vorlage, " + "ausgewählte Dateien, Prüfung und Ergebnisse — und Sie kehren zum " + "Startbildschirm zurück. Ihre gespeicherten Signaturen und " + "Einstellungen bleiben erhalten." ), "es": ( - "Esto descarta todo lo introducido hasta ahora — archivos " - "seleccionados, ajustes y resultados — y vuelve a la pantalla de " - "bienvenida." + "Esto descarta la sesión actual — plantilla, archivos " + "seleccionados, validación y resultados — y vuelve a la pantalla " + "de bienvenida. Sus firmas guardadas y sus preferencias se " + "conservan." ), "pt": ( - "Isto elimina tudo o que foi introduzido até agora — ficheiros " - "selecionados, definições e resultados — e regressa ao ecrã " - "inicial." + "Isto elimina a sessão atual — modelo, ficheiros selecionados, " + "validação e resultados — e regressa ao ecrã inicial. As suas " + "assinaturas guardadas e as suas preferências são mantidas." ), }, "cancel.confirm": { @@ -466,37 +485,37 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "step.files.help": { "en": ( "Choose every PDF document to sign in this run. The same " - "signature, position and settings are applied to the whole batch. " - "Documents that do not match the template are filtered out at the " - "next step." + "signatures, positions and settings are applied to the whole " + "batch. Documents that do not match the template are filtered out " + "at the next step." ), "fr": ( - "Choisissez tous les documents PDF à signer dans ce lot. La même " - "signature, la même position et les mêmes réglages s'appliquent à " - "tout le lot. Les documents qui ne correspondent pas au modèle " - "seront écartés à l'étape suivante." + "Choisissez tous les documents PDF à signer dans ce lot. Les mêmes " + "signatures, les mêmes positions et les mêmes réglages " + "s'appliquent à tout le lot. Les documents qui ne correspondent " + "pas au modèle seront écartés à l'étape suivante." ), "nl": ( "Kies alle PDF-documenten die u in deze reeks wilt ondertekenen. " - "Dezelfde handtekening, positie en instellingen gelden voor de " + "Dezelfde handtekeningen, posities en instellingen gelden voor de " "hele reeks. Documenten die niet met het sjabloon overeenkomen, " "worden in de volgende stap uitgefilterd." ), "de": ( "Wählen Sie alle PDF-Dokumente, die in diesem Durchgang signiert " - "werden sollen. Dieselbe Signatur, Position und dieselben " + "werden sollen. Dieselben Signaturen, Positionen und " "Einstellungen gelten für den gesamten Stapel. Dokumente, die " "nicht zur Vorlage passen, werden im nächsten Schritt aussortiert." ), "es": ( - "Elija todos los documentos PDF que desea firmar en este lote. La " - "misma firma, posición y ajustes se aplican a todo el lote. Los " - "documentos que no coincidan con la plantilla se descartarán en " - "el paso siguiente." + "Elija todos los documentos PDF que desea firmar en este lote. Las " + "mismas firmas, posiciones y ajustes se aplican a todo el lote. " + "Los documentos que no coincidan con la plantilla se descartarán " + "en el paso siguiente." ), "pt": ( - "Escolha todos os documentos PDF a assinar neste lote. A mesma " - "assinatura, posição e definições aplicam-se a todo o lote. Os " + "Escolha todos os documentos PDF a assinar neste lote. As mesmas " + "assinaturas, posições e definições aplicam-se a todo o lote. Os " "documentos que não correspondam ao modelo serão excluídos no " "passo seguinte." ), @@ -658,8 +677,12 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "Azure (AES) — an advanced signature with your personal certificate " "in Azure Key Vault. One Microsoft sign-in for the whole batch, no " "card; only the document fingerprint ever leaves this machine.\n\n" - "Image — pastes a picture. NOT a cryptographic signature, no legal " - "value; works fully offline.\n\n" + "Visual signature — stamps typed text, an image or a drawing on " + "the pages. NOT a cryptographic signature, no legal value; works " + "fully offline.\n\n" + "In every mode, visual signatures are added and placed on the " + "next step. With eID or Azure they are applied first, and the " + "cryptographic signature then covers them.\n\n" "The PAdES level sets durability. Keep b-lta: the signature stays " "verifiable for decades (needs network). Choose b-b only to sign " "offline. The full documentation — modes, levels, glossary and " @@ -675,9 +698,14 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "dans Azure Key Vault. Une seule connexion Microsoft pour tout le " "lot, sans carte ; seule l'empreinte du document quitte cette " "machine.\n\n" - "Image — colle une image. Ce N'EST PAS une signature " + "Signature visuelle — appose un texte saisi, une image ou un " + "dessin sur les pages. Ce N'EST PAS une signature " "cryptographique, sans valeur juridique ; fonctionne entièrement " "hors ligne.\n\n" + "Dans tous les modes, les signatures visuelles s'ajoutent et se " + "positionnent à l'étape suivante. Avec eID ou Azure, elles sont " + "apposées en premier, puis la signature cryptographique les " + "couvre.\n\n" "Le niveau PAdES règle la durabilité. Gardez b-lta : la signature " "reste vérifiable pendant des décennies (réseau requis). Choisissez " "b-b uniquement pour signer hors ligne. La documentation complète — " @@ -693,8 +721,12 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "certificaat in Azure Key Vault. Eén Microsoft-aanmelding voor de " "hele reeks, zonder kaart; alleen de vingerafdruk van het document " "verlaat deze computer.\n\n" - "Afbeelding — plakt een afbeelding. GEEN cryptografische " + "Visuele handtekening — brengt getypte tekst, een afbeelding of " + "een tekening aan op de pagina's. GEEN cryptografische " "handtekening, zonder juridische waarde; werkt volledig offline.\n\n" + "In elke modus voegt u visuele handtekeningen toe en plaatst u ze " + "in de volgende stap. Met eID of Azure worden ze eerst " + "aangebracht; de cryptografische handtekening omvat ze daarna.\n\n" "Het PAdES-niveau bepaalt de duurzaamheid. Behoud b-lta: de " "handtekening blijft tientallen jaren verifieerbaar (netwerk " "vereist). Kies b-b alleen om offline te ondertekenen. De volledige " @@ -712,8 +744,13 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "persönlichen Zertifikat in Azure Key Vault. Eine einzige " "Microsoft-Anmeldung für den ganzen Stapel, ohne Karte; nur der " "Fingerabdruck des Dokuments verlässt diesen Rechner.\n\n" - "Bild — fügt ein Bild ein. KEINE kryptografische Signatur, ohne " + "Visuelle Signatur — stempelt getippten Text, ein Bild oder eine " + "Zeichnung auf die Seiten. KEINE kryptografische Signatur, ohne " "Rechtswert; funktioniert vollständig offline.\n\n" + "In jedem Modus werden visuelle Signaturen im nächsten Schritt " + "hinzugefügt und platziert. Mit eID oder Azure werden sie zuerst " + "aufgebracht; die kryptografische Signatur deckt sie anschließend " + "mit ab.\n\n" "Das PAdES-Niveau bestimmt die Haltbarkeit. Behalten Sie b-lta: Die " "Signatur bleibt über Jahrzehnte prüfbar (Netzwerk erforderlich). " "Wählen Sie b-b nur, um offline zu signieren. Die vollständige " @@ -730,8 +767,12 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "Key Vault. Un solo inicio de sesión de Microsoft para todo el " "lote, sin tarjeta; solo la huella del documento sale de este " "equipo.\n\n" - "Imagen — pega una imagen. NO es una firma criptográfica, sin valor " - "legal; funciona totalmente sin conexión.\n\n" + "Firma visual — estampa un texto escrito, una imagen o un dibujo " + "en las páginas. NO es una firma criptográfica, sin valor legal; " + "funciona totalmente sin conexión.\n\n" + "En todos los modos, las firmas visuales se añaden y se colocan " + "en el paso siguiente. Con eID o Azure se aplican primero, y la " + "firma criptográfica las cubre después.\n\n" "El nivel PAdES define la durabilidad. Mantenga b-lta: la firma " "seguirá siendo verificable durante décadas (requiere red). Elija " "b-b solo para firmar sin conexión. La documentación completa — " @@ -747,8 +788,12 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "Azure Key Vault. Um único início de sessão Microsoft para todo o " "lote, sem cartão; apenas a impressão digital do documento sai " "deste computador.\n\n" - "Imagem — cola uma imagem. NÃO é uma assinatura criptográfica, sem " + "Assinatura visual — aplica um texto escrito, uma imagem ou um " + "desenho nas páginas. NÃO é uma assinatura criptográfica, sem " "valor legal; funciona totalmente offline.\n\n" + "Em todos os modos, as assinaturas visuais são adicionadas e " + "posicionadas no passo seguinte. Com eID ou Azure, são aplicadas " + "primeiro, e a assinatura criptográfica abrange-as em seguida.\n\n" "O nível PAdES define a durabilidade. Mantenha b-lta: a assinatura " "permanece verificável durante décadas (requer rede). Escolha b-b " "apenas para assinar offline. A documentação completa — modos, " @@ -770,130 +815,211 @@ def split_markup(text: str) -> list[tuple[str, bool]]: }, "step.place.help": { "en": ( - "Click on the page preview to set the lower-left corner of the " - "signature. **eID and Azure**: the visible vignette (photo, name, " - "date) is placed exactly where you click, on the chosen page; if " - "you do not click, it goes bottom-right on the last page. " - "**Image**: choose the image, then click to place it.\n\n" - "**Target page** — the page that actually gets signed. It follows " - "the preview; adjust it if a document must be signed on a different " - "page than the previewed template page. Documents without that page " - "will fail with a clear message.\n\n" + "Build the list of elements stamped on every document, then place " + "each one.\n\n" + "**Elements** — with **eID and Azure** the list starts with the " + "signature vignette (photo, name, date): it goes bottom-right on " + "the last page unless you place it. Add as many visual signatures " + "as you need with **Add text**, **Add image** or **Draw**; untick " + "one to keep it in your list without using it.\n\n" + "**Placing** — select an element in the list, then click on the " + "page preview: the click sets its lower-left corner. The preview " + "shows every element at its real size. **On every page** repeats a " + "signature on all pages (initials). In a text, {date} and " + "{filename} are replaced for each document, so the size of that " + "text can vary slightly.\n\n" + "**Target page** — the page that receives the selected element. It " + "follows the preview; type another page number to move the " + "element.\n\n" "**Documents with a different page count** — when some documents " "have more or fewer pages than the template, a selector at the top " - "of this step lets you choose whether each of them is signed on its " - "**first** or its **last** page (the same choice as on the " - "validation step). That page must have the template's page size: " - "the preview is locked on the corresponding template page, the " - "target-page field is disabled, and changing the choice re-checks " - "the documents." + "of this step lets you choose whether they are signed on their " + "**first** or their **last** page (the same choice as on the " + "validation step). Every element then goes on that page: the " + "preview is locked on the corresponding template page, the " + "target-page field and \"On every page\" are disabled, and " + "changing the choice re-checks the documents.\n\n" + "**Saved for next time** — your signatures, their last position " + "and your preferences are stored **unencrypted** in your user " + "folder and reloaded at the next start. **Delete** removes a " + "signature and its stored image. PIN codes and sign-in tokens are " + "never stored." ), "fr": ( - "Cliquez sur l'aperçu de la page pour définir le coin inférieur " - "gauche de la signature. **eID et Azure** : la vignette visible " - "(photo, nom, date) est placée exactement à l'endroit où vous " - "cliquez, sur la page choisie ; si vous ne cliquez pas, elle ira en " - "bas à droite de la dernière page. **Image** : choisissez l'image, " - "puis cliquez pour la positionner.\n\n" - "**Page cible** — la page réellement signée. Elle suit l'aperçu ; " - "ajustez-la si un document doit être signé sur une autre page que " - "celle du modèle affiché. Les documents sans cette page échoueront " - "avec un message clair.\n\n" + "Composez la liste des éléments apposés sur chaque document, puis " + "placez chacun d'eux.\n\n" + "**Éléments** — avec **eID et Azure**, la liste commence par la " + "vignette de signature (photo, nom, date) : elle ira en bas à " + "droite de la dernière page si vous ne la placez pas. Ajoutez " + "autant de signatures visuelles que nécessaire avec **Ajouter un " + "texte**, **Ajouter une image** ou **Dessiner** ; décochez-en une " + "pour la garder dans votre liste sans l'utiliser.\n\n" + "**Placement** — sélectionnez un élément dans la liste, puis " + "cliquez sur l'aperçu de la page : le clic définit son coin " + "inférieur gauche. L'aperçu montre chaque élément à sa taille " + "réelle. **Sur toutes les pages** répète une signature sur chacune " + "des pages (paraphe). Dans un texte, {date} et {filename} sont " + "remplacés pour chaque document ; la taille de ce texte peut donc " + "varier légèrement.\n\n" + "**Page cible** — la page qui reçoit l'élément sélectionné. Elle " + "suit l'aperçu ; saisissez un autre numéro de page pour déplacer " + "l'élément.\n\n" "**Documents dont le nombre de pages diffère** — lorsque certains " "documents comptent plus ou moins de pages que le modèle, un " - "sélecteur en haut de cette étape permet de choisir si chacun d'eux " - "est signé sur sa **première** ou sa **dernière** page (le même " - "choix qu'à l'étape de validation). Cette page doit avoir les mêmes " - "dimensions que le modèle : l'aperçu est verrouillé sur la page " - "correspondante du modèle, le champ « page cible » est désactivé et " - "tout changement de ce choix revérifie les documents." + "sélecteur en haut de cette étape permet de choisir s'ils sont " + "signés sur leur **première** ou leur **dernière** page (le même " + "choix qu'à l'étape de validation). Tous les éléments vont alors " + "sur cette page : l'aperçu est verrouillé sur la page " + "correspondante du modèle, le champ « page cible » et « Sur toutes " + "les pages » sont désactivés, et tout changement de ce choix " + "revérifie les documents.\n\n" + "**Mémorisé pour la prochaine fois** — vos signatures, leur " + "dernière position et vos préférences sont enregistrées **sans " + "chiffrement** dans votre dossier utilisateur et rechargées au " + "prochain démarrage. **Supprimer** retire une signature et son " + "image stockée. Les codes PIN et les jetons de connexion ne sont " + "jamais enregistrés." ), "nl": ( - "Klik op het paginavoorbeeld om de linkerbenedenhoek van de " - "handtekening te bepalen. **eID en Azure**: het zichtbare vignet " - "(foto, naam, datum) wordt op de gekozen pagina precies daar " - "geplaatst waar u klikt; klikt u niet, dan komt het rechtsonder op " - "de laatste pagina. **Afbeelding**: kies de afbeelding en klik " - "daarna om ze te plaatsen.\n\n" - "**Doelpagina** — de pagina die daadwerkelijk wordt ondertekend. " - "Dit veld volgt het voorbeeld; pas het aan als een document op een " - "andere pagina moet worden ondertekend dan de getoonde " - "sjabloonpagina. Documenten zonder die pagina zullen mislukken met " - "een duidelijke melding.\n\n" + "Stel de lijst samen van de elementen die op elk document worden " + "aangebracht en plaats ze daarna één voor één.\n\n" + "**Elementen** — met **eID en Azure** begint de lijst met het " + "handtekeningvignet (foto, naam, datum): het komt rechtsonder op " + "de laatste pagina, tenzij u het zelf plaatst. Voeg zoveel visuele " + "handtekeningen toe als u nodig hebt met **Tekst toevoegen**, " + "**Afbeelding toevoegen** of **Tekenen**; vink er een uit om ze in " + "uw lijst te bewaren zonder ze te gebruiken.\n\n" + "**Plaatsen** — selecteer een element in de lijst en klik daarna " + "op het paginavoorbeeld: de klik bepaalt de linkerbenedenhoek " + "ervan. Het voorbeeld toont elk element op ware grootte. **Op elke " + "pagina** herhaalt een handtekening op alle pagina's (paraaf). In " + "een tekst worden {date} en {filename} voor elk document " + "vervangen; de grootte van die tekst kan daardoor licht " + "variëren.\n\n" + "**Doelpagina** — de pagina die het geselecteerde element krijgt. " + "Dit veld volgt het voorbeeld; typ een ander paginanummer om het " + "element te verplaatsen.\n\n" "**Documenten met een ander aantal pagina's** — wanneer sommige " "documenten meer of minder pagina's hebben dan het sjabloon, kunt u " - "met een keuzelijst bovenaan deze stap kiezen of elk van die " - "documenten op zijn **eerste** of zijn **laatste** pagina wordt " - "ondertekend (dezelfde keuze als in de validatiestap). Die pagina " - "moet de paginagrootte van het sjabloon hebben: het voorbeeld is " - "vergrendeld op de overeenkomstige sjabloonpagina, het veld " - "'Doelpagina' is uitgeschakeld en als u de keuze wijzigt, worden de " - "documenten opnieuw gecontroleerd." + "met een keuzelijst bovenaan deze stap kiezen of ze op hun " + "**eerste** of hun **laatste** pagina worden ondertekend (dezelfde " + "keuze als in de validatiestap). Elk element komt dan op die " + "pagina: het voorbeeld is vergrendeld op de overeenkomstige " + "sjabloonpagina, het veld 'Doelpagina' en 'Op elke pagina' zijn " + "uitgeschakeld en als u de keuze wijzigt, worden de documenten " + "opnieuw gecontroleerd.\n\n" + "**Bewaard voor de volgende keer** — uw handtekeningen, hun " + "laatste positie en uw voorkeuren worden **onversleuteld** in uw " + "gebruikersmap opgeslagen en bij de volgende start opnieuw " + "geladen. **Verwijderen** wist een handtekening en de bijbehorende " + "opgeslagen afbeelding. Pincodes en aanmeldtokens worden nooit " + "opgeslagen." ), "de": ( - "Klicken Sie auf die Seitenvorschau, um die linke untere Ecke der " - "Signatur festzulegen. **eID und Azure**: Die sichtbare Vignette " - "(Foto, Name, Datum) wird auf der gewählten Seite genau dort " - "platziert, wo Sie klicken; ohne Klick kommt sie unten rechts auf " - "die letzte Seite. **Bild**: Wählen Sie das Bild und klicken Sie " - "dann, um es zu platzieren.\n\n" - "**Zielseite** — die Seite, die tatsächlich signiert wird. Sie " - "folgt der Vorschau; passen Sie sie an, wenn ein Dokument auf einer " - "anderen Seite signiert werden soll als der angezeigten " - "Vorlagenseite. Dokumente ohne diese Seite schlagen mit einer " - "klaren Meldung fehl.\n\n" + "Stellen Sie die Liste der Elemente zusammen, die auf jedes " + "Dokument gestempelt werden, und platzieren Sie dann jedes " + "einzelne.\n\n" + "**Elemente** — bei **eID und Azure** beginnt die Liste mit der " + "Signaturvignette (Foto, Name, Datum): Sie kommt unten rechts auf " + "die letzte Seite, sofern Sie sie nicht selbst platzieren. Fügen " + "Sie mit **Text hinzufügen**, **Bild hinzufügen** oder " + "**Zeichnen** beliebig viele visuelle Signaturen hinzu; entfernen " + "Sie das Häkchen, um eine Signatur in Ihrer Liste zu behalten, " + "ohne sie zu verwenden.\n\n" + "**Platzieren** — wählen Sie ein Element in der Liste aus und " + "klicken Sie dann auf die Seitenvorschau: Der Klick legt seine " + "linke untere Ecke fest. Die Vorschau zeigt jedes Element in " + "Originalgröße. **Auf jeder Seite** wiederholt eine Signatur auf " + "allen Seiten (Paraphe). In einem Text werden {date} und " + "{filename} für jedes Dokument ersetzt; die Größe dieses Textes " + "kann daher leicht variieren.\n\n" + "**Zielseite** — die Seite, die das ausgewählte Element erhält. " + "Sie folgt der Vorschau; geben Sie eine andere Seitenzahl ein, um " + "das Element zu verschieben.\n\n" "**Dokumente mit abweichender Seitenzahl** — haben einige Dokumente " "mehr oder weniger Seiten als die Vorlage, können Sie über ein " - "Auswahlfeld oben in diesem Schritt festlegen, ob jedes davon auf " - "seiner **ersten** oder seiner **letzten** Seite signiert wird " - "(dieselbe Wahl wie im Prüfschritt). Diese Seite muss die " - "Seitengröße der Vorlage haben: Die Vorschau ist auf der " - "entsprechenden Vorlagenseite gesperrt, das Feld „Zielseite“ ist " + "Auswahlfeld oben in diesem Schritt festlegen, ob sie auf ihrer " + "**ersten** oder ihrer **letzten** Seite signiert werden (dieselbe " + "Wahl wie im Prüfschritt). Alle Elemente kommen dann auf diese " + "Seite: Die Vorschau ist auf der entsprechenden Vorlagenseite " + "gesperrt, das Feld „Zielseite“ und „Auf jeder Seite“ sind " "deaktiviert, und bei einer Änderung der Wahl werden die Dokumente " - "erneut geprüft." + "erneut geprüft.\n\n" + "**Für das nächste Mal gespeichert** — Ihre Signaturen, deren " + "letzte Position und Ihre Einstellungen werden **unverschlüsselt** " + "in Ihrem Benutzerordner gespeichert und beim nächsten Start " + "wieder geladen. **Löschen** entfernt eine Signatur und ihr " + "gespeichertes Bild. PINs und Anmeldetoken werden niemals " + "gespeichert." ), "es": ( - "Haga clic en la vista previa de la página para fijar la esquina " - "inferior izquierda de la firma. **eID y Azure**: la viñeta visible " - "(foto, nombre, fecha) se coloca exactamente donde haga clic, en la " - "página elegida; si no hace clic, irá abajo a la derecha en la " - "última página. **Imagen**: elija la imagen y luego haga clic para " - "colocarla.\n\n" - "**Página de destino** — la página que realmente se firma. Se " - "actualiza con la vista previa; ajústela si un documento debe " - "firmarse en una página distinta de la página de la plantilla " - "mostrada. Los documentos sin esa página fallarán con un mensaje " - "claro.\n\n" + "Componga la lista de elementos que se estampan en cada documento " + "y, después, coloque cada uno.\n\n" + "**Elementos** — con **eID y Azure** la lista empieza por la viñeta " + "de firma (foto, nombre, fecha): irá abajo a la derecha en la " + "última página, salvo que usted la coloque. Añada tantas firmas " + "visuales como necesite con **Añadir texto**, **Añadir imagen** o " + "**Dibujar**; desmarque una para conservarla en su lista sin " + "utilizarla.\n\n" + "**Colocación** — seleccione un elemento de la lista y luego haga " + "clic en la vista previa de la página: el clic fija su esquina " + "inferior izquierda. La vista previa muestra cada elemento a su " + "tamaño real. **En todas las páginas** repite una firma en cada " + "una de las páginas (rúbrica). En un texto, {date} y {filename} se " + "sustituyen en cada documento, por lo que el tamaño de ese texto " + "puede variar ligeramente.\n\n" + "**Página de destino** — la página que recibe el elemento " + "seleccionado. Se actualiza con la vista previa; escriba otro " + "número de página para mover el elemento.\n\n" "**Documentos con un número de páginas distinto** — cuando algunos " "documentos tienen más o menos páginas que la plantilla, un " "selector en la parte superior de este paso le permite elegir si " - "cada uno de ellos se firma en su **primera** o en su **última** " - "página (la misma elección que en el paso de validación). Esa " - "página debe tener el tamaño de página de la plantilla: la vista " - "previa queda bloqueada en la página correspondiente de la " - "plantilla, el campo «Página de destino» se desactiva y cambiar la " - "elección vuelve a comprobar los documentos." + "se firman en su **primera** o en su **última** página (la misma " + "elección que en el paso de validación). Todos los elementos van " + "entonces a esa página: la vista previa queda bloqueada en la " + "página correspondiente de la plantilla, el campo «Página de " + "destino» y «En todas las páginas» se desactivan, y cambiar la " + "elección vuelve a comprobar los documentos.\n\n" + "**Guardado para la próxima vez** — sus firmas, su última posición " + "y sus preferencias se guardan **sin cifrar** en su carpeta de " + "usuario y se vuelven a cargar en el siguiente inicio. " + "**Eliminar** borra una firma y su imagen almacenada. Los códigos " + "PIN y los tokens de inicio de sesión nunca se guardan." ), "pt": ( - "Clique na pré-visualização da página para definir o canto inferior " - "esquerdo da assinatura. **eID e Azure**: a vinheta visível " - "(fotografia, nome, data) é colocada exatamente onde clicar, na " - "página escolhida; se não clicar, ficará em baixo à direita na " - "última página. **Imagem**: escolha a imagem e depois clique para a " - "posicionar.\n\n" - "**Página de destino** — a página realmente assinada. Segue a " - "pré-visualização; ajuste-a se um documento tiver de ser assinado " - "numa página diferente da página do modelo apresentada na " - "pré-visualização. Os documentos sem essa página falharão com uma " - "mensagem clara.\n\n" + "Componha a lista dos elementos aplicados em cada documento e, " + "depois, posicione cada um.\n\n" + "**Elementos** — com **eID e Azure**, a lista começa pela vinheta " + "de assinatura (fotografia, nome, data): ficará em baixo à direita " + "na última página, a menos que a posicione. Adicione as " + "assinaturas visuais de que precisar com **Adicionar texto**, " + "**Adicionar imagem** ou **Desenhar**; desmarque uma para a manter " + "na lista sem a utilizar.\n\n" + "**Posicionamento** — selecione um elemento na lista e depois " + "clique na pré-visualização da página: o clique define o seu canto " + "inferior esquerdo. A pré-visualização mostra cada elemento no " + "tamanho real. **Em todas as páginas** repete uma assinatura em " + "cada uma das páginas (rubrica). Num texto, {date} e {filename} " + "são substituídos em cada documento, pelo que o tamanho desse " + "texto pode variar ligeiramente.\n\n" + "**Página de destino** — a página que recebe o elemento " + "selecionado. Segue a pré-visualização; escreva outro número de " + "página para mover o elemento.\n\n" "**Documentos com um número de páginas diferente** — quando alguns " "documentos têm mais ou menos páginas do que o modelo, um seletor " - "no topo deste passo permite escolher se cada um deles é assinado " - "na sua **primeira** ou na sua **última** página (a mesma escolha " - "que no passo de validação). Essa página deve ter as dimensões de " - "página do modelo: a pré-visualização fica bloqueada na página " - "correspondente do modelo, o campo «página de destino» fica " - "desativado e alterar a escolha volta a verificar os documentos." + "no topo deste passo permite escolher se são assinados na sua " + "**primeira** ou na sua **última** página (a mesma escolha que no " + "passo de validação). Todos os elementos ficam então nessa " + "página: a pré-visualização fica bloqueada na página " + "correspondente do modelo, o campo «página de destino» e «Em todas " + "as páginas» ficam desativados, e alterar a escolha volta a " + "verificar os documentos.\n\n" + "**Guardado para a próxima vez** — as suas assinaturas, a " + "respetiva última posição e as suas preferências são guardadas " + "**sem encriptação** na sua pasta de utilizador e recarregadas no " + "arranque seguinte. **Eliminar** remove uma assinatura e a " + "respetiva imagem armazenada. Os códigos PIN e os tokens de início " + "de sessão nunca são guardados." ), }, "step.run.short": { @@ -915,7 +1041,9 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "asked once per document. **Azure**: a Microsoft sign-in window may " "open if you have not signed in yet. Levels above b-b contact the " "timestamp authority and revocation services, so network access is " - "required. Keep the window open while signing is in progress." + "required. Keep the window open while signing is in progress. " + "Visual signatures are stamped first; the cryptographic signature " + "(eID or Azure) is applied last and covers them." ), "fr": ( "Vérifiez le récapitulatif, puis lancez le lot. **eID** : insérez " @@ -925,7 +1053,9 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "s'ouvrir si vous n'êtes pas encore connecté. Au-delà de b-b, " "l'autorité d'horodatage et les services de révocation sont " "contactés : un accès réseau est requis. Gardez la fenêtre ouverte " - "pendant la signature." + "pendant la signature. Les signatures visuelles sont apposées en " + "premier ; la signature cryptographique (eID ou Azure) est " + "appliquée en dernier et les couvre." ), "nl": ( "Controleer het overzicht en start de reeks. **eID**: steek uw " @@ -934,7 +1064,10 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "**Azure**: er kan een Microsoft-aanmeldvenster verschijnen als u " "nog niet bent aangemeld. Boven b-b worden de tijdstempelautoriteit " "en de intrekkingsdiensten gecontacteerd: netwerktoegang is " - "vereist. Houd het venster open zolang het ondertekenen bezig is." + "vereist. Houd het venster open zolang het ondertekenen bezig is. " + "Visuele handtekeningen worden eerst aangebracht; de " + "cryptografische handtekening (eID of Azure) komt als laatste en " + "omvat ze." ), "de": ( "Prüfen Sie die Übersicht und starten Sie den Stapel. **eID**: " @@ -944,7 +1077,9 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "öffnen, falls Sie noch nicht angemeldet sind. Oberhalb von b-b " "werden Zeitstempel- und Sperrdienste kontaktiert: Netzwerkzugang " "ist erforderlich. Lassen Sie das Fenster geöffnet, solange " - "signiert wird." + "signiert wird. Visuelle Signaturen werden zuerst aufgebracht; die " + "kryptografische Signatur (eID oder Azure) folgt zuletzt und deckt " + "sie mit ab." ), "es": ( "Compruebe el resumen y lance el lote. **eID**: inserte su tarjeta " @@ -953,7 +1088,9 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "una ventana de inicio de sesión de Microsoft si aún no ha iniciado " "sesión. Por encima de b-b se contacta con la autoridad de sellado " "de tiempo y los servicios de revocación: se necesita acceso a la " - "red. Mantenga la ventana abierta mientras se firma." + "red. Mantenga la ventana abierta mientras se firma. Las firmas " + "visuales se estampan primero; la firma criptográfica (eID o " + "Azure) se aplica al final y las cubre." ), "pt": ( "Verifique o resumo e inicie o lote. **eID**: insira o seu cartão " @@ -962,7 +1099,9 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "janela de início de sessão Microsoft se ainda não tiver iniciado " "sessão. Acima de b-b são contactados a autoridade de selos " "temporais e os serviços de revogação: é necessário acesso à rede. " - "Mantenha a janela aberta enquanto a assinatura decorre." + "Mantenha a janela aberta enquanto a assinatura decorre. As " + "assinaturas visuais são aplicadas primeiro; a assinatura " + "criptográfica (eID ou Azure) é aplicada por último e abrange-as." ), }, "step.results.short": { @@ -1199,12 +1338,12 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "pt": "Azure Key Vault — assinatura avançada (AES)", }, "mode.image": { - "en": "Image stamp — no cryptographic signature", - "fr": "Image — aucune signature cryptographique", - "nl": "Afbeelding — geen cryptografische handtekening", - "de": "Bildstempel — keine kryptografische Signatur", - "es": "Imagen — sin firma criptográfica", - "pt": "Imagem — sem assinatura criptográfica", + "en": "Visual signature (text / image) — no cryptographic signature", + "fr": "Signature visuelle (texte / image) — aucune signature cryptographique", + "nl": "Visuele handtekening (tekst / afbeelding) — geen cryptografische handtekening", + "de": "Visuelle Signatur (Text / Bild) — keine kryptografische Signatur", + "es": "Firma visual (texto / imagen) — sin firma criptográfica", + "pt": "Assinatura visual (texto / imagem) — sem assinatura criptográfica", }, "mode.beid_hint": { "en": "Card reader + one PIN per document. Embeds your national register number (RRN) in every signature.", @@ -1223,12 +1362,67 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "pt": "Um único início de sessão Microsoft para todo o lote; requer rede. Apenas o resumo (digest) do documento sai deste computador.", }, "mode.image_hint": { - "en": "Visual stamp only, no legal value; works fully offline.", - "fr": "Simple tampon visuel, sans valeur juridique ; fonctionne entièrement hors ligne.", - "nl": "Alleen een visuele stempel, zonder juridische waarde; werkt volledig offline.", - "de": "Nur ein sichtbarer Stempel ohne Rechtswert; funktioniert vollständig offline.", - "es": "Solo un sello visual, sin valor legal; funciona totalmente sin conexión.", - "pt": "Apenas um carimbo visual, sem valor legal; funciona totalmente offline.", + "en": ( + "A typed, drawn or image signature stamped on the pages — one or " + "several per document. No legal value; works fully offline." + ), + "fr": ( + "Une signature saisie au clavier, dessinée ou sous forme d'image, " + "apposée sur les pages — une ou plusieurs par document. Sans " + "valeur juridique ; fonctionne entièrement hors ligne." + ), + "nl": ( + "Een getypte of getekende handtekening of een afbeelding, " + "aangebracht op de pagina's — één of meerdere per document. Zonder " + "juridische waarde; werkt volledig offline." + ), + "de": ( + "Eine getippte, gezeichnete oder als Bild vorliegende Signatur, " + "auf die Seiten gestempelt — eine oder mehrere pro Dokument. Ohne " + "Rechtswert; funktioniert vollständig offline." + ), + "es": ( + "Una firma escrita, dibujada o en forma de imagen, estampada en " + "las páginas — una o varias por documento. Sin valor legal; " + "funciona totalmente sin conexión." + ), + "pt": ( + "Uma assinatura escrita, desenhada ou em imagem, aplicada nas " + "páginas — uma ou várias por documento. Sem valor legal; funciona " + "totalmente offline." + ), + }, + "mode.stamps_hint": { + "en": ( + "In every mode you can add visual signatures (text, image, " + "drawing) on the placement step. With eID or Azure they are " + "applied before the cryptographic signature." + ), + "fr": ( + "Dans tous les modes, vous pouvez ajouter des signatures visuelles " + "(texte, image, dessin) à l'étape de positionnement. Avec eID ou " + "Azure, elles sont apposées avant la signature cryptographique." + ), + "nl": ( + "In elke modus kunt u in de plaatsingsstap visuele handtekeningen " + "(tekst, afbeelding, tekening) toevoegen. Met eID of Azure worden " + "ze vóór de cryptografische handtekening aangebracht." + ), + "de": ( + "In jedem Modus können Sie im Platzierungsschritt visuelle " + "Signaturen (Text, Bild, Zeichnung) hinzufügen. Mit eID oder Azure " + "werden sie vor der kryptografischen Signatur aufgebracht." + ), + "es": ( + "En todos los modos puede añadir firmas visuales (texto, imagen, " + "dibujo) en el paso de colocación. Con eID o Azure se aplican " + "antes de la firma criptográfica." + ), + "pt": ( + "Em todos os modos pode adicionar assinaturas visuais (texto, " + "imagem, desenho) no passo de posicionamento. Com eID ou Azure, " + "são aplicadas antes da assinatura criptográfica." + ), }, "mode.level": { "en": "PAdES level:", @@ -1523,14 +1717,6 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "pt": "Cachet — Documentação", }, # ------------------------------------------------------------- step 6 - "place.image_choose": { - "en": "Choose image…", - "fr": "Choisir l'image…", - "nl": "Afbeelding kiezen…", - "de": "Bild wählen…", - "es": "Elegir imagen…", - "pt": "Escolher imagem…", - }, "place.page": { "en": "Target page:", "fr": "Page cible :", @@ -1635,14 +1821,6 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "es": "Sin posición definida — la viñeta irá abajo a la derecha en la {anchor} de cada documento.", "pt": "Nenhuma posição definida — a vinheta ficará em baixo à direita na {anchor} de cada documento.", }, - "place.image_missing": { - "en": "Choose an image, then click on the preview to place it.", - "fr": "Choisissez une image, puis cliquez sur l'aperçu pour la positionner.", - "nl": "Kies een afbeelding en klik daarna op het voorbeeld om ze te plaatsen.", - "de": "Wählen Sie ein Bild und klicken Sie dann auf die Vorschau, um es zu platzieren.", - "es": "Elija una imagen y luego haga clic en la vista previa para colocarla.", - "pt": "Escolha uma imagem e depois clique na pré-visualização para a posicionar.", - }, "place.anchor_status": { "en": ( "{ok}/{total} document(s) accepted with this choice — details on " @@ -1704,6 +1882,494 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "modelo." ), }, + "place.elements_title": { + "en": "Elements to place", + "fr": "Éléments à placer", + "nl": "Te plaatsen elementen", + "de": "Zu platzierende Elemente", + "es": "Elementos a colocar", + "pt": "Elementos a posicionar", + }, + "place.list_empty": { + "en": "No signature yet — add one with the buttons above.", + "fr": "Aucune signature pour l'instant — ajoutez-en une avec les boutons ci-dessus.", + "nl": "Nog geen handtekening — voeg er een toe met de knoppen hierboven.", + "de": "Noch keine Signatur — fügen Sie eine über die Schaltflächen oben hinzu.", + "es": "Aún no hay ninguna firma — añada una con los botones de arriba.", + "pt": "Ainda não há nenhuma assinatura — adicione uma com os botões acima.", + }, + "place.el_vignette": { + "en": "Signature vignette (certificate)", + "fr": "Vignette de signature (certificat)", + "nl": "Handtekeningvignet (certificaat)", + "de": "Signaturvignette (Zertifikat)", + "es": "Viñeta de firma (certificado)", + "pt": "Vinheta de assinatura (certificado)", + }, + "place.el_vignette_short": { + "en": "Vignette", "fr": "Vignette", "nl": "Vignet", + "de": "Vignette", "es": "Viñeta", "pt": "Vinheta", + }, + "place.st_page": { + "en": "page {page}", + "fr": "page {page}", + "nl": "pagina {page}", + "de": "Seite {page}", + "es": "página {page}", + "pt": "página {page}", + }, + "place.st_all": { + "en": "every page", + "fr": "toutes les pages", + "nl": "elke pagina", + "de": "jede Seite", + "es": "todas las páginas", + "pt": "todas as páginas", + }, + "place.st_default": { + "en": "default position", + "fr": "position par défaut", + "nl": "standaardpositie", + "de": "Standardposition", + "es": "posición predeterminada", + "pt": "posição predefinida", + }, + "place.st_unplaced": { + "en": "not placed", + "fr": "non placée", + "nl": "niet geplaatst", + "de": "nicht platziert", + "es": "sin colocar", + "pt": "não posicionada", + }, + "place.st_error": { + "en": "⚠ unusable", + "fr": "⚠ inutilisable", + "nl": "⚠ onbruikbaar", + "de": "⚠ nicht verwendbar", + "es": "⚠ no utilizable", + "pt": "⚠ inutilizável", + }, + "place.all_pages": { + "en": "On every page (initials)", + "fr": "Sur toutes les pages (paraphe)", + "nl": "Op elke pagina (paraaf)", + "de": "Auf jeder Seite (Paraphe)", + "es": "En todas las páginas (rúbrica)", + "pt": "Em todas as páginas (rubrica)", + }, + "place.pos_all": { + "en": "Position: every page, ({x}, {y}) pt from the bottom-left corner.", + "fr": "Position : toutes les pages, ({x}, {y}) pt depuis le coin inférieur gauche.", + "nl": "Positie: elke pagina, ({x}, {y}) pt vanaf de linkerbenedenhoek.", + "de": "Position: jede Seite, ({x}, {y}) pt von der linken unteren Ecke.", + "es": "Posición: todas las páginas, ({x}, {y}) pt desde la esquina inferior izquierda.", + "pt": "Posição: todas as páginas, ({x}, {y}) pt a partir do canto inferior esquerdo.", + }, + "place.select_hint": { + "en": "Select an element in the list, then click on the page preview to place it.", + "fr": "Sélectionnez un élément dans la liste, puis cliquez sur l'aperçu de la page pour le placer.", + "nl": "Selecteer een element in de lijst en klik daarna op het paginavoorbeeld om het te plaatsen.", + "de": "Wählen Sie ein Element in der Liste aus und klicken Sie dann auf die Seitenvorschau, um es zu platzieren.", + "es": "Seleccione un elemento de la lista y luego haga clic en la vista previa de la página para colocarlo.", + "pt": "Selecione um elemento na lista e depois clique na pré-visualização da página para o posicionar.", + }, + "place.need_signature": { + "en": "Add at least one visual signature and keep it ticked.", + "fr": "Ajoutez au moins une signature visuelle et laissez-la cochée.", + "nl": "Voeg minstens één visuele handtekening toe en laat ze aangevinkt.", + "de": "Fügen Sie mindestens eine visuelle Signatur hinzu und lassen Sie das Häkchen gesetzt.", + "es": "Añada al menos una firma visual y manténgala marcada.", + "pt": "Adicione pelo menos uma assinatura visual e mantenha-a marcada.", + }, + "place.unplaced": { + "en": "“{name}” is not placed yet: select it, then click on the page preview.", + "fr": "« {name} » n'est pas encore placée : sélectionnez-la, puis cliquez sur l'aperçu de la page.", + "nl": "'{name}' is nog niet geplaatst: selecteer deze handtekening en klik daarna op het paginavoorbeeld.", + "de": "„{name}“ ist noch nicht platziert: Wählen Sie sie aus und klicken Sie dann auf die Seitenvorschau.", + "es": "«{name}» aún no está colocada: selecciónela y luego haga clic en la vista previa de la página.", + "pt": "«{name}» ainda não está posicionada: selecione-a e depois clique na pré-visualização da página.", + }, + "place.el_broken": { + "en": "“{name}” cannot be used: {error}", + "fr": "« {name} » est inutilisable : {error}", + "nl": "'{name}' kan niet worden gebruikt: {error}", + "de": "„{name}“ kann nicht verwendet werden: {error}", + "es": "«{name}» no se puede utilizar: {error}", + "pt": "«{name}» não pode ser utilizada: {error}", + }, + "place.save_failed": { + "en": "⚠ Your signatures could not be saved: {error}", + "fr": "⚠ Vos signatures n'ont pas pu être enregistrées : {error}", + "nl": "⚠ Uw handtekeningen konden niet worden opgeslagen: {error}", + "de": "⚠ Ihre Signaturen konnten nicht gespeichert werden: {error}", + "es": "⚠ No se pudieron guardar sus firmas: {error}", + "pt": "⚠ Não foi possível guardar as suas assinaturas: {error}", + }, + "place.storage_note": { + "en": "Signatures and preferences are saved unencrypted in your user folder.", + "fr": "Les signatures et les préférences sont enregistrées sans chiffrement dans votre dossier utilisateur.", + "nl": "Handtekeningen en voorkeuren worden onversleuteld opgeslagen in uw gebruikersmap.", + "de": "Signaturen und Einstellungen werden unverschlüsselt in Ihrem Benutzerordner gespeichert.", + "es": "Las firmas y las preferencias se guardan sin cifrar en su carpeta de usuario.", + "pt": "As assinaturas e as preferências são guardadas sem encriptação na sua pasta de utilizador.", + }, + # ------------------------------------------- step 6: signature editor + "sig.add_text": { + "en": "Add text…", + "fr": "Ajouter un texte…", + "nl": "Tekst toevoegen…", + "de": "Text hinzufügen…", + "es": "Añadir texto…", + "pt": "Adicionar texto…", + }, + "sig.add_image": { + "en": "Add image…", + "fr": "Ajouter une image…", + "nl": "Afbeelding toevoegen…", + "de": "Bild hinzufügen…", + "es": "Añadir imagen…", + "pt": "Adicionar imagem…", + }, + "sig.draw": { + "en": "Draw…", + "fr": "Dessiner…", + "nl": "Tekenen…", + "de": "Zeichnen…", + "es": "Dibujar…", + "pt": "Desenhar…", + }, + "sig.edit": { + "en": "Edit…", + "fr": "Modifier…", + "nl": "Bewerken…", + "de": "Bearbeiten…", + "es": "Editar…", + "pt": "Editar…", + }, + "sig.delete": { + "en": "Delete", + "fr": "Supprimer", + "nl": "Verwijderen", + "de": "Löschen", + "es": "Eliminar", + "pt": "Eliminar", + }, + "sig.delete_title": { + "en": "Delete this signature?", + "fr": "Supprimer cette signature ?", + "nl": "Deze handtekening verwijderen?", + "de": "Diese Signatur löschen?", + "es": "¿Eliminar esta firma?", + "pt": "Eliminar esta assinatura?", + }, + "sig.delete_body": { + "en": ( + "“{name}” will be removed from your saved signatures, together " + "with its stored image. This cannot be undone." + ), + "fr": ( + "« {name} » sera retirée de vos signatures enregistrées, ainsi que " + "son image stockée. Cette action est irréversible." + ), + "nl": ( + "'{name}' wordt uit uw opgeslagen handtekeningen verwijderd, samen " + "met de bijbehorende opgeslagen afbeelding. Dit kan niet ongedaan " + "worden gemaakt." + ), + "de": ( + "„{name}“ wird aus Ihren gespeicherten Signaturen entfernt, " + "zusammen mit dem zugehörigen gespeicherten Bild. Dies kann nicht " + "rückgängig gemacht werden." + ), + "es": ( + "«{name}» se eliminará de sus firmas guardadas, junto con su " + "imagen almacenada. Esta acción no se puede deshacer." + ), + "pt": ( + "«{name}» será removida das suas assinaturas guardadas, juntamente " + "com a respetiva imagem armazenada. Esta ação não pode ser " + "anulada." + ), + }, + "sig.delete_confirm": { + "en": "Delete", + "fr": "Supprimer", + "nl": "Verwijderen", + "de": "Löschen", + "es": "Eliminar", + "pt": "Eliminar", + }, + "sig.delete_keep": { + "en": "Keep it", + "fr": "Conserver", + "nl": "Behouden", + "de": "Behalten", + "es": "Conservar", + "pt": "Manter", + }, + "sig.text_title_add": { + "en": "New text signature", + "fr": "Nouvelle signature texte", + "nl": "Nieuwe teksthandtekening", + "de": "Neue Textsignatur", + "es": "Nueva firma de texto", + "pt": "Nova assinatura de texto", + }, + "sig.text_title_edit": { + "en": "Edit text signature", + "fr": "Modifier la signature texte", + "nl": "Teksthandtekening bewerken", + "de": "Textsignatur bearbeiten", + "es": "Editar la firma de texto", + "pt": "Editar a assinatura de texto", + }, + "sig.name": { + "en": "Name (optional):", + "fr": "Nom (facultatif) :", + "nl": "Naam (optioneel):", + "de": "Name (optional):", + "es": "Nombre (opcional):", + "pt": "Nome (opcional):", + }, + "sig.text": { + "en": "Text:", + "fr": "Texte :", + "nl": "Tekst:", + "de": "Text:", + "es": "Texto:", + "pt": "Texto:", + }, + "sig.text_hint": { + "en": ( + "Several lines are allowed. {date} is replaced by the date of the " + "run and {filename} by the name of each document." + ), + "fr": ( + "Plusieurs lignes sont possibles. {date} est remplacé par la date " + "de la signature et {filename} par le nom de chaque document." + ), + "nl": ( + "Meerdere regels zijn toegestaan. {date} wordt vervangen door de " + "datum van ondertekening en {filename} door de naam van elk " + "document." + ), + "de": ( + "Mehrere Zeilen sind möglich. {date} wird durch das Datum der " + "Signierung ersetzt und {filename} durch den Namen des jeweiligen " + "Dokuments." + ), + "es": ( + "Se admiten varias líneas. {date} se sustituye por la fecha de la " + "firma y {filename} por el nombre de cada documento." + ), + "pt": ( + "São permitidas várias linhas. {date} é substituído pela data da " + "assinatura e {filename} pelo nome de cada documento." + ), + }, + "sig.font": { + "en": "Font:", + "fr": "Police :", + "nl": "Lettertype:", + "de": "Schriftart:", + "es": "Fuente:", + "pt": "Tipo de letra:", + }, + "sig.font_custom": { + "en": "Other font file…", + "fr": "Autre fichier de police…", + "nl": "Ander lettertypebestand…", + "de": "Andere Schriftdatei…", + "es": "Otro archivo de fuente…", + "pt": "Outro ficheiro de tipo de letra…", + }, + "sig.size": { + "en": "Size (pt):", + "fr": "Taille (pt) :", + "nl": "Grootte (pt):", + "de": "Größe (pt):", + "es": "Tamaño (pt):", + "pt": "Tamanho (pt):", + }, + "sig.color": { + "en": "Colour:", + "fr": "Couleur :", + "nl": "Kleur:", + "de": "Farbe:", + "es": "Color:", + "pt": "Cor:", + }, + "sig.color_title": { + "en": "Signature colour", + "fr": "Couleur de la signature", + "nl": "Kleur van de handtekening", + "de": "Farbe der Signatur", + "es": "Color de la firma", + "pt": "Cor da assinatura", + }, + "sig.preview": { + "en": "Preview", + "fr": "Aperçu", + "nl": "Voorbeeld", + "de": "Vorschau", + "es": "Vista previa", + "pt": "Pré-visualização", + }, + "sig.preview_size": { + "en": "Size on the page: {w} × {h} pt", + "fr": "Taille sur la page : {w} × {h} pt", + "nl": "Grootte op de pagina: {w} × {h} pt", + "de": "Größe auf der Seite: {w} × {h} pt", + "es": "Tamaño en la página: {w} × {h} pt", + "pt": "Tamanho na página: {w} × {h} pt", + }, + "sig.save": { + "en": "Save", + "fr": "Enregistrer", + "nl": "Opslaan", + "de": "Speichern", + "es": "Guardar", + "pt": "Guardar", + }, + "sig.cancel": { + "en": "Cancel", + "fr": "Annuler", + "nl": "Annuleren", + "de": "Abbrechen", + "es": "Cancelar", + "pt": "Cancelar", + }, + "sig.err_text_empty": { + "en": "Enter some text.", + "fr": "Saisissez un texte.", + "nl": "Voer een tekst in.", + "de": "Geben Sie einen Text ein.", + "es": "Introduzca un texto.", + "pt": "Introduza um texto.", + }, + "sig.err_size": { + "en": "The size must be a number greater than 0, up to {max}.", + "fr": "La taille doit être un nombre supérieur à 0 et au plus égal à {max}.", + "nl": "De grootte moet een getal groter dan 0 en hoogstens {max} zijn.", + "de": "Die Größe muss eine Zahl größer als 0 und höchstens {max} sein.", + "es": "El tamaño debe ser un número mayor que 0 y como máximo {max}.", + "pt": "O tamanho deve ser um número superior a 0 e no máximo {max}.", + }, + "sig.err_render": { + "en": "This signature cannot be rendered: {error}", + "fr": "Impossible de générer cette signature : {error}", + "nl": "Deze handtekening kan niet worden weergegeven: {error}", + "de": "Diese Signatur kann nicht dargestellt werden: {error}", + "es": "No se puede generar esta firma: {error}", + "pt": "Não é possível gerar esta assinatura: {error}", + }, + "sig.draw_title": { + "en": "Draw a signature", + "fr": "Dessiner une signature", + "nl": "Een handtekening tekenen", + "de": "Signatur zeichnen", + "es": "Dibujar una firma", + "pt": "Desenhar uma assinatura", + }, + "sig.draw_hint": { + "en": "Draw with the mouse or a stylus in the box below. The background stays transparent.", + "fr": "Dessinez à la souris ou au stylet dans le cadre ci-dessous. Le fond reste transparent.", + "nl": "Teken met de muis of een stylus in het vak hieronder. De achtergrond blijft transparant.", + "de": "Zeichnen Sie mit der Maus oder einem Stift in das Feld unten. Der Hintergrund bleibt transparent.", + "es": "Dibuje con el ratón o un lápiz óptico en el recuadro inferior. El fondo se mantiene transparente.", + "pt": "Desenhe com o rato ou uma caneta digital na caixa abaixo. O fundo mantém-se transparente.", + }, + "sig.draw_clear": { + "en": "Clear", + "fr": "Effacer", + "nl": "Wissen", + "de": "Leeren", + "es": "Borrar", + "pt": "Limpar", + }, + "sig.err_draw_empty": { + "en": "Draw something first.", + "fr": "Dessinez d'abord quelque chose.", + "nl": "Teken eerst iets.", + "de": "Zeichnen Sie zuerst etwas.", + "es": "Dibuje algo primero.", + "pt": "Desenhe algo primeiro.", + }, + "sig.err_draw_too_large": { + "en": "This drawing is too large. Clear it and draw a smaller one.", + "fr": "Ce dessin est trop grand. Effacez-le et dessinez-en un plus petit.", + "nl": "Deze tekening is te groot. Wis ze en teken een kleinere.", + "de": "Diese Zeichnung ist zu groß. Löschen Sie sie und zeichnen Sie eine kleinere.", + "es": "Este dibujo es demasiado grande. Bórrelo y dibuje uno más pequeño.", + "pt": "Este desenho é demasiado grande. Apague-o e desenhe um mais pequeno.", + }, + "sig.drawn_label": { + "en": "Drawn signature", + "fr": "Signature dessinée", + "nl": "Getekende handtekening", + "de": "Gezeichnete Signatur", + "es": "Firma dibujada", + "pt": "Assinatura desenhada", + }, + "sig.image_title": { + "en": "Edit image signature", + "fr": "Modifier la signature image", + "nl": "Afbeeldingshandtekening bewerken", + "de": "Bildsignatur bearbeiten", + "es": "Editar la firma de imagen", + "pt": "Editar a assinatura de imagem", + }, + "sig.width": { + "en": "Width (pt):", + "fr": "Largeur (pt) :", + "nl": "Breedte (pt):", + "de": "Breite (pt):", + "es": "Ancho (pt):", + "pt": "Largura (pt):", + }, + "sig.err_width": { + "en": "The width must be a number greater than 0, up to {max}.", + "fr": "La largeur doit être un nombre supérieur à 0 et au plus égal à {max}.", + "nl": "De breedte moet een getal groter dan 0 en hoogstens {max} zijn.", + "de": "Die Breite muss eine Zahl größer als 0 und höchstens {max} sein.", + "es": "El ancho debe ser un número mayor que 0 y como máximo {max}.", + "pt": "A largura deve ser um número superior a 0 e no máximo {max}.", + }, + "sig.err_image": { + "en": "This image cannot be used: {error}", + "fr": "Cette image est inutilisable : {error}", + "nl": "Deze afbeelding kan niet worden gebruikt: {error}", + "de": "Dieses Bild kann nicht verwendet werden: {error}", + "es": "No se puede utilizar esta imagen: {error}", + "pt": "Não é possível utilizar esta imagem: {error}", + }, + "sig.err_store": { + "en": ( + "The signature could not be stored in your user folder, so it was " + "not added: {error}" + ), + "fr": ( + "La signature n'a pas pu être enregistrée dans votre dossier " + "utilisateur ; elle n'a donc pas été ajoutée : {error}" + ), + "nl": ( + "De handtekening kon niet in uw gebruikersmap worden opgeslagen en " + "is dus niet toegevoegd: {error}" + ), + "de": ( + "Die Signatur konnte nicht in Ihrem Benutzerordner gespeichert " + "werden und wurde daher nicht hinzugefügt: {error}" + ), + "es": ( + "No se pudo guardar la firma en su carpeta de usuario, por lo que " + "no se ha añadido: {error}" + ), + "pt": ( + "Não foi possível guardar a assinatura na sua pasta de utilizador, " + "pelo que não foi adicionada: {error}" + ), + }, # ------------------------------------------------------------- step 7 "run.summary_docs": { "en": "Documents to sign: {count}", @@ -1738,12 +2404,28 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "pt": "Pasta de saída: {output}", }, "run.summary_place": { - "en": "Placement: {place}", - "fr": "Positionnement : {place}", - "nl": "Plaatsing: {place}", - "de": "Platzierung: {place}", - "es": "Colocación: {place}", - "pt": "Posicionamento: {place}", + "en": "Signature vignette: {place}", + "fr": "Vignette de signature : {place}", + "nl": "Handtekeningvignet: {place}", + "de": "Signaturvignette: {place}", + "es": "Viñeta de firma: {place}", + "pt": "Vinheta de assinatura: {place}", + }, + "run.summary_stamps": { + "en": "Visual signatures: {count}", + "fr": "Signatures visuelles : {count}", + "nl": "Visuele handtekeningen: {count}", + "de": "Visuelle Signaturen: {count}", + "es": "Firmas visuales: {count}", + "pt": "Assinaturas visuais: {count}", + }, + "run.stamp_line": { + "en": " • {name} — {place}", + "fr": " • {name} — {place}", + "nl": " • {name} — {place}", + "de": " • {name} — {place}", + "es": " • {name} — {place}", + "pt": " • {name} — {place}", }, "run.place_custom": { "en": "page {page} @ ({x}, {y}) pt", @@ -1777,6 +2459,14 @@ def split_markup(text: str) -> list[tuple[str, bool]]: "es": "abajo a la derecha, {anchor} de cada documento", "pt": "em baixo à direita, {anchor} de cada documento", }, + "run.place_all": { + "en": "every page @ ({x}, {y}) pt", + "fr": "toutes les pages @ ({x}, {y}) pt", + "nl": "elke pagina @ ({x}, {y}) pt", + "de": "jede Seite @ ({x}, {y}) pt", + "es": "todas las páginas @ ({x}, {y}) pt", + "pt": "todas as páginas @ ({x}, {y}) pt", + }, "run.summary_anchor_last": { "en": "Files with a different page count are signed on their last page.", "fr": "Les fichiers dont le nombre de pages diffère sont signés sur leur dernière page.", diff --git a/i18n_docs.py b/i18n_docs.py index 4647fcc..136effb 100644 --- a/i18n_docs.py +++ b/i18n_docs.py @@ -41,12 +41,17 @@ "does. Trust is anchored on your organisation's internal CA.\n" " Use it when: you need a real cryptographic signature for many " "files quickly, without your physical card.\n\n" - "• **IMAGE — paste a picture only**\n" - " What it is: a visual stamp, NOT a cryptographic signature. No " - "legal value.\n" + "• **IMAGE — visual signatures only**\n" + " What it is: typed text (your choice of font and colour), an " + "image or a hand-drawn signature stamped on the pages. NOT a " + "cryptographic signature. No legal value.\n" " Requires: nothing; works fully offline.\n" - " Use it when: you only need a document to look signed, with no " - "legal effect.\n\n" + " Use it when: you only need a document to look signed, or to add " + "initials on every page.\n" + " Good to know: you can combine several elements per document, " + "and the same visual signatures can be added in BEID and AZURE " + "modes — they are stamped first and the cryptographic signature " + "then covers them.\n\n" "**Recommendation:** use BEID for legally binding documents, AZURE " "for large batches, and IMAGE only for appearance." ), @@ -75,12 +80,18 @@ " Quand l'utiliser : lorsque vous avez besoin d'une véritable " "signature cryptographique pour de nombreux fichiers, rapidement, " "sans votre carte physique.\n\n" - "• **IMAGE — coller une simple image**\n" - " Nature : un tampon visuel, PAS une signature cryptographique. " - "Aucune valeur juridique.\n" + "• **IMAGE — signatures visuelles uniquement**\n" + " Nature : un texte saisi (police et couleur au choix), une image " + "ou une signature dessinée à la main, apposés sur les pages. PAS " + "une signature cryptographique. Aucune valeur juridique.\n" " Prérequis : aucun ; fonctionne entièrement hors ligne.\n" " Quand l'utiliser : lorsque vous voulez seulement qu'un document " - "ait l'air signé, sans effet juridique.\n\n" + "ait l'air signé, ou pour ajouter un paraphe sur toutes les " + "pages.\n" + " Bon à savoir : vous pouvez combiner plusieurs éléments par " + "document, et les mêmes signatures visuelles peuvent être ajoutées " + "en modes BEID et AZURE — elles sont apposées en premier, puis la " + "signature cryptographique les couvre.\n\n" "**Recommandation :** utilisez BEID pour les documents " "juridiquement contraignants, AZURE pour les lots volumineux et " "IMAGE uniquement pour l'aspect visuel." @@ -112,12 +123,19 @@ " Gebruik deze modus wanneer: u snel een echte cryptografische " "handtekening voor veel bestanden nodig hebt, zonder uw fysieke " "kaart.\n\n" - "• **IMAGE — alleen een afbeelding plakken**\n" - " Wat het inhoudt: een visuele stempel, GEEN cryptografische " - "handtekening. Zonder juridische waarde.\n" + "• **IMAGE — alleen visuele handtekeningen**\n" + " Wat het inhoudt: getypte tekst (lettertype en kleur naar keuze), " + "een afbeelding of een met de hand getekende handtekening, " + "aangebracht op de pagina's. GEEN cryptografische handtekening. " + "Zonder juridische waarde.\n" " Vereist: niets; werkt volledig offline.\n" " Gebruik deze modus wanneer: een document er alleen ondertekend " - "moet uitzien, zonder juridisch effect.\n\n" + "moet uitzien, of om op elke pagina een paraaf te zetten.\n" + " Goed om te weten: u kunt meerdere elementen per document " + "combineren, en dezelfde visuele handtekeningen kunnen ook in de " + "modi BEID en AZURE worden toegevoegd — ze worden eerst " + "aangebracht en de cryptografische handtekening omvat ze " + "daarna.\n\n" "**Aanbeveling:** gebruik BEID voor juridisch bindende documenten, " "AZURE voor grote reeksen en IMAGE alleen als visuele stempel." ), @@ -147,12 +165,19 @@ "Ihrer Organisation verankert.\n" " Geeignet, wenn: Sie schnell eine echte kryptografische Signatur " "für viele Dateien benötigen, ohne Ihre physische Karte.\n\n" - "• **IMAGE — nur ein Bild einfügen**\n" - " Worum es sich handelt: ein sichtbarer Stempel, KEINE " - "kryptografische Signatur. Ohne Rechtswert.\n" + "• **IMAGE — nur visuelle Signaturen**\n" + " Worum es sich handelt: getippter Text (Schriftart und Farbe nach " + "Wahl), ein Bild oder eine von Hand gezeichnete Signatur, auf die " + "Seiten gestempelt. KEINE kryptografische Signatur. Ohne " + "Rechtswert.\n" " Erfordert: nichts; funktioniert vollständig offline.\n" - " Geeignet, wenn: ein Dokument lediglich signiert aussehen soll, " - "ohne rechtliche Wirkung.\n\n" + " Geeignet, wenn: ein Dokument lediglich signiert aussehen soll " + "oder jede Seite eine Paraphe erhalten soll.\n" + " Gut zu wissen: Sie können mehrere Elemente pro Dokument " + "kombinieren, und dieselben visuellen Signaturen lassen sich auch " + "in den Modi BEID und AZURE hinzufügen — sie werden zuerst " + "aufgebracht, und die kryptografische Signatur deckt sie " + "anschließend mit ab.\n\n" "**Empfehlung:** Verwenden Sie BEID für rechtsverbindliche " "Dokumente, AZURE für große Stapel und IMAGE nur, wenn es allein um " "das Erscheinungsbild geht." @@ -180,12 +205,17 @@ "interna de su organización.\n" " Úselo cuando: necesite una verdadera firma criptográfica para " "muchos archivos con rapidez, sin su tarjeta física.\n\n" - "• **IMAGE — solo pegar una imagen**\n" - " Qué es: un sello visual, NO una firma criptográfica. Sin valor " - "legal.\n" + "• **IMAGE — solo firmas visuales**\n" + " Qué es: un texto escrito (con la fuente y el color que elija), " + "una imagen o una firma dibujada a mano, estampados en las " + "páginas. NO es una firma criptográfica. Sin valor legal.\n" " Requiere: nada; funciona totalmente sin conexión.\n" - " Úselo cuando: solo necesite que un documento parezca firmado, " - "sin efecto legal.\n\n" + " Úselo cuando: solo necesite que un documento parezca firmado, o " + "para añadir una rúbrica en todas las páginas.\n" + " Conviene saber: puede combinar varios elementos por documento, " + "y las mismas firmas visuales pueden añadirse en los modos BEID y " + "AZURE — se estampan primero y la firma criptográfica las cubre " + "después.\n\n" "**Recomendación:** use BEID para documentos legalmente " "vinculantes, AZURE para lotes grandes e IMAGE solo por la " "apariencia." @@ -214,12 +244,18 @@ "interna da sua organização.\n" " Use-o quando: precisa de uma verdadeira assinatura criptográfica " "para muitos ficheiros, rapidamente e sem o seu cartão físico.\n\n" - "• **IMAGE — colar apenas uma imagem**\n" - " O que é: um carimbo visual, NÃO uma assinatura criptográfica. " - "Sem valor legal.\n" + "• **IMAGE — apenas assinaturas visuais**\n" + " O que é: um texto escrito (com o tipo de letra e a cor à sua " + "escolha), uma imagem ou uma assinatura desenhada à mão, aplicados " + "nas páginas. NÃO é uma assinatura criptográfica. Sem valor " + "legal.\n" " Requer: nada; funciona totalmente offline.\n" - " Use-o quando: basta que um documento pareça assinado, sem efeito " - "jurídico.\n\n" + " Use-o quando: basta que um documento pareça assinado, ou para " + "acrescentar uma rubrica em todas as páginas.\n" + " Convém saber: pode combinar vários elementos por documento, e " + "as mesmas assinaturas visuais podem ser adicionadas nos modos " + "BEID e AZURE — são aplicadas primeiro e a assinatura " + "criptográfica abrange-as em seguida.\n\n" "**Recomendação:** use BEID para documentos juridicamente " "vinculativos, AZURE para lotes grandes e IMAGE apenas para efeitos " "de aparência." @@ -399,9 +435,9 @@ "**AES VS QES: WHICH SIGNATURE DO I NEED?**\n\n" "Under EU law (eIDAS) there are three levels of electronic " "signature:\n\n" - "• **SES (simple)**: any electronic mark, even a pasted picture. " - "Easy, but weak proof of who signed. This is what \"image\" mode " - "produces — no legal value.\n\n" + "• **SES (simple)**: any electronic mark, even a pasted picture or a " + "typed name. Easy, but weak proof of who signed. This is what the " + "visual signatures of \"image\" mode produce — no legal value.\n\n" "• **AES (advanced)**: uniquely tied to one signer and to the exact " "document; any later change is detectable. This is \"azure\" mode.\n\n" "• **QES (qualified)**: an AES made with a certified device and a " @@ -433,8 +469,9 @@ "Le droit européen (eIDAS) distingue trois niveaux de signature " "électronique :\n\n" "• **SES (simple)** : toute marque électronique, même une image " - "collée. Facile, mais preuve faible de l'identité du signataire. " - "C'est ce que produit le mode « image » — aucune valeur juridique.\n\n" + "collée ou un nom saisi au clavier. Facile, mais preuve faible de " + "l'identité du signataire. C'est ce que produisent les signatures " + "visuelles du mode « image » — aucune valeur juridique.\n\n" "• **AES (avancée)** : liée de manière univoque à un seul " "signataire et au document lui-même ; toute modification ultérieure " "est détectable. C'est le mode « azure ».\n\n" @@ -471,8 +508,9 @@ "Volgens de EU-wetgeving (eIDAS) zijn er drie niveaus van " "elektronische handtekening:\n\n" "• **SES (eenvoudig)**: elk elektronisch merkteken, zelfs een " - "geplakte afbeelding. Gemakkelijk, maar een zwak bewijs van wie " - "heeft ondertekend. Dit is wat de modus 'image' oplevert — zonder " + "geplakte afbeelding of een getypte naam. Gemakkelijk, maar een " + "zwak bewijs van wie heeft ondertekend. Dit is wat de visuele " + "handtekeningen van de modus 'image' opleveren — zonder " "juridische waarde.\n\n" "• **AES (geavanceerd)**: uniek gekoppeld aan één ondertekenaar en " "aan het exacte document; elke latere wijziging is detecteerbaar. " @@ -509,9 +547,9 @@ "Nach EU-Recht (eIDAS) gibt es drei Stufen elektronischer " "Signaturen:\n\n" "• **SES (einfach)**: jedes elektronische Zeichen, selbst ein " - "eingefügtes Bild. Unkompliziert, aber nur ein schwacher Nachweis " - "dafür, wer signiert hat. Das erzeugt der Modus „image“ — ohne " - "Rechtswert.\n\n" + "eingefügtes Bild oder ein getippter Name. Unkompliziert, aber nur " + "ein schwacher Nachweis dafür, wer signiert hat. Das erzeugen die " + "visuellen Signaturen des Modus „image“ — ohne Rechtswert.\n\n" "• **AES (fortgeschritten)**: eindeutig einem Unterzeichner und " "genau diesem Dokument zugeordnet; jede spätere Änderung ist " "erkennbar. Das ist der Modus „azure“.\n\n" @@ -549,8 +587,9 @@ "Según la legislación de la UE (eIDAS) existen tres niveles de " "firma electrónica:\n\n" "• **SES (simple)**: cualquier marca electrónica, incluso una " - "imagen pegada. Fácil, pero con una prueba débil de quién firmó. Es " - "lo que produce el modo «image» — sin valor legal.\n\n" + "imagen pegada o un nombre escrito. Fácil, pero con una prueba " + "débil de quién firmó. Es lo que producen las firmas visuales del " + "modo «image» — sin valor legal.\n\n" "• **AES (avanzada)**: vinculada de forma única a un firmante y al " "documento exacto; cualquier cambio posterior es detectable. Es el " "modo «azure».\n\n" @@ -584,8 +623,9 @@ "Ao abrigo do direito da UE (eIDAS), existem três níveis de " "assinatura eletrónica:\n\n" "• **SES (simples)**: qualquer marca eletrónica, mesmo uma imagem " - "colada. Fácil, mas uma prova fraca de quem assinou. É o que o modo " - "«image» produz — sem valor legal.\n\n" + "colada ou um nome escrito. Fácil, mas uma prova fraca de quem " + "assinou. É o que as assinaturas visuais do modo «image» produzem " + "— sem valor legal.\n\n" "• **AES (avançada)**: ligada de forma única a um signatário e ao " "documento em causa; qualquer alteração posterior é detetável. É o " "modo «azure».\n\n" @@ -624,8 +664,9 @@ "Cachet signs PDF documents in batches. It can apply three kinds of " "mark: a cryptographic signature made with your Belgian eID card " "(beid), a cryptographic signature made with your personal " - "certificate held in Azure Key Vault (azure), or a simple pasted " - "image with no legal value (image). For the two cryptographic modes " + "certificate held in Azure Key Vault (azure), or visual signatures " + "with no legal value — typed text, an image or a drawing (image). " + "For the two cryptographic modes " "it follows the European PAdES standard and, after signing, " "re-checks each file and tells you exactly what was achieved. The " "terms below explain what those checks and labels mean.\n\n" @@ -742,6 +783,29 @@ "invisible cryptographic signature. You choose its position by " "clicking on the page preview; without a click it goes bottom-right " "on the last page.\n\n" + "**Visual signature**\n" + "A text, an image or a hand-drawn signature stamped on a page. It " + "is only an appearance: by itself it proves nothing. With eID or " + "Azure, Cachet stamps the visual signatures first and signs " + "afterwards, so the cryptographic signature covers them. A document " + "that is already signed cannot receive a visual signature without " + "breaking that earlier signature: with eID or Azure, Cachet refuses " + "such a document (sign it without visual signatures to add your " + "signature next to the existing one; if that earlier signature was " + "made by Cachet, use the command line with another --field name); " + "in image mode it stamps it and warns you in the report.\n\n" + "**Initials on every page**\n" + "A visual signature repeated at the same position on all pages of " + "each document (\"On every page\"). Not available for a batch whose " + "documents have different page counts.\n\n" + "**Signature library**\n" + "The visual signatures you created, their last position and your " + "preferences. They are saved unencrypted in your user folder and " + "reloaded at the next start; \"Delete\" removes a signature and its " + "stored image. PIN codes and sign-in tokens are never stored. To " + "erase everything, delete Cachet's configuration and data folders " + "in your user folder (a single folder on Windows and macOS; the " + "README gives their location).\n\n" "**Template validation**\n" "A safety check: before signing, every input PDF is compared to a " "model (\"template\") and must have the same page count and identical " @@ -764,8 +828,9 @@ "types de marques : une signature cryptographique réalisée avec " "votre carte eID belge (beid), une signature cryptographique " "réalisée avec votre certificat personnel conservé dans Azure Key " - "Vault (azure), ou une simple image collée sans valeur juridique " - "(image). Pour les deux modes cryptographiques, il suit la norme " + "Vault (azure), ou des signatures visuelles sans valeur juridique " + "— texte saisi, image ou dessin (image). " + "Pour les deux modes cryptographiques, il suit la norme " "européenne PAdES et, après la signature, revérifie chaque fichier " "et vous indique exactement ce qui a été obtenu. Les termes " "ci-dessous expliquent la signification de ces vérifications et de " @@ -898,6 +963,34 @@ "nu d'une signature cryptographique par ailleurs invisible. Vous " "choisissez sa position en cliquant sur l'aperçu de la page ; sans " "clic, elle ira en bas à droite de la dernière page.\n\n" + "**Signature visuelle**\n" + "Un texte, une image ou une signature dessinée à la main, apposés " + "sur une page. Ce n'est qu'une apparence : à elle seule, elle ne " + "prouve rien. Avec eID ou Azure, Cachet appose d'abord les " + "signatures visuelles et signe ensuite, de sorte que la signature " + "cryptographique les couvre. Un document déjà signé ne peut pas " + "recevoir de signature visuelle sans que cette signature antérieure " + "soit rompue : avec eID ou Azure, Cachet refuse un tel document " + "(signez-le sans signature visuelle pour ajouter votre signature à " + "côté de celle qui existe ; si cette dernière a été apposée par " + "Cachet, passez par la ligne de commande avec un autre nom " + "--field) ; en mode image, il y appose les signatures visuelles et " + "vous en avertit dans le rapport.\n\n" + "**Paraphe sur toutes les pages**\n" + "Une signature visuelle répétée à la même position sur toutes les " + "pages de chaque document (« Sur toutes les pages »). Indisponible " + "pour un lot dont les documents n'ont pas tous le même nombre de " + "pages.\n\n" + "**Bibliothèque de signatures**\n" + "Les signatures visuelles que vous avez créées, leur dernière " + "position et vos préférences. Elles sont enregistrées sans " + "chiffrement dans votre dossier utilisateur et rechargées au " + "prochain démarrage ; « Supprimer » retire une signature et son " + "image stockée. Les codes PIN et les jetons de connexion ne sont " + "jamais enregistrés. Pour tout effacer, supprimez les dossiers de " + "configuration et de données de Cachet dans votre dossier " + "utilisateur (un seul et même dossier sous Windows et macOS ; le " + "README indique leur emplacement).\n\n" "**Validation par rapport au modèle**\n" "Un contrôle de sécurité : avant la signature, chaque PDF à signer " "est comparé à un document de référence (le « modèle ») et doit " @@ -923,8 +1016,9 @@ "Cachet ondertekent PDF-documenten in reeksen. Het kan drie soorten " "merktekens aanbrengen: een cryptografische handtekening met uw " "Belgische eID-kaart (beid), een cryptografische handtekening met " - "uw persoonlijke certificaat in Azure Key Vault (azure), of een " - "eenvoudige geplakte afbeelding zonder juridische waarde (image). " + "uw persoonlijke certificaat in Azure Key Vault (azure), of " + "visuele handtekeningen zonder juridische waarde — getypte tekst, " + "een afbeelding of een tekening (image). " "Voor de twee cryptografische modi volgt het de Europese PAdES-norm " "en controleert het na het ondertekenen elk bestand opnieuw, " "waarbij het precies meldt wat is bereikt. De onderstaande termen " @@ -1058,6 +1152,34 @@ "een verder onzichtbare cryptografische handtekening. U kiest de " "positie door op het paginavoorbeeld te klikken; zonder klik komt " "het rechtsonder op de laatste pagina.\n\n" + "**Visuele handtekening**\n" + "Een tekst, een afbeelding of een met de hand getekende " + "handtekening die op een pagina wordt aangebracht. Het is alleen " + "een uiterlijk kenmerk: op zichzelf bewijst ze niets. Met eID of " + "Azure brengt Cachet eerst de visuele handtekeningen aan en " + "ondertekent het daarna, zodat de cryptografische handtekening ze " + "omvat. Een document dat al ondertekend is, kan geen visuele " + "handtekening krijgen zonder die eerdere handtekening ongeldig te " + "maken: met eID of Azure weigert Cachet zo'n document (onderteken " + "het zonder visuele handtekeningen om uw handtekening naast de " + "bestaande te plaatsen; is die eerdere handtekening door Cachet " + "gezet, gebruik dan de opdrachtregel met een andere --field-naam); " + "in de modus image brengt Cachet ze wel aan en waarschuwt het u in " + "het rapport.\n\n" + "**Paraaf op elke pagina**\n" + "Een visuele handtekening die op dezelfde positie wordt herhaald " + "op alle pagina's van elk document ('Op elke pagina'). Niet " + "beschikbaar voor een reeks waarvan de documenten een verschillend " + "aantal pagina's hebben.\n\n" + "**Handtekeningenbibliotheek**\n" + "De visuele handtekeningen die u hebt gemaakt, hun laatste positie " + "en uw voorkeuren. Ze worden onversleuteld in uw gebruikersmap " + "opgeslagen en bij de volgende start opnieuw geladen; " + "'Verwijderen' wist een handtekening en de bijbehorende opgeslagen " + "afbeelding. Pincodes en aanmeldtokens worden nooit opgeslagen. Om " + "alles te wissen, verwijdert u de configuratie- en de gegevensmap " + "van Cachet in uw gebruikersmap (onder Windows en macOS is dat één " + "enkele map; de README vermeldt de locatie).\n\n" "**Sjabloonvalidatie**\n" "Een veiligheidscontrole: vóór het ondertekenen wordt elke " "invoer-PDF vergeleken met een model ('sjabloon') en moet die " @@ -1083,8 +1205,9 @@ "Cachet signiert PDF-Dokumente stapelweise. Es kann drei Arten von " "Kennzeichnung anbringen: eine kryptografische Signatur mit Ihrer " "belgischen eID-Karte (beid), eine kryptografische Signatur mit " - "Ihrem persönlichen Zertifikat in Azure Key Vault (azure) oder ein " - "einfach eingefügtes Bild ohne Rechtswert (image). Für die beiden " + "Ihrem persönlichen Zertifikat in Azure Key Vault (azure) oder " + "visuelle Signaturen ohne Rechtswert — getippter Text, ein Bild " + "oder eine Zeichnung (image). Für die beiden " "kryptografischen Modi folgt es dem europäischen PAdES-Standard, " "prüft nach dem Signieren jede Datei erneut und teilt Ihnen genau " "mit, was erreicht wurde. Die folgenden Begriffe erklären, was " @@ -1220,6 +1343,33 @@ "kryptografischen Signatur. Die Position wählen Sie per Klick auf " "die Seitenvorschau; ohne Klick kommt sie unten rechts auf die " "letzte Seite.\n\n" + "**Visuelle Signatur**\n" + "Ein Text, ein Bild oder eine von Hand gezeichnete Signatur, die " + "auf eine Seite gestempelt wird. Sie ist nur ein Erscheinungsbild: " + "Für sich allein beweist sie nichts. Mit eID oder Azure bringt " + "Cachet zuerst die visuellen Signaturen auf und signiert danach, " + "sodass die kryptografische Signatur sie mit abdeckt. Ein bereits " + "signiertes Dokument kann keine visuelle Signatur erhalten, ohne " + "dass die frühere Signatur ungültig wird: Mit eID oder Azure lehnt " + "Cachet ein solches Dokument ab (signieren Sie es ohne visuelle " + "Signaturen, um Ihre Signatur neben die bestehende zu setzen; " + "stammt diese von Cachet, verwenden Sie die Kommandozeile mit " + "einem anderen --field-Namen); im Modus image stempelt Cachet es " + "und weist Sie im Bericht darauf hin.\n\n" + "**Paraphe auf jeder Seite**\n" + "Eine visuelle Signatur, die an derselben Position auf allen " + "Seiten jedes Dokuments wiederholt wird („Auf jeder Seite“). Nicht " + "verfügbar für einen Stapel, dessen Dokumente unterschiedliche " + "Seitenzahlen haben.\n\n" + "**Signaturbibliothek**\n" + "Die von Ihnen erstellten visuellen Signaturen, deren letzte " + "Position und Ihre Einstellungen. Sie werden unverschlüsselt in " + "Ihrem Benutzerordner gespeichert und beim nächsten Start wieder " + "geladen; „Löschen“ entfernt eine Signatur und ihr gespeichertes " + "Bild. PINs und Anmeldetoken werden niemals gespeichert. Um alles " + "zu löschen, entfernen Sie den Konfigurations- und den Datenordner " + "von Cachet in Ihrem Benutzerordner (unter Windows und macOS ein " + "und derselbe Ordner; die README nennt den Speicherort).\n\n" "**Vorlagenprüfung**\n" "Eine Sicherheitsprüfung: Vor dem Signieren wird jedes Eingabe-PDF " "mit einem Muster („Vorlage“) verglichen und muss dieselbe " @@ -1244,8 +1394,9 @@ "Cachet firma documentos PDF por lotes. Puede aplicar tres tipos de " "marca: una firma criptográfica realizada con su tarjeta eID belga " "(beid), una firma criptográfica realizada con su certificado " - "personal almacenado en Azure Key Vault (azure) o una simple imagen " - "pegada sin valor legal (image). En los dos modos criptográficos " + "personal almacenado en Azure Key Vault (azure) o firmas visuales " + "sin valor legal — texto escrito, una imagen o un dibujo (image). " + "En los dos modos criptográficos " "sigue la norma europea PAdES y, tras firmar, vuelve a comprobar " "cada archivo y le indica exactamente lo que se ha conseguido. Los " "términos siguientes explican el significado de esas comprobaciones " @@ -1374,6 +1525,31 @@ "firma criptográfica que, de otro modo, sería invisible. Su " "posición se elige haciendo clic en la vista previa de la página; " "si no hace clic, irá abajo a la derecha en la última página.\n\n" + "**Firma visual**\n" + "Un texto, una imagen o una firma dibujada a mano que se estampa " + "en una página. Es solo una apariencia: por sí sola no demuestra " + "nada. Con eID o Azure, Cachet estampa primero las firmas visuales " + "y firma después, de modo que la firma criptográfica las cubre. Un " + "documento que ya está firmado no puede recibir una firma visual " + "sin invalidar esa firma anterior: con eID o Azure, Cachet rechaza " + "ese documento (fírmelo sin firmas visuales para añadir su firma " + "junto a la existente; si esa firma anterior la hizo Cachet, use " + "la línea de comandos con otro nombre --field); en modo image lo " + "estampa y le avisa en el informe.\n\n" + "**Rúbrica en todas las páginas**\n" + "Una firma visual repetida en la misma posición en todas las " + "páginas de cada documento («En todas las páginas»). No está " + "disponible para un lote cuyos documentos tienen distinto número " + "de páginas.\n\n" + "**Biblioteca de firmas**\n" + "Las firmas visuales que ha creado, su última posición y sus " + "preferencias. Se guardan sin cifrar en su carpeta de usuario y se " + "vuelven a cargar en el siguiente inicio; «Eliminar» borra una " + "firma y su imagen almacenada. Los códigos PIN y los tokens de " + "inicio de sesión nunca se guardan. Para borrarlo todo, elimine " + "las carpetas de configuración y de datos de Cachet en su carpeta " + "de usuario (una sola carpeta en Windows y macOS; el README indica " + "su ubicación).\n\n" "**Validación con la plantilla**\n" "Una comprobación de seguridad: antes de firmar, cada PDF de " "entrada se compara con un modelo («plantilla») y debe tener el " @@ -1399,8 +1575,9 @@ "O Cachet assina documentos PDF em lote. Pode aplicar três tipos de " "marca: uma assinatura criptográfica feita com o seu cartão eID " "belga (beid), uma assinatura criptográfica feita com o seu " - "certificado pessoal guardado no Azure Key Vault (azure), ou uma " - "simples imagem colada sem valor legal (image). Para os dois modos " + "certificado pessoal guardado no Azure Key Vault (azure), ou " + "assinaturas visuais sem valor legal — texto escrito, uma imagem ou " + "um desenho (image). Para os dois modos " "criptográficos, segue a norma europeia PAdES e, depois de assinar, " "volta a verificar cada ficheiro e indica-lhe exatamente o que foi " "alcançado. Os termos abaixo explicam o significado dessas " @@ -1526,6 +1703,32 @@ "uma assinatura criptográfica que, de outro modo, seria invisível. " "A posição é escolhida clicando na pré-visualização da página; sem " "clique, a vinheta fica em baixo à direita na última página.\n\n" + "**Assinatura visual**\n" + "Um texto, uma imagem ou uma assinatura desenhada à mão, aplicados " + "numa página. É apenas uma aparência: por si só, não prova nada. " + "Com eID ou Azure, o Cachet aplica primeiro as assinaturas visuais " + "e assina depois, pelo que a assinatura criptográfica as abrange. " + "Um documento que já esteja assinado não pode receber uma " + "assinatura visual sem invalidar essa assinatura anterior: com eID " + "ou Azure, o Cachet recusa esse documento (assine-o sem " + "assinaturas visuais para acrescentar a sua assinatura ao lado da " + "existente; se essa assinatura anterior foi feita pelo Cachet, use " + "a linha de comandos com outro nome --field); no modo image, " + "aplica-as e avisa-o no relatório.\n\n" + "**Rubrica em todas as páginas**\n" + "Uma assinatura visual repetida na mesma posição em todas as " + "páginas de cada documento («Em todas as páginas»). Não está " + "disponível para um lote cujos documentos têm números de páginas " + "diferentes.\n\n" + "**Biblioteca de assinaturas**\n" + "As assinaturas visuais que criou, a respetiva última posição e as " + "suas preferências. São guardadas sem encriptação na sua pasta de " + "utilizador e recarregadas no arranque seguinte; «Eliminar» remove " + "uma assinatura e a respetiva imagem armazenada. Os códigos PIN e " + "os tokens de início de sessão nunca são guardados. Para apagar " + "tudo, elimine as pastas de configuração e de dados do Cachet na " + "sua pasta de utilizador (uma única pasta em Windows e macOS; o " + "README indica a sua localização).\n\n" "**Validação face ao modelo**\n" "Uma verificação de segurança: antes de assinar, cada PDF de " "entrada é comparado com um documento de referência (o «modelo») e " diff --git a/sign_pdfs_beid.py b/sign_pdfs_beid.py index 21581e2..1e71466 100644 --- a/sign_pdfs_beid.py +++ b/sign_pdfs_beid.py @@ -28,10 +28,11 @@ # merging develop -> main triggers the release workflow, which tags # v{__version__} and publishes the binaries (see .github/workflows/release.yml # and BUILD.md "Release process"). -__version__ = "1.3.1" +__version__ = "1.4.0" import argparse import dataclasses +import datetime import io import os import platform @@ -39,6 +40,7 @@ import sys import tempfile import warnings +from collections.abc import Sequence from pathlib import Path import requests @@ -53,7 +55,6 @@ from pyhanko.pdf_utils import images from pyhanko.pdf_utils.layout import ( AxisAlignment, - BoxConstraints, InnerScaling, Margins, SimpleBoxLayoutRule, @@ -63,9 +64,17 @@ from pyhanko.sign.validation import validate_pdf_signature from pyhanko.sign.validation.dss import DocumentSecurityStore from pyhanko.sign.validation.errors import NoDSSFoundError -from pyhanko.stamp import StaticStampStyle, TextStampStyle +from pyhanko.stamp import TextStampStyle from pyhanko_certvalidator import ValidationContext +# Visual signatures (text / image stamps). NAMES are imported, never the +# module object: `stamps` is also a RunConfig field and a sign_one() keyword. +from stamps import ( + BUNDLED_FONTS, DEFAULT_COLOR, DEFAULT_FONT, DEFAULT_FONT_SIZE, PAGE_ANCHORS, + Stamp, StampError, apply_stamps, existing_signature_count, load_stamps_file, + page_mediabox, validate_stamp, +) + # Since pyHanko >= 0.22, Belgian eID support lives in the separate plugin. # On a very old install (< 0.22), replace with: # from pyhanko.sign.beid import BEIDSigner @@ -285,33 +294,22 @@ def load_trust_anchor_certs(path) -> list: return certs -def _page_mediabox(writer, page_index: int) -> list[float]: - """MediaBox of page `page_index` (0-based, -1 = last), with inheritance - from the page tree.""" - page_ref, _ = writer.find_page_for_modification(page_index) - node = page_ref.get_object() - for _ in range(50): - if "/MediaBox" in node: - mb = node.raw_get("/MediaBox").get_object() - return [ - float(v.get_object() if hasattr(v, "get_object") else v) for v in mb - ] - parent = node.get("/Parent") - if parent is None: - break - node = parent.get_object() - return [0.0, 0.0, 595.276, 841.89] # A4 default +def default_vignette_rect(page_w: float, page_h: float) -> tuple[float, float, float, float]: + """(x, y, w, h) of the default bottom-right vignette, relative to the page's + bottom-left corner.""" + x1 = page_w - _STAMP_MARGIN + x0 = max(4, x1 - _STAMP_W) + y0 = _STAMP_MARGIN + y1 = min(y0 + _STAMP_H, page_h - 4) + return (x0, y0, x1 - x0, y1 - y0) def _default_vignette_box(writer, page_index: int = -1) -> tuple[float, float, float, float]: """Vignette rectangle, anchored bottom-right of page ``page_index`` (0-based, -1 = last page — the historical default).""" - mb = _page_mediabox(writer, page_index) - x1 = mb[2] - _STAMP_MARGIN - x0 = max(mb[0] + 4, x1 - _STAMP_W) - y0 = mb[1] + _STAMP_MARGIN - y1 = min(y0 + _STAMP_H, mb[3] - 4) - return (x0, y0, x1, y1) + mb = page_mediabox(writer, page_index) + x, y, w, h = default_vignette_rect(mb[2] - mb[0], mb[3] - mb[1]) + return (mb[0] + x, mb[1] + y, mb[0] + x + w, mb[1] + y + h) def build_stamp_style( @@ -488,10 +486,21 @@ def sign_one( legacy_cms: bool = False, timestamper: timestamps.TimeStamper | None = None, validation_context: ValidationContext | None = None, + stamps: Sequence[Stamp] = (), + stamp_date: datetime.date | None = None, + stamp_cache: dict | None = None, ) -> None: """Sign a PDF (incremental signature) with any pyHanko ``Signer`` and stamp the visible vignette onto it ("Signed by ..." + optional photo). + ``stamps`` are the visual signatures (text / image) of the run: they are + applied into the SAME incremental writer BEFORE the signature, so the + signature covers them — there is never a second pass on ``dst``. + ``stamp_date`` is the run date for ``{date}`` and ``stamp_cache`` the + batch-wide cache of rendered content. With stamps, an input that already + carries a signature or a document timestamp is refused (``StampError``) + before anything is signed; without stamps it is countersigned as before. + ``pades_level`` selects the PAdES baseline level (see ``signature_meta_kwargs``); ``timestamper`` must be provided for levels >= b-t and ``validation_context`` for b-lt/b-lta (both are built once per @@ -519,13 +528,27 @@ def sign_one( # refuses to sign them # ("hybrid cross-reference sections while hybrid xrefs are disabled"). writer = IncrementalPdfFileWriter(inf, strict=False) + if stamps: + # Stamps rewrite page content: on an input that already carries a + # signature or a document timestamp they would invalidate it, and + # self-verification (last signature only) would not notice. + if existing_signature_count(writer): + raise StampError( + "the document is already signed: a visual signature would " + "invalidate the existing signature(s) (sign it without visual " + "signatures to countersign)") + # Visual signatures go into THIS writer, before the signature. + # Stamping the signed output afterwards would be flagged as a + # modification of the signed document. + apply_stamps(writer, stamps, filename=src.stem, date=stamp_date, + cache=stamp_cache) if pos is None: on_page = page_index if page_index is not None else -1 box = _default_vignette_box(writer, on_page) style = build_stamp_style(identity) else: on_page = page_index if page_index is not None else -1 - mb = _page_mediabox(writer, on_page) + mb = page_mediabox(writer, on_page) vw, vh = vignette_size_pt(mb[2] - mb[0]) x0, y0 = mb[0] + pos[0], mb[1] + pos[1] box = (x0, y0, x0 + vw, y0 + vh) @@ -551,7 +574,6 @@ def sign_one( # batch contain documents whose page count differs from the template: the # anchor page must still match the template's anchor page exactly, so the # chosen (x, y) is guaranteed to fit the page that carries the signature. -PAGE_ANCHORS = ("first", "last") def anchor_page_index(page_anchor: str) -> int: @@ -599,15 +621,22 @@ def validate_against_template( pdf_path, *, page_anchor: str | None = None, + anchors=None, + blocker: str | None = None, ) -> ValidationResult: """Check that a PDF has the SAME page count AND per-page dimensions EXACTLY identical to the template (no tolerance). - With ``page_anchor`` ("first"/"last"), a file whose page count DIFFERS - from the template is accepted iff its anchor page has exactly the - template's anchor-page dimensions — that is the page the signature lands - on, so the chosen position is guaranteed to fit it. Files with the - template's page count keep the full strict check. + A file whose page count DIFFERS from the template is accepted iff EVERY + placed element targets a page anchor ("first"/"last") and each of those + anchor pages has exactly the template's anchor-page dimensions — those + are the pages the elements land on, so the chosen positions are + guaranteed to fit them. ``page_anchor`` names a single anchor; + ``anchors`` (a collection of anchors, see ``anchor_requirements``) + replaces it when given. ``blocker`` is a phrase naming an element that + does NOT target first/last: it rejects every page-count mismatch, with + that reason. Files with the template's page count keep the full strict + check. """ path = Path(pdf_path) try: @@ -616,20 +645,29 @@ def validate_against_template( return ValidationResult(path, False, f"unreadable ({exc})") if len(dims) != len(template_dims): count_msg = f"{len(dims)} page(s), the template has {len(template_dims)}" - if page_anchor is None or not dims or not template_dims: - return ValidationResult(path, False, count_msg) - idx = anchor_page_index(page_anchor) - d, t = dims[idx], template_dims[idx] - if d != t: + names = (tuple(a for a in PAGE_ANCHORS if a in anchors) if anchors is not None + else ((page_anchor,) if page_anchor else ())) + if blocker: return ValidationResult( path, False, - f"{count_msg}; {page_anchor} page {d[0]:.2f}×{d[1]:.2f} pt " - f"≠ template {t[0]:.2f}×{t[1]:.2f} pt", + f"{count_msg}; {blocker} (only first/last page targets accept " + "a different page count)", ) - return ValidationResult( - path, True, f"{count_msg} — signed on the {page_anchor} page" - ) + if not names or not dims or not template_dims: + return ValidationResult(path, False, count_msg) + for name in names: # EVERY anchor page must match + idx = anchor_page_index(name) + d, t = dims[idx], template_dims[idx] + if d != t: + return ValidationResult( + path, + False, + f"{count_msg}; {name} page {d[0]:.2f}×{d[1]:.2f} pt " + f"≠ template {t[0]:.2f}×{t[1]:.2f} pt", + ) + where = f"{names[0]} page" if len(names) == 1 else "first and last pages" + return ValidationResult(path, True, f"{count_msg} — signed on the {where}") for i, (d, t) in enumerate(zip(dims, template_dims), start=1): if d != t: return ValidationResult( @@ -652,49 +690,31 @@ def validate_files( # ========================================================================= -# "image" mode: inserting a signature image +# "image" mode: visual signatures only (text / image stamps) # ========================================================================= -_IMG_TARGET_W_PT = 150.0 # default insertion width (points, ratio preserved) - - -def image_size_pt(image_path) -> tuple[float, float]: - """Size (width, height) in points of the inserted image: fixed width - (_IMG_TARGET_W_PT), height derived from the ratio.""" - with Image.open(image_path) as im: - w_px, h_px = im.size - return (_IMG_TARGET_W_PT, _IMG_TARGET_W_PT * h_px / w_px) - - -def insert_image_one(src, dst, image_path, page_index: int, x: float, y: float) -> None: - """Insert the image on page `page_index` (0-based, -1 = last) with its - lower-left corner at (x, y) points from the page's lower-left corner. - Incremental update — no card required.""" - img = Image.open(image_path) - img.load() - w_pt, h_pt = image_size_pt(image_path) - n_pages = len(page_dimensions(src)) # clear message if the page is out of range - if not (-n_pages <= page_index < n_pages): - shown = page_index + 1 if page_index >= 0 else page_index - raise ValueError(f"page {shown} out of range (the document has {n_pages} page(s))") - with open(src, "rb") as inf: +def apply_stamps_one(src, dst, stamp_list, *, date=None, cache=None) -> bool: + """Visual-only path (image mode): apply every stamp, write ONE incremental update. + `dst` is written only when everything succeeded (no partial output). No card required. + + Returns True when the input already carried a signature or a document timestamp: + the stamps then invalidate it (historical behaviour of image mode, kept) and the + caller must say so.""" + if not stamp_list: + raise StampError("no visual signature to apply") + src = Path(src) + with src.open("rb") as inf: writer = IncrementalPdfFileWriter(inf, strict=False) - mb = _page_mediabox(writer, page_index) # (x, y) relative to the page corner - style = StaticStampStyle( - background=images.PdfImage(img), - background_opacity=1.0, - background_layout=SimpleBoxLayoutRule( - x_align=AxisAlignment.ALIGN_MID, - y_align=AxisAlignment.ALIGN_MID, - margins=Margins(), - inner_content_scaling=InnerScaling.STRETCH_TO_FIT, - ), - border_width=0, # no black border around the inserted image - ) - stamp = style.create_stamp(writer, BoxConstraints(width=w_pt, height=h_pt), {}) - stamp.apply(page_index, int(round(mb[0] + x)), int(round(mb[1] + y))) + try: + already_signed = existing_signature_count(writer) > 0 + except Exception: # noqa: BLE001 - malformed form (e.g. /AcroForm not a dictionary) + # Image mode has always stamped such a document: the flag only + # drives a warning, it must not fail what used to succeed. + already_signed = False + apply_stamps(writer, stamp_list, filename=src.stem, date=date, cache=cache) out = io.BytesIO() writer.write(out) Path(dst).write_bytes(out.getbuffer()) + return already_signed # ========================================================================= @@ -841,7 +861,7 @@ class RunConfig: inputs: list[Path] output: Path - mode: str = "beid" # "beid" (eID card + vignette) | "image" + mode: str = "beid" # "beid" | "azure" | "image" (visual signatures only) template: Path | None = None pades_level: str = "b-lta" # b-b | b-t | b-lt | b-lta (beid mode) field: str = "Signature" @@ -873,6 +893,11 @@ class RunConfig: azure_auth: str | None = None # None -> device-code (CLI) azure_trust_anchors: Path | None = None # PEM/DER file or directory azure_use_graph: bool = False # Graph /me displayName opt-in + # Visual signatures (text / image). beid/azure: applied into the same + # incremental writer BEFORE the cryptographic signature. image mode: + # they are the whole job. The legacy single-image fields above + # (image_path/page/x/y/page_anchor) still work in image mode: see effective_stamps(). + stamps: list[Stamp] = dataclasses.field(default_factory=list) @dataclasses.dataclass @@ -885,6 +910,46 @@ class DocResult: detail: str +def effective_stamps(cfg: RunConfig) -> list[Stamp]: + """Every visual signature of the run: the legacy single image of image mode (if any), + then cfg.stamps.""" + out: list[Stamp] = [] + if cfg.mode == "image" and cfg.image_path: + out.append(Stamp( + kind="image", image_path=Path(cfg.image_path), + page=None if cfg.page_anchor else (cfg.page or 1), + page_anchor=cfg.page_anchor, + x=cfg.x if cfg.x is not None else 0.0, + y=cfg.y if cfg.y is not None else 0.0)) + out.extend(cfg.stamps) + return out + + +def anchor_requirements(cfg: RunConfig) -> tuple[tuple[str, ...], str | None]: + """(anchors, blocker) for template validation. `anchors`: the first/last anchors used + by the placed elements, ordered ("first", "last"). `blocker`: None when EVERY element + (each stamp, and the vignette in beid/azure) targets first/last, else a phrase naming the + first element that does not.""" + recorded: set[str] = set() + blocker = None + for i, s in enumerate(effective_stamps(cfg), 1): + if s.page_anchor: + recorded.add(s.page_anchor) + elif blocker is None: + blocker = (f"signature #{i} targets every page" if s.all_pages + else f"signature #{i} targets page {s.page}") + if cfg.mode in ("beid", "azure"): + if cfg.page_anchor: + recorded.add(cfg.page_anchor) + elif blocker is None: + # The default bottom-right vignette is NOT auto-anchored: a safety + # check is never relaxed silently, --page first|last must be explicit. + blocker = (f"the vignette targets page {cfg.page or 1}" + if cfg.x is not None and cfg.y is not None + else "the vignette has no first/last page target") + return (tuple(a for a in PAGE_ANCHORS if a in recorded), blocker) + + def validate_config(cfg: RunConfig) -> None: """Check the consistency of a RunConfig; raises ValueError otherwise.""" if not cfg.inputs: @@ -957,13 +1022,24 @@ def validate_config(cfg: RunConfig) -> None: raise ValueError( f"Trust anchors not found: {cfg.azure_trust_anchors}" ) + # Visual signatures: the legacy image-mode checks first (their historical + # messages win), then every stamp. Optional in beid/azure, where + # cfg.image_path is ignored. + stamp_list = effective_stamps(cfg) if cfg.mode == "image": - if not cfg.image_path: - raise ValueError("--image-path is required in image mode.") - if not Path(cfg.image_path).exists(): + if cfg.image_path and not Path(cfg.image_path).exists(): raise ValueError(f"Image not found: {cfg.image_path}") if cfg.page is not None and cfg.page < 1: raise ValueError("--page must be >= 1.") + if not stamp_list: + raise ValueError( + "image mode needs at least one visual signature: " + "--text, --image-path or --signatures.") + for i, s in enumerate(stamp_list, 1): + try: + validate_stamp(s) + except StampError as exc: + raise ValueError(f"Signature #{i}: {exc}.") from None if cfg.template and not Path(cfg.template).exists(): raise ValueError(f"Template not found: {cfg.template}") @@ -1104,13 +1180,21 @@ def verify_signed_pdf( return label -def process_batch(cfg: RunConfig, *, on_progress=None) -> list[DocResult]: +def process_batch(cfg: RunConfig, *, on_progress=None, + today: datetime.date | None = None) -> list[DocResult]: """Validate (if a template is provided) then process each file according to the mode. Returns one DocResult per input file. `on_progress` is called after each document (useful for the GUI). In beid mode the PKCS#11 session, the RFC 3161 timestamper and the LTV ValidationContext are built ONCE here and reused for every document. + + The visual signatures (``effective_stamps``) are resolved ONCE too, with + one run date for ``{date}`` (``today``, injectable for tests; default: the + local date) and one batch-wide cache of rendered content. In beid/azure + mode they are handed to ``sign_one``, which applies them into the same + incremental writer BEFORE the signature — the signed output is never + stamped afterwards. In image mode they are the whole job. """ results: list[DocResult] = [] template_dims = page_dimensions(cfg.template) if cfg.template else None @@ -1161,7 +1245,13 @@ def process_batch(cfg: RunConfig, *, on_progress=None) -> list[DocResult]: Path(cfg.output).mkdir(parents=True, exist_ok=True) - # Optional position (None = unspecified). beid mode: if provided, vignette + stamp_list = effective_stamps(cfg) + stamp_date = today or datetime.date.today() # ONE local date for the whole run + stamp_cache: dict = {} # rendered/loaded images, batch-wide + anchors, blocker = anchor_requirements(cfg) + + # VIGNETTE placement (beid/azure; unused in image mode, where every stamp + # carries its own). Optional position (None = unspecified): if provided, vignette # placed freely; otherwise default vignette (bottom-right corner). # A page anchor resolves the page PER DOCUMENT (first -> 0, last -> -1), # which is what makes page-count mismatches against the template workable. @@ -1172,8 +1262,6 @@ def process_batch(cfg: RunConfig, *, on_progress=None) -> list[DocResult]: else: page_index = (cfg.page or 1) - 1 page_label = f"page {cfg.page or 1}" - x = cfg.x if cfg.x is not None else 0.0 - y = cfg.y if cfg.y is not None else 0.0 label = signature_level_label(cfg.pades_level, cfg.legacy_cms) mode_tag = "eID" if cfg.mode == "beid" else ( @@ -1183,7 +1271,7 @@ def process_batch(cfg: RunConfig, *, on_progress=None) -> list[DocResult]: src = Path(src) if template_dims is not None: verdict = validate_against_template( - template_dims, src, page_anchor=cfg.page_anchor + template_dims, src, anchors=anchors, blocker=blocker ) if not verdict.ok: res = DocResult(src, None, False, f"rejected — {verdict.reason}") @@ -1199,13 +1287,17 @@ def process_batch(cfg: RunConfig, *, on_progress=None) -> list[DocResult]: legacy_cms=cfg.legacy_cms, timestamper=material.timestamper, validation_context=material.validation_context, + # Applied by sign_one BEFORE the signature, same writer. + stamps=stamp_list, + stamp_date=stamp_date, + stamp_cache=stamp_cache, ) if placement: sign_one(signer, src, dst, f"{cfg.field}1", cfg.pades_level, - identity, page_index=page_index, pos=(x, y), + identity, page_index=page_index, pos=(cfg.x, cfg.y), **sign_kwargs) prefix = (f"signed ({mode_tag}) — vignette {page_label} " - f"@ ({x:.0f}, {y:.0f})") + f"@ ({cfg.x:.0f}, {cfg.y:.0f})") else: # No position: default bottom-right vignette. An anchor # moves it to the first/last page; None keeps the @@ -1217,6 +1309,8 @@ def process_batch(cfg: RunConfig, *, on_progress=None) -> list[DocResult]: prefix = f"signed ({mode_tag}) — vignette" if cfg.page_anchor: prefix += f" ({page_label}, bottom-right)" + if stamp_list: + prefix += f" + {len(stamp_list)} visual signature(s)" # R8: re-open + validate, report the *achieved* level. A # mismatch raises SelfVerificationError -> document failed. if (cfg.verify and not cfg.legacy_cms @@ -1229,8 +1323,14 @@ def process_batch(cfg: RunConfig, *, on_progress=None) -> list[DocResult]: else: detail = f"{prefix} — {label}" else: - insert_image_one(src, dst, cfg.image_path, page_index, x, y) - detail = f"image inserted — {page_label} @ ({x:.0f}, {y:.0f})" + already_signed = apply_stamps_one( + src, dst, stamp_list, date=stamp_date, cache=stamp_cache) + detail = (f"{len(stamp_list)} visual signature(s) applied — " + + "; ".join(s.describe() for s in stamp_list)) + if already_signed: + # Historical outcome of image mode, kept — but said out loud. + detail += (" — WARNING: the document was already signed; its " + "existing signature(s) are no longer valid") res = DocResult(src, dst, True, detail) except SelfVerificationError as exc: res = DocResult( @@ -1291,9 +1391,15 @@ def describe_placement(cfg: RunConfig) -> str: return f"vignette bottom-right, {cfg.page_anchor or 'last'} page" +def describe_stamps(cfg: RunConfig) -> list[str]: + """One human line per visual signature of the run (CLI banner).""" + return [f"{s.describe()} — {s.content_label()}" for s in effective_stamps(cfg)] + + def build_arg_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( - description="Batch-sign (Belgian eID card) or stamp an image onto PDFs." + description="Batch-sign PDFs (Belgian eID card or Azure Key Vault) and/or " + "stamp visual signatures (text, images) onto them." ) # Positionals kept for backward compatibility: "inputs… output". parser.add_argument( @@ -1318,32 +1424,68 @@ def build_arg_parser() -> argparse.ArgumentParser: "--mode", choices=("beid", "image", "azure"), default="beid", - help="Mode: beid (eID card + vignette), image (image insertion), or " - "azure (your personal certificate in Azure Key Vault via a " - "Microsoft Entra ID login — an advanced (AES), not qualified, " - "signature).", + help="Mode: beid (eID card + vignette), azure (your personal " + "certificate in Azure Key Vault via a Microsoft Entra ID login — " + "an advanced (AES), not qualified, signature), or image (visual " + "signatures only: text and/or images, NOT a cryptographic " + "signature). beid and azure can also carry visual signatures " + "(--signatures), applied before the cryptographic signature.", ) parser.add_argument( "--image-path", dest="image_path", default=None, - help="Image to insert (required in --mode image).", + help="Image to stamp in --mode image (legacy single-image form; " + "placed with --page/--x/--y).", ) parser.add_argument( "--page", type=page_arg, default=None, metavar="N|first|last", help="Target page: a 1-based number, or 'first'/'last' (resolved per " - "document). Image: insertion page. beid: vignette page. With " - "--template, first/last also accepts files whose page count " - "differs from the template (their first/last page must still " - "match the template's).", + "document). image mode: page of the --text / --image-path " + "signature. beid/azure: vignette page. With --template, a file " + "whose page count differs from the template is accepted only if " + "EVERY element targets first/last (and those pages match the " + "template's).", ) parser.add_argument( "--x", type=float, default=None, help="X position (points, from the page's lower-left corner). " - "In beid mode, --x/--y place the vignette (otherwise: bottom-right).", + "image mode: the --text / --image-path signature. beid/azure: " + "--x/--y place the vignette (otherwise: bottom-right).", ) parser.add_argument( "--y", type=float, default=None, help="Y position (points, from the page's lower-left corner).", ) + visual = parser.add_argument_group( + "visual signatures", "Text and image signatures stamped on the pages. " + "Not a cryptographic signature by themselves." + ) + visual.add_argument( + "--signatures", dest="signatures", default=None, metavar="FILE.json", + help="JSON file: a list of visual signatures (kind text|image, " + "text/font/color/font_size or image_path/width_pt, one of page / " + "page_anchor / all_pages, x, y). Works in every mode; in " + "beid/azure they are applied before the cryptographic signature. " + "See README.", + ) + visual.add_argument( + "--text", default=None, + help="Text signature for --mode image, placed with --page/--x/--y. " + "'\\n' starts a new line; {date} and {filename} are replaced per " + "document.", + ) + visual.add_argument( + "--font", default=None, + help=f"Font of --text: one of {', '.join(BUNDLED_FONTS)} or the path of " + f"a .ttf/.otf file (default: {DEFAULT_FONT}).", + ) + visual.add_argument( + "--color", default=None, + help=f"Colour of --text as #RRGGBB (default: {DEFAULT_COLOR}).", + ) + visual.add_argument( + "--font-size", dest="font_size", type=float, default=None, + help="Font size of --text in points (default: 24).", + ) parser.add_argument("--lib", default=None, help="Path to the eID PKCS#11 lib.") parser.add_argument( "--field", default="Signature", help="Base name of the signature field (beid mode)." @@ -1486,6 +1628,43 @@ def resolve_config(args) -> RunConfig: if isinstance(page, str): page_anchor, page = page, None + # Visual signatures. getattr(): hand-made namespaces may lack the flags. + # --page/--x/--y belong to the single convenience stamp (--text here, or + # the legacy --image-path through effective_stamps) in image mode, and to + # the vignette in beid/azure; the entries of --signatures carry their own + # placement. The persisted GUI profile is NEVER read here. + text = getattr(args, "text", None) + font = getattr(args, "font", None) + color = getattr(args, "color", None) + font_size = getattr(args, "font_size", None) + sig_file = getattr(args, "signatures", None) + if text is None and (font is not None or color is not None or font_size is not None): + raise ValueError("--font, --color and --font-size need --text.") + if text is not None and args.mode != "image": + raise ValueError( + "--text only applies to --mode image; in beid/azure mode pass the " + "visual signatures with --signatures.") + if text is not None and args.image_path: + raise ValueError( + "--text and --image-path are mutually exclusive; use --signatures " + "to stamp several elements.") + stamp_list: list[Stamp] = [] + if text is not None: + stamp_list.append(Stamp( + kind="text", text=text.replace("\\n", "\n"), + font=font or DEFAULT_FONT, color=color or DEFAULT_COLOR, + font_size=font_size if font_size is not None else DEFAULT_FONT_SIZE, + page=None if page_anchor else (page or 1), page_anchor=page_anchor, + x=args.x if args.x is not None else 0.0, + y=args.y if args.y is not None else 0.0)) + if sig_file: + stamp_list.extend(load_stamps_file(sig_file)) # StampError is a ValueError + if (args.mode == "image" and text is None and not args.image_path + and (page is not None or page_anchor or args.x is not None or args.y is not None)): + raise ValueError( + "--page/--x/--y need --text or --image-path in image mode: the " + "signatures of --signatures carry their own placement.") + cfg = RunConfig( inputs=collect_pdfs([str(p) for p in raw_inputs]), output=Path(output) if output else None, @@ -1521,12 +1700,21 @@ def resolve_config(args) -> RunConfig: else None ), azure_use_graph=getattr(args, "azure_use_graph", False), + stamps=stamp_list, ) validate_config(cfg) return cfg def main() -> int: + # Texts and file names are echoed: a character the console encoding lacks + # (redirected output on Windows is the ANSI code page) is escaped instead + # of raising UnicodeEncodeError before any document is processed. Guarded: + # a replaced stream (StringIO) has no reconfigure, and there is no stdout + # at all in the windowed binary. + for stream in (sys.stdout, sys.stderr): + if hasattr(stream, "reconfigure"): + stream.reconfigure(errors="backslashreplace") parser = build_arg_parser() args = parser.parse_args() @@ -1549,6 +1737,13 @@ def main() -> int: except ValueError as exc: parser.error(str(exc)) + stamp_lines = describe_stamps(cfg) + extra = f" + {len(stamp_lines)} visual signature(s)" if stamp_lines else "" + + def print_stamp_lines() -> None: + for i, line in enumerate(stamp_lines, 1): + print(f" {i}. {line}") + if cfg.mode == "beid": lib_path = cfg.lib or default_pkcs11_lib() if not Path(lib_path).exists(): @@ -1558,7 +1753,8 @@ def main() -> int: file=sys.stderr, ) return 1 - print(f"Mode: eID — {describe_placement(cfg)}. PKCS#11 lib: {lib_path}") + print(f"Mode: eID — {describe_placement(cfg)}{extra}. PKCS#11 lib: {lib_path}") + print_stamp_lines() # R9: the RRN is in the signing certificate, hence in every signature. print( "WARNING: each eID signature embeds the signer's national " @@ -1575,8 +1771,9 @@ def main() -> int: print(f"LTV trust anchors: EU trusted list ({resolve_lotl_url(cfg.trust_list_url)})") print(f"{len(cfg.inputs)} PDF(s). The PIN will be requested for each document.") elif cfg.mode == "azure": - print(f"Mode: Azure Key Vault — {describe_placement(cfg)}. " + print(f"Mode: Azure Key Vault — {describe_placement(cfg)}{extra}. " f"Vault: {cfg.azure_vault_url}") + print_stamp_lines() # R11: AES, not QES — and the signature carries the user's identity. print( "Note: signs with YOUR personal Key Vault certificate — an " @@ -1592,18 +1789,17 @@ def main() -> int: print(f"{len(cfg.inputs)} PDF(s). One Microsoft sign-in for the whole " f"batch ({resolve_azure_auth(cfg.azure_auth)}).") else: - page_phrase = (f"{cfg.page_anchor} page" if cfg.page_anchor - else f"page {cfg.page or 1}") - print( - f"Mode: image — {cfg.image_path} " - f"({page_phrase}, x={cfg.x or 0:.0f}, y={cfg.y or 0:.0f})." - ) + print(f"Mode: visual signatures — {len(stamp_lines)} element(s):") + print_stamp_lines() print(f"{len(cfg.inputs)} PDF(s).") if cfg.template: print(f"Validation against the template: {cfg.template}") - if cfg.page_anchor: + anchors, blocker = anchor_requirements(cfg) + if anchors and not blocker: + where = (f"{anchors[0]} page" if len(anchors) == 1 + else "first and last pages") print(f" Files whose page count differs from the template are " - f"accepted and signed on their {cfg.page_anchor} page.") + f"accepted and signed on their {where}.") print() def progress(r: DocResult) -> None: diff --git a/test_azure.py b/test_azure.py index 85f76b0..b0a1e8f 100644 --- a/test_azure.py +++ b/test_azure.py @@ -11,6 +11,7 @@ import base64 import datetime import json +import os import tempfile import unittest from pathlib import Path @@ -19,7 +20,26 @@ import azure_signer import sign_pdfs_beid as core -from test_sign_pdfs_beid import make_pdf +from stamps import Stamp +from test_sign_pdfs_beid import make_pdf, xobject_counts + +_PROFILE_SANDBOX = None + + +def setUpModule(): + """Safety net: no test of this module can reach the real user profile + (GuiAzurePanel's per-test directories sit on top of this).""" + global _PROFILE_SANDBOX + root = tempfile.mkdtemp(prefix="cachet-tests-") + _PROFILE_SANDBOX = mock.patch.dict(os.environ, { + "CACHET_CONFIG_DIR": os.path.join(root, "cfg"), + "CACHET_DATA_DIR": os.path.join(root, "data")}) + _PROFILE_SANDBOX.start() + + +def tearDownModule(): + _PROFILE_SANDBOX.stop() + # --------------------------------------------------------------------------- # Local key/cert helpers (cryptography) — no Azure, no network @@ -361,6 +381,43 @@ def test_ec_raw_rs_converted_to_der_and_validates(self): trust_anchors=[signer.signing_cert]) self.assertEqual(detail, "PAdES-B-B") + def test_stamps_then_azure_signature_validates(self): + # Visual signature + azure signature through the REAL core.sign_one: + # the stamp goes into the same writer before the signature, so the + # signature covers it — and still only the digest goes to Key Vault. + from pyhanko.pdf_utils.reader import PdfFileReader + from pyhanko.sign.validation import validate_pdf_signature + from pyhanko.sign.validation.status import ( + ModificationLevel, SignatureCoverageLevel) + from pyhanko_certvalidator import ValidationContext + + for ec_key, alg in ((False, "RS256"), (True, "ES256")): + with self.subTest(alg=alg): + signer, fake = self._build(ec_key=ec_key) + src = make_pdf(self.p(f"doc_{alg}.pdf"), [(595, 842)] * 2) + dst = self.p(f"signed_{alg}.pdf") + core.sign_one( + signer, src, dst, "Signature1", "b-b", + core.read_cert_identity(signer.signing_cert), + stamps=[Stamp(kind="text", text="Jane Doe\n{date}", + all_pages=True, x=360.0, y=120.0)]) + (call_alg, digest), = fake.calls + self.assertEqual(call_alg, alg) + self.assertEqual(len(digest), 32) + self.assertEqual( + core.verify_signed_pdf(dst, "b-b", + trust_anchors=[signer.signing_cert]), + "PAdES-B-B") + with dst.open("rb") as f: + reader = PdfFileReader(f, strict=False) + status = validate_pdf_signature( + reader.embedded_regular_signatures[0], + ValidationContext(trust_roots=[signer.signing_cert])) + self.assertTrue(status.bottom_line, status.summary()) + self.assertEqual(status.coverage, SignatureCoverageLevel.ENTIRE_FILE) + self.assertEqual(status.modification_level, ModificationLevel.NONE) + self.assertEqual(xobject_counts(dst), [1, 1]) # stamped on both pages + def test_vault_error_is_actionable(self): key_client = SimpleNamespace( get_key=mock.Mock(side_effect=OSError("connection refused"))) @@ -520,6 +577,28 @@ def test_default_vignette_and_placement_pass_through(self): self.assertEqual(kw.get("pos"), (10.0, 20.0)) self.assertIn("page 2", results[0].detail) + def test_stamps_forwarded_to_sign_one(self): + srcs = [make_pdf(self.p(f"d{i}.pdf"), [(595, 842)]) for i in range(2)] + extra = [Stamp(kind="text", text="Jane Doe", page_anchor="last", x=10.0, y=20.0), + Stamp(kind="text", text="JD", all_pages=True, x=540.0, y=20.0)] + cfg = core.RunConfig(inputs=srcs, output=self.p("out"), mode="azure", + azure_vault_url="https://v.example", stamps=extra) + calls, results = self._run(cfg) + self.assertTrue(all(r.ok for r in results)) + self.assertEqual(len(calls["sign"]), 2) + for _, kw in calls["sign"]: + self.assertEqual(kw["stamps"], extra) + self.assertIsInstance(kw["stamp_date"], datetime.date) + self.assertIsNone(kw.get("pos")) # the vignette keeps its default + # ONE cache for the whole batch + self.assertIsInstance(calls["sign"][0][1]["stamp_cache"], dict) + self.assertIs(calls["sign"][0][1]["stamp_cache"], + calls["sign"][1][1]["stamp_cache"]) + self.assertEqual( + results[0].detail, + "signed (Azure, jane@example.org) — vignette + 2 visual signature(s) " + "— PAdES-B-LTA, LTV ok") + class AzureSigningMaterial(TmpCase): """build_signing_material: azure uses the INTERNAL CA, never the LOTL.""" @@ -568,7 +647,19 @@ def setUp(self): tkinter.Tk().destroy() import gui # noqa: F401 except Exception as exc: # noqa: BLE001 + # A run that is SUPPOSED to exercise the GUI must not turn a + # broken gui.py or a missing display into a green "all skipped". + if os.environ.get("CACHET_REQUIRE_GUI") == "1": + self.fail("GUI tests are required (CACHET_REQUIRE_GUI=1) but " + f"unavailable: {exc!r}") self.skipTest(f"tkinter/GUI unavailable: {exc}") + # The GUI loads and auto-saves a user profile: never the real one. + self.tmp = Path(tempfile.mkdtemp()) + env = mock.patch.dict(os.environ, { + "CACHET_CONFIG_DIR": str(self.tmp / "cfg"), + "CACHET_DATA_DIR": str(self.tmp / "data")}) + env.start() + self.addCleanup(env.stop) def _wizard_to_mode_step(self, app): """Complete steps 1-4 with minimal state and enter the mode step.""" @@ -604,10 +695,11 @@ def test_azure_panel_toggles_with_mode(self): app._refresh_azure_visibility() app.update() self.assertFalse(app.azure_section.winfo_manager()) # hidden again - # the image picker lives on the placement step, image mode only + # placement step, image mode: the add buttons, and no vignette app._goto_step(5) app.update() - self.assertTrue(app.image_row.winfo_manager()) + self.assertTrue(app.add_image_btn.winfo_manager()) + self.assertNotIn(gui.VIGNETTE_ID, app._element_rows) finally: app.destroy() diff --git a/test_sign_pdfs_beid.py b/test_sign_pdfs_beid.py index f076253..df35499 100644 --- a/test_sign_pdfs_beid.py +++ b/test_sign_pdfs_beid.py @@ -6,34 +6,30 @@ Run with: ./venv/bin/python -m unittest -v """ +import dataclasses +import datetime +import gc +import json +import os +import shutil import subprocess import sys import tempfile import unittest import warnings from pathlib import Path +from unittest import mock from PIL import Image import sign_pdfs_beid as core +import stamps as stamplib +from stamps import Stamp, StampError -def make_pdf(path, page_sizes) -> Path: - """Writes a minimal but valid PDF (correct xref) with the given pages, - each described by a (width, height) in points. Each page has a (empty) - /Contents stream — required by pyHanko in order to stamp.""" - n = len(page_sizes) - objs = [b"<>"] # obj 1 - kids = " ".join(f"{3 + 2 * i} 0 R" for i in range(n)) - objs.append(f"<>".encode()) # obj 2 - content = b"q Q\n" - for i, (w, h) in enumerate(page_sizes): - objs.append( - f"<>".encode() - ) - objs.append(b"<>\nstream\n" % len(content) + content + b"\nendstream") - +def write_pdf_objects(path, objs) -> Path: + """Writes a PDF (correct xref) from the bodies of its objects: `objs[0]` + is object 1 and must be the catalog.""" out = bytearray(b"%PDF-1.4\n") offsets = [] for i, body in enumerate(objs, start=1): @@ -49,11 +45,72 @@ def make_pdf(path, page_sizes) -> Path: return Path(path) +def pdf_stream(data: bytes) -> bytes: + """Body of a stream object holding `data`.""" + return b"<>\nstream\n" % len(data) + data + b"\nendstream" + + +def make_pdf(path, page_sizes, origin=(0, 0)) -> Path: + """Writes a minimal but valid PDF (correct xref) with the given pages, + each described by a (width, height) in points. Each page has a (empty) + /Contents stream — required by pyHanko in order to stamp. `origin` is the + lower-left corner of every MediaBox.""" + n = len(page_sizes) + ox, oy = origin + objs = [b"<>"] # obj 1 + kids = " ".join(f"{3 + 2 * i} 0 R" for i in range(n)) + objs.append(f"<>".encode()) # obj 2 + for i, (w, h) in enumerate(page_sizes): + objs.append( + f"<>".encode() + ) + objs.append(pdf_stream(b"q Q\n")) + return write_pdf_objects(path, objs) + + def make_png(path, size=(300, 120)) -> Path: Image.new("RGBA", size, (255, 0, 0, 128)).save(path) return Path(path) +def xobject_counts(pdf_path) -> list[int]: + """Number of XObjects referenced by each page of a PDF: one per visual + signature stamped on it (the signature vignette is an annotation, not a + page XObject).""" + # Lazy: test_stamps imports this module at import time. + from test_stamps import page_xobjects, pdf_pages + return [len(page_xobjects(page)) for page in pdf_pages(pdf_path)] + + +def text_stamp(text="Jane Doe", **kwargs) -> Stamp: + """A text stamp; placed on page 1 at (50, 50) unless told otherwise.""" + if not {"page", "page_anchor", "all_pages"} & kwargs.keys(): + kwargs["page"] = 1 + kwargs.setdefault("x", 50.0) + kwargs.setdefault("y", 50.0) + return Stamp(kind="text", text=text, **kwargs) + + +_PROFILE_SANDBOX = None + + +def setUpModule(): + """Safety net: no test of this module can reach the real user profile, + even one that builds `gui.CachetApp` without `_GuiTestBase` (whose + per-test directories sit on top of this).""" + global _PROFILE_SANDBOX + root = tempfile.mkdtemp(prefix="cachet-tests-") + _PROFILE_SANDBOX = mock.patch.dict(os.environ, { + "CACHET_CONFIG_DIR": os.path.join(root, "cfg"), + "CACHET_DATA_DIR": os.path.join(root, "data")}) + _PROFILE_SANDBOX.start() + + +def tearDownModule(): + _PROFILE_SANDBOX.stop() + + class TmpCase(unittest.TestCase): def setUp(self): self.tmp = Path(tempfile.mkdtemp()) @@ -126,13 +183,111 @@ def test_anchor_keeps_strict_check_for_same_page_count(self): self.assertFalse(r.ok) self.assertIn("page 1", r.reason) + def test_two_anchors_both_checked(self): + dims = core.page_dimensions(self.tpl) + both = ("first", "last") + # first page matches, last page differs -> rejected, naming the last page + odd_last = make_pdf(self.p("odd_last.pdf"), + [(595, 842), (595, 842), (200, 200)]) + r = core.validate_against_template(dims, odd_last, anchors=both) + self.assertFalse(r.ok) + self.assertIn("last page", r.reason) + # ... and the other way round names the first page + odd_first = make_pdf(self.p("odd_first.pdf"), + [(200, 200), (595, 842), (595, 842)]) + r = core.validate_against_template(dims, odd_first, anchors=both) + self.assertFalse(r.ok) + self.assertIn("first page", r.reason) + # both anchor pages match -> accepted + more = make_pdf(self.p("more.pdf"), [(595, 842), (100, 100), (595, 842)]) + r = core.validate_against_template(dims, more, anchors=both) + self.assertTrue(r.ok, r.reason) + self.assertIn("first and last pages", r.reason) + # the order of the collection does not matter + self.assertEqual( + core.validate_against_template(dims, more, anchors={"last", "first"}).reason, + r.reason) + + def test_blocker_rejects_with_reason(self): + dims = core.page_dimensions(self.tpl) + fewer = make_pdf(self.p("fewer.pdf"), [(595, 842)]) + blocker = "signature #1 targets page 1" + # even with a matching anchor: ONE non-anchored element is enough + r = core.validate_against_template(dims, fewer, anchors=("last",), blocker=blocker) + self.assertFalse(r.ok) + self.assertIn("1 page(s), the template has 2", r.reason) + self.assertIn(blocker, r.reason) + self.assertIn("only first/last", r.reason) + # a blocker never rejects a file with the template's page count + same = make_pdf(self.p("same.pdf"), [(595, 842), (595, 842)]) + r = core.validate_against_template(dims, same, anchors=(), blocker=blocker) + self.assertEqual((r.ok, r.reason), (True, "")) + + def test_single_anchor_reason_unchanged(self): + dims = core.page_dimensions(self.tpl) + fewer = make_pdf(self.p("fewer.pdf"), [(595, 842)]) + odd_last = make_pdf(self.p("odd_last.pdf"), + [(595, 842), (595, 842), (200, 200)]) + accepted = "1 page(s), the template has 2 — signed on the last page" + rejected = ("3 page(s), the template has 2; last page 200.00×200.00 pt " + "≠ template 595.00×842.00 pt") + # historical keyword and its generalisation give the very same strings + for kwargs in ({"page_anchor": "last"}, {"anchors": ("last",)}): + r = core.validate_against_template(dims, fewer, **kwargs) + self.assertEqual((r.ok, r.reason), (True, accepted)) + r = core.validate_against_template(dims, odd_last, **kwargs) + self.assertEqual((r.ok, r.reason), (False, rejected)) + # no anchor at all: the bare count message, as before + r = core.validate_against_template(dims, fewer) + self.assertEqual((r.ok, r.reason), (False, "1 page(s), the template has 2")) + + def test_anchors_keyword_overrides_page_anchor(self): + dims = core.page_dimensions(self.tpl) + odd_last = make_pdf(self.p("odd_last.pdf"), + [(595, 842), (595, 842), (200, 200)]) + # page_anchor alone would accept ("first" matches) ... + self.assertTrue( + core.validate_against_template(dims, odd_last, page_anchor="first").ok) + # ... but anchors replaces it + r = core.validate_against_template(dims, odd_last, page_anchor="first", + anchors=("last",)) + self.assertFalse(r.ok) + self.assertIn("last page", r.reason) + # an EMPTY collection also replaces it: no anchored element at all + r = core.validate_against_template(dims, odd_last, page_anchor="first", anchors=()) + self.assertEqual((r.ok, r.reason), (False, "3 page(s), the template has 2")) + + def test_one_page_document_must_match_both_anchor_pages(self): + # its only page is the first AND the last one + one = make_pdf(self.p("one.pdf"), [(595, 842)]) + both = ("first", "last") + mixed = make_pdf(self.p("mixed.pdf"), [(595, 842), (300, 300)]) + r = core.validate_against_template(core.page_dimensions(mixed), one, anchors=both) + self.assertFalse(r.ok) + self.assertIn("last page", r.reason) + self.assertTrue(core.validate_against_template( + core.page_dimensions(mixed), one, anchors=("first",)).ok) + r = core.validate_against_template(core.page_dimensions(self.tpl), one, anchors=both) + self.assertTrue(r.ok, r.reason) + self.assertIn("first and last pages", r.reason) + class ImageInsertion(TmpCase): + @staticmethod + def insert(src, dst, png, **placement) -> bool: + """ONE image stamp through the image-mode path.""" + return core.apply_stamps_one( + src, dst, [Stamp(kind="image", image_path=png, **placement)]) + + @staticmethod + def size_pt(image, **kwargs) -> tuple[float, float]: + return stamplib.stamp_content(Stamp(kind="image", image_path=image, **kwargs))[1] + def test_insert_preserves_pages_and_writes_output(self): src = make_pdf(self.p("src.pdf"), [(400, 600), (400, 600)]) png = make_png(self.p("sig.png")) dst = self.p("out.pdf") - core.insert_image_one(src, dst, png, page_index=1, x=50, y=60) + self.insert(src, dst, png, page=2, x=50, y=60) self.assertTrue(dst.exists()) self.assertGreater(dst.stat().st_size, src.stat().st_size) # the page count must be unchanged @@ -140,15 +295,15 @@ def test_insert_preserves_pages_and_writes_output(self): def test_image_size_keeps_aspect(self): png = make_png(self.p("s.png"), size=(300, 150)) - w, h = core.image_size_pt(png) - self.assertEqual(w, core._IMG_TARGET_W_PT) - self.assertAlmostEqual(h, core._IMG_TARGET_W_PT * 0.5) + w, h = self.size_pt(png) + self.assertEqual(w, stamplib.DEFAULT_IMAGE_WIDTH_PT) + self.assertAlmostEqual(h, stamplib.DEFAULT_IMAGE_WIDTH_PT * 0.5) def test_page_out_of_range_clear_error(self): src = make_pdf(self.p("src.pdf"), [(400, 600), (400, 600)]) png = make_png(self.p("sig.png")) with self.assertRaises(ValueError) as cm: - core.insert_image_one(src, self.p("o.pdf"), png, page_index=5, x=10, y=10) + self.insert(src, self.p("o.pdf"), png, page=6, x=10, y=10) self.assertIn("out of range", str(cm.exception)) def test_inserted_image_has_no_black_border(self): @@ -158,7 +313,7 @@ def test_inserted_image_has_no_black_border(self): png = self.p("s.png") Image.new("RGB", (160, 80), (210, 210, 210)).save(png) dst = self.p("o.pdf") - core.insert_image_one(src, dst, png, page_index=0, x=60, y=160) + self.insert(src, dst, png, page=1, x=60, y=160) img = core.render_page_image(dst, 0, px_width=300) if img is None: self.skipTest("pdftoppm (poppler) unavailable") @@ -168,6 +323,32 @@ def test_inserted_image_has_no_black_border(self): if sum(px[xx, yy]) < 90) self.assertLess(black, 30, f"{black} (near-)black pixels -> border present") + def test_page_target_selects_the_stamped_page(self): + src = make_pdf(self.p("src.pdf"), [(400, 600)] * 3) + png = make_png(self.p("sig.png")) + for name, target, expected in (("last", {"page_anchor": "last"}, [0, 0, 1]), + ("first", {"page_anchor": "first"}, [1, 0, 0]), + ("2", {"page": 2}, [0, 1, 0])): + dst = self.p(f"out{name}.pdf") + self.assertIs(self.insert(src, dst, png, x=50.5, y=60, **target), False) + self.assertEqual(xobject_counts(dst), expected) + with self.assertRaises(ValueError) as cm: + self.insert(src, self.p("o.pdf"), png, page=4, x=10, y=10) + self.assertEqual(str(cm.exception), + "page 4 out of range (the document has 3 page(s))") + self.assertFalse(self.p("o.pdf").exists()) + + def test_image_size_follows_width_and_orientation(self): + png = make_png(self.p("s.png"), size=(300, 150)) + self.assertEqual(self.size_pt(png, width_pt=80), (80, 40.0)) + # EXIF orientation is applied first: the size is the one that gets stamped + jpg = self.p("rot.jpg") + exif = Image.Exif() + exif[0x0112] = 6 # rotate 90° to display + Image.new("RGB", (40, 20), (200, 0, 0)).save(jpg, exif=exif) + self.assertEqual(self.size_pt(jpg), (stamplib.DEFAULT_IMAGE_WIDTH_PT, + stamplib.DEFAULT_IMAGE_WIDTH_PT * 2)) + class BatchImageMode(TmpCase): """Shared CLI/GUI path: validation + image insertion end-to-end.""" @@ -214,6 +395,292 @@ def test_anchor_signs_count_mismatches_on_their_last_page(self): self.assertFalse((outdir / "long_bad_signe.pdf").exists()) +class EffectiveStamps(TmpCase): + """Pure helpers: the visual signatures of a run and what they require + from template validation.""" + + def _cfg(self, **kw): + kw.setdefault("inputs", [Path("x.pdf")]) + kw.setdefault("output", Path("out")) + return core.RunConfig(**kw) + + def test_legacy_image_becomes_one_stamp(self): + png = self.p("s.png") + cfg = self._cfg(mode="image", image_path=png, page=2, x=10, y=20) + self.assertEqual(core.effective_stamps(cfg), + [Stamp(kind="image", image_path=png, page=2, x=10, y=20)]) + # unspecified page / position: page 1, (0, 0) — as before + (s,) = core.effective_stamps(self._cfg(mode="image", image_path=png)) + self.assertEqual((s.page, s.page_anchor, s.all_pages, s.x, s.y), + (1, None, False, 0.0, 0.0)) + self.assertEqual(s.width_pt, stamplib.DEFAULT_IMAGE_WIDTH_PT) + # an anchor replaces the page number + (s,) = core.effective_stamps( + self._cfg(mode="image", image_path=png, page_anchor="last", x=5, y=6)) + self.assertEqual((s.page, s.page_anchor, s.x, s.y), (None, "last", 5, 6)) + self.assertTrue(s.is_placed) + + def test_legacy_image_then_cfg_stamps_in_order(self): + png = self.p("s.png") + extra = [text_stamp("A"), text_stamp("B", all_pages=True)] + cfg = self._cfg(mode="image", image_path=png, page=1, x=1, y=2, stamps=extra) + got = core.effective_stamps(cfg) + self.assertEqual([s.kind for s in got], ["image", "text", "text"]) + self.assertEqual(got[1:], extra) + self.assertEqual(cfg.stamps, extra) # cfg is not mutated + # without the legacy image: cfg.stamps alone (a copy, not the list itself) + cfg = self._cfg(mode="image", stamps=extra) + self.assertEqual(core.effective_stamps(cfg), extra) + self.assertIsNot(core.effective_stamps(cfg), cfg.stamps) + + def test_beid_ignores_image_path(self): + png = self.p("s.png") + for mode in ("beid", "azure"): + self.assertEqual( + core.effective_stamps(self._cfg(mode=mode, image_path=png, page=1, x=1, y=2)), + []) + extra = [text_stamp()] + self.assertEqual( + core.effective_stamps(self._cfg(mode=mode, image_path=png, stamps=extra)), + extra) + + def test_anchor_requirements_table(self): + png = self.p("s.png") + first = text_stamp(page_anchor="first") + last = text_stamp(page_anchor="last") + numbered = text_stamp(page=3) + every = text_stamp(all_pages=True) + rows = [ + ("all anchored", dict(mode="image", stamps=[last, first, last]), + (("first", "last"), None)), + ("legacy image anchored", dict(mode="image", image_path=png, page_anchor="last"), + (("last",), None)), + ("numbered stamp", dict(mode="image", stamps=[last, numbered]), + (("last",), "signature #2 targets page 3")), + ("legacy numbered image", dict(mode="image", image_path=png), + ((), "signature #1 targets page 1")), + ("all-pages stamp", dict(mode="image", stamps=[every, last]), + (("last",), "signature #1 targets every page")), + ("first blocker wins", dict(mode="image", stamps=[numbered, every]), + ((), "signature #1 targets page 3")), + ("no element", dict(mode="image"), ((), None)), + ("beid default vignette", dict(mode="beid"), + ((), "the vignette has no first/last page target")), + ("beid default vignette + anchored stamp", dict(mode="beid", stamps=[last]), + (("last",), "the vignette has no first/last page target")), + ("beid numbered vignette", dict(mode="beid", page=2, x=1, y=2), + ((), "the vignette targets page 2")), + ("beid placed vignette, default page", dict(mode="azure", x=1, y=2), + ((), "the vignette targets page 1")), + ("beid anchored default vignette", dict(mode="beid", page_anchor="first"), + (("first",), None)), + ("beid page_anchor + anchored stamps", + dict(mode="beid", page_anchor="last", x=1, y=2, stamps=[first, last]), + (("first", "last"), None)), + ("stamp blocker wins over the vignette", + dict(mode="azure", stamps=[every]), + ((), "signature #1 targets every page")), + ] + for label, kwargs, expected in rows: + with self.subTest(label): + self.assertEqual(core.anchor_requirements(self._cfg(**kwargs)), expected) + + +class BatchVisualStamps(TmpCase): + """Image mode = visual signatures only: text and image stamps through the + real process_batch (no card).""" + + def setUp(self): + super().setUp() + self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True) + self.out = self.p("out") + + def _cfg(self, inputs, stamp_list=(), **kw): + return core.RunConfig(inputs=list(inputs), output=self.out, mode="image", + stamps=list(stamp_list), **kw) + + def test_text_image_and_all_pages(self): + src = make_pdf(self.p("doc.pdf"), [(595, 842)] * 3) + png = make_png(self.p("sig.png")) + (res,) = core.process_batch(self._cfg([src], [ + text_stamp(page=1, x=360, y=120), + Stamp(kind="image", image_path=png, page_anchor="last", x=60, y=700), + text_stamp("JD", font="caveat", font_size=14, all_pages=True, x=540, y=20), + ])) + self.assertTrue(res.ok, res.detail) + self.assertEqual(res.output, self.out / "doc_signe.pdf") + self.assertEqual(xobject_counts(res.output), [2, 1, 2]) + self.assertEqual(xobject_counts(src), [0, 0, 0]) # the input is untouched + self.assertEqual(len(core.page_dimensions(res.output)), 3) + + def test_detail_wording(self): + src = make_pdf(self.p("doc.pdf"), [(595, 842)] * 2) + png = make_png(self.p("sig.png")) + (res,) = core.process_batch(core.RunConfig( + inputs=[src], output=self.out, mode="image", + image_path=png, page=1, x=360, y=150)) + self.assertEqual(res.detail, + "1 visual signature(s) applied — image page 1 @ (360, 150)") + (res,) = core.process_batch(self._cfg([src], [ + text_stamp(page=1, x=360, y=120), + text_stamp("JD", all_pages=True, x=540, y=20), + ])) + self.assertIn("2 visual signature(s) applied", res.detail) + self.assertEqual( + res.detail, + "2 visual signature(s) applied — text page 1 @ (360, 120); " + "text all pages @ (540, 20)") + + def test_count_mismatch_numbered_rejected_with_reason(self): + tpl = make_pdf(self.p("tpl.pdf"), [(595, 842), (595, 842)]) + short = make_pdf(self.p("short.pdf"), [(595, 842)]) + results = core.process_batch( + self._cfg([short, tpl], [text_stamp(page=1)], template=tpl)) + by_name = {r.path.name: r for r in results} + self.assertFalse(by_name["short.pdf"].ok) + self.assertEqual( + by_name["short.pdf"].detail, + "rejected — 1 page(s), the template has 2; signature #1 targets page 1 " + "(only first/last page targets accept a different page count)") + self.assertFalse((self.out / "short_signe.pdf").exists()) + self.assertTrue(by_name["tpl.pdf"].ok) # same page count: signed + + def test_count_mismatch_all_anchored_accepted(self): + tpl = make_pdf(self.p("tpl.pdf"), [(595, 842), (595, 842)]) + short = make_pdf(self.p("short.pdf"), [(595, 842)]) + long_bad = make_pdf(self.p("long_bad.pdf"), # first page differs + [(200, 200), (595, 842), (595, 842)]) + results = core.process_batch(self._cfg( + [short, long_bad], + [text_stamp(page_anchor="last"), text_stamp("JD", page_anchor="first", x=300)], + template=tpl)) + by_name = {r.path.name: r for r in results} + self.assertTrue(by_name["short.pdf"].ok, by_name["short.pdf"].detail) + self.assertIn("last page", by_name["short.pdf"].detail) + self.assertEqual(xobject_counts(self.out / "short_signe.pdf"), [2]) + self.assertFalse(by_name["long_bad.pdf"].ok) + self.assertIn("first page", by_name["long_bad.pdf"].detail) + self.assertFalse((self.out / "long_bad_signe.pdf").exists()) + + def test_all_pages_rejects_count_mismatch(self): + tpl = make_pdf(self.p("tpl.pdf"), [(595, 842), (595, 842)]) + longer = make_pdf(self.p("longer.pdf"), [(595, 842)] * 3) + (res,) = core.process_batch(self._cfg( + [longer], [text_stamp(page_anchor="last"), text_stamp(all_pages=True)], + template=tpl)) + self.assertFalse(res.ok) + self.assertIn("rejected", res.detail) + self.assertIn("signature #2 targets every page", res.detail) + self.assertFalse((self.out / "longer_signe.pdf").exists()) + # without a template there is nothing to reject: every page is stamped + (res,) = core.process_batch(self._cfg([longer], [text_stamp(all_pages=True)])) + self.assertTrue(res.ok, res.detail) + self.assertEqual(xobject_counts(res.output), [1, 1, 1]) + + def test_placeholders_resolved_per_document(self): + a = make_pdf(self.p("a.pdf"), [(595, 842)]) + b = make_pdf(self.p("b.pdf"), [(595, 842)]) + rendered = [] + real = stamplib.render_text_image + + def spy(text, *args, **kwargs): + rendered.append(text) + return real(text, *args, **kwargs) + + with mock.patch.object(stamplib, "render_text_image", spy): + results = core.process_batch( + self._cfg([a, b], [text_stamp("{filename} {date}"), + text_stamp("static", y=200)]), + today=datetime.date(2026, 10, 7)) + self.assertTrue(all(r.ok for r in results), [r.detail for r in results]) + self.assertEqual([t for t in rendered if t != "static"], + ["a 07/10/2026", "b 07/10/2026"]) + # static content is rendered ONCE for the whole batch + self.assertEqual(rendered.count("static"), 1) + # the run date is the injected one, whatever the day the suite runs + del rendered[:] + with mock.patch.object(stamplib, "render_text_image", spy): + core.process_batch(self._cfg([a], [text_stamp("{date}")]), + today=datetime.date(2001, 2, 3)) + self.assertEqual(rendered, ["03/02/2001"]) + + def test_unreadable_image_fails_document_not_batch(self): + a = make_pdf(self.p("a.pdf"), [(595, 842)]) + b = make_pdf(self.p("b.pdf"), [(595, 842)]) + fake = self.p("fake.png") + fake.write_text("not an image", encoding="utf-8") + seen = [] + # a readable stamp FIRST: nothing of it may reach an output either + results = core.process_batch( + self._cfg([a, b], [text_stamp(), + Stamp(kind="image", image_path=fake, page=1, x=10, y=10)]), + on_progress=seen.append) + self.assertEqual(len(results), 2) # the batch went on + self.assertEqual(seen, results) + for res in results: + self.assertFalse(res.ok) + self.assertIsNone(res.output) + self.assertTrue(res.detail.startswith("failed — cannot read image"), res.detail) + self.assertEqual(list(self.out.glob("*.pdf")), []) # no partial output + + def test_page_out_of_range_detail(self): + one = make_pdf(self.p("one.pdf"), [(595, 842)]) + three = make_pdf(self.p("three.pdf"), [(595, 842)] * 3) + results = core.process_batch(self._cfg([one, three], [text_stamp(page=3)])) + self.assertFalse(results[0].ok) + self.assertEqual(results[0].detail, + "failed — page 3 out of range (the document has 1 page(s))") + self.assertFalse((self.out / "one_signe.pdf").exists()) + self.assertTrue(results[1].ok, results[1].detail) # the next one is processed + self.assertEqual(xobject_counts(results[1].output), [0, 0, 1]) + + def test_never_overwrites(self): + src = make_pdf(self.p("doc.pdf"), [(595, 842)]) + cfg = self._cfg([src], [text_stamp()]) + (first,) = core.process_batch(cfg) + kept = first.output.read_bytes() + (second,) = core.process_batch(cfg) + self.assertEqual(first.output.name, "doc_signe.pdf") + self.assertEqual(second.output.name, "doc_signe - 1.pdf") + self.assertEqual(first.output.read_bytes(), kept) # intact + self.assertTrue(second.output.exists()) + + def test_image_mode_without_stamp_fails_document(self): + # programmatic misuse (validate_config was skipped): never a silent no-op + a = make_pdf(self.p("a.pdf"), [(595, 842)]) + b = make_pdf(self.p("b.pdf"), [(595, 842)]) + results = core.process_batch( + core.RunConfig(inputs=[a, b], output=self.out, mode="image")) + self.assertEqual([(r.ok, r.output, r.detail) for r in results], + [(False, None, "failed — no visual signature to apply")] * 2) + self.assertEqual(list(self.out.glob("*.pdf")), []) + + def test_blank_page_is_stamped(self): + from test_stamps import strip_page_contents # lazy: circular at import time + src = strip_page_contents(make_pdf(self.p("doc.pdf"), [(595, 842)] * 2), 1) + (res,) = core.process_batch(self._cfg([src], [text_stamp(all_pages=True)])) + self.assertTrue(res.ok, res.detail) + self.assertEqual(xobject_counts(res.output), [1, 1]) + + def test_malformed_form_is_still_stamped(self): + # /AcroForm that is not a dictionary: the "already signed?" probe cannot + # walk it. Image mode stamped such a file before and still does. + from pyhanko.pdf_utils import generic + from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter + plain = make_pdf(self.p("plain.pdf"), [(595, 842)]) + src = self.p("odd_form.pdf") + with plain.open("rb") as f: + writer = IncrementalPdfFileWriter(f, strict=False) + writer.root[generic.pdf_name("/AcroForm")] = generic.ArrayObject([]) + writer.update_root() + with src.open("wb") as out: + writer.write(out) + (res,) = core.process_batch(self._cfg([src], [text_stamp()])) + self.assertTrue(res.ok, res.detail) + self.assertNotIn("WARNING", res.detail) + self.assertEqual(xobject_counts(res.output), [1]) + + class BatchBeidWiring(TmpCase): """beid vignette placement wiring (no card: sign_one is mocked).""" @@ -275,6 +742,70 @@ def test_anchor_without_position_moves_default_vignette(self): self.assertIsNone(kw.get("pos")) self.assertIn("first page", results[0].detail) + def test_count_mismatch_needs_every_element_on_the_anchor(self): + # a file whose page count differs from the template is signed only + # when the vignette AND every visual signature target first/last + tpl = make_pdf(self.p("t.pdf"), [(595, 842), (595, 842)]) + short = make_pdf(self.p("short.pdf"), [(595, 842)]) + base = dict(inputs=[short], output=self.p("o"), mode="beid", template=tpl, + stamps=[text_stamp(page_anchor="last")]) + calls, results = self._run(core.RunConfig(page_anchor="last", **base)) + self.assertTrue(results[0].ok, results[0].detail) + ((_, kw),) = calls + self.assertEqual(kw.get("page_index"), -1) # the vignette on ITS last page + self.assertEqual(kw["stamps"], base["stamps"]) + calls, results = self._run(core.RunConfig(**base)) # default vignette: not anchored + self.assertFalse(results[0].ok) + self.assertIn("the vignette has no first/last page target", results[0].detail) + self.assertEqual(calls, []) # never signed + + def test_stamps_forwarded_to_sign_one(self): + srcs = [make_pdf(self.p(f"d{i}.pdf"), [(595, 842)]) for i in range(2)] + extra = [text_stamp("{filename}"), text_stamp("JD", all_pages=True)] + cfg = core.RunConfig(inputs=srcs, output=self.p("o"), mode="beid", stamps=extra) + calls, results = self._run(cfg) + self.assertTrue(all(r.ok for r in results)) + self.assertEqual(len(calls), 2) + for _, kw in calls: + self.assertEqual(kw["stamps"], core.effective_stamps(cfg)) + self.assertEqual(kw["stamps"], extra) + self.assertIsInstance(kw["stamp_date"], datetime.date) + self.assertIsInstance(kw["stamp_cache"], dict) + self.assertIsNone(kw.get("pos")) # the vignette is untouched + # ONE cache and ONE date for the whole batch + self.assertIs(calls[0][1]["stamp_cache"], calls[1][1]["stamp_cache"]) + self.assertEqual(calls[0][1]["stamp_date"], calls[1][1]["stamp_date"]) + + def test_detail_mentions_visual_signatures(self): + src = make_pdf(self.p("d.pdf"), [(595, 842), (595, 842)]) + extra = [text_stamp(), text_stamp("JD", all_pages=True)] + cfg = core.RunConfig(inputs=[src], output=self.p("o"), mode="beid", + page=2, x=100, y=50, stamps=extra) + _, results = self._run(cfg) + self.assertIn("+ 2 visual signature(s)", results[0].detail) + self.assertEqual( + results[0].detail, + "signed (eID) — vignette page 2 @ (100, 50) + 2 visual signature(s) " + "— PAdES-B-LTA, LTV ok") + # default vignette: the count follows the vignette phrase as well + cfg = core.RunConfig(inputs=[src], output=self.p("o"), mode="beid", + stamps=extra[:1]) + _, results = self._run(cfg) + self.assertEqual( + results[0].detail, + "signed (eID) — vignette + 1 visual signature(s) — PAdES-B-LTA, LTV ok") + + def test_no_stamps_detail_unchanged(self): + src = make_pdf(self.p("d.pdf"), [(595, 842)]) + png = make_png(self.p("s.png")) + # image_path is ignored in beid mode (as before): no stamp at all + cfg = core.RunConfig(inputs=[src], output=self.p("o"), mode="beid", + image_path=png) + calls, results = self._run(cfg) + self.assertEqual(results[0].detail, + "signed (eID) — vignette — PAdES-B-LTA, LTV ok") + self.assertEqual(calls[0][1]["stamps"], []) + class OutputNaming(TmpCase): def test_unique_output_path_increments(self): @@ -321,6 +852,25 @@ def test_anchor_page_index(self): self.assertEqual(core.anchor_page_index("first"), 0) self.assertEqual(core.anchor_page_index("last"), -1) + def test_default_vignette_rect(self): + # pure geometry behind the default box, relative to the page corner + self.assertEqual( + core.default_vignette_rect(595, 842), + (595 - core._STAMP_MARGIN - core._STAMP_W, core._STAMP_MARGIN, + core._STAMP_W, core._STAMP_H)) + # a page too small for the box: clamped inside it, 4 pt from the edges + x, y, w, h = core.default_vignette_rect(100, 30) + self.assertEqual((x, y), (4, core._STAMP_MARGIN)) + self.assertEqual((x + w, y + h), (100 - core._STAMP_MARGIN, 30 - 4)) + + def test_box_follows_mediabox_origin(self): + # non-zero MediaBox origin: the page-relative rect, shifted by the origin + with mock.patch.object(core, "page_mediabox", + lambda writer, page_index: [100.0, 200.0, 695.0, 1042.0]): + box = core._default_vignette_box(None, -1) + x, y, w, h = core.default_vignette_rect(595, 842) + self.assertEqual(box, (100 + x, 200 + y, 100 + x + w, 200 + y + h)) + class PageRender(TmpCase): def test_render_page_image(self): @@ -421,6 +971,78 @@ def test_page_anchor_config_rules(self): core.validate_config(core.RunConfig(inputs=[self.a], output=self.tmp, page_anchor="middle")) + def test_image_mode_requires_a_signature(self): + with self.assertRaises(ValueError) as cm: + core.validate_config(core.RunConfig(inputs=[self.a], output=self.tmp, + mode="image")) + self.assertIn("--signatures", str(cm.exception)) + self.assertIn("--text", str(cm.exception)) + # the historical checks of the legacy image keep their messages + with self.assertRaises(ValueError) as cm: + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode="image", + image_path=self.p("missing.png"))) + self.assertTrue(str(cm.exception).startswith("Image not found:")) + with self.assertRaises(ValueError) as cm: + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode="image", + image_path=make_png(self.p("s.png")), page=0)) + self.assertEqual(str(cm.exception), "--page must be >= 1.") + + def test_bad_stamp_reported_with_index(self): + good = text_stamp() + for bad, fragment in ( + (text_stamp(" "), "text is empty"), + (text_stamp(color="blue"), "bad color"), + (text_stamp(font="no-such-font"), "unknown font"), + (Stamp(kind="text", text="x", page=1), "x and y are required"), + (Stamp(kind="image", image_path=self.p("nope.png"), page=1, x=0, y=0), + "image not found"), + ): + with self.subTest(fragment): + with self.assertRaises(ValueError) as cm: + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode="image", stamps=[bad])) + self.assertTrue(str(cm.exception).startswith("Signature #1: "), + cm.exception) + self.assertIn(fragment, str(cm.exception)) + # the index is the position in effective_stamps (1-based) + with self.assertRaises(ValueError) as cm: + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode="image", + stamps=[good, text_stamp("")])) + self.assertEqual(str(cm.exception), "Signature #2: text is empty.") + with self.assertRaises(ValueError) as cm: # legacy image = #1, cfg.stamps follow + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode="image", + image_path=make_png(self.p("s.png")), stamps=[text_stamp("")])) + self.assertEqual(str(cm.exception), "Signature #2: text is empty.") + + def test_oversized_text_rejected_by_validate_config(self): + huge = text_stamp("W" * 300, font_size=400) + with self.assertRaises(ValueError) as cm: + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode="image", stamps=[huge])) + self.assertTrue( + str(cm.exception).startswith("Signature #1: text is too large to render"), + cm.exception) + + def test_beid_accepts_stamps(self): + for mode, extra in (("beid", {}), ("azure", {"azure_vault_url": "https://v.example"})): + # stamps are optional in the cryptographic modes ... + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode=mode, pades_level="b-b", **extra)) + # ... accepted when valid ... + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode=mode, pades_level="b-b", + stamps=[text_stamp(), text_stamp(all_pages=True)], **extra)) + # ... and validated like anywhere else + with self.assertRaises(ValueError) as cm: + core.validate_config(core.RunConfig( + inputs=[self.a], output=self.tmp, mode=mode, pades_level="b-b", + stamps=[text_stamp(x=None)], **extra)) + self.assertEqual(str(cm.exception), "Signature #1: x and y are required.") + class LevelMapping(unittest.TestCase): """Pure mapping pades_level -> PdfSignatureMetadata kwargs (R3-R6).""" @@ -567,6 +1189,216 @@ def test_tsa_url_precedence_flag_env_default(self): self.assertEqual(core.resolve_tsa_url(None), core.DEFAULT_TSA_URL) +class SignaturesCli(TmpCase): + """CLI flags of the visual signatures (--text…, --signatures) through the + real arg parser, and who owns --page/--x/--y.""" + + def setUp(self): + super().setUp() + self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True) + self.a = make_pdf(self.p("a.pdf"), [(595, 842)]) + self.png = make_png(self.p("sig.png")) + self.entries = [ + {"kind": "text", "text": "Jane Doe\nRead and approved, {date}", + "font": "great-vibes", "color": "#1A2B8C", "font_size": 24, + "page_anchor": "last", "x": 360, "y": 120}, + {"kind": "image", "image_path": "sig.png", "width_pt": 120, + "page": 1, "x": 60, "y": 700}, + ] + self.sigs = self.p("sigs.json") + self.sigs.write_text(json.dumps(self.entries), encoding="utf-8") + + def parse(self, *extra): + argv = ["--input", str(self.a), "--output", str(self.p("out")), *extra] + return core.resolve_config(core.build_arg_parser().parse_args(argv)) + + def assert_rejected(self, *extra) -> str: + with self.assertRaises(ValueError) as cm: + self.parse(*extra) + return str(cm.exception) + + def test_text_flags_build_one_text_stamp(self): + cfg = self.parse("--mode", "image", "--text", "Jane Doe", "--font", "caveat", + "--color", "#FF0000", "--font-size", "30", + "--page", "2", "--x", "10", "--y", "20.5") + self.assertEqual(cfg.stamps, [Stamp( + kind="text", text="Jane Doe", font="caveat", color="#FF0000", + font_size=30.0, page=2, x=10.0, y=20.5)]) + self.assertEqual(core.effective_stamps(cfg), cfg.stamps) + self.assertIsNone(cfg.image_path) + + def test_explicit_zero_font_size_rejected(self): + # "is not None", not "or": 0 must not silently become the default size + self.assertIn("font_size must be greater than 0", self.assert_rejected( + "--mode", "image", "--text", "JD", "--font-size", "0")) + + def test_text_defaults(self): + (s,) = self.parse("--mode", "image", "--text", "Jane Doe").stamps + self.assertEqual(s, Stamp( + kind="text", text="Jane Doe", font=stamplib.DEFAULT_FONT, + color=stamplib.DEFAULT_COLOR, font_size=24.0, page=1, x=0.0, y=0.0)) + + def test_text_newline_escape(self): + # the two characters backslash + n, as typed in any shell + (s,) = self.parse("--mode", "image", "--text", r"Jane Doe\nRead and approved").stamps + self.assertEqual(s.text, "Jane Doe\nRead and approved") + (s,) = self.parse("--mode", "image", "--text", "{date} {x} {}").stamps + self.assertEqual(s.text, "{date} {x} {}") # placeholders: not at parse time + + def test_text_with_page_last(self): + cfg = self.parse("--mode", "image", "--text", "JD", "--page", "last", + "--x", "5", "--y", "6") + (s,) = cfg.stamps + self.assertEqual((s.page, s.page_anchor, s.x, s.y), (None, "last", 5.0, 6.0)) + self.assertEqual((cfg.page, cfg.page_anchor), (None, "last")) + self.assertEqual(core.anchor_requirements(cfg), (("last",), None)) + + def test_font_without_text_rejected(self): + for flags in (("--font", "caveat"), ("--color", "#FF0000"), ("--font-size", "12")): + for mode in (("--mode", "image", "--image-path", str(self.png)), + ("--mode", "image", "--signatures", str(self.sigs)), + ("--mode", "beid", "--pades-level", "b-b")): + with self.subTest(flags=flags, mode=mode): + self.assertEqual(self.assert_rejected(*mode, *flags), + "--font, --color and --font-size need --text.") + + def test_text_with_image_path_rejected(self): + msg = self.assert_rejected("--mode", "image", "--text", "JD", + "--image-path", str(self.png)) + self.assertIn("mutually exclusive", msg) + self.assertIn("--signatures", msg) + + def test_text_in_beid_rejected(self): + for mode in (("--mode", "beid"), + ("--mode", "azure", "--azure-vault-url", "https://v.example")): + with self.subTest(mode=mode): + msg = self.assert_rejected(*mode, "--pades-level", "b-b", "--text", "JD") + self.assertIn("--text only applies to --mode image", msg) + self.assertIn("--signatures", msg) + + def test_signatures_file_loaded(self): + cfg = self.parse("--mode", "image", "--signatures", str(self.sigs)) + self.assertEqual(cfg.stamps, [ + Stamp(kind="text", text="Jane Doe\nRead and approved, {date}", + font="great-vibes", color="#1A2B8C", font_size=24.0, + page_anchor="last", x=360.0, y=120.0), + # relative image_path: against the directory of the JSON file + Stamp(kind="image", image_path=self.sigs.resolve().parent / "sig.png", + width_pt=120.0, page=1, x=60.0, y=700.0), + ]) + self.assertIsNone(cfg.image_path) + self.assertEqual((cfg.page, cfg.page_anchor, cfg.x, cfg.y), (None, None, None, None)) + # an empty list is not "a signature": image mode still needs one + empty = self.p("empty.json") + empty.write_text("[]", encoding="utf-8") + self.assertIn("at least one visual signature", + self.assert_rejected("--mode", "image", "--signatures", str(empty))) + + def test_signatures_plus_text_convenience_first(self): + cfg = self.parse("--mode", "image", "--signatures", str(self.sigs), + "--text", "JD", "--page", "2", "--x", "1", "--y", "2") + self.assertEqual([s.kind for s in cfg.stamps], ["text", "text", "image"]) + self.assertEqual((cfg.stamps[0].text, cfg.stamps[0].page, cfg.stamps[0].x, + cfg.stamps[0].y), ("JD", 2, 1.0, 2.0)) + # --page/--x/--y went to the convenience stamp only + self.assertEqual(cfg.stamps[1].page_anchor, "last") + self.assertEqual((cfg.stamps[2].page, cfg.stamps[2].x), (1, 60.0)) + + def test_signatures_plus_image_path_additive(self): + cfg = self.parse("--mode", "image", "--signatures", str(self.sigs), + "--image-path", str(self.png), "--page", "last", + "--x", "7", "--y", "8") + self.assertEqual(len(cfg.stamps), 2) # the file's entries + got = core.effective_stamps(cfg) + self.assertEqual([s.kind for s in got], ["image", "text", "image"]) + self.assertEqual((got[0].image_path, got[0].page_anchor, got[0].x, got[0].y, + got[0].width_pt), (self.png, "last", 7.0, 8.0, 150.0)) + self.assertEqual(got[1:], cfg.stamps) + + def test_page_xy_without_convenience_stamp_rejected(self): + for flags in (("--page", "2"), ("--page", "last"), ("--x", "5"), ("--y", "0"), + ("--page", "1", "--x", "5", "--y", "6")): + with self.subTest(flags=flags): + msg = self.assert_rejected("--mode", "image", "--signatures", + str(self.sigs), *flags) + self.assertIn("--page/--x/--y need --text or --image-path", msg) + # and with no signature at all the missing signature is what is reported + self.assertIn("at least one visual signature", + self.assert_rejected("--mode", "image", "--page", "2")) + + def test_legacy_image_invocation_fields_unchanged(self): + cfg = self.parse("--mode", "image", "--image-path", str(self.png), + "--page", "1", "--x", "360", "--y", "150") + self.assertEqual((cfg.mode, cfg.image_path, cfg.page, cfg.page_anchor, cfg.x, cfg.y), + ("image", self.png, 1, None, 360.0, 150.0)) + self.assertEqual(cfg.stamps, []) + self.assertEqual(core.effective_stamps(cfg), [Stamp( + kind="image", image_path=self.png, page=1, x=360.0, y=150.0)]) + self.assertEqual(core.describe_stamps(cfg), + ["image page 1 @ (360, 150) — sig.png"]) + + def test_beid_page_xy_stay_vignette_with_signatures(self): + for mode in (("--mode", "beid"), + ("--mode", "azure", "--azure-vault-url", "https://v.example")): + with self.subTest(mode=mode): + cfg = self.parse(*mode, "--pades-level", "b-b", "--signatures", + str(self.sigs), "--page", "2", "--x", "100", "--y", "50") + self.assertEqual((cfg.page, cfg.page_anchor, cfg.x, cfg.y), + (2, None, 100.0, 50.0)) + self.assertEqual(core.describe_placement(cfg), + "vignette page 2 @ (100, 50)") + # the file's entries, with their OWN placement + self.assertEqual(core.effective_stamps(cfg), cfg.stamps) + self.assertEqual([(s.kind, s.target_label()) for s in cfg.stamps], + [("text", "last page"), ("image", "page 1")]) + # --image-path stays ignored there (as before) + cfg = self.parse(*mode, "--pades-level", "b-b", + "--image-path", str(self.png)) + self.assertEqual(core.effective_stamps(cfg), []) + + def test_bad_signatures_file_is_value_error(self): + bad_json = self.p("bad.json") + bad_json.write_text("[{", encoding="utf-8") + not_a_list = self.p("obj.json") + not_a_list.write_text('{"kind": "text"}', encoding="utf-8") + bad_entry = self.p("entry.json") + bad_entry.write_text(json.dumps([self.entries[0], {"kind": "text", "text": ""}]), + encoding="utf-8") + for path, fragment in ((bad_json, "invalid JSON"), + (not_a_list, "expected a JSON list"), + (self.p("missing.json"), "cannot read signatures file"), + (bad_entry, "entry.json: signature #2: text is empty")): + for mode in (("--mode", "image"), ("--mode", "beid", "--pades-level", "b-b")): + with self.subTest(path=path.name, mode=mode): + with self.assertRaises(ValueError) as cm: # what main() turns into exit 2 + self.parse(*mode, "--signatures", str(path)) + self.assertIsInstance(cm.exception, StampError) + self.assertIn(fragment, str(cm.exception)) + + def test_profile_is_never_read(self): + # A GUI profile full of signatures in the user folder: a headless run + # must not pick any of it up (deterministic CLI). + import profile_store + cfg_dir, data_dir = self.p("cfg"), self.p("data") + store = profile_store.ProfileStore(config_dir=cfg_dir, data_dir=data_dir) + store.save(profile_store.Profile(signatures=[profile_store.Signature( + id=profile_store.new_id(), label="Jane", stamp=text_stamp(all_pages=True), + placed_on=(595.0, 842.0))])) + self.assertEqual(len(store.load().signatures), 1) # the profile is real + before = store.profile_path.read_bytes() + env = {profile_store.ENV_CONFIG_DIR: str(cfg_dir), + profile_store.ENV_DATA_DIR: str(data_dir)} + with mock.patch.dict(os.environ, env): + beid = self.parse("--pades-level", "b-b") + image = self.parse("--mode", "image", "--image-path", str(self.png)) + self.assertEqual(beid.stamps, []) + self.assertEqual(core.effective_stamps(beid), []) + self.assertEqual(image.stamps, []) + self.assertIn("at least one visual signature", + self.assert_rejected("--mode", "image")) + self.assertEqual(store.profile_path.read_bytes(), before) + + class SigningMaterialWiring(unittest.TestCase): """build_signing_material: timestamper/context per level (offline-safe).""" @@ -766,6 +1598,246 @@ def test_legacy_subfilter_rejected_as_non_pades(self): with self.assertRaises(core.SelfVerificationError): self._verify(dst, "b-b") + # --- visual signatures + cryptographic signature ------------------------- + # Real core.sign_one with the in-memory signer of this class: only the + # PKCS#11 hardware is replaced, the stamping + signing + validation path + # is the production one. + + def _sign_one(self, src, dst, *, field="Signature1", level="b-b", stamps=()) -> Path: + networked = level != "b-b" + core.sign_one(self.signer, src, dst, field, level, + core.CardIdentity("Jane Doe", None), + timestamper=self.timestamper if networked else None, + validation_context=self.signing_vc if networked else None, + stamps=stamps) + return dst + + def _statuses(self, pdf) -> list: + """pyHanko validation status of EVERY signature of `pdf`, in order + (verify_signed_pdf only looks at the last one).""" + from pyhanko.pdf_utils.reader import PdfFileReader + from pyhanko.sign.validation import validate_pdf_signature + from pyhanko_certvalidator import ValidationContext + + with Path(pdf).open("rb") as f: + reader = PdfFileReader(f, strict=False) + return [validate_pdf_signature( + emb, ValidationContext(trust_roots=[self.root])) + for emb in reader.embedded_regular_signatures] + + def assert_covers_whole_file(self, status): + from pyhanko.sign.validation.status import ( + ModificationLevel, SignatureCoverageLevel) + self.assertTrue(status.bottom_line, status.summary()) + self.assertEqual(status.coverage, SignatureCoverageLevel.ENTIRE_FILE) + self.assertEqual(status.modification_level, ModificationLevel.NONE) + + def _batch_beid(self, cfg): + """process_batch in beid mode with the card replaced by this class's + signer: ONLY the session, the signer factory and the identity read are + mocked — sign_one, the stamps and the verification are real.""" + with mock.patch.object(core, "open_eid_session", lambda *a, **k: object()), \ + mock.patch.object(core, "BEIDSigner", lambda session: self.signer), \ + mock.patch.object(core, "read_card_identity", + lambda session: core.CardIdentity("Jane Doe", None)): + return core.process_batch(cfg) + + def test_stamps_then_signature_validates_unmodified(self): + from test_stamps import pdf_pages # lazy: circular at import time + src = make_pdf(self.p("doc.pdf"), [(595, 842)] * 3) + png = make_png(self.p("sig.png")) + dst = self._sign_one(src, self.p("doc_signed.pdf"), stamps=[ + text_stamp("JD {date}", all_pages=True, x=540, y=20), + Stamp(kind="image", image_path=png, page=1, x=60, y=700), + ]) + self.assertEqual(core.verify_signed_pdf(dst, "b-b", trust_anchors=[self.root]), + "PAdES-B-B") + (status,) = self._statuses(dst) + self.assert_covers_whole_file(status) # the signature covers the stamps + self.assertEqual(xobject_counts(dst), [2, 1, 1]) + pages = pdf_pages(dst) + self.assertEqual(len(pages[-1]["/Annots"]), 1) # the vignette, last page only + self.assertNotIn("/Annots", pages[0]) + self.assertNotIn("/Annots", pages[1]) + + def test_stamps_then_b_lta(self): + src = make_pdf(self.p("doc.pdf"), [(595, 842)] * 2) + dst = self._sign_one(src, self.p("doc_signed.pdf"), level="b-lta", stamps=[ + text_stamp(all_pages=True), text_stamp("JD", page_anchor="last", y=200)]) + self.assertEqual(self._verify(dst, "b-lta"), "PAdES-B-LTA, LTV ok") + self.assertEqual(xobject_counts(dst), [1, 2]) + + def test_stamp_after_signature_is_flagged(self): + # Negative control: a stamp added AFTER the signature is an + # illegal modification — which is why sign_one stamps first. + signed = self._sign_one(make_pdf(self.p("doc.pdf"), [(595, 842)]), + self.p("signed.pdf")) + self.assertEqual(core.verify_signed_pdf(signed, "b-b", trust_anchors=[self.root]), + "PAdES-B-B") + out = self.p("restamped.pdf") + self.assertIs(core.apply_stamps_one(signed, out, [text_stamp()]), True) + self.assertTrue(out.exists()) + # (pyHanko logs the offending objects of its diff analysis: captured here) + with self.assertLogs("pyhanko", level="WARNING"), \ + self.assertRaises(core.SelfVerificationError): + core.verify_signed_pdf(out, "b-b", trust_anchors=[self.root]) + # an unsigned input is not reported as signed + plain = make_pdf(self.p("plain.pdf"), [(595, 842)]) + self.assertIs(core.apply_stamps_one(plain, self.p("plain_out.pdf"), [text_stamp()]), + False) + + def test_existing_signature_count(self): + from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter + + def count(pdf) -> int: + with Path(pdf).open("rb") as f: + return core.existing_signature_count( + IncrementalPdfFileWriter(f, strict=False)) + + plain = make_pdf(self.p("plain.pdf"), [(595, 842)]) + self.assertEqual(count(plain), 0) + self.assertEqual(count(self._sign_one(plain, self.p("bb.pdf"))), 1) + # b-lta = the signature + its archival document timestamp + self.assertEqual(count(self._sign_one(plain, self.p("lta.pdf"), level="b-lta")), 2) + + def test_stamps_on_already_signed_input_refused(self): + first = self._sign_one(make_pdf(self.p("doc.pdf"), [(595, 842)]), + self.p("first.pdf"), field="Other1") + dst = self.p("second.pdf") + signer = mock.Mock() # must never be asked to sign + with self.assertRaises(StampError) as cm: + core.sign_one(signer, first, dst, "Signature1", "b-b", + core.CardIdentity("Jane Doe", None), stamps=[text_stamp()]) + self.assertIn("already signed", str(cm.exception)) + self.assertEqual(signer.mock_calls, []) + self.assertFalse(dst.exists()) + # the same holds for an input that only carries a document timestamp chain + lta = self._sign_one(make_pdf(self.p("doc2.pdf"), [(595, 842)]), + self.p("lta.pdf"), field="Other1", level="b-lta") + with self.assertRaises(StampError): + self._sign_one(lta, dst, stamps=[text_stamp()]) + self.assertFalse(dst.exists()) + (status,) = self._statuses(first) # the input is intact + self.assert_covers_whole_file(status) + + def test_countersign_without_stamps_keeps_first_signature_valid(self): + from pyhanko.sign.validation.status import ModificationLevel + first = self._sign_one(make_pdf(self.p("doc.pdf"), [(595, 842)]), + self.p("first.pdf"), field="Other1") + both = self._sign_one(first, self.p("both.pdf"), stamps=()) + earlier, ours = self._statuses(both) + self.assertTrue(earlier.bottom_line, earlier.summary()) + self.assertEqual(earlier.modification_level, ModificationLevel.FORM_FILLING) + self.assert_covers_whole_file(ours) + + def test_image_mode_on_signed_input_warns(self): + signed = self._sign_one(make_pdf(self.p("doc.pdf"), [(595, 842)]), + self.p("signed.pdf")) + plain = make_pdf(self.p("plain.pdf"), [(595, 842)]) + out = self.p("out") + results = core.process_batch(core.RunConfig( + inputs=[signed, plain], output=out, mode="image", stamps=[text_stamp()])) + by_name = {r.path.name: r for r in results} + # historical outcome kept: the output is written, the document is "ok" + self.assertTrue(by_name["signed.pdf"].ok) + self.assertTrue((out / "signed_signe.pdf").exists()) + self.assertIn("WARNING: the document was already signed", + by_name["signed.pdf"].detail) + self.assertTrue(by_name["signed.pdf"].detail.startswith( + "1 visual signature(s) applied — text page 1 @ (50, 50) — WARNING")) + self.assertTrue(by_name["plain.pdf"].ok) + self.assertNotIn("WARNING", by_name["plain.pdf"].detail) + + def test_batch_beid_refuses_stamps_on_signed_input(self): + signed = self._sign_one(make_pdf(self.p("doc.pdf"), [(595, 842)]), + self.p("signed.pdf"), field="Other1") + plain = make_pdf(self.p("plain.pdf"), [(595, 842)]) + out = self.p("out") + results = self._batch_beid(core.RunConfig( + inputs=[signed, plain], output=out, mode="beid", pades_level="b-b", + stamps=[text_stamp()])) + by_name = {r.path.name: r for r in results} + refused = by_name["signed.pdf"] + self.assertFalse(refused.ok) + self.assertIsNone(refused.output) + self.assertTrue( + refused.detail.startswith("failed — the document is already signed"), + refused.detail) + self.assertFalse((out / "signed_signe.pdf").exists()) + # the batch went on: the unsigned input is stamped and signed + self.assertTrue(by_name["plain.pdf"].ok, by_name["plain.pdf"].detail) + (status,) = self._statuses(out / "plain_signe.pdf") + self.assert_covers_whole_file(status) + # without stamps the very same input is countersigned, as before + (res,) = self._batch_beid(core.RunConfig( + inputs=[signed], output=out, mode="beid", pades_level="b-b")) + self.assertTrue(res.ok, res.detail) + self.assertEqual(len(self._statuses(res.output)), 2) + + def test_blank_page_stamped_then_signed(self): + from test_stamps import strip_page_contents # lazy: circular at import time + src = strip_page_contents(make_pdf(self.p("doc.pdf"), [(595, 842)] * 2), 1) + dst = self._sign_one(src, self.p("doc_signed.pdf"), + stamps=[text_stamp(all_pages=True)]) + (status,) = self._statuses(dst) + self.assert_covers_whole_file(status) + self.assertEqual(xobject_counts(dst), [1, 1]) + + def test_process_batch_beid_with_stamps_real_signature(self): + src = make_pdf(self.p("doc.pdf"), [(595, 842)] * 2) + png = make_png(self.p("sig.png")) + out = self.p("out") + (res,) = self._batch_beid(core.RunConfig( + inputs=[src], output=out, mode="beid", pades_level="b-b", + page=2, x=100, y=50, + stamps=[text_stamp("{filename}", all_pages=True, x=540, y=20), + Stamp(kind="image", image_path=png, page_anchor="first", x=60, y=700)])) + self.assertTrue(res.ok, res.detail) + self.assertEqual( + res.detail, + "signed (eID) — vignette page 2 @ (100, 50) + 2 visual signature(s) — PAdES-B-B") + self.assertEqual(res.output, out / "doc_signe.pdf") + self.assertEqual(core.verify_signed_pdf(res.output, "b-b", trust_anchors=[self.root]), + "PAdES-B-B") + (status,) = self._statuses(res.output) + self.assert_covers_whole_file(status) + self.assertEqual(xobject_counts(res.output), [2, 1]) + + def test_failing_stamp_leaves_no_signed_output(self): + one = make_pdf(self.p("one.pdf"), [(595, 842)]) + out = self.p("out") + signer = mock.Mock() # must never be asked to sign + with mock.patch.object(core, "open_eid_session", lambda *a, **k: object()), \ + mock.patch.object(core, "BEIDSigner", lambda session: signer), \ + mock.patch.object(core, "read_card_identity", + lambda session: core.CardIdentity("Jane Doe", None)): + (res,) = core.process_batch(core.RunConfig( + inputs=[one], output=out, mode="beid", pades_level="b-b", + stamps=[text_stamp(), text_stamp(page=9)])) + self.assertFalse(res.ok) + self.assertIsNone(res.output) + self.assertEqual(res.detail, + "failed — page 9 out of range (the document has 1 page(s))") + self.assertEqual(signer.mock_calls, []) + self.assertEqual(list(out.glob("*")), []) # no _signe.pdf, nothing partial + + def test_sign_one_resolves_placeholders(self): + # {filename} is the source STEM, {date} the run date handed to sign_one + src = make_pdf(self.p("contract.pdf"), [(595, 842)]) + rendered = [] + real = stamplib.render_text_image + + def spy(text, *args, **kwargs): + rendered.append(text) + return real(text, *args, **kwargs) + + with mock.patch.object(stamplib, "render_text_image", spy): + core.sign_one(self.signer, src, self.p("out.pdf"), "Signature1", "b-b", + core.CardIdentity("Jane Doe", None), + stamps=[text_stamp("{filename} {date}")], + stamp_date=datetime.date(2001, 2, 3)) + self.assertEqual(rendered, ["contract 03/02/2001"]) + class SummaryOutput(unittest.TestCase): def _capture(self, **kw): @@ -784,6 +1856,165 @@ def test_no_rrn_note_otherwise(self): self.assertNotIn("national register number", self._capture()) +class CliEndToEnd(TmpCase): + """The real CLI in a subprocess: visual signatures end to end (image + mode: no card, no network), exit codes included.""" + + def setUp(self): + super().setUp() + self.addCleanup(shutil.rmtree, self.tmp, ignore_errors=True) + self.doc = make_pdf(self.p("doc.pdf"), [(595, 842)] * 2) + self.png = make_png(self.p("sig.png")) + self.out = self.p("out") + + def run_cli(self, *argv, encoding="utf-8"): + # The CLI never reads the GUI profile; the directories are pinned to + # temp ones anyway so that nothing can reach the real user folder. + env = dict(os.environ, PYTHONIOENCODING=encoding, + CACHET_CONFIG_DIR=str(self.p("cfg")), + CACHET_DATA_DIR=str(self.p("data"))) + proc = subprocess.run( + [sys.executable, "sign_pdfs_beid.py", *argv], + capture_output=True, text=True, encoding=encoding, env=env, + cwd=str(Path(__file__).parent), timeout=120) + self.assertFalse(self.p("cfg").exists()) # no profile was created + self.assertFalse(self.p("data").exists()) + return proc + + def test_text_mode_exit_0_and_output(self): + proc = self.run_cli( + "--mode", "image", "--input", str(self.doc), "--output", str(self.out), + "--text", r"Jane Doe\nSigned on {date}", "--font", "caveat", + "--color", "#0A6B3C", "--font-size", "18", + "--page", "last", "--x", "360", "--y", "120") + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + self.assertEqual(xobject_counts(self.out / "doc_signe.pdf"), [0, 1]) + self.assertIn("Mode: visual signatures — 1 element(s):", proc.stdout) + self.assertIn(' 1. text last page @ (360, 120) — "Jane Doe"', proc.stdout) + self.assertIn("1 visual signature(s) applied — text last page @ (360, 120)", + proc.stdout) + self.assertIn("1/1 document(s) processed successfully", proc.stdout) + + def test_text_outside_the_stdout_encoding(self): + # redirected output on Windows is the ANSI code page, strict: a name + # it cannot encode must not kill the run before any document + proc = self.run_cli( + "--mode", "image", "--input", str(self.doc), "--output", str(self.out), + "--text", "Ayşe Yılmaz", "--font", "lato", encoding="cp1252") + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + self.assertEqual(xobject_counts(self.out / "doc_signe.pdf"), [1, 0]) + self.assertIn(r'"Ay\u015fe Y\u0131lmaz"', proc.stdout) # escaped, not fatal + self.assertIn("1/1 document(s) processed successfully", proc.stdout) + + def test_signatures_file_exit_0(self): + sigs = self.p("sigs.json") + sigs.write_text(json.dumps([ + {"kind": "text", "text": "JD", "font": "caveat", "font_size": 14, + "all_pages": True, "x": 540, "y": 20}, + {"kind": "image", "image_path": "sig.png", "width_pt": 120, + "page": 1, "x": 60, "y": 700}, + {"kind": "text", "text": "skipped", "enabled": False, + "page": 1, "x": 0, "y": 0}, + ]), encoding="utf-8") + proc = self.run_cli( + "--mode", "image", "--input", str(self.doc), "--output", str(self.out), + "--signatures", str(sigs)) + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + self.assertEqual(xobject_counts(self.out / "doc_signe.pdf"), [2, 1]) + self.assertIn("Mode: visual signatures — 2 element(s):", proc.stdout) + self.assertIn("2 visual signature(s) applied", proc.stdout) + + def test_legacy_image_invocation_exit_0(self): + # the invocation documented since 1.x, template validation included + other = make_pdf(self.p("other.pdf"), [(595, 842)] * 2) + proc = self.run_cli( + "--mode", "image", "--template", str(self.doc), + "--input", str(self.doc), str(other), "--output", str(self.out), + "--image-path", str(self.png), "--page", "1", "--x", "360", "--y", "150") + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + for name in ("doc_signe.pdf", "other_signe.pdf"): + self.assertEqual(xobject_counts(self.out / name), [1, 0]) + self.assertIn("1 visual signature(s) applied — image page 1 @ (360, 150)", + proc.stdout) + self.assertIn("2/2 document(s) processed successfully", proc.stdout) + + def test_bad_signatures_file_exit_2(self): + sigs = self.p("sigs.json") + sigs.write_text(json.dumps([ + {"kind": "text", "text": "ok", "page": 1, "x": 0, "y": 0}, + {"kind": "text", "text": "no position", "page": 1}, + ]), encoding="utf-8") + proc = self.run_cli( + "--mode", "image", "--input", str(self.doc), "--output", str(self.out), + "--signatures", str(sigs)) + self.assertEqual(proc.returncode, 2, proc.stdout + proc.stderr) # argparse error + self.assertIn("error: sigs.json: signature #2: x and y are required", proc.stderr) + self.assertNotIn("Traceback", proc.stderr) + self.assertFalse(self.out.exists()) # nothing was started + + def test_rejected_document_exit_2(self): + short = make_pdf(self.p("short.pdf"), [(595, 842)]) + proc = self.run_cli( + "--mode", "image", "--template", str(self.doc), + "--input", str(self.doc), str(short), "--output", str(self.out), + "--text", "JD", "--page", "1", "--x", "10", "--y", "10") + self.assertEqual(proc.returncode, 2, proc.stdout + proc.stderr) + self.assertIn("rejected — 1 page(s), the template has 2; signature #1 targets " + "page 1 (only first/last page targets accept a different page count)", + proc.stdout) + self.assertTrue((self.out / "doc_signe.pdf").exists()) # the valid one is done + self.assertFalse((self.out / "short_signe.pdf").exists()) + self.assertIn("1/2 document(s) processed successfully", proc.stdout) + + def test_template_note_only_when_every_element_is_anchored(self): + longer = make_pdf(self.p("longer.pdf"), [(595, 842)] * 3) + common = ("--mode", "image", "--template", str(self.doc), + "--input", str(longer), "--output", str(self.out)) + last = {"kind": "text", "text": "JD", "page_anchor": "last", "x": 10, "y": 10} + first = dict(last, page_anchor="first") + numbered = {"kind": "text", "text": "JD", "page": 1, "x": 10, "y": 10} + + def run_with(*entries): + sigs = self.p("sigs.json") + sigs.write_text(json.dumps(list(entries)), encoding="utf-8") + return self.run_cli(*common, "--signatures", str(sigs)) + + proc = self.run_cli(*common, "--text", "JD", "--page", "last", + "--x", "10", "--y", "10") + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + self.assertIn("accepted and signed on their last page.", proc.stdout) + self.assertEqual(xobject_counts(self.out / "longer_signe.pdf"), [0, 0, 1]) + proc = run_with(last, first) + self.assertEqual(proc.returncode, 0, proc.stdout + proc.stderr) + self.assertIn("accepted and signed on their first and last pages.", proc.stdout) + self.assertEqual(xobject_counts(self.out / "longer_signe - 1.pdf"), [1, 0, 1]) + # ONE numbered target blocks page-count mismatches: no such promise + proc = run_with(last, numbered) + self.assertEqual(proc.returncode, 2, proc.stdout + proc.stderr) + self.assertNotIn("accepted and signed", proc.stdout) + self.assertIn("signature #2 targets page 1", proc.stdout) + + def test_beid_banner_lists_visual_signatures(self): + # No card is faked: the run stops at the PKCS#11 library load (a dummy + # file), AFTER the banner that announces what would be applied. + sigs = self.p("sigs.json") + sigs.write_text(json.dumps([ + {"kind": "text", "text": "JD", "all_pages": True, "x": 540, "y": 20}, + ]), encoding="utf-8") + lib = self.p("dummy.so") + lib.write_bytes(b"") + proc = self.run_cli( + "--mode", "beid", "--pades-level", "b-b", "--lib", str(lib), + "--input", str(self.doc), "--output", str(self.out), + "--signatures", str(sigs)) + self.assertEqual(proc.returncode, 1, proc.stdout + proc.stderr) + self.assertIn("Cannot load the PKCS#11 library", proc.stderr) + self.assertIn("Mode: eID — vignette bottom-right, last page " + "+ 1 visual signature(s). PKCS#11 lib:", proc.stdout) + self.assertIn(' 1. text all pages @ (540, 20) — "JD"', proc.stdout) + self.assertFalse(self.out.exists()) # nothing was signed + + class _GuiTestBase(unittest.TestCase): """Shared display-guarded setup for the wizard tests.""" @@ -794,16 +2025,37 @@ def setUp(self): tkinter.Tk().destroy() # detects the absence of a display import gui # noqa: F401 - requires customtkinter+tk except Exception as exc: # noqa: BLE001 + # A run that is SUPPOSED to exercise the GUI must not turn a + # broken gui.py or a missing display into a green "all skipped". + if os.environ.get("CACHET_REQUIRE_GUI") == "1": + self.fail("GUI tests are required (CACHET_REQUIRE_GUI=1) but " + f"unavailable: {exc!r}") self.skipTest(f"tkinter/GUI unavailable: {exc}") + # Cyclic GC stays off while a GUI test runs. Step widgets are rebuilt + # constantly, which leaves CTkFont objects in reference cycles; when + # the collector happens to run in the batch WORKER thread, each + # Font.__del__ is a Tk call from a non-main thread that waits a full + # second for a mainloop these tests never enter (they pump update()), + # and the batch then outlives the test's wait loop. Which thread + # collects depends on allocation counts, i.e. on unrelated code. + gc.disable() + self.addCleanup(gc.enable) self.tmp = Path(tempfile.mkdtemp()) + # The GUI loads and auto-saves a user profile: each test gets its own + # (never the real one), so tests stay independent of each other. + env = mock.patch.dict(os.environ, { + "CACHET_CONFIG_DIR": str(self.tmp / "cfg"), + "CACHET_DATA_DIR": str(self.tmp / "data")}) + env.start() + self.addCleanup(env.stop) self.types = types - def make_app(self): + def make_app(self, store=None): import contextlib import tkinter import gui - app = gui.CachetApp(self.types.SimpleNamespace(lib=None)) + app = gui.CachetApp(self.types.SimpleNamespace(lib=None), store=store) app.update() def _cleanup(): @@ -844,7 +2096,7 @@ def test_launch_populates_report_and_writes_output(self): self.wizard_with_state(app, tpl, out) self.assertEqual(len(app.valid_paths), 1) app.mode_var.set("image") - app.image_path = png + app._add_image_signature(png) # before step 6 is built; it is selected app._goto_step(5) # placement step builds the canvas app._draw_page() app.update() @@ -894,33 +2146,36 @@ def boom(*a, **k): class GuiBeidPlacement(_GuiTestBase): - """Placement step in beid mode: 3:1 placeholder (1/5 page), no image - picker, click → target-page sync, canvas that follows the window.""" + """Placement step in beid mode: the vignette heads the element list, a + 3:1 box (1/5 page); click → target-page sync, canvas that follows the + window.""" def test_beid_placeholder_and_resize(self): + import gui tpl = make_pdf(self.tmp / "t.pdf", [(600, 800), (600, 800)]) app = self.make_app() - app.geometry("900x950") + app.geometry("1500x950") app.update() self.wizard_with_state(app, tpl, self.tmp) app.mode_var.set("beid") app._goto_step(5) # placement step app.update() - # beid mode: no image picker (row not handled by a manager) - self.assertEqual(app.image_row.winfo_manager(), "") + # beid mode: the vignette is the first element of the list + self.assertIn(gui.VIGNETTE_ID, app._element_rows) # placeholder = 3:1 vignette, width = page/5 - iw, ih = app._placeholder_size_pt() + iw, ih = app._element_size_pt(gui.VIGNETTE_ID) self.assertAlmostEqual(iw, 600 / 5) self.assertAlmostEqual(iw / ih, 3.0) # a click sets the position (in beid mode too, not just image) and # syncs the manual target-page field fw, fh, ox, oy = app._frame_geom app._on_canvas_click(self.types.SimpleNamespace(x=ox + fw * 0.5, y=oy + fh * 0.5)) - self.assertIsNotNone(app.place_x) + self.assertIsNotNone(app.profile.settings.vignette.x) self.assertEqual(app.page_text, "1") big = app.canvas.winfo_reqwidth() # shrink the window -> the canvas shrinks, proportions preserved - app.geometry("520x680") + # (both sizes are above the width where the canvas hits its floor) + app.geometry("1000x680") app.update() small = app.canvas.winfo_reqwidth() app.destroy() @@ -1042,7 +2297,7 @@ def test_selector_locks_page_and_signs_short_file(self): self.assertEqual(app.cur_page, 0) # end-to-end in image mode: the 1-page file gets signed on page 1 app.mode_var.set("image") - app.image_path = png + app._add_image_signature(png) app._goto_step(5) # placement step, locked app.update() self.assertEqual(app.cur_page, 0) @@ -1330,10 +2585,11 @@ def test_card_box_only_in_beid_mode(self): app._goto_step(6) app.update() self.assertTrue(app.card_box.winfo_manager()) - # image mode: step 6 needs an image + a position to be complete + # image mode: step 6 needs a placed visual signature to be complete app.mode_var.set("image") - app.image_path = make_png(self.tmp / "s.png") - app.place_page, app.place_x, app.place_y = 1, 10.0, 10.0 + sig = app._add_image_signature(make_png(self.tmp / "s.png")) + sig.stamp = dataclasses.replace(sig.stamp, page=1, x=10.0, y=10.0) + sig.placed_on = app.template_dims[0] app._goto_step(6) app.update() self.assertEqual(app.step_index, 6) @@ -1467,6 +2723,1461 @@ def test_logo_loads_and_degrades_gracefully(self): gui._logo_pil = orig_cache +class _GuiEditorBase(_GuiTestBase): + """Shared fixtures of the step-6 editor and persistence tests: a 2-page + template, an app parked on the placement step, synthetic clicks. Native + pickers are always patched and dialogs are driven through their handlers + — nothing here blocks.""" + + def setUp(self): + super().setUp() + import gui + import i18n + self.gui, self.i18n, self.tr = gui, i18n, i18n.tr + self.addCleanup(i18n.set_language, "en") + self.tpl = make_pdf(self.tmp / "t.pdf", [(595, 842), (595, 842)]) + self.out = self.tmp / "out" + + def app_at_place(self, mode="image", inputs=None): + """A fresh app on the placement step (step 6) in `mode`.""" + app = self.make_app() + self.wizard_with_state(app, self.tpl, self.out, inputs=inputs) + app.mode_var.set(mode) + app._goto_step(5) + app.update() + self.assertEqual(app.step_index, 5) + return app + + def pump(self, app, until=lambda: False, rounds=120): + """Pump the Tk loop (these tests never enter mainloop) until + `until()` holds, for at most ~rounds × 50 ms.""" + import time + for _ in range(rounds): + app.update() + time.sleep(0.05) + if until(): + break + app.update() + + def click(self, app, fx=0.5, fy=0.5): + """Click on the page preview, at a fraction of the page frame.""" + fw, fh, ox, oy = app._frame_geom + app._on_canvas_click(self.types.SimpleNamespace(x=ox + fw * fx, y=oy + fh * fy)) + app.update() + + def add_text(self, app, text="Jane", label=None, **stamp_kw): + """An (unplaced) text signature straight into the library.""" + return app._add_signature(Stamp(kind="text", text=text, **stamp_kw), + label or text) + + @staticmethod + def fill(entry, value): + entry.delete(0, "end") + entry.insert(0, value) + + @staticmethod + def type_text(app, text): + """Replace the text of the text dialog, as typing does (each key + release refreshes the preview).""" + app.dlg_text_box.delete("1.0", "end") + app.dlg_text_box.insert("1.0", text) + app._on_text_dialog_edit() + + def draw(self, app, *strokes): + """Freehand strokes on the draw dialog, through its mouse handlers.""" + event = self.types.SimpleNamespace + for points in strokes: + x, y = points[0] + app._draw_start(event(x=x, y=y)) + for x, y in points[1:]: + app._draw_move(event(x=x, y=y)) + + @staticmethod + def items(app, element_id, kind=None): + """Canvas items of one element (optionally of one canvas type).""" + return [i for i in app.canvas.find_withtag(f"el:{element_id}") + if kind is None or app.canvas.type(i) == kind] + + @staticmethod + def saved(app) -> dict: + """The profile as it is on disk right now ({} if never saved).""" + path = app.store.profile_path + return json.loads(path.read_text(encoding="utf-8")) if path.exists() else {} + + @staticmethod + def modal_button(app, text): + """A button of the open confirmation modal (its last child row).""" + import customtkinter as ctk + top = [w for w in app.winfo_children() if isinstance(w, ctk.CTkToplevel)][-1] + return next(b for b in top.winfo_children()[-1].winfo_children() + if isinstance(b, ctk.CTkButton) and b.cget("text") == text) + + def launch_capturing_config(self, app) -> core.RunConfig: + """Start the batch from the signing step with `process_batch` + replaced: returns the RunConfig the GUI built.""" + seen = [] + with mock.patch.object(core, "process_batch", + side_effect=lambda cfg, **_k: seen.append(cfg) or []): + app._launch() + self.pump(app, lambda: not app._running, rounds=60) + (cfg,) = seen + return cfg + + +class GuiSignatureEditor(_GuiEditorBase): + """Step 6 as a multi-element editor: the element list (vignette + the + library of visual signatures), the three dialogs (text, drawing, image), + click-to-place of the SELECTED element, the to-scale preview of every + element, the step predicates, the anchor lock and the launched config.""" + + def test_vignette_row_only_in_crypto_modes(self): + app = self.app_at_place("beid") + self.assertIn(self.gui.VIGNETTE_ID, app._element_rows) + self.assertEqual(app.selected_id, self.gui.VIGNETTE_ID) + app.mode_var.set("image") + app._goto_step(5) + self.assertNotIn(self.gui.VIGNETTE_ID, app._element_rows) + self.assertIsNone(app.selected_id) # empty library: nothing to select + app.mode_var.set("azure") + app.azure_anchors_path = self.tpl # completes step 5 in azure mode + app._goto_step(5) + self.assertIn(self.gui.VIGNETTE_ID, app._element_rows) + + # ---------------------------------------------------------- text dialog + def test_add_text_dialog_creates_selected_signature(self): + app = self.app_at_place() + app.add_text_btn.invoke() + app.update() + dialog = app._dialog + self.assertTrue(dialog.winfo_exists()) + self.assertEqual(dialog.title(), self.tr("sig.text_title_add")) + self.type_text(app, "Jane Doe\nRead and approved") + app.dlg_save_btn.invoke() + app.update() + (sig,) = app.profile.signatures + # default font, colour and size; not placed yet + self.assertEqual(sig.stamp, Stamp(kind="text", text="Jane Doe\nRead and approved")) + self.assertEqual(sig.label, "Jane Doe") # first line of the text + self.assertEqual(app.selected_id, sig.id) + self.assertIn(sig.id, app._element_rows) + self.assertIsNone(app._dialog) + self.assertFalse(dialog.winfo_exists()) + self.assertEqual([s["text"] for s in self.saved(app)["signatures"]], + ["Jane Doe\nRead and approved"]) + self.assertEqual(app._place_error(), self.tr("place.unplaced", name="Jane Doe")) + # a second one, with an explicit name + app._open_text_dialog() + self.fill(app.dlg_name_entry, " Initials ") + self.type_text(app, "JD") + app._apply_text_dialog() + self.assertEqual([s.label for s in app.profile.signatures], + ["Jane Doe", "Initials"]) + self.assertEqual(len(self.saved(app)["signatures"]), 2) + + def test_text_dialog_validation_errors(self): + app = self.app_at_place() + app._open_text_dialog() + app.update() + blank = app._blank_ctk_image() + self.assertEqual(app.dlg_error_lbl.cget("text"), "") # untouched: no error yet + app._apply_text_dialog() # no text at all + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_text_empty")) + app._update_text_preview() # a refresh keeps it after a failed save + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_text_empty")) + self.type_text(app, " \n ") # blank text + app._apply_text_dialog() + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_text_empty")) + self.type_text(app, "Jane") + for bad in ("abc", "0", "-3", "401", "nan", ""): + with self.subTest(size=bad): + self.fill(app.dlg_size_entry, bad) + app._apply_text_dialog() + self.assertEqual(app.dlg_error_lbl.cget("text"), + self.tr("sig.err_size", max=400)) + self.assertTrue(app._dialog.winfo_exists()) # stays open + self.assertEqual(app.profile.signatures, []) # nothing was added + # A valid preview followed by an error: the previous picture must go + # (CTkLabel.configure(image=None) would leave it on screen) ... + self.fill(app.dlg_size_entry, "24") + app._update_text_preview() + self.assertEqual(app.dlg_error_lbl.cget("text"), "") + self.assertIsNot(app.dlg_preview_lbl._cachet_img, blank) + self.fill(app.dlg_size_entry, "abc") + app._update_text_preview() + self.assertIs(app.dlg_preview_lbl._cachet_img, blank) + self.assertIs(app.dlg_preview_lbl.cget("image"), blank) + # ... and the next valid keystroke renders again, also once the + # dropped picture has really been freed (TclError "image doesn't + # exist" otherwise). + gc.collect() + app.update() + self.fill(app.dlg_size_entry, "30") + app._update_text_preview() + app.update() + self.assertIsNot(app.dlg_preview_lbl._cachet_img, blank) + self.assertEqual(app.dlg_error_lbl.cget("text"), "") + + def test_oversized_text_refused_and_not_persisted(self): + import time + app = self.app_at_place() + app._open_text_dialog() + self.fill(app.dlg_size_entry, "400") + start = time.monotonic() + self.type_text(app, "W" * 300) # ~500 MP at 300 dpi + self.assertLess(time.monotonic() - start, 2.0) # refused by measuring alone + refusal = app.dlg_error_lbl.cget("text") + self.assertTrue(refusal.startswith(self.tr("sig.err_render", error="")), refusal) + self.assertIn("too large", refusal) + self.assertIs(app.dlg_preview_lbl.cget("image"), app._blank_ctk_image()) + app._apply_text_dialog() + self.assertTrue(app._dialog.winfo_exists()) # kept open + self.assertEqual(app.dlg_error_lbl.cget("text"), refusal) + self.assertEqual(app.profile.signatures, []) + self.assertEqual(self.saved(app).get("signatures", []), []) + + def test_text_box_does_not_wrap(self): + # The stamp breaks lines only at real newlines, so the box must not + # wrap a long line visually: it scrolls sideways instead. (CTkTextbox + # 5.2.2 has no cget("wrap"): the behaviour itself is asserted.) + app = self.app_at_place() + app._open_text_dialog() + self.type_text(app, "A sentence typed without ever pressing Enter. " * 8) + self.pump(app, rounds=3) + first, last = app.dlg_text_box.xview() + self.assertEqual(first, 0.0) + self.assertLess(last, 1.0) # part of the line is off to the right + + def test_preview_shows_size_on_page(self): + app = self.app_at_place() + app._open_text_dialog() + self.type_text(app, "Jane Doe") + at_24 = app.dlg_size_lbl.cget("text") + self.assertRegex(at_24, r"\d+ × \d+ pt") + self.fill(app.dlg_size_entry, "48") + app._update_text_preview() + # the size ON THE PAGE (what the stamping code gives), not the + # size of the scaled-down preview + _img, (w_pt, h_pt) = stamplib.stamp_content( + Stamp(kind="text", text="Jane Doe", font_size=48.0)) + self.assertEqual(app.dlg_size_lbl.cget("text"), + self.tr("sig.preview_size", w=round(w_pt), h=round(h_pt))) + self.assertNotEqual(app.dlg_size_lbl.cget("text"), at_24) + # a line wider than the page: the preview is scaled down to its box, + # the size line still tells the truth + wide = "A sentence typed without ever pressing Enter. " * 3 + self.type_text(app, wide) + _img, (w_pt, h_pt) = stamplib.stamp_content( + Stamp(kind="text", text=wide, font_size=48.0)) + self.assertGreater(w_pt, 595) + width, height = app.dlg_preview_lbl.cget("image").cget("size") + self.assertTrue(width <= 500 and height <= 120, (width, height)) + self.assertEqual(app.dlg_size_lbl.cget("text"), + self.tr("sig.preview_size", w=round(w_pt), h=round(h_pt))) + self.fill(app.dlg_size_entry, "abc") + app._update_text_preview() + self.assertEqual(app.dlg_size_lbl.cget("text"), "") + + def test_picker_after_dialog_closed_is_harmless(self): + # the dialog can be closed while a native picker is open + app = self.app_at_place() + font = Path(shutil.copy(stamplib.resolve_font("caveat"), self.tmp / "hand.ttf")) + + def closing_picker(value): + def picker(*_a, **_k): + app._close_dialog() + return value + return picker + + app._open_text_dialog() + with mock.patch.object(self.gui.filedialog, "askopenfilename", + side_effect=closing_picker(str(font))): + app._on_dialog_font(self.tr("sig.font_custom")) + self.assertIsNone(app._dialog) + for opener in (app._open_text_dialog, app._open_draw_dialog): + opener() + with mock.patch.object(self.gui.colorchooser, "askcolor", + side_effect=closing_picker(((255, 0, 0), "#ff0000"))): + app._pick_dialog_color() + self.assertIsNone(app._dialog) + app.update() + self.assertEqual(app.profile.signatures, []) + + def test_text_dialog_colour_and_custom_font(self): + app = self.app_at_place() + font = Path(shutil.copy(stamplib.resolve_font("caveat"), self.tmp / "My Hand.ttf")) + custom = self.tr("sig.font_custom") + app._open_text_dialog() + self.type_text(app, "Jane") + self.assertEqual(app.dlg_font_menu.cget("values"), + [name for _id, name in stamplib.font_choices()] + [custom]) + with mock.patch.object(self.gui.colorchooser, "askcolor", + return_value=((255, 0, 0), "#ff0000")) as ask: + app.dlg_color_btn.invoke() + self.assertIs(ask.call_args.kwargs["parent"], app._dialog) # not behind the grab + self.assertEqual(app.dlg_color_btn.cget("text"), "#FF0000") + self.assertEqual(app.dlg_color_btn.cget("fg_color"), "#FF0000") + with mock.patch.object(self.gui.colorchooser, "askcolor", + return_value=(None, None)): # cancelled + app._pick_dialog_color() + self.assertEqual(app._dialog_state["color"], "#FF0000") + with mock.patch.object(self.gui.filedialog, "askopenfilename", + return_value=str(font)) as ask: + app._on_dialog_font(custom) + self.assertIs(ask.call_args.kwargs["parent"], app._dialog) + self.assertEqual(app.dlg_font_menu.get(), "My Hand.ttf") + with mock.patch.object(self.gui.filedialog, "askopenfilename", return_value=""): + app.dlg_font_menu.set(custom) # what picking the entry shows first + app._on_dialog_font(custom) # cancelled: back to the font in use + self.assertEqual(app.dlg_font_menu.get(), "My Hand.ttf") + self.assertEqual(app.dlg_error_lbl.cget("text"), "") + app._apply_text_dialog() + (sig,) = app.profile.signatures + self.assertEqual((sig.stamp.font, sig.stamp.color), (str(font), "#FF0000")) + thumb, _size = app._content(sig) # rendered with that colour + self.assertEqual([c for _n, c in thumb.convert("RGB").getcolors()], [(255, 0, 0)]) + # editing it shows the custom font's file name; the menu goes back + # to a bundled font + app._edit_selected() + self.assertEqual(app.dlg_font_menu.get(), "My Hand.ttf") + self.assertEqual(app.dlg_color_btn.cget("text"), "#FF0000") + app._on_dialog_font("Lato") + app._apply_text_dialog() + self.assertEqual(sig.stamp.font, "lato") + + def test_text_preview_renders(self): + app = self.app_at_place() + app._open_text_dialog() + app.update() + blank = app._blank_ctk_image() + self.assertIs(app.dlg_preview_lbl.cget("image"), blank) # nothing typed yet + # ... and no reproach for it: not before the user typed or tried to save + self.assertEqual(app.dlg_error_lbl.cget("text"), "") + app._on_dialog_font("Lato") # another refresh, still untouched + self.assertEqual(app.dlg_error_lbl.cget("text"), "") + self.type_text(app, "") # typed, then emptied: now it is said + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_text_empty")) + app._on_dialog_font("Great Vibes") + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_text_empty")) + self.type_text(app, "Jane Doe\n{date} {filename}") + app.update() + shown = app.dlg_preview_lbl.cget("image") + self.assertIsNot(shown, blank) + self.assertEqual(app.dlg_error_lbl.cget("text"), "") + width, height = shown.cget("size") + self.assertTrue(0 < width <= 500 and 0 < height <= 120, (width, height)) + # the preview IS the stamping code's output, for a sample document + with mock.patch.object(self.gui.stamplib, "stamp_content", + wraps=stamplib.stamp_content) as spy: + self.type_text(app, "JD") + self.assertEqual(spy.call_args.args[0], + Stamp(kind="text", text="JD")) + self.assertEqual(spy.call_args.kwargs["filename"], "t") + self.assertIsNot(app.dlg_preview_lbl.cget("image"), shown) # a fresh picture + # whatever the renderer raises becomes the dialog's message + with mock.patch.object(self.gui.stamplib, "stamp_content", + side_effect=MemoryError()): + self.type_text(app, "Jane") + self.assertEqual(app.dlg_error_lbl.cget("text"), + self.tr("sig.err_render", error="MemoryError")) + self.assertIs(app.dlg_preview_lbl.cget("image"), blank) + + def test_edit_text_keeps_placement(self): + app = self.app_at_place() + sig = self.add_text(app, "Jane", label="My signature") + app._turn_page(1) + self.click(app, 0.3, 0.6) + placement = (sig.stamp.page, sig.stamp.x, sig.stamp.y, sig.placed_on) + size_before = app._element_size_pt(sig.id) + app.edit_btn.invoke() + app.update() + self.assertEqual(app._dialog.title(), self.tr("sig.text_title_edit")) + self.assertEqual(app.dlg_name_entry.get(), "My signature") # seeded + self.assertEqual(app.dlg_text_box.get("1.0", "end-1c"), "Jane") + self.assertEqual(app.dlg_size_entry.get(), "24") + self.assertEqual(app.dlg_font_menu.get(), "Great Vibes") + self.type_text(app, "Jane Doe") + self.fill(app.dlg_size_entry, "36,5") # decimal comma + app._on_dialog_font("Caveat") + app._apply_text_dialog() + self.assertIsNone(app._dialog) + self.assertEqual([s.id for s in app.profile.signatures], [sig.id]) # in place + self.assertEqual((sig.stamp.text, sig.stamp.font, sig.stamp.font_size), + ("Jane Doe", "caveat", 36.5)) + self.assertEqual((sig.stamp.page, sig.stamp.x, sig.stamp.y, sig.placed_on), + placement) + self.assertEqual(placement[0], 2) + self.assertTrue(app._sig_placed(sig)) + self.assertEqual(sig.label, "My signature") + self.assertNotEqual(app._element_size_pt(sig.id), size_before) # re-rendered + saved = self.saved(app)["signatures"][0] + self.assertEqual((saved["text"], saved["font_size"], saved["page"]), + ("Jane Doe", 36.5, 2)) + # an emptied name falls back on the first non-empty line (40 chars) + app._edit_selected() + self.fill(app.dlg_name_entry, "") + self.type_text(app, "\n " + "x" * 50 + "\nsecond line") + app._apply_text_dialog() + self.assertEqual(sig.label, "x" * 40) + + # ------------------------------------------------------- image signatures + def test_add_image_copies_into_store(self): + app = self.app_at_place() + png = make_png(self.tmp / "s.png") + with mock.patch.object(self.gui.filedialog, "askopenfilename", + return_value=str(png)): + app.add_image_btn.invoke() + (sig,) = app.profile.signatures + self.assertEqual(sig.label, "s") + self.assertEqual(app.selected_id, sig.id) + self.assertTrue(app.store.is_store_file(sig.stamp.image_path)) + self.assertTrue(str(sig.stamp.image_path).startswith(str(self.tmp))) + self.assertEqual(self.saved(app)["signatures"][0]["image_path"], + sig.stamp.image_path.name) + # the stored COPY is used: the original may go away + png.unlink() + app._preview_cache.clear() + app._scaled_cache.clear() + self.assertIsNotNone(app._content(sig)) + self.click(app) + self.assertEqual(len(self.items(app, sig.id, "image")), 1) + with mock.patch.object(self.gui.filedialog, "askopenfilename", return_value=""): + app._pick_image_signature() # cancelled picker: nothing happens + self.assertEqual(len(app.profile.signatures), 1) + + def test_unreadable_image_reports_error(self): + app = self.make_app() + self.wizard_with_state(app, self.tpl, self.out) + app.mode_var.set("image") + bad = self.tmp / "bad.png" + bad.write_text("not an image") + self.assertIsNone(app._add_image_signature(bad)) # step 6 is not built yet + self.assertEqual(app.profile.signatures, []) + notice = app._element_notice + self.assertTrue(notice.startswith(self.tr("sig.err_image", error="")), notice) + app._goto_step(5) + app._update_place_labels() + self.assertEqual(app.place_warn_lbl.cget("text"), notice) + app._save_profile() # a successful save does not erase it + app._update_place_labels() + self.assertEqual(app.place_warn_lbl.cget("text"), notice) + sig = self.add_text(app) # (a new operation clears it ...) + app._element_notice = notice + app._select(sig.id) # ... and so does selecting + self.assertIsNone(app._element_notice) + self.assertNotEqual(app.place_warn_lbl.cget("text"), notice) + + def test_image_store_failure_adds_nothing(self): + # no fallback to the original file when the copy cannot be made + app = self.app_at_place() + with mock.patch.object(app.store, "import_image", side_effect=OSError("disk full")): + self.assertIsNone(app._add_image_signature(make_png(self.tmp / "s.png"))) + self.assertEqual(app.profile.signatures, []) + self.assertEqual(app._element_notice, self.tr("sig.err_store", error="disk full")) + self.assertIsNone(app._profile_error) # not a profile-save failure + self.assertEqual(app.place_warn_lbl.cget("text"), app._element_notice) + + def test_edit_image_width(self): + app = self.app_at_place() + sig = app._add_image_signature(make_png(self.tmp / "s.png")) # 300×120 px + self.click(app) + placement = (sig.stamp.page, sig.stamp.x, sig.stamp.y, sig.placed_on) + app.edit_btn.invoke() + app.update() + self.assertEqual(app._dialog.title(), self.tr("sig.image_title")) + self.assertEqual((app.dlg_name_entry.get(), app.dlg_width_entry.get()), + ("s", "150")) + self.assertIsNot(app.dlg_preview_lbl.cget("image"), app._blank_ctk_image()) + for bad in ("abc", "0", "5001", ""): + with self.subTest(width=bad): + self.fill(app.dlg_width_entry, bad) + app._apply_image_dialog() + self.assertEqual(app.dlg_error_lbl.cget("text"), + self.tr("sig.err_width", max=5000)) + self.assertTrue(app._dialog.winfo_exists()) + self.assertEqual(sig.stamp.width_pt, 150.0) + self.fill(app.dlg_width_entry, "60,5") + self.fill(app.dlg_name_entry, "Company stamp") + app.dlg_save_btn.invoke() + self.assertIsNone(app._dialog) + self.assertEqual((sig.stamp.width_pt, sig.label), (60.5, "Company stamp")) + self.assertEqual((sig.stamp.page, sig.stamp.x, sig.stamp.y, sig.placed_on), + placement) + width, height = app._element_size_pt(sig.id) # the preview follows + self.assertAlmostEqual(width, 60.5) + self.assertAlmostEqual(height, 60.5 * 120 / 300) + self.assertEqual(self.saved(app)["signatures"][0]["width_pt"], 60.5) + # stored file gone: no preview, the reason, and the dialog still opens + sig.stamp.image_path.unlink() + app._preview_cache.clear() + app._scaled_cache.clear() + app._edit_selected() + self.assertIs(app.dlg_preview_lbl.cget("image"), app._blank_ctk_image()) + self.assertEqual(app.dlg_error_lbl.cget("text"), + self.tr("sig.err_image", error=app._sig_error(sig))) + + # ----------------------------------------------------------- draw dialog + def test_draw_dialog_creates_transparent_png(self): + app = self.app_at_place() + app.draw_btn.invoke() + app.update() + self.assertEqual(app._dialog.title(), self.tr("sig.draw_title")) + self.draw(app, [(100, 100), (200, 60), (400, 140)], [(250, 200)]) # a line, a dot + self.assertEqual(len(app._dialog_state["strokes"]), 2) + self.assertEqual(len(app.dlg_draw_canvas.find_all()), 4) # the on-screen echo + with mock.patch.object(self.gui.colorchooser, "askcolor", + return_value=((0, 128, 0), "#008000")): + app.dlg_color_btn.invoke() + for item in app.dlg_draw_canvas.find_all(): # recoloured + self.assertEqual(app.dlg_draw_canvas.itemcget(item, "fill"), "#008000") + app.dlg_save_btn.invoke() + app.update() + self.assertIsNone(app._dialog) + (sig,) = app.profile.signatures + self.assertEqual((sig.stamp.kind, sig.label), ("image", self.tr("sig.drawn_label"))) + self.assertEqual(app.selected_id, sig.id) + self.assertTrue(app.store.is_store_file(sig.stamp.image_path)) + self.assertEqual(sig.stamp.image_path.suffix, ".png") + with Image.open(sig.stamp.image_path) as png: + self.assertEqual(png.mode, "RGBA") + self.assertEqual(png.getchannel("A").getextrema(), (0, 255)) + self.assertEqual([c for _n, c in png.convert("RGB").getcolors()], + [(0, 128, 0)]) + # 0.4 pt per canvas px: 300 px of strokes (+ the pen) -> ~121 pt + self.assertAlmostEqual(sig.stamp.width_pt, 303 * 0.4, delta=2) + self.assertEqual(self.saved(app)["signatures"][0]["image_path"], + sig.stamp.image_path.name) + self.click(app) # it is placed like any image + self.assertEqual(len(self.items(app, sig.id, "image")), 1) + + def test_draw_points_are_clamped_to_the_canvas(self): + # a drag goes on outside the canvas: far-away points must not turn + # the drawing into a gigapixel raster + app = self.app_at_place() + app._open_draw_dialog() + self.draw(app, [(10, 10), (99999, -99999)]) + self.assertEqual(app._dialog_state["strokes"], [[(10, 10), (620, 0)]]) + app._apply_draw_dialog() + (sig,) = app.profile.signatures + self.assertEqual(sig.stamp.width_pt, 240.0) # widest allowed + with Image.open(sig.stamp.image_path) as png: + self.assertLessEqual(png.width, (620 + 6) * 4) + + def test_draw_dialog_empty_is_refused(self): + app = self.app_at_place() + app._open_draw_dialog() + app._apply_draw_dialog() + self.assertTrue(app._dialog.winfo_exists()) + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_draw_empty")) + self.draw(app, [(10, 10), (50, 50)]) + self.assertEqual(app.dlg_error_lbl.cget("text"), "") # no stale message + app._dialog_error("x") + app.dlg_clear_btn.invoke() # empties the model and its echo + self.assertEqual(app._dialog_state["strokes"], []) + self.assertEqual(app.dlg_draw_canvas.find_all(), ()) + self.assertEqual(app.dlg_error_lbl.cget("text"), "") + app._apply_draw_dialog() + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_draw_empty")) + self.assertEqual(app.profile.signatures, []) + self.assertFalse(app.store.signatures_dir.exists()) # nothing was stored + # a drawing over the pixel budget says so (not "draw something first") + self.draw(app, [(10, 10), (50, 50)]) + with mock.patch.object(stamplib, "MAX_TEXT_PIXELS", 10): + app._apply_draw_dialog() + self.assertEqual(app.dlg_error_lbl.cget("text"), self.tr("sig.err_draw_too_large")) + self.assertTrue(app._dialog.winfo_exists()) + self.assertEqual(app.profile.signatures, []) + # a drawing that cannot be stored is not added either + with mock.patch.object(app.store, "store_image", side_effect=OSError("disk full")): + app._apply_draw_dialog() + self.assertEqual(app.dlg_error_lbl.cget("text"), + self.tr("sig.err_store", error="disk full")) + self.assertTrue(app._dialog.winfo_exists()) + self.assertEqual(app.profile.signatures, []) + + def test_dialog_cancel_and_window_close_add_nothing(self): + app = self.app_at_place() + app._open_text_dialog() + self.type_text(app, "Jane") + app.dlg_cancel_btn.invoke() + self.assertIsNone(app._dialog) + app._open_draw_dialog() + app.update() + dialog = app._dialog + self.draw(app, [(10, 10), (50, 50)]) + app.tk.call(dialog.protocol("WM_DELETE_WINDOW")) # the window's close button + self.assertFalse(dialog.winfo_exists()) + self.assertIsNone(app._dialog) + self.assertEqual(app._dialog_state, {}) + self.assertEqual(app.profile.signatures, []) + self.assertFalse(app.store.signatures_dir.exists()) + # only one dialog at a time: opening another closes the previous one + app._open_text_dialog() + first = app._dialog + app._open_draw_dialog() + self.assertFalse(first.winfo_exists()) + self.assertEqual(app._dialog_state["kind"], "draw") + + # ------------------------------------------- delete, enable, every page + def test_delete_removes_signature_and_file(self): + app = self.app_at_place() + sig = app._add_image_signature(make_png(self.tmp / "s.png")) + stored = sig.stamp.image_path + self.assertTrue(stored.exists()) + app.delete_btn.invoke() + app.update() + self.modal_button(app, self.tr("sig.delete_keep")).invoke() # changed my mind + app.update() + self.assertEqual(app.profile.signatures, [sig]) + app._delete_selected() + app.update() + self.modal_button(app, self.tr("sig.delete_confirm")).invoke() + app.update() + self.assertEqual(app.profile.signatures, []) + self.assertFalse(stored.exists()) + self.assertIsNone(app.selected_id) + self.assertEqual(self.saved(app)["signatures"], []) + self.assertEqual(str(app.delete_btn.cget("state")), "disabled") + self.assertEqual(str(app.edit_btn.cget("state")), "disabled") + + def test_enable_toggle_persists_and_ungates(self): + app = self.app_at_place("beid") + sig = self.add_text(app) + self.assertEqual(app._place_error(), self.tr("place.unplaced", name="Jane")) + self.assertEqual(str(app._btn_next.cget("state")), "disabled") + app._element_checks[sig.id].toggle() # what a click on the box does + app.update() + self.assertFalse(sig.enabled) + self.assertIsNone(app._place_error()) # an unticked signature never blocks + self.assertEqual(str(app._btn_next.cget("state")), "normal") + self.assertFalse(self.saved(app)["signatures"][0]["enabled"]) + self.assertEqual(app._element_checks[sig.id].get(), 0) + app._toggle_enabled(sig.id) + self.assertTrue(sig.enabled) + self.assertEqual(app._element_checks[sig.id].get(), 1) + self.assertTrue(self.saved(app)["signatures"][0]["enabled"]) + + def test_toggle_all_pages_flips_model(self): + # direct calls: the direction comes from the model, not the checkbox + app = self.app_at_place() + sig = self.add_text(app) + app._toggle_all_pages() + self.assertTrue(sig.stamp.all_pages) + self.assertEqual(app.all_pages_chk.get(), 1) # the widget follows + self.assertIs(self.saved(app)["signatures"][0]["all_pages"], True) + app._toggle_all_pages() # off, no position yet + self.assertFalse(sig.stamp.all_pages) + self.assertIsNone(sig.stamp.page) + self.assertEqual(app.all_pages_chk.get(), 0) + app._toggle_all_pages() + self.click(app) + self.assertTrue(sig.stamp.all_pages) + self.assertIsNone(sig.stamp.page) + self.assertEqual(app.page_text, "") # no single target page + self.assertTrue(app._sig_placed(sig)) + app._turn_page(1) + app._toggle_all_pages() # off, with a position + self.assertEqual(sig.stamp.page, app.cur_page + 1) + self.assertEqual((sig.stamp.page, app.page_text), (2, "2")) + self.assertEqual(app.all_pages_chk.get(), 0) + app.all_pages_chk.toggle() # a real click flips too + app.update() + self.assertTrue(sig.stamp.all_pages) + self.assertEqual(app.all_pages_chk.get(), 1) + + def test_untick_all_pages_keeps_a_stale_placement_unplaced(self): + app = self.app_at_place() + sig = self.add_text(app) + app._toggle_all_pages() + self.click(app, 0.5, 0.05) # near the top of an A4 page + self.assertTrue(app._sig_placed(sig)) + before = (sig.stamp.x, sig.stamp.y, tuple(sig.placed_on)) + app.template_dims = [(612.0, 792.0)] * 2 # as with another template: Letter + app._refresh_place() + self.assertFalse(app._sig_placed(sig)) # saved for another page size + app._toggle_all_pages() # untick: must NOT place it by itself + self.assertFalse(sig.stamp.all_pages) + self.assertIsNone(sig.stamp.page) + self.assertEqual((sig.stamp.x, sig.stamp.y, tuple(sig.placed_on)), before) # kept + self.assertFalse(app._sig_placed(sig)) + self.assertIsNotNone(app._place_error()) # still blocks until a click + self.click(app) + self.assertTrue(app._sig_placed(sig)) + self.assertEqual((sig.stamp.page, tuple(sig.placed_on)), (1, (612.0, 792.0))) + + def test_toggle_all_pages_ignored_for_vignette_and_anchor(self): + app = self.app_at_place("beid") + app._toggle_all_pages() # the vignette is selected + self.assertEqual(str(app.all_pages_chk.cget("state")), "disabled") + self.assertEqual(app.all_pages_chk.get(), 0) + app.destroy() + short = make_pdf(self.tmp / "short.pdf", [(595, 842)]) + app = self.app_at_place("image", inputs=[short]) + sig = self.add_text(app) + self.assertEqual(app._page_anchor(), "last") + app._toggle_all_pages() # every element goes on the anchor page + self.assertFalse(sig.stamp.all_pages) + self.assertEqual(str(app.all_pages_chk.cget("state")), "disabled") + + # ------------------------------------------------- selection and placing + def test_click_places_only_the_selected_element(self): + app = self.app_at_place("beid") + a = self.add_text(app, "A") + b = self.add_text(app, "B") + app._select(a.id) + self.click(app, 0.3, 0.3) + self.assertTrue(app._sig_placed(a)) + self.assertFalse(app._sig_placed(b)) + self.assertIsNone(app.profile.settings.vignette) + self.assertEqual((a.stamp.page, a.placed_on), (1, (595.0, 842.0))) + self.assertEqual(app.page_text, "1") + app._select(self.gui.VIGNETTE_ID) + self.click(app, 0.6, 0.6) + vignette = app.profile.settings.vignette + self.assertEqual((vignette.page, vignette.placed_on), (1, (595.0, 842.0))) + self.assertFalse(app._sig_placed(b)) + saved = self.saved(app) + self.assertIn("vignette", saved["settings"]) + self.assertIn("x", saved["signatures"][0]) + self.assertNotIn("x", saved["signatures"][1]) + # "Reset position" also acts on the selected element only + app.reset_btn.invoke() + self.assertIsNone(app.profile.settings.vignette) + self.assertEqual(app.page_text, "") + self.assertTrue(app._sig_placed(a)) + app._select(a.id) + app._reset_selected_position() + self.assertFalse(app._sig_placed(a)) + self.assertIsNone(a.placed_on) + + def test_disabled_selected_signature_is_outlined(self): + app = self.app_at_place() + a = self.add_text(app, "A") + b = self.add_text(app, "B") + app._toggle_enabled(a.id) # untick A, select it, click + app._select(a.id) + self.click(app) + self.assertIsNotNone(a.stamp.x) # the position is stored + self.assertEqual(self.items(app, a.id, "image"), []) # outline only + (rect,) = self.items(app, a.id, "rectangle") + self.assertEqual(app.canvas.itemcget(rect, "outline"), "#777") + self.assertTrue(app.canvas.itemcget(rect, "dash")) + app._select(b.id) # no longer selected: not drawn + self.assertEqual(self.items(app, a.id), []) + + def test_page_field_follows_selection(self): + app = self.app_at_place() + a = self.add_text(app, "A") + b = self.add_text(app, "B") + app._select(a.id) + app._turn_page(1) + self.click(app) + self.assertEqual((a.stamp.page, app.page_text), (2, "2")) + app._turn_page(-1) + app._select(b.id) # unplaced: no page + self.assertEqual((app.page_text, app.page_entry.get()), ("", "")) + app._select(a.id) # back on its own page + self.assertEqual((app.page_text, app.cur_page, app.page_entry.get()), + ("2", 1, "2")) + app._delete_signature(a.id) # the field must not keep "2" + self.assertEqual(app.page_text, "") + # a new, shorter template: a stale page number would block the step + one_page = make_pdf(self.tmp / "one.pdf", [(595, 842)]) + app.page_text = "2" + with mock.patch.object(self.gui.filedialog, "askopenfilename", + return_value=str(one_page)): + app._pick_template() + self.assertEqual(app.page_text, "") + self.assertIsNone(app._page_entry_error()) + + def test_page_entry_retargets_selected_element(self): + app = self.app_at_place("beid") + a = self.add_text(app, "A") + self.click(app) # A on page 1 + self.fill(app.page_entry, "2") + app._on_page_entry_change() + self.assertEqual((a.stamp.page, app.cur_page), (2, 1)) + self.assertEqual(self.saved(app)["signatures"][0]["page"], 2) + app._select(self.gui.VIGNETTE_ID) + self.click(app) # vignette on the previewed page 2 + self.assertEqual(app.profile.settings.vignette.page, 2) + self.fill(app.page_entry, "1") + app._on_page_entry_change() + self.assertEqual(app.profile.settings.vignette.page, 1) + self.assertEqual(a.stamp.page, 2) # only the selected element moved + + def test_page_entry_retarget_follows_the_page_size(self): + # pages of different sizes: an element moved through the page field + # is "placed on" its NEW page, so the placement stays in force + self.tpl = make_pdf(self.tmp / "mixed.pdf", [(595, 842), (842, 595)]) + app = self.app_at_place("beid") + a = self.add_text(app, "A") + self.click(app) # A on page 1 (portrait) + self.assertEqual(tuple(a.placed_on), (595.0, 842.0)) + self.fill(app.page_entry, "2") + app._on_page_entry_change() + self.assertEqual((a.stamp.page, tuple(a.placed_on)), (2, (842.0, 595.0))) + self.assertTrue(app._sig_placed(a)) + self.assertIsNone(app._place_error()) + app._select(self.gui.VIGNETTE_ID) + self.click(app) # vignette on page 2 (landscape) + self.fill(app.page_entry, "1") + app._on_page_entry_change() + vignette = app.profile.settings.vignette + self.assertEqual((vignette.page, tuple(vignette.placed_on)), (1, (595.0, 842.0))) + self.assertTrue(app._vignette_placed()) + + def test_page_beyond_template_blocks(self): + app = self.app_at_place("beid") + self.assertIsNone(app._place_error()) + self.fill(app.page_entry, "7") + app._on_page_entry_change() + self.assertEqual(app._place_error(), + self.tr("place.page_beyond", page=7, total=2)) + self.assertEqual(str(app._btn_next.cget("state")), "disabled") # blocking + self.assertEqual(app.place_warn_lbl.cget("text"), app._place_error()) + # "²" (one key on an AZERTY keyboard) is a digit for str.isdigit() + # but not a number for int(): invalid, not a ValueError in every + # navigation callback; so is a pasted number too long for int() + for bad in ("x", "²", "1²", "9" * 5000): + with self.subTest(page=bad): + self.fill(app.page_entry, bad) + app._on_page_entry_change() + self.assertEqual(app._place_error(), self.tr("place.page_invalid")) + app._refresh_chrome() + self.assertEqual(str(app._btn_next.cget("state")), "disabled") + self.fill(app.page_entry, "") + app._on_page_entry_change() + self.assertIsNone(app._place_error()) + self.assertEqual(str(app._btn_next.cget("state")), "normal") + + # ----------------------------------------------------------------- layout + def test_empty_list_has_hint_and_no_gap(self): + import customtkinter as ctk + app = self.app_at_place() # image mode, empty library + + def assert_only_the_hint(): + app.update() + (hint,) = app.elements_list.winfo_children() + self.assertIsInstance(hint, ctk.CTkLabel) + self.assertEqual(hint.cget("text"), self.tr("place.list_empty")) + # an empty CTkFrame would keep its 200×200 default size + self.assertLess(app.elements_list.winfo_reqheight(), 80) + + assert_only_the_hint() + sig = self.add_text(app) + app.update() + app._delete_signature(sig.id) + assert_only_the_hint() + self.assertEqual(app.pos_lbl.cget("text"), self.tr("place.select_hint")) + self.click(app) # nothing to place: no crash + self.assertEqual(app.pos_lbl.cget("text"), self.tr("place.select_hint")) + + def test_long_label_does_not_widen_panel(self): + app = self.app_at_place("beid") + sig = self.add_text(app, label="W" * 60) + app.update() + self.assertLessEqual(app.elements_panel.winfo_reqwidth(), + self.gui._ELEMENTS_PANEL_W + 12) + shown = app._element_labels[sig.id][0].cget("text") + self.assertTrue(shown.endswith("…") and len(shown) < 60, shown) + self.assertEqual(sig.label, "W" * 60) # only the display is elided + + def test_layout_fits_default_window(self): + # the layout contract at the default window size, in the two + # languages with the longest step-6 labels + for lang in ("pt", "nl"): + with self.subTest(lang=lang): + self.i18n.set_language(lang) + app = self.make_app() + app.geometry("1180x950") + app.update() + self.wizard_with_state(app, self.tpl, self.out) + app.mode_var.set("beid") + self.add_text(app, "A") + self.add_text(app, "B") + app._goto_step(5) + self.pump(app, rounds=5) + self.assertEqual(app.winfo_width(), 1180) + self.assertLessEqual(app.elements_panel.winfo_reqwidth(), + self.gui._ELEMENTS_PANEL_W + 12) + visible_right = (app._content_left.winfo_rootx() + + app._content_left.winfo_width()) + for widget in (app.page_next_btn, app.canvas): + self.assertLessEqual( + widget.winfo_rootx() + widget.winfo_width(), visible_right, + widget) + app.destroy() + + # ---------------------------------------------------------------- preview + def test_content_failure_never_reaches_chrome(self): + app = self.app_at_place() + with mock.patch.object(self.gui.stamplib, "stamp_content", + side_effect=MemoryError()) as spy: + sig = self.add_text(app) + app._refresh_chrome() # none of these may raise + app._goto_step(4) + app._goto_step(5) + app._refresh_chrome() + self.click(app) + self.assertEqual(app._place_error(), self.tr( + "place.el_broken", name="Jane", error="MemoryError")) + self.assertEqual(spy.call_count, 1) # never rendered twice + self.assertEqual(app._element_labels[sig.id][1].cget("text"), + self.tr("place.st_error")) + self.assertEqual(len(self.items(app, sig.id, "text")), 1) # the ⚠ sign + self.assertEqual(self.items(app, sig.id, "image"), []) + + def test_all_elements_drawn_with_live_image_refs(self): + app = self.app_at_place() + a = self.add_text(app, "A") + self.click(app, 0.3, 0.3) + b = app._add_image_signature(make_png(self.tmp / "s.png")) + self.click(app, 0.6, 0.6) + + def element_images(): + return [i for i in app.canvas.find_withtag("element") + if app.canvas.type(i) == "image"] + + self.assertEqual(len(app._canvas_imgs), 2) + self.assertEqual(len(element_images()), 2) + # the selected element is drawn last (on top), in red; the other in blue + (rect_a,) = self.items(app, a.id, "rectangle") + (rect_b,) = self.items(app, b.id, "rectangle") + self.assertEqual(app.canvas.find_withtag("element")[-1], rect_b) + self.assertEqual(app.canvas.itemcget(rect_b, "outline"), "#c00") + self.assertEqual(app.canvas.itemcget(rect_a, "outline"), "#3B8ED0") + app.geometry("1500x1000") # a resize redraws everything + self.pump(app, rounds=4) + self.assertEqual(len(app._canvas_imgs), 2) + images = element_images() + self.assertEqual(len(images), 2) + for item in images: # a freed PhotoImage has no size + x0, _y0, x1, _y1 = app.canvas.bbox(item) + self.assertGreater(x1 - x0, 3) + + def test_scaled_preview_cached_across_redraws(self): + app = self.app_at_place() + self.add_text(app, "A") + self.click(app, 0.3, 0.3) + app._add_image_signature(make_png(self.tmp / "s.png")) + self.click(app, 0.6, 0.6) + app._preview_cache.clear() + app._scaled_cache.clear() + with mock.patch.object(self.gui.stamplib, "stamp_content", + wraps=stamplib.stamp_content) as spy: + for _ in range(4): + app._draw_page() + self.assertEqual(spy.call_count, 2) # once per signature + scaled = dict(app._scaled_cache) + self.assertEqual(len(scaled), 2) + app._draw_page() + for key, bitmap in scaled.items(): # the very same bitmaps are reused + self.assertIs(app._scaled_cache[key], bitmap) + app.geometry("1500x1000") # a resize rescales the cached + self.pump(app, rounds=4) # content, it never re-renders + app._refresh_chrome() + self.assertEqual(spy.call_count, 2) + self.assertGreater(len(app._scaled_cache), 2) + + def test_all_pages_shown_on_every_preview_page(self): + app = self.app_at_place() + sig = self.add_text(app) + app._toggle_all_pages() + self.click(app) + self.assertEqual(len(self.items(app, sig.id, "image")), 1) + app._turn_page(1) + self.assertEqual(len(self.items(app, sig.id, "image")), 1) + self.assertEqual(app._element_labels[sig.id][1].cget("text"), + self.tr("place.st_all")) + self.assertEqual(app.pos_lbl.cget("text"), self.tr( + "place.pos_all", x=f"{sig.stamp.x:.0f}", y=f"{sig.stamp.y:.0f}")) + app._toggle_all_pages() # now on page 2 only + app._turn_page(-1) + self.assertEqual(self.items(app, sig.id), []) + + def test_default_vignette_drawn_on_last_page_only(self): + vignette = self.gui.VIGNETTE_ID + app = self.app_at_place("beid") + self.assertEqual(self.items(app, vignette), []) # page 1 of 2 + app._turn_page(1) + (rect,) = self.items(app, vignette, "rectangle") + self.assertTrue(app.canvas.itemcget(rect, "dash")) # dashed: default + x0, y0, _x1, _y1 = app.canvas.coords(rect) + fw, fh, ox, oy = app._frame_geom + self.assertGreater(x0, ox + fw / 2) # bottom-right corner + self.assertGreater(y0, oy + fh / 2) + self.click(app, 0.2, 0.2) # placed on page 2 + (rect,) = self.items(app, vignette, "rectangle") + self.assertFalse(app.canvas.itemcget(rect, "dash")) # solid: placed + self.assertEqual(app._element_labels[vignette][1].cget("text"), + self.tr("place.st_page", page=2)) + app._turn_page(-1) + self.assertEqual(self.items(app, vignette), []) + + # ------------------------------------------------- predicates and the run + def test_step_completion_rules(self): + app = self.app_at_place() # image mode + self.assertEqual(app._place_error(), self.tr("place.need_signature")) + sig = self.add_text(app) + self.assertEqual(app._place_error(), self.tr("place.unplaced", name="Jane")) + self.assertFalse(app._step_complete(5)) + app._toggle_enabled(sig.id) # disabled: ignored, so none is left + self.assertEqual(app._place_error(), self.tr("place.need_signature")) + app._toggle_enabled(sig.id) + self.click(app) + self.assertIsNone(app._place_error()) + self.assertTrue(app._step_complete(5)) + app.mode_var.set("beid") # beid: complete without any signature + app._toggle_enabled(sig.id) + self.assertIsNone(app._place_error()) + app._delete_signature(sig.id) + self.assertIsNone(app._place_error()) + + def test_anchor_lock_forces_every_element(self): + short = make_pdf(self.tmp / "short.pdf", [(595, 842)]) # 1 page vs 2 + app = self.app_at_place("image", inputs=[short]) + self.assertEqual(app._page_anchor(), "last") + a = self.add_text(app, "A") + a.stamp = dataclasses.replace(a.stamp, page=1, x=10.0, y=10.0) + a.placed_on = app.template_dims[0] + b = self.add_text(app, "B", all_pages=True, x=5.0, y=5.0) + b.placed_on = app.template_dims[0] + app._refresh_place() + self.assertFalse(app._sig_placed(a)) # page 1, but the anchor is "last" + self.assertTrue(app._sig_placed(b)) # forced onto the anchor page + self.assertEqual(app._element_labels[a.id][1].cget("text"), + self.tr("place.st_unplaced")) + self.assertEqual(app._element_labels[b.id][1].cget("text"), + self.tr("anchor.last_page")) + self.assertEqual(str(app.all_pages_chk.cget("state")), "disabled") + self.assertEqual(str(app.page_entry.cget("state")), "disabled") + app._set_page_anchor_choice("first") # nothing was lost + app.update() + self.assertTrue(app._sig_placed(a)) + app._set_page_anchor_choice("last") + app.update() + app._select(a.id) + self.click(app) # places it on the locked page + self.assertTrue(app._sig_placed(a)) + self.assertEqual((a.stamp.page, app.page_text), (2, "")) + self.assertTrue(b.stamp.all_pages) + app._goto_step(6) + app.update() + self.assertEqual(app.step_index, 6) + cfg = self.launch_capturing_config(app) + self.assertEqual(len(cfg.stamps), 2) + for stamp in cfg.stamps: # resolved per document + self.assertEqual((stamp.page_anchor, stamp.page, stamp.all_pages), + ("last", None, False)) + self.assertEqual((cfg.page, cfg.page_anchor, cfg.x, cfg.y), + (None, None, None, None)) # image mode: no vignette + self.assertTrue(b.stamp.all_pages) # the library itself is untouched + + def test_run_summary_lists_elements(self): + import customtkinter as ctk + app = self.app_at_place("beid") + a = self.add_text(app, "A", label="Alpha") + self.click(app) + b = self.add_text(app, "B", label="Beta") + app._toggle_all_pages() + self.click(app) + c = self.add_text(app, "C", label="Gamma") + app._toggle_enabled(c.id) # unticked: not part of the run + app._goto_step(6) + app.update() + self.assertEqual(app.step_index, 6) + + def label_texts(widget): + for child in widget.winfo_children(): + if isinstance(child, ctk.CTkLabel): + yield child.cget("text") + yield from label_texts(child) + + summary = next(t for t in label_texts(app._content_left) + if self.tr("run.summary_stamps", count=2) in t) + self.assertIn(self.tr("run.summary_place", place=self.tr("run.place_default")), + summary) + self.assertIn(self.tr("run.stamp_line", name="Alpha", place=self.tr( + "run.place_custom", page=1, x=f"{a.stamp.x:.0f}", y=f"{a.stamp.y:.0f}")), + summary) + self.assertIn(self.tr("run.stamp_line", name="Beta", place=self.tr( + "run.place_all", x=f"{b.stamp.x:.0f}", y=f"{b.stamp.y:.0f}")), summary) + self.assertNotIn("Gamma", summary) + + def test_end_to_end_two_elements_image_mode(self): + app = self.app_at_place() + self.add_text(app, "Jane Doe\n{date} {filename}") + self.click(app, 0.3, 0.3) # page 1 + app._add_image_signature(make_png(self.tmp / "s.png")) + app._toggle_all_pages() + self.click(app, 0.6, 0.6) # every page + app._goto_step(6) + app._launch() # the real worker thread + self.assertTrue(app._running) + self.pump(app, lambda: not app._running, rounds=160) + self.assertIsNone(app.run_error) + (result,) = app.run_results + self.assertTrue(result.ok, result.detail) + self.assertIn("2 visual signature(s) applied", result.detail) + self.assertEqual(app.step_index, 7) # auto-advanced to the report + self.assertEqual(xobject_counts(self.out / "t_signe.pdf"), [2, 1]) + # The report never truncates the detail: its column is at least as + # wide as the text and takes the width the other two leave, whatever + # the window size (a scrollbar reaches what the window cannot show). + from tkinter import font as tkfont, ttk + table = app.summary_table + doc, status, detail = table["columns"] + text_px = tkfont.Font(font=ttk.Style().lookup("Treeview", "font")).measure( + result.detail) + self.assertGreater(text_px, 360) # wider than the column used to be + for geometry in ("1180x950", "1700x950"): + app.geometry(geometry) + self.pump(app, rounds=5) + widths = [table.column(c, "width") for c in (doc, status, detail)] + self.assertEqual(widths[:2], [240, 130], geometry) + self.assertGreaterEqual(widths[2], text_px, geometry) + self.assertGreaterEqual(sum(widths) + 4, table.winfo_width(), geometry) + if sum(widths) > table.winfo_width(): # e.g. at the default size + self.assertLess(table.xview()[1], 1, geometry) + + def test_beid_launch_passes_stamps_and_vignette(self): + app = self.app_at_place("beid") + a = self.add_text(app, "A") + self.click(app, 0.3, 0.3) + b = self.add_text(app, "B") + app._toggle_enabled(b.id) # unticked: left out + app._select(self.gui.VIGNETTE_ID) + app._turn_page(1) + self.click(app, 0.5, 0.5) # vignette on page 2 + app._goto_step(6) + app.update() + cfg = self.launch_capturing_config(app) + self.assertEqual(cfg.mode, "beid") + self.assertEqual(cfg.stamps, [a.stamp]) + vignette = app.profile.settings.vignette + # the legacy fields carry the VIGNETTE placement only + self.assertEqual((cfg.page, cfg.x, cfg.y, cfg.page_anchor), + (2, vignette.x, vignette.y, None)) + self.assertIsNone(cfg.image_path) + + def test_beid_anchored_launch_targets_the_anchor_page(self): + # a short file accepted at the validation step: the batch must get + # the SAME anchor for the vignette and every signature, or it would + # reject at run time what the wizard showed as accepted + short = make_pdf(self.tmp / "short.pdf", [(595, 842)]) # 1 page vs 2 + app = self.app_at_place("beid", inputs=[short]) + self.assertEqual(app._page_anchor(), "last") + self.add_text(app, "A") + self.click(app, 0.3, 0.3) + app._select(self.gui.VIGNETTE_ID) + self.click(app, 0.5, 0.5) + app._goto_step(6) + app.update() + self.assertEqual(app.step_index, 6) + cfg = self.launch_capturing_config(app) + vignette = app.profile.settings.vignette + self.assertIsNotNone(vignette.x) + self.assertEqual((cfg.page, cfg.page_anchor, cfg.x, cfg.y), + (None, "last", vignette.x, vignette.y)) + self.assertEqual([(s.page_anchor, s.page, s.all_pages) for s in cfg.stamps], + [("last", None, False)]) + self.assertEqual(core.anchor_requirements(cfg), (("last",), None)) + self.assertEqual(cfg.inputs, [short]) # accepted by the wizard too + + def test_language_switch_closes_dialog_and_keeps_library(self): + app = self.app_at_place("beid") + sig = self.add_text(app, "A", label="Alpha") + self.click(app) + app._open_text_dialog() # its texts are language-bound + app.update() + dialog = app._dialog + app._on_wizard_language_change("Français") + app.update() + self.assertFalse(dialog.winfo_exists()) + self.assertIsNone(app._dialog) + self.assertEqual(self.i18n.get_language(), "fr") + self.assertEqual(app.step_index, 5) + self.assertEqual(app.selected_id, sig.id) + self.assertEqual(app._element_labels[sig.id][0].cget("text"), "Alpha") # user data + self.assertEqual(app.add_text_btn.cget("text"), "Ajouter un texte…") + self.assertTrue(app._sig_placed(sig)) + self.assertEqual(self.saved(app)["settings"]["language"], "fr") + # leaving the wizard closes it too + app._open_text_dialog() + dialog = app._dialog + app._finish() + self.assertFalse(dialog.winfo_exists()) + self.assertEqual([s.label for s in app.profile.signatures], ["Alpha"]) + + +class GuiPersistence(_GuiEditorBase): + """The user profile behind the GUI: library, placements and wizard + settings are saved on every change and reloaded at start; Cancel and + Finish keep them; nothing here ever touches the real user folders.""" + + def test_profile_lives_in_the_temp_dirs(self): + app = self.make_app() + self.assertTrue(str(app.store.profile_path).startswith(str(self.tmp))) + self.assertTrue(str(app.store.signatures_dir).startswith(str(self.tmp))) + + def test_library_and_settings_survive_restart(self): + app = self.app_at_place() # image mode + app.pades_level_var.set("b-b") + sig = self.add_text(app, color="#FF0000") + self.click(app) + stamp = sig.stamp + app.destroy() + app = self.make_app() # "restart" on the same folders + self.assertEqual((app.mode_var.get(), app.pades_level_var.get()), + ("image", "b-b")) + (restored,) = app.profile.signatures + self.assertEqual((restored.id, restored.label, restored.stamp, restored.enabled), + (sig.id, "Jane", stamp, True)) + # same template: placed, and step 6 is complete without a click + self.wizard_with_state(app, self.tpl, self.out) + self.assertEqual(app.mode_var.get(), "image") # (Start reloads, never wipes) + self.assertTrue(app._sig_placed(app.profile.signatures[0])) + self.assertTrue(app._step_complete(5)) + app._goto_step(6) + app.update() + self.assertEqual(app.step_index, 6) + + def test_restored_placement_shown_on_its_page(self): + app = self.app_at_place() + self.add_text(app) + app._turn_page(1) + self.click(app) # placed on page 2 of 2 + app.destroy() + app = self.make_app() + self.wizard_with_state(app, self.tpl, self.out) + app._goto_step(5) + app.update() + self.assertEqual((app.cur_page, app.page_text, app.page_entry.get()), + (1, "2", "2")) + self.assertIn("2/2", app.page_lbl.cget("text")) + + def test_placement_not_reapplied_on_other_page_size(self): + app = self.app_at_place() + sig = self.add_text(app) + self.click(app) + other = make_pdf(self.tmp / "other.pdf", [(300, 300)]) + with mock.patch.object(self.gui.filedialog, "askopenfilename", + return_value=str(other)): + app._pick_template() + self.assertFalse(app._sig_placed(sig)) # not in force on that page size + self.assertIsNotNone(sig.stamp.x) # ... but nothing was destroyed + self.assertEqual(app._element_status(sig.id), self.tr("place.st_unplaced")) + with mock.patch.object(self.gui.filedialog, "askopenfilename", + return_value=str(self.tpl)): + app._pick_template() + self.assertTrue(app._sig_placed(sig)) # back with the original template + + def test_vignette_placement_survives_restart(self): + app = self.app_at_place("beid") + app._turn_page(1) + self.click(app, 0.4, 0.4) + placed = dataclasses.replace(app.profile.settings.vignette) + app.destroy() + app = self.make_app() + self.wizard_with_state(app, self.tpl, self.out) + self.assertEqual(app.profile.settings.vignette, placed) + self.assertTrue(app._vignette_placed()) + app._goto_step(5) + app.update() + self.assertEqual((app.cur_page, app.page_text), (1, "2")) + + def test_cancel_and_finish_keep_library(self): + app = self.app_at_place() + self.add_text(app) + self.click(app) + app._cancel_wizard() + app.update() + self.modal_button(app, self.tr("cancel.confirm")).invoke() + app.update() + self.assertIsNone(app.template_path) # the session is reset ... + self.assertEqual(app._stepper_btns, []) + self.assertEqual([s.label for s in app.profile.signatures], ["Jane"]) # ... not the library + self.assertEqual(app.mode_var.get(), "image") + self.wizard_with_state(app, self.tpl, self.out) + self.assertTrue(app._sig_placed(app.profile.signatures[0])) + app._finish() + app.update() + self.assertIsNone(app.template_path) + self.assertEqual([s.label for s in app.profile.signatures], ["Jane"]) + self.assertEqual(len(self.saved(app)["signatures"]), 1) + + def test_reset_does_not_overwrite_saved_settings(self): + # _reset_state sets the tk variables, whose traces save the settings: + # it must not write the defaults back over the user's choices + import profile_store + app = self.make_app() + app._start_wizard() + app.mode_var.set("azure") + app.pades_level_var.set("b-t") + app.azure_auth_var.set("device-code") + app.destroy() + app = self.make_app() + app._start_wizard() + app._start_wizard() + app.update() + settings = self.saved(app)["settings"] + self.assertEqual( + (settings["mode"], settings["pades_level"], settings["azure_auth"]), + ("azure", "b-t", "device-code")) + self.assertEqual((app.mode_var.get(), app.azure_auth_var.get()), + ("azure", "device-code")) + # The variables are set one after the other: a trace that saved in + # between would mix the file's values with the previous session's. + # (Here the file changed behind the app's back, as a second window + # would do.) + store = profile_store.ProfileStore() # the same temp folders + profile = store.load() + profile.settings.mode = "image" + profile.settings.pades_level = "b-b" + profile.settings.azure_auth = "interactive" + store.save(profile) + on_disk = store.profile_path.read_bytes() + app._start_wizard() + app.update() + self.assertEqual(store.profile_path.read_bytes(), on_disk) + self.assertEqual( + (app.mode_var.get(), app.pades_level_var.get(), app.azure_auth_var.get()), + ("image", "b-b", "interactive")) + + def azure_step(self, app): + """Park `app` on step 5 in azure mode (the vault entry exists).""" + self.wizard_with_state(app, self.tpl, self.out) + app.mode_var.set("azure") + app._goto_step(4) + app.update() + + def test_vault_precedence(self): + # saved user choice > CACHET_AZURE_VAULT_URL > built-in default + with mock.patch.dict(os.environ): + os.environ.pop(core.ENV_AZURE_VAULT_URL, None) + app = self.make_app() + self.assertEqual(app.azure_vault, "https://login.live.com") + app.destroy() + os.environ[core.ENV_AZURE_VAULT_URL] = "https://env.vault.azure.net" + app = self.make_app() + self.assertEqual(app.azure_vault, "https://env.vault.azure.net") + self.azure_step(app) + self.fill(app.azure_vault_entry, "https://mine.vault.azure.net") + app._on_azure_entry_edit() # a real edit is persisted + self.assertEqual(self.saved(app)["settings"]["azure_vault_url"], + "https://mine.vault.azure.net") + app.destroy() + app = self.make_app() # ... and wins over the env + self.assertEqual(app.azure_vault, "https://mine.vault.azure.net") + + def test_focus_out_does_not_persist_env_vault(self): + with mock.patch.dict(os.environ, + {core.ENV_AZURE_VAULT_URL: "https://env.vault.azure.net"}): + app = self.make_app() + self.azure_step(app) + self.assertEqual(app.azure_vault_entry.get(), "https://env.vault.azure.net") + app._on_azure_entry_edit() # what a mere calls + self.assertNotIn("azure_vault_url", self.saved(app)["settings"]) + # the key-name override is never persisted + self.fill(app.azure_key_entry, "sig-override") + app._on_azure_entry_edit() + self.assertEqual(app.azure_key, "sig-override") + on_disk = app.store.profile_path.read_text(encoding="utf-8") + self.assertNotIn("sig-override", on_disk) + self.assertNotIn("env.vault", on_disk) + + def test_output_dir_restored_only_if_it_exists(self): + app = self.make_app() + out = self.tmp / "signed" + out.mkdir() + with mock.patch.object(self.gui.filedialog, "askdirectory", + return_value=str(out)): + app._pick_output() + with mock.patch.object(self.gui.filedialog, "askopenfilename", + return_value=str(self.tpl)): + app._pick_azure_anchors() # (any existing file will do) + app.destroy() + app = self.make_app() + self.assertEqual(app.output_dir, out) + self.assertEqual(app.azure_anchors_path, self.tpl) + app.destroy() + out.rmdir() # the folder is gone since + app = self.make_app() + self.assertIsNone(app.output_dir) + self.assertEqual(self.saved(app)["settings"]["output_dir"], str(out)) # kept + app.destroy() + # A saved path the OS refuses to even probe (here an over-long name; + # likewise an unreachable share or a permission problem — pathlib + # raises for those) is ignored too: the app must still start. + unprobeable = str(self.tmp / ("a" * 300) / "signed") + profile = self.saved(app) + profile["settings"].update(output_dir=unprobeable, azure_trust_anchors=unprobeable) + app.store.profile_path.write_text(json.dumps(profile), encoding="utf-8") + with mock.patch.dict(os.environ): + os.environ.pop(core.ENV_AZURE_TRUST_ANCHORS, None) + app = self.make_app() + self.assertIsNone(app.output_dir) + self.assertIsNone(app.azure_anchors_path) + + def test_language_persisted_and_applied_by_launch_gui(self): + app = self.make_app() + app._on_language_change("Deutsch") + app.update() + self.assertEqual(self.saved(app)["settings"]["language"], "de") + app.destroy() + self.i18n.set_language("en") + stores = [] + + class StubApp: + def __init__(self, args, store=None): + stores.append(store) + + def mainloop(self): + pass + + with mock.patch.object(self.gui, "CachetApp", StubApp), \ + mock.patch.object(self.gui.ctk, "set_appearance_mode"): + self.assertEqual(self.gui.launch_gui(self.types.SimpleNamespace(lib=None)), 0) + self.assertEqual(self.i18n.get_language(), "de") # persisted > system + self.assertTrue(str(stores[0].profile_path).startswith(str(self.tmp))) + + def test_app_init_does_not_change_language(self): + # only launch_gui applies the saved language: tests (and embedders) + # build apps directly and rely on the current one + app = self.make_app() + app._on_language_change("Deutsch") + app.destroy() + self.i18n.set_language("en") + self.make_app() + self.assertEqual(self.i18n.get_language(), "en") + + def test_save_failure_is_non_fatal(self): + app = self.app_at_place() + with mock.patch.object(app.store, "save", side_effect=OSError("read-only")): + sig = self.add_text(app) # must not raise + self.click(app) + self.assertEqual(app._profile_error, "read-only") + self.assertTrue(app._sig_placed(sig)) # the session goes on + self.assertEqual(app.place_warn_lbl.cget("text"), + self.tr("place.save_failed", error="read-only")) + app._save_profile() # the folder is writable again + app._update_place_labels() + self.assertIsNone(app._profile_error) + self.assertEqual(app.place_warn_lbl.cget("text"), "") + self.assertEqual(len(self.saved(app)["signatures"]), 1) + + def test_corrupt_profile_starts_clean(self): + cfg = Path(os.environ["CACHET_CONFIG_DIR"]) + cfg.mkdir(parents=True) + (cfg / "profile.json").write_bytes(b"\x00\xff garbage {") + app = self.make_app() # must start + self.assertEqual(app.profile.signatures, []) + self.assertEqual((cfg / "profile.json.bak").read_bytes(), b"\x00\xff garbage {") + app._start_wizard() + app.update() + self.assertEqual(app.step_index, 0) + + class HeadlessImport(unittest.TestCase): def test_core_imports_without_tkinter(self): code = "import sign_pdfs_beid, sys; print('tkinter' in sys.modules)" @@ -1475,6 +4186,25 @@ def test_core_imports_without_tkinter(self): self.assertEqual(out.returncode, 0, out.stderr) self.assertEqual(out.stdout.strip(), "False") + def test_core_does_not_import_profile_store(self): + # The CLI never reads the persisted GUI profile, not even implicitly. + code = ("import sign_pdfs_beid, sys; " + "print('profile_store' in sys.modules, 'stamps' in sys.modules)") + out = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, + cwd=str(Path(__file__).parent)) + self.assertEqual(out.returncode, 0, out.stderr) + self.assertEqual(out.stdout.strip(), "False True") + + def test_new_modules_import_without_tkinter(self): + # stamps.py and profile_store.py serve the CLI binary too (no Tk). + code = ("import stamps, profile_store, sys; " + "print(sorted({'tkinter', 'customtkinter', 'gui', 'i18n'} " + "& set(sys.modules)))") + out = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, + cwd=str(Path(__file__).parent)) + self.assertEqual(out.returncode, 0, out.stderr) + self.assertEqual(out.stdout.strip(), "[]") + if __name__ == "__main__": unittest.main() From 06954da31184e89d1feae01e31e19464773c7e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Denooz?= Date: Wed, 7 Oct 2026 09:56:19 +0200 Subject: [PATCH 4/6] build: bundle the signature fonts in both binaries --- cachet.spec | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cachet.spec b/cachet.spec index 1892831..c7bde73 100644 --- a/cachet.spec +++ b/cachet.spec @@ -133,6 +133,13 @@ if _ilu.find_spec("tzdata") is not None: common_hidden += ["tzdata"] _meta("tzdata", common_datas) +# Bundled OFL fonts for text signatures (CLI + GUI). stamps.asset_path resolves +# them next to the module, or under sys._MEIPASS in the frozen binaries. The +# OFL requires the licence texts to travel with the fonts. +common_datas += [("fonts/*.ttf", "fonts"), ("fonts/licenses/*", "fonts/licenses")] +# Visual stamps: local module + Pillow's FreeType text renderer. +common_hidden += ["stamps", "PIL.ImageFont", "PIL.ImageDraw", "PIL.ImageOps", "PIL._imagingft"] + # --------------------------------------------------------------------------- # # GUI extras (only for the windowed binary) # --------------------------------------------------------------------------- # @@ -143,8 +150,9 @@ gui_hidden = list(common_hidden) # customtkinter: hook provided, but collect_all guarantees themes + fonts. _add_all("customtkinter", datas=gui_datas, binaries=gui_binaries, hidden=gui_hidden) -# The GUI's own assets: the top-bar logo (gui._asset_path resolves it under -# sys._MEIPASS in the frozen binary). GUI binary only — the CLI has no UI. +# The GUI's own assets: the top-bar logo (gui._asset_path delegates to +# stamps.asset_path, which resolves it under sys._MEIPASS in the frozen +# binary). GUI binary only — the CLI has no UI. gui_datas.append(("logo.png", ".")) gui_hidden += [ "darkdetect", @@ -152,6 +160,8 @@ gui_hidden += [ "tkinter.ttk", "tkinter.filedialog", "tkinter.messagebox", + "tkinter.colorchooser", # colour picker of the text / drawing dialogs + "profile_store", # user profile + signature image store (GUI only) "PIL.ImageTk", "PIL._tkinter_finder", "gui", # local module imported lazily by gui_main From 7d6a9e4aa2c40e495f40866ed6f6aaebfdcf6978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Denooz?= Date: Wed, 7 Oct 2026 09:56:19 +0200 Subject: [PATCH 5/6] ci: run the GUI suites under Xvfb and add GitLab and Forgejo pipelines The GitHub workflows gain the Xvfb GUI run, a frozen-binary smoke test for text signatures and job timeouts. GitLab CI and Forgejo Actions run the same headless and GUI suites. --- .forgejo/workflows/tests.yml | 42 ++++++++++++++++++++++ .github/workflows/build.yml | 66 +++++++++++++++++++++++++++++------ .github/workflows/release.yml | 60 +++++++++++++++++++++++++++---- .gitlab-ci.yml | 32 +++++++++++++++++ 4 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 .forgejo/workflows/tests.yml create mode 100644 .gitlab-ci.yml diff --git a/.forgejo/workflows/tests.yml b/.forgejo/workflows/tests.yml new file mode 100644 index 0000000..9e1e201 --- /dev/null +++ b/.forgejo/workflows/tests.yml @@ -0,0 +1,42 @@ +name: Tests + +# Forgejo Actions: runs the test suites only. The standalone executables and +# the releases are built on GitHub Actions (.github/workflows/build.yml and +# release.yml); .gitlab-ci.yml is the GitLab twin of this file. +# +# Three steps, as on GitHub: the headless suite, a GUI canary, then the +# guarded Gui* suites under Xvfb (the end-to-end layer of this Tk app). +on: + push: + branches: [develop, main] + pull_request: + workflow_dispatch: + +jobs: + tests: + runs-on: docker # adapt to the instance's runner label + timeout-minutes: 30 # a stalled Tk suite must not hold the runner + container: + image: python:3.13-bookworm # full image: tkinter + libtk included + env: + XMODIFIERS: "@im=none" # Tk must not wait on the ibus XIM bridge + PIP_DISABLE_PIP_VERSION_CHECK: "1" + steps: + # nodejs: JS actions (checkout) run inside the job container on Forgejo + - name: System deps + run: | + apt-get update + apt-get install -y --no-install-recommends nodejs git xvfb xauth fonts-dejavu-core + - uses: actions/checkout@v4 + - name: Install dependencies + run: pip install -r requirements.txt + - name: Unit tests (headless) + run: env -u DISPLAY python -m unittest -v + - name: GUI canary (broken Tk or broken gui module must fail, not skip) + run: xvfb-run -a -s "-screen 0 1920x1200x24" python -c "import tkinter, customtkinter, gui; tkinter.Tk().destroy()" + - name: GUI suites (Xvfb, skips are failures) + timeout-minutes: 20 + env: + CACHET_REQUIRE_GUI: "1" + PYTHONFAULTHANDLER: "1" # with timeout -s ABRT: a stalled suite dumps its stacks + run: xvfb-run -a -s "-screen 0 1920x1200x24" timeout -s ABRT 900 python -m unittest -v -k Gui diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c91f91..e467171 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,6 +23,9 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} + # A stalled Tk suite or build must not hold the runner (and, for a + # release, its concurrency group) for GitHub's 6-hour default. + timeout-minutes: 45 steps: - uses: actions/checkout@v4 @@ -35,37 +38,72 @@ jobs: # poppler-utils: only to enable a future smoke-test of the GUI preview; # not bundled into the binary (runtime dependency on the user's side). + # xvfb/xauth + Tcl/Tk: the virtual display and the Tk runtime of the GUI + # suites below. - name: Linux system deps if: runner.os == 'Linux' - run: sudo apt-get update && sudo apt-get install -y poppler-utils + run: sudo apt-get update && sudo apt-get install -y poppler-utils xvfb xauth libtk8.6 libtcl8.6 - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt -r requirements-build.txt - # Headless: the GUI tests skip without a display. Linux only — on the - # Windows runner Tk could open real windows and hang the job. - - name: Unit tests + # Tests run on Linux only — on the Windows runner Tk could open real + # windows and hang the job. Three steps: the headless suite (the Gui* + # classes skip themselves without a display), a canary, then the Gui* + # suites under Xvfb — the end-to-end layer of this Tk app. + - name: Unit tests (headless) if: runner.os == 'Linux' - run: python -m unittest -v + run: env -u DISPLAY python -m unittest -v + + # The canary imports gui on purpose: the display guard of the GUI tests + # swallows an ImportError / NameError / SyntaxError of gui.py exactly + # like a missing display. + - name: GUI canary (a broken Tk or a broken gui module must fail, not skip) + if: runner.os == 'Linux' + env: + XMODIFIERS: "@im=none" + run: xvfb-run -a -s "-screen 0 1920x1200x24" python -c "import tkinter, customtkinter, gui; tkinter.Tk().destroy()" + + # CACHET_REQUIRE_GUI=1 turns the guard's skip into a failure, so "GUI + # suites green" can never mean "everything skipped". + - name: GUI suites (Xvfb, skips are failures) + if: runner.os == 'Linux' + timeout-minutes: 20 + env: + XMODIFIERS: "@im=none" + CACHET_REQUIRE_GUI: "1" + PYTHONFAULTHANDLER: "1" # with timeout -s ABRT: a stalled suite dumps its stacks + run: xvfb-run -a -s "-screen 0 1920x1200x24" timeout -s ABRT 900 python -m unittest -v -k Gui - name: Build with PyInstaller run: pyinstaller --noconfirm --clean cachet.spec # Smoke-test WITHOUT a card: we generate the fixtures with the project's # generators (make_pdf writes a valid raw PDF; make_png a PNG), then we - # exercise the CLI binary's image mode end to end. We do NOT use Pillow's - # Image.save(".pdf"): its PDF writer requires the JPEG encoder, which is - # absent from some Pillow wheels (KeyError: 'JPEG'). eID mode requires - # hardware -> not tested here. - - name: Smoke test (CLI image mode, no eID hardware) + # exercise the CLI binary's visual signatures end to end: the legacy + # single image, a --text signature and a --signatures file. The last two + # prove that fonts/ and Pillow's FreeType renderer (PIL._imagingft) are + # in the CLI binary. We do NOT use Pillow's Image.save(".pdf"): its PDF + # writer requires the JPEG encoder, which is absent from some Pillow + # wheels (KeyError: 'JPEG'). eID mode requires hardware -> not tested + # here. + - name: Smoke test (CLI visual signatures, no eID hardware) shell: bash run: | python - <<'PY' + import json from test_sign_pdfs_beid import make_pdf, make_png - make_pdf("smoke.pdf", [(595, 842)]) + make_pdf("smoke.pdf", [(595, 842), (595, 842)]) make_png("sig.png") + with open("smoke_sigs.json", "w", encoding="utf-8") as fh: + json.dump([ + {"kind": "text", "text": "JD {date}", "font": "caveat", "font_size": 14, + "all_pages": True, "x": 500, "y": 20}, + {"kind": "image", "image_path": "sig.png", "width_pt": 120, + "page": 1, "x": 60, "y": 700}, + ], fh) print("fixtures written") PY CLI=$(ls dist/cachet-cli* | head -1) @@ -75,6 +113,12 @@ jobs: --output smoke_out --page 1 --x 100 --y 100 test -n "$(ls smoke_out/*.pdf 2>/dev/null)" || { echo "FAIL: no output PDF"; exit 1; } echo "OK: image mode works in the frozen binary." + "$CLI" --mode image --text "Jane Doe" --font great-vibes --color "#1A3FB4" \ + --input smoke.pdf --output smoke_text --page 1 --x 100 --y 100 + test -n "$(ls smoke_text/*.pdf 2>/dev/null)" || { echo "FAIL: no text-mode output"; exit 1; } + "$CLI" --mode image --signatures smoke_sigs.json --input smoke.pdf --output smoke_multi + test -n "$(ls smoke_multi/*.pdf 2>/dev/null)" || { echo "FAIL: no --signatures output"; exit 1; } + echo "OK: bundled fonts + text rendering work in the frozen binary." - name: Verify both binaries exist shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 24952ec..7f1723b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,6 +58,9 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} + # A stalled Tk suite or build must not hold the runner (and, for a + # release, its concurrency group) for GitHub's 6-hour default. + timeout-minutes: 45 steps: - uses: actions/checkout@v4 @@ -68,28 +71,65 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} cache: pip + # xvfb/xauth + Tcl/Tk: the virtual display and the Tk runtime of the GUI + # suites below. + - name: Linux system deps + if: runner.os == 'Linux' + run: sudo apt-get update && sudo apt-get install -y poppler-utils xvfb xauth libtk8.6 libtcl8.6 + - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt -r requirements-build.txt - # Gate the release on the test suite (Linux only: headless, the GUI - # tests skip without a display; on the Windows runner Tk could open - # real windows and hang the job). - - name: Unit tests + # Gate the release on the test suite (Linux only: on the Windows runner + # Tk could open real windows and hang the job). Same three steps as + # build.yml: headless suite (the Gui* classes skip themselves), a + # canary, then the Gui* suites under Xvfb. + - name: Unit tests (headless) + if: runner.os == 'Linux' + run: env -u DISPLAY python -m unittest -v + + # The canary imports gui on purpose: the display guard of the GUI tests + # swallows an ImportError / NameError / SyntaxError of gui.py exactly + # like a missing display. + - name: GUI canary (a broken Tk or a broken gui module must fail, not skip) if: runner.os == 'Linux' - run: python -m unittest -v + env: + XMODIFIERS: "@im=none" + run: xvfb-run -a -s "-screen 0 1920x1200x24" python -c "import tkinter, customtkinter, gui; tkinter.Tk().destroy()" + + # CACHET_REQUIRE_GUI=1 turns the guard's skip into a failure, so "GUI + # suites green" can never mean "everything skipped". + - name: GUI suites (Xvfb, skips are failures) + if: runner.os == 'Linux' + timeout-minutes: 20 + env: + XMODIFIERS: "@im=none" + CACHET_REQUIRE_GUI: "1" + PYTHONFAULTHANDLER: "1" # with timeout -s ABRT: a stalled suite dumps its stacks + run: xvfb-run -a -s "-screen 0 1920x1200x24" timeout -s ABRT 900 python -m unittest -v -k Gui - name: Build with PyInstaller run: pyinstaller --noconfirm --clean cachet.spec - - name: Smoke test (CLI image mode, no eID hardware) + # Legacy single image, then --text and --signatures: the last two prove + # that fonts/ and PIL._imagingft are in the CLI binary. + - name: Smoke test (CLI visual signatures, no eID hardware) shell: bash run: | python - <<'PY' + import json from test_sign_pdfs_beid import make_pdf, make_png - make_pdf("smoke.pdf", [(595, 842)]) + make_pdf("smoke.pdf", [(595, 842), (595, 842)]) make_png("sig.png") + with open("smoke_sigs.json", "w", encoding="utf-8") as fh: + json.dump([ + {"kind": "text", "text": "JD {date}", "font": "caveat", "font_size": 14, + "all_pages": True, "x": 500, "y": 20}, + {"kind": "image", "image_path": "sig.png", "width_pt": 120, + "page": 1, "x": 60, "y": 700}, + ], fh) print("fixtures written") PY CLI=$(ls dist/cachet-cli* | head -1) @@ -98,6 +138,12 @@ jobs: --output smoke_out --page 1 --x 100 --y 100 test -n "$(ls smoke_out/*.pdf 2>/dev/null)" || { echo "FAIL: no output PDF"; exit 1; } echo "OK: image mode works in the frozen binary." + "$CLI" --mode image --text "Jane Doe" --font great-vibes --color "#1A3FB4" \ + --input smoke.pdf --output smoke_text --page 1 --x 100 --y 100 + test -n "$(ls smoke_text/*.pdf 2>/dev/null)" || { echo "FAIL: no text-mode output"; exit 1; } + "$CLI" --mode image --signatures smoke_sigs.json --input smoke.pdf --output smoke_multi + test -n "$(ls smoke_multi/*.pdf 2>/dev/null)" || { echo "FAIL: no --signatures output"; exit 1; } + echo "OK: bundled fonts + text rendering work in the frozen binary." - name: Package (Linux) if: runner.os == 'Linux' diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..2ff107e --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,32 @@ +# GitLab CI: runs the test suites only. The standalone executables and the +# releases are built on GitHub Actions (.github/workflows/build.yml and +# release.yml); .forgejo/workflows/tests.yml is the Forgejo twin of this file. +# +# Three steps, as on GitHub: the headless suite, a GUI canary, then the +# guarded Gui* suites under Xvfb (the end-to-end layer of this Tk app). +stages: [test] + +variables: + PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip" + PIP_DISABLE_PIP_VERSION_CHECK: "1" + XMODIFIERS: "@im=none" # Tk must not wait on the ibus XIM bridge + +tests: + stage: test + timeout: 30m # a stalled Tk suite must not hold the runner + image: python:3.13-bookworm # full image: tkinter + libtk included + cache: + key: pip-py313 + paths: [.cache/pip] + before_script: + - apt-get update + - apt-get install -y --no-install-recommends xvfb xauth fonts-dejavu-core + - pip install -r requirements.txt + script: + # 1. headless: the Gui* suites skip themselves + - env -u DISPLAY python -m unittest -v + # 2. canary: a broken Tk OR a broken gui module must FAIL the job instead of silently skipping + - xvfb-run -a -s "-screen 0 1920x1200x24" python -c "import tkinter, customtkinter, gui; tkinter.Tk().destroy()" + # 3. guarded GUI suites (the e2e layer), one run, sequential; a skipped GUI test is a failure + # (timeout -s ABRT + faulthandler: a stalled suite dumps its stacks) + - CACHET_REQUIRE_GUI=1 PYTHONFAULTHANDLER=1 xvfb-run -a -s "-screen 0 1920x1200x24" timeout -s ABRT 900 python -m unittest -v -k Gui From af921c0847e3444551bc40e2f9067850db7a10f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Denooz?= Date: Wed, 7 Oct 2026 09:56:19 +0200 Subject: [PATCH 6/6] docs: document text signatures, multiple signatures and persistence --- BUILD.md | 80 ++++- CLAUDE.md | 957 +++++++++++++++++++++++++++++++++--------------------- README.md | 330 ++++++++++++++++--- 3 files changed, 948 insertions(+), 419 deletions(-) diff --git a/BUILD.md b/BUILD.md index c1f7c07..14bd111 100644 --- a/BUILD.md +++ b/BUILD.md @@ -54,18 +54,40 @@ This is the recommended route for a production deliverable: it produces a native ## 3. Windows — via GitHub Actions (CI, reproducible) The `.github/workflows/build.yml` workflow compiles **Windows + Linux** on the -GitHub runners on every `push`/tag, runs a smoke test (image mode, no card) and -publishes the binaries as artifacts. +GitHub runners (pushes to `develop`, pull requests, manual runs) and publishes +the binaries as artifacts. Before building, the Linux job runs the tests in +three steps: + +1. the **headless suite** (`env -u DISPLAY python -m unittest -v`; the `Gui*` + classes skip themselves); +2. a **GUI canary** under Xvfb — `import tkinter, customtkinter, gui` and a + `Tk()` window — so a broken Tk or a `gui.py` that no longer imports fails + the job instead of making every GUI test skip; +3. the **`Gui*` suites** under Xvfb with `CACHET_REQUIRE_GUI=1`, which turns + any remaining skip into a failure (they are the end-to-end layer of this + desktop app). + +After the build, a **smoke test** runs the frozen CLI without a card, on both +OSes: the legacy single image (`--image-path`), a text signature (`--text`) +and a `--signatures` file. The last two prove that the bundled fonts and +Pillow's FreeType renderer are in the CLI binary. ```bash -# once: push the repository to GitHub +# once: push the repository to GitHub (build.yml runs on `develop`; a push to +# `main` runs the release workflow instead — see "Release process" below) git remote add origin git@github.com:/.git -git push -u origin main +git push -u origin develop ``` Then: **Actions** tab → run → **Artifacts** → `cachet-windows-latest` / `cachet-ubuntu-latest`. Can also be triggered manually (*workflow_dispatch*). +**GitLab CI** (`.gitlab-ci.yml`) and **Forgejo Actions** +(`.forgejo/workflows/tests.yml`) run the same three test steps in a +`python:3.13-bookworm` container. They run the tests only: builds and releases +stay on GitHub. On Forgejo, adapt `runs-on: docker` to your instance's runner +label. + ## Release process (develop → main) Branch model: day-to-day work lands on **`develop`** (CI builds + tests every @@ -76,8 +98,10 @@ publishes a release** (`.github/workflows/release.yml`): truth — the CLI `--version` and the GUI title read it). 2. Open a PR `develop` → `main` and merge it. 3. The release workflow then: reads the version → checks the tag `v{version}` - does not already exist → runs the unit tests → builds **both** executables - on Windows AND Linux → smoke-tests the frozen CLI → packages + does not already exist → runs the tests (Linux: headless suite, GUI canary, + `Gui*` suites under Xvfb with `CACHET_REQUIRE_GUI=1`) → builds **both** + executables on Windows AND Linux → smoke-tests the frozen CLI (legacy + image, `--text`, `--signatures`) → packages `cachet-{v}-linux-x86_64.tar.gz` + `cachet-{v}-windows-x86_64.zip` → creates the tag and a **GitHub Release** with auto-generated notes and the two archives attached. @@ -133,7 +157,7 @@ These components are loaded dynamically and **cannot** be packaged: and the CAs' **OCSP/CRL** endpoints. `azure` mode additionally needs **`login.microsoftonline.com`** (Entra ID) and the **Key Vault URL**. Offline machines can only sign at `--pades-level b-b` in beid mode (or - stamp images); on failure the app names the unreachable endpoint and + stamp visual signatures); on failure the app names the unreachable endpoint and **never silently downgrades the level**. - **Azure per-user provisioning** (azure mode only) — each user needs a Key Vault key + certificate (internal CA) named after the key template @@ -144,8 +168,27 @@ The GUI's **page preview** (step 6) is rendered by **pypdfium2** (PDFium engine `poppler` (`pdftoppm`) is now only an **optional fallback** used only if it is already present on the machine (see `core.render_page_image`). -The **image mode** depends on none of these components: it is fully functional -and testable without hardware. +**Bundled fonts** — the six OFL fonts of the text signatures (`fonts/*.ttf`) +and their licence texts (`fonts/licenses/`, which the OFL requires to travel +with the fonts) are bundled in **both** binaries (`common_datas` in +`cachet.spec`): the CLI stamps text too. `stamps.asset_path` finds them next +to the module in a checkout and under `sys._MEIPASS` in a frozen binary. A +font the user designates by path (`.ttf`/`.otf`) is read from that path at +run time and is never bundled. + +**User profile** (GUI only — the CLI never reads it) — the GUI keeps the +signature library, the last placements and the wizard settings in +`profile.json` under the user config dir, and a copy of the imported/drawn +images in `signatures/` under the user data dir (Linux: `~/.config/Cachet/` +and `~/.local/share/Cachet/`; Windows: `%LOCALAPPDATA%\Cachet\` for both; +macOS: `~/Library/Application Support/Cachet/` for both). Override with +`CACHET_CONFIG_DIR` / `CACHET_DATA_DIR`. The files are **unencrypted** and +never contain a PIN, a token or any other credential. Nothing has to be +installed or created beforehand: the folders appear at the first save. + +The **visual signatures** (image mode, and the stamps added in beid/azure +mode) depend on none of the components listed above: they are fully +functional and testable without hardware or network. --- @@ -169,6 +212,8 @@ and testable without hardware. | GUI: `Can't find a usable init.tcl` / empty window | Tcl/Tk data not collected | rebuild with a Python that has a complete `tkinter`; the `_tkinter` hook collects it into `_tcl_data`/`_tk_data` | | GUI: `FileNotFoundError` on a `.json` theme | missing customtkinter assets | make sure `pyinstaller-hooks-contrib` is installed (it is); the spec also does `collect_all('customtkinter')` | | `ModuleNotFoundError: pkcs11._pkcs11` | native extension not bundled | already handled (`collect_dynamic_libs('pkcs11')` + hiddenimport); check the build log | +| Text signature: `cannot load font '…': cannot open resource` / `bundled font file missing: …` | `fonts/` not in the bundle | check that `common_datas` in `cachet.spec` still carries `("fonts/*.ttf", "fonts")` (it must be in the **common** list, not only the GUI's) and that `fonts/` is present in the checkout | +| Text signature: `The _imagingft C module is not installed` | Pillow's FreeType renderer not bundled | `PIL._imagingft` must stay in `common_hidden` (`cachet.spec`); check the build log | | `ZoneInfoNotFoundError` at signing time **on Windows** | zoneinfo database missing | `tzdata` (installed via `requirements-build.txt` on Windows; collected by the spec) | | OpenSSL error from `oscrypto` | version parsing on certain OpenSSL builds | not triggered by this app's image/eID modes (the Linux trust-list reads PEM files); otherwise `pip install` a fixed oscrypto or pyhanko-certvalidator ≥ 0.41 | | `beid mode` "fails" on a clean machine | eID middleware/reader/card missing | **expected**: install the eID middleware (see above); this is not a packaging bug | @@ -195,6 +240,18 @@ test on real hardware** before distribution: 4. Cross-check with the pyHanko CLI: `pyhanko sign validate --pretty-print --ltv-profile pades-lta ` must report the expected level and a sound timestamp chain. +5. **Visual signatures + eID signature.** Sign a multi-page PDF with the card + AND two visual signatures, one of them on every page (`--mode beid + --signatures sigs.json`, or the GUI's step 6), at B-LTA. In Adobe Acrobat + Reader the signature must be valid, "LTV enabled", and must **not** report + that the document was modified after signing: the visual signatures are + stamped before the signature, in the same revision. +6. **Already-signed input.** Take the output of step 5 and + (a) countersign it with the card, with another field base name + (`--field Countersign`) and **no** visual signature — both signatures must + be valid in Acrobat; (b) try again **with** a visual signature — Cachet + must refuse the document (`the document is already signed…`) **before** + asking for the PIN, and write nothing. Reminder: with the default **free TSA** the timestamps are technically valid but **not qualified**; for eIDAS-qualified preservation, run the acceptance @@ -218,6 +275,11 @@ path must be validated manually against a provisioned tenant: 5. Negative check: pass `--azure-key-name ` — the run must print the override warning, and Key Vault must deny the `sign` operation unless your account was explicitly granted it. +6. Visual signatures: repeat step 1 with `--signatures sigs.json` (two visual + signatures, one on every page). Acrobat must show the signature as valid + and must **not** report a modification after signing. Then run it again on + that signed output: Cachet must refuse the document + (`the document is already signed…`) and write nothing. Reminder: azure mode produces an **advanced** signature (AES) with the internal CA — appropriate for internal documents, not a qualified (QES) diff --git a/CLAUDE.md b/CLAUDE.md index 0284dd9..b2bd5b1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,316 +4,455 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## What this is -A batch PDF-signing app for Belgian electronic identity cards (eID), with two -signature modes, template-based input validation, and a CustomTkinter GUI that +A batch PDF-signing app for Belgian electronic identity cards (eID), with +three modes, template-based input validation, and a CustomTkinter GUI that wraps the same logic as the headless CLI. -- **`beid` mode** — cryptographic eID signature (pyHanko over the eID PKCS#11 - middleware), with a visible **vignette** (cardholder photo + "Signed by:" / - name / date) bottom-right of the last page. Signatures are **PAdES, - default level B-LTA** (timestamp + embedded revocation info + archival - timestamp chain), selectable via `--pades-level`; levels ≥ b-t need network. -- **`azure` mode** — personal **AES (advanced, not qualified)** signature with - the signed-in user's own certificate + non-exportable key in **Azure Key - Vault**, after ONE interactive Microsoft Entra ID login per batch. Only the - digest is sent to Azure. Reuses the PAdES level pipeline; LTV trust comes - from the **internal CA chain** (`--azure-trust-anchors`), NEVER the EU LOTL. -- **`image` mode** — stamps a user-supplied image onto a chosen page at a chosen - position. See the design note below: **image mode does NOT use the card** and - is not a cryptographic signature; it is the alternative to `beid`. - -No build system, no linter config. Tests use stdlib `unittest`. -Code comments and CLI text are in English; the GUI is **localized** -(EN/FR/NL/DE/ES/PT) through `i18n.py` — every user-visible GUI string goes -through `i18n.tr(key, **fmt)`, never a hard-coded literal. +- **`beid`** — cryptographic eID signature (pyHanko over the eID PKCS#11 + middleware) with a visible **vignette** (cardholder photo + "Signed by:" / + name / date), bottom-right of the last page by default. **PAdES, default + level B-LTA** (`--pades-level`); levels ≥ b-t need network. +- **`azure`** — personal **AES (advanced, not qualified)** signature with the + signed-in user's certificate + non-exportable key in **Azure Key Vault**, + after ONE Microsoft Entra ID login per batch. LTV trust comes from the + **internal CA chain** (`--azure-trust-anchors`), NEVER the EU LOTL. +- **`image`** — **visual signatures only**: typed texts, images or hand-drawn + signatures stamped on chosen pages. **No card**, not a cryptographic + signature. (Name kept for backward compatibility.) + +`beid`/`azure` can carry the same N **visual stamps** (`RunConfig.stamps`) +plus exactly ONE cryptographic signature per document. The GUI **persists** +the signature library, placements and wizard settings in a user profile +(`profile_store.py`); the CLI never reads it. + +Vocabulary trap: "visual signature" (user wording) = `Stamp` (`stamps.py`). +The older `_STAMP_*` constants and `build_stamp_style` in the core mean the +**vignette** of the cryptographic signature and were NOT renamed. + +No build system, no linter config; tests use stdlib `unittest`. Comments and +CLI text are in English; the GUI is **localized** (EN/FR/NL/DE/ES/PT): every +GUI string goes through `i18n.tr(key, **fmt)`, in ALL six languages. ## Modules -- `sign_pdfs_beid.py` — **core + CLI entry point**. All business logic lives - here (eID signing, vignette, image insertion, validation, placement math, - `RunConfig`/`process_batch`, arg parsing). Imports cleanly **without tkinter**. -- `gui.py` — CustomTkinter GUI: a **landing page + 8-step wizard** (see "GUI - workflow"). Imported **only** when `--gui` is passed (lazy), so the - CLI/core/tests never require a display. It is a thin façade over the core; - all non-widget logic it needs is imported from the core, all its text from - `i18n.py`. -- `i18n.py` — GUI localization: `LANGUAGES` (en/fr/nl/de/es/pt), - `tr(key, **fmt)`, `set_language`, `system_language` and the UI `CATALOG` - (key → per-language strings). Texts may carry a light **`**bold**`** - markup; `split_markup(text)` (pure) turns it into `(segment, is_bold)` - pairs that the GUI renders through a text tag. `DOC_SECTIONS` / - `DOC_SOURCES` (title key → URL) drive the "Full documentation" popup. - Import-safe **without tkinter**; `test_i18n.py` enforces that every key - exists in every language, that placeholders match the English reference, - that bold markers are balanced with the same count per language, and that - the documentation is genuinely translated — add new GUI strings in ALL - six languages. -- `i18n_docs.py` — the long-form documentation of the popup (`DOCS_CATALOG`: - `docs.modes/levels/tiers/glossary/glance`, `docs.sources_*`, `docs.src.*` - link titles) in six languages, merged into `i18n.CATALOG` at import so - `tr()` and the test invariants cover it. Kept apart so `i18n.py` stays - readable; bundled into the GUI binary through the import chain. -- `trust.py` — EU trusted-list (LOTL, ETSI TS 119 612) trust provider for LTV: - LOTL → Belgian list → granted CA/QC-for-eSignatures certs as - `ValidationContext` anchors; JSON cache under `platformdirs` (24 h TTL, - `--refresh-trust-list`); raises actionable `TrustListError` offline. - Import-safe without tkinter; network injectable (`fetcher=`) for tests. - **beid-mode only** (azure uses the internal CA instead). -- `azure_signer.py` — azure mode: Entra credential factory + process-wide - cache (`get_cached_credential` — one login per batch, shared with the GUI - sign-in), token-claims user resolution (UPN/oid, decoded locally, never - logged), per-user key/cert name template (`sig-{upn}`, sanitised; explicit - override flagged), `AzureKeyVaultSigner` (pyHanko `Signer`: hashes locally, - sends ONLY the digest to `CryptographyClient.sign`, maps key type + - `--digest` to RS256/…/ES256/…, converts ECDSA r||s → DER). Azure SDK - imports are lazy; clients injectable for tests. -- `test_sign_pdfs_beid.py`, `test_trust.py`, `test_azure.py`, `test_i18n.py` - — headless `unittest` suites (no card, no network; the `Gui*` classes need - a display and skip themselves otherwise). -- `pdfs/` (`../pdfs`), `signes/` (`../signes`) — sample inputs / output dir. -- `venv/` — Python virtualenv (see "tkinter in this environment"). +- `sign_pdfs_beid.py` — **core + CLI entry point** (signing, vignette, + validation, placement math, `RunConfig`/`process_batch`, arg parsing). +- `stamps.py` — visual signatures: the frozen `Stamp` dataclass, bundled + fonts, text / freehand rendering, image normalisation, `stamp_content` (THE + single source of pixels + size for the PDF and the GUI preview), validation, + the `--signatures` JSON, `apply_stamps(writer, …)`. Every failure is a + `StampError` (a `ValueError`). +- `profile_store.py` — the GUI's user profile (see "Persistence"). +- `gui.py` — CustomTkinter **landing page + 8-step wizard**, imported + **only** with `--gui` (lazy), so the CLI/core/tests never need a display. +- `i18n.py` — `tr`, `set_language`, `system_language`, the UI `CATALOG`; + texts may carry a light `**bold**` markup (`split_markup`). `i18n_docs.py` + holds the long documentation-popup texts, merged into the catalog at + import. `test_i18n.py` enforces: every key in all six languages, + placeholders matching English, balanced bold markers with equal counts. +- `trust.py` — EU trusted-list (LOTL, ETSI TS 119 612) anchors for LTV: LOTL → + Belgian list → CA/QC-for-eSignatures certs; JSON cache (24 h TTL, + `--refresh-trust-list`); actionable `TrustListError` offline; network + injectable (`fetcher=`). **beid only**. +- `azure_signer.py` — Entra credential + process-wide cache + (`get_cached_credential`: one login per batch, shared with the GUI sign-in), + user from token claims (decoded locally, never logged), per-user key/cert + name template (`sig-{upn}`; explicit override flagged), + `AzureKeyVaultSigner` (hashes locally, sends ONLY the digest, ECDSA r||s → + DER). Azure SDK imports are lazy; clients injectable for tests. +- `test_*.py` — headless suites (no card, no network); the `Gui*` classes + skip themselves without a display. + +Import graph (no cycles — keep it that way): + +``` +stamps -> stdlib, PIL, pyhanko (nothing of this app) +profile_store -> stdlib, stamps, platformdirs (lazy) +sign_pdfs_beid -> stamps (NEVER profile_store) +gui -> sign_pdfs_beid, stamps, profile_store, i18n +``` + +- Only `gui.py` / `gui_main.py` need tkinter. `stamps` and + `profile_store` never import the core: it is the CLI entry script + (`__main__`), a module importing it would load it twice. +- The core never imports `profile_store`: headless runs stay deterministic. +- Name shadowing: `stamps` is also a `RunConfig` field and a `sign_one` + keyword, so the core imports **names** (`from stamps import Stamp, …`); + `gui.py` and `profile_store.py` use `import stamps as stamplib`. ## Commands ```bash -# eID signing (vignette), new flat flags — PAdES B-LTA by default: +# eID signing (PAdES B-LTA by default); legacy positionals still work: ./venv/bin/python sign_pdfs_beid.py --input ../pdfs --output ../signes --mode beid - -# eID signing, offline basic level; legacy positional form (still supported) -./venv/bin/python sign_pdfs_beid.py ../pdfs ../signes --pades-level b-b - -# azure mode (personal Key Vault cert; one Microsoft login per batch): -./venv/bin/python sign_pdfs_beid.py --mode azure \ - --azure-vault-url https://myorg-sign.vault.azure.net \ - --azure-trust-anchors ./internal-ca-chain.pem \ +./venv/bin/python sign_pdfs_beid.py ../pdfs ../signes --pades-level b-b # offline + +# azure mode (one Microsoft login per batch): +./venv/bin/python sign_pdfs_beid.py --mode azure --azure-vault-url https://x.vault.azure.net \ + --azure-trust-anchors ./internal-ca-chain.pem --input ../pdfs --output ../signes + +# visual signatures, no card: one text (or --image-path img.png) / a JSON list +./venv/bin/python sign_pdfs_beid.py --mode image --template ../pdfs/MODELE.pdf \ + --text "Jane Doe\nApproved, {date}" --font great-vibes --color "#1A2B8C" \ + --page last --x 360 --y 120 --input ../pdfs --output ../signes +# --signatures also works with --mode beid|azure (stamped BEFORE the signature): +./venv/bin/python sign_pdfs_beid.py --mode image --signatures sigs.json \ --input ../pdfs --output ../signes -# image stamp (no card), with template validation: -./venv/bin/python sign_pdfs_beid.py --mode image \ - --template ../pdfs/MODELE.pdf --input ../pdfs --output ../signes \ - --image-path signature.png --page 1 --x 360 --y 150 - -# GUI: +# GUI — it loads and AUTO-SAVES the user profile: for development export +# CACHET_CONFIG_DIR / CACHET_DATA_DIR to scratch folders first. ./venv/bin/python sign_pdfs_beid.py --gui -# Tests (headless, no card): -./venv/bin/python -m unittest -v +# Tests, headless (the Gui* classes skip themselves): +env -u DISPLAY ./venv/bin/python -m unittest -v +# GUI suites — ONE run at a time; skips are failures with CACHET_REQUIRE_GUI=1 +# (no xvfb-run on this workstation: use DISPLAY=:0 instead of `xvfb-run -a`): +CACHET_REQUIRE_GUI=1 XMODIFIERS=@im=none PYTHONFAULTHANDLER=1 timeout -s ABRT 900 \ + xvfb-run -a ./venv/bin/python -m unittest -v -k Gui -# Syntax check everything: -./venv/bin/python -m py_compile sign_pdfs_beid.py gui.py gui_main.py trust.py azure_signer.py i18n.py i18n_docs.py test_sign_pdfs_beid.py test_trust.py test_azure.py test_i18n.py +# Syntax check everything (all modules and tests sit at the repo root): +./venv/bin/python -m py_compile *.py ``` -### CLI flags - -| flag | meaning | -|------|---------| -| `--gui` | launch the GUI; otherwise run headless. Running without `--gui` never opens a window. | -| `--input ` | files and/or directories to process (dirs are globbed for `*.pdf`). | -| `--output

` | output folder; files are written `{stem}_signe.pdf`, **never overwriting** (collisions get ` - 1`, ` - 2`, …). | -| `--template ` | model PDF; if given, inputs are validated against it (CLI **and** GUI). | -| `--mode beid\|image\|azure` | signature mode (default `beid`). | -| `--azure-vault-url` / `--azure-key-name` / `--azure-key-name-template` / `--azure-cert-name` / `--azure-auth` / `--azure-trust-anchors` / `--azure-graph` | azure mode config; each falls back to its `CACHET_AZURE_*` env var. Vault URL required; key derived per-user from the template (default `sig-{upn}`; explicit override flagged); auth `interactive`/`device-code` (CLI default)/`default` (CI only, breaks per-user model); trust anchors = internal CA PEM/DER file-or-dir, required when LTV/verification needs them. | -| `--image-path ` | image to stamp (**required** for `--mode image`). | -| `--page ` | target page. A number is **1-based**; `first`/`last` (→ `RunConfig.page_anchor`) are resolved **per document** (index 0 / -1) and, with `--template`, accept files whose page count differs from the template (see validation rules). Image: insertion page. beID: vignette page (with `--x/--y`; with `first`/`last` and no position the default bottom-right vignette moves to that page). | -| `--x --y ` | lower-left position, points from the page's bottom-left. Image: image corner. beID: vignette corner — **omit both → default bottom-right of last page**. | -| `--pades-level {b-b,b-t,b-lt,b-lta}` | PAdES baseline level, **default `b-lta`**. b-t+ needs a TSA; b-lt+ embeds OCSP/CRL (LTV) using EU-trusted-list anchors. Never silently downgraded on network failure. | -| `--timestamp-url` / `--trust-list-url` | RFC 3161 TSA and EU LOTL overrides. Precedence: flag > env (`CACHET_TSA_URL` / `CACHET_LOTL_URL`) > default (DigiCert free TSA / official EU LOTL). Free TSA = technically valid but NOT qualified timestamps. | -| `--digest {sha256,sha384,sha512}` | digest, pinned as `md_algorithm` (default sha256). | -| `--no-verify` | skip post-signing self-verification (levels ≥ b-t); also skips the trusted-list fetch at b-t. | -| `--refresh-trust-list` | bypass the 24 h LOTL cache. | -| `--pades` | deprecated no-op alias (warns); PAdES is the default now. | -| `--legacy-cms` | deprecated; old `adbe.pkcs7.detached` path, only combinable with level b-b. | -| `--lib` / `--field` | eID options (as before): PKCS#11 lib path, field name. | - -Backward compatibility: `--input`/`--output` take precedence; if absent, the -legacy positional form `inputs… output_dir` is used. `resolve_config()` does -this resolution and `validate_config()` rejects bad combos (e.g. `image` mode -without `--image-path`). Both are pure and unit-tested. +### CLI flags (the non-obvious parts; `--help` has the full list) + +- Without `--gui` no window is ever opened. +- `--input` takes files and/or directories (globbed for `*.pdf`); `--output` + writes `{stem}_signe.pdf` and **never overwrites** (` - 1`, ` - 2`, …). + If both are absent the legacy positional form `inputs… output_dir` is used. +- `--page `: a number is **1-based**; `first`/`last` + (→ `RunConfig.page_anchor`) are resolved **per document**. `--x/--y`: + lower-left corner in points. In beid/azure they place the vignette — + **omit both → default bottom-right box** (on the last page, or on the + anchor page with `--page first|last`). +- `--signatures `: JSON **list** of visual signatures, in EVERY + mode. UTF-8 (BOM accepted); relative `image_path` / font paths resolve + against the JSON file's directory; unknown keys ignored; `"enabled": false` + entries skipped. +- `--text` (+ `--font`, `--color`, `--font-size`, which need it): ONE text + signature, **image mode only**; the two characters `\n` become a newline. + `--image-path`: ONE image (legacy, 150 pt wide), mutually exclusive with + `--text`, silently ignored in beid/azure (as before). +- `--pades-level {b-b,b-t,b-lt,b-lta}`, default `b-lta`: b-t+ needs a TSA, + b-lt+ embeds OCSP/CRL. Never silently downgraded on network failure. + `--no-verify` skips the post-signing self-verification (and the + trusted-list fetch at b-t). +- `--timestamp-url` / `--trust-list-url`: flag > env (`CACHET_TSA_URL` / + `CACHET_LOTL_URL`) > default (DigiCert free TSA — valid but NOT qualified + timestamps — / official EU LOTL). +- `--azure-*`: each falls back to its `CACHET_AZURE_*` env var. `--azure-auth` + `default` is for CI only (it breaks the per-user model); trust anchors + (internal CA PEM/DER file or directory) are required when LTV/verification + needs them. +- Deprecated: `--pades` (no-op, warns); `--legacy-cms` (old + `adbe.pkcs7.detached`, level b-b and beid only). + +`resolve_config()` / `validate_config()` are pure (they read files, never +write). + +**Who owns `--page/--x/--y`**: in image mode the single *convenience* stamp +(`--text`, or the legacy `--image-path`); in beid/azure the **vignette**. The +entries of `--signatures` carry their own placement, so in image mode +`--page/--x/--y` with `--signatures` alone is an error. `--signatures` is +additive with at most one convenience stamp, which comes FIRST. The legacy +image is NOT put in `cfg.stamps`: `image_path/page/x/y/page_anchor` stay +populated as before and `effective_stamps(cfg)` turns them into the first +stamp. `--font-size` is tested with `is not None`: an explicit 0 is rejected, +not replaced by the default. + +`main()` reconfigures stdout/stderr with `errors="backslashreplace"`: texts +and file names are echoed, and redirected output on Windows is the ANSI code +page — a character outside it must not kill the run before any document. ## Shared core: `process_batch` -Both the CLI (`main`) and the GUI call `process_batch(cfg: RunConfig, on_progress=…)`: -1. If `cfg.template` is set, read its per-page dimensions once. -2. For `beid` mode, open **one** PKCS#11 session, build `BEIDSigner`, read the - identity once (no PIN), and build the network material once via - `build_signing_material(cfg)` → `SigningMaterial` (an `HTTPTimeStamper` - for levels ≥ b-t; trust anchors + a fetching `ValidationContext` for - b-lt/b-lta — anchors are passed as `extra_trust_roots` because pyHanko - validates the TSA chain against the same context). The trust source is - **mode-dependent**: beid → EU LOTL (`trust.py`); azure → internal CA - (`load_trust_anchor_certs`). A `TrustListError`/`ValueError` here fails - the whole batch — the level is NEVER silently downgraded. - For `azure` mode the setup-once path is: `get_cached_credential` → - `acquire_user` (ONE login per batch) → `resolve_key_names` → - `build_azure_signer` → `read_cert_identity` (vignette name from the cert - subject or Graph displayName; `photo=None`). -3. Per input: validate against the template (if any) → reject+report on failure; - else `sign_one()` (beid) or `insert_image_one()` (image). Returns a - `DocResult` per file (`ok`, `detail`). `on_progress` fires per document so - the GUI can stream rows into its summary table. -4. beid + levels ≥ b-t (unless `--no-verify`): `verify_signed_pdf()` re-opens - the output, validates it (pyHanko validation API + EU anchors) and detects - the **achieved** level structurally (timestamp → b-t, DSS revinfo → b-lt, - doc-timestamp → b-lta); the result lands in `DocResult.detail` - (e.g. `PAdES-B-LTA, LTV ok`); `SelfVerificationError` ⇒ document FAILED. +Both the CLI and the GUI call `process_batch(cfg, on_progress=…, today=…)`: +1. Resolved ONCE per batch: the template's page dimensions; + `effective_stamps(cfg)`; ONE run date for `{date}` (`today`, injectable); + ONE cache of stamp content; `anchor_requirements(cfg)`. +2. `beid`: **one** PKCS#11 session, `BEIDSigner`, identity read once (no PIN), + network material built once by `build_signing_material(cfg)` (an + `HTTPTimeStamper` for levels ≥ b-t; trust anchors + a fetching + `ValidationContext` for b-lt/b-lta — anchors go in `extra_trust_roots` + because pyHanko validates the TSA chain against the same context). Trust + source is **mode-dependent**: beid → EU LOTL; azure → internal CA + (`load_trust_anchor_certs`). A `TrustListError`/`ValueError` here fails the + whole batch — the level is NEVER silently downgraded. + `azure`: `get_cached_credential` → `acquire_user` (ONE login) → + `resolve_key_names` → `build_azure_signer` → `read_cert_identity` + (`photo=None`). +3. Per input: validate against the template (if any) → reject+report; else + `sign_one(…, stamps=, stamp_date=, stamp_cache=)` (beid/azure) or + `apply_stamps_one()` (image). One `DocResult` (`ok`, `detail`) per file; + `on_progress` fires per document. Any `StampError` (bad page, unreadable + image, font, oversized text, already-signed input) fails THAT document + (`failed — …`, no output file) and the batch continues. +4. beid/azure, levels ≥ b-t (unless `--no-verify`): `verify_signed_pdf()` + re-opens the output, validates it and detects the **achieved** level + structurally (timestamp → b-t, DSS revinfo → b-lt, doc-timestamp → b-lta); + `SelfVerificationError` ⇒ document FAILED. The level → `PdfSignatureMetadata` mapping is the pure -`signature_meta_kwargs(level, digest, legacy_cms=…, validation_context=…)` -(unit-tested for all four levels + legacy CMS). - -The **same** image/vignette + page + (x, y) is applied to every document — -validation guarantees the files are geometrically identical, so one placement -fits all. With `cfg.page_anchor` (`"first"`/`"last"`, exclusive with -`cfg.page`) the page is resolved **per document** (`anchor_page_index`: 0 / --1) and validation only pins the anchor page, so page counts may differ. -Output paths come from `unique_output_path()`: `{stem}_signe.pdf`, -then `{stem}_signe - 1.pdf`, ` - 2`, … on collision — **existing files are never -overwritten**. +`signature_meta_kwargs(…)`. + +**Visual signatures in the core.** The legacy `RunConfig` fields keep their +meaning — in beid/azure `page/x/y/page_anchor` place the VIGNETTE, in image +mode (with `image_path`) they describe one legacy image stamp. Exactly two +writers of stamps, no third one: +- `sign_one(…, stamps=…)` — beid/azure: `apply_stamps(writer, …)` then + `sign_pdf(writer)` on the SAME writer (workaround 4). +- `apply_stamps_one(src, dst, stamp_list, …) -> bool` — image mode: ONE + incremental update, `dst` written only when everything succeeded; an empty + list is an error, never a silent no-op; returns True when the input was + already signed. + +The **same** elements (vignette and/or stamps, each with its own page target +and (x, y)) are applied to every document — validation guarantees the files +are geometrically identical, so one placement fits all. A page anchor +(`cfg.page_anchor` for the vignette, `Stamp.page_anchor` for a stamp; +exclusive with a page number) is resolved **per document** +(`anchor_page_index`: 0 / -1), so page counts may differ. ## Template validation rules `validate_against_template(template_dims, pdf)` rejects a file unless it has **(a)** the same page count and **(b)** EXACTLY identical per-page dimensions — -exact float equality of `(width, height)` from each page's MediaBox, **no -tolerance**. Failures are returned as `ValidationResult(ok=False, reason=…)` and -surfaced (CLI summary / GUI table); they are never silently signed. Dimensions -come from the MediaBox (inherited through the page tree); rotation is not -considered. - -With `page_anchor="first"|"last"` (CLI `--page first|last`, GUI validation-step -selector), a file whose **page count differs** from the template is accepted -**iff its anchor page exactly matches the template's anchor page** — that is -the page the signature lands on, so the chosen (x, y) is guaranteed to fit it. -Files with the template's page count keep the full strict check; a count -mismatch whose anchor page differs is rejected with both facts in the reason. -Accepted mismatches carry an informative `reason` ("N page(s), the template -has M — signed on the last page") even though `ok=True`. - -## Image placement convention - -`(x, y)` is the **lower-left** corner of the placed image, in PDF points from -the page's **bottom-left** corner (MediaBox origin is added internally, so it is -correct even for non-zero-origin MediaBoxes). Page numbers are **1-based** at the -CLI/GUI boundary and converted to pyHanko's 0-based (`-1` = last) internally. -The image is scaled to a fixed width `_IMG_TARGET_W_PT` (150 pt) preserving -aspect, with **no border** — `insert_image_one` sets `border_width=0` on the -`StaticStampStyle` (whose default is 3 pt black, which would frame the image). -The GUI and CLI share this convention exactly. An out-of-range `--page` is -reported as a clear per-document failure ("page N out of range…"), not a raw -pyHanko error. - -**beID vignette placement.** In `beid` mode, supplying `--x/--y` (or clicking in -the GUI) places the vignette on `--page` at that lower-left point, sized to a -**3:1 landscape box of width = page_w/5** (`vignette_size_pt`). With no position, -the vignette keeps its default bottom-right corner box -(`_default_vignette_box(writer, page_index)` — the last page by default, the -anchor page when `--page first|last` is set). -`build_stamp_style(identity, box_w, box_h)` makes the photo band proportional to -the box width (`_PHOTO_BAND_FRAC`, 0.2 → 42 pt for the default 210 pt box, -unchanged), so the same layout fits both the default box and the smaller placed -box without overflowing pyHanko's layout margins. - -Placement math is in pure, tkinter-free functions (`fit_frame`, -`frame_click_to_pdf_xy`, `pdf_rect_to_frame_rect`) so it is unit-tested and -reused by the GUI canvas. +exact float equality of each page's MediaBox `(width, height)` (inherited +through the page tree), **no tolerance**, rotation ignored. Failures come back +as `ValidationResult(ok=False, reason=…)` and are surfaced, never signed. + +A file whose **page count differs** is accepted **iff EVERY placed element +targets a page anchor** (`first`/`last`) **and each of those anchor pages +exactly matches the template's anchor page** — the pages the elements land +on, so the chosen positions fit. `anchor_requirements(cfg)` → `(anchors, +blocker)`: the anchors in use, ordered `("first", "last")`, and None or a +phrase naming the FIRST element that is not anchored (it ends up in the +rejection reason). Deliberate: in beid/azure the default bottom-right +vignette (no `--page first|last`) is NOT auto-anchored (`the vignette has no +first/last page target`) — a safety check is never relaxed silently. + +The GUI's step-3 `_validate` passes the single batch anchor as +`page_anchor=`; `process_batch` passes `anchors=` + `blocker=`. The GUI must +therefore hand the batch the SAME anchor for the vignette and every stamp, or +files shown as accepted at step 3 are rejected at run time. Accepted +mismatches carry an informative `reason` even though `ok=True`. + +## Stamp placement convention + +`(x, y)` is the **lower-left** corner of the placed element, in PDF points +(floats, never rounded) from the page's **bottom-left** corner — the MediaBox +origin is added per page inside `apply_stamps` (non-zero origins work). Page +numbers are **1-based** at the CLI/GUI/JSON boundary, 0-based (`-1` = last) +inside. A placed stamp has exactly ONE page target: `page`, `page_anchor` +(per document) or `all_pages`. An out-of-range page is a clear per-document +failure, not a raw pyHanko error. + +- **Image stamps**: scaled to `width_pt`. `load_image` normalises once (EXIF + orientation; any mode other than RGB/RGBA/L/LA → RGBA); the embedded + bitmap is capped at `IMAGE_MAX_DPI`. +- **Text stamps are rasters** (no font embedded, no shaping library): Pillow + at `TEXT_DPI` into a **tightly cropped** RGBA image, then the image + pipeline. `ImageFont.Layout.BASIC` is pinned so sizes do not depend on + raqm. Because of the crop, `(x, y)` is the corner of the INK box, and with + `{filename}` / `{date}` the box (and baseline) can vary per document. A + character the font lacks is drawn as a box or (Sacramento) not at all — + accepted limitation, in README. +- **Placeholders**: `resolve_text` replaces `{date}` (dd/mm/YYYY, run date) + then `{filename}` (source stem) with `str.replace` — never `str.format`. +- **`apply_stamps` paints the image XObject directly** (`w 0 0 h x y cm /Name + Do`), NOT through a pyHanko `StaticStampStyle`: pyHanko's `BoxConstraints` + truncates the box to whole points, so the PDF differed from the preview and + anything under 1 pt high (a `______` line) raised `ZeroDivisionError`. ONE + image per stamp, shared by its pages; a FRESH resource name per page (pages + may share one `/Resources`; pyHanko refuses a duplicate name); numbers via + `_pdf_number` (`%g` can emit an exponent, invalid in PDF). No border. +- **Every stamped page is `mark_update`d**: when `/Contents` is an indirect + array pyHanko updates the array only, and the `/Resources` it adds to the + page would never be written (invisible stamp, reported as success). Such + an array is first COPIED onto the page: pyHanko appends in place, and a + page sharing it would get the stamp too. A page without `/Contents` first + gets an empty stream (pyHanko raises `KeyError`). +- **No half-stamped writer**: pages and content are resolved for ALL stamps + before the first write. +- **Memory is bounded**: `text_layout` MEASURES (1×1 probe) and refuses a + text above `MAX_TEXT_PIXELS` BEFORE any allocation; `validate_stamp` runs + the same probe, so no entry point (CLI, JSON, dialog, hand-edited profile) + can trigger a huge raster. Freehand drawings: same budget. +- **Caching**: `stamp_content(stamp, cache=…)` keys on `content_key`; a text + with `{filename}` is never cached (unbounded growth over a batch). + +JSON schema (`--signatures` and profile entries, `Stamp.to_dict/from_dict`): +`kind`; text → `text`, `font`, `color`, `font_size`; image → `image_path`, +`width_pt`; then `page` | `page_anchor` | `all_pages: true`, `x`, `y`; +optional `enabled`. `from_dict` only type-checks (a `bool` is never a +number); `validate_stamp(stamp, placed=True)` checks content then placement, +`placed=False` content only. A relative font PATH is joined to the JSON +folder, but a bare word that is no file there stays as typed, so a mistyped +bundled id is reported as an id. + +**Vignette placement (beid/azure).** With `--x/--y` (or a click in the GUI) +it goes on `--page` at that point, sized to a **3:1 box of width page_w/5** +(`vignette_size_pt`). Without a position it keeps its default bottom-right +box (`_default_vignette_box`, from the pure `default_vignette_rect` that the +GUI also draws). `build_stamp_style(identity, box_w, box_h)` makes the photo +band proportional to the box width (`_PHOTO_BAND_FRAC`), so one layout fits +both boxes without overflowing pyHanko's layout margins. The canvas ↔ PDF +math is pure and tkinter-free (`fit_frame`, `frame_click_to_pdf_xy`, +`pdf_rect_to_frame_rect`). ## GUI workflow (`gui.py`) -`CachetApp` (a `ctk.CTk`) opens on a **landing page** (overview text, top -bar, Start bottom-right — no stepper there); Start builds the **wizard**. Both -screens share the same **top bar** (`_build_top_bar`): the brand on the left -(`logo.png` + "Cachet" — `_load_logo` caches a `CTkImage`, `_asset_path` -resolves the file next to `gui.py` or under `sys._MEIPASS` in the frozen -binary via `gui_datas` in cachet.spec; a missing logo degrades to the name -alone), and on the right the language selector (`_wizard_lang_menu` in the -wizard) with the **support link** to its right (`support.button` → -`_SUPPORT_URL`, the Stripe payment page, opened in the browser). The wizard -adds a stepper bar, a split body (form on the left inside a `CTkScrollableFrame`, -per-step contextual help `i18n` text on the right, rendered with -`_fill_textbox` so `**bold**` markup shows as bold), and a footer whose -Previous/Next labels **name the target step** (`nav.next`/`nav.previous`). -Cancel opens a confirm modal; confirming (and Finish on the last step) calls -`_reset_state()` and returns to the landing page. All texts come from -`i18n.tr`; the language defaults to `system_language()` and can be switched -at any step: `_on_wizard_language_change` sets the language, closes the -(language-bound) docs popup, then rebuilds the chrome and the current step -in place (`_build_wizard()` + `_goto_step(min(step, _first_incomplete()))`) -— state lives on the app, so nothing the user entered is lost. The selector -is disabled while a batch runs. - -The 8 steps (`_STEP_KEYS` → `_build_step_`): (1) template, (2) files, -(3) validation — auto-runs on first entry, pass/fail table, plus a localized -**first/last-page selector** (`anchor_row`, default "last") that appears only -when some files' page count differs from the template; it maps to -`RunConfig.page_anchor` for the whole batch and re-validates on change, -(4) output folder, (5) signature type (beid/azure/image radios + per-input -hints + **PAdES level selector**, default `b-lta`; azure panel appears only in -azure mode; the **"Full documentation" popup is localized**: `_show_docs_popup` -renders `i18n.DOC_SECTIONS` with bold markup, then `i18n.DOC_SOURCES` as -clickable links — `tag_bind` → `webbrowser.open`), (6) placement — when -`count_mismatch` is set, a **mirror of the step-3 first/last selector** sits -at the top (`place_anchor_row`, same shared `anchor_choice`, re-validates on -change and shows "N/M accepted" via `_update_place_anchor_widgets`), then the -page preview + click for **all** modes (image mode adds the image picker) -plus a manual **target-page field** (`page_text`) that follows the preview -when in range and only warns when beyond the template; while a page anchor -applies the field and Prev/Next are **disabled**, the preview is **locked** -onto the template's first/last page (label says "locked") and a position -clicked on another page is dropped (`_sync_anchor_page`) — `page` and -`page_anchor` stay mutually exclusive in the built `RunConfig`, (7) signing — -config summary (names the anchor when active), in beid mode a **green -"insert your eID card" box** (`card_box`, hidden by `_launch`, shown again by -`_show_card_box` when the batch fails to start), Start + progress bar, -(8) results report table + an **"Open output folder"** button -(`core.open_in_file_manager`: `os.startfile` / `open` / `xdg-open`; failures -are shown inline, never raised into the Tk loop). - -Step state drives the chrome (`_refresh_chrome`): per-step predicates -`_step_complete` / `_step_error` color the stepper chips — current = accent, -passed & clean = light-green border (`_COL_DONE`), problems = light-red -(`_COL_ERROR`, e.g. rejected files on step 3, missing azure vault/anchors on -step 5), reachable-pending = gray, beyond the first incomplete step = disabled -(`_COL_LOCKED`) — a step is never shown green just because its *defaults* are -valid. Next is enabled only while the current step **and every step before -it** are complete (`i < _first_incomplete()` — the step-6 selector can -re-validate step 3 down to zero accepted files); ALL navigation (stepper, -Prev/Next, Cancel, language selector) locks while `_running`. Editing upstream state -invalidates downstream results (`validation_results`, `run_results`) so the -gating recomputes. Step content is **rebuilt on every entry** (state lives on -the app, widgets are disposable) — update helpers guard widget access with -`_alive(...)`. - -Step 6's `tkinter.Canvas` shows the **actual rendered template page** as its -background (`core.render_page_image`: **pypdfium2** primary, `pdftoppm` fallback; -cached per page; falls back to a white frame only if both are unavailable). -Prev/Next change the preview page; a click sets the position AND syncs the -target-page field, drawing a to-scale placeholder — the image (image mode) or a -**3:1 box of width page_w/5** (beid/azure). The canvas **resizes with the -window**: `` on the toplevel → `_draw_page` recomputes the canvas -size from the window (`_canvas_target_size`) and refits the page, preserving -proportions (cached full-res page image is just rescaled, so no re-render on -resize). Tables use `rowheight=30` + an explicit font so full text lines show. - -Tkinter is **not thread-safe**, so the worker thread never touches widgets: it -pushes `("row"/"done"/"error", payload)` onto a `queue.Queue`, and the main -thread drains it via a periodic `self.after(100, self._poll_results)` (progress -bar + status on step 7; "done" auto-advances to the report). Calling -`self.after(...)` *from* the worker raises `main thread is not in main loop` — -do not reintroduce that. The worker catches `(Exception, SystemExit)`: -`open_eid_session()` raises **`SystemExit`** (no reader/card), which is *not* an -`Exception`, so a bare `except Exception` would let the worker die silently and -hang the GUI on "Processing…". `_poll_results` also no-ops if the -window was closed mid-batch. Guarded end-to-end tests (`GuiImageEndToEnd`, -`GuiWizardChrome`, …, skipped without a display) cover these paths. +`CachetApp` (a `ctk.CTk`) opens on a **landing page**; Start builds the +**wizard**: top bar, stepper, a split body (form in a `CTkScrollableFrame`, +per-step help), and a footer whose Previous/Next labels **name the target +step**. Cancel opens +`_confirm_modal` (shared with Delete — its button row must stay the window's +LAST child, a test finds the buttons that way); confirming (and Finish) calls +`_reset_state()`, which resets the SESSION only and RELOADS the profile — the +library and the settings are never wiped. + +Language: `launch_gui` applies the saved language, else `system_language()`; +`CachetApp.__init__` never changes it (tests build apps directly). A switch +closes the docs popup and any editor dialog (language-bound), then rebuilds +the chrome and the current step in place. + +The 8 steps (`_STEP_KEYS` → `_build_step_`): template, files, +validation, output folder, signature type, placement (the element editor), +signing, report. Step 3 auto-validates on first entry; its **first/last-page +selector** (`anchor_row`, default "last") appears only when some files' page +count differs from the template: ONE anchor for the whole batch, +re-validating on change. Step 7's "insert your eID card" box (beid) is hidden +by `_launch` and shown again by `_show_card_box` when the batch fails to +start. The step-3 and step-8 tables (`_make_table` / `_fill_table`) keep +their first columns fixed; the last one (detail) takes the remaining width, +follows the window and is never narrower than its longest text — a +horizontal scrollbar shows up only while that does not fit. + +**Step 6 — the element editor.** Elements = the vignette (beid/azure, id +`VIGNETTE_ID`) + the library `profile.signatures` (ids are 12 hex digits, so +never `"vignette"`). Top to bottom: a mirror of the step-3 selector when +`count_mismatch`; the navigation row at FULL width; then the +`elements_panel` (stacked add buttons, element list, actions) beside the +preview column (canvas, red `place_warn_lbl`). +- Selection happens in the LIST only; a canvas click always PLACES the + selected element (no hit-testing). +- Every library/placement mutation ends with `_commit_elements()` (save → + invalidate run → refresh); the helpers are `_alive`-guarded, so element + operations also work while step 6 is not built. +- **Placement is never destroyed** by a template or anchor change: an element + keeps its position plus `placed_on`, the `(w, h)` of the page it was placed + on; whether it is *in force* is a pure predicate (`_sig_placed`, + `_vignette_placed` → `profile_store`: exact page-size equality; under an + anchor the element must sit on the anchor's template page). Not in force = + "not placed", and it comes back when the template/anchor does. Code that + re-targets an element (e.g. unticking "On every page") must ask + `_sig_placed`, never "has coordinates", or a placement saved for another + page size is applied without a click. +- `_place_error()` (first problem or None): page field invalid or beyond the + template (BLOCKING), an enabled signature that cannot be rendered, image + mode without any enabled signature, an enabled signature not placed. + beid/azure with no enabled signature is complete without a click (default + vignette); disabled signatures never block. +- The page field is parsed with `str.isdecimal()`: `isdigit()` accepts "²" + (one key on AZERTY), `int()` rejects it, and the exception would hit every + navigation callback. `_sync_page_to_selection()` is the ONLY place deriving + `page_text` from an element; `_pick_template` empties the field. +- **Anchor lock** (page counts differ): the batch anchor forces EVERY element + onto each document's first/last page; the preview is locked on that + template page and no position is dropped. `_launch` rewrites every enabled + stamp to `page_anchor=anchor, page=None, all_pages=False` and passes + `page_anchor` for the vignette in beid/azure (None in image mode) — `page` + and `page_anchor` stay exclusive. `_launch` never passes `image_path`: + `cfg.stamps` = the enabled signatures; the legacy `page/x/y/page_anchor` + carry the VIGNETTE only. +- Layout contract at the default 1180 px window in every language (asserted + by a GUI test in `pt` and `nl`): nav row above the editor row, panel no + wider than `_ELEMENTS_PANEL_W` + 12 px, canvas inside the visible column. + +**Editor dialogs** (`_open_dialog`): ONE `self._dialog` at a time, a +non-blocking `CTkToplevel` with a delayed guarded `grab_set`, never +`wait_window`; closed on step change, reset and language switch; widgets are +`dlg_*` attributes, plain values live in `_dialog_state`. The footer (error +label + Cancel/Save) is packed FIRST from the bottom so it never leaves the +fixed-size window. Text dialog: live preview through `stamps.stamp_content`; +the "enter some text" error stays hidden until the user typed or tried to +save (`_dialog_state["edited"]`); editing KEEPS the placement. Draw dialog: +the strokes are the model, the canvas only their echo; points are clamped to +the canvas. An image that cannot be read or copied into the store is NOT +added — no fallback to the original file. A picker opened from a dialog gets +`parent=self._dialog`, and its handler re-checks `_alive(self._dialog)`. + +Chrome (`_refresh_chrome`): `_step_complete` / `_step_error` colour the +stepper chips — a step is never green just because its *defaults* are valid. +Next is enabled only while the current step **and every step before it** are +complete (the step-6 selector can re-validate step 3 down to zero accepted +files); ALL navigation locks while `_running`. Editing upstream state +invalidates downstream results. Step content is **rebuilt on every entry** +(state lives on the app, widgets are disposable): update helpers guard widget +access with `_alive(...)`. + +The step-6 canvas shows the **rendered template page** +(`core.render_page_image`: **pypdfium2**, `pdftoppm` fallback, white frame if +neither) and every element of that page to scale, the selected one LAST. +`_content(sig)` caches a thumbnail of `stamps.stamp_content` per +`content_key`; it runs inside `_refresh_chrome` on every navigation, so it +**never raises** (`except Exception`; the message is cached instead) and +never renders the same failing content twice. Every `ImageTk.PhotoImage` of a +draw is kept in the list `_canvas_imgs` (Tk only keeps a name). On resize +cached images are rescaled, never re-rendered. + +**Persistence hooks.** `CachetApp(args, store=None)`; `_save_profile()` never +raises (an `OSError` is shown as `place.save_failed`), runs on the main +thread only, and is called on every change. The vault URL is saved only on a +REAL edit of the entry (a focus-out must not turn the env/default value into +a saved choice). **`_loading` guard**: `_reset_state` sets the tk +variables from the loaded profile, which fires their traces — the save +handlers return at once while `_loading`, or a reset would write defaults +back over the saved settings. Loading precedence: saved choice > +`CACHET_AZURE_*` env > built-in default. A saved output folder / anchors file +is probed with `os.path.isdir/exists`, NEVER `Path.is_dir()/exists()`: pathlib +raises on EACCES / ENAMETOOLONG / an unreachable share, and the app could no +longer start. + +Tkinter is **not thread-safe**: the worker thread never touches widgets, the +profile or the GUI caches. It pushes `("row"/"done"/"error", payload)` onto a +`queue.Queue`, drained on the main thread by a periodic +`self.after(100, self._poll_results)` ("done" auto-advances to the report). +Calling `self.after(...)` *from* the worker raises `main thread is not in main +loop` — do not reintroduce that. The worker catches `(Exception, SystemExit)`: +`open_eid_session()` raises **`SystemExit`** (no reader/card), which is *not* +an `Exception`, so a bare `except Exception` would let the worker die silently +and hang the GUI on "Processing…". `_poll_results` no-ops if the window was +closed mid-batch. **CTkEntry + StringVar pitfall**: `CTkEntry.destroy()` (CustomTkinter 5.2.2) does NOT remove the trace it adds on its textvariable (radio buttons and option menus do). Since step content is rebuilt constantly, entry-backed state is kept in **plain strings** (`page_text`, `azure_vault`, `azure_key`) synced via key bindings — do not "simplify" these back to shared `StringVar`s, or -every later `var.set()` fires callbacks on dead widgets (TclError spam). - -## Three deliberate workarounds (beid mode) — do not "simplify" away +every later `var.set()` fires callbacks on dead widgets (TclError spam). Rule +for new code: **no variable on any `CTkEntry`**, dialogs included (seed with +`.insert`, read with `.get()`); the step-6 check boxes and the dialog option +menu are used WITHOUT a variable. + +**Other CustomTkinter 5.2.2 pitfalls** (each covered by a GUI test): +- Never `CTkLabel.configure(image=None)` (nor `""`): the old picture stays on + screen and, once freed, the next `configure` raises `TclError: image + "pyimageN" doesn't exist`. "No preview" = the 1×1 transparent image of + `_blank_ctk_image()`; every preview image is pinned on its label. +- An empty `CTkFrame` keeps a 200×200 default size and does not shrink when + its last child is destroyed: `elements_list` always keeps one child. +- `CTkButton` has no `justify` and its `width` is a minimum: list rows are + two stacked `CTkLabel`s, and the panel's buttons are stacked. +- `CTkTextbox` wraps visually by default: the text dialog uses `wrap="none"` + (the stamp breaks lines only at real newlines). +- `CTkCheckBox.select()/.deselect()` never call `command`, and there is no + `invoke()` (tests use `toggle()`): handlers flip the MODEL and the list + refresh re-syncs the widget, never the other way round. +- A `CTkScrollableFrame` inside the scrollable content column double-scrolls: + `elements_list` is a plain frame. + +## Deliberate workarounds and invariants — do not "simplify" away 1. **`open_eid_session()` replaces `pyhanko_beid.open_beid_session()`** — the plugin hard-codes a `BELPIC` token label; the same opaque error also appears @@ -321,13 +460,25 @@ every later `var.set()` fires callbacks on dead widgets (TclError spam). token and gives distinct "no reader" / "no card" / "other label" messages. 2. **`IncrementalPdfFileWriter(inf, strict=False)`** — inputs use *hybrid* xref sections; strict mode refuses them (`hybrid cross-reference sections - while hybrid xrefs are disabled`). `strict=False` is the intended escape - hatch. Image insertion uses the same `strict=False` writer. -3. **Vignette via `signers.PdfSigner(stamp_style=…, new_field_spec=…)`** — field - box defaults to a bottom-right corner box on the target page - (`_default_vignette_box`, `on_page=-1` unless a page anchor moves it), or, - when `sign_one(..., pos=(x, y))` is given, a 3:1 box of width page_w/5 on the - chosen page; background image and text positioned independently. + while hybrid xrefs are disabled`). Same writer for the visual-only path. +3. **Vignette via `signers.PdfSigner(stamp_style=…, new_field_spec=…)`** — the + field box is the default bottom-right box (`on_page=-1` unless a page + anchor moves it) or, with `sign_one(..., pos=(x, y))`, the placed 3:1 box; + background image and text are positioned independently. +4. **Visual stamps go into the SAME writer BEFORE `sign_pdf`, never after** — + a stamp added to a signed output is an incremental update that validators + flag as a modification (`verify_signed_pdf` raises). For the same reason, + in beid/azure, stamps are never applied to an INPUT that is already + signed: `sign_one` checks `existing_signature_count(writer)` (FILLED + signature fields + document timestamps — an empty field prepared for + signing does not count) right after opening the writer and raises + `StampError` before any PIN prompt; self-verification only validates the + LAST signature and would not notice the broken earlier one. Without stamps + the guard is not evaluated (plain countersignature; use another `--field`, + pyHanko refuses a filled one). Image mode keeps its historical outcome (it + stamps, invalidating the old signature) but appends a WARNING to the + detail; there a malformed `/AcroForm` counts as "not signed", while + `sign_one` fails closed. Do not add a code path that stamps `dst`. ## Where the signer's identity comes from (beid mode) @@ -339,114 +490,180 @@ national register number is embedded in every signature — mind PDF distributio ## Runtime requirements -- **beid mode**: eID middleware (`libbeidpkcs11.so`), reader + inserted card, - `pcscd` running. Prompts for the **PIN once per document**, so a full eID run - needs hardware + a human and cannot be exercised headlessly. Levels ≥ b-t - (default b-lta) additionally need **network**: TSA, EU trusted list - (cached 24 h) and OCSP/CRL endpoints; `--pades-level b-b` is offline. -- **azure mode**: no hardware; outbound network to `login.microsoftonline.com`, - the vault URL, the TSA (≥ b-t) and the internal CA's CRL/OCSP (≥ b-lt); - per-user Key Vault key/cert provisioned by an Azure admin (README). Tokens - and key material are never logged; only the digest leaves the machine. -- **image mode**: nothing special — pure PDF stamping, fully testable headless. -- **GUI**: `customtkinter` (pip) **and** a Python with `tkinter` + a display. - The step-6 page preview is rendered by **pypdfium2** (bundled PDFium, no - external binary); `pdftoppm` (poppler-utils) is only an optional fallback if - already present. Without either, the canvas falls back to a blank white frame. +- **beid**: eID middleware (`libbeidpkcs11.so`), reader + inserted card, + `pcscd` running. The **PIN is requested once per document**, so a full eID + run needs hardware + a human and cannot be exercised headlessly. Levels + ≥ b-t need **network** (TSA, EU trusted list, OCSP/CRL); `b-b` is offline. +- **azure**: no hardware; network to `login.microsoftonline.com`, the vault, + the TSA (≥ b-t) and the internal CA's CRL/OCSP (≥ b-lt). +- **visual signatures**: no network; text needs Pillow's FreeType renderer + (`PIL._imagingft`) and the bundled `fonts/`. ### tkinter in this environment -The system Python (3.12 here) lacks the `_tkinter` C extension, so `tkinter` -(and thus `customtkinter`) cannot import out of the box. The clean fix is -`sudo apt install python3-tk`. In this checkout the venv has been -**provisioned** without root: `tkinter/` + `_tkinter*.so` extracted from the -`python3-tk` .deb into `venv/lib/python3.12/site-packages/`, plus -`libBLT.2.5.so.8.6` (from the `tk8.6-blt2.5` .deb — Ubuntu's `_tkinter` links -against it) preloaded by `_blt_preload.pth` (a `sitecustomize.py` would be -shadowed by Ubuntu's own). Recreating the venv requires redoing that (or the -apt install). +The system Python (3.12 here) lacks `_tkinter` (clean fix: `sudo apt install +python3-tk`). The venv was **provisioned** without root: `tkinter/` + +`_tkinter*.so` extracted from the `python3-tk` .deb into +`venv/lib/python3.12/site-packages/`, plus `libBLT.2.5.so.8.6` (from the +`tk8.6-blt2.5` .deb — Ubuntu's `_tkinter` links against it) preloaded by +`_blt_preload.pth` (a `sitecustomize.py` would be shadowed by Ubuntu's own). +Recreating the venv requires redoing that. +Packaging side effect: PyInstaller cannot see that `.pth` preload, so a GUI +binary built from THIS venv lacks libBLT — launch it with +`LD_LIBRARY_PATH=venv/lib/python3.12/site-packages` to check it here. ## Validating changes without hardware -- **image mode & validation**: fully end-to-end via the CLI or `process_batch` - (no card). The `unittest` suite builds synthetic PDFs (`make_pdf`) to assert - page-count / dimension validation, image insertion, placement math, and arg - resolution. +- **Never touch the real user profile.** The GUI loads and AUTO-SAVES one. + Non-GUI tests pass explicit temp dirs to `ProfileStore(config_dir=…, + data_dir=…)`; GUI tests get `CACHET_CONFIG_DIR` / `CACHET_DATA_DIR` from + `_GuiTestBase.setUp`, with a `setUpModule` sandbox underneath. The same + holds for anything that is NOT a unittest (screenshot script, manual + `--gui`, ad-hoc `gui.CachetApp(args)`): export both variables to scratch + directories first, or pass `store=`. +- **Visual signatures & validation**: fully end-to-end via the CLI or + `process_batch`. Fixtures: `make_pdf` (optional MediaBox `origin`), + `write_pdf_objects` for unusual page shapes, `make_png`. Do not assert + pixel-exact text sizes (hinting differs between FreeType builds): use + ratios, bounding boxes, colours, or the paint matrix. - **PAdES levels & self-verification**: `SelfVerification` signs real PDFs *offline* with `SimpleSigner` + pyHanko's `DummyTimeStamper` (RSA-only) and a pre-loaded CRL, then asserts `verify_signed_pdf()` detects B-T/B-LT/B-LTA - and fails on mismatch. Do NOT fake the eID hardware path into passing — - real-card B-LTA stays the manual acceptance test in BUILD.md. -- **trust.py**: `test_trust.py` covers LOTL parsing, cert filtering, cache, - TTL, refresh and offline errors with the network mocked (`fetcher=`); a - live run against the real LOTL takes ~1 s if you need to sanity-check. -- **azure mode**: `test_azure.py` mocks ONLY the Azure transport — the fake + and fails on mismatch. It is also the recipe for **stamps + signature** + (real `core.sign_one(…, stamps=[…])`, then coverage `ENTIRE_FILE` and + modification level `NONE`) and holds the negative control (a stamp after + the signature fails verification). +- **azure**: `test_azure.py` mocks ONLY the Azure transport — the fake `CryptographyClient` really signs the digest with a local key, so RSA/EC - signatures flow through pyHanko + `verify_signed_pdf` end-to-end (incl. - the r||s→DER conversion). Auth/claims/key-template/material/batch wiring - are unit-tested with stub credentials; NO test performs a real login — - the real Entra+Key Vault path is the manual acceptance test in BUILD.md. - Do not fake it into passing. -- **GUI**: instantiate `gui.CachetApp(args)`, call `app._start_wizard()`, - inject state directly (`template_path`/`template_dims`/`input_paths`/ - `output_dir`…), walk with `app._goto_step(i)`, call `app.update()`, and - screenshot the window by id with ImageMagick - (`import -window shot.png`) on `DISPLAY=:0` — this catches real - CustomTkinter API errors that `py_compile` cannot. If a GUI test run stalls - at window creation with ~0 % CPU, it is Tk waiting on the ibus X input-method - bridge (`XCreateIC`/`_XimRead`), not the app: run with - `XMODIFIERS=@im=none` (and `PYTHONFAULTHANDLER=1 timeout -s ABRT …` to get a - stack if it ever recurs). Never run several GUI suites concurrently on the - same display. Step 3 auto-validates on - entry; step 6 builds `app.canvas`; a finished batch auto-advances to step 8. -- **i18n**: `test_i18n.py` (headless) checks catalog completeness, - placeholder parity, balanced / equal-count `**bold**` markup, and that the - docs catalog (`i18n_docs.py`) is merged and genuinely translated in all six - languages. -- **vignette appearance** (beid): render `build_stamp_style(identity)` via - `pyhanko.stamp.TextStamp.apply()` onto a copy with an explicit + signatures flow through pyHanko + `verify_signed_pdf` end-to-end. +- **Do NOT fake the hardware / login paths into passing**: real-card B-LTA + and the real Entra + Key Vault run stay the manual acceptance tests of + BUILD.md. +- **GUI**: (profile env vars set) `gui.CachetApp(args)`, + `app._start_wizard()`, inject state directly (`template_path` / + `template_dims` / `input_paths` / `output_dir`…; signatures through + `app._add_signature(stamp, label)`), walk with `app._goto_step(i)`, + `app.update()`, and screenshot the window by id with ImageMagick + (`import -window shot.png`) on `DISPLAY=:0` — this catches + CustomTkinter API errors that `py_compile` cannot. A finished batch + auto-advances to step 8. Dialogs are driven through their handlers (fill + the `dlg_*` widgets, `_on_text_dialog_edit()`, `_apply_*_dialog()`), with + `gui.filedialog.*` and `gui.colorchooser.askcolor` patched. +- **A GUI run stalling at window creation with ~0 % CPU** is Tk waiting on + the ibus X input-method bridge, not the app: run with + `XMODIFIERS=@im=none`. Never run several GUI suites concurrently on one + display. +- **`CACHET_REQUIRE_GUI=1`**: the display guard of the GUI tests turns ANY + failure of `tkinter.Tk()` or `import gui` (no display, broken Tk, an + ImportError in `gui.py`) into a skip — a green `-k Gui` run with skips + proves nothing. With this variable the guard FAILS instead; every run + meant to exercise the GUI sets it and must report zero skips. +- **GUI tests and the cyclic GC**: `_GuiTestBase.setUp` calls `gc.disable()`. + The tests pump `update()` instead of a mainloop; when the collector runs in + the batch WORKER thread, each garbage `CTkFont.__del__` is a Tk call from a + non-main thread that waits one second for a mainloop that never comes, and + the batch outlives the test's wait loop. New worker-thread GUI tests must + inherit `_GuiTestBase`. +- **Vignette appearance** (beid): render `build_stamp_style(identity)` via + `pyhanko.stamp.TextStamp.apply()` with an explicit `BoxConstraints(width=_STAMP_W, height=_STAMP_H)`, then rasterize with `pdftoppm`. `read_card_identity()` needs the card inserted but no PIN. ## Packaging (standalone executables) -PyInstaller builds **two onefile binaries** from one shared spec -(`cachet.spec`), full details in **`BUILD.md`**: +PyInstaller builds **two onefile binaries** from one spec (`cachet.spec`), +details in **`BUILD.md`**: -- **`cachet`** — windowed (`console=False`), entry `gui_main.py` (parses the - core arg parser then calls `gui.launch_gui`); double-click → GUI. -- **`cachet-cli`** — console (`console=True`), entry `sign_pdfs_beid.py`; - headless, **excludes** tkinter/customtkinter to stay lean. +- **`cachet`** — windowed (`console=False`), entry `gui_main.py`. +- **`cachet-cli`** — console, entry `sign_pdfs_beid.py`; headless, + **excludes** tkinter/customtkinter (and pypdfium2) to stay lean. -`i18n.py` is a plain module imported by `gui.py`, so PyInstaller's import -analysis bundles it into the GUI binary by itself — no spec change needed; -the CLI neither imports nor needs it. +**Fonts are data of BOTH binaries** (as `stamps.py` is code of both): +`common_datas` carries `fonts/*.ttf` and `fonts/licenses/*` (the OFL requires +the licence texts to travel with the fonts) — never move them to +`gui_datas`, the CLI stamps text too. +`stamps.asset_path` resolves them next to the module or under +`sys._MEIPASS`. `common_hidden` must keep `PIL._imagingft` (Pillow's FreeType +renderer); `gui_hidden` adds `profile_store` and `tkinter.colorchooser`. Key spec facts (don't regress): no built-in PyInstaller hooks exist for `pyhanko`/`pyhanko_beid`/`pyhanko_certvalidator`/`asn1crypto`/`oscrypto`/`pkcs11` → they are `collect_all`'d; `pkcs11._pkcs11` native ext + `collect_dynamic_libs`; `copy_metadata` for the pyhanko family (defensive). `oscrypto` **must not be -excluded** (hard import in certvalidator) but its OpenSSL backend is never on -this app's signing path. `tzdata` is collected **only on Windows** (pyHanko -timestamps need a zoneinfo there). `upx=False` (UPX can corrupt crypto libs). -The eID middleware (`libbeidpkcs11.so`/`beidpkcs11.dll`) is a **runtime dep, -never bundled**. The page preview uses **pypdfium2** (bundled in the GUI binary -via the contrib hooks; excluded from the CLI binary), so poppler is no longer -required — only an optional fallback. The Azure SDK -(`azure.core`/`azure.identity`/`azure.keyvault.*`/`msal`/`msal_extensions`) -has no provided hooks either → `collect_all`'d + metadata into the **common** -collection, and `azure_signer`/`jwt` are explicit hiddenimports — azure mode -must stay available in the **CLI** binary (do NOT add azure to CLI_EXCLUDES). - -Build routes: `./build_linux.sh` (native), `build_windows.bat` (real Windows), -`./build_windows_wine.sh` (Linux→Windows via Wine, best-effort), and -`.github/workflows/build.yml` (CI matrix, windows+linux, artifacts — runs on -`develop` pushes and PRs). **Releases**: merging `develop` into `main` runs -`.github/workflows/release.yml`, which tags `v{__version__}` (read from -`sign_pdfs_beid.py` — bump it on develop, it is the single source of truth) -and publishes a GitHub Release with both packaged binaries; an existing tag -makes the workflow skip gracefully. See BUILD.md "Release process". Verify -headlessly: CLI `--help`, image-mode end-to-end, a PKCS#11 native-load canary -(`--lib` at a dummy `.so` → expect a PKCS#11 error, not `ImportError`), and the -GUI binary launched on `DISPLAY=:0` + screenshot. Real eID signing needs -hardware and a real-Windows acceptance test. +excluded** (hard import in certvalidator). `tzdata` is collected **only on +Windows** (pyHanko timestamps need a zoneinfo there). `upx=False` (UPX can +corrupt crypto libs). The eID middleware is a **runtime dep, never bundled**. +The Azure SDK (`azure.*`, `msal`, `msal_extensions`) has no hooks either → +`collect_all`'d + metadata into the **common** collection, with +`azure_signer`/`jwt` as explicit hiddenimports — azure mode must stay +available in the **CLI** binary (do NOT add azure to CLI_EXCLUDES). + +Build routes: `./build_linux.sh`, `build_windows.bat`, +`./build_windows_wine.sh` (best-effort), and `.github/workflows/build.yml` +(on `develop` pushes and PRs). **Releases**: merging +`develop` into `main` runs `release.yml`, which tags `v{__version__}` (read +from `sign_pdfs_beid.py` — the single source of truth, bump it on develop) +and publishes both binaries; an existing tag makes it skip. Verify a build +headlessly: CLI `--help`; `--text` / `--signatures` end-to-end (fonts and +`PIL._imagingft` in the frozen CLI); a PKCS#11 native-load canary (`--lib` at +a dummy `.so` → a PKCS#11 error, not `ImportError`); the GUI binary on +`DISPLAY=:0` + screenshot (profile env vars set). + +**CI** — four pipeline files run the tests in the same three Linux steps: the +headless suite; a **GUI canary** (`import tkinter, customtkinter, gui` + a +`Tk()` under Xvfb — a broken Tk or `gui.py` must fail, not skip); the `Gui*` +suites under Xvfb with `CACHET_REQUIRE_GUI=1` and `XMODIFIERS=@im=none` (the +end-to-end layer: a Tk desktop app has no browser to drive). Every test job +has a timeout — a stalled Tk call must not hold a runner or the release +concurrency group — and the GUI step runs under `timeout -s ABRT 900` with +`PYTHONFAULTHANDLER=1`, so a stall dumps its stacks. +GitHub Actions (`build.yml`, `release.yml`) run them on Linux only (on the +Windows runner Tk could open real windows and hang), then build on Windows + +Linux and smoke-test the frozen CLI. GitLab CI (`.gitlab-ci.yml`) and Forgejo +Actions (`.forgejo/workflows/tests.yml`) run the tests only, in +`python:3.13-bookworm` + `xvfb xauth fonts-dejavu-core`; on Forgejo the +runner label and `actions/checkout@v4` depend on the instance. + +## Persistence (user profile) — `profile_store.py` + +GUI only; tkinter-free; the core/CLI never imports it. + +- **Where**: `profile.json` in the config dir, the image store `signatures/` + in the data dir — each: explicit argument > `CACHET_CONFIG_DIR` / + `CACHET_DATA_DIR` > `platformdirs` (ONE folder for both on Windows/macOS). + `ProfileStore()` resolves both ONCE at construction and creates nothing. +- **What**: `settings` — only keys with a value are written (`None` = "never + set by the user", so env/defaults keep applying); `signatures` — per entry + `Stamp.to_dict(base_dir=signatures_dir)` + `id`, `label`, `enabled`, + `placed_on`. A stored image is written as its bare file name, any other as + an absolute path. "Unplaced" = no `x`/`y` (it may still remember + `all_pages: true`). +- **NEVER stored**: PIN, tokens, any credential, the azure key name, the + signed-in UPN, the template, the input files. Everything is UNENCRYPTED + (files created 0600 on POSIX); the GUI help and README say so. +- **Atomic writes** (temp file in the same directory + `os.replace`); `save` + raises only `OSError`. +- **Tolerant `load()` — never raises**: missing file → defaults; a UTF-8 BOM + is accepted; not UTF-8 / invalid JSON / deep nesting / wrong top level / + `version` missing or ≠ 1 → moved aside as `profile.json.bak` → defaults. A + malformed entry is skipped, the others kept; an entry whose image or font + FILE is missing is KEPT (shown as unusable, deletable) — recognised by the + `StampError` prefixes in `_MISSING_FILE_PREFIXES`, keep them in sync with + `stamps.py`; an incomplete placement is cleared; bad / duplicate ids are + regenerated. +- **A degraded load must not lead to a destructive save**: when the file + could not be read (`OSError`) or not be moved aside, it stays in place and + `save()` REFUSES (`OSError`) until a later `load()` succeeds — the GUI + saves on every click and would replace a good profile with an empty one. +- **Image store**: imported images and drawings are COPIED to + `signatures/<32 hex of sha256>` (content-addressed: same bytes → one + file; a moved original does not break a signature). User FONTS given by + path are not copied. +- **Deleting**: `remove_signature` is the ONLY code that unlinks anything, + and only a file for which `is_store_file(path)` holds (not a symlink, + RESOLVED parent = the resolved `signatures/` dir, content-addressed name) + and that no remaining signature references. Never use a lexical + `is_relative_to` / `relative_to` test for "inside the store" + (`dir/../../x` would pass). Deliberately **no sweep of unreferenced + files**: the data dir may serve another profile and a `.bak` still + references its images. diff --git a/README.md b/README.md index 36e89b9..3d2d9fc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,13 @@ both a **command line** and a **CustomTkinter GUI**, with three modes: - **`azure`** — personal *advanced* (AES) signatures with the user's own certificate held in Azure Key Vault, after a single Microsoft Entra ID login per batch; only the document digest ever leaves the machine. -- **`image`** — a simple image stamp (no cryptographic value). +- **`image`** — **visual signatures only** (no cryptographic value): typed + text in the font and colour of your choice, images, or a hand-drawn + signature — one or several per document, each on a given page, on the + first/last page or **on every page** (initials). + +`beid` and `azure` can carry the same visual signatures: they are stamped +first, and the cryptographic signature then covers them. Signatures are **PAdES up to B-LTA** by default: trusted RFC 3161 timestamp, embedded revocation info (LTV), and an archival timestamp chain — with trust @@ -26,7 +32,9 @@ The GUI is a **step-by-step wizard** (template → documents → validation → output folder → signature type → placement → signing → report) with contextual help on every step, available in **English, French, Dutch, German, Spanish and Portuguese** (language selector on the welcome screen and at the top of every -wizard step; the system language is picked by default). +wizard step; the system language is picked by default). It **remembers** your +visual signatures, their last positions and your settings between sessions +(see *Saved profile*). > ⚖️ The eID mode uses the card's **non-repudiation** certificate, legally > equivalent to a handwritten signature. The **national register number** is @@ -41,13 +49,41 @@ wizard step; the system language is picked by default). |---|---|---|---| | **`beid`** | reader + eID card + PIN per document | **cryptographic** eID signature (pyHanko via the PKCS#11 middleware) — *qualified*-grade (QES) | visible **vignette**: cardholder photo + "Signed by:" / name / date | | **`azure`** | Microsoft (Entra ID) login, one per batch + a personal key/cert in Azure Key Vault | **cryptographic** personal signature — **advanced (AES), not qualified** | visible **vignette**: "Signed by:" / name / date (no photo) | -| **`image`** | nothing | **image stamp** (this is *not* a cryptographic signature) | the supplied image, placed at a chosen position | - -In all modes, the same vignette/image + page + position is applied to **all** -the documents in the batch — template validation guarantees the files are -geometrically identical. With `--page first|last` the target page is resolved -**per document** instead, which also lets the batch contain files whose page -count differs from the template (see *Template validation*). +| **`image`** | nothing | **visual signatures** — typed text, images, drawings (this is *not* a cryptographic signature) | the elements you defined, each at its own position | + +A run applies **a list of elements**: the vignette of the cryptographic +signature (`beid`/`azure`) and/or any number of visual signatures, each with +its own target — page *N*, the first page, the last page or every page — and +its own position. The same list is applied identically to **all** the +documents in the batch — template validation guarantees the files are +geometrically identical. A `first`/`last` target is resolved **per document**, +which also lets the batch contain files whose page count differs from the +template (see *Template validation*). Only **one** cryptographic signature is +made per document, and the visual signatures are always stamped **before** it, +never after. + +### Documents that are already signed + +A visual signature rewrites page content, so it **invalidates any signature +the document already carries**. An input that already holds a signature or a +document timestamp is therefore handled as follows: + +- **`beid`/`azure` with visual signatures** — the document is refused before + anything is signed (no PIN prompt, nothing written) and reported as failed + (`the document is already signed: a visual signature would invalidate the + existing signature(s)…`). The rest of the batch continues. +- **`beid`/`azure` without visual signatures** — the document is + countersigned and the earlier signature stays valid. A signature field name + can be used only once per document: to countersign a file that Cachet + already signed, give the new signature another base name with `--field` + (the GUI always uses the default name, so it cannot countersign Cachet's own + output). +- **`image`** — the document is stamped, as it always was, and its report + line ends with `WARNING: the document was already signed; its existing + signature(s) are no longer valid`. + +The post-signing self-verification only checks the signature Cachet just +created; it says nothing about earlier ones. ### eID vs Azure — which one? @@ -60,7 +96,8 @@ count differs from the template (see *Template validation*). signature (AES): fine for internal documents; for documents relied upon by external third parties, a publicly recognised (qualified) issuer would be needed. -- **`image`** is a visual stamp only — no cryptographic value. +- **`image`** adds visual signatures only — an appearance, with no + cryptographic value. ## Template validation (`--template`) @@ -69,13 +106,21 @@ If a template PDF is supplied, each input is accepted **only** if it has the equality, no tolerance). Rejected files are never signed; the rejection reason is displayed (CLI summary / GUI table). -**Files with a different page count** (e.g. scanned annexes were appended) can -still be processed by targeting a per-document page: pass `--page first` or -`--page last` (in the GUI, a selector appears after validation whenever such -files are detected). Every file is then signed on its own first/last page at -the chosen position; that page must still have **exactly** the template's -corresponding page dimensions, so the position is guaranteed to fit. Files with -the template's page count keep the full strict check. +**Files with a different page count** (e.g. scanned annexes were appended) are +accepted only when **every element of the run targets the first or the last +page**: each visual signature (`--page first|last`, or `"page_anchor"` in a +`--signatures` file) and, in `beid`/`azure`, the vignette. Each of those pages +must still have **exactly** the template's corresponding page dimensions, so +the positions are guaranteed to fit. An element on a numbered page or on every +page rejects such a file, and the reason names it, e.g. `1 page(s), the +template has 2; signature #2 targets every page (only first/last page targets +accept a different page count)`. For the vignette, `--page first|last` must be +explicit: the default bottom-right vignette does **not** count as a last-page +target (a safety check is never relaxed silently). Files with the template's +page count keep the full strict check. + +In the GUI, a selector appears after validation whenever such files are +detected: it puts **every** element on each document's own first or last page. ## Output @@ -97,6 +142,10 @@ overwritten**: on collision, ` - 1`, ` - 2`, … are appended. internal CA's CRL/OCSP (≥ b-lt); per-user keys provisioned in Key Vault (see the azure section above). - **`image` mode**: nothing special — pure PDF stamping. +- **Text signatures** (every mode): no new dependency — the text is rendered + by Pillow. Six fonts under the SIL Open Font License are **bundled** + (`fonts/`, licence texts in `fonts/licenses/`): Great Vibes, Dancing Script, + Caveat, Sacramento (handwriting), Lato (sans) and Libre Baskerville (serif). - **Graphical interface**: `customtkinter` + a Python with `tkinter` and a display. The page preview (step 6) is rendered by **pypdfium2** (the **bundled** PDFium engine) — no external dependency to install. (poppler / @@ -126,6 +175,20 @@ python3 -m venv venv --template ../pdfs/MODELE.pdf --input ../pdfs --output ../signes \ --image-path signature.png --page 1 --x 360 --y 150 +# Text signature (no card): two lines, on the last page of each document: +./venv/bin/python sign_pdfs_beid.py --mode image \ + --text "Jane Doe\nRead and approved, {date}" --font great-vibes \ + --color "#1A2B8C" --page last --x 360 --y 120 \ + --input ../pdfs --output ../signes + +# Several visual signatures (texts, images, initials on every page): +./venv/bin/python sign_pdfs_beid.py --mode image --signatures sigs.json \ + --input ../pdfs --output ../signes + +# The same visual signatures, then the eID signature that covers them: +./venv/bin/python sign_pdfs_beid.py --mode beid --signatures sigs.json \ + --input ../pdfs --output ../signes + # Azure mode (personal Key Vault certificate, one Microsoft login per batch): ./venv/bin/python sign_pdfs_beid.py --mode azure \ --azure-vault-url https://myorg-sign.vault.azure.net \ @@ -144,10 +207,15 @@ python3 -m venv venv | `--input ` | files and/or folders to process (folders are globbed for `*.pdf`). | | `--output ` | output folder (`{name}_signe.pdf`, never overwritten). | | `--template ` | template PDF; if supplied, inputs are validated against it. | -| `--mode beid\|image` | signature mode (default `beid`). | -| `--image-path ` | image to stamp (**required** in `--mode image`). | -| `--page ` | target page: a **1-based** number, or `first`/`last` (resolved **per document**; with `--template` this also accepts files whose page count differs — their first/last page must still match the template's). Image: insertion page. beID: vignette page. | -| `--x --y ` | lower-left corner, in points from the page's bottom-left. beID: **omit both ⇒ bottom-right of the last page**. | +| `--mode beid\|azure\|image` | signature mode (default `beid`). `image` = visual signatures only. | +| `--signatures ` | JSON list of visual signatures (see *Visual signatures* below). Works in **every** mode; in beid/azure they are applied before the cryptographic signature. | +| `--text ` | text signature for `--mode image`, placed with `--page/--x/--y`. `\n` starts a new line; `{date}` and `{filename}` are replaced per document. | +| `--font ` | font of `--text`: `great-vibes` (default), `dancing-script`, `caveat`, `sacramento`, `lato`, `libre-baskerville`, or the path of a `.ttf`/`.otf` file. | +| `--color <#RRGGBB>` | colour of `--text` (default `#1A2B8C`). | +| `--font-size ` | font size of `--text` in points (default 24, at most 400). | +| `--image-path ` | image to stamp in `--mode image` — the legacy single-image form, 150 pt wide, placed with `--page/--x/--y`. Ignored in beid/azure. | +| `--page ` | target page: a **1-based** number, or `first`/`last` (resolved **per document**). image mode: page of the `--text` / `--image-path` signature (default 1). beid/azure: vignette page. With `--template`, see *Template validation* for files whose page count differs. | +| `--x --y ` | lower-left corner, in points from the page's bottom-left. image mode: the `--text` / `--image-path` signature (default 0, 0). beid/azure: the vignette — **omit both ⇒ bottom-right of the last page**. | | `--pades-level ` | PAdES baseline level: `b-b`, `b-t`, `b-lt`, `b-lta` (**default `b-lta`**). See *Signature levels* below. | | `--timestamp-url ` | RFC 3161 TSA for levels ≥ b-t. Precedence: flag > `CACHET_TSA_URL` env > `http://timestamp.digicert.com`. | | `--trust-list-url ` | EU LOTL URL seeding the LTV trust anchors. Precedence: flag > `CACHET_LOTL_URL` env > the official EU URL. | @@ -166,6 +234,89 @@ python3 -m venv venv | `--azure-trust-anchors ` | PEM/DER file or directory with the **internal CA chain** used as LTV trust anchors in azure mode (required for b-lt/b-lta and for self-verification at b-t). Env `CACHET_AZURE_TRUST_ANCHORS`. | | `--azure-graph` | opt-in: use the Microsoft Graph `/me` displayName for the vignette. | +Which flags define the visual signatures of a run, and what `--page/--x/--y` +place: + +| Mode | Flags | Visual signatures of the run | `--page/--x/--y` belong to | +|---|---|---|---| +| image | `--image-path` | 1 image | that image | +| image | `--text` (`--font`, `--color`, `--font-size`) | 1 text | that text | +| image | `--signatures` | the file's entries | — (giving them is an error) | +| image | `--signatures` + `--image-path` or `--text` | that image/text **first**, then the file's entries | the image/text | +| image | `--text` + `--image-path` | error (use `--signatures` for several elements) | | +| image | none of the three | error | | +| beid/azure | `--signatures` | the file's entries, applied before the signature | the vignette | +| beid/azure | `--text` (or `--font`/`--color`/`--font-size`) | error (use `--signatures`) | | +| beid/azure | `--image-path` | none (ignored) | the vignette | +| any | `--font`/`--color`/`--font-size` without `--text` | error | | + +### Visual signatures (`--text`, `--signatures`) + +A visual signature is a **text** or an **image** stamped on one or several +pages. It is an appearance only: by itself it proves nothing. In `beid` and +`azure` modes the visual signatures are stamped first, into the same revision +that is then signed, so the cryptographic signature covers them — a signed +output is never stamped afterwards. + +A `--signatures` file is a **UTF-8 JSON array** of objects, one per visual +signature (a byte-order mark is accepted, e.g. PowerShell's +`Out-File -Encoding utf8`): + +```json +[ + {"kind": "text", "text": "Jane Doe\nRead and approved, {date}", + "font": "great-vibes", "color": "#1A2B8C", "font_size": 24, + "page_anchor": "last", "x": 360, "y": 120}, + {"kind": "text", "text": "JD", "font": "caveat", "font_size": 14, + "all_pages": true, "x": 540, "y": 20}, + {"kind": "image", "image_path": "stamp.png", "width_pt": 120, + "page": 1, "x": 60, "y": 700} +] +``` + +| Key | Type | Applies to | Default | Notes | +|---|---|---|---|---| +| `kind` | `"text"` \| `"image"` | all | required | | +| `text` | string | text | required | Line breaks are allowed. `{date}` → `dd/mm/YYYY` (local date of the run); `{filename}` → name of the source file without `.pdf`. Any other brace is left as it is. At most 2000 characters. | +| `font` | string | text | `"great-vibes"` | A bundled id (`great-vibes`, `dancing-script`, `caveat`, `sacramento`, `lato`, `libre-baskerville`) or the path of a `.ttf`/`.otf` file. A relative path resolves against the folder of the JSON file (the `--font` flag: against the current folder). | +| `color` | `"#RRGGBB"` | text | `"#1A2B8C"` | | +| `font_size` | number | text | `24` | points, greater than 0, at most 400 | +| `image_path` | string | image | required | A relative path resolves against the folder of the JSON file; `~` is expanded. | +| `width_pt` | number | image | `150` | points, greater than 0, at most 5000; the height follows the aspect ratio | +| `page` | integer ≥ 1 | all | — | give exactly **one** of `page`, `page_anchor`, `all_pages: true` | +| `page_anchor` | `"first"` \| `"last"` | all | — | resolved per document | +| `all_pages` | boolean | all | `false` | every page of each document (initials) | +| `x`, `y` | number | all | required | lower-left corner, points from the page's bottom-left | +| `enabled` | boolean | all | `true` | `false` → the entry is skipped | + +Unknown keys are ignored, so an entry copied from the GUI's `profile.json` +(which adds `id`, `label`, `placed_on`) is accepted as it is — only the +`image_path` of an image entry has to be rewritten to a real path. A bad +entry stops the run before anything is processed, with its position in the +file (`sigs.json: signature #2: …`). + +Good to know: + +- **Text is drawn as a picture.** It is rendered at 300 dpi with a + transparent background and cropped tightly to its ink; no font is embedded + in the PDF. `(x, y)` is the lower-left corner of that ink box, and the text + grows right and up from it. With `{date}` or `{filename}` the box is + measured per document, so its size — and the baseline, by the depth of the + descenders — can vary slightly from one document to the next. +- **Missing characters.** A character the chosen font does not contain is + drawn as an empty box or, depending on the font (Sacramento, for + instance), not drawn at all — without any error. A text none of whose + characters can be drawn is refused as `text is empty`. Check the result, or + point `font` at a `.ttf`/`.otf` file that covers your script. +- **Limits.** A text whose rendering would exceed 40 megapixels at 300 dpi is + refused with a clear error (reduce the size or the length). Images are + embedded at no more than 600 dpi of their width on the page (a large photo + is downsampled), with their EXIF orientation applied; the alpha channel + of a PNG (and palette transparency) is kept. +- **Blank pages** are stamped like any other. +- **The command line never reads the GUI's saved profile**: a headless run + depends on its flags and files only. + ### Signature levels (PAdES baseline, ETSI EN 319 142-1) | Level | Adds | Network needed | @@ -190,7 +341,8 @@ python3 -m venv venv is re-opened and validated, and the *achieved* level is reported in the summary (e.g. `PAdES-B-LTA, LTV ok`). A mismatch marks the document failed — the level is **never silently downgraded**; `--no-verify` skips this check. -- **Offline behaviour**: `b-b` and `image` mode work fully offline. Levels +- **Offline behaviour**: `b-b` and `image` mode work fully offline (visual + signatures never need the network, in any mode). Levels ≥ b-t fail with an actionable error naming the unreachable endpoint (TSA, EU trusted list, OCSP/CRL). - **🔒 Privacy**: the signer's **national register number (RRN)** is embedded @@ -237,25 +389,94 @@ Cachet** link that opens the payment page in the browser. The wizard adds a stepper (completed steps green, problems red, unreached steps disabled), the current step's form on the left, contextual help on the right, and Previous/Next buttons that -name the target step. **Cancel** asks for confirmation, then resets everything -back to the welcome screen. +name the target step. **Cancel** asks for confirmation, then discards the +current session (template, files, validation, results) and returns to the +welcome screen — your saved signatures and settings are kept. The 8 steps: **1.** template (with a single PDF to sign, pick that document itself as the template) → **2.** documents → **3.** validation (pass/fail table; if some files have a **different page count** than the template, a selector appears to sign every file on its own **first or last page**) → -**4.** output folder → **5.** signature type (eID/image/**Azure** + PAdES -level selector, default `b-lta`; in Azure mode a panel offers the vault -settings and a **"Sign in with Microsoft"** action; **"Full documentation"** -opens the localized reference — modes, PAdES levels, AES vs QES, glossary — -ending with clickable links to the source standards) → **6.** placement -(actual page preview, click to place — in eID/Azure modes the vignette is -signed exactly there —, plus a manual **target page** field; when page counts -differ, the first/last selector is also shown at the top of this step and the -preview is locked onto that page) → **7.** signing (summary, a green -**"insert your eID card"** reminder in eID mode, progress) → **8.** +**4.** output folder → **5.** signature type (eID / Azure / **visual +signature (text / image)** + PAdES level selector, default `b-lta`; in Azure +mode a panel offers the vault settings and a **"Sign in with Microsoft"** +action; **"Full documentation"** opens the localized reference — modes, PAdES +levels, AES vs QES, glossary — ending with clickable links to the source +standards) → **6.** placement, a small **editor** (see below) → **7.** +signing (summary listing the vignette placement and every visual signature, a +green **"insert your eID card"** reminder in eID mode, progress) → **8.** per-document report with an **"Open output folder"** button. +**Step 6 — the element editor.** On the left, the list of **elements** stamped +on every document: in eID/Azure modes the **signature vignette** comes first +(bottom-right of the last page unless you place it), followed by your visual +signatures, each with a tick box (untick one to keep it in your library +without using it). **Add text…** opens a dialog (text on one or several lines, +font, size, colour, with a live preview and the size the text will have on +the page), **Add image…** picks a picture, **Draw…** lets you sign by hand +with the mouse or a stylus (transparent background); **Edit…** and **Delete** +act on the selected signature. On the right, the **actual page preview** shows +every element at its real size: **select an element in the list, then click +on the page** — the click sets its lower-left corner. **On every page +(initials)** repeats the selected signature on all pages, a **target page** +field moves it to another page, and **Reset position** un-places it. The step +is complete when every ticked signature is placed (the visual-signature mode +needs at least one). When page counts differ, the first/last selector is also +shown at the top of this step: every element then goes on that page, the +preview is locked onto it and "On every page" is disabled. + +### Saved profile + +The GUI saves, on every change, and reloads at the next start: + +- your **signature library** — texts (with font, colour and size), imported + images and drawings, with their name and tick box; +- each signature's **last placement** (page, position), re-applied only when + the page of the current template has exactly the size it was placed on — + otherwise the signature simply reads "not placed" and nothing is lost; +- your **settings**: language, signature mode, PAdES level, output folder, + Azure vault URL / sign-in method / trust-anchors file, and the position of + the eID/Azure vignette. + +Where it lives: + +| OS | `profile.json` | Images (`signatures/`) | +|---|---|---| +| Linux | `~/.config/Cachet/` (or `$XDG_CONFIG_HOME/Cachet/`) | `~/.local/share/Cachet/signatures/` (or `$XDG_DATA_HOME/Cachet/…`) | +| Windows | `%LOCALAPPDATA%\Cachet\` | `%LOCALAPPDATA%\Cachet\signatures\` | +| macOS | `~/Library/Application Support/Cachet/` | `~/Library/Application Support/Cachet/signatures/` | + +Set `CACHET_CONFIG_DIR` and/or `CACHET_DATA_DIR` to use other folders (the +first holds `profile.json`, the second `signatures/`). + +- Everything is stored **unencrypted** (files readable by your user account + only on Linux/macOS). **Never stored**: PIN codes, sign-in tokens or any + other credential, the Azure key name, the signed-in account, the template + and the documents. +- Imported images and drawings are **copied** into `signatures/`, so moving + or deleting the original does not break a saved signature. A custom font + file (`.ttf`/`.otf`) is only referenced by its path: if it disappears, the + signature is shown as unusable until you edit or delete it. +- **Cancel** and **Finish** keep the profile; **Delete** removes a signature + and its stored image. +- Precedence for the Azure vault URL and trust anchors: your saved choice, + then the `CACHET_AZURE_*` environment variables, then the built-in default. + A saved output folder or trust-anchors file that no longer exists is + ignored. +- The **command line never reads this profile**. + +Limits, stated plainly: an image that cannot be copied into the user folder +is not added (the reason is shown). A profile that cannot be read (damaged +file, or written by a newer version) is set aside as `profile.json.bak` and +the app starts with an empty library; if it can be neither read nor moved +(access denied, for instance) it is left untouched and nothing is saved over +it until it is readable again. After that, or when the profile was +edited by hand, image files that no signature references any more can remain +in `signatures/`: Cachet never sweeps that folder, because a backup or +another profile may still use them. **To erase everything, delete the folders +above** (a single folder on Windows and macOS; on Windows it also holds the +cached EU trusted list, which is simply downloaded again). + --- ## Standalone executables (Linux & Windows) @@ -274,14 +495,39 @@ build_windows.bat # Windows -> dist\cachet.exe , dist\cachet-cli.exe The eID middleware remains a **runtime dependency** (beid mode) and is never bundled; the page preview, for its part, works without installing anything -(PDFium bundled via pypdfium2). +(PDFium bundled via pypdfium2), and the six fonts of the text signatures are +bundled in both binaries. ## Tests -Headless `unittest` suite (no card, no tkinter): +Headless `unittest` suites (no card, no network, no display — the `Gui*` +classes skip themselves): + +```bash +env -u DISPLAY ./venv/bin/python -m unittest -v +``` + +GUI suites (they drive the real wizard, the editor dialogs and a batch +through the worker thread — the end-to-end layer of this desktop app). Run +them **one at a time**, under a virtual display when available: ```bash -./venv/bin/python -m unittest -v +CACHET_REQUIRE_GUI=1 XMODIFIERS=@im=none xvfb-run -a ./venv/bin/python -m unittest -v -k Gui +``` + +With `CACHET_REQUIRE_GUI=1`, a GUI test that cannot run (no display, broken +Tk, `gui.py` that no longer imports) **fails** instead of being skipped — a +green `-k Gui` run with skips proves nothing. Without `xvfb-run`, use a real +display (`DISPLAY=:0`). + +The tests never touch your real profile: each one works in temporary +folders. The same rule applies to **manual** runs of the GUI during +development — point it at scratch folders first, otherwise it loads and +auto-saves your own profile: + +```bash +export CACHET_CONFIG_DIR=/tmp/cachet-dev/cfg CACHET_DATA_DIR=/tmp/cachet-dev/data +./venv/bin/python sign_pdfs_beid.py --gui ``` ## Project structure @@ -289,14 +535,18 @@ Headless `unittest` suite (no card, no tkinter): | File | Role | |---|---| | `sign_pdfs_beid.py` | core + CLI entry point (business logic, importable without tkinter). | +| `stamps.py` | visual signatures: model, bundled fonts, text/drawing rendering, the `--signatures` JSON, stamping onto a PDF (importable without tkinter). | +| `profile_store.py` | the GUI's saved profile: signature library, last placements, settings, and the image store (never read by the CLI). | | `trust.py` | EU trusted-list (LOTL) trust provider: anchors for LTV in beid mode, with local cache. | | `azure_signer.py` | azure mode: Entra ID login, per-user Key Vault key/cert resolution, pyHanko signer (digest-only signing). | -| `gui.py` | CustomTkinter interface: landing page + 8-step wizard (façade over the core). | +| `gui.py` | CustomTkinter interface: landing page + 8-step wizard with the step-6 element editor (façade over the core). | | `i18n.py` | GUI localization catalog (EN/FR/NL/DE/ES/PT), light `**bold**` markup helper, documentation sections/sources. | | `i18n_docs.py` | long-form documentation of the "Full documentation" popup, six languages (merged into the catalog). | | `gui_main.py` | entry point of the windowed binary (opens the GUI). | -| `test_sign_pdfs_beid.py`, `test_trust.py`, `test_azure.py`, `test_i18n.py` | `unittest` test suites. | +| `fonts/` | the six bundled OFL fonts for text signatures; `fonts/licenses/` holds their licence texts (shipped in both binaries). | +| `test_sign_pdfs_beid.py`, `test_stamps.py`, `test_profile_store.py`, `test_trust.py`, `test_azure.py`, `test_i18n.py` | `unittest` test suites. | | `cachet.spec` | PyInstaller recipe (two binaries). | | `build_*.sh` / `build_windows.bat` | build scripts. | -| `.github/workflows/build.yml` | CI: Windows + Linux binaries as artifacts. | +| `.github/workflows/build.yml`, `release.yml` | GitHub Actions: tests (headless + GUI suites under Xvfb), Windows + Linux binaries as artifacts, and the release on `main`. | +| `.gitlab-ci.yml`, `.forgejo/workflows/tests.yml` | GitLab CI and Forgejo Actions: the same tests (no build, no release). | | `BUILD.md` | detailed packaging guide. |