DIRECTORY
Convert, GGBasicTypes, GGBoundBox, GGParseIn, Imager, ImagerColor, ImagerColorPrivate, ImagerTransformation, IO, RefText, Rope;

GGParseInImpl: CEDAR PROGRAM
IMPORTS Convert, GGBoundBox, Imager, ImagerColor, ImagerColorPrivate, ImagerTransformation, IO, RefText, Rope
EXPORTS GGParseIn =
BEGIN

SyntaxError: PUBLIC SIGNAL [position: NAT, wasThere: Rope.ROPE, notThere: Rope.ROPE] = CODE;

BoundBox: TYPE = GGBasicTypes.BoundBox;
Color: TYPE = Imager.Color;
Point: TYPE = GGBasicTypes.Point;
SequenceOfReal: TYPE = REF SequenceOfRealObj;
SequenceOfRealObj: TYPE = GGBasicTypes.SequenceOfRealObj;

ReadBlank: PUBLIC PROC [f: IO.STREAM] = {
[] _ IO.SkipWhitespace[f, TRUE];
};

ReadWhiteSpace: PUBLIC PROC [f: IO.STREAM] = {
WhiteSpaceProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED {
SELECT char FROM
IO.TAB => RETURN [other];
IO.CR =>RETURN [other];
IO.SP => RETURN [other];
ENDCASE => RETURN [break];
};
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 SyntaxError[IO.GetIndex[f], "null", "<whitespace>"];
};

ReadHorizontalBlank: PUBLIC PROC [f: IO.STREAM] RETURNS [good: BOOL] = {
HorizontalBlankProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED {
SELECT char FROM
IO.TAB, IO.SP => RETURN [other];
ENDCASE => RETURN [break];
};
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};
};

ReadWord: PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = {
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];
};
[word, ----] _ IO.GetTokenRope[f, WordBreakProc
!IO.EndOfStream => {word _ NIL; CONTINUE}];
};

ReadBlankAndWord: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = {
ReadBlank[f];
word _ ReadWord[f];
};

ReadRope: 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 SyntaxError [IO.GetIndex[f], NIL, rope];
IF NOT c = Rope.Fetch[rope,i-1] THEN 
SIGNAL SyntaxError [IO.GetIndex[f], Rope.FromChar[c], rope];
ENDLOOP;
};

ReadBlankAndRope: PUBLIC PROC [f: IO.STREAM, rope: Rope.ROPE] = {
ReadBlank[f];
ReadRope[f, rope];
};

ReadLine: PUBLIC PROC [f: IO.STREAM] RETURNS [line: Rope.ROPE] = {
LineBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED {
SELECT char FROM
IO.CR =>RETURN [break];
ENDCASE => RETURN [other];
};
end: BOOL _ FALSE;
ReadBlank[f];
[line, ----] _ IO.GetTokenRope[f, LineBreakProc
!IO.EndOfStream => {end _ TRUE; CONTINUE}];
IF end THEN {line _ NIL; RETURN};
[----, ----] _ IO.GetTokenRope[f, LineBreakProc]; -- remove <CR>
};

ReadChar: PUBLIC PROC [f: IO.STREAM, c: CHAR] = {
streamC: CHAR;
ReadBlank[f];
streamC _ IO.GetChar[f];
IF NOT c = streamC THEN SIGNAL SyntaxError[IO.GetIndex[f], Rope.FromChar[streamC], Rope.FromChar[c]];
};

ReadKeyWord: PUBLIC PROC [f: IO.STREAM] RETURNS [keyWord: Rope.ROPE, good: BOOL] = {
KeyWordBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED {
SELECT char FROM
IO.CR =>RETURN [break];
': => RETURN [break];
ENDCASE => RETURN [other];
};
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];
};

ReadNAT: PROC [f: IO.STREAM] RETURNS [n: NAT] = {
NATBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED {
SELECT char FROM
'], IO.CR, IO.SP, '., ',, ': => RETURN [break];
ENDCASE => RETURN [other];
};
end: BOOL _ FALSE;
intRope: Rope.ROPE;
[intRope, ----] _ IO.GetTokenRope[f, NATBreakProc
!IO.EndOfStream => {end _ TRUE; CONTINUE}];
IF end THEN {n _ 1; RETURN};
n _ Convert.IntFromRope[intRope];
};

ReadBlankAndNAT: PUBLIC PROC [f: IO.STREAM] RETURNS [n: NAT] = {
ReadBlank[f];
n _ ReadNAT[f];
};

ReadReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = {
RealBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED {
SELECT char FROM
'), '], ', => RETURN [break];
IO.CR =>RETURN [break];
IO.SP => RETURN [break];
ENDCASE => RETURN [other];
};
realText, buffer: REF TEXT;
end: BOOL _ FALSE;
buffer _ RefText.ObtainScratch[50];
[realText, ----] _ IO.GetToken[f, RealBreakProc, buffer
!IO.EndOfStream => {end _ TRUE; CONTINUE}];
IF end THEN {r _ 0.0; RETURN};
IF RefText.Find[realText, ".", 0, FALSE] = -1 THEN realText _ RefText.Append[realText, ".0"];
r _ Convert.RealFromRope[RefText.TrustTextAsRope[realText]];
RefText.ReleaseScratch[buffer];
};

ReadBlankAndReal: PUBLIC PROC [f: IO.STREAM] RETURNS [r: REAL] = {
ReadBlank[f];
r _ ReadReal[f];
};

ReadColor: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [color: Color] = {
s: IO.STREAM;
word: Rope.ROPE;
isBlackToner, good: BOOL;
IF version < 8701.26 THEN {
word _ ReadColorToken[f];
IF Rope.Equal[word, "none"] THEN RETURN[NIL];
s _ IO.RIS[word, colorStream];
ReadChar[s, '[];
}
ELSE {
word _ ReadBracketedExpression[f];
IF word = NIL THEN RETURN[NIL];
s _ IO.RIS[word, colorStream];
};
IF version >= 8701.26 THEN {
[isBlackToner, good] _ ReadBOOL[s, version];
IF NOT good THEN ERROR;
}
ELSE isBlackToner _ FALSE;
IF isBlackToner THEN {
black: REAL;
black _ ReadBlankAndReal[s];
color _ ImagerColor.ColorFromGray[black];
}
ELSE {
r, g, b: REAL;
r _ ReadBlankAndReal[s];
IF version < 8701.26 THEN ReadChar[s, ',];
g _ ReadBlankAndReal[s];
IF version < 8701.26 THEN ReadChar[s, ',];
b _ ReadBlankAndReal[s];
color _ ImagerColor.ColorFromRGB[[r, g, b]];
};
IF version < 8701.26 AND ImagerColorPrivate.GrayFromColor[NARROW[color]] = 1.0 THEN color _ Imager.black; -- the default used to be "black toner"
}; -- end of ReadColor

ReadColorToken: PUBLIC PROC [f: IO.STREAM] RETURNS [word: Rope.ROPE] = {
ColorBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED {
SELECT char FROM
IO.TAB => RETURN [break];
IO.CR =>RETURN [break];
IO.SP => RETURN [break];
ENDCASE => RETURN [other];
};
ReadBlank[f];
[word, ----] _ IO.GetTokenRope[f, ColorBreakProc
!IO.EndOfStream => {word _ NIL; CONTINUE}];
};

ReadStrokeEnd: PUBLIC PROC [f: IO.STREAM] RETURNS [strokeEnd: Imager.StrokeEnd] = {
endName: Rope.ROPE;
ReadBlank[f];
endName _ ReadBlankAndWord[f];
SELECT TRUE FROM
Rope.Equal[endName, "square", TRUE] => strokeEnd _ square;
Rope.Equal[endName, "butt", TRUE] => strokeEnd _ butt;
Rope.Equal[endName, "round", TRUE] => strokeEnd _ round;
ENDCASE => ERROR;
};

ReadStrokeJoint: PUBLIC PROC [f: IO.STREAM] RETURNS [strokeJoint: Imager.StrokeJoint] = {
endName: Rope.ROPE;
ReadBlank[f];
endName _ ReadBlankAndWord[f];
SELECT TRUE FROM
Rope.Equal[endName, "round", TRUE] => strokeJoint _ round;
Rope.Equal[endName, "miter", TRUE] => strokeJoint _ miter;
Rope.Equal[endName, "bevel", TRUE] => strokeJoint _ bevel;
ENDCASE => ERROR;
};

ReadPoint: PUBLIC PROC [f: IO.STREAM] RETURNS [point: Point] = {
ReadBlank[f];
ReadRope[f, "["];
point.x _ ReadBlankAndReal[f];
ReadRope[f, ","];
point.y _ ReadBlankAndReal[f];
ReadRope[f, "]"];
};

ReadTransformation: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = {
a, b, c, d, e, g: REAL;
ReadBlankAndRope[f, "["];
a _ ReadBlankAndReal[f];
b _ ReadBlankAndReal[f];
c _ ReadBlankAndReal[f];
d _ ReadBlankAndReal[f];
e _ ReadBlankAndReal[f];
g _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "]"];
transform _ ImagerTransformation.Create[a, b, c, d, e, g];
};

ReadFactoredTransformationVEC: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = {
r1, sx, sy, r2 : REAL;
ReadBlankAndRope[f, "[r1:"];
r1 _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "s:"];
ReadBlankAndRope[f, "["];
sx _ ReadBlankAndReal[f];
sy _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "]"];
ReadBlankAndRope[f, "r2:"];
r2 _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "]"];
{
OPEN ImagerTransformation;
transform _ Cat[Rotate[r1], Scale2[[sx, sy]], Rotate[r2]];
};
};

ReadFactoredTransformation: PUBLIC PROC [f: IO.STREAM] RETURNS [transform: ImagerTransformation.Transformation] = {
r1, sx, sy, r2, tx, ty: REAL;
ReadBlankAndRope[f, "[r1:"];
r1 _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "s:"];
ReadBlankAndRope[f, "["];
sx _ ReadBlankAndReal[f];
sy _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "]"];
ReadBlankAndRope[f, "r2:"];
r2 _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "t:"];
ReadBlankAndRope[f, "["];
tx _ ReadBlankAndReal[f];
ty _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "]" ];
ReadBlankAndRope[f, "]" ];
{
OPEN ImagerTransformation;
transform _ Cat[Rotate[r1], Scale2[[sx, sy]], Rotate[r2], Translate[[tx, ty]] ];
};
};

ReadBox: PUBLIC PROC [f: IO.STREAM] RETURNS [box: BoundBox] = {
loX, loY, hiX, hiY: REAL;
ReadBlankAndRope[f, "["];
loX _ ReadBlankAndReal[f];
loY _ ReadBlankAndReal[f];
hiX _ ReadBlankAndReal[f];
hiY _ ReadBlankAndReal[f];
ReadBlankAndRope[f, "]"];
IF loX = 0.0 AND hiX = -1.0 THEN RETURN[GGBoundBox.NullBoundBox[]];
IF loY = 0.0 AND hiY = -1.0 THEN RETURN[GGBoundBox.CreateBoundBox[0,0,0,0,FALSE,TRUE]];
box _ GGBoundBox.CreateBoundBox[loX, loY, hiX, hiY];
};

ReadBOOL: PUBLIC PROC [f: IO.STREAM, version: REAL] RETURNS [truth: BOOL, good: BOOL] = {
BoolBreakProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = TRUSTED {
SELECT char FROM
'], IO.CR, IO.SP, '., ', => RETURN [break];
ENDCASE => RETURN [other];
};
end: BOOL _ FALSE;
boolRope: Rope.ROPE;
ReadBlank[f];
[boolRope, ----] _ IO.GetTokenRope[f, BoolBreakProc
!IO.EndOfStream => {end _ TRUE; CONTINUE}];
IF end THEN {good _ FALSE; truth _ FALSE; RETURN};
good _ TRUE;
IF version >= 8701.26 THEN {
IF Rope.Equal[boolRope, "T", TRUE] THEN truth _ TRUE
ELSE IF Rope.Equal[boolRope, "F", TRUE] THEN truth _ FALSE
ELSE {truth _ FALSE; good _ FALSE};
}
ELSE {
IF Rope.Equal[boolRope, "TRUE", TRUE] THEN truth _ TRUE
ELSE IF Rope.Equal[boolRope, "FALSE", TRUE] THEN truth _ FALSE
ELSE {truth _ FALSE; good _ FALSE};
};
};

ReadListOfRope: PUBLIC PROC [f: IO.STREAM] RETURNS [ropeList: LIST OF Rope.ROPE] = {
RopesOnOneLineOrParenProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED {
SELECT char FROM
IO.CR, '), '] =>RETURN [break];
IO.SP, IO.TAB, ', , '; => RETURN [sepr];
ENDCASE => RETURN [other];
};

rope: Rope.ROPE;
end: BOOL _ FALSE;
ReadBlank[f];
ropeList _ NIL;
WHILE TRUE DO
[rope, ----] _ IO.GetTokenRope[f, RopesOnOneLineOrParenProc
!IO.EndOfStream => {end _ TRUE; CONTINUE}];
IF end OR rope = NIL THEN RETURN;
IF Rope.Equal[rope, Rope.FromChar[IO.CR]] THEN RETURN;
IF Rope.Equal[rope, Rope.FromChar[')]] THEN {
f.Backup[')];
RETURN;
};
IF Rope.Equal[rope, Rope.FromChar[']]] THEN {
f.Backup[']];
RETURN;
};
ropeList _ AppendRopeToRopeList[rope, ropeList];
ENDLOOP;
};

ReadBracketedExpression: PROC [f: IO.STREAM] RETURNS [expr: Rope.ROPE] = {
CloseBracketProc: SAFE PROC [char: CHAR] RETURNS [IO.CharClass] = CHECKED {
SELECT char FROM
'] =>RETURN [break];
ENDCASE => RETURN [other];
};
end: BOOL _ FALSE;
ReadChar[f, '[];
[expr, ----] _ IO.GetTokenRope[f, CloseBracketProc];
IF Rope.Equal[expr, "]"] THEN RETURN[NIL]
ELSE ReadChar[f, ']];
};

RealLength: PROC [list: LIST OF Rope.ROPE] RETURNS [n: INT _ 0] = {
UNTIL list = NIL DO
n _ n+1;
list _ list.rest;
ENDLOOP;
};

ReadArrayOfReal: PUBLIC PROC [f: IO.STREAM] RETURNS [reals: SequenceOfReal] = {
ropeList: LIST OF Rope.ROPE;
real: REAL;
len, index: NAT;
ReadBlankAndRope[f, "["];
ropeList _ ReadListOfRope[f];
ReadBlankAndRope[f, "]"];
len _ RealLength[ropeList];
reals _ NEW[SequenceOfRealObj[len]];
index _ 0;
FOR list: LIST OF Rope.ROPE _ ropeList, list.rest UNTIL list = NIL DO
real _ Convert.RealFromRope[list.first
! Convert.Error => {ERROR SyntaxError[position: IO.GetIndex[f],  wasThere: IO.PutFR["Couldn't convert %g to a REAL", [rope[list.first]]], notThere: NIL]}];
reals[index] _ real;
index _ index + 1;
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];
};

colorStream: IO.STREAM;

Init: PROC [] = {
colorStream _ IO.RIS["This string is longer than any color is likely to be."];
};

Init[];

END.
���	z��GGParseInImpl.mesa
Copyright c 1986 by Xerox Corporation.  All rights reserved.
Last edited by Bier on February 10, 1987 1:37:36 pm PST
Last edited by Pier on February 26, 1987 3:11:28 pm PST
Contents:  Routines for reading gargoyle data structures from a stream.  Stolen from Solidviews Solidmodeler TFI3d.mesa.

Reads, <SPACE>'s, <CR>'s, and <TAB>'s until something else is encountered.  Doesn't mind if no white space characters are found.  Treats comments as white space.
Reads, <SPACE>'s, <CR>'s, and <TAB>'s until something else is encountered.  Signals SyntaxError if no white space characters are found.
Reads <SPACE>'s, and <TABS>'s until something else is encountered.  Returns good = FALSE if a CR is encountered before anything else
Used to read in a rope which is data.
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 SyntaxError if some other rope is on top.
Reads a rope UNTIL <CR> is encountered.
Reads a rope until a ':' or <CR> are encountered.  If CR is encountered first, then good is FALSE since ":" is expected after a keyword.
ReadBlank[f];
Reads digits up to the next ], <CR>, <SPACE>.  Leaves these terminators on the stream.
A convenience function.  Equivalent to ReadBlank[f]; n _ ReadNAT[f];
Reads digits up to the next ), ], <CR>, <SPACE> or <COMMA>.  Leaves these terminators on the stream.
A convenience function.  Equivalent to ReadBlank[f]; r _ ReadReal[f];
Reads a rope until <SPACE>, <CR> or <TAB> are encountered.
Assumes the next rope on the stream will be of the form "[<real1>,<real2>]".
FactoredTransformation: TYPE ~ RECORD[r1: REAL, s: VEC, r2: REAL, t: VEC];
Represents Cat[Rotate[r1], Scale2[s], Rotate[r2], Translate[t]].
Expects "[r1: REAL s: [REAL REAL] r2: REAL ].  No translation"
FactoredTransformation: TYPE ~ RECORD[r1: REAL, s: VEC, r2: REAL, t: VEC];
Represents Cat[Rotate[r1], Scale2[s], Rotate[r2], Translate[t]].
Gargoyle file format "[r1: REAL s: [REAL REAL] r2: REAL t: [REAL REAL] ]"
Tries to read T or F from the stream.  If it encounters another word, good = FALSE;
Reads a list of REALs enclosed in square brackets, separated by spaces, tabs, commas, or semi-colons.  For instance [3.5, 2.6, 1, 4. 3.0 ] returns a list of 5 real numbers.
A copy of List.Nconc1 for LIST OF Rope.ROPE instead of LIST OF REF ANY
Ê²��˜�Icodešœ™Kšœ
Ïmœ1™<Kšœ7™7Kšœ7™7Kšœx™xK™�šÏk	˜	Kšœžœ,žœ(žœ˜—K˜�šœžœž˜Kšžœ(žœ(žœ
˜mKšžœ˜—Kšž˜K˜�Iprocš
œ
žœžœžœžœžœžœ˜\L˜�Lšœ
žœ˜'Lšœžœ˜Lšœžœ˜!Lšœžœžœ˜-Lšœžœ"˜9L˜�š
Ïn	œžœžœžœžœ˜)Lšœ¡™¡Lšœžœžœ˜ Lšœ˜L˜�—š
Ÿœžœžœžœžœ˜.Lšœ‡™‡šŸœžœžœžœžœžœžœ˜Išžœž˜Lšžœžœžœ	˜Lšžœžœžœ	˜Lšžœžœžœ	˜Lšžœžœ	˜—Lšœ˜—Lšœžœ˜Lšœžœžœ˜šœ
Ïcœžœ˜6Lšœžœžœžœ˜+—Lš
žœžœžœžœ
žœ&˜dLšœ˜L˜�—šŸœžœžœžœžœžœžœ˜HLšœ„™„šŸœžœžœžœžœžœžœ˜Nšžœž˜Lš
žœžœžœžœžœ	˜ Lšžœžœ	˜—Lšœ˜—Lšœžœ˜Lšœžœ˜Lšœžœžœ˜Lšœžœ˜šœ
 œžœ$˜;Lšœžœžœžœ˜+—Lšžœžœ	žœžœ˜#Lšœ˜šžœž˜
Lšžœžœžœžœ˜ Lšžœžœžœžœžœžœ˜'Lšžœžœžœžœ˜2—Lšœ˜L˜�—šŸœžœžœžœžœ
žœ˜;Lšœ%™%šŸ
œžœžœžœžœžœžœ˜Hšžœž˜Lšžœžœžœ	˜Lšžœžœžœ	˜Lšžœžœžœ	˜Lšœžœ	˜Lšœžœ	˜Lšœžœ	˜Lšžœžœ	˜—Lšœ˜—šœ œžœ˜/Lšœžœžœžœ˜+—Lšœ˜L˜�—šŸœžœžœžœžœžœ
žœ˜JLšœ
˜
Lšœ˜Lšœ˜L˜�—š
Ÿœžœžœžœ
žœ˜2Lšœ»™»Lšœ1™1Lšœžœ˜Lšœ
žœžœ˜šžœžœžœž˜&šœžœ
˜LšœÐkrÏrœžœžœ˜4—šžœ
žœ˜Lšžœžœžœ˜/—šžœžœžœ˜%Lšžœžœ&˜<——Lšžœ˜Lšœ˜L˜�—šŸœžœžœžœžœ
žœ˜ALšœ
˜
Lšœ˜Lšœ˜L˜�—šŸœžœžœžœžœžœ
žœ˜BLšœ'™'šŸ
œžœžœžœžœžœžœ˜Hšžœž˜Lšžœžœžœ	˜Lšžœžœ	˜—Lšœ˜—Lšœžœžœ˜Lšœ
˜
šœ œžœ˜/Lšœžœžœžœ˜+—Lšžœžœ	žœžœ˜!Lšœ œ œžœ! ˜@Lšœ˜L˜�—šŸœžœžœžœžœžœ˜1Lšœ	ž˜Lšœ
˜
Lšœ
žœ˜Lš
žœžœ
žœžœ
žœ8˜eLšœ˜L˜�—šŸœžœžœžœžœžœžœžœ˜TLšœˆ™ˆšŸœžœžœžœžœžœžœ˜Kšžœž˜Lšžœžœžœ	˜Lšœžœ	˜Lšžœžœ	˜—Lšœ˜—Lšœžœžœ˜Lšœžœ˜Lšœ
™
šœ
 œžœ!˜5Lšœžœžœžœ˜+—Lš
žœžœ	žœžœžœ˜2šœ œžœ!˜6Lšœžœžœžœ˜+—Lšžœžœ	žœžœ˜#Lšœ!žœ˜'Lšœ˜L˜�—šŸœžœžœžœžœžœ˜1LšœV™VšŸœžœžœžœžœžœžœ˜Gšžœž˜Lšœžœžœžœžœžœ	˜/Lšžœžœ	˜—Lšœ˜—Lšœžœžœ˜Lšœžœ˜šœ
 œžœ˜1Lšœžœžœžœ˜+—Lšžœžœ	žœ˜Lšœ!˜!Lšœ˜L˜�—šŸœžœžœžœžœžœžœ˜@LšœD™DLšœ
˜
Lšœ˜Lšœ˜L˜�—šŸœžœžœžœžœžœžœ˜:Lšœd™dšŸ
œžœžœžœžœžœžœ˜Hšžœž˜Lšœžœ	˜Lšžœžœžœ	˜Lšžœžœžœ	˜Lšžœžœ	˜—Lšœ˜—Lšœžœ˜Lšœžœžœ˜Lšœ#˜#šœ œžœ"˜7Lšœžœžœžœ˜+—Lšžœžœžœ˜Lšžœ žœžœ+˜]Lšœ<˜<Lšœ˜Lšœ˜L˜�—šŸœžœžœžœžœžœžœ˜BLšœE™ELšœ
˜
Lšœ˜Lšœ˜L˜�—šŸ	œžœžœžœžœžœžœ˜OLšœžœžœ˜
Lšœžœ˜Lšœžœ˜šžœžœ˜Lšœ˜Kšžœžœžœžœ˜-Kšœžœžœ˜K˜K˜—šžœ˜Lšœ"˜"Lš
žœžœžœžœžœ˜Kšœžœžœ˜L˜—šžœžœ˜Lšœ,˜,Lšžœžœžœžœ˜L˜—Lšžœžœ˜šžœžœ˜Lšœžœ˜Lšœ˜Lšœ)˜)L˜—šžœ˜Lšœ	žœ˜Lšœ˜Lšžœžœ˜*Lšœ˜Lšžœžœ˜*Lšœ˜Lšœ,˜,L˜—Kš	žœžœ"žœžœ '˜‘Lšœ ˜L˜�—šŸœžœžœžœžœžœ
žœ˜HLšœ:™:šŸœžœžœžœžœžœžœ˜Išžœž˜Lšžœžœžœ	˜Lšžœžœžœ	˜Lšžœžœžœ	˜Lšžœžœ	˜—Lšœ˜—L˜
šœ œžœ˜0Lšœžœžœžœ˜+—Lšœ˜L˜�—šŸ
œžœžœžœžœžœ"˜SLšœž˜Lšœ
˜
Lšœ˜Lšžœžœž˜Lšœžœ˜:Lšœžœ˜6Lšœžœ˜8Lšžœžœ˜L˜L˜�—šŸœžœžœžœžœžœ&˜YLšœž˜Lšœ
˜
Lšœ˜šžœžœž˜Lšœžœ˜:Lšœžœ˜:Lšœžœ˜:Lšžœžœ˜—L˜L˜�—šŸ	œžœžœžœžœžœ˜@LšœL™LLšœ
˜
Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜L˜�—šŸœžœžœžœžœžœ5˜kLšœžœ˜L˜L˜L˜L˜L˜L˜L˜L˜Lšœ:˜:L˜L˜�—šŸœžœžœžœžœžœ5˜vš
œžœžœžœžœžœžœ™JKšœ@™@Kšœ>™>—Lšœžœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜šœ˜L•StartOfExpansionÄ[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šžœ˜K–Ä[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šœ:˜:Lšœ˜—L˜L˜�—šŸœžœžœžœžœžœ5˜sš
œžœžœžœžœžœžœ™JKšœ@™@KšœI™I—Lšœžœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜šœ˜L–Ä[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šžœ˜K–Ä[m1: ImagerTransformation.Transformation _ NIL, m2: ImagerTransformation.Transformation _ NIL, m3: ImagerTransformation.Transformation _ NIL, m4: ImagerTransformation.Transformation _ NIL]šœP˜PLšœ˜—Lšœ˜L˜�—šŸœžœžœžœžœžœ˜?Lšœžœ˜L˜L˜L˜L˜L˜L˜Lšžœžœžœžœ˜CLšžœžœžœžœ#žœžœ˜WLšœ4˜4L˜L˜�—šŸœžœžœžœžœžœžœ	žœžœ˜YLšœS™SšŸ
œžœžœžœžœžœžœ˜Hšžœž˜Lšœžœžœžœžœžœ	˜+Lšžœžœ	˜—Lšœ˜—Lšœžœžœ˜Lšœžœ˜Lšœ
˜
šœ œžœ˜3Lšœžœžœžœ˜+—Lš
žœžœ	žœ
žœžœ˜2Lšœžœ˜šžœžœ˜Lšžœžœžœ	ž˜4š	žœžœžœžœ	ž˜:Lšžœ
žœ	žœ˜#—L˜—šžœ˜Lšžœžœžœ	ž˜7š	žœžœžœžœ	ž˜>Lšžœ
žœ	žœ˜#—L˜—Lšœ˜L˜�—šŸœžœžœžœžœžœžœžœžœ˜TšŸœžœžœžœžœžœžœ˜Tšžœž˜Lšžœžœžœ	˜Lš
žœžœžœžœ
žœ˜(Lšžœžœ	˜—Lšœ˜—Lšœžœ˜Lšœžœžœ˜Lšœ
˜
Lšœžœ˜šžœžœž˜
šœ œžœŸ˜;Lšœžœžœžœ˜+—Lš
žœžœžœžœžœ˜!Lš
žœ žœžœžœžœ˜6šžœ%žœ˜-Lšœ
˜
Lšžœ˜L˜—šžœ%žœ˜-Lšœ
˜
Lšžœ˜L˜—Lšœ0˜0—Lšžœ˜L˜L˜�—šŸœžœžœžœžœ
žœ˜JšŸœžœžœžœžœžœžœ˜Kšžœž˜Lšœžœ	˜Lšžœžœ	˜—Lšœ˜—Lšœžœžœ˜L˜Lšœ œžœ#˜4Lšžœžœžœžœ˜)Lšžœ˜L˜L˜�—šŸ
œžœžœžœžœžœžœ	˜Cšžœžœž˜Kšœ˜Kšœ˜Kšžœ˜—L˜L˜�—šŸœžœžœžœžœžœ˜OL™¬Lšœ
žœžœž˜Lšœžœ˜Lšœžœ˜L˜Lšœ˜L˜Lšœ˜Lšœžœ˜$L˜
š
žœžœžœžœžœžœž˜Ešœ&˜&Lš	œžœžœžœGžœ˜›—Lšœ˜Lšœ˜Lšžœ˜—L˜L˜�—šŸœžœ
žœžœžœžœžœžœžœžœ˜eJšœF™FJšœžœžœžœ˜Jšžœžœžœžœžœžœ˜'Jšžœ
žœžœ
žœ˜*Jšœ	žœžœ˜Jšžœ˜
Jšœ˜—J˜�Jšœ
žœžœ˜J˜�šŸœžœ˜Jšœžœžœ:˜NJ˜—J˜�J˜L˜�Kšžœ˜—�…—����2��U8��