DIRECTORY Asserting, AssertingIO, Convert, FS, GetMe, IO, OrderedSymbolTableRef, PupDefs, Rope, RoseCapture, RoseCreate, RoseTypes, UserCredentials; RoseCaptureImpl: CEDAR PROGRAM IMPORTS Asserting, AssertingIO, Convert, FS, GetMe, IO, OrderedSymbolTableRef, PupDefs, Rope, RoseCreate, RoseTypes, UserCredentials EXPORTS RoseCapture = BEGIN OPEN RoseTypes; LORA: TYPE = LIST OF REF ANY; DesignCapture: TYPE = REF DesignCaptureRep; DesignCaptureRep: TYPE = RECORD [ fileNameRoot: ROPE, dfOut: STREAM, genCount: INT _ 0 ]; CTCapture: TYPE = REF CTCaptureRep; CTCaptureRep: TYPE = RECORD [ dc: DesignCapture, cellOut: STREAM, cell: Cell ]; Wire: TYPE = REF WireRep; WireRep: TYPE = RECORD [name: ROPE, better: Wire _ NIL, worse: WireList _ NIL]; WireList: TYPE = LIST OF Wire; machineName: ROPE _ "??"; userName: ROPE _ "??"; capKey: ATOM _ $Capture; wireKey: ATOM _ $Wire; captureExpansion: ERClass _ NEW [ERClassRep _ [ CellInstance: CellInstance, NodeInstance: NodeInstance, Equivalence: Equivalence ]]; Log: PROC [format: ROPE, v1, v2, v3, v4, v5: IO.Value _ [null[]]] = BEGIN msg: ROPE _ IO.PutFR[format, v1, v2, v3, v4, v5]; SIGNAL Warning[msg]; END; CaptureDesign: PUBLIC PROC [directory, designName, topCellTypeName: ROPE] = BEGIN fileNameRoot: ROPE _ designName; dfName: ROPE _ fileNameRoot.Cat["-Str.DF"]; dc: DesignCapture _ NEW [DesignCaptureRep _ [fileNameRoot, FS.StreamOpen[dfName, create]]]; topCellType: CellType _ RoseCreate.GetCellType[topCellTypeName]; IF topCellType = NIL THEN {Log["No such cell type as %g", IO.refAny[topCellTypeName]]; RETURN}; machineName _ PupDefs.GetMyName[]; userName _ UserCredentials.Get[].name; dc.dfOut.PutF["-- (DesignName %g)\n", IO.refAny[designName]]; dc.dfOut.PutF["-- (CreatingUser %g)\n", IO.refAny[userName]]; dc.dfOut.PutF["-- (CreationTime \"%g\")\n", IO.time[]]; dc.dfOut.PutF["-- (CreationSite \"MilkyWay Sol III USA Xerox PARC ComputerResearch %q\")\n", IO.rope[machineName]]; dc.dfOut.PutF["-- (DerivingProgram \"Rosemary Structure Capturer\" %g)\n", IO.refAny[GetMe.StandardScrewyEncoding[GetMe.GetVersion[]]]]; dc.dfOut.PutF["\n\nDirectory %g\n %g\n", IO.rope[directory], IO.rope[dfName]]; CaptureCellType[dc, topCellType]; dc.dfOut.Close[]; END; CaptureCellType: PROC [dc: DesignCapture, cellType: CellType] = BEGIN cell: Cell _ NEW [CellRep _ [ name: Rope.Cat["An instance of ", cellType.name, ", which is being captured"], type: cellType, parent: NIL, internalNodes: OrderedSymbolTableRef.CreateTable[ RoseCreate.CompareNodes], components: OrderedSymbolTableRef.CreateTable[ RoseCreate.CompareComponents], interfaceNodes: NEW [NodeSR[cellType.ports.length]], substantiality: Shadow, expansion: Expand ]]; WriteNode: PROC [ra: REF ANY] RETURNS [stop: BOOL] = { WriteAliases: PROC [worse: WireList] = { FOR worse _ worse, worse.rest WHILE worse # NIL DO ctc.cellOut.PutF[" (%g (G P))", IO.refAny[worse.first.name]]; WriteAliases[worse.first.worse]; ENDLOOP}; WriteWires: PROC [type: NodeType, ra: REF ANY, other: Assertions] = { WITH type SELECT FROM ant: ArrayNodeType => {list: LORA _ NARROW[ra]; FOR i: INT IN [0 .. ant.length) DO WriteWires[ant.element, list.first, other]; list _ list.rest; ENDLOOP}; ant: AtomNodeType => {w: Wire _ NARROW[ra]; IF w.better = NIL THEN { ctc.cellOut.PutF["(N %g (G D)", IO.refAny[w.name]]; IF w.worse # NIL THEN { ctc.cellOut.PutRope[" (A"]; WriteAliases[w.worse]; ctc.cellOut.PutRope[")"]}; FOR ol: Assertions _ other, ol.rest WHILE ol # NIL DO ctc.cellOut.PutRope[" "]; AssertingIO.WriteAssn[ctc.cellOut, ol.first]; ENDLOOP; ctc.cellOut.PutRope[")\n"]; }; }; ENDCASE => ERROR}; n: Node _ NARROW[ra]; w: REF ANY _ Asserting.FnVal[fn: wireKey, from: n.other]; stop _ FALSE; WriteWires[n.type, w, Asserting.Filter[reln: wireKey, from: n.other].notAbout]; }; DestroyNode: PROC [ra: REF ANY] RETURNS [stop: BOOL] = { n: Node _ NARROW[ra]; stop _ FALSE; IF cell.internalNodes.Delete[n] # n THEN ERROR; n.type _ NIL; n.cellIn _ NIL; IF n.nextPerturbed # notInNodeList OR n.nextAffected # notInNodeList OR n.nextDelayed # notInNodeList OR n.prevDelayed # notInNodeList THEN ERROR; n.watchers _ ALL[NIL]; n.designNext _ NIL; n.other _ NIL; }; WriteComponent: PROC [ra: REF ANY] RETURNS [stop: BOOL] = { WriteConnection: PROC [type: NodeType, portName: ROPE, ra: REF ANY] = {WITH type SELECT FROM ant: ArrayNodeType => {list: LORA _ NARROW[ra]; FOR i: INTEGER IN [0 .. ant.length) DO WriteConnection[ant.element, Sub[portName, i], list.first]; list _ list.rest; ENDLOOP}; ant: AtomNodeType => {w: Wire _ Best[ra]; ctc.cellOut.PutF["\n\t\t(%g %g)", IO.refAny[portName], IO.refAny[w.name]]; }; ENDCASE => ERROR}; c: Cell _ NARROW[ra]; prev: Cell _ NIL; stop _ FALSE; ctc.cellOut.PutF["(CI %g %g (G D)\n\t(CIC", IO.refAny[c.name], IO.refAny[c.type.name]]; FOR index: CARDINAL IN [0 .. c.type.ports.length) DO w: REF ANY_ Asserting.FnVal[fn: wireKey, from: c.interfaceNodes[index].other]; WriteConnection[c.type.ports[index].type, c.type.ports[index].name, w]; ENDLOOP; ctc.cellOut.PutRope[")"]; FOR ol: Assertions _ c.other, ol.rest WHILE ol # NIL DO ctc.cellOut.PutRope["\n\t"]; AssertingIO.WriteAssn[ctc.cellOut, ol.first]; ENDLOOP; ctc.cellOut.PutRope[")\n"]; SELECT Asserting.FnVal[fn: capKey, from: c.type.other] FROM ctc.dc => NULL; ENDCASE => CaptureCellType[ctc.dc, c.type]; IF cell.components.Delete[c] # c THEN ERROR; IF c.realCellStuff # NIL THEN ERROR; c.other _ NIL; c.interfaceNodes _ NIL; c.internalNodes.DestroyTable[]; c.components.DestroyTable[]; c.internalNodes _ c.components _ NIL; IF c.firstInternalNode # NIL THEN ERROR; IF c.leftChild # NIL THEN ERROR; c.parent _ c.rightSibling _ NIL; c.sim _ NIL; c.nextInstance _ NIL; c.type _ NIL; }; cellFileName: ROPE _ CellTypeFileName[dc, cellType]; ctc: CTCapture _ NEW [CTCaptureRep _ [ dc: dc, cellOut: FS.StreamOpen[cellFileName, create], cell: cell ]]; cellType.other _ Asserting.AssertFn1[fn: capKey, val: dc, inAdditionTo: cellType.other]; dc.dfOut.PutF["\n-- (CellType %g)\n %g\n", IO.refAny[cellType.name], IO.rope[cellFileName]]; ctc.cellOut.PutF["(CellTypeName %g)\n", IO.refAny[cellType.name]]; ctc.cellOut.PutF["(CreationTime \"%g\")\n", IO.time[]]; ctc.cellOut.PutF["(CreatingUser %g)\n", IO.refAny[userName]]; ctc.cellOut.PutF["(CreationSite \"MilkyWay Sol III USA Xerox PARC ComputerResearch %q\")\n", IO.rope[machineName]]; ctc.cellOut.PutF["(DerivingProgram \"Rosemary Structure Capturer\" %g)\n", IO.refAny[GetMe.StandardScrewyEncoding[GetMe.GetVersion[]]]]; WritePorts[cellType, ctc.cellOut]; WriteAssertions[cellType.other, ctc.cellOut]; ctc.cellOut.PutRope["(PrivateFollows)\n"]; IF cellType.expand # NIL THEN { FOR pi: PortIndex IN [0 .. cellType.ports.length) DO port: Port _ cellType.ports[pi]; cell.interfaceNodes[pi] _ captureExpansion.NodeInstance[ctc, port.name, port.type]; ENDLOOP; cellType.expand[ctc.cell, [ctc, captureExpansion]]; cell.internalNodes.EnumerateIncreasing[WriteNode]; WritePortNets[cellType, ctc.cellOut, cell.interfaceNodes]; cell.components.EnumerateIncreasing[WriteComponent]; cell.internalNodes.EnumerateIncreasing[DestroyNode]; } ELSE ctc.cellOut.PutRope["(InsidesUnspecified)\n"]; ctc.cellOut.Close[]; END; CellTypeFileName: PROC [dc: DesignCapture, cellType: CellType] RETURNS [cellFileName: ROPE] = { fullCellFileName: ROPE; cp: FS.ComponentPositions; cellFileName _ NIL; [fullCellFileName, cp, ] _ FS.ExpandName[cellType.name !FS.Error => CONTINUE]; IF fullCellFileName # NIL AND fullCellFileName.Substr[start: cp.base.start, len: cp.base.length].Equal[cellType.name] THEN RETURN [cellType.name.Cat[".sch"]]; cellFileName _ IO.PutFR["%g-%g.sch", IO.rope[dc.fileNameRoot], IO.card[dc.genCount _ dc.genCount + 1]]; }; WriteAssertions: PROC [assertions: Assertions, to: IO.STREAM] = BEGIN FOR assertions _ assertions, assertions.rest WHILE assertions # NIL DO AssertingIO.WriteAssn[to: to, assertion: assertions.first]; to.PutRope["\n"]; ENDLOOP; END; WritePorts: PROC [ct: CellType, to: IO.STREAM] = BEGIN dir: ROPE; other: Assertions; WritePort: PROC [type: NodeType, portName, ecName: ROPE] = { WITH type SELECT FROM ant: ArrayNodeType => { IF ecName # NIL THEN Log["undoable equivalence class (%g) for port %g of cell type %g", IO.refAny[ecName], IO.refAny[portName], IO.refAny[ct.name]]; FOR i: INTEGER IN [0 .. ant.length) DO WritePort[ant.element, Sub[portName, i], NIL]; ENDLOOP}; ant: AtomNodeType => { to.PutF["\n\t(%g (G D) (%g)", IO.refAny[portName], IO.rope[dir]]; IF (ecName # NIL) AND (NOT ecName.Equal[portName]) THEN to.PutF[" (EC \"Structure\" %g)", IO.refAny[ecName]]; FOR al: Assertions _ other, al.rest WHILE al # NIL DO to.PutChar[' ]; AssertingIO.WriteAssn[to, al.first]; ENDLOOP; to.PutRope[")"]; }; ENDCASE => ERROR}; to.PutRope["(Ports"]; FOR pi: CARDINAL IN [0 .. ct.ports.length) DO ec: ROPE _ NARROW[Asserting.FnVal[$EC, ct.ports[pi].other, LIST[NARROW["Structure", ROPE]]]]; dir _ IF ct.ports[pi].input THEN (IF ct.ports[pi].output THEN "BIDIR" ELSE "IN") ELSE IF ct.ports[pi].output THEN "OUT" ELSE ERROR; other _ Asserting.Filter[$EC, ct.ports[pi].other].notAbout; WritePort[ct.ports[pi].type, ct.ports[pi].name, ec]; ENDLOOP; to.PutRope[")\n"]; END; WritePortNets: PROC [ct: CellType, to: IO.STREAM, insideNodes: NodeS] = BEGIN WritePortNet: PROC [type: NodeType, portName: ROPE, node: REF ANY] = { WITH type SELECT FROM ant: ArrayNodeType => {l: LORA _ NARROW[node]; FOR i: INTEGER IN [0 .. ant.length) DO WritePortNet[ant.element, Sub[portName, i], l.first]; l _ l.rest; ENDLOOP; IF l # NIL THEN ERROR}; ant: AtomNodeType => to.PutF["(PN %g %g)\n", IO.refAny[portName], IO.refAny[Best[node].name]]; ENDCASE => ERROR}; FOR pi: CARDINAL IN [0 .. ct.ports.length) DO WritePortNet[ct.ports[pi].type, ct.ports[pi].name, Asserting.FnVal[fn: wireKey, from: insideNodes[pi].other]]; ENDLOOP; END; NodeInstance: PROC [erInstance: REF ANY, name: ROPE, type: NodeType, initialValue, initialValueFormat: ROPE _ NIL, initData: REF ANY _ NIL, other: Assertions _ NIL] RETURNS [node: Node] = BEGIN ctc: CTCapture _ NARROW[erInstance]; node _ NEW [NodeRep _ [ name: name, type: type, cellIn: ctc.cell, nextPerturbed: notInNodeList, nextAffected: notInNodeList, nextDelayed: notInNodeList, prevDelayed: notInNodeList, significances: designOnly, other: other]]; ctc.cell.internalNodes.Insert[node !OrderedSymbolTableRef.DuplicateKey => {Log["Duplicated Node name: %g", IO.rope[name]]; CONTINUE}]; node.other _ Asserting.AssertFn1[fn: wireKey, val: CreateWires[type, name], inAdditionTo: node.other]; END; CreateWires: PROC [type: NodeType, name: ROPE] RETURNS [ra: REF ANY] = BEGIN WITH type SELECT FROM ant: ArrayNodeType => { list: LORA _ NIL; FOR i: INTEGER DECREASING IN [0 .. ant.length) DO list _ CONS[CreateWires[ant.element, Sub[name, i]], list]; ENDLOOP; ra _ list}; ant: AtomNodeType => ra _ NEW [WireRep _ [name: name]]; ENDCASE => ERROR END; CellInstance: PROC [erInstance: REF ANY, instanceName, typeName, interfaceNodes: ROPE, other: Assertions _ NIL] RETURNS [cell: Cell] = BEGIN ctc: CTCapture _ NARROW[erInstance]; type: CellType _ RoseCreate.GetCellType[typeName]; IF type = NIL THEN Log["No such cell type as %g", IO.refAny[typeName]] ELSE { cell _ NEW [CellRep _ [ name: instanceName, type: type, parent: ctc.cell, internalNodes: OrderedSymbolTableRef.CreateTable[ RoseCreate.CompareNodes], components: OrderedSymbolTableRef.CreateTable[ RoseCreate.CompareComponents], interfaceNodes: NEW [NodeSR[type.ports.length]], substantiality: Shadow, expansion: Expand, other: other ]]; RoseCreate.FillInInterfaceNodes[cell, interfaceNodes]; ctc.cell.components.Insert[cell !OrderedSymbolTableRef.DuplicateKey => {Log["Duplicated Cell name: %g", IO.rope[instanceName]]; CONTINUE}]; }; END; Equivalence: PROC [erInstance: REF ANY, a, b: NodeExpression] = BEGIN aWires: LORA _ Flatten[[NIL, NIL], a].head; bWires: LORA _ Flatten[[NIL, NIL], b].head; IF (a = NIL) # (b = NIL) THEN ERROR; IF a = NIL THEN RETURN; DO IF (aWires = NIL) # (bWires = NIL) THEN ERROR; IF aWires = NIL THEN EXIT; MergeWires[aWires.first, bWires.first]; aWires _ aWires.rest; bWires _ bWires.rest; ENDLOOP; END; TList: TYPE = RECORD [head, tail: LORA]; Flatten: PROC [prefix: TList, ne: NodeExpression] RETURNS [wtl: TList] = { WITH ne SELECT FROM x: PrimaryNE => { wl: LORA _ GetNodeWires[x.node]; wtl _ TLCat[prefix, WLSelect[wl, x.selector]]; }; x: UnnamedConsNE => { wtl _ prefix; FOR elts: LIST OF PrimaryNE _ x.elts, elts.rest WHILE elts # NIL DO wtl _ Flatten[wtl, elts.first]; ENDLOOP; }; x: CatenateNE => { wtl _ prefix; FOR pieces: LIST OF NodeExpression _ x.pieces, pieces.rest WHILE pieces # NIL DO wtl _ Flatten[wtl, pieces.first]; ENDLOOP; }; ENDCASE => ERROR; }; GetNodeWires: PROC [n: Node] RETURNS [wl: LORA] = { ra: REF ANY _ Asserting.FnVal[fn: wireKey, from: n.other]; WITH ra SELECT FROM w: Wire => RETURN [LIST[w]]; x: LORA => RETURN [x]; ENDCASE => ERROR; }; WLSelect: PROC [wl: LORA, s: Selector] RETURNS [wtl: TList] = { WITH s SELECT FROM whole => { wtl _ [NIL, NIL]; FOR wl _ wl, wl.rest WHILE wl # NIL DO wtl _ TLAppend[wtl, wl.first]; ENDLOOP; }; number => { FOR i: INT IN [0 .. index) DO wl _ wl.rest; ENDLOOP; wl _ LIST[wl.first]; wtl _ [wl, wl]; }; range => { min, max: INT; IF up THEN {min _ first; max _ first + count - 1} ELSE {min _ first + 1 - count; max _ first}; FOR i: INT IN [0 .. min) DO wl _ wl.rest ENDLOOP; wtl _ [NIL, NIL]; FOR i: INT IN [min .. max) DO wtl _ TLAppend[wtl, wl.first]; wl _ wl.rest; ENDLOOP; }; ENDCASE => ERROR; }; TLAppend: PROC [wtl: TList, r: REF ANY] RETURNS [wul: TList] = { this: LORA _ LIST[r]; wul _ wtl; IF wul.tail # NIL THEN wul.tail.rest _ this ELSE wul.head _ this; wul.tail _ this; }; TLCat: PROC [a, b: TList] RETURNS [c: TList] = { IF a = [NIL, NIL] THEN RETURN [b]; IF b = [NIL, NIL] THEN RETURN [a]; c _ [a.head, b.tail]; a.tail.rest _ b.head; }; MergeWires: PROC [a, b: REF ANY] = { wa: Wire _ Best[a]; wb: Wire _ Best[b]; IF wa # wb THEN {wb.better _ wa; wa.worse _ CONS[wb, wa.worse]} ELSE ERROR; }; Best: PROC [ra: REF ANY] RETURNS [w: Wire] = {w _ NARROW[ra]; WHILE w.better # NIL DO w _ w.better ENDLOOP}; Sub: PROC [name: ROPE, i: INTEGER] RETURNS [s: ROPE] = { s _ name.Cat["[", Convert.RopeFromInt[i], "]"]}; Setup: PROC = { AssertingIO.SetWriter[capKey, AssertingIO.DontWrite]; }; Setup[]; END. [Indigo]3.0>Rosemary.df=>RoseCaptureImpl.Mesa Last Edited by: Spreitzer, May 8, 1985 3:19:11 pm PDT WITH assertions.first.first SELECT FROM a: ATOM => SELECT a FROM $Capture => LOOP; ENDCASE; ENDCASE => ERROR; to.PutF["%g\n", IO.refAny[assertions.first]]; Κ“– "cedar" style˜Jšœ7™7J™5J˜IcodešΟk œ"œ œ\˜”K˜šΠbxœœ˜Kšœ"œ œN˜„Kšœ˜—K˜Kšœœ ˜K˜Kš œœœœœœ˜K˜Kšœœœ˜+šœœœ˜!Kšœœ˜Kšœœ˜Kšœ œ˜K˜—K˜Kšœ œœ˜#šœœœ˜K˜Kšœ œ˜K˜ K˜—K˜Kšœœœ ˜Kš œ œœœœœ˜OKšœ œœœ˜K˜Kšœ œ˜Kšœ œ˜K˜Kšœœ ˜Kšœ œ ˜K˜šœœ˜/Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜šΟnœœ œœ˜CKš˜Kšœœœ#˜1Kšœ˜Kšœ˜—K˜šŸ œœœ*œ˜KKš˜Kšœœ˜ Kšœœ˜+Kšœœ$œ˜[Kšœ@˜@Kš œœœ!œœ˜_Kšœ"˜"K˜&Kšœ&œ˜=Kšœ(œ˜=Kšœ,œ ˜7Kšœ]œ˜sKšœKœ;˜ˆKšœ*œœ˜OKšœ!˜!K˜Kšœ˜—K˜šŸœœ*˜?Kš˜šœ œ ˜K˜NK˜Kšœœ˜ KšœK˜KKšœM˜MKšœœ!˜4Kšœ˜Kšœ˜Kšœ˜—š Ÿ œœœœœœ˜6šŸ œœ˜(šœœ œ˜2Kšœ œ˜=K˜ Kšœ˜ ——šŸ œœœœ˜Ešœœ˜šœœœ˜/šœœœ˜"K˜=Kšœ˜ ——šœ œ˜+šœ œœ˜Kšœ œ˜3šœ œœ˜Kšœ˜Kšœ˜Kšœ˜—šœ!œœ˜5Kšœ˜K˜-Kšœ˜—K˜K˜—Kšœ˜—Kšœœ˜——Kšœ œ˜Kšœœœ/˜9Kšœœ˜ KšœO˜OK˜—š Ÿ œœœœœœ˜8Kšœ œ˜Kšœœ˜ Kšœ"œœ˜/Kšœ œ˜ Kšœ œ˜Kš œ!œ œœœœ˜’Kšœ œœ˜Kšœœ˜Kšœ œ˜K˜—š Ÿœœœœœœ˜;š Ÿœœœœœ˜Ešœœœ˜šœœœ˜/šœœœ˜&Kšœ;˜;Kšœ˜Kšœ˜ ——šœ)˜)Kšœ"œœ˜JK˜—Kšœœ˜——Kšœ œ˜Kšœ œ˜Kšœœ˜ Kšœ,œœ˜Wšœœœ˜4KšœœœD˜NKšœG˜GKšœ˜—Kšœ˜šœ#œœ˜7K˜K˜-Kšœ˜—Kšœ˜šœ1˜;Kšœ œ˜Kšœ$˜+—Kšœœœ˜,Kšœœœœ˜$Kšœ œ˜Kšœœ˜Kšœ˜Kšœ˜Kšœ!œ˜%Kšœœœœ˜(Kšœœœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜Kšœ œ˜ K˜—Kšœœ"˜4šœœ˜&Kšœ˜Kšœ œ"˜-Kšœ ˜ Kšœ˜—KšœX˜XKšœ,œœ˜]Kšœ(œ˜BKšœ,œ ˜7Kšœ(œ˜=Kšœ]œ˜sKšœKœ;˜ˆKšœ"˜"K˜-K˜*šœ˜šœ˜šœœ˜4K˜ KšœS˜SKšœ˜—Kšœ3˜3Kšœ2˜2Kšœ:˜:Kšœ4˜4Kšœ4˜4K˜—Kšœ/˜3—K˜Kšœ˜—K˜šŸœœ)œœ˜_Kšœœ˜Kšœœ˜Kšœœ˜Kšœœœ œ˜NKš œœœYœœ˜žKšœœœœ&˜gK˜—K˜šŸœœœœ˜?Kš˜šœ*œœ˜FK˜;K˜šœœ™'šœœœ™Kšœ œ™Kšœ™—Kšœœ™—Kšœœ™-Kšœ˜—Kšœ˜—K˜šŸ œœœœ˜0Kš˜Kšœœ˜ K˜šŸ œœ$œ˜<šœœ˜šœ˜Kš œ œœDœœœ˜”šœœœ˜&Kšœ)œ˜.Kšœ˜ ——šœ˜Kšœœœ ˜AKš œ œœœœ#œ˜mšœ!œœ˜5K˜K˜$Kšœ˜—K˜K˜—Kšœœ˜——K˜šœœœ˜-Kš œœœ*œœœ˜]Kšœœœœœ œœœœœœ˜ƒKšœ;˜;Kšœ4˜4Kšœ˜—K˜Kšœ˜—K˜šŸ œœœœ˜GKš˜š Ÿ œœœœœ˜Fšœœ˜šœœœ˜.šœœœ˜&Kšœ5˜5K˜ Kšœ˜—Kšœœœœ˜—Kšœ-œœ˜^Kšœœ˜——šœœœ˜-šœ˜Kšœ˜Kšœ;˜;—Kšœ˜—Kšœ˜—K˜šŸ œœœœœ4œœ œœœœœ˜»Kš˜Kšœœ ˜$šœœ ˜K˜ K˜ K˜K˜K˜K˜K˜K˜K˜—Kšœkœœ˜†Kšœf˜fKšœ˜—K˜š Ÿ œœœœœœ˜FKš˜šœœ˜šœ˜Kšœœœ˜š œœ œœ˜1Kšœœ/˜:Kšœ˜—K˜ —šœ˜Kšœœ˜"—Kšœ˜—Kšœ˜—K˜šŸ œœœœ*œœœ˜†Kš˜Kšœœ ˜$K˜2šœ˜ Kšœ œ˜8šœ˜šœœ ˜Kšœ˜K˜ K˜KšœK˜KKšœM˜MKšœœ˜0Kšœ˜Kšœ˜K˜ K˜—Kšœ6˜6Kšœhœœ˜‹K˜——Kšœ˜—K˜šŸ œœœœ˜?Kš˜Kšœœ œœ ˜+Kšœœ œœ ˜+Kš œœ œœœ˜$Kšœœœœ˜š˜Kš œ œœœœ˜.Kšœ œœœ˜K˜'Kšœ˜Kšœ˜Kšœ˜—Kšœ˜—K˜Kšœœœœ˜(K˜šŸœœ%œ˜Jšœœ˜šœ˜Kšœœ˜ K˜.K˜—šœ˜K˜ š œœœœœ˜CK˜Kšœ˜—K˜—šœ˜K˜ š œ œœ(œ œ˜PKšœ!˜!Kšœ˜—K˜—Kšœœ˜—K˜—K˜šŸ œœ œœ˜3Kšœœœ/˜:šœœ˜Kšœ œœ˜Kšœœœ˜Kšœœ˜—K˜—K˜šŸœœœœ˜?šœœ˜˜ Kšœœœ˜šœœœ˜&Kšœ˜Kšœ˜—K˜—šœ ˜ šœœœ˜K˜ Kšœ˜—Kšœœ ˜K˜K˜—šœ ˜ Kšœ œ˜šœ˜Kšœ'˜+Kšœ(˜,—Kš œœœ œœ˜1Kšœœœ˜šœœœ˜Kšœ˜K˜ Kšœ˜—K˜—Kšœœ˜—K˜—K˜š Ÿœœœœœ˜@Kšœœœ˜K˜ Kšœ œœœ˜AKšœ˜K˜—K˜šŸœœœ˜0Kš œœœœœ˜"Kš œœœœœ˜"K˜K˜K˜—K˜šŸ œœœœ˜$Kšœ˜Kšœ˜šœ˜ Kšœœ˜4Kšœœ˜ —Kšœ˜—K˜š Ÿœœœœœœ˜=Kšœ œœœ˜.—K˜š Ÿœœœœœœ˜8K˜0—K˜šŸœœ˜Kšœ5˜5K˜—K˜K˜K˜Kšœ˜—…—7–K9