DIRECTORY IO USING [int, Put, PutChar, PutRope, PutText, real, STREAM], IPBasic USING [PrimitiveOrSymbol, Rational], IPEncoding USING [Error, nullToken, Reader, ReaderProcs, ReaderRep, Register, Token, TokenType, Writer, WriterProcs, WriterRep], IPWritten USING [], Real USING [ReadReal], Rope USING [ActionType, FromProc, FromRefText, Map, ROPE, Substr], RopeReader USING [Backwards, Get, GetIndex, GetRope, Peek, Ref, SetCharForEndOfRope, SetIndex]; IPWrittenEncodingImpl: CEDAR PROGRAM IMPORTS IO, IPEncoding, Real, Rope, RopeReader EXPORTS IPWritten = BEGIN OPEN IPEncoding, IPBasic; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; NonDefaultingText: TYPE = REF TEXT _; EncodeTable: TYPE = ARRAY PrimitiveOrSymbol OF NonDefaultingText; encode: REF READONLY EncodeTable = NEW[EncodeTable = [nil: NIL, abs: "ABS", add: "ADD", and: "AND", arcto: "ARCTO", atan: "ATAN", ceiling: "CEILING", clipoutline: "CLIPOUTLINE", cliprectangle: "CLIPRECTANGLE", concat: "CONCAT", concatt: "CONCATT", conicto: "CONICTO", copy: "COPY", correct: "CORRECT", correctmask: "CORRECTMASK", correctspace: "CORRECTSPACE", cos: "COS", count: "COUNT", curveto: "CURVETO", div: "DIV", do: "DO", dobody: "DOBODY", dosave: "DOSAVE", dosaveall: "DOSAVEALL", dosaveallbody: "DOSAVEALLBODY", dosavebody: "DOSAVEBODY", dosavesimplebody: "DOSAVESIMPLEBODY", dround: "DROUND", dup: "DUP", env: "ENV", eq: "EQ", eqn: "EQN", exch: "EXCH", exp: "EXP", fget: "FGET", findcolor: "FINDCOLOR", findcolormodeloperator: "FINDCOLORMODELOPERATOR", findcoloroperator: "FINDCOLOROPERATOR", finddecompressor: "FINDDECOMPRESSOR", findfont: "FINDFONT", findfontvec: "FINDFONTVEC", floor: "FLOOR", frame: "FRAME", fset: "FSET", ge: "GE", get: "GET", getcp: "GETCP", getcprounded: "GETCPROUNDED", getp: "GETP", getprop: "GETPROP", gt: "GT", if: "IF", ifcopy: "IFCOPY", ifelse: "IFELSE", iget: "IGET", invert: "INVERT", iset: "ISET", lineto: "LINETO", linetox: "LINETOX", linetoy: "LINETOY", log: "LOG", loop: "LOOP", makeco: "MAKECO", makecompiledimage: "MAKECOMPILEDIMAGE", makegray: "MAKEGRAY", makeoutline: "MAKEOUTLINE", makepixelarray: "MAKEPIXELARRAY", makepool: "MAKEPOOL", makesampledblack: "MAKESAMPLEDBLACK", makesampledcolor: "MAKESAMPLEDCOLOR", makesimpleco: "MAKESIMPLECO", maket: "MAKET", makevec: "MAKEVEC", makeveclu: "MAKEVECLU", mark: "MARK", maskfill: "MASKFILL", maskpixel: "MASKPIXEL", maskrectangle: "MASKRECTANGLE", maskstroke: "MASKSTROKE", maskstrokeclosed: "MASKSTROKECLOSED", masktrapezoidx: "MASKTRAPEZOIDX", masktrapezoidy: "MASKTRAPEZOIDY", maskunderline: "MASKUNDERLINE", maskvector: "MASKVECTOR", max: "MAX", mergeprop: "MERGEPROP", min: "MIN", mod: "MOD", modifyfont: "MODIFYFONT", move: "MOVE", moveto: "MOVETO", mul: "MUL", neg: "NEG", nop: "NOP", nopool: "NOPOOL", not: "NOT", opent: "OPENT", openvec: "OPENVEC", or: "OR", pget: "PGET", pool: "POOL", poolop: "POOLOP", pop: "POP", pset: "PSET", rem: "REM", roll: "ROLL", rotate: "ROTATE", round: "ROUND", roundxy: "ROUNDXY", roundxyvec: "ROUNDXYVEC", scale: "SCALE", scale2: "SCALE2", setcorrectmeasure: "SETCORRECTMEASURE", setcorrecttolerance: "SETCORRECTTOLERANCE", setfont: "SETFONT", setgray: "SETGRAY", setxrel: "SETXREL", setxy: "SETXY", setxyrel: "SETXYREL", setyrel: "SETYREL", shape: "SHAPE", show: "SHOW", showandxrel: "SHOWANDXREL", sin: "SIN", space: "SPACE", sqrt: "SQRT", startunderline: "STARTUNDERLINE", sub: "SUB", trans: "TRANS", transform: "TRANSFORM", transformvec: "TRANSFORMVEC", translate: "TRANSLATE", trunc: "TRUNC", type: "TYPE", unmark: "UNMARK", unmark0: "UNMARK0", beginBlock: "BEGIN", endBlock: "END", beginBody: "{", endBody: "}", pageInstructions: "PAGEINSTRUCTIONS", noPages: "NOPAGES", beginVec: "[", comma: ",", endVec: "]" ]]; Match: PROC[a, b: REF READONLY TEXT] RETURNS[BOOL] = INLINE { RETURN[IF a.length=b.length THEN MatchChars[a, b] ELSE FALSE]; }; MatchChars: PROC[a, b: REF READONLY TEXT] RETURNS[BOOL] = { len: NAT = a.length; IF b.length#len THEN RETURN[FALSE]; FOR i: NAT IN[0..len) DO IF a[i]#b[i] THEN RETURN[FALSE] ENDLOOP; RETURN[TRUE]; }; Decode: PROC[name: REF READONLY TEXT] RETURNS[PrimitiveOrSymbol] = { FOR op: PrimitiveOrSymbol IN PrimitiveOrSymbol DO IF op#nil AND Match[name, encode[op]] THEN RETURN[op]; ENDLOOP; RETURN[nil]; }; RopeFromOp: PUBLIC PROC[op: PrimitiveOrSymbol] RETURNS[ROPE] = { RETURN[Rope.FromRefText[encode[op]]]; }; readerProcs: REF READONLY ReaderProcs = NEW[ReaderProcs = [ GetToken: GetToken, GetInt: GetInt, GetRational: GetRational, GetReal: GetReal, GetRope: GetRope ]]; EOF: CHAR = '\000; -- end of file marker (the master better not include any NULs) bufferSize: NAT = 50; -- must be enough for longest primitive name NewReader: PROC[ropeReader: RopeReader.Ref] RETURNS[Reader] = { self: Reader = NEW[ReaderRep _ [procs: NIL, ropeReader: NIL, buffer: NIL, bytesRemaining: 0, startingIndex: 0]]; self.procs _ readerProcs; self.ropeReader _ ropeReader; self.buffer _ NEW[TEXT[bufferSize]]; self.startingIndex _ ropeReader.GetIndex[]; ropeReader.SetCharForEndOfRope[EOF]; RETURN[self]; }; Get: PROC[self: Reader] RETURNS[CHAR] = INLINE { RETURN[self.ropeReader.Get[]] }; Peek: PROC[self: Reader] RETURNS[CHAR] = INLINE { RETURN[self.ropeReader.Peek[]] }; BackUp: PROC[self: Reader] = INLINE { [] _ self.ropeReader.Backwards[] }; GetIndex: PROC[self: Reader] RETURNS[INT] = INLINE { RETURN[self.ropeReader.GetIndex[]] }; SetIndex: PROC[self: Reader, index: INT] = INLINE { self.ropeReader.SetIndex[index] }; GetBaseRope: PROC[self: Reader] RETURNS[ROPE] = INLINE { RETURN[self.ropeReader.GetRope[]] }; GetToken: PROC[self: Reader, index: INT] RETURNS[Token] = { name: REF TEXT _ self.buffer; len: NAT _ 0; -- character count maxLen: NAT = name.maxLength; token: Token _ nullToken; state: {null, paren, file, star, op, id, string, escape, escape2, escape3, com, comdash, plus, dash, int, integer, dnext, dsign, denom, dot, fraction, enext, esign, expon} _ null; val: NAT _ 0; -- short integer value maxVal: NAT = (LAST[NAT]-9)/10; lcount, rcount: NAT _ 0; -- digits to left and right of . or / SetIndex[self, token.index _ index]; DO char: CHARACTER = Get[self]; SELECT state FROM null => SELECT char FROM EOF => { token.type _ eof; GOTO Stop }; ' , '\n, '\t => { token.index _ GetIndex[self] }; '{ => { token.op _ beginBody; token.type _ op; GOTO Stop }; '} => { token.op _ endBody; token.type _ op; GOTO Stop }; '[ => { token.op _ beginVec; token.type _ op; GOTO Stop }; ', => { token.op _ comma; token.type _ op; GOTO Stop }; '] => { token.op _ endVec; token.type _ op; GOTO Stop }; '< => { len _ 0; state _ string }; -- begin string '( => { state _ paren }; -- might begin (* '+ => { state _ plus }; -- might begin number '- => { state _ dash }; -- might begin number or comment '. => { state _ dot }; -- might begin real IN['0..'9] => { lcount _ 1; state _ integer }; -- begin integer IN['A..'Z] => { name[0] _ char; len _ 1; state _ op }; -- begin op IN['a..'z] => { state _ id; len _ 1 }; -- begin identifier ENDCASE => { ERROR Error["invalid character"]; --GOTO Stop-- }; paren => SELECT char FROM '* => { len _ 0; state _ file }; -- next char begins name for insertFile ENDCASE => { ERROR Error["misused ("]; --GOTO Stop-- }; -- left paren alone file => SELECT char FROM '* => { state _ star }; -- look for ) ENDCASE => { len _ len+1 }; -- extend file name star => SELECT char FROM ') => { token.type _ insertFile; GOTO Stop }; -- end insertFile ENDCASE => { len _ len+2; state _ file }; -- extend file name op => SELECT char FROM IN['A..'Z], IN['0..'9] => { IF len { len _ len+1; state _ id }; -- must be an id ENDCASE => { -- end op token IF len<=maxLen THEN { name.length _ len; token.op _ Decode[name] }; IF token.op#nil THEN token.type _ op ELSE token.type _ identifier; -- *** or raise an Error *** GOTO Back; }; id => SELECT char FROM IN['a..'z], IN['A..'Z], IN['0..'9], '- => { len _ len+1 }; -- extend id ENDCASE => { token.type _ identifier; GOTO Back }; string => SELECT char FROM '> => { token.type _ string; GOTO Stop }; '\\ => { state _ escape }; -- escape sequence follows ENDCASE => { len _ len+1 }; -- extend string escape => SELECT char FROM IN['0..'9] => { state _ escape2 }; -- 1st of three digits ENDCASE => { len _ len+1; state _ string }; escape2 => SELECT char FROM IN['0..'9] => { state _ escape3 }; -- 2nd digit ENDCASE => ERROR Error["invalid escape sequence"]; escape3 => SELECT char FROM IN['0..'9] => { len _ len+1; state _ string }; -- 3rd digit ENDCASE => ERROR Error["invalid escape sequence"]; com => SELECT char FROM '- => { state _ comdash }; -- another dash will end comment ENDCASE => { len _ len+1 }; -- extend comment comdash => SELECT char FROM '- => { token.index _ GetIndex[self]; state _ null }; -- ignore annotation ENDCASE => { len _ len+2; state _ com }; -- false alarm; extend comment plus => SELECT char FROM IN['0..'9] => { val _ (char-'0); lcount _ 1; state _ int }; -- first integer digit ENDCASE => { ERROR Error["misused +"]; --GOTO Back-- }; -- plus sign alone dash => SELECT char FROM '- => { len _ 0; state _ com }; -- begin comment with next char IN['0..'9] => { lcount _ 1; state _ integer }; -- first integer digit ENDCASE => { ERROR Error["misused -"]; --GOTO Back-- }; -- minus sign alone integer => SELECT char FROM IN['0..'9] => { lcount _ lcount+1 }; -- integer digit '. => { state _ fraction }; -- fraction coming '/ => { state _ dnext }; -- denominator coming 'E, 'e => { state _ enext }; -- exponent coming ENDCASE => { token.type _ int; GOTO Back }; -- end integer token dnext => SELECT char FROM '+, '- => { state _ dsign }; -- denominator sign IN['0..'9] => { rcount _ 1; state _ denom }; -- first denominator digit ENDCASE => { ERROR Error["missing denominator"]; --GOTO Back-- }; dsign => SELECT char FROM IN['0..'9] => { rcount _ 1; state _ denom }; -- first denominator digit ENDCASE => { ERROR Error["invalid denominator"]; --GOTO Back-- }; denom => SELECT char FROM IN['0..'9] => { rcount _ rcount+1 }; -- extend denominator ENDCASE => { -- end rational token token.type _ (IF MAX[lcount, rcount]<10 THEN rational ELSE real); GOTO Back; }; dot => SELECT char FROM IN['0..'9] => { rcount _ 1; state _ fraction }; -- first fraction digit ENDCASE => { ERROR Error["misused ."]; --GOTO Back-- }; -- no digits after dot fraction => SELECT char FROM IN['0..'9] => { rcount _ rcount+1 }; -- extend fraction 'E, 'e => { state _ enext }; -- exponent coming ENDCASE => { -- end real token with no exponent token.type _ real; GOTO Back; }; enext => SELECT char FROM '+, '- => { state _ esign }; -- exponent sign IN['0..'9] => { state _ expon }; -- first exponent digit ENDCASE => { ERROR Error["missing exponent"]; --GOTO Back-- }; esign => SELECT char FROM IN['0..'9] => { state _ expon }; -- first exponent digit ENDCASE => { ERROR Error["invalid exponent"]; --GOTO Back-- }; expon => SELECT char FROM IN['0..'9] => { }; -- extend exponent ENDCASE => { token.type _ real; GOTO Back }; -- end real token ENDCASE => ERROR; -- unknown state IF char=EOF THEN { ERROR Error["end of file inside token"]; --GOTO Back-- }; REPEAT Stop => NULL; -- token ends with current char Back => BackUp[self]; -- token ended with previous char ENDLOOP; token.length _ len; token.next _ GetIndex[self]; RETURN[token]; }; ReadInt: PROC[self: Reader] RETURNS[INT] = { i: INT _ 0; sign: CHAR _ '+; IF Peek[self] NOT IN['0..'9] THEN sign _ Get[self]; DO c: CHAR = Get[self]; IF c IN['0..'9] THEN i _ i*10+(c-'0) ELSE { BackUp[self]; EXIT }; ENDLOOP; RETURN[IF sign='- THEN -i ELSE i]; }; ReadReal: PROC[self: Reader] RETURNS[REAL] = { get: PROC RETURNS[CHAR] = { RETURN[Get[self]] }; putback: PROC[CHAR] = { BackUp[self] }; r: REAL = Real.ReadReal[get, putback]; RETURN[r]; }; GetInt: PROC[self: Reader, token: Token] RETURNS[INT] = { SetIndex[self, token.index]; IF token.type=int THEN { i: INT = ReadInt[self]; RETURN[i]; } ELSE ERROR Error["wrong token type"]; }; GetRational: PROC[self: Reader, token: Token] RETURNS[Rational] = { SetIndex[self, token.index]; IF token.type=rational THEN { r: Rational; r.num _ ReadInt[self]; IF Get[self]#'/ THEN ERROR Error["malformed rational"]; r.den _ ReadInt[self]; RETURN[r]; } ELSE ERROR Error["wrong token type"]; }; GetReal: PROC[self: Reader, token: Token] RETURNS[REAL] = { SetIndex[self, token.index]; IF token.type=real THEN { r: REAL = ReadReal[self]; RETURN[r]; } ELSE ERROR Error["wrong token type"]; }; GetRope: PROC[self: Reader, token: Token] RETURNS[ROPE] = { base: ROPE = GetBaseRope[self]; SELECT token.type FROM identifier => RETURN[Rope.Substr[base, token.index, token.length]]; string => RETURN[GetString[self, token]]; comment => RETURN[Rope.Substr[base, token.index+2, token.length]]; insertFile => RETURN[Rope.Substr[base, token.index+2, token.length]]; ENDCASE => ERROR Error["wrong token type"]; }; GetString: PROC[self: Reader, token: Token] RETURNS[string: ROPE] = { gp: PROC RETURNS[c: CHAR] = { c _ Get[self]; IF c='> THEN ERROR; IF c='\\ THEN { c _ Get[self]; SELECT c FROM 'n, 'N => c _ '\n; 'r, 'R => c _ '\r; 't, 'T => c _ '\t; 'b, 'B => c _ '\b; 'f, 'F => c _ '\f; 'l, 'L => c _ '\l; IN['0..'9] => { x: NAT _ c-'0; c _ Get[self]; IF c IN['0..'9] THEN x _ x*10B+(c-'0) ELSE ERROR; c _ Get[self]; IF c IN['0..'9] THEN x _ x*10B+(c-'0) ELSE ERROR; c _ LOOPHOLE[x MOD 400B]; }; ENDCASE; }; RETURN[c] }; SetIndex[self, token.index]; IF Get[self]#'< THEN ERROR Error["invalid string"]; string _ Rope.FromProc[token.length, gp]; IF Get[self]#'> THEN ERROR Error["invalid string"]; }; writerProcs: REF READONLY WriterProcs = NEW[WriterProcs = [ PutOp: PutOp, PutInt: PutInt, PutRational: PutRational, PutReal: PutReal, PutRope: PutRope ]]; NewWriter: PROC[stream: STREAM] RETURNS[Writer] = { self: Writer = NEW[WriterRep _ [procs: writerProcs, stream: stream]]; RETURN[self]; }; PutOp: PROC[self: Writer, op: IPBasic.PrimitiveOrSymbol] = { s: STREAM = self.stream; name: REF READONLY TEXT = encode[op]; IF name=NIL THEN ERROR Error["invalid op"]; s.PutText[name]; s.PutChar[' ]; }; PutInt: PROC[self: Writer, i: INT] = { s: STREAM = self.stream; s.Put[IO.int[i]]; s.PutChar[' ]; }; PutRational: PROC[self: Writer, r: Rational] = { s: STREAM = self.stream; s.Put[IO.int[r.num]]; s.PutChar['/]; s.Put[IO.int[r.den]]; s.PutChar[' ]; }; PutReal: PROC[self: Writer, r: REAL] = { s: STREAM = self.stream; s.Put[IO.real[r]]; s.PutChar[' ]; }; LowerCase: PROC[c: CHAR] RETURNS[CHAR] = INLINE { RETURN[IF c IN['A..'Z] THEN 'a+(c-'A) ELSE c] }; PutRope: PROC[self: Writer, type: TokenType, text: ROPE] = { s: STREAM = self.stream; SELECT type FROM identifier => s.PutRope[text]; string => PutString[s, text]; comment => { s.PutRope["**"]; s.PutRope[text]; s.PutRope["**"]; }; insertFile => { s.PutRope["(*"]; s.PutRope[text]; s.PutRope["*)"]; }; largeVec => { put: PROC[c: CHAR] RETURNS[BOOL] = { n: NAT = LOOPHOLE[c]; s.Put[IO.int[n]]; s.PutChar[' ]; RETURN[FALSE]; }; s.PutRope["[ "]; [] _ Rope.Map[base: text, action: put]; s.PutRope["]"]; }; ENDCASE => ERROR Error["wrong token type for PutRope"]; s.PutChar[' ]; }; PutString: PROC[s: STREAM, string: ROPE] = { pp: Rope.ActionType --PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE]-- = { SELECT c FROM '\\, '<, '> => { s.PutChar['\\]; s.PutChar[c] }; <40C, >176C => { n: NAT = LOOPHOLE[c]; s.PutChar['\\]; s.PutChar['0+(n/100B) MOD 10B]; s.PutChar['0+(n/10B) MOD 10B]; s.PutChar['0+(n/1B) MOD 10B]; }; ENDCASE => s.PutChar[c]; }; s.PutChar['<]; [] _ Rope.Map[base: string, action: pp]; s.PutChar['>]; }; IPEncoding.Register["Written", [2,0], NewReader, NewWriter]; END. ˆIPWrittenEncodingImpl.mesa Last edited by: Doug Wyatt, April 29, 1983 4:45 pm maybe some day this search will be made smarter... Κ˜headšœ™šœ™Jšœ"™"—J˜šΟk ˜ Jšœœ-œ˜=Jšœœ˜,Jšœ œp˜€Jšœ œ˜Jšœœ ˜Jšœœ*œ ˜BJšœ œO˜_—J˜—šœœ˜$Jšœœ$˜.Jšœ ˜Jšœœœ˜!J˜Jšœœœ˜Jšœœœœ˜J˜Jšœœœœ˜%Jšœ œœœ˜AJ˜š œœœœœ˜?Jšœœ œ œ œ œ œ œ œ œ œ œ œ œ œ œ œ œ œ œœ œ œ œ œ œœ œ œ œœ œ œ œ œ œœœœœ œ œ œ œœ œ œ œ œ œœœ œ œ œ œ œ œ œ œ œ œ œœœ œœœœœ œ œ œ œ œœ œ œ œœœœ œ œ œ œ œ œ œ œ œ œ œ œ œ œ œ œœ œ œ œ œ œ œ œ œ œ œ œ œ œœœ œ œ œ œœ œ œ œ œ œ œ œœ œ œ œ œ œ œ œ œ œ˜₯Jš œ œœ4œ œ)˜€Jšœ˜—J˜šΟnœœœœœœœœ˜=Jš œœœœœ˜>Jšœ˜—J˜šž œœœœœœœ˜;Jšœœ ˜Jšœœœœ˜#Jšœœœ œœ œœœœ˜AJšœœ˜ Jšœ˜—J˜š žœœœœœœ˜DJšœ2™2šœœ˜1Jšœœœœ˜6Jšœ˜—Jšœ˜ J˜—J˜š ž œœœœœ˜@Jšœ˜%J˜—J˜šœ œœœ˜;Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—J˜Jšœœ Οc>˜QJ˜Jšœ œŸ,˜BJ˜šž œœœ ˜?šœœœ˜+Jšœ œ œ(˜D—J˜Jšœ˜Jšœœœ˜$Jšœ+˜+Jšœœ˜$Jšœ˜ J˜—J˜š žœœœœœ˜0Jšœ˜ —J˜š žœœœœœ˜1Jšœ˜!—J˜šžœœœ˜%Jšœ#˜#—J˜š žœœœœœ˜4Jšœ˜%—J˜šžœœœœ˜3Jšœ"˜"—J˜š ž œœœœœ˜8Jšœ˜$—J˜šžœœœœ ˜;Jšœœœ˜JšœœŸ˜ Jšœœ˜Jšœ˜J˜³JšœœŸ˜$Jšœœœœ˜JšœœŸ%˜>J˜$šœ œ ˜šœ˜šœœ˜Jšœœ˜'Jšœ1˜1Jšœ/œ˜;Jšœ-œ˜9Jšœ.œ˜:Jšœ+œ˜7Jšœ,œ˜8Jšœ#Ÿ˜2JšœŸ˜*JšœŸ˜-JšœŸ ˜8JšœŸ˜*Jšœ-Ÿ˜?Jšœ5Ÿ ˜BJšœ%Ÿ˜:Jš œœŸœŸœ˜?—šœ œ˜Jšœ!Ÿ'˜HJš œœŸœŸœŸ˜K—šœœ˜JšœŸ ˜%JšœŸ˜/—šœœ˜Jšœ!œ Ÿ˜?Jšœ#Ÿ˜=—šœœ˜Jšœ œœ œ!˜OJšœ-Ÿ˜?šœŸ˜Jšœ œ0˜CJšœœ˜$JšœŸ˜:Jšœ˜ Jšœ˜——šœœ˜Jšœ œ œ!Ÿ ˜GJšœœ˜2—šœ œ˜Jšœœ˜)JšœŸ˜5JšœŸ˜,—šœ œ˜Jšœ!Ÿ˜9Jšœ$˜+—šœ œ˜Jšœ!Ÿ ˜/Jšœœ"˜2—šœ œ˜Jšœ-Ÿ ˜;Jšœœ"˜2—šœœ˜JšœŸ ˜;JšœŸ˜-—šœ œ˜Jšœ6Ÿ˜JJšœ"Ÿ˜G—šœœ˜Jšœ:Ÿ˜RJš œœŸœŸœŸ˜J—šœœ˜Jšœ Ÿ˜?Jšœ-Ÿ˜EJš œœŸœŸœŸ˜K—šœ œ˜Jšœ#Ÿ˜5JšœŸ˜.JšœŸ˜.JšœŸ˜/Jšœœ Ÿ˜@—šœ œ˜JšœŸ˜0Jšœ+Ÿ˜GJš œœŸœŸœ˜A—šœ œ˜Jšœ+Ÿ˜GJš œœŸœŸœ˜A—šœ œ˜Jšœ#Ÿ˜:šœŸ˜"Jš œœœœ œ˜AJšœ˜ Jšœ˜——šœœ˜Jšœ.Ÿ˜GJš œœŸœŸœŸ˜N—šœ œ˜Jšœ#Ÿ˜7JšœŸ˜/šœŸ"˜/Jšœ˜Jšœ˜ Jšœ˜——šœ œ˜JšœŸ˜-JšœŸ˜8Jš œœŸœŸœ˜>—šœ œ˜JšœŸ˜8Jš œœŸœŸœ˜>—šœ œ˜JšœŸ˜%Jšœœ Ÿ˜>—JšœœŸ˜"—Jš œœœœ$ŸœŸœ˜Lš˜JšœœŸ˜-JšœŸ!˜7—Jšœ˜—J˜J˜Jšœ˜J˜—J˜šžœœœœ˜,Jšœœ˜ Jšœœ˜Jšœ œœ œ˜3šœœ ˜Jšœœ œ˜$Jšœœ˜Jšœ˜—Jšœœ œœ˜"J˜—J˜šžœœœœ˜.Jš œœœœœ˜0Jšœ œœ˜'Jšœœ˜&Jšœ˜ J˜—J˜šžœœœœ˜9J˜šœœ˜Jšœœ˜Jšœ˜ J˜—Jšœœ˜%J˜—J˜šž œœœ˜CJ˜šœœ˜J˜ Jšœ˜Jšœœœ˜7Jšœ˜Jšœ˜ J˜—Jšœœ˜%J˜—J˜šžœœœœ˜;J˜šœœ˜Jšœœ˜Jšœ˜ J˜—Jšœœ˜%J˜—J˜šžœœœœ˜;Jšœœ˜šœ ˜Jšœœ/˜CJšœ œ˜)Jšœ œ1˜BJšœœ1˜EJšœœ˜+—J˜—J˜šž œœœ œ˜Ešœœœœ˜Jšœ˜Jšœœœ˜šœœ˜J˜šœ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜šœ ˜Jšœœ˜Jš œœœ œœœ˜@Jš œœœ œœœ˜@Jšœœœ˜J˜—Jšœ˜—Jšœ˜—Jšœ˜ J˜—J˜Jšœœœ˜3J˜)Jšœœœ˜3J˜—J˜šœ œœœ˜;Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—J˜šž œœ œœ ˜3Jšœœ3˜EJšœ˜ J˜—J˜šžœœ1˜