DIRECTORY Atom USING [GetPName, MakeAtom], BasicTime USING [GMT, nullGMT], FS USING [Error, FileInfo], FSExtras USING [GetWDir], IO USING [PutFR], MessageWindow USING [Append, Blink, Clear], NodeStyle USING [GetReal, RealParam, Ref, SetReal], NodeStyleFont USING [FontFromStyleParams], NodeStyleOps USING [Create, defaultStyleName, FlushCaches, OfStyle], NodeStyleValidate USING [], NodeStyleWorks USING [AddRealProc, ForceLowerName, LoadProc, Ops, OpsRec, Param, ParamRec, PercentProc, PopName, RegisterStyleCommand, run, SetNameProc, StoreProc, TryToPopName, TypeCheckDict, TypeCheckName, WhoIsExecuting], PrincOpsUtils USING [], Process USING [GetCurrent], RefTab USING [Create, Fetch, Pairs, Ref, Store], Rope USING [Cat, Concat, Equal, FromChar, ROPE], SystemNames USING [LocalDir], TextLooks USING [Look, Looks], TJaM USING [ABind, ACopy, AGet, Any, APut, Array, AtomFromAny, AtomFromRope, AttachDict, Begin, ClrDict, CommandProc, CountStack, CvX, DetachAll, DetachDict, Dict, DictLength, DictTop, End, Execute, ExecuteAtom, Frame, Load, NewArray, NewDict, NewFrame, Object, Pop, PopDict, PopReal, Push, PushInt, PushReal, PushRope, Put, Register, RopeFromAtom, Stop, TryToGet, TryToLoad], UserProfile USING [ListOfTokens]; NodeStyleWorks1Impl: CEDAR MONITOR IMPORTS Atom, FS, FSExtras, IO, MessageWindow, NodeStyle, NodeStyleFont, NodeStyleOps, NodeStyleWorks, Process, RefTab, Rope, SystemNames, TJaM, UserProfile EXPORTS NodeStyleWorks, NodeStyleValidate ~ BEGIN OPEN NodeStyle, NodeStyleWorks; ROPE: TYPE ~ Rope.ROPE; Frame: TYPE ~ TJaM.Frame; OfStyle: TYPE ~ NodeStyleOps.OfStyle; Object: TYPE ~ TJaM.Object; defaultFrame: PUBLIC Frame; FrameInfo: TYPE ~ REF FrameInfoBody; FrameInfoBody: TYPE ~ RECORD [ frame: Frame, style: Ref, rest: FrameInfo ]; GetFrame: PUBLIC PROC [style: Ref, styleName: ATOM, kind: OfStyle] RETURNS [frame: Frame] ~ { found: BOOL; AllocFrame: ENTRY PROC [name: ATOM, kind: OfStyle] ~ INLINE { ENABLE UNWIND => NULL; allocFrameCalls _ allocFrameCalls+1; IF name # NIL THEN { IF name = styleName1 AND kind = styleKind1 AND freeFrame1 # NIL THEN { frame _ freeFrame1; freeFrame1 _ NIL; RETURN }; IF name = styleName2 AND kind = styleKind2 AND freeFrame2 # NIL THEN { frame _ freeFrame2; freeFrame2 _ NIL; RETURN }; IF name = styleName3 AND kind = styleKind3 AND freeFrame3 # NIL THEN { frame _ freeFrame3; freeFrame3 _ NIL; RETURN }; IF name = styleName4 AND kind = styleKind4 AND freeFrame4 # NIL THEN { frame _ freeFrame4; freeFrame4 _ NIL; RETURN }}; IF freeFrame1 # NIL THEN { frame _ freeFrame1; freeFrame1 _ NIL } ELSE IF freeFrame2 # NIL THEN { frame _ freeFrame2; freeFrame2 _ NIL } ELSE IF freeFrame3 # NIL THEN { frame _ freeFrame3; freeFrame3 _ NIL } ELSE IF freeFrame4 # NIL THEN { frame _ freeFrame4; freeFrame4 _ NIL } ELSE { frame _ TJaM.NewFrame[]; frameAlloc _ frameAlloc+1; TJaM.Begin[frame, styledict]; }; }; SaveStyleInfo: ENTRY PROC ~ INLINE { ENABLE UNWIND => NULL; IF frame1 = NIL THEN { frame1 _ frame; style1 _ style } ELSE IF frame2 = NIL THEN { frame2 _ frame; style2 _ style } ELSE IF frame3 = NIL THEN { frame3 _ frame; style3 _ style } ELSE IF frame4 = NIL THEN { frame4 _ frame; style4 _ style } ELSE FOR lst: FrameInfo _ frameList, lst.rest UNTIL lst=NIL DO IF lst.frame = NIL THEN { lst.frame _ frame; lst.style _ style; EXIT }; REPEAT FINISHED => frameList _ NEW[FrameInfoBody _ [frame, style, frameList]]; ENDLOOP; }; AllocFrame[styleName, kind]; -- use styleName and kind as hint about which to allocate IF styleName # NIL THEN { styleNameObj: Object; done: BOOL _ FALSE; [found, styleNameObj] _ TJaM.TryToLoad[frame, styleDictName]; IF found THEN { -- some style dictionary on stack already IF TypeCheckName[styleNameObj] = styleName THEN { -- still must check kind of style kindNameObj: Object; [found, kindNameObj] _ TJaM.TryToLoad[frame, styleKindName]; IF found AND TypeCheckName[kindNameObj] = kindNames[kind] THEN done _ TRUE; }; -- already there IF NOT done THEN -- get rid of top dictionary WHILE TJaM.DictTop[frame] # styledict DO TJaM.End[frame]; ENDLOOP; }; IF NOT done THEN TJaM.Begin[frame, GetStyleDict[frame, styleName, kind]] } ELSE WHILE TJaM.DictTop[frame] # styledict DO TJaM.End[frame] ENDLOOP; SaveStyleInfo[]; }; FreeFrame: PUBLIC ENTRY PROC [frame: Frame, styleName: ATOM, kind: OfStyle] ~ { ENABLE UNWIND => NULL; freeFrameCalls _ freeFrameCalls+1; IF freeFrame1 = NIL THEN { freeFrame1 _ frame; styleName1 _ styleName; styleKind1 _ kind } ELSE IF freeFrame2 = NIL THEN { freeFrame2 _ frame; styleName2 _ styleName; styleKind2 _ kind } ELSE IF freeFrame3 = NIL THEN { freeFrame3 _ frame; styleName3 _ styleName; styleKind3 _ kind } ELSE IF freeFrame4 = NIL THEN { freeFrame4 _ frame; styleName4 _ styleName; styleKind4 _ kind } ELSE { frameFree _ frameFree+1; }; -- let garbage collector find it SELECT frame FROM frame1 => { frame1 _ NIL; style1 _ NIL }; frame2 => { frame2 _ NIL; style2 _ NIL }; frame3 => { frame3 _ NIL; style3 _ NIL }; frame4 => { frame4 _ NIL; style4 _ NIL }; ENDCASE => FOR lst: FrameInfo _ frameList, lst.rest UNTIL lst=NIL DO IF lst.frame = frame THEN { lst.frame _ NIL; lst.style _ NIL; EXIT }; ENDLOOP; }; frame1, frame2, frame3, frame4: Frame _ NIL; -- small cache of active frames frameAlloc: INT _ 0; -- number of frames allocated from TJaM frameFree: INT _ 0; -- number of frames freed by TJaM allocFrameCalls: INT _ 0; -- number of times called AllocFrame freeFrameCalls: INT _ 0; -- number of times called FreeFrame. should = allocFrameCalls style1, style2, style3, style4: Ref; -- style bodies associated with active frames 1,2,3,4 frameList: FrameInfo; -- chain of known frames beyond the small cache here freeFrame1, freeFrame2, freeFrame3, freeFrame4: Frame _ NIL; styleName1, styleName2, styleName3, styleName4: ATOM _ NIL; styleKind1, styleKind2, styleKind3, styleKind4: OfStyle _ screen; debugFlag: BOOL _ TRUE; debugStyle: Ref; StyleForFrame: PUBLIC PROC [frame: Frame] RETURNS [style: Ref] ~ { GetIt: ENTRY PROC RETURNS [s: Ref] ~ { ENABLE UNWIND => NULL; SELECT frame FROM frame1 => RETURN [style1]; frame2 => RETURN [style2]; frame3 => RETURN [style3]; frame4 => RETURN [style4]; ENDCASE => FOR lst: FrameInfo _ frameList, lst.rest UNTIL lst=NIL DO IF lst.frame=frame THEN RETURN [lst.style]; ENDLOOP }; IF (style _ GetIt[]) = NIL THEN { -- failed to find the frame IF debugFlag THEN { IF debugStyle = NIL THEN debugStyle _ NodeStyleOps.Create[]; RETURN [debugStyle]; }; ERROR; }; RETURN [style]; }; GetStyleDict: PUBLIC PROC [frame: Frame, styleName: ATOM, kind: OfStyle, def: ROPE _ NIL] RETURNS [d: TJaM.Dict] ~ { found, ok: BOOL; styleName _ ForceLowerName[styleName]; [d, found] _ CheckStyleDict[styleName, kind]; IF found THEN RETURN; ok _ IF def # NIL THEN RunStyleString[frame, styleName, def] ELSE RunStyle[frame, styleName]; IF ok THEN [d, found] _ CheckStyleDict[styleName, kind]; IF NOT found THEN { BadStyleFile[frame, styleName]; [d, found] _ CheckStyleDict[styleName, kind]; }; }; BadStyleFile: PUBLIC PROC [frame: Frame, styleName: ATOM] ~ { { ENABLE { WhatStyle => RESUME[styleName]; StartOfStyle => RESUME; EndOfStyle => RESUME; }; BeginStyleOp[frame]; IF styleName # NodeStyleOps.defaultStyleName THEN { TJaM.Push[frame, NodeStyleOps.defaultStyleName]; AttachStyleOp[frame]; }; EndStyleOp[frame]; }; [] _ RefTab.Store[fileForStyle, styleName, NEW [FileIDRep _ []]]; MessageWindow.Append[" ... "]; MessageWindow.Append[TJaM.RopeFromAtom[styleName]]; MessageWindow.Append[".style could not be loaded. "]; MessageWindow.Blink[]; }; CheckStyleDict: PROC [styleName: ATOM, kind: OfStyle] RETURNS [d: TJaM.Dict, found: BOOL] ~ { obj: Object; [found, obj] _ TJaM.TryToGet[stylesDicts[kind], styleName]; IF found THEN d _ TypeCheckDict[obj]; }; CreateStyleDict: PROC RETURNS [d: TJaM.Dict] ~ INLINE { -- creates dict for style RETURN [TJaM.NewDict[50]]; }; EnterStyleDict: PROC [styleName: ATOM, d: Object, kind: OfStyle] ~ INLINE { TJaM.Put[stylesDicts[kind], styleName, d]; }; systemDir: ROPE ~ FSExtras.GetWDir[]; commandsDir: ROPE ~ SystemNames.LocalDir["Commands"]; defaultSearch: LIST OF ROPE _ LIST[commandsDir, systemDir]; FileID: TYPE ~ REF FileIDRep; FileIDRep: TYPE ~ RECORD [name: ROPE _ NIL, time: BasicTime.GMT _ BasicTime.nullGMT]; Same: PROC [a, b: FileID] RETURNS [BOOL] ~ INLINE { RETURN [a.time = b.time AND Rope.Equal[a.name, b.name, FALSE]] }; GetFileID: PROC [shortName: ATOM, extension: ROPE] RETURNS [FileID] ~ { dirs: LIST OF ROPE _ UserProfile.ListOfTokens["Tioga.StyleSearchRules", defaultSearch]; name: ROPE ~ Rope.Concat[TJaM.RopeFromAtom[shortName], extension]; fileName: ROPE _ NIL; created: BasicTime.GMT _ BasicTime.nullGMT; WHILE fileName = NIL AND dirs # NIL DO [fullFName: fileName, created: created] _ FS.FileInfo[name: name, wDir: dirs.first ! FS.Error => CONTINUE]; dirs _ dirs.rest; ENDLOOP; IF fileName = NIL THEN RETURN [NIL]; RETURN [NEW[FileIDRep _ [fileName, created]]]; }; styleLockProcess: UNSAFE PROCESS _ NIL; styleLockCount: CARDINAL _ 0; styleLockFree: CONDITION; DoLocked: PUBLIC PROC [action: PROC] ~ { me: UNSAFE PROCESS ~ Process.GetCurrent[]; Lock: ENTRY PROC ~ { UNTIL styleLockProcess = me OR styleLockCount = 0 DO WAIT styleLockFree ENDLOOP; styleLockProcess _ me; styleLockCount _ styleLockCount + 1; }; Unlock: ENTRY PROC ~ { styleLockCount _ styleLockCount - 1; IF styleLockCount = 0 THEN {styleLockProcess _ NIL; NOTIFY styleLockFree}; }; Lock[]; action[ ! UNWIND => Unlock[]]; Unlock[]; }; fileForStyle: RefTab.Ref ~ RefTab.Create[5]; ValidateStyles: PUBLIC PROC RETURNS [changed: BOOL _ FALSE] ~ { Locked: PROC ~ { Action: PROC [key: REF, val: REF] RETURNS [quit: BOOLEAN] ~ { IF ValidateStyle[NARROW[key]] THEN changed _ TRUE; RETURN [FALSE] }; [] _ RefTab.Pairs[fileForStyle, Action]; }; DoLocked[Locked]; }; ValidateStyle: PUBLIC PROC [styleName: ATOM] RETURNS [changed: BOOL _ FALSE] ~ { Locked: PROC ~ { fileID: FileID ~ GetFileID[styleName, ".style"]; oldFileID: FileID ~ NARROW[RefTab.Fetch[fileForStyle, styleName].val]; IF oldFileID = NIL OR fileID = NIL OR Same[fileID, oldFileID] THEN changed _ FALSE ELSE { frame: Frame _ GetFrame[NIL, NIL, screen]; changed _ TRUE; IF RunStyle[frame, styleName] THEN FreeFrame[frame, NIL, screen] ELSE BadStyleFile[frame, styleName]; }; }; DoLocked[Locked]; }; runNesting: CARDINAL _ 0; -- to decide whether to clear message window. RunStyle: PUBLIC PROC [frame: Frame, styleName: ATOM] RETURNS [ok: BOOL _ FALSE] ~ { Inner: PROC ~ { started, finished: BOOL _ FALSE; fileID: FileID ~ GetFileID[styleName, ".style"]; TJaM.Put[attachmentsDict, styleName, TJaM.NewArray[0]]; IF fileID = NIL THEN {ok _ FALSE; RETURN}; MessageWindow.Append["Using ", runNesting=0]; MessageWindow.Append[fileID.name, FALSE]; MessageWindow.Append[" . . . ", FALSE]; runNesting _ runNesting + 1; TJaM.PushRope[frame, fileID.name]; TJaM.Execute[frame, run ! WhatStyle => RESUME[styleName]; StartOfStyle => { started _ TRUE; RESUME }; EndOfStyle => { finished _ TRUE; RESUME }; TJaM.Stop => { finished _ FALSE; CONTINUE }; ]; runNesting _ runNesting - 1; ok _ started AND finished; IF ok THEN MessageWindow.Append["ok ", FALSE]; IF ok THEN [] _ RefTab.Store[fileForStyle, styleName, fileID]; IF ok AND runNesting=0 THEN MessageWindow.Clear[]; }; DoLocked[Inner]; }; RunStyleString: PUBLIC PROC [frame: Frame, styleName: ATOM, def: ROPE] RETURNS [ok: BOOL] ~ { started, finished: BOOL _ FALSE; TJaM.Put[attachmentsDict, styleName, TJaM.NewArray[0]]; TJaM.Execute[frame, TJaM.CvX[def] ! WhatStyle => { RESUME[styleName] }; StartOfStyle => { started _ TRUE; RESUME }; EndOfStyle => { finished _ TRUE; RESUME }; TJaM.Stop => { finished _ FALSE; CONTINUE }; ]; RETURN [started AND finished]; }; sysdict: PUBLIC TJaM.Dict; userdict: PUBLIC TJaM.Dict; styledict: PUBLIC TJaM.Dict; styleDictName: ATOM ~ TJaM.AtomFromRope["##styleDictName"]; styleKindName: ATOM ~ TJaM.AtomFromRope["##styleKindName"]; InitDict: PUBLIC PROC [name: ATOM, size: CARDINAL _ 100] RETURNS [dictionary: TJaM.Dict] ~ { found: BOOL; d: Object; [found, d] _ TJaM.TryToGet[sysdict, name]; IF found THEN dictionary _ TypeCheckDict[d] ELSE { dictionary _ TJaM.NewDict[size]; TJaM.Put[sysdict, name, dictionary]; } }; bindingDict: PUBLIC TJaM.Dict; attachmentsDict: PUBLIC TJaM.Dict; kindNames: REF ARRAY OfStyle OF ATOM _ NEW[ARRAY OfStyle OF ATOM _ [ $screen, $print, $base]]; styleRuleDictNames: REF ARRAY OfStyle OF ATOM ~ NEW[ARRAY OfStyle OF ATOM _ [ TJaM.AtomFromRope["##BaseStyleRuleDictName"], TJaM.AtomFromRope["##ScreenStyleRuleDictName"], TJaM.AtomFromRope["##PrintStyleRuleDictName"] ]]; styleDictNames: REF ARRAY OfStyle OF ATOM ~ NEW[ARRAY OfStyle OF ATOM _[ TJaM.AtomFromRope["##BaseStyleDictName"], TJaM.AtomFromRope["##ScreenStyleDictName"], TJaM.AtomFromRope["##PrintStyleDictName"] ]]; stylesDicts: PUBLIC REF ARRAY OfStyle OF TJaM.Dict _ NEW[ARRAY OfStyle OF TJaM.Dict]; StartOfStyle: SIGNAL ~ CODE; -- raised to indicate start of loading style EndOfStyle: SIGNAL ~ CODE; -- raised to indicate successful loading WhatStyle: SIGNAL RETURNS [ATOM] ~ CODE; -- raised to find name of style being loaded BeginStyleOp: TJaM.CommandProc ~ { name: ATOM _ ForceLowerName[SIGNAL WhatStyle]; -- get style name from RunStyle screenDict, printDict, baseDict: TJaM.Dict; ResetDict: PROC [dict: TJaM.Dict] ~ INLINE { TJaM.ClrDict[dict]; TJaM.DetachAll[dict]; }; MakeDict: PROC [kind: OfStyle] RETURNS [dict: TJaM.Dict] ~ INLINE { dict _ CreateStyleDict[]; EnterStyleDict[name, dict, kind]; }; SetupDict: PROC [dict: TJaM.Dict, kind: OfStyle] ~ INLINE { TJaM.Put[baseDict, styleRuleDictNames[kind], TJaM.NewDict[50]]; TJaM.Put[dict, styleKindName, kindNames[kind]]; }; found: BOOL; [baseDict, found] _ CheckStyleDict[name, base]; -- check if reloading IF found THEN { ResetDict[baseDict]; [printDict, ] _ CheckStyleDict[name, print]; ResetDict[printDict]; [screenDict, ] _ CheckStyleDict[name, screen]; ResetDict[screenDict]; NodeStyleOps.FlushCaches[]; } ELSE { baseDict _ MakeDict[base]; screenDict _ MakeDict[screen]; printDict _ MakeDict[print]; }; SetupDict[baseDict, base]; SetupDict[screenDict, screen]; SetupDict[printDict, print]; TJaM.AttachDict[screenDict, baseDict]; TJaM.AttachDict[printDict, baseDict]; TJaM.Put[baseDict, styleDictNames[screen], screenDict]; TJaM.Put[baseDict, styleDictNames[print], printDict]; TJaM.Put[baseDict, styleDictNames[base], baseDict]; TJaM.Put[baseDict, styleDictName, name]; TJaM.Begin[frame, baseDict]; TJaM.Push[frame, baseDict]; -- leave this around for EndStyleOp SIGNAL StartOfStyle; -- caught by RunStyle }; EndStyleOp: TJaM.CommandProc ~ { d1, d2: TJaM.Dict _ NIL; d1 _ TJaM.DictTop[frame]; -- the current dictionary d2 _ TJaM.PopDict[frame]; -- pushed by StyleOp IF d1 # d2 THEN { TJaM.PushRope[frame, "mismatched Style and EndStyle commands"]; StyleError[frame, 1]; } ELSE { -- change attachments so look in own basicDict before any attached dicts name: ATOM _ SIGNAL WhatStyle; screenDict: TJaM.Dict ~ CheckStyleDict[name, screen].d; printDict: TJaM.Dict ~ CheckStyleDict[name, print].d; TJaM.DetachDict[screenDict, d1]; TJaM.DetachDict[printDict, d1]; TJaM.AttachDict[screenDict, d1]; TJaM.AttachDict[printDict, d1]; TJaM.End[frame]; }; SIGNAL EndOfStyle; -- caught by RunStyle }; StyleNameOp: TJaM.CommandProc ~ { -- expects style dictionary on op stack TJaM.Push[frame, TJaM.Load[frame, styleDictName]] }; StyleRuleOp: TJaM.CommandProc ~ { DefineStyleRule[frame, base] }; PrintRuleOp: TJaM.CommandProc ~ { DefineStyleRule[frame, print] }; ScreenRuleOp: TJaM.CommandProc ~ { DefineStyleRule[frame, screen] }; PutNew: PROC [frame: Frame, dict: TJaM.Dict, key: ATOM, val: TJaM.Any] ~ { IF RefTab.Fetch[dict.refTab, key].found THEN { TJaM.Push[frame, key]; TJaM.PushRope[frame, "is multiply defined"]; TJaM.PushInt[frame, 2]; TJaM.ExecuteAtom[frame, $ReportStyleError]; }; TJaM.Put[dict, key, val]; -- save the definition }; DefineStyleRule: PROC [frame: Frame, kind: OfStyle] ~ { definition: Object _ TJaM.Pop[frame]; comment: Object _ TJaM.Pop[frame]; styleRule: ATOM _ PopName[frame]; name: ATOM _ ForceLowerName[styleRule]; dict: TJaM.Dict _ LoadStyleDict[frame, kind]; styleName: ATOM _ TJaM.AtomFromAny[TJaM.Load[frame, styleDictName]]; WITH definition SELECT FROM x: TJaM.Array => TJaM.ABind[x, bindingDict]; ENDCASE; -- def may be a string definition _ TJaM.CvX[definition]; PutNew[frame, dict, name, definition]; -- save the definition IF name # styleRule THEN PutNew[frame, dict, styleRule, definition]; TJaM.Put[dict, Atom.MakeAtom[Rope.Cat[Atom.GetPName[styleName], ".", Atom.GetPName[name]]], definition]; -- save the definition TJaM.Put[LoadStyleRuleDict[frame, kind], name, comment]; -- save the comment in the rule name dict }; LoadStyleDict: PROC [frame: Frame, kind: OfStyle] RETURNS [TJaM.Dict] ~ { RETURN [TypeCheckDict[TJaM.Load[frame, styleDictNames[kind]]]]; }; LoadStyleRuleDict: PROC [frame: Frame, kind: OfStyle] RETURNS [TJaM.Dict] ~ { RETURN [TypeCheckDict[TJaM.Load[frame, styleRuleDictNames[kind]]]]; }; AttachStyleOp: TJaM.CommandProc ~ { -- expects opstk to contain style name as a rope name: ATOM _ ForceLowerName[PopName[frame]]; found: BOOL; printDict, screenDict: TJaM.Dict; array: TJaM.Array; styleName: ATOM _ SIGNAL WhatStyle; val: Object; [printDict, found] _ CheckStyleDict[name, print]; IF NOT found THEN { IF RunStyle[frame, name] THEN [printDict, found] _ CheckStyleDict[name, print]; IF NOT found THEN { BadStyleFile[frame, name]; RETURN; }; }; [screenDict, found] _ CheckStyleDict[name, screen]; IF NOT found THEN ERROR; TJaM.AttachDict[LoadStyleDict[frame, screen], screenDict]; TJaM.AttachDict[LoadStyleDict[frame, print], printDict]; [found, val] _ TJaM.TryToGet[attachmentsDict, styleName]; IF NOT found THEN array _ TJaM.NewArray[1] -- this is the first attachment ELSE { -- add new item to the array WITH val SELECT FROM x: TJaM.Array => array _ x; ENDCASE => ERROR; array _ TJaM.ACopy[array: array, expand: 1]; }; TJaM.APut[array, array.len-1, name]; TJaM.Put[attachmentsDict, styleName, array]; }; ForEachAttachedStyle: PUBLIC PROC [dictName: ATOM, proc: PROC [attached: ATOM] RETURNS [stop: BOOL]] ~ { val: Object; array: TJaM.Array; found: BOOL; dictName _ ForceLowerName[dictName]; [found, val] _ TJaM.TryToGet[attachmentsDict, dictName]; IF NOT found THEN RETURN; WITH val SELECT FROM x: TJaM.Array => array _ x; ENDCASE => ERROR; FOR i: CARDINAL IN [0..array.len) DO IF proc[TypeCheckName[TJaM.AGet[array, i]]] THEN RETURN; ENDLOOP; }; scratchDict: TJaM.Dict _ NIL; AllocProtectDict: ENTRY PROC RETURNS [protectDict: TJaM.Dict] ~ INLINE { ENABLE UNWIND => NULL; protectDict _ scratchDict; scratchDict _ NIL; IF protectDict = NIL THEN { Illegal: PROC [name: ROPE, nArgs: INT] ~ { ob: TJaM.Any ~ TJaM.CvX[IO.PutFR["(%g command not allowed in style rules) %g StyleError", [rope[name]], [integer[nArgs+1]]]]; TJaM.Put[dict: protectDict, key: Atom.MakeAtom[name], val: ob]; }; protectDict _ TJaM.NewDict[]; Illegal[".store", 2]; Illegal["PrintRule", 3]; Illegal["ScreenRule", 3]; Illegal["StyleParam", 2]; Illegal["StyleRule", 3]; }; }; FreeProtectDict: ENTRY PROC [protectDict: TJaM.Dict] ~ INLINE { scratchDict _ protectDict; }; ExecuteObject: PROC [frame: Frame, object: Object] RETURNS [ok: BOOL _ TRUE] ~ { initDepth: CARDINAL _ TJaM.CountStack[frame]; finalDepth: CARDINAL _ 0; protectDict: TJaM.Dict _ AllocProtectDict[]; beforeSize: INT ~ TJaM.DictLength[protectDict]; TJaM.Begin[frame: frame, dict: protectDict]; TJaM.Execute[frame, object]; finalDepth _ TJaM.CountStack[frame]; IF finalDepth # initDepth THEN { TJaM.Push[frame, object]; TJaM.PushRope[frame, "Failed to leave stack at same depth after execution."]; StyleError[frame, 2]; ok _ FALSE; }; IF TJaM.DictTop[frame] = protectDict AND TJaM.DictLength[protectDict] = beforeSize AND protectDict.attach = NIL THEN { TJaM.End[frame]; FreeProtectDict[protectDict] } ELSE { IF TJaM.DictTop[frame] = protectDict THEN TJaM.End[frame]; TJaM.Push[frame, object]; TJaM.PushRope[frame, "Illegally modified dictionary."]; StyleError[frame, 2]; ok _ FALSE; }; }; ExecuteName: PUBLIC PROC [frame: Frame, name: ATOM] RETURNS [ok: BOOL _ FALSE] ~ { ok _ ExecuteObject[frame, name ! TJaM.Stop => {ok _ FALSE; CONTINUE}; NodeStyleWorks.WhoIsExecuting => {RESUME[name]}; ]; }; ExecuteNameInStyle: PUBLIC PROC [ref: Ref, kind: OfStyle, styleRule: ATOM] RETURNS [ok: BOOL _ FALSE] ~ { styleName: ATOM _ ref.name[style]; frame: Frame _ GetFrame[ref, styleName, kind]; IF NOT TJaM.TryToLoad[frame, styleRule].found THEN { FreeFrame[frame, styleName, kind]; frame _ NIL; RETURN [ok: FALSE]; }; ok _ ExecuteName[frame, styleRule]; IF ok THEN FreeFrame[frame, styleName, kind]; frame _ NIL; ref.font _ NIL; }; ExecuteObjectInStyle: PUBLIC PROC [ref: Ref, kind: OfStyle, object: Object] RETURNS [ok: BOOL _ TRUE] ~ { styleName: ATOM _ ref.name[style]; frame: Frame _ GetFrame[ref, styleName, kind]; { ENABLE TJaM.Stop => GO TO stop; ok _ ExecuteObject[frame, TJaM.CvX[object]]; EXITS stop => ok _ FALSE; }; IF ok THEN FreeFrame[frame, styleName, kind]; frame _ NIL; ref.font _ NIL; }; ExecuteLooksInStyle: PUBLIC PROC [ref: Ref, kind: OfStyle, looks: TextLooks.Looks] RETURNS [ok: BOOL _ TRUE] ~ { styleName: ATOM _ ref.name[style]; frame: Frame _ GetFrame[ref, styleName, kind]; FOR c: CHAR IN TextLooks.Look DO IF looks[c] AND TJaM.TryToLoad[frame, lookNames[c]].found THEN ok _ ExecuteName[frame, lookNames[c]] AND ok ENDLOOP; IF ok THEN FreeFrame[frame, styleName, kind]; frame _ NIL; ref.font _ NIL; IF nodeStyleFonts THEN { ref.font _ NodeStyleFont.FontFromStyleParams[prefix: ref.name[fontPrefix], family: ref.name[fontFamily], face: ref.fontFace, size: GetReal[ref, fontSize], alphabets: ref.fontAlphabets]; }; }; nodeStyleFonts: BOOL _ FALSE; LookNames: TYPE ~ ARRAY TextLooks.Look OF ATOM; lookNames: REF LookNames _ InitLookNames[]; InitLookNames: PROC RETURNS [names: REF LookNames] ~ --gfi saver-- INLINE { names _ NEW[LookNames]; FOR c: CHAR IN TextLooks.Look DO names[c] _ TJaM.AtomFromRope[Rope.Concat["look.", Rope.FromChar[c]]]; ENDLOOP; }; StyleError: PUBLIC PROC [frame: Frame, num: INTEGER] ~ { TJaM.PushInt[frame, num]; TJaM.Execute[frame, $StyleError ! TJaM.Stop => CONTINUE]; }; DoStyleOp: PUBLIC PROC [frame: Frame, p: Param] ~ { aName: BOOL; name: ATOM; style: Ref _ StyleForFrame[frame]; Error: PROC ~ --gfi saver-- INLINE { TJaM.Push[frame, name]; TJaM.PushRope[frame, "illegal as qualifer for"]; TJaM.Push[frame, p.opName]; StyleError[frame, 3]; }; [name, aName] _ TryToPopName[frame]; IF NOT aName THEN p.ops.Store[frame, p, style] -- e.g., "10 pt leading" ELSE SELECT name FROM $the => p.ops.Load[frame, p, style]; -- e.g., "the leading" $bigger => { [name, aName] _ TryToPopName[frame]; IF NOT aName THEN p.ops.AddReal[frame, TJaM.PopReal[frame], p, style] ELSE IF name = $percent THEN p.ops.Percent[frame, 100+TJaM.PopReal[frame], p, style] ELSE { Error[]; RETURN }; }; $smaller => { [name, aName] _ TryToPopName[frame]; IF NOT aName THEN p.ops.AddReal[frame, -TJaM.PopReal[frame], p, style] ELSE IF name = $percent THEN p.ops.Percent[frame, 100-TJaM.PopReal[frame], p, style] ELSE { Error[]; RETURN }; }; $percent => p.ops.Percent[frame, TJaM.PopReal[frame], p, style]; ENDCASE => p.ops.SetName[frame, name, p, style]; -- e.g., "TimesRoman family" }; StoreError: PUBLIC StoreProc ~ { ob: Object _ TJaM.Pop[frame]; TJaM.Push[frame, ob]; TJaM.PushRope[frame, "is not legal as value for"]; TJaM.Push[frame, p.opName]; StyleError[frame, 3]; }; AddRealError: PUBLIC AddRealProc ~ { TJaM.PushRope[frame, "Numbers are illegal as values for"]; TJaM.Push[frame, p.opName]; StyleError[frame, 2]; }; PercentError: PUBLIC PercentProc ~ { TJaM.PushRope[frame, "Numbers are illegal as values for"]; TJaM.Push[frame, p.opName]; StyleError[frame, 2]; }; SetNameError: PUBLIC SetNameProc ~ { TJaM.PushRope[frame, "Only numbers are legal as values for"]; TJaM.Push[frame, p.opName]; StyleError[frame, 2]; }; nameOps: PUBLIC Ops _ NEW [OpsRec _ [LoadNameParam, StoreError, AddRealError, PercentError, SetNameParam]]; LoadNameParam: PUBLIC LoadProc ~ { TJaM.Push[frame, style.name[NARROW[p, REF ParamRec.name].param]]; }; SetNameParam: PUBLIC SetNameProc ~ { style.name[NARROW[p, REF ParamRec.name].param] _ name; }; NameError: PUBLIC PROC [frame: Frame, name: ATOM, p: Param] ~ { TJaM.Push[frame, name]; TJaM.PushRope[frame, "illegal as value for"]; TJaM.Push[frame, p.opName]; StyleError[frame, 3]; }; realOps: PUBLIC Ops _ NEW [OpsRec _ [RealOpLoad, RealOpSetReal, RealOpAddReal, RealOpPercent, SetNameError]]; RealOpLoad: PUBLIC LoadProc ~ { TJaM.PushReal[frame, GetReal[style, NARROW[p, REF ParamRec.real].param]]}; RealOpSetReal: PUBLIC StoreProc ~ { SetReal[style, NARROW[p, REF ParamRec.real].param, TJaM.PopReal[frame]]}; RealOpAddReal: PUBLIC AddRealProc ~ { x: REF ParamRec.real ~ NARROW[p]; SetReal[style, x.param, GetReal[style, x.param]+inc]}; RealOpPercent: PUBLIC PercentProc ~ { val: REAL _ GetReal[style, NARROW[p, REF ParamRec.real].param]; SetReal[style, NARROW[p, REF ParamRec.real].param, (percent*0.01)*val]; }; glueOps: PUBLIC Ops _ NEW [OpsRec _ [GlueOpLoad, GlueOpSetReal, GlueOpAddReal, GlueOpPercent, SetNameError]]; GlueOpLoad: PUBLIC LoadProc ~ { Get: PROC [param: RealParam] ~ --gfi saver-- INLINE { TJaM.PushReal[frame, GetReal[style, param]] }; x: REF ParamRec.glue ~ NARROW[p]; Get[x.size]; Get[x.stretch]; Get[x.shrink]; }; GlueOpSetReal: PUBLIC StoreProc ~ { Set: PROC [param: RealParam] ~ --gfi saver-- INLINE { SetReal[style, param, TJaM.PopReal[frame]] }; x: REF ParamRec.glue ~ NARROW[p]; Set[x.shrink]; Set[x.stretch]; Set[x.size]; }; GlueOpAddReal: PUBLIC AddRealProc ~ { Add: PROC [param: RealParam] ~ --gfi saver-- INLINE { SetReal[style, param, GetReal[style, param]+inc] }; x: REF ParamRec.glue ~ NARROW[p]; Add[x.size]; Add[x.stretch]; Add[x.shrink]; }; GlueOpPercent: PUBLIC PercentProc ~ { Set: PROC [param: RealParam] ~ --gfi saver-- INLINE { val: REAL _ GetReal[style, param]; SetReal[style, param, (percent*0.01)*val]; }; x: REF ParamRec.glue ~ NARROW[p]; Set[x.size]; Set[x.stretch]; Set[x.shrink]; }; colorOps: PUBLIC Ops _ NEW [OpsRec _ [ColorOpLoad, ColorOpSetReal, ColorOpAddReal, ColorOpPercent, SetNameError]]; ColorOpLoad: PUBLIC LoadProc ~ { Get: PROC [param: RealParam] ~ --gfi saver-- INLINE { TJaM.PushReal[frame, GetReal[style, param]]; }; x: REF ParamRec.color ~ NARROW[p]; Get[x.hue]; Get[x.saturation]; Get[x.brightness]; }; ColorOpSetReal: PUBLIC StoreProc ~ { Set: PROC [param: RealParam] ~ --gfi saver-- INLINE { SetReal[style, param, TJaM.PopReal[frame]]; }; x: REF ParamRec.color ~ NARROW[p]; Set[x.brightness]; Set[x.saturation]; Set[x.hue]; }; ColorOpAddReal: PUBLIC AddRealProc ~ { Add: PROC [param: RealParam] ~ --gfi saver-- INLINE { SetReal[style, param, GetReal[style, param]+inc]; }; x: REF ParamRec.color ~ NARROW[p]; Add[x.hue]; Add[x.saturation]; Add[x.brightness]; }; ColorOpPercent: PUBLIC PercentProc ~ { Set: PROC [param: RealParam] ~ --gfi saver-- INLINE { val: REAL _ GetReal[style, param]; SetReal[style, param, (percent*0.01)*val]; }; x: REF ParamRec.color ~ NARROW[p]; Set[x.hue]; Set[x.saturation]; Set[x.brightness]; }; RegisterWorks1: PUBLIC PROC [frame: Frame] ~ { RegisterStyleCommand[frame, $BeginStyle, BeginStyleOp]; RegisterStyleCommand[frame, $EndStyle, EndStyleOp]; RegisterStyleCommand[frame, $StyleRule, StyleRuleOp]; RegisterStyleCommand[frame, $PrintRule, PrintRuleOp]; RegisterStyleCommand[frame, $ScreenRule, ScreenRuleOp]; RegisterStyleCommand[frame, $AttachStyle, AttachStyleOp]; TJaM.Register[frame, $StyleName, StyleNameOp]; }; END. ŽNodeStyleWorks1Impl.mesa Copyright Σ 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Rick Beach, November 25, 1985 1:03:07 pm PST Michael Plass, December 30, 1987 4:30:48 pm PST Russ Atkinson (RRA) August 8, 1985 1:09:13 am PDT Doug Wyatt, January 24, 1987 11:34:17 pm PST Execution Frames for Style Machinery -- style is the StyleRef you will be using with the frame -- styleName tells which style dictionary you want -- will give you default style if requested style bombs during load -- first try to find one that already has the right style -- look for any free one get the proper style dictionary on the frame dictionary stack name and kind are just a hint about what style dictionary is on the frame stack add it to cache of free frames or really free it if cache full remove it from active frame info Style Dictionaries fake it so looks as if had a file saying "BeginStyle (Cedar) AttachStyle EndStyle" TJaM.Push[frame, styleName]; TJaM.PushRope[frame, "style was bad."]; StyleError[frame, 2]; Style File handling. Search rule handling Locking to avoid concurrent changes to internal style representation. Running styles and validation of style to file correspondence. Called from elsewhere in Tioga when something changes that may have changed any style. Does not attempt to refresh screen. Called from elsewhere in Tioga when something changes that may have changed a style. Does not attempt to refresh screen. this is probably where the use of working directories for style files needs to be added bindingDictName: PUBLIC ATOM; -- removed by mfp November 19, 1987 attachmentsDictName: PUBLIC ATOM; -- removed by mfp November 19, 1987 styledictName: PUBLIC ATOM; -- removed by mfp November 19, 1987 stylesDictsNames: PUBLIC REF ARRAY OfStyle OF ATOM _ NEW[ARRAY OfStyle OF ATOM]; -- not used; removed by mfp November 19, 1987 is the following redundant? I think so, so I commented it out. RJB stylesDictNames: PUBLIC REF ARRAY OfStyle OF ATOM _ NEW[ARRAY OfStyle OF ATOM]; create rule name dict in baseDict record the style kind expects on op stack OpenPrintStyleOp: TJaM.CommandProc ~ { -- expects style name on op stack OpenStyle[frame, print]; }; OpenScreenStyleOp: TJaM.CommandProc ~ { -- expects style name on op stack OpenStyle[frame, screen]; }; OpenStyle: PROC [frame: Frame, kind: OfStyle] ~ { name: ATOM _ PopName[frame]; IF NOT NodeStyleOps.LoadStyle[name] THEN RETURN; WHILE TJaM.DictTop[frame] # sysdict DO TJaM.End[frame]; ENDLOOP; TJaM.Begin[frame, styledict]; TJaM.Begin[frame, GetStyleDict[frame, name, kind]]; }; ResetTestStyleOp: TJaM.CommandProc ~ { IF debugStyle=NIL THEN debugStyle _ NodeStyleOps.Create[]; debugStyle^ _ NodeStyleOps.defaultStyle^; }; StyleRuleDictOp: TJaM.CommandProc ~ { GetRuleDict[frame, base] }; PrintRuleDictOp: TJaM.CommandProc ~ { GetRuleDict[frame, print] }; ScreenRuleDictOp: TJaM.CommandProc ~ { GetRuleDict[frame, screen] }; GetRuleDict: PROC [frame: Frame, kind: OfStyle] ~ { TJaM.Push[frame, styleRuleDictNames[kind]]; TJaM.Execute[frame, get]; }; Execute Styles Utility routine; ensures same stack depth after execution; protects against defs; does NOT handle TJaM.Stop makes sure that same stack depth after execute makes sure that same stack depth after execute makes sure that same stack depth after execute makes sure that same stack depth after execute names are "look.a", "look.b", "look.c", etc. Implementing Style Attribute Operations -- e.g., "2 pt bigger leading" -- e.g., "2 percent bigger leading" -- e.g., "2 pt smaller leading" -- e.g., "2 percent smaller leading" General Error Routines Name Parameter Operations Real Parameter Operations Glue Parameter Operations Color Parameter Operations Initialization register the various style commands and JaM commands in this module -- the following don't seem to be documented or used, so I removed them - mfp TJaM.Register[frame, $OpenPrintStyle, OpenPrintStyleOp]; TJaM.Register[frame, $OpenScreenStyle, OpenScreenStyleOp]; TJaM.Register[frame, $ResetTestStyle, ResetTestStyleOp]; TJaM.Register[frame, $StyleRuleDict, StyleRuleDictOp]; TJaM.Register[frame, $PrintRuleDict, PrintRuleDictOp]; TJaM.Register[frame, $ScreenRuleDict, ScreenRuleDictOp]; Κ#»˜codešœ™KšœH™HK™,K™/K™1K™,—K™šΟk ˜ Kšœœ˜ Kšœ œœ ˜Kšœœ˜Kšœ œ ˜Kšœœ ˜Kšœœ˜+Kšœ œ$˜3Kšœœ˜*Kšœ œ2˜DKšœœ˜KšœœΜ˜ΰKšœœ˜Kšœœ˜Kšœœ$˜0Kšœœ œ˜0Kšœ œ ˜Kšœ œ˜Kšœœξ˜ψKšœ œ˜!—K˜šΠblœœ˜"Kšœœ œ~˜œKšœ"˜)Kšœœœ˜'K˜—headšœ$™$K˜Kšœœœ˜K˜Kšœœ˜Kšœ œ˜%Kšœœ˜K˜Kšœœ˜Kšœ œœ˜$Kšœœœ/˜KK˜š Οnœœœœœ˜]Kšœ9™9Kšœ2™2KšœC™CKšœœ˜ š Ÿ œœœœœ˜>Kšœœœ˜K˜$šœœœ˜Kšœ:™:š œœœœ˜DKšœ#œœ˜1—š œœœœ˜DKšœ#œœ˜1—š œœœœ˜DKšœ#œœ˜1—š œœœœ˜DKšœ#œœ˜2——Kšœ™Kšœœœ$œ˜AKš œœœœ$œ˜FKš œœœœ$œ˜FKš œœœœ$œ˜Fšœ˜Kšœ˜K˜K˜K˜—K˜—šŸ œœœœ˜$Kšœœœ˜Kšœ œœ#˜7Kšœœ œœ#˜Kšœ œœ)œ˜GKšœœœ,˜NKšœ˜—Kšœ˜—KšœΟc9˜Všœ œœ˜Kšœ=™=K˜Kšœœœ˜K˜=šœœ )˜9šœ)œ !˜SK˜K˜<šœœ.˜>Kšœœ˜ —Kšœ ˜—šœœœ ˜-šœ!˜(Kšœœ˜——Kšœ˜—Kšœœœ8˜HKšœ˜—Kšœœ!œœ˜FK˜K˜—K˜š Ÿ œœœœœ˜OKšœO™OKšœœœ˜K˜"Kšœ>™>šœœœ˜Kšœ?˜?—šœœœœ˜Kšœ?˜?—šœœœœ˜ K˜?—šœœœœ˜K˜?—Kšœ  ˜CKšœ ™ šœ˜Kšœœ œ˜)Kšœœ œ˜)Kšœœ œ˜)Kšœœ œ˜)š œœ&œœ˜DKš œœœœœ˜EKšœ˜——K˜—K˜Kšœ(œ ˜LKšœ œ '˜Kšœœ =˜VKšœ& 5˜[Kšœ 4˜KK˜Kšœ8œ˜Kšœ˜—š Ÿ œœ œ œœ ˜GKšœœœœE˜WKšœœ8˜BKšœ œœ˜Kšœœ˜+š œ œœœ˜&Kšœ*œ)œ œ˜kKšœ˜Kšœ˜—Kš œ œœœœ˜$Kšœœ#˜.Kšœ˜——™EKšœœœ˜'Kšœœ˜Kšœ œ˜šŸœœœ œ˜(Kšœœ˜*šŸœœœ˜Kš œœœœœ˜PKšœ;˜;Kšœ˜—šŸœœœ˜Kšœ$˜$Kšœœœœ˜JKšœ˜—Kšœ˜Kšœ œ˜Kšœ ˜ Kšœ˜——šœ>™>šœ,˜,K˜—š Ÿœœœœ œœ˜?K™VK™#šŸœœ˜š Ÿœœœœœœ˜=Kšœœœ œ˜2Kšœœ˜Kšœ˜—Kšœ(˜(Kšœ˜—Kšœ˜Kšœ˜K˜—šŸ œœœ œœ œœ˜PK™TK™#šŸœœ˜Kšœ0˜0Kšœœ,˜Fš œ œœ œœ˜=Kšœ ˜šœ˜Kšœœœ ˜*Kšœ œ˜Kšœœœ œ ˜eKšœ˜——Kšœ˜—Kšœ˜Kšœ˜K˜—Kšœ œ -˜HšŸœœœœœœœ˜TšŸœœ˜Kšœœœ˜ KšœW™WKšœ0˜0K˜7Kš œ œœœœ˜*Kšœ-˜-Kšœ"œ˜)Kšœ œ˜'Kšœ˜Kšœ"˜"˜Kšœ œ ˜Kšœœœ˜+Kšœœœ˜*Kšœœœ˜,Kšœ˜—Kšœ˜Kšœ œ ˜Kšœœœ˜.Kšœœ4˜>Kšœœœ˜2Kšœ˜—Kšœ˜Kšœ˜K˜—šŸœœœœœœœ˜]Kšœœœ˜ K˜7šœ$˜$Kšœœ˜#Kšœœœ˜+Kšœœœ˜*Kšœœœ˜,Kšœ˜—Kšœ œ ˜Kšœ˜—K˜—Kšœ œ ˜Kšœ œ ˜Kšœ œ ˜K˜Kšœœ(˜;Kšœœ(˜;K˜š Ÿœœœœœœ˜\Kšœœ˜ K˜ K˜*Kšœœ˜+šœ˜Kšœ ˜ K˜$K˜—K˜K˜—Kšœœœ&™BKšœœœ&™Fšœœœ&™@K˜—Kšœ œ ˜Kšœœ ˜"K˜Kšœ œœ œœœœ œœ˜^šœœœ œœœœ œœ˜MKšœ-˜-Kšœ/˜/Kšœ-˜-Kšœ˜—šœœœ œœœœ œœ˜HKšœ)˜)Kšœ+˜+Kšœ)˜)Kšœ˜—K˜Kšœ œœ œœœœ œœ1™K™CKšœ œœ œœœœ œœ™OK˜Kš œ  œœ œ œœ œ ˜UK˜Kšœœœ ,˜IKšœ œœ (˜CKš œ œœœœ ,˜UK˜šŸ œ˜"Kšœœœ  ˜NK˜+šŸ œœœ˜,Kšœ˜Kšœ˜Kšœ˜—šŸœœœœ˜CK˜K˜!K˜—šŸ œœ$œ˜;K˜?Kšœ!™!K˜/Kšœ™K˜—Kšœœ˜ Kšœ0 ˜Ešœ˜šœ˜K˜K˜,K˜K˜.K˜K˜K˜—šœ˜K˜K˜K˜K˜——K˜VK˜&K˜%K˜7K˜5K˜3K˜(K˜Kšœ #˜?Kšœ ˜*Kšœ˜K˜—šŸ œ˜ Kšœœ˜Kšœ ˜3Kšœ ˜.šœ˜ šœ˜K˜?K˜K˜—šœ H˜OKšœœœ ˜K˜7K˜5K˜ K˜K˜ K˜K˜K˜——Kšœ  ˜(Kšœ˜K˜—šŸ œ '˜IKšœ1˜1K˜K˜—K˜šŸ œ6˜AK˜—šŸ œ7˜BK˜—KšŸ œ8˜DK˜•StartOfExpansion1[dict: TJaM.Dict, key: ATOM, val: TJaM.Any]šŸœœ&œ˜Jšœ&œ˜.Kšœ˜Kšœ,˜,Kšœ˜Kšœ+˜+Kšœ˜—Kšœ ˜0Kšœ˜K˜—šŸœœ"˜7Kšœ1™1K˜%K˜"Kšœ œ˜!Kšœœ˜'K˜-Kšœ œ5˜Dšœ œ˜K˜,Kšœ ˜—Kšœ"˜"Kšœ' ˜=Kšœœ,˜DKšœi ˜Kšœ9 )˜bK˜K˜—šŸ œœœ˜IKšœ9˜?Kšœ˜K˜—šŸœœœ˜MKšœ=˜CKšœ˜K˜—šŸœ !™HK™K™K™—šŸœ !™IK™K™K™—šŸ œœ"™1Kšœœ™Kšœœœœ™0Kšœœœ™@K™K™3K™K™—šŸœ™'Kšœ œœ$™:Kšœ)™)K™—K˜šŸœ2™AK™—šŸœ3™BK™—KšŸœ4™DK˜šŸ œœ"™3K™+K™K™K™—šŸ œ 0˜TKšœœ"˜,Kšœœ˜ K˜!K˜Kšœ œœ ˜#K˜ K˜1šœœœ˜Kšœœ2˜Ošœœœ˜K˜Kšœ˜Kšœ˜—Kšœ˜—K˜3Kšœœœœ˜K˜:K˜8K˜9Kšœœœ ˜Jšœ ˜#šœœ˜K˜Kšœœ˜—K–([array: TJaM.Array, expand: INT _ 0]˜,K˜—K˜$K˜,K˜K˜—šŸœœœ œœ œœœ˜hK˜ K˜Kšœœ˜ K˜$K˜8Kšœœœœ˜šœœ˜K˜Kšœœ˜—šœœœ˜$Kšœ*œœ˜8Kšœ˜—K˜K˜——™Kšœœ˜š Ÿœœœœœ˜HKšœœœ˜Kšœ)œ˜-šœœœ˜šŸœœœ œ˜*Kšœ}˜}K–1[dict: TJaM.Dict, key: ATOM, val: TJaM.Any]šœ?˜?Kšœ˜—Kšœ˜Kšœ˜K–1[dict: TJaM.Dict, key: ATOM, val: TJaM.Any]šœ˜K–1[dict: TJaM.Dict, key: ATOM, val: TJaM.Any]šœ˜K–1[dict: TJaM.Dict, key: ATOM, val: TJaM.Any]šœ˜K–1[dict: TJaM.Dict, key: ATOM, val: TJaM.Any]šœ˜Kšœ˜—Kšœ˜K˜—šŸœœœœ˜?Kšœ˜Kšœ˜K˜—š Ÿ œœ œœœ˜PKš bœ ™kKšœ œ˜-Kšœ œ˜Kšœ,˜,K–([frame: TJaM.Frame, dict: TJaM.Dict]šœ œ ˜/Kšœ,˜,Kšœ˜Kšœ$˜$šœœ˜ Kšœ˜K˜MKšœ˜Kšœœ˜ Kšœ˜—šœ#œ+œ˜oKšœ2˜6šœ˜Kšœ#œ˜:Kšœ˜K˜7Kšœ˜Kšœœ˜ Kšœ˜——šœ˜K˜——šŸ œœœœœœœ˜RKš .™.šœ ˜ Kšœœœ˜$Kšœ"œ˜0Kšœ˜—šœ˜K˜——šŸœœœ&œœœœ˜iKš .™.Kšœ œ˜"Kšœ.˜.šœœ(œ˜4Kšœ+œ˜/Kšœœ˜Kšœ˜—Kšœ#˜#Kšœœ#˜-Kšœœ˜ Kšœ œ˜šœ˜K˜——š Ÿœœœ+œœœ˜iKš .™.Kšœ œ˜"Kšœ.˜.˜Kšœœœ˜Kšœ,˜,Kšœœ˜K˜—Kšœœ#˜-Kšœœ˜ Kšœ œ˜šœ˜K˜——š Ÿœœœ3œœœ˜pKš .™.Kšœ œ˜"Kšœ.˜.šœœœ˜ Kšœ œ+œ'œ˜kKšœ˜—Kšœœ#˜-Kšœœ˜ Kšœ œ˜šœœ˜KšœΉ˜ΉK˜—šœ˜K˜——šœœœ˜K˜—Kš œ œœœœ˜0šœ œ˜+š Ÿ œœœ œ  œœ˜KKš ,™,Kšœœ ˜šœœœ˜ KšœE˜EKšœ˜—Kšœ˜——K˜šŸ œœœœ˜8Kšœ˜Kšœ/œ˜9Kšœ˜K˜——™'K˜šŸ œ œ˜3Kšœœ˜ Kšœœ˜ K˜"šŸœœ  œœ˜$K˜K˜0K˜K˜K˜—K˜$Kšœœœ ˜Gšœœ˜Kšœ% ˜;šœ ˜ Kšœ$˜$šœœœ4˜EKšœ™—šœœœ8˜TKšœ#™#—Kšœ œ˜Kšœ˜—šœ ˜ Kšœ$˜$šœœœ5˜FKšœ™—šœœœ8˜TKšœ$™$—Kšœ œ˜Kšœ˜—Kšœ@˜@Kšœ* ˜M—K˜K˜——šœ™K˜šŸ œœ˜ K˜K˜K˜2K˜K˜K˜K˜—šŸ œœ˜%K˜:K˜K˜K˜K˜—šŸ œœ˜%K˜:K˜K˜K˜K˜—šŸ œœ˜%K˜=K˜K˜K˜K˜——šœ™K˜Kšœ œœR˜kK˜šŸ œœ ˜"Kšœœœ˜Ašœ˜K˜——šŸ œœ˜$Kšœ œœ˜6Kšœ˜—K˜šŸ œœœœ˜?K˜K˜-K˜K˜K˜K˜——šœ™K˜Kšœ œœT˜mK˜šŸ œœ ˜šœ$œœ˜JK˜——šŸ œœ˜#šœœœ-˜IK˜——šŸ œœ˜%Kšœœœ˜!šœ6˜6K˜——šŸ œœ˜%Kšœœœœ˜?Kšœœœ+˜GKšœ˜K˜——šœ™K˜Kšœ œœT˜mK˜šŸ œœ ˜šŸœœ  œœ˜5Kšœ.˜.—Kšœœœ˜!Kšœ+˜+šœ˜K˜——šŸ œœ˜#šŸœœ  œœ˜5K˜-—Kšœœœ˜!Kšœ+˜+šœ˜K˜——šŸ œœ˜%šŸœœ  œœ˜5K˜3—Kšœœœ˜!Kšœ+˜+šœ˜K˜——šŸ œœ˜%šŸœœ  œœ˜5Kšœœ˜"K˜*K˜—Kšœœœ˜!Kšœ+˜+šœ˜K˜———šœ™K˜Kšœ œœX˜rK˜šŸ œœ ˜ šŸœœ  œœ˜5Kšœ,˜,K˜—Kšœœœ˜"Kšœ1˜1šœ˜K˜——šŸœœ˜$šŸœœ  œœ˜5K˜+K˜—Kšœœœ˜"Kšœ1˜1šœ˜K˜——šŸœœ˜&šŸœœ  œœ˜5K˜1K˜—Kšœœœ˜"Kšœ1˜1šœ˜K˜——šŸœœ˜&šŸœœ  œœ˜5Kšœœ˜"K˜*K˜—Kšœœœ˜"Kšœ1˜1Kšœ˜K˜——™K˜šŸœœœ˜.KšœC™CKšœ7˜7Kšœ3˜3Kšœ5˜5Kšœ5˜5Kšœ7˜7Kšœ9˜9K˜.™MK™8K™:K™8K™6K™6K™8—K˜——K™Kšœ˜K™—…—kvŸΏ