%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
%                                                                          %
% This is file 'ltxkeys.sty', version 0.1.0, July 2011.                    %
%                                                                          %
% 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 Ahmed Musa (amusa22@gmail.com).                       %
%                                                                          %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
\RequirePackage{catoptions}[2011/07/07]
\UseNormalCatcodes
\StyleFilePurpose{Robust and fast key-value parser}
\StyleFileRCSInfo
$Id: ltxkeys.sty,v 0.1.0 2011/07/07 09:00:00 Ahmed Musa Exp $
\ProvidesPackage{ltxkeys}[\StyleFileInfo]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\SetStyleFileMessages[ltxkeys@]{info}{warn}{err}
\newvariables{if}[ltxkeys@]{break,st,pl,sw,sv,noval,pxop,exop,kf,
  rm,ssk,dec,dep,twk,verbose,inputvalid}[false]
\newvariables{if}{inputvalid}[false]
\robust@def*\SetSlaveWithMaster{\global\ltxkeys@ssktrue}
\robust@def*\SetNoSlaveWithMaster{\global\ltxkeys@sskfalse}
\SetNoSlaveWithMaster
\newvariables{count}[ltxkeys@]{csvdepth,keydepth}[\z@pt]
\newletcs\ltxkeys@nil\relax
\new@def*\ltxkeys@nnil{\ltxkeys@nil}
\ifdefTF\cpt@documentclass{}{%
  \ltxkeys@err{No \string\documentclass}\@ehc
  \emptifycsset{\cpt@documentclass,\cpt@classoptionslist}%
}
\robust@def*\ltxkeys@gobble@to@nil{%
  \begingroup
  \defpass\reserved@a##1\ltxkeys@nil{\endgroup}%
}
\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@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@kf,\ifltxkeys@pxop,\ifltxkeys@exop,\CurrentKeyval,%
  \CurrentKey,\CurrentVal
}
\robust@def*\ltxkeys@trimspaces{\begingroup\ltxkeys@tr@mspaces}
\robust@def*\ltxkeys@trimspacesincs#1{\s@expandarg\ltxkeys@trimspaces{#1}#1}
\defpass\reserved@a#1{%
  \long\def\ltxkeys@tr@mspaces##1##2{%
    \edef\reserved@a{%
      \expandcsonce{\romannumeral-`\q
        \ltxkeys@trimspace.##1\trimsp@nil#1\trimsp@nil}%
    }%
    \ifxTF##2\reserved@a{%
      \cptpassacross##2\endgroup
    }{%
      \let##2=\reserved@a
      \expandafter\ltxkeys@tr@mspaces\expandafter{##2}##2%
    }%
  }%
  \long\def\ltxkeys@trimspace##1#1\trimsp@nil{%
    \ltxkeys@tr@mspace##1\trimsp@nil
  }%
  \long\def\ltxkeys@tr@mspace##1\trimsp@nil##2{%
    \expandafter\noexpand\@gobble##1%
  }%
}{ }
\newvariables{tog}{rem@repl,rem@repl@all}
\robust@def*\ltxkeys@removeoneelement{\cpt@testopt\ltxkeys@rem@veoneelement,}
\robust@def\ltxkeys@rem@veoneelement[#1]#2#3{%
  \ifcpt@check\cpt@checklistparser{#1}\relax\fi
  \begingroup
  \edef\parser{\detokenize{#1}}%
  \def\ltxkeys@tempa##1{%
    \def\ltxkeys@remove####1#1##1#1####2\remove@nil{%
      \def#2{####1#1####2}%
      \cpt@trimparser[#1]#2%
    }%
    \xifinsetTF{\detokenize{#1##1#1}}{\parser\cptoxdetok{#2}\parser}{%
      \expandafter\ltxkeys@remove\expandafter#1#2#1\remove@nil
      \iftogFT{rem@repl@all}{}{%
        \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
      }%
    }{}%
  }%
  \iftogTF{rem@repl}{%
    \edef\ltxkeys@tempb{\unexpanded{#3}}%
  }{%
    \cpt@sttrue\cpt@csvnormalize[#1]#2%
    \ltxkeys@trimspaces{#3}\ltxkeys@tempb
  }%
  \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
  \postgroupdef#2\endgroup
}
\robust@def*\ltxkeys@removeelements{\cpt@testopt\ltxkeys@rem@veelements,}
\robust@def\ltxkeys@rem@veelements[#1]#2#3{%
  \begingroup
  \cpt@sttrue\cpt@csvnormalize[#1]#2%
  \cpt@checkfalse
  \togtrue{rem@repl}%
  \long\def\csv@do##1{%
    \ltxkeys@removeoneelement[#1]#2{##1}%
  }%
  \csv@@parse[#1]{#3}%
  \postgroupdef#2\endgroup
}
% \ltxkeys@replaceoneelement[<parser>]{<cs>}{<search>}{<replace>}
\robust@def*\ltxkeys@replaceoneelement{%
  \cpt@testopt\ltxkeys@repl@ceoneelement,%
}
\robust@def\ltxkeys@repl@ceoneelement[#1]#2#3#4{%
  \ifcpt@check\cpt@checklistparser{#1}\relax\fi
  \begingroup
  \edef\parser{\detokenize{#1}}%
  \def\ltxkeys@tempa##1{%
    \def\ltxkeys@replace####1#1##1#1####2\rep@nil{%
      \def#2{####1#1#4#1####2}%
      \cpt@trimparser[#1]#2%
    }%
    \xifinsetFT{\detokenize{#1##1#1}}{\parser\cptoxdetok#2\parser}{}{%
      \expandafter\ltxkeys@replace\expandafter#1#2#1\rep@nil
      \iftogFT{rem@repl@all}{}{%
        \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
      }%
    }%
  }%
  \iftogTF{rem@repl}{%
    \edef\ltxkeys@tempb{\unexpanded{#3}}%
  }{%
    \cpt@sttrue\cpt@csvnormalize[#1]#2%
    \ltxkeys@trimspaces{#3}\ltxkeys@tempb
  }%
  \expandafter\ltxkeys@tempa\expandafter{\ltxkeys@tempb}%
  \postgroupdef#2\endgroup
}
\robust@def*\ltxkeys@replaceelements{\cpt@testopt\ltxkeys@repl@ceelements,}
\robust@def\ltxkeys@repl@ceelements[#1]#2#3#4{%
  \begingroup
  \edef\ltxkeys@tempa{\unexpanded{#3}}%
  \edef\ltxkeys@tempb{\unexpanded{#4}}%
  \def\csv@do##1{\cpt@sttrue\cpt@csvnormalize[#1]##1}%
  \csv@@loop[,]{#2,\ltxkeys@tempa,\ltxkeys@tempb}%
  \def\ltxkeys@tempc##1#1##2\noboundary##3#1##4\noboundary{%
    \ltxkeys@replaceoneelement[#1]#2{##1}{##3}%
    \ifblankTF{##2}{}{%
      \ifblankTF{##4}{}{%
        \ltxkeys@tempc##2\noboundary##4\noboundary
      }%
    }%
  }%
  \cpt@checkfalse
  \togtrue{rem@repl}%
  \cptexpandsecond\ltxkeys@tempc{%
    \expandcsonce\ltxkeys@tempa#1\noboundary
    \expandcsonce\ltxkeys@tempb#1\noboundary
  }%
  \postgroupdef#2\endgroup
}
\robust@def*\ltxkeys@oneoftwo#1\endgroup{%
  \let\@firstoftwo\relax
  \let\@secondoftwo\relax
  \edefpass\ltxkeys@tempa{\endgroup
    \ifcase#1\relax
      \if@boolTF{cpt@choicefd}\@firstoftwo\@secondoftwo
    \or
      \if@boolTF{cpt@choicefd}\@secondoftwo\@firstoftwo
    \else
      \ltxkeys@err{Invalid number '#1'}\noexpand\@ehc
    \fi
  }%
}
\robust@def*\ltxkeys@getorder#1#2{%
  \def\ltxkeys@order{-1}%
  \begingroup
  \lowercase{\ltxkeys@trimspaces{#1}\ltxkeys@tempa}%
  \@tempcnta\z@pt
  \toks@{}%
  \def\ltxkeys@do##1{%
    \oifstrcmpFT\ltxkeys@tempa{##1}{}{%
      \cptexpanded{%
        \toks@{\def\noexpand\ltxkeys@order{\the\@tempcnta}}%
      }%
      \ltxkeys@breaktrue
    }%
    \advance\@tempcnta\@ne
  }%
  \ltxkeys@csvparse{#2}%
  \expandafter\endgroup\the\toks@
}
\robust@def*\ltxkeys@ifeltcountTF{\cpt@testopt\ltxkeys@ifeltcount{=}}
\robust@def*\ltxkeys@ifeltcount[#1]#2#3{%
  \begingroup
  \def\ltxkeys@do##1{\advance\@tempcnta by1}%
  \@tempcnta\z@pt
  \ltxkeys@csvloop{#2}%
  \expandafter\endgroup\csname @\ifnum\@tempcnta#1\numexpr#3%
    first\else second\fi oftwo\endcsname
}
\robust@def*\ltxkeys@nomatcherr{%
  \ltxkeys@err{User input '\reserved@e' not in list:
    \MsgBrk '\reserved@f'}\@ehc
  \@gobble
}
% A re-implementation of xkeyval's \XKV@checkchoice for
% arbitrary parser and more robustness:
\robust@def*\ltxkeys@checkchoice{%
  \cpt@teststpl{\cpt@testopt\ltxkeys@cc@a,}%
}
\robust@def*\ltxkeys@cc@a[#1]{%
  \ifcpt@check\cpt@checklistparser{#1}{}\fi
  \cpt@testopt{\ltxkeys@cc@b#1}{}%
}
\robust@def*\comma@cc{%
  \cpt@teststpl{\cpt@testopt{\ltxkeys@cc@b,}{}}%
}
\robust@def*\CheckInput#1#2{%
  \lowercase{\edef\nominations{\unexpanded{#2}}}%
  \cpt@sttrue\cpt@pltrue
  \ltxkeys@cc@b,[\userinput\nr]{#1}{#2}{%
    \inputvalidtrue
  }{%
    \inputvalidfalse
  }%
}
\robust@def*\ltxkeys@cc@b#1[#2]#3#4{%
  \begingroup
  \ifcpt@st\lowercase{\fi
    \ltxkeys@trimspaces{#3}\user@input
    \edef\valid@vals{\unexpanded{#4}}%
  \ifcpt@st}\fi
  \def\ltxkeys@ccparser{#1}%
  \cpt@sttrue\cpt@csvnormalize[#1]\valid@vals
  \cptexpandsecond{%
    \ifblankTF{#2}\ltxkeys@cc@d{\ltxkeys@cc@c#2}\ltxkeys@nil
  }{%
    {\expandcsonce\user@input}{\expandcsonce\valid@vals}%
  }%
}
\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}%
  \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{%
    \if@boolTF{cpt@pl}{%
      \rightaddtocs\ltxkeys@tempa\@firstoftwo
    }{%
      \rightaddtocs\ltxkeys@tempa\@firstofone
    }%
  }{%
    \if@boolTF{cpt@pl}{%
      \rightaddtocs\ltxkeys@tempa\@secondoftwo
    }{%
      \rightaddtocs\ltxkeys@tempa{%
        \expandafter\ltxkeys@nomatcherr\@gobble
      }%
    }%
  }%
  \cptpassexpanded{%
    \endgroup
    \def\noexpand\reserved@e{\expandcsonce\user@input}%
    \def\noexpand\reserved@f{\expandcsonce\valid@vals}%
    \expandcsonce\ltxkeys@tempa
  }%
}
\robust@def*\ltxkeys@cc@e#1#2#3#4{%
  \chardef#2\z@pt
  \cpt@choicefdfalse
  \def\csv@do##1{%
    \def#1{##1}%
    \ifstrcmpTF{##1}{#3}{%
      \cpt@choicefdtrue\cptbreakloop
    }{%
      \pushnumber#2%
    }%
  }%
  \expandafter\csv@@loop\expandafter[\ltxkeys@ccparser]{#4}%
  \cptpassexpanded{%
    \endgroup
    \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
        \def\noexpand\reserved@e{\expandcsonce\user@input}%
        \def\noexpand\reserved@f{\expandcsonce\valid@vals}%
        \unexpanded{\expandafter\ltxkeys@nomatcherr\@gobble}%
      \fi
    \fi
  }%
}

% \ltxkeys@ifincsvlistTF*[parser](no.){sublist}{mainlist}{true}{false}
\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\itemspresent{}%
  \def\csv@do##1{%
    \xifinsetFT{\detokenize{#1##1#1}}
      {\parser\cptoxdetok\ltxkeys@tempb\parser}{}{%
      \edef\itemspresent{\cptliststack,\itemspresent\unexpanded{##1}}%
      \advance\cpt@cnta\@ne
    }%
    \ifnum\cpt@cnta>\numexpr#2-1\relax\cptbreakloop\fi
  }%
  \csv@@parse*[#1]\ltxkeys@tempa
  \ifnum\cpt@cnta>\numexpr#2-1\relax
    \edef\nritems{\the\cpt@cnta}%
  \else
    \def\itemspresent{}\def\nritems{-1}%
  \fi
  \cptexpandsecond\endgroup{%
    \cpt@csexit\itemspresent\cpt@csexit\nritems
    \ifx\itemspresent\@empty\noexpand\@secondoftwo\else
      \noexpand\@firstoftwo\fi
  }%
}
% \ltxkeys@ifintsvlistTF(no){sublist}{mainlist}{true}{false}
\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\itemspresent{}\cpt@cnta\z@pt
  \def\tsv@do##1{%
    \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{%
      \edef\itemspresent{\cptliststack{}\itemspresent\unexpanded{##1}}%
      \advance\cpt@cnta\@ne
    }%
    \ifnum\cpt@cnta>\numexpr#1-1\relax\cptbreakloop\fi
  }%
  \s@expandarg\tsv@@parse\ltxkeys@tempa
  \ifnum\cpt@cnta>\numexpr#1-1\relax
    \edef\nritems{\the\cpt@cnta}%
  \else
    \def\itemspresent{}\def\nritems{-1}%
  \fi
  \cptexpandsecond\endgroup{%
    \cpt@csexit\itemspresent\cpt@csexit\nritems
    \ifx\itemspresent\@empty\noexpand\@secondoftwo\else
      \noexpand\@firstoftwo\fi
  }%
}
% \ltxkeys@ifinTF*(no.){sublist}{mainlist}{true}{false}
\robust@def*\ltxkeys@ifinTF{%
  \cpt@testst{\cpt@testpnopt\ltxkeys@ifin{1}}%
}
\robust@def*\ltxkeys@ifin(#1)#2#3{%
  \begingroup
  \ifcpt@st\lowercase{\fi
    \edef\ltxkeys@tempa{\unexpanded{#2}}%
    \edef\ltxkeys@tempb{\unexpanded{#3}}%
  \ifcpt@st}\fi
  \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@tempa
  \cpt@cnta\z@pt\def\itemspresent{}%
  \def\do##1,{%
    \ifnot@nil{##1}{%
      \xifinsetFT{\detokenize{##1}}{\cptoxdetok\ltxkeys@tempb}{}{%
        \edef\itemspresent{\cptliststack,\itemspresent\unexpanded{##1}}%
        \advance\cpt@cnta\@ne
      }%
      \ifnumcmpTF\cpt@cnta>\numexpr#1-1{\gobble@to@sentinel\@nil,}{\do}%
    }%
  }%
  \expandafter\do\ltxkeys@tempa,\@nil,%
  \ifnum\cpt@cnta>\numexpr#1-1\relax
    \edef\nritems{\the\cpt@cnta}%
  \else
    \def\itemspresent{}\def\nritems{-1}%
  \fi
  \cptexpandsecond\endgroup{%
    \cpt@csexit\itemspresent\cpt@csexit\nritems
    \ifcsemptyTF\itemspresent{\noexpand\@secondoftwo}
      {\noexpand\@firstoftwo}%
  }%
}
\robust@def*\ltxkeys@inpkgcls#1{%
  \ifinstylefileTF{}{%
    \ltxkeys@err{Command '\detokenize{#1}' issued outside
      style file}{The command '\detokenize{#1}' is available
      only in style files.}%
  }%
}
\new@def*\ltxkeys@parsestack{}
\newletcs\ltxkeys@break\ltxkeys@breaktrue
\robust@def*\ltxkeys@csvloop{%
  \let\ltxkeys@nlz\cptfalse
  \let\ltxkeys@inkv\cptfalse
  \cpt@testst\ltxkeys@parse@a
}
\robust@def*\ltxkeys@csvparse{%
  \let\ltxkeys@nlz\cpttrue
  \let\ltxkeys@inkv\cptfalse
  \cpt@testst\ltxkeys@parse@a
}
\robust@def*\ltxkeys@kvloop{%
  \let\ltxkeys@nlz\cptfalse
  \let\ltxkeys@inkv\cpttrue
  \cpt@testst\ltxkeys@parse@a
}
\robust@def*\ltxkeys@kvparse{%
  \let\ltxkeys@nlz\cpttrue
  \let\ltxkeys@inkv\cpttrue
  \cpt@testst\ltxkeys@parse@a
}
\robust@def*\ltxkeys@parse@a#1{%
  \cpt@stchoose{cpt@st}{#1}\ltxkeys@arg\ltxkeys@parse@a
  \global\advance\ltxkeys@csvdepth\@ne
  \letcsntocsn{ifltxkeys@break@\romannumeral\ltxkeys@csvdepth}
    {ifltxkeys@break}%
  \letcsntocs{ltxkeys@doo@\romannumeral\ltxkeys@csvdepth}\ltxkeys@doo
  \xdef\ltxkeys@parsestack{%
    \letcsntocsn{ifltxkeys@break}
      {ifltxkeys@break@\romannumeral\ltxkeys@csvdepth}%
    \letcsntocsn{ltxkeys@doo}{ltxkeys@doo@\romannumeral\ltxkeys@csvdepth}%
    \ltxkeys@nil{\expandcsonce\ltxkeys@parsestack}%
  }%
  \ifdefTF\ltxkeys@do
    {\let\ltxkeys@doo\ltxkeys@do}{\cpt@notdeferr\ltxkeys@do}%
  \def\ltxkeys@parse@b{%
    \if@boolTF{ltxkeys@break}{%
      \defpass\reserved@a####1\ltxkeys@nil,{}%
    }{%
      \ltxkeys@parse@c.%
    }%
  }%
  \long\def\ltxkeys@parse@c##1,{%
    \edef\ltxkeys@arg{\expandcsonce{\@gobble##1}}%
    \ifxTF\ltxkeys@arg\ltxkeys@nnil{}{%
      \ifxTF\@empty\ltxkeys@arg{}{%
        \expandafter\ltxkeys@doo\expandafter{\ltxkeys@arg}\relax
      }%
      \ltxkeys@parse@b
    }%
  }%
  \ifpsiboolTF{ltxkeys@nlz}{%
    \cpt@sttrue
    \usename{cpt@\if\ltxkeys@inkv kv\else csv\fi normalize}[,]\ltxkeys@arg
  }{}%
  \ltxkeys@breakfalse
  \expandafter\ltxkeys@parse@b\ltxkeys@arg,\ltxkeys@nil,%
  \def\reserved@a##1\ltxkeys@nil{##1\gdef\ltxkeys@parsestack}%
  \expandafter\reserved@a\ltxkeys@parsestack
  \global\advance\ltxkeys@csvdepth\m@one
  \ifnum\ltxkeys@csvdepth=\z@pt\undefcs\ltxkeys@do\fi
}
\robust@def*\ltxkeys@testopt@a#1{\cpt@testopt{\ltxkeys@testopt@b#1}{KV}}
\robust@def*\ltxkeys@testopt@b#1[#2]#3{%
  \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}\@ehc
    }%
    \ltxkeys@ifeltcountTF[>]{#2}\@ne{%
      \temp@err{prefixes}%
    }{%
      \ltxkeys@ifeltcountTF[>]{#3}\@ne{%
        \temp@err{families}%
      }{}%
    }%
  \fi
  \endgroup
  \def\ltxkeys@prefs{#2}%
  \def\ltxkeys@fams{#3}%
  \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@prefs
  \cpt@sttrue\cpt@csvnormalize[,]\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{%
  \if@boolTF{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]{%
  \def\ltxkeys@prefs{#2}%
  \cpt@testfam{\ltxkeys@testopt@@d#1}%
}
\robust@def*\ltxkeys@testopt@@d#1<#2>{%
  \edef\ltxkeys@fams{#2}%
  \cpt@testopt{#1}{}%
}
\robust@def*\ltxkeys@findneedvalue#1{%
  \ltxkeys@findpointer\needvalue{#1}\ltxkeys@tkey{%
    \ltxkeys@addtopointedkeys{needvalue}\ltxkeys@tkey
  }{}%
}
\robust@def*\ltxkeys@findpointer#1#2#3{%
  \def\reserved@a##1#1##2##3\ltxkeys@nil{%
    \edef#3{\unexpanded{##2}}%
    \ifxTF#3\ltxkeys@nnil{%
      \edef#3{\unexpanded{##1}}%
      \ltxkeys@trimspacesincs#3%
      \@secondoftwo
    }{%
      \ltxkeys@trimspacesincs#3%
      \@firstoftwo
    }%
  }%
  \reserved@a#2#1{\ltxkeys@nil}\ltxkeys@nil
}
\robust@def*\ltxkeys@addtopointedkeys#1#2{%
  \letcstocsn\reserved@a{\ltxkeys@hdr#1@keys}%
  \ifdefTF\reserved@a{%
    \xifinsetTF{,\cptoxdetok{#2},}{,\cptoxdetok\reserved@a,}{}{%
      \csn@xdef{\ltxkeys@hdr#1@keys}%
        {\cptliststack,\reserved@a\expandcsonce{#2}}%
    }%
  }{%
    \csn@xdef{\ltxkeys@hdr#1@keys}{\expandcsonce{#2}}%
  }%
}
\robust@def*\ltxkeys@makepf#1{%
  \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@ttpref
  \edef\ltxkeys@tpref{%
    \ifcsnullTF\ltxkeys@ttpref{}{\ltxkeys@ttpref @}%
  }%
}
\robust@def*\ltxkeys@makehdr#1{%
  \s@expandarg\ltxkeys@trimspaces{#1}\ltxkeys@tfam
  \edef\ltxkeys@hdr{%
    \ltxkeys@tpref\ifcsnullTF\ltxkeys@tfam{}{\ltxkeys@tfam @}%
  }%
}
\robust@def*\ltxkeys@saveinitialkeyvals#1#2#3{%
  \xifinsetTF{\detokenize{\savevalue}}{\cptoxdetok{#2}}{%
    \ltxkeys@err{\noexpand\savevalue pointer not allowed
      \MsgBrk when defining a key}\@ehc
  }{}%
  \ifltxkeys@twk\else
    \ifltxkeys@sv
      \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr initial@keyvals}%
      \csn@xdef{\ltxkeys@hdr initial@keyvals}{%
        \cptliststack,\ltxkeys@tempa\expandcsonce{#2}=%
        \ifstrcmpTF{#1}{bool}{false}{\unexpanded{#3}}%
      }%
    \fi
  \fi
  \ifltxkeys@verbose
    \wlog{Key defined: \ltxkeys@ttpref, \ltxkeys@tfam, \ltxkeys@tkey.}%
  \fi
}
% \ltxkeys@ordkey[pref]{fam}{key}[dft]{fn}
\robust@def*\ltxkeys@ordkey{%
  \ltxkeys@svtrue\ltxkeys@swfalse
  \ltxkeys@testopt@a\ltxkeys@ordkey@a
}
\robust@def*\ltxkeys@ordkey@a#1{%
  \ltxkeys@findneedvalue{#1}%
  \cpt@ifbrack{%
    \ltxkeys@bracedefault
      {\ltxkeys@sttrue\s@expandarg\ltxkeys@ordkey@b\ltxkeys@tkey}%
  }{%
    \ltxkeys@stfalse\s@expandarg\ltxkeys@ordkey@b\ltxkeys@tkey[]%
  }%
}
\robust@def*\ltxkeys@ordkey@b#1[#2]#3{%
  \if@boolFT{ltxkeys@st}{}{\ltxkeys@definedefault{#1}{#2}}%
  \ltxkeys@saveinitialkeyvals{}{#1}{#2}%
  \csn@def{\ltxkeys@hdr#1}##1{#3}%
}
% \ltxkeys@cmdkey[pref]{fam}[mp]{key}[dft]{fn}
\robust@def*\ltxkeys@cmdkey{%
  \ltxkeys@svtrue\ltxkeys@swfalse
  \ltxkeys@testopt@e\ltxkeys@cmdkey@a{cmd}%
}
\robust@def*\ltxkeys@cmdkey@a#1#2[#3]#4{%
  \ltxkeys@findneedvalue{#2}%
  \if@boolFT{ltxkeys@st}{}{\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}%
}
% \ltxkeys@boolkey[pref]{fam}[mp]{key}[dft]{fn}
% \ltxkeys@boolkey+[pref]{fam}[mp]{key}[dft]{fn}{keyvalerr}
\robust@def*\ltxkeys@boolkey{%
  \ltxkeys@svtrue\ltxkeys@swtrue
  \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@boolkey@a{bool}}%
}
\robust@def*\ltxkeys@boolkey@a#1#2[#3]{%
  \ltxkeys@findneedvalue{#2}%
  \ltxkeys@saveinitialkeyvals{bool}\ltxkeys@tkey{#3}%
  \aftercsname{\if@boolTF{ltxkeys@pl}\ltxkeys@boolkey@c\ltxkeys@boolkey@b}%
    {\ltxkeys@hdr\ltxkeys@tkey}{\ltxkeys@tkey}{#1\ltxkeys@tkey}{#3}%
}
\robust@def*\ltxkeys@boolkey@b#1#2#3#4#5{%
  \ltxkeys@boolkey@d#1{#2}{#3}{#4}%
    {{\ltxkeys@setbool\ltxkeys@resa\usename{#3\ltxkeys@resa}#5}}%
}
\robust@def*\ltxkeys@boolkey@c#1#2#3#4#5#6{%
  \ltxkeys@boolkey@d#1{#2}{#3}{#4}%
    {{\ltxkeys@setbool\ltxkeys@resa\usename{#3\ltxkeys@resa}#5}{#6}}%
}
\robust@def*\ltxkeys@boolkey@d#1#2#3#4#5{%
  \csn@newif{#3}%
  \if@boolFT{ltxkeys@st}{}{\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>}
\robust@def*\ltxkeys@biboolkeys{%
  \ltxkeys@svtrue\ltxkeys@swtrue
  \ltxkeys@testpl{\ltxkeys@testopt@e\ltxkeys@biboolkeys@a{}}%
}
\robust@def*\ltxkeys@biboolkeys@a#1#2[#3]{%
  \if@boolTF{ltxkeys@pl}\ltxkeys@biboolkeys@c\ltxkeys@biboolkeys@b
  {#1}{#2}{#3}%
}
\robust@def*\ltxkeys@biboolkeys@b#1#2#3#4#5{%
  \ltxkeys@biboolkeys@d{#1}{#2}{#3}%
  \ltxkeys@tempa{#4}%
  \ltxkeys@tempb{#5}%
}
\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}%
}
\robust@def*\ltxkeys@biboolkeys@d#1#2#3{%
  \ltxkeys@ifeltcountTF[=]{#2}\tw@{}{%
    \ltxkeys@err{Biboolean keys '#2' not equal to 2}\@ehc
    \@gobble
  }%
  \def\ltxkeys@keys{#2}%
  \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@keys
  \def\ltxkeys@tempa##1,##2\ltxkeys@nil##3##4{%
    \ltxkeys@findneedvalue{##1}%
    \let\ltxkeys@tkeya\ltxkeys@tkey
    \ltxkeys@findneedvalue{##2}%
    \cpt@newv@riables{tog}{\ltxkeys@hdr}{##1,##2}[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
}
\robust@def\ltxkeys@biboolkeys@e#1#2#3#4#5#6{%
  \ifltxkeys@pl
    \long\def\ltxkeys@tempa##1##2{%
      \aftercsname\ltxkeys@boolkey@d{\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}}%
    }%
    \long\def\ltxkeys@tempb##1##2{%
      \aftercsname\ltxkeys@boolkey@d{\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
    \long\def\ltxkeys@tempa##1{%
      \aftercsname\ltxkeys@boolkey@d{\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}%
      }%
    }%
    \long\def\ltxkeys@tempb##1{%
      \aftercsname\ltxkeys@boolkey@d{\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{%
  \iftogTF{\ltxkeys@hdr#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>}
\robust@def*\ltxkeys@stylekey{%
  \ltxkeys@svtrue\ltxkeys@swfalse
  \ltxkeys@testst{%
    \cpt@cnta\ifltxkeys@st1\else0\fi\relax
    \ltxkeys@testopt@e\ltxkeys@stylekey@a{style}%
  }%
}
\robust@def*\ltxkeys@stylekey@a#1#2[#3]{%
  \cpt@testpnopt{\ltxkeys@stylekey@b{#1}{#2}{#3}}{}%
}
\robust@def*\ltxkeys@stylekey@b#1#2#3(#4)#5{%
  \ltxkeys@findneedvalue{#2}%
  \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#3}%
  \ifltxkeys@st
    \s@expandarg\ltxkeys@definedefault\ltxkeys@tkey{#3}%
  \fi
  \cptexpandtwoargs\cpt@in
    {\detokenize\expandafter{\unexpanded\expandafter
    {\csname\ltxkeys@hdr\ltxkeys@tkey @value\endcsname}}}
    {\detokenize{#4}}%
  \csn@edef{\ltxkeys@hdr\ltxkeys@tkey @dependants}{\unexpanded{#4}}%
  \cptpassexpanded{%
    \long\csn@def{\ltxkeys@hdr\ltxkeys@tkey}####1{%
      \csn@edef{#1\ltxkeys@tkey}{\noexpand\unexpanded{####1}}%
      \edef\noexpand\parentval{\noexpand\unexpanded{####1}}%
      \ifcpt@in
        \csn@xdef{\ltxkeys@hdr\ltxkeys@tkey @value}%
          {\noexpand\unexpanded{####1}}%
      \fi
      \unexpanded{#5}\relax
      \ltxkeys@setdependants{\number\cpt@cnta}{#1}%
    }%
  }%
}
\robust@def*\ltxkeys@setdependants#1#2{%
  \letcstocsn\ltxkeys@tempa{\ltxkeys@hdr\ltxkeys@tkey @dependants}%
  \ifcsemptyTF\ltxkeys@tempa{}{%
    \cpt@sttrue\cpt@csvnormalize[;]\ltxkeys@tempa
    \if@boolTF{ltxkeys@dec}{}{%
      \cptexpandargonce{\ltxkeys@s@tdependants{#1}{#2}}\ltxkeys@tempa
    }%
  }%
}
\robust@def*\ltxkeys@s@tdependants#1#2#3{%
  \begingroup
  \toks0{}\toks1{}\toks2{}%
  \def\csv@do##1{%
    \ltxkeys@s@td@pendants{##1}%
    \ltxkeys@s@td@p@ndants{#1}%
  }%
  \expandafter\csv@@loop\expandafter[\ltxkeys@keyparser]{#3}%
  \let\ifblankTF\relax
  \cptpassexpanded{%
    \endgroup
    \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:^^J||\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
  \emptifycsset{\key@name,\key@default,\key@macro}%
  \@temptokena{#1}%
  \def\ltxkeys@splita##1/##2/{%
    \ifblankTF{##1##2}{%
      \gobble@to@ltxkeys@nil
    }{%
      \ltxkeys@trimspaces{##1}\key@type
      \def\stripstar####1*\@empty####2\@nil{\edef\key@type{####1}}%
      \expandafter\stripstar\key@type\@empty*\@empty\@nil
      \xifstrcmpFT\key@type{sty}{}{%
        \ltxkeys@err{A dependant key can't have dependants:
          \MsgBrk ||\the\@temptokena||}\@ehc
      }%
      \xifinsetTF\key@type{,ord,cmd,bool,choice,}{}{%
        \ltxkeys@err{Invalid key type '\key@type' in dependant key(s)
          \MsgBrk ||\the\@temptokena||}\@ehc
      }%
      \ifblankTF{##2}{%
        \ltxkeys@err{Empty key name in dependant key(s)\MsgBrk
          ||\the\@temptokena||}\@ehc
      }{%
        \ltxkeys@findneedvalue{##2}%
        \let\key@name\ltxkeys@tkey
      }%
      \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@macro{\unexpanded{##2}}%
  }%
  \ltxkeys@splita#1////\ltxkeys@nil
  \cptpassexpanded{%
    \endgroup
    \cpt@csexit\key@type\cpt@csexit\key@name
    \cpt@csexit\key@default\cpt@csexit\key@macro
  }%
}
\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{%
      \ifnum\numexpr#1=\@ne
        \toks1{%
          \the\toks1\oifblankTF{\the\toks1}{}{;}%
          \key@type/\key@name
          \ifcsnullTF\key@default{}{/\expandcsonce\key@default}%
          \ifcsnullTF\key@macro{}{/\expandcsonce\key@macro}%
        }%
      \else
        \toks2{\the\toks2\oifblankTF{\the\toks2}{}{,}%
          \expandcsonce\key@name}%
      \fi
    }%
  }%
}
% \ltxkeys@choicekey
%   *+[<pref]{<fam>}[<mp>]{<key>}[<bin>]{<alt>}[<dft>]{<f1>}{<f2>}
\robust@def*\ltxkeys@choicekey{%
  \ltxkeys@svtrue\ltxkeys@swfalse
  \ltxkeys@teststpl{%
    \ltxkeys@testopt@a{\cpt@testopt\ltxkeys@choicekey@a{chc\ltxkeys@hdr}}%
  }%
}
\robust@def*\ltxkeys@choicekey@a[#1]#2{%
  \begingroup
  \def\siso@do##1{\catcode`##1\string=12\relax}%
  \siso@@loop{=,.}%
  \cpt@testopt{\expandafter\endgroup\ltxkeys@choicekey@b{#1}{#2}}{}%
}
\robust@def*\ltxkeys@choicekey@b#1#2[#3]#4{%
  \ltxkeys@makechclist{#4}{0}%
  \cpt@ifbrack{%
    \ltxkeys@sttrue\ltxkeys@bracedefault
      {\ltxkeys@choicekey@c{#2}{#1#2}{#3}{#4}}%
  }{%
    \ltxkeys@stfalse\ltxkeys@choicekey@c{#2}{#1#2}{#3}{#4}[]%
  }%
}
\robust@def*\ltxkeys@choicekey@c#1#2#3#4[#5]{%
  \ltxkeys@findneedvalue{#1}%
  \ifltxkeys@st\ltxkeys@definedefault\ltxkeys@tkey{#5}\fi
  \ltxkeys@saveinitialkeyvals{}\ltxkeys@tkey{#5}%
  \cptexpanded{%
    \ifltxkeys@pl\ltxkeys@choicekey@e\else\ltxkeys@choicekey@d\fi
    \cptmakecs{\ltxkeys@hdr\ltxkeys@tkey}%
  }%
  {#2}{#3}{#4}%
}
\robust@def*\ltxkeys@choicekey@d#1#2#3#4#5{%
  \ltxkeys@choicekey@f{#1}{#2}{#3}{#4}{{#5\relax}}%
}
\robust@def*\ltxkeys@choicekey@e#1#2#3#4#5#6{%
  \ltxkeys@choicekey@f{#1}{#2}{#3}{#4}{{#5\relax}{#6\relax}}%
}
\robust@def*\ltxkeys@choicekey@f#1#2#3#4#5{%
  \ifinsetTF{/.code=}{#4}{%
    \def\ltxkeys@tempa{\ltxkeys@executechclist}%
  }{%
    \def\ltxkeys@tempa{\@gobble}%
  }%
  \edef#1{%
    \edef\cptmakecs{#2}{\noexpand\unexpanded{####1}}%
    \cptmakecs{cpt@st\ifltxkeys@st true\else false\fi}%
    \cptmakecs{cpt@pl\ifltxkeys@pl true\else false\fi}%
    \unexpanded{\ltxkeys@cc@b,[#3]}{####1}{\expandcsonce\ltxkeys@chclist}%
    \unexpanded{#5}\expandcsonce\ltxkeys@tempa{\unexpanded{#4}}%
  }%
  \def\ltxkeys@tempa{\def#1####1}%
  \expandafter\ltxkeys@tempa\expandafter{#1}%
}
\robust@def*\ltxkeys@makechclist#1#2{%
  \begingroup
  \def\ltxkeys@chclist{}%
  \def\ltxkeys@tempb##1/.code=##2\ltxkeys@nil{%
    \ltxkeys@trimspaces{##1}\ltxkeys@tempa
    \ifcase#2\relax
      \cptaddtolist*[,]\ltxkeys@chclist\ltxkeys@tempa
    \or
      \cptpassexpanded{\lowercase{%
        \def\noexpand\ltxkeys@tempa{\expandcsonce\ltxkeys@tempa}%
        \def\noexpand\ltxkeys@tval{\expandcsonce\ltxkeys@tval}%
      }}%
      \oifstrcmpFT\ltxkeys@tempa\ltxkeys@tval{}{%
        \edef\ltxkeys@chclist{\unexpanded{##2}}%
        \cptbreakloop
      }%
    \else
      \ltxkeys@err{Invalid number '#2' in \string\ltxkeys@makechclist}\@ehc
    \fi
  }%
  \def\csv@do##1{%
    \ifinsetTF{/.code=}{##1}{%
      \ltxkeys@tempb##1\ltxkeys@nil
    }{%
      \ltxkeys@tempb##1/.code=\ltxkeys@nil
    }%
  }%
  \ifinsetTF{/.code=}{#1}{%
    \expandafter\csv@@parse\expandafter[\ltxkeys@keyparser]{#1}%
  }{%
    \csv@@parse[,]{#1}%
  }%
  \postgroupdef\ltxkeys@chclist\endgroup
}
\robust@def*\ltxkeys@executechclist#1{%
  \begingroup
  \ltxkeys@makechclist{#1}{1}%
  \expandafter\endgroup\ltxkeys@chclist
}
\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@trimspaces{#1}#3%
}
\robust@def*\ltxkeys@getkeynames#1{%
  \def\ltxkeys@keynames{}%
  \def\ltxkeys@do##1{%
    \ltxkeys@getkeyname##1=\ltxkeys@nil\ltxkeys@tkey
    \edef\ltxkeys@keynames{%
      \cptliststack,\ltxkeys@keynames\expandcsonce\ltxkeys@tkey
    }%
  }%
  \ifblankTF{#1}{}{\ltxkeys@csvparse{#1}}%
}
\robust@def*\option@keys{%
  \ltxkeys@inpkgcls\option@keys
  \cpt@testst\ltxkeys@optionk@ys
}
\robust@def*\ltxkeys@optionk@ys{%
  \if@boolTF{cpt@st}{%
    \ltxkeys@testopt@g{optionkeys}{not}%
  }{%
    \ltxkeys@testopt@g{optionkeys}{}%
  }%
}
\robust@def*\notoption@keys{%
  \ltxkeys@inpkgcls\notoption@keys
  \ltxkeys@testopt@g{optionkeys}{not}%
}
\robust@def*\ltxkeys@optionkeys#1#2{%
  \def\ltxkeys@do##1{%
    \ifcsndefTF{\ltxkeys@hdr##1}{%
      \ifcsndefTF{\ltxkeys@hdr#1option@keys}{%
        \xifinsetTF{,\detokenize{##1},}
          {,\cptsxdetok{\@nameuse{\ltxkeys@hdr#1option@keys}},}{}{%
          \csn@edef{\ltxkeys@hdr#1option@keys}{%
            \expandcsnonce{\ltxkeys@hdr#1option@keys},%
            \unexpanded{##1}%
          }%
        }%
      }{%
        \csn@def{\ltxkeys@hdr#1option@keys}{##1}%
      }%
    }{%
      \ltxkeys@err{Key '##1' is undefined in family '\ltxkeys@tfam'
        \MsgBrk Only defined keys can be made '#1option' keys.}\@ehc
    }%
  }%
  \ltxkeys@csvparse{#2}%
}
\robust@def*\makeoption@keys{\cpt@teststopt\ltxkeys@makeoptionkeys{KV}}
\robust@def*\ltxkeys@makeoptionkeys[#1]#2{%
  \let\ifmakeoptst\ifcpt@st
  \ifcsndefTF{#1@#2@initial@keyvals}{%
    \edef\ltxkeys@tempa{\expandcsnonce{#1@#2@initial@keyvals}}%
  }{%
    \ltxkeys@err{No initial key-values for family '#2'}\@ehc
  }%
  \s@expandarg\ltxkeys@getkeynames\ltxkeys@tempa
  \ifcsnullTF\ltxkeys@keynames{}{%
    \cptexpandarg{\usename{\ifmakeoptst not\fi option@keys}[#1]{#2}}{%
      \expandcsonce\ltxkeys@keynames
    }%
  }%
  \undefcs\ifmakeoptst
}
\robust@def*\makenotoption@keys{%
  \cpt@sttrue\cpt@testopt\ltxkeys@makeoptionkeys{KV}%
}
\robust@def*\ltxkeys@testoptionkey#1{%
  \ifcsndefFT{\ltxkeys@hdr#1option@keys}{}{%
    \cpt@choicefdfalse
    \def\ltxkeys@do##1{%
      \s@expandarg\ifstrcmpTF\ltxkeys@tkey{##1}{%
        \cpt@choicefdtrue\ltxkeys@break
      }{}%
    }%
    \aftercsname{\ltxkeys@csvloop*}{\ltxkeys@hdr#1option@keys}%
    \if@boolFT{cpt@choicefd}{}{%
      \ltxkeys@err{The following key should
        \ifnullTF{#1}\@gobblespace{#1} appear in
        \MsgBrk\noexpand\usepackage or \string\RequirePackage:
        ^^J||\ltxkeys@ttpref, \ltxkeys@tfam, \ltxkeys@tkey||%
      }\@ehc
    }%
  }%
}
\robust@def*\ltxkeys@testneedvalkey{%
  \begingroup
  \cpt@choicefdfalse
  \def\ltxkeys@do##1{%
    \s@expandarg\ifstrcmpTF\ltxkeys@tkey{##1}{%
      \cpt@choicefdtrue\ltxkeys@break
    }{}%
  }%
  \aftercsname{\ltxkeys@csvloop*}{\ltxkeys@hdr needvalue@keys}%
  \ifcpt@choicefd
    \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.
    }%
  \fi
  \endgroup
}
\new@def*\ltxkeys@setbool#1{%
  \xifstrcmpTF{#1}{on}{%
    \def#1{true}%
  }{%
    \xifstrcmpTF{#1}{off}{%
      \def#1{false}%
    }{%
      \edef#1{#1}%
    }%
  }%
}
\robust@def*\ltxkeys@accumkeyvals#1{%
  \ltxkeys@ifinTF(1)%
    {\ltxkeys@setmnkey,\setmnkey,\setaliaskey}{#1}%
    \ltxkeys@twktrue\ltxkeys@twkfalse
  \begingroup
  \edef\key@vals{%
    \cptliststack,\key@vals\expandcsonce\key@name=%
    \ifltxkeys@dep
      \expandcsonce\key@default
    \else
      \oifstrcmpTF\key@default{true}{false}{%
        \expandcsonce\key@default
      }%
    \fi
  }%
  \ifltxkeys@ssk
    \gletcs\key@vals\key@vals
  \else
    \ifltxkeys@twk\else
      \gletcs\key@vals\key@vals
    \fi
  \fi
  \endgroup
}
% \ltxkeys@definekeys[pref]<fam>[macropf]{<keyname>=<dft>/<callback>; ...}
\robust@def*\ltxkeys@definekeys{%
  \begingroup
  \endlinechar\m@one
  \cpt@teststopt\ltxkeys@definekeys@a{KV}%
}
\robust@def*\ltxkeys@definekeys@a[#1]{%
  \gletcs\ifdefkeyst\ifcpt@st
  \cpt@testfam{\ltxkeys@definekeys@b#1}%
}
\robust@def*\ltxkeys@definekeys@b#1<#2>{%
  \cpt@testopt
    {\expandafter\endgroup\ltxkeys@definekeys@c{#1}{#2}}{}%
}
\robust@def*\ltxkeys@definekeys@c#1#2[#3]#4{%
  \begingroup
  \ltxkeys@trimspaces{#1}\key@prefix
  \ltxkeys@trimspaces{#2}\key@family
  \ltxkeys@trimspaces{#3}\macro@prefix
  \toks@{\undefcs\ifdefkeyst}%
  \def\key@vals{}%
  \def\ltxkeys@splita##1={%
    \begingroup
    \defpass\reserved@a####1\ltxkeys@nil{\endgroup
      \ltxkeys@splitb##1/####1//\ltxkeys@nil
    }.%
  }%
  \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{%
    \ifblankTF{##1}{%
      \ifblankTF{##2##3}{}{%
        \ltxkeys@err{Empty key name while in
          \string\ltxkeys@definekeys}\@ehc
      }%
    }{%
      \ltxkeys@findneedvalue{##1}%
      \let\key@name\ltxkeys@tkey
      \ifdefkeyst
        \ifcsndefFT{\key@prefix @\key@family @\key@name}{}{%
          \ltxkeys@err{Key '\key@name' already defined in family
            \MsgBrk '#2' with prefix '#1'}\@ehc
        }%
      \fi
      \ifblankTF{##2}{%
        \def\key@default{}%
      }{%
        \s@expandarg\ltxkeys@trimspaces{\@gobble##2}\key@default
      }%
      \ltxkeys@accumkeyvals{##3}%
      \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@prefix]{\key@family}%
          \ifx\macro@prefix\@empty\else[\macro@prefix]\fi
          {\key@name}[\expandcsonce\key@default]{\unexpanded{##3}}%
        }%
      }%
    }%
  }%
  \long\def\csv@do##1{%
    \cpt@checkeq##1\cpt@nil{%
      \ltxkeys@splita##1\ltxkeys@nil
    }{%
      \ltxkeys@splitb##1///\ltxkeys@nil
    }%
  }%
  \expandafter\csv@@parse\expandafter[\ltxkeys@keyparser]{#4}%
  \cptexpandsecond\endgroup{%
    \the\toks@
    \noexpand\ltxkeys@twkfalse
    \ifcsnullTF\key@vals{}{\noexpand\ltxkeys@setkeys
      [\key@prefix]{\key@family}{\expandcsonce\key@vals}%
    }%
  }%
}
\new@def*\ltxkeys@badkeytypes{}
\robust@def*\ltxkeys@keytypeerr#1{%
  \edef\ltxkeys@badkeytypes{\cptliststack,\ltxkeys@badkeytypes#1}%
}
% \ltxkeys@declarekeys[pref]<fam>[macropf]{<keytype>/<keyname>
%   /<dft>/<callback><parser> ...}
\robust@def*\ltxkeys@declarekeys{%
  \begingroup
  \endlinechar\m@one
  \cpt@teststopt\ltxkeys@declarekeys@a{KV}%
}
\robust@def*\ltxkeys@declarekeys@a[#1]{%
  \gletcs\ifdefkeyst\ifcpt@st
  \cpt@testfam{\ltxkeys@declarekeys@b{#1}}%
}
\robust@def*\ltxkeys@declarekeys@b#1<#2>{%
  \cpt@testopt{\expandafter\endgroup\ltxkeys@declarekeys@c{#1}#2}{}%
}
\robust@def*\ltxkeys@declarekeys@c#1#2[#3]#4{%
  \ltxkeys@dectrue
  \begingroup
  \ltxkeys@trimspaces{#1}\key@prefix
  \ltxkeys@trimspaces{#2}\key@family
  \ltxkeys@trimspaces{#3}\macro@prefix
  \def\key@vals{}%
  \toks@{\undefcs\ifdefkeyst}%
  \def\ltxkeys@splita##1/##2/{%
    \ifblankTF{##1##2}{%
      \gobble@to@ltxkeys@nil
    }{%
      \ifblankTF{##2}{%
        \ltxkeys@err{Empty key name in \string\ltxkeys@declarekeys}\@ehc
      }{%
        \ltxkeys@trimspaces{##1}\key@type
        \ltxkeys@findneedvalue{##2}%
        \let\key@name\ltxkeys@tkey
        \ifdefkeyst
          \ifcsndefFT{\key@prefix @\key@family @\key@name}{}{%
            \ltxkeys@err{Key '\key@name' already defined in family
              \MsgBrk '#2' with prefix '#1'}\@ehc
          }%
        \fi
        \oifstrcmpFT\key@type{choice}{}{%
          \s@expandarg\ltxkeys@splitchoice\key@name
        }%
        \ltxkeys@splitb.%
      }%
    }%
  }%
  \def\ltxkeys@splitb##1/##2/##3/##4\ltxkeys@nil{%
    \edef\key@default{\expandcsonce{\@gobble##1}}%
    \ifcsnullTF\key@default{%
      \oifstrcmpFT\key@type{bool}{}{\def\key@default{true}}%
    }{%
      \ltxkeys@trimspacesincs\key@default
    }%
    \oifinsetFT{sty}\key@type{}{\ltxkeys@declarekeys@d{##3}}%
    \ltxkeys@accumkeyvals{##2}%
    \def\ltxkeys@tempa{ord}%
    \edef\ltxkeys@tempa{%
      [\key@prefix]{\key@family}%
      \ifx\key@type\ltxkeys@tempa\else\ifx\macro@prefix\@empty\else
        [\macro@prefix]\fi\fi
      {\key@name}%
    }%
    \cptpassexpanded{%
      \toks@{\the\toks@
        \cptmakecs{ltxkeys@twk\ifltxkeys@twk true\else false\fi}%
        \IfStrEqCase[\ltxkeys@keytypeerr{\expandcsonce\key@type}]%
        {\key@type}{%
          {sty}{%
            \ltxkeys@stylekey\ltxkeys@tempa
            [\expandcsonce\key@default](\expandcsonce\dependant)%
            {\unexpanded{##2}}%
          }%
          {sty*}{%
            \ltxkeys@stylekey*\ltxkeys@tempa
            [\expandcsonce\key@default](\expandcsonce\dependant)%
            {\unexpanded{##2}}%
          }%
          {cmd}{%
            \ltxkeys@cmdkey\ltxkeys@tempa
            [\expandcsonce\key@default]{\unexpanded{##2}}%
          }%
          {bool}{%
            \ltxkeys@boolkey+\ltxkeys@tempa
            [\expandcsonce\key@default]{\unexpanded{##2}}%
            {\ltxkeys@keyvalerr}%
          }%
          {choice}{%
            \ltxkeys@choicekey*+\ltxkeys@tempa
            [\unexpanded{\val\nr}]{\expandcsonce\ltxkeys@alt}%
            [\expandcsonce\key@default]{\unexpanded{##2}}%
            {\ltxkeys@keyvalerr}%
          }%
          {ord}{%
            \ltxkeys@ordkey\ltxkeys@tempa
            [\expandcsonce\key@default]{\unexpanded{##2}}%
          }%
        }%
      }%
    }%
  }%
  \ifdefTF\ltxkeys@keyparser{%
    \stripallouterbracesincs\ltxkeys@keyparser
  }{%
    \def\ltxkeys@keyparser{;}%
  }%
  \def\csv@do##1{%
    \ltxkeys@splita##1/////\ltxkeys@nil
  }%
  \expandafter\csv@@loop\expandafter[\ltxkeys@keyparser]{#4}%
  \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'}\@ehc
  \fi
  \ifcsnullTF\key@vals{}{%
    \cptexpandargonce{\ltxkeys@setkeys[#1]{#2}}\key@vals
  }%
  \ltxkeys@decfalse
}
\robust@def\ltxkeys@declarekeys@d#1{%
  \begingroup
  \ifblankTF{#1}{%
    \def\dependant{}%
  }{%
    \ifinsetFT{>}{#1}{%
      \ltxkeys@err{Missing key type and name in dependant key
        ^^J\detokenize{#1}'}{No '>' in dependant key.}%
      \def\dependant{}%
    }{%
      \def\ltxkeys@tempa##1>##2>##3>##4>##5\ltxkeys@nil{%
        \edef\dependant{\unexpanded{##1/##2/##3/##4}}%
      }%
      \ltxkeys@tempa#1>>>>\ltxkeys@nil
    }%
  }%
  \postgroupdef\dependant\endgroup
}
\robust@def*\ltxkeys@setmnkey#1{%
  \xifinsetTF{,}{\detokenize{#1}}{%
    \ltxkeys@err{\noexpand\ltxkeys@setmnkey doesn't accept key list}\@ehc
  }{%
    \cpt@testopt{\ltxkeys@settmnkey@a#1}{}%
  }%
}
\robust@def*\ltxkeys@settmnkey@a#1[#2]{%
  \cptexpandsecond\ltxkeys@setkeys{%
    [\ltxkeys@ttpref]{\ltxkeys@tfam}{%
      #1=\ifnullTF{#2}{\expandcsonce\ltxkeys@tval}{\unexpanded{#2}}%
    }%
  }%
}
\newletcs\setmnkey\ltxkeys@setmnkey
\newletcs\setaliaskey\ltxkeys@setmnkey
\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'}\@ehc
    }{%
      \cptifmacroTF{##2}{%
        \edef\ltxkeys@alt{\expandcsonce{##2}}%
      }{%
        \edef\ltxkeys@alt{\unexpanded{##2}}%
      }%
      \despacecontent\ltxkeys@alt
    }%
  }%
  \ltxkeys@tempa#1..\ltxkeys@nil
}
\robust@def*\ltxkeys@setinitialkeyvals#1#2{%
  \ifcsndefFT{#1@#2@initial@keyvals}{}{%
    \ifcsnnullTF{#1@#2@initial@keyvals}{}{%
      \cptpassexpanded{%
        \noexpand\ltxkeys@setkeys[#1]{#2}%
        {\expandcsnonce{#1@#2@initial@keyvals}}%
      }%
    }%
  }%
}
% \ltxkeys@initializekeys[<prefix>]{<fams>}[<na>]
\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]{%
  \begingroup
  \def\ltxkeys@resa{}%
  \def\ltxkeys@do##1{%
    \edef\ltxkeys@resa{%
      \cptliststack,\ltxkeys@resa
      \ifcsndefFT{#1@##1@initial@keyvals}{}{%
        \expandcsnonce{#1@##1@initial@keyvals}%
      }%
    }%
  }%
  \ltxkeys@csvparse{#2}%
  \ltxkeys@getkeynames{#3}%
  \cptexpandsecond{\endgroup\ltxkeys@setkeys*+[#1]{#2}}%
    {[\ltxkeys@keynames]{\ltxkeys@resa}}%
}

% \ltxkeys@launchkeys[<prefix>]{<fams>}{<curr>}
\robust@def*\ltxkeys@launchkeys{\cpt@testopt\ltxkeys@l@unchkeys{KV}}
\robust@def*\ltxkeys@l@unchkeys[#1]#2#3{%
  \ltxkeys@in@ti@lizekeys{#1}{#2}[#3]%
  \ifblankTF{#3}{}{\ltxkeys@setkeys[#1]{#2}{#3}}%
}

% \ltxkeys@setkeys*+[<prfs>]{<fams>}[<na>]{<curr>}
\robust@def*\ltxkeys@setkeys{%
  \ltxkeys@rmfalse
  \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setkeys@a}%
}
\robust@def*\ltxkeys@setrmkeys{%
  \ltxkeys@rmtrue
  \ltxkeys@teststpl{\ltxkeys@testopt@c\ltxkeys@setrmkeys@a}%
}
\robust@def*\ltxkeys@setrmkeys@a[#1]{%
  \cptexpandarg{\ltxkeys@setkeys@a[#1]}
    {\expandcsnonce{\ltxkeys@hdr rmkeys}}%
}
\robust@def*\ltxkeys@setkeys@a[#1]#2{%
  \cpt@choicefdfalse
  \def\siso@do##1{%
    \ifstrcmpTF{#2}{##1}\cpt@choicefdtrue\relax
  }%
  \siso@@loop{.,;:+-=*^_/[()]}%
  \ifcpt@choicefd
    \ltxkeys@err{Invalid key list '#2'}\@ehc
  \fi
  \ifnum\ltxkeys@keydepth=\z@pt
    \csn@def{\ltxkeys@hdr rmkeys}{}%
    \def\ltxkeys@undefinedkeys{}%
  \fi
  \edef\ltxkeys@nakeys{\unexpanded{#1}}%
  \ifcsemptyTF\ltxkeys@nakeys{}{%
    \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@nakeys
  }%
  \def\ltxkeys@do##1{%
    \edef\CurrentKeyval{\unexpanded{##1}}%
    \ltxkeys@setkeys@b##1=\ltxkeys@nil
  }%
  \ltxkeys@kvparse{#2}%
  \emptifycsset{\CurrentPref,\CurrentFam,\CurrentKeyval,
    \CurrentKey,\CurrentVal}%
  \ltxkeys@exopfalse\ltxkeys@pxopfalse
  \ifcsnullTF\ltxkeys@undefinedkeys{}\ltxkeys@logunknownkeys
}
\robust@def*\ltxkeys@setkeys@b#1=#2\ltxkeys@nil{%
  \ifinsetTF{\needvalue}{#1}{%
    \ltxkeys@err{\noexpand\needvalue pointer not allowed
      \MsgBrk when setting keys}\@ehc
  }{}%
  \ltxkeys@findpointer\savevalue{#1}\ltxkeys@tkey
    \ltxkeys@svtrue\ltxkeys@svfalse
  \let\CurrentKey\ltxkeys@tkey
  \ifinsetTF{=\ltxkeys@nil}{#2\ltxkeys@nil}{%
    \ltxkeys@novalfalse
    \begingroup
    \defpass\reserved@a##1=##2\ltxkeys@nil{\endgroup
      \edef\ltxkeys@tval{\expandcsonce{\@gobble##1}}%
      \let\CurrentVal\ltxkeys@tval
    }%
    .#2\ltxkeys@nil
  }{%
    \ltxkeys@novaltrue
    \def\ltxkeys@tval{}%
  }%
  \ifcsemptyTF\ltxkeys@tkey{%
    \ifltxkeys@noval\else
      \ltxkeys@err{No key specified for value
        '\expandcsonce\ltxkeys@tval'
        \MsgBrk in families '\ltxkeys@fams'}\@ehc
    \fi
  }{%
    \xifinsetTF{,\ltxkeys@tkey,}{,\ltxkeys@nakeys,}{}{%
      \ltxkeys@setkeys@c
    }%
  }%
}
\robust@def*\ltxkeys@setkeys@c{%
  \ltxkeys@kffalse
  \if@boolTF{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@d
      }%
      \ltxkeys@csvloop*\ltxkeys@fams
    }%
    \ltxkeys@csvloop*\ltxkeys@prefs
  }{%
    \def\ltxkeys@do##1{%
      \if@boolTF{ltxkeys@kf}{%
        \ltxkeys@break
      }{%
        \def\CurrentPref{##1}%
        \ltxkeys@makepf{##1}%
        \def\ltxkeys@do####1{%
          \if@boolTF{ltxkeys@kf}{%
            \ltxkeys@break
          }{%
            \def\ltxkeys@tfam{####1}%
            \let\CurrentFam\ltxkeys@tfam
            \ltxkeys@makehdr\ltxkeys@tfam
            \ltxkeys@setkeys@d
          }%
        }%
        \ltxkeys@csvloop*\ltxkeys@fams
      }%
    }%
    \ltxkeys@csvloop*\ltxkeys@prefs
  }%
  \if@boolTF{ltxkeys@kf}{%
    \if@boolFT{ltxkeys@pxop}{}{%
      \ifx\ltxkeys@testname\cpt@documentclass
        \cpt@removecurroption\CurrentKeyval
      \fi
    }%
  }{%
    \ifcsndefTF{\ltxkeys@hdr default@ds}{%
      \begingroup
      \let\xp\expandcsonce
      \cptexpandsecond{%
        \endgroup\usename{\ltxkeys@hdr default@ds}%
      }{%
        {\xp\ltxkeys@ttpref}{\xp\ltxkeys@tfam}%
        {\xp\ltxkeys@tkey}{\xp\ltxkeys@tval}%
      }%
    }{%
      \if@boolTF{ltxkeys@pxop}{%
        \ifxTF\@currext\@clsextension{}\ltxkeys@unknownoptionerror
      }{%
        \if@boolTF{ltxkeys@st}{%
          \cptexpandargonce{\aftercsname{\cptfiltermergekv[,]}
            {\ltxkeys@hdr rmkeys}}\CurrentKeyval\nofilter
        }{%
          \ltxkeys@getinnoval
          \cptexpandarg{\cptfiltermergecsv[;]\ltxkeys@undefinedkeys}{%
            \ltxkeys@ttpref,\ltxkeys@tfam,\ltxkeys@tkey,\InnocentVal
          }\nofilter
        }%
      }%
    }%
  }%
}
\robust@def*\ltxkeys@setkeys@d{%
  \ifcsndefFT{\ltxkeys@hdr\ltxkeys@tkey}{}{%
    \ltxkeys@kftrue
    \if@boolTF{ltxkeys@pxop}{%
      \ltxkeys@testoptionkey{not}%
    }{%
      \if@boolTF{ltxkeys@exop}{}{\ltxkeys@testoptionkey{}}%
    }%
    \if@boolTF{ltxkeys@sv}{%
      \edef\ltxkeys@tempa{\ltxkeys@tkey{\expandcsonce\ltxkeys@tval}}%
      \ltxkeys@addtopointedkeys{savevalue}\ltxkeys@tempa
    }{}%
    \if@boolTF{ltxkeys@noval}{%
      \ifcsndefTF{\ltxkeys@hdr needvalue@keys}{\ltxkeys@testneedvalkey}{}%
      \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey @default}{%
        \cptsevenxp\ltxkeys@usedefault
          \usename{\ltxkeys@hdr\ltxkeys@tkey @default}\ltxkeys@nil
      }{%
        \ltxkeys@err{No value specified for key '\ltxkeys@tkey'}\@ehc
      }%
    }{%
      \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval
      \if@boolTF{ltxkeys@verbose}{%
        \ltxkeys@getinnovalnopad
        \wlog{Key executed: \ltxkeys@ttpref, \ltxkeys@tfam,
          \ltxkeys@tkey, \InnocentVal; on level '\the\ltxkeys@keydepth'.}%
      }{}%
      \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
    }%
  }%
}
\robust@def*\ltxkeys@usedefault#1#2\ltxkeys@nil{%
  \begingroup
  \csn@def{\ltxkeys@hdr\ltxkeys@tkey}##1{%
    \toks@{\def\ltxkeys@tval{##1}}%
  }%
  \usename{\ltxkeys@hdr\ltxkeys@tkey @default}%
  \expandafter\endgroup\the\toks@
  \s@expandarg\ltxkeys@replacepointers\ltxkeys@tval
  \if@boolTF{ltxkeys@verbose}{%
    \ltxkeys@getinnovalnopad
    \wlog{Key executed: \ltxkeys@ttpref, \ltxkeys@tfam,
      \ltxkeys@tkey, \InnocentVal\@space(default);
      on level '\the\ltxkeys@keydepth'.}%
  }{}%
  \cpt@pushstate\ltxkeys@setkeys\ltxkeys@state\ltxkeys@keydepth
  \cptifmacroTF{#1}{%
    \expandafter#1\expandafter{\ltxkeys@tval}\relax
  }{%
    \ltxkeys@err{Faulty key macro '\detokenize{#1}'}\@ehc
  }%
  \cpt@popstate\ltxkeys@setkeys\ltxkeys@keydepth
}

\robust@def*\ltxkeys@getsavedval#1{%
  \def\reserved@a##1#1##2##3\ltxkeys@nil{%
    \ifblankTF{##3}\@firstoftwo{%
      \def\reserved@a{##2}\@secondoftwo
    }%
  }%
  \cptsevenxp\reserved@a\@nameuse
    {\ltxkeys@hdr savevalue@keys}#1{\ltxkeys@nil}\ltxkeys@nil
}
\robust@def*\ltxkeys@replacepointers#1{%
  \def\ltxkeys@resa{}%
  \@tempswafalse
  \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}%
  \ifxTF\reserved@a\ltxkeys@nnil{%
    \edef\ltxkeys@tval{\unexpanded{#1}}%
    \if@tempswa
      \ifltxkeys@verbose
        \ltxkeys@getinnovalnopad
        \wlog{Value '\InnocentVal' of key '\ltxkeys@tkey'
          inherited from key '\ltxkeys@tempb'.}%
      \fi
    \fi
  }{%
    \ltxkeys@getsavedval{#2}{%
      \ltxkeys@err{No value recorded for key '#2'}\@ehc
      \ltxkeys@r@placepointers
    }{%
      \@tempswatrue
      \def\ltxkeys@tempb{#2}%
      \oifinset@sp@TF,{#2}\ltxkeys@resa{%
        \ltxkeys@err{Dangerous back linking of pointers}{%
          Key pointer replacement terminated due
          \MsgBrk to possible back linking.}%
        \@gobble
      }{%
        \edef\ltxkeys@resa{\cptliststack,\ltxkeys@resa#2}%
        \s@expandarg\ifbracedTF\reserved@a{%
          \s@expandarg\ltxkeys@r@placepointers\reserved@a
        }{%
          \expandafter\ltxkeys@r@placepointers\reserved@a
        }%
      }%
    }%
  }%
}
\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}%
      \@ehc
  }%
  \ifescapedTF{#2}{}{\cpt@notescapederr{#2}}%
  \ltxkeys@getsavedval{#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@getinnoval{\@tempswatrue\ltxkeys@g@tinnoval}
\robust@def*\ltxkeys@getinnovalnopad{\@tempswafalse\ltxkeys@g@tinnoval}
\robust@def*\ltxkeys@g@tinnoval{%
  \ifxTF\ltxkeys@tval\@empty{%
    \def\InnocentVal{???}%
  }{%
    \def\InnocentVal{}%
    \def\ltxkeys@tempa{\\}%
    \def\do##1##2##3##4##5##6##7##8##9\@@{%
      \def\siso@do####1{%
        \edef\InnocentVal{\InnocentVal\ifx\siso@arg\ltxkeys@tempa
          \if@tempswa\@space\fi\else\if\siso@arg\cpt@leftbracechar[\else
          \if\siso@arg\cpt@rightbracechar]\else####1\fi\fi\fi}%
      }%
      \siso@@loop{##1##2##3##4##5##6##7##8}%
    }%
    \expandafter\do\detokenize\expandafter
      {\ltxkeys@tval}\\\\\\\\\\\\\\\\\\\@@

  }%
}
\robust@def*\ltxkeys@keyvalerr{%
  \ltxkeys@getinnovalnopad
  \ltxkeys@err{Erroneous value '\InnocentVal' for key or option
    \MsgBrk'\ltxkeys@tkey'}\@ehc
}
\robust@def*\ltxkeys@unknownkeyhandler{%
  \cpt@testopt\ltxkeys@unkn@wnkeyhandler{KV}%
}
\robust@def*\ltxkeys@unkn@wnkeyhandler[#1]#2#3{%
  \begingroup
  \toks@{}%
  \toks1{##1##2##3##4}%
  \toks2{\ltxkeys@getinnovalnopad#3}%
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \ltxkeys@makehdr{####1}%
      \toks@\expandafter{\the\expandafter\toks@\expandafter
        \csn@def\expandafter{\ltxkeys@hdr default@ds}%
        \the\toks1{\the\toks2}}%
    }%
    \ltxkeys@csvparse{#2}%
  }%
  \ltxkeys@csvparse{#1}%
  \edef\reserved@a{\s@expandarg\@iden{\the\toks@}}%
  \expandafter\endgroup\reserved@a
}

\robust@def*\ltxkeys@logunknownkeys{%
  \ltxkeys@l@gunknownkeys
  \ltxkeys@err{The above keys are undefined and %
    couldn't be set}\@ehc
}
\robust@def*\ltxkeys@l@gunknownkeys{%
  \gletcs\ltxkeys@l@gunknownkeys\relax
  \begingroup
  \cpt@cnta\z@pt
  \edef\ltxkeys@skipa{}%
  \cptwhilenum\cpt@cnta<20\do{%
    \edef\ltxkeys@skipa{\expandcsonce\ltxkeys@skipa\@space}%
    \advance\cpt@cnta\@ne
  }%
  \typeout{^^J\ltxkeys@skipa*** Unknown keys ***^^J}%
  \def\ltxkeys@tempb{\\}%
  \def\align@do##1##2##3##4##5##6##7##8##9\@@{%
    \def\ltxkeys@tempc{##9}%
    \def\siso@do####1{%
      \ifx\siso@arg\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@csvparse{##1,##2,##3,##4}%
    \typeout{\ltxkeys@msg}%
  }%
  \def\csv@do##1{%
    \ltxkeys@splita##1\ltxkeys@nil
  }%
  \csv@@loop*[;]\ltxkeys@tempa
  \typeout{^^J\ltxkeys@skipa*******************^^J}%
  \endgroup
}
\robust@def*\ltxkeys@disablekeys{\ltxkeys@testst\ltxkeys@dis@blekeys}
\robust@def*\ltxkeys@dis@blekeys{%
  \let\ifdisablest\ifltxkeys@st
  \begingroup
  \catcode`\,=12\relax
  \cpt@testopt{\ltxkeys@dis@bl@keys}{KV}%
}
\robust@def*\ltxkeys@dis@bl@keys[#1]#2#3{%
  \endgroup
  \def\ltxkeys@prefs{#1}%
  \def\ltxkeys@fams{#2}%
  \def\ltxkeys@keys{#3}%
  \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@prefs
  \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams
  \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@keys
  \def\ltxkeys@do##1{%
    \ltxkeys@makepf{##1}%
    \def\ltxkeys@do####1{%
      \def\ltxkeys@tfam{####1}%
      \ltxkeys@makehdr{####1}%
      \ltxkeys@dis@bl@k@ys
    }%
    \s@expandarg\ltxkeys@csvloop\ltxkeys@fams
  }%
  \s@expandarg\ltxkeys@csvloop\ltxkeys@prefs
}
\robust@def\ltxkeys@dis@bl@k@ys{%
  \def\ltxkeys@do##1{%
    \ifcsndefFT{\ltxkeys@hdr##1}{%
      \ifltxkeys@verbose
        \ltxkeys@warn{Key '##1' undefined in families '\ltxkeys@tfam':
          \MsgBrk can't be disabled}%
      \fi
    }{%
      \edef\ltxkeys@tempa{%
        \noexpand\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
          \noexpand\documentclass or \string\usepackage.
        }%
      }%
      \cptpassexpanded{%
        \ifdisablest\noexpand\AtBeginDocument{\fi
          \ifcsndefTF{\ltxkeys@hdr##1@default}{%
            \noexpand\ltxkeys@ordkey[\ltxkeys@ttpref]%
            {\ltxkeys@tfam}{##1}[]{\expandcsonce\ltxkeys@tempa}%
          }{%
            \noexpand\ltxkeys@ordkey[\ltxkeys@ttpref]%
            {\ltxkeys@tfam}{##1}{\expandcsonce\ltxkeys@tempa}%
          }%
        \ifdisablest}\fi
      }%
    }%
  }%
  \s@expandarg\ltxkeys@csvloop\ltxkeys@keys
  \undefcs\ifdisablest
}
\robust@def*\ltxkeys@nostarform#1#2{%
  \if\detokenize{#1*.}%
    \ltxkeys@err{No star (*) form of command \string#2}\@ehc
  \fi
}
\robust@def*\ltxkeys@declareoption{%
  \let\ltxkeys@tempa\ltxkeys@ordkey
  \let\@fileswith@pti@ns\@badrequireerror
  \cpt@ifstar\ltxkeys@unknownoptionhandler\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{%
  \ltxkeys@unkn@wnkeyhandler[#1]{#2}{#3}%
}
\robust@def*\ltxkeys@declarecmdoption#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \ltxkeys@d@clareoption{#1}{cmd}%
}
\robust@def*\ltxkeys@declarebooloption#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \ltxkeys@d@clareoption{#1}{bool}%
}
\robust@def*\ltxkeys@declarechoiceoption#1{%
  \let\@fileswith@pti@ns\@badrequireerror
  \ltxkeys@d@clareoption{#1}{choice}%
}
\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
  \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@executeoptions#1{%
  \ltxkeys@nostarform{#1}\ltxkeys@executeoptions
  \ltxkeys@exoptrue\ltxkeys@stfalse\ltxkeys@pltrue
  \ltxkeys@rmfalse
  \ltxkeys@testopt@@b\ltxkeys@setkeys@a#1%
}
\emptify\ltxkeys@processedoptions
\robust@def*\ltxkeys@processoptions{%
  \ltxkeys@pltrue\ltxkeys@rmfalse
  \ltxkeys@testopt@@a\ltxkeys@pr@cessoptions
}
\robust@def*\ltxkeys@pr@cessoptions[#1]{%
  \def\ltxkeys@poxlist{}%
  \ltxkeys@pxoptrue
  \let\@fileswith@pti@ns\@badrequireerror
  \edef\ltxkeys@testname{\@currname.\@currext}%
  \ifxTF\ltxkeys@testname\cpt@documentclass{%
    \let\@unusedoptionlist\cpt@classoptionslist
  }{%
    \if@boolFT{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{}{%
          \ifcsnullTF\@unusedoptionlist{%
            \cptgaddtolist\ltxkeys@processedoptions{##1}%
          }{%
            \cpt@removecurroption{##1}%
          }%
          \cptaddtolist\ltxkeys@poxlist{##1}%
        }%
      }%
      \ifcsnullTF\cpt@classoptionslist{}%
        {\ltxkeys@csvloop*\cpt@classoptionslist}%
    }%
  }%
  \begingroup
  \edef\ltxkeys@tempa{\cpt@optionlist{\@currname.\@currext}}%
  \cptexpanded{\endgroup
    \ifcsnullTF\ltxkeys@tempa{}{%
      \cptaddtolist\noexpand\ltxkeys@poxlist{\expandcsonce\ltxkeys@tempa}%
    }%
  }%
  \ifcsnullTF\ltxkeys@poxlist{}{%
    \cptexpandargonce{\ltxkeys@setkeys@a[#1]}\ltxkeys@poxlist
  }%
  \gundefcs\ltxkeys@poxlist
  \csn@def{\ltxkeys@hdr @rmkeys}{}%
  \ltxkeys@pxopfalse
  \let\@fileswith@pti@ns\@@fileswith@pti@ns
  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
}
\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{%
  \def\ltxkeys@prefs{#2}%
  \def\ltxkeys@fams{#3}%
  \cpt@sttrue\cpt@csvnormalize[,]\ltxkeys@fams
  \ltxkeys@trimspaces{#4}\ltxkeys@tkey
  \cpt@choicefdfalse
  \def\ltxkeys@do##1{%
    \if@boolTF{cpt@choicefd}{%
      \ltxkeys@break
    }{%
      \ltxkeys@makepf{##1}%
      \ltxkeys@ifk@yd@f
    }%
  }%
  \ltxkeys@csvparse*\ltxkeys@prefs
  \ltxkeys@oneoftwo#1\endgroup
}
\robust@def*\ltxkeys@ifk@yd@f{%
  \def\ltxkeys@do##1{%
    \ltxkeys@makehdr{##1}%
    \ifcsndefTF{\ltxkeys@hdr\ltxkeys@tkey}{%
      \cpt@choicefdtrue\ltxkeys@break
    }{}%
  }%
  \ltxkeys@csvloop*\ltxkeys@fams
}
\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{%
  \@tx@warn{Unknown option '\CurrentOption' for package '\@currname'}%
  \typein[\answer]{%
    ^^JUnknown option '\CurrentOption' for package '\@currname'.
    ^^JThe option '\CurrentOption' was not declared in package
    ^^J'\@currname'. Perhaps you misspelled its name.
    ^^JEnter 'x' and <return> to stop or any character and
      <return> to continue.
  }%
  \xifstrcmpTF\answer{x}\ltxkeys@emergencystop\relax
}
\cpt@cleanup\ltxkeys@processedoptions
\cptonlypreamble{%
  \ltxkeys@declareoption,\ltxkeys@declarecmdoption,
  \ltxkeys@declarebooloption,\ltxkeys@declarechoiceoption,
  \ltxkeys@processoptions,\ltxkeys@executeoptions,
  \ltxkeys@unknownoptionhandler,\ltxkeys@unknownkeyhandler
}
\ltxkeys@declareoption*[KV]<ltxkeys>{%
  \ltxkeys@warn{Unknown option '\CurrentKey' with
    value '\InnocentVal' ignored.}%
}
\ltxkeys@declarecmdoption[KV]<ltxkeys>[ltxkeys@]{keyparser}[{;}]{%
  \stripallouterbracesincs\ltxkeys@keyparser
}
\ltxkeys@declarebooloption[KV]<ltxkeys>[ltxkeys@]{verbose}[true]{}
\ltxkeys@executeoptions[KV]<ltxkeys>{keyparser}\relax
\ltxkeys@processoptions*[KV]<ltxkeys>\relax

\endinput
