[Bio] / FigWebServices / align_and_tree.cgi Repository:
ViewVC logotype

View of /FigWebServices/align_and_tree.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (download) (annotate)
Sat Nov 12 00:01:44 2011 UTC (8 years, 4 months ago) by golsen
Branch: MAIN
Changes since 1.1: +47 -61 lines
First running version.

# -*- perl -*-
#
# Copyright (c) 2003-2011 University of Chicago and Fellowship
# for Interpretations of Genomes. All Rights Reserved.
#
# This file is part of the SEED Toolkit.
#
# The SEED Toolkit is free software. You can redistribute
# it and/or modify it under the terms of the SEED Toolkit
# Public License.
#
# You should have received a copy of the SEED Toolkit Public License
# along with this program; if not write to the University of Chicago
# at info@ci.uchicago.edu or the Fellowship for Interpretation of
# Genomes at veronika@thefig.info or download a copy from
# http://www.theseed.org/LICENSE.TXT.
#

use strict;
use HTML;
use FIG_CGI;
use FIGgjo;        # colorize_roles, colorize_functions
use gjoseqlib;     # read_fasta, print_alignment_as_fasta
use gjoalign2html; # repad_alignment, color_alignment_by_consensus
use gjonewicklib;
use SAPserver;
use AlignsAndTreesServer qw( peg_alignment_metadata
                             peg_alignment_by_ID
                             peg_tree_by_ID
                             aligns_with_pegID
                           );

use Data::Dumper;
use Carp;

my( $fig, $cgi, $user ) = FIG_CGI::init( debug_save   => 0,
                                         debug_load   => 0,
                                         print_params => 0 );

#  Incoming information:

my $ali_tree_id  = $cgi->param( 'ali_tree_id' );
my @ali_tree_ids = $cgi->param( 'at_ids' );
my $align_format = $cgi->param( 'align_format' );
my $align_id     = $cgi->param( 'align_id' );
my @checked      = $cgi->param( 'checked' );
my $color_aln_by = $cgi->param( 'color_aln_by' ) || 'consensus';
my $fid          = $cgi->param( 'fid' );
my $show_aliases = $cgi->param( 'show_aliases' );
my $show_align   = $cgi->param( 'show_align' );
my $show_tree    = $cgi->param( 'show_tree' );
my $tree_format  = $cgi->param( 'tree_format' );
my $tree_id      = $cgi->param( 'tree_id' );

#  Let's see if we can work out missing values from other data:

$fid         ||= $checked[0] if @checked == 1;
$ali_tree_id ||= $align_id || $tree_id;
if ( ( ! $ali_tree_id ) && $fid )
{
    @ali_tree_ids = AlignsAndTreesServer::aligns_with_pegID( $fid ) if ! @ali_tree_ids;
    $ali_tree_id  = $ali_tree_ids[0] if @ali_tree_ids == 1;
}

#  Move alignment and tree selection information into one id and two booleans

$show_align = ( $ali_tree_id && $show_align ) || $align_id;
$show_tree  = ( $ali_tree_id && $show_tree  ) || $tree_id;
$align_id   = undef;
$tree_id    = undef;


# The html will be assembled here.

print $cgi->header;

my @html = ();
if ( $show_align )
{
    if ( $show_tree )
    {
        push @html, page_head_html( "The SEED: Protein Alignment $ali_tree_id" );
    }
    else
    {
        push @html, page_head_html( "The SEED: Protein Alignment and Tree $ali_tree_id" );
    }
}
else
{
    if ( $show_tree )
    {
        push @html, page_head_html( "The SEED: Protein Tree $ali_tree_id" );
    }
    elsif ( $fid )
    {
        push @html, page_head_html( "The SEED: Protein Alignment and Tree Selector for '$fid'" );
    }
    else
    {
        push @html, page_head_html( "The SEED: Protein Alignment and Tree Selector" );
    }
}

#==============================================================================
#  Alignment and tree format controls:
#==============================================================================

push @html, join( "\n",
                  $cgi->start_form( -method => 'post',
                                    -action => 'align_and_tree.cgi',
                                    -name   => 'alignment'
                                  ),
                  $cgi->hidden( -name => 'fid',     -value =>  $fid ),
                  $cgi->hidden( -name => 'user',    -value =>  $user ),

                  @checked     ? $cgi->hidden( -name => 'checked',     -value => \@checked )    : (),
                  $ali_tree_id ? $cgi->hidden( -name => 'ali_tree_id', -value => $ali_tree_id ) : (),

                  $cgi->checkbox( -name     => 'show_align',
                                  -label    => 'Show alignment',
                                  -override => 1,
                                  -checked  => $show_align
                                ),

                  $cgi->checkbox( -name     => 'show_tree',
                                  -label    => 'Show tree',
                                  -override => 1,
                                  -checked  => $show_tree
                                ),
                  $cgi->br,

                  'Color alignment by: ',
                  $cgi->radio_group( -name     => 'color_aln_by',
                                     -override => 1,
                                     -values   => [ 'consensus', 'residue' ],
                                     -default  => $color_aln_by
                                   ),
                  $cgi->br,

                  'Alignment format: ',
                  $cgi->radio_group( -name     => 'align_format',
                                     -override => 1,
                                     -values   => [ 'default', 'fasta', 'clustal' ],
                                     -default  => $align_format || 'default'
                                   ),
                  $cgi->br,

                  'Tree format: ',
                  $cgi->radio_group( -name     => 'tree_format',
                                     -override => 1,
                                     -values   => [ 'default', 'newick', 'png' ],
                                     -default  => $tree_format || 'default'
                                   ),
                  $cgi->br,

                  $cgi->checkbox( -name     => 'show_aliases',
                                  -label    => 'Show aliases in tree',
                                  -override => 1,
                                  -checked  => $show_aliases
                                ),
                  $cgi->br,

                  $cgi->submit( 'update' ),
                  $cgi->br,
                  $cgi->end_form,
                  "\n"
                ) if $ali_tree_id && ( $show_align || $show_tree );


#------------------------------------------------------------------------------
#  Get the metadata for the alignment and/or tree.
#  The per sequence metadata are:
#
#      [ $peg_id, $peg_length, $trim_beg, $trim_end, $location_string ]
#
#------------------------------------------------------------------------------

my ( $align, $tree, $metaH, @uids, %fid_of_uid, @fids, $fid_funcH, $orgH, $aliasH );
if ( $ali_tree_id && ( $show_align || $show_tree ) )
{
    if ( $show_align )
    {
        ( $align, $metaH ) = AlignsAndTreesServer::peg_alignment_by_ID( $ali_tree_id );
    }
    elsif ( $show_tree )
    {
        ( $tree, $metaH ) = AlignsAndTreesServer::peg_tree_by_ID( $ali_tree_id );
    }
    else
    {
        $metaH = AlignsAndTreesServer::peg_alignment_metadata( $ali_tree_id );
    }

    $metaH && %$metaH
        or push @html, cgi->h2( "No data for alignment and tree '$ali_tree_id'." );

    @uids = keys %$metaH;    # Ids of alignment line and tree tips
    %fid_of_uid = map { $_ => $metaH->{$_}->[0] } @uids;

    my %peg_seen = {};
    @fids = grep { ! $peg_seen{$_}++ } values %fid_of_uid;

    #--------------------------------------------------------------------------
    #  Find the current functions:
    #--------------------------------------------------------------------------

    my $sapObject = SAPserver->new();
    $fid_funcH = $sapObject->ids_to_functions( -ids => \@fids ) || {};

    #--------------------------------------------------------------------------
    #  Get the organism names:
    #--------------------------------------------------------------------------

    $orgH = $sapObject->ids_to_genomes( -ids => \@fids, -name => 1 );

    #------------------------------------------------------------------
    #  Aliases
    #------------------------------------------------------------------
    my %alias;
    if ( $show_aliases ) { 0 }
    $aliasH = \%alias;
    # push @html, '<PRE>', Dumper( $fid_funcH, $orgH ), '</PRE>';
}


#==============================================================================
#  Alignment.  The alignment is triples: [ $seq_id, $def, $aligned_seq ]
#==============================================================================

if ( $show_align )
{
    #----------------------------------------------------------------------
    #  Got the alignment above
    #----------------------------------------------------------------------
    $align && @$align
        or push @html, cgi->h2( "No data for alignment '$ali_tree_id'." );

    #  This defines the ordering.
    my @seq_ids = map { $_->[0] } @$align;

    push @html, "<h2>Alignment $ali_tree_id</h2>\n";

    if ( $align && @$align && ( $align_format eq "fasta" ) )
    {
        my ( $id, $peg );
        my %def = map { $id = $_->[0];
                        $peg = $fid_of_uid{ $id };
                        $id => join( ' ', $id,
                                          ( $fid_funcH->{ $id } ? $fid_funcH->{$id} : () ),
                                          ( $orgH->{ $id }      ? "[$orgH->{$id}]"    : () )
                                   )
                      }
                  @$align;

        push @html, join( "\n",
                          "<PRE>",
                          ( map { ( ">$def{$_->[0]}", $_->[2] =~ m/(.{1,60})/g ) } @$align ),
                          "</PRE>\n"
                        );
    }

    elsif ( $align && @$align && ( $align_format eq "clustal" ) )
    {
        push @html, "<PRE>\n", &to_clustal( $align ), "</PRE>\n";
    }

    elsif ( $align && @$align )
    {
        my ( $align2, $legend );

        #  Color by residue type:

        if ( $color_aln_by eq 'residue' )
        {
            my %param1 = ( align => $align, protein => 1 );
            $align2 = gjoalign2html::color_alignment_by_residue( \%param1 );
        }

        #  Color by consensus:

        else
        {
            my %param1 = ( align => $align );
            ( $align2, $legend ) = gjoalign2html::color_alignment_by_consensus( \%param1 );
        }

        #  Add organism names:

        foreach ( @$align2 ) { $_->[1] = $orgH->{ $_->[0] || '' } }

        #  Build a tool tip with organism names and functions:

        my %tips = map { $_ => [ $_, join( $cgi->hr, $orgH->{ $_ }, $fid_funcH->{ $_ } ) ] }
                   map { $_->[0] }
                   @$align2;
        $tips{ 'Consen1' } = [ 'Consen1', 'Primary consensus residue' ];
        $tips{ 'Consen2' } = [ 'Consen2', 'Secondary consensus residue' ];

        my %param2 = ( align   => $align2,
                       tooltip => \%tips
                     );
        $param2{ legend } = $legend if $legend;

        push @html, join( "\n",
                           scalar gjoalign2html::alignment_2_html_table( \%param2 ),
                           $cgi->br,
                         );
    }
}


#==============================================================================
#  Tree:
#==============================================================================

if ( $show_tree )
{
    $tree ||= AlignsAndTreesServer::peg_tree_by_ID( $ali_tree_id );
    $tree or push @html, cgi->h2( "No data for tree '$ali_tree_id'." );

    push @html, "<h2>Tree $ali_tree_id</h2>\n"  if $tree;

    #------------------------------------------------------------------
    #  Newick tree
    #------------------------------------------------------------------
    if ( $tree && ( $tree_format eq "newick" ) )
    {
	push @html, "<pre>\n" . &gjonewicklib::formatNewickTree( $tree ) . "</pre>\n";
    }

    #------------------------------------------------------------------
    #  PNG tree
    #------------------------------------------------------------------
    elsif ( $tree && ( $tree_format eq "png" ) )
    {
        my $okay;
        eval { require gd_tree_0; $okay = 1 };
        my $fmt;
        if ( $okay && ( $fmt = ( gd_tree::gd_has_png() ? 'png'  :
                                 gd_tree::gd_has_jpg() ? 'jpeg' :
                                                         undef
                               ) ) )
        {
            #------------------------------------------------------------------
            #  Formulate the desired labels
            #------------------------------------------------------------------
            my %labels;
            foreach my $id ( @uids )
            {
                my   $peg = $fid_of_uid{ $id };
                my   @label;
                push @label, $id;
                push @label, $fid_funcH->{ $peg }          if $fid_funcH->{ $peg };
                push @label, "[$orgH->{$peg}]"             if $orgH->{ $peg };
                push @label, html_esc( $aliasH->{ $peg } ) if $aliasH->{ $peg };
        
                $labels{ $id } = join( ' ', @label );
            }

            #------------------------------------------------------------------
            #  Relabel the tips, midpoint root, pretty it up and draw
            #  the tree as printer plot
            #
            #  Adjustable parameters on text_plot_newick:
            #
            #     @lines = text_plot_newick( $node, $width, $min_dx, $dy )
            #------------------------------------------------------------------
            my $tree2 = newick_relabel_nodes( $tree, \%labels );
            my $tree3 = reroot_newick_to_midpoint_w( $tree2 );
        
            $tree = aesthetic_newick_tree( $tree3 );
            my $options = { thickness =>  2,
                            dy        => 15,
                          };
            my $gd = gd_tree::gd_plot_newick( $tree, $options );

            my $name = sprintf( "align_and_tree_%d_%08d.$fmt", $$, int(1e8*rand()) );
            my $file = "$FIG_Config::temp/$name";
            open    TREE, ">$file";
            binmode TREE;
            print   TREE $gd->$fmt;
            close   TREE;
            chmod   0644, $file;

            my $url = &FIG::temp_url() . "/$name";
            push @html, $cgi->br . "\n"
                      . "<img src='$url' border=0>\n"
                      .  $cgi->br . "\n";
        }
        else
        {
            push @html, "<h3>Failed to convert tree to PNG.  Sorry.</h3>\n"
                      . "<h3>Please choose another format above.</h3>\n";
        }
    }

    #------------------------------------------------------------------
    #  Printer plot tree
    #------------------------------------------------------------------
    else
    {
        #------------------------------------------------------------------
        #  Formulate the desired labels:
        #------------------------------------------------------------------
        #  Build a function-to-color translation table based on frequency of
        #  function. Normally white is reserved for the current function, but
        #  there is none here. Assign colors until we run out, then go gray.
        #  Undefined function is not in %func_color, and so is not in
        #  %formatted_func
        #----------------------------------------------------------------------
        my %formatted_func = &FIGgjo::colorize_roles( $fid_funcH );

        my %labels;
        foreach my $id ( @uids )
        {
            my   $peg = $fid_of_uid{ $id };
            my   @label;
            push @label, &HTML::fid_link( $cgi, $peg ) . '&nbsp;';
            push @label, qq(<INPUT Type=checkbox Name=checked Value="$peg">);
            push @label, qq(<INPUT Type=radio    Name=from    Value="$peg">)  if $fid_funcH->{ $peg };
            push @label, $formatted_func{ $fid_funcH->{ $peg } }              if $fid_funcH->{ $peg };
            push @label, "[$orgH->{$peg}]"                                    if $orgH->{ $peg };
            push @label, html_esc( $aliasH->{ $peg } )                        if $aliasH->{ $peg };

            $labels{ $id } = join( ' ', @label );
        }

        #------------------------------------------------------------------
        #  Relabel the tips, midpoint root, and pretty it up.
        #------------------------------------------------------------------

        my $tree2 = newick_relabel_nodes( $tree, \%labels );
        my $tree3 = reroot_newick_to_midpoint_w( $tree2 );
        $tree = aesthetic_newick_tree( $tree3 );

        #------------------------------------------------------------------
        #  Form and JavaScript added by RAE, 2004-Jul-22, 2004-Aug-23.
        #  Modified by GDP to make it DWWM, 2004-Jul-23, 2004-Aug-04.
        #------------------------------------------------------------------

        push @html, join( "\n",
                           $cgi->start_form( -method => 'post',
                                             -target => '_blank',
                                             -action => 'fid_checked.cgi',
                                             -name   => 'protein_tree'
                                           ),
                           $cgi->hidden( -name => 'align_format', -value => $align_format ),
                           $cgi->hidden( -name => 'color_aln_by', -value => $color_aln_by ),
                           $cgi->hidden( -name => 'fid',          -value => $fid ),
                           $cgi->hidden( -name => 'show_aliases', -value => $show_aliases ),
                           $cgi->hidden( -name => 'tree_format',  -value => $tree_format ),
                           $cgi->hidden( -name => 'user',         -value => $user ),
                           ""
                         );

        #------------------------------------------------------------------
        #  Draw the tree as printer plot.
        #------------------------------------------------------------------

        my $plot_options = { chars  => 'html',     # html-encoded unicode box set
                             format => 'tree_lbl', # line = [ $graphic, $label ]
                             dy     =>  1,
                             min_dx =>  1,
                             width  => 64
                           };
        push @html, join( "\n",
                           '',
                           '<DIV Class="tree">',
                           ( map { my ( $line, $lbl ) = @$_;
                                   #  Fix white space for even spacing:
                                   $line =~ s/((&nbsp;)+)/<SPAN Class=w>$1<\/SPAN>/g;
                                   $line =~ s/&nbsp;/&#9474;/g;
                                   #  Output line, with or without label:
                                   $lbl ? "<PRE>$line</PRE> $lbl<BR />"
                                        : "<PRE>$line</PRE><BR />"
                                 }
                             gjonewicklib::text_plot_newick( $tree, $plot_options )
                           ),
                           '</DIV>',
                           '', ''
                         );

        push @html, join ("\n", $cgi->br, &HTML::java_buttons("protein_tree", "checked"), $cgi->br, "");

        push @html, join("\n",
             "For selected (checked) sequences: "
             , $cgi->submit('align'),
             , $cgi->submit('view annotations')
             , $cgi->submit('show regions')
             , $cgi->br
             , ""
             );

        if ( $user )
        {
            push @html, $cgi->submit('assign/annotate') . "\n";

            push @html, join( "\n",
                               $cgi->br,
                               "<A HRef='Html/help_for_assignments_and_rules.html' Target=_blank>Help on Assignments, Rules, and Checkboxes</A>",
                               ""
                             );
        }

        push @html, $cgi->end_form, "\n";
    }

}

#==============================================================================
#  Find alignments and trees with fid
#==============================================================================

if ( ! $show_align && ! $show_tree )
{
    if ( $fid && ! @ali_tree_ids )
    {
        @ali_tree_ids = AlignsAndTreesServer::aligns_with_pegID( $fid );
        push @html, "Sorry, no alignments with protein id '$fid'\n<BR /><BR />\n" if ! @ali_tree_ids;
    }

    if ( @ali_tree_ids )
    {
        push @html, $cgi->h2( "Select an Alignment and/or Tree" );

        push @html, join( "\n",
                          'Select an alignment/tree ID: ',
                          $cgi->start_form( -method => 'post',
                                            -action => 'align_and_tree.cgi',
                                            -name   => 'align_and_tree'
                                          ),
                          $cgi->hidden( -name => 'fid',     -value => $fid ),
                          $cgi->hidden( -name => 'user',    -value => $user ),
                          @checked ? $cgi->hidden( -name => 'checked', -value => \@checked ) : (),

	                  $cgi->scrolling_list( -name   => 'ali_tree_id',
                                                -values => \@ali_tree_ids,
                                                -size   => scalar @ali_tree_ids
                                              ),
                          $cgi->br,

                          $cgi->checkbox( -name     => 'show_align',
                                          -label    => 'Show alignment',
                                          -override => 1,
                                          -checked  => $show_align
                                        ),

                          $cgi->checkbox( -name     => 'show_tree',
                                          -label    => 'Show tree',
                                          -override => 1,
                                          -checked  => $show_tree
                                        ),
                          $cgi->br,

                          'Color alignment by: ',
                          $cgi->radio_group( -name     => 'color_aln_by',
                                             -override => 1,
                                             -values   => [ 'consensus', 'residue' ],
                                             -default  => $color_aln_by
                                           ),
                          $cgi->br,

                          'Alignment format: ',
                          $cgi->radio_group( -name     => 'align_format',
                                             -override => 1,
                                             -values   => [ 'default', 'fasta', 'clustal' ],
                                             -default  => $align_format || 'default'
                                           ),
                          $cgi->br,

                          'Tree format: ',
                          $cgi->radio_group( -name     => 'tree_format',
                                             -override => 1,
                                             -values   => [ 'default', 'newick', 'png' ],
                                             -default  => $tree_format || 'default'
                                           ),
                          $cgi->br,

                          $cgi->checkbox( -name     => 'show_aliases',
                                          -label    => 'Show aliases in tree',
                                          -override => 1,
                                          -checked  => $show_aliases
                                        ),
                          $cgi->br,

                          $cgi->submit( 'show' ),
                          $cgi->br,
                          $cgi->end_form,
                          ''
                        );
    }

    #==============================================================================
    #  Request a fid
    #==============================================================================

    else
    {
        push @html, $cgi->h2( "Enter a Protein ID for an Alignment and/or Tree" );

        push @html, join( "\n",
                          $cgi->start_form( -method => 'post',
                                            -action => 'align_and_tree.cgi',
                                            -name   => 'align_and_tree'
                                          ),
                          $cgi->hidden( -name => 'user', -value => $user ),
                          @checked ? $cgi->hidden( -name => 'checked', -value => \@checked ) : (),

                          'Enter a SEED protein id: ',
                          $cgi->textfield( -name => "fid", -size => 32 ),
                          $cgi->br,

                          $cgi->checkbox( -name     => 'show_align',
                                          -label    => 'Show alignment',
                                          -override => 1,
                                          -checked  => $show_align
                                        ),

                          $cgi->checkbox( -name     => 'show_tree',
                                          -label    => 'Show tree',
                                          -override => 1,
                                          -checked  => $show_tree
                                        ),
                          $cgi->br,

                          'Color alignment by: ',
                          $cgi->radio_group( -name     => 'color_aln_by',
                                             -override => 1,
                                             -values   => [ 'consensus', 'residue' ],
                                             -default  => $color_aln_by
                                           ),
                          $cgi->br,

                          'Alignment format: ',
                          $cgi->radio_group( -name     => 'align_format',
                                             -override => 1,
                                             -values   => [ 'default', 'fasta', 'clustal' ],
                                             -default  => $align_format || 'default'
                                           ),
                          $cgi->br,

                          'Tree format: ',
                          $cgi->radio_group( -name     => 'tree_format',
                                             -override => 1,
                                             -values   => [ 'default', 'newick', 'png' ],
                                             -default  => $tree_format || 'default'
                                           ),
                          $cgi->br,

                          $cgi->checkbox( -name     => 'show_aliases',
                                          -label    => 'Show aliases in tree',
                                          -override => 1,
                                          -checked  => $show_aliases
                                        ),
                          $cgi->br,

                          $cgi->submit( 'show' ),
                          $cgi->br,
                          $cgi->end_form,
                          ''
                        );
    }
}

#==============================================================================
#  Report the output
#==============================================================================

print join( '', @html, "\n" );
exit;


#==============================================================================
#  Only subroutines below
#==============================================================================
#  This is a sufficient set of escaping for text in HTML (function and alias):
#
#     $html = html_esc( $text )
#------------------------------------------------------------------------------

sub html_esc { local $_ = $_[0]; s/\&/&amp;/g; s/\>/&gt;/g; s/\</&lt;/g; $_ }


sub to_clustal
{
    my($alignment) = @_;

    my($tuple,$seq,$i);
    my $len_name = 0;
    foreach $tuple (@$alignment)
    {
	my $sz = length($tuple->[0]);
	$len_name = ($sz > $len_name) ? $sz : $len_name;
    }

    my @seq  = map { $_->[2] } @$alignment;
    my $seq1 = shift @seq;
    my $cons = "\377" x length($seq1);
    foreach $seq (@seq)
    {
	$seq  = ~($seq ^ $seq1);
	$seq  =~ tr/\377/\000/c;
	$cons &= $seq;
    }
    $cons =~ tr/\000/ /;
    $cons =~ tr/\377/*/;

    push(@$alignment,["","",$cons]);

    my @out = ();
    for ($i=0; ($i < length($seq1)); $i += 50)
    {
	foreach $tuple (@$alignment)
	{
	    my($id,undef,$seq) = @$tuple;
	    my $line = sprintf("\%-${len_name}s %s\n", $id, substr($seq,$i,50));
	    push(@out,$line);
	}
	push(@out,"\n");
    }
    return join("","CLUSTAL W (1.8.3) multiple sequence alignment\n\n\n",@out);
}


sub page_head_html
{
    my ( $title ) = @_;

    $title ||= 'The SEED: Alignments and Trees';

#  This stuff is because different browsers render the contents differently.

    my $agent  = $ENV{ HTTP_USER_AGENT } || '';
    my $height = $agent =~ /Safari/i  ? '110%'
               : $agent =~ /Firefox/i ? '100%'
               :                        '100%';
    my $lsize  = $agent =~ /Safari/i  ? '160%'
               : $agent =~ /Firefox/i ? '130%'
               :                        '140%';

    return <<"End_of_Head";
<HTML>
<HEAD>
<TITLE>$title</TITLE>

<STYLE Type="text/css">
  /* Support for HTML printer graphics tree */
  DIV.tree {
    border-spacing: 0px;
    font-size:     100%;
    line-height:    $height;
    white-space: nowrap;
  }
  DIV.tree A {
    text-decoration: none;
  }
  DIV.tree PRE {
    padding:    0px;
    margin:     0px;
    font-size: $lsize;
    display: inline;
  }
  DIV.tree INPUT {
    padding: 0px;
    margin:  0px;
    height: 10px;    /* ignored by Firefox */
    width:  10px;    /* ignored by Firefox */
  }
  DIV.tree SPAN.w {  /* used for tree white space */
    color: white;
  }
</STYLE>

</HEAD>
<BODY>
End_of_Head

}

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3