From 4435e0a790ba18784aca888df298889d5c499fcf Mon Sep 17 00:00:00 2001 From: Astoria Date: Mon, 8 Apr 2024 00:01:53 -0500 Subject: [PATCH] Change font. --- readme.md | 2 +- .../net/brokenmoon/BasicMonitorDriver.java | 63 +++++++++--------- src/main/resources/C64ProMonoMonitor.ttf | Bin 0 -> 50288 bytes src/main/resources/font.png | Bin 3057 -> 0 bytes 4 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 src/main/resources/C64ProMonoMonitor.ttf delete mode 100644 src/main/resources/font.png diff --git a/readme.md b/readme.md index 20d7978..fe33ae0 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,7 @@ Bigfoot - Original emulator in C, rpcboot.bin, tetris.img, slideshow.img, and re Simon816 - Creator of J65el02, the implementation that without this machine would not be possible. - https://github.com/simon816/J65el02 -Timmie3054, Amon, Pcmaster160, CadenDonuts, and HanFox - Original source of the font which I have used in this emulator. https://bdcraft.net/community/viewtopic.php?t=354 +Style64 - Font used inside this. Slightly modified purely to adjust character positions for ease of coding, no true visual modifications have been made. https://style64.org/c64-truetype # TODO: Speed up monitor rendering. diff --git a/src/main/java/net/brokenmoon/BasicMonitorDriver.java b/src/main/java/net/brokenmoon/BasicMonitorDriver.java index be58a5d..391363b 100644 --- a/src/main/java/net/brokenmoon/BasicMonitorDriver.java +++ b/src/main/java/net/brokenmoon/BasicMonitorDriver.java @@ -6,10 +6,13 @@ import com.simon816.j65el02.device.RPMonitor; import javax.imageio.ImageIO; import javax.swing.*; +import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.image.BufferedImage; +import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.util.Objects; import static com.simon816.j65el02.device.RPMonitor.HEIGHT; @@ -18,14 +21,11 @@ import static com.simon816.j65el02.device.RPMonitor.WIDTH; public class BasicMonitorDriver implements MonitorDriver, KeyListener { BufferedImage display; - BufferedImage fontSheet; final int width = 8; final int height = 8; int rows = 16; int cols = 16; - BufferedImage[] sprites = new BufferedImage[rows * cols]; - ImageIcon[] characters = new ImageIcon[rows * cols]; - JLabel[][] displayArray = new JLabel[HEIGHT][WIDTH]; + JLabel[] lines = new JLabel[HEIGHT]; Machine emu; int xoffset = 32; @@ -34,22 +34,6 @@ public class BasicMonitorDriver implements MonitorDriver, KeyListener { this.emu = emu; try{ display = ImageIO.read(Objects.requireNonNull(getClass().getResourceAsStream("/display.png"))); - fontSheet = ImageIO.read(Objects.requireNonNull(getClass().getResourceAsStream("/font.png"))); - for (int i = 0; i < rows; i++) - { - for (int j = 0; j < cols; j++) - { - sprites[(i * cols) + j] = fontSheet.getSubimage( - j * width, - i * height, - width, - height - ); - } - } - for(int i = 0; i < characters.length; i++){ - characters[i] = new ImageIcon(sprites[i]); - } } catch(IOException e){ System.out.print("No image!"); } @@ -59,18 +43,33 @@ public class BasicMonitorDriver implements MonitorDriver, KeyListener { JFrame frame = new JFrame("Monitor"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - for(int y = 0; y < displayArray.length; y++){ - for(int x = 0; x < displayArray[y].length; x++){ - displayArray[y][x] = new JLabel(new ImageIcon(sprites[' '])); - displayArray[y][x].setBounds(xoffset + (x * 8), yoffset + (y * 8), 8, 8); - displayArray[y][x].setVisible(true); - panel.add(displayArray[y][x]); - } + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + Font bescii; + try { + bescii = Font.createFont(Font.TRUETYPE_FONT, new File(getClass().getResource("/C64ProMonoMonitor.ttf").toURI())); + ge.registerFont(bescii); + } catch (FontFormatException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + bescii = bescii.deriveFont(Font.PLAIN, 8f); + + for(int i = 0; i < HEIGHT; i++){ + lines[i] = new JLabel(); + lines[i].setFont(bescii); + lines[i].setBounds(xoffset, yoffset + i * 8, 8 * WIDTH, 16); + lines[i].setForeground(Color.GREEN); + panel.add(lines[i]); } JLabel label = new JLabel(new ImageIcon(display.getScaledInstance(350 * 2,230 * 2,0))); label.setBounds(0, 0, 350 * 2, 230 * 2); panel.add(label); + frame.add(panel); frame.addKeyListener(this); @@ -101,11 +100,13 @@ public class BasicMonitorDriver implements MonitorDriver, KeyListener { @Override public void update(byte[][] windowData) { - for(int y = 0; y < windowData.length; y++){ - for(int x = 0; x < windowData[y].length; x++){ - char chars = (char) windowData[y][x]; - displayArray[y][x].setIcon(characters[chars % 255]); + for(int y = windowData.length - 1; y >= 0; y--){ + String text = ""; + for(int x = 0; xJ*tQdB?+f`|x+ zh=5E2A|fCn&R7uv5djeqk&6|%TvRU3P-#it|G&PqviHeEh5LRy@5|ZE*?aB1_BT&! z?X^#h7-PnovrU>=n@k>k*e8mP_<%7F9F4Qn-?OGZX{%%u+C^y3J>sZkCC5E^`^Cn{ zacG~?xT&GzFQ*-`)0oUEWAZNA(9qS<+iL*vfd#mpy`gp6`mb-e`lH57TWQSsuWW2? zXv&wvI&tke{8enkiQLf{6@WJp?YSE_b)SCU<9FbieAAfpGh5pm8)mLqz0{aV51@Ve zriRly>|y47Tn9drXlvNi{6^u|dW`u3@Qv;6Xz%K-{q(sTjk)U@VNNG5EiOC?0bX*a9bI%*oO!g=%nK_x(W{aF{%=SF9>l9pc zpQDyml$q7W?CMn-vT#QN0M5qM44}g&VI-g=M?8);1NbCI&!mAAvL*N?=BQu%h`r+N z)Z^i%Sa-~Vs2sX7}@bAw$Q-e>*=P6>#A)77EIor4x#YPv}uw;ua-W;KLa z0AbEBXPGaUd(4l_Z_Mw^Kht(3#wTVZ3T9tgFlEl7!nDHag>wrR7nT*SEIg#JtMKx| z>k1z%e7x{ig)bHUY2Nzz6XqW}ziIyOi*kPR_|CI-_Wt&)-}b(6)(gGAJL`A7f9l=U zi;Tn1WRo!0o4d{T&96L;yu@VSxCA&B7Mj8_g>wq`D=aNs0UVnO&n~75?>T$E&DPH2 zjd^|@kD|}7=l?p_m}g&qb``#N;O|yre)Wl8RXlTD)F<^QX9Xm;&a~m|7W3iQwJqj! zw9a;a=a>u3t>!j!ySc;lxZQm}f$yjBhpg#7FPIn2OZLUI8`Dq8n3?fh=2cn8Wlzd} z%3afd$MBW`t+-Tz5!zIl<@C5==%n9BP{DCbF;a{d=b+566Et`Na!n&(VgZl z^Ho^H*I;>HH}{%vm~WbInQxo#nD3hJnfqWVJIoKv{pN?}0a)gP<{|U2`LTJ#{KPzJ zerg^wkDDjV&&-qN=jJK%3&{AF<{8-5v*y>3^?#V>Vaq$sZ_Nv^winHRnwQLfnU~G) z%^%Dk%`4`=&8y~5=FjFY=C9^&=I`bo<~8%W*=7D|-Y~n(9`mN@F}=uwB39BQT{0w7 zvLst_WR#4SF)~)hNv`C{c*&OuGEw%CNwTj@mMJn-rpa`fAv0x`BxJS}$Q+p~g)&d( z%K}*_i)24pEK6jmER!NBmJ%tIGAWk|sgx?ImgTZSR?7aeN)C|KQX{oeCu^i$lJXuo zP!5uV2w5xdl_TXSIa-d9W95BvoE$GF$ou6)`GA}xC(9|)AnT-2nxt9Q z%LdsfEpn=yCatnb+N51NFUD7R^Ws7W;(`B2SAs>CYhkmaV4Gu5 zy^b@vu-5S=-%KzQ%|5W+eGw0)n5kwOqR|X9)67D2n2lI8$ION8%!BnTFbmBhv!7XP zmYAhxnJF^Gro@z*GE;6UOr@zZ)n>U_VOE;`%_?&MVp$C;y*jhTw3sCPAsfDs319f2 zTqoDd4RWJ=!F&X9?o7GKeAJvRH_I*NL-IwFCbz<)&w&+Z$d_QfopKxQIs(pb z@_#$}bMlw3%H0FyFJF5r`I~D~m#>=5a*upn?v-!IH|1OMZTXITSH36r$@gW4 z{6OxPAIbyrBY99Bl85ET@`(II9+jWUWAeB>AwQER<>&I0{6e0VU&=G`D|uFaEzik+ z$n)|W*(tx37vy*HqWq`4B>yEZ%kSk6@<(|^{##y^KgplvFY;IUoBUn=f$!Jkb=f8V zls9Cz?2$L6M|x55i?!xTn`YB(hRw8D=5sdN=Gakov>hY=uwxP1HzVqAGw0iJHW%Dn zVDk|1FR z*qL^gP1xDCz|OIAZK0iK=i3E#pK(H)BN!+$NzWgzwg+7-(~-Y{@+>tc<1_m7vsOVRDS-> z;>Z7h{@+di|BT7Bn3;65IjQ3so(cosuxH2U6Ce5T>^rrDw_8cpqmq0N>c4~DmL)f# zj$Cgxn2o3eIj5?hE#Uw)=39S06zkH0W45>XbEn0w^*>C7t>eJdJ~^mjJ7T9ejtpbU z*y(axJqi-7h!05+DzdB~(nB2Ckx%nmeYw{1zKQ4cL{u%k_=3ktDW&SPscjbRO z|Ka?n^Iyz=HGkKH^abIdSL2SNEB^ z&%ygN?Q_LG5AXBmNs}h6nbb7t%1IASdT!FLeHZOpwQudd9s6Fh@BRD!VRGK&s>w%A z-Z=S^$+t~@VDgJoCQVr|N!&{ntI>V=ckRDHgnpd zX=T&aPwSX=@wB_AJvr@_X}hM+oW5#$)ATc^Uo-ui)1ROI+KkCFmd;o^qix0+GcK8N z?~JEs?3`(4&YOAM%n#4JapuD_pPspMmYr2Ft7O)ySqINLZdTK*&RJ*Ax@gu_iBXA3 ziIPNZ;)Fy~qBC)J;^M?LiCYr)B<@c3{!li|$7G7KU z?ZW5gO`KOWZ{@s>dDqT+bl#r%3+5j?f6M&K=I@yQ!UDTs!Gd)Q&RB5Mf=3tpec|MV z$%SVuynErJ3twF{Y0>IMXDqsL(Nl|F-LGK3rTZPd-%0zOv)>*2J-y$q#p#Pn7N4;A z+{L#nesuAxOQtVbxuj{yIZJL^^4OARm+V?PZ|UJnTbEwGbjQ*+md#yu;I=bkjqK!qJMOPNxSoC1g6GhJ!yt-d6cw<=?9&RaI1-San6!9aYa%o9YGChgP3a zeMj|6%gyqFy8KH`cv|K@P%C7N@7uIGZN3 z$Io_uIP(UQP&y`h!V#u=(3cZwn42)@IOvAic(*Zu>0fB`i3z7y`FO1t(?@z9AS1Zb zhK5UQ5$yQWmpJ@zUeASZ;7C_KL3AxCqLgKDwY! z-rr9}+0drq)4S3gOFRw`jpcN>dq$`B018M2*{4W2dC93iQc2rM2d$84Utc05G;VwX z^``p+NLR%;+nI)$tUlTIBar+~QTtOX39yKde?b93dP>rW%QVI7BsK(xyr$YCB$XqrhOIPrMvXlK=jidIg!tpsu_ugPsC~!p=v0|fV!V_0 zq*|mAD&9@h$2=~s3-#&fejagCn1ra20#7Y4C!?_PMw{{Ee+S6mzih^@x70IbN*Yzx z+*8A}sDP7ul~LfHZTh+Z8*mKZJA?_spxg+PmP5W(Z@96~{)UIXI=X3PB>bW zlVGd#B$c1q6|wZdpZGkI=XVoBpDzL-H|H zi2`$S-u^vd|4cJb^6&;~Z)_8vJB}~bm6q6!G z3bjZcE4?mb#_t~@_5}$9izLhdOXDzU(mF@4gl}q(!@d${)3yCW+M@x0G&2a6HTv(udn0u|(&{7@2_GjuHGS8hf843&FQs8Wfl zj0rW+7wMhemJ%=C!gkaSnZpS?co02XajBK6rSeROOewmAnFL#8R>^dKgzyICJ*2+{ z+}zXi-*A7-DY1L{X<03l{Azu~Bg!@dp2t77Lr$X2A}3YkV80^{6Eaa-4^*e_)$Y_s z7z=n5Fw&oR%xFdpP%_-~_+O)&QVwHf#?=(Qhp0qIsbb_eD?Ft}D~{+&ppsV!w=aIh zbVVB^2jo{{j^=WXFY@ZlWG=1RVOHZiWem2)=XmJV>b%ff$TOl!j{?QqM>VdVRcWid zaR$Wq0teP;r(wMbA^|>Wq`Pmf!pCFilQTIqU?%(EY?0wQF@*SmI4~BgZu+cN^&dr$ zkjEq64U{v|BL;ZC#n>>7F@$%50>5c>N67|1qJPmVGzWqQ=M$NXNBwe;`T|EXY8{k> z*6N|oa=JN$GEv6~Ev;~4!Wk{)qtjgjd*Rn0rdD4X&gV9ieApjbUD!~;s5cxl-@;+%!b88G_QV#G=r z^PWA>8#1`Jd-UDw{7ZSO4byV)iEPB_sE^B(OcyMJ@lE~4NgrbkwJ*e{<6}OsS3Hp4 zFjwkq6#DAJ?tPb1W8JD$?@qB+wR6>$T7Hln><#|XAC}JFX>O&*XslN2Cw%bY$4(em zjW+M29(Tm`F@z8H&wWu2(O6G?I-3~69;x{#Z>fCgQH;I3!kIxH;SGtd&EO0Zd#A?I9tzH)o|O!;iPDChD@!6lP+6KN zNLdiQ?n5x@g(3poRIxLNkn>Ty6=20FGQZqLa`Zgq2w&+SZ#(+VrSse-J;(WKUzZ?E zkuaTa;n@sl+msK&kk&3xagYx+!e0F2H#`-xWc}gbw?*)I4ma{%FB83wzMbuGaNMdm zbdHz7jjw4jZz_Hd!)F>&sgzQ!9(&(WkEewkfd4wKU(YnF87)8~?aR@)-E88FwZZw- z_{Ik`csvNbN(0-wV%KmXcFje3e;;T4!!_Ew-q+i!$Dkw4Y;}g>N*E-LY4+h*CBz>!4fXVREu1+Z|A%|ku%b~_iY!K(GlRY;gACF%K-R?VBQYqU z-_eOw?_Sp1%|}vYN_ng8z~(*@w?oJOcJon2EaSC9IrQn^E$ZYDl{5~82p!}ScOj)y z`;mtjjybC5U{6Es361xMh@}vDR-^r+}s+%Kq~ z-MAEBAs?n$yjdCd71%)xR+bwJXn)SjpntCG?O`}SNwZTNMlT;X1?yp`&(IGP21h}# z-R7u&rnBb=r-rJ~pHDf_|6(_*0r=_@0FHkGPv$$59FrkaK|cBfP5aX~0-wOS-CUMx zFR^O{SW)k>;I7Dy;8LzwLPTLE$yI#B{mcd_GmiF?|kG_e9XLK?(81H;v;O zXA!H1oim8XlL#uUG(e2fGHJ(YNXOS9K6j+%ufg*J@1rc$7br7Q9_5wc{VH{=ukuUv z&6rI4)d!59-o~4OogWx_A1%59#Ca#5!O=>%XAar}D^T9pVszs-|MWY+fsCi%jhk}3 zRpa19wh%jt*J{yeV8W)~JmR1#Y(W9K4`-tyJ%s9i;*QWKx+gUm#P4FC0F4uaZ1=#$ zLZWkO?(H2!Zm6MDmN5Q4PNTXcs&R&ndwWxdsVXS{wOqiDINYzM zOtm>k4DuK%e^8a)?k+@V#)oh-!a3wbXN`c7?#{8PexYk+aD(@m!SZF02Xlqolo~_y zT52w0eKuIEAG~%PHaDf_pOG~}kgGbB)<2O81}D=!lo_q37+E9K7j85Fg^=`i$Jjbo zsZcoHVh~FiM$ipCT4 z@sTw`x^`};Ia1mYBVX{z;L#&%gmkt-=UhhC2w^@0BTkJmj5R79W=cv(Tfv4#)(GjC z0pm0sqmQf+f+S+&F_a0Rt{qt;6eOX0OlQv4`if68Sdosb5sFKQ^M;H+`sg=2UDLS4 zCu{gb>p$EYEJ+zdQNA2Eab(YkHnK)2RM{HUBR|FX9_w`?>5Z%rqP4*{N7e|zYjh@p zkt+D3u90J#Hl(=^v(-baZ{eL`#K&V+5F=}Zf-kBJ`9$+yf5(wh)vBH{m3*&BQI;3Y{s_Ui392H|c>b}?X`-}|^^*8Z`Ezuky+ zT0QqpS#3x)K6sYc^HBDoSu3#Cav6SGuSPM(v)@}CN70%+*`nTqk21nXkLH4{1ut}0 z5AC@}&%3jSzJ3oX{fDGF^}cXM;o*Bl&yNB$t$Lt1#o`=YL&uy^hgH$HH ze_Cy7Fk3{)_Ixq>xU5PXxi{0ob8w{}QDO0(r_zo?pG#ivNIQPd7c-7etK9Qruwr_y z&R(5$2n^dj@4}Pd)w_4#++DlBzWZu8f$3?>Zp~VY>&RpZRbghd?zudz6<1$)3(5p*>&AzUTEr>DN7<%DyYBD_l!68F%5# zi?2^tep1(|z&BRH{=R_qFLice?;|~?F1ebB1;1Z>L-xrqLGYOdyE!@gzMdO0PJZJC z`o@p&{Ie_jZurJ|y-%c#s$E;#rL^*`3iw}|^u*W3xM!7vtPzQ1GR&Hk?KXd)FL|Ho zTPqUN)ppZwZHcps?b+Q~jeR=n?%AHb^YsMyq)puEY%SH&;4bdz^Koz7>gLw(%)Vgv zkJBq(KOMjG>Esh==NhkIpSTJ7fIO@@pcWaK;6|!(XFyiT%mC8e)Bfi(T!8)7c z4~-G5mH9>ouW`*qeCvw^KqI>T53=sV=edq!=zpx0IctCjZYtEUW*fgf4~n8*@u#KM zt>*!1J|GYH`Q8H8nSu(5$yzD!XQEXV{8{;34uOi1OX4ZkAcU~*@j{@0NsKPw(&3u+ zA^Ez1E0Voml@#Y*muiGtBH1eU@wJpNDXhVX+g}_`G>aG2Wjs<{>9b72)aM@2+BD~{ zb@H9qx}->Vx%>r+{un8<_(qLzPDpJ{wWGF58`M<@#H?1yw}Aq!T0J@;ML2a;ats0S z(LdF?3I9!SMStKQ#lHt_a1_b8pPzCKTbQ-dRa$zV#sqJtZUF{)r7dP-1t8xUvWfV#D-W%9roUXnY_~I?B$ZW?by`v`)Z^ z??EL(x$8!nNCCf_ z%ALZew1VyVSQqIb%|-e_;*4rRgNu5+&Xe-}aN^b9z@Z(h9gq^*Is3-=8OHxPuMwwT z=Z{GLo7hy>!TSfqX!i>ULs_XnQj}77;><{_QX}muA+;U#NcPkqO3qSj$FHaCuLH`H zkW}Bn_Nh&t(;p`}qwO{)(9Muu!5%sFq5Y&}=+7|!fdesc8StrGQ_fl5O%;X^Q zxF9RV7Bs?{m0doc15dX&<5JOh79t>dBn9y}NE%Y~ zv=@G(F+h;6{yG13h3jE0M08TJ-T$Bb{?hX^D`b&lF!DXV2UfK{XpE+Tmyl4yh9;KI9B(H(7 zfEssDNJog@`b!k#E(0{WdGxoG3-8xw#~j5{F7XN?#@`SzpR&-5suiiqh%k6WtE2Vx zs~x5cR*wd41zT1b^P6zge<>N|RyCp5csAO0p}x@bDRz-E4<1=WWDA&6ireT|{%%Y^ zOYj~RDC3^*R;U-#G8j!cT+o4pN&ubEcI&prawc^!m;oZS!MjPnS{h|b8aXhb<)qN) z)`6wMQ|a;k!E#n=ZK&_lq|k@A3{v6Imq?xJSz~LUO{wmS8xfzw#yq7>$B2|r1d}yF z&@}Tc-?a1Z1Vpfh&k3Gd%1Uj3M{ykdosfV-dueQ?hvO6Z%Ul?oF9!J05OEoHtVrkX7ZhoU!)@x*0g_5D(8|oM zp02e3bwZ6(zTEWqoydiGh~q5gr$OWIAmh3?H`JL*AdHWcvY`KPO~*!oY8O|Bw4v}^ zo))LsGaidEpQiI`o-)oD4z^`?cL(HZ%7HMQki&m=8sQu0I$owtkpfnmI(AUeDA*LZeNVU}xS-Kh zZ+l$!q-9YGI$Odc^(3xnA_jaSUm50|Ioc;9tlE^;!5Y_DE5vnWXU23Dmq8X~KqipQlYLhICxfIg&^|DRd9Hra8GetpZIRlE!Em`c zqNWdwgQ<3=woJ*>_S6#9H&q9un7@NIh%NGWZvZl~Z1&+B_PmGuhMH4zzw_NFHVml1 z0*{(mbv&jtsJAKHkgb&77_aWPL?T`tWw@-`qdo9VMxCd4L%E6crt|;({oer_{yoy* zVXh*Nbmy#KV68>H>mAg8h#^`x@K<=%CR2QMam-gE_NCXbGwS zbqF4i=pJmvV#jv*%fRQfd@q#0t$_b`1wgew-$})L@9rF2&%xktYrEe!KtK8c->+j# z=d)zf>^uYK7~}Q%vS}tXd?J78d*-jdd&D>j8Q@msneVa={cK%s(r4@J&-%}L`Z$i$ z^<6CeNQ)cU;T+==f3Jq;$OS%5zWyEc*t_3ezSv>PoP+%E&7q`D-=uy6)S&N3d;KAe z^wpsR%Cr&od-HC&(oQ=7?Qiq_;Z(T})O(P5|8+1i8~k7RUVF^e?oO2nH0|vWVvmi^ z8H4F+I#;XJ5HpL$KNvz}-?6)JQ*6eLvZkx@&&3bKmp(rqS!d914vMl%-KYab$tX+2 za~eaPKJlSU>8K%Zqz+(5))`PzQ9k4mD{HN^RH8c0qK(Gl$H+PZjpu!%0Vd$+2^Yuv z_(bu8u|L*VM|PAoV}{E_QOtOYd7`L}q@J`!r50I9sO}!mJ&S!xQBY9|zXy;Tg!tI)l_a9knz+X z@eWrb#ph!BDzY#l4iPwt!kn9M^Fh&gVq~2GY?*Q&S!cj%oRN>Vr}7BLI+*5gS}kv6 zoq^6Og;`a~ha(qGGK{PP6R?pl7@e{J*#sL1Po< zt_PW0_ty&KPW)!CHRsY4Vzw}0u+{&x3rd7r;ET4v*=()mSicZ5xeZdHJoL%09;M9R zY?r^K&UMCQQ^4Qm#w;^t^#L`KSpolV70`ShNsgT#Ew4rM@O`|$HYEJ*@>=SgevJPd z{=!Y*RXGkng34$9s#|hPo@oE%Tj%>jPRJWAy9c3XcR!qXCzQ`GkV7!4AVxlc(End3 zM$cI4BbA=i7P$-?*H@9Q!8bnH2rHia9g%FeOK*R9skievjDW$2NB(~>`mSDd&OH|x zEw3xzG|AqKFm&+d7KnM|+IOLz~XM?c&t^+Uj2jK?!J zn&MZ43`E>iE!=Yoi6BV`ulAEiKYNSfz2le95(nD?4Z+V<>fu}MChqIrk{qYxo)s52 z_xw1Dy?xJ~!ZS?bCN6!B5&lO5eaA~zowLIC)qP}7{C|wFb_GzPr;p@B!!#FIYr3Pz zd88ZNmK#4&9Wvy)FaE!7MYo6i%qY>HUfcLiJ zJoe2kq)LfdS0Tk@6X|u}`^lhG@7UcZ%NPy)-%s|jh#KM(Z(XMu>yLM8Q*A2c8dhac z9IM~<`^ida6c6zZvgej~{QqT;#^?`GIav<(-f;i-e|b}%UiwyMr8q&~N*dxFSx3jU zUL))1w9*|}N9X?kIL2&-B)2i5jjW?Xyb2j92!>L^-^e;TCSX>{nv%mBBUTKo>2!XR zS-CGRkF2Bfp7sCXI=ZMkS;Rk^k+oHFHZ#=guuFo7-PnWSTG-5iZSJr*f zV*D-fN7c}E!W?C~%{KgRY|UmVS_{lZw7X4*Sq?i`X1e;WR+uvMXg8f^1E84&jSCYc zMa4x+@KwDyaa8xV*5;*&1sl7&JC-k7*2QK;+0ypT4d`2Ecyq$6#m(*5ABOKX{F%Cn zvc%fX_QYZBZD<_{8a9~CprrvF&5_L;Hn%q5V5r-d!w#C!v&*zNfC+H76ucFu0$zS> zb7xmedt0J-X$ddw9Wg_JUV$IY>HyLfkV%B)PKYYnYGdNKR@8KKwzMXS%NJ8pxTvUA z3UL`g1S)|@7sd(Hn0lbu3S_547qP4Lty^18U*`J+P+cIb0lIEBO(3lulI+IaEf94x zWW+P;@!bs#H)9{<(1F#njUH`)%)W$w3|cL?ryVWA+k`6} z*obcf`mew_9yfx9&8`n=Sd05=2I-vuZM3a~nQzwMzD~d-J-nkHUUd}cJqX);oKZU1 z^Ch7w+8SFoHvz)h zV`}1=N7POPmz`lz~t4w|0;jKut-8atbt+X!S?9S|LP#9{M6(%$%) z8R$;N9Pd<1FRHvGhn39A1z0wYa@l<`bErgmGrF$E)yumtlU zy^(P=;jXQK(u#e9Gt2c3(k8&9nUK=0z`hQ9h6x%t!(6HiDLZwP({R)cSP4_GR|;AN z?it&b;I2+ck8ZOK+%)6yCz&MbXVCa;SI$)$-YAHyE5^RP8 zuERH7b1?0xb5R1sxD-7}L*z_LAt!2wA!3WuTZ@yR_78NcwRAvQ4NkVSt)V5IfJ7*D zYB_<~pFr;t9BH6RIH{?9kPG%7-u_e$-GJJN{w*%-Y`{I_D#&XK+6*4bGXvIO_CL6s z8XP1BQr;DUW&@78oP4?=Ctf3!8g5TRn-nCx|0Lj#hnqv4Z?-sjcA*C?dv9O_uhp>D z>ZF|N9jam4D8n9GDmB_t+_o8zY5xt-7HL;cWh~H8ulEJ(W0Kf_UX*MDzR3@{UH~rJ zaX2%{KJkjJ|==kemoplSe!?>Afrj^lChX zk+OfqH#PPtze_+>D0K>$6pnA-oH(rJ_{8By9K9TYzqJ+lprs3eysf)0$S><`Zffc3 z?rd4Nxw|>KjvRp4zRmSbG`6?4BI>im=xpAAoYC6c<p+WIZx&qH{Cku>$A& z$qzJiw=^bNHZ^QOE+t)CAVolK=#1naqp6`Q(Sb|M+YO1X_VwLc8#P=@>`yg{o})9_lEJnZ{rSY#g4W<>ARpKA!kZ#2ea^@KkLwMrc#< z{Bk;er)?&lu_f^Iy#T+SI2X_0=b>g>fPk{d?1$od30!rV8@ZI2Ql#2)B-~0q*AJ+T9(TS zStZVKsiVbmP6!FIZO_hBV;XpAM{8$N{*IeY z`K(+ipOdTPYPm)}FW1U-a=qLjH_8|AF5Jy>i+oXTl`qL{@@2VQz9M(XopP6aRqmFr z$vyIQxmUg+-;{63x8*zXUHP8eC*PMH@&mbFekc#fkK{plNFJ6S%Omm=c~pKXkICcm zg#1jNl%LB}@(X!deksq$ujE~vzsO(ZZ}NBf2cGS}F1zHP@`mh|J@TgX2;K^W30s?H(`|;$v{^RW=Gako zv>ju|+Hp45=GpN!-%hX-?LKyr-PcaGQ|web%}%#7>`Xh$ChTlmVCUGmw$RSA^X&q= z&@Qt3*~NB=U22!vB3o=rY^g1?<+j3B+A3RZm)jL~rQP4IvIp4Jw#L@lI=jZ!+oXMu zJH&R-)~Q}AFwCclkF+C!LGB7 zw#hcz^>%~ZXj|;5_B7jSH`zAZZaeG;ZKv(B-FCCxVz=7U?KXRc{gC~z{fIr&o@LLr zAGPP$?e<)Ip8c3T-(FxpZZEW-uou}++KcU{>?QV6dzt;Tz1)7rUSU6Lue6`DSJ|uW zHTLuNT6>+n-rituv|q3{*_-Vx_KWsb`z3pu{j$B?e#PEl@3eQ>uiCrq*X%v^>-Jvz z4f{>|E&FZz9s6DTJ$s-1zTIJeVDGm-v=7)H*$3@I_F?;D`-uICeboNcK4u@cPuQQ? zC+*MeQ}!43Y5U8Jjm<~`Sxqeso7&r&(lHWSmw}O8Q*%~BXJ`A?%^f*z-`c#sJ8N@W zOHol}GNWrFu4f;WEUGTThX2Ylv4&J(U+?!x-B%X*eX-w{_)Tg056%@*wWe9+MLtUwq@OB z6hhrR(sTQ+YejZ$ZQt75+1auIr3=f44Xw?SqVv>K>gmlL9nGEb(+b6%PJxosxUsqM zv`r12r;)TZ^=q66v3DZG-iZu*Co=3E>)1QdVedqMy%PcUP6XIH5n%5`fV~p|_D%%Y zI}u>-M1Z|h;hOq-kH6mIulM-tJ^p%+zux1o_xM$1xZmTi_xS5Q{(6tU-s7+L`0G9X zdXGQp@h3h0q{pB1_>&%g(&JYXSyP|%{3kvBq{pB1_>&%g(&JBh{7H{LsrZvcia%MT z_>)D7AI|3VlPpsF$s)y{EK>fHMT$RJr1;^bzQ5v67AgK@k>XDlDgI=U;!hTN{KX!B zvBzKR@fUmi#U6jL$6xI67km809)GdNU+nQ0d;G;7f3e43?C}?S{3RZLiN{~!@t1h~ zB_4l?$6w;{mw5ao9)F3)U*hqXc>EhYI){AC`0na5w|@t1l0WgdT-$6x00mwEhU9)Fp~ zU*_?bdHiJ_f0@T$=JA(#{N)~hxyN7b@t1r29)G#VU+(djd;H}d zf4RqB?(vs<{1qO5g~wmv@mF~K6&`EO}zow8iNlhWx zd;FS0)+8%E{z{L((&Ml6_$xjBN{_$N7kH6C6uk`pUJ^z)S|4NU)%JX04 z@oUOjlhl-jy~khW@mG2LRUUtp$6w{~S9$zZ9)Fd`U*+*@N&{SvzuM!k_V}wk|J9y< zO?_*U)gHg5K(sx6O@U~8{M8Fb< z{~C|K#`9m}@z;3#H6DMB$6w>|*LeBYc>J{+#om{Iwo`t;b*M@z;9%wH|-1 z$6xF5*LwW59)GRJU+eMLdi-@Bf1Sr)=keEh{B<6GoyTA2@z;6$bsm46$6x31*LnPP z9)F$3U+3}HIsEnY8egz?@UeIBv3KyXckr=yaIp9HY22u<*LZ=wqZ4~a2ll?d`e}W= z`Y9?c4`2NUZ4Y1lroLGHqduwep+2d8U0<*EfxVLt_D(+7d%S8NXnXi-A832{Y9DAj z`C#wlgT1Fy?E`HmAM8D!Y9ICWY9H8p{AwR)d;Dr2XnXu>A8330Y9DBO{AwR)d;Dr2 zXnXu>A1H5}ePHkG1AC8O;{)0rzs3i&J${W3XnXt`AJF#rH9ny2@oRiQ+vC^xP+za{ z0eg>M;{)1W{u&?9_V%Ok0c~$T8XwU1cA@bBZ7+X~4`@64#NOlA_)uT3{(-&6ul|9y z=Ue>(ZO^y*1=^l(^$WB;-|81=d%o2#(DrzPUua!i@9SagJ-=EHqwV?CdKhhwPwQZ` zJwC02(f0VX{>6~P)30?c+Wvm6ThaFN(0UbZZ;x89qUq(K^(xw)KCM&H_VU(x6m5l< z^mdf=cI5L+z0Wh)D_==(M@er-NpD9GKTQDj%O`&{p{-bsSNj)cU_Zsr&+Mk~3{w=jvwR#$Z1ke_XS? l5u2Fn>xyP+cGM-UlOvGOQ;kXUhyq%J7Vsq1aK~JrYSc_?<^^ zI5U>~EQ!b-h{}2900TD!vv}&ZiwC0>#Oc^yq$U2=;2Vgo)dRBkavsmArEa2(w!-PB zbt6o4LyCJIYRR9ybRS7bk`wit?HnR>$5B$7MLQKS;|dUCk)~=w zI`tWHW?TdZnME;`EdKN7z@8WMZEkfdMYifN!gqb|s#L=YRZuNisMj@k5G(rnz-i7# zGcAJ(bxYRI|EbL-;6S~`Yve`}T9nd|+W5_#P!^bltl|4s($`-xs9Cfn^8W!iJ3&#D5WJF7Vatdqkyqh!ZX$!}NRvqb5%9JHO}I3|H|R9*lzxpM#AXH}tk?zoLnktH$y>{Th*#AT2tncVZA z_>XHJ>sBH%i({7RgDd#kYl}0Ap-;gX+1Imn z-0^1jvOMo@ILM|S_UPC5xaKLK4&p<-Mt6ehbca~Vbs4|Nj2pT8IYEN2!%K>Rj60f_ zomqRF+gGqNAjTim3fsu)O;C|VrlCckQf`Ke;>bYIR_<#<^~sT%NfXarfU}zgS-J*$ zz0#n5Bq1`3__ETqm2Xv5Pj!r5^h!M}{XXjSm0CGRy+K^A%(Xd2(>}Ow>D4uak-z6V z#0SI!toRxr2V>jC`$C~*BYG3FMN9$Bu@elB!lQHHk(CjFr@p9Cgpb&D!buF4U0ldR z$R4o@rjyQvjLQGjKtDWg>?bsKNSIqwrS!yVZFR+H{>2ivF2Oj3EYmWHHKXw0)QO`B zZx!jzKX#U<61zmZvrr89Cfq!4UNzoz9m>bviGDPKJGq6=9L9W}v0Aph?Ri(U3TttrXz zW4BkF9<`N#F1&r%s)ZNVYfAi6#d9=h+;cbru|D2Tm}%>!ZM(9r3n6_C50nh^`%W>L#`!H~Q*f_!T;E7`iH6XiNXu(IakEuK~9Dnhlc^Oj6 z)S^@Ettk91Quj=`@}$Wks!-Bc^64R`UDHIjsO=GjLLOI0pAQ_(6(y__1!lt9FnMa@uc+?M{VyY?P$|#kx{oqUQ8kO@NeHN41bv4^v|-Tovw$ zPsQ%WNbFo|jJ$A*X-OX8D&BPEE9P^%@@)DZ;^h~&1_dv^r0gDjoA-<&wd@9T$ylkk z*$hH|Chth-%^Gpywsto2Vk))0AL&bfrrf7m%E7gCm)*Zf;?r;u2To3bqvx}MT@M$k zO8!pFCb8)%xgF`|GZcpfszGCC*GHTA6|j{0P|jH7?Tdn_r9RagDg?i+n0R6rhr#+5 z`=$zPAE$=TQx;AzcE29krT$P6q-fhheQ0OzzJ!z*s1L?Qgrk0<`_7N*517T$96u~- zJTVbZwh!ne?fg)HH}U&wj-pJjk^x_Zt_s=>o#}9I6$&bMkvdjEa)zxlU9AGhO4v$s zr`X+*YCGdZU!_@qfIGG!5#ASpPx@uv=I(MV;jZ-z7w2pjyXiLd8uDp>hW@pik++C~ z7U3swzo2F&mEK_r8VY%{rSJ-Ju#&g=fQ@bupWbk4e4=ZQ`Cd!H@|bj}k`#x>SYBjJHo2wb0_aiJy_`>4Z$PGP5KK;<~p`NE4*dktLE_M<=lj5E4bm~xuuH+gd9 zno9oVQdr5@^cc`v(CpMwYFaB%9!}%TjJKJ6swzm(99S5j4eKBiH2aJHv81{bSz_g% zs=!dN_Z2qZ&UY;=)5BlHxYND514vXWY%sFeGU4LXW5|zbC?y`butqc^QtF-4HXL{% za`@enhlSZ7|h+@J@fIxJnF!rdCipti=BLdAw6+ z@{g#t7NAIlA)0#*cToE7_vv$zjpupI)gLQme=Dnb`P~0cZp1uV6=2O8TD`b$O`6XD zfAwB9iN0$?hwHb#R5lk$*YD1Q`T3Bj#QX=3g$)56iT(EqgK!U?*qRAkM|;6Z(Wz2{ zgh;%P#*%STG=RT6=W{o!!*?pD_cwVPEYCe1#xHwK{#^L@USPFaTyj0 zCh#JhJ@1e6B}$^*4R3MF9Mk?ek(609<)8P2EZabWy86n5WimH$gXA9HuqFnpZwyu! zIvn@YU=n=sg8@xVMG_co?-FzKKZrO~eaPa{#M4+ti5CsD)H|qo>8-vRPfj|>v0}-7 wST5u06KB*B`;GB}JFA%6y=gkpNoL=%wAe#S*khBB-ya^ZK537yJmHn_Ur1KX7XSbN