THE WORKLITE COLLABORATIVE WORD PROCESSOR

eyelashesnectarineΛογισμικό & κατασκευή λογ/κού

3 Νοε 2013 (πριν από 3 χρόνια και 8 μήνες)

107 εμφανίσεις












THE WORKLITE COLLABORATIVE WORD PROCESSOR

by

Aron Fay and Bob Waldrop

ECE 345

Jon Benson

12/7/99

Project #27

ii

ABSTRACT


A collaborative word processor allows multiple users to work simultaneously on one or more
documents. Research in collaborat
ion has proven to be an exciting, growing area and is now being
incorporated with word processing. By taking advantage of the latest Java Swing libraries and standard
Java networking classes, the
WorkLite

word processor provides a fine example of a single

server,
multiple clients implementation of such collaborative efforts. This paper provides a discussion of how
the
WorkLite
word processor addresses topics such as reliability, synchronization, revision control and
threading of network components. Alte
rnative techniques for handling these measures are also
discussed.


iii

TABLE OF CONTENTS


PAGE

1.

INTRODUCTION

................................
................................
................................
...........

1

2.

DESIGN PROCEDURE

................................
................................
................................
..

2


2.1

Java

................................
................................
................................
......................

2


2.2

Swing

................................
................................
................................
...................

3


2.3

Thread use

................................
................................
................................
............

4


2.4

User locks / Version Control
................................
................................
................

5


2.5

Lowpass Amplifier
................................
................................
...............................

7

3.

DESIGN DET
AILS

................................
................................
................................
.........

8


3.1

Graphical User Interface (GUI)

................................
................................
...........

8


3.2

Features to be implemented

................................
................................
.................

8


3.3

Serialization

................................
................................
................................
.........

11


3.4

Lowpass Amplifier
................................
................................
...............................

11

4.

DESIGN VERIFICATION

................................
................................
..............................

14


4.1

WorkLite

................................
................................
................................
...............

14


4.2

Lowpass Amplifier
................................
................................
...............................

14

5.

COSTS

................................
................................
................................
.............................

16

6.

CONCLUSIONS
................................
................................
................................
..............

17


REFERENCES

................................
................................
................................
................

18


APPENDIX 1. TABLES AND SCREEN SHOTS

................................
.........................

19

1



1. INTRODUCTION

The motivations behind building the networked word processor are twofold. First there is a need
for an environment which promotes collaboration without requiring face
-
to
-
face interaction. Secon
d,
work combining these two components is still open to research. If an efficient scheme can be utilized to
unite these standard computing units then surely something useful will be the result. Clearly, this is not
a simple undertaking, nor is it one tha
t two students would effectively bring to market on the level of an
actual hard product, for even large corporations such as Corel have difficulty competing in this market.
The collaborative word processing concept can be roughly proven by building a simp
le front end
containing common word processing features, and combining it with a client/server networking
component. This work also provides a means by which to introduce the concept to an already
established firm in an attempt to sell the intellectual pr
operty.


In the original proposal it was suggested that the
WorkLite
team would build a networked system
containing the word processor front end, an underlying networking package, a registry service for
adding new users, a database for files and a system o
f revision control for the file database. In addition,
the circuit design project required for software projects was assigned. The software design goals were
stated loosely, if for no other reason than it was not certain whether tools were available to m
eet them.
All of the goals planned for the package were provided for at a significant level.



2

2. DESIGN PROCEDURE



Three significantly large projects were brought into one, thus increasing the complexity of the
design. These three components are the
user interface, the network interface and tools, revision control,
and finally the hardware circuit requirement. If enhanced, each of these parts could have been expanded
into their own stand alone project. Each component was scaled to a reasonable level

while still
producing a quality tool.


2.1 Java


The first issue that needed to be addressed was that of determining which software platform or
platforms we wished to support as well as what standard development package to use. Though a
commercial prod
uct might approach the development completely from scratch on all component levels,
this was not feasible given the time constraints. Common tools such as sockets would have to be built,
requiring several levels of development. On nearly all major platfo
rms, these tools are provided in
various degrees. Superceding them all is the Java platform which boasts nearly seamless interaction
from the developer's point of view with underlying OS's and constructs (again the network socket is an
example). The add
ed feature of cross
-
platform compatability as well as experience in the group with
developing Java tools made this an appealing approach.

Java is a powerful tool for development but the choice of Java always opens the door to a set of
issues. The most
fundamental is determining which major version to use (there are currently three
relatively backwardly compatible versions with several forwardly available feature differences
--
1.0, 1.1
and 1.2) based on performance and features. The 1.2 version is still
considered beta and is generally not
browser compatible (required for an applet version of the project) while the 1.0 version lacks certain
networking and Swing library compatibility features (see below concerning Swing). We therefore chose
the 1.1 becaus
e of its nice mix of features and stability.



3

2.2 Swing


Unfortunately, core Java tools are still very basic in nature and provide only one relatively poor
tool for use as a building block for the text processing element required in a word processor, so
again we
were forced to search for an extension to Java platform fundamentals. The Swing 1.1.1 GUI interface
(released just this summer) was the answer to a broad set of these problems because it provides several
features with decent reliability. Swing i
s problematic because it is an extension and not a reworking of
the standard 1.1 Java Development Kit (JDK) windowing tools mentioned above. The current
maintainers and updaters of Java developed Swing because there was a need for an improvement to the
ba
sic Abstract Window Toolkit (AWT), the fundamental windowing building block in the JDK. But the
need to maintain backward compatibility among Java versions as well as the complexity of rewriting the
fundamental layers, caused the lead engineers at JavaSof
t to make Swing an extension instead of a core
Java improvement. This decision has its benefits in that it provides a better set of more extensible
components for developers, but is poor in that it resulted in the creation of significant bugs and more
imp
ortantly did not yield a "thread safe" [1] framework. In the core Java framework (the AWT) window
events are queued onto a special First In First Out (FIFO) event queue and maintain a good ordering
across threads. In some cases, Swing components override

this for the development reasons mentioned.
Though tools to combat thread locking and erroneous callbacks are available in the Swing package, the
circumvention of the event FIFO has introduced some significant constraints for the end developer.


The posi
tive upshot of all of the above decisions was a very complete set of tools with several
features. The downside is that several of the tools in the Swing package contain bugs pivotal to our
work. There are undoubtedly ways to work around these problems, a
s we demonstrated, but features
such as color highlighting and cursor positioning which are pertinent in any word processor, especially a
collaborative one, are quite difficult as a result.


Beyond the issues of toolkits and packages, planning the user i
nterface brought several questions
regarding scope and feasibility which we filtered through the funnel of the project's focus. Since our
goal was to provide a networked tool, we had a time constraint and the principal point of engineering in

4

the project
was not a complex user interface, we did not implement several standard word processor
features and also chose not to do a rewrite of Swing components or an extension of other components.
Some of these features include spell and grammar checking, drawing
tools and art packages, bulleting
and other layout formatting, more advanced printing services, highly extensible look and feel, a variety
of file format parsers, web support and so on. It is important to note that with the exception of some of
the layout

editing features, all of the above are not pivotal in demonstrating the networked interaction of
the product. Layout editing, however, is an interesting issue which would need to be addressed in a
commercial product since it is necessary and popular.


Ne
tworks contain many complex issues including threading, queueing of data, connection
handling and storing. Again Java was the answer to this problem by providing a reasonably high level
abstraction for client and server socket creation and data serializat
ion.


2.3 Thread Use


The fewer threads used the better; not just from the perspective of performance, but also for the
sake of dependability. Independent threading of the CPU resource is complex and inter
-
thread
communication is even more so. Initial
ly we planned to reduce the number of threads to at most two
extra (on top of built
-
in AWT threads) per end point. Many complexities come from the fact that some
obvious errors still exist in the Java thread model. One such problem is evident in certain

monitoring
functions. For example, subclasses of the Java Thread class inherit a method isAlive() [2] which is
intended to communicate the live status of a thread to the thread monitor. In practice, problems arise
because dead or dying threads may give
unexpected or misleading responses. Java threads also overly
allocate resources.


Of interest was the allowance of multiple (boundless if possible) clients for any given document.
Thus use of a centralized server was more logical than multicasting clie
nts. Java support for
multicasting is not supported except for already created multicast groups [3]. To provide a reasonable
level of security and to facilitate the use of applets, which require that all resources be arbitrated or

5

specially handled for s
ecurity reasons, the decision was made to have all files saved to a server
-
side
repository as shown in Fig. 1.

(All figures appear at the end of the report.)

In practice, using an applet
version of the
WorkLite
is not recommended because network latencie
s and other performance issues
associated with applets (which must be downloaded and are usually run in restricted mode in a browser)
would not allow efficient word processing. A multicast implementation was of interest, but would have
required that all c
lients maintain a total ordering of network messages and act as servers for clients
which wish to be added to the group. The multicast approach also would create large security issues.


2.4 User locks / Version Control


A perfect collaborative word proce
ssor would not only be powerful, but also easy to learn and
use. To approach this goal, we needed to introduce no more than a minimal number of foreign tools to
the user.


The display of a target document must show the current stage of document producti
on. If the
user is unsure whether or not a document section is editable, then writing time will be lost while trying
to make such a determination. All locking information must be seen at face value by the user.


Lastly, the response of the program to the

user must be as predictable as possible. A word
processor which decides for the users what they want is not only frustrating, but is cause for
inefficiency. Accidental data loss is definitely a possibility considering the complexity of collaborating
mul
tiple users, therefore, reliability is a major concern.


As we looked at the complexities of these problems, we decided to spend more than 60% of our
project time in the design phase. As each proposal regarding features was brought up, we would discuss
th
e ramifications of adding this particular feature to the total package.


One of the many features that we rejected, based on these constraints, was the presence of
"whole
-
document attributes" in the master document. The benefits of these features would b
e a
standard printing format for each page. If a user found that a change in margins needed to be made to
meet a requirement, they would be able to do so. However, the same things that make this feature useful

6

show the problems associated with its implem
entation. If two or more users disagreed on the general
format of the document, it might change so often that the document may no longer be manageable. The
only solution to this would be to enforce a "super
-
user" who would make all final decisions on the
se
issues. However, adding the complexity of a super
-
user would violate our promise of a product that is
easy to use. The current design also provides more flexibility by giving each user the same priority. An
alternative is to allow clients to set thes
e values according in local preferences.


The design brought to the design review said that an atomic piece of each document would be a
line. This means that if a user needed to change any portion of a line, the whole line would need to be
reserved under
their name. We originally thought that we could not complete this project in time, unless
we simplified it with this constraint. The desired atomic level was a single character. This would allow
the most flexibility among users, and would make the learn
ing process for new users simpler. As we
progressed in the specifics of the design, we found a way to remove this larger constraint. We felt that
adding a feature of this quality would justify modification of our original design.


Another change that was

made was the method of revision control. Though we did not commit
to it, we originally had an interest in utilizing the eXtensible Markup Languange (XML) as our medium
for revision control, and as our document format for permanent storage. This was not
completed, but the
serialization scheme we use for client/server communication allows for cross
-
platform, extensible
revision control by developers. Many of the commercial word processors today have proprietary
revision control systems. For example, Micr
osoft Word


has an option to commit the current revision
to disk. This makes it questionable whether we should put substantial effort into developing our own
revision control file format.

The last major design decision that had to be made was a method of

synchronization. The
current design gives a unique number to each keystroke or other action. This allows a single ordered
representation to be made from the keystrokes and simplifies many of the problems with
synchronization.



7

2.5 Low
-
pass Amplifier


The low pass amplifier design had few requirements. The amplification factor and cut
-
off
frequencies needed to meet a standard of 5% accuracy. Quality requirements (e.g. drop
-
off rate) were
not made. To best fulfill the given requirements and keep the d
esign simple, a first order, dual stage
amplifier was built using operational amplifiers.



8

3. DESIGN DETAILS

3.1 Graphical User Interface (GUI)


There are several features to the
WorkLite
package that are of interest. The GUI was designed as
a wrapper

around the network layers of the program. This lends to a great deal of pluggability and
reusability of the
WorkLite
code. The GUI is complex enough to test a variety of different schemes of
underlying components. Changing the network scheme, for examp
le, only requires the insertion of very
simple calls into the event functions of the GUI. The client
-
side networking component (the LiteCaster)
is plugged into a stand
-
alone interface, allowing non
-
collaborative editing. Non
-
networked experiments
with re
vision control are also a possiblility using the WorkLite UI.


The WorkLite UI is very editable as most features including color swatches, available fonts and
font sizes, menu text, and images for buttons are determined at program startup from a user edita
ble
properties file. Values can also be set after startup as shown in the case of color in Fig. 4
(All figures
appear at the end of the report.)
. The startup properties file can be set to reference or contain locale
specific information, so that users of

any Unicode compliant language can personalize the interface,
their fonts or language preference. Applet versions of the WorkLite are limited to only system available
fonts due to Java security controls (unless the remote user has pre
-
configured the clie
nt and set up a
special properties file on the server). These security rules also made it reasonable to use an internal
clipboard [4] for copy and paste, for applets are not allowed to access system clipboards. This Java
security restriction makes sense
as it is possible that clipboards contain sensitive information such as
credit card numbers and other personal information.


3.2 Features to be implemented


Due to the limitations of the Swing API, several features that were originally of interest were no
t
incorporable. The most disappointing handicap was the lack of standard support for the highlighting of
collaboration mode user entries into the document. Text attributes in Swing's JTextPane class, the most
useful tool from the Swing package for the
Wo
rkLite

development, are held in one class type

9

appropriately called the AttributeSet. When these attributes are serialized and return from the server,
the attribute of background color (not foreground) returns poorly, whereas; the superscripting attribute

(which we chose for sake of the demo) returns appropriately. In all fairness, if we had been expert
Swing developers before taking on the project, we might have been able to for see the need for work
-
arounds and implement them. Though the mentioned attr
ibute bug seems very provable, issues in the
complexity of serialization of the attribute data may be more simple to adjust than they appear.


The following standard word processing elements were implemented due to their ease in
development or there releva
nce to the other project components: font families, sizing, color
(foreground), formatting (including bolding, italics, underlining), copy and paste, insertion, deletion,
save and open, and more. All of these features require that special collaborative m
ode events be sent to
the server as well as be multiplexed to each listening client, if so authorized by the server. Each text key
action, copy event, or image insertion corresponds to a generic insertion event. Cut and deletion
oriented key events corre
spond to an abstract removal event. More complex editor events use a
combination of the two fundamental event types. In the case of an insertion into already selected text,
for example, the client sends a request for a removal event followed by a request

for an insertion event.

All editor events are packaged into a LiteElement data type. This element contains the text and
the attributes for the given insertion event as well as offsets that allow for high speed adjustment of the
size of the element. The
alternative to endpoint offsets is to actually adjust the characters of data in the
element as opposed to simply decrementing the integer endpoints useful for later processing. The data
adjustment approach requires significant memory allocation for each a
djustment and would be a serious
performance hit. The server does not actually use the endpoint data but a future implementation of the
WorkLite
might use it for more complex revision control or a look ahead style scheme to decrease the
network latency of

each editor event. The protocol selected for communication is very extensible and
usable even in its current state because of the nesting data types described below.

Interestingly, a paste event, regardless of data length, is equal to a single text eve
nt in terms of
the number objects used. This seems to be a major waste of data space for character events as

10

mentioned, however greatly eases the development. It is possible that a better implementation would
be to use two sets of clients and servers. O
ne for heavier weight objects and another for simple
character events. This increases the complexity of keystroke communication significantly by causing
the ordering of received objects to become an issue. Time stamps could be used to circumvent some of
the problems but overall client and server processing will still be increased for each event. The question
of which approach to use becomes related to the type of network and processing resources available. In
either case, adding a second connection betw
een the client and server is usually frowned upon by the
software community in part because of the wide variety of low
-
bandwidth, single connection networks
that are currently employed (point to point, for example).


Client events that are not editor relat
ed such as requests for the saving and opening of files,
adding of users, viewing of document options from the data repository and the removal of user locks are
handled similar to the editor events. Once the editor event has been categorized by the client
’s event
model, the pertaining data is packaged into a single data type (regardless of the content) called a
LiteObject. The LiteObject contains the event type, the length of the data and the content. All network
communication is via serialization of Lit
eObjects. This clearly simplifies the network level
communication, but is not optimal in terms of performance from the standpoint of network packet size.
Overall using the LiteObject type is not a significant performance hit if it is a hit at all. Data
members
of the LiteObject class that are not used by a client/server message are nullified and so are very
lightweight, and more importantly the use of one communication data type clearly decreases the amount
of demultiplexing and type checking required by

the client and server. As it is, the server avoids heavy
type checking by using the action identification number in a received LiteObject.


Once a
WorkLite
client establishes connection with the LiteServer, the connection is cached in
the server and two
queues for the client are created (again by the server). As mentioned all data for
communication is in the form of LiteObjects, so the FIFOs only contain references to LiteObjects. The
client works similarly after a connection by using a LiteObject FIFO
for incoming commands from the
server. Though a more robust implementation might also contain an output FIFO for the clients, our

11

implementation avoids the use of one because outgoing requests to the server are event based and so
are predictable whereas t
he network when viewed as a queue is not predictable. User events are handled
immediately except in situations of overflow (thus the reference to the use of an out FIFO in a
commercial level application) whereas networks send events seemingly at their lei
sure. The AWT
(which pertains to us because it supports Swing) provides, in effect, a queue for outgoing events for the
WorkLite because it places events on a special event stack. Unfortunately, this stack is not effectively
used by Swing in the placemen
t of the editor's carot positions, so in cases of high speed typing, the
placement position of the carot becomes incorrect. Several work
-
arounds were attempted to no avail.


3.3 Serialization


Serialization was a key component to this project. Java allo
ws any class to be serialized, as long
as each component in the class is serializable. However, we had some problems with the way that Java
implemented this, so we occasionally would need to redesign the serialization procedure for various
components. Al
so, since not all components were in a form which could be efficiently broadcast over a
network, some components actually needed to be broken down, and sent in smaller pieces, so that
redundant information would not flood the network. Many of these consid
erations did not come up until
we were past the design phase of this project. Fortunately, all the serialization issues seemed to be
solved in time for our presentation.


3.4 Low
-
pass Ampifier


The design of the low pass amplifier was broken into two st
eps. First, a low pass filter was built.
The design used would allow for a maximum amplification factor of one. The output of this filter was
then passed into a standard amplifier. The design of this circuit can be seen in Fig. 2
(All figures appear
at

the end of the report.)
. The final output would be



12


total
A
A
A


1
2

(1)


where
A
1

is amplification factor of the filter, and
A
2

is the amplification made by the second stage of
the circuit. The equation
s specifying
1
A

and
2
A
are below:


1
1
1
1
A
R
s
C




(
)

(2)


2
3
2
1
A
R
R



(3)


The frequency response of this circuit would be determined by the values of
1
R
and C. Specifically,



1
1
2
R
C
f







(4)


Since we had a capacitor on hand with a value of 96.9 nF, we chose the values of the rest of the
components to work with it. Specifically, eq. 4 specified R1 to be 265 ohms. Putting these values into
eq. 2, we found the am
plification factor to be


A
j




1
1
2
54
5

.


(5)


This value was equal to one when the frequency was zero. Using this, we chose R2 and R3 so that A_2
would be 6.4. We found resistors with values of 9.87 kOhms and 54.86 kOmhs. These were used as R2

and R3, respectively.



13

The last requirement was to make the input resistance of the circuit equal to 500 ohms, when the
frequency of the input signal was 1 kHz. We based our decision on what the current input resistance
was. The resistance followed th
e equation below.




(6)


Complex arithmetic shows this value to be 16.65 ohms. Since

was greater than the
desired value of 500 ohms, we inserted a resistor
as shown in Fig. 2. Inserti
ng the
resistor in such a way would not change the frequency response of the circuit, but only draw more
current from the source. This was the desired effect.



= 500

(7)


Using the above equation, we found
715 ohms to be the desired value for R4. The decibels of a current
point is calculated from the voltage at that point using the following formula:



14



(6)


Since the maximum output is 3.2v, the cut
-
off frequency would be 3dB below th
is point.




(7)


Using Eq. 6, we can see this point would be at 2.26V. Using the data in Table 2

(All tables appear at the
end of the report.)

contextually with the shape of the curve, we can see that this point was at
approximatel
y 5.3 kHz. This is within 4% of the desired cut
-
off frequency.



15

4. DESIGN VERIFICATION

4.1
WorkLite


To test the software project, we needed to see that all of the features we supported were
implemented correctly, and that the services provided were rel
iable. We decided
not
to keep a careful
record of the number of times we ran the program. This is because simple program execution does not
necessarily qualify as a test. However, whenever we added a new feature, we tested it and related
services. We h
ave kept a careful count of crashes since we had a final product running. We split the
types of tests into three categories.


The first type of test we did was to be sure the client was crash safe when not connected to a
server. Of all the times we have
ran the client as a standalone, we have never had it crash.


The second type of test was to run a server along with one or more clients, and verify that no
crashes occur. After many heavy duty tests were performed, we only had the combined systems crash
t
wo times. Both of these times, it was the server that crashed, and then the clients followed.


The third type of test performed involved the testing of individual components and features.
Some components, we could test alone from the whole package, to
see if it was ready to be added.
Many of our features were added one at a time, to aid in debugging. In these tests, we had many fails. It
is common to build a bad feature, and find the bug after first trying it with the whole package. Nearly
all of th
ese bugs have been fixed. The ones that we have not yet fixed are not crucial to the project, and
have been left as unsupported features.


4.2 Low
-
pass amplifier

The hardware design project had a more specific testing procedure. This procedure was
dev
eloped during the time of our design, and was as follows:


16


First, equipment was acquired. This included a 12 volt power supply, our completed circuit on a
bread board, an oscilloscope, and the PM 5139 function generator. Next, we would connect the funct
ion
generator and power supply to our circuit. The oscilloscope would be setup to monitor both the input
function generator, and the output from our circuit. The following parameters were placed into the
function generator:












Sinusoidal wave

The output voltage (peak to peak) was then measured to determine the amplification from our circuit.

We stepped through several input frequencies in the range from 0.1 kHz to 150 kHz. W
e chose
frequency points to measure in a fashion promoting an even graph along a logarithmic scale. This data
appears in Table 2. The current through the circuit was measured when the frequency was held at 1kHz
to find the input impedance. To find the c
ut
-
off (3dB) point, we used formula (6) above. We were
accurate within 4% of the desired value. To find the rate of drop off, we entered the 11 kHz point and
110kHz point into eq. (6). The difference between these points was the drop
-
off per decade and
the
value found was 20.8 dB / decade. This was near the theoretical expectation of 20dB / decade for first
-
order circuits. Results are available in Fig. 3.


17



18

5. COSTS



The projected expenses given in the project proposal are seen in Table 1
(All tables
appear at the
end of the report.).
The total development time was significantly greater than projected. We imagine
around 250 to 300 hours. Another added expense was the purchase of Java books to aide in
development. This totaled approximately $150. G
iven the rate above for man hours we project the total
project cost was roughly $92,000. If this is a correct approximation (this is probably on the low side),
then our project was a fairly decent success. Experienced Swing developers might have decrease
d the
development time, but would probably demand a greater hourly wage.





19

6. CONCLUSIONS




Through the use of the Java Swing libraries and Java network APIs we were able to create a
fairly powerful collaborative word processor and test tool. If improv
ed to meet market demands in
features and performance, such a package would likely be very marketable in the current economy.
With the advantage that our program runs on the three main operating systems: Windows, MacOS, and
Linux, the system would be more

powerful than almost anything that is on the market today.


20

REFERENCES

[1] David M. Geary,
Graphic Java, Mastering the JFC, 3rd Ed., Vol 2.
Palo Alto: Sun Microsystems,
1999, pp. 57
-
69.

[2] Scott Oaks & Henry Wong,
Java Threads
. Tokyo: O'Reilly & Ass
ociates, Inc., 1997, pp. 33.

[3] Elliotte Rusty Harold,
Java Network Programming
. Tokyo: O'Reilly & Associates Inc., 1997, pp
325
-
346.

[4] David M. Geary,
Graphic Java, Mastering the JFC, 3rd Ed., Vol 1.
Palo Alto: Sun Microsystems,
1999, pp. 670
-
672.

[
5] David Flanagan,
Java in a Nutshell, 2nd Ed.
Tokyo: O'Reilly & Associates, Inc., 1997
.


21

APPENDIX 1.














Fig. 1 High level client/server flow chart



Fig. 2 Final filter circuit diagram


22


Fig. 3 Charted data for the lowpass filter


Fig. 4 C
olor swatch dialog box from the LiteClient
Low Bandpass Filter / Amplifier
0
0.5
1
1.5
2
2.5
3
3.5
0.05
0.5
1.5
2.5
3.5
4.5
5.5
Input Frequency
Output Voltage

23

Table 1: Expected costs for developing such a project

Requirement/Units

Cost per unit

Total Cost

3 X Pentium II class
computers with monitor,
keyboard, network adapter
and mouse

$1200

$3600

Network access (T1
c
onnection)

㌠畳3牳渠
e獴慢汩s桥搠湥瑷潲t

␷$

␲㈵

䑥癥汯灭e湴⁴業e
ㄴ
桯畲猠瑩he猠瑷漠灥牳潮猩

␴$

␱ㄲ〰

Sy獴敭⁁摭s湩獴牡瑩潮⁡湤n
浡楮瑥湡湣e c潳瑳
㔰
桯畲猩

␶$

␳〰$

Be湥晩瑳f呡xe猯佴se爠
ex灥湳n猠景s⁥ac栠h浰moyee
⡩湣汵摩湧⁳y獴敭⁡摭d温

␲〰〰

␶〰〰

Pa楤ea癥
湯琠楮捬畤 搠d渠
扥湥晩瑳⤠㔠摡y猠se爠
e浰moyee

␴〠堠㐰⁨$献⁤s癥汯灥牳

␶〠堠㐰⁨$献⁳y猠a摭dn

␴〰$

呏呁L⁣潳o


␸㈰㈵


呡扬攠㈺†

L潷oa獳⁦楬se爠r牥煵qncy⁶献畴灵琠癯p瑡te⁤ ta

I湰畴

F牥煵e湣y
⡫楬潨(牴r)

併瑰畴O
噯汴慧s
⡶潬瑳(

I
湰畴

F牥煵e湣y
⡫楬潨(牴r)

併瑰畴O
噯汴慧s
⡶潬瑳(

I湰畴

F牥煵e湣y
⡫楬潨(牴r)

併瑰畴O
噯汴慧s
⡶潬瑳(

〮0

㌮3

㠮8

ㄮ1



〮㔵

〮0

㌮3

㤮9

ㄮ㘵



〮㐷0

〮0

㌮3

㤮9

ㄮ㔵



〮㐱0

〮0

㌮3



ㄮ1



〮㌷0

ㄮ1

㌮3



ㄮ㌸



〮㌲0

ㄮ1

㌮〵



ㄮ㌰



〮㈹
0

㈮2

㌮3



ㄮ㈰



〮㈶0

㈮2

㈮2



ㄮㄵ



〮㈴0

㌮3

㈮㜵



ㄮ〸



〮㈲0

㌮3

㈮㘵



ㄮ〰



〮㈰0

㐮4

㈮㔰



〮㤵



〮ㄸ

㐮4

㈮㐰



〮0



〮ㄷ

㔮5

㈮㈸



〮㠷



〮ㄶ

㔮5

㈮2



〮㠲

㄰1

〮ㄴ

㘮6

㈮2



〮㜹

ㄱ1

〮ㄲ0

㘮6

㈮2



〮㜵

1


〮ㄱ0

㜮7

ㄮ1



〮㜲

ㄳ1

〮㄰0

㜮7

ㄮ㠲



〮㜰

ㄴ1

〮〸0

㠮8

ㄮ㜵



〮㘹

ㄵ1

〮〷0



24