DIRECTORY Carets USING [ResumeCarets, SuspendCarets], ColorWorld USING [NewContext], Graphics USING [black, ClipBox, Context, DrawBox, DrawRope, FontRef, Mark, NewContext, nullMark, PaintMode, Restore, Save, Scale, SetColor, SetCP, SetDefaultFont, SetPaintMode, Translate, white], GraphicsOps USING [Disable], IconManager USING [selectedIcon], Icons USING [DrawIcon], Menus USING [], MenusPrivate USING [DrawMenu], Process USING [Detach, GetCurrent, MsecToTicks, Pause, Ticks], Rope USING [ROPE], VFonts USING [defaultFont, defaultGFont, StringWidth], ViewerOps, ViewerClasses, ViewerLocks USING [CallUnderReadLock, CallUnderWriteLock, ColumnWedged, Wedged], ViewerSpecs, ViewersStallNotifier, ViewerTools USING [GetSelectedViewer]; ViewerPaintImpl: CEDAR MONITOR IMPORTS Carets, ColorWorld, Graphics, GraphicsOps, IconManager, Icons, MenusPrivate, Process, VFonts, ViewerLocks, ViewerTools, ViewerOps, ViewerSpecs EXPORTS ViewerOps, ViewersStallNotifier SHARES Menus, ViewerClasses, ViewerLocks = BEGIN OPEN Graphics, ViewerClasses, ViewerOps, ViewerSpecs; InvisiblePaint: PUBLIC SIGNAL = CODE; PaintDocumentHeader: PROC [viewer: Viewer, context: Context, clear: BOOL, hint: PaintHint, whatChanged: REF ANY] = BEGIN OPEN viewer; wbs: INTEGER = IF viewer.border THEN windowBorderSize ELSE 0; ClipBox[context, [wx, wy, wx+ww, wy+wh]]; IF hint#menu THEN BEGIN IF viewer.class.caption#NIL THEN BEGIN -- client-painted caption mark: Mark _ Save[context]; ClipBox[context, [wx+wbs, wy+wh-captionHeight-wbs, wx+ww-(2*wbs), wy+wh-wbs]]; viewer.class.caption[viewer, context]; Restore[context, mark]; END ELSE BEGIN headerW: INTEGER _ VFonts.StringWidth[name]; IF viewer.saveInProgress THEN headerW _ headerW + sipW ELSE IF viewer.newFile THEN headerW _ headerW + newFW ELSE IF viewer.newVersion THEN headerW _ headerW + newVW; IF viewer.link#NIL THEN headerW _ headerW + linkW; headerW _ MIN[headerW, ww]; DrawBox[context, XYWH2Box[wx, wy+wh-captionHeight, ww, captionHeight]]; SetColor[context, white]; SetCP[context, wx+((ww-headerW)/2), wy+wh-captionHeight+4]; DrawRope[context, name]; IF viewer.saveInProgress THEN DrawRope[context, sipT] ELSE IF viewer.newFile THEN DrawRope[context, newFT] ELSE IF viewer.newVersion THEN DrawRope[context, newVT]; IF viewer.link#NIL THEN DrawRope[context, linkT]; END; END; IF menu#NIL AND hint#caption THEN BEGIN height: INTEGER _ menu.linesUsed*menuHeight; IF whatChanged=NIL THEN BEGIN IF ~clear THEN BEGIN SetColor[context, white]; DrawBox[context, XYWH2Box[wx+wbs, wy+wh-captionHeight-height, ww-(2*wbs), height]]; END; SetColor[context, black]; DrawBox[context, XYWH2Box[wx, wy+wh-captionHeight-height-windowBorderSize, ww, menuBarHeight]]; END; MenusPrivate.DrawMenu[viewer.menu, context, wx+wbs, wy+wh-menuHeight-captionHeight, whatChanged]; END; END; PaintIcon: PROC [viewer: Viewer, hint: PaintHint, whatChanged: REF ANY _ NIL] = BEGIN context: Context; label: Rope.ROPE; IF viewer.parent#NIL THEN RETURN; context _ AcquireContext[viewer, FALSE]; -- all icons on b&w display IF viewer.icon=private THEN viewer.class.paint[viewer, context, whatChanged, hint=all] ELSE IF hint=all OR hint=caption THEN BEGIN mark: Mark _ Save[context]; -- since Icons.DrawIcon will set clipper IF viewer.icon=document AND (viewer.newVersion OR viewer.newFile) THEN viewer.icon _ dirtyDocument ELSE IF viewer.icon=dirtyDocument AND NOT (viewer.newVersion OR viewer.newFile) THEN viewer.icon _ document; label _ NARROW[ViewerOps.FetchProp[viewer, $IconLabel]]; IF label = NIL THEN label _ viewer.name; Icons.DrawIcon[flavor: viewer.icon, context: context, label: label]; Restore[context, mark]; IF IconManager.selectedIcon=viewer THEN BEGIN [] _ SetPaintMode[context, invert]; DrawBox[context, [0, 0, iconWidth, iconHeight]]; END; END; ReleaseContext[context]; END; SetIconLabel: PUBLIC PROC [viewer: Viewer, label: Rope.ROPE] = BEGIN ViewerOps.AddProp[viewer, $IconLabel, label]; END; RecursivelyPaintViewers: PROC [viewer: Viewer, hint: PaintHint, clearClient: BOOL, clear: BOOL, rect: PaintRectangle, whatChanged: REF ANY] = BEGIN OPEN viewer; vx, vy: INTEGER; context: Context _ NIL; bitmapY: INTEGER _ 0; FOR v: Viewer _ viewer, v.parent UNTIL v=NIL DO -- visibility test IF v.parent#NIL THEN BEGIN IF (v.wy+v.wh < 0) OR (v.wy > v.parent.ch) THEN RETURN; IF (v.ww+v.ww < 0) OR (v.wx > v.parent.cw) THEN RETURN; END ENDLOOP; IF hint#client THEN BEGIN ENABLE UNWIND => IF context#NIL THEN ReleaseContext[context]; context _ AcquireContext[parent, viewer.column=color]; IF ~viewer.visible OR viewer.destroyed THEN SIGNAL InvisiblePaint; IF clearClient AND ~clear AND hint=all THEN BEGIN SetColor[context, white]; DrawBox[context, XYWH2Box[wx, wy, ww, wh]]; SetColor[context, black]; clear _ TRUE; END; IF border AND hint=all THEN BEGIN wbs: INTEGER ~ windowBorderSize; DrawBox[context, XYWH2Box[wx, wy, ww, wbs]]; DrawBox[context, XYWH2Box[wx, wy, wbs, wh]]; DrawBox[context, XYWH2Box[wx+ww-wbs, wy, wbs, wh]]; DrawBox[context, XYWH2Box[wx, wy+wh-wbs, ww, wbs]]; END; IF parent=NIL AND viewer.column#static THEN PaintDocumentHeader[viewer, context, clear, hint, whatChanged]; ReleaseContext[context]; END; IF hint=all OR hint=client THEN BEGIN ENABLE UNWIND => IF context#NIL THEN ReleaseContext[context]; context _ NIL; context _ AcquireContext[viewer, viewer.column=color]; IF ~viewer.visible OR viewer.destroyed THEN SIGNAL InvisiblePaint; IF rect#NIL AND class.bltContents = none THEN clearClient _ TRUE; IF clearClient AND ~clear THEN BEGIN SetColor[context, white]; DrawBox[context, [0, 0, cw, ch]]; SetColor[context, black]; IF rect # NIL THEN whatChanged _ NIL; rect _ NIL; clear _ TRUE; END; IF class.paint#NIL THEN class.paint[viewer, context, whatChanged, clear]; ReleaseContext[context]; END; IF rect # NIL AND viewer.parent = NIL THEN { IF viewer.cx >= rect.x AND (viewer.cx + viewer.cw <= rect.x + rect.w) AND viewer.cy >= rect.y AND (viewer.cy + viewer.ch <= rect.y + rect.h) THEN RETURN}; IF hint=all OR hint=client OR clear THEN FOR v: Viewer _ viewer.child, v.sibling UNTIL v=NIL DO IF rect # NIL THEN { -- don't paint if it is completely within the blt -- map to the coodinate system that rect uses IF viewer.class.coordSys = top THEN [vx, vy] _ ViewerOps.UserToScreenCoords[viewer, v.wx, v.wy+v.wh] ELSE [vx, vy] _ ViewerOps.UserToScreenCoords[viewer, v.wx, v.wy]; IF vx >= rect.x AND (vx + v.ww <= rect.x + rect.w) AND vy >= rect.y AND (vy + v.wh <= rect.y + rect.h) THEN LOOP}; RecursivelyPaintViewers[v, all, FALSE, clear, rect, whatChanged]; ENDLOOP; END; PaintViewer: PUBLIC PROC [viewer: Viewer, hint: PaintHint _ client, clearClient: BOOL _ TRUE, whatChanged: REF ANY _ NIL] = BEGIN LocalPaintViewer: PROC = { ENABLE ABORTED => {Carets.ResumeCarets[]; CONTINUE}; rect: PaintRectangle; IF ~viewer.visible OR viewer.destroyed THEN RETURN; IF viewer.iconic THEN {PaintIcon[viewer, hint, whatChanged]; RETURN}; Carets.SuspendCarets[]; IF ISTYPE[whatChanged, PaintRectangle] THEN rect _ NARROW[whatChanged]; RecursivelyPaintViewers[viewer, hint, clearClient AND ~(hint=menu OR hint=caption), FALSE, rect, whatChanged ! InvisiblePaint => CONTINUE]; Carets.ResumeCarets[]}; ViewerLocks.CallUnderReadLock[LocalPaintViewer, viewer ! ViewerLocks.Wedged => CONTINUE]; END; PaintVector: TYPE = REF PaintVectorRec; PaintVectorRec: TYPE = RECORD [ next: PaintVector _ NIL, viewer: Viewer _ NIL, inUse: BOOL _ FALSE, resetOnRelease: BOOL _ FALSE, color: BOOL _ FALSE, mark: Graphics.Mark _ nullMark, process: UNSAFE PROCESS _ NIL, context: Context _ NIL, previous: PaintVector _ NIL]; nVectors: CARDINAL = 5; usedVectors: CARDINAL _ 0; PaintVectorAvailable: CONDITION; paintingLock: CARDINAL _ 0; vectorRoot: PaintVector _ NIL; colorVector: PaintVector _ NIL; Init: ENTRY PROC = BEGIN new: PaintVector; FOR n: CARDINAL IN [0..nVectors) DO new _ NEW[PaintVectorRec]; new.context _ NewContext[]; SetDefaultFont[new.context, VFonts.defaultGFont]; new.next _ vectorRoot; IF vectorRoot#NIL THEN vectorRoot.previous _ new; vectorRoot _ new; ENDLOOP; newFW _ VFonts.StringWidth[newFT]; newVW _ VFonts.StringWidth[newVT]; linkW _ VFonts.StringWidth[linkT]; sipW _ VFonts.StringWidth[sipT]; colorVector _ NEW[PaintVectorRec]; colorVector.color _ TRUE; END; colorInit: BOOL _ FALSE; InitialiseColorPainting: PUBLIC PROC = BEGIN ColorCriticalInit: ENTRY PROC = BEGIN colorVector.context _ ColorWorld.NewContext[]; SetDefaultFont[colorVector.context, VFonts.defaultGFont]; colorInit _ TRUE; END; ColorCriticalInit[]; ViewerOps.GreyScreen[0, 0, 9999, 9999, TRUE, FALSE]; END; ZapVector: INTERNAL PROC [p: PaintVector] = BEGIN oldContext: Context _ p.context; p.context _ IF p.color THEN ColorWorld.NewContext[] ELSE NewContext[]; Graphics.SetDefaultFont[p.context, VFonts.defaultGFont]; p.viewer _ NIL; p.inUse _ FALSE; p.process _ NIL; p.mark _ nullMark; IF ~p.color THEN usedVectors _ usedVectors - 1; GraphicsOps.Disable[oldContext]; -- smash old BROADCAST PaintVectorAvailable; END; UnWedgePainter: PUBLIC ENTRY PROC [process: PROCESS, kind: ATOM] = BEGIN ENABLE UNWIND => NULL; IF colorVector.inUse AND colorVector.process=process THEN ZapVector[colorVector] ELSE FOR p: PaintVector _ vectorRoot, p.next UNTIL p=NIL DO IF p.inUse AND p.process=process THEN ZapVector[p]; ENDLOOP; END; UnWedge: ENTRY PROC [process: PROCESS, kind: ATOM] = BEGIN IF colorVector.inUse THEN ZapVector[colorVector] ELSE FOR p: PaintVector _ vectorRoot, p.next UNTIL p=NIL DO IF p.inUse THEN ZapVector[p]; ENDLOOP; usedVectors _ 0; -- make sure paintingLock _ 0; -- make sure BROADCAST PaintVectorAvailable; END; DisablePainting: PUBLIC ENTRY PROC [wait: BOOL _ TRUE] = BEGIN ENABLE UNWIND => NULL; InternalDisablePainting[wait]; END; InternalDisablePainting: INTERNAL PROC [wait: BOOL _ TRUE] = INLINE BEGIN IF wait THEN WHILE usedVectors#0 OR colorVector.inUse DO WAIT PaintVectorAvailable; ENDLOOP; paintingLock _ paintingLock+1; END; EnablePainting: PUBLIC ENTRY PROC = BEGIN ENABLE UNWIND => NULL; InternalEnablePainting[]; END; InternalEnablePainting: INTERNAL PROC = INLINE BEGIN IF paintingLock#0 THEN paintingLock _ paintingLock-1; IF paintingLock=0 THEN BROADCAST PaintVectorAvailable; END; DisablePaintingUnWedged: INTERNAL PROC [wait: BOOL _ TRUE] = INLINE BEGIN AllWedged: INTERNAL PROC RETURNS[BOOL] = INLINE BEGIN IF colorVector.inUse THEN BEGIN IF colorVector.viewer=NIL THEN RETURN[FALSE]; -- context = screen IF ~ViewerLocks.ColumnWedged[color].wedged THEN RETURN[FALSE]; END; FOR p: PaintVector _ vectorRoot, p.next UNTIL p=NIL DO IF ~p.inUse THEN LOOP; IF p.viewer = NIL THEN RETURN[FALSE]; -- context = screen IF ~ViewerLocks.ColumnWedged[ViewerColumn[p.viewer]].wedged THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; END; IF wait THEN WHILE usedVectors#0 OR colorVector.inUse DO IF AllWedged[] THEN EXIT ELSE WAIT PaintVectorAvailable; ENDLOOP; paintingLock _ paintingLock+1; END; WaitForPaintingToFinish: PUBLIC ENTRY PROC = BEGIN WHILE usedVectors#0 AND colorVector.inUse DO WAIT PaintVectorAvailable ENDLOOP; END; ResetPaintCache: PUBLIC ENTRY PROC [viewer: Viewer _ NIL, wait: BOOL _ TRUE] = BEGIN ENABLE UNWIND => NULL; DisablePaintingUnWedged[wait]; FOR p: PaintVector _ vectorRoot, p.next UNTIL p=NIL DO IF p.inUse THEN BEGIN IF p.viewer = NIL OR ~ViewerLocks.ColumnWedged[ViewerColumn[p.viewer]].wedged THEN IF wait THEN RETURN WITH ERROR fatalViewersError; p.resetOnRelease _ TRUE; END ELSE IF p.viewer#NIL THEN BEGIN ResetContext[p.context]; p.viewer _ NIL; END; ENDLOOP; IF colorVector.context#NIL THEN BEGIN IF colorVector.inUse AND ~ViewerLocks.ColumnWedged[color].wedged THEN BEGIN IF wait THEN RETURN WITH ERROR fatalViewersError; colorVector.resetOnRelease _ TRUE; END ELSE IF colorVector.viewer#NIL THEN BEGIN ResetContext[colorVector.context]; colorVector.viewer _ NIL; END; END; InternalEnablePainting[]; END; fatalViewersError: ERROR = CODE; ReleaseContext: PUBLIC ENTRY PROC [free: Context] = BEGIN ENABLE UNWIND => NULL; CleanUp: INTERNAL PROC [p: PaintVector] = BEGIN Restore[free, p.mark]; -- throw away any client changes p.inUse _ FALSE; p.mark _ nullMark; IF ~p.color THEN {IF usedVectors=0 THEN RETURN WITH ERROR fatalViewersError ELSE usedVectors _ usedVectors-1}; IF p.resetOnRelease THEN BEGIN ResetContext[p.context]; p.viewer _ NIL; p.resetOnRelease _ FALSE; END; p.process _ NIL; BROADCAST PaintVectorAvailable; END; IF free=NIL THEN RETURN WITH ERROR fatalViewersError; IF free=colorVector.context THEN CleanUp[colorVector] ELSE FOR p: PaintVector _ vectorRoot, p.next UNTIL p=NIL DO IF free=p.context THEN {CleanUp[p]; EXIT}; ENDLOOP; END; AcquireContext: PUBLIC ENTRY PROC [viewer: Viewer, color: BOOL _ FALSE] RETURNS [allocated: Context] = BEGIN ENABLE UNWIND => NULL; bestFit: PaintVector; nil: BOOL _ FALSE; MakeFirst: INTERNAL PROC [pv: PaintVector] = INLINE BEGIN -- LRU caching scheme IF pv=vectorRoot THEN RETURN; pv.previous.next _ pv.next; IF pv.next#NIL THEN pv.next.previous _ pv.previous; pv.next _ vectorRoot; vectorRoot.previous _ pv; vectorRoot _ pv; END; IF color THEN BEGIN IF ~colorInit THEN ERROR fatalViewersError; WHILE colorVector.inUse OR paintingLock#0 DO WAIT PaintVectorAvailable; ENDLOOP; IF viewer#NIL AND (~viewer.visible OR viewer.destroyed) THEN SIGNAL InvisiblePaint; -- someone got changed while waiting in the loop above bestFit _ colorVector; END ELSE BEGIN UNTIL usedVectors<nVectors AND paintingLock=0 DO WAIT PaintVectorAvailable; ENDLOOP; IF viewer#NIL AND (~viewer.visible OR viewer.destroyed) THEN SIGNAL InvisiblePaint; -- someone got changed while waiting in the loop above FOR p: PaintVector _ vectorRoot, p.next UNTIL p=NIL DO IF p.inUse THEN LOOP; IF viewer=p.viewer THEN {bestFit _ p; EXIT} ELSE IF p.viewer=NIL THEN {bestFit _ p; nil _ TRUE} ELSE IF ~nil THEN bestFit _ p; ENDLOOP; usedVectors _ usedVectors+1; MakeFirst[bestFit]; END; bestFit.inUse _ TRUE; TRUSTED {bestFit.process _ Process.GetCurrent[]}; SetContext[viewer, bestFit]; bestFit.mark _ Save[allocated _ bestFit.context]; -- protect context END; SetContext: INTERNAL PROC [viewer: Viewer, paintVector: PaintVector] = BEGIN pViewer: Viewer = paintVector.viewer; pContext: Context = paintVector.context; RecursivelyPushParent: INTERNAL PROC [viewer: Viewer] = BEGIN IF viewer.parent#NIL THEN RecursivelyPushParent[viewer.parent]; PushContext[viewer, pContext] END; SELECT TRUE FROM -- try to efficiently set up client context pViewer=viewer => NULL; viewer=NIL => ResetContext[pContext]; pViewer=viewer.parent => PushContext[viewer, pContext]; pViewer=NIL => RecursivelyPushParent[viewer]; pViewer.destroyed => {ResetContext[pContext]; RecursivelyPushParent[viewer]}; pViewer.parent=viewer => PopContext[pContext]; pViewer.parent=viewer.parent => {PopContext[pContext]; PushContext[viewer, pContext]}; ENDCASE => {ResetContext[pContext]; RecursivelyPushParent[viewer]}; paintVector.viewer _ viewer; END; PushContext: INTERNAL PROC [viewer: Viewer, context: Context] = BEGIN OPEN viewer; invertCoords: BOOL = IF viewer.parent=NIL THEN viewer.class.coordSys=top ELSE viewer.class.coordSys#viewer.parent.class.coordSys; [] _ Save[context]; IF viewer.iconic THEN BEGIN IF wy+wh > openBottomY THEN ClipIcon[context]; ClipBox[context, XYWH2Box[wx, wy, ww, wh]]; Translate[context, wx, wy]; END ELSE IF invertCoords THEN BEGIN ClipBox[context, XYWH2Box[cx, cy, cw, ch]]; Translate[context, cx, cy+ch]; Scale[context, 1, -1]; END ELSE BEGIN ClipBox[context, XYWH2Box[cx, cy, cw, ch]]; Translate[context, cx, cy]; END; END; PopContext: INTERNAL PROC [context: Context] = INLINE BEGIN Restore[context]; END; ResetContext: INTERNAL PROC [context: Context] = INLINE BEGIN screen: Mark = LOOPHOLE[0]; Restore[context, screen]; END; InvertForMenus: PUBLIC PROC [viewer: Viewer, x,y: INTEGER, w,h: INTEGER] = BEGIN context: Context; context _ AcquireContext[viewer.parent, viewer.column=color]; [] _ SetPaintMode[context, invert]; DrawBox[context, ViewerOps.XYWH2Box[viewer.wx+x, y, w, h]]; ReleaseContext[context]; END; ClipIcon: PROC [context: Context] = BEGIN ClipOpenViewer: ViewerOps.EnumProc = BEGIN IF ~v.iconic AND (v.column=right OR v.column=left) THEN Graphics.ClipBox[context, [v.wx, v.wy, v.wx+v.ww, v.wy+v.wh], TRUE]; END; ViewerOps.EnumerateViewers[ClipOpenViewer]; END; BlinkIcon: PUBLIC PROC [viewer: Viewer, count, interval: NAT] = BEGIN IF interval >= 1000 THEN interval _ interval/1000; IF viewer.offDeskTop THEN ViewerOps.ChangeColumn[viewer, left]; IF count = 1 THEN BlinkProcess[viewer, count, interval] ELSE TRUSTED {Process.Detach[FORK BlinkProcess[viewer, count, interval]]}; END; BlinkProcess: PROC [viewer: Viewer, count, n: NAT] = BEGIN howOften: Process.Ticks = Process.MsecToTicks[500]; Blink: PROC = BEGIN OPEN viewer; context: Context; IF NOT visible OR destroyed THEN RETURN; context _ AcquireContext[viewer, IF iconic THEN FALSE ELSE column=color]; [] _ SetPaintMode[context, invert]; DrawBox[context, ViewerOps.XYWH2Box[0, 0, viewer.ww, viewer.wh]]; Process.Pause[Process.MsecToTicks[400]]; DrawBox[context, ViewerOps.XYWH2Box[0, 0, viewer.ww, viewer.wh]]; ReleaseContext[context]; Process.Pause[Process.MsecToTicks[350]]; -- so can be called back-to-back END; DO ViewerLocks.CallUnderWriteLock[Blink, viewer]; IF count = 1 THEN RETURN; IF count > 0 THEN count _ count - 1; FOR i: NAT IN [0..2*n) DO -- blink every n seconds, but wake up every half second. Process.Pause[howOften]; IF viewer.destroyed OR ~viewer.iconic OR viewer = ViewerTools.GetSelectedViewer[] THEN RETURN; ENDLOOP; ENDLOOP; END; newVT: Rope.ROPE = " [New Version]"; newVW: INTEGER; newFT: Rope.ROPE = " [New File]"; newFW: INTEGER; linkT: Rope.ROPE = " [Split]"; linkW: INTEGER; sipT: Rope.ROPE = " [Saving...]"; sipW: INTEGER; Init[]; ViewerOps.GreyScreen[0, 0, 9999, 9999, FALSE, FALSE]; END. ���ú��ViewerPaintImpl.mesa; written by S. McGregor Edited by McGregor on May 2, 1983 11:11 am Edited by Maxwell, June 3, 1983 8:23 am IF flavor is private then client wants to draw the icon do we need to paint any of the children? recursively paint children these guys should be painted in reverse order for correct overlaps call from debugger broadcast since all are likely to be free assumes interesting paints already in progress clips for overlapping top level windows given valid Context and Viewer �Êb��–"Mesa" style˜�JšÏc,™,Jš*™*J™'J™�šÏk ˜ Jšœžœ˜+Jšœžœ˜šœ žœ-˜;J˜>J˜H—Jšœžœ˜Jšœžœ˜!Jšœžœ˜Jšœžœ˜Jšœ žœ˜Jšœžœ1˜>Jšœžœžœ˜Jšœžœ*˜6J˜ J˜Jšœžœ@˜QJšœ˜J˜Jšœžœ˜&J˜�—Jšœž ˜J˜�Jšžœ˜–Jšžœ ˜'Jšžœ$˜*J˜�Jšžœžœ1˜;J˜�Jšœžœžœžœ˜%J˜�š Ïnœžœ+žœ žœžœ˜rJšžœžœ˜Jš œžœžœžœžœ˜=J˜)šžœžœž˜š žœžœžœžœ˜@J˜˜AJ˜—J˜&J˜Jšž˜—šžœž˜ Jšœ žœ˜,Jšžœžœ˜6Jšžœžœžœ˜5Jšžœžœžœ˜9Jšžœ žœžœ˜2Jšœ žœ˜J˜GJ˜J˜;J˜Jšžœžœ˜5Jšžœžœžœ˜4Jšžœžœžœ˜8Jšžœ žœžœ˜1Jšžœ˜—Jšžœ˜—š žœžœžœžœž˜'Jšœžœ˜,šžœ žœžœž˜šžœžœž˜J˜˜=J˜—Jšžœ˜—J˜˜JJ˜—Jšžœ˜—˜3J˜-—Jšžœ˜—Jšžœ˜J˜�—šŸ œžœ0žœžœžœž˜UJ˜Jšœžœ˜J˜�Jšžœžœžœžœ˜!J˜�Jšœ!žœ˜DJ˜�Jš7™7Jšžœžœ;˜VJ˜�š žœžœ žœžœž˜+Jšœ(˜Dšžœžœžœž˜FJ˜—šžœžœžœžœžœž˜TJ˜—Jšœžœ*˜8Jšžœ žœžœ˜(J˜DJ˜šžœ!žœž˜-J˜#J˜0Jšžœ˜—Jšžœ˜J˜�—J˜Jšžœ˜—J˜�š Ÿœžœžœžœž˜DJ˜-Jšžœ˜J˜�—šŸœžœ0žœ˜RJšœžœ%žœžœžœžœ˜MJšœžœ˜Jšœžœ˜Jšœ žœ˜J˜�š žœžœžœžœ˜Bšžœ žœžœž˜Jšžœžœžœžœ˜7Jšžœžœžœžœ˜7Jšž˜—Jšžœ˜—J˜�šžœ žœž˜Jš žœžœžœ žœžœ˜=J˜6Jšžœžœžœžœ˜Bš žœ žœžœ žœž˜1J˜J˜+J˜Jšœžœ˜ Jšžœ˜—šžœžœ žœž˜!Jšœžœ˜ J˜,J˜,J˜3J˜3Jšžœ˜—šžœžœžœ˜'Jšžœ@˜D—J˜Jšžœ˜J˜�—šžœ žœ žœž˜%Jš žœžœžœ žœžœ˜=Jšœ žœ8˜EJšžœžœžœžœ˜BJš žœžœžœžœžœ˜Ašžœ žœžœž˜$J˜J˜!J˜Jšžœžœžœžœ˜%Jšœžœ˜Jšœžœ˜ Jšžœ˜—Jšžœ žœžœ2˜IJ˜Jšžœ˜J˜�—Jšœ(™(šžœžœžœžœžœ˜.šžœžœ,ž˜IJšœžœ,žœžœ˜P——J˜�Jš™šžœ žœ žœž˜(JšB™Bšžœ%žœžœž˜6šžœžœžœ2˜GJš-˜-šžœ˜JšžœA˜EJšžœ=˜A—šžœžœ ž˜6Jšœ žœ žœžœ˜;——Jšœ žœ˜AJšžœ˜J˜�——Jšžœ˜J˜�—š Ÿœžœžœ9žœžœ˜]Jšœ žœžœžœž˜#šŸœžœ˜Jšžœžœžœ˜4J˜Jšžœžœžœžœ˜3Jšžœžœ(žœ˜EJ˜Jšžœžœžœžœ˜Gšœ2žœ žœ˜SJšžœ(žœ˜7—Jšœ˜—JšœOžœ˜YJšžœ˜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˜1J˜Jšžœžœžœ˜1J˜Jšžœ˜—J˜"J˜"J˜"J˜ Jšœžœ˜"Jšœžœ˜Jšžœ˜J˜�—Jšœžœžœ˜J˜�šŸœžœžœž˜,šŸœžœžœž˜%J˜.J˜9Jšœžœ˜Jšžœ˜—J˜Jšœ'žœžœ˜4Jšžœ˜J˜�—šŸ œžœžœž˜1J˜ Jšœžœ žœžœ˜FJ˜8Jšœžœ˜Jšœ žœ˜Jšœžœ˜J˜Jšžœ žœ˜/Jšœ!˜-Jšž œ˜Jšžœ˜J˜�—š Ÿœžœžœžœžœžœž˜HJšžœžœžœ˜Jšžœžœžœ˜Pš žœžœ%žœžœž˜;Jšžœ žœžœ˜3Jšžœ˜—Jšžœ˜J˜�—šŸœžœžœžœžœž˜:Jš™Jšžœžœ˜0š žœžœ%žœžœž˜;Jšžœ žœ˜Jšžœ˜—Jšœ˜Jšœ˜Jšž œ˜Jšžœ˜J˜�—š Ÿœžœžœžœžœžœž˜>Jšžœžœžœ˜J˜Jšžœ˜š Ÿœžœžœžœžœžœž˜Išžœž˜Jšžœžœžœžœ˜GJšžœ˜J˜—Jšžœ˜J˜�——š Ÿœžœžœžœž˜)Jšžœžœžœ˜J˜Jšžœ˜š Ÿœžœžœžœž˜4Jšžœžœ˜5Jš)™)Jšžœžœž œ˜6Jšžœ˜——J˜�š Ÿœžœžœžœžœžœž˜Iš Ÿ œžœžœžœžœžœž˜5šžœžœž˜Jšžœžœžœžœžœ˜AJšžœ)žœžœžœ˜>Jšžœ˜—šžœ%žœžœž˜6Jšžœ žœžœ˜Jšžœžœžœžœžœ˜9Jšžœ:žœžœžœ˜OJšžœ˜—Jšžœžœ˜ Jšžœ˜J˜�—šžœž˜šžœžœžœ˜,Jš žœ žœžœžœžœ˜9—Jšžœ˜J˜—Jšžœ˜J˜�—š Ÿœžœžœžœž˜2Jš.™.Jš žœžœžœžœžœ˜OJšžœ˜J˜�—šŸœžœžœžœžœžœžœž˜TJšžœžœžœ˜J˜šžœ%žœžœž˜6šžœ žœž˜šžœžœžœ:˜NJš žœžœžœžœžœ˜6—Jšœžœ˜Jšž˜—š žœžœ žœžœž˜J˜Jšœžœ˜Jšžœ˜—Jšžœ˜—šžœžœžœž˜%šžœžœ'žœž˜KJš žœžœžœžœžœ˜1Jšœžœ˜"Jšž˜—š žœžœžœžœž˜)J˜"Jšœžœ˜Jšžœ˜—Jšžœ˜—J˜Jšžœ˜J˜�—Jšœžœžœ˜ J˜�š Ÿœžœžœžœž˜9Jšžœžœžœ˜šŸœžœžœž˜/Jšœ ˜7Jšœ žœ˜J˜šžœ žœžœžœžœžœžœ˜KJšžœ˜"—šžœžœž˜J˜Jšœžœ˜Jšœžœ˜Jšžœ˜—Jšœžœ˜Jšž œ˜Jšžœ˜—Jšžœžœžœžœžœžœ˜5Jšžœžœ˜5š žœžœ%žœžœž˜;Jšžœžœžœ˜*Jšžœ˜—Jšžœ˜J˜�—šŸœžœžœžœžœžœ˜GJšžœž˜$Jšžœžœžœ˜J˜Jšœžœžœ˜J˜�šŸ œžœžœžœžœ˜OJšžœžœžœ˜J˜Jšžœ žœžœ ˜3J˜J˜J˜Jšžœ˜J˜�—šžœžœž˜Jšžœžœžœ˜+Jš žœžœžœžœžœ˜Pš žœžœžœžœž˜<Jšžœ6˜M—J˜Jšž˜J˜�—šžœž˜ Jš žœžœžœžœžœ˜Tš žœžœžœžœž˜<Jšžœ6˜M—šžœ%žœžœž˜6Jšžœ žœžœ˜Jšžœžœžœ˜+Jš žœžœ žœžœžœ˜3Jšžœžœžœ ˜Jšžœ˜—J˜J˜Jšžœ˜J˜�—Jšœžœ˜Jšžœ*˜1J˜Jšœ2˜DJšžœ˜J˜�—šŸ œžœžœ.ž˜LJ˜%J˜(J˜�šŸœžœžœž˜=Jšžœžœžœ&˜?J˜Jšžœ˜J˜�—šžœžœžœ+˜<Jšœžœ˜Jšœžœ˜(J˜7Jšœžœ%˜0JšœN˜NJšœ.˜.J˜VJšžœ@˜GJ˜�—J˜Jšžœ˜J˜�—š Ÿœžœžœ&žœžœ˜Rš œžœžœžœžœ˜HJšžœ4˜8—J˜šžœžœž˜Jšžœžœ˜.J˜+J˜Jšž˜—šžœžœžœž˜J˜+J˜J˜Jšž˜—šžœž˜ J˜+J˜Jšžœ˜—Jšžœ˜J˜�—š Ÿ œžœžœžœž˜;J˜Jšžœ˜J˜�—š Ÿœžœžœžœž˜=Jšœžœ˜J˜Jšžœ˜J˜�—šŸœžœžœžœžœž˜PJ˜J˜=J˜#J˜;J˜Jšžœ˜J˜�—šŸœžœž˜)JšF™Fšœ%ž˜*šžœžœžœž˜7Jšœ>žœ˜D—Jšžœ˜—J˜+Jšžœ˜J˜�—šŸ œžœ#žœž˜EJ˜2Jšžœžœ&˜?Jšžœžœ&˜7Jšžœžœžœ)˜JJšžœ˜J˜�—šŸœžœžœž˜;Jšœ3˜3šŸœžœž œ˜ J˜Jš žœžœ žœžœžœ˜(Jš œ!žœžœžœžœ˜IJ˜#J˜AJ˜(J˜AJ˜Jšœ) ˜IJšžœ˜J˜�—šž˜J˜.Jšžœžœžœ˜Jšžœžœ˜$š žœžœžœ žœ8˜SJšœ˜šžœžœ˜&Jšžœ*žœžœ˜8—Jšžœ˜—Jšžœ˜—Jšžœ˜J˜�—J˜�Jšœžœ˜%Jšœžœ˜J˜�Jšœžœ˜"Jšœžœ˜J˜�Jšœžœ˜Jšœžœ˜J˜�Jšœžœ˜"Jšœžœ˜J˜�J˜J˜�Jšœ'žœžœ˜5J˜�Jšžœ˜J˜�J˜�—�…—����EZ��^¶��