%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  v 1.7
%  AlDraTex                                             %
%  Copyright (C) 1992 Eitan M. Gurari                   %
%                                                       %
% This program can redistributed and/or modified under  %
% the terms of the LaTeX Project Public License         %
% Distributed from CTAN archives in directory           %
% macros/latex/base/lppl.txt; either version 1 of the   %
% License, or (at your option) any later version.       %
%                                                       %
% However, you are allowed to modify this program       %
% without changing its name, if you modify its          %
% signature. Changes to the signature can be introduced %
% with a directive of the form                          %
%            \message{signature}                        %
%                                                       %
%                            gurari@cis.ohio-state.edu  %
%        http://http://www.cis.ohio-state.edu/~gurari/  %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\expandafter\edef\csname :RestoreCatcodes\endcsname{%
   \catcode`\noexpand\noexpand\noexpand \^=\the\catcode`\^%
}
\catcode`\^=7
\expandafter\edef\csname :RestoreCatcodes\endcsname{%
   \csname :RestoreCatcodes\endcsname
   \catcode`\noexpand \_=\the\catcode`\_%
   \catcode`\noexpand :=\the\catcode`:%
   \catcode`\noexpand &=\the\catcode`&%
   \catcode`\noexpand \#=\the\catcode`\#%
   \catcode`\noexpand \^^M=\the\catcode`\^^M%
   \let\expandafter\noexpand
       \csname:RestoreCatcodes\endcsname=\noexpand\undefined}
\catcode`\:=11
\ifx \AlDraTex\:undefined  \def\AlDraTex{chart,diagram} \fi

\newif\if:circle
\newif\if:option
\def\:CheckOption#1{ \def\:temp{#1}
   \:optionfalse
   \expandafter\:GetOptions\AlDraTex,,// }

\def\:GetOptions#1,#2//{  \def\:next{#1}
   \ifx        \:next\empty
   \else \ifx  \:temp\:next   \:optiontrue   \let\:next=\relax
   \else \def\:next{\:GetOptions#2//}
   \fi  \fi  \:next }
\def\:DefineExt#1{%
   \Define#1{\begingroup  \:DraCatCodes
             \csname .:\string#1\endcsname}%
  \expandafter\Define\csname .:\string#1\endcsname}
\IntVar\:C   \IntVar\:Ca
\IntVar\:Cb  \IntVar\:Cc  \newtoks\:tk
\DecVar\Va   \DecVar\Vb
\DecVar\:Vc   \DecVar\:Vd   \DecVar\:Ve

\Define\:GetX(2){\Va=#1;}
\Define\:GetY(2){\Vb=#2;}
\Define\:GetXY(2){\Va=#1;\Vb=#2;}\Define\:GetExit(2){
    \:Vc=#1;  \IF \LtDec(\:Vc,0)  \THEN  \:Vc=-\:Vc;  \FI
    \:Vd=#2;  \IF \LtDec(\:Vd,0)  \THEN  \:Vd=-\:Vd;  \FI
    \IF  \LtDec(\:Vd,\:Vc)  \THEN  \:Vd=\:Vc;  \FI
    \Va=#1;   \Vb=#2;
    \IF \GtDec(\:Vd,0)  \THEN  \Va/\:Vd;  \Vb/\:Vd;   \FI }
\Define\:GetEdgeFront(1){\def\:EdgeFront{#1}}
\Define\:Count(1){\:C+1;}\let\Defend=\noexpand
\def\KeepSpaces{\def\:Spaces{\catcode`\ =10 \relax}}
\def\RemoveSpaces{\let\:Spaces=\relax}
\RemoveSpaces\def\:edef#1#2{\edef\:Temp{\noexpand\Define
   \noexpand#1{#2}}\:Temp }
\:CheckOption{chart}\if:option
   \edef\AlDraTex{\AlDraTex,pie,bar,xy}
\else \:CheckOption{pie}\if:option
   \edef\AlDraTex{\AlDraTex,chart}
\else \:CheckOption{xy}\if:option
   \edef\AlDraTex{\AlDraTex,chart}
\else \:CheckOption{bar}\if:option
   \edef\AlDraTex{\AlDraTex,chart}
\fi\fi\fi\fi
\:CheckOption{chart}\if:option
   \def\Compute#1(#2){\def\NextDefine{\::Comp#1(#2)}\Define\:Comp(#2)}

\def\::Comp#1(#2){\Define\:Temp(#2){}\ifx \:Temp\:Comp
         \let\:Compute=\empty
   \else \Define\:Compute(1){\:Comp(##1)\:Return#1}\fi}

\Compute\I(1){}\Define\:ChooseColor(1){
\IF \EqDec(#1,1) \THEN  \SetBrush(0,0){}
\ELSE\IF \EqDec(#1,2) \THEN
   \SetBrush(2pt\du,1pt\du){  \PenSize(0.2pt)
        \Units(1pt,1pt)  \Move(0,-0.37)  \Line(0,0.75)}
\ELSE\IF \EqDec(#1,3) \THEN
   \SetBrush(1pt\du,2pt\du){  \PenSize(0.2pt)
        \Units(1pt,1pt)  \Move(-0.37,0)  \Line(0.75,0)}
\ELSE\IF \EqDec(#1,4) \THEN
   \SetBrush(2pt\du,2pt\du){  \PenSize(0.2pt)
        \Units(1pt,1pt){\Move(-1,0)\Line(2,0)}
               \Move(0,-1)\Line(0,2)}
\ELSE\IF \EqDec(#1,5) \THEN
   \SetBrush(5pt\du,2pt\du){  \PenSize(0.2pt)
        \Units(1pt,1pt)  \Move(0,-0.37)  \Line(0,0.75)}
\ELSE\IF \EqDec(#1,6) \THEN
   \SetBrush(2pt\du,5pt\du){  \PenSize(0.2pt)
        \Units(1pt,1pt)  \Move(-0.37,0)  \Line(0.75,0)}
\ELSE
   \SetBrush(#1pt\du,#1pt\du){
                \Units(1pt,1pt)\PaintRect(0.37,0.37)}
\FI\FI\FI\FI\FI\FI} 
\fi
\:CheckOption{pie}\if:option
   \Define\PieChart{\begingroup   \:Spaces  \:PieChart}

\Define\:PieChart(1){\endgroup
   \Table\:Temp{#1}
   \:Ve=0;  \:Temp(0,99){\:total}
   \MarkLoc(o:) \MoveF(\:PieR)  \MarkLoc(b:)
   \DSeg\:Vd(o:,b:) \MoveToLoc(o:)
   \:C=0;  \:Temp(0,99){\:InsertSlice} }  \Define\PieChartSpec(1){
   \IF  \EqText(,#1)  \THEN\ELSE   \:PieSpec(#1)
   \FI  \:PieCol}

\Define\:PieSpec(3){
   \:edef\:PieR{#2}      \:edef\:LblDist{#3}
   \IF  \EqInt(1,#1)  \THEN
      \def\:ReturnComp##1{\:slice(\Val##1,\Val##1)}
      \Define\:total(1){
         \ifx  \:Compute\empty          \:Ve+##1;
         \else \let\:Return=\:ReturnAdd \:Compute(##1)\fi}
      \Define\:InsertSlice(1){
         \ifx \:Compute\empty           \:slice(##1,##1)
         \else \let\:Return=\:ReturnComp\:Compute(##1) \fi}
   \ELSE
      \def\:ReturnComp##1{\edef\:tempa{\Val##1}}
      \Define\:total(2){
         \ifx  \:Compute\empty          \:Ve+##1;
         \else \let\:Return=\:ReturnAdd \:Compute(##1)\fi}
      \Define\:InsertSlice(2){
         \ifx \:Compute\empty           \:slice(##1,##2)
         \else \let\:Return=\:ReturnComp\:Compute(##1)
                                       \:slice(\:tempa,##2) \fi}
   \FI  }
\def\:ReturnAdd#1{\:Ve+#1;}\Define\:slice(2){  \:C+1;  \Va=#1;  \Va/\:Ve;
    \Va*360; {
       \Va/2;  \Rotate(\Val\Va)   \:DetachSlice
       \MarkLoc(o:)
       \MoveF(1pt\du)  \MarkLoc(x:)  \CSeg\:SetEnEx(x:,o:)
       \MoveToLoc(o:)  \MoveF(\:LblDist)  \:AdjChatLbl(0,99){\:MvLbl}
       \SliceText(--#2--)  \MoveToLoc(o:)
       \Vb=\:Vd; \Vb+\Va;  \Vb+\Va;
       \DrawOvalArc(\:PieR,\:PieR)(\Val\:Vd,\Val\Vb)
       \:Ca=0; \:PieColors(0,99){\:Ca+1;\:PaintPie}
   {\RotateTo(\Val\:Vd)  \LineF(\:PieR)}
       \RotateTo(\Val\Vb)  \LineF(\:PieR)
    }  \Rotate(\Val\Va)  \:Vd+\Va;  }

\Define\:SetEnEx(2){\:Vc=#1; \Vb=#2; \EntryExit(\Val\:Vc,\Val\Vb,0,0)}
\Define\DetachSlices(2){
   \IF  \EqInt(#2,0)  \THEN
      \Define\:DetachSlice{}
   \ELSE\IF  \EqText(,#1) \THEN
      \def\:DetachSlice{ \MoveF(#2) }
   \ELSE
      \Table\:DSlice{#1}
      \Define\:OptDSlice(1){
         \IF \EqInt(\:C,##1) \THEN
            \MoveF(#2)
         \FI}
      \Define\:DetachSlice{ \:DSlice(0,99){\:OptDSlice} }
   \FI  \FI } \Define\MovePieLabels(1){
   \IF  \EqText(,#1)  \THEN
      \Table\:AdjChatLbl{0,0,0}
   \ELSE     \Table\:AdjChatLbl{0,0,0&#1}  \FI}

\Define\:MvLbl(3){
   \IF \EqInt(\:C,#1)  \THEN  \Move(#2,#3)  \FI }
\:DefineExt\:PieCol(1){\endgroup
   \IF \EqText(,#1)  \THEN
   \ELSE                   \Table\:PieColors{#1} \FI}
\Define\:PaintPie(1){{
   \IF \EqInt(\:C,\:Ca) \THEN
      \IF \GtDec(#1,0) \THEN
         \:ChooseColor(#1)
          \:Ve=\:PieR;
          \IF \GtDec(\Va,90) \THEN
             \Va=\:Vd;  \Va+181;
             \PaintOvalArc(\Val\:Ve,\Val\:Ve)(\Val\:Vd,\Val\Va)
             \Va-1;  \:Vd=\Va;    \FI
          \PaintOvalArc(\Val\:Ve,\Val\:Ve)(\Val\:Vd,\Val\Vb)
          \RotateTo(\Val\Vb)  \MoveF(\:PieR)  \MarkLoc(a:)
\MoveToLoc(o:)  \RotateTo(\Val\:Vd)  \MoveF(\:PieR)
\MarkLoc(b:)    \PaintQuad(o:,o:,a:,b:) 
          \MoveF(-0.5pt\du)  \MarkLoc(b:) \MoveToLoc(o:)
\Rotate(1) \MoveF(\:PieR)  \MarkLoc(b':)
\MoveToLoc(o:) \RotateTo(\Val\Vb)  \MoveF(\:PieR)
\MoveF(-0.5pt\du)  \MarkLoc(a:) \MoveToLoc(o:)
\Rotate(-1) \MoveF(\:PieR) \MarkLoc(a':)
\PaintQuad(a:,a':,b':,b:)
   \FI \FI  }}\Define\Legend(1){   \AlignGrid(-1,\:LgEn)
   \PictNode(2){  \EntryExit(-1,\:LgEn,0,0)
      \DrawRect(\:LgSzX,\:LgSzY)
      \IF  \GtDec(##1,0)  \THEN
         \:ChooseColor(##1)
         \IF  \EqDec(##1,4)  \THEN
            \Move(0.05,0.05)  \:Vd=\:LgSzX;  \:Ve=\:LgSzY;
            \:Vd-0.1;  \:Ve-0.1;
            \PaintRect(\Val\:Vd,\Val\:Ve) \Move(-0.05,-0.05)
         \ELSE  \PaintRect(\:LgSzX,\:LgSzY)  \FI
      \FI
      \:Vd=\:LgSzX;  \:Vd+5;
      \:Ve=\:LgEn;  \:Ve+1;  \:Ve*\:LgSzY;  \:Ve/2;
      \Move(\Val\:Vd,\Val\:Ve)
 \Text(--\ignorespaces##2--)    }
    \GridDiagram(#1)()()}

\:DefineExt\LegendSpec(3){\endgroup
    \:edef\:LgSzX{#1}\:edef\:LgSzY{#2}\:edef\:LgEn{#3}}

\LegendSpec(10,10,0) 
\PieChartSpec(1,40,20)(0)
\TextPar\Define\SliceText(1){\Text(--#1--)}
\DetachSlices(,0) \MovePieLabels()

\fi
\:CheckOption{xy}\if:option
   \Define\Axis(2){     \MoveToLoc(#1)   \CSeg\:GetXY(#1,#2)
   \begingroup   \:Spaces  \:axis}

\Define\:axis(2){ \endgroup\:axs#1//{#2}}

\def\:axs#1#2//#3{\::axs(#1,#2,#3)}
\Define\::axs(3){ \SaveAll  \Units(1pt,1pt)
   \def\:tic{\:ticLn( \Val\:Vc,0)}
\IF       \EqText(W,#1)  \THEN
   \def\:MvTicTxt{\Move(-\:TxtPos,0)}
   \IF  \LtDec(\Va,0)  \THEN \Move(\Val\Va,0)    \:Vc=-\Va;
   \ELSE    \:Vc=\Va;   \FI
   \EntryExit(1,0,0,0)  \Va=0;
\ELSE\IF  \EqText(E,#1)  \THEN
   \IF  \GtDec(\Va,0)  \THEN
      \Move(\Val\Va,0)     \:Vc=-\Va;
   \ELSE     \:Vc=\Va;  \FI
   \def\:MvTicTxt{\Move(\:TxtPos,0)}
   \Va=0;   \EntryExit(-1,0,0,0)
\ELSE
   \def\:tic{\:ticLn(0, \Val\:Vc)}
   \IF  \EqText(N,#1)  \THEN
      \IF  \GtDec(\Vb,0)  \THEN
         \Move(0,\Val\Vb)       \:Vc=-\Vb;
      \ELSE        \:Vc=\Vb;  \FI
      \EntryExit(0,-1,0,0)
      \def\:MvTicTxt{\Move(0,\:TxtPos)}
   \ELSE     \EntryExit(0,1,0,0)
      \IF  \LtDec(\Vb,0)  \THEN
         \Move(0,\Val\Vb)    \:Vc=-\Vb;
      \ELSE    \:Vc=\Vb;       \FI
      \def\:MvTicTxt{\Move(0,-\:TxtPos)}
   \FI
   \Vb=0;
\FI\FI
   \:Ca=#2;   \IF \EqText(#2,-0) \THEN   \:Ca=-1; \FI
   \IF  \LtInt(\:Ca,0)  \THEN
      \:Ca=-#2;  { \Line(\Val\Va,\Val\Vb)
\MarkLoc(bk:)
\IF  \EqDec(\Va,0)  \THEN
    \IF  \GtDec(\Vb,0)  \THEN
        \ifx \:FrArrowHead\empty \else  \Line(0,5)  \fi
        \Vb=\:ArrowLength;
    \ELSE
        \ifx \:FrArrowHead\empty \else   \Line(0,-5) \fi
        \Vb=-\:ArrowLength; \FI
\ELSE
    \IF  \GtDec(\Va,0)  \THEN
        \ifx \:FrArrowHead\empty \else  \Line(5,0)  \fi
        \Va=\:ArrowLength;
    \ELSE
        \ifx \:FrArrowHead\empty \else  \Line(-5,0)  \fi
        \Va=-\:ArrowLength; \FI
\FI
\Move(\Val\Va,\Val\Vb)  \MarkLoc(fr:) \:FrArrowHead  }

   \FI
   \:C=\:Ca;  \:C/10;  \:C*10;  \:Ca-\:C;
   \IF  \GtInt(\:Ca,4)  \THEN   \:Ca-5; \let\:PutTics=\:TicsByLoc  \FI
   \IF \EqInt(\:Ca,4) \THEN
  \Define\:ticLn(2){\DoLine(##1,##2)(7pt\du){
     \Units(1pt,1pt) \MoveF(-4) \LineF(2) }}
  \:Ca-1;
\ELSE  \let\:ticLn=\Line  \FI
   \IF  \LtInt(\:Ca,3)  \THEN
   \IF  \GtDec(\:Vc,0)  \THEN \:Vc= \:TicLn;
   \ELSE                     \:Vc=-\:TicLn;
\FI\FI
\ifcase \Val\:Ca
       \:Vc=   0;   \def\:TxtPos{3}  % 0
   \or \:Vc=-\:Vc;   \:Vd=\:TicLn; \:Vd+3; \edef\:TxtPos{\Val\:Vd} % 1
\else              \def\:TxtPos{3} \fi
   \:Ca=\:C;  \:Ca/10;
   \Table\:Temp{#3}  \:C=-1;  \:Temp(0,99){\:Count}
   \IF  \GtInt(\:C,0) \THEN  \:PutTics \FI \RecallAll}
\Define\:PutTics{       \Va/\:C;   \Vb/\:C;
  { \:Temp(0,99){  {\PenSize(\:TicTh)\:tic} \:TicText }  }
    \IF  \GtInt(\:Ca,0)  \THEN
       \:C*\:Ca;  \Va/\:Ca;  \Vb/\:Ca;
       \IF  \GtDec(\:Vc,\:TicLn)  \THEN  \:Vc= \:TicLn;  \FI
       \IF  \LtDec(\:Vc,-\:TicLn) \THEN  \:Vc=-\:TicLn;  \FI
       \:Vc*\:TicFc;       { \let\:ticLn=\:Ln
       \Do(0,\Val\:C){  {\PenSize(\:TicTh)\:tic}
                          \Move(\Val\Va,\Val\Vb)  }}
     \FI}\Define\:TicsByLoc{ \MarkLoc(x:)
  \Define\:tempa(2){\MoveTo(0,##1) \MarkLoc(a:)
                    \MoveTo(0,##2) \MarkLoc(b:)
                    \LSeg\:Ve(a:,b:)}
  \:Temp(0,0){\:tempa }
  \Define\:tempa(2){ \MoveTo(0,##1) \MarkLoc(b:)
     \LSeg\:Vd(a:,b:)  \:Vd/\:Ve;
     { \Va*\:Vd;   \Vb*\:Vd;  \MoveToLoc(x:)
       \Move(\Val\Va,\Val\Vb)
       {\PenSize(\:TicTh)\:tic} \:TicText(##2) }}
  \:Temp(1,99){\:tempa  } }\Define\:TicText(1){          \MarkLoc(o:)
   \:MvTicTxt\TicText(--#1--) \MoveToLoc(o:)
   \Move(\Val\Va,\Val\Vb)}

\Define\TicSpec(3){
    \:edef\:TicLn{#1} \:edef\:TicFc{#2} \:edef\:TicTh{#3}}

\TicSpec(6,0.6,0.2 pt)

\TextPar\Define\TicText(1){ \IF \EqText(,#1) \THEN
                     \ELSE \Text(--\strut#1--) \FI}  
\fi
\:CheckOption{bar}\if:option
   \:DefineExt\BarChart(1){\endgroup
   \Table\:Chart{#1}  \MarkLoc(Origin)
   \XSaveUnits    \:Ca=0;  \Vb=0;  \:Vc=0;
\:Chart(0,999){\:Ca+1;\:MaxBar}
\ifx  \:Hchart\empty
   \:Ca*10;  \:Vc+\:BarGrdOver;
\ifx H\:BarDir
   \Move(\Val\:Vc,0)  \MarkLoc(NE)
   \Move(0,-\Val\:Ca) \MarkLoc(SE)
   \Vb-\:Vc;  \Move(\Val\Vb,0) \Move(-\:BarGrdUnder,0)
   \MarkLoc(SW)   \Move(0,\Val\:Ca)   \MarkLoc(NW)
   \edef\:BsLn{{\noexpand\Line(0,-10)}}
\else
   \Move(0,\Val\:Vc)  \MarkLoc(NW)
   \Move(\Val\:Ca,0) \MarkLoc(NE)
   \Vb-\:Vc;  \Move(0,\Val\Vb)
   \Move(0,-\:BarGrdUnder)    \MarkLoc(SE)
   \Move(-\Val\:Ca,0) \MarkLoc(SW)
   \edef\:BsLn{{\noexpand\Line(10,0)}}
\fi  \MoveToLoc(Origin) 
\else
   \Va=\:Vc; \:Vd=\:Vc;  \:Vd-\Vb;  \Va/\:Vd;
\ifx H\:BarDir
   \Va*\:Hchart;   \Move(\Val\Va,0)
   \Move(\:BarGrdOver,0)  \MarkLoc(NE)
   \Move(0,-\:Vchart) \MarkLoc(SE)
   \Move(-\:Hchart,0) \Move(-\:BarGrdOver,0)
       \Move(-\:BarGrdUnder,0) \MarkLoc(SW)
   \Move(0,\:Vchart) \MarkLoc(NW)
   \:Ca*10;  \edef\:BsLn{{\noexpand\Line(0,-10)}}
\else
   \Va*\:Vchart;   \Move(0,\Val\Va)
   \Move(0,\:BarGrdOver)  \MarkLoc(NW)
   \Move(\:Hchart,0) \MarkLoc(NE)
   \Move(0,-\:Vchart) \Move(0,-\:BarGrdOver)
       \Move(0,-\:BarGrdUnder) \MarkLoc(SE)
   \Move(-\:Hchart,0) \MarkLoc(SW)
   \:Ca*10;  \edef\:BsLn{{\noexpand\Line(10,0)}}
\fi  \MoveToLoc(Origin) 
   \Va=\:Hchart;   \Va/\:Ca;
   \:Vc-\Vb;  \:Vd=\:Vchart;  \:Vd/\:Vc;
   \:Hflip\Units(\Val\Va pt,\Val\:Vd pt)
   \:Vc+\Vb;
\fi   
   \def\:GrdLn{}
\ifx  \:BarGrdDist\empty   \def\:BsLn{}    \else
    \let\du=\relax
   \IF  \GtInt(\:BarGrdDist,0)  \THEN
      \:Vd=\:Vc;  \:Vd/\:BarGrdDist;  \:C[\:Vd];
      \IF \GtDec(\:C,\:Vd) \THEN \:C-1; \FI
      \IF \GtInt(\:C,0)  \THEN
         \edef\:GrdLn{{  { \noexpand\noexpand\noexpand\:BsLn }
   \PenSize(\:TicTh)
   \noexpand\noexpand\noexpand\Do(1,\Val\:C){
   \:Hflip{\noexpand\noexpand\noexpand\Move}(0,\:BarGrdDist)
   { \:HflipMY{\noexpand\noexpand\noexpand\Line}(10,0) }  }}}
\:GridLoc(Max)

      \FI
      \Vb+\:Vc;   \Vb-\:BarGrdUnder;
      \Vb/\:BarGrdDist;  \:C[\Vb];
      \IF \LtDec(\:C,\:Vd) \THEN \:C+1; \FI
      \IF \LtInt(\:C,0)  \THEN
             \edef\:GrdLn{
   \ifx\:AddBarDepth\:AddBarDp\:HflipMY{\noexpand\Move}(-\:HBarx,\:VBarx)
   \fi
    { \noexpand\:BsLn }
    \:GrdLn { \PenSize(\:TicTh)
        \noexpand\Do(-1,\Val\:C){
           \:Hflip{\noexpand\Move}(0,-\:BarGrdDist)
        { \:HflipMY{\noexpand\Line}(10,0) }  }}
}
\:GridLoc(Min)

      \ELSE  \edef\:GrdLn{{\ifx\:AddBarDepth\:AddBarDp
            \:HflipMY{\noexpand\Move}(-\:HBarx,\:VBarx)  \fi

            {\noexpand\:BsLn}   \:GrdLn}}
        \FI
      \MoveToLoc(Origin)
   \FI
   \let\du=\:SvDu
\fi 
   \Va=0;  \:Vc=0;
   \:Chart(0,99){
      \:Hflip\Move(0,\Val\:Vc) 
      \:NoBarClip()      \:DrawBars}
   \ifx\:AddBarDepth\:AddBarDp
   \MoveToLoc(Origin) \:HflipMY\Move(-\:HBarx,\:VBarx)  \MarkLoc(Origin)
   \MoveToLoc(NW) \:HflipMY\Move(-\:HBarx,\:VBarx)  \MarkLoc(NW)
   \MoveToLoc(NE) \:HflipMY\Move(-\:HBarx,\:VBarx)  \MarkLoc(NE)
   \MoveToLoc(SW) \:HflipMY\Move(-\:HBarx,\:VBarx)  \MarkLoc(SW)
   \MoveToLoc(SE) \:HflipMY\Move(-\:HBarx,\:VBarx)  \MarkLoc(SE)
\fi
   \XRecallUnits   \MoveToLoc(Origin)
   \let\:Return=\:undefined   \:NoBarClip()   }  \Define\:DrawBar(2){
   \:Bars(#1,#1){\:GetXY}  \Vb-\Va;
   \ifx \:Compute\empty                       \edef\:tempa{#2}
   \else    \def\:Return##1{\edef\:tempa{\Val##1}}\:Compute(#2)
   \fi
   \ifx  H\:BarDir      \Move(0,-\Val\Va)
      \:DrawBr(\:tempa,-\Val\Vb) \:AddBarPaint(#1,\:tempa)
      \Clip(\:tempa,-\Val\Vb)
      \:AddBarDepth(#1,\:tempa) \:Cluster(\:tempa) \Move(0,\Val\Va)
   \else                \Move(\Val\Va,0)
      \:DrawBr(\Val\Vb,\:tempa) \:AddBarPaint(#1,\:tempa)
      \Clip(\Val\Vb,\:tempa)
      \:AddBarDepth(#1,\:tempa) \:Cluster(\:tempa) \Move(-\Val\Va,0)
   \fi  }


\Define\DrawBar(2){ \DrawRect(#1,#2)}

\Define\:DrawBr(1){\MarkLoc(x:)\DrawBar(#1)\MoveToLoc(x:)}
\:DefineExt\BarChartSpec(1){\endgroup
   \IF  \EqText(,#1) \THEN \ELSE \:BarSpc(#1)    \FI  \:BarCol }

\Define\:BarSpc(2){
   \let\:Temp=\:SeqBars       \let\:BarDir=V  \let\:newStck=\empty
\let\:endnewStck=\empty
\Define\:AddBarDepth(2){}  \Define\:Cluster(1){}
\:OptBars#1...//    \Table\:Bars{#2}
   \:C=-1;  \:Bars(0,999){\:Count}
   \ifx \:Temp\:TxtBar  \IF  \GtInt(\:C,1)  \THEN
      \:tk{#1,#2}  \:aldwarn8{}
   \FI \fi
  \:Temp }\def\:OptBars#1#2#3#4//{\:OpBr(#1)\:OpBr(#2)\:OpBr(#3)}

\Define\:OpBr(1){
        \IF \EqText(H,#1)  \THEN   \let\:BarDir=H
   \ELSE\IF \EqText(T,#1)  \THEN   \let\:Temp=\:TxtBar
   \ELSE\IF \EqText(S,#1)  \THEN   \Define\:Cluster(1){ \:Vc-##1;
     \:Hflip\Move(0,##1) }
\def\:newStck{
   \edef\:svMinBar{\Val\Vb}   \Vb=0;
   \edef\:svMaxBar{\Val\:Vc}   \:Vc=0;  }
\def\:endnewStck  {
   \IF \LtDec(\:svMinBar,\Vb)  \THEN  \Vb=\:svMinBar;  \FI
   \IF \GtDec(\:svMaxBar,\:Vc)  \THEN  \:Vc=\:svMaxBar;  \FI }


   \ELSE\IF \EqText(3,#1)  \THEN   \let\:AddBarDepth=\:AddBarDp
   \FI\FI\FI\FI  }  \def\:BarsCommand#1{\EqInt(\Val\:C,#1)\THEN
       \Define\:DrawBars(}

\Define\:SeqBars{
   \IF \:BarsCommand01){ \:DrawBar(0,##1) \:GrdLn
           \:HflipMY\Move(10,0)  \:Vc=0;}
        \Define\:MaxBar{\:maxBar}

   \ELSE  \IF \:BarsCommand12){  \:DrawBar(0,##1)  \:DrawBar(1,##2)
           \:slotgrdln
 }
        \Define\:MaxBar(2){
   \:newStck   \:maxBar(##1)\:maxBar(##2)   \:endnewStck   }

   \ELSE  \IF \:BarsCommand23){ \:DrawBar(0,##1)
           \:DrawBar(1,##2)   \:DrawBar(2,##3)
           \:slotgrdln
 }
        \Define\:MaxBar(3){
   \:newStck   \:maxBar(##1)\:maxBar(##2)\:maxBar(##3)   \:endnewStck   }

   \ELSE  \IF \:BarsCommand34){ \:DrawBar(0,##1)
           \:DrawBar(1,##2)  \:DrawBar(2,##3)      \:DrawBar(3,##4)
           \:slotgrdln
 }
        \Define\:MaxBar(4){   \:newStck
   \:maxBar(##1)\:maxBar(##2)\:maxBar(##3)\:maxBar(##4)   \:endnewStck  }

   \ELSE  \IF \:BarsCommand45){ \:DrawBar(0,##1)
           \:DrawBar(1,##2)  \:DrawBar(2,##3)
           \:DrawBar(3,##4)  \:DrawBar(4,##5)
           \:slotgrdln
 }
        \Define\:MaxBar(5){   \:newStck   \:maxBar(##1)
   \:maxBar(##2)\:maxBar(##3)\:maxBar(##4)\:maxBar(##5) \:endnewStck  }

   \ELSE \:aldwarn7{}
   \FI  \FI  \FI  \FI  \FI  }\Define\:GOBBLE(1){}
\Define\:AddBarDp(2){       \MarkLoc(a:)
   \:HflipMY\Line(-\:HBarx,\:VBarx)  \MarkLoc(b:)
   \:HflipMY\Line(0,#2)         \MarkLoc(c:)
   \:HflipMY\Line(\:HBarx,-\:VBarx)  \MarkLoc(d:)
   \ifx \:Cluster\:GOBBLE  \:TopIIIdTop
   \else
      \IF \GtInt(\:C,#1) \THEN\ELSE \:TopIIIdTop \FI
   \fi
   \:HflipMY\Move(\:HBarx,0)    \MarkLoc(f:) \MoveToLoc(b:)
   \:HflipMY\Move(0,-\:VBarx) \MarkLoc(b:) \CSeg\Clip(b:,f:)
   \MoveToLoc(a:) }

\Define\BarDepth(1){
   \edef\:HBarx{#1pt\noexpand\du}  \Va=#1;  \Va*1.25;
   \edef\:VBarx{\Val\Va pt\noexpand\du} }


\BarDepth(3)

\def\:Hflip#1(#2,#3){%
   \ifx  H\:BarDir   #1(#3,#2)\else  #1(#2,#3)\fi}
\def\:HflipMY#1(#2,#3){%
   \ifx  H\:BarDir   #1(#3,-#2)\else  #1(#2,#3)\fi}  \Define\:TopIIIdTop{
   \:HflipMY\Line(\Val\Vb,0)  \MarkLoc(e:)
   \:HflipMY\Line(-\:HBarx,\:VBarx) \MarkLoc(f:)
   {\LineToLoc(c:)}}\def\::Compute#1{\ifx \:Compute\empty
         \edef\:tempa{#1}%
   \else \def\:Return##1{\edef\:tempa{\Val##1}}\:Compute(#1)\fi}

\Define\:TxtBar{
   \Define\:DrawBars(2){
      \MarkLoc(a:)  \:Bars(0,0){\:GetXY}  \Va+\Vb;  \Va/2;
\:HflipMY\Move(\Val\Va,0)  \MarkLoc(BarBot)
\::Compute{##1}  \:Hflip\Move(0,\:tempa)         \MarkLoc(BarTop)  
      \BarText(--##2--)  \MoveToLoc(a:)
      \:DrawBar(0,##1)   \:GrdLn
      \:HflipMY\Move(10,0)  \:Vc=0;}
   \Define\:MaxBar{\:maxTxtBar}}

\Define\:maxTxtBar(2){\:maxBar(#1)}

\TextPar\Define\BarText(1){
   \:Hflip\Move(0,4pt\du)  \:Hflip\EntryExit(0,-1,0,0)
   \Text(--\ignorespaces#1--)}\:DefineExt\:BarCol(1){\endgroup
   \IF  \EqText(,#1) \THEN\ELSE
      \Table\:Color{#1&0&0&0&0} \FI}  \Define\:GetColor(1){\:Vc=#1;}

\Define\:AddBarPaint(2){{    \PenSize(0.2pt)
   \MarkLoc(a:)  \MoveTo(0,0)  \MarkLoc(b:)
\ifx  V\:BarDir    \MoveTo(\Val\Vb,#2)
\else              \MoveTo(#2,-\Val\Vb)    \fi
\MarkLoc(c:) \MoveToLoc(a:)  \Units(1pt,1pt) 
   \:Color(#1,#1){\:GetColor}
   \IF         \EqDec(\:Vc,2)  \THEN
      \:VrPnt
   \ELSE\IF    \EqDec(\:Vc,3)  \THEN
      \:HrPnt
   \ELSE\IF    \EqDec(\:Vc,4)  \THEN
      \PenSize(0.2pt)  {\:VrPnt}  \:HrPnt 
   \ELSE \IF   \GtDec(\:Vc,0)  \THEN
      \:ChooseColor(\Val\:Vc)
      \CSeg\PaintRect(b:,c:)
   \FI  \FI  \FI  \FI}}\Define\:VrPnt{   \CSeg\:GetXY(b:,c:)  \:C[\Va];
   \:Vc=\Va;  \:Vc-2;  \:Vc/1.5;  \:C[\:Vc];
   \:Vc=\:C; \:Vc*1.5;  \:Vc-\Va;  \:Vc/-2;    \Move(\Val\:Vc,0)
   \Do(0,\Val\:C){ {\Line(0,\Val\Vb)} \Move(1.5,0) } }
\Define\:HrPnt{   \CSeg\:GetXY(b:,c:)  \:C[\Vb];
   \:Vc=\Vb; \ifx  V\:BarDir \:Vc-2; \else \:Vc+2; \fi
   \:Vc/1.5; \:C[\:Vc];  \:Vc=\:C;  \:Vc*1.5;
   \:Vc-\Vb; \:Vc/-2;  \Move(0,\Val\:Vc)
   \Do(0,\Val\:C){ {\Line(\Val\Va,0)}
       \Move(0,\ifx  H\:BarDir-\fi 1.5)} }
\Define\BarClipOn{\Define\:NoBarClip(1){}}
\Define\BarClipOff{\let\:NoBarClip=\Clip}

\BarClipOff\Define\:maxBar(1){
   \ifx \:Compute\empty                       \edef\:tempa{#1}
   \else    \def\:Return##1{\edef\:tempa{\Val##1}}\:Compute(#1)
   \fi
   \IF  \GtDec(\:tempa,0)  \THEN
       \ifx \:Cluster\:GOBBLE
   \IF \GtDec(\:tempa,\:Vc)  \THEN  \:Vc=\:tempa;  \FI
\else
   \:Vc+\:tempa;
\fi

   \ELSE
       \ifx \:Cluster\:GOBBLE
   \IF \LtDec(\:tempa,\Vb)  \THEN  \Vb=\:tempa;  \FI
\else
   \Vb-\:tempa;
\fi

   \FI}
\Define\ChartSize(1){
   \IF  \EqText(,#1)  \THEN
      \def\:Hchart{}  \def\:Vchart{}
   \ELSE  \:ChartSz(#1)  \FI}

\Define\:ChartSz(2){
   \MarkLoc(o:) \Move(#1   \du,#2 \du)  \MarkLoc(x:)
   \CSeg\:GetXY(o:,x:)     \edef\:Hchart{\Val\Va}
   \edef\:Vchart{\Val\Vb}  \MoveToLoc(o:) }

\ChartSize()\let\:SvDu=\du

\Define\:GridLoc(1){
   \:Vd=\:C; \:Vd*\:BarGrdDist; \MoveToLoc(Origin)
   \ifx V\:BarDir
      \Move(10,0)  \MarkLoc(#1)
      \MoveToLL(Origin,#1)(NE,SE)  \Move(0,\Val\:Vd)
   \else
      \Move(0,-10)  \MarkLoc(#1)
      \MoveToLL(Origin,#1)(SW,SE)  \Move(\Val\:Vd,0)
   \fi
   \let\du=\:SvDu
   \ifx\:AddBarDepth\:AddBarDp  \:HflipMY\Move(-\:HBarx,\:VBarx)  \fi
   \let\du=\relax   \MarkLoc(#1)}
\Define\BarGrid(3){
   \def\:BarGrdDist{#1}  \def\:BarGrdUnder{#2}
   \def\:BarGrdOver{#3}}
\BarChartSpec(V,2.5,7.5)(0)\BarGrid(0,0,0)
\Define\:slotgrdln{
   \:HflipMY\Move(0,\Val\:Vc) \:GrdLn
   \:HflipMY\Move(10,0)  \:Vc=0;         }

\fi
\:CheckOption{diagram}\if:option
   \edef\AlDraTex{spread,grid,tree,\AlDraTex}
\else \:CheckOption{spread}\if:option
   \edef\AlDraTex{diagram,\AlDraTex}
\else \:CheckOption{grid}\if:option
   \edef\AlDraTex{diagram,\AlDraTex}
\else \:CheckOption{tree}\if:option
   \edef\AlDraTex{diagram,\AlDraTex}
\fi\fi\fi\fi
\:CheckOption{xy}     \if:option  \:circletrue  \fi
\:CheckOption{diagram}\if:option  \:circletrue  \fi
\if:circle     \Define\ArrowHeads(1){
   \Define\:FrArrowHead{}
   \Define\:BkArrowHead{}
   \Define\:FrCrvArrowHead{}
   \Define\:BkCrvArrowHead{}
   \IF  \GtInt(#1,0) \THEN
      \Define\:FrArrowHead{\:ArrowHead(bk:,fr:)}
      \Define\:FrCrvArrowHead{
         \DSeg\RotateTo(2:,2':)
         \MoveToLoc(2:)  \MoveF(\:ArrowLength pt\du)
         \MoveF(0.1 pt\du) \MarkLoc(1'':)   \MarkLoc(2'':)
         \MoveToLoc(2':) \MoveF(\:ArrowLength pt\du)
         \MoveF(0.1 pt\du) \MarkLoc(1'':)  \MarkLoc(2':)
         \:ArrowHead(2'':,2:) }
   \FI
   \IF  \GtInt(#1,1) \THEN
      \Define\:BkArrowHead{\:ArrowHead(fr:,bk:)}
      \Define\:BkCrvArrowHead{
         \DSeg\RotateTo(1:,1':)
         \MoveToLoc(1:)  \MoveF(\:ArrowLength pt\du)
         \MoveF(0.1 pt\du) \MarkLoc(1'':)  \MarkLoc(1'':)
         \MoveToLoc(1':) \MoveF(\:ArrowLength pt\du)
         \MoveF(0.1 pt\du) \MarkLoc(1'':)  \MarkLoc(1':)
         \:ArrowHead(1'':,1:) }
   \FI }

\Define\:ArrowHead(2){
   \LSeg\Va(#1,#2)
   \IF  \LtDec(\Va,\:ArrowLength)  \THEN      \:aldwarn0{}
   \ELSE   \MoveToLoc(#2)  \DSeg\RotateTo(#1,#2)
      \MoveF(-\:ArrowLength pt\du)
      { \Ragged(\:ArrowRagged)  \Rotate(90)  \Va=\:ArrowWidth;
        \Va/2;     \MoveF(\Val\Va pt\du)  \MarkLoc(#2')
        \Va*2;  \MoveF(-\Val\Va pt\du)  \MarkLoc(#2'')
        \:head(#2)   }   \MarkLoc(#2)                    \FI   }

\Define\ArrowSpec(1){\:ArSp(#1,)}

\Define\:ArSp(2){
  \IF \EqText(V,#1) \THEN \Define\:head(1){
   { \Va/2;  \MoveF(\Val\Va pt\du) \MarkLoc(a:)
     \CSeg\:EdgeLine(a:,##1)  }
    \MarkLoc(a:) \CSeg\:EdgeLine(a:,##1)
    \MarkLoc(a:) \CSeg\:EdgeLine(a:,##1') }        \FI
  \IF \EqText(H,#1) \THEN \Define\:head(1){
   \MarkLoc(a:) \CSeg\:EdgeLine(a:,##1)
   \MarkLoc(a:) \CSeg\:EdgeLine(a:,##1')
   \MarkLoc(a:) \CSeg\:EdgeLine(a:,##1'')}  \FI
  \IF \EqText(F,#1) \THEN \Define\:head(1){\PaintQuad(##1,##1,##1',##1'')}
  \FI
  \IF \EqText(,#2) \THEN\ELSE  \:ArrowHeadSpec(#2) \FI }

\Define\:ArrowHeadSpec(4){  \:edef\:ArrowLength{#1}
   \:edef\:ArrowWidth{#2}  \:edef\:ArrowRagged{#3}}
\ArrowHeads(0)   \ArrowSpec(F,10,6,5)     \:circlefalse \fi
\:CheckOption{diagram}\if:option
      \Define\NewNode(2){
   \Define#1(1){
      \Define\:FrameType{\csname \string#1:Frame\endcsname}
      \Define\:NodeName{##1}
      \Indirect\Define<##1.mvto>{#2}  \:NodeBody}
   \expandafter\Define\csname \string#1:Frame\endcsname}
\Define\TextNode{
    \TextPar\Define\:NodeBody(1){
       \Object\:tmp{
          \:NodeContent(--##1--)
          \:FrameType }
       \:SetNode }
    \TextPar\Define\:NodeContent}

\Define\PictNode{
    \Define\:NodeBody(1){
       \Object\:tmp{ \Object\:temp{\:NodeContent(##1)}
              \:temp \:FrameType }
       \:SetNode }
    \TextPar\Define\:NodeContent}

\TextNode(1){\Text(--#1--)}\Define\:SetNode{\:SetNodeA }

\Define\:SetNodeA{  \:tmp
   \MarkLoc(a:)  \MoveToExit(0,0)  \MarkLoc(\:NodeName)
                 \MoveToExit(1,1)  \MarkLoc(\:NodeName;:11)
   \MoveToLoc(a:)   \:circlefalse }
\Define\DefNode{
   \Define\:SetNode{
      \Indirect\let<\:NodeName :call> = \:tmp
\def\:temp{\Indirect\let<\:NodeName :bdy> = }
   \expandafter\:temp \csname \string \:tmp .\endcsname
\Indirect\let<\:NodeName :frm> = \:FrameType
\Indirect\let<\:NodeName :cnt> = \:NodeContent
\Indirect\edef<\:NodeName :crc>{
   \if:circle \noexpand\:circletrue
   \else      \noexpand\:circlefalse \fi}

      \FigSize\Va\Vb{ \:SetNodeA }   \Va/2; \Vb/2;
\MarkLoc(\:NodeName)      \Move(\Val\Va,\Val\Vb)
\MarkLoc(\:NodeName;:11)  \MoveToLoc(\:NodeName)

      \:circlefalse
      \Define\:SetNode{\:SetNodeA }  }
   \:DefNode
}
\def\:DefNode#1(#2){#1(#2)}
\Define\PutNode(1){
   \def\:NodeName{#1}
   \Indirect{ \expandafter \let \csname \string \:tmp .\endcsname = }
               <#1:bdy>
   \Indirect<#1:crc>
   \Indirect{ \let\:FrameType   = }<#1:frm>
   \Indirect{ \let\:NodeContent = }<#1:cnt>
   \Indirect{ \let\:tmp        = }<#1:call>
   \ifx\:tmp\relax  \:aldwarn{10}{#1}\fi
   \:SetNodeA
   \Indirect\let<\:NodeName :call> = \:undef
\Indirect\let<\:NodeName :cnt>  = \:undef
\Indirect\let<\:NodeName :frm>  = \:undef
\Indirect\let<\:NodeName :bdy>  = \:undef
\Indirect\let<\:NodeName :crc>  = \:undef
   }
\Define\ZeroNodesDim{
   \def\MaxX{0}    \def\MaxY{0}
   \def\WidthX{0}  \def\WidthY{0} }
\Define\AddNodeDim(1){
   \CSeg\:GetXY(#1,#1;:11)
   \IF \GtDec(\Va,\MaxX) \THEN  \edef\MaxX{\Val\Va} \FI
   \Va*2;    \edef\Widthx{\Val\Va}  \Va+\WidthX;   \edef\WidthX{\Val\Va}
   \IF \GtDec(\Vb,\MaxY) \THEN  \edef\MaxY{\Val\Vb} \FI
   \Vb*2;   \edef\Widthy{\Val\Vb}  \Vb+\WidthY;   \edef\WidthY{\Val\Vb}  }

\Define\NewCIRCNode(3){
   \ifx \CIRC\:undefined                  \:aldwarn9\relax
      \font\CIRC=lcircle10\space scaled\magstep5
   \fi
   \Define\:Temp(2){
      \IF  \EqText(,#3)  \THEN
         \NewNode(#1,\MoveToOval){
            \Text(--\hbox to##1pt{%
               \vrule height ##2pt depth ##2pt%
                           width0pt%
            \hss\hbox to##2pt{%
               \CIRC \char #2\hss}}--)}
       \ELSE
          \NewNode(#1,\MoveToOval){
             \Text(--\hbox to##1pt{%
                \hss\hbox to##2pt{%
                   \CIRC \char #3\hss}}--)
             \Text(--\hbox to##1pt{%
                \vrule height ##2pt depth ##2pt%
                           width0pt%
             \hss\hbox to##2pt{%
                \CIRC \char #2\hss}}--)}
        \FI  }
   \setbox\:box=\hbox{\CIRC \char #2}
   \IF \EqText(,#3) \ELSE \IF  \GtInt(#3,#2)  \THEN
       \setbox\:box=\hbox{\CIRC \char #3}
   \FI  \FI
   \edef\:tempa{\noexpand\Va=\:Cons\wd\:box;}
   \:tempa  \Vb=\Va; \Vb/2;
   \edef\:tempa{\noexpand\:Temp(\Val\Va,\Val\Vb)}
   \:tempa  }
\Define\NodeMargin(2){\def\:XNodeMargin{#1}\def\:YNodeMargin{#2}}
\NodeMargin(2,2) \Define\GetNodeSize{
    \MoveToExit(1,1)
    \Move(\:XNodeMargin pt\du,\:YNodeMargin  pt\du)
    \MarkLoc(:11)    \MoveToExit(0,0)   \MarkLoc(:00)
    \CSeg\:GetXY(:00,:11)}

\Define\SetMinNodeSize{
    \IF \LtDec(\Va,\:NodeX)  \THEN  \Va=\:NodeX;  \FI
    \IF \LtDec(\Vb,\:NodeY)  \THEN  \Vb=\:NodeY;  \FI }


\Define\MinNodeSize(1){\:MinNodeSize(#1,)}
\Define\:MinNodeSize(2){
   \IF  \EqText(,#2)  \THEN
      \edef\:Temp{\noexpand\:MinNdSz(\csname :#1::\endcsname,)}
   \ELSE
      \def\:Temp{\:MinNdSz(#1,#2)}
   \FI  \:Temp}
\Define\:MinNdSz(3){
    \Va=#1;  \Va/2;  \edef\:NodeX{\Val\Va}
    \Va=#2;  \Va/2;  \edef\:NodeY{\Val\Va}  }

\Define\SaveNodeSize(1){ \CSeg\:GetXY(#1,#1;:11)
   \Va*2;  \Vb*2;
   \expandafter\edef\csname :#1::\endcsname{\Val\Va,\Val\Vb}  }

               \Define\:Temp{
\def\SaveDrawSize(##1)##2{
   \FigSize\Va\Vb{##2}
   \expandafter\edef\csname :##1::\endcsname{\Val\Va,\Val\Vb}  }
                      }\:Temp

\MinNodeSize(0,0)\def\:NodeLine{\Line}   \def\:NodeArc{\DrawOvalArc}
\Define\SRectNodeSpec(1){\:edef\:ShadowSize{#1}}
\Define\VRectNodeSpec(1){\:edef\:Vdepth{#1}}

\VRectNodeSpec(4)  \SRectNodeSpec(3) \def\NodeIx#1#2{#1=\:C;#2=\:Ca;}
\NewNode(\RectNode,\MoveToRect){   \:RectShape }
\NewNode(\VRectNode,\:MoveToVRect){ \:RectShape
   \:Vc=\:Vdepth;  \:Vc/2;  \:NodeLine(\:Vdepth,-\Val\:Vc)
   \:NodeLine(\Val\Va,0)    {\:NodeLine(-\:Vdepth,\Val\:Vc)}
   \:NodeLine(0,\Val\Vb)     \:NodeLine(-\:Vdepth,\Val\:Vc) }
\NewNode(\SRectNode,\MoveToRect){  \Units(1pt,1pt)
   \GetNodeSize   \SetMinNodeSize
   \Move(-\Val\Va,-\Val\Vb)   \Va*2;   \Vb*2;
   \:NodeLine(0,\Val\Vb)  \:NodeLine(\Val\Va,0)
   \PenSize(\:ShadowSize pt)
   \:Ve=\:ShadowSize;   \:Ve/2; \Va+\:ShadowSize;
   \Move(\Val\:Ve,0)   \Line(0,-\Val\Vb)
   \Move(\Val\:Ve,-\Val\:Ve)  \Line(-\Val\Va,0) }

\Define\:RectShape{  \Units(1pt,1pt)
   \GetNodeSize   \SetMinNodeSize
   \Move(-\Val\Va,-\Val\Vb)   \Va*2;   \Vb*2;
   \:NodeLine(0,\Val\Vb)  \:NodeLine(\Val\Va,0)
   \:NodeLine(0,-\Val\Vb) \:NodeLine(-\Val\Va,0) }

\Define\MoveToRect(3){
    \CSeg[#2]\:GetX(#1,#1;:11)
    \CSeg[#3]\:GetY(#1,#1;:11)    \MoveToLoc(#1)
    \Move(\Val\Va pt\du,\Val\Vb pt\du)}
\NewNode(\RRectNode,\:MoveToRRect){    \Units(1pt,1pt)
   \GetNodeSize   \SetMinNodeSize
   \Va+3;   \Move(-\Val\Va,-\Val\Vb)   \Va*2;   \Vb*2;
   \:Vc=\Va;  \:Vc/4;   \:Vd=\Vb;  \:Vd/4;
\IF \GtDec(\:Vc,9) \THEN   \:Vc=9; \FI
\IF \GtDec(\:Vd,9) \THEN   \:Vd=9; \FI
\Va-\:Vc;   \Va-\:Vc;   \Vb-\:Vd;  \Vb-\:Vd;
   { \Move       (\Val\:Vc,\Val\:Vd)
     \:NodeArc(\Val\:Vc,\Val\:Vd)(180,225)  }
   \Move(0,\Val\:Vd)  \:NodeLine(0,\Val\Vb)    \Move(\Val\:Vc,0)
   \:NodeArc(\Val\:Vc,\Val\:Vd)(90,180)
   \Move(0,\Val\:Vd)  \:NodeLine(\Val\Va,0)    \Move(0,-\Val\:Vd)
   \:NodeArc(\Val\:Vc,\Val\:Vd)(45,90)
      \:NodeArc(\Val\:Vc,\Val\:Vd)(0,45)
   \Move(\Val\:Vc,0)  \:NodeLine(0,-\Val\Vb)  \Move(-\Val\:Vc,0)
   \:NodeArc(\Val\:Vc,\Val\:Vd)(270,360)
   \Move(0,-\Val\:Vd)  \:NodeLine(-\Val\Va,0)   \Move(0,\Val\:Vd)
   \:NodeArc(\Val\:Vc,\Val\:Vd)(225,270)
}\NewNode(\ORectNode,\:MoveToORect){  \Units(1pt,1pt)
   \GetNodeSize   \SetMinNodeSize   \Va-2;
   { \Move(\Val\Va,0)   \:NodeArc(9,\Val\Vb)(-90,90) }
   { \Move(-\Val\Va,0)  \:NodeArc(9,\Val\Vb)(90,-90) }
   \Move(-\Val\Va,\Val\Vb)   \Va*2;   \Vb*2;
   \:NodeLine(\Val\Va,0)
   { \Move(0,-\Val\Vb)   \:NodeLine(-\Val\Va,0)} }
\NewNode(\DRectNode,\:MoveToDRect){ \Units(1pt,1pt)
   \GetNodeSize   \SetMinNodeSize
   { \Move(\Val\Va,0) \Move(9,0)
     {\:NodeLine(-9,\Val\Vb)}
     {\:NodeLine(-9,-\Val\Vb)} }
   { \Move(-\Val\Va,0)  \Move(-9,0) {\:NodeLine(9,\Val\Vb)}
     {\:NodeLine(9,-\Val\Vb)} }
   \Move(\Val\Va,\Val\Vb)   \Va*2;
   \:NodeLine(-\Val\Va,0) { \Move(0,-\Val\Vb)
      \Move(0,-\Val\Vb)
   \:NodeLine(\Val\Va,0)} }\Define\CircleNode{ \:circletrue  \OvalNode}

\NewNode(\OvalNode,\MoveToOval){
   \Units(1pt,1pt)    \GetNodeSize     \Va/0.707;  \Vb/0.707;
   \SetMinNodeSize
   \if:circle
      \IF        \LtDec(\Va,\Vb)  \THEN \Va=\Vb;
      \ELSE  \IF \LtDec(\Vb,\Va)  \THEN \Vb=\Va;
      \FI \FI
   \fi        \:NodeArc(\Val\Va,\Val\Vb) (0,360) }
\NewNode(\DiamondNode,\:MoveToDiamond){
    \Units(1pt,1pt)      \GetNodeSize
    \Vb*1.66;  \Va+\Vb;  \Vb=\Va; \Vb*0.66; \SetMinNodeSize
    \Move(0,\Val\Vb)  \:NodeLine(-\Val\Va,-\Val\Vb)
    \:NodeLine(\Val\Va,-\Val\Vb)
    \:NodeLine(\Val\Va,\Val\Vb)
    \:NodeLine(-\Val\Va,\Val\Vb)}\NewNode(\Node,\MoveToRect){ \:NoShape  }

\Define\:NoShape{
   \GetNodeSize   \SetMinNodeSize
   \MoveToExit(0,0) \EntryExit(0,0,0,0)   \Va*2; \Vb*2;
   \Text(--\vbox to\Val\Vb pt{\hsize=\Val\Va pt
           \leavevmode\hfil\vfil}--)}\Define\FcNode(1){
   \edef\:Temp{\noexpand\Indirect\let<#1.mvto>=\noexpand\MoveToRect}
   \:Temp  \MarkLoc(#1)  \Move(0.01pt\du,0.01pt\du)
   \MarkLoc(#1;:11) \MoveToLoc(#1) }
\Define\MoveToNodeDir(1){\edef\:Temp{\noexpand\::MvToExit(#1)}\:Temp}

\Define\::MvToExit(2){
   \DSeg\:Vc(#1,#2)  \let\:Temp=\relax
   \IF          \EqDec(\:Vc,0)  \THEN  \MoveToNode(#1,1,0)
   \ELSE   \IF  \EqDec(\:Vc,90) \THEN  \MoveToNode(#1,0,1)
   \ELSE   \IF  \EqDec(\:Vc,180)\THEN  \MoveToNode(#1,-1,0)
   \ELSE   \IF  \EqDec(\:Vc,270)\THEN  \MoveToNode(#1,0,-1)
   \ELSE   \DSeg\Va(#1,#1;:11)
\IF  \LtDec(\:Vc,\Va)  \THEN         \:PreSrchExit(#1,1,\Val\:Ve,0,1)
\ELSE  \Vb=180;  \Vb-\Va;
   \IF  \LtDec(\:Vc,\Vb)  \THEN      \:PreSrchExit(#1,\Val\:Ve,1,1,-1)
   \ELSE  \Vb=180;  \Vb+\Va;
      \IF  \LtDec(\:Vc,\Vb)  \THEN   \:PreSrchExit(#1,-1,\Val\:Ve,1,-1)
      \ELSE  \Vb=360;  \Vb-\Va;
         \IF  \LtDec(\:Vc,\Vb)  \THEN\:PreSrchExit(#1,\Val\:Ve,-1,-1,1)
         \ELSE                      \:PreSrchExit(#1,1,\Val\:Ve,-1,0)
\FI\FI\FI\FI  \FI\FI\FI\FI   \:Temp }\Define\:PreSrchExit(5){
   \def\:Temp{\def\:tempa{(#1,#2,#3}\:SearchExit(#1,#4,#5)} }
\Define\:SearchExit(3){
   \:Ve=#3;  \:Ve-#2;  \IF \LtDec(\:Ve,0)  \THEN \:Ve=-\:Ve;  \FI
   \IF  \LtDec(\:Ve,0.01)  \THEN \let\:Temp=\relax
   \ELSE
      \:Ve=#2;  \:Ve+#3;  \:Ve/2;  \edef\:tempb{\Val\:Ve}
      \expandafter\MoveToNode\:tempa)   \MarkLoc(x:)
      \DSeg\:Vd(#1,x:)
      \IF  \GtDec(\:Vd,\:Vc) \THEN
         \edef\:Temp{\noexpand\:SearchExit(#1,#2,\:tempb)}
      \ELSE
         \edef\:Temp{\noexpand\:SearchExit(#1,\:tempb,#3)}
    \FI \FI  \:Temp  }\Define\TraceDiagramOn{\def\:TrcDiag##1{##1}}
\Define\TraceDiagramOff{\def\:TrcDiag##1{}}
\TraceDiagramOff \Define\TagNode(1){{\:TagNode(#1)}}

\Define\::TagNode(1){ \let&=\relax
   \xdef\:tgnd{\:tgnd&#1,\Val\:C..\Val\:Ca}}

\Define\:bgDiTags{
   \Define\:TagNode(1){}
   \Define\:EdgeNode(1){}
   \let\:svTgNd=\:tgnd  \gdef\:tgnd{}
   \let\:svEdNd=\:ednd  \gdef\:ednd{} }

\Define\:endDiTags{
   \MarkLoc(o:)
   \ifx\:tgnd\empty \else
      \Table\:Temp{\:tgnd}
      \:Temp(1,999){\:SetNdTg} \fi
   \global\let\:tgnd=\:svTgNd
      \ifx\:ednd\empty \else
      \Table\:Temp{\:ednd}
      \:C=0;
      \:Temp(1,999){\::CurrEdge} \fi
   \global\let\:ednd=\:svEdNd

   \MoveToLoc(o:)}

\Define\:SetNdTg(2){
   \Indirect{ \Indirect\let<#1.mvto>= }<#2.mvto>
   \MoveToLoc(#2)  \MarkLoc(#1)
   \MoveToLoc(#2;:11)  \MarkLoc(#1;:11)  }

   \fi
   \:CheckOption{diagram}\if:option
      \Define\MoveToNode(3){
   \XSaveUnits \Units(1pt,1pt)
   \edef\:Temp{\noexpand\Indirect<#1.mvto>(#1,#2,#3)}
   \:Temp  \XRecallUnits }\Define\:MoveToVRect(3){
   \MoveToRect(#1,#2,#3) \:Ve=\:Vdepth;  \:Ve/2;
   \:Vd=\:Ve;  \:Vd/2;
   \IF \GtDec(#2,0.98) \THEN      \Move(-\Val\:Ve,0)
      \IF \GtDec(#3,0.98) \THEN   \Move(0,-\Val\:Vd)
   \FI \FI
   \IF \LtDec(#3,-0.98) \THEN     \Move(0,\Val\:Vd)
      \IF \LtDec(#2,-0.98) \THEN  \Move(\Val\:Ve,0)
   \FI \FI}  \Define\:MoveToRRect(3){   \MoveToRect(#1,#2,#3)
   \Va=#2;  \IF \LtDec(\Va,0)  \THEN \Va=-\Va;  \FI
   \Vb=#3;  \IF \LtDec(\Vb,0)  \THEN \Vb=-\Vb;  \FI
   \IF  \GtDec(\Va,1)  \THEN \Va=1;  \FI
   \IF  \GtDec(\Vb,1)  \THEN \Vb=1;  \FI
   \IF        \LtDec(\Va,0.9) \THEN \Va=0; \Vb=0;
   \ELSE \IF  \LtDec(\Vb,0.9) \THEN \Va=0; \Vb=0;
   \ELSE \Va-1;  \Va=-\Va;  \Vb-1;  \Vb=-\Vb;  \FI \FI
   \IF \GtDec(#2,0) \THEN  \Va=-\Va;  \FI
   \IF \GtDec(#3,0) \THEN  \Vb=-\Vb;  \FI
   \Va*30;  \Vb*30;
   \Move(\Val\Va pt\du,\Val\Vb pt\du) }\Define\:MoveToORect(3){
   \MoveToRect(#1,0,0)   \MarkLoc(o:mv)
   \MoveToRect(#1,#2,#3) \MarkLoc(x:mv)  \MarkLoc(y:mv)
   \CSeg\:GetX(o:mv,x:mv)
   \MoveToRect(#1,1,0)  \MarkLoc(a:mv)   \LSeg\:Ve(a:mv,x:mv)
\IF \LtDec(\:Ve,0.1) \THEN  \Move(9pt\du,0)
\ELSE   \DSeg\:Ve(a:mv,x:mv)
   \IF \LtDec(\:Ve,90) \THEN
      \MoveToRect(#1,1,1)  \MarkLoc(1:mv)
      \DSeg\:Vd(o:mv,x:mv)      \DSeg\:Ve(o:mv,1:mv)
      \:Vd/\:Ve; \:Vd*90;  \RotateTo(\Val\:Vd)  \MoveToLoc(a:mv)
      \MoveFToOval(9 pt\du,\Val\Vb pt\du)   \MarkLoc(y:mv)
   \ELSE \IF \GtDec(\:Ve,270)\THEN
      \MoveToRect(#1,1,-1)  \MarkLoc(1:mv)
      \DSeg\:Vd(o:mv,x:mv)      \DSeg\:Ve(o:mv,1:mv)
      \:Vd-360;   \:Ve-360;   \:Vd/\:Ve;
      \:Vd*90;  \RotateTo(-\Val\:Vd)  \MoveToLoc(a:mv)
      \MoveFToOval(9 pt\du,\Val\Vb pt\du)   \MarkLoc(y:mv)
\FI \FI \FI
   \MoveToRect(#1,-1,0)  \MarkLoc(a:mv)    \LSeg\:Ve(a:mv,x:mv)
\IF \LtDec(\:Ve,0.1) \THEN  \Move(-9pt\du,0)
\ELSE    \DSeg\:Ve(a:mv,x:mv)
   \IF \GtDec(\:Ve,90) \THEN
      \IF \LtDec(\:Ve,180) \THEN
         \MoveToRect(#1,-1,1)  \MarkLoc(1:mv)
         \DSeg\:Vd(o:mv,x:mv)      \DSeg\:Ve(o:mv,1:mv)
         \:Vd-180;  \:Ve-180;  \:Vd/\:Ve;
         \:Vd*90;  \:Vd-180;  \:Vd=-\:Vd;
         \RotateTo(\Val\:Vd)  \MoveToLoc(a:mv)
         \MoveFToOval(9 pt\du,\Val\Vb pt\du)   \MarkLoc(y:mv)
      \ELSE\IF \LtDec(\:Ve,180) \THEN
         \MoveToRect(#1,-1,-1)  \MarkLoc(1:mv)
         \DSeg\:Vd(o:mv,x:mv)      \DSeg\:Ve(o:mv,1:mv)
         \:Vd-180;  \:Ve-180;  \:Vd/\:Ve;
         \:Vd*90;  \:Vd+180;  \:Vd=-\:Vd;
         \RotateTo(\Val\:Vd)  \MoveToLoc(a:mv)
         \MoveFToOval(9 pt\du,\Val\Vb pt\du)   \MarkLoc(y:mv)
\FI \FI \FI \FI  \MoveToLoc(y:mv) }\Define\:MoveToDRect(3){ \XSaveUnits
   \MoveToRect(#1,0,0)   \MarkLoc(o:mv)
   \MoveToRect(#1,#2,#3) \MarkLoc(x:mv)  \MarkLoc(y:mv)
   \CSeg\:GetX(o:mv,x:mv)
   \MoveToRect(#1,1,0)  \MarkLoc(a:mv)     \LSeg\:Ve(a:mv,x:mv)
\IF \LtDec(\:Ve,0.1) \THEN  \Move(9pt\du,0)
\ELSE     \DSeg\:Ve(a:mv,x:mv)
   \IF \LtDec(\:Ve,90) \THEN
      \Move(0,\Val\Vb)  \MarkLoc(.:)
      \Move(9,-\Val\Vb) \MarkLoc(..:)
      \MoveToLL(.:,..:) \MarkLoc(y:mv)
   \ELSE \IF \GtDec(\:Ve,270) \THEN
      \Move(0,-\Val\Vb)  \MarkLoc(.:)
      \Move(9,\Val\Vb) \MarkLoc(..:)
      \MoveToLL(.:,..:) \MarkLoc(y:mv)
\FI \FI \FI
   \MoveToRect(#1,-1,0)  \MarkLoc(a:mv)    \LSeg\:Ve(a:mv,x:mv)
\IF \LtDec(\:Ve,0.1) \THEN  \Move(-9pt\du,0)
\ELSE      \DSeg\:Ve(a:mv,x:mv)
   \IF    \GtDec(\:Ve,90) \THEN
      \IF \LtDec(\:Ve,180)\THEN
         \Move(0,\Val\Vb)  \MarkLoc(.:)
         \Move(-9,-\Val\Vb) \MarkLoc(..:)
         \MoveToLL(.:,..:) \MarkLoc(y:mv)
      \ELSE  \IF \LtDec(\:Ve,270)\THEN
         \Move(0,-\Val\Vb)  \MarkLoc(.:)
         \Move(-9,\Val\Vb) \MarkLoc(..:)
         \MoveToLL(.:,..:) \MarkLoc(y:mv)
\FI \FI \FI \FI
\XRecallUnits \MoveToLoc(y:mv) }\Define\MoveToOval(3){
   \CSeg[#2]\:GetX(#1,#1;:11)
   \CSeg[#3]\:GetY(#1,#1;:11)
   \MoveTo(0,0)   \MarkLoc(00:)
   \MoveTo(\Val\Va pt\du,\Val\Vb pt\du)  \MarkLoc(11:)
    \MoveToLoc(#1)   \LSeg\Va(00:,11:)
   \IF \GtDec(\Va,0.001) \THEN
      \DSeg\RotateTo(00:,11:)
      \CSeg\MoveFToOval(#1,#1;:11)
   \FI}\Define\:MoveToDiamond(3){
   \CSeg\:GetXY(#1,#1;:11)
   \IF \LtDec(#2,0)  \THEN  \Va=-\Va;  \FI
   \IF \LtDec(#3,0)  \THEN  \Vb=-\Vb;  \FI
   \MoveToLoc(#1)  \Move(\Val\Va pt\du,0)  \MarkLoc(.:)
   \MoveToLoc(#1)  \Move(0,\Val\Vb pt\du)  \MarkLoc(..:)
   \CSeg\:GetXY(#1,#1;:11)  \Va*#2;  \Vb*#3;
   \MoveToLoc(#1)  \Move(\Val\Va pt\du,\Val\Vb pt\du)
   \MarkLoc(..:..)  \LSeg\Va(#1,..:..)
   \IF \GtDec(\Va,0) \THEN  \MoveToLL(.:,..:)(#1,..:..)  \FI }

   \fi
   \:CheckOption{diagram}\if:option
      \Define\EdgeSpec(1){\:EdgeSpec#1....//}
\def\:EdgeSpec#1#2#3#4.//{\:EdSp(#1)\:EdSp(#2)\:EdSp(#3)}

\Define\:EdSp(1){
   \IF  \EqText(L,#1) \THEN
      \def\:EdgeLine{\Line}     \def\:EdgeCurve{\Curve}
   \FI
   \IF  \EqText(D,#1) \THEN
      \let\:EdgeLine=\:DotLine  \let\:EdgeCurve=\:DotCurve
   \FI
   \IF  \EqText(C,#1) \THEN
      \def\:LocByAddr##1(##2){ \MoveTo(##2)
                         \MarkLoc(;:) ##1(;:)}
   \FI
   \IF  \EqText(T,#1) \THEN
      \let\:LocByAddr=\relax
   \FI
   \IF  \EqText(R,#1) \THEN
      \Define\:EdgeCorner{
   \MoveToLoc(fr:)   \MarkLoc(nxt':)   \MarkLoc(fr':)
   \:SetEndCorner(fr:,bk:)      \:SetEndCorner(nxt':,nxt:)
   \:EdgeCurve(fr:,fr:1,nxt':1,nxt':) }
   \FI
   \IF  \EqText(S,#1) \THEN
      \Define\:EdgeCorner{\MoveToLoc(fr:)    \MarkLoc(nxt':)}
   \FI}

\Define\:DotLine(1){
   {  \MarkLoc(a:)  \Move(#1) \MarkLoc(b:)
      \DSeg\RotateTo(a:,b:)  \LineF(-\:thickness \du)
      \MoveToLoc(a:)  \LineF(\:thickness\du)}
    \DoLine(#1)(3pt\du){
       \Units(1pt,1pt) \MoveF(-0.5) \LineF(1) }}

\Define\:DotCurve(4){
   { \DSeg\RotateTo(#1,#2)  \MoveToLoc(#1)
     \divide\:thickness by2  \LineF(\:thickness \du)  }
   { \DSeg\RotateTo(#4,#3)  \MoveToLoc(#4)
     \divide\:thickness by2  \LineF(\:thickness \du)  }
     \DoCurve(#1,#2,#3,#4)(3pt\du){
        \Units(1pt,1pt) \MoveF(-0.5) \LineF(1) } }

\Define\EdgeAt(6){
   \MoveToNode(#1,#2,#3)  \MarkLoc(EdgeBack)
   \Table\:EdgePath{#6}
   \:EdgePath(0,0){\:GetEdgeFront}
   \MoveToNode(#4,#5,\:EdgeFront)  \:InsertEdge(#6)}\Define\Edge(2){
   \Table\:EdgePath{#1&#2}
   \:C=-1; \:EdgePath(0,99){\:Count}
   \IF \EqDec(\:C,1)  \THEN
      \MoveToNodeDir(#1,#2)    \MarkLoc(EdgeBack)
      \MoveToNodeDir(#2,#1)
   \ELSE  \:EdgePath(2,2){\:LocByAddr\MoveToLoc}  \MarkLoc(:)
\MoveToNodeDir(#1,:)  \MarkLoc(EdgeBack)
\Define\:Temp(1){\def\:Temp{##1}}
\:EdgePath(1,1){\:Temp}
\:EdgePath(\Val\:C,\Val\:C){\:LocByAddr\MoveToLoc}
\MarkLoc(EdgeFront)   \MoveToNodeDir(\:Temp,EdgeFront)     \FI
   \Table\:EdgePath{#2}    \:InsertEdge(#2) }\Define\EdgeTo(4){
   \Table\:EdgePath{#4}
   \:C=-1; \:EdgePath(0,1){\:Count}
   \IF \EqDec(\:C,0)  \THEN
      \MoveToNode(#2,#3,#4)  \MarkLoc(EdgeFront)
      \MoveToNodeDir(#1,EdgeFront)    \MarkLoc(EdgeBack)
      \MoveToLoc(EdgeFront)
   \ELSE   \:EdgePath(1,1){\:LocByAddr\MoveToLoc}  \MarkLoc(:)
\MoveToNodeDir(#1,:)    \MarkLoc(EdgeBack)
\:EdgePath(0,0){\:GetEdgeFront}
\MoveToNode(#2,#3,\:EdgeFront)    \FI
   \:InsertEdge(#4) }\Define\EdgeFrom(4){
   \Table\:EdgePath{#1&#4}
   \:C=-1; \:EdgePath(0,99){\:Count}
   \MoveToNode(#1,#2,#3)  \MarkLoc(EdgeBack)
   \IF \EqDec(\:C,1)  \THEN
      \MoveToNodeDir(#4,EdgeBack)
   \ELSE  \Define\:Temp(1){\def\:Temp{##1}}
\:EdgePath(1,1){\:Temp}
\:EdgePath(\Val\:C,\Val\:C){\:LocByAddr\MoveToLoc}
\MarkLoc(EdgeFront)      \MoveToNodeDir(\:Temp,EdgeFront)   \FI
   \Table\:EdgePath{#4}    \:InsertEdge(#4) }\Define\:InsertEdge(1){
    \MarkLoc(EdgeFront)       \:C=-1;    \:EdgePath(0,2){\:Count}
    \IF  \EqInt(\:C,0)  \THEN
       \:OneSegmentEdge
    \ELSE
       \Define\:Temp(1){
   \:LocByAddr\MoveToLoc(##1)\MarkLoc(temp:)}
\:EdgePath(1,1){\:Temp}
\MoveToLoc(EdgeBack)  \MarkLoc(bk:)
\MoveToLoc(temp:)     \MarkLoc(fr:)   \:BkArrowHead
       \IF  \GtInt(\:C,1)  \THEN
          \def\:temp##1&##2(&){\Table\:EdgePath{##2}}
         \:temp#1(&)  \:EdgePath(1,99){\:InterEdge}
       \FI
       \MoveToLoc(EdgeFront) \MarkLoc(nxt:)
\:EdgeCorner \:EdgeSegment
\MoveToLoc(nxt':) \MarkLoc(bk:)
\MoveToLoc(nxt:)  \MarkLoc(fr:)
\:FrArrowHead  \:EdgeSegment
    \FI  \def\EdgeLabel{\:PutLabel\:LineLbl}  }\Define\:OneSegmentEdge{
   \MoveToLoc(EdgeBack)   \MarkLoc(bk:)
   \MoveToLoc(EdgeFront)     \MarkLoc(fr:)
   \:BkArrowHead  \:FrArrowHead  \:EdgeSegment }\Define\:InterEdge(1){
   \:LocByAddr\MoveToLoc(#1) \MarkLoc(nxt:)
   \:EdgeCorner \:EdgeSegment
   \MoveToLoc(nxt':) \MarkLoc(bk:)
   \MoveToLoc(nxt:)  \MarkLoc(fr:)}

\Define\:EdgeSegment{\MoveToLoc(bk:) \CSeg\:EdgeLine(bk:,fr:)}
\Define\:SetEndCorner(2){ \MoveToLoc(fr':)
   \CSeg[0.5]\Move(fr':,#2)  \MarkLoc(#1)  \LSeg\Va(fr':,#1)
   \IF  \GtDec(\Val\Va,10)  \THEN
      \MoveToLoc(fr':)  \DSeg\RotateTo(fr':,#2)
      \MoveF(10)  \MarkLoc(#1)
   \FI
   \MoveToLoc(fr':) \CSeg[0.5]\Move(fr':,#1)  \MarkLoc(#1 1)}
\Define\CurvedEdgeAt(6){
    \MoveToNode(#1,#2,#3)  \MarkLoc(1:)   \MarkLoc(EdgeBack)
    \MoveToNode(#4,#5,#6)  \MarkLoc(2:)   \MarkLoc(EdgeFront)
    \:CurvedEdgeAtDir}

\Define\:CurvedEdgeAtDir(4){
    \RotateTo(#3)   \LSeg[#4]\MoveF(1:,2:)
    \MarkLoc(2':)   \MoveToLoc(1:)
    \RotateTo(#1)   \LSeg[#2]\MoveF(1:,2:)
    \MarkLoc(1':)   \:InCrvEd    }

\Define\CurvedEdge(2){
   \DSeg\RotateTo(#1,#2)   \Rotate(\:StartEdgeDir)
   \MoveToLoc(#1)   \MoveF(50)  \MarkLoc(1:)
   \MoveToNodeDir(#1,1:)    \MarkLoc(EdgeBack)
   \MarkLoc(1:)  \LSeg[\:StartEdgeTension]\MoveF(#2,#1)
   \MarkLoc(1':)
   \DSeg\RotateTo(#2,#1)   \Rotate(\:EndEdgeDir)
   \MoveToLoc(#2)   \MoveF(50)  \MarkLoc(2:)
   \MoveToNodeDir(#2,2:)    \MarkLoc(EdgeFront)
   \MarkLoc(2:)  \LSeg[\:EndEdgeTension]\MoveF(#2,#1)
   \MarkLoc(2':) \:InCrvEd }\Define\:InCrvEd{
   \:BkCrvArrowHead\:FrCrvArrowHead
    \MoveToLoc(1:)     \MarkLoc(EdgeBack')
    \MoveToLoc(1':)    \MarkLoc(EdgeBack'')
    \MoveToLoc(2':)    \MarkLoc(EdgeFront'')
    \MoveToLoc(2:)     \MarkLoc(EdgeFront')
    \:EdgeCurve(1:,1':,2':,2:)   \def\EdgeLabel{\:PutLabel\:CurveLbl} }

\Define\CurvedEdgeSpec(4){
   \:edef\:StartEdgeDir{#1}  \:edef\:StartEdgeTension{#2}
   \:edef\:EndEdgeDir{#3}    \:edef\:EndEdgeTension{#4}   }

\CurvedEdgeSpec(10,0.2,-10,0.2)\Define\HVEdge(2){  \:XYEdge(#1,#2,1,)  }
\Define\VHEdge(2){  \:XYEdge(#1,#2,,1)  }   \Define\:XYEdge(4){
   \MoveToNode(#1,0,0) \MarkLoc(1:)  \Move(#30,#40)  \MarkLoc(1':)
\MoveToNode(#2,0,0) \MarkLoc(2:)  \Move(#40,#30)  \MarkLoc(2':)
\MoveToLL(1:,1':)(2:,2':) 
   \MarkLoc(x:)  \MarkLoc(bk:)
   \CSeg\:GetExit(1:,x:)  \MoveToNode(#1,\Val\Va,\Val\Vb)
   \MarkLoc(EdgeBack)
   \CSeg\:GetExit(2:,x:)  \MoveToNode(#2,\Val\Va,\Val\Vb)
   \MarkLoc(EdgeFront)
   \LSeg\Va(#1,EdgeBack)   \LSeg\Vb(#1,x:)
\IF \GtDec(\Vb,\Va) \THEN
   \LSeg\Va(#2,EdgeFront)   \LSeg\Vb(#2,x:)
   \IF \GtDec(\Vb,\Va) \THEN   \:Vc=1;  \ELSE  \:Vc=-1;  \FI
\ELSE  \:Vc=-1;  \FI
   \IF  \GtDec(\:Vc,0)  \THEN
      \MarkLoc(fr:)  \:FrArrowHead
      \CSeg\:EdgeLine(fr:,bk:)  \MarkLoc(fr:)
      \MoveToLoc(EdgeBack) \MarkLoc(bk:) \:BkArrowHead
      \CSeg\:EdgeLine(bk:,fr:)
      \def\EdgeLabel{\:PutLabel\:XYLbl}
   \ELSE  \CSeg\:GetExit(#1,#2)
\IF  \LtDec(\Va,0)  \THEN
   \Va=-\Va;  \:Vc=-1;  \ELSE \:Vc=1;
\FI
\IF  \LtDec(\Vb,0)  \THEN
   \Vb=-\Vb;  \:Vd=-1;  \ELSE \:Vd=1;
\FI
\IF  \GtDec(\Va,\Vb)  \THEN
      \:Vd=0;  \:MarkMid(#1,#2)  \HHEdge(#1,#2,A:)
\ELSE \:Vc=0;  \:MarkMid(#1,#2)  \VVEdge(#1,#2,A:)   \FI
 \FI }\Define\:MarkMid(2){
   \MoveToNode(#1,\Val\:Vc,\Val\:Vd)   \MarkLoc(1:)
   \MoveToNode(#2,-\Val\:Vc,-\Val\:Vd) \MarkLoc(2:)
   \CSeg[0.5]\Move(2:,1:)  \MarkLoc(A:)}
\Define\VVEdge(3){  \:XXedge(#1,#2,#3,,1) }
\Define\HHEdge(3){  \:XXedge(#1,#2,#3,1,) }\Define\:XXedge(5){
   \MoveToNode(#1,0,0) \MarkLoc(1:)  \Move(#40,#50)  \MarkLoc(1':)
   \MoveToNode(#2,0,0) \MarkLoc(2:)  \Move(#40,#50)  \MarkLoc(2':)
   \MoveToLoc(#3)      \MarkLoc(3:)  \Move(#50,#40)  \MarkLoc(3':)
   \DSeg\Va(1:,3:)  \IF \GtDec(\Va,179) \THEN  \Va-180;  \FI
\DSeg\Vb(2:,3:)  \IF \GtDec(\Vb,179) \THEN  \Vb-180;  \FI
\IF  \EqText(,#4)  \THEN
   \IF       \EqDec(\Va,0) \THEN  \HVEdge(#1,#2)
   \ELSE \IF \EqDec(\Vb,0) \THEN  \VHEdge(#1,#2)
   \ELSE \::XXEdge(#1,#2)  \FI\FI
\ELSE
   \IF       \EqDec(\Va,90) \THEN  \VHEdge(#1,#2)
   \ELSE \IF \EqDec(\Vb,90) \THEN  \HVEdge(#1,#2)
   \ELSE \::XXEdge(#1,#2)  \FI\FI
\FI}

\Define\::XXEdge(2){
   \MoveToLL(2:,2':)(3:,3':)  \MarkLoc(y:)
   \MoveToLL(1:,1':)(3:,3':)  \MarkLoc(x:)  \MarkLoc(fr:)
   \CSeg\:GetExit(1:,x:)  \MoveToNode(#1,\Val\Va,\Val\Vb)
   \MarkLoc(EdgeBack) \MarkLoc(bk:) \:BkArrowHead
   \CSeg\:EdgeLine(bk:,fr:)
   \CSeg\:EdgeLine(x:,y:) \MarkLoc(bk:)
   \CSeg\:GetExit(2:,y:)  \MoveToNode(#2,\Val\Va,\Val\Vb)
   \MarkLoc(EdgeFront)  \MarkLoc(fr:)  \:FrArrowHead
   \CSeg\:EdgeLine(fr:,bk:)
   \def\EdgeLabel{\:PutLabel\:XXLbl}  } \Define\CycleEdge(1){
   \MoveToNode(#1,0,0)  \MarkLoc(o:)  \MoveF(10)
   \MarkLoc(oo:)  \Rotate(\:CrvEdgeDir)   \MoveF(10)
   \MarkLoc(1':)  \CSeg\:GetExit(oo:,1':)
   \MoveToNode(#1,\Val\Va,\Val\Vb)    \MarkLoc(EdgeBack)
   \MarkLoc(1:) \MoveF(\:CrvEdgeTension)
   \MarkLoc(1':) \DSeg\RotateTo(o:,oo:)
   \MoveToLoc(o:)  \Rotate(-\:CrvEdgeDir)   \MoveF(10)
   \MarkLoc(2':)  \CSeg\:GetExit(o:,2':)
   \MoveToNode(#1,\Val\Va,\Val\Vb) \MarkLoc(EdgeFront)
   \MarkLoc(2:)  \MoveF(\:CrvEdgeTension)
   \MarkLoc(2':) \:InCrvEd   \:EdgeCurve(1:,1':,2':,2:) }

\Define\CycleEdgeSpec(2){
   \:edef\:CrvEdgeDir{#1}  \:edef\:CrvEdgeTension{#2}}

\CycleEdgeSpec(30,20)\EdgeSpec(LTS) \Define\TransEdge(4){
   \IF  \EqText(,#3)  \THEN
      \IF  \EqText(,#4)  \THEN
             \Edge(#1,#2)
      \ELSE  \Edge(#2,#1)
         \EdgeLabel(--#4--) \relax \FI
   \ELSE \IF  \EqText(,#4)  \THEN
      \Edge(#1,#2)    \EdgeLabel(--#3--)\relax
   \ELSE \IF  \EqText(#1,#2)  \THEN
      \RotateTo(#3)   \CycleEdge(#1)
      \EdgeLabel(--#4--)\relax
   \ELSE              \CurvedEdge(#1,#2)
      \EdgeLabel(--#3--) \relax \CurvedEdge(#2,#1)
      \EdgeLabel(--#4--) \relax   \FI  \FI  \FI }
\:DefineExt\:DiagEg(1){\endgroup
   \IF  \EqText(,#1)  \THEN  \ELSE
      \Define\:DiagramEdge{#1}
   \FI }\Define\GridEdge(2){
   \LSeg\Va(#1,#2)
   \IF  \EqDec(\Va,0)  \THEN       \:aldwarn2{#2}    \FI
   \MoveToNode(#1,0,1)  \MarkLoc(1:)
\MoveToNode(#2,0,-1) \MarkLoc(2:)   \CSeg\:GetXY(1:,2:)
\IF  \GtDec(\Vb,-0.1)  \THEN
   \MoveToNode(#1,1,0)  \MarkLoc(1:)
   \MoveToNode(#2,-1,0) \MarkLoc(2:)   \CSeg\:GetXY(1:,2:)
   \IF  \GtDec(\Va,-0.1)  \THEN \EdgeAt(#1,1,1,#2,-1,-1)
   \ELSE
      \MoveToNode(#1,-1,0)  \MarkLoc(1:)
      \MoveToNode(#2,1,0) \MarkLoc(2:)   \CSeg\:GetXY(1:,2:)
      \IF  \LtDec(\Va,0.1)  \THEN  \EdgeAt(#1,-1,1,#2,1,-1)
      \ELSE  \EdgeAt(#1,0,1,#2,0,-1)
    \FI \FI  
   \ELSE \MoveToNode(#1,0,-1)  \MarkLoc(1:)
\MoveToNode(#2,0,1) \MarkLoc(2:)   \CSeg\:GetXY(1:,2:)
\IF  \LtDec(\Vb,0.1)  \THEN
   \MoveToNode(#1,1,0)  \MarkLoc(1:)
   \MoveToNode(#2,-1,0) \MarkLoc(2:)   \CSeg\:GetXY(1:,2:)
   \IF  \GtDec(\Va,-0.1)  \THEN \EdgeAt(#1,1,-1,#2,-1,1)
   \ELSE
      \MoveToNode(#1,-1,0)  \MarkLoc(1:)
      \MoveToNode(#2,1,0) \MarkLoc(2:)   \CSeg\:GetXY(1:,2:)
      \IF  \LtDec(\Va,0.1)  \THEN \EdgeAt(#1,-1,-1,#2,1,1)
      \ELSE   \EdgeAt(#1,0,-1,#2,0,1)
   \FI\FI 
   \ELSE \IF  \GtDec(\Va,0)  \THEN   \EdgeAt(#1,1,0,#2,-1,0)
\ELSE                       \EdgeAt(#1,-1,0,#2,1,0)  \FI
  \FI\FI}    \Define\EdgeToNode(1){{\:EdgeNode(#1)}}

\Define\::EdgeNode(1){ \let&=\relax
   \xdef\:ednd{\:ednd&\Val\:C..\Val\:Ca,#1} }

\Define\::CurrEdge(2){ \:C+1;
   \IF \EqInt(\:C,2) \THEN
      \:CurrEdge(#1,#2)  \:C=0;
   \FI }

   \fi
   \:CheckOption{diagram}\if:option
                \Define\:Temp{
\def\:PutLabel##1{
   \Define\:Lbl{\def\:Temp{\noexpand##1}
      \begingroup   \:DraCatCodes  \:GetLbl}
   \edef\:Temp{\noexpand\:Opt[]
      \noexpand\:Lbl\noexpand{\:LblAdj\noexpand}}
   \:Temp}

\def\:GetLbl[##1]{\endgroup
   \IF  \EqText(+,##1) \THEN
      \edef\:Temp{\:Temp[+\:LblAdj]}
   \ELSE  \edef\:Temp{\:Temp[##1]}  \FI
   \:Temp }
                }\:Temp\Define\:PutLbl(1){
   \MarkLoc(1:)  \XSaveUnits  \Units(1pt,1pt)
   \MoveF(\:LblDis)  \XRecallUnits
   \IF  \EqText(,#1)  \THEN \ELSE    \:AdjLbl(#1)
   \FI    \MarkLoc(2:)    \CSeg\:GetExit(1:,2:)
   \EntryExit(-\Val\Va,-\Val\Vb,0,0) \:EdgeLabel }

\def\:AdjLbl(#1;#2){\Move(#1,#2)}\Define\LabelPos(2){
   \def\:LblAdj{#1}  \def\:LblDis{#2} }
\LabelPos(0.5;,3)          \Define\:Temp{
\def\:LineLbl[##1##2;##3]{
   \MoveToLoc(EdgeBack)   \MarkLoc(a:)
   \MoveToLoc(EdgeFront)  \MarkLoc(b:)
   \DSeg\RotateTo(a:,b:)
   \:C=-1; \:EdgePath(0,99){\:Count}
\IF  \EqInt(\:C,1)  \THEN
    \:EdgePath(1,1){\:LocByAddr\MoveToLoc}
    \MarkLoc(a:)  \MarkLoc(b:)
\ELSE  \IF  \GtInt(\:C,1)  \THEN
   \:C/2;  \:EdgePath(\Val\:C,\Val\:C){\:LocByAddr\MoveToLoc}
   \MarkLoc(a:)
   \:C+1;  \:EdgePath(\Val\:C,\Val\:C){\:LocByAddr\MoveToLoc}
   \MarkLoc(b:)
   \DSeg\RotateTo(a:,b:)
\FI \FI
   \MoveToLoc(a:)
   \IF  \EqText(+,##1) \THEN  \Rotate(-90)
      \CSeg[##2]\Move(a:,b:)
   \ELSE                     \Rotate(90)
      \CSeg[##1##2]\Move(a:,b:)
   \FI
   \:PutLbl(##3) }
          }\:Temp           \Define\:Temp{
\def\:CurveLbl[##1##2;##3]{
   \MoveToLoc(EdgeBack')  \MarkLoc(a:)
   \MoveToLoc(EdgeBack'') \MarkLoc(A:)
   \MoveToLoc(EdgeFront'')   \MarkLoc(B:)
   \MoveToLoc(EdgeFront')    \MarkLoc(b:)
   \DSeg\RotateTo(a:,b:)
   \IF  \EqText(+,##1)  \THEN
       \Rotate(-90)
   \ELSE
       \Rotate(90)
   \FI
   \MoveToCurve[##2](a:,A:,B:,b:) \:PutLbl(##3)  }      }\:Temp
           \Define\:Temp{
\def\:XYLbl[##1##2;##3]{
   \IF  \EqText(+,##1)  \THEN  \Vb=-1; \Va=##2;
                        \ELSE  \Vb= 1; \Va=##1##2;
   \FI
   \MoveToLoc(x:)
   \IF  \LtDec(\Va,0.5)  \THEN
      \MarkLoc(b:)  \MoveToLoc(EdgeBack)  \MarkLoc(a:)
      \DSeg[\Val\Vb]\RotateTo(EdgeFront,x:)
   \ELSE
      \MarkLoc(a:)  \Va-0.5;
      \MoveToLoc(EdgeFront)  \MarkLoc(b:)
      \DSeg[\Val\Vb]\RotateTo(EdgeBack,x:)
   \FI
   \Va*2;
   \MoveToLoc(a:)   \CSeg[\Val\Va]\Move(a:,b:)
   \:PutLbl(##3)  }
            }\:Temp           \Define\:Temp{
\def\:XXLbl[##1##2;##3]{
   \LSeg\Va(x:,y:)
\IF  \LtDec(\Va,0.01) \THEN
   \MoveToLoc(x:)
   \DSeg\RotateTo(EdgeBack,EdgeFront)
   \MoveF(0.1pt\du)  \MarkLoc(y:)
\FI  
   \IF  \EqText(+,##1)  \THEN
       \Vb=-90;  \Va=##2;
   \ELSE
       \Vb=90;   \Va=##1##2;
   \FI
   \IF  \LtDec(\Va,0.333)  \THEN
      \MoveToLoc(x:)    \MarkLoc(b:)
      \MoveToLoc(EdgeBack)  \MarkLoc(a:)
   \ELSE   \IF  \LtDec(\Va,0.666)  \THEN
      \MoveToLoc(x:)   \MarkLoc(a:)
      \MoveToLoc(y:)   \MarkLoc(b:)  \Va-0.3333;
   \ELSE
      \MoveToLoc(y:)   \MarkLoc(a:)
      \MoveToLoc(EdgeFront)   \MarkLoc(b:)  \Va-0.666;
   \FI  \FI
   \Va*3;
   \DSeg\RotateTo(a:,b:)  \Rotate(\Val\Vb)
   \MoveToLoc(a:)   \CSeg[\Val\Va]\Move(a:,b:)
   \:PutLbl(##3)  }
            }\:Temp    \Define\LabelSpec{
   \TextPar\Define\:EdgeLabel }
\def\PictLabel#1{\Object\:Temp{#1}\:Temp}
\LabelSpec(1){\Text(--#1--)}
\fi
\:CheckOption{spread}\if:option
   \:DefineExt\DiagramSpec(1){\endgroup
    \:C=0;  \let\:Next=\:DiagNodes  \:Next#1&&
    \Indirect\let<DiagNod:\Val\:C>=\relax }

             \Define\:Temp{
\def\:DiagNodes##1&{
   \def\:Temp{##1}
   \ifx \:Temp\empty  \let\:Next=\relax
   \else
      \:tk={##1} \:Ca=\:C;  \:C+1;
      \edef\:Temp{\noexpand\:AddDiagNodes
         (\Val\:C,\Val\:Ca,\the\:tk)}   \:Temp
   \fi  \:Next }
              }\:Temp

\Define\:AddDiagNodes(3){
   \Indirect\def<DiagNod:#2>{\begingroup\:Spaces
      \:DiagNds(#1,#3)}}

       \Define\:Temp{
\def\:DiagNds(##1,##2)(##3){\endgroup
   \Table\:Temp{##3} \:SetDiaNodes##2
   \Indirect<DiagNod:##1>}
        }\:Temp \Define\Diagram{ \Indirect<DiagNod:0> }

\def\:SetDiaNodes#1{\:Temp(0,999){#1}}
\DiagramSpec(\DiagramNode&\Edge)
\Define\DiagramNode(4){ \MoveTo(#2,#3) \Node(#1)(--#4--) }  
\fi
\:CheckOption{grid}\if:option
   \:DefineExt\GridDiagramSpec(1){\endgroup
   \IF  \EqText(,#1)  \THEN  \ELSE
      \:CheckSpecTyp(#1,&)
      \IF  \:Temp  \THEN  \Table\:PolyShapes{u,\noexpand#1}
\Define\:ShapeTyp{u,}
      \ELSE               \Define\:ShapeTyp{}
\:SetPolyNodes#1&,&      \let\:Temp=\:PolyShapes
\Table\:PolyShapes{\:Temp}      \FI
   \FI
   \:DiagEg }\Define\:CheckSpecTyp(2){
   \IF  \EqText(#2,&)  \THEN  \def\:Temp{\EqInt(1,1)}
   \ELSE                      \def\:Temp{\EqInt(1,2)}
   \FI  }\GridDiagramSpec(\Node)(\GridEdge)
                                         \Define\:Temp{
\def\:SetPolyNodes##1,##2&{
   \Define\:PolyShapes{##1,\noexpand##2}
   \:MorePolyNodes   }                   }\:Temp

\Define\:MorePolyNodes{
    \def\:Temp{\Define\:PolyShapes}
    \Define\:Next{\:GetPolyNodes}    \:Next  }

                                               \Define\:Temp{
\def\:GetPolyNodes##1,##2&{
   \IF \EqText(,##1) \THEN     \Define\:Next{}
   \ELSE
      \expandafter\expandafter\expandafter\:Temp\expandafter{
              \:PolyShapes & ##1,\noexpand##2 }
   \FI    \:Next}}                              \:Temp
\Define\GridSpace(2){
   \:edef\:VGridSp{#2}   \:edef\:HGridSp{#1}}
\GridSpace(20,20)\Define\AlignGrid(2){
   \def\:XGridEntry{#1}     \def\:YGridEntry{#2}}
\AlignGrid(0,0)

\Define\GridDiagram(2){  \MarkLoc(GridOrg)
   \IF  \LtInt(#1,2)  \:aldwarn{11}{#1,#2} \THEN  \FI
   \IF  \LtInt(#2,2)  \:aldwarn{11}{#1,#2} \THEN  \FI
   \EntryExit(\:XGridEntry,\:YGridEntry,0,0)
   \Do(0,#1){ \:C=\DoReg;  \Indirect\DecVar<y.\Val\:C>  }
   \Do(0,#2){ \:C=\DoReg;  \Indirect\DecVar<x.\Val\:C> }
   \Define\:Nrows{#1}       \Define\:Ncols{#2}
   \:VGridSpace }
                   \Define\:VGridSpace(1){
   \IF  \EqText(,#1)  \THEN
          \Define\:Temp{\:VGridSp,0,1000}
   \ELSE  \Define\:Temp{#1}              \FI
   \Table\:VerAdj{\:Temp}
   \:C=0;  \:VerAdj(0,99){\:Count}
   \IF  \LtInt(\:C,\:Nrows) \THEN
      \:C=-\:C;   \:C+\:Nrows;    \:C-1;
\IF \LtInt(\Val\:C,\:Nrows)  \THEN
   \def\:tempA{\def\:Temp}
   \IF  \GtInt(\Val\:C,0)  \THEN
      \Do(1,\Val\:C){  \expandafter\expandafter
         \expandafter\:tempA\expandafter{
                   \:Temp & \:VGridSp,0,1000}}
   \FI
   \Table\:VerAdj{\:Temp}
\FI
   \ELSE   \IF \GtInt(\:Nrows,1) \THEN
      { \def&{\string&}\:aldwarn4{#1} }
   \FI   \FI
   \:HGridSpace}
                   \Define\:HGridSpace(1){
   \IF  \EqText(,#1)  \THEN
          \Define\:Temp{\:HGridSp,0,1000}
   \ELSE  \Define\:Temp{#1}              \FI
   \Table\:HorAdj{\:Temp}
   \:C=0; \:HorAdj(0,99){\:Count}
   \IF  \LtInt(\:C,\:Ncols) \THEN
      \:C=-\:C;   \:C+\:Ncols;   \:C-1;
\IF \LtInt(\:C,\:Ncols)  \THEN
   \def\:tempA{\def\:Temp}
   \IF  \GtInt(\:C,0)  \THEN
      \Do(1,\Val\:C){  \expandafter\expandafter
         \expandafter\:tempA\expandafter{
                   \:Temp & \:HGridSp,0,1000}}
   \FI
   \Table\:HorAdj{\:Temp}
\FI
   \ELSE \IF \GtInt(\:Ncols,1) \THEN
       { \def&{\string&}\:aldwarn4{#1} }
   \FI   \FI
   \:GridEntries}

                   \Define\:GridEntries{\begingroup\:Spaces\::GridEntries}

\Define\::GridEntries(1){\endgroup
   \:bgDiTags
   \:C=0;  \Define\:Next{\:C+1;\:GetGridRows}  \:Next#1//
   \Do(1,\:Nrows){\:C=\DoReg;  \:Ca=0;
   \Indirect<row.\Val\:C>(0,99){\:Ca+1;
      \IF  \GtInt(\Val\:C,\:Nrows)  \THEN  \:aldwarn5{}  \FI
      \IF  \GtInt(\Val\:Ca,\:Ncols) \THEN  \:aldwarn6{}  \FI
      \:GetEntrySize}}
   \IF  \GtInt(\:Nrows,1)  \THEN
   \Do(2,\:Nrows){                 \:C=\DoReg;
   \Indirect{\Va=-}<y.\Val\:C>;  \:C-1;
   \Indirect{\Va+}<y.\Val\:C>;
   \Va*\:YGridEntry;            \:C+1;
   \Indirect{\Va+}<y.\Val\:C>;  \:C-1;
   \Indirect<y.\Val\:C>+\Va;         }
\:C=0;  \:VerAdj(0,99){\:C+1; \:AdjGridHeight}
\Do(2,\:Nrows){     \:C=\DoReg;  \:C-1;
   \Indirect{\Va=}<y.\Val\:C>;  \:C+1;
   \Indirect<y.\Val\:C>+\Va;         }    \FI
\IF  \GtInt(\:Ncols,1)  \THEN
   \Do(2,\:Ncols){                   \:C=\DoReg;
   \Indirect{\Va=+}<x.\Val\:C>;  \:C-1;
   \Indirect{\Va-}<x.\Val\:C>;
   \Va*\:XGridEntry;             \:C+1;
   \Indirect{\Va+}<x.\Val\:C>;  \:C-1;
   \Indirect<x.\Val\:C>+\Va;         }
\:C=0;  \:HorAdj(0,99){\:C+1; \:AdjGridWidth}
\Do(2,\:Ncols){     \:C=\DoReg;  \:C-1;
   \Indirect{\Va=}<x.\Val\:C>; \:C+1;
   \Indirect<x.\Val\:C>+\Va;         }    \FI
\Do(1,\:Nrows){  \:C=\DoReg;
   \Indirect{\Indirect<y.\Val\:C>=-}<y.\Val\:C>; }
   \let\:TagNode=\::TagNode
\let\:EdgeNode=\::EdgeNode

\Do(1,\:Nrows){  \:C=\DoReg;
   \Do(1,\:Ncols){   \:Ca=\DoReg;
      \Indirect<\Val\:C..\Val\:Ca>}}
    \Do(1,\:Nrows){  \:C=\DoReg;
   \Do(1,\:Ncols){   \:Ca=\DoReg;
      \Indirect\let<\Val\:C..\Val\:Ca>=\:undefined}}
   \Table\:PolyBaseEdges{\:BaseEdges}
\:C=-1;  \:PolyBaseEdges(0,1){\:Count}
\IF  \EqInt(\:C,1)  \THEN
   \:PolyBaseEdges(1,999){\:InsertBaseEdge}
\FI
   \let\:CurrEdge=\:DiagramEdge
\:endDiTags }
                              \Define\:Temp{
\def\:GetGridRows##1//{
   \IF  \EqText(,##1)  \THEN  \let\:Next=\relax
   \ELSE   {\:C-1; \:TrcDiag{\immediate\write16{...read\space
                                        row\space \Val\:C}}}
      \def\Defend{\noexpand\noexpand\noexpand}
\def\:Comma{,}  \let\:CsCom=\,
\def\,{\noexpand\:Comma}
\let\:Temp=&  \def&{\:Temp\:ShapeTyp}

      \Indirect\Table<row.\Val\:C>{\:ShapeTyp##1}
      \let\Defend=\noexpand\let&=\:Temp    
   \FI  \:Next }              }\:Temp\Define\:GetEntrySize(1){
   \IF \EqText(,#1)  \THEN \ELSE
     \:TrcDiag{{  \:C-1;  \:Ca-1;  \:tk={#1}
    \immediate\write16{\Val\:C..\Val\:Ca\space\space\the\:tk}}}
     \:GetEntrySizeA(#1,)  \FI  }\Define\:GetEntrySizeA(3){
   \def\:Temp{\:tk=}    \:AddBaseEdges(#3)
   \:PolyShapes(0,99){\:GetEntrySizeB(#1,#2)}}
               \Define\:Temp{
\def\:GetEntrySizeB(##1,##2)(##3,##4){
   \IF  \EqText(,##2)  \THEN \ELSE
      \IF  \EqText(##1,##3)  \THEN
         \Indirect\Define<\Val\:C..\Val\:Ca>{
   \:AddGridNode(##4,##2)}
         \let\:SvWg=~ \let~=\relax
         \edef\:Temp{\noexpand##4(.;)(--##2--)}
         \let~=\:SvWg
         \FigSize\Va\Vb{\:Temp}   \Va/2; \Vb/2;
         \Indirect{\:Ve=}<x.\Val\:Ca>;
         \IF  \GtDec(\Va,\:Ve)  \THEN
            \Indirect<x.\Val\:Ca>=\Va;      \FI
         \Indirect{\:Ve=}<y.\Val\:C>;
         \IF  \GtDec(\Vb,\:Ve)  \THEN
            \Indirect<y.\Val\:C>=\Vb;
   \FI \FI \FI }}  \:Temp  \Define\:AddGridNode(2){
   \:C-1; \:Ca-1;    \MoveToGrid(\Val\:C,\Val\:Ca)
   \let\:SvWg=~\let~=\relax
   \edef\:Temp{ \noexpand #1(\Val\:C..\Val\:Ca)(--#2--) }
   \let~=\:SvWg
   \:Temp    \:C+1; }\Define\MoveToGrid(2){
    \IF \LtInt(#1,0) \THEN  \:aldwarn3{(#1,#2)}  \FI
    \IF \LtInt(#2,0) \THEN  \:aldwarn3{(#1,#2)}  \FI
    \IF \GtInt(#1,\:Nrows) \THEN  \:aldwarn3{(#1,#2)}  \FI
    \IF \GtInt(#2,\:Ncols) \THEN  \:aldwarn3{(#1,#2)}  \FI
    \Indirect{\Va=}<x.#2>;
    \Indirect{\Vb=}<y.#1>;
    \MoveToLoc(GridOrg)
    \Move(\Val\Va pt\du,\Val\Vb pt\du)             }
\Define\:AddBaseEdges(1){
   \IF  \EqText(,#1)  \THEN  \def\:Next{}
   \ELSE
      \:AddBaseEdgesB(#1)
   \FI \:Next}

\Define\:AddBaseEdgesB(2){
   \expandafter\expandafter\expandafter\:Temp
      \expandafter{\:BaseEdges &}
   \edef\:BaseEdges{  \the\:tk \Val\:C,\Val\:Ca,#1 }
   \def\:Next{\:AddBaseEdges(#2)}}

\Define\:BaseEdges{0,0,0,0}\Define\:AdjGridWidth(3){
   \Indirect{\Va=}<x.\Val\:C>;    \Va+#1;
   \IF \LtDec(\Va,#2) \THEN \Va=#2;  \ELSE
   \IF \GtDec(\Va,#3) \THEN \Va=#3;  \FI  \FI
   \Indirect<x.\Val\:C>=\Va;  }\Define\:AdjGridHeight(3){
   \Indirect{\Va=}<y.\Val\:C>;    \Va+#1;
   \IF \LtDec(\Va,#2) \THEN \Va=#2;  \ELSE
   \IF \GtDec(\Va,#3) \THEN \Va=#3;  \FI  \FI
   \Indirect<y.\Val\:C>=\Va;  }\Define\:InsertBaseEdge(3){
   \:C=#1;  \:Ca=#2;  \:TargetNode(#3,)
\IF  \EqInt(\:C,1) \THEN  \:GetGridLbl(#3) \FI
\:C=#1;    \:Ca=#2;
\expandafter\:GetTarget\:Temp..
   \:C=#1;   \:C-1;   \:Ca=#2;  \:Ca-1;
   \edef\:Temp{\noexpand\:DiagramEdge(\Val\:C..\Val\:Ca,\:Temp\the\:tk)}
   \:Temp} \Define\:TargetNode(2){
   \def\:Temp{#1}
   \IF \EqText(,#2)  \THEN \:C=0;  \:tk={}
   \ELSE \:C=1;  \FI }

\Define\:GetGridLbl(2){ \:tk={,#2} }        \Define\:Temp{
\def\:GetTarget##1##2..##3##4..{
   \:C-1; \:Ca-1;  \edef\:tempa{\Val\:C..\Val\:Ca}
   \IF      \EqText(+,##1)  \THEN
       \:C+##2;  \:Ca##3##4;  \edef\:Temp{\Val\:C..\Val\:Ca}
   \ELSE\IF \EqText(-,##1)  \THEN
       \:C-##2;  \:Ca##3##4;  \edef\:Temp{\Val\:C..\Val\:Ca}
   \ELSE                     \def\:Temp{##1##2..##3##4}  \FI\FI
   \:TrcDiag{\immediate\write16{\:tempa-->\:Temp}}    }
         }\:Temp
\fi
\:CheckOption{tree}\if:option
   \Define\:MoveH(2){
   \ifx H\:TreeDir   \Move(0,-#2)
   \else             \Move(#1,0)  \fi  }

\Define\:MoveV(2){
   \ifx H\:TreeDir   \Move(#1,0)
   \else             \Move(0,#2)  \fi  }

\Define\:MoveHV(2){
   \ifx H\:TreeDir   \Move(0,#2)
   \else             \Move(#1,0)  \fi  }

\Define\:DistH(2){
   \ifx H\:TreeDir   \Va=#2;  \else  \Va=#1;  \fi}
\def\:oochild{0} \Define\:MoveLFr(2){
  \ifx H\:TreeDir \MoveToNode(#2,0,-1) \else \MoveToNode(#2,1,0)  \fi}
\Define\:FrDs(2){  \MoveToLoc(:a) \MarkLoc(:a')
   \if H\:TreeDir\relax  \MoveToNode(#2,0,-1)
   \else \MoveToNode(#2,1,0) \fi
   \MarkLoc(:a)
   \:tempb(\DoReg,\DoReg){\:MoveRFr}
   \CSeg\:AddX(:a,:a')  \CSeg\:AddX(:b',:b)  
   \ifx H\:TreeDir
   \IF \GtDec(\:va,0) \THEN   \:vb-\:va; \:va=0;   \FI
\else
   \IF \LtDec(\:vb,0) \THEN   \:va-\:vb; \:vb=0;   \FI
\fi
          }

\Define\:MoveRFr(2){
   \MoveToLoc(:b)       \MarkLoc(:b')
   \ifx H\:TreeDir \MoveToNode(#1,0,1) \else \MoveToNode(#1,-1,0)  \fi
   \MarkLoc(:b)  }
\Define\:AddX(2){ \ifx H\:TreeDir  \:va+#2;  \else  \:vb+#1; \fi }
\Define\:Temp{  \let\:aprsnd=& }
\:Temp \Define\:left(2){ \def\:frL{#1}}
\Define\:right(2){         \let&=\relax
   \edef\:frL{\:frL,#2}    \let&=\:aprsnd  }
\Define\:copy(1){          \let&=\relax
   \edef\:frL{\:frL & #1}  \let&=\:aprsnd  }

\Define\:addleft(2){   \let&=\relax
   \edef\:frL{\:frL&#1}   \let&=\:aprsnd}

\Define\:both(1){
   \IF \GtInt(#1,0) \THEN
      \Do(1,#1){
         \:tempa(\DoReg,\DoReg){\:addleft}
         \:tempb(\DoReg,\DoReg){\:right}  }
    \FI  }           
   \:DefineExt\TreeSpec(1){\endgroup
   \IF  \EqText(,#1)  \THEN   \ELSE
      \:TrNodes#1&&\let  \:LeafNode=\:TreeNode
   \FI  \:DecideLeafNode  }

\def\:Temp{\catcode`\ =10 \catcode`\^^M=5 \catcode`\&=4 }
\catcode`\ =9 \catcode`\^^M=9  \catcode`\&=13
\def\:TrNodes#1&#2&{
   \IF  \EqText(,#2)  \THEN
      \Define\:TreeNode(2){#1(##1)(--##2--)}
      \let\:Next=\relax
   \ELSE
      \Define\:TreeNode{
         \expandafter\:CondTreeNode\:pars(#1)
         \expandafter\:CondTreeNode\:pars(#2)  }
       \def\:tempa{ \Define\:TreeNode }
       \let\:Next=\:DecideTreeNodes
   \FI \:Next}

\def\:DecideTreeNodes#1&{
   \IF  \EqText(,#1)  \THEN \let\:Next=\relax
      \def\:tempa{\Define\:TrNd}
      \expandafter\expandafter\expandafter
         \:tempa\expandafter{  \:TreeNode  \:Temp  }
      \def\:TreeNode(##1,##2){
           \def\:pars{(##1)(##2)}  \:TrNd}
   \ELSE
      \expandafter\expandafter\expandafter
         \:tempa\expandafter{  \:TreeNode
             \expandafter\:CondTreeNode\:pars(#1)}
   \FI  \:Next}
                \:Temp

                \Define\:Temp{
\def\:CondTreeNode(##1)(##2,##3)(##4,##5){
   \IF \EqText(##2,##4)  \THEN
      \def\:Temp{##5(##1)(--##3--)}
   \FI}
                }\:Temp\:DefineExt\:DecideLeafNode(1){\endgroup
   \IF  \EqText(,#1)  \THEN  \ELSE
      \Define\:LeafNode(2){#1(##1)(--##2--)}
   \FI
   \:DecideTreeEdge}\:DefineExt\:DecideTreeEdge(1){\endgroup
   \IF \EqText(,#1) \THEN  \ELSE
      \Define\:TreeEdge(2){
   \Indirect{\let\:Temp=} <##2.mvto>
   \ifx \:Temp\:ChkInv \else
      \:TrcDiag{\immediate\write16{##1,##2}}
      \ifx H\:TreeDir   \MoveToNode(##1,\:EntryX,0)
      \else             \MoveToNode(##1,0,\:EntryY)  \fi
      \:MvToDivider##1..   \MarkLoc(EdgeGuide)
      #1(##1,##2)
   \fi } 
   \FI} \Define\Tree(1){
   \Define\:PolyVerTreeSp{#1}
   \Define\:BareTr(1){,##1}
   \begingroup   \:Spaces  \:Tree }

\Define\LTree(1){
   \Define\:PolyVerTreeSp{#1} \:LTree  }

\catcode`\#=13
\Define\:LTree{\def#{\Defend&}  \let\-=#  \let\:BareTr=\relax
  \begingroup \catcode`\#=13   \:Spaces  \:Tree }
\catcode`\#=6

\Define\:Tree(1){\endgroup
   \:bgDiTags  
   \let\:MergTree=\relax
\ifx \:Cspace\:InInx  \let\:MergTree=\::MergTree  \fi
\:TrSp(0,99){\:copt}
   \ifx H\:TreeDir      \let\:tempc=\Va
   \def\:TreeEnEx{\EntryExit(\:EntryX,\:EntryY,0,0)}
\else                \let\:tempc=\Vb
   \def\:TreeEnEx{\EntryExit(\:EntryX,\:EntryY,0,0)}  \fi
\:C=-1;
   \let\:Next=\:GetTreeRows  \:Next#1//
   \Do(1,\Val\:C){ \:Ca=\DoReg;
   \Indirect{\Va=-}<y.\Val\:Ca>;  \:Ca-1;
   \Indirect\DecVar<x.\Val\:Ca>
\ifx H\:TreeDir \Indirect<x.\Val\:Ca>=-\:EntryX;
\else           \Indirect<x.\Val\:Ca>=\:EntryY;  \fi
\Indirect<x.\Val\:Ca>+1;
\Indirect{\Indirect<x.\Val\:Ca>*}<y.\Val\:Ca>;
\Indirect<x.\Val\:Ca>/2;  
   \Indirect{\Va+}<y.\Val\:Ca>;
   \ifx H\:TreeDir   \Va*-\:EntryX;
   \else             \Va*\:EntryY;  \fi
   \:Ca+1;  \Indirect{\Va+}<y.\Val\:Ca>;  \:Ca-1;
   \Indirect<y.\Val\:Ca>+\Va;
   \Indirect<y.\Val\:Ca>/2;}\:Ca=-1;
\ifx  \:PolyVerTreeSp\empty  \else
   \let\:tempa=\:PolyVerTreeSp
   \Table\:PolyVerTreeSp{\:tempa}
  \:PolyVerTreeSp(0,99){\:AddVerTreeSp}
\fi
\:Cb=\:Ca;  \:Cb+1;
\IF \GtInt(\:C,\:Cb)  \THEN
  \:Cb+1;
   \Do(\Val\:Cb,\Val\:C){\:AddVerTreeSp(\:VerTreeSp)}
\ELSE \IF \GtInt(\:Cb,\:C) \THEN
   \:aldwarn1{}\FI\FI

   \Indirect{\let\:va=}<x.0>
\Indirect{\let\:vb=}<y.0> 
   \let\:TagNode=\::TagNode
\let\:EdgeNode=\::EdgeNode

\Do(0,\Val\:C){ \:Ca=-1;  \:Cb=-1;
  \Indirect<row.\DoReg>(0,99){
      \:Ca+1;  \:DefSubTree}  }
\gdef\:GetNodesAddr{}    \:AddrCount=1;
\Indirect<0..0>  \global\let\:GetNodesAddr=\:undefined
   \ifx \:BareTr\relax     \let\:EnterTreeEdge=\:::EnterTreeEdge   
\else                \let\:EnterTreeEdge=\::EnterTreeEdge    \fi
\:C-1;
\Do(0,\Val\:C){ \:C=\DoReg; \:Ca=-1;  \:Cb=\DoReg;    \:Cb+1;  \:Cc=-1;
  \Indirect<row.\DoReg>(0,99){
      \:Ca+1;  \:EnterTreeEdge}  } 
   \let\:CurrEdge=\:TreeEdge
\let\:tempa=\:MvToDivider
\def\:MvToDivider##1..##2..{\Move(0.001pt\du,0.001pt\du)}
\:endDiTags  \let\:MvToDivider=\:tempa  
   \let\-=\:svneg  }

\let\:svneg=\-                     \Define\:Temp{
\def\:GetTreeRows##1//{
   \def\:Temp{##1}
   \ifx \:Temp\empty   \let\:Next=\relax  \else
      \:C+1;
      \ifx  \:BareTr\relax  \else
         \TableData\:Temp\:BareTr{##1}
      \fi
      \Indirect\Table<row.\Val\:C>{\:Temp}
      \def\:tempa{}   \:Vc=0;
\def\:tempb{\:tk=}     \:Ca=-1;
\Indirect<row.\Val\:C>(0,99){\:Ca+1; \:MeasureRow}
\Indirect\DecVar<y.\Val\:C>
\Indirect<y.\Val\:C>=\:Vc;
   \fi  \:Next}
                    }\:Temp\Define\::EnterTreeEdge(3){
   \IF \GtInt(#2,0) \THEN
      \Do(1,#2){    \:Cc+1;
         \edef\:temp{\noexpand\:TreeEdge
            (\Val\:C..\Val\:Ca,\Val\:Cb..\Val\:Cc)
            \noexpand\:C=\Val\:C;  \noexpand\:Ca=\Val\:Ca;}
                       \:temp  }
   \FI }\Define\:::EnterTreeEdge(3){
   \edef\:temp{\:tk={\noexpand\:C=\Val\:C;
                     \noexpand\:Ca=\Val\:Ca;}} \:temp
   \IF \GtInt(#2,0) \THEN
      \Table\:BareTr{#1}
      \:BareTr(0,99){    \:Cc+1;  \the\:tk
         \edef\:temp{\noexpand\:TreeEdgePos
            (\Val\:C..\Val\:Ca,\Val\:Cb..\Val\:Cc)  }
            \:temp  \:TreeLabel }
   \FI     \the\:tk  }

\Define\:TreeEdgePos(2){  \:TreeEdge(#1,#2)  \LTreePos(#1,#2)  }

\Define\:TreeLabel(1){ \EdgeLabel(--#1--) }
\Define\LTreePos(2){   \DSeg\Va(#1,#2)
  \IF  \LtDec(\Va,270) \THEN \LabelPos(0.65;-3;3,)
  \ELSE \LabelPos(+0.65;3;3,)     \FI  }\Define\:DefSubTree(3){ \:tk={#3}
   \edef\:Temp{
      \noexpand\::DefSubTree(#2,\the\DoReg,\Val\:Ca,\Val\:Cb,\the\:tk)}
   \:Cb+#2;   \:Temp}\Define\::DefSubTree(5){
   \Indirect\Object<#2..#3>{
      \let\:ochild=\:oochild \let\:currFrL=\:frL  \let\:currDpL=\:dpL
\def\:dpL{-1} \def\:frL{} 
      \:Ca=#3; \:Cc=#2;
      \:TrSp(0,99){\:unl}
      \:Cc+1;  \:Cb=#4;  \:Cb+1;
      \IF  \GtInt(#1,0) \THEN
         \edef\:parmA{#1} \edef\:parmB{#2}
         \:tk={#5}  \def\:parmC{\the\:tk}
         \def\:Temp{\:Cind }
      \ELSE   \:tk={#5}
         \edef\:Temp{\noexpand  \:Clnd  (#2,\noexpand\the\:tk) }
      \FI
      \edef\:Temp{\expandafter\noexpand\:Temp
         \noexpand\:endSubTr (#1,#2,#3)}
      \:Temp }}\Define\:endSubTr(3){
   \Indirect{\Indirect
   { \global\let}<#2..\Val\:Ca.mvto>= }<#2..\Val\:Ca.mvto>
\MoveToLoc(#2..\Val\:Ca)     \MarkXLoc(#2..\Val\:Ca)
\MoveToLoc(#2..\Val\:Ca;:11)  \MarkXLoc(#2..\Val\:Ca;:11)
\edef\:temp{\noexpand\:AddNodesAddr(#2..\Val\:Ca) }  \:temp
   \:Ca=\:dpL;  \:Ca+1; \xdef\:dpR{\Val\:Ca} \let&=\relax
\xdef\:frR{ #2..#3,#2..#3 & \:frL }
\ifx  \:Cspace\:InInx
   \let&=\:aprsnd
   \:Ca=#2;  \:Ca*#1;  \:Ca*\:ochild;  \:Ca*\:lchild;
\IF  \GtInt(\:Ca,0)  \THEN
    \IF \GtInt(\:currDpL,\:dpR) \THEN \def\:tempc{\:dpR}
\ELSE                         \def\:tempc{\:currDpL}  \FI
\Table\:tempa{\:currFrL}
\Table\:tempb{\:frR} \if H\:TreeDir  \MoveToNode(#2..#3,0,1)
\else \MoveToNode(#2..#3,-1,0) \fi            \MarkLoc(:b)
\:tempa(0,0){\:MoveLFr}   \MarkLoc(:a)
\:va=0;  \:vb=0;  \IF  \GtInt(\:tempc,0)  \THEN
    \let\:MoveToInv=\::MoveToInv  
    \DoReg=0\relax   \:tempa(1,\:tempc){\advance\DoReg by 1 \:FrDs}
\FI  
    \MoveToLoc(a:)    \:MoveH(-\Val\:va,\Val\:vb)
    \MarkXLoc(INc:)
\FI   \fi  } \Define\:Cind{
   \edef\:lchild{\Val\:Cb}  
\def\:oochild{0}  
\:trcTree
\Indirect<\Val\:Cc..\Val\:Cb>[\:InInx]   \:SubTreeAddrs
\let\:dpL=\:dpR  \let\:frL=\:frR  
\MoveToLoc(INx:)  \MarkLoc(-12:)
\MoveToLoc(IN:)   \MarkLoc(-11:)
\MoveToLoc(OUTx:) \MarkLoc(12:)
\MoveToLoc(OUT:)  \MarkLoc(11:) 
\IF  \GtInt(\:parmA,1)  \THEN
   \def\:oochild{1}  
   \Do(2,\:parmA){
      \MoveToLoc(\:OutOutx)
      \:MoveH(\:HorTreeSp,\:HorTreeSp)   
      \:TrSp(0,99){\:spbn}    \:Cb+1;
      \:trcTree
      \Indirect<\Val\:Cc..\Val\:Cb>[\:InInx]  \:SubTreeAddrs
      \MarkLoc(o:)
\MoveToLoc(INx:)  \MarkLoc(-\DoReg2:)
\MoveToLoc(IN:)   \MarkLoc(-\DoReg1:)
\MoveToLoc(OUTx:) \MarkLoc(\DoReg2:)
\MoveToLoc(OUT:)  \MarkLoc(\DoReg1:)
\MoveToLoc(o:) 
      \:MergTree    }
\FI \:C=\:parmB;    \:TrSp(0,99){\:lcalg}
\:ChildLoc(\:AlignA,-12:,-11:,11:,12:)   \MarkLoc(a:)
\:ChildLoc(\:AlignB,INx:,IN:,OUT:,OUTx:) \MarkLoc(b:)
\:C=\:parmB;
\IF  \LtDec(\:AlignC,-1)  \THEN
   \MoveToLoc(a:)  \:MoveH(\:AlignC,\:AlignC)
\ELSE  \IF  \GtDec(\:AlignC,1)  \THEN
   \MoveToLoc(b:)  \:MoveH(\:AlignC,\:AlignC)
\ELSE
   \CSeg[0.5]\Move(b:,a:) \MarkLoc(o:)
   \CSeg[\:AlignC]\Move(o:,b:)
\FI  \FI
\:TrSp(0,99){\:mvpr}
\ifx  H\:TreeDir   \Indirect{\Move(-\Val}<y.\Val\:C>,0)
\else              \Indirect{\Move(0,\Val}<y.\Val\:C>)   \fi
 \MarkLoc(o:)  \:TreeEnEx
\edef\:Temp{\noexpand\:TreeNode(\:parmB..\Val\:Ca,\:parmC)}\:Temp
\ifx H\:TreeDir
   \MoveToNode(\:parmB..\Val\:Ca,0,1)   \MarkLoc(a:)
   \MoveToNode(\:parmB..\Val\:Ca,0,-1)  \MarkLoc(b:)
\else
   \MoveToNode(\:parmB..\Val\:Ca,-1,0) \MarkLoc(a:)
   \MoveToNode(\:parmB..\Val\:Ca,1,0)  \MarkLoc(b:)
\fi
\MoveToLoc(o:)   \CSeg\:MoveHV(o:,a:)
\MarkLoc(a:)  \MarkXLoc(IN:)
\MarkXLoc(INc:) 
\MoveToLoc(o:)   \CSeg\:MoveHV(o:,b:)
\MarkXLoc(OUT:)  \MarkLoc(b:)
\MoveToLoc(o:)   \CSeg\:MoveHV(o:,-12:)   \MarkLoc(-12:)
\MoveToLoc(a:)   \CSeg\:DistH(a:,-12:)
\IF  \LtDec(\Va,0) \THEN
   \ifx  H\:TreeDir
   \else             \Move(\Val\Va,0)   \fi
\ELSE
   \ifx  H\:TreeDir  \Move(0,\Val\Va)
   \else            \fi
  \FI
\MarkXLoc(INx:)
\MoveToLoc(o:)   \CSeg\:MoveHV(o:,OUTx:)   \MarkLoc(OUTx:)
\MoveToLoc(b:)   \CSeg\:DistH(b:,OUTx:)
\IF  \GtDec(\Va,0) \THEN
   \ifx  H\:TreeDir
   \else             \Move(\Val\Va,0)   \fi
\ELSE
   \ifx  H\:TreeDir  \Move(0,\Val\Va)
   \else               \fi
 \FI
\MarkXLoc(OUTx:)  }
\Define\:Clnd(2){
   \MarkLoc(o:)  \:TreeEnEx  \:C=#1;  \:LeafNode(#1..\Val\:Ca,#2)
\ifx H\:TreeDir
   \MoveToNode(#1..\Val\:Ca,0,1) \MarkLoc(IN:)
   \MoveToNode(#1..\Val\:Ca,0,-1)
\else
   \MoveToNode(#1..\Val\:Ca,-1,0) \MarkLoc(IN:)
   \MoveToNode(#1..\Val\:Ca,1,0)               \fi
\MarkLoc(OUT:)   \MoveToLoc(o:)   \CSeg\:MoveHV(o:,IN:)
\MarkXLoc(IN:)   \MarkXLoc(INc:)    \MarkXLoc(INx:)
\MoveToLoc(o:)   \CSeg\:MoveHV(o:,OUT:)
\MarkXLoc(OUT:)  \MarkXLoc(OUTx:)   }
\Define\TreeAlign(3){ \let\:TreeDir=#1
   \def\:EntryX{#2}  \def\:EntryY{#3}    \:AlignTree}

\Define\:AlignTree(3){
   \def\:AlignA{#1}   \def\:AlignB{#2}   \def\:AlignC{#3}}

\TreeAlign(V,0,0)(0,0,0)
\Define\:trcTree{\:TrcDiag{\immediate\write16{\space
   \:parmB..\Val\:Ca,\Val\:Cc..\Val\:Cb}}}
\Define\:ChildLoc(2){
\IF  \LtDec(#1,0)  \THEN \Va=-#1;
                   \ELSE \Va= #1;  \FI
\IF \LtDec(\Va,100) \THEN
   \::ChildLoc(#1,#2)
\ELSE   \Va/100; \:C[\Va]; \Vb=#1;
   \IF  \GtDec(#1,0)   \THEN  \Vb-\:C 00;
   \ELSE  \Vb+\:C 00; \FI
   \edef\:Temp{\noexpand\::ChildLoc
      (\Val\Vb,-\Val\:C2:,-\Val\:C1:,\Val\:C1:,\Val\:C2:)}\:Temp
\FI } \Define\::ChildLoc(5){
   \IF  \LtDec(#1,-2)  \THEN
      \MoveToLoc(#2)  \:MoveH(#1,#1)
   \ELSE \IF  \GtDec(#1,2)  \THEN
      \MoveToLoc(#4)  \:MoveH(#1,#1)
   \ELSE \IF  \LtDec(#1,-1)  \THEN
      \MoveToLoc(#3)   \Va=#1;  \Va+1;
      \CSeg[\Val\Va]\Move(#2,#3)
   \ELSE \IF  \GtDec(#1,1)  \THEN
      \MoveToLoc(#4)   \Va=#1;  \Va-1;
      \CSeg[\Val\Va]\Move(#4,#5)
   \ELSE   \MoveToLoc(#3)
      \CSeg[0.5]\Move(#3,#4)  \:MoveH(#1,#1)
   \FI \FI \FI \FI}\def\:GetIx#1..#2//{\:Ca=#1;\:Cb=#2;}

\Define\::MoveToInv(3){
   \Indirect{\let\:temp=}<#1.mvto>
   \expandafter\ifx\:temp\MoveToInv
      \:GetIx#1//        \ifx H\:TreeDir \:Cb-#3; \else \:Cb-#2; \fi
      \edef\:Temp{\noexpand\MoveToInv(\Val\:Ca..\Val\:Cb,
                     \ifx H\:TreeDir 0,#3 \else -#2,0 \fi)}
      \expandafter\:Temp
   \ELSE
      \ifx H\:TreeDir  \Indirect<#1.mvto>(#1,0,#3)
      \else            \Indirect<#1.mvto>(#1,-#2,0)  \fi
   \FI    }

\def\MoveToInv{\:MoveToInv}
\let\:MoveToInv=\MoveToRect \Define\::MergTree{
   \edef\:Temp{\DoReg=\the\DoReg\relax}
   \Table\:tempa{\:frL}
\Table\:tempb{\:frR}
\:tempa(0,0){\:left}
\:tempb(0,0){\:right}  
\IF \GtInt(\:dpR,\:dpL) \THEN
   \:both(\:dpL)  \:DoReg=\:dpL  \advance\:DoReg by 1\relax
\:tempb(\:DoReg,\:dpR){\:copy}        
   \let\:dpL=\:dpR
\ELSE
   \:both(\:dpR)
\IF  \GtInt(\:dpL,\:dpR) \THEN
   \:DoReg=\:dpR    \advance\:DoReg by 1\relax
   \:tempa(\:DoReg,\:dpL){\:copy}
\FI  
\FI      \:Temp } \Define\:copt(3){\::copt(#3,)}
\Define\::copt(2){
   \IF \EqText(#1,C) \THEN
       \let\:MergTree=\::MergTree  \FI }
\Define\:MeasureRow(3){
   \:TrcDiag{{      \:tk={#1,#2,#3}
       \immediate\write16{\Val\:C..\Val\:Ca\space\space\the\:tk}}}
   \IF  \EqInt(#2,0) \THEN
         \FigSize\Va\Vb{\:LeafNode(x,#3)}
   \ELSE \FigSize\Va\Vb{\:TreeNode(x,#3)} \FI
   \expandafter\expandafter\expandafter\:tempb
      \expandafter{\:tempa &}
   \edef\:tempa{\the\:tk #2,\Val\Va,\Val\Vb}
   \IF \LtDec(\:Vc,\:tempc)  \THEN  \:Vc=\:tempc; \FI  }
\Define\:AddVerTreeSp(1){
   \:Ca+1; \Indirect<y.\Val\:Ca>+#1;
   \Va=#1; \Va*\:TreeEdgeSpec; \Indirect<x.\Val\:Ca>+\Va;   }

\:DefineExt\TreeSpace(3){\endgroup
   \IF \EqText(D,#1) \THEN
      \def\:OutOutx{OUT:}   \def\:InInx{IN:}  \FI
   \IF \EqText(C,#1) \THEN
   \def\:OutOutx{OUT:}   \def\:InInx{INc:}
   \let\:Cspace=\:InInx  \FI 
   \IF \EqText(S,#1) \THEN
      \def\:OutOutx{OUTx:}  \def\:InInx{INx:}   \FI
   \:edef\:HorTreeSp{#2}
   \:edef\:VerTreeSp{#3}  }

\TreeSpace(S,10,20)\:DefineExt\AdjTree(1){\endgroup
   \IF \EqText(#1,) \THEN \Table\:TrSp{,,}
   \ELSE                  \Table\:TrSp{#1} \FI }

\AdjTree()\Define\:unl(3){
   \IF \EqText(#1,L) \THEN
      \IF \EqInt(\:Cc,#2) \THEN \TreeSpace(#3,0) \FI
   \ELSE \IF \EqText(#1,N) \THEN
      \:edef\:Temp{\noexpand\EqText(\Val\:Cc..\Val\:Ca,#2)}
      \IF \:Temp \THEN \TreeSpace(#3,0) \FI
   \FI \FI}\Define\:spbn(3){
   \IF \EqText(#1,B) \THEN
      \:edef\:Temp{\noexpand\EqText(\Val\:Cc..\Val\:Cb,#2)}
      \IF \:Temp \THEN  \:MoveH(#3,#3)
   \FI\FI}\Define\:lcalg(3){
   \IF \EqText(#1,A) \THEN
      \:edef\:Temp{\noexpand\EqText(\Val\:C..\Val\:Ca,#2)}
      \IF \:Temp \THEN
         \:xalg(#3)
   \FI\FI}
\Define\:xalg(2){ \def\:EntryX{#1} \:AlignTree(#2)  }
\Define\:mvpr(3){
   \IF \EqText(#1,M) \THEN
      \:edef\:Temp{\noexpand\EqText(\Val\:C..\Val\:Ca,#2)}
      \IF \:Temp \THEN  \:MoveH(#3,-#3)
   \FI\FI}\Define\TreeEdgeSpec(1){\:edef\:TreeEdgeSpec{#1}}
\TreeEdgeSpec(0.5) \def\:ChkInv{\MoveToInv}

                              \Define\:Temp{
\def\:MvToDivider##1..##2..{
   \ifx H\:TreeDir   \Indirect{\Move(\Val}<x.##1>,0)
   \else             \Indirect{\Move(0,-\Val}<x.##1>)  \fi  }
                              }\:Temp \Define\TreeEdge(2){
   \ifx H\:TreeDir   \HHEdge(#1,#2,EdgeGuide)
   \else             \VVEdge(#1,#2,EdgeGuide)  \fi }
\Define\:AddNodesAddr(1){
   \Define\:temp{\gdef\:GetNodesAddr}
   \expandafter\expandafter\expandafter
      \:temp\expandafter{\:GetNodesAddr & #1  }}

\Define\:SubTreeAddrs{
   \Table\:AddrPoly{ \:GetNodesAddr}
   \:AddrPoly(\Val\:AddrCount,999){\:AddrCount+1;\:RecordAddr}  }

\Define\:RecordAddr(1){\MoveToLoc(#1)     \MarkXLoc(#1)
      \MoveToLoc(#1;:11)  \MarkXLoc(#1;:11)}

\IntVar\:AddrCount\TreeSpec(\Node)()(\TreeEdge) 
\fi
\let\if:option=\:undefined
\let\:CheckOption=\:undefined
\let\:GetOptions=\:undefined
\let\AlDraTex=\:undefined 
\def\:aldwarn#1#2{\immediate
   \write16{---AlDraTeX warning--- \ifcase #1
      insufficient space for arrow head   %0
   \or \string\Tree(too many values)(...) %1
   \or     edge from node #2 to itself    %2
   \or     #2 not a grid point            %3
   \or     too many entries in (#2)       %4
   \or     too many rows: \Val\:C         %5
   \or     row \Val\:C\space has too many columns: \Val\:Ca    %6
   \or     \Val\:C\space(>5) entries in \string\BarChartSpec   %7
   \or     more than one bar in \string\BarChartSpec(\the\:tk) %8
   \or     no font for \string\NewCIRCNode, trying `\string
           \font\string\CIRC=lcircle10 scaled\string\magstep5'   %9
   \or     \string\PutNode(#2)?                                  %10
   \or     \string\GridDiagram(#2)? less than 2 rows/columns     %11
                                   \fi}}

\:RestoreCatcodes    \endinput

