DIRECTORY Atom, CMosContacts, CD, CDCallSpecific, CDIO, CDLRUCache, CDOrient, CDInline, CDApplications, CMos, Rope, TokenIO; CMosContactsImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDCallSpecific, CDIO, CDLRUCache, CDOrient, CDInline, CDApplications, CMos, Rope, TokenIO EXPORTS CMosContacts = BEGIN OPEN CMos; lambda: CD.DesignNumber = CD.lambda; ContactType: TYPE = CMosContacts.ContactType; ContactPtr: TYPE = CMosContacts.ContactPtr; ContactRec: TYPE = CMosContacts.ContactRec; undef: CD.Level = CMosContacts.undef; wellSurround: CD.DesignNumber = CMos.wellSurround; butConSX: CD.DesignNumber = 4*lambda; butConSY: CD.DesignNumber = 6*lambda; difCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; polyCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; dsCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; butCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; burCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; mmCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont]; ToPosition: PROC [x: REF] RETURNS [p: CD.DesignPosition] = BEGIN IF x=NIL THEN p _ [0, lambda] ELSE WITH x SELECT FROM rp: REF CD.DesignPosition => p _ rp^; rn: REF CD.DesignNumber => p _ [0, rn^]; ENDCASE => p _ [0, 0]; END; Aequivalent: PROC[mySpecific, other: REF ANY] RETURNS [BOOL] = { WITH other SELECT FROM p2: ContactPtr => RETURN [NARROW[mySpecific, ContactPtr]^=p2^]; ENDCASE => RETURN [FALSE] }; NewCont: PROC [] RETURNS [CD.ObPtr] = { ob: CD.ObPtr _ NEW[CD.ObjectDefinition]; ob.specificRef _ NEW[ContactRec]; RETURN [ob] }; InsideRectWithSurround: PROC [ob: CD.ObPtr] RETURNS [CD.DesignRect] = BEGIN RETURN [CDInline.Extend[CDInline.RectAt[[0, 0], ob.size], -wellSurround]] END; ShowSelectedWithSurround: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.outLineProc[CDInline.Extend[CDOrient.RectAt[pos, aptr.ob.size, orient], -wellSurround], pr] END; HitInsideWithSurround: PROC [aptr: CD.ApplicationPtr, hitRect: CD.DesignRect] RETURNS [BOOL] = BEGIN RETURN [CDInline.Intersect[ CDInline.Extend[ CDApplications.ApplicationRect[aptr], -wellSurround], hitRect]] END; MatchContact: PROC [me: CD.ObPtr, r: CD.DesignRect, level: CD.Level, prim: BOOL, horz: BOOL] RETURNS [BOOL] = BEGIN IF level=me.level THEN RETURN [TRUE] ELSE { cp: ContactPtr = NARROW[me.specificRef]; RETURN [ SELECT cp.typ FROM burr => (level=CMos.pol), mDif => (level=CMos.met), difShort => FALSE, butt => (level=CMos.met OR level=CMos.pol), mPol => (level=CMos.met), mm2 => (level=CMos.met2), ENDCASE => FALSE ] } END; pForDifPolCon: REF CD.ObjectProcs = RegisterObjectType[$CMosContactDifAndPol]; pForWellDifPolCon: REF CD.ObjectProcs = RegisterObjectType[$CMosContactWellDifAndPol]; difpolRimWidth: CD.DesignNumber = lambda; CreateDifCon: PUBLIC PROC [l: CD.DesignNumber, difLev: CD.Level] RETURNS [CD.ObPtr] = BEGIN cob: CD.ObPtr ~ difCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; IF difLev=undef THEN difLev_ndif; l _ MAX[l, butConSX]; cp.typ _ mDif; cob.level _ difLev; IF difLev=CMos.pdif THEN { cob.p _ pForWellDifPolCon; cob.size _ [butConSX+2*wellSurround, l+2*wellSurround]; } ELSE { cob.p _ pForDifPolCon; cob.size _ [butConSX, l]; }; RETURN [difCache.ReplaceByAequivalent[cob]] END; CreatePolyCon: PUBLIC PROC [l: CD.DesignNumber] RETURNS [CD.ObPtr] = BEGIN cob: CD.ObPtr ~ polyCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; l _ MAX[l, butConSX]; cp.typ _ mPol; cob.p _ pForDifPolCon; cob.size _ [butConSX, l]; cob.level _ pol; RETURN [polyCache.ReplaceByAequivalent[cob]] END; LengthenPolyDif: CDCallSpecific.CallProc = BEGIN amount: CD.DesignPosition = ToPosition[x]; IF amount.y=0 OR amount.x#0 THEN done _ FALSE ELSE { new: CD.ObPtr; sur: INT = IF aptr.ob.level=CMos.pdif THEN 2*wellSurround ELSE 0; cp: ContactPtr = NARROW[aptr.ob.specificRef]; sz: CD.DesignPosition _ CDInline.SubPoints[CDInline.AddPoints[aptr.ob.size, amount], [sur, sur]]; IF sz.x<=0 OR sz.y<=0 THEN {done _ FALSE; RETURN}; IF aptr.ob.level=pol THEN new _ CreatePolyCon[sz.y] ELSE new _ CreateDifCon[sz.y, aptr.ob.level]; IF new#NIL THEN aptr.ob _ new ELSE done _ FALSE; repaintMe _ TRUE; } END; DefaultenPolyDif: CDCallSpecific.CallProc = BEGIN new: CD.ObPtr; cp: ContactPtr = NARROW[aptr.ob.specificRef]; IF aptr.ob.level=pol THEN new _ CreatePolyCon[4*lambda] ELSE new _ CreateDifCon[4*lambda, aptr.ob.level]; repaintMe _ TRUE; IF new#NIL THEN aptr.ob _ new ELSE done _ FALSE; END; ReadDifPolCon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN lev: CD.Level = CDIO.ReadLevel[]; IF lev=pol THEN RETURN [ CreatePolyCon[TokenIO.ReadInt[]] ] ELSE RETURN [ CreateDifCon[TokenIO.ReadInt[], lev] ] END; WriteDifPolCon: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN sur: INT = IF me.level=CMos.pdif THEN 2*wellSurround ELSE 0; CDIO.WriteLevel[me.level]; TokenIO.WriteInt[me.size.y-sur]; END; DrawDifPolCon: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN r: CD.DesignRect = CDOrient.RectAt[pos, aptr.ob.size, orient]; pr.drawRect[r, met, pr]; pr.drawRect[r, aptr.ob.level, pr]; pr.saveRect[CDInline.Extend[r, -difpolRimWidth], cut, pr]; END; DrawWellDifPolCon: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN r: CD.DesignRect = CDOrient.RectAt[pos, aptr.ob.size, orient]; inr: CD.DesignRect = CDInline.Extend[r, -wellSurround]; pr.drawRect[inr, met, pr]; pr.drawRect[inr, aptr.ob.level, pr]; pr.saveRect[CDInline.Extend[inr, -difpolRimWidth], cut, pr]; pr.drawRect[r, nwel, pr]; END; pForDifShorts: REF CD.ObjectProcs = RegisterObjectType[$CMosContactDifShort]; pForWellDifShorts: REF CD.ObjectProcs = RegisterObjectType[$CMosContactWellDifShort]; difShortRimWidth: CD.DesignNumber = lambda; CreateDifShortCon: PUBLIC PROC [difLev: CD.Level] RETURNS [CD.ObPtr] = BEGIN cob: CD.ObPtr ~ dsCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; IF difLev=undef THEN difLev _ ndif; cp.typ _ difShort; cob.level _ difLev; IF difLev=CMos.pdif THEN { cob.p _ pForWellDifShorts; cob.size _ [butConSX+2*wellSurround, 8*lambda+2*wellSurround] } ELSE IF difLev=CMos.ndif THEN { cob.p _ pForDifShorts; cob.size _ [butConSX, 8*lambda] } ELSE ERROR; RETURN [dsCache.ReplaceByAequivalent[cob]] END; ReadDifShortCon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN RETURN [ CreateDifShortCon[CDIO.ReadLevel[]] ] END; WriteDifShortCon: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN CDIO.WriteLevel[me.level]; END; DrawDifShortContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.saveRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size]; mr: CD.DesignRect = CDInline.Extend[r, -difShortRimWidth]; h: CD.DesignNumber = (r.y2-r.y1)/2; Draw[r, met]; Draw[[x1: r.x1, y1: r.y1, x2: r.x2, y2: r.y1+h], CMos.ndif]; Draw[[x1: r.x1, y1: r.y1+h, x2: r.x2, y2: r.y2], CMos.pwelCont]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y1, y2: mr.y1+2*lambda], cut]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y2-2*lambda, y2: mr.y2], cut]; END; DrawWellDifShortContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size]; inr: CD.DesignRect = CDInline.Extend[r, -wellSurround]; mr: CD.DesignRect = CDInline.Extend[inr, -difShortRimWidth]; h: CD.DesignNumber = (inr.y2-inr.y1)/2; Draw[inr, met]; Draw[[x1: inr.x1, y1: inr.y1, x2: inr.x2, y2: inr.y1+h], CMos.pdif]; Draw[[x1: inr.x1, y1: inr.y1+h, x2: inr.x2, y2: inr.y2], CMos.nwelCont]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y1, y2: mr.y1+2*lambda], cut]; Save[[x1: mr.x1, x2: mr.x2, y1: mr.y2-2*lambda, y2: mr.y2], cut]; Draw[[x1: r.x1, x2: r.x2, y1: r.y1, y2: r.y2-h], nwel]; END; -- But -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- pForButContact: REF CD.ObjectProcs = RegisterObjectType[$CMosContactBut]; pForWellButContact: REF CD.ObjectProcs = RegisterObjectType[$CMosContactWellBut]; CreateButCon: PUBLIC PROC [difLev: CD.Level] RETURNS [CD.ObPtr] = BEGIN cob: CD.ObPtr ~ butCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; cp.typ _ butt; IF difLev=undef THEN difLev_ndif; cob.level _ difLev; IF difLev=CMos.pdif THEN { cob.p _ pForWellButContact; cob.size _ [butConSX+2*wellSurround, butConSY+2*wellSurround]; } ELSE { cob.p _ pForButContact; cob.size _ [butConSX, butConSY]; }; RETURN [butCache.ReplaceByAequivalent[cob]] END; ReadButCon: CD.InternalReadProc --PROC [] RETURNS [ObPtr]-- = BEGIN RETURN [ CreateButCon[CDIO.ReadLevel[]] ] END; WriteButCon: CD.InternalWriteProc -- PROC [me: ObPtr] -- = BEGIN CDIO.WriteLevel[me.level]; END; DrawButContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.saveRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; rimWidth: CD.DesignNumber = lambda; polySize: CD.DesignNumber = aptr.ob.size.y/2; Draw[[0, 0, aptr.ob.size.x, aptr.ob.size.y], met]; Draw[[0, 0, aptr.ob.size.x, polySize], pol]; Draw[[0, polySize-lambda, aptr.ob.size.x, aptr.ob.size.y], aptr.ob.level]; Save[[rimWidth, rimWidth, aptr.ob.size.x-rimWidth, aptr.ob.size.y-rimWidth], cut]; END; DrawWellButContact: PROC [aptr: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Save: PROC[r: CD.DesignRect, l: CD.Level] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: aptr.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; rimWidth: CD.DesignNumber = lambda; r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size]; inr: CD.DesignRect = CDInline.Extend[r, -wellSurround]; polySize: CD.DesignNumber = (inr.y2-inr.y1)/2; Draw[inr, met]; Draw[[x1: inr.x1, y1: inr.y1, x2: inr.x2, y2: inr.y1+polySize], pol]; Draw[[x1: inr.x1, y1: inr.y1+polySize-lambda, x2: inr.x2, y2: inr.y2], aptr.ob.level]; Save[CDInline.Extend[inr, -rimWidth], cut]; Draw[r, nwel]; END; pForBurCon: REF CD.ObjectProcs = RegisterObjectType[$CMosBurContact]; pForWellBurCon: REF CD.ObjectProcs = RegisterObjectType[$CMosWellBurContact]; CreateBurCon: PUBLIC PROC [w, l: CD.DesignNumber, wex: CD.DesignNumber, lex: CD.DesignNumber, difLev: CD.Level] RETURNS [CD.ObPtr] = BEGIN burAct: CD.DesignNumber = 2*lambda; actWidth, xMargins: CD.DesignNumber; cob: CD.ObPtr ~ burCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; IF difLev=undef THEN difLev_ndif; wex _ MAX[0, wex]; lex _ MAX[0, lex]; xMargins _ burAct + (IF wex< burAct THEN MAX[wex+lambda, burAct] ELSE wex); actWidth _ MAX[2*lambda, w-xMargins]; w _ actWidth+xMargins; l _ MAX[l, (IF lex Rope.Concat["buried contact ", DescribeLevel[me.level]], mDif => Rope.Concat[DescribeLevel[me.level], " contact"], difShort => Rope.Concat["dif - short contact", DescribeLevel[me.level]], butt => Rope.Concat["butting contact ", DescribeLevel[me.level]], mPol => "contact poly", mm2 => "via", ENDCASE => "unknown contact" ] END; Init: PROC [] = BEGIN pForDifPolCon.drawMe _ DrawDifPolCon; pForDifPolCon.internalRead _ ReadDifPolCon; pForDifPolCon.internalWrite _ WriteDifPolCon; pForDifPolCon.describe _ Describe; pForDifPolCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForDifPolCon, LengthenPolyDif]; CDCallSpecific.Register[$Default, pForDifPolCon, DefaultenPolyDif]; pForWellDifPolCon.drawMe _ DrawWellDifPolCon; pForWellDifPolCon.insideRect _ InsideRectWithSurround; pForWellDifPolCon.showMeSelected _ ShowSelectedWithSurround; pForWellDifPolCon.hitInside _ HitInsideWithSurround; pForWellDifPolCon.internalRead _ ReadDifPolCon; pForWellDifPolCon.internalWrite _ WriteDifPolCon; pForWellDifPolCon.describe _ Describe; pForWellDifPolCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForWellDifPolCon, LengthenPolyDif]; CDCallSpecific.Register[$Default, pForWellDifPolCon, DefaultenPolyDif]; pForButContact.drawMe _ DrawButContact; pForButContact.internalRead _ ReadButCon; pForButContact.internalWrite _ WriteButCon; pForButContact.describe _ Describe; pForButContact.match _ MatchContact; pForWellButContact.drawMe _ DrawWellButContact; pForWellButContact.insideRect _ InsideRectWithSurround; pForWellButContact.hitInside _ HitInsideWithSurround; pForWellButContact.internalRead _ ReadButCon; pForWellButContact.internalWrite _ WriteButCon; pForWellButContact.describe _ Describe; pForWellButContact.match _ MatchContact; pForBurCon.drawMe _ DrawBurrCon; pForBurCon.internalRead _ ReadBurCon; pForBurCon.internalWrite _ WriteBurCon; pForBurCon.describe _ Describe; pForBurCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForBurCon, LengthenBur]; CDCallSpecific.Register[$ChangeExt, pForBurCon, ChangeExtensionBur]; CDCallSpecific.Register[$Default, pForBurCon, DefaultenBur]; pForWellBurCon.drawMe _ DrawWellBurrCon; pForWellBurCon.insideRect _ InsideRectWithSurround; pForWellBurCon.hitInside _ HitInsideWithSurround; pForWellBurCon.internalRead _ ReadBurCon; pForWellBurCon.internalWrite _ WriteBurCon; pForWellBurCon.describe _ Describe; pForWellBurCon.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForWellBurCon, LengthenBur]; CDCallSpecific.Register[$ChangeExt, pForWellBurCon, ChangeExtensionBur]; CDCallSpecific.Register[$Default, pForWellBurCon, DefaultenBur]; pForVia.drawMe _ DrawVia; pForVia.internalRead _ ReadVia; pForVia.internalWrite _ WriteVia; pForVia.describe _ Describe; pForVia.match _ MatchContact; CDCallSpecific.Register[$Lengthen, pForVia, LengthenVia]; CDCallSpecific.Register[$Default, pForVia, DefaultenVia]; pForDifShorts.drawMe _ DrawDifShortContact; pForDifShorts.internalRead _ ReadDifShortCon; pForDifShorts.internalWrite _ WriteDifShortCon; pForDifShorts.describe _ Describe; pForDifShorts.match _ MatchContact; pForWellDifShorts.drawMe _ DrawWellDifShortContact; pForWellDifShorts.insideRect _ InsideRectWithSurround; pForWellDifShorts.hitInside _ HitInsideWithSurround; pForWellDifShorts.internalRead _ ReadDifShortCon; pForWellDifShorts.internalWrite _ WriteDifShortCon; pForWellDifShorts.describe _ Describe; pForWellDifShorts.match _ MatchContact; END; Init[]; END. hCMosContactsImpl.mesa (part of Chipndale) by Christian Jacobi June 24, 1983 5:03 pm last edited Christian Jacobi December 14, 1983 3:08 pm --y field defaults to lambda, x field defaults to 0 --[0, 0] if not done -- Don't care about different diffusions and such -- Dif and Pol -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --connect diffusion with metal --connect poly with metal -- DifShort -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --uses outer stuff!! --uses outer stuff!! --uses outer stuff!! --uses outer stuff!! --connects metal with poly and diffusion --uses outer stuff!! --uses outer stuff!! --uses outer stuff!! --uses outer stuff!! -- Bur -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- connects diffusion with poly without accessing metal -- copied from chipmonk without understanding --uses outer stuff!! --uses outer stuff!! --copied from chipmonk without understanding --uses outer stuff!! --uses outer stuff!! --Mm -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --ignores wex and lex in chipmonk, why??? --connects two layers of metal --cp.wExt _ ; --cp.wExt _ ; --does not read specificRef !!!!!! -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Êâ˜Jšœ*™*Jšœ,™,Jšœ8™8J˜šÏk ˜ J˜J˜ Jšœ˜J˜J˜J˜ J˜ J˜ J˜J˜Jšœ˜Jšœ˜J˜—šÏbœœœ˜ Jšœd˜kJšœ˜—Jšœœ˜J˜Jšœœœ˜$Jšœ œ˜-Jšœ œ˜+Jšœ œ˜+Jšœœ˜%J˜Jšœœ"˜2Jšœ œ˜%Jšœ œ˜%J˜Jšœl˜lJšœm˜mJšœk˜kJšœl˜lJšœl˜lJšœk˜kJ˜š Ïn œœœœœ˜:Jšœ3™3Jšœ™Jš˜Jšœœœ˜šœœœ˜Jšœœœ˜%Jšœœœ˜(Jšœ˜—Jšœ˜—J˜š Ÿ œœœœœœ˜@šœœ˜Jšœœœ˜?Jšœœœ˜—J˜—J˜šŸœœœœ ˜'Jšœœ œœ˜(Jšœœ ˜!Jšœ˜ J˜—J˜š Ÿœœœœœ˜EJš˜JšœD˜JJšœ˜J˜—šŸœœœœ˜QJšœœœ ˜)Jš˜Jšœ^˜^Jšœ˜J˜—šŸœœœœ ˜NJšœœ˜Jš˜šœ˜˜J˜&Jšœ˜—J˜ —Jšœ˜—J˜š Ðbn žœ9œœœœ˜mJš˜Jšœ1™1Jšœœœœ˜$šœ˜Jšœœ˜(šœ˜šœ˜Jšœ˜Jšœ˜Jšœ œ˜Jšœœ˜+Jšœ˜Jšœ˜Jšœ˜—J˜—J˜—Jšœ˜—J˜Jšœc™cJ˜Jšœœ9˜NJšœœ=˜VJšœœ˜)J˜šŸ œœœœœœœ ˜UJšœ™Jš˜Jšœœ ˜'Jšœœ˜)Jšœœ˜"Jšœœ˜J˜J˜šœœ˜Jšœ˜J˜7J˜—šœ˜Jšœ˜J˜J˜—Jšœ%˜+Jšœ˜J˜—š Ÿ œœœœœœ ˜DJšœ™Jš˜Jšœœ!˜(Jšœœ˜)Jšœœ˜J˜Jšœ˜J˜J˜Jšœ&˜,Jšœ˜J˜—J˜šžœ˜*Jš˜Jšœœ ˜*Jšœ œ œ˜-šœ˜Jšœœ˜Jš œœœœœ˜BJšœœ˜-Jšœœ[˜aJš œ œ œœœ˜2Jšœœœ)˜aJš œœœœœ˜0Jšœ˜J˜—Jšœ˜J˜—šžœ˜+Jš˜Jšœœ˜Jšœœ˜-Jšœœœ-˜iJšœ œ˜Jš œœœœœ˜0Jšœ˜J˜—šŸ œœÏcœ˜@Jš˜Jšœœ œ ˜!Jšœ œœ%˜;Jšœœ)˜4Jšœ˜—J˜šŸœœ¡œ˜=Jš˜Jš œœœœœ˜=Jšœ˜Jšœ ˜ Jšœ˜—J˜š Ÿ œœœœœ ˜]Jšœœ ˜Jš˜Jšœœ?˜DJ˜Jšœ"˜"J˜:Jšœ˜J˜—š Ÿœœœœœ ˜aJšœœ ˜Jš˜Jšœœ9˜>Jšœœ1˜8J˜Jšœ$˜$J˜˜EJšœ œ˜Jš œœœœœ˜0Jšœ˜—J˜šŸœœ¡œ˜:Jš˜Jšœ)˜/Jšœ˜—J˜šŸœœ¡œ˜7Jš˜Jšœ˜Jšœ˜—J˜š Ÿœœœœœ ˜WJšœœ ˜Jšœ"™"Jš˜Jšœœ9˜>J˜J˜J˜7Jšœ˜J˜—JšœZ™ZJ˜š Ÿ œœœœœ˜6Jšœœœ˜)—J˜š Ÿœœœœœ˜2Jš˜Jšœœ˜(šœ˜šœ˜Jšœ@˜@Jšœ9˜9JšœH˜HJšœA˜AJšœ˜Jšœ ˜ Jšœ˜—J˜—Jšœ˜—J˜šŸœœ˜Jš˜Jšœ%˜%Jšœ+˜+Jšœ-˜-Jšœ"˜"Jšœ#˜#JšœC˜CJšœC˜CJ˜Jšœ-˜-Jšœ6˜6Jšœ<˜