%\iffalse
%<*copyright>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% aeb_pro.sty package,                                 %%
%% Copyright (C) 2006--2017  D. P. Story                %%
%%   dpstory@acrotex.net                                %%
%%                                                      %%
%% 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.2 of    %%
%% the License, or (at your option) any later version.  %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%</copyright>
%<package>\NeedsTeXFormat{LaTeX2e}[1997/12/01]
%<package>\ProvidesPackage{aeb_pro}
%<package> [2017/03/08 v2.8a aeb_pro: A support package (dps)]
%<*driver>
\documentclass{ltxdoc}
\usepackage[colorlinks,hyperindex=false]{hyperref}
\pdfstringdefDisableCommands{\let\\\textbackslash}
\def\CMD#1{\textbackslash{#1}}\def\EXCL{!}
\let\opt\texttt \let\app\textsf \let\pkg\textsf \let\env\texttt
\OnlyDescription  % comment out for implementation details
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\bgroup\ttfamily
\gdef\brpr#1{\char123\relax#1\char125\relax}\egroup
\let\darg\brpr
\let\env\texttt
\let\opt\texttt
\let\app\textsf
\def\visispace{\symbol{32}}
\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
\def\meta#1{\textsl{\texttt{#1}}}
\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}}
\InputIfFileExists{aebdocfmt.def}{\PackageInfo{aeb_pro}{Inputting aebdocfmt.def}}
    {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
     \PackageInfo{aeb_pro}{aebdocfmt.def cannot be found}}
\begin{document}
  \GetFileInfo{aeb_pro.sty}
  \title{aeb\_pro\\as suggested by J\"{u}rgen Gilg}
  \author{D. P. Story\\
    Email: \texttt{dpstory@acrotex.net}}
  \date{processed \today}
  \maketitle
  \tableofcontents
  \DocInput{aeb_pro.dtx}
\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here.\\Execute
    \texttt{makeindex -s gind.ist -o aeb\_pro.ind aeb\_pro.idx} on the command line and recompile
    \texttt{aeb\_pro.dtx}.}
\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here.\\Execute
    \texttt{makeindex -s gglo.ist -o aeb\_pro.gls aeb\_pro.glo} on the command line and recompile
    \texttt{aeb\_pro.dtx}.}
\end{document}
%</driver>
% \fi
% \MakeShortVerb{|}
% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{aeb_pro}{Inputting aebdonotindex.def}}
%    {\PackageInfo{aeb_pro}{cannot find aebdonotindex.def}}
%
%    \begin{macrocode}
% Begin package segment
%<*package>
%    \end{macrocode}
% \changes{v1.9}{2016/03/03}{Allow users of pdftex and xetex to access JavaScript related
% methods provided they use \string\textsf{Acrobat} as their PDF reader.}
% \changes{v2.5}{2016/08/31}{Revised \string\texttt{aeb\_pro.js} to include
% \string\texttt{aebDocSaveAs()}.}
%
% \section{Introduction}
%
%    The \pkg{aeb\_pro} package that access the `advanced' features of the PDF
%    specification. It uses various combinations of driver-dependent code,
%    \textbf{pdfmark} code, and JavaScript methods and techniques that require
%    \app{Acrobat~7.0 Professional} for document assembly. The package provides
%    the \textbf{AeB Control Central}. Use the \textbf{AeB Control Central} to
%    load all your Acro\negthinspace\TeX packages in the correct order. See
%    additional remarks in the titled paragraph \textbf{\nameref{para:beast}}
%    below.
%
% \section{Declare Options}
%
%    We declare some options for this package.
%\changes{v2.2}{2016/07/26}{Removed the generation of \string\texttt{fsprodef.js} from the INS file.}
%    \begin{macrocode}
\RequirePackage{ifpdf}[2006/02/20]
\RequirePackage{ifxetex}[2006/08/21]
\RequirePackage{xkeyval}
%    \end{macrocode}
% Some standard flags used by this package.
%    \begin{macrocode}
\let\aebp@One=1 \let\aebp@Zero=0
\let\aebp@YES=y \let\aebp@NO=n
%    \end{macrocode}
% \subsection{AeB Control Central}
%
%    \noindent\IndexOpt{web}^^A
%    \IndexOpt{exerquiz}^^A
%    \IndexOpt{dljslib}^^A
%    \IndexOpt{eforms}
%    \IndexOpt{insdljs}^^A
%    \IndexOpt{eq2db}\par
%    \IndexOpt{aebxmp}^^A
%    \IndexOpt{hyperref}^^A
%    \IndexOpt{graphicxsp}^^A
%    \IndexOpt{rmannot}^^A
% \vskip-\baselineskip\noindent AeB control central
% is simply a set of options for including the
% other members of the AeB family.  This assures that the package are
% loaded in the correct order.
% The values of each of these option
% keys are the options of the packages they reference.
% \par\medskip\noindent
% (2016/12/09) Incorporate the version argument into package specification, for example,
%\begin{verbatim}
%   \usepackage[web={designi,forpaper,req=2016/11/03}]{aeb_pro}
%\end{verbatim}
%    The version takes a key of \texttt{req}, as shown above.
%    \changes{v0.8f}{2008/06/15}{Added \textsf{graphicxsp} to the list of support packages}
%    \changes{v2.7}{2016/12/10}{Incorporate the version argument into package specification}
%    \par\medskip\noindent
%    \cs{ap@csarg} is a convenience macro for working with command names.
%    \begin{macrocode}
\def\ap@csarg#1#2{\expandafter#1\csname#2\endcsname}
%    \end{macrocode}
%    Define an \pkg{xkeyval} family \texttt{aebpreq} with a single key \IndexKey{req}\texttt{req}. Later, we
%    use this key to separate package options from the key-value \texttt{req=\ameta{release date}}.
%    \begin{macrocode}
\define@key{aebpreq}{req}[]{\def\eq@pkgReq{#1}}
%    \end{macrocode}
%    A convenience command to save the value of package for later use.
%    \begin{macrocode}
\def\aebp@setCCOptions#1#2{%#1=package #2=options
    \ap@csarg\edef{aeb@#1@opts}{#2}}
%    \end{macrocode}
%    We not define options for \pkg{aeb\_pro} of \texttt{web}, \texttt{exerquiz}, \texttt{eforms}, \texttt{insdljs},
%    \texttt{eq2db}, \texttt{aebxmp}, \texttt{hyperref}, \texttt{graphicxsp}, and \texttt{rmannot}.
%    \begin{macrocode}
\@tfor\aeb@pcks:={web}{exerquiz}{dljslib}%
{eforms}{insdljs}{eq2db}{aebxmp}{hyperref}{graphicxsp}{rmannot}\do
{%
    \ap@csarg\let{aeb@\aeb@pcks @req}\@empty
    \ap@csarg\let{aeb@\aeb@pcks @opts}\relax
    \edef\aeb@pack@def{\noexpand
        \define@key{aeb_pro.sty}{\aeb@pcks}[]{%
            \noexpand\aebp@setCCOptions{\aeb@pcks}{##1}}%
    }\aeb@pack@def
}
%    \end{macrocode}
% We provide a convenient way to pass the \texttt{driver}\IndexOpt{driver} used, \texttt{dvips} or
% \texttt{dvipsone}. If the user chooses the \opt{web} option, then he/she might
% have a \texttt{web.cfg} file, so using this option may not be
% needed, in this case.
%    \begin{macrocode}
\let\aebp@passDriver\aebp@YES
\ifpdf\let\aebp@passDriver\aebp@NO\else
\ifxetex\let\aebp@passDriver\aebp@NO\fi\fi
\define@choicekey+{aeb_pro.sty}{driver}%
    {dvipsone,dvips,pdftex,dvipdfm,textures,%
    dvipdfmx,xetex}{%
    \def\aeb@driver{#1}\ifx\aeb@driver\@empty\else
        \PassOptionsToPackage{#1}{web}
        \PassOptionsToPackage{#1}{exerquiz}
\def\aebp@PassToHYIns{\PassOptionsToPackage{#1}{hyperref}
    \PassOptionsToPackage{#1}{insdljs}}
\ifx\aebp@passDriver\aebp@YES
    \expandafter\aebp@PassToHYIns\fi
        \PassOptionsToPackage{#1}{eforms}
        \PassOptionsToPackage{#1}{graphicxsp}
    \fi
}{\PackageError{aeb_pro}{Bad choice for the driver, permissible values
   \MessageBreak are dvipsone, dvips, pdftex, dvipdfm,
    textures,\MessageBreak dvipdfmx, and xetex}
    {Try again with a permissible driver name}}
\let\aeb@driver\@empty
%    \end{macrocode}
%
%    \paragraph*{On the nature of the beast}\label{para:beast} There are three types of commands
%    (and environments) in this package: (1) commands that use driver dependent
%    code, available to all workflows; (2) commands that depend on the
%    \textbf{pdfmark} operator, available only to the \app{dvips/Distiller}
%    workflow; and (3) commands that use `post-PDF creation' methods that rely
%    on the document author having the full \app{Acrobat} application.
%
%    For the workflow \app{dvips/Distiller}, all three code types are
%    available; for whose authors that prefer \app{pdflatex/\penalty0
%    lualatex/\penalty0 xelatex}, but \emph{do not have} the full
%    \texttt{Acrobat} product, the commands of type~(1) are available through
%    the \opt{nopro} option. Finally, for authors that prefer
%    \app{pdflatex/\penalty0 lualatex/\penalty0 xelatex} and \emph{do have}
%    \app{Acrobat}, the commands of type~(1) and~(3) are available through
%    the \opt{useacrobat} option.

% \subsection{The \texttt{useacrobat} option}
%
% If the document author has \app{Acrobat}, but wants to use
% \app{pdflatex}, \app{xelatex}, etc, we shall let them but under
% restricted conditions using the \opt{useacrobat}\IndexOpt{useacrobat} option.
% Essentially, all of \pkg{aeb\_pro} is available except for any commands that use
% layers; hence, the \opt{uselayers} and \opt{ocganime} options are not supported.
%    \begin{macrocode}
\newif\if@useacrobat \@useacrobatfalse
\DeclareOptionX{useacrobat}{\@useacrobattrue}
%    \end{macrocode}
%
% \subsection{\texttt{nopro} option}
%
% The normally \pkg{aeb\_pro} will brings in all the
% code that would require the use of the \app{Distiller} and \app{Acrobat Pro},
% this is the default. The \opt{nopro}\IndexOpt{nopro} option gives
% access, for non-\app{Distiller} workflows, to the \textbf{AeB Control Center} and to all commands that do
% no involve layers or post-PDF creation methods.
%    \begin{macrocode}
\newif\if@gopro \@goprotrue
\DeclareOptionX{nopro}{\@useacrobattrue\@goprofalse
    \PassOptionsToPackage{nopro}{insdljs}}
%    \end{macrocode}
% \paragraph*{Input \texttt{aebpro.def}} We input \texttt{aebpro.def} at the end of the package.
%    \begin{macrocode}
\def\aeb@InputAeBPro{\InputIfFileExists{aebpro.def}%
    {\PackageInfo{aeb_pro}{Inputting code for the pro option}}%
    {\PackageInfo{aeb_pro}{Cannot find aebpro.def.
        Reinstall or refresh your file name database, as needed.}}}
\AtEndOfPackage{\aeb@InputAeBPro}
%    \end{macrocode}
%
% \subsection{\texttt{uselayers} option}
% The \texttt{uselayers}\IndexOpt{uselayers} option activates the use of
% Optional Content Groups, a.k.a., layers.
%    \begin{macrocode}
\let\aebp@uselayers=0
\DeclareOptionX{uselayers}{%
    \ifx\aebp@uselayers0\AtEndOfPackage{\aeb@InputAeBLayers}%
    \global\let\aebp@uselayers=1\fi
}
\def\aeb@InputAeBLayers{\InputIfFileExists{aeblayers.def}%
    {\PackageInfo{aeb_pro}{Inputting code for uselayers option}}%
    {\PackageInfo{aeb_pro}{Cannot find aeblayers.def.
        Reinstall or refresh your file name database.}}}
%    \end{macrocode}
%
% \subsection{\texttt{gopro} option}
% Some of the components of AeB have the pro option. Use \texttt{gopro}\IndexOpt{gopro} to
% pass the \texttt{pro} option to all components that take it.
%    \begin{macrocode}
\DeclareOptionX{gopro}{\PassOptionsToPackage{pro}{web}}
%    \end{macrocode}
% \subsection{\texttt{attachsource} option}
% A simple interface, \texttt{attachsource}\IndexOpt{attachsource} to attaching the source file(s) of \cs{jobname}.
%    \begin{macrocode}
\DeclareOptionX{attachsource}{\def\aeb@attachsource{#1}}
\let\aeb@attachsource\@empty
%    \end{macrocode}
% \subsection{\texttt{attachments} option}
% The \texttt{attachments}\IndexOpt{attachments} option is a general routine
% for attaching files other than the \cs{jobname}.
%    \begin{macrocode}
\DeclareOptionX{attachments}{\def\aeb@attachments{#1}}
\let\aeb@attachments\@empty
%    \end{macrocode}
% \changes{v1.4}{2013/02/24}{Support for optional attachments}
% The two options, \texttt{optattachments}\IndexOpt{optattachments} and \texttt{!optattachments}\IndexOpt{!optattachments},
% set the Booleaqn switch \cs{ifoptattachments} to true or false, respectively.
% the default is false. When the command \cs{prjInput} is used, files are input into
% the source file, but also attached to the PDF when \texttt{optattachments} is used, and not
% attached when \texttt{!optattachments} is used.
%    \begin{macrocode}
\newif\ifoptattachments\optattachmentsfalse
\newif\ifoptattachmentsTaken\optattachmentsTakenfalse
\DeclareOptionX{optattachments}{%
    \optattachmentsTakentrue
    \optattachmentstrue}
\DeclareOptionX{!optattachments}{%
    \optattachmentsTakentrue
    \optattachmentsfalse}
%    \end{macrocode}
% \subsection{The \texttt{linktoattachments} option}
% The option \texttt{linktoattachments}\IndexOpt{linktoattachments} is a
% general routine for linking to attached PDF files.
%    \begin{macrocode}
\def\@aeb@InputUnicodes{\InputIfFileExists{unicodes.def}%
   {\typeout{aeb_pro: Inputting code for the linktoattachments option}}%
   {\typeout{aeb_pro: Cannot find unicodes.def.
       Reinstall or refresh your file name database, as needed.}}}
\let\aeb@InputUnicodes\@empty
%    \end{macrocode}
% \changes{v1.7k}{2015/08/06}{Added code so that the childof is read after linktoattachments}
% (2015/08/06) Added code so that the childof is read after linktoattachments
% \changes{v2.4}{2016/08/03}{Removed the \string\texttt{latin1} option as unworkable across some workflows}
%    \begin{macrocode}
\DeclareOptionX{linktoattachments}{%
    \let\aeb@InputUnicodes\@aeb@InputUnicodes}
\let\aeb@childofInput\@empty
\let\aeb@childof\@empty
\DeclareOptionX{childof}{\def\aeb@childof{#1}\def\aeb@childofInput{%
    \InputIfFileExists{\aeb@childof_xref.cut}{}{}}}
\def\inputAttachmentRelatedFiles{%
    \aeb@InputUnicodes
    \aeb@childofInput
}
\AtEndOfPackage{\inputAttachmentRelatedFiles}
%    \end{macrocode}
% When the \texttt{ocganime}\IndexOpt{ocganime} option is taken, the code for ocg animation is included.
%    \begin{macrocode}
\let\inputCommonAnimeCode\relax
\DeclareOptionX{ocganime}{%
    \ifx\aebp@uselayers0\ExecuteOptionsX{uselayers}
    \global\let\aebp@uselayers=1\fi
    \ifx\inputCommonAnimeCode\relax
        \let\inputCommonAnimeCode\aebp@inputCommonAnimeCode
        \AtEndOfPackage{\inputCommonAnimeCode}\fi
    \AtEndOfPackage{\inputOcgAnimeCode}
}
%    \end{macrocode}
% When the \texttt{btnanime}\IndexOpt{btnanime} option is taken, the code for button animation is included.
%    \begin{macrocode}
\DeclareOptionX{btnanime}{%
    \ifx\inputCommonAnimeCode\relax
        \let\inputCommonAnimeCode\aebp@inputCommonAnimeCode
        \AtEndOfPackage{\inputCommonAnimeCode}\fi
    \AtEndOfPackage{\inputBtnAnimeCode}
}
\def\inputBtnAnimeCode{\InputIfFileExists{btnnanime.def}
    {\PackageInfo{aeb_pro}{inputting btnnanime.def}}
    {\PackageWarning{aeb_pro}{cannot find btnnanime.def}}}%
\def\inputOcgAnimeCode{\InputIfFileExists{ocganime.def}
    {\PackageInfo{aeb_pro}{inputting ocganime.def}}
    {\PackageWarning{aeb_pro}{cannot find ocganime.def}}}%
\def\aebp@inputCommonAnimeCode{\InputIfFileExists{anime_support.def}
    {\PackageInfo{aeb_pro}{inputting anime_support.def}}
    {\PackageWarning{aeb_pro}{cannot find anime_support.def}}}%
%    \end{macrocode}
% We allow for a configuration file, usually of the form
%\begin{verbatim}
%   \ExecuteOptionsX{driver=<driver>} % dvips, dvipsone, pdftex, xetex
%\end{verbatim}
% For the last two, \app{AeB Pro} can only act as a central control of
% the \app{AeB} Family.
% \changes{v1.7}{2015/06/12}{Added a test for \texttt{pdftex} and \texttt{xetex}}
% If the driver being used (automatically detected) is \texttt{pdftex} or \texttt{xetex}, we
% use the \texttt{nopro} option and don't input \texttt{aebpro.cfg}.
%    \begin{macrocode}
\let\pathToBtnCtrlIcons\@empty
\let\ExecuteOptionsXSAVE\ExecuteOptionsX
\let\ExecuteOptionsX\@gobble
\InputIfFileExists{aebpro.cfg}{}{}
\let\ExecuteOptionsX\ExecuteOptionsXSAVE
\ifpdf\ExecuteOptionsX{driver=pdftex}\else
    \ifxetex\ExecuteOptionsX{driver=xetex}\else
    \@ifundefined{l@tex@@@@driver}{\ExecuteOptionsX{driver=dvips}}
            {\ExecuteOptionsX{driver=dvipsone}}\fi\fi
%    \end{macrocode}
% \paragraph*{Process the options}
%    \begin{macrocode}
\ProcessOptionsX
\edef\ap@restoreCats{%
    \catcode`\noexpand\"=\the\catcode`\"\relax
    \catcode`\noexpand\,=\the\catcode`\,\relax
    \catcode`\noexpand\(=\the\catcode`\(\relax
    \catcode`\noexpand\!=\the\catcode`\!\relax
}
\@makeother\"\@makeother\,\@makeother\(\@makeother\!
%    \end{macrocode}
% \paragraph*{Set up variables}
% We set a switch to indicate we are using the \textbf{pdfmark} operator or not.
% Initially we assume so.
% \changes{v1.9}{2016/03/03}{Set up \string\cs{ifpdfmark} switch earlier}
%    \begin{macrocode}
\@ifundefined{ifpdfmarkup}{\newif\ifpdfmarkup}{}
\pdfmarkuptrue
%    \end{macrocode}
%\changes{v2.2}{2016/07/26}{Added support for luatex .85}
% Added support for luatex .85. Moved this code to \pkg{insdljs} (2016/07/31); \pkg{aeb\_pro} requires
% \pkg{insdljs} so put it there.
%\begin{verbatim}
%    \ifpdf\ifx\pdffeedback\@undefined\else
%    \def\pdfpageref{\pdffeedback pageref}\fi\fi
%\end{verbatim}
% Set the variables for the case of \opt{dvips} and \opt{dvipsone}.
% \changes{v1.9}{2016/03/03}{Modified driver check, adding \string\cs{@useacrobattrue}}
%    \begin{macrocode}
\def\aeb@testdriver{dvips}%
\ifx\aeb@testdriver\aeb@driver
    \@useacrobattrue\else
\def\aeb@testdriver{dvipsone}%
\ifx\aeb@testdriver\aeb@driver
    \@useacrobattrue\else
%    \end{macrocode}
% If not \texttt{dvips} or \texttt{dvipsone}, the user is
% not to use the \textbf{pdfmark} operator.
% \changes{v1.9}{2016/03/03}{Mark as non-pdfmark}
%    \begin{macrocode}
    \pdfmarkupfalse
\fi\fi
%    \end{macrocode}
% \paragraph*{Summary of switch settings}
% \begin{itemize}
%       \item \app{Distiller} workflow: \cs{pdfmarkuptrue}, \cs{@useacrobatrue}, \cs{@goprotrue}
%       \item non-\app{Distiller}/non-\app{Acrobat} workflow (the \opt{nopro} option):
%           \cs{pdfmarkupfalse}, \cs{@useacrobatrue}, \cs{@goprofalse}
%       \item non-\app{Distiller}/\app{Acrobat} workflow (the \opt{useacrobat} option):
%           \cs{pdfmarkupfalse}, \cs{@useacrobatrue}, \cs{@goprotrue}
% \end{itemize}
% Some options are not valid when using the \opt{nopro}, such as attachments.
%    \begin{macrocode}
\if@gopro\else
\let\aebp@isattach\aebp@NO
\ifx\aeb@attachsource\@empty\else\let\aebp@isattach\aebp@YES\fi
\ifx\aeb@attachments\@empty\else\let\aebp@isattach\aebp@YES\fi
    \let\aeb@attachsource\@empty
    \let\aeb@attachments\@empty
    \optattachmentsfalse\optattachmentsTakenfalse
    \let\inputAttachmentRelatedFiles\relax
\ifx\aebp@isattach\aebp@YES
    \PackageWarningNoLine{aeb_pro}{The various attachment options
        are not\MessageBreak supported with the nopro option,
        ignoring them}\fi
\fi
%    \end{macrocode}
% \paragraph*{Disallow some options that use the \textsf{pdfmark}}
% We do what we say.
%    \begin{macrocode}
\ifpdfmarkup\else
\if\aebp@uselayers1
    \def\aeb@InputAeBLayers{\PackageError{aeb_pro}
    {The uselayers and ocganime options are not supported,\MessageBreak
     with the useacrobat and nopro options,\MessageBreak
     ignoring these options}{Remove dependence on layers,
     or obtain\MessageBreak the full Acrobat product}}
    \let\texHelpIndicator\@gobble
    \let\addJStexHelpEnter\@gobble
    \let\addJStexHelpExit\@gobble
    \let\texHelp\@gobbletwo
    \def\xBld#1\eBld{}
    \let\defineRC\@gobbletwo
    \let\insertRC\@gobble
    \let\definePR\@gobbletwo
    \let\insertPR\@gobble
    \let\proofRollovers\relax
    \let\texPHProof\@gobbletwo
    \newcommand\animeBld[1][]{}
    \def\DeclareAnime#1#2#3{}
    \newcommand\backAnimeBtn[3][]{}
    \newcommand\clearAnimeBtn[3][]{}
    \newcommand\forwardAnimeBtn[3][]{}
\fi\fi
%    \end{macrocode}
%
% \section{Package requirements}
%
% AeB builds on the \textsf{web} package to a certain extent,
% hence requires \textsf{insdljs}.
%    \begin{macrocode}
\def\aebp@PkgWarningi#1{\ifpdfmarkup\else\PackageWarningNoLine{aeb_pro}
    {The #1\space package requires Adobe Distiller,\MessageBreak
        do not load this package}\fi}
\def\aebp@PkgWarningii#1{\PackageWarningNoLine{aeb_pro}
    {The #1\space package requires Adobe Distiller,\MessageBreak
        ignoring #1\space as an option}}
\def\aebp@PkgWarningiii#1{\PackageWarningNoLine{aeb_pro}
    {The #1\space package requires Adobe Distiller or\MessageBreak
        the useacrobat option (Acrobat required),\MessageBreak
        ignoring #1\space as an option}}
\providecommand\getargsii[2]{\def\aeb@argi{#1}\def\aeb@argii{#2}}
%    \end{macrocode}
%    \cs{ap@RP} is a command that computes the appropriate
%    \cs{PassOptionsToPackage} and \cs{RequiredPackage} commands
%\begin{verbatim}
%   #1 aeb_pro required options, #2 = package name
%\end{verbatim}
%    \begin{macrocode}
\newcommand\ap@RP[2][]{\def\@rgi{#1}\def\@rgii{#2}%
    \ifx\@rgi\@empty\else\edef\@rgi{[\@rgi]}\fi
    \@ifnextchar[%]
    {\ap@@RP}{\ap@@RP[]}}
%    \end{macrocode}
%    \cs{ap@@RP} continues \cs{ap@RP} and is the one that formulates
%    \cs{PassOptionsToPackage} and \cs{RequiredPackage} commands
%\begin{verbatim}
%   #1 = aeb_pro required date
%\end{verbatim}
%    \begin{macrocode}
\def\ap@@RP[#1]{\def\@rgiii{#1}%
    \let\XKV@rm\@empty\let\eq@pkgReq\@empty
    \@ifundefined{aeb@\@rgii @opts}
        {\ifx\@rgi\@empty\else
            \ap@csarg\edef{aeb@\@rgii @req}{#1}\fi
        }{%
%    \end{macrocode}
%    Calculate \cs{PassOptionsToPackage} and its arguments
%    \begin{macrocode}
            \edef\x{\noexpand
                \setkeys*{aebpreq}{\@nameuse{aeb@\@rgii @opts}}}\x
            \edef\eq@theseOpts{\XKV@rm}%
            \ap@csarg\edef{aeb@\@rgii @req}{\eq@pkgReq}%
            \edef\x{\noexpand
                \PassOptionsToPackage{\eq@theseOpts}{\@rgii}}\x
        }%
%    \end{macrocode}
%    Construct \cs{RequirePackage} and its arguments
%    \begin{macrocode}
    \ifx\@rgiii\@empty
        \if!\@nameuse{aeb@\@rgii @req}!\else
        \ap@csarg\edef{aeb@\@rgii @req}{[\@nameuse{aeb@\@rgii @req}]}\fi
    \else
        \@ifl@t@r{#1}{\@nameuse{aeb@\@rgii @req}}%
            {\if!\@nameuse{aeb@\@rgii @req}!\else
                \ap@csarg\edef{aeb@\@rgii @req}%
                    {[\@nameuse{aeb@\@rgii @req}]}\fi
            }{\ap@csarg\edef{aeb@\@rgii @req}{[#1]}}%
    \fi
    \edef\x{\noexpand
        \RequirePackage{\@rgii}\@nameuse{aeb@\@rgii @req}}\x
}
\@ifpackageloaded{web}{}
{%
    \@ifundefined{aeb@web@opts}{}{\ap@RP{web}}%
}
\@ifpackageloaded{exerquiz}{}
{%
    \@ifundefined{aeb@exerquiz@opts}{}{\ap@RP{exerquiz}}%
}
\@ifpackageloaded{hyperref}{}
{%
    \@ifundefined{aeb@hyperref@opts}{}{\ap@RP{hyperref}}%
}
\@ifpackageloaded{eq2db}{}
{%
    \@ifundefined{aeb@eq2db@opts}{}{\ap@RP{eq2db}}%
}
\@ifpackageloaded{dljslib}{}
{%
    \@ifundefined{aeb@dljslib@opts}{}{\ap@RP{dljslib}}%
}
\@ifpackageloaded{insdljs}{\let\execjs\aebp@YES}
{%
    \ap@RP[execJS]{insdljs}[2016/07/31]% incls conv-xkv
}
\@ifpackageloaded{eforms}{\let\execjs\aebp@YES}
{%
    \@ifundefined{aeb@eforms@opts}{}
    {\ap@RP[execJS]{eforms}[2017/01/03]}%
}
\@ifpackageloaded{aebxmp}{\aebp@PkgWarningi{aebxmp}}
{%
    \@ifundefined{aeb@aebxmp@opts}{}
    {\edef\temp@exp{\ifpdfmarkup
        \noexpand\ap@RP{aebxmp}\else
     \if@useacrobat
        \noexpand\ap@RP{aebxmp}[2016/05/12]\else
        \noexpand\aebp@PkgWarningiii{aebxmp}\fi\fi}\temp@exp}
}
\@ifpackageloaded{graphicxsp}{\aebp@PkgWarningi{graphicxsp}}
{%
    \@ifundefined{aeb@graphicxsp@opts}{}
    {\edef\temp@exp{\ifpdfmarkup
        \noexpand\ap@RP{graphicxsp}\else
        \noexpand\aebp@PkgWarningii{graphicxsp}\fi}\temp@exp}
}
\@ifpackageloaded{rmannot}{\aebp@PkgWarningi{rmannot}}
{%
    \@ifundefined{aeb@rmannot@opts}{}
    {\edef\temp@exp{\ifpdfmarkup\noexpand\ap@RP{rmannot}\else
        \noexpand\aebp@PkgWarningii{rmannot}\fi}\temp@exp}
}
\let\execjs\aebp@YES
\RequirePackage{comment}
\RequirePackage{calc}
\RequirePackage{eso-pic}
\ifpdfmarkup\else\if\aebp@uselayers1
    \excludecomment{printRollover}%
    \excludecomment{rollover}%
\fi\fi
%    \end{macrocode}
% The following write command is used by both the layers stuff, and the attachments routines.
%    \begin{macrocode}
\def\aeb@IWVO{\immediate\write\verbatim@out}
%    \end{macrocode}
% \section{Support for PDF help}
% The \DescribeMacro{\pdfHelp}\cs{pdfHelp} macro requires \textsf{eforms}. We define
% the necessary commands for PDF help, as well as some comments needed for \cs{texHelp},
% which uses layers.
% \changes{v2.1}{2016/05/15}{Moved \string\cs{pdfHelp} from \texttt{aeblayers} to
% \texttt{package} to support non-Distiller workflows.}
%    \begin{macrocode}
\newsavebox{\aebsavehelp}
\newcommand{\pdfHelpIndicator}[1]{#1\thinspace${}^{\mbox
    {\footnotesize\negthinspace\ding{109}}%
    \raisebox{.225ex}{\llap{\color{webblue}\tiny?\hspace{1.3ex}}}}$}
\def\pdfHelpCnt{0}
\newcommand{\pdfHelp}{\@ifstar{{\count0=\pdfHelpCnt\relax
\advance\count0by1\relax\xdef\pdfHelpCnt{\the\count0 }}%
    \pdfHelpi{pdfhelp-\pdfHelpCnt}}{\pdfHelpi}}
\newcommand{\pdfHelpi}[3]{%
    \let\rollormargstring\texorpdfstring
    \sbox{\aebsavehelp}{\pdfHelpIndicator{#3}}%
    \makebox[0pt][l]{\makespecialJS\pushButton[\S{S}\BG{}\BC{}\H{N}
    \TU{#2}]{#1}{\wd\aebsavehelp}{11bp}}\usebox{\aebsavehelp}%
    \let\rollormargstring\@gobbletwo
}
\newcommand\pdfPHProof[3]{\small\raggedright\texttt{#3}: #2}
\newcommand\pdfPrintHelp{\@ifstar{{\count0=\pdfHelpCnt\relax
\advance\count0by1\relax\xdef\pdfHelpCnt{\the\count0}}%
    \pdfPrintHelpi{pdfhelp-\pdfHelpCnt}}{\pdfPrintHelpi}}
\newcommand\pdfPrintHelpi[3]{%
    \let\rollormargstring\texorpdfstring
    \ifeqforpaper
        \ifeq@proofing
            \pdfHelp{#1}{#2}{#3}\marginpar{\Hy@pdfstringfalse
                \pdfPHProof{#1}{#2}{{\Hy@pdfstringtrue#3}}}\else
            \pdfHelpIndicator{#3}\fi
    \else
        \pdfHelp{#1}{#2}{#3}\ifeq@proofing
        \marginpar{\Hy@pdfstringfalse
            \pdfPHProof{#1}{#2}{{\Hy@pdfstringtrue#3}}}\fi
    \fi
    \let\rollormargstring\@gobbletwo
}
%    \end{macrocode}
%    \begin{macrocode}
% End of package segment
%</package>
%<*aeblayers>
%    \end{macrocode}
%    \begin{macrocode}
%    \end{macrocode}
% \section{Support for OCG}
% We place PostScript code in the document that supports OCG.
% \subsection{Initialization}
%    \begin{macrocode}
\newif\ifaeb@ocOn \aeb@ocOntrue
\ifaeb@ocOn
\AtBeginDocument{%
\headerps@out{%
{/OCProcSet /ProcSet findresource} stopped not
{/initialize get exec}
{
/BeginOC /pop load def
/EndOC {} def
/SimpleOC /pop load def
/SetOCGInitState {pop pop} bind def
/OCEndPage {} def
/SetOCGIntent {pop pop} bind def
/SetOCGUsage {pop pop} bind def
/AddASEvent {pop pop pop} bind def
}
ifelse
}
}\fi
\ifaeb@ocOn
    \AtEndDocument{\literalps@out{{/OCProcSet /ProcSet findresource
    /terminate get exec} stopped pop}}
\fi
%    \end{macrocode}
% \subsection{Supporting commands for OCG}
% In this section we install the necessary code creating and
% navigating through PDF layers.
% \subsubsection{Document JavaScript in support of OCG}
%    \begin{macrocode}
\begin{insDLJS}[getxBld]{aebocg}{AeB Pro: OCG Support}
var ocgs = this.getOCGs();
var xBlds = new Array();
%console.println("Reindexing ocgs and creating xBlds");
if ( ocgs != null ) {
    var l = ocgs.length;
    for ( i=0; i<l; i++ ) {
        if (ocgs[0].name.substring(0,3) == "xb." )
            xBlds.push(ocgs.shift());
        else ocgs.push(ocgs.shift());
    }
}
var assocxLayers = new Array();
if ( xBlds != null ) {
    for ( var i=0; i<xBlds.length; i++)
        assocxLayers[xBlds[i].name]=i;
}
function getxBld (name) {
    var i = assocxLayers["xb."+name];
    return ( i == undefined ) ? null : xBlds[i];
}
function toggleHelp (name)
{
    var o = getxBld(name);
    if ( o != null ) o.state = (event.name.indexOf("Enter") != -1);
}
function toggleSetThisLayer(name, bState) {
    var oLayer = getxBld(name);
    if ( oLayer != null )
        oLayer.state = (arguments.length > 1) ? bState : !oLayer.state;
}
function getLayerState(name) {
    var oLayer = getxBld(name);
    return ( oLayer != null ) ? oLayer.state : null;
}
\end{insDLJS}
%    \end{macrocode}
% \subsubsection{Macros for creating rollovers}
% The following commands were taken from the \textsf{APB}
% package, and slightly modified.
% \changes{v1.3f}{2012/06/01}{Added controls for adding JS code to a
% rollover; used for starting and stopping an anime.}
%    \begin{macrocode}
\newcommand{\texHelpIndicator}[1]{#1\thinspace${}^{\mbox
    {\footnotesize\negthinspace\ding{109}}\raisebox{.225ex}
    {\llap{\color{webblue}\tiny?\hspace{1.3ex}}}}$}
\newcommand{\addJStexHelpEnter}[1]{\def\aebp@addJStexHelpEnter{\r#1}}
\newcommand{\addJStexHelpExit}[1]{\def\aebp@addJStexHelpExit{\r#1}}
\newcommand{\resetaddJStexHelp}{%
    \let\aebp@addJStexHelpEnter\@empty
    \let\aebp@addJStexHelpExit\@empty
}
\resetaddJStexHelp
\newcommand{\texHelp}[2]{%
    \let\rollormargstring\texorpdfstring
    \sbox{\aebsavehelp}{\texHelpIndicator{#2}}%
    \makebox[0pt][l]{\pushButton[\S{S}\BG{}\BC{}\H{N}
    \AA{\AAMouseEnter{\JS{toggleHelp("#1");\aebp@addJStexHelpEnter}}%
    \AAMouseExit{\JS{toggleHelp("#1");\aebp@addJStexHelpExit}}}]{#1}%
%    \end{macrocode}
%\changes{v1.3h}{2012/11/25}{Changed height calculation in \cs{texHelp}}
% Changed height calculation in \cs{texHelp} to allow a rollover of more
% than text.
%    \begin{macrocode}
        {\wd\aebsavehelp}{\ht\aebsavehelp+\dp\aebsavehelp}}%
    \usebox{\aebsavehelp}\resetaddJStexHelp
    \let\rollormargstring\@gobbletwo
}
%    \end{macrocode}
%
% \subsubsection{Macros for layers}
% We have some basic commands for creating layers in AeB Pro.
%    \begin{macrocode}
\newif\ifaeb@SimpleOCOn \aeb@SimpleOCOnfalse
\newcommand{\@SOC}[2][false]{\global\aeb@SimpleOCOntrue%
    \ifaeb@ocOn\literalps@out{(#2) SimpleOC (#2) #1 SetOCGInitState}\fi}
\newcommand{\b@OC}[2][false]{\ifaeb@SimpleOCOn\@aebSimpleNesterror\fi
    \ifaeb@ocOn\literalps@out{(#2) BeginOC (#2) #1 SetOCGInitState}\fi}
\newcommand{\e@OC}{\ifaeb@ocOn\literalps@out{EndOC}\fi}
%    \end{macrocode}
%    \begin{macro}{\xBld}
% We have some basic commands for creating layers in AeB Pro.
% The syntax for \cs{xBld} is as follows:
%\begin{verbatim}
%    \xBld[true|false|print=(true|false)]
%        {<layer_name>}<content in layer>\eBld
%\end{verbatim}
%The description of the optional parameters follows:
%\begin{itemize}
%  \item \texttt{true}\IndexKey{true}: Inserting \texttt{true} as an optional argument causes the layer to be initially visible.
%  \item \texttt{false}\IndexKey{false}: Inserting \texttt{false} as an optional argument causes the layer to be initially hidden.
%  The default is \texttt{false}, so if no \texttt{true} or \texttt{false} argument is passed as an optional argument,
%  the layer will be initially hidden.
%  \item \texttt{print}\IndexKey{print}: This key allows you to set the printability of the layer: If \texttt{print=true},
%  the layer \emph{always prints}, no matter if it is visible or not. If \texttt{print=false},
%  the layer \emph{never prints}, no matter if it is visible or not. If the print key is not specified,
%  then the layer will print if visible, otherwise, it does not print. Normally, the \texttt{print}
%  key is not specified, and the layer is printed if visible.
%\end{itemize}
%    \begin{macrocode}
\newcommand{\xBld}[2][]{%
    \setkeys{aebpxBld}{false,#1}\b@OC[\aebpxBld@visible]{xb.#2}%
    \ifx\aebpxBld@print\@empty\else
        \literalps@out{/Print [/Print] [(xb.#2)] AddASEvent}%
        \ifAEBP@aebpxBld@print
            \literalps@out{(xb.#2) << /Print<<
                /PrintState/ON >> >> SetOCGUsage}%
        \else
            \literalps@out{(xb.#2) << /Print<<
                /PrintState/OFF >> >> SetOCGUsage}%
        \fi
        \global\let\aebpxBld@print\@empty
    \fi
}
\let\eBld\e@OC
\def\@aebSimpleNesterror{\PackageWarning{aeb}
{The scope of the last \string\Bld\space command
\MessageBreak includes the scope of the nested Bld.
\MessageBreak Executing \protect\ocOff\space to correct this.
\MessageBreak The problem occurs}\ocOff}
%    \end{macrocode}
%    \end{macro}
% The \textsf{keyval} definitions of the optional parameters for \cs{xBld}.
%\changes{v1.7m}{2015/08/08}{Made \texttt{print} key into a choice field}
%(2015/08/08) Made \texttt{print} key into a choice field.
%    \begin{macrocode}
\newif\ifAEBP@aebpxBld@print \AEBP@aebpxBld@printfalse
\define@choicekey+{aebpxBld}{print}[\val\nr]{true,false,%
    visible,always,never}[visible]{%
        \ifcase\nr\relax
            \def\aebpxBld@print{true}\AEBP@aebpxBld@printtrue\or
            \def\aebpxBld@print{false}\AEBP@aebpxBld@printfalse\or
            \let\aebpxBld@print\@empty\or
            \def\aebpxBld@print{true}\AEBP@aebpxBld@printtrue\or
            \def\aebpxBld@print{false}\AEBP@aebpxBld@printfalse\fi
}{\PackageWarning{aeb_pro}{Bad choice for initState, permissible values
   are true, false, visible, always, and never. Try again}}
\let\aebpxBld@print\@empty
\define@key{aebpxBld}{true}[true]{\def\aebpxBld@visible{#1}}
\define@key{aebpxBld}{false}[false]{\def\aebpxBld@visible{#1}}
%    \end{macrocode}
% The \texttt{initState}\IndexKey{initState} sets the initial state of the OCG, the
% default is \texttt{false}, meaning the layer is initially not shown.
%    \begin{macrocode}
\define@choicekey+{aebpxBld}{initState}[\val\nr]{on,off,%
    true,false}[false]{%
    \ifcase\nr\relax
        \def\aebpxBld@visible{true}\or
        \def\aebpxBld@visible{false}\or
        \def\aebpxBld@visible{true}\or
        \def\aebpxBld@visible{false}\fi
}{\PackageWarning{aeb_pro}{Bad choice for initState, permissible values
   are on, off, true and false. Try again}}
%    \end{macrocode}
% \subsubsection{The behavior of the rollovers}
%    \begin{macro}{\defineRC}
%    \begin{macro}{\insertRC}
% RC stands for rollover content. \cs{defineRC} is used to define the content of the rollover
% so the content can be used for the \texttt{rollover} and the \texttt{printRollover} environments.
% These two environments are comment environments that are included or excluded depending on various
% conditions.
%
% The command \cs{csarg} is a convenience command defined in the \texttt{comment} package.
% The \texttt{comment} package is required so this command is available.
%    \begin{macrocode}
\long\def\defineRC#1#2{\csarg\def{RC#1}{#2}}
\def\insertRC#1{\@nameuse{RC#1}}
\long\def\definePR#1#2{%
    \ifeqforpaper\csarg\def{PR#1}{#2}\else
    \ifeq@proofing\csarg\def{PR#1}{#2}\else
    \csarg\let{PR#1}\relax\fi\fi
}
\def\insertPR#1{%
    \ifeq@proofing\@nameuse{PR#1}\else
    \csarg\let{insertPR}\@gobble\fi
    \csarg\let{PR#1}\relax
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{environment}{rollover}
%    \begin{environment}{printRollover}
%    \begin{macro}{\definePR}
%    \begin{macro}{\insertPR}
% Depending on the switches \cs{ifeqforpaper} and \cs{ifeq@proofing}, the comment environments
% \texttt{rollover} and \texttt{printRollover} are included or excluded. Also defined here are the
% two commands \cs{definePR} and \cs{insertPR} (PR stands for print rollover). These two commands
% are set equal to either \cs{defineRC} and \cs{insertRC}, or \cs{relax}, depending on the switches.
%
% If \textsf{exerquiz} is not loaded, then the switch \cs{ifeq@proofing} is undefined. We must
% define this switch in this case, and set it to \texttt{false}.
%    \begin{macrocode}
\@ifundefined{ifeqforpaper}{\newif\ifeqforpaper \eqforpaperfalse}{}
\@ifundefined{ifeq@proofing}{\newif\ifeq@proofing \eq@proofingfalse}{}
\providecommand\turnProofingOn{\eq@proofingtrue}
\providecommand\turnProofingOff{\eq@proofingfalse}
%    \end{macrocode}
% \DescribeMacro\proofRollovers turns on the \texttt{printRollover} environment, if there
% any defined in the document.
% \changes{v1.7}{2015/07/21}{Modified \cs{proofRollovers} command and added
% a number of other related commands.}
%    \begin{macrocode}
\def\proofRollovers{%
    \ifeqforpaper
        \ifeq@proofing
            \includecomment{rollover}%
            \includecomment{printRollover}%
        \else
            \excludecomment{printRollover}%
            \includecomment{rollover}%
        \fi
    \else
        \ifeq@proofing
            \includecomment{rollover}%
            \includecomment{printRollover}%
        \else
            \excludecomment{printRollover}%
            \includecomment{rollover}%
        \fi
    \fi
}
%    \end{macrocode}
% We expand \cs{proofRollovers} immediately, but may be expanded in preamble with \cs{turnProofingOn}.
%    \begin{macrocode}
\proofRollovers
\@onlypreamble\proofRollovers
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{environment}
%    \end{environment}
%    \begin{macro}{\texPrintHelp}
% The \cs{texPrintHelp} command reduces to \cs{texHelp} or typesets its second argument.
%    \begin{macrocode}
\newcommand\texPHProof[2]{\small\raggedright\texttt{#1}: #2}
\let\rollormargstring\@gobbletwo
\def\texPrintHelp#1#2{%
    \let\rollormargstring\texorpdfstring
    \ifeqforpaper
        \ifeq@proofing
            \texHelp{#1}{#2}\marginpar{\Hy@pdfstringfalse
                \texPHProof{#1}{#2}}\else
            \texHelpIndicator{#2}\fi
    \else
        \texHelp{#1}{#2}\ifeq@proofing\marginpar{\Hy@pdfstringfalse
            \texPHProof{#1}{#2}}\fi
    \fi
    \let\rollormargstring\@gobbletwo
}
%    \end{macrocode}
%    \end{macro}
% \subsection{In Support of Anime using Layers}
% Using layers, it is possible to create a sort of animation (anime).  The following
% are some rudimentary methods for creating anime. An example can be found below,
% as well as in \texttt{aebpro\_ex4.tex}.
%
% \subsubsection{\protect\LaTeX{} Support}
%    \begin{macro}{\animeBld}
%    \begin{macro}{\DeclareAnime}
% The command \cs{animeBld} increments \texttt{ocSeq}, and names
% the layer so that the JS can run through the layers in an orderly way.
%
% \cs{DeclareAnime} takes three arguments, the anime base name, the speed at which
% you wish the anime to be played, and the number of frames of this animation. It
% saves these three parameters in macros, and creates \cs{animBldName}, which is used
% in the creation of the anime. See example file \texttt{aebpro\_ex4.tex}.
%    \begin{macrocode}
\newcommand{\animeBld}[1][]{\stepcounter{ocSeq}%
    \xBld[#1]{\animBldName}}
\newcounter{ocSeq}
%    \end{macrocode}
% (10/01/01) We give an animation the special `\texttt{anime!!}' prefix, so JavaScript can identify
% animation layers.
%    \begin{macrocode}
\newcommand{\animeName}[1]{anime!!#1}%01/01/2010
\newcommand{\DeclareAnime}[3]
{%
    \setcounter{ocSeq}{0}%
    \xdef\animBaseName{anime!!#1}%01/01/2010
    \xdef\animSpeed{#2}\xdef\nFrames{#3}%
    \gdef\animBldName{\animBaseName\#\theocSeq}%
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\backAnimeBtn}
%    \begin{macro}{\clearAnimeBtn}
%    \begin{macro}{\forwardAnimeBtn}
% The command \cs{animeBld} increments \texttt{ocSeq}, and names
% the layer so that the JS can run through the layers in an orderly way.
%
% \cs{DeclareAnime} takes three arguments, the anime base name, the speed at which
% you wish the anime to be played, and the number of frames of this animation. It
% saves these three parameters in macros, and creates \cs{animBldName}, which is used
% in the creation of the anime. See example file \texttt{aebpro\_ex4.tex}.
% \begin{itemize}
%    \item \texttt{\#1}: This is an optional parameter for changing the appearance
%           of the button, See the \textsf{eforms} package documentation.
%    \item \texttt{\#2}: width of the button
%    \item \texttt{\#3}: height of the button
% \end{itemize}
%    \begin{macrocode}
\newcommand{\backAnimeBtn}[3][]
{%
    \pushButton[\textFont{Wingdings3}\uCA{FEFF00C5}\TU{Reverse}#1
    \A{\JS{%
        try { aebAnimeTimeOutF.running=false; } catch(e) {}\r
        try { aebAnimeTimeOutB.running=false; } catch(e) {}\r
        aebAnimeLayersBackward(\animSpeed,\nFrames,"\animBaseName");
    }}]{\animBaseName BtnBack}{#2}{#3}%
}
\newcommand{\clearAnimeBtn}[3][]
{%
    \pushButton[\textFont{Wingdings}\CA{n}\TU{Clear}#1
    \A{\JS{%
        try { aebAnimeTimeOutF.running=false; } catch(e) {}\r
        try { aebAnimeTimeOutB.running=false; } catch(e) {}\r
        aebAnimeLayersClear(\animSpeed,\nFrames,"\animBaseName");
    }}]{\animBaseName BtnClear}{#2}{#3}%
}
\newcommand{\forwardAnimeBtn}[3][]
{%
    \pushButton[\textFont{Wingdings3}\uCA{FEFF00C6}\TU{Graph It!}#1
    \A{\JS{%
        try { aebAnimeTimeOutF.running=false; } catch(e) {}\r
        try { aebAnimeTimeOutB.running=false; } catch(e) {}\r
        aebAnimeLayersForward(\animSpeed,\nFrames,"\animBaseName");
    }}]{\animBaseName BtnForward}{#2}{#3}%
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% Here is a simple example if anime, using the above commands. The code
% below uses the \textsf{pstricks-add} and \textsf{fp} packages.
%\begin{verbatim}
%\begin{center}
%\DeclareAnime{sinegraph}{10}{40}
%\def\thisframe{\animeBld\psplot[linecolor=red]{0}{\xi}{sin(x)}\eBld}
%\psset{llx=-12pt,lly=-12pt,urx=12pt,ury=12pt}
%\begin{psgraph*}[arrows=->](0,0)(-.5,-1.5)(6.5,1.5){164pt}{70pt}
%    \psset{algebraic=true}%
%    \rput(4,1){$y=\sin(x)$}
%    \FPdiv{\myDelta}{\psPiTwo}{\nFrames}%
%    \def\xi{0}%
%    \multido{\i=1+1}{\nFrames}{\FPadd{\xi}{\xi}{\myDelta}\thisframe}
%\end{psgraph*}
%
%\backAnimeBtn{24bp}{12bp}\kern1bp\clearAnimeBtn{24bp}{12bp}\kern1bp
%\forwardAnimeBtn{24bp}{12bp}
%\end{center}
%\end{verbatim}
% \subsubsection{JavaScript Support}
%    \begin{macrocode}
\begin{insDLJS}[_animeLayers]{animelayers}
    {AeB Pro: JS in Support of Anime}
var _animeLayers = true;
var aebAnimeTimeOutF = new Object();
aebAnimeTimeOutF.running=false;
var aebAnimeTimeOutB = new Object();
aebAnimeTimeOutB.running=false;
var aebAnimeTimeOutC = new Object();
function aebAnimeLayersForward(animSpeed,nFrames,baseName)
{
    var timeinterval = animSpeed;
    aebAnimeTimeOutF = app.setInterval("aebAnimeTimeOutF.count++;"
        + "if (aebAnimeTimeOutF.count > "
        + nFrames + " || !aebAnimeTimeOutF.running )"
        +" app.clearInterval(aebAnimeTimeOutF);\r"
        + "else { if (aebAnimeTimeOutF.count == 1 )"
        +" getxBld('"+baseName+"\#1').state=true;\t"
        + "else { getxBld('"+baseName+"\#'"
        + "+(aebAnimeTimeOutF.count-1)).state=false;\t"
        + "getxBld('"+baseName+"\#'"
        + "+aebAnimeTimeOutF.count).state=true;}}", timeinterval);
    aebAnimeTimeOutF.running = true;
    aebAnimeTimeOutF.start = 1;
    aebAnimeTimeOutF.count=0;
}
function aebAnimeLayersBackward(animSpeed,nFrames,baseName)
{
    var timeinterval = animSpeed;
    aebAnimeTimeOutB = app.setInterval("aebAnimeTimeOutB.count++;\r"
     + "if (aebAnimeTimeOutB.count > "+nFrames
     +"|| !aebAnimeTimeOutB.running )"
     +" app.clearInterval(aebAnimeTimeOutB);\r"
     + "else { if (aebAnimeTimeOutB.count == "
     +nFrames+") getxBld('"+baseName+"\#1').state=false;\r"
     + "else { getxBld('"+baseName+"\#'"
     + "+(aebAnimeTimeOutB.start-%
aebAnimeTimeOutB.count+1)).state=false;\r"
     + "getxBld('"+baseName+"\#'"
     + "+(aebAnimeTimeOutB.start-%
aebAnimeTimeOutB.count)).state=true;}}",
     timeinterval);
    aebAnimeTimeOutB.running = true;
    aebAnimeTimeOutB.start = nFrames;
    aebAnimeTimeOutB.count=0;
}
function aebAnimeLayersClear(animSpeed,nFrames,baseName)
{
    aebAnimeTimeOutF.running = false;
    aebAnimeTimeOutB.running = false;
    clearFrames = app.setTimeOut(
        "hideAllFrames("+nFrames+",\""+baseName+"\")",animSpeed);
    var timeinterval = animSpeed;
    aebAnimeTimeOutC = app.setInterval("aebAnimeTimeOutC.count++;\r"
     + "if (aebAnimeTimeOutC.count >= "+nFrames
     +") app.clearInterval(aebAnimeTimeOutC);\r"
     + "else { getxBld('"+baseName+"\#'"
     +"+(aebAnimeTimeOutC.start-aebAnimeTimeOutC.count)).state=false;}",
     timeinterval);
    aebAnimeTimeOutC.start = nFrames;
    aebAnimeTimeOutC.count=0;
}
function hideAllFrames(n, baseName)
{
    for ( var i=1; i <= n ; i++ )
        getxBld(baseName+"\#"+i).state=false;
}
\end{insDLJS}
%    \end{macrocode}
%    \begin{macrocode}
% End of the layers segment
%</aeblayers>
%<*aebpro>
%    \end{macrocode}
%
% \section{Initial View}
%  Supported preferences include \texttt{HideToolbar}, \texttt{HideMenubar}, \texttt{FitWindow},
% \texttt{Center\-Window}, \texttt{DisplayDocTitle},
% \texttt{NonFullScreenPageMode} (\texttt{UseNone}, \texttt{UseOutlines}, \texttt{UseThumbs},
% \texttt{UseOC}, \texttt{UseAttachments})
%
% \subsection{Window Options}
%
% The keys recognized for the windows options are \texttt{fit}\IndexKey{fit},
% \texttt{center}\IndexKey{center}, \texttt{fullscreen}\IndexKey{fullscreen},
% and \texttt{showtitle}\IndexKey{showtitle}.
%    \begin{macrocode}
\@tfor\aeb@windowopts:={{fit}{FitWindow}}{{center}{CenterWindow}}%
    {{fullscreen}{FullScreen}}{{showtitle}{DisplayDocTitle}}\do
{%
    \expandafter\getargsii\aeb@windowopts
    \edef\temp@expand@def{%
            \noexpand\define@key{aebWindowOpts}{\aeb@argi}[true]{%
            \noexpand\def\csname aeb@windowopts\aeb@argii\endcsname{%
                /\aeb@argii\space##1}%
        }%
    }\temp@expand@def
    \csarg\let{aeb@windowopts\aeb@argii}\@empty
}
%    \end{macrocode}
%    \begin{macro}{\setWindowOptions}
% Set the User Window options on the Initial View tab of the Document Properties dialog box.
%    \begin{macrocode}
\newcommand{\setWindowOptions}[1]{\cxkvsetkeys{aebWindowOpts}{#1}}
%    \end{macrocode}
%    \end{macro}
% \subsection{User Interface Options}
% Key recognized for the use interface options are \texttt{hidetoolbar}\IndexKey{hidetoolbar},
% \texttt{hidemenubar}\IndexKey{hidemenubar}, and \texttt{hidewindowui}\IndexKey{hidewindowui}.
%    \begin{macrocode}
\@tfor\aeb@uiopts:={{hidetoolbar}{HideToolbar}}
    {{hidemenubar}{HideMenubar}}{{hidewindowui}{HideWindowUI}}\do{%
    \expandafter\getargsii\aeb@uiopts
    \edef\temp@expand@def{%
        \noexpand\define@key{aebUIOpts}{\aeb@argi}[true]%
        {%
            \noexpand\edef\csname aeb@uiopts\aeb@argii\endcsname{%
                /\aeb@argii\space##1}%
        }%
    }\temp@expand@def
    \csarg\let{aeb@uiopts\aeb@argii}\@empty
}
%    \end{macrocode}
%    \begin{macro}{\setUIOptions}
% Set the User Interface options on the Initial View tab of the Document Properties dialog box.
%    \begin{macrocode}
\newcommand{\setUIOptions}[1]{\cxkvsetkeys{aebUIOpts}{#1}}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Layout and Magnification}
%
% \subsubsection{Navigation Tab (Page Mode)}
% Supported values for the \texttt{navitab}\IndexKey{navitab} key are:
%\begin{itemize}
% \item \texttt{UseNone}: Page Only
% \item \texttt{UseOutlines}: Bookmarks Panel and Page
% \item \texttt{UseThumbs}: Pages Panel and Page
% \item \texttt{FullScreen}: Fullscreen mode
% \item \texttt{UseOC}: Layers Panel and Page
% \item \texttt{UseAttachments}: Attachments Panel and Page
%\end{itemize}
%    \begin{macrocode}
\define@choicekey+{aebLayoutMag}{navitab}{UseNone,UseOutlines,%
    UseThumbs,FullScreen,UseOC,UseAttachments}[UseNone]{%
        \def\aeb@layoutMagNaviTab{#1}%
}{\PackageWarning{aeb}{Bad choice for PageLayout, permissible values
   are UseNone, UseOutlines, UseThumbs, FullScreen,%
    UseOC, UseAttachments. Try again}}
\let\aeb@layoutMagNaviTab\@empty
%    \end{macrocode}
% \subsubsection{Page Layout}
% Supported value for the \texttt{pagelayout}\IndexKey{pagelayout} key are:
%\begin{itemize}
%   \item \texttt{SinglePage}: Single page
%   \item \texttt{OneColumn}: Single page continuous
%   \item \texttt{TwoPageLeft}: Two-Up (Facing)
%   \item \texttt{TwoColumnLeft}: Two-Up Continuous (Facing)
%   \item \texttt{TwoPageRight}: Two-Up (Cover Page)
%   \item \texttt{TwoColumnRight}: Two-Up Continuous (Cover Page)
%\end{itemize}
%    \begin{macrocode}
\define@choicekey+{aebLayoutMag}{pagelayout}{SinglePage,OneColumn,%
    TwoColumnLeft,TwoColumnRight,TwoPageLeft,TwoPageRight}[SinglePage]{%
        \def\aeb@layoutMagPageLayout{#1}%
}{\PackageWarning{aeb}{Bad choice for PageLayout, permissible values
   are SinglePage, OneColumn, TwoColumnLeft, TwoColumnRight,
   TwoPageLeft,TwoPageRight. Try again}}
\let\aeb@layoutMagPageLayout\@empty
%    \end{macrocode}
% \subsubsection{Magnification}
% Supported values for the \texttt{mag}\IndexKey{mag} key are:
%\begin{verbatim}
% Actual Size <</D[1 0 R/XYZ -32768 -32768 1.0]/S/GoTo>>
% Fit Page <</D[1 0 R/Fit]/S/GoTo>>
% Fit Width <</D[21 0 R/FitH -32768]/S/GoTo>>
% Fit Height <</D[1 0 R/FitV -32768]/S/GoTo>>
% Fit Visible <</D[21 0 R/FitBH -32768]/S/GoTo>>
%\end{verbatim}
%    \begin{macrocode}
\define@choicekey+{aebLayoutMag}{mag}[\val\nr]%
    {ActualSize,FitPage,FitWidth,FitHeight,FitVisible}[FitPage]%
{%
    \ifcase\nr\relax
        \edef\aeb@layoutMagMag{\dl@actualsize}\or
        \def\aeb@layoutMagMag{\dl@fitpage}\or
        \def\aeb@layoutMagMag{\dl@fitwidth}\or
        \def\aeb@layoutMagMag{\dl@fitheight}\or
        \def\aeb@layoutMagMag{\dl@fitvisible}\fi
%    \end{macrocode}
%\changes{v2.2}{2016/07/26}{Change division from postscript operation to a tex calculation}
%    Change division from postscript operation to a tex calculation to support the \texttt{useacrobat} option.
%    \begin{macrocode}
}{\setlength\@tempdima{1pt*\ratio{\val pt}{100pt}}%
  \edef\aeb@layoutMagMag{\dl@mag{\strip@pt\@tempdima}}}
\let\aeb@layoutMagMag\@empty
%    \end{macrocode}
% \subsubsection{Open to page}
% The \texttt{openatpage}\IndexKey{openatpage} key takes a page number as its value.
%    \begin{macrocode}
\define@key{aebLayoutMag}{openatpage}[1]{\def\aeb@openatpageChoice{#1}%
    \ifpdfmarkup\def\aeb@layoutMagPage{Page#1}\else
    \def\aeb@layoutMagPage{#1}\fi}
\let\aeb@openatpageChoice\@empty
\let\aeb@layoutMagPage\@empty
%    \end{macrocode}
%    \begin{macro}{\setLayoutMag}
% Set the Layout and Magnifications options on the Initial View tab of the Document Properties dialog box.
%    \begin{macrocode}
\newcommand{\setLayoutMag}[1]{\setkeys{aebLayoutMag}{openatpage=1}%
    \cxkvsetkeys{aebLayoutMag}{#1}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\DeclareInitView}
% This command is the ultimate holder of the Initial View data. It has three keys
% \texttt{layoutmag}\IndexKey{layoutmag},
% \texttt{windowoptions}\IndexKey{windowoptions} and \texttt{uioptions}\IndexKey{uioptions}. The
% values for each of these three are key values for the commands defined above:
% \cs{setLayoutMag}, \cs{setWindowOptions} and \cs{setUIOptions}.
%    \begin{macrocode}
\define@key{aebDeclareInitView}{layoutmag}
    {\def\aebDeclareInitView@layoutmag{#1}}
\let\aebDeclareInitView@layoutmag\@empty
\define@key{aebDeclareInitView}{windowoptions}
    {\def\aebDeclareInitView@windowoptions{#1}}
\let\aebDeclareInitView@windowoptions\@empty
\define@key{aebDeclareInitView}{uioptions}
    {\def\aebDeclareInitView@uioptions{#1}}
\let\aebDeclareInitView@uioptions\@empty
\newcommand{\DeclareInitView}[1]{%
    \setkeys{aebDeclareInitView}{#1}%
    \edef\temp@expand@sets{%
        \noexpand\setLayoutMag{\aebDeclareInitView@layoutmag}%
        \noexpand\setWindowOptions{\aebDeclareInitView@windowoptions}%
        \noexpand\setUIOptions{\aebDeclareInitView@uioptions}%
    }\temp@expand@sets
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\taggedPDF}
% Added 07/08/09 to support tagged pdf, principally tabbing using structure. Strictly
% speaking, the document need not be marked as tagged.
%    \begin{macrocode}
\providecommand{\taggedPDF}{\def\aeb@TaggedPDF{true}}
\let\aeb@TaggedPDF\@empty
\@onlypreamble\taggedPDF
%    \end{macrocode}
%    \end{macro}
% Additional Open action
%    \begin{macro}{\additionalOpenAction}
% Document open action, this command is renamed to \cmd{\addToDocOpen} and enhanced.
%    \begin{macro}{\addToDocOpen}
% \changes{v1.7}{2015/06/11}{Renamed \cmd{\additionalOpenAction} to
% \cmd{\addToDocOpen}, this version is additive.}
% This command enhances \cmd{\additionalOpenAction}. This version can be used
% several times in the preamble with possibly different action types.
% Use the command \cmd{\addToDocOpen} to include additional action to be performed when the
% document opens. This is different from the actions that may be performed when the first page
% is opened.  In fact, \emph{this action is independent of what what page is initially opened}.
%    \begin{macro}{\requiresVersion}
%\changes{v0.8h}{2008/07/19}
%{
%   Added an optional argument to \cs{requiresVersion}, to give the option
%   of only warning the user that a certain version is required; no exiting
%   of the document is forced on the user.
%}
% \cmd{\requiresVersion} can be used to put a version condition on viewing the document. \cs{requiresVersion}
% uses \cmd{\addToDocOpen}. If you want to combine several actions, including a version requirement
% you''ll have to use \cmd{\addToDocOpen}. Usage:
%\begin{verbatim}
%   \requiresVersion{7}
%\end{verbatim}
%    \begin{macro}{\alternateDocumentURL}
% An URL to direct the user to, it is used by \cmd{requiresVersion} when the version requirement
% is not met.
%    \begin{macro}{\requiredVersionMsg}
% \cs{requireVersionMsg} is the message that is displayed when the version condition is not met.
%    \begin{macro}{\requiredVersionMsgRedirect}
% An redirect message when the version requirement fails, and the document is in a browser.
%    \begin{macro}{\afterRequirementPassedJS}
% A hook into the end of the \cmd{\requiresVersion} command for additional JS to be
% executed.
%    \begin{macrocode}
\let\aeb@addOpenAction\@empty
\let\aeb@addActionCode\@empty
\let\aeb@addOpenActionArg\@empty
\def\AEB@psMrk{[\space}
\let\aebpopentoks\@empty
\let\aebpFA\aebp@NO
\def\aebp@rightDelimiters{}
%    \end{macrocode}
%    \begin{macro}{\addToDocOpen}
% The argument of \cmd{\addToDocOpen} is an action, usually
% JavaScript or named.
%\begin{verbatim}
%   \addToDocOpen{/S/GoTo/D[\Page{2}/Fit]}
%   \addToDocOpen{\JS{console.println("Public: Open it baby!");}}
%\end{verbatim}
% As of 2015/06/15, the original version of \cs{addToDocOpen} was moved to
% \textsf{insdljs} (v2.1). This redefinition extends that capability slightly
% by incorporating into it the \cs{dev@addToDocOpen} command, see definition
% below.
% \changes{v1.9}{2016/03/03}{Redefine \string\cs{addtoDocOpen} only for pdfmarkup}
% \par\medskip\noindent
% The \cmd{\addToDocOpen} command is the major interface
% between the document author for inserting open actions (not first page actions).
% At least in the case of \textsf{pdflatex}, \textsf{hyperref} has the potential of
% overwriting the user's choices with its own choice. We turn off the open page
% action of \textsf{hyperref} by setting the following two commands to empty.
%    \begin{macrocode}
\let\@pdfstartview\@empty
\let\@pdfstartpage\@empty
%    \end{macrocode}
% Now for the definition of \cmd\addToDocOpen.
% \changes{v2.1}{2016/05/15}{Finalized changes to \string\cs{addToDocOpen} for
% non-Distiller workflows.}
%    \begin{macrocode}
\renewcommand{\addToDocOpen}[1]{%
%    \end{macrocode}
% The \cs{aebpFA} flag indicates whether this command has been used. The first it is
% used, we set things up.
%    \begin{macrocode}
    \ifx\aebpFA\aebp@NO
        \gdef\aeb@addOpenActionArg{#1}%
        \g@addto@macro\aebpopentoks{#1}%
        \def\aeb@addActionCode{\bgroup\makeJSspecials\dl@preProcDefns
\ifpdfmarkup
        \literalps@out{\AEB@psMrk/_objdef {pubAddToDocOpen}
            /type/dict /OBJ pdfmark^^J%
        \AEB@psMrk{pubAddToDocOpen}
            << \aebpopentoks
               \ifx\dev@addOpenAction\@empty\else
               \ifx\aeb@addOpenActionArg\@empty\else^^J%
                \dev@addOpenAction\fi\fi\aebp@rightDelimiters
            >> /PUT pdfmark}%
        \gdef\pubAddToDocOpen{{pubAddToDocOpen}}%
        \xdef\aeb@addOpenAction{/Next \pubAddToDocOpen}%
\else\ifpdf
        \immediate\pdfobj{<< \aebpopentoks
            \ifx\dev@addOpenAction\@empty\else
            \ifx\aeb@addOpenActionArg\@empty\else^^J%
            \dev@addOpenAction\fi\fi\aebp@rightDelimiters
        >>}\xdef\pubAddToDocOpen{\the\pdflastobj\space 0 R}%
        \xdef\aeb@addOpenAction{/Next \pubAddToDocOpen}%
\else\ifxetex
        \immediate\@pdfm@mark{obj @pubAddToDocOpen << \aebpopentoks
            \ifx\dev@addOpenAction\@empty\else
            \ifx\aeb@addOpenActionArg\@empty\else^^J%
            \dev@addOpenAction\fi\fi\aebp@rightDelimiters >> }%
        \gdef\pubAddToDocOpen{@pubAddToDocOpen}%
        \xdef\aeb@addOpenAction{/Next \pubAddToDocOpen}%
\fi\fi\fi\egroup}%
%    \end{macrocode}
% Set the \cs{aebpFA} flag to \cs{aebp@YES} to indicate this command has been executed
% at least once.
%    \begin{macrocode}
        \global\let\aebpFA\aebp@YES
    \else
%    \end{macrocode}
% If the document author uses this command a second time, the code goes to here.
%    \begin{macrocode}
            \edef\aebp@dljstmp{\aebp@rightDelimiters}%
            \xdef\aebp@rightDelimiters{\aebp@dljstmp >> }%
            \g@addto@macro\aebpopentoks{/Next << #1 }%
    \fi
}
\let\additionalOpenAction\addToDocOpen
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\dev@addToDocOpen}
% \changes{v1.7}{2015/06/07}{Added private additional action}
% The \cs{dev@addToDocOpen} is similar to
% \cs{addToDocOpen} but is meant for package developers. These actions are executed
% \emph{after the actions} of \cs{addToDocOpen}.
% \changes{v2.1}{2016/05/15}{Extended \string\cs{dev@addToDocOpen} to include
% non-Distiller workflows.}
%    \begin{macrocode}
\let\dev@addOpenAction\@empty
\let\dev@addOpenActionArg\@empty
\let\dev@addActionCode\@empty
\let\aebpFAP\aebp@NO
\let\aebpopentoksP\@empty
\def\aebp@rightDelimitersP{}
\newcommand{\dev@addToDocOpen}[1]{%
%    \end{macrocode}
% The \cs{aebpFAP} flag indicates whether this command has been used. The first it is
% used, we set things up.
%    \begin{macrocode}
    \ifx\aebpFAP\aebp@NO
        \gdef\dev@addOpenActionArg{#1}%
        \g@addto@macro\aebpopentoksP{#1}%
        \def\dev@addActionCode{\bgroup\makeJSspecials\dl@preProcDefns
\ifpdfmarkup
            \literalps@out{\AEB@psMrk/_objdef {privAddDocOpen}
                /type/dict /OBJ pdfmark^^J%
            \AEB@psMrk{privAddDocOpen} << \aebpopentoksP
              \aebp@rightDelimitersP\space>> /PUT pdfmark}%
            \gdef\privAddDocOpen{{privAddDocOpen}}%
            \gdef\dev@addOpenAction{/Next {privAddDocOpen}}%
\else\ifpdf
        \immediate\pdfobj{<< \aebpopentoksP
            \aebp@rightDelimitersP\space>>}%
        \xdef\privAddDocOpen{\the\pdflastobj\space 0 R}%
            \xdef\dev@addOpenAction{/Next \privAddDocOpen}%
\else\ifxetex
        \immediate\@pdfm@mark{obj @privAddToDocOpen << \aebpopentoksP
            \aebp@rightDelimitersP\space>> }%
        \gdef\privAddDocOpen{@privAddToDocOpen}%
            \gdef\dev@addOpenAction{/Next \privAddDocOpen}%
\fi\fi\fi\egroup}%
%    \end{macrocode}
% Set the \cs{aebpFAP} flag to \cs{aebp@YES} to indicate this command has been executed
% at least once.
%    \begin{macrocode}
        \global\let\aebpFAP\aebp@YES
%    \end{macrocode}
% If the package developer uses this command a second time, the code goes to here.
%    \begin{macrocode}
    \else
        \edef\aebp@dljstmpP{\aebp@rightDelimitersP}%
        \xdef\aebp@rightDelimitersP{\aebp@dljstmpP >> }%
        \g@addto@macro\aebpopentoksP{/Next << #1 }%
    \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\def\aebp@warnonly{warnonly}
\newcommand{\aebp@app@title}{AcroTeX Message}
%    \end{macrocode}
%\begin{verbatim}
% #1 = warnonly or empty
% #2 = version number
%\end{verbatim}
%    \begin{macrocode}
\newcommand{\requiresVersion}[2][]{\def\aebp@argi{#1}%
    \def\requiredVersionNumber{#2}\dev@addToDocOpen{\JS{%
\ifx\aebp@argi\aebp@warnonly
    var warnOnly=true;
\else
    var warnOnly=false;
\fi
%    \end{macrocode}
% (2015/10/14) Inserted parentheses to prevent dvips from breaking lines within a string.
% \changes{v1.7n}{2015/10/14}{Inserted parentheses to prevent dvips from breaking lines within a string.}
%    \begin{macrocode}
    var reqVerMsgC=("\aeb@requiredVersionMsg\space")
        + ((warnOnly) ? ("\aeb@reqVerMsgW") : ("\aeb@reqVerMsgC"));
    var reqVerMsgR=("\aeb@requiredVersionMsgRedirect\space")
        + ((warnOnly) ? ("\aeb@reqVerMsgW") : ("\aeb@reqVerMsgR"));
    if( app.viewerVersion < #2 ) {
        var viewerPassedReq=false;
    try {
        if (this.external) {
            app.alert({cTitle:"\aebp@app@title", cMsg: reqVerMsgR});
            if (!warnOnly) {
                if (app.viewerVersion >= 7.0)
                    app.launchURL("\aebAlternateDocumentURL");
                else
                    this.getURL("\aebAlternateDocumentURL",false);
            }
        } else {
            app.alert({cTitle:"\aebp@app@title", cMsg: reqVerMsgC});
        if (!warnOnly) this.closeDoc(true);
        }
    } catch(e) {}
    } else {
        var viewerPassedReq=true;
        \aeb@ViewerPassedRequirementJS
    }
}}}
\def\requiredVersionNumber{7}
\newcommand{\alternateDocumentURL}[1]{\def\aebAlternateDocumentURL{#1}}
\alternateDocumentURL{http://www.acrotex.net/}
\newcommand{\requiredVersionMsg}[1]{\def\aeb@requiredVersionMsg{#1}}
\requiredVersionMsg{This document requires Adobe Reader or Acrobat,
    version \requiredVersionNumber\space or later.}
\newcommand{\requiredVersionResult}[3]{\def\aeb@reqVerMsgC{#1}%
    \def\aeb@reqVerMsgR{#2}\def\aeb@reqVerMsgW{#3}}
\requiredVersionResult{The document is now closing.}
    {Redirecting browser to an alternate page.}
    {Some features of this document may not work properly.}
\newcommand{\requiredVersionMsgRedirect}[1]{%
    \def\aeb@requiredVersionMsgRedirect{#1}}
\requiredVersionMsgRedirect{%
    This document requires Adobe Reader or Acrobat,
    version \requiredVersionNumber\space or later.}
\newcommand{\afterRequirementPassedJS}[1]{%
    \def\aeb@ViewerPassedRequirementJS{#1}}
\let\aeb@ViewerPassedRequirementJS\@empty
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% Now let's put it all together. The two flags, \cs{aebpFA} and \cs{aebpFAP} indicate
% whether the commands \cs{addToDocOpen} and \cs{dev@addToDocOpen} were used.
%    \begin{macrocode}
\def\aeb@SetCatalog{%
    \ifx\aebpFA\aebp@NO\addToDocOpen{\JS{;}}\fi
    \ifx\aebpFAP\aebp@YES\dev@addActionCode\fi
    \aeb@addActionCode
%    \end{macrocode}
% The viewer preferences.
%    \begin{macrocode}
\def\aeb@CatEntry{/ViewerPreferences<<%
    \ifx\aeb@windowoptsFitWindow\@empty\else
        \aeb@windowoptsFitWindow\fi
    \ifx\aeb@windowoptsCenterWindow\@empty\else
        \aeb@windowoptsCenterWindow\fi
    \ifx\aeb@windowoptsDisplayDocTitle\@empty\else
        \aeb@windowoptsDisplayDocTitle\fi
    \ifx\aeb@uioptsHideToolbar\@empty\else
        \aeb@uioptsHideToolbar\fi
    \ifx\aeb@uioptsHideMenubar\@empty\else
        \aeb@uioptsHideMenubar\fi
    \ifx\aeb@uioptsHideWindowUI\@empty\else
        \aeb@uioptsHideWindowUI\fi
    \ifx\aeb@layoutMagNaviTab\@empty\else
        /NonFullScreenPageMode/\aeb@layoutMagNaviTab\fi
>>%
    \ifx\aeb@TaggedPDF\@empty\else
        /MarkInfo<</Marked true>>\fi
    \ifx\aeb@layoutMagPageLayout\@empty\else
        /PageLayout/\aeb@layoutMagPageLayout\fi
    \ifx\aeb@windowoptsFullScreen\@empty
        \ifx\aeb@layoutMagNaviTab\@empty\else
            /PageMode/\aeb@layoutMagNaviTab\fi
    \else/PageMode/FullScreen\fi
%    \end{macrocode}
% The open action key (\textsf{\textbf{OpenAction}}) is implemented any of three ways,
% depending on the driver. The command \cs{pubAddToDocOpen} is an indirect reference
% to additional open actions; this is defined in \cs{addToDocOpen}.
%\changes{v1.9}{2016/03/03}{Removing pdfmark code for non-Distiller workflow}
%    \begin{macrocode}
\ifpdfmarkup
    \ifx\aeb@layoutMagPage\@empty
        \ifx\aeb@layoutMagMag\@empty
            /OpenAction \pubAddToDocOpen
        \else/OpenAction<</D[{Page1}\aeb@layoutMagMag]%
             /S/GoTo\aeb@addOpenAction>>\fi
    \else
        \ifx\aeb@layoutMagMag\@empty
            /OpenAction<</D[{\aeb@layoutMagPage}/Fit]%
                /S/GoTo\aeb@addOpenAction>>\else
            /OpenAction<</D[{\aeb@layoutMagPage}\aeb@layoutMagMag]%
                /S/GoTo\aeb@addOpenAction>>\fi
    \fi
\else\ifpdf
    \ifx\aeb@layoutMagPage\@empty
        \ifx\aeb@layoutMagMag\@empty
            /OpenAction \pubAddToDocOpen
        \else/OpenAction <<%
            /D[\pdfpageref1\space\space 0 R\aeb@layoutMagMag]%
            /S/GoTo\aeb@addOpenAction>>\fi
    \else
        \ifx\aeb@layoutMagMag\@empty
            /OpenAction<</D[\expandafter
                \pdfpageref\aeb@layoutMagPage\space\space 0 R/Fit]%
                /S/GoTo\aeb@addOpenAction>>\else
            /OpenAction<</D[\expandafter\pdfpageref
                \aeb@layoutMagPage\space\space 0 R\aeb@layoutMagMag]%
                /S/GoTo\aeb@addOpenAction>>\fi
    \fi
\else\ifxetex
    \ifx\aeb@layoutMagPage\@empty
        \ifx\aeb@layoutMagMag\@empty
            /OpenAction \pubAddToDocOpen
        \else/OpenAction<</D[@page1 \aeb@layoutMagMag]%
             /S/GoTo\aeb@addOpenAction>>\fi
    \else
        \ifx\aeb@layoutMagMag\@empty
            /OpenAction<</D[@page\aeb@layoutMagPage\space/Fit]%
                /S/GoTo\aeb@addOpenAction>>\else
            /OpenAction<<%
                /D[@page\aeb@layoutMagPage\space\aeb@layoutMagMag]%
                /S/GoTo\aeb@addOpenAction>>\fi
    \fi
\fi\fi\fi}%
%    \end{macrocode}
% Load \cs{aeb@SetCatalog} only if a Distiller user.
%\changes{v1.9}{2016/03/03}{Removing pdfmark code for non-Distiller workflow}
%\changes{v2.0}{2016/05/08}{Attempt to extend package to include more features
%for pdftex and xetex. Modified \string\cs{aeb@SetCatalog}.}
%    \begin{macrocode}
    \ifpdfmarkup\literalps@out{\AEB@psMrk{Catalog}
        <<\aeb@CatEntry>> /PUT pdfmark}\else
    \ifpdf\pdfcatalog{\aeb@CatEntry}\else
    \ifxetex\immediate\@pdfm@mark{put @catalog <<\aeb@CatEntry>>}%
    \fi\fi\fi
}
\AtBeginDocument{\aeb@SetCatalog}
%    \end{macrocode}
%
% \section{Fullscreen and Transitions}
%
% \subsection{\texorpdfstring{\cs{setDefaultFS}}{\textbackslash setDefaultFS}}
%    \begin{macro}{\setDefaultFS}
% Use \cs{setDefaultFS} to set the defaults for fullscreen
% mode in the Adobe Reader or Acrobat.
%    \begin{macrocode}
\newcommand{\setDefaultFS}[1]
{%
    \setkeys{aebDefFS}{Trans=Replace}\setkeys{aebDefFS}{#1}%
    \makeatletter
    \InputIfFileExists{fsprodef.js}{}{\PackageWarning{aeb_pro}
        {Cannot find fsprodef.js, please run aeb_pro.ins again}}
    \makeatother
}
\@onlypreamble\setDefaultFS
%    \end{macrocode}
%    \end{macro}
% Definitions of the values of the \texttt{Trans}\IndexKey{Trans} key for
% supported transitions;  these are set using the command
% \cs{setDefaultFS}.
%
%    \begin{macrocode}
\def\aeb@NoTransition{NoTransition}
\define@choicekey+{aebDefFS}{Trans}
{NoTransition,UncoverLeft,UncoverRight,UncoverDown,UncoverUp,%
UncoverLeftDown,UncoverLeftUp,UncoverRightDown,UncoverRightUp,%
CoverLeft,CoverRight,CoverDown,CoverUp,CoverLeftDown,CoverLeftUp,%
CoverRightDown,CoverRightUp,PushLeft,PushRight,PushDown,PushUp,%
PushLeftDown,PushLeftUp,PushRightDown,PushRightUp,FlyInRight,%
FlyInLeft,FlyInDown,FlyInUp,FlyOutRight,FlyOutLeft,FlyOutDown,%
FlyOutUp,FlyIn,FlyOut,Blend,Fade,Random,Dissolve,%
GlitterRight,GlitterDown,GlitterRightDown,BoxIn,BoxOut,%
BlindsHorizontal,BlindsVertical,SplitHorizontalIn,%
SplitHorizontalOut,SplitVerticalIn,SplitVerticalOut,WipeLeft,%
WipeRight,WipeDown,WipeUp,WipeLeftDown,WipeLeftUp,%
WipeRightDown,WipeRightUp,Replace,ZoomInDown,ZoomInLeft,%
ZoomInLeftDown,ZoomInLeftUp,ZoomInRight,ZoomInRightDown,%
ZoomInRightUp,ZoomInUp,ZoomOutDown,ZoomOutLeft,ZoomOutLeftDown,%
ZoomOutLeftUp,ZoomOutRight,ZoomOutRightDown,ZoomOutRightUp,%
ZoomOutUp,CombHorizontal,CombVertical}[Replace]{%
    \def\aeb@arg{#1}\ifx\aeb@arg\@empty
    \let\aeb@fsTran\@empty\else
    \ifx\aeb@arg\aeb@NoTransition
        \def\aeb@fsTran{app.fs.defaultTransition = "";^^J}
    \else
    \def\aeb@fsTran{app.fs.defaultTransition = "#1";^^J}\fi\fi}
{\PackageWarning{aeb}{Bad choice, try again. Meanwhile,
    will use the default, Replace}%
    \def\aeb@fsTran{app.fs.defaultTransition = "Replace";^^J}}
%    \end{macrocode}
% The \texttt{bgColor}\IndexKey{bgColor} key.
%    \begin{macrocode}
\define@key{aebDefFS}{bgColor}[]{%
    \def\aeb@arg{#1}\ifx\aeb@arg\@empty
    \let\aeb@fsBGColor\@empty\else
    \def\aeb@fsBGColor{app.fs.backgroundColor = #1;^^J}\fi}
\let\aeb@fsBGColor\@empty
%    \end{macrocode}
% The \texttt{timeDelay}\IndexKey{timeDelay} key.
%    \begin{macrocode}
\define@key{aebDefFS}{timeDelay}[]{%
    \def\aeb@arg{#1}\ifx\aeb@arg\@empty
    \let\aeb@fstimeDelay\@empty\else
    \def\aeb@fstimeDelay{app.fs.timeDelay = #1;^^J}\fi}
\let\aeb@fstimeDelay\@empty
%    \end{macrocode}
% The \texttt{loop}\IndexKey{loop} key.
%    \begin{macrocode}
\define@boolkey{aebDefFS}{loop}[true]{%
    \def\aeb@fsLoop{app.fs.loop = #1;^^J}}
\let\aeb@fsLoop\@empty
%    \end{macrocode}
% The \texttt{cursor}\IndexKey{cursor} key.
%    \begin{macrocode}
\define@choicekey+{aebDefFS}{cursor}{hidden,delay,visible}{%
    \def\aeb@arg{#1}\ifx\aeb@arg\@empty
    \let\aeb@fscursor\@empty\else
    \def\aeb@fscursor{app.fs.cursor = cursor.#1;^^J}\fi
}{\PackageWarning{aeb}{Bad choice for cursor, permissible values
   are hidden, delay and visible. Try again}}
\let\aeb@fscursor\@empty
%    \end{macrocode}
% The \texttt{escape}\IndexKey{escape} key.
%    \begin{macrocode}
\define@boolkey{aebDefFS}{escape}[true]{%
    \def\aeb@fsEscape{app.fs.escapeExits = #1;^^J}}
\let\aeb@fsEscape\@empty
%    \end{macrocode}
% The \texttt{clickAdv}\IndexKey{clickAdv} key.
%    \begin{macrocode}
\define@boolkey{aebDefFS}{clickAdv}[true]{%
    \def\aeb@fsclickAdv{app.fs.clickAdvances = #1;^^J}}
\let\aeb@fsclickAdv\@empty
%    \end{macrocode}
% The \texttt{fullscreen}\IndexKey{fullscreen} key.
%    \begin{macrocode}
\define@boolkey{aebDefFS}{fullscreen}[true]{%
    \def\aeb@windowoptsFullScreen{true}%
}
\let\aeb@fsFS\@empty
%    \end{macrocode}
% The \texttt{useTimer}\IndexKey{useTimer} key.
%    \begin{macrocode}
\define@boolkey{aebDefFS}{useTimer}[true]{%
    \def\aeb@fsuseTimer{app.fs.useTimer = #1;^^J}}
\let\aeb@fsuseTimer\@empty
%    \end{macrocode}
% The \texttt{usePageTiming}\IndexKey{usePageTiming} key.
%    \begin{macrocode}
\define@boolkey{aebDefFS}{usePageTiming}[true]{%
    \def\aeb@fsusePageTiming{app.fs.usePageTiming = #1;^^J}}
\let\aeb@fsusePageTiming\@empty
%    \end{macrocode}
% \subsection{\texorpdfstring{\cs{setPageTransition}}{\textbackslash setPageTransition}}
%
%    \begin{macro}{\setPageTransition}
% By setting the \texttt{aebTrans} family of keys, you can change the transition
% effect of the next slide.
% \changes{v2.1}{2016/05/15}{Finalized changes in \string\cs{setPageTransition} for
% non-Distiller workflows.}
%    \begin{macrocode}
\def\aebp@PageTransCnt{0}
\def\aebp@Step@PageTransCnt{{\count0=\aebp@PageTransCnt\relax
    \advance\count0by1\relax
    \xdef\aebp@PageTransCnt{\the\count0 }}}
\newcommand{\setPageTransition}[1]{%
    \begingroup
    \aebp@Step@PageTransCnt
    \setkeys{aebTrans}{TransDur,Speed,#1}%
    \edef\aeb@pagetranschoices{\aeb@Page@Dur
            /Trans <<\aeb@Trans@Dur\aeb@TranChoice>>}%
    \csarg{\xdef}{aeb@pagetransCodeL\aebp@PageTransCnt}{%
        \ifpdfmarkup
            \noexpand\literalps@out{\AEB@psMrk{ThisPage} <<
                \aeb@pagetranschoices\space>> /PUT pdfmark}%
        \else\ifpdf
%    \end{macrocode}
% There may be open / close page actions already defined, so we combine
% previous page actions with current page actions. This seems necessary
% only for \textsf{pdftex}.
%    \begin{macrocode}
            \noexpand\global\noexpand\pdfpageattr=\noexpand\expandafter
            {\noexpand\the\noexpand\pdfpageattr\aeb@pagetranschoices}%
        \else\ifxetex
            \noexpand\immediate\noexpand\@pdfm@mark{put @thispage <<
                \aeb@pagetranschoices\space >>}
        \fi\fi\fi
    }
    \ifx\aeb@TranChoice\@empty\else
        \csarg\xdef{aebpP@geTr@nsP@ge\arabic{page}}%
            {\noexpand\@nameuse{aeb@pagetransCodeL\aebp@PageTransCnt}}%
    \fi
    \endgroup
}
%    \end{macrocode}
%    \begin{macro}{\setPageTransitionAt}
%    Set the transition for a particular page
% \changes{v2.1}{2016/05/15}{Finalized changes in \string\cs{setPageTransitionAt} for
% non-Distiller workflows.}
%    \begin{macrocode}
\newcommand{\setPageTransitionAt}[2]{%
    \begingroup
    \aebp@Step@PageTransCnt
    \setkeys{aebTrans}{#2}%
    \edef\aeb@pagetranschoices{\aeb@Page@Dur
            /Trans <<\aeb@Trans@Dur\aeb@TranChoice>>}%
    \csarg{\xdef}{aeb@pagetransCode\aebp@PageTransCnt}{%
        \ifpdfmarkup
            \noexpand\literalps@out{\AEB@psMrk{ThisPage} <<
                \aeb@pagetranschoices\space>> /PUT pdfmark}%
        \else\ifpdf
%    \end{macrocode}
% There may be open / close page actions already defined, so we combine
% previous page actions with current page actions. This seems necessary
% only for \textsf{pdftex}.
%    \begin{macrocode}
            \noexpand\global\noexpand\pdfpageattr=\noexpand\expandafter
             {\noexpand\the\noexpand\pdfpageattr\aeb@pagetranschoices}%
        \else\ifxetex
            \noexpand\immediate\noexpand\@pdfm@mark{put @thispage <<
                \aeb@pagetranschoices\space>>}
        \fi\fi\fi
    }
    \ifx\aeb@TranChoice\@empty\else
        \expandafter\aebp@rse\expandafter{#1}%
        \edef\shakeandbake{%
            \noexpand\@for\noexpand\@mypage:=\the\aeb@parsetoks}%
        \shakeandbake \do {%
            \csarg\xdef{aebpP@geTr@nsP@ge\@mypage}%
             {\noexpand\@nameuse{aeb@pagetransCode\aebp@PageTransCnt}}%
        }%
    \fi
    \endgroup
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
% The values of the \texttt{Trans}\IndexKey{Trans} key. There are the 50 transitions effects as listed by
% \texttt{app.fs.transitions} plus one more called
% ``\texttt{NoTransition}''. The \texttt{pdfmark} code accurately
% represents each of this options.
%    \begin{macrocode}
\define@choicekey+{aebTrans}{Trans}
{NoTransition,UncoverLeft,UncoverRight,UncoverDown,UncoverUp,%
UncoverLeftDown,UncoverLeftUp,UncoverRightDown,UncoverRightUp,%
CoverLeft,CoverRight,CoverDown,CoverUp,CoverLeftDown,CoverLeftUp,%
CoverRightDown,CoverRightUp,PushLeft,PushRight,PushDown,PushUp,%
PushLeftDown,PushLeftUp,PushRightDown,PushRightUp,FlyInRight,%
FlyInLeft,FlyInDown,FlyInUp,FlyOutRight,FlyOutLeft,FlyOutDown,%
FlyOutUp,FlyIn,FlyOut,Blend,Fade,Random,Dissolve,%
GlitterRight,GlitterDown,GlitterRightDown,BoxIn,BoxOut,%
BlindsHorizontal,BlindsVertical,SplitHorizontalIn,%
SplitHorizontalOut,SplitVerticalIn,SplitVerticalOut,WipeLeft,%
WipeRight,WipeDown,WipeUp,WipeLeftDown,WipeLeftUp,%
WipeRightDown,WipeRightUp,Replace,ZoomInDown,ZoomInLeft,%
ZoomInLeftDown,ZoomInLeftUp,ZoomInRight,ZoomInRightDown,%
ZoomInRightUp,ZoomInUp,ZoomOutDown,ZoomOutLeft,ZoomOutLeftDown,%
ZoomOutLeftUp,ZoomOutRight,ZoomOutRightDown,ZoomOutRightUp,%
ZoomOutUp,CombHorizontal,CombVertical}[Replace]%
    {\edef\aeb@TranChoice{\csname aeb@Trans@#1\endcsname}%
}{\PackageWarning{aeb}{Bad choice, try again}}
\let\aeb@TranChoice\@empty
\define@key{aebTrans}{TransDur}[]{\def\aeb@arg{#1}\ifx\aeb@arg\@empty
    \let\aeb@Trans@Dur\@empty\else\def\aeb@Trans@Dur{/D #1}\fi}
\let\aeb@Trans@Dur\@empty
%    \end{macrocode}
% Length\IndexKey{Speed} of duration of transition effect: \texttt{Slow}, \texttt{Medium}, \texttt{Fast}
%    \begin{macrocode}
\define@choicekey+{aebTrans}{Speed}[\val\nr]%
    {Slow,Medium,Fast}[Slow]{%dps/change 02/27/07
    \ifcase\nr\relax
        \let\aeb@Trans@Speed\@empty\or
        \def\aeb@Trans@Speed{/D 0.666656}\or
        \def\aeb@Trans@Speed{/D 0.333328}\fi
}{\PackageWarning{aeb}{Bad choice for Speed, permissible values
   are Slow, Medium and Fast. Try again}}
\let\apb@apbTrans@Speed\@empty
%    \end{macrocode}
% The page duration\IndexKey{PageDur} key
%    \begin{macrocode}
\define@key{aebTrans}{PageDur}[]{\def\aeb@arg{#1}\ifx\aeb@arg\@empty
    \let\aeb@Page@Dur\@empty\else\def\aeb@Page@Dur{/Dur #1}\fi}
%    \end{macrocode}
% The code for the values of the \texttt{Trans} key
%    \begin{macrocode}
\let\aeb@Page@Dur\@empty
\def\aeb@Trans@NoTransition{}
\def\aeb@Trans@SplitHorizontalIn{/Dm/H/M/I/S/Split}
\def\aeb@Trans@SplitHorizontalOut{/Dm/H/M/O/S/Split}
\def\aeb@Trans@SplitVerticalIn{/Dm/V/M/I/S/Split}
\def\aeb@Trans@SplitVerticalOut{/Dm/V/M/O/S/Split}
\def\aeb@Trans@BlindsHorizontal{/Dm/H/S/Blinds}
\def\aeb@Trans@BlindsVertical{/Dm/V/S/Blinds}
\def\aeb@Trans@BoxIn{/M/I/S/Box}
\def\aeb@Trans@BoxOut{/M/O/S/Box}
\def\aeb@Trans@WipeLeft{/Di 180/S/Wipe}
\def\aeb@Trans@WipeRight{/Di 0/S/Wipe}
\def\aeb@Trans@WipeDown{/Di 270/S/Wipe}
\def\aeb@Trans@WipeUp{/Di 90/S/Wipe}
\def\aeb@Trans@Dissolve{/S/Dissolve}
\def\aeb@Trans@GlitterRight{/Di 0/S/Glitter}
\def\aeb@Trans@GlitterDown{/Di 270/S/Glitter}
\def\aeb@Trans@GlitterRightDown{/Di 315/S/Glitter}
\def\aeb@Trans@Replace{/S/R}
\def\aeb@Trans@FlyInRight{/Di 0/M/I/S/Fly}
\def\aeb@Trans@FlyInLeft{/Di 180/M/I/S/Fly}
\def\aeb@Trans@FlyInDown{/Di 270/M/I/S/Fly}
\def\aeb@Trans@FlyInUp{/Di 90/M/I/S/Fly}
\def\aeb@Trans@FlyOutRight{/Di 0/M/O/S/Fly}
\def\aeb@Trans@FlyOutLeft{/Di 180/M/O/S/Fly}
\def\aeb@Trans@FlyOutDown{/Di 270/M/O/S/Fly}
\def\aeb@Trans@FlyOutUp{/Di 90/M/O/S/Fly}
\def\aeb@Trans@FlyIn{/M/I/S/Fly}
\def\aeb@Trans@FlyOut{/M/O/S/Fly}
\def\aeb@Trans@PushLeft{/Di 180/S/Push}
\def\aeb@Trans@PushRight{/Di 0/S/Push}
\def\aeb@Trans@PushDown{/Di 270/S/Push}
\def\aeb@Trans@PushUp{/Di 90/S/Push}
\def\aeb@Trans@CoverLeft{/Di 180/S/Cover}
\def\aeb@Trans@CoverRight{/Di 0/S/Cover}
\def\aeb@Trans@CoverDown{/Di 270/S/Cover}
\def\aeb@Trans@CoverUp{/Di 90/S/Cover}
\def\aeb@Trans@CoverLeftDown{/Di 225.0/S/Cover}
\def\aeb@Trans@CoverLeftUp{/Di 135.0/S/Cover}
\def\aeb@Trans@CoverRightDown{/Di 315.0/S/Cover}
\def\aeb@Trans@CoverRightUp{/Di 45.0/S/Cover}
\def\aeb@Trans@UncoverLeft{/Di 180/S/Uncover}
\def\aeb@Trans@UncoverRight{/Di 0/S/Uncover}
\def\aeb@Trans@UncoverDown{/Di 270/S/Uncover}
\def\aeb@Trans@UncoverUp{/Di 90/S/Uncover}
\def\aeb@Trans@UncoverLeftDown{/Di 225.0/S/Uncover}
\def\aeb@Trans@UncoverLeftUp{/Di 135.0/S/Uncover}
\def\aeb@Trans@UncoverRightDown{/Di 315.0/S/Uncover}
\def\aeb@Trans@UncoverRightUp{/Di 45.0/S/Uncover}
\def\aeb@Trans@Fade{/S/Fade}
\def\aeb@Trans@Random{/S/Random}
\def\aeb@Trans@Blend{/S/Blend}
%    \end{macrocode}
% New Transitions for Acrobat 8.0
%    \begin{macrocode}
\def\aeb@Trans@PushLeftDown{%
    /S/Push/Directional/BiDir/Di 225.0/Curve/Easy}
\def\aeb@Trans@PushLeftUp{%
    /S/Push/Directional/BiDir/Di 135.0/Curve/Easy}
\def\aeb@Trans@PushRightDown{%
    /S/Push/Directional/BiDir/Di 315.0/Curve/Easy}
\def\aeb@Trans@PushRightUp{%
    /S/Push/Directional/BiDir/Di 45.0/Curve/Easy}
\def\aeb@Trans@WipeLeftDown{%
    /S/Wipe/Directional/BiDir/Di 225/Curve/Easy}
\def\aeb@Trans@WipeLeftUp{%
    /S/Wipe/Directional/BiDir/Di 135/Curve/Easy}
\def\aeb@Trans@WipeRightDown%
    {/S/Wipe/Directional/BiDir/Di 315/Curve/Easy}
\def\aeb@Trans@WipeRightUp{%
    /S/Wipe/Directional/BiDir/Di 45/Curve/Easy}
\def\aeb@Trans@ZoomInDown{%
    /S/ZoomIn/Directional/BiDir/Di 270.0/Curve/Easy}
\def\aeb@Trans@ZoomInLeft{%
    /S/ZoomIn/Directional/BiDir/Di 180.0/Curve/Easy}
\def\aeb@Trans@ZoomInLeftDown{%
    /S/ZoomIn/Directional/BiDir/Di 225.0/Curve/Easy}
\def\aeb@Trans@ZoomInLeftUp{%
    /S/ZoomIn/Directional/BiDir/Di 135.0/Curve/Easy}
\def\aeb@Trans@ZoomInRight{%
    /S/ZoomIn/Directional/BiDir/Di 0.0/Curve/Easy}
\def\aeb@Trans@ZoomInRightDown{%
    /S/ZoomIn/Directional/BiDir/Di 315.0/Curve/Easy}
\def\aeb@Trans@ZoomInRightUp{%
    /S/ZoomIn/Directional/BiDir/Di 45.0/Curve/Easy}
\def\aeb@Trans@ZoomInUp{%
    /S/ZoomIn/Directional/BiDir/Di 90.0/Curve/Easy}
\def\aeb@Trans@ZoomOutDown{%
    /S/ZoomOut/Directional/BiDir/Di 270.0/Curve/Easy}
\def\aeb@Trans@ZoomOutLeft{%
    /S/ZoomOut/Directional/BiDir/Di 180.0/Curve/Easy}
\def\aeb@Trans@ZoomOutLeftDown{%
    /S/ZoomOut/Directional/BiDir/Di 225.0/Curve/Easy}
\def\aeb@Trans@ZoomOutLeftUp{%
    /S/ZoomOut/Directional/BiDir/Di 135.0/Curve/Easy}
\def\aeb@Trans@ZoomOutRight{%
    /S/ZoomOut/Directional/BiDir/Di 0.0/Curve/Easy}
\def\aeb@Trans@ZoomOutRightDown{%
    /S/ZoomOut/Directional/BiDir/Di 315.0/Curve/Easy}
\def\aeb@Trans@ZoomOutRightUp{%
    /S/ZoomOut/Directional/BiDir/Di 45.0/Curve/Easy}
\def\aeb@Trans@ZoomOutUp{%
    /S/ZoomOut/Directional/BiDir/Di 90.0/Curve/Easy}
\def\aeb@Trans@CombHorizontal{%
    /S/Comb/Directional/BiDir/Dm/H/Curve/Easy}
\def\aeb@Trans@CombVertical{%
    /S/Comb/Directional/BiDir/Dm/V/Curve/Easy}
%    \end{macrocode}
%    \begin{macrocode}
% End of aebpro segment
%</aebpro>
%<*fsdefjs>
%    \end{macrocode}
% \subsection{JS for Fullscreen Support}
%  The ``Presentation Defaults'' are used in conjunction with the
%  \cs{setDefaultFS} for setting the defaults of the application. These
%  settings can be viewed under the \texttt{Edit > Preferences >
%  General > Full Screen}. This script save the viewers preferences,
%  sets them according the needs of the document author, and upon
%  closing the document, resets the original preferences. The last task
%  is performed by the \texttt{willClose} environment.
%    \begin{macrocode}
\begin{insDLJS}[_fsDefaults]{fsdef}{AeB Pro: Presentation Defaults}
var _fsDefaults = true;
%if ( typeof global.fsexec == "undefined" )
if ( typeof fsexec == "undefined" )
{
    try {
        var fsexec = true;
%        global.fsexec = true;
        var aebdefaultTransition = app.fs.defaultTransition;
        var aebbackgroundColor = app.fs.backgroundColor;
        var aebloop = app.fs.loop;
        var aebtimeDelay = app.fs.timeDelay;
        var aebuseTimer = app.fs.useTimer
        var aebusePageTiming = app.fs.usePageTiming;
        var aebclickAdvances = app.fs.clickAdvances;
        var aebcursor = app.fs.cursor;
        var aebescapeExits = app.fs.escapeExits;
\aeb@fsTran%
\aeb@fsBGColor%
\aeb@fsLoop%
\aeb@fsclickAdv%
\aeb@fscursor%
\aeb@fstimeDelay%
\aeb@fsuseTimer%
\aeb@fsusePageTiming%
\aeb@fsEscape%
\aeb@fsFS%
    } catch(e) {}
}
\end{insDLJS}
%    \end{macrocode}
% This is a series of script lines that will be inserted into the \texttt{willClose}
% section of the document. These will attempt to restore the user's full screen
% defaults.
%    \begin{macrocode}
\begin{fs@willClose}
try {
    delete global.fsexec;
    app.fs.defaultTransition = aebdefaultTransition;
    app.fs.backgroundColor = aebbackgroundColor;
    app.fs.loop = aebloop;
    app.fs.timeDelay = aebtimeDelay;
    app.fs.useTimer = aebuseTimer;
    app.fs.usePageTiming = aebusePageTiming;
    app.fs.clickAdvances = aebclickAdvances;
    app.fs.cursor = aebcursor;
    app.fs.escapeExits = aebescapeExits;
} catch(e) { console.println("Could not reset one of the defaults"); }
\end{fs@willClose}
%    \end{macrocode}
%    \begin{macrocode}
% End of fsdefjs segment
%</fsdefjs>
%<*aebpro>
%    \end{macrocode}
% \section{Set Page Actions}
%    \begin{environment}{addJSToPageOpen}
%    \begin{environment}{addJSToPageOpenAt}
%    \begin{environment}{addJSToPageClose}
%    \begin{environment}{addJSToPageCloseAt}
% The document author can add to the default page open action through
% this environment. Use this environment between slides, effective
% the next slide. The first slide (possibly generated by
% \cs{maketitle}) is a special case: When setting the open and close
% page actions for the first page, these environments \emph{must go}
% in the preamble.
%    \begin{macrocode}
\def\canceleveryPageOpen{\global\@everyPageOpenfalse
    \global\let\every@PageOpen\@empty}
\def\canceleveryPageClose{\global\@everyPageClosefalse
    \global\let\every@PageClose\@empty}
\newenvironment{everyPageOpen}[1][]
{\global\@everyPageOpentrue\@defineJS[#1]{\every@PageOpen}}
{\end@defineJS
    \ifnum\value{page}=1\relax
    \gdef\ap@AddtoOpenJS{\thisPageAction{\JS{\every@PageOpen}}{}}%
    \expandafter\aftergroup\expandafter\ap@AddtoOpenJS\fi
}
\newenvironment{everyPageClose}[1][]
{\global\@everyPageClosetrue\@defineJS[#1]{\every@PageClose}}
{\end@defineJS
    \ifnum\value{page}=1\relax
    \gdef\ap@AddtoCloseJS{\thisPageAction{}{\JS{\every@PageClose}}}%
    \expandafter\aftergroup\expandafter\ap@AddtoCloseJS\fi
}
\let\every@PageOpen\@empty
\let\every@PageClose\@empty
\newenvironment{addJSToPageOpen}[1][]
{\@defineJS[#1]{\addJST@PageOpen}}{\end@defineJS
    \ifnum\value{page}=1\relax
    \gdef\ap@AddtoOpenJS{\thisPageAction{\JS{\addJST@PageOpen}}{}}%
    \expandafter\aftergroup\expandafter\ap@AddtoOpenJS\fi
}
\newenvironment{addJSToPageOpenAt}[2][]
{\@@defineJS[#1]{addJST@PageOpenAt}{#2}}{\end@@defineJS
%    \end{macrocode}
%\changes{v1.7}{2015/06/17}{\texttt{addJSToPageOpenAt} can now be used in preamble}
% The \texttt{addJSToPageOpenAt} and \texttt{addJSToPageCloseAt} can now be used
% in the preamble on the first page.
%    \begin{macrocode}
    \ifnum\value{page}=1\relax\if\frstPageSpec\aebp@YES
        \thisPageAction{\JS{\@nameuse{addJST@PageOpenAt1}}}{}\fi\fi
}
\newenvironment{addJSToPageClose}[1][]
{\@defineJS[#1]{\addJST@PageClose}}{\end@defineJS
    \ifnum\value{page}=1\relax
    \gdef\ap@AddtoCloseJS{%
        \thisPageAction{}{\JS{\addJST@PageClose}}}%
    \expandafter\aftergroup\expandafter\ap@AddtoCloseJS\fi
}
\newenvironment{addJSToPageCloseAt}[2][]
{\@@defineJS[#1]{addJST@PageCloseAt}{#2}}{\end@@defineJS
    \ifnum\value{page}=1\relax\if\frstPageSpec\aebp@YES
        \thisPageAction{}{\JS{\@nameuse{addJST@PageCloseAt1}}}\fi\fi
}
\let\addJST@PageOpen\@empty
\let\addJST@PageClose\@empty
%    \end{macrocode}
%    \end{environment}
%    \end{environment}
%    \end{environment}
%    \end{environment}
%    \begin{macro}{\aebp@PageOpenCloseHandler}
% This command gets expanded by \cs{AddToShipoutPicture} for each page. Here we
% define how our page actions are to be inserted.
%    \begin{macrocode}
\def\aebp@PageOpenCloseHandler{%
    \@ifundefined{addJST@PageOpenAt\arabic{page}}%
        {\global\let\thisOpenPageActionAt\@empty}%
        {\gdef\thisOpenPageActionAt{%
            \@nameuse{addJST@PageOpenAt\arabic{page}}}}%
    \@ifundefined{addJST@PageCloseAt\arabic{page}}%
        {\global\let\thisClosePageActionAt\@empty}%
        {\gdef\thisClosePageActionAt{%
            \@nameuse{addJST@PageCloseAt\arabic{page}}}}%
    \aebPageAction{\thisOpenPageActionAt\addJST@PageOpen}%
        {\thisClosePageActionAt\addJST@PageClose}%
    \global\let\addJST@PageOpen\@empty
    \global\let\addJST@PageClose\@empty
}
%    \end{macrocode}
% (2016/05/15) Added \cs{aebp@PageTransHandler} to handle the page
% transitions.
% \changes{v2.1}{2016/05/15}{Added the command \string\cs{aebp@PageTransHandler} to handle the page
% transitions}
%    \begin{macrocode}
\def\aebp@PageTransHandler{\@ifundefined{aebpP@geTr@nsP@ge\arabic{page}}
    {}{\@nameuse{aebpP@geTr@nsP@ge\arabic{page}}}}
%    \end{macrocode}
% The two handlers are executed on each page
% \changes{v2.1}{2016/05/15}{Added the command \string\cs{aebp@PageTransHandler}
% to the shipout cmd \string\cs{AddToShipoutPicture}.}
%    \begin{macrocode}
\AddToShipoutPicture{\aebp@PageOpenCloseHandler
    \aebp@PageTransHandler}
%    \end{macrocode}
%    \end{macro}
% \DescribeMacro{\@@defineJS} is a variation of \cs{@defineJS}, as defined in the \textsf{insdljs} package.
% This version, at the end of the environment, calls the \cs{aebp@rse} command to parse the
% complex command argument, then makes a series of definitions to be used in the open/close
% page events.
%    \begin{macrocode}
\newenvironment{@@defineJS}[3][]
{%
    \gdef\argType{#2}\gdef\defineJSArg{#3}\JStoks={}%
    \def\verbatim@processline
        {%
            \xdef\JS@temp{\the\JStoks\the\verbatim@line\defineJSjsR}%
            \global\JStoks=\expandafter{\JS@temp}%
        }%
    \let\do\@makeother\dospecials\catcode`\^^M\active
    #1%
    \verbatim@start
}{%
    \expandafter\aebp@rse\expandafter{\defineJSArg}%
    \edef\shakeandbake{%
        \noexpand\@for\noexpand\@mytoks:=\the\aeb@parsetoks}%
    \aeb@parsecnt=0 \shakeandbake \do {%
        \ifnum\aeb@parsecnt=0
            \edef\firsttok{\@mytoks}%
            \csarg\xdef{\argType\@mytoks}{\the\JStoks}%
        \else
            \edef\letsmakelet{\global\let\expandafter\noexpand
                \csname\argType\@mytoks\endcsname=\expandafter\noexpand
                \csname\argType\firsttok\endcsname}%
            \letsmakelet
        \fi
        \advance\aeb@parsecnt1\relax
    }%
}
%    \end{macrocode}
%    \begin{macrocode}
\newif\ifaeb@PageOpen
\newif\ifaeb@PageClose
\newif\if@everyPageOpen\@everyPageOpenfalse
\newif\if@everyPageClose\@everyPageClosefalse
%    \end{macrocode}
%    \begin{macro}{\aebPageAction}
% This is used internally, but can be used by the document author. The commands creates the code
% to set an open page and a close page action. The first (optional) argument is a the page number (base 1),
% this optional argument defaults to the current page if no page number is given. The second and third
% arguments are the open and closed JavaScript actions.
%
% If the document author uses this command, he may overwrite actions created by the \texttt{addJSTo...}
% environments. See \cs{aeb@addToPageOpenCloseActions} for usage by this package.
% \changes{v2.1}{2016/05/15}{Final changes to \string\cs{aebPageAction} to include non-Distiller
% workflows.}
%    \begin{macrocode}
\newcommand\aebPageAction[3][ThisPage]{%
    \let\ispageactions=0\aeb@PageOpenfalse\aeb@PageClosefalse
    \def\@aebOpen{#2}%
    \if1\@aebOpen1%
        \if@everyPageOpen
            \aeb@PageOpentrue\let\ispageactions=1%
            \def\@aebOpen{/O << \JS{\every@PageOpen#2} >>}%
        \fi
    \else
        \let\ispageactions=1%
        \aeb@PageOpentrue
        \def\@aebOpen{/O << \JS{\every@PageOpen#2} >>}%
    \fi
    \def\@aebClose{#3}%
    \if1\@aebClose1%
        \if@everyPageClose
            \aeb@PageClosetrue\let\ispageactions=1%
            \def\@aebClose{/C << \JS{\every@PageClose#3} >>}%
        \fi
    \else
        \let\ispageactions=1%
        \aeb@PageClosetrue
        \def\@aebClose{/C << \JS{\every@PageClose#3} >>}%
    \fi
    \if@everyPageOpen\aeb@PageOpentrue\let\ispageactions=1\fi
    \if@everyPageClose\@everyPageClosetrue\let\ispageactions=1\fi
    \if\ispageactions1%
        \xdef\aebp@PageActionCode{/AA <<
            \ifaeb@PageOpen\@aebOpen\space\fi
            \ifaeb@PageClose\@aebClose\space\fi >>}
%    \end{macrocode}
% For page 1, the open page is handled by \textsf{insdljs}
% \changes{v2.0a}{2016/05/11}{Let \string\textsf{insdljs} handle page open
% for page 1.}
%    \begin{macrocode}
        \ifnum\value{page}=1\relax\else
            \ifpdfmarkup\literalps@out{\AEB@psMrk{#1} <<
                \aebp@PageActionCode\space >> /PUT pdfmark}\else
            \ifpdf\global\pdfpageattr=\expandafter
                {\aebp@PageActionCode}\else
            \ifxetex\@pdfm@mark{put @thispage <<
                \aebp@PageActionCode\space>>}\fi\fi\fi
        \fi
    \fi
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\atPage}
% \cs{atPage} is a modification of \cs{pageref}, so its value will always be an integer.
% returned in the token register \cs{aeb@parsetoks}. Used in the arguments of such environments
% as \texttt{addJSToPageOpenAt} and \texttt{addJSToPageCloseAt}.
%    \begin{macrocode}
\def\aeb@exiii{\expandafter\expandafter\expandafter}
\let\ahrefexafter\aeb@exiii
\def\atPage#1{\@ifundefined{r@#1}{1}
    {\aeb@exiii\@secondoffive\csname r@#1\endcsname}}
\def\labelRef#1{\@ifundefined{r@#1}{Doc-Start}
    {\aeb@exiii\@fourthoffive\csname r@#1\endcsname}}
%    \end{macrocode}
%    \end{macro}
% The command \cs{aebp@rse} parses such arguments as
%\begin{verbatim}
%   {1,3,4-6,8-12,15,\atPage{firstlabel}-\atPage{secondlabel},30-}
%\end{verbatim}
% The expanded list is returned in the token register \cs{aeb@parsetoks}.
%    \begin{macrocode}
\newtoks\aeb@parsetoks
\newcount\aeb@parsecnt
\def\ap@gobtonil#1\@nil{}
\def\ap@gettonil#1\@nil{\def\to@nilarg{#1}}
\def\ap@ifspc{\ifx\@let@token\@sptoken
    \let\ap@next\ap@xifspc\else
    \let\ap@next\ap@gettonil\fi\ap@next}
\begingroup
\def\:{\ap@xifspc}
\expandafter\gdef\: {\futurelet\@let@token\ap@ifspc}
\endgroup
%    \end{macrocode}
% \cmd{\ap@strpspcs} strips any spaces, usage: \verb~\expandafter\ap@strpspcs\cmd\@nil~
% where \cs{cmd} is a command that expands to text; the text is returned in \cs{to@nilarg}
% without any leading spaces.
%    \begin{macrocode}
\def\ap@strpspcs{\futurelet\@let@token\ap@ifspc}
\def\ap@pgrngLabelsInPream{\@ifundefined{aebLastPage}
    {\PackageWarning{aeb_pro}{The \string\atPage\space
        command is not supported\MessageBreak in the preamble}}{}}
\def\aeb@removelastcomma#1,\@nil{\aeb@parsetoks={#1}}
\def\aebp@rse#1{\global\let\frstPageSpec\aebp@NO
    \aeb@parsetoks={}\aeb@parse#1,\relax}
\def\aeb@parse{\@ifnextchar\relax
    {\expandafter\aeb@removelastcomma\the\aeb@parsetoks\@nil}
    {\aeb@@parse}}
\def\aeb@@parse#1,{\aeb@@@parse#1-\@nil}
\def\aeb@@@parse#1-#2\@nil{%
    \def\argi{#2}\ifx\argi\@empty\def\aeb@next{\aeb@@@@parse{#1}}\else
        \def\aeb@next{\aeb@@@@@parse#1-#2}\fi\aeb@next}
\def\aeb@@@@parse#1{%single page #1
    \@ifnextchar\atPage{\ap@pgrngLabelsInPream\ap@gobtonil}
        {\ap@gobtonil}#1\@nil
    \aeb@parsecnt=#1\relax
    \edef\edefaeb@parsetoks{\the\aeb@parsetoks\the\aeb@parsecnt,}%
    \aeb@parsetoks=\expandafter{\edefaeb@parsetoks}%
%    \end{macrocode}
%\changes{v1.7}{2015/06/17}{Use \cs{frstPageSpec}}
% The \cs{frstPageSpec} signals that page 1 is specified in the
% page specification argument.
%    \begin{macrocode}
    \ifnum\aeb@parsecnt=1\relax\global\let\frstPageSpec\aebp@YES\fi
    \aeb@parse}
\def\aeb@@@@@parse#1-#2-{\def\aeb@lowerlimit{#1}\def\aeb@upperlimit{#2}%
    % range argument from #1 to \csname aebLastPage\endcsname
    \ifx\aeb@upperlimit\@empty
        \@ifundefined{aebLastPage}{\aeb@parsecnt=#1}
            {\expandafter\aeb@parsecnt\expandafter=
                \csname aebLastPage\endcsname}%
    \else % page range #1 to #2, switch the two if #2 < #1
        \aeb@parsecnt=\aeb@lowerlimit\relax
        \edef\aeb@lowerlimit{\the\aeb@parsecnt}
        \aeb@parsecnt=\aeb@upperlimit\relax
        \ifnum\aeb@parsecnt<\aeb@lowerlimit\relax
            \aeb@parsecnt=\aeb@lowerlimit\relax
            \def\aeb@lowerlimit{#2}%
            \def\aeb@upperlimit{#1}%
        \fi
    \fi
    \@ifnextchar\atPage{\ap@pgrngLabelsInPream\ap@gobtonil}
        {\ap@gobtonil}#1\@nil
    \@ifnextchar\atPage{\ap@pgrngLabelsInPream\ap@gobtonil}
        {\ap@gobtonil}#2\@nil
   \advance\aeb@parsecnt1\relax
   \edef\aeb@upperlimit{\the\aeb@parsecnt}%
   \aeb@parsecnt=\aeb@lowerlimit\relax
%    \end{macrocode}
%\changes{v1.7}{2015/06/17}{Use \cs{frstPageSpec}}
% If page 1 is there, is will be as the lower limit.
% The \cs{frstPageSpec} signals that page 1 is specified in the
% page specification argument.
%    \begin{macrocode}
    \ifnum\aeb@parsecnt=1\relax\global\let\frstPageSpec\aebp@YES\fi
    \loop
        \edef\edefaeb@parsetoks{\the\aeb@parsetoks\the\aeb@parsecnt,}%
        \aeb@parsetoks=\expandafter{\edefaeb@parsetoks}%
        \advance\aeb@parsecnt1\relax
        \ifnum\aeb@parsecnt < \aeb@upperlimit\relax\repeat
    \aeb@parse}
%    \end{macrocode}
% \section{Set Document Actions}
%
%    \begin{environment}{willClose}
%    \begin{environment}{willSave}
%    \begin{environment}{didSave}
%    \begin{environment}{willPrint}
%    \begin{environment}{didPrint}
% We add a \texttt{willClose} environment, not really meant for the document
% author to use. This environment is used with \cs{setDefaultFS} for saving
% setting and restoring the application preferences for full screen.
%    \begin{macrocode}
\@ifpackageloaded{insdljs}{%
    \newenvironment{fs@willClose}
    {\@defineJS{\fs@will@Close}}
    {\end@defineJS}
    \let\fs@will@Close\@empty
}{%
    \newenvironment{willClose}
    {\@defineJS{\will@Close}}
    {\end@defineJS}
    \let\will@Close\@empty
    \newenvironment{fs@willClose}
    {\@defineJS{\fs@will@Close}}
    {\end@defineJS}
    \let\fs@will@Close\@empty
    \newenvironment{willSave}
    {\@defineJS{\will@Save}}
    {\end@defineJS}
    \let\will@Save\@empty
    \newenvironment{didSave}
    {\@defineJS{\did@Save}}
    {\end@defineJS}
    \let\did@Save\@empty
    \newenvironment{willPrint}
    {\@defineJS{\will@Print}}
    {\end@defineJS}
    \let\will@Print\@empty
    \newenvironment{didPrint}
    {\@defineJS{\did@Print}}
    {\end@defineJS}
    \let\did@Print\@empty
}
%    \end{macrocode}
%    \end{environment}
%    \end{environment}
%    \end{environment}
%    \end{environment}
%    \end{environment}
% In addition to the provided environments, there are developer hooks, the package developer
% can use to insert page actions, in addition to what the package user may do.
% Now put the \texttt{willClose} JS into the document \texttt{Catalog}. The developer's
% actions will possibly overwrite that of the user; under the theory that the developer's
% actions are critical to the functioning of the package. The hooks are
%    \begin{macrocode}
\let\developer@will@Close\@empty
\let\developer@will@Save\@empty
\let\developer@did@Save\@empty
\let\developer@will@Print\@empty
\let\developer@did@Print\@empty
%    \end{macrocode}
%\changes{v0.8g}{2008/06/30}
%{
%   Added developer hooks to this open page events.
%}
%\changes{v2.1}{2016/05/15}{Changes to \string\cs{@setDocAction} for non-Distiller workflows.}
% (2016/05/15) modify to include non-Distiller workflows.
%    \begin{macrocode}
\newcommand\@setDocActions{%
    \edef\test@will@Close{%
        \fs@will@Close\will@Close\developer@will@Close}%
    \edef\test@will@Save{\will@Save\developer@will@Save}%
    \edef\test@did@Save{\did@Save\developer@did@Save}%
    \edef\test@will@Print{\will@Print\developer@will@Print}%
    \edef\test@did@Print{\did@Print\developer@did@Print}%
    \def\aebp@DocActionsCode{/AA << %
        \ifx\test@will@Close\@empty\else/WC <<
            \JS{\fs@will@Close\will@Close\developer@will@Close} >>\fi
        \ifx\test@will@Save\@empty\else/WS <<
            \JS{\will@Save\developer@will@Save} >>\fi
        \ifx\test@did@Save\@empty\else/DS <<
            \JS{\did@Save\developer@did@Save} >>\fi
        \ifx\test@will@Print\@empty\else/WP <<
            \JS{\will@Print\developer@will@Print} >>\fi
        \ifx\test@did@Print\@empty\else/DP <<
            \JS{\did@Print\developer@did@Print} >>\fi
        >>
   }
    \ifpdfmarkup\literalps@out{\AEB@psMrk{Catalog}
        << \aebp@DocActionsCode\space>> /PUT pdfmark}\else
    \ifpdf\pdfcatalog{\aebp@DocActionsCode}\else
    \ifxetex\immediate
        \@pdfm@mark{put @catalog <<\aebp@DocActionsCode\space>>}\fi
    \fi\fi
}
\AtBeginDocument{\@setDocActions}
%    \end{macrocode}
%
% \section{In support of attachments}
%
% \subsection{Processing the \texttt{attachsource} and \texttt{attachments} key}
%
% If the value of either the \texttt{\texttt{attachsource}} or
% \texttt{attachments} keys are non empty, the values are contained
% in the macros \cs{aeb@attachsource} and \cs{aeb@attachments}. If
% either of these text macros is different from \cs{empty}, we need
% to write out a cut file that lists the requested attachments, then
% input the cut file back in at the end of the package.
%    \begin{macro}{\aref}
% This command, whose argument is \textit{delimited by parentheses},
% is to be used with \cs{inputDataObject}, defined below, to expand
% the value of the \texttt{cName} key, when the label is defined by
% \cs{labelName}. It is also used by this package to set the
% description of the attachment.
%    \begin{macrocode}
\def\aref(#1){\csname aeb@aDescript@#1\endcsname}
%    \end{macrocode}
%    \end{macro}
% The next command \cs{aeb@initAttachWrite} we prepare to write by opening a stream, and
% starting the \texttt{execJS} environment, but only if we have an attachment request.
%    \begin{macrocode}
\def\aeb@initAttachWrite{%
    \newwrite \aeb@attachmentswrite
    \immediate\openout \aeb@attachmentswrite \jobname_attach.cut
    \let\verbatim@out\aeb@attachmentswrite
    \aeb@IWVO{\string\begin{execJS}{aebpro_attach}}%
    {\lccode`P=`\{\lowercase{\aeb@IWVO{try P}}}%
}
%    \end{macrocode}
% \changes{v1.4}{2013/02/24}{Support for optional attachments}
% \paragraph{Optional attachments.} Support for optional attachments.
%    \begin{macro}{\prjInputUser}
%    \begin{macro}{\prjIncludeUser}
%    \begin{macro}{\addtoOptAttachments}
% User interface to project for \cs{input} and \cs{include}. These commands
% may be redefined, but they need to include the appropriate input/include
% command in them. The \cs{addtoOptAttachments} command is a way of optionally
% attaching a file without the input.
%    \begin{macrocode}
\newcommand{\prjInputUser}[1]{\input{#1}}
\newcommand{\prjIncludeUser}[1]{\include{#1}}
\newcommand{\addtoOptAttachments}[1]{%
    \g@addto@macro\AP@addtoAttachments{,#1}}
\newcommand{\getcNameFromFileName}[1]{\@nameuse{descrip4#1}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% The main code for optional attachments.
%    \begin{macrocode}
\def\AP@addtoAttachments{}
%    \end{macrocode}
% The attachments are listing in a comma-delimited list. If there is a space following a comma, it may appear
% as part of the path of the next attachment. So, we'll get JavaScript to strip away any leading spaces to
% avoid the need to instruct the user to insert a \texttt{\%} if the attachment list is on multiple lines.
%    \begin{macrocode}
\def\jsstrsps{replace(/^\string\s*/, "")}
\def\jsstrdotsp{replace(/\string\.\string\s*/g, ".")}
\ifoptattachments
    \def\AP@writeOptAttach{%
        \newwrite\AP@OptAttachlist
            \immediate\openout \AP@OptAttachlist \jobname_oa.cut
%    \end{macrocode}
% Define the optional attachments list command, |\APOptAttachments|.
%    \begin{macrocode}
        \immediate\write\AP@OptAttachlist{\string\def\string
            \APOptAttachments{\AP@addtoAttachments}}
        \immediate\closeout\AP@OptAttachlist}
%    \end{macrocode}
% Write the optional attachments list (|\APOptAttachments|) at the end of the document.
%    \begin{macrocode}
    \AtEndDocument{\AP@writeOptAttach}
%    \def\AP@addtoAttachments{}
    \def\AP@pathInput#1{%
        \addtoOptAttachments{#1}\prjInputUser{#1}}
    \def\AP@pathInclude#1{%
        \addtoOptAttachments{#1.tex}\prjIncludeUser{#1}}
%    \end{macrocode}
% Input the optional attachments list (|\APOptAttachments|) here.
%    \begin{macrocode}
    \InputIfFileExists{\jobname_oa.cut}{%
        \def\AP@next{\edef\aeb@attachments
            {\aeb@attachments\APOptAttachments}}%
    }{\let\AP@next\relax}
    \AP@next
\else
%    \end{macrocode}
% When \texttt{!optattachments} is taken, we use the user commands \cs{prjInputUser} and
% \cs{prjIncludeUser} versions.
%    \begin{macrocode}
    \def\AP@pathInput#1{\prjInputUser{#1}}
    \def\AP@pathInclude#1{\prjIncludeUser{#1}}
\fi
%    \end{macrocode}
% \DescribeMacro{\prjinput}\DescribeMacro{\prjinclude}These are the main
% commands for inputting project files where the files themselves are optionally
% attached.
%    \begin{macrocode}
\ifoptattachmentsTaken
    \def\prjinput{\hyper@normalise\AP@pathInput}
    \def\prjinclude{\hyper@normalise\AP@pathInclude}
%    \end{macrocode}
% The \cs{include} command makes the following comparison.
%\begin{verbatim}
%    \@for\reserved@a:=\@partlist\do
%      {\ifx\reserved@a\reserved@b\@tempswatrue\fi}%
%\end{verbatim}
% The elements from \cs{@parlist} they come from the \cs{includeonly} command.
% The argument of \cs{include} has been normalized using \cs{hyper@normalise} but
% the filenames listed in \cs{includeonly} have not. So the comparison can fail.
% We normalize the file list as well.
%
% When the \texttt{optattachments} is present in the option list,
% the definition of \cs{optattachmentsTaken} is \cs{relax}, hence,
% the redefinition occurs.
%    \begin{macrocode}
    \let\AP@includeonly\includeonly
    \def\includeonly{\hyper@normalise\AP@includeonly}
\else
    \def\prjinput{\prjInputUser}
    \def\prjinclude{\prjIncludeUser}
\fi
%    \end{macrocode}
% \paragraph*{Attaching files.}
% If either the two attachments keys is used, then we execute \cs{aeb@initAttachWrite}.
%    \begin{macrocode}
\ifx\aeb@attachsource\@empty
    \ifx\aeb@attachments\@empty
    \else\aeb@initAttachWrite\fi
\else
    \@ifundefined{aeb@attachmentswrite}
    {\aeb@initAttachWrite}{}
\fi
%    \end{macrocode}
% If \cs{aeb@attachsource} is non empty, go through the comma delimited list, and write to the
% cut file we just opened.
%
%\changes{v0.8i}{2008/10/08}{%
%  Beginning with version 7.05, there is a \texttt{description} property.
%  Prior to that, the value of \texttt{cname} was used for the description.
%  I've added an additional line that sets the description equal to
%  \texttt{cname} for 7.05 or later.
%}
%\changes{v1.4d}{2014/02/24}{%
%  Within this and the next \cs{@for} look, added a test for the empty
%  argument.
%}
% Some commands for setting \texttt{cName} and description.
%    \begin{macrocode}
\def\ap@cName(#1){\csname aeb@aName@attach#1\endcsname}
\def\ap@cNamexdef(#1){\expandafter
    \xdef\csname aeb@aName@attach#1\endcsname}
\def\ap@cDescript(#1){\csname aeb@aDescript@attach#1\endcsname}
\def\ap@cDescriptSource(#1){\csname aeb@aDescript@#1\endcsname}
\def\ap@cDescriptxdef(#1){\expandafter
    \xdef\csname aeb@aDescript@attach#1\endcsname}
\def\ap@cDescriptSourcexdef(#1){\expandafter
    \xdef\csname aeb@aDescript@#1\endcsname}
%    \end{macrocode}
% We now process the list from the \texttt{attachsource} key.
%    \begin{macrocode}
\ifx\aeb@attachsource\@empty\else
    \edef\temp@expand{\noexpand\@for\noexpand\@@tmp:=\aeb@attachsource}
    \temp@expand\do{%
        \ifx\@@tmp\@empty\else
            \expandafter\ap@strpspcs\@@tmp\@nil\edef\@@tmp{\to@nilarg}%
            \ap@cDescriptSourcexdef(\@@tmp){\jobname.\@@tmp}%
            \aeb@IWVO{\space\space\space\space
               var retn=\string\importDataObject({%
%    \end{macrocode}
% \changes{v1.7}{2015/07/01}{Changed cName from \cs{jobname.\cs{@@tmp}} to
% just \cs{@@tmp}}
% (2015/07/01) Changed cName from \cs{jobname.}\cs{@@tmp} to
% just \cs{@@tmp}.
%    \begin{macrocode}
               cName: "\@@tmp",
                cDIPath: "\jobname.\@@tmp".\jsstrdotsp});}%
            \aeb@IWVO{\space\space\space\space
               if ( (app.viewerVersion>7) && retn  )
%    \end{macrocode}
% \changes{v1.7}{2015/07/01}{Changed \texttt{"\cs{jobname.\cs{@@tmp}}"}  to
% just \texttt{"\cs{@@tmp}"}}
% (2015/07/01) Changed \texttt{"\cs{jobname.\cs{@@tmp}}"}  to
% just \texttt{"\cs{@@tmp}"} within argument of \texttt{this.getDataObject}.
%    \begin{macrocode}
                   this.getDataObject("\@@tmp").description=%
                    "\string\ap@cDescriptSource(\@@tmp)".\jsstrdotsp;}%
            \expandafter
            \edef\csname aeb@aName@\@@tmp\endcsname{\jobname.\@@tmp}%
        \fi
    }%
\fi
%    \end{macrocode}
% Similarly, if \cs{aeb@attachments} is non empty, go through the comma delimited list, and write to the
% cut file we just opened.
%    \begin{macrocode}
\ifx\aeb@attachments\@empty\else
\typeout{\string\aeb@attachments: \aeb@attachments}%
    \aeb@parsecnt=0
    \edef\temp@expand{\noexpand\@for\noexpand\@@tmp:=\aeb@attachments}
    \temp@expand\do
    {%
        \ifx\@@tmp\@empty\else
            \expandafter\ap@strpspcs\@@tmp\@nil\edef\@@tmp{\to@nilarg}%
            \advance\aeb@parsecnt1\relax
%    \end{macrocode}
% Set default definitions of the name and description
%    \begin{macrocode}
            \ap@cNamexdef(\the\aeb@parsecnt){attach\the\aeb@parsecnt}%
            \ap@cDescriptxdef(\the\aeb@parsecnt)%
                {AeB Attachment \the\aeb@parsecnt}%
            \aeb@IWVO{\space\space\space\space
            var retn=\string\importDataObject({%
%    \end{macrocode}
%\changes{v1.7}{2015/07/01}{Remove \cs{aref} in \texttt{cName}}
% (2015/07/01) Remove \cs{aref} in \texttt{cName}
%    \begin{macrocode}
            cName:"\string\ap@cName(\the\aeb@parsecnt)",%
                cDIPath: "\@@tmp".\jsstrsps});}%
            \aeb@IWVO{\space\space\space\space
            if ( (app.viewerVersion>7) && retn )
%    \end{macrocode}
%\changes{v1.7}{2015/07/01}{Remove \cs{aref} in first argument}
% (2015/07/01) Remove \cs{aref} in first argument
%    \begin{macrocode}
            this.getDataObject(%
                "\string\ap@cName(\the\aeb@parsecnt)").description=%
                "\string\ap@cDescript(\the\aeb@parsecnt)";}%
            \expandafter
%    \end{macrocode}
% We associate the filename (path) with the label \texttt{cName}. This makes it convenient
% to reference an attachment. We can say |\@usenname{descrip4<name>}|. Also defined
% a convenience command \cs{getcNameFromFileName} for that purpose; for example,
% |\getcNameFromFileName{<name>}|.
%    \begin{macrocode}
            \expandafter\xdef\csname descrip4\@@tmp\endcsname
                {\noexpand\ap@cName(\the\aeb@parsecnt)}%
        \fi
    }
\fi
%    \end{macrocode}
% Now, if \cs{aeb@attachmentswrite} is defined, which means we have attachments and we opened a stream,
% we'll close off the environment, and close the file.
%    \begin{macrocode}
\@ifundefined{aeb@attachmentswrite}{}
{%
    {\lccode`P=`\}\def\jsMsg{"Attachments error: "
        + e.toString()}\lowercase{\aeb@IWVO{P catch(e)
            { console.println( \jsMsg\space); }}}}%
    \aeb@IWVO{\string\end{execJS}}
    \immediate\closeout \aeb@attachmentswrite
}
%    \end{macrocode}
% Create a little macro to input the file \cs{jobname\_attach.cut} at the end of the package.
%    \begin{macrocode}
\def\aeb@inputAttachments{\@ifundefined{aeb@attachmentswrite}{}
    {\InputIfFileExists{\jobname_attach.cut}%
    {\typeout{Inputting attachments file}}%
    {\typeout{Cannot find attachments file}}}%
}
%    \end{macrocode}
% \subsection{Creating a PDF Package}
% Beginning with Version 8, there is a special "Package" interface to access attachments.
% The commands in this section support creating a PDF Package using the specified attachments.
%
% The \texttt{viewmode}\IndexKey{viewmode} has values of \texttt{details},
% \texttt{tile}, \texttt{layout}, and \texttt{hidden}.
%    \begin{macrocode}
\define@choicekey+{aebpdfpack}{viewmode}[\val\nr]%
    {details,tile,layout,hidden}{%
    \ifcase\nr\relax
        \def\aeb@pdfpack@viewmode{/D}\or
        \def\aeb@pdfpack@viewmode{/T}\or
        \def\aeb@pdfpack@viewmode{/T}\or
        \def\aeb@pdfpack@viewmode{/H}\fi
}{}
%    \end{macrocode}
% The \texttt{initview}\IndexKey{initview} of the package. The value of \texttt{initview}
% is a label name of one of the attached files.
%    \begin{macrocode}
\define@key{aebpdfpack}{initview}[]{\def\aeb@pdfpack@initview{#1}}
\let\aeb@pdfpack@initview\@empty
%    \end{macrocode}
%    \begin{macro}{\earlyAttachForPkgs}
% Use this command to package the attachments to the parent document.
%    \begin{macrocode}
\newcommand{\earlyAttachForPkgs}{%
%    \end{macrocode}
%\changes{v1.7}{2015/07/11}{Added \string\texttt{CollectionPreview} menu item to assure the Hidden view
% is displayed.}
% (2015/07/11) Recent versions of \textsf{Acrobat DC} seem not to support the Hidden view. There is no
% difference between Hidden and Tiles, so we use \texttt{'CollectionPreview'}
% menu item to force the viewer into Preview mode, which I'm assuming is the same
% as Hidden mode.
%    \begin{macrocode}
if (this.collection!=null&&this.collection.initialView == "Hidden")
var hideto=app.setTimeOut("app.clearTimeOut(hideto);"
    +"app.execMenuItem('CollectionPreview');",1);
\if@gopro
if(typeof _aebpro_attach == "undefined")
( app.viewerVersion > 8 ) ? %
aebTrustedFunctions(this,aebImportAnFDF,"aebpro_attach.fdf") : %
this.importAnFDF("aebpro_attach.fdf");\fi
%    \end{macrocode}
% For Version XI (or prior), there seems to be a bug. When
% no initial view is specified, the cover sheet should be displayed. It is
% but is disappears after a moment in favor of the first listed attachment
% in the package. To compensate for this, we force the Cover Sheet to appear
% after 2 seconds (trial and error value).
%    \begin{macrocode}
\ifisPDFPackage\ifx\aeb@pdfpack@initview\@empty^^J%
if(app.viewerVersion<15)^^J%
var pkto=app.setTimeOut("app.clearTimeOut(pkto);"
+"app.execMenuItem('CollectionShowRoot');",5000);\fi\fi}
%    \end{macrocode}
% \changes{v1.7k}{2015/08/05}{Added a \cs{ifisPDFPackage} switch}
% (2015/08/05) Added a \cs{ifisPDFPackage} switch.
% \changes{v2.1}{2016/05/15}{Finalized changes in \string\cs{makePDFPackage} to accommodate
% non-Distiller workflows.}
%    \begin{macrocode}
\newif\ifisPDFPackage\isPDFPackagefalse
\newcommand{\makePDFPackage}[1]{\isPDFPackagetrue
    \setkeys{aebpdfpack}{viewmode=details,#1}%
    \ifx\aeb@pdfpack@initview\@empty
        \let\aeb@pdfpackage@initview\@empty
    \else
%    \end{macrocode}
% \changes{v1.7}{2015/07/01}{Removed \cs{aeb@exiii} and \cs{aref()},
% replaced with \cs{expandafter} and argument.}
% (2015/07/01) Removed \cs{aeb@exiii} and \cs{aref()},
% replaced with \cs{expandafter} and argument.
% \changes{v2.0}{2016/05/08}{Extend \string\cs{makePDFPackage} to include
% pdftex and xetex.}
%    \begin{macrocode}
        {\obeyspaces\sanitize@attach\gdef\aeb@pdfpackage@initview%
{/D<\expandafter\stringiiUnicode\aeb@pdfpack@initview\relax>}}%
    \fi
    \def\aeb@PDFPackageCode{/PageMode/UseAttachments%
        /Collection<</Type/Collection%
            \aeb@pdfpackage@initview/View\aeb@pdfpack@viewmode>>}%
    \ifpdfmarkup
        \def\aeb@setPDFPackage{\literalps@out{\AEB@psMrk{Catalog}
            <<\aeb@PDFPackageCode>>/PUT pdfmark}}%
    \else\ifpdf\def\aeb@setPDFPackage{%
        \pdfcatalog{\aeb@PDFPackageCode}}\else
    \ifxetex\def\aeb@setPDFPackage{\immediate
        \@pdfm@mark{put @catalog <<\aeb@PDFPackageCode>>}}\else
        \let\aeb@setPDFPackage\relax\PackageWarning{aeb_pro}
            {The \string\makePDFPackage/string\makePDFPortfolio\space
            is supported for\MessageBreak
            dvips, pdftex, and xetex only}\fi\fi\fi
}
%    \end{macrocode}
% \DescribeMacro{\makePDFPortfolio} is an alias for \cs{makePDFPackage}. The accepted
% name for a PDF Package is now a PDF Portfolio.
%    \begin{macrocode}
\let\makePDFPortfolio\makePDFPackage
\@onlypreamble\makePDFPackage
%    \end{macrocode}
%    We check to see if there are any attachments, if there are, we'll
%    import them early; useful for \cs{makePDFPackage} and for open events
%    that cause the view to display a page other than the first one on opening.
%    \begin{macrocode}
\let\aebp@attachments\aebp@Zero
\ifx\aeb@attachsource\@empty\else\let\aebp@attachments\aebp@One\fi
\ifx\aeb@attachments\@empty\else\let\aebp@attachments\aebp@One\fi
\ifx\aebp@attachments\aebp@One
    \dev@addToDocOpen{\JS{\earlyAttachForPkgs}}%
\fi
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% End of aebpro segment
%</aebpro>
%<*package>
\AtEndOfPackage{\@nameuse{aeb@inputAttachments}}
\AtBeginDocument{\@nameuse{aeb@setPDFPackage}}
\@ifpackageloaded{web}{}
    {\def\aebwritelastpage{%
    \immediate\write\@auxout{\string\expandafter\string\gdef
    \string\csname\space aebLastPage\string\endcsname{\arabic{page}}}}
    \AtEndDocument{\clearpage\addtocounter{page}{-1}\aebwritelastpage
    \addtocounter{page}{1}}%
}
% End of package segment
%</package>
%<*unicode>
%    \end{macrocode}
% \section{Support for linking to attachments.}
%
% \subsection{\texorpdfstring{\cs{ahyperref}, \cs{ahyperlink}, \cs{ahyperextract}}
%  {\CMD{ahyperref}, \CMD{ahyperlink}, \CMD{ahyperextract}}}
%
% The \cs{ahyperref} command is for linking between parent and child, or
% between child and child. \cs{ahyperref} takes three arguments, the first optional
% and the second two required.
%\begin{verbatim}
%   \ahyperref[<optargs>]{<label>}{<text>}
%\end{verbatim}
% where \texttt{<label>} is one defined by either \cs{autolabelNum} or \cs{labelName}. The
% \texttt{<text>} is the text to be typeset around the link. The optional arguments are defined
% and described below.
% \begin{itemize}
%   \item \verb!goto=p2c,c2p,c2c!: The type of jump, parent to child, child to parent, and child to
%         child. The default is \texttt{p2c}
%   \item \texttt{page=<number>}: the page of the embedded document to jump to. Default is \texttt{0}
%   \item \texttt{view=<value>}: the view to be used for the jump. Default is \texttt{Fit}
%   \item \texttt{dest=<string>}: jump to a named destination. When this key has a value, the values
%         of the keys \texttt{page} and \texttt{view} are ignored.
%   \item \verb!open=usepref|new|existing!: open the attachment according to the user preferences,
%         a new window, or the existing window. The default is \texttt{userpref}
%   \item \verb!border=visible|invisible!: Determines whether a visible rectangle appears around the
%         link. The default is \texttt{invisible}
%   \item \verb!highlight=none|invert|outline|insert!: How the viewer highlights the link when the
%         link is clicked.  The default is \texttt{invert}.
%   \item \texttt{bordercolor=r g b}: The color of the border when it is visible. The default is black.
%   \item \verb!linestyle=solid|dashed|underlined!: The line style of the border when it is visible.
%         The default is \texttt{solid}
%   \item \texttt{textcolor=<color>}: the color of the text in the hypertext link. An empty
%           value is equivalent to \cs{normalcolor}.
%   \item \verb!linewidth=thin|medium|thick!: The line width when the border is visible. When invisible,
%         this is set to a width of zero. The default is \texttt{thin}
%   \item \texttt{preset=\cs{presetCommand}}: A convenience key. You can define some preset values, like so
%\begin{verbatim}
%\def\preseti{bordercolor={0 0 1},highlight=outline,border=visible,%
%             linestyle=dashed}
%\end{verbatim}
%           Then you can say, for example,
%\begin{verbatim}
%\ahyperref[dest={target1-s:intro},preset=\preseti]{target1}{Jump!}
%\end{verbatim}
% \end{itemize}
% \paragraph*{Key-value pairs of attachment links.}
% The following are the key-values of the optional first argument of \cs{ahyperref}
% \cs{hyperlink} and \cs{hyperextract}.\par\medskip
%\noindent
% The \texttt{page}\IndexKey{page} key, takes a zero-based page number.
%    \begin{macrocode}
\define@key{ahref}{page}[0]{\def\ahref@page{#1}}
\def\ahref@page{0}
%    \end{macrocode}
% The key \texttt{view}\IndexKey{view} represents an ``explicit destination,'' as termed by the PDF Ref, \S8.2.1.
%\begin{itemize}
%   \item \texttt{/XYZ left top zoom}
%   \item \texttt{/Fit}
%   \item \texttt{/FitH top}
%   \item \texttt{/FitV left}
%   \item \texttt{/FitR left bottom right}
%   \item \texttt{/FitB}
%   \item \texttt{/FitBH top}
%   \item \texttt{/FitBV left}
%\end{itemize}
% For the \texttt{view} key, enter view=Fit or view=XYB null null null, for example. The forward slash
% is added later.
%
% (2015/07) More recent advances allows  \cs{fitpage}, \cs{fitvisible},
% \cs{actualsize}, \cs{fitheight}, \cs{fitwidth}, and \cs{inheritzoom} to be used.
% These are defined in \textsf{insdljs}.
%
% Each of these is preceded by a page number. The page number is entered via the \texttt{page}
% key.
%
% If a named destination is given with the dest key, then the \texttt{view} and \texttt{page} are ignored.
%    \begin{macrocode}
\def\ap@fslash{/}
\def\@isfirstslash#1#2\@nil{\def\arg@i{#1}\ifx\ap@fslash\arg@i
    \else\edef\ahref@view@keyvalue{/\ahref@view@keyvalue}\fi}
\define@key{ahref}{view}[/Fit]{\edef\ahref@view@keyvalue{#1}%
    \expandafter\@isfirstslash\ahref@view@keyvalue\@nil
}
\def\ahref@view@keyvalue{/Fit}
%    \end{macrocode}
% The \texttt{dest}\IndexKey{dest} key
%    \begin{macrocode}
\define@key{ahref}{dest}[]{\def\ahref@dest{#1}}
\let\ahref@dest\@empty
%    \end{macrocode}
% The \texttt{open}\IndexKey{open} key takes values of \texttt{userpref}, \texttt{new}, and \texttt{existing}.
%    \begin{macrocode}
\define@choicekey{ahref}{open}[\val\nr]{userpref,new,existing}
{%
    \ifcase\nr\relax
        \let\ahref@open@keyvalue\@empty\or
        \def\ahref@open@keyvalue{/NewWindow true }\or
        \def\ahref@open@keyvalue{/NewWindow false }\fi
}{}
\let\ahref@open@keyvalue\@empty
%    \end{macrocode}
% The \texttt{border}\IndexKey{border} key takes values of \texttt{visible} and \texttt{invisible}.
%    \begin{macrocode}
\define@choicekey{ahref}{border}[\val\nr]{visible,invisible}
{%
    \ifcase\nr\relax
        \def\ahref@border{0 0 1}%
        \def\ahef@invisible@border{1}\or
       \def\ahref@border{0 0 0}% W = 0 also?
       \let\ahef@invisible@border\@empty\fi
}{}
%    \end{macrocode}
% The \texttt{highlight}\IndexKey{highlight} key takes values of \texttt{none},
% \texttt{invert}, \texttt{outline}, and \texttt{insert}.
%    \begin{macrocode}
\define@choicekey{ahref}{highlight}[\val\nr]{none,invert,outline,insert}
{%
    \ifcase\nr\relax
        \let\ahref@highlight\@empty\or
        \def\ahref@highlight{/H/I}\or
        \def\ahref@highlight{/H/O}\or
        \def\ahref@highlight{/H/P}\fi
}{}
%    \end{macrocode}
% The \texttt{bordercolor}\IndexKey{bordercolor} key\par\medskip\noindent
%    (2017/03/08) \cs{ahref@bordercolor} can be a named color,
%    \changes{v2.8a}{2017/03/08}{\string\cs{ahref@bordercolor} can be a named color}
%    \begin{macrocode}
\define@key{ahref}{bordercolor}[]{\def\ap@argi{#1}\ifx\ap@argi\@empty
    \let\ahref@bordercolor\@empty\else
    \HyColor@IfXcolor{\HyColor@XZeroOneThreeFour{#1}
        {\ahref@bordercolor}{}{}}
        {\edef\ahref@bordercolor{#1}}\fi
} % PDF color
\let\ahref@bordercolor\@empty
%    \end{macrocode}
% The \texttt{linestyle}\IndexKey{linestyle} key takes values of \texttt{solid},
% \texttt{dashed}, and \texttt{underlined}.
%    \begin{macrocode}
\define@choicekey{ahref}{linestyle}[\val\nr]{solid,dashed,underlined}
{%
    \ifcase\nr\relax
        \def\ahref@linestyle@keyvalue{/S/S}\or
        \def\ahref@linestyle@keyvalue{/S/D}\or % Dashed [0 0 1[3.0]]
        \def\ahref@linestyle@keyvalue{/S/U}\fi
}
\def\ahref@dashedlinetyle{/S/D}
%    \end{macrocode}
% The \texttt{linewidth}\IndexKey{linewidth} key takes values of \texttt{thin},
% \texttt{medium}, and \texttt{thick}.
%    \begin{macrocode}
\define@choicekey{ahref}{linewidth}[\val\nr]{thin,medium,thick}
{%
    \ifcase\nr\relax
        \def\ahref@linewidth{1}\or
        \def\ahref@linewidth{2}\or
        \def\ahref@linewidth{3}\fi
}
%    \end{macrocode}
% The \texttt{goto}\IndexKey{goto} key takes values of \texttt{p2c},
% \texttt{c2p}, and \texttt{c2c}.
%    \begin{macrocode}
\define@choicekey{ahref}{goto}[\val\nr]{p2c,c2p,c2c}
{%
    \ifcase\nr\relax
        \global\let\targetDictionary\targetDictionary@pc\or
        \global\let\targetDictionary\targetDictionary@cp\or
        \global\let\targetDictionary\targetDictionary@cc\fi
}{}
%    \end{macrocode}
% The \texttt{launch}\IndexKey{launch} key takes values of \texttt{save},
% \texttt{view}, and \texttt{viewnosave}.
%    \begin{macrocode}
\define@choicekey{ahref}{launch}[\val\nr]{save,view,viewnosave}
    {\edef\ahref@launch@type{\nr}}{}
\def\ahref@launch@type{0}%
%    \end{macrocode}
% The \texttt{preset}\IndexKey{preset} key
%    \begin{macrocode}
\define@key{ahref}{preset}[]{\def\ahref@preset{#1}}
\let\ahref@preset\@mpty
%    \end{macrocode}
% Color of the link text by command \DescribeMacro{\ahrefcolor}\cs{ahrefcolor}
% or as a key \texttt{textcolor}\IndexKey{textcolor}.
%    \begin{macrocode}
\def\ahypertxtcolor#1{\def\ahrefcolor{#1}}
\def\ahrefcolor{red}
\define@key{ahref}{textcolor}[]{\def\ahrefcolor{#1}}
%    \end{macrocode}
%\changes{v1.7}{2015/07/01}{Changed \cs{aeb@exiii} to \cs{expandafter}, changed
% \cs{aref(\#1)} to \texttt{\#1}.}
% (2015/07/01) Changed \cs{aeb@exiii} to \cs{expandafter}, changed
% \cs{aref(\#1)} to \texttt{\#1} in \cs{targetDictionary@pc}
% and \cs{targetDictionary@cc}.
%    \begin{macrocode}
\def\targetDictionary@pc#1{%
/T<</N<\expandafter\stringiiUnicode#1\relax>/R/C>>}
\def\targetDictionary@cp#1{/T<</R/P>>}
\def\targetDictionary@cc#1{%
/T<</R/P/T<</N<\expandafter\stringiiUnicode#1\relax>/R/C>>>>}
%    \end{macrocode}
%    \begin{macro}{\factory@ahyperref@defaults}
%    \begin{macro}{\setahyperDefaults}
%    \begin{macro}{\resetahyperDefaults}
% The defaults, \cs{factory@ahyperref@defaults}, of \cs{ahyperref}, as indicated above in the descriptions of the keys.  Can be redefined, I suppose.
% Perhaps the better approach is to use \cs{setahyperDefaults} to set the defaults, possibly overwriting the factory defaults.
% Use \cs{resetahyperDefaults} to cancel out the user defined defaults. You can also use the \texttt{preset} key for conveniently changing
% the attributes of the link.
%    \begin{macrocode}
\def\factory@ahyperref@defaults{goto=p2c,page,dest,open=userpref,view,%
    border=invisible,highlight=invert,linestyle=solid,linewidth=thin,%
    bordercolor,textcolor=red,preset}
\newcommand{\setahyperDefaults}[1]{\def\aeb@setahyperrefDefaults{#1}}
\let\aeb@setahyperrefDefaults\@empty
\newcommand{\resetahyperDefaults}{%
    \let\aeb@setahyperrefDefaults\@empty}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\ahyperref}
%    \begin{macro}{\ahyperlink}
% The \cs{ahyperref} command links a parent to its embedded children, or a child to a child. Cool.
% \changes{v1.7}{2015/07/01}{Rewrite the link to stuff, we'll use \texttt{cName} rather than description
% to link to the attachments, this is how it should have been to begin with.}
% (2015/07/01) Rewrite the link to stuff, we'll use \texttt{cName} rather than description
% to link to the attachments, this is how it should have been to begin with. All changes
% dated as (2015/07/01) are the changes needed.
%    \begin{macrocode}
\def\aeb@initahref#1{%
    \edef\expand@setkeys{%
    \noexpand\setkeys{ahref}{\factory@ahyperref@defaults}}%
    \expand@setkeys
    \ifx\aeb@setahyperrefDefaults\@empty\else
%    \end{macrocode}
% For the \cmd{\setahyperrefDefaults} we do not allow \texttt{dest}, \texttt{goto},
% \texttt{page}, or \texttt{preset}.
%    \begin{macrocode}
        \edef\expand@setkeys{\noexpand\setkeys{ahref}%
            [dest,goto,page,preset]{\aeb@setahyperrefDefaults}}%
        \expand@setkeys
    \fi
    \setkeys{ahref}{#1}%
    \ifx\ahref@preset\@empty\else
    \edef\expand@setkeys{%
        \noexpand\setkeys{ahref}{\ahref@preset}}\expand@setkeys\fi
    \let\ahref@dasharray\@empty
    \ifx\ahref@linestyle@keyvalue\ahref@dashedlinetyle
        \def\aeb@border@parameters{0 0 \ahref@linewidth[3.0]}%
        \def\ahref@dasharray{/D[3.0]}%
    \else
        \edef\aeb@border@parameters{\ahref@border}%
    \fi
    \ifx\ahef@invisible@border\@empty\def\ahref@linewidth{0}\fi
    \def\ahref@BS@Dict{/BS<<%
        \ahref@dasharray\ahref@linestyle@keyvalue/W \ahref@linewidth>>
    \ifx\ahref@bordercolor\@empty\else
        /C[\ahref@bordercolor]\fi\ahref@highlight}%
}
\newcommand{\ahyperref}[3][]{%
    \begingroup
    \dl@preProcDefns
    \def\u{\string\\u}%
    \aeb@initahref{#1}%
    \ifx\ahref@dest\@empty
        \def\ahref@dest@keyvalue{%
            /D[\ahref@page\space\ahref@view@keyvalue]}%
    \else
        \edef\ahref@dest@keyvalue{/D(\labelRef{\ahref@dest})}%
    \fi
    \aeb@ahref@setlink{#2}{#3}%
}
\newcommand{\ahyperlink}[3][]{%
    \begingroup
    \dl@preProcDefns
    \def\u{\string\\u}%
    \aeb@initahref{#1}%
    \ifx\ahref@dest\@empty
        \def\ahref@dest@keyvalue{%
            /D[\ahref@page\space\ahref@view@keyvalue]}%
    \else
        \def\ahref@dest@keyvalue{/D(\ahref@dest)}%
    \fi
    \aeb@ahref@setlink{#2}{#3}%
}
\def\aeb@ahref@setlink#1#2{%
    \ifx\ahrefcolor\@empty
        \@eqlinktxtcolor{}\let\ahypercolor\@empty\else
        \def\ahypercolor{\textcolor{\ahrefcolor}}\fi
    \setLink[\Border{\aeb@border@parameters}%
    \rawPDF{\ahref@BS@Dict}%
    \A{\ahref@dest@keyvalue/S/GoToE%
    \ahref@open@keyvalue\targetDictionary{#1}}]{\ahypercolor{#2}}%
    \endgroup
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \begin{macro}{\ahyperextract}
% The \cs{ahyperextract} command extracts an embedded file from the parent
% to simple view the document, to save and view, or simply to save. The
% \texttt{open} key determines the resulting action.
%    \begin{macrocode}
\newcommand{\ahyperextract}[3][]
{%
    \begingroup\dl@preProcDefns
    \def\u{\string\\u}%
    \aeb@initahref{#1}%
    \ifx\ahrefcolor\@empty
        \@eqlinktxtcolor{}\let\ahypercolor\@empty\else
        \def\ahypercolor{\textcolor{\ahrefcolor}}\fi
    \setLink[\Border{\aeb@border@parameters}%
    \rawPDF{\ahref@BS@Dict}%
%    \end{macrocode}
%\changes{v1.7}{2015/07/01}{Removed \cs{aref(\#2)}, replaced with \texttt{\#2}}
% (2015/07/01) Removed \cs{aref(\#2)}, replaced with \texttt{\#2}
%    \begin{macrocode}
%    \A{\JS{this.exportDataObject({cName: "\aref(#2)",%
    \A{\JS{this.exportDataObject({cName: "#2",%
nLaunch: \ahref@launch@type})}}]{\ahypercolor{#3}}%
    \endgroup
}
%    \end{macrocode}
%    \end{macro}
% \subsection{Unicodes}
%    \begin{macro}{\convertChriiUnicode}
% A simple command for mapping a character to its unicode
%    \begin{macrocode}
\def\convertChriiUnicode#1#2{\csarg\gdef{uni@#1}{#2}}%
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
\convertChriiUnicode\space{0020}
\convertChriiUnicode{!}{0021}
{\@makeother\"
\convertChriiUnicode{"}{0022}}
%\convertChriiUnicode{"}{0022}   % not available, but use \u0022 instead
\convertChriiUnicode{#}{0023}
\convertChriiUnicode{$}{0024}
{\@makeother\%
\convertChriiUnicode{%}{0025}}
\convertChriiUnicode{&}{0026}
\convertChriiUnicode{'}{0027}
\convertChriiUnicode{(}{0028}
\convertChriiUnicode{)}{0029}
\convertChriiUnicode{*}{002A}
\convertChriiUnicode{+}{002B}
\convertChriiUnicode{,}{002C}
\convertChriiUnicode{-}{002D}
\convertChriiUnicode{.}{002E}
\convertChriiUnicode{/}{002F}
\convertChriiUnicode{0}{0030}
\convertChriiUnicode{1}{0031}
\convertChriiUnicode{2}{0032}
\convertChriiUnicode{3}{0033}
\convertChriiUnicode{4}{0034}
\convertChriiUnicode{5}{0035}
\convertChriiUnicode{6}{0036}
\convertChriiUnicode{7}{0037}
\convertChriiUnicode{8}{0038}
\convertChriiUnicode{9}{0039}
\convertChriiUnicode{:}{003A}
\convertChriiUnicode{;}{003B}
\convertChriiUnicode{<}{003C}
\convertChriiUnicode{=}{003D}
\convertChriiUnicode{>}{003E}
\convertChriiUnicode{?}{003F}
\convertChriiUnicode{@}{0040}
\convertChriiUnicode{A}{0041}
\convertChriiUnicode{B}{0042}
\convertChriiUnicode{C}{0043}
\convertChriiUnicode{D}{0044}
\convertChriiUnicode{E}{0045}
\convertChriiUnicode{F}{0046}
\convertChriiUnicode{G}{0047}
\convertChriiUnicode{H}{0048}
\convertChriiUnicode{I}{0049}
\convertChriiUnicode{J}{004A}
\convertChriiUnicode{K}{004B}
\convertChriiUnicode{L}{004C}
\convertChriiUnicode{M}{004D}
\convertChriiUnicode{N}{004E}
\convertChriiUnicode{O}{004F}
\convertChriiUnicode{P}{0050}
\convertChriiUnicode{Q}{0051}
\convertChriiUnicode{R}{0052}
\convertChriiUnicode{S}{0053}
\convertChriiUnicode{T}{0054}
\convertChriiUnicode{U}{0055}
\convertChriiUnicode{V}{0056}
\convertChriiUnicode{W}{0057}
\convertChriiUnicode{X}{0058}
\convertChriiUnicode{Y}{0059}
\convertChriiUnicode{Z}{005A}
\convertChriiUnicode{[}{005B}
%\convertChriiUnicode{\}{005C} % not available, use unicode \u005C
\convertChriiUnicode{]}{005D}
\convertChriiUnicode{^}{005E}
\convertChriiUnicode{_}{005F}
\convertChriiUnicode{`}{0060}
\convertChriiUnicode{a}{0061}
\convertChriiUnicode{b}{0062}
\convertChriiUnicode{c}{0063}
\convertChriiUnicode{d}{0064}
\convertChriiUnicode{e}{0065}
\convertChriiUnicode{f}{0066}
\convertChriiUnicode{g}{0067}
\convertChriiUnicode{h}{0068}
\convertChriiUnicode{i}{0069}
\convertChriiUnicode{j}{006A}
\convertChriiUnicode{k}{006B}
\convertChriiUnicode{l}{006C}
\convertChriiUnicode{m}{006D}
\convertChriiUnicode{n}{006E}
\convertChriiUnicode{o}{006F}
\convertChriiUnicode{p}{0070}
\convertChriiUnicode{q}{0071}
\convertChriiUnicode{r}{0072}
\convertChriiUnicode{s}{0073}
\convertChriiUnicode{t}{0074}
\convertChriiUnicode{u}{0075}
\convertChriiUnicode{v}{0076}
\convertChriiUnicode{w}{0077}
\convertChriiUnicode{x}{0078}
\convertChriiUnicode{y}{0079}
\convertChriiUnicode{z}{007A}
%\convertChriiUnicode{{}{007B}     % not available, use unicode \u007B
\convertChriiUnicode{|}{007C}
%\convertChriiUnicode{}}{007D}     % not available, use unicode \u007D
{\@makeother~
\convertChriiUnicode{~}{007E}}
%    \end{macrocode}
%    \begin{macro}{\EURO}
%    \begin{macro}{\BSLASH}
%    \begin{macro}{\LBRACE}
%    \begin{macro}{\RBRACE}
%    \begin{macro}{\DQUOTE}
% These characters are entered into the description parameter of \cs{autolabelNum}
% or \cs{labelName} as either as literal characters or as its unicode \cs{uXXXX}.
% When \cs{u} is detected \cs{@stringiiUnicode}, the command that converts the string
% to all unicode hex, it calls \cs{getRawUnicode} to get the next four characters, which
% should be XXXX, place them in the stream, followed by \cs{@stringiiUnicode} so as to
% continue the processing of the next character in the description string. I've placed
% an \cs{expandafter} in the definition of \cs{getRawUnicode} to allow the commands below
% to be used. Thus instead of using \cs{u20AC}, which might necessitate the user to
% look up the code, \verb!\u\EURO! can be used instead.  Additional shortcut commands
% like these can be created. Except for \cs{EURO}, these are the ones \TeX{} has trouble
% processing.
%    \begin{macrocode}
\def\EURO{20AC}
\def\BSLASH{005C}
\def\LBRACE{007B}
\def\RBRACE{007D}
\def\DQUOTE{0022}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
% Display the Unicode encoding of a character
%
%    \begin{macrocode}
\def\displayUnicode#1{\csname uni@#1\endcsname}
%    \end{macrocode}
%    \begin{macro}{\stringiiUnicode}
% This is the primary command for converting a string, which
% may contain \cs{uXXXX} control sequences into unicode encoding.
% The first four hex digits must be \texttt{FEFF} to signal that
% the hex represents unicode.
%    \begin{macrocode}
\def\stringiiUnicode{FEFF\expandafter\@stringiiUnicode}
\def\@stringiiUnicode#1{%
    \ifx#1\relax\else
        \ifx#1\u\aeb@exiii\getRawUnicode
        \else
            \displayUnicode{#1}\aeb@exiii\@stringiiUnicode
        \fi
    \fi
}
\def\getRawUnicode{\expandafter\@getRawUnicode}
\def\@getRawUnicode#1#2#3#4{#1#2#3#4\@stringiiUnicode}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\unicodeStr}
% A convenience command for setting the initial value of a form field with unicode.
% Usage:
%\begin{verbatim}
%\labelName{myCoolIV}{\u0022\u20AC|e^\u007B\u005Cln(17)\u007D|$\u0022}
%\textField[\textSize{10}\textFont{MyriadPro-Regular}
%    \uDV{\unicodeStr(myCoolIV)}\uV{\unicodeStr(myCoolIV)}
%]{myCoolIV}{1.5in}{12bp}
%\end{verbatim}
% First you set the string using \cs{labelName}. The argument for \cs{unicodeStr}
% is delimited by parentheses, the argument itself is the label defined with
% \cs{labelName}.
%
%\medskip\noindent
% (2015/07/12) If \texttt{\#1} does not define a recognizable label (defined by \cs{labelName}
% we assume \texttt{\#1} is raw hex digits.
%    \begin{macrocode}
\def\unicodeStr(#1){\expandafter
    \ifx\csname aeb@aDescript@#1\endcsname\relax
    FEFF#1\else\aeb@exiii\stringiiUnicode\aref(#1)\relax\fi}
%    \end{macrocode}
%    \end{macro}
%
% \subsection{\texorpdfstring{\cs{labelName} and \cs{autolabelNum}}
%  {\CMD{labelName} and \CMD{autolabelNum}}}
%
%    \begin{macro}{\autolabelNum}
%    \begin{macro}{\autolabelNum*}
%    \begin{macro}{\labelName}
% Commands for defining the description string for the attachments.
% It is important that the description of the attached file, and the reference
% to in in the \texttt{/GoToE} exactly match. The commands define here set up the
% mapping between a ``\LaTeX'' label and the description. These commands also allow
% the document author to overwrite the default attachment descriptions. Usage:
%\begin{enumerate}
%\item\verb!\autolabelNum[<label>]{<attachment_number>}!
%\item\verb!\autolabelNum*[<label>]{<attachment_number>}{<description>}!
%\item\verb!\labelName{<label>}{<description>}!
%\end{enumerate}
% \cs{autolabelNum} and \cs{autolabelNum*} are used with attachments attached using the
% \texttt{attachments} option, while \cs{labelName} is used it the document author attached
% a file using the \texttt{docassembly} environment. \cs{labelName} is also used by
% \cs{autolabelNum} and \cs{autolabelNum*} to make definitions, in that respect, \cs{labelName}
% is the low-level command for setting up the mappings and definitions.
%    \begin{macrocode}
\def\ucspace{\u0020}
\begingroup\catcode`\"=\active \gdef\DQ{\string\"}%
    \gdef\@handledblquotes{\catcode`\"=\active\def"{\DQ}}%
    \toks0=\expandafter{\DLspecialDefs\@handledblquotes}%
    \xdef\DLspecialDefs{\the\toks0}%
\endgroup
%    \end{macrocode}
%\changes{v1.7l}{2015/08/07}{Add the switch \cs{ifHandleDblQuotes} switch}
% (2015/08/07) Add the switch \cs{ifHandleDblQuotes} switch.
%    \begin{macrocode}
\newif\ifHandleDblQuotes \HandleDblQuotesfalse
\def\sanitize@attach{\ifHandleDblQuotes\@handledblquotes\fi%
\@makeother\#\@makeother\$\@makeother\%\@makeother~}
{\obeyspaces\gdef\getdscrptCont#1{\gdef\aebp@description{#1}%
\aeb@labelName}%
\gdef\getdscrptStrCont#1{\gdef\aebp@description{#1}%
\aeb@labelNamestar}}%
%    \end{macrocode}
% \changes{v1.7}{2015/07/05}{Modified the commands \string\cs{labelName} and \string\cs{labelName@star} to
% gobble up any spaces between arguments before we switch to \string\cs{obeyspaces}.}
% (2015/07/05) Modified \cs{labelName} and \cs{labelName@star} to
% gobble up any spaces between arguments before we switch to \cs{obeyspaces}.
%    \begin{macrocode}
\let\aeb@isFromAutoLabelNum\aebp@Zero
\def\labelName#1{\bgroup\let\aeb@isFromAutoLabelNum\aebp@Zero
    \@for\x:=ABCDEFabcdef\do{\@makeother\x}%
    \def\aebp@labelname{#1}\@ifnextchar\bgroup{\labelName@i}{}}
%    \end{macrocode}
%\changes{v1.7k}{2015/08/02}{Added \cs{labelName@a}}
% (2015/08/02) \cs{autoLabelNum} used to call \cs{labelName}, not it calls
% \cs{labelName@a}, which sets a switch to notify \cmd{\aeb@labelName} of the origins
% of the call.
%    \begin{macrocode}
\def\labelName@a#1{\bgroup\let\aeb@isFromAutoLabelNum\aebp@One
    \def\aebp@labelname{#1}\@ifnextchar\bgroup{\labelName@i}{}}
\def\labelName@i{\obeyspaces\sanitize@attach\getdscrptCont}%
\def\labelName@star#1{\bgroup\@for\x:=ABCDEFabcdef\do{\@makeother\x}%
    \def\aebp@labelname{#1}\@ifnextchar\bgroup{\labelName@star@i}{}}%
\def\labelName@star@i{\obeyspaces\sanitize@attach\getdscrptStrCont}%
\newcommand{\autolabelNum}{%
    \@ifstar{\aeb@autoLabelNumstar}{\aeb@autoLabelNum}}
\newcommand\aeb@autoLabelNum[2][]{\def\alnargi{#1}%
    \def\@thisattachnum{#2}%
    \ifx\alnargi\@empty
         \def\aeb@next{%
            \labelName@a{attach#2}{AeB\space Attachment\space #2}}%
    \else
        \def\aeb@next{%
            \labelName@a{#1}{AeB\space Attachment\space #2}}%
    \fi
    \aeb@next%
}
\newcommand{\aeb@autoLabelNumstar}[2][]{%
    \def\alnargi{#1}\gdef\@thisattachnum{#2}%
    \ifx\alnargi\@empty\def\aeb@next{\labelName@star{attach#2}}\else
    \def\aeb@next{\labelName@star{#1}}\fi
    \aeb@next%
}
\def\aeb@labelName{%
%    \end{macrocode}
% \changes{v1.7k}{2015/08/02}{Added additional logic to \cs{aeb@labelName}}
% (2015/08/02) The definitions differ depending on whether it comes from
% the command \cs{autoLabelNum} or from \cs{labelNum}.
%    \begin{macrocode}
    \if\aeb@isFromAutoLabelNum\aebp@One
        \global\csarg\let
            {aeb@aDescript@attach\@thisattachnum}\aebp@description
        \global\csarg\let
            {aeb@aName@attach\@thisattachnum}\aebp@labelname
    \else
        \global\csarg\let
            {aeb@aDescript@\aebp@labelname}\aebp@description
        \global\csarg\let
            {aeb@aName@\aebp@labelname}\aebp@labelname\fi\egroup}
\def\aeb@labelNamestar{%
    \global\csarg\let
        {aeb@aDescript@attach\@thisattachnum}\aebp@description
    \global\csarg\let{aeb@aName@attach\@thisattachnum}\aebp@labelname
    \global\csarg\let{aeb@aDescript@\aebp@labelname}\aebp@description
    \global\csarg\let{aeb@aName@\aebp@labelname}\aebp@labelname\egroup}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% We need a general verbatim write environment, here is the one used by \textsf{exerquiz} and several other packages.
% If \textsf{exerquiz} is loaded, no need to redefine it.
%    \begin{macrocode}
\@ifpackageloaded{exerquiz}{}
{%
    \def\verbatimwrite{\@bsphack
        \let\do\@makeother\dospecials
        \catcode`\^^M\active\catcode`\^^I=12%
        \def\verbatim@processline{%
            \immediate\write\verbatim@out
            {\the\verbatim@line}}%
        \verbatim@start}
    \def\endverbatimwrite{\@esphack}
}
%    \end{macrocode}
%    \begin{environment}{attachmentNames}
% Enclose the \cs{labelName} and \cs{autolabelNum} commands this environment, which writes
% it contents verbatim to the file \cs{jobname\_xref.cut} and inputs it back in.  Child files can input this
% file to get the labels assigned for them by the parent document.
%    \begin{macrocode}
\newenvironment{attachmentNames}{%
    \newwrite \aeb@attachments@xref
    \immediate\openout \aeb@attachments@xref \jobname_xref.cut
    \let\verbatim@out\aeb@attachments@xref
%    \end{macrocode}
%\changes{v1.7l}{2015/08/07}{Set \cs{ifHandleDblQuotes} to true}
% (2015/08/07) Set \cs{ifHandleDblQuotes} to true, added a group.
%    \begin{macrocode}
    \immediate\write\verbatim@out{\string\begingroup
        \string\HandleDblQuotestrue}%
    \verbatimwrite}{%
    \endverbatimwrite
    \immediate\write\verbatim@out{\string\endgroup}%
    \immediate\closeout \aeb@attachments@xref
    \aftergroup\aeb@Input@xref}
\def\aeb@Input@xref{\InputIfFileExists{\jobname_xref.cut}{}{}}
%    \end{macrocode}
%    \end{environment}
%    \begin{macrocode}
% End of unicode segment
%</unicode>
%    \end{macrocode}
% \texttt{(2013/04/01)} The \texttt{createicon} block separates out the
% import icon macros, doc and pre-\texttt{docassembly} stuff.
%\changes{v1.4b}{2013/04/01}{The \texttt{createicon} block separates the
%import icon macros, doc and pre-\texttt{docassembly} stuff.}
%    \begin{macrocode}
% Begin aebpro and createicon segments
%<*aebpro|createicon>
%    \end{macrocode}
%
% \section{Document Assembly Methods}
%    Special commands and environment to take advantage of \app{Acrobat}'s extensive
%    library of security restricted methods. It is assumed the document author has properly
%    installed \texttt{aeb\_pro.js}.
%
% \subsection{The \texttt{docassembly} Environment}
%
%    \begin{environment}{docassembly}
% This is a wrapper environment for the \texttt{execJS} environment of the
% \textsf{insDLJS} Package. Place JavaScript lines in this environment and
% the script will execute one time after the file has been distilled and opened
% in Acrobat Pro for the fist time.
%    \begin{macrocode}
\newenvironment{docassembly}{%
\execJS{docassembly}
}{\endexecJS}
%    \end{macrocode}
%    \end{environment}
% \subsection{Supported Assembly JS API}
%
%    These are convenience commands -- called JavaScript helper commands -- to
%    executing security restricted JavaScript. The JS methods are defined in the
%    \texttt{aeb\_pro.js} file, kept as folder JavaScript. These commands are
%    executed in a verbatim environment where `\verb!\!' is still the escape
%    character. Each of the JavaScript helper commands expects a left
%    parenthesis `\texttt{(}' following the command name \emph{on the
%    same line} as the command name.\footnote{This requirement is consistent with JavaScript function usage.}
%    See the example below for correct usage.
%\begin{verbatim}
%\begin{docassembly}
%\addWatermarkFromFile({
%    bOnTop:false,
%    cDIPath:"/C/AcroTeX/AcroPackages/ManualBGs/Manual_BG_Print_AeB.pdf"
%});
%\end{docassembly}
%\end{verbatim}
% For each of the methods below, see the \textsl{JavaScript for Acrobat API Reference}.
%
%\medskip\noindent The command \cs{theDocObject} is normally set to \texttt{this}, meaning
% the current document. You may need to set it to some other doc object if you are trying to
% access a doc object other than the current one.
% \par\medskip\noindent
% Revised all these function that use \cs{theDocObject}; the revisions allow you to change
% the use of \cs{theDocObject}. The following are support commands for changing \cs{theDocObject}
% from within the \texttt{docassembly} environment.
% \changes{v2.5}{2016/08/03}{Revised all these function that use \string\cs{theDocObject}.}
%    \begin{macro}{\chngDocObjectTo}
%    All the JavaScript helper commands use \cs{theDocObject}, which is defined to be the \texttt{this}
%    object. To change it within the \env{docassembly} environment is difficult. The next command
%    aids in that problem.
%    \begin{macrocode}
\let\ap@mrk\@empty
\def\ap@gobtocomma#1,{}
\providecommand\chngDocObjectTo[2]{%
    \def#1##1\ap@mrk{#2,\ap@gobtocomma##1}}
%    \end{macrocode}
%    \end{macro}
%    The above defines a new command given by \texttt{\#1}. The command has one argument which is all content
%    up to the terminating mark \cs{sp@mrk}. The trick to removing \cs{thisDocObject} and replacing it with
%    \texttt{\#2}, in the above definition, we insert `\texttt{(\#2}' followed by \cs{ap@gobtocomma}, which absorbs
%    \cs{thisDocObject,} (absorbs everything through the first comma), followed by all content (\texttt{\#\#1}); the second \cs{@gobble} absorbs the left
%    parenthesis that opens the argument.
%    \begin{macrocode}
\def\ap@TF{aebTrustedFunctions}
%    \end{macrocode}
% An example of usage of \cs{chngDocObject} is \verb~\chngDocObjectTo{\newDO}{doc}~
% expanded above the \texttt{docassembly} environment. Later, we can say,
%\begin{verbatim}
%   \chngDocObjectTo{\newDO}{doc}
%   \begin{docassembly}
%   ...
%   \docSaveAs\newDO({ cPath: _path });
%   ...
%   \end{docassembly}
%\end{verbatim}
%That is, it is placed immediately after any of the commands below that uses \cs{theDocObject}.
%    \begin{macro}{\theDocObject}
%    This command is used in the definition of all JavaScript helper commands, as seen in the
%    definition of \cs{DeclareJSHelper} below. It is set to the doc object \texttt{this}. It can
%    be changed using \cs{chngDocObjectTo}, as described above.
%    \begin{macrocode}
\def\theDocObject{this}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\DeclareJSHelper}
%    A general purpose command for defining what I am calling JavaScript helper commands.
%    \begin{macrocode}
\providecommand\DeclareJSHelper[2]{%
    \def#1##1({\ap@TF(##1\theDocObject,#2,\ap@mrk}}
%    \end{macrocode}
%    For example, we declare |\DeclareJSHelper{\docSaveAs}{aebDocSaveAs}| below, the declaration defines a new command,
%    \cs{docSaveAs}:
%\begin{verbatim}
%    \def\docSaveAs#1({\ap@TF(#1\theDocObject,aebDocSaveAs,\ap@mrk}}
%\end{verbatim}
%    Note that the argument of \cs{docSaveAs} is delimited by the left parenthesis, thus \texttt{\#1} is everything through that opening
%    parenthesis. This approach allows more flexibility in the definition, there can be spaces following the
%    command name |\docSaveAs ({path: _path})|, for example.
%    \end{macro}
%    \begin{macrocode}
% End aebpro and createicon segments
%</aebpro|createicon>
%<*aebpro>
%    \end{macrocode}
%    \begin{macro}{\addWatermarkFromFile}
% This is the method \texttt{Doc.addWatermarkFromFile}.
%    \begin{macrocode}
\DeclareJSHelper{\addWatermarkFromFile}{aebAddWatermarkFromFile}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% End aebpro segment
%</aebpro>
%<*aebpro|createicon>
%    \end{macrocode}
%    \begin{macro}{\importIcon}
% This is the method \texttt{Doc.importIcon}.
%    \begin{macrocode}
\DeclareJSHelper{\importIcon}{aebImportIcon}
%    \end{macrocode}
%    \begin{macrocode}
% End aebpro and createicon segments
%</aebpro|createicon>
%<*aebpro>
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\importSound}
% This is the method \texttt{Doc.importSound}.
%    \begin{macrocode}
\DeclareJSHelper{\importSound}{aebImportSound}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\appopenDoc}
% This is the method \texttt{app.openDoc}.
%    \begin{macrocode}
\DeclareJSHelper{\appopenDoc}{aebAppOpenDoc}
%    \end{macrocode}
%    \end{macro}
% This is the method \texttt{Doc.saveAs}.
%    \changes{v2.5}{2016/08/31}{Added \string\cs{docSaveAs}}
%    \begin{macro}{\docSaveAs}
%    This is the document method \texttt{Doc.saveAs}.
%    \begin{macrocode}
\DeclareJSHelper{\docSaveAs}{aebDocSaveAs}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\insertPages}
% This is the method \texttt{Doc.insertPages}.
%    \begin{macrocode}
\DeclareJSHelper{\insertPages}{aebInsertPages}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\createTemplate}
% This is the method \texttt{Doc.createTemplate}.
%    \begin{macrocode}
\DeclareJSHelper{\createTemplate}{aebCreateTemplate}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\importDataObject}
% This is the method \texttt{Doc.importDataObject}.
%    \begin{macrocode}
\DeclareJSHelper{\importDataObject}{aebImportDataObject}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\executeSave}
% To save the document, use at the \emph{end of the doc assembly environment}. Usage:
% \verb!\executeSave()!. The \cs{@gobble} used below absorbs the comma that is placed immediately
% after the second argument by \cs{DeclareJSHelper}.
%    \begin{macrocode}
\DeclareJSHelper{\executeSave}{aebSaveAs,"Save"\@gobble}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\extractPages}
% API to extract pages from a newly formed document.
%    \begin{macrocode}
\DeclareJSHelper{\extractPages}{aebExtractPages}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\mailDoc}
% Used by eEnvelope to programmatically mail a document.
%    \begin{macrocode}
\DeclareJSHelper{\mailDoc}{aebMailDoc}
%    \end{macrocode}
%    \end{macro}
%    \begin{macro}{\sigInfo}
%    \begin{macro}{\signatureSign}
%    \begin{macro}{\signatureSetSeedValue}
% The \cs{signInfo} command is used for entering signing formation into what will
% become an object. \cs{signatureSign} takes no arguments, but uses the info
% entered by \cs{signInfo}. An example is
%\begin{verbatim}
%\begin{docassembly}
%\signInfo{
%    cSigFieldName: "sigOfDPS", ohandler: security.PPKLiteHandler,
%    cert: "D_P_Story.pfx", password: "dps017",
%    oInfo: { location: "Niceville, FL",
%      reason: "I am approving this document",
%      contactInfo: "dpstory@acrotex.net",
%      appearance: "My Signature" }
%};
%\signatureSign
%\end{docassembly}
%\end{verbatim}
% The \cs{sigInfo} command is a latex interface to creating the
% \texttt{oSigInfo} object.
%    \begin{macrocode}
\newcommand{\sigInfo}{var oSigInfo=}
\def\sigFieldObj(#1){var oSigField=this.getField(#1)}
%    \end{macrocode}
% For the \cs{signatureSetSeedValue}, the field object is required.
% This function assumes that the JavaScript variable \texttt{oSigField}
% is the field object. For examle,
%\begin{verbatim}
%\begin{docassembly}
%\sigFieldObj("sigOfDPS");
%\signatureSetSeedValue({
%    lockDocument:true,
%    appearanceFilter:"My Signature",
%    reasons: ["This is a reason", "This is a better reason"],
%    flags:0x80|0x100|0x8
%});
%\end{docassembly}
%\end{verbatim}
% The signatureSetSeedValue() methods seeds a signature field with various default values
% available to the signer.
%\begin{verbatim}
%\begin{docassembly}
%var sv={
%    mdp: "defaultAndComments",
%    reasons: ["This is a reason", "This is a better reason"],
%    flags:0x80|0x100|0x8
%};
%\sigFieldObj("sigOfDPS");
%\signatureSetSeedValue(sv);
%\end{docassembly}
%\end{verbatim}
%    \begin{macrocode}
\def\signatureSetSeedValue#1{%
    \ap@TF( oSigField, aebSignatureSetSeedValue, }
%    \end{macrocode}
% The function \cs{signatureSign} takes the info in the \texttt{oSigInfo} object,
% gets the security handler object, logs into the handler, calls
% \texttt{signatureSetSeedValue} if the \texttt{sv} property is in the
% \texttt{oSigInfo} object, and signs the field.
%    \begin{macrocode}
\begin{defineJS}[\def\defineJSjsR{^^J}]{\signatureSign}
if ( typeof oSigInfo.oHandler=="undefined" )
    oSigInfo.oHandler=security.PPKLiteHandler;
var engine=aebTrustedFunctions( security,
    aebSecurityGetHandler, oSigInfo.oHandler );
var path2Cert = (typeof oSigInfo.path2Cert == "undefined") ?
    aebTrustedFunctions( this, aebAppGetPath,
        {cCategory:"user"} )+"/Security"+"/"+oSigInfo.cert :
    oSigInfo.path2Cert;
aebTrustedFunctions( engine, aebSecurityHandlerLogin,
    { cPassword: oSigInfo.password, cDIPath: path2Cert});
var oSigField = this.getField(oSigInfo.cSigFieldName);
oSigInfo.oInfo.password=oSigInfo.password;
if ( typeof oSigInfo.sv!="undefined" ) {
    for (var o in oSigInfo.sv )
        oSigInfo.oInfo[o]=oSigInfo.sv[o];
}
var oSigArgs={ oSig: engine, oInfo: oSigInfo.oInfo };
if ( typeof oSigInfo.cLegalAttest!="undefined" )
    oSigArgs.cLegalAttest=oSigInfo.cLegalAttest;
if ( typeof oSigInfo.cDIPath!="undefined")
        oSigArgs.cDIPath=oSigInfo.cDIPath;
if ( typeof oSigInfo.bUI!="undefined")
        oSigArgs.bUI=oSigInfo.bUI;
aebTrustedFunctions( oSigField, aebSignatureSign, oSigArgs );
\end{defineJS}
%    \end{macrocode}
%    \begin{macro}{\certifyInvisibleSign}
% This command uses the trusted version of \texttt{certifyInvisibleSign} to sign. The command
% requires that \cs{sigInfo} is populated appropriately.
%\begin{verbatim}
%\begin{docassembly}
%\sigInfo{
%    cert: "DonStory.pfx", password: "myPassword",
%    cLegalAttest: "Certified using JavaScript",
%    bUI:false,
%    oInfo: {
%      location: "Niceville, FL",
%      reason: "I am certifying this document",
%      mdp: "defaultAndComments",
%    }
%};
%\certifyInvisibleSign
%\end{docassembly}
%\end{verbatim}
%    \begin{macrocode}
\begin{defineJS}[\def\defineJSjsR{^^J}]{\certifyInvisibleSign}
if ( typeof oSigInfo.oHandler=="undefined" )
    oSigInfo.oHandler=security.PPKLiteHandler;
var engine=aebTrustedFunctions( security,
    aebSecurityGetHandler, oSigInfo.oHandler );
var path2Cert=aebTrustedFunctions( this, aebAppGetPath,
    {cCategory:"user"} )+"/Security"+"/"+oSigInfo.cert;
aebTrustedFunctions( engine, aebSecurityHandlerLogin,
    { cPassword: oSigInfo.password, cDIPath: path2Cert});
oSigInfo.oInfo.password=oSigInfo.password;
var oSigArgs={ oSig: engine, oInfo: oSigInfo.oInfo };
if ( typeof oSigInfo.cLegalAttest!="undefined" )
    oSigArgs.cLegalAttest=oSigInfo.cLegalAttest;
if ( typeof oSigInfo.cDIPath!="undefined")
        oSigArgs.cDIPath=oSigInfo.cDIPath;
if ( typeof oSigInfo.bUI!="undefined")
        oSigArgs.bUI=oSigInfo.bUI;
aebTrustedFunctions( this, aebCertifyInvisibleSign, oSigArgs );
\end{defineJS}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
%    \begin{macrocode}
% End aebpro segment
%</aebpro>
%<*aebpro|createicon>
%    \end{macrocode}
% \subsection{Pre-docassembly Commands}
%
% In this section, we'll gather some ``useful'' commands
% for combining several \texttt{docassembly} tasks together.
% The \texttt{docassembly} environment is a partial-verbatim
% environment, expansion is severely limited. (\verb!\! is
% the escape sequence, but \verb!{}! are no longer grouping characters; hence
% macros with no argument can be expanded.) The trick is to expand
% before placing the lines in the \texttt{docassembly} environment.
%
% \subsubsection{Import and Place Images}
%
%    \begin{macro}{\declareImageAndPlacement}
% With this command, the document author can import images (icons)
% into the document give them names, and associate the image with a
% push button, specifically, once created by the \cs{placeImage}
% command, defined below. The command may be used several times, once
% for each image (icon) that is to be embedded and placed.
%
% This command should appear outside the \texttt{docassembly} environment.
%
% In the example below, give an image a name manAvatar, specify the
% path (\texttt{man1.pdf}) and list the names of the push buttons
% (ones created by \cs{placeImage}) where this image is to appear as
% a button face.
%\begin{verbatim}
% \declareImageAndPlacement
% {
%    name=manAvatar,path=man1.pdf,placement={Avatar1,Avatar2}
% }
%\end{verbatim}
%\par\medskip\noindent
%The macro \cs{@importIconToks} will contain all JavaScript the commands created
% by the command \cs{declareImageAndPlacement}. \cs{aebp@image@cnt} is used
% for automatically generating a name if one is not given.
%    \begin{macrocode}
\let\predocassemJS\@empty
\def\aeb@image@cnt{0}
%    \end{macrocode}
% These keys are^^A
% valid for the argument of \cs{declareImageAndPlacement}:
% name, path, and placement are required; if the image is a PDF, \texttt{page=0} is the
% default, otherwise, you can specify from which page the PDF image is to be
% extracted from the PDF file.
% \IndexKey{name}\IndexKey{path}\IndexKey{page}\IndexKey{placement}\IndexKey{embedonly}%
% \IndexKey{firstpage}\IndexKey{lastpage}^^A
%    \begin{macrocode}
\define@key{importIcons}{name}[]{\def\importIcons@name{#1}}
\define@key{importIcons}{path}[]{\def\importIcons@path{#1}}
\define@key{importIcons}{page}[]{\def\importIcons@page{#1}}
\define@key{importIcons}{placement}[]{\def\importIcons@placement{#1}}
\define@boolkey{importIcons}{embedonly}[true]{}
\define@key{importIcons}{firstpage}[]{\def\importIcons@firstpage{#1}}
\define@key{importIcons}{lastpage}[]{\def\importIcons@lastpage{#1}}
%    \end{macrocode}
% The next two macros parse \cs{importIcons@placement} after it has been
% broken down into its comma-delimited parts. We pick off the optional
% argument using \cs{aebp@getFace}, then we call \cs{aebp@getPlacement} to
% get the field name. These are executed from within \cs{declareImageAndPlacement}
% below.
%
% If there is no optional argument, the default is 0, for the normal appearance state.
%    \begin{macrocode}
\newcommand{\aebp@getFace}[1][0]{%
    \def\importIcons@face{#1}\aebp@getPlacement}
\def\aebp@getPlacement#1\@nil{\def\importIcons@fieldname{#1}%
    \expandafter\ap@strpspcs\importIcons@fieldname\@nil
    \edef\importIcons@fieldname{\to@nilarg}%
}
%    \end{macrocode}
% The command \cs{declareImageAndPlacement} takes one argument, key-value
% pairs as described above. This command may be use many times, once for
% each image.
%    \begin{macro}{\declareMultiImages}
% Here is another macro, created after \cs{declareImageAndPlacement},
% that enables the declaration of multiple images and placements.
% The following is an example of usage:
%\begin{verbatim}
%\declareMultiImages{%
%    {name=manAvatar,path=man1.pdf,placement={Avatar1,Avatar2}}
%    {path=girl.png,placement={Avatar3,Avatar4}}
%    {path=AcroFord.jpg,placement=AcroFord}
%    {path=scot.gif,placement=Scot}
%}
%\end{verbatim}
% (9/24/2009) Now you can enter the face number as an optional argument
% in the placement value: \texttt{[0]} (default, normal icon), \texttt{[1]} (down icon)
% \texttt{[2]} (rollover icon). The optional argument precedes the field name. For Example
%\begin{verbatim}
%\declareMultiImages
%{%
%    {path=graphics/man1.pdf,placement={Avatar1,Avatar2}}
%    {path=graphics/girl.png,placement={[2]Avatar1,[2]Avatar2}}
%}
%\end{verbatim}
%    \begin{macrocode}
\newcommand{\declareMultiImages}[1]{%
    \edef\@tforExp{\noexpand\@tfor\noexpand\@dipArgs:=#1}%
    \@tforExp\do{%
        \expandafter\declareImageAndPlacement
        \expandafter{\@dipArgs}%
    }%
}
%    \end{macrocode}
%    \end{macro}
% The definition of \cs{declareImageAndPlacement}. Keys recognized are
% defined above: \texttt{name}, \texttt{path}, \texttt{page}, \texttt{placement}.
%    \begin{macrocode}
\newcommand{\declareImageAndPlacement}[1]{%
    \edef\@tempexp{\noexpand\setkeys{importIcons}{name,path,page,%
        placement,embedonly=false,#1}}\@tempexp
    \ifx\importIcons@name\@empty{\count0=\aeb@image@cnt
    \advance\count0by1\relax\xdef\aeb@image@cnt{\the\count0}}%
    \edef\importIcons@name{aebImage\aeb@image@cnt}\fi
    \ifx\importIcons@path\@empty
        \PackageError{aeb_pro}{The `path' key is required}
            {Please give the path of the icon.}\fi
    \ifx\importIcons@placement\@empty\ifKV@importIcons@embedonly\else
        \PackageWarningNoLine{aeb_pro}{%
        The `placement' key was not found for the\MessageBreak
        image named "\importIcons@name".\MessageBreak
        Specify this key, or insert the image manually in\MessageBreak
        the docassembly environment.}\fi\fi
    \xdef\predocassemJS{\predocassemJS
            var retn=\importIcon({cName:"\importIcons@name",%
            cDIPath:"\importIcons@path"%
            \ifx\importIcons@page\@empty\else,%
            nPage:\importIcons@page\fi});^^J%
        if ( retn==-1 ) console.println("The file
        \string\"\importIcons@path\string\" could not be opened.");^^J%
        if ( retn==-2 ) console.println("Selected page
        (page=\importIcons@page) for \string\"\importIcons@path\string\"
        is invalid.");^^J}%
    \ifx\importIcons@placement\@empty\else
        \@for\@fieldname:=\importIcons@placement\do{%
            \expandafter\aebp@getFace\@fieldname\@nil
            \xdef\predocassemJS{\predocassemJS
            var f = this.getField("\importIcons@fieldname");^^J%
            if ( f == null ) console.println("The field
                \string\"\importIcons@fieldname\string\"
                    does not exist.");^^J%
            try { f.buttonSetIcon(this.getIcon("\importIcons@name"),%
                \importIcons@face); }
            catch(e){};^^J}%
        }%
    \fi
}
\@onlypreamble\declareImageAndPlacement
%    \end{macrocode}
%    \end{macro}
%
% \subsubsection{Embed Multi-page Images}
%
%    \begin{macro}{\iconNameI}
% \cs{iconNameI} is the ``template name'' for the icons, this template is a JavaScript string and expands to a
% function of \texttt{i}. The default definition is given below.
%    \begin{macrocode}
\newcommand{\iconNameI}[1]{\def\IconNameI(##1){#1}}
\iconNameI{#1+"."+i}
%\iconNameI{#1+i}
\@onlypreamble\iconNameI
%    \end{macrocode}
%    \begin{macro}{\embedMultiPageImages}
% \cs{embedMultiPageImages} is designed for a PDF filled with icon pages. It sets up a JavaScript
% loop, and imports the specified page range. The name of the icon is determined by
% the command \cs{iconNameI}, this is function of the JavaScript variable \texttt{i}, the index
% for the loop. The command embeds the icons only. The parameters are\dots
% \begin{itemize}
%   \item[] key-value pairs: \texttt{firstpage}, \texttt{lastpage}, \texttt{placement},
%           \texttt{name} and \texttt{path} are the only keys recognized.
%\end{itemize}
%    \begin{macrocode}
\newcommand{\embedMultiPageImages}[1]{%
    \setkeys{importIcons}{name,path,page,placement,%
        firstpage,lastpage,#1}%
    \ifx\importIcons@firstpage\@empty
        \def\importIcons@firstpage{1}\else
        {\count0=\importIcons@firstpage}\fi
    \ifx\importIcons@lastpage\@empty
        \def\importIcons@lastpage{this.numPages}\else
        {\count0=\importIcons@lastpage}\fi
    \ifx\importIcons@name\@empty
        \PackageError{aeb_pro}{The `name' key is required}
        {Please give the icon family a name.}\fi
    \ifx\importIcons@path\@empty
        \PackageError{aeb_pro}{The `path' key is required}
            {Please give the path of the icon.}\fi
    \def\r{^^J}\def\t{\space\space\space\space}%
    \let\predocassemJSPlace\@empty
    \ifx\importIcons@placement\@empty\else
        \@for\@fieldname:=\importIcons@placement\do{%
            \expandafter\aebp@getFace\@fieldname\@nil
            \edef\predocassemJSPlace{\predocassemJSPlace\t
            var f = this.getField("\importIcons@fieldname."+i);\r\t
            if ( f == null ) console.println("The field
                \string\"\importIcons@fieldname."+i+"\string\"
                    does not exist.");\r\t
            try { f.buttonSetIcon(this.getIcon(%
\IconNameI("\importIcons@name")),%
                \importIcons@face); }
            catch(e){};\r}%
        }%
    \fi
    \xdef\predocassemJS{\predocassemJS
        var l=\importIcons@lastpage-\importIcons@firstpage+1;\r
        for (var i=0; i<l; i++) {\r\t
            var retn=\importIcon({%
                cName:\IconNameI("\importIcons@name"),%
                cDIPath:"\importIcons@path",%
                nPage:\importIcons@firstpage+i-1});\r\t
            if ( retn==-1 ) console.println("The file
            \string\"\importIcons@path\string\" could not
                be opened.");\r\t
            if ( retn==-2 ) console.println("Selected page
            (page="+(i+1)+") for \string\"\importIcons@path\string\"
            is invalid.");\r
            \predocassemJSPlace
        }\r
        var oIcon=this.getIcon("nullIcon");\r
        if ( oIcon == null )
            this.addIcon("nullIcon", this.createIcon("", 0, 0));\r
    }%
}
\@onlypreamble\embedMultiPageImages
% End aebpro and createicon segments
%</aebpro|createicon>
%<*aebpro>
%    \end{macrocode}
%    \begin{macrocode}
% End aebpro segment
%</aebpro>
%<*animecommon>
%    \end{macrocode}
%    \begin{macro}{\placeAnimeCtrlBtnFaces}
% This command is part of the button anime set. It embeds (using the command \cs{declareMultiImages})
% the icon appearances of the anime controls, The field names for these controls have a name
% of the form
%\begin{quote}
%\texttt{<anime\_basename>4BtnCtrl.<fieldName>}
%\end{quote}
% where \texttt{<anime\_basename>} is the
% base name of the field that displays the images; and \texttt{<fieldName>} is the name of
% the particular control.
%
% The first parameter is the relative or absolute path to the icons set (this path is
% used by Acrobat JavaScript, not by {\LaTeX}; the second parameter is a comma-delimited
% list of button animes to be controlled. An example follows:
%\begin{verbatim}
%\placeAnimeCtrlBtnFaces{graphics/btn_anime_icons1.pdf}%
%   {myAnimation,mysine,FamPhotos}
%\end{verbatim}
%    \begin{macrocode}
\newcommand{\placeAnimeCtrlBtnFaces}[3][\pathToBtnCtrlIcons]{\begingroup
    \toks@={\aep@I{\aep@setAFirst}{animeFirst}%
            \aep@I{\aep@setASB}{animeSB}%
            \aep@I{\aep@setAPB}{animePB}%
            \aep@I{\aep@setAPaus}{animePause}%
            \aep@I{\aep@setAPF}{animePF}%
            \aep@I{\aep@setASF}{animeSF}%
            \aep@I{\aep@setALast}{animeLast}%
            \aep@I{\aep@setAPlus}{animePlus}%
            \aep@I{\aep@setAMinus}{animeMinus}}%
    \def\aep@I##1##2{\let##1\@empty}\the\toks@
    \def\aep@I##1##2{\edef##1{##1,\aep@thisAnime4BtnCtrl.##2}}%
    \@for\aep@thisAnime:=#3\do{\the\toks@}%
    \def\aep@I##1##2{\edef##1{\expandafter\@gobble##1}}\the\toks@
    \ifx\pathToBtnCtrlIcons\@empty
    \let\@pathsep\@empty\else\def\@pathsep{/}\fi
    \declareMultiImages{%
%    \end{macrocode}
% A document author may supply his own icon set, they must be placed in a
% PDF document in the expected order:\par
% \begin{center}
% \begin{tabular}{cl}
% Page & Icon\\\hline
%   0  & Go to first frame\\
%   1  & Go to last frame\\
%   2  & Step back one frame\\
%   3  & Step forward one frame\\
%   4  & Play backward\\
%   5  & Play forward\\
%   6  & Pause\\
%   7  & Increase speed\\
%   8  & Decrease speed
% \end{tabular}
% \end{center}
%    \begin{macrocode}
        {path=#1\@pathsep#2,page=0,placement={\aep@setAFirst}}
        {path=#1\@pathsep#2,page=2,placement={\aep@setASB}}
        {path=#1\@pathsep#2,page=4,placement={\aep@setAPB}}
        {path=#1\@pathsep#2,page=6,placement={\aep@setAPaus}}
        {path=#1\@pathsep#2,page=5,placement={\aep@setAPF}}
        {path=#1\@pathsep#2,page=3,placement={\aep@setASF}}
        {path=#1\@pathsep#2,page=1,placement={\aep@setALast}}
        {path=#1\@pathsep#2,page=7,placement={\aep@setAPlus}}
        {path=#1\@pathsep#2,page=8,placement={\aep@setAMinus}}
    }%
    \endgroup
}
\@onlypreamble\placeAnimeCtrlBtnFaces
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% End animecommon segment
%</animecommon>
%<*aebpro>
%    \end{macrocode}
%    \begin{macrocode}
%    \end{macrocode}
%    \begin{macro}{\placeImageToBtn}
% \cs{iconNameI} is the ``template name'' for the icons, this template is a
% JavaScript string and expands to a function of \texttt{i}. The default
% definition is given below.
%    \begin{macrocode}
\newcommand{\placeImageToBtn}[1]{%
    \setkeys{importIcons}{name,path,page,placement,#1}%
    \ifx\importIcons@placement\@empty\else
        \@for\@fieldname:=\importIcons@placement\do{%
            \expandafter\aebp@getFace\@fieldname\@nil
            \xdef\predocassemJS{\predocassemJS
            var f = this.getField("\importIcons@fieldname");^^J%
            if ( f == null ) console.println("The field
                \string\"\importIcons@fieldname\string\"
                    does not exist.");^^J%
            try { f.buttonSetIcon(this.getIcon("\importIcons@name"),%
                \importIcons@face); }
            catch(e){};^^J}%
        }%
    \fi
}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% \subsubsection{\texorpdfstring{\cs{insertPreDocAssembly}}{\CMD{insertPreDocAssembly}}}
%    \begin{macro}{\insertPreDocAssembly}
% This command is to be used within the \texttt{docassembly} environment,
% and expands to all the JavaScript lines created by
% \cs{declareImageAndPlacement}.
%    \begin{macrocode}
% End aebpro segment
%</aebpro>
%<*aebpro|createicon>
\newcommand{\insertPreDocAssembly}{\predocassemJS}
\let\importAndSetImages\insertPreDocAssembly
%    \end{macrocode}
%    \end{macro}
%
% \subsection{Placing an Image (\texorpdfstring{\cs{placeImage}}{\CMD{placeImage}})}
%
%    \begin{macro}{\placeImage}
% This command creates the target push buttons for the images imported using
% \cs{declareImageAndPlacement} and \cs{importAndSetImages}. It creates a readonly
% push button with an icon only appearance. The first argument can be used
% to modify the appearance (as described in the eforms manual), the second is
% the name of the field (this is referenced in the \texttt{placement} key of
% \cs{declareImageAndPlacement}, the third and fourth parameters are the width
% and height, respectively of the push button.
%    \begin{macrocode}
\newcommand{\placeImage}[4][]{\pushButton[%
    \BC{}\BG{}\S{S}\Ff{\FfReadOnly}\autoCenter{n}\FB{true}
    #1\I{null}\TP{1}]{#2}{#3}{#4}}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% End of aebpro and createicon segments
%</aebpro|createicon>
%<*animecommon>
%    \end{macrocode}
%
% \subsection{Button and Ocg Animation (Anime)}
%
% The following are the key-value pairs common to both button and ocg anime.
%    \begin{macro}{\animeSetup}
%    \begin{macro}{\widthFirstRow}
% \cs{animeSetup} can be used to set the anime parameters when controls=none, and
% you want to move button set to a place other than the default location, which is
% below the anime. After setting the parameters, we have some code for calculating
% the \cs{widthFirstRow}. this value is used by \cs{insertCtrlButtons} to set the
% width of an enclosing \cs{parbox}, the first row is always wider than the second.
%    \begin{macrocode}
\newcommand{\animeSetup}[1]{%
    \let\animeSetupPresets\@empty
    \edef\@tempExp{\noexpand\setkeys{btnAnime}{#1}}\@tempExp
%    \setkeys{btnAnime}{#1}%
    \ifx\btnAnimeCtrlBdryColor\@empty\else
%    \end{macrocode}
% Calculate the presets for the buttons as passed by the key-values of
% \cs{animeSetup}.
%    \begin{macrocode}
    \edef\@tmpExp{\noexpand\g@addto@macro%
        \noexpand\animeSetupPresets{%
        \noexpand\BC{\btnAnimeCtrlBdryColor}}}\@tmpExp
    \edef\@tmpExp{\noexpand\g@addto@macro%
        \noexpand\animeSetupPresets{%
        \noexpand\W{\btnAnimeCtrlBdryWidth}}}\@tmpExp\fi
%    \end{macrocode}
% Calculate the value of \cs{@btnanimerowsep}, the distance between rows
%    \begin{macrocode}
    \edef\@btnanimerowsep{\btnanimerowsep}% dps10
%    \setlength{\@tempdima}{\btnanimerowsep+2bp}%
%    \edef\@btnanimerowsep{\the\@tempdima}%
%    \end{macrocode}
% Calculate the width of the widest row, usually the first.
%    \begin{macrocode}
    \setlength{\@tempdima}{%
        (\btnAnimeCtrlW+2bp)*\numWidgetsFirstRow+%
        (\btnanimebtnsep*(\numWidgetsFirstRow-1))}%
    \addtolength{\@tempdima}{\addSpaceBtwnPMBtns}%
    \edef\widthFirstRow{\the\@tempdima}%
}
%    \end{macrocode}
%    \begin{macro}{\insertCtrlButtons}
% This command can be used to place the anime controls somewhere other than at
% the default location (under the anime).
%    \begin{macrocode}
\newcommand{\insertCtrlButtons}[1][c]{%
    \parbox[#1][\totalheight+2bp]{\widthFirstRow}{%
    \offinterlineskip\centering\aep@btn@anime@controls}}
\newcommand{\setspaceBtwnPMBtns}[1]{{%
    \settowidth{\@tempdima}{#1\kern2bp}%
    \xdef\tmp@spaceBtwnPMBtns{\the\@tempdima}}%
    \edef\@spaceBtwnPMBtns{\tmp@spaceBtwnPMBtns}}
\setspaceBtwnPMBtns{\space}
\def\addSpaceBtwnPMBtns{\ifKV@btnAnime@usetworows0bp\else
    \ifKV@btnAnime@nospeedcontrol0bp\else\@spaceBtwnPMBtns\fi\fi}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% \paragraph{Define Key-value Pairs for anime.} The next set of code
% defines the key-value pairs for \cs{btnAnime} and \texttt{ocgAnime}.\IndexKey{type}
% \IndexKey{fieldName}\IndexKey{ocgAnimeName}\IndexKey{iconName}\IndexKey{speed}\par
% \IndexKey{nFrames}
%    \begin{macrocode}
\define@choicekey+{btnAnime}{type}[\val\nr]%
    {loop,palindrome,stopatboundary}[stopatboundary]{%
        \edef\aebp@btnAnime@type{\nr}}{}
\define@key{btnAnime}{fieldName}[]{\gdef\animeBtnFieldName{#1}}
\define@key{btnAnime}{ocgAnimeName}[]{\gdef\animeBtnFieldName{#1}}
\define@key{btnAnime}{iconName}[]{\gdef\animeBtnBaseName{#1}}
\define@key{btnAnime}{speed}[200]{\gdef\animeBtnSpeed{#1}}
\define@key{btnAnime}{nFrames}[]{\gdef\nFrames{#1}}
%    \end{macrocode}
% Additional keys
% \IndexKey{autorun}\IndexKey{autopause}\IndexKey{autoplayevent}
% \IndexKey{autopauseevent}
% \IndexKey{poster}%
%    \begin{macrocode}
\define@boolkey{btnAnime}{autorun}[true]{}
\define@boolkey{btnAnime}{autopause}[true]{}
\define@choicekey+{btnAnime}{autoplayevent}[\val\nr]%
    {pageopen,pagevisible}[pageopen]{\ifcase\nr\relax
        \def\aebp@autoplayevent{\AAPageOpen}\or
        \def\aebp@autoplayevent{\AAPageVisible}\fi}{}%
\def\aebp@autoplayevent{\AAPageOpen}
\define@choicekey+{btnAnime}{autopauseevent}[\val\nr]%
    {pageclose,pageinvisible}[pageclose]{\ifcase\nr\relax
        \def\aebp@autopauseevent{\AAPageClose}\or
        \def\aebp@autopauseevent{\AAPageInvisible}\fi}{}%
\def\aebp@autopauseevent{\AAPageClose}
\define@choicekey+{btnAnime}{poster}[\val\nr]%
    {first,last,none}[first]{\edef\aebp@btnAnime@poster{\nr}}{}
%    \end{macrocode}
% (Needs FIX) Behavior of the poster. When \texttt{poster=first} this is OK, no bugs.
% When \texttt{poster=last} and the animation begins (at least for button)
% the animation does not appear to be running until the last frame, then
% it starts up. In this case, we display the last frame but when play is pressed
% the animation is `cleared' and begins from frame 1.
%    \begin{macrocode}
%    \end{macrocode}
% The following are key-values for the control buttons, in addition
% to \texttt{ctrlwidth}\IndexKey{ctrlwidth} and \texttt{ctrlheight}\IndexKey{ctrlheight},
% we also include \texttt{ctrlbdrywidth}\IndexKey{ctrlbdrywidth}
% and \texttt{ctrlbdrycolor}\IndexKey{ctrlbdrycolor} the latter two so we can get the spacing
% correct.
%    \begin{macrocode}
\define@key{btnAnime}{ctrlwidth}[18bp]{\def\btnAnimeCtrlW{#1}}
\define@key{btnAnime}{ctrlheight}[9bp]{\def\btnAnimeCtrlH{#1}}
\define@choicekey{btnAnime}{ctrlbdrywidth}[\val\nr]{none,%
    thin,medium,thick}[thin]{\edef\btnAnimeCtrlBdryWidth{\nr}}
%    \end{macrocode}
%    (2017/03/08) Let \texttt{ctrlbdrycolor} accept \pkg{xcolor}, if loaded
%    \changes{v2.8a}{2017/03/08}{\string\texttt{ctrlbdrycolor} accepts \string\pkg{xcolor}, if loaded}
%    \begin{macrocode}
\define@key{btnAnime}{ctrlbdrycolor}[]{\def\ap@argi{#1}%
    \ifx\ap@argi\@empty\let\btnAnimeCtrlBdryColor\@empty\else
    \HyColor@IfXcolor{\HyColor@XZeroOneThreeFour{#1}
        {\btnAnimeCtrlBdryColor}{}{}}
        {\edef\btnAnimeCtrlBdryColor{#1}}\fi
} % PDF color
\let\animeSetupPresets\@empty
%    \end{macrocode}
% A command to set the space between control buttons, uses \cs{btnanimebtnsep}
%    \begin{macrocode}
\newcommand{\@ctrlsbtnsep}{\cgBdry[\btnanimebtnsep]} % dps10
%    \end{macrocode}
%    \begin{macro}{\btnanimebtnsep}
% The space between buttons
%    \begin{macro}{\vspacectrlsep}
% The vertical space between the bottom of the anime and the control button set.
%    \begin{macro}{\btnanimerowsep}
% The vertical distance between two rows of control buttons.
%    \begin{macrocode}
\newcommand{\btnanimebtnsep}{1bp}
\newcommand{\vspacectrlsep}{3bp}
\newcommand{\aep@vspacectrlsep}{\vspacectrlsep}
\newcommand{\btnanimerowsep}{1bp}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%
% \paragraph{Definitions of ``skins'' may be redefined.}
%    \begin{macro}{\btnAnimeSkini}
%    \begin{macro}{\btnAnimeSkinii}
%    \begin{macro}{\btnAnimeSkiniii}
%    \begin{macro}{\btnAnimeSkiniv}
%    \begin{macro}{\btnAnimeSkinv}
%    \begin{macro}{\btnAnimeSkinvi}
% The definitions of the various control button layouts. These are normally
% not used by the document author.
%    \begin{macrocode}
\newcommand{\btnAnimeSkini}{\ifKV@btnAnime@usetworows
    \makebox[\linewidth][c]{%
    \btnAnimeGoToFirst\@ctrlsbtnsep\btnAnimeStepBack
    \@ctrlsbtnsep\btnAnimePlayBack
    \@ctrlsbtnsep\btnAnimePause
    \@ctrlsbtnsep\btnAnimePlayForward
    \@ctrlsbtnsep\btnAnimeStepForward
    \@ctrlsbtnsep\btnAnimeGoToLast}\ifKV@btnAnime@nospeedcontrol\else
    \vcgBdry[\@btnanimerowsep]\makebox[\linewidth][c]{%
    \btnAnimePlus\@ctrlsbtnsep\btnAnimeMinus}\fi\else
    \makebox[\linewidth][s]{\hss
    \btnAnimeGoToFirst
    \@ctrlsbtnsep\btnAnimeStepBack
    \@ctrlsbtnsep\btnAnimePlayBack
    \@ctrlsbtnsep\btnAnimePause
    \@ctrlsbtnsep\btnAnimePlayForward
    \@ctrlsbtnsep\btnAnimeStepForward
    \@ctrlsbtnsep\btnAnimeGoToLast
    \ifKV@btnAnime@nospeedcontrol\else
    \kern\@spaceBtwnPMBtns\btnAnimePlus
    \@ctrlsbtnsep\btnAnimeMinus\fi\hss}\fi}
\newcommand{\btnAnimeSkinii}{\ifKV@btnAnime@usetworows
    \makebox[\linewidth][c]{%
    \btnAnimeGoToFirst
    \@ctrlsbtnsep\btnAnimePlayBack
    \@ctrlsbtnsep\btnAnimePause
    \@ctrlsbtnsep\btnAnimePlayForward
    \@ctrlsbtnsep\btnAnimeGoToLast}%
    \ifKV@btnAnime@nospeedcontrol\else\vcgBdry[\@btnanimerowsep]%
    \makebox[\linewidth][c]{\btnAnimePlus\@ctrlsbtnsep
    \btnAnimeMinus}\fi\else\makebox[\linewidth][s]{\hss
    \btnAnimeGoToFirst\@ctrlsbtnsep
    \btnAnimePlayBack\@ctrlsbtnsep\btnAnimePause%
    \@ctrlsbtnsep\btnAnimePlayForward\@ctrlsbtnsep
    \btnAnimeGoToLast\ifKV@btnAnime@nospeedcontrol\else
    \kern\@spaceBtwnPMBtns\btnAnimePlus
    \@ctrlsbtnsep\btnAnimeMinus\fi\hss}\fi}
\newcommand{\btnAnimeSkiniii}{\ifKV@btnAnime@usetworows
    \makebox[\linewidth][c]{%
    \btnAnimeGoToFirst\@ctrlsbtnsep\btnAnimePause
    \@ctrlsbtnsep\btnAnimePlayForward}%
    \ifKV@btnAnime@nospeedcontrol\else
    \vcgBdry[\@btnanimerowsep]\makebox[\linewidth][c]{%
        \btnAnimePlus\@ctrlsbtnsep\btnAnimeMinus}\fi\else
    \makebox[\linewidth][s]{\hss
    \btnAnimeGoToFirst\@ctrlsbtnsep\btnAnimePause
    \@ctrlsbtnsep\btnAnimePlayForward
    \ifKV@btnAnime@nospeedcontrol\else\kern\@spaceBtwnPMBtns
    \btnAnimePlus\@ctrlsbtnsep\btnAnimeMinus\fi\hss}\fi}
\newcommand{\btnAnimeSkiniv}{%
    \makebox[\linewidth][c]{%
    \btnAnimeGoToFirst
    \@ctrlsbtnsep\btnAnimeStepBack
    \@ctrlsbtnsep\btnAnimeStepForward
    \@ctrlsbtnsep\btnAnimeGoToLast}}
\newcommand{\btnAnimeSkinv}{\PackageWarning{aeb_pro}
    {skin5 is undefined.\MessageBreak You may customize
     by defining skin5;\MessageBreak meanwhile, using default,
     skin1}\btnAnimeSkini}
\newcommand{\btnAnimeSkinvi}{\PackageWarning{aeb_pro}
    {skin6 is undefined.\MessageBreak You may customize
    by defining skin6;\MessageBreak meanwhile, using default,
     skin1}\btnAnimeSkini}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% The choice for the \texttt{controls}\IndexKey{controls} key. \texttt{skin5} and \texttt{skin6}
% default to \texttt{skin1}. These can be redefined for a custom configuration.
%    \begin{macrocode}
\newcommand{\aepnumWidgetsFirstRow}[2]{\def\numWidgetsFirstRow{%
    \ifKV@btnAnime@nospeedcontrol#1\else
    \ifKV@btnAnime@usetworows#1\else#2\fi\fi}}
\newcommand{\numWidgetsFirstRowV}{\aepnumWidgetsFirstRow{7}{9}}
\newcommand{\numWidgetsFirstRowVI}{\aepnumWidgetsFirstRow{7}{9}}
\define@choicekey+{btnAnime}{controls}[\val\nr]%
    {none,skin1,skin2,skin3,skin4,skin5,skin6}[skin1]{%
    \ifcase\nr\relax
        \let\aep@btn@anime@controls\@empty
        \def\widthFirstRow{0pt}\or
        \def\aep@btn@anime@controls{\btnAnimeSkini}%
            \aepnumWidgetsFirstRow{7}{9}\or
        \def\aep@btn@anime@controls{\btnAnimeSkinii}%
            \aepnumWidgetsFirstRow{5}{7}\or
        \def\aep@btn@anime@controls{\btnAnimeSkiniii}%
            \aepnumWidgetsFirstRow{3}{5}\or
        \def\aep@btn@anime@controls{\btnAnimeSkiniv}%
            \aepnumWidgetsFirstRow{4}{4}\or
        \def\aep@btn@anime@controls{\btnAnimeSkinv}%
            \numWidgetsFirstRowV\or
        \def\aep@btn@anime@controls{\btnAnimeSkinvi}%
            \numWidgetsFirstRowVI\fi
    }{}
%    \end{macrocode}
% The \texttt{usetworows}\IndexKey{usetworows} and
% \texttt{nospeedcontrol}\IndexKey{nospeedcontrol} key
%    \begin{macrocode}
\define@boolkey{btnAnime}{usetworows}[true]{}
\define@boolkey{btnAnime}{nospeedcontrol}[true]{}
%    \end{macrocode}
% Set the defaults for button animation.
%    \begin{macrocode}
\setkeys{btnAnime}{fieldName,iconName,speed,nFrames,type,poster,
    controls,usetworows=false,nospeedcontrol=false,ctrlwidth,ctrlheight,
    ctrlbdrywidth,ctrlbdrycolor}
%    \end{macrocode}
%    \begin{macrocode}
\newcommand{\btnAnimePresets}[1]{\def\aeb@btnAnimePresets{#1}}
\def\aeb@btnAnimePresets{}
%    \end{macrocode}
%    \begin{macro}{\ctrlButtonsWrapper}
% The \cs{ctrlButtonsWrapper} command takes one argument, and that is
% \cs{in\-sert\-Ctrl\-But\-tons}. Redefine this command to, for example, place
% a \cs{colorbox} around the button set,
%\begin{verbatim}
%   \renewcommand\ctrlButtonsWrapper}[1]{\colorbox{red}{#1}}
%\end{verbatim}
% The default definition is\dots
%    \begin{macrocode}
\newcommand{\ctrlButtonsWrapper}[1]{#1}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% End animecommon segment
%</animecommon>
%<*btnanime>
%    \end{macrocode}
% \subsubsection{Define \texorpdfstring{\cs{btnAnime}}{\CMD{btnAnime}}}
%    \begin{macro}{\btnAnime}
% The command \cs{btnAnime} supplies basic animation support using buttons.
% The command \cs{btnAnime} assumes the images are embedded in the document using
% \cs{embedMultiPageImages}, icon images for the controls are supplied by
% \cs{placeAnimeCtrlBtnFaces}.
%    \begin{macrocode}
\newcommand{\btnAnime}[3]{\begingroup\animeSetup{#1}%
    \ifx\animeBtnFieldName\@empty\PackageError{aeb_pro}%
        {The fieldName key is required}{}\fi
    \ifx\animeBtnBaseName\@empty\PackageError{aeb_pro}%
        {The iconName key is required}{}\fi
    \ifx\nFrames\@empty\PackageError{aeb_pro}%
        {The nFrames key is required}{}\fi
    \parbox[t][#3]{#2}{%
%    \end{macrocode}
% Set the properties of the pushbutton to be created.
%    \begin{macrocode}
        \everyPushButton{\BC{}\BG{}\S{S}\autoCenter{n}\FB{true}\TP{1}%
        \Ff{\FfReadOnly}\presets{\aeb@btnAnimePresets}\I{null}}%
%    \end{macrocode}
% Set the options for the first frame, it is either visible if \texttt{poster=first}
% or hidden, otherwise.
%    \begin{macrocode}
        \edef\termLoop{\nFrames}\edef\firstBtnOpts{%
        \ifnum\aebp@btnAnime@poster=0 \else\noexpand\F{\FHidden}\fi
        \noexpand\AA{\ifKV@btnAnime@autorun
            \aebp@autoplayevent{\noexpand\btnAnimePFAction}\fi
        \ifKV@btnAnime@autopause
            \aebp@autopauseevent{\noexpand\btnAnimePauseAction}\fi}}%
%    \end{macrocode}
% Begin with the first button.
%    \begin{macrocode}
        \makebox[0pt][l]{\expandafter\pushButton
            \expandafter[\firstBtnOpts]{\animeBtnFieldName.0}{#2}{#3}}%
%    \end{macrocode}
% If \texttt{poster=last}, decrement \cs{termLoop} by one.
%    \begin{macrocode}
        \ifnum\aebp@btnAnime@poster=1
        \count0=\nFrames\relax\advance\count0by-1
        \edef\termLoop{\the\count0}\fi\@tempcnta=1
%    \end{macrocode}
% Begin to `stack' the buttons (first button already in place)
%    \begin{macrocode}
        \loop\ifnum\@tempcnta<\termLoop\relax
        \makebox[0pt][l]{\pushButton[\F{\FHidden}]{%
        \animeBtnFieldName.\the\@tempcnta}{#2}{#3}}%
        \advance\@tempcnta1\relax\repeat
%    \end{macrocode}
% Finished with the look, if \texttt{poster=last}, then we did  not stack
% the last button, we do it now.
%    \begin{macrocode}
        \ifnum\aebp@btnAnime@poster=1\relax\makebox[0pt][l]{%
            \pushButton{\animeBtnFieldName.\termLoop}{#2}{#3}}%
        \fi\hfill\ifx\aep@btn@anime@controls\@empty\else
        \offinterlineskip\vcgBdry[\vspacectrlsep]%
%    \end{macrocode}
% Now build the control buttons
%    \begin{macrocode}
        \everyPushButton{}\centering
        \ctrlButtonsWrapper{\insertCtrlButtons}\fi
    }%parbox
    \endgroup
}
%    \end{macrocode}
%    \end{macro}
%    \begin{macrocode}
% End btnanime segment
%</btnanime>
%<*ocganime>
%    \end{macrocode}
% \subsubsection{Define \texttt{ocgAnime}}
%    \begin{environment}{ocgAnime}
% We upgrade the ocg animation to the same level of button animation. We define the
% \texttt{ocgAnime} environment. Between he \verb!\begin{ocgAnime}! and \verb!\end{ocgAnime}!,
% place the code for creating the animation. The only required parameters consist of the same
% key-value pairs accepted by \cs{btnAnime}. Some keys are not used, such as \texttt{iconName}.
% The fields \texttt{ocgAnimeName} and \texttt{nFrames} are required.
%    \begin{macrocode}
\newenvironment{ocgAnime}[1]{\animeSetup{#1}%
    \ifx\animeBtnFieldName\@empty\PackageError{aeb_pro}%
        {The ocgAnimeName key is required}{}\fi
    \ifx\nFrames\@empty\PackageError{aeb_pro}%
        {The nFrames key is required}{}\fi
    \DeclareAnime{\animeBtnFieldName}{\animeBtnSpeed}{\nFrames}%
}{%
    \edef\aep@ExpOpts{\noexpand\AA{\ifKV@btnAnime@autorun
        \aebp@autoplayevent{\noexpand\btnAnimePFAction}\fi
        \ifKV@btnAnime@autopause\aebp@autopauseevent{%
        \noexpand\btnAnimePauseAction}\fi}}\smash{\makebox[0pt][l]%
   {\expandafter\pushButton\expandafter[\aep@ExpOpts\W0\BC{}\BG{}\S{S}]%
   {\animeBtnFieldName-autorunpause}{0bp}{0bp}}}%
   \ifx\aep@btn@anime@controls\@empty\else\offinterlineskip
        \vcgBdry[\vspacectrlsep]\everyPushButton{}%
        \centering\ctrlButtonsWrapper{\insertCtrlButtons}\fi
}
%    \end{macrocode}
%    \end{environment}
%    \begin{macrocode}
% End of ocganime segment
%</ocganime>
%<*animecommon>
%    \end{macrocode}
%    \begin{macro}{\btnAnimeCtrlPresets}
% Use \cs{btnAnimeCtrlPresets} to set the appearances for all these buttons below.
%    \begin{macro}{\btnAnimeGoToFirst}
%    \begin{macro}{\btnAnimeStepBack}
%    \begin{macro}{\btnAnimePlayBack}
%    \begin{macro}{\btnAnimePause}
%    \begin{macro}{\btnAnimePlayForward}
%    \begin{macro}{\btnAnimeStepForward}
%    \begin{macro}{\btnAnimeGoToLast}
%    \begin{macro}{\btnAnimePlus}
%    \begin{macro}{\btnAnimeMinus}
% The control buttons for button anime. These commands are not normally used by
% the document author, but can be used for a custom layout.
%    \begin{macrocode}
\newcommand{\btnAnimeCtrlPresets}[1]{\def\aeb@btnAnimeCtrlPresets{#1}}
\def\aeb@btnAnimeCtrlPresets{}
\newcommand{\btnAnimeGoToFirst}{%
    \pushButton[\TU{Go to first frame}\S{S}\BC{}
        \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimeFirstAction}}]%
        {\animeBtnFieldName4BtnCtrl.animeFirst}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}%
\newcommand{\btnAnimeStepBack}{%
    \pushButton[\TU{Step Back}\S{S}\BC{}
        \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimeSBAction}}]%
        {\animeBtnFieldName4BtnCtrl.animeSB}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
\newcommand{\btnAnimePlayBack}{%
    \pushButton[\TU{Play Backwards}\S{S}\BC{}
        \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimePBAction}}]%
        {\animeBtnFieldName4BtnCtrl.animePB}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
\newcommand{\btnAnimePause}{%
    \pushButton[\TU{Pause}\S{S}\BC{}
        \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimePauseAction}}]%
        {\animeBtnFieldName4BtnCtrl.animePause}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
\newcommand{\btnAnimePlayForward}{%
    \pushButton[\TU{Play Forwards}\S{S}\BC{}
        \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimePFAction}}]%
        {\animeBtnFieldName4BtnCtrl.animePF}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
\newcommand{\btnAnimeStepForward}{%
    \pushButton[\TU{Step Forward}\S{S}\BC{}
        \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimeSFAction}}]%
        {\animeBtnFieldName4BtnCtrl.animeSF}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
\newcommand{\btnAnimeGoToLast}{%
    \pushButton[\TU{Go to last frame}\S{S}\BC{}
        \FB{false}\I{null}\TP{1}\presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimeLastAction}}]%
        {\animeBtnFieldName4BtnCtrl.animeLast}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
% These last two do not take an icon.
\newcommand{\btnAnimePlus}{%
    \pushButton[\TU{Increase speed\r Shift-click to restore
        default speed}%\textFont{HeBo}\CA{+}
        \S{S}\BC{}\FB{false}\I{null}\TP{1}
        \presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimePlusAction}}]%
        {\animeBtnFieldName4BtnCtrl.animePlus}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
\newcommand{\btnAnimeMinus}{%
    \pushButton[\TU{Decrease speed\r Shift-click to restore
        default speed}%\textFont{HeBo}\uCA{FEFF2212}
        \S{S}\BC{}\FB{false}\I{null}\TP{1}
        \presets{\aeb@btnAnimeCtrlPresets}
        \presets{\animeSetupPresets}\A{\JS{\btnAnimeMinusAction}}]%
        {\animeBtnFieldName4BtnCtrl.animeMinus}%
        {\btnAnimeCtrlW}{\btnAnimeCtrlH}}
%    \end{macrocode}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
%    \end{macro}
% The following are the field events for the controls for \cs{btnAnime}
% and \texttt{acgAnime}.
%    \begin{macrocode}
\newcommand{\btnAnimeFirstAction}{%
if (typeof \animeBtnFieldName\space == "object")\r\t
        btnAnimeFirst(\animeBtnFieldName);
}
\newcommand{\btnAnimeSBAction}{%
    if ( typeof \animeBtnFieldName\space=="undefined")\r\t
        var \animeBtnFieldName= new Object();\r
        btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",%
            "\animeBtnBaseName",\animeBtnSpeed,\nFrames,false,%
            \aebp@btnAnime@type,true);
}
\newcommand{\btnAnimePBAction}{%
    if ( typeof \animeBtnFieldName\space=="undefined")\r\t
        var \animeBtnFieldName= new Object();\r
        btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",%
            "\animeBtnBaseName",\animeBtnSpeed,\nFrames,false,%
            \aebp@btnAnime@type,false);
}
\newcommand{\btnAnimePauseAction}{%
    if ((typeof \animeBtnFieldName\space == "object")&&%
        \animeBtnFieldName.animeStart)\r\t
        btnAnimePause(\animeBtnFieldName);
}
\newcommand{\btnAnimePFAction}{%
    if ( typeof \animeBtnFieldName\space=="undefined")\r\t
        var \animeBtnFieldName= new Object();\r
    btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",%
        "\animeBtnBaseName",\animeBtnSpeed,\nFrames,true,%
        \aebp@btnAnime@type,false);
}
\newcommand{\btnAnimeSFAction}{%
    if ( typeof \animeBtnFieldName\space=="undefined")\r\t
        var \animeBtnFieldName= new Object();\r
    btnAnimePlay(\animeBtnFieldName,"\animeBtnFieldName",%
        "\animeBtnBaseName",\animeBtnSpeed,\nFrames,true,%
        \aebp@btnAnime@type,true);
}
\newcommand{\btnAnimeLastAction}{%
    if (typeof \animeBtnFieldName\space == "object")\r\t
            btnAnimeLast(\animeBtnFieldName);
}
\newcommand{\btnAnimePlusAction}{%
    if (typeof \animeBtnFieldName\space == "object")\r\t
            btnAnimePlus(\animeBtnFieldName,\animeBtnSpeed);
}
\newcommand{\btnAnimeMinusAction}{%
    if (typeof \animeBtnFieldName\space == "object")\r\t
            btnAnimeMinus(\animeBtnFieldName,\animeBtnSpeed);
}
%    \end{macrocode}
% The supporting JavaScript. This set of JavaScript functions support both button anime and
% ocg anime (the \cs{btnAnime} command and the \texttt{ocgAnime} environment).
%    \begin{macrocode}
\begin{insDLJS}[_loadBtnAnimeCtrls]{btnanime}
    {AeB Pro: Button and Ocg Anime Controls}
var _loadBtnAnimeCtrls=true;
var activeAnimes=new Array();
%    \end{macrocode}
% This function may be called with a single argument \texttt{oAnime}
% when the anime is playing.
%    \begin{macrocode}
function btnAnimePlay(oAnime,fieldName,baseFrameName,%
nSpeed,nFrames,bForward,type,bStep) {
    // ocgAnime is characterized by baseFrameName=""
    if ( oAnime.animeStart && !oAnime.animePause ) return;
    var callingFieldName=event.target.name;
    var re=/\.anime(PB|PF)/;
    var doRebuild=( event.shift && re.test(callingFieldName) );
    if ( (arguments.length>1) && %
( (typeof activeAnimes[fieldName] == "undefined")|| doRebuild) ) {
        activeAnimes[fieldName]=oAnime;
        oAnime.isOcgAnime=(baseFrameName==""); // ocg change
        oAnime.fieldName=fieldName;
        oAnime.baseFrameName=baseFrameName;
        oAnime.numSecs=nSpeed;
        oAnime.nFrames=nFrames;
        oAnime.type=type;
        oAnime.bStep=bStep;
        oAnime.aMyIcons = new Array();
        oAnime.count = 0;
        if ( !oAnime.isOcgAnime ) {// ocg change
            for ( var i=0; i < nFrames; i++) {
                oAnime.aMyIcons[i] = this.getField(fieldName+"."+i);
%    \end{macrocode}
% (2015/08/09) When starting for the first time, be sure initial frame
% showing is the first frame 0.
%    \begin{macrocode}
                oAnime.aMyIcons[i].display=(i==0)?display.visible:%
display.hidden;
            }
        }
    }
    if (arguments.length>1) {
        oAnime.bForward=bForward;
        oAnime.bStep=bStep;
    }
%    \end{macrocode}
% \texttt{type}: \texttt{loop}(0), \texttt{palindrome}(1), \texttt{stopatboundary}(2)
%    \begin{macrocode}
    if (oAnime.bStep) {
        this.delay=true
        if ( oAnime.isOcgAnime ) // ocg change
            getxBld("anime!!"+oAnime.fieldName+"\#"%
+(oAnime.count+1)).state=false; // ocg
        else
            oAnime.aMyIcons[oAnime.count].display=display.hidden;
        var currCount=oAnime.count;
        if (oAnime.bForward) {
                oAnime.count++;
                if (oAnime.count==oAnime.nFrames) // hit upper boundary
                    oAnime.count=(oAnime.type==0)?0:currCount;
        } else {
            oAnime.count--;
            if (oAnime.count<0)
                oAnime.count=(oAnime.type==0)?(oAnime.nFrames-1):0;
        }
        if ( oAnime.isOcgAnime ) // ocg change
            getxBld("anime!!"+oAnime.fieldName+"\#"%
+(oAnime.count+1)).state=true; // ocg
        else
            oAnime.aMyIcons[oAnime.count].display=display.visible;
        this.delay=false;
    } else {
        var args="\""+oAnime.fieldName+"\","+oAnime.type;
        oAnime.run = app.setInterval(%
"btnAnimeNewFrame("+args+")",oAnime.numSecs);
        oAnime.animeStart=true;
        oAnime.animePause=false;
    }
}
function btnAnimeFirst(oAnime)
{
    try { app.clearInterval(oAnime.run);} catch(e){}
    oAnime.animeStart=false;
    oAnime.animePause=false;
    if ( oAnime.isOcgAnime )
        getxBld("anime!!"+oAnime.fieldName+"\#"%
+(oAnime.count+1)).state=false; // ocg
    else
        oAnime.aMyIcons[oAnime.count].display=display.hidden;
    oAnime.count=0;
    if ( oAnime.isOcgAnime )
        getxBld("anime!!"+oAnime.fieldName+"\#"%
+(oAnime.count+1)).state=true; // ocg
    else
        oAnime.aMyIcons[0].display=display.visible;
}
function btnAnimeLast(oAnime)
{
    try { app.clearInterval(oAnime.run);} catch(e){}
    oAnime.animeStart=false;
    oAnime.animePause=false;
    var l = oAnime.nFrames-1;
    if ( oAnime.isOcgAnime )
            getxBld("anime!!"+oAnime.fieldName+"\#"%
+(oAnime.count+1)).state=false; // ocg
    else
        oAnime.aMyIcons[oAnime.count].display=display.hidden;
    oAnime.count=l;
    if ( oAnime.isOcgAnime )
            getxBld("anime!!"+oAnime.fieldName+"\#"%
+(l+1)).state=true; // ocg
    else
        oAnime.aMyIcons[l].display=display.visible;
}
function btnAnimePause(oAnime)
{
    try { app.clearInterval(oAnime.run);} catch(e){}
    oAnime.animePause=true;
}
function btnAnimePlus(oAnime,nDefSpeed){
    var isPlaying=(oAnime.animeStart&&!oAnime.animePause);
    if (isPlaying) btnAnimePause(oAnime);
    if ( event.shift ) oAnime.numSecs=nDefSpeed;
    else oAnime.numSecs -= 50;
    if (oAnime.numSecs<10) oAnime.numSecs=10
    if (isPlaying) btnAnimePlay(oAnime);
}
function btnAnimeMinus(oAnime,nDefSpeed){
    var isPlaying=(oAnime.animeStart&&!oAnime.animePause);
    if (isPlaying) btnAnimePause(oAnime);
    if ( event.shift ) oAnime.numSecs=nDefSpeed;
    else oAnime.numSecs += 50;
    if (isPlaying) btnAnimePlay(oAnime);
}
function btnAnimeNewFrame(fieldName, type)
{
%    \end{macrocode}
% \texttt{type=0,2,3}: \texttt{loop}(0), \texttt{palindrome}(1), \texttt{stopatboundary}(2)
%    \begin{macrocode}
    var oAnime=activeAnimes[fieldName];
    this.delay=true
    if ( oAnime.isOcgAnime ) // ocg change
        getxBld("anime!!"+oAnime.fieldName+"\#"%
+(oAnime.count+1)).state=false;
    else
        oAnime.aMyIcons[oAnime.count].display=display.hidden;
    var currCount=oAnime.count;
    var bBdaryMet=false;
    if (oAnime.bForward) {
        oAnime.count++;
        if (oAnime.count==oAnime.nFrames) {
            if(type==0) oAnime.count \%= oAnime.nFrames;
            else if(type==1) {
                    oAnime.count=currCount;
                    oAnime.count--;
                    oAnime.bForward=false;
                } else {
                    bBdaryMet=true;
                    oAnime.count=currCount;
                }
        }
    } else {
        oAnime.count--;
        if (oAnime.count<0) {
            if(type==0) oAnime.count=(oAnime.nFrames-1);
            else if(type==1) {
                    oAnime.count=currCount;
                    oAnime.count++;
                    oAnime.bForward=true;
                } else { // stop
                    bBdaryMet=true;
                    oAnime.count=currCount;
                }
        }
    }
    if ( oAnime.isOcgAnime) // ocg change
        getxBld("anime!!"+oAnime.fieldName+"\#"%
+(oAnime.count+1)).state=true;
    else
        oAnime.aMyIcons[oAnime.count].display=display.visible;
    this.delay=false;
    if ( type==2 && bBdaryMet ) {
        try { app.clearInterval(oAnime.run);} catch(e){}
        // try { app.clearTimeOut(timeout);} catch(e){}
        oAnime.animeStart=false;
        oAnime.animePause=false;
    }
}
\end{insDLJS}
%    \end{macrocode}
%    \begin{macrocode}
% End of animecommon segment
%</animecommon>
%    \end{macrocode}
%    \begin{macrocode}
% Begin package segment
%<*package>
\ap@restoreCats
%</package>
%    \end{macrocode}
%  \Finale
\endinput
