#!/usr/bin/perl -w

use CGI qw(:standard -debug);
use Cwd;

$MY_NAME	= "Randall Murphy";
$MY_ADDR	= "webmaster";

$LOCK_EX	= 2;
$LOCK_UN	= 8;

%list = ("INDI" => \%indi, "FAM" => \%fam, "NOTE" => \%note, "SOUR" => \%source, "HEAD" => \@head, "SUBM" => \%subm);

@time = localtime (time);
$gen{'year'} = 1900 + $time[5];

$HTTP_HOST = (defined ($ENV{'HTTP_HOST'})) ? $ENV{'HTTP_HOST'} : "www.secondserve.net";
if (defined ($ENV{'SERVER_NAME'})) {
    $DOMAIN = $ENV{'SERVER_NAME'};
}
else {
    ($DOMAIN = $HTTP_HOST) =~ s/^www\.//;
}

$PATH = "";

if (defined ($ENV{'SCRIPT_NAME'})) {
    $gen{'progpath'} = $ENV{'SCRIPT_NAME'};
}
else {
    if (($gen{'progpath'} = $0) !~ m/^\//) {
        $pwd .= "/"  if (($pwd = cwd()) !~ m/\/$/);
        $gen{'progpath'} = $pwd . $gen{'progpath'};
    }
    while ($gen{'progpath'} =~ s/^\.\///) {
    }
    while ($gen{'progpath'} =~ s/\/\.\//\//) {
    }
    while ($gen{'progpath'} =~ s/[^\.\/]+\/+\.\.\///) {
    }
    if (0 < ($idx = index ($gen{'progpath'}, "/cgi-bin"))) {
        $gen{'progpath'} = substr ($gen{'progpath'}, $idx);
    }
}
($gen{'progname'} = $gen{'progpath'}) =~ s/.*\///;

if (defined ($ENV{'DOCUMENT_ROOT'})) {
    $filepath = $ENV{'DOCUMENT_ROOT'};
#    $filepath =~ s/\/public_html.*$//;
}
elsif (defined ($ENV{'SITE_HTMLROOT'})) {
    $filepath = $ENV{'SITE_HTMLROOT'};
}
else {
    if (defined ($ENV{'SCRIPT_FILENAME'})) {
        $filepath = $ENV{'SCRIPT_FILENAME'};
    }
    elsif (($filepath = $0) !~ m/^\//) {
        $pwd .= "/"  if (($pwd = cwd()) !~ m/\/$/);
        $filepath = $pwd . $filepath;
        while ($filepath =~ s/^\.\///) {
        }
        while ($filepath =~ s/\/\.\//\//) {
        }
        while ($filepath =~ s/\.?[^\.\/]+\/+\.\.\///) {
        }
    }
    if (-1 < ($idx = index ($filepath, "/cgi-bin"))) {
        $filepath  = substr ($filepath, 0, $idx);
#        $filepath .= "/html";
    }
    elsif (-1 < ($idx = rindex ($filepath, "/"))) {
        $filepath = substr ($filepath, 0, $idx);
    }
    else {
        $filepath = "";
    }
}
$filepath = substr ($filepath, 0, -1)  if ($filepath =~ m/\/$/);

$gen{'cfg_dir'} = "$PATH/cfg";

if (open (CONFIG, "$filepath$gen{'cfg_dir'}/$gen{'progname'}.cfg")) {
    $parm = "";
    while (defined ($record = <CONFIG>)) {
        chomp ($record);
        if ("#" ne substr ($record, 0, 1)) {
            if ($record =~ s/^\s+(.+?)$/$1/) {
                $config{$parm} .= "\n" . $record  if ($parm);
            }
            else {
                @record = split(/\s*=\s*/, $record, 2);
                if (1 < @record && $record[0]) {
                    $config{$parm = lc ($record[0])} = $record[1];
                    $origcfg{$parm} = 1;
                }
                else {
                    $parm = "";
                }
            }
        }
    }
    close (CONFIG);
}
if (defined ($config{'cfg_dir'}) && "" ne $config{'cfg_dir'}) {
    $gen{'cfg_dir'} = $config{'cfg_dir'};
}

$PUBLIC = $Public = $GED = $Config = $View = $Type = "";
$HELP = $Help = $DEBUG = $Debug = "";
$ID = $Name = $Title = $NumGen = $Cols = "";
if (param()) {
    foreach $parm (param()) {
        if ("public" eq lc ($parm)) {
            $PUBLIC	= $parm;
            $Public	= param("$parm")  if (param("$parm"));
        }
        $Config	= param("$parm")  if ("config"	eq lc ($parm) && param("$parm"));
        $ID	= param("$parm")  if ("ID"	eq uc ($parm) && param("$parm"));
        $Name	= param("$parm")  if ("name"	eq lc ($parm) && param("$parm"));
        $Title	= param("$parm")  if ("title"	eq lc ($parm) && param("$parm"));
        $View	= param("$parm")  if ("view"	eq lc ($parm) && param("$parm"));
        $Type	= param("$parm")  if ("type"	eq lc ($parm) && param("$parm"));
        $NumGen	= param("$parm")  if ("numgen"	eq lc ($parm) && param("$parm"));
        $Cols	= param("$parm")  if ("cols"	eq lc ($parm) && param("$parm"));
        $GED	= param("$parm")  if ("ged"	eq lc ($parm) || "gedcom" eq lc ($parm) && param("$parm"));
        $GED	= param("$parm")  if ("surname"	eq lc ($parm) && param("$parm") && "" eq $GED);
        if ("help" eq lc ($parm)) {
            $HELP	= $parm;
            $Help	= param("$parm")  if (param("$parm"));
        }
        if ("debug" eq lc ($parm)) {
            $DEBUG	= $parm;
            $Debug	= param("$parm")  if (param("$parm"));
        }
    }
}

$seperator = "?";
$urlparms = $idxparms = "";
if ($PUBLIC) {
    $urlparms .= $seperator . "Public";
    $urlparms .= "=" . $Public  if ($Public);
    $seperator = "&amp;";
}

$cfg = $gen{'family'} = "murphy";
if ($Config) {
    $cfg = lc ($Config);
    if (-e "$filepath$gen{'cfg_dir'}/$cfg.cfg") {
        $gen{'family'} = $cfg;
    }

    $urlparms .= $seperator . "Config=" . $Config;
    $seperator = "&amp;";
}
elsif ($GED) {
    $cfg = lc ($GED);
}
$gen{'cfg'} = $cfg;

@cfg = ();
while (1 > @cfg || $cfg ne $cfg[@cfg - 1]) {
    for ($i = 0; $i < @cfg && $cfg ne $cfg[$i]; $i++) {
    }
    $cfg[$i++] = $cfg;
    $file = $filepath . $gen{'cfg_dir'} . "/" . $cfg . ".cfg";
    if ($i == @cfg && open (CONFIG, $file)) {
        $parm = "";
        while (defined ($record = <CONFIG>)) {
            chomp ($record);
            if ("#" ne substr ($record, 0, 1)) {
                if ($record =~ s/^\s+(.+?)$/$1/) {
                    $config{$parm} .= "\n" . $record  if ($parm);
                }
                else {
                    @record = split(/\s*=\s*/, $record, 2);
                    if (1 < @record && $record[0]) {
                            $config{($parm = lc ($record[0]))} = $record[1];
                            $origcfg{$parm} = 0;
                            $cfg = lc ($record[1])  if ("config" eq $parm);
                    }
                    else {
                        $parm = "";
                    }
                }
            }
        }
        close (CONFIG);
    }
}

if ($GED) {
    $gen{'family'} = lc ($GED);
    $urlparms .= $seperator . "GED=" . $GED;
    $seperator = "&amp;";
}
elsif (defined ($config{'ged'})) {
    $gen{'family'} = lc ($config{'ged'});
}
elsif (defined ($config{'gedcom'})) {
    $gen{'family'} = lc ($config{'gedcom'});
}

if ($gen{'family'} ne $gen{'cfg'}) {
    $file = $filepath . $gen{'cfg_dir'} . "/" . $gen{'family'} . ".cfg";
    if (open (CONFIG, $file)) {
        $parm = "";
        while (defined ($record = <CONFIG>)) {
            chomp ($record);
            if ("#" ne substr ($record, 0, 1)) {
                if ($record =~ s/^\s+(.+?)$/$1/) {
                    $config{$parm} .= "\n" . $record  if ($parm);
                }
                else {
                    @record = split(/\s*=\s*/, $record, 2);
                    if (1 < @record && $record[0] && (! defined ($config{lc ($record[0])}) || (defined ($origcfg{lc ($record[0])}) && $origcfg{lc ($record[0])} > 0))) {
                        $config{($parm = lc ($record[0]))} = $record[1];
                    }
                    else {
                        $parm = "";
                    }
                }
            }
        }
        close (CONFIG);
    }
}
if (! defined ($config{'e-mail'})) {
    if (defined ($ENV{'SERVER_ADMIN'})) {
        $config{'e-mail'} = $ENV{'SERVER_ADMIN'};
    }
    else {
        $config{'e-mail'} = 'genealogy@secondserve.net';
    }
}
$sepidx = $seperator;
if ($ID) {
    $idxparms .= $sepidx . "ID=" . $ID;
    $sepidx = "&amp;";
}
if ($Name) {
    ($name = $Name) =~ s/\s+/\+/g;
    $idxparms .= $sepidx . "Name=" . $name;
    $sepidx = "&amp;";
}
if ($View) {
    ($name = $View) =~ s/\s+/\+/g;
    $idxparms .= $sepidx . "View=" . $name;
    $sepidx = "&amp;";
}
if ($Title) {
    ($name = $Title) =~ s/\s+/\+/g;
    $idxparms .= $sepidx . "Title=" . $name;
    $sepidx = "&amp;";
}
if ($Cols) {
    $idxparms .= $sepidx . "Cols=" . $Cols;
    $sepidx = "&amp;";
}

if (defined ($config{'ged_dir'}) && "" ne $config{'ged_dir'}) {
    $gen{'ged_dir'} = $config{'ged_dir'};
}
else {
    $gen{'ged_dir'} = "$PATH/ged";
}
$file = $filepath . $gen{'ged_dir'} . "/" . $gen{'family'} . ".ged";
if (open (GEDCOM, $file)) {
flock (GEDCOM, $LOCK_EX);

@ident_pri = @ident_sec = ();
if ($Name) {
    ($match = lc ($Name)) =~ s/\s+/.*\\s+.*/g;
}
elsif (defined ($config{'index'}) && $config{'index'}) {
    ($match = lc ($config{'index'})) =~ s/\s+/.*\\s+.*/g;
}

#
# Build "INDI", "FAM", "NOTE", "SOUR", "SUBM", & "HEAD" lists from GEDCOM file.
#

$ident = $index = ""; $count = 0;
while (defined ($record = <GEDCOM>)) {
    chomp ($record);
    $record =~ s/^\s*//;
    @record = split(/\s+/, $record, 3);
    if (@record > 1 && ($lvl = $record[0]) == 0) {
        if (@record > 2 && $record[2]) {
            if ($record[1] =~ m/^\@\S+?\@$/) {
                if (! defined ($list{$head = uc ($record[2])})) {
                    $list{$head} = {};
                }
                $list{$head}->{$index = $record[1]} = [];
                $list{$head}->{$index}->[0] = $index;
                $contptr[0] = $list{$head}->{$index};
            }
            else {
                $record[2] =~ s/\@\@/\@/g;
                if (! defined ($list{$head = uc ($record[1])})) {
                    $list{$head} = [];
                }
                $list{$head}->[0] = $record[2];
                $contptr[0] = $list{$head};
            }
        }
        else{
            if (! defined ($list{$head = uc ($record[1])})) {
                $list{$head} = [""];
            }
            else {
                $list{$head}[0] = "";
            }
            $contptr[0] = $list{$head};
        }
        $contid[0] = 1;
    }
    elsif (defined ($head) && @record > 1) {
        $ptr1 = $contptr[$lvl - 1];
        $listid = $contid[$lvl - 1];
        if (@record > 2 && $record[2]) {
            if ("CONT" eq uc ($record[1])) {
                $record[2] =~ s/\@\@/\@/g;
                $ptr1->[@$ptr1] = $record[2];
            }
            elsif ("CONC" eq uc ($record[1])) {
                $record[2] =~ s/\@\@/\@/g;
                if (@$ptr1 == 1 && $ptr1->[0] =~ m/^\@\S+?\@$/) {
                    $ptr1->[@$ptr1] = $record[2];
                }
                else {
                    $ptr1->[@$ptr1 - 1] .= $record[2];
                }
            }
            else {
                if (! defined ($ptr1->[$listid]->{$record[1]})) {
                    $ptr1->[$listid]->{$record[1]} = [];
                }
                $ptr = $ptr1->[$listid]->{$record[1]};
                if (! ($record[2] =~ m/^\@\S+?\@$/)) {
                    $record[2] =~ s/\@\@/\@/g;
                    if ($lvl == 1 && $head eq "INDI" && "NAME" eq uc ($record[1])) {
                        $record[2] =~ s/\s+/ /g;
                        @name = split (/\s*\//, $record[2], 3);
                        if (! defined ($surname{$name[1]})) {
                            $surname{$name[1]} = {};
                        }
                        $name = $name[0];
                        $name = "?"  if ($name =~ m/^\s*$/);
                        if (@name > 2) {
                            $name .= $name[2];
                        }
                        if (! defined ($surname{$name[1]}->{$name})) {
                            $surname{$name[1]}->{$name} = [];
                        }
                        $ptrname =  $surname{$name[1]}->{$name};
                        $ptrname->[@$ptrname] = $index;
                        $count++;
                        ($name = lc ($record[2])) =~ s/\///g;
                        if ($Name) {
                            if (lc ($Name) eq $name) {
                                $ident_pri[@ident_pri] = $index;
                                $ident = $index  if ("\@$ID\@" eq $index);
                            }
                            elsif ($name =~ m/$match/) {
                                $ident_sec[@ident_sec] = $index;
                                $ident = $index  if ("\@$ID\@" eq $index);
                            }
                        }
                        elsif (! $ID && defined ($config{'index'})) {
                            if (lc ($config{'index'}) eq $name) {
                                $ident_pri[@ident_pri] = $index;
                                $ident = $index  if (defined ($config{'index_id'}) && "\@$config{'index_id'}\@" eq $index);
                            }
                            elsif ($name =~ m/$match/) {
                                $ident_sec[@ident_sec] = $index;
                                $ident = $index  if (defined ($config{'index_id'}) && "\@$config{'index_id'}\@" eq $index);
                            }
                        }
                    }
                }
                $ptr->[int ((@$ptr + 1) / 2) * 2] = $record[2];
                $contptr[$lvl] = $ptr;
                $contid[$lvl]  = @$ptr;
            }
        }
        else {
            if ("CONT" eq uc ($record[1])) {
                $ptr1->[@$ptr1] = "";
            }
            else {
                if (! defined ($ptr1->[$listid]->{$record[1]})) {
                    $ptr1->[$listid]->{$record[1]} = [];
                }
                $ptr = $ptr1->[$listid]->{$record[1]};
                $ptr->[int ((@$ptr + 1) / 2) * 2] = "";
                $contptr[$lvl] = $ptr;
                $contid[$lvl]  = @$ptr;
            }
        }
    }
}
flock (GEDCOM, $LOCK_UN);
close (GEDCOM);

foreach $familyid (keys (%fam)) {
    if (exists ($fam{$familyid}->[1]->{"CHIL"})) {
        $childptr = $fam{$familyid}->[1]->{"CHIL"};
        for ($i = 0; $i < @$childptr; $i += 2) {
            $child1 = $childptr->[$i];
            if (defined ($indi{$child1}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                if (($year1 = format_year ($indi{$child1}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) && $year1 ne "Unknown") {
                    for ($k = $i; $k < @$childptr; $k += 2) {
                        $child2 = $childptr->[$k];
                        if (defined ($indi{$child2}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                            if (($year2 = format_year ($indi{$child2}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) && $year2 ne "Unknown") {
                                if ($year1 > $year2) {
                                    $childinfo = $childptr->[$k+1];
                                    $childptr->[$k+1] = $childptr->[$i+1];
                                    $childptr->[$i+1] = $childinfo;
                                    $childptr->[$k] = $child1;
                                    $childptr->[$i] = $child2;
                                    $child1 = $child2;
                                    $year1 = $year2;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
if (! $ident) {
    if (1 == @ident_pri) {
        $ident = $ident_pri[0];
    }
    elsif (1 == @ident_sec) {
        $ident = $ident_sec[0];
    }
    elsif ($ID) {
        $ident = "\@$ID\@";
    }
    elsif (defined ($config{'index_id'})) {
        $ident = "\@$config{'index_id'}\@";
    }
}

$view = "";
if ("tree" eq lc ($View) || "index" eq lc ($View)) {
    if ($Type) {
        $view  = lc ($Type) . " ";
    }
    elsif ("tree" eq lc ($View)) {
        $view = "ancestor ";
    }
    $view .= lc ($View);
}
elsif ($View) {
    $view = lc ($View);
}
elsif (! $Name && ! $ID) {
    $view = "index"  if (defined ($config{'index'}));
}

$title = "";
if ($Title) {
    $title = $Title;
}
elsif (defined ($config{'title'}) && ! $Name && ! $ID) {
    $title = $config{'title'};
}

$gen{'title'} = $title1 = $link = "";
if ($DEBUG || $HELP) {
    $title = ucfirst ($gen{'progname'});
    if ($DEBUG) {
        $title1 = "Debug Information";
    }
    else {
        $title1 = "Usage Information";
    }
}
elsif ($ident && exists ($indi{$ident}->[1]->{"NAME"})) {
    $groups = 0;
    if ($view) {
        %group = ();
        if ($view eq "ancestor tree" || $view eq "descendent tree") {
            ($title = $view) =~ s/(\w+)/\u\L$1/g;
            ($name = $indi{$ident}->[1]->{"NAME"}->[0]) =~ s/\///g;
            $title .= " - " . $name;
        }
        elsif ($view eq "index" || $view eq "ancestor index" || $view eq "descendent index") {
            %surname = ();
            $count = 0;
            if ($NumGen) {
                $numgen = ("all" eq lc ($NumGen)) ? -1 : $NumGen;
            }
            else {
                $numgen = -1;
            }
            if ($view ne "descendent index") {
                if ($view eq "ancestor index") {
                    index_ancestor ($ident, $numgen, 1);
                }
                else {
                    index_ancestor ($ident, $numgen, 2);
                    index_descendent ($ident, 1);
                }
            }
            else {
                index_ancestor ($ident, $numgen, 0);
                index_descendent ($ident, 0);
            }

            unless ($title) {
                ($title = $indi{$ident}->[1]->{"NAME"}->[0]) =~ s/\///g;
                ($idx = $ident) =~ s/\@//g;
                $link = $gen{'progpath'} . $urlparms . $seperator . "ID=$idx";
                if ($view eq "index") {
                    $title1 = "Family Index";
                }
                else {
                    ($title1 = $view) =~ s/(\w+)/\u\L$1/g;
                }
            }
        }
        $groups = scalar (keys (%group));
    }
    unless ($title) {
        ($name = $indi{$ident}->[1]->{"NAME"}->[0]) =~ s/\///g;
        ($title = $gen{'family'}) =~ s/(\w+)/\u\L$1/g;
        $title .= " Family Index";
        $title .= " - \"" . $name . "\"";
    }
}
elsif ($Name || (defined ($config{'index'}) && "" ne $config{'index'}) || (@ident_pri || @ident_sec)) {
    $title = "Search Results";
}
else {
    unless ($title) {
        $title = ucfirst ($gen{'family'});
        $title .= " Family Index";
        $groups = scalar (keys (%fam));
    }
}
print "Content-Style-Type: text/css\n";
print header;
if ($config{'doctype'}) {
    print "$config{'doctype'}\n";
}
print <<EOF_HTML;
<html>
<head>
EOF_HTML

print "<title>$title";
print " $title1"  if ($title1);
print "</title>\n";
print "<meta name=\"Robots\" content=\"";
if ((! $ident && (@ident_pri || @ident_sec)) || ($ident && ($view eq ""  || $view eq "ancestor tree" || $view eq "descendent tree")) || $HELP || $DEBUG) {
    print "none\" />\n";
}
else {
    print "index, nofollow\" />\n<meta name=\"description\" content=\"View an index of all the names in our family tree as well as individual records.\" />\n";
    $unknown = "(unknown)";
    @name = sort (sort_file (keys (%surname)));
    while (($holdname = shift (@name)) =~ m/^\s*$/ || $holdname =~ m/^\W/) {
        $ptr = $surname{$holdname};
        unless (exists ($surname{$unknown})) {
            $surname{$unknown} = {};
        }
        $unkptr = $surname{$unknown};
        foreach $given (keys (%$ptr)) {
            $unkptr->{$given} = []  if (! defined($unkptr->{$given}));
            $nameptr = $unkptr->{$given};
            $idptr = $ptr->{$given};
            for ($i = 0; $i < @$idptr; $i++) {
                $nameptr->[@$nameptr] = $idptr->[$i];
            }
        }
    }
    print "<meta name=\"keywords\" content=\"genealogy, surname, family, tree, history, research, $holdname";
    foreach $name (@name) {
        print ", $name";
    }
    print "\" />\n";
}

print "<base href=\"http://$HTTP_HOST\" />\n";
if (($main = $HTTP_HOST) =~ s/genealogy\.//i) {
    print "<link rel=\"stylesheet\" type=\"text/css\" href=\"http://";
    print $main;
    print "/standard.css\" />\n";
}
print "<link rel=\"stylesheet\" type=\"text/css\" href=\"$PATH/standard.css\" />\n";
if (defined ($config{'css_url'}) && $config{'css_url'}) {
    foreach $style (split (/\n|\0/, $config{'css_url'})) {
        print "<link rel=\"stylesheet\" type=\"text/css\" href=\"$style\" />\n";
    }
}
print "<script language=\"JavaScript\" src=\"$config{'jscript_url'}\"></script>\n"  if (defined ($config{'jscript_url'}) && $config{'jscript_url'});

$style = "";
print "</head>\n\n<body";
if ((! $ident && (@ident_pri || @ident_sec)) || ($ident && ($view eq ""  || $view eq "ancestor tree" || $view eq "descendent tree")) || $HELP || $DEBUG) {
    print " class=\"sans-serif\"";
    $style .= "margin: 12px; ";
}
if ((defined ($config{'bg_color'}) && $config{'bg_color'}) || (defined ($config{'bg_image'}) && $config{'bg_image'})) {
    $style .= "background:";
    $style .= " " . $config{'bg_color'}  if (defined ($config{'bg_color'}) && $config{'bg_color'});
    $style .= " url(". $config{'bg_image'} . ")"  if (defined ($config{'bg_image'}) && $config{'bg_image'});
    $style .= "; ";
}
$style .= "color: " . $config{'text_color'} . "; "  if (defined ($config{'text_color'}) && $config{'text_color'});
print " style=\"$style\""  if ($style);
print ">\n";

if ($DEBUG) {
    print "<h1 style=\"text-align: center;\">$title<br /><small>$title1</small></h1>\n";
    $sep = ""; $col = 0;
    print "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"table-layout: auto;\">\n<tr valign=\"top\">\n<td>\n";
    if (! $Debug || lc ($Debug) =~ m/env|all/) {
        print "$sep<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"table
-layout: auto;\">\n<tr><th align=\"center\" colspan=\"3\"><big>Environment</big></th></tr><tr><td style=\"height: 8px;\" colspan=\"3\"></td></tr>\n";
        $pre = "";
        foreach $parm (sort (sort_file (keys (%ENV)))) {
            print "$pre<tr valign=\"baseline\">\n<th align=left>$parm</th><th>&nbsp;=&gt;&nbsp;</th><td>$ENV{$parm}</td>\n</tr>";
            $pre = "<tr><td style=\"height: 8px;\" colspan=\"3\"></td></tr>";
        }
        print "\n</table>\n";
        $sep = "</td><td style=\"width: 32px; white-space: nowrap;\">&nbsp; &nbsp;</td><td>\n";
        ++$col;
    }
    if (! $Debug || lc ($Debug) =~ m/var|all/) {
        print "$sep<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"table
-layout: auto;\">\n<tr><th align=\"center\" colspan=\"3\"><big>Variables</big></th></tr><tr><td style=\"height: 8px;\" colspan=\"3\"></td></tr>\n";
        $pre = "";
        foreach $parm (sort (sort_file (keys (%gen)))) {
            print "$pre<tr valign=\"baseline\">\n<th align=\"left\">$parm &nbsp;</th><th>&nbsp;=&gt;&nbsp;</th><td>$gen{$parm}</td>\n</tr>";
            $pre = "<tr><td style=\"height: 8px;\" colspan=\"3\"></td></tr>";
        }
        print "\n</table>\n";
        $sep = "</td><td style=\"width: 32px; white-space: nowrap;\">&nbsp; &nbsp;</td><td>\n";
        ++$col;
    }
    if ($col) {
        $sep = "</td><tr><td style=\"height: 24px;\" colspan=\"" . int ($col + $col - 1) . "\">&nbsp;</td></tr><tr valign=\"top\"><td colspan=\"" . int ($col + $col - 1) . "\">\n";
    }
    if (! $Debug || lc ($Debug) =~ m/c(on)?fi?g|all/) {
        print "$sep<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr><th align=\"center\" colspan=\"3\"><big>Config</big></th></tr><tr><td style=\"height: 8px;\" colspan=\"3\"></td></tr>\n";
        $pre = "";
        foreach $parm (sort (sort_file (keys (%config)))) {
            ($temp = $config{$parm}) =~ s/\&/\&amp\;/g;
            $temp =~ s/\</\&lt\;/g;
            $temp =~ s/\>/\&gt\;/g;
            while ($temp =~ s/  /\&nbsp\; /) {
            }
            $temp =~ s/\n/\\n/g;
            $temp =~ s/\0/\n/g;
            print "$pre<tr valign=\"baseline\">\n<th align=\"left\">$parm</th><th>&nbsp;=&gt;&nbsp;</th><td>$temp</td>\n</tr>";
            $pre = "<tr><td style=\"height: 8px;\" colspan=\"3\"></td></tr>";
        }
        print "\n</table>\n";
        $sep = "</td><td style=\"white-space: nowrap; width: 32px;\">&nbsp; &nbsp;</td><td>\n";
    }
    print "</td>\n</tr>\n</table>\n";
}
elsif ($HELP) {
    print "<h1 style=\"text-align: center;\">$title<br /><small>$title1</small></h1>\n";
    $sep = "";
    if (! $Help || lc ($Help) =~ m/ur[il]|para?m|all/) {
        print $sep;
        $sep = "<br />\n";
        print <<EOF_HTML;
<p><big><strong>URI Parameters</strong></big></p>
<ul>
<li><p><strong>Config</strong> - Name of the configuration file to use.&nbsp; The parameters in the configuration file will be used to specify default parameters.&nbsp; The default parameters can be overridden by specifying any of the following parameters in the URI.&nbsp; The parameters read from the specified configuration file are in addition to, and will override, the parameters from the configuration file for the particular GEDCOM file that is being used.</p></li>
<li><p><strong>GED</strong> - Name of the GEDCOM database file that contains the genealogy information to be displayed.</p></li>
<li><p><strong>Name</strong> - Name of an individual contained in the database.&nbsp; If there is no single exact match or there is more than one individual that patially matches, a list of the individuals will be displayed.</p></li>
<li><p><strong>ID</strong> - Identifier of an individual contained in the database.&nbsp; This parameter uniquely identifies a specific individual in the GEDCOM file.&nbsp; (Do not include the delimiting &quot;\@&quot; characters in the ID.)</p></li>
<li><p><strong>View</strong> - Specifies the information that will be displayed.&nbsp; The following values are allowed:</p></li>
<ul>
<li><p>Index - If <strong><em>Type</em></strong> <small>(see below)</small> is not specified, a complete index of all individuals in the family, including their spouses and siblings, is displayed.&nbsp; If no individual was identified, via <strong><em>Name</em></strong> or <strong><em>ID</em></strong>, a complete index of all individuals in the database is displayed.&nbsp; (This is the default if <strong><em>View</em></strong> is not specified.)</p></li>
<li><p>Tree - If <strong><em>Type</em></strong> <small>(see below)</small> is not specified, the default is to display an ancestor tree of all individuals in the family.&nbsp; If no individual was identified, via <strong><em>Name</em></strong> or <strong><em>ID</em></strong>, an index is diplayed instead.</p></li>
<p><strong>Type</strong> - If <strong><em>View</em></strong> is set to <em>Index</em> or <em>Tree</em>, the view may be further classified by setting <strong><em>Type</em></strong> to one of the following:</p></li>
<ul>
<li><p>Ancestor - Specifies that all ancestors of the identified individual are to be displayed in the tree or index view.</p></li>
<li><p>Descendent - Specifies that all descendents of the identified individual are to be displayed in the tree or index view.</p></li>
</ul>
<li><p>Ancestor Index - Specifies that all ancestors of the identified individual are to be displayed in the index.&nbsp; This is identical to specifying <strong><em>View</em></strong>=<em>Index</em> and <strong><em>Type</em></strong>=<em>Ancestor</em>.</p></li>
<li><p>Descendent Index - Specifies that all descendents of the identified individual are to be displayed in the index.&nbsp; This is identical to specifying <strong><em>View</em></strong>=<em>Index</em> and <strong><em>Type</em></strong>=<em>Descendent</em>.</p></li>
<li><p>Ancestor Tree - Specifies that all ancestors of the identified individual are to be displayed in the tree.&nbsp; This is identical to specifying <strong><em>View</em></strong>=<em>Tree</em> and <strong><em>Type</em></strong>=<em>Ancestor</em>.</p></li>
<li><p>Descendent Tree - Specifies that all descendents of the identified individual are to be displayed in the tree.&nbsp; This is identical to specifying <strong><em>View</em></strong>=<em>Tree</em> and <strong><em>Type</em></strong>=<em>Descendent</em>.</p></li>
</ul>
<li><p><strong>Title</strong> - Title to be used when displaying the information.&nbsp; If not specified, a default title is displayed.&nbsp; (The default is generated based on the particular view being displayed.</p></li>
<li><p><strong>NumGen</strong> - Number of generations of ancestors and/or descendents to include in the tree or index.&nbsp; (The default is <em>All</em>.)</p></li>
<li><p><strong>Cols</strong> - Number of columns that will be displayed in an index view.&nbsp; (Only valid for an index view.&nbsp; The default is <em>2</em>.)</p></li>
</ul>
EOF_HTML
    }
    if (! $Help || lc ($Help) =~ m/c(on)?fi?g|all/) {
        print $sep;
        $sep = "<br />\n";
        print <<EOF_HTML;
<p><big><strong>Configuration Parameters</strong></big></p>
<ul>
<li><p><strong>Config</strong> - Name of another configuration file used to specify default parameters not specified in this file.&nbsp; Those parameters do not override any parameters read from a previously specified configuration file, including this one.</p></li>
<li><p><strong>GED</strong> - Name of the GEDCOM database file that contains the genealogy information to be displayed.</p></li>
<li><p><strong>Index</strong> - Name of an individual contained in the database.&nbsp; An index will be displayed containing this individuals complete index of ancestors and descendents, including their spouses and siblings.&nbsp; If there is no single exact match or there is more than one individual that patially matches, the <strong><em>Index_ID</em></strong> parameter may be specified to further identify the correct individual.</p></li>
<li><p><strong>Index_ID</strong> - Identifier of an individual contained in the database.&nbsp; This parameter is used, in conjuction with the <strong><em>Index</em></strong> parameter, to uniquely identify a specific individual in the GEDCOM file when the <strong><em>Index</em></strong> parameter is not enough to identify a single individual.&nbsp; (Do not include the delimiting &quot;\@&quot; characters in the ID.)</p></li>
<li><p><strong>Title</strong> - Text to be used for the Title information being displayed.&nbsp; If not specified, a default title is displayed.&nbsp; (The default is generated based on the particular view being displayed.&nbsp; (See also, <strong><em>Title</em></strong> under &quot;<strong>URI Parameters</strong>&quot; above.)</p></li>
<li><p><strong>Doctype</strong> - HTML tag to be placed immediately following the HTTP headers and before the '<html>' start tag.</p></li>
<li><p><strong>Text</strong> - Text to be displayed on the index page.&nbsp; Must have embedded HTML tags required for proper display.&nbsp; It should, minimally, contain a beginning paragraph tag (&lt;p&gt;) and an ending paragraph tag (&lt;/p&gt;).</p></li>
<li><p><strong>Header_Index</strong> - HTML embedded string that will be placed immediately following the &lt;body&gt tag in an index view.&nbsp; Must adhere to the HTML standard and include all necessary beginning and ending tags.</p></li>
<li><p><strong>Footer_Index</strong> - HTML embedded string that will be placed immediately preceding the &lt;/body&gt tag in an index view.&nbsp; Must adhere to the HTML standard and include all necessary beginning and ending tags.</p></li>
<li><p><strong>BG_Color</strong> - Color to use for the background when an image is not specified or cannot be loaded.&nbsp; (Can be specified in any recognized HTML/CSS format.)</p></li>
<li><p><strong>BG_Image</strong> - Image to be used for the background.</p></li>
</ul>
EOF_HTML
    }
    print "</body>\n\n</html>\n";
}
elsif (! $ident && ($Name || (defined ($config{'index'}) && $config{'index'}) || (@ident_pri || @ident_sec))) {
    print "<div style=\"text-align: center; font-size: x-large;\">";
    print "<strong>$title</strong></div>\n";
    if (@ident_pri || @ident_sec) {
        print "<p><big>Please select, from the names listed below, which individual you would like to see displayed.";
        print "&nbsp; Names highlighted in <strong>bold</strong> are exact matches."  if (@ident_pri);
        print "</big></p>\n";
        print "<div style=\"text-align: center;\">\n<table cellspacing=\"2\" cellpadding=\"4\" border=\"0\">\n";
        foreach $id (@ident_pri) {
            ($name = $indi{$id}->[1]->{"NAME"}->[0]) =~ s/\///g;
            ($idx = $id) =~ s/\@//g;
            print "<tr align=\"left\" valign=\"baseline\"><td><strong><a href=\"$gen{'progpath'}";
            print $urlparms  if ($urlparms);
            print $seperator . "ID=$idx\">$name</a></strong></td><td>&nbsp; &nbsp;</td><td";
##
            $birthline = $deathline = "";
            if ($PUBLIC || exists ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"})) {
                if (defined ($indi{$id}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                    $birthline = format_year ($indi{$id}->[1]->{"BIRT"}->[1]->{"DATE"}->[0]);
                }
                if (defined ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"}->[0])) {
                    $deathline = format_year ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"}->[0]);
                }
                if ($birthline || $deathline) {
                    print " style=\"white-space: nowrap;\" align=\"right\"><small>$birthline</small"  if ($birthline);
                    print "></td><td style=\"white-space: nowrap;\"><small>&nbsp;-&nbsp;</small></td><td";
                    print " style=\"white-space: nowrap;\" align=\"right\"><small>$deathline</small"  if ($deathline);
                }
                else {
                    print " colspan=\"3\"";
                }
            }
            else {
                print " align=\"right\"><small>Private</small></td><td colspan=\"2\"";
            }
            print "></td></tr>\n";
##
        }
        foreach $id (@ident_sec) {
            ($name = $indi{$id}->[1]->{"NAME"}->[0]) =~ s/\///g;
            ($idx = $id) =~ s/\@//g;
            print "<tr align=\"left\" valign=\"baseline\"><td><a href=\"$gen{'progpath'}";
            print $urlparms  if ($urlparms);
            print $seperator . "ID=$idx\">$name</a></td><td>&nbsp; &nbsp;</td><td";
##
            $birthline = $deathline = "";
            if ($PUBLIC || exists ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"})) {
                if (defined ($indi{$id}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                    $birthline = format_year ($indi{$id}->[1]->{"BIRT"}->[1]->{"DATE"}->[0]);
                }
                if (defined ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"}->[0])) {
                    $deathline = format_year ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"}->[0]);
                }
                if ($birthline || $deathline) {
                    print " style=\"white-space: nowrap;\" align=\"right\"><small>$birthline</small"  if ($birthline);
                    print "></td><td style=\"white-space: nowrap;\"><small>&nbsp;-&nbsp;</small></td><td";
                    print " style=\"white-space: nowrap;\" align=\"right\"><small>$deathline</small"  if ($deathline);
                }
                else {
                    print " colspan=\"3\"";
                }
            }
            else {
                print " align=\"right\"><small>Private</small></td><td colspan=\"2\"";
            }
            print "></td></tr>\n";
##
        }
        print "</table>\n</div>\n";
    }
    else {
        print "<p class=\"center\"><big><strong>";
        if ($Name) {
            print $Name;
        }
        else {
            print $config{'index'};
        }
        print "</strong> not found!</big></p>\n";
    }
    print "</body>\n</html>\n";
}
elsif ($ident eq "" || ($view eq "index" || $view eq "ancestor index" || $view eq "descendent index")) {
    $gen{'title'} .= "$title1<br />"  if ($title1);
    $gen{'title'} .= "<a href=\"$link\">"  if ($link);
    $gen{'title'} .= "<strong>$title</strong>";
    $gen{'title'} .= "</a>"  if ($link);
    $gen{'subm'} = $mail = $submitter = "";
    if (defined ($config{'submitter'})) {
        $submitter = $config{'submitter'};
        if (defined ($config{'subm-mail'})) {
            $mail = $config{'subm-mail'};
        }
    }
    elsif (exists ($head[1]->{"SUBM"})) {
        $ptr = $head[1]->{"SUBM"};
        if (defined ($ptr->[0])) {
            if ($ptr->[0] =~ m/^\@\S+?\@$/) {
                if (defined ($subm{$ptr->[0]}->[1]->{"ADDR"}->[0])) {
                    $mail = $subm{$ptr->[0]}->[1]->{"ADDR"}->[0];
                    unless ($mail =~ m/\@/) {
                        $mail = "";
                    }
                }
                $ptr = $subm{$ptr->[0]}->[1]->{"NAME"};
            }
            $submitter = $ptr->[0]
        }
    }
    if ($submitter !~ m/^\s*$/) {
        $gen{'subm'} .= "<div class=\"sans-serif\" style=\"text-align: center; font-size: x-small;\">Information Provided Courtesy of<br /><strong>";
        $gen{'subm'} .= "<!--a href=\"mailto\:$mail\"-->"  if ($mail);
        $gen{'subm'} .= $submitter;
        $gen{'subm'} .= "<!--/a-->"  if ($mail);
        $gen{'subm'} .= "</strong></div>";
    }
    unless (defined ($config{'header_index'}) && ($text = $config{'header_index'})) {
        $text = "<div style=\"text-align: center; font-size: x-large;\"><\$title><\$subm></div>\n";
    }
    $text =~ s/\<\?counter\>//g  if ($gen{'progname'} =~ m/beta/i || ! defined ($config{'counter'}));
    $i = 99;
    while ($i && ($text =~ s/\<\$(.+?)\>/$gen{$1}/g || $text =~ s/\<\?(.+?)\>/$config{$1}/g)) {
        $text =~ s/\<\?counter\>//g  if ($gen{'progname'} =~ m/beta/i || ! defined ($config{'counter'}));
        --$i;	# Prevent endless loop
    }
    print "$text\n";
    print "<p style=\"text-align: center\"><big>Index contains " . (scalar (@name) + 1) . " surnames of $count individuals in $groups family groups</big></p>\n";

    if (defined ($config{'text'}) && ($text = $config{'text'})) {
        $i = 99;
        while ($i && ($text =~ s/\<\$(.+?)\>/$gen{$1}/g || $text =~ s/\<\?(.+?)\>/$config{$1}/g)) {
            --$i;	# Prevent endless loop
        }
        print "$text\n<p>";
    }
    else {
        print "<p>Welcome to our family genealogy page.&nbsp; ";
    }

    print "Click on a surname in the \"List of Surnames\" or just scroll down the page to see a list of individuals in the \"Family Name Index\" with that surname.&nbsp; Then, click on an individual's name to see their personal family record.&nbsp; There you will have the option of viewing an ancestor or descendent tree for that individual.&nbsp; You may also search for a name by entering it (fully or partially) below and selecting the \"Search\" button.</p>\n";

    if (defined ($config{'download'}) && ($text = $config{'download'})) {
        $i = 99;
        while ($i && ($text =~ s/\<\$(.+?)\>/$gen{$1}/g || $text =~ s/\<\?(.+?)\>/$config{$1}/g)) {
            --$i;	# Prevent endless loop
        }
        print "$text\n";
    }
    print "<form action=\"$gen{'progpath'}\" method=\"get\">\n";
    print "<input type=\"hidden\" Name=\"Public\" value=\"" . $Public . "\" />\n"  if ($PUBLIC);
    print "<input type=\"hidden\" Name=\"Config\" value=\"" . $Config . "\" />\n"  if ($Config);
    print "<input type=\"hidden\" Name=\"GED\" value=\"" . $GED . "\" />\n"  if ($GED);
    print "<p  style=\"text-align: center;\"><strong>Name:</strong> &nbsp;<input type=\"text\" name=\"Name\" size=\"24\" maxlength=\"48\" /> &nbsp; &nbsp; <input type=\"submit\" value=\"Search\" /></p>\n</form>\n";
    print "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"margin-top: 4px; margin-bottom: 20px;\">\n<tr valign=\"baseline\">\n<th align=\"center\">List of Surnames</th>\n</tr><tr><td style=\"height: 16px;\">&nbsp;</td></tr><tr valign=\"baseline\">\n";
    print "<td><div style=\"text-align: ";
    if (($i = @name) < 18) {
        print "center";
    }
    else {
        print "justify";
    }
    print "; font-size: small; font-weight: bold;\">";
    print "<a href=\"$gen{'progpath'}";
    print $urlparms  if ($urlparms);
    print $idxparms  if ($idxparms);
    print $sepidx . "Cols=$Cols"  if ($Cols);
    ($nameid = $holdname) =~ s/\s+/./g;
    $nameid =~ s/\W/./g;
    print "#" . $nameid . "\">$holdname</a>";
    foreach $name (@name) {
        print ", ";
        if (18 > @name && 8 < @name && (($i * 2) == @name || ($i * 2) == @name +1)) {
            print "<br />";
        }
        print "<a href=\"$gen{'progpath'}";
        print $urlparms  if ($urlparms);
        print $idxparms  if ($idxparms);
        print $sepidx . "Cols=$Cols"  if ($Cols);
        ($nameid = $name) =~ s/\s+/./g;
        $nameid =~ s/\W/./g;
        print "#" . $nameid . "\">$name</a>";
        --$i;
    }
    print ".</div></td>\n</tr>\n</table>\n";

    unshift (@name, $holdname);
    unshift (@name, $unknown)  if (defined ($surname{$unknown}));
    $count += @name - 1;
    $cols = ($Cols && $Cols =~ m/^\d$/ && 0 < $Cols) ? $Cols - 1 : 1;
    while ($cols && $count < ($cols + 1) * 4) {
        --$cols;
    }
    $rows = int (($count + $cols) / ($cols + 1));
    $adj = ($rows * ($cols + 1)) - $count;
    $width = int ((100 - (2 * $cols)) / ($cols + 1));
    print "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"margin-top: 0px; margin-bottom: 0px;\">\n<tr><th align=\"center\" colspan=\"" . int ((($cols + 1) * 2) - 1) . "\">Family Name Index</th></tr>";
    print "<tr><td style=\"height: 16px;\" colspan=\"3\">&nbsp;</td></tr><tr valign=\"top\">\n<td align=\"center\" style=\"width: " . $width . "%;\">\n";
    print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"font-size: small;\">\n";
    $flag = 0;

    foreach $name (@name) {
        $prtline = $sep = "";
        $rowcnt = $anchor = 0;
        $ptr = $surname{$name};
        @given = sort (sort_file (keys (%$ptr)));
        foreach $given (@given) {
            $idptr = $ptr->{$given};
            $rowcnt += @$idptr;
            foreach $id (@$idptr) {
                $urlid = $id;
                $urlid =~ s/\@//g;
                $prtline .= "$sep<td style=\"white-space: nowrap;\"><a href=\"$gen{'progpath'}";
                $prtline .= $urlparms  if ($urlparms);
                $prtline .= $seperator . "ID=" . $urlid . "\">" . $given . "</a></td><td style=\"width: 8px;\"></td><td";
                $birthline = $deathline = "";
                if ($PUBLIC || exists ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"})) {
                    if (defined ($indi{$id}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                        $birthline = format_year ($indi{$id}->[1]->{"BIRT"}->[1]->{"DATE"}->[0]);
                    }
                    if (defined ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"}->[0])) {
                        $deathline = format_year ($indi{$id}->[1]->{"DEAT"}->[1]->{"DATE"}->[0]);
                    }
                    if ($birthline || $deathline) {
                        $prtline .= " style=\"white-space: nowrap;\" align=\"right\"><small>$birthline</small"  if ($birthline);
                        $prtline .= "></td><td style=\"white-space: nowrap;\"><small>&nbsp;-&nbsp;</small></td><td";
                        $prtline .= " style=\"white-space: nowrap;\" align=\"right\"><small>$deathline</small"  if ($deathline);
                    }
                    else {
                        $prtline .= " colspan=\"3\"";
                    }
                }
                else {
                    $prtline .= " align=\"right\"><small>Private</small></td><td colspan=\"2\"";
                }
                $prtline .= "></td></tr>";
                $sep = "<tr align=\"left\" valign=\"baseline\">\n";
            }
            if ($cols && ($count - $rowcnt) < ($rows * $cols) - $adj + 1 - $flag) {
                print "<tr align=\"left\" valign=\"baseline\">\n<th align=\"left\" style=\"white-space: nowrap;\"";
                print " rowspan=\"$rowcnt\""  if ($rowcnt > 1);
                if ($name ne $unknown) {
                    print ">";
                    if (! $anchor) {
                        ($nameid = $name) =~ s/\s+/./g;
                        $nameid =~ s/\W/./g;
                        print "<a name=\"$nameid\">";
                    }
                    print "$name,";
                    print "</a>"  if (! $anchor);
                }
                else {
                    print ">";
                }
                $anchor = 1;
                print "</th><td style=\"width: 8px;\"";
                print " rowspan=\"$rowcnt\""  if ($rowcnt > 1);
                print "></td>\n";
                print $prtline;
                print "<tr>\n<td colspan=\"7\">&nbsp;</td>\n</tr>";
                $count -= $rowcnt;

                print "\n</table>\n</td><td style=\"width: 2%\"></td><td align=\"center\" style=\"width: " . $width . "%\">\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"font-size: small;\">\n";
                --$cols;
                --$adj  if ($adj > $cols);

                $prtline = $sep = "";
                $rowcnt = $flag = 0;
            }
        }
        if ($rowcnt) {
            print "<tr align=\"left\" valign=\"baseline\">\n<th align=\"left\" style=\"white-space: nowrap;\"";
            print " rowspan=\"$rowcnt\""  if ($rowcnt > 1);
            if ($name ne $unknown) {
                print ">";
                if (! $anchor) {
                    ($nameid = $name) =~ s/\s+/./g;
                    $nameid =~ s/\W/./g;
                    print "<a name=\"$nameid\">";
                }
                print "$name,";
                print "</a>"  if (! $anchor);
            }
            else {
                print ">";
            }
            print "</th><td style=\"width: 8px;\"";
            print " rowspan=\"$rowcnt\""  if ($rowcnt > 1);
            print "></td>\n";
            print $prtline;
            print "<tr>\n<td colspan=\"7\">&nbsp;</td>\n</tr>";
        }
        else {
            $flag = 1;
        }
        $count -= $rowcnt + 1;
        if ($cols && $count < ($rows * $cols) - $adj + 1 - $flag) {
            print "\n</table>\n</td><td style=\"width: 2%;\"></td><td align=\"center\" style=\"width: " . $width . "%\">\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"font-size: small;\">\n";
            $flag = 0;
            --$cols;
            --$adj  if ($adj > $cols);
        }
    }
    print "\n</table>\n</td>\n";
    print "</tr>\n</table>\n";

    unless (defined ($config{'footer_index'}) && ($text = $config{'footer_index'})) {
        $text = "<div><hr style=\"height: 2px; color: #3333FF; border: 1px solid #3333FF;\" /><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr valign=\"baseline\"><td style=\"width: 90px;\"><?counter></td><td style=\"width: 12px;\"></td><td align=\"center\"><small>Thank you for visiting our family genealogy pages.<br />For more information contact <?contact> at <strong><!--a href=\"mailto:<?contact> &lt;<?e-mail>&gt;\"><?e-mail><!--/a--></strong></small></td><td style=\"width: 12px;\"></td><td style=\"width: 90px;\"></td></tr></table></div><hr style=\"height: 2px; color: #3333FF; border: 1px solid #3333FF;\" /><table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr valign=\"top\"><td align=\"left\"><?return_link_index></td><td align=\"right\"><?copyright></td></tr></table>";
    }
    $text =~ s/\<\?counter\>//g  if ($gen{'progname'} =~ m/beta/i || ! defined ($config{'counter'}));
    $i = 99;
    while ($i && ($text =~ s/\<\$(.+?)\>/$gen{$1}/g || $text =~ s/\<\?(.+?)\>/$config{$1}/g)) {
        $text =~ s/\<\?counter\>//g  if ($gen{'progname'} =~ m/beta/i || ! defined ($config{'counter'}));
        --$i;	# Prevent endless loop
    }
    print "$text\n";

    print <<EOF_HTML;
</body>
</html>
EOF_HTML

}
elsif (defined ($indi{$ident}->[0])) {
    $priv_msg = "<font color=\"#DF0000\"><small><strong>(Private)</strong></small></font>";
    if ($PUBLIC || exists ($indi{$ident}->[1]->{"DEAT"})) {
        $public = 1;
    }
    else {
        $public = 0;
    }
    if ($NumGen) {
        if (lc ($NumGen) eq "all") {
            $maxnum = 0;
        }
        else {
            $maxnum = $NumGen;
        }
    }
    else {
        $maxnum = 0;
    }
    ($idx = $ident) =~ s/\@//g;
    if ($view eq "ancestor tree") {
        ($name = $indi{$ident}->[1]->{"NAME"}->[0]) =~ s/\///g;
        print "<div style=\"text-align: center; font-size: x-large;\">Ancestor Tree<br /><strong>";
        print "<a href=\"$gen{'progpath'}";
        print $urlparms  if ($urlparms);
        print $seperator . "ID=$idx\">$name</a>";
        print "</strong></div>\n<div style=\"text-align: center; margin: 20px 0px;\">\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"display: inline;\">";
        @string = ();
        traverse($ident);
        print "\n</table>\n</div>\n";
    }
    elsif ($view eq "descendent tree") {
        ($name = $indi{$ident}->[1]->{"NAME"}->[0]) =~ s/\///g;
        print "<div style=\"text-align: center; font-size: x-large;\">Descendent Tree<br /><strong>";
        print "<a href=\"$gen{'progpath'}";
        print $urlparms  if ($urlparms);
        print $seperator . "ID=$idx\">$name</a>";
        print "</strong></div>\n<div style=\"text-align: center; margin: 20px 0px;\">\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"display: inline;\">\n";
        @footnote = ();
        $maxrow = 0;
        @rowsav = ();
        traverse_descendent($ident);
        for ($i = 0; $i < $maxrow; $i++) {
            print "<tr valign=\"middle\" align=\"left\">";
            for ($k = 0; $k < @rowsav; $k++) {
                print "<td";
                if (defined ($table{$i}{$k})) {
                    $idx = $table{$i}{$k};
                    if ($idx =~ m/^\@\S+?\@$/) {
                        print " colspan=\"2\" style=\"white-space: nowrap;\">&nbsp;";
                        prt_anchor ($idx);
                        if (defined ($relation{$i}{$k})) {
                            $footnote[@footnote] = $relation{$i}{$k} . " Child";
                            print "<sup><small> " . scalar (@footnote) . "</small></sup>";
                        }
                    }
                    elsif ("||" eq $idx) {
                        print " align=\"right\"><img src=\"$PATH/images/v_dbl.gif\" width=\"41\" height=\"21\" style=\"vertical-align: middle;\" alt=\"\" /></td><td>";
                    }
                    else {
                        print " align=\"right\"><img src=\"$PATH/images/" . $spousym{$i}{$k} . ".gif\" width=\"41\" height=\"21\" style=\"vertical-align: middle;\" alt=\"\" /></td><td align=\"center\" style=\"white-space: nowrap;\">&nbsp;<small><em>" . $idx . "</em></small>&nbsp;";
                    }
                }
                else {
                    print " colspan=\"2\">";
                }
                print "</td><td";
                if (defined ($symbol{$i}{$k})) {
                    print "><img src=\"$PATH/images/" . $symbol{$i}{$k} . ".gif\" width=\"41\" height=\"21\" style=\"vertical-align: middle;\" alt=\"\" /";
                }
                print "></td>";
            }
            print "</tr>\n";
        }
        print "</table>\n</div>";
        if (@footnote) {
            print "<div align=\"right\">\n<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr valign=\"baseline\">";
            print "<th align=\"right\" style=\"white-space: nowrap;\" rowspan=\"" . scalar (@footnote) . "\"><small>Footnotes: &nbsp;</small></th><td";
            for ($i = 0; $i < @footnote; $i++) {
                print " align=\"right\"><small><sup>";
                print $i + 1 . ")</sup></small>&nbsp;</td><td><small>" . $footnote[$i] . "</small></td></tr><tr valign=\"baseline\"><td";
            }
            print "></td></tr></table>\n</div>";
        }
        print "\n";
    }
    else {
        print <<EOF_HTML;
<div align=CENTER>
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr valign="middle">
<td></td>
EOF_HTML
        ($urlid = $ident) =~ s/\@//g;
        ($name = $indi{$ident}->[1]->{"NAME"}->[0]) =~ s/^(.*?)(\s*)\/(.*?)\/(.*?)\s*$/\<nobr\>$1\<\/nobr\>$2\<nobr\>$3$4\<\/nobr\>/;
        print "<th align=\"left\" colspan=\"2\" style=\"font-size: x-large;\">$name";
        if (exists ($indi{$ident}->[1]->{"ALIA"})) {
		print "<br><span style=\"font-size: large; font-weight: normal;\">AKA: <span style=\"font-weight: normal;\">" . $indi{$ident}->[1]->{"ALIA"}->[0] . "</span></span>";
	}
	print "</th>\n";
        print "<td align=\"center\" colspan=\"2\"><form action=\"$gen{'progpath'}\" method=\"get\">";
        print "<input type=\"hidden\" Name=\"Public\" value=\"" . $Public . "\" />"  if ($PUBLIC);
        print "<input type=\"hidden\" Name=\"Config\" value=\"" . $Config . "\" />"  if ($Config);
        print "<input type=\"hidden\" Name=\"GED\" value=\"" . $GED . "\" />"  if ($GED);
        print "<input type=\"hidden\" Name=\"ID\" value=\"$urlid\" />";
        print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr valign=\"baseline\">";
        print "<td align=\"right\"><small><input type=\"radio\" Name=\"View\" value=\"Index\" /></small></td><td><small>Index View</small></td><td width=12></td>";
        print "<td align=\"right\"><small><input type=\"radio\" Name=\"Type\" value=\"\" /></small></td><td><small>Full <small>(Index only)</small></small></td><td width=18 rowspan=\"3\"></td>";
        print "<td align=\"center\" valign=\"middle\" rowspan=\"3\"><small><input type=\"submit\" value=\"View\" /></small></td>";
#        print "<td align=\"center\" valign=\"middle\" rowspan=\"3\"><small><input type=\"submit\" name=\"Key\" value=\"View\" /></small></td>";
        print "</tr><tr valign=\"baseline\">";
        print "<td align=\"right\"><small><input type=\"radio\" Name=\"View\" value=\"Tree\" checked=\"checked\" /></small></td><td><small>Tree View</small></td><td style=\"width: 12px;\"></td>";
        print "<td align=\"right\"><small><input type=\"radio\" Name=\"Type\" value=\"Ancestor\" checked=\"checked\" /></small></td><td><small>Ancestor</small></td></tr><tr valign=\"baseline\">";
        print "<td align=\"right\"><small><select name=\"NumGen\" size=\"1\"><option";
        if ($NumGen) {
            $maxnum = ("all" eq lc ($NumGen)) ? 0 : $NumGen;
        }
        else {
            $maxnum = 0;
        }
        for ($i = 4; $i <= 24; $i += 4) {
            print " selected" if ($i == $maxnum);
            print "><small>$i</small>";
            print "</option><option";
        }
        print " selected" unless ($maxnum);
        print "><small>All</small></select></small></td><td><small>&nbsp;Generations</small></td><td width=12></td>";
        print "<td align=\"right\"><input type=\"radio\" Name=\"Type\" value=\"Descendent\" /></td><td><small>Descendent</small></td>";
        print "</tr></table></form></td>\n</tr><tr><td style=\"height: 16px;\" colspan=\"0\"></td></tr><tr valign=\"baseline\">";

        print "<th align=\"right\" style=\"white-space: nowrap;\"><small>Born:</small> &nbsp;</th><td>";
        if ($public && exists ($indi{$ident}->[1]->{"BIRT"})) {
            print "<span style=\"white-space: nowrap;\">";
            prt_info ($indi{$ident}->[1]->{"BIRT"}->[1]);
            print "</span>";
            prt_source ($indi{$ident}->[1]->{"BIRT"}->[1]);
        }
        else {
            if ($public == 0) {
                print $priv_msg;
            }
        }
        print "</td><td style=\"width: 32px;\"></td>\n<th";
        if ($public && exists ($indi{$ident}->[1]->{"DEAT"})) {
            print " align=\"right\" style=\"white-space: nowrap;\"><small>Died:</small> &nbsp;</th><td>";
            print "<span style=\"white-space: nowrap;\">";
            prt_info ($indi{$ident}->[1]->{"DEAT"}->[1]);
            print "</span>";
            prt_source ($indi{$ident}->[1]->{"DEAT"}->[1]);
        }
        else {
            print "></th><td>";
        }
        print "</td>\n</tr><tr><td style=\"height: 24px;\" colspan=\"0\"></td></tr><tr valign=\"baseline\">";

        print "  <th align=RIGHT nowrap><small>Father:</small> &nbsp;</th><td style=\"white-space: nowrap;\">";
        if (exists ($indi{$ident}->[1]->{"FAMC"}) && defined ($fam{$indi{$ident}->[1]->{"FAMC"}->[0]}->[1]->{"HUSB"}->[0])) {
            $idx = $fam{$indi{$ident}->[1]->{"FAMC"}->[0]}->[1]->{"HUSB"}->[0];
            prt_anchor ($idx);
            if ($PUBLIC || exists ($indi{$idx}->[1]->{"DEAT"})) {
                $yearbirth = $yeardeath = "";
                if (defined ($indi{$idx}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                    $yearbirth = format_year ($indi{$idx}->[1]->{"BIRT"}->[1]->{"DATE"}->[0]);
                }
                if (defined ($indi{$idx}->[1]->{"DEAT"}->[1]->{"DATE"}->[0])) {
                    $yeardeath = format_year ($indi{$idx}->[1]->{"DEAT"}->[1]->{"DATE"}->[0]);
                }
                if ($yearbirth || $yeardeath) {
                    print "<br /><small><small>";
                    if ($yearbirth) {
                        print "$yearbirth";
                    }
                    else {
                        print "Unknown";
                    }
                    print "&nbsp;-&nbsp;$yeardeath</small></small>";
                }
            }
        }
        print "</td><td style=\"width: 32px;\"></td>\n<th align=\"right\" style=\"white-space: nowrap;\"><small>Mother:</small> &nbsp;</th><td style=\"white-space: nowrap;\">";
        if (exists ($indi{$ident}->[1]->{"FAMC"}) && defined ($fam{$indi{$ident}->[1]->{"FAMC"}->[0]}->[1]->{"WIFE"}->[0])) {
            $idx = $fam{$indi{$ident}->[1]->{"FAMC"}->[0]}->[1]->{"WIFE"}->[0];
            prt_anchor ($idx);
            if ($PUBLIC || exists ($indi{$idx}->[1]->{"DEAT"})) {
                $yearbirth = $yeardeath = "";
                if (defined ($indi{$idx}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                    $yearbirth = format_year ($indi{$idx}->[1]->{"BIRT"}->[1]->{"DATE"}->[0]);
                }
                if (defined ($indi{$idx}->[1]->{"DEAT"}->[1]->{"DATE"}->[0])) {
                    $yeardeath = format_year ($indi{$idx}->[1]->{"DEAT"}->[1]->{"DATE"}->[0]);
                }
                if ($yearbirth || $yeardeath) {
                    print "<br /><small><small>";
                    if ($yearbirth) {
                        print "$yearbirth";
                    }
                    else {
                        print "Unknown";
                    }
                    print "&nbsp;-&nbsp;$yeardeath</small></small>";
                }
            }
        }
        print "</td>\n</tr>";

        @footnote = ();
        if ($indi{$ident}->[1]->{"SEX"}->[0] eq "M") {
            $key = "WIFE";
        }
        else {
            $key = "HUSB";
        }
        if (exists ($indi{$ident}->[1]->{"FAMS"})) {
            $ptr = $indi{$ident}->[1]->{"FAMS"};
            for ($k = 0; $k < @$ptr; $k += 2) {
                print "<tr><td style=\"height: 24px;\" colspan=\"0\"></td></tr><tr valign=\"top\">\n";
                print "<th align=\"right\" style=\"white-space: nowrap;\"><small>Spouse:</small> &nbsp;</th><td style=\"white-space: nowrap;\">";
                if (defined ($fam{$familyid = $ptr->[$k]}->[1]->{$key}->[0])) {
                    prt_anchor ($idx = $fam{$familyid}->[1]->{$key}->[0]);

                    $sep = "<sup><small> ";
		    if (exists ($fam{$familyid}->[1]->{"REFN"}) && "" ne $fam{$familyid}->[1]->{"REFN"}->[0]) {
                            $footnote[@footnote] = $fam{$familyid}->[1]->{"REFN"}->[0];
                            print $sep . scalar (@footnote);
                            $sep = ",";
		    }
                    if (exists ($fam{$familyid}->[1]->{"_MSTAT"}) && "Married" ne ($relation = $fam{$familyid}->[1]->{"_MSTAT"}->[0])) {
                        if ($public && $PUBLIC) {
                            $footnote[@footnote] = "Not Married (" . $relation . ")";
                            print $sep . scalar (@footnote);
                            $sep = ",";
                        }
                    }
                    if (exists ($fam{$familyid}->[1]->{"_MEND"}) && "" ne $fam{$familyid}->[1]->{"_MEND"}->[0]) {
                            $footnote[@footnote] = "Union Ended In " . $fam{$familyid}->[1]->{"_MEND"}->[0];
                            print $sep . scalar (@footnote);
                            $sep = ",";
                    }
                    print "</small></sup>"  if ("," eq $sep);

                    if ($PUBLIC || exists ($indi{$idx}->[1]->{"DEAT"})) {
                        $yearbirth = $yeardeath = "";
                        if (defined ($indi{$idx}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                            $yearbirth = format_year ($indi{$idx}->[1]->{"BIRT"}->[1]->{"DATE"}->[0]);
                        }
                        if (defined ($indi{$idx}->[1]->{"DEAT"}->[1]->{"DATE"}->[0])) {
                            $yeardeath = format_year ($indi{$idx}->[1]->{"DEAT"}->[1]->{"DATE"}->[0]);
                        }
                        if ($yearbirth || $yeardeath) {
                            print "<br /><small><small>";
                            if ($yearbirth) {
                                print "$yearbirth";
                            }
                            else {
                                print "Unknown";
                            }
                            print "&nbsp;-&nbsp;$yeardeath</small></small>";
                        }
                    }
                }
                print "</td><td style=\"width: 32px;\" rowspan=\"3\"></td>\n";

                if (exists ($fam{$familyid}->[1]->{"CHIL"})) {
                    $childptr = $fam{$familyid}->[1]->{"CHIL"};
                    print "<th align=\"right\" rowspan=\"4\" style=\"white-space: nowrap;\"><small>Children:</small> &nbsp;</th><td rowspan=\"4\"><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
                    for ($i = 0; $i < @$childptr; $i += 2) {
                        if ($indi{$ident}->[1]->{"SEX"}->[0] eq "M") {
                            $rel_my = "_FREL";
                            $rel_spouse = "_MREL";
                        }
                        else {
                            $rel_my = "_MREL";
                            $rel_spouse = "_FREL";
                        }
                        if (true || !defined ($childptr->[$i+1]->{$rel_spouse}) || "" eq ($relation = $childptr->[$i+1]->{$rel_spouse}->[0]) || "Natural" eq $relation) {
                            print "<tr valign=\"baseline\"><td style=\"white-space: nowrap;\">";
                            prt_anchor ($child = $childptr->[$i]);
                            if (defined ($childptr->[$i+1]->{$rel_my})) {
                                $relation = $childptr->[$i+1]->{$rel_my}->[0];
                            }
                            else {
                                $relation = "";
                            }
                            if ($relation && "Natural" ne $relation) {
                                $footnote[@footnote] = $relation . " Child";
                                print "<sup><small> " . scalar (@footnote) . "</small></sup>";
                            }
                            print "</td><td align=\"right\">";
                            if (($PUBLIC || exists ($indi{$child}->[1]->{"DEAT"})) && defined ($indi{$child}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                                if (defined ($indi{$child}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) {
                                    if (($year = format_year ($indi{$child}->[1]->{"BIRT"}->[1]->{"DATE"}->[0])) && $year ne "Unknown") {
                                        print "<small>&nbsp; $year</small>";
                                    }
                                }
                            }
                            print "</td></tr>";
                        }
                    }
                    print "</table></td>";
                }
                else {
                    print "<td colspan=\"2\" rowspan=\"4\"></td>";
                }
                print "</tr><tr><td style=\"height: 12px;\" colspan=\"2\"></td></tr><tr valign=\"baseline\">\n";

# Print Marriage Date & Place Here
                print "<th align=\"right\" rowspan=\"2\" style=\"white-space: nowrap;\"><small>Married:</small> &nbsp;</th><td rowspan=\"2\" style=\"white-space: nowrap;\">";

                $sep = "";
                if (exists ($fam{$familyid}->[1]->{"MARR"})) {
                    $spouse_deceased = 0;
                    if (defined ($fam{$familyid}->[1]->{$key}->[0])) {
                        if (exists ($indi{$fam{$familyid}->[1]->{$key}->[0]}->[1]->{"DEAT"})) {
                            $spouse_deceased = 1;
                        }
                    }
                    if ($public && ($spouse_deceased || $PUBLIC)) {
                        prt_info ($fam{$familyid}->[1]->{"MARR"}->[1]);
                        prt_source ($fam{$familyid}->[1]->{"MARR"}->[1]);
                        $sep = "<br />";
                    }
                    else {
                        if ($public == 0 || $spouse_deceased == 0) {
                            print $priv_msg;
                            $sep = "<br />";
                        }
                    }
                }
                elsif (exists ($fam{$familyid}->[1]->{"_MSTAT"}) && "Married" ne ($relation = $fam{$familyid}->[1]->{"_MSTAT"}->[0])) {
                    if ($public && ($spouse_deceased || $PUBLIC)) {
                        print "<small>Never</small>";
                        $sep = "<br />";
                    }
                    else {
                        if ($public == 0 || $spouse_deceased == 0) {
                            print $priv_msg;
                            $sep = "<br />";
                        }
                    }
                }
                print "</td></tr><tr><td></td></tr>\n";
            }
        }
        print "<tr><td style=\"height: 24px;\" colspan=\"0\"></td></tr><tr valign=\"baseline\">\n";

# Print Notes Here
        print "<th align=\"right\" style=\"white-space: nowrap;\"><small>Notes:</small> &nbsp;</th>\n<td colspan=\"4\">";
        if ($public && defined ($indi{$ident}->[1]->{"NOTE"}->[0])) {
            $ptr = $indi{$ident}->[1]->{"NOTE"};
            if ($ptr->[0] =~ m/^\@\S+?\@$/) {
                $ptr = $note{$ptr->[0]};
            }
            print "<div>";
            foreach $line (@$ptr) {
                unless ($line =~ m/^\@\S+?\@$/) {
                    print $line . "<br />";
                }
            }
            print "</div>";
        }
        if (@footnote) {
            print "<tr><td style=\"height: 24px;\" colspan=\"0\"></td></tr><tr valign=\"baseline\">\n";
            print "<th align=\"right\" style=\"white-space: nowrap;\" rowspan=\"" . scalar (@footnote) . "\"><small>Footnotes: &nbsp;</small></th>";
#            print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">";
            $sep = "";
            for ($i = 0; $i < @footnote; $i++) {
                print "$sep<td colspan=\"4\"><small><sup>";
                print $i + 1 . ")</sup> " . $footnote[$i] . "</small></td>\n";
                $sep = "</tr><tr valign=\"baseline\">\n";
            }
#            print "</table>";
        }
        print "</tr>\n</table>\n</div>\n";

    }
    print <<EOF_HTML;
<hr style="height: 2px; color: #3333FF; border: 1px solid #3333FF;" />
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tr valign="top">
<td align="left">
EOF_HTML

    if (defined ($config{'return_link_family'})) {
        print $config{'return_link_family'};
    }
    elsif (0) {
        print "<table cellspacing=\"0\" cellpadding=\"0\" border=\"0\">\n<tr valign=\"middle\">\n<td align=\"right\"><a href=\"$gen{'progpath'}";
        print $urlparms  if ($urlparms);
        print "\"><img src=\"/images/larrw.gif\" width=\"31\" height=\"31\" alt=\"\" /></a></td>\n<td style=\"width: 6px;\"></td>\n<td>Return to <a href=\"$gen{'progpath'}";
        print $urlparms  if ($urlparms);
        print "\">Family Index</a>.</td>\n</tr>\n</table>\n";
    }
    print "</td><td align=\"right\"><small><small>&copy;1998-";
    print $gen{'year'};
    print " </small><!--a href=\"mailto:$MY_NAME%20&lt;$MY_ADDR\@$DOMAIN&gt;\"-->$MY_NAME<!--/a--></small></td>\n";

    print <<EOF_HTML;
</tr>
</table>

</body>
</html>
EOF_HTML

}
else {
    print <<EOF_HTML;
<h2 align=CENTER>ERROR: Record Not Found!</h2>
EOF_HTML

    print "<p style=\"text-align: left;\">Please notify <strong><!--a href=\"mailto:$MY_ADDR\@$DOMAIN\?Subject=" . ucfirst ($gen{'progname'}) . "+Error:+$gen{'family'}.ged+-+$ident\"-->$MY_NAME<!--/a--></strong> that record <strong>" . $ident . "</strong> does not exist in file: <strong>$gen{'ged_dir'}/$gen{'family'}.ged</strong></p>";

    print <<EOF_HTML;
</body>
</html>
EOF_HTML
}
} # open
else {
    print header;
    print <<EOF_HTML;
<html>
<head><title>ERROR: File Not Found!</title></head>
<body>
<h2 style=\"text-align: center;\">ERROR: File Not Found!</h2>
EOF_HTML

    print "<p style=\"text-align: left;\">Please notify <strong><!--a href=\"mailto:$MY_ADDR\@$DOMAIN\?Subject=" . ucfirst ($gen{'progname'}) . "+Error:+$file\"-->$MY_NAME<!--/a--></strong> that file <strong>$gen{'ged_dir'}/$gen{'family'}.ged</strong> does not exist on the server!</p>";

    print <<EOF_HTML;
</body>
</html>
EOF_HTML
}

sub index_ancestor {
    local ($idx, $num, $name, @name, $childptr, $child, $ptridx, $addname, $ptr, $nameptr, $flag, $i);
    $idx = $_[0];
    $num = @_ > 1 ? $_[1] : -1;
    $flag = @_ > 2 ? $_[2] : 0;

    @name = split (/\s*\//, $indi{$idx}->[1]->{"NAME"}->[0], 3);
    if (! defined ($surname{$name[1]})) {
        $surname{$name[1]} = {};
    }
    $name = $name[0];
    $name = "?"  unless ($name);
    if (@name > 2) {
        $name .= $name[2];
    }
    if (! defined ($surname{$name[1]}->{$name})) {
        $surname{$name[1]}->{$name} = [];
    }
    $nameptr = $surname{$name[1]}->{$name};
    $addname = 1;
    foreach $ptridx (@$nameptr) {
        $addname = 0  if ($idx eq $ptridx);
    }
    if ($addname) {
        $nameptr->[@$nameptr] = $idx;
        $count++;
    }
    if ($num && defined ($indi{$idx}->[1]->{"FAMC"})) {
        $ptr = $indi{$idx}->[1]->{"FAMC"};
        if ($addname) {
            if ($flag) {
                $group{$ptr->[0]} = $ptr->[0];
                $childptr = $fam{$ptr->[0]}->[1]->{"CHIL"};
                for ($i = 0; $i < @$childptr; $i += 2) {
                    if (($child = $childptr->[$i]) ne $idx && defined ($indi{$child}->[1]->{"NAME"})) {
                        @name = split (/\s*\//, $indi{$child}->[1]->{"NAME"}->[0], 3);
                        if (! defined ($surname{$name[1]})) {
                            $surname{$name[1]} = {};
                        }
                        $name = $name[0];
                        $name = "?"  unless ($name);
                        if (@name > 2) {
                            $name .= $name[2];
                        }
                        if (! defined ($surname{$name[1]}->{$name})) {
                            $surname{$name[1]}->{$name} = [];
                        }
                        $nameptr = $surname{$name[1]}->{$name};
                        $addname = 1;
                        foreach $ptridx (@$nameptr) {
                            $addname = 0  if ($child eq $ptridx);
                        }
                        if ($addname) {
                            $nameptr->[@$nameptr] = $child;
                            $count++;
                            index_descendent($child, 1)  if ($flag > 1);
                        }
                    }
                }
            }
        }
        if ($flag) {
            if (defined ($fam{$ptr->[0]}->[1]->{"HUSB"})) {
                index_ancestor($fam{$ptr->[0]}->[1]->{"HUSB"}->[0], $num > 0 ? $num - 1 : $num, $flag);
            }
            if (defined ($fam{$ptr->[0]}->[1]->{"WIFE"})) {
                index_ancestor($fam{$ptr->[0]}->[1]->{"WIFE"}->[0], $num > 0 ? $num - 1 : $num, $flag);
            }
        }
    }
}

sub index_descendent {
    local ($idx, $ptr, $nameptr, $spouseptr, $name, @name, $childptr, $child, $ptridx, $addname, $flag, $i, $k);
    $idx = $_[0];
    $flag = @_ > 1 ? $_[1] : 0;

    if (defined ($indi{$idx}->[1]->{"FAMS"})) {
        $ptr = $indi{$idx}->[1]->{"FAMS"};
        for ($k = 0; $k < @$ptr; $k += 2) {
            if ($flag) {
                if ($indi{$idx}->[1]->{"SEX"}->[0] eq "M") {
                    $spouseptr = $fam{$ptr->[$k]}->[1]->{"WIFE"};
                }
                else {
                    $spouseptr = $fam{$ptr->[$k]}->[1]->{"HUSB"};
                }

                if (defined ($spouseptr->[0])) {
                    @name = split (/\s*\//, $indi{$spouseptr->[0]}->[1]->{"NAME"}->[0], 3);
                    if (! defined ($surname{$name[1]})) {
                        $surname{$name[1]} = {};
                    }
                    $name = $name[0];
                    $name = "?"  unless ($name);
                    if (@name > 2) {
                        $name .= $name[2];
                    }
                    if (! defined ($surname{$name[1]}->{$name})) {
                        $surname{$name[1]}->{$name} = [];
                    }
                    $nameptr = $surname{$name[1]}->{$name};
                    $addname = 1;
                    foreach $ptridx (@$nameptr) {
                        $addname = 0  if ($spouseptr->[0] eq $ptridx);
                    }
                    if ($addname) {
                        $nameptr->[@$nameptr] = $spouseptr->[0];
                        $count++;
                    }
                }
            }
            if (exists ($fam{$ptr->[$k]}->[1]->{"CHIL"})) {
                $childptr = $fam{$ptr->[$k]}->[1]->{"CHIL"};
                $group{$ptr->[$k]} = $ptr->[$k]  if (@$childptr);
                for ($i = 0; $i < @$childptr; $i += 2) {
                    if (defined ($indi{$child = $childptr->[$i]}->[1]->{"NAME"})) {
                        @name = split (/\s*\//, $indi{$child}->[1]->{"NAME"}->[0], 3);
                        if (! defined ($surname{$name[1]})) {
                            $surname{$name[1]} = {};
                        }
                        $name = $name[0];
                        $name = "?"  unless ($name);
                        if (@name > 2) {
                            $name .= $name[2];
                        }
                        if (! defined ($surname{$name[1]}->{$name})) {
                            $surname{$name[1]}->{$name} = [];
                        }
                        $nameptr = $surname{$name[1]}->{$name};
                        $addname = 1;
                        foreach $ptridx (@$nameptr) {
                            $addname = 0  if ($child eq $ptridx);
                        }
                        if ($addname) {
                            $nameptr->[@$nameptr] = $child;
                            $count++;
                            index_descendent($child, $flag);
                        }
                    }
                }
            }
        }
    }
}

sub traverse_descendent {
    my ($idx, $ptr, $spouseptr, $childptr, $col, $i, $j, $k, $name, $spoused, $relative, $rel_flag, $delta, @savsav);
    my ($row, $firstrow, $lastrow, $spouserow, $prevrow, $retrow, $lowrow, $newrow);
    $idx = $_[0];
    $col = @_ > 1 ? $_[1] : 0;
    $relative = @_ > 2 ? $_[2] : "";

    $rowsav[$col] = 0  unless ($col < @rowsav);
    $row = $rowsav[$col];
    if (($maxnum == 0 || $col < $maxnum) && defined ($indi{$idx}->[1]->{"FAMS"})) {
        $ptr = $indi{$idx}->[1]->{"FAMS"};
        $spoused = 0;
        for ($k = 0; $k < @$ptr; $k += 2) {
            $firstrow = $retrow = $row;
            if (defined ($fam{$ptr->[$k]}->[1]->{"CHIL"})) {
                $childptr = $fam{$ptr->[$k]}->[1]->{"CHIL"};
                @savsav = ();
                for ($i = $col + 1; $i < @rowsav; $i++) {
                    $savsav[$i - ($col + 1)] = $rowsav[$i];
                }
                for ($i = 0; $i < @$childptr; $i += 2) {
                    if (defined ($indi{$childptr->[$i]}->[0])) {
                        if ($indi{$idx}->[1]->{"SEX"}->[0] eq "M") {
                            $rel_flag = "_FREL";
                        }
                        else {
                            $rel_flag = "_MREL";
                        }
                        if (defined ($childptr->[$i+1]->{$rel_flag})) {
                            $rel_flag = $childptr->[$i+1]->{$rel_flag}->[0];
                        }
                        else {
                            $rel_flag = "";
                        }
                        $retrow = traverse_descendent($indi{$childptr->[$i]}->[0], $col+1, $rel_flag);
                    }
                    $firstrow = $retrow  if (0 == $i);
                }
                $lastrow = $retrow;
                $spouserow = $firstrow - 1;
                if (0 == $firstrow || !defined ($spousym{$firstrow - 1}{$col + 1})) {
                    for ($i = $firstrow; $i < $lastrow && $spouserow < $firstrow + 1; $i++) {
                        if (defined ($spousym{$i}{$col + 1})) {
                            $spouserow = $i - 1;
                        }
                        elsif (defined ($table{$i}{$col + 1})) {
                            $retrow = $i + 1;
                        }
                    }
                    if (($delta = $spouserow - $retrow) > 0) {
                        for ($i = $retrow - 1; $i > $firstrow - 1; $i--){
                            $table{$i + $delta}{$col + 1} = $table{$i}{$col + 1};
                            undef ($table{$i}{$col + 1});
                            if (defined ($relation{$i}{$col + 1})) {
                                $relation{$i + $delta}{$col + 1} = $relation{$i}{$col + 1};
                                undef ($relation{$i}{$col + 1});
                            }
                            $symbol{$i + $delta}{$col} = $symbol{$i}{$col};
                            undef ($symbol{$i}{$col});
                        }
                        $firstrow += $delta;
                    }
                    ++$spouserow;
                    $retrow = $lastrow;
                }
                while (defined ($spousym{$spouserow}{$col + 1})) {
                    ++$spouserow;
                }
                while ($spouserow < $lastrow - 1) {
                    ++$spouserow;
                    while (defined ($spousym{$spouserow}{$col + 1})) {
                        ++$spouserow;
                    }
                    while (!defined ($table{$spouserow}{$col + 1})) {
                        ++$spouserow;
                    }
                    if (!defined ($spousym{$spouserow}{$col + 1})) {
                        $newrow = $spouserow;
                        for ($i = $spouserow; $i < $lastrow && $spouserow < $retrow; $i++) {
                            if (defined ($spousym{$i}{$col + 1})) {
                                $spouserow = $i - 1;
                            }
                            elsif (defined ($table{$i}{$col + 1})) {
                                $retrow = $i + 1;
                            }
                        }
### Compress to better utilize unused space (Not currently working)
                        if (0 == 1 && $spouserow > $newrow) {
                            $delta = ($spouserow - $newrow + ($retrow - $newrow) + 1) / ($retrow - $newrow + 1);
print STDERR "\n\"col\" => $col\n\t\"spouserow\" => $spouserow\n\t\"newrow\" => $newrow\n\t\"retrow\" => $retrow\n\t\"delta\" => $delta";
                            for ($i = $retrow - $newrow; $i > 0; $i--){
                                $lowrow = $newrow + int ($delta * $i) - 1;
print STDERR "\n\t\t$i) \"lowrow\" => $lowrow";
                                if ($lowrow != ($newrow + $i - 1)) {
                                    $table{$lowrow}{$col + 1} = $table{$newrow + $i - 1}{$col + 1};
                                    undef ($table{$newrow + $i - 1}{$col + 1});
                                    if (defined ($relation{$newrow + $i - 1}{$col + 1})) {
                                        $relation{$lowrow}{$col + 1} = $relation{$newrow + $i - 1}{$col + 1};
                                        undef ($relation{$newrow + $i - 1}{$col + 1});
                                    }
                                    $symbol{$lowrow}{$col} = $symbol{$newrow + $i - 1}{$col};
                                    $symbol{$newrow + $i - 1}{$col} = "v_bar";
                                }
                            }
print STDERR "\n";
                        }
#################
                        ++$spouserow;
                    }
                    $retrow = $lastrow;
                    while (defined ($spousym{$spouserow}{$col + 1})) {
                        ++$spouserow;
                    }
                }
                $spouserow = $firstrow + int (($lastrow - $firstrow) / 2);
                ++$row  if ($row && $spoused == 0 && defined ($table{$row - 1}{$col}));
                if (($delta = $row - $spouserow) > 0) {
                    $firstrow += $delta;
                    $lastrow += $delta;
                    $spouserow += $delta;

                    for ($j = $col + 1; $j < @rowsav; $j++) {
                        if (($j - ($col + 1)) < @savsav) {
                            $lowrow = $savsav[$j - ($col + 1)];
                        }
                        else {
                            $lowrow = 0;
                        }
                        for ($i = $rowsav[$j] - 1; $i > $lowrow - 1; $i--) {
                            if (defined ($table{$i}{$j})) {
                                $table{$i + $delta}{$j} = $table{$i}{$j};
                                undef ($table{$i}{$j});
                                if (defined ($relation{$i}{$j})) {
                                    $relation{$i + $delta}{$j} = $relation{$i}{$j};
                                    undef ($relation{$i}{$j});
                                }
                            }
                            if (defined ($spousym{$i}{$j})) {
                                $spousym{$i + $delta}{$j} = $spousym{$i}{$j};
                                undef ($spousym{$i}{$j});
                            }
                            if (defined ($symbol{$i}{$j - 1})) {
                                $symbol{$i + $delta}{$j - 1} = $symbol{$i}{$j - 1};
                                undef ($symbol{$i}{$j - 1});
                            }
                        }
                        $maxrow = $rowsav[$j]  if (($rowsav[$j] += $delta) > $maxrow);
                    }
                }
                if ($lastrow == $firstrow) {
                    $symbol{$spouserow}{$col} = "h_bar"  if (defined ($symbol{$spouserow}{$col}));
                    ++$rowsav[$col + 1];
                }
                else {
                    $symbol{$firstrow}{$col} = "se";
                    for ($i = $firstrow + 1; $i < $lastrow; $i++) {
                        $symbol{$i}{$col} = "v_bar"  if (!defined ($symbol{$i}{$col}));
                    }
                    $symbol{$lastrow}{$col} = "ne";
                }
                if ($indi{$idx}->[1]->{"SEX"}->[0] eq "M") {
                    $spouseptr = $fam{$ptr->[$k]}->[1]->{"WIFE"};
                }
                else {
                    $spouseptr = $fam{$ptr->[$k]}->[1]->{"HUSB"};
                }
                if (defined ($spouseptr->[0])) {
                    ($name = $indi{$spouseptr->[0]}->[1]->{"NAME"}->[0]) =~ s/\///g;
                }
                else {
                    $name = "???";
                }
                $table{$spouserow}{$col} = $name;
                if ("east" eq $symbol{$spouserow}{$col}) {
                    $symbol{$spouserow}{$col} = "cross";
                }
                elsif ("ne" eq $symbol{$spouserow}{$col}) {
                    $symbol{$spouserow}{$col} = "north";
                }
                elsif ("se" eq $symbol{$spouserow}{$col}) {
                    $symbol{$spouserow}{$col} = "south";
                }
                elsif ("h_bar" ne $symbol{$spouserow}{$col}) {
                    $symbol{$spouserow}{$col} = "west";
                }
                $spoused++;
                if (1 == $spoused) {
                    $spousym{$spouserow}{$col} = "se_dbl";
                    $row = $spouserow + 1;
                }
                else {
                    if (2 == $spoused) {
                        $row = $prevrow + int (($spouserow - $prevrow) / 2);
                    }
                    else {
                        $spousym{$prevrow}{$col} = "east_dbl";
                    }
                    for ($i = $prevrow + 1; $i < $spouserow; $i++) {
                        $table{$i}{$col} = "||";
                    }
                    $spousym{$spouserow}{$col} = "ne_dbl";
                }
                $prevrow = $spouserow;
            }
        }
        if (1 < $spoused) {
            $rowsav[$col] = $spouserow + 2;
        }
        else {
            $rowsav[$col] = $row + 1;
        }
        ++$rowsav[$col + 1]  if ($spoused && defined ($table{$rowsav[$col + 1] - 1}{$col + 1}));
    }
    else {
        $rowsav[$col] = $row + 1;
    }
    $table{$row}{$col} = $idx;
    $relation{$row}{$col} = $relative  if ($relative && "Natural" ne $relative);
    $symbol{$row}{$col - 1} = "east"  if ($col);
    $maxrow = $rowsav[$col]  if ($rowsav[$col] > $maxrow);
    return ($row);
}

sub traverse {
    my ($idx, $ptr, $num, $i);
    $idx = $_[0];
    $num = @_ > 1 ? $_[1] : 0;
    if (defined ($indi{$idx}->[1]->{"FAMC"})) {
        $ptr = $indi{$idx}->[1]->{"FAMC"};
        if (($maxnum == 0 || $num < $maxnum) && defined ($fam{$ptr->[0]}->[1]->{"HUSB"})) {
            if ($indi{$idx}->[1]->{"SEX"}->[0] eq "M") {
                $string[$num] = "fill";
            }
            else {
                $string[$num] = "v_bar";
            }
            traverse($fam{$ptr->[0]}->[1]->{"HUSB"}->[0], $num + 1);
        }
    }
    print "<tr";
    if ($num) {
        print " valign=\"middle\" align=\"left\"><td><table cellspacing=\"0\" cellpadding=\"0\" border=\"0\"><tr valign=\"middle\" align=\"left\">\n<td style=\"white-space: nowrap;\"";
        for ($i = 1; $i < $num; $i++) {
            print "><img src=\"$PATH/images/$string[$i].gif\" width=\"41\" height=\"21\" style=\"vertical-align: middle;\" alt=\"\" /";
        }
        print "><img src=\"$PATH/images/";
        if ($indi{$idx}->[1]->{"SEX"}->[0] eq "M") {
            print "se";
        }
        else {
            print "ne";
        }
        print ".gif\" width=\"41\" height=\"21\" style=\"vertical-align: middle;\" alt=\"\" /></td>\n<td";
    }
    else {
        print " valign=\"middle\" align=\"left\">\n<td";
    }
    print " style=\"white-space: nowrap;\">&nbsp;";
    prt_anchor ($idx);
    print "</td>\n</tr>";
    if ($num) {
        print "</table></td></tr>";
    }
    if (defined ($ptr)) {
        if (($maxnum == 0 || $num < $maxnum) && defined ($fam{$ptr->[0]}->[1]->{"WIFE"})) {
            if ($indi{$idx}->[1]->{"SEX"}->[0] eq "F") {
                $string[$num] = "fill";
            }
            else {
                $string[$num] = "v_bar";
            }
            traverse($fam{$ptr->[0]}->[1]->{"WIFE"}->[0], $num + 1);
        }
    }
}

sub prt_anchor {
    my ($name, $urlid);
    $urlid = $_[0];
    $urlid =~ s/\@//g;
    print "<a href=\"$gen{'progpath'}";
    print $urlparms  if ($urlparms);
    print $seperator . "ID=$urlid";
    if ($NumGen) {
        print "&NumGen=";
        print ((0 == $maxnum) ? "All" : $maxnum);
    }
    ($name = $indi{$_[0]}->[1]->{"NAME"}->[0]) =~ s/\///g;
    print "\">" . $name . "</a>";
}

sub prt_info {
    if (exists ($_[0]->{"DATE"})) {
        print $_[0]->{"DATE"}->[0];
    }
    if (exists ($_[0]->{"PLAC"})) {
        print "<br />" . $_[0]->{"PLAC"}->[0];
    }
}

sub prt_source {
    my ($ptr, $ptr1);
    if (exists ($_[0]->{"SOUR"})) {
        print "<br />\n   <table cellspacing=\"0\" cellpadding=\"2 border=\"0\">\n";
        print "   <tr valign=\"baseline\"><th align=\"right\" style=\"font-size: x-small;\">Source:</th><td style=\"font-size: x-small;\">";
        $ptr = $_[0]->{"SOUR"};
        if ($ptr->[0] =~ m/^\@\S+?\@$/) {
            if (exists ($source{$ptr->[0]}->[1]->{"TITL"})) {
                $ptr1 = $source{$ptr->[0]}->[1]->{"TITL"};
                if (defined ($ptr->[1]->{"DATA"}->[1]->{"TEXT"})) {
                    $ptr = $ptr->[1]->{"DATA"}->[1]->{"TEXT"};
                    print $ptr1->[0] . ", ";
                }
                else {
                    $ptr = $ptr1;
                }
            }
            else {
                if (defined ($ptr->[1]->{"DATA"}->[1]->{"TEXT"})) {
                    $ptr = $ptr->[1]->{"DATA"}->[1]->{"TEXT"};
                }
            }
            foreach $line (@$ptr) {
                print $line . "<br />"  if (defined ($line));
            }
        }
        else {
            foreach $line (@$ptr) {
                print $line . "<br />"  if (defined ($line));
            }
        }
        print "</td></tr>\n   </table>\n  ";
    }
}

sub format_year {
    my (@hold, $year);
    @hold = split (/\s+/, $_[0]);
    if (@hold < 4 && $hold[0] ne "WFT") {
        if ($hold[0] eq "UNKNOWN" || (@hold > 1 && ($hold[0] eq "ABT." || $hold[0] eq "ABOUT" || $hold[0] eq "AFT." || $hold[0] eq "AFTER" || $hold[0] eq "BEF." || $hold[0] eq "BEFORE"))) {
            $year = ucfirst (lc ($hold[0]));
            $year .= " $hold[@hold-1]"  if (@hold > 1);
        }
        else {
            $year = $hold[@hold-1];
        }
    }
    else {
        $year = "Unknown";
    }
    return ($year);
}

sub sort_file {
    my ($s1, $s2);

    ($s1, $s2) = ($a, $b);

    return (lc ($s1) cmp lc ($s2));
}

