\begindata{text,270332748}
\textdsversion{12}
\template{default}
\define{footnote

attr:[Flags OverBar Int Set]
attr:[FontSize PreviousFontSize Point -2]}
\define{up15
menu:[Justify,Up15]
attr:[Script PreviousScriptMovement Point -15]}
\define{sans
menu:[Font,Sans]
attr:[FontFamily AndySans Int 0]}
\define{fullwidth
menu:[Justify,Full Width]
attr:[LeftMargin LeftMargin Cm -25431]
attr:[RightMargin RightMargin Cm -27743]}
\formatnote{.\\" To print at 4.25 x 10.25, remove the other instance of 
backslash-quote and use ~wjh/tmac/tmac.atk425

.\\"rm BT

.\\"ds CT


.de OC

.br

.ne 3.1v

..}


\flushright{\smaller{4 January 1990}}\formatnote{



}
\formatnote{.\\"ll 6.5i}

\majorheading{Enhancing documents with embedded programs:

How Ness extends insets in the Andrew 
ToolKit}\footnote{\
\begindata{fnote,270321112}
\textdsversion{12}
(C) 1990 IEEE. Reprinted with permission, from Proceedings of IEEE Computer 
Society 1990 International Conference on Computer Languages, March 12-15, 
1990, New Orleans, to appear.


Permission to copy without fee all or part of this material is granted 
provided that the copies are not made or distributed for direct commercial 
advantage, the IEEE copyright notice and the title of the publication and its 
date appear, and notice is given that copying is by permission of the 
Institute of Electrical and Electronics Engineers.  To copy otherwise, or to 
republish, requires a fee and specific permission.\
\enddata{fnote,270321112}
\view{fnotev,270321112,32,0,0}}



\center{Wilfred J. Hansen

Information Technology Center

Carnegie Mellon University

Pittsburgh, PA 15213-3890}

\formatnote{.\\"ll 4.75i}


\italic{\bold{Abstract:}   An enhanced document responds to its reader in 
non-traditional ways: a button press may scroll the document, play music, ... 
.  Although such operations may be implemented as objects embedded in text, 
full generality requires that a programming language be available to the 
author of a document.  This paper sketches the problems of embedding programs 
in documents and reviews the solutions adopted in the Ness component of the 
Andrew ToolKit.  A key question is the connection from user actions to program 
functions.  Other questions include the appropriate level of programming 
language, its string processing capabilities, and security. }



Traditionally a computer document is an emulation of a paper one;  it sits 
there for the reader to explore at will.  This present paper is no different 
because even though I am writing it on a computer I expect most readers will 
view it on paper.  But suppose you were reading it at a computer;  how much 
more could it do?  Simulations, calculations, interactive examples, waving 
flags, music, fireworks?


The report below describes a system in which it is possible to write documents 
that have most of these behaviors.  In order to provide the most general 
environment, the system incorporates a programming language, Ness, the design 
of which has been kept simple so as to reach a broad range of authors.  The 
underlying system is the Andrew ToolKit (ATK).


Typical applications of such a system include


\indent{enhanced documents - with various animations and simulations to 
illustrate the points of the document


parameterized letter - after the user fills in a few fields in a form letter 
other fields are calculated and the full letter is constructed


personal data base - addresses, appointments, course records, bibliography, 
...


directory editor - click on a file to see its attributes or select it for 
moving or deleting


system status monitor - a user builds a personal monitor for work station 
status by selecting from a library of system measurement tools and a library 
of ways to view dynamically changing values: dials, strip charts, and so on.


dungeons and dragons - the description of the world is a large text through 
which the reader can scroll;  as the reader solves puzzles, descriptions of 
new rooms and objects are added to the text.}


The remainder of this paper discusses the system as though it were intended 
for extending document:  objects are inserted in the document at various 
places and their behavior is controlled by a \italic{script} written in the 
programming language.  In all cases the discussion applies equally well to 
programming an application; such a situation is just an image that cannot be 
scrolled off the screen as parts of a document can.  For documents the 
substrate is a text;  for applications the substrate is a drawing editor or 
some other tool for laying out the contents of a window.


\formatnote{.\\"sp 2.75i}

Hypertext documents can be created easily within a system that supports 
authorship of enhanced documents.  The author need only insert in the text a 
button extended to respond to a button press by scrolling elsewhere in the 
same document or another.  Nor is the link constrained to always branch to the 
same place; the author can arrange the script so the destination is chosen 
among several depending on what the reader has seen so far.  Because lengthy 
linear documents are possible, the Ness/ATK combination may reduce the 
disorientation readers sometimes encounter in hypertext systems with small 
nodes.  The scroll bar in the view of the document serves as a visual 
indication of where the current image is within the context of the entire 
document.  See [8] for a good discussion of the advantages of hypertext and 
references to the growing literature on user disorientation.


Some discussion in the multi-media mail community has focussed on using a 
language to describe mail documents.  With this facility, new varieties of 
objects can be sent if the receiving system has no more capability than the 
language interpreter.  The work reported below is both more and less general. 
 It is not a language suitable for describing any object, it assumes that a 
collection of objects will be available in the software of both sender and 
receiver.  It does, however, provide a language tailored for the author to 
describe a myriad of different forms of interconnection and behavior of 
objects.


It is important to distinguish the notion of enhancing a document with a 
script from the various authoring languages for educational tutorials (good 
examples are cT and Best Course of Action;  see [7]).  With the latter, the 
author constructs a program which \italic{generates} a sequence of images; 
this contrasts with the enhanced document approach of Ness where the program 
within the images.  The crucial difference is in user control:  with an 
enhanced document the reader is in control and can employ ordinary text 
operations to move through the text.  With program generated images control 
lies with the system;  the reader can move only to where the system allows. 
 Experience has shown that it is not easy for authors to always imagine where 
readers will want to go in reviewing a tutorial, so the reader many be 
sometimes stymied in trying to get to a desired place.

 

The best known system with a programming language for enhancing what the 
reader sees is Hypercard [1].  However, Hypercard operates in a far more 
limited environment:  its images are constrained to a certain small size and 
only two forms of object may be embedded, buttons and fields.  In contrast the 
system described below is implemented within the far richer environment of the 
Andrew ToolKit, ATK.  [5]


Underlying ATK is an object architecture, complete with inheritance of 
methods.  Two principle forms of object are 

	

\indent{\italic{data object }- this provides for storage and manipulation of 
information;  every data object has at least the methods for writing the 
object to a data stream and reading it back.


\italic{view} - this provides user access to the contents of a data object by 
displaying it in a rectangle on the screen;  it also provides user interface 
operations for scrolling or modifying the information.}


The ATK architecture is specifically designed so that a view cannot know 
whether it occupies an entire window or whether it is a subrectangle in 
another view.  If a view has embedded child views, the architecture provides 
for the parent view to completely control the events seen by the child, thus 
views can be nested arbitrarily.  To describe what the user sees of the 
combination of view and data object, this combination is called an 
\italic{inset}.  It is worth noting that the architecture proved sufficiently 
general that little change to the underlying system was required to add Ness.


In starting Ness, it was not clear how script pieces should interface with 
insets and the user.  The many design alternatives are outlined in the next 
section and the following section describes the choices made for Ness.  A 
sketch of other facets of Ness--especially the string algebra--is in the third 
section, followed by a discussion of security issues in the last section.



\underline{\bold{1.  How can documents be enhanced?}} 


Define an "extension" as a sequence of code to be executed at some particular 
time during a user's perusal of a document.  The principal semantic questions 
are


\indent{1)  What sorts of events can trigger the extension? 


2) What effect can the extension have on the containing text and surrounding 
objects?} 


It is apparent that in the usual workstation environment the set of events 
that can trigger an extension must include user actions with the keyboard and 
the mouse.  In ATK, an important subset of mouse actions are selection from 
the popup menu.  Another set of trigger events are those defined by each inset 
class.  For instance text objects may initiate an event when some portion is 
selected or when the text scrolls, both of which may be caused by any of 
several user actions.  


In principle, inset-defined events would be a sufficient set of triggers. 
 However, user inputs are an important additional form of trigger because they 
enable the extension language to deal with any object, whether or not it has 
been constructed with the language in mind. 


How is each object to be connected to the portion of the script which 
specifies the response to events on that object?  One answer to this is given 
by Hypercard, which associates a script with each object.  The difficulty with 
this approach is that scripts and their functionality get scattered all over 
the place.  In trying to understand what happens in response to a mouse click 
on a button it may be necessary to look at as many as five different scripts 
(button, card, background, stack, and home stack);  and trying to understand 
the interaction of several buttons requires looking at each in turn.  The 
situation is similar to the difficulties of trying to understand a spreadsheet 
of even modest complexity [3]. 


In Ness all the scripts for a collection of objects are gathered together. 
 Each object is named and the extensions for an object appear together in a 
group identified with the name of the object.  Review of the script is thus 
reduced to looking in a single place, though it is now not as easy to see 
which object each name refers to, especially if many objects are extended. 
 Ness authors can avoid this by using multiple scripts in the document, one 
for each section.  It is the author's responsibility to clarify as far as 
possible the relation between script portions and objects. 



A few people who have heard about Ness without seeing it have suggested that 
the script ought to include not only the extensions but also textual 
descriptions of the objects themselves.  Among the claimed advantages are that 
the script could be editted with a plain ASCII editor and that scripts could 
be generated by programs.  Ness has taken a very different approach. 
 Construction of objects and their assembly into a document or application are 
handled with the ordinary ATK object oriented editing facilities.  If a button 
is required in the upper left corner, the author puts a button there and it is 
immediately visible, just as the reader will eventually see it.  Ultimately 
ATK data streams are indeed encoded in ASCII, so they can be editted with 
ASCII editors by incorrigible hackers.  It is also possible for a Ness script 
to insert an object in the document or application.  To select its size and 
place the script negotiates with the parent inset inset which the object is 
inserted.


In a fully developed system there is a point to having representations of the 
objects in the script so the author can click on one to request that it be 
highlighted in the document.  At present this is handled for Ness by an 
"arbiter" application, part of the mechanism that handles naming of objects.



What can an extension do to its environment?  A guiding principal of Ness is 
that the instructions in an extension ought to have at least the same 
capabilities as the user sitting at the workstation.  Consequently, primitives 
are provided for simulating the user actions of mouse hits, menu selections, 
and key strokes.  In addition, each object makes available a set of operations 
that Ness extensions may invoke. 


One of the serious problems with allowing scripts to pretend to be the user is 
that ATK permits users to alter the binding from keystrokes and menu options 
to function calls.  If the author writes a script which invoke the sequence 
ESC-N it may work for the author but fail for others who have ESC-N bound to a 
different operation.  The correct approach is for the author to instead call 
the function which he or she has bound to the ESC-N key.  Functions behave the 
same for all users. 



How does the extension script refer to objects in the environment?  For each 
execution of an extension there is one unique object, namely the one which 
triggered the extension;  this object can be referred to by a special name. 
 There is also a special name for the text in which the script is embedded; 
 via this name the program can access any portion of the document and any of 
its other objects.  Most commonly, however, objects are referenced by the same 
name which is used to associate extensions with objects. 



\bold{\underline{2.  The Ness `Extend' construct}}


A Ness script is a sequence of attribute specifications: declarations of 
global variables, global functions, and \italic{extend} blocks.  An extend 
block associates a set of contained attributes with some named object.  An 
extend block has the syntax: 


\indent{\bold{extend} <name>

	<attributes> 

\bold{end extend}}


where the <name> must be a string constant giving the name of an object. 


There are situations in which it might make sense that the <name> value be an 
expression rather than a constant and that the extend construction be 
executable rather than a declaration.  For instance an author may wish to have 
different extensions for an object at different times.  This design was not 
chosen for Ness because I felt that readers and authors would be best served 
by a language with relatively "static" semantics; one where the reader could 
tell what the program refers to without a great deal of poking around the 
code.  There could be confusion for some authors if they were allowed an 
expression for <name>: they might not know when the expression would be 
evaluated or whether a change in the value of the expression would cause the 
extend construct to refer to a different object.  Furthermore, the static 
nature of the extend construct helps suggest to the author that the behavior 
of documents should be constant rather than dynamic;  once a reader has 
understood a given button, it should not change its behavior without a clear 
cause. Nonetheless, a button can have differing behavior if an author really 
so desires;  the extension for the button need only test a global flag and 
behave differently for different values. 


Suppose the author wants to dynamically create an object and insert it in the 
document. How can extensions be specified for it?  With Ness this can be 
accomplished if the name of the future object is pre-known.  The <name> in the 
extend construct can refer to an object which does not yet exist.  When it is 
created, the extensions will be automatically applied to it.  For complete 
generality, however, it will probably be necessary to add to Ness some form of 
executable \bold{extend} operation.


In additional to declarations and function definitions, the attributes in a 
extend block may include \italic{event specifications}.  Each such specifies a 
trigger event and a list of statements to be executed when the event occurs. 
 In a manner similar to the extend construct, an event specification is a 
static declaration with the form


\indent{\bold{on} <event-type> <specifier-string>

	<statements> 

\bold{end} <event-type>}


The <event-type>s are \bold{mouse}, \bold{menu}, \bold{keys}, and 
\bold{event}, where the first three intercept the various user events and the 
fourth reacts to named events initiated by objects.  The interpretation of the 
<specifier-string>, which must be a constant, depends on the <event-type>. 
 For \bold{mouse} it says which button is to be intercepted and whether the 
interception is for the down stroke, movement while down, upstroke, or all of 
the above.  For \bold{menu} and \bold{keys} it specifies which operations are 
to intercepted or provided for the user.  In particular, the 
<specifier-string> for \bold{menu} can add new options to the menu.  The 
statements for an  \bold{on event} are executed whenever the object extended 
(by the surrounding \bold{extend} construct) initates the event named by the 
<specifier-string>.


In writing Ness scripts one of the early discoveries is that intercepting a 
mouse hit means that that hit will not go to the object.  In one example, the 
object was a slider and the final value, when the mouse is let up, is to be 
transferred to a computation.  If the mouse is intercepted, the slider will 
not change its value in response to the mouse, so the script must perform an 
additional operation to tell the extended inset of the mouse change.  A 
built-in function in Ness provides for passing the event along to the inset.


Passing an intercepted event along to an inset may seem similar to the "pass" 
operation in Hypercard, an operation that sends the current input message 
\italic{up} the hierarchy to the next level (button to card to stack to ...). 
 However, in Ness and ATK events go \italic{down} the hierarchy so the 
bottommost object will not see the event at all if the surrounding script so 
dictates.  In our estimation, this gives the script and surroundings more 
control with less special purpose code within the objects. 



Naming of insets and interception of mouse, menu, and keystroke events is 
handled by the \italic{cel} and \italic{arbiter} insets provided by the ADEW 
component of ATK [4].  These mechanisms are outside the insets themselves, so 
their facilities can be utilized without the collaboration of the subject 
inset.  Cels and arbiters are both examples of \italic{wrapper} insets, ones 
which have a single child to which they allocate their entire screen space. 
 Each cel wraps around a simple inset like a button, so it can name the button 
and intercept events.  Each arbiter wraps around a substrate inset, like text, 
which can have multiple embedded objects;  from this vantage the arbiter 
collects the names from all enclosed cels and makes the names available to 
Ness.


Since an arbiter wraps a substrate and a substrate may contain arbitrary 
insets, one subinset of an arbiter may be another arbiter together with its 
own enclosed substrate, Ness script,  and collection of insets.  So how does a 
script refer to objects in an arbiter other than its own.  It doesn't.  At 
present, a Ness script can only refer to objects that share the same 
surrounding arbiter as the script itself.  This restriction could be 
eliminated, but not without some difficulty.  Consider the case where an 
author has defined a simulation with a collection of named insets and a Ness 
script that refers to them.  Suppose then that the author inserts two copies 
of this simulation in a document.  It is only because each is surrounded with 
its own arbiter that name conflicts are avoided: the Ness script in each 
simulation still refers to the local insets.  As yet we have not enough 
experience with Ness to suggest that a capability of referring to objects 
within embedded arbiters is a necessary capability.



The statements within an \bold{on} construct may refer to \italic{currentinset} 
to refer to the inset whose event has triggered the current execution;  they 
may refer to inset(<string expression>) to refer to the inset whose name is 
given by the <string expression>.  Both constructions yield objects as their 
values; objects on which it is possible to invoke two classes of function that 
are defined in C code.  First, the script may refer to methods and instance 
variables of the object.  Since this is not well protected and can lead to 
incorrect behavior, it is discouraged, but there are situations in which it is 
crucial.  More safely, the script can call functions in what is called the 
\italic{proctable}.  Each inset defines a set of procedures in this table, 
from which they are available to be called from Ness functions or to be bound 
to keystrokes or menu options as a user customizes his environment.



\bold{\underline{3.  The String Algebra}}


Other than for string values, the Ness language is as simple and traditional 
as possible.  The seven statement forms currently implemented provide for 
variables, functions, and flow-of-control, as sketched in Table 1 and 
illustrated in Appendix 1.  Semicolons are optional between statements. 
 Parentheses are used only for function call and expression nesting.  Since it 
is implemented with ATK, programs may be typographically formatted for 
clarity.  There are five types of data in Ness: \bold{integer},  \bold{real}, 
 \bold{boolean},  \bold{object}, and \bold{marker}.  The first three of these 
are as in other common languages.  An object value is a pointer to an object; 
it is principally of use for values that are to be passed to methods and 
proctable functions written in C. 



\formatnote{.ne 4.0i}

variables

	declaration:   \italic{boolean} p, q    \italic{real} x, y, z 
   \italic{integer} i, j

	assignment:   x := y + z    p := \italic{not} q \italic{or} \italic{True}


function

	call:   f(x, p, i)    sin(z)

	return:   \italic{return} x + y    \italic{exit function}


flow-of-control:  while-do,  exit-while,  if-then-elif-else

	\italic{while} i < j \italic{do}

		x := x * 2.5

		\italic{if}  x > y  \italic{then} 

			\italic{exit while} 

		\italic{end if}

		i := i + 1

	\italic{end while}


\bold{Table 1.  The seven statement forms in Ness.}  Other flow-of-control 
statements are planned for the future.


 

String values in Ness had to differ from those in other languages for several 
reasons.  Most importantly, strings in any user-level language must be able to 
include full typography--fonts, indentation, italic, non-ASCII characters, and 
so on--as well as embedded objects.  In a functional language it is also 
important that substrings be first class objects which can be passed as 
arguments and returned as values.  In other programming languages it is 
difficult to write parsing and other string processing functions because 
substring references are clumsy.  If substrings are not an integral part of 
the language, each substring reference needs three components: a reference to 
the underlying string, an indication of the start of the substring, and an 
indication of the length of the substring.  It is possible to retain such 
values by keeping three separate variables;  it is even reasonable to pass 
them as arguments to functions.  Returning such a triple of values from a 
function, however, is awkward at best.  The situation is so bad that it is 
difficult to see how to write a satisfactory string package as either a set of 
functions or a preprocessor for C; the algebra needs to be incorporated as a 
fundamental part of a language.


In Ness, \bold{marker} values serve as string values.  Each such value refers 
to a substring of some underlying base string.  In particular, for documents 
one base string will be the document itself and a Ness script can refer to and 
modify an associated text via marker values.  A formal algebra underlies 
marker values, as detailed in [2], where it is proven that the algebra is 
Turing equivalent.  Within this algebra, constants and concatenation serve 
traditional roles: each returns a marker value for an entire, newly-created 
string.  Five functions provide for all possible manipulations on strings: 
 base(), start(), next(), extent(), and replace().  See table 2.



\formatnote{.ne 4.0i}

\description{\indent{base(\italic{s}) - returns a marker for the entire base 
string underlying \italic{s}


start(\italic{s}) - returns a marker for the empty string which starts where 
\italic{s} does


next(\italic{s}) - returns a marker for the single character which starts 
where \italic{s} ends


extext(\italic{s}, \italic{r}) - returns a marker for the portion of the base 
between start(\italic{s}) and start(next(\italic{r})); if the latter precedes 
the former, the value is an empty marker at start(next(\italic{r}))


replace(\italic{s}, \italic{r}) - modifies the base string underlying 
\italic{s} so the portion that \italic{s} originally referred to will contain 
a copy of the value initially in \italic{r}}}


\bold{Table 2.  The five primitive operations in the string algebra.}



The string algebra solves other problems in addition to convenience in writing 
string processing as function calls.  The programmer need not be concerned 
with allocating storage for strings because that is handled by the system. 
 Strings are not restricted to the array model found in some languages and 
programmers need not resort to integers, pointers, or some other non-string 
data type in order to refer to substrings.  Strings also provide a data 
structuring form that may be more amenable to non-programmer computation than 
traditional programming constructs which are designed more for the convenience 
of hte machine than the human.


For data structuring, Ness markers provide not only string processing, but 
also all the capabilities of structures and arrays.  A string is a structure 
when it has multiple objects embedded in it.  It is an array when the embedded 
objects are all the same type and integer subscription functions are used to 
access the object.  It should be noted that integer accessing does not reflect 
the majority of applications of arrays; in many applications an array is 
accessed sequentially, varying the subscript by one at each step.  This 
corresponds to sequencing through a marker value with the \italic{next}() 
function.  For non-sequential access, however, it is trivial to write a 
function in the string algebra to access the i'th element of a marker value, 
see Algorithm 1.  In practice, this algorithm is a primitive provided in the 
Ness system.   (When it becomes common for users to store marker value objects 
within strings, garbage collection will be necessary.  At the moment storage 
for the underlying strings is released when no markers refer to them.)



\formatnote{.ne 4.4i}

-- subscript(m, i)

--	Returns the i'th element of m.  If the length of m is

--	less than i, the function returns an empty marker

--	at the end of m.  If i is less than zero the function

--	returns an empty marker at start(m).

--

\italic{function} \bold{subscript }(m, i)

	\italic{marker} \bold{s}

	\italic{if} i <= 0 \italic{then return} start(m)\italic{ end if}

	s := next(start(m))  -- first element of m

	\italic{while} extent(s, m) /= "" \italic{do}

		-- we are not at the end of m

		\italic{if} i = 1 \italic{then  } \italic{return} s   \italic{end if}

		s := next(s)   -- next element of m

		i := i - 1

	\italic{end while}

	-- we are at the end of m

	\italic{return} start(next(m))

\italic{end function}


\bold{Algorithm 1.  The i'th element of a marker value.} This example also 
illustrates typographical formatting of Ness code.



The desire for simplicity in Ness has led to a number of decisions to defer or 
not implement popular semantic tools.  The two major such decisions are that 
Ness is not object oriented and functions are not first class objects.  Ness 
does provide access to objects, but these must be written in C as augmented 
with the \italic{class} preprocessor [6].  If functions were first-class, the 
\bold{extend} functionality could be expressed as an assignment to an 
attribute of the object extended.  During the design it was felt that this 
provision would make it possible to make more complex, less intelligible 
programs.  For both functions and object-orientedness, only experience will 
suggest whether we need to augment the language.


Some observers have asked: should Ness be Lisp or be more like Lisp?  One 
argument in favor of Lisp is that it has "less" syntax.  However, this 
argument does not hold up when we notice that each "special form" in Lisp has 
its own unique syntax; and that there are many more special forms in Lisp than 
language constructs in Ness  Another argument for Lisp is that it is a well 
known language.  This is true, but the domain for Ness is so different that a 
Lisp programmer must learn a new set of functions anyway;  this set of 
function names is a much higher hurdle to Ness than is the syntax of the 
language.  A final argument for Lisp is that lists are a convenient data 
structure which is simple to learn.  Ness counters this with the string 
algebra, which is just as powerful and may be even more intuitive for 
non-programmers.



\bold{\underline{4.  Security}}


Embedding of scripts in documents does not introduce a new level of security 
problem, but makes more obvious a common security problem.  The problem is 
that in small operating systems when I execute a program written by someone 
else it may do anything I myself may do; in particular, delete a file, modify 
a file, or send a copy of a file--say a forth-coming examination--to an 
interloper, perhaps a student about to take that examination.  Since a Ness 
script is a program, and since it can do anything a user can, its execution is 
a security loophole.


Hypercard offers a security level scheme of a sort: users may choose to 
execute at one of five levels of privilege.  However, these levels restrict 
the user from dangerous operations while not restricting  scripts; a script 
may even reset the level itself.  One reason this is not more of a problem in 
the Hypercard environment is that the equipment is less frequently connected 
to networks.  However, stackware is shared and we can expect virus attacks via 
stackware in the future.


Some mainframe operating systems have implemented "capabilities", permissions 
that can be granted to limit the operations available to programs.  These 
would ease the security problems, though they will still exist.  Consider, for 
example, the user who offers a brand-new spiffy shell which gives graphical 
access to files.  This shell will have to be given enough capabilities that it 
could be dangerous.


Ultimately the best and only protection is Trust;  the reader must trust the 
person from whom he or she got a document.  In a small closed community, such 
trust is an important factor in the free and open exchange of software. 
 Unfortunately, the spread of networking is widening our communities and 
exacerbating the security problems.


The Ness implementation has features that make it more difficult--though by no 
means impossible--for a villain to damage an unwary 
user.\footnote{\
\begindata{fnote,270439136}
\textdsversion{12}
It may be no surprise that despite considerable early design work actual 
implementation of Ness security began November 4, 1988, two days after the 
infamous Morris internet virus.\
\enddata{fnote,270439136}
\view{fnotev,270439136,33,0,0}}  In particular, no script is ever executed--or 
even compiled--without permission from the reader.  Users may choose among two 
options for this protection.  The default option, automatically invoked for 
any user who has not chosen otherwise, is that the Ness script is surrounded 
with a text that describes the dangers of executing a script (see Appendix 2). 
 The tail end of this text has buttons which allow the reader several options, 
including that of \bold{Empower}ing the script, which compiles the script and 
activates any extensions it specifies.  To be absolutely sure the user wants 
to empower the script, a click on the Empower button pops up a dialog box 
asking whether the user \italic{really} intends to empower the script.


A villain should also be intimidated by the fact that Ness scripts are stored 
only in source form.  The villain cannot know which readers will take the time 
to examine the script before empowering it, an examination which might ferret 
out any suspicious code.  (Few readers will read scripts in their entirety, 
but enough will to provide a deterent.)  Such examination of the code is aided 
by \bold{Scan}, another option among the buttons at the end of the warning 
text.  This option compiles the script, but generates an error message for 
each operation which might conceivably modify any of the reader's files, 
whether in memory or on the disk.  Without artificial intelligence, this scan 
is forced to be quite paranoiac;  it flags many statements which are 
completely harmless.  Nonetheless, it typically selects less than a fifth of 
all statements.


More experienced readers may wish a direct approach to empowering scripts. 
 They may specify in their personal preferences that they wish to see a dialog 
box instead of the warning text.  Then whenever a Ness appears for the first 
time the reader is presented a dialog box which offers the same options as the 
buttons at the end of the warning text.


The necessity for security adds an unfortunate complexity.  It would be 
preferable if users did not have to know about the script and the notion of 
empowering it.  Worse, the requirement means that an author must position the 
script in such a way that it will be visible on the screen, because otherwise 
the reader will never see it to Empower it.  This can clutter the design of 
applications with an unwanted element.  In the future Ness and ATK will have 
mechanisms to reveal the script at the outset and later hide it.



\bold{\underline{Evaluation}}


This paper has shown that document extension has considerable potential for 
bringing the computer revolution to information delivery.  It has described 
the Ness language which permits an author to construct a document with a 
variety of behaviors. 


The first problem in defining the interconnection of a language embedded in a 
document is to identify those user events which initiate the operations 
described by the language.  With the \bold{extend} construct, Ness associates 
event handlers with named insets.  If the inset signals appropriate events, 
they may be handled via the \bold{on event} construct; otherwise the script 
can intercept user events destined for the inset with the \bold{on menu}, 
\bold{on mouse}, and \bold{on keys} constructs. 


Next the design must specify how the language can affect the document.  One 
general tool is to allow the script to perform all possible user operations. 
 In addition, Ness provides a full set of functions for manipulating insets, 
especially the text inset for which Ness provides a string algebra.


Finally, the design must provide some control so nefarious authors are not as 
free to produce programs which can damage readers' files.  With Ness, the 
reader has the option to empower a script or not and also the Scan mode which 
aids in reviewing the script for potentially dangerous statements. 


Although apriori it may seem that enhanced documents would be excellent for 
mail, they turn out not to be used in mail very much.  The world of electronic 
mail is much more a world of short immediate messages than it is a world of 
carefully crafted communication.  Plans for multi-media mail must satisfy the 
requirement for transmission of a variety of kinds of bulk 
information--including scripts--but this will not be the majority of the 
traffic. 


A number of other lessons have been learned from this work: 


\leftindent{o  One can go quite far with static declaration of extends, 
events, and functions.  Simple scripts for enhancing documents do not seem to 
need a highly dynamic language. 


o  Ness shows how to do extensions in a more comprehensible manner than 
scattering scripts behind each individual object.  By giving names to objects 
they can be extended in the script and can serve as the targets of operations.


o  The syntax of the extension language is far less a barrier to authors than 
is the size of the library of functions available.


o  Strings can be dealt with functionally with the string algebra.  However, 
the algebra is not as simple for non-programmers as could be hoped.  The next 
step will be to define a pattern matching language to see if this can make 
clearer the description of string processing algorithms.} 


Ness is currently in daily use for maintenance of a data base of bugs and a 
bibliography.  Over time, the number of applications will grow; these will 
serve as the basis for a future report. 

\begindata{bp,270321348}
\enddata{bp,270321348}
\view{bpv,270321348,34,0,0}

\bold{\center{\underline{References}}}


\description{
[1] \italic{Hypercard User's Manual}  Publication 030-3081-A, Apple Computer 
Inc. (Cupertino, Calif.)  1987.


[2] Wilfred J. Hansen, "The Computational Power of an Algebra for 
Subsequences", Information Technology Center, Carnegie-Mellon Univ., 1989.


[3] Clayton Lewis and Gary M. Olson, "Can Principles of Cognition Lower the 
Barriers to Programming?"  Report on an informal workshop, University of 
Colorado, July, 1986.


[4] Thomas P. Neuendorffer, "ADEW: The Andrew Development Environment 
Workbench: An Overview",  presented at the X Conference, Boston, MA, 1989.


[5] Andrew J. Palay, Wilfred J. Hansen, et al., "The Andrew Toolkit - An 
Overview",  presented at the Usenix Conference, Dallas, TX, January, 1988.


[6] Paul G. Crumley, "The Andrew Class System", Information Technology Center, 
Carnegie Mellon University, file andrew/doc/Class.doc, 1989.


[7] Bruce A. Sherwood and Jill H. Larkin, "New tools for courseware 
production."  \italic{Journal of Computing in Higher Education}, vol. 1, no. 
1, pp. 3-20, 1989.


[8] Ben Shneiderman and Greg Kearsley, \italic{Hypertext Hands-On!}, 
Addison-Wesley, 1989.}

\begindata{bp,270321304}
\enddata{bp,270321304}
\view{bpv,270321304,35,0,0}
\bold{\underline{\center{Appendix 1:  A Ness extended birthday card}}}


After empowering the Ness in the birthday card below, the reader can click the 
mouse on the cake;  the card plays "Happy Birthday", shows the words, and 
lights the candle on the cake. 


Before:


\begindata{raster,270424108}
2 0 77083 77083 0 0 542 434
bits 270424108 542 434
/aa/aa/aa/aa"aa	a8 |
/55/55/55/55"55	54 |
bfZZZLf8 |
7fZZZLf4 |
bfZ27f9Gf9fcJ	!e7Jf93fJe7G9f	HfcS3fKf8 |
7fZ27f9G39fcJ	!e7Jf93fJe7G9f	HfcS3fKf4 |
bfZ27f9G39fcJ	!e7Jf93fJe7G9f	HfcS3fKf8 |
7e181fWfe6473	86099991"e1cf	070e48!f87323	c393c9cf20fc1c
 33cfe0S07c391	f178f274 |
bc4f9fWfe62!33	!3988"c4ce4626	22727133119989	c4cf22791993cf
 c8S139988e472	7078 |
7ccf3fVfe3667	33f338799ccc!cf	cce6!666733f3	39f99cce666733
 9f999f9cS39f9	9cce6733f4 |
bc0e7fVfc8667	338338799cc0!e1	cce60666673873	39c19cce666733
 9c199f9cS39c1	9cce6733f8 |
7cfe7fVfdcce7	273339339ccf!f8	9ce67e66673e27	39999cce76e733
 999dbf9cS3999	9cce6733f4 |
bcfcXfce72733	39339ccf!fc9c	e67e66673f2739	999cce70e73399
 9c3f9cS39999c	ce6733f8 |
7c49Xfce72703	29939c"c49e46	26667271273981	89c4f9e279181e
 79c8S13819ce4	7273f4 |
be181fWfce727	8999939c"e19f	270e6678f86739	c483c1f9e4fc9c
 4e79e4S27c49c	f078f3f8 |
7fZX9fcff9Ife	7fWfe7fGf4 |
bfZX9fcff3Ifc	Xcc7fGf8 |
7fZX9fcfe3If8	Xe0Hf4 |
bfZZZLf8 |
7fZZZLf4 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
68888azzzj14 |
a2!22zzzj18 |
68888azzzj14 |
bfGfezzzj18 |
707f06zzzj14 |
b07f06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zh0fc3f0	l0ff0i38g0380	zj18 |
70g06zh03gc0l	031c0ch18g0180	zj14 |
b0g06zh03gc0l	03!0ch18g0180	zj18 |
70g06zh0701c0	l070eh0830g03	80zj14 |
b0g06zh060180	l060eh1830g03	zk18 |
70g06zh060180	l060ch3830g03	zk14 |
b0g06zh0e0380	7671c71cf0e00e	0c38737e61803b	01dbc380zg18 |
70g06zh0c0301	ce33e33e30600c	3818373067c0e6	0738c180zg14 |
b0g06zh0fG030c	34634630600fe0	183b3068c1860c	30c180zg18 |
70g06zh0c0306	0c78678630c00c	3830!70f0c306	1830c3zh14 |
b0g06zh1c070c	1860660618801c	1830!60e08604	306062zh18 |
70g06zh18060c	1860c60c198018	1c70e060e1860c	306066zh14 |
b0g06zh1806!18	e0ce0c19g181c	60c060c18c0c!60	64zh18 |
70g06zh380e18	70c18c181bg38	3c60c0e1c18c3c	61c06czh14 |
b0g06zh300c18	b0c30c300eg!30	c180c5830c5862	c038zh18 |
70g06zh300c1f	34ce0ce00cg30	f0c980d9834f9a	7cd030zh14 |
b0g06zhfc3f0e	38f80f800cgGc0	71806183871c38	e030zh18 |
70g06zk018018	g18q60zh14 |
b0g06zk018018	g10q40zh18 |
70g06zk018018	g30qc0zh14 |
b0g06zk03g3001	a0p0680zh18 |
70g06zk07c07c	01c0p07zi14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06h0fXfezzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08h-5550	g06zzh14 |
b0g06h08h2a,aa	a8g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20k01	m08g06zzh18 |
70g06h08h40k01	m10g06zzh14 |
b0g06h08h20k0f	c0l08g06zzh18 |
70g06h08h40k0c	40l10g06zzh14 |
b0g06h08h20k0c	40l08g06zzh18 |
70g06h08h40k0c	40l10g06zzh14 |
b0g06h08h20k0c	40l08g06zzh18 |
70g06h08h40k0c	40l10g06zzh14 |
b0g06h08h20k0c	40l08g06zzh18 |
70g06h08h40k0c	40l10g06zzh14 |
b0g06h08h20k0c	40l08g06zzh18 |
70g06h08h40k0c	40l10g06zzh14 |
b0g06h08h20k0c	40l08g06zzh18 |
70g06h08h40k!7c	l10g06zzh14 |
b0g06h08h20j7f	fc7ffek08g06zzh	18 |
70g06h08h40i1f	f80c4007fcj10	g06zzh14 |
b0g06h08h20h03	f8g0c40g0fc0i	08g06zzh18 |
70g06h08h40h3f	80g0c40hf8i10	g06zzh14 |
b0g06h08h20hf0	h0c40h1ei08g06	zzh18 |
70g06h08h40g01	80h1c60h0380h	10g06zzh14 |
b0g06h08h20g03	i2c50ic0h08g06	zzh18 |
70g06h08h40g02	i2c50i60h10g06	zzh14 |
b0g06h08h20g07	i!30i20h08g06	zzh18 |
70g06h08h40g07	80h1fe0i30h10	g06zzh14 |
b0g06h08h20g06	c0h0540i70h08	g06zzh18 |
70g06h08h40g06	60md0h10g06zzh	14 |
b0g06h08h20g06	18l0110h08g06	zzh18 |
70g06h08h40g06	0el0610h10g06	zzh14 |
b0g06h08h20g06	0380k1c10h08g	06zzh18 |
70g06h08h40g06	gf0k7010h10g06	zzh14 |
b0g06h08h20g06	g1fj03c010h08	g06zzh18 |
70g06h08h40g06	g03f0i3fg10h10	g06zzh14 |
b0g06h08h20g06	h3fh17e8g10h08	g06zzh18 |
70g06h08h40g06	h07Ih10h10g06	zzh14 |
b0g06h08h20g06	i4ffe40h10h08	g06zzh18 |
70g06h08h40g06	n10h10g06zzh14 |
b0g06h08h20g06	n10h08g06zzh18 |
70g06h08h40g06	n10h10g06zzh14 |
b0g06h08h20g06	n10h08g06zzh18 |
70g06h08h40g06	n10h10g06zzh14 |
b0g06h08h20g07	n10h08g06zzh18 |
70g06h08h40g07	80m30h10g06zzh	14 |
b0g06h08h20g06	60m70h08g06zzh	18 |
70g06h08h40g06	30md0h10g06zzh	14 |
b0g06h08h20g06	1cl0110h08g06	zzh18 |
70g06h08h40g06	0780k0610h10g	06zzh14 |
b0g06h08h20g06	ge0k1c10h08g06	zzh18 |
70g06h08h40g06	g38k7010h10g06	zzh14 |
b0g06h08h20g06	g0fj03c010h08	g06zzh18 |
70g06h08h40g06	g01f0i7fg10h10	g06zzh14 |
b0g06h08h20g06	h3fh0fe0g10h08	g06zzh18 |
70g06h08h40g06	h07Ih10h10g06	zzh14 |
b0g06h08h20g06	i6fG40h10h08g	06zzh18 |
70g06h08h40g06	n10h10g06zzh14 |
b0g06h08h20g02	n10h08g06zzh18 |
70g06h08h40g03	n30h10g06zzh14 |
b0g06h08h20g01	80m20h08g06zzh	18 |
70g06h08h40he0	m60h10g06zzh14 |
b0g06h08h20h30	mc0h08g06zzh18 |
70g06h08h40h1c	l01i10g06zzh14 |
b0g06h08h20h07	l06i08g06zzh18 |
70g06h08h40h01	c0k1ci10g06zzh	14 |
b0g06h08h20i78	k70i08g06zzh18 |
70g06h08h40i0f	j02c0i10g06zzh	14 |
b0g06h08h20i01	d0i3fj08g06zzh	18 |
70g06h08h40j3a	h0ae8j10g06zzh	14 |
b0g06h08h20j07	I80j08g06zzh18 |
70g06h08h40k2d	f580k10g06zzh	14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h2a,aa	a8g06zzh18 |
70g06h08h-5550	g06zzh14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h0fXfezzh	18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06h07f0l0c	g030ei26g18g01	i60018806i0180	h03h30g0fc2g18
 06l20q14 |
b0g06h0210l84	g0104i42g08h80	h20g8002i1080	h01h50g042001
 0802k04r18 |
70g06h02m84g01	04i44g10h80h40	01g02i1080h01	h40g0420010804
 k04r14 |
b0g06h044edb60	cc98c583cb0c02	8830e380850610	cc98806b634039
 30e4c063607961	8038d26301e316	084cb796343730	1eb1831ecd8f38
 o18 |
70g06h07c36993	649322010d3202	88c924808e9923	649081b1a4c0ca
 132481b1a021a6	40cb624c808d88	0f84421a4cd910	24464c88469248
 o14 |
b0g06h04864912	24926402192602	489904g889322	24908113288082
 220f0113204324	c0822789808890	08c88432888910	4484c9908ca240
 o18 |
70g06h08049114	24a78402127804	51e0820108bc!24	a0822248810224
 0a021240424f01	04451e01109010	48842489112048	8f1e10892420o
 14 |
b0g06h08049224	45a40804124004	51g4101112044	45a10262490104
 440a0222408248	0104c510011120	10510824913120	31081021091810
 o18 |
70g06h08292a66	!c64805256404	319249011b3256	c6c102acab4195
 56528364a0a4ac	8195!59011b20	10950a4ab55540	410c992952a091
 o14 |
b0g06h1fc91383	0483880622380e	10e38e010c1c23	048101344580e2
 2391018440c447	ge2688e020c20	3f090c44589880	71070e309138e1
 o18 |
70g06j04q01j02	v02n8088j44p14 |
b0g06j04q01j02	v0am05g88j44p	18 |
70g06j0er80i04	v0cm06g70j38p	14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06h07f0g03	l0cm077e3070!3f	89f87ai30i40zm	18 |
70g06h0210g01	h10i0440l0221	106010a48884c4	i10g8008zn14 |
b0g06h02h02h10	i0840l022118a0	1084108504i10	g8008zn18 |
70g06h04418b02	830e782c61cc89	e7g3238600d6c	04422940210811
 09g19318b2673	c6bd8636zl14 |
b0g06h0786c407	4c922011924490	89g1249903634	047c29403e0821
 f2g0926c42491	1b109b1azl18 |
70g06h04844804	49904021320911	08g2441302264	04462a40280821
 02g0924487882	11211132zl14 |
b0g06h!084804	5e084023c10911	04g2423c04448	08824a80441042
 02g09!48504222	!2124zl18 |
70g06h!089008	90048042g9222	02g4812g4c4808	824c8044104202
 g0b4890502426	422224zl14 |
b0g06h080d900d	9924a0432496aa	92305a93205594	08844880421082
 03100d8d909525	2ad2b64a40zk18 |
70g06h1c061006	0e38c041c71b13	1c106ce1c02688	1df8e9c0e33887
 01e009061089c6	1361184440zk14 |
b0g06t20zzo18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h0fHzzy14 |
b0g06h083f83zzy	18 |
70g06h083f83zzy	14 |
b0g06h08g03zzy	18 |
70g06h0fHzzy14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223h	08zzv18 |
70g06h088889h	1czzv14 |
b0g06h022223h	3ezzv18 |
70g06h088889h	7fzzv14 |
b0g06h022223h	77zzv18 |
70g06h088889zzy	14 |
b0g06h022223j	0e70i07e1g0c03	j0c38h02zv18 |
70g06h088889j	0420i0210g8401	h04g0410h02zv	14 |
b0g06h022223j	0420i0210g8402	h04g0410h02zv	18 |
70g06h088889j	0841bb36660426	5bcb1a1b981e30	0a20c38e02zv14 |
b0g06h022223j	0fc6cc992207c2	210d266c8808d8	0a23249202zv18 |
70g06h088889j	08444891220464	4219!44881088	0922641002zv14 |
b0g06h022223h	0f7810!889124	08244212448890	11081147820802
 zv18 |
70g06h088889j	10899122240828	84124898902110	11440104zw14 |
b0g06h022223j	108ab32628084a	85255aaaa029b0	10c6492402zv18 |
70g06h088889j	39c4dc38101f84	86222c4c4030c0	38438e3802zv14 |
b0g06h022223l	204010l40zzi18 |
70g06h088889l	2040a0k0280zzi	14 |
b0g06h022223l	70e0c0k03zzj18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
7fGfezzzj14 |
a2!22zzzj18 |
68888azzzj14 |
a2!22zzzj18 |
68888azzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
bfZZZLf8 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
bfZZZLf8 |
/55/55/55/55"55	54 |
\enddata{raster, 270424108}
\view{rasterview,270424108,36,0,0}
\begindata{bp,270438440}
\enddata{bp,270438440}
\view{bpv,270438440,37,0,0}
After clicking on the cake:


\begindata{raster,270423948}
2 0 77083 77083 0 0 542 435
bits 270423948 542 435
/aa/aa/aa/aa"aa	a8 |
/55/55/55/55"55	54 |
bfZZZLf8 |
7fZZZLf4 |
bfZ27f9Gf9fcJ	!e7Jf93fJe7G9f	HfcS3fKf8 |
7fZ27f9G39fcJ	!e7Jf93fJe7G9f	HfcS3fKf4 |
bfZ27f9G39fcJ	!e7Jf93fJe7G9f	HfcS3fKf8 |
7e181fWfe6473	86099991"e1cf	070e48!f87323	c393c9cf20fc1c
 33cfe0S07c391	f178f274 |
bc4f9fWfe62!33	!3988"c4ce4626	22727133119989	c4cf22791993cf
 c8S139988e472	7078 |
7ccf3fVfe3667	33f338799ccc!cf	cce6!666733f3	39f99cce666733
 9f999f9cS39f9	9cce6733f4 |
bc0e7fVfc8667	338338799cc0!e1	cce60666673873	39c19cce666733
 9c199f9cS39c1	9cce6733f8 |
7cfe7fVfdcce7	273339339ccf!f8	9ce67e66673e27	39999cce76e733
 999dbf9cS3999	9cce6733f4 |
bcfcXfce72733	39339ccf!fc9c	e67e66673f2739	999cce70e73399
 9c3f9cS39999c	ce6733f8 |
7c49Xfce72703	29939c"c49e46	26667271273981	89c4f9e279181e
 79c8S13819ce4	7273f4 |
be181fWfce727	8999939c"e19f	270e6678f86739	c483c1f9e4fc9c
 4e79e4S27c49c	f078f3f8 |
7fZX9fcff9Ife	7fWfe7fGf4 |
bfZX9fcff3Ifc	Xcc7fGf8 |
7fZX9fcfe3If8	Xe0Hf4 |
bfZZZLf8 |
7fZZZLf4 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
68888azzzj14 |
a2!22zzzj18 |
68888azzzj14 |
bfGfezzzj18 |
707f06zzzj14 |
b07f06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zh0fc3f0	l0ff0i38g0380	zj18 |
70g06zh03gc0l	031c0ch18g0180	zj14 |
b0g06zh03gc0l	03!0ch18g0180	zj18 |
70g06zh0701c0	l070eh0830g03	80zj14 |
b0g06zh060180	l060eh1830g03	zk18 |
70g06zh060180	l060ch3830g03	zk14 |
b0g06zh0e0380	7671c71cf0e00e	0c38737e61803b	01dbc380zg18 |
70g06zh0c0301	ce33e33e30600c	3818373067c0e6	0738c180zg14 |
b0g06zh0fG030c	34634630600fe0	183b3068c1860c	30c180zg18 |
70g06zh0c0306	0c78678630c00c	3830!70f0c306	1830c3zh14 |
b0g06zh1c070c	1860660618801c	1830!60e08604	306062zh18 |
70g06zh18060c	1860c60c198018	1c70e060e1860c	306066zh14 |
b0g06zh1806!18	e0ce0c19g181c	60c060c18c0c!60	64zh18 |
70g06zh380e18	70c18c181bg38	3c60c0e1c18c3c	61c06czh14 |
b0g06zh300c18	b0c30c300eg!30	c180c5830c5862	c038zh18 |
70g06zh300c1f	34ce0ce00cg30	f0c980d9834f9a	7cd030zh14 |
b0g06zhfc3f0e	38f80f800cgGc0	71806183871c38	e030zh18 |
70g06zk018018	g18q60zh14 |
b0g06zk018018	g10q40zh18 |
70g06zk018018	g30qc0zh14 |
b0g06zk03g3001	a0p0680zh18 |
70g06zk07c07c	01c0p07zi14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06h0fXfezzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08h-5550	g06zzh14 |
b0g06h08h2a,aa	a8g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06h03c780j1c	06g0eg1czm18 |
70g06h08h40s10	g06h0183k0c06	g06g0czm14 |
b0g06h08h20s08	g06h0183k0ch06	g0czm18 |
70g06h08h40s10	g06h0183k08h44	g0ci40zi14 |
b0g06h08h20s08	g06h0306k18hcc	g08ic0zi18 |
70g06h08h40s10	g06h03060f5dce	ee301b9cefecc0	e83de303e3c0e3
 0f38c0x14 |
b0g06h08h20s08	g06h03fe338e67	36301ccc6d8de3	38ce63018ce063
 3398c0x18 |
70g06h08h40s10	g06h0306218c66	362018cc718e62	18866201886062
 2198c0x14 |
b0g06h08h20s08	g06h060c618c66	324018c8610c66	11862401186024
 619180x18 |
70g06h08h40s10	g06h060c63186c	334030d8c318c6	318c3403186034
 61b180x14 |
b0g06h08h20s08	g06h060c6318cc	63803198c318c6	318c3803184038
 613380x18 |
70g06h08h40s10	g06h060c77588c	4380311ac358d7	75dd38035cc038
 733dc0x14 |
b0g06h08h20k07	m08g06h0f1e19	9f0f81g5e1cc1	98e1986610018f
 g103c1980x18 |
70g06h08h40k02	c0l10g06k3018	03n30i30zg14 |
b0g06h08h20k01	20l08g06k3018	02n20i20zg18 |
70g06h08h40l90	l10g06k301806	n60i60zg14 |
b0g06h08h20l90	l08g06k783c1c	m01c0h01c0zg18 |
70g06h08h40k01	48l10g06zzh14 |
b0g06h08h20k01	48l08g06zzh18 |
70g06h08h40k02	48l10g06zzh14 |
b0g06h08h20k04	48l08g06h03c7	80j1c06g0eg1c	zm18 |
70g06h08h40k08	88l10g06h0183	k0c06g06g0czm	14 |
b0g06h08h20k08	90l08g06h0183	k0ch06g0czm18 |
70g06h08h40k11	10l10g06h0183	k08h44g0ci40zi	14 |
b0g06h08h20k11	20l08g06h0306	k18hccg08ic0zi	18 |
70g06h08h40k12	40l10g06h0306	0f5dceee301b9c	efecc0e83de303
 e3c0e30f38c0x	14 |
b0g06h08h20k12	40l08g06h03fe	338e6736301ccc	6d8de338ce6301
 8ce0633398c0x	18 |
70g06h08h40k0a	80l10g06h0306	218c66362018cc	718e6218866201
 8860622198c0x	14 |
b0g06h08h20k09	80l08g06h060c	618c66324018c8	610c6611862401
 186024619180x	18 |
70g06h08h40k05	m10g06h060c63	186c334030d8c3	18c6318c340318
 603461b180x14 |
b0g06h08h20k03	m08g06h060c63	18cc63803198c3	18c6318c380318
 4038613380x18 |
70g06h08h40k02	80l10g06h060c	77588c4380311a	c358d775dd3803
 5cc038733dc0x	14 |
b0g06h08h20k0f	c0l08g06h0f1e	199f0f81g5e1c	c198e198661001
 8fg103c1980x18 |
70g06h08h40k0c	40l10g06k3018	03n30i30zg14 |
b0g06h08h20k0c	40l08g06k3018	02n20i20zg18 |
70g06h08h40k0c	40l10g06k3018	06n60i60zg14 |
b0g06h08h20k0c	40l08g06k783c	1cm01c0h01c0zg	18 |
70g06h08h40k0c	40l10g06zzh14 |
b0g06h08h20k0c	40l08g06zzh18 |
70g06h08h40k0c	40l10g06zzh14 |
b0g06h08h20k0c	40l08g06h03c7	80j1c06g0eg1c	zm18 |
70g06h08h40k0c	40l10g06h0183	k0c06g06g0czm	14 |
b0g06h08h20k0c	40l08g06h0183	k0ch06g0czm18 |
70g06h08h40k!7c	l10g06h0183k08	h44g0czm14 |
b0g06h08h20j7f	fc7ffek08g06h	0306k18hccg08	zm18 |
70g06h08h40i1f	f80c4007fcj10	g06h03060f5dce	ee301b9cefecc0
 e83de3zk14 |
b0g06h08h20h03	f8g0c40g0fc0i	08g06h03fe338e	6736301ccc6d8d
 e338ce63zk18 |
70g06h08h40h3f	80g0c40hf8i10	g06h0306218c66	362018cc718e62
 188662zk14 |
b0g06h08h20hf0	h0c40h1ei08g06	h060c618c6632	4018c8610c6611
 8624zk18 |
70g06h08h40g01	80h1c60h0380h	10g06h060c6318	6c334030d8c318
 c6318c34zk14 |
b0g06h08h20g03	i2c50ic0h08g06	h060c6318cc63	803198c318c631
 8c38zk18 |
70g06h08h40g02	i2c50i60h10g06	h060c77588c43	80311ac358d775
 dd3830zj14 |
b0g06h08h20g07	i!30i20h08g06	h0f1e199f0f81	g5e1cc198e198
 661030zj18 |
70g06h08h40g07	80h1fe0i30h10	g06k301803n!30	zj14 |
b0g06h08h20g06	c0h0540i70h08	g06k301802n20	60zj18 |
70g06h08h40g06	60md0h10g06k30	1806n60zk14 |
b0g06h08h20g06	18l0110h08g06	k783c1cm01c0zk	18 |
70g06h08h40g06	0el0610h10g06	zzh14 |
b0g06h08h20g06	0380k1c10h08g	06zzh18 |
70g06h08h40g06	gf0k7010h10g06	zzh14 |
b0g06h08h20g06	g1fj03c010h08	g06o03fcj!f0h	06zh18 |
70g06h08h40g06	g03f0i3fg10h10	g06o0187j3020	h06zh14 |
b0g06h08h20g06	h3fh17e8g10h08	g06o018380i78	20zk18 |
70g06h08h40g06	h07Ih10h10g06	o018180i5860zk	14 |
b0g06h08h20g06	i4ffe40h10h08	g06o030180i5c	40zk18 |
70g06h08h40g06	n10h10g06o0301	8707aec04c43!87	9c1czg14 |
b0g06h08h20g06	n10h08g06o!03	!99c6c0"cc!8c	66zg18 |
70g06h08h40g06	n10h10g06o!03	1190c7gc6c8cc	!0c46zg14 |
b0g06h08h20g06	n10h08g06o0607	3330c6g869986	0608cczg18 |
70g06h08h40g06	n10h10g06o!06	3c318cg879e!03	18f0zg14 |
b0g06h08h20g07	n10h08g06o060c	30b18c01839851	9198c2zg18 |
70g06h08h40g07	80m30h10g06o06	38393bac01831c	!999ae4zg14 |
b0g06h08h20g06	60m70h08g06o0f	e01e0ccc03c10f	!1f1c78zg18 |
70g06h08h40g06	30md0h10g06zzh	14 |
b0g06h08h20g06	1cl0110h08g06	zzh18 |
70g06h08h40g06	0780k0610h10g	06zzh14 |
b0g06h08h20g06	ge0k1c10h08g06	zzh18 |
70g06h08h40g06	g38k7010h10g06	zzh14 |
b0g06h08h20g06	g0fj03c010h08	g06zzh18 |
70g06h08h40g06	g01f0i7fg10h10	g06zzh14 |
b0g06h08h20g06	h3fh0fe0g10h08	g06h03c780j1c	06g0eg1czm18 |
70g06h08h40g06	h07Ih10h10g06	h0183k0c06g06	g0czm14 |
b0g06h08h20g06	i6fG40h10h08g	06h0183k0ch06	g0czm18 |
70g06h08h40g06	n10h10g06h0183	k08h44g0ci40zi	14 |
b0g06h08h20g02	n10h08g06h0306	k18hccg08ic0zi	18 |
70g06h08h40g03	n30h10g06h0306	0f5dceee301b9c	efecc0e83de303
 e3c0e30f38c0x	14 |
b0g06h08h20g01	80m20h08g06h03	fe338e6736301c	cc6d8de338ce63
 018ce0633398c0	x18 |
70g06h08h40he0	m60h10g06h0306	218c66362018cc	718e6218866201
 8860622198c0x	14 |
b0g06h08h20h30	mc0h08g06h060c	618c66324018c8	610c6611862401
 186024619180x	18 |
70g06h08h40h1c	l01i10g06h060c	63186c334030d8	c318c6318c3403
 18603461b180x	14 |
b0g06h08h20h07	l06i08g06h060c	6318cc63803198	c318c6318c3803
 184038613380x	18 |
70g06h08h40h01	c0k1ci10g06h06	0c77588c438031	1ac358d775dd38
 035cc038733dc0	x14 |
b0g06h08h20i78	k70i08g06h0f1e	199f0f81g5e1c	c198e198661001
 8fg103c1980x18 |
70g06h08h40i0f	j02c0i10g06k30	1803n30i30zg14 |
b0g06h08h20i01	d0i3fj08g06k30	1802n20i20zg18 |
70g06h08h40j3a	h0ae8j10g06k30	1806n60i60zg14 |
b0g06h08h20j07	I80j08g06k783c	1cm01c0h01c0zg	18 |
70g06h08h40k2d	f580k10g06zzh	14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h20s08	g06zzh18 |
70g06h08h40s10	g06zzh14 |
b0g06h08h2a,aa	a8g06zzh18 |
70g06h08h-5550	g06zzh14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h08x06zzh	18 |
70g06h08x06zzh	14 |
b0g06h0fXfezzh	18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06h07f0l0c	g030ei26g18g01	i60018806i0180	h03h30g0fc2g18
 06l20q14 |
b0g06h0210l84	g0104i42g08h80	h20g8002i1080	h01h50g042001
 0802k04r18 |
70g06h02m84g01	04i44g10h80h40	01g02i1080h01	h40g0420010804
 k04r14 |
b0g06h044edb60	cc98c583cb0c02	8830e380850610	cc98806b634039
 30e4c063607961	8038d26301e316	084cb796343730	1eb1831ecd8f38
 o18 |
70g06h07c36993	649322010d3202	88c924808e9923	649081b1a4c0ca
 132481b1a021a6	40cb624c808d88	0f84421a4cd910	24464c88469248
 o14 |
b0g06h04864912	24926402192602	489904g889322	24908113288082
 220f0113204324	c0822789808890	08c88432888910	4484c9908ca240
 o18 |
70g06h08049114	24a78402127804	51e0820108bc!24	a0822248810224
 0a021240424f01	04451e01109010	48842489112048	8f1e10892420o
 14 |
b0g06h08049224	45a40804124004	51g4101112044	45a10262490104
 440a0222408248	0104c510011120	10510824913120	31081021091810
 o18 |
70g06h08292a66	!c64805256404	319249011b3256	c6c102acab4195
 56528364a0a4ac	8195!59011b20	10950a4ab55540	410c992952a091
 o14 |
b0g06h1fc91383	0483880622380e	10e38e010c1c23	048101344580e2
 2391018440c447	ge2688e020c20	3f090c44589880	71070e309138e1
 o18 |
70g06j04q01j02	v02n8088j44p14 |
b0g06j04q01j02	v0am05g88j44p	18 |
70g06j0er80i04	v0cm06g70j38p	14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06h07f0g03	l0cm077e3070!3f	89f87ai30i40zm	18 |
70g06h0210g01	h10i0440l0221	106010a48884c4	i10g8008zn14 |
b0g06h02h02h10	i0840l022118a0	1084108504i10	g8008zn18 |
70g06h04418b02	830e782c61cc89	e7g3238600d6c	04422940210811
 09g19318b2673	c6bd8636zl14 |
b0g06h0786c407	4c922011924490	89g1249903634	047c29403e0821
 f2g0926c42491	1b109b1azl18 |
70g06h04844804	49904021320911	08g2441302264	04462a40280821
 02g0924487882	11211132zl14 |
b0g06h!084804	5e084023c10911	04g2423c04448	08824a80441042
 02g09!48504222	!2124zl18 |
70g06h!089008	90048042g9222	02g4812g4c4808	824c8044104202
 g0b4890502426	422224zl14 |
b0g06h080d900d	9924a0432496aa	92305a93205594	08844880421082
 03100d8d909525	2ad2b64a40zk18 |
70g06h1c061006	0e38c041c71b13	1c106ce1c02688	1df8e9c0e33887
 01e009061089c6	1361184440zk14 |
b0g06t20zzo18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h0fHzzy14 |
b0g06h083f83zzy	18 |
70g06h083f83zzy	14 |
b0g06h08g03zzy	18 |
70g06h0fHzzy14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223h	08zzv18 |
70g06h088889h	1czzv14 |
b0g06h022223h	3ezzv18 |
70g06h088889h	7fzzv14 |
b0g06h022223h	77zzv18 |
70g06h088889zzy	14 |
b0g06h022223j	0e70i07e1g0c03	j0c38h02zv18 |
70g06h088889j	0420i0210g8401	h04g0410h02zv	14 |
b0g06h022223j	0420i0210g8402	h04g0410h02zv	18 |
70g06h088889j	0841bb36660426	5bcb1a1b981e30	0a20c38e02zv14 |
b0g06h022223j	0fc6cc992207c2	210d266c8808d8	0a23249202zv18 |
70g06h088889j	08444891220464	4219!44881088	0922641002zv14 |
b0g06h022223h	0f7810!889124	08244212448890	11081147820802
 zv18 |
70g06h088889j	10899122240828	84124898902110	11440104zw14 |
b0g06h022223j	108ab32628084a	85255aaaa029b0	10c6492402zv18 |
70g06h088889j	39c4dc38101f84	86222c4c4030c0	38438e3802zv14 |
b0g06h022223l	204010l40zzi18 |
70g06h088889l	2040a0k0280zzi	14 |
b0g06h022223l	70e0c0k03zzj18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06h022223zzy	18 |
70g06h088889zzy	14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
70g06zzzj14 |
b0g06zzzj18 |
7fGfezzzj14 |
a2!22zzzj18 |
68888azzzj14 |
a2!22zzzj18 |
68888azzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
a2!22zzzj18 |
60g02zzzj14 |
a8888azzzj18 |
60g02zzzj14 |
bfZZZLf8 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a7f0zzzk18 |
6118zzzk14 |
a108zzzk18 |
61047361c0zzzh	14 |
a104d9b220zzzh	18 |
61048913e0zzzh	14 |
a1048912zzzi18 |
61088912zzzi14 |
a118d91310zzzh	18 |
67f073b9e0zzzh	14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
a0zzzl18 |
60zzzl14 |
bfZZZLf8 |
/55/55/55/55"55	54 |
/aa/aa/aa/aa"aa	a8 |
\enddata{raster, 270423948}
\view{rasterview,270423948,38,0,0}


One the next page is the Ness script for the birthday card.  The image area at 
the top of the card has two named insets: "visible cake" is the raster on the 
left and to its right is a text inset called "song text".  The "visible cake" 
inset is extended so mouse clicks on it can be intercepted.

\begindata{bp,270475268}
\enddata{bp,270475268}
\view{bpv,270475268,39,0,0}
-- \bigger{\italic{Happy Birthday to Ness}} ! 

 

\italic{boolean} lit:= \italic{False}	-- "visible cake" is initially unlit

\italic{marker} Cakes := 
"\
\begindata{raster,270442384}
2 0 137084 137084 0 0 112 109
bits 270442384 112 109
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
l08m |
l08m |
l7em |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
k03e3e0l |
j03Ge3Gf0k |
jGc062g3fe0j |
i1fc0g62h7ej |
h01fch62h07c0	i |
h0780h62if0i |
h0cie3i1ci |
h18h016280h06	i |
h10h016280h03	i |
h38h018180h01	i |
h3ciGi0180h |
h36i2ai0380h |
h33m0680h |
h30c0l0880h |
h3070l3080h |
h301cle080h |
h300780j03!80	h |
h30gf8j1eg80h |
h30g1f80h01f8	g80h |
h30g01f8hbf40	g80h |
h30h3fHf8h80h |
h30h027ff2i80	h |
h30n80h |
h30n80h |
h30n80h |
h30n80h |
h30n80h |
h38n80h |
h3cm0180h |
h33m0380h |
h3180l0680h |
h30e0l0880h |
h303cl3080h |
h3007le080h |
h3001c0j03!80	h |
h30g78j1eg80h |
h30g0f80h03f8	g80h |
h30g01f8h7fh80	h |
h30h3fHf8h80h |
h30h037ffai80	h |
h30n80h |
h10n80h |
h18m0180h |
h0cm01i |
h07m03i |
h0180l06i |
ie0l08i |
i38l30i |
i0ele0i |
i03c0j0380i |
j78j16j |
j0e80h01f8j |
j01d0h5740j |
k3fHfck |
k016facl |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
\enddata{raster, 270442384}
\view{rasterview,270442384,40,0,0} 
 \
\begindata{raster,270422220}
2 0 137084 137084 0 0 112 109
bits 270422220 112 109
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
l38m |
l16m |
l09m |
l0480l |
l0480l |
l0a40l |
l0a40l |
l1240l |
l2240l |
l4440l |
l4480l |
l8880l |
l89m |
l92m |
l92m |
l54m |
l4cm |
l28m |
l18m |
l14m |
l7em |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
l62m |
k03e3e0l |
j03Ge3Gf0k |
jGc062g3fe0j |
i1fc0g62h7ej |
h01fch62h07c0	i |
h0780h62if0i |
h0cie3i1ci |
h18h016280h06	i |
h10h016280h03	i |
h38h018180h01	i |
h3ciGi0180h |
h36i2ai0380h |
h33m0680h |
h30c0l0880h |
h3070l3080h |
h301cle080h |
h300780j03!80	h |
h30gf8j1eg80h |
h30g1f80h01f8	g80h |
h30g01f8hbf40	g80h |
h30h3fHf8h80h |
h30h027ff2i80	h |
h30n80h |
h30n80h |
h30n80h |
h30n80h |
h30n80h |
h38n80h |
h3cm0180h |
h33m0380h |
h3180l0680h |
h30e0l0880h |
h303cl3080h |
h3007le080h |
h3001c0j03!80	h |
h30g78j1eg80h |
h30g0f80h03f8	g80h |
h30g01f8h7fh80	h |
h30h3fHf8h80h |
h30h037ffai80	h |
h30n80h |
h10n80h |
h18m0180h |
h0cm01i |
h07m03i |
h0180l06i |
ie0l08i |
i38l30i |
i0ele0i |
i03c0j0380i |
j78j16j |
j0e80h01f8j |
j01d0h5740j |
k3fHfck |
k016facl |
t |
t |
t |
t |
t |
t |
t |
t |
t |
t |
\enddata{raster, 270422220}
\view{rasterview,270422220,41,0,0} "

\italic{extend} "\bold{visible cake}"   \italic{on mouse} "any"

	\italic{if} mouseaction = mouseleftup \italic{then}

		lit := \italic{not} lit

		\italic{if} lit \italic{then}

		        showcake(FirstObject(

			    second(Cakes)))

		        sing()

		\italic{else}

		        showcake(FirstObject(Cakes))

		        replace(base(currentselection

			    (inset("song text"))), " \\n")

		\italic{end if}

	\italic{end if

end mouse   end extend}


\italic{function} \bold{showcake}(\italic{object} cake)

	raster_copy_subraster(cake)

	raster_select_entire(inset("visible cake"))

	raster_replace_subraster(inset("visible cake"))

	raster_center_image(inset("visible cake"))

\italic{end function}


\italic{function} \bold{sing}()

	\italic{marker} m

	m := last(base(currentselection(inset("song text"))))

	m := last(replace(m, "\\nHappy birthday to you\\n"))

	im_ForceUpdate()

	play_notes("L7 CC L4 DCF    E P4")

	m := last(replace(m, "\\nHappy birthday to you\\n"))

	play_notes("L7 CC L4 DCG   F P4")

	im_ForceUpdate()

	m := last(replace(m, 

		"\\nHappy birthday,\\n\\tDear Nessie\\n"))

	play_notes("L7 CC L4 >C <A  FED P4")

	im_ForceUpdate()

	m := last(replace(m, "\\nHappy birthday to you\\n"))

	play_notes("L7 A#A# L4 AF G  F.") 

\italic{end function}


In function showcake, the raster_xxx() functions are proctable entires defined 
by the raster inset.  The copy/replace sequence copies the cake to the cut 
buffer and then replaces the visible cake with the new image.


The text inset named "song text" initially contains a blank and a newline. 
 The expression currentselection(inset("song text")) returns a marker value 
for the currently selected portion of the text in this inset;  this will 
usually be the empty string at the beginning.  It is immaterial which marker 
value is returned because the base() function is applied to the value to get a 
marker for the entire contents of "song text".


im_ForceUpdate() causes the display to update to make visible the preceding 
change to the text.


The function play_notes() is inserted in the proctable by a package which 
interprets notes strings and plays them on the keyboard speaker in the IBM 
RT/PC.

\begindata{bp,270473516}
\enddata{bp,270473516}
\view{bpv,270473516,42,0,0}


\center{\bold{\underline{Appendix 2:  The Warning to novices}}}


The warning text given below is wrapped around a Ness script when it appears 
in a document for user perusal.  (The user may set a preference option to get 
a dialog box instead.  Such a user is presumed to know what he or she is 
doing.)


 _____________________


\bold{NESS} - This inset is a Ness script.  If you choose the 
\bold{\sans{empower}} option at the end of this inset, the script may alter 
the behavior of this window.  It may respond in new, useful, exciting, or 
bizarre ways to your mouse clicks, keystrokes, and menu selections.  


\bold{Warning: Empowering a Ness script is just like running a program.  The 
author of the script or program--if malicious--can write it in such a way that 
it can destroy your files.  If you do not trust the place or person from which 
you got this script, DO NOT EMPOWER IT.}


To learn what this script is supposed to do, you should read the surrounding 
document for a description.  Or, you can read the script itself if you are 
familiar with Ness.  After reading, you have four choices: do nothing, empower 
the script, "scan" it for potentially dangerous statements, or change it.  The 
last three options appear after the script.


To learn about Ness, give the command `help ness` or see the files in 
/usr/andrew/doc/ness.


\bold{\italic{---- The Ness Script ----}}


<< the script is nested here >>



\italic{\bold{---- End of the Ness Script ----}}


\bold{Your Options}


If you are uncertain whether to empower this script, the safest choice is to 
select NONE of the options below.  


Also safe is the \sans{\bold{\underline{Scan}}} option, which you can choose 
if you are familiar with the Ness language.  The scan highlights each 
statement in the script which might conceivably change this file or other 
files.  After choosing the Scan option, select the \bold{Next danger} item on 
the \bold{Ness} menu card to cycle through all the potentially dangerous 
statements.


If you know Ness and wish to modify the script, you can choose the 
\bold{\sans{\underline{Author mode}}} option.  If you do so, this help text 
surrounding the script will vanish and you will be able to edit the script. 
 You can select the \bold{Add warning} item on the \bold{Ness} menu card to 
get this help text back.


The final option is to decide to \sans{\bold{\underline{Empower}}} this 
script.  To do so means that you trust the author of the script and the person 
who gave you this file;  it also means you are aware that the script may 
change how the system responds to your actions.


\begindata{raster,270437928}
2 0 134521 134521 0 0 295 19
bits 270437928 295 19
ZVfe |
80zu02 |
80zu02 |
80jfci01c0h30	zh02 |
80i01cei03i30	o0cg60j18k02 |
80i0186i03i30	o0cg60j18k02 |
80i01c01c3c6e	078e1b01f1e370	7478d8e18c7807	9f3cf9e36e1e37
 3e78j02 |
80jf03e667703	1b1f037333b8dc	ecf9b18cec0ecc	6663b3bb!3b98
 ecj02 |
80j3c66066303	3198063033198c	ccc3198cc0!0c	0663"333198c0
 j02 |
80j0e603e6303	31980631f3198c	fcc3198c78078c	3e63f3333f3198
 78j02 |
80j0660666303	319806!33198c	c0c3198c1c01cc	66630333303198
 1cj02 |
80i0186!666303	319806!33198c	c0c3198c0cgcc	66630333303198
 0cj02 |
80i01dc3e7e63	031b180373f318	dcecc1b1dcec0e	cd7e6bb3333b31
 9aecj02 |
80jf81c3b6303	0e1801b1db187c	78c0e0ec780786	3b31e3331e318c
 78j02 |
80u0cy02 |
80t019cy02 |
80uf8y02 |
80zu02 |
ZVfe |
\enddata{raster, 270437928}
\view{rasterview,270437928,43,0,0} 

\begindata{raster,270421308}
2 0 134521 134521 0 0 295 19
bits 270421308 295 19
ZVfe |
80zu02 |
80zu02 |
80i60g03l0ch06	m1980g60j0ci02 |
80i60g63l0ch06	g06k19980c60j	0cg60g02 |
80if0g63l0ch06	g06k!180c60l60	g02 |
80i90c6fb!70d8	36!e07c78g0603	cf836e1e01e0f9	be1f6e1e01e0e3
 6cd8f8g02 |
80h0198c663b8	d8f83bb1b0dcec	g06076603bb3b	03b1b9980c773b
 03b1f3!ec60g02 |
80h0198c66319	8cc0!33198ccc	g!066603!3303	3319980c6333!03
 330cc660g02 |
80h030cc66319	8cc0!33198cfc	1f0607e603333f	03f319980c633f
 01e3030cc660g	02 |
80h03fcc66319	8cc0!33198cc0	g"06033330!03	19980c6330g73
 030cc660g02 |
80h030cc66319	8cc0!33198cc0	g"06033330!03	19980c6330g!33
 0cc660g02 |
80h!06ee6b18d8	c03331b0dcecg	06076683333b03	b1b99a0d633b03
 b1f30cec68g02 |
80h!0676331870	c03330e06c78g	07f3c303331e01	e0d98c06631e01
 e0e30cf830g02 |
80zrc0h02 |
80zrc0h02 |
80zrc0h02 |
80zu02 |
ZVfe |
\enddata{raster, 270421308}
\view{rasterview,270421308,44,0,0} 

\begindata{raster,270472568}
2 0 134521 134521 0 0 295 19
bits 270472568 295 19
ZVfe |
80zu02 |
80zu02 |
87f0n60k18o03	803018j60g02 |
86o!60h060318	o!063018j6003	02 |
86o!60h060318	o!0630l0302 |
86036e36071999	e360g60fb6c63	cf87db87807838	63363878038f0f
 b718f00f071b66	c7c2 |
8603bb3b0d999b	b3e0g6063ec67	66031dcec0ec6c	633e7cec06c606
 3b99d81d8f9f67	6302 |
87f3333198d99b	33h60630c6606	0318cc!c0c663	30!cc0c660631
 99801819986633	02 |
8603333198cdb3	f301f060630c63	c60318cfc078c6	6330c0fc0c6606
 3198f00f!1866	3302 |
8603333198cdb3	03h60630c60e6	0318ccg1cc663	30!c00c660631
 98380398186633	02 |
8603333198c663	03h60630c6066	0318ccg0cc663	30ccc00c660631
 98180199986633	02 |
8603333b0d8663	b3h606b0ee766	8358cec0ec6c77	307cec06c606b1
 99d81d8f986763	42 |
87f3333e070661	e3h60330763c3	0198c78078383b	30387803860331
 98f00f071867c1	82 |
80h30zp06g02 |
80h30zp06g02 |
80h30zp06g02 |
80zu02 |
ZVfe |
\enddata{raster, 270472568}
\view{rasterview,270472568,45,0,0} 
           \
\begindata{raster,270520980}
2 0 134051 134051 0 0 34 22
bits 270520980 34 22
k |
k |
k |
k |
k |
g404608g |
01c0fc18g |
07808810g |
!011e30g |
023213e0g |
02642041g |
06e820c7g |
033040f8g |
h8040g |
h80h |
g01i |
g02i |
gc4i |
g98i |
gf0i |
k |
k |
\enddata{raster, 270520980}
\view{rasterview,270520980,46,0,0} \fullwidth{

 \
}\enddata{text,270332748}
