DIRECTORY Atom, CMosCMContacts, CMosObjects, CD, CDBasics, CDCallSpecific, CDIO, CDLRUCache, CDOrient, CDRects USING [CreateRect], CDStretchyExtras, CMos, Rope, TokenIO; CMosCMContactsImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDCallSpecific, CDIO, CDLRUCache, CDOrient, CDStretchyExtras, CDRects, CMos, Rope, TokenIO, CMosObjects EXPORTS CMosCMContacts = BEGIN OPEN CMos; lambda: CD.Number = CMos.lambda; ContactType: TYPE = CMosCMContacts.ContactType; ContactPtr: TYPE = CMosCMContacts.ContactPtr; ContactRec: TYPE = CMosCMContacts.ContactRec; undef: CD.Layer = CMosCMContacts.undef; wellSurround: CD.Number = CMos.wellSurround; 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 [class: CD.Position] = BEGIN IF x=NIL THEN class _ [0, lambda] ELSE WITH x SELECT FROM rp: REF CD.Position => class _ rp^; rn: REF CD.Number => class _ [0, rn^]; ENDCASE => class _ [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.Object] = { ob: CD.Object _ NEW[CD.ObjectRep]; ob.specificRef _ NEW[ContactRec]; RETURN [ob] }; InsideRectWithSurround: PROC [ob: CD.Object] RETURNS [CD.Rect] = BEGIN RETURN [CDBasics.Extend[CDBasics.RectAt[[0, 0], ob.size], -wellSurround]] END; ShowSelectedWithSurround: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.drawOutLine[CDBasics.Extend[CDOrient.RectAt[pos, inst.ob.size, orient], -wellSurround], CD.selectionLayer, pr] END; MatchContact: PROC [me: CD.Object, r: CD.Rect, layer: CD.Layer, prim: BOOL, horz: BOOL] RETURNS [BOOL] = BEGIN IF layer=me.layer THEN RETURN [TRUE] ELSE { cp: ContactPtr = NARROW[me.specificRef]; RETURN [ SELECT cp.typ FROM burr => (layer=CMos.pol), mDif => (layer=CMos.met), difShort => FALSE, butt => (layer=CMos.met OR layer=CMos.pol), mPol => (layer=CMos.met), mm2 => (layer=CMos.met2), ENDCASE => FALSE ] } END; pForDifPolCon: CD.ObjectClass = RegisterObjectClass[$CMosContactDifAndPol]; pForWellDifPolCon: CD.ObjectClass = RegisterObjectClass[$CMosContactWellDifAndPol]; difpolRimWidth: CD.Number = lambda; CreateDifCon: PUBLIC PROC [l: CD.Number, difLev: CD.Layer] RETURNS [CD.Object] = BEGIN cob: CD.Object ~ difCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; IF difLev=undef THEN difLev_ndif; IF l=butConSX THEN { IF difLev=CMos.pdif THEN difLev _ CMos.wpdif; IF difLev=CMos.pol THEN RETURN [CMosObjects.CreatePolyCon[]] ELSE RETURN [CMosObjects.CreateDifCon[difLev]] }; l _ MAX[l, butConSX]; cp.typ _ mDif; cob.layer _ difLev; IF difLev=CMos.pdif THEN { cob.class _ pForWellDifPolCon; cob.size _ [butConSX+2*wellSurround, l+2*wellSurround]; } ELSE { cob.class _ pForDifPolCon; cob.size _ [butConSX, l]; }; RETURN [difCache.ReplaceByAequivalent[cob]] END; CreatePolyCon: PUBLIC PROC [l: CD.Number] RETURNS [CD.Object] = BEGIN cob: CD.Object ~ polyCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; IF l=butConSX THEN { RETURN [CMosObjects.CreatePolyCon[]] }; l _ MAX[l, butConSX]; cp.typ _ mPol; cob.class _ pForDifPolCon; cob.size _ [butConSX, l]; cob.layer _ pol; RETURN [polyCache.ReplaceByAequivalent[cob]] END; LengthenPolyDif: CDCallSpecific.CallProc = BEGIN amount: CD.Position = ToPosition[x]; IF amount.y=0 OR amount.x#0 THEN done _ FALSE ELSE { new: CD.Object; sur: INT = IF inst.ob.layer=CMos.pdif THEN 2*wellSurround ELSE 0; cp: ContactPtr = NARROW[inst.ob.specificRef]; sz: CD.Position _ CDBasics.SubPoints[CDBasics.AddPoints[inst.ob.size, amount], [sur, sur]]; IF sz.x<=0 OR sz.y<=0 THEN {done _ FALSE; RETURN}; IF inst.ob.layer=pol THEN new _ CreatePolyCon[sz.y] ELSE new _ CreateDifCon[sz.y, inst.ob.layer]; IF new#NIL THEN inst.ob _ new ELSE done _ FALSE; repaintMe _ TRUE; } END; DefaultenPolyDif: CDCallSpecific.CallProc = BEGIN new: CD.Object; cp: ContactPtr = NARROW[inst.ob.specificRef]; IF inst.ob.layer=pol THEN new _ CreatePolyCon[4*lambda] ELSE new _ CreateDifCon[4*lambda, inst.ob.layer]; repaintMe _ TRUE; IF new#NIL THEN inst.ob _ new ELSE done _ FALSE; END; ReadDifPolCon: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN lev: CD.Layer = CDIO.ReadLayer[]; IF lev=pol THEN RETURN [ CreatePolyCon[TokenIO.ReadInt[]] ] ELSE RETURN [ CreateDifCon[TokenIO.ReadInt[], lev] ] END; WriteDifPolCon: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN sur: INT = IF me.layer=CMos.pdif THEN 2*wellSurround ELSE 0; CDIO.WriteLayer[me.layer]; TokenIO.WriteInt[me.size.y-sur]; END; DrawDifPolCon: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN r: CD.Rect = CDOrient.RectAt[pos, inst.ob.size, orient]; pr.drawRect[r, met, pr]; pr.drawRect[r, inst.ob.layer, pr]; pr.drawRect[CDBasics.Extend[r, -difpolRimWidth], cut, pr]; END; DrawWellDifPolCon: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN r: CD.Rect = CDOrient.RectAt[pos, inst.ob.size, orient]; inr: CD.Rect = CDBasics.Extend[r, -wellSurround]; pr.drawRect[inr, met, pr]; pr.drawRect[inr, inst.ob.layer, pr]; pr.drawRect[CDBasics.Extend[inr, -difpolRimWidth], cut, pr]; pr.drawRect[r, nwell, pr]; END; pForDifShorts: CD.ObjectClass = RegisterObjectClass[$CMosContactDifShort]; pForWellDifShorts: CD.ObjectClass = RegisterObjectClass[$CMosContactWellDifShort]; difShortRimWidth: CD.Number = lambda; CreateDifShortCon: PUBLIC PROC [difLev: CD.Layer] RETURNS [CD.Object] = BEGIN IF difLev=CMos.pdif THEN difLev _ CMos.wpdif; RETURN [CMosObjects.CreateDifShortCon[difLev]] END; ReadDifShortCon: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN RETURN [ CreateDifShortCon[CDIO.ReadLayer[]] ] END; WriteDifShortCon: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN CDIO.WriteLayer[me.layer]; END; DrawDifShortContact: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.Rect, l: CD.Layer] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; r: CD.Rect = CDOrient.RectAt[[0, 0], inst.ob.size]; mr: CD.Rect = CDBasics.Extend[r, -difShortRimWidth]; h: CD.Number = (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.pwellCont]; Draw[[x1: mr.x1, x2: mr.x2, y1: mr.y1, y2: mr.y1+2*lambda], cut]; Draw[[x1: mr.x1, x2: mr.x2, y1: mr.y2-2*lambda, y2: mr.y2], cut]; END; DrawWellDifShortContact: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.Rect, l: CD.Layer] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; r: CD.Rect = CDOrient.RectAt[[0, 0], inst.ob.size]; inr: CD.Rect = CDBasics.Extend[r, -wellSurround]; mr: CD.Rect = CDBasics.Extend[inr, -difShortRimWidth]; h: CD.Number = (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.nwellCont]; Draw[[x1: mr.x1, x2: mr.x2, y1: mr.y1, y2: mr.y1+2*lambda], cut]; Draw[[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], nwell]; END; -- But -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- pForButContact: CD.ObjectClass = RegisterObjectClass[$CMosContactBut]; pForWellButContact: CD.ObjectClass = RegisterObjectClass[$CMosContactWellBut]; butContactPolyYS: CD.Number = 3*lambda; butContactDiffY: CD.Number = butContactPolyYS-lambda; butContactDiffYS: CD.Number = 4*lambda; butConSX: CD.Number = 4*lambda; butConSY: CD.Number = butContactDiffY+butContactDiffYS; butContactRimWidth: CD.Number = lambda; pButConInnerY: CD.Number = wellSurround-butContactDiffY; pButConSX: CD.Number = butConSX+2*wellSurround; pButConSY: CD.Number = pButConInnerY+butConSY+wellSurround; pButConInner: CD.Rect = [ x1: wellSurround, x2: wellSurround+butConSX, y1: pButConInnerY, y2: pButConInnerY+butConSY ]; CreateButCon: PUBLIC PROC [difLev: CD.Layer] RETURNS [CD.Object] = BEGIN IF difLev=CMos.pdif THEN difLev _ CMos.wpdif; RETURN [CMosObjects.CreateButCon[difLev]] END; ReadButCon: CD.InternalReadProc --PROC [] RETURNS [Object]-- = BEGIN RETURN [ CreateButCon[CDIO.ReadLayer[]] ] END; WriteButCon: CD.InternalWriteProc -- PROC [me: Object] -- = BEGIN CDIO.WriteLayer[me.layer]; END; DrawButContact: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.Rect, l: CD.Layer] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; Draw[[0, 0, butConSX, butConSY], met]; Draw[[0, 0, butConSX, butContactPolyYS], pol]; Draw[[0, butContactDiffY, butConSX, butConSY], inst.ob.layer]; Draw[[butContactRimWidth, butContactRimWidth, butConSX-butContactRimWidth, butConSY-butContactRimWidth], cut]; END; DrawWellButContact: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN Draw: PROC[r: CD.Rect, l: CD.Layer] = INLINE BEGIN pr.drawRect[ CDOrient.MapRect[ itemInCell: r, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos], l, pr]; END; inr: CD.Rect = [ x1: wellSurround, y1: pButConInnerY, x2: wellSurround+butConSX, y2: pButConInnerY+butConSY ]; Draw[inr, met]; Draw[[x1: inr.x1, y1: inr.y1, x2: inr.x2, y2: inr.y1+butContactPolyYS], pol]; Draw[[x1: inr.x1, y1: inr.y1+butContactDiffY, x2: inr.x2, y2: inr.y2], inst.ob.layer]; Draw[[x1: 0, y1: 0, x2: pButConSX, y2: pButConSY], nwell]; Draw[CDBasics.Extend[inr, -butContactRimWidth], cut]; END; PButInsideRectWithSurround: PROC [ob: CD.Object] RETURNS [CD.Rect] = BEGIN RETURN [pButConInner] END; PButShowSelectedWithSurround: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: CD.DrawRef] = BEGIN pr.drawOutLine[ CDOrient.MapRect[ itemInCell: pButConInner, cellSize: [pButConSX, pButConSY], cellInstOrient: orient, cellInstPos: pos ], CD.selectionLayer, pr] END; pForBurCon: CD.ObjectClass = RegisterObjectClass[$CMosBurContact]; pForWellBurCon: CD.ObjectClass = RegisterObjectClass[$CMosWellBurContact]; CreateBurCon: PUBLIC PROC [w, l: CD.Number, wex: CD.Number, lex: CD.Number, difLev: CD.Layer] RETURNS [CD.Object] = BEGIN burAct: CD.Number = 2*lambda; actWidth, xMargins: CD.Number; cob: CD.Object ~ 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 lexmins THEN --old technology-- pr.drawRect[CDBasics.Extend[r, -2*lambda --oldmmRimWidth-- ], cut2, pr] ELSE --new technology-- pr.drawRect[CDBasics.Extend[r, -mmRimWidth], cut2, pr]; END; DescribeLayer: PROC[l: CD.Layer] RETURNS [Rope.ROPE] = {RETURN [Atom.GetPName[CD.LayerKey[l]]]}; Describe: PROC[me: CD.Object] RETURNS [Rope.ROPE] = BEGIN cp: ContactPtr = NARROW[me.specificRef]; RETURN [ SELECT cp.typ FROM burr => Rope.Concat["buried contact ", DescribeLayer[me.layer]], mDif => Rope.Concat[DescribeLayer[me.layer], " contact"], difShort => Rope.Concat["dif - short contact ", DescribeLayer[me.layer]], butt => Rope.Concat["butting contact ", DescribeLayer[me.layer]], mPol => "contact poly", mm2 => "via", ENDCASE => "unknown contact" ] END; Init: PROC [] = BEGIN pForDifPolCon.drawMe _ pForDifPolCon.quickDrawMe _ DrawDifPolCon; pForDifPolCon.internalRead _ ReadDifPolCon; pForDifPolCon.internalWrite _ WriteDifPolCon; pForDifPolCon.describe _ Describe; CDStretchyExtras.InstallMatch[pForDifPolCon, MatchContact]; pForWellDifPolCon.drawMe _ pForWellDifPolCon.quickDrawMe _ DrawWellDifPolCon; pForWellDifPolCon.interestRect _ InsideRectWithSurround; pForWellDifPolCon.showMeSelected _ ShowSelectedWithSurround; pForWellDifPolCon.internalRead _ ReadDifPolCon; pForWellDifPolCon.internalWrite _ WriteDifPolCon; pForWellDifPolCon.describe _ Describe; CDStretchyExtras.InstallMatch[pForWellDifPolCon, MatchContact]; pForButContact.drawMe _ pForButContact.quickDrawMe _ DrawButContact; pForButContact.internalRead _ ReadButCon; pForButContact.internalWrite _ WriteButCon; pForButContact.describe _ Describe; CDStretchyExtras.InstallMatch[pForButContact, MatchContact]; pForWellButContact.drawMe _ pForWellButContact.quickDrawMe _ DrawWellButContact; pForWellButContact.interestRect _ PButInsideRectWithSurround; pForWellButContact.showMeSelected _ PButShowSelectedWithSurround; pForWellButContact.internalRead _ ReadButCon; pForWellButContact.internalWrite _ WriteButCon; pForWellButContact.describe _ Describe; CDStretchyExtras.InstallMatch[pForWellButContact, MatchContact]; pForBurCon.drawMe _ pForBurCon.quickDrawMe _ DrawBurrCon; pForBurCon.internalRead _ ReadBurCon; pForBurCon.internalWrite _ WriteBurCon; pForBurCon.describe _ Describe; CDStretchyExtras.InstallMatch[pForBurCon, MatchContact]; CDCallSpecific.Register[$Lengthen, pForBurCon, LengthenBur]; CDCallSpecific.Register[$ChangeExt, pForBurCon, ChangeExtensionBur]; CDCallSpecific.Register[$Default, pForBurCon, DefaultenBur]; pForWellBurCon.interestRect _ InsideRectWithSurround; pForWellBurCon.internalRead _ ReadBurCon; pForWellBurCon.internalWrite _ WriteBurCon; pForWellBurCon.describe _ Describe; CDStretchyExtras.InstallMatch[pForWellBurCon, MatchContact]; CDCallSpecific.Register[$Lengthen, pForWellBurCon, LengthenBur]; CDCallSpecific.Register[$ChangeExt, pForWellBurCon, ChangeExtensionBur]; CDCallSpecific.Register[$Default, pForWellBurCon, DefaultenBur]; pForVia.drawMe _ pForVia.quickDrawMe _ DrawVia; pForVia.internalRead _ ReadVia; pForVia.internalWrite _ WriteVia; pForVia.describe _ Describe; CDStretchyExtras.InstallMatch[pForVia, MatchContact]; pForDifShorts.drawMe _ pForDifShorts.quickDrawMe _ DrawDifShortContact; pForDifShorts.internalRead _ ReadDifShortCon; pForDifShorts.internalWrite _ WriteDifShortCon; pForDifShorts.describe _ Describe; CDStretchyExtras.InstallMatch[pForDifShorts, MatchContact]; pForWellDifShorts.drawMe _ pForWellDifShorts.quickDrawMe _ DrawWellDifShortContact; pForWellDifShorts.interestRect _ InsideRectWithSurround; pForWellDifShorts.internalRead _ ReadDifShortCon; pForWellDifShorts.internalWrite _ WriteDifShortCon; pForWellDifShorts.describe _ Describe; CDStretchyExtras.InstallMatch[pForWellDifShorts, MatchContact]; END; Init[]; END. CMosCMContactsImpl.mesa (part of ChipNDale) Copyright c 1983, 1984 by Xerox Corporation. All rights reserved. Christian Jacobi, June 24, 1983 5:03 pm last edited Christian Jacobi, March 25, 1986 4:34:31 pm PST --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!! --connects metal with poly and diffusion cob: CD.Object ~ butCache.UnusedOrNew[]; cp: ContactPtr ~ NARROW[cob.specificRef]; cp.typ _ butt; IF difLev=undef THEN difLev_ndif; cob.layer _ difLev; IF difLev=CMos.pdif THEN { cob.class _ pForWellButContact; cob.size _ [pButConSX, pButConSY]; } ELSE { cob.class _ pForButContact; cob.size _ [butConSX, butConSY]; }; RETURN [butCache.ReplaceByAequivalent[cob]] --uses outer stuff!! --uses outer stuff!! -- Bur -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Buried contacts come in three flavours, Pol-Surround, Dif-Surround and Crossing. The buried contacts in chipndale are parameterized by lExt and wExt, their interpretation is as follows: Diff always extends 1l to the left, material above/below and to the right is determined by lExt and wExt respectively. 2l is the pivotal value, below 2l the material is Pol, at 2l or above the material is Diff. (Note: some combinations give Diff on all four sides, it is assumed that such combinations will not be created.) -- connects diffusion with poly without accessing metal -- copied from chipmonk without understanding --some people told me that this can not be produced cob.class _ pForWellBurCon; cob.size _ [w+2*wellSurround, l+2*wellSurround]; --uses outer stuff!! --copied from chipmonk without understanding --Mm -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --ignores wex and lex in chipmonk, why??? --connects two layers of metal --cp.wExt _ ; --cp.wExt _ ; --does not read specificRef !!!!!! -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CDCallSpecific.Register[$Lengthen, pForDifPolCon, LengthenPolyDif]; CDCallSpecific.Register[$Default, pForDifPolCon, DefaultenPolyDif]; CDCallSpecific.Register[$Lengthen, pForWellDifPolCon, LengthenPolyDif]; CDCallSpecific.Register[$Default, pForWellDifPolCon, DefaultenPolyDif]; pForWellBurCon.drawMe _ pForWellBurCon.quickDrawMe _ DrawWellBurrCon; CDCallSpecific.Register[$Lengthen, pForVia, LengthenVia]; --I'm not shure changing size is a good idea CDCallSpecific.Register[$Default, pForVia, DefaultenVia]; Κͺ˜šœ,™,Jšœ Οmœ7™BJšœ)™)Jšœ<™˜SJšœžœ˜#J˜š  œžœžœžœžœžœžœ ˜PJšœ™Jšž˜Jšœžœ!˜(Jšœžœ˜)Jšžœžœ˜"šžœ žœ˜Jšžœžœ˜-Jšžœžœžœ˜Jšž˜Jš œžœžœžœžœ˜=Jšžœ˜Jšœ ˜ Jšžœ˜—J˜š   œžœžœžœžœ ˜QJšœžœ ˜Jšž˜Jšœžœ9˜>J˜Jšœ"˜"Jšœ:˜:Jšžœ˜J˜—š  œžœžœžœžœ ˜UJšœžœ ˜Jšž˜Jšœžœ3˜8Jšœžœ+˜2J˜Jšœ$˜$Jšœ<˜Jšž˜Jšžœ#˜)Jšžœ˜—J˜š  œžœ’œ˜;Jšž˜Jšžœ˜Jšžœ˜—J˜š  œžœžœžœžœ ˜RJšœžœ ˜Jšž˜J˜š  œžœžœ žœ ž˜,Jšœ™Jšž˜˜ ˜J˜Jšœ˜J˜J˜—J˜J˜—Jšžœ˜J˜—Jšœ&˜&Jšœ.˜.Jšœ>˜>šœ.˜.Jšœ@˜@—Jšžœ˜J˜—š  œžœžœžœžœ ˜VJšœžœ ˜Jšž˜J˜š  œžœžœ žœ ž˜,Jšœ™Jšž˜˜ ˜J˜Jšœ˜J˜J˜—J˜J˜—Jšžœ˜J˜—šœžœ ˜Jšœ%˜%Jšœ5˜5Jšœ˜—Jšœ˜JšœM˜MJšœV˜VJšœ:˜:Jšœ5˜5Jšžœ˜—J˜š  œžœžœ žœžœ˜DJšž˜Jšžœ˜Jšžœ˜—J˜š œžœžœžœ ˜Išœžœžœ ˜)Jšž˜šœ˜šœ˜Jšœ˜Jšœ"˜"Jšœ˜Jšœ˜J˜—Jšœ˜Jšœ˜—Jšžœ˜J˜——J™Jšœa™aJ˜Jšœ žœ4˜BJšœžœ8˜JJ˜Icode™šœ„™„J™—š  œžœžœžœ˜+Jšœžœ˜Jšœžœ˜Jšœžœžœžœ ˜'Jšœ7™7Jšžœ˜Jšœ-™-Jšœžœ˜Jšœžœ˜Jšœžœ!˜(Jšœžœ˜)Jšžœžœ˜"Jšœžœ ˜Jšœžœ ˜šœ˜Jš œžœ žœžœžœ˜7—Jšœ žœ˜%Jšœ˜šœžœ˜ Jš œžœ žœžœžœžœ˜XJšœ˜—J˜J˜J˜šžœžœ˜Jšœ3™3Jšœ™J™0Jšžœžœ˜2J˜—šžœ˜Jšœ˜J˜J˜—J˜Jšžœ%˜+Jšžœ˜J˜—šŸ œžœ’œ˜>Jšž˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœ$˜$Jšžœ)˜/Jšžœ˜—J˜šŸ œžœ’œ˜;Jšž˜Jšœžœ˜(šžœžœ˜Jšœ+˜+Jšœ+˜+J˜—šžœ˜Jšœ˜Jšœ˜J˜—Jšœ˜Jšœ˜Jšžœ˜Jšžœ˜—J˜š   œžœžœžœžœžœ ˜aJšž˜J˜š  œžœžœ žœ ž˜,Jšœ™Jšž˜˜ ˜J˜Jšœ˜J˜J˜—J˜J˜—Jšžœ˜J˜—Jšœ,™,Jšœžœ˜0Jšœžœ˜Jšœžœ˜šœ žœ ˜Jš œžœžœžœžœ˜SJš œžœžœžœžœ˜RJ˜—JšœB˜BJšœV˜VJšœ]˜]Jšžœ˜J˜—šŸ œ˜&Jšž˜Jšœžœ˜$Jšžœ žœ žœž˜.šžœ˜Jšœžœ˜Jš œžœžœžœžœ˜BJšœžœ˜-JšœžœU˜[Jš žœ žœ žœžœžœ˜2JšœX˜XJšœ žœ˜Jš žœžœžœžœžœ˜0J˜—Jšžœ˜J˜—šŸœ˜-Jšž˜Jšœžœ˜$Jšžœ žœ žœž˜.šžœ˜Jš œžœžœžœžœ˜CJšœžœ˜-šœžœ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœ žœ˜Jš žœžœžœžœžœ˜0J˜—Jšžœ˜J˜—šŸ œ˜'Jšž˜Jš œžœžœžœžœ˜AJšœžœ˜-Jšœžœn˜uJšœ žœ˜Jš žœžœžœžœžœ˜0Jšžœ˜J˜—Jšœ_™_J˜Jšœ žœ3˜>Jšœ žœ˜Jšœ žœ˜J˜š  œžœžœžœ˜'Jšœžœ˜Jšœžœ žœžœ ˜%Jšœ)™)Jšœ™Jšžœ˜Jšœžœ ˜'Jšœžœ˜)Jšœžœ˜'Jšœ žœ+˜6Jšœžœ ˜Jšžœžœžœ˜2J˜ Jšœ ™ Jšœ ™ J˜šžœ žœ’>œ˜QJšœ˜—šžœ’œ˜Jšœ˜—J˜Jšžœ$˜*Jšžœ˜J˜—šŸ œ˜&Jšž˜Jšœžœ˜$Jšžœ žœ žœž˜-šžœ˜Jšœžœ˜Jšœžœ˜-Jšœžœ5˜;Jš žœ žœ žœžœžœ˜0Jšœ7˜7Jšœ žœ˜Jš žœžœžœžœžœ˜0J˜—Jšžœ˜J˜—šŸ œ˜'Jšž˜Jšœžœ˜-Jšœžœ?˜FJšœ žœ˜Jš žœžœžœžœžœ˜0Jšžœ˜—J˜š œžœ’œ˜;Jšž˜Jšžœ)˜/Jšžœ˜—J˜š œžœ’œ˜8Jšž˜Jšœ˜Jšžœ˜—J˜š  œžœžœžœžœ ˜KJšœžœ ˜Jšœ"™"Jšž˜Jšœžœ˜'Jšœžœ3˜8J˜J˜šžœžœ’œ˜/Jšœ)’œ ˜G—šž’œ˜Jšœ7˜7—Jšžœ˜J˜—JšœZ™ZJ˜š   œžœžœžœžœ˜6Jšœžœžœ˜)—J˜š  œžœžœ žœžœ˜3Jšž˜Jšœžœ˜(šžœ˜šžœž˜Jšœ@˜@Jšœ9˜9JšœI˜IJšœA˜AJšœ˜Jšœ ˜ Jšžœ˜—J˜—Jšžœ˜—J˜š œžœ˜Jšž˜JšœA˜AJšœ+˜+Jšœ-˜-Jšœ"˜"Jšœ;˜;JšœC™CJšœC™CJ˜JšœM˜MJšœ8˜8Jšœ<˜