DIRECTORY CD, RTBasic, SC, SCChanUtil, SCNetUtil, SCPrivate, SCNewRoutePinsUtil, SCRowUtil, SCNewWidth, SCWidthUtil, SCInstUtil, TerminalIO, IO; SCNewWidthImpl: CEDAR PROGRAM IMPORTS RTBasic, SC, SCChanUtil, SCInstUtil, SCNewRoutePinsUtil, SCRowUtil EXPORTS SCNewWidth SHARES SC = BEGIN vertWireToAreaFact: SC.Number _ 3; horzWireToAreaFact: SC.Number _ 3; ChanNetList: TYPE = LIST OF SCNewRoutePinsUtil.ChanNetDat; GetChanWidth: PUBLIC PROCEDURE[handle: SC.Handle, rowChan: SCPrivate.RowChan, form: SCPrivate.FomType, doWidth: BOOLEAN] RETURNS [chanWidth, wireLength: SC.Number _ 0] = { -- lambda: SC.Number _ handle.rules.rowParms.technology.lambda; [chanWidth, wireLength] _ SetAuxiDS[handle, rowChan, form, doWidth]; -- TerminalIO.PutF[" Channel: %g, Width: %g, WireLength: %g\n", IO.int[rowChan.chanNum], IO.int[chanWidth/lambda], IO.int[wireLength/lambda]]; TermGetChanWidth[handle, rowChan]}; GetSideWidth: PUBLIC PROCEDURE[handle: SC.Handle, lRSide: SCPrivate.LRSide, fom: SCPrivate.FomType] RETURNS [chanWidth, wireLength: SC.Number _ 0] = {}; AllChanWidths: PUBLIC PROCEDURE[handle: SC.Handle, fom: SCPrivate.FomType] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; SideChan: SCChanUtil.EachSideChanProc = { [sideChan.sideChanWidth, sideChan.wireLength] _ GetSideWidth[handle, lrSide, fom]}; RowChan: SCChanUtil.EachRowChanProc = { [rowChan.chanWidth, rowChan.wireLength] _ GetChanWidth[handle, rowChan, fom, TRUE]}; [] _ SCChanUtil.EnumerateRowChans[handle, RowChan]; [] _ SCChanUtil.EnumerateSideChans[handle, SideChan]}; TermGetChanWidth: PUBLIC PROCEDURE[handle: SC.Handle, rowChan: SCPrivate.RowChan] = { InstProc: SCRowUtil.EachInstProc = { PinProc: SCInstUtil.EachPinProc = {netPin.pinInChan _ NIL}; [ ] _ SCInstUtil.EnumeratePinsOnInst[instance, PinProc]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; chanNum: NAT _ rowChan.chanNum; IF chanNum = 1 THEN { [] _ SCRowUtil.EnumerateAllInstsOnSide[handle, bottom, InstProc]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle,1, InstProc]} ELSE IF chanNum = layoutData.rowChans.count THEN { [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, layoutData.lgRows.count, InstProc]; [] _ SCRowUtil.EnumerateAllInstsOnSide[handle, top, InstProc]} ELSE { [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, chanNum - 1, InstProc]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, chanNum, InstProc]}; SCNewRoutePinsUtil.TermGetChanPins[handle, rowChan]; }; SetAuxiDS: PUBLIC PROCEDURE[handle: SC.Handle, rowChan: SCPrivate.RowChan, form: SCPrivate.FomType, doWidth: BOOLEAN] RETURNS[chanWidth, chanWL: SC.Number _ 0] = { pinsHead, pinsTail: SCNewRoutePinsUtil.PinInChan _ NIL; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; IF doWidth THEN { lgRows: SCPrivate.LgRows _ layoutData.lgRows; rowChans: SCPrivate.RowChans _ layoutData.rowChans; pitch: SC.Number _ handle.rules.rowRules.trunkToTrunk; SCNewRoutePinsUtil.InitGetChanPins[handle, rowChan]; IF rowChan.chanNum = 1 THEN { EnterSideData[rowChan, handle, bottom, top, bottom]; EnterRowData[rowChan, handle, 1, bottom]} ELSE IF rowChan.chanNum = rowChans.count THEN { EnterRowData[rowChan, handle, lgRows.count, top]; EnterSideData[rowChan, handle, top, bottom, top]} ELSE { EnterRowData[rowChan, handle, rowChan.chanNum-1, top]; EnterRowData[rowChan, handle, rowChan.chanNum, bottom]}; EnterExitData[handle, rowChan, left]; EnterExitData[handle, rowChan, right]; InitProcess[handle, rowChan]; chanWL _ rowChan.wireLength; IF form = wlFom THEN { chanWidth _ chanWL * pitch * horzWireToAreaFact / lgRows.maxRowWidth; rowChan.chanWidth _ chanWidth} ELSE { chanWidth _ 2*handle.rules.rowRules.trunkToEdge + pitch*(rowChan.chanDensity-1); rowChan.chanWidth _ chanWidth}}}; EnterRowData: PUBLIC PROCEDURE[rowChan: SCPrivate.RowChan, handle: SC.Handle, row: SCPrivate.MaxRowSr, interestingSide: SC.Side] = { InstProc: SCRowUtil.EachInstProc = { PinProc: SCInstUtil.EachPinProc = { IF netPin.pin # NIL AND netPin.net # NIL THEN { pd: SCInstUtil.PinDescription _ SCInstUtil.PosOf[instance, netPin.pin]; pinList: SCNewRoutePinsUtil.PinList _ NARROW[netPin.net.pinList]; IF pd.sideOn = interestingSide THEN { xPos: SC.Number _ instance.offset + lgRow.rowOrg.p + pd.xPos; tail: SCNewRoutePinsUtil.PinInChan _ SCNewRoutePinsUtil.EnterPin[rowChan, xPos, xPos, 0, netPin.pin.layer, netPin.net, RTBasic.OtherSide[interestingSide], FALSE]; netPin.pinInChan _ tail; pinList _ CONS[tail, pinList]; netPin.net.pinList _ pinList}}}; [ ] _ SCInstUtil.EnumeratePinsOnInst[instance, PinProc]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRow: SCPrivate.LgRow _ layoutData.lgRows.rows[row]; [ ] _ SCRowUtil.EnumerateAllInstsOnRow[handle, row, InstProc]}; EnterSideData: PUBLIC PROCEDURE[rowChan: SCPrivate.RowChan, handle: SC.Handle, side, interestingSide, chanSide: SC.Side] = { InstProc: SCRowUtil.EachInstProc = { PinProc: SCInstUtil.EachPinProc = { IF netPin.pin # NIL THEN { pd: SCInstUtil.PinDescription _ SCInstUtil.PosOf[instance, netPin.pin]; IF pd.sideOn = interestingSide AND netPin.net # NIL THEN { net: SCPrivate.Net _ netPin.net; IF net # NIL THEN { pinList: SCNewRoutePinsUtil.PinList _ NARROW[netPin.net.pinList]; pqPos: CD.Position _ SELECT side FROM bottom, top => [bpRow.sideOrg.p + instance.offset + pd.xPos, pd.yPos], left, right => [bpRow.sideOrg.q + instance.offset + pd.yPos, pd.xPos], ENDCASE => SC.Error[programmingError, "Not suppose to happen."]; tail: SCNewRoutePinsUtil.PinInChan _ SCNewRoutePinsUtil.EnterPin[rowChan, pqPos.x, pqPos.x, 0, netPin.pin.layer, netPin.net, chanSide, FALSE]; netPin.pinInChan _ tail; pinList _ CONS[tail, pinList]; netPin.net.pinList _ pinList}}}}; [ ] _ SCInstUtil.EnumeratePinsOnInst[instance, PinProc]}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; [ ] _ SCRowUtil.EnumerateAllInstsOnSide[handle, side, InstProc]}; EnterExitData: PUBLIC PROCEDURE[handle: SC.Handle, rowChan: SCPrivate.RowChan, lrSide: SCPrivate.LRSide] = { ExitProc: SCChanUtil.EachExitProc = { pos: SC.Number _ IF lrSide = left THEN lgRows.horzRowOrg ELSE lgRows.horzRowOrg + lgRows.maxRowWidth; pinList: SCNewRoutePinsUtil.PinList _ NARROW[exit.net.pinList]; tail: SCNewRoutePinsUtil.PinInChan _ SCNewRoutePinsUtil.EnterExit[rowChan, pos, exit.layer, exit.net, lrSide]; exit.pinInChan _ tail; pinList _ CONS[tail, pinList]; exit.net.pinList _ pinList}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; sideChan: SCPrivate.SideChan _ layoutData.sideChans[lrSide]; [] _ SCChanUtil.EnumerateExits[handle, rowChan, lrSide, ExitProc]}; OnThroughLine: PROCEDURE[pin: SCNewRoutePinsUtil.PinInChan] RETURNS [yes : BOOLEAN _ FALSE] = { oppEnd: SCNewRoutePinsUtil.ConnectionType; IF pin # NIL THEN { IF pin.pinConn = left THEN oppEnd _ right ELSE IF pin.pinConn = right THEN oppEnd _ left ELSE SC.Error[programmingError, "Invalid pin type"]; IF (pin.nextPinInChan # NIL) THEN IF(pin.nextPinInChan.net = pin.net) AND (pin.nextPinInChan.pinConn = oppEnd) AND (pin.nextPinInChan.min = pin.min) THEN yes _ TRUE; IF (pin.prevPinInChan # NIL) THEN IF (pin.prevPinInChan.net = pin.net) AND (pin.prevPinInChan.pinConn = oppEnd) AND (pin.prevPinInChan.min = pin.min) THEN yes _ TRUE}}; NetSpan: PROCEDURE[rightPin: SCNewRoutePinsUtil.PinInChan] RETURNS [length: SC.Number _ 0] = { leftPin: SCNewRoutePinsUtil.PinInChan _ rightPin; IF rightPin.pinConn # right THEN SC.Error[programmingError, "Not the end of a net span"] ELSE { WHILE leftPin.pinConn # left DO leftPin _ leftPin.prevPinInNet; ENDLOOP; length _ rightPin.min - leftPin.min}}; ComputeDW: PUBLIC PROCEDURE[ rowChan: SCPrivate.RowChan] RETURNS[density, wireLength: SC.Number _ 0] = { chanDat : SCNewRoutePinsUtil.ChanDat _ NARROW[rowChan.chanDat]; current: SCNewRoutePinsUtil.PinInChan _ chanDat.head; localD: SC.Number _ rowChan.numExits[left]; current _ current.nextPinInChan; WHILE (current # NIL) AND (current.pinClass = isExit) DO current.localDensity _ localD; current _ current.nextPinInChan; ENDLOOP; density _ localD; WHILE (current # NIL) AND (current.pinClass = isPin) DO [localD, density, wireLength] _ DensityAtAPin[current, localD, density, wireLength]; current _ current.nextPinInChan; ENDLOOP; WHILE (current # NIL) AND (current.pinClass = isExit) DO current.localDensity _ localD; current _ current.nextPinInChan; ENDLOOP}; DensityAtAPin: PROCEDURE[current: SCNewRoutePinsUtil.PinInChan, localD, density, wireLength: SC.Number] RETURNS[newLocalD, newDensity, newWireLength: SC.Number _ 0] = { pinConn: SCNewRoutePinsUtil.ConnectionType _ current.pinConn; IF (pinConn = interior) OR (pinConn = unconnected) THEN { IF (current.nextPinInChan # NIL) AND (current.nextPinInChan.pinConn = left) AND (current.nextPinInChan.min = current.min) THEN current.localDensity _ localD + 1 ELSE IF (current.prevPinInChan # NIL) AND (current.prevPinInChan.pinConn = right) AND (current.min = current.prevPinInChan.min) THEN current.localDensity _ localD + 1 ELSE current.localDensity _ localD} ELSE IF pinConn = left THEN { IF OnThroughLine[current] -- a through line THEN current.localDensity _ localD ELSE { localD _ localD + 1; current.localDensity _ localD; IF (current.nextPinInChan # NIL) AND (current.nextPinInChan.pinConn = left) AND (current.nextPinInChan.min = current.min) THEN current.localDensity _ current.localDensity + 1; IF (current.prevPinInChan # NIL) AND (current.prevPinInChan.pinConn = right) AND (current.min = current.prevPinInChan.min) THEN current.localDensity _ current.localDensity + 1; density _ MAX[density, current.localDensity]}} ELSE -- pinConn = right IF OnThroughLine[current] THEN current.localDensity _ localD ELSE { current.localDensity _ localD; IF (current.prevPinInChan # NIL) AND (current.prevPinInChan.pinConn = right) AND (current.min = current.prevPinInChan.min) THEN current.localDensity _ current.localDensity + 1; IF (current.nextPinInChan # NIL) AND (current.nextPinInChan.pinConn = left) AND (current.nextPinInChan.min = current.min) THEN current.localDensity _ current.localDensity + 1; localD _ localD - 1; IF localD < 0 THEN SC.Error[programmingError, "Invalid net segment"]; wireLength _ wireLength + NetSpan[current]}; newLocalD _ localD; newWireLength _ wireLength; newDensity _ density}; InitProcess: PROCEDURE[handle: SC.Handle, rowChan: SCPrivate.RowChan] = { SCNewRoutePinsUtil.CreateNetDat[handle, rowChan]; SCNewRoutePinsUtil.EnterAllNetSegInChan[handle, rowChan, NIL, NIL]; [rowChan.chanDensity, rowChan.wireLength] _ ComputeDW[rowChan]}; SwapPinsInChanOnTwoInsts: PUBLIC PROCEDURE[handle: SC.Handle, instance1, instance2: SCPrivate.Instance, deltaX1, deltaX2: SC.Number, side: RTBasic.Side, chanNum: NAT, whichFom: SCPrivate.FomType] = { MovePinsInChanOnInst: PROCEDURE[instance: SCPrivate.Instance, deltaX: SC.Number, side: RTBasic.Side ] = { AddChanNetList: PROCEDURE[chanNetList: ChanNetList, chanNetDat: SCNewRoutePinsUtil.ChanNetDat] RETURNS [newList: ChanNetList] = { rList: ChanNetList _ NIL; FOR rList _ chanNetList, rList.rest WHILE (rList # NIL) AND (rList.first # chanNetDat) DO ENDLOOP; IF rList = NIL THEN newList _ CONS[chanNetDat, chanNetList] ELSE newList _ chanNetList}; FOR pinNum: NAT IN [0 .. instance.pinNets.size) DO IF instance.pinNets.n[pinNum].net # NIL THEN { pin: SCNewRoutePinsUtil.PinInChan _ NARROW[instance.pinNets.n[pinNum].pinInChan]; IF (pin # NIL) AND (pin.chanSide = RTBasic.OtherSide[side]) THEN { IF (pin.prevPinInChan # NIL) AND (pin.prevPinInChan.min < leftBound) THEN { leftBound _ pin.prevPinInChan.min; leftPin _ pin.prevPinInChan}; IF (pin.nextPinInChan # NIL) AND (pin.nextPinInChan.min > rightBound) THEN { rightBound _ pin.nextPinInChan.min; rightPin _ pin.nextPinInChan}; scan _ SCNewRoutePinsUtil.MoveAPinInChan[rowChan, pin, deltaX] OR scan; IF (pin.prevPinInChan # NIL) AND (pin.prevPinInChan.min < leftBound) THEN { leftBound _ pin.prevPinInChan.min; leftPin _ pin.prevPinInChan}; IF (pin.nextPinInChan # NIL) AND (pin.nextPinInChan.min > rightBound) THEN { rightBound _ pin.nextPinInChan.min; rightPin _ pin.nextPinInChan}; IF (pin.net.routeTopology[chanNum].upper # full) OR (pin.net.routeTopology[chanNum].lower # full) THEN chanNetList _ AddChanNetList[chanNetList, pin.chanNet]}}; ENDLOOP}; UpdateNetsInChan: PROCEDURE[rowChan: SCPrivate.RowChan, chanNetList: ChanNetList] = { UpdateANetInChan: PROCEDURE[chanNet: SCNewRoutePinsUtil.ChanNetDat] = { EquiNetSeg: PROCEDURE[old, new: SCNewRoutePinsUtil.ChanNetDatRec] RETURNS[yes: BOOLEAN _ FALSE] = { IF (old.leftmost = NIL) AND (new.leftmost = NIL) THEN yes _ TRUE ELSE IF (old.leftmost = new.leftmost) AND (old.rightmost = new.rightmost) THEN yes _ TRUE ELSE yes _ FALSE}; DeleteWire: PROCEDURE[left, right: SCNewRoutePinsUtil.PinInChan] = { current: SCNewRoutePinsUtil.PinInChan _ left; length: SC.Number; length _ right.min - left.min; DO IF current.localDensity = rowChan.chanDensity THEN scan _ TRUE; current.localDensity _ current.localDensity - 1; IF current = right THEN EXIT ELSE current _ current.nextPinInChan; ENDLOOP; IF (left.prevPinInChan # NIL) AND (left.prevPinInChan.min = left.min) THEN left.prevPinInChan.localDensity _ left.prevPinInChan.localDensity - 1; IF (right.nextPinInChan # NIL) AND (right.nextPinInChan.min = right.min) THEN right.nextPinInChan.localDensity _ right.nextPinInChan.localDensity - 1; rowChan.wireLength _ rowChan.wireLength - length}; AddWire: PROCEDURE[left, right: SCNewRoutePinsUtil.PinInChan] = { current: SCNewRoutePinsUtil.PinInChan _ left; length: SC.Number; length _ right.min - left.min; IF (left.prevPinInChan # NIL) AND (left.prevPinInChan.min = left.min) THEN left.prevPinInChan.localDensity _ left.prevPinInChan.localDensity + 1; DO current.localDensity _ current.localDensity + 1; rowChan.chanDensity _ MAX[rowChan.chanDensity, current.localDensity]; IF current = right THEN EXIT ELSE current _ current.nextPinInChan; ENDLOOP; IF (right.nextPinInChan # NIL) AND (right.nextPinInChan.min = right.min) THEN right.nextPinInChan.localDensity _ right.nextPinInChan.localDensity + 1; rowChan.wireLength _ rowChan.wireLength + length}; oldChanNetRec, newChanNetRec: SCNewRoutePinsUtil.ChanNetDatRec _ chanNet^; SCNewRoutePinsUtil.EnterANetSegInChan[handle, rowChan, chanNet.net, NIL, NIL]; newChanNetRec _ chanNet^; IF ~ EquiNetSeg[oldChanNetRec, newChanNetRec] THEN { DeleteWire[oldChanNetRec.leftmost, oldChanNetRec.rightmost]; AddWire[newChanNetRec.leftmost, newChanNetRec.rightmost]}}; FOR rList: ChanNetList _ chanNetList , rList.rest WHILE rList # NIL DO chanNet: SCNewRoutePinsUtil.ChanNetDat _ rList.first; UpdateANetInChan[chanNet]; ENDLOOP}; ChanScan: PROCEDURE[chanRow: SCPrivate.RowChan] RETURNS[density: SC.Number _ 0] = { chanDat : SCNewRoutePinsUtil.ChanDat _ NARROW[rowChan.chanDat]; pin: SCNewRoutePinsUtil.PinInChan _ chanDat.head.nextPinInChan; WHILE pin # NIL DO density _ MAX[density, pin.localDensity]; pin _ pin.nextPinInChan; ENDLOOP}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; pitch: SC.Number _ handle.rules.rowRules.trunkToTrunk; rowChans: SCPrivate.RowChans _ layoutData.rowChans; rowChan: SCPrivate.RowChan _ rowChans.chans[chanNum]; chanNetList: ChanNetList _ NIL; scan: BOOLEAN _ FALSE; current, leftPin, rightPin: SCNewRoutePinsUtil.PinInChan_ NIL; leftBound: SC.Number _ LAST[INT]; rightBound: SC.Number _ FIRST[INT]; localD, density, dummy: SC.Number _ 0; MovePinsInChanOnInst[instance1, deltaX1, side]; MovePinsInChanOnInst[instance2, deltaX2, side]; IF leftPin.pinConn = right THEN IF (leftPin.prevPinInChan # NIL) AND (leftPin.prevPinInChan.min = leftPin.min) AND (leftPin.prevPinInChan.pinConn = right) THEN localD _ leftPin.localDensity - 2 ELSE localD _ leftPin.localDensity - 1 ELSE IF (leftPin.prevPinInChan # NIL) AND (leftPin.prevPinInChan.min = leftPin.min) AND (leftPin.prevPinInChan.pinConn = right) THEN localD _ leftPin.localDensity - 1 ELSE localD _ leftPin.localDensity; current _ leftPin.nextPinInChan; WHILE current # rightPin DO [localD, density, dummy] _ DensityAtAPin[current, localD, density, dummy]; current _ current.nextPinInChan; ENDLOOP; UpdateNetsInChan[rowChan, chanNetList]; IF scan AND (density < rowChan.chanDensity) THEN rowChan.chanDensity _ ChanScan[rowChan] ELSE rowChan.chanDensity_ MAX[ rowChan.chanDensity, density]; IF whichFom = wlFom THEN rowChan.chanWidth _ rowChan.wireLength * pitch * horzWireToAreaFact / layoutData.lgRows.maxRowWidth ELSE rowChan.chanWidth _ 2*handle.rules.rowRules.trunkToEdge + pitch*(rowChan.chanDensity-1)}; END. ŒSCNewWidthImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Jason Cong, August 23, 1987 6:26:49 pm PDT get width of channel on side ind widths of all channels assemble data for pins on this channel enter routing data for one side of one side into data base EachInstProc: TYPE = PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL _ FALSE]; EachPinProc: TYPE = PROC [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] RETURNS [quit: BOOL _ FALSE]; enter routing data for one side of one side into data base side is the side of the chip the the io row is on intrestingSide is the side of the cell that the pin is on chanSide is the side of the channel the pin is on enter exit data for a channel into routing data structure EachExitProc: TYPE = PROC [exitNum: SCPrivate.MaxExitsSr, lrSide: SCPrivate.LRSide, rowChan: SCPrivate.RowChan, exit: SCPrivate.Exit] RETURNS [quit: BOOL _ FALSE]; Main body of InitProcess. 'side' is the side of the instance those pins on. Main Body of MovePinsOnInst main body of 'UpdateANetInChan' main body of 'UpdateNetsInChan' main body of 'SwapPinsInChanOnTwoInsts' Κ»˜codešœ™Kšœ<™—šœ˜K˜EK˜B—Kšœ5˜5Kšœ˜K˜K˜—šž œœ œ œIœœœ˜₯K˜Kšœ3œ˜7Kšœ#œ˜=šœ œ˜Kšœ-˜-Kšœ3˜3Kšœœ-˜6K˜Kšœ4˜4K˜Kšœ'™'šœœ˜Kšœ4˜4Kšœ)˜)—šœœ"œ˜/Kšœ1˜1Kšœ1˜1—šœ˜Kšœ6˜6Kšœ8˜8—Kšœ%˜%Kšœ&˜&K˜K˜šœœ˜KšœE˜EKšœ˜—šœ˜KšœP˜PK˜!—K˜—K˜—šž œœ&œ3œ ˜†Kšœ;™;K˜K˜šžœ˜$Kš œœœœ œœœ™`šžœ˜#Kš œ œœ%œœœœ™yš œœœœœ˜0KšœG˜GKšœ&œ˜Ašœœ˜%Kšœœ6˜>Kšœ€˜€J˜Kšœ˜Kšœ ˜ ——K˜—Kšœ9˜9K˜—K˜Kšœ#œ˜=Kšœ5˜5Kšœ@˜@—K˜Kšœ;™;šž œœ%œ*œ ˜|Kšœ1™1Kšœ9™9Kšœ1™1K™šžœ˜$šžœ˜#šœœœ˜KšœG˜Gšœœœœ˜:Kšœ ˜ šœœœ˜Kšœ&œ˜Ašœœ œœ˜&KšœF˜FKšœF˜FKšœœ3˜@—Kšœ˜J˜Kšœ˜Kšœ!˜!———K˜—Kšœ9˜9K˜—Kšœ#œ˜=Kšœ1˜1KšœA˜AK˜—Kšœ:™:šž œœ œC˜mK˜šžœ˜%Kš œœœmœœœ™£K˜Kš œœ œœœ(˜eKšœ&œ˜?Kšœn˜nKšœ˜Kšœ˜Kšœ˜K˜—Kšœ#œ˜=K˜-Kšœ<˜Kšœ œ œœ˜!Kšœ œ œœ˜#Kšœœ ˜&K˜K˜/K˜/šœ˜š œœœ+œ)˜K˜!—Kšœ"˜&—š œœœœ+œ)œ˜…K˜!—Kšœ˜#K˜ šœ˜K˜JK˜ Kšœ˜—Kšœ'˜'šœ*œ˜2K˜'—Kšœœ ˜=šœœ˜Kšœc˜c—šœ˜KšœY˜Y—K˜—šœ˜˜K˜K˜K™K˜———…—@θT/