DIRECTORY AMBridge, AMEvents, AMEventsBackdoor, AMEventsBackdoorExtra, AMModel, AMModelBridge, AMTypes, AMViewerOps, Basics, Commander, ComputeServerClient, ComputeServer, ComputeServerControl, ComputeServerDebugger, ComputeServerDebuggerRpcControl, ComputeServerInternal, EvalQuote, FS, Interpreter, InterpreterOps, InterpreterToolPrivate, IO, MBQueue, PrincOps, PrincOpsUtils, Process, PupDefs, PupErrors, PupStream, PupTypes, SymTab, Rope, RPC, RuntimeError, WorldVM; ComputeServerDebuggerImpl: CEDAR PROGRAM IMPORTS AMBridge, AMEvents, AMEventsBackdoor, AMEventsBackdoorExtra, AMModel, AMModelBridge, AMTypes, AMViewerOps, ComputeServerDebuggerRpcControl, ComputeServerInternal, EvalQuote, FS, Interpreter, InterpreterOps, IO, MBQueue, PrincOpsUtils, Process, PupDefs, PupErrors, PupStream, Rope, RPC, RuntimeError, SymTab, WorldVM = BEGIN STREAM: TYPE = IO.STREAM; ROPE: TYPE = Rope.ROPE; ActiveServicesItem: TYPE = ComputeServerInternal.ActiveServicesItem; ActiveServicesPointer: TYPE = ComputeServerInternal.ActiveServicesPointer; PupListener: TYPE = ComputeServerInternal.PupListener; BufStreamData: TYPE = ComputeServerInternal.BufStreamData; BufStreamDataObject: TYPE = ComputeServerInternal.BufStreamDataObject; guestLocalEvent: PROC[event: AMEvents.Event, f: PrincOps.FrameHandle, stack: POINTER TO PrincOps.StateVector, return: BOOL _ FALSE] RETURNS[debugLocally: BOOL _ FALSE] = TRUSTED BEGIN serverPupAddress: PupDefs.PupAddress; outcome: AMEvents.Outcome; interface: ComputeServerDebuggerRpcControl.InterfaceRecord _ NIL; serviceItemPointer: ActiveServicesPointer; IF ~PrincOpsUtils.IsBound[LOOPHOLE[AMEventsBackdoorExtra.PSBIToTV]] THEN RETURN[TRUE]; -- skip if the interface isn't exported serviceItemPointer _ LOOPHOLE[ComputeServerInternal.GetGuestProcessData[LOOPHOLE[Process.GetCurrent[]]]]; IF serviceItemPointer = NIL THEN RETURN[TRUE]; interface _ ComputeServerDebuggerRpcControl.ImportNewInterface[ interfaceName: [ type: "ComputeServerDebugger.summoner", instance: serviceItemPointer.clientNetAddressRope, version: [1,1]] ! RPC.ImportFailed => { CONTINUE; }; ]; IF interface = NIL THEN RETURN[TRUE]; event.world _ AMEventsBackdoorExtra.LocalActor.world; event.session _ AMEventsBackdoorExtra.LocalActor.bootCount; event.process _ AMEventsBackdoorExtra.PSBIToTV[PrincOpsUtils.PsbHandleToIndex[PrincOpsUtils.ReadPSB[]], AMEventsBackdoorExtra.LocalActor.world]; event.frame _ AMBridge.TVForFrame[f, stack, return, event.type = break]; event.worry _ FALSE; IF AMEventsBackdoorExtra.Informing THEN RuntimeError.InformationalSignal[AMEvents.Debugging]; [outcome, serverPupAddress, debugLocally] _ remoteEventHandler[event, interface, serviceItemPointer]; --used to call InvokeEvent who called InterpreterToolImpl.EventHandler [] _ ComputeServerInternal.DeletePupAddress[serverPupAddress]; IF AMEventsBackdoorExtra.Informing THEN RuntimeError.InformationalSignal[AMEvents.Debugged]; IF ~debugLocally THEN { WITH o: outcome SELECT FROM proceed => NULL; quit => ERROR ABORTED -- I don't like it, but that's the convention for now --; retry, returnFrom => ERROR AMEventsBackdoorExtra.NotImplemented[]; ENDCASE => ERROR; }; END; remoteEventHandler: PROC[event: AMEvents.Event, interface: ComputeServerDebuggerRpcControl.InterfaceRecord, serviceItemPointer: ActiveServicesPointer] RETURNS[outcome: AMEvents.Outcome, serverPupAddress: PupDefs.PupAddress, debugLocally: BOOL _ FALSE] = TRUSTED { h: InterpreterToolPrivate.Handle; context: AMModel.Context = IF event = NIL THEN AMModel.RootContext[WorldVM.LocalWorld[]] ELSE AMModelBridge.ContextForFrame[event.frame]; remoteWorld: WorldVM.World _ NIL; oldPriority: Process.Priority _ Process.GetPriority[]; listener: PupListener; debugServicesItem: ActiveServicesItem _ NIL; byteStreamOK: BOOL; name: ROPE _ NIL; in, out: STREAM; inData, outData: BufStreamData ; copyProcess: PROCESS; procMainLoop: PROC [h: InterpreterToolPrivate.Handle] RETURNS [outcome: AMEvents.Outcome ]; serverPupAddress _ PupDefs.AnyLocalPupAddress[PupDefs.UniqueLocalPupSocketID[]]; Process.SetPriority[Process.priorityNormal]; IF context = NIL THEN ERROR; IF WorldVM.LocalWorld[] # AMModel.ContextWorld[context] THEN remoteWorld _ AMModel.ContextWorld[context]; h _ NEW[ InterpreterToolPrivate.InterpreterObject _ [remoteWorld: remoteWorld, context: context, event: event, menuHitQueue: MBQueue.Create[], symTab: SymTab.Create[], readEvalPrintProcess: LOOPHOLE[Process.GetCurrent[]]]]; -- LOOPHOLE should not be needed, but the compiler give a bogus type error name _ NewViewer[h]; listener _ ComputeServerInternal.CreatePupByteStreamListener[local: serverPupAddress.socket, proc: ComputeServerInternal.ListenerProcess, ticks: PupStream.SecondsToTocks[1], filter: ComputeServerInternal.DontReject]; debugServicesItem _ ComputeServerInternal.AddPupAddress[serverPupAddress, NIL, listener]; debugServicesItem.debugItem _ TRUE; debugServicesItem.h _ h; debugServicesItem.debuggerInterface _ interface; debugServicesItem.originalListenerPupAddress _ serviceItemPointer.listenerPupAddress; byteStreamOK _ interface.OpenDebugStream[listenerPupAddress: serviceItemPointer.listenerPupAddress, newListenerPupAddress: serverPupAddress, name: name, serverMachine: ComputeServerInternal.myHostName ! RPC.CallFailed => { byteStreamOK _ FALSE; }; ]; IF byteStreamOK THEN { WHILE debugServicesItem.remoteStream = NIL DO Process.Pause[5]; ENDLOOP; in _ IO.CreateStream[streamProcs: ComputeServerInternal.inStreamProcs, streamData: inData _ NEW[BufStreamDataObject _ [listenerItem: debugServicesItem]]]; out _ IO.CreateStream[streamProcs: ComputeServerInternal.outStreamProcs, streamData: outData _ NEW[BufStreamDataObject _ [listenerItem: debugServicesItem]]]; debugServicesItem.remoteStream.PutRope[Rope.Cat[name, "\n"]]; debugServicesItem.remoteStream.Flush[]; h.tsInStream _ in; h.tsOutStream _ out; TRUSTED { Process.Detach[copyProcess _ FORK DebugStreamCopy[debugServicesItem, in, out, inData, outData]]}; procMainLoop _ LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.MainLoop"].result]]; outcome _ procMainLoop[h]; } ELSE { outcome _ [quit[]]; }; debugServicesItem.callOver _ TRUE; [] _ ComputeServerInternal.DeletePupAddress[serverPupAddress]; Process.SetPriority[oldPriority]; }; DebugStreamCopy: PROC[debugServicesItem: ActiveServicesItem, in, out: STREAM, inData, outData: BufStreamData] = { lastLoop: BOOL _ FALSE; WHILE ~debugServicesItem.inEOF OR debugServicesItem.outEOF ~= true DO doneSomething: BOOL _ FALSE; IF debugServicesItem.outEOF ~= true AND ComputeServerInternal.inCharsAvail[out, FALSE] > 0 THEN { WHILE ComputeServerInternal.inCharsAvail[out, FALSE] > 0 AND debugServicesItem.outEOF = false DO debugServicesItem.remoteStream.PutChar[ComputeServerInternal.inBufGetChar[out ! IO.EndOfStream => {debugServicesItem.outEOF _ pending; CONTINUE;}]]; ENDLOOP; debugServicesItem.remoteStream.Flush[ ! PupErrors.StreamClosing => {debugServicesItem.outEOF _ true; CONTINUE;}; ]; IF debugServicesItem.outEOF = pending THEN { PupStream.SendMark[debugServicesItem.remoteStream, 27B ! PupErrors.StreamClosing => CONTINUE]; debugServicesItem.outEOF _ true; }; doneSomething _ TRUE; }; WHILE debugServicesItem.remoteStream.CharsAvail[] > 0 AND ~debugServicesItem.inEOF AND (inData.inPointer - (inData.outPointer + 1)) MOD ComputeServerInternal.BufStreamBufferSize # 0 DO doneSomething _ TRUE; ComputeServerInternal.outBufPutChar[in, debugServicesItem.remoteStream.GetChar[ ! IO.EndOfStream => { FOR i:INT IN [0..5) DO ComputeServerInternal.outBufPutChar[in, '\n]; ENDLOOP; TRUSTED {abort[debugServicesItem.h]; }; inData.EOF _ pending; debugServicesItem.inEOF _ TRUE; CONTINUE; } ]]; ENDLOOP; IF lastLoop THEN EXIT; IF debugServicesItem.callOver THEN { lastLoop _ TRUE; LOOP;}; IF ~doneSomething THEN Process.Pause[5]; ENDLOOP; PupStream.SendMark[debugServicesItem.remoteStream, 26B ! PupErrors.StreamClosing => CONTINUE]; debugServicesItem.remoteStream.Close[! IO.Error => CONTINUE;] ; }; NewViewer: PROC[h: InterpreterToolPrivate.Handle] RETURNS[name: ROPE _ NIL] = TRUSTED { LocalRegister: PROC [name: ROPE, ref: REF, help: ROPE] = TRUSTED { ENABLE AMTypes.Error => GO TO err; InterpreterOps.RegisterTV[ name: name, tv: AMBridge.TVForReferent[ref], help: help, symTab: h.symTab ]; EXITS err => { IO.PutF[h.tsOutStream, "** Failed to register %g\n", [rope[name]]]; }; }; IF h.event # NIL THEN { procEventToName: PROC [event: AMEvents.Event] RETURNS [name: ROPE ]; procEventToName _ LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.EventToName"].result]]; IF h.event.world # WorldVM.LocalWorld[] THEN name _ "WORLDSWAP "; name _ Rope.Cat[name, "Event: ", procEventToName[h.event]]; } ELSE name _ Rope.Cat["Interp: ", AMModel.ContextName[h.context]]; LocalRegister[ "&H", NEW[InterpreterToolPrivate.Handle _ h], "this interpretertool's handle"]; LocalRegister[ "&depth", NEW[INT _ 4], "printing depth for this interpretertool"]; LocalRegister[ "&width", NEW[INT _ 32], "printing width for this interpretertool"]; LocalRegister[ "&WalkStack", NEW[UNSAFE PROC[nFrames: INT _ 1, h: InterpreterToolPrivate.Handle _ NIL] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.WalkStack"].result]] ], "set a local frame context (eventhandler)"]; LocalRegister[ "&slf", NEW[UNSAFE PROC[nFrames: INT _ 1, h: InterpreterToolPrivate.Handle _ NIL] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.WalkStack"].result]] ], "set a local frame context (eventhandler)"]; LocalRegister[ "&ShowFrame", NEW[UNSAFE PROC[h: InterpreterToolPrivate.Handle _ NIL] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.ShowFrame"].result]] ], "show the current lf context (eventhandler)"]; LocalRegister[ "&Source", NEW[UNSAFE PROC[h: InterpreterToolPrivate.Handle _ NIL] _ Source], "show source loc of current lf context (eventhandler)"]; EvalQuote.Register["&sgf", LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.SetGlobalFrameHelper"].result]], h.symTab, h]; LocalRegister[ "&sgf", NEW[UNSAFE PROC[progName: ROPE, h: InterpreterToolPrivate.Handle _ NIL] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.SetGlobalFrameContext"].result]] ], "&sgf[rope]\tset context to be that for the given module"]; EvalQuote.Register["&gf", LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.GlobalFrameHelper"].result]], h.symTab, h]; LocalRegister[ "&gf", NEW[UNSAFE PROC[progName: ROPE, h: InterpreterToolPrivate.Handle _ NIL] RETURNS [AMTypes.TV] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.GlobalFrameContext"].result]] ], "&gf[rope]\tget the given module's context"]; EvalQuote.Register["&sir", LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.SetIRHelper"].result]], h.symTab, h]; LocalRegister[ "&sir", NEW[UNSAFE PROC[interfaceName: ROPE, h: InterpreterToolPrivate.Handle _ NIL] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.SetIRContext"].result]] ], "&sir[rope]\tset context to be that for the given IR"]; EvalQuote.Register["&type", LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.TypeHelper"].result]], h.symTab, h]; LocalRegister[ "&type", NEW[UNSAFE PROC[expr: ROPE, h: InterpreterToolPrivate.Handle _ NIL] RETURNS[AMTypes.Type] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.TypeGetter"].result]] ], "&type[expr]\tget the type of the given expr"]; EvalQuote.Register["&ir", LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.IRHelper"].result]], h.symTab, h]; LocalRegister[ "&ir", NEW[UNSAFE PROC[interfaceName: ROPE, h: InterpreterToolPrivate.Handle _ NIL] RETURNS[AMTypes.TV] _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate[ "InterpreterToolImpl.IRContext"].result]] ], "&ir[rope]\tget the given IR"]; LocalRegister[ "&ABORT", NEW[UNSAFE PROC[h: InterpreterToolPrivate.Handle _ NIL] _ abort], "abort button hit"];}; abort: UNSAFE PROC[h: InterpreterToolPrivate.Handle _ NIL] = TRUSTED { giveFinalCR: BOOL_ TRUE; procSetAbortRequested: PROC[h: InterpreterToolPrivate.Handle]; procSetAbortRequested _ LOOPHOLE[ AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.SetAbortRequested"].result]]; procSetAbortRequested[h]; Process.Abort[h.readEvalPrintProcess ! Process.InvalidProcess => {giveFinalCR _ FALSE; CONTINUE;}; ]; -- ERROR possible due to timing error, but the Process.Abort is only being used to wake up the interperter and the timeing error is that the interperter woke up, so it is ok. IF giveFinalCR THEN StuffIt[h, "\n"]; }; Source: PROC [h: InterpreterToolPrivate.Handle _ NIL] = { name: ROPE; index: INT; fName: ROPE _ NIL; report: AMViewerOps.ReportProc = -- [msg: ROPE, severity: Severity] TRUSTED {h.tsOutStream.PutRope[msg]}; TRUSTED { IF h = NIL THEN { procGetHandlePlease: PROC RETURNS [InterpreterToolPrivate.Handle]; procGetHandlePlease _ LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate["InterpreterToolImpl.GetHandlePlease"].result]]; h _ procGetHandlePlease[]; }; }; [name, index] _ AMViewerOps.SourceFromTV[h.context, report]; IF name # NIL THEN { fName _ FS.FileInfo[name: name, remoteCheck: FALSE ! FS.Error => CONTINUE;].attachedTo; }; IF fName # NIL THEN { interface: ComputeServerDebuggerRpcControl.InterfaceRecord _ NIL; debuggerItem: ActiveServicesItem _ ComputeServerInternal.findDebuggerItemFromInterpreterHandle[h].item; IF debuggerItem # NIL THEN debuggerItem.debuggerInterface.OpenSourceViewer[debuggerItem.originalListenerPupAddress, fName, index ! RPC.CallFailed => CONTINUE]; }; }; StuffIt: PROC [h: InterpreterToolPrivate.Handle, rope: ROPE] = { h.tsOutStream.PutRope[rope]; }; disableGuest: PROC [localFS: BOOL] = { process: PROCESS = LOOPHOLE[Process.GetCurrent[]]; IF localFS THEN ComputeServerInternal.MarkProcessNotGuest[process] ELSE ComputeServerInternal.RemoveMarkProcessNotGuest[process]; }; newProcs: REF AMEventsBackdoor.GuestProcsRec _ NEW[AMEventsBackdoor.GuestProcsRec _ [ IsGuestProcess: ComputeServerInternal.IsGuestProcess, disableGuest: disableGuest, guestLocalEvent: guestLocalEvent ]]; TRUSTED {AMEventsBackdoor.RegisterGuestProcs[newProcs];}; END. ComputeServerDebuggerImpl.mesa The Compute Server side of the Summoner. Last Edited by: Bob Hagmann, November 26, 1985 2:33:13 pm PST Copyright c 1984 by Xerox Corporation. All rights reserved. Variable Declarations Uncaught Signals modified from AMEventsImpl.LocalEvent procPSBIToTV: PROC [psbi: CARDINAL, world: WorldVM.World] RETURNS [p: AMTypes.TV]; procPSBIToTV_ LOOPHOLE[AMBridge.TVToProc[Interpreter.Evaluate["AMEventsImpl.PSBIToTV"].result]]; event.process _ procPSBIToTV[PrincOpsUtils.PsbHandleToIndex[PrincOpsUtils.ReadPSB[]], AMEventsBackdoorExtra.LocalActor.world]; InterpreterToolImpl.EventHandler basically calls InterpreterToolImpl.CreateTool if it can't find a suitable window to nest the call in. CreateTool is copied below, less the dormant Event window finding stuff. glue the streams together and wake up remote window streams connected: start up the interpreter out.Close[]; debugServicesItem.remoteStream.Close[! IO.Error => CONTINUE;] ; copy from the internal stream to the remote stream copy from the remote stream to the internal stream Initialization Bob Hagmann May 3, 1985 8:05:30 am PDT changes to: remoteEventHandler Bob Hagmann July 5, 1985 9:01:47 am PDT use Interpreter to find procedures inside of AMEventsImpl and InterpreterToolImpl Ê W– "Cedar" style˜head™Ibodyšœ(™(L™=Jšœ Ïmœ1™<code2šÏk ˜ Mšœ ˜ Mšœ ˜ M˜Mšœ˜M˜M˜M˜M˜ Mšœ˜M˜ Mšœ˜Mšœ˜M˜Mšœ˜Mšœ ˜ Mšœ˜Mšœ ˜ M˜M˜ M˜Mšœ˜Mšžœ˜M˜M˜ M˜M˜Mšœ˜M˜ M˜ M˜ Mšœ˜M˜Mšžœ˜Mšœ ˜ Mšœ˜——šœžœž˜(MšžœÐžœHžœ˜ÃM˜Mšœž˜—™Mšžœžœžœžœ˜Icodešžœžœžœ˜N˜N˜Icode1˜Ošœžœ,˜DOšœžœ/˜JOšœ žœ%˜6J˜Jšœžœ'˜:Jšœžœ-˜FJ˜—™N˜šÏbœžœ8žœžœžœžœžœžœžœžœž˜·Jšœ&™&Jšœ%˜%J˜Jšœ=žœ˜AJšœ*˜*Jš žœžœ"žœžœžœÏc'˜Jš œžœžœžœ žœ™RJšœžœ+žœ˜iJš žœžœžœžœžœ˜.šœ?˜?Mšœ{˜{šœžœ˜Mšžœ˜ Mšœ˜—Mšœ˜—Jš žœ žœžœžœžœ˜%Jšœ5˜5Jšœ;˜;˜Nšœ€˜€—JšœžœJ™`™Jšœn™n—J˜HJšœžœ˜Jšžœ!žœ6˜]Jšœg F˜­Jšœ>˜>Jšžœ!žœ5˜\šžœžœ˜šžœ žœž˜Jšœ žœ˜Jšœžœžœ 8œ˜OJšœžœ(˜BJšžœžœ˜—J˜—Jšžœ˜—J˜š ŸžœžœPžœžœžœ˜‰JšœÑ™ÑJšœ!˜!šœ˜Jšžœ žœžœ+žœ,˜n—Jšœžœ˜!Jšœ6˜6Jšœ˜Jšœ(žœ˜,Jšœžœ˜Jšœžœžœ˜Jšœ žœ˜Mšœ ˜ Mšœ žœ˜Mšœžœ$žœ˜[J˜JšœP˜PJšœ,˜,Jšžœ žœžœžœ˜šžœ5˜7Jšžœ-˜1—šœžœ˜šœ(˜(šœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜Jšœžœ G˜„———Jšœ˜˜J™3—JšœØ˜ØJšœJžœ ˜YJšœžœ˜#Jšœ˜Jšœ0˜0JšœU˜UšœËžœ˜ÞJšœžœ˜Jšœ˜—Jšœ˜šœ˜šžœ"žœž˜-M˜Mšžœ˜—JšœžœUžœ;˜šNšœžœWžœ;˜Jšœ=˜=Jšœ'˜'Jšœ˜Jšœ˜šžœ žœ@˜kJ™+—JšœžœQ˜hJšœ˜J˜—˜Jšœ˜J˜—Jšœ ™ Jšœ'žœ žœ™?Jšœžœ˜"Jšœ>˜>Jšœ!˜!Jšœ˜—J˜šÐbnœžœ1žœ%˜qMšœ žœžœ˜šžœžœ"ž˜Ešœžœžœ˜M™2—šžœ#žœ)žœžœ˜bšžœ)žœžœ"ž˜`MšœPžœ5žœ˜”Mšžœ˜—Mšœežœ˜sšžœ$žœ˜,JšœTžœ˜^Mšœ ˜ M˜—Mšœžœ˜Mšœ˜M™2—š žœ1žœžœ.žœ/ž˜¸Mšœžœ˜šœRžœ˜eMšžœžœžœžœ7˜MMšžœ ˜'Mšœžœ ˜Mšœžœ˜Mšžœ˜ Mšœ˜—Mšœ˜—Mšžœ˜Mšžœ žœžœ˜Mšžœžœžœžœ˜=Mšžœžœ˜(Mšžœ˜—JšœTžœ˜^Jšœ'žœ žœ˜@J˜—J˜š Ïn œžœ#žœžœžœžœ˜WJ˜š ¢ œžœžœžœžœÐksœ˜BJšžœžœžœ˜"šœ˜JšœI˜IJšœ˜—šžœ ˜JšžœA˜CJšœ˜—J˜—šžœ žœžœ˜Jšœžœžœžœ˜DJšœžœT˜nJšžœ&žœ˜AJšœ;˜;Jšœ˜—Jšžœ=˜Ašœ˜JšœžœF˜O—šœ˜Jšœ žœžœ2˜C—šœ˜Jšœ žœžœ3˜D—šœ˜Jšœ ˜ Jšžœžœžœ žœ)žœžœSŸœ˜ªJšœ,˜,—šœ˜Jšœ˜Jšžœžœžœ žœ)žœžœSŸœŸ˜«Jšœ,˜,—šœ˜Jšœ ˜ Jš žœžœžœ$žœžœSŸœ˜˜Jšœ.˜.—šœ˜Jš œ žœžœžœ$žœ ˜MJšœ8˜8—Jšœžœm˜šœ˜Jšœ˜Jšžœžœžœ žœ%žœžœ_Ÿœ˜´Jšœ;˜;—J˜Jšœžœj˜Œšœ˜Jšœ˜Jšžœžœžœ žœ%žœžœ žœžœ]Ÿœ˜ÇJšœ-˜-—J˜Jšœžœd˜‡šœ˜Jšœ˜Jšžœžœžœžœ%žœžœWŸœ˜±Jšœ7˜7—J˜Jšœžœc˜‡šœ˜Jšœ˜Jšžœžœžœžœ%žœžœžœUŸœ˜¼Jšœ/˜/—J˜Jšœžœa˜ƒšœ˜Jšœ˜Jšžœžœžœžœ%žœžœ žœžœTŸœ˜ÂJšœ˜—šœ˜Jš œ žœžœžœ$žœ ˜KJšœ˜——J˜J˜š Ÿœžœžœ$žœžœ˜FJšœ žœžœ˜Jšœžœ#˜>Jšœžœ[˜{Jšœ˜JšœPžœžœ  ®˜–Jšžœ žœ˜%J˜—J˜š¡œžœ%žœ˜9Jšœžœ˜ Jšœžœ˜ Jšœžœžœ˜šœ" "˜DJšžœ˜%—šžœ˜ šžœžœžœ˜Jšœžœžœ!˜BJšœžœX˜vJšœ˜Jšœ˜—Jšœ˜—Jšœ<˜<šžœžœžœ˜Jš œžœ#žœžœ žœ˜WJ˜—šžœ žœžœ˜Jšœ=žœ˜AJšœg˜gJšžœžœžœ˜Jšœižœžœ˜…J˜—Jšœ˜J˜—J˜˜J˜—š¢œžœ*žœ˜@Jšœ˜J˜—J˜šŸ œžœ žœ˜&Jšœ žœžœ˜2Jšžœ žœ4žœ:˜J˜——™šœU˜UNšœ5˜5Nšœ˜Jšœ ˜ N˜N˜—Nšžœ2˜9Mšžœ˜—™&Nšœ Ïr™—™'N™Q—N™—…—7|IÓ