DIRECTORY TrcEdit, Convert USING [RealFromRope], Draw2d USING [Line], Imager USING [black, Color, --MaskVector,-- SetColor, SetStrokeWidth, white], ImagerBackdoor USING [GetReal], IO USING [GetCedarTokenRope, PutF, PutRope, TokenKind], Real USING [CompareREAL], RedBlackTree, --using lots... Rope USING [Equal, Fetch, ROPE], TIPUser USING [InstantiateNewTIPTable, TIPScreenCoords], Trc, TrcTool USING [NewSelectableTrc, SelectNewTrc], TrcViewers USING [VecFromTIPCoords], Vector2 USING [InlineAdd, Length, Sub, VEC], ViewerClasses USING [Viewer, ViewerRec], ViewerOps USING [PaintViewer]; TrcEditImpl: CEDAR PROGRAM IMPORTS Convert, Draw2d, Imager, ImagerBackdoor, IO, Real, RedBlackTree, Rope, TIPUser, Trc, TrcTool, TrcViewers, Vector2, ViewerOps EXPORTS TrcEdit ~ BEGIN OPEN TrcEdit; ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector2.VEC; margin: NAT ~ 10; EditInstance: TYPE ~ REF EditInstanceRep; EditInstanceRep: TYPE ~ RECORD [ trc: Trc.TRC _ TrcTool.NewSelectableTrc[], listener: REF _ NIL, pins: RedBlackTree.Table _ RedBlackTree.Create[getKey: TrcEditGet, compare: TrcEditCompare], joinPin: BOOL _ FALSE, selected: REAL, --When action~select, this contains x-value of selected pin toAdjust: VEC, action: EditAction _ none ]; EditAction: TYPE ~ {none, abort, insert, delete, select}; MarkRequest: TYPE ~ RECORD [vec: VEC, color: Imager.Color _ Imager.black]; Pin: TYPE ~ REF PinRep; PinRep: TYPE ~ RECORD [ vec: Vector2.VEC ]; EditControlData: TYPE ~ REF EditControlDataRep; EditControlDataRep: TYPE ~ RECORD [ container, childControl: ViewerClasses.Viewer _ NIL, trc: Trc.TRC _ NIL, y: INTEGER ]; NewEditTrc: PUBLIC PROC [underlying: Trc.TRC] RETURNS [trc: Trc.TRC] ~ { instance: EditInstance _ NEW[EditInstanceRep]; trc _ NEW[Trc.TRCRep _ [class: editClass, instance: instance]]; instance.listener _ Trc.InstallListener[trc: instance.trc, listener: [EditListener, trc]]; }; NewUnderlyingTrc: PUBLIC PROC [edit, new: Trc.TRC, notify: BOOL _ TRUE] ~ { instance: EditInstance ~ NARROW[edit.instance]; Trc.DeinstallListener[registration: instance.listener]; instance.trc _ new; instance.listener _ Trc.InstallListener[trc: new, listener: [EditListener, edit]]; IF notify THEN Trc.NotifyListeners[trc: edit]; }; GetUnderlyingTrc: PUBLIC PROC [edit: Trc.TRC] RETURNS [underlying: Trc.TRC] ~ { instance: EditInstance ~ NARROW[edit.instance]; RETURN [instance.trc]; }; EditFcn: Trc.Fcn = { VecFromRef: PROC [ref: REF] RETURNS [vec: VEC] ~ { WITH ref SELECT FROM p: Pin => RETURN [p^]; --This will return NIL as well real: REF REAL => RETURN [[x: real^, y: Trc.ApplyFcn[instance.trc, real^]]]; ENDCASE => ERROR; }; Join: PROC [ref: REF] RETURNS [join: BOOL] ~ INLINE { RETURN [ref=NIL OR ISTYPE[ref, REF REAL]] }; instance: EditInstance ~ NARROW[trc.instance]; left, equal, right: REF; [left, equal, right] _ RedBlackTree.Lookup3[self: instance.pins, lookupKey: RealToRef[a]]; SELECT TRUE FROM equal#NIL => RETURN [VecFromRef[equal].y]; Join[left] AND Join[right] => RETURN [Trc.ApplyFcn[instance.trc, a]]; --This covers the case that we're between two join pins, or that we're outside the extreme pin and it's a join pin, or that there are no pins at all. left=NIL => RETURN [NARROW[right, Pin].y]; --Note that left=NIL => ~Join[right] (see previous check) => right#NIL AND ~ISTYPE[right, REF REAL] => ISTYPE[right, Pin] right=NIL => RETURN [NARROW[left, Pin].y] --Note that right=NIL => ~Join[left] (see previous check) => left#NIL AND ~ISTYPE[left, REF REAL] => ISTYPE[left, Pin] ENDCASE => { --We're between two pins, at least one of which is a fixed Pin. vLeft: VEC ~ VecFromRef[left]; vRight: VEC ~ VecFromRef[right]; alpha: REAL ~ (a-vLeft.x)/(vRight.x-vLeft.x); RETURN [alpha*(vRight.y) + (1.0-alpha)*(vLeft.y)] }; }; EditNotify: Trc.NotifyProc = { instance: EditInstance ~ NARROW[trc.instance]; vec: Vector2.VEC; markRequests: LIST OF MarkRequest _ NIL; FOR each: LIST OF REF ANY _ input, each.rest UNTIL each=NIL DO WITH each.first SELECT FROM coords: TIPUser.TIPScreenCoords => { vec _ TrcViewers.VecFromTIPCoords[viewer: viewer, coords: coords]; }; token: ATOM => SELECT token FROM $Commit => { IF instance.action=select THEN [] _ RedBlackTree.Delete[self: instance.pins, deleteKey: RealToRef[instance.selected]]; --select same as insert except for this... SELECT instance.action FROM delete => [] _ RedBlackTree.Delete[self: instance.pins, deleteKey: RealToRef[instance.toAdjust.x]]; insert, select => RedBlackTree.Insert[self: instance.pins, dataToInsert: IF instance.joinPin THEN NEW[REAL _ instance.toAdjust.x] ELSE NEW[PinRep _ [instance.toAdjust]], insertKey: RealToRef[instance.toAdjust.x]]; ENDCASE; instance.action _ none; instance.joinPin _ FALSE; Trc.NotifyListeners[trc: trc, fork: TRUE]; }; $Abort => instance.action _ abort; $JoinPin => instance.joinPin _ TRUE; $Insert => { UNTIL RedBlackTree.Lookup[self: instance.pins, lookupKey: RealToRef[vec.x]]=NIL DO vec.x _ LOOPHOLE[SUCC[LOOPHOLE[vec.x, INT]], REAL]; ENDLOOP; instance.action _ insert; IF instance.joinPin THEN vec.y _ Trc.ApplyFcn[instance.trc, vec.x]; --If a joinPin, then set y-value to match underlying trc instance.toAdjust _ vec; markRequests _ LIST[[vec]]; }; $Select => { [instance.toAdjust, instance.joinPin] _ FindNearestPin[pins: instance.pins, loc: vec, trc: instance.trc ! NoPins => GOTO Abort]; instance.selected _ instance.toAdjust.x; instance.action _ select; markRequests _ LIST[[instance.toAdjust, Imager.white]]; EXITS Abort => instance.action _ abort; }; $Delete => { [instance.toAdjust, instance.joinPin] _ FindNearestPin[pins: instance.pins, loc: vec, trc: instance.trc ! NoPins => GOTO Abort]; instance.action _ delete; markRequests _ LIST[[instance.toAdjust, Imager.white]]; EXITS Abort => instance.action _ abort; }; $Adjust => SELECT instance.action FROM delete => { ViewerOps.PaintViewer[viewer: viewer, hint: client, clearClient: FALSE, whatChanged: NARROW[LIST[[instance.toAdjust]], LIST OF MarkRequest]]; --This clearing operation has to be specifically done, as we don't know that the repaint will be of the same shape, as the value of instance.joinPin may change [instance.toAdjust, instance.joinPin] _ FindNearestPin[pins: instance.pins, loc: vec, trc: instance.trc]; markRequests _ LIST[[instance.toAdjust, Imager.white]]; }; select => { XFromRef: PROC [ref: REF] RETURNS [x: REAL] ~ { WITH ref SELECT FROM p: Pin => RETURN [p^.x]; --This will return NIL as well real: REF REAL => RETURN [real^]; ENDCASE => ERROR; }; ref: REF ~ RedBlackTree.Lookup[self: instance.pins, lookupKey: RealToRef[vec.x]]; IF ref=NIL OR XFromRef[ref]=instance.selected THEN { --We'll pretend we didn't see it iff he's exactly vertically aligned with a different pin IF instance.joinPin THEN vec.y _ Trc.ApplyFcn[instance.trc, vec.x]; markRequests _ LIST[[instance.toAdjust, Imager.white], [vec]]; instance.toAdjust _ vec; }; }; insert => { IF RedBlackTree.Lookup[self: instance.pins, lookupKey: RealToRef[vec.x]]=NIL THEN { --Otherwise ignore IF instance.joinPin THEN vec.y _ Trc.ApplyFcn[instance.trc, vec.x]; markRequests _ LIST[[instance.toAdjust, Imager.white], [vec]]; instance.toAdjust _ vec; }; }; ENDCASE; ENDCASE; ENDCASE; ENDLOOP; IF markRequests#NIL THEN ViewerOps.PaintViewer[viewer: viewer, hint: client, clearClient: FALSE, whatChanged: markRequests]; }; EditBackground: Trc.BackgroundProc = { Mark: PROC [vec: VEC] ~ INLINE { Draw2d.Line[context: context, vec0: vec.InlineAdd[[-d,-d]], vec1: vec.InlineAdd[[d,d]]]; Draw2d.Line[context: context, vec0: vec.InlineAdd[[d,-d]], vec1: vec.InlineAdd[[-d,d]]]; }; MarkPlus: PROC [vec: VEC] ~ INLINE { Draw2d.Line[context: context, vec0: vec.InlineAdd[[-d,0]], vec1: vec.InlineAdd[[d,0]]]; Draw2d.Line[context: context, vec0: vec.InlineAdd[[0,-d]], vec1: vec.InlineAdd[[0,d]]]; }; instance: EditInstance ~ NARROW[trc.instance]; w: REAL ~ ImagerBackdoor.GetReal[context: context, key: strokeWidth]; d: REAL ~ 3*w; Imager.SetStrokeWidth[context: context, strokeWidth: 0.0]; IF whatChanged=NIL THEN { XMarksTheSpot: RedBlackTree.EachNode = { WITH data SELECT FROM pin: Pin => Mark[pin^]; real: REF REAL => MarkPlus[[x: real^, y: Trc.ApplyFcn[instance.trc, real^]]]; ENDCASE => ERROR; }; RedBlackTree.EnumerateIncreasing[self: instance.pins, procToApply: XMarksTheSpot]; } ELSE { WITH whatChanged SELECT FROM atom: ATOM => NULL; --Somebody has us layered markRequest: LIST OF MarkRequest => { FOR each: LIST OF MarkRequest _ markRequest, each.rest UNTIL each=NIL DO Imager.SetColor[context: context, color: each.first.color]; IF instance.joinPin THEN MarkPlus[each.first.vec] ELSE Mark[each.first.vec]; ENDLOOP; }; ENDCASE => ERROR; }; }; EditPickle: Trc.PickleProc = { instance: EditInstance ~ NARROW[trc.instance]; WriteEachPin: RedBlackTree.EachNode = { WITH data SELECT FROM pin: Pin => IO.PutF[stream: stream, format: "\n%g\t%g\t%g", v1: [rope[indentation]], v2: [real[pin.x]], v3: [real[pin.y]]]; real: REF REAL => IO.PutF[stream: stream, format: "\n%g\t%g\t*", v1: [rope[indentation]], v2: [real[real^]]] ENDCASE => ERROR; }; under: Trc.TRC ~ instance.trc; IO.PutRope[self: stream, r: " {"]; RedBlackTree.EnumerateIncreasing[self: instance.pins, procToApply: WriteEachPin]; Trc.PickleArbitraryTrc[trc: under, stream: stream, indentation: indentation]; IO.PutF[stream: stream, format: "\n%g}", v1: [rope[indentation]]]; }; EditDepickle: Trc.DepickleProc = { instance: EditInstance ~ NEW[EditInstanceRep]; token: ROPE; tokenKind: IO.TokenKind; trc _ NEW[Trc.TRCRep _ [class: class, instance: instance, listener: NIL]]; IF ~IO.GetCedarTokenRope[stream: stream].token.Equal["{"] THEN ERROR; [tokenKind: tokenKind, token: token] _ IO.GetCedarTokenRope[stream: stream]; WHILE tokenKind=tokenREAL DO x: REAL ~ Convert.RealFromRope[token]; [tokenKind: tokenKind, token: token] _ IO.GetCedarTokenRope[stream: stream]; SELECT tokenKind FROM tokenSINGLE => IF Rope.Fetch[token]='* THEN RedBlackTree.Insert[self: instance.pins, dataToInsert: NEW[REAL _ x], insertKey: RealToRef[x]]; tokenREAL => RedBlackTree.Insert[self: instance.pins, dataToInsert: NEW[PinRep _ [[x: x, y: Convert.RealFromRope[token]]]], insertKey: RealToRef[x]]; ENDCASE => ERROR; [tokenKind: tokenKind, token: token] _ IO.GetCedarTokenRope[stream: stream]; ENDLOOP; instance.trc _ Trc.DepickleArbitraryTrc[stream: stream]; IF instance.trc.class.flavor#$Selectable THEN { temp: Trc.TRC ~ instance.trc; instance.trc _ TrcTool.NewSelectableTrc[]; TrcTool.SelectNewTrc[trc: instance.trc, under: temp, paint: FALSE, notify: FALSE]; }; instance.listener _ Trc.InstallListener[trc: instance.trc, listener: [EditListener, trc]]; [tokenKind: tokenKind, token: token] _ IO.GetCedarTokenRope[stream: stream]; IF ~Rope.Equal[token, "}"] THEN ERROR; }; EditControl: Trc.BuildControlViewerProc = { instance: EditInstance; IF trc.instance=NIL THEN { --Need to instantiate viewer trc.instance _ instance _ NEW[EditInstanceRep]; instance.listener _ Trc.InstallListener[trc: instance.trc, listener: [EditListener, trc]] } ELSE instance _ NARROW[trc.instance]; viewer _ Trc.BuildControlViewer[trc: instance.trc, info: info, paint: paint]; instance.listener _ Trc.InstallListener[trc: instance.trc, listener: [EditListener, trc]]; }; EditCopy: Trc.CopyProc = { CopyEachPin: RedBlackTree.EachNode = { RedBlackTree.Insert[self: newInstance.pins, dataToInsert: data, insertKey: data]; }; instance: EditInstance ~ NARROW[trc.instance]; newInstance: EditInstance ~ NEW[EditInstanceRep]; new _ NEW[Trc.TRCRep _ [class: trc.class, instance: newInstance, listener: NIL]]; RedBlackTree.EnumerateIncreasing[self: instance.pins, procToApply: CopyEachPin]; newInstance.trc _ Trc.Copy[instance.trc]; newInstance.listener _ Trc.InstallListener[trc: newInstance.trc, listener: [EditListener, new]]; }; EditListener: Trc.ListenerProc = { Trc.NotifyListeners[trc: NARROW[listenerData]]; }; editClass: Trc.Class ~ NEW[Trc.ClassRep _ [ flavor: $Edit, fcn: EditFcn, blockFcn: Trc.DefaultBlockFcn, copy: EditCopy, pickle: EditPickle, depickle: EditDepickle, notify: EditNotify, tipTable: TIPUser.InstantiateNewTIPTable[file: "TrcEdit.tip"], background: EditBackground, control: EditControl, classData: NIL ]]; RealToRef: PROC [real: REAL] RETURNS [ref: REF] ~ INLINE { RETURN [NEW[REAL _ real]]; }; RefToReal: PROC [ref: REF] RETURNS [real: REAL] ~ INLINE { WITH ref SELECT FROM refReal: REF REAL => RETURN [refReal^]; pin: Pin => RETURN [pin.x] ENDCASE => ERROR; }; TrcEditGet: RedBlackTree.GetKey = { RETURN [data]; }; TrcEditCompare: RedBlackTree.Compare = { RETURN [Real.CompareREAL[RefToReal[data], RefToReal[k]]]; }; NoPins: SIGNAL ~ CODE; FindNearestPin: PROC [pins: RedBlackTree.Table, loc: VEC, trc: Trc.TRC] RETURNS [closest: VEC, joinPin: BOOL] ~ { PinFromRef: PROC [ref: REF] RETURNS [pin: Pin] ~ { IF ref=NIL THEN RETURN [NIL]; WITH ref SELECT FROM p: Pin => RETURN [p]; --This will return NIL as well real: REF REAL => RETURN [NEW[PinRep _ [[x: real^, y: Trc.ApplyFcn[trc, real^]]]]]; ENDCASE => ERROR; }; left, equal, right: REF; [left, equal, right] _ RedBlackTree.Lookup3[self: pins, lookupKey: RealToRef[loc.x]]; IF equal=NIL THEN { pin1: Pin ~ PinFromRef[left]; pin2: Pin ~ PinFromRef[right]; pickLeft: BOOL ~ SELECT TRUE FROM pin1=NIL AND pin2=NIL => ERROR NoPins[], pin1=NIL => FALSE, pin2=NIL => TRUE, ENDCASE => pin1^.Sub[loc].Length[] < pin2^.Sub[loc].Length[]; IF pickLeft THEN RETURN [pin1^, ISTYPE[left, REF REAL]] ELSE RETURN [pin2^, ISTYPE[right, REF REAL]]; } ELSE { pin1: Pin ~ PinFromRef[equal]; RETURN [pin1^, ISTYPE[equal, REF REAL]]; }; }; Trc.RegisterClass[editClass]; END. œTrcEditImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Eric Nickell, January 14, 1987 8:29:36 am PST [trc: TRC, a: REAL] RETURNS [b: REAL] Englishly, we're to the left of all the pins, the leftmost of which is a fixed Pin. Englishly, we're to the right of all the pins, the rightmost of which is a fixed Pin. [viewer: ViewerClasses.Viewer, trc: TRC, input: LIST OF REF ANY] This is an extreme kludge to get slightly off the pin, but to be as close as can be to it. markRequests _ LIST[[instance.toAdjust]]; [trc: TRC, context: Imager.Context, rectangle: ImagerTransformation.Rectangle, whatChanged: REF _ NIL] Imager.MaskVector[context: context, p1: vec.InlineAdd[[-d,-d]], p2: vec.InlineAdd[[d,d]]]; Imager.MaskVector[context: context, p1: vec.InlineAdd[[d,-d]], p2: vec.InlineAdd[[-d,d]]]; Imager.MaskVector[context: context, p1: vec.InlineAdd[[-d,0]], p2: vec.InlineAdd[[d,0]]]; Imager.MaskVector[context: context, p1: vec.InlineAdd[[0,-d]], p2: vec.InlineAdd[[0,d]]]; [data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE] [trc: TRC, stream: STREAM, indentation: ROPE _ NIL] [data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE] IO.PutF[stream: stream, format: "\n%g| %g", v1: [rope[indentation]], v2: [atom[under.class.flavor]]]; Trc.Pickle[trc: under, stream: stream, indentation: Rope.Concat[indentation, "\t"]]; [class: Trc.Class, stream: STREAM] RETURNS [trc: TRC] IF ~Rope.Equal[token, "|"] THEN ERROR; { --Depickle the underlying trc flavor: ATOM ~ IO.GetAtom[stream: stream]; class: Trc.Class ~ Trc.ClassFromFlavor[flavor: flavor]; instance.trc _ TrcTool.NewSelectableTrc[]; TrcTool.SelectNewTrc[trc: instance.trc, under: Trc.Depickle[class, stream], paint: FALSE, notify: FALSE]; instance.listener _ Trc.InstallListener[trc: instance.trc, listener: [EditListener, trc]]; }; [trc: TRC, info: ViewerClasses.ViewerRec, propList: Properties.PropList _ NIL] RETURNS [viewer: ViewerClasses.Viewer] [trc: TRC] RETURNS [new: TRC] [data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE] [trc: TRC, listenerData: REF ANY] [data: RedBlackTree.UserData] RETURNS [RedBlackTree.Key] [k: RedBlackTree.Key, data: RedBlackTree.UserData] RETURNS [Basics.Comparison] Κv˜™Icodešœ Οmœ1™šžœ žœž˜šœ$˜$K˜BKšœ˜—šœžœžœž˜ –"[trc: TRC, fork: BOOL _ FALSE]šœ ˜ K–;[self: RedBlackTree.Table, deleteKey: RedBlackTree.Key]šžœžœYŸ*˜‘šžœž˜K–;[self: RedBlackTree.Table, deleteKey: RedBlackTree.Key]˜cK–b[self: RedBlackTree.Table, dataToInsert: RedBlackTree.UserData, insertKey: RedBlackTree.Key]š œIžœžœžœžœžœžœK˜ΥKšžœ˜—K˜Kšœžœ˜Kšœ$žœ˜*Kšœ˜—K˜"Kšœžœ˜$šœ ˜ –;[self: RedBlackTree.Table, lookupKey: RedBlackTree.Key]šžœGžœž˜RK™ZKš œžœžœžœžœžœ˜3Kšžœ˜—Kšœ˜K˜Kšžœžœ-Ÿ8˜}Kšœ˜Kšœžœ˜Kšœ˜—šœ ˜ Kšœtžœ˜€K˜(Kšœ˜Kšœžœ$˜7Kšžœ"˜'Kšœ˜—šœ ˜ Kšœtžœ˜€Kšœ˜Kšœžœ$˜7Kšžœ"˜'Kšœ˜—šœ žœž˜&šœ ˜ K–w[viewer: ViewerClasses.Viewer, hint: ViewerOps.PaintHint, clearClient: BOOL _ TRUE, whatChanged: REF ANY _ NIL]šœžœ™)Kš œAžœžœžœžœžœŸŸ˜­Kšœi˜iKšœžœ$˜7Kšœ˜—šœ ˜ š ’œžœžœžœžœ˜/šžœžœž˜Kšœ žœ Ÿ£Ÿ˜8Kšœžœžœžœ ˜!Kšžœžœ˜—K˜—KšœžœI˜Qš žœžœžœ!žœŸLΠbc Ÿ˜ŽKšžœžœ+˜CKšœžœ+˜>Kšœ˜Kšœ˜—Kšœ˜—šœ ˜ šžœGžœžœŸ˜fKšžœžœ+˜CKšœžœ+˜>Kšœ˜Kšœ˜—Kšœ˜—Kšžœ˜—Kšžœ˜—Kšžœ˜—Kšžœ˜—K–w[viewer: ViewerClasses.Viewer, hint: ViewerOps.PaintHint, clearClient: BOOL _ TRUE, whatChanged: REF ANY _ NIL]šžœžœžœBžœ˜|K˜—šœ&˜&Kš£f™fš’œžœžœžœ˜ KšœZ™ZK–1[context: Imager.Context, p1: VEC, p2: VEC]šœZ™ZK–Z[context: Imager.Context, vec0: VEC, vec1: VEC, drawType: Draw2d.DrawType _ solid]šœX˜XK–Z[context: Imager.Context, vec0: VEC, vec1: VEC, drawType: Draw2d.DrawType _ solid]šœX˜XK˜—š’œžœžœžœ˜$KšœY™YK–1[context: Imager.Context, p1: VEC, p2: VEC]šœY™YK–Z[context: Imager.Context, vec0: VEC, vec1: VEC, drawType: Draw2d.DrawType _ solid]šœW˜WK–Z[context: Imager.Context, vec0: VEC, vec1: VEC, drawType: Draw2d.DrawType _ solid]šœW˜WK˜—Kšœžœ˜.K–:[context: Imager.Context, key: ImagerBackdoor.RealKey]šœžœ>˜EKšœžœ˜K–0[context: Imager.Context, strokeWidth: REAL]˜:šžœ žœžœ˜–> -- [data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE]˜(Kš£:™:šžœžœž˜K˜Kšœžœžœ?˜MKšžœžœ˜—K˜—K–B[self: RedBlackTree.Table, procToApply: RedBlackTree.EachNode]˜RKšœ˜—šžœ˜šžœ žœž˜KšœžœžœŸ˜.šœ žœžœ˜%š žœžœžœ&žœžœž˜HK–;[context: Imager.Context, color: ImagerColorDefs.Color]šœ;˜;Kšžœžœžœ˜LKšžœ˜—Kšœ˜—Kšžœžœ˜—Kšœ˜—K˜—–7 -- [trc: TRC, stream: STREAM, indentation: ROPE _ NIL]šœ˜Kš£3™3Kšœžœ˜.–> -- [data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE]˜'Kš£:™:šžœžœž˜Kšœ žœm˜{K–―[stream: STREAM, format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šœžœžœžœX˜lKšžœžœ˜—K˜—Kšœ žœ˜Kšžœ ˜"K–B[self: RedBlackTree.Table, procToApply: RedBlackTree.EachNode]˜QK–―[stream: STREAM, format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]˜MKšžœc™eKšœT™TK–―[stream: STREAM, format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šžœ@˜BK˜—–9 -- [class: Trc.Class, stream: STREAM] RETURNS [trc: TRC]šœ"˜"Kš£5™5Kšœžœ˜.Kšœžœ˜ Kšœ žœ ˜K–0[stream: STREAM, flushComments: BOOL _ TRUE]šœžœ;žœ˜JKšžœžœ4žœžœ˜EKšœ'žœ#˜Lšžœž˜K–[stream: STREAM]šœžœ˜&Kšœ'žœ#˜Lšžœ ž˜K– [base: ROPE, index: INT _ 0]š œžœžœ8žœžœ ˜‹KšœDžœN˜•Kšžœžœ˜—Kšœ'žœ#˜LKšžœ˜—K–-[s1: ROPE, s2: ROPE, case: BOOL _ TRUE]˜8šžœ&žœ˜/Kšœ žœ˜K˜*Kšœ<žœ žœ˜RKšœ˜—KšœZ˜ZKšžœžœžœ™&šœŸ™Kšœžœžœ™*K–[flavor: ATOM]™7K™*KšœSžœ žœ™iKšœZ™ZKšœ™—Kšœ'žœ#˜LK–-[s1: ROPE, s2: ROPE, case: BOOL _ TRUE]šžœžœžœ˜&K˜—–y -- [trc: TRC, info: ViewerClasses.ViewerRec, propList: Properties.PropList _ NIL] RETURNS [viewer: ViewerClasses.Viewer]˜+Kš£u™uK–³ -- [proc: ChoiceButtons.SelectionNotifierProc, permission: ChoiceButtons.EnumPermissionProc, namesOfButtons: ChoiceButtons.ButtonList _ NIL, nextx: CARDINAL, nexty: CARDINAL, type: ChoiceButtons.DisplayStyle, buttonOn: Buttons.Button _ NIL, flipLabel: ViewerClasses.Viewer _ NIL, clientdata: REF ANY _ NIL]šœ˜K˜šžœžœžœŸ˜7Kšœžœ˜/K–&[trc: TRC, listener: Trc.Listener]šœY˜YKšœ˜—Kšžœ žœ˜%K˜MKšœZ˜ZK˜—˜Kš£™–> -- [data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE]˜&Kš£:™:K–b[self: RedBlackTree.Table, dataToInsert: RedBlackTree.UserData, insertKey: RedBlackTree.Key]šœQ˜QK˜—Kšœžœ˜.Kšœžœ˜1KšœžœBžœ˜QK–B[self: RedBlackTree.Table, procToApply: RedBlackTree.EachNode]˜PK˜)K–&[trc: TRC, listener: Trc.Listener]šœ`˜`K˜—–% -- [trc: TRC, listenerData: REF ANY]šœ"˜"Kš£!™!K–"[trc: TRC, fork: BOOL _ FALSE]šœžœ˜/K˜—K˜šœžœ˜+Kšœ œ˜K˜ Kšœ˜K˜Kšœ˜Kšœ˜Kšœ˜K–[file: ROPE _ NIL]šœ  3œ˜>Kšœ˜Kšœ˜Kšœ ž˜K˜—š ’ œžœžœžœžœžœ˜:Kšžœžœžœ ˜K˜—š ’ œžœžœžœžœžœ˜:šžœžœž˜Kšœ žœžœžœ ˜'Kšœ žœ˜Kšžœžœ˜—K˜—šœ#˜#Kš£8™8Kšžœ˜K˜—–R -- [k: RedBlackTree.Key, data: RedBlackTree.UserData] RETURNS [Basics.Comparison]šœ(˜(Kš£N™NKšžœ3˜9K˜—Lšœžœžœ˜š’œžœ!žœ žœžœ žœ žœ˜qš’ œžœžœžœ˜2Kš žœžœžœžœžœ˜šžœžœž˜Kšœ žœŸ£Ÿ˜5Kš œžœžœžœžœ6˜SKšžœžœ˜—K˜—Kšœžœ˜K–;[self: RedBlackTree.Table, lookupKey: RedBlackTree.Key]šœU˜Ušžœžœžœ˜Kšœ˜Kšœ˜šœ žœžœžœž˜!Kš œžœžœžœžœ ˜(Kšœžœžœ˜Kšœžœžœ˜Kšžœ6˜=—Kšžœ žœžœ žœžœžœžœžœ žœžœžœ˜eKšœ˜—šžœ˜K˜Kšžœ žœžœžœ˜(Kšœ˜—K˜—K˜Kšœ˜K˜—K˜Kšžœ˜—…—4Ό[Ξ