DIRECTORY Atom USING [DottedPair, DottedPairNode, PropList], Basics USING [bitsPerWord], Font USING [CreateScaled], Imager USING [Box, Color, ConstantColor, Context, ErrorCode, FONT, Matrix, Pair, PathProc, StrokeEnd, Trajectory, TrajectoryList, TrajectoryRep, Transformation], ImagerBasic USING [ColorRep, PixelArray], ImagerConic USING [FromArc], ImagerMasks USING [PixelArrayFromPixelMap], ImagerPixelMaps USING [Create, PixelMap], ImagerTransform USING [Concat, Contents, FromRec, InverseTransform, InverseTransformVec, Invert, Rotate, Scale, Scale2, Transform, TransformVec, Translate], PrincOps USING [BBTableSpace, BBptr], PrincOpsUtils USING [AlignedBBTable, BITBLT], Real USING [RoundLI], Rope USING [ROPE]; ImagerImpl: CEDAR PROGRAM IMPORTS Font, ImagerConic, ImagerMasks, ImagerPixelMaps, ImagerTransform, PrincOpsUtils, Real EXPORTS Imager ~ BEGIN OPEN Imager; ROPE: TYPE ~ Rope.ROPE; Create: PUBLIC PROC[deviceType: ATOM, data: REF _ NIL] RETURNS [Context] ~ { ERROR; }; Error: PUBLIC ERROR[errorCode: ErrorCode] ~ CODE; DoSave: PUBLIC PROC[context: Context, body: PROC] ~ { context.class.DoSave[context, body]; }; DoSaveAll: PUBLIC PROC[context: Context, body: PROC] ~ { context.class.DoSaveAll[context, body]; }; SetPriorityImportant: PUBLIC PROC[context: Context, priorityImportant: BOOL] ~ { context.class.SetPriorityImportant[context, priorityImportant]; }; PropList: TYPE ~ Atom.PropList; DottedPair: TYPE ~ Atom.DottedPair; DottedPairNode: TYPE ~ Atom.DottedPairNode; RemPropFromList: PROC[p: PropList, key: REF] RETURNS[PropList] ~ { IF p=NIL THEN RETURN[NIL] ELSE IF p.first.key=key THEN RETURN[p.rest] ELSE { rest: PropList ~ RemPropFromList[p.rest, key]; IF rest=p.rest THEN RETURN[p] ELSE RETURN[CONS[p.first, rest]]; }; }; PutPropOnList: PROC[p: PropList, key: REF, value: REF] RETURNS[PropList] ~ { rest: PropList ~ RemPropFromList[p, key]; IF value=NIL THEN RETURN[rest] ELSE { pair: DottedPair ~ NEW[DottedPairNode _ [key, value]]; RETURN[CONS[pair, rest]]; }; }; GetPropFromList: PROC[p: PropList, key: REF] RETURNS[value: REF] ~ { FOR list: PropList _ p, list.rest UNTIL list=NIL DO pair: DottedPair ~ list.first; IF pair.key=key THEN RETURN[pair.val]; ENDLOOP; RETURN[NIL]; }; GetProp: PUBLIC PROC[context: Context, key: REF] RETURNS[value: REF] ~ { RETURN[GetPropFromList[context.propList, key]]; }; PutProp: PUBLIC PROC[context: Context, key: REF, value: REF] ~ { context.propList _ PutPropOnList[context.propList, key, value]; }; RemProp: PUBLIC PROC[context: Context, key: REF] ~ { context.propList _ RemPropFromList[context.propList, key]; }; MakeT: PUBLIC PROC[m: Matrix] RETURNS[Transformation] ~ { RETURN[ImagerTransform.FromRec[m]] }; OpenT: PUBLIC PROC[m: Transformation] RETURNS[Matrix] ~ { RETURN[ImagerTransform.Contents[m]]; }; Scale: PUBLIC PROC[s: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Scale[s]]; }; Scale2: PUBLIC PROC[sx, sy: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Scale2[sx, sy]]; }; Rotate: PUBLIC PROC[a: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Rotate[a]]; }; Translate: PUBLIC PROC[x, y: REAL] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Translate[x, y]]; }; Concat: PUBLIC PROC[m, n: Transformation] RETURNS[Transformation] ~ { RETURN[ImagerTransform.Concat[m, n]]; }; Invert: PUBLIC PROC[m: Transformation] RETURNS[Transformation] ~ { RETURN [ImagerTransform.Invert[m]] }; Transform: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.Transform[p, m]] }; TransformVec: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.TransformVec[p, m]] }; InverseTransform: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.InverseTransform[p, m]] }; InverseTransformVec: PUBLIC PROC[m: Transformation, p: Pair] RETURNS[Pair] ~ { RETURN[ImagerTransform.InverseTransformVec[p, m]] }; ConcatT: PUBLIC PROC[context: Context, m: Transformation] ~ { context.class.ConcatT[context, m]; }; ScaleT: PUBLIC PROC[context: Context, s: REAL] ~ { context.class.ScaleT[context, s]; }; Scale2T: PUBLIC PROC[context: Context, sx, sy: REAL] ~ { context.class.Scale2T[context, sx, sy]; }; RotateT: PUBLIC PROC[context: Context, a: REAL] ~ { context.class.RotateT[context, a]; }; TranslateT: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.TranslateT[context, x, y]; }; Move: PUBLIC PROC[context: Context] ~ { context.class.Move[context]; }; Trans: PUBLIC PROC[context: Context] ~ { context.class.Trans[context]; }; LastPoint: PUBLIC PROC[t: Trajectory] RETURNS[x, y: REAL] ~ { RETURN[t.lp.x, t.lp.y]; }; LastPointP: PUBLIC PROC[t: Trajectory] RETURNS[Pair] ~ { RETURN[t.lp]; }; MoveTo: PUBLIC PROC[x, y: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[move] _ [prev: NIL, lp: [x, y], variant: move[]]]]; }; MoveToP: PUBLIC PROC[p: Pair] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[move] _ [prev: NIL, lp: p, variant: move[]]]]; }; LineTo: PUBLIC PROC[t: Trajectory, x, y: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: [x, y], variant: line[]]]]; }; LineToP: PUBLIC PROC[t: Trajectory, p: Pair] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: p, variant: line[]]]]; }; LineToX: PUBLIC PROC[t: Trajectory, x: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: [x, t.lp.y], variant: line[]]]]; }; LineToY: PUBLIC PROC[t: Trajectory, y: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[line] _ [prev: t, lp: [t.lp.x, y], variant: line[]]]]; }; CurveTo: PUBLIC PROC[t: Trajectory, x1, y1, x2, y2, x3, y3: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[curve] _ [prev: t, lp: [x3, y3], variant: curve[[x1, y1], [x2, y2]]]]]; }; CurveToP: PUBLIC PROC[t: Trajectory, p1, p2, p3: Pair] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[curve] _ [prev: t, lp: p3, variant: curve[p1, p2]]]]; }; ConicTo: PUBLIC PROC[t: Trajectory, x1, y1, x2, y2: REAL, r: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[conic] _ [prev: t, lp: [x2, y2], variant: conic[[x1, y1], r]]]]; }; ConicToP: PUBLIC PROC[t: Trajectory, p1, p2: Pair, r: REAL] RETURNS[Trajectory] ~ { RETURN[NEW[TrajectoryRep[conic] _ [prev: t, lp: p2, variant: conic[p1, r]]]]; }; ArcTo: PUBLIC PROC[t: Trajectory, x1, y1, x2, y2: REAL] RETURNS[Trajectory] ~ { conic: PROC[p1, p2: Pair, r: REAL] ~ {t _ ConicToP[t, p1, p2, r]}; ImagerConic.FromArc[t.lp, [x1, y1], [x2, y2], conic]; RETURN[t]; }; ArcToP: PUBLIC PROC[t: Trajectory, p1, p2: Pair] RETURNS[Trajectory] ~ { conic: PROC[p1, p2: Pair, r: REAL] ~ {t _ ConicToP[t, p1, p2, r]}; ImagerConic.FromArc[t.lp, p1, p2, conic]; RETURN[t]; }; MapTrajectory: PUBLIC PathProc ~ { WITH data SELECT FROM end: Trajectory => { move[end.lp]; FOR t: Trajectory _ end, t.prev UNTIL t.prev=NIL DO p0: Pair ~ t.prev.lp; WITH t SELECT FROM t: REF TrajectoryRep[move] => ERROR; -- should have had t.prev=NIL t: REF TrajectoryRep[line] => line[p0]; t: REF TrajectoryRep[curve] => curve[t.p2, t.p1, p0]; t: REF TrajectoryRep[conic] => conic[t.p1, p0, t.r]; ENDCASE => ERROR; -- unknown variant ENDLOOP; }; ENDCASE => ERROR; -- data is wrong type or NIL }; MapTrajectoryList: PUBLIC PathProc ~ { WITH data SELECT FROM head: TrajectoryList => { FOR list: TrajectoryList _ head, list.rest UNTIL list=NIL DO t: Trajectory ~ list.first; MapTrajectory[t, move, line, curve, conic]; ENDLOOP; }; ENDCASE => ERROR; -- data is wrong type or NIL }; MaskFill: PUBLIC PROC[context: Context, outline: REF] ~ { WITH outline SELECT FROM t: Trajectory => context.class.MaskFill[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.MaskFill[context, MapTrajectoryList, tlist]; ENDCASE => ERROR Error[$InvalidOutline]; -- outline is wrong type or NIL }; MaskFillPath: PUBLIC PROC[context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.MaskFill[context, pathProc, pathData]; }; SetStrokeWidth: PUBLIC PROC[context: Context, strokeWidth: REAL] ~ { context.class.SetStrokeWidth[context, strokeWidth]; }; SetStrokeEnd: PUBLIC PROC[context: Context, strokeEnd: StrokeEnd] ~ { context.class.SetStrokeEnd[context, strokeEnd]; }; MaskStroke: PUBLIC PROC[context: Context, stroke: REF] ~ { WITH stroke SELECT FROM t: Trajectory => context.class.MaskStroke[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.MaskStroke[context, MapTrajectoryList, tlist]; ENDCASE => ERROR Error[$InvalidStroke]; -- stroke is wrong type or NIL }; MaskStrokeClosed: PUBLIC PROC[context: Context, stroke: REF] ~ { WITH stroke SELECT FROM t: Trajectory => context.class.MaskStrokeClosed[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.MaskStrokeClosed[context, MapTrajectoryList, tlist]; ENDCASE => ERROR Error[$InvalidStroke]; -- stroke is wrong type or NIL }; MaskStrokePath: PUBLIC PROC[ context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.MaskStroke[context, pathProc, pathData]; }; MaskStrokeClosedPath: PUBLIC PROC[ context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.MaskStrokeClosed[context, pathProc, pathData]; }; MaskRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { context.class.MaskRectangle[context: context, x: x, y: y, w: w, h: h]; }; MaskBox: PUBLIC PROC[context: Context, box: Box] ~ { context.class.MaskRectangle[context: context, x: box.xmin, y: box.ymin, w: box.xmax-box.xmin, h: box.ymax-box.ymin]; }; MaskVector: PUBLIC PROC[context: Context, x1, y1, x2, y2: REAL] ~ { context.class.MaskVector[context: context, x1: x1, y1: y1, x2: x2, y2: y2]; }; MaskVectorP: PUBLIC PROC[context: Context, p1, p2: Pair] ~ { context.class.MaskVector[context: context, x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y]; }; SetXY: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetXY[context, x, y]; }; SetXYP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetXY[context, p.x, p.y]; }; SetXYRel: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetXYRel[context, x, y]; }; SetXYRelP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetXYRel[context, p.x, p.y]; }; SetXRel: PUBLIC PROC[context: Context, x: REAL] ~ { context.class.SetXYRel[context, x, 0]; }; SetYRel: PUBLIC PROC[context: Context, y: REAL] ~ { context.class.SetXYRel[context, 0, y]; }; FindFont: PUBLIC PROC[name: ROPE] RETURNS[FONT] ~ { RETURN[NIL]; }; ModifyFont: PUBLIC PROC[font: FONT, m: Transformation] RETURNS[FONT] ~ { RETURN[NIL]; }; MakeFont: PUBLIC PROC[name: ROPE, size: REAL] RETURNS[FONT] ~ { RETURN[Font.CreateScaled[name, size]]; }; SetFont: PUBLIC PROC[context: Context, font: FONT] ~ { context.class.SetFont[context, font]; }; ShowRope: PUBLIC PROC[context: Context, rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] ~ { context.class.ShowRope[context, rope, start, len]; }; ShowText: PUBLIC PROC[context: Context, text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST] ~ { context.class.ShowText[context, text, start, len]; }; ShowChar: PUBLIC PROC[context: Context, char: CHAR] ~ { context.class.ShowChar[context, char]; }; SetAmplifySpace: PUBLIC PROC[context: Context, amplifySpace: REAL] ~ { context.class.SetAmplifySpace[context, amplifySpace]; }; StartUnderline: PUBLIC PROC[context: Context] ~ { context.class.StartUnderline[context]; }; MaskUnderline: PUBLIC PROC[context: Context, dy, h: REAL] ~ { context.class.MaskUnderline[context, dy, h]; }; CorrectMask: PUBLIC PROC[context: Context] ~ { context.class.CorrectMask[context]; }; CorrectSpace: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.CorrectSpace[context, x, y]; }; CorrectSpaceP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.CorrectSpace[context, p.x, p.y]; }; Correct: PUBLIC PROC[context: Context, body: PROC] ~ { context.class.Correct[context, body]; }; SetCorrectMeasure: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetCorrectMeasure[context, x, y]; }; SetCorrectMeasureP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetCorrectMeasure[context, p.x, p.y]; }; SetCorrectTolerance: PUBLIC PROC[context: Context, x, y: REAL] ~ { context.class.SetCorrectTolerance[context, x, y]; }; SetCorrectToleranceP: PUBLIC PROC[context: Context, p: Pair] ~ { context.class.SetCorrectTolerance[context, p.x, p.y]; }; SetCorrectShrink: PUBLIC PROC[context: Context, correctShrink: REAL] ~ { context.class.SetCorrectShrink[context, correctShrink]; }; Space: PUBLIC PROC[context: Context, x: REAL] ~ { context.class.Space[context, x]; }; PixelArray: TYPE ~ ImagerBasic.PixelArray; MakePixelArrayFromBits: PUBLIC PROC[ bitPointer: LONG POINTER TO PACKED ARRAY [0..0) OF [0..1], bitsPerLine, samplesPerLine, numberOfLines: NAT] RETURNS [pixelArray: PixelArray] ~ TRUSTED { pixelMap: ImagerPixelMaps.PixelMap _ ImagerPixelMaps.Create[0, [0, 0, numberOfLines, samplesPerLine]]; bbTableSpace: PrincOps.BBTableSpace; bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace]; bb^ _ [ dst: [word: pixelMap.refRep.pointer, bit: 0], dstBpl: pixelMap.refRep.rast*Basics.bitsPerWord, src: [word: bitPointer, bit: 0], srcDesc: [srcBpl[bitsPerLine]], height: numberOfLines, width: samplesPerLine, flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: null, dstFunc: null] ]; PrincOpsUtils.BITBLT[bb]; pixelArray _ ImagerMasks.PixelArrayFromPixelMap[pixelMap]; pixelArray.m _ pixelArray.m.Concat[ImagerTransform.Rotate[-90]].Concat[ImagerTransform.Translate[0, numberOfLines]]; }; MaskPixel: PUBLIC PROC[context: Context, pa: PixelArray] ~ { context.class.MaskPixel[context, pa]; }; Card: PROC[real: REAL] RETURNS[card: CARDINAL] ~ { int: INT _ Real.RoundLI[real*LAST[CARDINAL]]; card _ MAX[MIN[int, LAST[CARDINAL]], 0]; }; MakeGray: PUBLIC PROC[f: REAL] RETURNS[ConstantColor] ~ { IF f<0 OR f>1 THEN ERROR Error[$GrayParameterOutOfRange]; RETURN[NEW[ImagerBasic.ColorRep[constant] _ [constant[x: Card[0.3101], y: Card[0.3163], Y: Card[1-f]]]]]; }; black: PUBLIC ConstantColor _ MakeGray[1]; white: PUBLIC ConstantColor _ MakeGray[0]; Color: TYPE ~ REF ImagerBasic.ColorRep; SetSampledColor: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, colorOperator: ATOM _ $Intensity] ~ { context.class.SetSampledColor[context, pa, pixelT, colorOperator]; }; SetSampledBlack: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, transparent: BOOL _ FALSE] ~ { context.class.SetSampledBlack[context, pa, pixelT, transparent]; }; SetColor: PUBLIC PROC[context: Context, color: Color] ~ { context.class.SetColor[context, color]; }; SetGray: PUBLIC PROC[context: Context, f: REAL] ~ { context.class.SetGray[context, f]; }; ClipOutline: PUBLIC PROC[context: Context, outline: REF] ~ { WITH outline SELECT FROM t: Trajectory => context.class.ClipOutline[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.ClipOutline[context, MapTrajectoryList, tlist]; ENDCASE => ERROR Error[$InvalidOutline]; -- outline is wrong type or NIL }; ClipOutlinePath: PUBLIC PROC[context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.ClipOutline[context, pathProc, pathData]; }; ExcludeOutline: PUBLIC PROC[context: Context, outline: REF] ~ { WITH outline SELECT FROM t: Trajectory => context.class.ExcludeOutline[context, MapTrajectory, t]; tlist: TrajectoryList => context.class.ExcludeOutline[context, MapTrajectoryList, tlist]; ENDCASE => ERROR Error[$InvalidOutline]; -- outline is wrong type or NIL }; ExcludeOutlinePath: PUBLIC PROC[context: Context, pathProc: PathProc, pathData: REF _ NIL] ~ { context.class.ExcludeOutline[context, pathProc, pathData]; }; ClipRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { context.class.ClipRectangle[context, x, y, w, h]; }; ExcludeRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { context.class.ExcludeRectangle[context, x, y, w, h]; }; END. ΊImagerImpl.mesa Michael Plass, February 20, 1984 9:15:15 am PST Doug Wyatt, July 3, 1984 3:25:43 pm PDT Imager contexts Creation For making a new context. The data field is optional; its type is dependent on the deviceType. Errors State The state of the imager is contained in two places: the page image, and the imager variables. The variables differ in their treatment by the Do-operators below: the non-persistent variables are restored by DoSave; all variables are restored by DoSaveAll. Priority Property lists The Imager's property list mechanism regards a PropList as an immutable value. We don't use the procedures from Atom since 1) they might smash an existing PropList, and 2) they hold a global monitor in AtomImpl. Transformations Creating transformations Applying transformations The current transformation Mask operators Trajectories PathProc: TYPE ~ PROC[ data: REF, moveTo: PROC[x, y: REAL], lineTo: PROC[x, y: REAL], curveTo: PROC[x1, y1, x2, y2, x3, y3: REAL], conicTo: PROC[x1, y1, x2, y2: REAL, r: REAL], arcTo: PROC[x1, y1, x2, y2: REAL] ]; t: REF TrajectoryRep[arc] => arc[t.p1, p0]; Outlines path: PATH => context.class.MaskFill[context, MapPath, path]; Strokes path: PATH => context.class.MaskStroke[context, MapPath, path]; path: PATH => context.class.MaskStrokeClosed[context, MapPath, path]; Rectangles and vectors Text Current position operators The imaging operators make it easy to locate a graphical object such as a character at the current position. The current position is measured in the view coordinate system, and is recorded in two persistent imager variables, cpx and cpy. It is by altering the current position that an operator displaying a character specifies where the next character on the text line should usually lie. The following operators change the current position. Character operators Underlining Character strings can be underlined by placing a rectangle of appropriate width and height just below the string. The width of the rectangle will be determined by the width of the character string. The position of the underline along the baseline will be determined by the current position, but because of spacing corrections the current position cannot be anticipated accurately when the master is created. The operators StartUnderline and MaskUnderline are provided to help position underlines accurately. They assume a master coordinate system in which the baseline is oriented in the positive x direction. Spacing correction Pixel arrays Color The color that will be deposited on the page image is determined by the value of the color variable when a mask operator is invoked. Wherever the mask allows it, the color specified by the imager variable color is deposited on the page image, obliterating any color previously laid down at the same position on the page. There are two ways to specify color: a constant color, and color sampled on a raster. A value of type Color fully specifies a color; a subtype ConstantColor is used for constant colors (ConstantColor widens to Color). Constant color Sampled color The current color Clipping path: PATH => context.class.MaskFill[context, MapPath, path]; path: PATH => context.class.MaskFill[context, MapPath, path]; Κ/˜šœ™J™/Jšœ'™'J™—šΟk ˜ Jšœœ(˜2Jšœœ˜Jšœœ˜Jšœœ1œ`˜‘Jšœ œ˜)Jšœ œ ˜Jšœ œ˜+Jšœœ˜)Jšœœ‡˜œJšœ œ˜%Jšœœœ˜-Jšœœ ˜Jšœœœ˜J˜—Jšœ œ˜JšœV˜]Jšœ˜Jšœœœ˜J˜Jšœœœ˜head™™šΟnœœœ œœœœ˜LJšœ™JšœD™DJšœ˜J˜J˜——™Jšœœœœ˜1—™šœ]™]J™—™ J™—šžœœœœ˜5Jšœ$˜$J˜J˜—šž œœœœ˜8Jšœ'˜'J˜J˜J˜——™šžœœœ&œ˜PJšœ?˜?J˜J˜——™Jšœ œ˜Jšœ œ˜#Jšœœ˜+J˜šœΤ™ΤJ™—šžœœœœ˜BJš œœœœœ˜Jšœœœœ˜+šœ˜Jšœ.˜.Jšœ œœ˜Jšœœœ˜!J˜—Jšœ˜J˜—š ž œœœ œœ˜LJšœ)˜)Jšœœœœ˜šœ˜Jšœœ ˜6Jšœœ˜J˜—Jšœ˜J˜—š žœœœœœ˜Dšœœœ˜3Jšœ˜Jšœœœ ˜&Jšœ˜—Jšœœ˜ Jšœ˜J˜—š žœœœœœœ˜HJšœ)˜/J˜J˜—š žœœœœ œ˜@Jšœ?˜?J˜J˜—šžœœœœ˜4Jšœ:˜:Jšœ˜J˜—J˜——šœ™™šžœœœ œ˜9Jšœ˜"J˜J˜—šžœœœœ ˜9Jšœ˜$J˜J˜—J˜š žœœœœœ˜7Jšœ˜!J˜J˜—š žœœœ œœ˜=Jšœ!˜'J˜J˜—š žœœœœœ˜8Jšœ˜"J˜J˜—š ž œœœœœ˜>Jšœ"˜(J˜J˜—J˜šžœœœœ˜EJšœ˜%J˜J˜—šžœœœœ˜BJšœ˜"J˜J˜J˜——™šž œœœœ ˜DJšœ!˜'J˜J˜—šž œœœœ ˜GJšœ$˜*J˜J˜J˜—šžœœœœ ˜KJšœ(˜.J˜J˜—šžœœœœ ˜NJšœ+˜1J˜J˜J™——™J˜šžœœœ)˜=J˜"J˜J˜—šžœœœœ˜2Jšœ!˜!J˜J™—šžœœœœ˜8Jšœ'˜'J˜J˜—šžœœœœ˜3Jšœ"˜"J˜J˜—šž œœœœ˜9Jšœ(˜(J˜J™J™—šžœœœ˜'Jšœ˜J˜J™—šžœœœ˜(Jšœ˜J˜J˜———šœ™™ J™š ž œœœœœ˜=Jšœ˜J˜J™—šž œœœœ ˜8Jšœ˜ J˜J™—š žœœœœœ˜7Jšœœœ!˜LJ˜J™—šžœœœ œ˜5Jšœœœ˜GJ˜J™—š žœœœœœ˜FJšœœ@˜JJ˜J™—šžœœœœ˜DJšœœ;˜EJ˜J™—š žœœœœœ˜DJšœœE˜OJ˜J™—š žœœœœœ˜DJšœœE˜OJ˜J™—š žœœœ(œœ˜YJšœœV˜`J˜J˜—šžœœœ"œ˜NJšœœD˜NJ˜J˜—š žœœœ œœœ˜ZJšœœO˜YJ˜J˜—š žœœœ!œœ˜SJšœœC˜MJ˜J˜—š žœœœ œœ˜OJšœœœ!˜BJšœ5˜5Jšœ˜ J˜J˜—šžœœœœ˜HJšœœœ!˜BJšœ)˜)Jšœ˜ J˜J˜—šœ œœ™Jšœœ™ Jšœœœ™Jšœœœ™Jšœ œœ™,Jšœ œœœ™-Jšœœœ™!Jšœ™J™—šœœ ˜"šœœ˜šœ˜J˜ šœœœ˜3J˜šœœ˜JšœœœΟc˜BJšœœ!˜'Jšœœ/˜5Jšœœ.˜4Jšœœ%™+JšœœŸ˜$—Jšœ˜—J˜—JšœœŸ˜.—J˜J˜—šœœ ˜&šœœ˜šœ˜šœ(œœ˜Jšœ6˜6J˜J˜—šžœœœ˜"Jšœ0œœ˜>Jšœ<˜Jšœ3˜3J˜J˜—šžœœœœ˜BJšœ1˜1J˜—šžœœœ˜@Jšœ5˜5J˜J˜—šžœœœ"œ˜HJšœ7˜7J˜J˜—šžœœœœ˜1Jšœ ˜ J˜J˜———™ šœ œ˜*J˜—šžœœœ˜$Jš œ œœœœœœ˜:Jšœ,œ˜0Jšœœ˜,Jšœf˜fJ˜$JšœA˜Ašœ˜Jšœ-˜-Jšœ0˜0Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ&œœœ˜kJ˜—Jšœœ˜Jšœ:˜:Jšœt˜tJ˜J˜—šž œœœ&˜