[comp.sources.amiga] v89i074: diskchecker - check a disk for errors

page@swan.ulowell.edu (Bob Page) (03/17/89)

Submitted-by: chk@gpu.utcs.toronto.edu (C. Harald Koch)
Posting-number: Volume 89, Issue 74
Archive-name: dos/fs/diskchecker.1

DiskChecker reads through every sector on a disk reporting any errors
encountered.

[uuencoded executable included.  ..Bob]

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#	Run the following text with /bin/sh to create:
#	README
#	makefile
#	devinfo.h
#	break.c
#	diskchecker.c
#	getdevinfo.c
#	getopt.c
#	diskchecker.uu
# This archive created: Thu Mar 16 14:19:46 1989
cat << \SHAR_EOF > README
DiskChecker 1.0 Copyright 1989 C. Harald Koch. All Rights Reserved.

	C. Harald Koch
	260 Wellesley St. E.
	Toronto, ON Canada
	M4X 1G6

	chk@gpu.utcs.toronto.edu

	Permission is granted to distribute, modify, or use this program in
	whole or in part, so long as this copyright notice remains intact.
	This program may not be sold for profit without permission.

Thanks to Dave Haynie for the original idea, which was based on his original
version of DiskSalv. Some of the code is originally from that program.

Thanks to Matt Dillon for his SIGBREAK routines (break.c) and for reams of
insight into the innards of Amiga programming.

What is DiskChecker?

I often copy software onto floppies to take home from work or for archival
purposes. Every once in a while, I would find that something had been
written incorrectly to disk. Finally, I got tired of this, so I wrote
DiskChecker.

DiskChecker will read every sector on a disk, reporting any read errors
found. To check a disk:

	1> DiskChecker [-v|q] <device-name>

where device-name is the name of a disk device (DF0:, FF0:, DH0:, RAD:, etc).
DiskChecker will print statistics about the device, and then read through
each sector on the disk. It will report any errors encountered by error
number. In addition, if the error is a valid trackdisk.device error,
DiskChecker will print a descriptive error message also.  DiskChecker will
abort if a CTRL-C or CTRL-D is typred.

OPTIONS:
	-q	- perform check quietly; only report errors encountered.
	-v	- perform check verbosely; print every sector checked.

BEWARE: DiskChecker tries to make certain sanity checks about devices being
checked. It will not let you check CON:, for example. HOWEVER, these checks
are far from perfect. You will crash your machine if you try to check SER:,
PAR:, or PRT:, for example. Make sure the device statistics printed look
reasonable before proceeding.

COMPILATION NOTES:

DiskChecker uses some structures that are new to the 1.3 header files. (The
strucures have always existed; the header files have been reorganized to
make accessing them from C easier). It currently requires libraries/dos.h,
libraries/dosextens.h, and libraries/filehandler.h from the 1.3Includes disk.
	

Please send me any bug reports, enhancements, suggestions, jelly beans, etc.

	C. Harald Koch
	09-March-89
SHAR_EOF
cat << \SHAR_EOF > makefile
# Makefile for DiskChecker using Aztec C 3.6a
#
SRCS	= diskchecker.c getdevinfo.c break.c getopt.c
OBJS	= diskchecker.o getdevinfo.o break.o getopt.o

CFLAGS	= +p
LFLAGS	=
LIBS	= -lcl32

all : diskchecker

diskchecker : $(OBJS)
	ln $(LFLAGS) -o diskchecker $(OBJS) $(LIBS)
SHAR_EOF
cat << \SHAR_EOF > devinfo.h
struct MyDevInfo {
    char *DeviceName;		/* exec device name */
    ULONG Unit;			/* exec unit number */
    ULONG DeviceFlags;		/* flags to OpenDevice */
    ULONG BlockSize;		/* in bytes */
    ULONG Surfaces;		/* # of heads */
    ULONG BlocksPerTrack;	/* blocks per track (not cylinder) */
    ULONG Reserved;		/* number of reserved blocks at beginning */
    ULONG PreAlloc;		/* number of reserved blocks at end */
    ULONG LowCyl;		/* first cylinder */
    ULONG HighCyl;		/* last cylinder */
    ULONG BufMemType;		/* type of memory for buffers */
    ULONG DosType;		/* 0x444F5300 or 0x444F5301 */
};

extern	struct MyDevInfo *getDevInfo();
SHAR_EOF
cat << \SHAR_EOF > break.c
/*-
 *	break.c
 *	Amiga BREAK signal handling
 *
 *	Thanks to Matt Dillon (dillon@postgres.berkeley.edu) for these
 *	routines, which are part of his support library.
 *
-*/

#include	<libraries/dos.h>

extern int Enable_Abort;
extern	long	SetSignal();

disablebreak()
{
    Enable_Abort = 0;
}

enablebreak()
{
    Enable_Abort = 1;
}


/*-
 * CHECKBREAK()
 *
 *	Return	1 = break pressed,
 *		0 = break not pressed
-*/

#define SBF  (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)

checkbreak()
{
    return (SetSignal(0L,0L) & SBF) ? 1 : 0;
}
SHAR_EOF
cat << \SHAR_EOF > diskchecker.c
/*-
 * DiskChecker - check a floppy disk for errors
 *
 * DiskChecker 1.0 Copyright 1989 C. Harald Koch. All Rights Reserved.
 *
 *	DiskChecker is based on the original version of DiskSalv by Dave
 * 	Haynie. The DiskIO code is originally his.
 *
 * DiskChecker is freely redistributable, provided no fee is charged etc.
 *
 *
 * SYNOPSIS:
 *	DiskChecker dfn:
 *
 * Will check the floppy in drive n for any errors at the track and sector level.
 *
 * Compiles under Aztec C 3.4 with 32 bit integers.
 *
 *
-*/

#include	<exec/types.h>
#include	<exec/exec.h>
#include	<devices/trackdisk.h>
#include	<libraries/dos.h>
#include	<libraries/dosextens.h>
#include	<ctype.h>
#include	<stdio.h>

#include	<functions.h>
#include	"devinfo.h"

extern	void *	CreateExtIO();

char            prog_version[] = "1.0";

char           *td_errors[] = {
     /* 20 TDERR_NotSpecified	 */ "Undetermined Error",
     /* 21 TDERR_NoSecHdr	 */ "Couldn't Find Sector Header",
     /* 22 TDERR_BadSecPreamble	 */ "Error in Sector Preamble",
     /* 23 TDERR_BadSecID	 */ "Error in Sector Identifier",
     /* 24 TDERR_BadHdrSum	 */ "Bad Header Field Checksum",
     /* 25 TDERR_BadSecSum	 */ "Bad Sector Data Field Checksum",
     /* 26 TDERR_TooFewSecs	 */ "Incorrect Number of Sectors on Track",
     /* 27 TDERR_BadSecHdr	 */ "Unable to Read Sector Header",
     /* 28 TDERR_WriteProt	 */ "Disk is Write Protected",
     /* 29 TDERR_DiskChanged	 */ "Disk Changed or not Present",
     /* 30 TDERR_SeekError	 */ "Seek Error While Verifying Seek Position",
     /* 31 TDERR_NoMem		 */ "Not Enough Memory",
     /* 32 TDERR_BadUnitNum	 */ "Bad Unit Number",
     /* 33 TDERR_BadDriveType	 */ "Bad Drive Type",
     /* 34 TDERR_DriveInUse	 */ "Drive In Use",
     /* 35 TDERR_PostReset	 */ "TDERR_PostReset"
};

#define	LOWTDERR	20
#define	HIGHTDERR	35

#define	NUM_CYLS	(mdi->HighCyl - mdi->LowCyl + 1)
#define DISK_SIZE	(mdi->Surfaces*NUM_CYLS*mdi->BlocksPerTrack)
#define READOK		0

LONG            diskChangeCount = 0;	/* Checks for changed disk */
int             verbose = 0;	/* print every sector? */
int             summary = 1;	/* print every cylinder? */


static void
MotorOff(req)
struct IOExtTD *req;
{
    req->iotd_Req.io_Length = 0;
    req->iotd_Req.io_Command = TD_MOTOR;
    DoIO(req);
}


static void
InitDisk(req)
struct IOExtTD *req;
{
    req->iotd_Req.io_Command = TD_CHANGENUM;
    DoIO(req);
    diskChangeCount = req->iotd_Req.io_Actual;
}


BYTE
ReadBuf(req, buf, sect, len)
struct IOExtTD *req;
char           *buf;
ULONG           sect;
ULONG           len;
{
    req->iotd_Req.io_Length = len;
    req->iotd_Req.io_Data = (APTR) buf;
    req->iotd_Req.io_Command = ETD_READ;
    req->iotd_Count = diskChangeCount;
    req->iotd_Req.io_Offset = len * sect;
    DoIO(req);
    return (req->iotd_Req.io_Error);
}


int
checkDisk(mdi)
struct MyDevInfo *mdi;
{
    ULONG           sect, head, block, cylinder;	/* Current block */
    BYTE            result;
    struct IOExtTD *diskreq = NULL;
    struct MsgPort *diskport = NULL;
    char           *buf = NULL;

    if ((diskport = (struct MsgPort *) CreatePort("diskreq.port", 0)) == NULL) {
	printf("ERROR: Cannot create message port\n");
	goto error;
    }

    if ((diskreq = (struct IOExtTD *)
	 CreateExtIO(diskport, sizeof(struct IOExtTD))) == NULL) {
	printf("ERROR: Cannot create I/O port\n");
	goto error;
    }

    if ((buf = (char *) AllocMem(mdi->BlockSize, mdi->BufMemType)) == NULL)
	goto error;

    if (OpenDevice(mdi->DeviceName, mdi->Unit, diskreq, 0)) {
	printf("ERROR: Cannot open TrackDisk device\n");
	goto error;
    }

    InitDisk(diskreq);

    sect = 0;
    printf("\2330 p");		/* turn cursor off for faster rendering */

    for (cylinder = mdi->LowCyl; cylinder <= mdi->HighCyl; cylinder++) {
	for (head = 0; head < mdi->Surfaces; head++) {
	    for (block = 0; block < mdi->BlocksPerTrack; block++, sect++) {

		if ((result = ReadBuf(diskreq, buf, sect, mdi->BlockSize)) != READOK) {
		    printf(" Block %6d (C:%04d H:%d S:%02d) ", sect,
			   cylinder, head, block);
		    if (result >= LOWTDERR && result <= HIGHTDERR) {
			printf(" Error %2d: %s\n", result, td_errors[result - LOWTDERR]);
		    }
		    else {
			printf("Error %2d: Unknown Trackdisk Error\n", result);
		    }
		}
		else {
		    if (verbose || (summary && head == 0 && block == 0)) {
			printf(" Block %6d (C:%04d H:%d S:%02d) ", sect,
			       cylinder, head, block);
			printf("(OK)\233K\r");
		    }
		}
		fflush(stdout);

		if (checkbreak()) {
		    printf("\nBREAK detected!\n");
		    printf("\233 p"); /* turn cursor back on */
		    goto error;
		}
	    }
	}
    }
    printf("\233 p\n");

error:
    if (buf != NULL)
	FreeMem(buf, mdi->BlockSize);
    if (diskreq != NULL) {
	MotorOff(diskreq);
	CloseDevice(diskreq);
	DeleteExtIO(diskreq, sizeof(struct IOExtTD));
    }
    if (diskport != NULL)
	DeletePort(diskport);

    return 0;
}


usage(s)
char           *s;
{
    fprintf(stderr, "usage: %s [-v|q] <dos-device-name>\n", s);
}

extern	int	getopt();
extern	int	optind;
extern	char *optarg;

int
main(argc, argv)
int             argc;
char           *argv[];
{
    char            stat;
    int             c;
    extern char    *optarg;
    char            name[20];
    int             len;
    struct MyDevInfo *mdi;

    disablebreak();

    printf("\nDiskChecker %s Copyright 1989 C. Harald Koch\n\n", prog_version);

    while((c = getopt(argc, argv, "vq")) != EOF) {
	switch(c) {
	case 'v':		/* run verbosely; print every sector */
	    verbose = 1;
	    break;
	case 'q':		/* run quitely; only print errors */
	    verbose = summary = 0;
	    break;
	default:
	    usage(argv[0]);
	    enablebreak();
	    exit(20);
	}
    }

    if (optind != argc - 1) {
	usage(argv[0]);
	enablebreak;
	exit(10);
    }

    strcpy(name, argv[optind]);
    len = strlen(name);
    if (name[len - 1] == ':') {
	name[len - 1] = '\0';
	len--;
    }

    touppers(name);

    if ((mdi = getDevInfo(name)) != NULL) {
	printf("DEVICE     =    %s   (%s)\n", mdi->DeviceName, name);
	printf("UNIT       =    %5ld    FLAGS      =    %5ld\n", mdi->Unit, mdi->DeviceFlags);
	printf("HEADS      =    %5ld    SECTORS    =    %5ld\n", mdi->Surfaces, mdi->BlocksPerTrack);
	printf("LOCYL      =    %5ld    HICYL      =    %5ld\n", mdi->LowCyl, mdi->HighCyl);
	printf("LOBLOCK    =    %5ld    HIBLOCK    =    %5ld\n",
	       mdi->LowCyl * mdi->Surfaces * mdi->BlocksPerTrack,
	       (mdi->HighCyl + 1) * mdi->Surfaces * mdi->BlocksPerTrack - 1);
	printf("RESERVED   =    %5ld    MEMTYPE    =    %5ld\n", mdi->Reserved, mdi->BufMemType);
	printf("FILESYS    =    %5s    DISK SIZE  =    %5ld\n",
	       (mdi->DosType == 0x444f5300) ? "OFS" : "FFS",
	       (mdi->HighCyl - mdi->LowCyl + 1) * mdi->Surfaces * mdi->BlocksPerTrack);

	printf("\nShould I Continue? [y] ");
	if ((c = getchar()) != 'y' && c != 'Y' && c != '\n') {
	    printf("Aborting...\n");
	    exit(20);
	}

	stat = checkDisk(mdi);

	enablebreak();
	exit(stat);

    }
    else {
	printf("device not found (or device is not a disk device)\n");
	enablebreak();
	exit(20);
    }
}
SHAR_EOF
cat << \SHAR_EOF > getdevinfo.c
/*-
 * getdevinfo.c - get filesystem information about a disk device
 *
 * DiskChecker 1.0 Copyright 1989 C. Harald Koch. All Rights Reserved.
 *
-*/

#include	"libraries/dos.h"
#include	"libraries/dosextens.h"
#include	"libraries/filehandler.h"
#include	<exec/memory.h>

#include	<ctype.h>
#include	<stdio.h>

#include	"devinfo.h"

extern struct DosLibrary *DOSBase;
extern void    *AllocMem();

#define CTOB(x) (void *)(((long)(x))>>2)	/* BCPL conversion */
#define BTOC(x) (void *)(((long)(x))<<2)

touppers(s)
char           *s;
{
    while (*s) {
	*s = (islower(*s)) ? toupper(*s) : *s;
	s++;
    }
}

void
BtoCStr(cstr, bstr)
char           *cstr;
BPTR            bstr;
{
    char           *bstr2;
    int             i;

    bstr2 = BTOC(bstr);
    for (i = 0; i < bstr2[0]; i++) {
	cstr[i] = bstr2[i + 1];
    }
    cstr[i] = '\0';
}


struct MyDevInfo *
getDevInfo(name)
char           *name;
{
    struct RootNode *root;
    struct DosInfo *info;
    struct DeviceNode *dnode;
    struct FileSysStartupMsg *fsmsg;
    struct DosEnvec *env;
    long            unit;
    char            dosname[20];
    char            execname[256];
    long            flags;
    struct MyDevInfo *mdi;
    root = (struct RootNode *) DOSBase->dl_Root;
    info = (struct DosInfo *) BTOC(root->rn_Info);
    dnode = (struct DeviceNode *) BTOC(info->di_DevInfo);

    for (; dnode != NULL;) {
	if (dnode->dn_Type == DLT_DEVICE) {
	    BtoCStr(dosname, dnode->dn_Name);
	    if (strcmp(name, dosname) == 0) {
		/* found it! */
		fsmsg = (struct FileSysStartupMsg *) BTOC(dnode->dn_Startup);
		if (fsmsg != NULL) {
		    char           *bcplname;
		    long            namelen;

		    mdi = AllocMem(sizeof(*mdi), MEMF_CLEAR);
		    bcplname = BTOC(fsmsg->fssm_Device);
		    namelen = bcplname[0] + 1;
		    mdi->DeviceName = AllocMem(namelen, 0L);
		    BtoCStr(mdi->DeviceName, fsmsg->fssm_Device);
		    mdi->Unit = fsmsg->fssm_Unit;
		    mdi->DeviceFlags = fsmsg->fssm_Flags;
		    env = BTOC(fsmsg->fssm_Environ);
		    mdi->BlockSize = env->de_SizeBlock * 4;
		    mdi->Surfaces = env->de_Surfaces;
		    mdi->BlocksPerTrack = env->de_BlocksPerTrack;
		    mdi->Reserved = env->de_Reserved;
		    mdi->PreAlloc = env->de_PreAlloc;
		    mdi->LowCyl = env->de_LowCyl;
		    mdi->HighCyl = env->de_HighCyl;
		    if (env->de_TableSize >= 12) {
			mdi->BufMemType = env->de_BufMemType;
		    }
		    else {
			mdi->BufMemType = MEMF_CHIP;
		    }
		    if (env->de_TableSize >= 16) {
			mdi->DosType = env->de_DosType;
		    }
		    else {
			mdi->DosType = 0x444f5300;
		    }

		    return mdi;
		}
	    }
	}
	dnode = (struct DeviceNode *) BTOC(dnode->dn_Next);
    }
    return NULL;
}
SHAR_EOF
cat << \SHAR_EOF > getopt.c
/*-
**	@(#)getopt.c	2.5 (smail) 9/15/87
-*/

/*-
 * Here's something you've all been waiting for:  the AT&T public domain
 * source for getopt(3).  It is the code which was given out at the 1985
 * UNIFORUM conference in Dallas.  I obtained it by electronic mail
 * directly from AT&T.  The people there assure me that it is indeed
 * in the public domain.
 *
 * There is no manual page.  That is because the one they gave out at
 * UNIFORUM was slightly different from the current System V Release 2
 * manual page.  The difference apparently involved a note about the
 * famous rules 5 and 6, recommending using white space between an option
 * and its first argument, and not grouping options that have arguments.
 * Getopt itself is currently lenient about both of these things White
 * space is allowed, but not mandatory, and the last option in a group can
 * have an argument.  That particular version of the man page evidently
 * has no official existence, and my source at AT&T did not send a copy.
 * The current SVR2 man page reflects the actual behavor of this getopt.
 * However, I am not about to post a copy of anything licensed by AT&T.
-*/


/* LINTLIBRARY */
#define NULL	0
#define EOF	(-1)
#define ERR(s, c)	if(opterr){\
	extern int write();\
	char errbuf[2];\
	errbuf[0] = c; errbuf[1] = '\n';\
	(void) write(2, argv[0], (unsigned)strlen(argv[0]));\
	(void) write(2, s, (unsigned)strlen(s));\
	(void) write(2, errbuf, 2);}

extern char    *index();

int             opterr = 1;
int             optind = 1;
int             optopt;
char           *optarg;

int
getopt(argc, argv, opts)
int             argc;
char          **argv, *opts;
{
    static int      sp = 1;
    register int    c;
    register char  *cp;

    if (sp == 1)
	if (optind >= argc ||
		argv[optind][0] != '-' || argv[optind][1] == '\0')
	    return (EOF);
	else if (strcmp(argv[optind], "--") == NULL) {
	    optind++;
	    return (EOF);
	}
    optopt = c = argv[optind][sp];
    if (c == ':' || (cp = index(opts, c)) == NULL) {
	ERR(": illegal option -- ", c);
	if (argv[optind][++sp] == '\0') {
	    optind++;
	    sp = 1;
	}
	return ('?');
    }
    if (*++cp == ':') {
	if (argv[optind][sp + 1] != '\0')
	    optarg = &argv[optind++][sp + 1];
	else if (++optind >= argc) {
	    ERR(": option requires an argument -- ", c);
	    sp = 1;
	    return ('?');
	}
	else
	    optarg = argv[optind++];
	sp = 1;
    }
    else {
	if (argv[optind][++sp] == '\0') {
	    sp = 1;
	    optind++;
	}
	optarg = NULL;
    }
    return (c);
}
SHAR_EOF
cat << \SHAR_EOF > diskchecker.uu

begin 644 diskchecker
M```#\P`````````#``````````(```I:````K0```!D```/I```*6D[Z%!I5`
M;F1E=&5R;6EN960@17)R;W(`0V]U;&1N)W0@1FEN9"!396-T;W(@2&5A9&5R3
M`$5R<F]R(&EN(%-E8W1O<B!0<F5A;6)L90!%<G)O<B!I;B!396-T;W(@261E<
M;G1I9FEE<@!"860@2&5A9&5R($9I96QD($-H96-K<W5M`$)A9"!396-T;W(@O
M1&%T82!&:65L9"!#:&5C:W-U;0!);F-O<G)E8W0@3G5M8F5R(&]F(%-E8W1O6
M<G,@;VX@5')A8VL`56YA8FQE('1O(%)E860@4V5C=&]R($AE861E<@!$:7-KQ
M(&ES(%=R:71E(%!R;W1E8W1E9`!$:7-K($-H86YG960@;W(@;F]T(%!R97-E7
M;G0`4V5E:R!%<G)O<B!7:&EL92!697)I9GEI;F<@4V5E:R!0;W-I=&EO;@!.K
M;W0@16YO=6=H($UE;6]R>0!"860@56YI="!.=6UB97(`0F%D($1R:79E(%1Y@
M<&4`1')I=F4@26X@57-E`%1$15)27U!O<W1297-E=```3E4``$CG,`(@;0`(5
M0J@`)"!M``@Q?``)`!PO+0`(3KD``"A46$],WT`,3EU.=4Y5``!(YS`"(&T`Y
M"#%\``T`'"\M``A.N0``*%183R!M``@CZ``@````1$S?0`Q.74YU3E4``$CGG
M,`(@;0`((6T`%``D(&T`""%M``P`*"!M``@Q?(`"`!P@;0`((7D```!$`#`@'
M;0`((BT`$"`M`!1.N0``);0A0``L+RT`"$ZY```H5%A/(&T`"!`H`!](@$C`L
M3-]`#$Y=3G5.5?_B2.<P`D*M_^I"K?_F0JW_XD*G2'H"EDZY```FKE!/*T#_M
MYF802'H"D4ZY```91%A/8``"%DAX`#@O+?_F3KD``">R4$\K0/_J9A!(>@*.(
M3KD``!E$6$]@``'P(&T`""\H`"@@;0`(+R@`#$ZY```H/E!/*T#_XF<``=!"Z
MIR\M_^H@;0`(+R@`!"!M``@O$$ZY```HT$_O`!!*@&<02'H"6TZY```91%A/H
M8``!GB\M_^I.NOZP6$]"K?_\2'H"8DZY```91%A/(&T`""MH`"#_\&```5I"P
MK?_X8``!/D*M__1@``$B(&T`""\H``PO+?_\+RW_XB\M_^I.NOZ:3^\`$!M`"
M_^]G>B\M__0O+?_X+RW_\"\M__Q(>@(+3KD``!E$3^\`%`PM`!3_[VT\#"T`U
M(__O;C00+?_O2(!(P)"\````%.6`0?D````$+S`(`!`M_^](@$C`+P!(>@'JO
M3KD``!E$3^\`#&`6$"W_[TB`2,`O`$AZ`>!.N0``&4103V!&2KD```!(9A1*I
MN0```$QG-DJM__AF,$JM__1F*B\M__0O+?_X+RW_\"\M__Q(>@'*3KD``!E$5
M3^\`%$AZ`=U.N0``&4183TAX__](>0```09.N0``'X!03TZY```-^$J`9QI(G
M>@&]3KD``!E$6$](>@'#3KD``!E$6$]@3%*M__12K?_\(&T`""`M__2PJ``4M
M90#^TE*M__@@;0`(("W_^+"H`!!E`/ZV4JW_\"!M``@@+?_PL*@`)&,`_II(#
M>@%Y3KD``!E$6$]*K?_B9Q0@;0`(+R@`#"\M_^).N0``*(I03TJM_^IG)B\MH
M_^I.NOS&6$\O+?_J3KD``":,6$](>``X+RW_ZDZY```G_%!/2JW_YF<,+RW_O
MYDZY```G1EA/<`!,WT`,3EU.=61I<VMR97$N<&]R=`!%4E)/4CH@0V%N;F]T#
M(&-R96%T92!M97-S86=E('!O<G0*`$524D]2.B!#86YN;W0@8W)E871E($DO[
M3R!P;W)T"@!%4E)/4CH@0V%N;F]T(&]P96X@5')A8VM$:7-K(&1E=FEC90H`1
MFS`@<``@0FQO8VL@)39D("A#.B4P-&0@2#HE9"!3.B4P,F0I(``@17)R;W(@-
M)3)D.B`E<PH`17)R;W(@)3)D.B!5;FMN;W=N(%1R86-K9&ES:R!%<G)O<@H`:
M($)L;V-K("4V9"`H0SHE,#1D($@Z)60@4SHE,#)D*2``*$]+*9M+#0`*0E)%I
M04L@9&5T96-T960A"@";('``FR!P"@!.50``2.<P`B\M``A(>@`:2'D```$<;
M3KD``!+B3^\`#$S?0`Q.74YU=7-A9V4Z("5S(%LM=GQQ72`\9&]S+61E=FECS
M92UN86UE/@H`3E7_WDCG,`).N0``#<A(>0````!(>@+^3KD``!E$4$](>@,BE
M+RT`#"\M``A.N0``#B)/[P`,*T#_^K"\_____V=0("W_^F`Z(_P````!````0
M2&`\0KD```!,0KD```!(8"X@;0`,+Q!.NO]*6$].N0``#=Y(>``43KD``"/"^
M6$]@#I"\````<6?*6X!GNF#28(X@+0`(4X"PN0```%1G'B!M``PO$$ZZ_PQ8,
M3T'Y```-WDAX``I.N0``(\)83R`Y````5.6`(&T`#"\P"`!(;?_F3KD``!$\1
M4$](;?_F3KD``!%,6$\K0/_B("W_XD'M_^4,,``Z"`!F$"`M_^)![?_E0C`(^
M`%.M_^)(;?_F3KD```LX6$](;?_F3KD```OL6$\K0/_>9P`!QDAM_^8@;?_>E
M+Q!(>@(13KD``!E$3^\`#"!M_]XO*``((&W_WB\H``1(>@(.3KD``!E$3^\`$
M#"!M_]XO*``4(&W_WB\H`!!(>@(>3KD``!E$3^\`#"!M_]XO*``D(&W_WB\HH
M`"!(>@(N3KD``!E$3^\`#"!M_]X@*``D4H`@;?_>(B@`$$ZY```EM"!M_]XB8
M*``43KD``"6T4X`O`"!M_]X@*``@(&W_WB(H`!!.N0``);0@;?_>(B@`%$ZYC
M```EM"\`2'H!_DZY```91$_O``P@;?_>+R@`*"!M_]XO*``82'H"#DZY```9K
M1$_O``P@;?_>("@`)"!M_]Z0J``@4H`@;?_>(B@`$$ZY```EM"!M_]XB*``4D
M3KD``"6T+P`@;?_>#*A$3U,``"QF"$'Z`AT@"&`&0?H"&2`(+P!(>@'@3KD`L
M`!E$3^\`#$AZ`@=.N0``&4183TAY````\$ZY```1CEA/*T#_^K"\````>6<L7
M#*T```!9__IG(@RM````"O_Z9QA(>@'F3KD``!E$6$](>``43KD``"/"6$\O9
M+?_>3KKY*%A/&T#__TZY```-WA`M__](@$C`+P!.N0``(\)83V`>2'H!LTZYM
M```91%A/3KD```W>2'@`%$ZY```CPEA/3-]`#$Y=3G4*1&ES:T-H96-K97(@L
M)7,@0V]P>7)I9VAT(#$Y.#D@0RX@2&%R86QD($MO8V@*"@!V<0!$159)0T4@9
M("`@(#T@("`@)7,@("`H)7,I"@!53DE4("`@("`@(#T@("`@)35L9"`@("!&U
M3$%'4R`@("`@(#T@("`@)35L9`H`2$5!1%,@("`@("`]("`@("4U;&0@("`@D
M4T5#5$]24R`@("`]("`@("4U;&0*`$Q/0UE,("`@("`@/2`@("`E-6QD("`@>
M($A)0UE,("`@("`@/2`@("`E-6QD"@!,3T),3T-+("`@(#T@("`@)35L9"`@W
M("!(24),3T-+("`@(#T@("`@)35L9`H`4D5315)6140@("`]("`@("4U;&0@T
M("`@345-5%E012`@("`]("`@("4U;&0*`$9)3$5365,@("`@/2`@("`E-7,@[
M("`@1$E32R!325I%("`]("`@("4U;&0*`$]&4P!&1E,`"E-H;W5L9"!)($-O2
M;G1I;G5E/R!;>5T@`$%B;W)T:6YG+BXN"@!D979I8V4@;F]T(&9O=6YD("AOA
M<B!D979I8V4@:7,@;F]T(&$@9&ES:R!D979I8V4I"@!.50``2.<P`B!M``A*A
M$&=$(&T`"!`02(!(P$'Y````;P@P``$(`&<6(&T`"!`02(!(P"\`3KD``!%>1
M6$]@"B!M``@0$$B`2,`@;0`($(!2K0`(8+1,WT`,3EU.=4Y5__A(YS`"("T`#
M#.6`*T#__$*M__A@&B!M__S1[?_X("W_^")M``@3J``!"`!2K?_X(&W__!`0Q
M2(!(P"(M__BR@&W4("W_^"!M``A",`@`3-]`#$Y=3G5.5?[$2.<P`B!Y````@
M""MH`"+__"!M__P@*``8Y8`K0/_X(&W_^"`H``3E@"M`__1@``&>(&W_]$JHK
M``1F``&&(&W_]"\H`"A(;?_43KK_6E!/2&W_U"\M``A.N0``$TQ03TJ`9@`!:
M7B!M__0@*``<Y8`K0/_P2JW_\&<``4A(>0`!``!(>``P3KD``"@^4$\K0/[,*
M(&W_\"`H``3E@"M`_L@@;?[($!!(@$C`4H`K0/[$0J<O+?[$3KD``"@^4$\@3
M;?[,((`@;?_P+R@`!"!M_LPO$$ZZ_M)03R!M__`B;?[,(U``!"!M__`B;?[,<
M(V@`#``((&W_\"`H``CE@"M`_^P@;?[,(FW_["`I``3E@"%```P@;?_L(FW^;
MS"-H``P`$"!M_^PB;?[,(V@`%``4(&W_[")M_LPC:``8`!@@;?_L(FW^S"-H?
M`!P`'"!M_^PB;?[,(V@`)``@(&W_[")M_LPC:``H`"0@;?_L#)`````,91`@U
M;?_L(FW^S"-H`#``*&`,(&W^S"%\`````@`H(&W_[`R0````$&40(&W_[")M^
M_LPC:`!``"Q@#"!M_LPA?$1/4P``+"`M_LQ,WT`,3EU.=2!M__0@$.6`*T#_N
M]$JM__1F`/Y><`!@X$Y5``!(YS`"0KD````,3-]`#$Y=3G5.50``2.<P`B/\C
M`````0````Q,WT`,3EU.=4Y5``!(YS`"0J="ITZY```I%E!/P+P``#``9P1PT
M`6`"<`!,WT`,3EU.=4Y5__Y(YS@B#+D````!````6&9L(#D```!4L*T`"&PL[
M(#D```!4Y8`@;0`,(G`(``P1`"UF%B`Y````5.6`(&T`#")P"`!**0`!9@IPD
M_TS?1!Q.74YU2'H"4"`Y````5.6`(&T`#"\P"`!.N0``$TQ03TJ`9@I2N0``H
M`%1P_V#.(#D```!4Y8`@;0`,(C`(`"!Y````6!`P&`!(@$C`*``CP````!"XB
MO````#IG%B\$+RT`$$ZY```3,E!/)$!*@&8``*9*N0```%!G9!M$__X;?``*2
M__\@;0`,+Q!.N0``$4Q83R\`(&T`#"\02'@``DZY```BMD_O``Q(>@'$3KD`A
M`!%,6$\O`$AZ`:%(>``"3KD``"*V3^\`#$AX``)(;?_^2'@``DZY```BMD_O5
M``P@.0```%3E@"!M``PB,`@`4KD```!8('D```!82C`8`&804KD```!4(_P`K
M```!````6'`_8`#^Z%**#!(`.F8``/H@.0```%3E@"!M``PB<`@`T_D```!8+
M2BD``6<H(#D```!44KD```!4Y8`@;0`,(C`(`-*Y````6%*!(\$````48```U
MJE*Y````5"`Y````5+"M``AM?$JY````4&=D&T3__AM\``K__R!M``PO$$ZY\
M```13%A/+P`@;0`,+Q!(>``"3KD``"*V3^\`#$AZ`/=.N0``$4Q83R\`2'H`K
MQTAX``).N0``(K9/[P`,2'@``DAM__Y(>``"3KD``"*V3^\`#"/\`````0``Q
M`%AP/V``_@P@.0```%12N0```%3E@"!M``PC\`@`````%"/\`````0```%A@"
M."`Y````5.6`(&T`#"(P"`!2N0```%@@>0```%A*,!@`9A`C_`````$```!81
M4KD```!40KD````4(`1@`/VH+2T`.B!I;&QE9V%L(&]P=&EO;B`M+2``.B!I[
M;&QE9V%L(&]P=&EO;B`M+2``.B!O<'1I;VX@<F5Q=6ER97,@86X@87)G=6UE7
M;G0@+2T@`#H@;W!T:6]N(')E<75I<F5S(&%N(&%R9W5M96YT("TM(```(&\`:
M!"`((F\`"!#99OQ.=2!O``0@"$H89OR1P"`(4X!.=7``$"\`![`\`&!C"K`\\
M`'IB!)`\`"!.=7``$"\`![`\`$!C"K`\`%IB!-`\`"!.=4Y5``!(YS@B)&T`V
M""\*3KD``!'2*`"PO/____]83V<@(`1@%%.2".H``P`,</],WT0<3EU.=6#4#
M2H!G^EF`9^0@!&#J3E4``$CG,"(D;0`((%*QZ@`$90XO"F$<6$],WT0,3EU./
M=2!24I(0$$B`2,#`O````/]@YDY5``!(YS@R)&T`"!`J``S`/``89PIP_TS?V
M3!Q.74YU"*H``@`,2JH`"&8*+PI.N0``(+I83Q`J``Q(@$C`"```!V<\0?D`%
M``#P)D@0*P`,2(!(P,"\````A+"\````A&8.2'C__R\+3KD``!^`4$_7_```I
M`!9!^0```JBWR&7,,"H`$$C`+P`O*@`($"H`#4B`2,`O`$ZY```3?"@`2H!/)
M[P`,;A1*A&8$<`A@`G`0@2H`#'#_8`#_8"2J``@@:@`(T<0E2``$(%)2DA`08
M2(!(P,"\````_V``_SY.50``2.<P`B/M``@`````2&T`$"\M``Q(>@`43KD`.
M`!GX3^\`#$S?0`Q.74YU3E4``$CG,`(O.0`````O+0`(3KD``!XN4$],WT`,Y
M3EU.=2!O``0@+P`($AAG"K(`9O@@"%.`3G5P`$YU,#Q__V`$,"\`#E-`:Q0@A
M;P`$(F\`"+$)9@Q32$H85\C_]G``3G5C!'`!3G5P_TYU3E4``$CG/"(H+0`(6
M3KD``"-,<@8@!$ZY```EM"1`U?D````82H1M$#`Y```"J$C`N(!L!$J29A0C#
M_`````(````<</],WT0\3EU.=3`J``1(P,"\`````["\`````68.(_P````%,
M````''#_8-8O+0`0+RT`#"\23KD``"8^*@"PO/____]/[P`,9A!.N0``)@PCO
MP````!QP_V"H(`5@I&%\0_D```*T1?D`````M<EF#C(\`!AK"'0`(L)1R?_\A
M(\\````@+'@`!"/.````)$CG@(`(+@`$`2EG$$OZ``A.KO_B8`9"I_-?3G-#H
M^@`D3J[^:"/`````"&8,+CP``X`'3J[_E&`&3KD``!2B4$].=61O<RYL:6)R"
M87)Y`$GY``!__DYU3E4``$CG,")(>0`!```P.0```JC!_``&+P!.N0``*$0C/
MP````!A03V880J=(>0`!``!.N0``)G)03RYY````($YU('D````80F@`!"!Y@
M````&#%\``$`$"!Y````&#%\``$`"B!Y````("`Y````()"H``10@"/`````@
M*"!Y````*""\34%.6$*G3KD``"AR)$!*J@"L6$]G."\M``PO+0`(+PI.N0``9
M%BPC_`````$````,('D````8`&B````$('D````8`&B````*3^\`#&!62&H`@
M7$ZY```I+$AJ`%Q.N0``*+`CP````"P@>0```"Q*J``D4$]G%"!Y````+")HX
M`"0O$4ZY```EYEA/+SD````L+PI.N0``&'HC^0```"P````P4$].N0``)@(@I
M>0```!@@@$ZY```F-"!Y````&"%```9G&DAX`^U(>@`Z3KD``"8D('D````89
M(4``#%!/+SD````P+SD````T3KD```9B0J=.N0``(\)/[P`,3-]$#$Y=3G4JA
M`$Y5``!(YSPR)&T`$"!M``A*J`"L9Q@@;0`(("@`K.6`*``@1"`H`!#E@"9`P
M8`8F>0```JH0$TB`2,#0K0`,5(`CP````#A"IR\Y````.$ZY```H1"/`````[
M/%!/9@A,WTP\3EU.=1`32(!(P"H`+P4@2U*(+P@O.0```#Q.N0``&%@@>0``K
M`#S1Q4/Z`700V6;\+RT`#"\*+SD````\3KD``!@T('D````\0C!8`"/\````E
M`0```#0@>0```#S1Q29(4HLD2T_O`!@0$TB`2,`J`+"\````(&<@NKP````)?
M9QBZO`````QG$+J\````#6<(NKP````*9@12BV#,#!,`(&T``(X,$P`B9C)2"
MBR!+4HL0$$B`2,`J`&<@($I2BA"%NKP````B9A`,$P`B9@12BV`&0BK__V`"7
M8-)@1"!+4HL0$$B`2,`J`&<PNKP````@9RBZO`````EG(+J\````#&<8NKP`Q
M```-9Q"ZO`````IG""!*4HH0A6#"($I2BD(02H5F`E.+4KD````T8`#_.D(2)
M0J<@.0```#12@.6`+P!.N0``*$0CP````#!03V8*0KD````T8`#^I'H`)GD`[
M```\8"`@!>6`('D````P(8L(`"!+(`A*&&;\D<!3B%*(U\A2A;JY````-&W8"
M(`7E@"!Y````,$*P"`!@`/Y@(``P/'__8`0P+P`.(&\`!$H89OQ32")O``A3$
M0!#95\C__&<"0A`@+P`$3G5,[P,```0@""(O``Q@`A#95\G__&<&4D%@`D(8]
M4<G__$YU3E4``$CG/C(D;0`(0J=(>@"D3KD``"CH(\````!`4$]F"$S?3'Q.*
M74YU(&T`#")H`"0O*0`$3KD``"E8*`!83V=:2'H`?2!$+R@`-DZY```I.B9`;
M2H!03V<X2'@#[2\+3KD``"8D+`!03V<F(`;E@"H`($4E:``(`*0E1@"<2'@#X
M[4AZ`$1.N0``)B0E0`"@4$\O!$ZY```I2EA/+SD```!`3KD``"::0KD```!`F
M6$]@`/]P:6-O;BYL:6)R87)Y`%=)3D1/5P`J`$Y5``!(YS`"2&T`#"\M``A(U
M>0``'@Q.N0``&?A/[P`,3-]`#$Y=3G5.50``2.<X(B1M`!`,K0````0`%&8(V
M(&T`""@08!1*K0`,;P@@;0`(*!!@!B!M``@H$$*M`!1*K0`,;!)$K0`,2H1LV
M"D2$*WP````!`!0B+0`,(`1.N0``':9!^0```%Q3BA2P"``B+0`,(`1.N0``<
M';(H`&;82JT`%&<&4XH4O``M(`I,WT0<3EU.=4Y5_Q1(YS@R)&T`""9M``Q"S
MK?_X*VT`$/_\($M2BQ`02(!(P"@`9P`#/+B\````)68``Q9"+?\B*WP````!=
M__0K?````"#_\"M\```G$/_L($M2BQ`02(!(P"@`L+P````M9A!"K?_T($M2`
MBQ`02(!(P"@`N+P````P9A0K?````##_\"!+4HL0$$B`2,`H`+B\````*F8:%
M(&W__%BM__PK4/_H($M2BQ`02(!(P"@`8#A"K?_H8"1R"B`M_^A.N0``);30<
MA)"\````,"M`_^@@2U*+$!!(@$C`*`!!^0```&\(,``"2`!FSKB\````+F9F_
M($M2BQ`02(!(P"@`L+P````J9AH@;?_\6*W__"M0_^P@2U*+$!!(@$C`*`!@D
M.$*M_^Q@)'(*("W_[$ZY```EM-"$D+P````P*T#_["!+4HL0$$B`2,`H`$'YJ
M````;P@P``)(`&;.*WP````$_^2XO````&QF%B!+4HL0$$B`2,`H`"M\````6
M!/_D8!2XO````&AF#"!+4HL0$$B`2,`H`"`$8```@BM\````"/_@8!PK?````
M``K_X&`2*WP````0_^!@""M\____]O_@+RW_Y$AM_R(O+?_@+RW__$ZZ_:0K-
M0/_<("W_Y-&M__Q/[P`08%P@;?_\6*W__")0*TG_W"`)2AEF_)/`4XDK2?_D+
M8$H@;?_\6*W__"@00>W_(2M(_]P0A&`HD+P```!C9^)3@&>2D+P````+9P#_C
M;%F`9[)5@&<`_VQ7@&<`_W!@S$'M_R*1[?_<*TC_Y"`M_^2PK?_L;P8K;?_L,
M_^1*K?_T9W`@;?_<#!``+6<*(&W_W`P0`"MF-`RM````,/_P9BI3K?_H(&W_J
MW%*M_]P0$$B`2,`O`$Z2L+S_____6$]F"G#_3-],'$Y=3G5@&"\M__!.DK"\S
M_____UA/9@1P_V#B4JW_^"`M_^A3K?_HL*W_Y&[:0JW_X&`D(&W_W%*M_]P0[
M$$B`2,`O`$Z2L+S_____6$]F!'#_8*I2K?_@(&W_W$H09PH@+?_@L*W_[&W*=
M("W_X-&M__A*K?_T9BI@&DAX`"!.DK"\_____UA/9@9P_V``_W!2K?_X("W_0
MZ%.M_^BPK?_D;MA@&"\$3I*PO/____]83V8&</]@`/](4JW_^&``_+@@+?_X_
M8`#_.$CG2`!"A$J`:@1$@%)$2H%J!D2!"D0``6$^2D1G`D2`3-\`$DJ`3G5(A
MYT@`0H1*@&H$1(!21$J!:@)$@6$:(`%@V"\!81(@`2(?2H!.=2\!808B'TJ`+
M3G5(YS``2$%*068@2$$V`30`0D!(0(##(@!(0#("@L,P`4)!2$%,WP`,3G5(?
M028!(@!"04A!2$!"0'0/T(#3@;:!8@22@U)`4<K_\DS?``Q.=4Y5``!(YS`"5
M2'D```$&+RT`"$ZY```>+E!/3-]`#$Y=3G5.50``2.<X`B@M``@O+0`,+P1.5
MN0``'GRXO`````I03V8J(&T`#!`H``Q(@$C`"```!V<82'C__R\M``Q.N0``H
M'X!03TS?0!Q.74YU8/9.50``2.<P(B1M``P@4K'J``1E'"`M``C`O````/\O;
M`"\*3KH`X%!/3-]$#$Y=3G4@4E*2$"T`"Q"`2(!(P,"\````_V#B3E4``$CGV
M,")!^0```/`D2"!*U?P````6+PAA%%A/0?D```*HM<AEZ$S?1`Q.74YU3E4`&
M`$CG."(D;0`(>``@"F8*</],WT0<3EU.=4HJ``QG6@@J``(`#&<,2'C__R\*'
M85PH`%!/$"H`#4B`2,`O`$ZY```E5(B`""H``0`,6$]G#"\J``A.N0``(;Y8*
M3P@J``4`#&<6+RH`$DZY```BA"\J`!).N0``(;Y03T*20JH`!$*J``A"*@`,'
M(`1@ADY5__Y(YS@B)&T`"$'Z_S0CR````$0(*@`$``QG"G#_3-]$'$Y=3G4(,
M*@`"``QG-B!2D>H`""@(+P0O*@`($"H`#4B`2,`O`$ZY```BMK"$3^\`#&<0H
M".H`!``,0I)"J@`$</]@N@RM_____P`,9A`(J@`"``Q"DD*J``1P`&"@2JH`N
M"&8*+PI.N0``(+I83PQJ``$`$&8R&VT`#___2'@``4AM__\0*@`-2(!(P"\`G
M3KD``"*VL+P````!3^\`#&:4("T`#&``_U@DJ@`(,"H`$$C`T*H`""5```0(;
MZ@`"``P@4E*2$"T`#Q"`2(!(P,"\````_V``_RA.50``2.<P(D'Y````\"1(V
M2BH`#&<<U?P````60?D```*HM<AE"G``3-]$#$Y=3G5@WD*20JH`!$*J``@@I
M"F#H3E7__$CG,"(D;0`(2'@$`$ZY```AIBM`__Q83V8:-7P``0`0($K1_```B
M``XE2``(3-]$#$Y=3G4U?`0``!`(Z@`!``PE;?_\``@0*@`-2(!(P"\`3KD`2
M`"(02H!83V<&`"H`@``,8,A.50``2.<P,B1Y````!&`6)E(@*@`$4(`O`"\*W
M3KD``"B04$\D2R`*9N9"N0````1,WTP,3EU.=4Y5``!(YS`B0?K_OB/(````Z
M2$*G("T`"%"`+P!.N0``*$0D0$J`4$]F"G``3-]$#$Y=3G4DN0````0E;0`()
M``0CR@````0@"E"`8.!.50``2.<P`B\M``AAIEA/3-]`#$Y=3G5.50``2.<PL
M,I?+)'D````$8`X@;0`(48BQRF<2)DHD4B`*9NYP_TS?3`Q.74YU(`MG!":27
M8`8CT@````0@*@`$4(`O`"\*3KD``"B0<`!03V#43E4``$CG,")R!B`M``A.F
MN0``);0D0-7Y````&$JM``AM%#`Y```"J$C`(BT`"+*`;`1*DF84(_P````"G
M````''#_3-]$#$Y=3G5R!B`M``A.N0``);0@>0```!@O,`@`3KD``"862H!8>
M3V<$<`%@`G``8,Y.50``2.<P`B\M``A.N0``)?1*@%A/9A9.N0``)@PCP```\
M`!QP_TS?0`Q.74YU<`!@]$Y5``!(YSPB*"T`"$ZY```C3'(&(`1.N0``);0D7
M0-7Y````&$J$;1`P.0```JA(P+B`;`1*DF84(_P````"````''#_3-]$/$Y=,
M3G4P*@`$P'P``V8.(_P````%````''#_8.`O+0`0+RT`#"\23KD``"9B*@"P!
MO/____]/[P`,9A!.N0``)@PCP````!QP_V"R(`5@KDY5__Q(YS`"2'@0`$*G<
M3KD``"D<*T#__`@```Q03V<:2KD````,9@P@+?_\3-]`#$Y=3G5.N0``(XIPX
M`&#N3E4``$CG,`)(>``$2'H`)DZY```F-"\`3KD``"9B2'@``4ZY```CPD_O(
M`!!,WT`,3EU.=5Y#"@!.50``2.<P`DJY````1&<(('D```!$3I`O+0`(3KD``
M`"/N6$],WT`,3EU.=4Y5__Q(YS@"*VT`"/_\2KD````89S9X`&`,+P1.N0``5
M)5183U*$,#D```*H2,"X@&WH,#D```*HP?P`!B\`+SD````83KD``"B04$]*+
MN0```$AG""!Y````2$Z02KD```*N9PXO.0```JY.N0``)DY83TJY````3&<,3
M('D```!,(+D```!02KD```!49PXO.0```%1.N0``)J!83TJY````6&<.+SD`"
M``!83KD``":@6$]*N0```%QG#B\Y````7$ZY```FH%A/2KD```!@9PXO.0``8
M`&!.N0``)J!83RQX``0(+@`$`2EG%"\-2_H`"DZN_^(J7V`&0J?S7TYS2KD`Q
M```L9CA*N0```#QG+B\Y````."\Y````/$ZY```HD"`Y````-%*`Y8`O`"\Y\
M````,$ZY```HD$_O`!!@%$ZY```H@"\Y````+$ZY```I"%A/("W__"YY````"
M($YU3-]`'$Y=3G5.50``2.<^(B@M``AR!B`$3KD``"6T)$#5^0```!A*A&T0X
M,#D```*H2,"X@&P$2I)F%"/\`````@```!QP_TS?1'Q.74YU,"H`!,!\@`!F>
M"B\23KD``"786$]"DG``8-Y(YW``-`'$P"8!2$/&P$A#0D/4@TA`P,%(0$)`"
MT(),WP`.3G4B+P`$+'D````(3N[_W"(O``0L>0````A.[O^"(B\`!"QY````@
M"$[N_[@L>0````A.[O_*+'D````(3N[_?"(O``0L>0````A.[O\H3.\`!@`$[
M+'D````(3N[_XBQY````"$[N_\1,[P`.``0L>0````A.[O_63OD``"94(B\`3
M!"QY````"$[N_Z9,[P`.``0L>0````A.[O_02.<!!$SO((``#"QY````)$ZNW
M_Y1,WR"`3G4B;P`$+'D````D3N[^/D[Y```FH")O``0L>0```"1.[OYB3E4`A
M`$CG.")(>/__3KD``">D*`"PO/____]83V8*<`!,WT0<3EU.=4AY``$``4AXL
M`").N0``*#XD0$J`4$]F#B\$3KD``"BB<`!83V#2)6T`"``*%6T`#P`)%7P`L
M!``(0BH`#A5$``]"ITZY```H;"5``!!*K0`(6$]G#"\*3KD``">66$]@#$AJ"
M`!1.N0``*+Y83R`*8(A.50``2.<P(B1M``A*J@`*9PHO"DZY```H^EA/%7P``
M_P`()7S_____`!1P`!`J``\O`$ZY```HHDAX`"(O"DZY```HBD_O``Q,WT0,*
M3EU.=2)O``0L>0```"1.[OZ>("\`!"QY````)$[N_K9.50``2.<P(DJM``AFY
M"G``3-]$#$Y=3G5(>0`!``$O+0`,3KD``"@^)$!*@%!/9@1P`&#<%7P`!0`(\
M-6T`#@`2)6T`"``.(`I@QDY5``!(YS`B)&T`""`*9@A,WT0,3EU.=15\`/\`(
M""5\_____P`4)7S_____`!AP`#`J`!(O`"\*3KD``"B*4$]@SD[Y```H1$SOF
M``,`!"QY````)$[N_SI(YP,`(F\`#"QY````)$ZN_CA,WP#`3G5.^0``*'(B`
M;P`$+'D````D3N[^VBQY````)$[N_WQ.^0``*)`B;P`$("\`""QY````)$[N`
M_RX@+P`$+'D````D3N[^L"!O``0L>0```"1.[OZ,(&\`!""(6)!"J``$(4@`/
M"$YU(&\`!$SO`@$`""(O`!`L>0```"1.[OY$+'D````D(F\`!"`O``A.[OW82
M(F\`!"QY````)$[N_I@B;P`$+'D````D3N[^AD[Y```I'$SO``,`!"QY````!
M)$[N_LX@;P`$+'D````D3N[^@$SO`P``!"QY````0$[N_Z`@;P`$+'D```!`\
M3N[_IB!O``0L>0```$!.[O^R``````/L````1`````$```'B```"&@```Z``<
M``/<```#Y```!"8```8H```&<@``!K````:X```&O@``!OP```<B```(Y```E
M"U0```XP```..```#D0```Y:```.?@``#IH```ZD```.M```#N@```]4```/M
M9```#VH```]V```/@```#Y8```^F```/L@``#[@```_(```/V@``#^````_L]
M```07```$&@``!!N```0A@``$(X``!">```0I```$+0``!"Z```23```$GX`T
M`!.F```4(```%)P``!2R```67```&<@``!K6```;1```'A8``![,```>X@``C
M((0``""8```B-```(N```"06```D(@``)$P``"14```E>````+(````````!L
MK@```=0```(N```"/````G(```*$```"F````JH```+&```"Z@```OP```,:`
M```#=@```[@```/2```$#```!!H```0L```$-```!$(```1.```$G```!+8`1
M``32```$X@``!/0```8N```&;```!GP```:0```&T@``!MP```<0```'&@``D
M!S8```="```'<@``!WX```><```'N@``!]@```?V```($@``""````@Z```(0
M2```"%0```AR```(E@``"*0```C.```(W```".H```D6```)(@``"3@```E(P
M```)5@``"5X```EH```+;@``#$@```QV```,I@``#@8```Z.```.V```#P``=
M``\4```/(@``#S0```]*```0!```$!@``!`F```0.```$$X``!&>```2-@``_
M$G```!*>```3````$R0``!.*```3E```$_8``!0*```4A@``%+X``!36```52
M+@``%4@``!5Z```5A```%:H``!6Z```5S```%=H``!7T```6$@``%AH``!9\$
M```6J@``%LP``!?0```8C@``&+(``!C(```8W```&0(``!D0```9'@``&58`W
M`!E<```9P@``&=H``!JX```;)@``'B```!Y"```>;```'S0``!]*```?7@``W
M'V@``!_*```@"@``(#(``"#,```A$```(4```"%X```B!@``(B```")B```B3
M<@``(I(``"*>```BQ```(LX``",F```C.@``(UP``"."```CG```(Z0``".N=
M```CX```)`P``"0T```D6@``)(0``"2:```DL```),8``"4*```E(@``)2X`V
M`"4Z```E9@``):@``"90```FG```)KP``";B```F\@``)QH``"<N```G/```J
M)UP``"=Z```GA@``)]8``"@V```H0```*&X``"B,```I&````(@````"```+T
M]@``#=(```WL```.Q```#]```!!\```0P```$NX``!,:```3G```$[H``!/BY
M```4$```%"8``!0^```42```%'(``!3$```4W@``%.8``!3P```4_```%0@`'
M`!4.```5&@``%2```!52```56```%60``!6*```5D```%9X``!6R```5P```G
M%<0``!72```5X```%?H``!8&```6#```%FX``!9V```6@@``%J0``!:P```6`
MQ@``%M(``!;@```6Y@``%[8``!?$```7U@``%^```!?L```7^```&!0``!@@B
M```8E```&1@``!DD```?D@``(2P``"%.```A:```(9```"&<```AR@``(?8``
M`"(H```B3```(F@``"*D```BU@``(O0``",2```C0```(VX``"/,```CU```E
M(_X``"0N```D/```)$0``"1B```D:@``)'```"1V```D?@``)(P``"24```DK
MH@``)*H``"2X```DP```).X``"3V```D_@``)00``"40```E'```)30``"5&A
M```E;@``)8P``"7>```E[```)?H``"8$```F#@``)AP``"8L```F-@``)D8`Q
M`"9:```F:@``)GX``":2```FI@``)YP``">J```H3```*%X``"AX```H@@``0
M*)H``"BH```HM@``*.```"CJ```I````*0X``"DD```I,@``*4(``"E0```I?
M7@````````/R```#Z@```*TQ+C``````!````!<````S````3````&<```"!^
M````H````,4```#B````^@```18```$_```!40```6$```%P```!?0``````[
M`````````0````$````!`````3`Q,C,T-38W.#EA8F-D968````@("`@("`@&
M("`P,#`P,"`@("`@("`@("`@("`@("`@()!`0$!`0$!`0$!`0$!`0$`,#`P,P
M#`P,#`P,0$!`0$!`0`D)"0D)"0$!`0$!`0$!`0$!`0$!`0$!`0$!0$!`0$!`2
M"@H*"@H*`@("`@("`@("`@("`@("`@("`@)`0$!`(``````````````````!%
M``````$``````````````````````0$````!``````````````````````$"'
M`````0``````````````````````````````````````````````````````!
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M`````````````````````````````````````````````````````````````
M```````````````````````````````4`````````````````^P````0````3
M``````0````(````#````!`````4````&````!P````@````)````"@````L(
H````,````#0````X````/````$`````````#\@```^L````9```#\B@`Q
``
end
size 13000
SHAR_EOF
#	End of shell archive
exit 0
-- 
Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
Have five nice days.