DIRECTORY Atom, Basics, CD, CDBasics, CDCells, CDDirectory, CDOps, CDProperties, CDRects, CDSatellites, CDSequencer, CDSequencerExtras, Core, CoreClasses, CoreOps, CoreGeometry, CoreProperties, IO, RefTab, Rope, Sequence, Sinix, Sisyph, TerminalIO; SequenceImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDCells, CDDirectory, CDOps, CDProperties, CDRects, CDSatellites, CDSequencerExtras, CoreClasses, CoreOps, CoreGeometry, CoreProperties, IO, RefTab, Rope, Sinix, Sisyph, TerminalIO EXPORTS Sequence SHARES Sinix, Sisyph = BEGIN OPEN Sequence; ROPE: TYPE = Rope.ROPE; ROPES: TYPE = LIST OF ROPE; Wire: TYPE = Core.Wire; Wires: TYPE = Core.Wires; CellType: TYPE = Core.CellType; CellClass: TYPE = Core.CellClass; Properties: TYPE = Core.Properties; sequenceCellClass: PUBLIC Core.CellClass _ CoreOps.SetClassPrintProc[NEW [Core.CellClassRec _ [name: "Sequence", recast: RecastSequence, layersProps: FALSE]], PrintSequence]; exposeAtoms: ARRAY PublicWireType OF ATOM _ [$Sequence, $FlatSequence, $Common, $First, $Last]; PrintSequence: CoreOps.PrintClassProc = { EachOperation: RefTab.EachPairAction = { wire: Core.Wire _ NARROW[key]; operation: Operation _ NARROW[val]; IO.PutF[out, "%g", IO.rope[CoreOps.GetShortWireName[wire]]]; FOR exposition: PublicWireType IN PublicWireType DO IF operation.expose[exposition] THEN { IO.PutRope[out, " "]; IO.PutRope[out, Atom.GetPName[exposeAtoms[exposition]]]; }; ENDLOOP; IO.PutRope[out, "\n"]; }; cell: SequenceCellType _ NARROW [data]; IO.PutF[out, "\n\nBase cell type: %g", IO.rope[CoreOps.GetCellTypeName[cell.base]]]; IO.PutF[out, ", count: %g\n", IO.int[cell.count]]; FOR binds: WireBindings _ cell.bindings, binds.rest UNTIL binds=NIL DO IO.PutF[out, "this: %g, that: %g\n", IO.rope[CoreOps.GetShortWireName[binds.first.this]], IO.rope[CoreOps.GetShortWireName[binds.first.that]]]; ENDLOOP; [] _ RefTab.Pairs[cell.operations, EachOperation]; }; CreateSequence: PUBLIC PROC [base: Core.CellType, count: NAT, bindings: WireBindings _ NIL, operations: Operations _ NIL, name: Rope.ROPE _ NIL, props: Core.Properties _ NIL, decorateProc: DecorateProc _ NIL] RETURNS [cellType: Core.CellType] = { cellType _ CoreOps.CreateCellType[ class: sequenceCellClass, public: CoreOps.CreateWire[ComputeSequence[base, count, bindings, operations, decorateProc].publics], data: NEW[SequenceCellTypeRec _ [ base: base, count: count, bindings: bindings, operations: operations]], name: name, props: props]; }; RecastSequence: Core.RecastProc = { data: SequenceCellType _ NARROW[me.data]; publics: Core.Wires _ NIL; internals: Core.Wires _ NIL; instances: LIST OF CoreClasses.CellInstance _ NIL; [internals, instances, publics] _ ComputeSequence[data.base, data.count, data.bindings, data.operations]; new _ CoreClasses.CreateRecordCell[ public: CoreOps.CreateWire[publics], internal: CoreOps.CreateWire[internals], instances: instances, name: CoreOps.GetCellTypeName[me], props: NIL]; }; BindTables: TYPE = REF BindTablesRec; BindTablesRec: TYPE = RECORD[tables: SEQUENCE size: NAT OF RefTab.Ref]; ComputeSequence: PROC [base: Core.CellType, count: NAT, bindings: WireBindings _ NIL, operations: Operations _ NIL, decorateProc: DecorateProc _ NIL] RETURNS [internals: Core.Wires _ NIL, instances: LIST OF CoreClasses.CellInstance _ NIL, publics: LIST OF Core.Wire _ NIL] = { RootWire: PROC [wire: Core.Wire] RETURNS [root: Core.Wire] = { root _ NARROW [RefTab.Fetch[actualBind, wire].val]; IF root#wire THEN { root _ RootWire[root]; [] _ RefTab.Replace[actualBind, wire, root]; }; }; BindActual: PROC [replace, by: Core.Wire] = { IF replace.size#by.size THEN ERROR; -- binding mismatching wires [] _ RefTab.Replace[actualBind, RootWire[replace], RootWire[by]]; FOR i: NAT IN [0..replace.size) DO BindActual[replace[i], by[i]]; ENDLOOP; }; EachOperation: RefTab.EachPairAction = { FetchActual: PROC [cell: NAT, public: Core.Wire] RETURNS [actual: Core.Wire] = { actual _ NARROW[RefTab.Fetch[publicsToActuals[cell], public].val]; actual _ CoreOps.SetShortWireName[RootWire[actual], NIL]; }; basePublic: Core.Wire _ NARROW[key]; name: Rope.ROPE _ CoreOps.GetShortWireName[basePublic]; expose: ARRAY PublicWireType OF BOOL _ NARROW[val, Operation].expose; exposed: ARRAY PublicWireType OF Core.Wire _ ALL[NIL]; firstActual: Core.Wire _ RootWire[NARROW[RefTab.Fetch[publicsToActuals[0], basePublic].val]]; lastActual: Core.Wire _ RootWire[NARROW[RefTab.Fetch[publicsToActuals[count-1], basePublic].val]]; IF expose[sequence] THEN { sequenceWire: Core.Wire _ NEW[Core.WireRec[count]]; FOR cell: NAT IN [0..count) DO sequenceWire[cell] _ FetchActual[cell, basePublic]; ENDLOOP; publics _ CONS[sequenceWire, publics]; IF name#NIL THEN [] _ CoreOps.SetShortWireName[sequenceWire, Rope.Cat[name, Atom.GetPName[exposeAtoms[sequence]]]]; exposed[sequence] _ sequenceWire; }; IF expose[flatSequence] THEN { size: NAT _ basePublic.size; sequenceWire: Core.Wire _ NEW[Core.WireRec[size*count]]; FOR cell: NAT IN [0..count) DO FOR i: NAT IN [0..size) DO sequenceWire[(size*cell)+i] _ FetchActual[cell, basePublic[i]]; ENDLOOP; ENDLOOP; publics _ CONS[sequenceWire, publics]; IF name#NIL THEN [] _ CoreOps.SetShortWireName[sequenceWire, Rope.Cat[name, Atom.GetPName[exposeAtoms[flatSequence]]]]; exposed[flatSequence] _ sequenceWire; }; IF expose[last] THEN { IF NOT expose[first] OR firstActual#lastActual THEN publics _ CONS[lastActual, publics]; IF name#NIL THEN [] _ CoreOps.SetShortWireName[lastActual, Rope.Cat[name, Atom.GetPName[exposeAtoms[last]]]]; exposed[last] _ lastActual; }; IF expose[first] THEN { publics _ CONS[firstActual, publics]; IF name#NIL THEN [] _ CoreOps.SetShortWireName[firstActual, Rope.Cat[name, Atom.GetPName[exposeAtoms[first]]]]; exposed[first] _ firstActual; }; IF expose[common] THEN { IF NOT (expose[last] OR expose[first]) THEN publics _ CONS[firstActual, publics]; FOR cell: NAT IN [0..count) DO IF RootWire[NARROW[RefTab.Fetch[publicsToActuals[cell], basePublic].val]]#firstActual THEN ERROR; ENDLOOP; IF name#NIL THEN [] _ CoreOps.SetShortWireName[firstActual, name]; exposed[common] _ firstActual; }; IF decorateProc#NIL THEN decorateProc[basePublic, exposed]; }; publicsToActuals: BindTables _ NEW[BindTablesRec[count]]; actualBind: RefTab.Ref _ RefTab.Create[]; baseName: ROPE _ CoreOps.GetCellTypeName[base]; FOR cell: NAT DECREASING IN [0..count) DO InsertBinding: CoreOps.EachWirePairProc = { [] _ RefTab.Store[publicsToActuals[cell], publicWire, actualWire]; }; InitActual: CoreOps.EachWireProc = { [] _ RefTab.Insert[actualBind, wire, wire]; }; actual: Core.Wire _ CoreOps.CopyWireUsingTable[base.public, RefTab.Create[], FALSE]; internals _ CONS[actual, internals]; instances _ CONS [CoreClasses.CreateInstance[ actual: actual, type: base, name: IF baseName=NIL THEN NIL ELSE IO.PutFR["%g%g", IO.rope[baseName], IO.int[cell]]], instances]; publicsToActuals[cell] _ RefTab.Create[]; [] _ CoreOps.VisitBindingSeq[actual, base.public, InsertBinding]; [] _ CoreOps.VisitWire[actual, InitActual]; ENDLOOP; FOR cell: NAT IN [0..count-1) DO FOR wpl: WireBindings _ bindings, wpl.rest UNTIL wpl=NIL DO oldActual: Core.Wire _ NARROW[RefTab.Fetch[publicsToActuals[cell], wpl.first.that].val]; newActual: Core.Wire _ NARROW[RefTab.Fetch[publicsToActuals[cell+1], wpl.first.this].val]; BindActual[newActual, oldActual]; ENDLOOP; ENDLOOP; FOR ins: LIST OF CoreClasses.CellInstance _ instances, ins.rest UNTIL ins=NIL DO FixActual: PROC [old: Core.Wire] RETURNS [new: Core.Wire] = { new _ RootWire[old]; FOR wireIndex: NAT IN [0..new.size) DO new[wireIndex] _ FixActual[old[wireIndex]]; ENDLOOP; }; IF ins.first.actual#FixActual[ins.first.actual] THEN ERROR; ENDLOOP; [] _ RefTab.Pairs[operations, EachOperation]; FOR wires: Core.Wires _ CoreOps.Reverse[publics], wires.rest UNTIL wires=NIL DO internals _ CONS[wires.first, internals]; ENDLOOP; }; MakeSequenceIcon: PROC [comm: CDSequencer.Command] = { selected: CD.Instance _ TheCellInstance[comm.design, "MakeSequenceIcon\n"]; IF selected=NIL THEN RETURN; CleanUpIconProperties[selected.ob]; CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, $NewSequenceExtractSequence]; IF ParseSatellites[CDSatellites.GetSatelliteRopes[selected.ob]].keyword=NIL THEN TerminalIO.PutF["*** Warning: there is no satellite of the form 'Seq: Expression'.\n"]; TerminalIO.PutF["Sequencing of %g done.\n", IO.rope[CDDirectory.Name[selected.ob, comm.design]]]; }; ParseSatellites: PROC [ropes: ROPES] RETURNS [keyword, expr: ROPE _ NIL, others: ROPES _ NIL] = { WHILE ropes#NIL DO tokenKind1, tokenKind2: IO.TokenKind; token1, token2: ROPE; rest: ROPE; [tokenKind1, token1, rest] _ Sisyph.ParseRope[ropes.first]; [tokenKind2, token2, rest] _ Sisyph.ParseRope[rest]; IF tokenKind1=tokenID AND Rope.Equal[token1, "Seq"] AND Sisyph.IsParsedChar[tokenKind2, token2, ':] THEN { IF keyword=NIL THEN {keyword _ token1; expr _ rest} ELSE ERROR; } ELSE others _ CONS [ropes.first, others]; ropes _ ropes.rest; ENDLOOP; }; ExtractSequence: Sinix.ExtractProc = { name: ROPE _ mode.nameProc[obj, userData]; cx: Sisyph.Context; keyword, expr: ROPE; others: ROPES; cellType: CellType; count: NAT; [keyword, expr, others] _ ParseSatellites[NARROW [CDProperties.GetObjectProp[obj, Sinix.satellitesProp]]]; IF keyword=NIL THEN { TerminalIO.PutF["*** SisyphExtractSequence: Sequence does not contain any of sequencing information (e.g. an object satellite 'Seq: 32').\n"]; ERROR}; CDProperties.PutObjectProp[obj, Sinix.satellitesProp, others]; cx _ Sisyph.EvaluateParameters[userData, obj, properties]; Sisyph.EvalExpr[cx, keyword, expr, FALSE]; count _ NAT [Sisyph.FetchInt[cx, keyword].value]; Sinix.PutF["Extracting [Sisyph] cell %g (%g: %g)\n", IO.rope[name], IO.rope[keyword], IO.int[count]]; name _ Rope.Substr[name, 0, Rope.Index[name, 0, ".sch"]]; -- hack name _ Rope.Substr[name, 0, Rope.Index[name, 0, ".icon"]]; -- hack cellType _ ExtractSequenceIcon[obj, cx, keyword, count, name, Sisyph.GetCoreProps[cx]]; props _ Sisyph.GetCoreInstProps[cx]; result _ cellType}; publicWireTypeBBox: ARRAY PublicWireType OF CoreGeometry.Rect = [ [0, 0, 4, 32], -- sequence [0, 0, 4, 28], -- flatSequence [0, 0, 4, 24], -- common [0, 0, 4, 20], -- first [0, 0, 4, 16]]; -- last ExtractSequenceIcon: PROC [obj: CD.Object, cx: Sisyph.Context, resultVar: ROPE, count: NAT, name: ROPE, props: Core.Properties] RETURNS [sequence: CellType] = { AddOp: PROC [wire: Core.Wire, expose: PublicWireType] = { operation: Operation _ NARROW[RefTab.Fetch[operations, wire].val]; IF operation=NIL THEN { operation _ NEW[OperationRec]; IF NOT RefTab.Store[operations, wire, operation] THEN ERROR; }; operation.expose[expose] _ TRUE; }; MatchingPins: PROC [firstPin, lastPin: CoreGeometry.Instance] RETURNS [yes: BOOL _ FALSE] = { TransformPin: PROC [instance: CoreGeometry.Instance] RETURNS [pinIR: CoreGeometry.Rect] = { pinIR _ CDBasics.MoveRect[CDBasics.MapRect[ CD.InterestRect[instance.obj], instance.trans], CDBasics.SubPoints[[0, 0], CDBasics.BaseOfRect[ir]]]; }; firstSides: CoreGeometry.Sides _ CoreGeometry.GetSides[ir, firstPin]; lastSides: CoreGeometry.Sides _ CoreGeometry.GetSides[ir, lastPin]; IF (firstSides[top] AND lastSides[bottom]) OR (firstSides[bottom] AND lastSides[top]) OR (firstSides[left] AND lastSides[right]) OR (firstSides[right] AND lastSides[left]) THEN { firstBBox: CoreGeometry.Rect _ TransformPin[firstPin]; lastBBox: CoreGeometry.Rect _ TransformPin[lastPin]; firstMin, firstMax, lastMin, lastMax: INT _ 0; IF firstSides[top] OR firstSides[bottom] THEN { firstMin _ firstBBox.x1; firstMax _ firstBBox.x2; lastMin _ lastBBox.x1; lastMax _ lastBBox.x2; } ELSE { firstMin _ firstBBox.y1; firstMax _ firstBBox.y2; lastMin _ lastBBox.y1; lastMax _ lastBBox.y2; }; yes _ firstMin<=lastMax AND firstMax>=lastMin; }; }; BindingsAndOps: CoreOps.EachWirePairProc = { IF CoreProperties.GetWireProp[actualWire, exposeAtoms[common]]#NIL THEN { bindings _ CONS[[publicWire, publicWire], bindings]; AddOp[publicWire, common]; }; IF CoreProperties.GetWireProp[actualWire, exposeAtoms[sequence]]#NIL THEN AddOp[publicWire, sequence]; IF CoreProperties.GetWireProp[actualWire, exposeAtoms[flatSequence]]#NIL THEN AddOp[publicWire, flatSequence]; IF CoreProperties.GetWireProp[actualWire, exposeAtoms[last]]#NIL THEN AddOp[publicWire, last]; IF CoreProperties.GetWireProp[actualWire, exposeAtoms[first]]#NIL THEN { EachFirstPin: CoreGeometry.EachInstanceProc = { firstPin: CoreGeometry.Instance _ instance; IF CDRects.IsBareRect[instance.obj] AND instance.obj.bbox = publicWireTypeBBox[first] THEN { FindMatchingWire: CoreOps.EachWirePairProc = { EachLastPin: CoreGeometry.EachInstanceProc = { IF CDRects.IsBareRect[instance.obj] AND instance.obj.bbox = publicWireTypeBBox[last] AND MatchingPins[firstPin, instance] THEN bindings _ CONS[[firstWire, publicWire], bindings]; }; IF CoreProperties.GetWireProp[actualWire, exposeAtoms[last]]#NIL THEN [] _ CoreGeometry.EnumeratePins[Sisyph.mode.decoration, actualWire, EachLastPin]; }; [] _ CoreOps.VisitBinding[parentRCT[0].actual, base.public, FindMatchingWire]; }; }; firstWire: Core.Wire _ publicWire; AddOp[publicWire, first]; [] _ CoreGeometry.EnumeratePins[Sisyph.mode.decoration, actualWire, EachFirstPin]; }; }; Decorate: DecorateProc = { DecoratePin: CoreGeometry.EachInstanceProc = { IF CDRects.IsBareRect[instance.obj] THEN FOR exposition: PublicWireType IN PublicWireType DO IF publicWireTypeBBox[exposition]=instance.obj.bbox THEN { pins: CoreGeometry.Instances _ CoreGeometry.GetPins[Sisyph.mode.decoration, parentWires[exposition]]; CoreGeometry.PutPins[Sisyph.mode.decoration, parentWires[exposition], CONS[instance, pins]]; EXIT; }; REPEAT FINISHED => ERROR; ENDLOOP; }; actualWire: Core.Wire _ CoreOps.CorrespondingActual[parentRCT[0].actual, base.public, baseWire]; [] _ CoreGeometry.EnumeratePins[Sisyph.mode.decoration, actualWire, DecoratePin]; }; parent: CellType = NARROW[Sinix.ExtractCell[obj, Sisyph.mode, NIL, cx].result]; parentRCT: CoreClasses.RecordCellType = NARROW[parent.data]; base: CellType; bindings: WireBindings _ NIL; operations: Operations _ RefTab.Create[]; ir: CoreGeometry.Rect _ CD.InterestRect[CoreGeometry.GetObject[Sisyph.mode.decoration, parent]]; IF parentRCT.size#1 THEN { TerminalIO.PutF["*** SisyphExtractSequence: Sequence should contain one and only one subcell.\n"]; ERROR}; base _ parentRCT[0].type; Sisyph.ProcessGlobalNames[parent, cx]; FOR wireIndex: NAT IN [0..parent.public.size) DO IF parent.public[wireIndex].size=0 THEN { FOR exposition: PublicWireType IN PublicWireType DO IF CoreProperties.GetWireProp[parent.public[wireIndex], exposeAtoms[exposition]]#NIL THEN EXIT; REPEAT FINISHED => CoreProperties.PutWireProp[parent.public[wireIndex], exposeAtoms[common], $present]; ENDLOOP; }; ENDLOOP; FOR i: NAT IN [0 .. parentRCT.internal.size) DO wire: Wire = parentRCT.internal[i]; name: ROPE _ CoreOps.GetShortWireName[wire]; IF name=NIL THEN name _ "some wire"; SELECT TRUE FROM NOT CoreOps.RecursiveMember[parentRCT[0].actual, wire] => { TerminalIO.PutF["*** SisyphExtractSequence: %g is not connected to subcell.\n", IO.rope[name]]; ERROR; }; NOT CoreOps.RecursiveMember[parent.public, wire] => { TerminalIO.PutF["*** SisyphExtractSequence: %g is not public.\n", IO.rope[name]]; ERROR; }; ENDCASE; ENDLOOP; [] _ CoreOps.VisitBinding[parentRCT[0].actual, base.public, BindingsAndOps]; sequence _ CreateSequence[base, count, bindings, operations, name, props, Decorate]; CoreGeometry.PutObject[Sisyph.mode.decoration, sequence, obj]; }; CopyWireProperties: PROC[from, to: Wire] = { EachProp: PROC[atom:ATOM, ref: REF] = { CoreProperties.PutWireProp[to, atom, ref]; }; CoreProperties.Enumerate[from.properties, EachProp]; }; TheCellInstance: PROC [design: CD.Design, text: ROPE _ NIL] RETURNS [inst: CD.Instance _ NIL] = { inst _ CDOps.TheInstance[design, text]; IF inst=NIL OR CDCells.IsCell[inst.ob] THEN RETURN; TerminalIO.PutF["*** Selected instance is not a cellcan't do it.\n"]; inst _ NIL}; CleanUpIconProperties: PROC [obj: CD.Object] = { Sinix.FlushCache[obj]; CDProperties.PutObjectProp[obj, $IconFor, NIL]; CDProperties.PutObjectProp[obj, $CodeFor, NIL]; CDProperties.PutObjectProp[obj, Sisyph.mode.extractProcProp, NIL]; CDProperties.PutObjectProp[obj, Sisyph.expressionsProp, StripResultExprs [NARROW [CDProperties.GetObjectProp[obj, Sisyph.expressionsProp]]]] }; StripResultExprs: PROC [in: ROPES] RETURNS [out: ROPES _ NIL] = { FOR l: ROPES _ in, l.rest WHILE l#NIL DO expr: ROPE _ l.first; IF NOT Rope.Match[expr, "*cI*_*"] AND NOT Rope.Match[expr, "*wI*_*"] AND NOT Rope.Match[expr, "*wire*_*"] THEN out _ CONS [expr, out]; ENDLOOP; }; Sinix.RegisterExtractProc[$NewSequenceExtractSequence, ExtractSequence]; CDSequencerExtras.RegisterCommand[key: $MakeNewSequenceIcon, proc: MakeSequenceIcon, queue: doQueue]; END.  SequenceImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Barth, July 8, 1988 4:06:11 pm PDT Sequence Icon Commands Sequence Icons There should be only one subcell We deal with Global Variables Compatibility hack We check that there is no internal only We compute the bindings and operations We create the sequence The object decoration! Internal Utilities Soon obsolete? Initialization Κ€˜šœ™Icode™Jšœœ&˜3šœ œ˜Jšœ˜Jšœ,˜,J˜—K˜—šž œœ˜-KšœœœΟc˜AKšœA˜Ašœœœ˜"Kšœ˜Kšœ˜—K˜—šž œ˜(šž œœœœ˜PKšœ œ3˜BKšœ4œ˜9K˜—Kšœœ˜$Jšœ œ(˜7Kš œœœœœ˜EKš œ œœ œœ˜6Kšœ"œ5˜]Kšœ!œ;˜bšœœ˜Kšœœ˜3šœœœ ˜Kšœ3˜3Jšœ˜—Kšœ œ˜&Kšœœœc˜sKšœ!˜!J˜—šœœ˜Jšœœ˜Kšœœ˜8šœœœ ˜šœœœ ˜Kšœ?˜?Kšœ˜—Kšœ˜—Kšœ œ˜&Kšœœœg˜wKšœ%˜%J˜—šœœ˜Jš œœœœ œ˜XKšœœœ]˜mKšœ˜J˜—šœœ˜Jšœ œ˜%Kšœœœ_˜oKšœ˜J˜—šœœ˜Kš œœœœ œ˜Qšœœœ ˜Kšœ œDœœ˜aKšœ˜—Kšœœœ2˜BKšœ˜J˜—Jšœœœ#˜;Kšœ˜—Kšœœ˜9K˜)Jšœ œ!˜/š œœ œœ ˜)šž œ˜+KšœB˜BK˜—šž œ˜$Jšœ+˜+K˜—KšœMœ˜TJšœ œ˜$šœ œ˜-Kšœ˜Kšœ ˜ Kšœœ œœœœœœœ ˜WKšœ ˜ —Kšœ)˜)KšœA˜AK˜+Kšœ˜—šœœœ˜ šœ(œœ˜;Kšœœ;˜XKšœœ=˜ZKšœ!˜!Kšœ˜—Kšœ˜—š œœœ0œœ˜Pšž œœœ˜=K˜šœ œœ˜&J˜+Jšœ˜—K˜—Kšœ.œœ˜;Kšœ˜—K˜-šœ:œœ˜OJšœ œ˜)Jšœ˜—˜K˜———™ šžœœ ˜6Kšœ œ?˜KKšœ œœœ˜Kšœ#˜#Kšœb˜bKšœFœœX˜¨Kšœ,œ3˜aJšœ˜——™šžœœ œœœœ œœ˜ašœœ˜Kšœœœœ˜GKšœ;˜;Kšœ4˜4šœœœ-œ˜jKš œ œœ!œœ˜?K˜—Kšœ œ˜)Kšœ˜Kšœ˜Kšœ˜—J˜—šžœ˜&Jšœœ ˜*Jšœ˜Jšœœ˜Jšœœ˜Jšœ˜Jšœœ˜ Jšœ*œ:˜jšœ œœ˜JšœŽ˜ŽJšœ˜—Jšœ>˜>Jšœ:˜:Jšœ#œ˜*Jšœœ&˜1Jšœ5œ œœ ˜eJšœ: ˜AJšœ; ˜BJšœX˜XJ˜$Jšœ˜J˜—šœœœ˜AJšœ  ˜Jšœ ˜Jšœ  ˜Jšœ ˜Jšœ ˜J˜—•StartOfExpansion‘ -- [obj: CD.Object, mode: Sinix.Mode, properties: PropertyLists.PropList _ NIL, userData: REF ANY _ NIL] RETURNS [result: REF ANY, props: Core.Properties _ NIL]šžœœœ(œ œœœ˜ šžœœ.˜9Kšœœ%˜Bšœ œœ˜Kšœ œ˜Kšœœ+œœ˜˜>Jšœ˜J˜—šžœœ˜,šžœœœœ˜'Jšœ*˜*Jšœ˜—Jšœ4˜4Jšœ˜——™š žœœ œœœ˜;Jšœœ œ˜%Jšœ'˜'Jš œœœœœ˜3JšœF˜FJšœœ˜ J˜—šžœœœ ˜0Jšœ˜Jšœ*œ˜/Jšœ*œ˜/Jšœ=œ˜BšœH˜HJšœœ?˜F—J˜—JšΟb™š žœœœœœœ˜Aš œœœœ˜(Jšœœ ˜šœœ˜!Kšœœ˜"Kšœœœœ ˜A—Jšœ˜—Jšœ˜J˜——™JšœH˜HJšœe˜eJ˜—Jšœ‘˜—…—AhT¬