DIRECTORY Buttons USING [Button, ButtonProc, Create, SetDisplayStyle], Commander USING [CommandProc, Register], Containers USING [ChildXBound, ChildYBound, Create], Cursors USING [CursorArray], FileNames USING [CurrentWorkingDirectory], Graphics USING [Context, Mark, Restore, Save, SetCP, SetPaintMode], GraphicsOps USING [BitmapRef, BitmapRep, DrawBitmap], IO USING [Close, Flush, PutF, time], Labels USING [Create, Label], Menus USING [AppendMenuEntry, ChangeNumberOfLines, CreateMenu, CreateEntry, GetNumberOfLines, Menu, MenuLine, MenuProc], MessageWindow USING [Append, Blink], Rope USING [ROPE], Rules USING [Create, Rule], spGlobals USING[ConRec, DumpIt, Handle, FuncTablePtr, Level2Model, ModelTablePtr, NodeRec, RefConRec, RefNodeRec, RefR, RefUnReal, ResistorBody, ShowDetails, SimulateIt, spFunctions, spModels, Stages, StopIt, ThymeToolRec, ToggleShowDetails, UnReal], TiogaOps USING [FindDef, FindText, FindWord, SearchDir], TypeScript USING [Create, TS], VFonts USING[CharWidth, StringWidth], ViewerBLT USING[ChangeNumberOfLines], ViewerClasses USING [PaintProc, Viewer, ViewerClass, ViewerClassRec], ViewerEvents USING [EventProc, RegisterEventProc], ViewerIO USING [CreateViewerStreams], ViewerOps USING [AddProp, CreateViewer, FetchProp, PaintViewer, RegisterViewerClass, RestoreViewer, SaveViewer, --SetMenu, --SetOpenHeight], ViewerTools USING [GetContents, MakeNewTextViewer, SetSelection]; ThymeViewers: CEDAR MONITOR IMPORTS Buttons, Commander, Containers, FileNames, Graphics, GraphicsOps, IO, Labels, Menus, MessageWindow, Rules, spGlobals, TiogaOps, TypeScript, ViewerEvents, ViewerIO, ViewerOps, VFonts, ViewerBLT, ViewerTools EXPORTS spGlobals = { entryHeight: CARDINAL = 12; entryVSpace: CARDINAL = 6; entryHSpace: CARDINAL = 10; msgViewerH: CARDINAL = 100; MakeThyme: Commander.CommandProc = { MakeThymeViewers[FileNames.CurrentWorkingDirectory[]]; }; -- MakeThyme MakeThymeViewers: PROC[wDir: Rope.ROPE _ NIL] = { handle: spGlobals.Handle _ NEW[spGlobals.ThymeToolRec _ []]; thymeMenus: Menus.Menu _ MakeThymeMenus[handle]; handle.outer _ Containers.Create[ info: [ name: version, data: handle, iconic: TRUE, menu: thymeMenus, column: left, scrollable: FALSE], paint: FALSE]; Menus.ChangeNumberOfLines[thymeMenus, 1]; MakeMainViewer[handle, wDir]; MakeMsgViewer[handle]; ViewerOps.SetOpenHeight[handle.outer, handle.height + msgViewerH]; ViewerOps.PaintViewer[handle.outer, all]; }; -- MakeThymeViewers MakeThymeMenus: PROC[handle: spGlobals.Handle] RETURNS[menu: Menus.Menu] = { requestConfirmMsg: Rope.ROPE = "Please confirm by clicking at it again."; menu _ Menus.CreateMenu[]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Stop", proc: Stop, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Dump", proc: Dump, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Run", proc: Run, clientData: handle] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "New", proc: New, clientData: handle] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "TypeScriptMenus", proc: TypeScriptMenus, clientData: handle] ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Save", proc: Save, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[ name: "Reset", proc: Reset, clientData: handle, guarded: TRUE, documentation: requestConfirmMsg], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Find", proc: Find, clientData: handle], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Word", proc: Word, clientData: handle], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "Def", proc: Def, clientData: handle], line: 1 ]; Menus.AppendMenuEntry[ menu: menu, entry: Menus.CreateEntry[name: "FindError", proc: FindError, clientData: handle], line: 1 ]; }; -- MakeThymeMenus Stop: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; spGlobals.StopIt[handle]; }; -- Stop Run: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; spGlobals.SimulateIt[handle]; }; -- Run Dump: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; spGlobals.DumpIt[handle]; }; -- Dump New: Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; []_ MakeThymeViewers[ViewerTools.GetContents[handle.wDir]]; }; TypeScriptMenus: ENTRY Menus.MenuProc = { viewer: ViewerClasses.Viewer _ NARROW[parent]; menu: Menus.Menu _ viewer.menu; numLines: Menus.MenuLine _ Menus.GetNumberOfLines[menu]; SELECT numLines FROM 1 => { numLines _ numLines + 1; }; 2 => numLines _ numLines - 1; ENDCASE => ERROR; ViewerBLT.ChangeNumberOfLines[viewer, numLines]; }; -- TypeScriptMenus Save: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.simulation # NIL THEN MessageWindow.Append["Thyme.log could NOT be saved when a circuit is being simulated.", TRUE] ELSE IF handle.msgStream # NIL THEN { handle.msgStream.PutF["\nSaved: %g\n", IO.time[]]; handle.msgStream.Flush[]; ViewerOps.SaveViewer[handle.message]; }; }; }; -- Save Reset: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.simulation # NIL THEN MessageWindow.Append["Thyme.log could NOT be reset when a circuit is being simulated.", TRUE] ELSE IF handle.msgStream # NIL THEN { ViewerOps.RestoreViewer[handle.message]; handle.msgStream.PutF["File: Thyme.log\nCreated: %g\n", IO.time[]]; }; }; }; -- Reset Find: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindText[ viewer: handle.message, rope: NIL, -- automatically uses contents of primary selection whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- Find Word: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindWord[ viewer: handle.message, rope: NIL, -- automatically uses contents of primary selection whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- Word Def: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindDef[ viewer: handle.message, rope: NIL, -- automatically uses contents of primary selection whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- Def FindError: ENTRY Menus.MenuProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { IF handle.msgStream # NIL AND handle.message # NIL THEN { dir: TiogaOps.SearchDir = SELECT mouseButton FROM red => forwards, yellow => anywhere, ENDCASE => backwards; case: BOOL = NOT shift; found: BOOL _ TiogaOps.FindText[ viewer: handle.message, rope: "g Error ", whichDir: dir, which: primary, case: case]; IF NOT found THEN BlinkMsg["Text not found."]; }; }; }; -- FindError BlinkMsg: PROC[msg: Rope.ROPE] = { MessageWindow.Blink[]; MessageWindow.Append[msg, TRUE]; }; -- BlinkMsg initialOutputName: Rope.ROPE = ""; MakeMainViewer: PROC [handle: spGlobals.Handle, workingDir: Rope.ROPE _ NIL] = { progressLabel, timeLabel, stepLabel: Labels.Label; inputButton: Buttons.Button; initialInputName: Rope.ROPE = ""; handle.height _ handle.height + entryVSpace; inputButton _ Buttons.Create[ info: [ name: "Working Directory:", parent: handle.outer, wy: handle.height + 2, wh: entryHeight, -- default the width so that it will be computed for us border: FALSE ], clientData: handle, proc: DirPrompt, paint: FALSE]; handle.wDir _ ViewerTools.MakeNewTextViewer[ info: [ parent: handle.outer, wx: inputButton.wx + inputButton.ww + entryHSpace, wy: handle.height, ww: 80*VFonts.CharWidth['M], wh: entryHeight + 2, data: workingDir, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; inputButton _ Buttons.Create[ info: [ name: "Input File:", parent: handle.outer, wy: handle.height + 2, wh: entryHeight, border: FALSE ], clientData: handle, proc: InputPrompt, paint: FALSE]; handle.input _ ViewerTools.MakeNewTextViewer[ info: [ parent: handle.outer, wx: inputButton.wx + inputButton.ww + entryHSpace, wy: handle.height, ww: 80*VFonts.CharWidth['M], wh: entryHeight + 2, data: initialInputName, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; [] _ Labels.Create[ info: [ name: "Output File:", parent: handle.outer, wy: handle.height, border: FALSE ], paint: FALSE]; handle.output _ Labels.Create[ info: [ name: initialOutputName, parent: handle.outer, wx: VFonts.StringWidth["Output File:"] + entryHSpace, wy: handle.height + 2, ww: 80*VFonts.CharWidth['W], wh: entryHeight, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; progressLabel _ Labels.Create[ info: [name: "Progress:", parent: handle.outer, wy: handle.height, border: FALSE ], paint: FALSE]; handle.progress _ CreateCursor[ parent: handle.outer, x: progressLabel.wx + progressLabel.ww + entryHSpace, y: handle.height]; handle.showDetailsButton _ Buttons.Create[ info: [ name: "details:", parent: handle.outer, wx: handle.progress.wx + handle.progress.ww + entryHSpace + entryHSpace, wy: handle.height, wh: entryHeight + 3, border: TRUE ], clientData: handle, proc: ShowDetailsProc, paint: FALSE]; Buttons.SetDisplayStyle[handle.showDetailsButton, IF spGlobals.ShowDetails[handle] THEN $WhiteOnBlack ELSE $BlackOnWhite]; timeLabel _ Labels.Create[ info: [ name: "time:", parent: handle.outer, wx: handle.showDetailsButton.wx + handle.showDetailsButton.ww + entryHSpace, wy: handle.height + 2, wh: entryHeight, border: FALSE ], paint: FALSE]; handle.time _ Labels.Create[ info: [ parent: handle.outer, wx: timeLabel.wx + timeLabel.ww + entryHSpace, wy: handle.height + 2, ww: 10*VFonts.StringWidth["M"], wh: entryHeight, border: FALSE], paint: FALSE]; stepLabel _ Labels.Create[ info: [ name: "step:", parent: handle.outer, wx: handle.time.wx + handle.time.ww + entryHSpace, wy: handle.height + 2, wh: entryHeight, border: FALSE ], paint: FALSE]; handle.step _ Labels.Create[ info: [ parent: handle.outer, wx: stepLabel.wx + stepLabel.ww + entryHSpace, wy: handle.height + 2, ww: 15*VFonts.StringWidth["M"], wh: entryHeight, border: FALSE], paint: FALSE]; handle.height _ handle.height + entryHeight + entryVSpace; }; -- MakeMainViewer DirPrompt: Buttons.ButtonProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN ViewerTools.SetSelection[handle.wDir]; }; -- InputPrompt InputPrompt: Buttons.ButtonProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN ViewerTools.SetSelection[handle.input]; }; -- InputPrompt ShowDetailsProc: Buttons.ButtonProc = { handle: spGlobals.Handle _ NARROW[clientData]; IF handle # NIL THEN { spGlobals.ToggleShowDetails[handle]; Buttons.SetDisplayStyle[handle.showDetailsButton, IF spGlobals.ShowDetails[handle] THEN $WhiteOnBlack ELSE $BlackOnWhite]; }; }; -- InputPrompt MakeMsgViewer: PROC [handle: spGlobals.Handle] = { rule: Rules.Rule _ Rules.Create[ info: [ parent: handle.outer, wy: handle.height, ww: handle.outer.cw, wh: 1], paint: FALSE]; Containers.ChildXBound[handle.outer, rule]; handle.height_ handle.height + 2; handle.message_ TypeScript.Create[ info: [ parent: handle.outer, wy: handle.height, ww: handle.outer.cw, wh: 800, border: FALSE, file: "Thyme.log"], paint: FALSE ]; IF ViewerOps.FetchProp[handle.message, $ThymeToolData] = NIL THEN ViewerOps.AddProp[handle.message, $ThymeToolData, handle]; [in: , out: handle.msgStream] _ ViewerIO.CreateViewerStreams[ name: "Thyme.log", viewer: handle.message, backingFile: "Thyme.log"]; IO.PutF[handle.msgStream, "File: Thyme.log\nCreated: %g\n", IO.time[]]; Containers.ChildXBound[handle.outer, handle.message]; Containers.ChildYBound[handle.outer, handle.message]; }; -- MakeMsgViewer MyDestroy: ViewerEvents.EventProc = { h: spGlobals.Handle _ NARROW[ViewerOps.FetchProp[viewer, $ThymeToolData]]; IF h=NIL THEN RETURN; IF event=destroy AND before THEN h.msgStream.Close[]; }; -- MyDestroy CursorBits: TYPE= REF Cursors.CursorArray; CursorArray: TYPE= Cursors.CursorArray; CursorData: TYPE= RECORD[ bits: REF CursorArray _ NIL, bitMap: GraphicsOps.BitmapRef _ NIL, invert: BOOL _ FALSE]; idleCursor: CursorBits= NEW[CursorArray _ ALL[0]]; inputCursor: CursorBits= NEW[CursorArray _ [177740B, 102040B, 2400B, 2400B, 2751B, 2451B, 2451B, 2447B, 2001B, 2007B, 2000B, 2242B, 2525B, 2527B, 2524B, 7523B] ]; bombCursor: CursorBits= NEW[CursorArray _ [ 30B, 140B, 200B, 700B, 600B, 700B, 3060B, 4010B, 4010B, 10004B, 10004B, 10004B, 4010B, 4010B, 3060B, 700B] ]; topoCursor: CursorBits= NEW[CursorArray _ [ 0B, 400B, 0B, 20410B, 10020B, 4440B, 2100B, 0B, 124052B, 0B, 2100B, 4440B, 10020B, 20410B, 0B, 400B] ]; runCursor: ARRAY [0..4) OF CursorBits= [ NEW[CursorArray _ [ 3700B, 14060B, 20410B, 41604B, 40404B, 100402B, 100402B, 100402B, 100002B, 100002B, 40004B, 40004B, 20010B, 14060B, 3700B, 0B] ], NEW[CursorArray _ [ 3700B, 14060B, 20010B, 40004B, 40004B, 100002B, 100022B, 100772B, 100022B, 100002B, 40004B, 40004B, 20010B, 14060B, 3700B, 0B] ], NEW[CursorArray _ [ 3700B, 14060B, 20010B, 40004B, 40004B, 100002B, 100002B, 100402B, 100402B, 100402B, 40404B, 41604B, 20410B, 14060B, 3700B, 0B] ], NEW[CursorArray _ [ 3700B, 14060B, 20010B, 40004B, 40004B, 100002B, 110002B, 137402B, 110002B, 100002B, 40004B, 40004B, 20010B, 14060B, 3700B, 0B] ] ]; CreateCursor: PROC [parent: ViewerClasses.Viewer, x, y: INTEGER _ 0] RETURNS [cursor: ViewerClasses.Viewer] = TRUSTED { cursorData: REF CursorData _ NEW[CursorData]; cursorData.bits _ NEW[CursorArray]; cursorData.bitMap _ NEW[GraphicsOps.BitmapRep _ [base: cursorData.bits, raster: 1, width: 16, height: 16]]; cursor _ ViewerOps.CreateViewer[ flavor: $ThymeCursor, info: [ parent: parent, wx: x, wy: y, ww: 16, wh: 16, data: cursorData, border: FALSE], paint: FALSE]; }; -- CreateCursor SetCursor: PUBLIC PROC [handle: spGlobals.Handle, invert: BOOL _ FALSE] = { ENABLE UNWIND => {}; d: REF CursorData; IF handle = NIL THEN RETURN; IF handle.progress = NIL THEN RETURN; d_ NARROW[handle.progress.data]; IF d = NIL THEN RETURN; SELECT handle.stage FROM idle => d.bits^ _ idleCursor^; input => d.bits^ _ inputCursor^; bomb => d.bits^ _ bombCursor^; topo => d.bits^ _ topoCursor^; run => d.bits^ _ IF handle.vars = NIL THEN runCursor[0]^ ELSE runCursor[handle.vars.runState]^; ENDCASE => BlinkMsg["* Weird situation at SetCursor detected. Please inform Thyme implementor."]; d.invert _ invert; PaintProcess[handle.progress]; }; -- SetCursor PaintProcess: -- ENTRY -- PROC[viewer: ViewerClasses.Viewer] = { ENABLE UNWIND=> {}; d: REF CursorData _ NARROW[viewer.data]; TRUSTED{ViewerOps.PaintViewer[viewer, client, FALSE, $Update]}; }; -- PaintProcess ThymeCursorPaint: ViewerClasses.PaintProc = { ctx: Graphics.Context _ context; cursorData: REF CursorData _ NARROW[self.data]; mark: Graphics.Mark _ Graphics.Save[ctx]; Graphics.SetCP[ctx, 0, 16]; IF cursorData.invert THEN [] _ Graphics.SetPaintMode[ctx, invert] ELSE [] _ Graphics.SetPaintMode[ctx, opaque]; GraphicsOps.DrawBitmap[ctx, cursorData.bitMap, 16, 16]; Graphics.Restore[ctx, mark]; }; -- ThymeCursorPaint version: PUBLIC Rope.ROPE_ "Thyme - Cedar5.2 - Aug. 1984"; refNodeRec: PUBLIC spGlobals.RefNodeRec= NEW[spGlobals.NodeRec]; refConRec: PUBLIC spGlobals.RefConRec= NEW[spGlobals.ConRec]; refR: PUBLIC spGlobals.RefR= NEW[spGlobals.ResistorBody]; refUnReal: PUBLIC spGlobals.RefUnReal= NEW[spGlobals.UnReal]; modelTable: PUBLIC spGlobals.ModelTablePtr_ NIL; functionTable: PUBLIC spGlobals.FuncTablePtr_ NIL; thymeCursor: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ paint: ThymeCursorPaint, tipTable: NIL] ]; ViewerOps.RegisterViewerClass[$ThymeCursor, thymeCursor]; Commander.Register[ key: "Thyme", proc: MakeThyme, doc: "Start an instance of the circuit simulator Thyme." ]; [] _ ViewerEvents.RegisterEventProc[proc: MyDestroy, event: destroy]; START spGlobals.spModels; START spGlobals.Level2Model; START spGlobals.spFunctions; }. ะThymeViewers.mesa -- Some parts stolen from PseudoCursorsImpl.mesa Last Edited by: SChen, September 17, 1984 6:21:43 pm PDT GetLine, SetLine, MenuEntry Process USING [Detach, InitializeCondition, MsecToTicks, Ticks], destroyEvent: ViewerEvents.EventRegistration _ NIL; menus typescript menus Menus.SetLine[menu, 1, tsMenuEntry]; main sub viewer openInput: Buttons.Button; working directory scrollable: FALSE, input file scrollable: FALSE, output file progress cursor force the selection into the user input field message viewer divider the msg sub window ViewerEvents.UnRegisterEventProc[proc: destroyEvent, event: destroy]; cursors newData: BOOL _ FALSE, paint: PROCESS _ NIL, timeout: CONDITION, cursorData.newData _ TRUE; Process.InitializeCondition[@cursorData.timeout, waitTime]; IF d.paint=NIL THEN TRUSTED{ Process.Detach[d.paint _ FORK PaintProcess[handle.progress]]}; waitTime: Process.Ticks _ Process.MsecToTicks[100]; d.newData _ TRUE; WHILE d.newData DO d.newData _ FALSE; TRUSTED{ViewerOps.PaintViewer[viewer, client, FALSE, $Update]}; WAIT d.timeout; ENDLOOP; d.paint _ NIL; Main Program starts here global variables -- progress cursor Thyme menus thymeMenus: Menus.Menu _ MakeThymeMenus[]; tsMenuEntry: Menus.MenuEntry _ Menus.GetLine[thymeMenus, 1]; Menus.SetLine[thymeMenus, 1, NIL]; Menus.ChangeNumberOfLines[thymeMenus, 1]; registrations: destroyEvent -- build the library functions and models CHANGE LOG Chen, June 12, 1984 11:21:28 am PDT, created. ส ˜JšœB™BJ™8J™šฯk ˜ Jšœœ/˜Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž˜ —J˜šœœ˜Jšœœ ˜.šœ œœ˜š œœœœœ˜9šœœ ˜1Jšœ%œ˜:—Jšœœœ˜šœœ˜ Jšœ˜Jšœœž3˜>Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž˜ J˜—šœœ˜Jšœœ ˜.šœ œœ˜š œœœœœ˜9šœœ ˜1Jšœ%œ˜:—Jšœœœ˜šœœ˜Jšœ˜Jšœœž3˜>Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž˜ —J˜šœ œ˜#Jšœœ ˜.šœ œœ˜š œœœœœ˜9šœœ ˜1Jšœ%œ˜:—Jšœœœ˜šœœ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ —Jšœœœ˜.J˜—J˜—Jšœž ˜—J˜šŸœœ œ˜"J˜Jšœœ˜ Jšœž ˜J˜—J™Jšœœ6˜RunitšŸœœ- œ˜PL˜2Jšœ˜Jšœ™Jšœœ%˜@J˜Jšœ,˜,J˜J™šœ˜šœ˜Jšœ˜Jšœ˜Jšœ˜Jšœž7˜HJšœœ˜—J˜Jšœ˜Jšœœ˜J˜—šœ,˜,šœ˜Jšœ˜Jšœ2˜2Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ™Jšœœ˜—Jšœœ˜—J˜Jšœ:˜:J™J™ šœ˜šœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœœ˜—J˜Jšœ˜Jšœœ˜J˜—šœ.˜.šœ˜Jšœ˜Jšœ2˜2Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ™Jšœœ˜—Jšœœ˜—J˜Jšœ:˜:J™J™ šœ˜šœ˜Jšœ˜Jšœ˜Jšœ˜Jšœœ˜—Jšœœ˜—J˜šœ˜šœ˜Jšœ˜Jšœ˜Jšœ5˜5Jšœ˜Jšœ˜Jšœ˜Jšœœ˜—Jšœœ˜—J˜Jšœ:˜:J™J™šœ˜šœ/˜/Jšœœ˜#—Jšœœ˜—J˜šœ˜J˜Jšœ5˜5Jšœ˜—J˜˜*šœ˜Jšœ˜Jšœ˜JšœH˜HJšœ˜Jšœ˜Jšœœ˜—J˜Jšœ˜Jšœœ˜—J˜šœ1˜1Jšœœœ˜H—J˜šœ˜šœ˜Jšœ˜Jšœ˜JšœL˜LJšœ˜Jšœ˜Jšœœ˜—Jšœœ˜—J˜šœ˜šœ˜Jšœ˜Jšœ.˜.Jšœ˜Jšœ˜Jšœ˜Jšœœ˜—Jšœœ˜—J˜šœ˜šœ˜Jšœ˜Jšœ˜Jšœ2˜2Jšœ˜Jšœ˜Jšœœ˜—Jšœœ˜—J˜šœ˜šœ˜Jšœ˜Jšœ.˜.Jšœ˜Jšœ˜Jšœ˜Jšœœ˜—Jšœœ˜—J˜Jšœ:˜:J˜Jšœž˜—J˜šœ!˜!Jšœœ ˜.Jšœ œœ'˜;Jšœž˜J˜—šœ#˜#Jšœœ ˜.Jšœ œœ(˜™>—Jšœ˜Jšœž ˜—J˜Jšœ3™3J˜šŸ œž œœ#˜AJšœœ˜Jšœœœ˜(Jšœ™šœ™Jšœ™Jšœ?™?Jšœ™Jšœ™—Jšœ™Jšœ'œ ˜?Jšœž˜—J˜šœ-˜-Jšœ ˜ Jšœ œœ ˜/Jšœ)˜)Jšœ˜Jšœœ(˜AJšœ)˜-Jšœ7˜7Jšœ˜Jšœž˜J˜—J™J™™J˜—Jšœ œœ!˜:Jšœ œœ˜@Jšœ œœ˜=Jšœœœ˜9Jšœ œœ˜>Jšœ œœ˜0Jšœœœ˜2J™J™šœ(˜(šœ!˜$Jšœ˜Jšœ œ˜Jšœ˜——J™Jšœ ™ Jšœ*™*Jšœ<™