DIRECTORY AtomButtonsTypes, SVGraphics, Feedback, Imager, ImagerColor, IO, Matrix3d, Rope, SV2d, SV3d, SVArtwork, SVMappings, SVMatrix2d, SVModelTypes, SVPolygon3d, SVScene, SVSceneTypes, TFI3d, ViewerClasses; TFI3dImpl: CEDAR PROGRAM IMPORTS SVGraphics, ImagerColor, IO, Matrix3d, SVArtwork, Feedback, SVMappings, SVMatrix2d, SVPolygon3d, SVScene, Rope EXPORTS TFI3d = BEGIN Slice: TYPE = SVSceneTypes.Slice; Color: TYPE = Imager.Color; CoordSystem: TYPE = SVModelTypes.CoordSystem; DrawStyle: TYPE = SVModelTypes.DrawStyle; FeedbackData: TYPE = AtomButtonsTypes.FeedbackData; FileCamera: TYPE = SVSceneTypes.FileCamera; FrameBox: TYPE = REF FrameBoxObj; FrameBoxObj: TYPE = SVModelTypes.FrameBoxObj; Matrix3by3: TYPE = SV2d.Matrix3by3; Matrix4by4: TYPE = SV3d.Matrix4by4; OMap: TYPE = SVModelTypes.OMap; Plane: TYPE = SV3d.Plane; Point3d: TYPE = SV3d.Point3d; Point2d: TYPE = SV2d.Point2d; Projection: TYPE = SVModelTypes.Projection; Scene: TYPE = SVSceneTypes.Scene; Vector3d: TYPE = SV3d.Vector3d; Viewer: TYPE = ViewerClasses.Viewer; Material: TYPE = SVModelTypes.Material; SMap: TYPE = SVModelTypes.SMap; CharClass: TYPE = IO.CharClass; FileinMatrix: PUBLIC PROC [f: IO.STREAM] RETURNS [mat: Matrix4by4] = { mat _ Matrix3d.Identity[]; ReadRope[f, "["]; ReadBlankAndRope[f, "["]; mat[1][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..4] DO ReadBlankAndRope[f,","]; mat[1][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlank[f]; ReadBlankAndRope[f, "]"]; FOR i: NAT IN[2..3] DO ReadBlankAndRope[f, ","]; ReadBlankAndRope[f, "["]; mat[i][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..4] DO ReadBlankAndRope[f, ","]; mat[i][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlankAndRope[f, "]"]; ENDLOOP; ReadBlankAndRope[f, "]"]; }; -- end of FileinMatrix FileinMatrix3by3: PUBLIC PROC [f: IO.STREAM] RETURNS [mat: Matrix3by3] = { mat _ SVMatrix2d.Identity[]; ReadRope[f, "["]; ReadBlankAndRope[f, "["]; mat[1][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..3] DO ReadBlankAndRope[f,","]; mat[1][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlank[f]; ReadBlankAndRope[f, "]"]; ReadBlankAndRope[f, ","]; ReadBlankAndRope[f, "["]; mat[2][1] _ ReadBlankAndReal[f]; FOR j: NAT IN[2..3] DO ReadBlankAndRope[f, ","]; mat[2][j] _ ReadBlankAndReal[f]; ENDLOOP; ReadBlankAndRope[f, "]"]; ReadBlankAndRope[f, "]"]; }; -- end of FileinMatrix3by3 ReadRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { c: CHAR; endofstream: BOOL _ FALSE; FOR i: INT IN[1..Rope.Length[rope]] DO c _ IO.GetChar[f ! IO.EndOfStream => {endofstream _ TRUE; CONTINUE}]; IF endofstream THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], NIL, rope]; IF NOT c = Rope.Fetch[rope,i-1] THEN SIGNAL RopeNotOnTop [IO.GetIndex[f], Rope.FromChar[c], rope]; ENDLOOP; }; RopeNotOnTop: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE; ReadChar: PUBLIC PROC [f: IO.STREAM, c: CHAR] = { streamC: CHAR _ IO.GetChar[f]; IF NOT c = streamC THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], Rope.FromChar[streamC], Rope.FromChar[c]]; }; ReadReturn: PUBLIC PROC [f: IO.STREAM] = { ReadChar[f, IO.CR]; }; WordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.TAB => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ', => RETURN [break]; '] => RETURN [break]; ') => RETURN [break]; ENDCASE => RETURN [other]; }; KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ': => RETURN [break]; ENDCASE => RETURN [other]; }; ReadWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { [word, ----] _ IO.GetTokenRope[f, WordBreakProc !IO.EndOfStream => {word _ NIL; CONTINUE}]; }; ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = { end: BOOL _ FALSE; nextChar: Rope.ROPE; [keyWord, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; keyWord _ NIL; RETURN}; [nextChar, ----] _ IO.GetTokenRope[f, KeyWordBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; good _ Rope.Equal[nextChar, ":", TRUE]; }; LineBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; ENDCASE => RETURN [other]; }; ReadLine: PUBLIC PROC [f: IO.STREAM] RETURNS [line: Rope.ROPE] = { end: BOOL _ FALSE; [line, ----] _ IO.GetTokenRope[f, LineBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {line _ NIL; RETURN}; [----, ----] _ IO.GetTokenRope[f, LineBreakProc]; -- remove }; WhiteSpaceProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = { SELECT char FROM IO.TAB => RETURN [other]; IO.CR =>RETURN [other]; IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; ReadWhiteSpace: PUBLIC PROC [f: IO.STREAM] = { whiteSpace: Rope.ROPE; end: BOOL _ FALSE; [whiteSpace, ----] _ IO.GetTokenRope[f, WhiteSpaceProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR Rope.Size[whiteSpace] = 0 THEN SIGNAL RopeNotOnTop[IO.GetIndex[f], "null", ""]; }; ReadBlank: PUBLIC PROC [f: IO.STREAM] = { [] _ IO.SkipWhitespace[f, TRUE]; }; ReadHorizontalBlank: PUBLIC PROC [f: IO.STREAM] RETURNS [good: BOOL] = { whiteSpace: Rope.ROPE; c: CHAR; end: BOOL _ FALSE; good _ TRUE; [whiteSpace, ----] _ IO.GetTokenRope[f, HorizontalBlankProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; RETURN}; c _ Rope.Fetch[whiteSpace, 0]; SELECT c FROM IO.CR => {good _ FALSE; RETURN}; IO.TAB, IO.SP => {good _ TRUE; RETURN}; ENDCASE => {good _ TRUE; IO.Backup[f, c]; RETURN}; }; HorizontalBlankProc: SAFE PROC [char: CHAR] RETURNS [CharClass] = { SELECT char FROM IO.TAB, IO.SP => RETURN [other]; ENDCASE => RETURN [break]; }; ReadBlankAndRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = { ReadBlank[f]; ReadRope[f, rope]; }; ReadBlankAndReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { ReadBlank[f]; r _ ReadReal[f]; }; ReadBlankAndWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = { ReadBlank[f]; word _ ReadWord[f]; }; ReadBlankAndNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { ReadBlank[f]; n _ ReadNAT[f]; }; ReadPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = { ReadRope[f, "["]; point3d[1] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point3d[2] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point3d[3] _ ReadBlankAndReal[f]; ReadRope[f, "]"]; }; ReadPoint2d: PUBLIC PROC [f: IO.STREAM] RETURNS [point2d: Point2d] = { ReadRope[f, "["]; point2d[1] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point2d[2] _ ReadBlankAndReal[f]; ReadRope[f, "]"]; }; ReadPoint2dAsPoint3d: PUBLIC PROC [f: IO.STREAM] RETURNS [point3d: Point3d] = { ReadRope[f, "["]; point3d[1] _ ReadBlankAndReal[f]; ReadRope[f, ","]; point3d[2] _ ReadBlankAndReal[f]; point3d[3] _ 0; ReadRope[f, "]"]; }; RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = { SELECT char FROM '], ', => RETURN [break]; IO.CR =>RETURN [break]; IO.SP => RETURN [break]; ENDCASE => RETURN [other]; }; ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = { realRope: Rope.ROPE; end: BOOL _ FALSE; [realRope, ----] _ IO.GetTokenRope[f, RealBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {r _ 0.0; RETURN}; IF Rope.Find[realRope, ".", 0, FALSE] = -1 THEN realRope _ Rope.Concat[realRope, ".0"]; r _ IO.GetReal[IO.RIS[realRope]]; }; NATBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = { SELECT char FROM '], IO.CR, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; ReadNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = { end: BOOL _ FALSE; intRope: Rope.ROPE; [intRope, ----] _ IO.GetTokenRope[f, NATBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {n _ 1; RETURN}; n _ IO.GetInt[IO.RIS[intRope]]; }; BoolBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = { SELECT char FROM '], IO.CR, IO.SP, '., ', => RETURN [break]; ENDCASE => RETURN [other]; }; ReadBool: PUBLIC PROC [f: IO.STREAM] RETURNS [truth: BOOL, good: BOOL] = { end: BOOL _ FALSE; boolRope: Rope.ROPE; [boolRope, ----] _ IO.GetTokenRope[f, BoolBreakProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end THEN {good _ FALSE; truth _ FALSE; RETURN}; good _ TRUE; IF Rope.Equal[boolRope, "TRUE", TRUE] THEN truth _ TRUE ELSE IF Rope.Equal[boolRope, "FALSE", TRUE] THEN truth _ FALSE ELSE {truth _ FALSE; good _ FALSE}; }; ReadColor: PUBLIC PROC [f: IO.STREAM] RETURNS [color: Color] = { r, g, b: REAL; ReadChar[f, '[]; r _ ReadBlankAndReal[f]; ReadChar[f, ',]; g _ ReadBlankAndReal[f]; ReadChar[f, ',]; b _ ReadBlankAndReal[f]; ReadChar[f, ']]; color _ ImagerColor.ColorFromRGB[[r, g, b]]; }; -- end of ReadColor ReadSurface: PUBLIC PROC [f: IO.STREAM] RETURNS [surface: REF ANY] = { surfType: Rope.ROPE _ ReadBlankAndWord[f]; SELECT TRUE FROM Rope.Equal[surfType, "tube", FALSE] => { radius, height: REAL; ReadBlankAndRope[f, "[radius:"]; radius _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; ReadBlankAndRope[f, "height:"]; height _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "]"]; surface _ SVMappings.CreateTube[radius, height]; }; Rope.Equal[surfType, "box", FALSE] => { boxSide: Vector3d; ReadBlank[f]; boxSide _ ReadPoint3d[f]; surface _ SVMappings.CreateBox[boxSide[1], boxSide[2], boxSide[3]]; }; Rope.Equal[surfType, "NIL"] => {}; ENDCASE => ERROR; }; -- end of ReadSurface ReadMaterial: PUBLIC PROC [f: IO.STREAM] RETURNS [material: Material] = { matRope: Rope.ROPE _ ReadWord[f]; success: BOOL; [material, success] _ SVArtwork.RopeToMaterial[matRope]; IF NOT success THEN ERROR; }; ReadSMap: PUBLIC PROC [f: IO.STREAM] RETURNS [sMap: SMap] = { mapRope: Rope.ROPE _ ReadWord[f]; success: BOOL; [sMap, success] _ SVArtwork.RopeToSMap[mapRope]; IF NOT success THEN ERROR; }; ReadOMap: PUBLIC PROC [f: IO.STREAM] RETURNS [oMap: OMap] = { mapRope: Rope.ROPE _ ReadWord[f]; success: BOOL; [oMap, success] _ SVArtwork.RopeToOMap[mapRope]; IF NOT success THEN ERROR; }; ReadCamera: PUBLIC PROC [f: IO.STREAM, worldCS: CoordSystem, scene: Scene, version: REAL] RETURNS [fileCamera: FileCamera] = { name: Rope.ROPE; origin, focusPoint: Point3d; slant, focalLength, resolution: REAL; projection: Projection; projectionRope: Rope.ROPE; clippingPlanes: LIST OF Plane; visibleAssemblies: LIST OF Rope.ROPE; frame: FrameBox; success: BOOL; ReadBlankAndRope[f, "Camera:"]; name _ ReadBlankAndWord[f]; ReadBlankAndRope[f, "origin:"]; ReadBlank[f]; origin _ ReadPoint3d[f]; ReadBlankAndRope[f, "focusPoint:"]; ReadBlank[f]; focusPoint _ ReadPoint3d[f]; ReadBlankAndRope[f, "slant:"]; slant _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "resolution:"]; resolution _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "focalLength:"]; focalLength _ ReadBlankAndReal[f]; IF version > 5.1 THEN { ReadBlankAndRope[f, "projection:"]; projectionRope _ ReadBlankAndWord[f]; [projection, success] _ SVGraphics.RopeToProjection[projectionRope]; IF NOT success THEN projection _ perspective; } ELSE projection _ perspective; ReadBlankAndRope[f, "frame:"]; ReadBlank[f]; frame _ ReadFrame[f]; ReadBlankAndRope[f, "clippingPlanes:"]; clippingPlanes _ ReadClippingPlanes[f]; ReadBlankAndRope[f, "visibleAssemblies:"]; visibleAssemblies _ ReadListOfRope[f]; ReadBlank[f]; fileCamera _ SVScene.CreateFileCamera[name, origin, focusPoint, slant, resolution, focalLength, projection, frame, clippingPlanes, visibleAssemblies]; }; ReadClippingPlanes: PUBLIC PROC [f: IO.STREAM] RETURNS [clippingPlanes: LIST OF Plane] = { plane: Plane; continue: BOOL; clippingPlanes _ NIL; continue _ ReadHorizontalBlank[f]; IF NOT continue THEN RETURN; plane _ ReadPlane[f]; clippingPlanes _ AppendPlaneToList[plane, clippingPlanes]; WHILE TRUE DO continue _ ReadHorizontalBlank[f]; IF NOT continue THEN RETURN; ReadRope[f, ","]; ReadBlank[f]; plane _ ReadPlane[f]; clippingPlanes _ AppendPlaneToList[plane, clippingPlanes]; ENDLOOP; }; AppendPlaneToList: PROC [plane: Plane, list: LIST OF Plane] RETURNS [LIST OF Plane] = { z: LIST OF Plane _ list; IF z = NIL THEN RETURN[CONS[plane,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[plane,NIL]; RETURN[list]; }; ReadPlane: PUBLIC PROC [f: IO.STREAM] RETURNS [plane: Plane] = { A, B, C, D: REAL; ReadBlankAndRope[f, "["]; A _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; B _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; C _ ReadBlankAndReal[f]; ReadBlankAndRope[f, ","]; D _ ReadBlankAndReal[f]; ReadBlankAndRope[f, "]"]; plane _ SVPolygon3d.PlaneFromCoefficients[A, B, C, D]; }; ReadStyle: PUBLIC PROC [f: IO.STREAM] RETURNS [style: DrawStyle] = { styleName: Rope.ROPE _ ReadBlankAndWord[f]; success: BOOL; [style, success] _ SVGraphics.RopeToDrawStyle[styleName]; IF NOT success THEN style _ wire; }; -- end of ReadStyle ReadFrame: PUBLIC PROC [f: IO.STREAM] RETURNS [frame: FrameBox] = { success: BOOL; point: Point2d; frame _ NEW[FrameBoxObj]; ReadBlankAndRope[f, "["]; ReadBlank[f]; point _ ReadPoint2d[f]; frame.downLeft[1] _ point[1]; frame.upRight[2] _ point[2]; ReadBlankAndRope[f, ","]; ReadBlank[f]; point _ ReadPoint2d[f]; frame.upRight[1] _ point[1]; frame.downLeft[2] _ point[2]; ReadBlankAndRope[f, "fullScreen:"]; ReadBlank[f]; [frame.fullScreen, success] _ ReadBool[f]; IF NOT success THEN frame.fullScreen _ TRUE; ReadBlankAndRope[f, "]"]; }; -- end of ReadFrame RopesOnOneLineProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED { SELECT char FROM IO.CR =>RETURN [break]; IO.SP, IO.TAB, ', , '; => RETURN [sepr]; ENDCASE => RETURN [other]; }; ReadListOfRope: PUBLIC PROC [f: IO.STREAM] RETURNS [ropeList: LIST OF Rope.ROPE] = { rope: Rope.ROPE; end: BOOL _ FALSE; ropeList _ NIL; WHILE TRUE DO [rope, ----] _ IO.GetTokenRope[f, RopesOnOneLineProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR rope = NIL THEN RETURN; IF Rope.Equal[rope, Rope.FromChar[IO.CR]] THEN RETURN ELSE ropeList _ AppendRopeToRopeList[rope, ropeList]; ENDLOOP; }; AppendRopeToRopeList: PROC [rope: Rope.ROPE, list: LIST OF Rope.ROPE] RETURNS [LIST OF Rope.ROPE] = { z: LIST OF Rope.ROPE _ list; IF z = NIL THEN RETURN[CONS[rope,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[rope,NIL]; RETURN[list]; }; ReadVisibleAssemblies: PUBLIC PROC [f: IO.STREAM, scene: Scene, feedback: FeedbackData] RETURNS [assemblyList: LIST OF Slice] = { end: BOOL _ FALSE; assembly: Slice; assemblyName: Rope.ROPE; continue, found: BOOL; assemblyList _ NIL; found _ TRUE; WHILE continue DO [assemblyName, ----] _ IO.GetTokenRope[f, RopesOnOneLineProc !IO.EndOfStream => {end _ TRUE; CONTINUE}]; IF end OR assemblyName = NIL OR Rope.Equal[assemblyName, Rope.FromChar[IO.CR]] THEN continue _ FALSE ELSE { [assembly, ----] _ SVScene.FindAssemblyFromName[assemblyName, scene ! SVScene.AssemblyNotFound => {found _ FALSE; CONTINUE}]; IF NOT found THEN { index: NAT _ IO.GetIndex[f]; Feedback.PutF[feedback, oneLiner, "Slice %g not found at: %g.", [rope[assemblyName]], [integer[index]]]; Feedback.Blink[feedback]; } ELSE assemblyList _ AppendAssemblyToList[assembly, assemblyList]; }; ENDLOOP; }; AppendAssemblyToList: PROC [assembly: Slice, list: LIST OF Slice] RETURNS [LIST OF Slice] = { z: LIST OF Slice _ list; IF z = NIL THEN RETURN[CONS[assembly,NIL]]; UNTIL z.rest = NIL DO z _ z.rest; ENDLOOP; z.rest _ CONS[assembly,NIL]; RETURN[list]; }; END. 8File: TFI3dImpl.mesa (Text File-In for 3d scenes) Last edited by Bier on March 1, 1987 6:08:51 pm PST Copyright c 1984 by Xerox Corporation. All rights reserved. Contents: convenience functions for parsing low-level parts of a 3d fileout produced by fileout3d.mesa {break, sepr, other} Removes the given rope from the top of the stream. Used to remove formatting words and phrases from 3d files. We are not interested in these strings but only in the data in between them. Signals RopeNotOnTop if some other rope is on top. Convenience function. Equivalent to ReadChar[f, IO.CR]; Reads a rope until , , or are encountered. Used to read in a rope which is data. ie the name of a coordinate system from a 3d file. Reads a rope until a ':' or are encountered. If CR is encountered first, then good is FALSE since ":" is expected after a keyword. Reads a rope UNTIL is encountered. Used to read Solidviews version rope Reads, 's, 's, and 's until something else is encountered. Signals RopeNotOnTop if no white space characters are found. Reads, 's, 's, and 's until something else is encountered. Doesn't mind if no white space characters are found. Treats comments as white space. Reads 's, and 's until something else is encountered. Returns good = FALSE if a CR is encountered before anything else A convenience function. Equivalent to ReadBlank[f]; r _ ReadReal[f]; A convenience function. Equivalent to ReadBlank[f]; word _ ReadWord[f]; A convenience function. Equivalent to ReadBlank[f]; n _ ReadNAT[f]; Assumes the next rope on the stream will be of the form "[,,]". Assumes the next rope on the stream will be of the form "[,]". Assumes the next rope on the stream will be of the form "[,]". Fills in point3d[3] with zero. Reads digits up to the next ], , or . Leaves these terminators on the stream. Reads digits up to the next ], , . Leaves these terminators on the stream. Tries to read TRUE or FALSE from the stream. If it encounters another word, good = FALSE; A copy of List.Nconc1 for LIST OF Plane instead of LIST OF REF ANY A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY A copy of List.Nconc1 for LIST OF Slice instead of LIST OF REF ANY Κ4– "cedar" style˜Iheadšœ1™1Iprocšœ3™3Jšœ Οmœ1™Lšžœ žœ žœ˜#—Lšœ˜—š Ÿ œžœžœžœžœžœ˜@Lšœ žœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ,˜,Lšœ ˜—šŸ œžœžœžœžœžœ žœžœ˜FLšœžœ˜*šžœžœž˜šœžœ˜(Lšœžœ˜Lšœ ˜ Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ0˜0Lšœ˜—šœžœ˜'Lšœ˜Lšœ ˜ Lšœ˜LšœC˜CLšœ˜—Lšœ"˜"Lšžœžœ˜—Lšœ ˜—š Ÿ œžœžœžœžœžœ˜ILšœžœ˜!Lšœ žœ˜Lšœ8˜8Lšžœžœ žœžœ˜Lšœ˜—š Ÿœžœžœžœžœžœ˜=Lšœžœ˜!Lšœ žœ˜Lšœ0˜0Lšžœžœ žœžœ˜Lšœ˜—š Ÿœžœžœžœžœžœ˜=Lšœžœ˜!Lšœ žœ˜Lšœ0˜0Lšžœžœ žœžœ˜Lšœ˜—šŸ œžœžœžœžœ/žœžœ˜~Lšœ žœ˜L˜Lšœ žœ˜%L˜Lšœžœ˜Lšœžœžœ˜Lšœžœžœžœ˜%L˜Lšœ žœ˜Lšœ˜Lšœ˜Lšœ˜L˜ Lšœ˜Lšœ#˜#L˜ Lšœ˜Lšœ˜Lšœ˜Lšœ#˜#Lšœ!˜!Lšœ$˜$Lšœ"˜"šžœžœ˜Lšœ#˜#Lšœ%˜%LšœD˜DLšžœžœ žœ˜-Lšœ˜—Lšžœ˜Lšœ˜L˜ Lšœ˜Lšœ'˜'L˜(Lšœ*˜*Lšœ&˜&L˜ L˜Lšœ–˜–L˜L˜—šŸœžœžœžœžœžœžœžœ ˜ZL˜ Lšœ žœ˜Lšœžœ˜L˜"Lšžœžœ žœžœ˜Lšœ˜Lšœ:˜:šžœžœž˜ L˜"Lšžœžœ žœžœ˜Lšœ˜Lšœ ˜ Lšœ˜Lšœ:˜:—Lšžœ˜Lšœ˜—šŸœžœžœžœžœžœžœ ˜WJšœB™BJšœžœžœ˜Jš žœžœžœžœžœžœ˜(Jšžœ žœžœ žœ˜*Jšœ žœžœ˜Jšžœ˜ Jšœ˜—š Ÿ œžœžœžœžœžœ˜@Lš žœžœžœžœžœ˜Lšœ˜Lšžœ˜Lšœ˜Lšžœ˜Lšœ˜Lšžœ˜Lšœ˜Lšžœ˜Lšœ˜Lš œ*žœžœžœžœ˜6L˜L˜—š Ÿ œžœžœžœžœžœ˜DLšœžœ˜+Lšœ žœ˜Lšœ9˜9Lšžœžœ žœ˜!Lšœ ˜—š Ÿ œžœžœžœžœžœ˜CLšœ žœ˜L˜Lšœžœ˜Lšœ˜L˜ Lšœ˜Lšœ˜Lšœ˜Lšœ˜L˜ Lšœ˜Lšœ˜Lšœ˜Lšœ#˜#L˜ Lšœ*˜*Lšžœžœ žœžœ˜,Lšœ˜Lšœ ˜—šŸœžœžœžœžœžœžœ˜Mšžœž˜Lšžœžœžœ ˜Lš žœžœžœžœ žœ˜(Lšžœžœ ˜—Lšœ˜—šŸœžœžœžœžœžœ žœžœžœ˜TLšœ žœ˜Lšœžœžœ˜Lšœ žœ˜šžœžœž˜ šœ œžœ#˜4Lšœžœžœžœ˜+—Lš žœžœžœžœžœ˜!Lš žœ žœžœžœž˜5Lšžœ1˜5—Lšžœ˜L˜—šŸœžœ žœžœžœžœžœžœžœžœ˜eJšœF™FJšœžœžœžœ˜Jš žœžœžœžœžœžœ˜'Jšžœ žœžœ žœ˜*Jšœ žœžœ˜Jšžœ˜ Jšœ˜L˜—šŸœžœžœžœžœ(žœžœžœ ˜Lšœžœžœ˜Lšœ˜Lšœžœ˜Lšœžœ˜Lšœžœ˜Lšœžœ˜ šžœ ž˜šœ œžœ#˜