DIRECTORY CD, CDApplications, CDCommands, CDCommandOps, CDEvents, CDExtras, CDInline, CDOps, CDOrient, CDProperties, CDRects, CDValue, Rope USING [IsEmpty, ROPE], TerminalIO; CDCommandsImpl: CEDAR PROGRAM IMPORTS CDApplications, CDCommandOps, CDEvents, CDExtras, CDInline, CDOps, CDOrient, CDProperties, CDRects, CDValue, Rope, TerminalIO EXPORTS CDCommands = BEGIN renameEvent: CDEvents.EventRegistration_CDEvents.RegisterEventType[$RenameDesign]; RenameDesign: PUBLIC PROC [design: CD.Design, name: Rope.ROPE] = BEGIN dont: BOOL; oldName: Rope.ROPE _ design.name; IF Rope.IsEmpty[name] THEN { TerminalIO.WriteRope[" not renamed\n"]; RETURN }; design.name _ name; dont _ CDEvents.ProcessEvent[renameEvent, design, oldName, TRUE]; IF dont THEN { design.name _ oldName; [] _ CDEvents.ProcessEvent[renameEvent, design, oldName, FALSE]; } END; Select: PUBLIC PROC [design: CD.Design, pos: CD.DesignPosition, verbose: BOOL] = BEGIN sel: CD.ApplicationPtr _ NIL; FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF ~w.first.selected THEN { IF CDApplications.PointToI[pos, w.first] THEN {sel _ w.first; EXIT} }; ENDLOOP; IF sel#NIL THEN { sel.selected _ TRUE; CDOps.ReOrderApplication[design, sel]; CDOps.DelayedRedraw[design, CDApplications.ARectO[sel]]; IF verbose THEN CDCommandOps.WriteInfo[sel] } ELSE IF verbose THEN { FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF w.first.selected THEN { IF CDApplications.PointToI[pos, w.first] THEN { CDCommandOps.WriteInfo[w.first]; TerminalIO.WriteRope[" again"]; RETURN } }; ENDLOOP; TerminalIO.WriteRope[" no pointed object"]; } END; DeSelect: PUBLIC PROC [design: CD.Design, pos: CD.DesignPosition] = BEGIN aptr: CD.ApplicationPtr _ CDApplications.AplicationAt[CDOps.AppList[design], pos, TRUE]; IF aptr#NIL THEN BEGIN IF ~aptr.selected THEN ERROR; aptr.selected _ FALSE; CDOps.DelayedRedraw[design, CDApplications.ARectO[aptr]]; CDOps.ReOrderApplication[design, aptr]; END; END; BoundingRectAndCount: PROC[list: CD.ApplicationList, selectedOnly: BOOLEAN_FALSE] RETURNS [bound: CD.DesignRect_CDInline.empty, cnt: NAT_0] = BEGIN FOR tem: LIST OF CD.ApplicationPtr _ list, tem.rest WHILE tem#NIL DO IF selectedOnly AND NOT tem.first.selected THEN LOOP; cnt _ cnt+1; bound _ CDInline.Surround[bound, CDApplications.ARectO[tem.first]] ENDLOOP; END; DeselectAll: PUBLIC PROC [design: CD.Design] = BEGIN doItSingleWise: NAT = 4; sel: CD.ApplicationList = CDApplications.OnlySelected[CDOps.AppList[design]]; b: CD.DesignRect; cnt: NAT; [b, cnt] _ BoundingRectAndCount[list: sel]; CDApplications.DeSelectList[sel]; IF cnt<=doItSingleWise THEN FOR l: CD.ApplicationList _ sel, l.rest WHILE l#NIL DO CDOps.DelayedRedraw[design, CDApplications.ARectO[l.first]] ENDLOOP ELSE CDOps.DelayedRedraw[design, b]; END; SelectAll: PUBLIC PROC [design: CD.Design] = BEGIN b: CD.Rect _ CDApplications.BoundingRect[list: CDOps.AppList[design], selectedOnly: FALSE]; FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO w.first.selected _ TRUE ENDLOOP; CDOps.DelayedRedraw[design, b, FALSE]; END; AreaSelectTouched: PROC [design: CD.Design, area: CD.DesignRect] = BEGIN FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF NOT w.first.selected AND CDInline.Intersect[area, CDApplications.ARectI[w.first]] THEN { w.first.selected _ TRUE; CDOps.DelayedRedraw[design, CDApplications.ARectO[w.first], FALSE]; }; ENDLOOP; END; AreaDeSelectTouched: PROC [design: CD.Design, area: CD.DesignRect] = BEGIN FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF w.first.selected AND CDInline.Intersect[area, CDApplications.ARectI[w.first]] THEN { w.first.selected _ FALSE; CDOps.DelayedRedraw[design, CDApplications.ARectO[w.first]]; }; ENDLOOP; END; AreaSelectContained: PROC [design: CD.Design, area: CD.DesignRect] = BEGIN FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF CDInline.Inside[CDApplications.ARectI[w.first], area] THEN w.first.selected _ TRUE ENDLOOP; CDOps.DelayedRedraw[design, area, FALSE]; END; AreaDeSelectContained: PROC [design: CD.Design, area: CD.DesignRect] = BEGIN FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF CDInline.Inside[CDApplications.ARectI[w.first], area] THEN w.first.selected _ FALSE ENDLOOP; CDOps.DelayedRedraw[design, area]; END; AreaSelect: PUBLIC PROC [design: CD.Design, area: CD.DesignRect, includePartial: BOOL] = BEGIN IF includePartial THEN AreaSelectTouched[design, area] ELSE AreaSelectContained[design, area]; END; AreaDeSelect: PUBLIC PROC [design: CD.Design, area: CD.DesignRect, includePartial: BOOL] = BEGIN IF includePartial THEN AreaDeSelectTouched[design, area] ELSE AreaDeSelectContained[design, area]; END; DeleteSelected: PUBLIC PROC [design: CD.Design] = BEGIN toDelete, newContents: CD.ApplicationList; [selected: toDelete, others: newContents] _ CDApplications.SplitSelected[CDOps.AppList[design]]; CDOps.SetAppList[design, newContents]; FOR w: CD.ApplicationList _ toDelete, w.rest WHILE w#NIL DO CDOps.DelayedRedraw[design, CDApplications.ARectO[w.first], TRUE]; ENDLOOP; RememberShortTime[design, toDelete]; END; DeletePointed: PUBLIC PROC [design: CD.Design, pos: CD.DesignPosition] = BEGIN app: CD.ApplicationPtr _ CDApplications.AplicationAt[CDOps.AppList[design], pos]; IF app#NIL THEN { CDOps.RemoveApplication[design, app, TRUE]; RememberShortTime[design, app]; }; END; RedrawMoved: PROC [design: CD.Design, r: CD.DesignRect, offset: CD.DesignPosition] = BEGIN moved: CD.DesignRect _ CDInline.MoveRect[r, offset]; IF CDInline.Intersect[r, moved] THEN CDOps.DelayedRedraw[design, CDInline.Surround[r, moved], TRUE] ELSE { CDOps.DelayedRedraw[design, r]; CDOps.DelayedRedraw[design, moved]; -- use eraseFirst because also used by copy } END; StretchyMoveMode: PROC[design: CD.Design] RETURNS [BOOL] = BEGIN mode: INT = CDValue.FetchInt[boundTo: design, key: $CDxStretchyMove, propagation: global, ifNotFound: 0]; RETURN [mode=1] END; MoveSelected: PUBLIC PROC [design: CD.Design, offset: CD.DesignPosition, stretchy: CDCommands.StretchyMode] = BEGIN IF stretchy=yes OR ((stretchy=option) AND StretchyMoveMode[design]) THEN StretchyMoveSelected[design, offset] ELSE SimpleMoveSelected[design, offset] END; MovePointed: PUBLIC PROC [design: CD.Design, offset: CD.DesignPosition, pos: CD.DesignPosition, stretchy: CDCommands.StretchyMode] = BEGIN IF stretchy=yes OR ((stretchy=option) AND StretchyMoveMode[design]) THEN StretchyMovePointed[design, offset, pos] ELSE SimpleMovePointed[design, offset, pos] END; SimpleMoveSelected: PUBLIC PROC [design: CD.Design, offset: CD.DesignPosition] = BEGIN sel: CD.ApplicationList = CDApplications.OnlySelected[CDOps.AppList[design]]; bounding: CD.DesignRect = CDApplications.BoundingRect[sel]; FOR w: CD.ApplicationList _ sel, w.rest WHILE w#NIL DO w.first.location _ CDInline.AddPoints[w.first.location, offset]; ENDLOOP; RedrawMoved[design, bounding, offset] END; SimpleMovePointed: PUBLIC PROC [design: CD.Design, offset: CD.DesignPosition, pos: CD.DesignPosition] = BEGIN app: CD.ApplicationPtr = CDApplications.AplicationAt[CDOps.AppList[design], pos]; IF app#NIL THEN { bounding: CD.DesignRect = CDApplications.ARectO[app]; app.location _ CDInline.AddPoints[app.location, offset]; RedrawMoved[design, bounding, offset] } END; CopySelected: PUBLIC PROC [design: CD.Design, offset: CD.DesignPosition] = BEGIN new: CD.ApplicationList_NIL; sel: CD.ApplicationList = CDApplications.OnlySelected[CDOps.AppList[design]]; bounding: CD.DesignRect _ CDApplications.BoundingRect[sel]; FOR w: CD.ApplicationList _ sel, w.rest WHILE w#NIL DO aptr: CD.ApplicationPtr _ NEW[CD.Application]; aptr.ob _ w.first.ob; aptr.location _ CDInline.AddPoints[w.first.location, offset]; aptr.orientation _ w.first.orientation; aptr.properties _ CDProperties.CopyProps[w.first.properties]; aptr.selected _ TRUE; new _ CONS[aptr, new]; w.first.selected _ FALSE; ENDLOOP; CDOps.IncludeApplicationList[design, new, FALSE]; RedrawMoved[design, bounding, offset]; END; CopyPointed: PUBLIC PROC [design: CD.Design, offset: CD.DesignPosition, pos: CD.DesignPosition] = BEGIN app: CD.ApplicationPtr = CDApplications.AplicationAt[CDOps.AppList[design], pos]; IF app#NIL THEN { bounding: CD.DesignRect = CDApplications.ARectO[app]; aptr: CD.ApplicationPtr = NEW[CD.Application]; aptr.ob _ app.ob; aptr.location _ CDInline.AddPoints[app.location, offset]; aptr.orientation _ app.orientation; aptr.properties _ CDProperties.CopyProps[app.properties]; CDOps.IncludeApplication[design, aptr, FALSE]; RedrawMoved[design, bounding, offset]; }; END; TransformSelected: PUBLIC PROC [design: CD.Design, transform: CD.Orientation] = BEGIN DrawIt: PROC[r: CD.Rect] = {CDOps.DelayedRedraw[design, r]}; sel: CD.ApplicationList = CDApplications.OnlySelected[CDOps.AppList[design]]; b: CD.DesignRect = CDApplications.BoundingRect[sel]; FOR w: CD.ApplicationList _ sel, w.rest WHILE w#NIL DO CDApplications.Transform[w.first, b, transform] ENDLOOP; CDOps.DelayedRedraw[design, b]; IF CDOrient.IncludesOddRot90[transform] THEN { CDExtras.DecomposeRect[r: CDOrient.OrientedRect[b, transform], test: b, outside: DrawIt]; }; END; TransformPointed: PUBLIC PROC [design: CD.Design, transform: CD.Orientation, pos: CD.DesignPosition] = BEGIN app: CD.ApplicationPtr _ CDApplications.AplicationAt[CDOps.AppList[design], pos]; b: CD.DesignRect; IF app=NIL THEN RETURN; b _ CDApplications.ARectO[app]; FOR w: CD.ApplicationList _ CDOps.AppList[design], w.rest WHILE w#NIL DO IF w.first=app THEN {CDApplications.Transform[w.first, b, transform]; EXIT} ENDLOOP; CDOps.DelayedRedraw[design, b]; IF CDOrient.IncludesOddRot90[transform] THEN CDOps.DelayedRedraw[design, CDOrient.OrientedRect[b, transform]]; END; BaseTransformSelected: PUBLIC PROC [design: CD.Design, transform: CD.Orientation, base: CD.DesignRect] = BEGIN sel: CD.ApplicationList = CDApplications.OnlySelected[CDOps.AppList[design]]; b: CD.DesignRect _ CDApplications.BoundingRect[sel]; newB: CD.DesignRect _ CDOrient.MapRect[ itemInCell: b, cellSize: CDInline.SizeOfRect[base], cellInstOrient: transform, cellInstPos: CDInline.BaseOfRect[base] ]; FOR w: CD.ApplicationList _ sel, w.rest WHILE w#NIL DO CDApplications.Transform[w.first, base, transform] ENDLOOP; CDOps.DelayedRedraw[design, b]; CDOps.DelayedRedraw[design, newB] END; -- -- -- -- -- -- -- -- -- -- -- -- remSize: CARDINAL = 20; RememberBuffer: TYPE = RECORD[ a: ARRAY [0..remSize) OF REF _ ALL[NIL], next: CARDINAL_0]; Forgett: PROC[p: REF] = BEGIN WITH p SELECT FROM al: CD.ApplicationList => FOR l: CD.ApplicationList _ al, l.rest WHILE l#NIL DO Forgett[l.first] ENDLOOP; app: CD.ApplicationPtr => {app.properties _ NIL; app.ob _ NIL}; ENDCASE => NULL; END; RememberShortTime: PROC [d: CD.Design, what: REF] = BEGIN dl: REF RememberBuffer; IF d^.actual.first.deletedList=NIL THEN d^.actual.first.deletedList _ NEW[RememberBuffer]; dl _ NARROW[d^.actual.first.deletedList]; Forgett[dl.a[dl.next]]; dl.a[dl.next] _ what; dl.next _ (dl.next+1) MOD remSize; END; GiveRemembered: PROC [d: CD.Design] RETURNS [REF] = BEGIN x: REF; dl: REF RememberBuffer; IF d^.actual.first.deletedList=NIL THEN RETURN [NIL]; dl _ NARROW[d^.actual.first.deletedList]; dl.next _ (dl.next+remSize-1) MOD remSize; x _ dl.a[dl.next]; dl.a[dl.next] _ NIL; RETURN [x]; END; Undelete: PUBLIC PROC [design: CD.Design] = BEGIN del: REF _ GiveRemembered[design]; IF del=NIL THEN RETURN; WITH del SELECT FROM al: CD.ApplicationList => CDOps.IncludeApplicationList[design, al]; app: CD.ApplicationPtr => CDOps.IncludeApplication[design, app] ENDCASE => NULL; END; -- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Primality: TYPE = {primary, secondary}; ChangeWireLength: PROC [design: CD.Design, aptr: CD.ApplicationPtr, amount: CD.DesignNumber] = BEGIN sz: CD.DesignPosition = CDInline.SizeOfRect[aptr.ob.p.insideRect[aptr.ob]]; r: CD.DesignRect _ CDApplications.ARectO[aptr]; newOb: CD.ObPtr_NIL; IF NOT WireTyped[aptr.ob] THEN ERROR; newOb _ CDRects.CreateRect[CD.DesignPosition[x: sz.x, y: sz.y+amount], aptr.ob.level]; IF newOb=NIL THEN RETURN; IF aptr.ob.p#newOb.p THEN ERROR; aptr.ob _ newOb; r _ CDInline.Surround[r, CDApplications.ARectO[aptr]]; CDOps.DelayedRedraw[design, r]; END; StretchyMoveSP: PROC[design: CD.Design, offset: CD.DesignPosition, selectedApps, nonSelectedApps: CD.ApplicationList] = BEGIN primApps: CD.ApplicationList _ NIL; primList, secondList, nonPrimList: StretchList _ NIL; rect: CD.DesignRect; rect _ CDApplications.BoundingRect[selectedApps]; FOR l: CD.ApplicationList _ nonSelectedApps, l.rest WHILE l#NIL DO IF WireTyped[l.first.ob] THEN { me: REF StretchRec_NEW[StretchRec_StretchRec[ ap: l.first, conductRect: CDApplications.ARectI[l.first], horizontal: CDOrient.IncludesOddRot90[l.first.orientation] -- (length in y direction) ]]; IF CDInline.Intersect[rect, me.conductRect] AND HasMatch[me, selectedApps, primary] THEN {primList _ CONS[me, primList]; primApps _ CONS[me.ap, primApps]} ELSE nonPrimList _ CONS[me, nonPrimList] }; ENDLOOP; FOR l: StretchList _ nonPrimList, l.rest WHILE l#NIL DO IF HasMatch[l.first, primApps, secondary] THEN secondList _ CONS[l.first, secondList] ENDLOOP; FOR l: StretchList _ secondList, l.rest WHILE l#NIL DO FiddleWire[design, l.first, offset, secondary] ENDLOOP; FOR l: StretchList _ primList, l.rest WHILE l#NIL DO FiddleWire[design, l.first, offset, primary] ENDLOOP; FOR l: CD.ApplicationList _ selectedApps, l.rest WHILE l#NIL DO MoveApplication[design, l.first, offset] ENDLOOP; END; StretchyMoveSelected: PROC[design: CD.Design, offset: CD.DesignPosition] = BEGIN selectedApps, nonSelectedApps: CD.ApplicationList _ NIL; [selectedApps, nonSelectedApps] _ CDApplications.SplitSelected[CDOps.AppList[design]]; StretchyMoveSP[design, offset, selectedApps, nonSelectedApps] END; StretchyMovePointed: PROC[design: CD.Design, offset: CD.DesignPosition, pos: CD.DesignPosition] = BEGIN selectedApps, nonSelectedApps: CD.ApplicationList _ NIL; [selectedApps, nonSelectedApps] _ CDApplications.SplitPointed[CDOps.AppList[design], pos]; StretchyMoveSP[design, offset, selectedApps, nonSelectedApps] END; StretchList: TYPE = LIST OF REF StretchRec; StretchRec: TYPE = RECORD [ ap: CD.ApplicationPtr, conductRect: CD.DesignRect, -- hint only near: BOOL _ FALSE, -- match at near edge (relative to the origin) far: BOOL _ FALSE, -- match at far edge (relative to the origin) horizontal: BOOL _ FALSE ]; FiddleWire: PROC [design: CD.Design, wire: REF StretchRec, offset: CD.DesignPosition, p: Primality] = BEGIN move: CD.DesignPosition_offset; IF ~wire.near AND ~wire.far THEN RETURN; IF p#primary THEN {IF wire.horizontal THEN move.y_0 ELSE move.x_0}; IF wire.near AND ~wire.far THEN { IF p#primary THEN {IF wire.horizontal THEN move.y_0 ELSE move.x_0}; ChangeWireLength[design, wire.ap, -(IF wire.horizontal THEN offset.x ELSE offset.y)]; }; IF ~wire.near AND wire.far THEN { IF wire.horizontal THEN {move.x_0} ELSE {move.y_0}; ChangeWireLength[design, wire.ap, (IF wire.horizontal THEN offset.x ELSE offset.y)]; }; IF wire.near AND wire.far THEN NULL; MoveApplication[design, wire.ap, move] END; HasMatch: PROC [me: REF StretchRec, list: CD.ApplicationList, p: Primality] RETURNS [BOOL] = BEGIN near, far: BOOL; nearEdge, farEdge: CD.DesignRect; nearEdge _ farEdge _ me.conductRect; -- edges at near or far end of wire, parallel to width IF ~CDOrient.IncludesOddRot90[me.ap.orientation] THEN { farEdge.y1 _ me.conductRect.y2; nearEdge.y2 _ me.conductRect.y1; } ELSE { farEdge.x1 _ me.conductRect.x2; nearEdge.x2 _ me.conductRect.x1; me.horizontal _ TRUE; }; FOR l: CD.ApplicationList _ list, l.rest WHILE l#NIL DO r: CD.DesignRect = CDApplications.ARectI[l.first]; near _ CDInline.Intersect[nearEdge, r]; far _ CDInline.Intersect[farEdge, r]; IF near OR far THEN { IF WireTyped[l.first.ob] THEN { IF l.first.ob.level#me.ap.ob.level THEN near _ far _ FALSE ELSE IF p#primary AND me.horizontal=CDOrient.IncludesOddRot90[l.first.orientation] THEN near _ far _ FALSE } ELSE IF l.first.ob.p.match#NIL THEN { rect: CD.DesignRect = CDApplications.ARectI[me.ap]; IF ~l.first.ob.p.match[l.first.ob, rect, me.ap.ob.level, p=primary, me.horizontal] THEN near _ far _ FALSE } ELSE IF ISTYPE[l.first.ob.specificRef, CD.CellPtr] THEN NULL ELSE near _ far _ FALSE; me.near _ me.near OR near; me.far _ me.far OR far; }; ENDLOOP; RETURN [me.near OR me.far] END; MoveApplication: PROC [design: CD.Design, ap: CD.ApplicationPtr, offset: CD.DesignPosition] = BEGIN r: CD.DesignRect _ CDApplications.ARectO[ap]; ap.location _ CDInline.AddPoints[ap.location, offset]; RedrawMoved[design, r, offset] END; WireTyped: PROC [ob: CD.ObPtr] RETURNS [BOOL] = INLINE {RETURN [ob.p.wireTyped]}; -- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx END. ÐCDCommandsImpl.mesa (part of Chipndale) by Christian Jacobi July 12, 1983 10:56 am last edited by Christian Jacobi February 16, 1984 1:57 pm --is only local name --reorder list, future select selects next lower application --reorder list, future select op finds next lower application --dont care about redrawing too much --helps the garbage collector, --special may prevent circularities through properties --?? for now CDRects.CreateRect is ONLY method to create wires --this checks if old object was created with CDRects.CreateRect --?? change slow case distinction, but now better is easy to understand -- checks weather me has some match with any of list --?? Only CDRects.CreateRect for now ÊB˜Jšœ-™-Jšœ-™-Jšœ;™;J˜šÏk ˜ Jšœ˜J˜Jšœ ˜ J˜ J˜ Jšœ ˜ Jšœ ˜ J˜J˜ J˜ J˜Jšœ˜Jšœœ œ˜J˜ J˜—šÏbœœœ˜Jšœ˜%Jšœ_˜_Jšœ˜—Jš˜J˜RJ˜š Ïn œœœ œœ˜@Jšœ™Jš˜Jšœœ˜ Jšœœ˜!šœœ˜Jšœ(˜(Jš˜J˜—Jšœ˜Jšœ;œ˜Ašœœ˜Jšœ˜Jšœ9œ˜@J˜—Jšœ˜—J˜š Ÿœœœ œœœ˜PJš˜Jšœœœ˜š œœ1œœ˜Hšœœ˜Jšœ'œœ˜CJ˜—Jšœ˜—šœœœ˜Jšœœ˜Jšœ=™=Jšœ&˜&Jšœ8˜8Jšœ œ˜+Jšœ˜—šœœ œ˜š œœ1œœ˜Hšœœ˜šœ'œ˜/Jšœ ˜ Jšœ˜Jš˜Jšœ˜—J˜—Jšœ˜—Jšœ+˜+J˜—Jšœ˜J˜—š Ÿœœœ œœ˜CJšœ˜JšœœJœ˜Xšœœœ˜Jš˜Jšœœœ˜Jšœœ˜Jšœ9˜9Jšœ>™>Jšœ'˜'Jšœ˜—Jšœ˜J˜—š Ÿœœœ œœ˜RJšœ œ!œ˜;Jš˜š œœœœ!œœ˜DJš œœœœœ˜5J˜ JšœB˜BJšœ˜—Jšœ˜—J˜šŸ œœœ œ ˜.Jš˜Jšœœ˜JšœœF˜MJšœœ ˜Jšœœ˜ Jšœ+˜+Jšœ!˜!šœœ˜š œœœœ˜6Jšœ;˜;Jš˜——Jšœ ˜$Jšœ˜J˜—šŸ œœœ œ ˜,Jš˜Jšœ$™$JšœœOœ˜[š œœ1œœ˜HJšœ˜Jšœ˜—Jšœœ˜&Jšœ˜J˜—šŸœœ œœ˜BJšœ˜š œœ1œœ˜Hšœœ˜Jšœ:œ˜CJšœœ˜Jšœ<œ˜CJ˜—Jšœ˜—Jšœ˜J˜—šŸœœ œœ˜DJšœ˜š œœ1œœ˜Hšœ˜Jšœ:œ˜CJšœœ˜Jšœ<˜—šœ˜Jšœ˜Jšœ$Ïc+˜OJšœ˜—Jšœ˜J˜—š Ÿœœ œ œœ˜:Jš˜Jšœœ`˜iJšœ ˜Jšœ˜—J˜š Ÿ œœœ œœ5˜mJš˜Jšœœœœ%˜mJšœ#˜'Jšœ˜—J˜š Ÿ œœœ œœœ5˜„Jš˜Jšœœœœ)˜qJšœ'˜+Jšœ˜—J˜š Ÿœœœ œœ˜PJš˜JšœœF˜MJšœ œ/˜;š œœœœ˜6J˜@Jšœ˜—J˜%Jšœ˜J˜—š Ÿœœœ œœœ˜gJš˜JšœœJ˜Qšœœœ˜Jšœ œ)˜5Jšœ8˜8J˜%J˜—Jšœ˜J˜—š Ÿ œœœ œœ˜JJš˜Jšœœœ˜JšœœF˜MJšœ œ0˜<š œœœœ˜6Jšœœœœ˜.Jšœ˜Jšœ=˜=Jšœ'˜'Jšœ=˜=Jšœ˜Jšœœ ˜Jšœœ˜Jšœ˜—Jšœ*œ˜1Jšœ&˜&Jšœ˜J˜—š Ÿ œœœ œœœ˜aJš˜JšœœJ˜Qšœœœ˜Jšœ œ*˜6Jšœœœœ˜.Jšœ˜Jšœ9˜9Jšœ#˜#Jšœ9˜9Jšœ'œ˜.Jšœ&˜&J˜—Jšœ˜J˜—š Ÿœœœ œœ˜RJš˜JšŸœœœ*˜œ˜jJ˜—šœœœœ˜%Jšœœ+˜3JšœQœ˜jJ˜—Jš œœœœ œ˜