DIRECTORY Basics USING [BITSHIFT, bitsPerWord, LongMult], CD, CDApplications, CDBasics, CDColors, CDOps, CDOrient, CDPrivate, CDTexts, CDVPrivate, CDVScale, Graphics, GraphicsBasic, GraphicsColor, GraphicsOps, PrincOps USING [BBptr, BitAddress, BBTable, SrcDesc, BitBltFlags, GrayParm], PrincOpsUtils USING [BITBLT], Real, Rope, RuntimeError, Terminal, TerminalExtras, ViewerClasses, ViewerSpecs; CDVDraw: CEDAR MONITOR IMPORTS Basics, CD, CDApplications, CDBasics, CDOps, CDOrient, CDVPrivate, CDVScale, Graphics, GraphicsOps, PrincOpsUtils, Real, RuntimeError, Terminal, TerminalExtras EXPORTS CDVPrivate, CD --DrawRef's private fields-- = BEGIN ViewerPrivateRep: PUBLIC TYPE ~ CDVPrivate.MyGraphicRec; ViewerSaveRep: PUBLIC TYPE ~ INTEGER; -- XXX placeholder MyGraphicRef: TYPE ~ CDVPrivate.MyGraphicRef; MyGraphicRec: TYPE ~ CDVPrivate.MyGraphicRec; maxInfluence: CD.DesignNumber ~ 0; virtual: Terminal.Virtual ~ Terminal.Current[]; defaultFont: Graphics.FontRef ~ GraphicsOps.DefaultFont[]; errrorReport: RECORD [ text: Rope.ROPE, me: MyGraphicRef, r: CD.Rect, color: REF CDColors.Brick ]; bitBltFlagsForPaint: PrincOps.BitBltFlags = PrincOps.BitBltFlags[ direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: TRUE, srcFunc: null, dstFunc: or ]; bitBltFlagsForOutline: PrincOps.BitBltFlags = PrincOps.BitBltFlags[ direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: TRUE, srcFunc: null, dstFunc: or ]; bitBltFlagsForClearPattern: PrincOps.BitBltFlags = PrincOps.BitBltFlags[ direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: TRUE, srcFunc: complement, dstFunc: and ]; blackBrick: REF CDColors.Brick = NEW[CDColors.Brick_ALL[LAST[CARDINAL]]]; whiteBrick: REF CDColors.Brick = NEW[CDColors.Brick_ALL[0]]; BitBlitDraw: PROC[me: MyGraphicRef, r: CD.Rect, color: REF CDColors.Brick] = TRUSTED INLINE BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { errrorReport.text _ "BitBlitDraw"; errrorReport.me _ me; errrorReport.r_r; errrorReport.color_color; IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT; }; }; xBit, x1, x2, y1, y2: CARDINAL; vr: CD.Rect; IF ~CDBasics.NonEmpty[r] THEN RETURN; vr _ CDVScale.DesignToViewerRect[me.scale, r]; x1 _ MAX[vr.x1, 0]; y1 _ MAX[vr.y1, 0]; IF vr.x2<=0 OR vr.y2<=0 THEN RETURN; x2 _ MIN[vr.x2, me.viewer.cw]; y2 _ MIN[vr.y2, me.viewer.ch]; IF x1>=x2 OR y1>=y2 THEN RETURN; xBit _ Basics.BITSHIFT[x1+me.vx, me.logbpp]; me.pBBptr.width _ Basics.BITSHIFT[x2-x1, me.logbpp]; me.pBBptr.height _ y2-y1; y1 _ me.vy-y2; me.pBBptr.dst _ [ me.screen + Basics.LongMult[y1, me.scWidthWords] + LONG[(xBit/Basics.bitsPerWord)],, xBit MOD Basics.bitsPerWord ]; me.pBBptr.src _ [ LOOPHOLE[ LOOPHOLE[color, LONG CARDINAL] + y1 MOD 4, LONG POINTER],, xBit MOD Basics.bitsPerWord]; me.pBBptr.srcDesc.gray.yOffset _ y1 MOD 4; IF me.bpp=1 THEN PrincOpsUtils.BITBLT[me.pBBptr] ELSE { TerminalExtras.LockColorFrame[vt: virtual, xmin: x1+me.vx, ymin: y1, xmax: x2+me.vx, ymax: y1+me.pBBptr.height ]; PrincOpsUtils.BITBLT[me.pBBptr]; TerminalExtras.UnlockColorFrame[virtual] }; EXITS SomeError => NULL; END; BitBlitSave: ENTRY PROC[me: MyGraphicRef, r: CD.Rect, color: REF CDColors.Brick, clearPattern: REF CDColors.Brick_NIL] = TRUSTED BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { errrorReport.text _ "BitBlitSave"; errrorReport.me _ me; errrorReport.r_r; errrorReport.color_color; IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT; }; }; xBit, x1, x2, y1, y2: CARDINAL; vr: CD.Rect; r _ CDBasics.Intersection[r, me.deviceDrawRef.worldClip]; IF ~CDBasics.NonEmpty[r] THEN RETURN; vr _ CDVScale.DesignToViewerRect[me.scale, r]; x1 _ MAX[vr.x1, 0]; y1 _ MAX[vr.y1, 0]; IF vr.x2<=0 OR vr.y2<=0 THEN RETURN; x2 _ MIN[vr.x2, me.viewer.cw]; y2 _ MIN[vr.y2, me.viewer.ch]; IF x1>=x2 OR y1>=y2 THEN RETURN; xBit _ Basics.BITSHIFT[x1+me.vx, me.logbpp]; me.xBBptr.width _ Basics.BITSHIFT[x2-x1, me.logbpp]; me.xBBptr.height _ y2-y1; y1 _ me.vy-y2; -- now y1 is device top pixel me.xBBptr.srcDesc _ PrincOps.SrcDesc[gray[PrincOps.GrayParm[ yOffset: y1 MOD 4, widthMinusOne: 0, --words heightMinusOne: 3 --lines ]]]; me.xBBptr.dst _ [ me.screen + Basics.LongMult[y1, me.scWidthWords] + LONG[(xBit/Basics.bitsPerWord)],, xBit MOD Basics.bitsPerWord ]; IF me.bpp#1 THEN TerminalExtras.LockColorFrame[vt: virtual, xmin: x1+me.vx, ymin: y1, xmax: x2+me.vx, ymax: y1+me.xBBptr.height ]; IF clearPattern#NIL THEN { me.xBBptr.flags _ bitBltFlagsForClearPattern; me.xBBptr.src _ [ LOOPHOLE[ LOOPHOLE[clearPattern, LONG CARDINAL] + y1 MOD 4, LONG POINTER],, xBit MOD Basics.bitsPerWord]; PrincOpsUtils.BITBLT[me.xBBptr]; }; me.xBBptr.src _ [ LOOPHOLE[ LOOPHOLE[color, LONG CARDINAL] + y1 MOD 4, LONG POINTER],, xBit MOD Basics.bitsPerWord]; me.xBBptr.flags _ bitBltFlagsForOutline; PrincOpsUtils.BITBLT[me.xBBptr]; IF me.bpp#1 THEN TerminalExtras.UnlockColorFrame[virtual]; EXITS SomeError => NULL; END; BitBlitOutLine: ENTRY PROC[r: CD.Rect, pr: CD.DrawRef] = BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { errrorReport.text _ "BitBlitOutLine"; errrorReport.me _ pr.viewerPrivate; errrorReport.r_r; IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT; }; }; me: MyGraphicRef ~ pr.viewerPrivate; vr, clipr: CD.Rect; DrawBlack: --INTERNAL-- PROC[me: MyGraphicRef, x1, y1, x2, y2: INTEGER] = TRUSTED INLINE BEGIN xBits: CARDINAL ~ Basics.BITSHIFT[x1+INTEGER[me.vx], me.logbpp]; me.xBBptr.width _ Basics.BITSHIFT[x2-x1, me.logbpp]; me.xBBptr.height _ y2-y1; me.xBBptr.dst _ [ me.screen + Basics.LongMult[INTEGER[me.vy]-y2, me.scWidthWords] + LONG[(xBits/Basics.bitsPerWord)],, xBits MOD Basics.bitsPerWord ]; PrincOpsUtils.BITBLT[me.xBBptr]; END; IF r.x2>me.dClip.x2 THEN r.x2_me.dClip.x2+1; IF r.y2>me.dClip.y2 THEN r.y2_me.dClip.y2+1; IF r.x1=clipr.x2 OR clipr.y1>=clipr.y2 THEN RETURN; --harder empty test than CDBasics --necessary because we add/subtract one TRUSTED { me.xBBptr.src _ [LOOPHOLE[blackBrick, LONG POINTER],,0]; me.xBBptr.flags _ bitBltFlagsForOutline; me.xBBptr.srcDesc _ PrincOps.SrcDesc[gray[PrincOps.GrayParm[ yOffset: 0, widthMinusOne: 0, --words heightMinusOne: 0 --lines ]]]; }; IF me.bpp#1 THEN { TerminalExtras.LockColorFrame[vt: virtual, xmin: clipr.x1+me.vx, ymin: me.vy+1-clipr.y2, xmax: clipr.x2+me.vx-1, ymax: me.vy-clipr.y1 ]; }; IF vr.x1>=clipr.x1 THEN DrawBlack[me, clipr.x1, clipr.y1, clipr.x1+1, clipr.y2]; --left IF vr.y2<=clipr.y2 THEN DrawBlack[me, clipr.x1, clipr.y2-1, clipr.x2, clipr.y2]; --top IF vr.x2<=clipr.x2 THEN DrawBlack[me, clipr.x2-1, clipr.y1, clipr.x2, clipr.y2]; --right IF vr.y1>=clipr.y1 THEN DrawBlack[me, clipr.x1, clipr.y1, clipr.x2, clipr.y1+1]; --bottom IF me.bpp#1 THEN TerminalExtras.UnlockColorFrame[virtual]; EXITS SomeError => NULL; END; BitBlitDrawRectForViewers: ENTRY PROC[r: CD.Rect, l: CD.Level, pr: CD.DrawRef] = BEGIN ENABLE UNWIND => NULL; me: MyGraphicRef = pr.viewerPrivate; BitBlitDraw[me, CDBasics.Intersection[r, pr.worldClip], me.colorTable[l]]; END; SaveRectForViewers: ENTRY PROCEDURE[r: CD.Rect, l: CD.Level, pr: CD.DrawRef] = BEGIN ENABLE UNWIND => NULL; me: MyGraphicRef = pr.viewerPrivate; IF me.saveList=NIL OR me.saveList.first.next>=CDVPrivate.saveListSize THEN me.saveList _ CONS[CDVPrivate.SavedRectArraySeq[next: 0], me.saveList]; me.saveList.first.x[me.saveList.first.next] _ [r: CDBasics.Intersection[r, pr.worldClip], l: l]; me.saveList.first.next _ me.saveList.first.next+1 END; SetGround: --CD.SetGroundProc-- PROC [pr: CD.DrawRef, pushedOut: BOOL] = BEGIN WITH pr.devicePrivate SELECT FROM me: MyGraphicRef => me.colorTable _ me.personalColors[me.display][IF pushedOut THEN back ELSE normal] ENDCASE => NULL; END; DrawCommentForViewers: PUBLIC PROC[r: CD.DesignRect, comment: Rope.ROPE, pr: CD.DrawRef] = BEGIN topToFontLine: NAT ~ 9+2; fontHeight: NAT ~ 12; leftMargin: NAT ~ 2; bothMargin: NAT ~ 2*leftMargin; me: MyGraphicRef _ NARROW[pr.devicePrivate]; vr: CD.Rect _ CDVScale.DesignToViewerRect[me.scale, r]; IF vr.y2-vr.y1>fontHeight THEN { xw: REAL ~ Graphics.RopeWidth[font: defaultFont, rope: comment].xw; IF vr.x2-vr.x1>xw+bothMargin THEN { me.viewerContext.SetColor[Graphics.black]; me.viewerContext.SetCP[vr.x1+leftMargin, vr.y2-topToFontLine]; me.viewerContext.DrawRope[comment]; } }; END; RepaintRectAreaInViewer: PUBLIC PROC[me: MyGraphicRef, rect: CD.DesignRect, eraseFirst: BOOL] = BEGIN ENABLE { RuntimeError.UNCAUGHT => IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT }; interestRect: CD.DesignRect; UpdateDrawInformation[me]; me.deviceDrawRef.worldClip _ interestRect _ CDBasics.Intersection[rect, me.dClip]; IF CDBasics.NonEmpty[interestRect] THEN { [] _ Graphics.SetPaintMode[me.viewerContext, transparent]; RepaintBackground[me, interestRect, eraseFirst]; CDOps.QuickDrawDesign[me.actualDesign, me.deviceDrawRef]; [] _ Graphics.SetPaintMode[me.viewerContext, opaque]; IF me.saveList#NIL THEN { l: CDVPrivate.SaveList _ me.saveList; me.saveList _ NIL; WHILE l#NIL DO FOR i: INTEGER IN [0..l.first.next) DO BitBlitSave[me, l.first.x[i].r, me.colorTable[l.first.x[i].l], me.greyTable[l.first.x[i].l]]; ENDLOOP; l _ l.rest ENDLOOP; }; FOR pl: CDVPrivate.PainterList _ me.painterList, pl.rest WHILE pl#NIL DO IF CDBasics.Intersect[interestRect, pl.first.rect] THEN pl.first.proc[me, pl.first, interestRect ! RuntimeError.UNCAUGHT => IF CDVPrivate.catchAny THEN CONTINUE ELSE REJECT ] ENDLOOP } EXITS SomeError=> NULL END; RepaintBackground: PUBLIC ENTRY PROC[me: MyGraphicRef, r: CD.DesignRect, eraseFirst: BOOL] = BEGIN ENABLE { UNWIND => NULL; RuntimeError.UNCAUGHT => { errrorReport.text _ "background"; errrorReport.me _ me; errrorReport.r _ r; IF CDVPrivate.catchAny THEN GOTO SomeError ELSE REJECT }; }; DrawOutside: --INTERNAL-- PROC [r: CD.DesignRect] = BEGIN BitBlitDraw[me, CDBasics.Intersection[r, me.dClip], me.colorTable[CD.backGround]]; END; IF eraseFirst THEN { TRUSTED {me.pBBptr.flags.dstFunc _ null}; BitBlitDraw[me, CDBasics.Intersection[r, me.dClip], whiteBrick]; TRUSTED {me.pBBptr.flags.dstFunc _ or}; }; IF me.actualDesign.actual.first.mightReplace#NIL AND ~me.suppressOutsidePushedCell AND me.actualDesign.actual.first.mightReplace.ob#NIL THEN CDBasics.DecomposeRect[r: r, test: CDApplications.ARectO[me.actualDesign.actual.first.mightReplace], outside: DrawOutside ]; EXITS SomeError => NULL; END; InitForBBLT: PROC [me: MyGraphicRef] = BEGIN x, y: REAL; IF me.viewer.column=color THEN TRUSTED { m: Terminal.ColorMode = Terminal.GetColorMode[virtual]; IF m.full OR m.bitsPerPixelChannelA=0 THEN ERROR CDVPrivate.notSupportedColorMode; me.bpp _ m.bitsPerPixelChannelA; me.screen _ virtual.colorBitmapA; me.scWidth _ virtual.colorWidth; -- pixels me.scWidthBits _ virtual.colorWidth*me.bpp; me.scHeight _ virtual.colorHeight; IF me.bpp=4 THEN { me.display _ bit4; me.logbpp _ 2; } ELSE IF me.bpp=8 THEN { me.display _ bit8; me.logbpp _ 3; } ELSE ERROR; } ELSE { -- b+w me.display _ bw; me.bpp _ 1; me.logbpp _ 0; me.scWidth _ ViewerSpecs.screenW/Basics.bitsPerWord; me.scWidthBits _ ViewerSpecs.screenW; me.scHeight _ ViewerSpecs.screenH; me.screen _ Terminal.GetBitBltTable[virtual].bbt.dst.word; }; me.colorTable _ me.personalColors[me.display][normal]; me.greyTable _ me.personalColors[me.display][grey]; [x, y] _ GraphicsOps.UserToDevice[me.viewerContext, 0, 0]; -- in device in pixels me.vx _ Real.RoundI[x]; me.vy _ Real.RoundI[y]; --bottom most pixel of viewer me.scWidthWords _ me.scWidthBits/Basics.bitsPerWord; TRUSTED BEGIN me.pBBptr^ _ PrincOps.BBTable[ dst: TRASH, dstBpl: LOOPHOLE[me.scWidthBits, INTEGER], src: TRASH, srcDesc: PrincOps.SrcDesc[gray[PrincOps.GrayParm[ yOffset: 0, --is actually trash widthMinusOne: 0, --words heightMinusOne: 3 --lines ]]], width: TRASH, height: TRASH, flags: bitBltFlagsForPaint ]; me.xBBptr^ _ me.pBBptr^; END; END; InternalCreateDrawInformation: INTERNAL PROC [me: MyGraphicRef] = BEGIN s: REAL; pr: CD.DrawRef ~ CD.NewNullDeviceDrawRef[me.actualDesign]; pr.drawRect _ BitBlitDrawRectForViewers; pr.outLineProc _ BitBlitOutLine; pr.drawComment _ DrawCommentForViewers; pr.deviceContext _ Graphics.CopyContext[me.viewerContext]; s _ CDVScale.DesignToViewerFactor[me.scale]; pr.scaleHint _ s*me.suppressFactorForCells; Graphics.Scale[pr.deviceContext, s, s]; Graphics.Translate[pr.deviceContext, -me.scale.off.x, -me.scale.off.y]; pr.contextFilter _ defaultContextFilter; pr.devicePrivate _ me; pr.stopFlag _ me.stoprequest; pr.suppressOutsidePushedCell _ me.suppressOutsidePushedCell; pr.setGround _ SetGround; me.dClip _ pr.worldClip _ CDVScale.GetClipRecord[me.scale, me.viewer.cw, me.viewer.ch]; pr.minimalSize _ --XXX-- MIN[(me.dClip.x2-me.dClip.x1)/8, (me.dClip.y2-me.dClip.y1)/8]; InitForBBLT[me]; pr.saveRect _ (IF me.display=bit8 THEN BitBlitDrawRectForViewers ELSE SaveRectForViewers); me.deviceDrawRef _ pr; pr.viewerPrivate _ me; -- this line last! it tells DummyNotify that the rest is initialized END; UpdateDrawInformation: ENTRY PROC [me: MyGraphicRef] = BEGIN ENABLE UNWIND => NULL; s: REAL; pr: CD.DrawRef; IF me.deviceDrawRef=NIL THEN InternalCreateDrawInformation[me]; pr _ me.deviceDrawRef; pr.deviceContext _ Graphics.CopyContext[me.viewerContext]; s _ CDVScale.DesignToViewerFactor[me.scale]; Graphics.Scale[pr.deviceContext, s, s]; Graphics.Translate[pr.deviceContext, -me.scale.off.x, -me.scale.off.y]; pr.contextFilter _ defaultContextFilter; END; CreateDrawInformation: PUBLIC ENTRY PROC [me: MyGraphicRef] = BEGIN ENABLE UNWIND => NULL; InternalCreateDrawInformation[me] END; defaultContextFilter: REF CD.ContextFilter = NEW[CD.ContextFilter]; FOR l: CD.Level IN CD.Level DO defaultContextFilter[l].paintMode _ transparent; defaultContextFilter[l].doit _ TRUE; ENDLOOP; defaultContextFilter[CD.backGround].doit _ FALSE; END. ˆCDVDraw.mesa Copyright c 1983, 1984 by Xerox Corporation. All rights reserved. Christian Jacobi August 5, 1983 11:07 am last edited by Christian Jacobi November 5, 1984 10:24:10 am PST -- r ALLREADY CLIPPED --DONE OUTSIDE r _ CDBasics.Intersection[r, me.deviceDrawRef.worldClip]; --draw exclusive high border pixels --no empty test; is guaranteed by caller --clip to area where --1) small enogh: it does not crash on scaling later --2) big enogh: if drawn, it does not draw artificial lines --RepaintBackground ---------- --fixed pBBptr initializations --done in viewerprocess: me.pBBptr _ PrincOpsUtils.AlignedBBTable[@bBTableSpace]; ÊŒ˜šœ ™ Jšœ Ïmœ7™BJšœ+™+JšœB™BJ˜—šÏk ˜ Jšœžœžœ˜/Jšžœ˜J˜J˜ J˜ J˜J˜ J˜ J˜Jšœ ˜ J˜ J˜ J˜J˜J˜ Jšœ žœ>˜LJšœžœžœ˜Jšœ˜J˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜J˜ J˜—šÏbœžœž˜Jšžœžœ•˜§Jšžœ žœÏcœ˜5—Jšž˜J˜Jšœžœžœ˜8Jšœžœžœžœ ˜:J˜Jšœžœ˜-Jšœžœ˜-Jšœžœ˜"Jšœ/˜/Jšœ:˜:J˜šœžœ˜Jšœ žœ˜Jšœ˜Jšœžœ˜ Jšœžœ˜Jšœ˜—J˜šœA˜AJ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜ Jšœ˜Jšœ ˜ J˜—J˜šœC˜CJ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜ Jšœ˜Jšœ ˜ J˜—J˜šœH˜HJ˜Jšœ žœ˜Jšœžœ˜Jšœžœ˜ Jšœ˜Jšœ ˜ J˜—J˜Jš œ žœžœžœžœžœ˜IJšœ žœžœžœ˜˜>Jšœ#˜#J˜—J˜—Jšžœ˜J˜—š ¡œžœžœžœžœ˜_Jšž˜šžœ˜Jš œ žœžœžœžœ žœž˜OJšœ˜—Jšœžœ ˜Jšœ˜JšœR˜Ršžœ!žœ˜)J˜:Jšœ0˜0Jšœ9˜9J˜5šžœ žœžœ˜Jšœ%˜%Jšœžœ˜šžœžœž˜šžœžœžœž˜&Jšœ]˜]Jšžœ˜—Jšœ ˜ Jšžœ˜—J˜—šžœ6žœžœž˜Hšžœ1ž˜7šœ*˜*Jš œ žœžœžœžœžœž˜IJšœ˜——Jšž˜—Jšœ˜—Jšžœ ž˜Jšžœ˜J˜—š ¡œžœžœžœžœžœ˜]Jšž˜šžœ˜Jšžœžœ˜šœ žœ˜Jšœ!˜!Jšœ˜Jšœ˜Jš žœžœžœ žœž˜6J˜—Jšœ˜—J˜š¡ œ  œžœžœ˜3Jšž˜JšœBžœ˜RJšžœ˜J˜—Jšœ™šžœ žœ˜Jšžœ"˜)Jšœ@˜@Jšžœ ˜'J˜—šžœ+žœžœž˜VJšœ-žœžœ˜6˜JšœH˜HJ˜J˜——šž˜Jšœ žœ˜—Jšžœ˜J˜—š¡ œžœ˜'Jšž˜Jšœžœ˜ šžœžœžœ˜(Jšœ7˜7Jšžœžœžœžœ"˜RJšœ!˜!Jšœ!˜!Jšœ"  ˜,Jšœ+˜+Jšœ"˜"šžœ žœ˜Jšœ˜Jšœ˜J˜—šžœžœ žœ˜Jšœ˜Jšœ˜J˜—Jšžœžœ˜ J˜—šžœ ˜ Jšœ˜J˜ Jšœ˜Jšœ4˜4J˜%J˜"Jšœ:˜:J˜—Jšœ6˜6Jšœ3˜3Jšœ; ˜QJ˜Jšœ ˜5Jšœ4˜4Jšœ ™ Jšœ™JšœQ™Qšžœž˜ šœ˜Jšœžœ˜ Jšœžœžœ˜*Jšœžœ˜ šœ1˜1Jšœ  ˜Jšœ ˜Jšœ œ˜Jšœ˜—Jšœžœ˜ Jšœžœ˜Jšœ˜J˜—Jšœ˜Jšžœ˜—Jšžœ˜—J˜š¡œžœžœ˜AJšž˜Jšœžœ˜Jšœžœ žœ'˜:Jšœ(˜(J˜ Jšœ'˜'Jšœ:˜:Jšœ-˜-Jšœ,˜,J˜'JšœG˜GJšœ(˜(Jšœ˜J˜Jšœ=˜=Jšœ˜JšœW˜Wšœ ˜Jšžœ;˜>—Jšœ˜Jšœžœžœžœ˜ZJšœ˜Jšœ D˜\Jšžœ˜—J˜š¡œžœžœ˜6Jšžœžœžœžœ˜Jšœžœ˜Jšœžœ ˜Jšžœžœžœ#˜?Jšœ˜Jšœ:˜:Jšœ-˜-J˜'JšœG˜GJšœ(˜(Jšžœ˜J˜—š¡œžœžœžœ˜=Jšžœžœžœžœ˜Jšœ!˜!Jšžœ˜J˜—Jš œžœžœžœžœ˜Cš žœžœžœžœž˜Jšœ0˜0Jšœžœ˜$Jšžœ˜—Jšœžœžœ˜1Jšžœ˜J˜—…—7 L4