DIRECTORY EditSpan USING [Inherit, Merge, NodeOrder, Place, Split], EditSpanSupport USING [ApplyProc, Event, LastOfSlice, MaxLen, NeededNestingChange, NodeItself, Slice, SliceArray], TextEdit USING [Size], TextNode USING [FirstChild, Level, Location, NewTextNode, Next, nullLocation, nullSpan, Parent, Node, Root, Span, StepBackward, StepForward]; EditSpanSupportImpl: CEDAR MONITOR IMPORTS EditSpan, EditSpanSupport, TextEdit, TextNode EXPORTS EditSpanSupport, EditSpan = BEGIN OPEN EditSpanSupport; Node: TYPE ~ TextNode.Node; Location: TYPE ~ TextNode.Location; Place: TYPE ~ EditSpan.Place; NodeOrder: TYPE ~ EditSpan.NodeOrder; Span: TYPE ~ TextNode.Span; nullSpan: Span ~ TextNode.nullSpan; freeSlice: Slice; -- free list of slices numFreeSlices: NAT ¬ 0; maxFreeSlices: NAT = 15; minSliceSize: NAT = 10; GetSlice: PUBLIC ENTRY PROC [len: NAT] RETURNS [slice: Slice] = { IF freeSlice # NIL THEN { -- look on free list prev: Slice; IF freeSlice.maxLength >= len THEN { -- take the first from list slice ¬ freeSlice; freeSlice ¬ freeSlice.next; slice.next ¬ NIL; numFreeSlices ¬ numFreeSlices-1; RETURN }; prev ¬ freeSlice; FOR s: Slice ¬ freeSlice.next, s.next UNTIL s=NIL DO IF s.maxLength >= len THEN { -- take this one prev.next ¬ s.next; s.next ¬ NIL; numFreeSlices ¬ numFreeSlices-1; RETURN [s] }; prev ¬ s; ENDLOOP }; RETURN [NEW[SliceArray[MAX[len,minSliceSize]]]] }; FreeSlice: PUBLIC ENTRY PROC [slice: Slice] = { IF slice=NIL OR numFreeSlices >= maxFreeSlices OR slice.maxLength < minSliceSize THEN RETURN; FOR i:NAT IN [0..slice.length) DO slice[i] ¬ NIL; ENDLOOP; slice.next ¬ freeSlice; freeSlice ¬ slice; numFreeSlices ¬ numFreeSlices+1 }; MakeSlices: PROC [node: Node] RETURNS [before, after: Slice] = { last: NAT; Slicer: PROC [node: Node, height: NAT] RETURNS [level: NAT] = { height ¬ height+1; IF node=NIL THEN { -- have gone beyond root before ¬ GetSlice[height]; before.kind ¬ before; after ¬ GetSlice[height+1]; after.kind ¬ after; RETURN [0] }; level ¬ Slicer[TextNode.Parent[node],height]; before[level] ¬ node; after[level] ¬ TextNode.Next[node]; RETURN [level+1] }; IF node=NIL THEN RETURN; last ¬ Slicer[node,0]; before.length ¬ last; IF node.child # NIL THEN { after[last] ¬ node.child; after.length ¬ last+1 } ELSE after.length ¬ last; FOR i: NAT ¬ after.length, i-1 DO -- delete trailing NIL's from after IF i=0 THEN { after.length ¬ 0; EXIT }; IF after[i-1] # NIL THEN { after.length ¬ i; EXIT }; ENDLOOP; }; InsertPrefix: PROC [first, last: Slice, firstLen: NAT] RETURNS [new: Slice] = { newLen: NAT; IF first = NIL OR last = NIL OR first.kind # before OR last.kind # before OR first.length < firstLen THEN ERROR; new ¬ GetSlice[newLen ¬ firstLen + last.length]; new.kind ¬ before; new.length ¬ newLen; FOR i: NAT IN [0..firstLen) DO new[i] ¬ first[i]; ENDLOOP; FOR i: NAT IN [0..last.length) DO new[firstLen+i] ¬ last[i]; ENDLOOP; }; NeedNestingChange: PUBLIC PROC [before, after, top, bottom: Slice, nesting: INTEGER, depth: NAT] RETURNS [NeededNestingChange] = { bandStart, afterOver: INTEGER; topLen, botLen: NAT; nesting ¬ MIN[1,nesting]; topLen ¬ top.length; botLen ¬ bottom.length; bandStart ¬ before.length+nesting-(topLen-depth); IF bandStart <= 0 THEN RETURN [needNest]; -- must be at least 1 afterOver ¬ after.length-(botLen-depth+bandStart); IF afterOver > 1 THEN RETURN [needUnNest]; RETURN [ok] }; AdoptChildren: PUBLIC PROC [node, child: Node] ~ { node.child ¬ child; FOR c: Node ¬ child, c.next UNTIL c=NIL DO c.parent ¬ node ENDLOOP; }; Splice: PUBLIC PROC [before, after: Slice, beforeStart, afterStart: NAT ¬ 0] = { beforeLen: NAT ~ before.length-beforeStart; afterLen: NAT ~ after.length-afterStart; IF before.kind#before OR after.kind#after THEN ERROR; IF afterLen>beforeLen+1 THEN ERROR; -- cannot have gaps in tree AdoptChildren[LastOfSlice[before], IF afterLen>beforeLen THEN LastOfSlice[after] ELSE NIL]; FOR i: NAT DECREASING IN[0..beforeLen) DO -- do successors b: Node ~ before[beforeStart+i]; a: Node ~ IF i= before.length+nesting THEN ERROR; depth ¬ MAX[1,before.length+nesting-top.length]; fullBottom ¬ InsertPrefix[before,bottom,depth]; Splice[fullBottom,after]; Splice[before,top,depth]; FreeSlice[fullBottom]; }; BadBand: PUBLIC ERROR = CODE; DescribeBand: PUBLIC PROC [first, last: Node] RETURNS [before, after, top, bottom: Slice, nesting: INTEGER, depth: NAT] = { BadBandError: PROC = { ERROR BadBand [! UNWIND => { FreeSlice[before]; FreeSlice[after]; FreeSlice[top]; FreeSlice[bottom] } ] }; pred: Node ¬ TextNode.StepBackward[first]; minDepth: NAT; IF pred=NIL THEN ERROR BadBand; -- first is root node IF pred=last THEN ERROR BadBand; -- this actually happened during testing! [before,top] ¬ MakeSlices[pred]; nesting ¬ top.length-before.length; [bottom,after] ¬ MakeSlices[last]; minDepth ¬ MIN[before.length,bottom.length]; FOR depth ¬ 0, depth+1 UNTIL depth >= minDepth DO IF before[depth] # bottom[depth] THEN { -- check for legality bot: Node ¬ bottom[depth]; FOR node: Node ¬ before[depth], TextNode.Next[node] DO SELECT node FROM bot => EXIT; NIL => BadBandError[]; -- last must come before first ENDCASE; ENDLOOP; EXIT }; ENDLOOP; IF depth=0 THEN BadBandError[]; -- different root nodes for first and last IF LastOfSlice[top] # first THEN ERROR; IF before[before.length+nesting-2] # TextNode.Parent[first] THEN ERROR; IF LastOfSlice[bottom] # last THEN ERROR }; DeletePrefix: PUBLIC PROC [slice: Slice, depth: NAT] = { newLen: NAT; IF slice.length < depth THEN ERROR; newLen ¬ slice.length-depth; FOR i:NAT IN [0..newLen) DO slice[i] ¬ slice[i+depth]; ENDLOOP; FOR i:NAT IN [newLen..slice.length) DO slice[i] ¬ NIL; ENDLOOP; slice.length ¬ newLen }; DestSlices: PUBLIC PROC [dest: Node, where: EditSpan.Place] RETURNS [before, after: Slice, nesting: INTEGER] = { SELECT where FROM after => { [before,after] ¬ MakeSlices[dest]; nesting ¬ 0 }; child => { [before,after] ¬ MakeSlices[dest]; nesting ¬ 1 }; before => { pred: Node ¬ TextNode.StepBackward[dest]; [before,after] ¬ MakeSlices[pred]; nesting ¬ after.length-before.length }; ENDCASE => ERROR }; CreateDest: PUBLIC PROC [depth: NAT] RETURNS [dest: Location] = { node: Node ¬ NIL; WHILE depth>0 DO child: Node ¬ TextNode.NewTextNode[]; IF node # NIL THEN { node.child ¬ child; child.parent ¬ node }; node ¬ child; depth ¬ depth-1; ENDLOOP; RETURN [[node, NodeItself]] }; CopySpan: PUBLIC PROC [span: Span] RETURNS [result: Span] = { node, sourceFirst, sourceLast, child, new, prev, parent, first: Node; firstLoc, lastLoc: INT; sourceFirst ¬ span.start.node; firstLoc ¬ span.start.where; sourceLast ¬ span.end.node; lastLoc ¬ span.end.where; IF (node ¬ sourceFirst)=NIL THEN RETURN [nullSpan]; parent ¬ TextNode.NewTextNode[]; -- parent for the span DO -- create new node each time through the loop new ¬ TextNode.NewTextNode[]; new.rope ¬ node.rope; new.runs ¬ node.runs; new.charSets ¬ node.charSets; new.charProps ¬ node.charProps; new.new ¬ TRUE; new.parent ¬ parent; IF prev#NIL THEN prev.next ¬ new ELSE parent.child ¬ new; -- insert new prev ¬ new; EditSpan.Inherit[node,new,TRUE]; -- inherit properties from node IF node=sourceFirst THEN first ¬ new; IF node=sourceLast THEN { RETURN [[[first,firstLoc], [new,lastLoc]]] }; IF (child ¬ node.child) # NIL THEN { -- descend in the tree node ¬ child; parent ¬ new; prev ¬ NIL } ELSE DO -- move to next node, sibling or up* then sibling IF node.next#NIL THEN { node ¬ node.next; EXIT }; prev ¬ parent; IF (parent ¬ prev.parent) = NIL THEN { -- need a new parent parent ¬ TextNode.NewTextNode[]; parent.child ¬ prev; prev.parent ¬ parent; }; IF (node ¬ node.parent)=NIL THEN RETURN [nullSpan]; -- bad arg span ENDLOOP; ENDLOOP }; CompareSliceOrder: PUBLIC PROC [s1, s2: Slice] RETURNS [order: EditSpan.NodeOrder] = { s1Len, s2Len: NAT; IF s1=NIL OR s2=NIL OR (s1Len¬s1.length)=0 OR (s2Len¬s2.length)=0 OR s1[0] # s2[0] THEN RETURN [disjoint]; IF s1.kind # before OR s2.kind # before THEN ERROR; -- only valid for parent slices FOR i:NAT ¬ 1, i+1 DO -- know that s1[j]=s2[j] for j { IF i=s2Len THEN RETURN [same]; -- s1Last=s2Last RETURN [before] }; -- s1Last is a parent of s2Last s2Len => RETURN [after]; -- s2Last is a parent of s1Last ENDCASE; IF s1[i] # s2[i] THEN { -- they are siblings, so can check order by Next's s2Node: Node ¬ s2[i]; FOR n:Node ¬ TextNode.Next[s1[i]], TextNode.Next[n] DO -- search from s1 to s2 SELECT n FROM s2Node => RETURN [before]; NIL => RETURN [after]; ENDCASE; ENDLOOP }; ENDLOOP }; CompareNodeOrder: PUBLIC PROC [node1, node2: Node] RETURNS [NodeOrder] ~ { IF node1=NIL OR node2=NIL THEN RETURN[disjoint]; IF node1=node2 THEN RETURN[same] ELSE { level1: INTEGER ~ TextNode.Level[node1]; level2: INTEGER ~ TextNode.Level[node2]; level: INTEGER ~ MIN[level1, level2]; n1: Node ¬ node1; n2: Node ¬ node2; THROUGH [level..level1) DO n1 ¬ TextNode.Parent[n1] ENDLOOP; THROUGH [level..level2) DO n2 ¬ TextNode.Parent[n2] ENDLOOP; IF n1=n2 THEN RETURN[IF level1 RETURN[before]; -- n1 branch is before n2 branch n2 => RETURN[after]; -- n2 branch is before n1 branch ENDCASE; ENDLOOP; ERROR; -- malformed data structure: n1 and n2 not children of their parent! } ELSE { n1 ¬ p1; n2 ¬ p2 }; ENDLOOP; RETURN[disjoint]; }; }; DoSplits: PUBLIC PROC [alpha, beta: Span, event: Event] RETURNS [Span, Span] = { MakeSplit: PROC [node: Node, offset: INT] = { FixLoc: PROC [old: Location] RETURNS [newLoc: Location] = { where: INT; IF old.node # node THEN RETURN [old]; SELECT where ¬ old.where FROM = NodeItself => ERROR; < offset => RETURN [[node,where]]; ENDCASE => RETURN [[new,where-offset]] }; new: Node; IF node = NIL THEN RETURN; new ¬ EditSpan.Split[TextNode.Root[node], [node,offset],event]; alpha.start ¬ FixLoc[alpha.start]; alpha.end ¬ FixLoc[alpha.end]; beta.start ¬ FixLoc[beta.start]; beta.end ¬ FixLoc[beta.end] }; IF alpha.start.where # NodeItself THEN MakeSplit[alpha.start.node,alpha.start.where]; IF beta.start.where # NodeItself THEN MakeSplit[beta.start.node,beta.start.where]; IF alpha.end.where # NodeItself THEN MakeSplit[alpha.end.node,alpha.end.where+1]; IF beta.end.where # NodeItself THEN MakeSplit[beta.end.node,beta.end.where+1]; RETURN [alpha,beta] }; DoSplits2: PUBLIC PROC [dest: Location, source: Span, where: EditSpan.Place, nesting: INTEGER, event: Event] RETURNS [Location, Span, EditSpan.Place, INTEGER] = { destLoc: Location; destSpan: Span ¬ [dest,TextNode.nullLocation]; [destSpan,source] ¬ DoSplits[destSpan,source,event]; destLoc ¬ destSpan.start; IF dest.where # NodeItself THEN { -- did a split destLoc ¬ BackLoc[destLoc]; where ¬ after; nesting ¬ 0 }; RETURN [destLoc, source, where, nesting] }; ReMerge: PUBLIC PROC [alpha, beta: Span, merge: Node, event: Event, tail: BOOL ¬ FALSE] RETURNS [Span, Span] = { loc: Location; FixLoc: PROC [old: Location] RETURNS [Location] = { where: INT; IF old.node = merge THEN SELECT where ¬ old.where FROM = NodeItself => ERROR; ENDCASE => RETURN [[loc.node,loc.where+where]]; RETURN [old] }; IF tail THEN merge ¬ TextNode.StepForward[merge]; loc ¬ EditSpan.Merge[TextNode.Root[merge],merge,event]; alpha.start ¬ FixLoc[alpha.start]; alpha.end ¬ FixLoc[alpha.end]; beta.start ¬ FixLoc[beta.start]; beta.end ¬ FixLoc[beta.end]; RETURN [alpha,beta] }; UndoSplits: PUBLIC PROC [alpha, beta: Span, event: Event] RETURNS [Span, Span] = { IF alpha.start.where # NodeItself THEN [alpha,beta] ¬ ReMerge[alpha,beta,alpha.start.node,event]; IF beta.start.where # NodeItself THEN [alpha,beta] ¬ ReMerge[alpha,beta,beta.start.node,event]; IF alpha.end.where # NodeItself THEN [alpha,beta] ¬ ReMerge[alpha,beta,alpha.end.node,event,TRUE]; IF beta.end.where # NodeItself THEN [alpha,beta] ¬ ReMerge[alpha,beta,beta.end.node,event,TRUE]; RETURN [alpha,beta] }; UndoSplits2: PUBLIC PROC [dest: Location, source: Span, event: Event] RETURNS [Location, Span] = { destSpan: Span ¬ [dest,TextNode.nullLocation]; [destSpan,source] ¬ UndoSplits[destSpan,source,event]; RETURN [destSpan.end,source] }; SliceOrder: PUBLIC PROC [alpha, beta: Span, aBefore, aBottom, bBefore, bBottom: Slice] RETURNS [overlap: BOOL, head, tail: Span, startOrder, endOrder: EditSpan.NodeOrder] = { IF CompareSliceOrder[aBottom,bBefore]#after --alphaend before betastart OR CompareSliceOrder[aBefore,bBottom]#before --alphastart after betaend THEN { overlap ¬ FALSE; startOrder ¬ endOrder ¬ disjoint; RETURN }; startOrder ¬ CompareSliceOrder[aBefore,bBefore]; endOrder ¬ CompareSliceOrder[aBottom,bBottom]; head ¬ SELECT startOrder FROM before => [alpha.start,BackLoc[beta.start]], same => nullSpan, after => [beta.start,BackLoc[alpha.start]], ENDCASE => ERROR; tail ¬ SELECT endOrder FROM before => [ForwardLoc[alpha.end],beta.end], same => nullSpan, after => [ForwardLoc[beta.end],alpha.end], ENDCASE => ERROR; overlap ¬ TRUE; }; Apply: PUBLIC PROC [span: Span, proc: ApplyProc] = { node, last: Node; start, lastLen: INT; IF (node ¬ span.start.node) = NIL THEN RETURN; IF (last ¬ span.end.node) = NIL THEN RETURN; IF (start ¬ span.start.where)=NodeItself THEN start ¬ 0; IF span.end.where=NodeItself THEN lastLen ¬ MaxLen ELSE IF span.end.where=MaxLen THEN lastLen ¬ MaxLen ELSE { lastLen ¬ span.end.where+1; IF node=last THEN lastLen ¬ lastLen-start }; DO IF proc[node, start, IF node=last THEN lastLen ELSE MaxLen] THEN RETURN; IF node=last OR (node ¬ TextNode.StepForward[node])=NIL THEN RETURN; start ¬ 0; ENDLOOP; }; BackLoc: PUBLIC PROC [loc: Location] RETURNS [new: Location] = { new.node ¬ TextNode.StepBackward[loc.node]; new.where ¬ IF loc.where=NodeItself THEN NodeItself ELSE TextEdit.Size[new.node] }; ForwardLoc: PUBLIC PROC [loc: Location] RETURNS [new: Location] = { new.node ¬ TextNode.StepForward[loc.node]; new.where ¬ IF loc.where=NodeItself THEN NodeItself ELSE 0 }; END. ` EditSpanSupportImpl.mesa Copyright Σ 1985, 1986, 1991, 1992 by Xerox Corporation. All rights reserved. written by Bill Paxton, June 1981 last edit by Bill Paxton, November 9, 1982 10:30 am Last Edited by: Maxwell, January 5, 1983 12:47 pm Michael Plass, March 29, 1985 4:01:21 pm PST Willie-s, February 14, 1991 10:51 am PST Doug Wyatt, June 30, 1992 2:40 pm PDT ***** Slice support routines before[0]=root; before[i]=Parent[before[i+1]]; before[before.length-1]=node after[i]=Next[before[i]] if node.child # NIL then after[before.length]=node.child new[i]=first[i] for i in [0..firstLen) new[i+firstLen]=last[i] for i in [0..last.length) new.length=last.length+firstLen join slices make after[afterStart+i] be successor of before[beforeStart+i] if more after's than before's, adopt as children of last before do Splices to insert (top-bottom) between (before-after) nesting tells how to offset last of before vs. last of top before[before.length-1+nesting] will be predecessor of top[top.length-1] top[top.length-1] = first before[before.length-1+nesting] = predecessor of first bottom[bottom.length-1] = last raises BadBand error if last doesn't follow first in tree structure or if first or last is root node check assertions remove entries from start of slice where = after means insert starting as sibling after dest where = child means insert starting as child of dest where = before means insert starting as sibling before dest create tree of parents go to next node determines relative order in tree of last nodes in the slices returns "same" if slices are identical returns "before" if last node of s1 comes before last node of s2 returns "after" if last node of s1 comes after last node of s2 returns "disjoint" if slices are not from the same tree At this point, Level[n1]=Level[n2]=level AND n1#n2 CompareNodeOrder: PUBLIC PROC [node1, node2: Node] RETURNS [order: EditSpan.NodeOrder] = { s1, s2: Slice; IF node1=NIL OR node2=NIL THEN RETURN [disjoint]; IF node1=node2 THEN RETURN [same]; s1 ¬ MakeParentSlice[node1]; s2 ¬ MakeParentSlice[node2]; order ¬ CompareSliceOrder[s1,s2]; FreeSlice[s1]; FreeSlice[s2] }; MakeParentSlice: PROC [node: Node] RETURNS [slice: Slice] = { result is same as MakeSlices[node].before Slicer: PROC [node: Node, height: NAT] RETURNS [level: NAT] = { height ¬ height+1; IF node=NIL THEN { -- have gone beyond root slice ¬ GetSlice[height]; slice.kind ¬ before; RETURN [0] }; level ¬ Slicer[TextNode.Parent[node],height]; slice[level] ¬ node; RETURN [level+1] }; IF node=NIL THEN RETURN; slice.length ¬ Slicer[node,0] }; split off head or tail sections of text ***** Miscellaneous Κj•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ ΟeœC™NKšΟy!™!Kšž3™3Kšž1™1Kšœ,™,K™(K™%K™—šΟk ˜ Kšœ Ÿœ,˜:KšœŸœ^˜sKšœ Ÿœ ˜Kšœ Ÿœ˜K˜—šΟnœŸœŸœ˜#KšŸœ.˜5KšŸœ˜!šœŸœŸœ˜K˜—KšœŸœ˜Kšœ Ÿœ˜#KšœŸœ˜Kšœ Ÿœ˜%KšœŸœ˜K˜#K˜—šœ™KšœΟc˜(KšœŸœ˜KšœŸœ˜KšœŸœ˜š  œŸœŸœŸœŸœŸœ˜AšŸœ ŸœŸœ‘˜.K˜ šŸœŸœ‘˜@K˜.Kšœ Ÿœ˜Kšœ!Ÿœ˜(K˜—K˜šŸœ#ŸœŸœŸ˜4šŸœŸœ‘˜-KšœŸœ˜!Kšœ!Ÿœ˜,K˜—K˜ KšŸœ˜—K˜—KšŸœŸœ Ÿœ˜0K˜—K˜š  œŸœŸœŸœ˜/KšŸœŸœŸœ Ÿœ˜PKšŸœŸœ˜ Kš ŸœŸœŸœŸœ ŸœŸœ˜:K˜*K˜ K˜—K˜š  œŸœŸœ˜@J™JšœK™KJšœ™Jšœ8™8J™KšœŸœ˜ š  œŸœŸœŸœ Ÿœ˜?K˜šŸœŸœŸœ‘˜+K˜0K˜/KšŸœ˜ K˜—K˜-K˜K˜#KšŸœ ˜K˜—KšŸœŸœŸœŸœ˜K˜K˜šŸœŸ˜KšŸœ4˜8KšŸœ˜—šŸœŸœŸœ‘#˜EKšŸœŸœŸœ˜'KšŸœŸœŸœŸœ˜4KšŸœ˜—K˜—K˜š  œŸœ ŸœŸœ˜OJ™Jšœ&™&Jšœ1™1Jšœ™J™KšœŸœ˜ KšŸœ ŸœŸœŸœŸœŸœŸœŸœŸœ˜qK˜0K˜'Kš ŸœŸœŸœŸœŸœ˜:Kš ŸœŸœŸœŸœŸœ˜EK˜—K˜š  œŸœŸœ/Ÿœ ŸœŸœ˜ƒKšœŸœ˜KšœŸœ˜Kšœ Ÿœ ˜K˜,K˜1KšŸœŸœŸœ ‘˜?K˜2KšŸœŸœŸœ˜*KšŸœ˜ K˜—K˜š  œŸœŸœ˜2K˜Kš ŸœŸœŸœŸœŸœ˜CK˜K˜—š œŸœŸœ1Ÿœ ˜PJ™Jšœ ™ Jšœ>™>Jšœ?™?J™Kšœ Ÿœ˜+Kšœ Ÿœ˜(KšŸœŸœŸœŸœ˜5KšŸœŸœŸœ‘˜?Kš œ#ŸœŸœŸœŸœ˜[š ŸœŸœŸ œŸœŸœ‘˜:K˜ Kš œ Ÿœ ŸœŸœŸœ˜:KšŸœŸœŸœ˜K˜ Kš ŸœŸœŸœŸœŸœ˜CKšŸœ˜—K˜—K˜š  œŸœŸœ/Ÿœ˜aJ™Jšœ8™8Jšœ:™:JšœH™HJ™KšœŸœ˜ K˜Kšœ Ÿœ ˜KšŸœ%ŸœŸœ˜2KšœŸœ%˜0K˜/K˜K˜K˜K˜—K˜š œŸœŸœŸœ˜K™—š   œŸœŸœŸœ.Ÿœ Ÿœ˜|J™Jšœ™Jšœ7™7Jšœ™JšœC™CJšœ ™ J™š  œŸœ˜šŸœ Ÿœ˜K˜$K˜"K˜—K˜—Kšœ*˜*Kšœ Ÿœ˜Kš ŸœŸœŸœŸœ ‘˜5KšŸœ ŸœŸœ ‘)˜JK˜ K˜#K˜"Kšœ Ÿœ˜,šŸœŸœŸ˜1šŸœŸœ‘˜=Kšœ˜šŸœ2Ÿ˜7šŸœŸ˜KšœŸœ˜ —KšŸœ‘˜5KšŸœ˜KšŸœ˜—KšŸœ˜K˜—KšŸœ˜—KšŸœ Ÿœ‘*˜JJ™Jšœ™KšŸœŸœŸœ˜'KšŸœ:ŸœŸœ˜GKšŸœŸœŸœ˜)K˜—K˜š  œŸœŸœŸœ˜8J™Jšœ"™"J™KšœŸœ˜ KšŸœŸœŸœ˜#K˜Kš ŸœŸœŸœ ŸœŸœ˜?Kš ŸœŸœŸœŸœ ŸœŸœ˜?K˜K˜—K˜š   œŸœŸœ%Ÿœ!Ÿœ˜qJ™Jšœ9™9Jšœ4™4Jšœ;™;J™šŸœŸ˜K˜™>Jšœ7™7J™KšœŸœ˜KšŸœŸœŸœŸœŸœŸœŸœ˜RKšŸœŸœ ˜Kš ŸœŸœŸœŸœ‘˜SšŸœŸœ Ÿœ‘ ˜6šŸœŸ˜ K˜ KšŸœ ŸœŸœ ‘˜/KšŸœ ˜Kšœ‘˜"—Kšœ Ÿœ ‘˜8KšŸœ˜šŸœŸœ‘2˜JKšœ˜šŸœ2Ÿœ‘˜OšŸœŸ˜ Kšœ Ÿœ ˜—KšŸœŸœ ˜KšŸœ˜KšŸœ˜—K˜—KšŸœ˜—K˜—K˜š œŸœŸœŸœ˜JKš ŸœŸœŸœŸœŸœŸœ ˜0KšŸœ ŸœŸœ˜ šŸœ˜KšœŸœ˜(KšœŸœ˜(KšœŸœŸœ˜%K˜K˜KšŸœŸœŸœ˜Kšœ)Ÿœ™2šŸœ Ÿœ‘˜3K˜K˜šŸœŸœ‘˜)šŸœ5ŸœŸœŸ˜FšŸœŸ˜ KšœŸœ œ‘‘˜6KšœŸœœ‘ ˜5KšŸœ˜—KšŸœ˜—JšŸœ‘D˜KK˜—KšŸœ˜KšŸœ˜—KšŸœ ˜K˜—K˜K˜—šΠnyžΠkyž£ž£ž ™ZKšž™Kš £ž£ž£ž£ž£ž£ž ™1Kš£ž £ž£ž™"Kšž™Kšž™Kšž!™!Kšž™Kšž™—K™š’ž£ž£ž™=Jšž)™)š ’ž£ž£ž£ž £ž™?Kšž™š£ž£ž£žΠcy™+Kšž.™.Kš£ž™ Kšž™—Kšž-™-Kšž™Kš£ž ™Kšž™—Kš£ž£ž£ž£ž™Kšž™Kšž™—K˜š œŸœŸœ#Ÿœ˜PJšœ(™(K˜š  œŸœŸœ˜-K˜š œŸœŸœ˜;KšœŸœ˜ KšŸœŸœŸœ˜%šŸœŸ˜KšœŸœ˜Kšœ Ÿœ˜"KšŸœŸœ˜'—K˜—Kšœ ˜ KšŸœŸœŸœŸœ˜K˜?K˜"K˜K˜ K˜K˜—K˜KšŸœ Ÿœ/˜UKšŸœŸœ-˜RKšŸœŸœ-˜QKšŸœŸœ+˜NKšŸœ˜K˜—K˜š  œŸœŸœ˜5Kšœ Ÿœ˜6—šŸœ"Ÿœ˜5K˜K˜.K˜4K˜šŸœŸœ‘˜0K˜7K˜—KšŸœ#˜)K˜—K˜š  œŸœŸœ6ŸœŸœ˜WKšŸœ˜K˜š œŸœŸœ˜3KšœŸœ˜ šŸœŸœŸœŸ˜6KšœŸœ˜KšŸœŸœ˜/—KšŸœ˜ K˜—KšŸœŸœ%˜1K˜7K˜"K˜K˜ K˜KšŸœ˜K˜—K˜š  œŸœŸœ#Ÿœ˜RKšŸœ Ÿ˜&K˜:KšŸœŸ˜%K˜9KšŸœŸ˜$Kšœ7Ÿœ˜=KšŸœŸ˜#Kšœ6Ÿœ˜