%% $Id: pstricks-add.tex 656 2022-11-21 08:41:43Z herbert $
%%
%% This is file `pstricks-add.tex',
%%
%% IMPORTANT NOTICE:
%%
%% Package `pstricks-add.tex'
%%
%% Dominique Rodriguez 
%% Herbert Voss <hvoss@tug.org>
%% Michael Sharpe <msharpe@ucsd.edu>
%%
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN archives
%% in directory macros/latex/base/lppl.txt.
%%
%% DESCRIPTION:
%%   `pstricks-add' is a PSTricks package for additionals to the standard
%%         pstricks package
%%
\csname PSTricksAddLoaded\endcsname
\let\PSTricksAddLoaded\endinput
%
% Requires some packages
\ifx\PSTricksLoaded\endinput\else \input pstricks \fi
\ifx\PSTplotLoaded\endinput\else  \input pst-plot \fi
\ifx\PSTnodesLoaded\endinput\else \input pst-node \fi
\ifx\PSTarrowLoaded\endinput\else \input pst-arrow \fi
\ifx\PSTthreeDLoaded\endinput\else\input pst-3d   \fi
\ifx\MultidoLoaded\endinput\else  \input multido  \fi
\ifx\PSTXKeyLoaded\endinput\else  \input pst-xkey \fi
\ifx\PSTmathLoaded\endinput\else  \input pst-math \fi
%
\def\fileversion{3.93}
\def\filedate{2022/11/21}
\let\pstricksaddFV\fileversion
\message{`pstricks-add' v\fileversion, \filedate\space (dr,hv)}
%
\edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax
\SpecialCoor
\pst@addfams{pstricks-add}
%
%% prologue for postcript
\pstheader{pstricks-add.pro}%
%
\def\psGetSlope(#1,#2)(#3,#4)#5{% 4 values without a dimen! #5 is a macro
  \pst@dimm=#1pt%
  \advance\pst@dimm by -#3pt%
  \pst@dimn=#2pt%
  \advance\pst@dimn by -#4pt
  \pst@divide{\pst@dimn}{\pst@dimm}#5}
%
\def\psGetDistance(#1,#2)(#3,#4)#5{% 4 values without a dimen! #5 is a macro
  \pst@dimm=#1pt%
  \advance\pst@dimm by -#3pt%
  \pst@dimn=#2pt%
  \advance\pst@dimn by -#4pt
  \pst@pyth\pst@dimm\pst@dimn\pst@dimo
  \edef#5{\strip@pt\pst@dimo}
}%
%--------------------------------------- small stuff -------------------------------
\define@boolkey[psset]{pstricks-add}[Pst@]{CMYK}[true]{}
\psset[pstricks-add]{CMYK=true}
%
\def\defineTColor{\@ifnextchar[{\defineTColor@i}{\defineTColor@i[]}}
\def\defineTColor@i[#1]#2#3{%     "semi transparency colors"
  \def\pst@tempA{#1}%
  \newpsstyle{#2}{%
     fillstyle=vlines,hatchwidth=0.1\pslinewidth,
     hatchsep=1\pslinewidth,hatchcolor=#3}%
  \ifx\pst@tempA\@empty\else\psset{#1}\fi%
}
\defineTColor{TRed}{red}
\defineTColor{TGreen}{green}
\defineTColor{TBlue}{blue}
%
\def\rmultiput{\pst@object{rmultiput}}
\def\rmultiput@i#1{%
  \pst@killglue%
  \begingroup%
  \use@par%
  \@ifnextchar({\rmultiput@ii{#1}}{\rmultiput@ii{#1}(\z@,\z@)}}
\def\rmultiput@ii#1(#2){%
  \if@star\rput*(#2){#1}\else\rput(#2){#1}\fi
  \@ifnextchar({\rmultiput@ii{#1}}{\endgroup}}

% #1: (x,y)  #2: rotAngle   #3: object
\def\psrotate{\pst@object{psrotate}}
\def\psrotate@i(#1)#2{%
  \pst@killglue
  \begingroup%
  \use@par\pst@makebox{\psrotate@ii(#1){#2}}}
\def\psrotate@ii(#1)#2{%
  \pst@getcoor{#1}\pst@tempA
  \pst@getangle{#2}\pst@tempB
  \leavevmode
  \pst@Verb{
     gsave
     { \pst@tempA /yRot ED /xRot ED 
       \pst@tempB dup cos /cosA ED sin /sinA ED
       /ax cosA def
       /by sinA def
       /cx sinA neg def
       /dy cosA def
       /ex xRot cosA mul neg xRot add yRot sinA mul add def
       /fy xRot sinA mul neg yRot add yRot cosA mul sub def
       [ax by cx dy ex fy] concat } \tx@TMChange 
     }%
    \box\pst@hbox
  \pst@Verb{ \tx@TMRestore grestore  }\endgroup
  \ignorespaces}
%
% [#1]: obtargs; (#2,#3): center; {#4}: factor; {#5}: object
\def\psHomothetie{\def\pst@par{}\pst@object{psHomothetie}}
\def\psHomothetie@i(#1)#2{%
  \begin@SpecialObj%
  \pst@getcoor{#1}\pst@tempA% converts the coordinates without a unit into pt
  \pst@makebox{\psHomothetie@ii{#2}}}% put the contents into a box
\def\psHomothetie@ii#1{%
  \pst@Verb{%
    { \pst@tempA  /yH ED /xH ED  
      [#1 0 0 #1 #1 xH mul neg xH add #1 yH mul neg yH add] concat }
      \tx@TMChange }%
  \box\pst@hbox%
  \pst@Verb{ \tx@TMRestore }%
  \end@SpecialObj}
%
\define@key[psset]{pstricks-add}{intSeparator}{\def\psk@intSeparator{#1}}
\psset{intSeparator={,}}
%
\def\psFormatInt{\def\pst@par{}\pst@object{psFormatInt}}
\def\psFormatInt@i#1{{%
  \pst@killglue
  \use@par
  \count1=#1\count2=\count1
  \ifnum\count1=0 0\else
    \ifnum\count1>999999
    \count3=\count1
    \divide\count3 by 1000000
    \the\count3\psk@intSeparator\relax
    \multiply\count3 by 1000000
    \advance\count1 by -\count3 % modulo 1000000
  \fi%
  \ifnum\count2>999
    \count3=\count1
    \divide\count3 by 1000
    \ifnum\count2>99999
	\ifnum\count3<100 0\fi
	\ifnum\count3<10 0\fi
    \fi%
    \the\count3\psk@intSeparator\relax
    \multiply\count3 by 1000
    \advance\count1 by -\count3 %modulo 1000
  \fi%
  \ifnum\count2>999
    \ifnum\count1<100 0\fi
    \ifnum\count1<10 0\fi
  \fi%
  \the\count1
  \fi%
}\ignorespaces}
%
\define@key[psset]{pstricks-add}{braceWidth}{\pst@getlength{#1}\psk@braceWidth}
\define@key[psset]{pstricks-add}{bracePos}{\pst@checknum{#1}\psk@bracePos}
\define@key[psset]{pstricks-add}{braceWidthInner}{\pst@getlength{#1}\psk@braceWidthInner}
\define@key[psset]{pstricks-add}{braceWidthOuter}{\pst@getlength{#1}\psk@braceWidthOuter}
%
\define@boolkey[psset]{pstricks-add}[PST@]{singleline}[true]{}%use \ifPST@metricFunction
\psset{singleline=false}

\def\psbrace{\def\pst@par{}\pst@object{psbrace}}
\def\psbrace@i(#1)(#2)#3{%
  \addbefore@par{ref=lb,linewidth=0.01pt,fillstyle=solid,fillcolor=black}% default setting
  \begin@SpecialObj
  \if@star\def\pst@tempC{true }\else\def\pst@tempC{false }\fi
  \ifx\psk@rot\empty\def\psk@@rot{0}\else\let\psk@@rot\psk@rot\fi
  \def\psk@rot{Alpha \psk@@rot\space add 90 sub}%
  \pst@getcoor{#1}\pst@tempA
  \pst@getcoor{#2}\pst@tempB
  \rput(!
    /ifStar \pst@tempC def
    /radius1 \psk@braceWidthOuter def
    /radius2 \psk@braceWidthInner def
    /Alpha \pst@tempA \pst@tempB 3 -1 roll sub 3 1 roll exch sub atan def 
    gsave  STV CP T /ps@rot \psk@rot\space def grestore 
    /Length \pst@tempA \pst@tempB Pyth2 def
    /Left { Length \psk@bracePos\space mul } bind def
    /Right { Length Left sub } bind def
    /Width \psk@braceWidth def
    /pop4 { pop pop pop pop } def
    gsave
    [ Alpha cos Alpha sin Alpha sin neg Alpha cos \pst@tempA ] concat 
    0 0 moveto
    0 radius2 neg radius2 radius2 neg radius2 arcto pop4
    Left radius2 sub radius1 sub 0 rlineto 
    Left radius2 neg Left radius2 radius1 add neg radius1 arcto pop4
    currentpoint /y@Label ED /x@Label ED
    Left radius2 neg Left radius1 add radius2 neg radius1 arcto pop4
    Right radius2 sub radius1 sub 0 rlineto
    Length radius2 neg Length 0 radius2 arcto pop4
    \ifPST@singleline\else
%    0 Width neg rlineto
      Length radius2 Width add neg Length radius2 sub radius2 Width add neg radius2 arcto pop4
      Right radius2 sub radius1 sub neg 0 rlineto
      Left radius1 add Width radius1 add radius2 add neg radius1 90 180 arc
      Left radius1 sub Width radius1 add radius2 add neg radius1 0 90 arc
      Left radius2 sub radius1 sub neg 0 rlineto 
      radius2 Width neg radius2 270 180 arcn
      0 0 lineto 
      \ifx\psk@fillstyle\relax\else
        gsave
        ifStar { \pst@usecolor\pslinecolor }{ \pst@usecolor\psfillcolor } ifelse 
        fill
      grestore
      \fi 
    \fi
%    \pst@number\pslinewidth setlinewidth \pst@usecolor\pslinecolor stroke
    \ifx\pslinestyle\@none\else
      \pst@number\pslinewidth SLW
      \pst@usecolor\pslinecolor 
      \@nameuse{psls@\pslinestyle}
      \tx@setStrokeTransparency
    \fi
    stroke
    0 0 moveto
    grestore
%   now calculate the label pos
    /Dh radius1 radius2 add Width add def
    \pst@tempA \pst@tempB 3 -1 roll sub 3 1 roll exch sub % dy dx 
    \psk@bracePos\space mul exch \psk@bracePos\space mul  % d'x d'y
    \pst@tempA 3 -1 roll add Dh Alpha cos mul sub	  % d'x x yA
    \psk@nodesepB sub					  % use minus sign to shidt right
    3 1 roll add Dh Alpha sin mul add \psk@nodesepA add 
    exch \tx@UserCoor ){#3}
  \end@SpecialObj}
%
\def\psBrace{\def\pst@par{}\pst@object{psBrace}}
\def\psBrace@i(#1)(#2){%
  \begin@ClosedObj
  \if@star\def\pst@tempC{true }\else\def\pst@tempC{false }\fi
%  \ifx\psk@rot\empty\def\psk@@rot{0}\else\let\psk@@rot\psk@rot\fi
%  \def\psk@rot{Alpha \psk@@rot\space add 90 sub}%
  \pst@getcoor{#1}\pst@tempA
  \pst@getcoor{#2}\pst@tempB
  \addto@pscode{
    /ifStar \pst@tempC def
    /radius1 \psk@braceWidthOuter def
    /radius2 \psk@braceWidthInner def
    /Alpha \pst@tempA \pst@tempB 3 -1 roll sub 3 1 roll exch sub atan def 
%    gsave  STV CP T /ps@rot \psk@rot\space def grestore 
    /Length \pst@tempA \pst@tempB Pyth2 def
    /Left { Length \psk@bracePos\space mul } bind def
    /Right { Length Left sub } bind def
    /Width \psk@braceWidth def
    /pop4 { pop pop pop pop } def
    [ Alpha cos Alpha sin Alpha sin neg Alpha cos \pst@tempA ] concat 
    0 0 moveto
    0 radius2 neg radius2 radius2 neg radius2 arcto pop4
    Left radius2 sub radius1 sub 0 rlineto 
    Left radius2 neg Left radius2 radius1 add neg radius1 arcto pop4
    currentpoint /y@Label ED /x@Label ED
    Left radius2 neg Left radius1 add radius2 neg radius1 arcto pop4
    Right radius2 sub radius1 sub 0 rlineto
    Length radius2 neg Length 0 radius2 arcto pop4
%    0 Width neg rlineto
    Length radius2 Width add neg Length radius2 sub radius2 Width add neg radius2 arcto pop4
    Right radius2 sub radius1 sub neg 0 rlineto
    Left radius1 add Width radius1 add radius2 add neg radius1 90 180 arc
    Left radius1 sub Width radius1 add radius2 add neg radius1 0 90 arc
    Left radius2 sub radius1 sub neg 0 rlineto 
    radius2 Width neg radius2 270 180 arcn
    0 0 lineto }
  \end@ClosedObj
  \ignorespaces}
%  
\newdimen\psparallelogramsep
\define@key[psset]{pstricks-add}{parallelogramsep}[3mm]{\pssetlength\psparallelogramsep{#1}}
\psset[pstricks-add]{parallelogramsep=3mm}
%
\def\psparallelogrambox{\pst@object{psparallelogrambox}}
\def\psparallelogrambox@i{\pst@makebox\psparallelogrambox@ii}
\def\psparallelogrambox@ii{%
	\begingroup
	\pst@useboxpar
	\pst@dima=\pslinewidth
	\advance\pst@dima by \psframesep
	\pst@dimc=\wd\pst@hbox\advance\pst@dimc by \pst@dima
	\pst@dimb=\dp\pst@hbox\advance\pst@dimb by \pst@dima
	\pst@dimd=\ht\pst@hbox\advance\pst@dimd by \pst@dima
% Dirk Osburg modification begin - Jul. 16, 2011
	\divide\psparallelogramsep by 2
	\advance\pst@dima by \psparallelogramsep 
	\advance\pst@dimc by \psparallelogramsep 
% Dirk Osburg modification end
	\setbox\pst@hbox=\hbox{%
		\ifpsboxsep\kern\pst@dima\fi
		\begin@ClosedObj
		\addto@pscode{%
			\psk@cornersize
			\pst@number\pst@dima neg % left
			\pst@number\pst@dimb neg % lower
			\pst@number\pst@dimc % right
			\pst@number\pst@dimd % upper
			.5
% D.G. modification begin - Nov. 28, 2001
%\tx@Frame}%
			\pst@number\psparallelogramsep
			\tx@Parallelogram}%
% D.G. modification end

			\def\pst@linetype{2}%
			\showpointsfalse
		\end@ClosedObj
		\box\pst@hbox
		\ifpsboxsep\kern\pst@dima\fi%
	}%
	\ifpsboxsep\dp\pst@hbox=\pst@dimb\ht\pst@hbox=\pst@dimd\fi
	\leavevmode\box\pst@hbox
	\endgroup%
}

% From the Frame and Rect PostScript macros
\pst@def{Parallelogram}<{%
  /ParallelogramA {
% Dirk Osburg modification begin - Jul. 16, 2011
%%%% old stuff: %%%
%x1 pgs sub y1 moveto
%x1 y2 lineto
%x2 pgs add y2 lineto
%x2 y1 lineto
%x1 pgs sub y1 lineto
%%%% replaced by: %%%
  x1 pgs sub y1 moveto
  x1 pgs add y2 lineto
  x2 pgs add y2 lineto
  x2 pgs sub y1 lineto
  x1 pgs sub y1 lineto
% Dirk Osburg modification end
  closepath} def
%
/pgs ED
CLW mul
/a ED
3 -1 roll
2 copy gt { exch } if
a sub
/y2 ED
a add
/y1 ED
2 copy gt { exch } if
a sub
/x2 ED
a add
/x1 ED
1 index 0 eq {pop pop ParallelogramA } { OvalFrame } ifelse}>
%
\def\parseRP#1;#2;#3\@nil{%check whether arg of refpt contains ;
  \def\arg@A{#1}\def\arg@B{#2}}
%
\def\Put{\pst@object{Put}}%
\def\Put@i{\@ifnextchar({\Put@ii{}}{\Put@ii}}%  
\def\Put@ii#1(#2)#3{{%
  \pst@killglue
  \use@par
  \expandafter\parseRP#1;;\@nil%sets \arg@A, \arg@B
  \ifx\arg@B\@empty% use \rput
    \edef\arg@A{\if@star*\fi\ifx\arg@A\@empty\else[\arg@A]\fi}%
    \expandafter\rput\arg@A(>#2){#3}
  \else% use \uput
    \edef\arg@A{\if@star*\fi%
      \ifx\arg@A\@empty\else{\arg@A}\fi%
      \ifx\arg@B\@empty[0]\else[\arg@B]\fi}%
    \expandafter\uput\arg@A(>#2){#3}
  \fi}\ignorespaces}%

% Modify pst@rot so that a rotation may be specified with a node or ps code
%
\define@key[psset]{pstricks-add}{Os}[0]{\def\PST@Os{#1}}
\psset{Os=0}%
\define@key[psset]{pstricks-add}{Ds}[1]{\def\PST@Ds{#1}}
\psset{Ds=1}%
\define@key[psset]{pstricks-add}{metricInitValue}[0]{\def\PST@metricInitValue{#1}}
\psset{metricInitValue=0}%
\define@boolkey[psset]{pstricks-add}[PST@]{metricFunction}[true]{}%use \ifPST@metricFunction
\psset{metricFunction=false}%
\def\pscurvepoints{\pst@object{pscurvepoints}}%
\def\pscurvepoints@i#1#2#3#4{{%optional [plotpoints=xx]
%  #1=tmin,#2=tmax,#3=function (of t),#4=array root name,
  \pst@killglue
  \use@par
  \edef\my@tempA{#3}% x(t) y(t) expanded
  \expandafter\testAlg\my@tempA|\@nil%
  \pst@Verb{                   % so we can use definitions from tx@Dict
	/unitratio \pst@number\psyunit \pst@number\psxunit div def 
	/unitratiosq unitratio dup mul def
	/t0 #1 def
	/t1 #2 def  
	 t1 t0 sub \psk@plotpoints\space div /dt exch def }%
  \pst@cntc=\psk@plotpoints\relax%\psk@plotpoints=plotpoints-1
  \pst@cntb=\pst@cntc\relax%\psk@plotpoints=plotpoints-1
  \advance\pst@cntc by \@ne\relax%=plotpoints
  \ifx\my@tempD\@empty\pst@Verb{ /Func (#3) cvx def }%
  \else\pst@Verb{ /Func (#3 ) AlgParser cvx def }%
  \fi%
  \pst@Verb{ 
    /#4.X \the\pst@cntc\space array def
    /#4.Y \the\pst@cntc\space array def %
    /#4Delta.X \the\pst@cntc\space array def %
    /#4Delta.Y \the\pst@cntc\space array def %
    /#4Normal.X \the\pst@cntc\space array def %
    /#4Normal.Y \the\pst@cntc\space array def %
    /t #1 def Func 2 copy /priory ED /priorx ED #4.Y  0 3 -1 roll put #4.X 0 3 -1 roll put %
    1 1 \the\pst@cntb\space { dup /j ED dt mul #1 add /t ED Func %x y on stack
    2 copy priory sub dup #4Delta.Y j 3 -1 roll put % x y x y-priory
    unitratiosq mul neg #4Normal.X j 3 -1 roll put % x y x
    priorx sub dup #4Delta.X j 3 -1 roll put % x y x-priorx
    #4Normal.Y j 3 -1 roll put % x y
    2 copy /priory ED /priorx ED % x y
    #4.Y j 3 -1 roll put #4.X j 3 -1 roll put } for %
     }%
  \expandafter\xdef \csname #4pointcount\endcsname {\psk@plotpoints}%
%  \typeout{Created points #40 .. #4\psk@plotpoints}%
}\ignorespaces}%
%
%code to place ticks along polyline
\def\pspolylineticks{\pst@object{pspolylineticks}}%
\def\pspolylineticks@i#1{\@ifnextchar[{\pspolylineticks@ii{#1}}{\pspolylineticks@ii{#1}[]}}%  
\newcount\pst@cntC%
\def\pspolylineticks@ii#1[#2]#3#4#5{{%
%#1= root name,#2=pscode (optional),#3=metric function,#4=first tick,#5=tick count
% Metric function may be a function of x, y (keyword metricFunction)
% or a function of x, y, dx, dy, ds  requiring incremental build
  \addbefore@par{arrows=-,linewidth=\psk@ytickwidth\pslinewidth}%
  \use@par%
  \pst@killglue%there's a leak that can occur here with ticksize--fixed in recent pstricks.tex
  \pst@cntC=\expandafter\csname #1pointcount\endcsname\relax%
  \pst@cntb=\pst@cntC\advance\pst@cntb\m@ne\relax%
  \pst@cntd=\pst@cntC\advance\pst@cntd\@ne\relax%
  \pst@Verb{ % so we can use definitions from tx@Dict in pstricks.pro
    /TDict 20 dict def TDict begin %
    /Func (#3) cvx def /sarray \the\pst@cntd\space array def %
    #2 
    \ifPST@metricFunction 
      0 1 #1.X length 1 sub { 
        /j ED sarray j %
        #1.X j get /x ED #1.Y j get /y ED Func put 
      } for %
    \else %build by increments
      sarray 0 \PST@metricInitValue\space put %
      1 1 #1.X length 1 sub { 
        /j ED sarray j %
        #1.X j 1 sub get 
        /x ED #1.Y j 1 sub get 
        /y ED #1Delta.X j get 
        /dx ED #1Delta.Y j get 
        /dy ED /ds dx dup mul dy dup mul add sqrt def %
        Func sarray j 1 sub get add put 
      } for %
    \fi %\ifPSTfunctionMetric
    \ifnum\Pst@Debug>0
      /str 10 string def 
      /tmpar [(Metric range: [) () (, ) () (])] def %
      tmpar 1 sarray 0 get str cvs put 
      /str 10 string def 
      tmpar 3 sarray \the\pst@cntC\space get str cvs put tmpar 
      tx@NodeDict begin concatstringarray = end %
    \fi % end debug
%compute ticks
  /nl 0 def /nu \the\pst@cntC\space def 
  /smin sarray 0 get def 
  /smax sarray nu get def 
  /Os \ifx\PST@Os\@empty smin \else \PST@Os\space \fi def %
  /Ds \ifx\PST@Ds\@empty smax Os sub 10 div \else \PST@Ds\space \fi def %
  /scount smax Os sub Ds div cvi def %
  /tarray scount 1 add array def %
  /#1Tick.X scount 1 add array def %
  /#1Tick.Y scount 1 add array def %
  /#1TickN.X scount 1 add array def %
  /#1TickN.Y scount 1 add array def %
  0 1 scount { dup Ds mul Os add tarray 3 1 roll put } for %tick positions in tarray
  % find the corresponding s values using binary search
  0 1 scount { 
    dup tarray exch get /s exch def /j exch def %sought metric value,index
    /m nl def /n nu def /k nl nu add 2 div cvi def 20 { s sarray k get lt { %
    /n k def /k k m add 2 div cvi def }{ /m k def /nl k def /k k n add 2 div cvi def } ifelse %
    n 1 sub m le { /nl m def exit } if } repeat %
    sarray n get sarray m get dup 3 1 roll % sm sn sm
    sub dup 0 le { pop pop 0 }{%sm sn-sm 
    exch %sn-sm sm
    s sub neg exch div } ifelse % s->(s-sm)/(sn-sm)
    dup #1Delta.X m 1 add get mul #1.X m get add #1Tick.X j 3 -1 roll put % s on stack
    #1Delta.Y m 1 add get mul #1.Y m get add #1Tick.Y j 3 -1 roll put % 
    #1TickN.X j #1Normal.X m 1 add get put #1TickN.Y j #1Normal.Y m 1 add get put %
  } for %
  \ifnum\Pst@Debug>0
    /tmpar 2 array def 
    /str 4 string def tmpar 0 (Created data for points #1Tick0..#1Tick) put 
    tmpar 1 scount str cvs put tmpar tx@NodeDict begin concatstringarray = end 
  \fi%
  end }% end pst@Verb
%Draw ticks
\multido{\iA=#4+1}{#5}{%
  \pnode(! TDict begin \iA\space scount gt 
    { 1 0 /VV ED /UU ED 0 0 }
    { #1TickN.X \iA\space get #1TickN.Y \iA\space get /VV ED /UU ED #1Tick.X \iA\space get #1Tick.Y \iA\space get } ifelse 
    2 copy /YY ED /XX ED end){#1Tick\iA}%
  \pnode(! TDict begin UU VV end ){#1Normal\iA}%
  \pnode(! TDict begin VV UU neg unitratiosq div end ){#1Tangent\iA}%
  \edef\cmd{\noexpand\psline(\the\pst@yticksizeA;{(! TDict begin UU VV end )})(\the\pst@yticksizeB;{(! TDict begin UU VV end )})}%
  \pscustom{\translate(! TDict begin XX YY end)\cmd}}%
}\ignorespaces}%
%
\define@key[psset]{pstricks-add}{randomPoints}[1000]{\def\psk@randomPoints{#1}}
\define@key[psset]{pstricks-add}{randInit}[rrand]{\def\psk@randInit{#1 }}
\define@boolkey[psset]{pstricks-add}[Pst@]{color}[true]{}
\psset{randomPoints=1000,color=false,randInit}
%
\def\psRandom{\def\pst@par{}\pst@object{psRandom}}%  hv  2004-11-12
\def\psRandom@i{\@ifnextchar({\psRandom@ii}{\psRandom@iii(0,0)(1,1)}}
\def\psRandom@ii(#1){\@ifnextchar({\psRandom@iii(#1)}{\psRandom@iii(0,0)(#1)}}
\def\psRandom@iii(#1)(#2)#3{%
  \def\pst@tempA{#3}%
  \ifx\pst@tempA\pst@empty\psclip{\psframe(#2)}\else\psclip{#3}\fi
  \pst@getcoor{#1}\pst@tempA 
  \pst@getcoor{#2}\pst@tempB 
  \begin@SpecialObj
  \addto@pscode{
    \pst@tempA\space /yMin exch def 
    /xMin exch def
    \pst@tempB\space /yMax exch def 
    /xMax exch def 
    /dy yMax yMin sub def
    /dx xMax xMin sub def
    \psk@randInit srand                 % initializes the random generator
    /getRandReal { rand 2147483647 div } def
    \psk@dotsize % defines /DS ... def
    \@nameuse{psds@\psk@dotstyle}
    \psk@randomPoints {
     \ifPst@color getRandReal getRandReal getRandReal setrgbcolor \fi
     getRandReal dx mul xMin add
     getRandReal dy mul yMin add
     Dot
     \ifx\psk@fillstyle\psfs@solid fill \fi stroke
    } repeat
  }%
  \end@SpecialObj
  \endpsclip
  \ignorespaces
}
%
\define@key[psset]{pstricks-add}{fillcolorA}[blue]{\pst@getcolor{#1}\psk@fillcolorA}
\define@key[psset]{pstricks-add}{fillcolorB}[red]{\pst@getcolor{#1}\psk@fillcolorB}
\define@boolkey[psset]{pstricks-add}[Pst@]{countDots}[true]{}
\psset[pstricks-add]{countDots=false,fillcolorA=blue,fillcolorB=red}
%
\def\psRandomPointArea{\pst@object{psRandomPointArea}}
\def\psRandomPointArea@i#1#2{%
  \pst@killglue
  \addbefore@par{radius=2pt,fillcolorA=blue,fillcolorB=red}%
  \begin@SpecialObj
  \pssetlength\pst@dimc{\psk@radius}
  \addto@pscode{
    realtime srand Rand pop
    4 dict begin
    /Func \ifPst@algebraic (#2) tx@addDict begin AlgParser end cvx \else { #2 } \fi def
    1 1 #1 {
      /i ED
      Rand /x ED
      Func /f ED  % function value
      Rand /y ED 
      gsave x y \tx@ScreenCoor \pst@number\pst@dimc 0 360 arc 
      y f lt { \pst@usecolor\psk@fillcolorA }{ \pst@usecolor\psk@fillcolorB } ifelse 
      fill grestore
      \ifPst@countDots
        x y \tx@ScreenCoor moveto i 4 string cvs 
        \ifpst@psfonts /Helvetica \else /NimbusSanL-Regu \fi 
          findfont 5 scalefont setfont show
      \fi
    } for  
    end
  }%
  \end@SpecialObj
  \ignorespaces
}

%
\def\psComment{\def\pst@par{}\pst@object{psComment}}
\def\psComment@i{\pst@getarrows\psComment@ii}
\def\psComment@ii(#1)(#2)#3{\@ifnextchar[
  {\psComment@iii(#1)(#2){#3}}
  {\psComment@iii(#1)(#2){#3}[\ncline]}}
\def\psComment@iii(#1)(#2)#3[#4]{\@ifnextchar[
  {\psComment@iv(#1)(#2){#3}[#4]}
  {\psComment@iv(#1)(#2){#3}[#4][\rput]}}
\def\psComment@iv(#1)(#2)#3[#4][#5]{%
  \pnode(#1){comment@1}
  \pnode(#2){comment@2}
  \ifx\relax#4\relax\let\pst@ConnectionCommand\ncline
  \else\let\pst@ConnectionCommand#4\fi
  \ifx\relax#5\relax\let\pst@PutCommand\rput
  \else\let\pst@PutCommand#5\fi
  \addbefore@par{npos=0}%
  \begin@SpecialObj%
  \pst@ConnectionCommand{comment@1}{comment@2}
  \if@star\pst@PutCommand*(#1){#3}\else\pst@PutCommand(#1){#3}\fi
  \end@SpecialObj%
  \ignorespaces%
}
%
\define@key[psset]{pstricks-add}{tipAngle}[60]{\pst@getangle{#1}\psk@tipAngle}
\define@key[psset]{pstricks-add}{tipLength}[5mm]{\pst@getlength{#1}\psk@tipLength}
\define@key[psset]{pstricks-add}{tipWidth}[2mm]{\pst@getlength{#1}\psk@tipWidth}
\define@key[psset]{pstricks-add}{tipPos}[0.2]{\def\psk@tipPos{#1 }}
\psset[pstricks-add]{tipAngle=60,tipLength=5mm,tipWidth=2mm,tipPos=0.2}%
%
\def\psCallout{\def\pst@par{}\pst@object{psCallout}}
\def\psCallout@i(#1)#2{%
  \setbox\pst@hbox=\hbox{#2}%
  \begingroup
  \addbefore@par{linewidth=0.1pt,framesep=6pt}%
  \use@par
  \pstVerb{
    /boxsepX { \pst@number\psframesep\space \pst@number\psxunit div } bind def
    /boxsepY { \pst@number\psframesep\space \pst@number\psyunit div } bind def
    /tipEnd { \psk@tipLength\space \pst@number\psxunit div \psk@tipAngle\space PtoC } bind def
    /boxW { \pst@number\wd\pst@hbox\space \pst@number\psxunit div boxsepX 2 mul add } bind def
    /boxH { \pst@number\ht\pst@hbox\space \pst@number\psyunit div boxsepY 2 mul add } bind def
  }%
  \rput(#1){%
    \psline[linearc=0,linejoin=2]%
      (! tipEnd exch \psk@tipWidth\space 2 div \pst@number\psxunit div sub exch)%
      (0,0)
      (! tipEnd exch \psk@tipWidth\space 2 div \pst@number\psxunit div add exch)%
    \psline[linejoin=2]%
      (! tipEnd exch \psk@tipWidth\space 2 div \pst@number\psxunit div sub exch)%
      (! tipEnd exch \psk@tipPos boxW mul sub exch)% lower left
      (! tipEnd exch \psk@tipPos boxW mul sub exch boxH add )% upper left
      (! tipEnd exch 1 \psk@tipPos sub boxW mul add exch boxH add)% upper right 
      (! tipEnd exch 1 \psk@tipPos sub boxW mul add exch)
      (! tipEnd exch \psk@tipWidth\space 2 div \pst@number\psxunit div add exch)%
    \rput[lb](! tipEnd boxsepY add exch \psk@tipPos boxW mul sub boxsepX add exch){#2}%
  }%
  \endgroup
  \ignorespaces
}
%
\def\tx@MovetoByHand{ tx@addDict begin MovetoByHand end }
\def\tx@LinetoByHand{ tx@addDict begin LinetoByHand end }
%/amplHand {.8} def 
%/dtHand 2 def

\def\pslineByHand{\def\pst@par{}\pst@object{pslineByHand}}
\def\pslineByHand@i{%
  \addbefore@par{VarStepEpsilon=2,varsteptol=0.8}
  \pst@getarrows{%
    \begin@OpenObj
    \pst@getcoors[\pslineByHand@ii}}
\def\pslineByHand@ii{%
  \addto@pscode{
    tx@addDict begin 
    /dtHand \psk@VarStepEpsilon\space def
    /amplHand \psk@varsteptol\space def
%    \pst@cp 		% current point
    \tx@setlinejoin 	% hv 2007-10-13
    MovetoByHand
    counttomark 2 div /maxLines ED
    1 1 maxLines { pop LinetoByHand } for
    end
  }%
  \end@OpenObj%
}
%
\def\psRelLine{\def\pst@par{}\pst@object{psRelLine}}
\def\psRelLine@i{\@ifnextchar({\psRelLine@iii}{\psRelLine@ii}}
\def\psRelLine@ii#1{%
  \addto@par{arrows=#1}%
  \psRelLine@iii%
}
\def\psRelLine@iii(#1)(#2)#3#4{{
  \pst@killglue
  \use@par
  \psRelNode(#1)(#2){#3}{#4}
  \pcline(#1)(#4)%%%%      \psline->\pcline   20140722
}\ignorespaces}
%
% #1 options
% draw a parallel line to #2 #3
%     #2---------#3
%         #4----------#5(new node)
% #5 length of the line
% #6 node name
\def\psParallelLine{\def\pst@par{}\pst@object{psParallelLine}}
\def\psParallelLine@i{\@ifnextchar({\psParallelLine@iii}{\psParallelLine@ii}}
\def\psParallelLine@ii#1{\addto@par{arrows=#1}\psParallelLine@iii}
\def\psParallelLine@iii(#1)(#2)(#3)#4#5{{
  \pst@killglue
  \use@par
  \pst@getcoor{#1}\pst@tempA
  \pst@getcoor{#2}\pst@tempB
  \pst@getcoor{#3}\pst@tempC
%  \pst@getlength{#4}\pst@dima
  \pnode(!%
     \pst@tempA /YA exch \pst@number\psyunit div def
     /XA exch \pst@number\psxunit div def
     \pst@tempB /YB exch \pst@number\psyunit div def
     /XB exch \pst@number\psxunit div def
     \pst@tempC /YC exch \pst@number\psyunit div def
     /XC exch \pst@number\psxunit div def
%            
    /dx XB XA sub  def
    /dy YB YA sub  def
    /laenge dy dup mul dx dup mul add sqrt #4 mul def
    /Alpha dy dx atan def 
    laenge Alpha cos mul XC add
    laenge Alpha sin mul YC add ){#5}%
  \pcline(#3)(#5)%%%%   \psline->\pcline   20140722
  }\ignorespaces
}
%
\define@key[psset]{pstricks-add}{startColor}[black]{\colorlet{tempcolor}[rgb]{#1}%   we need rgb
  \pst@getcolor{tempcolor}\ps@startColor}
\define@key[psset]{pstricks-add}{endColor}[white]{\colorlet{tempcolor}[rgb]{#1}%
  \pst@getcolor{tempcolor}\ps@endColor}
\define@key[psset]{pstricks-add}{colorsteps}[256]{\pst@getint{#1}\pst@colorsteps}% hv 20211224
\psset[pstricks-add]{startColor=black,endColor=white,colorsteps=256}
%
\def\psColorLine{\def\pst@par{}\pst@object{psColorLine}}
\def\psColorLine@i{%
  \pst@getarrows{%
    \begin@OpenObj
    \psColorLine@ii}%
}    
\def\psColorLine@ii(#1){\@ifnextchar({\psColorLine@iii(#1)}{\psColorLine@iii(0,0)(#1)}}%
\def\psColorLine@iii(#1,#2)(#3,#4){%
%  \use@par
  \ifx\psk@arrowA\@empty\else\psline[linecolor=\ps@startColor]{->}(!#3 0.5 mul #4 0.5 mul)(#1,#2)\fi
  \ifx\psk@arrowB\@empty\else\psline[linecolor=\ps@endColor]{->}(!#1 0.5 mul #2 0.5 mul)(#3,#4)\fi
  \pst@getcoor{#1,#2}\pst@tempA
  \pst@getcoor{#3,#4}\pst@tempB
  \addto@pscode{
    20 dict begin
    [ \psgetRGBColorValues{\ps@startColor} ] aload length 1 eq { dup dup } if 
      3 copy 3 array astore /startColor ED
    [ \psgetRGBColorValues{\ps@endColor} ] aload length 1 eq { dup dup } if 
      3 copy 3 array astore /endColor ED
%   on stack R1 G1 B1 R2 G2 B2 
    4 -1 roll               % R1 G1 R2 G2 B2 B1
    sub \pst@colorsteps\space div /dB ED      % R1 G1 R2 G2 
    3 -1 roll               % R1 R2 G2 G1 
    sub \pst@colorsteps\space div /dG ED      % R1 R2 
    exch sub \pst@colorsteps\space div /dR ED
    \pst@tempB /Y2 ED /X2 ED 
    \pst@tempA /Y1 ED /X1 ED 
    Y2 Y1 sub X2 X1 sub atan /Angle ED
    Y2 Y1 sub Angle sin dup 0 eq { pop }{ div } ifelse /L_line ED     % line length
    \ifx\psk@arrowA\@empty\else 
      X2 X1 sub L_line div \psk@arrowlength\space mul \pst@number\psxunit mul X1 add /X1 ED
      Y2 Y1 sub L_line div \psk@arrowlength\space mul \pst@number\psyunit mul Y1 add /Y1 ED
     \fi
    \ifx\psk@arrowB\@empty\else 
      X2 X1 sub L_line div \psk@arrowlength\space mul \pst@number\psxunit mul X2 exch sub /X2 ED
      Y2 Y1 sub L_line div \psk@arrowlength\space mul \pst@number\psyunit mul Y2 exch sub /Y2 ED
     \fi
    Y2 Y1 sub \pst@colorsteps\space 1 add div /dY ED
    X2 X1 sub \pst@colorsteps\space 1 add div /dX ED
%    dR dG dB == == ==
%startColor == endColor ==
    \ifPst@noCurrentPoint\else\pst@cp\fi 	  % current point?
    0 1 \pst@colorsteps {      
      /dIndex ED
%startColor == 
      X1 Y1 moveto
      X1 dX add  Y1 dY add % start for coordinate array
%      gsave
      lineto
      CP /Y1 ED /X1 ED
      \pst@number\pslinewidth SLW
      startColor aload pop 3 copy setrgbcolor
      % on stack r g b
      dB add 3 1 roll    % b+dB r g 
      dG add 3 1 roll    % b+dB g+dG r
      dR add 3 1 roll    % b+dB g+dG r+dR
      3 array astore /startColor ED
      \tx@setStrokeTransparency
      stroke
%      grestore
    } for 
    end % of local part
  }%
  \end@OpenObj
  \ignorespaces
}
%
\def\psIntersectionPoint(#1)(#2)(#3)(#4)#5{%
    \pst@getcoor{#1}\pst@tempA
    \pst@getcoor{#2}\pst@tempB
    \pst@getcoor{#3}\pst@tempC
    \pst@getcoor{#4}\pst@tempd
\pnode(!%
     \pst@tempA /YA exch \pst@number\psyunit div def
     /XA exch \pst@number\psxunit div def
     \pst@tempB /YB exch \pst@number\psyunit div def
     /XB exch \pst@number\psxunit div def
     \pst@tempC /YC exch \pst@number\psyunit div def
     /XC exch \pst@number\psxunit div def
     \pst@tempd /YD exch \pst@number\psyunit div def
     /XD exch \pst@number\psxunit div def
    /dY1 YB YA sub def
    /dX1 XB XA sub def
    /dY2 YD YC sub def
    /dX2 XD XC sub def
    dX1 abs 0.01 lt {
        /m2 dY2 dX2 div def
        XA dup XC sub m2 mul YC add
    }{
        dX2 abs 0.01 lt {
            /m1 dY1 dX1 div def
            XC dup XA sub m1 mul YA add
        }{%
            /m1 dY1 dX1 div def
            /m2 dY2 dX2 div def
            m1 XA mul m2 XC mul sub YA sub YC add m1 m2 sub div dup
            XA sub m1 mul YA add
        } ifelse
    } ifelse ){#5}%
}
%
\def\psRiemannSum(#1,#2)#3#4{%    (x0,x1) n f(#1)
  \def\psFunction@##1{#4}%
  \edef\ps@@dx{\pscalculate{(#2-#1)/#3}}%
  \edef\ps@@dxHalf{\pscalculate{\ps@@dx/2}}%
%  \typeout{dx=\ps@dx}%
  \def\psRightSumValue{0}%
  \def\psLeftSumValue{0}%
  \def\psMiddleSumValue{0}%
  \def\psDiffSumValue{0}%
  \Multido{\rA=#1+\ps@@dx,\rB=\ps@@dx+\ps@@dx,\rC=\ps@@dxHalf+\ps@@dx}{#3}{%
  	\def\ps@rightY{\pscalculate{\psFunction@{\rB}}}%
  	\def\ps@leftY{\pscalculate{\psFunction@{\rA}}}%
  	\def\ps@middleY{\pscalculate{\psFunction@{\rC}}}%
%  	\typeout{\ps@leftY, \ps@rightY }%
  	\edef\psLeftSumValue{\pscalculate{\psLeftSumValue+\ps@@dx*\ps@leftY}}%
  	\edef\psRightSumValue{\pscalculate{\psRightSumValue+\ps@@dx*\ps@rightY}}%
  	\edef\psMiddleSumValue{\pscalculate{\psMiddleSumValue+\ps@@dx*\ps@middleY}}%
  	\edef\psDiffSumValue{\pscalculate{\psDiffSumValue+abs(\ps@@dx*(\ps@rightY-\ps@leftY))}}%
%  	\typeout{\psLeftSumValue , \psRightSumValue }%
  }% end \Multido
}

%\define@key[psset]{pstricks-add}{method}{\def\psk@method{#1}}%     	   defined in pst-plot
\define@key[psset]{pstricks-add}{whichabs}{\def\psk@whichabs{#1}}%
\define@key[psset]{pstricks-add}{whichord}{\def\psk@whichord{#1}}%
\define@key[psset]{pstricks-add}{plotfuncx}{\def\psk@plotfuncx{#1}}%
\define@key[psset]{pstricks-add}{plotfuncy}{\def\psk@plotfuncy{#1}}%
\define@key[psset]{pstricks-add}{expression}{\def\psk@expression{#1}}%
\define@boolkey[psset]{pstricks-add}[Pst@]{buildvector}[true]{}%
%
\define@key[psset]{pstricks-add}{varsteptol}{\def\psk@varsteptol{#1}}%  
\define@key[psset]{pstricks-add}{adamsorder}{\def\psk@adamsorder{#1}}% 
%\define@key[psset]{pstricks-add}{varstepincrease}{\def\psk@varstepincrease{#1}}% varrk4
%
\define@boolkey[psset]{pstricks-add}[Pst@]{saveSumValue}[true]{}
\psset[pstricks-add]{saveSumValue=false}

\define@key[psset]{pstricks-add}{StepType}{\pst@expandafter\psset@@StepType{#1}\@nil}%
\def\psset@@StepType#1#2\@nil{%
  \ifx#1u\let\psk@StepType\@ne
  \else\ifx#1l\let\psk@StepType\z@
  \else\ifx#1i\let\psk@StepType\thr@@
  \else\ifx#1s\let\psk@StepType\f@ur
  \else\let\psk@StepType\tw@\fi\fi\fi\fi}
\psset{StepType=lower} %               alternative StepType=upper/inf/sup/Riemann
\define@boolkey[psset]{pstricks-add}[Pst@]{noVerticalLines}[true]{}%
\psset{noVerticalLines=false}
\define@boolkey[psset]{pstricks-add}[Pst@]{drawLines}[true]{}%
\psset{drawLines=true}
%
\newcount\pst@stepcount 
\pst@stepcount=1
\def\get@Letter#1;{%
  \ifcase#1\or A\or B\or C\or D\or E\or F\or G\or H\or I\or J\or
   K\or L\or M\or N\or O\or P\or Q\or R\or S\or T\or U\or V\or W\or X\or
    Y\or Z\else0\fi}


\def\psStep{\def\pst@par{}\pst@object{psStep}}
\def\psStep@i(#1,#2)#3#4{%
  \expandafter\xdef\csname pstArea\get@Letter\the\pst@stepcount;\endcsname{undef}%
  \IfFileExists{\jobname-area\the\pst@stepcount.tex}{\input{\jobname-area\the\pst@stepcount.tex}}{}%
  \begin@ClosedObj
  \addto@pscode{
    \ifPst@saveSumValue
      /AreaFile (\jobname-area\the\pst@stepcount.tex) (w) file def
      AreaFile (\string\% Created by \string\\psStep\string\n ) writestring 
    \fi
    /Func \ifPst@algebraic (#4) tx@addDict begin AlgParser end cvx \else {#4} \fi def 
    /x #1  def
    /dx #2 #1 sub #3 div def
    /scx { \pst@number\psxunit mul } def 
    /scy { \pst@number\psyunit mul } def
    /Area 0 def
%
    \ifcase\psk@StepType % 0->lower, height is always f(x)
      \ifPst@drawLines x scx 0 moveto \fi
      #3 {
        Func dup dx mul Area add /Area ED 
        \ifPst@drawLines scy dup x scx exch \ifPst@noVerticalLines  moveto \else lineto \fi 
        \else pop \fi
        /x x dx add def
        \ifPst@drawLines
          x scx exch lineto 
          x scx 0 \ifPst@noVerticalLines  moveto \else lineto \fi
        \fi
      } repeat
    \or % 1-> upper, height is always f(x+dx)
      \ifPst@drawLines x scx 0 moveto \fi
      #3 {
        /x x dx add def
        Func \ifPst@saveSumValue dup dx mul Area add /Area ED \fi
        \ifPst@drawLines
          scy dup x dx sub scx exch 
          \ifPst@noVerticalLines  moveto \else lineto \fi
          x scx exch lineto
          x scx 0 \ifPst@noVerticalLines  moveto \else lineto \fi
        \else 
          pop
        \fi
      } repeat
      \ifPst@saveSumValue      
      \fi
    \or % 2-> Riemann
      /eps3 500 def   %% increased  from 100 to 500 20140507
      /xMinMax [] def
      /AMax [] def
      /AMin [] def
      /dt dx eps3 div def
      #3 {
        /Max Func def 
        /Min Max def 
	/t x def % save x value
	eps3 {
          Func \ifPst@saveSumValue dup dx mul Area add /Area ED \fi
          dup
          Max lt { /Max exch def } { dup Min gt { /Min exch def }{ pop } ifelse } ifelse
	  /x x dt add def
	} repeat 
	/x t def  % restore
	x scx Min scy Max scy xMinMax aload length 3 add array astore /xMinMax exch def
        /x x dx add def
	closepath
      } repeat
      /dx dx scx def
      \ifPst@drawLines
        xMinMax aload length 3 div cvi { 
          /yMax ED /yMin ED /x ED 
	  x yMin moveto 
	  dx 0 \ifPst@noVerticalLines rmoveto \else rlineto \fi
	  x dx add yMax lineto 
	  dx neg 0 \ifPst@noVerticalLines rmoveto \else rlineto \fi
	  x yMin \ifPst@noVerticalLines moveto \else lineto \fi 
	  closepath 
      \fi
      } repeat
    \or % 3->inf(imum)
%      \ifPst@drawLines      
        x scx 0 moveto 
%      \fi
      #3 {
        \ifPst@algebraic Func \else #4 \fi 
        \ifPst@saveSumValue dup dx mul Area add /Area ED \fi
        /yMin ED % Max value f(x)
        /xStart x def
        /xEnd xStart dx add def
        /DX dx 100 div def
        xStart DX xEnd {
          /x ED
          \ifPst@algebraic Func \else #4 \fi /yVal ED
          yVal yMin lt { /yMin yVal def } if
        } for
%        y0 y1 gt { y0 }{ y1 } ifelse 		  % use supremum
        /x xEnd def
	yMin scy dup xStart scx exch \ifPst@noVerticalLines moveto \else lineto \fi 
        x scx exch lineto 
        x scx 0 \ifPst@noVerticalLines moveto \else lineto \fi
	closepath  x scx 0 moveto 
      } repeat
    \or % 4-> sup(remum)
      x scx 0 moveto 
      #3 {
        \ifPst@algebraic Func \else #4 \fi 
        \ifPst@saveSumValue dup dx mul Area add /Area ED \fi
        /yMax ED % Max value f(x)
        /xStart x def
        /xEnd xStart dx add def
        /DX dx 100 div def
        xStart DX xEnd {
          /x ED
          \ifPst@algebraic Func \else #4 \fi /yVal ED
          yVal yMax gt { /yMax yVal def } if
        } for
%        y0 y1 gt { y0 }{ y1 } ifelse 		  % use supremum
        /x xEnd def
	yMax scy dup xStart scx exch \ifPst@noVerticalLines  moveto \else lineto \fi 
        x scx exch lineto 
        x scx 0 \ifPst@noVerticalLines  moveto \else lineto \fi
	closepath x scx 0 moveto 
      } repeat
    \fi
    \ifPst@saveSumValue
      AreaFile (\string\\gdef\string\\pstArea\get@Letter\the\pst@stepcount;\string{) writestring
      Area 10 string cvs AreaFile exch writestring
      AreaFile (\string}\string\n) writestring
      AreaFile closefile
    \fi
  }%
  \global\advance\pst@stepcount by 1
  \psk@fillstyle
  \pst@stroke
  \end@ClosedObj
  \ignorespaces
}
%
\define@key[psset]{pstricks-add}{Derive}{\def\psk@Derive{#1}}
%\define@key[psset]{pstricks-add}{Derive}{\expandafter\psk@@Derive#1,,\@nil}%
%\def\psk@@Derive#1,#2,#3\@nil{%
%  \ifx\relax#2\relax 
%    \ifPST@algebraic\def\psk@Derive{ (#1) tx@addDict begin AlgParser end cvx }\else \def\psk@Derive{ #1 }\fi
%  \else\def\psk@Derive{ (#1)(x) tx@Derive begin Derive end tx@addDict begin AlgParser end cvx } \fi
%}
\define@boolkey[psset]{pstricks-add}[PST@]{Tnormal}[true]{}

\psset[pstricks-add]{CMYK=true}
\def\@NOTEMPTY{NOT@EMPTY}%%dr 0606
%
\def\psTangentLine{\def\pst@par{}\pst@object{psTangentLine}}
\def\psTangentLine@i(#1,#2)(#3,#4)(#5,#6)#7#8{%
  \begin@OpenObj%
  \addto@pscode{
    [[#1 dup dup mul exch 1 #2]
     [#3 dup dup mul exch 1 #4]
     [#5 dup dup mul exch 1 #6]]
    SolveLinEqSystem
    /abc ED
    abc aload pop    % a b c on stack
    exch #7          % a c b x
    mul add exch     % c+b*x a
    #7 dup mul mul add 	    % a*x^2+b*x+c
    /y0 ED 		    % save value
    abc aload pop pop exch  % b a
    #7 mul 2 mul add        % b+2*a*x0=mTan
    \ifPST@Tnormal
      neg 1 exch div         % -1/mTan=mOrth
      #8 mul /dy ED          % mOrth*dx=dy
      [
       #7 #8 add y0 dy add \tx@ScreenCoor % x0+dx y0 +dy
       #7 y0 \tx@ScreenCoor   % x0 y0
    \else
      dup                     % mTan mTan
      #8 mul /dy1 ED          % mTan*dx
      #8 neg mul /dy2 ED      % mTan*-dx
      [
       #7 #8 add y0 dy1 add \tx@ScreenCoor % x0+dx y0 +dy1
       #7 #8 sub y0 dy2 add \tx@ScreenCoor % x0-dx y0 +dy2
    \fi
    /Lineto /lineto load def
    \ifshowpoints true \else false \fi
    \tx@setlinejoin 		       %
    \tx@Line 
    }%
  \end@OpenObj%
    \pnode(!
     [[#1 dup dup mul exch 1 #2][#3 dup dup mul exch 1 #4][#5 dup dup mul exch 1 #6]]
     SolveLinEqSystem /abc ED
    abc aload pop    % a b c on stack
    exch #7          % a c b x
    mul add exch     % c+b*x a
    #7 dup mul mul add 	    % a*x^2+b*x+c
    /y0 ED 		    % save value
      #7 y0 ){OCurve}%
    \pnode(!
     [[#1 dup dup mul exch 1 #2][#3 dup dup mul exch 1 #4][#5 dup dup mul exch 1 #6]]
     SolveLinEqSystem /abc ED
    abc aload pop    % a b c on stack
    exch #7          % a c b x
    mul add exch     % c+b*x a
    #7 dup mul mul add 	    % a*x^2+b*x+c
    /y0 ED 		    % save value
    abc aload pop pop exch  % b a
    #7 mul 2 mul add        % b+2*a*x0=mTan
    neg 1 exch div         % -1/mTan=mOrth
      #8 mul /dy ED          % mOrth*dx=dy
      #7 #8 add y0 dy add % x0+dx y0 +dy
     ){ENormal}%
    \pnode(!
      [[#1 dup dup mul exch 1 #2][#3 dup dup mul exch 1 #4][#5 dup dup mul exch 1 #6]]
      SolveLinEqSystem
      /abc ED
      abc aload pop    % a b c on stack
      exch #7          % a c b x
      mul add exch     % c+b*x a
      #7 dup mul mul add 	    % a*x^2+b*x+c
      /y0 ED 		    % save value
      abc aload pop pop exch  % b a
      #7 mul 2 mul add        % b+2*a*x0=mTan
      #8 mul /dy1 ED          % mTan*dx
      #7 #8 add y0 dy1 add ){ETangent}%
\ignorespaces}

\def\psplotTangent@x#1,#2,#3\@nil{%
  \def\pst@tempLeft{#1}%
  \def\pst@tempRight{#2}}
%% #1 : x value
%% #2 : delta x or x0,x1
%% #3 : function
\def\psplotTangent{\@ifnextchar*{\@startrue\psplotTangent@i}{\@starfalse\psplotTangent@i*}}
\def\psplotTangent@i*{\@ifnextchar[{\psplotTangent@ii}{\psplotTangent@ii[]}}
\def\psplotTangent@ii[#1]#2#3#4{%
  \pst@killglue
  \expandafter\psplotTangent@x#3,,\@nil\relax
  \begingroup
  \ifx\relax#1\relax\else\psset{linestyle=solid,#1}\fi
  \ifx\psk@Derive\@empty\ifPst@algebraic\def\psk@Derive{NOT@EMPTY}\fi\fi              %%dr 0606 hv 1003
  \pst@addarrowdef
  \addto@pscode{
    /F@pstplot \ifPst@algebraic (#4) tx@addDict begin AlgParser end cvx \else { #4 } \fi def % define function
    \ifx\psk@Derive\@empty\else
      \ifx\psk@Derive\@NOTEMPTY\else                                                  %%dr 0606
        /FDer@pstplot                                                                 % do we have a derivation defined?
        \ifPst@algebraic (\psk@Derive) tx@addDict begin AlgParser end cvx \else { \psk@Derive } \fi def % define derivation
      \fi                                                                             %%dr 0606
    \fi%
    /@parametric false def                                                            %%dr 0606
    % first we calculate the origin
    #2 dup /x ED /t ED tx@addDict begin mark F@pstplot end counttomark 1 gt           % test, if we have parametricplot
      { /y ED /x ED /@parametric true def }                                           % if yes, then we have 2 values %%dr 0606
      { \ifPst@polarplot x \ifPst@algebraic RadtoDeg \fi PtoC /y ED /x ED \else /y ED \fi } ifelse
    cleartomark
    \ifx\psk@Derive\@NOTEMPTY                                                         %%begin dr 0606
%                                                                                      %% algebraic we can use the derivative machine
        /FDer@pstplot (#4) @parametric { (t) } { (x) } ifelse
        tx@Derive begin Derive end tx@addDict begin AlgParser end cvx def
    \fi                                                                               %%end dr 0606
    x \pst@number\psxunit mul y \pst@number\psyunit mul
    translate % define the temporary origin
    % now we calculate the slope of the tangent
    \ifx\psk@Derive\@empty                                                            % de we have a derivation defined?
      #2 abs 1.0e-6 lt                                                                % no, we choose secant for the tangent
      { #2 0.0005 add dup /x ED /t ED tx@addDict begin mark F@pstplot end counttomark 1 gt % test, if we have parametricplot
        { /y2 ED /x2 ED }                                                             % we have 2 values
        { \ifPst@polarplot dup x \ifPst@algebraic RadtoDeg \fi
	  cos mul /x2 ED x \ifPst@algebraic RadtoDeg \fi sin mul \else /x2 x def \fi /y2 ED } ifelse
        cleartomark                                                                   % delete the mark
        #2 0.0005 sub dup /x ED /t ED tx@addDict begin mark F@pstplot end counttomark 1 gt % test, if we have parametricplot
          { /y1 ED /x1 ED }
	  { \ifPst@polarplot dup x \ifPst@algebraic RadtoDeg \fi
	    cos mul /x1 ED x \ifPst@algebraic RadtoDeg \fi sin mul \else /x1 x def \fi /y1 ED } ifelse
         cleartomark
        y2 y1 sub x2 x1 sub } % dy dx
      {  % > 1.0e-06
        #2 1.0005 mul dup /x ED /t ED tx@addDict begin mark F@pstplot end counttomark 1 gt % test, if we have parametricplot
          { /y2 ED /x2 ED } % we have 2 values
          { \ifPst@polarplot dup x \ifPst@algebraic RadtoDeg \fi
	    cos mul /x2 ED x \ifPst@algebraic RadtoDeg \fi sin mul \else /x2 x def \fi /y2 ED } ifelse
	cleartomark
        #2 .9995 mul dup /x ED /t ED tx@addDict begin mark F@pstplot end counttomark 1 gt % test, if we have parametricplot
          { /y1 ED /x1 ED } % we have 2 values
          { \ifPst@polarplot dup x \ifPst@algebraic RadtoDeg \fi
	    cos mul /x1 ED x \ifPst@algebraic RadtoDeg \fi sin mul \else /x1 x def \fi /y1 ED } ifelse
	cleartomark
        y2 y1 sub \pst@number\psyunit mul x2 x1 sub \pst@number\psxunit mul } ifelse
      atan %  atan(dy dx), we have the slope angle of the secant
      \ifPST@Tnormal 90 add \fi
    \else % there is a derivation defined
      #2 dup /x ED /t ED tx@addDict begin mark FDer@pstplot end counttomark 1 gt % test, if we have parametricplot
        { /y ED /x ED }
        { \ifPst@polarplot /Fphi ED % the value F'(phi)
            tx@addDict begin F@pstplot end x \ifPst@algebraic RadtoDeg \fi PtoC /y0 ED /x0 ED % the x y values
            x \ifPst@algebraic RadtoDeg \fi sin Fphi mul x0 add /y ED
            x \ifPst@algebraic RadtoDeg \fi cos Fphi mul y0 sub /x ED
          \else /y ED /x 1 def \fi } ifelse
      cleartomark
      y \pst@number\psyunit mul x \pst@number\psxunit mul Atan \ifPST@Tnormal 90 add \fi
  %    y ATAN1  % we have the slope angle of the tangent. ATAN is defined int the pstricks.pro, patch 6
    \fi
    dup  					% to prevent rounding errors use original value
    cvi 180 mod 90 gt { 180 sub } if            % -90 <= angle <= 90
    rotate                                      % rotate, depending to the origin
    /Lineto /lineto load def                    % the pro file needs /Lineto
    \pst@cp                                     % kill the currentpoint, if any
    [                                           % start array of points
    \ifPST@Tnormal
      0 \psk@nodesepA add 0 % moveto
      #3 \pst@number\psxunit mul \psk@nodesepB sub 0
%      y \pst@number\psyunit mul x \pst@number\psxunit mul Atan cos div \pst@number\psxunit mul 0  % lineto
    \else % points are in reverse order ...
      \ifx\pst@tempRight\@empty #3 \psk@nodesepA \pst@number\psxunit div sub \else \pst@tempRight\space \fi \pst@number\psxunit mul 0            % moveto
      \if@star 0
      \else
          \ifx\pst@tempRight\@empty #3 \psk@nodesepB \pst@number\psxunit div sub neg \else \pst@tempLeft\space \fi
          \pst@number\psxunit mul
        \fi 0     % lineto
    \fi
    \pst@usecolor\pslinecolor
    false                                       % don't show the points
    \tx@Line
    \ifx\pslinestyle\@none\else
      \pst@number\pslinewidth SLW
      \tx@setStrokeTransparency
      \@nameuse{psls@\pslinestyle}
    \fi
    \ifshowpoints                               % show the points?
      gsave
      \psk@dotsize
      \@nameuse{psds@\psk@dotstyle}
      0 0 Dot
      grestore
    \fi
   }%
  \use@pscode
  %% ---- only for algebraic: 3 Nodes for Origin, Tangent-End and Normal-End --- 31.05.2014 TS
\iffalse
  \ifPst@algebraic
    \pst@Verb{
      #2 /x ED %                                                                        x-Wert wird definiert
      /Function (#4) tx@AlgToPs begin AlgToPs end cvx def 
      /mt (#4) (x) tx@Derive begin Derive end tx@addDict begin AlgParser end cvx def %  mt ist die Steigung an der Stelle x = #2
      x Function /y ED %                                            y = f(x=#2) ist der Funktionswert an der Stelle x = #2
      #3 mt 1 Atan cos dup mul mt 1 Atan sin \pst@number\psyunit mul \pst@number\psxunit div dup mul add sqrt div /ldt ED 
      mt 0 ge { ldt mt 1 Atan cos mul /Dx ED ldt mt 1 Atan sin mul /Dy ED } 
              {ldt mt 1 Atan cos mul neg /Dx ED ldt mt 1 Atan sin mul neg /Dy ED } ifelse 
      x Dx add /xt ED
      y Dy add /yt ED
      x Dy \pst@number\psyunit mul \pst@number\psxunit div add /xn ED 
      y Dx \pst@number\psxunit mul \pst@number\psyunit div sub /yn ED 
    }%
    \pnode(! x y){OCurve}%
    \pnode(! xt yt){ETangent}%
    \pnode(! xn yn){ENormal}%
    \psLNode(ENormal)(OCurve){2}{ENormalE}%
    \psLNode(ETangent)(OCurve){2}{ETangentE}%
  \fi
\fi
  \endgroup
  \@starfalse
  \ignorespaces}
%
%% #1-#2 x range
%% #3 initial value of y (which is a vector) y(0) y'(0) y''(0) ...
%% #4 value of the derivative (y and t can be used)
%
\define@boolkey[psset]{pstricks-add}[Pst@]{GetFinalState}[true]{}
\define@key[psset]{pstricks-add}{filename}{\def\psk@filename{#1}}%
\define@boolkey[psset]{pstricks-add}[Pst@]{saveData}[true]{} % \ifPst@saveData
\psset[pstricks-add]{GetFinalState=false,saveData=false,filename=PSTdata}
%
\def\Begin@SaveFinalState{ end 
  /PST@beginspecial /@beginspecial load def 
  /PST@endspecial /@endspecial load def 
  /PST@setspecial /@setspecial load def 
  /@beginspecial {} def /@endspecial{} def /@setspecial {} def
  tx@Dict begin
}
\newif\ifPst@BeginSaveFinalState \Pst@BeginSaveFinalStatefalse
\def\BeginSaveFinalState{\Pst@BeginSaveFinalStatetrue}
\def\End@SaveFinalState{
  /@beginspecial /PST@beginspecial load def 
  /@endspecial /PST@endspecial load def 
  /@setspecial /PST@setspecial load def
}
\def\EndSaveFinalState{\pstverb{\End@SaveFinalState}}

\def\psplotDiffEqn{\def\pst@par{}\pst@object{psplotDiffEqn}}% initial code by Dominique 2005-05-21
\def\psplotDiffEqn@i#1#2#3#4{%
  \addbefore@par{xStart=#1}% 
  \pst@killglue%
  \begingroup%
  \use@par%
  \@nameuse{beginplot@\psplotstyle}%
  \addto@pscode{%
    \ifPst@BeginSaveFinalState \Begin@SaveFinalState \fi
    \ifPst@saveData /Pst@data (\psk@filename) (w) file def \fi
    /x #1 def				% first value
    /x1 #2 def				% last value
    \ifPst@GetFinalState \Begin@SaveFinalState  /y FinalState def
    \else /y [ #3 ] def \fi			% values for t=0
    /ylength y length def		% number of elements in #3
    /addvect {
      1 1 ylength {
        /i exch def
	ylength i sub 2 add -1 roll add ylength 2 mul i sub 1 roll
      } for
    } def
    /dx x1 x sub \psk@plotpoints\space div def
    /mulvect {
      ylength exch
      1 index {
        dup 4 -1 roll mul 2 index 2 add 1 roll
      } repeat
      pop pop } def
    /divvect { ylength exch 1 index { dup 4 -1 roll exch div 2 index 2 add 1 roll } repeat pop pop } def
    /k0 0 def /k1 0 def /k2 0 def /k3 0 def
    \ifPst@algebraic /F@pstplot (#4) tx@addDict begin AlgParser end cvx def \fi
    /Func {
      \ifPst@algebraic F@pstplot ylength array astore
      \else
        \ifPst@buildvector\else y aload pop \fi #4 
        \ifPst@buildvector\else ylength array astore \fi
      \fi
    } def
    \ifx\psk@method\@adams /F1 0 def /F2 0 def /F3 0 def /F4 0 def /F5 0 def /F6 0 def /INIT 1 def \fi
    \ifx\psk@method\@empty\else
      \ifx\psk@method\@varrkiv            %% RUNGE-KUTTA method with var step algorithm
        /VarStep false def /VarStepRatio 1 def
        /RK {
           /k0 Func { dx mul } forall ylength array astore def 				%% y
           dup aload pop k0 { 2 div } forall addvect ylength array astore /y exch def %
           x dup dx 2 div add /x exch def 						%% y x
           /k1 Func { dx mul } forall ylength array astore def 				%% y x
           exch dup aload pop k1 { 2 div } forall addvect y astore pop 			%% x y
           /k2 Func { dx mul } forall ylength array astore def 				%% x y
           dup aload pop k2 aload pop addvect y astore pop exch dup dx add /x exch def 	%% y x
           /k3 Func { dx mul } forall ylength array astore def %% y x
           /x exch def 									%% y
           dup aload pop k0 aload pop k1 aload pop k2 aload pop addvect
           2 mulvect addvect k3 aload pop addvect
           6 divvect addvect y astore
        } def
        /VARRK {
          VarStep
          %{ /dx dx \psk@varstepincrease\space mul def /VarStep false def } if
          { /dx dx VarStepRatio mul def /VarStep false def } if
          x dx add x1 gt { /dx x1 x sub def } if
          %{ /dx dx \psk@varstepdecrease\space div def } ifelse
          %% we compute y(x+dx) from y(x) using RK4
          RK %% y(x) y(x+dx)
          exch /y exch def /dx dx 2 div def
          { %% we compute y(x+dx/2) from y(x) using RK4
            y RK %% y(x+dx) y(x+dx/2)
            %% then y(x+dx) from y(x+dx/2) using RK4
            /y exch def y RK %% y(x+dx) y(x) y(x+dx/2) y(x+dx)
            dup aload pop 4 ylength add -1 roll
            { -1 mul } forall addvect 0 ylength { exch abs 2 copy lt { exch } if pop } repeat
            0 3 -1 roll {abs 2 copy lt { exch } if pop } forall
            dup 1e-6 lt { pop } { div } ifelse
            /dx dx 2 mul def
            dup \psk@varsteptol\space lt
            %{ \psk@varsteptol\space div .1 lt { /VarStep true def } if pop exit } if
            %pop /dx dx 4 div def exch /y exch def } loop
            { .001 div dup .1 lt
              { dup 1e-6 lt { pop 3 } { log neg } ifelse /VarStepRatio exch def /VarStep true def }
              { pop } ifelse pop exit } if
            pop /dx dx 4 div def exch /y exch def } loop
        } def
      \else			%% RUNGE-KUTTA & ADAMS  methods
        /RK {
           /k0 Func { dx mul } forall ylength array astore def 				%% y
           dup aload pop k0 { 2 div } forall addvect ylength array astore /y exch def %
           x dup dx 2 div add /x exch def 						%% y x
           /k1 Func { dx mul } forall ylength array astore def 				%% y x
           exch dup aload pop k1 { 2 div } forall addvect y astore pop 			%% x y
           /k2 Func { dx mul } forall ylength array astore def 				%% x y
           dup aload pop k2 aload pop addvect y astore pop exch dup dx add /x exch def 	%% y x
           /k3 Func { dx mul } forall ylength array astore def %% y x
           /x exch def 									%% y
           dup aload pop k0 aload pop k1 aload pop k2 aload pop addvect
           2 mulvect addvect k3 aload pop addvect
           6 divvect addvect y astore pop
        } def
        \ifx\psk@method\@adams
           /ADAMS {
             \ifcase\psk@adamsorder
                \errmessage{pstricks-add error: no order 0th for adams method (see user's manual)}
             \or\errmessage{pstricks-add error: no order 1st for adams method (see user's manual)}
             \or\errmessage{pstricks-add error: no order 2nd for adams method (see user's manual)}
             \or\errmessage{pstricks-add error: no order 3rd for adams method (see user's manual)}
             \or
             %% ORDRE 4
               F4 aload pop  55 mulvect
               F3 aload pop -59 mulvect addvect
               F2 aload pop  37 mulvect addvect
               F1 aload pop  -9 mulvect addvect
               dx mulvect 24 divvect
             \or
             %% ORDRE 5
               F5 aload pop  1901 mulvect
               F4 aload pop -2774 mulvect addvect
               F3 aload pop  2616 mulvect addvect
               F2 aload pop -1274 mulvect addvect
               F1 aload pop   251 mulvect addvect
               dx mulvect 720 divvect
             \or
             %% ORDRE 6
               F6 aload pop  4277 mulvect
               F5 aload pop -7923 mulvect addvect
               F4 aload pop  9982 mulvect addvect
               F3 aload pop -7298 mulvect addvect
               F2 aload pop  2877 mulvect addvect
               F1 aload pop  -475 mulvect addvect
               dx mulvect 1440 divvect
             \fi
             y aload pop addvect ylength array astore /y exch def } def
        \fi
      \fi
    \fi
    /xy {
      \ifx\psk@plotfuncx\@empty
        \ifx\psk@whichabs\@empty x \else y \psk@whichabs\space get \fi
      \else \psk@plotfuncx\space \fi
      \pst@number\psxunit mul y 
      \ifx\psk@method\@empty							%% EULER method
        /y Func { dx mul } forall y aload pop addvect ylength array astore def
      \else%
        \ifx\psk@method\@varrkiv						%% RUNGE-KUTTA method
	  VARRK
        \else\ifx\psk@method\@rkiv						%% RUNGE-KUTTA method
	  RK
        \else
          /F1 F2 def /F2 F3 def /F3 F4 def /F4 				        %% ADAMS method
          \ifcase\psk@adamsorder\or\or\or\or
           %% ORDRE 4
           Func def
           \or
           %% ORDRE 5
           F5 def /F5 Func def
           \or
           %% ORDRE 6
           F5 def /F5 F6 def /F6 Func def
          \fi
           INIT \psk@adamsorder\space lt
           { RK /INIT INIT 1 add def }
           { ADAMS } ifelse
        \fi\fi
      \fi
      \ifx\psk@plotfuncy\@empty
        \ifx\psk@whichord\@empty 0 \else \psk@whichord\space \fi  get %
      \else \psk@plotfuncy\space \fi
      \pst@number\psyunit mul  
%        Pst@data (\string\[) writestring
      \ifPst@saveData 
        2 copy
        \pst@number\psyunit div exch  \pst@number\psxunit div 
        20 string cvs Pst@data exch writestring 
        Pst@data (\space) writestring 
        20 string cvs Pst@data exch writestring 
        Pst@data (\string\n) writestring 
      \fi
    } def
  }%
  \gdef\psplot@init{}%
  \@pstfalse
  \@nameuse{testqp@\psplotstyle}%
  \if@pst\psplot@ii\else\psplot@iii\fi
%  \addto@pscode{\ifPst@saveData Pst@data closefile \fi}
  \endgroup%
  \ignorespaces%
}
%
%
\def\psGTriangle{\def\pst@par{}\pst@object{psGTriangle}}
\def\psGTriangle@i(#1)(#2)(#3)#4#5#6{{%
  \begin@ClosedObj
  \pst@getcoor{#1}\pst@tempA	%   A: "rgb xr xg xb" or "gray xg"
  \pst@getcoor{#2}\pst@tempB	%   B
  \pst@getcoor{#3}\pst@tempC	%   C
  \pst@getcolor{#4}\pst@colorA
  \pst@getcolor{#5}\pst@colorB
  \pst@getcolor{#6}\pst@colorC
  \addto@pscode{%
    \pst@tempC		    % C
    \pst@tempB		    % B
    \psk@gangle             %   rotating angle
    \pst@tempA 		    % A, temporary origin
%    /rgb {} def
%    /gray {} def
%    /rg /setrgbcolor load def
%    /RG /setrgbcolor load def
% we use RGB
    [ \psgetRGBColorValues{\pst@colorC} ] aload length 1 eq { dup dup } if 3 array astore % gray -> rgb
    [ \psgetRGBColorValues{\pst@colorB} ] aload length 1 eq { dup dup } if 3 array astore
    [ \psgetRGBColorValues{\pst@colorA} ] aload length 1 eq { dup dup } if 3 array astore
    tx@addDict begin GTriangle end % PS part
  }%
  \if@star\pspolygon[fillstyle=none](#1)(#2)(#3)\fi%	draw borderline
  \def\pst@linetype{2}%
  \end@ClosedObj%
}\ignorespaces}
%
\def\psdice{\def\pst@par{}\pst@object{psdice}}
\def\psdice@i#1{{%
  \pst@killglue%
  \addbefore@par{framearc=0.3,linewidth=1pt}%
  \use@par%
  \psframe(-0.5,-0.5)(0.5,0.5)%
  \ifodd#1 \qdisk(0,0){0.1\psunit}\else\qdisk(-0.3,-0.3){0.1\psunit}\qdisk(0.3,0.3){0.1\psunit}\fi
  \ifcase#1%
    \or\or\or\qdisk(-0.3,-0.3){0.1\psunit}\qdisk(0.3,0.3){0.1\psunit}% 3
    \or\qdisk(-0.3,0.3){0.1\psunit}\qdisk(0.3,-0.3){0.1\psunit}%      4
    \or\qdisk(-0.3,-0.3){0.1\psunit}\qdisk(0.3,0.3){0.1\psunit}%      5
       \qdisk(-0.3,0.3){0.1\psunit}\qdisk(0.3,-0.3){0.1\psunit}
    \or\qdisk(-0.3,0.3){0.1\psunit}\qdisk(0.3,-0.3){0.1\psunit}%      6
       \qdisk(-0.3,0){0.1\psunit}\qdisk(0.3,0){0.1\psunit}%
  \fi%
  \ignorespaces%
}}
%
% the datafile must be a matrix with
% /dotmatrix [
%   .....
%   .....
% ] def
%
\def\pswavelengthToGRAY{ tx@addDict begin wavelengthToGRAY end }
\def\pswavelengthToRGB{ tx@addDict begin wavelengthToRGB Red Green Blue end }
%
\define@key[psset]{pstricks-add}{Xoffset}[0pt]{\pst@getlength{#1}\psk@Xoffset}
\define@key[psset]{pstricks-add}{Yoffset}[0pt]{\pst@getlength{#1}\psk@Yoffset}
\define@key[psset]{pstricks-add}{XYoffset}[0pt]{\pst@getlength{#1}\psk@Xoffset\let\psk@Yoffset\psk@Xoffset}
\psset[pstricks-add]{XYoffset=0pt}
\define@boolkey[psset]{pstricks-add}[Pst@]{PixelPlot}[true]{} % \ifPst@saveData
\define@key[psset]{pstricks-add}{colorType}[0]{\def\psk@colorType{#1}}
\define@key[psset]{pstricks-add}{colorTypeDef}[{}]{\def\psk@colorTypeDef{#1\space}}
\psset[pstricks-add]{PixelPlot=false,colorType=0,colorTypeDef={}} % 0-> two color mode 1->wavelength mode (400..700nm)
% 0-> two color mode 
% 1-> wavelength mode (400..700nm)
% 2-> wavelength mode inverse
% 3-> gray color mode
% 4-> gray color mode invers
% 5-> own color definition
%

\def\psMatrixPlot{\def\pst@par{}\pst@object{psMatrixPlot}}
\def\psMatrixPlot@i#1#2#3{%
  \pst@killglue%
  \addbefore@par{xStep=1,yStep=1}%
  \begin@SpecialObj%
  \addto@pscode{
    20 dict begin
    (#3) run   		% load the data file
    /Min 0 def /Max 0 def
    dotmatrix { dup Min lt { /Min ED } { dup Max gt { /Max ED } { pop } ifelse } ifelse } forall
    /dMaxMin Max Min sub def
    \psk@dotsize % defines /DS ... def
    \psk@Xoffset\space \psk@Yoffset\space translate
    \ifPst@PixelPlot\else\@nameuse{psds@\psk@dotstyle}\fi
    /n 0 def   		% index for element
    1 1 #1 {		% the y loop (outer one)
      /y exch def	% save y
      1 1 #2 {		% the x loop (inner one)
        /x exch def	% save x
	dotmatrix n get % get value from matrix 
        \ifcase\psk@colorType
  	  dup 0 gt { 	% test if > 0
  	\or
          Min sub dMaxMin div 300 mul 400 add
          \pswavelengthToRGB setrgbcolor
        \or
          Min sub dMaxMin div neg 1 add 300 mul 400 add
          \pswavelengthToRGB setrgbcolor
        \or        
          Min sub dMaxMin div neg 1 add 300 mul 400 add
          \pswavelengthToGRAY setgray
        \or        
          Min sub dMaxMin div neg 1 add 300 mul 400 add
          \pswavelengthToGRAY neg 1 add setgray
        \or
          currentdict /colorTypeDef known { colorTypeDef } { \psk@colorTypeDef } ifelse
        \fi
	  x \psk@xStep\space mul \pst@number\psxunit mul 
	  \ifPst@ChangeOrder #1 y sub 1 add \else y \fi \psk@yStep\space mul \pst@number\psyunit mul 
	  \ifPst@PixelPlot 1 DS mul 0 360 arc fill \else Dot \fi
        \ifcase\psk@colorType
 	  } { pop } ifelse
 	\fi
	/n n 1 add def
      } for 
    } for
    end
  }%
  \end@SpecialObj%
  \ignorespaces%
}
%
\newdimen\chart@ColorIndex
\newdimen\chart@ColorStep
\newdimen\pst@chartHeight
\newdimen\pst@chartStackDepth
\newdimen\pst@chartStackWidth
\newcount\chart@Toggle
\newif\if@chartSep
\newif\if@chartUserColor
%
\define@key[psset]{pstricks-add}{chartStyle}{\def\psk@chartStyle{#1}}
\psset[pstricks-add]{chartStyle=pie}% p)ie P)ie-3d-view h)istogram H)istogram-3dview
%
\define@key[psset]{pstricks-add}{chartColor}{\pst@expandafter\psk@@chartColor{#1}\@nil}
\def\psk@@chartColor#1#2\@nil{%
  \ifx#1r\def\psk@chartColor{2}\else%
    \ifx#1c\def\psk@chartColor{380}\else\def\psk@chartColor{0}\fi\fi}
\psset[pstricks-add]{chartColor=gray}% gray, color, randomColor
%
\define@key[psset]{pstricks-add}{chartSep}{\pst@getlength{#1}\psk@chartSep}
\define@key[psset]{pstricks-add}{chartStack}{\pst@getint{#1}\psk@chartStack}
\define@key[psset]{pstricks-add}{chartStackDepth}{\pssetylength\pst@chartStackDepth{#1}}
\define@key[psset]{pstricks-add}{chartStackWidth}{\pssetxlength\pst@chartStackWidth{#1}}
\define@key[psset]{pstricks-add}{chartHeight}{\pssetylength\pst@chartHeight{#1}}
\psset[pstricks-add]{chartSep=10pt,chartStack=0,chartStackDepth=2cm,chartStackWidth=2cm,%
    chartHeight=5mm}
%
\define@boolkey[psset]{pstricks-add}[Pst@]{uselinecolor}[true]{}
\psset[pstricks-add]{uselinecolor=false}
%
\define@key[psset]{pstricks-add}{userColor}{%
  \chart@Toggle=0\relax%
  \def\chart@option{#1}%
  \ifx\chart@option\@empty\@chartUserColorfalse%
  \else%
    \@chartUserColortrue%
    \expandafter\psk@@chartUserColor#1,,\@nil%
  \fi}
\def\psk@@chartUserColor#1,#2,#3\@nil{%
  \advance\chart@Toggle by \@ne%
  \xglobal\colorlet{chartFillColor\the\chart@Toggle}{#1}%
  \def\chart@option{#2}%
  \ifx\chart@option\@empty\else\psk@@chartUserColor#2,#3,\@nil\fi}%
\psset[pstricks-add]{userColor={}}

\define@key[psset]{pstricks-add}{chartNodeI}{\def\psk@chartNodeI{#1}}
\define@key[psset]{pstricks-add}{chartNodeO}{\def\psk@chartNodeO{#1}}
\psset[pstricks-add]{chartNodeI=0.75,chartNodeO=1.5}
%
\def\psChart{\pst@object{psChart}}
\def\psChart@i#1#2#3{%
% #1:values  #2:separated charts
% #3 radius->pie; max height->histogram
  \pst@killglue%
  \global\pssetylength\pst@chartHeight{#3}%
  \global\let\pst@chartRadius\pst@chartHeight%
  \begingroup
  \edef\psk@chartValues{#1}%
  \def\psk@chartSepValues{#2}% only valid for a pie chart
  \pst@dimm=\z@% sum of all entries (for a pie)
  \pst@cnta=1\relax% number of entries
  \pst@dimn=\z@% greatest entry
  \psforeach{\chart@tempA}{#1}{%
    \global\advance\pst@cnta by \@ne%			% no of entries
    \global\advance\pst@dimm by \chart@tempA\p@%	% sum of all entries
    \pst@dima=\chart@tempA\p@% 
    \ifdim\pst@dima>\pst@dimn\global\pst@dimn=\pst@dima\fi%
  }%
  \addbefore@par{linejoin=2,dimen=outer}%
  \begin@SpecialObj%
  \ifnum\psk@chartColor>0\relax%
    \chart@ColorStep=400\p@\else\chart@ColorStep=\p@\fi	% the "numerical color"
  \divide\chart@ColorStep by \pst@cnta%			% step =1/no or 400/no
  \chart@ColorIndex=\psk@chartColor\p@%			% the start color (gray or wave)
  \@nameuse{pscs@\psk@chartStyle}%
  \end@SpecialObj%
  \endgroup%
  \ignorespaces%
}
%
\def\pscs@pie{%
  \degrees[\pst@number\pst@dimm]%			% instead of 360 degrees
  \def\chart@alpha{0}%
  \pst@dimm=\z@\pst@dimn=\z@\pst@dimo=\z@\pst@cnta=0\relax%
  \global\chart@Toggle=1\relax%
  \ifpsshadow%						create shadow first
    \psforeach{\chart@tempA}{\psk@chartValues}{%
      \global\advance\pst@dimm by \chart@tempA\p@%
      \global\advance\pst@dimn by \chart@alpha\p@%
      \global\advance\pst@cnta by \@ne%
      \pst@dimo=0.5\pst@dimn\advance\pst@dimo by 0.5\pst@dimm%	half angle of the chart
      \global\@chartSepfalse%
      \if$\psk@chartSepValues$\else%
        \psforeach{\chart@tempC}{\psk@chartSepValues}{\ifnum\chart@tempC=\the\pst@cnta\relax\global\@chartSeptrue\fi}%
      \fi%
      \if@chartSep% 
        \pswedge(\psk@chartSep\p@;\pst@number\pst@dimo){\pst@chartRadius}{\pst@number\pst@dimn}{\pst@number\pst@dimm}%
      \else%
        \pswedge(0,0){\pst@chartRadius}{\pst@number\pst@dimn}{\pst@number\pst@dimm}%
      \fi%
      \global\let\chart@alpha\chart@tempA%
    }%
    \psshadowfalse%
  \fi%
  \def\chart@alpha{0}%
  \pst@dimm=0pt\pst@dimn=0pt\pst@dimo=0pt\pst@cnta=0\relax%
  \psForeach{\chart@tempA}{\psk@chartValues}{%
    \global\advance\pst@dimm by \chart@tempA\p@%
    \global\advance\pst@dimn by \chart@alpha\p@%
    \def\pst@tempB{\pst@number\chart@ColorIndex}%
%    \psDEBUG[psChart:wave:color]{\pst@tempB}%
    \global\advance\pst@cnta by \@ne%
    \if@chartUserColor\else%
      \def\chart@FillColor{chartFillColor\the\pst@cnta}%
      \ifnum\psk@chartColor>0\relax%
        \xglobal\definecolor{\chart@FillColor}{wave}{\pst@tempB}%
      \else\xglobal\definecolor{\chart@FillColor}{gray}{\pst@tempB}\fi%
    \fi%
    \pst@dimo=0.5\pst@dimn\advance\pst@dimo by 0.5\pst@dimm%	half angle of the chart
    \global\@chartSepfalse%
    \if$\psk@chartSepValues$\else%
      \psForeach{\chart@tempC}{\psk@chartSepValues}{\ifnum\chart@tempC=\the\pst@cnta\relax\global\@chartSeptrue\fi}%
    \fi%
    \if@chartSep
      \ifPst@uselinecolor
        \pswedge[linecolor=\pslinecolor,fillstyle=solid,fillcolor={chartFillColor\the\pst@cnta}]%
          (\psk@chartSep\p@;\pst@number\pst@dimo){\pst@chartRadius}{\pst@number\pst@dimn}{\pst@number\pst@dimm}%
      \else
        \pswedge*[linecolor={chartFillColor\the\pst@cnta}]%
           (\psk@chartSep\p@;\pst@number\pst@dimo){\pst@chartRadius}{\pst@number\pst@dimn}{\pst@number\pst@dimm}%
      \fi
      \pst@dima=\pst@chartRadius\advance\pst@dima by \psk@chartSep\p@%
      \pnode(\pst@dima;\pst@number\pst@dimo){psChart\the\pst@cnta}%
      \pst@dimb=\psk@chartNodeI\pst@dima%
      \pst@dimc=\psk@chartNodeO\pst@dima%
      \pnode(\pst@dimb;\pst@number\pst@dimo){psChartI\the\pst@cnta}%
      \pnode(\pst@dimc;\pst@number\pst@dimo){psChartO\the\pst@cnta}%
    \else%
      \ifPst@uselinecolor
        \pswedge[linecolor=\pslinecolor,fillstyle=solid,fillcolor={chartFillColor\the\pst@cnta}](0,0)%
          {\pst@chartRadius}{\pst@number\pst@dimn}{\pst@number\pst@dimm}%
      \else
        \pswedge*[linecolor={chartFillColor\the\pst@cnta}](0,0)%
          {\pst@chartRadius}{\pst@number\pst@dimn}{\pst@number\pst@dimm}%
      \fi
      \pnode(\pst@chartRadius;\pst@number\pst@dimo){psChart\the\pst@cnta}%
      \pst@dima=\pst@chartRadius%
      \pst@dimb=\psk@chartNodeI\pst@dima%
      \pst@dimc=\psk@chartNodeO\pst@dima%
      \pnode(\pst@dimb;\pst@number\pst@dimo){psChartI\the\pst@cnta}%
      \pnode(\pst@dimc;\pst@number\pst@dimo){psChartO\the\pst@cnta}%
    \fi%
    \global\let\chart@alpha\chart@tempA%
    \global\advance\chart@Toggle by \@ne%
    \ifnum\chart@Toggle<3\relax%
      \global\advance\chart@ColorIndex by 2\chart@ColorStep%
    \else%
      \global\chart@Toggle=0%
      \global\advance\chart@ColorIndex by -\chart@ColorStep%
    \fi%
  }% end foreach
  \ignorespaces%
}
%
\def\pscs@histogram{%
  \def\chart@maxValue{\pst@number\pst@dimn}%		max of the data
  \pst@@divide\pst@dimn\pst@chartHeight%		maxValue/maxHeight
  \psDEBUG[pscs@histogram]{chart@maxValue=\chart@maxValue}
  \psDEBUG[pscs@histogram]{(maxValue/maxHeight)pst@dimg=\pst@number\pst@dimg}
  \psDEBUG[pscs@histogram]{pst@chartHeight=\the\pst@chartHeight}
  \pst@dimo=28.46\pst@dimg
  \edef\pst@chartUnit{\pst@number\pst@dimo}
%  \psaxes[axesstyle=frame,
%    dy=1cm,Dy=\pst@number\pst@dimo](\the\pst@cnta,\the\pst@chartHeight)
  \pst@dimm=0pt\pst@dimn=0pt\pst@dimo=0pt\pst@cnta=0%
  \global\chart@Toggle=1
  \psforeach{\chart@tempA}{\psk@chartValues}{%
    \global\advance\pst@dimm by \chart@tempA pt%
    \def\pst@tempB{\pst@number\chart@ColorIndex}%
    \psDEBUG[psChart:wave:color]{\pst@tempB}%
    \global\advance\pst@cnta by \@ne%
    \if@chartUserColor\else
      \def\chart@FillColor{chartFillColor\the\pst@cnta}
      \ifnum\psk@chartColor>0 \xglobal\definecolor{\chart@FillColor}{wave}{\pst@tempB}%
      \else\xglobal\definecolor{\chart@FillColor}{gray}{\pst@tempB}\fi%
    \fi
    \psframe[linecolor={chartFillColor\the\pst@cnta},fillstyle=solid,fillcolor={chartFillColor\the\pst@cnta}]%
        (!\the\pst@cnta\space \psk@chartSep\space 28.46 div sub 0)
        (!\the\pst@cnta\space \psk@chartSep\space 28.46 div add \chart@tempA\space \pst@chartUnit\space div)
    \pnode(!\the\pst@cnta\space 0){psChart\the\pst@cnta}%
    \pnode(!\the\pst@cnta\space  \chart@tempA\space 2 div \pst@chartUnit\space div){psChartM\the\pst@cnta}%
    \pnode(!\the\pst@cnta\space  \chart@tempA\space \pst@chartUnit\space div){psChartT\the\pst@cnta}%
    \global\advance\chart@Toggle by \@ne
    \ifnum\chart@Toggle<3
      \global\advance\chart@ColorIndex by 2\chart@ColorStep
    \else
      \global\chart@Toggle=0
      \global\advance\chart@ColorIndex by -\chart@ColorStep%
    \fi%
  }% end foreach
}
%
\def\pst@stackList{}
\def\addbefore@stackList#1{%
  \ifx\pst@stackList\@empty
    \xdef\pst@stackList{#1}%
  \else
    \toks@{#1}%
    \pst@toks\expandafter{\pst@stackList}%
    \xdef\pst@stackList{\the\toks@,\the\pst@toks}%
  \fi%
}
%
\def\pscs@Histogram{%
  \psDEBUG[pscs@Histogram]{psk@chartStack=\psk@chartStack}%
  \def\chart@maxValue{\pst@number\pst@dimn}%		max of the data
  \pst@@divide\pst@dimn\pst@chartHeight%		maxValue/maxHeight
  \psDEBUG[pscs@Histogram]{chart@maxValue=\chart@maxValue}%
  \psDEBUG[pscs@Histogram]{(maxValue/maxHeight)pst@dimg=\pst@number\pst@dimg}%
  \psDEBUG[pscs@Histogram]{pst@chartHeight=\the\pst@chartHeight}%
  \pst@dimo=28.46\pst@dimg%
  \edef\pst@chartUnit{\pst@number\pst@dimo}%
%  \psaxes[axesstyle=frame,
%    dy=1cm,Dy=\pst@number\pst@dimo](\the\pst@cnta,\the\pst@chartHeight)
  \pst@dimm=0pt\pst@dimn=0pt\pst@dimo=0pt\pst@cnta=0%
  \global\chart@Toggle=1			% for color toggling
  \pst@cntn=0					% stacked step
  \pst@cnto=0					% for a stacked view
  \pst@cntp=\psk@chartStack			% for a stacked view
  \def\pst@stackList{}
  \psDEBUG[pscs@Histogram]{psk@chartStack=\the\pst@cntp}%
  \psforeach{\chart@tempA}{\psk@chartValues}{%	  the loop
    \ifnum\pst@cntp>0 				% stacked version?
      \advance\pst@cnto by \@ne 		% increase
      \psDEBUG[pscs@Histogram]{chart@tempA=\chart@tempA}%
      \expandafter\addbefore@stackList\expandafter{\chart@tempA}%
      \psDEBUG[pscs@Histogram]{stack list=\pst@stackList}%
      \ifnum\pst@cnto=\pst@cntp			% draw?
        \pst@cnto=\psk@chartStack\advance\pst@cnto by \m@ne
        \psforeach{\chart@tempB}{\pst@stackList}{%	  the stack loop
          \global\pst@cnta=\pst@cntn				% we do not need the value
          \psDEBUG[pscs@Histogram]{pst@cnto=\the\pst@cnto}%
          \psDEBUG[pscs@Histogram]{pst@chartStackDepth=\the\pst@chartStackDepth}%
          \psDEBUG[pscs@Histogram]{pst@chartStackWidth=\the\pst@chartStackWidth}%
          \edef\pst@tempA{\the\pst@cnto}%
          \psDEBUG[pscs@Histogram]{pst@tempA=\pst@tempA}%
          \ifnum\pst@cnto>0 
            \pst@dima=\pst@chartStackDepth%
            \pst@dimb=\pst@chartStackWidth%
            \divide \pst@dima by \pst@tempA%
            \divide \pst@dimb by \pst@tempA% 
          \else\pst@dima=\z@ \pst@dimb=\z@%
          \fi%
          \rput(\the\pst@dima, \the\pst@dimb){\pscs@Histogram@i{\chart@tempB}}
          \advance\pst@cnto by \m@ne		% decrease stack counter
        }%
        \advance\pst@cntn by \tw@ 		% increase
        \def\pst@stackList{}%			  reset stack list
        \pst@cnto=0				% reset stack counter
      \fi%
    \else%
      \pscs@Histogram@i{\chart@tempA}% non stacked version
    \fi%
  }% end foreach
}
%
\def\pscs@Histogram@i#1{% draw the 3d-like bar
    \def\pst@tempB{\pst@number\chart@ColorIndex}%
    \global\advance\pst@cnta by \@ne%
    \if@chartUserColor\else
      \def\chart@FillColor{chartFillColor\the\pst@cnta}
      \ifnum\psk@chartColor>0 \xglobal\definecolor{\chart@FillColor}{wave}{\pst@tempB}%
      \else\xglobal\definecolor{\chart@FillColor}{gray}{\pst@tempB}\fi%
    \fi
    \pspolygon[fillstyle=solid,fillcolor={chartFillColor\the\pst@cnta}]%
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div sub 0)% ll
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div add 0)% lr
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div 1.5 mul add \psk@chartSep\space 56.92 div)% 'lr 
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div 1.5 mul add 
    	    \psk@chartSep\space 56.92 div #1 \pst@chartUnit\space div add )% 'ur 
      (!\the\pst@cnta\space \psk@chartSep\space 56.92 div sub 
    	    \psk@chartSep\space 56.92 div #1 \pst@chartUnit\space div add )% 'ul 
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div sub #1 \pst@chartUnit\space div)%ul
    \psline%
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div add 0)% lr
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div add #1 \pst@chartUnit\space div)
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div sub #1 \pst@chartUnit\space div)%ul
    \psline%
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div add #1 \pst@chartUnit\space div)
      (!\the\pst@cnta\space \psk@chartSep\space 28.46 div 1.5 mul add 
    	    \psk@chartSep\space 56.92 div #1 \pst@chartUnit\space div add )% 'ur 
     \pnode(!\the\pst@cnta\space 0){psChart\the\pst@cnta}%
     \pnode(!\the\pst@cnta\space  #1 2 div \pst@chartUnit\space div){psChartM\the\pst@cnta}%
     \pnode(!\the\pst@cnta\space  #1 \pst@chartUnit\space div){psChartT\the\pst@cnta}%
    \global\advance\chart@Toggle by \@ne
    \ifnum\chart@Toggle<3
      \global\advance\chart@ColorIndex by 2\chart@ColorStep
    \else
      \global\chart@Toggle=0
      \global\advance\chart@ColorIndex by -\chart@ColorStep%
    \fi%
     \global\advance\chart@ColorIndex by 1pt
}
%
\define@key[psset]{pstricks-add}{cancelType}{\pst@expandafter\psk@@cancelType{#1xx}\@nil}
\def\psk@@cancelType#1#2\@nil{%
  \ifx\relax#1\relax\def\psk@cancelType{2}\else% x
    \ifx#1B\def\psk@cancelType{5}\else%          \                                           new option B
      \ifx#1S\def\psk@cancelType{4}\else%          \                                         new option S
        \ifx#1X\def\psk@cancelType{3}\else%          \                                       new option X
          \ifx#1b\def\psk@cancelType{2}\else%          \
            \ifx#1s\def\psk@cancelType{1}\else%        /
              \def\psk@cancelType{0}\fi\fi\fi\fi\fi\fi}%        x every other

\psset[pstricks-add]{cancelType=}% x, crossing 
\def\psCancel{\def\pst@par{}\pst@object{psCancel}}% by Stefano Baroni 2008-06-21
\def\psCancel@i{\pst@makebox\psCancel@iii}
\def\psCancel@iii{%
  \begingroup
  \solid@star
  \use@par
  \ifnum\psk@cancelType>\tw@ %                                     check if \psk@cancelType > 2
  % here: option cancelType with small letter X, S, B
    \pst@dimc=\wd\pst@hbox
    \pst@dimb=\dp\pst@hbox
    \pst@dimd=\ht\pst@hbox
    \pst@dima=\z@
    \edef\psk@cancelType{\the\numexpr\psk@cancelType-3\relax}
  \else
  % here: option cancelType with capital letter x, s, b            set \pst@diam as before
    \pst@dima=\pslinewidth
    \advance\pst@dima by \psframesep
    \pst@dimc=\wd\pst@hbox\advance\pst@dimc by \pst@dima
    \pst@dimb=\dp\pst@hbox\advance\pst@dimb by \pst@dima
    \pst@dimd=\ht\pst@hbox\advance\pst@dimd by \pst@dima
  \fi
  \setbox\pst@hbox=\hbox{%
    \ifpsboxsep\kern\pst@dima\fi
    \begin@ClosedObj
    \addto@pscode{
      \psk@cornersize % arcradius boolean
      \pst@number\pst@dima neg
      \pst@number\pst@dimb neg
      \pst@number\pst@dimc
      \pst@number\pst@dimd
       .5 
      \if@star \tx@Frame \else
         CLW mul /a ED			% the middle of the line
         3 -1 roll 2 copy gt { exch } if
         a sub /y2 ED 
         a add /y1 ED 
         2 copy gt { exch } if
         a sub /x2 ED 
         a add /x1 ED 
         pop pop 			% delete arc values
         \ifnum\psk@cancelType<\tw@ % / or x (1 oder 0)
           x1 y1 moveto 
           x2 y2 lineto 
         \fi
         \ifnum\psk@cancelType=\@ne\else % \ or x (2 oder 0)
           x2 y1 moveto 
           x1 y2 lineto
         \fi
       \fi
     }%
     \def\pst@linetype{2}%
     \showpointsfalse
     \end@ClosedObj
     \box\pst@hbox
     \ifpsboxsep\kern\pst@dima\fi
   }%
   \ifpsboxsep\dp\pst@hbox=\pst@dimb\ht\pst@hbox=\pst@dimd\fi
   \leavevmode\box\pst@hbox
   \endgroup%
}

\iffalse
\define@key[psset]{pstricks-add}{cancelType}{\pst@expandafter\psk@@cancelType{#1xx}\@nil}
\def\psk@@cancelType#1#2\@nil{%
  \ifx\relax#1\relax\def\psk@cancelType{2}\else% x
    \ifx#1b\def\psk@cancelType{2}\else%          \
      \ifx#1s\def\psk@cancelType{1}\else%        /
        \def\psk@cancelType{0}\fi\fi\fi}%        x every other

\psset[pstricks-add]{cancelType=}% x, crossing 
\def\psCancel{\def\pst@par{}\pst@object{psCancel}}% by Stefano Baroni 2008-06-21
\def\psCancel@i{\pst@makebox\psCancel@iii}
\def\psCancel@iii{%
  \begingroup
  \solid@star
  \use@par
  \pst@dima=\pslinewidth
  \advance\pst@dima by \psframesep
  \pst@dimc=\wd\pst@hbox\advance\pst@dimc by \pst@dima
  \pst@dimb=\dp\pst@hbox\advance\pst@dimb by \pst@dima
  \pst@dimd=\ht\pst@hbox\advance\pst@dimd by \pst@dima
  \setbox\pst@hbox=\hbox{%
    \ifpsboxsep\kern\pst@dima\fi
    \begin@ClosedObj
    \addto@pscode{
      \psk@cornersize % arcradius boolean
      \pst@number\pst@dima neg
      \pst@number\pst@dimb neg
      \pst@number\pst@dimc
      \pst@number\pst@dimd
       .5 
      \if@star \tx@Frame \else
         CLW mul /a ED			% the middle of the line
         3 -1 roll 2 copy gt { exch } if
         a sub /y2 ED 
         a add /y1 ED 
         2 copy gt { exch } if
         a sub /x2 ED 
         a add /x1 ED 
         pop pop 			% delete arc values
         \ifnum\psk@cancelType<\tw@ % / or x
           x1 y1 moveto 
           x2 y2 lineto 
         \fi%
         \ifnum\psk@cancelType=\@ne\else % \ or x
           x2 y1 moveto 
           x1 y2 lineto
         \fi
       \fi
     }%
     \def\pst@linetype{2}%
     \showpointsfalse
     \end@ClosedObj
     \box\pst@hbox
     \ifpsboxsep\kern\pst@dima\fi%
   }%
   \ifpsboxsep\dp\pst@hbox=\pst@dimb\ht\pst@hbox=\pst@dimd\fi
   \leavevmode\box\pst@hbox
   \endgroup%
}
\fi
%
\newcount\psVectorCtr
\define@boolkey[psset]{pstricks-add}[Pst@]{markAngle}[true]{}
\psset[pstricks-add]{markAngle=false}
%
\newpsstyle{psMarkAngleStyle}{arrows=->,arrowsize=4pt}
\newpsstyle{psMarkAngleLineStyle}{linestyle=dotted,arrows=-}
%
\def\psStartPoint{\@ifnextchar[{\psStartPoint@i}{\psStartPoint@i[Vector]}}
\def\psStartPoint@i[#1](#2){%
  \global\psVectorCtr=\@ne
  \gdef\psVectorName{#1}%
  \pnode(#2){#10}%
%  \pst@getcoor{#2}\pst@vector@cp 
  \pstVerb{ 
    gsave tx@Dict begin
    STV CP T \psGetNodeCenter{#10}
    /cp.X  #10.x def /cp.Y #10.y def
%           \pst@vector@cp 
%           \pst@number\psyunit mul /cp.Y exch def 
%           \pst@number\psxunit mul /cp.X exch def 
   end grestore }%
  \ignorespaces}
%
\def\psVector{\pst@object{psVector}}
\def\psVector@i{%
  \pst@killglue
  \addbefore@par{arrows=->,arrowsize=6pt}%
%  \addto@par{showpoints=false}%
  \psVector@ii}

\def\psVector@ii{\@ifnextchar<\psVector@iii\psVector@iv}%
\def\psVector@iii<#1>{\psStartPoint(#1)\psVector@iv}

\def\psVector@iv(#1){%
  \pst@getcoor{#1}\pst@tempCoor
  \begingroup
  \use@keep@par
  \pst@cntm=\the\psVectorCtr \advance\pst@cntm by \m@ne
  \rput(\psVectorName\the\pst@cntm){% \else cp.X cp.Y \fi){%
    \pnode(0,0){@@@A}\pnode(#1){@@@B}
    \ifPst@markAngle
      \psarc[style=psMarkAngleStyle](0,0){1}{0}{!\pst@tempCoor exch atan}%
      \psline[style=psMarkAngleLineStyle](1.5,0)%
    \fi}%
  \ncline[nodesep=0pt]{@@@A}{@@@B}
  \pnode(! \pst@tempCoor \pst@number\psyunit div cp.Y add exch
                         \pst@number\psxunit div cp.X add exch ){\psVectorName\the\psVectorCtr}%
  \global\advance\psVectorCtr by \@ne%
  \endgroup
  \pst@Verb{  
    \pst@tempCoor 
    \pst@number\psyunit div cp.Y add /cp.Y exch def 
    \pst@number\psxunit div cp.X add /cp.X exch def 
  }%  
  \@ifnextchar(\psVector@iv\ignorespaces}
%
\define@key[psset]{pstricks-add}{basename}{\def\psk@basename{#1}}%
\psset[pstricks-add]{basename=}%
%
\def\psCircleTangents{\pst@object{psCircleTangents}}
\def\psCircleTangents@i(#1){\@ifnextchar({\psCircleTangents@ii(#1)}{\psCircleTangents@iii(#1)}}%
\def\psCircleTangents@ii(#1)(#2)#3{%  (viewpoint) (circle) {radius}
    \pst@killglue
    \begingroup
       \pst@getlength{#3}\pst@LengthA
       \addbefore@par{basename=CircleT}%
       \use@par
%       \edef\@cmd{\noexpand\psEllipseTangentsN(#2)(! \pst@LengthA dup 
%       \pst@number\psxunit div exch \pst@number\psyunit div )(#1){\psk@basename}}%
%       \@cmd
       \psEllipseTangentsN(#2)(!\pst@LengthA dup \pst@number\psxunit div exch \pst@number\psyunit div )(#1){\psk@basename}%
    \endgroup
  \ignorespaces
}%
\def\psCircleTangents@iii(#1)#2(#3)#4{%  two circles--- (Cntr1){radius1}(Cntr2){radius2}
  \pst@killglue
  \begingroup
     \pst@getlength{#2}\pst@LengthA% radius1
     \pst@getlength{#4}\pst@LengthB% radius2
     \addbefore@par{basename=CircleT}%
     \use@par
     \psLCNodeVar(#1)(#3)(! \pst@LengthA \pst@number\psrunit div dup \pst@LengthB 
     \pst@number\psrunit div % r1 r1 r2 on stack
     3 copy add div /tti ED sub dup 0 eq % r1 r1-r2 on stack
     { pop pop /ttx 1000 def }{ div dup abs 1000 gt % r1/(r1-r2) on stack
     { 0 gt { ttx 1000 def }{ ttx -1000 def } ifelse}{ /ttx ED } ifelse } ifelse 
     1 tti sub tti )% 1-tti tti on stack
     {\psk@basename C1}%
     % tti=r1/(r1+r2), ttx=r1/(r1-r2)
     \psLCNodeVar(#1)(#3)(! 1 ttx sub ttx ){\psk@basename C2}% outside crossing pt
     \expandafter\psCircleTangents@ii\expandafter(\psk@basename C1)(#1){#2}%
     \pnode(CircleT1){\psk@basename I1}\pnode(CircleT2){\psk@basename I3}%
     \expandafter\psCircleTangents@ii\expandafter(\psk@basename C1)(#3){#4}%
     \pnode(CircleT1){\psk@basename I2}\pnode(CircleT2){\psk@basename I4}%
     % external tangents
     \expandafter\psCircleTangents@ii\expandafter(\psk@basename C2)(#1){#2}%
     \pnode(CircleT1){\psk@basename O2}\pnode(CircleT2){\psk@basename O4}%
     \expandafter\psCircleTangents@ii\expandafter(\psk@basename C2)(#3){#4}%
     \pnode(CircleT1){\psk@basename O1}\pnode(CircleT2){\psk@basename O3}%
  \endgroup%
  \ignorespaces%  
}%
%
\def\psEllipseTangents{\pst@object{psEllipseTangents}}
\def\psEllipseTangents@i(#1)(#2)(#3){% (Center)(axes)(viewpoint)
   \pst@killglue{%
   \use@par% only one parameter matters---psk@basename
   \ifx\psk@basename\@empty \def\psk@basename{EllipseT}\fi %
   \edef\@cmd{\noexpand\psEllipseTangentsN(#1)(#2)(#3){\psk@basename}}%
   \@cmd}\ignorespaces}%
%
\def\psEllipseTangentsN(#1)(#2)(#3)#4{%  (xe,ye)(a,b)(xP,yP){basename} % no optional arguments
  \pst@killglue
%  \pst@getcoor{#1}\pst@tempA
  \pnode(#1){E@Cntr}%
  \pnode(#2){@@TMP}%
  \pnode(#3){@@@TMP}% (center)(semimajor, semiminor)(viewpt)
  \pst@getcoor{#3}\my@tempC% external viewpoint
  \AtoB(E@Cntr)(@@@TMP){@TMP}% center to viewpoint
  \ifnum\Pst@Debug>0
    \shownode(E@Cntr)%
    \shownode(@TMP)%
    \shownode(@@@TMP)%
  \fi
  \pnode(! 
     \psGetNodeCenter{E@Cntr}\space
     /Xc E@Cntr.x def /Yc E@Cntr.y def
     \psGetNodeCenter{@@TMP}\space
     /B @@TMP.y def % semiminor
     /A @@TMP.x def % semimajor
     \psGetNodeCenter{@TMP}\space
     /Xp @TMP.x def /Yp @TMP.y def % center to viewpoint
%
     /A2 A dup mul def /B2 B dup mul def 
     /C2 B A div dup mul def 
     /Xp2 Xp dup mul def /Yp2 Yp dup mul def
     /R Xp2 A2 sub C2 mul Yp2 add Sqrt def % R=Sqrt{(Xp2-A2) C2 + Yp2}
     /Q C2 Xp2 mul Yp2 add def % C2 Xp2 + Yp2
     /Xta B2 Xp mul A Yp R mul mul sub Q div def
     /Yta Yp Xp R mul A div add B2 mul Q div def
     /Xtb B2 Xp mul A Yp R mul mul add Q div def
     /Ytb Yp Xp R mul A div sub B2 mul Q div def
     0 Xta Yp mul Yta Xp mul sub gt % swap a, b
       { /A Xta def /B Yta def /Xta Xtb def /Yta Ytb def /Xtb A def /Ytb B def } if
          Xta Xc add %/xTemp ED 
          Yta Yc add %/yTemp ED
%     xTemp Xc yTemp Yc Pyth2 /Length ED
%     xTemp Xc sub yTemp Yc sub exch atan 0 add Length exch PtoC 
%     Yc add exch Xc add exch 
          ) {#42}%
  \pnode(! Xtb Xc add Ytb Yc add ) {#41}%
 \ignorespaces}% 
%
\define@key[psset]{pstricks-add}{rotate}{\def\psk@rotate{#1 }}
\psset[pstricks-add]{rotate=0}

\def\pst@saveDegrees{}

\def\psKiviat{\pst@object{psKiviat}}
\def\psKiviat@i#1#2{%  #1: number of edges #2 radius
  \gdef\pst@saveDegrees{#1}
  \begingroup%
  \degrees[#1]%
  \SpecialCoor%
  \addbefore@par{rotate=0}
  \use@par%
  \global\let\psk@@rotate\psk@rotate
  \def\pst@Coordinates{}
  \psLoop{#1}{\xdef\pst@Coordinates{\pst@Coordinates(#2;\the\psLoopIndex)}}
  \rput{\psk@rotate}(0,0){\expandafter\pspolygon\pst@Coordinates
    \multido{\nA=0+1}{#1}{\uput{\pslabelsep}[\nA]{*0}(#2;\nA){\psPutYLabel{\nA}}}}
  \endgroup%
  \ignorespaces}
%
\def\psKiviatLine{\pst@object{psKiviatLine}}
\def\psKiviatLine@i#1{{%
  \addbefore@par{showpoints}%
  \use@par%
  \degrees[\pst@saveDegrees]%
  \psKiviatLine@ii#1\@nil}}%
\def\psKiviatLine@ii#1,#2\@nil{%
  \global\pst@cntm=0
  \global\pst@cntn=1
  \begingroup
  \xdef\pst@saveCoors{}
  \psKiviatLine@iii#1,#2,#1,,\@nil
  \rput{\psk@@rotate}(0,0){\expandafter\pspolygon\pst@saveCoors}
}
\def\psKiviatLine@iii#1,#2,#3\@nil{%
  \ifx\relax#2\relax\else%\psline(#1;\the\pst@cntm)(#2;\the\pst@cntn)
      \xdef\pst@saveCoors{\pst@saveCoors(#1;\the\pst@cntm)}\fi
  \advance\pst@cntm\@ne
  \advance\pst@cntn\@ne
  \ifx\relax#3\relax\endgroup\else\psKiviatLine@iii#2,#3\@nil\fi}
%
\def\psKiviatTicklines{\pst@object{psKiviatTicklines}}
\def\psKiviatTicklines@i#1#2{{%  n, radius
  \degrees[#1]%
  \use@par%
  \pstFPDiv\pst@tempN{#2}{\psk@Dx}% 
  \pst@cntm=\pst@tempN \advance\pst@cntm by \m@ne
  \multido{\rA=\psk@Dx+\psk@Dx}{\the\pst@cntm}{%
    \def\pst@Coordinates{}%
    \psLoop{#1}{\xdef\pst@Coordinates{\pst@Coordinates(\rA;\the\psLoopIndex)}}%
    \rput{\psk@@rotate}(0,0){\expandafter\pspolygon\pst@Coordinates}%
  }%
}\ignorespaces}%
%
\def\psKiviatAxes{\pst@object{psKiviatAxes}}
\def\psKiviatAxes@i#1#2{{%
  \degrees[#1]
  \use@par%
  \multido{\iA=0+1}{#1}{\rput{\psk@@rotate}(0,0){\psline(0,0)(#2;\iA)}}%
  }\ignorespaces}%
%
\define@key[psset]{pstricks-add}{colSteps}{\def\psk@colSteps{#1 }}
\define@boolkey[psset]{pstricks-add}[Pst@]{colored}[true]{}
\define@key[psset]{pstricks-add}{colorOffset}[]{\def\psk@colorOffset{#1 }}
\psset[pstricks-add]{colSteps=0,colored=false,colorOffset=}% continuing colors and grayscale
%
\def\pstContour{\pst@object{pstContour}}
\def\pstContour@i#1{%
\addbefore@par{radius=1pt}
\begin@SpecialObj%
  \pssetlength\pst@dimb\psk@radius
  \addto@pscode{
    (#1) run
    /zMax 0 def /zMin 0 def 			% lowest and highest value
    contourdata aload length /N_data ED 	% get the no of arrays
    N_data{					% inside contourdata
      /data ED 					% save first inner array
      data aload length 3 div round cvi {	% get the records
        \psk@colorOffset 
        dup zMin lt 				% z<zMin?
	  { /zMin ED }				% yes, save it
	  { dup zMax gt { /zMax ED }{ pop } ifelse } ifelse
        pop pop					% delete x y 
      } repeat
    } repeat
    clear					% clear stack
    /dz zMax zMin sub def			% value range
    /steps \psk@colSteps\space 0 gt { true }{ false } ifelse def
    0 1 N_data 1 sub { 				% for i=0 to N-1
      contourdata exch get /data ED		% get first array
      data aload length 3 div round cvi 1 sub { %0 .. length-1
        \psk@colorOffset
        /z_data ED /y_data ED /x_data ED
        z_data zMin sub dz div 			% relative z (0..1)
        \ifPst@colored 400 mul 380 add tx@addDict begin wavelengthToRGB 
           Red Green Blue end setrgbcolor 	% set color	
        \else
          steps {\psk@colSteps\space mul round \psk@colSteps\space div} if
          setgray 
	\fi
        x_data \pst@number\psxunit mul y_data \pst@number\psyunit mul 
        \pst@number\pst@dimb 0 360 arc fill 
      } repeat
    } for
  }%
\end@SpecialObj
}

\newrgbcolor{OlympicRed}{0.87 0 0.14}
\newrgbcolor{OlympicGreen}{0 0.62 0.24}
\newrgbcolor{OlympicBlue}{0 0.52 0.78}
\newrgbcolor{OlympicYellow}{0.96 0.78 0}
%\definecolor{oblue}{rgb}{0,.52,.78}
%\definecolor{oyellow}{rgb}{.96,.76,0}
%\definecolor{ogreen}{rgb}{0,.62,.24}
%\definecolor{ored}{rgb}{.87,0,.14}

\def\ps@lympicRing(#1)#2{%
  \rput(#1){%
	\pscircle[linewidth=0.25,linecolor=#2](0,0){1.375}%
	\pscircle[linewidth=0.05,linecolor=\pst@bgcolor](0,0){1.525}%
	\pscircle[linewidth=0.05,linecolor=\pst@bgcolor](0,0){1.225}}}

\def\ps@lympicArc(#1)#2#3#4{%
  \rput(#1){%
	\psarc[linewidth=0.25,linecolor=#2](0,0){1.375}{#3}{#4}%
	\psarc[linewidth=0.05,linecolor=\pst@bgcolor](0,0){1.525}{#3}{#4}%
	\psarc[linewidth=0.05,linecolor=\pst@bgcolor](0,0){1.225}{#3}{#4}}}

\def\psOlympicRings{\pst@object{psOlympicRings}}

\def\psOlympicRings@i(#1){%
  \pst@killglue
  \begingroup
  \addbefore@par{bgcolor=white,dimen=inner,psscale=1,dimen=middle}%  
  \use@par
  \rput(#1){%
    \psscalebox{\psk@@psscale}{%
      \ps@lympicRing(-3.2,0){OlympicBlue}%
      \ps@lympicRing(-1.6,-1.375){OlympicYellow}%
      \ps@lympicArc(-3.2,0){OlympicBlue}{330}{30}%
      \ps@lympicRing(0,0){black}%
      \ps@lympicArc(-1.6,-1.375){OlympicYellow}{30}{90}%
      \ps@lympicRing(1.6,-1.375){OlympicGreen}%
      \ps@lympicArc(0,0){black}{330}{30}%
      \ps@lympicRing(3.2,0){OlympicRed}%
      \ps@lympicArc(1.6,-1.375){OlympicGreen}{30}{90}
    }%
  }%
  \endgroup
}

\def\resetOptions{%
  \def\pst@linetype{0}%
%  \pstScalePoints(1,1){}{}%
  \psset[pstricks-add]{%
    randomPoints=1000,color=false,
    whichabs={},whichord={},
    plotfuncx={},plotfuncy={},buildvector=false,
    Derive={},adamsorder=4,
    Tnormal=false,
    braceWidth=2\pslinewidth,
    bracePos=0.5,
    braceWidthInner=10\pslinewidth,
    braceWidthOuter=10\pslinewidth,
    chartNodeI=0.75,
    chartNodeO=1.5,
    markAngle=false,
    colSteps=0,
    colored=false,
    randInit,
}}
%
\resetOptions
%
\catcode`\@=\PstAtCode\relax
%
%% END: pstricks-add.tex
\endinput
