The Gargoyle Design Document Eric Bier Maureen Stone Introduction Gargoyle will be an synthetic graphics illustrator in the tradition of Draw, Griffin, Gremlin (U. C. Berkeley) and Unicorn (University of East Anglia) and MacDraw. Our orientation is systems that enable a designer to achieve graphic art quality output using an interactive workstation and a digital printer. Each part of the design will be defined in a device independent manner, typically as an analytic outline. The designer works principally to produce a visual effect on the target device, but the image can also be rendered usefully on a set of devices for proofing, etc. In our systems, design elements consist of line and curve bounded regions. The boundary is a continuous function, such as a line or cubic splines. A region can be colored with either a constant or a sampled color, following the model defined by Interpress. The user thinks of the regions as shapes or objects that can be copied and transformed. The objects overlap opaquely (always?) in a defined order. This approach is in contrast to "painting" systems where the designer works directly with the pixels on the display. Our current illustrator of this form is Griffin. Griffin supports line and curve bounded areas, a primitive form of graphical style, and one-line captions in a limited number of rotations. Griffin was designed as an Alto Mesa program in 1978 and was carefully crafted to match the imaging model of the printing format Press. Griffin exposed a number of research issues in computer graphics, user interfaces, printing and interactive systems. Among these are the mathematics of "wide lines", high speed incremental refresh, color definition, user interfaces for shape editing including mathematical tranformations, control of a large number of graphical style properties, proper management of shared objects such as fonts and styles, and overall reliability including user friendly fail-safe mechanisms. Gargoyle will exploit the advances we have made in device independent graphics, printing and computing environments. Gargoyle will use the full power of the Imager, Interpress and Cedar. Like Griffin, Gargoyle will be a single page illustrator. The size of the page is not limited except, of course, when you actually print it. The point is, we are not investigating issues of pagination or large document management except in the use of graphical style. In this project we will focus on making a single, complex page. If you take Griffin as a starting point, Gargoyle will advance from it in several different areas. First, the objects themselves will be more complex and the editing model will be richer. Gargoyle will support contours with holes, where each trajectory in the contour can contain different types of curves (conics and cubics with a range of continuity constraints). We intend to allow users to break contours at (nearly) arbitrary points and insert pieces of other contours. We intend to have special tools for creating objects with symmetry (and other structure). Eventually we would like to include the full set of Boolean point set operations on contours (e.g. union, intersection, and difference) for constructing shapes. We would like also to explore the use of curve-fitting algorithms [Plass and Stone] to explore a combined painting and construction model for defining shapes. All in all, Gargoyle will be a test-bed for shape editing. For text editing, Gargoyle will attempt to leverage off of Tioga as much as possible. Actual integration with Tioga will have to be driven by Tioga development. As a minimum position, Gargoyle will interactively "paste-up" text from the Tioga formatter. Placement points for text will integrate with the shape editing point control mechanisms. Gargoyle style will support Tioga-like style for text. Second, the relationship between the objects in the scene will be more complex. There will be multi-level clustering, special tools for defining symmetry (and other structure), and (later) a simple constraint solver. We will provide a mechanism for explicily defining objects that touch. Eventually, we will include user defined "grids" and other alignment mechanisms. Gargoyle will employ an "intelligent dragging" mechanism for object placement which shows symmetry and alignment in real-time. Third, Gargoyle will support graphical style. Graphical style describes a set of named formulas for rendering illustrations from their raw "geometry". Work with Griffin, Tioga and TiogaArtwork convince us that there is merit (and many hard problems) in trying to separate the basic "skeleton" of the figure from such issues as font, color and line weight. This separation provides a mechanism for ensuring consistancy across a number of related illustrations, gives a way to codify some esthetic decisions, such as the relationship between font, line weight and arrowheads, in a manner that can be used by the esthetically naive, and leads us to consider defining "meta-illustrations" that can be rendered for significantly different viewing environments simply by changing style. An example of this last point is the illustrations for a conference paper and the acompanying talk. The "style" for slides and the "style" for the procedings are very different, but the same illustration needs to appear in both. We can imagine designing a meta-illustration that is rendered with two different styles, a bold, multi-colored "slide style" and an elegant, monochrome "procedings style". Fourth, Gargoyle will be an integrated Cedar program for making illustrations, posters and slides. We hope to make a system that is useful and "feels good" to members of the Cedar community and serves as an example of the kind of application that Cedar makes "easy". We intend to leverage as much as possible off of the Cedar environment, in contrast to Griffin which had to build everything above BitBLT from scratch. We want to make full use of our research on device independent graphics and quality printing to give the user the ability to predict the printed version of their illustration from the displayed one. Gargoyle Development The first version of Gargoyle will be a polygon editor with intelligent dragging, symmetry tools, fragile touching constraints and full scene hierarchy. Objects will have properties (line weight and fill color). There will be a simple, text-based file format and Interpress printing. This is Eric Bier's summer project with the goal to explore intelligent dragging and symmetry tools for his thesis work. Both "the ideal shape editor" and graphical style are open-ended research issues. Both can be pursued in the context of Gargoyle, but we don't yet have a crisp plan, just a bunch of ideas. It is interesting to note that once some form of simple shape and style editors are available, Gargoyle could surplant the Griffin as the Cedar illustrator. The systems aspects of Gargoyle must be coordinated with related research such as the "Artist's workbench" project (DILL), Tioga extensions, and the the "Document framework". The rest of this document Below, we describe Gargoyle in more detail. First, we describe the scene hierarchy as the user will perceive it. With this structure in mind, we detail the desired capabilities and our impressions of how they should be partitioned into operations. Next, we describe a possible user interface. Finally, we define the Gargoyle programmer's interface as it may appear in the Cedar Language. Gargoyle Scene Structure A Gargoyle scene is (almost) a strict hierarchy. In this section we describe the levels in the hierarchy and define our terms. Proceding from root to leaf, a Gargoyle scene consists of clusters, outlines and captions. Outlines consist of trajectories and trajectories consist of segments. Geometric points for defining segments are specified using control points. Some Gargoyle objects remember symmetry information about their sub-components, to be used by the alignment tools, as noted below. Segments. Shapes are made from curve segments. A segment is any space-curve with specified endpoints and tangent vectors. Some examples of segments are: a single straight vector, a cubic Bezier segment, a cubic spline, a conic segment or a conic spline. Segments in Gargoyle will be object oriented so that we can separate the representation of these curves from their use in a Gargoyle trajectory. As a practical matter, it should be possible to approximate the segment with an Imager trajectory so it can easily be displayed. Joint. The point at which one curve segment touches its neighboring segment. Control points. Each segment has a set of data values which determine its shape. These data values may be represented by x-y points in the plane called control points. For different editing situations the control points have different interpretations. We would like to set the interpretations in a manner similar to Tioga Looks. For example, to define a segment control points can be interpreted as follows: Straight line: Two points define the endpoints of a vector. Bezier segment: Four control points define a cubic segment. B-spline segment: Four control points define a cubic segment. Conic section: Three control points in a triangle for the overall shape and a fourth determines the value of r. Trajectories. A trajectory is an ordered sequence of segments with the constraint that each segment must meet its neighboring segment at a joint. In an open trajectory, the first and last segments have no neighbors. In a closed trajectory, the first and last segment are neighbors. A trajectory knows (some of the) symmetry groups to which its control points belong. If we allow arbitrary interpretations assigned to arbitrary sequences of control points, the various possible relationships between control points and joints makes it difficult to enforce continutity in an intuitive manner. Between interpolatory segments the relationship is clear; adjacent segments share a control point. If one of the segments is approximating, then the control point at the joint will automatically control the placement of both segments, even though this point may not normally be explicit for the non-interpolating segment (imaging a Bezier and B-Spline segment). This could cause a problem by overconstraining the solution for the non-interpolating segment. For adjecent non-interpolating segments, the problem is even more complex. Possible solutions: Don't allow arbitrary combinations. Insert extra segments to interpolate between the ends. Sacrifice locality. Outlines. An outline is a set of trajectories which define an object with holes. A single trajectory behaves also as an outline. The outline is the basic shape object in Gargoyle. An outline knows (some of the) symmetry groups to which its trajectories belong. Clusters. A cluster is defined recursively as a set of one or more outlines and clusters. The outlines and clusters may overlap in the image plane. The result of rendering a cluster is determined by the priority of its components (see below). A cluster knows (some of the) symmetry groups to which its outlines and sub-clusters belong. Rigidity. Unclustered outlines and trajectories can always be edited if the control points are visible. The control points of a trajectory can always be moved whenever they are visible. Thus, the command to make control points invisible, enforces rigidity. A more permanent form of rigidity can be achieved by clustering the outline. Wrap number. A trajectory may intersect itself; the set of points which are inside such a contour is determined by the Imager wrap-number machinery. The multiple trajectories in an outline also follow the Imager wrap-number conventions. The user interface will make it easy to define the containing object or fence vs. the hole-defining trajectories. Ideally, the user would produce an outline by selecting a trajectory for editing, selecting a second trajectory as a "cookie cutter" then "cut" holes in the first trajectory using the second. We may have to compromise on this ideal to get started because general purpose trajectory intersection code is non-trivial. At the minimum, there will be a way to indicate that one trajectory is the fence and the rest are holes. To start, only holes that do not intersect other trajectories will work "correctly." Priority. Every outline has a priority number determining its position in the drawing order. Priority numbers are unique. Thus, all of the trajectories in a given outline have the same priority. Most likely, this priority number will be the number originally held by the fence trajectory. Text. We wish to give the user the full facilities of Tioga to edit text, without complicating Gargoyle. The general approach will be to edit the text off to the side and then position it in the scene. Text may be positioned with the same operations which apply to outlines. Entity. For convenience, we use the term entity to denote an object which could equally well be a control point, a trajectory, an outline, or a cluster. Gargoyle Capabilities Gargoyle must provide the following sorts of operations, grouped by the entities to which they apply: All Entities (point, sequence of points, trajectory, outline, cluster) Select/Deselect/Extend Drag/Rotate/Scale Copy Transform (affine transformation) Delete Control Point Sequences Only Set Interpretation Add Point Sequence Rubberbanding {On/Off} Segments Only Apply Joint Properties Trajectories Only {Reveal/Hide} Control Polygon Add Alignment Point Compute Intersection Points Apply Trajectory Properties Outlines Only Add Holes/Delete Holes Apply Style Change Overlap Order Clusters Only Cluster/Uncluster Miscellaneous Undo/Redo Below, Gargoyle's commands are discussed in more detail. Afterwards, the planned symmetry/constraint tools are described. Operations on Control Points Editing a trajectory in Gargoyle will be, in some ways, like editing a string of characters in Tioga. We make the analogy as follows: Tioga Text <=> Gargoyle Scene Character <=> Segment Word <=> Trajectory Node <=> Outline Intercharacter Space <=> Joint Caret between characters <=> caret at a joint Primary selection (underlined) <=> multiple primary selections (highlighted joints) Caret looks <=> caret looks. Plain, Bold, Italic, Underlined <=> Polygonal, Bezier, Natural, Thick Lines The analogy is not quite complete in these ways: 1) There are multiple primary selections. 2) We wish to select and move control points, which are not mentioned in the analogy at all. 3) We wish to be able to splice a control point into the middle of a segment (which would correspond, in Tioga, to splittling a character in two). In particular, imagine editing this picture: /Cyan/Imaging/gargoyle/trajectories.Press leftMargin: 1.25 in, topMargin: 0.5 in, width: 7.0 in, height: 3.0 in This picture corresponds to this Tioga string: ABCDEF The segments must maintain C0 continuity. We could imagine editing such a sequence with these operations: Create a sequence: ABCDEF (creates an open straight line sequence by default). Select a subsequence: {ABCD}EF Make it be an interpolating spline: ABCDEF (overrides the polygonal property) Select another subsequence: ABCDE{F} Make it be a Bezier spline: ABCDEF (control points 7 and 8 are created). Select a mixed subsequence: AB{CDE}F Make it have thick lines: ABCDEF (giving the picture above). Splice in a new control point (10) in the middle of segment E: ABCDE1E2F Add a new control point (11) on the "right" end (to make a new segment G): ABCDE1E2FG (the new segment has control points 11 13 14 12, where 13 and 14 are added automatically). Weld on another subsequence (LMNO): ABCDE1E2FGLMNO The Weld operation takes advantage of the idea of a caret position (like the selection caret in Tioga). A subsequence can be "SHIFT-selected" from any revealed control polygon and automatically translated up to the caret (See the Interface section, under Curve Editing, for more details). We also anticipate a Split operation which will break a trajectory in two at a selected point. If the selected point can be a point of intersection with another trajectory then we can provide the same functionality as Boolean set operations (the union, intersection, and difference of areas) and other operations as well. Operations on All Entities Select/Deselect/Extend. There is a single (possibly heterogeneous) set of seleted entities. In other words, control points, outlines, and clusters may all be in the selected set at once. Note that segments are not officially entities; control points can be selected, but segments cannot. However, a segment is "selected" when all of its control points are selected (since control points can go off of the screen this may require a special operation which selects all of the control points of a segment -- sort of a backwards way of doing things). The Select command selects a particular control point, sequence, or trajectory and deselects all others. Extending is just like selecting except that nothing is deselected (similar to Star). Drag/Rotate. All of the selected objects can be dragged. This may be a little slower than Griffin, since in Gargoyle one must select objects in order to drag them. However, this seems to win in two ways: Selection feedback shows which objects will actually be dragged (where Griffin had no feedback), and multiple objects may be dragged as a unit (instead of requiring the Map transform or clustering, in Griffin). Rotation of points and point sequences is accomplished similarly. Rotation occurs around the caret position. Copy. The "caret" position can be on a trajectory or out in free space. A SHIFT-select type operation copies the selected object and translates it to the caret position. DEL may cancel this operation as in Tioga. Transform. Perform a specified affine transformation on the selected entities. Unlike Griffin, these transformation will involve typing numbers. We expect transformation based on pointing to be accomplished with intelligent dragging and alignment tools. Delete. An object is deleted by selecting it and hitting DEL. There may also be a notion similar to Backspace and SHIFT-Backspace in Tioga. . There may also be a notion similar to CTRL-select in Tioga (sequences selected with CTRL held down are deleted when CTRL is released ). Operations on Control Point Sequences Set Interpretation. Takes a selected point sequence. All segments spanning those control points will now be of the specified spline type. Where possible, the shape of the segment will be preserved (for Conic to Bezier, this might work, for Conic to Straight Line it won't). This is just a beginning plan. Part of the research of Gargoyle is to develop a better scheme. Add Point Sequence. New points can be added to either end of an open trajectory, in which case a new segment is added at the ends. The type of segment is determined by the caret looks. New points may also be added in the middle of an existing segment. In this case, the old segment becomes two segments of the same type as the segment which they replace. Both commands require placing the caret at the desired adding-site and then positioning the new point. Note that whole sequence of points can be copied from other trajectories and inserted into a control point sequence. Rubberbanding {On/Off}. We are concerned that with some spline types rubberbanding may be so slow that it is distracting. With rubberbanding off, the user may reposition several control points and then invoke a ReDraw! command to see the results. In fact, this is much like the way Griffin works. (It's funny -- after a few minutes of playing with the PathTool one wonders how one got along without rubberbanding.) Segments Only Apply Joint Properties. It will be possible to specify how two segments join. The joint properties are position and tangent values at the joint. It is possible to assign constraints to the tangents such as, make these tangents equal. In the absence of constraints, each segments can be edited independently. Trajectory and Outline Commands In Gargoyle, we wish to be able to move whole objects and control points or other objects at the same time. One possible design is as follows: Trajectories and Outlines are not rigid unless they are explicitly clustered (Clusters with only a single outline in them are fine). The control points of an outline can be MOVED if 1) The outline is not part of a cluster, and 2) The control points are revealed. The control points of a trajectory can be revealed even if it is part of a cluster. This is useful for copying parts of existing trajectories to make new trajectories. {Reveal/Hide} Control Polygon Add Alignment Point. Extra points which are not joints or control points may be added to a trajectory for use in alignment operations. These points may be selected, but are not part of the control point sequence. Extra points may be added manually by positioning the caret and invoking a command. However, they may also be generated by Gargoyle -- for instance, when the user asks Gargoyle to find all of the intersection points of two trajectories. Compute Intersection Points Apply Trajectory Properties Add Holes/Delete Holes. Holes are made with the AddHole operation which works as follows: Select any outline which includes a closed (fence) trajectory. Extend the selection to any number of outlines which have only closed (fence) trajectories. Invoke the AddHoles command. Each of the simple outlines donates its trajectory to be a hole in the outline which was selected first. All outlines but the first are destroyed (and information about how they were filled is lost). The donated trajectories maintain their color and line width styles. These operations have an effect on appearance (the holes are now negative objects), but not on rigidity (outlines are not, of themselves, rigid). Change Overlap Order. Overlap order will be managed much as in Griffin. However, there are plans for Up One and Down One operations which move the selected entity up one place relative to those objects which obscure it, rather than relative to all the objects in the scene. Properties and Style: See below Cluster Commands Cluster/Uncluster Text The initial plan: A single line of text may be placed in a box and positioned in the scene. The box will be aligned using one of the 12 alignment positions ({top, middle, baseline, bottom} x {left, center, right}) mentioned in Rick Beach's dissertation. The more elaborate plan involves the full facilities of Tioga available in the Gargoyle window. Miscellaneous Undo/Redo Gargoyle will have undo and redo mechanisms. About Clustering and Selection Gargoyle will allow multiple levels of clustering. Before describing the mechanism, let's review clustering and selection in Griffin and Star. Clustering in Griffin had three major effects: 1) Dragging. Multiple objects could be translated with the interactive (left mouse button) drag commands which only worked on the nearest top-level object. 2) Rigidity. Clusters guaranteed that the relative positions of its objects were protected from accidental dragging motions. 3) Indivisibility. A cluster of objects was selected as a whole and participated in affine transformations as a whole. There was only one layer of clustering in Griffin. This had its good and bad points. The problem was that the user expends of good deal of effort in clustering objects so that carefully created relationships will be maintained. When a cluster A is made part of a larger cluster B and then unclustered, the work of selecting the parts of A is lost. Furthermore, the work is often hard to redo since the scene in the locality of A is more cluttered than when A was made initially. The advantage was that one was never more than one Uncluster away from being able to edit a trajectory or change a text string that happened to be part of a cluster. Another problem was the persistence of selections. Because many selections persist after commands (e.g. so that Apply Style commands can be repeated without having to reselect the affected objects), the expert Griffin user soon learns to click the "Deselect all" button before almost every command. As there was no keystroke accelerator for "Deselect all", this was particularly painful. In Tioga, there is only one selection so each new selection undoes all previous selections. In Juno, some commands require multiple selections. Since each command is a mode, Juno can proceed much as Tioga does, except with multiple selections -- if a command requires 4 arguments then entering a fifth argument undoes the first. In Star, each new selection undoes the previous ones. Multiple selections can be made either by extending the selection individually to new objects with an extend selection (like Tioga), or by stretching out a box. In Star, an object must be selected to be dragged. This allows an arbitrary collection of objects to be dragged together as well as a single object. With this design, clustering has lost one of its main motivations -- rigidity under smooth dragging. Instead, clustering represents simply a remembered collection of objects -- e.g. a way to save work when reselecting a group of objects. Star, like Griffin, provides one level of clustering. Gargoyle's selection mechanism will be much like Star's. Arbitrary multiple selections will be possible. Only selected objects can be dragged. A new selection (as opposed to extension) removes previous selections. Here are the details: Commands will be provided to select a control point, a sequence of control points, a trajectory, an outline, and top-level objects (in Griffin, only top-level objects could be selected, which admittedly was simpler), and commands will be provided to extend the selection. Adequate feedback must be provided to show what has been selected. Transformations (dragging, rotation, scaling, etc.) can only be performed on top-level objects. Thus, the only reasons to select a non-top-level object are: 1) To reveal the control polygon of a trajectory. 2) To copy pieces of a revealed trajectory to build a new trajectory (see Trajectory Commands below). 3) To change the style of a selected set of segments. 4) To invoke the Gargoyle UnclusterToSelection command. The UnclusterToSelection command works as follows: Only one entity may be selected. The selected entity O need (should) not be at top-level. All the clusters on the path from the root cluster to O are undone. In other words, we undo as little possible in order to bring O to be top-level (See Figure). This is what is needed when you just want to change "one-little-thing" which happens to be part of a cluster. When coupled with a Recluster command, this should make the simple changes convenient. Because outlines and trajectories are not units of rigidity, UnclusterToSelection will have the same effect for a selected control point, as if that control point's trajectory had been selected, or as if that control point's trajectory's outline had been selected. /Cyan/Imaging/gargoyle/Uncluster.Press leftMargin: 1.25 in, topMargin: 0.5 in, width: 6.25 in, height: 6.5 in Recluster works as follows: Gargoyle remembers the effect of the last UnclusterToSelection operations. It remakes all of the clusters which were unmade with the following exceptions: If an entity has been deleted, it is not included. All selected entities which were not part of the original hierarchy become children of the lowest-level cluster. This allows you to delete "one little thing" or add "one little thing" without having to work hard remaking clusters. There will also be an Uncluster command with the effect that the topmost layer of clustering (of all selected clusters) is removed. The Cluster command works as in Griffin. All selected entities become part of a new cluster. About Topology In Sketchpad, Sutherland represented a scene as a network of vertices and edges. This topological representation allowed the user to explicitly declare two vertices to be identical (merged). Along with constraints, it was possible to specify that two objects are to remain touching and so on. Sketchpad did not provide filled areas (the TX-2's screen was a vector device), so Sutherland used a very homogenous representation for his network. We would like Gargoyle to have some of the capabilities of Sketchpad. In particular, we would like to be able to merge a point on one object with a point on another object as in box-and-pointer diagrams: /Cyan/Imaging/gargoyle/boxAndPointer.press leftMargin: 0.75 in, topMargin: 1.25 in, width: 5.5 in, height: 4.75 in The idea, of course, is that it be possible to move the endpoints of the lines and the box together. Notice that this is a very unGriffin-like thing to do. In Griffin, there is no way to change the shape of several objects at the same time. There are three main ways to make this functionality available: 1) In Burton's Sketch system, there is a MovePts command (the name is a little misleading) which does this: Puts Sketch in a mode where all control points are visible. Allows the user to select either control points or clusters (clusters are rigid even during a MovePts operation). All selected objects are translated with a smooth dragging operation. Nothing rubberbands during the dragging. Instead, objects some of whose control points are selected (but not all) stay put until the dragging is done and then redraw themselves in the new position. There is no explicit representation of vertex merging (or even gravity). Two points are coincident in Sketch because they have been placed on the same grid point. 2) In ThingLab, objects can be dragged under the influence of constraints. The constraints are solved several times per second and the image rubberbands. 3) Special "constraints" like "two vertices are merged" or "a vertex is stuck to a particular point on a rigid line" can be solved without requiring the general constraint solver which ThingLab has. The Sketch system solution is quite intuitive and we are tempted to use it, at least initially. However, we wish to represent the touching relationship explicitly rather than having it be an accident of grid points. There are two reasons for this: First, we are interested in a system where grids are less important. Second, we are working on ideas of graphical style, and explicit relationships make more intelligent style decisions possible. For instance, a line with an arrow-head end-style might behave differently if the arrow-head is touching a line than if the arrow-head is free in space: /Cyan/Imaging/gargoyle/arrows.press leftMargin: 1.5 in, topMargin: 2.0 in, width: 6.25 in, height: 2.5 in The simplest implementation for our purposes is a "fragile" touching constraint. We will provide gravity or some other mechanism for putting a point on a point and a point on a line. This touching constraint is independent of the cluster hierarchy. It is always a relationship between two trajectories. If the user moves one of the trajectories, the constraint is broken until it is remade manually. However, if the user moves both trajectories together (or one trajectory and the constrained point of the other) the constraint is maintained. Styles, Properties and Attributes Attributes, Styles and Properties. Attributes, styles and properties all affect how an object appears. Attributes usually affect the geometry of a trajectory (the shape of its centerline). Styles and properties affect the way in which the final visible shape depends upon the centerline geometry. Attributes can only be applied to objects while they are editable. Styles and properties can be applied anytime. In the sane, ordinary world, style involves line width and color. In the wild, untamed world, this might involve rendering trajectories as dotted lines with strange and wonderful dots, or with candy canes onto them. Joint attributes are: continuity. Segment attributes are: curve type. Segment styles are: line width, color, dotted. Outline styles are: fill color (including sampled image "colors") and endjoint shape (rounded, butt, square). In Gargoyle, at each joint the user may specify whether or not slope continuity should be preserved across that joint. In other words, there are segment attributes, and joint attributes. Continuity is a joint attribute. We will preserve this continuity using a scheme such as in Darlene Plebon's PathTool. Extensibility Programmers Interface ŽFile: GargoyleDesign.tioga Last edited by Bier on July 8, 1985 10:24:43 pm PDT Last edited by Stone on November 4, 1985 4:37:58 pm PST Ê3˜code™K™3K™7—Ititle˜Iauthors˜head1˜ IbodyšœÕ˜ÕOšœ§˜§Ošœ½˜½OšœÎ˜ÎOšœË ˜Ë Ošœô˜ôO˜¥ O˜ì—head˜O˜—O˜ÜO˜¯—˜O˜‡—˜Ošœ©Ïiœ œ œ œ œœ>œ…˜ôOšœŒ˜”OšœH˜MOšœàœO˜ÌOšœN˜NIitemšœ;˜;Qšœ<˜Q˜pOš œ˜œOšœT˜TOšœ€˜€Oš œ®˜·OšœP˜POšœÆœ˜õOšœ\˜\OšœÉ˜ÑOš œ¬œ£˜àOšœœ˜¤Ošœ˜•Ošœ#œi˜˜—˜O˜ehead2˜FIdisplay˜V— ˜S˜<— ˜ S˜— ˜S˜i— ˜ S˜7— ˜ S˜— ˜ S˜ O˜z— šœ˜Iblockšœ†˜†Q˜Q˜Q˜Q˜Q˜Q˜-Q˜SQ˜Qš œÏbœœÏz œžœœ ˜KO˜0Q˜*Q˜]Q˜“Qšœ.˜.Icenter• ArtworkClass IncludePressšœs˜sI continuation˜V˜.SšÐizŸž˜V˜VšœÏuœM˜jSšœQ˜QSšœ ˜ Sšœ&œ&˜PSšœœ˜&Sšœœžœ&˜JSšœœž˜$Sšœ Ÿžœ˜=SšœA ŸÐdzŸ¢ž˜JSš œM Ÿ¢Ÿ¢žœZ˜²Sš œœ Ÿ¢Ÿ¢ž˜3Ošœ˜œÅ˜å— šœ˜Ošœ5œ±˜ƒOš œ…˜OšœÓ˜×Oš œ÷˜€Ošœ›˜¡—šœ&˜&Ošœã˜õOšœ²˜ÄOšœ˜£— ˜ Ošœ¡˜·— ˜O˜O˜¶Q˜-Q˜$V˜¨Oš˜Ošœ²˜ÅOš˜Oš˜Ošœîžœ¬˜¸Ošœÿ˜“Ošœ ˜ — ˜Oš˜—˜O˜ÿO˜_— ˜ Oš œÃ˜Ì——˜Ošœ˜O˜.Q˜œQ˜}Q˜wO˜âO˜¥OšœÑ˜ÑOšœôœ™˜•O˜ïO˜òQ˜2Q˜fQ˜6Q˜8O˜ƒU– IncludePressšœq˜qO˜ÕO˜ƒO˜]—˜O˜ŠU– IncludePressšœv˜vO˜³Q˜ÐQ˜›Q˜ÆO˜ÚU– IncludePressšœm˜mO˜¤—˜!Oš!œ×˜øQ˜"Q˜$Q˜.Q˜mOšœ’œœ|Ÿ*œ˜â—N˜ N˜O˜—…—‚šˆ[