DIRECTORY Environment USING [Long], LooksReader USING [Create, Get, Ref, SetPosition], NameSymbolTable USING [RopeFromName], NodeStyle USING [ApplyLooks, Copy, Create, FontFace, FontUnderlining, GetBodyIndentI, GetFirstIndentI, GetFontFace, GetLeadingI, GetLeftIndentI, GetRightIndentI, GetFontFamily, GetFontSizeI, GetLineFormatting, GetStrikeout, GetTabLeaderSpacingI, GetTabRuleWeightI, GetTabRuleVShiftI, RulesTabCount, RulesTabInfoI, GetTabLocI, GetTabStopsI, GetTopLeadingI, GetUnderlining, GetVShiftI, LineFormatting, Ref, TabAlign, TabStop], RopeEdit USING [AlphaNumericChar], RopeReader USING [Create, Get, ReadOffEnd, Ref, SetPosition], TextEdit USING [GetRope, GetRuns, Offset, RefTextNode, Size], TextLooks USING [Looks, allLooks, noLooks], TextNode USING [ForwardClipped, Location, Ref, StepForward], TEditCompile USING [maxCharsPerLine], TEditDocument USING [fatalTiogaError, maxClip], TEditFormat, UnifiedFonts; TEditFormatImpl: MONITOR IMPORTS LooksReader, NameSymbolTable, NodeStyle, RopeEdit, RopeReader, TEditDocument, TextEdit, TextNode EXPORTS TEditFormat = BEGIN OPEN TEditFormat; Lengthen: PROCEDURE [integer: INTEGER] RETURNS [Dimension] = INLINE { long: Environment.Long _ [any[low: 0, high: integer]]; RETURN[[long.li]] }; FormatLine: PUBLIC ENTRY PROC [tdd: TEditDocumentData, node: TextEdit.RefTextNode, startOffset: TextEdit.Offset, nodeStyle: NodeStyle.Ref, lineWidth: Dimension, buildBitmap, trimEnd: BOOL _ FALSE] RETURNS [TEditFormat.LineInfo _ lineInfo] = BEGIN font: UnifiedFonts.FONT; fontWidths: UnifiedFonts.WidthArray; savedLooks, prevTabLooks: TextLooks.Looks _ TextLooks.allLooks; looks, tabCharLooks: TextLooks.Looks _ TextLooks.noLooks; char: CHARACTER; width: Dimension; tabStop: NodeStyle.TabStop; tabNumber: CARDINAL; -- tells us which tab stop to use tabLoc, tabStart, tabWidth, tabTextStart: CARDINAL; tabAlignment: NodeStyle.TabAlign; tabAlignmentChar: CHAR; endPtr: LONG POINTER TO TEditFormat.CharInfo; -- init below blankPtr, tabPtr: LONG POINTER TO TEditFormat.CharInfo _ NIL; offEnd: Dimension = [LAST[INT]]; endOffset, blankOffset: TextEdit.Offset _ startOffset; currentX: Dimension; -- init below blankX: Dimension _ offEnd; extraIndent: Dimension = UnifiedFonts.RealToFixed[(IF endOffset = 0 THEN NodeStyle.GetFirstIndent[nodeStyle] ELSE NodeStyle.GetBodyIndent[nodeStyle])]; leftIndent: Dimension = UnifiedFonts.RealToFixed[NodeStyle.GetLeftIndent[nodeStyle] + (IF endOffset = 0 THEN NodeStyle.GetFirstIndent[nodeStyle] ELSE NodeStyle.GetBodyIndent[nodeStyle])]; doingTab: BOOL _ FALSE; level: INTEGER _ 0; -- in case we are doing level clipping maxLevel: INTEGER = tdd.clipLevel; levelClipping: BOOL _ maxLevel < TEditDocument.maxClip; lineFormatting: NodeStyle.LineFormatting; underlining, strikeout: NodeStyle.FontUnderlining; vShift: Dimension; Init: PROC = { tabNumber _ 0; endPtr _ @(lineInfo.chars[0]); currentX _ 0; }; NewFormattingLooks: PROC = { NodeStyle.Copy[dest: charStyle, source: tabStyle]; IF looks#TextLooks.noLooks THEN NodeStyle.ApplyLooks[charStyle, looks]; font _ GetFont[charStyle]; IF buildBitmap THEN BEGIN underlining _ NodeStyle.GetUnderlining[charStyle]; strikeout _ NodeStyle.GetStrikeout[charStyle]; vShift _ RealToFixed[NodeStyle.GetVShift[charStyle]]; END; savedLooks _ looks; lineInfo.ascent _ MAX[lineInfo.ascent, RealToFixed[font.fontBoundingBox.ymax]]; lineInfo.descent _ MAX[lineInfo.ascent, RealToFixed[-font.fontBoundingBox.ymin]]; fontWidths _ font.GetWidthArray[minimum: Lengthen[1], undefined: Lengthen[3]]; }; FinishFormattingTab: PROC = { textWidth: CARDINAL _ currentX-tabTextStart; distanceToMove: CARDINAL; alignmentPoint: CARDINAL _ SELECT tabAlignment FROM FlushRight, Character => currentX, -- move right end of text to tabLoc Centered => (currentX+tabTextStart)/2, -- move center of text to tabLoc ENDCASE => ERROR; -- handle FlushLeft elsewhere IF alignmentPoint >= tabLoc THEN distanceToMove _ 0 -- too much text to fit; leave it alone ELSE { distanceToMove _ MIN[tabLoc-alignmentPoint, lineWidth-currentX]; currentX _ currentX+distanceToMove }; tabPtr.width _ tabWidth _ distanceToMove+tabTextStart-tabStart; -- fix-up tab width tabPtr.tab _ tabStop; -- fix-up tab info doingTab _ FALSE }; DisplayTab: PROC = BEGIN TabRule: PROC [weight, vshift: INTEGER] = { bltYOffset: LONG POINTER = LOOPHOLE[oneLineBitmap, LONG POINTER] + ((maxLineAscent-vshift-weight+1)*bitmapWPL); ubbp.width _ endPtr.width; ubbp.dst _ [LOOPHOLE[bltYOffset+(currentX/16)],,currentX MOD 16]; ubbp.height _ MAX[1,weight]; BitBlt.BITBLT[ubbp]; ubbp.height _ 1 }; IF endPtr.underlining=All THEN Underline[]; IF endPtr.strikeout=All THEN Strikeout[]; IF endPtr.tab#NIL THEN WITH ts:endPtr.tab SELECT FROM blank => NULL; leaders => { charWidth: CARDINAL _ font.width[ts.char]; spacing: INTEGER _ MAX[charWidth, NodeStyle.GetTabLeaderSpacingI[@ts, nodeStyle]]; leaderStart: INTEGER _ currentX; leaderQuit: INTEGER _ tabStart+endPtr.width-spacing; src: CARDINAL _ font.xInSegment[ts.char]; extra: CARDINAL _ (spacing-charWidth)/2; leaderStart _ leaderStart + extra; -- even out the extra space leaderQuit _ leaderQuit + extra; cbbp.flags.dstFunc _ or; -- to take care of kerning cbbp.width _ charWidth; cbbp.src _ [font.bitmap+(src/16),,src MOD 16]; FOR xx: INTEGER _ leaderStart, xx+spacing UNTIL xx > leaderQuit DO cbbp.dst _ [LOOPHOLE[bltYOffset+(xx/16)],,xx MOD 16]; BitBlt.BITBLT[cbbp]; ENDLOOP; cbbp.flags.dstFunc _ null }; rule => { weight: INTEGER _ NodeStyle.GetTabRuleWeightI[@ts, nodeStyle]; vshift: INTEGER _ NodeStyle.GetTabRuleVShiftI[@ts, nodeStyle]; TabRule[weight, vshift] }; rules => { FOR i: INTEGER IN [0..NodeStyle.RulesTabCount[@ts]) DO weight, vshift: INTEGER; [weight, vshift] _ NodeStyle.RulesTabInfoI[@ts, i]; TabRule[weight, vshift]; ENDLOOP }; ENDCASE => ERROR; END; IF startOffset > TextEdit.Size[node] THEN RETURN WITH ERROR TEditDocument.fatalTiogaError; Init[]; {indent: Dimension _ RealToFixed[NodeStyle.GetRightIndent[nodeStyle]]; lineWidth _ [MAX[INT[0], INT[lineWidth] - indent - leftIndent]] }; NodeStyle.Copy[dest: tabStyle, source: nodeStyle]; RopeReader.SetPosition[ropeReader, TextEdit.GetRope[node], endOffset]; LooksReader.SetPosition[looksReader, TextEdit.GetRuns[node], endOffset]; lineInfo.ascent _ lineInfo.descent _ [0]; lineInfo.break _ wrap; THROUGH [0..TEditCompile.maxCharsPerLine) DO char _ RopeReader.Get[ropeReader ! RopeReader.ReadOffEnd => {lineInfo.break _ eon; EXIT}]; IF (looks_LooksReader.Get[looksReader])#savedLooks THEN NewFormattingLooks[]; width _ fontWidth[char]; SELECT char FROM 40C => {blankPtr _ endPtr; blankOffset _ endOffset; blankX _ currentX}; 11C => BEGIN -- tab tabLooks: TextLooks.Looks; minSpace: CARDINAL; IF doingTab THEN FinishFormattingTab[]; -- finish previous tab before start this one endPtr.tab _ NIL; -- clear out old information tabNumber _ tabNumber+1; IF tabNumber > nodeStyle.numTabStops THEN { IF (tabStop _ nodeStyle.defaultTabStops) # NIL THEN { tabLoc _ IF nodeStyle.tabStops=NIL THEN 0 ELSE NodeStyle.GetTabLocI[nodeStyle.tabStops.first, nodeStyle]; tabLoc _ tabLoc + (tabNumber-nodeStyle.numTabStops)* NodeStyle.GetTabLocI[tabStop, nodeStyle] } ELSE NULL -- calculate tabLoc after establish looks -- } ELSE { -- go down list until find the proper tab stop tabStops: LIST OF NodeStyle.TabStop _ nodeStyle.tabStops; FOR i: CARDINAL _ nodeStyle.numTabStops, i-1 UNTIL i=tabNumber DO tabStops _ tabStops.rest; ENDLOOP; tabStop _ tabStops.first; tabLoc _ NodeStyle.GetTabLocI[tabStop, nodeStyle] }; IF nodeStyle.fixedTabs THEN tabLoc _ tabLoc-leftIndent; tabLooks _ IF tabStop = NIL THEN TextLooks.noLooks ELSE tabStop.looks; IF tabLooks # prevTabLooks THEN { NodeStyle.Copy[dest: tabStyle, source: nodeStyle]; IF tabLooks#TextLooks.noLooks THEN NodeStyle.ApplyLooks[tabStyle, tabLooks]; prevTabLooks _ tabLooks; NewFormattingLooks[] } ELSE IF looks#savedLooks THEN NewFormattingLooks[]; tabCharLooks _ looks; minSpace _ font.width[40C]; -- this must come after establish looks IF tabStop=NIL THEN { -- pick value [spaceWidth..tabWidth+spaceWidth) for tab width maxSpace, toNextTab: CARDINAL; tabWidth _ NodeStyle.GetTabStopsI[nodeStyle]; maxSpace _ tabWidth*minSpace; toNextTab _ maxSpace - ((currentX+extraIndent) MOD maxSpace); width _ IF toNextTab tabLoc THEN { -- we are beyond the tab stop IF tabStop=NIL OR ~tabStop.breakIfPast THEN { -- treat like a space tabWidth _ minSpace } ELSE -- force line break -- EXIT} ELSE IF tabAlignment=FlushLeft THEN { -- simple case; finish now tabWidth _ width _ tabLoc-currentX } ELSE { -- will finish after have the text to be positioned doingTab _ TRUE; tabAlignmentChar _ IF tabAlignment=Character THEN tabStop.alignmentChar ELSE 0C; tabTextStart _ tabStart+width }; END ENDCASE => BEGIN IF doingTab AND char=tabAlignmentChar AND tabAlignment=Character THEN FinishFormattingTab[]; IF currentX + width >= lineWidth THEN EXIT; END; IF buildBitmap THEN endPtr^ _ [ width: width, char: char, strikeout: strikeout, underlining: underlining, vShift: vShift, font: font] ELSE endPtr.width _ width; endPtr _ endPtr+SIZE[TEditFormat.CharInfo]; endOffset _ endOffset+1; currentX _ currentX+width; IF char=15C THEN {lineInfo.break _ cr; EXIT}; ENDLOOP; IF doingTab THEN FinishFormattingTab[]; IF lineInfo.break=cr OR lineInfo.break=eon OR blankPtr=NIL THEN endPtr.width _ offEnd ELSE BEGIN (blankPtr _ blankPtr+SIZE[TEditFormat.CharInfo]).width _ offEnd; endOffset _ blankOffset+1; END; IF endOffset>=TextEdit.Size[node] THEN BEGIN n: TextNode.Ref; IF levelClipping THEN [n,level] _ TextNode.ForwardClipped[node,maxLevel,level] ELSE n _ TextNode.StepForward[node]; lineInfo.nextPos _ [n, 0]; lineInfo.nChars _ TextEdit.Size[node] - startOffset; END ELSE BEGIN lineInfo.nextPos _ [node, endOffset]; lineInfo.nChars _ endOffset - startOffset; END; lineInfo.leading _ IF startOffset=0 THEN NodeStyle.GetTopLeadingI[nodeStyle] ELSE NodeStyle.GetLeadingI[nodeStyle]; lineInfo.width _ IF lineInfo.break=cr THEN currentX+width ELSE IF lineInfo.break=eon OR blankX=offEnd THEN currentX ELSE blankX; lineInfo.indent _ SELECT (lineFormatting _ NodeStyle.GetLineFormatting[nodeStyle]) FROM FlushLeft, Justified => leftIndent, FlushRight => leftIndent + (lineWidth-lineInfo.width), Centered => leftIndent + (lineWidth-lineInfo.width)/2, ENDCASE => ERROR; IF ~buildBitmap THEN {lineInfo.bits _ NIL; RETURN} ELSE lineInfo.bits _ formatBitmapRep; Init[]; ClearLineBuffer[]; font _ NIL; WHILE (width_endPtr.width)#offEnd DO -- display each formatted character in buffer IF endPtr.font#font THEN NewDisplayLooks[]; -- sets blt info and font _ endPtr.font SELECT (char_endPtr.char) FROM 40C, 15C => BEGIN -- blanks and returns IF endPtr.underlining=All THEN Underline[]; IF endPtr.strikeout=All THEN Strikeout[]; END; 11C => DisplayTab[]; -- tabs ENDCASE => BEGIN -- normal characters IF NOT char IN [font.min..font.max] THEN BEGIN -- illegal char for font black: CARDINAL _ 177777B; oldsrcDesc: INTEGER = cbbp.srcDesc.srcBpl; cbbp.height _ font.ascent; cbbp.width _ width-2; -- hack some white space between bad chars cbbp.dst _ [LOOPHOLE[bltYOffset+((currentX+1)/16)],,(currentX+1) MOD 16]; cbbp.flags.gray _ TRUE; cbbp.srcDesc.gray _ [0, 0, 0, 0]; cbbp.src _ [@black,,0]; BitBlt.BITBLT[cbbp]; cbbp.height _ font.height; cbbp.flags.gray _ FALSE; cbbp.srcDesc.srcBpl _ oldsrcDesc; END ELSE BEGIN src: CARDINAL = font.xInSegment[char]; cbbp.width _ width; cbbp.src _ [font.bitmap+(src/16),,src MOD 16]; cbbp.dst _ [LOOPHOLE[bltYOffset+(currentX/16)],,currentX MOD 16]; BitBlt.BITBLT[cbbp]; END; SELECT endPtr.underlining FROM All, Visible => Underline[]; LettersAndDigits => IF RopeEdit.AlphaNumericChar[char] THEN Underline[]; ENDCASE; SELECT endPtr.strikeout FROM All, Visible => Strikeout[]; LettersAndDigits => IF RopeEdit.AlphaNumericChar[char] THEN Strikeout[]; ENDCASE; END; currentX _ currentX+width; endPtr _ endPtr+SIZE[TEditFormat.CharInfo]; ENDLOOP; savedAscent _ lineInfo.ascent; savedDescent _ lineInfo.descent; -- so can clear line buffer next time lineInfo.yOffset _ maxLineAscent-savedAscent; IF trimEnd AND currentX#width THEN TrimLineBuffer[lineInfo.width, currentX, lineInfo.ascent, lineInfo.descent]; END; savedAscent: CARDINAL _ maxLineAscent; savedDescent: CARDINAL _ maxLineDescent; ClearLineBuffer: PROC = INLINE { IF savedAscent#0 THEN BEGIN [] _ RTMicrocode.LONGZERO[LOOPHOLE[oneLineBitmap, LONG POINTER TO UNSPECIFIED] + ((maxLineAscent-savedAscent)*bitmapWPL), (savedAscent+savedDescent)*bitmapWPL]; savedAscent _ savedDescent _ 0; END; }; TrimLineBuffer: PROC [start, end, ascent, descent: CARDINAL] = INLINE { bltYOffset: LONG POINTER = LOOPHOLE[oneLineBitmap, LONG POINTER] + ((maxLineAscent-ascent)*bitmapWPL); bbbp.height _ ascent+descent; bbbp.width _ MIN[bitmapWPL*16, end]-start; bbbp.dst _ [LOOPHOLE[bltYOffset+(start/16)],,start MOD 16]; BitBlt.BITBLT[bbbp]; }; GetFont: PROC [style: NodeStyle.Ref] RETURNS [font: VFonts.Font] = INLINE BEGIN face: NodeStyle.FontFace _ NodeStyle.GetFontFace[style]; font _ VFonts.EstablishFont[ NameSymbolTable.RopeFromName[NodeStyle.GetFontFamily[style]], NodeStyle.GetFontSizeI[style], face=Bold OR face=BoldItalic, face=Italic OR face=BoldItalic ]; END; AllocateBitmap: PROC [nWords: CARDINAL] RETURNS [REF] = BEGIN Words: TYPE = RECORD[SEQUENCE COMPUTED CARDINAL OF CARDINAL]; RETURN[NEW[Words[nWords]]]; END; bbbTable, cbbTable, ubbTable: BitBlt.BBTableSpace; bbbp: BitBlt.BBptr _ BitBlt.AlignedBBTable[@bbbTable]; -- buffer end trimming cbbp: BitBlt.BBptr _ BitBlt.AlignedBBTable[@cbbTable]; -- chars to line buffer ubbp: BitBlt.BBptr _ BitBlt.AlignedBBTable[@ubbTable]; -- underline and strikeout oneLineBitmap: REF _ AllocateBitmap[bitmapWPL*maxLineHeight]; formatBitmapRep: REF GraphicsOps.BitmapRep _ NEW[GraphicsOps.BitmapRep _ [ base: oneLineBitmap, raster: bitmapWPL, width: bitmapWPL*16, height: maxLineHeight ]]; lineInfo: TEditFormat.LineInfo _ NEW[TEditFormat.LineInfoRec]; myWhiteWord: CARDINAL _ 0; -- white for erasing bitmap buffers myBlackWord: CARDINAL _ 177777B; -- black for underlining and strikeout ropeReader: RopeReader.Ref _ RopeReader.Create[]; looksReader: LooksReader.Ref _ LooksReader.Create[]; charStyle: NodeStyle.Ref _ NodeStyle.Create[]; tabStyle: NodeStyle.Ref _ NodeStyle.Create[]; bbbp.flags.disjoint _ TRUE; bbbp.flags.disjointItems _ TRUE; bbbp.flags.gray _ TRUE; bbbp.srcDesc.gray _ [0, 0, 0, 0]; bbbp.src _ [@myWhiteWord,,0]; bbbp.dstBpl _ bitmapWPL*16; cbbp.flags.disjoint _ TRUE; cbbp.flags.disjointItems _ TRUE; cbbp.dstBpl _ bitmapWPL*16; ubbp.flags.disjoint _ TRUE; ubbp.flags.disjointItems _ TRUE; ubbp.flags.gray _ TRUE; ubbp.srcDesc.gray _ [0, 0, 0, 0]; ubbp.src _ [@myBlackWord,,0]; ubbp.dstBpl _ bitmapWPL*16; ubbp.height _ 1; savedAscent _ maxLineAscent; -- so will be cleared first time through savedDescent _ maxLineDescent; END. ΪOldTEditFormatImpl.mesa, Edited by McGregor, January 14, 1983 11:24 am Edited by Paxton, December 20, 1982 4:38 pm Edited by Plass, February 1, 1983 10:10 am TEditCompile USING [bitmapWPL, maxLineAscent, maxLineDescent, maxLineHeight], Initialises variables used in both format and display Pass 1: Format the line and fill in lineInfo fields -- we fell out of the loop because we got to the right edge or because -- we hit a logical end-of-line (return or end-of-node) ------ see if need to finish a tab End of Pass 1 Pass 2: build the line bitmap from the LineInfoRec clear off broken word at end End of Pass 2 -- Main Program -- line buffer; magic storage provided by AllocateBitmap -- RopeReader and LooksReader Stuff ΚΒ˜JšœF™FJšœ+™+Jšœ*™*J˜šΟk ˜ Jšœ œ˜Jšœ œ!˜2Jšœœ˜%Jšœ œ™˜¨Jšœ œ˜"Jšœ œ-˜=Jšœ œ/˜=Jšœ œ˜+Jšœ œ.˜Jšœ ˜ JšœŸ˜3Jšœ˜Jšœ&œ˜.šœœœ˜BJšœ œœ˜5Jšœœ˜Jš˜—Jšœ˜—šœ ˜ Jšœœ/˜>Jšœœ/˜>Jšœ˜—šœ ˜ šœœœ#˜6Jšœœ˜Jšœ3˜3Jšœ˜Jšœ˜ ——Jšœœ˜—Jšœ˜—Kš œ#œœœœ˜ZKšΟb4™4Kšœ˜šœF˜FJšœ œœœ#˜?Jšœ˜—Kšœ2˜2KšœF˜FJšœH˜HK˜)J˜šœ#˜,JšœSœ˜ZJšœ1œ˜MJšœ˜šœ˜JšœG˜GšœœŸ˜J˜Jšœ œ˜Jšœ œŸ,˜TJšœ œŸ˜.Jšœ˜šœ#œ˜+šœ)œœ˜5šœ œœœ˜.Jšœ:˜:—šœ4˜4Jšœ*˜*——JšœœŸ,œ˜8—šœŸ.˜5Jšœ œœ(˜9šœœœ ˜AJšœœ˜"—Jšœ˜Jšœ4˜4—Jšœœ˜7Jš œ œ œœœ˜Fšœœ˜!Jšœ2˜2Jšœœ*˜LJšœ˜Jšœ˜—Jšœœœ˜3J˜JšœŸ'˜Cšœ œœŸ=˜SJšœœ˜Jšœ-˜-Jšœ˜Jšœ/œ ˜=šœœœ˜5Jšœ ˜—Jšœ˜—Jšœ7˜7Jš œœ œœ œ˜DšœœŸ˜Bš œ œœœŸ˜CJšœ˜—JšœŸœœ˜!—šœœœŸ˜@Jšœ$˜$—šœŸ3˜:Jšœ œ˜šœ˜Jšœœœ˜=—Jšœ ˜ —Jš˜—šœ˜Jšœ œœœ˜\Jšœœœ˜+Jšœ˜——šœ œ ˜Jšœ ˜ Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœ ˜ —Jšœ˜Jšœœ˜+J˜Jšœ˜Jšœ œœ˜-Jšœ˜—JšŸF™FJšŸ7™7JšŸ"™"Jšœ œ˜'Jš œœœ œœ˜Ušœ˜ Jšœœ'˜@J˜Jšœ˜—šœ œ˜,J˜Jšœœ9˜NJšœ ˜$J˜J˜4Jš˜—šœ˜ J˜%J˜*Jšœ˜—šœœœ$˜LJšœ"˜&—šœœœ˜9Jš œœœœ œ˜F—šœœ;˜WJšœ#˜#Jšœ8˜8Jšœ9˜9Jšœœ˜—J˜Jš  ™ J˜Jš œœœœœ!˜XJ˜Jš 3™3J˜Jšœ˜Jšœ˜Jšœœ˜ J˜šœœŸ-˜RJ˜JšœœŸ'˜SJ˜šœ˜šœ œŸ˜)Jšœœ ˜+Jšœœ ˜)Jšœ˜—JšœŸ˜šœœŸ˜'š œœœœœŸ˜GJšœœ ˜Jšœ œ˜*J˜JšœŸ*˜@Jšœ œ-œ˜IJšœœ˜J˜!J˜Jšœœ˜J˜Jšœœ˜J˜!Jš˜—šœ˜ Jšœœ˜'Jšœ˜Jšœ&œ˜.Jšœ œ%œ˜AJšœœ˜Jšœ˜—šœ˜Jšœ˜Jšœœ!œ ˜HJšœ˜—šœ˜Jšœ˜Jšœœ!œ ˜HJšœ˜—Jšœ˜—J˜Jšœ˜Jšœœ˜+Jšœ˜J˜——Jšœ˜Jšœ!Ÿ%˜FJ˜Jšœ-˜-J˜šœ œ˜"JšœL˜LJšœ™—J˜Jš  ™ J˜Jšœ˜—J˜Jšœ œ˜&Jšœœ˜(J˜šžœœœ˜ šœœ˜š œœœœœœ œ˜PJ˜O—J˜Jšœ˜—J˜J˜—šžœœœœ˜Gšœ œœ˜Jšœœœ'˜K—Jšœ˜Jšœ œ˜*Jšœ œœ˜;Jšœœ˜J˜J˜—š žœœœœ˜OJ˜8˜J˜=J˜Jšœ œ˜Jšœ œ˜J˜—Jšœ˜J˜—š žœœ œœœ˜=Jšœœœœœœœœ˜=Jšœœ˜Jšœ˜J˜—JšŸ™J˜Jšœ2˜2J˜Jšœ7Ÿ˜MJšœ7Ÿ˜NJšœ7Ÿ˜QJ˜šœœ+˜=JšŸ8™8J˜—šœœœ˜JJ˜J˜J˜J˜J˜J˜—Jšœ!œ˜>J˜Jšœ œŸ#˜?Jšœ œ Ÿ&˜GJ˜JšŸ#™#J˜1J˜4J˜J˜.J˜-J˜Jšœœ˜Jšœœ˜ Jšœœ˜J˜!J˜J˜J˜Jšœœ˜Jšœœ˜ J˜J˜Jšœœ˜Jšœœ˜ Jšœœ˜J˜!J˜J˜J˜J˜JšœŸ(˜EJšœ˜J˜Jšœ˜J˜—…—:ΊMV