summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/eq-pin2corr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-02-21 03:01:41 +0000
committerNorbert Preining <norbert@preining.info>2021-02-21 03:01:41 +0000
commitf35565737733e319e7293a9fafe1b78e87f8a14e (patch)
tree197b08b39b09262f4e71486f610106580871631d /macros/latex/contrib/eq-pin2corr
parentb94dba90d83866ccb6db5273d214512e859c3179 (diff)
CTAN sync 202102210301
Diffstat (limited to 'macros/latex/contrib/eq-pin2corr')
-rw-r--r--macros/latex/contrib/eq-pin2corr/README.md19
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdfbin0 -> 256673 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdfbin0 -> 245015 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex423
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.pdfbin0 -> 237391 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.tex312
-rw-r--r--macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx281
-rw-r--r--macros/latex/contrib/eq-pin2corr/eq-pin2corr.ins60
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdfbin0 -> 83433 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex52
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdfbin0 -> 171609 bytes
-rw-r--r--macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.tex99
12 files changed, 1246 insertions, 0 deletions
diff --git a/macros/latex/contrib/eq-pin2corr/README.md b/macros/latex/contrib/eq-pin2corr/README.md
new file mode 100644
index 0000000000..78c08c4d5f
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/README.md
@@ -0,0 +1,19 @@
+The eq-pin2corr package
+Author: D. P. Story
+Dated: 2021-02-20
+
+This package is an add-on to the quiz environment of the exerquiz
+package (part of the acrotex bundle). It adds PIN security to a quiz created by
+the quiz environment. To correct a quiz, the document consumer must
+press the Correct button of the quiz and successfully enter the correct
+PIN number. The PIN security is designed for the instructor to mark and record
+the students effort on that quiz.
+
+The package works for a the usual workflows
+
+D. P. Story
+www.acrotex.net
+blog.acrotex.net
+dpstory@uakron.edu
+dpstory@acrotex.net
+
diff --git a/macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdf b/macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdf
new file mode 100644
index 0000000000..92c3cec32b
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/doc/eq-pin2corr.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdf b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdf
new file mode 100644
index 0000000000..0103c028ca
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex
new file mode 100644
index 0000000000..aa2f13dbc9
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/doc/eqpin2corrman.tex
@@ -0,0 +1,423 @@
+%
+% Need some discussion on workflow
+%
+% makeindex < aebpro_man.idx > aebpro_man.ind
+\RequirePackage[!use=preview,!use=usebw]{spdef}
+\documentclass[10pt]{article}
+\usepackage[fleqn]{amsmath}
+%\usepackage{hyperref}
+\usepackage[
+ web={centertitlepage,designv,forcolorpaper,latextoc,pro},
+ exerquiz,
+% linktoattachments,
+ aebxmp
+]{aeb_pro}
+\usepackage[!showscore]{eq-pin2corr}
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+\useMCCircles
+
+\declPINId{5243}{02JRVZdRgYgCA-Rtje8VkD} % PIN number, hash string
+%\classPINVar{_PinCode1}
+
+
+%\usepackage{booktabs}
+%\usepackage{aeb_mlink}
+%\usepackage{eq-pin2corr}
+%\usepackage{graphicx,array}
+%\usepackage{ifthen}
+%\usepackage{myriadpro}
+%\usepackage{calibri}
+
+\usepackage[altbullet]{lucidbry}
+
+%\usepackage{xbmks}
+%\DeclareInitView{layoutmag={navitab:UseOutlines}}
+
+%\xbmksetup{colors={int=red},styles={intbf}}
+
+\addtolength{\marginparwidth}{20pt}
+
+%\previewtrue
+%\usepackage{makeidx}
+%\makeindex
+\usepackage{acroman}
+\usepackage[active]{srcltx}
+
+\setcounter{secnumdepth}{5}
+\setcounter{tocdepth}{5}
+\makeatletter
+\renewcommand*{\thesubsubsection}{\texorpdfstring{$\bullet$}{\textbullet}}
+\renewcommand*{\theparagraph}{\texorpdfstring{\protect\P}{\textparagraph}}
+\renewcommand*{\thesubparagraph}{\texorpdfstring{\protect\P\protect\P}{\textparagraph\textparagraph}}
+\renewcommand{\paragraph}
+ {\renewcommand{\@seccntformat}[1]{\theparagraph\space}%
+ \@startsection{paragraph}{4}{0pt}{6pt}{-3pt}{\bfseries}}
+\renewcommand*\l@paragraph{\@dottedtocline{4}{5.0em}{1em}} %{7.0em}{4.1em}}
+\renewcommand{\subparagraph}
+ {\renewcommand{\@seccntformat}[1]{\thesubparagraph\space}%
+ \@startsection{subparagraph}{5}{\parindent}{6pt}{-3pt}{\bfseries}}
+\def\dps{$\mbox{$\mathfrak D$\kern-.3em\mbox{$\mathfrak P$}%
+ \kern-.6em \hbox{$\mathcal S$}}$}
+
+\newenvironment{aebQuote}
+ {\list{}{\leftmargin\amtIndent}%
+ \item\relax}{\endlist}
+\def\parboxValign{t}
+\newcommand{\FmtMP}[2][0pt]{\mbox{}\marginpar{%
+ \raisebox{.5\baselineskip+#1}{%
+ \expandafter\parbox\expandafter[\parboxValign]%
+ {\marginparwidth}{\aebbkFmtMp#2}}}}
+\def\aebbkFmtMp{\kern0pt\itshape\small
+ \ifusebw\color{gray}\else\color{blue}\fi
+ \raggedleft\hspace{0pt}}\newcommand{\BlogArticle}{%
+ \makebox[0pt][l]{\hspace{-1pt}\color{blue}\Pisymbol{webd}{254}%
+ }\raisebox{.5pt}{\ifusebw\color{black}\else
+ \color{red}\fi\ding{045}}}
+\def\dps{$\mbox{$\mathfrak D$\kern-.3em\mbox{$\mathfrak P$}%
+ \kern-.6em \hbox{$\mathcal S$}}$}
+
+\def\chgCurrLblName#1{\def\@currentlabelname{#1}}
+\def\echgCurrLblName#1{\edef\@currentlabelname{#1}}
+\let\db\@gobble
+
+%\newenvironment{aebQuote}
+% {\list{}{\leftmargin\amtIndent}%
+% \item\relax}
+% {\endlist}
+
+\makeatother
+
+%\getDimsFromGraphic{graphics/dpsweb}{\dpswebW}{\dpswebH}
+
+
+%\urlstyle{rm}
+\urlstyle{sf}
+\let\uif\textsf
+\let\app\textsf
+\def\psf#1{\textbf{\textsf{#1}}}
+%\let\amtIndent\leftmargini
+\edef\amtIndent{\the\parindent}
+
+\renewcommand*\descriptionlabel[1]{\hspace\labelsep
+ \normalfont #1}
+
+\let\tops\texorpdfstring
+
+\DeclareDocInfo
+{
+ university={Acro\negthinspace\TeX.Net},
+ title={The \textsf{eq-pin2corr} package\tops{\\}{: } Apply PIN security to quizzes},
+ author={D. P. Story},
+ email={dpstory@acrotex.net},
+ subject={Documentation for the eq-pin2corr package from AcroTeX: Apply PIN security to quizzes},
+ talksite={\url{www.acrotex.net}},
+ version={0.5, 2021/15/06},
+ Keywords={AcroTeX, mini-toc},
+ copyrightStatus=True,
+ copyrightNotice={Copyright (C) \the\year, D. P. Story},
+ copyrightInfoURL={http://www.acrotex.net}
+}
+
+\def\dps{$\hbox{$\mathfrak D$\kern-.3em\hbox{$\mathfrak P$}%
+ \kern-.6em \hbox{$\mathcal S$}}$}
+
+\universityLayout{fontsize=Large}
+\titleLayout{fontsize=LARGE}
+\authorLayout{fontsize=Large}
+\tocLayout{fontsize=Large,color=aeb}
+\sectionLayout{indent=-62.5pt,fontsize=large,color=aeb}
+\subsectionLayout{indent=-31.25pt,color=aeb}
+\subsubsectionLayout{indent=0pt,color=aeb}
+\subsubDefaultDing{\tops{$\bullet$}{\textbullet}}
+
+\widestNumber{0.00.}
+%\pagestyle{empty}
+%\parindent0pt\parskip\medskipamount
+
+\begin{defineJS}{\btnAct}
+ var resp=app.response({
+ cQuestion: "Enter a PIN number",
+ cTitle: "Get Hash String"
+ });
+ if (resp != null) {
+ var f=this.getField("txt");
+ f.value=Collab.hashString(resp);
+ }
+\end{defineJS}
+
+
+\frenchspacing
+
+\chngDocObjectTo{\newDO}{doc}
+\begin{docassembly}
+var titleOfManual="The eq-pin2corr package MANUAL";
+var manualfilename="Manual_BG_Print_pin2corr.pdf";
+var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown
+var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate;
+var doc;
+var buildIt=false;
+if ( buildIt ) {
+ console.println("Creating new " + manualfilename + " file.");
+ doc = \appopenDoc({cPath: _pathToBlank, bHidden: true});
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ _path=_path.substring(0,pos)+"/"+manualfilename;
+ \docSaveAs\newDO ({ cPath: _path });
+ doc.closeDoc();
+ doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true});
+ f=doc.getField("ManualTitle");
+ f.value=titleOfManual;
+ doc.flattenPages();
+ \docSaveAs\newDO({ cPath: manualfilename });
+ doc.closeDoc();
+} else {
+ console.println("Using the current "+manualfilename+" file.");
+}
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+_path=_path.substring(0,pos)+"/"+manualfilename;
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\maketitle
+
+
+\selectColors{linkColor=black}
+\tableofcontents
+\selectColors{linkColor=webgreen}
+
+\def\AcroT{Acro\!\TeX}\def\cAcroT{\textcolor{blue}{\AcroT}}
+\def\AcroEB{\AcroT{} eDucation Bundle}\def\cAcroEB{\textcolor{blue}{\AcroEB}}
+\def\AcroB{\AcroT{} Bundle}\def\cAcroB{\textcolor{blue}{\AcroB}}
+\def\bUrl{http://www.math.uakron.edu/~dpstory}
+
+\hypersetup{linktocpage}
+
+\section{Introduction}
+
+This package is an add-on to the \env{quiz} environment of the \pkg{exerquiz}
+package.
+
+\paragraph*{Purpose.} This package adds PIN security to a quiz created by
+ the \env{quiz} environment. To correct a quiz, the document consumer must
+press the \uif{Correct} button of a quiz and successfully enter the correct
+PIN number. For example,
+
+\usePINCorrBtn
+
+\begin{quiz*}{qz1}
+Solve each, passing is 100\%.\hfill\llap{\smash{\parbox[t]{145pt}{\leavevmode\llap{\color{red}\ding{042}\enspace}Take the quiz, when finished, press the \uif{Correct} button and enter the PIN number
+to correct the quiz.}}}
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry[1bp]
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\ScoreField[\rectW{2.25in}]\currQuiz\olBdry\CorrButton{\currQuiz} (PIN: \numPINId)\vcgBdry[6pt]
+
+Answers: \AnswerField\currQuiz\vcgBdry[6pt]
+
+ This package is designed for the educational sector, for instructors who use
+ the quizzes from the \pkg{exerquiz} package to assess the
+ understanding their students of the course material.
+
+ \paragraph*{PDF Viewers.} Discussion of PDF viewers for the document author and the document consumer.
+ \begin{aebQuote}
+ \begin{description}
+ \item[\textbf{Instructor:}] Any PDF viewer may be used as a PDF
+ \emph{previewer}, \app{sumatraPDF}, for instance. To verify the newly
+ created quiz is functioning correctly, \app{Adobe Reader DC}
+ (\FmtMP{\app{AR}}\app{AR}) or \app{Acrobat DC}
+ (\FmtMP{\app{AA}}\app{AA}) \emph{must be used}.
+ \item[\textbf{Document consumers (students):}] The \pkg{exerquiz} and
+ \pkg{eq-pin2tocorr} extensively use JavaScript to perform many
+ background tasks. For the student to have any success in this
+ workflow, he/she must use \app{Adobe Reader DC}(\FmtMP{\app{AR}}\app{AR}).
+ \end{description}
+ \end{aebQuote}
+ \paragraph*{Workflow.} The package is designed for the following workflow:\begingroup\tightsettings
+ \begin{enumerate}
+ \item The instructor creates\FmtMP{create quiz} the quiz using the
+ \pkg{exerquiz} and \pkg{eq-pin2corr} packages.
+ \item The instructor delivers\FmtMP{deliver quiz} the ``PDF quiz'' to
+ each student. (System drive or email)
+ \item The student takes\FmtMP{take quiz} the quiz. The student can
+ press the \uif{Correct} but, unless s/he knows the PIN, the quiz
+ is not marked up.
+ \item The student saves\FmtMP{save quiz} the PDF quiz in \app{Adobe
+ Reader DC}.
+ \item The student returns\FmtMP{return quiz} the PDF to the
+ instructor. (System drive or email)
+ \item The instructor opens the returned PDF quiz in AA/AR and
+ presses\FmtMP{correct quiz} the \uif{Correct} button to mark up
+ the quiz. The instructor \emph{saves the quiz}. The instructor
+ records the grade of the student.
+ \item The instructor returns\FmtMP{returns quiz} the PDF, at some
+ point, to the student.
+ \item Both instructor and student happily\FmtMP{happy people} go on
+ with their lives.
+ \end{enumerate}
+ The implementation details are left to the instructor.
+\endgroup
+
+\paragraph*{Document creation.} Any of the PDF creators current to the
+{\LaTeX} world can be used: (1) \app{pdflatex}, (2) \app{lualatex}, (3)
+\app{xelatex}, and my old friend, (4) \app{dvips}/\app{Distiller} (or
+\app{dvips}/\app{ps2pdf}). In the latter case (4), \app{Acrobat} is required
+to import Document JavaScripts.
+
+\section{The preamble}
+
+The minimal preamble for documents that use the \pkg{eq-pin2corr} package.
+\bVerb\def\1{\rlap{\hskip150pt\%\textsf{ or some other class}}}%
+\def\2{\rlap{\hskip150pt\%\textsf{ recommended but not required}}}%
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+!1\documentclass{article}
+!2\usepackage[!ameta(options)]{web}
+\usepackage[!ameta(options)]{exerquiz}!textbf([2021/02/17])
+\usepackage[!ameta(options)]{eq-pin2corr}
+...
+\declPINId{!ameta(pin-num)}{!ameta(hash-string)}
+\classPINVar{!ameta(class-pin-var)}
+...
+\begin{document}
+\end{Verbatim}
+\eVerb A recent version of \pkg{exerquiz} (2021/02/17 or later) is required;
+\pkg{eq-pin2corr} brings in the \pkg{eq-save} package (2021/02/17 or later).
+
+\section{Package options}
+
+There are two options for this package: \opt{showscore} and \opt{!showscore}.
+If you took the test on page~3, you will have noticed that when \uif{End
+Quiz} control is pressed the phase \textsf{"Success! Now save and send to the
+instructor"} appears in the \cs{ScoreField} or the \cs{PointsField}, this is
+the default behavior. Passing \FmtMP{\opt{showscore}}\opt{showscore} in the
+optional argument list of \pkg{eq-key2corr} causes the actual score to appear
+in the same box (eg, \texttt{Score: 2 out of 3}), which is historically what
+always appears in these boxes. The other option \FmtMP{\opt{!showscore}}\opt{!showscore} is a
+convenience option to aid in switching from one option to the other without
+too much cut and paste. The default definition of the text string that
+appears is,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small]
+\flJSStr[noquotes]{\SaveAndSendMsg}{Success! %
+Now save and send to the instructor}
+\end{Verbatim}
+Refer to the \texttt{eformsman.pdf} for a discussion of \cs{flJSStr}.
+
+\paragraph*{Local controls.} The two options can be turned off and on locally with \FmtMP{\cs{showScoreOff}}\cs{showScoreOff} and
+\FmtMP{\cs{showScoreOn}}\cs{showScoreOn} commands.
+
+\section{Setting the pin-hash values}
+
+In the preamble, as indicated above, are two commands, the first is required,
+the second is optional.
+\bVerb\takeMeasure{\string\declPINId\darg{\ameta{pin-num}}\darg{\ameta{hash-string}}}%
+%\setlength{\dimen0}{\wd\webtempboxi+2\fboxsep+2\fboxrule}%
+\def\1{\rlap{\sffamily\hskip\linewidth(optional)}}
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\declPINId{!ameta(pin-num)}{!ameta(hash-string)}
+!1\classPINVar{!ameta(class-pin-var)}
+\end{dCmd}
+\eVerb It is through the \cs{declPINId} command that the PIN security is set up.
+
+\paragraph*{\cs{declPINId\darg{\ameta{pin-num}}\darg{\ameta{hash-string}}}} The \ameta{pin-num} is a number, perhaps four digits,
+that is used to pass through the security of the \uif{Correct} button.\footnote{The \ameta{pin-num} does not have to be a number,
+it can be any password (passcode) that is easy to remember. I prefer a four digit number.} Once you decide on the
+PIN number, you need to generate the corresponding \emph{hash-string}. The hash-string is obtained from the demo file
+\texttt{get-hash-string.pdf}, the contents of that files is reproduced below.
+\begin{aebQuote}
+\pushButton[\CA{Push}\AAmouseup{\btnAct}]{btn}{}{11bp}\olBdry
+\textField[\textSize{8}]{txt}{2in}{11bp}\olBdry
+\pushButton[\CA{Reset}\AAmouseup{this.resetForm();}]{reset}{}{11bp}
+\end{aebQuote}
+Press the button labeled \uif{Push} and enter your PIN number into the dialog
+box (enter, for example, \texttt{\numPINId}), then press \uif{OK}, the
+corresponding hash-string appears in the text field, \texttt{\hashPINId}.
+Copy the PIN number (\texttt{\numPINId}) into the first argument of
+\cs{declPINId} and copy the hash-string (\texttt{\hashPINId}) from the text
+field into the second argument, like so,
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+\declPINId{!numPINId}{!hashPINId}
+\end{Verbatim}
+The above is placed in the preamble of the document.
+
+When the user enters a PIN number (right or wrong), it is converted to a
+hash-string and compared with the hash string of the correct PIN number; if
+they match, then the quiz is corrected. It is important to note that the PIN
+number \emph{does not appear anywhere} in the document, so it cannot be
+discovered. Knowledge of the correct hash-string does not help. Of course
+both PIN number and hash string appear in the source file of the document.
+
+\paragraph*{\cs{classPINVar\darg{\ameta{class-pin-var}}}} From the
+instructor's viewpoint, it takes a lot of effort to enter the PIN number for
+every quiz that is submitted (it may be in the hundreds). There is a way of
+avoiding the requirement of entering the PIN number, and that is through the
+use of the \cs{classPINVar} command. This method will work if you have
+\app{Adobe Acrobat} or if you only have \app{Adobe Reader DC}. The steps for
+doing this are as follows:
+\begin{enumerate}
+ \item Decide on a class PIN variable name, it can be a generic one, or one specialize to your class,
+ for example, \cs{classPINVar\darg{Calc2Sprg21}}, then declare it in the preamble:
+\begin{Verbatim}[xleftmargin=\amtIndent]
+\classPINVar{Calc2Spr21}
+\end{Verbatim}
+The value of the argument must be a valid JavaScript name.
+ \item Go to the user config.js file of AA/AR and edit that file by
+ including the following line in it,
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+var Calc2Spr21 = "!hashPINId";
+\end{Verbatim}
+where the hash string used here is the same one corresponding to the PIN
+number for the document (\texttt{\numPINId} in our example).
+\end{enumerate}
+\app{AA/AR} only reads \texttt{config.js} one time when it opens, so
+\texttt{Calc2Spr21} will not be known until the next time \app{AA/AR} is opened.
+The location of the \texttt{config.js} file is described in general in the
+file \texttt{\href{install_jsfiles.pdf}{install\_jsfiles.pdf}}, found in the \texttt{doc} folder of this
+distribution.
+
+Once the above line is placed in the \texttt{config.js} file, the instructor does not
+enter the PIN number, pressing \uif{Correct} immediately corrects the quiz.
+
+\section{Turning the PIN security feature on and off}
+
+The security PIN feature can be turned on and off through the following two
+commands.
+\bVerb\takeMeasure{\string\restoreCorrBtn}%
+\def\1{\leavevmode\rlap{\sffamily\hskip\linewidth(Turn on PIN security)}}%
+\def\2{\leavevmode\rlap{\sffamily\hskip\linewidth(Turn off PIN security)}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\usePINCorrBtn
+!2\restoreCorrBtn
+\end{dCmd}
+\eVerb These can placed anywhere outside a \env{quiz} environment. The
+commands take effect beginning at the next quiz in the document.
+
+\medbreak\noindent
+Now, I really must get back to retirement.\enspace\dps
+
+
+\end{document}
diff --git a/macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.pdf b/macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.pdf
new file mode 100644
index 0000000000..7b2d3fab78
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.tex b/macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.tex
new file mode 100644
index 0000000000..5639318335
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/doc/install_jsfiles.tex
@@ -0,0 +1,312 @@
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+%
+% the driver line is not necessary if you
+% have aebpro.cfg configured to your driver.
+%
+\usepackage[web]{aeb_pro}
+\usepackage{eforms}
+\usepackage[altbullet]{lucidbry}
+\usepackage{pifont}
+
+\usepackage{fancyvrb}
+
+\makeatletter
+\renewcommand{\paragraph}
+ {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}
+ {\normalfont\normalsize\bfseries}}
+\renewcommand{\subparagraph}
+ {\@startsection{subparagraph}{5}{\parindent}{6pt}{-3pt}%
+ {\normalfont\normalsize\bfseries}}
+\makeatother
+
+\mathindent\parindent
+
+\def\AEBP{\app{AeB Pro}}
+\def\AEB{\app{AeB}}
+\def\app#1{\textsf{#1}}
+\def\amtIndent{\parindent}
+\def\meta#1{$\langle\textit{\texttt{#1}}\rangle$}
+\def\SC#1{{\small#1}}
+\def\PDF{\SC{PDF}}
+\let\opt\texttt
+
+\def\copyGetPath{\qquad\pushButton[\TU{Copy app.getPath to console}
+\CA{getPath}\A{\JS{console.show();\r
+console.println('\\napp.getPath("user");');
+}}]{cpyGtPth}{}{11bp}}
+
+\def\copyGetPathJS{\qquad\pushButton[\TU{Copy app.getPath to console}
+\CA{getPath}\A{\JS{console.show();\r
+console.println('\\napp.getPath("user", "javascript");');
+}}]{cpyGtPthJS}{}{11bp}}
+
+%\reversemarginpar
+\def\jsSupInstr{How to install JavaScript support files}
+\title{\jsSupInstr}
+\author{D. P. Story}
+\version{1.0}
+
+\chngDocObjectTo{\newDO}{doc}
+\begin{docassembly}
+var titleOfManual="How to install JavaScript files";
+var manualfilename="Manual_BG_Print_jsfiles.pdf";
+var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown
+var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate;
+var doc;
+var buildIt=true;
+if ( buildIt ) {
+ console.println("Creating new " + manualfilename + " file.");
+ doc = \appopenDoc({cPath: _pathToBlank, bHidden: true});
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ _path=_path.substring(0,pos)+"/"+manualfilename;
+ \docSaveAs\newDO ({ cPath: _path });
+ doc.closeDoc();
+ doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true});
+ f=doc.getField("ManualTitle");
+ f.value=titleOfManual;
+ doc.flattenPages();
+ \docSaveAs\newDO({ cPath: manualfilename });
+ doc.closeDoc();
+} else {
+ console.println("Using the current "+manualfilename+" file.");
+}
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+_path=_path.substring(0,pos)+"/"+manualfilename;
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\maketitle
+
+\section{Introduction}
+
+Because some of the \app{Acrobat} JavaScript methods have security
+restrictions, they can be only executed in the console window, or as part
+of a batch sequence, or from the JavaScript folder reserved by
+\app{Acrobat} for that use. The developer (of {\LaTeX} packages or {\PDF}
+form documents) may want to use these restricted JavaScript methods as
+part of document assembly. To use the restricted methods, they must be
+called from the user JavaScript folder. The scripts are contained in a
+\SC{JS} file that \app{Acrobat} reads when it first starts up.
+
+In this article, we provide detailed steps for locating the user
+JavaScript folder. For {\AEB} and {\AEBP}, the files \texttt{aeb.js} and
+\texttt{aeb\_pro.js} are placed in the folder. Other JavaScript files may
+be placed in the folder as well, for example, the \texttt{config.js} file
+is one that is commonly used for general purposes.
+
+Before we get started, if you are using a version of \app{Acrobat} prior
+to version~8.1, you need not read any further. The security restrictions
+described below were not in effect for those versions.
+
+\section{Installing the JavaScript support files}
+
+The functionality of {\AEB} and {\AEBP} depends, to some extent, on the
+proper installation of their JavaScript support files.
+\begin{itemize}
+ \item \AEB: For authors using the $\app{dvips}+\app{Acrobat Distiller}$
+ workflow, \texttt{aeb.js} is required; this file is not used by
+ \app{pdflatex} or \app{xelatex} users.
+
+ \item \AEBP: For authors using the $\app{dvips}+\app{Acrobat
+ Distiller}$ workflow, \texttt{aeb\_pro.js} is required; for authors
+ that prefer \app{pdflatex}, \app{lualatex}, or \app{xelatex} as the
+ {\PDF} creator \emph{and who own} the \app{Acrobat} application,
+ the \texttt{aeb\_pro.js} is required with the \opt{useacrobat}
+ option of \AEBP. When using the \opt{nopro} option of \AEBP, the
+ JavaScript file \texttt{aeb\_pro.js} is not used.
+
+\end{itemize}
+The placement of the JavaScript files has changed over the years and is a
+function of the version number \meta{ver}. Start \app{Acrobat} and open the
+console debugger window by pressing \texttt{Ctrl+J} (for \app{Windows OS})
+or \texttt{Cmd+J} (for \app{Mac OS}). Now execute the code
+\texttt{app.getPath("user")} in the console window. To do this, press the
+\textsf{getPath} button provided below, which copies the necessary code to
+the console window.
+\begin{equation}
+\begin{minipage}{.8\linewidth}
+\begin{Verbatim}[commandchars={!~@}]
+app.getPath("user");!copyGetPath
+\end{Verbatim}
+\end{minipage}\label{display:getPath}
+\end{equation}
+Now, with the cursor on the line containing the script, press the
+\texttt{Ctrl+Enter} (for \app{Windows OS}) or \texttt{Cmd+Enter} (for
+\app{Mac~OS}) key. This will execute the JavaScript and return the `root'
+path to the user's application data for \app{Acrobat}.
+
+The rest of the instructions depend on your operating system,
+\app{Windows} or \app{Mac}.
+
+\subsection{For users of \app{Windows OS}}
+
+There are several cases, jump to the numbered paragraph that describes your
+version (\meta{ver}) of \app{Acrobat}.
+
+%/C/Users/D. P. Story/AppData/Roaming/Adobe/Acrobat/11.0
+%/C/Users/D. P. Story/AppData/Roaming/Adobe/Acrobat/Privileged/11.0/JavaScripts
+
+\def\Stepi{\ding{182}\enspace}
+\def\Stepii{\ding{183}\enspace}
+\def\Stepiii{\ding{184}\enspace}
+
+\paragraph*{{\Stepi}For $\boldmath\text{\meta{ver}}$, $\boldmath 8.1 \le
+\text{\meta{ver}} < 10.1.1$.} For the \app{Windows OS}, executing the script
+in display~\eqref{display:getPath} returns a string of the
+form:\footnote{This string is for \app{Windows OS} beyond \app{WinXP}.}
+\begin{equation}
+\begin{minipage}{.8\linewidth}
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/!meta(ver)
+\end{Verbatim}
+\end{minipage}\label{display:path}
+\end{equation}
+Navigate to this folder location. The correct location for the \SC{JS}
+files is in the \texttt{JavaScripts} subfolder. If the folder does not
+exist, create it. The final path for the JavaScript support files is then
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/!meta(ver)/JavaScripts
+\end{Verbatim}
+Finally, copy \texttt{aeb.js} (and \texttt{aeb\_pro.js}, if applicable)
+into this folder. Close \app{Acrobat}, the next time \app{Acrobat}
+is started, it will read in the \SC{JS} files.
+
+\paragraph*{{\Stepii}For $\boldmath\text{\meta{ver}}$, $\boldmath10.1.1 \le
+\text{\meta{ver}} < 12$.} For these versions of \app{Acrobat} security has
+have tightened up even more; the \texttt{JavaScripts} folder is now a
+subfolder of a special \texttt{Privileged} folder. Execute
+\texttt{app.getPath("user")} in the console window, as in
+display~\eqref{display:getPath}. The method brings back a string similar to
+the one in display~\eqref{display:path}. The correct path is obtained by
+simply inserting \texttt{Privileged} into the path in
+display~\eqref{display:path}, between \texttt{Acrobat} and \meta{ver}, as
+displayed below.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/!textbf(Privileged)/!meta(ver)/JavaScripts
+\end{Verbatim}
+But this is a mere description of the correct location, the path must
+exist! The path must be created, if it does not already exist.
+
+Navigate to the folder, one folder above the path shown in
+display~\eqref{display:path}, that is, navigate to,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/
+\end{Verbatim}
+If a \texttt{Privileged} folder exists, enter into it; otherwise, create
+it, then enter it.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/Privileged
+\end{Verbatim}
+Now create a folder named \meta{ver}, unless it already exists, and enter
+it. The version is always the major release \texttt{8.0}, \texttt{9.0},
+\texttt{10.0}, or \texttt{11.0}.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/Privileged/!meta(ver)
+\end{Verbatim}
+Finally, create the \texttt{JavaScript} folder, unless it already exists,
+to obtain the final path to the user folder JavaScripts:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/
+ Acrobat/Privileged/!meta(ver)/JavaScripts
+\end{Verbatim}
+Copy \texttt{aeb.js} (and \texttt{aeb\_pro.js}, if applicable) into this
+folder. Close \textsf{Acrobat}, the next time \textsf{Acrobat} is started,
+it will read in the \SC{JS} files.
+
+\paragraph*{{\Stepiii}For $\boldmath\text{\meta{ver}}$, $\boldmath
+\text{\meta{ver}} > 12 $.} Beginning with the next major version following
+version~11, Adobe changed its versioning scheme. There are now two tracks,
+\emph{subscription} and \emph{classic} (also called \emph{perpetual}). For
+subscription, the version, as I understand it, will always be \texttt{DC}
+(Document Cloud), and for the classic, for which you've purchased a
+\emph{perpetual license}, the \meta{ver} is a calendar year. The first
+classic version is \texttt{2015}, the next one is most likely \texttt{2017},
+since major releases occur about every two years.
+
+Execute the code of display~\eqref{display:getPath} by pressing the button
+provided to obtain a path of the form,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/DC
+\end{Verbatim}
+for the subscription license or,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/C/Users/!meta(username)/AppData/Roaming/Adobe/Acrobat/2015
+\end{Verbatim}
+for the classic (or perpetual) license. Of course, this last path is for
+the first classic version.
+
+Now, to obtain the path to the \texttt{JavaScripts} folder, follow the
+instructions for numbered paragraph \ding{183}, but with \meta{ver} equal
+to either \texttt{DC} or \texttt{2015} (a calendar year).
+
+%/C/Users/D. P. Story/AppData/Roaming/Adobe/Acrobat/Privileged/11.0/JavaScripts
+
+\subsection{For users of \app{Mac OS}}
+
+\app{Mac OS} does not have the security restrictions that \app{Windows OS}
+does, as described in paragraphs \ding{183} and \ding{184}.
+
+Follow the instructions of paragraph \ding{182}, by first pressing the button
+provided in display~\eqref{display:getPath}, then, in the console window,
+execute this script as described in the paragraph following
+display~\eqref{display:getPath}. After working through \ding{182}, one
+obtains any of the following paths depending on the version (\meta{ver}) you
+are using:\medskip
+
+\noindent
+For $\text{\meta{ver}} = \texttt{8.0}, \texttt{9.0}, \texttt{10.0},
+\texttt{11.0}$:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/!meta(ver)/JavaScripts
+\end{Verbatim}
+\medskip
+
+\noindent
+For $\text{\meta{ver}} > 12$, the path is,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/DC/JavaScripts
+\end{Verbatim}
+for a subscription license, and,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/2015/JavaScripts
+\end{Verbatim}
+or more generally,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+/Users/!meta(user)/Library/Application\ Support/Adobe/
+ Acrobat/!meta(year)/JavaScripts
+\end{Verbatim}
+for the perpetual license.
+
+In all cases, if the \texttt{JavaScripts} folder does not exist, it must
+be created. Copy any \SC{JS} support files into the \texttt{JavaScripts}
+folder. The script files are read the next time \app{Acrobat} is started.
+
+\section{Testing the placement of the JavaScript support files}
+
+Assuming you have successfully followed the instructions and created the
+\texttt{JavaScripts} folder, test the validity of what you have done by
+closing \app{Acrobat} then opening it again. Open the console window
+(\texttt{Ctrl+J} or \texttt{Cmd+J}, for \app{Mac OS}) and execute this
+command in the console window:
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars={!~@}]
+app.getPath("user","javascript");!quad!copyGetPathJS
+\end{Verbatim}
+If you have followed the instructions, the return string should read the
+complete path to the \texttt{JavaScripts} folder.
+\end{document}
diff --git a/macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx b/macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx
new file mode 100644
index 0000000000..091ba8a94f
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/eq-pin2corr.dtx
@@ -0,0 +1,281 @@
+% \iffalse
+% makeindex -s gglo.ist -o eq-pin2corr.gls eq-pin2corr.glo
+% makeindex -s gind.ist -o eq-pin2corr.ind eq-pin2corr.idx
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% eq-pin2corr.sty package, %%
+%% Copyright (C) 2021 D. P. Story %%
+%% dpstory@uakron.edu 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}
+%<package>\ProvidesPackage{eq-pin2corr}
+%<package> [2021/02/20 v1.0 Applies PIN security to quizzes]
+%<*driver>
+\documentclass{ltxdoc}
+%\usepackage[colorlinks,hyperindex=false,linktocpage,bookmarksnumbered]{hyperref}
+\usepackage[colorlinks,hyperindex=false]{hyperref}
+\usepackage{fancyvrb}
+\usepackage{calc}
+%\usepackage{eq-pin2corr}
+%\def\texorpdfstring#1#2{#1}
+%\pdfstringdefDisableCommands{\let\\\textbackslash}
+\OnlyDescription % comment out for implementation details
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\gdef\brpr#1{\texttt{\char123\relax#1\char125\relax}}
+\let\darg\brpr
+\let\env\texttt
+\let\opt\texttt
+\let\app\textsf
+\let\pkg\textsf
+\let\uif\textsf
+\def\EXCL{!}
+\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}}}}
+\def\CMD#1{\textbackslash#1}
+\makeatletter
+\renewcommand\theparagraph{\texorpdfstring{\protect\P\protect\ }{\textparagraph}}
+\renewcommand\thesubparagraph{\texorpdfstring{\protect\P\protect\P\protect\ }{\textparagraph\textparagraph}}
+\renewcommand{\section}
+ {\renewcommand{\@seccntformat}[1]{\thesection\quad}%
+ \@startsection {section}{1}{\z@}%
+ {-3.5ex \@plus -1ex \@minus -.2ex}%
+ {2.3ex \@plus.2ex}%
+ {\normalfont\Large\bfseries}}
+\renewcommand{\paragraph}
+ {\renewcommand{\@seccntformat}[1]{\theparagraph\unskip\,}%
+ \@startsection{paragraph}{4}{0pt}{6pt}{-3pt}{\bfseries}}
+\renewcommand{\subparagraph}
+ {\renewcommand{\@seccntformat}[1]{\thesubparagraph\unskip\,}%
+ \@startsection{subparagraph}{5}{\parindent}{6pt}{-3pt}{\bfseries}}
+\edef\amtIndent{\the\parindent}
+\newenvironment{aebQuote}
+ {\list{}{\leftmargin\amtIndent}%
+ \item\relax}
+ {\endlist}
+\makeatother
+\InputIfFileExists{aebdocfmt.def}{\PackageWarning{eq-pin2corr}{Inputting aebdocfmt.def}}
+ {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+ \PackageInfo{eq-pin2corr}{aebdocfmt.def cannot be found}}
+\begin{document}
+\addtolength{\marginparwidth}{3pt}
+ \GetFileInfo{eq-pin2corr.sty}
+ \title{The \textsf{eq-pin2corr} Package}
+ \author{D. P. Story\\
+ Email: \texttt{dpstory@uakron.edu}}
+ \date{processed \today}
+ \maketitle
+\setcounter{secnumdepth}{5}
+\setcounter{tocdepth}{5}
+\bgroup
+\value{secnumdepth}=3
+\value{tocdepth}=3
+ \tableofcontents
+\egroup
+ \DocInput{eq-pin2corr.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here. Execute
+ \begin{quote}\texttt{makeindex -s gind.ist -o eq-pin2corr.ind eq-pin2corr.idx}\end{quote}
+ on the command line and recompile
+ \texttt{eq-pin2corr.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here. Execute
+ \begin{quote}
+ \texttt{makeindex -s gglo.ist -o eq-pin2corr.gls eq-pin2corr.glo}
+ \end{quote}
+ on the command line and recompile \texttt{eq-pin2corr.dtx}.}
+\end{document}
+%</driver>
+% \fi
+% \MakeShortVerb{|}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{web}{Inputting aebdonotindex.def}}
+% {\PackageInfo{web}{cannot find aebdonotindex.def}}
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% \section{Introduction}
+% This package is an add-on to the \env{quiz} environment of the \pkg{exerquiz} package. It uses
+% the \pkg{eq-save} package. To correct a quiz, the document consumer must press
+% the \uif{Correct} button of a quiz and successfully enter the correct PIN number.
+%
+% \changes{v1.0}{2021/02/20}{Completed documentation, publish package for first time}
+%
+% \paragraph*{Purpose.} This package adds PIN security to a quiz created by
+% the \env{quiz} environment. This package is designed for the educational
+% sector, for instructors who use the quizzes of \pkg{exerquiz} to assess their
+% students understanding of the course material.
+%
+% \paragraph*{PDF Viewers.} Discussion of PDF viewers for document author and document consumer.
+% \begin{aebQuote}
+% \begin{description}
+% \item[Instructor] Any PDF viewer may be used as a PDF previewer, \app{sumatraPDF}, for instance,
+% can be used, but it has not functionality. To test the newly created document
+% to see if it is functioning correctly, must use \app{Adobe Reader DC} or \app{Acrobat DC}.\footnote
+% {We use DC here to refer to actually any Adobe AA/AR application. Earlier versions of these applications
+% will work.}
+% \item[Document consumers (students)] The \pkg{exerquiz} and \pkg{eq-pin2tocorr} extensively
+% use JavaScript to perform many background tasks. For the student to have any success in this
+% workflow, he/she must use \app{Adobe Reader}.
+% \end{description}
+% \end{aebQuote}
+% \paragraph*{Workflow.} The package is designed for the following workflow:
+% \begin{enumerate}
+% \item The instructor creates the quiz using the \pkg{exerquiz} and
+% \pkg{eq-pin2corr} packages.
+% \item The instructor delivers the ``PDF quiz'' to each student. (System drive or email)
+% \item The student takes the quiz. The student can press the \uif{Correct}
+% but, unless he/she knows the PIN, the quiz is not marked up.
+% \item The student saves the PDF quiz in \app{Adobe Reader DC}.
+% \item The student returns the PDF to the instructor. (System drive or email)
+% \item The instructor presses the \uif{Correct} button to mark up the quiz
+% and record the grade of the student. The instructor saves the quiz.
+% \item The instructor returns the PDF, at some point, to the student.
+% \item Both instructor and student happily go on with their lives.
+% \end{enumerate}
+% \section{Options and package requirements}
+% \begin{macrocode}
+\newif\ifPINshowScore \PINshowScorefalse
+\DeclareOption{showscore}{\PINshowScoretrue}
+\DeclareOption{!showscore}{\PINshowScorefalse}
+\ProcessOptions\relax
+\RequirePackage{exerquiz}[2021/02/17]
+\RequirePackage{eq-save}[2021/02/17]
+% \end{macrocode}
+% \section{Package commands}
+% Implement local versions\DescribeMacro{\showScoreOn}\DescribeMacro{\showScoreOff}{} of the package options \opt{showscore} and \opt{!showscore},
+% these are \cs{showScoreOn} and \cs{showScoreOff}.
+% \begin{macrocode}
+\def\showScoreOn{\PINshowScoretrue}
+\def\showScoreOff{\PINshowScorefalse}
+% \end{macrocode}
+% Define \DescribeMacro{\SaveAndSendMsg} a message that appears on the console when the PIN entered is not correct.
+% \begin{macrocode}
+\flJSStr[noquotes]{\SaveAndSendMsg}{Success! %
+Now save and send to the instructor}
+% \end{macrocode}
+% Make changes to the \uif{End Quiz} control and to the \uif{Correct} control.
+% Begin by modifying the \DescribeMacro{\postSubmitQuiz}\cs{postSubmitQuiz} command, which is a hook within the executing
+% code of the \uif{End Quiz} control.
+% \begin{macrocode}
+\begin{defineJS*}[\makeesc\@\makecmt\%]{\postSubmitQuiz}
+// Begin post submit quiz code%
+@ifPINSecurity%
+@ifPINshowScore@else
+ var f = this.getField("ScoreField.@oField");
+ if ( f!=null ) {
+ f.textSize=0;
+ f.value = "@SaveAndSendMsg";
+ } else {
+ var f = this.getField("PointsField.@oField");
+ if (f!=null) {
+ f.textSize=0;
+ f.value = "Success! Now save and send to instructor";
+ }
+ }@fi@fi
+ oRecordOfQuizData["ScoreData.@oField"]=%
+[1*Score,1*NQuestions,1*ptScore,1*NPointTotal];
+ oRecordOfQuizData["RightWrong.@oField"]=%
+eval(RightWrong.toSource());
+ oRecordOfQuizData["ProbDist.@oField"]=%
+eval(ProbDist.toSource());
+ cntCorrectResponses();
+\end{defineJS*}
+% \end{macrocode}
+% The command name for the action of the \uif{End Quiz} control is
+% \DescribeMacro{\eQzBtnActns}\cs{eQzBtnActns}.
+% We save this and pre-pend a single code line, as needed.
+% \begin{macrocode}
+\let\eQzBtnActnsSave\eQzBtnActns
+\def\eQzBtnActns{\ifPINshowScore\else
+ var bDisplaySilent=true;\r\fi
+ \eQzBtnActnsSave
+}
+% \end{macrocode}
+% The command name for the action of the \uif{Correct} control is \cs{CorrBtnActionsJS}
+% we save this and later modify it.
+% \begin{macrocode}
+\let\CorrBtnActionsJSSave\CorrBtnActionsJS
+% \end{macrocode}
+% We can turn on and off the PIN feature by expanding \DescribeMacro{\usePINCorrBtn}
+% \cs{usePINCorrBtn} and \DescribeMacro{\restoreCorrBtn}\cs{restoreCorrBtn}.
+% \begin{macrocode}
+\newif\ifPINSecurity \PINSecurityfalse
+\def\usePINCorrBtn{\PINSecuritytrue
+ \let\CorrBtnActionsJS\CorrBtnActionsPwdJS}
+\def\restoreCorrBtn{\PINshowScoretrue\PINSecurityfalse
+ \let\CorrBtnActionsJS\CorrBtnActionsJSSave}
+% \end{macrocode}
+% The instructor can tediously press the \uif{Correction} button, or place
+% an entry,
+%\begin{Verbatim}[xleftmargin=\parindent,fontsize=\small,
+%commandchars={!()},codes={\catcode`\%=9}]
+%var _PinCode1 = "02JRVZdRgYgCA-Rtje8VkD";
+%\end{Verbatim}
+%in the file \texttt{config.js}. If such a variable exists and its value
+%matches the PIN hash string, the instructor clicks the \uif{Correction} button
+%to get the quiz markup. Conceivably, the instructor might want different PIN names
+%and string hash values. The \DescribeMacro\classPINVar\cs{classPINVar} is a convenient
+%way of declaring the PIN variable name; eg, if |\classPINVar{_PinCode1}| is declared
+%prior to the \env{quiz} environment, the instructor need not manually enter the PIN.
+% \begin{macrocode}
+\def\classPINVar#1{\def\PINclassPV{#1}}
+\let\PINclassPV\@empty
+% \end{macrocode}
+% The modified action for the \uif{Correct} button.
+% we save this and later modify it.
+% \begin{macrocode}
+\begin{defineJS*}[\makeesc\!\makecmt\%]{\CorrBtnActionsPwdJS}
+!ifx!PINclassPV!@empty%
+var userPIN = "";!else%
+var userPIN = "!PINclassPV";!fi
+if (userPIN == "" ) userPIN = undefined;
+try {
+ if ( typeof eval(userPIN) == "undefined") userPIN = undefined;
+} catch(e) { userPIN = undefined; }
+if (typeof userPIN == "undefined") {
+ var resp=app.response({
+ cQuestion: "Enter the PIN number",
+ cTitle: "View Answers",
+ bPassword: true
+ });
+ var _resp=Collab.hashString(resp);
+ var _bQzResults = ( _resp ==_PinCode );
+} else var _bQzResults = ( eval(userPIN) ==_PinCode );
+if (_bQzResults) {
+ RightWrong=eval("RightWrong.!currQuiz");
+ ProbDist=eval("ProbDist.!currQuiz");
+ correctQuiz("!currQuiz",3);
+ DisplayQuizResults("!currQuiz",3,3);
+ if (typeof correctSumryTbl == "function")
+ correctSumryTbl("!currQuiz",3);
+} else {
+ console.println("Something went wrong, \\
+you entered an incorrect PIN Id, \\
+or the class PIN Id (\\\\classPINVar) was incorrect or undefined");
+ console.show();
+}
+\end{defineJS*}
+% \end{macrocode}
+% \DescribeMacro\declPINId\hskip-\marginparsep\texttt{\darg{\ameta{PIN-Id}}\darg{\ameta{hash-str}}}
+% Set the basic parameters of this PIN security scheme: the pin-id and its corresponding hash-string.
+% \begin{macrocode}
+\def\declPINId#1#2{\def\numPINId{#1}\def\hashPINId{#2}}
+\@onlypreamble\declPINId
+\declPINId{5243}{02JRVZdRgYgCA-Rtje8VkD} % PIN Id, hash-str
+\begin{insDLJS}{pin}{Pin Code}
+var _PinCode = "\hashPINId";
+\end{insDLJS}
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%\Finale
diff --git a/macros/latex/contrib/eq-pin2corr/eq-pin2corr.ins b/macros/latex/contrib/eq-pin2corr/eq-pin2corr.ins
new file mode 100644
index 0000000000..b759729ac9
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/eq-pin2corr.ins
@@ -0,0 +1,60 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright 2021 D. P. Story
+%%
+%% This file is part of the `AcroTeX eDucation Bundle'.
+%% -------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.2 of this license or (at your option) any
+%% later version. The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.2 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\filedate{2018/09/21}
+\def\batchfile{eq-pin2corr.ins}
+
+\input docstrip
+\ifx\generate\undefined
+ \Msg{**********************************************}
+ \Msg{*}
+ \Msg{* This installation requires docstrip}
+ \Msg{* version 2.4 or later.}
+ \Msg{*}
+ \Msg{* An older version of docstrip has been input}
+ \Msg{*}
+ \Msg{**********************************************}
+ \errhelp{Move or rename old docstrip.tex and get a newer one.}
+ \errmessage{Old docstrip in input path}
+ \batchmode
+ \csname @@end\endcsname\end
+\fi
+
+\keepsilent
+\askforoverwritefalse
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\preamble
+\endpreamble
+
+\generate
+{%
+ \file{eq-pin2corr.sty}{\from{eq-pin2corr.dtx}{copyright,package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files }
+\Msg{*}
+\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
diff --git a/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdf b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdf
new file mode 100644
index 0000000000..c1920bddba
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex
new file mode 100644
index 0000000000..29422f836b
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/examples/get-hash-string.tex
@@ -0,0 +1,52 @@
+\documentclass{article}
+\usepackage[designv]{web}
+\usepackage{eforms}
+
+%\previewOn\pmpvOn
+
+\begin{defineJS}{\btnHashStrAct}
+var resp=app.response({
+ cQuestion: "Enter a PIN number",
+ cTitle: "Get Hash String"
+});
+if (resp !=null) {
+ var f=this.getField("txtHashStr");
+ var hashStr=Collab.hashString(resp);
+ f.value=hashStr;
+ f=this.getField("txtPINNum");
+ f.value=resp;
+ f=this.getField("txtdeclPINId");
+ f.value = "\\\\declPINId{"+resp+"}{"+hashStr+"}";
+}
+\end{defineJS}
+
+\parindent0pt
+
+\begin{document}
+
+\section*{Get Hash String from PIN number}
+
+\textbf{Extensive Instructions.} Create a four digit (PIN) number.
+Push the button and enter the four digit number you just created into the response box.
+When you press the \textsf{OK} button,
+the hash string of the PIN number you entered appears in the text field. The PIN number goes in as the
+first argument of \verb|\declPINId|, and the hash string is the second argument of \verb|\declPINId|; eg,
+\begin{verbatim}
+\declPINId{5243}{02JRVZdRgYgCA-Rtje8VkD} % PIN number, hash string
+\end{verbatim}
+
+\textbf{Brief Instructions.} Press \textsf{Push}, enter your PIN, press \textsf{OK}.\medskip\par\noindent
+\pushButton[\CA{Push}\AAmouseup{\btnHashStrAct}]{btn}{}{11bp}\olBdry
+\textField[\textSize{8}]{txtHashStr}{2in}{11bp} Chosen PIN: \textField[\textSize{8}]{txtPINNum}{\widthof{00000}}{11bp}
+\medskip\par\noindent
+%
+Save these two values as arguments of \verb|\declPINId| and place in the preamble of your
+quiz document.\medskip
+
+\noindent
+Copy to quiz document: \textField[\textSize{8}]{txtdeclPINId}{3in}{13bp}\olBdry
+\pushButton[\CA{Reset}\AAmouseup{this.resetForm();}]{reset}{}{13bp}
+
+
+
+\end{document}
diff --git a/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdf b/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdf
new file mode 100644
index 0000000000..1fca51e00a
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.pdf
Binary files differ
diff --git a/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.tex b/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.tex
new file mode 100644
index 0000000000..b084b55c5a
--- /dev/null
+++ b/macros/latex/contrib/eq-pin2corr/examples/qz-pin-to-correct.tex
@@ -0,0 +1,99 @@
+\documentclass{article}
+\usepackage[designv,forcolorpaper]{web}
+\usepackage{exerquiz}[2021/02/17]
+\usepackage[!showscore]{eq-pin2corr}
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+\showCreditMarkup % optional
+\let\uif\textsf
+\useMCCircles % optional
+
+%
+% When building your own quiz document, decide on a PIN number
+% then use the utility document get-hash-string.pdf to acquire
+% the corresponding hash string. Place your own PIN and hash string
+% in the two arguments of \declPINId.
+\declPINId{5243}{02JRVZdRgYgCA-Rtje8VkD} % PIN number, hash string
+% So instructor can bypass entering the PIN.
+\classPINVar{_PinCode1}
+
+\parindent0pt
+\parskip6pt
+
+\begin{document}
+
+\section*{PIN Security for Quizzes}
+
+This demo file implements a feature that prevents that student from
+correcting his/her own quiz. The \uif{Correct} button appears at the end of
+the quiz, but a PIN number is needed for it to execute. For the purpose of
+this demo files, the PIN number is given to the right of the \uif{Correct}
+button; of course, the PIN is not given to the student. \verb~:-{)~ Test it
+out: (1) take the test; (2) press the \uif{End} button; (3) save and close
+the document; (4) open the document and press the \uif{Correct} button, the
+graded quiz should be reported. \textsf{Adobe Reader DC} (or \textsf{Adobe
+Acrobat}) is required for the document to function as designed.
+
+\usePINCorrBtn
+
+\begin{quiz*}{qz1}
+Solve each, passing is 100\%.
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry\kern1bp
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry\kern1bp
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\ScoreField[\rectW{2.25in}]\currQuiz\olBdry\CorrButton{\currQuiz} (PIN: \numPINId)
+
+\noindent
+Answers: \AnswerField\currQuiz
+
+% remove this \end{document} and recompile. This next quiz has no PIN security.
+\end{document}
+
+\section*{No PIN security}
+
+To restore the default definition of the \verb|\CorrButton| action, expand
+the freshly defined macro \verb|\restoreCorrBtnJS|.
+
+% restore the Correct button to its normal/default behavior: the student
+% can get his/her score and the quiz is marked up.
+\restoreCorrBtn
+
+\begin{quiz*}{qz2}
+Solve each, passing is 100\%.
+\begin{questions}
+ \item The sum of 1 and 1 is \dots
+\begin{answers}{8}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+ \item $ \cos(\pi) = \RespBoxMath{-1}{1}{.0001}{[0,1]}\cgBdry\kern1bp
+\CorrAnsButton{-1} $
+
+\item $\displaystyle\frac{d}{dx}{\sin(x)}=\RespBoxMath{cos(x)}{4}{.0001}{[0,1]}\cgBdry\kern1bp
+\CorrAnsButton{cos(x)} $
+\end{questions}
+\end{quiz*}\quad\PointsField{\currQuiz}\olBdry\CorrButton{\currQuiz}
+
+\end{document}