groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Groff] fixes for grohtml etc


From: Gaius Mulley
Subject: [Groff] fixes for grohtml etc
Date: Sat, 15 Jan 2000 03:00:20 +0000 (GMT)

Hi Werner,

here are some fixes for some of the problems you and others
reported. Many other to do's still left to do though.

[ Does anyone know what command line rhunes are needed to
  produce anti aliased png files from gs and the pngtools?
  I've tried a few but my png tools dump core.. ]

I've included the groff_markup.man manual inside the tmac
directory. I've also included the first page of the homepage.ms
inside the doc directory. Feel free to rm it if its presence
is not required, through the doc/Makefile will need to be
altered accordingly. I'll copy it to Eddie as he might find it
useful. The new font files and some extra .h files are
inside the uuencoded file at the bottom.

Note that I've added an extra field to the devhtml font files
(what would I do without emacs yank-rectangle ;-) I wonder
whether there is a better method - if so maybe someone
can enlighten me?

All diffs against 18:00 GMT Friday

hope these are ok.

cheers Gaius


Here are the changelog excepts:

groff/ChangeLog

2000-01-14  Gaius Mulley <address@hidden>

        * altered tbl to issue table-start and table-end
        special characters if using the html device.

        * modified devhtml font files to incorporate html
        encoding of characters.

        * tmac/groff_markup.man: added manual page.

        * tmac/troffrc-end: added. This is invoked at the
        end of all user specified macros. Currently used
        by the html device to include the tmac.html at the
        end of all macrosets invoked. Thus no need for
        users to specify -mhtml anymore.

        * altered libgroff/font.cc to include reading of
        extra device specific information about fonts.

        * many grohtml fixes.

groff/grohtml/ChangeLog

2000-01-14  Gaius Mulley  <address@hidden>

        * html.cc: many fixes to table code. Fixes to
        manual page handling, font changes, spaces and
        diacritical characters. All *standard* html character
        encodings are handled. Added -T option which turns
        off all image generation for tables. One day grohtml
        should be able to determine this for itself.
        Altered image name to: <groff_input_file>-<index>.png
        as per Werners suggestion.

------------- cut here ------------------ cut here -----
*** groff-cvs/ChangeLog Fri Jan 14 02:06:13 2000
--- groff-html/ChangeLog        Sat Jan 15 02:07:24 2000
***************
*** 1,3 ****
--- 1,24 ----
+ 2000-01-14  Gaius Mulley <address@hidden>
+ 
+       * altered tbl to issue table-start and table-end
+       special characters if using the html device.
+ 
+       * modified devhtml font files to incorporate html
+       encoding of characters.
+ 
+       * tmac/groff_markup.man: added manual page.
+ 
+       * tmac/troffrc-end: added. This is invoked at the
+       end of all user specified macros. Currently used
+       by the html device to include the tmac.html at the
+       end of all macrosets invoked. Thus no need for
+       users to specify -mhtml anymore.
+ 
+       * altered libgroff/font.cc to include reading of
+       extra device specific information about fonts.
+ 
+       * many grohtml fixes.
+ 
  2000-01-12  Bruno Haible  <address@hidden>
  
        * devutf8/R.proto: Add mappings for ti, Fn, st, an.  Change mappings
*** groff-cvs/libgroff/font.cc  Sat Jan 15 01:30:59 2000
--- groff-html/libgroff/font.cc Sat Jan 15 01:31:57 2000
***************
*** 41,46 ****
--- 41,47 ----
    int pre_math_space;
    int italic_correction;
    int subscript_correction;
+   char *special_device_coding;
  };
  
  struct font_kern_list {
***************
*** 359,364 ****
--- 360,371 ----
    return internalname;
  }
  
+ const char *font::get_special_device_encoding(int c)
+ {
+   assert(c >= 0 && c < nindices && ch_index[c] >= 0);
+   return( ch[ch_index[c]].special_device_coding );
+ }
+ 
  void font::alloc_ch_index(int index)
  {
    if (nindices == 0) {
***************
*** 663,668 ****
--- 670,685 ----
            t.error("bad code `%1' for character `%2'", p, nm);
            return 0;
          }
+ 
+         p = strtok(0, WS);
+         if (p == NULL) {
+           metric.special_device_coding = NULL;
+         } else {
+           char *name=(char *)malloc(strlen(p)+1);
+           strcpy(name, p);
+           metric.special_device_coding = name;
+         }
+ 
          if (strcmp(nm, "---") == 0) {
            last_index = number_to_index(metric.code);
            add_entry(last_index, metric);
*** groff-cvs/include/font.h    Fri May 21 05:50:38 1999
--- groff-html/include/font.h   Tue Jan  4 21:43:41 2000
***************
*** 50,55 ****
--- 50,56 ----
    int get_left_italic_correction(int index, int point_size);
    int get_subscript_correction(int index, int point_size);
    int get_code(int i);
+   const char *get_special_device_encoding(int index);
    const char *get_name();
    const char *get_internal_name();
  
diff -r -c groff-cvs/tmac/Makefile.sub groff-html/tmac/Makefile.sub
*** groff-cvs/tmac/Makefile.sub Sat Jan  8 00:26:49 2000
--- groff-html/tmac/Makefile.sub        Wed Jan  5 02:06:44 2000
***************
*** 1,10 ****
  MAN7=groff_ms.n groff_man.n groff_me.n groff_msafer.n \
!       groff_mdoc.n groff_mdoc.samples.n
  
  NORMALFILES=tmac.andoc tmac.pic tmac.ps tmac.psnew tmac.psold tmac.pspic \
        tmac.psatk tmac.dvi tmac.tty tmac.tty-char tmac.X tmac.Xps tmac.latin1 \
!       tmac.lj4 eqnrc troffrc tmac.safer tmac.html tmac.arkup \
!       tmac.trace tmac.a4
  SPECIALFILES=tmac.an tmac.s
  STRIPFILES=tmac.e tmac.doc tmac.doc.old
  MDOCFILES=doc-common doc-ditroff doc-nroff doc-syms
--- 1,9 ----
  MAN7=groff_ms.n groff_man.n groff_me.n groff_msafer.n \
!       groff_mdoc.n groff_mdoc.samples.n groff_markup.n
  
  NORMALFILES=tmac.andoc tmac.pic tmac.ps tmac.psnew tmac.psold tmac.pspic \
        tmac.psatk tmac.dvi tmac.tty tmac.tty-char tmac.X tmac.Xps tmac.latin1 \
!       tmac.lj4 eqnrc troffrc troffrc-end tmac.safer tmac.html tmac.arkup
  SPECIALFILES=tmac.an tmac.s
  STRIPFILES=tmac.e tmac.doc tmac.doc.old
  MDOCFILES=doc-common doc-ditroff doc-nroff doc-syms
Only in groff-html/tmac: doc-common-s
Only in groff-html/tmac: doc-ditroff-s
Only in groff-html/tmac: doc-nroff-s
Only in groff-html/tmac: doc-syms-s
Only in groff-html/tmac: groff-html-1-708.png
Only in groff-html/tmac: groff_man.n
Only in groff-html/tmac: groff_markup.html
Only in groff-html/tmac: groff_markup.i
Only in groff-html/tmac: groff_markup.man
Only in groff-html/tmac: groff_markup.man~
Only in groff-html/tmac: groff_markup.n
Only in groff-html/tmac: groff_markup.ps
Only in groff-html/tmac: groff_mdoc.n
Only in groff-html/tmac: groff_mdoc.samples.n
Only in groff-html/tmac: groff_me.n
Only in groff-html/tmac: groff_ms.n
Only in groff-html/tmac: groff_msafer.n
Only in groff-html/tmac: stamp-strip
Only in groff-html/tmac: stamp-wrap
Only in groff-html/tmac: t.html
Only in groff-html/tmac: t.i
Only in groff-html/tmac: t.ps
diff -r -c groff-cvs/tmac/tmac.an groff-html/tmac/tmac.an
*** groff-cvs/tmac/tmac.an      Thu Dec 23 21:21:20 1999
--- groff-html/tmac/tmac.an     Sat Jan 15 01:22:50 2000
***************
*** 32,43 ****
  .if !rC .nr C 0
  .if rP .pn 0\nP
  .de set-an-margin
! .  ie '\*(.T'html' \{\
! .    nr an-margin 0i
! .  \}
! .  el \{\
! .    nr an-margin \\n[IN]
! .  \}
  ..
  .\" .TH title section extra1 extra2 extra3
  .de TH
--- 32,38 ----
  .if !rC .nr C 0
  .if rP .pn 0\nP
  .de set-an-margin
! .  nr an-margin \\n[IN]
  ..
  .\" .TH title section extra1 extra2 extra3
  .de TH
***************
*** 54,60 ****
  \\..
  .DT
  .ie '\*(.T'html' \{\
! .  nr IN 1.3i
  .\}
  .el \{\
  .  nr IN 7.2n
--- 49,55 ----
  \\..
  .DT
  .ie '\*(.T'html' \{\
! .  nr IN 1.2i
  .\}
  .el \{\
  .  nr IN 7.2n
Only in groff-html/tmac: tmac.doc-s
Only in groff-html/tmac: tmac.doc.old-s
Only in groff-html/tmac: tmac.e-s
diff -r -c groff-cvs/tmac/tmac.html groff-html/tmac/tmac.html
*** groff-cvs/tmac/tmac.html    Sat Dec  4 08:57:07 1999
--- groff-html/tmac/tmac.html   Wed Jan 12 09:27:39 2000
***************
*** 12,19 ****
  .char \(ul \v'.25m'\D'l .5m 0'\v'-.25m'
  .char \(br \v'.25m'\D'l 0 -1m'\v'.75m'
  .char \(rn \v'-.75m'\D'l .5m 0'\v'.75m'
! .char ~ \v'-.55m'\\s[\\n(.s/2u]\v'.2m'\(ti\v'-.2m'\s0\v'.55m'
! .char ^ \v'-.55m'\\s[\\n(.s/2u]\v'.3m'\(ha\v'-.3m'\s0\v'.55m'
  .if !c\(va .char \(va \o'\(ua\(da'
  .if !c\(em .char \(em --
  .if !c\(en .char \(en \-
--- 12,19 ----
  .char \(ul \v'.25m'\D'l .5m 0'\v'-.25m'
  .char \(br \v'.25m'\D'l 0 -1m'\v'.75m'
  .char \(rn \v'-.75m'\D'l .5m 0'\v'.75m'
! .\" .char ~ \v'-.55m'\\s[\\n(.s/2u]\v'.2m'\(ti\v'-.2m'\s0\v'.55m'
! .\" .char ^ \v'-.55m'\\s[\\n(.s/2u]\v'.3m'\(ha\v'-.3m'\s0\v'.55m'
  .if !c\(va .char \(va \o'\(ua\(da'
  .if !c\(em .char \(em --
  .if !c\(en .char \(en \-
diff -r -c groff-cvs/tmac/troffrc groff-html/tmac/troffrc
*** groff-cvs/tmac/troffrc      Mon Jan 10 23:30:48 2000
--- groff-html/tmac/troffrc     Sat Jan 15 01:28:01 2000
***************
*** 14,20 ****
  .do ds troffrc!latin1 tmac.tty
  .do ds troffrc!utf8 tmac.tty
  .do ds troffrc!lj4 tmac.lj4
! .do ds troffrc!html tmac.html
  .do if d troffrc!\*[.T] \
  .     do mso \*[troffrc!\*[.T]]
  .do rm troffrc!ps troffrc!Xps troffrc!dvi troffrc!X75 troffrc!X75-12 \
--- 14,20 ----
  .do ds troffrc!latin1 tmac.tty
  .do ds troffrc!utf8 tmac.tty
  .do ds troffrc!lj4 tmac.lj4
! .do ds troffrc!html tmac.arkup
  .do if d troffrc!\*[.T] \
  .     do mso \*[troffrc!\*[.T]]
  .do rm troffrc!ps troffrc!Xps troffrc!dvi troffrc!X75 troffrc!X75-12 \
Only in groff-html/tmac: troffrc-end
Only in groff-html/tmac: troffrc-end~
*** groff-cvs/tbl/main.cc       Wed Jan 12 14:16:53 2000
--- groff-html/tbl/main.cc      Sat Jan 15 00:58:03 2000
***************
*** 229,242 ****
          c = getc(fp);
        }
        putchar('\n');
!       printf(".if '\\*(.T'html' \\X(graphic-start(\n");
        current_lineno++;
        {
          table_input input(fp);
          process_table(input);
          set_troff_location(current_filename, current_lineno);
          if (input.ended()) {
!           printf(".if '\\*(.T'html' \\X(graphic-end(\n");
            fputs(".TE", stdout);
            while ((c = getc(fp)) != '\n') {
              if (c == EOF) {
--- 229,242 ----
          c = getc(fp);
        }
        putchar('\n');
!       printf(".if '\\*(.T'html' \\X(table-start(\n");
        current_lineno++;
        {
          table_input input(fp);
          process_table(input);
          set_troff_location(current_filename, current_lineno);
          if (input.ended()) {
!           printf(".if '\\*(.T'html' \\X(table-end(\n");
            fputs(".TE", stdout);
            while ((c = getc(fp)) != '\n') {
              if (c == EOF) {
*** groff-cvs/doc/Makefile      Mon Jan 10 23:30:27 2000
--- groff-html/doc/Makefile     Sat Jan 15 01:40:59 2000
***************
*** 20,26 ****
  FFLAG=-F..
  TROFF=../troff/troff -M../tmac $(FFLAG)
  GROPS=../grops/grops $(FFLAG)
! DOCS=meref.ps meintro.ps pic.ps pic.html
  MEMACROS=../macros/tmac.e
  SOELIM=../soelim/soelim
  
--- 20,26 ----
  FFLAG=-F..
  TROFF=../troff/troff -M../tmac $(FFLAG)
  GROPS=../grops/grops $(FFLAG)
! DOCS=meref.ps meintro.ps pic.ps pic.html homepage.html
  MEMACROS=../macros/tmac.e
  SOELIM=../soelim/soelim
  
***************
*** 63,72 ****
  pic.ps: pic.ms
        sed -e "s;@VERSION@;$(version)$(revision);" $< \
        | ../groff/groff -p -e -t -Tps $(FFLAG) -ms  >$@
- 
- pic.html: pic.ms
-       sed -e "s;@VERSION@;$(version)$(revision);" $< \
-       | ../groff/groff -p -e -t -Thtml $(FFLAG) -ms -mhtml >$@
  
  install:
  
--- 63,68 ----
Only in groff-html/grohtml: .gdbinit
Only in groff-html/grohtml: .gdbinit~
diff -r -c groff-cvs/grohtml/ChangeLog groff-html/grohtml/ChangeLog
*** groff-cvs/grohtml/ChangeLog Fri Jan 14 02:06:14 2000
--- groff-html/grohtml/ChangeLog        Sat Jan 15 01:49:51 2000
***************
*** 1,3 ****
--- 1,14 ----
+ 2000-01-14  Gaius Mulley  <address@hidden>
+ 
+       * html.cc: many fixes to table code. Fixes to
+       manual page handling, font changes, spaces and
+       diacritical characters. All *standard* html character
+       encodings are handled. Added -T option which turns
+       off all image generation for tables. One day grohtml
+       should be able to determine this for itself.
+       Altered image name to: <groff_input_file>-<index>.png
+       as per Werners suggestion.
+ 
  2000-01-13  Bruno Haible  <address@hidden>
  
        * html.cc: Avoid most "g++ -Wall -Wno-sign-compare" warnings.
diff -r -c groff-cvs/grohtml/Makefile.dep groff-html/grohtml/Makefile.dep
*** groff-cvs/grohtml/Makefile.dep      Sun Sep 12 08:30:00 1999
--- groff-html/grohtml/Makefile.dep     Tue Jan  4 13:01:50 2000
***************
*** 1,3 ****
  html.o: html.cc ordered_list.h ../include/driver.h ../include/errarg.h \
   ../include/error.h ../include/font.h ../include/printer.h \
!  ../include/lib.h
--- 1,6 ----
  html.o: html.cc ordered_list.h ../include/driver.h ../include/errarg.h \
   ../include/error.h ../include/font.h ../include/printer.h \
!  ../include/lib.h html.h html_chars.h
! output.o: output.cc ../include/driver.h ../include/errarg.h \
!  ../include/error.h ../include/font.h ../include/printer.h \
!  ../include/lib.h html.h html_chars.h
\ No newline at end of file
diff -r -c groff-cvs/grohtml/Makefile.sub groff-html/grohtml/Makefile.sub
*** groff-cvs/grohtml/Makefile.sub      Sun Sep 12 08:30:00 1999
--- groff-html/grohtml/Makefile.sub     Tue Jan  4 12:38:17 2000
***************
*** 2,6 ****
  MAN1=grohtml.n
  XLIBS=$(LIBDRIVER) $(LIBGROFF)
  MLIB=$(LIBM)
! OBJS=html.o
! CCSRCS=html.cc
--- 2,6 ----
  MAN1=grohtml.n
  XLIBS=$(LIBDRIVER) $(LIBGROFF)
  MLIB=$(LIBM)
! OBJS=html.o output.o
! CCSRCS=html.cc output.cc
Only in groff-html/grohtml: foo.ppm
Only in groff-html/grohtml: foo2.ppm
Only in groff-html/grohtml: grohtml
diff -r -c groff-cvs/grohtml/grohtml.man groff-html/grohtml/grohtml.man
*** groff-cvs/grohtml/grohtml.man       Tue Dec 21 07:08:23 1999
--- groff-html/grohtml/grohtml.man      Fri Jan 14 13:00:07 2000
***************
*** 28,34 ****
  .SH SYNOPSIS
  .B grohtml
  [
! .B \-atvdgm?
  ] [
  .BI \-F dir
  ] [
--- 28,34 ----
  .SH SYNOPSIS
  .B grohtml
  [
! .B \-atTvdgm?
  ] [
  .BI \-F dir
  ] [
***************
*** 106,111 ****
--- 106,117 ----
  The default in
  .B grohtml
  is that html tables are generated when appropriate.
+ .TP
+ .B \-T
+ forbids
+ .B grohtml
+ from generating images when processing output from tbl.
+ This is useful when simple textual tables are being produced.
  .TP
  .BI \-F dir
  Search the directory
Only in groff-html/grohtml: grohtml.n
diff -r -c groff-cvs/grohtml/html.cc groff-html/grohtml/html.cc
*** groff-cvs/grohtml/html.cc   Sat Jan 15 01:51:39 2000
--- groff-html/grohtml/html.cc  Sat Jan 15 02:02:45 2000
***************
*** 28,33 ****
--- 28,34 ----
  #include "cset.h"
  
  #include "html.h"
+ #include "html_chars.h"
  #include <time.h>
  
  #ifdef HAVE_UNISTD_H
***************
*** 45,50 ****
--- 46,52 ----
  
  #define MAX_TEMP_NAME                1024
  #define MAX_STRING_LENGTH            4096
+ #define MAX_CHAR_SIZE                  50        // maximum length of 
character name
  
  #define Y_FUDGE_MARGIN              +0.83
  #define A4_PAGE_LENGTH              (11.6944-Y_FUDGE_MARGIN)
***************
*** 85,90 ****
--- 87,93 ----
  static int table_on                 =  TRUE;
  static int image_res                = DEFAULT_IMAGE_RES;
  static int debug_table_on           = FALSE;
+ static int table_image_on           =  TRUE;   // default is to create images 
for tbl
  
  static int linewidth = -1;
  
***************
*** 117,123 ****
    }
  }
  
- 
  /*
   *  is_subsection - returns TRUE if a1..a2 is within b1..b2
   */
--- 120,125 ----
***************
*** 128,134 ****
    return( !((a1 < b1) || (a1 > b2) || (a2 < b1) || (a2 > b2)) );
  }
  
- 
  /*
   *  is_intersection - returns TRUE if range a1..a2 intersects with b1..b2
   */
--- 130,135 ----
***************
*** 139,145 ****
    return( ! ((a1 > b2) || (a2 < b1)) );
  }
  
- 
  /*
   *  is_digit - returns TRUE if character, ch, is a digit.
   */
--- 140,145 ----
***************
*** 149,155 ****
    return( (ch >= '0') && (ch <= '9') );
  }
  
- 
  /*
   * more_than_line_break - returns TRUE should v1 and v2 differ by more than
   *                        a simple line break.
--- 149,154 ----
***************
*** 160,166 ****
    return( abs(v1-v2)>size );
  }
  
- 
  /*
   *  the class and methods for styles
   */
--- 159,164 ----
***************
*** 649,662 ****
    if (g->maxh < g->minh) {
      if (debug_on) {
        fprintf(stderr, "assert failed minh > maxh\n"); fflush(stderr);
!       stop();
      }
      g->maxh = g->minh;
    }
    if (g->maxv < g->minv) {
      if (debug_on) {
        fprintf(stderr, "assert failed minv > maxv\n"); fflush(stderr);
!       stop();
      }
      g->maxv = g->minv;
    }
--- 647,660 ----
    if (g->maxh < g->minh) {
      if (debug_on) {
        fprintf(stderr, "assert failed minh > maxh\n"); fflush(stderr);
!       // stop();
      }
      g->maxh = g->minh;
    }
    if (g->maxv < g->minv) {
      if (debug_on) {
        fprintf(stderr, "assert failed minv > maxv\n"); fflush(stderr);
!       // stop();
      }
      g->maxv = g->minv;
    }
***************
*** 787,1001 ****
    }
  }
  
- /*
-  *  the classes and methods for simple_output manipulation
-  */
- 
- simple_output::simple_output(FILE *f, int n)
- : fp(f), col(0), max_line_length(n), need_space(0), fixed_point(0)
- {
- }
- 
- simple_output &simple_output::set_file(FILE *f)
- {
-   fp = f;
-   col = 0;
-   return *this;
- }
- 
- simple_output &simple_output::copy_file(FILE *infp)
- {
-   int c;
-   while ((c = getc(infp)) != EOF)
-     putc(c, fp);
-   return *this;
- }
- 
- simple_output &simple_output::end_line()
- {
-   if (col != 0) {
-     putc('\n', fp);
-     col = 0;
-     need_space = 0;
-   }
-   return *this;
- }
- 
- simple_output &simple_output::special(const char *s)
- {
-   return *this;
- }
- 
- simple_output &simple_output::simple_comment(const char *s)
- {
-   if (col != 0)
-     putc('\n', fp);
-   fputs("<!-- ", fp);
-   fputs(s, fp);
-   fputs(" -->\n", fp);
-   col = 0;
-   need_space = 0;
-   return *this;
- }
- 
- simple_output &simple_output::begin_comment(const char *s)
- {
-   if (col != 0)
-     putc('\n', fp);
-   fputs("<!-- ", fp);
-   fputs(s, fp);
-   col = 5 + strlen(s);
-   return *this;
- }
- 
- simple_output &simple_output::end_comment()
- {
-   if (need_space) {
-     putc(' ', fp);
-   }
-   fputs(" -->\n", fp);
-   col = 0;
-   need_space = 0;
-   return *this;
- }
- 
- simple_output &simple_output::comment_arg(const char *s)
- {
-   int len = strlen(s);
- 
-   if (col + len + 1 > max_line_length) {
-     fputs("\n ", fp);
-     col = 1;
-   }
-   fputs(s, fp);
-   col += len + 1;
-   return *this;
- }
- 
- simple_output &simple_output::set_fixed_point(int n)
- {
-   assert(n >= 0 && n <= 10);
-   fixed_point = n;
-   return *this;
- }
- 
- simple_output &simple_output::put_delimiter(char c)
- {
-   putc(c, fp);
-   col++;
-   need_space = 0;
-   return *this;
- }
- 
- simple_output &simple_output::put_string(const char *s, int n)
- {
-   int i=0;
- 
-   while (i<n) {
-     fputc(s[i], fp);
-     i++;
-   }
-   col += n;
-   return *this;
- }
- 
- simple_output &simple_output::put_translated_string(const char *s)
- {
-   int i=0;
- 
-   while (s[i] != (char)0) {
-     if ((s[i] & 0x7f) == s[i]) {
-       fputc(s[i], fp);
-     }
-     i++;
-   }
-   col += i;
-   return *this;
- }
- 
- simple_output &simple_output::put_string(const char *s)
- {
-   int i=0;
- 
-   while (s[i] != '\0') {
-     fputc(s[i], fp);
-     i++;
-   }
-   col += i;
-   return *this;
- }
- 
- struct html_2_postscript {
-   char *html_char;
-   char *postscript_char;
- };
- 
- static struct html_2_postscript char_conversions[] = {
-   { "+-", "char177" },
-   { "eq", "=" },
-   { "mu", "char215" },
-   { NULL, NULL },
- };
- 
- 
- // this is an aweful hack which attempts to translate html characters onto
- // postscript characters. Can this be done inside the devhtml files?
- //
- // or should we read the devps files and find out the translations?
- //
- 
- simple_output &simple_output::put_translated_char (const char *s)
- {
-   int i=0;
- 
-   while (char_conversions[i].html_char != NULL) {
-     if (strcmp(s, char_conversions[i].html_char) == 0) {
-       put_string(char_conversions[i].postscript_char);
-       return *this;
-     } else {
-       i++;
-     }
-   }
-   put_string(s);
-   return *this;
- }
- 
- simple_output &simple_output::put_number(int n)
- {
-   char buf[1 + INT_DIGITS + 1];
-   sprintf(buf, "%d", n);
-   int len = strlen(buf);
-   put_string(buf, len);
-   need_space = 1;
-   return *this;
- }
- 
- simple_output &simple_output::put_float(double d)
- {
-   char buf[128];
- 
-   sprintf(buf, "%.4f", d);
-   int len = strlen(buf);
-   put_string(buf, len);
-   need_space = 1;
-   return *this;
- }
- 
- 
- simple_output &simple_output::put_symbol(const char *s)
- {
-   int len = strlen(s);
- 
-   if (need_space) {
-     putc(' ', fp);
-     col++;
-   }
-   fputs(s, fp);
-   col += len;
-   need_space = 1;
-   return *this;
- }
- 
  class html_font : public font {
    html_font(const char *);
  public:
--- 785,790 ----
***************
*** 1105,1110 ****
--- 894,900 ----
    int left;       // the start of a word or text
    int right;      // the end of the text and beginning of white space
    int is_used;    // will this this column be used for words or space
+   int right_hits; // count of the number of words touching right position
    int percent;    // what percentage width should we use for this cell?
  };
  
***************
*** 1156,1165 ****
    int                       no_of_columns;     // how many columns are we 
using?
    struct text_defn         *columns;           // left and right margins for 
each column
    int                       vertical_limit;    // the limit of the table
  };
  
  html_table::html_table ()
!   : no_of_columns(0), columns(0), vertical_limit(0)
  {
  }
  
--- 946,956 ----
    int                       no_of_columns;     // how many columns are we 
using?
    struct text_defn         *columns;           // left and right margins for 
each column
    int                       vertical_limit;    // the limit of the table
+   int                       wrap_margin;       // is the current rightmost 
margin able to wrap words?
  };
  
  html_table::html_table ()
!   : no_of_columns(0), columns(0), vertical_limit(0), wrap_margin(0)
  {
  }
  
***************
*** 1176,1193 ****
    int                  space_char_index;
    int                  no_of_printed_pages;
    int                  paper_length;
!   enum                 { SBUF_SIZE = 256 };
    char                 sbuf[SBUF_SIZE];
    int                  sbuf_len;
    int                  sbuf_start_hpos;
    int                  sbuf_vpos;
    int                  sbuf_end_hpos;
-   int                  sbuf_space_width;
-   int                  sbuf_space_count;
-   int                  sbuf_space_diff_count;
-   int                  sbuf_space_code;
    int                  sbuf_kern;
    style                sbuf_style;
    style                output_style;
    int                  output_hpos;
    int                  output_vpos;
--- 967,981 ----
    int                  space_char_index;
    int                  no_of_printed_pages;
    int                  paper_length;
!   enum                 { SBUF_SIZE = 8192 };
    char                 sbuf[SBUF_SIZE];
    int                  sbuf_len;
    int                  sbuf_start_hpos;
    int                  sbuf_vpos;
    int                  sbuf_end_hpos;
    int                  sbuf_kern;
    style                sbuf_style;
+   int                  sbuf_dmark_hpos;
    style                output_style;
    int                  output_hpos;
    int                  output_vpos;
***************
*** 1201,1206 ****
--- 989,995 ----
    int                  page_number;
    title_desc           title;
    header_desc          header;
+   int                  header_indent;
    page                *page_contents;
    html_table           indentation;
    int                  left_margin_indent;
***************
*** 1222,1228 ****
    struct graphic_glob *start_graphic;
    struct text_glob    *start_text;
  
- 
    void  flush_sbuf                    ();
    void  set_style                     (const style &);
    void  set_space_code                (unsigned char c);
--- 1011,1016 ----
***************
*** 1236,1241 ****
--- 1024,1031 ----
    void  terminate_current_font        (void);
    void  flush_font                    (void);
    void  flush_page                    (void);
+   void  add_char_to_sbuf              (unsigned char code);
+   void  add_to_sbuf                   (char code, const char *name);
    void  display_word                  (text_glob *g, int is_to_html);
    void  html_display_word             (text_glob *g);
    void  troff_display_word            (text_glob *g);
***************
*** 1274,1287 ****
    void  write_title                   (int in_head);
    void  find_title                    (void);
    int   is_bold                       (text_glob *g);
!   void  write_header                  (void);
    void  determine_header_level        (void);
    void  build_header                  (text_glob *g);
    void  make_html_indent              (int indent);
    int   is_whole_line_bold            (text_glob *g);
    int   is_a_header                   (text_glob *g);
    int   processed_header              (text_glob *g);
!   void  make_new_image_name           (void);
    void  create_temp_name              (char *name, char *extension);
    void  calculate_region_margins      (region_glob *r);
    void  remove_redundant_regions      (void);
--- 1064,1077 ----
    void  write_title                   (int in_head);
    void  find_title                    (void);
    int   is_bold                       (text_glob *g);
!   void  write_header                  (text_glob *g);
    void  determine_header_level        (void);
    void  build_header                  (text_glob *g);
    void  make_html_indent              (int indent);
    int   is_whole_line_bold            (text_glob *g);
    int   is_a_header                   (text_glob *g);
    int   processed_header              (text_glob *g);
!   void  make_new_image_name           (char *extension);
    void  create_temp_name              (char *name, char *extension);
    void  calculate_region_margins      (region_glob *r);
    void  remove_redundant_regions      (void);
***************
*** 1339,1345 ****
    int   large_enough_gap              (text_defn *last_col);
    int   is_worth_column               (int left, int right);
    int   is_subset_of_columns          (text_defn *a, text_defn *b);
!   void  count_hits                    (text_defn *col);
    int   calculate_min_gap             (text_glob *g);
    int   right_indentation             (struct text_defn *last_guess);
    void  calculate_percentage_width    (text_glob *start);
--- 1129,1136 ----
    int   large_enough_gap              (text_defn *last_col);
    int   is_worth_column               (int left, int right);
    int   is_subset_of_columns          (text_defn *a, text_defn *b);
!   void  count_hits                    (text_defn *col, int no_of_columns, int 
limit);
!   void  count_right_hits              (text_defn *col, int no_of_columns);
    int   calculate_min_gap             (text_glob *g);
    int   right_indentation             (struct text_defn *last_guess);
    void  calculate_percentage_width    (text_glob *start);
***************
*** 1358,1367 ****
    int   is_column_subset              (struct text_defn *cols_1, struct 
text_defn *cols_2);
    int   is_appropriate_to_start_table (struct text_defn *cols_1, struct 
text_defn *cols_2,
                                       struct text_defn *last_guess);
!   int   is_a_column                   (int percent);
    int   right_most_column             (struct text_defn *col);
    int   large_enough_gap_for_two      (struct text_defn *col);
    void  remove_zero_percentage_column (void);
  
    // ADD HERE
  
--- 1149,1173 ----
    int   is_column_subset              (struct text_defn *cols_1, struct 
text_defn *cols_2);
    int   is_appropriate_to_start_table (struct text_defn *cols_1, struct 
text_defn *cols_2,
                                       struct text_defn *last_guess);
!   int   is_a_full_width_column        (void);
    int   right_most_column             (struct text_defn *col);
    int   large_enough_gap_for_two      (struct text_defn *col);
    void  remove_zero_percentage_column (void);
+   void  translate_to_html             (text_glob *g);
+   int   html_knows_about              (char *troff);
+   void  determine_diacritical_mark    (const char *name, const environment 
*env);
+   int   sbuf_continuation             (unsigned char code, const char *name, 
const environment *env, int w);
+   char *remove_last_char_from_sbuf    ();
+   const char *check_diacritical_combination (unsigned char code, const char 
*name);
+   int   seen_backwards_escape         (char *s, int l);
+   int   should_defer_table            (int lines, struct text_glob *start, 
struct text_defn *cols_1);
+   int   is_new_exact_right            (struct text_defn *last_guess, struct 
text_defn *last_cols, struct text_defn *next_cols);
+   void  issue_left_paragraph          (void);
+   void  adjust_margin_percentages     (void);
+   int   total_percentages             (void);
+   int   get_left                      (void);
+   void  can_loose_column              (text_glob *start, struct text_defn 
*last_guess, int limit);
+   int   check_lack_of_hits            (struct text_defn *next_guess, struct 
text_defn *last_guess, text_glob *start, int limit);
  
    // ADD HERE
  
***************
*** 1382,1393 ****
--- 1188,1201 ----
    troff(0, MAX_LINE_LENGTH),
    no_of_printed_pages(0),
    sbuf_len(0),
+   sbuf_dmark_hpos(-1),
    output_hpos(-1),
    output_vpos(-1),
    line_thickness(-1),
    fill(FILL_MAX + 1),
    inside_font_style(0),
    page_number(0),
+   header_indent(-1),
    left_margin_indent(0),
    right_margin_indent(0),
    need_one_newline(0),
***************
*** 1432,1442 ****
--- 1240,1509 ----
    current_paragraph = new html_paragraph(FALSE, FALSE, left_alignment, 0);
  }
  
+ /*
+  *  add_char_to_sbuf - adds a single character to the sbuf.
+  */
+ 
+ void html_printer::add_char_to_sbuf (unsigned char code)
+ {
+   if (sbuf_len < SBUF_SIZE) {
+     sbuf[sbuf_len] = code;
+     sbuf_len++;
+   } else {
+     fatal("need to increase SBUF_SIZE");
+   }
+ }
+ 
+ /*
+  *  add_to_sbuf - adds character code or name to the sbuf.
+  *                It escapes \ with \\
+  *                We need to preserve the name of characters if they exist
+  *                because we may need to send this character to two different
+  *                devices: html and postscript.
+  */
+ 
+ void html_printer::add_to_sbuf (char code, const char *name)
+ {
+   if (name == 0) {
+     if (code == '\\') {
+       add_char_to_sbuf('\\');
+     }
+     add_char_to_sbuf(code);
+   } else {
+     int l=strlen(name);
+     int i=0;
+     
+     add_char_to_sbuf('\\');
+     add_char_to_sbuf('(');
+     while (i<l) {
+       if (name[i] == '\\') {
+       add_char_to_sbuf('\\');
+       }
+       add_char_to_sbuf(name[i]);
+       i++;
+     }
+     add_char_to_sbuf('\\');
+     add_char_to_sbuf(')');
+   }
+ }
+ 
+ int html_printer::sbuf_continuation (unsigned char code, const char *name,
+                                    const environment *env, int w)
+ {
+   if ((sbuf_end_hpos == env->hpos) || (sbuf_dmark_hpos == env->hpos)) {
+     name = check_diacritical_combination(code, name);
+     add_to_sbuf(code, name);
+     determine_diacritical_mark(name, env);
+     sbuf_end_hpos += w + sbuf_kern;
+     return( TRUE );
+   } else {
+     if ((sbuf_len < SBUF_SIZE-1) && (env->hpos >= sbuf_end_hpos) &&
+       ((sbuf_kern == 0) || (sbuf_end_hpos - sbuf_kern != env->hpos))) {
+       /*
+        *  lets see whether a space is needed or not
+        */
+       int space_width = sbuf_style.f->get_space_width(sbuf_style.point_size);
+ 
+       if (env->hpos-sbuf_end_hpos < space_width) {
+       name = check_diacritical_combination(code, name);
+       add_to_sbuf(code, name);
+       determine_diacritical_mark(name, env);
+       sbuf_end_hpos = env->hpos + w;
+       return( TRUE );
+       }
+     } else if ((sbuf_len > 0) && (sbuf_dmark_hpos)) {
+       /*
+        *  check whether the diacritical mark is on the same character
+        */
+       int space_width = sbuf_style.f->get_space_width(sbuf_style.point_size);
+ 
+       if (abs(sbuf_dmark_hpos-env->hpos) < space_width) {
+       name = check_diacritical_combination(code, name);
+       add_to_sbuf(code, name);
+       determine_diacritical_mark(name, env);
+       sbuf_end_hpos = env->hpos + w;
+       return( TRUE );
+       }
+     }
+   }
+   return( FALSE );
+ }
+ 
+ /*
+  *  seen_backwards_escape - returns TRUE if we can see a escape at position 
i..l in s
+  */
+ 
+ int html_printer::seen_backwards_escape (char *s, int l)
+ {
+   /*
+    *  this is tricky so it is broken into components for clarity
+    *  (we let the compiler put in all back into a complex expression)
+    */
+   if ((l>0) && (sbuf[l] == '(') && (sbuf[l-1] == '\\')) {
+     /*
+      *  ok seen '\(' but we must now check for '\\('
+      */
+     if ((l>1) && (sbuf[l-2] == '\\')) {
+       /*
+        *  escaped the escape
+        */
+       return( FALSE );
+     } else {
+       return( TRUE );
+     }
+   } else {
+     return( FALSE );
+   }
+ }
+ 
+ /*
+  *  reverse - return reversed string.
+  */
+ 
+ char *reverse (char *s)
+ {
+   int i=0;
+   int j=strlen(s)-1;
+   char t;
+ 
+   while (i<j) {
+     t = s[i];
+     s[i] = s[j];
+     s[j] = t;
+     i++;
+     j--;
+   }
+   return( s );
+ }
+ 
+ /*
+  *  remove_last_char_from_sbuf - removes the last character from sbuf.
+  */
+ 
+ char *html_printer::remove_last_char_from_sbuf ()
+ {
+   int l=sbuf_len;
+   static char last[MAX_STRING_LENGTH];
+ 
+   if (l>0) {
+     l--;
+     if ((sbuf[l] == ')') && (l>0) && (sbuf[l-1] == '\\')) {
+       /*
+        *  found terminating escape
+        */
+       int i=0;
+ 
+       l -= 2;
+       while ((l>0) && (! seen_backwards_escape(sbuf, l))) {
+       if (sbuf[l] == '\\') {
+         if (sbuf[l-1] == '\\') {
+           last[i] = sbuf[l];
+           i++;
+           l--;
+         }
+       } else {
+         last[i] = sbuf[l];
+         i++;
+       }
+       l--;
+       }
+       last[i] = (char)0;
+       sbuf_len = l;
+       if (seen_backwards_escape(sbuf, l)) {
+       sbuf_len--;
+       }
+       return( reverse(last) );
+     } else {
+       if ((sbuf[l] == '\\') && (l>0) && (sbuf[l-1] == '\\')) {
+       l -= 2;
+       sbuf_len = l;
+       return( "\\" );
+       } else {
+       sbuf_len--;
+       last[0] = sbuf[sbuf_len];
+       last[1] = (char)0;
+       return( last );
+       }
+     }  
+   } else {
+     return( NULL );
+   }
+ }
+ 
+ /*
+  *  check_diacriticial_combination - checks to see whether the character code
+  *                                   if combined with the previous 
diacriticial mark
+  *                                   forms a new character.
+  */
+ 
+ const char *html_printer::check_diacritical_combination (unsigned char code, 
const char *name)
+ {
+   static char troff_char[2];
+ 
+   if ((name == 0) && (sbuf_dmark_hpos >= 0)) {
+     // last character was a diacritical mark
+     char *last = remove_last_char_from_sbuf();
+ 
+     int i=0;
+     int j;
+     
+     while (diacritical_table[i].mark != NULL) {
+       if (strcmp(diacritical_table[i].mark, last) == 0) {
+       j=0;
+       while ((diacritical_table[i].second_troff_char[j] != (char)0) &&
+              (diacritical_table[i].second_troff_char[j] != code)) {
+         j++;
+       }
+       if (diacritical_table[i].second_troff_char[j] == code) {
+         troff_char[0] = diacritical_table[i].translation;
+         troff_char[1] = code;
+         troff_char[2] = (char)0;
+         return( troff_char );
+       }
+       }
+       i++;
+     }
+     add_to_sbuf(last[0], last);
+   }
+   return( name );
+ }
+ 
+ /*
+  *  determine_diacritical_mark - if name is a diacriticial mark the record 
the position.
+  *                                --fixme-- is there a better way of doing 
this
+  *                                this must be done in troff somewhere.
+  */
+ 
+ void html_printer::determine_diacritical_mark (const char *name, const 
environment *env)
+ {
+   if (name != 0) {
+     int i=0;
+ 
+     while (diacritical_table[i].mark != NULL) {
+       if (strcmp(name, diacritical_table[i].mark) == 0) {
+       sbuf_dmark_hpos = env->hpos;
+       return;
+       }
+       i++;
+     }
+   }
+   sbuf_dmark_hpos = -1;
+ }
+ 
+ /*
+  *  set_char - adds a character into the sbuf if it is a continuation with 
the previous
+  *             word otherwise flush the current sbuf and add character anew.
+  */
  
  void html_printer::set_char(int i, font *f, const environment *env, int w, 
const char *name)
  {
    unsigned char code = f->get_code(i);
  
+ #if 0
+   if (code == ' ') {
+     stop();
+   }
+ #endif
    style sty(f, env->size, env->height, env->slant, env->fontno);
    if (sty.slant != 0) {
      if (sty.slant > 80 || sty.slant < -80) {
***************
*** 1455,1526 ****
      sbuf_vpos       = env->vpos;
      sbuf_style      = sty;
      sbuf_kern       = 0;
!     return;
!   }
! 
!   if (sbuf_len > 0) {
!     if (sbuf_len < SBUF_SIZE
!       && sty == sbuf_style
!       && sbuf_vpos == env->vpos) {
!       if (sbuf_end_hpos == env->hpos) {
!       sbuf[sbuf_len++] = code;
!       sbuf_end_hpos += w + sbuf_kern;
!       return;
!       }
!       /* If sbuf_end_hpos - sbuf_kern == env->hpos, we are better off
!        starting a new string. */
!       if (sbuf_len < SBUF_SIZE - 1 && env->hpos >= sbuf_end_hpos
!         && (sbuf_kern == 0 || sbuf_end_hpos - sbuf_kern != env->hpos)) {
!       if (sbuf_space_code < 0) {
! #if 0
!         sbuf_space_code = ' ';
!         sbuf_space_count++;
!         sbuf_space_width = env->hpos - sbuf_end_hpos;
!         sbuf_end_hpos = env->hpos + w + sbuf_kern;
!         sbuf[sbuf_len++] = ' ';
!         sbuf[sbuf_len++] = code;
!         return;
! #endif
!       } else {
!         int diff = env->hpos - sbuf_end_hpos - sbuf_space_width;
!         if (diff == 0) {
!           sbuf_end_hpos = env->hpos + w + sbuf_kern;
!           sbuf[sbuf_len++] = sbuf_space_code;
!           sbuf[sbuf_len++] = code;
!           sbuf_space_count++;
!           if (diff == 1)
!             sbuf_space_diff_count++;
!           else if (diff == -1)
!             sbuf_space_diff_count--;
!           return;
!         }
!       }
!       }
      }
-     flush_sbuf();
    }
-   sbuf_len = 1;
-   sbuf[0] = code;
-   sbuf_end_hpos = env->hpos + w;
-   sbuf_start_hpos = env->hpos;
-   sbuf_vpos = env->vpos;
-   sbuf_style = sty;
-   sbuf_space_code = -1;
-   sbuf_space_width = 0;
-   sbuf_space_count = sbuf_space_diff_count = 0;
-   sbuf_kern = 0;
  }
  
- 
  /*
   *  make_new_image_name - creates a new file name ready for a image file.
   *                        it leaves the extension off.
   */
  
! void html_printer::make_new_image_name (void)
  {
    image_number++;
!   sprintf(image_name, "groff-html-%d-%ld", image_number, (long)getpid());
  }
  
  /*
--- 1522,1559 ----
      sbuf_vpos       = env->vpos;
      sbuf_style      = sty;
      sbuf_kern       = 0;
!   } else {
!     if ((sbuf_len > 0) && (sbuf_len < SBUF_SIZE) && (sty == sbuf_style) &&
!       (sbuf_vpos == env->vpos) && (sbuf_continuation(code, name, env, w))) {
!       return;
!     } else {
!       flush_sbuf();
!       sbuf_len = 0;
!       add_to_sbuf(code, name);
!       determine_diacritical_mark(name, env);
!       sbuf_end_hpos = env->hpos + w;
!       sbuf_start_hpos = env->hpos;
!       sbuf_vpos = env->vpos;
!       sbuf_style = sty;
!       sbuf_kern = 0;
      }
    }
  }
  
  /*
   *  make_new_image_name - creates a new file name ready for a image file.
   *                        it leaves the extension off.
   */
  
! void html_printer::make_new_image_name (char *extension)
  {
    image_number++;
!   if ((strcmp(current_filename, "<standard input>") == 0) ||
!       (strcmp(extension, "troff") == 0)) {
!     sprintf(image_name, "grohtml-%d-%ld", image_number, (long)getpid());
!   } else {
!     sprintf(image_name, "%s-%d", current_filename, image_number);
!   }
  }
  
  /*
***************
*** 1543,1548 ****
--- 1576,1677 ----
    }
  }
  
+ /*
+  *  get_html_translation - given the position of the character and its name
+  *                         return the device encoding for such character.
+  */
+ 
+ char *get_html_translation (font *f, char *name)
+ {
+   int  index;
+ 
+   index = f->name_to_index(name);
+   if (index == 0) {
+     error("character `%s' not found", name);
+     return( NULL );
+   } else {
+     return( (char *)f->get_special_device_encoding(index) );
+   }
+ }
+ 
+ /*
+  *  str_translate_to_html - converts a string, str, into html text. It places
+  *                          the output input buffer, buf. It truncates 
string, str, if
+  *                          there is not enough space in buf.
+  */
+ 
+ void str_translate_to_html (font *f, char *buf, int buflen, char *str, int 
len)
+ {
+   int         l;
+   char       *translation;
+   int         e;
+   char        escaped_char[MAX_STRING_LENGTH];
+   int         i=0;
+   int         b=0;
+   int         t=0;
+ 
+ #if 0
+   if (strcmp(str, "\\(\\\\-\\)") == 0) {
+     stop();
+   }
+ #endif
+   while (str[i] != (char)0) {
+     if ((str[i]=='\\') && (i+1<len)) {
+       i++; // skip the leading backslash
+       if (str[i] == '(') {
+       // start of escape
+       i++;
+       e = 0;
+       while ((str[i] != (char)0) &&
+              (! ((str[i] == '\\') && (i+1<len) && (str[i+1] == ')')))) {
+         if (str[i] == '\\') {
+           i++;
+         }
+         escaped_char[e] = str[i];
+         e++;
+         i++;
+       }
+       if ((str[i] == '\\') && (i+1<len) && (str[i+1] == ')')) {
+         i += 2;
+       }
+       escaped_char[e] = (char)0;
+       translation = get_html_translation(f, escaped_char);
+       if (translation) {
+         l = strlen(translation);
+         t = max(0, min(l, buflen-b));
+         strncpy(&buf[b], translation, t);
+         b += t;
+       } else {
+         int index=f->name_to_index(escaped_char);
+         
+         if (index != 0) {
+           buf[b] = f->get_code(index);
+           b++;
+         }
+       }
+       }
+     } else {
+       char name[2];
+ 
+       name[0] = str[i];
+       name[1] = (char)0;
+       translation = get_html_translation(f, name);
+       if (translation) {
+       l = strlen(translation);
+       t = max(0, min(l, buflen-b));
+       strncpy(&buf[b], translation, t);
+       b += t;
+       } else {
+       if (b<buflen) {
+         buf[b] = str[i];
+         b++;
+       }
+       }
+       i++;
+     }
+   }
+   buf[min(b, buflen)] = (char)0;
+ }
  
  /*
   *  find_title - finds a title to this document, if it exists.
***************
*** 1553,1564 ****
    text_glob    *t;
    int           r=font::res;
    int           removed_from_head;
  
    if ((page_number == 1) && (guess_on)) {
      if (! page_contents->words.is_empty()) {
  
        int end_title_hpos     = 0;
-       int start_title_hpos   = 0;
        int start_title_vpos   = 0;
        int found_title_start  = FALSE;
        int height             = 0;
--- 1682,1693 ----
    text_glob    *t;
    int           r=font::res;
    int           removed_from_head;
+   char          buf[MAX_STRING_LENGTH];
  
    if ((page_number == 1) && (guess_on)) {
      if (! page_contents->words.is_empty()) {
  
        int end_title_hpos     = 0;
        int start_title_vpos   = 0;
        int found_title_start  = FALSE;
        int height             = 0;
***************
*** 1587,1597 ****
          return;
        } else if (t->is_raw_command) {
          // skip raw commands
        } else if ((!found_title_start) && (t->minh > left_margin_indent) &&
                   ((start_region == -1) || (t->maxv < start_region))) {
          start_title_vpos     = t->minv;
          end_title_hpos       = t->minh;
!         strcpy((char *)title.text, (char *)t->text_string);
          height               = t->text_style.point_size*r/72;
          found_title_start    = TRUE;
          page_contents->words.sub_move_right();
--- 1716,1728 ----
          return;
        } else if (t->is_raw_command) {
          // skip raw commands
+         page_contents->words.move_right();      // move onto next word
        } else if ((!found_title_start) && (t->minh > left_margin_indent) &&
                   ((start_region == -1) || (t->maxv < start_region))) {
          start_title_vpos     = t->minv;
          end_title_hpos       = t->minh;
!         str_translate_to_html(t->text_style.f, buf, MAX_STRING_LENGTH, 
t->text_string, t->text_length);
!         strcpy((char *)title.text, buf);
          height               = t->text_style.point_size*r/72;
          found_title_start    = TRUE;
          page_contents->words.sub_move_right();
***************
*** 1605,1611 ****
            start_title_vpos = min(t->minv, start_title_vpos);
            end_title_hpos   = max(t->maxh, end_title_hpos);
            strcat(title.text, " ");
!           strcat(title.text, (char *)t->text_string);
            page_contents->words.sub_move_right();
            removed_from_head = ((!page_contents->words.is_empty()) &&
                                 (page_contents->words.is_equal_to_head()));
--- 1736,1743 ----
            start_title_vpos = min(t->minv, start_title_vpos);
            end_title_hpos   = max(t->maxh, end_title_hpos);
            strcat(title.text, " ");
!           str_translate_to_html(t->text_style.f, buf, MAX_STRING_LENGTH, 
t->text_string, t->text_length);
!           strcat(title.text, buf);
            page_contents->words.sub_move_right();
            removed_from_head = ((!page_contents->words.is_empty()) &&
                                 (page_contents->words.is_equal_to_head()));
***************
*** 1614,1620 ****
            title.has_been_found = TRUE;
            return;
          }
!       } else if (t->minh == left_margin_indent) {
          // no margin exists
          return;
        } else {
--- 1746,1752 ----
            title.has_been_found = TRUE;
            return;
          }
!       } else if (t->minh <= left_margin_indent) {
          // no margin exists
          return;
        } else {
***************
*** 1646,1651 ****
--- 1778,1799 ----
  }
  
  /*
+  *  issue_left_paragraph - emits a left paragraph together with appropriate
+  *                         margin if header_indent is < left_margin_indent.
+  */
+ 
+ void html_printer::issue_left_paragraph (void)
+ {
+   if ((header_indent < left_margin_indent) && (! using_table_for_indent())) {
+     html.put_string("<p style=\"margin-left: ");
+     
html.put_number(((left_margin_indent-header_indent)*100)/(right_margin_indent-header_indent));
+     html.put_string("%\">");
+   } else {
+     html.put_string("<p>");
+   }
+ }
+ 
+ /*
   *  force_begin_paragraph - force the begin_paragraph to be emitted.
   */
  
***************
*** 1654,1660 ****
    if (current_paragraph->in_paragraph && current_paragraph->need_paragraph) {
      switch (current_paragraph->para_type) {
  
!     case left_alignment:   html.put_string("<p>");
                             break;
      case center_alignment: html.put_string("<p align=center>");
                             break;
--- 1802,1808 ----
    if (current_paragraph->in_paragraph && current_paragraph->need_paragraph) {
      switch (current_paragraph->para_type) {
  
!     case left_alignment:   issue_left_paragraph();
                             break;
      case center_alignment: html.put_string("<p align=center>");
                             break;
***************
*** 1716,1724 ****
        int height   = output_style.point_size*r/72;
  
        output_vpos += height;
        html.put_string("</p>\n");
      }
-     terminate_current_font();
      current_paragraph->para_type    = left_alignment;
      current_paragraph->in_paragraph = FALSE;
    }
--- 1864,1874 ----
        int height   = output_style.point_size*r/72;
  
        output_vpos += height;
+       terminate_current_font();
        html.put_string("</p>\n");
+     } else {
+       terminate_current_font();
      }
      current_paragraph->para_type    = left_alignment;
      current_paragraph->in_paragraph = FALSE;
    }
***************
*** 1770,1776 ****
  
      if (! page_contents->words.is_empty()) {
  
!       // firstly check the words right margin
  
        page_contents->words.start_from_head();
        do {
--- 1920,1926 ----
  
      if (! page_contents->words.is_empty()) {
  
!       // firstly check the words to determine the right margin
  
        page_contents->words.start_from_head();
        do {
***************
*** 1788,1837 ****
      /*
       *  only examine graphics if no words present
       */
!       if (! page_contents->lines.is_empty()) {
!       // now check for diagrams for right margin
!       page_contents->lines.start_from_head();
!       do {
!         g = page_contents->lines.get_data();
!         if ((g->maxh >= 0) && (g->maxh > right_margin_indent)) {
!           right_margin_indent = g->maxh;
  #if 0
!           if (right_margin_indent == 950) stop();
  #endif
!         }
!         page_contents->lines.move_right();
!       } while (! page_contents->lines.is_equal_to_head());
!       }
  
!     // now we know the right margin lets do the same to find left margin
  
      left_margin_indent  = right_margin_indent;
! 
      if (! page_contents->words.is_empty()) {
        do {
        w = page_contents->words.get_data();
        if ((w->minh >= 0) && (w->minh < left_margin_indent)) {
!         left_margin_indent = w->minh;
        }
        page_contents->words.move_right();
        } while (! page_contents->words.is_equal_to_head());
      }
  
!       /*
!        *  only examine graphic for margins if text yields nothing
!        */
! 
!       if (! page_contents->lines.is_empty()) {
!       // now check for diagrams
!       page_contents->lines.start_from_head();
!       do {
!         g = page_contents->lines.get_data();
!         if ((g->minh >= 0) && (g->minh < left_margin_indent)) {
!           left_margin_indent = g->minh;
!         }
!         page_contents->lines.move_right();
!       } while (! page_contents->lines.is_equal_to_head());
!       }
    }
  }
  
--- 1938,1994 ----
      /*
       *  only examine graphics if no words present
       */
!     if (! page_contents->lines.is_empty()) {
!       // now check for diagrams for right margin
!       page_contents->lines.start_from_head();
!       do {
!       g = page_contents->lines.get_data();
!       if ((g->maxh >= 0) && (g->maxh > right_margin_indent)) {
!         right_margin_indent = g->maxh;
  #if 0
!         if (right_margin_indent == 950) stop();
  #endif
!       }
!       page_contents->lines.move_right();
!       } while (! page_contents->lines.is_equal_to_head());
!     }
  
!     /*
!      *  now we know the right margin lets do the same to find left margin
!      */
  
+     if (header_indent == -1) {
+       header_indent     = right_margin_indent;
+     }
      left_margin_indent  = right_margin_indent;
!     
      if (! page_contents->words.is_empty()) {
        do {
        w = page_contents->words.get_data();
        if ((w->minh >= 0) && (w->minh < left_margin_indent)) {
!         if (! is_a_header(w) && (! w->is_raw_command)) {
!           left_margin_indent = w->minh;
!         }
        }
        page_contents->words.move_right();
        } while (! page_contents->words.is_equal_to_head());
      }
  
!     /*
!      *  only examine graphic for margins if text yields nothing
!      */
!     
!     if (! page_contents->lines.is_empty()) {
!       // now check for diagrams
!       page_contents->lines.start_from_head();
!       do {
!       g = page_contents->lines.get_data();
!       if ((g->minh >= 0) && (g->minh < left_margin_indent)) {
!         left_margin_indent = g->minh;
!       }
!       page_contents->lines.move_right();
!       } while (! page_contents->lines.is_equal_to_head());
!     }
    }
  }
  
***************
*** 2267,2272 ****
--- 2424,2438 ----
            
(end_region_hpos-start_region_hpos)*image_res/font::res+IMAGE_BOARDER_PIXELS,
            
(end_region_vpos-start_region_vpos)*image_res/font::res+IMAGE_BOARDER_PIXELS,
            name, image_name);
+ #if 0
+     sprintf(buffer,
+           "echo showpage | gs -q -dSAFER -sDEVICE=ppmraw -r%d -g%dx%d 
-sOutputFile=- %s.ps - > %s.pnm ; pnmtopng -transparent white %s.pnm > %s.png 
\n",
+           /* image_device, */
+           image_res,
+           
(end_region_hpos-start_region_hpos)*image_res/font::res+IMAGE_BOARDER_PIXELS,
+           
(end_region_vpos-start_region_vpos)*image_res/font::res+IMAGE_BOARDER_PIXELS,
+           name, name, name, image_name);
+ #endif
    }
    if (debug_on) {
      fprintf(stderr, "%s", buffer);
***************
*** 2289,2295 ****
  
  void html_printer::create_temp_name (char *name, char *extension)
  {
!   make_new_image_name();
    sprintf(name, "/tmp/%s.%s", image_name, extension);
  }
  
--- 2455,2461 ----
  
  void html_printer::create_temp_name (char *name, char *extension)
  {
!   make_new_image_name(extension);
    sprintf(name, "/tmp/%s.%s", image_name, extension);
  }
  
***************
*** 2381,2391 ****
        convert_to_image(name);
  
        if (is_center) {
        begin_paragraph(center_alignment);
!       } else {
!       begin_paragraph(left_alignment);
        }
-       force_begin_paragraph();
        html.put_string("<img src=\"");
        html.put_string(image_name);
        if (image_type == gif) {
--- 2547,2556 ----
        convert_to_image(name);
  
        if (is_center) {
+       end_paragraph();
        begin_paragraph(center_alignment);
!       force_begin_paragraph();
        }
        html.put_string("<img src=\"");
        html.put_string(image_name);
        if (image_type == gif) {
***************
*** 2393,2409 ****
        } else {
        html.put_string(".png\"");
        }
-       if (is_center) {
-       html.put_string(" align=\"middle\"");
-       }
        html.put_string(">\n");
        html_newline();
!       end_paragraph();
  
        output_vpos      = end_region_vpos;
        output_hpos      = 0;
        need_one_newline = FALSE;
        output_style.f   = 0;
      }
      // unlink(name);  // remove troff file
    }
--- 2558,2574 ----
        } else {
        html.put_string(".png\"");
        }
        html.put_string(">\n");
        html_newline();
!       if (is_center) {
!       end_paragraph();
!       }
  
        output_vpos      = end_region_vpos;
        output_hpos      = 0;
        need_one_newline = FALSE;
        output_style.f   = 0;
+       end_paragraph();
      }
      // unlink(name);  // remove troff file
    }
***************
*** 2413,2419 ****
  {
    calculate_margin();
    output_vpos     = -1;
!   output_hpos     = left_margin_indent;
    supress_sub_sup = TRUE;
  #if 0
    dump_page();
--- 2578,2584 ----
  {
    calculate_margin();
    output_vpos     = -1;
!   output_hpos     = get_left();
    supress_sub_sup = TRUE;
  #if 0
    dump_page();
***************
*** 2497,2510 ****
        write_html_font_type(oldfontname, "</", ">");
      }
    }
!   if (fontname != 0) {
      // now emit the size if it has changed
!     if (((output_style.f == 0) || (output_style.point_size != size)) && (size 
!= 0)) {
!       sprintf(buffer, "<font size=%d>", convertSizeToHTML(size));
!       html.put_string(buffer);
!       output_style.point_size = size;  // and remember the size
!     }
  
      if (! g->is_raw_command) {
        // now emit the new font
        write_html_font_face(fontname, "<", ">");
--- 2662,2683 ----
        write_html_font_type(oldfontname, "</", ">");
      }
    }
! 
!   if ((output_style.point_size != size) && (output_style.point_size != 0)) {
!     // shutdown the previous font size
!     html.put_string("</font>");
!   }
! 
!   if ((output_style.point_size != size) && (size != 0)) {
      // now emit the size if it has changed
!     sprintf(buffer, "<font size=%d>", convertSizeToHTML(size));
!     html.put_string(buffer);
!     output_style.point_size = size;  // and remember the size
!   }
!   output_style.f = 0;                // no style at present
!   output_style.point_size = size;    // remember current font size
  
+   if (fontname != 0) {
      if (! g->is_raw_command) {
        // now emit the new font
        write_html_font_face(fontname, "<", ">");
***************
*** 2514,2521 ****
  
        output_style = g->text_style;  // remember style for next time
      }
-   } else {
-     output_style.f = 0;   // no style at present
    }
  }
  
--- 2687,2692 ----
***************
*** 2585,2591 ****
    html_change_font(&g, 0, 0);   
  }
  
! void html_printer::write_header (void)
  {
    if (strlen(header.header_buffer) > 0) {
      if (header.header_level > 7) {
--- 2756,2762 ----
    html_change_font(&g, 0, 0);   
  }
  
! void html_printer::write_header (text_glob *g)
  {
    if (strlen(header.header_buffer) > 0) {
      if (header.header_level > 7) {
***************
*** 2606,2621 ****
  
        header.no_of_headings++;
  
!       text_glob *g=new text_glob(&st,
                                 
header.headings.add_string(header.header_buffer, strlen(header.header_buffer)),
                                 strlen(header.header_buffer),
                                 header.no_of_headings, header.header_level,
                                 header.no_of_headings, header.header_level,
                                 FALSE, FALSE);
!       header.headers.add(g);   // and add this header to the header list
      }
  
-     end_paragraph();
      // and now we issue the real header
      html.put_string("<h");
      html.put_number(header.header_level);
--- 2777,2800 ----
  
        header.no_of_headings++;
  
!       text_glob *h=new text_glob(&st,
                                 
header.headings.add_string(header.header_buffer, strlen(header.header_buffer)),
                                 strlen(header.header_buffer),
                                 header.no_of_headings, header.header_level,
                                 header.no_of_headings, header.header_level,
                                 FALSE, FALSE);
!       header.headers.add(h);   // and add this header to the header list
!     } else {
!       terminate_current_font();
!       end_paragraph();
!     }
! 
!     // we adjust the margin if necessary
! 
!     if (g->minh < left_margin_indent) {
!       header_indent = g->minh;
      }
  
      // and now we issue the real header
      html.put_string("<h");
      html.put_number(header.header_level);
***************
*** 2624,2629 ****
--- 2803,2809 ----
      html.put_string("</h");
      html.put_number(header.header_level);
      html.put_string(">");
+ 
      need_one_newline = FALSE;
      begin_paragraph(left_alignment);
      header.written_header = TRUE;
***************
*** 2631,2636 ****
--- 2811,2829 ----
  }
  
  /*
+  *  translate_str_to_html - translates a string, str, into html 
representation.
+  *                          len indicates the string length.
+  */
+ 
+ void translate_str_to_html (font *f, char *str, int len)
+ {
+   char buf[MAX_STRING_LENGTH];
+ 
+   str_translate_to_html(f, buf, MAX_STRING_LENGTH, str, len);
+   strncpy(str, buf, max(len, strlen(buf)+1));
+ }
+ 
+ /*
   *  write_headings - emits a list of links for the headings in this document
   */
  
***************
*** 2669,2680 ****
  {
    text_glob *l;
    int current_vpos;
  
    strcpy(header.header_buffer, "");
    do {
      l = g;
      current_vpos = g->minv;
!     strcat(header.header_buffer, (char *)g->text_string);
      page_contents->words.move_right();
      g = page_contents->words.get_data();
      if (g->minv == current_vpos) {
--- 2862,2875 ----
  {
    text_glob *l;
    int current_vpos;
+   char buf[MAX_STRING_LENGTH];
  
    strcpy(header.header_buffer, "");
    do {
      l = g;
      current_vpos = g->minv;
!     str_translate_to_html(g->text_style.f, buf, MAX_STRING_LENGTH, 
g->text_string, g->text_length);
!     strcat(header.header_buffer, (char *)buf);
      page_contents->words.move_right();
      g = page_contents->words.get_data();
      if (g->minv == current_vpos) {
***************
*** 2758,2767 ****
  
  int html_printer::processed_header (text_glob *g)
  {
!   if ((guess_on) && (g->minh == left_margin_indent) && (! 
using_table_for_indent()) &&
        (is_a_header(g))) {
      build_header(g);
!     write_header();
      return( TRUE );
    } else {
      return( FALSE );
--- 2953,2962 ----
  
  int html_printer::processed_header (text_glob *g)
  {
!   if ((guess_on) && (g->minh <= left_margin_indent) && (! 
using_table_for_indent()) &&
        (is_a_header(g))) {
      build_header(g);
!     write_header(g);
      return( TRUE );
    } else {
      return( FALSE );
***************
*** 2816,2822 ****
     *             (output_style.point_size > g->text_style.point_size)) );
     */
  
!   return( (! supress_sub_sup) && (output_vpos+height < g->maxv) );
  }
  
  /*
--- 3011,3017 ----
     *             (output_style.point_size > g->text_style.point_size)) );
     */
  
!   return( (output_style.point_size != 0) && (! supress_sub_sup) && 
(output_vpos+height < g->maxv) );
  }
  
  /*
***************
*** 2833,2839 ****
   *        (output_style.point_size > g->text_style.point_size)));
   */
  
!   return( (! supress_sub_sup) && (output_vpos+height > g->maxv) );
  }
  
  /*
--- 3028,3034 ----
   *        (output_style.point_size > g->text_style.point_size)));
   */
  
!   return( (output_style.point_size != 0) && (! supress_sub_sup) && 
(output_vpos+height > g->maxv) );
  }
  
  /*
***************
*** 2873,2891 ****
  int html_printer::pretend_is_on_same_line (text_glob *g, int left_margin, int 
right_margin)
  {
    return( auto_on && (right_margin == output_hpos) && (left_margin == 
g->minh) &&
!         (right_margin != g->maxh) && ((! is_whole_line_bold(g)) || 
(g->text_style.f == output_style.f)) );
  }
  
  int html_printer::is_on_same_line (text_glob *g, int vpos)
  {
    if (g->is_html_command) {
      stop();
    }
    return(
         (vpos >= 0) &&
         (is_intersection(vpos, vpos+g->text_style.point_size*font::res/72-1, 
g->minv, g->maxv))
         );
-   // was && ((is_intersection(vpos, vpos, g->minv, g->maxv) && 
(g->is_raw_command))))
  }
  
  
--- 3068,3088 ----
  int html_printer::pretend_is_on_same_line (text_glob *g, int left_margin, int 
right_margin)
  {
    return( auto_on && (right_margin == output_hpos) && (left_margin == 
g->minh) &&
!         (right_margin != g->maxh) && ((! is_whole_line_bold(g)) || 
(g->text_style.f == output_style.f)) &&
!         (! (using_table_for_indent()) || (indentation.wrap_margin)) );
  }
  
  int html_printer::is_on_same_line (text_glob *g, int vpos)
  {
+ #if 0
    if (g->is_html_command) {
      stop();
    }
+ #endif
    return(
         (vpos >= 0) &&
         (is_intersection(vpos, vpos+g->text_style.point_size*font::res/72-1, 
g->minv, g->maxv))
         );
  }
  
  
***************
*** 2895,2903 ****
  
  void html_printer::make_html_indent (int indent)
  {
!   html.put_string("<span style=\" text-indent: ");
!   
html.put_float(((double)(indent*100)/((double)(right_margin_indent-left_margin_indent))));
!   html.put_string("%;\"></span>");
  }
  
  /*
--- 3092,3102 ----
  
  void html_printer::make_html_indent (int indent)
  {
!   if (indent > 0) {
!     html.put_string("<span style=\" text-indent: ");
!     html.put_number((indent*100)/(right_margin_indent-get_left()));
!     html.put_string("%;\"></span>");
!   }
  }
  
  /*
***************
*** 2917,2923 ****
  
  int html_printer::calculate_min_gap (text_glob *g)
  {
!   return( 
g->text_style.f->get_space_width(g->text_style.point_size)*GAP_SPACES );
  }
  
  /*
--- 3116,3134 ----
  
  int html_printer::calculate_min_gap (text_glob *g)
  {
!   text_glob *t = g;
! 
!   while ((t->is_raw_command) && (! page_contents->words.is_equal_to_tail()) &&
!        ((t->minv < end_region_vpos) || (end_region_vpos < 0))) {
!     page_contents->words.move_right();
!     t=page_contents->words.get_data();
!   }
!   rewind_text_to(g);
!   if (t->is_raw_command) {
!     return( font::res * 10 );  // impossibly large gap width
!   } else {
!     return( 
t->text_style.f->get_space_width(t->text_style.point_size)*GAP_SPACES );
!   }
  }
  
  /*
***************
*** 2948,2954 ****
    if (start != 0) {
      int graphic_limit = end_region_vpos;
  
!     if (is_whole_line_bold(t) && (t->minh == left_margin_indent)) {
        /*
         *  found header therefore terminate indentation table.
         *  Return a negative number so we know a header has
--- 3159,3165 ----
    if (start != 0) {
      int graphic_limit = end_region_vpos;
  
!     if (is_whole_line_bold(t) && (t->minh <= left_margin_indent)) {
        /*
         *  found header therefore terminate indentation table.
         *  Return a negative number so we know a header has
***************
*** 3054,3059 ****
--- 3265,3271 ----
  
        remove_redundant_columns(next_cols);
  
+ #if 0
        for (k=0; k<count_columns(next_cols); k++) {
        if (next_cols[k].left > next_cols[k].right) {
          fprintf(stderr, "left > right\n"); fflush(stderr);
***************
*** 3066,3071 ****
--- 3278,3284 ----
          fatal("next_cols has messed up columns");
        }
        }
+ #endif
      }
    }
    return( upper_limit );
***************
*** 3320,3330 ****
        j++;
      }
    }
!   calculate_right(match, max_words);
!   return( found );
  }
  
- 
  /*
   *  remove_white_using_words - remove white space in, last_guess, by 
examining, next_line
   *                             placing results into next_guess.
--- 3533,3583 ----
        j++;
      }
    }
!   calculate_right(match, max_words);
!   return( found );
! }
! 
! /*
!  *  check_lack_of_hits - returns TRUE if a column has been moved to a position
!  *                       of only one hit from a position of more than one hit.
!  */
! 
! int html_printer::check_lack_of_hits (struct text_defn *next_guess,
!                                     struct text_defn *last_guess,
!                                     text_glob *start, int limit)
! {
!   text_glob *current=page_contents->words.get_data();
!   int              n=count_columns(last_guess);
!   int              m=count_columns(next_guess);
!   int           i, j;
! 
!   if (limit > 0) {
!     rewind_text_to(start);
!     count_hits(last_guess, n, limit);
!     rewind_text_to(current);
!     i=0;
!     j=0;
!     while ((i<n) && (j<m) &&
!          (last_guess[i].left != 0) && (next_guess[j].left != 0)) {
!       if ((is_intersection(last_guess[i].left, last_guess[i].right,
!                          next_guess[j].left, next_guess[j].right)) &&
!         (next_guess[j].left < last_guess[i].left) &&
!         (last_guess[i].is_used >= 2)) {
!       /*
!        *  next_guess has to be = 1 as this position is new
!        */
!       return( TRUE );
!       }
!       if (last_guess[i].left < next_guess[j].left) {
!       i++;
!       } else {
!       j++;
!       }
!     }
!   }
!   return( FALSE );
  }
  
  /*
   *  remove_white_using_words - remove white space in, last_guess, by 
examining, next_line
   *                             placing results into next_guess.
***************
*** 3374,3379 ****
--- 3627,3638 ----
        }
      }
    }
+   while (next_line[k].left != 0) {
+     next_guess[i].left  = next_line[k].left;
+     next_guess[i].right = next_line[k].right;
+     i++;
+     k++;
+   }
    if (i<MAX_WORDS_PER_LINE) {
      next_guess[i].left  = 0;
      next_guess[i].right = 0;
***************
*** 3420,3425 ****
--- 3679,3713 ----
  }
  
  /*
+  *  can_loose_column - checks to see whether we should combine two columns.
+  *                     This is allowed if there are is only one hit on the
+  *                     left hand edge and the previous column is very close.
+  */
+ 
+ void html_printer::can_loose_column (text_glob *start, struct text_defn 
*last_guess, int limit)
+ {
+   text_glob *current=page_contents->words.get_data();
+   int              n=count_columns(last_guess);
+   int              i;
+ 
+   rewind_text_to(start);
+   count_hits(last_guess, n, limit);
+   i=0;
+   while (i<n-1) {
+     if ((last_guess[i+1].is_used == 1) &&
+       (calculate_min_gap(start) > 
(last_guess[i+1].left-last_guess[i].right))) {
+       last_guess[i].right = last_guess[i+1].right;
+       remove_entry_in_line(last_guess, i+1);
+       n = count_columns(last_guess);
+       i = 0;
+     } else {
+       i++;
+     }
+   }
+   rewind_text_to(current);
+ }
+ 
+ /*
   *  display_columns - a long overdue debugging function, as this column code 
is causing me grief :-(
   */
  
***************
*** 3429,3435 ****
  
    fprintf(stderr, "[%s:%s]", name, word);
    while (line[i].left != 0) {
!     fprintf(stderr, " <left=%d right=%d> ", line[i].left, line[i].right);
      i++;
    }
    fprintf(stderr, "\n");
--- 3717,3723 ----
  
    fprintf(stderr, "[%s:%s]", name, word);
    while (line[i].left != 0) {
!     fprintf(stderr, " <left=%d right=%d %d%%> ", line[i].left, line[i].right, 
line[i].percent);
      i++;
    }
    fprintf(stderr, "\n");
***************
*** 3464,3472 ****
    struct text_defn t;
  
    // firstly lets see whether we need an initial column on the left hand side
!   if ((line[0].left != left_margin_indent) && (line[0].left != 0) &&
!       (left_margin_indent < line[0].left) && 
(is_worth_column(left_margin_indent, line[0].left))) {
!     t.left  = left_margin_indent;
      t.right = line[0].left;
      include_into_list(line, &t);
    }
--- 3752,3760 ----
    struct text_defn t;
  
    // firstly lets see whether we need an initial column on the left hand side
!   if ((line[0].left != get_left()) && (line[0].left != 0) &&
!       (get_left() < line[0].left) && (is_worth_column(get_left(), 
line[0].left))) {
!     t.left  = get_left();
      t.right = line[0].left;
      include_into_list(line, &t);
    }
***************
*** 3623,3650 ****
  }
  
  /*
!  *  count_hits - counts the number of hits per column. A hit is when the
!  *               left hand position of a glob hits the left hand column.
   */
  
! void html_printer::count_hits (text_defn *col)
  {
    int        i;
    text_glob *start = page_contents->words.get_data();
    text_glob *g     = start;
-   int        r     = font::res;
-   int        gap   = r/GAP_WIDTH_ONE_LINE;
-   int        n     = count_columns(col);
-   int        left;
  
    // firstly reset the used field
!   for (i=0; i<n; i++) {
!     col[i].is_used = 0;
    }
    // now calculate the left hand hits
!   while ((g != 0) && (g->minv <= indentation.vertical_limit)) {
      i=0;
!     while ((col[i].left < g->minh) && (col[i].left != 0)) {
        i++;
      }
      if ((col[i].left == g->minh) && (col[i].left != 0)) {
--- 3911,3935 ----
  }
  
  /*
!  *  count_hits - counts the number of hits per column. A left hit
!  *               is when the left hand position of a glob hits
!  *               the left hand column.
   */
  
! void html_printer::count_hits (text_defn *col, int no_of_columns, int limit)
  {
    int        i;
    text_glob *start = page_contents->words.get_data();
    text_glob *g     = start;
  
    // firstly reset the used field
!   for (i=0; i<no_of_columns; i++) {
!     col[i].is_used   = 0;
    }
    // now calculate the left hand hits
!   while ((g != 0) && (g->minv <= limit)) {
      i=0;
!     while ((i<no_of_columns) && (col[i].right < g->minh)) {
        i++;
      }
      if ((col[i].left == g->minh) && (col[i].left != 0)) {
***************
*** 3658,3682 ****
        g=page_contents->words.get_data();
      }
    }
!   // now remove any column which is less than the
!   // minimal gap for one hit.
!   // column 0 is excempt
! 
!   left = col[0].left;
!   i=1;
!   while (i<count_columns(col)) {
!     if (col[i].is_used == 1) {
!       if (col[i].left - left < gap) {
!       col[i-1].right = col[i].right;
!       remove_entry_in_line(col, i);
!       left = col[i].left;
!       } else {
!       left = col[i].left;
!       i++;
        }
      } else {
!       left = col[i].left;
!       i++;
      }
    }
  }
--- 3943,3986 ----
        g=page_contents->words.get_data();
      }
    }
! }
! 
! /*
!  *  count_right_hits - counts the number of right hits per column.
!  *                     A right hit is when the left hand position
!  *                     of a glob hits the right hand column.
!  */
! 
! void html_printer::count_right_hits (text_defn *col, int no_of_columns)
! {
!   int        i;
!   text_glob *start = page_contents->words.get_data();
!   text_glob *g     = start;
! 
!   // firstly reset the used field
!   for (i=0; i<no_of_columns; i++) {
!     col[i].right_hits = 0;
!   }
!   // now calculate the left hand hits
!   while ((g != 0) && (g->minv <= indentation.vertical_limit)) {
!     i=0;
!     while ((i<no_of_columns) && (col[i].right < g->minh)) {
!       i++;
!     }
!     if ((i<no_of_columns) && (col[i].right == g->maxh)) {
!       if (debug_table_on) {
!       fprintf(stderr, "found right hit [%s] at %d in %d\n",
!               g->text_string, g->maxh, i);
!       fflush(stderr);
        }
+       col[i].right_hits++;
+     }
+     page_contents->words.move_right();
+     if (page_contents->words.is_equal_to_head()) {
+       g = 0;
+       page_contents->words.start_from_tail();
      } else {
!       g=page_contents->words.get_data();
      }
    }
  }
***************
*** 3745,3758 ****
  
  void html_printer::utilize_round_off (void)
  {
!   int total = 0;
    int excess, i;
  
    // use up the spare excess
!   for (i=0; i<indentation.no_of_columns; i++) {
!     total += indentation.columns[i].percent;
!   }
    excess = 100-total;
    for (i=0; (i<indentation.no_of_columns) && (excess>0); i++) {
      if ((indentation.columns[i].is_used) &&
        (indentation.columns[i].percent < PERCENT_THRESHOLD)) {
--- 4049,4061 ----
  
  void html_printer::utilize_round_off (void)
  {
!   int total = total_percentages();
    int excess, i;
  
    // use up the spare excess
! 
    excess = 100-total;
+ 
    for (i=0; (i<indentation.no_of_columns) && (excess>0); i++) {
      if ((indentation.columns[i].is_used) &&
        (indentation.columns[i].percent < PERCENT_THRESHOLD)) {
***************
*** 3883,3894 ****
--- 4186,4200 ----
  
  int html_printer::will_wrap_text (int i, text_glob *start)
  {
+   text_glob *current=page_contents->words.get_data();
+ 
    if (auto_on) {
      rewind_text_to(start);
      while ((start != 0) && (start->minv < indentation.vertical_limit)) {
        if (indentation.columns[i].right == start->maxh) {
        // ok right word is on column boarder - check next line
        if (next_line_on_left_column(i, start)) {
+         rewind_text_to(current);
          return( TRUE );
        }
        }
***************
*** 3900,3905 ****
--- 4206,4212 ----
        }
      }
    }
+   rewind_text_to(current);
    return( FALSE );
  }
  
***************
*** 3912,3917 ****
--- 4219,4226 ----
  void html_printer::remove_unnecessary_unused (text_glob *start)
  {
    int i=0;
+   int left=get_left();
+   int right;
  
    while (i<indentation.no_of_columns) {
      if ((indentation.columns[i].is_used) &&
***************
*** 3922,3928 ****
         *  This can only be done if column, i, is not wrapping text.
         */
        if (! will_wrap_text(i, start)) {
!       indentation.columns[i].percent += indentation.columns[i+1].percent;
        remove_table_column(i+1);
        i=-1;
        }
--- 4231,4248 ----
         *  This can only be done if column, i, is not wrapping text.
         */
        if (! will_wrap_text(i, start)) {
! #if 1
!       if (i+1 < indentation.no_of_columns) {
!         right = indentation.columns[i+1].right;
!       } else {
!         right = right_margin_indent;
!       }
!       indentation.columns[i].percent = (((right - 
indentation.columns[i].left) * 100) /
!                                         (right_margin_indent-left));
! #else
!       indentation.columns[i].percent = (((indentation.columns[i+1].right - 
indentation.columns[i].left) * 100) /
!                                         (right_margin_indent-left));
! #endif
        remove_table_column(i+1);
        i=-1;
        }
***************
*** 3950,3955 ****
--- 4270,4288 ----
  }
  
  /*
+  *  get_left - returns the actual left most margin.
+  */
+ 
+ int html_printer::get_left (void)
+ {
+   if ((header_indent < left_margin_indent) && (header_indent != -1)) {
+     return( header_indent );
+   } else {
+     return( left_margin_indent );
+   }
+ }
+ 
+ /*
   *  calculate_percentage_width - calculates the percentage widths,
   *                               this function will be generous to
   *                               columns which have words as some browsers
***************
*** 3963,3977 ****
  void html_printer::calculate_percentage_width (text_glob *start)
  {
    int i;
  
    // firstly calculate raw percentages
    for (i=0; i<indentation.no_of_columns; i++) {
      indentation.columns[i].percent = (((indentation.columns[i].right - 
indentation.columns[i].left) * 100) /
!                                     (right_margin_indent-left_margin_indent));
    }
    // now steal from the unused columns..
    remove_unnecessary_unused(start);
    utilize_round_off();
    remove_zero_percentage_column();
  }
  
--- 4296,4333 ----
  void html_printer::calculate_percentage_width (text_glob *start)
  {
    int i;
+   int left=get_left();
+   int right;
  
    // firstly calculate raw percentages
    for (i=0; i<indentation.no_of_columns; i++) {
+ #if 0
      indentation.columns[i].percent = (((indentation.columns[i].right - 
indentation.columns[i].left) * 100) /
!                                     (right_margin_indent-left));
! #else
!     if (i+1 < indentation.no_of_columns) {
!       right = indentation.columns[i+1].left;
!     } else {
!       right = right_margin_indent;
!     }
!     indentation.columns[i].percent = (((right - indentation.columns[i].left) 
* 100) /
!                                     (right_margin_indent-left));
! #endif
!   }
!   if (debug_table_on) {
!     display_columns(start->text_string, "[b4 steal] indentation.columns", 
indentation.columns);
    }
+ 
    // now steal from the unused columns..
    remove_unnecessary_unused(start);
+ 
+   if (debug_table_on) {
+     display_columns(start->text_string, "[after steal] indentation.columns", 
indentation.columns);
+   }
+ 
+ #if 0
    utilize_round_off();
+ #endif
    remove_zero_percentage_column();
  }
  
***************
*** 4107,4112 ****
--- 4463,4471 ----
    }
  
    if ((count_columns(last_guess)==1) && (right_indentation(last_guess))) {
+     if (lines == 1) {
+       *limit = *limit_1;
+     }
      return( TRUE );
    }
  
***************
*** 4116,4121 ****
--- 4475,4481 ----
  
    if (lines == 1) {
      if (large_enough_gap(last_guess)) {
+       *limit = *limit_1;
        return( TRUE );
      }
    } else if (count_columns(last_guess)>1) {
***************
*** 4159,4173 ****
  }
  
  /*
!  *  is_a_column - returns TRUE if there exists a column with, percent, width.
   */
  
! int html_printer::is_a_column (int percent)
  {
    int i=0;
  
    while (i<indentation.no_of_columns) {
!     if (indentation.columns[i].percent == percent) {
        return( TRUE );
      }
      i++;
--- 4519,4535 ----
  }
  
  /*
!  *  is_a_full_width_column - returns TRUE if there exists a full width column.
   */
  
! int html_printer::is_a_full_width_column (void)
  {
    int i=0;
  
    while (i<indentation.no_of_columns) {
!     if (((indentation.columns[i].left == get_left()) ||
!        (indentation.columns[i].left == left_margin_indent)) &&
!       (indentation.columns[i].right == right_margin_indent)) {
        return( TRUE );
      }
      i++;
***************
*** 4176,4181 ****
--- 4538,4598 ----
  }
  
  /*
+  *  should_defer_table - returns TRUE if we should defer this table.
+  *                       This can occur if the first line seen indent
+  *                       is < than future lines. In which case it
+  *                       will cause future lines in this table
+  *                       to be indented. The lesser of the evils
+  *                       is to treat the first line by itself.
+  */
+ 
+ int html_printer::should_defer_table (int lines, struct text_glob *start, 
struct text_defn *cols_1)
+ {
+   if (lines > 2) {
+     int i=0;
+     int c=count_columns(cols_1);
+ 
+     count_hits(cols_1, count_columns(cols_1), indentation.vertical_limit);
+     rewind_text_to(start);
+     count_right_hits(cols_1, count_columns(cols_1));
+     rewind_text_to(start);
+     while (i<c) {
+       if ((cols_1[i].is_used > 1) || (cols_1[i].right_hits > 1)) {
+       return( FALSE );
+       }
+       i++;
+     }
+     /*
+      *  first line (cols_1) is not aligned on any future column, we defer.
+      */
+     return( TRUE );
+   }
+   return( FALSE );
+ }
+ 
+ /*
+  *  is_new_exact_right - returns TRUE if the, next_cols, has a word sitting
+  *                       on the right hand margin of last_guess. But only
+  *                       if no exact right word was found in last_cols.
+  */
+ 
+ int html_printer::is_new_exact_right (struct text_defn *last_guess,
+                                     struct text_defn *last_cols,
+                                     struct text_defn *next_cols)
+ {
+   int n=count_columns(last_guess)-1;
+   return( FALSE );
+ 
+   if ((n>=0) && (last_guess[n].left != 0) && (last_cols[n].left != 0) && 
(next_cols[n].left != 0)) {
+     if ((last_cols[n].right != last_guess[n].right) &&
+       ((next_cols[n].right == last_guess[n].right) || (next_cols[n].right == 
right_margin_indent))) {
+       return( TRUE );
+     }
+   }
+   return( FALSE );
+ }
+ 
+ /*
   *  found_use_for_table - checks whether the some words on one line directly 
match
   *                        the horizontal alignment of the line below.
   *                        This is rather complex as we need to detect text 
tables
***************
*** 4224,4231 ****
    int                limit;                              // vertical limit 
reached in our table
    int                limit_1;                            // vertical position 
after line 1
  
! #if 0
!   if (strcmp(start->text_string, "oD") == 0) {
      stop();
    }
  #endif
--- 4641,4648 ----
    int                limit;                              // vertical limit 
reached in our table
    int                limit_1;                            // vertical position 
after line 1
  
! #if 1
!   if (strcmp(start->text_string, "This") == 0) {
      stop();
    }
  #endif
***************
*** 4361,4370 ****
        display_columns(t->text_string, "[l] next_words", next_words);
        display_columns(t->text_string, "[l] next_cols" , next_cols);
        }
!       
        t = page_contents->words.get_data();
  #if 0
!       if (strcmp(t->text_string, "market,") == 0) {
        stop();
        }
  #endif
--- 4778,4794 ----
        display_columns(t->text_string, "[l] next_words", next_words);
        display_columns(t->text_string, "[l] next_cols" , next_cols);
        }
! 
!       if (limit >= 0) {
!       /*
!        *  (if limit is < 0 then the table ends anyway.)
!        *  we check to see whether we should combine close columns.
!        */
!       can_loose_column(start, last_guess, limit);
!       }
        t = page_contents->words.get_data();
  #if 0
!       if (strcmp(t->text_string, "heT") == 0) {
        stop();
        }
  #endif
***************
*** 4373,4379 ****
--- 4797,4805 ----
             (! conflict_with_words(next_guess, all_words)) &&
             (continue_searching_column(next_guess, last_guess, all_words)) &&
             ((is_continueous_column(prev_guess, last_cols)) || 
(is_exact_left(last_guess, next_cols))) &&
+            (! is_new_exact_right(last_guess, last_cols, next_cols)) &&
             (! page_contents->words.is_equal_to_head()) &&
+            (! check_lack_of_hits(next_guess, last_guess, start, limit)) &&
             ((end_region_vpos <= 0) || (t->minv < end_region_vpos)) &&
             (limit >= 0));
      lines--;
***************
*** 4391,4396 ****
--- 4817,4823 ----
        // end of page reached - therefore include everything
        page_contents->words.start_from_tail();
        t = page_contents->words.get_data();
+       combine_line(last_guess, next_guess);
        indentation.vertical_limit = t->minv;
      }
    } else {
***************
*** 4419,4426 ****
    rewind_text_to(start);
  
    i = count_columns(last_guess);
!   if ((i>1) || right_indentation(last_guess)) {
      // was (continue_searching_column(last_guess, last_guess, all_words)))) {
      if (is_small_table(lines, last_guess, words_1, cols_1, words_2, cols_2,
                       &indentation.vertical_limit, &limit_1)) {
  
--- 4846,4862 ----
    rewind_text_to(start);
  
    i = count_columns(last_guess);
!   if ((i>1) || (right_indentation(last_guess))) {
! 
      // was (continue_searching_column(last_guess, last_guess, all_words)))) {
+     if (should_defer_table(lines, start, cols_1)) {
+       /*
+        *  yes, but let us check for a single line table
+        */
+       lines = 1;
+       copy_line(last_guess, cols_1);
+     }
+ 
      if (is_small_table(lines, last_guess, words_1, cols_1, words_2, cols_2,
                       &indentation.vertical_limit, &limit_1)) {
  
***************
*** 4437,4447 ****
        display_columns(start->text_string, "[g] last_guess", last_guess);
        }
  
        indentation.no_of_columns = count_columns(last_guess);
!       indentation.columns       = (struct text_defn 
*)malloc(indentation.no_of_columns*sizeof(struct text_defn));
  
        i=0;
!       while (i<indentation.no_of_columns) {
        indentation.columns[i].left  = last_guess[i].left;
        indentation.columns[i].right = last_guess[i].right;
        i++;
--- 4873,4888 ----
        display_columns(start->text_string, "[g] last_guess", last_guess);
        }
  
+       /*
+        * +1 for the potential header_margin
+        * +1 for null
+        */
+ 
        indentation.no_of_columns = count_columns(last_guess);
!       indentation.columns       = (struct text_defn 
*)malloc((indentation.no_of_columns+2)*sizeof(struct text_defn));
  
        i=0;
!       while (i<=indentation.no_of_columns) {
        indentation.columns[i].left  = last_guess[i].left;
        indentation.columns[i].right = last_guess[i].right;
        i++;
***************
*** 4452,4459 ****
        rewind_text_to(start);
        calculate_percentage_width(start);
  
!       // clearly a single column 100% is not worth using a table for
!       if (is_a_column(100)) {
          indentation.no_of_columns = 0;
          free( indentation.columns );
          indentation.columns = 0;
--- 4893,4908 ----
        rewind_text_to(start);
        calculate_percentage_width(start);
  
!       if (debug_table_on) {
!         display_columns(start->text_string, "[g] indentation.columns", 
indentation.columns);
!       }
! 
!       /*
!        * clearly a single column 100% is not worth using a table.
!        * Also we check to see whether the first line is sensibly
!        * part of this table.
!        */
!       if (is_a_full_width_column()) {
          indentation.no_of_columns = 0;
          free( indentation.columns );
          indentation.columns = 0;
***************
*** 4500,4506 ****
          if (g->is_raw_command) {
            html.put_string((char *)g->text_string);
          } else {
!           html.html_write_string((char *)g->text_string);
          }
          if (postword != 0) {
            html.put_string(postword);
--- 4949,4955 ----
          if (g->is_raw_command) {
            html.put_string((char *)g->text_string);
          } else {
!           translate_to_html(g);
          }
          if (postword != 0) {
            html.put_string(postword);
***************
*** 4527,4539 ****
  }
  
  /*
   *  start_table - creates a table according with parameters contained within 
class html_table.
   */
  
  void html_printer::start_table (void)
  {
!   save_paragraph();  // was end_paragraph();
!   html.put_string("\n<table width=\"100%\" rules=\"none\" frame=\"none\" 
cols=\"");
    html.put_number(indentation.no_of_columns);
    html.put_string("\" cellspacing=\"0\" cellpadding=\"0\">\n");
  }
--- 4976,5005 ----
  }
  
  /*
+  *  total_percentages - returns the total of all the percentages in the table.
+  */
+ 
+ int html_printer::total_percentages ()
+ {
+   int i;
+   int sum=0;
+ 
+   for (i=0; i<indentation.no_of_columns; i++) {
+     sum += indentation.columns[i].percent;
+   }
+   return( sum );
+ }
+ 
+ /*
   *  start_table - creates a table according with parameters contained within 
class html_table.
   */
  
  void html_printer::start_table (void)
  {
!   save_paragraph();
!   html.put_string("\n<table width=\"");
!   html.put_number(total_percentages());
!   html.put_string("%\" rules=\"none\" frame=\"none\" cols=\"");
    html.put_number(indentation.no_of_columns);
    html.put_string("\" cellspacing=\"0\" cellpadding=\"0\">\n");
  }
***************
*** 4579,4585 ****
          if (debug_on) {
            fprintf(stderr, "problem as right word = %s      %d    [%d..%d]\n",
                    g->text_string, right, g->minh, g->maxh); fflush(stderr);
!           stop();
          }
        }
        }
--- 5045,5051 ----
          if (debug_on) {
            fprintf(stderr, "problem as right word = %s      %d    [%d..%d]\n",
                    g->text_string, right, g->minh, g->maxh); fflush(stderr);
!           // stop();
          }
        }
        }
***************
*** 4595,4605 ****
      if (rightmost == -1) {
        return( right );  // no words in this column
      } else {
!       if (count == 1) {
!       return( rightmost );    // why do we add 1 gaius ? was +1
!       } else {
!       return( rightmost );
!       }
      }
    }
  }
--- 5061,5067 ----
      if (rightmost == -1) {
        return( right );  // no words in this column
      } else {
!       return( rightmost );
      }
    }
  }
***************
*** 4681,4693 ****
    int        i;
    int        vpos, last, prev;
    text_glob *is_gap[MAX_WORDS_PER_LINE];
  
    if (v >= indentation.vertical_limit) {
      return( v+1 );
    } else {
!     // initially we start with all gaps in our table
!     // after a gap we start a new row
!     // here we set the gap array to the previous line
  
      if (v>=0) {
        t = page_contents->words.get_data();
--- 5143,5164 ----
    int        i;
    int        vpos, last, prev;
    text_glob *is_gap[MAX_WORDS_PER_LINE];
+   text_glob  zero(&start->text_style, 0, 0, 0, 0, 0, 0, 0, 0);
+ 
+ #if 1
+   if ((v == -1) && (strcmp(start->text_string, "CASE") == 0)) {
+     stop();
+   }
+ #endif
  
    if (v >= indentation.vertical_limit) {
      return( v+1 );
    } else {
!     /*
!      *  initially we start with all gaps in our table
!      *  after a gap we start a new row
!      *  here we set the gap array to the previous line
!      */
  
      if (v>=0) {
        t = page_contents->words.get_data();
***************
*** 4699,4714 ****
                 (t->minv <= v));
        }
      }
!     if (! page_contents->words.is_equal_to_head()) {
        page_contents->words.move_left();
      }
!     t = page_contents->words.get_data();
      prev = t->minv;
      for (i=0; i<indentation.no_of_columns; i++) {
        is_gap[i] = t;
      }
  
!     if (! page_contents->words.is_equal_to_tail()) {
        page_contents->words.move_right();
      }
      t = page_contents->words.get_data();
--- 5170,5191 ----
                 (t->minv <= v));
        }
      }
!     if (page_contents->words.is_equal_to_head()) {
!       t = &zero;
!     } else {
        page_contents->words.move_left();
+       t = page_contents->words.get_data();
      }
! 
      prev = t->minv;
      for (i=0; i<indentation.no_of_columns; i++) {
        is_gap[i] = t;
      }
  
!     if (page_contents->words.is_equal_to_tail()) {
!       rewind_text_to(start);
!       return( indentation.vertical_limit );
!     } else {
        page_contents->words.move_right();
      }
      t = page_contents->words.get_data();
***************
*** 4718,4735 ****
      do {
        last = vpos;
        vpos = t->minv;
!       i = find_column_index(t);
!       if (! is_on_same_line(t, last)) {
!       prev = last;
        }
  
!       if ((! is_on_same_line(is_gap[i], vpos)) && (! 
is_on_same_line(is_gap[i], prev)) &&
!         (indentation.columns[i].is_used)) {
!       // no word on previous line - must be a gap - force alignment of row
!       rewind_text_to(start);
!       return( last );
        }
-       is_gap[i] = t;
        page_contents->words.move_right();
        t = page_contents->words.get_data();
      } while ((! page_contents->words.is_equal_to_head()) &&
--- 5195,5223 ----
      do {
        last = vpos;
        vpos = t->minv;
!       if (vpos > indentation.vertical_limit) {
!       // we have reached the end of the table, quit
!       rewind_text_to(start);
!       return( indentation.vertical_limit );
        }
+       
+       i = find_column_index(t);
+       if (i>=indentation.no_of_columns) {
+       error("find_column_index has failed");
+       stop();
+       } else {
+       if (! is_on_same_line(t, last)) {
+         prev = last;
+       }
  
!       if ((! is_on_same_line(is_gap[i], vpos)) && (! 
is_on_same_line(is_gap[i], prev)) &&
!           (indentation.columns[i].is_used)) {
!         // no word on previous line - must be a gap - force alignment of row
!         rewind_text_to(start);
!         return( prev );
!       }
!       is_gap[i] = t;
        }
        page_contents->words.move_right();
        t = page_contents->words.get_data();
      } while ((! page_contents->words.is_equal_to_head()) &&
***************
*** 4783,4788 ****
--- 5271,5302 ----
  }
  
  /*
+  *  adjust_margin_percentages - so far we have ignored the header_indent
+  *                              and just considered 
left_margin_indent..right_margin_indent.
+  *                              (We do this since we can assume 100% is total 
width for main text).
+  *                              However as header_indent can be < 
left_margin_indent we need to
+  *                              recalculate the real percentages in the light 
of the extended width.
+  */
+ 
+ void html_printer::adjust_margin_percentages (void)
+ {
+   if ((header_indent < left_margin_indent) && (header_indent != -1)) {
+     /*
+      *  recalculation necessary
+      */
+     int i=0;
+ 
+     while (i<indentation.no_of_columns) {
+       indentation.columns[i].percent = (indentation.columns[i].percent *
+                                       (right_margin_indent - 
left_margin_indent)) /
+                                       (right_margin_indent - header_indent);
+       i++;
+     }
+     // remove_zero_percentage_column();
+   }
+ }
+ 
+ /*
   *  foreach_column_include_text - foreach column in a table place the
   *                                appropriate html text.
   */
***************
*** 4796,4801 ****
--- 5310,5317 ----
  
      start_table();
      rewind_text_to(start);
+     count_right_hits(indentation.columns, indentation.no_of_columns);
+     rewind_text_to(start);  
  
      do {
        limit = determine_row_limit(start, limit);   // find the bottom of the 
next row
***************
*** 4816,4830 ****
        if (right>indentation.columns[i].right) {
          if (debug_on) {
            fprintf(stderr, "assert calculated right column edge is greater 
than column\n"); fflush(stderr);
!           stop();
          }
        }
  
        if (left<indentation.columns[i].left) {
          if (debug_on) {
            fprintf(stderr, "assert calculated left column edge is less than 
column\n"); fflush(stderr);
!           stop();
          }
        }
  
        column_display_word(i, limit, left, right, 
indentation.columns[i].right);
--- 5332,5359 ----
        if (right>indentation.columns[i].right) {
          if (debug_on) {
            fprintf(stderr, "assert calculated right column edge is greater 
than column\n"); fflush(stderr);
!           // stop();
          }
        }
  
        if (left<indentation.columns[i].left) {
          if (debug_on) {
            fprintf(stderr, "assert calculated left column edge is less than 
column\n"); fflush(stderr);
!           // stop();
!         }
!       }
! 
!       if ((indentation.columns[i].right_hits == 1) &&
!           (indentation.columns[i].right != right_margin_indent)) {
!         indentation.wrap_margin = FALSE;
!         if (debug_on) {
!           fprintf(stderr, "turning auto wrap off during column %d for start 
word %s\n",
!                   i, start->text_string);
!           fflush(stderr);
!           // stop();
          }
+       } else {
+         indentation.wrap_margin = TRUE;
        }
  
        column_display_word(i, limit, left, right, 
indentation.columns[i].right);
***************
*** 4843,4850 ****
        }
  
        html.put_string("</tr>\n");
!     } while ((limit < indentation.vertical_limit) && (start != 0) &&
!            (! page_contents->words.is_empty()));
      end_table();
  
      if (start == 0) {
--- 5372,5379 ----
        }
  
        html.put_string("</tr>\n");
!     } while (((limit < indentation.vertical_limit) && (start != 0) &&
!            (! page_contents->words.is_empty())) || (limit == -1));
      end_table();
  
      if (start == 0) {
***************
*** 4880,4886 ****
        if (g->is_raw_command) {
        html.put_string((char *)g->text_string);
        } else {
!       html.html_write_string((char *)g->text_string);
        }
        if (postword != 0) {
        html.put_string(postword);
--- 5409,5415 ----
        if (g->is_raw_command) {
        html.put_string((char *)g->text_string);
        } else {
!       translate_to_html(g);
        }
        if (postword != 0) {
        html.put_string(postword);
***************
*** 4930,4935 ****
--- 5459,5465 ----
      struct text_defn   last_words[MAX_WORDS_PER_LINE];
  
      collect_columns(last_words, last_guess, 0, 0, MAX_WORDS_PER_LINE);
+ 
      rewind_text_to(g);    
      if ((count_columns(last_guess) == 1) && (is_in_middle(last_guess[0].left, 
last_guess[0].right))) {
        write_centered_line(g);
***************
*** 5136,5143 ****
    if (auto_on && (is_in_middle(start_region_hpos, end_region_hpos))) {
      is_center = TRUE;
    } else {
!     if (start_region_hpos > left_margin_indent) {
!       make_html_indent(start_region_hpos-left_margin_indent);
      }
    }
    output_vpos = start_region_vpos;
--- 5666,5673 ----
    if (auto_on && (is_in_middle(start_region_hpos, end_region_hpos))) {
      is_center = TRUE;
    } else {
!     if (start_region_hpos > get_left()) {
!       make_html_indent(start_region_hpos-get_left());
      }
    }
    output_vpos = start_region_vpos;
***************
*** 5145,5151 ****
    return( is_center );
  }
  
- 
  /*
   *  gs_x - translate and scale the x axis
   */
--- 5675,5680 ----
***************
*** 5228,5234 ****
        if (g->is_raw_command) {
        html.put_string((char *)g->text_string);
        } else {
!       html.html_write_string((char *)g->text_string);
        }
        if (postword != 0) {
        html.put_string(postword);
--- 5757,5763 ----
        if (g->is_raw_command) {
        html.put_string((char *)g->text_string);
        } else {
!       translate_to_html(g);
        }
        if (postword != 0) {
        html.put_string(postword);
***************
*** 5250,5256 ****
        troff.put_string("\n");
      } else if (l > 1) {
        troff.put_string("C");
!       troff.put_translated_char((char *)g->text_string);
        troff.put_string("\n");
      }
    } else {
--- 5779,5785 ----
        troff.put_string("\n");
      } else if (l > 1) {
        troff.put_string("C");
!       troff.put_troffps_char((char *)g->text_string);
        troff.put_string("\n");
      }
    } else {
***************
*** 5276,5305 ****
    }
  }
  
- 
  /*
!  *  this information may be better placed inside some of the font files
!  *  in devhtml - however one must bare in mind that we need the ability
!  *  to write out to TWO devices (image and html) and image
!  *  invokes ghostscript.
   */
  
! simple_output &simple_output::html_write_string (const char *s)
  {
!   int i=0;
  
!   while (s[i] != (char)0) {
!     if (s[i] == '<') {
!       put_string("&lt;");
!     } else if (s[i] == '>') {
!       put_string("&gt;");
!     } else {
!       fputc(s[i], fp);
!       col++;
!     }
!     i++;
!   }
!   return *this;
  }
  
  /*
--- 5805,5833 ----
    }
  }
  
  /*
!  *  translate_to_html - translates a textual string into html text
   */
  
! void html_printer::translate_to_html (text_glob *g)
  {
!   char buf[MAX_STRING_LENGTH];
  
!   str_translate_to_html(g->text_style.f, buf, MAX_STRING_LENGTH,
!                       g->text_string, g->text_length);
!   html.put_string(buf);
! }
! 
! /*
!  *  html_knows_about - given a character name, troff, return TRUE
!  *                     if we know how to display this character using
!  *                     html unicode.
!  */
! 
! int html_printer::html_knows_about (char *troff)
! {
!   // --fixme-- needs to have similar code as above
!   return( FALSE );
  }
  
  /*
***************
*** 5478,5483 ****
--- 6006,6015 ----
  }
  
  
+ /*
+  *  flush_sbuf - flushes the current sbuf into the list of glyphs.
+  */
+ 
  void html_printer::flush_sbuf()
  {
    if (sbuf_len > 0) {
***************
*** 5491,5578 ****
      output_hpos = sbuf_end_hpos;
      output_vpos = sbuf_vpos;
      sbuf_len = 0;
    }
- 
- #if 0
-   enum {
-     NONE,
-     RELATIVE_H,
-     RELATIVE_V,
-     RELATIVE_HV,
-     ABSOLUTE
-     } motion = NONE;
-   int space_flag = 0;
-   if (sbuf_len == 0)
-     return;
- 
-   if (output_style != sbuf_style) {
-     set_style(sbuf_style);
-     output_style = sbuf_style;
-   }
- 
-   int extra_space = 0;
-   if (output_hpos < 0 || output_vpos < 0)
-     motion = ABSOLUTE;
-   else {
-     if (output_hpos != sbuf_start_hpos)
-       motion = RELATIVE_H;
-     if (output_vpos != sbuf_vpos) {
-       if  (motion != NONE)
-       motion = RELATIVE_HV;
-       else
-       motion = RELATIVE_V;
-     }
-   }
-   if (sbuf_space_code >= 0) {
-     int w = sbuf_style.f->get_width(space_char_index, sbuf_style.point_size);
-     if (w + sbuf_kern != sbuf_space_width) {
-       if (sbuf_space_code != output_space_code) {
-       output_space_code = sbuf_space_code;
-       }
-       space_flag = 1;
-       extra_space = sbuf_space_width - w - sbuf_kern;
-       if (sbuf_space_diff_count > sbuf_space_count/2)
-       extra_space++;
-       else if (sbuf_space_diff_count < -(sbuf_space_count/2))
-       extra_space--;
-     }
-   }
- 
-   if (space_flag)
-     html.put_number(extra_space);
-   if (sbuf_kern != 0)
-     html.put_number(sbuf_kern);
- 
-   html.put_string(sbuf, sbuf_len);
- 
-   char sym[2];
-   sym[0] = 'A' + motion*4 + space_flag + 2*(sbuf_kern != 0);
-   sym[1] = '\0';
-   switch (motion) {
-   case NONE:
-     break;
-   case ABSOLUTE:
-     html.put_number(sbuf_start_hpos)
-        .put_number(sbuf_vpos);
-     break;
-   case RELATIVE_H:
-     html.put_number(sbuf_start_hpos - output_hpos);
-     break;
-   case RELATIVE_V:
-     html.put_number(sbuf_vpos - output_vpos);
-     break;
-   case RELATIVE_HV:
-     html.put_number(sbuf_start_hpos - output_hpos)
-        .put_number(sbuf_vpos - output_vpos);
-     break;
-   default:
-     assert(0);
-   }
- 
-   output_hpos = sbuf_end_hpos;
-   output_vpos = sbuf_vpos;
-   sbuf_len = 0;
- #endif
  }
  
  
--- 6023,6030 ----
      output_hpos = sbuf_end_hpos;
      output_vpos = sbuf_vpos;
      sbuf_len = 0;
+     sbuf_dmark_hpos = -1;
    }
  }
  
  
***************
*** 5876,5891 ****
    }
  }
  
  
  void html_printer::special(char *s, const environment *env)
  {
    if (s != 0) {
!     if (strcmp(s, "graphic-start") == 0) {
        graphic_level++;
        if (graphic_level == 1) {
        page_contents->is_in_graphic = TRUE;    // add words and lines to 
temporary region lists
        }
!     } else if ((strcmp(s, "graphic-end") == 0) && (graphic_level > 0)) {
        graphic_level--;
        if (graphic_level == 0) {
        flush_graphic();
--- 6328,6368 ----
    }
  }
  
+ /*
+  *  is_graphic_start - returns TRUE if the start of table, pic, eqn was seen.
+  */
+ 
+ int is_graphic_start (char *s)
+ {
+   return( (strcmp(s, "graphic-start") == 0) ||
+         ((strcmp(s, "table-start") == 0) && (table_image_on)) );
+ }
+ 
+ /*
+  *  is_graphic_end - return TRUE if the end of a table, pic, eqn was seen.
+  */
+ 
+ int is_graphic_end (char *s)
+ {
+   return( (strcmp(s, "graphic-end") == 0) ||
+         ((strcmp(s, "table-end") == 0) && (table_image_on)) );
+ }
+ 
+ /*
+  *  special - handle all x X requests from troff. For grohtml they allow users
+  *            to pass raw html commands, turn auto linked headings off/on and
+  *            also allow tbl, eqn & pic say what commands they have generated.
+  */
  
  void html_printer::special(char *s, const environment *env)
  {
    if (s != 0) {
!     if (is_graphic_start(s)) {
        graphic_level++;
        if (graphic_level == 1) {
        page_contents->is_in_graphic = TRUE;    // add words and lines to 
temporary region lists
        }
!     } else if (is_graphic_end(s) && (graphic_level > 0)) {
        graphic_level--;
        if (graphic_level == 0) {
        flush_graphic();
***************
*** 5921,5944 ****
    }
  }
  
- // A conforming PostScript document must not have lines longer
- // than 255 characters (excluding line termination characters).
- 
- static int check_line_lengths(const char *p)
- {
-   for (;;) {
-     const char *end = strchr(p, '\n');
-     if (end == 0)
-       end = strchr(p, '\0');
-     if (end - p > 255)
-       return 0;
-     if (*end == '\0')
-       break;
-     p = end + 1;
-   }
-   return 1;
- }
- 
  printer *make_printer()
  {
    return new html_printer;
--- 6398,6403 ----
***************
*** 5952,5958 ****
    static char stderr_buf[BUFSIZ];
    setbuf(stderr, stderr_buf);
    int c;
!   while ((c = getopt(argc, argv, "F:atvdgmx?I:r:")) != EOF)
      switch(c) {
      case 'v':
        {
--- 6411,6417 ----
    static char stderr_buf[BUFSIZ];
    setbuf(stderr, stderr_buf);
    int c;
!   while ((c = getopt(argc, argv, "F:atTvdgmx?I:r:")) != EOF)
      switch(c) {
      case 'v':
        {
***************
*** 5966,5971 ****
--- 6425,6433 ----
        break;
      case 't':
        table_on = FALSE;
+       break;
+     case 'T':
+       table_image_on = FALSE;
        break;
      case 'F':
        font::command_line_font_dir(optarg);
Only in groff-html/grohtml: html.cc.margin.new
Only in groff-html/grohtml: html.cc.thurs
Only in groff-html/grohtml: html.cc.tues.2
Only in groff-html/grohtml: html.cc.wed
diff -r -c groff-cvs/grohtml/html.h groff-html/grohtml/html.h
*** groff-cvs/grohtml/html.h    Sun Sep 12 08:30:10 1999
--- groff-html/grohtml/html.h   Sat Jan 15 00:49:41 2000
***************
*** 23,30 ****
    simple_output(FILE *, int max_line_length);
    simple_output &put_string(const char *, int);
    simple_output &put_string(const char *s);
!   simple_output &html_write_string(const char *s);
!   simple_output &put_translated_char (const char *s);
    simple_output &put_translated_string(const char *s);
    simple_output &put_number(int);
    simple_output &put_float(double);
--- 23,29 ----
    simple_output(FILE *, int max_line_length);
    simple_output &put_string(const char *, int);
    simple_output &put_string(const char *s);
!   simple_output &put_troffps_char (const char *s);
    simple_output &put_translated_string(const char *s);
    simple_output &put_number(int);
    simple_output &put_float(double);
***************
*** 39,51 ****
    simple_output &include_file(FILE *);
    simple_output &copy_file(FILE *);
    simple_output &end_line();
!   simple_output &put_delimiter(char);
    simple_output &special(const char *);
    FILE *get_file();
  private:
    FILE *fp;
-   int col;
    int max_line_length;                // not including newline
    int need_space;
    int fixed_point;
  };
--- 38,51 ----
    simple_output &include_file(FILE *);
    simple_output &copy_file(FILE *);
    simple_output &end_line();
!   simple_output &put_raw_char(char);
    simple_output &special(const char *);
+   simple_output &put_html_char (char);
    FILE *get_file();
  private:
    FILE *fp;
    int max_line_length;                // not including newline
+   int col;
    int need_space;
    int fixed_point;
  };
Only in groff-html/grohtml: html.o
Only in groff-html/grohtml: html_chars.h
Only in groff-html/grohtml: html_chars.h~
Only in groff-html/grohtml: output.cc
Only in groff-html/grohtml: output.cc~
Only in groff-html/grohtml: output.o
------------- cut here ------------------ cut here -----
begin 644 newfiles.tar.gz
M'XL("'3:?S@"`VYE=V9I;&5S+G1A<@#MO?EC&UFVWS>_LOZ*&address@hidden
address@hidden&$O5(:GKZM?IIBD"!K!&V00&BV#/=_TOL),X>9WG9%V=W',=Q
M'">.XR2.LSJ)LSFK$SO).7>OPD6I+IH`*:DX/2*!6[?J[LLYG^^M3OSF?-+O
M[?QHB3]VX(3UNOTCV[;=(,C\9C^.;8>.'X:.XP8>A+JN[_S(KO]H!3_3=!*-
M;?M'9U$R30NOB\?ICSZXGPZK_[V?'^]<=_U[#=]G]5]O^%7]K[K^CX;#R3*>
MX3I.(U?OV?JO^TK]0UMPO:#A_<AVJOI?^L_=$>3K33R^&PV&@_:;]#[[7>MV
MDZ0V')_=W7D3C7?@&^M'U<\'WO_CT3!-)L/QY8K[O]O(]7\_=.M5_U_%S]EX
MV.WNL%90=?&/NO_O#R;C)+[Z1OZ._N_Z#2^W_O,]MU'U_U7\[.P]V'%KY'\[
MQ].!?1R/8/EE.^%=KW6WWK+=5JNULV/!90?EKBMYV5&IRQ[N'address@hidden
ME4O>XY*7E<O%T^AUW$UZ<2V=GI:*\.Q!R<OF)=-W[CJ.O*[D94>E+CLN==7)
address@hidden;2<G+,`N>N,1KV$[S;E"_&S3Y)0^K.4X[_F-/6]8SWK7^<\.Z;3?"
M1J-1]]U&B/O_1AA6X_\J?M+)92].[2/[P'Y@/SBPNL/!)+6AWXC_'5MI\BU<
M`EW(P4[G!K;;M+W`=JPQ?`V5:TW:PWX_&address@hidden'XYMUX(]Y01^30?)Y"+I
M3,address@hidden/1>&C#HK-:;MZP]=^#Y3VCN/^[C49([3\A]/J&1_I_O5K_K>9G
M$/5C>^^!E8ZB=DP[:LMJGT?C-)Y8V]O;:ZTM=\U9<P+'^C'\W2)_N]8Z?N^0
M#][:K5]/AY-/V6!N_80$L5C^FJW^6.GYVOK:6N[+GV(,E\4(<H$/AYH8?T0^
address@hidden>?BI#;,E*8B[2!6=OR,*SNY,+N*&%N+FR3%TG=RX5\
MPI-1SQ?!%H1X['[YS+[$\JZ3H'R^:FL\$8U<R`XM<!J8SUG:TQ2?(TJBD<^M
M*X/address@hidden>00?G<UF50/K<-&93/;BB#\IEMBJ`PGZ^6#,KGZRX$
MA20DGZU/,806;)C/UV>address@hidden@[59/-'\(N0<A#1*2SU7\:TUE?"YN!`WV3+W1
M[_#6%>8S>I^'P-":"XHFFF?LRNOSN7\@@_+9WY-!^=P_E$'Y6MV70?G\/Y)!
M^5K]0@;E,_M8!+GYS![(H'R^?E<&Y?/U,QF4S]<3&93/UU,9E,_7,QF4S]>A
M#,KGZ[D(\O+Y^CTYYKA>/F=',EX^9\<R*)^S$QF4S]D+&93/V<]E4#YG7\J@
M?,Y^(8+\?,Z^DD'Y?/V^#,KGZVNE//Q\SGH/-"W^I3(HNGX^Q^-4$^4;]2'Y
address@hidden'O(',L7YTHG^0'/]>:3Y\A7<1"0T7Y*_%,.6&^2+<J@;32(^F+E!OGQ/
ME7OE"address@hidden/E"ZRK1,L7SAD95WT:F,_RN8PX,Q<address@hidden>[^B
M-4[O.C,?OU9BSC0@)2R?P[[(X<R,/)!!^0P.95`^>R,E[S.S[Z_5P'P&Q^*F
M,_-O*H/RF9N(-CHS_TYEK'S>address@hidden;V]%T,S\>ZGD;&8&_E;&R^?L
M-TJGG)F#>WN:'O!;-48^R\.Q)L:IKEM^I]YF9C30/?A[/N^[X<QH\+VNJXXT
M7TX2S9?C'\N%B`?]^E82OVWWV$K!^CLT,=JDVNF2VL,E>CL>R"7Z']7$>#[D
M#<6#(>#6:address@hidden/@3_ICF^CW1YCP8%FZUI^-Q/*`1K+]3<_U7L;Q_?>W6);\8
MP_XN7:6<address@hidden<"U_.GYS&HW9$_YN38RTK>P\/!A7;J5Q6V;ZC^NJ0`YN'@PV
MMZ;]GDS5WZ,K5UE*,`#=:@]'E^(!?Z_F^L.NO!YJ83CN=,address@hidden
M&*9N]2+86O%:^/LUUP^&?,/@P=!U:R#W8;;U#VBN5_<7M]+S2WGU^26Y//OE
M/ZAKC&<R2U`MX_A,7O\/Z<IX6UX/==*/VF-1!/^PYOJ.;"@P/M[JJ/?_$YKK
M/]GF"V@/ALQ;H]XT[?.&^(]HKC^6^Q@/!M);Z73DB03]H[H(OA+!)Q%\$>$?
MT^4XDCF`2HG:TTG,*_$?UUS_AW)L]&`DOM5/VF-1ZZ-4;=4P&M\:1>-(//^?
MT-ROWQ&-HH$EGG0ZO%U8_Z0NO:3CL`3`R`V#12<1P\L_I2L2N4WT8#3'(G%%
MDOYI73_HBR():3_HB^O_&5T_:(M^`*/^K;':#_Y9S?5NH"0(RKP[CMINP/+\
MS^DB**T`AG<:@;4#ZY_71/#5)S1H!)\_X5_0]9/?409MV,'=2GX]C5->#_^B
M)L8O<9OFD@@^[.MN[9Z-HS>LY5A_4A/AMAH!JF%7:6K6OZ1;L*H1H!YVV\FX
MS<OU7];-:6H$J(C=2=+K\"?\*YH(=]4(4!&[RI!J_:N:"$,address@hidden
M_6NZO:S88/JPB[RUN]]+Q/7_NN;Z+;*-W0IH#*B'/:5Y6_^&address@hidden
MJ_7PIW3UH$:`>MA7Z^'?U-6#&@'J85^MAS^M*U8U`M3#OEJL_Y8N#P=*!*B'
M`S4/?T:7!S4"U,.!FH=_6Y<'-0)4Q(&:AS^KRX,:`>KA0,W#OZ.;K(25P?>P
M&DX>address@hidden:ZS/address@hidden(ATH$J(9#M9#^O*Z0U`A0#8=J(?U[
MND)2(T`U'*J%]!=T>5`C0#4<JGGX]W6EJD:`:CA42_4_T,T.4SY?^K!QOS5)
M^G'*4_07-=?O'(J!SX?M_*W#M!>EYRQ%_Z&N5%_(%,$F_]8+M53_DJY4U0A0
M#2_44OV/=*6J1H!J>*&6ZE_6%9(:`:KAA5I(_[$N25\I$:`:OE*3])]H(IP(
M:X[O0RV</#X\>L93])_J%JNIO!Y7JM\JH]A?T15J)&address@hidden(U$+]SW0Y4"-`
M+41J#OZJKE#5"!XN6Y1"_<address@hidden"U
M$*ESPW^E6\D(@X1/S/^Q4JK_M6YN('8/address@hidden&address@hidden:X>8IDDW#'$:CW\
M-5T]J!&@'F*U'OY;73VH$:`>8K4>_CM=L:H1H!YBM5C_>UT>$B4"U$.BYN&O
address@hidden/address@hidden"(2-0__HRX/:@1<*ZEY^)]T*U"Y<_-QFQ!/SN7D
M\#_K6NM`B0#U,%!;Z_^B*Z6A$@'7K&HI_0U=*:D1H!Z&:BG]K[I24B-`/0S5
M4OK?='E0(T`]#-4\_.^Z8E4C0#T,U6+]/W2;KT1,#KAUZ"1O$O&`_U,W.0A+
MEX\;address@hidden&J%NK?U!6J&@%J8:H6ZO^M*U0U`M3"5"W4_T=7
M1FH$J(6I6D9_2Y>D2\72Z./FX5)address@hidden,:`B)N?#,3>`6/^O+E79
MAT!=7*KI^O_6UJTK]O\?7*/_OR[]_\@"N&[#K_0?J_3_'Y0%`)@#G1(`K?D`
M@'M#`8#6E?O_:3(J`*`"`"H`H`(`*@"@address@hidden@#\^0!`J_+_5_[_RO__T?O_
M_8_._\\'\`H`*`0`&A\>`,#][>\Q`<`C5`A`A0!4"$"%`%0(0(4`O,<(0*LB
M`"H"H"(address@hidden@(@`J`B!'`#0K`N`])0"$___@&O7_>.8']__7`Z+_Q_-?*___
MJOS_!]>O_W>N6__/NYH6`!"!U0D`%0!0`0`5`%`!`*L'`(1W=ZD$@'S*#4(`
MJC,`*@;@HV8`1*VN'`*03RY-`=1OTBD`S&'U,1T"T#)&`%HWC``(address@hidden
MKO0,@-;'Z/\/*___>^K_=V^>_]__`/address@hidden@_W<K__\2_/]NY?]_I__?K?S_
MU^__;YFZ_]VEN__]]]_]WWK_O?^MROF_!.=_JU+_O\OWW[J)KO_6TK7_&?__
MT76>_^_FW_]:address@hidden:W?]>D?O_YK\`P*W<_Q^7^Y_6
M>`4`5`#`QP,`+'`$@&L.`'@5`%`!`!4`<,,``._:``#O?08`6I7_O_+_S_K_
M[0H`>,address@hidden>!4!$!%`%0$0$4`5`1`10!4!$!%`-P0`L"I"("*`-`1`%Y%
M`%0$0$4`_'#__^,'U^;_#YW`$?K_T&L0_[];Z?]7Y_]__$#U_P<address@hidden/\#
MMGXB`$#(/^@/`##Q_S=A(#?S_[L^?_HL`(!O$G#F(`!U'FT6`<"@N2<`*(&S
M"$"#W=2(`0BV/.:Q-V(address@hidden,`*^<address@hidden(0!$T"P!(()F"0`1-$L`B*!9
M`D`$S1(`(FB6`!!!LP0`#](0`")HE@"H,Q?\+`$`(;2B-`1`DW$#/address@hidden
M$0`LS;,(@!N(MV:address@hidden'^K.PP"4P%D0`!_ESD,!E$`=#,##=#0`#YO%`92;
MS@(!,JT:)"`08;-,0%.$S4(!RDUGL0`9<address@hidden"P`3#R\<!9.D"F
M1\,'R)@:/D`^4T,(*+>=901$-C60@'+764Q`N>LL*."**M&B`BQ,PPK(NVII
M`1XVBPO((;LT+B#26!864)]1$A80Q?N#:(%F$2W`)[G2M$"3#GYS:`%W'BT@
MHFEI`7<>+2"BS=("address@hidden"SD!9PY]$"XJ8:6B"0%:BA!41=:address@hidden>address@hidden
M9G,^+M"<CPLTY^,"S2)<H#D?%VBPFVIP`5X1&address@hidden(+2_0G,<address@hidden
MCYOS@(&0!6F`@:;(FP88X'G3``,-6;address@hidden&address@hidden/6_."address@hidden:&&@:
MOSB`]Y/2T$"30P"EH0'^@)address@hidden@`VUI<$!,V:address@hidden:(<#/8
M@>address@hidden/address@hidden(8BM/#[2,Z`%1]67I`1FA)#T@(Y2E!YH%](#2
MNLOB`X$A/address@hidden'%H:'Q#5NBQ^0#;-L@"!$J,D0:#$*(address@hidden
address@hidden&"4A`B5&28I`B5$2(U!BE.0(address@hidden@!V0:9PP2!*4P0F,($
address@hidden,$!C!!(&(4!(address@hidden"1.(+6QIG`!C!$8\`?;address@hidden&*4
M)`J4&"61`B5&2:9`B;$DJ$",A:6Q`ED;9;D")49)L$")49(L4&*41`OD.%66
M+1"6D-)T05-$*(D7B`AE\0(9H21>(".4Q`MDA))address@hidden/JLE9<'
M#)J&@(%(4UG`0$8H"1C(""4!`QFA)&address@hidden"0,9H21A(".4)`QDA/*(@6N*
M&+BFB(%KBABXIHB!:XH8N*9O&'!OVAL&7%/&P#5E#%S3-PRX1I"!W+$90`8R
M2DG*0'address@hidden:J'YNY(_D/PZNC__PZY+_J#O(?S0\K^(_5LA_')0#0.HE`1!<
MJIH3(.Y-)D`:2R%`O(H`>3\($&_9!$AK<0+$,SP&XD8!(,T*`%D.`.)4`(@Q
M`-*H`)#K!4#J'address@hidden(0`DK`"0'P:`U%<address@hidden,`1`NUK])`$CKPP!`
M(!-+)4#JUT6`N!4!<N,)$--72-273H"([G"C$!#?%`%I&B,@+5,"I&address@hidden,
M^8^6*?[1,J4_6L;P1U#!'Q7\4<$?%?SQH<$?K0K^N!'P1[."/]Y3^*.Y=/BC
M:0I_-$WACZ8I_-$TA3^:RX8_FA\A_!&N!/X(*_BCXC\8_[$\_*,$_]&0_$>C
M3L[_\*KW?ZR0_SA8X/R/^K6>_^$5T!_.?/K#7\;Y'\U%Z`]_,?K#K^B/I=`?
MP5SZ(RB@/UK+IS^:!?2'O\#Y'^["^(=3A'\X*S__PRW`/^H%^$=K*?A'L##^
MX1;@'ZTB^L-=E/YH+07^<!>%/Q3`0_>address@hidden@CW`^_-&\
M^M,_FD7P1W-!^,,OA#_"`OC#+X(_W/GP1W,A^*-9!'\TB^"/^GSX(YP/?P0%
M\$=S/OP17OGI'address@hidden'_Q1-X<_FN_WZ1\M\],_FA_(Z1_.DN&/NBG\
MT>address@hidden>address@hidden'[T;QN]L,W/OW#F/VHF[(?O#>\WZ=_F*,?TB%9^O0/
MU_CT#]?X]`_7^/0/B.&;G?[AKN#T#^=#`4!\(P"D;@J`U$T!D+HI`%(7>address@hidden
address@hidden@K`$!<8P#$-09`7&,`Q#4&0$3O6QH`XGXX`(AO^F*1P/#%(M79'S<"__`,
M\8_PH\0_?%/\PS?%/WQ3_,-?.O[1K/"/I>`?S"!1&@!IF@(@35,`I&address@hidden
M`(`T*P"D^EF8_SBZ1O[#<RG_$3J.X[K(?P1AO>(_5L=_'%TM_]'\N/B/L.(_
MWGO^PU^(_UC!^U^NF/\H.OVCM7+Z8_6'?X0%]$=K4?C#*X(_G/<'address@hidden
M`?S1*F(__`4/address@hidden(-'/\+W'_WP*_3C2M&/\`-%/_P*_5C=BU_,
MT(_0%/WP/Q3THV&.?GR`+WX)JA>_W'STH[Y\]*-ACGZ$'R7Z<3-/_?#?_U,_
M/E+HXV:>^K%TZ,.IH(\;!'TXQM"'8PQ].,;0AW/SH(address@hidden>=>9'!7U4
MT(?]H9SY42$?!LB'4R$?U4^._WCVX!KYCT9#\A^-@)S_X005_[$R_N/9`Y7_
M<-T,`,)=S,LG0*[N_2\B;)8`"=Y!@'A%!(AG_OZ79L'[7_SY!$BSX/TO_AP"
MI'YU!$CC8SP!))Q+@(0%!$AS#@'2-"5`FG,(D/`=[W]9U?D?A:]_\0H($.6V
MLPB($JAA0+PB!L0K8$#"address@hidden(7E,#T"Q%O>&V"8RU$'@address@hidden&X4LT
M*(BWG'address@hidden"`0SX@&"1<Z",2[AK?`A%L.?^XL#1*8TB#L$"(=#2(;
MB_8U,.$\'$2)-\N#B.?-\B"-17D0^4`-$")>:J(!0NIB7Z0#0EH%0$B]"`BI
address@hidden/".%%HR%",%K1JV#"^4A(R.ZJ14+">4A(HP`)$7G0,B'A7";$
MXV&S3`C/NI8)"8N8D+#P73">$1,B^N</?Q.,=U.(D$7>!--<address@hidden(>_+!(B
M9H+23(BD5$H2(:&HMM)$2'@CB1"SPT":[\-A("'C-98&A'!$Z>8`(0U#($3.
M$%HB1$R1I8&0.FL8[S<0\B&<!1(N=!9(address@hidden)?]ED@
M"[P,address@hidden&"7)$.D`+XN&A.(1)=$0&:$D&B(CE$1#0N,7PGC&
M:(BWR`MAZL8OA*D;OQ"F?N->"--<address@hidden,8HBX9XQB^$<6_@
M"V%:IG!(RQ0.:9G"(7RW4!H.D1%*PB$MXQ-!F.'8``X)#>&0EBD<TC*%0UJF
M<(@HU[)P2-T4#JF;PB%U4SBD+O)address@hidden<(A0HI<address@hidden(A+5,ZI&5*AXBJ
M+DN'address@hidden"F(1W2XF:)TGR('"W+`B)*C)*$B!*C)"(BF\<2&1&address@hidden>IG
M'O]Q<'W\1RCY#]?QD?]HN$[%?ZR0_RCY`IBZBG\TKAW_V%HE`-(H`D#"Q0`0
MC[$<A@"(MWP`I%D!(!(`J?,5N_85,*VY1X"$9J^`:2T`@/@address@hidden
MD.9R`)!Z$0#B+PR`N.\$0+SW!P"address@hidden@2AOD)D%0$)S`*1E"H"$UP6`
MM*X4`!'>?,address@hidden:!*2U!`0DN%$(2',^`M)<!@'2G$^`U.G4
M9`J`-`L`$'\A`*15!("TKA0`:5T7``(1WFL"1+J7RQ\*TC(C0)RE$R`M<P*D
ML7P"I&E*@/#>:7`H2'CS$9#&QX>`U*\6`6E]``1(TY0`$9VA0D`J!.0*3P;Y
MB!&0ABD"TC!%0!JF"$AC!0B(address@hidden)RU0A(2SRB+`'BFA(@JBNP+`0BO9IE
M*1`E1DD,1(address@hidden((@2HR0)HJ2J_#DART9!;N8Y(1\?"M)</@IR,P\*
M<4P/"EDN"L)L3!\="-):R6$AK8H#^4CXCZ?1Z[B;].):.CU=+?]!CONP[4;8
M:#3JL,P/X0N80"address@hidden;@`5_/#IXLG]\[^'^\9Y]<F2?'address@hidden"_
M`WOOR-Z#?Q_`?P?VXR/[,?S[`/X[L)\=V<address@hidden(D-C'U7#P'O-?R\._WLU_
M!;X\_Z?NTO-_O*K_KX[_NF+\"W>FR^:address@hidden:Z!50\_DON2BL"+#5
M'0'address@hidden@WI428(address@hidden"+\RUWP_)]"_,LIP+]:RSG^
MQUGX^!^GF/YR%Z:_G(7I+V?15T$I$-<5TE\-<_JK:4I_-<SIK\;[=?Q/T<N@
M&O/AKU8!^]58E/T*BX[_:address@hidden'!ZZ""PM=!-0O0KZ`(_0KFHU^M^>17.)_\
M"HO(K^;5G_U30'ZU%COYQYT/?C47//FG^6&`7ZV;]BXH;[DG_YAB7ZT/X]P?
M_\:]">HZSOWQ*^CKG=!78`A]M3YXYNLC?0U48R'D*S!&O@)CY"NXD<A7]3*H
MLB^#,C[Q)S`]\2<P/?$G6/*)/^X*3OQQC%\&Y1B_#,HQ?AF48XQ[.4O'O9Q%
M<*_`&/<*C'&O8/FXU[(/_&F:TU[5D3^E."_'D/-J&'->#5/.JV'*>35,.:^&
M*><5F')>@2GG%9AR7H$IYQ6:<EXM4\PK-,6\0E/,*S3%O$)3S"M<-N85&I_X
MTS+EO%JFF%?+E/)JK>"TG[`Z[*?Z683_.+I._D-Y_U-`^0^W7O$?J^,_CLKQ
M'W[YMS^YQOB'9XQ_O`>'_S`GB3G\$1C#'T%U^,_*T0^^$=">_F/address@hidden<$?
MYL?_.,LY_L=]CX[_"8OX#W?AXW\:"Q__XRX,@+B+`R#-A?D/?V'^HU'$?_A%
MKW]R%GS]4[`"_B,PYS_"&\A_-!?C/\+Y_$>S@/\(B_F/^2?_A`O3'TLX^&>U
address@hidden'XZKIC^9B[WTJH#^:"[[W*;@N^J.^"/U1?Y_IC^:RZ8^F*?W1
M6@']87[F3[!T^B,T?.L3:address@hidden,address@hidden<$//GI_C_QY-_W!&G=9
address@hidden:,\_^$NF_^HF_(?X0?QUJ<%^`_'F/]PC/D/QYC_<(SY#XCAF_$?CC'_
ML;*W/@7&1_X$QD?^!,L_\B<P/?(G,#WR)UCRD3_N"H[\<8T9$->8`7&-&1#7
MF`%Q31D0-I669T!<8P;$-V9`?&,&Q#=F0'SCMSXYJX%`C!"0IBD"TC1%0)JF
M"$C3%`%IFB(@36,$Q#-$0$)C!"0T14!"address@hidden"0*T)`^#11(2!%
M"$AS)>?\-"L$Y"/G/XY_=%W\A]V`SB#/_PD=Y#\")ZCXCY7Q'\=6.H+I/^J5
M/@;$81A(address@hidden,P"@4]8#VLBCP<,`L9MT$]U=DP'address@hidden'8
MB%1WZ.$;_*-K;2)R00_5\,@!&XRQL$8]>.36FB_1"OHF)6:QM/H)A-<PG#(4
ME)IP*#5!.`G+$5EH.)8K/[B6)S]XEB\_^%8@/P1677ZH6PWYH6&%\D-H-<6'
MT+%:address@hidden&<U#,CA$G4*&!"DP/I<!#8H,T#O%UKWOA>N%<>Q-G=E
MJ;L.E.4#48&NXUF;OU"#?6OSH1(<6)O[RL>ZM?E(O;IA;7ZA!(?6YE=*L`O/
M/I"OWW!=ZY-S>;4+C_Z9/`;/=>'13]3/\.RG9(?%/L/#GZEWAX<?JM?#TY\K
MX1X\_;$2[D'.CT33=#UX_+%,C0=//U$^!J0+R,]U:Y(J_C8/'OZE^C!X^)Z\
MW(=G_YX2[,.S?U\)]JROE?;M^CYQ3%N3KGRYAA]8?@>^^R9S89UXEZW12,F8
MWV!^879-:(VC3M*.>O%;;&0>\PA;FZK>W]H\558-+O3DS;>JIQ6*HZ/address@hidden
M5/address@hidden;^*!F\S+">address@hidden
M<D]6$_3GS3ZYE<<<address@hidden>+CZZA1K<R3]D?#@<]'37.C2FV/5I0I/
M5M^"8FU.I&\4'CR5877KDQ%6:)/Y.:W-C+#=VB3.)(_[+.&YO\Z\NL3:_%8!
M=5WHZ+T]!<-UH:__!O)U&B%Q)[X,B`O2^BW\?YR]O&Y]!U]&(SXFN#`&;+X0
M3<S#@;HOACH/ZO>S>](!YUO='24PL!+2\AK,VV8]&B@/\Z!Z]YZ(W'I0NP\/
MY$>HW,?[RD?7.GZN?(0'?RY>B.-![7ZV+=SD'M3NE$PGK.`\J-YH/!Y>O(G'
MD\D(<KC]N7)UP^IDKP[EU:<3N+HC)0L>U/address@hidden(S+?%'#WHVK%2Q8D'+>!S
address@hidden@Y'address@hidden<#A`*R"8.Y.?.KBKL7Y\3W[C
M6O?$`4$>M(#OE3#?^OY[S"X,.E!8'O-'R.S%;]6,0_5'`[PP8$X%:^\(4]EB
M'@-K]US.NS[,address@hidden&address@hidden><6-W'[5GL3:['%+/%6^Q/E
M(TQ`J1J]8;7EJZ1\F`?:\C5!/DP#Z4CYZ%H)_4BSZ<-$0++MB-T>3`7IJ1(#
MVN=I)@;,ZT,EO&$-^IGXH;address@hidden/DP%9V/%D`93`7L+"0OW^,M9V&??FO35
M^'address@hidden"2,>$8F6&4L5]YL-L,"#I8Z=[.^A8M7:?B0TPS`>'1_*39YWO
MBC[BXVRP*]\Q#A/!=)=4/C,;6F,U%/J$&AI:O6_EUA]&_1YQ*WK<$.6*G#!K
MF9?_PJ=?N-*>QJM'9!Y&B%$TC@>]N(N]M*'<OR%#H,FJ(:$,.9VH(3"`G(ZC
M]NMX,GL_&$UZ;1P7Y079V\+XHH3E;@P%V6618W;O4`D.K-Y$#>XGG4QXW>J]
M5L/A[FIPP^J=\N!Q<G8^8?,M#P]E3`B!"]_P#N[QZH(Q:IRI'QBBDA1'9G8V
MGM\0G4->X\]^%<Q^Q>J(I"Q;J(V&$I0MSD:H!&5+,Q35I+DEC&UCI9XT=PZ]
M3&#NWKXU[F;*,EM5,!*.)address@hidden;address@hidden/*ZM&9O]_\N#:]!\-
MZ+=$_]%H!(Z#9P'C^9^5_F-U^_^3!^K&W\]L_'UEXQ_(C?^ZW.IG]1\9(\#:
MN]0?UD_I0EAW]J=.^X$F!)&*+%F'address@hidden<@J/ZCPP]$(/W*6AK6<[$,U.ZS-
MJCX<C>I#-4BLY30?_AS-QWS)AVJM6)L5?#@:P8=.[Y$Q:ZSEU![2QK&6$WM(
address@hidden:3NLAK1]K.:F'-(6LY90>TBZREA-Z2"/)6D[G(2TF:SF9AS2?K.54'M*6
MLE9*Y%&@\5!-+AF%AVI_67N7OD.US634'?3=SHY&W(':#D(E>SIUAT[<P;0=
MCD[;866,/&MY88>,ELO]0S4L5Y\92]!:3M31E$:A-8VDP]%).MB)GHY.T6%E
M+$=KLWH.9TNKZ&""#D<GZ*#G>3HZ.8>5-36MY<4<TLR4R]ZA^KA<]IXK!J1<
M[IAUB)N3<AD\4NU6N?P=*S:L7/8R!JRUO(9#WC&7O9^K8;GL?2D'W[R"@QW@
MZ>@$'$R_X>CT&U;&$K:64V]DS&)K[Q)O6"\EY9_3;NBD&WEKVMJ[A!OTK<V.
M3K>ADVWH5!LYX]S:K&;#T6DV=)(-*Y(:address@hidden;\\_KM.19=GFYQOS3
M.JE8P]&)-<A)G7.T&M:Y8M/+Y72^4J-0J$%/address@hidden,@U4:7AZE8:E
M&A77RFDTBB0:10H-:RPMC;ELS=5GS)=G6%,I]\CE:>[1G*C-</3:#.NME%CD
MLE1P+J?UK4AX?KK]3=;4N?8N68;U6VH&]72Z#)TL0Z?*L+[+6DS7WJ7)L*3;
M),SW]>\UG7%6D*'38U`Y1JB78VC4&"C&".>),31:#";%<'12#(address@hidden
MAD:'P608CDZ&H5%AH`A#5EQ>AJ%183`1AJ,address@hidden&"C!J,^18&@4&!F[7EZ`
MH=%?H/Q"WCXKO]"H+U!\T=*++S3:BP+IA49Y8:$'-B.\T`DN-'J+C&TS+[?0
MJ"T*Q!8:K47.QIZ16FB4%EG[>T9HH=%9H,PBD+;YC,Q"H[)`D86\/"NRT&@L
MBB06&H6%]8=RK,L++%!?(0F:O+Y"(address@hidden'MZ9H:<47AV9H::04J*T1!Y)05
M&F$%TU4X.EV%1E:!JHJ67E6A$540384C[I[55&@D%411(:_/*BHT@@JBIY#7
M9_44&CD%?8%RJ%=3:,04A5H*C92B4$FA$5(address@hidden,@address@hidden)00Z&1
M4!0J*#0""GY^IJ/33VCD$_ST3$>OGM"()XK.SM0H)XI.SM3()HK.S=1H)MBI
MF;Y.,:$13*!>HCY'+Z&12Z!:HCY'+:$12Z!6HCY'*Z&12J!2HB[2GE5*:(02
M7"?AZ'02&ID$44F(EI9326A$$H4:"8U$HE`AH1%(%.HC-/((KH[P=>H(C3B"
M:R-\G39"(XU0G,EY981&&"%T$5M:981&&$%T$<X<781&%D%4$<X<581&%$$T
M$<X<381&$D$4$:(]Y!01&D%$H1Y"(X=`-82@:7-B"(address@hidden')T40J.$0"%$
M.$<(H=%!H`PBG".#T*@@4`01SA%!:#00*($(YT@@-`H(%$"$<P00&OT#RA_"
M.?('C?J!B!]<O?A!HWTHE#YHE`]%P@>-[J%(]J!1/12)'C2:AR+)@T;Q4"1X
address@hidden&K5#D=A!HW4HDCIHE`Y,Z.#HA`X:G0/*')IS9`X:E4.1R$&C<2B2
M.&@4#D4"!XV^H4C>H%$W%(D;--H&!?O)2QLTRH9"88-&UX"RAG".K$&C:D!1
M0SA'U*#1-*"D(9PC:=`H&E#0$&8%#3VQ<_A;FL04G6BI43,P,8.C%S-HM`SS
M3K.L-`PE_/\'U^3_MQNP'LKS_PVW4?G_5^C_/R@'`(1Z`(`>address@hidden>+*
MS_KNT5WO2/S_ME05(/[?R.+_C0S^K[C>U2,6LX<J9GSJ.>B_<0.A_WH!]-\0
MT#_'"%7JOR&H_Z:D_N^38PVD_YBXC*U=Q6GK9KW"ED*L.W[.]<L.\1/@_R/E
address@hidden/`_K-^W*SK-N^MS3EHLS[9G!O6R@'_.=X_XU]E+T>4+M6<%S7K.&4G
address@hidden:/^L?S;E$V7L,!>K_BPSI_Y7B(G2MWU<^>?1MA'G,_Z5HC4CYHYM23_EG
M?(address@hidden@-,R>[T;/<N&LPXPW,address@hidden)[0Q-Y\$_'-\?\:=
address@hidden><U9<4/?39#-6O^MQR[\'+>=8RSK2,_\R:P-.XRRSC
M);/>R,L:UH4\W2RTWDH_EF-=*OF&7JOZN/)N+>+)LGXK\\?Y?71.Y;U1Q`%E
M?2^Z-P+\Z&4B;B7B1T+'4:@XCM!71)U#;/&(5/\?A>^>R]4JHOU_#+[*.'G0
MKX..''E1'7TWZ*R1&H`&>F?0':.8M:&>_SBFJ"-?Q>address@hidden'"CNXBGM.
MT%E"7TS&O2/H$,address@hidden',1@<'>address@hidden"(:>B3FX?RN+^V==
M"address@hidden"]`3GS_XS%'XW\V3.3T)"?M]RCL3YGG4>#/'NS%;?`
MH]&=OKN*6]G1L)ZWI*/Q/&\M1P-YWB*.1G"T>C<5JS<:NM&R+4R9,#_\2?CJ
MMOJ5B^9JM$_+KSRT2*,)6G[EH]$9K<SRJP#MRFA(EE_5T72<MQ6C>1CMP2W5
M'(P68'Y<CL\5`W\*TY;YSD5;address@hidden<E\YZ-5EIEA?:X?^#-X._6K
M.EI7F3G5YRJ"/XLWRYA,T4I*S**.HB7X<address@hidden(O63OX:()]K"OX\/C3S
MG8]62_XJ'Y]K"_X"WB_S71VMC_QU/-S<B!;&[&$K1)_"7ZDCS(9H*>2F09_+
M#?X2IB7SG8<6/V[B\[GRX"_C<[-F/+3<H:FN*;ZJHW$N9XU#`QQ:W)3-&,Q-
M?P63HA[.X:`IC1TAXG!)PE_%A&0."4&36.X8$#1[Y0[Z0--6[B@/-%_E[%5H
MHLJ_D07-4,SNY'`1PE_#A*E?N6A.RMF/T&24LQ&address@hidden/CK>"_UJSJ:
M=W+V'#3AY&PV:*;)V670%).SO:"YA=E7'*X2^!OX1/4K'\TF.3L)FD9RMA`T
M?^3L'6CBR![70*1,.;L%FBJ8;<+A&H"_B8E0O_+0Y)"S,:!9(6='0-,address@hidden:
M8OV*1/_?QD8VRFSO&V@"P#V_>F58;?87VO\O;_O_;OX?/@C^W_?H^Q\J_?\*
M]_\EM_]U=?O?N"[^WYO/_[MS^?_Z"OE_3M+-"@#0/N%6`H";*0!P]0(`(C5U
M]1H`:8XI(P)0[F2B`U`TX.5T`*WY,H#F?!E`Z\I5`*T"%8!3H`)P%E(!-.19
M$C,:`&>^!J!9H`'P"C0`;H$&P%E,`^`4:0!:\R4`X7P)0',Q"4"K0`'@SE<`
MM.8+`)KS^?_F?/Z_L63^OV'*_S>NAO\/YO#_]:OB_\,KYO_#0OY?&`;S"H!&
address@hidden(@O'H%0+B8`L"9JP`(address@hidden,!0"!>@address@hidden
MAKD`H+X,`4!CR0*`T$P`$!H)`$(S`4"@address@hidden@OL<"@-!0`-`H+P"0IO$5
M*`#XY<N0`(BS:6Z"!D!>?AT:@."]U0"$'Y4&0/&4E)$`*%Z4,@H`Q<address@hidden
M,N/_Q7E`Y?!_Q6M3BO[WS>address@hidden&__MF\+]O!O][9O"_;P;_^V;POV\&
M_WLF\+]C"/^[AO"_XATK!?\KGK-2\+_B52L%_SN&\+\CS_LJ`_^+$\I*TO_.
M(O2_;TC_^X;TOV](_WL&]+_B4EP"_)]Q19;$_QTS_-^Y0?A_RXS^=TSH?\>(
M_F^8T_^.&?WO+)/^;YG!_XX9_.\L$_YO+8_]#XW9?\>,_7=N$/O?,D#_1>=8
M&OOOF+'_SC+9_Y89^N\8H?^A.?K?JLC_1?W_1]?F_W<@F/C_PT88-GR7^/]]
MK_+_K\[_?W1U_G];\Q:`.6*`>>\"H+[[S*%][WHC0%82T,Q(address@hidden@/Q
M'@!VW?OU)@#BDBY\'0!Q-6??"<"]RGEU0.;5`'EY@'I.W*P^H)address@hidden
M*P]P"N0!BALWY[G]8>address@hidden@520-:1<address@hidden/SHK#:CKI`%!
M26E`6"`-\*4T()B5!H3SI0%A26F`O&LC=^A7ULMG)address@hidden&A`L*`^H%
MPH#F'&%`J`H#U%/^5;address@hidden@#FD7"@+K&H:03"##G$=<)*`=%X<#-
M7$5<,J!Q"VFT`]0'Q!4$OE00"%\/address@hidden)CQX>B$!<Q;P_4%P8QC
MALL,9GTP4FZ0];<PT0&WPZN>E9GO-$H$ZDKA>address@hidden/R700S+YW6
MJ!28TT,C5F#^#:Y9T!QGI-$N<+<%>BQ"C<address@hidden,Z30/W1&BT#<SKP"4.
MLPX&KG28]27H%`_";Z"3/@@address@hidden(3P"7`S1T)G_N2I"GAJB&/NY/D()E*9]
MKI10`H4AGTLFE#!IM>?B"6D[%39Z+J)address@hidden:&SO7%4QYY0=KJ_0':G#
M=1:Z\W.XWD)S6`Z77<P>C*.(+V;.P%%4&#,'WBARC/SI-AI9!C-FZ]09U&ZM
M:C1F7N*KBC5FSJ)151LS!\^H\HW\*3.JC&/F?;LZ/0>S('-9Q^Q),7IYA[`+
MJSJ/address@hidden,''S'DOJO(C?[B+3@'"3+E<"-+2'-G"%2'address@hidden)&6.Y/D1W
address@hidden@.6>&*$8U)E2M'9)`TGW()R>Q1*5Q)HCD51:,HX390KBS1GG:B2$QF
MCC91M"8SYYAH1"?<;*D1GS`;)=>@^)address@hidden<</,)5*?ZLH9&K4_R9$T4T
M(A5J0.12%6F=DZ9"1;,R<R:((EZ9.0!$HV+A%C]%S>+FK7L:60NSY7%UB^;$
M#IW,19CH%+W+S%D<BO!EYN`-C0*&6]HT2ACVBE`NB-$?GJ%5QG!S&5?(A'-?
M\%E9R#YN^]^PO7,^[,>CZ"RN]=-KL?_!R$#M?T&`6Q[XRJO>_[&BG]J3YU;M
MY3K^W[;3>&)'=F\X.(O'=B\9Q/;D/!K`/['=B;O1M`?!J7T1V^<PSMDI-!MR
ML=V=C.RHTQG':1JG]%87YTG[W#X;#[M=NQT-8+-EIZ->,J$/&XSM)T_L,+%J
M)address@hidden<6S%_8)_GFG9M72D>W"59!(\;55>W'TQ%[?()??6;?Q
M]4!W=W;(HVK=;I+4AN.S'6O;CNB5&)%=<W%Q43L;3.D%H_'P5[`'K=F/A^DD
address@hidden>;O:Z1B2<?!LGR8FGU0[2:'DH#--^[##MN'>;2B,X9B6
address@hidden>0M//(BF9S;W>&X'TTFL+JPV\-^/QK`E?`/WJ,S
MA;M8[`*X?CB=C*:3FI*$P?#"ADW6:#B>I/;CDZ=/\':DPKZ,3VO6\UX<I5!3
M<<Q*C<:",/LD&:7K]OI/Q-]8V%;M^+'U<'@QZ`VC#GD,+<(84C"XM->[NJ(>
M34_I5SOKUF]IA!?'N_QB^%>4.?P65XJ;/TG:\0`2J:DCW._C&[-VSD:]&KHI
M^/W7GT9)#TNLEZ23]9G:ZD,H)'@'0Y-!=\@>*F+34L"2^C(9=(876!#*X]MI
M[<VT-NCM?#_IGR6]G7Z2MG<NX'address@hidden@O8$B`BD]A]VA#07?NVB=028^C
M<0>NM6I/=P^>G!SB=S7VW?T!-(H$QMEVNQ:U:]/7I%F=Q.WS`;ZB,WNO+^/Q
M`.[_).Z?QF-YNXO>?58\M,)(AG9/H6E`M4,K3)-)7,.*/<%/Q_!IG=3JT?[N
MPZ>T]9(0^`^;"39AVDM%XU4:9'H)7:-?L^T3N/0-#(#)<&`/address@hidden"VYPEKR)
M!W9"1XANTHOMG^\?'1\</J--]&#0[DT[4"3D"KA^'-/V&(UC.^F/>C$^#Y;C
MPT&*`\`$T[%ECY+VEAW_>K!E3TY[6]!WNO%XBSQB&RK51M/*D'81^EW*OMHB
MWW7&"2:4U.YSZ-G'[7$RFFQ!*?_"[KQ)6.ZV[,?/[2>0EO'address@hidden&=+!A.(
MMB4Z$5QD;T#SZ?7LJ#<ZC^Z0VUN3RU%\,892'6_WDM<X+KZ!]IM"$>WVTB'D
ME&<9QX/^L)-T$_C$BPXS>1Y;#^+Q:RB*2TA\K"3>C@<PW+9GKK=_X;KVVTXR
M>9/$%S!NQ?@;RP3S"]&R1<DC;??[O*S:P\%DG)address@hidden/X:_H
M3#:N7YW?C]XF:2V-204>Q[&LVH-GQR>address@hidden@UNSUZ//PPWC:)M4(Y?#5
M<`H#&Q3;./[U-!G'5F3O??()CFTCN,address@hidden/H1!3J*73&%L(6BAM
MG&RWWR1I<@J7M*%0SB!L,J0M51W_H)B[XQCGHN[D`IH5/#^3Z+W#YU\=//N"
M)!I'$VS4(QC-H*=!<G-I>7YT^.#)_E,U/address@hidden><address@hidden&>@79#I[S2.
M!U8\:`^GV')H*Z>9A(=L\2(B?V,]C:>#`3Y=R<(C-E3WAUAYM(GS7DB+-H(!
MH1^SIUY"P6+/B7HXG5Q:W:@/SX+%"YE&,/*+0?*6MQVU1V&_V2(]A?4:;$1B
MCDIE,?2AP_`Z8)TUTQC/>*%'address@hidden"9A4-AH/+/I86K@>ZXV'?
address@hidden/DQTH$FT)\/QI4WF#3XCT#3LVGL_/X8GCX8PC.$U\"B<XL1SMDA;AFD4
MBQ)O1RW3$^R'<address@hidden(7;4QCS;R406&address@hidden
MSXK?XKR*23HZ/#RY=W<$K1+N?1<SVGZ3WF>_Q4QX=P>:RPY\8\'address@hidden(
M7]O?MN`I-"UPXR.KUH4US=$^?2!D>R.A71:JI#^:B"E\!-5_,1Q#'Q^-X@@'
MIU_!:address@hidden&V//MU?`E+I=TN_AW!:H!DL3OMT1209C,8\E7=((X[K'N,
address@hidden>:D.58!!TO;K^FRPZU3M+SX;0'address@hidden'*LL-R
MXWEF]]KNT$PK&6;K$FS')#$X2=NX!2&M%N-C&72G8P@<0]U"C?=8,]WM03X'
address@hidden@8MD\V&%+%SL=1"-(YP1F=KD,T:Q82+.A?V^SIE2#_4#M[%MK
address@hidden<?1C$!2+V"LQW5>='F'-/!LOA=]4KYTAEB/,'-TZ;`$'9%D%P=`+"SX
M%$/address@hidden:address@hidden/=(]3J=G*0S8O$/BU)E9
M$CQX\<7VT?[SPZ.33VE==^(($F]-^"ID"-,4S*3I=!S3@>[1\2,88G&0Z8G6
address@hidden,QF6PFI`F3:-WDK87AD`*<?R?D8LC%):address@hidden::#IPV%0/-02HRNN
MI'N7VN>2:Q+<_[PFC1,>N$\6/UT^+EMDCR,R@;LCR"*4"ED*0!JW>(DE$U9>
M,EEWR0+)(O-F/"`CZI3D$=H^3E?8S\YCTAL2[(R0Q$MQ8QL:##R<#^,X'_:5
M]7%*9PT^A,Z.<W"+;=(&^,I28E78#6FJ\6Y8U=:<*_G59S&L6J%5=F#1/$TS
MX[#%6C^,-\GD/F^.-&I$*FM[.(!\8:)address@hidden>X:address@hidden'\E.
M(]I!]]EPPJHJFR,address@hidden&:EHQ`-Y:G]E%1W'\?AT]A*IZ=TI=#A#_XEN?PV
M:6&_5/-[F]4%7)?&I/F)(>T$ON(WVJ*A\3:&X\5?8[1OMG$Q!;W^_M>=(80,
MOK$WXK<1KOONLE+E%_"$WI$S')E#?BD><1N[9YR0QH1K`0C`C3"VHM-AYY*O
M'UD2-F"0OSWA"address@hidden/G-ZIB7TY'8$NT#8`2^,)=(O32_MW(URY[/6B\6LZ
M.O_J5^W[OVKCYQH4B74PX;,address@hidden(Z-=]#85&7V"R1S;M5F3JS/Q/8(NR0
M9>*XO0TM[QK._[6]>IW8_X*ZYP=>`^U_#=^M['\KL?\QVU\W&<"@C64QF8[H
MQ$V6H=3B!A>0Z9I\#[]'R`?"NI2N.6'.(AM-M!^F<G-$1G1J[X-9\O;+S8W:
MR6VTGMRV:WW8*V/3HU8=O/]#,LST8#=^VHL&KXGY$7:N,)F-<+R"P2JN5=UU
M.?V?C-^O^C`R3T<UV`NLM/][7L/S./];#^H!A/IAQ?^NJ/^?/+:_.#I\].C5
MT]VCG[UX;M]_NOLLW/_%R7U[_?[3A[LG^_?7N<'TYVQ??9]9^>[3H6-O.+H<
M)V?G$WMC[X[M.8YC/\(UZ#&SR=B/D"address@hidden/`?Y\*9<+7V#YVT^G
M/;2+;9#:N'_6B_ITDK\CG!0GN7%H(K?Y))S\<Z8U#GW*=XLP,L'RE)G$R*I^
MT-F!T8[8ZR[)^GS0B<=LW(address@hidden/%VR1^WQZVDO:PH0-"Z`1?I.>
MTZ4,7HY%06ZD*8Y/^3*,6RR\+5R%;=#MR-@>CO"J.S;:WG'71U/$+M9E5^:J
address@hidden'8O9']QBGN+N#OM;<&"?F)_>7#R^/#%B;W[["MRLR]WCXYVGYU\
M]2E90.+>/\:-#MD0P8(3S9F0C7$TF)"EXM/]H[W'</address@hidden,G!R=?0?K)71X=
MG#S;/SZV'QT>V;OV\]VCDX.]%T]VC^SG+XZ>'Q[O*X:Z^05*9R92,>-8,0/P
M?*-5AUDCR*R#EBO8*'?0=@&-LDR-H5F$W(NLEDE!?HK^DAD3(B3X`/TML*TD
M]E^^X,\T=9IUI;G76[!VQ66Z_;P7M6-[VSZ>8F3?=[;address@hidden<]W;4=SW7=
M;==WPBUTGM1$<\=A!V9%V*;;9].D0QXK-]O;=,QF=MZ8>==>[-D^=U8=/[:?
M[3[=M]0AWGZYS9H,LP]C$4=3)`;PQA?Q*;7%*/<X_NK9X?/address@hidden/K#7:=R7
M[.'KUM>LH:;V-Q8ILEJM9I-H#_>/]XX.GI_`8$&]#C"Y3*$6\/:*E957TLML
M?K8L:H)1.CI>^4YW!35E*D^"&Q"address@hidden/;`W7K8Q
MI_`D#(0/Q,%'O0'address@hidden'$V*H(*L=;OJW8#,S9*9.UANQ:^."!WLA^E<Q
M*]8H'F*[(`TW(D;N-FU4:-Q)8#?_.!['=(^?3OM0,*(]=Z<#:FV'O$-3$^X5
ML0BK\3J#GH9U-HEL+WEBO;Q50^_&P;.'^[]8DX8%J/DA6CG:N.9Z;;>GQ+9$
M7%-KHV%"B]A&7A>?N7,address@hidden@XW/'!X<address@hidden'!ZMI:.XC<-G>]B#P0O&
M2]A%B\8D+M_=^QG,-R^>/137GT;MUU#2)"=]Y5+8,address@hidden)$]'?=XN[]`
M4^$8=I<3)1ETPR>O)Y4:DQTL\TSS*Q^=/)>7H:6:.)AB*'U^Q<'3W2_VU_B.
MESA8L!5AT^:78#FNH7V6/VH<7=AL"\Y'address@hidden,A'A
M3*(S:C3_J<LOWGN(B:6=BUA\6+JQ"-`X%Q/3-]8:address@hidden<%A*4/CG,+S@
MG?G=L#,K.8>9UJ:"'^SWWZ)9';(Q97FL/7]N'1)W,W=:U0Z(9PY_HW,.?U/7
M'&[`\=/DM)?U*Z"+$`WNHPDQ:$%'20;4?PVM\VC_]U[L'Y\<PT!Q\AP[FVB:
MEFB:*3/QDP9IR[:8:[&L/(F9;FAA^X022&address@hidden)+4!F>8#L-1'=W\BQ!#NC
M1<J3%36WZ_3MB)H7)\,1[X:DZGC[KJ$]HQ]=GK+)EOC+V86]X06,*>SQ=#"'
MJ7J(DXEPDI&'UNR,=9L2%F(XQMN3.,2&address@hidden/$Z(MVE')K'UKZ
MTFWO9??KO:-OU''`=EYVG[],/_&H?0RN)6N$2=SK*2,@L6VB_XVW7)I<:W=@
MO^SNB9O!K3#/'EUG].-HP,<\GE)\P,ON`[<&_X-9$[5GR:070T3Y;'S6::RX
address@hidden:address@hidden/!,3E*2!V1FHNRA4S+'^;G&F]C8K"R)M'K&->1;V)E,+F+
MK2NF8]&6,BYM03,F%OCSRU$\)@`'IF;+RGXF*;^$'2QZ+B>DCCKB[]RE=)"4
M"1/#(address@hidden)address@hidden(S&9Z2]XUH*!B1[
M_2<0OF[]U.7W)@,2;[V87.SB/_5X,)0&SJT0J4;(@(address@hidden<3)I/9T+
MZ:#)$%VHS&-.>8+3&#K,G'9K^(!\V_[R/&9S99)R2(<NU2,^7`^9730B37O[
MA"P`ND<6[A*H&XZX6&;38&]\!I/477U*/K]#5R68?EJ+N`TYI8XVZ,F(%9!;
M,:LN0E;HUE+F)I+U_3$,>D?197^(F-"(KV76\4]J2SF]+"JZ=\;/EQAK3G1Z
M%2V*F,CI[$IG/YY,VAZH;Y&W,BAK"QV,$?$>1LQUJ4[--!:?YW"I,42R@<6W
M6*LCG8>X:6(<'>@6Z70\O(`E<LU^I!2>6"5:PK0\)EX081A>3]_"/K5^/WWK
MU1X?_7[MQ2#9?C@<3_K0G6H/]V'+F[4HK]-)CL<NLD>ODV!NPJZM"]PF:I\G
M\1NY,^P.>SWJXZ#+75IOF3I;-+5\/)VYD4G"L1T0QPG<2#I+N',,VGK*!@)T
MF:';B\V8$0%.8,V*61L,+:PW'"Z(address@hidden;FTN2\9HT!+'-,;$+^6Q?Q<
M.(Q"]^L,T2`835.&'G(F(U/W5GZ>QETQG]X/;N,8'I$)`U8JW>2MW;^D3=%B
M39'N`U]V#W;IY[M0`G1,N$A2OO>`$0IK,B5C-=TXI;PMDPW!MS'V\',8P-LX
MK]!U5HVVA&&[#:MCBSE9(7NG,<T465.(62+C]$P)"P!["[)`3*'AT[U"9HFI
M[`O)TAJ*7"3!2G%MBCL,&-1>OOS%'V"WA;P]SU=#EX");,J%:XF1EFS*L"D<
M\*R3-AP3O(65"7$TD>4DFS=$M4]P5PG;&address@hidden'address@hidden:9B6=6%
MY2C!4>D2<DJF,5C<D8F/=GEQS19;[O#ET2FV#SN.TDLQ&\(R&K9EG:1-QB[R
M*!B.(C$(GS+WTYN$;`F44<Q21C%;?3JI)+Z%9",6NP2Z!AWMH\Z;"(:?,S+,
M\]H1\SCD24PU9,3"P35I6W*.2%A:&1XBVG%F\NH*7(!L!RS6)B;GS&A#;P5U
M'XW2:8\50*PRN[3-;WR&J`#_#N:KW(AJX<[)7N?`#=N%2^PFL]U=MU\NC$.P
M2J&K=,@]CUU3IN^"HA@,&33"B\'J1>A/1E@&.P!CTR)8U:WG)XURF;-842V8
MP<_OL'9G:;)X(FN,I2LZ';Z)B7.5;address@hidden,H.HD\4>W=4:U,U+LL=;,/TP$-`E
address@hidden>D!VS%>%\EF:;ZD0PD;C$F$!/3^>M$:B%4:QDR54#[&69)2N9:OA2`78@
M_`9X$>M_=!B",address@hidden,address@hidden"+<address@hidden
M5>91;Z+>-,[<4BD;W!U99-8D(P9QF>56\W+B1#,"#H"PG2SJ\S`_,>,L3D]T
MEA=+5=+U+=GU<?5Q-H"-38<-]N)KG&63'MDPG?:&address@hidden:?<XAX\+R2-<G
M-%?Y+D,?+O<ON`<4#X#2(N/JY'R*RQO"F[`5"30(9=,address@hidden(Q""W-W<
M>_GRI^[G>$7-(NL:7)G2HH6]B_5.8PJ?X>@H2X86L5SMT%'9DIL7W`CQ_1#)
M!HM.=D'8"<4J#N>*42]J8^E%F!0^:^)]J&V3M%*+=F`Q5=#)NS<<OL:[OB9-
M+\UW9\P?,YB5W\H)"Q/-!OGB'7LZ<HEN7\<ZN1U/VB1I`[$`I/MNS+GP`$N>
M4(RR;)F/>QMLTZ1FL0/@8EXN?91%']O#TZ436R^Q:B9F,+YCQT6_S+3]``VZ
ME(82G1+'0MH$R<0F]A70Q*.>I>Q5#B:D2J&RH(/0-)`QC%84EA<=2>6"ZS0F
M769BH:TI8X7K8\,address@hidden)6D-<VKO,SJW"address@hidden'EISG@@;E
M=B!,AMP6LI@(_=M\A<68M`NT'U,5"6VC>P^/#I]B$R`[)V6!:9$O-,\4B:=9
MCQ!Q3R<XE&"address@hidden"address@hidden&address@hidden
address@hidden@@6'7:COP']V%L#7'B>R9-._0E.BSD\$;:#9L&<ZZ*711[*FW5I4\
M=<9E:]TX&J1\74B&/32?L$&"5`YKCS8;4V@:^8W(0)@;4Z!VV+5S$U"S#_E.
MR,*N2[!_''BQ%++W^&%K"]'UB0-*2>A\J[4RS&-+Y:,TFWDRM88WS2QBCA];
MQ_M[Z*6R'^_O/D3!`%SSLV,"N$DKLFH0E980:I>D0P?WDDA;,W8,,E:2T0`]
MCGH[,I_G:_B0+]A#<"N)address@hidden>NIECLU=,X3IE>
MC:Z186=$_`:X>address@hidden,I&address@hidden&-^"/2<,ZP32V6(*#;(A
ML]+D6S8(=DFN80(A`RW?,VNR0`87&,F(XA`*Y70(>U&R6J*-G5!)*2\Y%(11
MH4(?YH%D4+/VH"F2[>address@hidden>PG*5'TP#9_4K-1J<66`-/Q@'@3L'1X`LC<
MC'9H6M1D/72)UDA2`#``O);[7)Q2L"W13]O/address@hidden&7AO7DX.G!R2XVHV/[
M\!%B%63MQZAU6*V=G3,'),D<:ZJ3,71EW)>AYQ!+![[`D1C&H8MHC,68GE,"
M&address@hidden(&^)7ZJUS)K,9$S-)K3ID,=1C!R*ZCR!#>[!@/A4DS9L"5&E
M",V9>*GDG82TA<4G3AQ:LPEI*]"[T$1]-HY&YRGZ_:F8H#?M#Y"DB`5PP!,#
M8WH/6H=L]-0O)$82BYIER#3(;address@hidden'Y-Y`E49DF9,:E/
M$'XBTNZECI(9X+CMT'K1F\#&8X(N%US#C2]9JR2(.);SD"+9I#31$3-,A3<:
M3^>P>$Y)!&AZ9*V"$_((.8O>)>O[/(1<address@hidden'[3FEI4K_(/I:G"81[*;H
M-=.#1I,VW,6^NXW[B^?/K9/3GA3+W6:4-Y:0G`?H.I%LJE+%2G)*AV]N;H..
MUT^HXHCZYAX=/-D_MNX_W=T[.GQX<'1_1UJ!2/CZ\?Z^O?OD^!#6F`^.N/D;
MR2$7R:$[6^3K^V?W)_D0?CVI_FP,U(/"O7=?X$$AEHH#";address@hidden(4'+[XX
MMHX41<)D**+-\NTSW]2X6)&@([A:F1`4NX?X-H>3N8F1C*X75!G(5XM86W21
address@hidden,\HK",O6='/"*FXHHM44XWE9K7\%ZN+'?SG%3GWL7:^8O[7]>J,
M_PL]/*$%^;]ZX%3\WRI^=G;L[<UMHM"$W];address@hidden<UNMUKMP/GL3_K/?1?#9
M%V/<0S(->[M-XB"`!H,G;%P(23&%5434QVD'.PDJA>C8AVL-]!*2/3V)address@hidden
M[(VLLN`.]JY1NC-*X2DB=6H#Y]]!1\6C7LA2*($-8T*F"FDUQZ'@-!DPM(!,
M`;@[('.1O;ECP0];`RO17^'>W_Z-99/[V)N(-'TJ/E%+\2LR,)+DB""Q$$`P
MT/KN4W)S`CG,>X;address@hidden@93B]W]P\.7ZS#Y]MW
M;address@hidden;Q6GOK4MY#<39FHW3AO5<KQ?)N-&<Y[V\?3L?EQQ<
MPV,^>_'D";F`_2&>NH'%<L?!F%@<%:N]S/%?=,O5G__B>@T^_M?=>H.,_Q!>
MC?_5^'^%X[_Z7'7PI[8^<H0"@EJ<'*+HVQA^DST%.BOIQH%8Y\E=8/S?V;2*
M>'3KBCCT*V'0KX0_%^RY=67,^0_GS:^&-9_ES*VKXLNOABV_"JZ<M-J?<(_<
address@hidden':N?KRG?47P^]*4VS`6TDB^$;^=5GN/FMG7^N7$2Z![VHVXF[]N/=G^^_
M>O'LX/CDX:O'2LSI`)I-A\1%8K5+(address@hidden@ZCC9.C%_MWK)_`]$"_L?$+V]YP
M[]US[_`HF1B/8#^:C4*^(5$<$85T6>S]Q`B->60F#11K#SL4A:>CP2LV!O2C
M03*:TG49[?69\+MW,Q\W<.]L;address@hidden;L[VNC>P8,K>AL._.Y';U^A
MH>)5+QZ<3<XW!O`=#B^O"!]#+B$0QBO"N\)GZS?6=[F'VK?R:address@hidden<=C
M)!N>#.O!+EEA#GOPIX-_CF-B`]M$&_>address@hidden)WQPRV\8ZPNX6&
MN+'1AD><Q9/V!KGFCOWC>_;^X:,[1+H-]VIOM"%KHSL+)`(JCY39!GMR%Q:'
MD"-X@'.'+'C9`VZ_'-P6S\CDVE;*F'_WG7E"&%BS06Q6?$E/$V5Z)_H1Q>$Q
M5+/FAIE<SLEC%[Y*-]8_^_'VMKV>^S;-7V5O;W_^<B`O4XIGMG`,LW,:GR6#
MU>2&)KMN?X(;(^A$&^FB38HG5Z90ED.V7=DRD=^MID!9VEY%XS-M<2+X#]/D
M/;40E&+^A(1^8KOVY_D1A^>,9>+E0"EKG@<address@hidden;VR8
MQ"3A:#R>;`SLSZ'([%NW[(']&23%H:U`QH'T#19X,OSS"A:29-=-]I9VFSXW
M-S9!%C_YY$KJ$)](I]-L%8K)@==D<L\AM<=&address@hidden)[8WTZ^0;I8X2FK[O
M9'TL6A[2^:!-Z-P48H*P*[,].D\MMCX:=LMVWH;=._8]:*#PF5\P)T/?S<E6
M<H6%_LZ\W'[IW#8L]CGIH_8:8G'RH,FF$PJ#*$8A88V2EB%Y'0M`$U#6`C1[
MQU%*+H:1;,#/_5*-0)]LKZ,U!ZYPPW"=6%+(]_&O\?M[Z]S4PK_O3_GUGEN7
MUZ-E1K'/<(L,7TQQH!Z/3;G`13ZLEMNOF=%;==>(UD;=/address@hidden,address@hidden)6LR
MM&;O18S[XX=.)<1[P656%!F%RDQ_A^WN<!5'%^X7RC%3<.F(;M:8AS(9T-.M
MR`9+FM_(;7;*]1]8U+-*L$NV-UV=)=_41)/`MHAEK78J:address@hidden'X7?%)EW.
MD?U-Z0YSHN8:'FOL^79-NJD=]V!3PV_-^@/M$=]9F6<M-"=C?'JZI#HMD#(Y
MG7:_=F'*.7AV\NKAP1<')\<X_WR##TG)X8W=#;@$&N\?Z4"['9"GS\R1<`4)
M4-))(D'8G9D!WUTP`]W>,)IL=(93-!=W\EGPFM^0MI!+="WH0K([2TMVF3'S
LLG\Z[)FN-4HLF)09M7A%42XOE<VV^JE^JI_JI_JI?G[HS_\/#=H^L`"address@hidden
`
end



reply via email to

[Prev in Thread] Current Thread [Next in Thread]