#!/bin/bash
######################################################################
#                               gff2ps                               #
######################################################################
#
#     Converting GFF files to PostScript.
#
#     Copyright (C) 1999 - Josep Francesc ABRIL FERRANDO  
#                                 Roderic GUIGO SERRA       
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
######################################################################
#
# Creation Date: 01.03.1999
# Last Update:
#         $Id: gff2ps,v 1.98 2002/11/08 18:12:47 jabril Exp $	
#
# Autor : Josep Francesc ABRIL FERRANDO
# e-mail: jabril@imim.es
#
# ( ./gff2ps -vC mygffcustomfile -- samples/data.gff > samples/.ps ) > & samples/report.
#
#
SECONDS=0; # For timing purposes

# Only for testing (only works in bash)
# set -o xtrace

GAWK="/bin/gawk";

##############################################################
#################### PROGRAM DEFINITIONS #####################
# 
# TT_start=`date +%T`;
CMDLine=$0" "$*;
PID=$$;
TEMP="/tmp";
  if [ $GFF2PS_TMP ];
    then
      if [ -d "$GFF2PS_TMP" ];      ###### Environment variable for temporary files directory.
        then
          TEMP="$GFF2PS_TMP";
        fi;
    fi;
PSHEAD=$TEMP/HEADPS.$PID;
PSMAIN=$TEMP/MAINPS.$PID;
GWKPRG=$TEMP/GAWKCODE.$PID;
GWKOPT=$TEMP/GAWKOPTS.$PID;

#
# To delete temporary files if program breaks...
trap "rm -f $GWKPRG $GWKOPT $PSHEAD $PSMAIN 2>/dev/null; exit 1" 0 1 2 3 9 15 ;
 
# 
# Defining Default Values...
RCSVERSION='$Id: gff2ps,v 1.98 2002/11/08 18:12:47 jabril Exp $';
AAA=`echo $RCSVERSION | $GAWK '{ print substr($0,2,length($0)-2); }'`;
#
Defaults () {
 # 
 # Constants: 
  PROGRAM="gff2ps";
  GAWK_PROG="gff2ps.awk";
  VERSION="v0.98c";
  CREATIONDATE="1999/03/01"; # PSCREATION="1999/03/01"
  REVISION=`echo $RCSVERSION | $GAWK '{print $3}'`;
  DATERELEASE=`echo $RCSVERSION | $GAWK '{print $3,$4}'`;
  PSPROGRAM="PostScript Output from gff2ps";
  AUTHOR="Josep Francesc ABRIL FERRANDO";
  EMAIL="jabril@imim.es";
  USAGE=$PROGRAM" [-h] [ ...(See available options with -h)... ] -- gff_files";
  COLORS="       Basic Colors: black white
       Variable Colors: grey magenta violet blue skyblue cyan seagreen green limegreen yellow orange red brown
       You can get five color shades from Variable Colors with \"verydark\", \"dark\", \"light\" and \"verylight\" prefixes.
         An example: verydarkseagreen darkseagreen seagreen lightseagreen verylightseagreen";
  PAGES="       From A0 to A10, from B0 to B10, 10x14, executive, folio, ledger, legal, letter, quarto, statement and tabloid.";
 # 
 # Default User-Defined Options:
  CFDIR=`pwd`;
  if [ $GFF2PS_CFDIR ];
    then
      if [ -d "$GFF2PS_CFDIR" ];      ###### Environment variable for custom file directory.
        then
          CFDIR="$GFF2PS_CFDIR";
        fi;
    fi;
  bgcolor="white";
  fgcolor="black";
  v01=0; n01="load_customfile";
  v02=""; n02="customfile_name";
  if [ $GFF2PS_CUSTOMFILE ];         ###### Environment variable for default custom file name.
    then
      v03="$CFDIR/$GFF2PS_CUSTOMFILE";
    else
      v03="$CFDIR/.gff2psrc";
    fi;
    n03="customfile_name_default";
  v04=0; n04="exist_default_customfile";
  v04_1=0; n04_1="create_default_customfile";
  v05=0; n05="print_report";
  v06="!!!???"; n06="page_orientation"; # "Landscape"
  v07="!!!???"; n07="page_size"; # "a4"
  v08="!!!???"; n08="page_number"; # 1
  v09="!!!???"; n09="blocks_x_page"; # 1
  v10="!!!???"; n10="nucleotides_x_line"; # 0
  v11="!!!???"; n11="show_blocks_top-bottom"; # 1
  v12="!!!???"; n12="page_bbox"; # "auto,0,0"
  v13="!!!???"; n13="major_tickmarks_num"; # 10
  v14="!!!???"; n14="major_tickmarks_nucleotides"; # -1
  v15="!!!???"; n15="minor_tickmarks_num"; # 10
  v16="!!!???"; n16="minor_tickmarks_nucleotides"; # -1
  v17="!!!???"; n17="show_positions"; # "false"
  v18_s='*'; v18_e='*'; n18="zoom_cmdln";
  v19="!!!???"; n19="foreground_color"; # "FGcolor"
  v20="!!!???"; n20="background_color"; # "BGcolor"
  v21="!!!???"; n21="header_style"; # "default"
  v22="!!!???"; n22="show_page_numbers"; # "on"
  v23="!!!???"; n23="show_date"; # "on"
  v24="!!!???"; n24="show_time"; # "on"
  v25="!!!???"; n25="title"; # "default"
  v26="!!!???"; n26="subtitle"; # "default"
  v27="!!!???"; n27="strand_show_forward"; # "on"
  v28="!!!???"; n28="strand_show_reverse"; # "on"
  v29="!!!???"; n29="strand_show_independent"; # "on"
  v30="!!!???"; n30="frame0_color"; # "blue"
  v31="!!!???"; n31="frame1_color"; # "red"
  v32="!!!???"; n32="frame2_color"; # "green"
  v33="!!!???"; n33="frame_unknown_color"; # "orange"
  v34=1; n34="quiet_mode";
  v35=1; n35="Show_Credits";
  v36="!!!???"; n36="page_bbox"; # "name,width,height"
  # 
  CHOSFLG=0;
  CHOSFILE="none";
} # End of Defaults

#  
# Default ColorDefinition:
#
colorDef () { # still not defined seagreen and limegreen (now same as green)
cat <<'@@@COLORS@@@'
%
% COLORS.gff2ps,v 1.3 1999/12/14 09:20:05 jabril Exp jabril
%
% black+grey+white
black               0.00 0.00 0.00 1.00
greyd               0.00 0.00 0.00 0.90
verydarkgrey        0.00 0.00 0.00 0.80
greyc               0.00 0.00 0.00 0.70
darkgrey            0.00 0.00 0.00 0.60
greyb               0.00 0.00 0.00 0.50
grey                0.00 0.00 0.00 0.40
greya               0.00 0.00 0.00 0.30
lightgrey           0.00 0.00 0.00 0.20
verylightgrey       0.00 0.00 0.00 0.10
white               0.00 0.00 0.00 0.00
% magenta
verydarkmagenta     0.00 1.00 0.00 0.30
darkmagenta         0.00 0.80 0.00 0.05
magenta             0.00 0.60 0.00 0.00
lightmagenta        0.00 0.40 0.00 0.00
verylightmagenta    0.00 0.20 0.00 0.00
% violet
verydarkviolet      0.45 0.85 0.00 0.00
darkviolet          0.30 0.65 0.00 0.00
violet              0.22 0.55 0.00 0.00
lightviolet         0.15 0.40 0.00 0.00
verylightviolet     0.10 0.20 0.00 0.00
% blue
verydarkblue        1.00 1.00 0.00 0.20
darkblue            0.90 0.90 0.00 0.00
blue                0.75 0.75 0.00 0.00
lightblue           0.50 0.50 0.00 0.00
verylightblue       0.30 0.30 0.00 0.00
% skyblue
verydarkskyblue     0.90 0.50 0.00 0.15
darkskyblue         0.75 0.45 0.00 0.00
skyblue             0.60 0.38 0.00 0.00
lightskyblue        0.45 0.25 0.00 0.00
verylightskyblue    0.30 0.15 0.00 0.00
% cyan
verydarkcyan        1.00 0.00 0.00 0.10
darkcyan            0.80 0.00 0.00 0.00
cyan                0.60 0.00 0.00 0.00
lightcyan           0.40 0.00 0.00 0.00
verylightcyan       0.20 0.00 0.00 0.00
% seagreen
verydarkseagreen    0.75 0.00 0.45 0.00
darkseagreen        0.62 0.00 0.38 0.00
seagreen            0.50 0.00 0.30 0.00
lightseagreen       0.38 0.00 0.22 0.00
verylightseagreen   0.25 0.00 0.15 0.00
% green
verydarkgreen       1.00 0.00 1.00 0.25
darkgreen           0.80 0.00 0.80 0.00
green               0.60 0.00 0.60 0.00
lightgreen          0.40 0.00 0.40 0.00
verylightgreen      0.20 0.00 0.20 0.00
% limegreen
verydarklimegreen   0.50 0.00 1.00 0.10
darklimegreen       0.40 0.00 0.95 0.00
limegreen           0.30 0.00 0.80 0.00
lightlimegreen      0.20 0.00 0.65 0.00
verylightlimegreen  0.10 0.00 0.50 0.00
% yellow
verydarkyellow      0.00 0.00 1.00 0.25
darkyellow          0.00 0.00 1.00 0.10
yellow              0.00 0.00 1.00 0.00
lightyellow         0.00 0.00 0.50 0.00
verylightyellow     0.00 0.00 0.25 0.00
% orange
verydarkorange      0.00 0.50 0.80 0.10
darkorange          0.00 0.40 0.80 0.00
orange              0.00 0.30 0.80 0.00
lightorange         0.00 0.20 0.75 0.00
verylightorange     0.00 0.15 0.70 0.00
% red
verydarkred         0.00 1.00 1.00 0.15
darkred             0.00 0.80 0.80 0.00
red                 0.00 0.60 0.60 0.00
lightred            0.00 0.40 0.40 0.00
verylightred        0.00 0.20 0.20 0.00
% brown
verydarkbrown       0.35 0.85 1.00 0.40
darkbrown           0.30 0.70 1.00 0.35
brown               0.25 0.75 1.00 0.25
lightbrown          0.20 0.60 0.70 0.15
verylightbrown      0.15 0.45 0.55 0.00
@@@COLORS@@@
} # End of colorDef

##############################################################
################### SHELL MAIN FUNCTIONS #####################
#
# Defining Help...
Help () {
#  echo ""
#  echo "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
#  echo "         1         2         3         4         5         6         7         8"
  echo "";
  echo "NAME           $PROGRAM";
  echo "VERSION        $VERSION";
  echo "";
  echo "Creation DATE: $CREATIONDATE";
  echo "Last REVISION: $DATERELEASE";
  echo "";
  echo "SYNOPSIS";
  echo "";
  echo "      $USAGE";
  echo "";
  echo "DESCRIPTION";
  echo "";
  echo "       This program draws color-filled DotPlots";
  echo "       from files with gff-formatted data fields.";
  echo ""; echo "";
  echo "OPTIONS";
  echo "";
  echo "     -h  Shows this help.";
  echo "     -H <option> Shows only help for the especified option.";
  echo "     -V Verbose mode, a full report is sent to standard error (default only sends Warnings).";
  echo "     -v Silent mode: Disable all warnings, no messages sent to standard error.";
  echo "     -d Write (or rewrite if exists) default customfile \"$v03\".";
  echo "     -D <default_custom_filename> Create a new default customfile with the given filename.";
  echo "     -C <custom_filename>  Load given custom file and append to default custom file (.gff2psrc).";
  echo "     -s <page_size> Useful to modify page size (default is a4).";
  echo "     -p Switches page orientation to Portrait (default is Landscape).";
  echo "     -G <color_name> Sets color for FOREGROUND (default is black).";
  echo "     -g <color_name> Sets color for BACKGROUND (default is white).";
  echo "     -P <\#> Sets how many pages are needed to split your output (default is one).";
  echo "     -S <\#> Zoom first nucleotide (default is sequence origin).";
  echo "     -E <\#> Zoom last nucleotide (default is sequence length).";
  echo "     -B <\#> Sets blocks per page (default is one).";
  echo "     -N <\#> Sets nucleotides per line (default is the largest sequence position from input gff-files).";
  echo "     -b Blocks from left to right and from top to bottom (default is top to bottom first).";
  echo "     -L Switch off Header (Title area).";
  echo "     -T <title_string> Defining title (default is input gff filename).";
  echo "     -t <subtitle_string> Defining subtitle (default is none).";
  echo "     -l Does not show page numbering.";
  echo "     -O Does not show date.";
  echo "     -o Does not show time.";
  echo "     -M <\#> Number of major tickmarks per line (default 10).";
  echo "     -K <\#> Major tickmarks scale in nucleotides, default is nucleotide length for lines divided by major tickmarks number (see option -T).";
  echo "     -m <\#> Number of minor tickmarks between major tickmarks (default 10).";
  echo "     -k <\#> Minor tickmarks scale in nucleotides default is major tickmarks size divided by minor tickmarks number (see option -t).";
  echo "     -w or -f Switch off displaying forward-strand(Watson) elements.";
  echo "     -c or -r Switch off displaying reverse-strand(Crick) elements.";
  echo "     -i Switch off displaying strand-independent elements.";
  echo "     -0 <color_name> Sets color for frame \"0\" (default is blue).";
  echo "     -1 <color_name> Sets color for frame \"1\" (default is red).";
  echo "     -2 <color_name> Sets color for frame \"2\" (default is green).";
  echo "     -3 <color_name> Sets color for frame \".\" (default is orange).";
  echo "     -n Switch off labels for element positions.";
  echo "     -a Switch off CopyRight line on plot.";
  echo "";
  echo "ENVIRONMENT VARIABLES";
  echo "";
  echo "   There are three environmental variables that can be set by users to their preferences:";
  echo "   + You can specify the path where GFF2PS can find the default files with the shell variable \"GFF2PS_CFDIR\". Default value is path where you are running GFF2PS.";
  echo "   + You can also define the default custom filename you will like with the variable \"GFF2PS_CUSTOMFILE\", program default filename for custom file is \".gff2psrc\".";
  echo "   + GFF2PS needs to write few temporary files in a directory with permissions for current user to read and write. Default temporary directory path is set to \"/tmp/\" but you can assign a different temporary directory path using the variable \"GFF2PS_TMP\".";
  echo "   + Setting those vars in Bourne-shell and C-shell:";
  echo "     o Using a Bourne-Shell (e.g. bash):";
  echo "           export GFF2PS_CFDIR=\"path\"";
  echo "           export GFF2PS_CUSTOMFILE=\"file_name\"";
  echo "           export GFF2PS_TMP=\"path\"";
  echo "     o Using a C-Shell:";
  echo "           setenv GFF2PS_CFDIR \"path\"";
  echo "           setenv GFF2PS_CUSTOMFILE \"file_name\"";
  echo "           setenv GFF2PS_TMP \"path\"";
  echo "";
  echo "COMMENTS";
  echo "";
  echo "  * Colors defined are:";
  echo "";
  echo "$COLORS";
  echo "";
  echo "  * Page Sizes defined are:";
  echo "";
  echo "$PAGES";
  echo "";
  echo "BUGS";
  echo "";
  echo "  Please, report bugs to:";
  echo "       $AUTHOR";
  echo "       e-mail: $EMAIL";
  echo "";
 return 0;
} # End of Help

ShowHelpLine () {
 Help | $GAWK 'BEGIN{
  IGNORECASE=1; flg=0; srch=ARGV[1]; ARGV[1]=""
  gsub("-","",srch); srch="\ -"srch"\ " }
  { if ($0~srch) { print $0; flg=1 } }
  END{ if (!flg) printf "\n\tERROR: Option %s is not defined,\n\t\tmake sure which option you need help.\n",srch }' $1 ;
 echo "";
 return 0;
} # End of ShowHelpLine

##############################################################
################# POSTSCRIPT MAIN FUNCTIONS ##################
#
# Printing PostScript Prolog (Constants,Variables and Functions)...
{
echo '%'; echo '%    *** '$AAA'***';
#
cat <<'@@@EndProlog@@@'
% 
% 
%        Converting GFF files to PostScript plots.
%
%        Copyright (C) 1999 - Josep Francesc ABRIL FERRANDO  
%                                    Roderic GUIGO SERRA       
%
%    This program is free software; you can redistribute it and/or modify
%    it under the terms of the GNU General Public License as published by
%    the Free Software Foundation; either version 2 of the License, or
%    (at your option) any later version.
%
%    This program is distributed in the hope that it will be useful,
%    but WITHOUT ANY WARRANTY; without even the implied warranty of
%    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%    GNU General Public License for more details.
%
%    You should have received a copy of the GNU General Public License
%    along with this program; if not, write to the Free Software
%    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
%
% ------------------------------------------------------------------------
%
%%BeginProlog
%
%%BeginProcSet: ShortNames 1.0 0
/tflg false def % test flag
/bdf { bind def } bind def
/xdf { exch def } bdf
/cm { 28.35 mul } bdf
/in { 72    mul } bdf
/mmod { 2 dict begin /y xdf /x xdf x x y div truncate y mul sub end } bdf
%%EndProcSet:   ShortNames 1.0 0
%
%%BeginProcSet: Constants  1.0 0
% Printing Offset
/VUpOS 0.25 cm def  % offset defines non printable
/VDnOS 0.25 cm def  % paper area for pages (printer outlimits).
/HLtOS 0.25 cm def
/HRtOS 0.25 cm def
@@@EndProlog@@@
#
colorDef | $GAWK 'BEGIN{ i=0 }
 { if ($1!="%") { count[i++]=$1; C[$1]=$2; M[$1]=$3; Y[$1]=$4; K[$1]=$5 } }
 END {
  printf "%% Fixed Color Variables (CMYK)\n";
  printf "/colordict %s dict def colordict begin %% %s colors + 28 definitions\n", (i+28), i;
  for (j=0;j<i;j++) { n=count[j]; printf "/%-20s { %-4s %-4s %-4s %-4s } def\n", n,C[n],M[n],Y[n],K[n] }
  printf "end %% colordict\n" }' -
#
} >$PSHEAD
#### End of MAINPSHEADER function #### 

#
# Printing Main PostScript Routines...
cat <<'@@@MAINProcs@@@' >$PSMAIN
%%EndProcSet:   Setting_Vars 1.0 0
%
%%BeginProcSet: Page_Layout 1.0 0
% checking if margins are within the defined offset
flglscape {
 UpM HLtOS lt { /UpM HRtOS def } if % Checking margins for flglscape mode
 DnM HRtOS lt { /DnM HLtOS def } if
 LtM VDnOS lt { /LtM VUpOS def } if
 RtM VUpOS lt { /RtM VDnOS def } if
 } {
  UpM VUpOS lt { /UpM VUpOS def } if % Checking margins for portrait mode
  DnM VDnOS lt { /DnM VDnOS def } if
  LtM HLtOS lt { /LtM HLtOS def } if
  RtM HRtOS lt { /RtM HRtOS def } if
  } ifelse
% defining pagelimits and X - Y scales (Xlim Ylim)
/pglim { Dpage pop LtM RtM add sub Dpage exch pop UpM DnM add sub } def
% Defining starting point on page.
/XORI flglscape { UpM } { LtM } ifelse def
/YORI flglscape { LtM } { UpM } ifelse def
% Defining page-elements layout.
/XSTitl pglim pop XOriTitl 2 mul sub def
/XSBlck pglim pop def
/FSF 4 def % Point size for Credits for A4
/CSF { pagedict begin pga4 pop end Dpage pop exch div dup 1 cm gt { pop 1 cm } if dup FSF lt { pop FSF } if } bdf
/CYSF { pagedict begin pga4 exch pop end Dpage exch pop exch div dup 1 cm gt { pop 1 cm } if dup FSF lt { pop FSF } if } bdf
% /TYSF { pagedict begin pga4 end Dpage 3 2 roll div 3 1 roll exch div div mul } bdf
% /YSTitl YSTitl TYSF dup 4 cm gt { pop 4 cm } if dup 0.5 cm lt { pop 0.5 cm } if Titlscl mul def
/YSTitl YSTitl dup 4 cm gt { pop 4 cm } if dup 0.5 cm lt { pop 0.5 cm } if Titlscl mul def
/XOriBlck 0 def
/XSPlot { XSBlck FLftLbl { XLftLbl sub } if FRgtLbl { XRgtLbl sub } if } def
/XOriPlot { XOriBlck FLftLbl { XLftLbl add } if } def
/Xscale XSPlot MaxNuclPage div def
/YOriBlck { FlgTitl { YSTitl BlckSp add } { 0 } ifelse } def
/adcrd { flgcrd { CYSF 2 mul FlgBkBx { 5 add } if sub } if } bdf
/is2tck LnBth 0 gt LnFwd 0 gt LnRvs 0 gt and and FlgISU FlgISD and and def % true if must plot two tickmark lines
/is1tck LnFwd 0 gt LnBth 0 gt and LnFwd 0 gt LnRvs 0 gt and or LnBth 0 gt LnRvs 0 gt and or is2tck or FlgISU FlgISD or and def
%
NBlck 0 eq {
  /YSBlck { pglim exch pop adcrd FlgTitl { YOriTitl YSTitl BlckSp add add sub } if } def
  /YS2Blck { pglim exch pop adcrd FlgTitl { YOriTitl YSTitl BlckSp add add sub } if FlgOSU { TkMrkW 1 TkMspc add mul sub } if FlgOSD { TkMrkW 1 TkMspc add mul sub } if } def
  /YSFwd LnFwd def
  /YSBth LnBth def
  /YSRvs LnRvs def
 } {
  /YSBlck { pglim exch pop adcrd FlgTitl { YOriTitl YSTitl add NBlck } { 0 NBlck 1 sub } ifelse BlckSp mul add sub NBlck div } def
  /YS2Blck { pglim exch pop adcrd FlgTitl { YOriTitl YSTitl add NBlck } { 0 NBlck 1 sub } ifelse BlckSp mul add sub NBlck div FlgOSU { TkMrkW 1 TkMspc add mul sub } if FlgOSD { TkMrkW 1 TkMspc add mul sub } if is1tck { TkMrkW 1 TkMspc add mul is2tck { TkMrkW 1 TkMspc add mul add } if sub } if } def
  /YSLine YS2Blck LnTot div def
  /tracksize tracksize YSLine mul def
  /spcrsize spcrsize YSLine mul def
  /YSFwd LnFwd YSLine mul def
  /YSBth LnBth YSLine mul def
  /YSRvs LnRvs YSLine mul def
} ifelse
%%EndProcSet:   Page_Layout 1.0 0
%
%%BeginProcSet: functions 1.0 0
/msg { print (\n) print flush } bdf
/mst { print (\n) print flush counttomark 1 add dup { dup index 20 string cvs print ( ) print 1 sub } repeat (\n) print pop flush } bdf
/F { scale } bdf
/T { translate } bdf
/S { gsave } bdf
/R { grestore } bdf
/m { moveto } bdf
/rm { rmoveto } bdf
/l { lineto } bdf
/rl { rlineto } bdf
/K { stroke } bdf
/scmyk { setcmykcolor } bdf
/slw { setlinewidth } bdf
%%EndProcSet:   functions 1.0 0
%
%%BeginProcSet: text_functions 1.0 0
/sfont { findfont exch scalefont setfont } bdf
/chrh { S newpath 0 0 m false charpath flattenpath pathbbox exch pop 3 -1 roll pop R } bdf
/strh { 2 dict begin /lly 0.0 def /ury 0.0 def { ( ) dup 0 4 -1 roll put chrh dup ury gt { /ury xdf } { pop } ifelse dup lly lt { /lly xdf } { pop } ifelse } forall ury end } bdf
/stringheight  { S newpath 0 0 m (0) false charpath flattenpath pathbbox exch pop exch sub exch pop 0.95 mul R } bdf
/ct { S 0 T sfont scmyk dup stringwidth pop 2 div neg stringheight 2 div neg m show R } bdf
% X Y angle string valign halign fnt color ttxt
% valign : tv (top) cv (middle) bv (bottom) --- halign : lh (left) ch (center) rh (right)
/ttxt { S scmyk sfont 8 dict begin /h xdf /v xdf /lbl xdf /angle xdf /y xdf /x xdf /hs lbl stringwidth pop neg def /vs lbl strh neg def x y T angle rotate h (rh) eq { hs } { h (ch) eq { hs 2 div } { 0 } ifelse } ifelse v (tv) eq { vs } { v (cv) eq { vs 2 div } { 0 } ifelse } ifelse m lbl show end R } bdf
%%EndProcSet:   text_functions 1.0 0
%
%%BeginProcSet: painting_functions 1.0 0
/solidline   { [] 0 setdash } def
/dotted      { [ 1 ] 0 setdash } def
/longdotted  { [ 1 ] 5 setdash } def
/shortdashed { [ 10 ] 10 setdash } def
/longdashed  { [ 20 ] 10 setdash } def
/bbox { 4 copy 3 1 roll exch 6 2 roll 8 -2 roll m l l l closepath } bdf
/scolor { colordict exch get exec scmyk } bdf
%
colordict begin % adding definitions and functions
 /lup { /ku xdf /yu xdf /mu xdf /cu xdf } bdf
 /lmd { /km xdf /ym xdf /mm xdf /cnm xdf } bdf
 /ldn { /kd xdf /yd xdf /md xdf /cd xdf } bdf
 /n (-) def
 /load2col { lup ldn /dk ku kd sub def /dy yu yd sub def /dm mu md sub def /dc cu cd sub def } bdf
 /load3col { lup lmd ldn /uk ku km sub def /uy yu ym sub def /um mu mm sub def /uc cu cnm sub def /dk km kd sub def /dy ym yd sub def /dm mm md sub def /dc cnm cd sub def } bdf
 /col2 { 2 dict begin /p xdf p n ne { /pcd { p mul add } bdf cd dc pcd md dm pcd yd dy pcd kd dk pcd } { BGcolor } ifelse scmyk end } bdf
 /col3 { 3 dict begin /p xdf p n ne { /pcd { p 2 mul mul add } bdf /pcu { p 0.5 sub 2 mul mul add } bdf p 0.5 le { cd dc pcd md dm pcd yd dy pcd kd dk pcd } { cnm uc pcu mm um pcu ym uy pcu km uk pcu } ifelse } { BGcolor } ifelse scmyk end } bdf
 /rainbow { 1 dict begin /p xdf p n ne { p 0.1 le { p 0.2 div 0.5 add 1 0 0 } { p 0.4 le { 1 1 p 0.1 sub 0.3 div sub 0 0 } { p 0.6 le { 1 0 p 0.4 sub 0.2 div 0 } { p 0.8 le { 1 p 0.6 sub 0.2 div sub 0 1 0 } { 0 p 0.8 sub 0.2 div 1 0 } ifelse } ifelse } ifelse } ifelse scmyk } if end } bdf % <ifelse> } { BGcolor } ifelse scmyk end } bdf
end % colordict
%%EndProcSet:   painting_functions 1.0 0
%
%%BeginProcSet: header_functions 1.0 0
headerdict begin
 /ttfsz { YSTitl 0.50 mul } def
 /stfsz { YSTitl 0.25 mul } def
 /xtfsz { YSTitl 0.25 mul } def
 /sepsz { YSTitl 0.125 mul } def
 /ttfnt { ttfsz /Helvetica-Bold } def
 /stfnt { stfsz /Helvetica      } def
 /dtfnt { xtfsz /Times-Roman    } def
 /tmfnt { xtfsz /Times-Roman    } def
 /pgfnt { xtfsz /Times-Roman    } def
 /ttlong { S ttfnt sfont Title stringwidth pop stfnt sfont SubTitle stringwidth pop R 2 copy gt { pop } { exch pop } ifelse 2 div } bdf
 /Header { S XOriTitl YOriTitl YSTitl add T 1 -1 F ShwTBx { S 0 0 XSTitl YSTitl bbox 0.125 slw fgcolor scmyk K R } if ShwTt Title () ne and { sepsz ttlong add YSTitl sepsz sub 0 Title (tv) (ch) ttfnt fgcolor ttxt } if ShwST SubTitle () ne and { sepsz ttlong add sepsz 0 SubTitle (bv) (ch) stfnt fgcolor ttxt } if ShwDate { XSTitl 4.5 sub xtfsz 0 Sdate (tv) (rh) tmfnt fgcolor ttxt } if ShwTime { XSTitl 4.5 sub YSTitl 2 div 0 Stime (cv) (rh) dtfnt fgcolor ttxt } if Shwp_num { XSTitl 4.5 sub YSTitl xtfsz sub 0 PageNumber (bv) (rh) pgfnt fgcolor ttxt } if R } bdf
%
 /s_credits { S 1 dict begin /fs_cd CYSF def pglim fs_cd 0.5 mul sub T 1 -1 F 0 0 0 (This plot has been obtained using gff2ps. The most recent version of gff2ps is freely available at \042http:\/\/www1.imim.es/software/gfftools/GFF2PS.html\042. Copyright      1999 by Josep F. Abril & Roderic Guigo) (bv) (rh) fs_cd /Times-Roman fgcolor ttxt S fs_cd /Times-Roman sfont (   1999 by Josep F. Abril & Roderic Guigo) stringwidth pop neg R 0 0 (\343) (bv) (ch) fs_cd /Symbol fgcolor ttxt end R } bdf
end
%
%%EndProcSet:   header_functions 1.0 0
%
%%BeginProcSet: tickmarks 1.5 0
% Rule.ps ---> rules and scales
/tmdct 30 dict def tmdct begin
 /ChkLimits { 3 copy pop 5 2 roll dup dup 5 1 roll 3 1 roll lt 3 1 roll gt or { pop false } { true } ifelse } bdf 
 /ShowGrid 0 def % 0 - none : 1 - MinTicks : 2 - MaxTicks : 3 - Both
 /Gridup true def /Griddn true def /flgup true def
 /TkMrkDW TkMrkW 10 div def
 /TkFont { TkMrkHW /Helvetica } def
 /MaxWidthT { S MaxNuclPage 10 string cvs TkFont sfont stringwidth pop 2 mul R } bdf
 /CheckCloser { 3 copy pop MaxWidthT sub 3 1 roll MaxWidthT add 3 1 roll dup dup 5 1 roll 3 1 roll lt 3 1 roll gt or 4 1 roll 3 copy dup 3 1 roll ne 3 1 roll ne and 5 -1 roll and { pop false } { true } ifelse } bdf
 /ctextick { S TkFont sfont dup stringheight 2 div exch stringwidth pop 2 Xscm div neg Xscm exch 2 copy neg T 2 mul exch 2 mul neg exch S 0 0 bbox bgcolor scmyk S tflg { fgcolor scmyk } if 0.75 slw K R fill R 0 0 m fgcolor scmyk show R } bdf
 /bltextick { S TkFont sfont dup stringwidth pop 2 Xscm div neg Xscm TkMrkHW 2 copy flgup { TkMrkDW add T } { 2 mul T 1 -1 F } ifelse exch 2 mul neg exch S 0 0 bbox bgcolor scmyk S tflg { fgcolor scmyk } if 0.75 slw K R fill R 0 0 m fgcolor scmyk show R } bdf
 /tonormtick { /go true def 2 copy pop 2100000000 gt { /go false def } if go { 0 eq { 2 { dup dup 0 ne { MinTick mod } if sub exch } repeat } { 2 { dup dup 0 ne { MaxTick mod } if sub exch } repeat } ifelse } { pop } ifelse } bdf %%%%% WARNING TEMPORARY HACK ON: tonormtick
 /Mkg { 0 0 m l fgcolor scmyk dotted K } bdf
 % Reset scale numbering
 /CHoffrsc { CHoffsets length 0 gt { dup CHnext ge { /CHcurrent CHnext def 0 1 CHoffsets length 1 sub { CHoffsets exch get dup CHnext gt { /CHnext exch def exit } { pop } ifelse } for } if CHcurrent sub } if } def
% the following Mklb prints integer scales
% /Mklb { S CHoffrsc 3 dict begin TS 3 eq { 1000000 div round cvi /q exch 20 string cvs def /y q length def /h y 2 add string def h 0 q putinterval h y (Mb) putinterval h } { TS 2 eq { 1000 div round cvi /q exch 20 string cvs def /y q length def /h y 2 add string def h 0 q putinterval h y (Kb) putinterval h } { 10 string cvs } ifelse } ifelse end R } bdf 
% the following Mklb prints 1 decimal position scales
 /mkexp { TrS 0 ne { 10 TrS exp cvi div } if div round cvi TrS 0 ne { 10 TrS exp cvi div } if } bdf
 /Mklb { S CHoffrsc 3 dict begin TS 3 eq { 1000000 mkexp /q exch 20 string cvs def /y q length def /h y 2 add string def h 0 q putinterval h y (Mb) putinterval h } { TS 2 eq { 1000 mkexp /q exch 20 string cvs def /y q length def /h y 2 add string def h 0 q putinterval h y (Kb) putinterval h } { 10 string cvs } ifelse } ifelse end R } bdf 
%
 /MkVGrid { S slw Gridup flgup not { not } if { 0 up Mkg } if Griddn flgup not { not } if { 0 down neg Mkg } if  R } bdf
 /MkAtick { slw 0 TkMrkHW neg m 0 TkMrkHW l fgcolor scmyk K } bdf
 /MkBtick { S dup Xscm 0 T ShowGrid 2 eq ShowGrid 3 eq or { 0.25 MkVGrid } if 1 MkAtick CheckCloser { Mklb ctextick } if R } bdf
 /MkCtick { slw 0 0 m 0 TkMrkHW 3 -1 roll { TkMrkDW sub } if l fgcolor scmyk K } bdf
 /MkDtick { S dup Xscm 0 T CheckCloser { Mklb bltextick } if ShowGrid 2 eq ShowGrid 3 eq or { 0.25 MkVGrid } if false 1 MkCtick R } bdf
 /baseline { S 2 setlinecap Xscm TkMrkDW 0.75 mul m Xscm TkMrkDW 0.75 mul l TkMrkDW 1.5 mul slw fgcolor scmyk K R } bdf % slw: 1.5 instead of 2
 /r { /Gridup true def /Griddn true def /flgup true def 0 exch TkMrkHW sub T S 0 T 1 -1 F 4 { 2 copy } repeat pop neg Xscm 0 T 0 tonormtick MinTick exch { ChkLimits { S Xscm 0 T 0.25 MkAtick ShowGrid 1 eq ShowGrid 3 eq or { 0 MkVGrid } if R } if } for 1 tonormtick MaxTick exch { ChkLimits { MkBtick } if } for 2 { dup dup 0 ne { MaxTick mmod } if 0 ne { MkBtick } { pop } ifelse } repeat pop pop R } bdf
 /x { 5 { 2 copy } repeat pop neg Xscm 0 T baseline 0 tonormtick MinTick exch { ChkLimits { S Xscm 0 T true 0.25 MkCtick ShowGrid 1 eq ShowGrid 3 eq or { 0 MkVGrid } if R } if } for 1 tonormtick MaxTick exch { ChkLimits { MkDtick } if } for 2 { dup dup 0 ne { MaxTick mmod } if 0 ne { MkDtick } { pop } ifelse } repeat pop pop } bdf 
 /s { /Gridup false def /Griddn true def /flgup true def 0 exch TkMrkW add T S 0 T 1 -1 F x R } bdf
 /z { /Gridup true def /Griddn false def /flgup false def 0 exch TkMrkW sub T S 0 T 1 1 F x R } bdf
 /g { /down xdf /up xdf S T 2 { 2 copy } repeat pop neg Xscm 0 T 1 tonormtick MaxTick exch { ChkLimits { S Xscm 0 T 0.125 slw 0 down Mkg R } if } for R pop pop } bdf
end % tmdct
%%EndProcSet:   tickmarks 1.5 0
%
%%BeginProcSet: objects 1.2 0
/shpdct 255 dict def shpdct begin
 /nucdif { 2 copy exch sub } bdf
 /mtrx matrix def
 /mrr false def
 /LY { Yscl FlgScRM { 0.45 mul } { 0.975 mul } ifelse } bdf
 /HLY { LY sc mul 2 div } bdf
 /rt { Yscl } bdf
 /vst 250 string def
 /clrselc { cvx exec dup 2 eq { pop load2col /clrproc /col2 load def } { dup 3 eq { pop load3col /clrproc /col3 load def } { dup 0 eq { pop white black load2col /clrproc /col2 load def } { dup 4 eq { 5 { pop } repeat /clrproc /rainbow load def } { 1 eq { white 8 4 roll load2col /clrproc /col2 load def } if } ifelse } ifelse } ifelse } ifelse } bdf % no end for closing dict because grdct must be closed by calling function
 /v { vtcsc clrproc v_s 0 m v_e 0 l vtcsc n ne { K } { newpath } ifelse /v_s v_s vstp add def /v_e v_e vstp add def } bdf
 /vc { v_s lvtcsc n ne { solidline lvtcsc } { dotted 0 } ifelse m v_e vtcsc n ne { solidline vtcsc } { dotted 0 } ifelse l K /v_s v_s vstp add def /v_e v_e vstp add def /lvtcsc vtcsc def } bdf
 /GetVtVar { /v_cmod xdf /v_ori xdf /v_end xdf /sc_ori xdf sc_ori v_ori gt { /v_ori sc_ori def } if } bdf
%%%
%%% score vector color gradient
% /vt { S /VStp xdf /VWdw xdf /vstp VStp Xscm def GetVtVar colordict begin v_cmod clrselc rt slw v_ori VWdw ge { v_ori VStp 2 div sub Xscm } { v_ori VWdw v_ori sub 2 div VStp 2 div sub add Xscm } ifelse dup /v_s xdf /v_e exch vstp add def S { currentfile vst readline pop { { token { cvx exec /vtcsc xdf v } { exit } ifelse } loop } stopped { exit } if } loop R end R } bdf
%%%
 /vt { S /VStp xdf /VWdw xdf /vstp VStp Xscm def GetVtVar colordict begin v_cmod clrselc rt slw v_ori Xscm 0 T VWdw 2 div Xscm dup /v_s xdf /v_e exch vstp add def S { currentfile vst readline pop { { token { cvx exec /vtcsc xdf v } { exit } ifelse } loop } stopped { exit } if } loop R end R } bdf
%%%
%%% score vector graph 
% /vtc { S /VStp xdf /VWdw xdf /vstp VStp Xscm def GetVtVar colordict begin v_cmod cvx exec scmyk 0.25 slw v_ori VWdw ge { v_ori VStp 2 div sub Xscm } { v_ori VWdw v_ori sub 2 div VStp 2 div sub add Xscm } ifelse dup /v_s xdf /v_e exch vstp add def /lvtcsc n def strnd (-) eq { 1 -1 F } if ScV 0 eq { 0 HLY neg T } if { currentfile vst readline pop { { token { cvx exec /vtcsc exch dup n ne { LY mul ScV 0 ne { 2 mul } if } if def vc } { exit } ifelse } loop } stopped { exit } if } loop end R } bdf % (Score-Vector Loop finished...LINE-PLOT) msg % ScV 0 eq { 4 } { 2 } ifelse div
%%%
 /vtc { S /VStp xdf /VWdw xdf /vstp VStp Xscm def GetVtVar colordict begin v_cmod cvx exec scmyk 0.25 slw v_ori Xscm 0 T VWdw 8 div Xscm dup /v_s xdf /v_e exch vstp add def /lvtcsc n def strnd (-) eq { 1 -1 F } if ScV 0 eq { 0 HLY neg T } if { currentfile vst readline pop { { token { cvx exec /vtcsc exch dup n ne { LY mul ScV 0 ne { 2 mul } if } if def vc } { exit } ifelse } loop } stopped { exit } if } loop end R } bdf % (Score-Vector Loop finished...LINE-PLOT) msg % ScV 0 eq { 4 } { 2 } ifelse div
%%%
%%%
 % position-score vector
 /vp { S GetVtVar v_ori 0 T { currentfile } bind loop (Position-Vector Loop finished...) msg R } bdf
 % segment-score vector
 /vg { S (Segment-Vector Loop finished...) msg R } bdf  
 % string vector
 /vw { S (String-Vector Loop finished...) msg R } bdf  
 % Functions for Shapes......
 /getfrcol { dup (.) eq { pop frmN } { dup 0 eq { pop frm0 } { dup 1 eq { pop frm1 } { 2 eq { frm2 } if } ifelse } ifelse } ifelse } bdf
 /cmdln { HLY m sqdif 2 div neg 0 rl scmyk K } bdf % S - R removed to allow frame-remainder fill mode to work.
 /lnfill { S Yscl slw sqdif cmdln sqdif 2 div cmdln R } bdf
 /frmfill { frm getfrcol rmd getfrcol lnfill } bdf
 /rnbfill { 1 dict begin S /incr sqdif 100 div def 0 incr sqdif { dup dup incr add 0 exch 0 m l dup 0 gt { sqdif div } if rainbow Yscl slw K } for R end } bdf 
 /setcolmod { cmod cvx exec dup 1 eq { pop scmyk fill } { dup 2 eq { pop lnfill } { dup 5 eq { 5 { pop } repeat frmfill } { dup 4 eq { 5 { pop } repeat rnbfill } { pop } ifelse } ifelse } ifelse } ifelse } bdf
  /ShFsz { GpFsz 2 div pslbSC mul } bdf
 /ShFont { ShFsz /Helvetica } bdf 
 /postk { S 0 0 m 0 LY ScV 0 eq { 0.65 } { 1.15 } ifelse mul rl longdotted fgcolor scmyk 0.125 slw K R } bdf
 /shwpos { S Flgspos { seqori LY neg ScV 0 eq { 0.65 mul T } { 1 -1 F 1.15 mul T } ifelse sqend sqdif sqori 0 2 { S 0 T postk 10 string cvs 0 0 S ScV 1 eq { 1 -1 F } if strnd (-) eq { 1 -1 F 45 } { -45 } ifelse ScV 1 eq { neg } if 4 -1 roll strnd (-) eq { ScV 1 ne { (bv) } { (tv) } ifelse } { ScV 1 ne { (tv) } { (bv) } ifelse } ifelse (lh) ShFont fgcolor ttxt R R } repeat } if R } bdf
 % *V align:  0 center : 1 baseline : -1 reverse
 /frs { S strnd (-) eq { -1 1 F } if FtV 0 eq { 0 HLY neg T } if colordict begin p_s cvx exec newpath end R } bdf
 /GetVar { /ftlbl xdf /flblfg xdf /Flgspos xdf /FtV exch dup 2 eq { pop 0 /mrr true def } { /mrr false def } ifelse def /p_s xdf /cmod xdf /sc xdf /rmd xdf /frm xdf /sqend xdf /seqend sqend Xscm def /sqori xdf /seqori sqori Xscm def /sqdif sqend sqori sub Xscm def sqdif 0.1 lt { /sqdif 0.1 def } if /fflbl ftlbl () eq { false } { flblfg } ifelse def /p_strk true def pop } bdf
 /p { S GetVar shwpos strnd (-) eq { seqend } { seqori } ifelse 0 T frs R } bdf
 %%
 % new shape for expand
 /trchg 0.20 def
 %%
 /resize_xp { S 5 dict begin /nd_xp sqend def /end_xp seqend def /or_xp sqori def /ori_xp seqori def /df_xp sqdif def MSLen 0 gt { sqdif MSLen Xscm lt { strnd (-) eq { /sqori sqend MSLen sub def /seqori sqori Xscm def } { /sqend sqori MSLen add def /seqend sqend Xscm def } ifelse /sqdif sqend sqori sub Xscm def } if } if S 0 LY trchg mul 2 div T 1 1.35 F bline R /sqend nd_xp def /seqend end_xp def /sqori or_xp def /seqori ori_xp def /sqdif df_xp def end R } bdf
 %%
 /xpVL { GetVar strnd (-) eq { seqend } { seqori } ifelse 0 T strnd (-) eq { -1 1 F } if FtV 0 eq { 0 HLY neg T } if mrr { 0 LY sc mul T 1 -1 F } if } bdf
 %%
 /lxpshp { S xpVL 4 dict begin /hdif sqdif 2 div def /xdif sqdif xpnd mul def /hxdif xdif 2 div hdif xpnd mul sub hdif add def /vrtfct LY 4 div neg def /xpndmv xpndmv Xscm def colordict begin gcmod token { exch pop cvx exec } { pop pop black } ifelse S 1 LY sc mul F hdif trchg m hdif trchg neg l 0.025 LY div slw fgcolor scmyk K newpath R resize_xp seqori neg trchg neg T /LY vrtfct def /Xscm { Xscale mul } bdf { currentfile token pop exec } loop end end R } bdf 
 %%
 /xpshp { S xpVL 3 dict begin /hdif sqdif 2 div def /xdif sqdif xpnd mul def /vrtfct LY 4 div def /xpndmv xpndmv Xscm def colordict begin gcmod token { exch pop cvx exec } { pop pop black } ifelse S 1 LY sc mul F 0.025 LY div slw 0 trchg 1.2 mul m 0 trchg 1.3 mul l hdif xdif 2 div sub xpndmv strnd (-) eq { sub } { add } ifelse dup 0.73 l 0.74 l fgcolor scmyk K newpath R resize_xp 1 LY sc mul F hdif xdif 2 div sub xpndmv strnd (-) eq { sub } { add } ifelse 0.745 T 1 1 LY div F 0.225 0 T S 0 0 xdif vrtfct bbox fgcolor scmyk 0.5 slw K newpath R seqori xpnd mul neg 0 T /LY vrtfct def /Xscm { Xscale xpnd mul mul } bdf S grlbl () ne glblfg and { gp_st gp_nd gp_st sub 2 div add Xscm LY strnd (-) eq { 1.3 } { 1.35 } ifelse mul T strnd (-) eq { -1 -1 F } if gp_nd gp_st sub MINshwLBLlen gt { 0 0 0 grlbl strnd (-) eq { (tv) } { (bv) } ifelse (ch) LY /Helvetica fgcolor ttxt } if } if R S { currentfile token pop exec } loop /Xscm { Xscale mul } bdf R end end R } bdf %% sqdif trchg 1.2 mul m sqdif trchg 1.3 mul l hdif neg xpndmv add strnd (-) eq { neg } if dup 0.73 l 0.74 l % right line %%
 %%
 /uxpshp { S xpVL 3 dict begin /hdif sqdif 2 div def /xdif sqdif xpnd mul def /vrtfct LY 4 div def /xpndmv xpndmv Xscm def colordict begin gcmod token { exch pop cvx exec } { pop pop black } ifelse S 1 LY sc mul F 0.025 LY div slw 0 trchg 1.2 mul m 0 trchg 1.3 mul l hdif xpndmv strnd (-) eq { sub } { add } ifelse dup 0.73 l 1.35 l fgcolor scmyk K newpath R resize_xp 1 LY sc mul F hdif xpndmv strnd (-) eq { sub } { add } ifelse 1.355 T 1 1 LY div F 0.225 0 T S 0 0 xdif vrtfct bbox fgcolor scmyk 0.5 slw K newpath R seqori xpnd mul neg 0 T /LY vrtfct def /Xscm { Xscale xpnd mul mul } bdf S grlbl () ne glblfg and { gp_st gp_nd gp_st sub 2 div add Xscm LY strnd (-) eq { 1.3 } { 1.35 } ifelse mul T strnd (-) eq { -1 -1 F } if gp_nd gp_st sub MINshwLBLlen gt { 0 0 0 grlbl strnd (-) eq { (tv) } { (bv) } ifelse (ch) LY /Helvetica fgcolor ttxt } if } if R S { currentfile token pop exec } loop /Xscm { Xscale mul } bdf R end end R } bdf %% sqdif trchg 1.2 mul m sqdif trchg 1.3 mul l hdif neg xpndmv add strnd (-) eq { neg } if dup 0.73 l 1.35 l % right line %% xdif 2 div sub 1.35 T
 %%
 % Shapes......
 /HLFcrt { ScV 0 ne { 1 2 F } if } bdf
 /CkMR { mrr { 0 LY sc mul T 1 -1 F } if } bdf
 /PMX { 1 dict begin /svmtrix mtrx currentmatrix def CkMR } bdf
 /PMK { svmtrix setmatrix end } bdf
 /KCFmod { 0.25 slw scmyk S clip setcolmod R K } bdf  %%%%%%%%%%%%%%%%%%%%%%ALSO MODIFIED
 /cpt { PMX sqdif LY sc mul F m { l } repeat closepath PMK KCFmod } bdf
 /cptc { sqdif LY sc mul F arc closepath PMK KCFmod } bdf
 /lft { sqdif 0 T -1 1 F } bdf
 /no_shp { 4 { pop } repeat } bdf
 /line   { PMX sqdif LY sc mul F 0 0.5 m 1 0.5 l PMK 2 slw scmyk K } bdf % 1 slw
 /tline  { PMX sqdif LY sc mul F 0 0.5 m 1 0.5 l PMK 1.6 slw scmyk K } bdf % 1 slw
% /bline  { LY trchg mul dup 0 exch 0.77 mul T PMX sqdif LY sc mul F 0 0 m 1 0 l PMK slw scmyk K } bdf % 1 slw
% /bline  { LY trchg mul dup 0 exch 0.77 mul T PMX sqdif exch sc mul F 1.0 -0.5 1.0 0.5 0.0 0.5 3 0.0 -0.5 m { l } repeat closepath PMK KCFmod } bdf % 1 slw
 /bline  { LY trchg mul PMX sqdif exch sc mul F 1.0 0.0 1.0 0.5 0.0 0.5 3 0.0 0.0 m { l } repeat closepath PMK KCFmod } bdf % 1 slw
 /scline { PMX sqdif LY sc mul F 0 0.5 m 1 0.5 l PMK LY sc mul slw scmyk K } bdf 
 /box    { 1.0 0.0 1.0 1.0 0.0 1.0 3 0.0 0.0 cpt } bdf
 /hbox   { ScV 0 ne { 1.0 0.0 1.0 0.5 0.0 0.5 3 0.0 0.0 } { 1.0 0.5 1.0 1.0 0.0 1.0 3 0.0 0.5 } ifelse cpt } bdf
 /gtgb   { PMX 1.0 0.0 1.0 1.0 0.0 1.0 3 0.0 0.0 sqdif LY sc mul F m { l } repeat closepath PMK 0.25 slw scmyk S BGcolor scmyk fill R K grlbl () ne { S sqdif 2 div LY 2 div dup sc mul 0 grlbl (cv) (ch) 6 -1 roll /Helvetica FGcolor ttxt R } if } bdf % S clip BGcolor scmyk fill R 
 /fcir   { PMX 0.5 0.5 0.5 0 360 cptc } bdf
 /hcir   { PMX ScV 0 ne { 1 2 F 0.5 0.0 } { 0.5 0.5 } ifelse 0.5 0 180 cptc } bdf
 /frhead { 0.75 0.0 0.75 -0.1 0.755 -0.1 1.0 0.5 0.755 1.1 0.75 1.1 0.75 1.0 0.0 1.0 8 0.0 0.0 cpt } bdf
 /flhead { lft frhead } bdf
 /hrhead { ScV 0 ne { 1.0 0.0 0.755 1.1 0.75 1.1 0.75 1.0 0.0 1.0 5 0.0 0.0 } { 1.0 0.5 0.755 1.1 0.75 1.1 0.75 1.0 0.0 1.0 5 0.0 0.5 } ifelse cpt } bdf
 /hlhead { lft hrhead } bdf
 /frend  { 1.0 0.0 1.0 1.0 0.0 1.0 0.0 0.995 0.25 0.5 0.0 0.005 6 0.0 0.0 cpt } bdf
 /flend  { lft frend } bdf
 /hrend  { ScV 0 ne { 1.0 0.0 1.0 1.0 0.0 1.0 0.0 0.995 4 0.25 0.0 } { 1.0 0.5 1.0 1.0 0.0 1.0 0.0 0.995 4 0.25 0.5 } ifelse cpt } bdf
 /hlend  { lft hrend } bdf
 /frsgl  { 0.75 0.0 0.75 -0.1 0.755 -0.1 1.0 0.5 0.755 1.1 0.75 1.1 0.75 1.0 0.0 1.0 0.0 0.995 0.25 0.5 0.0 0.005 11 0.0 0.0 cpt } bdf
 /flsgl  { lft frsgl } bdf
 /hrsgl  { ScV 0 ne { 1.0 0.0 0.755 1.1 0.75 1.1 0.75 1.0 0.0 1.0 0.0 0.995 6 0.25 0.0 } { 1.0 0.5 0.755 1.1 0.75 1.1 0.75 1.0 0.0 1.0 0.0 0.995 6 0.25 0.5 } ifelse cpt } bdf
 /hlsgl  { lft hrsgl } bdf
 /frtgl  { 0.0 0.0 0.0 1.0 1.0 0.505 3 1.0 0.495 cpt } bdf
 /fltgl  { lft frtgl } bdf
 /hrtgl  { ScV 0 ne { 0.0 0.0 0.0 1.0 2 1.0 0.0 } { 0.0 0.5 0.0 1.0 2 1.0 0.5 } ifelse cpt } bdf
 /hltgl  { lft hrtgl } bdf
 /fdmd   { 0.0 0.5 0.5 1.0 1.0 0.5 3 0.5 0.0 cpt } bdf
 /hdmd   { ScV 0 ne { ScV 1 eq { 1.0 0.0 0.5 1.0 2 0.0 0.0 } { 0.0 1.0 1.0 1.0 2 0.5 0.0 } ifelse } { mrr { 1.0 0.5 0.5 1.0 2 0.0 0.5 } { 1.0 0.5 0.5 1.0 2 0.0 0.5 } ifelse } ifelse cpt } bdf
 /fdtgl  { ScV 0 ne { ScV 1 eq { 0.0 1.0 1.0 1.0 2 0.5 0.0 } { 1.0 0.0 0.5 1.0 2 0.0 0.0 } ifelse } { mrr { 0.0 1.0 1.0 1.0 2 0.5 0.5 } { 0.0 1.0 1.0 1.0 2 0.5 0.5 } ifelse } ifelse cpt } bdf
 /f2tgl { 1.0 0.0 0.0 1.0 1.0 1.0 3 0.0 0.0 cpt } bdf
 /fast  { scmyk PMX sqdif LY sc mul F 0.5 0.5 T 0.025 slw 10 { -0.5 0 m 0.5 0 l K 18 rotate } repeat PMK } bdf
 /fstar { PMX sqdif LY sc mul F 0 0.5 T 22.5 rotate 0 0 m 8 { 0.925 0 rlineto 225 rotate } repeat closepath PMK 0.75 slw scmyk S K R clip setcolmod } bdf 
 % gap shape definition begin 
 /gbbx { 1.1 -0.5 1.1 1.5 -0.1 1.5 3 -0.1 -0.5 m { l } repeat closepath } bdf
 /gfna { 0.60 1.50 0.0 0.5 0.50 0.5 -0.10 -0.50 m 3 { l } repeat } bdf
 /gfnb { 1 LY sc mul F gfna reversepath sqdif 0.50 sub 0 T gfna } bdf
 /gfnc { 0.0 0.0 0.0 1.0 1.0 1.0 3 1.0 0.0 m { l } repeat closepath } bdf
 /gap { PMX gfnb S 0.10 0 T sqdif 0.68 sub neg 1 F gbbx clippath newpath gfnc PMK 0.1 slw 4 copy scmyk S dotted K R clip setcolmod R S scmyk 0.36 slw K R S BGcolor scmyk 0.12 slw K R } bdf
 % New shapes
 /loop { PMX sqdif LY sc mul F 0.5 0.5 T -0.05 0 m -0.05 0.4 l -0.6 0.4 -0.6 1.0 0 1.0 curveto 0.6 1.0 0.6 0.4 0.05 0.4 curveto 0.05 0 l closepath PMK 0.75 slw scmyk S K R clip setcolmod } bdf
 % New CELERA Feature SHAPES X - Y
 /langl { PMX sqdif LY FlgScRM { 2.35 } { sc 1.10 mul } ifelse mul F 1.0 0.0 m 0.0 1.0 l PMK 0.175 slw scmyk K } bdf 
 /rangl { PMX sqdif LY FlgScRM { 2.35 } { sc 1.10 mul } ifelse mul F 0.0 0.0 m 1.0 1.0 l PMK 0.175 slw scmyk K } bdf 
% /hstar { PMX ScV 0 ne { 1 2 F 0.0 0.5 } { 0.0 -0.5 } ifelse T sqdif LY sc mul F newpath -0.1 -0.1 1.1 0.5 bbox newpath 22.5 rotate 0 0 m 8 { 0.925 0 rlineto 225 rotate } repeat closepath PMK 0.75 slw scmyk S K R S eoclip setcolmod R newpath 0 0.5 m sqdif 0.5 l K } bdf
 % ......Shapes
 % Group functions...
 /g_score 1 def % /g_score 1.1 def % /g_score 0.5 def
 % /GpFsz { Yscl 0.15 mul dup 8 gt { pop 8 } if gplbSC mul } def
 /GpFsz { Yscl 0.15 mul gplbSC mul } def
 /GpFont { GpFsz /Helvetica } bdf
 /gshp { S 0 gp_st gp_nd 0 0 g_score gcmod g_shape GpV Flgrpspos Flgglbl grlbl p R } bdf
 /gp_no { 4 { pop } repeat } bdf
 /gp_ln { scmyk 0.25 slw 0 0 m grdif 0 l K } bdf
 /gp_dt { dotted gp_ln } bdf
 /gp_lt { longdotted  gp_ln } bdf
 /gp_sh { shortdashed gp_ln } bdf
 /gp_lh { longdashed  gp_ln } bdf
 /gp_bk { scmyk 0.125 slw 2 dict begin /tl GpFsz 0.05 mul def /ol GpFsz 0.05 mul def 0 0 m S 0 ol neg rl K R tl 0 rl S 0 ol rl K R tl 0 rl S 0 ol neg rl K R K end } bdf
 /gp_raw { scmyk 0.125 slw strnd (-) eq { grdif 0 T -1 1 F } if 2 dict begin /tl GpFsz 0.05 mul def /ol GpFsz 0.1 mul def tl 0 m tl neg dup S ol rl K R S ol neg rl K R grdif 0 l S tl neg ol rl 0 -2 ol mul rl tl ol rl S fill R K R K end } bdf
 /gp_law { grdif 0 T -1 1 F gp_raw } bdf
 /CkGPL { dup GpFsz 2 div lt { pop GpFsz 0.55 mul } if } bdf
 /gln { S colordict begin g_line cvx exec end R } bdf
 /shgl { S grori Yscl ScV 0 eq { 0.2875 mul } { 0.775 mul } ifelse T gln S grdif 2 div Yscl 0.25 mul 2 div CkGPL 2 div T strnd (-) eq { 1 -1 F } if ScV -1 eq { 1 -1 F } if Flgglbl { 0 0 0 grlbl strnd (-) eq { ScV -1 eq { (bv) } { (tv) } ifelse } { ScV -1 eq { (tv) } { (bv) } ifelse } ifelse (ch) GpFont fgcolor ttxt } if R R } bdf 
 /GetGVar { /gplbSC xdf /grlbl xdf /glblfg xdf /Flgrpspos xdf /g_line xdf /GpV xdf /g_shape xdf /gcmod xdf /gp_nd xdf /grend gp_nd Xscm def /gp_st xdf /grori gp_st Xscm def /grdif gp_nd gp_st sub Xscm def /Flgglbl grlbl () eq { false } { glblfg } ifelse def } bdf
 /gx { exit } bdf 
end % shpdct
%%EndProcSet:   objects 1.2 0
%
%%BeginProcSet: blocks 1.1 0
/blckdct 80 dict def blckdct begin
 /Xscm { Xscale mul } bdf /Xscme { Xscm exch } bdf
 /gst 250 string def
 /XLL { blckori MaxTick sub } bdf
 /XLR { blckend MaxTick add } bdf
 /CKL { 2 { dup XLL lt { pop XLL } { dup XLR gt { pop XLR } if } ifelse exch } repeat } bdf
 % Group Functions
 /gp { S shpdct begin GetGVar shgl gshp { currentfile token pop exec } loop end R } bdf
 % EXPAND group function
 /xp { S shpdct begin /xpnlvl xdf /xpndmv xdf /xpnd xdf GetGVar /xpdsv save def /xpdmat matrix currentmatrix def S 0 gp_st gp_nd 0 0 g_score gcmod g_shape GpV Flgrpspos Flgglbl grlbl xpnlvl 2 eq { uxpshp } { xpnlvl 1 eq { xpshp } { lxpshp } ifelse } ifelse R xpdmat setmatrix xpdsv restore end R } bdf
 % Source Functions.
 /ScFsz { Yscl 0.75 mul dup 10 gt { pop 10 } if sclbSC mul } def
 /ScFont { ScFsz /Courier } bdf 
 /sc_no { 4 { pop } repeat } bdf
 /sc_ln { scmyk 0.25 slw 0 0 m XSPlot 0 l K } bdf
 /sc_dt { dotted      sc_ln } bdf
 /sc_lt { longdotted  sc_ln } bdf
 /sc_sh { shortdashed sc_ln } bdf
 /sc_lh { longdashed  sc_ln } bdf
 /sln { S colordict begin s_line cvx exec end R } bdf
 % /sbc { -10 Yscl 2 mul neg XSPlot 10 add Yscl 1.5 mul bbox clip newpath } bdf
 /sbb { -4 Yscl neg XSPlot 4 add Yscl 3 mul bbox clip newpath FlgScBx { 0 0 XSPlot Yscl bbox 0.25 slw fgcolor scmyk K newpath 0.125 0.125 XSPlot 0.125 sub Yscl 0.125 sub bbox clip newpath } if } bdf
 /shsll { S FLftLbl Flgslftlbl and { XLftLbl 2 div neg Yscl 2 div T strnd (-) ne { 1 -1 F } if 0 0 0 srclftlbl sclbva (ch) ScFont fgcolor ttxt } if R } bdf
 /shsrl { S FRgtLbl Flgsrgtlbl and { XSPlot XRgtLbl 2 div add Yscl 2 div T strnd (-) ne { 1 -1 F } if 0 0 0 srcrgtlbl sclbva (ch) ScFont fgcolor ttxt } if R } bdf
 /GetSVar { /sclbva xdf /sclbSC xdf /srcrgtlbl xdf /srclftlbl xdf /srgtlblfg xdf /slftlblfg xdf /s_line xdf /strnd xdf /FlgScRM xdf /FlgScBx xdf /spacer exch spcrsize mul def /Yscl exch tracksize mul def /ScV exch dup 2 eq { pop 0 } if def /Flgsrgtlbl srcrgtlbl () eq { false } { srgtlblfg } ifelse def /Flgslftlbl srclftlbl () eq { false } { slftlblfg } ifelse def strnd (.) eq { /Y Y spacer 2 div add def } { strnd (-) eq { /Y Y Yscl spacer add add def } if } ifelse } bdf
 /source { S GetSVar XOriPlot Y T strnd (-) eq { 1 -1 F } if shsrl shsll sbb S ScV 0 eq { 0 Yscl 2 div T 1 -1 F } { ScV 1 eq { 0 Yscl T 1 -1 F } if } ifelse sln S blckori Xscm neg 0 T } bdf
 /s_end { R R R strnd (.) eq { /Y Y Yscl add spacer 2 div add def } { strnd (+) eq { /Y Y Yscl spacer add add def } if } ifelse } bdf
 % Block Functions.
 /GetBVar { /blcknum exch 1 sub def /blckend xdf /blckori xdf /Y FlgOSU { TkMrkW 1 TkMspc add mul } { 0 } ifelse def /YB YOriBlck YSBlck blcknum mul add BlckSp blcknum mul add def } bdf
 /kbb { XOriBlck 5 sub -2 XSBlck 10 add YSBlck 2 add bbox FlgBkBx { S 1 slw fgcolor scmyk K R } { newpath } ifelse } bdf
 % tickmark calls
 /tm { S tmdct begin /ShowGrid xdf exec end R } bdf
 /shwgrd { FlgGrd { blckori blckend XOriPlot FlgOSU { TkMrkW } { 0 } ifelse 0 YSBlck FlgOSU { TkMrkW sub } if FlgOSD { TkMrkW sub } if {g} 0 tm } if } bdf
 /shwtck { shwgrd FlgOSU { blckori blckend XOriPlot 0 {s} 0 tm } if FlgOSD { blckori blckend XOriPlot YSBlck {z} 0 tm } if } bdf
 /chgtst { FlgISU FlgISD or is2tck not is1tck and and FlgISU is2tck and or is2tck FlgISD and or } bdf
 /uptck { shwgrd FlgOSU { blckori blckend XOriPlot 0 {s} 0 tm } if } bdf
 /dntck { FlgOSD { blckori blckend XOriPlot Y TkMrkW 1 TkMspc add mul add {z} 0 tm } if } bdf
 /nxtblck { dup dup (.) eq { pop YSFwd 0 gt { YSBth } { 0 } ifelse } { (-) eq { YSFwd 0 gt YSBth 0 gt or { YSRvs } { 0 } ifelse } { 0 } ifelse } ifelse } bdf
 /Strand { nxtblck 0 gt { /Y Y chgtst { TkMrkW 1 TkMspc add mul 2 div add } if def dup (-) eq { pop is1tck FlgISU FlgISD or is2tck not and FlgISU is2tck and or and { blckori blckend XOriPlot TkMrkW FlgOSU { 2 TkMspc 1.5 mul add mul } { 1 TkMspc 0.5 mul add mul } ifelse YSFwd 0 gt { YSFwd add } { YSBth add } ifelse {r} 0 tm } if } { (.) eq { is2tck FlgISD and { blckori blckend XOriPlot TkMrkW FlgOSU { 3 TkMspc 2.5 mul add mul } { 2 TkMspc 1.5 mul add mul } ifelse YSFwd add YSBth add {r} 0 tm } if } if } ifelse /Y Y chgtst { TkMrkW 1 TkMspc add mul 2 div add } if def } { pop } ifelse } bdf 
 /b_end { R end } bdf
 /vb_end { dntck R end } bdf
 % BG block fill functs
 % /bgtsz { TkMrkHW 1.25 mul /Helvetica-bold } def
 /bgtsp 5 def % /bgtsp { BlckSp 0.25 mul } def
 /bgtsz { bgtsp /Helvetica } def
 %% 
 /bgb { S /blbl xdf /cmod xdf /gp_nd exch dup blckend gt { pop blckend } if def /grend gp_nd Xscm def /gp_st exch dup blckori lt { pop blckori } if def /grori gp_st Xscm def /sqdif gp_nd gp_st sub Xscm def grori 0 T colordict begin S PMX sqdif YY F 0 0 1 1 bbox PMK clip setcolmod end R bgtsz sfont /ttt blbl stringwidth pop def sqdif ttt gt { /hpos sqdif 2 div def /haln (ch) def } { /hpos gp_st blckori ge { 0 } { sqdif } ifelse def /haln gp_nd blckori ge { (lh) } { (rh) } ifelse def } ifelse sqdif 10 mul ttt gt { hpos YY 1.025 mul T 1 -1 F 0 0 0 blbl (tv) haln bgtsz fgcolor ttxt } if R } bdf
 %%
 /bgw { S /blbl xdf /cmod xdf /gp_nd exch dup blckend gt { pop blckend } if def /grend gp_nd Xscm def /gp_st exch dup blckori lt { pop blckori } if def /grori gp_st Xscm def /sqdif gp_nd gp_st sub Xscm def grori 0 T colordict begin S PMX sqdif YY F 0 0 1 1 bbox PMK 0.5 slw S dotted K R clip setcolmod end R bgtsz sfont /ttt blbl stringwidth pop def sqdif ttt gt { /hpos sqdif 2 div def /haln (ch) def } { /hpos gp_st blckori ge { 0 } { sqdif } ifelse def /haln gp_nd blckori ge { (lh) } { (rh) } ifelse def } ifelse sqdif 10 mul ttt gt { hpos YY 1.025 mul T 1 -1 F 0 0 0 blbl (tv) haln bgtsz fgcolor ttxt } if R } bdf
 %%
 /oim { S /blbl xdf /cmod xdf /gp_nd exch dup blckend gt { pop blckend } if def /grend gp_nd Xscm def /gp_st exch dup blckori lt { pop blckori } if def /grori gp_st Xscm def /sqdif gp_nd gp_st sub Xscm def /sqh sqdif 2 div def /ttt bgtsz sfont blbl stringwidth pop def grori sqh add YY dup 3 1 roll T 1 -1 F colordict begin S -1 2 1 4 -1 roll bbox 0 -2 T ttt 0.9 mul dup neg 0.4 sub 0 m 2.5 1.75 rl 0 -3.5 rl closepath 0.5 add 0 m -2.5 1.75 rl 0 -3.5 rl closepath S fgcolor scmyk 0.0125 slw K R clip setcolmod R end 0 -2 0 blbl (cv) (ch) bgtsz fgcolor ttxt R } bdf
 %% BG block features
 /orm { S /blbl xdf /cmod xdf /gp_nd exch dup blckend gt { pop blckend } if def /grend gp_nd Xscm def /gp_st exch dup blckori lt { pop blckori } if def /grori gp_st Xscm def /sqdif gp_nd gp_st sub Xscm def /sqdH sqdif 2 div def grori sqdH add 0 T /dwcdcol { colordict begin cmod cvx exec pop end } def /dwcdln 0.25 def colordict begin S PMX sqdif TkMrkW neg F -0.5 0.15 m 0.5 0.15 l 0 1.25 l closepath PMK 0.125 slw fgcolor scmyk S K R clip setcolmod end R blbl () ne { 90 rotate TkMrkW 1.85 mul neg 0 T 1 -1 F bgtsp bgtsz sfont blbl stringwidth pop 0.85 mul blbl 1.4 drawcard } if R } bdf %% TkMrkW 1.60 mul neg %% bgtsp 1.20 mul %% 0.95 mul blbl
 %%
 /backft { S 2 dict begin /xtrhg TkMrkW TkMspc mul def /YY YSBlck FlgOSU { TkMrkW sub xtrhg add } if FlgOSD { TkMrkW sub xtrhg add } if def XOriPlot blckori Xscm sub FlgOSU { TkMrkW } { 0 } ifelse T /FlgScRM false def shpdct begin { currentfile token pop exec } loop end end R } bdf  % exit the loop with "gx" function from shpdct
 %% Block Vertical LABELS
 /drawcard { S 5 dict begin /dclblsc xdf /dclbl xdf /height xdf /width xdf /Hwidth width 2 div def newpath 0 height 2 div neg T Hwidth 0 m width 0 width height Hwidth arcto width height 0 height Hwidth arcto 0 height 0 0 Hwidth arcto 0 0 width 0 Hwidth arcto closepath 16 { pop } repeat S dwcdcol scmyk fill R fgcolor scmyk dwcdln slw K  Hwidth height 2 div 90 dclbl (cv) (ch) Hwidth dclblsc mul /Helvetica-Bold fgcolor ttxt end R } bdf
 %%
 /split_ruler { S XOriPlot blckori Xscm sub TkMrkW 2 div neg T /YY YSBlck FlgOSU { TkMrkW 3 div TkMspc add add } if FlgOSD { TkMrkW 3 div add } if def /FlgScRM false def shpdct begin /cmod (bgcolor 1) def /srlbl xdf /gp_nd xdf /grend gp_nd Xscm def /gp_st xdf /grori gp_st Xscm def /sqdif gp_nd gp_st sub Xscm def grori 2500 Xscm add YSBlck TkMrkW TkMspc add add T 1 -1 F /dwcdcol { colordict begin Blblcol end } def /dwcdln 1 def colordict begin FlgOSU { 0 TkMrkW 3 div neg T } if 1.0 0.0 1.0 1.0 0.0 1.0 3 0.0 0.0 PMX sqdif 5000 Xscm sub YY F m { l } repeat closepath PMK setcolmod srlbl () ne { sqdif YY 2 div T sqdif 4 div blklblsc mul dup -1.5 mul 0 T YY srlbl 1 drawcard } if end end R } bdf
%%
end % blockdict
%%EndProcSet:   blocks 1.0 0
%
%%BeginProcSet: main_function_calls 1.0 0
/block { blckdct begin GetBVar S 0 YB T kbb shwtck } bdf
/vblock { blckdct begin GetBVar S 0 YB T kbb uptck } bdf
%%EndProcSet:   main_function_calls 1.0 0
%
%%EndProlog
%
%%BeginSetup
% initgraphics
% true setpacking
true setstrokeadjust
0.125 slw
0 setlinejoin
0 setlinecap
% mark % Only for error-tracking purposes
%%EndSetup
%
@@@MAINProcs@@@
#
#### End of MAINPSPROCS function

##############################################################
##################### SHELL FUNCTIONS ########################
#
# Testing parameters passed by User: Colors.
CheckColor () {
  $GAWK 'BEGIN{
    color=ARGV[1];
    if (tolower(color)!~/^((b|f)g(color)?|black|white|(very)?(light|dark)?(grey[abcd]?|(sea|lime)?green|(sky)?blue|cyan|violet|magenta|red|orange|yellow|brown))$/) {
      if (ARGV[4]) {
		printf "\n<<<<ERROR>>>> \"%s\" is not a defined color.\n", color | "cat 1>&2";
		printf "              Default \"" ARGV[2] "\" is asigned to this option.\n" | "cat 1>&2";
		printf "              You can choose one of this colors:\n" | "cat 1>&2";
		print ARGV[3] | "cat 1>&2";
		print "" | "cat 1>&2";
	  }
      color=ARGV[2]
    } # if color
    print color
    ARGV[1]=ARGV[2]=ARGV[3]=ARGV[4]=""
    }' $1 $2 "$COLORS" $v34;
  return 0;
} # End of CheckColor

#
# Testing parameters passed by User: Integer Numbers.
CheckInt () {
  if [ `expr $1 : '[-]?[0-9]*'` -eq `expr $1 : '[-]?.*'` ];
    then
      echo "1"; return 0;
    elif [ $v34 -eq 1 ];
      then 
	    { echo "<<<<ERROR>>>> \" $1 \" is not an integer value.";
	      echo "              You must especify an integer value to -$W_OPTION";
          echo "              Program will take value from defaults..."; echo ""; } 1>&2 ;
        echo "0"; return 1;
    else
      return 1;
    fi
} # End of CheckInt

#
# Testing if files exist.
ExistFile () {
  if [ ! -f "$1" ];
    then
      echo "0";
      if [ $v34 -eq 1 ];
        then 
          { echo "INPUT FILE: File \"$1\" is empty or does not exist... Not Loaded!"; } 1>&2;
        fi;
      return 1;
    else
      echo "1"; # exist_file
      if [ $v34 -eq 1 ];
        then 
          { echo "INPUT FILE: File \"$1\" exist, included as GFF-file."; } 1>&2;
        fi;
      return 0;
    fi;
} # End of ExistFile

ExistCustomfile () {
  if [ ! -f "$1" ];
    then
      echo "0";
      if [ $v34 -eq 1 ];
        then 
          { echo "CUSTOM FILE: Default Custom File does not exist... Not Loaded!"; echo ""; } 1>&2;
        fi
      return 0;
    else
      echo "1"; # exist_default_customfile
      if [ $v34 -eq 1 ];
        then 
          { echo "CUSTOM FILE: Default Custom File exist."; echo "";
            echo "             Filename: \"$1\""; echo ""; } 1>&2;
        fi;
      return 1;
    fi;
} # End of ExistCustomfile

XtrCustomExist () {
  if [ ! -f "$1" -a ! -f "$CFDIR/$1"  -a ! -f "./$1" ];    # load_customfile customfile_name
	then
      v01=0;
      if [ $v34 -eq 1 ];
        then 
          { echo "CUSTOM FILE: Custom File \"$1\" does not exist... Not Loaded!"; echo ""; } 1>&2;
        fi;
	  return 1;
	else
      v01=1;
      if [ -f "$1" ];
	    then
		  v02="$1";
        else
          if [ -f "$CFDIR/$1" ];
            then 
			  v02="$CFDIR/$1";
            else
              if [ -f "./$1" ];
			    then 
                  v02="./$1";
				fi;
            fi;
		fi;
      if [ $v34 -eq 1 ];
        then 
	      { echo "CUSTOM FILE: Adding User-Defined Custom File to defaults:"; echo "";
            echo "             Filename: \"$v02\""; echo ""; } 1>&2;
        fi;
	  return 0;
    fi;
} # XtrCustomExist

###################################################################
################## MAIN GFF2PS SHELL SCRIPT #######################
###################################################################
############### CONVERTING GFF TO POSTSCRIPT ######################
###################################################################

Defaults

#
# When no options, no parameters and 
#  no inputstream are given, print USAGE.
npar=$#;
if [ $npar -eq 0 ];
  then
    echo; echo $USAGE; echo; exit 1;
  fi;

#
# Asking for Help, output it to screen. 
case $1 in
  -h) (Help | more); exit 2;;
  -H) echo; echo $PROGRAM" : Option Definition Help."; echo;
      if [ $npar -gt 1 ]; 
        then shift; fi;
      for temp in $@;
        do ShowHelpLine $temp; done;
      exit 2;;
  esac;

#
# Processing all options and parameters passed to program.
while getopts :HhVvdD:C:z:Z:s:pG:g:P:S:E:B:N:bLT:t:lOoM:K:m:k:wfcri0:1:2:3:na W_OPTION;
  do
    case $W_OPTION in
      H|h) (Help | more); exit 2;;
      V) v05=1;v34=1;;                # print_report
      v) v34=0;;                      # quiet_mode
      d) v04_1=1;;                    # create_default_customfile (.gff2psrc) or rewrite
      D) v04_1=1;                     # create_default_customfile or rename_it if exist
         v03="$CFDIR/$OPTARG";;
      C) cftmp=$OPTARG;;
      s) v07=$OPTARG;;                # page_bbox
         # v12=`chkpagesize $v07`;;  
      p) v06="Portrait";;             # page_orientation
      G) v19=`CheckColor $OPTARG $v19`;;  # foreground_color
      g) v20=`CheckColor $OPTARG $v20`;;  # background_color
      P) if [ `CheckInt $OPTARG` ];
           then
             v08=$OPTARG;
           fi;;               # page_number
      S) if [ `CheckInt $OPTARG` ];
           then
             v18_s=$OPTARG;
           fi;;               # zoom_begin
      E) if [ `CheckInt $OPTARG` ];
           then
             v18_e=$OPTARG;
           fi;;               # zoom_end
      B) if [ `CheckInt $OPTARG` ];
           then
             v09=$OPTARG;
           fi;;               # blocks_x_page
      N) if [ `CheckInt $OPTARG` ];
           then
             v10=$OPTARG;
           fi;;               # nucleotides_x_line
      b) v11=0;;              # show_blocks_top-bottom
      L) v21="none";;         # header_style
      T) v25=$OPTARG;;        # title
      t) v26=$OPTARG;;        # subtitle
      l) v22="off";;          # show_page_numbers
      O) v23="off";;          # show_date
      o) v24="off";;          # show_time
      M) if [ `CheckInt $OPTARG` ];
           then
             v13=$OPTARG;
           fi;;               # major_tickmarks_num
      K) if [ `CheckInt $OPTARG` ];
           then
             v14=$OPTARG;
           fi;;               # major_tickmarks_nucleotides
      m) if [ `CheckInt $OPTARG` ];
           then
             v15=$OPTARG;
           fi;;               # minor_tickmarks_num
      k) if [ `CheckInt $OPTARG` ];
           then
             v16=$OPTARG;
           fi;;               # minor_tickmarks_nucleotides
      w|f) v27="off";;        # strand_show_forward
      c|r) v28="off";;        # strand_show_reverse
      i) v29="off";;          # strand_show_independent
      0) v30=`CheckColor $OPTARG $fgcolor`;;  # frame0_color
      1) v31=`CheckColor $OPTARG $fgcolor`;;  # frame1_color
      2) v32=`CheckColor $OPTARG $fgcolor`;;  # frame2_color
      3) v33=`CheckColor $OPTARG $fgcolor`;;  # frame_unknown_color
      n) v17="true";;         # show_positions
      a) v35=0;;              # Show_Credits
      Z) v36=$OPTARG;;        # page_bbox
      z) CHOSFLG=1; CHOSFILE=$OPTARG;; # offsets file
       :) ShowHelpLine $1; exit 2;;
      \?) ShowHelpLine $1; exit 2;;
    esac # case $W_OPTION
  done   # while getopts
# Done GetOpts
v18="$v18_s..$v18_e";

#
# Shifting all options tested before,
# without removing files passed to shell...
incr=1;
while [ $OPTIND -gt $incr ];
  do shift; incr=`expr $incr + 1`; done;

#
# Report Command Line
if [ $v34 -eq 1 ];
  then 
   { echo "************** Begin Report ****************"; echo "";
     echo "********************************************";
     echo "*  Running $PROGRAM $VERSION [$DATERELEASE] ";
     echo "********************************************"; echo "";
	 echo "Report: You have typed the following command line:"; echo "";
	 echo $CMDLine; echo "";
     if [ -n "$GFF2PS_CFDIR" -o -n "$GFF2PS_CUSTOMFILE" -o -n "$GFF2PS_TMP" -o -n "$GAWK_DIR" ];
       then
	     echo "Report: You have defined the following $PROGRAM Shell-Vars:"; echo "";
	     if [ $GFF2PS_CFDIR ];      then echo "        \$GFF2PS_CFDIR      = \"$GFF2PS_CFDIR\""; fi;
	     if [ $GFF2PS_CUSTOMFILE ]; then echo "        \$GFF2PS_CUSTOMFILE = \"$GFF2PS_CUSTOMFILE\""; fi;
	     if [ $GFF2PS_TMP ];        then echo "        \$GFF2PS_TMP        = \"$GFF2PS_TMP\""; fi;
	     if [ $GAWK_DIR ];          then echo "        \$GAWK_DIR          = \"$GAWK_DIR\""; fi;
         echo "";
       fi; } 1>&2;
  fi;

#
# Checking files
if [ $v34 -eq 1 ];
  then 
   { echo "********************************************";
     echo "*  Checking input filenames given by user";
     echo "********************************************"; echo ""; } 1>&2;
  fi;

GFF_INPUT_FILES=""; ck=0; hmf=0; rd_std=1;
if [ $npar -ge $OPTIND ];
   then
     for files in $@;
       do
	     if [ $files = "-" ];
		   then
             if [ $ck -eq 1 ]; 
               then
                 GFF_INPUT_FILES=$GFF_INPUT_FILES" ";
               fi		   
             GFF_INPUT_FILES=$GFF_INPUT_FILES$files;  
             shift; ck=1;
             hmf=`expr $hmf + 1`;
             rd_std=1;
             if [ $v34 -eq 1 ];
               then
                 { echo "INPUT DATA: Standard-input is going to be included with input files..."; echo ""; } 1>&2;
               fi;
           else
             if [ `ExistFile $files` -eq 1 ];  # Checks any kind of input files (*, ./*, path/*). 
               then 
                 if [ $ck -eq 1 ]; 
                   then
                     GFF_INPUT_FILES=$GFF_INPUT_FILES" ";
                   fi
                 GFF_INPUT_FILES=$GFF_INPUT_FILES$files;
                 shift; ck=1;
                 hmf=`expr $hmf + 1`;
               fi;
		   fi;
       done;
     if [ $v34 -eq 1 ];
       then
         { echo "INPUT DATA: $GFF_INPUT_FILES"; echo ""; } 1>&2;
       fi;
   fi;
if [ $hmf -eq 0 ];
   then
     GFF_INPUT_FILES="-";
     if [ $v34 -eq 1 ];
       then
         { echo "INPUT DATA: Redirecting from standard-input..."; echo ""; } 1>&2;
       fi;
   fi;

#
# Checking for custom files...

v04=`ExistCustomfile "$v03"`

XtrCustomExist $cftmp

#
# Defining PLOToptions STRING for GNU awk programs.
# if [ $v34 -eq 1 ];
#   then
#    { echo "";
#      echo "********************************************";
#      echo "*  VARs passed to Program";
#      echo "********************************************"; echo ""; } 1>&2;
#   fi;

#
# Printing GAWK OPTIONS.
cat <<@@@EndOfOptions@@@ > $GWKOPT
BG_COLOR:=$bgcolor::FG_COLOR:=$fgcolor::$n04_1:=$v04_1
$n01:=$v01::$n02:=$v02::$n03:=$v03::$n04:=$v04::$n05:=$v05
$n06:=$v06::$n07:=$v07::$n08:=$v08::$n09:=$v09::$n10:=$v10
$n11:=$v11::$n12:=$v12::$n13:=$v13::$n14:=$v14::$n15:=$v15
$n16:=$v16::$n17:=$v17::$n18:=$v18::$n19:=$v19::$n20:=$v20
$n21:=$v21::$n22:=$v22::$n23:=$v23::$n24:=$v24::$n25:=$v25
$n26:=$v26::$n27:=$v27::$n28:=$v28::$n29:=$v29::$n30:=$v30
$n31:=$v31::$n32:=$v32::$n33:=$v33::$n34:=$v34::$n35:=$v35::$n36:=$v36
PID:=$PID::InputFNs:=$GFF_INPUT_FILES::PS_Header_FN:=$PSHEAD::PS_Main_FN:=$PSMAIN
PROGRAM:=$PROGRAM::VERSION:=$VERSION::AUTHOR:=$AUTHOR::EMAIL:=$EMAIL::PSPROGRAM:=$PSPROGRAM
CHOSFLAG:=$CHOSFLG::CHOSFILE:=$CHOSFILE
@@@EndOfOptions@@@

#
# Main GFF2APLOT GNU AWK PROGRAM
#
cat << '@@@EndPROGRAM@@@' >> $GWKPRG # Shell file
BEGIN{ ######### INITIALITATION ###############
  OFS="\t";
  #
  # Loading Default Variables...
  GFF_FORMAT_DEFS();
  ARY_VARIABLES();
  PageSizesDEF();
  #
  # Find actual date...
  "date +%Y/%m/%d" | getline date; close("date +%Y/%m/%d");
  "date +%T" | getline time; close("date +%T");
  #
  # Finding logged user...
  "whoami" | getline usr; close("whoami");
  #
  # Defining pre-variables by CommandLine
  READ_CL();
  #
  # Initialization for some vars.
  BigLINE="********************************************";
  MINSCORE=0.10; MAXSCORE=1.00;
  MINV_SCO=0.00; MAXV_SCO=1.00;
  FIRST_POS=0;
  LAST_POS=0;
  nordcnt=ordcnt=0;
  src_nordcnt=src_ordcnt=0;
  seq_nordcnt=seq_ordcnt=0;
  grouped_=1;ungrouped_=0;
  gff_NR=0;
  TITLE_FN="";
  CHOffSet[0]=0; CHOSblnk=0;
  #
  # Color REGEXP
# V_COLORS="(^fgcolor$|^black$|^white$|^(very)?(light|dark)?(grey[abcd]?|(sea|lime)?green|(sky)?blue|cyan|violet|magenta|red|orange|yellow|brown)$)";
  V_COLORS="((fg|foreground)(color)?|black|white|(very)?(light|dark)?(grey[abcd]?|(sea|lime)?green|(sky)?blue|cyan|violet|magenta|red|orange|yellow|brown))";
# Valid_Colors="^"V_COLORS"(\.\."V_COLORS"(\.\."V_COLORS")?)?$";
  Valid_Colors="^("V_COLORS"(\\\.\\\."V_COLORS"(\\\.\\\."V_COLORS")?)?)$"
  # 
  PrintWRN(sprintf("%s\n*  GFF2PS Inizialization DONE \!\!\!\n%s\n\n",BigLINE,BigLINE));
  PrintWRN(sprintf("%s\n*  Processing GFF Records...\n*\n",BigLINE));
}
########## INITIALITATION Finished ##########
#
############ READING .GFF FILES  ############
{ 
  is_EOF=0;
  #
  # skips those comment lines (starting with "#") or empty lines
  # also checking if input line is gff_formated.
  while (!ChkInput()) { 
    PrintWRN(sprintf(">>> %10s :: Not Read :: <%s>\n", NR, ChkCharIF($0)));
    if (getline<=0) { is_EOF=1; break };
  } # while
  if (!is_EOF) {
    #
    # Printing Input Lines
    if (NF>10) PrintRPT(sprintf("OK: %10s :: GFF v.%s  :: <%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s (...)>\n", NR, GFF_V, $1,$2,$3,$4,$5,$6,$7,$8,$9,$10));
	else PrintRPT(sprintf("OK: %10s :: GFF v.%s  :: <%s>\n", NR, GFF_V, $0));
    #
    # Reading gff-line elements.
	ReadElements();
  } # if (!is_EOF)
}
########### .GFF FILES WERE READ ############
#
########### MAIN PROGRAM PROCESSES ##########
END{
  # 
  PrintWRN(sprintf("*\n*  ...GFF Records READ\n%s\n\n",BigLINE));
  # 
  OFS=" ";
  #
  # Defining Object Properties.
  SET_VARS();
  #
  # Defining New Order array combining src and seq oredrings (allows multiple seqs by src or srcs by seq).
  SET_ORDER();
  #
  # Sorting groups
  SortGroups();
  #
  # Making Lines...
  MakeGroupLines();
  #
  # Printing groups and elements sorted
# PrtSorted();
  #
  # Defining Page variables.
  SET_PAGE_VARS();
  #
  # Writing PS Header...
  PSheader();
  #
  # PostScript Variables Setup.
  defPSvars();
  #
  # Pages MAIN LOOP.
  MAIN_PAGE_LOOP();
  #
  # Closing PostScript document.
  PSTrailer();
  #
  # If not exist, create custom file (.gff2psrc)
  CREATECUSTOM();
}
############ MAIN PROCESSES DONE ############
#
#################### MAIN ###################
############ FUNCTIONS DEFINITION ###########
#
function GFF_FORMAT_DEFS() {
  #
  PrintRPT("*  GFF Format Definitions...\n");
  #
  # gff BASIC data-structure
  seqname = 1 ; REseqname = "[^\\# ]+" ;
  source  = 2 ; REsource  = "[^\\# ]+"  ;
  feature = 3 ; REfeature = "[^\\# ]+"  ;
#  start   = 4 ; REstart   = "([+-]?[0-9]+)" ;
#  end     = 5 ; REend     = "([+-]?[0-9]+)" ;
  start   = 4 ; REstart   = "([+-]?[0-9]*[.]?[0-9]*(e[+-]?[0-9]+)?)" ;
  end     = 5 ; REend     = "([+-]?[0-9]*[.]?[0-9]*(e[+-]?[0-9]+)?)" ;
  score   = 6 ; REscore   = "([+-]?[0-9]*[.]?[0-9]*(e[+-]?[0-9]+)?)" ;
  strand  = 7 ; REstrand  = "[+.-]"  ; # to ensure that works on all systems
  frame   = 8 ; REframe   = "[.012]" ;
  group   = 9 ;
  #
  # gff2ps extra data-structure
  gpname=1; gpstart=2; gpend=3; is_grouped=4; gplabel=5;
  vector=10; v_window=11; v_step=12; v_scmin=13; v_scmax=14; v_DATA=15; v_NUM=16; v_CLASS=0;
  VctSPLIT="[\\t ]+[Vv][Ee][Cc][Tt][Oo][Rr][\\t ]+";
  expand="::x"; xpnd_zoom="::z"; xpnd_delta="::d"; xpnd_level="::l"; xpnd_frame="::f";
  XpndSPLIT="[\\t ]+[Ee][Xx][Pp][Aa][Nn][Dd][\\t ]+";
  #
  ### GFF FORMAT - Tag-Value definition ###
  REST="^";
  REND="$";
  REtag= "[A-Za-z][A-Za-z0-9_]*" ;
  REval= "\\\"[^\\\"\\#]+\\\"(;)?" ;
  #
  ### GFF FORMAT - Version 1 - Record Definition ###
  REfs1     = "[\\t ]+" ;
  REtagval  = REtag REfs1 REval ; # "([\\t ]*;)?"
  PlainGP   = "[^\\\"\\# ]+" ;
  REtail1   = ".*" ;     # ".*" ;
  REgroupV1 = "(" PlainGP "|" REval "|" REtagval REtail1 ")" ;
  CKgroupV1 = "(" PlainGP "|" REval ")" ;
  REGV1     = "(" REfs1 "(" REgroupV1 REtail1 ")?)?" ;
  #    Version1 : ..$1.......FS.....$2......FS.....$3.......FS.....$4.....FS.....$5...FS.....$6.....FS.....$7......FS.....$8.....FS.....$9.....
  gff_format_V1 = REST REseqname REfs1 REsource REfs1 REfeature REfs1 REstart REfs1 REend REfs1 REscore REfs1 REstrand REfs1 REframe REGV1 REND ;
  #
  ### GFF FORMAT - Version 2 - Record Definition ###
  # In version 2 gff-format field separator is \t.
  REfs2     = "[\\t]+" ;
  REgroupV2 = REtagval ; # REtag REfs1 REval ;
  REtail2   = ".*" ;
  REGV2     = "(" REfs2 "(" REgroupV2 REtail2 ")?)?" ; # "([^\\#]+)*";
  #    Version2 : ..$1.......FS.....$2......FS.....$3.......FS.....$4.....FS.....$5...FS.....$6.....FS.....$7......FS.....$8.....FS.....$9.....
  gff_format_V2 = REST REseqname REfs2 REsource REfs2 REfeature REfs2 REstart REfs2 REend REfs2 REscore REfs2 REstrand REfs2 REframe REGV2 REND ;
} # End of GFF_FORMAT_DEFS
#
function ARY_VARIABLES() {
  #
  PrintRPT("*  Default Settings...\n");
  #
  ############################################## LAYOUT
  # Page Layout
  Default["page_size"]="a4";               # Var["page_size"]
  Default["page_bbox"]="auto,0,0";         # Var["page_bbox"]
  Default["page_orientation"]="Landscape"; # Var["page_orientation"] : Landscape (default), Portrait.
  Default["margin_left"]="1cm";            # cm, in, pt
  Default["margin_right"]="1cm";           #
  Default["margin_upper"]="1cm";           #
  Default["margin_lower"]="1cm";           #
  Default["foreground_color"]="FGcolor";   #
  Default["background_color"]="BGcolor";   #
  Default["page_number"]=1;                # Var["page_number"] : Default=1
  Default["zoom_cmdln"]="*..*";            # retrieving zoom from custom file
  Default["zoom"]="*..*";                  # "*..*", "*..end", "start..*", "start..end"
  Default["blocks_x_page"]=1;              # Var["blocks_x_page"] : Default=1 # if ==0 then multiple vertical pages.
  Default["nucleotides_x_line"]=0;         # Var["nucleotides_x_line"] : Default=0,gets the seqlenght from data
  Default["block_style"]="default";        # default, boxed
  Default["default_block_spacing_width"]="0.25cm"; #
  Default["show_blocks_top-bottom"]=1;     # Var["show_blocks_top-bottom"] : 1->TopBottom, 2->LeftRight.
  Default["show_page_limits"]="off";
  # Title Area
  Default["header_style"]="default"; # none, default, boxed
  Default["header_scale"]=1;
  Default["title"]="default";        # none, default, "user def"
  Default["subtitle"]="default";     # none, default, "user def"
  Default["show_page_numbers"]="on"; #
  Default["show_date"]="on";         #
  Default["show_time"]="on";         #
  # Tick Marks
  Default["major_tickmarks_num"]=10;         #
  Default["major_tickmarks_nucleotides"]=-1; #
  Default["minor_tickmarks_num"]=10;         #
  Default["minor_tickmarks_nucleotides"]=-1; #
  Default["show_grid"]=1;                    #
  Default["show_inner_scale"]="both";        # both(default)/none/top/bottom
  Default["show_outer_scale"]="both";        #
  Default["default_scale_width"]="0.25cm";   #
  Default["default_scale_spacing_width"]=1;  # Only for outer scale. Units in rule_widths
  Default["nucleotide_scale"]="default";     #
# Blocks Layout
# Default["strand_show_mixed"]="off";
  Default["strand_show_forward"]="on";       #
  Default["strand_show_reverse"]="on";       #
  Default["strand_show_independent"]="on";   #
  Default["show_left_source_label"]="true";  #
  Default["left_source_label_width"]="2cm";  #
  Default["show_right_source_label"]="false"; #
  Default["right_source_label_width"]="2cm"; #
  Default["default_track_width"]="1cm";      #
  Default["default_track_spacing_width"]="0.25cm"; #
  Default["sort_tracks_by_sequence"]="on";   # on : by sequence - off : by source
# Default["default_track_scale"]=1;
# Default["default_track_spacing_scale"]=0.25;
  Default["block_label_scale"]=1;
  # General Properties
  Default["frame_unknown_color"]="orange"; #
  Default["frame0_color"]="blue";         #
  Default["frame1_color"]="red";          #
  Default["frame2_color"]="green";        #
  Default["block_label_fill_color"]="verylightred"; #
  Default["show_positions"]="false";      #
  Default["group_label_scale"]=1;
  Default["position_label_scale"]=1;
  Default["minimum_single_length"]=0; # minimum length for those elements that have a single component. 
  Default["show_label_min_gene_length"]=-1; # shortest gene length to show its label (-1 show all labels)
  Default["min_group_separation"]=10;     # minimum nucleotide distance between two groups to avoid overlapping.
  #
  ############################################## GFF-FEATURES
  FT_PROP["feature_color"]="default";    # default,1color(color),2color(color..color),3color(color..color..color)
  FT_PROP["feature_stroke_color"]="default"; #
  FT_PROP["shape"]="box";                # box, arrow, end_arrow, circle # still not implemented: vector, spike, block
  FT_PROP["fill_shape_mode"]="default";  # none(BGcolor), default(FGcolor 1color), 1_color, 2_color, frame-remainder, rainbow
  FT_PROP["vector_shape"]="default";     # line_plot, gradient
  FT_PROP["fill_vector_mode"]="default"; # none(0 BGcolor grad), default(0 black grad), rainbow(1), 1_color(BGcolor color 2), 2_color(color1 color2 2), 3_color(col1 col2 col3 2)
  FT_PROP["vert_align"]="default";       # center,baseline # still not implemented: reverse
  FT_PROP["layer"]=0;                    # now is implemented, first sorting for feature lines is made on FT_PROP["layer"]
  FT_PROP["label"]="++default++";        # ++none++ , ++default++ , "user-def"
  FT_PROP["show_feature"]="on";          # 
  FT_PROP["show_feature_positions"]="false"; #
  #
  ############################################## GROUPS
  GR_PROP["feature_color"]="default";      # 
  GR_PROP["feature_stroke_color"]="default"; #
  GR_PROP["group_color"]="default";        # 
  GR_PROP["group_stroke_color"]="default"; # 
  GR_PROP["group_shape"]="none";           # default (none) , ...
  GR_PROP["fill_shape_mode"]="default";    # none(BGcolor), default(FGcolor 1color), 1_color, 2_color, frame-remainder, rainbow
  GR_PROP["fill_vector_mode"]="default";   # none(0 BGcolor grad), default(0 black grad), rainbow(1), 1_color(BGcolor color 2), 2_color(color1 color2 2), 3_color(col1 col2 col3 2)
  GR_PROP["group_line"]="default";         # none , default (black line)
  GR_PROP["group_line_color"]="default";   #
  GR_PROP["vert_align"]="default";         # center or baseline
  GR_PROP["label"]="++default++";          # ++none++ , ++default++ , "user-def"
  GR_PROP["group_label_scale"]="default";  # LAYOUT variable rules over this one
  GR_PROP["show_group"]="on";              # 
  GR_PROP["show_group_positions"]="false"; #
  #
  ############################################## METHODS/SOURCES
  SO_PROP["feature_color"]="default";   # 
  SO_PROP["feature_stroke_color"]="default"; #
  SO_PROP["group_color"]="default";          # 
  SO_PROP["group_stroke_color"]="default";   # 
  SO_PROP["left_label"]="++default++";  # ++none++ , ++default++ , ++sequence++, ++source++ , ++both++ , ++info++ , "user-def"
  SO_PROP["show_left_label"]="on";      #
  SO_PROP["right_label"]="++default++"; # ++none++ , ++default++ , ++sequence++, ++source++ , ++both++ , ++info++ , "user-def"
  SO_PROP["show_right_label"]="on";     #
  SO_PROP["source_label_scale"]=1;
  SO_PROP["source_label_vert_align"]="center";
  SO_PROP["source_style"]="default";    # default, boxed
  SO_PROP["source_line"]="default";     # none , default (black line), line, dotted, longdotted, shortdashed, longdashed 
  SO_PROP["source_line_color"]="verydarkred"; #
  SO_PROP["vert_align"]="default";      # default,center,baseline(down), 
  SO_PROP["range"]="default";           # range of lower-upper scores (none, default, "#user_def number#")
  SO_PROP["show_source_positions"]="false";   #
  SO_PROP["keep_feature_label_space"]="true"; # on/off
  SO_PROP["track_scale"]=1;                   #
  SO_PROP["track_spacing_scale"]=0.25;        #
  SO_PROP["unfold_grouped_ungrouped"]="off";  # on/off
  SO_PROP["unfold_grouped_line"]="on";        # on/off
  SO_PROP["unfold_ungrouped_line"]="on";      # on/off
  SO_PROP["fit_block_height"]="off";
#
# Not defined yet:
#
#  Default["text_color"]=Default["foreground_color"]; 
#
#  FT_PROP["join"]="on";
#
#  GR_PROP["join_align"]="center";
#  GR_PROP["join_color"]=Default["foreground_color"];
#  GR_PROP["join_linetype"]="solid";
#  GR_PROP["join_show"]="off";
#
#  SO_PROP["bbox_color"]=Default["foreground_color"];
#
#  ?_PROP["rule_scale"]="nucleotide";
#  ?_PROP["rule_rel"]="none";
#  ?_PROP["rule_abs"]="none";
#
  #
  ############################################## PRE-DEFINED PARAMETERS
  # gff2ps strand-frame codification
  strands["+"]=strands["."]=strands["-"]=1;
  wstr[1]="+";wstr[2]=".";wstr[3]="-";
  Frames["."]=Frames["0"]=Frames["1"]=Frames["2"]=1;
  #
  # vector classes
  VT["sco"]=VT["score"]=VT["0pos-sco"]= 0;                            # only scores
  VT["pos"]=VT["position"]=VT["1pos-sco"]=VT["def"]=VT["default"]= 1; # position-score pairs
  VT["seg"]=VT["segment"]=VT["2pos-sco"]= 2;                          # position-position-score triplets
  VT["str"]=VT["string"]=VT["sequence"]= 3;                           # position-position-score triplets
  shpVT["default"]=shpVT["gradient"]="vt";
  shpVT["line_plot"]=shpVT["line"]="vtc";
  #
  # Coding shape-names
  shpnm["none"]="no_shp";
  shpnm["default"]=shpnm["line"]="line";
  shpnm["base_line"]="bline";
  shpnm["thick_line"]="tline";
  shpnm["weighted_line"]="scline";
  shpnm["box"]="box";
  shpnm["half_box"]="hbox";
  shpnm["circle"]="fcir";
  shpnm["half_circle"]="hcir";
  shpnm["arrow_head"]=shpnm["right_arrow_head"]="frhead";
  shpnm["half_arrow_head"]=shpnm["half_right_arrow_head"]="hrhead";
  shpnm["left_arrow_head"]="flhead";
  shpnm["half_left_arrow_head"]="hlhead";
  shpnm["arrow_end"]=shpnm["right_arrow_end"]="frend";
  shpnm["half_arrow_end"]=shpnm["half_right_arrow_end"]="hrend";
  shpnm["left_arrow_end"]="flend";
  shpnm["half_left_arrow_end"]="hlend";
  shpnm["single"]=shpnm["right_single"]=shpnm["arrow"]=shpnm["right_arrow"]="frsgl";
  shpnm["half_single"]=shpnm["half_arrow"]=shpnm["half_right_arrow"]="hrsgl";
  shpnm["left_single"]=shpnm["left_arrow"]="flsgl";
  shpnm["half_left_single"]=shpnm["half_left_arrow"]="hlsgl";
  shpnm["right_triangle"]="frtgl";
  shpnm["half_right_triangle"]="hrtgl";
  shpnm["left_triangle"]="fltgl";
  shpnm["half_left_triangle"]="hltgl";
  shpnm["diamond"]="fdmd";
  shpnm["half_diamond"]=shpnm["up_triangle"]="hdmd";
  shpnm["down_triangle"]="fdtgl";
  shpnm["sand_clock"]="f2tgl";
  shpnm["asterisk"]="fast";
  shpnm["star"]="fstar";
  shpnm["gap"]="gap";
  shpnm["group_tag_box"]="gtgb";
  shpnm["right_angle"]="rangl";
  shpnm["left_angle"]="langl";
  shpnm["loop"]="loop";
  # BG features
  shpnm["background_box"]="bgb";
  shpnm["background_boundary"]="bgw";
  shpnm["on_interval"]="oim";
  shpnm["on_ruler_mark"]="orm";
  # shpnm["half_star"]="hstar";
  #
  # Coding baseline alignment
  shpal["baseline"]=shpal["bottom"]=1;
  shpal["default"]=shpal["center"]=0;
  shpal["mirror"]=2;
  shpal["reverse"]=shpal["top"]=-1;
  #
  # Label Valign
  shplv["default"]=shplv["center"]="(cv)";
  shplv["top"]="(tv)";
  shplv["bottom"]="(bv)";  
  #
  # Coding line-types
  lnnm["none"]="no";
  lnnm["default"]=lnnm["line"]="ln";
  lnnm["dotted"]=lnnm["dotted_line"]="dt";
  lnnm["long_dotted"]="lt";
  lnnm["short_dashed"]="sh";
  lnnm["long_dashed"]="lh";
  lnnm["bracket"]="bk";
  lnnm["arrow"]=lnnm["right_arrow"]="raw";
  lnnm["left_arrow"]="law";
} # End of function ARY_VARIABLES
#
function PageSizesDEF() { # Default PageSizes:
  #
  PrintRPT("*  Default Page Formats...\n");
  #
  PsizeX["a0"]=2384; PsizeY["a0"]=3370;
  PsizeX["a1"]=1684; PsizeY["a1"]=2384;
  PsizeX["a2"]=1190; PsizeY["a2"]=1684;
  PsizeX["a3"]=842; PsizeY["a3"]=1190;
  PsizeX["a4"]=595; PsizeY["a4"]=842;
  PsizeX["a5"]=420; PsizeY["a5"]=595;
  PsizeX["a6"]=297; PsizeY["a6"]=420;
  PsizeX["a7"]=210; PsizeY["a7"]=297;
  PsizeX["a8"]=148; PsizeY["a8"]=210;
  PsizeX["a9"]=105; PsizeY["a9"]=148;
  PsizeX["a10"]=73; PsizeY["a10"]=105;
  PsizeX["b0"]=2920; PsizeY["b0"]=4127;
  PsizeX["b1"]=2064; PsizeY["b1"]=2920;
  PsizeX["b2"]=1460; PsizeY["b2"]=2064;
  PsizeX["b3"]=1032; PsizeY["b3"]=1460;
  PsizeX["b4"]=729; PsizeY["b4"]=1032;
  PsizeX["b5"]=516; PsizeY["b5"]=729;
  PsizeX["b6"]=363; PsizeY["b6"]=516;
  PsizeX["b7"]=258; PsizeY["b7"]=363;
  PsizeX["b8"]=181; PsizeY["b8"]=258;
  PsizeX["b9"]=127; PsizeY["b9"]=181;
  PsizeX["b10"]=91; PsizeY["b10"]=127;
  PsizeX["10x14"]=720; PsizeY["10x14"]=1008;
  PsizeX["executive"]=540; PsizeY["executive"]=720;
  PsizeX["folio"]=612; PsizeY["folio"]=936;
  PsizeX["ledger"]=1224; PsizeY["ledger"]=792;
  PsizeX["legal"]=612; PsizeY["legal"]=1008;
  PsizeX["letter"]=612; PsizeY["letter"]=792;
  PsizeX["quarto"]=610; PsizeY["quarto"]=780;
  PsizeX["statement"]=396; PsizeY["statement"]=612;
  PsizeX["tabloid"]=792; PsizeY["tabloid"]=1224;
  PsizeX["userdefined"]=595; PsizeY["userdefined"]=2384;
  NumPGSZ=34; # 32 fixed + 2 variable
} # End of function PageSizesDEF
#
function READ_CL() {
  #
  PrintRPT("*  Processing Comman-Line Options...\n");
  #
  while ( ( getline < ARGV[1] ) > 0 ) {
	npar=split($0,parm,"::");
	for (r=1;r<=npar;r++) {
	  split(parm[r],elem,":=");
	  if (elem[1]~/COLOR$/) {
		ecolor=elem[2];
		if (!ChkColor(ecolor)) elem[2]=BG_COLOR;
		else if (tolower(ecolor)~/^fg(color)?$/) elem[2]=FG_COLOR;
	  } # if elem[1]
	  if (elem[2]!="!!!???") Var[elem[1]]=elem[2];
	} # for
  } # while
  ARGV[1]="";  
} # End of function READ_CL
#
function ChkInput() { # some changes will be made on input line if some defaults were present.
  f=split($0,ln,/[\t ]*[\#]/);
  if (ln[1]!="") {
	$0=""; $0=ln[1]; for (s=1;s<=f;s++) { delete ln[s] };
	if (!($frame in Frames) && NF>=8) { 
	  PrintWRN(sprintf("*** WARNING ***  Unknown frame \"%s\" (replaced by \".\") in [%s]:\n", $frame, NR)); #  ***  <%s>\n", $frame, NR, $0));
	  $frame=".";
	} # if frame not exist
	if (!($strand in strands) && NF>=8) {
	  PrintWRN(sprintf("*** WARNING ***  Unknown strand \"%s\" (replaced by \".\") in [%s]:\n", $strand, NR)); #  ***  <%s>\n", $strand, NR, $0));
	  $strand=".";
	} # if strand not exist
	if ($start>$end && NF>=8) {
	  kk=$start; $start=$end; $end=kk;
	  # PrintWRN(sprintf("*** WARNING ******  Non-standard gff-formatted input line [%s]: <%s>\n            ***  REMEMBER that START(%s) must be lower or equal than END(%s): Swapping their values.\n", NR, $0,$start,$end));
	  PrintWRN(sprintf("*** WARNING ******  Non-standard gff-formatted input line [%s].\n            ***  REMEMBER that START(%s) must be lower or equal than END(%s): Swapping their values.\n", NR, $start, $end));
	} # if start>end
	if ($0~gff_format_V2) { 
	  GFF_V=2;
	  return 1;
	} # if gff-line Version 2 OK
	else { 
	  if ($0~gff_format_V1) {
		GFF_V=1;
		return 1;
	  } # if gff-line Version 1 OK    
	  else { # PrintWRN
        if ($0!~/^[\t ]*$/) {
          if (NF<8) PrintWRN(sprintf("*** WARNING ***  Non-standard gff-formatted input line [%s]: <%s>\n            ***  There are %s fields left: Standard gff lines need a minimum of 8 fields.\n", NR, $0, 8-NF));
		  else {		
		    PrintWRN(sprintf("*** WARNING ******  GARBAGE\!: Non-standard gff-formatted input line [%s]:\n            ***  <%s>\n", NR, $0));
		  } # else if NF>8
        }
	    else PrintWRN(sprintf(">>> %10s :: Empty line... <%s>\n", NR, $0));
		return 0 } # else gff-line WRONG
	} # else gff-line NON-Standard
  } # else empty line
  else {
    if ($0~/^[\t ]*[\#].*/) PrintWRN(sprintf(">>> %10s :: Comment Line: <%s>\n", NR, ChkCharIF($0)));
    else PrintWRN(sprintf(">>> %10s :: Empty line... <%s>\n", NR, $0));
	return 0;
  } # if not comment
} # End function ChkInput
#
function scan_quotes(Vscn) {
  while ($Vscn!~/^.*[^\"]\"(\;)?$/ && Vscn<NF) { Gtv=Gtv" "$Vscn; $Vscn=""; Vscn++ };
  if ($Vscn~/^.*[^\"]\"(\;)?$/) { Gtv=Gtv" "$Vscn } # solving '"<label>";' issue
  else Gtv=Gtv" "$Vscn"\"";
  gsub(/\;$/,"",Gtv); 
  $Vscn="";
} # End function scan_quotes
#
function LOAD_Quoted(GFN,    mm) {
  if ($GFN~"^"REgroupV2"$") { 
	split($GFN,mm,/\"/);
	gp_tag=mm[1];
	Gtv=mm[2];
	gp_TYPE="Tag-Value (Single)";
	# printf "***GFFV*** %s *** %s ***Tag*** %s ***Val*** %s\n", GFF_V, gp_TYPE, gp_tag, Gtv | "cat 1>&2";
  } # if tag-value single single
  else {
	if ($GFN~"^"REtag"$" && $(GFN+1)~"^"REval"$") {
	  gp_tag=$GFN;
	  Gtv=$(GFN+1);
	  gp_TYPE="Tag-Value (Single)";
	  # printf "***GFFV*** %s *** %s ***Tag*** %s ***Val*** %s\n", GFF_V, gp_TYPE, gp_tag, Gtv | "cat 1>&2"; 
	} # if tag-value single double
	else {
	  if ($GFN~"^"REtag"$" && $(GFN+1)~/^\".*[^\"]$/) {
		gp_tag=$GFN;
		Gtv=$(GFN+1);
		Vscn=GFN+2;
		scan_quotes(Vscn);
		gp_TYPE="Tag-Value (Multiple)";
		# printf "***GFFV*** %s *** %s ***Tag*** %s ***Val*** %s\n", GFF_V, gp_TYPE, gp_tag, Gtv | "cat 1>&2"; 
	  } # if tag-value multiple
	  else {
		if ($GFN~"^"CKgroupV1"$") {
		  Gtv=$GFN;
		  gp_TYPE="Value (Single)";
		  # printf "***GFFV*** %s *** %s ***Tag*** %s ***Val*** %s\n", GFF_V, gp_TYPE, gp_tag, Gtv | "cat 1>&2"; 
		} # if value single
		else {
		  if ($GFN~/^\".*[^\"]$/) {
			Gtv=$GFN;
			Vscn=GFN+1;
			scan_quotes(Vscn);
			gp_TYPE="Value (Multiple)";
			# printf "***GFFV*** %s *** %s ***Tag*** %s ***Val*** %s\n", GFF_V, gp_TYPE, gp_tag, Gtv | "cat 1>&2";
		  } # if value multiple
		} # else value multiple
	  } # else value single
	} # else tag-value multiple
  } # else tag-value single double
} # End function LOAD_Quoted
#
function LOAD_Groups(    pnt,lbgp_tmp) {
  # Obtaining group string values.
  gptv=1;
  gp_tag=".";
  Gtv=".";
  if (NF>8 && $group!=".") {
	LOAD_Quoted(group);
	gsub("\"","",Gtv); # removing quotes from group name.
	gsub(/\;$/,"",Gtv); # solving '"<label>";' issue
	lbgp_tmp=Gtv;
	Gtv=$seqname $source $strand Gtv;
	label_group[Gtv]=lbgp_tmp;
	flg_grp=1;
  } # else NF>8 and group!="." o group!=""
  else {                               # else group = string_value
	# if (NF==8 || $group==".") {             # if no group is given.
	Gtv=NR $seqname $source $strand;   # empty group defined as default (none==".")
	label_group[Gtv]="";
	gp_TYPE="Ungrouped";
	flg_grp=0;
  } # if NF=8 and group="." o group=""
} # End function LOAD_Groups
#
function LOAD_Vectors(    v_nm,K,k,W,w,vs,vv,va,v_,stp,lsco,usco,nsc,vtsc,equal) {
  if (NF==Vscn) {  # Loading multi-record vectors.
	v_nm=vct_element[$feature,iG2];
    # loading VECTOR elements.
	element[iG2,v_nm,start]    = min(element[iG2,N[iG2],start],$start);
	element[iG2,v_nm,end]      = max(element[iG2,N[iG2],end],$end);
	element[iG2,v_nm,v_window] = 0;
	element[iG2,v_nm,v_step]   = 0;
	if ($score!=".") {
      element[iG2,v_nm,v_scmin]  = min(element[iG2,v_nm,v_scmin],$score);
	  element[iG2,v_nm,v_scmax]  = max(element[iG2,v_nm,v_scmax],$score);
    }
	element[iG2,v_nm,v_DATA]   = element[iG2,v_nm,v_DATA] sprintf(" %5.3f %s %s",$score,$start,$end);
	element[iG2,v_nm,v_NUM]++;
	# removing FEATURE elements.
	if (vct_element[iG2,v_nm,v_NUM]>1) {
	  element[iG2,v_nm,v_CLASS]=VT["segment"];
	  delete element[iG2,N[iG2],feature];
	  delete element[iG2,N[iG2],start];
	  delete element[iG2,N[iG2],end];
	  delete element[iG2,N[iG2],frame];
	  delete element[iG2,N[iG2],score];
	  N[iG2]--;
	  sources[iS]--;     # field 2 (source) record-counter
	  FT_ary[iF]-- ;     # field 3 (gff-feature) record-counter
	  GP_ary[Gtv]--;     # field 9 (group) record-counter
	}
  } # if multi-record vectors.
  else { # Loading single-record vectors. (Vector: sco sco ... sco)
	v_nm=N[iG2];
	element[iG2,v_nm,v_window] = 0; # if none then paired data.
	element[iG2,v_nm,v_step]   = 0; # if none then paired data.
	element[iG2,v_nm,v_scmin]  = 0; # score defined?
	element[iG2,v_nm,v_scmax]  = 0; # score defined?
    # PrintRPT(sprintf("GPName: %s\nMAIN: %s\nVECTOR: %s\n",VctSPLIT,vs[1],vs[2]));
    split($0,vs,VctSPLIT);
    # PrintRPT(sprintf("GPName: %s\nMAIN: %s\nVECTOR: %s\n",VctSPLIT,vs[1],vs[2]));
    K=split(vs[2],vv,/[ \t]*;[ \t]+/);
	# K=split(yoyoba,vv,/[ \t]*;[ \t]+/);
  # gsub(/[ \t]*/,"",vv[1]);
	if (tolower(vv[1]) in VT) element[iG2,v_nm,v_CLASS]=VT[vv[1]]; # vector class: score position(default) segment
	else element[iG2,v_nm,v_CLASS]=VT["default"]; # set as position-score
    lsco=usco=0;
	for (k=2;k<=K;k++) {
	  W=split(vv[k],va,/[ \t]+/);
	  v_=tolower(va[1]);
      # PrintRPT(sprintf("V-TAG: %s \tV-DATA: %s\n",va[1],va[2]));
	  if (v_~/^window/ && va[2]~/[0-9]+/)    element[iG2,v_nm,v_window] = va[2];
	  else if (v_~/^step/ && va[2]~/[0-9]+/) element[iG2,v_nm,v_step]   = va[2];
	  else if (v_~/^minval/ && va[2]~/[+-]?[0-9]*[.]?[0-9]+(e[+-]?[0-9]+)?/) {
              element[iG2,v_nm,v_scmin] = va[2];
              lsco=1;
              }
	  else if (v_~/^maxval/ && va[2]~/[+-]?[0-9]*[.]?[0-9]+(e[+-]?[0-9]+)?/) {
              element[iG2,v_nm,v_scmax] = va[2];
              usco=1;
              }
	  else if (v_~/^scores/) {
		stp=element[iG2,v_nm,v_CLASS]+1;
        vtsc=""; equal=0;
		for (w=2;w<=W;w+=stp) {          
		  if (element[iG2,v_nm,v_CLASS]==0) {
            vtsc=vtsc""va[w]" ";
            nsc=va[w] }
		  else if (element[iG2,v_nm,v_CLASS]==1) {
            vtsc=vtsc""va[w]" "va[w+1]" ";
            nsc=va[w+1] }
		  else if (element[iG2,v_nm,v_CLASS]==2) {
            vtsc=vtsc""va[w]" "va[w+1]" "va[w+2]" ";
            nsc=va[w+2] }
          if (equal) {
            if (nsc!="-") {
              if (!lsco) element[iG2,v_nm,v_scmin] = min(element[iG2,v_nm,v_scmin],nsc);
              if (!usco) element[iG2,v_nm,v_scmax] = max(element[iG2,v_nm,v_scmax],nsc);
            }
	      } # if 
          else {
            if (nsc!="-") {
              element[iG2,v_nm,v_scmin]=element[iG2,v_nm,v_scmax]=nsc;
              equal=1;
            } 
          }; # else equal==0
	    } # for w
        element[iG2,v_nm,v_DATA]=vtsc;
		for (w=1;w<=W;w++) delete va[w];
	  } # if scores
	}  # for
	if (element[iG2,v_nm,v_step]==0) {
      element[iG2,v_nm,v_step]=element[iG2,v_nm,v_window];
    };
	for (k=2;k<=K;k++) delete vv[k]; delete vs[1]; delete vs[2];
  }  # else single-record
  #
  element[iG2,v_nm,vector] = 1;
}  # End function LOAD_Vectors
#
function ReadElements() { # read gff element within source, strand, and group 
  sp_feat=0;
  # GFF format compliant record-counter
  gff_NR++;
  #
  $feature=tolower($feature);
  # Defining some indexes.
  iS=$source;  # iS=$seqname SUBSEP $source;
  iF=$feature; # iF=$seqname SUBSEP $feature;
  II=$seqname SUBSEP iS;
  # getting sequence order from file...
  if (!($seqname in seqs)) {
    TITLE_FN=TITLE_FN""$seqname" ";
  }
  if ($strand~/[+-]/) {
    STR_PMT=1;
    Nss[II]++; # Valid Sequence-Source Combinations (Strand)
  }
  else {
    STR_PMT=0;
    Nsn[II]++; # Valid Sequence-Source Combinations (No-Strand)
  }
  if (SQ_ORD[$seqname,STR_PMT]!="Y") {
    if (STR_PMT) seq_order["strand",seq_ordcnt++]=$seqname;
    else seq_order["none",seq_nordcnt++]=$seqname;
    SQ_ORD[$seqname,STR_PMT]="Y";
  }
  # getting source order from file...
  if (!(iS in sources)) {
    sc_score["MIN",iS] = 0;
    sc_score["MAX",iS] = $score;
  }
  if (SC_ORD[$seqname,iS,STR_PMT]!="Y") {
    if (STR_PMT) src_order["strand",src_ordcnt++]=$source;
    else src_order["none",src_nordcnt++]=$source;
    SC_ORD[$seqname,iS,STR_PMT]="Y";
  }
  # Defining some counters.
  seqs[$seqname]++;
  sources[iS]++;   # field 2 (source) record-counter (Nsources for no-strand)
  FT_ary[iF]++ ;              # field 3 (gff-feature) record-counter
  # Defining groups.
  LOAD_Groups();
  GP_ary[Gtv]++;              # field 9 (group) record-counter
  # Creating group arrays.
  iG1=$seqname SUBSEP $source SUBSEP $strand;
  iG2=iG1 SUBSEP Gtv;
  if (!(iG2 in N)) {
    G[iG1]++;
    gp[iG1,G[iG1],gpname]     = Gtv;
    gp[iG1,G[iG1],gplabel]    = label_group[Gtv];
    gp[iG1,G[iG1],gpstart]    = $start;
    gp[iG1,G[iG1],gpend]      = $end;
    gp[iG1,G[iG1],is_grouped] = flg_grp;
    gp_cnt[Gtv]               = G[iG1];
	# PrintRPT(sprintf("***** %s {%s} *** Creating Group DataSet on %s\n",Gtv,G[iG1],iG1));
	# PrintRPT(sprintf("***** %s {%s} *** Is grouped? %s *** Group Class \"%s\"\n",Gtv,G[iG1],TxtBool(gp[iG1,G[iG1],is_grouped]),gp_TYPE));
  } # if tmp in N
  N[iG2]++;
  # PrintRPT("#######FILE###START#" $start "##END#" $end "##\n");
  element[iG2,N[iG2],feature] = $feature; 
  element[iG2,N[iG2],start]   = $start;
  element[iG2,N[iG2],end]     = $end;
  element[iG2,N[iG2],frame]   = $frame;  
  element[iG2,N[iG2],score]   = $score;    # element[iG2,N[iG2],group] = $group; 
  # PrintRPT("#######ELEM###START#" element[iG2,N[iG2],start] "##END#" element[iG2,N[iG2],end] "##\n");
  # Defining vectors if present.
  if (!vct_element[$feature,iG2]) vct_element[$feature,iG2]=N[iG2];
  if (tolower(gp_tag)=="vector") {
    LOAD_Vectors();
    gp[iG1,G[iG1],is_grouped] = 0;
    gp[iG1,G[iG1],gplabel]    = "";
    }
  else element[iG2,N[iG2],vector]=0;
  # Defining expands if present
  if (!vct_expand[Gtv,iG2]) {
    gpx[Gtv,xpnd_zoom] = gpx[Gtv,xpnd_delta] = 0;
    vct_expand[Gtv,iG2]++;
    }
  if (tolower(gp_tag)=="expand") {
    expand_ct++;
    gpx[Gtv,expand] = 1;
    gsub(";","",$12);
    gsub(";","",$14);
    gpx[Gtv,xpnd_zoom] = $12;
    gpx[Gtv,xpnd_delta] = $14;  
    if ($16=="2") gpx[Gtv,xpnd_level] = "2"; 
    else if ($16=="1") gpx[Gtv,xpnd_level] = "1"; 
    else if ($16=="-1") gpx[Gtv,xpnd_level] = "-1"; 
    else gpx[Gtv,xpnd_level] = "1";
    gpx[Gtv,xpnd_frame] = $8; # frame
PrintRPT("###############Found EXPAND Z:"gpx[Gtv,xpnd_zoom]" D:"gpx[Gtv,xpnd_delta]" L:"gpx[Gtv,xpnd_level]"\n");
    }
  # Defaults for sequence start and end.
  if (FIRST_POS>$start) FIRST_POS = $start;
  if (LAST_POS<$end)    LAST_POS  = $end;
  # start-end for each group-sc-strand  
  gp[iG1,gp_cnt[Gtv],gpstart] = min(gp[iG1,gp_cnt[Gtv],gpstart],$start);
  # PrintRPT("##############MIN#" gp[iG1,gp_cnt[Gtv],gpstart] "##" min(gp[iG1,gp_cnt[Gtv],gpstart],$start) "##\n");
  gp[iG1,gp_cnt[Gtv],gpend]   = max(gp[iG1,gp_cnt[Gtv],gpend],$end);
  # PrintRPT("##############MAX#" gp[iG1,gp_cnt[Gtv],gpend] "##" max(gp[iG1,gp_cnt[Gtv],gpend],$end) "##\n");
  # getting score - boundaries 
  sc_score["MIN",iS]=min($score,sc_score["MIN",iS]);
  sc_score["MAX",iS]=max($score,sc_score["MAX",iS]);
  # place gff element in sort array by acceptor position
  NS=N[iG2]-1;
  while ($start < element[iG2,S[iG2,NS],start] && NS>0) { 
    S[iG2,NS+1]=S[iG2,NS]; NS-- } # while
  S[iG2,NS+1]=N[iG2];
} # End of ReadElements
#
function SET_VARS() {
  #
  PrintWRN(sprintf("%s\n*  Processing User-Defined Options...\n%s\n\n",BigLINE,BigLINE));
  #
  # Variable definition hierarchy:
  # Program Defaults < Default Custom File < Custom File < Command Line.
  CreateProps(0);
  if (Var["exist_default_customfile"]) { # Modifying Defaults with default custom file
    PrintWRN(sprintf("\n%s\n*  Reading Default Custom File:\n*  \"%s\"\n*\n",BigLINE,Var["customfile_name_default"]));
    RCFile(Var["customfile_name_default"]);
  } # if exist_default_customfile
  else PrintWRN(sprintf("\n%s\n*  Default Custom File not loaded.\n%s\n",BigLINE,BigLINE));
  if (Var["load_customfile"]) { # Modifying Defaults with custom file
	PrintWRN(sprintf("\n%s\n*  Reading User Custom File:\n*  \"%s\"\n*\n",BigLINE,Var["customfile_name"]));
	RCFile(Var["customfile_name"]);
  } # if load_customfile
  else PrintWRN(sprintf("\n%s\n*  User Custom File not loaded.\n%s\n",BigLINE,BigLINE));
  PrintWRN(sprintf("\n%s\n*  Command-Line Options\n*\n",BigLINE));
  for (lytdef in Default) {
    dft=Default[lytdef];
 	if (PLOT_LY[lytdef]!="") Default[lytdef]=PLOT_LY[lytdef];
    if (lytdef in Var) {
      if (Default[lytdef]!=Var[lytdef] && Var[lytdef]!="") Default[lytdef]=Var[lytdef];
    } # if lytdef in var
    else Var[lytdef]="\"NOT_DEF\"";
    if (PLOT_LY[lytdef]=="") PLOT_LY[lytdef]="\"NOT_DEF\"";
	if (Var["print_report"]) printf "%s *** Default Value=%s : Custom File=%s : Command-Line=%s *** Using=%s\n", lytdef,dft,PLOT_LY[lytdef],Var[lytdef],Default[lytdef] | "sort 1>&2";
  } # for lytdef
  if (Var["print_report"]) close("sort 1>&2");
  PrintWRN(sprintf("*\n* ........................................................ DONE\n*\n%s\n",BigLINE));
  # forcing page_size if page_bbox is provided in custom-files with its format.
  split(Default["page_bbox"],bbm,",");
  bbpgsz=tolower(bbm[1]); bbx=bbm[2]; bby=bbm[3];
  if (bbpgsz=="auto" || (bbx==0 || bby==0)) {
	bbpgsz=tolower(Default["page_size"]);
	if (!chkps(bbpgsz)) { bbx=PsizeX["a4"]; bby=PsizeY["a4"] }
    else { bbx=PsizeX[bbpgsz]; bby=PsizeY[bbpgsz] }
  } # if
  else {
    Default["page_size"]=bbpgsz;
    PsizeX[bbpgsz]=bbx; PsizeY[bbpgsz]=bby;
    NumPGSZ++;
  }
  # Title definition...
  # TITLE_FN=TITLE_SEQNAME # TITLE_FN=Var["InputFNs"];
  if (Default["title"]=="none") { flgt="false"; title="" }
  else {
	flgt="true";
	if (Default["title"]=="default") { title=TITLE_FN } 
	else title=Default["title"] }
  title=substr(title,1,100);
  # First and last position, zoom option checking...
  t_ori=Nuc_round(FIRST_POS,0); # floor
  t_end=Nuc_round(LAST_POS,1);  # ceiling
  #
  split(Default["zoom"],poszm,/\.\./);
  split(Default["zoom_cmdln"],poszmc,/\.\./);
  if (poszmc[1]!="*") poszm[1]=poszmc[1];
  if (poszmc[2]!="*") poszm[1]=poszmc[2];
  if (poszm[1]=="*") PORI=t_ori; else PORI=poszm[1];
  if (poszm[2]=="*") PEND=t_end; else PEND=poszm[2];
  #
  if (gff_NR==0) { ## Here can be included a checking for no strand drawn??
	PORI=0; PEND=1000;
	title="Empty PLOT";
	PrintWRN("\n***************\n*** WARNING *** There were no gff-records from input-files.\n*** WARNING *** You are going to obtain an empty page...\n***************\n");
  }
  if (PORI!=0) PDIF=PEND-PORI; # if PDIF=PEND-PORI+1 then plot with an "extra" nucleotide position.
  else PDIF=PEND;
  MGS=Default["min_group_separation"];
  # switching for tickmarks (none,both/default,top,bottom)
  FlgSwISUp=0; FlgSwISDn=0; TmTt=chktmk(Default["show_inner_scale"]);
  if (TmTt=="both") { FlgSwISUp=1; FlgSwISDn=1; }
  else {
    if (TmTt=="top") FlgSwISUp=1;
    else
      if (TmTt=="bottom") FlgSwISDn=1;
  }
  FlgSwOSUp=0; FlgSwOSDn=0; TmTt=chktmk(Default["show_outer_scale"]);
  if (TmTt=="both") { FlgSwOSUp=1; FlgSwOSDn=1; }
  else {
    if (TmTt=="top") FlgSwOSUp=1;
    else
      if (TmTt=="bottom") FlgSwOSDn=1;
  }
  #
  #
  # Defining Multi-Chromosome Display Offsets.
  #   File format: offset/blank start end label(blanks as underscore)
  if (OnOff(Var["CHOSFLAG"])) { 
    PrintRPT("\n"BigLINE"\nReading New OFFSET Line from file: "Var["CHOSFILE"]"\n"BigLINE"\n");
    while ((getline < Var["CHOSFILE"]) > 0 ) {
      if (tolower($1)=="offset") {
        CHOffSet[0]++;
        CHOffSet[CHOffSet[0]] = $2;
        CHOffSetend[CHOffSet[0]] = $3;
        gsub("_"," ",$4);
        CHOSlabel[CHOffSet[0]] = $4;
        PrintRPT("OFFSET "CHOffSet[0]" : "$0"\n");
        }
      else {
        CHOSblnk++;
        CHOSblnkori[CHOSblnk] = $2;
        CHOSblnkend[CHOSblnk] = $3;
        PrintRPT("BLANK "CHOSblnk" : "$0"\n");
        }
      } # while CHOSFILE
      close(Var["CHOSFILE"]);
    } # if CHOSFLAG
  #
} # End of function SET_VARS
#
function SET_ORDER(    Q,S,lseq,lsrc,seso_rd) { # for swapping order for seqs or srcs.
  PrintWRN(sprintf("\n%s\n*  SORTING TRACKS and SEQUENCES\n*\n",BigLINE));
  #
  if (OnOff(Default["sort_tracks_by_sequence"])) {
    PrintWRN("*  Sorting by SEQUENCES then by SOURCES (Comparing Sources)\n*\n");
	lseq=seq_ordcnt; lsrc=src_ordcnt;   # strand(+/-) counter
	for (Q=0;Q<lseq;Q++) {   # sequence ordering ary loop
	  for (S=0;S<lsrc;S++) { # source ordering ary loop
        seso_rd=seq_order["strand",Q] SUBSEP src_order["strand",S];
		if ((seso_rd in Nss) && !(seso_rd in CHKs)) {
		  order["strand",ordcnt++]=seso_rd;
          PrintRPT(sprintf("***+++***STRAND***Order[%s]::%s::***K1::%s::***K2::%s::***CTRL::%s\n", (ordcnt-1), order["strand",(ordcnt-1)], seq_order["strand",Q], src_order["strand",S], CHKs[seso_rd]));
        } # if seso_rd
        CHKs[seso_rd]++;
	  } # for S
	} # for Q
	lseq=seq_nordcnt; lsrc=src_nordcnt; # no-strand counter
	for (Q=0;Q<lseq;Q++) {   # sequence ordering ary loop
	  for (S=0;S<lsrc;S++) { # source ordering ary loop
        seso_rd=seq_order["none",Q] SUBSEP src_order["none",S];
		if ((seso_rd in Nsn) && !(seso_rd in CHKn)) {
		  order["none",nordcnt++]=seso_rd;
		  PrintRPT(sprintf("***+++***NO-STR***Order[%s]::%s::***K1::%s::***K2::%s::***CTRL::%s\n", (nordcnt-1), order["none",(nordcnt-1)], seq_order["none",Q], src_order["none",S], CHKn[seso_rd]));
        } # if seso_rd
        CHKn[seso_rd]++;
	  } # for S
	} # for Q
  } # if sort by sequence
  else {
    PrintWRN("*  Sorting by SOURCES then by SEQUENCES (Comparing Sequences)\n*\n");
	lseq=seq_ordcnt; lsrc=src_ordcnt;   # strand(+/-) counter
	for (S=0;S<lsrc;S++) {   # source ordering ary loop
	  for (Q=0;Q<lseq;Q++) { # sequence ordering ary loop
        seso_rd=seq_order["strand",Q] SUBSEP src_order["strand",S];
		if ((seso_rd in Nss) && !(seso_rd in CHKs)) {
		  order["strand",ordcnt++]=seso_rd;
		  PrintRPT(sprintf("***+++***STRAND***Order[%s]::%s::***K1::%s::***K2::%s::***CTRL::%s\n", (ordcnt-1), order["strand",(ordcnt-1)], seq_order["strand",Q], src_order["strand",S], CHKs[seso_rd]));
        } # if seso_rd
        CHKs[seso_rd]++;
	  } # for Q
	} # for S
	lseq=seq_nordcnt; lsrc=src_nordcnt; # no-strand counter
	for (S=0;S<lsrc;S++) {   # source ordering ary loop
	  for (Q=0;Q<lseq;Q++) { # sequence ordering ary loop
        seso_rd=seq_order["none",Q] SUBSEP src_order["none",S];
		if ((seso_rd in Nsn) && !(seso_rd in CHKn)) {
          order["none",nordcnt++]=seso_rd;
		  PrintRPT(sprintf("***+++***NO-STR***Order[%s]::%s::***K1::%s::***K2::%s::***CTRL::%s\n", (nordcnt-1), order["none",(nordcnt-1)], seq_order["none",Q], src_order["none",S], CHKn[seso_rd]));
        } # if seso_rd
        CHKn[seso_rd]++;
	  } # for Q	
	} # for S
  } # else sort by source
  #
  PrintWRN(sprintf("* ........................................................ DONE\n*\n%s\n",BigLINE));
} # End of function SET_ORDER
#
function SortGroups(    g) {
  PrintWRN(sprintf("\n%s\n*  SORTING GROUPS\n*\n",BigLINE));
  #
  for (sq in seqs) {
	for (sc in sources) {
	  for (s in strands) {
		g=sq SUBSEP sc SUBSEP s;
		if (G[g]>0) {
		  for (t=1;t<=G[g];t++) {
			gs=t-1;
            if (s!="-") { # sorting forward and no-strand by acceptors
			  gpstrt_=gp[g,t,gpstart];
			  # PrintRPT(sprintf("------- %s : (%s) #%s# #%s#\n",t,gp[g,t,gpname],gpstrt_,gp[g,t,gpend]));
			  while (gpstrt_ < gp[g,SG[g,gs],gpstart] && gs>0) {
                # PrintRPT(sprintf("------- %s < %s\n",gp[g,t,gpstart],gp[g,SG[g,gs],gpstart]));
			    SG[g,gs+1]=SG[g,gs]; gs--;
			  } # while
            }
            else { # sorting reverse by acceptors
			  gpstrt_=gp[g,t,gpend];
			  # PrintRPT(sprintf("------- %s : (%s) #%s# #%s#\n",t,gp[g,t,gpname],gpstrt_,gp[g,t,gpend]));
			  while (gpstrt_ > gp[g,SG[g,gs],gpend] && gs>0) {
                # PrintRPT(sprintf("------- %s > %s\n",gp[g,t,gpend],gp[g,SG[g,gs],gpend]));
			    SG[g,gs+1]=SG[g,gs]; gs--;
			  } # while              
            }
			SG[g,gs+1]=t;
		  } # for t 
		  for (t=1;t<=G[g];t++)
			PrintRPT(sprintf("*** Re-Sorting groups : {%s} %s %s %s %s ( %s %s )\n",t,sq,sc,s,gp[g,SG[g,t],gpname],gp[g,SG[g,t],gpstart],gp[g,SG[g,t],gpend]));
		} # if 
	  } # for strands
	} # for sources
  } # for seqs
  #
  PrintWRN(sprintf("*\n* ........................................................ DONE\n*\n%s\n",BigLINE));
} # End of SortGroups
#
function Aux_LINES(sq,sc,s,   g,lg,pg,fldGxU,fldGln,fldUln,LN,c) {
  lg=sq SUBSEP sc SUBSEP s;
  fldGxU=OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"]);
  fldGln=OnOff(PLOT_FT[sc,":","unfold_grouped_line"]);
  fldUln=OnOff(PLOT_FT[sc,":","unfold_ungrouped_line"]);
  #if (!fldGxU) { c=(fldGln||fldUln); fldGln=fldUln=c }
  if (G[lg]>0) {
    if (s!="-") lastpos[lg,grouped_,1]=lastpos[lg,ungrouped_,1]=t_ori-1; # PORI;
    else lastpos[lg,grouped_,1]=lastpos[lg,ungrouped_,1]=t_end+1; # PEND;
	lines[lg,grouped_]=lines[lg,ungrouped_]=1;
	for (pg=1;pg<=G[lg];pg++) {
      g=SG[lg,pg];
	  gp_nm =gp[lg,g,gpname];
	  gp_ori=gp[lg,g,gpstart];
	  gp_end=gp[lg,g,gpend];
      c=gp[lg,g,is_grouped];
      if (fldGxU) gp_gpd=c
	  else gp_gpd=1; # 1 (grouped_) or 0 (ungrouped_)
	  PrintRPT(sprintf(">>>>>>>%s %s %s %s (%s %s) G %s SG %s\n",sq,sc,s,gp_nm,gp_ori,gp_end,G[lg],g));
	  LN=1;
      ttt=lg SUBSEP gp_gpd SUBSEP LN;
	  if ((fldGln && c) || (fldUln && !c)) {
		PrintRPT(sprintf("A........%s : %s (%s) G %s SG %s %s %s %s %s \n",LN,lastpos[lg,gp_gpd,LN],gp_ori,G[lg],g,sq,sc,s,gp_nm));
		if (gp_end>PORI && gp_ori<PEND) {
          if (s!="-") {
            gpo=gp_ori-MGS;
		    if (gpo<PORI) gpo=gp_end;
            while (lastpos[ttt] > gpo) { # && gp_ori<=gpo
              LN++;
              ttt=lg SUBSEP gp_gpd SUBSEP LN;
              if (!(ttt in lastpos)) lastpos[ttt]=t_ori-MGS; # PORI;
              PrintRPT(sprintf("a(%s).........%s : %s : %s (%s..%s)\n",s,LN,ttt,lastpos[ttt],gp_ori,gpo));
            } # while lastpos
		    lastpos[lg,gp_gpd,LN]=gp_end;
          }
          else {
            gpe=gp_end+MGS;
		    if (gpe>PEND) gpe=gp_ori;
            while (lastpos[ttt] < gpe) { # && gpe>=gp_end
              LN++;
              ttt=lg SUBSEP gp_gpd SUBSEP LN;
              if (!(ttt in lastpos)) lastpos[ttt]=t_end+MGS; # PEND;
              PrintRPT(sprintf("a(%s).........%s : %s : %s (%s..%s)\n",s,LN,ttt,lastpos[ttt],gp_end,gpe));
            } # while lastpos
		    lastpos[lg,gp_gpd,LN]=gp_ori;
          }
		} # if checklimits
		PrintRPT(sprintf("B........%s : %s (%s %s) G %s SG %s\n",LN,lastpos[lg,gp_gpd,LN],gp_ori,gp_end,G[lg],g));
        PrintRPT(sprintf(">>>>>>> Line %s : LastPos %s : ID <%s><%s><%s><%s> (%s %s) \#G %s \#SG %s\n",LN,lastpos[lg,gp_gpd,LN],sq,sc,s,gp_nm,gp_ori,gp_end,G[lg],g));
	  } # if checking
	  lines[lg,gp_gpd]=max(lines[lg,gp_gpd],LN);
	  LE[lg,gp_gpd,LN]++;
	  LNelem[lg,gp_gpd,LN,LE[lg,gp_gpd,LN]]=g;
	} # for g(SG)
  } # if G>0
} # End of function Aux_LINES
#
function MakeGroupLines(    lg,c) {
  PrintWRN(sprintf("\n%s\n*  Minimizing Lines for Overlapping Groups.\n%s\n",BigLINE,BigLINE));
  for (stp=1;stp<=3;stp++) { # for s in strand
    s=wstr[stp];
	if (OnOff(Default["sort_tracks_by_sequence"])) {
	  for (sq in seqs) {
		for (sc in sources) {
		  Aux_LINES(sq,sc,s);
		} # for sources
	  } # for seqs
	}
	else {
	  for (sc in sources) {
		for (sq in seqs) {
		  Aux_LINES(sq,sc,s);
		} # for seqs
	  } # for sources
	}
  } # for strands
} # End of MakeGroupLines
#
function SET_PAGE_VARS() {  # Calculating Page Number, Blocks and NucxLine
  # header flags
  if (Default["header_style"]=="boxed") { shtt="true"; shbt="true" }
  else {
	if (Default["header_style"]=="default") { shtt="true"; shbt="false" }
	else { shtt="false"; shbt="false" }}
  HDRheight="1cm";
  # 
  P=Default["page_number"];
  B=Default["blocks_x_page"];
  if (B>0) {
	if (Default["nucleotides_x_line"]==0) {
	  if (B>1 || P>1) NOFFSET=Nuc_round((PDIF/(B*P)),1);
	  else NOFFSET=PDIF;
	}
	else NOFFSET=Default["nucleotides_x_line"];
	# if (NOFFSET>PDIF) NOFFSET=PDIF; # necessary if it is defined a Zoom.
	B1= PDIF%NOFFSET!=0 ? ((PDIF-(PDIF%NOFFSET))/NOFFSET)+1 : ((PDIF-(PDIF%NOFFSET))/NOFFSET);
	P = B1%B!=0 ? ((B1-(B1%B))/B)+1 : ((B1-(B1%B))/B);
	if (OnOff(Default["show_blocks_top-bottom"])) { BOFFSET=NOFFSET; POFFSET=B*NOFFSET }
	else { BOFFSET=P*NOFFSET; POFFSET=NOFFSET }
	PrintWRN(sprintf("\n%s\n*  PostScript Page Definitions\n%s\n\n",BigLINE,BigLINE));
	PrintRPT(sprintf("page_number %s\nblocks_x_page %s\nnucleotides_x_line %s\nshow_blocks_top-bottom %s\n\n",P,B,NOFFSET,OnOff(Default["show_blocks_top-bottom"])));
	# PrintRPT(sprintf("\nPORI %s\nPEND %s\nP %s\nB %s\nNOFFSET %s\nBOFFSET %s\n\n",PORI,PEND,P,B,NOFFSET,BOFFSET));
  } # if B>0
  else { # B==0
	if (Default["nucleotides_x_line"]==0) {
	  if (P>1) NOFFSET=Nuc_round((PDIF/P),1);
	  else NOFFSET=PDIF;
	}
	else NOFFSET=Default["nucleotides_x_line"];
	# if (NOFFSET>PDIF) NOFFSET=PDIF; # necessary if it is defined a Zoom.
	P = PDIF%NOFFSET!=0 ? ((PDIF-(PDIF%NOFFSET))/NOFFSET)+1 : ((PDIF-(PDIF%NOFFSET))/NOFFSET);
	POFFSET=BOFFSET=NOFFSET;
	PrintWRN(sprintf("\n%s\n*  PostScript Page Definitions\n%s\n\n",BigLINE,BigLINE));
	PrintRPT(sprintf("page_number %s\nblocks_x_page %s\nnucleotides_x_line %s\nshow_blocks_top-bottom %s\n\n",P,B,NOFFSET,OnOff(Default["show_blocks_top-bottom"])));
  } # else B==0
  # Calculating Block scale factor.
  StrSize=0; NStSize=0; # for strands...
  aS=calcpt(Default["default_track_width"]);
  bS=calcpt(Default["default_track_spacing_width"]);
  for (ws in order) {
	split(ws,wsb,SUBSEP);
    split(order[ws],K,SUBSEP);
    # PrintRPT(sprintf("***+++***WS::%s::***wsb1::%s::***wsb2::%s::\n", ws, wsb[1], wsb[2]));
    # PrintRPT(sprintf("***+++***Order[ws]::%s::***K1::%s::***K2::%s::\n", order[ws], K[1], K[2]));
   # PrintRPT(sprintf("***+++***Order[ws]::%s::***ws::%s::***wsb1::%s::***wsb2::%s::\n", order[ws], ws, wsb[1], wsb[2]));
    # PrintRPT(sprintf("***+++***Order[ws]::%s::***K1::%s::***K2::%s::\n", order[ws], K[1], K[2]));
    # k=order[ws]; #K[2];
    k=order[ws]; #K[2];
    q=K[2];
	if (wsb[1]=="strand") {
	  if (!OnOff(PLOT_FT[q,":","unfold_grouped_ungrouped"]) && !OnOff(PLOT_FT[q,":","unfold_grouped_line"]) && !OnOff(PLOT_FT[q,":","unfold_ungrouped_line"]))
		cl=1;
	  else {
		if (DoUnFoldMixed(q) && !OnOff(PLOT_FT[q,":","unfold_grouped_ungrouped"]))
		  cl=max(lines[k,"+",grouped_],lines[k,"-",grouped_]);
		else
		  cl=max(lines[k,"+",grouped_],lines[k,"-",grouped_])+max(lines[k,"+",ungrouped_],lines[k,"-",ungrouped_]);
	  }
	  StrSize=StrSize+(cl*((aS*PLOT_FT[q,":","track_scale"])+(bS*PLOT_FT[q,":","track_spacing_scale"])));
      # PrintRPT(sprintf("   +++***StrSize::%s::***cl::%s::***aS::%s::***bS::%s::\n", StrSize, cl, aS, bS));
	}
	else {
	  if (wsb[1]=="none") {
		if (!OnOff(PLOT_FT[q,":","unfold_grouped_ungrouped"]) && !OnOff(PLOT_FT[q,":","unfold_grouped_line"]) && !OnOff(PLOT_FT[q,":","unfold_ungrouped_line"]))
		  cl=1;
		else { 
		  if (DoUnFoldMixed(q) && !OnOff(PLOT_FT[q,":","unfold_grouped_ungrouped"]))
			cl=lines[k,".",grouped_];
		  else
			cl=lines[k,".",grouped_]+lines[k,".",ungrouped_];
		}
		NStSize=NStSize+cl*((aS*PLOT_FT[q,":","track_scale"])+(bS*PLOT_FT[q,":","track_spacing_scale"]));
		# PrintRPT(sprintf("   +++***NStSize::%s::***cl::%s::***aS::%s::***bS::%s::\n", NStSize, cl, aS, bS));
	  } # if wsb==none
	} # else if wsb 
  } # for order
  if (OnOff(Default["strand_show_forward"])) StrSizeFwd=StrSize; else StrSizeFwd=0;
  if (OnOff(Default["strand_show_reverse"])) StrSizeRvs=StrSize; else StrSizeRvs=0;
  if (!OnOff(Default["strand_show_independent"])) NStSize=0;
  if (gff_NR==0) { StrSizeFwd=0.33; StrSizeRvs=0.33; NStSize=0.33 }
  BSize=StrSizeFwd+StrSizeRvs+NStSize; # +xtra; # +SclSize (points)
  # PrintRPT(sprintf("\n***+++***StrSizeFwd::%s::***StrSizeRvs::%s::***NStSize::%s::***BSize::%s::\n", StrSizeFwd, StrSizeRvs, NStSize, BSize));
  if (B>0) VP=1;
  else {
    Sw=calcpt(Default["default_scale_width"]);
    if (StrSizeFwd>0 && (NStSize>0 || StrSizeRvs>0) && (OnOff(FlgSwISDn) || OnOff(FlgSwISUp))) BSize=BSize+Sw;
    if (NStSize>0 && StrSizeRvs>0 && (OnOff(FlgSwISDn) || OnOff(FlgSwISUp))) BSize=BSize+Sw;
    if (Default["page_orientation"]=="Landscape") ttbby=bbx; else ttbby=bby;
	if (OnOff(shtt)) {
      tthdr=calcpt(HDRheight)*(bbx/PsizeX["a4"]);
      tthdr=(tthdr>calcpt("4cm"))?calcpt("4cm"):tthdr;
      tthdr=tthdr+calcpt(Default["default_block_spacing_width"]);
    }
    else tthdr=0; # +(4*calcpt(Default["default_scale_width"]))
    if (OnOff(Var["Show_Credits"])) {
      crdt=calcpt("2.5pt")*(bbx/PsizeX["a4"]);
      crdt=(crdt>calcpt("1cm"))?calcpt("1cm"):crdt;
      crdt=2*crdt;
    }
    else crdt=0;
    if (OnOff(FlgSwOSUp)) TSwu=(1+Default["default_scale_spacing_width"])*Sw; else TSwu=0;
    if (OnOff(FlgSwOSDn)) TSwd=(1+Default["default_scale_spacing_width"])*Sw; else TSwd=0;
    TSw=TSwu+TSwd;
    Tsize=ttbby-(tthdr+calcpt(Default["margin_upper"])+calcpt(Default["margin_lower"])+TSw+crdt);
	VP=(BSize/Tsize);
    if (int(VP)<VP) VP=int(VP)+1;
    PrintRPT(sprintf("\n*********\n**** Page Vsize = %s cm \n**** Title Vsize = %s cm \n**** Block Tsize = %s cm \n**** Credit Vsize = %s cm \n***************\n\n",ttbby/28.35,tthdr/28.35,Tsize/28.35,crdt/28.35));
  } # else B==0
  # Major Minor Tickmarks ratio
  if (Default["major_tickmarks_nucleotides"]==-1 || NOFFSET<Default["major_tickmarks_nucleotides"]) {
	kt=NOFFSET/Default["major_tickmarks_num"];
    Default["major_tickmarks_nucleotides"]=kt<1000?kt:Nuc_round(kt,0); }
  if (Default["minor_tickmarks_nucleotides"]==-1 || Default["major_tickmarks_nucleotides"]<Default["minor_tickmarks_nucleotides"]) {
	Default["minor_tickmarks_nucleotides"]=Default["major_tickmarks_nucleotides"]/Default["minor_tickmarks_num"] }
} # End of function SET_PAGE_VARS
#
function MAIN_PAGE_LOOP() { # MAIN LOOP: Start
  if (OnOff(FlgSwISUp)) VSwu=Sw; else VSwu=0; 
  if (OnOff(FlgSwISDn)) VSwd=Sw; else VSwd=0; # for PRINTTRACKS function only
  VSw=VSwu+VSwd;
  for (pages=1;pages<=P;pages++) {
	Vpages=1;
    BORI=PORI;
	startPSpage(pages,P,Vpages,VP);  # PostSCript PageSetup.
	if (B>0) {
	  for (blocks=1;blocks<=B;blocks++) {
		BEND=BORI+NOFFSET;
        # make groups. assumes elements sorted by increasing acceptor position
        # PostScript Drawing strands, sources, groups, features
        # make plotlines. Put non-overlapping groups into the same plotting line.
		printf "%%%%%%%% BLOCK %s - PAGE %s\n",blocks,pages;
		printf "%s %s %s block\n", BORI, BEND, blocks;
		PrintWRN(sprintf("*  Page: %s - Block: %s - Nuc_Ori: %s - Nuc_End: %s\n",pages,blocks,BORI,BEND));
		#
        PRINTblockBG();
		PRINTSOURCES();
        # if (Var["print_report"]) close("sort +6 1>&2");
        # Closing Pages MAIN LOOP.
      if (OnOff(Var["CHOSFLAG"])) { 
	    PrintRPT(sprintf("   * Sequence: %-25s Source: %-25s Strand: %s *** Printing block offsets labels...\n", sq, sc, s));
        printf "%%%%%%%% BLABELS\n";
        if (Default["major_tickmarks_nucleotides"]==-1) theta=1000;
        else theta=Default["major_tickmarks_nucleotides"];
        for (lzd=1;lzd<=CHOffSet[0];lzd++) {
          if (CHOffSet[lzd]>=BORI && CHOffSet[lzd]<BEND) {
            kukoo = CHOffSet[lzd] - theta;
            printf "%d %d (%s) split_ruler\n", kukoo, CHOffSet[lzd], CHOSlabel[lzd];
            } # if
          } # for CHOffSet
        for (lzd=1;lzd<=CHOSblnk;lzd++) {
          if (CHOSblnkori[lzd]>=BORI && CHOSblnkori[lzd]<BEND) {
            printf "%d %d () split_ruler\n", CHOSblnkori[lzd], CHOSblnkend[lzd];
            } # if
          } # for CHOSblnk
        } # if CHOSFLAG
		printf "b_end %%%%%%%% Closing BLOCK\n";
		BORI+=BOFFSET;
	  } # for blocks
      # PostSCript Page Trailer.
	  endPSpage(pages);
	} # if B>0
	else { # if B==0
	  BEND=BORI+NOFFSET;
      # Converting to PostScript all plot elements.
	  printf "%%\n%% Block Num: - Page: %s.%s\n%%\n",pages,Vpages;
	  printf "%s %s 1 vblock\n", BORI, BEND;
      PrintWRN(sprintf("\n*  Page: %sH.%sV\nNuc_Ori: %s - Nuc_End: %s\n",pages,Vpages,BORI,BEND));
	  #
	  PRINTTRACKS(); # VP=(BSize/Tsize)
      # Closing Pages MAIN LOOP.
	  printf "vb_end\n";
	  endPSpage(pages,Vpages);
	} # else B==0
    PORI+=POFFSET;
  } # for pages
} # End of function MAIN_PAGE_LOOP # MAIN LOOP: End
#
function PlotElement(kokoinc,fso,    shwpst,KEKE,mycece,ftcolor,tmpstr) {
  shwpst=TxtBool(OnOff(Default["show_positions"]) || OnOff(PLOT_FT[feature_,":","show_feature_positions"]) || OnOff(PLOT_FT[ng_,":","show_group_positions"]) || OnOff(PLOT_FT[sc,":","show_source_positions"]));
  start_=element[PE,start];
  end_=element[PE,end];
##
  if (rscaled_gp==1) { end_=start_ + Default["minimum_single_length"] };
##
  # PrintRPT(sprintf("Element %s : %s : %s - %s\n",el,sel,start_,end_));
  # PrintRPT(sprintf("Positions for %s: Start %s - BORI %s : End %s - BEND %s\n",el,start_,BORI,end_,BEND));
  KEKE=ChkLimits(start_,BORI,end_,BEND);
#   if (!gpx[ng_,expand]) { KEKE=ChkLimits(start_,BORI,end_,BEND); mycece=0 }
#   else {
#     mycece=(gpx[ng_,xpnd_delta]*gpx[ng_,xpnd_zoom]);
#     KOKO=ChkLimits(min(sg_,(sg_ + mycoco - ((eg_ - sg_) * gpx[ng_,xpnd_zoom]))),BORI,max(eg_,(eg_ + mycoco + ((eg_ - sg_) * gpx[ng_,xpnd_zoom]))),BEND);
#     KEKE=ChkLimits(min(start_,(sg_ + mycece - ((eg_ - sg_) * gpx[ng_,xpnd_zoom]))),BORI,max(end_,(eg_ + mycece + ((eg_ - sg_) * gpx[ng_,xpnd_zoom]))),BEND);
#     # KEKE=ChkLimits((start_ - mycoco),BORI,(end_ - mycoco),BEND) || ChkLimits((start_ + mycoco),BORI,(end_ + mycoco),BEND);
#   };
  if (KEKE || gpx[ng_,expand]) {
    elem_sc=element[PE,score];
    # PrintRPT(sprintf("Scores for %s: score %s (Min:%s - Max:%s)\n",el,elem_sc,lower_sc,upper_sc));
    if (sco_lm) score_=1; else score_=GetScore(elem_sc,lower_sc,upper_sc);
    # for gene mode. try to recompute relative frame and remainder
    if (element[PE,frame]!=".") {
      frame_=element[PE,frame];
      remainder_=(3-(end_-(start_+frame_)+1)%3)%3;
      frcfrm=1 }
    else { frame_="(.)"; remainder_="(.)"; frcfrm=0 }
    if (PLOT_FT[feature_,":","label"]=="++none++") flflg="false";
    else flflg="true";
    ftcolor=Set_feat_Clr(feature_,ng_,sc,0,frcfrm);
    if (gpx[ng_,expand]) {
      if (gpx[ng_,xpnd_level]>0) {
        if (feature_ ~ "^transcript") PLOT_FT[feature_,":","layer"]--;
        if (feature_ !~ "^transcript") ftcolor="fgcolor 1";
      };
    };
    printf "%s %d %d %s %s %4.2f (%s) (%s) %s %s %s (%s) p\n", PLOT_FT[feature_,":","layer"], start_, end_, frame_ , remainder_, score_, ftcolor, Set_feat_Shape(feature_,ng_,sc), VertPos(3,sc,ng_,feature_), shwpst, flflg, Plot_Lbl(feature_) | fso;
  } # if element checklimits
} # End of function PlotElement
#
function PlotVector(    lnct,step_,window_,scmin_,scmax_,start_,end_,WK,w,pos_,cmmnd,cmmnt,vct_there) {
  start_=element[PE,start];
  end_=element[PE,end];
  step_=element[PE,v_step];
  window_=element[PE,v_window];
  if (step_=="NONE") step_=1;
  if (PLOT_FT[sc,":","range"]=="default") {
	scmin_=element[PE,v_scmin];
	scmax_=element[PE,v_scmax];
    }
  else { scmin_=lower_sc; scmax_=upper_sc }
  PrintRPT(sprintf("     Vector : %s : %s - %s : Window %s Step %s : Min %s Max %s\n",feature_,start_,end_,window_,step_,scmin_,scmax_));
  gsub(/[ \t]+$/,"",element[PE,v_DATA]);
  WK=split(element[PE,v_DATA],V_ary,/[ \t]+/);
  lnct=0;
  if (WK>0) {
    if (window_!="NONE") {
      #
      #   # score vectors
      #
      cmmnt=tolower(PLOT_FT[feature_,":","vector_shape"]);
      cmmnd=shpVT[cmmnt];
      if (cmmnd!~/vt|vtc/) cmmnd="vt";
	  pos_=start_+((window_/2));
      vct_there=0;
      for (w=1;w<=WK;w++) {
        if (pos_>=BORI && pos_<=BEND) { # pos_ is always taken as mid_position.
          if (vct_there==0) {
            vct_there=1;
            if (cmmnd=="vt") {
	          printf "%s %s %s (%s) %s %s vt\n", BORI, BEND, start_, Set_feat_Clr(feature_,ng_,sc,1), window_, step_;
            } else if (cmmnd=="vtc") {
	          printf "%s %s %s (%s) %s %s vtc\n", BORI, BEND, start_, PLOT_FT[feature_,":","feature_color"], window_, step_;
            };
          };
          lnct++;
          if (lnct>1) printf " ";
          if (V_ary[w]!="-") {
            if (sco_lm) score_=1; else score_=GetScore(V_ary[w],scmin_,scmax_);
            printf "%5.3f", score_;
            }
          else printf "n"; # inorder to save memory, we reduce the empty spaces
		} # if frame is on page
        if (lnct==20 || (lnct>0 && w==WK)) { printf "\n"; lnct=0 }
        pos_=pos_+step_;
	  } # for fixed steps...
	} # if step_ for fixed values.
      #
      #   # position-score vectors
      #
    else {
      #
      #   # segment-score vectors
      #
      vct_there=0;
      for (w=1;w<=(WK-1);w+=2) {
        pos_=V_ary[w];
        if (pos_>=BORI && pos_<=BEND) { # pos_ is always taken as mid_position.
          if (vct_there==0) {
            vct_there=1;
            printf "%s %s (%s) vp\n", start_, end_, Set_feat_Clr(feature_,ng_,sc,1);
          };
          lnct++;
          if (sco_lm) score_=1; else score_=GetScore(V_ary[w+1],scmin_,scmax_);
          printf "%5.3f %s ", score_, pos_;
		} # if frame is on page
        if (lnct==10 || w==WK-1) { printf "\n"; lnct=0 }
	  }  # for position score pairs...
      #
      #   # string vector
      #
	} # if step_ for position score pairs.
    if (vct_there==1) printf "(stop)\n";
  } # if WK>0    
} # End of function PlotVector
#
function PRINT_ELEMENTS(    KOKO,lbl,lbltmp,K_k,glsvr) {
  for (gl=1;gl<=LE[SSS,i,l];gl++) {
	g=LNelem[SSS,i,l,gl];
	ng_=gp[SSS,g,gpname];
	if (OnOff(PLOT_FT[ng_,":","show_group"])) {
      rscaled_gp=0;
	  sg_=gp[SSS,g,gpstart];
	  eg_=gp[SSS,g,gpend];
##
# length hack
K_k=eg_ - sg_;
if ((N[SSS,ng_]==1 && Default["minimum_single_length"]>0) && (K_k<Default["minimum_single_length"])) {
  eg_=sg_ + Default["minimum_single_length"];
  rscaled_gp=1;
  };
##
      KOKO=ChkLimits(sg_,BORI,eg_,BEND);
      if (!gpx[ng_,expand]) { mycoco=0; xpco=0; }
      else {
         mycoco=(gpx[ng_,xpnd_delta]*gpx[ng_,xpnd_zoom]);
         xpco=gpx[ng_,expand];
      };
#       if (!gpx[ng_,expand]) { KOKO=ChkLimits(sg_,BORI,eg_,BEND);
#                               mycoco=0; xpco=0; }
#       else {
#          mycoco=(gpx[ng_,xpnd_delta]*gpx[ng_,xpnd_zoom]);
#          # FWD : (END or XEND)>BORI, (ORI or XORI)<BEND
#          # RVS :  
#          KOKO=ChkLimits(min(sg_,(sg_ + mycoco - ((eg_ - sg_) * gpx[ng_,xpnd_zoom]))),BORI,max(eg_,(eg_ + mycoco + ((eg_ - sg_) * gpx[ng_,xpnd_zoom]))),BEND);
#          xpco=gpx[ng_,expand];
#       };
	  if (KOKO) {
        # plot group in file
        shwgrpst=TxtBool(OnOff(Default["show_positions"]) || OnOff(PLOT_FT[ng_,":","show_group_positions"]) || OnOff(PLOT_FT[sc,":","show_source_positions"]));
        if (PLOT_FT[ng_,":","label"]=="++none++") glflg="false";
        else glflg="true";
#
        if (PLOT_FT[ng_,":","group_label_scale"]=="default" || PLOT_FT[ng_,":","group_label_scale"] !~ /[0-9]*[.]?[0-9]*/) {
           glsvr=Default["group_label_scale"]; }
        else { glsvr=PLOT_FT[ng_,":","group_label_scale"]; };
        if (!gpx[ng_,expand]) {
           if (expand_ct>0) glflg="false"; # CELERA's HACK
	   printf "%s %s (%s) (%s) %s (%s) %s %s (%s) %s gp\n", sg_, eg_, Set_group_Clr(ng_,sc), Set_group_Shape(ng_,sc), VertPos(2,sc,ng_), Set_Line(ng_,"gp_"), shwgrpst, glflg, Plot_Lbl(ng_,sq,sc,s),glsvr; }
        else {
          # maybe someday include a charlength cutoff for labels...
          # if (length(gp[sq,sc,s,gp_cnt[ng_],gplabel])<=7) {
          lbl=Plot_Lbl(ng_,sq,sc,s);
          glflg="true";
          # } else { glflg="false" }; # lbl=""; 
          ncl=gpx[ng_,xpnd_frame];
          if (ncl==0) 
             ncl=Default["frame0_color"]; # darkgreen
          else if (ncl==1)
             ncl=Default["frame1_color"]; # skyblue
          else if (ncl==2)
             ncl=Default["frame2_color"]; # darkred
          else # ncl==2
             ncl=Default["frame_unknown_color"]; # black
          zm=gpx[ng_,xpnd_zoom];
          dt=gpx[ng_,xpnd_delta];
          lv=gpx[ng_,xpnd_level];
#		  printf "%s %s (%s 1) (%s) %s (%s) %s %s (%s) %s %s xp\n", sg_, eg_, PLOT_FT[ng_,":","group_color"], Set_group_Shape(ng_,sc), VertPos(2,sc,ng_), Set_Line(ng_,"gp_"), shwgrpst, glflg, Plot_Lbl(ng_,sq,sc,s), gpx[ng_,xpnd_zoom], gpx[ng_,xpnd_delta]; }; ## tolower(PLOT_FT[ng_,":","group_color"]) Set_group_Shape(ng_,sc)
#		  print sg_ " " eg_ " (" Set_Color("1_color",ncl) ") (" ncl " box) " VertPos(2,sc,ng_) " (" Set_Line(ng_,"gp_") ") " shwgrpst " " glflg " (" lbl ") " zm " " dt " xp";
           printf "%s %s (%s) (%s box) %s (%s) %s %s (%s) %s %s %s %s xp\n", sg_, eg_, Set_Color("1_color",ncl), ncl, VertPos(2,sc,ng_), Set_Line(ng_,"gp_"), shwgrpst, glflg, lbl, glsvr, zm, dt, lv;
        }; # else print expand group
#
#        fsort = (s=="-") ? "sort -bn +0 -1 +1 -2 +2r -3 +5r -6" : "sort -bn +0 -1 +2 -3 +1 -2 +5 -6";
        fsort = "sort +0bn +1bn +2bnr -3 +5bnr -6";
		for (el=1;el<=N[SSS,ng_];el++) {
		  sel=S[SSS,ng_,el];
		  PE=sq SUBSEP sc SUBSEP s SUBSEP ng_ SUBSEP sel;
		  feature_=element[PE,feature];
		  IS_VECT=element[PE,vector];
		  if (OnOff(PLOT_FT[feature_,":","show_feature"])) {
			if (!IS_VECT) PlotElement(mycoco,fsort);
			else { # if vector
			  PlotVector() } # if vector
		  } # if show feature
		} # for elements in group
        if (!IS_VECT) close(fsort);            
		printf "gx\n";
	  } # if group checklimits
	} # if show group
  } # for LE
} # End of function PRINT_ELEMENTS
#
function PRINTblockBG(    do_prt,blckSTR,myolof,olofstr,rlabel,cmmnd) { # do_brk,
  # do_brk=0;
  for (stp=1;stp<=3;stp++) { # for s in strand
      # if (do_brk) break;
      do_prt=0;
      sbg=wstr[stp];
	  if (s~/[+-]/) lastcnt=ordcnt;
	  else lastcnt=nordcnt; 
	  for (srcord=0;srcord<lastcnt;srcord++) { # for sc in sources
 		if (sbg=="-") { ngcnt=(lastcnt-1)-srcord; split(order["strand",ngcnt],SQC,SUBSEP) }
		else {
		  if (sbg=="+") split(order["strand",srcord],SQC,SUBSEP);
		  else split(order["none",srcord],SQC,SUBSEP);      # (s==".")
        }
		sq=SQC[1];
		sc=SQC[2];
		SSS=sq SUBSEP sc SUBSEP sbg;
   if (!OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"])) ungp=grouped_;
   else ungp=ungrouped_; 
   for (pd=grouped_;pd>=ungp;pd--) {
    if (s=="-" && OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"])) i=!pd; else i=pd;
    if (s!=".") m_lines=max(lines[sq,sc,"+",i],lines[sq,sc,"-",i]);
    else m_lines=lines[sq,sc,".",i];
	for (pl=1;pl<=m_lines;pl++) {
	 if (s=="-") l=m_lines-pl+1; else l=pl;
		if (OnOff(PLOT_FT[sc,":","fit_block_height"])) {
		  blckSTR = "%%%%%%%% BGFEAT\nbackft \n";
          for (gl=1;gl<=LE[SSS,i,l];gl++) {
            ngbg=gp[SSS,LNelem[SSS,i,l,gl],gpname];
	      ##  if (ChkLimits(sg_,BORI,eg_,BEND)) {
            for (el=1;el<=N[SSS,ngbg];el++) {
		      PE=sq SUBSEP sc SUBSEP sbg SUBSEP ngbg SUBSEP S[SSS,ngbg,el];
		      featurebg=element[PE,feature];
 	          if (OnOff(PLOT_FT[featurebg,":","show_feature"])) {
                startbg=element[PE,start];
                endbg=element[PE,end];
                if (ChkLimits(startbg,BORI,endbg,BEND)) {
#	  PrintRPT(">>>>>L>>>>" sq "<<>>" sc "<<>>" gl "<<<<<<\n");
                    myolof = Set_feat_Clr(featurebg,ngbg,sc,0,frcfrm);
                    rlabel = Plot_Lbl(ngbg,sq,sc,sbg);
                    cmmnd = shpnm[PLOT_FT[featurebg,":","shape"]];
                    if (cmmnd!~/bg[bw]|o[ri]m/) cmmnd="bgb";
                    olofstr = sprintf("%d %d (%s) (%s) %s\n", startbg, endbg, myolof, rlabel, cmmnd);
                    blckSTR = blckSTR "" olofstr;
                    do_prt = 1;
                } # checklimits
              } # if show feature
            } # for elements
           ##  } # checklimits
          } # for groups
          if (do_prt) { 
            PrintRPT(sprintf("   * Sequence: %-25s Source: %-25s Strand: %s *** Printing background features...\n", sq, sc, s));
            printf blckSTR "gx %%%%%%%% Closing BGFEAT\n";
          }; # do_[rt
          # do_brk=1;
	    } # fit_block_height
  } # for pl 
} # for pd
	} # for scord in sources
  } # for s in strands
} # PRINTblockBG
function PRINTSOURCES() { # print groups PlotSeqComp-like.
  notyet=1;
  for (stp=1;stp<=3;stp++) { # for s in strand
    s=wstr[stp];
    printf "%%%%%%%% STRAND %s\n(%s) Strand\n", s, s;
	if ((s=="+" && OnOff(Default["strand_show_forward"])) || (s=="." && OnOff(Default["strand_show_independent"])) || (s=="-" && OnOff(Default["strand_show_reverse"]))) {
	  if (s~/[+-]/) lastcnt=ordcnt;
	  else lastcnt=nordcnt; 
	  for (srcord=0;srcord<lastcnt;srcord++) { # for sc in sources
		if (s=="-") { ngcnt=(lastcnt-1)-srcord; split(order["strand",ngcnt],SQC,SUBSEP) }
		else {
		  if (s=="+") split(order["strand",srcord],SQC,SUBSEP);
		  else split(order["none",srcord],SQC,SUBSEP);      # (s==".")
        }
		sq=SQC[1];
		sc=SQC[2];
		SSS=sq SUBSEP sc SUBSEP s;
if (!OnOff(PLOT_FT[sc,":","fit_block_height"])) {
		PrintRPT(sprintf("   * Sequence: %-25s Source: %-25s Strand: %s\n", sq, sc, s));
		if (!OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"])) ungp=grouped_;
		else ungp=ungrouped_; 
		for (pd=grouped_;pd>=ungp;pd--) {
		  if (s=="-" && OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"])) i=!pd; else i=pd;
		  if (s!=".") m_lines=max(lines[sq,sc,"+",i],lines[sq,sc,"-",i]);
		  else m_lines=lines[sq,sc,".",i];
		  for (pl=1;pl<=m_lines;pl++) {
			if (s=="-") l=m_lines-pl+1; else l=pl;
			if (DoUnFoldMixed(sc) || (!OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"]) && !OnOff(PLOT_FT[sc,":","unfold_grouped_line"]) && !OnOff(PLOT_FT[sc,":","unfold_ungrouped_line"]))) fl_gp="M";
			else { if (i) fl_gp="G"; else fl_gp="U" }
			sco_lm=ScoreLimits();
            if (PLOT_FT[sc,":","source_style"]=="boxed") shscbx="true";
            else shscbx="false";
            if (!OnOff(PLOT_FT[sc,":","show_left_label"])) lftflb="false"; else lftflb="true";
            if (!OnOff(PLOT_FT[sc,":","show_right_label"])) rgtflb="false"; else rgtflb="true";
            if (PLOT_FT[sc,":","left_label"]=="++none++") lftflb="false";
            if (PLOT_FT[sc,":","right_label"]=="++none++") rgtflb="false";
            if (tolower(PLOT_FT[sc,":","source_label_vert_align"])~/default|center|top|bottom/) 
              sr_v_al=shplv[PLOT_FT[sc,":","source_label_vert_align"]];
            else sr_v_al=shplv["default"];
            printf "%%%%%%%% SOURCE %s\n",sc;
			printf "%s %s %s %s %s (%s) (%s) %s %s %s %s %s source\n", VertPos(1,sc), PLOT_FT[sc,":","track_scale"], PLOT_FT[sc,":","track_spacing_scale"],shscbx,TxtBool(OnOff(PLOT_FT[sc,":","keep_feature_label_space"])),s,Set_Line(sc,"sc_"),lftflb,rgtflb,Source_Lbl(sq,sc,s,fl_gp),PLOT_FT[sc,":","source_label_scale"],sr_v_al;  # (lines[sq,sc,s,grouped_]+lines[sq,sc,s,ungrouped_])
			#
			# Plotting all elements for that source
			PRINT_ELEMENTS();
			#
			printf "s_end  %%%%%%%% Closing SOURCE %s\n",sc;
          }   # for lines
        } # for grpd
} # !fit_block_height
      }   # for scord(source_ordering)
	}    # if strand_show
    # printf "%%%%%%%% END of STRAND %s\n",s;
  }     # for strands(stp)
} # End of function PRINTSOURCES
#
function ChangePage(ttt,ooo) {
  if (ttt>=Tsize) {
	printf "vb_end\n";
	endPSpage(pages,Vpages);
	Vpages++;
	startPSpage(pages,P,Vpages,VP);
	printf "%%\n%% Block Num: - Page: %s.%s\n%%\n",pages,Vpages;
	printf "%s %s 1 vblock\n", BORI, BEND;
    PrintWRN(sprintf("*  Page: %sH.%sV\nNuc_Ori: %s - Nuc_End: %s\n",pages,Vpages,BORI,BEND));
	return ooo;
  } # if up>Tsize
  else return ttt;
} # End of function ChangePage
#
function PRINTTRACKS(    up_,tmpup,dflt_up) {
  up_=0; # 4*Sw+crdt;
  laststrand="+"; notyet=1;
  for (stp=1;stp<=3;stp++) { # for s in strand
    s=wstr[stp];
    printf "(%s) Strand %% ------------------ Strand(%s) Begin\n", s, s;
	if ((s=="+" && OnOff(Default["strand_show_forward"])) || (s=="." && OnOff(Default["strand_show_independent"])) || (s=="-" && OnOff(Default["strand_show_reverse"]))) {
	  if (s=="+" || s=="-") lastcnt=ordcnt;
	  else lastcnt=nordcnt;
 	  if (laststrand=="." && NStSize>0) {
        dflt_up=VSw;
        tmpup=up_+dflt_up;
		up_=ChangePage(tmpup,dflt_up);
	  } # if changestrand
	  for (srcord=0;srcord<lastcnt;srcord++) { # for sc in sources
		if (s=="-") { ngcnt=(lastcnt-1)-srcord; split(order["strand",ngcnt],SQC,SUBSEP) }
		else {
		  if (s=="+") split(order["strand",srcord],SQC,SUBSEP);
		  else split(order["none",srcord],SQC,SUBSEP);      # (s==".")
        }
		sq=SQC[1];
		sc=SQC[2];
		SSS=sq SUBSEP sc SUBSEP s;
		PrintRPT(sprintf("   * Sequence: %-25s Source: %-25s Strand: %s\n", sq, sc, s));
		if (!OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"])) ungp=grouped_;
		else ungp=ungrouped_; 
		for (pd=grouped_;pd>=ungp;pd--) {
		  if (s=="-" && OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"])) i=!pd; else i=pd;
		  if (s!=".") m_lines=max(lines[sq,sc,"+",i],lines[sq,sc,"-",i]);
		  else m_lines=lines[sq,sc,".",i];
		  for (pl=1;pl<=m_lines;pl++) {
			#
			# Computing if next line fits on current page
            dflt_up=(aS*PLOT_FT[sc,":","track_scale"])+(bS*PLOT_FT[sc,":","track_spacing_scale"]);
            tmpup=up_+dflt_up;
			up_=ChangePage(tmpup,dflt_up);
            #
			if (s=="-") l=m_lines-pl+1; else l=pl;
			if (DoUnFoldMixed(sc) || (!OnOff(PLOT_FT[sc,":","unfold_grouped_ungrouped"]) && !OnOff(PLOT_FT[sc,":","unfold_grouped_line"]) && !OnOff(PLOT_FT[sc,":","unfold_ungrouped_line"]))) fl_gp="M";
			else { if (i) fl_gp="G"; else fl_gp="U" }
			sco_lm=ScoreLimits();
			if (PLOT_FT[sc,":","source_style"]=="boxed") shscbx="true"; 
			else shscbx="false";
            if (!OnOff(PLOT_FT[sc,":","show_left_label"])) lftflb="false"; else lftflb="true";
            if (!OnOff(PLOT_FT[sc,":","show_right_label"])) rgtflb="false"; else rgtflb="true";
            if (PLOT_FT[sc,":","left_label"]=="++none++") lftflb="false";
            if (PLOT_FT[sc,":","right_label"]=="++none++") rgtflb="false";
			printf "%s %s %s %s %s (%s) (%s) %s %s %s %s source\n", VertPos(1,sc), PLOT_FT[sc,":","track_scale"], PLOT_FT[sc,":","track_spacing_scale"],shscbx,TxtBool(OnOff(PLOT_FT[sc,":","keep_feature_label_space"])),s,Set_Line(sc,"sc_"),lftflb,rgtflb,Source_Lbl(sq,sc,s,fl_gp),PLOT_FT[sc,":","source_label_scale"];  # (lines[sq,sc,s,grouped_]+lines[sq,sc,s,ungrouped_])
			#
			# Plotting all elements for that source
			PRINT_ELEMENTS();
			#
			# Closing source
			printf "s_end  %%%%%%%% Closing SOURCE %s\n",sc;
		  } # for pl(m_lines)
		} # for pd
	  } # for scord
	} # if show_strand
	if (laststrand=="+" && StrSizeFwd>0 && notyet ) { 
	  notyet=0;
      dflt_up=VSw;
      tmpup=up_+dflt_up;
	  up_=ChangePage(tmpup,dflt_up);
	} # if changestrand
	laststrand=s;
	printf "%% ------------------------------ Strand(%s) End\n",s;
  } # for stp
} # End of function PRINTTRACKS
#
function CREATECUSTOM() {
  if (Var["create_default_customfile"]) { 
    PrintWRN(sprintf("\n%s\n*  Custom File:\n*  %s\n\n%s\n\n", BigLINE,BigLINE, Var["customfile_name_default"]));
    if (Var["exist_default_customfile"]) {
      PrintWRN(sprintf("Warning: I am going to rewrite your Default Custom File.\n"));
	  PrintWRN(sprintf("         Moving last Default Custom File to %s.old.%s\n",Var["customfile_name_default"],PID));
      system("cp "Var["customfile_name_default"]" "Var["customfile_name_default"]".old."PID);
	}
    else {
      PrintWRN(sprintf("Warning: Writing Default Custom File %s.\n",Var["customfile_name_default"]));
	}
    CreateProps(2);
  } # if create
  else {
	NTC="%s\n* Warning: Defaults were taken from program defaults,\n";
	NTC=NTC"*          but current variable definitions are not saved.\n";
	NTC=NTC"*          If you want to force program to write default file,\n";
	NTC=NTC"*          you must pass the command-line option -d to the program.\n";
	NTC=NTC"*          Default custom-file name: %s\n*\n";
	NTC=NTC"*          ...See help for -d and -D <filename> options...\n*\n";
    PrintWRN(sprintf(NTC,BigLINE,Var["customfile_name_default"]));
  } # else !created
  # Object Properties Report...
  CreateProps(1);
} # End of function CREATECUSTOM
#
function CreateProps(flag,    STRING,prop,dffeat,feat,gpfeat,sofeat) {
  ############ Create Properties Index for Objects ############ 
  STRING="#\n# L ######PAGE LAYOUT \& PROGRAM OPTIONS######\n#\n";
  if (flag==0) {
    PrintWRN(sprintf("%s\n*  Default Values to Variables\n*  for ALL GFF-Elements Read from INPUT:\n*\n",BigLINE));
    }
  if (flag==1) { 
    PrintWRN(sprintf("%s\n*  Variables Defined for Default Custom File:\n*  \"%s\"\n*\n",BigLINE,Var["customfile_name_default"]));
    # for (dffeat in Default)
    #   printf "%s=%s\n", dffeat, Default[dffeat] | "sort 1>&2";
    # close("sort 1>&2");
  }
  else if (flag==2) {
    PrintWRN(sprintf("%s\n*  Writting Default Custom File: %s\n*\n",Var["customfile_name_default"],BigLINE));
	CF_HEAD=       "########################################\n";
	CF_HEAD=CF_HEAD"##   DEFAULT CUSTOM FILE FOR GFF2PS   ##\n";
	CF_HEAD=CF_HEAD"########################################\n";
	CF_HEAD=CF_HEAD"##\n## User Name: %s\n##   Created: %s at %s\n##\n";
	printf CF_HEAD,usr,date,time > Var["customfile_name_default"];
    printf STRING > Var["customfile_name_default"];
    for (dffeat in Default)
      printf "%s=%s\n", dffeat, Default[dffeat] > Var["customfile_name_default"];
  }
  STRING="#\n# F ############GENOMIC FEATURES############\n#\n";
  PrintWRN(STRING);
  if (flag==2) {
    printf STRING > Var["customfile_name_default"];
  }
  for (feat in FT_ary) {
    for (prop in FT_PROP) {
      if (flag==0) PLOT_FT[feat,":",prop]=FT_PROP[prop];
      else {
        if (PLOT_FT[feat,":",prop]=="") PLOT_FT[feat,":",prop]=FT_PROP[prop];
        # if (flag==1)
	    #   printf "%s::%s=%s\n", feat, prop, PLOT_FT[feat,":",prop] | "sort 1>&2";
        # else
        if (flag==2)
	      printf "%s::%s=%s\n", feat, prop, PLOT_FT[feat,":",prop] > Var["customfile_name_default"];
	  }
	}
    if (flag==1) {
      # close("sort 1>&2");
      PrintRPT(sprintf("# %s::%s=%s\n", feat, "feature_counter", FT_ary[feat]));
	}
  }
  STRING="#\n# G ############GROUP FEATURES##############\n#\n";
  PrintWRN("*\n* ........................................................ DONE\n"STRING);
  if (flag==2) {
    printf STRING > Var["customfile_name_default"];
  }
  for (gpfeat in GP_ary) {
    for (prop in GR_PROP) {
      if (flag==0) PLOT_FT[gpfeat,":",prop]=GR_PROP[prop];
      else {
        if (PLOT_FT[gpfeat,":",prop]=="") PLOT_FT[gpfeat,":",prop]=GR_PROP[prop];
        # if (flag==1)
	    #   printf "%s::%s=%s\n", gpfeat, prop, PLOT_FT[gpfeat,":",prop] | "sort 1>&2";
        # else
        if (flag==2)
	      printf "%s::%s=%s\n", gpfeat, prop, PLOT_FT[gpfeat,":",prop] > Var["customfile_name_default"];
	  }
	}
    if (flag==1) {
      # close("sort 1>&2");
      PrintRPT(sprintf("# %s::%s=%s\n#\n", gpfeat, "group_elements_counter", GP_ary[gpfeat]));
	}
  }
  STRING="#\n# S ############SOURCE FEATURES#############\n#\n";
  PrintWRN("*\n* ........................................................ DONE\n"STRING);
  if (flag==2) {
    printf STRING > Var["customfile_name_default"];
  }
  for (sofeat in sources) {
    for (prop in SO_PROP) {
      if (flag==0) PLOT_FT[sofeat,":",prop]=SO_PROP[prop];
      else {
        if (PLOT_FT[sofeat,":",prop]=="") PLOT_FT[sofeat,":",prop]=SO_PROP[prop];
        # if (flag==1)
	    #   printf "%s::%s=%s\n", sofeat, prop, PLOT_FT[sofeat,":",prop] | "sort 1>&2";
        # else
        if (flag==2)
	      printf "%s::%s=%s\n", sofeat, prop, PLOT_FT[sofeat,":",prop] > Var["customfile_name_default"];
	  }
	}
    if (flag==1) {
      # close("sort 1>&2");
      PrintRPT(sprintf("# %s::%s=%s\n#\n", sofeat, "source_groups_counter", sources[sofeat]));
	}
  }
  if (flag==2) close(Var["customfile_name_default"]);
  PrintWRN(sprintf("*\n* ........................................................ DONE\n*\n%s\n",BigLINE));
} # End of CreateProps
#
function chkGlobal(feat,gffirst,re,np,    go_on) {
  ChkCharRG(feat);
  if (!re) ChkCharRG(gffirst);
  # else gffirst="/"gffirst"/"
  if (np) { if (match(feat,gffirst)) go_on=0; else go_on=1 }
  else {
	if (re) { if (match(feat,gffirst)) go_on=1; else go_on=0 }
	else { 
	  if (feat==gffirst) go_on=1;
	  else go_on=0;
	} # else !exp_reg
  } # else !neg_ptrn
  return go_on;
} # End of function chkGlobal
# 
function RCFile(file,    MATCH_T,MATCH_F,nothere,first,gffirst,second,ft_type,feat,lytdef,dft,exp_reg,neg_ptrn,df_,eq_,type_sel) { # Read CustomFile
  # PrintRPT(sprintf("\n%s\n*  Reading Custom File:\n%s\n\n*  %s\n*\n", BigLINE,BigLINE,file));
  MATCH_T="*** %s *** Feature %s - Match between: %s & %s : %s=%s\n";
  MATCH_F="********* Feature %s - No Match found : %s=%s\n";
  type_sel=0;
  while ((getline < file) > 0 ) {
	if ( $0~/^[^\#]/ && $0!~/^( )*$/ && type_sel ) { 
	  # PrintRPT("\n>>> "ft_type" <<< "$0"\n");
      gsub(/[ \t]+([\#].*)?$/,"",$0)
      # PrintRPT("*** Removing Comments ***["$0"]***\n");
	  nothere=global=exp_reg=neg_ptrn=0;
	  df_="!=";eq_="==";
	  if (ft_type!="L") {
		split($0,defs,"::");
		first=defs[1];
		split(defs[2],nwfeat,"=");
	  }
	  else {
		split($0,nwfeat,"=");
		first=nwfeat[1];
	  }
	  if (first~/^\*$/) first="\/.*\/";
	  if (first~/^(\!)?\//) exp_reg=1; else exp_reg=0;
	  if (exp_reg) { 
		if (first~/^\!/) {
		  neg_ptrn=1; df_="=="; eq_="!=";
		}
		else neg_ptrn=0;
        #gsub(/^!/,"",first);
		gsub(/^(!)?\//,"",first);
		gsub(/\/$/,"",first);
	  }
	  else neg_ptrn=0;
	  second=nwfeat[1];
      PrintRPT("***:"$0":***:"first":***:"second":***:"nwfeat[2]":***REGEXP:"exp_reg"\n");
	  if (ft_type=="F") { # F
		gffirst=tolower(first);
		if (second in FT_PROP) {
		 for (feat in FT_ary) { 
		  go_on=chkGlobal(feat,gffirst,exp_reg,neg_ptrn);
		  if (go_on) {
			PLOT_FT[feat,":",second]=nwfeat[2];
			PrintRPT(" +++ "ft_type" +++ Match found: "feat" "eq_" "gffirst" +++ <"nwfeat[2]">\n");
		  } # if go_on
		  # else PrintRPT(" +++ "go_on" +++ No Match found: "feat" "df_" "gffirst" \n");
		 }
		 if (!exp_reg && !(gffirst in FT_ary)) {
		  for (pro_ in FT_PROP) {
			PLOT_FT[gffirst,":",pro_]=FT_PROP[pro_];
			# PrintRPT("********* PLOT_FT["gffirst":"pro_"]="PLOT_FT[gffirst,":",pro_]"\n");
		  }
		  FT_ary[gffirst]++;
		  PLOT_FT[gffirst,":",second]=nwfeat[2];
		  # PrintRPT(sprintf(MATCH_F,gffirst,(gffirst":"second),nwfeat[2]));
		 } # if !go_on
        } # if varname exist
	    else PrintWRN(sprintf("*** VAR NAME NOT DEFINED on FEATURE SECTION *** "MATCH_F,first,second,nwfeat[2]));
      } # if type="F"
	  else { 
		if (ft_type=="G") { # G
		  gffirst=first;
		  if (second in GR_PROP) {
		   for (feat in GP_ary) { 
			go_on=chkGlobal(feat,gffirst,exp_reg,neg_ptrn);
			if (go_on) {
			  PLOT_FT[feat,":",second]=nwfeat[2];
			  PrintRPT(" +++ "ft_type" +++ Match found: "feat" "eq_" "gffirst" +++ <"nwfeat[2]">\n");
			} # if go_on
			# else PrintRPT(" +++ "go_on" +++ No Match found: "feat" "df_" "gffirst" \n");
		   }
		   if (!exp_reg && !(gffirst in GP_ary)) {
			for (pro_ in GP_PROP) {
			  PLOT_FT[gffirst,":",pro_]=GP_PROP[pro_];
			  # PrintRPT("********* PLOT_FT["gffirst":"pro_"]="PLOT_FT[gffirst,":",pro_]"\n");
			}
			GP_ary[gffirst]++;
			PLOT_FT[gffirst,":",second]=nwfeat[2];
			# PrintRPT(sprintf(MATCH_F,gffirst,(gffirst":"second),nwfeat[2]));
		   } # if !go_on
          } # if varname exist
		  else PrintWRN(sprintf("*** VAR NAME NOT DEFINED on GROUP SECTION *** "MATCH_F,first,second,nwfeat[2]));
		} # if type="G"
		else { 
		  if (ft_type=="S") { # S
			gffirst=first;
			if (second in SO_PROP) {
			 for (feat in sources) { 
			  go_on=chkGlobal(feat,gffirst,exp_reg,neg_ptrn);
			  if (go_on) {
				PLOT_FT[feat,":",second]=nwfeat[2];
				PrintRPT(" +++ "ft_type" +++ Match found: "feat" "eq_" "gffirst" +++ <"nwfeat[2]">\n");
			  } # if go_on
			  # else PrintRPT(" +++ "go_on" +++ No Match found: "feat" "df_" "gffirst" \n");
			 }
			 if (!exp_reg && !(gffirst in sources)) {
			  for (pro_ in SO_PROP) {
				PLOT_FT[gffirst,":",pro_]=SO_PROP[pro_];
				# PrintRPT("********* PLOT_FT["gffirst":"pro_"]="PLOT_FT[gffirst,":",pro_]"\n");
			  }
			  sources[gffirst]++;
			  PLOT_FT[gffirst,":",second]=nwfeat[2];
			  # PrintRPT(sprintf(MATCH_F,gffirst,(gffirst":"second),nwfeat[2]));
			 } # if !go_on
            } # if varname exist
			else PrintWRN(sprintf("*** VAR NAME NOT DEFINED on SOURCE SECTION *** "MATCH_F,first,second,nwfeat[2]));
		  } # if type="S"
		  else { # L
			if (ft_type=="L") {
			  if (first in Default) {
				PLOT_LY[first]=nwfeat[2];
				PrintRPT(sprintf(" +++ %s +++ Match found: %s & %s : <%s>\n",ft_type,first,first,nwfeat[2]));
				# PrintRPT(sprintf(MATCH_T,ft_type,first,first,first,first,nwfeat[2]));
			  }
			  else PrintWRN(sprintf("*** VAR NAME NOT DEFINED on LAYOUT SECTION *** "MATCH_F,first,first,nwfeat[2]));
			} # if type="L"
		  } # else ! "S"
		} # else ! "G"
	  } # else ! "F"
	} # if not empty or comment line
	else {  
	  if ( $0~/^(\# )[LFGS]( \#)/ ) { 
        # PrintRPT("*B*******"$0"\n");
		type_sel=1;
		split($0,cfo," ");
		ft_type=cfo[2];
		# PrintRPT("\n>>> "ft_type" <<< "$0"\n")
        }
	  else {
		if ( $0~/^[^\#]/ && $0!~/^( )*$/ && !type_sel )
		  PrintWRN("*** BLOCK TYPE NOT DEFINED *** <"$0">\n");
		# else
		#   PrintRPT("\n************\n* NOT READ * "$0"\n************\n");
	  }
	} # else change ft_type
  } # while getline
  close(file);
  PrintWRN(sprintf("*\n* ........................................................ DONE\n*\n%s\n",BigLINE));
} # End of RCFile
#
########################################
######## Secondary Functions ###########
#
function PrintRPT(STRNG) { if (Var["print_report"]) printf STRNG | "cat 1>&2" }
function PrintWRN(STRNG) { if (Var["quiet_mode"]) printf STRNG | "cat 1>&2" }
#
## function lcase(string,    chr) { for (chr in CM) gsub(chr,CM[chr],string); return string }
function OnOff(v) { if (tolower(v)~/^1$|^on$|^y(es)?$|^t(rue)?$/) return 1; else return 0 }
function TxtBool(n) { if (n) return "true"; else return "false" }
#
function min(a,b) { if (a!~/([+-]?[0-9]*[.]?[0-9]*(e[+-]?[0-9]+)?)/) a=1; if (b!~/([+-]?[0-9]*[.]?[0-9]*(e[+-]?[0-9]+)?)/) b=1; if(a<=b) return a; else return b }
function max(a,b) { if (a!~/([+-]?[0-9]*[.]?[0-9]*(e[+-]?[0-9]+)?)/) a=1; if (b!~/([+-]?[0-9]*[.]?[0-9]*(e[+-]?[0-9]+)?)/) b=1; if(a>=b) return a; else return b }
function ChkLimits(o,O,e,E) { if (e<=O || o>=E) return 0; else return 1 } # start_,BORI,end_,BEND
function ChkLimitsXPND(o,xo,O,e,xe,E) { if (e<=O || o>=E) return 0; else return 1 } # start_,BORI,end_,BEND
#
function DoUnFoldMixed(SC) {
  if (!OnOff(PLOT_FT[SC,":","unfold_grouped_ungrouped"])&&((OnOff(PLOT_FT[SC,":","unfold_grouped_line"]) || OnOff(PLOT_FT[SC,":","unfold_ungrouped_line"]))))
	return 1; 
  else return 0 } # end of DoUnFoldMixed
#
function ChkColor(ncolor) {
  # { PrintRPT(sprintf(" +++ Checking COLOR_NAMES: %s :: %s\n",ncolor,TxtBool(tolower(ncolor)~Valid_Colors))); return 1; } 
  if (tolower(ncolor)~Valid_Colors) return 1; 
  else return 0 } # also when ncolor == ^BG$|(##DEFAULT##)
#
function checklbl(chain) {
  if (chain=="") return ""; 
  else {
	gsub(/[\\]/,"\\134",chain); gsub(/[\(]/,"\\050",chain); gsub(/[\)]/,"\\051",chain);
    return chain }
} # End of function checklbl
#
function chktmk(tk,    t) {
  t=tolower(tk);
  if (t~/both|top|bottom|none/) return t;
  else return "both";
}
#
function ChkCharIF(chain) { # Avoiding problems with config file variable names for elements.
  if (chain=="") return ""; 
  else { gsub(/[%]/,"%%",chain); return chain }
} # End of function ChkCharIF
#
function ChkCharRG(chain) { # Avoiding problems with config file variable names for elements.
  if (chain=="") return ""; 
  else { # gsub(/[ \t]/,"",chain);
   gsub(/[\\]/,"\\\\",chain); gsub(/[\(]/,"\\(",chain); gsub(/[\)]/,"\\)",chain);
    gsub(/[\[]/,"\\[",chain); gsub(/[\]]/,"\\]",chain); gsub(/[\|]/,"\\|",chain);
    gsub(/[\{]/,"\\{",chain); gsub(/[\}]/,"\\}",chain); gsub(/[\/]/,"\\/",chain);
    gsub(/[\^]/,"\\^",chain); gsub(/[\$]/,"\\$",chain); gsub(/[\.]/,"\\.",chain);
    gsub(/[\?]/,"\\?",chain); gsub(/[\+]/,"\\+",chain); gsub(/[\*]/,"\\*",chain);
    return chain }
} # End of function ChkCharRG
#
function chkpo(v) { if (tolower(v)=="portrait") return "false"; else return "true" }
function cktxpo(v) { if (tolower(v)=="portrait") return "Portrait"; else return "Landscape" }
function chkps(v) {
  if (v~/^(a|b)([0-9]|10)$|^10x14$|^(executive|folio|(le)(tter|gal|dger)|quarto|statement|tabloid|userdefined)$/)
	return 1;
  else return 0;
} # End of function chkps
#
function chkun(st,    t,p) {
  t=tolower(st);
  if (gsub(/cm(s)?/,"",t)>0) { p=t" cm"; return p }
  else {
	if (gsub(/in(ch)?(s)?/,"",t)>0) { p=t" in"; return p }
	else {
	  if (gsub(/pt(s)?/,"",t)>0) return t;
	  else return "1 cm" }}
} # End of function chkun
#
function calcpt(st,    t,p) { # return points
  t=tolower(st);
  if (gsub(/cm(s)?/,"",t)>0) { p=t*28.35; return p }
  else {
	if (gsub(/in(ch)?(s)?/,"",t)>0) { p=t*72; return p }
	else {
	  if (gsub(/pt(s)?/,"",t)>0) return t;
	  else return 0 }}
} # End of function calcpt
#
function Nuc_round(nm,flg,    sign,nmp,i,mlt,smm,t) { # flg=0 then floor; flg=1 then ceiling.
  sign=nm<0?-1:1;
  if (sign==-1) { nm=-nm; flg=!(flg) }
  nmp=nm; for (i=1;nmp>10;i++) { nmp=nmp/10 };
  if (nm>=1000) mlt=2; else mlt=1;
  if (flg) {
	if (nm>0) {
	  if (nm%10^(i-mlt)==0) smm=0; else smm=1;
	  t=nm>=100?sign*((int(nmp*10^(mlt-1))+smm)*10^(i-mlt)):sign*100 }
	else t=0 }
  else { if (nm>0) t=nm>=100?sign*((int(nmp*10^(mlt-1)))*10^(i-mlt)):0; else t=0 }
  return t;
} # End of Nuc_round
#
function Nuc_Scale(st,    ts) {
  ts=tolower(st);
  if (ts~/^m(ega)?(b(ases)?)?/) return 3;
  else if (ts~/^k(ilo)?(b(ases)?)?/) return 2;
  else return 1; # (ts~/^b(ases)?|default/);
}
#
function showelemGS(sq,s,p,g,q,  string) {
  string=" : ";
  string=string" "element[sq,s,p,g,q,feature]" ";
  string=string" "element[sq,s,p,g,q,start]" ";
  string=string" "element[sq,s,p,g,q,end]" ";
  string=string" "element[sq,s,p,g,q,frame]" ";
  string=string" "element[sq,s,p,g,q,group];
  return string } # End of showelemS
#
function Plot_Lbl(gff_feat,    sq,sc,s,lbl,vn) {
  vn=PLOT_FT[gff_feat,":","label"];
  if (vn=="++default++" || vn=="++none++") { 
    lbl=gff_feat;
    if (gff_feat in GP_ary)  lbl=gp[sq,sc,s,gp_cnt[gff_feat],gplabel];
  } else lbl=vn;
  return checklbl(lbl);
} # End of function Plot_Lbl
#
function SRC_LBL(sl,sq,sc,s,flg    ,lbl) {
	if (sl=="++default++" || sl=="++none++") {  # is not wrong, when sorting by sequence, source label is source else seqname
	  if (OnOff(Default["sort_tracks_by_sequence"])) lbl=sc; else lbl=sq;
    }
	else
      if (sl=="++strand++") {
        if (s=="+") lbl="FWD"; 
        else 
          if (s=="-") lbl="REV"; 
          else lbl=" ";
        }
	else
      if (sl=="++sequence++") lbl=sq;
      else
        if (sl=="++source++") lbl=sc;
        else
          if (sl=="++both++" || sl=="++info++") {
            if (OnOff(Default["sort_tracks_by_sequence"])) lbl=sq" ("sc")";
            else lbl=sc" ("sq")";
            if (sl=="++info++") lbl=lbl" ["flg""s"]" }
          else lbl=sl;
  return checklbl(lbl);
}
#
function Source_Lbl(sq,sc,s,flg,    lftlbl,rgtlbl,tlb) {
  lftlbl=SRC_LBL(PLOT_FT[sc,":","left_label"],sq,sc,s,flg);
  rgtlbl=SRC_LBL(PLOT_FT[sc,":","right_label"],sq,sc,s,flg);
  tlb="("lftlbl") ("rgtlbl")";
  return tlb;
} # End of function Plot_Lbl
#
function Set_Color(sv,clst,fc,fv    ,clrmode,color1,color2,color3,clm,k,tmp) {
  clrmode=0; color2=""; color3=""; # "none" or not defined
  #PrintRPT(sprintf("*** FEATURE COLORS ::%s:: FILLSHAPE MODE ::%s::\n",clst,sv));
  if (clst=="default" || clst=="") { clm[1]="fgcolor"; k=1 }
  else {
    k=split(clst,clm,/\.\./);
    if (!ChkColor(clm[1])) clm[1]="bgcolor";
  }
  color1=clm[1];
  if (sv=="none") { clrmode=0; color1="" }
  else if (sv=="bgcolor") { clrmode=1; color1="bgcolor" }
  else if (sv=="fgcolor") { clrmode=1; color1="fgcolor" }
  else if (sv=="default" && !fv) { 
    if (fc) clrmode=5; # if frame is present in feature default shows frame-remainder fill shape.
    else clrmode=1; # else default fill-mode.
  }
  else if (sv=="default" && fv) { clrmode=4 }
  else if (sv=="1_color") { clrmode=1 }
  else if (sv=="2_color") {
	clrmode=2;
	if (k>1 && ChkColor(clm[2])) color2=clm[2];
    else color2="fgcolor";
  }
  else if (sv=="3_color" && fv ) {
	clrmode=3;
	if (color1=="bgcolor") color3="fgcolor";
	else if (color1=="fgcolor") color3="bgcolor";
	if (k>1 && ChkColor(clm[2])) color2=clm[2];
	else
	  if (color1=="bgcolor" || color1=="fgcolor") color2="grey";
	  else color2="bgcolor";
	if (k>2 && ChkColor(clm[3])) color3=clm[3];
  }
  else if (sv=="rainbow") { clrmode=4 }
  else if (sv=="frame-remainder") { clrmode=5 }
  if (color1!="") color1=color1" ";
  if (color2!="") color2=color2" ";
  if (color3!="") color3=color3" ";
  tmp=color1""color2""color3""clrmode;
  return tmp;
} # End of function Set_Color
#
function Set_feat_Clr(gff_feat,gp,sc,is_vector,fcf,    vn,stcl,a1,a2,a3) { # remaining to add vector definition colors.
  a1=PLOT_FT[gff_feat,":","feature_color"];
  a2=PLOT_FT[gp,":","feature_color"];
  a3=PLOT_FT[sc,":","feature_color"];
  if (a2!~/^(default|[ \t]*)$/) a1=a2;
  if (a3!~/^(default|[ \t]*)$/) a1=a3;
  if (ChkColor(a1)) stcl=a1;
  else stcl="fgcolor";    
  if (is_vector) vn=PLOT_FT[gff_feat,":","fill_vector_mode"];
  else vn=PLOT_FT[gff_feat,":","fill_shape_mode"];
  return Set_Color(tolower(vn),tolower(stcl),fcf,is_vector);
} # End of function Set_feat_Clr
#
function Set_feat_Shape(gff_feat,grp,src    ,shp,tmp,vn,cl,a1,a2,a3) {
  a1=PLOT_FT[gff_feat,":","feature_stroke_color"];
  a2=PLOT_FT[grp,":","feature_stroke_color"];
  a3=PLOT_FT[src,":","feature_stroke_color"];
  if (a2!~/^(default|[ \t]*)$/) a1=a2;
  if (a3!~/^(default|[ \t]*)$/) a1=a3;
  if (ChkColor(a1)) cl=a1;
  else cl="fgcolor";
  vn=PLOT_FT[gff_feat,":","shape"];
  if (vn in shpnm) shp=shpnm[vn];
  else shp=shpnm["none"];  # (vn==" vector, spike, block ")
  tmp=tolower(cl)" "shp; return tmp;
} # End of function Set_feat_Shape
#
function Set_group_Clr(grp,src,    vn,stcl,a1,a2) {
  a1=PLOT_FT[grp,":","group_color"];
  a2=PLOT_FT[src,":","group_color"];
  if (a2!~/^(default|[ \t]*)$/) a1=a2;
  if (ChkColor(a1)) stcl=a1;
  else stcl="fgcolor";    
  vn=PLOT_FT[grp,":","fill_shape_mode"];
  if (vn~/default/) vn="1_color";
  return Set_Color(tolower(vn),tolower(stcl),0,0);
} # End of function Set_group_Clr
#
function Set_group_Shape(grp,src,    shp,ln,tmp,vn,clg,a1,a2) {
  a1=PLOT_FT[grp,":","group_stroke_color"];
  a2=PLOT_FT[src,":","group_stroke_color"];
  if (a2!~/^(default|[ \t]*)$/) a1=a2;
  if (ChkColor(a1)) clg=a1;
  else clg="fgcolor";
  vn=PLOT_FT[grp,":","group_shape"];
  if (vn in shpnm) shp=shpnm[vn];
  else shp=shpnm["none"];
  tmp=tolower(clg)" "shp; return tmp;
} # End of function Set_group_Shape
#
function Set_Line(nm,ext,    vn,cl,ln,fl,c,tmp) {
  if (ext=="gp_") {
	cl=PLOT_FT[nm,":","group_line_color"];
	vn=PLOT_FT[nm,":","group_line"];
    fl=gp[sq,sc,s,gp_cnt[nm],is_grouped];
	if ((vn in lnnm) && fl) ln=lnnm[vn];
	else ln=lnnm["none"];
  }
  else {
	cl=PLOT_FT[nm,":","source_line_color"];
	vn=PLOT_FT[nm,":","source_line"];
	if (vn~/none|default|(long_|short_)?dashed|(long_)?dotted|(dotted_)?line/) ln=lnnm[vn];
	else ln=lnnm["none"];
  }
  if (ChkColor(cl)) c=cl;
  else {
	if (cl=="default" || cl=="fgcolor") c="fgcolor";
	else c="bgcolor" }
  tmp=tolower(c)" "ext""ln; return tmp;
} # End of function Set_Line
#
function ChkVT(tt) {
  if (tt in shpal) return tt;
  else return "default";
} # End of function ChkVT
#
function VertPos(lv,Vsc,Vgp,Vfg,   ps1,ps2,ps3) { 
  ps1="default"; ps2="default"; ps3="default";
  if (lv>=1) {
    ps1=ChkVT(tolower(PLOT_FT[Vsc,":","vert_align"]));
    #PrintRPT(sprintf("*******>>> Vertical ALIGN  SC(%s) GP(%s) FT(%s)\n",ps1,ps2,ps3))
  }
  if (lv>=2) {
    ps2=ChkVT(tolower(PLOT_FT[Vgp,":","vert_align"]));
    if (ps2~/default|center|mirror/ && ps1~/default/) ps1=ps2;
    #PrintRPT(sprintf("*******>>> Vertical ALIGN  SC(%s) GP(%s) FT(%s)\n",ps1,ps2,ps3))
  }
  if (lv>=3) {
    ps3=ChkVT(tolower(PLOT_FT[Vfg,":","vert_align"]));
    if (ps3~/default|center|mirror/ && ps2~/default/ && ps1~/default/) ps1=ps3;
    #PrintRPT(sprintf("*******>>> Vertical ALIGN  SC(%s) GP(%s) FT(%s)\n",ps1,ps2,ps3))
  }
    #PrintRPT(sprintf("*******>>> Vertical ALIGN  SC(%s) GP(%s) FT(%s) ---> %s\n",ps1,ps2,ps3,shpal[ps1]))
  return shpal[ps1];
} # End of function VertPos
#
function ScoreLimits(    no_score,tt,scmt) {
  if (PLOT_FT[sc,":","range"]=="none") no_score=1;
  else {
    no_score=0;
    if (PLOT_FT[sc,":","range"]=="default") {
      lower_sc=sc_score["MIN",sc];
      upper_sc=sc_score["MAX",sc] }
    else {
      split(PLOT_FT[sc,":","range"],scmt,/\.\./);
      if (scmt[1]=="*") scmt[1]=sc_score["MIN",sc];
      if (scmt[2]=="*") scmt[2]=sc_score["MAX",sc];
      if (scmt[1]>scmt[2]) { tt=scmt[1]; scmt[1]=scmt[2]; scmt[2]=tt }
      lower_sc=scmt[1];
      upper_sc=scmt[2] }}
  return no_score;
} # End of function ScoreLimits
#
function GetScore(sco,lwr,upr,   tmp) {
  if (sco<lwr) { sco=lwr }
  else if (sco>upr) { sco=upr };
  a=upr-lwr;
  if (a<1e-15) a=IS_VECT?MINV_SCO:MINSCORE;
  if (sco!~/^\.$/) {
	if (IS_VECT) tmp=(((MAXV_SCO-MINV_SCO)/a)*(sco-lwr))+MINV_SCO;
	else tmp=(((MAXSCORE-MINSCORE)/a)*(sco-lwr))+MINSCORE;
	return tmp;
  }
  else return 1;
} # End of function GetScore
#
#############################################
######## PostScript Code DEFINITION #########
#
function PSheader() { 
  PrintWRN("*  Writting PostScript Header.\n");
  # Printing PostScript Header...
  printf "%%\!PS-Adobe-3.0\n";
  printf "%%%%Title: %s\n", title;
  printf "%%%%Creator: %s\n", Var["PROGRAM"];
  printf "%%%%Version: %s\n", Var["VERSION"];
  printf "%%%%CreationDate: %s\n", date" "time;
  printf "%%%%For: %s\n", usr;
  printf "%%%%Pages: %s\n", "(atend)";
  printf "%%%%Orientation: Portrait\n";
  printf "%%%%BoundingBox: 0 0 %s %s\n", PsizeX[bbpgsz], PsizeY[bbpgsz];
  printf "%%%%EndComments\n%%\n";
  printf "%%    Author : %s\n", Var["AUTHOR"];
  printf "%%    e-mail :        %s\n%%\n", Var["EMAIL"];
  printf "%% ------------------------------------------------------------------------\n";
  printf "%%                     %s\n", Var["PSPROGRAM"];
  printf "%% ------------------------------------------------------------------------\n";
  # Writing PostScript Header...
  system("cat "Var["PS_Header_FN"]);
  close("cat "Var["PS_Header_FN"]);
  # Generating Page-sizes table...
  printf "%%  Paper Sizes  (in points)\n";
  printf "/pagedict %s dict def pagedict begin %% %s+2 sizes defined\n", NumPGSZ, NumPGSZ-2;
  for (pasize in PsizeX) 
    printf "/pg%-12s { %4s %4s } def\n", pasize, PsizeX[pasize], PsizeY[pasize] | "sort" ;
  close("sort");
  # printf "/pg%-12s { %4s %4s } def\n", bbpgsz, bbx, bby;
  printf "end %% pagedict\n%%%%EndProcSet:   Constants 1.0 0\n";
} # End of function PSheader
#
function defPSvars(    flgst,subtitle,shbx,fixed,dfgc,dbgc) {
  PrintWRN("*  Writting PostScript Variables.\n");
  printf "%% BG \& FG colors\n";
  dbgc=tolower(Default["background_color"]); if (!ChkColor(dbgc)) dbgc="bg";
  if (dbgc~/(bg|background)(color)?/) dbgc=Var["BG_COLOR"];
  printf "/BGcolor { colordict begin %s end } def /bgcolor { BGcolor } bdf\n", dbgc;
  dfgc=tolower(Default["foreground_color"]); if (!ChkColor(dfgc)) dfgc="fg";
  if (dfgc~/(fg|foreground)(color)?/) dfgc=Var["FG_COLOR"];
  printf "/FGcolor { colordict begin %s end } def /fgcolor { FGcolor } bdf\n", dfgc;
  printf "/frmN { colordict begin %s end } def\n", Default["frame_unknown_color"];
  printf "/frm0 { colordict begin %s end } def\n", Default["frame0_color"];
  printf "/frm1 { colordict begin %s end } def\n", Default["frame1_color"];
  printf "/frm2 { colordict begin %s end } def\n", Default["frame2_color"];
  printf "/Blblcol { colordict begin %s end } def\n", Default["block_label_fill_color"];
  printf "%% page orientation flag\n";
  printf "/flglscape %s def\n", chkpo(Default["page_orientation"]);
  printf "%% page size in points used for plot % pgA4 == 595  842\n";
  printf "/pglimflg %s def\n",TxtBool(OnOff(Default["show_page_limits"]));
  printf "/Dpage { pagedict begin pg%s flglscape { exch } if end } bdf\n", bbpgsz;
  printf "%% margins (1 cm) (Up Down Left Right - margins are XY independent)\n";
  printf "/UpM %s def\n", chkun(Default["margin_upper"]);
  printf "/DnM %s def\n", chkun(Default["margin_lower"]);
  printf "/LtM %s def\n", chkun(Default["margin_left"]);
  printf "/RtM %s def\n%%\n", chkun(Default["margin_right"]);
  printf "/TkMrkW %s def %% Defining tickmark-width.\n/TkMrkHW TkMrkW 2 div def\n", chkun(Default["default_scale_width"]);
  printf "/TkMspc %s def\n", Default["default_scale_spacing_width"];
  printf "/BlckSp %s def %% Defining blocks-spacing\n%%\n", chkun(Default["default_block_spacing_width"]);
  printf "/SeqLen %s def\n", PDIF; 
  printf "/XNucOffSet %s def\n", PORI; 
  printf "/NPages %s def\n", P; 
  printf "/NBlck %s def\n", B; 
  printf "/MaxNuclPage %s def\n", NOFFSET;
  printf "/MSLen %s def\n", Default["minimum_single_length"];
  printf "/MINshwLBLlen %s def \% minimum gene length to show gene label on expands\n", Default["show_label_min_gene_length"];
  if (Default["block_style"]=="boxed") shbx="true"; 
  else shbx="false";
  printf "/FlgBkBx %s def\n", shbx;
  printf "/FlgOSU %s def\n",TxtBool(OnOff(FlgSwOSUp));
  printf "/FlgOSD %s def\n",TxtBool(OnOff(FlgSwOSDn));
  printf "/FlgISU %s def\n",TxtBool(OnOff(FlgSwISUp));
  printf "/FlgISD %s def\n",TxtBool(OnOff(FlgSwISDn));
  my_nuc=Nuc_Scale(Default["nucleotide_scale"]);
  my_mjtk=Default["major_tickmarks_nucleotides"];
##
  my_exp=0;
  if ((my_nuc == 3) && (my_mjtk % 1000000 != 0)) my_exp=1
  else if ((my_nuc == 2) && (my_mjtk % 1000 != 0)) my_exp=1;
##
  printf "/TS %s def\n", my_nuc;
  printf "/TrS %s def\n", my_exp;
  printf "/FlgGrd %s def\n",TxtBool(OnOff(Default["show_grid"]));
  printf "/MaxTick %s def\n", my_mjtk;
  printf "/MinTick %s def\n%%\n", Default["minor_tickmarks_nucleotides"];
  printf "/tracksize %s def\n", chkun(Default["default_track_width"]);
  printf "/spcrsize  %s def\n", chkun(Default["default_track_spacing_width"]);
  printf "/LnTot  %s def\n", BSize;    # size in points (size is relative here)
  printf "/LnFwd %s def\n", StrSizeFwd; # if they are 0 then not showed
  printf "/LnRvs %s def\n", StrSizeRvs;
  printf "/LnBth %s def\n", NStSize;
  printf "/blklblsc %s def\n", Default["block_label_scale"];
  printf "/vectoffset 10 def\n%%\n";
  printf "/XLftLbl %s def\n", chkun(Default["left_source_label_width"]);
  printf "/FLftLbl %s def\n", TxtBool(OnOff(Default["show_left_source_label"])); #
  printf "/XRgtLbl %s def\n", chkun(Default["right_source_label_width"]);
  printf "/FRgtLbl %s def\n%%\n", TxtBool(OnOff(Default["show_right_source_label"])); #
  printf "/XOriTitl 0 cm def\n";
  printf "/YOriTitl 0 cm def\n";
  printf "/YSTitl %s def\n", chkun(HDRheight);
  printf "/Titlscl %s def\n", Default["header_scale"];
  printf "/flgcrd %s def %% credits flag\n", TxtBool(OnOff(Var["Show_Credits"]));
  printf "/FlgTitl %s def\n", shtt;
  printf "/headerdict 25 dict def headerdict begin\n";
  printf " /ShwTBx %s def\n", shbt;
  printf " /ShwTt %s def\n", flgt;
  printf " /Title (%s) def\n", checklbl(title);
  if (Default["subtitle"]=="none" || Default["subtitle"]=="default") { flgst="false"; subtitle="" }
  else { flgst="true"; subtitle=Default["subtitle"] }
  printf " /ShwST %s def\n", flgst;
  printf " /SubTitle (%s) def\n", checklbl(subtitle);
  printf " /ShwDate %s def\n", TxtBool(OnOff(Default["show_date"]));
  printf " /Sdate (%s) def\n", checklbl(date);
  printf " /ShwTime %s def\n", TxtBool(OnOff(Default["show_time"]));
  printf " /Stime (%s) def\n", checklbl(time);
  printf " /Shwp_num %s def\n", TxtBool(OnOff(Default["show_page_numbers"]));
  printf "end %% headerdict \n";
  # printf "/gplbSC %s def\n", Default["group_label_scale"];
  printf "/pslbSC %s def\n", Default["position_label_scale"];
  printf "/sclbSC 1 def\n%%\n";
  #
  if (CHOffSet[0]>0) lstCHos = CHOffSet[1]
  else lstCHos = 0;
  printf "/CHcurrent %d def\n", lstCHos;
  if (CHOffSet[0]>1) lstCHos = CHOffSet[2]
  else lstCHos = P * B * NOFFSET;
  printf "/CHnext %d def\n", lstCHos; # 12000000
  printf "/CHoffsets [ "; # 26000000 36000000 56000000 501000000
  for (z=3;z<=CHOffSet[0];z++) { printf "%d ", CHOffSet[z]; };
#  printf "%d ] def\n%%\n", lstCHos ;
  if (CHOffSet[0]==2) {
    if (Default["major_tickmarks_nucleotides"]==-1) lstCHos = (P * B * NOFFSET) + 1000
    else lstCHos = (P * B * NOFFSET) + Default["major_tickmarks_nucleotides"];
    printf "%d ", lstCHos;
    };
  printf " ] def\n%%\n";
  #
  # PostScript Main Procs.
  PrintWRN("*  Writting PostScript Prolog.\n");
  system("cat "Var["PS_Main_FN"]);
  close("cat "Var["PS_Main_FN"]);
} # End of function defPSvars
#
function startPSpage(num,tot,vpg,vtot) {
  # PrintWRN("*  Opening PostScript Page.\n");
  if (B>0) printf "%%%%Page: %s %s\n",num,num;
  else printf "%%%%Page: %s.%s %s\n",num,vpg,++BPC;
  printf "%%%%BeginPageSetup\n%%\n";
  printf "%% Saving current page settings\n";
  printf "/pgsave save def\n";
  printf "%% Setting BGcolor for sheet \n";
  printf "Dpage flglscape { exch } if 0 0 bbox S bgcolor scmyk fill R pglimflg { S shortdashed K R } if clip newpath\n";
  printf "%% Only for testing pagelimits\n% S XORI YORI T pglim flglscape { exch } if 0 0 bbox FGcolor scmyk longdashed K R\n";
  printf "%% setting coordinate axes for page orientation\n";
  printf "flglscape\n";
  printf " { XORI YORI T 90 rotate 1 -1 F }                  %% (0,0) - Ori for landscape pages\n";
  printf " { XORI Dpage exch pop YORI sub T 1 -1 F } ifelse  %% (0,0) - Ori for portrait pages\n";
  printf "%% Printing Header\n";
  printf "headerdict begin\n";
  if (B>0) printf " /PageNumber (Page %s of %s) def\n",num,tot;
  else printf " /PageNumber (Page %s.%s of %s.%s) def\n",num,vpg,tot,vtot;
  printf " FlgTitl { Header } if\n";
  printf "end\n";
  printf "%%%%EndPageSetup\n";
  printf "%%\n";
} # End of function startPSpage
#
function endPSpage(p,vp) {
  # PrintWRN("*  Closing PostScript Page.\n");
  printf "%%%%%%%% SHOWPAGE\nflgcrd { headerdict begin s_credits end } if\ngrestoreall\npgsave restore\n";
  printf "%%%%%%LEGEND%%%%%%\nshowpage\n";
  if (B>0) printf "%%\n%% PageEND: %s %s\n%%\n",p,p;
  else printf "%%\n%% PageEND: %s.%s %s\n%%\n",p,vp,BPC;
} # End of function endPSpage
#
function PSTrailer() {
  PrintWRN(sprintf("*  Closing PostScript File.\n\n%s\n\n",BigLINE));
  printf "%%%%Trailer\n%%\n";
  if (B>0) printf "%%%%Pages: %s\n", P;
  else printf "%%%%Pages: %s\n", BPC;
  printf "%%%%Orientation: Portrait\n";
  printf "%%%%BoundingBox: 0 0 %s %s\n", PsizeX[bbpgsz], PsizeY[bbpgsz];
  printf "%%%%EOF\n";
} # End of function PSTrailer
@@@EndPROGRAM@@@
#
# End of MAIN gff2ps gawk-script

######################################################
####            MAIN GFF2PS PROGRAM               ####
# Processing gff files and converting to PostScript. #

    $GAWK -f $GWKPRG $GWKOPT $GFF_INPUT_FILES ;      #

#                                                    #
####     Main GFF2PS GNU awk Program :  DONE      ####
######################################################

#
# Removing all temporal files...
rm -f $GWKPRG $GWKOPT $PSHEAD $PSMAIN 2>/dev/null;

#
# Timing gff2ps...
# TT_end=`date +%T`;
if [ $v34 -eq 1 ];
 then
perl -e '        $r = shift @ARGV; 
  $s = $r % 60;  $r = ($r - $s) / 60;
  $m = $r % 60;  $r = ($r - $m) / 60;
  $h = $r % 24;
  ($s,$m,$h) = (&fill_left($s,2,"0"),&fill_left($m,2,"0"),&fill_left($h,2,"0"));
print STDERR <<EOF;
**
********************************************
**  GFF2PS Execution Time:  $h:$m:$s
********************************************
EOF
sub fill_left { ($_[2] x ($_[1] - length($_[0]))).$_[0] }
' $SECONDS;
 fi;

#
##################### EOF #####################
exit 0
