DIRECTORY Basics USING [bitsPerWord, LongMult], ImagerColor, ImagerDevice USING [Class, ClassRep, Device, DeviceRep, HalftoneParameters, RunProc], ImagerPixelArray, ImagerPixelArrayPrivate, ImagerPixelMap USING [DeviceRectangle, Function, PixelMap], ImagerTransformation, PrincOps USING [BBTableSpace, BitBltTable, BitBltTablePtr, zBNDCK, zINC], PrincOpsUtils USING [AlignedBBTable, BITBLT], Vector2 USING [VEC]; ImagerLFDeviceImpl: CEDAR PROGRAM IMPORTS Basics, ImagerColor, ImagerTransformation, PrincOpsUtils ~ BEGIN Device: TYPE ~ ImagerDevice.Device; RunProc: TYPE ~ ImagerDevice.RunProc; HalftoneParameters: TYPE ~ ImagerDevice.HalftoneParameters; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; VEC: TYPE ~ Vector2.VEC; Transformation: TYPE ~ ImagerTransformation.Transformation; Color: TYPE ~ ImagerColor.Color; ConstantColor: TYPE ~ ImagerColor.ConstantColor; SampledColor: TYPE ~ ImagerColor.SampledColor; ColorOperator: TYPE ~ ImagerColor.ColorOperator; GrayArray: TYPE ~ ARRAY [0..16) OF CARDINAL; grayHeight: NAT ~ 16; -- must not exceed 16, should be a power of 2 checkeredGray: GrayArray ~ [ 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH, -- @ . @ . @ . @ . @ . @ . @ . @ . 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH, -- @ . @ . @ . @ . @ . @ . @ . @ . 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH, -- @ . @ . @ . @ . @ . @ . @ . @ . 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH, -- @ . @ . @ . @ . @ . @ . @ . @ . 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH, -- @ . @ . @ . @ . @ . @ . @ . @ . 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH, -- @ . @ . @ . @ . @ . @ . @ . @ . 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH, -- @ . @ . @ . @ . @ . @ . @ . @ . 05555H, -- . @ . @ . @ . @ . @ . @ . @ . @ 0AAAAH -- @ . @ . @ . @ . @ . @ . @ . @ . ]; desktopGray: GrayArray ~ [ 01111H, -- . . . @ . . . @ . . . @ . . . @ 01111H, -- . . . @ . . . @ . . . @ . . . @ 04444H, -- . @ . . . @ . . . @ . . . @ . . 04444H, -- . @ . . . @ . . . @ . . . @ . . 01111H, -- . . . @ . . . @ . . . @ . . . @ 01111H, -- . . . @ . . . @ . . . @ . . . @ 04444H, -- . @ . . . @ . . . @ . . . @ . . 04444H, -- . @ . . . @ . . . @ . . . @ . . 01111H, -- . . . @ . . . @ . . . @ . . . @ 01111H, -- . . . @ . . . @ . . . @ . . . @ 04444H, -- . @ . . . @ . . . @ . . . @ . . 04444H, -- . @ . . . @ . . . @ . . . @ . . 01111H, -- . . . @ . . . @ . . . @ . . . @ 01111H, -- . . . @ . . . @ . . . @ . . . @ 04444H, -- . @ . . . @ . . . @ . . . @ . . 04444H -- . @ . . . @ . . . @ . . . @ . . ]; Case: TYPE ~ {nil, constant, gray, sampled}; defaultHalftone: HalftoneParameters _ [dotsPerInch: 18, angle: 30, shape: 0.5]; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD[ frame: ImagerPixelMap.PixelMap, -- the bitmap pixelsPerInch: REAL, -- declared resolution case: Case _ nil, -- what type of color function: ImagerPixelMap.Function _ [null, null], -- bitblt function gray: GrayArray _ ALL[0] -- bitblt gray block ]; class: ImagerDevice.Class ~ NEW[ImagerDevice.ClassRep _ [ type: $LFDisplay, SetColor: SetColor, SetPriority: SetPriority, SetHalftone: SetHalftone, MaskRuns: MaskRuns ]]; defaultPixelsPerInch: REAL ~ 72; Create: PUBLIC PROC[frame: ImagerPixelMap.PixelMap, pixelsPerInch: REAL _ defaultPixelsPerInch] RETURNS[Device] ~ { data: Data ~ NEW[DataRep _ [frame: frame, pixelsPerInch: pixelsPerInch]]; surfaceToDevice: Transformation ~ ImagerTransformation.Translate[[frame.sSize, 0]]; surfaceToDevice.ApplyPreRotate[90]; RETURN[NEW[ImagerDevice.DeviceRep _ [class: class, clipBox: [sMin: 0, fMin: 0, sSize: frame.sSize, fSize: frame.fSize], surfaceToDevice: surfaceToDevice, surfaceUnitsPerInch: [pixelsPerInch, pixelsPerInch], surfaceUnitsPerPixel: 1, data: data]]]; }; SetColor: PROC[device: Device, color: Color, viewToDevice: Transformation] ~ { data: Data ~ NARROW[device.data]; WITH color SELECT FROM color: ConstantColor => { data.function _ [null, null]; SELECT color FROM ImagerColor.black => { data.gray _ ALL[177777B]; data.case _ constant }; ImagerColor.white => { data.gray _ ALL[0]; data.case _ constant }; ENDCASE => { data.gray _ checkeredGray; data.case _ gray }; }; ENDCASE => ERROR; -- unknown color variant }; SetPriority: PROC[device: Device, priorityImportant: BOOL] ~ { }; SetHalftone: PROC[device: Device, halftone: HalftoneParameters] ~ { data: Data ~ NARROW[device.data]; }; nullBitBltTable: PrincOps.BitBltTable ~ [ dst: [word: NIL, bit: 0], dstBpl: 0, src: [word: NIL, bit: 0], srcDesc: [srcBpl[0]], width: 0, height: 0, flags: []]; Check: PROC[x: INTEGER, max: NAT] RETURNS[NAT] ~ TRUSTED MACHINE CODE { PrincOps.zINC; PrincOps.zBNDCK }; MaskRuns: PROC[device: Device, runs: PROC[RunProc]] ~ { data: Data ~ NARROW[device.data]; frame: ImagerPixelMap.PixelMap ~ data.frame; SELECT data.case FROM nil => ERROR; -- color not initialized constant, gray => TRUSTED { bbspace: PrincOps.BBTableSpace; bb: PrincOps.BitBltTablePtr ~ PrincOpsUtils.AlignedBBTable[@bbspace]; gray: LONG POINTER ~ LOOPHOLE[@data.gray]; base: LONG POINTER ~ frame.refRep.pointer; rast: CARDINAL ~ frame.refRep.rast; runConstant: PROC[sMin, fMin: INTEGER, fSize: NAT] ~ TRUSTED { f: NAT ~ Check[fMin, frame.fSize]; s: NAT ~ Check[sMin, frame.sSize]; bb.dst.word _ base+Basics.LongMult[s, rast]+f/Basics.bitsPerWord; bb.dst.bit _ f MOD Basics.bitsPerWord; bb.width _ Check[fSize, frame.fSize-f]; bb.height _ Check[1, frame.sSize-s]; PrincOpsUtils.BITBLT[bb]; }; runGray: PROC[sMin, fMin: INTEGER, fSize: NAT] ~ TRUSTED { f: NAT ~ Check[fMin, frame.fSize]; s: NAT ~ Check[sMin, frame.sSize]; bb.dst.word _ base+Basics.LongMult[s, rast]+f/Basics.bitsPerWord; bb.dst.bit _ bb.src.bit _ f MOD Basics.bitsPerWord; bb.src.word _ gray+(bb.srcDesc.gray.yOffset _ s MOD grayHeight); bb.width _ Check[fSize, frame.fSize-f]; bb.height _ Check[1, frame.sSize-s]; PrincOpsUtils.BITBLT[bb]; }; bb^ _ nullBitBltTable; bb.dstBpl _ rast*Basics.bitsPerWord; bb.src.word _ gray; bb.src.bit _ 0; bb.srcDesc.gray _ [yOffset: 0, widthMinusOne: 0, heightMinusOne: grayHeight-1]; bb.flags _ [direction: forward, disjoint: TRUE, gray: TRUE, srcFunc: data.function.srcFunc, dstFunc: data.function.dstFunc]; runs[IF data.case=constant THEN runConstant ELSE runGray]; }; ENDCASE => ERROR; -- illegal case }; END. πImagerLFDeviceImpl.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Michael Plass, June 19, 1984 1:19:53 pm PDT Doug Wyatt, March 13, 1985 5:34:41 pm PST dot: ImagerPixelMap.PixelMap, -- a halftone dot halftone: HalftoneParameters _ defaultHalftone, -- halftone screen parameters pa: ImagerPixelArray.PixelArray _ NIL, -- pixel array from sampled color multiplier: CARDINAL _ 1, lgScale: INTEGER _ 0, -- scale pa samples to match dot samples transparent: BOOL _ FALSE, paToDevice: Transformation _ NIL, -- transformation from pa coords to display dotToDevice: Transformation _ NIL, -- transformation from dot coords to display source: ImagerPixelMap.PixelMap _ [0, 0, 0, 0, 0, 0, NIL], -- source values from pixel array paSampler: ImagerSampler.Sampler _ NIL, -- for sampling pixel array dotSampler: ImagerSampler.Sampler _ NIL, -- for sampling halftone dot paRow: ImagerPixelRow.PixelRow _ NIL, -- buffer for pixels sampled from pa dotRow: ImagerPixelRow.PixelRow _ NIL -- buffer for pixels sampled from dot defaultDot: ImagerPixelMap.PixelMap ~ ImagerSampler.DotScreen[ r: 0.5, sSize: 16, fSize: 16, maxPixelValue: 255]; data.paRow _ ImagerPixelRow.CreatePixelRow[sMin: 0, fMin: 0, fSize: frame.fSize]; data.dotRow _ ImagerPixelRow.CreatePixelRow[sMin: 0, fMin: 0, fSize: frame.fSize]; Val: TYPE ~ ImagerPixelArrayOps.Val; Table: TYPE ~ REF TableRep; TableRep: TYPE ~ RECORD[SEQUENCE size: NAT OF CARDINAL]; BuildTable: PROC[max: Val, scale: REAL, sWhite, sBlack: REAL, map: ImagerColor.SampleMap _ NIL] RETURNS[Table] ~ { table: Table ~ NEW[TableRep[max+1]]; FOR s0: Val IN[0..max] DO s: REAL ~ IF map=NIL THEN s0 ELSE map[s0]; v: REAL ~ MIN[MAX[(s-sBlack)/(sWhite-sBlack), 0], 1]; table[s0] _ Real.FixC[scale*v]; ENDLOOP; RETURN[table]; }; IF color.ref=$XOR THEN data.function _ [xor, null]; color: SampledColor => { pa: ImagerPixelArray.PixelArray ~ color.pa; samples: ImagerPixelArrayOps.Row ~ NEW[ImagerPixelArrayOps.RowRep[pa.fSize]]; row: ImagerPixelRow.PixelRow ~ ImagerPixelRow.CreatePixelRow[ sMin: 0, fMin: 0, fSize: pa.fSize]; data.pa _ pa; data.paToDevice _ ImagerTransformation.Cat[pa.m, color.um, viewToDevice]; data.dotToDevice _ viewToDevice.Copy[]; data.dotToDevice.ApplyPreScale[data.pixelsPerInch/(data.halftone.dotsPerInch*16)]; data.dotToDevice.ApplyPreRotate[data.halftone.angle]; data.source _ ImagerPixelMap.Create[lgBitsPerPixel: 3, bounds: [sMin: 0, fMin: 0, sSize: pa.sSize, fSize: pa.fSize]]; WITH color.colorOperator.data SELECT FROM data: REF ImagerColorOperatorPrivate.BlackDataRep => { ERROR }; data: REF ImagerColorOperatorPrivate.GrayLinearDataRep => { table: Table _ NIL; IF pa.samplesPerPixel#1 THEN ERROR; -- samplesPerPixel must be 1 table _ BuildTable[max: ImagerPixelArrayOps.MaxSampleValue[pa, 0], scale: 255, sWhite: data.sWhite, sBlack: data.sBlack, map: data.map]; FOR s: NAT IN[0..pa.sSize) DO ImagerPixelArrayOps.GetRow[pa, samples, s, 0, 0]; FOR f: NAT IN[0..pa.fSize) DO row[f] _ table[samples[f]] ENDLOOP; row.sOrigin _ s; ImagerPixelRow.StorePixelRow[row, data.source]; ENDLOOP; }; data: REF ColorOperatorRep.separations => { tables: ARRAY[0..4) OF Table _ ALL[NIL]; IF pa.samplesPerPixel#data.samplesPerPixel THEN ERROR; -- samplesPerPixel must match FOR i: NAT IN[0..pa.samplesPerPixel) DO sep: ImagerColor.Separation ~ data[i]; tables[i] _ BuildTable[max: ImagerPixelArrayOps.MaxSampleValue[pa, i], scale: 255*sep.cie.Y, sWhite: sep.sMax, sBlack: sep.sMin, map: sep.map]; ENDLOOP; FOR s: NAT IN[0..pa.sSize) DO row.sOrigin _ s; ImagerPixelRow.ClearPixelRow[row]; FOR i: NAT IN[0..pa.samplesPerPixel) DO table: Table ~ tables[i]; ImagerPixelArrayOps.GetRow[pa, samples, s, 0, i]; FOR f: NAT IN[0..pa.fSize) DO row[f] _ row[f]+table[samples[f]] ENDLOOP; ENDLOOP; ImagerPixelRow.StorePixelRow[row, data.source]; ENDLOOP; }; ENDCASE => ERROR; -- unknown ColorOperator data.paSampler _ ImagerSampler.CreateSampler[ m: data.paToDevice, x: 0, y: 0, sPixels: pa.sSize, fPixels: pa.fSize]; data.dotSampler _ ImagerSampler.CreateSampler[ m: data.dotToDevice, x: 0, y: 0, sPixels: data.dot.sSize, fPixels: data.dot.fSize]; data.case _ sampled; }; data.halftone _ halftone; IF x IN[0..max] THEN RETURN[x] ELSE ERROR RuntimeError.BoundsFault sampled => { paRow: ImagerPixelRow.PixelRow ~ data.paRow; dotRow: ImagerPixelRow.PixelRow ~ data.dotRow; pa: ImagerPixelArray.PixelArray ~ data.pa; -- pixel array from sampled color source: ImagerPixelMap.PixelMap ~ data.source; run: PROC[sMin, fMin: INTEGER, fSize: NAT] ~ { paRow.sOrigin _ dotRow.sOrigin _ Check[sMin, frame.sSize]; paRow.fOrigin _ dotRow.fOrigin _ Check[fMin, frame.fSize]; paRow.fSize _ dotRow.fSize _ Check[fSize, frame.fSize-fMin]; Might want to interpolate or average here. How do we decide? ImagerSampler.ObtainPointSamples[sampler: data.paSampler, pixelRow: paRow, source: source, multiplier: data.multiplier, lgScale: data.lgScale]; ImagerSampler.ObtainPointSamples[sampler: data.dotSampler, pixelRow: dotRow, source: data.dot]; ImagerSampler.HalftoneLine[dest: frame, pixels: paRow, thresholds: dotRow, invertOutput: FALSE, transparent: data.transparent]; }; runs[run]; }; MaskRectanglesGray: PROC[device: Device, rectangles: PROC[RectangleProc]] ~ TRUSTED { data: Data ~ NARROW[device.data]; bbspace: PrincOps.BBTableSpace; bb: PrincOps.BitBltTablePtr ~ PrincOpsUtils.AlignedBBTable[@bbspace]; gray: LONG POINTER ~ @data.gray; base: LONG POINTER ~ data.frame.refRep.pointer; rast: CARDINAL ~ data.frame.refRep.rast; fSizeDevice: NAT ~ data.frame.fSize; sSizeDevice: NAT ~ data.frame.sSize; rectangle: PROC[r: DeviceRectangle] ~ TRUSTED { f: NAT ~ Check[r.fMin, fSizeDevice]; s: NAT ~ Check[r.sMin, sSizeDevice]; bb.dst.word _ base+Basics.LongMult[s, rast]+f/Basics.bitsPerWord; bb.dst.bit _ bb.src.bit _ f MOD Basics.bitsPerWord; bb.src.word _ gray+(bb.srcDesc.gray.yOffset _ s MOD grayHeight); bb.width _ Check[r.fSize, fSizeDevice-f]; bb.height _ Check[r.sSize, sSizeDevice-s]; PrincOpsUtils.BITBLT[bb]; }; bb^ _ nullBitBltTable; bb.dstBpl _ rast*Basics.bitsPerWord; bb.srcDesc.gray _ [yOffset: 0, widthMinusOne: 0, heightMinusOne: grayHeight-1]; bb.flags _ [direction: forward, disjoint: TRUE, gray: TRUE, srcFunc: data.function.srcFunc, dstFunc: data.function.dstFunc]; rectangles[rectangle]; }; MaskRectanglesConst: PROC[device: Device, rectangles: PROC[RectangleProc]] ~ TRUSTED { data: Data ~ NARROW[device.data]; bbspace: PrincOps.BBTableSpace; bb: PrincOps.BitBltTablePtr ~ PrincOpsUtils.AlignedBBTable[@bbspace]; gray: LONG POINTER ~ @data.gray; base: LONG POINTER ~ data.frame.refRep.pointer; rast: CARDINAL ~ data.frame.refRep.rast; fSizeDevice: NAT ~ data.frame.fSize; sSizeDevice: NAT ~ data.frame.sSize; rectangle: PROC[r: DeviceRectangle] ~ TRUSTED { f: NAT ~ Check[r.fMin, fSizeDevice]; s: NAT ~ Check[r.sMin, sSizeDevice]; bb.dst.word _ base+Basics.LongMult[s, rast]+f/Basics.bitsPerWord; bb.dst.bit _ f MOD Basics.bitsPerWord; bb.width _ Check[r.fSize, fSizeDevice-f]; bb.height _ Check[r.sSize, sSizeDevice-s]; PrincOpsUtils.BITBLT[bb]; }; bb^ _ nullBitBltTable; bb.dstBpl _ rast*Basics.bitsPerWord; bb.src.word _ gray; bb.src.bit _ 0; bb.srcDesc.gray _ [yOffset: 0, widthMinusOne: 0, heightMinusOne: grayHeight-1]; bb.flags _ [direction: forward, disjoint: TRUE, gray: TRUE, srcFunc: data.function.srcFunc, dstFunc: data.function.dstFunc]; rectangles[rectangle]; }; MaskRunsGray: PROC[device: Device, runs: PROC[RunProc]] ~ TRUSTED { data: Data ~ NARROW[device.data]; bbspace: PrincOps.BBTableSpace; bb: PrincOps.BitBltTablePtr ~ PrincOpsUtils.AlignedBBTable[@bbspace]; gray: LONG POINTER ~ @data.gray; base: LONG POINTER ~ data.frame.refRep.pointer; rast: CARDINAL ~ data.frame.refRep.rast; fSizeDevice: NAT ~ data.frame.fSize; sSizeDevice: NAT ~ data.frame.sSize; run: PROC[sMin, fMin: INTEGER, fSize: NAT] ~ TRUSTED { f: NAT ~ Check[fMin, fSizeDevice]; s: NAT ~ Check[sMin, sSizeDevice]; bb.dst.word _ base+Basics.LongMult[s, rast]+f/Basics.bitsPerWord; bb.dst.bit _ bb.src.bit _ f MOD Basics.bitsPerWord; bb.src.word _ gray+(bb.srcDesc.gray.yOffset _ s MOD grayHeight); bb.width _ Check[fSize, fSizeDevice-f]; bb.height _ Check[1, sSizeDevice-s]; PrincOpsUtils.BITBLT[bb]; }; bb^ _ nullBitBltTable; bb.dstBpl _ rast*Basics.bitsPerWord; bb.srcDesc.gray _ [yOffset: 0, widthMinusOne: 0, heightMinusOne: grayHeight-1]; bb.flags _ [direction: forward, disjoint: TRUE, gray: TRUE, srcFunc: data.function.srcFunc, dstFunc: data.function.dstFunc]; runs[run]; }; Κ z˜codešœ™Kšœ Οmœ7™BK™+K™)—K˜šΟk ˜ Kšœžœ˜%Kšœ ˜ Kšœ žœC˜UKšœ˜Kšœ˜Kšœžœ'˜;Kšœ˜Kšœ žœ;˜IKšœžœžœ˜-Kšœžœžœ˜—K˜KšΠblœžœž˜!Kšžœ9˜@Kšœž˜K˜Kšœžœ˜#Kšœ žœ˜%Kšœžœ#˜;Kšœžœ"˜7K˜Kšžœžœ žœ˜Kšœžœ'˜;Kšœžœ˜ Kšœžœ˜0Kšœžœ˜.Kšœžœ˜0K˜Kš œ žœžœ žœžœ˜,Kšœ žœΟc-˜CK˜˜KšΟf*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*K˜K˜—˜Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*Kš‘*˜*K˜K˜—Kšœžœ"˜,K˜KšœO˜OK˜Kšœžœžœ ˜šœ žœžœ˜Kšœ   ˜-Kšœžœ ˜+Kšœ ™/Kšœ ˜'Kšœ2 ˜DKšœžœ ˜-Kšœ0 ™MKšœ"žœ !™HKšœ žœžœ (™XKšœ žœžœ™Kšœžœ +™MKšœžœ ,™OKšœ5žœ !™\Kšœ#žœ ™CKšœ$žœ ™EKšœ!žœ $™JKšœ"žœ %™KK˜K˜—šœžœ˜9Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—šœ>™>Kšœ2™2K™—šœžœ˜ K˜—šΟnœžœžœ ˜3Kšœžœžœ ˜?Kšœ žœ9˜IKšœS˜SKšœ#˜#K™QK™Ršžœžœ(˜2KšœD˜DKšœ!˜!Kšœ4˜4Kšœ˜Kšœ˜—K˜K˜—Kšœžœ™$Kšœžœžœ ™Kš œ žœžœžœžœžœžœ™8K™š’ œžœžœžœ™=Kšœžœžœ ™4Kšœžœ™$šžœ žœ ž™Kš œžœžœžœžœžœ ™*Kšœžœžœžœ$™5Kšœ™Kšžœ™—Kšžœ™K™K™—K˜š’œžœ@˜NKšœ žœ˜!šžœžœž˜˜Kšœ˜šžœž˜Kšœ#žœ"˜HKšœ#žœ˜BKšžœ4˜;—Kšžœžœ™3K˜—™Kšœ+™+Kšœ#žœ'™M™=K™#—K™ KšœI™IKšœ'™'KšœR™RKšœ5™5šœ6™6Kšœ>™>—šžœžœž™)šœžœ-™6Kšž™K™—šœžœ2™;Kšœžœ™Kšžœžœžœ ™@Kšœ‰™‰šžœžœžœž™Kšœ1™1Kš žœžœžœžœžœ™AK™K™/Kšžœ™—K™—šœžœ"™+Kš œžœžœ žœžœ™(Kšžœ)žœžœ ™Tšžœžœžœž™'K™&Kšœ[žœ4™Kšžœ™—šžœžœžœž™K™Kšœ"™"šžœžœžœž™'K™K™1Kš žœžœžœžœ#žœ™HKšžœ™—K™/Kšžœ™—K™—Kšžœžœ ™*—šœ-™-KšœF™F—šœ.™.KšœS™S—K™K™—Kšžœžœ ˜*—Kšœ˜K˜—š’ œžœ$žœ˜>Kšœ˜K˜—š’ œžœ2˜CKšœ žœ˜!K™K˜K˜—šœ)˜)Kšœ žœ˜$Kšœ žœ ˜/Kšœ ˜ K˜—š ’œžœžœžœžœžœ˜0Kšžœžœžœ$˜8Kš žœžœ žœžœžœžœ™BK˜—š’œžœžœ˜7Kšœ žœ˜!Kšœ,˜,šžœ ž˜Kšœžœ ˜&šœžœ˜K˜KšœE˜EKšœžœžœžœ ˜*Kšœžœžœ˜*Kšœžœ˜#š œ žœ žœ žœžœ˜>Kšœžœ˜"Kšœžœ˜"KšœA˜AKšœžœ˜&Kšœ'˜'Kšœ$˜$Kšœžœ˜K˜—š œ žœ žœ žœžœ˜:Kšœžœ˜"Kšœžœ˜"KšœA˜AKšœžœ˜3Kšœ0žœ ˜@Kšœ'˜'Kšœ$˜$Kšœžœ˜K˜—Kšœ˜Kšœ$˜$Kšœ˜Kšœ˜KšœO˜Ošœ*žœžœ˜;Kšœ@˜@—Kšœžœžœ žœ ˜:K˜—™ K™,Kšœ.™.Kšœ+ !™LKšœ.™.šœžœ žœ žœ™.Kšœ:™:Kšœ:™:Kšœ<™