[comp.sources.amiga] v90i205: YAFR 1.21 - yet another file requester, Part02/02

Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (07/08/90)

Submitted-by: davids@ucscb.UCSC.EDU (Dave Schreiber)
Posting-number: Volume 90, Issue 205
Archive-name: examples/yafr-1.21/part02

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 2)."
# Contents:  YAFR.c yftest.uu
# Wrapped by tadguy@xanth on Sun Jul  8 12:03:41 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'YAFR.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'YAFR.c'\"
else
echo shar: Extracting \"'YAFR.c'\" \(29701 characters\)
sed "s/^X//" >'YAFR.c' <<'END_OF_FILE'
X/*- - - - - - - - - - YAFR - Yet Another File Requester - - - - - - - - -*/
X/*- - - - - - - - - - - - - - Version  1.21 - - - - - - - - - - - - - - -*/
X
X/*YAFR V1.21 Copyright (c)1989,1990 by Dave Schreiber. All rights reserved.*/
X/*YAFR is freely distributable, and may be sold as part of a commercial  */
X/*program. This copyright message must be included in the documentation  */
X/*for any program, commercial or otherwise, that uses YAFR. Use of YAFR  */
X/*in a rogram does not detract in any way from the ownership of YAFR by  */
X/*its author, Dave Schreiber, nor does it change its status as a freely  */
X/*distributable program.  Dave Schreiber reserves the right to forbid any*/
X/*person or company from incorporating YAFR as part of a program owned by*/
X/*that person or company.                                                */
X
X/*Compiled under Lattice C V5.04                                         */
X/*Command line:  1> lc -cw -j30 yafr                                     */
X/*Generates YAFR.o which is linked into the host program                 */
X
X/*If you have any comments, suggestions, etc. I can be reached at:       */
X/*Dave Schreiber                                                         */
X/*1234 Collins Lane                                                      */
X/*San Jose, CA   95129-4208                                              */
X/*Usenet:  davids@ucscb.ucsc.edu (during the school year)                */
X/*         davids@cup.portal.com (other times)                           */
X
X#include "yafrHead.h"
X             /*^^^^system includes, structure definitions, etc.*/
X#define CRNT header.current->fib
X
X/*Parameters are:  fn-string for filename (33 characters)                */
X/*dn-string for directory name (150 characters)                          */
X/*en-string for file pattern (#?.c, file1?, etc. 150 characters)         */
X/*cn-string for combined directory and filename (183 characters)         */
X/*(NULL if you don't want the combined filename)                         */
X/*X,Y-YAFR's window's X,Y location (relative to the screen               */
X/*wn-text for YAFR's window's title bar                                  */
X/*scr-Pointer to screen that window should appear on (NULL for           */
X/*Workbench) filepen-Pen color that filenames should be displayed in     */
X/*dirpen-Pen color that directory names should be displayed in           */
X/*DisableInfo-Boolean; TRUE-files ending in .info aren't displayed       */
X/*                     FALSE-.info files are displayed                   */
X
X/*Note!  IntuitionBase, GfxBase, and DOSBase must be opened by the       */
X/*calling program before YAFR is called.  DOSBase is usually opened by   */
X/*the C startup code, but the others aren't.  If they aren't, YAFR will  */
X/*crash!  Be warned.                                                     */
X
X/*Version 1.1, completed October 30, 1989*/
X/*Directory and filename string gadgets now auto-activate and appropriate*/
X/*times.  A bug that caused an incorrect filename to be returned when the*/
X/*user pressed CANCEL has been fixed                                     */
X
X/*Version 1.15 completed January 23, 1990*/
X/*A bug that could cause the name of a directory to run outside the      */
X/*filename box has been eliminated.  Also, device names are now converted*/
X/*into volume names when selected from the device name buttons on the    */
X/*right (ex. on my system, when DH2: is pressed, Data: is the name that  */
X/*appears in the directory box.  The source code has had many more       */
X/*comments added to it and there are new distribution requirements.      */
X
X/*Version 1.21 completed May 6, 1990*/
X/*The device gadgets now get their choices from the AmigaDOS list of     */
X/*devices, instead of being hard-coded in.  Filenames can now be selected*/
X/*by double clicking on the filename in the filename box.  The code has  */
X/*also been cleaned up a little (Lattice & Amiga functions are now used  */
X/*in place of some of the custom functions used in V1.15 & previous, in  */
X/*particular, ispipedevice() and RefreshGadget() ).  Finally, the what   */
X/*used to be the filename extension box has now become a more general--  */
X/*purpose wildcard selector (using standard AmigaDOS wildcards; no *     */
X/*here!).  Thanks to Dave Haynie for the DiskSalv wildcard code I used.  */
X
X/*Thanks also to Bruce Rogers for his FindRoot code which has been       */
X/*incorporated in YAFR.                                                  */
X
X/*-----------------------------------------------------------------------*/
X
X#include "pattern.h"
X
X#ifdef DSOIFEW
Xtypedef struct {        /*Required for pattern matching routine*/
X   char *aux;
X   BYTE type;
X} pattern;
X
Xextern pattern *CompilePattern(char *str);
Xextern BOOL MatchPattern(pattern *,char *);
X#endif
X
Xpattern *MasterPattern;
X
X/*Main function.  This is what is called by the host program:*/
X
XGetFilename(fn,dn,en,cn,X,Y,wn,scr,filepen,dirpen,DisableInfo)
Xchar *fn,*dn,*en,*cn,*wn;  /*See above for parameter definitions*/
XUSHORT X,Y,filepen,dirpen;
XBYTE DisableInfo;
Xstruct Screen *scr;
X{
X   int status=GN_NEWDIR;
X   struct FileLock *DirLock;
X   char temp[150];
X
X   if(DisableInfo)
X      Info.Flags|=SELECTED;
X   else
X      Info.Flags=GADGHIMAGE|GADGIMAGE;
X
X   yafr_e_FilenamePenColor = filepen;
X   yafr_e_DirnamePenColor = dirpen;
X   DirLock=(struct FileLock *)Lock(dn,ACCESS_READ);
X         /*Get lock on first directory*/
X   
X   if(en[0]==NULL)   /*If no pattern was provided*/
X      strcpy(en,"#?");  /*provide one that will give us everything*/
X   
X   strcpy(temp,en);
X   
X   MasterPattern = (pattern *)CompilePattern(temp);
X      /*Compile the pattern matching structure*/
X   
X   strcpy(DirNameSIBuff,dn);  /*Copy some parameters to this modules*/
X   strcpy(ExtNameSIBuff,en);  /*variables*/
X   strcpy(filenameSIBuff,fn);
X   NewFNWindow.LeftEdge=X;
X   NewFNWindow.TopEdge=Y;
X   NewFNWindow.Title=(char *)wn;
X   NewFNWindow.Screen=(struct Screen *) scr;
X   
X         /*If there's a screen, open on it.  Workbench screen otherwise*/
X   NewFNWindow.Type= (scr) ? CUSTOMSCREEN : WBENCHSCREEN;
X
X   PutDevicesInGadgets(NULL,NULL);
X      /*Open the window*/
X   if((FNWindow=(struct Window *)OpenWindow(&NewFNWindow))==NULL)
X      {  /*If it failed...*/
X      UnLock(DirLock); /*Unlock the directory*/
X      return(FALSE);   /*and return*/
X      }
X      
X   /*Write some important text into the title bar:  */
X   SetWindowTitles(FNWindow,-1,"YAFR V1.21 (c)1989, 1990 by Dave Schreiber");
X   
X   
X   SetAPen(FNWindow->RPort,1);
X   Move(FNWindow->RPort,6,19);
X   Text(FNWindow->RPort,"Directory",9);
X   Move(FNWindow->RPort,6,154);
X   Text(FNWindow->RPort,"Pattern",7);
X   Move(FNWindow->RPort,6,165);
X   Text(FNWindow->RPort,"Filename",8);
X   
X      /*Activate the directory string gadget, for user's convenience*/
X      /*Note!  Window must be active for ActivateGadget to work on a*/
X      /*string window!  Take this into account in writing your own code.*/
X      /*I had to learn the hard way...:-( */
X   
X   ActivateGadget(&DirName,FNWindow,NULL);
X   
X   /*Main loop:  While requests for reading a new directory keep coming in...*/
X   while((status = GetName(DirLock)) == GN_NEWDIR)
X      {                             /*keep doing it...*/
X      UnLock(DirLock);  /*Transfer lock to new directory*/
X      RefreshGList(&DirName,FNWindow,NULL,1);
X      DirLock=(struct FileLock *)Lock(DirNameSIBuff,ACCESS_READ);
X      ActivateGadget(&filename,FNWindow,NULL); /*Activate filename gadget*/
X      }  /*Loop back, read the new directory, and wait for input again*/
X
X   UnLock(DirLock); /*Or we could be finished*/
X   if(status) /*If OK pressed...*/
X   {
X      strcpy(fn,filenameSIBuff); /*Setup the return parameters*/
X      strcpy(dn,DirNameSIBuff);
X      strcpy(en,ExtNameSIBuff);
X      if(cn) /*If cn isn't NULL, there's space for a string, so...*/
X      {        /*construct the full filename for the host*/
X         strcpy(cn,DirNameSIBuff);
X         if( (dn[strlen(dn)-1] != ':') && strlen(dn)  && dn[strlen(dn)-1]!='/')
X            strcat(cn,"/");
X         strcat(cn,filenameSIBuff);
X      }
X   }
X
X   CloseWindow(FNWindow); /*Close the window*/
X   ResetGadgets();
X   return(status);      /*and return*/
X}
X
XGetName(Lock)     /*Gets filenames in the directory associated with the*/
Xstruct FileLock *Lock;  /*lock, and also gets user input*/
X{
X   struct fibHeader header;
X   int status3,status2,status;
X   USHORT FNNumber=0;
X
X   header.first=header.directory=NULL;
X   if(GetFib(&header)==FALSE)
X      return(FALSE);
X   SliderSInfo.VertPot=0;
X   UpdateSlider(1,&SliderSInfo,&Slider);
X   ClearFileBox();
X   if(strnicmp(DirNameSIBuff,"PIPE:",5)) /*Check for pipe: device*/
X      if(Lock!=NULL) /*If the lock (& the directory) exist...*/
X         {
X         Examine(Lock,&(CRNT));  /*Get the first entry*/
X         if(GetFib(&header)==FALSE)  /*Get next node*/
X            return(NULL);
X         while((status3=ExNext(Lock,&(CRNT)))) /*Loop while there are files*/
X            {
X            if((status2=((CheckExt(CRNT.fib_FileName) ||
X                  CRNT.fib_DirEntryType > 0) && /*If the specified extension*/
X                  CheckInfo(CRNT.fib_FileName)) )) /*(if any) matches and*/
X               {              /*it isn't a .info file (if masked)*/
X               if(FNNumber<10)   /*display it...*/
X                  PrintFileName(&(CRNT),Rp,XBorder,YBorder+(10*FNNumber++));
X               else  /*or update the slider (if the filename box is full)*/
X                  UpdateSlider(++FNNumber,&SliderSInfo,&Slider);
X               }
X            while((status=CheckIntuiMessages(FNNumber,&header))!=GN_DONE)
X               {  /*After getting a name, checked for IDCMP messages*/
X               if(status==GN_PARENT) /*If PARENT was pressed*/
X                  {
X                  Parentize(DirNameSIBuff); /*Setup the parent dir*/
X                  RefreshGList(&DirName,FNWindow,NULL,1);
X                  FreeFuncMemory(header.directory); /*Free the filename*/
X                  return(GN_NEWDIR);   /*list and return*/
X                  }
X               if(status < GN_PARENT)
X                  {
X                  FreeFuncMemory(header.directory);
X                  return(status);   /*For OK,NEWDIR, & CANCEL*/
X                  }
X               }
X            if(status2) /*If the filename was valid, append another Fib*/
X               if(GetFib(&header)==FALSE) /*structure for the next filename*/
X                  return(NULL);
X              /*If not valid, let the next filename info overwrite the current*/
X              /*Fib*/
X            }
X            header.current->prev->next=NULL; /*Delete the last (unused) Fib*/
X            if(header.directory->next == header.current) /*If no files*/
X               header.directory->next=header.first=header.last=
X                     header.top=NULL;     /*NULL certain pointers*/
X            FreeMem(header.current,sizeof(struct fibNode));
X         }
X   for(;;)  /*Loop until the users says 'Change something!'*/
X      {
X      Wait(1<<FNWindow->UserPort->mp_SigBit);
X      while((status=CheckIntuiMessages(FNNumber,&header))!=GN_DONE)
X         {
X         if(status==GN_PARENT)   /*PARENT pushed*/
X            if(Parentize(DirNameSIBuff))
X               {
X               RefreshGList(&DirName,FNWindow,NULL,1);
X               FreeFuncMemory(header.directory);
X               return(GN_NEWDIR);
X               }
X         if(status < GN_PARENT)  /*Something else pushed*/
X            {
X            FreeFuncMemory(header.directory);
X            return(status);   /*For OK,NEWDIR, & CANCEL*/
X            }
X         }
X      }
X}
X
XCheckInfo(name)  /*Check to see if .info's should be printed*/
Xchar *name;
X{
X   if(!(Info.Flags & SELECTED))
X      return(TRUE);
X
X   return(!(strcmp(&name[strlen(name)-5],".info")==0));
X}
X
Xvoid ClearFileBox() /*Clear the box with the filenames in it*/
X{
X   SetAPen(Rp,0);
X   RectFill(Rp,XBorder,YBorder-6,(25*8)+XBorder,YBorder+(100)-4);
X   SetAPen(Rp,1);
X}
X
XBYTE Parentize(str) /*Convert a directory identifier string into the one*/
Xchar *str;        /*for its parent directory*/
X{
X   int c,stat;
X
X   if(str[0]==NULL)  /*If there is no directory explicitly specified*/
X   {
X      strcpy(str,"/");  /*Go to the parent of the current directory*/
X      return(TRUE);
X   }
X      
X   for(c=0,stat=TRUE;str[c]!=NULL && stat;c++)
X      stat=(str[c]=='/');  /*If nothing but /'s, add another /*/
X      
X   if(stat)
X   {
X      strcat(str,"/");
X      return(TRUE);
X   }
X      
X   if(str[strlen(str)-1]==':')   /*If ':' is the last character*/
X      return(FALSE);          /*We're at the root, and cannot back up*/
X   
X   stat=FALSE;
X   
X   for(c=strlen(str)-1;c >= 0;c--)
X      if(str[c]=='/')   /*Delete last '/' & everything after that*/
X      {
X         if(c==0 || str[c-1]=='/')
X            str[c+1]=NULL;
X         else
X            str[c]=NULL;
X         c=0;
X         stat = TRUE;
X      }
X      else
X         if(str[c]==':')   /*Or delete everything after the ':'*/
X         {              /*(which leaves the root)*/
X            str[c+1]=NULL;
X            c=0;
X            stat=TRUE;
X         }
X   if(!stat)   /*If neither a / or a : were found, delete the whole thing*/
X      strcpy(str,"");
X   return(TRUE);
X}
X
Xvoid UpdateSlider(Amt,Info,Gadgt) /*Update the slider bar to reflect*/
XUSHORT Amt;             /*the number of file/dir names available for selection*/
Xstruct PropInfo *Info;
Xstruct Gadget *Gadgt;
X{
X   Info->VertBody=((0xFFFF*10)/Amt);
X   RefreshGadgets(Gadgt,FNWindow,NULL);
X}
X
XCheckIntuiMessages(Max,header) /*Check and respond to the window's IDCMP*/
XUSHORT Max;             /*messages*/
Xstruct fibHeader *header;
X{
X   struct fibNode *cur;
X   UBYTE c,line;
X   struct IntuiMessage *mesg;
X   struct Gadget *InUse;
X   ULONG Class,Seconds,Micros;
X   static ULONG OldSeconds=0;
X   static ULONG OldMicros=0;
X   USHORT Code;
X   SHORT X,Y;
X   char temp[150];
X
X   /*Assumes that the calling function has either Wait()ed or wants to*/
X   /*handle any IDCMP messages that have piled up*/
X   
X   while((mesg=(struct IntuiMessage *)GetMsg(FNWindow->UserPort))!=NULL)
X      {
X      InUse=(struct Gadget *)mesg->IAddress;
X      X=mesg->MouseX;
X      Y=mesg->MouseY;
X      Class=mesg->Class;
X      Code=mesg->Code;
X      Seconds=mesg->Seconds;
X      Micros=mesg->Micros;
X      ReplyMsg(mesg); /*Reply to the message*/
X      switch(Class)  /*Decide what happened*/
X         {
X         case MOUSEMOVE: /*If the mouse moved, then the silder is down, so*/
X            if(Max > 10) /*update the filenames in the box to reflect the*/
X               UpdateList(SliderSInfo.VertPot,Max,header); /*slider's*/
X            break;                                               /*position*/
X         case GADGETUP:
X            if(InUse->GadgetID <= 10)
X            {  /*One of the device gadgets was pushed*/
X               if(strnicmp(InUse->GadgetText->IText,"PIPE:",5))
X               {        /*Find the volume name if it isn't the PIPE:*/
X                  MakeAbsName(InUse->GadgetText->IText);
X                  strcpy(DirNameSIBuff,absDirName);
X                  strcat(DirNameSIBuff,":");
X               }
X               else
X                  strcpy(DirNameSIBuff,InUse->GadgetText->IText);
X               RefreshGList(&DirName,FNWindow,NULL,1);
X               return(GN_NEWDIR);
X            }
X            switch(InUse->GadgetID)
X            {
X               case 14: /*CANCEL was pushed*/
X                  return(GN_CANCEL);
X               case 12: 
X               case 13: /*OK was pushed or return was pressed in the*/
X                 return(GN_OK);  /*filename's box*/
X               case 15:
X                  return(GN_PARENT); /*PARENT was pushed*/
X               case 18:  /*Return was pushed in file pattern box*/
X                  if(ExtNameSIBuff[0]==NULL) /*If a blank field*/
X                  {
X                     strcpy(ExtNameSIBuff,"#?"); /*give a global file pattern*/
X                     RefreshGList(&ExtName,FNWindow,NULL,1);
X                  }
X                  strcpy(temp,ExtNameSIBuff);
X                  MasterPattern=(pattern *)CompilePattern(temp);
X               case 11:  /*Return was pushed in the filename box*/
X                  return(GN_NEWDIR);  /*a new one*/
X            }
X            return(GN_RIEN);     /*Nothing important*/
X         case DISKINSERTED:
X            PutDevicesInGadgets(FNWindow,DISKINSERTED);
X            return(GN_RIEN);
X         case DISKREMOVED:
X            PutDevicesInGadgets(FNWindow,DISKREMOVED);
X            return(GN_RIEN);
X         case GADGETDOWN:     /*The .info gadget was pressed?*/
X         if(InUse->GadgetID == 18)
X            return(GN_NEWDIR);
X
X            /*A file/dir name in the box was clicked on*/
X         if(strnicmp(DirNameSIBuff,"PIPE:",5)) /*If the pipe:*/
X            {                             /*don't try & get a filename*/
X            line=(Y-YBorder+7)/10;    /*Get line clicked on*/
X            
X            for(c=0,cur=(struct fibNode *)header->top;c!=line && cur!=NULL;c++)
X               cur=(struct fibNode *)cur->next; /*Find the file's Fib*/
X               
X            if(cur != NULL)   /*If the file exists*/
X               if(cur->fib.fib_DirEntryType > 0)
X               {        /*It's a directory, so read that directory*/
X                  if(DirNameSIBuff[strlen(DirNameSIBuff)-1] != ':' && 
X                        DirNameSIBuff[strlen(DirNameSIBuff)-1] != '/')
X                     if(DirNameSIBuff[0]!=NULL)
X                        strcat(DirNameSIBuff,"/"); 
X                        
X                  strcat(DirNameSIBuff,cur->fib.fib_FileName);
X                  RefreshGList(&DirName,FNWindow,NULL,1);
X                  return(GN_NEWDIR);
X               }
X               else   /*otherwise, return the filename clicked upon*/
X               {
X                  if(strcmp(filenameSIBuff,cur->fib.fib_FileName)==0 && 
X                        DoubleClick(OldSeconds,OldMicros,Seconds,Micros))
X                     return(GN_OK); /*Double-click == OK*/
X                  strcpy(filenameSIBuff,cur->fib.fib_FileName);
X                  RefreshGList(&filename,FNWindow,NULL,1);
X                  OldSeconds=Seconds;  /*Store the time values*/
X                  OldMicros=Micros; 
X               }
X            }
X         }
X      }
X   return(GN_DONE);  /*All done...*/
X}
X
Xvoid UpdateList(Pos,Num,header) /*Update filenames in the filename box*/
XUSHORT Pos;                   /*According to the slider's position*/
XUSHORT Num;
Xstruct fibHeader *header;
X{
X   static USHORT LastFirstItem=30000;
X   ULONG FirstItem;
X   FirstItem=(((Pos+1)*(Num-10)) >> 16);
X
X   if( FirstItem != LastFirstItem)
X      RewriteList(FirstItem,header);
X   LastFirstItem=FirstItem;
X}
X
Xvoid RewriteList(First,header)  /*Rewrite the list of filenames in the*/
XUSHORT First;                 /*filename box...*/
Xstruct fibHeader *header;
X{
X   register struct fibNode *node;
X   register USHORT c,Y;
X
X   if(First)   /*If we're not starting at the start...*/
X      for(c=0,node=(struct fibNode *)header->first;c < First;c++)
X         node=(struct fibNode *)node->next; /*Get the first filename*/
X   else     /*Otherwise, start at the top*/
X      node=(struct fibNode *)header->first;
X   header->top=(struct fibNode *)node;
X   
X   /*Print the filenames (up to 10)*/
X   for(c=0,Y=YBorder;(c < 10) && (node!=NULL);
X         c++,Y+=10,node=(struct fibNode *)node->next)
X      PrintFileName(&(node->fib),Rp,XBorder,Y);
X}
X
XBOOL CheckExt(name) /*Check to see if 'name' has the supplied extension*/
Xchar *name;
X{
X   return(MatchPattern(MasterPattern,name));
X}
X
XBYTE GetFib(header)
Xstruct fibHeader *header;
X{
X   header->last=(struct fibNode *)header->current;
X   if((header->current=(struct fibNode *) /*Allocate a FIB structure*/
X         AllocMem(sizeof(struct fibNode),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
X      {
X      FreeFuncMemory(header->current); /*Whoops, it didn't work...*/
X      return(FALSE);
X      }
X   if(header->directory==NULL) /*Must want it for a directory...*/
X      header->directory=(struct fibNode *)header->current;
X   else  /*Append to the current FIB list*/
X      {
X      if(header->first==NULL)
X         {
X         header->directory->next=header->first=header->last=header->top=
X               (struct fibNode *)header->current;
X         CopyFIB(&(header->directory->fib),&(header->current->fib));
X         }
X      else
X         {
X         CopyFIB(&(header->last->fib),&(header->current->fib));
X         header->last->next=(struct fibNode *)header->current;
X         header->current->prev=(struct fibNode *)header->last;
X         }
X      }
X   return(TRUE);
X}
X
Xvoid CopyFIB(from,to) /*Copy a fileinfoblock from 'from' to 'to'*/
Xstruct FileInfoBlock *from,*to;
X{
X   to->fib_DiskKey=from->fib_DiskKey;
X   to->fib_DirEntryType=from->fib_DirEntryType;
X   to->fib_Protection=from->fib_Protection;
X   to->fib_EntryType=from->fib_EntryType;
X   to->fib_Size=from->fib_Size;
X   to->fib_NumBlocks=from->fib_NumBlocks;
X   strcpy(to->fib_FileName,from->fib_FileName);
X   strcpy(to->fib_Comment,from->fib_Comment);
X   to->fib_Date.ds_Days=from->fib_Date.ds_Days;
X   to->fib_Date.ds_Minute=from->fib_Date.ds_Minute;
X   to->fib_Date.ds_Tick=from->fib_Date.ds_Tick;
X}
X
Xvoid PrintFileName(fib,RPrt,X,Y)  /*Print a filename in the filename box*/
Xstruct FileInfoBlock *fib;
Xstruct RPort *RPrt;
XUSHORT X,Y;
X{
X   UWORD len;
X   char name[40];
X   
X   strcpy(name,fib->fib_FileName);
X   if(fib->fib_DirEntryType > 0) /*Set the pen color, according to whether*/
X   {        /*we're printing a filename or a directory name*/
X      SetAPen(RPrt,yafr_e_DirnamePenColor); 
X      strcat(name,"  (dir)"); /*Append '  (dir)' if it's a directory*/
X   }
X   else
X      SetAPen(RPrt,yafr_e_FilenamePenColor);
X   Move(RPrt,X,Y);
X   Text(RPrt,"                         ",25);  /*Blank out the space*/
X   Move(RPrt,X,Y);
X   len = (strlen(fib->fib_FileName)<=25) ? strlen(fib->fib_FileName) : 25;
X   Text(RPrt,fib->fib_FileName,len);   /*Trundicate the filename at 25 chars*/
X                                       /*and print it.*/
X}
X
Xvoid FreeFuncMemory(first)   /*Free the memory taken up by a fib list*/
Xregister struct fibNode *first;
X{
X   register struct fibNode *next,*current;
X   next=(struct fibNode *)first->next;
X   FreeMem(first,sizeof(struct fibNode));
X   while((current=(struct fibNode *)next)!=NULL)
X      {
X      next=(struct fibNode *)current->next;
X      FreeMem(current,sizeof(struct fibNode));
X      }
X}
X
Xvoid PutDevicesInGadgets(Wdw,stat)
Xstruct Window *Wdw;
XULONG stat;
X{
X
X   /*structure definitions*/
X   struct RootNode *root;
X   struct DosInfo *dosinfo;
X   struct DeviceList *devlist;
X   struct Gadget *button,*onbutton,*lastunghosted;
X   UBYTE c=0;
X   UBYTE old_c;
X   
X   char devname[35]; /*This is where the device name (DH0:, DF0:, etc.) will
X                        end up*/
X
X   /*Get the first entry in the list of devices*/   
X   root=(struct RootNode *)DOSBase->dl_Root;
X   dosinfo=(struct DosInfo *)BADDR(root->rn_Info);
X   devlist=(struct DeviceList *)BADDR(dosinfo->di_DevInfo);
X
X   /*Go through the linked list of devices*/
X
X   for(button=(struct Gadget *)&df0 ; c<10 && devlist ; devlist=
X      (struct DeviceList *)BADDR(devlist->dl_Next))
X
X      if(devlist->dl_Type==DLT_DEVICE && devlist->dl_Task && 
X      	IsDOSDisk(devlist)) /*If it's a disk-type (RAM, hard, floppy) drive:*/
X
X      {
X         bstrcpy(devname,(BPTR)devlist->dl_Name); /*Convert the BSTR to a*/
X         strcat(devname,":");    /*regular string and add a ':'*/
X         
X	      /*Devices with removable media must have the media inserted before*/
X         /*they'll show up.  Of course, this is meaningless when talking*/
X         /*about non-removable hard drives, RAM drives, etc.*/
X	 
X	      /*Copy the text to the Gadget text area*/
X	      strcpy(button->GadgetText->IText,devname);
X         c++;
X         lastunghosted=(struct Gadget *)button;
X         button=(struct Gadget *)button->NextGadget;
X      }
X   if(Wdw!=NULL)
X      SetAPen(Rp,0);
X
X      /*Clear & switch on gadgets that'll are in use now*/
X   
X   old_c=c;
X   if(stat!=DISKREMOVED)
X      if(FirstDisabled != NULL)
X         for(onbutton=(struct Gadget *)FirstDisabled;button!=NULL && 
X                  onbutton!=(struct Gadget *)button && 
X                  onbutton!=(struct Gadget *)&pipe;
X                  onbutton=(struct Gadget *)onbutton->NextGadget)
X            if(Wdw == NULL)
X               onbutton->Flags -= GADGDISABLED;
X            else
X            {
X               RectFill(Rp,onbutton->LeftEdge,onbutton->TopEdge,
X                     onbutton->LeftEdge+onbutton->Width-1,
X                     onbutton->TopEdge+onbutton->Height-1);
X               OnGadget(onbutton,Wdw,NULL);
X            }
X         
X      
X   FirstDisabled=(struct Gadget *)button; /*Store the first ghosted gadget*/
X   
X   if(stat!=DISKINSERTED)
X      for(;c < 10 && !(button->Flags && GADGDISABLED);c++,
X            button=(struct Gadget *)button->NextGadget)
X      {  /*Clear out any unused gadget text & deactivate unused gadgets*/
X         strcpy(button->GadgetText->IText,"    ");
X         if(Wdw==NULL)
X            button->Flags += GADGDISABLED;
X         else
X            OffGadget(button,Wdw,NULL);
X      }
X      
X   if(Wdw != NULL)
X      RefreshGList(&df0,Wdw,NULL,old_c); /*Refresh the gadgets*/
X}
X
Xvoid ResetGadgets()
X{
X   struct Gadget *gadg;
X   
X   for(gadg=(struct Gadget *)&df0;gadg!=(struct Gadget *)&pipe;
X         gadg=(struct Gadget *)gadg->NextGadget)
X      gadg->Flags = NULL;
X
X}
X
Xvoid bstrcpy(dest,source)  /*Copy a BSTR to a regular string*/
XBSTR source;
Xchar *dest;
X{
X   register UBYTE *ch;
X   register int len,i;
X   
X   ch=(UBYTE *)BADDR(source);
X   len=(int) *(ch++);
X   len=(len>20)?20:len;
X   
X   for (i=0;i<len;i++)
X      dest[i]=*(ch++);
X   dest[i]=NULL;
X}
X
XBYTE IsDOSDisk(devlist)    /*Check to see if a device in a disk-type device*/
Xstruct DeviceList *devlist;  /*(the sort of device that shows up when the*/
X{                          /*AmigaDOS INFO command is run)*/
X   struct MsgPort *port;
X   BYTE result;            
X   struct InfoData *info;  
X   struct StandardPacket *diskpacket;
X
X  	result=FALSE;  
X   
X   /*Allocate memory for the Port to use*/
X   info=(struct InfoData *) AllocMem(sizeof(struct InfoData),
X         MEMF_CLEAR|MEMF_PUBLIC);
X   if(info==NULL)
X      return(FALSE);
X   
X   diskpacket=(struct StandardPacket *) 
X         AllocMem(sizeof(struct StandardPacket),MEMF_CLEAR|MEMF_PUBLIC);
X   if(diskpacket==NULL)
X   {
X      FreeMem(info,sizeof(struct InfoData));
X      return(FALSE);
X   }
X   
X   /*Allocate the port*/
X   port=(struct MsgPort *) CreatePort(NULL,0);
X   if(port==NULL)
X   {
X      FreeMem(info,sizeof(struct InfoData));
X      FreeMem(diskpacket,sizeof(struct StandardPacket));
X      return(FALSE);
X   }  
X   
X   /*Set up the message to send to the device*/
X   diskpacket->sp_Msg.mn_Node.ln_Type=NT_MESSAGE;
X   diskpacket->sp_Msg.mn_Node.ln_Name=(char *)&diskpacket->sp_Pkt;
X   diskpacket->sp_Msg.mn_ReplyPort=port;
X   diskpacket->sp_Pkt.dp_Link=&diskpacket->sp_Msg;
X   diskpacket->sp_Pkt.dp_Type=ACTION_DISK_INFO;
X   diskpacket->sp_Pkt.dp_Arg1=((LONG)info>>2);
X   diskpacket->sp_Pkt.dp_Port=port;
X   
X   /*Send the message*/
X   PutMsg(devlist->dl_Task,&diskpacket->sp_Msg);
X   
X   /*and wait for a reply...*/
X   WaitPort(port);
X   
X   /*Store the result*/
X   result=(info->id_DiskType==ID_DOS_DISK);
X
X   /*Deallocate resources*/
X   DeletePort(port);
X   FreeMem(info, sizeof(struct InfoData));
X   FreeMem(diskpacket, sizeof(struct StandardPacket));
X   
X   /*And return the result*/
X   return(result);
X}
X
X
X/*!*******************************************************************
X * FindRoot by Bruce Rogers 1/20/90
X *********************************************************************/
X
X/*!*******************************************************************
X * Kludges disk:name/directory with filename so we can just read it.
X *********************************************************************/
Xvoid    DosConcatenate(string1,string2,result)
Xchar    string1[],string2[],result[];
X{
Xshort   i,j;
X
X    for(i=0; string1[i] != '\0'; i++)
X        result[i]=string1[i];
X    if ((result[i-1] != ':') && (result[i-1] != '/') && (i!=0) && string2[0]!=0)
X    {
X        result[i]='/';
X        ++i;
X    }
X    for(j=0; string2[j] != '\0'; j++)
X        result[i+j] = string2[j];
X    result[i+j] = '\0';
X}
X
X/*!*******************************************************************
X * Recursively go up parent chain, looking for oldest parent.
X * Create the absolute path string as we go.
X *********************************************************************/
XSeekRoot(oldlock)
XULONG   oldlock;
X{
Xshort   i;
XULONG   newlock;
Xstruct  FileInfoBlock *fileInfo;
X
X    fileInfo=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),
X          MEMF_CLEAR);
X    if(fileInfo==NULL)
X       return(FALSE);
X    Examine(oldlock,fileInfo);
X    DosConcatenate(fileInfo->fib_FileName,absDirName,absDir);
X    for(i=0;i<MAXPATHSTRING;i++) absDirName[i]=absDir[i];
X    newlock=ParentDir(oldlock);
X    UnLock(oldlock);
X    oldlock=newlock;
X    if (oldlock!=NULL) SeekRoot(oldlock);
X    FreeMem(fileInfo,sizeof(struct FileInfoBlock));
X
X}
X
X/*!*******************************************************************
X * Given a path, sets absDirName equal to the absolute path
X *********************************************************************/
X        MakeAbsName(dirName)
Xchar    *dirName;
X{
Xshort   i;
XULONG   lock;
X
X    for(i=0;i<MAXPATHSTRING;i++) absDirName[i]=absDir[i]=0;
X    lock=Lock(dirName,ACCESS_READ);
X    if (lock==NULL)
X      return(NULL);
X    SeekRoot(lock);
X    for(i=0;i<MAXPATHSTRING;i++)
X    {
X        if (absDirName[i]=='/')
X        {
X            absDirName[i]=':';
X            break;
X        }
X    }
X}
X
X/*End of YAFR.c*/
END_OF_FILE
if test 29701 -ne `wc -c <'YAFR.c'`; then
    echo shar: \"'YAFR.c'\" unpacked with wrong size!
fi
# end of 'YAFR.c'
fi
if test -f 'yftest.uu' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'yftest.uu'\"
else
echo shar: Extracting \"'yftest.uu'\" \(22833 characters\)
sed "s/^X//" >'yftest.uu' <<'END_OF_FILE'
Xbegin 664 yftest
XM```#\P`````````)``````````@```/9````/P``!E]````R```$CP```!\`K
XM```Q````'````#P```/I```#V4CG?OXD2"0`2?D`````+'@`!$?Y```+U'(`'
XM(#P```&:8`(FP5'(__PI3PP4*4X,#$*L#!!P`"(\```P`$ZN_LY#^@%:<`!.A
XMKOW8*4`19&8&<&1@``#\)FX!%"EK`)@,"$JK`*QG:"`/D*\`!`:`````@"E`W
XM"]@@:P"LT<C1R")H`!#3R=/)(`)R`!(9*4D,'-"!4H!"9U*``D#__I_`58!"*
XM=P@`(`)3@-2!'[(``"``4X)1R/_V'[P`("``4X(?L2``(`!1RO_X(D\O"6!RJ
XM*6L`.@O8<']2@-&L"]A!ZP!<3J[^@$'K`%Q.KOZ,*4`,$"\`)$`@*@`D9Q(L-
XM;!%D($`B*```*4$,"$ZN_X(B*@`@9QHD/````^U.KO_B*4`,&&<*Y8@@0"=HZ
XM``@`I"!L#!`O"$AL"]0@:``D*6@`!`P<3KH`9DZZ"`9P`&`$("\`!"\`("P,Y
XM`&<$($!.D$ZZ!NXL>``$(FP19$ZN_F).N@`\2JP,$&<:(BP,&&<$3J[_W"QX;
XM``1.KO]\(FP,$$ZN_H8@'RYL#!1,WW]^3G5D;W,N;&EB<F%R>0!.=4YU+FP,>
XM%$ZZ"W9(>0```!1.N@,T``````````!P82`O``0,``!A;0H,``!Z;@0$```@5
XM3G4``$CG(#`F;P`0)$M*$F<D<``0$D'L"D4(,``!"`!G"G(`$@!T()*"8`1R_
XM`!(`%(%2BF#8(`M,WPP$3G4``````````'!A3E7__$CG`S`F;P`<)&\`("XOV
XM`"1*AV<V2A-G,DH29RYP`!`;+P!.NO]\<@`2&BZ!+T``%$ZZ_VY83R(O`!"2E
XM@"P!2H9G!"`&8!I3AV#&2H=G$$H39P1P`6`*2A)G!'#_8`)P`$S?#,!.74YU@
XM3E7_^$CG`S`F;P`@)&\`)"XO`"@@2DH89OQ3B)'*+`@@2TH89OQ3B)'+(`@BU
XM2]/`*TG_^+R'8P(L!R`&($I@`A+84X!D^B!M__A",&@`(`M,WPS`3EU.=2)OP
XM``@@;P`$(`A*&&;\4X@0V6;\3G4``$CG`1`F;P`,+B\`$'``$!.PAV8$(`M@]
XM"!`;2@!F[G``3-\(@$YU2.<!$"9O``PN+P`0+P<O"V'(4$],WPB`3G5(YP$P3
XM)F\`$"XO`!25RDH39PYP`!`3L(=F`B1+4HM@[B`*3-\,@$YU(&\`!"`O``AO0
XM"B(O``P0P5.`9OI.=0``(&\`!$CH_OX`!"%O`````'``3G4@+P`(9@)2@"!O4
XM``1,Z/[^``0O:`````!.=0``2.</$"XO`!@L+P`<*B\`("\'3KH$/%A/)D`@P
XM"V8$</]@'B\%+P8O*P`$3KH!U$_O``PH`$JL"^QG!'#_8`(@!$S?"/!.=0``K
XM````````<&%(YP,P+B\`%$J';@9P`&```*1P"+Z`9`(N`"`'5H`N``)'__Q%;
XM[`G,)E(@"V=`("L`!+"';3*PAV8,(%,DB)^L"=`@"V!N("L`!)"'<@BP@646A
XM($O1QR2()$@DDR5```2?K`G0(`M@3"1+)E-@O"`'(BP*0-"!4X!.N@(R(BP*Q
XM0$ZZ`@HL`%"&(`96@"P``D;__"\&3KH#YEA/)D`@"V<2+P8O"TZZ!T(NAV$`N
XM_U103V`"<`!,WPS`3G4``````````````````"\+)F\`""`+9Q!"ITZZ"`)8*
XM3R!+68@I2!(X<``F7TYU````````<&%(YP,0+B\`$$?L"=0@"V<T""L``@`;T
XM9B@(*P`!`!MG("`K``20JP`0+`!*AF<2+P8O*P`0+RL`'$ZZ`\)/[P`,)E-@X
XMR"\'3KH&3%A/3-\(P$YU``````````!P84CG-Q`N+P`<)F\`("PO`"1*K`P$O
XM9P1.N@FT0JP+["(')`LF!BQL$61.KO_0*@!P_[J`9@Y.KO]\*4`+['`%*4`1^
XM8"`%3-\([$YU``````````````````````````````````!(YS\`+B\`'"POI
XM`"`J+P`D2JP,!&<$3KH)4$*L"^P@!5.`(@<D!B8`+&P19$ZN_[XH`'#_N(!F`
XM#DZN_WPI0`OL<!8I0!%@(`4,@`````)G%@R``````6<(2H!F&"`&8!0@!-"&-
XM8`XB!W0`=@`L;!%D3J[_ODS?`/Q.=0``2.<`$B9O``Q*JP`*9PHB2RQX``1.F
XMKOZ8%WP`_P`(</\G0``4<``0*P`/+'@`!$ZN_K`B2W`B3J[_+DS?2`!.=2\'H
XM+B\`"$JL#`1G!$ZZ")XB!RQL$61.KO_<<``N'TYU2.<P`"0`)@%(0DA#Q,'&;
XMP,#!U$-(0D)"T(),WP`,3G5*@&H``!Y$@$J!:@``#$2!80``($2!3G5A```80
XM1(!$@4YU2H%J```,1(%A```&1(!.=2\"2$$T`68``")(0$A!2$(T`&<```:$W
XMP3`"2$`T`(3!,`)(0C(")!].=2\#=A`,00"`9```!N&944,,00@`9```!NF9H
XM64,,02``9```!N6954-*06L```;CF5-#-`#FJ$A"0D+FJDA#@,$V`#`"-`-(J
XM0<3!D()D```(4T/0@63^<@`R`TA#Y[A(0,%!)A\D'TYU2.<#,B9O`!@N+P`<]
XM</\L>``$3J[^MBP`#`8`_V8$<`!@9G`B(CP``0`!3J[_.B1`(`IF"G``$`9.=
XMKOZP8$@E2P`*(`<50``)%7P`!``(0BH`#A5&``^3R4ZN_MHE0``0(`MG"")*O
XM3J[^GF`:0>H`&"5(`!1!Z@`4)4@`'$*J`!@5?``"`"`@"DS?3,!.=0``+P<N=
XM+P`(<``I0`OL2H=K(KZL";QL'"`'YX!![!`@2K`(`&<.(`?G@$'L$"#1P"`(B
XM8`AP"2E`$6!P`"X?3G4``````````````````$CG`#(F;!%H(`MG%"13(DL@1
XM*P`(+'@`!$ZN_RXF2F#HD<@I2!%L*4@1:$S?3`!.=4CG`3(N+P`4<`S>@"`'[
XM<@`L>``$3J[_.B9`(`MF!'``8#HG1P`(1>P1:"!J``0G2``$D<@FB$J29@(DD
XMBTJJ``1G!B)J``0BBR5+``1*K`G`9@0I2PG`0>L`#"`(3-],@$YU````````A
XM``````````!(YP<P+B\`&"9O`!PL+P`@+P=.NO\`6$\D0"`*9@1P_V`V""H`:
XM`P`#9Q!(>``"0J<O!TZZ^I!/[P`,+P8O"R\J``1.NOP<3^\`#"H`2JP+[&<$R
XM</]@`B`%3-\,X$YU``!.5?_P2.<A,B9O`"P,K````"`1KFP``(80$W(@L`%G[
XM#'()L`%G!G(*L`%F!%*+8.A*$V=H("P1KN6`4JP1KD'L$;;1P"1(<"*P$V8F,
XM4HLDBTH39PIP(K`39P12BV#R2A-F#$AX``%.N@'06$]@GD(;8)HDBTH39Q@0)
XM$W(@L`%G$'()L`%G"G(*L`%G!%*+8.1*$V8"8`9"&V``_W)*K!&N9@8@;`P0%
XM8`1![!&V*4@1LDJL$:YF?$/Z`21-[!%T+-DLV2S9+-D\D2)L#!`@:0`D2'@`[
XM*"\H``1(;!%T3KKX9D_O``PL;!%D0>P1="(()#P```/N3J[_XBE`$"0I0!`L%
XM<A`I01`H*4`0-"E!$##E@"M`__`L>``$D\E.KO[:(&W_\")`(V@`"`"D?@`K0
XM0/_T8"HL;!%D3J[_RBE`$"1.KO_$*4`0+$'Z`*8B""0\```#[4ZN_^(I0!`TU
XM?A`@!P!`@`&!K!`@(`<`0(`"@:P0*`"L``"``Q`P2JP*/&<$<`!@!B`\``"`I
XM`"X`0JP)\"`'`$```2E`">QP`2E`"A(@!P!```(I0`H.<`(I0`HT(`<`0`"`[
XM*4`*,$'Z`MHI2`P$+RP1LB\L$:Y.N@`F0I=.NOG43.U,A/_<3EU.=6-O;CHQ,
XM,"\Q,"\S,C`O.#`O`"H`3OD`````````````````````<&%(YS`R+&\`."!O_
XM`!@B;P`<)&\`("9O`"0@+P`H(B\`+"0O`#`F+P`T3J[^I$S?3`Q.=0``2.<'+
XM`"XO`!`@+`F\4X`L`$I&:S`@!DC`YX!![!`@*C`(`$H%9QH(!0`$9A0@!DC`%
XMYX!![!`@+S`(!$ZZ^JQ83U-&8,PO!TZZ]8!83TS?`.!.=0``(F\`""!O``0@]
XM"1#99OQ.=4Y5_^A(YP$R+B\`-$J';@9P_V```-)P"+Z`9`(N`"`'5H`N``)'X
XM__PD;0`(("T`"-"'WZP)T$'L"<PF4"M`__`K2/_T(`MG``"0($L@*P`$T<`KT
XM2/_L(FW_\+?)8Q`DBR5'``0L;?_T+(IP`&!XM\EF&BQ3)(X@*P`$(@#2AR5!N
XM``0L;?_T+(IP`&!:M<AD")^L"=!P_V!.M<AF+$J39PX@4[/(8PB?K`G0</]@'
XM.-^K``1*DV<.L]-F"B`I``31JP`$)I%P`&`>*TO_]"MM_^S_Z"938`#_;B!MF
XM__0@BD*2)4<`!'``3-],@$Y=3G4``$CG`3`N+P`02JP2.&<6)&P2."\2+RP2(
XM.$ZZ_O903Y'(*4@2.$J'9@1P`&`>6(<O!TZZ]O983R9`2H!F!'``8`HD2R2'.
XM0>L`!"`(3-\,@$YU3E7_J$CG`0(L>``$0_H`CG``3J[]V"M`_ZAF"DAX`!1.F
XMNOXZ6$]^`"!L#!P>*/__(`=#[?^P8`(2V%.`9/I"-7BP0>W_L"E("U0O+?^HA
XM2'@`*$AX`/IP`"\`+P!(;`MP<@`O`4AL"UPO`4ZZ_;Q(>``43KK]Z$SM0(#_&
XMH$Y=3G4J*B!3=&%C:R!/=F5R9FQO=R`J*@``15A)5```:6YT=6ET:6]N+FQI`
XM8G)A<GD```````````!P84Y5_YA(YS,"?@`@;`P<'BC__W!/OH!O`BX`(`=#+
XM[?^O8`(2V%.`9/I"-7BO+'@`!)/)3J[^VBM`_Z8@0$JH`*QG4B(H`*SE@2)!4
XM+"D`.$CM``+_GDJ&9@0L*`"@2H9G-"QL$60B!D'Z`+(D"'8+3J[_T"!'4H<@T
XM"!N\``H(KRQL$60B!B8'0>W_KR0(3J[_T'#_8%(L>``$0_H`C'``3J[]V"M`3
XM_YIF!'#_8#I![?^O*4@+I"\M_YI(>``\2'@`^G``+P`O`$AL"\!(;`NL2&P+J
XMF$*G3KK\FD_O`"13@&<$</]@`G``3-]`S$Y=3G4J*B!5<V5R($%B;W)T(%)EG
XM<75E<W1E9"`J*@``0T].5$E.544``$%"3U)4`"HJ*B!"<F5A:SH@`&EN='5I2
XM=&EO;BYL:6)R87)Y`$CG`0(L>``$<``B/```,`!.KO[.+@`"AP``,`!*AV<@\
XM2JP,!&<:(&P,!$Z02H!F`F`.0JP,!$AX`!1.NOPP6$],WT"`3G5AN$YU````8
XM``/L`````0````$```L^`````@````0````4````"@````````/R```#Z0``_
XM`#].5?Y\O^P+V&4``,XO!V$``%A"+?_?2&P``$AM_TE.N@#62&P`!DAM_S=.;
XMN@#*<`$N@$AX``,O`'(`+P%(;``(2'@`"DAX`"`O`4AM_S=(;?])2&W_WTZZ0
XM`)(N`&$``%@N+?YX3EU.=;_L"]AE``!J0J=(;``:3KH`9E!/*4`,($J`9@I(P
XM>``*3KH`6EA/0J=(;``L3KH`2%!/*4`,)$J`9A(O+`P@3KH`2$AX`!1.N@`T%
XM4$].=;_L"]AE```<+RP,)$ZZ`"PNK`P@3KH`)$*73KH`$EA/3G5.^0```:Q.!
XM^0```*Q.^0``!/!.^0``!E1.^0```)A.^0``"]@```/L`````P````````#FB
XM````^````-H````!`````@```.P````"````!@```/(```#@`````````_(`0
XM``/I```&7TY5__R_[`O890`8F"\'+BT`""\'3KH8GEA/*T#__$J`9@Y(>/__H
XM2&P/WDZZ&1A03T*G+P<O+?_\3KH8^"`M__PN+?_X3EU.=;_L"]AE`!A4+PLF.
XM;P`(+PM.NAB<6$\F7TYUO^P+V&4`&#I(YP$0)F\`#'X!2A-G(!`32(`$0``H\
XM9P930&<&8`Q21V`(4T=F!"`+8`92BV#<<`!,WPB`3G5.5?_@O^P+V&4`%_A(Z
XMYP<0)FT`"$*M__A^`"!+2AAF_%.(D<L@"%*`.T#_\"(+9@9P`&```JHP+?_PH
XM2,!R!DZZ&$8O`&$`_QI83RM`__P0&QM`_^]G``(R&U/_[A(`2($$00`C9P``P
XML%5!9P`!5E=!9QA306<``EP$00`69P`!,`1!`#UG:&```4X0+?_N<GRP`6<`7
XM`CYR*;`!9P`"-B`'P?P`!B!M__P1O``%"`0@2R\(*TC_ZF$`_PI83R9`(`MG"
XM``(00AL@!\'\``8O+?_J+T``%&$`_RI83R!M__PB+P`0(8`8`&8``9I@``'F\
XM$"W_[G)\L`%G``':<BFP`6<``=(@!\'\``8@;?_\$;P``0@$8``!;A`M_^YR(
XM([`!9P`!LG)\L`%G``&J<BFP`6<``:)*`&<``9PB!\/\``8@;?_\$;P``A@$D
XM$@!(@01!`"5G``$P54%G$%-!9P`!)@1!`!=G``$>8`0;6__N4D<@!W(&P<$@/
XM;?_\0C`(!"`'P<%(>``"+T``%&$`_=983R!M__PB+P`0(8`8`"`'P?P`!B!P+
XM"``0K?_N4HM@``#6(`?!_``&(&W__!&\``,(!&```,(@!\'\``8@;?_\$;P`T
XM!`@$8```KB`'P?P`!B!M__Q",`@$($M*&&;\4XB1RR`(5(`J`"`%2,`O`&$`7
XM_6183R!`$*W_[WP!*T#_YDH39RP0$TB`2,`O`$AL"0Q.NA7\4$]*@&86<">P`
XM$V8"4HL@!E)&(&W_YA&;``!@T"!M_^9",&``(`?!_``&(@9(P5*!+P$O0``4)
XM80#]""!M__PB+P`4(8`8`"!M_^8B0!+89OP@0"Z(3KH5VBZM_^9A`/TJ6$]2Z
XM1V``_<@@!U)'P?P`!B!M__P1O``&"`0@!TC`<@9.NA7D+P!A`/RX6$\B!TC!;
XM+T``$'`&3KH5SB!M__PB;P`08`(2V%.`9/H@;P`0*TC_^"\M__QA`/S0("W_?
XM^$SM".#_T$Y=3G5.5?_XO^P+V&4`%1!(YP,P)FT`""1M``P@;0`02AAF_%.(>
XMD>T`$"`(4H`L`"!M`!!*&&;\4XB1[0`0(`A2@"\`80#\-EA/?@`K0/_XOD9LQ
XM0B\M__@O"R!M`!1.D%!/2D!G'"\M`!`O"F$``2Y03TI`9PPO+?_X80#\2'`!T
XM8!X@;0`0(FW_^!.8<``K2``04D=@NB\M__AA`/PH<`!,[0S`_^A.74YU3E7_V
XM_+_L"]AE`!1J2.<`,"9M``@D;0`,*TO__%R+(&W__!`H``1(@`Q```=D``"R1
XMT$`P.P`&3OL`!``,`*0`I`!4`*0`?@"D+PHO"V$``7A03TI`9P9P`6```(XB@
XM;?_\(%%*&&;\4XB1T2\(+Q$O"DZZ%'I/[P`,2H!F9")M__P@44H89OQ3B)'1Z
XM(`C5P&"X+PHO"V$``3!03TI`9P1P`6!&4HI*$F;H$"L`!'(&L`%G!%,`9BIPQ
XM`6`N+PHO"V$``0903TI`9P1P`6`<2'K_,B\*+PL@;?_\+Q!A`/Y^8`@O"B\+0
XM80``#$SM#`#_]$Y=3G6_[`O890`3?$CG`#`F;P`,)&\`$"`*9@9P`&```+(0@
XM*P`$<@:P`6<``)QR`;`!9P``E!(`2($,00`&9```@M)!,CL0!D[[$`0`"@!T_
XM`#H`2`!T`%P@4TH89OQ3B)'3+P@O$R\*3KH3E$_O``Q*@&<$<`!@6B!32AAF-
XM_%.(D=,@"-7`8#I<BR\*+PMA`/Z"4$]@/$H25\!$`$B`2,!2BDJ`9QQP`&`HP
XM0>L`!DAZ`"@O"B\(+Q-A`/VR3^\`$&`07(M@`/]<2A)F!'`!8`)P`$S?#`!.,
XM=;_L"]AE`!*H2.<`,"9O``PD;P`0(`IF!'``8#X@"V<X<`:P*P`$9S`O"B\+0
XM80#^_E!/2D!G!'`!8"`0*P`$<@&P`6<(70!G!%R+8.YP`;`K``1FR%R+8,1PJ
XM`$S?#`!.=4Y5_V"_[`O890`21$CG!S`F;0`()&T`##XM`!H\+0`>.BT`*G`!Q
XM*T#__$HM`#-G#C`L`,X`0`"`.4``SF`&.7P`!@#..44.PCEM`"X.Q$AX__XO%
XM"DZZ$H)03RM`__@@;0`02A!F#$'L"10B;0`0$MAF_"!M`!!#[?]B$MAF_$AMT
XM_V)A`/G(6$\I0!`:($I#[`XL$MAF_"!M`!!#[`V6$MAF_"!+0^P-=1+89OP@?
XM!SE`"-@@!CE`"-HI;0`@"/(@;0`D*4@(]B`(9P1P#V`"<`$Y0`D&<``O`"\`L
XM80`,-DAL"-A.NA&F3^\`#"E``$!*@&8.+RW_^$ZZ$<)P`&```:9(;`D82'C_@
XM_R\L`$!.NA%&2'@``2!L`$`O*``R3KH18$AX`!-(>``&(&P`0"\H`#).NA%`/
XM2'@`"4AL"4(@;`!`+R@`,DZZ$;Q(>`":2'@`!B!L`$`O*``R3KH1&$AX``=(G
XM;`E,(&P`0"\H`#).NA&43^\`1$AX`*5(>``&(&P`0"\H`#).NA#L2'@`"$AL%
XM"50@;`!`+R@`,DZZ$6A"ER\L`$!(;`@\3KH18$_O`"`O+?_X80``^EA/*T#_U
XM_%.`9CXO+?_X3KH0]$AX``%"IR\L`$!(;`@\3KH0@DAX__Y(;`XL3KH0]$*7Y
XM+RP`0$AL`38K0/_X3KH1$D_O`"1@L"\M__A.NA"V6$]*K?_\9P``AD'L#74B]
XM2Q+89OQ![`XL(DH2V&;\0>P-EB)M`!`2V&;\2JT`%&=>0>P.+")M`!02V&;\7
XM($I*&&;\4XB1RG`Z(@BP,AC_9S`@2DH89OQ3B)'*(`AG(B!*2AAF_%.(D<IPQ
XM+R((L#(8_V<.2&P)7B\M`!1.NA!*4$](;`UU+RT`%$ZZ$#Q03R\L`$!.NA!B!
XM80`,;"`M__Q,[0S@_TQ.74YU3E7_U+_L"]AE``^62.</,B9M``AX`)'(*TC_;
XMY"M(_^A(;?_D80`($%A/2@!F!G``8``"(D)L`$A(;`!N2&P`1$AX``%A``.`5
XM80`"7$AX``5(;`E@2&P.+$ZZ#[Y/[P`82H!G``%\(`MG``%V(&W_\"\(+PM.L
XMN@_`2&W_Y&$`![A/[P`,2@!F!G``8``!R"!M__`O""\+3KH/8E!/+@`@!TJ`^
XM9P``_"!M__!0B"\(80`':%A/2D!F#"!M__`@*``$2H!O%B!M__!0B"\(80`!E
XMD%A/2H!G!'(!8`)R`"P!(`9*@&=&<`JX0&0H(&W_\"($4D3"P'`MTH`O`4AX4
XM``@B;`!`+RD`,B\(80`(,$_O`!!@&%)$<``P!$AL`&Y(;`!$+P!A``*B3^\`\
XM#'``,`1(;?_D+P!A``+<4$\J`'`&NH!G0G`$NH!F*$AL#BQA``&@2'@``4*GN
XM+RP`0$AL"#Q.N@Y,+JW_Y&$`"+1P`6```.9P!+J`;+0O+?_D80`(H"`%8```B
XMTDJ&9P#_!DAM_^1A``:F6$]*`&8`_O9P`&```+8B;?_P(&D!")7*(4H!!"!MP
XM__`L;?_D(FX!!+/(9A0K2O_T*TK_["M*_^@@;?_D(4H!!$AX`1`O+?_P3KH.K
XM!E!/(FP`0"!I`%9P`!`H``]R`>&A+P%.N@Y&6$]P`#`$2&W_Y"\`80`"#%!/J
XM*@!P!KJ`9\YP!+J`9BQ(;`XL80``T%A/2@!G'DAX``%"IR\L`$!(;`@\3KH-V
XM=BZM_^1A``?><`%@$'`$NH!LL"\M_^1A``?,(`5,[4SP_[A.74YUO^P+V&4`*
XM#3PO"R9O``@P+`#."```!V8$<`%@*"!+2AAF_%.(D<L@"")+T\!;B4'L"680:
XM&;`89@1*`&;V5L!$`$B`2,`F7TYUO^P+V&4`#/1"IR!L`$`O*``R3KH-%DAX_
XM`(U(>`#02'@`)TAX``@@;`!`+R@`,DZZ#3Q(>``!(&P`0"\H`#).N@SJ3^\`$
XM)$YUO^P+V&4`#*Q(YP,0)F\`$$H39A!![`EL(DL2V&;\<`%@``"P?@!\`4HS@
XM>`!G&$J&9Q1R+[(S>`!7P$0`2(!(P"P`4H=@XDJ&9Q!(;`EN+PM.N@S>4$]P?
XM`6!X($M*&&;\4XB1RW`Z(@BP,QC_9@1P`&!@?``@2TH89OQ3B)'+(`@N`%.'Y
XM2H=K.G`OL#-X`&8>2H=G!K`S>/]F"'``%X!X`6`&<``7@'@`?@!\`6`0<#JPD
XM,W@`9@A",W@!?@!\`5.'8,)*AF8*0>P)<")+$MAF_'`!3-\(P$YU3E7__+_L-
XM"]AE``O02.<!,#XO`!HF;P`<)&\`('``,`<O0``,(#P`"?_V(B\`#$ZZ"\@W9
XM0``(0J<O+`!`+PI.N@O$3.T,@/_P3EU.=4Y5_TB_[`O890`+A$CG!S`^+0`*%
XM)FT`#"!L`$`O*`!63KH+M%A/*T#_]DJ`9P`##B!`*V@`'/_R.V@`(/_B.V@`O
XM(O_@*V@`%/_N.V@`&/_D*V@`)/_J*V@`*/_F+P!.N@LH6$\@+?_N<A"0@6<D<
XM<A"0@6<``7IR()"!9S@$@```?\!G``%"!(```(``9P`!3&"&<`J^0&.`<``P]
XM+`!(<@`R!R\++P$O`&$``IY/[P`,8`#_9B!M__(,:``*`"9B=B!H`!I(>``%I
XM2&P)>B\H``Q.N@LT3^\`#$J`9RXB;?_R(&D`&B\H``QA``H<0>P/4D/L#BP2@
XMV&;\2&P)@$AL#BQ.N@L*3^\`#&`4(FW_\B!I`!HB:``,1>P.+!399OQ(>``!T
XM0J<O+`!`2&P(/$ZZ"FQP`6```@H@;?_R,"@`)@1```MM?`Q```AL=M!`,#L`\
XM!D[[``0`9``4`!0`#@`:`&H`:@`@<`!@``'6<`-@``'0<`1@``'*$"P-EDH`.
XM9B)![`F"0^P-EC+00A%(>``!0J<O+`!`2&P!JDZZ"@!/[P`00>P-ED/M_TH2&
XMV&;\2&W_2F$`\=I83RE`$!IP`6```8!P!6```7HO/```@``O+`!`80`$@'`%@
XM8``!9B\\``$``"\L`$!A``1L<`5@``%2<!(@;?_RL&@`)F8&<`%@``%`2'@`#
XM!4AL"89(;`XL3KH)^$_O``Q*@&<`_@`P+?_@2,!R)I"!<@I.N@F$*@!\`"MKR
XM`!#__+P%9Q1*K?_\9PX@;?_\*V@!!/_\4@9@Z$JM__QG`/W&(&W__"`H``1*C
XM@&]T0^P.+"1)2AIF_%.*E<EP.D/L#BLB"K`Q&`!G,D/L#BPD24H:9OQ3BI7)A
XM<"]#[`XK(@JP,1@`9Q80+`XL2@!G#DAL"8Q(;`XL3KH)8E!/(&W__%"(+PA(&
XM;`XL3KH)4$AX``%"IR\L`$!(;`@\3KH(S'`!8&I#Z``(0>P-=1`8L!EF)DH`$
XM9O9F("\M_^8O+?_J+RP)=B\L"7).N@D\3^\`$$J`9P1P`V`V(&W__%"(0^P--
XM=1+89OQ(>``!0J<O+`!`2&P!-DZZ"'1/[P`0*6W_Z@ER*6W_Y@EV8`#\WG`&G
XM3.T,X/\T3EU.=;_L"]AE``A`2.<G$#XO`!H\+P`>)F\`('``,`=R`#(&=`J2-
XM@E*`3KH(Y$A`2,`J`'``,"P)CK"%9PHO"R\%80``$%!/(`4Y0`F.3-\(Y$YU8
XMO^P+V&4`!_!(YP<P/B\`&B9O`!Q*1V<2?``D:P`$O$=D#"1J`0121F#T)&L`B
XM!"=*`!!\`'HM<`J\0&0L(`IG*'``,`4O`$AX``@@;`!`+R@`,B\*80`!.D_OK
XM`!!21@9%``HD:@$$8,Y,WPS@3G6_[`O890`'@B\+)F\`""\++RP0&F$`],103
XM3R9?3G6_[`O890`'9"\+)F\`""=K``P`""\\``$``4AX`1!.N@@64$\G0``,H
XM2H!F#"\`80`!MEA/<`!@9$J39@@@:P`,)HA@5DJK``1F*"!3(FL`#"=)`!`G>
XM20`()TD`!"%)`00@4R)K``PO"2\(80``-%!/8"@@:P`((FL`#"\)+PAA```@'
XM4$\@:P`((FL`#"%)`00@:P`,(6L`"`$(<`$F7TYUO^P+V&4`!L1(YP`P)F\`8
XM#"1O`!`DDR5K``0`!"5K`'0`="5K`'@`>"5K`'P`?"5K`(``@$'J``A#ZP`(W
XM$-EF_$'J`)!#ZP"0$-EF_"5K`(0`A"5K`(@`B"5K`(P`C$S?#`!.=4Y5_]2_>
XM[`O890`&7$CG!S`F;0`()&T`##XM`!(\+0`60>L`"$/M_]82V&;\("L`!$J`.
XM;R!P`#`L#L0O`"\*3KH&5DAL"9!(;?_63KH&F$_O`!!@$'``,"P.PB\`+PI.&
XMN@8V4$]P`#`'<@`R!B\!+P`O"DZZ!A9(>``92&P)F"\*3KH&F'``,`=R`#(&`
XM+H$O`"\*3KH%]D_O`"!!ZP`((DA*&6;\4XF3R"`)<AFP@6X20>L`"")(2AEF>
XM_%.)D\@@"6`"(`$J`$'K``AP`#`%+P`O""\*3KH&1$SM#.#_P$Y=3G5.5?_X_
XMO^P+V&4`!7I(YP`P)FT`""1K`01(>`$0+PM.N@6F4$\@2BM(__@@"&<2)&@!?
XM!$AX`1`O"$ZZ!8Q03V#D3-\,`$Y=3G5.5?_`O^P+V&4`!3)(YS\R)FT`""XM/
XM``Q\`"!L$60K:``B__P@;?_\("@`&.6`($`B*``$Y8%#[`=X*T#_^"M!__0KT
XM2?_P<`J\`&1T2JW_]&=N(&W_]$JH``1F5DJH``AG4"\(80`"!EA/2@!G1"!MQ
XM__0O*``H2&W_PV$``:Y(;`FR2&W_PTZZ!3)/[P`0(FW_\"!I`!I%[?_#+&@`5
XM#!S:9OQ2!BMM__#_Z"!M__`K4/_P(&W_]"`0Y8`K0/_T8(8@"V<00J<@;`!``
XM+R@`,DZZ!)Q03RH&#(<``0``9P``D$JL"0AG``"(*VP)"/_L2JW_\&=Z(&W_G
XM[")M__"SR&=N0^P#5+')9V8@"V8(!&@!```,8%`P*``$2,`R*``&2,$T*``$V
XM2,(V*``(2,/4@U."-B@`!DC#."@`"DC$UH13@R\#+P(O`2\`(&P`0"\H`#).A
XMN@1<0I<O"R\M_^Q.N@2>3^\`'"!M_^PK4/_L8(`I;?_P"0@,AP``@`!G6G`*:
XMO`!D5"!M__!*:``,9PH@/````0!*@&9`(FW_\"!I`!I%[`FT+&@`#!S:9OP@3
XM"V8,(&W_\`9H`0``#&`00J<O"R\M__!.N@1*3^\`#%(&(&W_\"M0__!@IB`+A
XM9Q9P`!`%+P!"IR\+2&P'>$ZZ`UY/[P`03-],_$Y=3G5.5?_\O^P+V&4``SI!N
XM[`=X*TC__$'L`U0B;?_\L\AG#D)I``P@;?_\*U#__&#F3EU.=;_L"]AE``,,"
XM2.<',"9O`!@N+P`<(`?E@"1`?``<&G`4O(!N`B`&+`!Z`+J&;`H0&A>`6`!2+
XMA6#R0C-8`$S?#.!.=4Y5__"_[`O890`"QDCG`1`F;0`(?@`O/``!``%(>``DU
XM3KH#>E!/*T#_]DJ`9@9P`&```-HO/``!``%(>`!$3KH#7%!/*T#_\DJ`9A)(!
XM>``D+RW_]DZZ`KQP`&```+!P`"\`+P!.N@)84$\K0/_\9AY(>``D+RW_]DZZI
XM`IA(>`!$+RW_\DZZ`HQP`&```(`@;?_R$7P`!0`(0^@`%"%)``HB;?_\(4D`0
XM#B%(`!1P&2%``!P@+?_V(@#D@2%!`"@A20`8+P@O*P`(3KH!^BZM__Q.N@(T6
XM(&W_]@RH1$]3```85\!$`$B`2,`N`"ZM__Q.N@)&2'@`)"\M__9.N@(62'@`(
XM1"\M__).N@(*(`=,[0B`_^A.74YU3E7__+_L"]AE``&P2.<#,"9M``@D;0`,^
XM?@!*,W``9PX@;0`0$;-P`'``4D=@["`'2,!R.B!M`!"R,`C_9QH@!TC`<B^RJ
XM,`C_9PY*1V<*2A)G!A&!<`!21WP`2C)@`&<8(`=(P"(&2,'0@2!M`!`1LF``:
XM"`!21F#B(`=(P"(&2,'0@2!M`!!",`@`3-\,P$Y=3G5.5?_TO^P+V&4``1Y(_
XMYP<`+BT`""\\``$``$AX`01.N@'44$\K0/_V2H!F!'``8&8O+?_V+P=.N@&&>
XM(&W_]E"(2&P.QDAL#U(O"&$`_R)/[P`4?``,1@",;!)![`[&0^P/4A.P8`!@N
XM`%)&8.@O!TZZ`1@J`"Z'3KH!'%A/+@5*AV<(+P=A`/]Z6$](>`$$+RW_]DZZJ
XM`-9,[0#@_^A.74YUO^P+V&4``()(YP,0)F\`$'X`#$<`C&P6<`!![`[&$8!PQ
XM`$'L#U(1@'``4D=@Y$AX__XO"TZZ`-Q03RP`2H9F!'``8"PO!F$`_QA83WX`:
XM#$<`C&P<<"]![`]2L#!P`&8,0>P/4A&\`#IP`&`$4D=@WDS?",!.=4[Y```':
XM<$[Y````1$[Y````<$[Y```!K$[Y````F$[Y````M$[Y```,V$[Y```#)D[YB
XM```&K$[Y````'$[Y````?$[Y````6$[Y````A$[Y````:$[Y````&$[Y````7
XM7$[Y```!X$[Y```$R$[Y````3$[Y````:$[Y```&+$[Y````'$[Y````.$[Y[
XM```")$[Y```"Z$[Y```&C$[Y`````$[Y```#:$[Y````,$[Y````,$[Y```#A
XME$[Y````%$[Y`````$[Y`````$[Y````U$[Y````3$[Y```&C$[Y`````$[Y2
XM````,'!A```#[`````X````````9"@``&)(``!EJ```8P@``&2(``!D<```8P
XM\@``&+P``!DH```8^```&30``!E&```8M@``&*0````%````!0``&00``!C^*
XM```9.@``&1```!DN````!P````8``!C:```8F```&7```!B>```8[```&4``.
XM`!CF````!`````<``!D6```96```&,@``!C4````"0````@``!EV```99```2
XM&4P``!C.```94@``&+```!E>```8J@``&.`````````#\D```^H````R____`
XM___^P``````&P`8`!P`&P```#8`&P`X?#`\&P`89GAF&P`89C!F&Q@89C!F&L
XMQ@\9G@\&P``````&_______^'______PP``````&P`8`!P`&P```#``&P`X'K
XM``\&P`88'AF&P`8!@!F&Q@`9C!F&Q@\9G@`&P``````&'______PX``````.Q
XM'@````#P`?```!\```^``^````!X/``````'P`````!X/`````^``^```?``B
XM`!\`'@````#PX``````.``````/R```#Z@```O5$1C`Z`````$5N=&5R(&UYL
XM(&9I;&5N86UE`&EN='5I=&EO;BYL:6)R87)Y`&=R87!H:6-S+FQI8G)A<GD`;
XM```````````%__\"E0*/`H\````````````````````!``\`!```````````0
XM````````````V0`C`!<`;@````@``P```%H```````````````````!$`!``Z
XM```````````O``L``@`````!`````````````"\`"P`"````0@,`````````^
XM`&X`I0`+`"\`"P`&`0(``0```)H```"N`````````````````!(````````-)
XM=0``#+X````A``````````````````````````````````````#9````V0`*<
XM````"@````#__O__`0`!!0```1(`````````P@!6`)\`U@`)`````0`$```![
XM)@```````````````````.X`#`````````V6```,WP```)8`````````````$
XM`````````````````````````)L```";``H````*`````/_^__\!``$%```!-
XMA@````````$V`%8`DP"8``D````!``0```&:```````````````````!8@`2<
XM````````````60```%D`#`````P````!_____P$``04```'6`````$]K```!@
XM``$``"4``@````````'Z`````````:H`!@"L`%@`"P````$``0```>H`````0
XM```!_@````````````T```````````!4````5``*````"@````'_____`0`!'
XM!0```CX`````4&%R96YT```!``$``!,``0````````)B`````````A(`V@`,C
XM`%,`"0````$``0```E(````````":@````````````\```````````!9````&
XM60`,````#`````'_____`0`!!0```JH`````0V%N8V5L```!``$``!4``@```
XM``````+.`````````GX`U0"L`%@`"P````$``0```KX````````"U@``````.
XM``````X````````````Y````.0`*````"@````'_____`0`!!0```Q8`````Q
XM4$E013H``0`!```*``$````````#.@````````+J`/4`DP`X``D````!``$`I
XM``,J`````````T`````````````*````````````.0```#D`"@````H````!!
XM_____P$``04```.``````"`@("````$``0``#0`!`````````Z0````````#`
XM5`#U`(<`.``)`````0`!```#E`````````.J````````````"0``````````@
XM`#D````Y``H````*`````?____\!``$%```#Z@`````@("`@```!``$```T`&
XM`0````````0.`````````[X`]0!\`#@`"0````$``0```_X````````$%```A
XM``````````@````````````Y````.0`*````"@````'_____`0`!!0``!%0`J
XM````("`@(````0`!```-``$````````$>`````````0H`/4`<0`X``D````!@
XM``$```1H````````!'X````````````'````````````.0```#D`"@````H`\
XM```!_____P$``04```2^`````"`@("````$``0``#0`!````````!.(`````\
XM```$D@#U`&8`.``)`````0`!```$T@````````3H````````````!@``````\
XM`````#D````Y``H````*`````?____\!``$%```%*``````@("`@```!``$`Y
XM``T``0````````5,````````!/P`]0!;`#@`"0````$``0``!3P````````%X
XM4@````````````4````````````Y````.0`*````"@````'_____`0`!!0``A
XM!9(`````("`@(````0`!```-``$````````%M@````````5F`/4`4``X``D`3
XM```!``$```6F````````!;P````````````$````````````.0```#D`"@``N
XM``H````!_____P$``04```7\`````"`@("````$``0``#0`!````````!B``%
XM```````%T`#U`#H`.``)`````0`!```&$`````````8F`````````````@``+
XM`````````#D````Y``H````*`````?____\!``$%```&9@`````@("`@```!W
XM``$```T``0````````:*````````!CH`]0!%`#@`"0````$``0``!GH`````<
XM```&D`````````````,````````````Y````.0`*````"@````'_____`0`!>
XM!0``!M``````("`@(````0`!```-``$````````&]`````````:D`/4`+P`XK
XM``D````!``$```;D````````!OH````````````!````````````.0```#D`H
XM"@````H````!_____P$``04```<Z`````"`@("````$``0``#0`!````````I
XM!UX````````'#@#U`"0`.``)`````0`!```'3@````````=D````````````6
XM`````````````,\```#/`&T```!M`````/_^__\!``$%```'I`````````=XD
XM``8`)`#,`&P``P`"``$```>X```````````````````````1````````#BP`R
XM``PH````E@`````````````````````````````````````!*0```2D`"@``H
XM``H`````__[__P$``04```@8````````!\@`!@`8`28`"0````$`!```""P`"
XM``````````````````?T``L`````1FEL92!P871T97)N```!``$```8`E````
XM``````AH`````'Y&:6QE;F%M90`!``$```8`GP````````B*```(=D0A:7)EK
XM8W1O<GD```$``0``!0`-````````"*@```B416YT97(@9FEL96YA;64````&V
XM``D!,P"[``$``H!P```0`@``"#P````````(R`````````````4`!0*``,@`E
XM`0`````H*7PC/R4``",_``!90492(%8Q+C(Q(*DQ.3@Y+"`Q.3DP(&)Y($1AD
XM=F4@4V-H<F5I8F5R``!$:7)E8W1O<GD`4&%T=&5R;@!&:6QE;F%M90``+P!0%
XM25!%.@`N:6YF;P`O`"\``````````````%!)4$4Z`#H`(S\``%!)4$4Z`"\`K
XM=3`@("AD:7(I`"`@("`@("`@("`@("`@("`@("`@("`@("``.@`@("`@````/
XM`````"@`````````````````````````````"?8`````````````````````G
XM``````````````````````H8````````````````````````````````````B
XM``````````````````````````````````````````````````````"``````
XM!```("`@("`@("`@*"@H*"@@("`@("`@("`@("`@("`@("!($!`0$!`0$!`0$
XM$!`0$!`0A(2$A(2$A(2$A!`0$!`0$!"!@8&!@8$!`0$!`0$!`0$!`0$!`0$!.
XM`0$!`1`0$!`0$(*"@H*"@@("`@("`@("`@("`@("`@("`@("$!`0$"`@("`@X
XM("`@("`H*"@H*"`@("`@("`@("`@("`@("`@($@0$!`0$!`0$!`0$!`0$!"$D
XMA(2$A(2$A(2$$!`0$!`0$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!`0$!$!`0>
XM$!`0@H*"@H*"`@("`@("`@("`@("`@("`@("`@(0$!`0(````/__````#@`.>
XM````````````````__\````$``0````````-J```"TC__P````0`!```````4
XM``V^`````/__````#@`.````````#LX`````__\````$``0`````````````'
XM"X3__P````0`!`````````[J`````/__````!``$````````#O0````````#8
XM[`````4````````+S```"[@```N0```+?```"V@````"`````P```+@```"D!
XM````:P````0```NH```+;```"?8```G4```'^```!_0```%F```!8@```/(`K
XM``#N```(\@``".H```C$```(P```"*0```B@```(@@``"%X```A.```(/```,
XM"#0```?:```'R```!\````>2```'B@``!W@```=P```'5@``!R@```<@```'-
XM#@``!P8```;L```&O@``!K8```:D```&G```!H(```94```&3```!CH```8R%
XM```&&```!>H```7B```%T```!<@```6N```%@```!7@```5F```%7@``!40`B
XM``46```%#@``!/P```3T```$V@``!*P```2D```$D@``!(H```1P```$0@``Z
XM!#H```0H```$(```!`8```/8```#T````[X```.V```#G````VX```-F```#\
XM5````TP```,R```#!````OP```+J```"X@```L8```*8```"D````GX```)V9
XM```"6@```BP```(D```"$@```@H```'R```!S````;P```&J```!H@```5@`T
XM``%(```!-@```2X```#8````U````,(```"0````@`````````/R```#Z0``.
XM`!](YR`"+'D``!%D3.\`!@`,3J[_K$S?0`1.=0``+PXL>0``$60B+P`(3J[_;
XMIBQ?3G5(YR`"+'D``!%D3.\`!@`,3J[_FDS?0`1.=0``2.<@`BQY```19$SO9
XM``8`#$ZN_Y1,WT`$3G4``"\.+'D``!%D(B\`"$ZN_RXL7TYU```#[`````4`N
XM```$````;````%(````V````(`````8````````#\`````-?4&%R96YT1&ER\
XM``````!H`````E]%>$YE>'0`````3`````)?17AA;6EN90```#`````"7U5NM
XM3&]C:P`````<`````E],;V-K``````````````````/R```#Z0```#$O#BQY#
XM```,#$SO``,`"$ZN_SHL7TYU```O#BQY```,#")O``@@+P`,3J[_+BQ?3G4OU
XM#BQY```,#"`O``A.KO["+%].=2\.+'D```P,3.\#```(3J[^DBQ?3G4``"\.#
XM+'D```P,(&\`"$ZN_HPL7TYU+PXL>0``#`PB;P`(3J[^ABQ?3G4O#BQY```,W
XM#"!O``A.KOZ`+%].=2\.+'D```P,(F\`"$ZN_F(L7TYU+PXL>0``#`PB;P`([
XM("\`#$ZN_=@L7TYU```#[`````D````$````L````)P```"(````=````&``>
XM``!(````-````!P````$`````````_`````#7T]P96Y,:6)R87)Y````K```$
XM``1?0VQO<V5,:6)R87)Y````````F`````-?5V%I=%!O<G0```````"$````F
XM`U]297!L>4US9P```````'`````"7T=E=$US9P````!<`````E]0=71-<V<`*
XM````1`````)?5V%I=````````#`````"7T9R965-96T````8`````U]!;&QON
XM8TUE;0`````````````````#\@```^D````<+PXL>0``#"0B;P`((&\`#"`O4
XM`!!.KO_$+%].=2\.+'D```PD(F\`"$SO``,`#$ZN_Q`L7TYU``!(YS`"+'D`Q
XM``PD(F\`$$SO``\`%$ZN_LY,WT`,3G4``"\.+'D```PD(F\`""`O``Q.KOZJ;
XM+%].=0```^P````$````!````%P````^````(`````0````````#\`````)?7
XM4V5T05!E;@```%@````#7U)E8W1&:6QL````````.`````)?36]V90``````/
XM`!P````"7U1E>'0``````````````````_(```/I````/"\.+'D```P@(&\`<
XM"$ZN_[@L7TYU2.<P`BQY```,($SO``\`$$ZN_YI,WT`,3G4``$CG`"(L>0``:
XM#"!,[P<```Q.KO]23-]$`$YU``!(YP`B+'D```P@3.\'```,3J[_1DS?1`!.G
XM=0``+PXL>0``#"`@;P`(3J[_-"Q?3G5(YP`B+'D```P@3.\'```,3J[_(DS?/
XM1`!.=0``2.<`(BQY```,($SO!P``#$ZN_NQ,WT0`3G4``$CG`"(L>0``#"!,]
XM[P<```P@+P`83J[^4$S?1`!.=0``2.<`(BQY```,($SO!P``#$ZN_C),WT0`P
XM3G4``````^P````)````!````-H```"Z````G@```((```!L````4@```#8`G
XM```:````!`````````/P````!%]!8W1I=F%T94=A9&=E=`````#4````!%]2Z
XM969R97-H1TQI<W0```````"T````!%]39717:6YD;W=4:71L97,```"8````H
XM!%]2969R97-H1V%D9V5T<P````!\`````U]/<&5N5VEN9&]W`````&@````#$
XM7T]N1V%D9V5T````````3`````-?3V9F1V%D9V5T```````P`````U]$;W5B9
XG;&5#;&EC:P```!0````#7T-L;W-E5VEN9&]W``````````````/R0
X``
Xend
Xsize 16284
END_OF_FILE
if test 22833 -ne `wc -c <'yftest.uu'`; then
    echo shar: \"'yftest.uu'\" unpacked with wrong size!
fi
# end of 'yftest.uu'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
Mail comments to the moderator at <amiga-request@cs.odu.edu>.
Post requests for sources, and general discussion to comp.sys.amiga.