💾 Archived View for aphrack.org › issues › phrack52 › 17.gmi captured on 2021-12-04 at 18:04:22. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-12-03)

-=-=-=-=-=-=-

---[  Phrack Magazine   Volume 8, Issue 52 January 26, 1998, article 17 of 20


-------------------------[  Protected mode programming and O/S development


--------[  Mythrandir <jwthomp@cu-online.com>




----[  Forward


About two months ago I decided to begin learning about developing an operating
system from the ground up.  I have been involved in trusted operating systems
development for over two years now but have always done my work with
pre-existing operating systems.  Mucking with this driver model, deciphering
that streams implementation, loving this, hating that.  I decided it was time
to begin fresh and start really thinking about how to approach the design
of one, so that I would be happy with every part.  At least if I wasn't, I
would only be calling myself names.

This article is the first tentative step in my development of an operating
system.  What is here is not really much of a kernel yet.  The big focus of
this article will be getting a system up and running in protected mode with a
very minimal kernel.  I stress minimal.  I have been asked repeatedly what my
design goals for this operating system are.  The fact is the operating system
itself was the goal for this part.  There was simply to much that I didn't
know about this stage of the development to go on designing something.  It
would be like asking a kindergarten fingerpainter what her final masterpiece
was going to look like.

However, now that I have this phase reasonably done, it is time to begin
thinking about such issues as: a security subsystem, a driver subsystem, as
well as developing a real task manager and a real memory manager.  Hopefully,
by the next phrack I will be able to not only answer what I want for these
topics but have also implemented many of them.  This will leave me with a much
more solid kernel that can be built upon.

So, why write this article?  There are several reasons.  First, writing down
what you have done always help solidify your thoughts and understanding.
Second, having to write an article imposes a deadline on me which forces me to
get the job done.  Finally, and most importantly I hope to give out enough
knowledge that others who are interested in the subject can begin to do some
work in it.

One comment on the name.  JeffOS is not going to be the final name for this OS.
In fact several names have been suggested.  However, I have no idea yet what I
want to call it, mostly because it just isn't solidified enough for a name.
When its all said and done, I do hope I can come up with something better than
JeffOS.  For now, getting a real working kernel is more important than a real
working name.

I hope that you find the following information interesting, and worth
investigating further.

Cheers,
Jeff Thompson
AKA Mythrandir


PS: Some words on the Cryptography article.  First a thank you for all of the
letters that I received on the article.  I am happy to find that many people
found the article interesting.  For several people it rekindled an old interest
which is always great to hear.  However, for several people I have unfortunate
news as well.  The next article in the series will have to be postponed for
a few issues until I complete this operating system.  As is with many people,
I have been caught by a new bug (The OS bug) and have set myself up to be
committed to the work for some time.  I am of course still interested in
discussing the topic with others and look forward to more email on the subject.


The winners of the decryption contest were:

1st message:
1st) Chaos at chaos@vector.nevtron.si
2nd) Oxygen at oxygen@james.kalifornia.com

Solution:
The baron's army will attack at dawn. Ready the Templar knights and strike his
castle while we hold him.

2nd message:

1st) Chaos

Solution:
MULTICAST PROTOCOLS HAVE BEEN DEVELOPED TO SUPPORT GROUP COMMUNICATIONS
THESE PROTOCOLS USE A ONE TO MANY PARADIGM FOR TRANSMISSION TYPICALLY
USING CLASS D INTERNET PROTOCOL ADDRESSES TO SPECIFY SPECIFIC MULTICAST GROUPS

Also, there is one typo in my article.  The book which was written without the
letter 'e' was not The Great Gatsby, but rather Gadsby.  Thanks to Andy
Magnusson for pointing that out.


Great job guys!


----[  Acknowledgements


I owe a certain debt to two people who have been available to me during my
development work.  Both have done quite a bit of work developing their own
protected mode operating systems.  I would like to thank Paul Swanson of the
ACM@UIUC chapter for helping solve several bugs and for giving me general tips
on issues I encountered.  I would also like to thank Brian Swetland of
Neoglyphics for giving me a glimpse of his operating system.  He was also nice
enough to allow me to steal some of his source code for my use.  This source
include the console io routines which saved me a great deal of time.  Also,
the i386 functions were given to me by Paul Swanson which has made a lot of
the common protected mode instructions easily useable.

Following new releases and information on this operating systems work, I am
currently redoing my web site and will have it up by Feb 1, 1998.  I will be
including this entire article on that site along with all updates to the
operating system as I work on it.  One of the first things that I will be
doing is rewriting all of the kernel.  A large part of what is contained
within these pages was a learning experience.  Unfortunately, one consequence
of trying to get this thing done was it becoming fairly messy and hackish.  I
would like to clean it up and begin to build upon it.  Having a good code base
will be invaluable to this.  So please watch for the next, and future releases
of this code and feel free to contact me with any feedback or questions.  I
will do my best to help.  I won't be able to answer every question but I will
certainly try.  Also, please be patient as I have a very busy schedule outside
of this project and am often times caught up by it.

I can be reached at:
        jwthomp@cu-online.com
and my web site is at:
        http://www.cu-online.com/~jwthomp/ (Up Feb 1, 1998)


----[  Introduction


Throughout this document I assume a certain level of knowledge on the part of
the reader.  This knowledge includes c and assembly language programming, and
x86 architecture.

The development requirements for the GuildOS operating system are:

An ELF compiler
    I used the gnu ELF compiler which comes with linux.  It is possible to use
    other ELF cross compilers on other systems as well.

a386 assembler
    This can be obtained from:

    Eric Isaacson
    416 E. University Ave.
    Bloomington IN 47401-4739
    71333.3154@compuserve.com

    or call 1-812-335-1611
    A86+D86+A386+D386 is $80
    Printed manual $10

    This is a really nice assembler.  Buy a copy.  I did.

    It is also possible to convert the boot loader assembly code to another
    assembler.

A 486+ machine
    You must have a machine to test the OS on.

Great books to read to gain an understanding of the various topics presented
in the following pages are:

Protected Mode Software Architecture by Tom Shanley from MindShare, Inc.
ISBN 0-201-55447-X  $29.95 US

This book covers the protected mode architecture of the x86.  It also explains
the differences between real mode and protected mode programming.  This book
contains much of the information which is in the Intel Operating Systems
Developers guide, but also explains things much more in depth.


Developing Your Own 32-Bit Operating System by Richard A. Burgess from SAMS
Publishing.  ISBN  0-672-30655-7

This book covers the development of a complete 32-bit OS.  The author also
creates his own 32-bit assembler and compiler.  Considerable portions of the
code are written in asm, but there is still quite a bit in C.

The entire Intel architecture series and their OS developers guides which are
available from their web site for free.


----[  Chapter 1 - Booting into protected mode


The first step in setting up an operating system on the x86 architecture is to
switch the machine into protected mode.  Protected mode allows you to use
hardware protection schemes to provide operating system level security.

The first component which I began working on was the first stage boot loader
which is located in "JeffOS/loader/first/".

The first stage boot loader is placed on the first sector of the floppy.  Each
sector is 512 bytes.  This is not a lot of room to write all of the code
required to boot into protected mode the way I would like to so I had to break
the boot loader into two parts.  Thus the first and second stage floppy loader.

After the Power On Self-Test (POST) test this first sector is loaded up into
memory location 0000:7C00.  I designed the first stage of the floppy boot
loader to load up all of the files into memory to be executed.  The first
instruction in the boot loader jumps to the boot code.  However, between the
jump and the boot code are some data structures.  

The first section is the disk parameters.  I'm not currently using any of this
information but will in future versions.  The next set of structures contain
information on the other data files on the floppy disk.  Each structure looks
like this in assembly:

APCX	DW	0000h		; Specifies CX value for INT 13h BIOS routine
APDX	DW	0000h		;           DX
APES	DW	0000h		;           ES
APBX	DW	0000h		;           BX
APSZ	DB	0h		; Specifies number of sectors to read in
APSZ2	DB	0h		; Unused

There are four copies of this structure (APxx, BPxx, CPxx, DPxx).

The INT 13h BIOS call has the following arguments:

ch: Cylinder number to start reading from.
cl: Sector number to start at.
dh: Head number of drive to read from (00h or 01h for 1.44M floppy disk drives)
dl: Drive number (00h for Disk A)
es: Segment to store the read in sectors at.
bx: Offset into the segment to read the sectors into.
ah: Number of sectors to read in.
al: Function number for INT 13h. (02h is to read in from the disk)

I use the APxx to load the second stage boot loader. BPxx is being used
to load the first stage kernel loader.  CPxx is used to load a simple user
program.  Finally, DPxx is used to load the kernel in.

Following the loader structures are two unused bytes which are used to store
temporary data. SIZE is used but SIZE2 is not currently used.

The boot code follows these structures.  This boot code relocates itself into
another section of memory (9000:0000 or 90000h linear).  Once relocated, it
loads all of the files into memory and then jumps into the beginning of the
second stage boot loader.

The first part of the second stage boot loader contains a macro which is used
to easily define a Global Descriptor Table (GDT) entry.  In protected mode the
GDT is used to store information on selectors.  A selector in protected mode
is referred to by a number stored in any of the segment registers.  A selector
has the following format:

Bits        Use
15 - 3      Descriptor Table Index
2           Table Indicator
1  - 0      The Requestor Privilege Level

The Descriptor Table Index or (DT) is an index into the GDT.  The first entry
in the GDT is 00h, the second is 08h, then 10h, etc..  The reason that the
entries progress in this manner is because the 3 least significant bits are
used for other information.  So to find the index into the GDT you do a
segment & 0xfff8 (DT = Selector & 0xfff8).

The Table Indicator selects whether you are using a GDT or a Local Descriptor
Table (LDT).  I have not yet had a reason to use LDT's so I will leave this
information to your own research for now.

Finally, the Requestor Privilege Level is used to tell the processor what
level of access you would like to have to the selector.
0 = OS
1 = OS (but less privileged than 0)
2 = OS (but less privileged than 1)
3 = User level

Typically levels 0 and 3 are the only ones used in modern operating systems.

The GDT entries which describe various types of segments have the following
form:

63 - 56    Upper Byte of Base Address
55         Granularity Bit
54         Default Bit
53         0
52         Available for Use (free bit)
51 - 48    Upper Digit of Limit
47         Segment Present Bit
46 - 45    Descriptor Privilege Level
44         System Bit
43         Data/Code Bit
42         Conforming Bit
41         Readable bit
40         Accessed bit
39 - 32    Third Byte of Base Address
31 - 24    Second Byte of Base Address
23 - 16    First Byte of Base Address
15 - 8     Second Byte of Limit
7 - 0      First Byte of Limit


The base address is the starting location of the segment descriptor (for code
or data segments). The limit is the number of bytes or 4k pages.  Whether it
is bytes or 4k pages depends on the setting of the granularity but.  If the
granularity bit is set to 0 then the limit specifies the length in bytes.  If
it is set to 1 then the limit specifies the length of the segment in 4k pages.

The default bit specifies whether the code segment is 32bit or 16bit.  If it is
set to 0 then it is 16bit.  If it is set to 1 then it is 32bit.

The present bit is set to one if the segment is currently in memory.  This is
used for virtual paging.

The descriptor privilege level is similar to the RPL.  The DPL simply states at
what protection level the segment exists at.  The values are the same as for
the RPL.

The system bit is used to specify whether the segment contains a system segment.
It is set to 0 if it is a system(OS) segment.

The data/code bit is used to specify whether the segment is to be used as a
code segment or as a data segment.  A code segment is used to execute code
from and is not writable.  A data segment is used for stacks and program
data.  It's format is slightly different from the code segment depicted above.

The readable bit is used to specify whether information can be read from the
segment or whether it is execute only.

The next part of the second stage floppy boot loader contains the code which
is used to enable the A20 address line.  This address line allows you to
access beyond the 1MB limit that was imposed on normal DOS real mode
operation. For a discussion of this address line I recommend looking at the
Intel architecture books.

Once enabled the GDT that exists as data at the end of the assembly file is
loaded into the GDT register. This must be done before the switch into
protected mode.  Other wise any memory accesses will not have a valid selector
described for them and will cause a fault (I learned this from experience).

Once this is completed the move is made to protected mode by setting the
protected mode bit in the CR0 register to 1.

Following the code which enables protected mode, there is data which represents
a far call into the next portion of the second stage boot loader.  This causes
a new selector to be used for CS as opposed to an undefined one.

The code that is jumped into simply sets up the various selectors for the data
segments.

There is then some simple debugging code which prints to the screen.  This was
used for myself and can be removed.

The stack segment is then set up along with the stack pointer.  I placed the
stack at 90000h.

Finally I push the value for the stack onto the stack (to be retrieved by the
kernel) and then call linear address 100080h which contains the first stage
loader for the kernel.


----[  Chapter 2 - The first stage kernel boot loader


The first stage kernel boot loader is located in \boot.

First some notes on what is happening with the first stage boot loader.  The
boot loader is compiled to ELF at a set TEXT address so that I can jump into
the code and have it execute for me.  In the makefile I specify the text
address to be 10080.  The first 80h bytes are used as the ELF header.  I
completely ignore this information and jump directly into linear memory
address 10080h.  It is my understanding that newer versions of the ELF compiler
have a slightly different header length and may cause this number to need to be
modified.  This can be determined by using a dissasembler (i.e. DEBUG in DOS)
to determine where the text segment is beginning.

The two files of importance to the boot loader are main.c and mem.c.

main.c contains the function `void _start(unsigned long blh);`.  This function
must be the first function linked in.  So main.c must be the first file which
is linked and _start() must be the first function in it.  This guarantees that
start will be at 10080h.  The parameter blh is the value which was pushed in
by the second stage boot loader.  This originally had meaning, but no longer
does.

The first thing that _start does is to call kinit_MemMgmt which is the
initialization routine for memory.

The first thing that kinit_MemMgmt does is set nMemMax to 0xfffff.  This is
the maximum number of bytes on the system.  This value is 1MB.  kinit_MemMgmt
then calls kmemcount which attempts to calculate the amount of free memory on 
the system.  Currently this routine does not work properly and assumes that
there is 2MB of free memory on the system.  This is sufficient for now but
needs to be fixed in the future.

kinit_MemMgmt then calls kinit_page which sets of the page tables for the
kernel. 

Paging is the mechanism used to define what memory a task is able to access.
This is done by creating a "virtual" memory space which the task accesses.
Whenever an access to memory occurs the processor looks into the page tables
to determine what "real" physical memory is pointed to by this memory location.
For example, the kernel could designate that each task will get 32k (8 pages)
of memory to use for the stack.  Without using paged memory each of these
memory locations would occur at a different address.  However, by using paging
you can map each of these physical memory allocations to a paged address
which allows each of these allocations to appear to occur at the same location.

The page tables are broken up in the following manner.  First is the page
directory.  It is composed of 1024 entries which have the following properties:

31 - 12    Page Table Base Address
11 - 9     Unused (Free bits)
8          0
7          Page Size Bit
6          0
5          Accessed Bit
4          Page Cache Disable Bit
3          Page Write Through Bit
2          User/Supervisor Bit
1          Read/Write Bit
0          Page Present Bit

The Page Table Base address is an index to the page table which contains
information about this memory location. When a memory location is accessed
the most significant 10 bits are used to reference one of the 1024 entries in 
the page directory. This entry will point to a page table which has a physical
memory address equal to the Page Table Base Address.  This table is then 
referenced to one of its 1024 entries by the 21 - 12 bits of the memory
address.

The Page Size Bit tells whether each page is equal to (Bit = 0) 4kb or 
(Bit = 1) 4MB.  

The accessed bit is used to show whether the page has ever been accessed.  Once
set to 1, the OS must reset it to 0. This is used for virtual paging.

The Page Cache Disable Bit and Page Write Bit are not currently used by me, so
I will leave its definition as an exercise to the reader (enjoy).

The User/Supervisor Bit specifies whether access to the page table is
restricted to access by tasks with privilege level 0,1,2 or 3.  If the bit is
set to 0 then only tasks with level 0, 1, or 2 can access this page table.  If
the bit is set to 1, then tasks with level 0, 1, 2, or 3 can access this page
table.

The Read/Write bit is used to specify whether a user level task can write to
this page table. If it is set to 0 then it is read only to "User" tasks.  If
it is set to 1 then it is read/writable by all tasks.

Finally, the Present Bit is used to specify whether the page table is present
in memory.  If this is set to 1 then it is.


Once the page directory is referenced, the offset into the page table is 
selected.  Using the next 10 bits of the memory reference.  Each page table
has 1024 entries with each entry having the following structure:

31 - 12    Page Base Address
11 - 9     Unused (Free bits)
8 - 7      0
6          Dirty Bit
5          Accessed Bit
4          Page Cache Disable Bit
3          Page Write Through Bit
2          User/Supervisor Bit
1          Read/Write Bit
0          Page Present Bit

The Page Base Address points to the upper 20 bits in physical memory where
the memory access points to.  The lower 12 bits are taken from the original
linear memory access.

The Dirty, Accessed, Page Cache, and Page Write Through Bits are all used for
virtual memory and other areas which I have not yet been concerned yet.  So
they are relegated to the reader (for now).

The remaining three bits behave just as in the page directory except that
they apply to the physical memory page as opposed to a page table.  All
kernel pages are set to have Supervisor, Read/Write, and Page Present bits
set.  User pages do not have the supervisor bits set.

The code in kinit_page creates the page directory in the first of the three
physical pages that it set aside.  The next page is used to create a low (user)
memory area of 4MB (One page table of 1024 entries points to 1024 4kb pages, 
Thus 4MB).  The third page is used to point to high (OS) memory.

The kinit_page function sets all of the low page memory equal to physical
memory.  This means that there is a one to one correlation for the first 4MB
of memory to paged memory.  kinit_page then maps in ten pages starting at
70000h linear into 0x80000000.  Entry number 0 of the page directory is then
set to point to the low page table.  Entry number 512 is set to point to the
high page table.

Finally the kinit_page function places the address of the page directory
into the cr3 register.  This tells the processor where to look for the page
tables.  Finally, cr0 has its paging bit turned on which informs the processor
that memory accesses should go through the page table rather than just being
direct physical memory accesses.

After this the _start function is returned into and k_start() has been set to 
0x80000080 which points to the _start() function in the main kernel.
_start in the boot code calls this function which starts the real kernel off.


----[  Chapter 3 - The Kernel


The kernel is where all of the fun begins.  Unfortunately, this is the place
that needs the most work.  However, there is enough here to demonstrate the
beginnings of what needs to be done to build a viable kernel for your own work.

The kernel boot loader created the kernel page table and then jumped into the
kernel at _start(); _start() then sets up the console, clears it, and displays
the message "Main kernel loaded.".  Once this is done it runs the memory
manager initialization routine 'kinit_page()'.

The memory manager initialization routine begins by initializing a structure
called the PMAT.  The PMAT is a giant bit field (2048 bytes), where each bit
represents one page of physical memory.  If a bit is set to 1, the
corresponding page of memory is considered allocated.  If the bit is set to 0
then it is considered unallocated.  Once this array is initialized the memory
management code sets aside the chunks of physical memory which are already in
use.  This include the system BUS memory areas, as well as the location of the
kernel itself in physical memory.  Once this is completed the memory manager
returns to the _start() function so that it can proceed with kernel
initialization.

The _start() function then calls a temporary function which I am using now to
allocate memory which is use by the user program loading in by the first
stage floppy loader.  This will go away after I add the loading of processes
off of disk during run time. This function sets aside the physical memory
which is located at 20000h linear.

Now that the basic memory system is set up the _start() function calls the 
kinit_task() function.  kinit_task() sets up the kernel task so that it can
run as a task rather than as a the only process on the system.

kinit_task() is really a shell function which calls two other functions: 
kinit_gdt() and kinit_ktask(); kinit_gdt() initializes a new kernel GDT which
is to be used by the kernel rather than the previous temporary one which was
set up by the second stage floppy boot loader.  Once the new location for the
gdt is mapped into memory several selectors are added to it.  Kernel Code and
Data selectors are added.  Also, User Code and Data selectors are added.  Once
these selectors are put into place, the new gdt is placed in the gdt register
on the processor so that it can be used.

kinit_task() now calls the kinit_ktask() function.  This task creates a task
which the kernel code will be executed as.  The first thing this function does
is to clear out the kernels task list.  This list contains a list of tasks
on the system.  Next a 4k page is allocated for the kernel task segment.  The
current executing task is then set to the kernel task. Next the task segment
is added to the GDT.  This task segment has the following structure and is
filled out for the kernel with the following values by me.  In fact all tasks
will start out with these settings.


struct TSS {
    ushort link;            // set to 0
    ushort unused0;
    ulong esp0;             // set to the end of the task segment page
    ushort ss0;             // set to SEL_KDATA (Kernel Data segment)
    ushort unused1;
    ulong esp1;             // set to 0
    ushort ss1;             // set to 0
    ushort unused2;
    ulong esp2;             // set to 0
    ushort ss2;             // set to 0
    ushort unused3;
    ulong cr3;              // set to the physical address of this tasks page 
                            // tables
    ulong eip;              // set to the entry point to this tasks code
    ulong eflags;           // set to 0x4202
    ulong eax, ecx, edx, ebx, esp, ebp, esi, edi; // set to garbage values
    ushort es;              // set to SEL_KDATA (Kernel data segment)
    ushort unused4;
    ushort cs;              // set to SEL_KCODE (Kernel code segment)
    ushort unused5;
    ushort ss;              // set to SEL_KDATA
    ushort unused6;
    ushort ds;              // set to SEL_KDATA
    ushort unused7;
    ushort fs;              // set to SEL_KDATA
    ushort unused8;
    ushort gs;              // set to SEL_KDATA
    ushort unused9;
    ushort ldt;             // set to 0
    ushort unused10;
    ushort debugtrap;       // set to 0
    ushort iomapbase;       // set to 0
};


The link field is used by the processor when an interrupt is called.  The
processor places a pointer to the task segment which was running prior to the
interrupt.  This is useful for determining access rights based on the calling
process.

The espx and ssx parameters are used to store a pointer to a stack which will 
be used when a task with a lower privilege level tries to access a high level
privilege area.

The cr3 parameter is used to store a pointer to the physical address of this
tasks page table.  Whenever this task is switched to, the processor will load
the value stored in cr3 into the cr3 register. This means that each task can
have a unique set of page tables and mappings.

The eax, ebx, etc.. registers are all set to a garbage value as they are
uninitialized and will only gain values once they are used. When the processor
switches to this task these parameters will be loaded into their respective
processor registers.

The cs, es, ss, ds, fs, and gs parameters are all set to meaningful values
which will be loaded into their respective processor registers when this
task is switched to.

As I am not using a local descriptor I set this parameter to 0 along with the
debugtrap and iomapbase parameters.

As I have mentioned every time a task is switched to the processor will load
all of the parameters from the task segment into their respective registers.
Likewise, when a task is switched out of, all of the registers will be stored
in their respective parameters.  This allows tasks to be suspended and to
restart with the state they left off at.

Switching tasks will be discussed later when the point in the kernel where this
takes place at is reached.

Once this task state segment is created it is necessary to create an entry in
the GDT which points to this task segment. The format of this 64 bit entry is
as follows:

63 - 56    Fourth Byte of Base Address
55         Granularity Bit
54 - 53    0
52         Available for use (free bit)
51 - 48    Upper Nibble of Size
47         Present in Memory Bit
46 - 45    Descriptor Privilege Level
44         System Built
43         16/32 Bit
42         0
41         Busy Bit
40         1
39 - 32    Third Byte of Base Address
31 - 24    Second Byte of Base Address
23 - 16    First Byte of Base Address
15 - 8     Second Byte of Segment Size
7 - 0      First Byte of Segment Size

As you have probably noticed, this structure is very similar to the code
segment descriptor. The differences are the 16/32 bit, and the Busy Bit.

The 16/32 Bit specifies whether the task state segment is 16 bit or 32 bit.
We will only be using the 32 Bit task segment (Bit = 1).  The 16 bit task state
segment was used for the 286 and was replaced by a 32 bit task state segment on
the 386+ processors.

The busy bit specifies whether the task is currently busy.  

Once the kernel task is allocated, a new kernel stack is allocated and made
active. This allows the stack to be in a known and mapped in location which
uses the memory manager of the kernel.

The user tasks is then created in a similar fashion as the kernel task.  In
this current implementation the user task is located at 0x20000.  Its stack
is located at 0x2107c.  Currently, this user task operates with OS level
privilege.  I encountered some problems when changing its selectors to user
entries in the GDT.  As soon as I fix this problem I will post a fix on my web
site.  After the user task is created it is added to the task queue to be
switched to once the scheduler starts.

Now that the kernel task and a user task (though running with kernel privilege
level) have been created it is necessary to set up the interrupt tables.  This
is done by a call to the kinit_idt() function.

kinit_idt() starts by setting all of the interrupts to point to a null 
interrupt function.  This means that for most interrupts a simple return
occurs.  However, interrupt handlers for the timer as well as for one system
call.  Also, interrupts are set up to handle the various exceptions.  Once
this table is filled out the interrupt descriptor table (IDT) is loaded into
the idt register. The interrupts are then enabled to allow them to be called.

The timer interrupt handler is a simple function which calls a task switch
every time the hardware timer fires.

The system call (interrupt 22h) is called, the handler will print out on the
console the string which is pointed to be the eax register.

The exception handling routine will dump the task registers and then hang the
system.  The jump.S file in JeffOS/kernel/ contains the assembly wrappers which
are called when an interrupt occurs.  These wrapper functions then call the C
handler functions.  

Now that the IDT is set up and interrupts are occurring task switches can occur.
These occur when the swtch() function is called in the task.c file.  The
swtch() function locates the next task in its queue and does a call to the
selector address of the new task.  This causes the processor to look up the
selector and switch to the new task.

You now have a very simple multi-tasking kernel.


----[  Chapter 4 - User level libraries


The user level libraries are fairly simplistic.

There are two files in this directory.  The first is the crt0.c file.
This file contains one function which is the _start() function.  This function
makes a call to main which will be defined in user code.  This stub function
must always be linked in first as it will be jumped into by the kernel to
begin running the process.

The second file is the syscall.c file.  This file contains one system call
function which is simply an interrupt 22.  This interrupt calls the console
system call.  eax is passed in as a pointer to a string which is printed to
the system console.

Both of these source files are compiled to objects and are used during the
linking phase of any user code.


----[  Chapter 5 - User code


The user code is stored in one file called test.c.  This file is located in
the /user/ directory.  All this code does is call the console system call
function provided by the library, wait a short amount of time, and call it
again in a non-terminating loop (good thing, as I don't handle task
termination yet).

The important thing to note is that when linking this user process is set to
have a text segment of 20000h linear.  Also the crt0.o and syscall.o files are
linked in as well.  crt0.o is linked in first to insure that its _start()
function is at 20080h so it will be jumped into by the kernel.  In truth,
_start() is the real main as opposed to the main() everyone is used to dealing
with.

This code is the task which is created and run alongside the kernel, as
described in chapter 3.


----[  Chapter 6 - Creating a disk image out of the binaries


Once you have compiled all of the binaries and placed them into the build
directory you will need to create two more files before continuing.  These
files are called STUFF.BIN and STUFF2.BIN.  These files are simply containers
of empty space to cause alignment of other binaries.  The floppy loader
expects the user program to be 1k in size.  If the user program is not exactly
this size then STUFF2.BIN needs to be created and be of such a size that when
added to USER.BIN the size is 1024 bytes.  Also, the floppy boot loader
expects the kernel boot loader to be 3.5k (3584 bytes) in size.  STUFF.BIN
needs to be made of such length that when added to the size of the BOOT.BIN
(kernel boot loader) file the size will be 3584 bytes.  In the future I will
try to automate this process, but for now this is simply how it must be done.
Once this is complete the shell program 'go' must be run.  This will place all
of the binary files into one file called 'os.bin'.  This file can then be
written to disk by one of the following two methods.

If you want to do it from linux you can do the following command:

dd if=os.bin of=/dev/fd0  (places os.bin directly onto the floppy disk)

or from DOS you can obtain the rawrite command and run it and follow its
directions.


----[  Conclusion


The kernel contained within is far from complete.  However, it is a first step
towards creating a real protected mode operating system.  It is also enough to
begin working with, or to refer to during you own work on a protected mode
operating system.  Doing this work is simply both one of the most rewarding
things you will ever do, and one of the most frustrating.  Many a night has
been spent at the local tavern telling war stories about this stuff.  But in
the end, it has all been great fun.

I wish you all the best of luck!

Jeff Thompson
jwthomp@cu-online.com
http://www.cu-online.com/~jwthomp/

<++> JeffOS.tgz.uue
begin 600 JeffOS.tgz
M'XL(`(-CQC0``^P\:W?:R)+Y"N?D/_3!<]=@$R(!Q@Y,<@\&G#CKUQKG9C(W
M<WP$:D"QD%BU,'AF\]^WJKI;+^-'LH[WSAUW'JA?]>[J:G7!>SX:'?=?/ON1
MA=6-;<-@SQB6[*>JL$:]8<+?K;K)F&F86^8SMO5#J5)E+D(K8.Q9X/OA;>/N
MZO^3EO=2_ZYOV3SX06:P0O]FO;Y"_U5CJV;6H==LU(U_,?W/!0_$8Q#TN"6M
M?\&'OF<_M!E\N_YKIEE[TO]CE)7ZEQ\52TP?!(=I&(U;]%_;WM[*Z'^K:H#^
MC0?!?D?YB^N_S\==+H;LL-TY/7Z>S]D+5ERKL?91EQE[4$JZK9II&[`U4S=-
M5$-=?6ZQXU.VUHB&]=^=LIWG^;7>X?/\\SQ(TH2^X].WS)A@PRZ(OHD/N:E_
MR0;+,MN>J(HU*8.MZ(I;9NOM=:@Y7@A!PB2:8\&<H5`56Y2A056XJCS/MZM&
MV[8#+@3@0KMKL3X/&30SU<Y<Q^-LP@..XW%(YV`?X'3:!P>,>];`Y3!:]O3/
ML.?]X0GK^%[H>'.8$PU1"+`,+=>-Y_IFW//%^YV)B1^{body}lt;;?M>SP>H%@V;',2
M-_KS$);*I&RY#XMCE,5A2!P)L,WT-#Y<EJL&E$EJE)L8]F4Z4^A_VJS&S8Z'
M.(&+N"GD(L3&Q"C7]V=`?A)T`A&RD<`4\!#4@6I[GM<*:=[/H'8S!A6;QEO7
M'U@NP_41.+/0#]@98B<+*;-PX@@V!??!!IPA.>SD=!_L/O392>"'[-"W(SLZ
M>-L](WOJ-_\)C[^E\>!P/@RY37.4`4(OL(+V)X<>'O^#..VU?RFSSJDR0\`7
MMYKID3"HC!VR%4T5"VF"5F8N9S0:(`Z#6[2`%[F</QH)(&@&!$%[0S<;.R09
M;&[F8/G6`$1.TCX'#?/QE'NA7GX<Y4VRC%;C(+D:H\HH61FKRO-\!,,8[$CK
M(B5>A9S-PH#]$_I^*[/JUJH.MLE,Z#2V;^BLWM99@TXRRA1SH36\T"RF.-S1
M'(H4A^B*7M&R8"]8/>)[5L8N::"YV5Q,9#4I,6.'A"97LY0%N$]C8!-)8#8N
M]QC_[SEK;.Q0'1VS,8)">K)AS1JO7DF=,8,0:>]N@"40364YH0S83#AE&<L!
MM`Q'V`X\7W3ZK`C*+K'.R8%QUWSC^OPNS`?5E[YC:A^G[MP]55.]DR#:;+!B
M]1O0[B2PTMR[\&*Y1K+5Z=\UZ3J?5O=[)O7[J,Y#,3Z`.(V6<7>7&5WL;L-_
MZ]CL>.-UA$;6@ILK%G.O!_6^,_:L<!YPG/@18K!V>PO7S[,;XK^ARRVO,K`>
MZ,![1_S'V%8M$__5MZO5I_CO,8K-7;91\0=?P-G`HXK\!XZ7JHNK*5G+4_EW
M*RO7?\`M>\HKX?)A',`=Z]_<,O7Z-XWMADGG/_-I_3]*.<,HUG8"B#_]X(J!
M^D/+\01$MYQ90O#IP,56"$M'$/]BJ[01#(S&T.CZL]D5&X#P\M*&*HSM>\P/
MX!%#882!,;,#`>65/Y<!LS]`)!)';:>A{body}lt;$,#R)A.P]]$)`'/EH@TP.#T(%]
M*4$KT#/U;6=T1?U$HT*(L-C<`Q+R%D"$@#I&4<GG]T=$B@7[X5S`MLG:2(1P
MIC/@-;R:<;9.9,6O0=8KC`2U<"`V@Z/BW"6Z+#9R7)['B`V"]Y$3B!!=)UM,
MG.%$#E8"3<H3AL(@*[BJL+:0N`&TQ;K'?98?6`+Z(=(>!]94GC$6?G`A@7D<
M^H!'?>``N#@)!/'1\6Q_(9!,+CB1):G-)^8,`G\^GH#X+Z5ND"8X\LZ7"{body}amp;*
M:>`OH=D*,P("W>>'_G3FN%;H^*#>$4V^X(''79#HZ=SS<-Q@[K@V!@Z:^=E5
MPF9(-D@::E>BIPD)G2[P\)-'Y$/+8T-P1!"C6S!`7#!GBA8G65D$3AA".(P*
MUT:(@Q*T1{body}amp;,UAJ$V@`+@^ME&%@>]^=""6H4^%,B)R:$+X=\%N:UT4O=@B5(
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
M&Y3_8=:?_/]C%%JD\0)]2O_[BQ6U_G


_V$_`G/O_+]:W6A4,?XS:[7&4_[?
M8Y2D_B%:<?S*\,%QW/7[#\:VJ>-_^6Q6MXVG_)]'*2\WV$_[=I,IW9<OF5FA
M/\Q\]6K[I6F\-&K,:#1KU:999V+!0Q?CG]YRQGYB&R_S^37'&[IS"+X+$L2D
MD,^#2"%:QT"/66$8L-?,++/9$CX-^+R"SVJ]I4<-X9C/-@2{body}gt;Q#2O69%62^Q
MSO'1>;]SVNL=98;.?(%Y,2N'LDVV8VQ4ZQO55D3&I>_8#.#[KCN?%;%68OD_
M\CD([XH$ZS53V#>9V3!:C!I_3K0BR"T`23V;FZ5\+K<AI[[`&26`0%2U5@/5
M%-T-^`^$+)\!P#I;;^D&8AB%"2U?\U_S>>(*1'Z.C442=0FY4@*W6JE!&`\'
M"=YQO`,BNDYOF3FOC9;SLR;-N94L:HC(RDD=PW.DY%Q6&$40Q8Y10@5]S;_<
MB$F<S<.AU.AP0IPX(ZBRUX#PL[=.-(Q]"/E1CX9$%Y,PG+3RURF:+3<W6P0(
M"7L-X@8P-+\)T")B:<`5#JC64;>YR%A*V,M=P;%U=D70KG,TNP*.-F=+8HJT
M`PLCR9=0EBJ(+S@?NKP(E3\DZ@V18C(G))J86Q.K7U,BWU"#KK&L>5[!M-DD
M+B*NK[&=X3MB/.+\+M:1R*]2K<D5.QO,1_]\]5LKGQ+*K#CWA#/VN$V.8E9*
MV27-V?E-T2KMU'F]W7+>H'6^>{body}amp;BHD$.#BH:2V./_0=`T;RKKC?L58GIRN9K
M_/V8%Z:AU9KJ,<BL9^S-F]>L+@TLTA^.*Z67%+0O8Q:(T27R@%L:@36(L"50
M92SWP$F\>8-@L5O39R3I,U+TX;"80B.F,`)O)L`;>Z4T9#,)V;P%LKD"<E6)
M'1LR$L`F:=__WQO74WF0<CW^FSPXCKO>_YK51A3_F=4JQ7_FT_O?1RGI^&]"
M\5\UCOUV0!?-ZG;3K*V._4:>S4?L'`*P_>/S=_DUJ.%O:$4-44L<HN7`71G&
M+F;:I;MW#]J=_]0'PDS/AYX^*IJIGK<4],E23?5T/K5U!ZNE>DY[W>C@64_U
M'+;?]H[.VM2SE>KYU#LX./XHYS12/1_?[9]IXK;5]G`Q"V`C&ZE=?S0-RXQ5
M*A7PT:NBMM;*,*UU0V34NB&R:-V^N;;NV+A:L2YPS&@\&!='X_)@7(K)+6+M
MYY]9G?T/@\X23>*>[8P8F)'6.7O:'/Y$)>G_?XCS?W;G]W_P)X^T_S>W\+>`
M8!.H/?G_1RF1"V_W#\_3/CQJB9KZX`.Q:??3^?L/AR?[1V_S&.NS#7D_1K<C
MJ1M$FN?@I9&([@^7.PVV?PQN283!G)*S!$)PO,%+QUO`/_>E/P\'^-\"_W.C
M"Y<"S,#+G4O0!$XKZ)LH_,X%P@"'*A"*0#""X`@")`B2<$L5]DE=+UFN\"F%
MMS"SZ)JK@!`TZ`@R=+C\189>1#0XGR&]\#\X]@K,38L!/C'-9LHM+U375OY@
M-!>8VNN-F\P)UU7>,-ZLN0YFF=L(`L86K1*;`--T;TJ75G3;N*!OF%@`U+K@
M@HV'0T;I\3##GX7.U/D=QR,,2[`%AVGP"2<VX0S4K55Q4&)A<(4RQ+LSVA'P
M,HT:]'=7P@E4$0I=%.(T^3#&B\R%$TZ8<!V\2+RT`L>2\L!1"M,5DH<`+80Q
M=6!Y70!D?\KI>@\E]3*V&LN[H*3F]X!9`$2/M8-0V!;^U)W\UL:`A_0-%.#/
M&[\8.71#Z9&D,-%JX:M?F/PRG\Y$4]U8H@&M"WE!Z/D>7P(9F#=#7U$1G$^%
M$O5X;@6@(<[3>`3CET`!Y@U:`@4^!*'@-9]4\[&\T967IJBI,MM?MYGK7.@K
M2H%9'&!#A/Y%"G\3(>RS{body}gt;<NL@<:AKW8&H&&!I@C)!DPECL&*ZJOYB`\&(`_
M.8E7N"5)12YWX'ASD=>1&*[B%0LT6L[GU-D]_G@$(Z!JB>GY.7Q>^GBMZ_+S
M\V(!LXC,T6?/;'X.X^="";9Y?!?P3;!0!^QOEEO^"9DA&!@J9+Q)#"-9C0S$
M<B^47,"2I&A`&8$O*LJ08I*./YR915%>EMCG/%^"+C&+@'[1E>S\_!R@K*V)
M./)9RIS`,HM:I"6ADDKLCPSL*L`69EE4$?XJCAFQ7&!K@A78WPI,F*Q@E/&A
MR@IF(0-.0EM*8#'I252%1:'$FO"G8!58D6@ME5G!A@J1"*?QKXGI:VO#:Q!6
M`G!NAG`^^PXBDHJ[1M(*B'<3E8&8%-W^{body}lt;"]KN+3WMF'TZ/SLT\G/1CD>"E%
MI]2:'GK92@._CY8=+Z%DU&U9:[N0!B9A.1CY$S1%>P*/DF[A-<KB_)*>(T&P
M\MJ:PT`<ZGLJ0*R2+@$"X:9A70?EW!_6^>P["$OKZ48RL[#O1>C-L--"[J\R
M!UKQL&/?8`9E.6`#OY08)-8_?G$1]N.Y%R+(/U8Z-C"`(?AD)&D&_SL8AH`U
M?,XC2UU@`V&B1;\>0D4!2TJO#':B1X%?T&-*&<Y@P=S,&@8S-_(&$1CL60_&
M(>)*L-A_*!:3ZS!U&LWC81*7SZ!<&!0D+*-40G>OFW$WF5/<FH!R.V224`1Z
M@19^'?3BNT##"5M.=V^:+CVB8@AY+*D620?1IIO<<AD`EO)Y:=V#DGI8Z`>W
MI."I3GI:1$_8+7?/(S_D,F*TYURG?&$4>7Z.&1X0]IV3K4``=#XKEBC53%">
M'LYF+S!.7@_5]]S0TAT;\[&4(8[T5RN*3J@3U#!0_%_VW@8\KJ-*$+VV)5OJ
M*,@A"1A(EAO'BKME_?3M'[5^8A-;:CN>6+*PI"2[P:NTU%?JEEO=G?[Q#\2)
M'"6#VT*,V3?+SNXR[^$O,_OXWGLSC^^;V2$+\S%VPL8+S%M"F'TOP'L[`69"
M&WF&P++!!"]ZYYRJNK?N3TNR(RL!^DI]?ZI.G:HZ577J[]0Y8RC^#DR=XT!Q
MKG@&\=#9:D@%1),[P7MU0@E34'V\D*?!)1>6,U+(^WE!?QQ48*?1PIC%1SQ>
MKVMF>%>BWG./X"OWJH%PAT_]$(2II['`V+@7,?E:!&RWZ67U\9F5%L;]WK<8
M-:`8YQ[=A@L/Y+%D%)"M5E81KE)F[7[6[(+O*F38P&)F63A9,WULE;)\K'+I
M'ELBN\?>>F:/.4KWF&M&5ZUTCRU5NL>6+-UCJU&ZQUQ*]YA[Z:96*<NIRJ6;
M6B*[J;>>V92C=%.N&5VUTDTM5;JI)4LWM1JEFW(IW91<NFQ6]W:O8U6OZ[OD
M]=\C>,A*7WT!L&7/?X0CYOY?1P3/A?L[.JKKOVMQB?T_4?;V#<"@JFG=X4!W
MR.^V`0BA@2S)6(I./.+JC$4D[-Y\(1[+3;8E=LER8DQ(S$UNS-R!FM94__'@
M1*<JNP7`+3#1:8'#$Q,$S[?>CL9&\VG+]MM8"VV!I5I4:3L.P%))/&Y_%,;B
M5OFR(TP&(MQA"*RX;.?AG)[+>LBHF'P$=Z5#I%YT;H$P7$!#3A_%U`(QH7\+
M3PH'`J[JE5R,[;XC%CD,L>XWD<GPM.)R^R@K$[:/R%-)HUH<:`J:[5"#/O5Q
M6FAL467''A->"QA>+,H*%U2#+FSA8UF8/G2V#K1J6`\,-&8$.S09O2,Y*,H2
MF;`G![*)!3BI%_KTL>(D'@NT9(WDJ53O739\88;/K_EXG'P-08*2)'J`N"9V
MC(X)H2V//^#WR7FB2N*#T!+EJ*#>H=VDS/^G8S#?6GWQWV7/?X0BAO[_8(#I
M?PU7Y7_7YG)CP^WM:B\[?)7-D-(8G+4S_6?D@-M16%>$EC$\>\=:D;?Y"&-[
M/BYKNE/U<@_NXB..@U>G7_!7SBFMBU1CJ00NPM=;Y!@*TUD4#H0{body}lt;O-,M+L(
MW4^63H?A=EB>4J=/9W(G//4`#TDX0DRQ7Y_NGYPN>!$Q1]*+>VNTW,!2X#,7
M-?@ZA)1-3_T1`882B2??>6WY>BY+^]>G;T3S7Z[]A_PA4_XK2.<_`L%PM?VO
MR66V?RQ]]W&9Z82G8_/$(ZR--8V-*W:\1W+'YGH{body}lt;-+2+S89/I:BMHC-U=;>
M4YEQ:N]<`KB^""_!``RW4K%"3SVVUD'D/;2I2ZW=.*YIP(Z.YX(,=%B'AD_[
MTV-<8QYXR7!^DG"M!.IG[&%?+C;&CLGB)G`AD=-UBIJD`QB+H0`F\\&U4D\]
M)EEPOF:?ZO6&_%T=S5Y.I';\`C[8JI)ST&!&*/M%:B(P2IFA<=U1E-NDGN?"
MT)0#-0D3=M0G"&]T,`'%HMV12?2B%#+!:63"%*(_EA5,CYWP#O7O00$"/&F,
M$@9I4N&(9C*)Q190+\DQ=1`P#X^E!$K2;+A#)<R8.Y3K@$%FT!:)YN=T)#R)
MY&1"D).=G<:CQ^8)8U5@#_A#G0)[4MV%:#X$_*0;*,Q*U@?#1^Q:`$C$[J/H
M593F-OH-TF:)).DS3OQB,G!Y&GNYI&X*JZ!\@504K&RY9#>/4[W'R/IAEE<&
M%-8"+F"8!P'FL='=4N8%ZBB#>_M03M*2?XB)R7X;J-'7)\=M0@:<D)PZ%0($
M70,$FN4@)BFA6<&X>A+%&VB4P,8'?*O!7NVP?<H4H::-*TIL#\J[%=5K-,%L
MH:D)(+=V=V_-X18AO/M$(XF2_4_$C$(J]1"0AX(0&-"_M7OK3AZ*!N;UO+'3
MXW%C\.''(P!F:!ZG7XK3S^)DDP8:PMMXFV50X<[++`&.QE(]T@


)"!7E#FA
MCNFII'Z4B>$P;4(Y$B&"=VC(T!@U:(P&T_'4<U:"[1>%:=%TX(1@(\AOF<*!
M:7HU>56&5;/\"2BM:4\])`@'1Q8>+0VMI`9H5DP8!)D,'+/)PQQB<ZOEHVT3
M)&7T.%FYQT`"LAEW/\-C'OC"PK,$0V4XC!H:&BCNM?L+K`#".!XDN0^%@U#5
M23N*0.FD]839H84$ZS%@0Q::4Y@](_N`;PM%5"C@A7MF6&[97":KYU(GU!-Z
M`57\#>AZ7FA>F$@>U^,><?"'I?5>7-^@M%)&ZUD>'R%/;(%:A!]DL7K<A3X^
MXW00ZL9!.+,^,.P[J)G6&]G>0:01];Z>`UD<3S)%.T;QB+!41F_W**5ZW:C+
M/OZ_$0+`R^M_D,?_(1K_5^U_KLVU1)\&O/WM3EWUNM&7W/[%PO1J+P(LT_[#
MD0YS_R?LQ_-?P5!5_]?:7&+_QRQ[]QV@KFY_5X4=(%0*GB.)<`S3HNZ!N71:
M_9TV=4B`WRL"WI?6,Y-MXYGI78X]!$]SL[H79]@X]4*A:8":UG/CN+H'M&]3
MU:$*=L$?'IZ*G.BXFX$8$)D_<#,IB&PL=UBKNZUH7]3'H9R_$0!7DUQ_#:9
M(3H=!Z=@`&6T$S!@8LH652_.7M&:@8_0C*.@%"0M-HYS(+6I"-\6KJHV/0Q.
M:F=%-*JGXJZ9O#$%8:=CV4=P=,@V)K;[M[>HVS6\!;:3BFNXA?`6WDX*#N$6
MV=["8#OQJPMO,;R-X6T<;W&\Z7B;V*YZ3O:\A8TTE>^8(%BZ)<FV10Q:%,W=
M,8:@T!*':?-AYBR.+]\%:-7''U?O&L.[-X7K&SX?W[SI8<'-;1GPO^<>2HJ/
M$X6C02<Z5M^$I^KEZ@{body}gt;>)I==L)HO:VM*8AG#*8!1ZR^E@^F-Y70V_".X[;0
M]OSV;MP.X_6*[X+)%\Y!@&A0P&QKD$]I>AR`<OX@=\UC[.`_)+Y%3;6V.O;C
M'`A<LN*`8XD>YXFFPRY2979)/J/>LG'SU-HSZI+-5<[*<9:53C6>G$2E@T;M
M,YLQ;FE,NN<.*@)6N$Z4$T^Q!386M7K2`5NTY4]N\R[Y=%%@8`>AG+)E.=[6
MB_QT_V$G/I8$KJO`[N%,[=B.G9UNQ`=7NV,EZKM0.RXJCLAX)<*F;<1RIQ&0
M/XTS8[DM6_.[4VU-N]."U[CMK=O=_1UMW`W(24BF*J%R<EQ2XR0^S=6+`2>E
M74A:9"25:U,EHBY=`Y?)6S'0[:0_(.QR9BB>J4"`.%>^452;5`U*;8>I2,*9
MUO:=JE`_X8@7>(`+Z1D'+"('3*I0T?T5N>2.'6P=O$*CXG4#D[NJE>,M\*F'
M63


''RJ4V)32["HP$I8U,I:':<.9SG0`F6%)2X$L\*G*[,HX"XN=7X%-(OK
M$[%BJN"LH*(3A%YH:<0F+5Q;L(S'XF'OC4PTQINS!_28`,UC;$]%B)78AE`P
M+."#*%2TM-KR1(@=$2\E340(I;UK>?['=_=6?8ZQW/I/P&^N_X2Y_H]`=?]W
M32[C_#>>4QD:O7_4/()DN'BP8B"095K#=G%ZG)[L+!)Z:QTNWE3KT;>SYYTK
M%O5;<\GM?[7UOHMK.?G?@"'_X>^(!-CZ3TBKMO^UN);2_YYG-N6XFFP7]>]8
M:[B5/]2K+NE]9^K"=1D-'@2SZ#&G#7<T<G-@K\H4G_-0.0\3`^"?>;&?C)HC
M)#4,:EXOM*%=-T-O.RI&,+1%[#EX<+AMS_X!#^EC{body}amp;8H)_6TGD-="\PV42:;
M9.PLHS*MQQ_Q>(83(L^T+V^A3RRG=WL\7%DF+OP(>N&9B@S:*CRHYC+%`FH+
MX&`)!I9D5CVX74R/D+>6<?#=5B%*S?!,`B(3"P/DB))I*)1III.=40Q:<`J(
MD<SS<WMQE>E<8)*=,@IF<JXX9BC.!]J@"@5.#0_)@LD!^&8N%[A+?I1%2Z)_
MYMJA'""F,E<5"XC,EE`0#Q]EF(!V)2&H*P++?AHWCA&XNO]XXRZ9__=#\\'*
MN=IQ+#?^(Y[/]?_X(\3__>%@E?^OQ76W.G!P.-I-AWPGB7\R1@]<3U0'&*4-
M'HK"O*8]KA_54YEL^W%X:1]+IML]^WI[P6.;%P!\D^/CGGTTK^+?.W9X#O09
MGZFXQW-PS^\,@0.QHPS7.9<19T\RYB9$!ME-6\;S0/30`'0/`Q#&8.>>;5[A
M[.L&W(C3YZG?YCW0YU-;,^JV^X2CVAH?4%N'"V@!B20=.OVJIWX\:^"":1<S
M=M#N\;2-C[=ENE5$!)F`L`?5UOUM:NNXP'FORH#RW0Z8(0,&00PTO;T5T0@L
M,H@%RQ!@,2'&)2\R;8$QY*:-C$HDN49>R=L_ZWIND`;XZ]#_WH'MOZK__<9?
MUO*_,1K@E^'_@4C$;\[_.[#\@X%@N,K_U^*JJF^OJF^OJF^OJF^OJF__[53?
M[M;_K_8.P'+K?_Z@:?\E'.Y@_7]U_K<F5U6%=U6%=U6%]V_O9>7_-T8#^#7I
M_XYTT/G_<%7^?TVNJO[OJO[OJO[OJO[OJO[OJO[OJO[OJO[OJO[OJO[OJO[O
MJO[OJO[OJO[OJO[OJO[OJO[OJO[OJO[OW]S+NOY[8S2`7XO^[P#3_Q",5.7_
MU^2JZO^NZO^NZO_^K=?_S?G_C=


gemini - kennedy.gemi.dev




OIS^WW#`X/^A$.W_!?T=U?V_-;E<=/M*
MG#K8V;&L3F"'WF!H/3:MP;'\$1L(X_=\9:N"+F'NRU?O43,C8!:2%>Z:P['A
M"L7A&*O:7#!5">>SYKND87BJ13W2(U1-3F$T3CV8_'07DR@CP0I#;J3%{body}amp;]!
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
M`._"'\\


YF4NVVH.5,^[@EU:<=.I"6^<WVB]>S,]4EVGG@*1UP\6A9FB1@)
MC7600+&Q4]=4;9M%+>;GO*%L6*:-8]1F/<4ZU:U&#QTZ>*C%-.V$O96>IEDV
M+XF4/D%=@[%2VA1GXQ&JOX)F1MW%4:L1+9M!)V%>G,GQU=(Q?3))\_!EJX"Q
M+H=G\,%/7@`5MJKZC-40W"NE96GG4JH>)PUDAN&G";;&J;*[F9>DE!W"GC/-
M1_'.&,9=HB+S5(M*Q6&/`""5CU?P#`-K"VN.C"%""55HW"MOV*O>E+%YN37G
M:BO\#6B%-[:I<$MK#CYOMIOK:RC83JQ3=]9>L&*QYB*-)NRM1"K3Y9H)K6;"
M_%D,.+#>FBU%6-7,9:9MN1*##V.C(T9FW;)BO3.6QF7C\80^?D2,0RSZT!&6
M*1-)JDU\'(M5T%)!*+=02W(Y'(X:)^7BNE$;TL!&0T?4L4PQ'8_EDM(0J&`9
M:E`UY270JC%U%*AEW!B+77/$N&[*RYRO:MKPBQ{body}lt;3LV+:<Y>'!2U6+,4A6'9
M\J*PK,:PLC8KO01OO!H#.AN?$6W9X"YVYF%@V*$F?=3<(>I\)0!#YP?Q#3?B
M#1MD(S16DZ*\K8.[()Z%>IQ;F(WZI#0D%-1@#I7K?^6^0QBUQ>>4,=_.NO;&
MHEUC/*QO0*@T*K&;,"W0TCH6)SA?[D'>'D3]B=?+VMF0&YGLX1O#TCE2*1Z7
MZ<(.U<LWE;!G>9Q1T8B6,?HXMWOHPN-'@:Y86@:O3V?81CCC[.8^O'7P8R\%
M)+RT>W!_+%6P["(GP"')3('S2B.X*_8(<8LI1>'C->=!4BZA"%NI"'T^ZQ1.
M;HC+5;V5CE"L$[YKF*VM>'JV7/&3B1]'13.+T,PT+T%4C00I*QAMFXK+7"4R
MVG<LA9L^)U2_O87[A0(F:\7C6JCDJ:#=RJO'PK"LU`27@>*T"^'W)`L.TH\)
M4\MCZN-`1@UU<'@9!NB-.DD^8`_Q55JLY3Z[=JG!P]SGGIWJ&)79!(;SF=P?
MV1=7]61A7Y9E=(]E(&7Q,O,A=F])BH8G6+A53#??@&8+!Q,3R'B):=&&+.[>
MH8P!+I@;J!PY1-1C0KX0Q[\#?=A.1]*X>+1G_["GO=VL'Q!!-T\SS?D?WSE&
M3X:V*7[8Z(894(LZ)EXIMA9G_-CL*@LW.BAI[:3>:;2{body}gt;O+$BHE)6;&0$ZO9
M,O1\PD;0:Z2G1-BWR?COKZ\=7EIL-02S'":F"S3$93R:#R/LWP&[0]#N$#*$
MX7""0LK<^(ADIT,<*LC%H:RS&[2VQ8<ITJB88T%PD187C.%*&,,5,0:8T`.M
M>#HC08OCLE?`@AVS&"1A+"M.3(.')FAFQ3,IB!Z/!,)8/P)A0`=T%UDQITL<
MW)Z?/MV<`0HJD?`++V^<"3;%*2T%FD98<K(*Y`I*Q`FM3IG2HK5G:3H$6M1P
M14*$5T*()=


;RSZT%LOQI/O2*$0I_S'FMO_T0(=02'_'=:"3/[#7[7_NB:7
M4TK;UB?;34*SOF(U]TDJX+R&Y=D>6YJ7';3;`RPWH+/#+S\$%)E2W^KR@8GH
M6J:#=BD<@ZNM)"B!B%&&K,FP6=I5Y(M<DD2.9?L7NV2FA<`L5I8CRWG^!_JC
M_:-,=SU3*HF79O4>&8H>,CT#[T@V^FM[6?G_C;


gemini - kennedy.gemi.dev




?FWVO_'\3P@J097_K\55
MM?]=M?]=M?]=M?]=M?^-5]7^MUJU_RU?5?O?:M7^-[^J]K_=X*OVOW\3['_S
M^=^-L0!^#?:_PP&F_R$0#E7G?VMQ5>U__W9?-OL/Z<+:G__T!SI"AOZ70"3(
MSG]V5-O_6ES7J/\E:=?MXG9(5&PDT%(Y5:Q1.JC.Q2"X7A<$:Q8J'(;A`X]^
M\GV!_7W#DF+NZ,/>M$^UJH/1C]]]=UHL-0,`C`T13F./`'L$V2/


F'VZ&"/
M"'MTLD<7PZ()-!R/QA%I')/&46D<E\:1:1P;G<3S2,?Q7<6R/)YZR"!)+/C%
M`7/G&4[YP&(L'A\%TG@A&(D$CXZB..AH,O<8;4I:O/W'@WZ$()+;048(QG\\
M$"0_(G\>"R5"M`..K9%"R9,70M26HR[[;X:^6H5?`/D&ZC@&R3?8`7?$/F&
M*OB&R3=<P;>#?#LJ^$;(-U+!MY-\.ROX=I%O5P7?W8P:E8BUAWE7HE8O\ZY$
MKC[F78E>4>9=B6![F7>8G9^RUQ8-JP+4$\VU+@6X;\#5-\A]@ZZ^(>X;<O4-
M<]^PJV\']^UP]8UPWXBK;R?W[73U[>*^7:Z^,4$-OZOWF/!VI]:X\'8G5UQX
MN]-+%][N!)L0WF$F\8+L.85LQI#=%I![]S+!5-PPA`!YDE/%_</\$?QF)[2A
M3J11@A(=?*9XD1&MQ(P=6X4H!\;V`7%-G=@<@#T2:`:?'9I5K%=E(#2KA(L)
MEC[.F5]GE)B?$;AB4`3&X!C4.Q0],/I`[\&^*,K0T3%I>^I'UB[YQD>'?]7R
M(MF^]<2+T]G1:7U:Y&C<W$#7DUGC'69^DMC<6'&"B[BZ:#P3<KK8W0`*+CL.
M;^H.0H,.._#PO.VD0M-Q]5K^4?H%1>2XD4XF*MRBTB>>0'8Z!9Q.0</)0(5J
MM9R`8:=3A],IXHJNTPG8Y9)@OXN;YHI0<\F)%G1Q<\F(9N3$Q\YUV.H#E<9H
M3I_,>_&F-N=<ZX-<3:13;#0M4^/@B1('*(PQD1>]ORAG>(_N?A@J!\J!JM$]
MYFNO^=K'7JF0Y=607.LN/7:\A9YC_#G.G_'CHH>2H]HS:"`=DE[WFU'MKQS5
M6):ASHMGDD>5M{body}lt;5W7M@][XA@53M-5ZC^P?=\>M<7`5)":2E[C..QR-UO$W@
M;3+/FYFI$:X)B=O4%#N^U3!S$L^3A+<$HSM@=`?,A`-FP@$SZ8"9S%NUS?69
M68Z:KQ(A]@Z9N:^OM]8,"Z8'AH>&U&M$)XWO6W<5\ODVQ.]PA`C=8"?=8"E1
MIGPQ7VA#+CE]@C6(E;8'M%AL9&X2=12F3=U:6^7#&!YC,&W1/"M/;G!/41*M
M'J8)S_Y#'U9QA*W'V9D$#&3JX&IOQR-1E@G23C7@0^6+YO$2=TEJWML9`_AK
MRS@:MZIO;S>L@AK*++&X5Z+BDE01;^7G+`P'(2B;:P,&<#VH1"=.J[]1T=^Q
M_?(6',]8\XB'Y5J,7FT%6>9.H^,D!FW)_J%HGZ6N?R3=W-RL1H^/ZUDZ.NT_
MWO1PL^IMROO8.5"6)E6G,RB/L,_#)%EK<N=[<BTL5<0_A#A7O=&?<[;2HG;@
M>`^+7,]U<UUB[,M<2":2V"DBLT)&&]EII6T`85UH8>&=;N0PJ,&3XZ`%8KAN
M<E2@![2'ZFKA*E[.];\UE_\-A+2PL?X71%UP6B`2J.I_7I.KO5G=/S#<=K]5
MRU9"C\6A.TJF898PS71'"`4]1@?)3)2BE$LN4RR@>4P2['31%6<8?#1F.EZM
MN=-G[BLPRZKJQPS>%$_B(`1O.+RCL1V-)6


gemini - kennedy.gemi.dev




"3<<34(/@V;FD+'T6,6DFCD?
M,N6DMO:AJB:]=>Q$ZT?U7(8/\K;2.7V3IPGG@?[]XG4/;DW2"0#A`K0Z:/@>
M'!GH&S)\TD=C,!E7#V91*:P9!ZDE&X#!Q>ZCL60*4V;X98KPU4J<7;CU9KCN
M(Z!V7I\D[<]H?C573-LCPL&8)>P0A\?(!G-Z7C>3/40:?QU9W:>G]5PL!="9
M@CXN^Z"4L;I7QMZ,&'-']7BS<-F;RI#VY%:B$.N.A=_N%$RW*36]>")?./<S
M0ZK<T7-2WD;U>&P:O\42IUCEM2T`&VL7KMZV`9O=VQPXN7KC(DM%G\IA@A5]
M0A5]PA5].BKZ1"KZ=%;TZ:J<4W]EK\I4T)8@764Z:)4)H1F4X$+EU[$.U6,-
M>DV+0#V_1EI;5^^R[?_CULT:VW_0`N&0<?XG$(Q{body}lt;/]?TX+5_G\MKJ6L-#@M
M.U2V!^%A?>]DO-#C8987F"IFMK''7"Q[?=;&*'D-%*<-E;`P4PL:UGG$Y`<Y
M1[I`9X)1<QSB?DS%D`>2^<(C_;'CT)V-'S8W&NWJ9>G3,ZD7(+&$R%18:.+>
ML5/M-'4[&.[20K-I\D`$%XJX)YDB;OYU1)A%J+>%Y1X8+_;ES4<*^;Q#<4!2
M7JOE6X,\B\;VH)'WY.&V@E`T@-AP_9E05S9D8)82`K-R`FB6%-.S=1?-U]`,
M`#NM`[Y2F8&[7-SUUN(42<+J,Z07^#C%B^8<=K!!(222ED]-)320@!95\X?(
M&0/F!@]%AZ(#P^KC*GWV#1[PBW<1G&F@X&J`H>JH7DE/A%`@!)-)TI*&I^*1
M1DSOOK&@-HY'29O\6[NW[D1S#E@#?6R[!?!"ZHM9H4"$*-MNI5(!NI.=1IYZ
M6#&T[LKG_<*Y;_?P;L,=1K8:GCD5'P'C(Y_7I/<`7V24H\+\X)%V+S,:@,7&
M:[C`/IX7D>*@6TJ,@3F>EV(W7B?,U\F\:[I3\8*)`X?1A5PL:[@D,].Q+%E)
MX@KR66KH`#-KT6SKJI#S"DI1P1G:_LUL<K7_YKK,;N/4+55PZ2PR?F.-IC-J
M_,/6XB;%EOPDI5^L5U5J'*[18E`I5O@T(F7O2U9T+`A655OX?M+>%=5P(QQ^
M388>X.Z3P<">_<.^I1L7EMSUQ&F$N\XX`VL<Z<@U$C>X"L0=N4;B!E><3]Y&
M)N7M7?AH(4L=[9URY:85-.I,N,TCWAF)RHNNDK69@F6A$SB64#VGXDS;;WX!
MU^(??#&_0`RN!>V`L%7[K-_X`&`+7IB@2WC'Y(]Q^2-NIHS'@)AQ`TF\CTGO
MX]([;299K.IHEIP$Y)QH\D?`-4X(+V<M(&5-D]ZM"B2`G4F1)K/2!_68EA2Y
M14O]C8@55S_%.]][,A-DC5?"'+?$8KY/2.^3>=?(S0CB<ES&ZX3Y.FG=#((N
M0$J!Z`-,)^H$S,]L/)ES2T$*J[1(@L!BN!@]28NP/<-V"5@]]\@FB<0VM[G8
MG<_*=L"DX4UEHTZL(XT!++?$PY'[W,9E!CQ3'&'VPZR/<PS;)!,[]?4QV8A.
MLIET@9$)'>P'Q3A"'J-B$J1V)VOL0\7=HBLK^+C1*54*X!Q^F.V,Q-#ZHKO[
M]D2C>R6?L8H^XQ5]XA5]V#A':ESF%QOIF,V+#QK,YF&5HD#"05UZQ'_8E,E`
MJ0P?UU(N19K,RE1*9B4O,9KU'P\%_`%+0N4P>2F,8S1E-!PY9W)6X-VLZ!.2
MEV-4938&$T@>5]F;@TDC/@J,8<6IT$\)KFWDJF",K)?KI7!@C7E@@S"AI=><
M!+{body}amp;"$U)[GD,>WMZZI


gemini - kennedy.gemi.dev




JB_#%Q*J82DAT2,8<8^.`A?!P##<[E''4X4\VE";
MAD%W,X3@RO!$H_)8&Z0Q8TMRS8H\3E0H@4F5F[(T0'936X'&M%K4>[@JBOHE
MFBT)PXCZ9]C3L#9EP\(&4_`HS3^2J,G+9AV!YAY&A::*+@J)%#'OX(I*B3,(
MG&SZD5<3R<G$M4001J&4G6Q*@[(VS1)NHW!C9N%*QL@,<AK,%9-G?!Q-Y@JR
M')+Q[M"`Z:`N0#MX(J)#G9^46DZ'I(]K^S4U0AK6!TPK8:P2VE?ZR*B8FRBN
MF)ARA6"HU8O/K0U=A;:Y]4YV.-$RM,*HN]'(&=J08):T8@7U;M0;W&V:^./C
M+N=LO>!PI?2"#SU[3$6&/4+M)LH:4"TSQ0UV#ST@]"4:EM7H&%$RKTX44RGK
M!CLE.ZZG=&A*EI;[UNE3X!H=718E*F9$)(N+1K@+34O"%4,/#??>WZWVDF1%
MF[H_3<L_W>K=;+0AD=VZ{body}amp;'Y!G+L1N-=W:13T;YB`36/9Q7Z%8W4T[HM:@C-
MBS8_%)[CRAJ-%FT0Q`H+U/'Q>D4;W90F&@98UU<J!Z\\Y;3*SD`?X)&66"3/
MZ^L/G`7"C,YQ19URD:RX1-P+&3$B`#<9U]YNSGBLP?D:`O5(=A]:X\D6\XD)
MM4?-9K(HA`7#GQ[4*)%2M_F/[\&YF^&*D.*#X">@=^K>&CLNMR,NIB-ZH[%4
MAHS9<6MP&30']\Y4^V5<+NO_JRX`L,S^?S`0"9GG_T(ALO\<J=I_6Y/+//\'
M/8CU^!]W6')+GZ\&\Y+TF^Z'1@;0_"_?XI'<86[P3\66;\!T'SH0C0Z.#AX\
M-(PUPNZ.<G1PA4QWG&,86\=A,T&":>.HK;+D@<4=Q^"J-^#J'E"]0;O'"$,4
M<K@S1&


(EPH]G:X23R,\H&5.6BFD1HF_G`/G@^W#>=:6U'Y/`[J!#B.EVS@
MW'B6'12'BQ*H??3(X&45U:V[5!^$/\GGPCV.U$.^`"_)6-@.?P+'/H*'%8II
MM![&3OU;>W2<P_:XA(2IJAE0<P^HN0?4S(`!]X`!]X`!,V#0)2"MT-#2C,Y'
MGD[<L>,MN#:%\BFX7H42*RBZ@C(L>CSI%BTNLHA80VX`XQ)`V#WA)D"'&T!<
M`HBX`4Q(`)UN`),20)<;`"W?&,7E6J+2JHXQ?X5ND;9''.V!!J-,:@=;#6U#
MX0<M;U!PFL9PS4*L8M.44OK.B6];(VO&N;(%TBQ.8\THI>MH.7HTD[:X)W./
M\:/S!792T2WAC]G,SCLG(2C.2Y`]'HLQ2USEE17MR1N$W)WC76[%BR-P3LQE
MCV7G2C*P;9K`O59M<MAC3/%=9OA"%D0>9U5/C:_F99/_Q`W^-9;_4$.ACH"A
M_R\2(/G/CD!5_^N:7-=Z_IL)>U"CM$TYF2@5+59;3]&(BS=[MIPO^$%R.EFH
M#-ZIDF)!SDPZU<E<+"U$UIN]AG273Z5H?;A>1!B-E6$Z8>>E)5/3B9^S4X4"
M)@LF>3&=8]VAAE0?_.TTTBFAQ)-\[$S@KEUT8@XBE.(3AC0>-\.R+&$J.EGR
M,%>&TAV6.!E>RA*>&R1T`!4RYZ&B*'"NNT\P3U$67!,'+L?2*++%0MFEJ2G"
ML%3U7!NU<##I#V,.>8YY%BGUJ'8,DP\C432T>H3D,K*Q8DK-'XNE\Z;`<5YO
M:VLC59-&3E%PP%QCI@0:J@?YRC(\CV92L4(RI<.'=RL$(:$.M7LK2G48P6PT
MI-.T%>NI$8GH>6EYFUR2;/F6E91$K"1;^#867=C@9ZF$0@I4;Y/?1VG-;L6M
M#T'@I&]'P)'BR1N3XN43.KFBA(JJ@FG-2VEM=DT?`&0+N4?


gemini - kennedy.gemi.dev




*]"U/DEHF88
M>/Q475D.=PK<D&MJJ,Q76.@Q:S0'TPY3\L4\#B>FN_U0?P-^B]L><M.L<!JX
M[;;!D9O&"TXZF"T?)\L4"V.C66@U&DQE6(P\$X8/JG9@\=I]_*&*/EHE'SQU
M*GS<6+`JJ=MT)DYS)*Z3HW/X^`,5?;1*/D;BM$J)4XV6P%1C7P]!_9VK25"_
MOR)!KXF2$?]J4M(O8;/2C*L#H,V9W&.";&@C+_<8Z<$T>B%$Y@7`,2_/'W#S
M)Y@-&PSILU&$EL4KA-6DL!A1*UJ^DM(N$OC6DO>X>MVI$T'=$_=VC]A6]W(9
M_Z_U^F^@PUS_#?D#03;^K^K_7I/+6/_=#T4_>K^Y_,N_<8#&AV]C2;AEZ`!1
M7M;A;]DTPO5#*%-4"LN/(Z%1;G8:B49QEE`D^8>5`GB4PT=C/@&G3X#YA)P^
M0>;3X:>$XQ"R+U:(M?=FXGH[+BCQ1#G33VNW%%8+.-(?!QQH.SP6;S^62Q9T
MU]"Y#(5VYMX,K6;2J1..P+2<S*+>[0B,A\EXU/IQ?=PU\'$6<^<2@8V8K:&1
M))S^78[0>!H>@(2<,Q*49BI+U0.49.08[?6`P@):@/"22DYMC\\1G,0?>>%:
M@W.=H(B!J7+F2#K&<!AIQ[/[P0,\&?8"01_`@;;5+).*MV,FV_.69V\]RTR+
M>E8\M^E9\9RB9[E!?8_[*%?2Z$;,97#WOOT#^T8/#GA]JK$YJS;1R4Z2Q1_/
MP<"%?6=RM$4K]B9:^"8M@9&P*`*+?5V=;=*Z1K9W[PIB$SO"$29<MG=%T;F/
M1"O2HM(8K*?"X,=8]C19\VKP?VO_CZQB6F\K'%^R*[S6:[G^/Q@0Y[_]$;^?
M]G\CH4BU_U^+:SB!/92QP6@Y!9[/%'/CNCH!\^Z\<?Z;U90VCV=_&EIEG!D@
M'\],9P%*#G4B4U2/)5,I-:WK<94T.!Q%ZQUJ],!>XBIQ$2KG829<^6=>6#0_
M#GT/)(4V6/`$.K!LM`*2G,Y"5X:KE=!(CC"#(`C.=J+;]NP?\&"*6>1CNCI)
MAYP+*"@T+$QH(OQ8,ATC0[]J^U@QF8JWHY[S&,.)T<92F,OAA"``'A>R$BN6
MT[L]GGX(0!'*E^%H)1LGCH<=FQNW=A/@F,^@'%_&,%22YY")BI#\I#[&Y7$"
MPH492"73Q>,J>5.BO%"9)XHI2EP6]^B2&1]JZ[2G2+6?]L>8C*21LHB5!^!)
MS7NFBM/9MJ&*X=!;B@6-4#G2A8X`PT#0T#MN/_IHC\P!3!M7T[%T;%*G`8"$
MFJ1=;*@E@K+"JQC\2"


=<D6'2]G]$*I)8E:M+5BBPR'5_FL/IZ<2(Z;L*HW
ME8G%,3@=^,`4Y%6],(XZPMD,;9DT!ZTM)^^9AC;MB!P=17H-%0Y>E>L9]ZD^
MM#3JK!+<0+9$A&8X!TUP@DOUUG#[I`<CCF9>/G6A!4O)#,=C^7BQ`KR*G7V
M29;=MYNI_AI=UOY?L*W5C6,Y_>\=0=/^8Z##C_T_#`"J_?]:7'>K`P>'H]UH
M8DN=I+Z/]5C0T8G*X/'T"LUYV[R]>WUJZWZU#:9.T$%VB^


gemini - kennedy.gemi.dev




=*:BTT2]S_32
M[:D?S\H`;6VLI_5X/`?W_`[B([Z$PP?LY#(JYZ@9TQI9!MD'W*G/R&`O`7?B
MVQF:JK1E/!XSAFY((&+V>>JW>0_T04KC`VKK<$_7E#9U`$FI:T9.4U2@(%^
M")#NE7UWB0\8O2/(T+!/\O:PKBS3S9(WA!"]O8!D7#AXQE-Z#"6,<]-JZX3:
M#*EN?D+-Y-N:(<\Y'1SX`R;2&`?<,=IF&L6L2?E;VS]+]FK'L9S]OXZ`L?^O
M13HTDO_LJ.[_K\EU-S/_QPK>9OHO$%3]P>Y@9W<X8#/]Y_&T8:/RM$VF,F,I
M29^.W^FD.9T"3J>@TRGD=`H[G3J<3A&G4Z?3J<OIM-MT$LJ'3!=#HY#I=&0L
M;G70C_OE#TW^",@?0?DC)'^$Y8\.^2,B?W3*'UV62*U)L*1!LR1"LZ1"LR1#
MLZ1#LR1$LZ1$DY*":GPL7P'+5]#R%;)\A2U?'9:OB.7+&E^7-7:_]=.:&LV:
M',V:'LV:(`L%A+(ICT?Z`+Z>+R3IZ)2GWF/6&7"?SAP=4[>A\O2F6,I3CWM,
M^-:";I[Z)(;PW"TUFV[/W?6X(!6#)QV),QL4>&2RZ.X(I54,I=E#26T/4L?"
M6(,$/"R$,YI@Q6B"2R0N5#%4:(E0X8JAPDN$ZJ@8JL,6JEX.%JD8++)4L,Z*
MP3J72&-7Q5!=2X3:73'4;GLHK({body}amp;CS(+>>F:2"A-SF:I`L3.3$3XP%513_T4
M3-!':37>3T":`TAS`@4<0`$G4-`!%'0"A1Q`(2=0V`$4=@)U.(`ZG


gemini - kennedy.gemi.dev




1!U#$
M"=0I@.H-J$X92B.H+@>J+A=J.FFN^9VX-!>J:RY@3KIK`1<P)^6UH`N8D_9:
MR`7,27W-A?R:D_Z:2P%HSA+07(I`ZW2"=5K!/(RQ=YN%)"A&M9_U6))OP.$;
ME'R##M^0Y!MR^(8EW[##MT/R[7#X1B3?B,.WL]M9[4S?+LFW2_*MY^3PR_3P
MNP!8"*:Y`,@TTP(N`#+9M*`+@$PY+>0"(!-/LU"/0QB%+Q@EN(W&D_ELK#">
M\-37+\<)!>^+Q>-0>"U->C[+&6$]!.8UJ)MS3/JRP4JLD[<%"W34%=P9VQHO
M7EGG?VUM-$%?Y3A@_A>I//\+A+2@(?\1"'?0_H_6497_6)/KR>B!O>O6K3.^
MURL;%/R:@?\0/._8SMQ#B@KN7J5.V23\"09_KV]3%'5``1^X-E];_".EOY]Z
M;WDOH"Q_&&Z)?WVG,E.>7`^?8[5P:]T(MRVW@L>?HL<`>$QMF%I7_I<05^GY
M^:>N-L+S*X<2Y]'7#[Z)QS>O5Q(SD(_R-V]7E-FO;)M2!LN??J^B-'ZY%IT'
M$_\986LPBB<;X/;^+1#J_T.WU]=A@-L2_PT_?@`?VLNS7ZDIO;'GU)N++=JZ
MHS]?^+NSD-YS-4W*S/S9ST+J2[?7P7OM9R$57<\?\\X?5<ZAPYG-I\\^N@A7
M+7X1/(.A[Z/?Y1B41CN&T%D*_Z*BLJ!SY'ONRC9EYO3Z"MC^K]+EPR^4WIC_
MR^V<GG/1NF<Q!+IC>H<HR+,(K'UU6?R[3_WB?P'D3_S?%VNO;J-B5B[6*N`!
M9%+F[D14IUZ@E-])&`Y?M<<_-'>X;J9':7SZ+'R?N77F34^QOG>A8_XOT)_B
M/[VYMV+\BQ3M[$Z\#Q:_8*;B'"9B]LJ68D/YV*\6%Q=N.CM?N{body}gt;Y[UET)K_Y
MFID+K]9LH`#KSF^H-7)]*0U%,?_G]R`6GMZSXD)ZC=3-1QL&#R6P8B>R$*#\
M'D6\M4!0.0#`SUZ^XZ


,9-SQ8:YD[?-GMP,>2U!?7KFNXU/G\+G&XV?/`'/
MN>CF,\KI:/GI\XU/3\#WO4V-SQR`YV)T\T#CT\,(,;+YS+MGGO]<XY>_5NHO
MS_Y";?SX!Q!@V_QG-T"&('_96F7F\RO\/5JCS+Q4LW)X^\_/PRJ2VPRXL9*;
M_RN\SUZLF=MWM12]#)E\^G?7818NGWGWZ9'RTR\W/GT4OD_?NAB]W#NP\+<L
M%.05@I2^TWMFW]73ZR\-`01'Q^K+[*\V-7[R,D=\\"I0X6+T,C(2:$MST?+L
MJXUGSC9@3>F_?/JV]UV8+M<L]E\^\?>S+]3-OGCE4BVB8P4K\/'TE9\Y?_+6
MG[\"+R]N:.T%<G\'/!?>?W9NI%P:*2_<<I8'DZ.MQ_H1+?\'[(*UEW_^D]+(
MZQ#^3/3U!C_D\G1?\\_F^LL`^CNED<O/?+50\\S+)U^"S,Z>O%S_Y!.4WLMG
M^KP_.[VA=Z"0YAY/_&AAW$*_7ZU[\B;MC84!*?Z'KD*23GW_=?B\\&;-F3.8
MW],W]<K9/WUK[^R+OUK8<G:N?_.9>O!<N)EA/1,M8WQ`9BB09\[\C\7%%S<H
M\_HKC_SS4:/]8U7M;X"Z-A^];?#0AX?*$0#C#0']+];.M{body}amp;IO_2AF2\M`NF?
M>[(-681R_P,G?C&EE#W`AX'C;H#'EY#GS7ZE#O(Z5/YI#;[7])[ZY2*X/O&/
M4]GRWX+3U&/E5_"1*W\3'_GRU_!1*+^`CV+Y+_%QM/SO\7&L_*>$0YTZ7OXC
M=#A1_D-XG,/47"@W#)9_3_JZ;[`\(WW.GE\_6,[4F`V:TQ/[$[7\(&*[JWP0
M'UO+]^/C[O)N?&PK=^.CJ1S$QSWE%GQL+S?QA'C+'T`'7_DV?#27;\;'CO)&
M?+24%S?`H[5\!1]MY9_@H[W\(WA@"EAY$+VC=?/(^V8N_*AA[F9,\-QG/@7]
MIW+J!\KKBXM#@XF-_P18"Q!NL?2*,_VSEVN0OXS4:8L+,>V[7=_*WPGL-=3S
M8&GD:OG`!J+ZW,C59\X7`[U=W\K]?=>WBET$]GXHE_F:GD&{body}amp;V9PO0`(,)<N
M_+!A(83\I/3SA6_(]7'?<\I]BN)[J>MB[O</)31,UZ4W%Q>U\PO;B;]"?2MU
M'7HH40`?Q/O7X`F5Z<.`]]!#Y2>P_>FO\\J&\,NE_Q/K5Y;^WU]_W>GWL?1O
MI?1+2;_%DO07%#GI<O\%B?_DX;J?O[`(G5SA@T.)SR+2O_G%XN)SV*4O?-3"
MOY[Y;K$E\4.`6/!0?(D/?!"@_YT!?6#AYK/R-3?2<&BH_!Z@6^GBA1\W:-^%
MYM1UN.'H5LP[T*A\A`8A-<^<+_SY@^4_91^]`''L>]KY>?UG+NF=O5R']"XV
M?`E&9\IS"@QJ?*]WO=`X^SCR,ZI_I?ZK@%][N>NG^5LA:,W[YTY>G;WWXTKQ
MOCU=/\W]N.NGQ7WD&9OKKROU7Z%R>#\4_4W]5P"RU/#Q4]$K.+)#Z+]?Z,&,
M\OA++RQ<D,NCUX@_=S9Q{body}amp;GQ;ZXL+I;#0$LHDYO.EEZY\&H#L)*9)^?URZ+>
M2.$9_;%GC=;58ALJO7!AH8%:_=R]?W#JA]B`M*]V_20?P'R\;^YV])F]]RFE
M>'OB'$:WXPJ5_NV\/5VL>0H?N[M^DGNI=,4DH-3>(*;2\[/?WW2AO*'Q+V9F
M[E%F&I]]*;=1.X]PS^%@EQ)I@;\P^[U-7T2O;WT?@M6=Q5""WPI_\/@B#%06
MO_6\:O'77G[NZN('E=(;+]9LOF7^_@VEFY^&/-3BT'GG+Q<_I!S]X7,PGE98
M,3-ZP)AW0_G<5>`7+SZ8^"%FL^_GBXO@6EN>0]>+#R46T;4-7(&-/5@N`F]Y
MJ)Q!#O/"4.*]*OB]&_Q>W/>^]TUM>+#\'N@`!A--Z/S+-R@(X?K0509/N+[_
M!L6PH>R3X_UK#E[[4/F;5Q%)/R+Y"X2M'2I_V71Z5N!]L/RYJT9L\^`J%<+9
ML[]\X?/J:^HW'BT'8:0?^\:C^%7>Q-ZGE$M`">71J767/D_/]9<^1\\-ESY+
MSYI+?T#/VDMGZ;GQTFEZ;KHT0\^Z2T_1LWXA_^B49^'XHU,WX5O#0OK1J9L7
MDH].O6LA_NA4X\+(HU.;%P8?G;IEX8%'I]Z]L'=JW4+GU/J%T-2&!?]4S4++
M5.V"=VKCPK:I30OJ5-W"'8!P"^"[#=!M!FP-@*P.<-4`*H5R$(-&^XWRZ[74
M>F/?*'^:OZ&SA1V<9?WOZ38VQM6^FWBJ09D9.H<.@^7_DYA@`^]BC_X@\7O@
M.>7GOI_"Z<['T66K!)_XM^BB<)=IPK`M\2PZKN..#R/8_XXNZ[G+7G3Y,W39
MP%U"/."7T+&&.WX0P5Y`EUKN<C.Z?!U=-G*77ZYC`;^%CINXXVLXLOXNNM1Q
ME[]!EQ^@2SUW>9X'+*.CASO^"8+]`[K<Q%W^+;K\%%T:N$N)!_PY.M[,'0L(
M=A5=WL5=QM!EW<W@TLA=!GG`V]%1XXX]"/8^=`EP%Q^ZW(DN0>[R7A[P+G0,
M<<?U"-:$+F'N@@.ZA`]=.KC+?U58P%9TC'#'KR*8ABZ=W.4+Z!)&ER[N\L<\
M8!<Z=G-'K/2)G>C2PUV>0)?=Z'(O=TGQ@%%TW,D='T*P_>BRB[M$T:4?73[$
M78(\((YYN),?!L;E.;C!J+#O)GA'?N{body}lt;OXCQ9G1SZ?E3WX<IP.+,?_YD:?CK
M-4V+4(UO5J"7*M5\71I_NL#_XQ+PV#^<W*R],7>X8;[F@]C1_16;+YSI^R>-
M3=A2!N'M7<;;S<9;@_%VD_'F,=[JC;<ZXVV3\;;1>*LUWFJ,MPW&VWKC;1U_
MJPFRE\0G[P(../<3Y(M]LR]LGHLVK+L"R7^J;U%FBM;YC#F>XO/-S7.]MPW.
M]6Z!WV;XW3&8^"M{body}amp;P*T<QO`H09^#8-SC]25#E\=2OP#^FVA*+T//C0'X__$
M![:"4RTX37SBE=(+$Y\X7[HP\8E72R].?*(,]'\-:5XJ7GWPU/?I#<9*I[Y'
M;_U7/WSJ!_2&B'<AEK]Z'1%OF[O]#P:@T_S"GH<'X?81O-T/MT/#&#J10,A_
M^3IF41XHFOE+_"N$R+_.)MJV\1+X+]8F<":>VVCIB,WP4^\M;_SQXF+B<XCF
M<7B;BVX;+.?A!7PN_Z/P&?LQB\`1GA/WI'^NV#E54_XBA)BK^<,[(,[!H<3_
MAD'_'PCZX-Q(Z-!#N%!03OR*=6WW/81NY21TI@N_,NN_P-<R5PP!OBD+OO^(
M^#[.\/DYOBT2/O^A\OML^,ZE<.'C?-VS^'09+Y4[<?7L5CY.<=)O2'M9.W]Q
MY@]X'P.8<$+FO71']%:VOZ?8:]?NO,L`%R<+:Q7Z"K=B85ZL?;W>;`I)5'"
M1V+HW"=PR'7>#_,OZ-8:U6^7;O[,`*[E$(*G$H``5VXG+O;6;<;[%GJ'T>/%
MWMMH2-;;@`\:TY6>RJXG[P-U>/\(!7B8[O?3?9CN@W2?(,@XW1\%!!AKJ?>.
M*7_Y=VO9]$TY=Y8XU;^#W`TE_A9I_0$@_U!9_ZG!J9SU!XG0]]\6%Y_%C`TF
MWL!@?_</BXN44>#_$#9Q'AGDO\';(LP+(")&A+K!\A1-';T,XE\X(#8/TORS
MDO<6P"\C>-,!H0Z6-QD(?NKP]@Z6RQL8`BPGGN8_KF&U0<S_AQ(-=T.NW@6Y
M:OQ";QWC$[-85(.)+>CSL\M`H%X_>+3`+P0_[V#B0^CSG<M8.UL@V!9HU,1T
M;B,>D\BB]Y<H8">X;(.?REC2'Z'/.0KHA3#($GJ1.?0B7^@=QMN!P<2W{body}gt;IC
M&'X6:P&Z3N`MCK='!Q.W;@/_1RZ;)<?FE\3_ZZC4/OD3K+K4'Y=>U,[#7$I[
MN?1&Z9LS7]U4^L3OXHSEU/-XOV\GU??7RG^"8UG*]_P<K1T_4,/JZ<5>[X^_
M_"?_]6)OB#U:V,./C\IU>&[CYY5:G))`-2Q]3+W8NVW]'G#M;R@]T.E:J0<=
M5=M6J4M_AJ2`QG9):FP;6$F5%S&?KTA=Q5$^_X,IQ]P,PI2B5Q</7VG<R+ID
M8SX^'[TZ.+5I:GWY#Y$)/J^=/\OG11>??DJLV#,:/?':7/1J+;HU;"JMIR96
MBTL7\/443B]++_&(K?P3NJ7#M\&\[-OY#\*\[+8N[-O^$\ST;HINF2O6E9[^
M-&+<W?7MW`_D*9A<GMKY+R&'TMXHO3';HQ2W/S28&*#R_Q&DN`>FS:5/?P;\
M%^ZQK??A0F#=?3L5J/#%%Q,%#.+]T9+]*<QQG\.HOH@,KJNNV'"1,3R:;T&3
M[GJI>$E.WSED@42<XBTF/S36G]%A[G:\S]?\%ZH4Q&IA`O_BLQB#49:#<[=3
M89ZE@GH)QE/87A%DL!R&+N`S#S<M`D\?_$/;>`KZ`DM_.7MY,\Z0<<QTYO!M
MIP^_?N;PEM.'KS9^861S"6B^N?[YTGM*7Z.1E'+A1YM/?0^"+=9_K?$OHJ]?
M>+6N_ODST:M-M-:(H'.'-^.J%'S]H*;^.Z4':^;U\B/_W+*>-3=2=R:Z>0*B
MN_"]S25/0VW3?Z?0=:4]-5)W).\_-"JO..KG2,.%[V\NC5R!*CH??;-QW1;!
MGRKX;Y;]<8D>W)3&+_2_6?)`%97XP>=O>4U=4!:4S_M?NXN>-?RYCC\7^?.6
MUSY+S\[7SM%S/7^NX\]%]K2OKQCXZ]SQ^\_;\&?=\0.<*W[,7W_=["\V/;GU
M8O0JK1A$K_[=75NC5U^[RT'?V0M7+D:O,*`K?W?N]/-;1ZZ<?NFU<Y;U-P,?
MK5Y\Z]42XCO]O&?D*H#>98D?\!E`A,]CXN/CA\2_PD;UK=>0F]<D_A@_7F0?
MS_T*AX-OW'_B?RS\T*RO#/Y9#O^_XL>G*\);+$(J-K.1BIN)2<6T1*F89BH5
MIRU+Q6;U4G$QD*DXK&DJ2YC@5&23G8J;;4_%:@94839"%30;JIC61)6!_OV*
MS?RH8C52"H0Q3^?@<2`]WN918LP,$1X-RF/F/`H:+$ARVQX>900(H^)A=[1/
MY%'V91"2],*C;"+@R60]BN<!;K\J@<<]V]H`;W\LF]7C_*@.AJ53^XD3^>0X
MD)1;SF(X484^US3>@B?;T)!67DT#$?1TICB9$.=]4OI


gemini - kennedy.gemi.dev




4_R\23K*NI#1Z7[
M1BYT/!8+Z'F`S(2P%L)41C-8TM@_D=,A1U$L?;60.\$53,=U`W<ZDT;MI6.9
M(AX)2AI9X9::5HP&B40EI.<L888-Z&(:3XYS[.S<(L\^N/,P0$VLF`:5TAF5
MJ3@DFIC%RK


gemini - kennedy.gemi.dev




5A3]-\C-G;'8H&B.L!/%$D+(5{body}amp;?SA:,%$U;#0T8J8JEL(!/
MJ'Y.<B!+D-'5H(MP#]O<L6""5+'PJT\WBTQ@.)8L)(3Z)"RZIK@5+KP$7+71
M5VCT4.^OY=^#(C31W0^K.U6RLA/=8[[VFJ]][)5![QDTW(>DU_TF]'X.'16G
M?I@%GU[C-;I_D(/TF=Y1\U4*M'>(0Y(2Y)6#3P)]45V$.!6J`-MR6J!O)A/T
MKE[<Q]5<G.QLFG/S**:=+'A?B5DL8+_79N6*^/4U6JGR*-=A8PH"7:>!*(]R
MW9:=&`67,X?A498U5N%1DND\M`ORT3Q*J[(#QPIG[E1F/@J_H_`[`K\)^(W"
M;Q!^/?!K@]^[X:?`[_(=RLS_"[^OPN_+\/LS^/W/\/LD_&;@)R2>4*I%F;E)
M47[O)L6O!8*A<{body}gt;DLRLV-A[7)YZ\2YG)P.\(_!Z%WR/P&X9?%'Y^^-T-OTWP
M^^^J,O,]^'T3?E^&WY_![W/P^Y_@-PN_HLJF#"3/MJ^WMUOU[AL8\:F!MDA;
MH"WXCG>KX[1"FOFU-K^F*.]X-Z4M?V(:^D-X%G+LF1!O>'1):<ME4#&/TL;N
M8_F\TC:>F4;.K[1!?WX-9V`_P./>J!@R<8IRA^DO1.+NXG"XPC;#ZJ'BJS/A
M1)WT\7>8<2K_!PR?X:=\18JOAC_;>=X1#H65X*?X?<YX0Q)NA<$J?RY]"[^=
M"I?A4YC_MGO<X6[A<8KK%8#K=8&K7N_\B\O_II)C[3<L#C6TE/PO<R3YWV#(
MWQ'`\Y^:%M(4-7S#4B1=O^7ROU+YC^<*_M57_JTL?_X_$-(,^6]_1P?J_PL$
M`U7Y[[6X3-7>_&`9Z?=N;Z<I58:T[`@5-J0OQ-#FXF5Z^N,XGT7:D+(YH;LJ
MF;;J[^<Z163=K!`%FG9B6"TXT)=0_`:JVWS'75+[%Q5@K?7_J\%(V-#_$23]
MGT%_*%AM_VMQ56S_I!@LR12!9=),S18ID02X@CZMTLFF<69C+76B#8/L+Y!K
M7E+F%`A0P&PLGV<JM&)B?4WUPMS91RN$:$0EF9Y$%&SM2JCN(B4@>ISQD$Q^
ME.N]XLJ^62C!3TBG'ZX7;?,?#P30DBCJY4.#FL*^"7CZ>%0^I@CY[2;^.^!R
M:?]KK?\7U?V9[3_(VW_5_MN:7(;^WZ%_.M2[^\`!606PZ;1T"S154[8W2Z%0
MO^K;G;WJM<PEM?\;H_Q368'^+[/_]W={body}lt;/P/HX"J_J\UN9;2_SDAM''2H6!R
MHE%Z2C^JI]3,V!0$8D"H*%/6`HH*EID:T+Q=76<QC_M67`^HT`#*=HD`-IF*
MY3PY_;$BI(@IZHZYJ!XUE7+R]+)IR,K5<^*%'A8]IPX,'C8C=H14U5Y!IGRA
M.,9F+<;HN2(L124-GL14R@CJ4)UXOUT7I17#:G!7J?W?&.5_R@KF_X&(.?\/
MATG_?U7_U]I<7/^7*'N;!C!_4-6T[G!7-VH@MVD`LRH%Y.H`J<5DA)(:U,YW
M71KPJN.&M;IX^\?:?<,6@*]C_3<8KJ[_KLDEES]3M;SZ<2R__ALP]7]@7P"/
M<'7\MR:7^_J/;1G7\S&[-=MDBSK%;"EYQE)D\UZ:'&XE,;2"$"_;RDPMUL,(
MQIN$_L+?HR;5>]4`M^4`7SMV^#SU]5/DYZF?S."0$["2*:AJ5W!#+[G]WZ@)
MX'+M/Q3R&_._2`3;?S!4G?^MS55I_D?S-ITIVL?Y#<T_8O+\CPO,M7GV%\0L
M#^5+\[3@R]:!Y=E.NC@]!F$#`;[&FRWBY(ZOQZH0;<:#TQO.0Z[3\D*O84)"
MGM;1&C,S]^!B3L`Z/[-E^S>>^\CM_T9-`)=M_QU^L_]'\UNH_[FZ_KLFET.U
M>UL;+@;PZ1RUELJZW0UO4[.[<.I6&:)V/B,D]XQP-.>'3D7M`:&E7<:^,DQ"
M@[L1<A=[E;2W"Z_JQ)1=O/W?L+5?O)9I_YH6YNL_\!_N(/N/87^U_:_))6_S
MDBB&V<F*%4=617BWC0=%H/>E]=;!1`YE[>\.!WAW;89EMF>*['`(+>&F4IEC
M>>BTQX#.:JNT@LJ-3&5PG3,'W2Z4QZ1A+XF@Z?A+#H+2,K04EOKT)!JGRF6F
MV2IU7MB#J!"'D4\&Y?


gemini - kennedy.gemi.dev




$W$!-88\TH`'(',4'02B%,GA)E*9;/8$3ZJ,!29)
M:,N]E5\LCU)`:P@[&3A:F0Q6?'D=1DR,*(5T!80<IB)&#V522I.4:9D>!<9\
M#=(=U7/^-DT.F,DE)Z%,4FXEHP+L;QS[_+6_./]G%M!N4!PK7O\+1()!FO]I
M87^DNOZW%I>E_/<</#B,IF=6.8ZE]?^J'7YA_SD8\H=I_S<0\5?M/Z[)55G_
M[SHZ-]#"#P0(_;_URD9)OG\=_?P;P7_3=>O_G8O6#9:WU*)NV(WKE,67##UJ
M-V^![U,7/@M@I9OO@/=SZ,!TWUXX=L_9<^AFZMJU0=#WT>\*+*2RUHDE@CI[
MT95TXN++W.V$MK8![JB4UA7M7W-=1*AK%P%-7;L(^2S":%]='J]0MOM?+M9N
MWLC(>K'V-GACRG8IY5S9+J&PZ$PB';M/8UGU>(H;>A="/(8-I]?W5HYRD6*:
MW8GWP>*7S(AG=U+$Q?KR#*K7K9OO6*2DG,.;T*V+P*A;U\CEI:.HO.BHH8;3
MH4_7#T#E=RGB[3ZN3[>2'MT/<3VZ$:Y'MYWIT9WI!#\5WF<ZFQJ?V0`O]Y5(
MBVX#O)[9;%6A^\HZ4J'[ZOIURME"S3KE\RO\G=T`"=RP<GC[+\[#;I;<_@C<
M3)VT;S0^/4@Z<\LSW9"A/G@_XSE]TY[22+EW8.%5H*--7^Y=`'&6=.3^M2(I
MMY5TY(Z49[_?>.:,BL4=O7RZ88M=1^[?(F"'H6?VF9=/WOKS[\`+UXM['KP7
MWGV6:;9=J)>CJ*@/MV9Y?;@IFS[<CYCZ<#^,.G`W:6\LW`\P;OIO,2^2_EOZ
M9/IOWV/JO[UIOH/I5S:UW_Z-7?LMTS_AU'_[I%7_[3G_IG5*$ZIQF3^MO+2X
MJ+T\WW&QYE/8*$HO77BUH?3"S-<WE#[S*>1MLV]ZGKRU%GE=PX;2TZ35=>%=
M$,]%]HX7UZ[TQ%_.4XB9KVTHW3)_BI2H;"B=(B4J7T>$__IG,.`J?>H*WD]=
MA7OCUF\WJN=OQA;=N/6\4'I#>:!V<K$6$XK:?\JW8]I>'"KOQ.;T^KQ^A>OL
MZ"!]3U_](BJ8U,Y#V!=K/+?,_[,-I3LQ*.F8//4\W=\D59.O\ECHW-I*SD2N
MR=D]^QG$U7-9]E2@=!J0#@$:9P*OX;*>!UQ'AS\_7FOZB_-[XCP@GJ7#KJ\.
M`G@5)]QVQ3SGATST_V_O;(#BJ.X`_H[/Y#((&@>U4;L2K$8]<E^`@XD2+V"B
M?%P"T8V2`KD/(#DXY"/%UH[,,*,F.)AQVAFUU@%-:\QDIJA,BPTU=!(SJ<(4
M:^SHI).F$\V08CNISL1\.*'O_][N[0=[=Y!<@,#_/_.XVWUOW^Y][-[N\OZ_
M'_S>)I@FMKN'*/E[A+4E1.URD!>Q$VV.WB]HN\<-VNGS_/Y+V]UGT$[.:0SU
M1S>V-XYO\Q)I^^"T8*&N/V`(GC7H+U+$ZUK%:]8,T_&ZZ03==*)N.DDWG:R;
M7J!98P+YWSB\KG;5J[_!H/YE5?T/Z5_X"4Y@4W$DDSZFJ:;A\[U>-7T7?;Q1
M-0W[Q,VJZ1RI_UT$WG<3><!@_>XX9?UK"/_>\$V*)R4&[=M4[3?2OW#039/6
M5V70GB0J[?WT[PIZ#DG/4\AU=#I('X_3+Z@@3;?1QV3I+.-:NOPS]+&(MJ^5
MZK=+[^<-TC1P+7?1_N^2IE^7MU]:?@]][*/+_TJJ?T_:?E\<G]XO;5^/5/^1
M;OE/I/?G3JG^"P+GKTH]4#KA<,F_M_'D)'T<H?WE2NWAAVJ!]'E<"]\_KE<F
M-1Z/O5(:TNC-(I+DFU2WM#21QC;2^!1I]C3Y?`VD,=C<`,^#@4!K(Y$]TF1K
MX^96/PFY3SVDUM=67]U(F(89NJMD7<D-2*6/';.@`FYF-Q&>9D6V@@BYLMA7
M7UQ3WT(J*^G13*J!IO"/-[*MNC+4#6\.M`[:(SO^;0VMH,%+&J"CZC:&-O$
M6^FA<*O4&\;5'YKK?_F?(S%>1Y3K?YO#IK[_P_RO=LS_F)X(?_T?QZ[_GY>J
MC/T_<:P4T>=0+O'Z?Q1^3]2\L0&P]P#/%(B."=O/Y*]D^IVS8U\Q'CJ]YA[.
M8.?NFF%&9,88%S/'FHACG\,*5;T1:P+>SP'ZF*IJ9\2:&*+MAG3K,V)-1&JG
M9TT,Z;;/B#4!]0M,QNWTYZ!PR8RLB=B%YOBOJ,UCNHYH_C>KU:D__F?G8O[O
MM$0T_]O!'_'YD?QO`_2"YG1Q;/QO/JW_;1/XW]:`_^VG&O_;ASK_VPL&_C=3
M>LC_=DCM?WLUY'_['?C?'@;_V]MJ_]O^*/ZWD4S%_W8D4^=_@QG*/6F88NVE
MF\<PO>VHU`/WOZE[<.YDR[-[QO"DD]7V')3\:(:]&?K?#FK\;[#(F]#8]I>H
M_:O\;X=#_K>A3-G_!EW)MZ19#U/UO\%"S/\69OWC;+4=*P_+_C=Y*WI@(PS\
M;S";U<GWJ`]+_K?0JYZ2_RT_Y'_+1__;[/"_?9XYO_QO\'I5][_9Y)7UO[DU
M_K=2C?\MC_O?''K_6T;B!/];:B+SOX&X:4O3J"F1^=_.<__;M]S_]C7WOWW%
M_6_'0OZW(]S_-@R*-]B:3LY59QJX_HDS\]VC;TR<RZ1P.PRZJ/T;'-+3%%V)
M^G@URWQQ;@-?W%>P^>MFGR\N#=1H[QOYXLHDZ=IKL]H7Q[;_W#FM+T[>]'^=
MF[0OKE/MBWL&.MT5R1=W2.6+.P^MM\TB7YQ[YGQQ66`8VQ(+7YP[K"_.K?CB
MVF%U%[Z[/%^<^Y)\<>XHOCAW1%]<^91\<8?@95ZO]\4=@[D7SQCZXL[(_C>M
M+RX!#&X?&_CB6%_OZGUQ;+VOZ7UQ]T`GSVI\<6Q6L]X7Q]:V"7UQ1KXX4?'%
MO<M\<:*Q+VX_]\6)BB_N#]P7I[3G]C8BS9%]<9]R7YRH^.*.<E^<J/CB3G!?
MG*CQQ8UQ7YRH^.*^Y;XX4?'%7>"^.%'CBXM/8;XX4?'%+4IAOCA1\<4M3F&^
M.%'CB[LQA?GB1,47QUQMBZ0YS!>7D<)\<:+&%W='"O/%B8HO[IX4YHL3%5^<
MC?OB1(TOKH#[XD3%%[>6^^)$Q1=7S'UQHL87MX[[XD3%%[>!^^)$Q1>WD?OB
M1(TO;A/WQ8F*+ZZ:^^)$Q1?GX[XX4>.+J^.^.%'QQ=5S7YRH^.*>Y+XX4>.+
M:^6^.%'QQ3W%?7&BXHO[.??%B1-]<2+ZXF+@BZL'>=L3,??%O0[=)AC[XH:@
M;O2TVA=W'F9]=OHR?7&W@%3K1=D75QO!%_<0M/1%\L5M@Q:N"+XX9S1?W-_!
M"O<<=%,D^^)<W!<W$*JQ3](7MX/[W48SF=]M.RSZUN7XXO(T_>V"_AZ;FB_N
M7LD7=^]E^>)JH_GBJG2^N%KFB_-.],553/#%!9@OKFIJOCCWY?KB`@:^N"J5
M+^X#>*_'_C-Y7UP%\\5]!HOU@2^N(H(OKB*J+ZXBLB^N(JHOKB*R+Z["T!=7
M{body}lt;87-P:OZMC7!KZX[Z#FH)$O[E80NNT)ZXLKA>I.(U]<!]0\&<T7UP^M'@GO
MB_L&ZN^>Y[ZXBAGUQ06FTQ=7J_/%64`U=;?BBPM$]\65P2)G3T7UQ<&J_E@[
M25^<5^V+DX^'H?O57N:+\ZI]<;6R+ZY6YXNKF.B+JT5?'/KB9J<O#K5.L\'E
MIC*!R6(CU+NAW@WU;C-_'$"]&^K=4._&N+6/WD+:"VEYD)9<6NRTW$W+S;0D
MTW+^9M)^C)8A6OIIV4W++VG90<LSM&RAY7%:BB;I<OOQ;:2]A):':7F`ECQ:
M'+1DTI)*2QPM)P72?H2605IZ:?DU+2_1\APM3;1LIJ5<[7*#F$6>MJO1W3;3
MGK:A)4J]T=C9(OX=(W=%\;2UT0O)MDEXVF!04?XD/6W0KELU;31V%NJ/AVFG
M'SO;CIXV#%UHQO_6!*_(.J+D?P@VNS+^U\KXOW9K;@Z._YV.H*=)0N':]66,
M^R&4%;A*2U:SIS(+1"@KWU!8R)Z%L&ILEIW-4X:,"_<#/6TN,M+F<FCV?_[Y
MQ7P=D?EO#D=.CI[_8\\%_C?N_U<^HO%?CH3AO[03.;?=1-STA*I<XK],<?A_
MB/_2!_R7W0K_13T^.Z5?Q8$9`"1)OY8#,Z#AP.A:L&G@P/2K.#`3>F{body}lt;F`&9
MUS+`X"FLV\2]$CS%L-LA@_^OPOC[O1HF#"SUY@!GPD1=AXH)TQMBPO2%F##]
M*B;,@,*$T8VG"(V_!S;,(M?8"KE>6B-GQ(3;A'&VYHZ5O8P1\YZR(1TK^R1&
MC)<Q8K:?&6>;UM.G8L3T2HR8T*N>TOC[$:#$L/'W[-EDQ]]W2N/O.Z3Q]S]3
M<6,",C>F5.'&B`;<&($/O1?BZ6<GW^\^G6`BUL3)E>-T0?<4VNM+;SQ_;%?U
M`:`'H_'WC"7SO$EAR3QMTK%D^/NM&W^_(>+X^S!LF<&P;)EDP_'WAIR9?Q`^
M_IYS9C3C[V/`FTE]\6EIFU5C\`/*&/SJT/JD\??N"./O![7\F4&%/_,#9?Q]
M*G\;]0R:Y_4C\`W&5TP8CW^'CD<SHN?1;#\3B4>S1,>C25?]_\^`2],7&RY-
MZ'@CL6E&9#;-382S:6PZ-DUHO+LAGV8D-GR:N7)/94JDFIC<#^&<FCM4.!3]
M_1"XEP`_T;LGP:F!@_=(!$Z-^M[#2!A.#?`?Y?L<4`^,.:-V^OL<+R=/CE.S
M8N'D.#5?3X%3(W-A9$[-[B1YFJ]Y)#1MS*GQAJ:GAU/3K>/4[-5Q:GIUG)H^
M':>F7\>I&=!Q:KJC<&K:=9R:$8E38PK#J>G5<6H&HW!J=NHX-6X=IZ8Q4<NI
M>4O'J:F*PJG)3])R:D94RP.G9H0N_Q91.#6P_>^H.#6P?6\3A5.C7OX3Z?U1
M<VJ.Z#@U(\DRAX9S:AJ3M)R:W<BI0<8%,B[F!.,"<_4Q5Q]S]3%7'W/U,5<?
M<_4Q5Q]S]3%7'W/U,5<?<_7G?J[^B3<P5Q]S]3%7'W/U,5<?<_4Q5Q]S]3%7
M'W/U,5<?<_4Q5Q]S]3%7'W/U,5<?<_4Q5Q]S]3%7'W/U,5<?<_4Q5U_>?@C,
MU3<.*?^3_KY:LVS+K\PZ!&?D_&^8R?,_;=FYD`MJLSEM#B)D7YG-T<8\S__4
M?OYPDEKORVIIBZG<,W+^KR#8LYVASS_;F0W^+V>N'?-_IR/*:^D//3UMH*?L
M<*7C"3:TT`M@N&`)T&L$H?XIH3Y(SP8\K4U-<"+.\L2;H0;.%K;1"[Q@:[.P
MN:X!+O6:S4V^)UMI7U[!#]=UM$6P.4N@%[P^"0T@^.OH59&'GDYNIA='377T
MZJF!79D*_D"PL1$NP,SUU5OIU3"]@`SR:ZA@LU!73Z\SLI`K<`5"N__+T(?8
MKB/*_I_C<*KV?X<#\O]S;$[<_Z<C,/\?\_\Q_Q_S_S'_'_/_,?]_]MRGP?Q_
MS/_7UF/^/^;_8_[_I>3_8X0/[?6_0G.,Y3HB7__;G5:KPO]T6G/@_E^V-1NO
M_Z<CD"F`3`%D"B!3`)D"R!1`I@`R!9`I@$P!9`H@4P"9`G.?*<#:(U,`F0+(
M%$"F`#(%D"F`3`%D"B!3`)D"R!1`I@`R!9`I@$P!9`H@4P"9`L@40*8`,@60
M*8!,`60*Q'@>,@7F'E,`X^H)[?A?V?`>VW5$R?^U.6Q67?ZOPY:-^;_3$NC&
M0S>>_!MV-;OQ,"XMM,?_LO(-A84Q!T!$X[\X'0K_(<=A`_Y#KLV&Q__I"`$C
M7,P+WHS!_F^/]0$@ZOZ?JYS_Y63GPOF?U>K`_7\Z8B9VK#D0<^;8H-W_:X)7
M8AUT_X_(_[/9E=__7*<=9ECM5MS_IR,\U2U"X=KU90S[)905N$I+5K.G,@I,
M")T3"O+=`4'YF1"4C&'A?@GR-F?VC?D0VOT_]$V(Z3JBW?^Q6E7\SVQ^_F]'
M_N.TQ"D_V;FFNBW85%IF(W$F$XD[3O(7G5Y(KM.@4I;ETPOM]6M=:Z3/K'!5
MN8T>J`76IHKC.@B[^Y!,V/XOP*T'-N:MD4V0\_UD9]?(`&F'QT''>/]@<M?G
MCC/OD[AO=]%9[OXNXO[XPH[TVXEC<'AQ4_RI%+(OF?1=T^L83AM.'[[I@]^8
M1C\CG=<\0#K35Y{body}gt;%^D:[+RU@'0_1-ZH(:-5M&8MZ3A'6LH[TQ\A/<6LNI1T
MKV/5JVAU&:O.[DS?0'H>8]4;2?<3K#J#5F]BU>F=Z96DIYI5>TBWCU7'DU-;
MR+KUO::^.,?1X<6/;VS_GK0LXEM7,)PV]F5W#;EXF+9<05KL+QSH."!T';CX
MY_9SBUL_:K](6I/>,?W>-+:_\XO!L:1G+W0<,#U[8?!$4N?'=#:Y^.'8;P_L
M-0^V+.R[AG9(._OF`.\X9SB-ODAW3P%]6U+,1<%J;UU##=D9V]BP1W?^'SK^
MQ_([-K7]GY__(_]Q>H)_V58-I[UPN.OSKL'SHPGDPJG;R&@J:5W2^\E)[V@2
M:;VN]Y\GJ_SOPQX]1K[T[HX[?E;ZDCXXG):5:DI_A9Q/%0;]'8=-J1F#8\3_
M[PJ21!:0?7`STM]UU-]UP-]UPM\UM@_^.WLH_O9#+E/R(5<<+?'>?3>R1I_V
M?S^^@&P_Z-X'A)WQ3_\T/OX*N\D)&03DU;_RQY>4QRNV3\RGT.___`0NUM^Q
MR/N_(U?#?[&Q\_\<9R[N_],1^/L_OW__\?@_GV/#'N0_(_\9^<_(?T;^,_*?
MD?\\>\;4(O\9^<_:>N0_(_\9^<^7PG^^G'_TS_$PX_A?'/\[%\;_SO!^=+5&
MA/T?^=_(_T;^-_*_D?^-_&_D?R/_&_G?R/]&_C?ROY'_C?QOY'\C_QOYW\C_
M1OXW\K^1_XW\;^1_(_\;^=_(_T;^-_*_D?N+_&_D?R/_&X\#R/\.UQSYW\C_
M1O[W7,E5N#K'3B+_.U(>`\;\"(G_4%R]U>>O"TQA9YI"1.._.',5_ILS%_@O
M]`GRGZ8EEKJ:@LW-%IX-4LW.KQJ;Z%>!GOTL=:\O*%P+)Y=UCGMS+*T-6QN"
M/VFP^`)^"ZTK+2OGE;3.;':YZ+/,._D2RVH\'OJ<MUAF7LHJ`QZ/8"D1+&N7
MMS8W+8?SL\#R0-WFY72^Q9EE75[7X`FT>GWFHM7JG@)>54<EQ>JJAGI555FY
MNHK^@-0UJFI7K5?75C>IJER%M,I2:C<OM?A;&R#3Q0)7ULV"Q1^LKVNQ^)NJ
MZWT6^:+1;"XH>90NX'*MS,B\T^5:EB$4K8:G1:OITY)B>%I23)^6E</3LG+Z
MU%7(VA8NRS";Z?53'KV,I6>_\MV`NLT"?+/,9IB;ER>8%^;[/+5!(2-#>6JQ
M6/A"%EUDT"8>+Z^[C[[`XE6/%"RCCW0CEYG-?!5Y>4J7FAZE+3#L4:J;V"?=
MWK`=PFO1;Z'<(=1-[`U>>=CNH-)XZUC-Q-X@MZ@AS_`M855A7IJJ3KN5J@K=
M&GD-<@XQ,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#!F//X/>T-0
%]0`@`P`Q
`
end
<-->
----[  EOF