DIRECTORY GGBasicTypes, GGError, GGInterfaceTypes, GGModelTypes, GGOutline, GGObjects, GGSelect, GGSegmentTypes, GGSequence, GGTraj, GGUtility, GGVector, GList, Imager, Rope; GGOutlineImplB: CEDAR PROGRAM IMPORTS GGError, GGObjects, GGOutline, GGSelect, GGSequence, GGTraj, GGUtility, GGVector, GList, Imager EXPORTS GGOutline = BEGIN OPEN GGOutline; BitVector: TYPE = GGBasicTypes.BitVector; BoundBox: TYPE = GGBasicTypes.BoundBox; CameraData: TYPE = GGModelTypes.CameraData; Circle: TYPE = GGBasicTypes.Circle; Color: TYPE = Imager.Color; ControlPointGenerator: TYPE = GGModelTypes.ControlPointGenerator; FeatureData: TYPE = GGInterfaceTypes.FeatureData; GargoyleData: TYPE = GGInterfaceTypes.GargoyleData; Joint: TYPE = GGSegmentTypes.Joint; JointGenerator: TYPE = GGModelTypes.JointGenerator; Line: TYPE = GGBasicTypes.Line; ObjectBag: TYPE = GGInterfaceTypes.ObjectBag; Outline: TYPE = REF OutlineObj; OutlineObj: TYPE = GGModelTypes.OutlineObj; OutlineClass: TYPE = REF OutlineClassObj; OutlineClassObj: TYPE = GGModelTypes.OutlineClassObj; OutlineDescriptor: TYPE = GGModelTypes.OutlineDescriptor; OutlineParts: TYPE = REF OutlinePartsObj; OutlinePartsObj: TYPE = GGOutline.OutlinePartsObj; OutlineSequence: TYPE = GGSelect.OutlineSequence; OutlineSequenceGenerator: TYPE = GGSelect.OutlineSequenceGenerator; Point: TYPE = GGBasicTypes.Point; PointGenerator: TYPE = GGModelTypes.PointGenerator; PointPairGenerator: TYPE = GGModelTypes.PointPairGenerator; Scene: TYPE = GGModelTypes.Scene; Segment: TYPE = GGSegmentTypes.Segment; SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator; SelectMode: TYPE = GGModelTypes.SelectMode; SelectionClass: TYPE = GGSegmentTypes.SelectionClass; Sequence: TYPE = GGModelTypes.Sequence; SliceClass: TYPE = REF SliceClassObj; SliceClassObj: TYPE = GGModelTypes.SliceClassObj; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; SliceParts: TYPE = GGModelTypes.SliceParts; Traj: TYPE = REF TrajObj; TrajEnd: TYPE = GGModelTypes.TrajEnd; TrajGenerator: TYPE = REF TrajGeneratorObj; TrajGeneratorObj: TYPE = GGModelTypes.TrajGeneratorObj; TrajObj: TYPE = GGModelTypes.TrajObj; TrajPartType: TYPE = GGModelTypes.TrajPartType; TriggerBag: TYPE = GGInterfaceTypes.TriggerBag; Vector: TYPE = GGBasicTypes.Vector; OutlineDescribeProc: TYPE = GGModelTypes.OutlineDescribeProc; OutlineFileoutProc: TYPE = GGModelTypes.OutlineFileoutProc; OutlineFileinProc: TYPE = GGModelTypes.OutlineFileinProc; OutlineUnionPartsProc: TYPE = GGModelTypes.OutlineUnionPartsProc; OutlineDifferencePartsProc: TYPE = GGModelTypes.OutlineDifferencePartsProc; OutlineFixedPartsProc: TYPE = GGModelTypes.OutlineFixedPartsProc; OutlineAugmentPartsProc: TYPE = GGModelTypes.OutlineAugmentPartsProc; OutlinePointsInDescriptorProc: TYPE = GGModelTypes.OutlinePointsInDescriptorProc; OutlinePointPairsInDescriptorProc: TYPE = GGModelTypes.OutlinePointPairsInDescriptorProc; OutlineNextPointProc: TYPE = GGModelTypes.OutlineNextPointProc; OutlineNextPointPairProc: TYPE = GGModelTypes.OutlineNextPointPairProc; OutlineClosestPointProc: TYPE = GGModelTypes.OutlineClosestPointProc; OutlineClosestPointAndTangentProc: TYPE = GGModelTypes.OutlineClosestPointAndTangentProc; OutlineClosestSegmentProc: TYPE = GGModelTypes.OutlineClosestSegmentProc; OutlineSetArrowsProc: TYPE = GGModelTypes.OutlineSetArrowsProc; OutlineGetArrowsProc: TYPE = GGModelTypes.OutlineGetArrowsProc; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = GGError.Problem; UnpackOnePointDescriptorOld: PUBLIC PROC [outlineD: OutlineDescriptor] RETURNS [traj: Traj, isACP: BOOL, segNum, cpNum, jointNum: NAT] = { parts: OutlineParts; theSeq: Sequence; IF outlineD = NIL THEN RETURN[NIL, FALSE, 999, 999, 999]; parts _ NARROW[outlineD.parts]; traj _ NIL; FOR list: LIST OF Sequence _ parts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN { IF traj # NIL THEN RETURN[NIL, FALSE, 999, 999, 999] ELSE { theSeq _ list.first; traj _ theSeq.traj; [isACP, segNum, cpNum, jointNum] _ GGSequence.UnpackOnePointSequence[theSeq]; }; }; ENDLOOP; }; UnpackSimpleDescriptorOld: PUBLIC PROC [outlineD: OutlineDescriptor] RETURNS [success: BOOL, partType: TrajPartType, traj: Traj, joint: Joint _ NIL, jointNum: NAT _ 999, cp: Point, cpNum: NAT _ 999, seg: Segment _ NIL, segNum: NAT _ 999] = { parts: OutlineParts; theSeq: Sequence; IF outlineD = NIL THEN RETURN[FALSE, joint, NIL, NIL, 999, [0,0]]; parts _ NARROW[outlineD.parts]; traj _ NIL; FOR list: LIST OF Sequence _ parts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN { IF traj # NIL THEN RETURN[FALSE, joint, NIL, NIL, 999, [0,0]] ELSE { theSeq _ list.first; traj _ theSeq.traj; [success, partType, traj, joint, jointNum, cp, cpNum, seg, segNum] _ GGSequence.UnpackSimpleSequence[theSeq]; }; }; ENDLOOP; }; UnpackSimpleDescriptor: PUBLIC PROC [sliceD: SliceDescriptor] RETURNS [success: BOOL, partType: TrajPartType, traj: Traj, joint: Joint _ NIL, jointNum: NAT _ 999, cp: Point, cpNum: NAT _ 999, seg: Segment _ NIL, segNum: NAT _ 999] = { ERROR Problem[msg: "Outlines are not slices yet"]; }; UnpackOnePointDescriptor: PUBLIC PROC [sliceD: SliceDescriptor] RETURNS [traj: Traj, isACP: BOOL, segNum, cpNum, jointNum: NAT] = { ERROR Problem[msg: "Outlines are not slices yet"]; }; UnpackOneSegmentDescriptorOld: PUBLIC PROC [outlineD: OutlineDescriptor] RETURNS [traj: Traj, segNum: NAT] = { parts: OutlineParts; theSeq: Sequence; IF outlineD = NIL THEN RETURN[NIL, 999]; parts _ NARROW[outlineD.parts]; traj _ NIL; FOR list: LIST OF Sequence _ parts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN { IF traj # NIL THEN RETURN[NIL, 999] ELSE { theSeq _ list.first; traj _ theSeq.traj; [segNum] _ GGSequence.UnpackOneSegmentSequence[theSeq]; }; }; ENDLOOP; }; UnpackOneSegmentDescriptor: PUBLIC PROC [sliceD: SliceDescriptor] RETURNS [traj: Traj, segNum: NAT] = { ERROR Problem[msg: "Outlines are not slices yet"]; }; FindTrajInDescriptor: PUBLIC PROC [outlineD: OutlineDescriptor, traj: Traj] RETURNS [seq: Sequence] = { outlineParts: OutlineParts; outlineParts _ NARROW[outlineD.parts]; FOR list: LIST OF Sequence _ outlineParts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL AND list.first.traj = traj THEN RETURN[list.first]; ENDLOOP; RETURN[NIL]; }; PartsFromSequence: PUBLIC PROC [outline: Outline, seq: Sequence] RETURNS [sliceParts: SliceParts] = { realParts: OutlineParts; ptr: LIST OF Sequence; trajGen: GGModelTypes.TrajGenerator; sliceParts _ realParts _ NEW[OutlinePartsObj]; [realParts.seqs, ptr] _ GGUtility.StartSequenceList[]; trajGen _ TrajsInOutline[outline]; FOR traj: Traj _ GGObjects.NextTraj[trajGen], GGObjects.NextTraj[trajGen] UNTIL traj = NIL DO IF traj = seq.traj THEN [realParts.seqs, ptr] _ GGUtility.AddSequence[seq, realParts.seqs, ptr] ELSE [realParts.seqs, ptr] _ GGUtility.AddSequence[NIL, realParts.seqs, ptr]; ENDLOOP; }; CopyParts: PUBLIC PROC [outline: Outline, parts: SliceParts] RETURNS [copy: SliceParts] = { realParts, realCopyParts: OutlineParts; copySeq: Sequence; ptr: LIST OF Sequence; realParts _ NARROW[parts]; copy _ realCopyParts _ NEW[OutlinePartsObj]; [realCopyParts.seqs, ptr] _ GGUtility.StartSequenceList[]; FOR list: LIST OF Sequence _ realParts.seqs, list.rest UNTIL list = NIL DO IF list.first = NIL THEN [realCopyParts.seqs, ptr] _ GGUtility.AddSequence[NIL, realCopyParts.seqs, ptr] ELSE { copySeq _ GGSequence.Copy[list.first]; [realCopyParts.seqs, ptr] _ GGUtility.AddSequence[copySeq, realCopyParts.seqs, ptr] }; ENDLOOP; }; AddHole: PUBLIC PROC [outline: Outline, hole: Traj] RETURNS [holier: Outline] = { holier _ outline.class.copy[outline]; holier.children _ AppendTrajList[holier.children, LIST[hole]]; hole.parent _ holier; hole.role _ hole; UpdateOutlineBoundBox[holier]; }; ReplaceFence: PUBLIC PROC [outline: Outline, newFence: Traj] RETURNS [newOutline: Outline] = { holeGen: TrajGenerator; newTraj: Traj; newOutline _ CreateOutline[newFence, outline.lineEnds, outline.fillColor]; holeGen _ HolesOfOutline[outline]; FOR hole: Traj _ GGObjects.NextTraj[holeGen], GGObjects.NextTraj[holeGen] UNTIL hole = NIL DO newTraj _ GGTraj.CopyTraj[hole]; newOutline.children _ AppendTrajList[newOutline.children, LIST[newTraj]]; newTraj.parent _ newOutline; ENDLOOP; UpdateOutlineBoundBox[newOutline]; }; ReplaceHole: PUBLIC PROC [outline: Outline, oldHole, newHole: Traj] RETURNS [newOutline: Outline] = { holeGen: TrajGenerator; newTraj, fence: Traj; fence _ FenceOfOutline[outline]; newTraj _ GGTraj.CopyTraj[fence]; newOutline _ CreateOutline[newTraj, outline.lineEnds, outline.fillColor]; holeGen _ HolesOfOutline[outline]; FOR hole: Traj _ GGObjects.NextTraj[holeGen], GGObjects.NextTraj[holeGen] UNTIL hole = NIL DO IF hole = oldHole THEN { newOutline.children _ AppendTrajList[newOutline.children, LIST[newHole]]; newHole.parent _ newOutline; } ELSE { newTraj _ GGTraj.CopyTraj[hole]; newOutline.children _ AppendTrajList[newOutline.children, LIST[newTraj]]; newTraj.parent _ newOutline; }; ENDLOOP; UpdateOutlineBoundBox[newOutline]; }; OutlineOfTraj: PUBLIC PROC [traj: Traj] RETURNS [outline: Outline] = { outline _ traj.parent; }; SaveSelectionsInOutline: PUBLIC PROC [outline: Outline, scene: Scene] = { outlineD: OutlineDescriptor; outlineParts: OutlineParts; outlineD _ GGSelect.FindSelectedOutline[outline, scene, hot]; ClearSelectionInOutline[outline, hot]; IF outlineD # NIL THEN { outlineParts _ NARROW[outlineD.parts]; FOR seqList: LIST OF Sequence _ outlineParts.seqs, seqList.rest UNTIL seqList = NIL DO IF seqList.first#NIL THEN SaveSelectionInSequence[seqList.first, hot]; ENDLOOP; }; outlineD _ GGSelect.FindSelectedOutline[outline, scene, normal]; ClearSelectionInOutline[outline, normal]; IF outlineD # NIL THEN { outlineParts _ NARROW[outlineD.parts]; FOR seqList: LIST OF Sequence _ outlineParts.seqs, seqList.rest UNTIL seqList = NIL DO IF seqList.first#NIL THEN SaveSelectionInSequence[seqList.first, normal]; ENDLOOP; }; outlineD _ GGSelect.FindSelectedOutline[outline, scene, active]; ClearSelectionInOutline[outline, active]; IF outlineD # NIL THEN { outlineParts _ NARROW[outlineD.parts]; FOR seqList: LIST OF Sequence _ outlineParts.seqs, seqList.rest UNTIL seqList = NIL DO IF seqList.first#NIL THEN SaveSelectionInSequence[seqList.first, active]; ENDLOOP; }; }; SaveSelectionInTraj: PUBLIC PROC [traj: Traj, selectClass: SelectionClass, scene: Scene] = { seq: Sequence _ GGSelect.FindSelectedSequence[traj, scene, selectClass]; IF seq=NIL THEN ClearSelectionInTraj[traj, selectClass] ELSE SaveSelectionInSequence[seq, selectClass]; }; ClearSelectionInTraj: PROC [traj: Traj, selectClass: SelectionClass] = { seg: Segment; joint: Joint; FOR i: NAT IN [0..GGTraj.HiSegment[traj]] DO seg _ GGTraj.FetchSegment[traj, i]; SetSegmentField[seg, FALSE, selectClass]; FOR j: NAT IN [0..seg.class.controlPointCount[seg]-1] DO SetControlPointField[seg, j, FALSE, selectClass]; ENDLOOP; ENDLOOP; FOR i: NAT IN [0..GGTraj.HiJoint[traj]] DO joint _ GGTraj.FetchJoint[traj, i]; SetJointField[joint, FALSE, selectClass]; ENDLOOP; }; RemakeSelectionFromTraj: PUBLIC PROC [traj: Traj, scene: Scene, selectClass: SelectionClass] = { seq: Sequence _ GGSequence.CreateEmpty[traj]; seg: Segment; joint: Joint; FOR i: NAT IN [0..GGTraj.HiSegment[traj]] DO seg _ GGTraj.FetchSegment[traj, i]; seq.segments[i] _ GetSegmentField[seg, selectClass]; IF seq.segments[i] THEN seq.segCount _ seq.segCount + 1; FOR j: NAT IN [0..seg.class.controlPointCount[seg]-1] DO seq.controlPoints[i][j] _ GetControlPointField[seg, j, selectClass]; IF seq.controlPoints[i][j] THEN seq.controlPointCount _ seq.controlPointCount + 1; ENDLOOP; ENDLOOP; FOR i: NAT IN [0..GGTraj.HiJoint[traj]] DO joint _ GGTraj.FetchJoint[traj, i]; seq.joints[i] _ GetJointField[joint, selectClass]; IF seq.joints[i] THEN seq.jointCount _ seq.jointCount + 1; ENDLOOP; GGSelect.SelectSequence[seq, scene, selectClass]; }; SaveSelectionInSequence: PROC [seq: Sequence, selectClass: SelectionClass] = { seg: Segment; joint: Joint; FOR i: NAT IN [0..GGTraj.HiSegment[seq.traj]] DO seg _ GGTraj.FetchSegment[seq.traj, i]; SetSegmentField[seg, seq.segments[i], selectClass]; FOR j: NAT IN [0..seg.class.controlPointCount[seg]-1] DO SetControlPointField[seg, j, seq.controlPoints[i][j], selectClass]; ENDLOOP; ENDLOOP; FOR i: NAT IN [0..GGTraj.HiJoint[seq.traj]] DO joint _ GGTraj.FetchJoint[seq.traj, i]; SetJointField[joint, seq.joints[i], selectClass]; ENDLOOP; }; ClearSelectionInOutline: PROC [outline: Outline, selectClass: SelectionClass] = { trajGen: GGModelTypes.TrajGenerator; trajGen _ TrajsInOutline[outline]; FOR traj: Traj _ GGObjects.NextTraj[trajGen], GGObjects.NextTraj[trajGen] UNTIL traj = NIL DO ClearSelectionInTraj[traj, selectClass]; ENDLOOP; }; RemakeSelectionsFromOutline: PUBLIC PROC [outline: Outline, scene: Scene] = { trajGen: GGModelTypes.TrajGenerator; trajGen _ TrajsInOutline[outline]; FOR traj: Traj _ GGObjects.NextTraj[trajGen], GGObjects.NextTraj[trajGen] UNTIL traj = NIL DO RemakeSelectionFromTraj[traj, scene, hot]; RemakeSelectionFromTraj[traj, scene, normal]; RemakeSelectionFromTraj[traj, scene, active]; ENDLOOP; }; SequencesOfOutline: PUBLIC PROC [outlineD: OutlineDescriptor] RETURNS [seqList: LIST OF Sequence] = { outlineParts: OutlineParts _ NARROW[outlineD.parts]; ptr: LIST OF Sequence; [seqList, ptr] _ GGUtility.StartSequenceList[]; FOR list: LIST OF Sequence _ outlineParts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN [seqList, ptr] _ GGUtility.AddSequence[list.first, seqList, ptr]; ENDLOOP; }; RemoveTraj: PUBLIC PROC [outlineD: OutlineDescriptor, traj: Traj] = { outlineParts: OutlineParts _ NARROW[outlineD.parts]; seq: Sequence; FOR list: LIST OF Sequence _ outlineParts.seqs, list.rest UNTIL list = NIL DO IF list.first#NIL AND list.first.traj = traj THEN { seq _ list.first; GOTO Done; }; REPEAT Done => { outlineParts.seqs _ NARROW[GList.DSubst[NIL, seq, outlineParts.seqs]]; }; FINISHED => NULL; ENDLOOP; }; NearestJointToHitData: PUBLIC PROC [hitData: REF ANY] RETURNS [jointNum: NAT, traj: Traj] = { outlineHitData: OutlineHitData _ NARROW[hitData]; nextNum: NAT; p1, p2: Point; d1, d2: REAL; traj _ outlineHitData.traj; SELECT outlineHitData.hitType FROM joint => { jointNum _ outlineHitData.jointNum; }; segment, controlPoint => { nextNum _ GGTraj.FollowingJoint[traj, outlineHitData.segNum]; p1 _ GGTraj.FetchJointPos[traj, outlineHitData.segNum]; p2 _ GGTraj.FetchJointPos[traj, nextNum]; d1 _ GGVector.DistanceSquared[p1, outlineHitData.hitPoint]; d2 _ GGVector.DistanceSquared[p2, outlineHitData.hitPoint]; IF d1 <= d2 THEN jointNum _ outlineHitData.segNum ELSE jointNum _ nextNum; }; ENDCASE => ERROR; }; UnpackHitData: PUBLIC PROC [hitData: REF ANY] RETURNS [traj: Traj, hitType: TrajPartType, segNum, cpNum, jointNum: INT, hitPoint: Point] = { outlineHitData: OutlineHitData _ NARROW[hitData]; traj _ outlineHitData.traj; hitType _ outlineHitData.hitType; segNum _ outlineHitData.segNum; cpNum _ outlineHitData.cpNum; jointNum _ outlineHitData.jointNum; hitPoint _ outlineHitData.hitPoint; }; UpdateDescriptorBoundBoxes: PUBLIC PROC [outlineD: OutlineDescriptor] = { parts: OutlineParts _ NARROW[outlineD.parts]; FOR list: LIST OF Sequence _ parts.seqs, list.rest UNTIL list = NIL DO IF list.first # NIL THEN GGSequence.UpdateBoundBox[list.first]; ENDLOOP; }; HasHoles: PUBLIC PROC [outline: Outline] RETURNS [BOOL] = { RETURN[outline.children.rest # NIL]; }; FenceOfOutline: PUBLIC PROC [outline: Outline] RETURNS [fence: Traj] = { fence _ outline.children.first; }; HolesOfOutline: PUBLIC PROC [outline: Outline] RETURNS [trajGen: TrajGenerator] = { list: LIST OF Traj _ outline.children.rest; trajGen _ NEW[TrajGeneratorObj _ [ list: list ]]; }; TrajsInOutline: PUBLIC PROC [outline: Outline] RETURNS [trajGen: TrajGenerator] = { list: LIST OF Traj _ outline.children; trajGen _ NEW[TrajGeneratorObj _ [ list: list ]]; }; END. GGOutlineImplB.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last edited by Bier on January 22, 1987 Contents: Procedures to implement the Outline Slice Class in Gargoyle. Outlines consist of Trajectories which in turn consist of Segments. Outline is the most important slice class. Outline-Only operations. outlineD describes either a single control point or a single joint. Return the [segNum, cpNum] pair or the jointNum as appropriate. outlineD describes either a single control point or a single joint. Return the [segNum, cpNum] pair or the jointNum as appropriate. Holes can be removed using DeleteSequence. Should check for duplicates. -- Bier, February 20 Like CopyOutline except in one place. Like CopyOutline except in one place. Finds the unique outline to which traj belongs. hotness. normal selection. active selection. This outline has just been created by copying parts from an existing outline. The selection information was copied as well. Make sequences from the selection bits, and select these sequences. hotness. normal selection. active selection. Used by GGSelect to do a DeselectTraj. Replace the old sequence with a NIL. No trajectory has actually been deleted. It is just no longer mentioned in outlineD. This will go away when the Caret machinery is revised. Update the bound boxes of all contained sequences. Queries about Outlines. Returns the unique fence trajectory of outline. Generates all of the holes of outline. Generates the fence and all of the holes of outline. ΚΫ˜J˜Icodešœ™Kšœ Οmœ1™Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—šŸ œž œ$žœ˜^K™%K˜Kšœ˜KšœJ˜JKšœ"˜"šžœGžœžœž˜]Kšœ ˜ Kšœ:žœ ˜IKšœ˜Kšžœ˜—Kšœ"˜"K˜K˜K˜—šŸ œž œ,žœ˜eK™%K˜Kšœ˜Kšœ ˜ Kšœ!˜!KšœI˜IKšœ"˜"šžœGžœžœž˜]šžœžœ˜Kšœ:žœ ˜IKšœ˜K˜—šžœ˜Kšœ ˜ Kšœ:žœ ˜IKšœ˜K˜—Kšžœ˜—Kšœ"˜"K˜K˜—šŸ œžœžœžœ˜FKšœ/™/Kšœ˜K˜K˜—šŸœžœžœ%˜IKšœ˜˜JšΟb™—Kšœ8 œ˜=Jšœ! œ˜&šžœ žœžœ˜Kšœžœ˜&šžœ=žœ žœž˜VJšžœžœžœ( œ˜FJšžœ˜—J˜Jš ™—Kšœ8 œ˜@Jšœ! œ˜)šžœ žœžœ˜Kšœžœ˜&šžœ=žœ žœž˜VJšžœžœžœ0˜IJšžœ˜—J˜Jš ™—Kšœ8 œ˜@Jšœ! œ˜)šžœ žœžœ˜Kšœžœ˜&š žœ žœžœ,žœ žœž˜VJšžœžœžœ( œ˜IJšžœ˜—J˜—J˜K˜—šŸœžœžœ<˜\JšœH˜HJšžœžœžœ(˜7Jšžœ+˜/J˜J˜—šŸœžœ.˜HJšœ ˜ Jšœ ˜ šžœžœžœž˜,Jšœ#˜#Jšœžœ˜)šžœžœžœ)ž˜8Jšœžœ˜1Jšžœ˜—Jšžœ˜—šžœžœžœž˜*Jšœ#˜#Jšœžœ˜)Jšžœ˜—šœ˜J˜——šŸœžœžœ<˜`Jšœ-˜-J˜ J˜ šžœžœžœž˜,Jšœ#˜#Jšœ4˜4Jšžœžœ!˜8šžœžœžœ)ž˜8JšœD˜DJšžœžœ3˜RJšžœ˜—Jšžœ˜—šžœžœžœž˜*Jšœ#˜#Jšœ2˜2Jšžœžœ%˜:Jšžœ˜—Jšœ1˜1K˜K˜—šŸœžœ1˜NJ˜ J˜ šžœžœžœ!ž˜0Jšœ'˜'Jšœ3˜3šžœžœžœ)ž˜8JšœC˜CJšžœ˜—Jšžœ˜—šžœžœžœž˜.Jšœ'˜'Jšœ1˜1Jšžœ˜—J˜J˜—šŸœžœ4˜QJšœ$˜$Jšœ"˜"šžœGžœžœž˜]Jšœ(˜(Jšžœ˜—Jšœ˜J˜—šŸœžœžœ%˜MK™ΑJšœ$˜$Jšœ"˜"šžœGžœžœž˜]Jš ™Jšœ% œ˜*Jš ™Jšœ% œ˜-Jš ™Jšœ% œ˜-Jšžœ˜—K˜K˜—š Ÿœžœžœžœ žœžœ˜eKšœžœ˜4Kšœžœžœ ˜Kšœ/˜/š žœžœžœ)žœžœž˜MJšžœžœžœB˜ZJšžœ˜—K˜K˜—šŸ œžœžœ.˜EK™&Kšœžœ˜4K˜š žœžœžœ)žœžœž˜Mšžœ žœžœžœ˜3J˜Jšžœ˜ J˜—šž˜˜ šœžœžœ˜FJšœ{™{—J˜—Jšžœžœ˜—Jšžœ˜—K˜—K™š Ÿœž œ žœžœžœ žœ˜]Kšœ!žœ ˜1Kšœ žœ˜ Kšœ˜Kšœžœ˜ Kšœ˜šžœž˜"˜ Kšœ#˜#K˜—šœ˜Kšœ=˜=Kšœ7˜7Kšœ)˜)Kšœ;˜;Kšœ;˜;Kšžœ žœ!˜1Kšžœ˜K˜—Kšžœžœ˜—K˜K˜—šŸ œžœžœ žœžœžœ>žœ˜ŒK™6Kšœ!žœ ˜1Kšœ˜Kšœ!˜!Kšœ˜Kšœ˜Kšœ#˜#Kšœ#˜#K˜K˜—šŸœžœžœ"˜IK™2Kšœžœ˜-š žœžœžœ"žœžœž˜FJšžœžœžœ'˜?Jšžœ˜—K˜—K™Kšœ œ™š Ÿœžœžœžœžœ˜