DIRECTORY CD, CDBasics, CDDrawQueue, CDCells, CDCommandOps, CDEnvironment, CDEvents, CDInstances, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, CDViewerInternals, CDVPrivate, CDVScale, IO, PopUpSelection, Process, Rope, TerminalIO, UserProfile, ViewerClasses USING [Viewer], ViewerOps USING [PaintViewer, GetViewer, SetViewer, OpenIcon, BlinkIcon]; CDVCommands: CEDAR PROGRAM IMPORTS CDBasics, CDCommandOps, CDDrawQueue, CDCells, CDEnvironment, CDEvents, CDInstances, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, CDVScale, IO, PopUpSelection, Process, Rope, TerminalIO, UserProfile, ViewerOps EXPORTS CDViewerInternals = BEGIN VRef: TYPE = CDVPrivate.VRef; DoWithVRef: PROC [comm: CDSequencer.Command, proc: PROC[vRef: VRef]] = { v: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF v=NIL THEN TerminalIO.WriteRope["failed: no viewer\n"] ELSE WITH v.data SELECT FROM vRef: VRef => IF ~vRef.viewer.destroyed THEN proc[vRef]; ENDCASE => NULL; }; AddCR: PROC [r: Rope.ROPE] RETURNS [Rope.ROPE] = { ml: INT _ Rope.Length[r]; IF Rope.Fetch[r, ml-1]#'\n THEN RETURN[Rope.Concat[r, "\n"]]; RETURN [r]; }; MsgAndVRef: PROC [comm: CDSequencer.Command, msg: Rope.ROPE] RETURNS [vRef: VRef_NIL] = { v: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; TerminalIO.WriteRope[AddCR[msg]]; IF v=NIL THEN TerminalIO.WriteRope[" failed: no viewer\n"] ELSE WITH v.data SELECT FROM vr: VRef => IF ~vr.viewer.destroyed THEN vRef _ vr ELSE TerminalIO.WriteRope[" failed: viewer destroyed\n"]; ENDCASE => TerminalIO.WriteRope[" failed: no ChipNDale viewer\n"]; }; Repaint: PROC [v: REF] = { WITH v SELECT FROM vRef: VRef => { CDDrawQueue.Flush[vRef.ct]; CDDrawQueue.QueueInsertDrawCommand[vRef.ct, CDDrawQueue.Request[$changeScale, CDBasics.universe]]; }; viewer: ViewerClasses.Viewer => Repaint[viewer.data]; comm: CDSequencer.Command => Repaint[comm.ref]; ENDCASE => NULL; }; SaveScale: PUBLIC PROC [viewer: ViewerClasses.Viewer] = { IF viewer#NIL THEN WITH viewer.data SELECT FROM vRef: VRef => CDProperties.PutProp[vRef.properties, $CDxSavedScale, NEW[CDVScale.ScaleRec _ vRef.scale]]; ENDCASE => NULL; }; RestoreScale: PUBLIC PROC [viewer: ViewerClasses.Viewer] = { IF viewer#NIL THEN WITH viewer.data SELECT FROM vRef: VRef => { GetScale: PROC [key: ATOM] RETURNS [CDVScale.ScaleRec] = { WITH CDProperties.GetProp[vRef.properties, key] SELECT FROM sr: REF CDVScale.ScaleRec => RETURN [sr^]; ENDCASE => RETURN [CDVScale.MakeScale[]]; }; scale: CDVScale.ScaleRec _ GetScale[$CDxSavedScale]; CDDrawQueue.Flush[vRef.ct]; IF vRef.scale.off=scale.off AND vRef.scale.nscale=scale.nscale THEN scale _ GetScale[$CDxSecondaryScale]; CDProperties.PutProp[vRef.properties, $CDxSecondaryScale, NEW[CDVScale.ScaleRec _ vRef.scale]]; vRef.intendedScale _ CDVScale.MakeScale[off: scale.off, nscale: scale.nscale, grid: vRef.scale.grid]; Repaint[vRef]; }; ENDCASE => NULL; }; WriteLnScale: PROC [v: REF] = { WITH v SELECT FROM vRef: VRef => TerminalIO.WriteF1[" (scale: %g)\n", IO.int[vRef.scale.nscale]]; viewer: ViewerClasses.Viewer => WriteLnScale[viewer.data]; comm: CDSequencer.Command => WriteLnScale[comm.ref]; ENDCASE => TerminalIO.WriteLn[]; }; ChangeScale: PROC [vRef: VRef, newScale: INT] = { newScale _ MIN[MAX[0, newScale], CDVScale.scaleNum-1]; IF vRef.scale.nscale = newScale THEN TerminalIO.WriteRope["no scale change"] ELSE { oldDesignCenterOffset, newDesignCenterOffset: CD.Position; viewerCenterOffset: CD.Position _ [vRef.viewer.cw/2, vRef.viewer.ch/2]; off: CD.Position _ vRef.scale.off; dscale: CDVScale.ScaleRec; CDDrawQueue.Flush[vRef.ct]; TerminalIO.WriteRope["change scale"]; dscale _ CDVScale.MakeScale[nscale: vRef.scale.nscale, grid: vRef.scale.grid]; oldDesignCenterOffset _ CDVScale.ViewerToDesignPosition[dscale, viewerCenterOffset]; dscale _ CDVScale.MakeScale[nscale: newScale, grid: vRef.scale.grid]; newDesignCenterOffset _ CDVScale.ViewerToDesignPosition[dscale, viewerCenterOffset]; off _ CDBasics.SubPoints[ CDBasics.AddPoints[off, oldDesignCenterOffset], newDesignCenterOffset ]; dscale _ CDVScale.MakeScale[off: off, nscale: newScale, grid: vRef.scale.grid]; vRef.intendedScale _ dscale; Repaint[vRef]; }; WriteLnScale[vRef.viewer]; }; ScaleUp: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { i: INT _ vRef.scale.nscale; i _ IF i>0 THEN i-1 ELSE 0; ChangeScale[vRef, i]; }; DoWithVRef[comm, Do] }; ScaleDown: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = {ChangeScale[vRef, vRef.scale.nscale+1]}; DoWithVRef[comm, Do] }; MoveScreen: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { off: CD.Position; CDDrawQueue.Flush[vRef.ct]; off.x _ vRef.scale.off.x-(comm.pos.x-comm.sPos.x); off.y _ vRef.scale.off.y-(comm.pos.y-comm.sPos.y); vRef.intendedScale _ CDVScale.MakeScale[off: off,nscale: vRef.scale.nscale,grid: vRef.scale.grid]; Repaint[vRef]; }; TerminalIO.WriteRope["move window\n"]; DoWithVRef[comm, Do] }; GetViewerInt: PROC [viewer: ViewerClasses.Viewer, at: ATOM] RETURNS [i: INT _ -1] = { WITH ViewerOps.GetViewer[viewer, at] SELECT FROM ri: REF INT => i _ ri^; ENDCASE => NULL; }; GridInfoComm: PROC [comm: CDSequencer.Command] = { GridRope: PROC [v: ViewerClasses.Viewer] RETURNS [r: Rope.ROPE] = { r _ CDCommandOps.LambdaRope[GetViewerInt[viewer, $Grid], lambda] }; g: INT _ -1; lambda: INT _ comm.design.technology.lambda; viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF viewer=NIL THEN TerminalIO.WriteRope["no viewer\n"] ELSE { TerminalIO.WriteF1["set grid (currently %g)\n", [rope[GridRope[viewer]]]]; SELECT PopUpSelection.Request[ choice: LIST["1", " 2", " 4", " 8", "16", "1/2", "default", "type lambda", "type int"], header: "grid", headerDoc: "distance used for snapping the cursor"] FROM 1 => g _ lambda; 2 => g _ 2*lambda; 3 => g _ 4*lambda; 4 => g _ 8*lambda; 5 => g _ 16*lambda; 6 => g _ lambda/2; 7 => g _ CDValue.FetchInt[boundTo: CDViewer.DesignOf[viewer], key: $CDxInitGrid, propagation: global]; 8 => g _ MIN[INT[2600/lambda], TerminalIO.RequestInt["grid: "]]*lambda; 9 => g _ MIN[INT[2600], TerminalIO.RequestInt["grid: "]]; ENDCASE => g _ -1; IF g>0 AND g<=2600 THEN { ViewerOps.SetViewer[viewer: viewer, data: NEW[INT_g], op: $Grid]; TerminalIO.WriteF1[" grid set to %g \n", IO.rope[CDCommandOps.LambdaRope[g, lambda]]]; } ELSE TerminalIO.WriteRope[" failed \n"]; }; }; SetSimplificationComm: PROC[comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { n: INT; CDDrawQueue.Flush[vRef.ct]; n _ PopUpSelection.Request[ choice: LIST["very simplified", "simplified", "standard", "detailed", "very detailed", "show all"], header: "viewer simplification treshold", headerDoc: "the viewer simplification treshold is multiplied with the cell simplification treshold" ]; SELECT n FROM 1 => vRef.suppressFactorForCells _ 0.4; 2 => vRef.suppressFactorForCells _ 0.7; 3 => vRef.suppressFactorForCells _ 1; 4 => vRef.suppressFactorForCells _ 1.6; 5 => vRef.suppressFactorForCells _ 2.6; 6 => vRef.suppressFactorForCells _ 0; ENDCASE => RETURN; Repaint[vRef] }; TerminalIO.WriteRope["set viewer simplification threshold\n"]; DoWithVRef[comm, Do] }; TicksInfoComm: PROC[comm: CDSequencer.Command] = { ticks, n: INT _ -2; lambda: INT _ comm.design.technology.lambda; viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF viewer=NIL THEN TerminalIO.WriteRope["no viewer\n"] ELSE { ticks _ GetViewerInt[viewer, $Ticks]; TerminalIO.WriteF1["input tick (currently%g)\n", IO.rope[CDCommandOps.LambdaRope[ticks, lambda]]]; n _ PopUpSelection.Request[ choice: LIST["off", " 4", " 8", " 16", " 32", "type", "type int"], header: "Ticks", headerDoc: "dots to help positioning; number for spacing of dots" ]; ticks _ -2; SELECT n FROM 1 => ticks _ 0; 2 => ticks _ 4*lambda; 3 => ticks _ 8*lambda; 4 => ticks _ 16*lambda; 5 => ticks _ 32*lambda; 6 => { n: INT _ TerminalIO.RequestInt["ticks: "]; IF n>=0 AND n<=LAST[INTEGER]/lambda-1 THEN ticks _ n*lambda }; 7 => { n: INT _ TerminalIO.RequestInt["ticks (int): "]; IF n>=0 AND n<=LAST[INTEGER]-1 THEN ticks _ n }; ENDCASE => NULL; ViewerOps.SetViewer[viewer: viewer, data: NEW[INT_ticks], op: $Ticks]; IF ticks<-1 THEN TerminalIO.WriteRope[" failed\n"] ELSE IF ticks<=0 THEN TerminalIO.WriteRope[" ticks off\n"] ELSE TerminalIO.WriteF1[" ticks set to %g \n", IO.rope[CDCommandOps.LambdaRope[ticks, lambda]]] }; }; InstanceNames: PROC [comm: CDSequencer.Command] = { v: ViewerClasses.Viewer ~ CDViewer.GetViewer[comm]; TerminalIO.WriteRope["display instance names\n"]; IF v#NIL THEN ViewerOps.PaintViewer[v, client, FALSE, $DrawInstanceNames] }; SignalNames: PROC [comm: CDSequencer.Command] = { v: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; TerminalIO.WriteRope["display signal names\n"]; IF v#NIL THEN ViewerOps.PaintViewer[v, client, FALSE, $DrawSignalNames] }; GetOppositViewer: PROC [comm: CDSequencer.Command] RETURNS [ViewerClasses.Viewer] = { vl: CDViewer.ViewerList = CDViewer.ViewersOf[comm.design]; viewer: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; onColor: BOOL = (viewer=NIL OR viewer.column=color); FOR l: CDViewer.ViewerList _ vl, l.rest WHILE l#NIL DO IF ~l.first.iconic THEN IF (l.first.column=color)#onColor THEN RETURN [l.first]; ENDLOOP; FOR l: CDViewer.ViewerList _ vl, l.rest WHILE l#NIL DO IF ~l.first.iconic THEN IF l.first.column#viewer.column THEN RETURN [l.first]; ENDLOOP; FOR l: CDViewer.ViewerList _ vl, l.rest WHILE l#NIL DO IF ~l.first.iconic THEN IF l.first#viewer THEN RETURN [l.first]; ENDLOOP; RETURN [viewer]; }; ShowRectX: PROC [comm: CDSequencer.Command] = { SmallScale: PROC [comm: CDSequencer.Command] RETURNS [BOOL] = { min: CD.Number = 30; RETURN [min>ABS[comm.pos.x-comm.sPos.x] AND min>ABS[comm.pos.y-comm.sPos.y]] }; viewer: ViewerClasses.Viewer ~ GetOppositViewer[comm]; TerminalIO.WriteRope["position a viewer\n"]; IF viewer#NIL THEN IF SmallScale[comm] THEN CDViewer.ShowPosition[viewer: viewer, pos: comm.sPos] ELSE CDViewer.ShowAndScale[viewer: viewer, rect: CDBasics.ToRect[comm.pos, comm.sPos]]; }; RestoreViewComm: PROC [comm: CDSequencer.Command] = { TerminalIO.WriteRope["restore previous scale\n"]; RestoreScale[CDViewer.GetViewer[comm]]; }; ShowRect: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer ~ CDViewer.GetViewer[comm]; TerminalIO.WriteRope["scale viewer"]; SaveScale[viewer]; IF comm.pos=comm.sPos THEN CDViewer.ShowPosition[viewer, comm.pos] ELSE CDViewer.ShowAndScale[viewer, CDBasics.ToRect[comm.pos, comm.sPos]]; WriteLnScale[viewer]; }; ResetScaleComm: PROC [comm: CDSequencer.Command] = { ResetScaleAll: PROC [viewer: ViewerClasses.Viewer] = { b: CD.Rect; TerminalIO.WriteRope["reset scale (view all)"]; b _ CDCommandOps.BoundingBox[CDViewer.DesignOf[viewer]]; IF CDBasics.NonEmpty[b] THEN CDViewer.ShowAndScale[viewer, b]; WriteLnScale[viewer]; }; viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF viewer#NIL THEN { SaveScale[viewer]; ResetScaleAll[viewer]; }; }; ResetScaleToSelectedComm: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; TerminalIO.WriteRope["reset scale to selection"]; IF viewer#NIL THEN { b: CD.Rect _ CDInstances.BoundingRectO[list: CDOps.InstList[comm.design], selectedOnly: TRUE]; IF CDBasics.NonEmpty[b] THEN { SaveScale[viewer]; CDViewer.ShowAndScale[viewer: viewer, rect: b]; WriteLnScale[viewer]; RETURN; }; }; TerminalIO.WriteRope[" no selection\n"]; }; ResetScaleToPushedComm: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer = CDViewer.GetViewer[comm]; IF viewer#NIL THEN { b: CD.Rect; SaveScale[viewer]; TerminalIO.WriteRope["reset scale (to view all of pushed cell)"]; b _ CDInstances.BoundingRectO[list: CDOps.InstList[comm.design], selectedOnly: FALSE]; IF CDBasics.NonEmpty[b] THEN CDViewer.ShowAndScale[viewer, b]; WriteLnScale[viewer]; }; }; ShowViewers: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { CDDrawQueue.QueueInsertDrawCommand[vRef.ct, CDDrawQueue.Request[$ShowViewers, CDBasics.universe]]; }; TerminalIO.WriteRope["show viewers\n"]; DoWithVRef[comm, Do] }; SplitViewer: PROC [comm: CDSequencer.Command] = { TerminalIO.WriteRope["split viewer\n"]; [] _ CDViewer.CreateViewer[comm.design] }; SetCellSimplification: PROC [comm: CDSequencer.Command] = { Do: PROC[vRef: VRef] = { scale: CDVScale.ScaleRec _ vRef.scale; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected AND CDCells.IsCell[l.first.ob] THEN { simplifyOn: CD.Number _ CDVScale.DesignToViewerScalar[scale, l.first.ob.size.y]; CDCells.SetSimplificationTreshhold[l.first.ob, simplifyOn, TRUE]; CDOps.RedrawInstance[comm.design, l.first]; }; ENDLOOP; }; TerminalIO.WriteRope["put visibility threshold to current scale\n"]; DoWithVRef[comm, Do] }; EnforcePanel: PROC [comm: CDSequencer.Command] = { v: ViewerClasses.Viewer; TerminalIO.WriteRope["enforce a control panel\n"]; v _ CDPanel.CreatePanel[comm.design]; IF v#NIL THEN { IF v.iconic THEN ViewerOps.OpenIcon[v] ELSE ViewerOps.BlinkIcon[v, 1, 1, 200] }; }; DrawEnvComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: draw environment of pushed cells"]; IF vRef#NIL THEN { vRef.environment _ TRUE; CDProperties.PutProp[comm.design, $CDxDrawEnvironment, NIL]; Repaint[vRef]; }; }; DontDrawEnvComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: don't draw environment of pushed cells"]; IF vRef#NIL THEN { vRef.environment _ FALSE; CDProperties.PutProp[comm.design, $CDxDrawEnvironment, $FALSE]; Repaint[vRef]; }; }; DrawSymbolicsComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: draw symbolic objects"]; IF vRef#NIL THEN { vRef.symbolics _ TRUE; CDProperties.PutProp[comm.design, $CDxDrawSymbolics, NIL]; Repaint[vRef]; }; }; DontDrawSymbolicsComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: don't draw symbolic objects"]; IF vRef#NIL THEN { vRef.symbolics _ FALSE; CDProperties.PutProp[comm.design, $CDxDrawSymbolics, $FALSE]; Repaint[vRef]; }; }; DrawBordersComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: draw with borders"]; IF vRef#NIL THEN { vRef.borders _ TRUE; CDProperties.PutProp[comm.design, $CDxSkipBorder, $FALSE]; Repaint[vRef]; }; }; DontDrawBordersComm: PROC [comm: CDSequencer.Command] = { vRef: VRef _ MsgAndVRef[comm, "viewer drawmode: don't draw borders"]; IF vRef#NIL THEN { vRef.borders _ FALSE; CDProperties.PutProp[comm.design, $CDxSkipBorder, NIL]; Repaint[vRef]; }; }; SetNewVersion: PROC [design: CD.Design, new: BOOL_TRUE] = { IF design#NIL THEN FOR vl: CDViewer.ViewerList _ CDViewer.ViewersOf[design], vl.rest WHILE vl#NIL DO IF vl.first.newVersion#new THEN { vl.first.newVersion _ new; ViewerOps.PaintViewer[vl.first, caption] }; ENDLOOP }; SetNewEvent: CDEvents.EventProc = { TRUSTED {Process.Detach[FORK SetNewVersion[design, TRUE]]}; }; AfterOutputEvent: CDEvents.EventProc = { TRUSTED {Process.Detach[FORK SetNewVersion[design, FALSE]]}; }; NoteProfileChange: UserProfile.ProfileChangedProc = { IF reason=edit THEN { FOR vl: CDViewer.ViewerList _ CDViewer.ViewersOf[NIL], vl.rest WHILE vl#NIL DO d: CD.Design _ CDViewer.DesignOf[vl.first]; IF d#NIL THEN vl.first.tipTable _ CDEnvironment.GetTipTable[d]; ENDLOOP }; }; UserProfile.CallWhenProfileChanges[NoteProfileChange]; CDPanel.DefineButton[tech: NIL, name: " new view ", proc: SplitViewer, queue: dontQueue, topLine: TRUE]; CDSequencer.ImplementCommand[$ScaleLessDetail, ScaleDown,, dontQueue]; CDSequencer.ImplementCommand[$ScaleMoreDetail, ScaleUp,, dontQueue]; CDSequencer.ImplementCommand[$MoveScreen, MoveScreen,, dontQueue]; CDSequencer.ImplementCommand[$DisplayNames, SignalNames,, doQueue]; CDSequencer.ImplementCommand[$DisplayInstanceNames, InstanceNames,, doQueue]; CDSequencer.ImplementCommand[$ShowRectX, ShowRectX,, dontQueue]; CDSequencer.ImplementCommand[$ShowRect, ShowRect,, dontQueue]; CDSequencer.ImplementCommand[$ResetScaleAll, ResetScaleComm,, dontQueue]; CDSequencer.ImplementCommand[$ResetScaleTop, ResetScaleToPushedComm,, dontQueue]; CDSequencer.ImplementCommand[$ResetScaleSel, ResetScaleToSelectedComm,, dontQueue]; CDSequencer.ImplementCommand[$DisplayViewers, ShowViewers,, doQueue]; CDSequencer.ImplementCommand[$SplitViewer, SplitViewer,, dontQueue]; CDSequencer.ImplementCommand[$GridInfo, GridInfoComm,, dontQueue]; CDSequencer.ImplementCommand[$TicksInfo, TicksInfoComm,, doQueue]; CDSequencer.ImplementCommand[$SetSimplification, SetSimplificationComm,, dontQueue]; CDSequencer.ImplementCommand[$RestoreScale, RestoreViewComm,, dontQueue]; CDSequencer.ImplementCommand[$SetCellSimplification, SetCellSimplification]; CDSequencer.ImplementCommand[$EnforcePanel, EnforcePanel,, doQueue]; CDSequencer.ImplementCommand[$ViewEnv, DrawEnvComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewNEnv, DontDrawEnvComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewSym, DrawSymbolicsComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewNSym, DontDrawSymbolicsComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewBord, DrawBordersComm,, dontQueue]; CDSequencer.ImplementCommand[$ViewNBord, DontDrawBordersComm,, dontQueue]; CDEvents.RegisterEventProc[event: $AfterOutput, proc: AfterOutputEvent]; CDEvents.RegisterEventProc[event: $SetEdited, proc: SetNewEvent]; END. ΌCDVCommands.mesa (part of ChipNDale) Copyright c 1983, 1985, 1986 by Xerox Corporation. All rights reserved. Created by Christian Jacobi, June 29, 1983 4:44 pm Last Edited by: Christian Jacobi, September 3, 1986 10:32:35 am PDT --Utilities and public --if r does not already has a CR --NO SaveScale[viewer]; it is better to have one fixed point --gets viewer on different screen if possible, --else different viewer, if possible... Κ±code– "cedar" style˜šœ&™&Kšœ Οmœ=™HKšœ3™3K™CK˜—šΟk ˜ Kšžœ˜K˜ Kšœ ˜ K˜Kšœ ˜ Kšœ˜K˜ K˜ Kšœ˜K˜Kšœ ˜ Kšœ ˜ Kšœ˜K˜ K˜Kšœ ˜ Kšœ ˜ Kšžœ˜Kšœ˜Kšœ˜K˜K˜ Kšœ ˜ Kšœžœ ˜Kšœ žœ:˜I—K˜šΟn œžœž˜KšžœžœC˜ιKšžœ˜—Kšž˜K˜Kšœžœ˜K˜KšŸ™K˜šŸ œžœ#žœ˜HKšœ3˜3Kšžœžœžœ,˜9šžœžœžœž˜Kšœžœžœ ˜8Kšžœžœ˜—Kšœ˜—K˜š Ÿœžœ žœžœžœ˜2Kšœ!™!Kšœžœ˜Kšžœžœžœ˜=Kšžœ˜ K˜—K˜š Ÿ œžœ'žœžœ žœ˜YKšœ3˜3Kšœ!˜!Kšžœžœžœ-˜:šžœžœžœž˜šœ ˜ Kšžœžœ ˜'Kšžœ5˜9—Kšžœ;˜B—Kšœ˜—K˜šŸœžœžœ˜šžœžœž˜šœ˜Kšœ˜Kšœb˜bK˜—Kšœ5˜5Kšœ/˜/Kšžœžœ˜—Kšœ˜K˜—šŸ œžœžœ#˜9šžœžœžœ˜šžœ žœž˜KšœDžœ"˜iKšžœžœ˜——Kšœ˜—K˜šŸ œž œ#˜<šžœžœžœ˜šžœ žœž˜šœ˜šŸœžœžœžœ˜:šžœ,žœž˜;Kšœžœžœ˜*Kšžœžœ˜)—K˜—Kšœ4˜4Kšœ˜Kšœ<™<šžœžœ žœ˜DKšœ%˜%—Kšœ:žœ"˜_Kšœe˜eKšœ˜Kšœ˜—Kšžœžœ˜——Kšœ˜—K˜šŸ œžœžœ˜šžœžœž˜Kšœ3žœ˜NKšœ:˜:Kšœ4˜4Kšžœ˜ —Kšœ˜—K˜šŸ œžœžœ˜1Kšœ žœžœ%˜7šžœžœ˜%Kšœ'˜'—šžœ˜Kšœ.žœ ˜:Kšœžœ1˜GKšœžœ˜"Kšœ˜Kšœ˜K˜%KšœN˜NKšœT˜TKšœE˜EKšœT˜Tšœ˜Kšœ0˜0Kšœ˜Kšœ˜—KšœO˜OKšœ˜Kšœ˜Kšœ˜—Kšœ˜Kšœ˜K˜—šŸœžœ ˜-šŸœžœ˜Kšœžœ˜Kšœžœžœžœ˜K˜K˜—Kšœ˜Kšœ˜K˜—šŸ œžœ ˜/KšŸœžœ9˜AKšœ˜Kšœ˜K˜—šŸ œžœ ˜0šŸœžœ˜Kšœžœ ˜Kšœ˜K˜2K˜3Kšœb˜bKšœ˜K˜—K˜&Kšœ˜Kšœ˜K˜—š Ÿ œžœ$žœžœžœ ˜Ušžœ!žœž˜0Kšœžœžœ ˜Kšžœžœ˜—K˜K˜—šŸ œžœ ˜2šŸœžœžœ žœ˜CKšœ@˜@Kšœ˜—Kšœžœ˜ Kšœžœ!˜,Kšœ8˜8Kšžœžœžœ$˜6šžœ˜KšœJ˜Jšžœ˜KšœžœL˜XKšœ˜Kšœ4ž˜8K˜K˜K˜K˜K˜K˜Kšœf˜fKšœ žœžœ7˜GKšœ žœžœ)˜9Kšžœ ˜—šžœžœ žœ˜Kšœ*žœžœ˜AKšœ+žœ+˜XK˜—Kšžœ&˜*K˜—Kšœ˜K˜—šŸœžœ˜:šŸœžœ˜Kšœžœ˜Kšœ˜šœ˜KšœžœW˜cKšœ)˜)Kšœc˜cK˜—šžœž˜ Kšœ'˜'Kšœ(˜(Kšœ&˜&Kšœ'˜'Kšœ'˜'Kšœ%˜%Kšžœžœ˜—Kšœ ˜ K˜—Kšœ>˜>Kšœ˜Kšœ˜K˜—šŸ œžœ˜2Kšœ žœ˜Kšœžœ!˜,Kšœ8˜8Kšžœžœžœ$˜6šžœ˜Kšœ%˜%Kšœ1žœ/˜bšœ˜Kšœžœ9˜EKšœ˜KšœA˜AKšœ˜—Kšœ ˜ šžœž˜ K˜K˜K˜K˜K˜šœ˜Kšœžœ$˜*Kš žœžœžœžœ žœ˜;Kšœ˜—šœ˜Kšœžœ*˜0Kš žœžœžœžœžœ ˜-Kšœ˜—Kšžœžœ˜—Kšœ*žœžœ˜FKšžœ žœ%˜5Kšžœžœ žœ'˜Kšœ˜Kšœ˜K˜—Kšœ8˜8šžœžœžœ˜Kšœ˜Kšœ˜K˜—Kšœ˜—K˜š œžœ ˜>Kšœ8˜8Kšœ1˜1šžœžœžœ˜KšœžœSžœ˜^šžœžœ˜Kšœ˜Kšœ/˜/Kšœ˜Kšžœ˜K˜—K˜—Kšœ)˜)Kšžœ˜—K˜š œžœ ˜Kšœ˜K˜—Kšœ˜—K˜š  œžœ ˜1šŸœžœ˜Kšœc˜cKšœ˜—Kšœ'˜'Kšœ˜Kšœ˜—K˜š  œžœ ˜1Kšœ'˜'K˜'Kšžœ˜—K˜šŸœžœ ˜;šŸœžœ˜Kšœ&˜&š žœžœ4žœžœž˜Kšžœžœžœ˜9Kšœ žœB˜PKšœ;žœ˜AKšœ+˜+Kšœ˜—Kšžœ˜—Kšœ˜—K˜EKšœ˜Kšœ˜—K˜šŸ œžœ ˜2Kšœ˜Kšœ2˜2Kšœ%˜%šžœžœžœ˜Kšžœ žœ˜&Kšžœ"˜&K˜—Kšœ˜K˜—š  œžœ ˜1KšœS˜Sšžœžœžœ˜Kšœžœ˜Kšœ7žœ˜˜>KšœI˜IKšœQ˜QKšœS˜SKšœE˜EKšœD˜DKšœB˜BKšœB˜BKšœT˜TKšœI˜IKšœL˜LK˜DK˜Kšœ@˜@KšœE˜EKšœF˜FKšœK˜KKšœE˜EKšœJ˜JK˜KšœH˜HKšœA˜AKšžœ˜K˜K˜—…—CΆX#