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

Annotation of /FigWebServices/pir.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.25 - (view) (download)

1 : redwards 1.1 # -*- perl -*-
2 :    
3 :     =pod
4 :    
5 :     =head1
6 :    
7 :     Compare some data between SEED and PIR. We probably need to add things like p2p or automatic ftp gets or something like that
8 :    
9 :     =cut
10 :    
11 :     use strict;
12 :     use FIG;
13 :     use HTML;
14 :     use raelib;
15 :     use CGI;
16 :     my $cgi=new CGI;
17 : redwards 1.22 use LWP::Simple qw(!head); # see the caveat in perldoc LWP about importing two head methods.
18 : redwards 1.1
19 :     my $fig;
20 :     eval {
21 :     $fig = new FIG;
22 :     };
23 :    
24 :     if ($@ ne "")
25 :     {
26 :     my $err = $@;
27 :    
28 :     my(@html);
29 :    
30 :     push(@html, $cgi->p("Error connecting to SEED database."));
31 :     if ($err =~ /Could not connect to DBI:.*could not connect to server/)
32 :     {
33 :     push(@html, $cgi->p("Could not connect to relational database of type $FIG_Config::dbms named $FIG_Config::db on port $FIG_Config::dbport."));
34 :     }
35 :     else
36 :     {
37 :     push(@html, $cgi->pre($err));
38 :     }
39 :     &HTML::show_page($cgi, \@html, 1);
40 :     exit;
41 :     }
42 :    
43 :    
44 :    
45 :     $ENV{"PATH"} = "$FIG_Config::bin:$FIG_Config::ext_bin:" . $ENV{"PATH"};
46 :    
47 : redwards 1.22
48 :     # these should probably be in FIG::Config. Oh well.
49 :     my $pir_file_from_pir="$FIG_Config::data/Global/pirsfinfo.dat";
50 :     my $pir_correspondence_file="$FIG_Config::data/Global/pirsfcorrespondence.txt";
51 :     my $pir_source_file="ftp://ftp.pir.georgetown.edu/pir_databases/pirsf/data/pirsfinfo.dat";
52 :    
53 :     # ha ha ha ha ha
54 :     # I am an idiot, and can't spell. so we need to correct that and make sure we always use an e
55 :     if (-e "$FIG_Config::data/Global/pirsfcorrespondance.txt") {rename("$FIG_Config::data/Global/pirsfcorrespondance.txt", $pir_correspondence_file)}
56 :    
57 :    
58 :    
59 : redwards 1.1 my $html = [];
60 :     my $user = $cgi->param('user');
61 :    
62 : redwards 1.19 unshift(@$html, "<TITLE>The SEED - PIR/SEED comparisons </TITLE>\n");
63 : redwards 1.1 # make sure that we read the file at the beginning
64 : redwards 1.22 my ($pegbypir, $pirid) =&read_pir_file("initial");
65 :    
66 : redwards 1.1
67 :    
68 : redwards 1.17 if ($cgi->param('submit') eq "Tabulate summary") {
69 : redwards 1.9 $html=&table_annotations($html, $pegbypir, $pirid);
70 : redwards 1.22 push @$html, $cgi->p({class=>"diagnostic"}, ("\n<small>Generating this table took approximately " . (time-$^T) . " seconds\n</small>"));
71 :     }
72 : redwards 1.24 elsif ($cgi->param('submit') =~ m/^Update/) {
73 :     # this should catch Update Data and Updata Anyway
74 :     $html=&update_data($html);
75 :     }
76 : redwards 1.22 elsif ($cgi->param('submit') eq "Check for updates") {
77 :     $html=&check_updates($html);
78 :     push @$html, $cgi->p({class=>"diagnostic"}, ("\n<small>Checking for updates took approximately " . (time-$^T) . " seconds\n</small>"));
79 : redwards 1.5 }
80 : redwards 1.17 elsif ($cgi->param('pirsf') && !($cgi->param('submit') eq "Update view")) {
81 : overbeek 1.21 # we want to display one of the correspondences
82 : redwards 1.5 my $selfurl=$cgi->url;
83 : redwards 1.23 push @$html, $cgi->p, "<a href=\"/FIG/Html/pir.html#correspondence\" class=\"help\" target=\"pirhelp\">Help on this correspondence table</a>";
84 : redwards 1.22 if ($cgi->param('ssonly')) {push @$html, "<a href=\"$selfurl?pirsf=" . $cgi->param("pirsf") . "&user=$user\">Show All Matches</a>\n"}
85 :     else {push @$html, "<a href=\"$selfurl?pirsf=" . $cgi->param("pirsf") . "&ssonly='1'&user=$user\">Show only matches with a subsystem</a>\n"}
86 : redwards 1.5
87 : overbeek 1.21 my $col_hdrs = ["PIR Superfamily<br><small>Link goes to PIR<small>", "Genome", "UniProt","PEG", "FIG Function", "FIG Subsystem"];
88 : redwards 1.1 my $tab = [];
89 : redwards 1.22
90 :     # figure out the colors
91 : redwards 1.23 my %color;
92 :     {
93 :     my %function_cnt; my $max;
94 :     foreach my $peg (@{$pegbypir->{$cgi->param('pirsf')}}) {
95 :     $function_cnt{scalar $fig->function_of($peg)}++;
96 :     }
97 :    
98 :     my @all_functions=sort {$function_cnt{$b} <=> $function_cnt{$a}} keys %function_cnt;
99 :     my @color=&cool_colors();
100 :    
101 :     for (my $i=0; $i<=$#all_functions; $i++) {
102 :     if ($i > $#color) {$color{$all_functions[$i]}="#FFFFFF"}
103 :     else {$color{$all_functions[$i]}=$color[$i]}
104 :     }
105 : redwards 1.22 }
106 :    
107 : redwards 1.2 foreach my $peg (@{$pegbypir->{$cgi->param('pirsf')}}) {
108 : redwards 1.1 my @sslinks;
109 :     foreach my $subsys ($fig->subsystems_for_peg($peg)) {
110 : redwards 1.22 my $spaced=$$subsys[0];
111 :     $spaced =~ s/_/ /g;
112 :     push @sslinks, $cgi->a({href => "subsys.cgi?&user=$user&ssa_name=" . $$subsys[0] . "&request=show_ssa"}, $spaced);
113 : redwards 1.1 }
114 :    
115 :     my $pirlink=$cgi->param('pirsf');
116 : redwards 1.2 $pirlink =~ /^PIR(SF\d+)/;
117 :     $pirlink="<a href='http://pir.georgetown.edu/sfcs-cgi/new/pirclassif.pl?id=$1'>PIR$1</a>" . $pirid->{$cgi->param('pirsf')};
118 : redwards 1.4 next if ($cgi->param("ssonly") && !(scalar @sslinks));
119 : redwards 1.22 push (@$tab,
120 :     [$pirlink,
121 :     $fig->genus_species($fig->genome_of($peg)),
122 :     &HTML::uni_link($cgi,$fig->to_alias($peg,"uni")),
123 :     &HTML::fid_link($cgi, $peg, 1),
124 : redwards 1.23 [scalar $fig->function_of($peg), "td style=\"background: $color{scalar $fig->function_of($peg)}\""],
125 : redwards 1.22 (join ", ", @sslinks)]
126 :     );
127 : redwards 1.1 }
128 : redwards 1.22 push(@$html,&HTML::make_table($col_hdrs,$tab,"\nCorrespondence between SEED and PIR"));
129 : redwards 1.1 }
130 :     else {
131 :     unshift @$html, "<TITLE>The SEED - PIR comparison page</TITLE>\n";
132 :     &show_initial($fig,$cgi,$html);
133 :     }
134 :    
135 :     &HTML::show_page($cgi,$html,1);
136 :     exit;
137 :    
138 :    
139 :    
140 :    
141 :    
142 :     sub show_initial {
143 :     my ($fig,$cgi,$html)=@_;
144 :     # generate a blank page
145 :     # we want a list of all functions that have >= 1 peg unless we want all
146 :     my $min=10;
147 :     if ($cgi->param("min")) {$min=$cgi->param("min")}
148 :     if ($cgi->param("showall")) {$min=0}
149 :     my $full=1;
150 :     if ($cgi->param("preliminary")) {$full=0}
151 :     # count different subsystems per sf
152 :     my $ss; my @pirsf;
153 : redwards 1.2 foreach my $sf (keys %$pegbypir) {
154 :     next unless ($pegbypir->{$sf});
155 :     next unless (scalar @{$pegbypir->{$sf}} >= $min);
156 :     next if ($full && $pirid->{$sf} =~ /\(preliminary\)/i);
157 :     next if (!$full && $pirid->{$sf} =~ /\(full/i);
158 : redwards 1.1 push @pirsf, $sf;
159 :     if ($cgi->param('showsubsys')) {
160 : redwards 1.2 foreach my $peg (@{$pegbypir->{$sf}}) {
161 : redwards 1.1 foreach my $subsys ($fig->subsystems_for_peg($peg)) {
162 :     $ss->{$sf}->{$$subsys[0]}++;
163 :     }
164 :     }
165 :     }
166 :     }
167 :    
168 :     # now generate the labels
169 :     my $display;
170 :     foreach my $sf (@pirsf) {
171 :     next unless ($sf);
172 : redwards 1.2 my $displayname=$pirid->{$sf};
173 : redwards 1.1 if (length($displayname) > 50) {$displayname=substr($displayname, 0, 50)}
174 : redwards 1.2 if ($cgi->param('showsubsys')) {$display->{$sf}=$displayname . " [". scalar @{$pegbypir->{$sf}} . "/". (scalar keys %{$ss->{$sf}}) . "]"}
175 :     else {$display->{$sf}=$displayname . " [". scalar @{$pegbypir->{$sf}} . "]"}
176 : redwards 1.1 }
177 :    
178 : redwards 1.22
179 : redwards 1.1 push (@$html, $cgi->start_form(-action => "pir.cgi"),
180 :     $cgi->h2("Please choose your super family"),
181 : redwards 1.22 "\nFirst, please enter a username: ", $cgi->textfield(-name=>"user", -value=>$user), $cgi->p,
182 : redwards 1.23 "\n<a href=\"/FIG/Html/pir.html\" class=\"help\" target=\"pirhelp\">Help on SEED/PIR Correspondence</a>",
183 : redwards 1.22 "\nThe list shows the PIR superfamilies. If only one number is shown (default) this is the number of PEGs that map to that superfamily. ",
184 :     "\nIf you choose to show subsystem counts in this menu, you will get two numbers. The first of the two numbers in parenthesis is the number ",
185 :     "\nof PEGs that map to that superfamily, and the second number in parenthesis is the number of <em>different</em> ",
186 :     "\nsubsystems that those PEGs are in.\n", $cgi->p,"\n",
187 :     $cgi->scrolling_list(-name=>'pirsf', -values=>[keys %$display], -labels=>$display, -size=>10), $cgi->p,"\n",
188 :     "\nNummber of superfamilies shown: ", scalar keys %$display, $cgi->p,"\n",
189 : redwards 1.23 "\n<a href=\"/FIG/Html/pir.html#menu\" class=\"help\" target=\"pirhelp\">Help on the menu contents</a>","\n",
190 : redwards 1.22 "\nMinimum number of pegs per PIR superfamily shown in list &nbsp; <input type='text' name='min' value='$min' size=3 />","\n",
191 :     "\nor show all PIR superfamilies: ", $cgi->checkbox(-name=>"showall", -label=>""), $cgi->p,"\n",
192 :     $cgi->checkbox(-name=>"showsubsys", -label=>"Show subsystem counts in list"), $cgi->p,"\n",
193 :     $cgi->checkbox(-name=>"preliminary", -label=>"Show only preliminary PIR superfamilies"), $cgi->p,"\n",
194 :     $cgi->submit('submit', 'Update view'),"\n",
195 :     $cgi->submit('submit', 'Show Correspondence'),"\n",
196 :     $cgi->reset,"\n",
197 :     $cgi->p, $cgi->hr, $cgi->p,"\n",
198 :     $cgi->p("<strong>Generate Data Tables</strong>"),
199 : redwards 1.23 "<a href=\"/FIG/Html/pir.html#datatables\" class=\"help\" target=\"pirhelp\">Help on Generating Data Tables</a>",
200 : redwards 1.22 $cgi->p("The data tables are an alternative way to view the data in summary form. For the summary of the comparisons between PIR and SEED annotations, please check here:\n"),
201 :     $cgi->checkbox(-name=>"onlyss", -label=>"Show only those PEGs that are in a subsystem and a superfamily", -checked=>"on"), $cgi->p,"\n",
202 :     $cgi->checkbox(-name=>"totalsort", -label=>"Sort by the total number of different annotations"), $cgi->p,"\n",
203 :     $cgi->submit('submit', 'Tabulate summary'),"\n",
204 :     $cgi->reset,"\n",
205 :     $cgi->p, $cgi->hr, "\n",
206 :     $cgi->p("<strong>Check for Updates</strong>"),"\n",
207 : redwards 1.23 "<a href=\"/FIG/Html/pir.html#updates\" class=\"help\" target=\"pirhelp\">Help on updates</a>", "\n",
208 : redwards 1.22 $cgi->p("Please click the button to check the PIR site and see whether there is a new version of the PIR superfamily data you should use"),"\n",
209 :     $cgi->submit('submit', 'Check for updates'),"\n",
210 : redwards 1.1 $cgi->end_form,
211 :     );
212 :    
213 :     }
214 :    
215 :    
216 :    
217 :     =head1 read_pir_file
218 :    
219 :     Read the PIR data file that describes superfamilies and the PIR proteins that have those families.
220 :     The PIR data file is from ftp://ftp.pir.georgetown.edu/pir_databases/pirsf/data/pirsfinfo.dat and
221 :     contains the family name beginning with a > and then a list of PIR ids.
222 :    
223 : redwards 1.2 I split this using the PIRSF\d+ and return two hashes. One that correlates PIRSF\d+ to fig id and one
224 :     that correlates it to superfamily names.
225 : redwards 1.1
226 :     =cut
227 :    
228 :     sub read_pir_file {
229 : redwards 1.22 unless (-e $pir_file_from_pir) {
230 : redwards 1.23 # background the job here
231 :     &update_data($html);
232 :     }
233 : redwards 1.22 # just read the file, convert it to an HTML table and return it
234 :     unless (-e $pir_correspondence_file) {
235 :     #print STDERR "Can't find the correspondence file pirsfcorrespondence.txt so we are going to make it\n";
236 :     raelib->pirsfcorrespondence($pir_file_from_pir, $pir_correspondence_file);
237 : redwards 1.23 push @$html, "<h2 style=\"background: red\">The PIR correspondence file was rebuilt for you</h2>";
238 : redwards 1.1 }
239 : redwards 1.22 open (IN, $pir_correspondence_file) || die "Can't open $pir_correspondence_file";
240 : redwards 1.1 my $pir;
241 : redwards 1.2 my $functions;
242 :     my $id;
243 : redwards 1.1 my $added;
244 :     while (<IN>) {
245 :     chomp;
246 :     if (s/^>//) {
247 :     unless ($added) {
248 :     # we didn't find anything that maps here
249 : redwards 1.2 $pir->{$id}=undef;
250 : redwards 1.1 }
251 : redwards 1.2 /^(PIRSF\d+)\s+(.*?)$/;
252 :     $id=$1;
253 :     $functions->{$id}=$2;
254 : redwards 1.1 undef $added;
255 :     }
256 :     else {
257 : redwards 1.2 my ($pirid, $peg)=split /\t/;
258 : redwards 1.1 next unless ($peg);
259 : redwards 1.2 push @{$pir->{$id}}, $peg;
260 : redwards 1.1 $added=1;
261 :     }
262 :     }
263 : redwards 1.2 return $pir, $functions;
264 : redwards 1.1 }
265 : redwards 1.5
266 : redwards 1.9 =head1 table_annotations
267 : redwards 1.5
268 : redwards 1.9 Return a table sorted by the number of annotations, and list a bunch of stuff
269 : redwards 1.5
270 :     =cut
271 :    
272 : redwards 1.9 sub table_annotations {
273 :     my ($html, $pegbypir, $pirid)=@_;
274 : redwards 1.12 my $count; my $subsystems; my $countinss;
275 : redwards 1.9 foreach my $sf (keys %$pegbypir) {
276 : redwards 1.12 my $function; my $ss; my $functionandss;
277 : redwards 1.9 foreach my $peg (@{$pegbypir->{$sf}}) {
278 : redwards 1.13 my $fn=scalar $fig->function_of($peg);
279 : redwards 1.16 my $newss=0; # this is a boolean to see whether this peg has a subsys associated with it.
280 :     foreach my $subsys ($fig->subsystems_for_peg($peg)) {$ss->{$$subsys[0]}++; $newss++}
281 : redwards 1.13 $function->{$fn}++;
282 : redwards 1.16 $functionandss->{$fn}++ if ($newss);
283 : redwards 1.5 }
284 : redwards 1.9 $subsystems->{$sf}=join "; ", keys %$ss;
285 :     $count->{$sf}=scalar keys %$function;
286 : redwards 1.12 $countinss->{$sf}=scalar keys %$functionandss;
287 : redwards 1.5 }
288 :    
289 : redwards 1.12 my $col_hdrs = ["Number of annotations in subsystems", "Number of SEED annotations", "PIRSF<br><small>(Link goes to SEED/PIR comparison)</small>",
290 : redwards 1.6 "Superfamily name", "Subsystems in superfamily"];
291 : redwards 1.10 my $tab; my $lastcount; my $row;
292 : redwards 1.12 # note we are going to make a new table every 200 or so rows because that way the browsers don't get messed up. We actually increment between two identical counts
293 :     my @superfamilies=sort {$countinss->{$b} <=> $countinss->{$a}} keys %$count;
294 :     if ($cgi->param('totalsort')) {@superfamilies=sort {$count->{$b} <=> $count->{$a}} keys %$count}
295 :     foreach my $sf (@superfamilies) {
296 :     next if ($cgi->param('onlyss') && !($countinss->{$sf}));
297 : redwards 1.10 $row++;
298 : redwards 1.9 if ($lastcount ne $count->{$sf}) {
299 :     $lastcount=$count->{$sf};
300 : redwards 1.12 if ($tab && ($row > 200)) {
301 : redwards 1.10 push(@$html,&HTML::make_table($col_hdrs,$tab,""));
302 : redwards 1.18 my $et=time-$^T;
303 :     print STDERR "pir.cgi: Added to table at $lastcount after $et total seconds\n";
304 : redwards 1.10 $row=0;
305 :     undef $tab;
306 :     }
307 : redwards 1.9 }
308 :     push @$tab, [
309 : redwards 1.22 "\n".$countinss->{$sf},
310 : redwards 1.9 $count->{$sf},
311 : redwards 1.22 "<a href=\"/FIG/pir.cgi?pirsf=$sf&ssonly='1'&user='$user'\">$sf</a>",
312 : redwards 1.9 $pirid->{$sf},
313 :     $subsystems->{$sf},
314 :     ];
315 : redwards 1.5 }
316 : redwards 1.6 push(@$html,&HTML::make_table($col_hdrs,$tab,""));
317 : redwards 1.5 return $html;
318 :     }
319 : redwards 1.22
320 :    
321 :     =pod
322 :    
323 :     =head2 check_updates()
324 :    
325 :     Check the PIR remote site and see whether there are updates that we need to get
326 :    
327 :     =cut
328 :    
329 :     sub check_updates {
330 :     my $html=shift;
331 :    
332 :     # first lets see if we can get the times of the updates to see if we have a newer file
333 :     # using LWP::Simple. this is straight from the perldoc
334 :     my ($content_type, $document_length, $remotemtime, $expires, $server)=LWP::Simple::head($pir_source_file);
335 :     my $localmtime=0;
336 :     # if we don't have the file yet, we don't want to panic!
337 :     if (-e $pir_file_from_pir) {
338 :     my @stat=stat($pir_file_from_pir);
339 :     $localmtime=$stat[8];
340 :     }
341 :     # now we are going to translate the difference in times into some English for the website
342 :     if (!$remotemtime) {
343 :     push @$html, $cgi->p({class=>"error"}, "Could not connect to PIR to check the status of the PIR file. Please check the location of $pir_source_file");
344 :     }
345 :     elsif ($remotemtime > $localmtime) {
346 :     # the remote version is newer
347 :     push @$html, $cgi->p("\nThe remote file $pir_source_file is newer than your current file. You should proceed with the update."),
348 :     $cgi->p("\nThe remote file was modified on ". scalar(localtime($remotemtime))),
349 :     $cgi->p("\nThe local file was modified on ". scalar(localtime($localmtime))),
350 :     $cgi->start_form(), $cgi->hidden(-name=>"user", -value=>$user), $cgi->submit('submit', 'Update Data'), $cgi->end_form();
351 :     }
352 :     else {
353 :     # the local version is as new as the remote one.
354 :     push @$html, $cgi->p("\nThe local file is up to date and there is no need to update your source PIR superfamilies."),
355 :     $cgi->p("\nThe remote file was modified on ". scalar(localtime($remotemtime))),
356 :     $cgi->p("\nThe local file was modified on ". scalar(localtime($localmtime))),
357 :     $cgi->start_form(), $cgi->hidden(-name=>"user", -value=>$user), $cgi->submit('submit', 'Update Anyway'), $cgi->end_form();
358 :     }
359 :    
360 :     return $html;
361 :     }
362 :    
363 :    
364 :     =pod
365 :    
366 :     =head2 update_data()
367 :    
368 :     Download the new data file from pir, and generate the correspondence
369 :    
370 :     =cut
371 :    
372 :     sub update_data {
373 :     # rename the old correspondence file. We are going to add a number to the old file so that we keep it, but this should allow us
374 :     # to save the information for a while in case something happens. At somepoint we should probably move these to /tmp or delete them
375 :     # or something.
376 :     my $html=shift;
377 : redwards 1.23
378 :     # here we need to background downloading and installing the data.
379 :     my $bkj=$fig->run_in_background(sub
380 :     {
381 : redwards 1.25 my $time=time;
382 :     print "Loading new PIR superfamily data started at ", scalar(localtime($time)), "\n";
383 : redwards 1.24 system("load_pirsf 1");
384 : redwards 1.25 print "Complete at ", scalar(localtime(time)), ". Running took ", (time-$time)/60, " minutes\n";
385 : redwards 1.23 }
386 :     );
387 :    
388 : redwards 1.24 push @$html, "<h2>Downloading and installing new data has started</h2>",
389 :     "<p>The job has started in the background but will likely take some time.<br />\n",
390 :     "The job has an ID of $bkj, and you can check it out from the <A href=\"/FIG/seed_ctl.cgi\">SEED Control Panel</a></p>\n",
391 :     "<p>You should not use the PIR superfamilies while the job is runnning</p>\n";
392 :    
393 : redwards 1.23
394 :     return $html;
395 : redwards 1.22 }
396 :    
397 :    
398 :    
399 :    
400 :    
401 :    
402 :     sub cool_colors {
403 :     # just an array of "websafe" colors or whatever colors we want to use. Feel free to remove bad colors (hence the lines not being equal length!)
404 :     return (
405 :     '#C0C0C0', '#FF40C0', '#FF8040', '#FF0080', '#FFC040', '#40C0FF', '#40FFC0', '#C08080', '#C0FF00', '#00FF80', '#00C040',
406 :     "#6B8E23", "#483D8B", "#2E8B57", "#008000", "#006400", "#800000", "#00FF00", "#7FFFD4",
407 :     "#87CEEB", "#A9A9A9", "#90EE90", "#D2B48C", "#8DBC8F", "#D2691E", "#87CEFA", "#E9967A", "#FFE4C4", "#FFB6C1",
408 :     "#E0FFFF", "#FFA07A", "#DB7093", "#9370DB", "#008B8B", "#FFDEAD", "#DA70D6", "#DCDCDC", "#FF00FF", "#6A5ACD",
409 :     "#00FA9A", "#228B22", "#1E90FF", "#FA8072", "#CD853F", "#DC143C", "#FF6347", "#98FB98", "#4682B4",
410 :     "#D3D3D3", "#7B68EE", "#FF7F50", "#FF69B4", "#BC8F8F", "#A0522D", "#DEB887", "#00DED1",
411 :     "#6495ED", "#800080", "#FFD700", "#F5DEB3", "#66CDAA", "#FF4500", "#4B0082", "#CD5C5C",
412 :     "#EE82EE", "#7CFC00", "#FFFF00", "#191970", "#FFFFE0", "#DDA0DD", "#00BFFF", "#DAA520",
413 :     "#00FF7F", "#9400D3", "#BA55D3", "#D8BFD8", "#8B4513", "#3CB371", "#5F9EA0", "#4169E1", "#20B2AA", "#8A2BE2", "#ADFF2F",
414 :     "#F0FFFF", "#B0E0E6", "#FF1493", "#B8860B", "#FF0000", "#F08080", "#7FFF00", "#8B0000",
415 :     "#40E0D0", "#0000CD", "#48D1CC", "#8B008B", "#696969", "#AFEEEE", "#FF8C00", "#EEE8AA", "#A52A2A",
416 :     "#FFE4B5", "#B0C4DE", "#FAF0E6", "#9ACD32", "#B22222", "#FAFAD2", "#808080", "#0000FF",
417 :     "#000080", "#32CD32", "#FFFACD", "#9932CC", "#FFA500", "#F0E68C", "#E6E6FA", "#F4A460", "#C71585",
418 :     "#BDB76B", "#00FFFF", "#FFDAB9", "#ADD8E6", "#778899",
419 :     );
420 :     }
421 :    

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3