DIRECTORY Basics, Convert, Rope, RTSets, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPrivate, SCPlaceUtil, SCSmash, SCWidthUtil, SCRowUtil, SCUtil, TerminalIO; SCPlaceImproveImpl: CEDAR PROGRAM IMPORTS Convert, Rope, SC, SCChanUtil, SCInstUtil, SCNetUtil, SCPlaceUtil, SCRowUtil, SCWidthUtil, SCSmash, SCUtil, TerminalIO EXPORTS SCPrivate SHARES SC = { debug: BOOLEAN _ FALSE; RowSpec: TYPE = RECORD[ row: SCPrivate.LgRow, doUpper, doLower: BOOLEAN]; PosResult: TYPE = RECORD[ area, channelWidth, wireLength: SC.Number, numFts: INT]; PlaceResult: TYPE = RECORD[ area, channelWidth, wireLength: SC.Number, numFts: INT]; WritePosResult: PROCEDURE [header: Rope.ROPE, Result: PosResult] = { -- write the results TerminalIO.PutRope[header]; TerminalIO.PutRope[Rope.Cat[" area: ", Convert.RopeFromInt[Result.area]]]; TerminalIO.PutRope[Rope.Cat[", channelWidth: ", Convert.RopeFromInt[Result.channelWidth]]]; TerminalIO.PutRope[Rope.Cat["\n wireLength: ", Convert.RopeFromInt[Result.wireLength]]]; TerminalIO.PutRope[Rope.Cat[", numFts: ", Convert.RopeFromInt[Result.numFts], "\n"]]}; ComparePosResult: PROCEDURE [result1, result2: PosResult] RETURNS [FirstRelationSecond: Basics.Comparison] = { IF result1.area < result2.area THEN FirstRelationSecond _ less ELSE IF result1.area > result2.area THEN FirstRelationSecond _ greater ELSE IF result1.channelWidth < result2.channelWidth THEN FirstRelationSecond _ less ELSE IF result1.channelWidth > result2.channelWidth THEN FirstRelationSecond _ greater ELSE IF result1.wireLength < result2.wireLength THEN FirstRelationSecond _ less ELSE IF result1.wireLength > result2.wireLength THEN FirstRelationSecond _ greater ELSE IF result1.numFts < result2.numFts THEN FirstRelationSecond _ less ELSE IF result1.numFts > result2.numFts THEN FirstRelationSecond _ greater ELSE FirstRelationSecond _ equal}; -- they are equal ComparePlaceResult: PROCEDURE [result1, result2: PlaceResult] RETURNS [FirstRelationSecond: Basics.Comparison] = BEGIN IF result1.area < result2.area THEN FirstRelationSecond _ less ELSE IF result1.area > result2.area THEN FirstRelationSecond _ greater ELSE IF result1.channelWidth < result2.channelWidth THEN FirstRelationSecond _ less ELSE IF result1.channelWidth > result2.channelWidth THEN FirstRelationSecond _ greater ELSE IF result1.wireLength < result2.wireLength THEN FirstRelationSecond _ less ELSE IF result1.wireLength > result2.wireLength THEN FirstRelationSecond _ greater ELSE IF result1.numFts < result2.numFts THEN FirstRelationSecond _ less ELSE IF result1.numFts > result2.numFts THEN FirstRelationSecond _ greater ELSE FirstRelationSecond _ equal; -- they are equal END; -- ComparePlaceResult DoWidths: PROCEDURE [handle: SC.Handle, doChanWidth: SCPrivate.ChanSet, doSideWidth: SCPrivate.LRSideSet, doRowWidth: SCPrivate.RowSet, fom: SCPrivate.FomType] RETURNS [wireLength: SC.Number _ 0] = { EachRow: SCRowUtil.EachRowProc = { IF doRowWidth[(row)-1] THEN SCInstUtil.LgOffsets[handle, row, 0, SCPrivate.maxPos]}; EachRowChan: SCChanUtil.EachRowChanProc = { IF doChanWidth[(chan )-1] THEN [rowChan.chanWidth, rowChan.wireLength] _ SCWidthUtil.GetChanWidth[handle, rowChan, fom, TRUE]; wireLength _ wireLength + layoutData.rowChans.chans[chan].wireLength}; EachSideChan: SCChanUtil.EachSideChanProc = { IF doSideWidth[LOOPHOLE[lrSide, INTEGER]] THEN { sideChan: SCPrivate.SideChan _ layoutData.sideChans[lrSide]; [sideChan.sideChanWidth, sideChan.wireLength] _ SCWidthUtil.GetSideWidth[handle, lrSide, fom]}; wireLength _ wireLength + sideChan.wireLength}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; [] _ SCChanUtil.EnumerateRowChans[handle, EachRowChan]; [] _ SCChanUtil.EnumerateSideChans[handle, EachSideChan]}; ChosRow: PROCEDURE[handle: SC.Handle, rowIndex: SCPrivate.ZMaxRowSr] RETURNS[rowSpec: RowSpec] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.ZMaxRowSr; doUpper, doLower: BOOLEAN; SELECT TRUE FROM layoutData.bpRows[top].fnlBpFxd AND layoutData.bpRows[bottom].fnlBpFxd => {IF (rowIndex MOD 2) # 0 THEN row _ (lgRows.count+1) /2 - (rowIndex-1) /2 ELSE row _ (lgRows.count+1) /2 + rowIndex /2; doUpper _ doLower _ TRUE}; layoutData.bpRows[top].fnlBpFxd => {row _ lgRows.count - rowIndex + 1; doUpper _ TRUE; doLower _ FALSE}; layoutData.bpRows[bottom].fnlBpFxd => {row _ rowIndex; doUpper _ FALSE; doLower _ TRUE}; ENDCASE => {IF (rowIndex MOD 2) # 0 THEN row _ (lgRows.count+1) /2 - (rowIndex-1) /2 ELSE row _ (lgRows.count+1) /2 + rowIndex /2; IF row = (lgRows.count+1) /2 THEN {doUpper _ TRUE; doLower _ TRUE} ELSE IF row < (lgRows.count+1) /2 THEN {doUpper _ TRUE; doLower _ row = 1} ELSE {doUpper _ row = lgRows.count; doLower _ TRUE}}; rowSpec _ [lgRows.rows[row], doLower, doUpper]}; PosImproveRow: PROCEDURE [handle: SC.Handle, rowSpec: RowSpec, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.MaxRowSr _ rowSpec.row.rowNum; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lowerChan: SCPrivate.RowChan _ rowChans.chans[row]; upperChan: SCPrivate.RowChan _ rowChans.chans[row+1]; numFts: INT _ structureData.instances.numFts; oldLowChWidth, oldUpChWidth, oldLowWireLength, oldUpWireLength: SC.Number; oldResult: PosResult; TrialInterchange: SCRowUtil.EachInstProc = { nextPos: SCPrivate.MaxPosSr _ pos + 1; lowChWidth, upChWidth, upWireLength, lowWireLength: SC.Number; newResult: PosResult; SCPlaceUtil.ExchPosRow[handle, pos, nextPos, row]; [lowChWidth, lowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower]; [upChWidth, upWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, rowSpec.doUpper]; newResult _ PosResult[(lowChWidth + upChWidth) * lgRows.maxRowWidth, (lowChWidth + upChWidth), (lowWireLength + upWireLength), numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.PutRope[" accept improvement\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal, greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ExchPosRow[handle, pos, nextPos, row]}; ENDCASE}; IF rowSpec.row.nLgsOnRow > 0 AND ~rowSpec.row.fnlLgFxd AND (rowSpec.doUpper OR rowSpec.doLower) THEN { TerminalIO.PutRope[Rope.Cat[" improve row ", Convert.RopeFromInt[row], ", "]]; [oldLowChWidth, oldLowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower]; [oldUpChWidth, oldUpWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, rowSpec.doUpper]; oldResult _ PosResult[(oldLowChWidth + oldUpChWidth) * lgRows.maxRowWidth, (oldLowChWidth + oldUpChWidth), (oldLowWireLength + oldUpWireLength), numFts]; IF debug THEN WritePosResult["\n original logic result: ", oldResult]; [] _ SCRowUtil.EnumerateInstsOnRow[handle, row, 1, MAX[0, rowSpec.row.nLgsOnRow-1], TrialInterchange]; TerminalIO.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; PosImproveLeftRight: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; sideChan: SCPrivate.SideChan _ layoutData.sideChans[side]; wireLength: SC.Number; oldResult: PlaceResult; TrialInterchange: SCRowUtil.EachInstProc = { doChanWidth: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty; doRowWidth: SCPrivate.ChanSet _ RTSets.RTMdSetEmpty; doSideWidth: SCPrivate.LRSideSet _ RTSets.RTSmSetEmpty; nextPos: SCPrivate.MaxPosSr _ pos +1; newWireLength: SC.Number; newResult: PlaceResult; nets: SCPrivate.NetList _ SCNetUtil.NetsOnInst[LIST[bpRow.bpsOnSide[pos], bpRow.bpsOnSide[nextPos]]]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RemoveNetsWFts[handle, nets, TRUE, doChanWidth, doSideWidth, doRowWidth]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.SmashNets[handle, nets, FALSE, doChanWidth, doSideWidth, doRowWidth]; newWireLength _ DoWidths[handle, doChanWidth, doSideWidth, doRowWidth, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]; newResult _ PlaceResult[layoutData.totWidth * layoutData.totHeight, layoutData.sideChans[side].sideChanWidth, newWireLength, structureData.instances.numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePlaceResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.PutRope[" accept improvement\n"]; wireLength _ newWireLength; oldResult _ newResult; goodExch _ goodExch + 1}; equal => { -- neutral exchange, take it IF debug THEN TerminalIO.PutRope[" accept neutral exchange\n"]; wireLength _ newWireLength; oldResult _ newResult}; greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RemoveNetsWFts[handle, nets, FALSE, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [doChanWidth, doSideWidth, doRowWidth] _ SCSmash.RestoreNetsWFts[handle, nets, doChanWidth, doSideWidth, doRowWidth]; wireLength _ DoWidths[handle, doChanWidth, doSideWidth, doRowWidth, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]}; ENDCASE}; IF ~ bpRow.fnlBpFxd THEN { TerminalIO.PutRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side, "]]; SCWidthUtil.AllChanWidths[handle, whichFom]; wireLength _ DoWidths[handle, RTSets.RTMdSetEmpty, RTSets.RTSmSetEmpty, RTSets.RTMdSetEmpty, whichFom]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCInstUtil.AsgnChanPos[handle]; oldResult _ PlaceResult[layoutData.totWidth * layoutData.totHeight, sideChan.sideChanWidth, wireLength, structureData.instances.numFts]; IF debug THEN WritePosResult[Rope.Cat["\n original ", SCRowUtil.sideName[side] ," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide -1], TrialInterchange]; TerminalIO.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]; SCWidthUtil.AllChanWidths[handle, areaFom]}}; PosImproveTopBot: PROCEDURE[handle: SC.Handle, side: SC.Side, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRow: SCPrivate.BpRow _ layoutData.bpRows[side]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; numFts: INT _ structureData.instances.numFts; oldChWidth, oldWireLength: SC.Number; oldResult: PosResult; chan: SCPrivate.RowChan _ SELECT side FROM top => rowChans.chans[rowChans.count], bottom => rowChans.chans[1], ENDCASE => SC.Error[programmingError, "Invalid side in Placement Improvement"]; TrialInterchange: SCRowUtil.EachInstProc = { nextPos: SCPrivate.MaxPosSr _ pos + 1; chWidth, wireLength: SC.Number; newResult: PosResult; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]; [chWidth, wireLength] _ SCWidthUtil.GetChanWidth[handle, chan, whichFom, TRUE]; newResult _ PosResult[chWidth * lgRows.maxRowWidth, chWidth, wireLength, numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.PutRope[" accept improvement\n"]; chan.chanWidth _ chWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal, greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ExchPosSide[handle, pos, nextPos, side]}; ENDCASE}; IF ~ bpRow.fnlBpFxd THEN { TerminalIO.PutRope[Rope.Cat[" improve ", SCRowUtil.sideName[side], " side, "]]; [oldChWidth, oldWireLength] _ SCWidthUtil.GetChanWidth[handle, chan, whichFom, TRUE]; oldResult _ PosResult[oldChWidth * lgRows.maxRowWidth, oldChWidth, oldWireLength, numFts]; IF debug THEN WritePosResult[Rope.Cat["\n original ", SCRowUtil.sideName[side]," result: "], oldResult]; [] _ SCRowUtil.EnumerateInstsOnSide[handle, side, 1, MAX[0, bpRow.nBpsOnSide-1], TrialInterchange]; TerminalIO.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; PosImprove: PUBLIC PROCEDURE [handle: SC.Handle, whichFom: SCPrivate.FomType, maxCycles: INT] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; bpRows: SCPrivate.BpRows _ layoutData.bpRows; startArea: SC.Number; numCycles: INT _ 0; stop: BOOLEAN _ FALSE; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; startArea _ SCUtil.WriteResults["Position improvement\n starting area:", handle, 0]; WHILE ~stop DO goodExch: INT _ 0; goodTopExch, goodBottomExch, goodRightExch, goodLeftExch: INT; EachRow: SCRowUtil.EachRowProc = { goodExch _ goodExch + PosImproveRow[handle, ChosRow[handle, row], whichFom]; quit _ stop}; IF numCycles >= maxCycles THEN EXIT; goodLeftExch _ PosImproveLeftRight[handle, left, whichFom]; goodRightExch _ PosImproveLeftRight[handle, right, whichFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; goodTopExch _ PosImproveTopBot[handle, top, whichFom]; goodBottomExch _ PosImproveTopBot[handle, bottom, whichFom]; IF goodExch + goodLeftExch + goodRightExch + goodTopExch + goodBottomExch <= 0 THEN EXIT; SCInstUtil.AsgnChanPos[handle]; numCycles _ numCycles + 1; ENDLOOP; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End position improvement\n ending area:", handle, startArea]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- PosImprove OrientImproveRow: PROCEDURE [handle: SC.Handle, rowSpec: RowSpec, whichFom: SCPrivate.FomType] RETURNS [goodExch: INT _ 0] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; row: SCPrivate.MaxRowSr _ rowSpec.row.rowNum; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lowerChan: SCPrivate.RowChan _ rowChans.chans[row]; upperChan: SCPrivate.RowChan _ rowChans.chans[row+1]; numFts: INT _ structureData.instances.numFts; oldLowChWidth, oldUpChWidth, oldLowWireLength, oldUpWireLength: SC.Number; oldResult: PosResult; TrialInterchange: SCRowUtil.EachInstProc = { lowChWidth, upChWidth, upWireLength, lowWireLength: SC.Number; newResult: PosResult; IF instance.fnlOrien = 0 THEN { SCPlaceUtil.ReverseOrientation[instance]; [lowChWidth, lowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower]; [upChWidth, upWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, rowSpec.doUpper]; newResult _ PosResult[(lowChWidth + upChWidth) * lgRows.maxRowWidth, (lowChWidth + upChWidth), (lowWireLength + upWireLength), numFts]; IF debug THEN WritePosResult[" trial result: ", newResult]; SELECT ComparePosResult[newResult, oldResult] FROM less => { -- strict improvement, thats good IF debug THEN TerminalIO.PutRope[" accept improvement\n"]; lowerChan.chanWidth _ lowChWidth; upperChan.chanWidth _ upChWidth; oldResult _ newResult; goodExch _ goodExch + 1}; equal, greater => { -- this change made it worse, restore old placement IF debug THEN WritePosResult[" restore old result: ", oldResult]; SCPlaceUtil.ReverseOrientation[instance]}; ENDCASE}}; IF rowSpec.row.nLgsOnRow > 0 AND (rowSpec.doUpper OR rowSpec.doLower) THEN { TerminalIO.PutRope[Rope.Cat[" improve orientation on row ", Convert.RopeFromInt[row], ", "]]; [oldLowChWidth, oldLowWireLength] _ SCWidthUtil.GetChanWidth[handle, lowerChan, whichFom, rowSpec.doLower]; [oldUpChWidth, oldUpWireLength] _ SCWidthUtil.GetChanWidth[handle, upperChan, whichFom, rowSpec.doUpper]; oldResult _ PosResult[(oldLowChWidth + oldUpChWidth) * lgRows.maxRowWidth, (oldLowChWidth + oldUpChWidth), (oldLowWireLength + oldUpWireLength), numFts]; IF debug THEN WritePosResult[" original result: ", oldResult]; [] _ SCRowUtil.EnumerateAllInstsOnRow[handle, row, TrialInterchange]; TerminalIO.PutRope[Rope.Cat[Convert.RopeFromInt[goodExch], " good exchanges\n"]]}}; OrientImprove: PUBLIC PROCEDURE [handle: SC.Handle, whichFom: SCPrivate.FomType, maxCycles: INT] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; startArea: SC.Number; numCycles: INT _ 0; stop: BOOLEAN _ FALSE; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; startArea _ SCUtil.WriteResults["Orientation improvement\n starting area:", handle, 0]; WHILE ~stop DO EachRow: SCRowUtil.EachRowProc = { goodExch _ OrientImproveRow[handle, ChosRow[handle, row], whichFom]; quit _ stop}; goodExch: INT _ 0; IF numCycles >= maxCycles THEN EXIT; SCInstUtil.AsgnChanPos[handle]; [] _ SCRowUtil.EnumerateRows[handle, EachRow]; IF goodExch <= 0 THEN EXIT; SCInstUtil.AsgnChanPos[handle]; numCycles _ numCycles + 1; ENDLOOP; SCInstUtil.AllOffsets[handle]; [lgRows.maxRowWidth, lgRows.numMaxRows] _ SCRowUtil.FindMaxRow[handle]; SCWidthUtil.AllChanWidths[handle, areaFom]; SCInstUtil.AsgnChanPos[handle]; [] _ SCUtil.WriteResults["End orientation improvement\n ending area:", handle, startArea]; IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; -- OrientImprove }. šfile: SCPlaceImproveImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. last edited: Bryan Preas December 21, 1986 4:15:03 pm PST map a row index in to a row improve positions on logic rows improve positions on bonding pad sides improve positions on bonding pad sides improve the left and right sides now improve the top and bottom sides improve orientation on logic rows Κί˜šœ™Icodešœ Οmœ6™AK™9—J˜šΟk ˜ Jšœžœžœs˜”J˜—šΟnœžœž˜!J˜Jšžœžœe˜~J˜Jšžœ ˜Jšžœžœ˜J˜Jšœžœžœ˜J˜šœ žœžœ˜Jšœ˜Jšœžœ˜J˜—šœ žœžœ˜Jšœ žœ˜*Jšœžœ˜ —J˜šœ žœžœ˜Jšœ žœ˜*Jšœžœ˜ —J˜š Ÿœž œžœŸœΟc˜YJšœ˜JšœL˜LJšœ[˜[Jšœ]˜]JšœV˜VJ˜—šŸœž œ˜9JšžœŸœ˜4šžœž˜#Jšœ˜—šžœžœž˜(Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ!ž˜,Jšœ˜—šžœžœ!ž˜,Jšœ˜—šž˜Jšœ ˜/——J˜šŸœž œ ˜=JšžœŸœ˜2J˜Jšž˜šžœž˜#Jšœ˜—šžœžœž˜(Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ-ž˜8Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ)ž˜4Jšœ˜—šžœžœ!ž˜,Jšœ˜—šžœžœ!ž˜,Jšœ˜—šž˜Jšœ ˜.—Jšžœ ˜J˜—šŸœž œ žœ˜'Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜Jšžœžœ˜'J˜šŸœ˜#Jšžœžœ9˜T—J˜šŸ œ!˜,šžœž˜JšœYžœ˜_—JšœF˜F—J˜šŸ œ!˜-šžœ žœ žœžœ˜0Jšœ<˜Jšœ˜J˜Jšœ2˜2Jšœe˜eJšœc˜cJšœ‡˜‡Jšžœžœ0˜=J˜šžœ(ž˜2šœ  "˜,Jšžœžœ/˜šŸœ˜#JšœL˜LJšœ ˜ —J˜šžœžœžœ˜$J˜—Jšœ!™!Jšœ;˜;Jšœ=˜=J˜Jšœ˜Jšœ.˜.J˜Jšœ%™%Jšœ6˜6Jšœ<˜Jšœ˜J˜šžœžœ˜Jšœ)˜)Jšœe˜eJšœc˜cJšœ‡˜‡Jšžœžœ0˜=J˜šžœ(ž˜2šœ  "˜,Jšžœžœ/˜