%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
% This is file 'ltxkeys.sty', version 0.0.3c, 2012/11/17.                  %
%                                                                          %
% This package and accompanying files may be distributed and/or            %
% modified under the conditions of the LaTeX Project Public License,       %
% either version 1.3 of this license or any later version. The latest      %
% version of this license is in http://www.latex-project.org/lppl.txt      %
% and version 1.3 or later is part of all distributions of LaTeX           %
% version 2005/12/01 or later.                                             %
%                                                                          %
% The LPPL maintenance status of this software is 'author-maintained'.     %
%                                                                          %
% This software is provided 'as it is', without warranty of any kind,      %
% either expressed or implied, including, but not limited to, the          %
% implied warranties of merchantability and fitness for a particular       %
% purpose.                                                                 %
%                                                                          %
% Copyright (c) 2011-2012 Ahmed Musa (amusa22@gmail.com).                  %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\@ifpackageloaded{catoptions}{%
  \@ifpackagelater{catoptions}{2012/10/14}{}{%
    \@latex@error{Loaded version of catoptions package is
      not current}\@ehd
  }%
}{%
  \RequirePackage{catoptions}[2012/10/14]%
}
\UseNormalCatcodes
\StyleFilePurpose{A robust key-value parser (AM)}
\StyleFileRCSInfo
$Id: ltxkeys.sty,v 0.0.3c 2012/11/17 09:00:00 Ahmed Musa Exp $
\ProvidesPackage{ltxkeys}[\StyleFileInfo]
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
\SetStyleFileMessages[ltxkeys@]{info}{warn}{err}
\cpt@setupsafeactivesedef
\catcode`\&=3\relax
\new@def\ltxkeys@afterfi#1\fi{\fi#1}
\new@def\ltxkeys@afterelsei#1\else#2\fi{\fi#1}
\new@def\ltxkeys@afterelseii#1\else#2\fi{\fi#2}
\new@def*\ltxkeys@ehd{%
  \ifx\protect\string\ltxkeys@afterfi
    A serious error has occurred.\MsgBrk
    Try typing <return>\space to proceed.\MsgBrk
    If that fails, type X and then <return>\space to quit.
  \fi
}
\new@def*\ltxkeys@truetoks{true}
\new@def*\ltxkeys@falsetoks{false}
\robust@def*\ltxkeys@specialhandler{%
  \cpt@testopt\ltxkeys@sp@cialhandler{}%
}
\robust@def*\ltxkeys@sp@cialhandler[#1]#2{%
  \begingroup
  \toks1{\endgroup\newcsnpdef*{#1@#2@handler}##1##2}%
  \def\reserved@a{\the\toks\expandafter1\expandafter{\the\toks0}}%
  \afterassignment\reserved@a\toks0=%
}
\newletcs\ltxkeys@nil\relax
\new@def*\ltxkeys@nnil{\ltxkeys@nil}
\new@def*\ltxkeys@quark{\@gobble\ltxkeys@quark}
\new@def*\ltxkeys@antiquark{\@gobble\ltxkeys@antiquark}
\new@def*\ltxkeys@cdr#1#2\ltxkeys@nil{#2}
\new@def*\ltxkeys@spcdr#1#2#3\ltxkeys@nil{\detokenize{#2}}
\new@def\ltxkeys@ifxFT#1#2{\ltxkeys@ifxTF{#1}{#2}\cptiiofii\cptiofii}
\new@def\ltxkeys@ifxTF#1#2{%
  \expandafter\cptswap\cpt@car#1\ltxkeys@quark\car@nil
  {\expandafter\ifx\cpt@car#2\ltxkeys@antiquark\car@nil}%
  \expandafter\cptiofii\else\expandafter\cptiiofii\fi
}
\new@def*\ltxkeys@ifcsemptyTF#1{%
  \expandafter\ltxkeys@ifxTF\cpt@car#1\ltxkeys@quark\car@nil\@empty
}
\robust@def*\ltxkeys@letmanytocs#1#2{\cptfor#1\dofor{\let##1= #2}}
\robust@def*\ltxkeys@error#1#2{\ltxkeys@err{#1}{#2}\@gobble}
\robust@def*\ltxkeys@debug#1#{%
  \ifboolTF{ltxkeys@tracingkeys}{%
    \ifstrcmpTF{#1}{*}{%
      \cpt@sttrue\ltxkeys@d@bug
    }{%
      \cpt@stfalse\ltxkeys@d@bug
    }%
  }{%
    \@gobbletwo
  }%
}
\robust@def*\ltxkeys@d@bug#1#2{%
  \wlog{\ifcpt@st^^J\fi ltxkeys debug [#1] #2.}%
}
\cptnewvariables{if}[ltxkeys@]{break,st,pl,cl,sw,sv,nv,novalue,pxop,exop,
  preset,disable,ini,kf,rm,ssk,dec,dep,twk,tracingkeys,useempty,chdef,
  swa,reservenopath,global,protected,inkeycmd}[false]
\cptnewvariables{if}{inputvalid}[false]
\cptnewvariables{switch}{infdpointers,infdp@inters}[false]
\cptnewvariables{count}[ltxkeys@]{csvdepth,keydepth}[\z@pt]
\robust@def*\setslavewithmaster{\global\ltxkeys@ssktrue}
\robust@def*\setnoslavewithmaster{\global\ltxkeys@sskfalse}
\setnoslavewithmaster
\robust@def*\allowemptykeypath{\global\ltxkeys@useemptytrue}
\robust@def*\disallowemptykeypath{\global\ltxkeys@useemptyfalse}
\DefSuffixChecker\ltxkeys@suffixcheck{*}{+}{!}
\newletcs\ltxkeys@documentclass\cpt@undefined
\robust@def*\ltxkeys@getdocumentclass{%
  \def\csv@do##1{%
    \filename@parse{##1}%
    \ifx\filename@ext\@clsextension
      \ifcsndefFT{opt@\filename@area\filename@base.\filename@ext}{}{%
        \xdef\ltxkeys@documentclass{%
          \filename@area\filename@base.\filename@ext
        }%
        \loopbreak
      }%
    \fi
  }%
  \csv@@parse*\@filelist
  \ifdefTF\ltxkeys@documentclass{}{%
    \ltxkeys@debug{==}{'ltxkeys' package loaded before
      \string\documentclass:\MsgBrk no problem}%
  }%
}
\cptpassunexpanded{%
  \ifdefFT\@filelist{}{%
    \ltxkeys@ifxTF\@filelist\@gobble{}{%
      \ltxkeys@ifcsemptyTF\@filelist{}\ltxkeys@getdocumentclass
    }%
  }%
  \ifdefFT\ltxkeys@documentclass{%
    \let\ltxkeys@classoptionslist\@empty
  }{%
    \ifdefFT\@classoptionslist{}{%
      \ltxkeys@ifcsemptyTF\@classoptionslist{}{%
        \kv@@normalize*\@classoptionslist
      }%
    }%
    \let\ltxkeys@classoptionslist\@classoptionslist
    \def\csv@do##1{%
      \ifinsetTF{=}{##1}{}{%
        \cptgaddtolist\@classoptionslist{##1}%
      }%
    }%
    \cptexpandbracenext
      {\def\@classoptionslist{}\csv@@loop}\@classoptionslist
    \def\@fileswith@ptions##1[##2]##3{%
      \edef\ltxkeys@tempa{\cptcommanormalize{##3}}%
      \cptfor xkeyval,kvoptions,catoptions\dofor{%
        \xifinsetFT{,####1,}{,\ltxkeys@tempa,}{}{%
          \let\@classoptionslist\ltxkeys@classoptionslist
          \forbreaktrue
        }%
      }%
      \cpt@ifbrack{\@fileswith@pti@ns##1[##2]##3}%
        {\@fileswith@pti@ns##1[##2]##3[]}%
    }%
  }%
}
\robust@def*\ltxkeys@striplaststar#1*\@empty#2\ltxkeys@nil#3{\edef#3{#1}}
\robust@def*\ltxkeys@ifrejname#1{%
  \ifcase0\ifx\key@type\ltxkeys@rej1\else
    \ifx\key@name\ltxkeys@rej1\fi\fi\relax
  \else
    #1%
  \fi
}
\robust@def*\ltxkeys@testst#1{%
  \cpt@ifstar{\ltxkeys@sttrue#1}{\ltxkeys@stfalse#1}%
}
\robust@def*\ltxkeys@testpl#1{%
  \cpt@ifplus{\ltxkeys@pltrue#1}{\ltxkeys@plfalse#1}%
}
\robust@def*\ltxkeys@testcl#1{%
  \cpt@ifclam{\ltxkeys@cltrue#1}{\ltxkeys@clfalse#1}%
}
\robust@def*\ltxkeys@teststpl#1{\ltxkeys@testst{\ltxkeys@testpl{#1}}}
\robust@def*\ltxkeys@state{%
  \\\ltxkeys@keys\\\ltxkeys@prefs\\\ltxkeys@fams\\\ltxkeys@nakeys
  \\\ltxkeys@tpref\\\ltxkeys@ttpref\\\ltxkeys@tfam\\\ltxkeys@tkey
  \\\ltxkeys@tval\\\ifltxkeys@st\\\ifltxkeys@pl\\\ifltxkeys@cl
  \\\ifltxkeys@kf\\\ifltxkeys@pxop\\\ifltxkeys@exop\\\ifltxkeys@ini
  \\\CurrentKeyval\\\CurrentKey\\\CurrentVal
}
\robust@def\ltxkeys@trimspacesincs#1{%
  \expandafter\ltxkeys@trimspaces\expandafter{#1}{#1}%
}
\robust@def\ltxkeys@trimspaces#1#2{%
  \begingroup
  \ifcase0%
    % 1. When #2 of \ltxkeys@trimspaces is empty token, #1, #2, #3 of
    %    \ltxkeys@spcdr will be '.', 'x', <empty>.
    % 2. No one will give #2 of \ltxkeys@trimspaces as a dot (.). So
    %    the test is fairly robust.
    \if.\ltxkeys@spcdr#2.x\ltxkeys@nil\else1\fi
    \if\expandafter\cpt@car\string#2\car@nil\@backslashchar\else1\fi\relax
  \else
    \ltxkeys@err{'\detokenize{#2}' has illegal form}\ltxkeys@ehd
  \fi
  \ltxkeys@tr@mspaces{#1}{#2}%
}
\robust@def\ltxkeys@tr@mspaces#1#2{%
  \edef\ltxkeys@trimmed{\cpttrimspace{#1}}%
  \ltxkeys@ifxTF#2\ltxkeys@trimmed{%
    \expandafter\endgroup\expandafter\edef\expandafter
    #2\expandafter{\expandafter\unexpanded\expandafter{#2}}%
  }{%
    \let#2=\ltxkeys@trimmed
    \expandafter\ltxkeys@tr@mspaces\expandafter{#2}#2%
  }%
}
\robust@def*\ltxkeys@trimspacesset#1{%
  \def\@do##1##2,{%
    \ifnot@nil{##1}{\ltxkeys@trimspaces{##1}##2\@do}%
  }%
  \@do#1,\@nil\@nil,%
}
\new@def*\ltxkeys@iffirstnull#1#2{\ltxkeys@ifcsemptyTF#1{}{#1#2}}
\robust@def*\ltxkeys@remdottrimspaces#1#2{%
  \cptexpandbracenext\ltxkeys@trimspaces{\@gobble#1}#2%
}
\robust@def*\ltxkeys@simplesplitkeyval#1{%
  \expandafter\ltxkeys@simplespl@tkeyval#1=^?^=^?^=\ltxkeys@nil
}
\robust@def*\ltxkeys@simplespl@tkeyval#1={%
  \def\reserved@a##1={%
    \def\reserved@a####1=####2\ltxkeys@nil{%
      \ltxkeys@trimspaces{#1}\key@name
      \ltxkeys@remdottrimspaces{##1}\key@value
      \ltxkeys@remdottrimspaces{####1}\remainder
    }%
    \reserved@a.%
  }%
  \reserved@a.%
}
\robust@def*\ltxkeys@splitkeyattrib#1{%
  \begingroup
  \def\ltxkeys@splita##1/##2/{%
    \ltxkeys@trimspacesset{{##1}\key@type,{##2}\key@name}%
    \ltxkeys@ifrejname{%
      \ltxkeys@err{Wrong syntax for attributes of a key}\ltxkeys@ehd
    }%
    \ltxkeys@splitb.%
  }%
  \def\ltxkeys@splitb##1/{%
    \ltxkeys@remdottrimspaces{##1}\key@default
    \ltxkeys@splitc.%
  }%
  \def\ltxkeys@splitc##1/{%
    \edef\key@callback{\unexpanded\expandafter{\@gobble##1}}%
    \ltxkeys@stripdotcode\key@callback
    \ltxkeys@splitd.%
  }%
  \def\ltxkeys@splitd##1/##2\ltxkeys@nil{%
    \ltxkeys@remdottrimspaces{##1}\key@dependants
  }%
  \ltxkeys@splita#1/^?^/^?^/^?^/^?^/^?^/\ltxkeys@nil
  \let\do\cpt@csexit
  \cptexpanded{\endgroup
    \do\key@type\do\key@name\do\key@default\do\key@callback
    \do\key@dependants
  }%
}
\new@def*\ltxkeys@rej{^?^}
% Does #1 start with '.code'? If it does, remove '.code':
\robust@def*\ltxkeys@stripdotcode#1{%
  \ltxkeys@trimspacesincs#1%
  \xifinsetTF{\relax\detokenize{.code=}}{\relax\cptoxdetok{#1}}{%
    \def\reserved@a##1.code=##2\ltxkeys@nil{%
      \def\reserved@a####1.\ltxkeys@nil{%
        \ltxkeys@remdottrimspaces{####1}#1%
      }%
      \reserved@a.##2\ltxkeys@nil
    }%
    \expandafter\reserved@a#1.\ltxkeys@nil
  }{}%
}
\robust@def*\ltxkeys@removedotcode#1#2{%
  \ltxkeys@trimspaces{#1}#2%
  \xifinsetTF{\detokenize{/.code=}}{\detokenize{#1}}{%
    \def\reserved@a##1/.code=##2\ltxkeys@nil{%
      \def\reserved@a####1.\ltxkeys@nil{%
        \ltxkeys@remdottrimspaces{####1}\reserved@a
        \edef#2{\expandcsonce{\@gobble##1}/\expandcsonce\reserved@a}%
      }%
      \reserved@a.##2\ltxkeys@nil
    }%
    \expandafter\reserved@a\expandafter.#2.\ltxkeys@nil
  }{}%
}
\robust@def*\ltxkeys@in{\cpt@testst\ltxkeys@in@a}
\robust@def*\ltxkeys@in@a#1#2{%
  \def\in@@##1#1##2\in@@{%
    \ifblankTF{##2}\in@false\in@true
    \ifboolTF{cpt@st}{\ifboolTF{in@}}{}%
  }%
  \in@@#2{\in@@}#1\in@@
}
\robust@def*\ltxkeys@iffound#1\in#2\then{%
  \ltxkeys@trimspaces{#1}\reserved@a
  \ltxkeys@trimspaces{#2}\reserved@b
  \ltxkeys@stfalse
  \cptexpandtwoargsonce\ltxkeys@in@a\reserved@a\reserved@b
  \ifin@
}
\robust@def*\ltxkeys@ifchcfd#1\endgroup{%
  % Don't make \@firstoftwo and \@secondoftwo equal to \relax
  % here since \ifbool needs \ifnull, which in turn needs
  % \@firstoftwo and \@secondoftwo.
  \cptpassexpanded{%
    \endgroup
    \ifcase#1\relax
      \ifdefboolTF{cpt@choicefd}
        {\noexpand\@firstoftwo}{\noexpand\@secondoftwo}%
    \or
      \ifdefboolTF{cpt@choicefd}
        {\noexpand\@secondoftwo}{\noexpand\@firstoftwo}%
    \else
      \ltxkeys@err{Invalid number '#1'}\ltxkeys@ehd
    \fi
  }%
}
\robust@def*\ltxkeys@getlasttoken#1{%
  \def\ltxkeys@resttokens{}%
  \ltxkeys@g@tlasttoken#1\ltxkeys@g@tlasttoken
    \ltxkeys@g@tlasttoken\ltxkeys@getlasttoken
}
\robust@def*\ltxkeys@g@tlasttoken#1#2{%
  \ifx#2\ltxkeys@g@tlasttoken
    \edef\ltxkeys@lasttoken{\unexpanded{#1}}%
    \def\reserved@a##1\ltxkeys@getlasttoken{}%
    \expandafter\reserved@a
  \else
    \edef\ltxkeys@resttokens
      {\expandcsonce\ltxkeys@resttokens\unexpanded{#1}}%
    \expandafter\ltxkeys@g@tlasttoken
  \fi
  #2%
}
\new@def\ltxkeys@stripNouterbraces#1#2{%
  \romannumeral\expandafter\ltxkeys@str@pNouterbraces
    \expandafter{\romannumeral\number#1000m}\strip@nil#2\strip@nil
}
\new@def\ltxkeys@str@pNouterbraces#1\strip@nil#2\strip@nil{%
  \ifbracedTF{#2}{%
    \expandafter\ifnullTF\expandafter{\@gobble#2}{%
      \expandafter\ifnullTF\expandafter{\@gobble#1}{0 #2}{%
        \cptexpandbracenext\ltxkeys@str@pNouterbraces{\@gobble#1}%
        \strip@nil#2\strip@nil
      }%
    }{0 #2}%
  }{0 #2}%
}
\new@def*\ltxkeys@stripallouterbraces#1{\ltxkeys@stripNouterbraces\@m{#1}}
\new@def*\ltxkeys@stripallouterbracesincs#1{%
  \ifmacroTF{#1}{%
    \edef#1{\cptexpandbracenext{\ltxkeys@stripNouterbraces\@m}{#1}}%
  }{%
    \cpt@notcserr{#1}%
  }%
}
\robust@def*\ltxkeys@getbasechars{\cpt@teststopt\ltxkeys@g@tchars{1}}
\robust@def*\ltxkeys@g@tchars[#1]#2#3{%
  \begingroup
  \def#3{}\gdef\ltxkeys@charcount{0}%
  \def\siso@do##1{%
    \edef#3{#3##1}%
    \xdef\ltxkeys@charcount{\the\numexpr\ltxkeys@charcount+1}%
    \ifnum\ltxkeys@charcount>#1\relax\loopbreak\fi
  }%
  \cptexpandarg\siso@@loop
    {\ifboolTF{cpt@st}\cptoxdetok\detokenize{#2}}%
  \postgroupdef#3\endgroup
}
\robust@def*\ltxkeys@getorder{\cpt@teststopt\ltxkeys@g@torder,}
\robust@def*\ltxkeys@g@torder[#1]#2#3{%
  \def\ltxkeys@order{-1}%
  \begintoksgroup
  \cpt@stchoose{cpt@st}{#3}\ltxkeys@tempa\ltxkeys@getorder
  \lowercase{\ltxkeys@trimspaces{#2}\ltxkeys@tempb}%
  \@tempcnta\z@pt
  \def\ltxkeys@do##1{%
    \oifstrcmpFT\ltxkeys@tempb{##1}{}{%
      \cptexpanded{%
        \toks@{\def\noexpand\ltxkeys@order{\the\@tempcnta}}%
      }%
      \loopbreaktrue
    }%
    \advance\@tempcnta\@ne
  }%
  \ltxkeys@listparse*1[;]\ltxkeys@tempa
  \endtoksgroup
}
\robust@def*\ltxkeys@ifeltcountTF{\cpt@teststopt\ltxkeys@ifeltcount,}
\robust@def*\ltxkeys@ifeltcount[#1]{%
  \cpt@testpnopt{\ltxkeys@ifeltc@unt{#1}}{=}%
}
\robust@def*\ltxkeys@ifeltc@unt#1(#2)#3#4{%
  \begingroup
  \edef\reserved@a{\ifcpt@st*\fi}%
  \def\eltnum{0}%
  \def\ltxkeys@do##1{%
    \cptpushnumber\eltnum
  }%
  \expandafter\ltxkeys@listparse\reserved@a1[#1]{#4}%
  \aftercsname\endgroup{@\ifnum\eltnum#2\numexpr#3%
    first\else second\fi oftwo}%
}
\robust@def*\ltxkeys@findmatch#1#2#3{%
  \def\currmatch{}%
  \ltxkeys@trimspaces{#1}\reserved@a
  \ltxkeys@f@ndmatch#2,:,\ltxkeys@nil{#3}%
}
\robust@def*\ltxkeys@f@ndmatch#1:#2,#3\ltxkeys@nil#4{%
  \ifblankTF{#3}{%
    #4%
  }{%
    \ltxkeys@trimspaces{#1}\reserved@b
    \ifx\reserved@a\reserved@b
      \edef\currmatch{\unexpanded{#2}}%
      \expandafter\@gobble
    \else
      \expandafter\@iden
    \fi
    {\ltxkeys@f@ndmatch#3\ltxkeys@nil{#4}}%
  }%
}
\robust@def*\ltxkeys@ifcase#1#2{%
  \def\currmatch{}%
  \ltxkeys@trimspaces{#1}\reserved@a
  \ltxkeys@ifc@se#2,:,\ltxkeys@nil
}
\robust@def*\ltxkeys@ifc@se#1:#2,#3\ltxkeys@nil{%
  \ifblankTF{#3}{%
    \@secondoftwo
  }{%
    \ltxkeys@trimspaces{#1}\reserved@b
    \ltxkeys@ifxTF\reserved@a\reserved@b{%
      \edef\currmatch{\unexpanded{#2}}%
      \@firstoftwo
    }{%
      \ltxkeys@ifc@se#3\ltxkeys@nil
    }%
  }%
}
\new@def\ltxkeys@alltoendif#1\endif{#1}
\new@def\ltxkeys@firsttoendif#1#2\endif{#1}
\new@def*\ltxkeys@ifcassenumcmpTF#1#2#3{%
  \ifdim#1pt#2pt %
  \expandafter\cptiofii\else\expandafter\cptiiofii\fi
}
\new@def\ltxkeys@ifcasse#1{%
  \ifstrcmpTF{#1}\elseif{%
    \ltxkeys@alltoendif
  }{%
    \ifstrcmpTF{#1}\endif{}{\ltxkeys@ifcasse@a{#1}}%
  }%
}
\new@def\ltxkeys@ifcasse@a#1#2{%
  \ifstrcmpTF{#2}\elseif{%
    \ltxkeys@alltoendif
  }{%
    \ifstrcmpTF{#2}\endif{}{%
      \ltxkeystestcmd{#1}{#2}\ltxkeys@firsttoendif{\ltxkeys@ifcasse@b{#1}}%
    }%
  }%
}
\new@def\ltxkeys@ifcasse@b#1#2{%
  \ifstrcmpTF{#2}\endif{}{\ltxkeys@ifcasse@a{#1}}%
}
\robust@def*\ltxkeys@removeelements{\cpt@teststopt\ltxkeys@rem@veelements,}
\robust@def*\ltxkeys@rem@veelements[#1]{%
  \cpt@testpnopt{\ltxkeys@rem@veelem@nts{#1}}\@ne
}
\robust@def\ltxkeys@rem@veelem@nts#1(#2)#3#4{%
  \let\ltxkeys@tempa#3%
  \ifcpt@st\else
    \ifnum#2=\z@pt\cptthreexp\cptgobbletorelax\fi
  \fi
  \iflacus#4\dolacus
    \expandafter\cptgobbletorelax
  \fi
  \begingroup
  \let\detk\detokenize
  \let\if@remvst\ifcpt@st
  \ifmacroTF{#3}{}{\cpt@notcserr{#3}}%
  \csv@@normalize*[#1]#3%
  \def\ltxkeys@remove@a##1{%
    \def\ltxkeys@do####1{%
      \@tempcnta\z@pt
      \def\ltxkeys@remove@a########1##1####1##1########2&{%
        \edef#3{\unexpanded{########1##1########2}}%
      }%
      \def\ltxkeys@remove@b########1{%
        \xifinsetTF{##1\detk{####1}##1}{##1\detk{########1}##1}{%
          \ltxkeys@remove@a##1########1##1&%
          \ifboolTF{@remvst}{%
            \s@expandarg\ltxkeys@remove@b#3%
          }{%
            \advance\@tempcnta\@ne
            \ifnumcmpTF\@tempcnta<#2{%
              \s@expandarg\ltxkeys@remove@b#3%
            }{}%
          }%
        }{}%
      }%
      \s@expandarg\ltxkeys@remove@b#3%
    }%
    \ltxkeys@listparse1[##1]{#4}%
    \csv@@normalize*[##1]#3%
  }%
  \s@expandarg\ltxkeys@remove@a{\detk{#1}}%
  \postgroupdef#3\endgroup
  \cpt@relax
  \ltxkeys@ifxFT#3\ltxkeys@tempa
}
\robust@def*\ltxkeys@replaceelements{%
  \cpt@teststopt\ltxkeys@r@placeelements,%
}
\robust@def*\ltxkeys@r@placeelements[#1]{%
  \cpt@testpnopt{\ltxkeys@r@pl@ceelements{#1}}\@ne
}
\robust@def\ltxkeys@r@pl@ceelements#1(#2)#3#4{%
  \let\ltxkeys@tempa#3%
  \ifcpt@st\else
    \ifnum#2=\z@pt\cptthreexp\cptgobbletorelax\fi
  \fi
  \iflacus#4\dolacus
    \expandafter\cptgobbletorelax
  \fi
  \begingroup
  \let\if@replst\ifcpt@st
  \ifmacroTF{#3}{}{\cpt@notcserr{#3}}%
  \edef\ltxkeys@sublist{\unexpanded{#4}}%
  \ltxkeys@n@rmalizecsset[#1]{#3,\ltxkeys@sublist}%
  \def\ltxkeys@replace@a##1{%
    \def\ltxkeys@replace@a####1####2##1####3&{%
      \ltxkeys@r@pl@ceelement[##1](#2)#3{####1}{####2}%
      \ifblankTF{####3}{}{\ltxkeys@replace@a####3&}%
    }%
    \expandafter\ltxkeys@replace@a\ltxkeys@sublist##1&%
    \csv@@normalize*[##1]#3%
  }%
  \s@expandarg\ltxkeys@replace@a{\detokenize{#1}}%
  \postgroupdef#3\endgroup
  \cpt@relax
  \ltxkeys@ifxFT#3\ltxkeys@tempa
}
\robust@def\ltxkeys@r@pl@ceelement[#1](#2)#3#4#5{%
  \begingroup
  \@tempcnta\z@pt
  \def\ltxkeys@replace@a##1#1#4#1##2&{%
    \edef#3{\unexpanded{##1#1#5#1##2}}%
  }%
  \def\ltxkeys@replace@b##1{%
    \xifinsetTF{#1\detokenize{#4}#1}{#1\detokenize{##1}#1}{%
      \ltxkeys@replace@a#1##1#1&%
      \ifboolTF{@replst}{%
        \s@expandarg\ltxkeys@replace@b#3%
      }{%
        \advance\@tempcnta\@ne
        \ifnumcmpTF\@tempcnta<#2{%
          \s@expandarg\ltxkeys@remove@b#3%
        }{}%
      }%
    }{}%
  }%
  \s@expandarg\ltxkeys@replace@b{#3}%
  \postgroupdef#3\endgroup
}
\robust@def*\ltxkeys@checkchoice{%
  \cpt@teststpl{\cpt@testopt\ltxkeys@cc@a,}%
}
\robust@def*\ltxkeys@cc@a[#1]{%
  \cpt@checklistparser{#1}{}%
  \cpt@testpnopt{\ltxkeys@cc@b#1}{}%
}
\robust@def*\ltxkeys@commacheckchoice{%
  \cpt@teststpl{\cpt@testpnopt{\ltxkeys@cc@b,}{}}%
}
\robust@def*\ltxkeys@checkinput#1#2{%
  \lowercase{\edef\nominations{\unexpanded{#2}}}%
  \cpt@sttrue\cpt@pltrue
  \ltxkeys@cc@b,(\userinput\order){#1}{#2}{%
    \@firstoftwo
  }{%
    \@secondoftwo
  }%
}
\robust@def*\CheckUserInput#1#2{%
  \lowercase{\edef\nominations{\unexpanded{#2}}}%
  \cpt@sttrue\cpt@pltrue
  \ltxkeys@cc@b,(\userinput\order){#1}{#2}{%
    \inputvalidtrue
  }{%
    \inputvalidfalse
  }%
}
\robust@def*\ltxkeys@cc@b#1(#2)#3#4{%
  \begingroup
  \ifcpt@st\lowercase{\fi
    \ltxkeys@trimspaces{#3}\ltxkeys@userinput
    \edef\ltxkeys@nominations{\unexpanded{#4}}%
  \ifcpt@st}\fi
  \def\ltxkeys@ccparser{#1}%
  \csv@@normalize*[#1]\ltxkeys@nominations
  \cptexpandsecond{%
    \ifblankTF{#2}\ltxkeys@cc@d{\ltxkeys@cc@c#2}\ltxkeys@nil
  }{%
    {\expandcsonce\ltxkeys@userinput}%
    {\expandcsonce\ltxkeys@nominations}%
  }%
}
\robust@def*\ltxkeys@cc@c#1#2\ltxkeys@nil#3#4{%
  \ifblankTF{#2}{\ltxkeys@cc@d#1}{\ltxkeys@cc@e#1#2}{#3}{#4}%
}
\robust@def*\ltxkeys@cc@d#1#2#3{%
  \def\reserved@a{#1}%
  \ltxkeys@ifxTF\reserved@a\ltxkeys@nnil{%
    \def\ltxkeys@tempa{}%
  }{%
    \def\ltxkeys@tempa{\def#1{#2}}%
  }%
  \edef\x{\cptoxdetok\ltxkeys@ccparser}%
  \edef\x{{\x\detokenize{#2}\x}{\x\detokenize{#3}\x}}%
  \expandafter\ifinsetTF\x{%
    \ifboolTF{cpt@pl}{%
      \rightaddtocs\ltxkeys@tempa\@firstoftwo
    }{%
      \rightaddtocs\ltxkeys@tempa\@firstofone
    }%
  }{%
    \ifboolTF{cpt@pl}{%
      \rightaddtocs\ltxkeys@tempa\@secondoftwo
    }{%
      \rightaddtocs\ltxkeys@tempa{%
        \expandafter\ltxkeys@nomatcherr\@gobble
      }%
    }%
  }%
  \cptpassexpanded{%
    \endgroup
    \cpt@csexit\ltxkeys@userinput
    \cpt@csexit\ltxkeys@nominations
    \expandcsonce\ltxkeys@tempa
  }%
}
\robust@def*\ltxkeys@cc@e#1#2#3#4{%
  \chardef#2\z@pt
  \cpt@choicefdfalse
  \def\ltxkeys@do##1{%
    \def#1{##1}%
    \ifstrcmpTF{##1}{#3}{%
      \cpt@choicefdtrue\loopbreak
    }{%
      \cptpushnumber#2%
    }%
  }%
  \cptexpandsecond{\ltxkeys@listparse0}{[\ltxkeys@ccparser]}{#4}%
  \cptpassexpanded{%
    \endgroup
    \cpt@csexit\ltxkeys@userinput
    \cpt@csexit\ltxkeys@nominations
    \ifcpt@choicefd
      \def\noexpand#1{\expandcsonce#1}%
      \def\noexpand#2{\the\numexpr#2}%
      \ifcpt@pl\noexpand\@firstoftwo\else\noexpand\@firstofone\fi
    \else
      \def\noexpand#1{\unexpanded{#3}}%
      \def\noexpand#2{-1}%
      \ifcpt@pl
        \noexpand\@secondoftwo
      \else
        \unexpanded{\expandafter\ltxkeys@nomatcherr\@gobble}%
      \fi
    \fi
  }%
}
\robust@def*\ltxkeys@nomatcherr{%
  \ltxkeys@error{User input '\ltxkeys@userinput' not in list
    of nominations ||\ltxkeys@nominations||}\ltxkeys@ehd
}
\robust@def*\ltxkeys@ifoneincsvlist{\cpt@teststopt\ltxkeys@ifoneincsvl@st,}
\robust@def*\ltxkeys@ifoneincsvl@st[#1]#2#3{%
  \begingroup
  \ifcpt@st
    \let\test@list#2%
    \let\master@list#3%
  \else
    \edef\test@list{\unexpanded{#2}}%
    \edef\master@list{\unexpanded{#3}}%
  \fi
  \csv@@normalize*[#1]\master@list
  \cpt@choicefdfalse
  \def\csv@do##1{%
    \oifinset@sp@TF#1{##1}\master@list{\cpt@choicefdtrue\loopbreak}{}%
  }%
  \csv@@parse*[#1]\test@list
  \expandafter\endgroup
  \ifcpt@choicefd\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}
\robust@def*\ltxkeys@ifincsvlistTF{\cpt@teststopt\ltxkeys@ifincsvlist,}
\robust@def*\ltxkeys@ifincsvlist[#1]{%
   \cpt@testpnopt{\ltxkeys@if@ncsvlist#1}{1}%
}
\robust@def*\ltxkeys@if@ncsvlist#1(#2)#3#4{%
  \begingroup
  \edef\parser{\detokenize{#1}}%
  \ifcpt@st\lowercase{\fi
    \edef\ltxkeys@tempa{\unexpanded{#3}}%
    \edef\ltxkeys@tempb{\unexpanded{#4}}%
  \ifcpt@st}\fi
  \cpt@sttrue\cpt@csvnormalize[#1]\ltxkeys@tempb
  \cpt@cnta\z@pt
  \def\ltxkeys@itemspresent{}%
  \def\ltxkeys@do##1{%
    \xifinsetFT{\detokenize{#1##1#1}}%
      {\parser\cptoxdetok\ltxkeys@tempb\parser}{}{%
      \edef\ltxkeys@itemspresent
        {\csliststack,\ltxkeys@itemspresent\unexpanded{##1}}%
      \advance\cpt@cnta\@ne
    }%
    \ifnum\cpt@cnta>\numexpr#2-1\relax\loopbreak\fi
  }%
  \ltxkeys@listparse*1[#1]\ltxkeys@tempa
  \ifnum\cpt@cnta>\numexpr#2-1\relax
    \edef\ltxkeys@nritems{\the\cpt@cnta}%
  \else
    \def\ltxkeys@itemspresent{}%
    \def\ltxkeys@nritems{-1}%
  \fi
  \cptexpandsecond\endgroup{%
    \cpt@csexit\ltxkeys@itemspresent
    \cpt@csexit\ltxkeys@nritems
    \ifx\ltxkeys@itemspresent\@empty\noexpand\@secondoftwo\else
      \noexpand\@firstoftwo\fi
  }%
}
\robust@def*\ltxkeys@ifoneintokenlist{\cpt@testst\ltxkeys@ifoneint@kenlist}
\robust@def*\ltxkeys@ifoneint@kenlist#1#2{%
  \begingroup
  \ifcpt@st
    \let\test@list#1%
    \let\master@list#2%
  \else
    \edef\test@list{\unexpanded{#1}}%
    \edef\master@list{\unexpanded{#2}}%
  \fi
  \cpt@choicefdfalse
  \def\tsv@do##1{%
    \edef\reserved@a{\ltxkeys@stripNouterbraces{1}{##1}}%
    \xifinsetTF{\cptoxdetok\reserved@a}
      {\cptoxdetok\master@list}{\cpt@choicefdtrue\loopbreak}{}%
  }%
  \tsv@@parse*\test@list
  \expandafter\endgroup
  \ifcpt@choicefd\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}
\robust@def*\ltxkeys@ifintsvlistTF{%
  \cpt@testst{\cpt@testpnopt\ltxkeys@ifintsvlist{1}}%
}
\robust@def*\ltxkeys@ifintsvlist(#1)#2#3{%
  \begingroup
  \ifcpt@st\lowercase{\fi
    \edef\ltxkeys@tempa{\unexpanded{#2}}%
    \edef\ltxkeys@tempb{\unexpanded{#3}}%
  \ifcpt@st}\fi
  \def\ltxkeys@itemspresent{}%
  \cpt@cnta\z@pt
  \def\tsv@do##1{%
    \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{%
      \edef\ltxkeys@itemspresent
        {\csliststack{}\ltxkeys@itemspresent\unexpanded{##1}}%
      \advance\cpt@cnta\@ne
    }%
    \ifnum\cpt@cnta>\numexpr#1-1\relax\loopbreak\fi
  }%
  \s@expandarg\tsv@@parse\ltxkeys@tempa
  \ifnum\cpt@cnta>\numexpr#1-1\relax
    \edef\ltxkeys@nritems{\the\cpt@cnta}%
  \else
    \def\ltxkeys@itemspresent{}%
    \def\ltxkeys@nritems{-1}%
  \fi
  \cptexpandsecond\endgroup{%
    \cpt@csexit\ltxkeys@itemspresent
    \cpt@csexit\ltxkeys@nritems
    \ifx\ltxkeys@itemspresent\@empty\noexpand\@secondoftwo\else
      \noexpand\@firstoftwo\fi
  }%
}
\robust@def*\ltxkeys@ifinlistTF{%
  \cpt@testst{\cpt@testpnopt\ltxkeys@ifinlist{1}}%
}
\robust@def*\ltxkeys@ifinlist(#1)#2#3{%
  \begingroup
  \ifcpt@st\lowercase{\fi
    \edef\ltxkeys@tempa{\unexpanded{#2}}%
    \edef\ltxkeys@tempb{\unexpanded{#3}}%
  \ifcpt@st}\fi
  \def\ltxkeys@itemspresent{}%
  \cpt@cnta\z@pt
  \def\ltxkeys@do##1{%
    \xifinsetTF{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{%
      \edef\ltxkeys@itemspresent
        {\csliststack,\ltxkeys@itemspresent\unexpanded{##1}}%
      \advance\cpt@cnta\@ne
    }{}%
    \ifnum\cpt@cnta>\numexpr#1-1\relax\loopbreak\fi
  }%
  \ltxkeys@listparse*1\ltxkeys@tempa
  \ifnum\cpt@cnta>\numexpr#1-1\relax
    \edef\ltxkeys@nritems{\the\cpt@cnta}%
  \else
    \def\ltxkeys@itemspresent{}\def\ltxkeys@nritems{-1}%
  \fi
  \cptexpandsecond\endgroup{%
    \cpt@csexit\ltxkeys@itemspresent
    \cpt@csexit\ltxkeys@nritems
    \ltxkeys@ifcsemptyTF\ltxkeys@itemspresent
      {\noexpand\@secondoftwo}{\noexpand\@firstoftwo}%
  }%
}
\robust@def*\ltxkeys@notinpkgclserr#1{%
  \ifinstylefileTF{}{%
    \ltxkeys@err{Command '\detokenize{#1}' issued
      \MsgBrk outside style or class file}
      {Command '\detokenize{#1}' is available
      only in style files.}%
  }%
}
\robust@def*\ltxkeys@commanormalize#1#2{\edef#2{\cptcommanormalize{#1}}}
\robust@def*\ltxkeys@commanormalizeset{%
  \let\normelt\ltxkeys@commanormalize
  \ltxkeys@normalizeset
}
\robust@def*\ltxkeys@kvnormalize#1#2{%
  \edef#2{\unexpanded{#1}}%
  \kv@@normalize*[,]#2%
}
\robust@def*\ltxkeys@kvnormalizeset{%
  \let\normelt\ltxkeys@kvnormalize
  \ltxkeys@normalizeset
}
\robust@def*\ltxkeys@normalizeset#1{%
  \edef\reserved@a{\cptcommanormalize{#1}}%
  \def\@do##1##2,{%
    \ifnot@nil{##1}{\normelt{##1}##2\@do}%
  }%
  \expandafter\@do\reserved@a,\@nil,%
  \undefcs\normelt
}
\robust@def*\ltxkeys@normalizecsset{\cpt@testopt\ltxkeys@n@rmalizecsset,}
\robust@def*\ltxkeys@n@rmalizecsset[#1]#2{%
  \cptfor#2\dofor{\csv@@normalize[#1]##1}%
}
\new@def*\ltxkeys@parser@nil{\@gobble\ltxkeys@parser@nil}

\begingroup
\catcode`\?=3
\robust@gdef*\ltxkeys@declarelistparser#1#2{%
  \ifcsdefinable{#1}\relax
  \begingroup
  \ltxkeys@letmanytocs{#1,\ifstrcmpTF,\cptexpandnext,
    \ltxkeys@ifxTF,\listbreak,\ltxkeys@parser@nil}\relax
  \def\elta##1{\noexpandcsn{\cptgobblescape#1@list@##1}}%
  \def\eltb##1{\cptexpandnext{\elta{b}##1}{########1}%
    #2\ltxkeys@parser@nil#2?{}}%
  \def\eltc{\ltxkeys@ifxTF!\unexpanded{{####1}{####4}{\unexpanded{####4}}}}%
  \cptexpanded{\endgroup
    \def#1####1{\ifstrcmpTF!{####1}{\elta{a}}{\eltb+}}%
    \def\elta{a}####1{\eltb!}%
    \def\elta{b}####1####2#2####3?####4####5{%
      \ltxkeys@ifxTF\ltxkeys@parser@nil{####2}{\eltc}{%
        \ifstrcmpTF{####2}{\listbreak}{\eltc}{%
          \elta{b}{####1}####3?{####4####5{####2}}{####5}%
        }%
      }%
    }%
  }%
}
\endgroup

% Break out of the loop using \loopbreak.
\robust@def*\ltxkeys@listparse{\cpt@testst\ltxkeys@listparse@a}
\robust@def*\ltxkeys@listparse@a#1{%
  \begingroup
  \def\reserved@a##1##2{\endgroup
    \def\ltxkeys@nlz{##1}\def\ltxkeys@inkv{##2}%
  }%
  \cptexpandsecond\reserved@a{%
    \ifcase#1{01}{01}\or{00}{01}\or{01}{00}\or{00}{00}\else{01}{01}\fi
  }%
  \cpt@testopt\ltxkeys@listparse@b,%
}
\robust@def*\ltxkeys@listparse@b[#1]#2{%
  \cpt@stchoose{cpt@st}{#2}\ltxkeys@listitem\ltxkeys@listparse
  \cptpushfunctions\ltxkeys@listparse{%
    \\\ifloopbreak\\\ifltxkeys@useempty\\\ltxkeys@doo
    \\\ltxkeys@listparse@c\\\ltxkeys@listparse@d\\\ltxkeys@loopcbk
    \\\stopprocessinglistkey
  }\cpt@csvdepth
  \let\stopprocessinglistkey\loopbreak
  \ifdefTF\ltxkeys@do
    {\let\ltxkeys@doo\ltxkeys@do}{\cpt@notdeferr\ltxkeys@do}%
  \def\ltxkeys@listparse@c{%
    \ifboolTF{loopbreak}
      {\gobble@to@sentinel\ltxkeys@nil#1}{\ltxkeys@listparse@d.}%
  }%
  \def\ltxkeys@listparse@d##1#1{%
    \edef\ltxkeys@listitem{\expandcsonce{\@gobble##1}}%
    \ltxkeys@ifxTF\ltxkeys@listitem\ltxkeys@nnil{}{%
      \ltxkeys@ifcsemptyTF\ltxkeys@listitem{%
        \ifboolFT{ltxkeys@useempty}{}{\ltxkeys@doo{}}%
      }{%
        \s@expandarg\ltxkeys@doo\ltxkeys@listitem
      }%
      \relax\ltxkeys@listparse@c
    }%
  }%
  \ifswitchTF{ltxkeys@nlz}{%
    \usename{\if\ltxkeys@inkv kv\else csv\fi @@normalize}*[#1]%
      \ltxkeys@listitem
  }{}%
  \loopbreakfalse
  \expandafter\ltxkeys@listparse@c\ltxkeys@listitem#1\ltxkeys@nil#1%
  \cptpopfunctions\ltxkeys@listparse\cpt@csvdepth
  \ifnum\cpt@csvdepth=\z@pt\undefcs\ltxkeys@do\fi
}
\def\ltxkeys@keyprefixhook{}
\def\ltxkeys@macroprefixhook{}
\def\ltxkeys@keyfamilyhook{}
\robust@def*\ltxkeys@reservekeyprefix{%
  \cpt@testst\ltxkeys@res@rvekeyprefix
}
\robust@def*\ltxkeys@res@rvekeyprefix#1{%
  \cptexpanded{%
    \ifcpt@st\AfterEndOfStyleFile{\fi
      \cptfiltermergecsv[,]\unexpanded{%
        \ltxkeys@keyprefixhook{#1}\nofilter
        \globalize\ltxkeys@keyprefixhook
      }%
    \ifcpt@st}\fi
  }%
}
\robust@def*\ltxkeys@reservekeyfamily{%
  \cpt@testst\ltxkeys@res@rvekeyfamily
}
\robust@def*\ltxkeys@res@rvekeyfamily#1{%
  \cptexpanded{%
    \ifcpt@st\AfterEndOfStyleFile{\fi
      \cptfiltermergecsv[,]\unexpanded{%
        \ltxkeys@keyfamilyhook{#1}\nofilter
        \globalize\ltxkeys@keyfamilyhook
      }%
    \ifcpt@st}\fi
  }%
}
\robust@def*\ltxkeys@reservemacroprefix{%
  \cpt@testst\ltxkeys@res@rvemacroprefix
}
\robust@def*\ltxkeys@res@rvemacroprefix#1{%
  \cptexpanded{%
    \ifcpt@st\AfterEndOfStyleFile{\fi
      \cptfiltermergecsv[,]\unexpanded{%
        \ltxkeys@macroprefixhook{#1}\nofilter
        \globalize\ltxkeys@macroprefixhook
      }%
    \ifcpt@st}\fi
  }%
}
\ltxkeys@reservekeyfamily*{ltxkeys}
\ltxkeys@reservemacroprefix*{ltxkeys@}

\robust@def*\ltxkeys@unreservekeyprefix{%
  \cpt@testst\ltxkeys@unres@rvekeyprefix
}
\robust@def*\ltxkeys@unres@rvekeyprefix#1{%
  \cptexpanded{%
    \ifcpt@st\AfterEndOfStyleFile{\fi
      \cptfilterremovecsv[,]\unexpanded{%
        \ltxkeys@keyprefixhook{#1}\nofilter
        \globalize\ltxkeys@keyprefixhook
      }%
    \ifcpt@st}\fi
  }%
}
\robust@def*\ltxkeys@unreservekeyfamily{%
  \cpt@testst\ltxkeys@unres@rvekeyfamily
}
\robust@def*\ltxkeys@unres@rvekeyfamily#1{%
  \cptexpanded{%
    \ifcpt@st\AfterEndOfStyleFile{\fi
      \cptfilterremovecsv[,]\unexpanded{%
        \ltxkeys@keyfamilyhook{#1}\nofilter
        \globalize\ltxkeys@keyfamilyhook
      }%
    \ifcpt@st}\fi
  }%
}
\robust@def*\ltxkeys@unreservemacroprefix{%
  \cpt@testst\ltxkeys@unres@rvemacroprefix
}
\robust@def*\ltxkeys@unres@rvemacroprefix#1{%
  \cptexpanded{%
    \ifcpt@st\AfterEndOfStyleFile{\fi
      \cptfilterremovecsv[,]\unexpanded{%
        \ltxkeys@macroprefixhook{#1}\nofilter
        \globalize\ltxkeys@macroprefixhook
      }%
    \ifcpt@st}\fi
  }%
}
\robust@def*\ltxkeys@testopt@a#1{\cpt@testopt{\ltxkeys@testopt@b#1}{KV}}
\robust@def*\ltxkeys@testopt@b#1[#2]#3{%
  \ifltxkeys@useempty\else
    \iflacus#3\dolacus
      \ltxkeys@warn{Empty key family encountered\on@line}%
    \fi
  \fi
  \ltxkeys@makepf{#2}%
  \ltxkeys@makehdr{#3}%
  #1%
}
\robust@def*\ltxkeys@testopt@c#1{%
  \begingroup
  \catcode`\,=12\relax
  \cpt@testopt{\ltxkeys@testopt@d#1}{KV}%
}
\robust@def*\ltxkeys@testopt@d#1[#2]#3{%
  \ifltxkeys@pl\else
    \def\temp@err##1{%
      \ltxkeys@err{Multiple ##1 in \noexpandcsn
        {ltxkeys@set\ifltxkeys@rm rm\fi keys}%
        without '+' suffix}\ltxkeys@ehd
    }%
    \ltxkeys@ifeltcountTF[,](>)\@ne{#2}{%
      \temp@err{prefixes}%
    }{%
      \ltxkeys@ifeltcountTF[,](>)\@ne{#3}{%
        \temp@err{families}%
      }{}%
    }%
  \fi
  \endgroup
  \ltxkeys@commanormalizeset{{#2}\ltxkeys@prefs,{#3}\ltxkeys@fams}%
  \cpt@testopt{#1}{}%
}
\robust@def*\ltxkeys@testopt@e#1#2{%
  \ltxkeys@testopt@a{%
    \cptexpandarg{\cpt@testopt{\ltxkeys@testopt@f#1}}{#2\ltxkeys@hdr}%
  }%
}
\robust@def*\ltxkeys@testopt@f#1[#2]#3{%
  \ifboolTF{ltxkeys@sw}{%
    \cpt@ifbrack{\ltxkeys@sttrue#1{#2}{#3}}{\ltxkeys@stfalse#1{#2}{#3}[]}%
  }{%
    \cpt@ifbrack{\ltxkeys@bracedefault{\ltxkeys@sttrue#1{#2}{#3}}}%
      {\ltxkeys@stfalse#1{#2}{#3}[]}%
  }%
}
\robust@def*\ltxkeys@testopt@g#1#2{%
  \cptexpandarg\ltxkeys@testopt@a{\noexpandcsn{ltxkeys@#1}{#2}}%
}
\robust@def*\ltxkeys@bracedefault#1[{%
  \begingroup
  \toks@{#1}%
  \defpass\ltxkeys@tempa##1]{%
    \toks1\expandafter{\@gobble##1}%
    \cptexpandsecond\endgroup{\the\toks@[{\the\toks1}]}%
  }.%
}
\robust@def*\ltxkeys@testopt@@a#1{\ltxkeys@testst{\ltxkeys@testopt@@b#1}}
\robust@def*\ltxkeys@testopt@@b#1{\cpt@testopt{\ltxkeys@testopt@@c#1}{KV}}
\robust@def*\ltxkeys@testopt@@c#1[#2]{%
  \ltxkeys@commanormalize{#2}\ltxkeys@prefs
  \cpt@testfam{\ltxkeys@testopt@@d#1}%
}
\robust@def*\ltxkeys@testopt@@d#1<#2>{%
  \expandafter\ltxkeys@commanormalize
  \expandafter{\romannumeral-`\q#2}\ltxkeys@fams
  \cpt@testopt{#1}{}%
}
\robust@def*\ltxkeys@findpointers#1{%
  \ltxkeys@svfalse\ltxkeys@nvfalse
  \let\infdpointers\cptswtrue
  \let\infdp@inters\cptswfalse
  \ltxkeys@findp@inters{\savevalue\needvalue}{#1}\ltxkeys@tkey{%
    \ltxkeys@svtrue\ltxkeys@nvtrue
    \ltxkeys@addtopointedkeys{savevalue}\ltxkeys@tkey
    \ltxkeys@addtopointedkeys{needvalue}\ltxkeys@tkey
  }{%
    \ltxkeys@findp@inters{\needvalue\savevalue}{#1}\ltxkeys@tkey{%
      \ltxkeys@svtrue\ltxkeys@nvtrue
      \ltxkeys@addtopointedkeys{needvalue}\ltxkeys@tkey
      \ltxkeys@addtopointedkeys{savevalue}\ltxkeys@tkey
    }{%
      \ltxkeys@findp@inters{\needvalue}{#1}\ltxkeys@tkey{%
        \ltxkeys@svfalse\ltxkeys@nvtrue
        \ltxkeys@addtopointedkeys{needvalue}\ltxkeys@tkey
      }{%
        \let\infdp@inters\cptswtrue
        \ltxkeys@findp@inters{\savevalue}{#1}\ltxkeys@tkey{%
          \ltxkeys@svtrue\ltxkeys@nvfalse
          \ltxkeys@addtopointedkeys{savevalue}\ltxkeys@tkey
        }{%
          \ltxkeys@debug{==}{Key '\ltxkeys@tkey' has no pointer}%
        }%
      }%
    }%
  }%
  \let\infdpointers\cptswfalse
}
\robust@def*\ltxkeys@findp@inters#1#2#3{%
  \def\reserved@a##1#1##2##3\ltxkeys@nil{%
    \edef#3{\unexpanded{##2}}%
    \ltxkeys@ifxTF#3\ltxkeys@nnil{%
      \edef#3{\unexpanded{##1}}%
      \if\infdpointers
        \if\infdp@inters
          \ltxkeys@trimspacesincs#3%
        \fi
      \else
        \ltxkeys@trimspacesincs#3%
      \fi
      \@secondoftwo
    }{%
      \ltxkeys@trimspacesincs#3%
      \@firstoftwo
    }%
  }%
  \reserved@a#2#1{\ltxkeys@nil}\ltxkeys@nil
}
\robust@def*\ltxkeys@addtopointedkeys#1#2{%
  \letcstocsn\reserved@e{\ltxkeys@hdr#1keys}%
  \ifdefTF\reserved@e{%
    \xifinsetTF{,\cptoxdetok{#2},}{,\cptoxdetok\reserved@e,}{}{%
      \csn@xdef{\ltxkeys@hdr#1keys}{%
        \csliststack,\reserved@e\expandcsonce{#2}%
      }%
    }%
  }{%
    \csn@xdef{\ltxkeys@hdr#1keys}{\expandcsonce{#2}}%
  }%
}
\robust@def*\ltxkeys@addtosavedvalue#1#2{%
  \edef\ltxkeys@tempa{#1{\expandcsonce{#2}}}%
  \letcstocsn\reserved@e{\ltxkeys@hdr @savedvaluelist}%
  \ifdefTF\reserved@e{%
    \oifinset@sp@TF,\ltxkeys@tempa\reserved@e{}{%
      \csn@xdef{\ltxkeys@hdr @savedvaluelist}{%
        \csliststack,\reserved@e\expandcsonce\ltxkeys@tempa
      }%
    }%
  }{%
    \csn@xdef{\ltxkeys@hdr @savedvaluelist}{%
      \expandcsonce\ltxkeys@tempa
    }%
  }%
}
\new@def*\ltxkeys@currtriple{%
  \ltxkeys@ifcsemptyTF\ltxkeys@ttpref{???}\ltxkeys@ttpref,%
  \ltxkeys@ifcsemptyTF\ltxkeys@tfam{???}\ltxkeys@tfam,%
  \ltxkeys@tkey
}
\robust@def*\ltxkeys@makepf#1{%
  \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@ttpref
  \edef\ltxkeys@tpref{%
    \ltxkeys@ifcsemptyTF\ltxkeys@ttpref{}{\ltxkeys@ttpref @}%
  }%
}
\robust@def*\ltxkeys@makehdr#1{%
  \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@tfam
  \edef\ltxkeys@hdr{%
    \ltxkeys@tpref\ltxkeys@ifcsemptyTF\ltxkeys@tfam{}{\ltxkeys@tfam @}%
  }%
}
\new@def*\ltxkeys@badkeynamelist{}
\robust@def*\ltxkeys@badkeynames#1{%
  \ltxkeys@ifcsemptyTF\ltxkeys@badkeynamelist{%
    \expandafter\ltxkeys@commanormalize\expandafter
      {\detokenize{#1}}\ltxkeys@badkeynamelist
  }{%
    \cptexpandsecond{\cptfiltermergecsv[,]}
      {\noexpand\ltxkeys@badkeynamelist{\detokenize{#1}}}\nofilter
  }%
}
\newletcs\ltxkeys@addbadkeynames\ltxkeys@badkeynames
\robust@def*\ltxkeys@removebadkeynames#1{%
  \ltxkeys@ifcsemptyTF\ltxkeys@badkeynamelist{%
    \ltxkeys@info{Couldn't delete from empty
      \string\ltxkeys@badkeynamelist}%
  }{%
    \cptexpandsecond{\cptfilterremovecsv[,]}
      {\noexpand\ltxkeys@badkeynamelist{\detokenize{#1}}}\nofilter
  }%
}
\ltxkeys@badkeynames{.code,ordkey,cmdkey,choicekey,boolkey,%
  handledkeys,presetkeys,postsetkeys,rmkeys,executedkeys,bool,%
  boolean,tog,toggle,switch,true,false,on,off,count,%
  savevaluekeys,xfamilykeys,needvalue,savevalue,usevalue%
}
\robust@def*\ltxkeys@findbadkeyname#1{%
  \begingroup
  \edef\ltxkeys@tempa{\cpttrimspaces{#1}}%
  \oifinset@sp@TF,\ltxkeys@tempa\ltxkeys@badkeynamelist{%
    \ltxkeys@err{Bad key name '\ltxkeys@tempb'}\ltxkeys@ehd
  }{}%
  \endgroup
}
\robust@def*\ltxkeys@saveinitialkeyvals#1#2#3{%
  \ifltxkeys@disable\else
    \ifltxkeys@tracingkeys
      \s@expandarg\ltxkeys@findbadkeyname{#2}%
    \fi
    \ifltxkeys@twk\else
      \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr initialkeyvals}%
      \csn@xdef{\ltxkeys@hdr initialkeyvals}{%
        \csliststack,\ltxkeys@tempa\expandcsonce{#2}=%
        \ifstrcmpTF{#1}{bool}{false}{%
        \ifstrcmpTF{#1}{switch}{false}{\unexpanded{#3}}%
        }%
      }%
    \fi
    \ifboolTF{ltxkeys@tracingkeys}{%
      \ltxkeys@getbasechars[20]{#3}\ltxkeys@tempa
      \ltxkeys@debug{==}{Definition done:
        \ltxkeys@currtriple,\ltxkeys@tempa}%
    }{}%
  \fi
}
\robust@def*\ltxkeys@checkdefkey{%
  \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey}{%
    \ifltxkeys@disable\else
      \ifltxkeys@chdef
        \ltxkeys@error{Key already exists: \ltxkeys@currtriple}
          {Defining only new keys: key '\ltxkeys@currtriple'
          already exists.}%
      \else
        \ltxkeys@debug{!!}{Key already exists: \ltxkeys@currtriple}%
      \fi
    \fi
  }{%
    \ltxkeys@debug{==}{This is a new key: \ltxkeys@currtriple}%
  }%
  \ltxkeys@chdeffalse
  \ifltxkeys@reservenopath\else
    \ltxkeys@checkreserved
  \fi
}
\robust@def*\ltxkeys@checkreserved{%
  \ltxkeys@debug{==}{Checking reserved key paths}%
  \def\@do##1,##2,##3;{%
    \ifnot@nil{##1}{%
      \ifnum\numexpr
        \ifdefTF##2{0}{-1}\ltxkeys@ifcsemptyTF##2{-1}{+0}%
        \ifdefTF##3{+0}{-1}\ltxkeys@ifcsemptyTF##3{-1}{+0}<\z@pt
      \else
        \oifinset@sp@FT,##2##3{}{%
          \ltxkeys@error{##1 '##2' is reserved}
          {You have used a reserved ##1: '##2'.}%
        }%
      \fi
      \@do
    }%
  }%
  \@do key prefix,\ltxkeys@ttpref,\ltxkeys@keyprefixhook;%
    key family,\ltxkeys@tfam,\ltxkeys@keyfamilyhook;%
    macro prefix,\ltxkeys@macpref,\ltxkeys@macroprefixhook;\@nil,,;%
  \ltxkeys@debug{==}{No clash with reserved key paths}%
}
\robust@def*\ltxkeys@ordkey{%
  \ltxkeys@swfalse
  \def\ltxkeys@macpref{}%
  \ltxkeys@testopt@a\ltxkeys@ordkey@a
}
\newletcs\ltxkeys@ordkeys\ltxkeys@ordkey
\robust@def*\ltxkeys@newordkey{\ltxkeys@chdeftrue\ltxkeys@ordkey}
\newletcs\ltxkeys@newordkeys\ltxkeys@newordkey
\robust@def*\ltxkeys@ordkey@a#1{%
  \ltxkeys@debug{==}{Ordinary key '\ltxkeys@tkey' is being defined}%
  \cpt@ifbrack{%
    \ltxkeys@bracedefault{\ltxkeys@sttrue\ltxkeys@ordkey@b{#1}}%
  }{%
    \ltxkeys@stfalse\ltxkeys@ordkey@b{#1}[]%
  }%
}
\robust@def*\ltxkeys@ordkey@b#1[#2]#3{%
  \let\ifltxkeys@keyst\ifltxkeys@st
  \edef\ltxkeys@loopcbk##1{{##1}\unexpanded{{#2}{#3}}}%
  \ifinsetTF,{#1}{%
    \def\ltxkeys@do##1{%
      \expandafter\ltxkeys@ordkey@c\ltxkeys@loopcbk{##1}%
    }%
    \ltxkeys@listparse1{#1}%
  }{%
    \ltxkeys@ordkey@c{#1}{#2}{#3}%
  }%
}
\robust@def*\ltxkeys@ordkey@c#1#2#3{%
  \ltxkeys@findpointers{#1}%
  \ltxkeys@checkdefkey
  \ifdefboolFT{ltxkeys@keyst}{}{%
    \ltxkeys@definedefault\ltxkeys@tkey{#2}%
  }%
  \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#2}%
  \@namedef{\ltxkeys@hdr\ltxkeys@tkey}##1{#3}%
}

\robust@def*\ltxkeys@denyusevaluepointer#1{%
  \xifinsetTF{\detokenize{\usevalue}}{\detokenize{#1}}{%
    \ltxkeys@err{Pointer '\string\usevalue' not allowed when
      defining keys}\@ehd
  }{}%
}
% List processor keys:
\robust@def*\ltxkeys@getlistseparator#1{%
  \xifinsetTF{\detokenize{\listsep}}{\detokenize{#1}}{%
    \def\reserved@a##1\listsep##2##3\ltxkeys@nil{%
      \ifblankTF{##2}{%
        \def\ltxkeys@listsep{,}%
      }{%
        \edef\ltxkeys@listsep{\cpttrimspace{##2}}%
      }%
      \edef\ltxkeys@tempb{\cpttrimspace{##1}\cpttrimspace{##3}}%
    }%
    \reserved@a#1\ltxkeys@nil
  }{%
    \def\ltxkeys@listsep{,}%
    \edef\ltxkeys@tempb{\cpttrimspace{#1}}%
  }%
}
% \ltxkeyslistkey[<pref>]{<fam>}{<key>}[<dft>]{<fn>}
\robust@def*\ltxkeys@listkey{%
  \ltxkeys@swfalse
  \def\ltxkeys@macpref{}%
  \ltxkeys@testopt@a\ltxkeys@listkey@a
}
\newletcs\ltxkeys@listkeys\ltxkeys@listkey
\robust@def*\ltxkeys@newlistkey{\ltxkeys@chdeftrue\ltxkeys@listkey}
\newletcs\ltxkeys@newlistkeys\ltxkeys@newlistkey
\robust@def*\ltxkeys@listkey@a#1{%
  \ltxkeys@debug{==}{Lisp key '\ltxkeys@tkey' is being defined}%
  \cpt@ifbrack{%
    \ltxkeys@bracedefault{\ltxkeys@sttrue\ltxkeys@listkey@b{#1}}%
  }{%
    \ltxkeys@stfalse\ltxkeys@listkey@b{#1}[]%
  }%
}
\robust@def*\ltxkeys@listkey@b#1[#2]#3{%
  \let\ifltxkeys@keyst\ifltxkeys@st
  \edef\ltxkeys@loopcbk##1{{##1}\unexpanded{{#2}{#3}}}%
  \ifinsetTF,{#1}{%
    \def\ltxkeys@do##1{%
      \expandafter\ltxkeys@listkey@c\ltxkeys@loopcbk{##1}%
    }%
    \ltxkeys@listparse1{#1}%
  }{%
    \ltxkeys@listkey@c{#1}{#2}{#3}%
  }%
}
\robust@def*\ltxkeys@listkey@c#1#2#3{%
  \ltxkeys@denyusevaluepointer{#1}%
  \ltxkeys@findpointers{#1}%
  \ltxkeys@checkdefkey
  \ifdefboolTF{ltxkeys@keyst}{%
    \ltxkeys@definedefault\ltxkeys@tkey{#2}%
  }{}%
  \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#2}%
  \ltxkeys@getlistseparator{#3}%
  \def\reserved@a{\csn@def{\ltxkeys@hdr\ltxkeys@tkey @auxcbk}####1}%
  \expandafter\reserved@a\expandafter{\ltxkeys@tempb}%
  \csn@edef{\ltxkeys@hdr\ltxkeys@tkey}##1{%
    \def\noexpand\ltxkeys@listcount{0}%
    \edef\noexpand\ltxkeys@tempa{\noexpand\ltxkeys@stripallouterbraces{##1}}%
    \def\noexpand\ltxkeys@do####1{%
      \noexpand\cptpushnumber\noexpand\ltxkeys@listcount
      \noexpandcsn{\ltxkeys@hdr\ltxkeys@tkey @auxcbk}{####1}%
    }%
    \ltxkeys@listparse*1[\ltxkeys@listsep]\noexpand\ltxkeys@tempa
  }%
}

\robust@def*\ltxkeys@cmdkey{%
  \ltxkeys@swfalse
  \ltxkeys@testopt@e\ltxkeys@cmdkey@a{cmd}%
}
\newletcs\ltxkeys@cmdkeys\ltxkeys@cmdkey
\robust@def*\ltxkeys@newcmdkey{\ltxkeys@chdeftrue\ltxkeys@cmdkey}
\newletcs\ltxkeys@newcmdkeys\ltxkeys@newcmdkey
\robust@def*\ltxkeys@cmdkey@a#1#2[#3]#4{%
  \let\ifltxkeys@keyst\ifltxkeys@st
  \edef\ltxkeys@loopcbk##1{%
    \ltxkeys@cmdkey@b{#1}{##1}\unexpanded{{#3}{#4}}%
  }%
  \ifinsetTF,{#2}{%
    \def\ltxkeys@do##1{\ltxkeys@loopcbk{##1}}%
    \ltxkeys@listparse1{#2}%
  }{%
    \ltxkeys@cmdkey@b{#1}{#2}{#3}{#4}%
  }%
}
\robust@def*\ltxkeys@cmdkey@b#1#2#3#4{%
  \def\ltxkeys@macpref{#1}%
  \ltxkeys@findpointers{#2}%
  \ltxkeys@debug{==}{Command key '\ltxkeys@tkey' is being defined}%
  \ltxkeys@checkdefkey
  \ifdefboolFT{ltxkeys@keyst}{}{\ltxkeys@definedefault\ltxkeys@tkey{#3}}%
  \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#3}%
  \begingroup
  \edef\ltxkeys@tempa{\endgroup\csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1}%
  \edef\ltxkeys@tempb##1{%
    {\csn@edef{#1\ltxkeys@tkey}{\noexpand\unexpanded{####1}}##1}%
  }%
  \expandafter\ltxkeys@tempa\ltxkeys@tempb{#4}%
}
\robust@def*\ltxkeys@boolkey{%
  \ltxkeys@swtrue
  \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@boolkey@a{bool}}%
}
\newletcs\ltxkeys@boolkeys\ltxkeys@boolkey
\robust@def*\ltxkeys@newboolkey{\ltxkeys@chdeftrue\ltxkeys@boolkey}
\newletcs\ltxkeys@newboolkeys\ltxkeys@newboolkey
\robust@def*\ltxkeys@boolkey@a#1#2[#3]{%
  \let\ifltxkeys@keyst\ifltxkeys@st
  \ifblankTF{#3}{}{%
    \xifstrcmpTF{#3}{true}{}{%
      \xifstrcmpTF{#3}{false}{}{%
        \ltxkeys@err{Bad boolean value '#3'}\ltxkeys@ehd
      }%
    }%
  }%
  \ltxkeys@commanormalize{#2}\ltxkeys@tempa
  \cptexpanded{%
    \ifboolTF{ltxkeys@pl}\ltxkeys@boolkey@d
    \ltxkeys@boolkey@c{#1}{\expandcsonce\ltxkeys@tempa}{#3}%
  }%
}
\robust@def*\ltxkeys@boolkey@b#1#2#3{%
  \ltxkeys@findpointers{#2}%
  \ltxkeys@debug{==}{Boolean key '\ltxkeys@tkey' is being defined}%
  \ltxkeys@saveinitialkeyvals{bool}\ltxkeys@tkey{#3}%
  \edef\ltxkeys@resa##1##2{%
    \ltxkeys@boolkey@e\cptmakecs{\ltxkeys@hdr\ltxkeys@tkey}%
    {\ltxkeys@tkey}{#1\ltxkeys@tkey}\unexpanded{{#3}}%
    {{\ltxkeys@setbool\noexpand\ltxkeys@resa\noexpand
    \usename{#1\ltxkeys@tkey\noexpand\ltxkeys@resa}##1}%
    \gobble@or@empty{##2}}%
  }%
}
\robust@def*\ltxkeys@boolkey@c#1#2#3#4{%
  \let\gobble@or@empty\@gobble
  \edef\ltxkeys@loopcbk##1{%
    \ltxkeys@boolkey@b{#1}{##1}\unexpanded{{#3}}%
    \noexpand\ltxkeys@resa\unexpanded{{#4}}{}%
  }%
  \ifinsetTF,{#2}{%
    \def\ltxkeys@do##1{\ltxkeys@loopcbk{##1}}%
    \ltxkeys@listparse1{#2}%
  }{%
    \ltxkeys@loopcbk{#2}%
  }%
}
\robust@def*\ltxkeys@boolkey@d#1#2#3#4#5{%
  \let\gobble@or@empty\@empty
  \edef\ltxkeys@loopcbk##1{%
    \ltxkeys@boolkey@b{#1}{##1}\unexpanded{{#3}}%
    \noexpand\ltxkeys@resa\unexpanded{{#4}{#5}}%
  }%
  \ifinsetTF,{#2}{%
    \def\ltxkeys@do##1{\ltxkeys@loopcbk{##1}}%
    \ltxkeys@listparse1{#2}%
  }{%
    \ltxkeys@loopcbk{#2}%
  }%
}
\robust@def*\ltxkeys@boolkey@e#1#2#3#4#5{%
  % We've delayed the calling of \ltxkeys@checkdefkey till
  % here because of biboolkeys:
  \def\reserved@a##1#2\ltxkeys@nil{%
    \def\ltxkeys@macpref{##1}%
  }%
  \reserved@a#3\ltxkeys@nil
  \ltxkeys@checkdefkey
  \csnnewif{#3}%
  \ifboolFT{ltxkeys@keyst}{}{\ltxkeys@definedefault{#2}{#4}}%
  \cptexpandarg{\def#1##1}{%
    \csn@def{#3}{####1}%
    \noexpandcsn{cpt@pl\ifltxkeys@pl true\else false\fi}%
    \unexpanded{\cpt@sttrue\ltxkeys@cc@b,(\ltxkeys@resa)%
    {##1}{true,false}#5}%
  }%
}
% \ltxkeys@biboolkeys[pref]{fam}[mp]{key1,key2}[dft]{key1-fn}{key2-fn}
% \ltxkeys@biboolkeys+[pref]{fam}[mp]{key1,key2}[dft]{key1-fn}{key2-fn}
%   {<fallback>}
% <fallback> will be called if input isn't valid (ie, not in the
% set {true | false}.
\robust@def*\ltxkeys@biboolkeys{%
  \ltxkeys@swtrue
  \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@biboolkeys@a{}}%
}
\robust@def*\ltxkeys@newbiboolkeys{\ltxkeys@chdeftrue\ltxkeys@biboolkeys}
% #1: <mp>
% #2: keys
% #3: default value
\robust@def*\ltxkeys@biboolkeys@a#1#2[#3]{%
  \ifboolTF{ltxkeys@pl}\ltxkeys@biboolkeys@c\ltxkeys@biboolkeys@b
  {#1}{#2}{#3}%
}
% #1: <mp>
% #2: keys
% #3: default value
% #4: callback for primary boolean key
% #5: callback for secondary boolean key
\robust@def*\ltxkeys@biboolkeys@b#1#2#3#4#5{%
  \ltxkeys@biboolkeys@d{#1}{#2}{#3}%
  \ltxkeys@tempa{#4}%
  \ltxkeys@tempb{#5}%
}
% #1: <mp>
% #2: keys
% #3: default value
% #4: callback for primary boolean key
% #5: callback for secondary boolean key
% #6: callback if user-supplied value isn't valid
\robust@def*\ltxkeys@biboolkeys@c#1#2#3#4#5#6{%
  \ltxkeys@biboolkeys@d{#1}{#2}{#3}%
  \ltxkeys@tempa{#4}{#6}%
  \ltxkeys@tempb{#5}{#6}%
}
% #1: <mp>
% #2: keys
% #3: default value
\robust@def*\ltxkeys@biboolkeys@d#1#2#3{%
  \ltxkeys@ifeltcountTF[,](=)\tw@{#2}{}{%
    \ltxkeys@error{Biboolean keys '#2' not equal to 2}\ltxkeys@ehd
  }%
  \ltxkeys@commanormalize{#2}\ltxkeys@keys
  \def\ltxkeys@tempa##1,##2\ltxkeys@nil##3##4{%
    \ltxkeys@findpointers{##1}%
    \ltxkeys@debug{==}{Boolean key '\ltxkeys@tkey' is being defined}%
    \let\ltxkeys@tkeya\ltxkeys@tkey
    \ltxkeys@findpointers{##2}%
    \ltxkeys@debug{==}{Boolean key '\ltxkeys@tkey' is being defined}%
    \cptexpandarg{\cpt@newv@riables{tog}\ltxkeys@hdr}
      {\ltxkeys@tkeya,\ltxkeys@tkey}[false]%
    \cptexpandsecond\ltxkeys@biboolkeys@e
      {{\ltxkeys@tkeya}{\ltxkeys@tkey}}{#1}{#3}{##3}{##4}%
  }%
  \cptexpandsecond\ltxkeys@tempa
    {\ltxkeys@keys\ltxkeys@nil{\ltxkeys@ttpref}{\ltxkeys@tfam}}%
  \undefcs\ltxkeys@tkeya
}
% #1: primary key
% #2: secondary key
% #3: <mp>
% #4: default value
% #5: key prefix
% #6: key family
\robust@def\ltxkeys@biboolkeys@e#1#2#3#4#5#6{%
  \ifltxkeys@pl
    % For primary key:
    \long\def\ltxkeys@tempa##1##2{%
      % ##1->callback if input is valid, ##2->callback otherwise
      \aftercsname\ltxkeys@boolkey@e{\ltxkeys@hdr#1}{#1}{#3#1}{#4}{{%
        \ltxkeys@setbool\ltxkeys@resa\usename{#3#1\ltxkeys@resa}%
        ##1\relax
        \ltxkeys@biboolkeys@f{#1}{#2}{#3#1}{#5}{#6}%
      }{##2}}%
    }%
    % For secondary key:
    \long\def\ltxkeys@tempb##1##2{%
      % ##1->callback if input is valid, ##2->callback otherwise
      \aftercsname\ltxkeys@boolkey@e{\ltxkeys@hdr#2}{#2}{#3#2}{#4}{{%
        \ltxkeys@setbool\ltxkeys@resa\usename{#3#2\ltxkeys@resa}%
        ##1\relax
        \ltxkeys@biboolkeys@f{#2}{#1}{#3#2}{#5}{#6}%
      }{##2}}%
    }%
  \else
    % For primary key:
    \long\def\ltxkeys@tempa##1{%
      % ##1->callback if input is valid
      \aftercsname\ltxkeys@boolkey@e{\ltxkeys@hdr#1}{#1}{#3#1}{#4}{%
        \ltxkeys@setbool\ltxkeys@resa\usename{#3#1\ltxkeys@resa}%
        ##1\relax
        \ltxkeys@biboolkeys@f{#1}{#2}{#3#1}{#5}{#6}%
      }%
    }%
    % For secondary key:
    \long\def\ltxkeys@tempb##1{%
      % ##1->callback if input is valid
      \aftercsname\ltxkeys@boolkey@e{\ltxkeys@hdr#2}{#2}{#3#2}{#4}{%
        \ltxkeys@setbool\ltxkeys@resa\usename{#3#2\ltxkeys@resa}%
        ##1\relax
        \ltxkeys@biboolkeys@f{#2}{#1}{#3#2}{#5}{#6}%
      }%
    }%
  \fi
}
\robust@def\ltxkeys@biboolkeys@f#1#2#3#4#5{%
  % If #1 is not being called by its twin (#2):
  \iftogTF{\ltxkeys@hdr#1}{}{%
    % Set flag to show that #2 is being set within its twin (#1):
    \settogtrue{\ltxkeys@hdr#2}%
    \cptexpandarg{\ltxkeys@setkeys[#4]{#5}}{#2=\thebool@reverse{#3}}%
    \settogfalse{\ltxkeys@hdr#2}%
  }%
}
%%++
% \ltxkeys@stylekey[<pref>]{<fam>}[<mp>]{<key>}[<dft>](<deps>){<fn>}.
% The dependants <deps> have the syntax:
%   {<keytype>/<keyname>/<dft>/<callback>; another set of dependant; etc}.
%
%   <keytype> can be 'ord' (ordinary key), 'cmd' (command key), 'bool'
%   (boolean key), or 'choice' (choice key).
%
% If the *-form is used, all undefined dependants will be defined and set
% on the fly as the parent is being set. If the *-form isn't used and
% undefined dependants occur, then an error message will be flagged
% at the time the parent is being set.

% It is possible to refer to the parent key's name and current value
% (with \parentkey and \parentval) and parent key's callback
% (with full macro name) within <dft> and <callback> of <deps>.
%
% '#1' in the callback of dependant key refers to the current value of
% the dependant key.

\robust@def*\ltxkeys@stylekey{%
  \ltxkeys@swfalse
  % The test for star here is for the 2 types of style key.
  % The test for defining a default for the key is at
  % \ltxkeys@testopt@f, via \ltxkeys@testopt@e.
  \ltxkeys@testst{%
    \cpt@cnta\ifltxkeys@st1\else0\fi\relax
    \ltxkeys@testopt@e\ltxkeys@stylekey@a{style}%
  }%
}
\newletcs\ltxkeys@stylekeys\ltxkeys@stylekey
\robust@def*\ltxkeys@newstylekey{\ltxkeys@chdeftrue\ltxkeys@stylekey}
\newletcs\ltxkeys@newstylekeys\ltxkeys@newstylekey
\robust@def*\ltxkeys@stylekey@a#1#2[#3]{%
  \def\ltxkeys@macpref{#1}%
  \cpt@testpnopt{\ltxkeys@stylekey@b{#1}{#2}{#3}}{}%
}
\robust@def*\ltxkeys@stylekey@b#1#2#3(#4)#5{%
  \let\ifltxkeys@keyst\ifltxkeys@st
  \edef\ltxkeys@loopcbk##1{%
    \ltxkeys@stylekey@c{#1}{##1}\unexpanded{{#3}{#4}{#5}}%
  }%
  \ifinsetTF,{#2}{%
    \def\ltxkeys@do##1{\ltxkeys@loopcbk{##1}}%
    \ltxkeys@listparse1{#2}%
  }{%
    \ltxkeys@stylekey@c{#1}{#2}{#3}{#4}{#5}%
  }%
}
\robust@def*\ltxkeys@stylekey@c#1#2#3#4#5{%
  \ltxkeys@debug{==}{Style key '\ltxkeys@tkey' is being defined}%
  \ltxkeys@findpointers{#2}%
  \ltxkeys@checkdefkey
  \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#3}%
  \ifltxkeys@keyst
    \s@expandarg\ltxkeys@definedefault\ltxkeys@tkey{#3}%
  \fi
  \cptexpandtwoargs\ltxkeys@in
    {\detokenize\expandafter{\unexpanded\expandafter
    {\csname\ltxkeys@hdr\ltxkeys@tkey @value\endcsname}}}
    {\detokenize{#4}}%
  \csn@edef{\ltxkeys@hdr\ltxkeys@tkey @dependants}{\unexpanded{#4}}%
  \cptpassexpanded{%
    \csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1{%
      \csn@edef{#1\ltxkeys@tkey}{\noexpand\unexpanded{####1}}%
      \edef\noexpand\parentval{\noexpand\unexpanded{####1}}%
      \ifin@
        \csn@xdef{\ltxkeys@hdr\ltxkeys@tkey @value}%
          {\noexpand\unexpanded{####1}}%
      \fi
      \unexpanded{#5}\relax
      \ltxkeys@setdependants{\number\cpt@cnta}{#1}%
    }%
  }%
}

% #1: style type: '1' (*-form) or '0' (plain, non-*-form).
% #2: <macro prefix>
\robust@def*\ltxkeys@setdependants#1#2{%
  \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr\ltxkeys@tkey @dependants}%
  % If no dependants:
  \ltxkeys@ifcsemptyTF\ltxkeys@tempa{}{%
    \cpt@sttrue
    \expandafter\cpt@csvnormalize
    \expandafter[\ltxkeys@keyparser]\ltxkeys@tempa
    % If we're in \ltxkeys@declarekeys, don't set dependants
    % when setting up defaults:
    \ifboolTF{ltxkeys@dec}{}{%
      \cptexpandargonce{\ltxkeys@s@tdependants{#1}{#2}}\ltxkeys@tempa
    }%
  }%
}
\robust@def*\ltxkeys@s@tdependants#1#2#3{%
  \begingroup
  \toks0{}\toks1{}\toks2{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@s@td@pendants{##1}%
    \ltxkeys@s@td@p@ndants{#1}%
  }%
  \cptexpandsecond{\ltxkeys@listparse0}{[\ltxkeys@keyparser]}{#3}%
  % We're in a group: so \ifblankTF can be temporarily redefined:
  \let\ifblankTF\relax
  \cptpassexpanded{%
    \endgroup
    % If we're in dependant keys, use the user-supplied value
    % of parent key to initialize the slave key in \ltxkeys@declarekeys:
    \noexpand\ltxkeys@deptrue
    \ifblankTF{\the\toks0}{}%
      {\ltxkeys@setkeys[\expandcsonce\ltxkeys@ttpref]%
        {\expandcsonce\ltxkeys@tfam}{\the\toks0}}%
    \ifblankTF{\the\toks1}{}%
      {\ltxkeys@declarekeys[\ltxkeys@ttpref]%
      {\ltxkeys@tfam}[#2]{\the\toks1}}%
    \ifblankTF{\the\toks2}{}{%
      \ltxkeys@err{Undefined dependant keys: ||\the\toks2||}
        {I have come across undefined dependant keys. You can
        \MsgBrk use the star (*) form of '\string\ltxkeys@stylekey'
        \MsgBrk to define and set dependant keys on the fly.
      }%
    }%
  }%
  \ltxkeys@depfalse
}
\robust@def*\ltxkeys@s@td@pendants#1{%
  \begingroup
  \def\key@name{}\def\key@default{}\def\key@callback{}%
  % '#1' may come with nested parameters that will make it
  % impossible to include '#1' directly in \temp@err.
  % So we put '#1' in a token register:
  \@temptokena{#1}%
  \def\ltxkeys@splita##1/##2/{%
    \ifblankTF{##1##2}{%
      % No keys to read (remove forward slashes):
      \ltxkeys@err{Something is wrong with dependant keys}\ltxkeys@ehd
      \expandafter\gobble@to@sentinel\expandafter
        \ltxkeys@nil\ltxkeys@keyparser
    }{%
      \ltxkeys@trimspaces{##1}\key@type
      % To avoid back-linking, a style key can't have another
      % style key as a dependant:
      \expandafter\ltxkeys@striplaststar
        \key@type\@empty*\@empty\ltxkeys@nil\key@type
      \xifstrcmpFT\key@type{sty}{}{%
        \ltxkeys@err{A dependant key can't have dependants:
          ||\the\@temptokena||}\ltxkeys@ehd
      }%
      \xifinsetTF\key@type{,ord,cmd,bool,choice,}{}{%
        \ltxkeys@err{Invalid key type '\key@type' in dependant key(s)
          ||\the\@temptokena||}\ltxkeys@ehd
      }%
      \ifblankTF{##2}{%
        \ltxkeys@err{Empty key name in dependant key(s)
          ||\the\@temptokena||}\ltxkeys@ehd
      }{%
        \ltxkeys@findpointers{##2}%
        \let\key@name\ltxkeys@tkey
      }%
      \ltxkeys@ifrejname{%
        \ltxkeys@err{Wrong syntax for dependant keys}\ltxkeys@ehd
      }%
      \ltxkeys@splitb.%
    }%
  }%
  \def\ltxkeys@splitb##1/##2/##3\ltxkeys@nil{%
    \edef\key@default{\expandcsonce{\@gobble##1}}%
    \ltxkeys@trimspacesincs\key@default
    \xifstrcmpTF{\cptoxdetok\key@default}{\detokenize{\parentval}}{%
      \edef\key@default{\expandcstwice\key@default}%
    }{}%
    \edef\key@callback{\unexpanded{##2}}%
    \ltxkeys@stripdotcode\key@callback
  }%
  \ltxkeys@splita#1/^?^/^?^/^?^/\ltxkeys@nil
  \let\do\cpt@csexit
  \cptpassexpanded{%
    \endgroup
    \do\key@type\do\key@name\do\key@default\do\key@callback
  }%
}
\robust@def*\ltxkeys@s@td@p@ndants#1{%
  \ifcsndefTF{\ltxkeys@hdr\key@name}{%
    \cptpassexpanded{%
      \toks0{\the\toks0\oifblankTF{\the\toks0}{}{,}%
        \expandcsonce\key@name=\expandcsonce\key@default}%
    }%
  }{%
    \cptpassexpanded{%
      % Test if the parent was defined with the
      % *-form of \ltxkeys@stylekey, ie, if #1=1 or 0:
      \ifnum\numexpr#1=\@ne
        \toks1{%
          \the\toks1\oifblankTF{\the\toks1}{}{\ltxkeys@keyparser}%
          \key@type/\expandcsonce\key@name
          \ifx\key@default\ltxkeys@rej\else/\expandcsonce\key@default\fi
          \ifx\key@callback\ltxkeys@rej\else/\expandcsonce\key@callback\fi
        }%
      \else
        \toks2{\the\toks2\oifblankTF{\the\toks2}{}{,}%
          \expandcsonce\key@name}%
      \fi
    }%
  }%
}

%%++
% \ltxkeys@choicekey*+![<pref]{<fam>}[<mp>]{<key>}[<bin>]{<alt>}[<dft>]{<f1>}{<f2>}
% If <mp> is absent, then \ltxkeys@choicekey uses \chc<pref>@<family>@<key>
% to hold user input.
%
% When there are no callbacks in <alt> ist has the syntax
% {choice1, choice2, etc}.
%
% But when <alt> has callbacks, it has the syntax:
% {choice1/.code=callback1; choice2/.code=callback2; etc}.
%
% It is possible to refer to the current value of <key> as '#1' in <alt>.
%
\robust@def*\ltxkeys@choicekey{%
  \ltxkeys@swfalse
  \ltxkeys@suffixcheck{\ltxkeys@teststpl{\ltxkeys@testcl
    {\ltxkeys@testopt@a{\cpt@testopt\ltxkeys@choicekey@a
    {chc\ltxkeys@hdr}}}}}%
}
\newletcs\ltxkeys@choicekeys\ltxkeys@choicekey
\robust@def*\ltxkeys@newchoicekey{\ltxkeys@chdeftrue\ltxkeys@choicekey}
\newletcs\ltxkeys@newchoicekeys\ltxkeys@newchoicekey
% #1: <mp> (prefix for user-input holder) name;
% #2: keynames
\robust@def*\ltxkeys@choicekey@a[#1]#2{%
  \edef\ltxkeys@macpref{#1}%
  \begingroup
  \catcode`\=\string=12\catcode`\,=12
  \catcode`\;=12\catcode`\.=12
  \cpt@testopt{\expandafter\endgroup\ltxkeys@choicekey@b{#1}{#2}}{}%
}
% #3: bin
% #4 alt values
\robust@def*\ltxkeys@choicekey@b#1#2[#3]#4{%
  \ifblankTF{#4}{%
    \ltxkeys@err{Choice key can't have empty nominations}\ltxkeys@ehd
  }{}%
  % Make \ltxkeys@chclist for the choice key:
  \ltxkeys@makechclist{#4}{0}%
  \cpt@ifbrack{%
    \ltxkeys@sttrue\ltxkeys@bracedefault
      {\ltxkeys@choicekey@c{#1}{#2}{#3}{#4}}%
  }{%
    \ltxkeys@stfalse\ltxkeys@choicekey@c{#1}{#2}{#3}{#4}[]%
  }%
}
% #1: mp, #2: keynames, #3: bin, #4: alt, #5: default
\robust@def*\ltxkeys@choicekey@c#1#2#3#4[#5]{%
  \ltxkeys@commanormalize{#2}\ltxkeys@tempa
  \edef\ltxkeys@tempa{\unexpanded{{#1}}{\expandcsonce\ltxkeys@tempa}}%
  \cptexpanded{%
    \noexpand\expandafter
    \ifltxkeys@pl\ltxkeys@choicekey@f\else\ltxkeys@choicekey@e\fi
  }%
  \ltxkeys@tempa{#3}{#4}{#5}%
}
% #1: mp, #2: keyname, #3: default
\robust@def*\ltxkeys@choicekey@d#1#2#3{%
  \ltxkeys@findpointers{#2}%
  \ltxkeys@debug{==}{Choice key '\ltxkeys@tkey' is being defined}%
  \ltxkeys@checkdefkey
  \ifltxkeys@st\ltxkeys@definedefault\ltxkeys@tkey{#3}\fi
  \ltxkeys@saveinitialkeyvals{choice}\ltxkeys@tkey{#3}%
  \edef\ltxkeys@resa##1##2##3{%
    \ltxkeys@choicekey@g\cptmakecs{\ltxkeys@hdr\ltxkeys@tkey}%
    {#1\ltxkeys@tkey}{##1}{##2}{##3}%
  }%
}
% #1: mp, #2: keynames, #3: bin, #4: alt, #5: default, #6: cbk
\robust@def*\ltxkeys@choicekey@e#1#2#3#4#5#6{%
  \edef\ltxkeys@loopcbk##1{%
    \ltxkeys@choicekey@d{#1}{##1}\unexpanded{{#5}}%
    \noexpand\ltxkeys@resa\unexpanded{{#3}{#4}{{#6}}}%
  }%
  \ifinsetTF,{#2}{%
    \def\ltxkeys@do##1{%
      \ltxkeys@loopcbk{##1}%
    }%
    \ltxkeys@listparse1{#2}%
  }{%
    \ltxkeys@loopcbk{#2}%
  }%
}
% #1: mp, #2: keyname, #3: bin, #4: alt, #5: default, #6: cbk1, #7: cbk2
\robust@def*\ltxkeys@choicekey@f#1#2#3#4#5#6#7{%
  \edef\ltxkeys@loopcbk##1{%
    \ltxkeys@choicekey@d{#1}{##1}\unexpanded{{#5}}%
    \noexpand\ltxkeys@resa\unexpanded{{#3}{#4}{{#6}{#7}}}%
  }%
  \ifinsetTF,{#2}{%
    \def\ltxkeys@do##1{%
      \ltxkeys@loopcbk{##1}%
    }%
    \ltxkeys@listparse1{#2}%
  }{%
    \ltxkeys@loopcbk{#2}%
  }%
}
% #1: keymacro, #2: mp+keyname, #3: bin, #4: alt, #5: cbk
\robust@def*\ltxkeys@choicekey@g#1#2#3#4#5{%
  \ifinsetTF{/.code=}{#4}{%
    \def\ltxkeys@tempa{\ltxkeys@executechclist}%
  }{%
    \ifinsetTF{/}{#4}{%
      \def\ltxkeys@tempa{\ltxkeys@executechclist}%
    }{%
      \def\ltxkeys@tempa{\@gobble}%
    }%
  }%
  \edef#1{%
    \csn@edef{#2}{\noexpand\unexpanded{####1}}%
    \cptmakecs{cpt@st\ifltxkeys@st true\else false\fi}%
    \cptmakecs{cpt@pl\ifltxkeys@pl true\else false\fi}%
    \ifltxkeys@cl
      \edef\noexpand\reserved@a{####1}%
    \else
      \edef\noexpand\reserved@a{\noexpand\unexpanded{####1}}%
    \fi
    \def\noexpand\reserved@b{\unexpanded{\ltxkeys@cc@b,(#3)}}%
    \unexpanded{\expandafter\reserved@b\expandafter{\reserved@a}}%
    {\expandcsonce\ltxkeys@chclist}\unexpanded{#5}%
    \expandcsonce\ltxkeys@tempa{\unexpanded{#4}}%
  }%
  % Believe it or not, this is one of the tricks that works:
  \def\ltxkeys@tempa{\def#1####1}%
  \expandafter\ltxkeys@tempa\expandafter{#1}%
}
% Make the list of valid alternate values of a choice key:
% #1: alt-list (containing choice callbacks)
% #2: caller identifier (0 for defining, 1 for setting key)
\robust@def*\ltxkeys@makechclist#1#2{%
  \begingroup
  \def\ltxkeys@chclist{}%
  \def\ltxkeys@tempb##1/.code=##2\ltxkeys@nil{%
    \ltxkeys@tempd{##1}{##2}%
  }%
  \def\ltxkeys@tempc##1/##2/##3\ltxkeys@nil{%
    \ltxkeys@tempd{##1}{##2}%
  }%
  \def\ltxkeys@tempd##1##2{%
    \ltxkeys@remdottrimspaces{##1}\ltxkeys@tempa
    \ifcase#2\relax
      % We're defining a choice key:
      \cptaddtolist*[,]\ltxkeys@chclist\ltxkeys@tempa
    \or
      % We're setting a choice key:
      \cptexpandarg\lowercase{%
        \def\noexpand\ltxkeys@tempa{\expandcsonce\ltxkeys@tempa}%
        \def\noexpand\ltxkeys@tval{\expandcsonce\ltxkeys@tval}%
      }%
      % The comparison must be catcode agonistic:
      \oifstrcmpTF\ltxkeys@tempa\ltxkeys@tval{%
        \edef\ltxkeys@chclist{\unexpanded{##2}}%
        \loopbreak
      }{}%
    \else
      \ltxkeys@err{Invalid number '#2' while
        in \string\ltxkeys@makechclist}\ltxkeys@ehd
    \fi
  }%
  \def\ltxkeys@do##1{%
    \ifinsetTF{/.code=}{##1}{%
      \ltxkeys@tempb.##1\ltxkeys@nil
    }{%
      \ltxkeys@tempc.##1//\ltxkeys@nil
    }%
  }%
  \expandafter\ifinsetTF\expandafter{\ltxkeys@keyparser}{#1}{%
    \cptexpandsecond{\ltxkeys@listparse1}{[\ltxkeys@keyparser]}{#1}%
  }{%
    \ifinsetTF{,}{#1}{%
      \ltxkeys@listparse1[,]{#1}%
    }{%
      \ltxkeys@listparse1[,]{#1,}%
    }%
  }%
  \postgroupdef\ltxkeys@chclist\endgroup
}
% Execute the callback for alternate values of a choice key:
% #1: alt-list (containing choice callbacks)
\robust@def*\ltxkeys@executechclist#1{%
  \begingroup
  \ltxkeys@makechclist{#1}{1}%
  \expandafter\endgroup\ltxkeys@chclist
}
% #1: key name
% #2: default value
\robust@def*\ltxkeys@definedefault#1#2{%
  \xifstrcmpTF{\detokenize{#2}}{\detokenize{\parentval}}{%
    \s@expandarg\ltxkeys@trimspaces{#2}\ltxkeys@tempa
  }{%
    \ltxkeys@trimspaces{#2}\ltxkeys@tempa
  }%
  \csn@edef{\ltxkeys@hdr#1@default}{%
    \noexpandcsn{\ltxkeys@hdr#1}{\expandcsonce\ltxkeys@tempa}%
  }%
}
\robust@def*\ltxkeys@getkeyname#1=#2\ltxkeys@nil#3{%
  \ltxkeys@findpointers{#1}%
  \let#3\ltxkeys@tkey
}
\robust@def*\ltxkeys@getkeynames#1{%
  \begingroup
  \def\ltxkeys@keynames{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tempa
    \edef\ltxkeys@keynames{%
      \csliststack,\ltxkeys@keynames\expandcsonce\ltxkeys@tempa
    }%
  }%
  \ifblankTF{#1}{}{\ltxkeys@listparse3{#1}}%
  \postgroupdef\ltxkeys@keynames\endgroup
}
\robust@def*\ltxkeys@getkeyvalue#1=#2\ltxkeys@nil#3{%
  \ifinsetTF{=\ltxkeys@nil}{#2\ltxkeys@nil}{%
    \ltxkeys@novaluefalse
    \begingroup
    \def\ltxkeys@tempa##1=##2\ltxkeys@nil{\endgroup
%      \s@expandarg\ltxkeys@trimspaces{\@gobble##1}#3%
      \ltxkeys@remdottrimspaces{##1}#3%
      \let\CurrentVal#3%
    }%
    \ltxkeys@tempa.#2\ltxkeys@nil
  }{%
    \ltxkeys@novaluetrue\def#3{}%
  }%
}
\robust@def*\ltxkeys@splitkeyval#1\ltxkeys@nil#2#3{%
  \ltxkeys@getkeyname#1=\ltxkeys@nil#2%
  \ltxkeys@getkeyvalue#1=\ltxkeys@nil#3%
}
% Keys that must (or not) appear in \usepackage and \RequirePackage:
% \ltxkeys@optionkeys[<prf>]{<fam>}{<keys>}
\robust@def*\ltxkeys@optionkeys{%
  \ltxkeys@notinpkgclserr\ltxkeys@optionkeys
  \cpt@testst\ltxkeys@opti@nkeys
}
\robust@def*\ltxkeys@opti@nkeys{%
  \ifboolTF{cpt@st}{%
    \ltxkeys@testopt@g{opti@nk@ys}{non}%
  }{%
    \ltxkeys@testopt@g{opti@nk@ys}{}%
  }%
}
\robust@def*\ltxkeys@nonoptionkeys#1{%
  \ltxkeys@notinpkgclserr\ltxkeys@nonoptionkeys
  \ifstrcmpTF{#1}{*}{%
    \ltxkeys@warn{No star form of \string\ltxkeys@nonoptionkeys:
      \MsgBrk star (*) ignored}%
    \ltxkeys@testopt@g{opti@nk@ys}{non}%
  }{%
    \ifsingletokenTF{#1}{%
      \ltxkeys@testopt@g{opti@nk@ys}{non}#1%
    }{%
      \ltxkeys@testopt@g{opti@nk@ys}{non}{#1}%
    }%
  }%
}
\robust@def*\ltxkeys@opti@nk@ys#1#2{%
  \def\ltxkeys@do##1{%
    \ifcsndefTF{\ltxkeys@hdr##1}{%
      \ifcsndefTF{\ltxkeys@hdr#1optionkeys}{%
        \xifinsetTF{,\detokenize{##1},}
          {,\cptsxdetok{\usename{\ltxkeys@hdr#1optionkeys}},}{}{%
          \csn@edef{\ltxkeys@hdr#1optionkeys}{%
            \expandcsnonce{\ltxkeys@hdr#1optionkeys},%
            \unexpanded{##1}%
          }%
        }%
      }{%
        \csn@def{\ltxkeys@hdr#1optionkeys}{##1}%
      }%
    }{%
      \ltxkeys@err{Key '##1' is undefined in family '\ltxkeys@tfam'}
        {Only defined keys can be made '#1option' keys.}%
    }%
  }%
  \ltxkeys@listparse1{#2}%
}
% Make defined keys option-keys from their <pref> and <fam>.
% The starred (*) variant makes non-option keys.
\robust@def*\ltxkeys@makeoptionkeys{%
  \cpt@teststopt\ltxkeys@m@keoptionkeys{KV}%
}
\robust@def*\ltxkeys@m@keoptionkeys[#1]#2{%
  \let\ifltxkeys@keyst\ifcpt@st
  \ifcsndefTF{#1@#2@initialkeyvals}{%
    \letcstocsn\ltxkeys@tempa{#1@#2@initialkeyvals}%
  }{%
    \ltxkeys@err{No initial key-values for family '#2'}\ltxkeys@ehd
  }%
  \s@expandarg\ltxkeys@getkeynames\ltxkeys@tempa
  \ltxkeys@ifcsemptyTF\ltxkeys@keynames{}{%
    \cptexpandargonce
      {\usename{ltxkeys@\ifltxkeys@keyst non\fi optionkeys}[#1]{#2}}
      \ltxkeys@keynames
  }%
}
\robust@def*\ltxkeys@makenonoptionkeys{%
  \cpt@sttrue\cpt@testopt\ltxkeys@m@keoptionkeys{KV}%
}
\robust@def*\ltxkeys@handledkeys{%
  \ltxkeys@testopt@g{h@ndledkeys}{handled}%
}
\newletcs\ltxkeys@addhandledkeys\ltxkeys@handledkeys
\robust@def*\ltxkeys@removehandledkeys{%
  \ltxkeys@testopt@g{rem@vehandledkeys}{handled}%
}
\robust@def*\ltxkeys@undefhandledkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{undefh@ndledkeys}{handled}}%
}
\robust@def*\ltxkeys@emptifyhandledkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{emptifyh@ndledkeys}{handled}}%
}
\robust@def*\ltxkeys@savevaluekeys{%
  % \<KV>@<fam>@savevalue@keys is used by pointed keys.
  \ltxkeys@testopt@g{h@ndledkeys}{savevalue}%
}
\newletcs\ltxkeys@addsavevaluekeys\ltxkeys@savevaluekeys
\robust@def*\ltxkeys@removesavevaluekeys{%
  \ltxkeys@testopt@g{rem@vehandledkeys}{savevalue}%
}
\robust@def*\ltxkeys@undefsavevaluekeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{undefh@ndledkeys}{savevalue}}%
}
\robust@def*\ltxkeys@emptifysavevaluekeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{emptifyh@ndledkeys}{savevalue}}%
}
\robust@def*\ltxkeys@h@ndledkeys#1#2{%
  \letcstocsn\ltxkeys@rsvda{\ltxkeys@hdr#1keys}%
  \def\ltxkeys@do##1{%
    \ifcsndefTF{\ltxkeys@hdr##1}{%
      \def\ltxkeys@tempb{##1}%
      \ifdefTF\ltxkeys@rsvda{%
        \oifinset@sp@TF,\ltxkeys@tempb\ltxkeys@rsvda{}{%
          \edef\ltxkeys@rsvda{%
            \csliststack,\ltxkeys@rsvda\unexpanded{##1}%
          }%
        }%
      }{%
        \let\ltxkeys@rsvda\ltxkeys@tempb
      }%
    }{%
      \ltxkeys@err{Key '##1' is undefined in family
        '\ltxkeys@tfam'}
        {Only defined keys can be made #1-keys.}%
    }%
  }%
  \ltxkeys@listparse1{#2}%
  \letcsntocs{\ltxkeys@hdr#1keys}\ltxkeys@rsvda
}
\robust@def*\ltxkeys@rem@vehandledkeys#1#2{%
  \letcstocsn\ltxkeys@rsvda{\ltxkeys@hdr#1keys}%
  \ifdefTF\ltxkeys@rsvda{%
    \def\ltxkeys@do##1{%
      \ifcsndefTF{\ltxkeys@hdr##1}{%
        \def\ltxkeys@tempb{##1}%
        \oifinset@sp@TF,\ltxkeys@tempb\ltxkeys@rsvda{%
          \let\cpt@fromrem\cptswtrue\cpt@sttrue
          \cpt@removeoneelement[,]\ltxkeys@rsvda{##1}%
        }{%
          \ltxkeys@warn{Key '##1' with prefix '\ltxkeys@ttpref'
            in family\MsgBrk '\ltxkeys@tfam' is not a #1 key:
            \MsgBrk It couldn't be deleted from #1-keys list.}%
        }%
      }{%
        \ltxkeys@err{Key '##1' with prefix '\ltxkeys@ttpref' in
          family\MsgBrk '\ltxkeys@tfam' is not defined.}
          {I couldn't delete #1-keys.}%
      }%
    }%
    \ltxkeys@listparse1{#2}%
  }{%
    \ltxkeys@err{No #1 keys for family '\ltxkeys@tfam'}%
      {No #1 keys exist for prefix '\ltxkeys@ttpref' and
      \MsgBrk family '\ltxkeys@tfam'.}%
  }%
  \letcsntocs{\ltxkeys@hdr#1keys}\ltxkeys@rsvda
}
\robust@def*\ltxkeys@undefh@ndledkeys#1{%
  \ifcsndefTF{\ltxkeys@hdr#1keys}{%
    \usename{\ifltxkeys@cl g\fi undefcsn}{\ltxkeys@hdr#1keys}%
  }{%
    \ltxkeys@err{No #1 keys for prefix '\ltxkeys@ttpref'
      \MsgBrk and family '\ltxkeys@tfam'}
      {I couldn't undefine #1-keys.}%
  }%
}
\robust@def*\ltxkeys@emptifyh@ndledkeys#1{%
  \ifcsndefTF{\ltxkeys@hdr#1keys}{%
    \usename{\ifltxkeys@cl g\fi emptifycsn}{\ltxkeys@hdr#1keys}%
  }{%
    \ltxkeys@err{No #1 keys for prefix '\ltxkeys@ttpref'
      \MsgBrk and family '\ltxkeys@tfam'}
      {I couldn't emptify #1-keys.}%
  }%
}
\robust@def*\ltxkeys@iftkeyinlist#1{%
  \ifcsndefTF{\ltxkeys@hdr#1}{%
    \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr#1}%
    \oifinset@sp@TF,\ltxkeys@tkey\ltxkeys@tempa
  }{%
    \@secondoftwo
  }%
}
\robust@def*\ltxkeys@testsavevaluekey{%
  \ltxkeys@debug{==}{Testing if '\ltxkeys@tkey' is a savevalue key}%
  \ltxkeys@iftkeyinlist{savevaluekeys}{%
    \ltxkeys@svtrue
  }{%
    \ltxkeys@svfalse
    \ltxkeys@debug{==}{'\ltxkeys@tkey' is not a savevalue key}%
  }%
}
% Test for option or non-option keys:
\robust@def*\ltxkeys@testoptionkey#1{%
  \begingroup
  \def\ltxkeys@tempc{\ifstrcmpTF{#1}{non}{not }{}}%
  \def\ltxkeys@tempd{\ifstrcmpTF{#1}{non}{}{not }}%
  \ltxkeys@debug{==}{Testing if '\ltxkeys@tkey' is
    \ltxkeys@tempc option key}%
  \ltxkeys@iftkeyinlist{#1optionkeys}{%
    \ltxkeys@err
    {The following key should \ltxkeys@tempc
    appear in \noexpand\usepackage or \string\RequirePackage:
    ||\ltxkeys@ttpref, \ltxkeys@tfam, \ltxkeys@tkey||}%
    {\ltxkeys@tempc option key error.}%
  }{%
    \ltxkeys@debug{==}{Key '\ltxkeys@tkey' is
      \ltxkeys@tempd option key}%
  }%
  \endgroup
}
\robust@def*\ltxkeys@testneedvaluekey{%
  \ltxkeys@debug{==}{Testing if '\ltxkeys@tkey' is a needvalue key}%
  \ltxkeys@iftkeyinlist{needvaluekeys}{%
    \ltxkeys@err{You're required to supply a value for
      \MsgBrk key '\ltxkeys@tkey' in family '\ltxkeys@tfam'}
      {Please supply a value for key '\ltxkeys@tkey' of families
      \MsgBrk'\ltxkeys@fams' and rerun. The author of this key
      \MsgBrk meant it to require a user value.}%
  }{%
    \ltxkeys@debug{==}{'\ltxkeys@tkey' is not a
      needvalue key}%
  }%
}
\robust@def*\ltxkeys@setbool#1{%
  \xifstrcmpTF{#1}{on}{%
    \def#1{true}%
  }{%
    \xifstrcmpTF{#1}{off}{%
      \def#1{false}%
    }{%
      \edef#1{#1}%
    }%
  }%
}

% Gather keys and their values for use in (declaring
% or defining keys). \key@vals must have been initialized
% by the caller.
%
% #1: default value
% #2: Key macro (for testing if it contains '\ltxkeys@setaliaskey').
% If the key macro contains '\ltxkeys@setaliaskey', then the key is a
% twin/alias key:
\robust@def*\ltxkeys@accumkeyvals#1#2{%
  \ifblankTF{#1}{%
    \ltxkeys@twkfalse
  }{%
    \ltxkeys@ifinlistTF(1){\ltxkeys@setaliaskey,\setaliaskey}{#2}%
      {\ltxkeys@twktrue}{\ltxkeys@twkfalse}%
  }%
  \begingroup
  \edef\elt{\ifblankTF{#1}{}{\unexpanded{#1}}}%
  \edef\key@vals{%
    \csliststack,\key@vals\expandcsonce\key@name=%
    \ifltxkeys@dep
    % We're dealing with a dependant key; use the user-supplied value:
      \expandcsonce\elt
    \else
      \ifstrcmpTF{#1}{true}{false}{\expandcsonce\elt}%
    \fi
  }%
  % Set slave key with master when 'ltxkeys@ssk' is true, whether
  % or not the key macro contains '\ltxkeys@setaliaskey':
  \ifltxkeys@ssk
    \gletcs\key@vals\key@vals
  \else
    % If the key macro contains '\ltxkeys@setaliaskey', don't include
    % it in the list:
    \ifltxkeys@twk\else
      \gletcs\key@vals\key@vals
    \fi
  \fi
  \endgroup
}
% Define boolean and command keys compactly & robustly:
% 1.  \ltxkeys@definekeys[pref]{<fam>}[macropf]{<keyname>=<dft>
%       /<callback>; ...}.
%     Key default value and macro can be absent,
%     but boolean keys must have values (<true> | <false>),
%     to be distinguishable from cmd keys.
% 2.  Use \ltxkeys@checkchoice or \CheckUserInput to introduce
%     choice keys as command keys.
% 3.  Ordinary and choice keys can't be introduced directly by
%     this command (use \ltxkeys@declarekeys).
% 4.  The *-form can be used to define new keys (in the sense
%     of \newcommand).
\robust@def*\ltxkeys@definekeys{%
  \begingroup
  \endlinechar\m@one
  \cpt@teststopt\ltxkeys@definekeys@a{KV}%
}
\robust@def*\ltxkeys@definekeys@a[#1]#2{%
  \gletcs\ifltxkeys@keyst\ifcpt@st
  \cpt@testopt{\expandafter\endgroup\ltxkeys@definekeys@b{#1}{#2}}{}%
}
\robust@def*\ltxkeys@definekeys@b#1#2[#3]#4{%
  \ltxkeys@makepf{#1}%
  \ltxkeys@makehdr{#2}%
  \ltxkeys@dectrue
  \begingroup
  \ltxkeys@trimspacesset{%
    {#1}\key@pref,{#2}\key@fam,{#3}\macro@pref
  }%
  \toks@{}%
  \def\key@vals{}%
  % We want \ltxkeys@definekeys to have a slightly different
  % syntax to \ltxkeys@declarekeys. So we use '=' here. But
  % the equality sign can always be replaced with '/' and
  % this won't cause any problems:
  \def\ltxkeys@splita##1={\ltxkeys@splitc##1/.}%
  \def\ltxkeys@splitb##1/{\ltxkeys@splitc##1/.}%
  \def\ltxkeys@splitc##1/##2/##3/##4\ltxkeys@nil{%
    \ifblankTF{##1}{%
      \ltxkeys@err{Empty key name while in
        \string\ltxkeys@definekeys}\ltxkeys@ehd
    }{%
      \ltxkeys@findpointers{##1}%
      \let\key@name\ltxkeys@tkey
      \ifltxkeys@keyst
        \ifcsndefFT{\ltxkeys@iffirstnull\key@pref @%
          \ltxkeys@iffirstnull\key@fam @\key@name
        }{}{%
          \ltxkeys@err{Key '\key@name' already defined in family
            \MsgBrk '\iflacus#2\dolacus???\else#2\fi' with prefix
            '\iflacus#1\dolacus???\else#1\fi'}\ltxkeys@ehd
        }%
      \fi
      \oifblankTF{\@gobble##2}{%
        \def\key@default{}%
      }{%
        \ltxkeys@remdottrimspaces{##2}\key@default
      }%
      \edef\key@callback{\unexpanded{##3}}%
      \ltxkeys@stripdotcode\key@callback
      \cptexpandsecond\ltxkeys@accumkeyvals{%
        {\ifx\key@default\ltxkeys@rej\else\expandcsonce\key@default\fi}%
        {\ifx\key@callback\ltxkeys@rej\else\expandcsonce\key@callback\fi}%
      }%
      \def\defwith{\ltxkeys@boolkey}%
      \oifstrcmpTF\key@default{true}{}{%
        \oifstrcmpTF\key@default{false}{}{%
          \def\defwith{\ltxkeys@cmdkey}%
        }%
      }%
      \cptexpanded{%
        \toks@{\the\toks@
          \cptmakecs{ltxkeys@twk\ifltxkeys@twk true\else false\fi}%
          \defwith[\key@pref]{\key@fam}%
          \ifx\macro@pref\@empty\else[\macro@pref]\fi
          {\expandcsonce\key@name}%
          \ifx\key@default\ltxkeys@rej\else[\expandcsonce\key@default]\fi
          \ifx\key@callback\ltxkeys@rej{}\else{\expandcsonce\key@callback}\fi
        }%
      }%
    }%
  }%
  \def\ltxkeys@do##1{%
    \ltxkeys@removedotcode{##1}\ltxkeys@tempa
    \expandafter\ltxkeys@in\expandafter*\expandafter
    =\expandafter{\ltxkeys@tempa}{%
      \expandafter\ltxkeys@splita\ltxkeys@tempa/^?^/^?^/\ltxkeys@nil
    }{%
      \expandafter\ltxkeys@splitb\ltxkeys@tempa/^?^/^?^/\ltxkeys@nil
    }%
  }%
  \cptexpandsecond{\ltxkeys@listparse1}{[\ltxkeys@keyparser]}{#4}%
  % Define and initialize the keys here directly:
  \cptexpandsecond\endgroup{%
    \the\toks@
    \noexpand\ltxkeys@twkfalse
    \ltxkeys@ifcsemptyTF\key@vals{}{%
      \noexpand\ltxkeys@setkeys[\key@pref]%
      {\key@fam}{\expandcsonce\key@vals}%
    }%
  }%
  \ltxkeys@decfalse
}
\new@def*\ltxkeys@badkeytypes{}
% Robustly define keys of all types by one command:
% 1.  \ltxkeys@declarekeys[pref]{<fam>}[macropf]{<keytype>/<keyname>
%       /<dft>/<callback><parser> ...}.
%     Key default and macro can be absent.
% 2.  keytype = <ord> | <cmd> | <sty> | <sty*> | <bool> | <choice>.
% 3.  Choice keys must have their names associated with
%     their admissible values in the format <keyname.chclist>.
% 4.  * -> We're defining new keys (in the sense of \newcommand).
%
% Example:
%   \ltxkeys@declarekeys*[KV]{<fam>}[mp@]{%
%     cmd/keya/mm/\def\x##1{##1*#1*##1};
%     bool/keyb;
%     sty/keyc/xxx/\def\y##1{##1yyy#1};
%     sty*/keyd/mm/\def\y##1{##1#1}/cmd>keye>#1>\def\z####1{####1+##1+####1}
%   }
%   Notice the >...> for the dependant key attributes.
%
\robust@def*\ltxkeys@declarekeys{%
  \begingroup
  \endlinechar\m@one
  \cpt@testst{\cpt@testpnopt\ltxkeys@declarekeys@a{}}%
}
\robust@def*\ltxkeys@declarekeys@a(#1){%
  \cpt@testopt{\ltxkeys@declarekeys@b{#1}}{KV}%
}
\robust@def*\ltxkeys@declarekeys@b#1[#2]#3{%
  \gletcs\ifltxkeys@keyst\ifcpt@st
  \cpt@testopt{\expandafter\endgroup
    \ltxkeys@declarekeys@c{#1}{#2}{#3}}{}%
}
\robust@def*\ltxkeys@declarekeys@c#1#2#3[#4]#5{%
  \ltxkeys@makepf{#2}%
  \ltxkeys@makehdr{#3}%
  \ltxkeys@dectrue
  \begingroup
  \ltxkeys@trimspacesset{{#2}\key@pref,{#3}\key@fam,{#4}\macro@pref}%
  \def\key@vals{}\toks@{}%
  \def\ltxkeys@splita##1/##2/{%
    \ifescapedTF{##1}{%
      \ltxkeys@err{Key type can't be a macro: '\detokenize{##1}'}%
      \ltxkeys@ehd
    }{}%
    \ltxkeys@trimspacesset{{##1}\key@type,{##2}\key@name}%
    \xifstrcmpTF\key@type{choice}{%
      \expandafter\ltxkeys@splitchoice\expandafter{\key@name}%
    }{}%
    \xifinsetTF{=}{\cptoxdetok\key@type}{%
      \ltxkeys@err{The syntax of \noexpand\ltxkeys@definekeys may
        \MsgBrk have been used for \string\ltxkeys@declarekeys.
        \MsgBrk This may have come from \noexpand\ltxkeyscmd or
        \MsgBrk \string\ltxkeysenv}\ltxkeys@ehd
    }{}%
    \ifx\key@type\@empty
      \ltxkeys@err{Empty key type in \string\ltxkeys@declarekeys}
      \ltxkeys@ehd
    \fi
    \ifx\key@name\@empty
      \ltxkeys@err{Empty key name in \string\ltxkeys@declarekeys}%
      \ltxkeys@ehd
    \fi
    \ltxkeys@ifrejname{%
      \ltxkeys@err{Wrong use syntax for \string\ltxkeys@declarekeys}%
      \ltxkeys@ehd
    }%
    \ifltxkeys@inkeycmd
      \xifstrcmpFT\key@type{ord}{}{\def\key@type{cmd}}%
    \fi
    \expandafter\ltxkeys@findpointers\expandafter{\key@name}%
    \let\key@name\ltxkeys@tkey
    \ifx\key@type\key@name
      \ltxkeys@err{Key type '\key@type' and key name '\key@name'
        are identical}{Maybe you gave key type both in parenthesis
        and in key list.}%
    \fi
    \ifltxkeys@keyst
      \ifcsndefFT{\ltxkeys@hdr\key@name}{}{%
        \ltxkeys@err{Key '\key@name' already defined in family
          \MsgBrk '\iflacus#3\dolacus???\else#3\fi' with prefix
          '\iflacus#2\dolacus???\else#2\fi'}\ltxkeys@ehd
      }%
    \fi
    \ltxkeys@splitb.%
  }%
  \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{%
    \edef\key@default{\expandcsonce{\@gobble##1}}%
    \ltxkeys@ifcsemptyTF\key@default{%
      \xifstrcmpTF\key@type{bool}{\def\key@default{true}}{}%
    }{%
      \ltxkeys@trimspacesincs\key@default
    }%
    \xifstrcmpTF\key@type{bool}{%
      \ifx\key@default\ltxkeys@rej
        \def\key@default{true}%
        \ltxkeys@debug{!!}{Boolean key '\key@name'
          has no default; 'true' used}%
      \else
        \ifcase0%
          \ifx\key@default\ltxkeys@truetoks\else
          \ifx\key@default\ltxkeys@falsetoks\else1\fi\fi\relax
        \else
          \ltxkeys@err{Invalid default value for boolean key
            '\key@name'}\ltxkeys@ehd
        \fi
      \fi
    }{}%
    \edef\key@callback{\unexpanded{##2}}%
    \ltxkeys@stripdotcode\key@callback
    \expandafter\ltxkeys@striplaststar\key@type\@empty*\@empty
      \ltxkeys@nil\key@type@aux
    \xifinsetTF{,\key@type@aux,}{,sty,}{%
      \ltxkeys@trimspaces{##3}\key@dependants
      \ltxkeys@ifxTF\key@dependants\ltxkeys@rej{%
        \def\key@dependants{}%
      }{%
        \expandafter\ltxkeys@declarekeys@e\expandafter{\key@dependants}%
      }%
    }{%
      \xifinsetTF{,\key@type@aux,}{,bool,choice,}{%
        \ltxkeys@trimspaces{##3}\key@bicallback
        \ltxkeys@ifxTF\key@bicallback\ltxkeys@rej{%
          \let\key@bicallback\ltxkeys@keyvalerr
        }{}%
      }{}%
    }%
    \cptexpandsecond\ltxkeys@accumkeyvals{%
      {\ifx\key@default\ltxkeys@rej\else\expandcsonce\key@default\fi}%
      {\ifx\key@callback\ltxkeys@rej\else\expandcsonce\key@callback\fi}%
    }%
    \def\key@callback@aux{%
      \ifx\key@callback\ltxkeys@rej{}\else{\expandcsonce\key@callback}\fi
    }%
    \def\key@default@aux{%
      \ifx\key@default\ltxkeys@rej\else[\expandcsonce\key@default]\fi
    }%
    \s@expandarg\ltxkeys@declarekeys@d\key@type
    \def\reserved@a{ord}%
    \edef\ltxkeys@tempa{%
      [\key@pref]{\key@fam}%
      \ifx\key@type\reserved@a\else\ifx\macro@pref\@empty\else
        [\macro@pref]\fi\fi{\expandcsonce\key@name}%
    }%
    \cptpassexpanded{%
      \toks@{\the\toks@
        \cptmakecs{ltxkeys@twk\ifltxkeys@twk true\else false\fi}%
        \ifcase\currmatch\relax
          \ltxkeys@cmdkey\ltxkeys@tempa\key@default@aux\key@callback@aux
        \or
          \ltxkeys@boolkey+\ltxkeys@tempa\key@default@aux
          \key@callback@aux{\expandcsonce\key@bicallback}%
        \or
          \ltxkeys@ordkey\ltxkeys@tempa\key@default@aux\key@callback@aux
        \or
          \ltxkeys@choicekey*+\ltxkeys@tempa
          [\unexpanded{\userinput\order}]{\expandcsonce\ltxkeys@alt}%
          \key@default@aux\key@callback@aux{\expandcsonce\key@bicallback}%
        \or
          \ltxkeys@stylekey\ltxkeys@tempa\key@default@aux
          (\expandcsonce\key@dependants)\key@callback@aux
        \or
          \ltxkeys@stylekey*\ltxkeys@tempa\key@default@aux
          (\expandcsonce\key@dependants)\key@callback@aux
        \else
          \cptgaddtolist\noexpand\ltxkeys@badkeytypes{\key@type}%
        \fi
      }%
    }%
  }%
  \ifdefTF\ltxkeys@keyparser{%
    \ltxkeys@stripallouterbracesincs\ltxkeys@keyparser
  }{%
    \def\ltxkeys@keyparser{;}%
  }%
  \ifblankTF{#1}{%
    % No 'onekeytype':
    \edef\ltxkeys@tempa{\unexpanded{#5}}%
  }{%
    \def\ltxkeys@tempa{}%
    \def\ltxkeys@do##1{%
      \edef\ltxkeys@tempa{%
        \expandafter\csliststack\ltxkeys@keyparser
        \ltxkeys@tempa#1/\unexpanded{##1}%
      }%
    }%
    \cptexpandsecond{\ltxkeys@listparse0}{[\ltxkeys@keyparser]}{#5}%
  }%
  \def\ltxkeys@do##1{%
    \ifblankTF{##1}{}{%
      \ltxkeys@splita##1/^?^/^?^/^?^/^?^/\ltxkeys@nil
    }%
  }%
  \cptexpandsecond{\ltxkeys@listparse0}
    {[\ltxkeys@keyparser]{\expandcsonce\ltxkeys@tempa}}%
  \cptexpandsecond\endgroup{%
    \the\toks@
    \noexpand\ltxkeys@twkfalse
    \edef\noexpand\key@vals{\ox@unexpanded\key@vals}%
  }%
  \ifx\ltxkeys@badkeytypes\@empty\else
    \cpt@err{Invalid key types '\ltxkeys@badkeytypes'}\ltxkeys@ehd
  \fi
  % Initialize keys:
  \ltxkeys@ifcsemptyTF\key@vals{}{%
    \cptexpandargonce{\ltxkeys@setkeys[#2]{#3}}\key@vals
  }%
  \ltxkeys@decfalse
}
\robust@def*\ltxkeys@declarekeys@d#1{%
  \ltxkeys@findmatch
  {#1}{cmd:0,bool:1,ord:2,choice:3,sty:4,syt*:5}{\def\currmatch{-1}}%
}
% \ltxkeys@declarekeys@e{<dependant key specs>}
\robust@def*\ltxkeys@declarekeys@e#1{%
  \ifblankTF{#1}{\def\key@dependants{}\cptgobbletorelax}{}%
  \begingroup
  \def\ltxkeys@splita##1>##2>{%
    \def\key@type{##1}%
    \edef\key@name{\unexpanded{##2}}%
    \ltxkeys@splitb.%
  }%
  \def\ltxkeys@splitb##1>##2>##3\ltxkeys@nil{%
    \edef\key@default{\expandcsonce{\@gobble##1}}%
    \edef\key@callback{\unexpanded{##2}}%
    \ltxkeys@stripdotcode\key@callback
    \ltxkeys@ifrejname{%
      \ltxkeys@err{Wrong syntax for dependants keys in
        \MsgBrk\string\ltxkeys@declarekeys}\ltxkeys@ehd
    }%
    \edef\key@dependants{%
      \expandafter\csliststack\ltxkeys@keyparser\key@dependants
      \key@type/\expandcsonce\key@name
      \ifx\key@default\ltxkeys@rej\else/\expandcsonce\key@default\fi
      \ifx\key@callback\ltxkeys@rej\else/\expandcsonce\key@callback\fi
    }%
  }%
  \def\key@dependants{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@splita##1>^?^>^?^>^?^>\ltxkeys@nil
  }%
  \ltxkeys@listparse1[,]{#1}%
  \postgroupdef\key@dependants\endgroup
  \cpt@relax
}
\robust@def*\ltxkeys@savexfamilykeys{%
  \begingroup
  \endlinechar\m@one
  \cpt@testst{\cpt@testltopt\ltxkeys@savexf@milykeys{}}%
}
\robust@def*\ltxkeys@savexf@milykeys<#1>{%
  \cpt@testpnopt{\ltxkeys@savexf@milyk@ys{#1}}{}%
}
\robust@def*\ltxkeys@savexf@milyk@ys#1(#2)#3{%
  \ifblankTF{#1}{%
    \ltxkeys@err{Empty set-identifier for \string\xfamilykeys:
      ||\detokenize{#3}||}\ltxkeys@ehd
  }{}%
  \ltxkeys@trimspaces{#1}\ltxkeys@tempb
  \ifcsndefTF{xfamilykeys@id@\ltxkeys@tempb}{%
    \ltxkeys@err{xfamilykeys identifier '\ltxkeys@tempb'
      already in use}\ltxkeys@ehd
  }{}%
  \cpt@stchoose{cpt@st}{#3}\ltxkeys@tempa\ltxkeys@savexfamilykeys
  \ifblankTF{#2}{}{%
    \def\ltxkeys@do##1{%
      \edef\ltxkeys@tempa{%
        \expandafter\csliststack\ltxkeys@keyparser
        \ltxkeys@tempa#2/\unexpanded{##1}%
      }%
    }%
    \cptexpandsecond{\def\ltxkeys@tempa{}\ltxkeys@listparse1}%
      {[\ltxkeys@keyparser]{\expandcsonce\ltxkeys@tempa}}%
  }%
  \cptexpandsecond{\endgroup\csn@edef}
    {{xfamilykeys@id@\ltxkeys@tempb}{\ox@unexpanded\ltxkeys@tempa}}%
}

\robust@def*\ltxkeys@definexfamilykeys{%
  \begingroup
  \cpt@testst{\cpt@testltopt\ltxkeys@d@finexfamilykeys{}}%
}
\robust@def*\ltxkeys@d@finexfamilykeys<#1>{%
  \edef\defwith{\ltxkeys@declarekeys\ifcpt@st*\fi}%
  \ifblankTF{#1}{%
    \ltxkeys@err{Invalid empty xfamilykeys identifier
      \MsgBrk in \string\ltxkeys@definexfamilykeys}\ltxkeys@ehd
  }{}%
  \ltxkeys@trimspaces{#1}\ltxkeys@tempa
  \ifcsndefTF{xfamilykeys@id@\ltxkeys@tempa}{%
    \expandafter\cpt@testopt\expandafter{\expandafter
    \ltxkeys@d@fin@xfamilykeys\expandafter{\ltxkeys@tempa}}{KV}%
  }{%
    \ltxkeys@err{Unknown xfamilykeys identifier '\ltxkeys@tempa'
      \MsgBrk in \string\ltxkeys@definexfamilykeys}\ltxkeys@ehd
  }%
}
\robust@def*\ltxkeys@d@fin@xfamilykeys#1[#2]#3{%
  \cpt@testopt{\ltxkeys@d@fin@xf@milykeys{#1}{#2}{#3}}{}%
}
\robust@def*\ltxkeys@d@fin@xf@milykeys#1#2#3[#4]#5{%
  \def\ltxkeys@na{#5}%
  \def\ltxkeys@splita##1/##2/{%
    \ltxkeys@trimspacesset{{##1}\key@type,{##2}\key@name@aux}%
    \xifstrcmpTF\key@type{choice}{%
      \expandafter\ltxkeys@splitchoice\expandafter{\key@name@aux}%
    }{%
      \let\key@name\key@name@aux
    }%
    \ltxkeys@splitb.%
  }%
  \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{%
    \edef\key@default{\expandcsonce{\@gobble##1}}%
    \edef\key@callback{\unexpanded{##2}}%
    \edef\key@dependants{\unexpanded{##3}}%
    \oifinset@sp@TF,\key@name\ltxkeys@na{}{%
      \let\do\expandcsonce
      \edef\ltxkeys@tempa{%
        \expandafter\csliststack\ltxkeys@keyparser
        \ltxkeys@tempa\key@type/\do\key@name@aux
        \ifx\key@default\ltxkeys@rej\else/\do\key@default\fi
        \ifx\key@callback\ltxkeys@rej\else/\do\key@callback\fi
        \ifx\key@dependants\ltxkeys@rej\else/\do\key@dependants\fi
      }%
    }%
  }%
  \def\ltxkeys@tempa{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@splita##1/^?^/^?^/^?^/^?^/\ltxkeys@nil
  }%
  \cptexpandsecond{\ltxkeys@listparse1}
    {[\ltxkeys@keyparser]{\expandcsnonce{xfamilykeys@id@#1}}}%
  \cptexpandsecond\endgroup
    {\defwith[#2]{#3}[#4]{\expandcsonce\ltxkeys@tempa}}%
}

\robust@def*\ltxkeys@presetkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{ppsetkeys}{pre}}%
}
\newletcs\ltxkeys@addpresetkeys\ltxkeys@presetkeys
\robust@def*\ltxkeys@removepresetkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{removeppsetkeys}{pre}}%
}
\robust@def*\ltxkeys@undefpresetkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{undefppsetkeys}{pre}}%
}
\robust@def*\ltxkeys@postsetkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{ppsetkeys}{post}}%
}
\newletcs\ltxkeys@addpostsetkeys\ltxkeys@postsetkeys
\robust@def*\ltxkeys@removepostsetkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{removeppsetkeys}{post}}%
}
\robust@def*\ltxkeys@undefpostsetkeys{%
  \ltxkeys@testcl{\ltxkeys@testopt@g{undefppsetkeys}{post}}%
}
\robust@def*\ltxkeys@ppsetkeys#1#2{%
  \def\ltxkeys@rsvda{}%
  \def\ltxkeys@rsvdb{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@splitkeyval##1\ltxkeys@nil\ltxkeys@tkey\ltxkeys@tval
    \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{%
      \ltxkeys@err{Key '\ltxkeys@currtriple' is undefined.}%
      \ltxkeys@ehd
    }{%
      \ifcsndefTF{\ltxkeys@hdr#1setkeys@alreadysaved}{}{%
        \csn@def{\ltxkeys@hdr#1setkeys@alreadysaved}{}%
      }%
      % You can't enter the same key twice in either
      % preset or post-set lists in the same family and prefix:
      \xifinsetTF{,\cptoxdetok\ltxkeys@tkey,}%
        {,\cptsxdetok{\usename{\ltxkeys@hdr#1setkeys@alreadysaved},}}{%
        \ltxkeys@err{Double entry for key '\ltxkeys@currtriple' in\MsgBrk
          #1set key list}\ltxkeys@ehd
      }{%
        \edef\ltxkeys@rsvda{\csliststack,\ltxkeys@rsvda
          \ltxkeys@tkey\ltxkeys@ifcsemptyTF\ltxkeys@tval{}%
            {=\expandcsonce\ltxkeys@tval}}%
        \edef\ltxkeys@rsvdb{\csliststack,\ltxkeys@rsvdb
          \expandcsonce\ltxkeys@tkey}%
      }%
    }%
  }%
  \ltxkeys@listparse3{#2}%
  % '...@alreadysaved' saves key names irrespective
  % of value, for testing if a preset key is being saved twice:
  \ltxkeys@ifcsemptyTF\ltxkeys@rsvda{}{%
    \ifcsndefTF{\ltxkeys@hdr#1setkeys}{%
      \cptpassexpanded{%
        \cptfiltermergekv\noexpandcsn{\ltxkeys@hdr#1setkeys}%
          {\expandcsonce\ltxkeys@rsvda}\noexpand\nofilter
        \cptfiltermergecsv\noexpandcsn{\ltxkeys@hdr#1setkeys@alreadysaved}%
          {\ltxkeys@rsvdb}\noexpand\nofilter
      }%
    }{%
      \csn@edef{\ltxkeys@hdr#1setkeys}{\expandcsonce\ltxkeys@rsvda}%
      \csn@edef{\ltxkeys@hdr#1setkeys@alreadysaved}%
        {\expandcsonce\ltxkeys@rsvdb}%
    }%
    \ifltxkeys@cl
      \globalizecsn{\ltxkeys@hdr#1setkeys}%
      \globalizecsn{\ltxkeys@hdr#1setkeys@alreadysaved}%
    \fi
  }%
}
\robust@def*\ltxkeys@removeppsetkeys#1#2{%
  \ifcsndefFT{\ltxkeys@hdr#1setkeys}{%
    \ltxkeys@err{No #1set keys defined for prefix '\ltxkeys@ttpref'
      and family '\ltxkeys@tfam'}\ltxkeys@ehd
  }{%
    \def\ltxkeys@rsvda{}\def\ltxkeys@rsvdb{}%
    \def\ltxkeys@do##1{%
      \ltxkeys@splitkeyval##1=\ltxkeys@nil\ltxkeys@tkey\ltxkeys@tval
      \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{%
        \ltxkeys@err{Key '\ltxkeys@currtriple' is undefined}%
        \ltxkeys@ehd
      }{%
        \xifinsetTF{,\cptoxdetok\ltxkeys@tkey=\cptoxdetok\ltxkeys@tval,}%
          {,\cptsxdetok{\usename{\ltxkeys@hdr#1setkeys}},}{%
          \edef\ltxkeys@rsvda{\csliststack,\ltxkeys@rsvda
            \ltxkeys@tkey\ltxkeys@ifcsemptyTF\ltxkeys@tval{}%
            {=\expandcsonce\ltxkeys@tval}}%
          \edef\ltxkeys@rsvdb{\csliststack,\ltxkeys@rsvdb
            \expandcsonce\ltxkeys@tkey}%
        }{%
          \ltxkeys@err{Key '\ltxkeys@currtriple' not a #1set key}%
          \ltxkeys@ehd
        }%
      }%
    }%
    \ltxkeys@listparse3{#2}%
    \ltxkeys@ifcsemptyTF\ltxkeys@rsvda{}{%
      \cptpassexpanded{%
        \cptfilterremovekv\noexpandcsn{\ltxkeys@hdr#1setkeys}%
          {\expandcsonce\ltxkeys@rsvda}\noexpand\nofilter
        \cptfilterremovecsv\noexpandcsn{\ltxkeys@hdr#1setkeys@alreadysaved}%
          {\ltxkeys@rsvdb}\noexpand\nofilter
      }%
      \ifltxkeys@cl
        \globalizecsn{\ltxkeys@hdr#1setkeys}%
        \globalizecsn{\ltxkeys@hdr#1setkeys@alreadysaved}%
      \fi
    }%
  }%
}
\robust@def*\ltxkeys@undefppsetkeys#1{%
  \ifcsndefFT{\ltxkeys@hdr#1setkeys}{%
    \ltxkeys@err{No #1set keys defined for prefix '\ltxkeys@ttpref'
      and family '\ltxkeys@tfam'}\ltxkeys@ehd
  }{%
    \usename{\ifltxkeys@cl g\fi undefcsn}{\ltxkeys@hdr#1setkeys}%
    \usename{\ifltxkeys@cl g\fi undefcsn}%
      {\ltxkeys@hdr#1setkeys@alreadysaved}%
  }%
}
% Set a main key after setting its twin/alias. This is NOT
% related to dependant or style keys:
\robust@def*\ltxkeys@setaliaskey#1{%
  \ltxkeys@commanormalize{#1}\ltxkeys@tempa
  \xifinsetTF{,}{\cptoxdetok\ltxkeys@tempa}{%
    \ltxkeys@err{\noexpand\ltxkeys@setaliaskey doesn't
      accept key list}\ltxkeys@ehd
  }{%
    \cptexpandarg\cpt@testopt{\ltxkeys@s@taliaskey\ltxkeys@tempa}{}%
  }%
}
\newletcs\setaliaskey\ltxkeys@setaliaskey
\robust@def*\ltxkeys@s@taliaskey#1[#2]{%
  \begingroup
  \let\x\ltxkeys@tkey
  \edef\y{\expandcstwice{\csname\ltxkeys@hdr#1\endcsname{}}}%
  \cptexpandsecond{\endgroup\ltxkeys@ifinlistTF(1)}{%
    {\ltxkeys@setaliaskey{\x},\setaliaskey{\x}}%
    {\expandcsonce\y}%
  }{%
    \ltxkeys@err{\noexpand\ltxkeys@setaliaskey
      or \noexpand\setaliaskey nested}\ltxkeys@ehd
  }{}%
  \cptexpandsecond\ltxkeys@setkeys{%
    [\ltxkeys@ttpref]{\ltxkeys@tfam}{%
      #1=\ifblankTF{#2}{\expandcsonce\ltxkeys@tval}{\unexpanded{#2}}%
    }%
  }%
}
\robust@def*\ltxkeys@splitchoice#1{%
  \begingroup
  \def\ltxkeys@tempa##1.##2##3\ltxkeys@nil{\endgroup
    \ltxkeys@trimspaces{##1}\key@name
    \ifstrcmpTF{##2}{.}{%
      \ltxkeys@err{Invalid alternate value list for key '#1'}
      \ltxkeys@ehd
    }{%
      \ifmacroTF{##2}{%
        \edef\ltxkeys@alt{\expandcsonce{##2}}%
      }{%
        \edef\ltxkeys@alt{\unexpanded{##2}}%
      }%
      \ltxkeys@trimspacesincs\ltxkeys@alt
    }%
  }%
  \ltxkeys@tempa#1..\ltxkeys@nil
}
% #1: key prefix
% #2: key family
\robust@def*\ltxkeys@setinitialkeyvals#1#2{%
  \ltxkeys@initrue
  \ifcsndefFT{#1@#2@initialkeyvals}{}{%
    \ifcsnnullTF{#1@#2@initialkeyvals}{}{%
      \cptpassexpanded{%
        \noexpand\ltxkeys@setkeys[#1]{#2}%
        {\expandcsnonce{#1@#2@initialkeyvals}}%
      }%
    }%
  }%
  \ltxkeys@inifalse
}

% \ltxkeys@initializekeys[<prefixes>]{<fams>}[<na>]
% 1.  Preset all keys defined in families <fams>;
%     ignore keys listed in <na>. <na> comes from key-val
%     pairs that the user wants to use as current values
%     of keys. Their keys are to be ignored when setting
%     up defaults.
% 2.  The key-val list to be preset comes from the macros
%     \<pref>@<fam>@initialkeyvals:
\robust@def*\ltxkeys@initializekeys{%
  \cpt@testopt\ltxkeys@in@tializekeys{KV}%
}
\robust@def*\ltxkeys@in@tializekeys[#1]#2{%
  \cpt@testopt{\ltxkeys@in@ti@lizekeys{#1}{#2}}{}%
}
\robust@def*\ltxkeys@in@ti@lizekeys#1#2[#3]{%
  \ltxkeys@initrue
  \begingroup
  \def\ltxkeys@resa{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \letcstocsn\ltxkeys@tempc{\ltxkeys@hdr initialkeyvals}%
      \ifdefTF\ltxkeys@tempc{%
        \ltxkeys@remdispox\ltxkeys@tempc
        \cptexpandargonce{\cptfiltermergecsv[,]\ltxkeys@resa}
          \ltxkeys@tempc\nofilter
      }{}%
    }%
    \ltxkeys@listparse1{#2}%
  }%
  \ltxkeys@listparse1{#1}%
  \ltxkeys@getkeynames{#3}%
  \cptexpandsecond{\endgroup\ltxkeys@setkeys*+[#1]{#2}}%
    {[\ltxkeys@keynames]{\expandcsonce\ltxkeys@resa}}%
  \ltxkeys@inifalse
}
% Remove disabled and pox keys:
\robust@def*\ltxkeys@remdispox#1{%
  \begingroup
  \letcstocsn\ltxkeys@tempd{\ltxkeys@hdr disabledkeys}%
  \ifdefTF\ltxkeys@tempd{}{\def\ltxkeys@tempd{}}%
  \letcstocsn\ltxkeys@tempe{\ltxkeys@hdr poxkeys}%
  \ifdefTF\ltxkeys@tempe{}{\def\ltxkeys@tempe{}}%
  \ltxkeys@ifcsemptyTF\ltxkeys@tempd{%
    \ltxkeys@ifcsemptyTF\ltxkeys@tempe\cptgobbletorelax\relax
  }{}%
  \edef\ltxkeys@tempd
    {\expandcsonce\ltxkeys@tempd,\expandcsonce\ltxkeys@tempe}%
  \def\ltxkeys@do##1{%
    \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tkey
    \xifinsetTF{,\ltxkeys@tkey,}{,\expandcsonce\ltxkeys@tempd,}{}{%
      \edef#1{\csliststack,#1\unexpanded{##1}}%
    }%
  }%
  \cptexpandargonce{\def#1{}\ltxkeys@listparse3}{#1}%
  \cpt@relax
  \postgroupdef#1\endgroup
}
% \ltxkeys@launchkeys*+[<prefix>]{<fams>}{<curr>}
% 1.  First preset all family keys before setting keys in <curr>.
% 2.  <curr> are the key-vals to be set in the current run; they
%     will be ignored when initializing the keys of families <fams>:
\robust@def*\ltxkeys@launchkeys{%
  \ltxkeys@teststpl{\cpt@testopt\ltxkeys@l@unchkeys{KV}}%
}
\robust@def*\ltxkeys@l@unchkeys[#1]#2#3{%
  \edef\ltxkeys@cmdpf{\ifltxkeys@st*\fi\ifltxkeys@pl+\fi}%
  \ltxkeys@commanormalizeset{{#1}\ltxkeys@prefs,{#2}\ltxkeys@fams}%
  \xifinsetTF{,}\ltxkeys@fams{%
    \ifltxkeys@pl\else
      \ltxkeys@err{Multiple key families: you need + prefix
        \MsgBrk for command \string\ltxkeys@launchkeys}\ltxkeys@ehd
    \fi
  }{}%
  \cptexpandsecond\ltxkeys@in@ti@lizekeys
    {{\ltxkeys@prefs}{\ltxkeys@fams}}[#3]%
  \ifblankTF{#3}\cptgobbletorelax\relax
  \begingroup
  \def\ltxkeys@resa{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \edef\ltxkeys@tempc{\unexpanded{#3}}%
      \ltxkeys@remdispox\ltxkeys@tempc
      \cptexpandargonce{\cptfiltermergecsv[,]\ltxkeys@resa}
        \ltxkeys@tempc\nofilter
    }%
    \ltxkeys@listparse*0\ltxkeys@fams
  }%
  \ltxkeys@listparse*0\ltxkeys@prefs
  \cptexpandargonce{\endgroup\expandafter\undefcs\expandafter
    \ltxkeys@cmdpf\expandafter\ltxkeys@setkeys
    \ltxkeys@cmdpf[#1]{#2}}\ltxkeys@resa
  \cpt@relax
}
\robust@def*\ltxkeys@nonlaunchkeys{%
  \cpt@teststopt{\ltxkeys@nonl@unchkeys}{KV}%
}
\newletcs\ltxkeys@noninitializekeys\ltxkeys@nonlaunchkeys
\robust@def*\ltxkeys@nonl@unchkeys[#1]#2#3{%
  \ifboolTF{cpt@st}{%
    \AtBeginDocument{\ltxkeys@nonl@un@hkeys{#1}{#2}{#3}}%
  }{%
    \ltxkeys@nonl@un@hkeys{#1}{#2}{#3}%
  }%
}
\robust@def*\ltxkeys@nonl@un@hkeys#1#2#3{%
  \ltxkeys@commanormalizeset
    {{#1}\ltxkeys@prefs,{#2}\ltxkeys@fams,{#3}\ltxkeys@keys}%
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \ltxkeys@nonl@un@hk@ys
    }%
    \ltxkeys@listparse*0\ltxkeys@fams
  }%
  \ltxkeys@listparse*0\ltxkeys@prefs
}
\robust@def*\ltxkeys@nonl@un@hk@ys{%
  \ifcsndefTF{\ltxkeys@hdr poxkeys}{}{%
    \csn@def{\ltxkeys@hdr poxkeys}{}%
  }%
  \letcstocsn\ltxkeys@tempc{\ltxkeys@hdr poxkeys}%
  \def\ltxkeys@do##1{%
    \ifcsndefTF{\ltxkeys@hdr##1}{%
      \xifinsetTF{,##1,}{,\expandcsonce\ltxkeys@tempc,}{}{%
        \edef\ltxkeys@tempc{%
          \csliststack,\ltxkeys@tempc\unexpanded{##1}%
        }%
      }%
    }{}%
  }%
  \ltxkeys@listparse*0\ltxkeys@keys
  \letcsntocs{\ltxkeys@hdr poxkeys}\ltxkeys@tempc
}
\robust@def*\ltxkeys@setkeys{%
  \ltxkeys@rmfalse
  \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setkeys@a}%
}
% Don't call \ltxkeysusekeys \ltxkeyssetkeys, since
% \ltxkeyssetkeys is used in mkii.
\newletcs\ltxkeysusekeys\ltxkeys@setkeys
\newletcs\ltxkeys@setkey\ltxkeys@setkeys
\robust@def*\ltxkeys@setrmkeys{%
  \ltxkeys@rmtrue
  \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setrmkeys@a}%
}
\robust@def*\ltxkeys@setrmkeys@a[#1]{%
  \ltxkeys@debug{==}{Setting 'remaining' keys now}%
  \cptexpandarg{\ltxkeys@setkeys@a[#1]}
    {\expandcsnonce{\ltxkeys@hdr rmkeys}}%
}
\robust@def*\ltxkeys@setkeys@a[#1]#2{%
  \begingroup
  \def\x{\ltxkeys@nil}%
  \xifinsetTF{\x\detokenize{#2}\x}
    {\x.\x,\x;\x:\x+\x-\x=\x*\x^\x_\x/\x|\x[\x(\x)\x]\x}{%
    \ltxkeys@err{Invalid key list '#2': Something is wrong}
    \ltxkeys@ehd
  }{}%
  \endgroup
  \ifcsndefTF{\ltxkeys@hdr executedkeys}{}{%
    \csn@def{\ltxkeys@hdr executedkeys}{}%
  }%
  \ifnum\ltxkeys@keydepth=\z@pt
    \csn@def{\ltxkeys@hdr rmkeys}{}%
    \def\ltxkeys@undefinedkeys{}%
  \fi
  \ltxkeys@getkeynames{#2}%
  \let\ltxkeys@naa\ltxkeys@keynames
  \ifblankTF{#1}{}{%
    \edef\ltxkeys@naa{\csliststack,\ltxkeys@naa\unexpanded{#1}}%
  }%
  \ifboolTF{ltxkeys@tracingkeys}{%
    \ltxkeys@getbasechars*[30]\ltxkeys@keynames\ltxkeys@tempa
    \edef\ltxkeys@tempb{\ifnum\ltxkeys@charcount>30\string\ETC\fi}%
    \wlog{\@spaces(on level \the\ltxkeys@keydepth)}%
    \ltxkeys@debug{==}{Setting keys: '\ltxkeys@tempa\ltxkeys@tempb'}%
  }{}%
  \ltxkeys@usepresetkeys{pre}%
  \ltxkeys@setkeys@b{#1}{#2}%
  \ltxkeys@usepresetkeys{post}%
  \ifnumcmpTF\ltxkeys@keydepth=\z@pt{%
    \ltxkeys@debug{==}{Setting keys, returned to level 0}%
    \ltxkeys@ifcsemptyTF\ltxkeys@undefinedkeys{%
      \ltxkeys@debug{==}{No undefined keys in this run}%
    }{%
      \ltxkeys@debug{==}{There're undefined keys; logging them}%
      \ltxkeys@logunknownkeys
    }%
  }{}%
  \ifltxkeys@exop
    \ltxkeys@exopfalse
    \ltxkeys@debug{==}{Ended executing options}%
  \fi
  \ltxkeys@pxopfalse
}
\robust@def*\ltxkeys@usepresetkeys#1{%
  \ltxkeys@presettrue
  \begingroup
  \toks@{}%
  \ltxkeys@debug{==}{Looking for #1-set keys}%
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \ifcsndefFT{\ltxkeys@hdr#1setkeys}{}{%
        \cptexpanded{\toks@{\the\toks@\relax\ltxkeys@setkeys@b
          {\expandcsonce\ltxkeys@naa}
          {\expandcsnonce{\ltxkeys@hdr#1setkeys}}}}%
      }%
    }%
    \ltxkeys@listparse*0\ltxkeys@fams
  }%
  \ltxkeys@listparse*0\ltxkeys@prefs
  \oifblankTF{\the\toks@}{%
    \endgroup
    \ltxkeys@debug{==}{No #1-set keys found}%
  }{%
    \ltxkeys@debug{==}{P\@gobble#1-set keys found. Setting them now}%
    \expandafter\endgroup\the\toks@
    \ltxkeys@debug{++}{Finished setting #1-set keys}%
  }%
  \ltxkeys@presetfalse
}
\robust@def*\ltxkeys@setkeys@b#1#2{%
  \ifblankTF{#1}{%
    \def\ltxkeys@nakeys{}%
  }{%
    \ltxkeys@commanormalize{#1}\ltxkeys@nakeys
  }%
  \def\ltxkeys@do##1{%
    \edef\CurrentKeyval{\unexpanded{##1}}%
    \ltxkeys@getkeyvalue##1=\ltxkeys@nil\ltxkeys@tval
    \ltxkeys@setkeys@c##1=\ltxkeys@nil
  }%
  \ltxkeys@listparse3{#2}%
}
\robust@def*\ltxkeys@setkeys@c#1=#2\ltxkeys@nil{%
  \ifinsetTF{\needvalue}{#1}{%
    \ltxkeys@err{\noexpand\needvalue pointer not allowed
      \MsgBrk when setting keys}\ltxkeys@ehd
  }{}%
  \ltxkeys@findp@inters\savevalue{#1}\ltxkeys@tkey{%
    \ltxkeys@svtrue
  }{%
    \ltxkeys@svfalse
  }%
  \let\CurrentKey\ltxkeys@tkey
  \ltxkeys@ifcsemptyTF\ltxkeys@tkey{%
    \ifltxkeys@novalue\else
      \ltxkeys@err{No key specified for value
        '\expandcsonce\ltxkeys@tval'
        \MsgBrk in families '\ltxkeys@fams'}\ltxkeys@ehd
    \fi
  }{%
    \oifinset@sp@TF,\ltxkeys@tkey\ltxkeys@nakeys{}{%
      \ltxkeys@setkeys@d
    }%
  }%
}
\robust@def*\ltxkeys@setkeys@d{%
  \ltxkeys@kffalse
  \ifboolTF{ltxkeys@preset}{%
    \ltxkeys@setkeys@e
  }{%
    \ifboolTF{ltxkeys@pl}{%
      \def\ltxkeys@do##1{%
        \def\CurrentPref{##1}%
        \ltxkeys@makepf{##1}%
        \def\ltxkeys@do####1{%
          \def\ltxkeys@tfam{####1}%
          \let\CurrentFam\ltxkeys@tfam
          \ltxkeys@makehdr\ltxkeys@tfam
          \ltxkeys@setkeys@e
        }%
        \ltxkeys@listparse*0\ltxkeys@fams
      }%
      \ltxkeys@listparse*0\ltxkeys@prefs
    }{%
      \def\ltxkeys@do##1{%
        \def\CurrentPref{##1}%
        \ltxkeys@makepf{##1}%
        \def\ltxkeys@do####1{%
          \def\ltxkeys@tfam{####1}%
          \let\CurrentFam\ltxkeys@tfam
          \ltxkeys@makehdr\ltxkeys@tfam
          \ltxkeys@setkeys@e
          \ifltxkeys@kf\loopbreak\fi
        }%
        \ltxkeys@listparse*0\ltxkeys@fams
        \ifltxkeys@kf\loopbreak\fi
      }%
      \ltxkeys@listparse*0\ltxkeys@prefs
    }%
  }%
  \ifboolTF{ltxkeys@kf}{%
    \ifdefboolTF{ltxkeys@pxop}{%
      \ltxkeys@ifxTF\ltxkeys@testname\ltxkeys@documentclass{%
        \cpt@removecurroption\CurrentKeyval
        \ltxkeys@debug{==}{Key \ltxkeys@currtriple, removed from
          \string\@unusedoptionlist}%
      }{}%
    }{}%
  }{%
    \ifdefboolTF{ltxkeys@pxop}{%
      \ifcsndefTF{\ltxkeys@hdr default@ds@opt}{%
        \begingroup
        \let\xp\expandcsonce
        \cptexpandsecond{%
          \endgroup\usename{\ltxkeys@hdr default@ds@opt}%
        }{%
          {\xp\ltxkeys@ttpref}{\xp\ltxkeys@tfam}%
          {\xp\ltxkeys@tkey}{\xp\ltxkeys@tval}%
        }%
      }{%
        \ltxkeys@ifxTF\@currext\@clsextension
          \relax\ltxkeys@unknownoptionerror
      }%
    }{%
      \ifboolTF{ltxkeys@st}{%
        \ifltxkeys@tracingkeys
          \ltxkeys@getinnovalue
          \ltxkeys@debug{==}{Undefined key \ltxkeys@currtriple,
            \InnocentVal, saved in \cptmakecs{\ltxkeys@hdr rmkeys}}%
        \fi
        \cptexpandargonce{\aftercsname{\cptfiltermergekv[,]}%
          {\ltxkeys@hdr rmkeys}}\CurrentKeyval\nofilter
      }{%
        \ifcsndefTF{\ltxkeys@hdr default@ds@key}{%
          \begingroup
          \let\xp\expandcsonce
          \cptexpandsecond{%
            \endgroup\usename{\ltxkeys@hdr default@ds@key}%
          }{%
            {\xp\ltxkeys@ttpref}{\xp\ltxkeys@tfam}%
            {\xp\ltxkeys@tkey}{\xp\ltxkeys@tval}%
          }%
        }{%
          \ltxkeys@debug{==}{Key \ltxkeys@currtriple, saved as undefined}%
          \ltxkeys@getinnovalue
          \cptexpandarg{\cptfiltermergecsv[;]\ltxkeys@undefinedkeys}{%
            \ltxkeys@ttpref,\ltxkeys@tfam,\ltxkeys@tkey,\InnocentVal
          }\nofilter
        }%
      }%
    }%
  }%
}
\robust@def*\ltxkeys@setkeys@e{%
  \ifboolTF{ltxkeys@tracingkeys}{%
    \ltxkeys@getinnovaluenopad
    \ltxkeys@debug{==}{Setting\@space\ifltxkeys@preset
      preset\@space\fi key: \ltxkeys@currtriple,\InnocentVal}%
  }{}%
  \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{%
    \relax
    \ltxkeys@debug{!!}{%
      \ifltxkeys@preset Preset key\else Key\fi\@space
      is not defined: \ltxkeys@currtriple,\InnocentVal
    }%
  }{%
    \ltxkeys@kftrue
    \ifltxkeys@tracingkeys
      \ltxkeys@debug{++}{\ifltxkeys@preset Preset key\else Key\fi
        \@space'\ltxkeys@tkey' is defined}%
      \ifltxkeys@dec\else\ifltxkeys@ini\else
        \edef\reserved@e{\ltxkeys@currtriple,\InnocentVal}%
        \@onelevel@sanitize\reserved@e
        \letcstocsn\reserved@f{\ltxkeys@hdr executedkeys}%
        \oifinset@sp@TF*\reserved@e\reserved@f{%
          \ltxkeys@debug{!!}{Key '\ltxkeys@currtriple' multiply
            set with same value}%
        }{%
          \csn@edef{\ltxkeys@hdr executedkeys}{%
            \csliststack*\reserved@f\reserved@e
          }%
        }%
      \fi\fi
    \fi
    \ifboolTF{ltxkeys@pxop}{%
      \ltxkeys@testoptionkey{non}%
    }{%
      \ifboolTF{ltxkeys@exop}{}{\ltxkeys@testoptionkey{}}%
    }%
    \ifboolTF{ltxkeys@sv}{}{%
      \ifcsndefTF{\ltxkeys@hdr savevaluekeys}{\ltxkeys@testsavevaluekey}{}%
    }%
    \ifboolTF{ltxkeys@sv}{%
      \ltxkeys@addtosavedvalue\ltxkeys@tkey\ltxkeys@tval
    }{}%
    \ifboolTF{ltxkeys@novalue}{%
      \ifcsndefTF{\ltxkeys@hdr needvaluekeys}{\ltxkeys@testneedvaluekey}{}%
      \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey @default}{%
        \ltxkeys@debug{==}{\ifltxkeys@preset Preset key\else Key\fi\@space
          '\ltxkeys@tkey', no user-value, default found}%
        \cptsevenxp\ltxkeys@usedefault
          \usename{\ltxkeys@hdr\ltxkeys@tkey @default}\ltxkeys@nil
      }{%
        \ltxkeys@err{No value specified for key '\ltxkeys@tkey'}
        \ltxkeys@ehd
      }%
    }{%
      \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval
      \ltxkeys@debug{==}{%
        \ifltxkeys@preset Preset key\else Key\fi\@space
        '\ltxkeys@tkey', macro being executed now%
      }%
      \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth
      \csname\ltxkeys@hdr\ltxkeys@tkey\expandafter
        \endcsname\expandafter{\ltxkeys@tval}\relax
      \cpt@popstate\ltxkeys@setkeys\ltxkeys@keydepth
      \ltxkeys@debug{++}{%
        \ifltxkeys@preset Preset key\else Key\fi\@space
        '\ltxkeys@tkey', macro executed%
      }%
    }%
  }%
}
\robust@def*\ltxkeys@usedefault#1#2\ltxkeys@nil{%
  \ltxkeys@debug{==}{Key '\ltxkeys@tkey', extracting default value}%
  \def\reserved@a##1##2\ltxkeys@nil{%
    \edef\reserved@a{\cptgobblescape{##1}}%
    \edef\reserved@b{%
      \detokenize\expandafter\expandafter\expandafter
        {\expandafter\ltxkeys@hdr\ltxkeys@tkey}%
    }%
    \ltxkeys@ifxTF\reserved@a\reserved@b{%
      \ltxkeys@debug{==}{Key '\ltxkeys@tkey' has standard macro}%
      \begintoksgroup
      \csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1{%
        \toks@{\edef\ltxkeys@tval{\unexpanded{####1}}}%
      }%
      \usename{\ltxkeys@hdr\ltxkeys@tkey @default}%
      \endtoksgroup
      \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval
    }{%
      \ltxkeys@debug{!!}{Key '\ltxkeys@tkey' has nonstandard macro}%
    }%
  }%
  \xaftercsname\reserved@a{\ltxkeys@hdr\ltxkeys@tkey @default}\ltxkeys@nil
  \ifboolTF{ltxkeys@tracingkeys}{%
    \ltxkeys@getinnovaluenopad
    \ltxkeys@debug{==}{%
      \ifltxkeys@preset Preset key\else Key\fi\@space
      '\ltxkeys@tkey', macro being executed now%
    }%
  }{}%
  \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth
  \ifmacroTF{#1}{%
    \expandafter#1\expandafter{\ltxkeys@tval}\relax
  }{%
    \ltxkeys@err{Faulty key macro '\detokenize{#1}'}\ltxkeys@ehd
  }%
  \cpt@popstate\ltxkeys@setkeys\ltxkeys@keydepth
  \ltxkeys@debug{++}{%
    \ifltxkeys@preset Preset key\else Key\fi\@space
    '\ltxkeys@tkey', macro executed%
  }%
}
\robust@def*\ltxkeys@getsavedvalue#1{%
  \def\reserved@a##1#1##2##3\ltxkeys@nil{%
    \edef\ltxkeys@tempc{\unexpanded{##2}}%
    \ltxkeys@ifxTF\ltxkeys@tempc\ltxkeys@nnil\@secondoftwo\@firstoftwo
  }%
  \cptsevenxp\reserved@a\usename{\ltxkeys@hdr @savedvaluelist}%
    #1{\ltxkeys@nil}\ltxkeys@nil
}
\robust@def*\ltxkeys@replacepointers#1{%
  \ltxkeys@debug{==}{Key '\ltxkeys@tkey', replacing pointers}%
  \def\ltxkeys@resa{}%
  \ltxkeys@swafalse
  \ifbracedTF{#1}{%
    \ltxkeys@r@placepointers{#1}\usevalue\ltxkeys@nil
  }{%
    \ltxkeys@r@placepointers#1\usevalue\ltxkeys@nil
  }%
  \let\ltxkeys@resa\relax
}
\robust@def*\ltxkeys@r@placepointers#1\usevalue#2{%
  \def\reserved@a{#2}%
  \ltxkeys@ifxTF\reserved@a\ltxkeys@nnil{%
    \edef\ltxkeys@tval{\unexpanded{#1}}%
    \ifltxkeys@swa
      \ifltxkeys@tracingkeys
        \ltxkeys@getinnovaluenopad
        \ltxkeys@debug{++}{Key '\ltxkeys@tkey', value
          inherited from '\ltxkeys@tempb'}%
      \fi
    \else
      \ltxkeys@debug{==}{Key '\ltxkeys@tkey', no pointers found}%
    \fi
  }{%
    \ltxkeys@getsavedvalue{#2}{%
      \ltxkeys@swatrue
      \def\ltxkeys@tempb{#2}%
      \oifinset@sp@TF,\ltxkeys@tempb\ltxkeys@resa{%
        \ltxkeys@error{Dangerous back linking of pointers}
          {Key pointer replacement terminated due
          \MsgBrk to possible back linking.}%
      }{%
        \edef\ltxkeys@resa{\csliststack,\ltxkeys@resa#2}%
        \s@expandarg\ifbracedTF\ltxkeys@tempc{%
          \s@expandarg\ltxkeys@r@placepointers\ltxkeys@tempc
        }{%
          \expandafter\ltxkeys@r@placepointers\ltxkeys@tempc
        }%
      }%
    }{%
      \ltxkeys@err{No value recorded for key '#2'}\ltxkeys@ehd
      \ltxkeys@r@placepointers
    }%
  }%
}
\robust@def*\ltxkeys@storevalue{%
  \ltxkeys@testpl{\ltxkeys@testopt@a\ltxkeys@st@revalue}%
}
\robust@def*\ltxkeys@st@revalue#1#2{%
  \ifinsetFT{,}{#1}{}{%
    \ltxkeys@err{Illegal multiple keys for
      \string\ltxkeys@storevalue}\ltxkeys@ehd
  }%
  \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}%
  \ltxkeys@getsavedvalue{#1}{%
    \ifltxkeys@pl
      \expandafter\@firstofone
    \else
      \ltxkeys@err{%
        No value recorded for key '#1' of
        \MsgBrk family '\ltxkeys@tfam' and prefix '\ltxkeys@ttpref'
      }{%
        You have asked me to store the value of key '#1'
        \MsgBrk (of family '\ltxkeys@tfam' and prefix '\ltxkeys@ttpref')
        in the macro '\detokenize{#2}',
        \MsgBrk but I can't find a value for key '#1'. Perhaps
        \MsgBrk you haven't yet executed key '#1' or you didn't
        \MsgBrk ask me to save its value.
      }%
    \fi
  }{%
    \let#2=\reserved@a
  }%
}
\robust@def*\ltxkeys@getinnovalue{\ltxkeys@swatrue\ltxkeys@g@tinnovalue}
\robust@def*\ltxkeys@getinnovaluenopad{\ltxkeys@swafalse\ltxkeys@g@tinnovalue}
\robust@def*\ltxkeys@g@tinnovalue{%
  \begingroup
  \ltxkeys@ifcsemptyTF\ltxkeys@tval{%
    \def\InnocentVal{???}%
  }{%
    \@tempcnta\z@pt
    \def\InnocentVal{}%
    \def\ltxkeys@tempa{\\}%
    \def\do##1{%
      \def\reserved@a{##1}%
      \ltxkeys@ifxTF\reserved@a\ltxkeys@nnil{}{%
        \advance\@tempcnta\@ne
        \ifnum\@tempcnta<20\relax
          \edef\InnocentVal{%
            \InnocentVal
            \ifx\reserved@a\ltxkeys@tempa
              \ifltxkeys@swa\@space\fi
            \else
              ##1%
            \fi
          }%
        \else
          \def\do####1\ltxkeys@nil{}%
        \fi
        \do
      }%
    }%
    \expandafter\do\detokenize\expandafter
      {\ltxkeys@tval}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ltxkeys@nil
  }%
  \postgroupdef\InnocentVal\endgroup
}
\robust@def*\ltxkeys@keyvalerr{%
  \ltxkeys@getinnovaluenopad
  \ltxkeys@err{Erroneous value '\InnocentVal' for key or option
    \MsgBrk'\ltxkeys@tkey'}{Invalid key value encountered.}%
}
\robust@def*\ltxkeys@unknownkeyhandler{%
  \def\ltxkeys@default@ds{default@ds@key}%
  \cpt@testopt\ltxkeys@unkn@wnkeyhandler{KV}%
}
\robust@def*\ltxkeys@unkn@wnkeyhandler[#1]#2#3{%
  \begintoksgroup
  \toks1{##1##2##3##4{\ltxkeys@getinnovaluenopad#3}}%
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \cptexpanded{%
        \toks@{\the\toks@
          \csn@def{\ltxkeys@hdr\ltxkeys@default@ds}\the\toks1%
        }%
      }%
    }%
    \ltxkeys@listparse1{#2}%
  }%
  \ltxkeys@listparse1{#1}%
  \endtoksgroup
}
\robust@def*\ltxkeys@logunknownkeys{%
  \ltxkeys@l@gunknownkeys
  \ltxkeys@err{The above keys are undefined and couldn't be set}
    {There are undefined keys; see above.}%
}
\robust@def*\ltxkeys@l@gunknownkeys{%
  \ltxkeys@debug{==}{Now logging undefined keys}%
  \begingroup
  \cpt@cnta\z@pt
  \edef\ltxkeys@skipa{}%
  \cptwhilenum\cpt@cnta<20\do{%
    \edef\ltxkeys@skipa{\ltxkeys@skipa\@space}%
    \advance\cpt@cnta\@ne
  }%
  \typeout{\ltxkeys@skipa*** Unknown keys ***}%
  \def\ltxkeys@tempb{\\}%
  \def\align@do##1##2##3##4##5##6##7##8##9\@@{%
    \def\ltxkeys@tempc{##9}%
    \def\siso@do####1{%
      \def\reserved@a{####1}%
      \ifx\reserved@a\ltxkeys@tempb
        \edef\ltxkeys@skipb{\@space\ltxkeys@skipb}%
      \fi
    }%
    \siso@@loop{##1##2##3##4##5##6##7##8}%
  }%
  \edef\ltxkeys@tempa{%
    *Prefix,*Family,*Name,*Value;\expandcsonce\ltxkeys@undefinedkeys
  }%
  \def\ltxkeys@splita##1,##2,##3,##4\ltxkeys@nil{%
    \def\ltxkeys@msg{}%
    \def\ltxkeys@do####1{%
      \let\ltxkeys@skipb\@empty
      \align@do####1\\\\\\\\\\\\\\\\\\\@@
      \expandafter\align@do\ltxkeys@tempc\\\\\\\\\\\\\\\\\\\@@
      \edef\ltxkeys@msg{\expandcsonce\ltxkeys@msg####1\ltxkeys@skipb}%
    }%
    \ltxkeys@listparse1{##1,##2,##3,##4}%
    \typeout{\ltxkeys@msg}%
  }%
  \def\ltxkeys@do##1{%
    \ltxkeys@splita##1\ltxkeys@nil
  }%
  \ltxkeys@listparse*0[;]\ltxkeys@tempa
  \typeout{\ltxkeys@skipa*******************}%
  \endgroup
}
\robust@def*\ltxkeys@disablekeys{%
  \cpt@teststopt{\ltxkeys@dis@blekeys}{KV}%
}
\robust@def*\ltxkeys@dis@blekeys[#1]#2#3{%
  \ltxkeys@debug{==}{Now disabling keys}%
  \ifboolTF{cpt@st}{%
    \AtBeginDocument{%
      \ltxkeys@dis@bl@keys{#1}{#2}{#3}%
    }%
  }{%
    \ltxkeys@dis@bl@keys{#1}{#2}{#3}%
  }%
}
\robust@def*\ltxkeys@dis@bl@keys#1#2#3{%
  \ltxkeys@commanormalizeset
    {{#1}\ltxkeys@prefs,{#2}\ltxkeys@fams,{#3}\ltxkeys@keys}%
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \ltxkeys@dis@bl@k@ys
    }%
    \ltxkeys@listparse*0\ltxkeys@fams
  }%
  \ltxkeys@listparse*0\ltxkeys@prefs
}
\robust@def*\ltxkeys@dis@bl@k@ys{%
  \begingroup
  \toks@{}%
  \ifcsndefTF{\ltxkeys@hdr disabledkeys}{}{%
    \@namedef{\ltxkeys@hdr disabledkeys}{}%
  }%
  \letcstocsn\ltxkeys@dkeys{\ltxkeys@hdr disabledkeys}%
  \edef\ltxkeys@tempb##1{%
    \ltxkeys@err
      {Key '##1' of family '\ltxkeys@tfam' has been disabled}%
      {Key '##1' has been disabled.\MsgBrk
      You can't set or reset it at this late stage.\MsgBrk
      Perhaps you should have set it earlier in\MsgBrk
      '\string\documentclass' or '\string\usepackage'.}%
  }%
  \def\ltxkeys@do##1{%
    \ifcsndefTF{\ltxkeys@hdr##1}{%
      \xifinsetTF{,##1,}{,\expandcsonce\ltxkeys@dkeys,}{}{%
        \cptpassexpanded{%
          \toks@{\the\toks@
            \ltxkeys@ordkey[\ltxkeys@ttpref]{\ltxkeys@tfam}{##1}%
            \ifcsndefTF{\ltxkeys@hdr##1@default}{[]}{}%
            {\expandcsonce{\ltxkeys@tempb{##1}}}%
          }%
        }%
        \edef\ltxkeys@dkeys{%
          \csliststack,\ltxkeys@dkeys\unexpanded{##1}%
        }%
      }%
    }{%
      \ltxkeys@debug{!!}{Key '##1' is undefined in
        family '\ltxkeys@tfam'}%
    }%
  }%
  \ltxkeys@listparse*0\ltxkeys@keys
  \cptpassexpanded{\endgroup
    \csn@def{\ltxkeys@hdr disabledkeys}{\ltxkeys@dkeys}%
    \noexpand\ltxkeys@disabletrue
    \the\toks@
    \noexpand\ltxkeys@disablefalse
  }%
}
\robust@def*\ltxkeys@nostarform#1#2{%
  \if\detokenize{#1*.}%
    \ltxkeys@err{No star (*) form of command \string#2}\ltxkeys@ehd
  \fi
}
\robust@def*\ltxkeys@declareoption{%
  \let\@fileswith@pti@ns\@badrequireerror
  \cpt@ifstar{%
    \ltxkeys@unknownoptionhandler
  }{%
    \let\ltxkeys@tempa\ltxkeys@ordkey
    \ltxkeys@d@cl@reoption
  }%
}
\robust@def\ltxkeys@unknownoptionhandler{%
  \cpt@testopt\ltxkeys@unkn@wnoptionhandler{KV}%
}
\robust@def*\ltxkeys@unkn@wnoptionhandler[#1]{%
  \cpt@testfam{\ltxkeys@unkn@wnopti@nhandler{#1}}%
}
\robust@def*\ltxkeys@unkn@wnopti@nhandler#1<#2>#3{%
  \def\ltxkeys@default@ds{default@ds@opt}%
  \ltxkeys@unkn@wnkeyhandler[#1]{#2}{#3}%
}
\robust@def*\ltxkeys@declareordoption#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \ltxkeys@d@clareoption{#1}{ord}%
}
\newletcs\ltxkeys@declareordoptions\ltxkeys@declareordoption
\newletcs\ltxkeys@declareoptions\ltxkeys@declareordoption
\robust@def*\ltxkeys@declarecmdoption#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \ltxkeys@d@clareoption{#1}{cmd}%
}
\newletcs\ltxkeys@declarecmdoptions\ltxkeys@declarecmdoption
\robust@def*\ltxkeys@declarebooloption#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \ltxkeys@d@clareoption{#1}{bool}%
}
\newletcs\ltxkeys@declarebooloptions\ltxkeys@declarebooloption
\robust@def*\ltxkeys@declarechoiceoption#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \ltxkeys@d@clareoption{#1}{choice}%
}
\newletcs\ltxkeys@declarechoiceoptions\ltxkeys@declarechoiceoption
\robust@def*\ltxkeys@d@clareoption#1#2{%
  \aftercsname{\ltxkeys@nostarform{#1}}{ltxkeys@declare#2option}%
  \edef\ltxkeys@tempa{\noexpandcsn{ltxkeys@#2key}}%
  \let\@fileswith@pti@ns\@badrequireerror
  \ifsingletokenTF{#1}{%
    \ltxkeys@d@cl@reoption#1%
  }{%
    \ltxkeys@d@cl@reoption{#1}%
  }%
}
\robust@def*\ltxkeys@d@cl@reoption{%
  \cpt@testopt\ltxkeys@d@cl@r@option{KV}%
}
\robust@def*\ltxkeys@d@cl@r@option[#1]{%
  \cpt@testfam{\ltxkeys@d@cl@r@opti@n{#1}}%
}
\robust@def*\ltxkeys@d@cl@r@opti@n#1<#2>{\ltxkeys@tempa[#1]{#2}}

\robust@def*\ltxkeys@declaremultitypeoptions{%
  \cpt@testst\ltxkeys@d@claremultitypeoptions
}
\newletcs\declaremultitypeoptions\ltxkeys@declaremultitypeoptions
\robust@def*\ltxkeys@d@claremultitypeoptions{%
  \cpt@testpnopt\ltxkeys@d@cl@remultitypeoptions{}%
}
\robust@def*\ltxkeys@d@cl@remultitypeoptions(#1){%
  \cpt@testopt{\ltxkeys@d@cl@rem@ltitypeoptions{#1}}{KV}%
}
\robust@def*\ltxkeys@d@cl@rem@ltitypeoptions#1[#2]{%
  \cpt@testfam{\ltxkeys@d@cl@rem@ltitypeopti@ns{#1}{#2}}%
}
\robust@def*\ltxkeys@d@cl@rem@ltitypeopti@ns#1#2<#3>{%
  \cptexpanded{%
    \ltxkeys@declarekeys\ifcpt@st*\fi
    \iflacus#1\dolacus\else(#1)\fi[#2]{#3}%
  }%
}
\robust@def*\ltxkeys@executeoptions#1{%
  \ltxkeys@nostarform{#1}\ltxkeys@executeoptions
  \ltxkeys@debug{==}{Executing options}%
  \ltxkeys@exoptrue\ltxkeys@stfalse\ltxkeys@pltrue
  \ltxkeys@rmfalse
  \ifsingletokenTF{#1}{%
    \ltxkeys@testopt@@b\ltxkeys@setkeys@a#1%
  }{%
    \ltxkeys@testopt@@b\ltxkeys@setkeys@a{#1}%
  }%
}
\robust@def*\ltxkeys@beforeprocessoptions{%
  \ifcsndefTF{\@currname @\@currext @ltxkeys@beginprocessopt}{%
    \ltxkeys@warn{Command \noexpand\ltxkeys@beforeprocessoptions
      is wrongly located}%
    \@gobble
  }{%
    \grightaddtocsn{\@currname @\@currext
      @ltxkeys@beforeprocessopt@hook}%
  }%
}
\robust@def*\ltxkeys@afterprocessoptions{%
  \ifcsndefTF{\@currname @\@currext @ltxkeys@endprocessopt}{%
    \@firstofone
  }{%
    \grightaddtocsn{\@currname @\@currext
      @ltxkeys@afterprocessopt@hook}%
  }%
}
\robust@def*\ltxkeys@useandrelaxcsn#1{%
  \ifcsndefFT{#1}{}{%
    \letcstocsn\reserved@a{#1}%
    \letcsntocs{#1}\relax
    \reserved@a
  }%
}

\def\ltxkeys@processedoptions{}
\robust@def*\ltxkeys@processoptions{%
  \ifcsndefTF{\@currname @\@currext @ltxkeys@beginprocessopt}{%
    \ltxkeys@err{\noexpand\ltxkeys@processoptions issued twice
      in same \@cls@pkg '\@currname'}\ltxkeys@ehd
  }{%
    \csn@def{\@currname @\@currext @ltxkeys@beginprocessopt}{}%
  }%
  \ltxkeys@useandrelaxcsn
    {\@currname @\@currext @ltxkeys@beforeprocessopt@hook}%
  \ltxkeys@debug{==}{Processing options}%
  \ltxkeys@pltrue\ltxkeys@rmfalse
  \ltxkeys@testopt@@a\ltxkeys@pr@cessoptions
}
\robust@def*\ltxkeys@pr@cessoptions[#1]{%
  \ltxkeys@pxoptrue
  \def\ltxkeys@poxlist{}%
  \let\@fileswith@pti@ns\@badrequireerror
  \edef\ltxkeys@testname{\@currname.\@currext}%
  \ltxkeys@ifxTF\ltxkeys@testname\ltxkeys@documentclass{%
    \let\@unusedoptionlist\ltxkeys@classoptionslist
  }{%
    \ifdefboolFT{ltxkeys@st}{}{%
      \def\ltxkeys@do##1{%
        \edef\CurrentKeyval{\unexpanded{##1}}%
        \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tkey
        \begingroup
        \let\xp\expandcsonce
        \edef\x{[\xp\ltxkeys@prefs]{\xp\ltxkeys@fams}{\xp\ltxkeys@tkey}}%
        \expandafter\endgroup\expandafter\ltxkeys@ifkeydefFT\x{}{%
          \ltxkeys@ifcsemptyTF\@unusedoptionlist{%
            \cptgaddtolist\ltxkeys@processedoptions{##1}%
          }{%
            \cpt@removecurroption{##1}%
            \ltxkeys@debug{==}{Key \ltxkeys@currtriple, removed from
              \string\@unusedoptionlist}%
          }%
          \cptaddtolist\ltxkeys@poxlist{##1}%
        }%
      }%
      \ltxkeys@ifcsemptyTF\ltxkeys@classoptionslist{}
        {\ltxkeys@listparse*0\ltxkeys@classoptionslist}%
    }%
  }%
  \edef\ltxkeys@tempa{\cpt@optionlist{\@currname.\@currext}}%
  \edef\ltxkeys@poxlist
    {\csliststack,\ltxkeys@tempa\expandcsonce\ltxkeys@poxlist}%
  \ltxkeys@ifcsemptyTF\ltxkeys@poxlist{}{%
    \cptexpandargonce{\ltxkeys@setkeys@a[#1]}\ltxkeys@poxlist
  }%
  \s@expandarg\ltxkeys@getkeynames\ltxkeys@poxlist
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \def\ltxkeys@do########1{%
        \ifcsndefTF{\ltxkeys@hdr########1}{%
          \csn@xdef{\ltxkeys@hdr poxkeys}{%
            \csnliststack,{\ltxkeys@hdr poxkeys}%
            \unexpanded{########1}%
          }%
        }%
      }%
      \ltxkeys@listparse*0\ltxkeys@keynames
      \ifcsndefFT{\ltxkeys@hdr optionkeys}{}{%
        \letcstocsn\ltxkeys@tempb{\ltxkeys@hdr poxkeys}%
        \ifdefTF\ltxkeys@tempb{}{\def\ltxkeys@tempb{}}%
        \def\ltxkeys@do########1{%
          \xifinsetTF{,########1,}{,\expandcsonce\ltxkeys@tempb,}{}{%
            \edef\ltxkeys@tempb{%
              \csliststack,\ltxkeys@tempb\unexpanded{########1}%
            }%
          }%
        }%
        \aftercsname{\ltxkeys@listparse*0}{\ltxkeys@hdr optionkeys}%
        \gletcsntocs{\ltxkeys@hdr poxkeys}\ltxkeys@tempb
      }%
    }%
    \ltxkeys@listparse*0\ltxkeys@fams
  }%
  \ltxkeys@listparse*0\ltxkeys@prefs
  \undefcs\ltxkeys@poxlist
  \csn@def{\ltxkeys@hdr rmkeys}{}%
  \ltxkeys@pxopfalse
  \let\@fileswith@pti@ns\@@fileswith@pti@ns
  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
  \ltxkeys@debug{==}{Ended processing options}%
  \ltxkeys@debug{==}{Now doing <afterprocessoptions>}%
  \ltxkeys@useandrelaxcsn
    {\@currname @\@currext @ltxkeys@afterprocessopt@hook}%
  \csn@def{\@currname @\@currext @ltxkeys@endprocessopt}{}%
}
\robust@def*\ltxkeys@ifkeydefTF{\begingroup\ltxkeys@ifkeydef0}
\robust@def*\ltxkeys@ifkeydefFT{\begingroup\ltxkeys@ifkeydef1}
\robust@def*\ltxkeys@ifkeydef#1{\cpt@testopt{\ltxkeys@ifk@ydef#1}{KV}}
\robust@def*\ltxkeys@ifk@ydef#1[#2]#3#4{%
  \ltxkeys@commanormalizeset{{#2}\ltxkeys@prefs,{#3}\ltxkeys@fams}%
  \ltxkeys@trimspaces{#4}\ltxkeys@tkey
  \cpt@choicefdfalse
  \def\ltxkeys@do##1{%
    \ifboolTF{cpt@choicefd}{%
      \loopbreak
    }{%
      \ltxkeys@makepf{##1}%
      \ltxkeys@ifk@yd@f
    }%
  }%
  \ltxkeys@listparse*0\ltxkeys@prefs
  \ltxkeys@ifchcfd#1\endgroup
}
\robust@def*\ltxkeys@ifk@yd@f{%
  \def\ltxkeys@do##1{%
    \ltxkeys@makehdr{##1}%
    \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey}{%
      \cpt@choicefdtrue\loopbreak
    }{}%
  }%
  \ltxkeys@listparse*0\ltxkeys@fams
}
\robust@def*\ltxkeysglobal{\ltxkeys@globaltrue}
\robust@def*\ltxkeysprotected{\ltxkeys@protectedtrue}
\newletcs\ltxkeysrobust\ltxkeysprotected
\robust@def*\ltxkeys@global@protected{%
  \ifltxkeys@global
    \ltxkeys@globalfalse
    \let\ltxkeys@tempa\global
  \else
    \let\ltxkeys@tempa\@empty
  \fi
  \ifltxkeys@protected
    \ltxkeys@protectedfalse\protected
  \fi
  \ltxkeys@tempa
}
\robust@def*\ltxkeyscmd{%
  \let\ltxkeys@inenv\cptswfalse
  \cpt@starorlong\ltxkeys@keycommand
}
\robust@def*\ltxkeys@keycommand#1{%
  \cpt@testopt{\ltxkeys@keycommand@a#1}0%
}
\robust@def*\ltxkeys@keycommand@a#1[#2]{%
  \ltxkeys@inkeycmdtrue
  \cpt@ifbrack
    {\ltxkeys@keycommand@e#1{#2}}{\ltxkeys@keycommand@b#1{#2}}%
}
\robust@def*\ltxkeys@keycommand@b#1#2{%
  \cpt@testltopt{\ltxkeys@keycommand@c{#1}{#2}}{}%
}
\robust@def*\ltxkeys@keycommand@c#1#2<#3>{%
  \cpt@testpnopt{\ltxkeys@keycommand@d{#1}{#2}{#3}}{}%
}
\robust@def\ltxkeys@keycommand@d#1#2#3(#4)#5{%
  \ifcsdefinable#1\relax
  \edef\reserved@a{\cptgobblescape#1}%
  \cptexpandsecond{\ltxkeys@declarekeys*[CMDKEY]}
    {{ltxkeys@\reserved@a}[\reserved@a @]}{#4}%
  \def\reserved@a{\ltxkeys@keycommand@h#1\@ne{#2}{#3}}%
  \expandafter\reserved@a\expandafter{%
    \expandafter\long\expandafter\edef\expandafter
    \ltxkeys@cmdbody\expandafter{\expandafter
    {\ltxkeys@inenv}{\unexpanded{#5}}}%
    \cptexpandarg\cpt@testpnopt{\ltxkeys@keycommand@j
      {\cptgobblescape#1}}{}%
  }%
}
\robust@def*\ltxkeys@keycommand@e#1#2[#3]{%
  \cpt@testltopt{\ltxkeys@keycommand@f{#1}{#2}{#3}}{}%
}
\robust@def*\ltxkeys@keycommand@f#1#2#3<#4>{%
  \cpt@testpnopt{\ltxkeys@keycommand@g{#1}{#2}{#3}{#4}}{}%
}
\robust@def\ltxkeys@keycommand@g#1#2#3#4(#5)#6{%
  \ifcsdefinable#1\relax
  \edef\reserved@a{\cptgobblescape#1}%
  \cptexpandsecond{\ltxkeys@declarekeys*[CMDKEY]}
    {{ltxkeys@\reserved@a}[\reserved@a @]}{#5}%
  \ifltxkeys@global\global\fi
  \ifltxkeys@protected\protected\fi
  \expandafter\def\expandafter#1\expandafter{%
    \expandafter\@protected@testopt\expandafter#1%
    \csname\string#1\endcsname{#3}%
  }%
  \def\reserved@a{%
    \aftercsname\ltxkeys@keycommand@h{\string#1}\tw@{#2}{#4}%
  }%
  \expandafter\reserved@a\expandafter{%
    \expandafter\long\expandafter\edef\expandafter
    \ltxkeys@cmdbody\expandafter{\expandafter
    {\ltxkeys@inenv}{\unexpanded{#6}}}%
    \cptexpandarg\cpt@testpnopt{\ltxkeys@keycommand@j
      {\cptgobblescape#1}}{}%
  }%
}
\robust@def*\ltxkeys@keycommand@h#1#2#3#4{%
  \ifnum#2=\tw@
    \def\ltxkeys@tempb##11{[####1]}%
  \else
    \let\ltxkeys@tempb\@gobble
  \fi
  \expandafter\ltxkeys@keycommand@i\expandafter{\number#3}#1{#4}%
}
\robust@def\ltxkeys@keycommand@i#1#2#3{%
  \begingroup
  \iflacus#3\dolacus
    \let\elt\@gobble
  \else
    \def\elt##1{\expandcsnonce{d##1}}%
    \@tempcnta\z@pt
    \loop
      \advance\@tempcnta\@ne
      \csn@def{d\number\@tempcnta}{}%
      \ifnum\@tempcnta<9\relax
    \repeat
    \@tempcnta\z@pt
    \def\@do##1##2{%
      \edef\ltxkeys@tempa{\cpttrimspace{##1}}%
      \ifstrcmpTF{##1}\keycommand@nil{}{%
        \advance\@tempcnta\@ne
        \ifnum\@tempcnta>#1\relax
          \ltxkeys@err{Number of delimiters exceeds
            number of parameters}\ltxkeys@ehd
        \fi
        \xifinsetTF{,\expandcsonce\ltxkeys@tempa,}%
          {,1,2,3,4,5,6,7,8,9,}{}{%
          \ltxkeys@err{Invalid delimiter syntax:
            \MsgBrk no digit [1-9] found before
            delimiter}\ltxkeys@ehd
        }%
        \csn@edef{d\ltxkeys@tempa}{\cpttrimspace{##2}}%
        \@do
      }%
    }%
    \@do#3\keycommand@nil\keycommand@nil
  \fi
  \iflacus#3\dolacus\else
    \ifx\ltxkeys@tempb\@gobble\else
      \expandafter\ifx\csname d1\endcsname\@empty\else
        \ltxkeys@err{First argument of command \string#2 is
          \MsgBrk already delimited by '[]'}\ltxkeys@ehd
      \fi
    \fi
  \fi
  \edef\ltxkeys@tempc{%
    0####1\ifx\ltxkeys@tempb\@gobble\elt1\fi
    ####2\elt2####3\elt3####4\elt4####5\elt5####6\elt6%
    ####7\elt7####8\elt8####9\elt9%
  }%
  \def\ltxkeys@tempa##1#1##2##{%
    \def\ltxkeys@tempc{%
      \ltxkeys@inkeycmdfalse
      \ltxkeys@global@protected\l@ngrel@x
    }%
    \cptexpandsecond{\expandafter\endgroup\ltxkeys@tempc
      \expandafter\def\expandafter#2\ltxkeys@tempb##1#1}{\elt{#1}}%
  }%
  \expandafter\ltxkeys@tempa\ltxkeys@tempc###1%
}
\robust@def*\ltxkeys@keycommand@j#1(#2){%
  \ltxkeys@setkeys[CMDKEY]{ltxkeys@#1}{#2}%
  \cptpushfunctions\ltxkeyscmd{%
    \\\val\\\ifval\\\ifvalTF\\\keyval\\\ifkeyval\\\ifkeyvalTF
  }\ltxkeyscmd@depth
  \def\val##1{\usename{#1@\cpttrimspace{##1}}}%
  \def\ifval##1\then{\usename{if#1@\cpttrimspace{##1}}}%
  \def\ifvalTF##1{%
    \ifval##1\then\expandafter\cptiofii\else\expandafter\cptiiofii\fi
  }%
  \def\keyval##1{%
    \ifcsndefTF{#1@\cpttrimspace{##1}}{%
      \usename{#1@\cpttrimspace{##1}}%
    }{%
      \ltxkeys@err{Key '\cpttrimspace{##1}' not defined by
        command '\@backslashchar#1'}\ltxkeys@ehd
    }%
  }%
  \def\ifkeyval##1\then{%
    \ifcsndefTF{if#1@\cpttrimspace{##1}}{%
      \usename{if#1@\cpttrimspace{##1}}%
    }{%
      \ltxkeys@err{Key '\cpttrimspace{##1}' not defined by
        command '\@backslashchar#1'}\ltxkeys@ehd
    }%
  }%
  \def\ifkeyvalTF##1{%
    \ifkeyval##1\then\expandafter\cptiofii\else\expandafter\cptiiofii\fi
  }%
  \long\def\reserved@a##1##2\ltxkeys@nil{%
    % \ifswitch won't work here:
    \ifcondTF\if##1\fi{%
      ##2%
    }{%
      ##2%
      \cptpopfunctions\ltxkeyscmd\ltxkeyscmd@depth
    }%
  }%
  \expandafter\reserved@a\ltxkeys@cmdbody\ltxkeys@nil
}
\robust@def*\reltxkeyscmd{%
  \let\ltxkeys@inenv\cptswfalse
  \cpt@starorlong\ltxkeys@rekeycommand
}
\robust@def*\ltxkeys@rekeycommand#1{%
  \ifdefTF{#1}{}{%
    \ltxkeys@warn{Command '\string#1' was previously undefined
      \MsgBrk but now defined by \string\ltsrenewcommand}%
  }%
  \let\ifcsdefinable\rc@ifcsdefinable
  \ltxkeys@keycommand#1%
}
\robust@def*\ltxkeysenv{%
  \let\ltxkeys@inenv\cptswtrue
  \cpt@starorlong\ltxkeys@keyenvironment
}
\robust@def*\ltxkeys@keyenvironment#1{\cpt@testopt{\ltxkeys@newenv@a#1}0}
\robust@def*\ltxkeys@newenv@a#1[#2]{%
  \begingroup
  \toks@{}%
  \ifnum#2=\z@pt\else
    \@tempcnta\z@pt
    \loop
    \advance\@tempcnta\@ne
    \cptexpanded{%
      \toks@{\the\toks@\csn@def{keyenvarg@\romannumeral\@tempcnta}%
        {########\the\@tempcnta}}%
    }%
    \ifnum\@tempcnta<#2\relax
    \repeat
  \fi
  \cpt@ifbrack{\ltxkeys@newenv@b#1[#2]}{\ltxkeys@newenv@c{#1}[#2]}%
}
\robust@def*\ltxkeys@newenv@b#1[#2][#3]{%
  \cpt@testltopt{\ltxkeys@newenv@d{#1}{[#2][{#3}]}}{}%
}
\robust@def*\ltxkeys@newenv@c#1[#2]{%
  \cpt@testltopt{\ltxkeys@newenv@d{#1}{[#2]}}{}%
}
\robust@def*\ltxkeys@newenv@d#1#2<#3>{%
  \cpt@testpnopt{\ltxkeys@newenv@e{#1}{#2}{#3}}{}%
}
\robust@def\ltxkeys@newenv@e#1#2#3(#4)#5#6{%
  \ifcsndefTF{#1}{}{\letcsntocsn{#1}{end#1}}%
  \def\@do##1{\edef\@do{\unexpanded{##1}}}%
  \ifblankTF{#3}{%
    \ifblankTF{#4}{%
      \@do{#2}%
    }{%
      \@do{#2(#4)}%
    }%
  }{%
    \ifblankTF{#4}{%
      \@do{#2<#3>}%
    }{%
      \@do{#2<#3>(#4)}%
    }%
  }%
  \xdef\ltxkeys@newenv@f{%
    \ifltxkeys@global\global\fi
    \ifltxkeys@protected\protected\fi
  }%
  \cptexpandsecond{%
    \endgroup\ltxkeys@keycommand
  }{%
    \noexpandcsn{#1}\expandcsonce\@do{%
      \the\toks@\unexpanded{#5}%
    }%
  }%
  \ltxkeys@newenv@f
  \l@ngrel@x\csn@def{end#1}{%
    \def\envarg####1{\usename{keyenvarg@\romannumeral####1}}%
    #6\relax
    \cptpopfunctions\ltxkeyscmd\ltxkeyscmd@depth
    \ltxkeys@everyeoehook
  }%
}
\robust@def*\reltxkeysenv{%
  \let\ltxkeys@inenv\cptswtrue
  \cpt@starorlong\ltxkeys@rekeyenvironment
}
\robust@def*\ltxkeys@rekeyenvironment#1{%
  \ifdefTF{#1}{}{%
    \ltxkeys@warn{Environment '\string#1' was previously undefined
      \MsgBrk but now defined by \string\reltxkeysenv}%
  }%
  \letcsntocs{#1}\relax
  \letcsntocs{end#1}\relax
  \ltxkeys@keyenvironment{#1}%
}
\robust@def\ltxkeys@ifpattern#1#2{%
  \begingroup
  \edef\ltxkeys@tempa##1{\def##1####1\detokenize{#1}####2&}%
  \ltxkeys@tempa\ltxkeys@tempa{%
    \aftercsname\endgroup{@\ifblankTF{##2}{second}{first}oftwo}%
  }%
  \edef\ltxkeys@tempb##1{##1\detokenize{#1}&}%
  \ltxkeys@tempb{\expandafter\ltxkeys@tempa\meaning#2}%
}

\new@def*\ltxkeys@everyeoehook{}
\robust@def*\ltxkeys@everyeoe#1{%
  \ifblankTF{#1}{%
    \gdef\ltxkeys@everyeoehook{}%
  }{%
    \xdef\ltxkeys@everyeoehook{%
      \unexpanded{#1}\expandcsonce\ltxkeys@everyeoehook
    }%
  }%
  \ltxkeys@ifpattern\@ignoretrue\ltxkeys@everyeoehook{%
    \ltxkeys@ifpattern\ignorespacesafterend\ltxkeys@everyeoehook{%
      \ltxkeys@err{Bad '\string\ltxkeys@everyeoe'}
        {You can't have both '\string\@ignoretrue' and
        '\string\ignorespacesafterend' in
        \MsgBrk '\string\ltxkeys@everyeoe'.}%
    }{%
      \ltxkeys@checkbadeoe\@ignoretrue
    }%
  }{%
    \ltxkeys@ifpattern\ignorespacesafterend\ltxkeys@everyeoehook{%
      \ltxkeys@checkbadeoe\ignorespacesafterend
    }{}%
  }%
}
\new@def*\ltxkeys@checkbadeoe#1{%
  \begingroup
  \edef\ltxkeys@tempa##1{\def##1####1\detokenize{#1}####2&}%
  \ltxkeys@tempa\ltxkeys@tempa{%
    \ifblankTF{##2}{}{%
      \xifinsetTF{\detokenize{#1}}{##2}{%
        \ltxkeys@err{'\detokenize{#1}' repeated in
          '\string\ltxkeys@everyeoe'.}
          {Multiple '\detokenize{#1}' not allowed in
          '\string\ltxkeys@everyeoe'.}%
      }{%
        \ltxkeys@err{Bad last token in '\string\ltxkeys@everyeoe'}
          {'\detokenize{#1}' not the last token in
          '\string\ltxkeys@everyeoe'.}%
      }%
    }%
  }%
  \expandafter\ltxkeys@tempa\meaning\ltxkeys@everyeoehook&%
  \endgroup
}
\ltxkeys@everyeoe\ignorespacesafterend

\robust@def*\setvarvalues{\cpt@testopt\ltxkeys@setvarvalues{var@subfam}}
\robust@def*\ltxkeys@setvarvalues[#1]#2{\pathkeys{pathkeys@var@fam/#1/set:#2}}
\new@def*\getvarvalue{\cpt@newxtestopt\ltxkeys@getvarvalue{var@subfam}}
\new@def*\ltxkeys@getvarvalue[#1]#2{\pathkeysval{pathkeys@var@fam/#1/#2}}
\robust@def*\ltxkeys@declarevariables{%
  \cpt@testopt\ltxkeys@d@clarevariables{var@subfam}%
}
\robust@def*\ltxkeys@d@clarevariables[#1]#2{%
  \begingroup
  \def\elt##1{\oifstrcmpTF{^?^}{##1}{}{/\expandcsonce##1}}%
  \cptdocommalist{#2}{%
    \ltxkeys@d@cl@revariables##1=^?^=^?^=\ltxkeys@nil
  }%
  \cptexpanded{\endgroup
    \pathkeys{pathkeys@var@fam/#1/define*:\expandcsonce\key@list}%
  }%
}
\robust@def*\ltxkeys@d@cl@revariables#1={%
  \def\reserved@a##1={%
    \def\reserved@a####1=####2\ltxkeys@nil{%
      \ltxkeys@trimspaces{#1}\reserved@a
      \ltxkeys@remdottrimspaces{##1}\reserved@b
      \ltxkeys@remdottrimspaces{####1}\reserved@c
      \cptexpanded{%
        \cptgaddtolist[;]\noexpand\key@list{%
          \cptexpandbracenext{\cptifcasse\ifstrcmpTF}\reserved@a
            {true}{bool}{false}{bool}%
          \elseif
            cmd%
          \endif
          /\expandcsonce\reserved@a\elt\reserved@b\elt\reserved@c
        }%
      }%
    }%
    \reserved@a.%
  }%
  \reserved@a.%
}
\robust@def*\ltxkeys@emergencystop{%
  \immediate\write\sixt@@n{OK, I'm exiting now.}%
  \interactionmode\z@pt
  \ifnumcmpTF\currentgrouptype>\z@pt{%
    \endgroup\aftergroup\@@end
  }{%
    \aftergroup\@@end
  }%
}
\robust@def*\ltxkeys@unknownoptionerror{%
  \ltxkeys@err{Unknown option '\CurrentKey' for
    \@cls@pkg\space '\@currname'}
    {Unknown option '\CurrentKey' for \@cls@pkg\space '\@currname'.
    \MsgBrk The option '\CurrentKey' was not declared in \@cls@pkg
    \MsgBrk'\@currname'. Perhaps you misspelled its name.
  }%
}
\cptonlypreamble{%
  \ltxkeys@declareoption,\ltxkeys@declareoptions,
  \ltxkeys@declareordoption,\ltxkeys@declareordoptions,
  \ltxkeys@declarecmdoption,\ltxkeys@declarecmdoptions,
  \ltxkeys@declarebooloption,\ltxkeys@declarebooloptions,
  \ltxkeys@declarechoiceoption,\ltxkeys@declarechoiceoptions,
  \ltxkeys@processoptions,\ltxkeys@executeoptions,
  \ltxkeys@unknownoptionhandler,\ltxkeys@declaremultitypeoptions,
  \declaremultitypeoptions
}
\ltxkeys@declareoption*[KV]<ltxkeys>{%
  \ltxkeys@warn{Unknown option '\CurrentKey' with
    value '\InnocentVal' ignored.}%
}
\ltxkeys@declarecmdoption[KV]<ltxkeys>[ltxkeys@]{keyparser}[{;}]{%
  \ltxkeys@stripallouterbracesincs\ltxkeys@keyparser
}
\ltxkeys@declarecmdoption[KV]<ltxkeys>[ltxkeys@]{%
  \needvalue{keydepthlimit}%
}{%
  \ifblankTF{#1}{%
    \ltxkeys@err{Invalid empty value for 'keydepthlimit'}
    \ltxkeys@ehd
  }{%
    \xdef\cpt@optionstacklimit{\number0#1}%
  }%
}
\ltxkeys@declarecmdoption[KV]<ltxkeys>[ltxkeys@]{%
  \needvalue{keystacklimit}%
}{%
  \ltxkeys@setaliaskey{keydepthlimit}%
}
\ltxkeys@declarebooloptions[KV]<ltxkeys>[ltxkeys@]{%
  tracingkeys,reservenopath
}[true]{}
\ltxkeys@declarebooloption[KV]<ltxkeys>[ltxkeys@]{allowemptypath}[true]{%
  \ifltxkeys@allowemptypath\ltxkeys@useemptytrue\fi
}
\ltxkeys@executeoptions[KV]<ltxkeys>{keyparser,keydepthlimit=4}\relax

\ltxkeys@processoptions*[KV]<ltxkeys>\relax

\cpt@optioncleanup\ltxkeys@processedoptions

\robust@def*\setltxkeysoptions#1{%
  \ifblankTF{#1}{}{\ltxkeys@setkeys[KV]{ltxkeys}{#1}}%
}

\endinput

%% End of file ltxkeys.sty %%
