DIRECTORY Atom USING [GetPName, MakeAtom], Buttons USING [ButtonProc], CharOps USING [XAlphaNumeric, XBlank], EditToolBuilder USING [BuildButton, BuildDataFieldPair, BuildPair, BuildTriple, DataFieldButton, GetDataNode, HGap, ToMiddle, ToNext, VGap], EditToolPrivate, Labels USING [Set], MessageWindow USING [Append, Blink], NodeProps, NodeStyleOps USING [StyleNameForNode], Process USING [Detach], Rope USING [Concat, Equal, ROPE, Substr], RuntimeError USING [UNCAUGHT], TEditDocument USING [Selection, SelectionPoint], TEditInput USING [CommandProc, CurrentEvent], TEditInputOps USING [CheckReadonly, LoadAbbreviations, ReloadStyleName, SetStyleName, SetFormatName], TEditLocks USING [Lock], TEditOps USING [GetSelData, SetTextContents], TEditSelection USING [LockSel, pSel, SelectionRoot, UnlockDocAndPSel, UnlockSel], TextEdit, TextNode USING [NodeItself, Ref, Root, StepForward], ViewerClasses USING [Viewer], ViewerOps USING [EnumerateChildren, EnumerateViewers, PaintViewer]; EditToolMiscImpl: CEDAR PROGRAM IMPORTS Atom, CharOps, EditToolBuilder, EditToolPrivate, Labels, MessageWindow, NodeProps, NodeStyleOps, Process, Rope, RuntimeError, TEditInput, TEditInputOps, TEditLocks, TEditOps, TEditSelection, TextEdit, TextNode, ViewerOps EXPORTS EditToolPrivate = BEGIN ROPE: TYPE ~ Rope.ROPE; BuildRealPropertyButtons: PUBLIC PROC [info: EditToolPrivate.Info] = { [, info.propNameArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "PropName:", PropNameArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; [, info.propValueArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "PropValue:", PropValueArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; info.propNode ¬ forSelectedNodes; [] ¬ EditToolBuilder.BuildButton[info.layout, "GetNodeProp", GetPropButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "SetNodeProp", SetPropButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "RemoveNodeProp", RemovePropButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "ListNodeProps", ListPropsButton, info]; EditToolBuilder.ToNext[info.layout]; EditToolBuilder.ToMiddle[info.layout]; propRootNameRope ¬ "PropForRoot"; propSelectionNameRope ¬ "PropForSelection"; propSelectedCharsNameRope ¬ "PropForSelectedCharacter"; [info.propNodeLabel, ] ¬ EditToolBuilder.BuildTriple[info.layout, PropNodeButton, ORD[info.propNode], propRootNameRope,propSelectionNameRope, propSelectedCharsNameRope, info]; EditToolBuilder.ToNext[info.layout]; [] ¬ EditToolBuilder.BuildButton[info.layout, "FindNodeProp", FindPropButton, info]; EditToolBuilder.HGap[info.layout]; [, info.propPatternArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "PropPattern:", PropPatternArgButton, info, 1]; }; BuildPropertyButtons: PUBLIC PROC [info: EditToolPrivate.Info] = { [, info.propNameArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Property name:", PropNameArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; [, info.propValueArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Property value:", PropValueArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; info.propNode ¬ forSelectedNodes; [] ¬ EditToolBuilder.BuildButton[info.layout, "Get", GetPropButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Set", SetPropButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Remove", RemovePropButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "List", ListPropsButton, info]; EditToolBuilder.ToMiddle[info.layout]; propRootNameRope ¬ "For root node"; propSelectionNameRope ¬ "For selected nodes"; propSelectedCharsNameRope ¬ "For selected characters"; [info.propNodeLabel, ] ¬ EditToolBuilder.BuildTriple[info.layout, PropNodeButton, ORD[info.propNode], propRootNameRope,propSelectionNameRope, propSelectedCharsNameRope, info]; EditToolBuilder.ToNext[info.layout]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Find", FindPropButton, info]; EditToolBuilder.HGap[info.layout]; [, info.propPatternArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Value pattern:", PropPatternArgButton, info, 1]; }; BuildRealStyleButtons: PUBLIC PROC [info: EditToolPrivate.Info] = { [, info.styleNameArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Style name:", StyleNameArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; info.styleNode ¬ forRoot; [] ¬ EditToolBuilder.BuildButton[info.layout, "GetNodeStyleName", GetStyleNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "SetNodeStyleName", SetStyleNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "ClearNodeStyleName", ClearStyleNameButton, info]; EditToolBuilder.ToNext[info.layout]; EditToolBuilder.ToMiddle[info.layout]; styleSelectionNameRope ¬ "StyleNameForSelection"; styleRootNameRope ¬ "StyleNameForRoot"; [info.styleNodeLabel, ] ¬ EditToolBuilder.BuildPair[info.layout, StyleNameNodeButton, info.styleNode=forSelectedNodes, styleSelectionNameRope, styleRootNameRope, info]; EditToolBuilder.ToNext[info.layout]; [] ¬ EditToolBuilder.BuildButton[info.layout, "LoadStyleDefinition", LoadStyleButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "LoadAbbreviations", LoadAbbreviationsButton, info]; }; BuildStyleButtons: PUBLIC PROC [info: EditToolPrivate.Info] = { [, info.styleNameArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Style name:", StyleNameArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; info.styleNode ¬ forRoot; [] ¬ EditToolBuilder.BuildButton[info.layout, "Get", GetStyleNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Set", SetStyleNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Clear", ClearStyleNameButton, info]; EditToolBuilder.ToMiddle[info.layout]; styleSelectionNameRope ¬ "For selected nodes"; styleRootNameRope ¬ "For root node"; [info.styleNodeLabel, ] ¬ EditToolBuilder.BuildPair[info.layout, StyleNameNodeButton, info.styleNode=forSelectedNodes, styleSelectionNameRope, styleRootNameRope, info]; EditToolBuilder.ToNext[info.layout]; [] ¬ EditToolBuilder.BuildButton[info.layout, "LoadStyleDefinition", LoadStyleButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "LoadAbbreviations", LoadAbbreviationsButton, info]; }; BuildFormatButtons: PUBLIC PROC [info: EditToolPrivate.Info] = { [, info.formatNameArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Format name:", FormatNameArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; info.formatNode ¬ forSelectedNodes; [] ¬ EditToolBuilder.BuildButton[info.layout, "Get", GetFormatNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Set", SetFormatNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "Clear", ClearFormatNameButton, info]; EditToolBuilder.ToMiddle[info.layout]; formatSelectionNameRope ¬ "For selected nodes"; formatRootNameRope ¬ "For root node"; [info.formatNodeLabel, ] ¬ EditToolBuilder.BuildPair[info.layout, FormatNameNodeButton, info.formatNode=forSelectedNodes, formatSelectionNameRope, formatRootNameRope, info]; }; BuildRealFormatButtons: PUBLIC PROC [info: EditToolPrivate.Info] = { [, info.formatNameArg] ¬ EditToolBuilder.BuildDataFieldPair[info.layout, "Format name:", FormatNameArgButton, info, 1]; EditToolBuilder.VGap[info.layout]; info.formatNode ¬ forSelectedNodes; [] ¬ EditToolBuilder.BuildButton[info.layout, "GetNodeFormatName", GetFormatNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "SetNodeFormatName", SetFormatNameButton, info]; [] ¬ EditToolBuilder.BuildButton[info.layout, "ClearNodeFormatName", ClearFormatNameButton, info]; EditToolBuilder.ToNext[info.layout]; EditToolBuilder.ToMiddle[info.layout]; formatSelectionNameRope ¬ "FormatNameForSelection"; formatRootNameRope ¬ "FormatNameForRoot"; [info.formatNodeLabel, ] ¬ EditToolBuilder.BuildPair[info.layout, FormatNameNodeButton, info.formatNode=forSelectedNodes, formatSelectionNameRope, formatRootNameRope, info]; }; BadArg: PUBLIC ERROR = CODE; GetNameArg: PUBLIC PROC [arg: ViewerClasses.Viewer] RETURNS [ROPE] = { node: TextNode.Ref ~ EditToolBuilder.GetDataNode[arg]; size: INT ~ TextEdit.Size[node]; start, end: INT ¬ size; FOR i: INT IN[0..size) DO IF NOT CharOps.XBlank[TextEdit.FetchChar[node, i]] THEN { start ¬ i; EXIT }; ENDLOOP; FOR i: INT IN[start..size) DO IF NOT CharOps.XAlphaNumeric[TextEdit.FetchChar[node, i]] THEN { end ¬ i; EXIT }; ENDLOOP; FOR i: INT IN[end..size) DO IF NOT CharOps.XBlank[TextEdit.FetchChar[node, i]] THEN GOTO Bad; ENDLOOP; IF end>start THEN RETURN[Rope.Substr[node.rope, start, end-start]] ELSE GOTO Bad; EXITS Bad => { MessageWindow.Append["Enter name consisting of one or more alphanumeric characters.", TRUE]; MessageWindow.Blink[]; ERROR BadArg; }; }; GetRopeArg: PUBLIC PROC [arg: ViewerClasses.Viewer] RETURNS [ROPE] = { node: TextNode.Ref ~ EditToolBuilder.GetDataNode[arg]; size: INT ~ TextEdit.Size[node]; FOR i: INT IN[0..size) DO IF NOT Char.Set[TextEdit.FetchChar[node, i]]=0 THEN GOTO Bad; ENDLOOP; RETURN[node.rope]; EXITS Bad => { MessageWindow.Append["Enter value consisting only of 8-bit characters.", TRUE]; MessageWindow.Blink[]; ERROR BadArg; }; }; ForEachNode: PROC [nodeKind: EditToolPrivate.NodeKind, pSel: TEditDocument.Selection, proc: PROC [node: TextNode.Ref, start: INT, size: INT]] = { SELECT nodeKind FROM forRoot => proc[TextNode.Root[pSel.start.pos.node], 0, 0]; forSelectedNodes, forSelectedChars => { FOR node: TextNode.Ref ¬ pSel.start.pos.node, TextNode.StepForward[node] DO start: INT ¬ 0; end: INT ¬ TextEdit.Size[node]; IF node = pSel.start.pos.node AND pSel.start.pos.where # TextNode.NodeItself THEN { start ¬ pSel.start.pos.where; }; IF node = pSel.end.pos.node AND pSel.end.pos.where # TextNode.NodeItself THEN { end ¬ MIN[end, pSel.end.pos.where+1]; }; proc[node: node, start: start, size: end-start]; IF node = pSel.end.pos.node THEN EXIT; ENDLOOP; }; ENDCASE => ERROR }; SetNodeName: PROC [info: EditToolPrivate.Info, name: ROPE, style: BOOLEAN, pSel: TEditDocument.Selection] = { Set: PROC [node: TextNode.Ref, start: INT, size: INT] = { IF style THEN TEditInputOps.SetStyleName[name, node] ELSE TEditInputOps.SetFormatName[name, node] }; ForEachNode[IF style THEN info.styleNode ELSE info.formatNode, pSel, Set] }; styleNameArgAtom: LIST OF REF = EditToolPrivate.Register[$StyleName, StyleNameArgOp]; clearStyleNameArgAtom: LIST OF REF = EditToolPrivate.Register[$ClearStyleName, ClearStyleNameArgOp]; StyleNameArgButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[styleNameArgAtom, clearStyleNameArgAtom, mouseButton=red] }; StyleNameArgOp: TEditInput.CommandProc = { EditToolBuilder.DataFieldButton[EditToolPrivate.mainToolInfo.styleNameArg, FALSE] }; ClearStyleNameArgOp: TEditInput.CommandProc = { EditToolBuilder.DataFieldButton[EditToolPrivate.mainToolInfo.styleNameArg, TRUE] }; formatNameArgAtom: LIST OF REF = EditToolPrivate.Register[$FormatName, FormatNameArgOp]; typeNameArgAtom: LIST OF REF = EditToolPrivate.Register[$TypeName, FormatNameArgOp]; clearFormatNameArgAtom: LIST OF REF = EditToolPrivate.Register[$ClearFormatName, ClearFormatNameArgOp]; clearTypeNameArgAtom: LIST OF REF = EditToolPrivate.Register[$ClearTypeName, ClearFormatNameArgOp]; FormatNameArgButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[formatNameArgAtom, clearFormatNameArgAtom, mouseButton=red] }; FormatNameArgOp: TEditInput.CommandProc = { EditToolBuilder.DataFieldButton[EditToolPrivate.mainToolInfo.formatNameArg, FALSE] }; ClearFormatNameArgOp: TEditInput.CommandProc = { EditToolBuilder.DataFieldButton[EditToolPrivate.mainToolInfo.formatNameArg, TRUE] }; getStyleNameAtom: LIST OF REF = EditToolPrivate.Register[$GetNodeStyleName, GetStyleNameOp]; GetStyleNameButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[getStyleNameAtom] }; GetStyleNameOp: TEditInput.CommandProc = { GetStyleNameCom[EditToolPrivate.mainToolInfo]; }; GetStyleNameCom: PROC [info: EditToolPrivate.Info] = { GetNameCom[info, TRUE]; }; getFormatNameAtom: LIST OF REF = EditToolPrivate.Register[$GetNodeFormatName, GetFormatNameOp]; getTypeNameAtom: LIST OF REF = EditToolPrivate.Register[$GetNodeTypeName, GetFormatNameOp]; GetFormatNameButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[getFormatNameAtom] }; GetFormatNameOp: TEditInput.CommandProc = { GetFormatNameCom[EditToolPrivate.mainToolInfo]; }; GetFormatNameCom: PROC [info: EditToolPrivate.Info] = { GetNameCom[info, FALSE]; }; NotUniform: SIGNAL = CODE; GetNameCom: PROC [info: EditToolPrivate.Info, style: BOOLEAN] = { pSel: TEditDocument.Selection = TEditOps.GetSelData[]; nodeKind: EditToolPrivate.NodeKind ¬ IF style THEN info.styleNode ELSE info.formatNode; name: ATOM ¬ NIL; arg: ViewerClasses.Viewer ¬ IF style THEN info.styleNameArg ELSE info.formatNameArg; Get: PROC [node: TextNode.Ref, start, size: INT] = { n: ATOM ¬ IF style THEN NodeStyleOps.StyleNameForNode[node] ELSE TextEdit.GetFormat[node]; IF name = NIL THEN name ¬ n ELSE IF name # n THEN { MessageWindow.Append[IF style THEN "Nodes don't have uniform style. Using first." ELSE "Nodes don't have uniform format. Using first.", TRUE]; MessageWindow.Blink[]; SIGNAL NotUniform; } }; IF NOT EditToolPrivate.CheckPSel[pSel] THEN RETURN; ForEachNode[nodeKind, pSel, Get ! NotUniform => CONTINUE]; TEditOps.SetTextContents[arg, IF name=NIL THEN NIL ELSE Atom.GetPName[name]]; }; setStyleNameAtom: LIST OF REF = EditToolPrivate.Register[$SetNodeStyleName, SetStyleNameOp]; SetStyleNameButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[setStyleNameAtom] }; SetStyleNameOp: TEditInput.CommandProc = { SetStyleNameCom[EditToolPrivate.mainToolInfo]; }; SetStyleNameCom: PROC [info: EditToolPrivate.Info] = { SetNameCom[info, TRUE]; }; setFormatNameAtom: LIST OF REF = EditToolPrivate.Register[$SetNodeFormatName, SetFormatNameOp]; setTypeNameAtom: LIST OF REF = EditToolPrivate.Register[$SetNodeTypeName, SetFormatNameOp]; SetFormatNameButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[setFormatNameAtom] }; SetFormatNameOp: TEditInput.CommandProc = { SetFormatNameCom[EditToolPrivate.mainToolInfo]; }; SetFormatNameCom: PROC [info: EditToolPrivate.Info] = { SetNameCom[info, FALSE]; }; SetNameCom: PROC [info: EditToolPrivate.Info, style: BOOLEAN] = { pSel: TEditDocument.Selection; arg: ViewerClasses.Viewer ¬ IF style THEN info.styleNameArg ELSE info.formatNameArg; name: ROPE ¬ GetNameArg[arg ! BadArg => GOTO Bad]; TEditSelection.LockSel[primary, "SetNameCom"]; pSel ¬ TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] OR NOT TEditInputOps.CheckReadonly[pSel] THEN { TEditSelection.UnlockSel[primary]; RETURN; }; SetNodeName[info, name, style, pSel]; TEditSelection.UnlockSel[primary]; EXITS Bad => RETURN }; clearFormatNameAtom: LIST OF REF = EditToolPrivate.Register[$ClearNodeFormatName, ClearFormatNameOp]; clearTypeNameAtom: LIST OF REF = EditToolPrivate.Register[$ClearNodeTypeName, ClearFormatNameOp]; ClearFormatNameButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[clearFormatNameAtom] }; ClearFormatNameOp: TEditInput.CommandProc = { ClearFormatNameCom[EditToolPrivate.mainToolInfo]; }; ClearFormatNameCom: PROC [info: EditToolPrivate.Info] = { pSel: TEditDocument.Selection = TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] THEN RETURN; IF NOT TEditInputOps.CheckReadonly[pSel] THEN RETURN; SetNodeName[info, NIL, FALSE, pSel] }; clearStyleNameAtom: LIST OF REF = EditToolPrivate.Register[$ClearNodeStyleName, ClearStyleNameOp]; ClearStyleNameButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[clearStyleNameAtom] }; ClearStyleNameOp: TEditInput.CommandProc = { ClearStyleNameCom[EditToolPrivate.mainToolInfo]; }; ClearStyleNameCom: PROC [info: EditToolPrivate.Info] = { pSel: TEditDocument.Selection = TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] THEN RETURN; IF NOT TEditInputOps.CheckReadonly[pSel] THEN RETURN; SetNodeName[info, NIL, TRUE, pSel] }; loadStyleAtom: LIST OF REF = EditToolPrivate.Register[$LoadStyleDefinition, LoadStyleOp]; LoadStyleButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[loadStyleAtom] }; LoadStyleOp: TEditInput.CommandProc = { LoadStyle[EditToolPrivate.mainToolInfo]; }; LoadStyle: PROC [info: EditToolPrivate.Info] = { repaint: PROC [v: ViewerClasses.Viewer] RETURNS [BOOL ¬ TRUE] = { SELECT v.class.flavor FROM $Text => TRUSTED {Process.Detach[FORK ViewerOps.PaintViewer[v, all]]}; $Container => ViewerOps.EnumerateChildren[v, repaint]; ENDCASE; RETURN [TRUE] }; name: ROPE ¬ GetNameArg[info.styleNameArg ! BadArg => GOTO Bad]; TEditInputOps.ReloadStyleName[name]; ViewerOps.EnumerateViewers[repaint]; EXITS Bad => RETURN }; loadAbbreviationsAtom: LIST OF REF = EditToolPrivate.Register[$LoadAbbreviations, LoadAbbreviationsOp]; LoadAbbreviationsButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[loadAbbreviationsAtom] }; LoadAbbreviationsOp: TEditInput.CommandProc = { LoadAbbreviations[EditToolPrivate.mainToolInfo]; }; LoadAbbreviations: PROC [info: EditToolPrivate.Info] = { name: ROPE ¬ GetNameArg[info.styleNameArg ! BadArg => GOTO Bad]; TEditInputOps.LoadAbbreviations[name]; EXITS Bad => RETURN }; styleRootNameRope: ROPE; formatRootNameRope: ROPE; propRootNameRope: ROPE; styleSelectionNameRope: ROPE; formatSelectionNameRope: ROPE; propSelectionNameRope: ROPE; propSelectedCharsNameRope: ROPE; rootFormatNameAtom: LIST OF REF = EditToolPrivate.Register[$FormatNameForRoot, RootFormatNameOp]; rootTypeNameAtom: LIST OF REF = EditToolPrivate.Register[$TypeNameForRoot, RootFormatNameOp]; selFormatNameAtom: LIST OF REF = EditToolPrivate.Register[$FormatNameForSelection, SelectionFormatNameOp]; selTypeNameAtom: LIST OF REF = EditToolPrivate.Register[$TypeNameForSelection, SelectionFormatNameOp]; FormatNameNodeButton: Buttons.ButtonProc = { EditToolPrivate.ChangeState[EditToolPrivate.mainToolInfo.formatNode=forSelectedNodes, selFormatNameAtom, rootFormatNameAtom] }; RootFormatNameOp: TEditInput.CommandProc = { RootFormatName[EditToolPrivate.mainToolInfo]; }; RootFormatName: PROC [info: EditToolPrivate.Info] = { info.formatNode ¬ forRoot; Labels.Set[info.formatNodeLabel, formatRootNameRope] }; SelectionFormatNameOp: TEditInput.CommandProc = { SelectionFormatName[EditToolPrivate.mainToolInfo]; }; SelectionFormatName: PROC [info: EditToolPrivate.Info] = { info.formatNode ¬ forSelectedNodes; Labels.Set[info.formatNodeLabel, formatSelectionNameRope] }; rootStyleNameAtom: LIST OF REF = EditToolPrivate.Register[$StyleNameForRoot, RootStyleNameOp]; selStyleNameAtom: LIST OF REF = EditToolPrivate.Register[$StyleNameForSelection, SelectionStyleNameOp]; StyleNameNodeButton: Buttons.ButtonProc = { EditToolPrivate.ChangeState[EditToolPrivate.mainToolInfo.styleNode=forSelectedNodes, selStyleNameAtom, rootStyleNameAtom] }; RootStyleNameOp: TEditInput.CommandProc = { RootStyleName[EditToolPrivate.mainToolInfo]; }; RootStyleName: PROC [info: EditToolPrivate.Info] = { info.styleNode ¬ forRoot; Labels.Set[info.styleNodeLabel, styleRootNameRope] }; SelectionStyleNameOp: TEditInput.CommandProc = { SelectionStyleName[EditToolPrivate.mainToolInfo]; }; SelectionStyleName: PROC [info: EditToolPrivate.Info] = { info.styleNode ¬ forSelectedNodes; Labels.Set[info.styleNodeLabel, styleSelectionNameRope] }; propNameArgAtom: LIST OF REF = EditToolPrivate.Register[$PropName, PropNameArgOp]; clearPropNameArgAtom: LIST OF REF = EditToolPrivate.Register[$ClearPropName, ClearPropNameArgOp]; PropNameArgButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[propNameArgAtom, clearPropNameArgAtom, mouseButton=red] }; PropNameArgOp: TEditInput.CommandProc = { PropNameArg[EditToolPrivate.mainToolInfo]; }; PropNameArg: PROC [info: EditToolPrivate.Info] = { EditToolBuilder.DataFieldButton[info.propNameArg, FALSE]; }; ClearPropNameArgOp: TEditInput.CommandProc = { ClearPropNameArg[EditToolPrivate.mainToolInfo]; }; ClearPropNameArg: PROC [info: EditToolPrivate.Info] = { EditToolBuilder.DataFieldButton[info.propNameArg, TRUE]; }; propValueArgAtom: LIST OF REF = EditToolPrivate.Register[$PropValue, PropValueArgOp]; clearPropValueArgAtom: LIST OF REF = EditToolPrivate.Register[$ClearPropValue, ClearPropValueArgOp]; PropValueArgButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[propValueArgAtom, clearPropValueArgAtom, mouseButton=red] }; PropValueArgOp: TEditInput.CommandProc = { PropValueArg[EditToolPrivate.mainToolInfo]; }; PropValueArg: PROC [info: EditToolPrivate.Info] = { EditToolBuilder.DataFieldButton[info.propValueArg, FALSE] }; ClearPropValueArgOp: TEditInput.CommandProc = { ClearPropValueArg[EditToolPrivate.mainToolInfo] }; ClearPropValueArg: PROC [info: EditToolPrivate.Info] = { EditToolBuilder.DataFieldButton[info.propValueArg, TRUE] }; propPatternArgAtom: LIST OF REF = EditToolPrivate.Register[$PropPattern, PropPatternArgOp]; clearPropPatternArgAtom: LIST OF REF = EditToolPrivate.Register[$ClearPropPattern, ClearPropPatternArgOp]; PropPatternArgButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[propPatternArgAtom, clearPropPatternArgAtom, mouseButton=red] }; PropPatternArgOp: TEditInput.CommandProc = { PropPatternArg[EditToolPrivate.mainToolInfo] }; PropPatternArg: PROC [info: EditToolPrivate.Info] = { EditToolBuilder.DataFieldButton[info.propPatternArg, FALSE] }; ClearPropPatternArgOp: TEditInput.CommandProc = { ClearPropPatternArg[EditToolPrivate.mainToolInfo] }; ClearPropPatternArg: PROC [info: EditToolPrivate.Info] = { EditToolBuilder.DataFieldButton[info.propPatternArg, TRUE] }; rootPropAtom: LIST OF REF = EditToolPrivate.Register[$PropForRoot, RootPropOp]; selPropAtom: LIST OF REF = EditToolPrivate.Register[$PropForSelection, SelectionPropOp]; charPropAtom: LIST OF REF = EditToolPrivate.Register[$PropForSelectedCharacter, CharacterPropOp]; PropNodeButton: Buttons.ButtonProc = { EditToolPrivate.CycleTriple[ORD[EditToolPrivate.mainToolInfo.propNode], rootPropAtom, selPropAtom, charPropAtom] }; RootPropOp: TEditInput.CommandProc = { RootProp[EditToolPrivate.mainToolInfo]; }; RootProp: PROC [info: EditToolPrivate.Info] = { info.propNode ¬ forRoot; Labels.Set[info.propNodeLabel, propRootNameRope] }; SelectionPropOp: TEditInput.CommandProc = { SelectionProp[EditToolPrivate.mainToolInfo]; }; SelectionProp: PROC [info: EditToolPrivate.Info] = { info.propNode ¬ forSelectedNodes; Labels.Set[info.propNodeLabel, propSelectionNameRope] }; CharacterPropOp: TEditInput.CommandProc = { SelectedCharsProp[EditToolPrivate.mainToolInfo]; }; SelectedCharsProp: PROC [info: EditToolPrivate.Info] = { info.propNode ¬ forSelectedChars; Labels.Set[info.propNodeLabel, propSelectedCharsNameRope] }; getPropAtom: LIST OF REF = EditToolPrivate.Register[$GetNodeProp, GetPropOp]; GetPropButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[getPropAtom] }; GetPropOp: TEditInput.CommandProc = { GetPropCom[EditToolPrivate.mainToolInfo]; }; GetPropCom: PROC [info: EditToolPrivate.Info] = { pSel: TEditDocument.Selection; root: TextNode.Ref; name: ROPE; key: ATOM; valueRope: ROPE; haveFirst: BOOLEAN ¬ FALSE; SaveOrCheck: PROC [value: REF] ~ { vrope: ROPE ¬ NodeProps.GetSpecs[key, value]; IF haveFirst THEN { IF NOT Rope.Equal[valueRope, vrope] THEN { MessageWindow.Append[IF info.propNode = forSelectedChars THEN "Characters" ELSE "Nodes", TRUE]; MessageWindow.Append[" don't have uniform property values. Using first.", FALSE]; MessageWindow.Blink[]; SIGNAL NotUniform; }; } ELSE { valueRope ¬ vrope; haveFirst ¬ TRUE; }; }; Get: PROC [node: TextNode.Ref, start, size: INT] = { IF info.propNode = forSelectedChars THEN { IF node.charProps#NIL THEN FOR i: INT IN [start..start+size) DO SaveOrCheck[TextEdit.GetCharProp[node, i, key]]; ENDLOOP; } ELSE SaveOrCheck[TextEdit.GetProp[node, key]]; }; name ¬ GetNameArg[info.propNameArg ! BadArg => GOTO Bad]; key ¬ Atom.MakeAtom[name]; TEditSelection.LockSel[primary, "GetPropCom"]; pSel ¬ TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] THEN { TEditSelection.UnlockSel[primary]; RETURN; }; root ¬ TEditSelection.SelectionRoot[pSel]; [] ¬ TEditLocks.Lock[root, "GetPropCom", read]; ForEachNode[info.propNode, pSel, Get ! NotUniform => CONTINUE]; TEditSelection.UnlockDocAndPSel[root]; TEditOps.SetTextContents[info.propValueArg, valueRope]; EXITS Bad => RETURN }; setPropAtom: LIST OF REF = EditToolPrivate.Register[$SetNodeProp, SetPropOp]; SetPropButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[setPropAtom] }; SetPropOp: TEditInput.CommandProc = { SetPropCom[EditToolPrivate.mainToolInfo]; }; SetPropCom: PROC [info: EditToolPrivate.Info] = { pSel: TEditDocument.Selection; name, valueRope: ROPE; key: ATOM; root: TextNode.Ref; Put: PROC [node: TextNode.Ref, start, size: INT] = { value: REF ~ NodeProps.DoSpecs[key, valueRope]; IF info.propNode = forSelectedChars THEN TextEdit.PutCharProp[node: node, index: start, name: key, value: value, nChars: size, event: TEditInput.CurrentEvent[], root: root] ELSE { IF NodeProps.Is[key, $ClientOnly] THEN { MessageWindow.Append["Can't change ", TRUE]; MessageWindow.Append[Atom.GetPName[key], FALSE]; MessageWindow.Append[" node property with the EditTool.", FALSE]; IF key = $CharProps THEN { MessageWindow.Append[" Set character properties with \"For selected characters\" option.", FALSE]; }; MessageWindow.Blink[]; } ELSE {TextEdit.PutProp[node, key, value, TEditInput.CurrentEvent[]]} }; }; name ¬ GetNameArg[info.propNameArg ! BadArg => GOTO Bad]; valueRope ¬ GetRopeArg[info.propValueArg ! BadArg => GOTO Bad]; key ¬ Atom.MakeAtom[name]; TEditSelection.LockSel[primary, "SetPropCom"]; pSel ¬ TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] OR NOT TEditInputOps.CheckReadonly[pSel] THEN { TEditSelection.UnlockSel[primary]; RETURN; }; root ¬ TEditSelection.SelectionRoot[pSel]; [] ¬ TEditLocks.Lock[root, "SetPropCom"]; ForEachNode[info.propNode, pSel, Put ! RuntimeError.UNCAUGHT => { MessageWindow.Append["Uncaught error in EditToolMiscImpl.SetPropCom", TRUE]; MessageWindow.Blink[]; CONTINUE; }; ]; TEditSelection.UnlockDocAndPSel[root]; EXITS Bad => RETURN }; removePropAtom: LIST OF REF = EditToolPrivate.Register[$RemoveNodeProp, RemovePropOp]; RemovePropButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[removePropAtom] }; RemovePropOp: TEditInput.CommandProc = { RemovePropCom[EditToolPrivate.mainToolInfo]; }; RemovePropCom: PROC [info: EditToolPrivate.Info] = { pSel: TEditDocument.Selection; root: TextNode.Ref; key: ATOM; Rem: PROC [node: TextNode.Ref, start, size: INT] = { IF info.propNode = forSelectedChars THEN TextEdit.PutCharProp[node: node, index: start, name: key, value: NIL, nChars: size, event: TEditInput.CurrentEvent[], root: root] ELSE TextEdit.PutProp[node, key, NIL, TEditInput.CurrentEvent[]] }; key ¬ Atom.MakeAtom[GetNameArg[info.propNameArg ! BadArg => GOTO Bad]]; TEditSelection.LockSel[primary, "RemovePropCom"]; pSel ¬ TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] OR NOT TEditInputOps.CheckReadonly[pSel] THEN { TEditSelection.UnlockSel[primary]; RETURN; }; root ¬ TEditSelection.SelectionRoot[pSel]; [] ¬ TEditLocks.Lock[root, "RemovePropCom"]; ForEachNode[info.propNode, pSel, Rem]; TEditSelection.UnlockDocAndPSel[root]; EXITS Bad => RETURN }; listPropsAtom: LIST OF REF = EditToolPrivate.Register[$ListNodeProps, ListPropsOp]; ListPropsButton: Buttons.ButtonProc = { EditToolPrivate.DoButton[listPropsAtom] }; ListPropsOp: TEditInput.CommandProc = { ListPropsCom[EditToolPrivate.mainToolInfo]; }; ListPropsCom: PROC [info: EditToolPrivate.Info] = { pSel: TEditDocument.Selection; valueRope: ROPE; root: TextNode.Ref; list: LIST OF ATOM ¬ NIL; listProp: PROC [name: ATOM, value: REF] RETURNS[BOOLEAN] = { IF value#NIL THEN {list ¬ CONS[name, list]}; RETURN [FALSE]; }; List: PROC[node: TextNode.Ref, start, size: INT] = { IF info.propNode = forSelectedChars THEN { IF node.charProps#NIL THEN FOR i: INT IN [start..start+size) DO FOR p: TextEdit.PropList ¬ TextEdit.GetCharPropList[node, i], p.rest UNTIL p=NIL DO [] ¬ listProp[NARROW[p.first.key], p.first.val]; ENDLOOP; ENDLOOP; } ELSE [] ¬ NodeProps.MapProps[node, listProp]; }; TEditSelection.LockSel[primary, "ListPropsCom"]; pSel ¬ TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] THEN { TEditSelection.UnlockSel[primary]; RETURN; }; root ¬ TEditSelection.SelectionRoot[pSel]; [] ¬ TEditLocks.Lock[root, "ListPropsCom", read]; ForEachNode[info.propNode, pSel, List]; TEditSelection.UnlockDocAndPSel[root]; FOR lst: LIST OF ATOM ¬ list, lst.rest UNTIL lst=NIL DO valueRope ¬ Rope.Concat[valueRope, Atom.GetPName[lst.first]]; IF lst.rest # NIL THEN valueRope ¬ Rope.Concat[valueRope, " "]; ENDLOOP; TEditOps.SetTextContents[info.propNameArg, valueRope] }; FindPropButton: Buttons.ButtonProc = { }; END. ’ EditToolMiscImpl.mesa Copyright Ó 1982, 1983, 1984, 1985, 1986, 1991, 1992 by Xerox Corporation. All rights reserved. Michael Plass, May 9, 1986 1:54:42 pm PDT Rick Beach, May 28, 1985 1:54:05 pm PDT Russ Atkinson (RRA) June 18, 1985 4:58:04 pm PDT Alison Lee June 11, 1986 10:32:02 pm PDT Swinehart, November 14, 1986 10:01:06 am PST Doug Wyatt, March 14, 1992 5:55 pm PST BuildPropertyButtons BuildStyleButtons BuildFormatButtons GetNameArg StyleNameArg FormatNameArg GetStyleName SetStyleName ClearFormat LoadStyle LoadAbbreviations Format/Style name ranges PropName PropValue PropPatternArg PropNode GetProp SetProp RemoveProp ListProps FindProp findPropAtom: LIST OF REF = EditToolPrivate.Register[$FindNodeProp, FindPropOp]; findBackPropAtom: LIST OF REF = EditToolPrivate.Register[$BackFindNodeProp, FindBackPropOp]; EditToolPrivate.DoButton[findPropAtom, findBackPropAtom, mouseButton=red] FindPropOp: TEditInput.CommandProc = { FindPropCom[EditToolPrivate.mainToolInfo, TRUE]; }; FindBackPropOp: TEditInput.CommandProc = { FindPropCom[EditToolPrivate.mainToolInfo, FALSE]; }; FindPropCom: PROC [info: EditToolPrivate.Info, forward: BOOLEAN] = { pSel: TEditDocument.Selection; root: TextNode.Ref ¬ NIL; node: TextNode.Ref; { startNode: TextNode.Ref; startCharFound: INT ¬ 0; endCharFound: INT ¬ 0; pattern: ROPE; tester: TextNode.RefTextNode ¬ TextNode.NewTextNode[]; name: ATOM; -- property name we're looking for finder: TreeFind.Finder; -- pattern for property value Step: PROC [n: TextNode.Ref] RETURNS [TextNode.Ref] = { RETURN [IF forward THEN TextNode.StepForward[n] ELSE TextNode.StepBackward[n]] }; name ¬ Atom.MakeAtom[GetNameArg[info.propNameArg ! BadArg => GOTO Bad]]; pattern ¬ TextEdit.GetRope[EditToolBuilder.GetDataNode[info.propPatternArg]]; IF Rope.Size[pattern] # 0 THEN -- create a finder for the pattern finder ¬ TreeFind.CreateFromRope[pattern ! TextFind.MalformedPattern => { ReportPatternError[ec]; GOTO Bad }]; TEditSelection.LockSel[primary, "FindPropCom"]; pSel ¬ TEditOps.GetSelData[]; IF NOT EditToolPrivate.CheckPSel[pSel] THEN { MessageWindow.Append["Select node.", TRUE]; MessageWindow.Blink[]; TEditSelection.UnlockSel[primary]; RETURN; }; root ¬ TEditSelection.SelectionRoot[pSel]; [] ¬ TEditLocks.Lock[root, "FindPropCom", read]; node ¬ NIL; -- start for search startNode ¬ IF forward THEN pSel.end.pos.node ELSE pSel.start.pos.node; IF finder#NIL THEN FOR n: TextNode.Ref ¬ startNode, Step[n] UNTIL n = NIL DO IF info.propNode = forSelectedChars THEN { selectionPoint: TEditDocument.SelectionPoint ~ IF forward THEN pSel.end ELSE pSel.start; SearchCharProps: PROC RETURNS [found: BOOLEAN ¬ FALSE] ~ { prev: REF ¬ NIL; foundRope: ROPE ¬ NIL; CharAction: PROC [i: INT] ~ { value: REF ¬ TextEdit.GetCharProp[n, i, name]; IF value # prev AND value # NIL THEN { tester.rope ¬ NodeProps.GetSpecs[name, value]; IF TextFind.Try[finder, tester].found THEN { startCharFound ¬ i; endCharFound ¬ i+1; foundRope ¬ tester.rope; prev ¬ value; found ¬ TRUE; }; prev ¬ value; }; }; CheckChar: PROC [i: INT] RETURNS [stop: BOOLEAN] ~ { value: REF ¬ TextEdit.GetCharProp[n, i, name]; IF value # prev OR NOT Rope.Equal[foundRope, NodeProps.GetSpecs[name, value]] THEN RETURN [TRUE]; startCharFound ¬ MIN[startCharFound, i]; endCharFound ¬ MAX[endCharFound, i+1]; prev ¬ value; RETURN [FALSE]; }; IF forward THEN { FOR i: INT IN [startChar..endChar) UNTIL found DO CharAction[i] ENDLOOP; IF found THEN FOR i: INT IN [endCharFound..endChar) UNTIL CheckChar[i].stop DO ENDLOOP; } ELSE { FOR i: INT DECREASING IN [startChar..endChar) UNTIL found DO CharAction[i] ENDLOOP; IF found THEN FOR i: INT DECREASING IN [startChar..startCharFound) UNTIL CheckChar[i].stop DO ENDLOOP; } }; startChar: INT ¬ 0; endChar: INT ¬ TextEdit.Size[n]; IF n = startNode AND selectionPoint.pos.where = TextNode.NodeItself THEN LOOP ELSE IF n = startNode THEN { IF forward THEN startChar ¬ MAX[MIN[selectionPoint.pos.where+1, endChar], startChar] ELSE endChar ¬ MIN[MAX[selectionPoint.pos.where, startChar], endChar] }; IF n.hascharprops AND SearchCharProps[].found THEN {node ¬ n; EXIT}; } ELSE IF n # startNode THEN { value: REF ¬ NodeProps.GetProp[n, name]; IF value # NIL THEN { -- see if matches pattern tester.rope ¬ NodeProps.GetSpecs[name, value]; IF TextFind.Try[finder, tester].found THEN {node ¬ n; EXIT}; }; }; ENDLOOP; IF node=NIL OR TextNode.Parent[node]=NIL THEN { MessageWindow.Append["Failed to find property matching given pattern.", TRUE]; MessageWindow.Blink[]; TEditSelection.UnlockDocAndPSel[root]; RETURN; }; IF info.propNode = forSelectedChars THEN { EditToolPrivate.tSel.start.pos ¬ [node, startCharFound]; EditToolPrivate.tSel.end.pos ¬ [node, endCharFound-1]; EditToolPrivate.tSel.granularity ¬ char; } ELSE { EditToolPrivate.tSel.start.pos ¬ [node, 0]; EditToolPrivate.tSel.end.pos ¬ [node, MAX[TextEdit.Size[node], 1]-1]; EditToolPrivate.tSel.granularity ¬ node; }; EditToolPrivate.tSel.viewer ¬ pSel.viewer; EditToolPrivate.tSel.data ¬ pSel.data; EditToolPrivate.tSel.insertion ¬ after; TEditSelection.MakeSelection[new: EditToolPrivate.tSel]; TEditInput.CloseEvent[]; TEditRefresh.ScrollToEndOfSel[EditToolPrivate.tSel.viewer, FALSE]; TEditSelection.UnlockDocAndPSel[root]; GetPropCom[info]; EXITS Bad => { RETURN; } } }; ReportPatternError: PUBLIC PROC [ec: TextFind.PatternErrorCode] = { msg: ROPE = SELECT ec FROM toobig => "Pattern too long", endquote => "Pattern ends with quote (')", endtilda => "Pattern ends with tilde (~)", boundary => "Pattern has | inside rather than at beginning or end", missingNameEnd => "Pattern has < without matching >", unmatchedNameEnd => "Pattern has > without previous <", ENDCASE => "Pattern error (consult CedarSupport^)"; MessageWindow.Append[msg, TRUE]; MessageWindow.Blink[] }; Ê ç–(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ ÏeœU™`Kšœ)™)K™'K™0K™(K™,Kšœ&™&K™—šÏk ˜ Kšœžœ˜!Kšœžœ˜Kšœžœ˜'Kšœžœx˜Kšœ˜Kšœžœ˜Kšœžœ˜%Kšœ ˜ Kšœ žœ˜'Kšœžœ ˜Kšœžœžœ ˜*Kšœ žœžœ˜Kšœžœ˜1Kšœ žœ˜.KšœžœS˜fKšœ žœ ˜Kšœ žœ ˜.Kšœžœ>˜RKšœ ˜ Kšœ žœ'˜5Kšœžœ ˜Kšœ žœ4˜C—headšœžœž˜KšžœÝ˜äKšžœ˜Kšœž˜K˜Kšžœžœžœ˜K˜—šœ™šÏnœžœžœ$˜IK˜pK˜"K˜sK˜"Kšœ!˜!KšœR˜RKšœR˜RKšœX˜XKšœV˜VK˜$K˜&Kšœ!˜!Kšœ+˜+Kšœ7˜7KšœRžœZ˜¯K˜$KšœT˜TK˜"Kšœy˜yK˜—K˜šŸœžœžœ$˜EK˜uK˜"K˜xK˜"Kšœ!˜!K˜JK˜JK˜PK˜MK˜&Kšœ#˜#Kšœ-˜-Kšœ6˜6KšœRžœZ˜¯K˜$K˜LK˜"K˜{K˜K˜——šœ™šŸœžœžœ$˜FK˜tK˜"Kšœ˜Kšœ\˜\Kšœ\˜\Kšœ`˜`K˜$K˜&Kšœ1˜1Kšœ'˜'Kšœ¨˜¨K˜$K˜\K˜bK˜—šŸœžœžœ$˜BK˜tK˜"Kšœ˜K˜OK˜OK˜SK˜&Kšœ.˜.Kšœ$˜$Kšœ¨˜¨K˜$K˜\K˜bK˜——šœ™šŸœžœžœ$˜CK˜wK˜"Kšœ#˜#K˜PK˜PK˜TK˜&Kšœ/˜/Kšœ%˜%Kšœ®˜®K˜—šŸœžœžœ$˜GK˜wK˜"Kšœ#˜#Kšœ^˜^Kšœ^˜^Kšœb˜bK˜$K˜&Kšœ3˜3Kšœ)˜)Kšœ®˜®K˜——šœ ™ KšŸœžœžœžœ˜K˜š Ÿ œžœžœžœžœ˜FKšœ6˜6Kšœžœ˜ Kšœ žœ˜šžœžœžœ ž˜Kšžœžœ-žœžœ˜LKšžœ˜—šžœžœžœž˜Kšžœžœ4žœ žœ˜QKšžœ˜—šžœžœžœ ž˜Kšžœžœ-žœžœ˜AKšžœ˜—Kš žœ žœžœ+žœžœ˜Qšžœ ˜KšœVžœ˜\K˜Kšžœ˜ K˜—K˜K™—š Ÿ œžœžœžœžœ˜FKšœ6˜6Kšœžœ˜ šžœžœžœ ž˜Kšžœžœ)žœžœ˜=Kšžœ˜—Kšžœ ˜šžœ ˜KšœIžœ˜OK˜Kšžœ˜ K˜—K˜K™—š Ÿ œžœKžœžœžœ˜‘šžœ ž˜Kšœ:˜:šœ'˜'šžœFž˜KKšœžœ˜Kšœžœ˜šžœžœ,žœ˜SKšœ˜Kšœ˜—šžœžœ*žœ˜OKšœžœ˜%Kšœ˜—Kšœ0˜0Kšžœžœžœ˜&Kšžœ˜—Kšœ˜—Kšžœžœ˜—K˜—K˜šŸ œžœ$žœ žœ$˜mšŸœžœžœžœ˜9Kšžœžœ'˜4Kšžœ)˜-K˜—Kšœ žœžœžœ˜JK˜—K˜—šœ ™ Kšœžœžœžœ8˜UKšœžœžœžœB˜dK˜šŸœ˜*K˜SK˜—K˜šŸœ˜*KšœKžœ˜RK˜K˜—šŸœ˜/KšœKžœ˜QK˜—K˜—šœ ™ Kšœžœžœžœ:˜XKšœžœžœžœ8˜TKšœžœžœžœD˜gKšœžœžœžœB˜cK˜šŸœ˜+K˜UK˜—K˜šŸœ˜+KšœLžœ˜SK˜K˜—šŸœ˜0KšœLžœ˜RK˜—K˜—šœ ™ Kšœžœžœžœ?˜\K˜šŸœ˜*K˜+K˜—K˜šŸœ˜*Kšœ.˜.Kšœ˜K˜—šŸœžœ!˜6Kšœžœ˜Kšœ˜—K˜KšœžœžœžœA˜_Kšœžœžœžœ?˜[K˜šŸœ˜+K˜,K˜—K˜šŸœ˜+Kšœ/˜/Kšœ˜K˜—šŸœžœ!˜7Kšœžœ˜Kšœ˜—K˜šŸ œžœžœ˜K˜—šŸ œžœ%žœ˜DK˜6Kšœ%žœžœžœ˜WKšœžœžœ˜Kšœžœžœžœ˜TšŸœžœ#žœ˜4šœžœžœžœ$˜;Kšžœ˜—šžœžœžœ ˜šžœžœ žœ˜Kš œžœžœ1žœ3žœ˜—K˜Kšžœ ˜K˜—K˜—Kšžœžœ!žœžœ˜3Kšœ0žœ˜:Kš œžœžœžœžœžœ˜MK˜—K˜—šœ ™ Kšœžœžœžœ?˜\K˜šŸœ˜*K˜+K˜—K˜šŸœ˜*Kšœ.˜.Kšœ˜K˜—šŸœžœ!˜6Kšœžœ˜Kšœ˜—K˜KšœžœžœžœA˜_Kšœžœžœžœ?˜[K˜šŸœ˜+K˜,K˜—K˜šŸœ˜+Kšœ/˜/Kšœ˜K˜—šŸœžœ!˜7Kšœžœ˜Kšœ˜K˜—šŸ œžœ%žœ˜AK˜Kšœžœžœžœ˜TKšœžœžœ˜2K˜.K˜š žœžœ!žœžœ#žœ˜VKšœ"˜"Kšžœ˜K˜—K˜%K˜"Kšžœžœ˜K˜—K˜—šœ ™ KšœžœžœžœE˜eKšœžœžœžœC˜aK˜šŸœ˜-K˜.K˜—K˜šŸœ˜-Kšœ1˜1Kšœ˜K˜—šŸœžœ!˜9K˜6Kšžœžœ!žœžœ˜3Kšžœžœ#žœžœ˜5Kšœžœžœ˜$K˜—K˜KšœžœžœžœC˜bK˜šŸœ˜,K˜-K˜—K˜šŸœ˜,Kšœ0˜0Kšœ˜K˜—šŸœžœ!˜8K˜6Kšžœžœ!žœžœ˜3Kšžœžœ#žœžœ˜5Kšœžœžœ˜#K˜—K˜—šœ ™ Kšœžœžœžœ?˜YK˜šŸœ˜'K˜(K˜—K˜šŸ œ˜'Kšœ(˜(Kšœ˜K˜—šŸ œžœ"˜1š Ÿœžœžœžœžœ˜Ašžœž˜Kšœ žœžœ!˜FK˜6Kšžœ˜—Kšžœžœ˜K˜—Kšœžœ,žœ˜@K˜$K˜$Kšžœžœ˜K˜—K˜—šœ™KšœžœžœžœE˜gK˜šŸœ˜/K˜0K˜—K˜šŸœ˜/Kšœ0˜0Kšœ˜K˜—šŸœžœ"˜9Kšœžœ,žœ˜@K˜&Kšžœžœ˜K˜—K˜—šœ™Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜ KšœžœžœžœB˜aKšœžœžœžœ@˜]KšœžœžœžœL˜jKšœžœžœžœJ˜fK˜šŸœ˜,K˜}K˜—K˜šŸœ˜,Kšœ-˜-Kšœ˜K˜—šŸœžœ$˜8Kšœ˜Kšœ5˜5K˜—K˜šŸœ˜1Kšœ2˜2Kšœ˜K˜—šŸœžœ$˜=Kšœ#˜#Kšœ:˜:K˜—K˜Kšœžœžœžœ@˜^KšœžœžœžœJ˜gK˜šŸœ˜+K˜zK˜—K˜šŸœ˜+Kšœ,˜,Kšœ˜K˜—šŸ œžœ$˜7Kšœ˜Kšœ3˜3K˜—K˜šŸœ˜0Kšœ1˜1Kšœ˜K˜—šŸœžœ$˜šžœ"žœ™*Kšœ/žœ žœ žœ ™Xš Ÿœžœžœ žœžœ™:Kšœžœžœ™Kšœ žœžœ™šŸ œžœžœ™Kšœžœ$™.šžœžœ žœžœ™&Kšœ.™.šžœ$žœ™,Kšœ™Kšœ™Kšœ™Kšœ ™ Kšœžœ™ Kšœ™—Kšœ ™ Kšœ™—Kšœ™—š Ÿ œžœžœžœžœ™4Kšœžœ$™.Kš žœžœžœ8žœžœžœ™aKšœžœ™(Kšœžœ™&Kšœ ™ Kšžœžœ™Kšœ™—šžœ žœ™Kš žœžœžœžœžœ žœ™HKšžœžœžœžœžœžœžœžœ™WKšœ™—šžœ™Kšžœžœž œžœžœžœ žœ™SKšžœžœžœžœž œžœžœž œ™fKšœ™—Kšœ™—Kšœ žœ™Kšœ žœ™ Kšžœžœ0žœž™Mšžœžœžœ™Kšžœ žœ žœžœ1™TKšžœ žœžœ/™EKšœ™—Kšžœžœžœ žœ™DKšœ™—šžœžœžœ™Kšœžœ™(šžœ žœžœ ™/Kšœ.™.Kšžœ$žœ žœ™