DIRECTORY Basics, NodeStyleExtra, NodeStyle, NodeStyleObject, NodeStyleStart USING [], TextNode, TextLooks, EditNotify, NodeProps, NameSymbolTable, TJaMOps; NodeStyleApplyImpl: CEDAR MONITOR IMPORTS Basics, TJaMOps, TextNode, EditNotify, NodeProps, NodeStyle, NodeStyleExtra, NameSymbolTable EXPORTS NodeStyle, NodeStyleExtra, NodeStyleStart = BEGIN OPEN NodeStyle, NodeStyleExtra; defaultStyle: PUBLIC Ref _ NIL; defaultName, rootName: Name; ApplyAll: PUBLIC PROC [ref: Ref, node: TextNode.Ref, kind: OfStyle _ screen] = { [] _ DoApplyAll[ref,node,kind]; }; DoApplyAll: PROC [ref: Ref, node: TextNode.Ref, kind: OfStyle] RETURNS [depth: CARDINAL] = { found: BOOL; parent: TextNode.Ref; alt: Name; IF node=NIL THEN { ref^ _ defaultStyle^; RETURN [0] }; [found,depth] _ FindInApplyAllCache[ref,node,kind]; IF found THEN RETURN [depth+1]; parent _ TextNode.Parent[node]; alt _ IF parent=NIL THEN rootName ELSE defaultName; depth _ DoApplyAll[ref,parent,kind]; ApplyForNode[ref,node,alt,kind]; EnterInApplyAllCache[ref,node,depth]; RETURN [depth+1]; }; applyCacheInfo: REF ApplyCacheRecord _ NEW[ApplyCacheRecord]; ApplyCacheRecord: TYPE = RECORD [ applyCacheDepth: CARDINAL _ 0, -- next free entry applyCacheResults: REF ApplyCacheResults, applyCacheNodes: REF ApplyCacheNodes, applyCacheProbes, applyCacheHits, applyCacheSaves: INT _ 0 ]; applyCacheSize: CARDINAL = 8; -- number of levels deep in tree ApplyCacheNodes: TYPE = ARRAY [0..applyCacheSize) OF TextNode.Ref; ApplyCacheResults: TYPE = ARRAY [0..applyCacheSize) OF StyleBody; InitApplyCacheRecord: PROC = { OPEN applyCacheInfo; applyCacheResults _ NEW[ApplyCacheResults]; applyCacheNodes _ NEW[ApplyCacheNodes]; }; RemoveAllFromApplyAllCache: PUBLIC PROC = { FlushApplyAllCache[] }; FlushApplyAllCache: PUBLIC ENTRY PROC [init: BOOL _ FALSE] = { ENABLE UNWIND => NULL; ClearApplyAllCache[init]; }; ClearApplyAllCache: PROC [init: BOOL] = { OPEN applyCacheInfo; nodes: REF ApplyCacheNodes _ applyCacheNodes; FOR i:CARDINAL IN [0..applyCacheSize) DO nodes[i] _ NIL; ENDLOOP; applyCacheDepth _ 0; }; RemoveNodeFromApplyAllCache: PUBLIC ENTRY PROC [node: TextNode.Ref] = { OPEN applyCacheInfo; ENABLE UNWIND => NULL; nodes: REF ApplyCacheNodes _ applyCacheNodes; FOR i:CARDINAL IN [0..applyCacheDepth) DO IF nodes[i]=node THEN { -- clear from here on FOR j:CARDINAL IN [i..applyCacheSize) DO nodes[j] _ NIL; ENDLOOP; applyCacheDepth _ i; EXIT }; ENDLOOP; }; FindInApplyAllCache: ENTRY PROC [ref: Ref, node: TextNode.Ref, kind: OfStyle] RETURNS [found: BOOL, depth: CARDINAL] = { OPEN applyCacheInfo; ENABLE UNWIND => NULL; nodes: REF ApplyCacheNodes _ applyCacheNodes; print: BOOL = (kind=print); -- if true, then find result with print true also applyCacheProbes _ applyCacheProbes+1; FOR i:CARDINAL DECREASING IN [0..applyCacheDepth) DO IF nodes[i]=node AND print=applyCacheResults[i].print THEN { -- found it applyCacheHits _ applyCacheHits+1; applyCacheSaves _ applyCacheSaves+i+1; ref^ _ applyCacheResults[i]; RETURN [TRUE, i] }; ENDLOOP; RETURN [FALSE, 0]; }; EnterInApplyAllCache: ENTRY PROC [ref: Ref, node: TextNode.Ref, depth: CARDINAL] = { OPEN applyCacheInfo; ENABLE UNWIND => NULL; nodes: REF ApplyCacheNodes _ applyCacheNodes; IF depth >= applyCacheSize THEN RETURN; nodes[depth] _ node; applyCacheResults[depth] _ ref^; FOR i:CARDINAL IN [depth+1..applyCacheSize) DO nodes[i] _ NIL; ENDLOOP; applyCacheDepth _ depth+1; }; prefixAtom: ATOM = NodeProps.PrefixAtom[]; postfixAtom: ATOM = NodeProps.PostfixAtom[]; Notify: PROC [change: REF READONLY EditNotify.Change] = TRUSTED { DoNode: PROC [node: TextNode.Ref] = TRUSTED { IF TextNode.FirstChild[node] # NIL THEN FlushApplyAllCache ELSE RemoveNodeFromApplyAllCache[node] }; WITH x:change SELECT FROM InsertingNode => IF TextNode.FirstChild[x.new] # NIL THEN FlushApplyAllCache; MovingNodes => FlushApplyAllCache; NodeNesting => IF x.first = x.last -- only changing one node AND TextNode.FirstChild[x.first] = NIL -- node has no children THEN SELECT x.change FROM 1 => -- increasing nesting in tree IF TextNode.Next[x.first] = NIL THEN RemoveNodeFromApplyAllCache[x.first] ELSE FlushApplyAllCache; -1 => -- decreasing nesting in tree RemoveNodeFromApplyAllCache[x.first]; ENDCASE => FlushApplyAllCache ELSE FlushApplyAllCache; ChangingType => DoNode[x.node]; ChangingProp => SELECT x.propAtom FROM prefixAtom, postfixAtom, $Comment, $StyleDef => DoNode[x.node]; ENDCASE; ENDCASE => ERROR; -- not expecting notify for any other kinds of changes }; ApplyForNode: PUBLIC PROC [ref: Ref, node: TextNode.Ref, alt: Name, kind: OfStyle] = { text: TextNode.RefTextNode = TextNode.NarrowToTextNode[node]; ext: ATOM; ref.isComment _ IF text # NIL THEN text.comment ELSE FALSE; ref.print _ (kind=print); ref.nestingLevel _ MIN[TextNode.Level[node], MaxNestingLevel]; EvalFreeVars[ref, node]; IF node.hasstyledef THEN { localStyle: LocalStyle _ NARROW[NodeProps.GetProp[node, $StyleDef]]; IF localStyle # NIL THEN ref.name[style] _ localStyle.name }; IF node.hasprefix THEN ApplyObject[ref, NodeProps.GetPrefixObject[node], kind] ELSE IF ref.nestingLevel=0 -- root node -- AND -- check for file extension default (ext _ NARROW[NodeProps.GetProp[node, $FileExtension]])#NIL THEN FOR list: LIST OF ExtObjPair _ defaultStylesForExtensions, list.rest UNTIL list=NIL DO IF list.first.fileExtension # ext THEN LOOP; ApplyObject[ref, list.first.styleObject, kind]; EXIT; ENDLOOP; ApplyType[ref, node.typename, alt, kind]; IF node.haspostfix THEN ApplyObject[ref,NodeProps.GetPostfixObject[node],kind]; }; ApplyType: PUBLIC PROC [ref: Ref, name, alt: Name, kind: OfStyle _ screen] = { OPEN ruleCacheInfo; names: REF RuleCacheNames _ ruleCacheNames; inputs: REF RuleCacheBodies _ ruleCacheInputs; input: StyleBody; initloc, loc: CARDINAL; FindInRuleCache: ENTRY PROC RETURNS [BOOL] = { ENABLE UNWIND => NULL; ruleCacheProbes _ ruleCacheProbes+1; DO -- search cache SELECT names[loc] FROM name => IF inputs[loc] = ref^ THEN { ref^ _ ruleCacheResults[loc]; ruleCacheHits _ ruleCacheHits+1; RETURN [TRUE] }; TextNode.nullTypeName => RETURN [FALSE]; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM ruleCacheSize => IF (loc _ 0)=initloc THEN RETURN [FALSE]; initloc => RETURN [FALSE]; ENDCASE; ENDLOOP; }; PutInRuleCache: ENTRY PROC = { ENABLE UNWIND => NULL; IF ruleCacheCount = ruleCacheMax THEN ClearRuleCache[]; loc _ initloc; DO -- search cache for place to put the entry SELECT names[loc] FROM name => IF inputs[loc] = input THEN RETURN; -- already in cache TextNode.nullTypeName => EXIT; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM ruleCacheSize => IF (loc _ 0)=initloc THEN ERROR; -- cache full initloc => ERROR; -- cache full ENDCASE; ENDLOOP; ruleCacheCount _ ruleCacheCount+1; inputs[loc] _ input; ruleCacheResults[loc] _ ref^; names[loc] _ name; }; ok: BOOL; frame: Frame _ NIL; styleName: Name; IF name = TextNode.nullTypeName AND (name _ alt) = TextNode.nullTypeName THEN RETURN; loc _ initloc _ Basics.BITXOR[LOOPHOLE[name,CARDINAL],Hash[ref]] MOD ruleCacheSize; IF FindInRuleCache[] THEN RETURN; frame _ GetFrame[ref, styleName _ ref.name[style], kind]; input _ ref^; -- save the input value of the record ok _ ExecuteName[frame,name]; FreeFrame[frame,styleName,kind]; frame _ NIL; IF ok THEN PutInRuleCache[] -- save results in cache ELSE IF name # alt THEN ApplyType[ref,alt,TextNode.nullTypeName]; }; ruleCacheInfo: REF RuleCacheInfoRecord _ NEW[RuleCacheInfoRecord]; RuleCacheInfoRecord: TYPE = RECORD [ ruleCacheCount: CARDINAL _ 0, -- number of entries currently in use ruleCacheNames: REF RuleCacheNames, ruleCacheInputs: REF RuleCacheBodies, ruleCacheResults: REF RuleCacheBodies, ruleCacheProbes, ruleCacheHits: INT _ 0 ]; ruleCacheSize: CARDINAL = 64; -- should be a power of 2 ruleCacheMax: CARDINAL = (ruleCacheSize*4)/5; -- don't fill too full RuleCacheNames: TYPE = ARRAY [0..ruleCacheSize) OF TextNode.TypeName; RuleCacheBodies: TYPE = ARRAY [0..ruleCacheSize) OF StyleBody; InitRuleCacheInfo: PROC = { OPEN ruleCacheInfo; ruleCacheNames _ NEW[RuleCacheNames]; ruleCacheInputs _ NEW[RuleCacheBodies]; ruleCacheResults _ NEW[RuleCacheBodies]; }; FlushRuleCache: ENTRY PROC [init: BOOL _ FALSE] = { ENABLE UNWIND => NULL; ClearRuleCache[]; }; ClearRuleCache: PROC [init: BOOL _ FALSE] = { OPEN ruleCacheInfo; names: REF RuleCacheNames _ ruleCacheNames; IF ~init AND ruleCacheCount = 0 THEN RETURN; ruleCacheCount _ 0; FOR i: CARDINAL IN [0..ruleCacheSize) DO names[i] _ TextNode.nullTypeName; ENDLOOP; }; Hash: PROC [ref: Ref] RETURNS [CARDINAL] = { RETURN [LOOPHOLE[ Basics.BITXOR[LOOPHOLE[ref.name[style]], Basics.BITXOR[LOOPHOLE[ref.name[fontFamily],CARDINAL], Basics.BITXOR[ref.real[fontSize], Basics.BITXOR[ref.real[leftIndent], ref.real[leading]]]]],CARDINAL]]; }; ApplyLooks: PUBLIC PROC [ref: Ref, looks: TextLooks.Looks, kind: OfStyle] = { OPEN looksCacheInfo; lks: REF LooksCacheLooks _ looksCacheLooks; inputs: REF LooksCacheBodies _ looksCacheInputs; initloc, loc: CARDINAL; input: StyleBody; FindInLooksCache: ENTRY PROC RETURNS [BOOL] = { ENABLE UNWIND => NULL; looksCacheProbes _ looksCacheProbes+1; DO -- search cache SELECT lks[loc] FROM looks => IF inputs[loc] = ref^ THEN { ref^ _ looksCacheResults[loc]; looksCacheHits _ looksCacheHits+1; RETURN [TRUE] }; TextLooks.noLooks => RETURN [FALSE]; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM looksCacheSize => IF (loc _ 0)=initloc THEN RETURN [FALSE]; initloc => RETURN [FALSE]; ENDCASE; ENDLOOP; }; PutInLooksCache: ENTRY PROC = { ENABLE UNWIND => NULL; IF looksCacheCount = looksCacheMax THEN ClearLooksCache[]; loc _ initloc; DO -- search cache SELECT lks[loc] FROM looks => IF inputs[loc] = input THEN RETURN; -- already in cache TextLooks.noLooks => EXIT; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM looksCacheSize => IF (loc _ 0)=initloc THEN ERROR; -- cache full initloc => ERROR; -- cache full ENDCASE; ENDLOOP; looksCacheResults[loc] _ ref^; lks[loc] _ looks; inputs[loc] _ input; looksCacheCount _ looksCacheCount+1; }; frame: Frame _ NIL; styleName: Name; IF looks = TextLooks.noLooks THEN RETURN; loc _ initloc _ Basics.BITXOR[LOOPHOLE[looks, TextLooks.LooksBytes].byte0, Basics.BITXOR[LOOPHOLE[looks, TextLooks.LooksBytes].byte1, Basics.BITXOR[LOOPHOLE[looks, TextLooks.LooksBytes].byte2, Hash[ref]]]] MOD looksCacheSize; IF FindInLooksCache[] THEN RETURN; frame _ GetFrame[ref, styleName _ ref.name[style], kind]; input _ ref^; -- save the input value of the record FOR c: CHAR IN TextLooks.Look DO IF looks[c] THEN [] _ ExecuteName[frame,lookNames[c]] ENDLOOP; FreeFrame[frame,styleName,kind]; frame _ NIL; PutInLooksCache[]; }; looksCacheInfo: REF LooksCacheInfoRecord _ NEW[LooksCacheInfoRecord]; LooksCacheInfoRecord: TYPE = RECORD [ looksCacheCount: CARDINAL _ 0, looksCacheLooks: REF LooksCacheLooks, looksCacheInputs: REF LooksCacheBodies, looksCacheResults: REF LooksCacheBodies, looksCacheProbes, looksCacheHits: INT _ 0 ]; looksCacheSize: CARDINAL = 16; -- should be a power of 2 looksCacheMax: CARDINAL = (looksCacheSize*4)/5; -- don't fill too full LooksCacheLooks: TYPE = ARRAY [0..looksCacheSize) OF TextLooks.Looks; LooksCacheBodies: TYPE = ARRAY [0..looksCacheSize) OF StyleBody; InitLooksCacheInfo: PROC = { OPEN looksCacheInfo; looksCacheLooks _ NEW[LooksCacheLooks]; looksCacheInputs _ NEW[LooksCacheBodies]; looksCacheResults _ NEW[LooksCacheBodies]; }; lookNames: REF LookNames _ NEW[LookNames]; LookNames: TYPE = ARRAY TextLooks.Look OF Name; FlushLooksCache: ENTRY PROC [init: BOOL _ FALSE] = { ENABLE UNWIND => NULL; ClearLooksCache[]; }; ClearLooksCache: PROC [init: BOOL _ FALSE] = { OPEN looksCacheInfo; IF ~init AND looksCacheCount = 0 THEN RETURN; looksCacheCount _ 0; FOR i: CARDINAL IN [0..looksCacheSize) DO looksCacheLooks[i] _ TextLooks.noLooks; ENDLOOP; }; nullObject: NameSymbolTable.Object = NameSymbolTable.NullObject[]; ApplyObject: PUBLIC PROC [ref: Ref, object: NameSymbolTable.Object, kind: OfStyle _ screen] = { OPEN objectCacheInfo; objects: REF ObjectCacheObjects _ objectCacheObjects; inputs: REF ObjectCacheBodies _ objectCacheInputs; input: StyleBody; initloc, loc: CARDINAL; initDepth, finalDepth: CARDINAL; obj: Object _ LOOPHOLE[object]; FindInObjectCache: ENTRY PROC RETURNS [BOOL] = { ENABLE UNWIND => NULL; objectCacheProbes _ objectCacheProbes+1; DO -- search cache SELECT objects[loc] FROM object => IF inputs[loc] = ref^ THEN { ref^ _ objectCacheResults[loc]; objectCacheHits _ objectCacheHits+1; RETURN [TRUE] }; nullObject => RETURN [FALSE]; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM objectCacheSize => IF (loc _ 0)=initloc THEN RETURN [FALSE]; initloc => RETURN [FALSE]; ENDCASE; ENDLOOP; }; PutInObjectCache: ENTRY PROC = { ENABLE UNWIND => NULL; IF objectCacheCount = objectCacheMax THEN ClearObjectCache[]; loc _ initloc; DO -- search cache for place to put the entry SELECT objects[loc] FROM object => IF inputs[loc] = input THEN RETURN; -- already in cache nullObject => EXIT; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM objectCacheSize => IF (loc _ 0)=initloc THEN ERROR; -- cache full initloc => ERROR; -- cache full ENDCASE; ENDLOOP; objectCacheCount _ objectCacheCount+1; inputs[loc] _ input; objectCacheResults[loc] _ ref^; objects[loc] _ object; }; HashObject: PROC RETURNS [CARDINAL] = { ob: RECORD [ a, b, c, d: CARDINAL ] _ LOOPHOLE[object]; RETURN [ob.b]; }; frame: Frame _ NIL; styleName: Name; IF object = nullObject THEN RETURN; loc _ initloc _ Basics.BITXOR[HashObject[],Hash[ref]] MOD objectCacheSize; IF FindInObjectCache[] THEN RETURN; frame _ GetFrame[ref, styleName _ ref.name[style], kind]; input _ ref^; -- save the input value of the record TRUSTED { initDepth _ TJaMOps.CountStack[frame.opstk]; TJaMOps.Execute[frame,CVX[obj]]; IF (finalDepth _ TJaMOps.CountStack[frame.opstk]) # initDepth THEN { PushObject[frame,obj]; PushText[frame,"Failed to leave stack at same depth after execution.\n"L]; StyleError[frame,2]; } ELSE PutInObjectCache[] }; FreeFrame[frame,styleName,kind]; frame _ NIL; }; objectCacheInfo: REF ObjectCacheInfoRecord _ NEW[ObjectCacheInfoRecord]; ObjectCacheInfoRecord: TYPE = RECORD [ objectCacheCount: CARDINAL, objectCacheObjects: REF ObjectCacheObjects, objectCacheInputs: REF ObjectCacheBodies, objectCacheResults: REF ObjectCacheBodies, objectCacheProbes, objectCacheHits: INT _ 0 ]; objectCacheSize: CARDINAL = 16; -- should be a power of 2 objectCacheMax: CARDINAL = (objectCacheSize*4)/5; -- don't fill too full ObjectCacheObjects: TYPE = ARRAY [0..objectCacheSize) OF NameSymbolTable.Object; ObjectCacheBodies: TYPE = ARRAY [0..objectCacheSize) OF StyleBody; InitObjectCacheInfo: PROC = { OPEN objectCacheInfo; objectCacheObjects _ NEW[ObjectCacheObjects]; objectCacheInputs _ NEW[ObjectCacheBodies]; objectCacheResults _ NEW[ObjectCacheBodies]; }; FlushObjectCache: ENTRY PROC [init: BOOL _ FALSE] = { ENABLE UNWIND => NULL; ClearObjectCache[]; }; ClearObjectCache: PROC [init: BOOL _ FALSE] = { OPEN objectCacheInfo; IF ~init AND objectCacheCount = 0 THEN RETURN; objectCacheCount _ 0; FOR i: CARDINAL IN [0..objectCacheSize) DO objectCacheObjects[i] _ nullObject; ENDLOOP; }; FlushCaches: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; ClearCaches[FALSE]; }; ClearCaches: PROC [init: BOOL] = { ClearApplyAllCache[init]; ClearRuleCache[init]; ClearLooksCache[init]; ClearObjectCache[init]; }; executingName: PUBLIC Name; ExecuteName: PROC [frame: Frame, name: Name] RETURNS [ok: BOOL] = TRUSTED { initDepth: CARDINAL _ TJaMOps.CountStack[frame.opstk]; finalDepth: CARDINAL; nameObj: Object; [ok,] _ TJaMOps.TryToLoad[frame, nameObj _ NameToObject[name]]; IF ~ok THEN RETURN; executingName _ name; TJaMOps.Execute[frame,CVX[nameObj]]; executingName _ NameSymbolTable.nullName; IF (finalDepth _ TJaMOps.CountStack[frame.opstk]) # initDepth THEN { PushText[frame,"Failed to leave stack at same depth after execution.\n"L]; PushName[frame,name]; StyleError[frame,2]; }; }; StyleError: PUBLIC PROC [frame: Frame, num: INTEGER] = TRUSTED { PushInteger[frame,num]; TJaMOps.Execute[frame,CVX[NameToObject[styleerror]]]; }; StyleNameForNode: PUBLIC PROC [node: TextNode.Ref] RETURNS [name: Name] = { s: Ref _ Alloc[]; ApplyAll[s, node]; name _ GetStyleName[s]; Free[s]; }; InitLookNames: PROC = TRUSTED { txt: STRING _ [6]; txt[0] _ 'l; txt[1] _ txt[2] _ 'o; txt[3] _ 'k; txt[4] _ '.; txt.length _ 6; FOR c: CHAR IN TextLooks.Look DO txt[5] _ c; lookNames[c] _ MakeName[LOOPHOLE[LONG[txt],REF READONLY TEXT]]; ENDLOOP; }; startCount: CARDINAL _ 0; StartApply: PUBLIC PROC = { changeSet: EditNotify.ChangeSet; frame: Frame _ NIL; IF (startCount _ startCount+1)>1 THEN RETURN; frame _ TJaMOps.defaultFrame; changeSet[ChangingProp] _ TRUE; changeSet[ChangingType] _ TRUE; changeSet[MovingNodes] _ TRUE; changeSet[NodeNesting] _ TRUE; changeSet[InsertingNode] _ TRUE; EditNotify.AddNotifyProc[Notify,after,high,changeSet]; defaultStyle _ Create[]; defaultName _ MakeName["default"]; rootName _ MakeName["root"]; InitLookNames[]; InitApplyCacheRecord[]; InitRuleCacheInfo[]; InitLooksCacheInfo[]; InitObjectCacheInfo[]; ClearCaches[TRUE]; SetDefaultStyle["Cedar"]; }; StartApply[]; END. ΜNodeStyleApplyImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. written by Bill Paxton, January 1981 Paxton, December 21, 1982 9:55 am Maxwell, January 6, 1983 9:50 am Russ Atkinson, March 7, 1985 3:29:21 am PST Plass, March 1, 1985 4:33:00 pm PST Doug Wyatt, March 5, 1985 10:53:24 am PST -- Apply operations -- when clearing, go all the way to applyCacheSize rather than stopping at applyCacheDepth -- if change invalidates one node only, remove that node -- else clear entire cache -- ***** Execute makes sure that same stack depth after execute -- ***** Miscellaneous -- does an ApplyAll and then returns the style name -- Initialization names are "look.a", "look.b", "look.c", etc. Κr˜codešœ™Kšœ Οmœ1™Kšœžœžœžœ˜BKšœžœžœžœ ˜BK˜š œžœžœ˜3Kšœžœ˜+Kšœžœ˜'Kšœ˜K˜—š œžœžœ˜CK˜—š  œžœžœžœžœžœ˜>Kšžœžœžœ˜K˜K˜K˜—š œžœžœžœ˜>Kšœžœ#˜-KšœZ™ZKš žœžœžœžœ žœžœ˜AK˜K˜K˜—š œžœžœžœ˜GKšžœ˜Kšžœžœžœ˜Kšœžœ#˜-šžœžœžœžœ˜*šžœžœ‘˜-šžœžœžœž˜(Kšœ žœžœ˜—Kšœžœ˜—Kšžœ˜—Kšœ˜K˜—š œžœžœ.˜MKšžœ žœ žœžœ˜?Kšžœžœžœ˜Kšœžœ#˜-Kšœžœ‘1˜MK˜&š žœžœž œžœž˜4šžœžœ"žœ‘ ˜HK˜"K˜&K˜Kšžœžœ˜—Kšžœ˜—Kšžœžœ˜Kšœ˜K˜—š œžœžœ'žœ˜TKšžœ˜Kšžœžœžœ˜Kšœžœ#˜-Kšžœžœžœ˜'K˜K˜ Kš žœžœžœžœ žœžœ˜GK˜K˜K˜—Kšœ žœ˜*Kšœ žœ˜,K˜š  œžœ žœžœžœ˜AKšœ8™8Kšœ™š œžœžœ˜-Kšžœžœžœ˜:Kšžœ%˜)—Kšžœ žœž˜Kšœžœžœžœ˜MK˜"šœžœ‘˜šžœžœ ž˜šœ‘˜"Kšžœžœžœ%˜IKšžœ˜—šœ‘˜#K˜%—Kšžœ˜—Kšžœ˜—K˜šœžœ ž˜&K˜?Kšžœ˜—Kšžœžœ‘6˜HK˜K˜—š  œžœžœ=˜VK˜=Kšœžœ˜ Kš œžœžœžœžœžœ˜;Kšœ˜Kšœžœ(˜>K˜šžœžœ˜Kšœžœ%˜DKšžœžœžœ%˜=—Kšžœžœ8˜Nš žœžœ‘œžœ‘#˜RKšœžœ+žœž˜@š žœžœžœ4žœžœž˜VKšžœ žœžœ˜,Kšœ/˜/Kšžœ˜Kšžœ˜——K˜)Kšžœžœ8˜Ošœ˜K˜——š  œžœžœ8˜NKšžœ˜Kšœžœ!˜+Kšœžœ#˜.K˜Kšœžœ˜K˜š  œžœžœžœžœ˜.Kšžœžœžœ˜K˜$šžœ‘˜šžœ ž˜šœžœžœ˜$K˜K˜ Kšžœžœ˜—Kšœžœžœ‘˜CKšžœ˜—šžœž˜Kš œžœžœžœžœ˜:Kšœ žœžœ˜Kšžœ˜—Kšžœ˜—šœ˜K˜——š œžœžœ˜Kšžœžœžœ˜Kšžœžœ˜7K˜šžœ‘*˜-šžœ ž˜Kšœžœžœžœ‘˜?Kšœžœ‘˜9Kšžœ˜—šžœž˜Kšœžœžœžœ‘ ˜?Kšœ žœ‘ ˜Kšžœ˜—Kšžœ˜—K˜"K˜K˜K˜K˜K˜—Kšœžœ˜ Kšœžœ˜K˜K˜šžœž˜#Kšœ%žœžœ˜1—Kš œžœžœžœ žœ˜SKšžœžœžœ˜!K˜9Kšœ‘%˜3K˜Kšœ)žœ˜-Kšžœžœ‘˜4Kšžœžœ žœ*˜AKšœ˜K˜—Kšœžœžœ˜Bšœžœžœ˜$Kšœžœ‘%˜CKšœžœ˜#Kšœžœ˜%Kšœžœ˜&Kšœ žœ˜'Kšœ˜—Kšœžœ‘˜7Kšœžœ‘˜DKšœžœžœžœ˜EKšœžœžœžœ ˜>K˜š œžœžœ˜/Kšœžœ˜%Kšœžœ˜'Kšœžœ˜(Kšœ˜K˜—š  œžœžœžœžœ˜3Kšžœžœžœ˜K˜K˜K˜—š  œžœžœžœžœ˜AKšœžœ!˜+Kšžœžœžœžœ˜,K˜Kš žœžœžœžœ#žœ˜SKšœ˜K˜—š œžœ žœžœ˜-šžœžœ˜šœžœžœ˜(šœžœžœžœ˜6šœžœ˜!šœžœ˜#Kšœžœ˜!—————šœ˜K˜——š  œžœžœ6˜MKšžœ˜Kšœžœ#˜+Kšœžœ%˜0Kšœžœ˜K˜K˜š  œžœžœžœžœ˜/Kšžœžœžœ˜K˜&šžœ‘˜šžœ ž˜šœ žœžœ˜%K˜K˜"Kšžœžœ˜—Kšœžœžœ‘˜?Kšžœ˜—šžœž˜Kš œžœžœžœžœ˜;Kšœ žœžœ˜Kšžœ˜—Kšžœ˜—šœ˜K˜——š œžœžœ˜Kšžœžœžœ˜Kšžœ!žœ˜:K˜šžœ‘˜šžœ ž˜Kšœ žœžœžœ‘˜@Kšœžœ‘˜5Kšžœ˜—šžœž˜Kšœžœžœžœ‘ ˜@Kšœ žœ‘ ˜Kšžœ˜—Kšžœ˜—K˜K˜K˜K˜$K˜K˜—Kšœžœ˜K˜K˜Kšžœžœžœ˜)šœ˜šœžœžœ$˜:šœžœžœ$˜:šœžœžœ$˜:Kšœ žœ˜ ————Kšžœžœžœ˜"K˜9Kšœ‘%˜3šžœžœžœž˜ Kšžœ žœ%˜5Kšžœ˜—Kšœ)žœ˜-K˜K˜K˜—Kšœžœžœ˜Ešœžœžœ˜%Kšœžœ˜Kšœžœ˜%Kšœžœ˜'Kšœžœ˜(Kšœ"žœ˜)Kšœ˜—Kšœžœ‘˜8Kšœžœ‘˜FKšœžœžœžœ˜EKšœžœžœžœ ˜@K˜š œžœžœ˜1Kšœžœ˜'Kšœžœ˜)Kšœžœ˜*K˜K˜—Kšœ žœ žœ ˜*Kšœ žœžœžœ˜0K˜š  œžœžœžœžœ˜4Kšžœžœžœ˜K˜K˜K˜—š  œžœžœžœžœ˜CKšžœžœžœžœ˜-K˜Kš žœžœžœžœ)žœ˜ZKšœ˜K˜—K˜BK˜š  œžœžœG˜_Kšžœ˜Kšœ žœ)˜5Kšœžœ'˜2K˜Kšœžœ˜Kšœžœ˜ Kšœžœ ˜K˜š  œžœžœžœžœ˜0Kšžœžœžœ˜K˜(šžœ‘˜šžœž˜šœ žœžœ˜&K˜K˜$Kšžœžœ˜—Kšœžœžœ‘˜8Kšžœ˜—šžœž˜Kš œžœžœžœžœ˜