DIRECTORY Random, Imager, ImagerColor, ImagerFont, Process, ImagerBackdoor, ImagerPixelArrayDefs, ImagerPixelArray, ImagerPixelArrayPrivate, ImagerTransformation, ImagerSample, ImagerColorOperator, ImagerInterpress, ImagerDitheredDevice, Rope; RandomImagerImpl: CEDAR PROGRAM IMPORTS Random, Imager, ImagerColor, ImagerFont, Process, ImagerBackdoor, ImagerPixelArray, ImagerTransformation, ImagerSample, ImagerColorOperator, ImagerInterpress, ImagerDitheredDevice, Rope EXPORTS ImagerPixelArrayDefs ~ BEGIN ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Imager.VEC; Context: TYPE ~ Imager.Context; PixelArray: TYPE ~ ImagerPixelArrayDefs.PixelArray; random: Random.RandomStream _ Random.Create[]; Rand: PROC RETURNS [REAL] ~ { RETURN [RandI[0, INT.LAST]/REAL[INT.LAST]]; }; RandI: PROC [min,max: INT] RETURNS [INT] ~ { RETURN [random.ChooseInt[min,max]]; }; imagePA: Imager.PixelArray _ ImagerPixelArray.FromAIS["Mandrill.ais"]; imageColorOperator: Imager.ColorOperator _ ImagerColorOperator.GrayLinearColorModel[255, 0, 255, NIL]; SetGrayImage: PROC [rootName: ROPE] ~ { imagePA _ ImagerPixelArray.FromAIS[rootName.Concat[".ais"]]; }; rgbImagePA: Imager.PixelArray _ ImagerPixelArray.Join3AIS["Umbrella-red.ais", "Umbrella-grn.ais", "Umbrella-blu.ais"]; rgbImageColorOperator: Imager.ColorOperator _ ImagerColorOperator.RGBLinearColorModel[255]; SetColorImage: PROC [rootName: ROPE] ~ { rgbImagePA _ ImagerPixelArray.Join3AIS[rootName.Concat["-red.ais"], rootName.Concat["-grn.ais"], rootName.Concat["-blu.ais"]]; }; RandomColor: PROC [context: Context] ~ { selectR: PROC [NAT] RETURNS [NAT] ~ {RETURN [RandI[0, pixelMasks.samplesPerPixel-1]]}; SELECT Rand[] FROM IN [0.0..0.15] => Imager.SetColor[context, Imager.black]; IN [0.15..0.2] => Imager.SetColor[context, ImagerDitheredDevice.ColorFromSpecialPixel[[55H, xor]]]; IN [0.2..0.3] => Imager.SetGray[context, Rand[]]; IN [0.3..0.6] => Imager.SetColor[context, ImagerColor.ColorFromRGB[[Rand[], Rand[], Rand[]]]]; IN [0.6..0.7] => Imager.SetSampledColor[context, rgbImagePA, ImagerTransformation.Scale[Rand[]+0.1], rgbImageColorOperator]; IN [0.7..0.75] => Imager.SetSampledBlack[context, ImagerPixelArray.Extract[old: pixelMasks, samplesPerPixel: 1, select: selectR], ImagerTransformation.Scale[RandI[1, 8]/2.0], 0=RandI[0,1]]; IN [0.75..0.8] => Imager.SetSampledColor[context, imagePA, ImagerTransformation.Scale[Rand[]+0.1], imageColorOperator]; IN [0.9..1.0] => Imager.SetColor[context, Imager.white]; ENDCASE => NULL; }; goodForText: BOOL _ FALSE; RandomScaleRotate: PROC [context: Context] ~ { SELECT Rand[] FROM IN [0.0..0.5] => {Imager.ScaleT[context, 0.5*(1+ABS[RandI[1, 6]+RandI[-5, 5]])]; goodForText _ TRUE}; IN [0.5..0.7] => Imager.ScaleT[context, Rand[]*Rand[]*10+0.01]; IN [0.7..0.8] => Imager.Scale2T[context, [2*Rand[]+0.01, 2*Rand[]+0.01]]; IN [0.9..0.95] => {Imager.Scale2T[context, [0.5*RandI[1, 3], 0.5*RandI[1, 3]]]; goodForText _ TRUE}; ENDCASE => goodForText _ TRUE; SELECT Rand[] FROM IN [0.0..0.7] => Imager.RotateT[context, 90*RandI[-20, 19]]; IN [0.7..0.9] => {Imager.RotateT[context, 360*4*Rand[]-360*2]; goodForText _ FALSE}; IN [0.9..0.95] => {Imager.RotateT[context, 23.0*RandI[-1, 1]]}; ENDCASE => NULL; }; RandomTranslate: PROC [context: Context] ~ { RandBI: PROC RETURNS [INT] ~ {RETURN [RandI[-50, 50]+RandI[-50, 50]+RandI[-50, 50+RandI[-50, 50]]]}; SELECT Rand[] FROM IN [0.0..0.7] => Imager.TranslateT[context, [RandBI[], RandBI[]]]; IN [0.7..1.0] => Imager.TranslateT[context, [RandBI[]*Rand[], RandBI[]*Rand[]]]; ENDCASE => NULL; }; CoordSys: PROC [context: Context] ~ { it: PROC ~ { Imager.MaskVector[context, [0,0], [0,5]]; Imager.MaskVector[context, [0,0], [4.8,0]]; Imager.MaskVector[context, [1,-0.2], [1,0.2]]; Imager.MaskVector[context, [-0.2,1], [0.2,1]]; Imager.MaskVector[context, [5,0], [4.8, 0.1]]; Imager.MaskVector[context, [4.8, 0.1], [4.8, -0.1]]; Imager.MaskVector[context, [4.8, -0.1], [5,0]]; Imager.MaskVector[context, [0,5], [0.1,4.8]]; Imager.MaskVector[context, [0,5], [-0.1,4.8]]; }; inner: PROC ~ { Imager.SetStrokeWidth[context, 0.2]; Imager.SetStrokeEnd[context, round]; Imager.SetColor[context, Imager.white]; Imager.SetStrokeWidth[context, 0.3]; Imager.MaskVector[context, [0,0], [0,0]]; it[]; Imager.SetStrokeWidth[context, 0]; Imager.SetColor[context, Imager.black]; it[]; Imager.SetStrokeWidth[context, 0.15]; it[]; }; Imager.DoSaveAll[context, inner]; }; Interp: PROC [a, b: VEC, r: REAL] RETURNS [VEC] ~ { s: REAL ~ 1.0-r; RETURN [[a.x*s+b.x*r, a.y*s+b.y*r]] }; RandomSplinePath: PROC [n: [3..10), close: BOOL, moveTo: PROC [VEC], curveTo: PROC [VEC, VEC, VEC]] ~ { k: ARRAY [0..11) OF VEC; nn: INT _ IF close THEN INT[n]+1 ELSE n; Mod: PROC [i: INT] RETURNS [INT] ~ { WHILE i<0 DO i _ i + nn ENDLOOP; WHILE i>=nn DO i _ i - nn ENDLOOP; RETURN [i]; }; FOR i: INT IN [0..nn) DO k[i] _ [Rand[]*scale.x, Rand[]*scale.y]; ENDLOOP; FOR i: INT IN [0..n) DO a: VEC _ Interp[k[Mod[i-2]], k[Mod[i-1]], 2/3.0]; c: VEC _ Interp[k[Mod[i-1]], k[Mod[i]], 1/3.0]; b: VEC _ Interp[a, c, 0.5]; d: VEC _ Interp[k[Mod[i-1]], k[Mod[i]], 2/3.0]; f: VEC _ Interp[k[Mod[i]], k[Mod[i+1]], 1/3.0]; e: VEC _ Interp[d, f, 0.5]; IF i=0 THEN moveTo[b]; curveTo[c, d, e]; ENDLOOP; }; RandomArc: PROC [start: VEC, arcTo: PROC [VEC, VEC]] RETURNS [lp: VEC] ~ { lp _ [Rand[]*scale.x, Rand[]*scale.y]; arcTo[[Rand[]*scale.x, Rand[]*scale.y], lp]; }; RandomLine: PROC [start: VEC, lineTo: PROC [VEC]] RETURNS [lp: VEC] ~ { lp _ [Rand[]*scale.x, Rand[]*scale.y]; lineTo[lp]; }; RandVec: PROC RETURNS [lp: VEC] ~ { lp _ [Rand[]*scale.x, Rand[]*scale.y]; }; strokeScale: REAL _ 10.0; RandomStrokeStyle: PROC [context: Context] ~ { Imager.SetStrokeWidth[context, strokeScale*Rand[]]; Imager.SetStrokeEnd[context, VAL[NAT[RandI[0,2]]]]; Imager.SetStrokeJoint[context, VAL[NAT[RandI[0,1]]]]; }; scale: VEC _ [1.0, 1.0]; closed: BOOL _ FALSE; RandomPath: Imager.PathProc ~ { lp: VEC _ RandVec[]; SELECT Rand[] FROM IN [0.0..0.3] => { FOR i: INT IN [0..RandI[0,3]*RandI[0,1]) DO RandomSplinePath[RandI[3,9], closed, moveTo, curveTo]; ENDLOOP; }; IN [0.3..0.4] => { RandomSplinePath[RandI[3,9], FALSE, moveTo, curveTo]; }; IN [0.4..0.6] => { n: INT _ RandI[1,4]; moveTo[lp]; FOR i: INT IN [0..n) DO lp _ RandomArc[lp, arcTo]; ENDLOOP; }; IN [0.6..1.0] => { n: INT _ RandI[0,20]; moveTo[lp]; FOR i: INT IN [0..n) DO lp _ RandomLine[lp, lineTo]; ENDLOOP; }; ENDCASE => NULL; }; PixelArrayImpl: TYPE ~ ImagerPixelArrayPrivate.PixelArrayImpl; PixelArrayImplRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayImplRep; PixelArrayClass: TYPE ~ ImagerPixelArrayPrivate.PixelArrayClass; PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep; RandomStippleColor: PROC RETURNS [Imager.Color] ~ { IF 0=RandI[0,4] THEN { bits: REF ARRAY [0..16) OF WORD _ NEW[ARRAY [0..16) OF WORD]; height: NAT ~ RandI[1,16]; width: NAT ~ RandI[1,16]; pa: PixelArray ~ NEW[ImagerPixelArrayDefs.PixelArrayRep _ [ samplesPerPixel: 1, sSize: height, fSize: width, m: ImagerTransformation.Scale[1], class: bitsClass, data: bits]]; t: CARDINAL _ 1; FOR i: NAT DECREASING IN [0..16) DO bits^[i] _ t; t _ 2*t; ENDLOOP; RETURN [ImagerColor.MakeSampledBlack[pa, ImagerTransformation.Scale[1], 0=RandI[0,1]]] }; RETURN [ImagerBackdoor.MakeStipple[RandI[0, LAST[WORD]]]] }; bitsClass: PixelArrayClass ~ NEW[PixelArrayClassRep _ [ type: $Bits, MaxSampleValue: BitsMaxSampleValue, UnsafeGetSamples: BitsUnsafeGetSamples ]]; BitsMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [ImagerPixelArray.Sample] ~ { RETURN [1]; }; BitsUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT, samples: ImagerSample.UnsafeSamples, count: NAT] ~ UNCHECKED { data: REF ARRAY [0..16) OF WORD ~ NARROW[pa.data]; ImagerSample.UnsafeGetF[samples: samples, count: count, base: LOOPHOLE[data, LONG POINTER], wordsPerLine: 1, bitsPerSample: 1, s: s, f: f] }; RandomClip: PROC [context: Context] ~ { path: Imager.PathProc ~ { RandomSplinePath[5, TRUE, moveTo, curveTo]; }; Imager.Clip[context, path, FALSE, RandI[0,4]=0]; Imager.SetColor[context, RandomStippleColor[]]; Imager.MaskBox[context, [-99999, -99999, 99999, 99999]]; }; RandomFill: PROC [context: Context] ~ { closed _ TRUE; Imager.MaskFill[context, RandomPath, RandI[0,1]=0]; }; RandomStroke: PROC [context: Context] ~ { closed _ RandI[0,1]=0; RandomStrokeStyle[context]; Imager.MaskStroke[context, RandomPath, closed]; }; RandomVector: PROC [context: Context] ~ { RandomStrokeStyle[context]; Imager.MaskVector[context, RandVec[], RandVec[]]; }; RandomRectangle: PROC [context: Context] ~ { p0: VEC _ RandVec[]; p1: VEC _ RandVec[]; Imager.MaskRectangle[context, [p0.x, p0.y, p1.x-p0.x, p1.y-p0.y]]; }; pa1: PixelArray _ ImagerPixelArray.FromAIS["Mask1.ais"]; pa2: PixelArray _ ImagerPixelArray.FromAIS["Mask2.ais"]; pa3: PixelArray _ ImagerPixelArray.FromAIS["Mask3.ais"]; pixelMasks: PixelArray _ ImagerPixelArray.Join3[pa1, pa2, pa3]; RandomPixels: PROC [context: Context] ~ { selectR: PROC [NAT] RETURNS [NAT] ~ {RETURN [RandI[0, pixelMasks.samplesPerPixel-1]]}; pa: PixelArray ~ ImagerPixelArray.Extract[old: pixelMasks, samplesPerPixel: 1, select: selectR]; Imager.MaskPixel[context, pa]; }; RandomMask: PROC [context: Context, textBounds: BOOL _ FALSE] ~ { SELECT Rand[] FROM IN [0.0..0.2] => RandomFill[context]; IN [0.2..0.3] => RandomStroke[context]; IN [0.3..0.58] => {IF goodForText THEN RandomShow[context, textBounds] ELSE RandomFill[context]}; IN [0.58..0.6] => RandomShow[context, textBounds]; IN [0.6..0.65] => RandomRectangle[context]; IN [0.65..0.85] => {IF goodForText THEN RandomPixels[context] ELSE RandomRectangle[context]}; IN [0.85..0.9] => RandomPixels[context]; ENDCASE => RandomVector[context]; }; nfonts: NAT _ 9; xerox: BOOL _ FALSE; logo: ROPE ~ "xerox/pressfonts/logo-mrr"; fontName: ARRAY [0..35) OF ROPE _ ["xerox/pressfonts/helvetica-bir", "xerox/pressfonts/modern-bir", "xerox/pressfonts/timesroman-brr", "xerox/pressfonts/modernpione-brr", logo, "xerox/pressfonts/classic-brr", "xerox/pressfonts/classic-mir", "xerox/pressfonts/timesroman-mrr", "xerox/pressfonts/oldenglish-mrr", "xerox/pressfonts/classic-mrr", "xerox/pressfonts/classicpione-brr", "xerox/pressfonts/classicpione-mir", "xerox/pressfonts/classicpione-mrr", "xerox/pressfonts/gacha-mrr", "xerox/pressfonts/gates-mrr", "xerox/pressfonts/helvetica-brr", "xerox/pressfonts/helvetica-mir", "xerox/pressfonts/helvetica-mrr", "xerox/pressfonts/hippo-mrr", "xerox/pressfonts/keyhole-brr", "xerox/pressfonts/laurel-mrr", "xerox/pressfonts/math-mrr", "xerox/pressfonts/mockingbird-mrr", "xerox/pressfonts/modern-brr", "xerox/pressfonts/modern-mir", "xerox/pressfonts/modern-mrr", "xerox/pressfonts/modernpione-bir", "xerox/pressfonts/modernpione-mir", "xerox/pressfonts/modernpione-mrr", "xerox/pressfonts/template-mrr", "xerox/pressfonts/timesroman-bir", "xerox/pressfonts/timesroman-mrr", "xerox/pressfonts/timesroman-mir", "xerox/pressfonts/xeroxbook-mrr", "xerox/pressfonts/arrows-mrr"]; RandomFont: PROC [context: Context] ~ { name: ROPE ~ fontName[RandI[0,MIN[nfonts, 35]-1]]; font: Imager.Font ~ ImagerFont.Find[name]; Imager.SetFont[context, ImagerFont.Scale[font, 8]]; xerox _ (name = logo); }; text: ARRAY [0..11) OF ROPE ~ ["Now is the time for all good ", "people to party", "The Quick Brown ", "Fox Jumps Over Lazy Dogs ", "Flash ", "Dazzle ", "Imager ", "Cedar ", "Dorado ", "Color Is Fun ", "XEROX "]; RandomShow: PROC [context: Context, checkBounds: BOOL] ~ { amp: REAL _ IF RandI[0,3] = 0 THEN 0.5+1.5*Rand[] ELSE 1.0; RandomFont[context]; Imager.SetAmplifySpace[context, amp]; IF checkBounds THEN { bounds: Imager.Rectangle ~ ImagerBackdoor.GetBounds[context]; cp: VEC ~ ImagerBackdoor.GetCP[context]; IF cp.x IN [bounds.x..bounds.x+bounds.w) AND cp.y IN [bounds.y..bounds.y+bounds.h) THEN NULL ELSE Imager.SetXY[context, [bounds.x+0.5*bounds.w*Rand[], bounds.y+0.5*bounds.h*Rand[]]]; }; Imager.ShowRope[context, IF xerox THEN "XEROX " ELSE text[RandI[0, 11-1]]]; }; limit: INT _ 0; Setup: PROC [n: INT _ -1, newRand: BOOL _ FALSE] ~ { IF newRand THEN random _ Random.Create[]; limit _ n; }; Run: PROC [context: Context] ~ { Do20: PROC ~ { bounds: Imager.Rectangle _ ImagerBackdoor.GetBounds[context]; scale _ [bounds.w, bounds.h]; RandomTranslate[context]; Imager.TranslateT[context, [bounds.w/2, bounds.h/2]]; RandomScaleRotate[context]; Imager.TranslateT[context, [-bounds.w/2, -bounds.h/2]]; CoordSys[context]; Imager.SetXY[context, [0, 0]]; IF 0 = RandI[0,5] THEN RandomClip[context]; FOR i: INT IN [0..20) UNTIL limit = 0 DO IF 0 = RandI[0,99] THEN RandomClip[context]; RandomColor[context]; RandomMask[context, TRUE]; limit _ limit - 1; Process.CheckForAbort[]; ENDLOOP; }; UNTIL limit = 0 DO Imager.DoSaveAll[context, Do20]; ENDLOOP; }; WriteInterpress: PROC [nOpsPerPage, nPages: INT _ 1] ~ { page: PROC [context: Context] ~ { n: INT _ nOpsPerPage; bounds: Imager.Rectangle ~ [0, 0, 8.5*72, 11*72]; Do20: PROC ~ { Imager.TranslateT[context, [bounds.w/2, bounds.h/2]]; RandomScaleRotate[context]; Imager.TranslateT[context, [-bounds.w/2, -bounds.h/2]]; CoordSys[context]; Imager.SetXY[context, [0, 0]]; IF 0 = RandI[0,5] THEN RandomClip[context]; FOR i: INT IN [0..20) UNTIL n = 0 DO IF 0 = RandI[0, 99] THEN RandomClip[context]; RandomColor[context]; RandomMask[context]; n _ n - 1; Process.CheckForAbort[]; ENDLOOP; }; Imager.ScaleT[context, 0.0254/72]; scale _ [bounds.w, bounds.h]; UNTIL n <= 0 DO Imager.DoSaveAll[context, Do20]; ENDLOOP; }; interpress: ImagerInterpress.Ref ~ ImagerInterpress.Create["Random.interpress"]; FOR i: NAT IN [0..5) DO ImagerInterpress.DeclareFont[interpress, ImagerFont.Find[fontName[i]]]; ENDLOOP; ImagerInterpress.DeclarePixelArray[interpress, imagePA]; ImagerInterpress.DeclarePixelArray[interpress, rgbImagePA]; ImagerInterpress.DeclarePixelArray[interpress, pa1]; ImagerInterpress.DeclarePixelArray[interpress, pa2]; ImagerInterpress.DeclarePixelArray[interpress, pa3]; ImagerInterpress.DeclareColorOperator[interpress, imageColorOperator]; THROUGH [0..nPages) DO ImagerInterpress.DoPage[interpress, page] ENDLOOP; ImagerInterpress.Close[interpress]; }; END. žRandomImagerImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Michael Plass, July 20, 1985 11:31:04 am PDT Anything is OK for text, but we try not to get too many different transformations to keep it quick. Run InterpressPackage Run RandomImagerImpl Run ImagerViewerImpl _ &c _ ImagerViewer.Create[[name: "Random Imager"], pixels] _ RandomImagerImpl.Setup[] _ RandomImagerImpl.Run[&c] Κ¬˜™Icodešœ Οmœ1™Kšœžœžœ-˜KK˜Kšœžœ+˜@Kšœžœžœ.˜MK˜š œžœžœ˜3šžœžœ˜Jšœžœžœ žœžœžœžœ žœžœ˜=Jšœžœ˜Jšœžœ˜Jšœžœ›˜―Kšœžœ˜š žœžœž œžœ ž˜#Kšœ ˜ K˜Kšžœ˜—KšžœP˜VKšœ˜—Kšžœ&žœžœ˜9Jšœ˜J˜—šœžœ˜7K˜ Kšœ#˜#Kšœ&˜&Kšœ˜K˜—š œžœžœžœ˜WKšžœ˜ K˜K˜—š œžœžœžœžœ/žœž œ˜…Kš œžœžœ žœžœžœ ˜2Kšœ>žœžœžœ1˜ŠK˜K˜—š  œžœ˜'šœ˜Jšœžœ˜+Jšœ˜—Jšœžœ˜0Jšœ/˜/Jšœ8˜8Jšœ˜J˜—š  œžœ˜'Jšœ žœ˜Jšœ3˜3Jšœ˜J˜—š  œžœ˜)Jšœ˜Jšœ˜Jšœ/˜/Jšœ˜J˜—š  œžœ˜)Jšœ˜Jšœ1˜1Jšœ˜J˜—š œžœ˜,Jšœžœ ˜Jšœžœ ˜JšœB˜BJšœ˜J˜—Jšœ8˜8Jšœ8˜8Jšœ8˜8šœ?˜?J˜—š  œžœ˜)K–O[old: ImagerPixelArrayDefs.PixelArray, samplesPerPixel: NAT, select: PROC [...]š œ žœžœžœžœžœ+˜VJ˜`Jšœ˜Jšœ˜J˜—š  œžœ žœžœ˜Ašžœž˜Jšžœ#˜%Jšžœ%˜'Jšžœžœ žœ!žœ˜aJšžœ0˜2Jšžœ)˜+Jšžœžœ žœžœ˜]Jšžœ&˜(Jšžœ˜!—Jšœ˜J˜—Jšœžœ˜Jšœžœžœ˜Jšœžœ˜)Jšœ žœ žœžœϋ˜š J˜š  œžœ˜'Jšœžœžœ˜2Jšœ*˜*Jšœ3˜3Jšœ˜Jšœ˜J˜—šœžœ žœžœΉ˜ΤJ˜—š  œžœ!žœ˜:Jš œžœžœžœžœ˜;Jšœ˜Jšœ%˜%šžœ žœ˜Kšœ=˜=Kšœžœ!˜(Kš žœžœžœžœžœž˜\KšžœU˜YKšœ˜—Jšœžœžœ žœ˜KJšœ˜J˜—Jšœžœ˜š  œžœžœžœžœ˜4Jšžœ žœ˜)Jšœ ˜ Jšœ˜J˜—š œžœ˜ š œžœ˜Jšœ=˜=Jšœ˜Jšœ˜Jšœ5˜5Jšœ˜Jšœ7˜7Jšœ˜Jšœ˜Jšžœžœ˜+š žœžœžœ žœ ž˜(Jšžœžœ˜,Jšœ˜Jšœžœ˜Jšœ˜J˜Jšžœ˜—Jšœ˜—šžœ ž˜Jšœ ˜ Jšžœ˜—Jšœ˜J˜—š œžœžœ ˜8šœžœ˜!Jšœžœ˜Jšœ1˜1š œžœ˜Jšœ5˜5Jšœ˜Jšœ7˜7Jšœ˜Jšœ˜Jšžœžœ˜+š žœžœžœ žœž˜$Jšžœžœ˜-Jšœ˜Jšœ˜Jšœ ˜ J˜Jšžœ˜—Jšœ˜—Jšœ"˜"Jšœ˜šžœž˜Jšœ ˜ Jšžœ˜—Kšœ˜—J˜Pšžœžœžœž˜KšœG˜GKšžœ˜—Jšœ8˜8Jšœ;˜;Jšœ4˜4Jšœ4˜4Jšœ4˜4JšœF˜FJšžœ žœ+žœ˜IJšœ#˜#Jšœ˜J˜—Jšžœ˜J˜Jšœ™J™Jšœ™Jšœ;™;Jšœ™Jšœ™——…—6ϊHD