From 8019e877ca2549141b9a2df81374344e3bd442e6 Mon Sep 17 00:00:00 2001
From: stephena
For space reasons, the Prompt, TIA, and Audio displays are split into -3 tabs, only one of which is visible at a time. You can use the mouse or -keyboard to select which tab you want to view.
-Pressing Ctrl-Tab cycles between tabs -from left to right, and Shift-Ctrl-Tab cycles from right to left. -Pressing Tab cycles between widgets in the current tab.
+ +The main debugger window will look similar to the following (note that the +letters here are for reference in the document below; they aren't actually +present in the debugger):
+For space reasons, the Prompt, TIA, I/O and Audio displays are split into +4 tabs, only one of which is visible at a time. You can use the mouse or +keyboard to select which tab you want to view. Pressing Shift with the left +or right arrow keys cycles between tabs from right-to-left and left-to-right, +respectively. Pressing Tab cycles between widgets in the current tab (except +for in the Prompt area, where 'tab' used for something else).
You can also enter the debugger at emulator startup by giving a breakpoint on the command line:
@@ -144,7 +149,9 @@ already contained the same value, that's not considered a change (old value was $whatever, new value is the same, so nothing got tracked). This may change in a future version of Stella. -Prompt tab
+ + +(A) Prompt tab
This is a command-line interface, similar to the DOS DEBUG command or Supermon for the C=64.
@@ -158,61 +165,17 @@ scroll with the mouse. Copy and paste is not (yet?) supported. be abbreviated: instead of "clearbreaks", you can type "clear" or even just "cl". However, "c" by itself is the Toggle Carry command. -Bash-style tab completion is supported for commands and labels (see below)
+Bash-style tab completion is supported for commands and labels (see below). +Other Bash-style commands are also supported, as follows:
+
For now, there are some functions that only exist in the prompt. We intend to add GUI equivalents for all (or almost all?) of the prompt -commands by the time we release Stella 2.0. People who like command -prompts will be able to use the prompt, but people who hate them will -have a fully functional debugger without typing (or without typing -much, anyway).
- - +commands in future releases. People who like command prompts will be able to +use the prompt, but people who hate them will have a fully functional +debugger without typing (or without typing much, anyway).Commands marked with a + are partially implemented.
-Most commands can be abbreviated just by typing a partial command: -"st" for "step", or "f" for "frame". Where there are conflicts, generally -the shortest name is chosen (so "tra" is "trap", not "trapread"). When -in doubt, press TAB.
-When selected, this tab shows detailed status of all the TIA registers (except for audio; use the Audio tab for those).
+Most of the values on the TIA tab will be self-explanatory to a 2600 programmer. The top line (with all the hex values) displays the raw @@ -677,141 +639,232 @@ Strobe button.
drawn in the current color. Changing a color register will change the color of this rectangle. -When selected, this tab shows detailed status of the Input, Output, +and Timer portion of the RIOT/M6532 chip (the RAM portion is accessed +in another part of the debugger).
+As with the TIA tab, most of the values here will be self-explanatory to a 2600 +programmer, and almost all can be modified.
+
+
+
+
+
This tab lets you view the contents of the TIA audio registers. In the current release of Stella, these are read-only displays. This tab will grow some features in a future release.
-This shows the current CPU state. All the registers and flags are -displayed, and can be changed by double-clicking on them. Flags are -toggled on double-click.
+ +The 0, Inv, Neg, ++, --, <<, and >> buttons affect the -currently-selected register (see RAM Widget below).
+In the upper left of the debugger, you'll see the current frame of +video as generated by the TIA. If a complete frame hasn't been drawn, +the partial contents of the current frame will be displayed up to the +current scanline, with the contents of the old frame (in black & +white) filling the rest of the display. Note that if 'phosphor mode' +has been enabled for a ROM, you will see the effect here as well. That +is, no flicker will be shown for 30Hz display, even though a real +system would alternate between drawing frames (and hence produce +flicker).
+You can use the "Scan+1" button or the prompt "scan" command to watch +the TIA draw the frame one scanline at a time.
+ +You can also right-click anywhere in this window to show a context menu, +as illustrated:
+The options are as follows:
+To the right of the TIA display (E) there is TIA information, as shown:
+The indicators are as follows:
+Below the TIA Info (F) is the TIA Zoom area. This allows you to enlarge +part of the TIA display, so you can see fine details. Note that unlike +the TIA display area, this one does generate frames as the real +system would. So, if you've enabled 'phosphor mode' for a ROM, it +won't be honoured here (ie, you'll see alternating frames at 30Hz display, +just like on a real system).
+You can also right-click anywhere in this window to show a context menu, +as illustrated:
+These options allow you to zoom in on the image for even greater detail. +If you click on the output window, you can scroll around using the cursor, +PageUp/Dn and Home/End keys. You can also select the zoom position from +a context menu in the TIA Display.
+ + + +Below the TIA Zoom (G), there is a status line that shows the reason the +debugger was entered (if a breakpoint/trap was hit), as shown:
+The output here will generally be self-explanatory. Due to space concerns, +conditional breakpoints will be shown as "CBP: ...", normal breakpoints +as "BP: ...", read traps as "RTrap: ..." and write traps as "WTrap: ...". +See the "Breakpoints" section for details.
+ + + +This displays the current CPU state, as shown:
+All the registers and flags are displayed, and can be changed by +double-clicking on them. Flags are toggled on double-click. Selected registers +here can also be changed by using the "Data Operations" buttons, further +described in (J).
There's not much else to say about the CPU widget: if you know 6502 assembly, it's pretty self-explanatory. If you don't, well, you should learn :)
-These buttons can be used to change values in either CPU Registers (I), or +the RIOT RAM (K), depending on which of these widgets is currently active. +
Each of these buttons also have a keyboard shortcut (indicated in square +brackets). In fact, many of the inputboxes in various parts of the debugger +respond to these same keyboard shortcuts. If in doubt, give them a try.
++ 0 [z] - Set the current location/register to zero. + Inv [i !] - Invert the current location/register [toggle all its bits]. + Neg [n] - Negate the current location/register [twos' complement negative]. + ++ [+ =] - Increment the current location/register + -- [-] - Decrement the current location/register + << [< ,] - Shift the current location/register left. + >> [> .] - Shift the current location/register right. + + Any bits shifted out of the location/register with << or >> + are lost (they will NOT end up in the Carry flag). ++ + + +
This is a spreadsheet-like GUI for inspecting and changing the contents of the 2600's RAM. All 128 bytes of RAM are visible on the screen at once. You can navigate with either the mouse or the keyboard arrow keys. To change a RAM location, either double-click on it or press Enter while it's highlighted. Enter the new value (hex only for now, sorry), then press Enter to make the change. If you change your mind, press Escape -and the original value will be restored.
+and the original value will be restored. The currently selected RAM cell +can also be changed by using the Data operations buttons/associated +shortcut keys (J). +The 'Undo' button in the upper right should be self-explanatory; it will +undo the most previous operation to one cell only. The 'Rev' button is +more comprehensive. It will undo all operations on all cells +since you first made a change.
+The UI objects at the bottom refer to the currently selected RAM cell. +The 'label' textbox shows the label attached to this RAM location (if any), +and the other textboxes show the decimal and binary equivalent value. +The remaining buttons to the right are further explained in section (L).
-Nearby there are also some buttons to do various things to the -currently-selected memory location from the RAM widget or -CPU register from the CPU widget (whichever was most recently -selected). The buttons are:
-- 0 - Set the current location/register to zero. - Inv - Invert the current location/register (toggle all its bits). - Neg - Negate the current location/register (twos' complement negative). - ++ - Increment the current location/register - -- - Decrement the current location/register - << - Shift the current location/register left. - >> - Shift the current location/register right. - - Any bits shifted out of the location/register with << or >> - are lost (they will NOT end up in the Carry flag). -- -
This widget also lets you search memory for values such as lives or remaining
+
+
+
The RIOT RAM widget also lets you search memory for values such as lives or remaining energy, but it's also very useful when debugging to determine which memory location holds which quantity.
- -To search RAM, click 'Search' and enter a byte value into the search editbox (0-255). +
To search RAM, click 'Srch' and enter a byte value into the search editbox (0-255). All matching values will be highlighted in the RAM widget. If 'Search' is clicked -when the input is empty, all RAM locations are searched.
+and the input is empty, all RAM locations are highlighted. -The 'Compare' button is used to compare the given value using all +
The 'Cmp' button is used to compare the given value using all addresses currently highlighted. This may be an absolute number (such as 2), or a comparitive number (such as -1). Using a '+' or '-' operator means 'search addresses for values that have changed by that amount'.
- +The 'Rset' button resets the entire operation; it clears the highlighted +addresses and allows another search.
The following is an example of inspecting all addresses that have -decreased by 1: - +decreased by 1:
In the upper left of the debugger, you'll see the current frame of -video as generated by the TIA. If a complete frame hasn't been drawn, -the partial contents of the current frame will be displayed up to the -current scanline, with the contents of the old frame (in black & -white) filling the rest of the display.
- -You can use the "Scan+1" button or the prompt "scan" command to watch -the TIA draw the frame one scanline at a time.
- -To the right of the video display, there are indicators for:
-Below the indicators is the TIA Zoom area. This allows you to enlarge -part of the TIA display, so you can see fine details. To set the zoom -region, right-click on the TIA display and choose "Set Zoom Position". To -set the magnification level, right-click on the TIA Zoom area and choose -2x, 4x, or 8x from the pop-up menu.
- -Below the TIA Zoom, there is a status line that shows the reason the -debugger was entered (if a breakpoint/trap was hit). This isn't really -part of the TIA display; see "Breakpoints" below for details.
- - - -The ROM Widget is a disassembly of the current bank of ROM. If a symbol file is loaded, the disassembly will have labels. Even without a symbol file, the standard TIA/RIOT labels will still be present.
+Each line of disassembly has four fields:
Speaking of banks: Above the disassembly there's an indicator for the current bank and total number of banks. If there's more than one bank, you can manually switch banks by double-clicking the bank number and enter -a new number. This won't work if the ROM only has one bank, of course.
+a new number (or using the shortcuts keys for inputboxes as described +in section (J). This won't work if the ROM only has one bank, of course. -If you patch your ROM, you'll want a way to save it. To do this, -right-click on any line of the disassembly and choose "Save ROM" from the -pop-up menu. You'll be asked for a filename, and then the ROM will be -saved. Note that the filename is considered relative to the current -directory, not the ROM or base directory. You can enter a full path, -though, in which case it doesn't matter.
- -
There's one more thing you can do from the ROM Widget: you can set -the Program Counter to the address of any disassembly line. Right-click -on the line you want and choose "Set PC" from the pop-up menu.
+The ROM listing also contains a context menu, accessible by right-clicking +anywhere in the listing:
+Currently, there are two options:
+These limitations will be addressed in a future release of Stella.
+ + +There are also buttons on the right that always show up no matter which tab you're looking at. These are always active. They are: Step, Trace, -Frame+1, Scan+1 and Exit.
+Scan+1, Frame+1 and Exit. +When you use these buttons, the prompt doesn't change. This means the status lines with the registers and disassembly will be "stale". You can update them just by pressing Enter in the prompt.
-You can also use the Step, Trace, Frame+1 and Scan+1 buttons from anywhere in -the GUI via the keyboard, with Alt-S, Alt-T, Alt-F and Alt-L.
+You can also use the Step, Trace, Scan+1 and Frame+1 buttons from anywhere in +the GUI via the keyboard, with Alt-S, Alt-T, Alt-L and Alt-F.
+ +Here is a step-by-step guide that shows you how to use the debugger to @@ -920,7 +982,7 @@ but it helps to know at least a little about 6502 programming.
J=pCf z&dn|i2EAi7y~@pj++q&o$mor8Q?3tlAh(Ps+Z@OXsP}e%q|w}dOMo24V@E7KOLf5y z2XDAmyM}MHsKE+XFd>)iXo#F`WwCpL4EQTa!oR?T`r2H&~q|^!<&8IkC zMZAa0@ZON86h17e{~{-hN58~eQyfY0k5W$kSM?M!9)p50x4=WX$PIs=7ou0WIgne- zfgBmVac;`>VGiV$@no9=c|l|~M3B;_hgW;us2G?<^LXi{Zy(T^SOHPs?k+391@o`# z!?Bk~M0v2duKfU-abh~*=fiIKuotpwoCp2pR`e3*^{J|SY2 5m;*U7dgI)b>%)}mL$C7xI|Vyydl3UP P00000NkvXXu0mjfk>If8 literal 0 HcmV?d00001 diff --git a/stella/docs/graphics/debugger_iotab.png b/stella/docs/graphics/debugger_iotab.png new file mode 100644 index 0000000000000000000000000000000000000000..f5a30c7a1b77c3bee349bd5d55e5716b25a8a823 GIT binary patch literal 5996 zcmZvA2UJs8xBm?h!GdutBZwrRABsrP8R>*jRFu#plo5nb6lnn@Kq!HrB8(#lQk5PZ zs?wwhfdq$cC{gJUf*P6$0Yfu{z`K6$z4hLIz5lxFth??$_ny1YK70T6Z|_IemZnmB zkM9KlK ?z62aFjE=!C-Bw=EJwo_X%D3S@j{70}!01kKCKNv6xy6qNx z`<6VxJJ?I!^qPgW!@UE?0N~fIYnO~{!^Rhx)j^Y2?(cTBE^K|jD&27QcNB0~4>O 2);YDx#>p FkCu}q!JbHh|0=0 b*+0Y z=SPy)eB?X{QO&XwHjPuecyrHca3(Xe6|dS^W$i-$Y7y}2;TEIkP5oik@rh3X ^m5@Ll*lklpGcwox@c)xEvBq6N78pq77!-$C1wu)NOS+Hk+Jb zlkHbVHz!zDEhxt~CKJfea5o>+Ugy1kaPoG=xGSJSzW6}HxNMmwOTE=5M$cQU%SLGo zw(QXP!M_k3xsn<1t-q74kk`@;O63;*)i}ZvwCu9)St1N%Vt^MWE^k#F+{VyFv~wiw!-7r zQ^`WTP8Y
t&SlZyBx@#MCvGmEsJWQj)($dEr=l%i3C*m<0;g)b9mWV9> z9gyeF^0$8U{Y$3nd&ADA)2EAF**@!=L2F&&S6Az0_n&CHE=CopSYfH-rjXfsc9awl zsPEql1r%U_WH?~h4F!zhz(GE!n8g2)wK`!TT-IW|6-mIH5!_u3F`?VAJo Q}wk?kOROEp6vS1R)}#EDhVKrVC4Vl(yV65qC*Sf`&J!!D|F$ z&fkSBq+5peJvnlRlgU0xoXG8wnRo~n=E!e7dFD0QC6?zK=a`P67r&36B5?*rb`qQ< zz8qf)AeDHK4)O! &yeXbMXNmWT713w?C;|UF3cD{S{q{j zX}w$&j-lAc*9Y|B>QSShimgV*hlOniwWi)(v%Jd8Fn#3zPhr6EGEx7m&II9a%Els0 zIEtuce~vZEKfY{2_!`d}9*9ax e77L&I*M)MBG4aQ0a1%ovtNgI3op> zGuKrl_)4pBSP?V`6n2)sUlSzK_l3El;bbVFDj>;5`nht|-Z6SjF>Tuxq6%!NpVOQl z_9;aUMfAyf#M>;+-}cHX^5)$MU7$r0CN5fhYNooRRW@$LTRE;g%A*o3B19r)BsNR* zZrl1K8{Y+0yO0;i4StSqi%9$)n;*UT74>;aL@;Zu{rpkXz!xf6H6Gqvn;F+{zSuX1 zrEScNf!0)X %dIr;Wxgqcly^aZ@_m|^xzLw^gtu`2*}pz zOlO18RAyFs%ph)8j7cmJ2hlsS**Nm;vF**h$TI`|r3b}i&6-XlKK z#RxU0Bk*VR?vb8xP+7{-ugXk@Jq#j^F?=!aH%OTj>f~Z}*@<574|Cl(q%sW`9-|>W z9O|iVlsqiE4*eM^=<`Ed8*>e`N7 Wb;oLXQ7XO% zMH^6AnzJCCF1HEZpoWLtHSXFjP=o>IK^9=->H}40DtgqFLey?OncL>Is6!6&O^@oq z_{s4}R_~XZ^}%QiRjnKGDThCCY@lzul1en$U7dLd*>53!#2@}+&(^HU&t3d%o``9i zO~|d-+NS3VVxyxPHDT&>)HhpB=+DC&irdQB<6JcSK|Q->n-Sr&?}z4z* sS1aF5}QudLgC!E;U%yt7NQGY2$Q2 z;?> AlqjiJL>-x8`c5({gxdp+9Cf*6Cj-wBslRj}WKcP%tqh;c zSXAF9Iw8zT<6q#EeAd~V4784B%|M0&-`|*@43mh-&^L_b(Cgm+@{bQwP55BZk^VDX zWjhDS6lKk*9M01Rlhn0Jtgrs^e;N>kIKvDrs@Q*HUHvR?Q@ru}lNxX_NdabaYeK|* z14HDevBJYMDo?z+`qP46gGZngBpHjX=t;WlMq;GopVzG48nvz#v8)m;P_<90S!?ts zIL=@stlXnqApn0y^E#;I^Is<(xEII@ABf1V-Cc3ZHZ#J?d}Y0QmDO$E1RN{3!(6bE zF7XFCln~`F-7odSU%pax4p|pdHw_6r%-492dt_w?Z^8`qyRB>13_xBNjuQEW#-R%t z;XLA6ow?mU;Ic`y(h;=8)Tl*hp)y3#*s&E_B|+g-(DYH;3$#&qeA )b3NO_o^Vq`#gO-E%PCafjh+e7i|&s&8za_tjyMhVh@Z z`DyDiDS@@pMrMb8aUOqja;+l`CQjgKL=lQ96foA3yAlaie{<+V-M2>(doP3{trK-p z9}~CNBC$Cj=A8fX@4PfpwI9>xenrI<-NebAhG;7>*8q7o I$t3UDYA1-R(J5O4q5E#4m@(?p}{? zY8l&n+;bK+jKts*UnAaER%ZUqP;z$JcXJ K VIZV5*wsxgrl5ahp zb6r%_dA4i2^@^&X)R!-^U$Z_(Y44LF`|=~-ey@-n#Ea<`6KVI8n-0vZyho&`UR;ld z#uAm%gmjzA%y<_>B)$XQwA|1{pJ0CHRY>%I?fV6l=DP|6GC+QjHT%DOqU?q%+LMgG zFEL#JM%hpL0m9<{xB-Z_|36u)(esD?M!x16zD0UK?A8^7olx3n6T-kia33OFNPz?W zQz o6CfHFpLWsdC{?T%t&)Ucl5DZ&zbzLeFG0G;}Al=Fb;Cok7AXq#D z+WOg;D!YmfX=vau@dN{a`x|?t>?%m7j{O7fX5+;y=X u(s^GZT_5yvRBfd@}6zLav zV)$DZ0v`L5zs0=#%}DA*>tOOnlgjK!8I^{UOy_~Ybyd3?OE8tAc%9y;3zFeio}YbE z7dsm>zpX!)V&BX7h~eap=RM0uFYK-dOuJJ%Y- Ro`b1L9OlmP$m2r28&may$H0{2sT^Qny z)}b(c#^V>7*6)7E%|3a$ApVIE^q|7Hc3#})oS6J9jUcbwvo)5p#9vh--WW$GmU _)iSpm6e@VH1L?uBF;a1jJuK4LZFG|vkIJ)f4+Q_k@*63I>Obcq`3;832|)s&uzppCG5Gyo@oDmQ86a=P=f`b=*{^ zOO@FV&reT2ox%X6ASL*2 q7{ghf^M(2(Z96p51Yr9sn62a%PT7y~%X8a>n!(rR7HCQP- $IK?|3-I!e-Rdo{LjIB_IXhnbVzFU0WHI$kfR%WJ zKg_ l#Y+Ot9}&9T>Cq2I_n+$Q`3^fDr5a&24N&$*x00?cV^l|LBEb@`DbzMv^er{ z98n6>=l|jOGuiP)8pWBPnN6DtJ2PKeSeNGnk)G%r1=PRGpzCtxR1jHLbkC%T>pqU% z8oZa~RMf7~!U**nOG#?%oFXN1_*Ds-!Nrc_XW!}CdrK>`U_zUtd*4}&oQ 3lY}L0F3VFmEJzB0f@PxSpLDj@n*! =W<$=ohG;$?0&Pk!L|DXZc6%^;00av>HP zvKVUQic9ayyM>Vl%o6gE7n!%-2g&!j#MP pJ5x($?AK z)~8UZnB<1L6DXBGuAGYz`n>l_#Shc88a>)Lw@tdC*|xfwZ=VMDeUKlK{4sfBD(>`C zhyuyR^RJh2X03-juK2k W(tjg%Hc|SxS;YLB2U3zb%6#Jf!vKS_*?SRNX@xyO;%8JQM{OpVFJ#*0yjltQ^u}zRhJBO%w zq{r+7?JpLUI%E~bFZ|Zip>pT(ie}420 h291`n^7MHr`F!$ z=(0%IuX_d7)17I#%K0_hEz)~APN$AqlLu%_(-t+)g6D@mb;cdvH+FOxnorQK)Iy(7 zLc?P(EY-0!RX)5KF`G-+rEEK#VpWP$*MQnJ2uUTLSoi*gawv7;jRRy_#VlklDLvnD z3K>umE6+Z+XS0q)32udnix>levG$QlxA0BiS((r`f~I1Wjib2*E-SG%qH9a1Ctn0$ z&&=zXF|5S#Ji*DjW<%3%hvTaUEVZK*Tf-rIxu8ELvI3gXxOCqR{IEyRLPiuXNc$$5 zO8KPzz1Qc_+DP 3 99rk-8lVE_` p~gtHy<)4YHo!f}rZB(hl#6nb;aN6^zz);9 zf`J9gfjyhN!4xMir&;Dsa2K>HmT6$@aB{xkAReq`LuG%KCUhOn=kD?E9FOM@z^^oX zs6y&uKY@UZ-17r0(!#@@!wt`@hN)CNNFK;l4qYhqqi~qY^Cp F|%(f!SA9- zw-WZHN0z9tyAGt4LY0cl=YgCEP1J3@dV^7q`%Z76)^_M<^}$)Pfk;h6&e)lpF-hvz zg@KgOUh;dX!Yi~&C0PO%y9IgfEtOSLAk~NZK(jhCm?9Co^~GG{mDr`5jIOEF-$OAK z_PSf3+uyUeZ*XhgJG-9Ps~eQrR_e&FGoLvgxnkkvI8h#gc$uB$Q(r&hkve0Jl$yRl zGFIIrGkB=*)EeTvhU2!R;3@R +rh z>b%tQm1Fqk=@0WPy0`ah37sp_4+O?!5Pbkkra(8in0s3F+ta*zrDpBJr)GyHPhA)U zy?3;jL)VD-m)`Ux1=NtU!KyjO-c9Dy8fuj?Ift77_B*dsga{ZMV`mYUE@BF2KP#5^ z4!&J$y=P3_9G<%bGw!W<+t>mV?eSW#C%$$+=!g)WtTpOhvMG^JSXEI2xE;Lw)cnZ9 zlZ@LBNAKJn*dpS5UfnzgpO#k@jF!63)ju&A_@~IyE_?H}KcVGL%XhVlcK)PBUPR2| z pI+f;yE&ggI(`vS(O3_2p7lw-}sVhxZeao-ztl!J5VO&=)FpYY5KM|*U4px*+ z{1p9G!*fBSY`6FEt`k4A;EAKX+4{dC`3}?vS3QtEjf+_wht*tqM82J~M_k3}Qu{N~ zLh$kunl^rrHh${Sr5~gq#p#RBIuihR JUJ?*DI$;Vi^@H+F$Ffs0{$THya;mXCqswBNF_cO2h~^L7;Q!tL%R28K-9YzcRGk zGYEJ$d5M@)iTjJ*{K%EOr_7brU+!cIKA27X(o*ZU-}Mdp4h_1_MYx38gwkc*UZOHd zCF7e^-SNe@DSyh2XSmtf-H_tkD&xlWYfwyMU{?2ip2&)}k0E_}Wh<8ZG7h~P=_sRb zYuE0cSn~{h*~|DOvh5A+u@HSbv`3|!r@&=MCz|fhJtPoa-)^EiRzP4X@c}OKN|0%u zJPqU7pI^!7nc@%)f5ZD1ly=uyo65of;78ekT77QXgHQ)8yt|soO1U6-j=Y;Ge~zB< z8&Wacz927afHC_{_VX}mu{cr GwtT z#qPwH?LbH)B@I&=#@ZxpOQ%J@;Ub5Kxk?x4;Q#1JBKA+&;cV%;r@uSDvLalro0vV7 z9gbc`Y7mc}H@s(<*R&+BfHTDkBrBXx0$+#jcD1c4#0V&8X^&ESq;=ajq8%{j0r((y zPJS$lGPo*sU!tvy>i`Zgs}nU<=4py*w<+Sa`?lGf@QnEAMDVz~oE6NcEN~#;jMcEr zKwWG`lf(&QX#aFNTg?LQ3jn`|RqkP1OB-`_`I4UA _`bT5XHN85hq1z>~KQZt(ph*)6EJ+rTr( zhMqx7=)u?StiNwnG>o9Wx1M%GbiR~(y^)XozI-vN?YhS<;eebd{zP$HB%wO)kvak^ z_Rrw!8=*1Wu$0Y9zK^?C0&K+rU@e7PqsoFwjZxw&5Z=y?45zdZ8NlW)J=^P%nB!8O z&-X6Uwpa*~#c@@wvxbYO^KiIqMty^oqQKChurO=qfUCSLugIn@Y3`CPegH5Rmd^`1 zzRE{Gao_X0PAJ>2+@wJ0%-FsII)XO-ehUQSm8336YJ@dSI=$esy>&g#%G+q < z3eM(l3en=1yZ%qzn2x>ChIln@-5>k*rc095r$HL60ZsGzy*iH$Mk H@l>i*#MKCAFLx^l&?Xj%A$Wu(ejNC)f1qyS_J_!MkL!=cq%e&y{T}V% zR%Bj9UVN4yWiH%C{#soeb}X?*w(Gptm!K=~+d=I>7bJ;;LIStrj|IB5 z)wkc1mH%A0&+jLNbO1z&DbYK>LGalpCT(HZxpn>bmlgad4^TO}v{62`3O5GvLa5ev z##N8eorGJfjUG?Db7{fK^Fryhavq@T*3EN@+5?aHg?4TY0CAll2HkA tz z0KBBs{dQ>RrvL}UdO#Dga!xUkS|l-jy-!`86zqthxcE8vg~pTc!>s#wAk0HUFXQ*u zXy- ~X) 7`Pcwc))4^?R2r{ 6P C#pzV(it4=jkc3fKkl2W*B zZOO;2AHSDjyPqWgfsvU-+X+{%6nKn9str`-*;-xxIC_aQ(6`7J>b&Ec6M?cV4-9dp znm4WdQ0c1_E``LI`LX*mbWfa9+TWr|0=^+!B*U9OqNHoM*l%uAX1l`yRn+NL%J>f3 zU|0wP@V0`g zOlxX&f4aY0^+;rmg|7u!NP-3v5jnfBtemPJOPZ2CHCN9Euj~*6;1LO|XHn2Do@^qB z%LRZ}kcIj2xQ5;24ywlkaPaB^|9%QbDqX(r3;<#&4{m*}>=^PZ!EqibD$*rx@4sx* z*{i1WR@8G1C`x0$*S9Ui>Mw7HaO}e8LDXu8YCuKZk(irqZL^!nG60alw~4GTuO}SB zy|#7*K0YKQUoFDQ=Br=1vA9>Bx?2mJzRD9``)(1&V5w8RcV0#g5cX_V#11CfYIH?P z`BS_?E+Q*WCYiK?cIXNWDDjMOv6lmeP!?kHcO!mLpsBuA_38iK-CGQqI+Ye2&doXM zsM0N o zf2YwIK{~iRoLKJByw3X!BKh 9b<#YD8jg6mk5f~P`1P3X&u=m~`|7g&bfq&j{21ThK zp8d(`zk9fVcrCG7g0B~j0)61-G+MM?=*_~b$etGx^KTsfP%8%(4-$ikO-2w4pWc@L5`P-;0 W1P=Ex%N}c zVFLBc8R%uv^j3=bI=W}PNcwLIR}*8cp4mMbhCU#bCc{%6)jmS`dt$@jDN}!F?;>H} z#JWXY9!TE|@6n9x@Ja>)lpBaYaxp?>NWM{1B|UIT_EA;1fS{7~TIA2FL%xM|cA0}_ zou?~eDr3h{pYv4|Ml|#~zeWR=!@6nmysFB)V<~%w)}g7~N_;l29?SxQT*cB;73cXE zxn!cu8B^Kt#(cUzWI`ZH0Yeb$imX5V%ZndCXiaRRa1p0B?nPGidqUltjM55Pjy)Qv zL+t&`xOnD?x$DPG`R67kz!AQP3I-aB`a8V4x6i0-ReIUyM3c)ReE^AGqE^Ch?Cm6! z@D0jgqn(G`ob4F+Fz>kU`~eV{AOz5W)Dr{$EQFEl*BdMQbr2u5B!{Yq6>aEDfie(h zD?>fAUX`(68*zN+g$s`M*72E3%IjC$BGf}{uw_qVO4SyZi#*CuC*yPuRR3*;Hc|09 zzy8#rlp|{r+w|T}rC-(olES~bEsAs3dk8O{7hZJ2yW?FeLz4nrBg7$E=eU4IUKZj@ zjz__RgF0^y-ELfUHhMImS0O*dv?n%OWJ7@B`!%{tEpNxms2(0Qw38CslU`%zC1>Ns zxur_&F%SB`&A>uw-cj%%+}8_L+&`lB;$nA?yRGK;Oo;n??(aQFI2?MR)cgdufcqm> zlDgOK^--^&i Vu^Uh z&+;Iqr}Nxfu~YhNjE4y7(`o>v@EG3S;T|I_b!N^ZEqvbyHxPf^V9GBP`}GNwi)M3& z6Q0^rxsmmm@ka-Y_MZ?hIM_NB%8Z8Myq3Rp(D}5{Gg9Y~wa8dWboOfClkv&{k^uzx zm)H(G_id?;i3se4$bY*;8S&N^i2Cqq2y1Ke;X?sV1OSg?$ua zy<;~_hyVg^WvXHzTs8a!u7XEhac|0lBP)#6L2{aFjPW)EMy}_#_T4wMhy>$-a*h98 z)5e$L+<@4cXkyQD6TG{^`8(mu!v_{%Fu37b^&% {FS#Y+ic~+Ne;b*(g6i)0r1Ky5 ziY|{@qKpz=Mb>$TE;5&!jY_JIK i%m;qPaRXZG;DYKlSn7K73YJza2+;XkqT)10P*47(#v?;KpX^k z6wR)OHwi5g`t{}BaWR)0LsH;0w%1(tYN*3B$3m1|%apM&)&oxLy-mjl`~;u-uMY*x z?QXs9yzGj7(X}>p{pkgvG6~3#UlS3C`0UAje?pU`@$4CzF&Xs87#v$Ivix9&<`k04 zd05Z9ba!#!8I$qkw!8j(UVDHk2OQ_%m{%NoOLV<> {)e5)Eeu=2_WJv$imj0)>rIrK8q6TiYZLl#mQOWAo*rzaih6bD>?as zo$1f3yXNL{WNe6-)oZ9;=Nzx)3s)BuXwD5N >RzTZ3p8GExI+%mc9TX6iLee0xq5~+#r%d5DR&ns=98gc4{;d^|$&G`*| zn$RlZ(1z$gg$9`3y9Lcv)~}{VzZNOjLk^a!i89> T^AT~hY!?+ zu%^+ty;+qCHb+E% qQ)OZ0dH#GC16sVYVLO}d{s5P49ct{YCPj)$z9H49t>PVnP)}WpMTFS`z zaqX9Y>H)Va$L6P_l|6)iu9V^V0RfrVk1ing&ZY{uJb?I`6(l+y?~{|r?El0Z(`b`A zZ7|?|5RhNNgIUYPpLHY Mf{v#X5fg+D|k*((p!2K8!@$(ZK0Vk`MpO55)hn!DJ}ND#a$f z0X^|Fci;rIdW9S7Mf2b!RsfLNH`wdW2(q!xd6jl>e<%jEH28o@l51i)!sO&t3-lTu zRjz;X$5{xq|IsztAzvI&lmh3N?l>sHE&JyrIC4OQ`cE)f3at$G_zE(f$)<;Q&2IZy zvK=c*N@;;&4GsFOukPRM``O1@aK$40s`(Qn`%gt6qv0&k+?*TF4uLSVV%^#t|j{FeS*o)z1SrFJbGYL>`7f zfQTy+f>&$W+#ed0C>i@n8b2aFEe0g)d54h=v9Cj>UGJ$TYPo>^Ddnngur0sv+T*Ge zF7$Z`&r1|`TI1F( 0g+IV_r{_r8Fvsv=m01Y|mLhhz zW!rtOD&m|+wSdT1R9;QC;%4+j1|R>7cQpKfa4QIT*}ufA(FMUrKKj|_lr|Dq-iR?( zxfYR<%6&wMw<(HR_fC{#!BZx|JLF-PMUvxs7CE3oJk}I@tP pT26&>ql0 zFcSJGqF;3(t)LpAFf3D+!fnd;qw>yYzG2f#=j2s^6z*?F_$?2p7VH`$M4}R2NYwlQ zr!=B;7LJFXe%hvo)#Wo6D%hBf=;2KIxVEdyVrr&1?>RYVAOcom%k$aRI0FccD~=)+ z13^cCfpl-R$P2+BG5~;Z=6mg_&^2TGp{fm2<}|V92i)&TBrz_UKKNpp?G;6)-+M71 zexPpu_YKh$E~&BqM2QvqH<2h?hr{r?dH5%p327d6Xq=JM fdWBp2u zp)W+a0O0Ib5PHfjkBIf%!Ayxhi~Onm#$|-g%X#23O5kZxhmrTz@gZc!r^n~2wZKF=N@i%XS6pZWZw#ShaDF!yOS#Q z(TZnr()ta!2i*5$4|nA=07tfv-1%<#%F}hqM+J3|vfk&tec}Vhp8%Vjuo4L!E?Vj* z_76hff5-VpsO|hv;5ZsDHNgBzYLexAkC1rVyeaR;+Br`k0Te4Zo8*d%s`JM3=sW5e zwA+kE0+h3};PHRrEb8vQ*XPdO_9Oa#B%8iQEUf!w-HF|dPohYAunGC8I99ADOuJhY ziRiqK>Y(SE LPC6e}`uy?9k%G~D&loB%?fXH|(W#E&_Y|6LG#!D$|nLU&@Cq=1p60k%E* z!ISuYrq63q=-Gq^DAR^tIVCsCs74! 5Gk_M6Erxx)ZHF63rUNP0aH6?K z0b+i88}KZud9nt*uyz%u+wlwJg-(Wbg(S-)zbo?oTh+0ViAOf)nrqYZLzx{db*jWP z5GMdYx(jl(VEL2cp_!9oT;6g4GtDa_9eV97TUa3RPta)fu$BNt*4KGPfkuV#*&eQ$ zxdH~d%{e1?f_@tEYj10mg6k27Gddn1x~=aA)uNSNcm4_Y%Er#EELh`u)`SP?*F<28 z?>BXRULXQ;Ja<$~Jek{$W5)n6cNio*;0B6mAku)FjTVPLf}3P~Ge^b0XSXYf3+VoI z3Uw5R*;RqG=df46<#(gdWBU|P-B!&fb3U+NWIrpRiyNy%V@!{(slFo`pM=zQM8* z>6gO1=De%VXOxp lOsD6{XFpB?k*AY=7*u7Oi>JTetHYz632 z;m!IIzTQZ88zPtnb~kg~p9sW7e4StS_ctyRMKGqD*j`_r^v) (#}7qpDS>Gn?S58&$DT zjCF!PgOuVQ_bAM7427dLD 8Pgq3wC0$B^7pMs0Ja(ehTEIum zm%u$JwlqE`g{#8(muKue&Ogs8hRQg!OsZj1nAe69y+ehJFZVG-*~X771SS6z!|?>` ze8P?Qbf3xtHmLVw!<5PTh5ubn-pFcKr&n>r{i&&@O?&%}Q?nl*W0~09h)c-j^Q#Qf zNkHAe0B9hX;ZMYRrs^4o`S}~0_dSbj+%mZ7{bN|ao5iZdPqSBScmaW?5tNJ07a#8h z7&h8prU2wQ@Zns-54-64Up&1_0?^YGN`e>8)v@q&YoWKwJw_IqWMw2EMc*tzvz19f z<*9` O5O`pH|{H{2yG;mUH@7uKRuWKziraBdx8yT{2 zeMoiKt6?eQUAIkux0knl*)hzPbb8xY8mmL35-Eq*UO_FAU>mIFS5-nL&0HQ>kF(yC znHl Wws=bRqyw8>tWDSgJe&j9nfk8qme{eSUf*%CBd-sxU0G|L;j(JX>34 z#%3 uPy3{wFYBLgJ^3|PX8=#P`o?mFf{{vGJkziVmtgOm z(Oa@w;Q?atnHTG^RHjvir&Y};yAsoI!9CE&wnLiZoyxM`BA$Kuf4uMNv#7Tpwo|zR zICE6=ZbQ VUbnfh}deCRPR^tUyu<$X{>E-F2Qrq-K}A?XRPHZC(iLk!B_W^Hu3xavhj!}+qm~ympG9U- zf{tH#(YcS<;Hl>!3`psz4hU1T`-kLWn~oPIUh;l0hc#qZz~yP=0G!`Z*lp(L@B}O7 zESg >Ii#EJw2iJuA8iL`JZzjHKTk!(d% zSRniDEz >agm7 T{Cy*P|xSIAIUIuPair`y;(Y zwOg(xtT;VPK0`G0&=3J@W)zer9)gT?{OOf*!BG3*;~$%KJ8@EmE58zcltMOU>>fp% zG+gZyE%pY*N@V}rtcxyd#vt{z*DAW<`O&L8g7lqVzm&@I;4`V*b>sU{jE8pRcux>Q z*k_T9thJtC1=UskrokxGB12S|dNKBDOrqi4C!WrQ1pJTjAB{$AyRIlnEmv^vZzl_v zsc=yPxIDTdD~sVj9S&4nYZN(filT~fidnuEWsvSuV>Cz3Hog!?UmN9%J%v`-x$Zk> zJcZO8mP#uPXC=J!b9G^EpRUWOd-?`r1WtR&yIL-(JPR#6B}?puXvOJF<^H$V!aIZ8 zP18v;Cu7v`_Bie1rKE-3$S~7Y)G|@!{HSTw$t3y~;mD!;@$zNXx*&X4u0Oi61C-TD z`$68U_D@uHI~7Fo_&$5IKW2Ojg|viH{%UrmV;*A8Y)qMwtrA0@gss~iI%aP~%bv@G zZF|{)1|VfuR|$9cnBSenZF_jS*1x@LkBY(A0SEliP_-}PE7C6uT=Z-OD;Pt0ty?Pv zj4<+R1CgA#uw_N(l%STiZ{#*Aw)|MO2kU 7m?V_HwR zk-|WbKb(>URTS)VYC_z?;&E?J9y~nl*50