DIRECTORY Imager, ImagerOps, ImagerPixelMap, ImagerPixelArray, ImagerTransformation, Terminal, ImagerBitmapDevicePrivate, ImagerDitheredDevicePrivate, ImagerColor24DevicePrivate, ImagerRasterPrivate, ImagerDevice, ImagerState, Vector2, ImagerManhattan, ImagerManhattanExtras, ImagerBackdoor, ImagerPixelArrayDefs, ImagerSample, UnsafeStorage, ImagerPixelArrayPrivate, PrincOps, Basics, PrincOpsUtils; ImagerOpsImpl: CEDAR MONITOR IMPORTS Imager, ImagerPixelMap, ImagerTransformation, ImagerRasterPrivate, ImagerManhattan, ImagerManhattanExtras, ImagerBackdoor, ImagerSample, UnsafeStorage, Basics, PrincOpsUtils, ImagerPixelArray, Terminal EXPORTS ImagerOps, Imager, ImagerPixelArrayDefs ~ BEGIN Context: TYPE ~ Imager.Context; VEC: TYPE ~ Vector2.VEC; Color: TYPE ~ Imager.Color; PixelArray: TYPE ~ ImagerPixelArray.PixelArray; PixelMap: TYPE ~ ImagerPixelMap.PixelMap; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; Transformation: TYPE ~ ImagerTransformation.Transformation; Rectangle: TYPE ~ ImagerTransformation.Rectangle; FrameBuffer: TYPE ~ Terminal.FrameBuffer; Virtual: TYPE ~ Terminal.Virtual; Kind: TYPE ~ ATOM; State: TYPE ~ ImagerState.State; StateRep: PUBLIC TYPE ~ ImagerState.StateRep; -- export to Imager.StateRep PixelArrayFromPixelMaps: PUBLIC PROC [pms: LIST OF PixelMap, um: Transformation] RETURNS [PixelArray] ~ { w: DeviceRectangle ~ ImagerPixelMap.BoundedWindow[pms.first]; samplesPerPixel: INT _ 0; FOR p: LIST OF PixelMap _ pms.rest, p.rest UNTIL p=NIL DO IF w # ImagerPixelMap.BoundedWindow[p.first] THEN ERROR Imager.Error[[$specification, "Pixel map windows do not match."]]; ENDLOOP; FOR p: LIST OF PixelMap _ pms, p.rest UNTIL p=NIL DO samplesPerPixel _ samplesPerPixel + 1; p.first _ ImagerPixelMap.ShiftMap[p.first, -w.sMin, -w.fMin]; ENDLOOP; RETURN [NEW[ImagerPixelArrayDefs.PixelArrayRep _ [ samplesPerPixel: samplesPerPixel, sSize: w.sSize, fSize: w.fSize, m: ImagerTransformation.PostTranslate[um, [w.sMin, w.fMin]], impl: NIL, class: pixelArrayClass, data: pms ]]]; }; PixelArrayClass: TYPE ~ ImagerPixelArrayPrivate.PixelArrayClass; PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep; pixelArrayClass: PixelArrayClass ~ NEW[PixelArrayClassRep _ [ type: $PixelMaps, MaxSampleValue: PmsMaxSampleValue, UnsafeGetSamples: PmsUnsafeGetSamples, UnsafeGetBits: PmsUnsafeGetBits ]]; GetPM: PROC [pa: PixelArray, i: NAT] RETURNS [PixelMap] ~ { pms: LIST OF PixelMap _ NARROW[pa.data]; THROUGH [0..Basics.BoundsCheck[i, pa.samplesPerPixel]) DO pms _ pms.rest ENDLOOP; RETURN [pms.first]; }; PmsMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [ImagerPixelArray.Sample] ~ { pm: PixelMap ~ GetPM[pa, i]; RETURN [Basics.BITSHIFT[1, Basics.BITSHIFT[1, pm.refRep.lgBitsPerPixel]]-1]; }; PmsUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT, samples: ImagerSample.UnsafeSamples, count: NAT] ~ UNCHECKED { pm: PixelMap ~ GetPM[pa, i]; ImagerSample.UnsafeGetF[samples: samples, count: count, base: pm.refRep.pointer, wordsPerLine: pm.refRep.rast, bitsPerSample: Basics.BITSHIFT[1, pm.refRep.lgBitsPerPixel], s: s-pm.sOrigin, f: f-pm.fOrigin]; }; bitsPerWord: NAT ~ Basics.bitsPerWord; PmsUnsafeGetBits: UNSAFE PROC [pa: PixelArray, i: NAT _ 0, s, f: INT, dst: PrincOps.BitAddress, dstBpl: INTEGER, width, height: CARDINAL, srcFunc: PrincOps.SrcFunc _ null, dstFunc: PrincOps.DstFunc _ null] ~ UNCHECKED { source: PixelMap ~ GetPM[pa, i]; sStartSource: NAT ~ s-source.sOrigin; fMinSource: NAT ~ f-source.fOrigin; bbTableSpace: PrincOps.BBTableSpace; bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace]; [] _ Basics.BoundsCheck[width, source.fSize+1]; [] _ Basics.BoundsCheck[height, source.sSize+1]; [] _ Basics.BoundsCheck[source.refRep.lgBitsPerPixel, 1]; bb^ _ [ dstBpl: dstBpl, srcDesc: [srcBpl[source.refRep.rast*bitsPerWord]], height: height, width: width, flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: srcFunc, dstFunc: dstFunc], dst: dst, src: [word: (source.refRep.pointer + Basics.LongMult[sStartSource, source.refRep.rast] + (fMinSource/bitsPerWord)), bit: fMinSource MOD bitsPerWord] ]; PrincOpsUtils.BITBLT[bb]; }; PixelMapFromPixelArray: PUBLIC PROC [pa: PixelArray, i: NAT] RETURNS [PixelMap] ~ { IF pa.class = pixelArrayClass THEN RETURN [GetPM[pa, i]] ELSE { max: INT ~ ImagerPixelArray.MaxSampleValue[pa, i]; bitsPerSample: NAT ~ Lg[max+1]; pm: PixelMap ~ ImagerPixelMap.Create[Lg[bitsPerSample], [0, 0, pa.sSize, pa.fSize]]; ImagerPixelMap.Clear[pm]; IF bitsPerSample = 1 THEN TRUSTED { ImagerPixelArray.UnsafeGetBits[pa: pa, i: i, s: 0, f: 0, dst: [word: pm.refRep.pointer, bit: 0], dstBpl: pm.refRep.rast*bitsPerWord, width: pm.fSize, height: pm.sSize, srcFunc: null, dstFunc: null] } ELSE TRUSTED { tZone: UNCOUNTED ZONE ~ UnsafeStorage.GetTransientPageUZone[]; buf: ImagerSample.UnsafeSamples _ tZone.NEW[ImagerSample.RawSamples[pm.fSize]]; base: LONG POINTER ~ pm.refRep.pointer; wpl: NAT ~ pm.refRep.rast; FOR line: NAT IN [0..pm.sSize) DO ImagerPixelArray.UnsafeGetSamples[pa: pa, i: i, s: line, f: 0, samples: buf, count: pm.fSize]; ImagerSample.UnsafePutF[samples: buf, count: pm.fSize, s: line, f: 0, base: base, wordsPerLine: wpl, bitsPerSample: bitsPerSample, srcFunc: null, dstFunc: null]; ENDLOOP; tZone.FREE[@buf]; }; RETURN [pm]; }; }; KindOf: PUBLIC PROC [context: Context] RETURNS [Kind] ~ { WITH context.data SELECT FROM rasterData: ImagerRasterPrivate.Data => { device: ImagerDevice.Device ~ rasterData.device; WITH device.data SELECT FROM bitmap: ImagerBitmapDevicePrivate.Data => RETURN [$Bitmap]; dithered: ImagerDitheredDevicePrivate.Data => RETURN [$Dithered]; fullColor: ImagerColor24DevicePrivate.Data => RETURN [$Color24]; ENDCASE => NULL; }; ENDCASE => NULL; RETURN [NIL] }; SurfaceToDevice: PUBLIC PROC [context: Context] RETURNS [Transformation] ~ { WITH context.data SELECT FROM rasterData: ImagerRasterPrivate.Data => { device: ImagerDevice.Device ~ rasterData.device; RETURN [device.surfaceToDevice]; }; ENDCASE => NULL; RETURN [NIL]; }; knownKinds: LIST OF Kind _ LIST [$Bitmap, $Dithered, $Color24]; KnownKinds: PUBLIC PROC RETURNS [LIST OF Kind] ~ {RETURN [knownKinds]}; TerminalFromContext: PUBLIC PROC [context: Context] RETURNS [vt: Virtual, color: BOOL] ~ { WITH context.data SELECT FROM rasterData: ImagerRasterPrivate.Data => { device: ImagerDevice.Device ~ rasterData.device; WITH device.data SELECT FROM bitmap: ImagerBitmapDevicePrivate.Data => { vt: Virtual ~ Terminal.Current[]; fb: Terminal.FrameBuffer ~ Terminal.GetBWFrameBuffer[vt]; IF fb = NIL OR fb.base # bitmap.frame.pointer THEN RETURN [NIL, FALSE] ELSE RETURN [vt, FALSE] }; dithered: ImagerDitheredDevicePrivate.Data => RETURN [dithered.terminal, TRUE]; fullColor: ImagerColor24DevicePrivate.Data => RETURN [fullColor.terminal, TRUE]; ENDCASE => NULL; }; ENDCASE => NULL; RETURN [NIL, FALSE]; }; Lg: PROC [n: INT] RETURNS [lg: NAT _ 0] ~ { nn: LONG CARDINAL ~ n; k: LONG CARDINAL _ 1; UNTIL k=0 OR k>= nn DO lg _ lg + 1; k _ k + k; ENDLOOP; }; PixelMapFromFrameBuffer: PUBLIC PROC [frameBuffer: FrameBuffer] RETURNS [PixelMap] ~ { refRep: REF ImagerPixelMap.PixelMapRep ~ NEW[ImagerPixelMap.PixelMapRep _ [ ref: frameBuffer, pointer: frameBuffer.base, words: INT[frameBuffer.wordsPerLine]*INT[frameBuffer.height], lgBitsPerPixel: Lg[frameBuffer.bitsPerPixel], rast: frameBuffer.wordsPerLine, lines: frameBuffer.height ]]; pixelMap: ImagerPixelMap.PixelMap ~ [ sOrigin: 0, fOrigin: 0, sMin: 0, fMin: 0, sSize: frameBuffer.height, fSize: frameBuffer.width, refRep: refRep ]; RETURN[pixelMap]; }; PixelMapsFromContext: PUBLIC PROC [context: Context] RETURNS [LIST OF PixelMap] ~ { WITH context.data SELECT FROM rasterData: ImagerRasterPrivate.Data => { device: ImagerDevice.Device ~ rasterData.device; WITH device.data SELECT FROM bitmap: ImagerBitmapDevicePrivate.Data => RETURN [LIST[[sOrigin: 0, fOrigin: 0, sMin: 0, fMin: 0, sSize: bitmap.sSizeFrame, fSize: bitmap.fSizeFrame, refRep: bitmap.frame]]]; dithered: ImagerDitheredDevicePrivate.Data => RETURN [LIST[dithered.frame]]; fullColor: ImagerColor24DevicePrivate.Data => RETURN [LIST[PixelMapFromFrameBuffer[fullColor.frame[A]], PixelMapFromFrameBuffer[fullColor.frame[B]]]]; ENDCASE => NULL; }; ENDCASE => NULL; RETURN [NIL]; }; Validate: PROC [context: Context, data: ImagerRasterPrivate.Data, needs: ImagerRasterPrivate.Flags] ~ INLINE { state: ImagerState.State ~ context.state; IF state.changed#ImagerState.notChanged THEN ImagerRasterPrivate.NoteStateChanges[data, state]; IF ImagerRasterPrivate.AndFlags[data.valid, needs]#needs THEN ImagerRasterPrivate.ValidateIfNeeded[data, state, needs]; }; DoSaveClipRectangleI: PROC [context: Context, action: PROC, x, y, w, h: INTEGER] ~ { clippedAction: PROC ~ { Imager.ClipRectangleI[context, x, y, w, h]; action[]; }; WITH context.data SELECT FROM rasterData: ImagerRasterPrivate.Data => { clientToDevice: Transformation; Validate[context, rasterData, [clientToDevice: TRUE]]; clientToDevice _ rasterData.clientToDevice; IF clientToDevice.form=9 AND clientToDevice.integerTrans AND NOT rasterData.specialClipPresent THEN { smin: INT _ INT[clientToDevice.tx]-y; smax: INT _ smin-h; fmin: INT _ INT[clientToDevice.ty]+x; fmax: INT _ fmin+w; IF smax rasterData.specialClipPresent _ rasterData.valid.clientClipper _ FALSE]; rasterData.specialClipPresent _ rasterData.valid.clientClipper _ FALSE; RETURN; }; }; ENDCASE => NULL; Imager.DoSave[context, clippedAction]; }; DoWithBuffer: PUBLIC PROC [context: Context, action: PROC, x, y, w, h: INTEGER, backgroundColor: Color _ NIL] ~ { paintBack: PROC ~ { Imager.SetColor[context, backgroundColor]; Imager.MaskRectangleI[context, x, y, w, h]; }; clippedAction: PROC ~ { IF bufferingOn THEN WITH context.data SELECT FROM rasterData: ImagerRasterPrivate.Data => { Validate[context, rasterData, [clientClipper: TRUE]]; IF rasterData.clientClipBoxOnly THEN { device: ImagerDevice.Device ~ rasterData.device; WITH device.data SELECT FROM bitmapData: ImagerBitmapDevicePrivate.Data => { IF DoWithBitmapBuffer[context, action, backgroundColor, rasterData, bitmapData] THEN RETURN; }; ditheredData: ImagerDitheredDevicePrivate.Data => { IF DoWithDitheredBuffer[context, action, backgroundColor, rasterData, ditheredData] THEN RETURN; }; fullColorData: ImagerColor24DevicePrivate.Data => { }; ENDCASE => NULL; }; }; ENDCASE => NULL; IF backgroundColor # NIL THEN Imager.DoSave[context, paintBack]; action[]; }; DoSaveClipRectangleI[context, clippedAction, x, y, w, h]; }; DeviceBoxFromDeviceRectangle: PROC [r: ImagerPixelMap.DeviceRectangle] RETURNS [ImagerDevice.DeviceBox] ~ { RETURN[[smin: r.sMin, smax: r.sMin+r.sSize, fmin: r.fMin, fmax: r.fMin+r.fSize]]; }; DoWithShift: PROC [rasterData: ImagerRasterPrivate.Data, action: PROC, sDelta, fDelta: INTEGER] ~ { delta: VEC ~ [sDelta, fDelta]; minusDelta: VEC ~ [-delta.x, -delta.y]; true: BOOL[TRUE..TRUE] ~ rasterData.valid.clientClipper; savedClipMask: ImagerManhattan.Polygon ~ rasterData.viewClipMask; savedDeviceBox: ImagerDevice.DeviceBox ~ rasterData.device.box; Restore: PROC ~ { minusDelta: VEC ~ [-delta.x, -delta.y]; ImagerTransformation.ApplyPostTranslate[rasterData.viewToDevice, minusDelta]; ImagerTransformation.ApplyPostTranslate[rasterData.device.surfaceToDevice, minusDelta]; rasterData.device.box _ savedDeviceBox; ImagerManhattan.Destroy[rasterData.viewClipMask]; rasterData.viewClipMask _ savedClipMask; rasterData.viewClipBox _ ImagerManhattan.BoundingBox[rasterData.viewClipMask]; rasterData.specialClipRect.sMin _ rasterData.specialClipRect.sMin-sDelta; rasterData.specialClipRect.fMin _ rasterData.specialClipRect.fMin-fDelta; rasterData.valid.clientClipper _ FALSE; rasterData.valid.clientToDevice _ FALSE; }; ImagerTransformation.ApplyPostTranslate[rasterData.viewToDevice, delta]; ImagerTransformation.ApplyPostTranslate[rasterData.device.surfaceToDevice, delta]; rasterData.viewClipMask _ ImagerManhattanExtras.DestructiveClip[ ImagerManhattan.Copy[rasterData.viewClipMask], rasterData.specialClipRect ]; ImagerManhattan.Shift[rasterData.viewClipMask, sDelta, fDelta]; rasterData.viewClipBox _ ImagerManhattan.BoundingBox[rasterData.viewClipMask]; rasterData.device.box _ DeviceBoxFromDeviceRectangle[rasterData.viewClipBox]; rasterData.specialClipRect.sMin _ rasterData.specialClipRect.sMin+sDelta; rasterData.specialClipRect.fMin _ rasterData.specialClipRect.fMin+fDelta; rasterData.valid.clientClipper _ FALSE; rasterData.valid.clientToDevice _ FALSE; action[ ! UNWIND => Restore[]]; Restore[]; }; nScratch: NAT ~ 2; scratch: ARRAY [0..nScratch) OF REF ImagerPixelMap.PixelMapRep _ ALL[NIL]; ObtainScratch: ENTRY PROC RETURNS [r: REF ImagerPixelMap.PixelMapRep] ~ { FOR i: NAT IN [0..nScratch) DO IF (r _ scratch[i]) # NIL THEN {scratch[i] _ NIL; RETURN}; ENDLOOP; RETURN [NIL]; }; ReleaseScratch: ENTRY PROC [r: REF ImagerPixelMap.PixelMapRep] ~ { FOR i: NAT IN [0..nScratch) DO IF scratch[i] = NIL THEN {scratch[i] _ r; RETURN} ENDLOOP; }; DoWithBitmapBuffer: PROC [context: Context, action: PROC, backgroundColor: Color, rasterData: ImagerRasterPrivate.Data, bitmapData: ImagerBitmapDevicePrivate.Data] RETURNS [ok: BOOL _ TRUE] ~ { tightBox: ImagerDevice.DeviceBox ~ rasterData.clientClipBox; box: ImagerDevice.DeviceBox ~ [ smin: tightBox.smin/4*4, fmin: tightBox.fmin/4*4, smax: tightBox.smax, fmax: tightBox.fmax]; display: PixelMap ~ [sOrigin: 0, fOrigin: 0, sMin: 0, fMin: 0, sSize: bitmapData.sSizeFrame, fSize: bitmapData.fSizeFrame, refRep: bitmapData.frame]; buffer: PixelMap ~ ImagerPixelMap.Reshape[ObtainScratch[], 0, [box.smin, box.fmin, box.smax-box.smin, box.fmax-box.fmin]].Clip[[tightBox.smin, tightBox.fmin, tightBox.smax-tightBox.smin, tightBox.fmax-tightBox.fmin]]; frameAction: PROC ~ { bitmapData.sSizeFrame _ buffer.sMin+buffer.sSize; bitmapData.fSizeFrame _ buffer.fMin+buffer.fSize; bitmapData.frame _ buffer.refRep; IF backgroundColor # NIL THEN { state: ImagerState.State ~ context.state; oldColor: Color ~ state.color; Imager.SetColor[context, backgroundColor]; Imager.MaskRectangle[context, ImagerBackdoor.GetBounds[context]]; Imager.SetColor[context, oldColor]; }; Imager.DoSave[context, action ! UNWIND => { bitmapData.sSizeFrame _ display.sSize; bitmapData.fSizeFrame _ display.fSize; bitmapData.frame _ display.refRep; }]; display.Transfer[buffer]; bitmapData.sSizeFrame _ display.sSize; bitmapData.fSizeFrame _ display.fSize; bitmapData.frame _ display.refRep; }; IF backgroundColor = NIL THEN { buffer.Transfer[display]; } ELSE IF backgroundColor = Imager.white THEN { ImagerPixelMap.Clear[buffer]; backgroundColor _ NIL; }; DoWithShift[rasterData, frameAction, -buffer.sOrigin, -buffer.fOrigin]; ReleaseScratch[buffer.refRep]; }; DoWithDitheredBuffer: PROC [context: Context, action: PROC, backgroundColor: Color, rasterData: ImagerRasterPrivate.Data, ditheredData: ImagerDitheredDevicePrivate.Data] RETURNS [ok: BOOL _ TRUE] ~ { tightBox: ImagerDevice.DeviceBox ~ rasterData.clientClipBox; box: ImagerDevice.DeviceBox ~ [ smin: tightBox.smin/12*12, fmin: tightBox.fmin/12*12, smax: tightBox.smax, fmax: tightBox.fmax]; terminal: Terminal.Virtual ~ ditheredData.terminal; display: PixelMap ~ ditheredData.frame; buffer: PixelMap ~ ImagerPixelMap.Reshape[ObtainScratch[], display.refRep.lgBitsPerPixel, [box.smin, box.fmin, box.smax-box.smin, box.fmax-box.fmin]].Clip[[tightBox.smin, tightBox.fmin, tightBox.smax-tightBox.smin, tightBox.fmax-tightBox.fmin]]; frameAction: PROC ~ { ditheredData.frame _ buffer; ditheredData.frame.sOrigin _ ditheredData.frame.fOrigin _ 0; IF backgroundColor # NIL THEN { state: ImagerState.State ~ context.state; oldColor: Color ~ state.color; Imager.SetColor[context, backgroundColor]; Imager.MaskRectangle[context, ImagerBackdoor.GetBounds[context]]; Imager.SetColor[context, oldColor]; }; Imager.DoSave[context, action ! UNWIND => { ditheredData.frame _ display; }]; IF terminal = NIL THEN display.Transfer[buffer] ELSE { action: PROC ~ {display.Transfer[buffer]}; Terminal.ModifyColorFrame[vt: terminal, action: action, xmin: box.fmin, ymin: box.smin, xmax: box.fmax, ymax: box.smax]; }; display.Transfer[buffer]; ditheredData.frame _ display; }; IF backgroundColor = NIL THEN { IF terminal = NIL THEN buffer.Transfer[display] ELSE { action: PROC ~ {buffer.Transfer[display]}; Terminal.ModifyColorFrame[vt: terminal, action: action, xmin: box.fmin, ymin: box.smin, xmax: box.fmax, ymax: box.smax]; }; buffer.Transfer[display]; }; ditheredData.terminal _ NIL; DoWithShift[rasterData, frameAction, -buffer.sOrigin, -buffer.fOrigin ! UNWIND => {ditheredData.terminal _ terminal}]; ditheredData.terminal _ terminal; ReleaseScratch[buffer.refRep]; }; bufferingOn: BOOL _ TRUE; END. ÔImagerOpsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Michael Plass, August 1, 1985 3:21:06 pm PDT Performs action with the surface to device post-translated by [sDelta, fDelta]. ÊI˜™Icodešœ Ïmœ1™Kšœ(žœ$˜OKšœžœžœ˜'Kšœžœ˜šžœžœžœž˜!Kšœ^˜^K–©[samples: ImagerSample.UnsafeSamples, count: NAT, s: NAT _ 0, f: NAT _ 0, base: LONG POINTER, wordsPerLine: NAT, bitsPerSample: ImagerSample.BitsPerSample]šœ¡˜¡Kšžœ˜—Kšœžœ˜Kšœ˜—Kšžœ˜ Kšœ˜—Kšœ˜K˜—š¡œžœžœžœ ˜9šžœ ž ˜šœ)˜)Kšœ0˜0šžœ žœž˜Kšœ*žœ ˜;Kšœ.žœ ˜AKšœ.žœ ˜@Kšžœžœ˜—K˜—Kšžœžœ˜—Kšžœžœ˜ Kšœ˜K˜—š¡œžœžœžœ˜Lšžœžœž˜šœ)˜)Kšœ0˜0Kšžœ˜ K˜—Kšžœžœ˜—Kšžœžœ˜ Kšœ˜K˜—šœ žœžœžœ ˜?K˜—š¡ œžœžœžœžœžœ žœ˜GK˜—š ¡œžœžœžœžœ˜Zšžœ ž ˜šœ)˜)Kšœ0˜0šžœ žœž˜šœ+˜+Kšœ!˜!Kšœ9˜9Kšžœžœžœ žœžœžœžœ˜FKšžœžœžœ˜Kšœ˜—Kšœ.žœžœ˜OKšœ.žœžœ˜PKšžœžœ˜—K˜—Kšžœžœ˜—Kšžœžœžœ˜Kšœ˜K˜—š ¡œžœžœžœžœ ˜+Kšœžœžœ˜Kšœžœžœ˜šžœžœž˜Kšœ ˜ Kšœ ˜ Kšžœ˜—K˜K˜—š¡œžœžœžœ˜Všœžœžœ˜KKšœ˜Kšœ˜Kšœžœžœ˜=Kšœ-˜-Kšœ˜Kšœ˜Kšœ˜—šœ%˜%Kšœ)˜)KšœC˜CKšœ˜—Kšžœ ˜Kšœ˜K˜K˜—š ¡œžœžœžœžœžœ˜Sšžœ ž ˜šœ)˜)Kšœ0˜0šžœ žœž˜Kšœ*žœžœx˜®Kšœ.žœžœ˜LKšœ.žœžœ\˜–Kšžœžœ˜—K˜—Kšžœžœ˜—Kšžœžœ˜ Kšœ˜K˜K˜—š¡œžœXžœ˜nJšœ)˜)Kšžœ&žœ3˜_Kšžœ7žœ:˜wK˜K˜—š¡œžœžœžœ˜Tšœžœ˜Kšœ+˜+K˜ Kšœ˜—šžœžœž˜šœ)˜)Kšœ˜Kšœ/žœ˜6Kšœ+˜+š žœžœžœžœžœ˜eKšœžœžœžœ ˜9Kšœžœžœžœ ˜9Kšžœ žœ žœ$˜AKšžœ žœ žœ$˜AKšœZ˜ZKšœ žœ˜%Kšœ!žœ˜'Kšœ žœEžœ˜rKšœAžœ˜GKšžœ˜K˜—Kšœ˜—Kšžœžœ˜—Kšœ&˜&K˜K˜—š ¡ œžœžœžœžœžœ˜qšœ žœ˜Kšœ*˜*Kšœ+˜+Kšœ˜—šœžœ˜š žœ žœžœžœž˜1šœ)˜)Kšœ.žœ˜5šžœžœ˜&Kšœ0˜0šžœ žœž˜˜/KšžœNžœžœ˜\K˜—˜3KšžœRžœžœ˜`K˜—˜3K˜—Kšžœžœ˜—Kšœ˜—K˜—Kšžœžœ˜—Kšžœžœžœ#˜@Kšœ ˜ Kšœ˜—Kšœ9˜9K˜K˜—š¡œžœ%žœ˜kKšžœK˜QK˜K˜—š¡ œžœ0žœžœ˜cKšœO™OKšœžœ˜Kšœ žœ˜'Kšœžœžœžœ#˜8KšœA˜AKšœ?˜?š¡œžœ˜Kšœ žœ˜'KšœM˜MKšœW˜WKšœ'˜'Kšœ1˜1Kšœ(˜(KšœN˜NKšœI˜IKšœI˜IKšœ!žœ˜'Kšœ"žœ˜(Kšœ˜—KšœH˜HKšœR˜Ršœ@˜@KšœI˜IKšœ˜—Kšœ?˜?KšœN˜NKšœM˜MKšœI˜IKšœI˜IKšœ!žœ˜'Kšœ"žœ˜(Kšœ žœ˜Kšœ ˜ šœ˜K˜——Kšœ žœ˜š œ žœžœžœžœžœ˜JK˜—š ¡ œžœžœžœžœ ˜Išžœžœž˜Kš žœžœžœžœžœ˜:Kšžœ˜—Kšžœžœ˜ Kšœ˜K˜—š¡œž œžœ ˜Bšžœžœžœž˜Kšžœžœžœžœ˜1Kšžœ˜—Kšœ˜K˜—š ¡œžœžœlžœžœžœ˜ÁKšœ<˜<šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ•˜•KšœÙ˜Ùšœ žœ˜Kšœ1˜1Kšœ1˜1Kšœ!˜!šžœžœžœ˜Jšœ)˜)Kšœ˜Kšœ*˜*KšœA˜AKšœ#˜#Kšœ˜—šœ žœ˜+Kšœ&˜&Kšœ&˜&Kšœ"˜"Kšœ˜—Kšœ˜Kšœ&˜&Kšœ&˜&Kšœ"˜"Kšœ˜—šžœžœžœ˜Kšœ˜Kšœ˜—šžœžœ žœ˜-Kšœ˜Kšœžœ˜Kšœ˜—KšœG˜GKšœ˜Kšœ˜K˜—š ¡œžœžœpžœžœžœ˜ÇKšœ<˜<šœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ3˜3Kšœ'˜'Kšœõ˜õšœ žœ˜Kšœ˜Kšœ<˜<šžœžœžœ˜Jšœ)˜)Kšœ˜Kšœ*˜*KšœA˜AKšœ#˜#Kšœ˜—šœ žœ˜+Kšœ˜Kšœ˜—Kšžœ žœžœ˜/šžœ˜Kšœžœ˜*Kšœx˜xKšœ˜—Kšœ˜Kšœ˜Kšœ˜—šžœžœžœ˜Kšžœ žœžœ˜/šžœ˜Kšœžœ˜*Kšœx˜xKšœ˜—Kšœ˜Kšœ˜—Kšœžœ˜KšœHžœ(˜vKšœ!˜!Kšœ˜Kšœ˜K˜—Kšœ žœžœ˜—K˜Kšžœ˜J˜—…—BrU