%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
%                                                                                    %
% This is file 'skeyval.sty', version 0.5.                                           %
%                                                                                    %
% Please see the package documentation for user guide.                               %
%                                                                                    %
% 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) 2010 Ahmed Musa (a.musa@rocketmail.com).                             %
%                                                                                    %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%

\begingroup
\catcode064 11% @
\catcode123 01% {
\catcode125 02% }
\def\SKV@tempa{\endgroup
  \edef\SKV@restorecodes{%
    \catcode035 \the\catcode035% #
    \catcode064 \the\catcode064% @
    \catcode123 \the\catcode123% {
    \catcode125 \the\catcode125% }
    \catcode061 \the\catcode061% =
  }%
}
\SKV@tempa
\catcode035 06% #
\catcode064 11% @
\catcode123 01% {
\catcode125 02% }
\def\SKV@ensurecode#1#2{%
  \edef\SKV@restorecodes{%
    \SKV@restorecodes
    \catcode#1 \the\catcode#1\relax
  }%
  \catcode#1 #2\relax
}
\AtEndOfPackage{\SKV@restorecodes}
\SKV@ensurecode{061}{12}% =
\SKV@ensurecode{044}{12}% ,
\SKV@ensurecode{058}{12}% :
\SKV@ensurecode{059}{12}% ;
\SKV@ensurecode{010}{12}% ^^J
\SKV@ensurecode{126}{13}% ~
\def\SKV@rcsid$#1: #2 #3 #4 #5${#4 v#3}
\ProvidesPackage{skeyval}%
  [\SKV@rcsid $Id: skeyval.sty,v 0.5 2010/02/26 09:00:00 Ahmed Musa $
  Extensions to the xkeyval parser (AM)]
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
\@ifpackageloaded{xkeyval}\relax{\RequirePackage{xkeyval}[2008/08/13]}
\ifnum0=0%
  \ifx\eTeXversion\SKV@undefined 1\else\ifnum\eTeXversion<\tw@ 1\fi\fi
\else
  \@latex@error{eTeX not loaded or old version}{%
    This package requires eTeX version 2 or later.}%
\fi
\@ifdefinable\SKV@ifdefinable\relax
\def\SKV@ifdefinable#1{%
  \edef\reserved@a{\expandafter\@gobble\string#1}%
  \ifdefined#1%
    \ifx#1\relax
      \expandafter\expandafter\expandafter\@firstofone
    \else
      \expandafter\expandafter\expandafter\@notdefinable
    \fi
  \else
    \edef\reserved@b{\expandafter\@carcube\reserved@a xxx\@nil}%
    \ifx\reserved@b\@qend
      \expandafter\expandafter\expandafter\@notdefinable
    \else
      \ifx\reserved@a\@qrelax
        \expandafter\expandafter\expandafter\expandafter
        \expandafter\expandafter\expandafter\@notdefinable
      \else
        \expandafter\expandafter\expandafter\expandafter
        \expandafter\expandafter\expandafter\@firstofone
      \fi
    \fi
  \fi
}
\SKV@ifdefinable\SKV@def{\protected\def\SKV@def{\@star@or@long\SKV@aux@def}}
\SKV@ifdefinable\SKV@aux@def{%
  \def\SKV@aux@def#1{\SKV@ifdefinable#1{\l@ngrel@x\def#1}}}
\SKV@ifdefinable\SKV@gdef{\protected\def\SKV@gdef{\@star@or@long\SKV@aux@gdef}}
\SKV@ifdefinable\SKV@aux@gdef{%
  \def\SKV@aux@gdef#1{\SKV@ifdefinable#1{\global\l@ngrel@x\def#1}}}
\SKV@ifdefinable\SKV@edef{\protected\def\SKV@edef{\@star@or@long\SKV@aux@edef}}
\SKV@ifdefinable\SKV@aux@edef{%
  \def\SKV@aux@edef#1{\SKV@ifdefinable#1{\l@ngrel@x\edef#1}}}
\SKV@ifdefinable\SKV@pdef{\protected\def\SKV@pdef{\@star@or@long\SKV@aux@pdef}}
\SKV@ifdefinable\SKV@aux@pdef{%
  \def\SKV@aux@pdef#1{\SKV@ifdefinable#1{\protected\l@ngrel@x\def#1}}}
\SKV@ifdefinable\SKV@pedef{\protected\def\SKV@pedef{\@star@or@long\SKV@aux@pedef}}
\SKV@ifdefinable\SKV@aux@pedef{%
  \def\SKV@aux@pedef#1{\SKV@ifdefinable#1{\protected\l@ngrel@x\edef#1}}}
\SKV@pdef\SKV@defined@err#1{\def\reserved@a{#1}\@notdefinable}
\SKV@def\SKV@for@ifdefinable#1{%
  \SKV@CommandGenParser{,}%
  \SKV@for@b#1\SKV@tempa{%
    \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil
    \if\expandafter\expandafter\expandafter\SKV@car\expandafter
      \string\SKV@tempa\SKV@nil\@backslashchar
      \SKV@err{Backslash not allowed}\@ehc
    \fi
    \SKV@ifnameundef\SKV@tempa{}{\SKV@defined@err\SKV@tempa}%
  }%
}
\SKV@pdef\SKV@info#1{\PackageInfo{skeyval}{#1\@gobble}}
\SKV@pdef\SKV@warn#1{\PackageWarningNoLine{skeyval}{#1}}
\SKV@pdef\SKV@err#1#2{\PackageError{skeyval}{#1}{#2}}
\SKV@def*\SKV@nil{\noexpand\SKV@nil}
\SKV@def*\SKV@nnil{\SKV@nil}
\SKV@def\SKV@car#1#2\SKV@nil{#1}
\gdef\@notprerr{\SKV@err{You've issued a preamble command here}%
  {Take command to preamble.}}
\SKV@pdef\SKV@afterfi#1\fi{\fi#1}
\SKV@pdef\SKV@afterelsefi#1\else#2\fi{\fi#1}
\SKV@def\SKV@aftercsname#1#2{\expandafter#1\csname#2\endcsname}
\SKV@def\SKV@findescape#1{%
  \begingroup\escapechar92 \expandafter\endgroup
  \if\expandafter\SKV@car\string#1\SKV@nil\@backslashchar
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\SKV@def*\SKV@expandox#1{\unexpanded\expandafter{#1}}
\SKV@def*\SKV@expandnameox#1{\SKV@aftercsname\SKV@expandox{#1}}
\SKV@def*\SKV@expandtx#1{\unexpanded\expandafter\expandafter\expandafter{#1}}
\SKV@def*\SKV@expandnametx#1{\SKV@aftercsname\SKV@expandtx{#1}}
\SKV@def*\SKV@noexpandcs#1{\SKV@aftercsname\noexpand{#1}}
\SKV@pdef\SKV@undef#1{\let#1\SKV@undefined}
\SKV@pdef\SKV@gundef#1{\global\let#1\SKV@undefined}
\SKV@pdef\SKV@nameundef#1{\SKV@aftercsname\let{#1}\SKV@undefined}
\SKV@pdef\SKV@namegundef#1{\global\SKV@aftercsname\let{#1}\SKV@undefined}
\SKV@def\SKV@ifdef#1{%
  \ifdefined#1%
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\SKV@def\SKV@ifundef#1{%
  \ifdefined#1%
    \ifx#1\relax
      \expandafter\expandafter\expandafter\@firstoftwo
    \else
      \expandafter\expandafter\expandafter\@secondoftwo
    \fi
  \else
    \expandafter\@firstoftwo
  \fi
}
\SKV@def*\SKV@ifnamedef#1{%
  \ifcsname#1\endcsname
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
\SKV@def*\SKV@ifnameundef#1{%
  \ifcsname#1\endcsname
    \expandafter\ifx\csname#1\endcsname\relax
      \expandafter\expandafter\expandafter\@firstoftwo
    \else
      \expandafter\expandafter\expandafter\@secondoftwo
    \fi
  \else
    \expandafter\@firstoftwo
  \fi
}
\SKV@def\SKV@remparser#1#2{%
  \def\tok@i{#1}\edef\tok@ii{#1#2}%
  \ifx#2\@empty\else
    \def\SKV@remove#1##1\SKV@nil{\def\tok@ii{##1}}%
    \SKV@r@move\let#2\tok@ii
  \fi
}
\SKV@def*\SKV@r@move{\expandafter\SKV@rem@ve\tok@ii\SKV@nil}
\SKV@def*\SKV@rem@ve{\futurelet\@temptoks\SKV@remo@e}
\SKV@def*\SKV@remo@e#1\SKV@nil{%
  \if\@temptoks\tok@i
    \expandafter\SKV@remove\tok@ii\SKV@nil
    \SKV@r@move
  \fi
}
\SKV@def\SKV@apptomacro@a#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \edef#1{\unexpanded{#2}}%
  }{%
    \edef#1{\SKV@expandox#1\unexpanded{#2}}%
  }%
}
\SKV@def\SKV@apptomacro@b#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \edef#1{\SKV@expandox{#2}}%
  }{%
    \xdef#1{\SKV@expandox#1\SKV@expandox{#2}}%
  }%
}
\SKV@def\SKV@preptomacro@a#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \edef#1{\unexpanded{#2}}%
  }{%
    \edef#1{\unexpanded{#2}\SKV@expandox#1}%
  }%
}
\SKV@def\SKV@preptomacro@b#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \edef#1{\SKV@expandox{#2}}%
  }{%
    \edef#1{\SKV@expandox{#2}\SKV@expandox#1}%
  }%
}
\SKV@def\SKV@gapptomacro@a#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \xdef#1{\unexpanded{#2}}%
  }{%
    \xdef#1{\SKV@expandox#1\unexpanded{#2}}%
  }%
}
\SKV@def\SKV@gapptomacro@b#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \xdef#1{\SKV@expandox{#2}}%
  }{%
    \xdef#1{\SKV@expandox#1\SKV@expandox{#2}}%
  }%
}
\SKV@def\SKV@gpreptomacro@a#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \xdef#1{\unexpanded{#2}}%
  }{%
    \xdef#1{\unexpanded{#2}\SKV@expandox#1}%
  }%
}
\SKV@def\SKV@gpreptomacro@b#1#2{%
  \SKV@findescape{#1}{}{%
    \SKV@err{Bad argument '\string#1'}{Backslash required in '\string#1'.}%
  }%
  \SKV@ifundef{#1}{%
    \xdef#1{\SKV@expandox{#2}}%
  }{%
    \xdef#1{\SKV@expandox{#2}\SKV@expandox#1}%
  }%
}
\SKV@def*\@afterpackageloaded#1{%
  \SKV@ifnamedef{ver@#1.\@pkgextension}{%
    \let\SKV@tempa\@firstofone
  }{%
    \def\SKV@tempa{\SKV@aftercsname\SKV@apptomacro@a{#1.\@pkgextension @afpl}}%
  }%
  \SKV@tempa
}
\SKV@preptomacro@a\@popfilename{%
  \SKV@nameuse{\@currname.\@currext @afpl}%
  \SKV@nameundef{\@currname.\@currext @afpl}%
}
\@onlypreamble\@afterpackageloaded
\SKV@def\ReserveKeyPrefixNames#1{\SKV@apptomacro@a\SKV@rkpnames{,#1}}
\SKV@def\ReserveMacroPrefixNames#1{\SKV@apptomacro@a\SKV@rmpnames{,#1}}
\SKV@def\ReserveFamilyNames#1{\SKV@apptomacro@a\SKV@rfnames{,#1}}
\SKV@def*\SKV@rkpnames{XKV}
\SKV@def*\SKV@rmpnames{XKV}
\SKV@def*\SKV@rfnames{XKV}
\SKV@pdef*\SKV@CommandGenParser#1{%
  \def\parser{#1}%
  \protected\long\def\SKV@for@a##1##2##3{%
    \edef##2{\unexpanded{##1}}%
    \SKV@oifblank{##2}\SKV@fornoop\SKV@forloop
    ##2{##3}##1#1\SKV@nil#1%
  }%
  \long\def\SKV@forloop##1##2##3#1{%
    \edef##1{\unexpanded{##3}}%
    \ifx##1\SKV@nnil
      \expandafter\@gobbletwo
    \else
      ##2\expandafter\SKV@forloop
    \fi
    ##1{##2}%
  }%
  \long\def\SKV@fornoop##1\SKV@nil#1{}%
}
\SKV@pdef\SKV@for@b#1{\expandafter\SKV@for@a\expandafter{#1}}
\SKV@pdef*\SKV@tfor@a#1#2#3{\SKV@ifblank{#2}{}{\@tf@r#1{#2}\do{#3}}}
\SKV@pdef*\SKV@tfor@b#1#2#3{%
  \SKV@expandargs{3}{\SKV@tfor@a#1}{{\SKV@expandox{#2}}}{{#3}}\SKV@nil
}
\SKV@def\SKV@checksanitizec#1#2{%
  \XKV@ch@cksanitize{#1}#2;%
  \ifin@\else\XKV@ch@cksanitize{#1}#2,\fi
  \ifin@\@selective@sanitize[0]{,;}#2\fi
}
\SKV@def*\SKV@CommandKeyParser#1{%
  \long\def\SKV@define@keylist##1{%
    \ifXKV@st
      \long\expandafter\def\expandafter\SKV@tempa\expandafter{##1}%
    \else
      \long\def\SKV@tempa{##1}%
    \fi
    \SKV@expandargs{3}\SKV@checksanitizec{{\SKV@expandox{\SKV@tempa}}}%
      \SKV@tempa\SKV@nil
    \def\SKV@nob{\z@}%
    \expandafter\SKV@readkeylist\SKV@tempa#1\SKV@nil
  }%
  \long\def\SKV@readkeylist##1#1##2\SKV@nil{%
    \SKV@ifblank{##1}\relax
    {%
      \SKV@ifstrequal{##1}{\stopread}{%
        \def\SKV@nob{\@ne}%
        \stopread##2\SKV@nil
      }{%
        \SKV@define@mult@keys##1\SKV@nil
      }%
    }%
    \ifnum\SKV@nob=\z@
      \SKV@ifblank{##2}\relax{\SKV@readkeylist##2\SKV@nil}%
    \fi
  }%
}
\SKV@def\SKV@expandargs#1#2#3#4\SKV@nil{%
  \begingroup
  \protected@edef\SKV@tempa{\endgroup
    \ifcase#1\relax
      \unexpanded{#2}{#3}%
    \or
      \unexpanded{#2#3}{#4}%
    \or
      \unexpanded{#2}{#3}{#4}%
    \or
      \unexpanded{#2}#3\unexpanded{#4}%
    \else
      \SKV@err{Unknown expansion type '#1' for \string\SKV@expandargs}%
        {Use the right expansion identifier (0 - 3)}%
    \fi
  }%
  \SKV@tempa
}
\SKV@pdef\SKV@checkchoice#1#2#3#4{%
  \SKV@expandargs{3}{\XKV@cc*+[\val\nr]}{{#1}{#2}}{{#3}{#4}}\SKV@nil
}
\SKV@pdef*\SKV@inputerr#1#2{%
  \SKV@err{Erroneous value '#1' for key '#2'}{%
    Please use the correct value for key '#2'.}%
}
\SKV@def\SKV@ifblank#1{\SKV@ifbl@nk#1\SKV@nil\SKV@nil\@secondoftwo\@firstoftwo:}
\SKV@def\SKV@ifbl@nk#1#2\SKV@nil#3#4#5:{#4}
\SKV@def\SKV@oifblank#1{\SKV@expandargs{0}\SKV@ifblank{\SKV@expandox{#1}}\SKV@nil}
\SKV@def\SKV@xifblank#1{\SKV@expandargs{0}\SKV@ifblank{#1}\SKV@nil}
\SKV@def\SKV@ifstrequal#1#2{%
  \begingroup
  \edef\SKV@tempa{\detokenize{#1}}%
  \edef\SKV@tempb{\detokenize{#2}}%
  \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@expandargs{1}\KV@@sp@def\SKV@tempb\SKV@tempb\SKV@nil
  \ifx\SKV@tempa\SKV@tempb
    \aftergroup\@firstoftwo
  \else
    \aftergroup\@secondoftwo
  \fi
  \endgroup
}
\SKV@def\SKV@oifstrequal#1#2{%
  \@expandtwoargs\SKV@ifstrequal{\SKV@expandox{#1}}{\SKV@expandox{#2}}%
}
\SKV@def\SKV@xifstrequal#1#2{\@expandtwoargs\SKV@ifstrequal{#1}{#2}}
\SKV@def\SKV@ifstrempty#1{%
  \romannumeral-`\@\csname @\if @\detokenize{#1}@first\else
  second\fi oftwo\endcsname
}
\SKV@def\SKV@oifstrempty#1{%
  \SKV@expandargs{0}\SKV@ifstrempty{\SKV@expandox{#1}}\SKV@nil}
\SKV@def\SKV@xifstrempty#1{\SKV@expandargs{0}\SKV@ifstrempty{#1}\SKV@nil}
\SKV@def*\SKV@keylistparser@err{%
  \SKV@err{Key list parser '\SKV@keyparser' not allowed}%
    {Use semicolon (preferable) or colon as parser.}%
}
\define@boolkey+[KV]{skeyval}[SKV@]{xchoicelist}[true]{}{%
  \SKV@inputerr{#1}{xchoicelist}%
}
\define@boolkey+[KV]{skeyval}[SKV@]{inputonce}[true]{}{%
  \SKV@inputerr{#1}{inputonce}%
}
\define@cmdkey[KV]{skeyval}[SKV@]{genparser}[,]{%
  \@onelevel@sanitize\SKV@genparser
  \SKV@expandargs{1}\KV@@sp@def\SKV@genparser\SKV@genparser\SKV@nil
  \SKV@expandargs{0}\SKV@CommandGenParser\SKV@genparser\SKV@nil
}
\define@cmdkey[KV]{skeyval}[SKV@]{keyparser}[;]{%
  \@onelevel@sanitize\SKV@keyparser
  \SKV@xifblank\SKV@keyparser\SKV@keylistparser@err\relax
  \SKV@expandargs{1}\KV@@sp@def\SKV@keyparser\SKV@keyparser\SKV@nil
  \begingroup
  \edef\SKV@tempa{\detokenize{,}}%
  \ifx\SKV@keyparser\SKV@tempa
    \aftergroup\SKV@keylistparser@err
  \fi
  \endgroup
  \SKV@expandargs{0}\SKV@CommandKeyParser\SKV@keyparser\SKV@nil
}
\SKV@def*\SKV@keyprefix@err{%
  \SKV@err{Key prefix '\SKV@keyprefix' is not allowed}%
    {Use another prefix instead of '\SKV@keyprefix'.}%
}
\define@cmdkey[KV]{skeyval}[SKV@]{keyprefix}[KV]{%
  \SKV@xifblank\SKV@keyprefix\SKV@keyprefix@err\relax
  \SKV@expandargs{1}\KV@@sp@def\SKV@keyprefix\SKV@keyprefix\SKV@nil
  \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rkpnames}}\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \ifx\SKV@keyprefix\SKV@tempa\SKV@afterfi\SKV@keyprefix@err\fi
  }%
}
\SKV@def*\SKV@keyfamily@err{%
  \SKV@err{Key family '\SKV@keyfamily' is not allowed}%
    {Use another family name instead of '\SKV@keyfamily'.}%
}
\define@cmdkey[KV]{skeyval}[SKV@]{keyfamily}[fam]{%
  \SKV@xifblank\SKV@keyfamily\SKV@keyfamily@err\relax
  \SKV@expandargs{1}\KV@@sp@def\SKV@keyfamily\SKV@keyfamily\SKV@nil
  \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rfnames}}\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \ifx\SKV@keyfamily\SKV@tempa\SKV@afterfi\SKV@keyfamily@err\fi
  }%
}
\SKV@def*\SKV@macroprefix@err{%
  \SKV@err{Macro prefix '\SKV@macroprefix' is not allowed}%
    {Use another macro prefix.}%
}
\define@cmdkey[KV]{skeyval}[SKV@]{macroprefix}[mp@]{%
  \SKV@xifblank\SKV@macroprefix\SKV@macroprefix@err\relax
  \SKV@expandargs{1}\KV@@sp@def\SKV@macroprefix\SKV@macroprefix\SKV@nil
  \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rmpnames}}\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \ifx\SKV@macroprefix\SKV@tempa\SKV@afterfi\SKV@macroprefix@err\fi
  }%
}
\DeclareOptionX*{\SKV@warn{Unknown option '\CurrentOption' ignored}}
\ExecuteOptionsX[KV]<skeyval>{genparser,keyparser,keyprefix,
  keyfamily,macroprefix,inputonce}
\ProcessOptionsX*[KV]<skeyval>\relax
\SKV@pdef*\skvoptions#1{\setkeys[KV]{skeyval}{#1}}
\SKV@def*\SKV@despacelist#1#2{%
  \SKV@CommandGenParser{#1}%
  \let\SKV@tempa#2%
  \let#2\@empty
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil
    \SKV@apptomacro@b#2{\expandafter#1\SKV@tempa}%
  }%
  \ifx#2\@empty\else
    \SKV@remparser{#1}#2%
  \fi
}
\SKV@def\SKV@named@f#1#2{%
  \ifcsname#2\endcsname
    \expandafter\ifx\csname#2\endcsname\relax\else
      \def\reserved@a{#2}%
      \expandafter\expandafter\expandafter\@notdefinable
    \fi
  \else
    \expandafter#1\csname#2\expandafter\endcsname
  \fi
}
\SKV@def*\SKV@newnamedef#1{\SKV@named@f\def{#1}}
\SKV@def*\SKV@newnamegdef#1{\SKV@named@f\gdef{#1}}
\SKV@def*\SKV@newnameedef#1{\SKV@named@f\edef{#1}}
\SKV@def*\SKV@newnamexdef#1{\SKV@named@f\xdef{#1}}
\SKV@def*\SKV@namedef#1{\SKV@aftercsname\def{#1}}
\SKV@def*\SKV@namegdef#1{\SKV@aftercsname\gdef{#1}}
\SKV@def*\SKV@nameedef#1{\SKV@aftercsname\edef{#1}}
\SKV@def*\SKV@namexdef#1{\SKV@aftercsname\xdef{#1}}
\SKV@def*\SKV@nameuse#1{%
  \ifcsname#1\endcsname\csname#1\expandafter\endcsname\fi}
\SKV@def\SKV@ifnextchar#1#2#3{%
  \let\SKV@@tempc=#1\def\SKV@@tempa{#2}\def\SKV@@tempb{#3}%
  \futurelet\@temptoks\SKV@ifnextch@r
}
\SKV@def\SKV@ifnextch@r{%
  \ifx\@temptoks\SKV@@tempc\let\SKV@@tempb\SKV@@tempa\fi
  \SKV@@tempb
}
\SKV@def\SKV@testopt#1#2{\SKV@ifnextchar[{#1}{#1[{#2}]}}
\SKV@def\SKV@ifstar#1#2{%
  \SKV@ifnextchar*{\begingroup
    \def\SKV@tempa*{\endgroup #1}\SKV@tempa}{#2}%
}
\SKV@def*\SKV@newlet#1#2{%
  \SKV@ifdef#1{%
    \SKV@err{Command '\string#1' already defined}{%
      I can't let '\string#1' to '\string#2'.}%
  }{%
    \SKV@ifdef#2{%
      \let#1#2%
    }{%
      \SKV@err{Command '\string#2' undefined}{%
        I can't let '\string#1' to '\string#2'.}%
    }%
  }%
}
\SKV@pdef*\SKV@newtoks#1{\SKV@ifdefinable#1{\@nameuse{newtoks}#1}}
\SKV@pdef*\SKV@newcount#1{\SKV@ifdefinable#1{\@nameuse{newcount}#1}}
\SKV@pdef*\SKV@newdimen#1{\SKV@ifdefinable#1{\@nameuse{newdimen}#1}}
\SKV@def*\nameletcs#1#2{%
  \SKV@ifdef{#2}{%
    \SKV@aftercsname\let{#1}#2%
  }{%
    \SKV@err{Command '\string#2' undefined}\@ehc
  }%
}
\SKV@def*\csletname#1#2{%
  \SKV@ifnamedef{#2}{%
    \expandafter\let\expandafter#1\csname#2\endcsname
  }{%
    \SKV@err{Command '\@backslashchar#2' undefined}\@ehc
  }%
}
\SKV@def*\nameletname#1#2{%
  \SKV@ifnamedef{#2}{%
    %\expandafter\let\csname#1\expandafter\endcsname\csname#2\endcsname
    \SKV@aftercsname\let{#1\SKV@aftercsname}{#2}%
  }{%
    \SKV@err{Command '\@backslashchar#2' undefined}\@ehc
  }%
}
\SKV@def*\@nameletcs#1#2{\SKV@aftercsname\let{#1}#2}
\SKV@def*\@csletname#1#2{%
  \begingroup\expandafter\endgroup
  \expandafter\let\expandafter#1\csname#2\endcsname
}
\SKV@def*\@nameletname#1#2{%
  \begingroup\expandafter\endgroup
  \expandafter\let\csname#1\SKV@aftercsname\endcsname{#2}%
}
\SKV@pdef*\SKV@numdef#1#2{%
  \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}%
  \SKV@ifstrempty{#2}{\SKV@err{Empty argument for counter '#1'}\@ehc}{}%
  \SKV@ifundef{#1}{%
    \newcount#1#1=\numexpr#2\relax
  }{%
    #1=\numexpr#2\relax
  }%
}
\SKV@pdef*\SKV@numnamedef#1{\SKV@aftercsname\SKV@numdef{#1}}
\SKV@pdef*\SKV@numgdef#1#2{%
  \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}%
  \SKV@ifstrempty{#2}{\SKV@err{Empty argument for counter '#1'}\@ehc}{}%
  \SKV@ifundef{#1}{%
    \newcount#1\global#1=\numexpr#2\relax
  }{%
    \global#1=\numexpr#2\relax
  }%
}
\SKV@pdef*\SKV@numnamegdef#1{\SKV@aftercsname\SKV@numgdef{#1}}
\SKV@pdef*\SKV@dimdef#1#2{%
  \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}%
  \SKV@ifstrempty{#2}{\SKV@err{Empty argument for dimension '#1'}\@ehc}{}%
  \SKV@ifundef{#1}{%
    \newdimen#1#1=\dimexpr#2\relax
  }{%
    #1=\dimexpr#2\relax
  }%
}
\SKV@pdef*\SKV@dimnamedef#1{\SKV@aftercsname\SKV@dimdef{#1}}
\SKV@pdef*\SKV@dimgdef#1#2{%
  \SKV@findescape{#1}{}{\SKV@err{Backslash required in '#1'}\@ehc}%
  \SKV@ifstrempty{#2}{\SKV@err{Empty argument for dimension '#1'}\@ehc}{}%
  \SKV@ifundef{#1}{%
    \newdimen#1\global#1=\dimexpr#2\relax
  }{%
    \global#1=\dimexpr#2\relax
  }%
}
\SKV@pdef*\SKV@dimnamegdef#1{\SKV@aftercsname\SKV@dimgdef{#1}}
\SKV@pdef*\define@compboolkeys{%
  \let\SKV@def@boolkey\define@boolkey
  \SKV@testopt{\SKV@compbool@opta}{KV}%
}
\SKV@pdef*\newcompboolkeys{%
  \let\SKV@def@boolkey\newboolkey
  \SKV@testopt{\SKV@compbool@opta}{KV}%
}
\SKV@def*\SKV@compbool@opta[#1]#2{%
  \SKV@testopt{\SKV@define@compboolkeys[#1]{#2}}{mp@}}
\SKV@def\SKV@define@compboolkeys[#1]#2[#3]#4[#5]#6#7#8{%
  \SKV@namedef{#1@#2@#4@func}{%
    #7\SKV@nameuse{if#3#4}\SKV@nameuse{#3#6false}\else
      \SKV@nameuse{#3#6true}\fi}%
  \SKV@namedef{#1@#2@#6@func}{%
    #8\SKV@nameuse{if#3#6}\SKV@nameuse{#3#4false}\else
      \SKV@nameuse{#3#4true}\fi}%
  \begingroup\protected@edef\SKV@tempa{\endgroup
    \unexpanded{%
      \SKV@def@boolkey+[#1]{#2}[#3]{#4}[#5]{%
          \SKV@nameuse{#1@#2@#4@func}%
        }{%
          \SKV@inputerr{##1}{#4}%
        }%
      \SKV@def@boolkey+[#1]{#2}[#3]{#6}[#5]{%
          \SKV@nameuse{#1@#2@#6@func}%
        }{%
          \SKV@inputerr{##1}{#6}%
        }%
    }%
  }%
  \SKV@tempa
}
\SKV@def\SKV@star@or@long#1{%
  \SKV@ifstar{%
    \let\l@ngrel@x\relax
    \def\SKV@star@or@none{*}#1%
  }{%
    \let\l@ngrel@x\long
    \def\SKV@star@or@none{}#1%
  }%
}
\SKV@pdef\requirecmd{\SKV@star@or@long\SKV@require@cmd}
\SKV@def\SKV@require@cmd#1{%
  \ifdefined#1%
    \SKV@afterelsefi
    \expandafter\CheckCommand\SKV@star@or@none
  \else
    \SKV@afterfi
    \expandafter\newcommand\SKV@star@or@none
  \fi
  {#1}%
}
\def\@check@eq#1#2{%
  \unless\ifx#1#2%
    \SKV@warn{%
      Previous definition of \string#1\MessageBreak
      doesn't match your new definition.\MessageBreak
      *** I haven't redefined \string#1\space ***
    }%
  \fi
}
\SKV@pdef*\SKV@undeftoggle@err#1{%
  \SKV@err{Toggle '#1' undefined}%
    {You need to first define '#1' before use.}%
}
\SKV@pdef*\deftog#1{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \SKV@warn{Toggle '#1' redefined\on@line}%
  }{}%
  \nameletcs{SKV@toggle@#1}\@secondoftwo
}
\SKV@pdef*\newtog#1{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \SKV@err{Toggle '#1' already defined}%
      {Please provide a new toggle or redefine '#1'.}%
  }{%
    \nameletcs{SKV@toggle@#1}\@secondoftwo
  }%
}
\SKV@pdef*\providetog#1{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \SKV@info{Toggle '#1' already defined.\MessageBreak
      Not redefined\on@line}%
  }{%
    \nameletcs{SKV@toggle@#1}\@secondoftwo
  }%
}
\SKV@pdef*\requiretog#1{%
  \SKV@aftercsname\requirecmd{SKV@toggle@#1}[2]{##2}%
}
\SKV@pdef*\settog#1#2{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \SKV@ifnamedef{SKV@t@ggle#2}{%
      \nameletname{SKV@toggle@#1}{SKV@t@ggle#2}%
    }{%
      \SKV@err{%
        Inadmissible value '#2' for toggle '#1'
      }{%
        Valid values for toggles are 'true' and 'false'.
      }%
    }%
  }{%
    \SKV@undeftoggle@err{#1}%
  }%
}
\SKV@pdef*\togtrue#1{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \nameletcs{SKV@toggle@#1}\SKV@t@ggletrue
  }{%
    \SKV@undeftoggle@err{#1}%
  }%
}
\SKV@pdef*\togfalse#1{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \nameletcs{SKV@toggle@#1}\SKV@t@gglefalse
  }{%
    \SKV@undeftoggle@err{#1}%
  }%
}
\SKV@newlet\SKV@t@ggletrue\@firstoftwo
\SKV@newlet\SKV@t@gglefalse\@secondoftwo
\SKV@pdef*\iftog#1{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \@nameuse{SKV@toggle@#1}%
  }{%
    \SKV@undeftoggle@err{#1}%
  }%
}
\SKV@pdef*\ifnottog#1{%
  \SKV@ifnamedef{SKV@toggle@#1}{%
    \@nameuse{SKV@toggle@#1}\@secondoftwo\@firstoftwo
  }{%
    \SKV@undeftoggle@err{#1}\@gobbletwo
  }%
}
\SKV@pdef*\SKV@definedkey@err#1{%
  \SKV@ifnamedef{\XKV@header#1}{%
    \SKV@err{%
      Key '#1' already defined in family '\XKV@tfam'
    }{%
      Use another key name for '#1'.
    }%
  }{}%
}
\SKV@pdef*\define@togkey{\XKV@t@stopta{\XKV@testoptd\SKV@define@togkey{}}}
\SKV@def*\SKV@define@togkey#1#2[#3]{%
  \SKV@reservedkey@err{#2}%
  \SKV@suspendedkey@err{#2}%
  \ifXKV@pl
    \SKV@afterelsefi
    \expandafter\SKV@d@f@ne@togkey
  \else
    \SKV@afterfi
    \expandafter\SKV@d@fine@togkey
  \fi
  \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}%
}
\SKV@def*\SKV@d@fine@togkey#1#2#3#4#5{%
  \SKV@d@f@ne@t@gkey#1{#2}{#3}{#4}%
  {{\settog{#3}{\XKV@resa}#5}}%
}
\SKV@def*\SKV@d@f@ne@togkey#1#2#3#4#5#6{%
  \SKV@d@f@ne@t@gkey#1{#2}{#3}{#4}%
    {{\settog{#3}{\XKV@resa}#5}{#6}}%
}
\SKV@def*\SKV@d@f@ne@t@gkey#1#2#3#4#5{%
  \deftog{#3}%
  \ifXKV@st\XKV@define@default{#2}{#4}\fi
  \ifXKV@pl
    \def#1##1{\XKV@pltrue\XKV@sttrue
      \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
    }%
  \else
    \def#1##1{\XKV@plfalse\XKV@sttrue
      \XKV@checkchoice[\XKV@resa]{##1}{true,false}#5%
    }%
  \fi
}
\SKV@pdef*\define@togkeys{%
  \XKV@plfalse\XKV@testoptd\SKV@define@togkeys{}}
\SKV@def*\SKV@define@togkeys#1#2[#3]{%
  \XKV@sp@deflist\SKV@tempa{#2}%
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@expandargs{3}\SKV@d@fine@togkeys{{\SKV@tempa}}{{#1}{#3}}\SKV@nil
  }%
}
\SKV@def*\SKV@d@fine@togkeys#1#2#3{%
  \SKV@aftercsname\SKV@d@f@ne@t@gkey{\XKV@header#1}%
    {#1}{#2#1}{#3}{{\settog{#2#1}{\XKV@resa}}}%
}
\SKV@pdef*\newordkey{\XKV@testoptb\SKV@newordkey}
\SKV@def*\SKV@newordkey#1{%
  \SKV@definedkey@err{#1}%
  \SKV@ifnextchar[{\XKV@d@fine@k@y{#1}}%
    {\SKV@namedef{\XKV@header#1}####1}%
}
\SKV@pdef*\newcmdkey{\XKV@testoptd\SKV@newcmdkey{cmd}}
\SKV@def*\SKV@newcmdkey#1#2[#3]#4{%
  \SKV@definedkey@err{#2}%
  \ifXKV@st\XKV@define@default{#2}{#3}\fi
  \edef\SKV@tempa{\noexpand\def\@nameuse{\XKV@header#2}####1}%
  \edef\SKV@tempb{\noexpand\def\@nameuse{#1#2}\unexpanded{{##1}#4}}%
  \expandafter\SKV@tempa\expandafter{\SKV@tempb}%
  \SKV@undef\SKV@tempa\SKV@undef\SKV@tempb
}
\SKV@pdef*\newcmdkeys{\XKV@testoptd\SKV@newcmdkeys{cmd}}
\SKV@def*\SKV@newcmdkeys#1#2[#3]{%
  \XKV@sp@deflist\SKV@tempa{#2}%
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \edef\SKV@tempa{\noexpand\SKV@newcmdkey{#1}{\SKV@tempa}}%
    \SKV@tempa[#3]{}%
  }%
}
\SKV@pdef*\newchoicekey{\XKV@testopta{\XKV@testoptb\SKV@newchoicekey}}
\SKV@def*\SKV@newchoicekey#1{%
  \SKV@definedkey@err{#1}%
  \@testopt{\XKV@d@fine@choicekey{#1}}{}%
}
\SKV@pdef*\newboolkey{\XKV@t@stopta{\XKV@testoptd\SKV@newboolkey{}}}
\SKV@def*\SKV@newboolkey#1#2[#3]{%
  \SKV@definedkey@err{#2}%
  \ifXKV@pl
    \SKV@afterelsefi
    \expandafter\XKV@d@f@ne@boolkey
  \else
    \SKV@afterfi
    \expandafter\XKV@d@fine@boolkey
  \fi
  \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}%
}
\SKV@pdef*\newboolkeys{\XKV@plfalse\XKV@testoptd\SKV@newboolkeys{}}
\SKV@def*\SKV@newboolkeys#1#2[#3]{%
  \XKV@sp@deflist\SKV@tempa{#2}%
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@definedkey@err\SKV@tempa
    \SKV@expandargs{3}\XKV@d@fine@boolkeys{{\SKV@tempa}}{{#1}{#3}}\SKV@nil
  }%
}
\SKV@pdef*\newtogkey{\XKV@t@stopta{\XKV@testoptd\SKV@newtogkey{}}}
\SKV@def*\SKV@newtogkey#1#2[#3]{%
  \SKV@definedkey@err{#2}%
  \ifXKV@pl
    \SKV@afterelsefi
    \expandafter\SKV@d@f@ne@togkey
  \else
    \SKV@afterfi
    \expandafter\SKV@d@fine@togkey
  \fi
  \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}%
}
\SKV@pdef*\newtogkeys{\XKV@plfalse\XKV@testoptd\SKV@newtogkeys{}}
\SKV@def*\SKV@newtogkeys#1#2[#3]{%
  \XKV@sp@deflist\SKV@tempa{#2}%
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@definedkey@err\SKV@tempa
    \SKV@expandargs{3}\SKV@d@fine@togkeys{{\SKV@tempa}}{{#1}{#3}}\SKV@nil
  }%
}
\SKV@pdef*\define@comptogkeys{%
  \let\SKV@def@togkey\define@togkey
  \SKV@testopt{\SKV@comptog@opta}{KV}%
}
\SKV@pdef*\newcomptogkeys{%
  \let\SKV@def@togkey\newtogkey
  \SKV@testopt{\SKV@comptog@opta}{KV}%
}
\SKV@def*\SKV@comptog@opta[#1]#2{%
  \SKV@testopt{\SKV@define@comptogkeys[#1]{#2}}{mp@}}
\SKV@def\SKV@define@comptogkeys[#1]#2[#3]#4[#5]#6#7#8{%
  \SKV@namedef{#1@#2@#4@func}{%
    #7\iftog{#3#4}{\togfalse{#3#6}}{\togtrue{#3#6}}}%
  \SKV@namedef{#1@#2@#6@func}{%
    #8\iftog{#3#6}{\togfalse{#3#4}}{\togtrue{#3#4}}}%
  \begingroup\protected@edef\SKV@tempa{\endgroup
    \unexpanded{%
      \SKV@def@togkey+[#1]{#2}[#3]{#4}[#5]{%
        \SKV@nameuse{#1@#2@#4@func}%
      }{%
        \SKV@inputerr{##1}{#4}%
      }%
      \SKV@def@togkey+[#1]{#2}[#3]{#6}[#5]{%
        \SKV@nameuse{#1@#2@#6@func}%
      }{%
        \SKV@inputerr{##1}{#6}%
      }%
    }%
  }%
  \SKV@tempa
}
\SKV@pdef*\stopread#1\SKV@nil{\long\edef\SKV@remainder{\unexpanded{#1}}}
\def\SKV@noa{\z@}\def\SKV@nob{\z@}\def\SKV@noc{\z@}
\SKV@pdef*\define@keylist{%
  \let\SKV@def@key\define@key
  \let\SKV@def@cmdkey\define@cmdkey
  \let\SKV@def@boolkey\define@boolkey
  \let\SKV@def@togkey\define@togkey
  \let\SKV@def@choicekey\define@choicekey
  \SKV@ifstar{\XKV@sttrue\SKV@define@keylist}%
    {\XKV@stfalse\SKV@define@keylist}%
}
\SKV@pdef*\newkeylist{%
  \let\SKV@def@key\newordkey
  \let\SKV@def@cmdkey\newcmdkey
  \let\SKV@def@boolkey\newboolkey
  \let\SKV@def@togkey\newtogkey
  \let\SKV@def@choicekey\newchoicekey
  \SKV@ifstar{\XKV@sttrue\SKV@define@keylist}%
    {\XKV@stfalse\SKV@define@keylist}%
}
\SKV@def\ChoiceKeyValues#1#2{%
  \ifSKV@xchoicelist
    \SKV@nameedef{\SKV@keyprefix @\SKV@keyfamily @#1@altlist}{#2}%
  \else
    \SKV@ifnameundef{\SKV@keyprefix @\SKV@keyfamily @#1@altlist}{%
      \SKV@newnameedef{\SKV@keyprefix @\SKV@keyfamily @#1@altlist}{#2}%
    }{%
      \SKV@err{%
        You have attempted to set two \MessageBreak
        \string\ChoiceKeyValues\space for the choice\MessageBreak
        key '#1' in the same family '\SKV@keyfamily'
      }{%
        You can only do that if you set 'xchoicelist'=true.
      }%
    }%
  \fi
}
\SKV@newlet\CKVS\ChoiceKeyValues
\SKV@def*\SKV@detok@z@p#1{%
  \edef#1{\expandafter\detokenize\expandafter{#1}\space}%
  \edef#1{\expandafter\zap@space#1\@empty}%
}
\SKV@def*\SKV@detok@zsp#1{%
  \begingroup
  \def\SKV@no{\z@}%
  \SKV@CommandGenParser{,}%
  \SKV@for@b#1\SKV@tempa{%
    \edef\SKV@no{\the\numexpr\SKV@no+\@ne}%
    \edef\SKV@tempa{\expandafter\detokenize\expandafter{\SKV@tempa}\space}%
    \edef\SKV@tempa{\expandafter\zap@space\SKV@tempa\@empty}%
    \SKV@namexdef{SKV@zsp\SKV@no}{\SKV@expandox{\SKV@tempa}}%
  }%
  \endgroup
}
\SKV@def*\SKV@detok@dsp#1{%
  \begingroup
  \def\SKV@no{\z@}%
  \SKV@CommandGenParser{,}%
  \SKV@for@b#1\SKV@tempa{%
    \edef\SKV@no{\the\numexpr\SKV@no+\@ne}%
    \edef\SKV@tempa{\expandafter\detokenize\expandafter{\SKV@tempa}}%
    \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil
    \SKV@namexdef{SKV@dsp\SKV@no}{\SKV@expandox{\SKV@tempa}}%
  }%
  \endgroup
}
\SKV@def*\SKV@if@err{%
  \SKV@err{You can't use '\protect\if' and '\protect\fi' in key macro}%
    {Use '\protect\fif' and '\protect\ffi' instead.}%
}
\SKV@def\SKV@define@mult@keys#1,#2,#3,#4\SKV@nil{%
  \begingroup
  \SKV@ifblank{#4}{}{%
    \def\SKV@tempa{\if,\fi,\fif}%
    \SKV@detok@dsp\SKV@tempa
    \def\SKV@tempb{#4}\SKV@detok@z@p\SKV@tempb
    \@expandtwoargs\in@{\@nameuse{SKV@dsp1}}\SKV@tempb
    \ifin@\SKV@afterfi\SKV@if@err\fi
    \@expandtwoargs\in@{\@nameuse{SKV@dsp3}}\SKV@tempb
    \ifin@
      \SKV@afterelsefi
      \SKV@namegdef{\SKV@keyprefix @\SKV@keyfamily @#2@func}{#4}%
    \else
      \SKV@afterfi
      \SKV@namexdef{\SKV@keyprefix @\SKV@keyfamily @#2@func}{\SKV@expandox{#4}}%
    \fi
  }%
  \protected@edef\SKV@tempa{\endgroup
    \ifcase#1\relax
      \def\SKV@noc{\@ne}%
    \or
      \noexpand\SKV@def@key[\SKV@keyprefix]{\SKV@keyfamily}%
        {#2}[#3]{%
          \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}%
        }%
    \or
      \noexpand\SKV@def@cmdkey[\SKV@keyprefix]{\SKV@keyfamily}%
        [\SKV@macroprefix]{#2}[#3]{%
          \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}%
        }%
    \or
      \noexpand\SKV@def@boolkey+[\SKV@keyprefix]{\SKV@keyfamily}%
        [\SKV@macroprefix]{#2}[#3]{%
          \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}%
        }{%
          \unexpanded{\SKV@inputerr{##1}{#2}}%
        }%
    \or
      \noexpand\SKV@def@togkey+[\SKV@keyprefix]{\SKV@keyfamily}%
        [\SKV@macroprefix]{#2}[#3]{%
          \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}%
        }{%
          \unexpanded{\SKV@inputerr{##1}{#2}}%
        }%
    \or
      \SKV@ifnameundef{\SKV@keyprefix @\SKV@keyfamily @#2@altlist}{%
        \def\SKV@noa{\@ne}%
      }{}%
      \noexpand\SKV@def@choicekey*+[\SKV@keyprefix]{\SKV@keyfamily}{#2}%
        [\unexpanded{\val\nr}]{%
          \SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@altlist}%
        }[#3]{%
          \noexpand\SKV@nameuse{\SKV@keyprefix @\SKV@keyfamily @#2@func}%
        }{%
          \unexpanded{\SKV@inputerr{##1}{#2}}%
        }%
    \else
      \def\SKV@noc{\@ne}%
    \fi
  }%
  \SKV@tempa
  \ifnum\SKV@noa=\@ne
    \SKV@afterfi
      \SKV@err{%
        Choice key '#2' can't be defined.\MessageBreak
        Alternate key values list for '#2' is empty
      }{%
        You need to first define admissible\MessageBreak
        key values through '\string\ChoiceKeyValues'\MessageBreak
        for choice key '#2'.
      }%
  \fi
  \ifnum\SKV@noc=\@ne
    \SKV@afterfi
      \SKV@err{Unknown key type/identifier '#1'}%
        {You can only use key types 1 to 5.}%
  \fi
}
\SKV@pdef*\in@tog#1#2{%
  \def\in@@##1#1##2##3\in@@{%
    \ifx\in@##2\togfalse{in@}\else\togtrue{in@}\fi
  }%
  \in@@#2#1\in@\in@@
}
\newtog{in@}
\SKV@pdef*\in@tok#1#2{%
  \begingroup
  \edef\SKV@tempa{\detokenize{#1}}%
  \edef\SKV@tempb{\detokenize{#2}}%
  \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@expandargs{1}\KV@@sp@def\SKV@tempb\SKV@tempb\SKV@nil
  \SKV@expandargs{3}{\def\in@@##1}\SKV@tempa{%
    ##2##3\in@@{\global\ifx\in@##2\in@false\else\in@true\fi}%
  }\SKV@nil
  \SKV@expandargs{3}\in@@{\SKV@tempb\SKV@tempa}{\in@\in@@}\SKV@nil
  \endgroup
}
\def\XKV@makepf#1{%
  \KV@@sp@def\XKV@prefix{#1}%
  \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rkpnames}}\SKV@tempa\SKV@nil
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \XKV@knftrue
  \XKV@whilist\SKV@tempa\SKV@tempa\ifXKV@knf\fi{%
    \ifx\XKV@prefix\SKV@tempa\XKV@knffalse\fi
  }%
  \unless\ifXKV@knf
    \SKV@afterfi
    \SKV@err{Prefix '\SKV@tempa' is not allowed}%
      {Use another prefix instead of '\SKV@tempa'}%
  \fi
  \edef\SKV@pref{\ifx\XKV@prefix\@empty\else\XKV@prefix\fi}%
  \edef\XKV@prefix{\ifx\XKV@prefix\@empty\else\XKV@prefix @\fi}%
}
\def\XKV@makehd#1{%
  \SKV@expandargs{1}\KV@@sp@def\XKV@header{#1}\SKV@nil
  \SKV@expandargs{3}\XKV@checksanitizeb{{\SKV@rfnames}}\SKV@tempa\SKV@nil
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \XKV@knftrue
  \XKV@whilist\SKV@tempa\SKV@tempa\ifXKV@knf\fi{%
    \ifx\XKV@header\SKV@tempa\XKV@knffalse\fi
  }%
  \unless\ifXKV@knf
    \SKV@afterfi
    \SKV@err{Family '\SKV@tempa' is not allowed}%
      {Use another family instead of '\SKV@tempa'}%
  \fi
  \edef\XKV@header{%
    \XKV@prefix\ifx\XKV@header\@empty\else\XKV@header @\fi}%
}
\def\XKV@define@key#1{%
  \SKV@reservedkey@err{#1}%
  \SKV@suspendedkey@err{#1}%
  \SKV@ifnextchar[{\XKV@d@fine@k@y{#1}}{\SKV@d@fine@k@y{#1}}%
}
\def\XKV@d@fine@k@y#1[#2]#3{%!
  \XKV@define@default{#1}{#2}%
  \SKV@namedef{\XKV@header#1}##1{#3}%
}
\def\SKV@d@fine@k@y#1#2{\SKV@namedef{\XKV@header#1}##1{#2}}
\def\XKV@define@cmdkey#1#2[#3]#4{%
  \SKV@reservedkey@err{#2}%
  \SKV@suspendedkey@err{#2}%
  \ifXKV@st\XKV@define@default{#2}{#3}\fi
  \edef\SKV@tempa{\noexpand\def\@nameuse{\XKV@header#2}####1}%
  \edef\SKV@tempb{\noexpand\def\@nameuse{#1#2}\unexpanded{{##1}#4}}%
  \expandafter\SKV@tempa\expandafter{\SKV@tempb}%
  \SKV@undef\SKV@tempa\SKV@undef\SKV@tempb
}
\def\XKV@define@choicekey#1{%
  \SKV@reservedkey@err{#1}%
  \SKV@suspendedkey@err{#1}%
  \@testopt{\XKV@d@fine@choicekey{#1}}{}%
}
\def\XKV@define@boolkey#1#2[#3]{%
  \SKV@reservedkey@err{#2}%
  \SKV@suspendedkey@err{#2}%
  \ifXKV@pl
    \SKV@afterelsefi\expandafter\XKV@d@f@ne@boolkey
  \else
    \SKV@afterfi\expandafter\XKV@d@fine@boolkey
  \fi
  \csname\XKV@header#2\endcsname{#2}{#1#2}{#3}%
}
\SKV@pdef*\reserve@keys{\@testopt\SKV@reserve@keys{KV}}
\SKV@def*\SKV@reserve@keys[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@res@rve@keys\expandafter{\SKV@tempa}{#2}{#3}%
  }%
}
\SKV@def*\SKV@res@rve@keys#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \SKV@for@b\XKV@fams\XKV@tfam{%
    \XKV@makehd\XKV@tfam
    \SKV@res@rve@k@ys{#3}%
  }%
}
\SKV@def*\SKV@res@rve@k@ys#1{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@ifnamedef{\XKV@header\SKV@tempa}{%
      \SKV@err{%
        Key '\SKV@tempa' with prefix '\SKV@pref' in family
        \MessageBreak '\XKV@tfam' is already defined
      }{%
        Key '\SKV@tempa' in family '\XKV@tfam' can't be reserved.
        \MessageBreak You may wish to remove it before reserving it.
        \MessageBreak In that case, you can use '\string\remove@keys'.
      }%
    }{%
      \SKV@nameedef{\XKV@header\SKV@tempa}{%
        \SKV@err{%
          Key '\SKV@tempa' with prefix '\SKV@pref' in family '\XKV@tfam'
          \MessageBreak was reserved\on@line
        }{%
          Unreserve '\SKV@tempa' before use.
        }%
      }%
      \SKV@namedef{\XKV@header\SKV@tempa @reser}{}%
    }%
  }%
}
\let\SKV@no\@empty
\SKV@pdef\SKV@aftergroup{%
  \SKV@ifstar{\SKV@aft@rgroup\@firstofone}{\SKV@aft@rgroup\unexpanded}%
}
\SKV@def\SKV@aft@rgroup#1#2{%
  \edef\SKV@no{\the\numexpr\SKV@no+1}%
  \SKV@namexdef{SKV@aft@rgr@up\SKV@no}{%
    \SKV@namegundef{SKV@aft@rgr@up\SKV@no}%
    #1{#2}%
  }%
  \SKV@aftercsname\aftergroup{SKV@aft@rgr@up\SKV@no}%
}
\SKV@pdef\SKV@afterassignment{%
  \SKV@ifstar{\SKV@aft@rassignment\@firstofone}%
    {\SKV@aft@rassignment\unexpanded}%
}
\SKV@def\SKV@aft@rassignment#1#2{%
  \begingroup
  \edef\SKV@no{\the\numexpr\SKV@no+1}%
  \SKV@namexdef{SKV@aft@rassignm@nt\SKV@no}{%
    \SKV@namegundef{SKV@aft@rassignm@nt\SKV@no}%
    #1{#2}%
  }%
  \expandafter\endgroup\expandafter\afterassignment
    \csname SKV@aft@rassignm@nt\SKV@no\endcsname
}
\SKV@def*\SKV@reservedkey@err#1{%
  \SKV@ifnamedef{\XKV@header#1@reser}{%
    \let\next\SKV@err
  }{%
    \let\next\@gobbletwo
  }%
  \next{%
    Key '#1' with prefix '\SKV@pref'\MessageBreak
    is reserved in family '\XKV@tfam'
  }{%
    Unreserve '#1' before use.
  }%
}
\SKV@def*\ifkeyreserved{\@testopt\SKV@ifkeyreserved{KV}}
\SKV@def*\SKV@ifkeyreserved[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \XKV@knftrue
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@ifkey@reserved\expandafter{\SKV@tempa}{#2}{#3}%
  }%
  \ifXKV@knf
    \expandafter\@secondoftwo
  \else
    \expandafter\@firstoftwo
  \fi
}
\SKV@def*\SKV@ifkey@reserved#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \KV@@sp@def\XKV@tkey{#3}%
  \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
    \XKV@makehd\XKV@tfam
    \SKV@ifnamedef{\XKV@header\XKV@tkey @reser}{\XKV@knffalse}{}%
  }%
}
\SKV@def*\ifkeysuspended{\@testopt\SKV@ifkeysuspended{KV}}
\SKV@def*\SKV@ifkeysuspended[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \XKV@knftrue
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@ifkey@suspended\expandafter{\SKV@tempa}{#2}{#3}%
  }%
  \ifXKV@knf
    \expandafter\@secondoftwo
  \else
    \expandafter\@firstoftwo
  \fi
}
\SKV@def*\SKV@ifkey@suspended#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \KV@@sp@def\XKV@tkey{#3}%
  \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
    \XKV@makehd\XKV@tfam
    \SKV@ifnamedef{\XKV@header\XKV@tkey @sus}{\XKV@knffalse}{}%
  }%
}
\SKV@def*\ifkeydefined{\@testopt\SKV@ifkeydefined{KV}}
\SKV@def*\SKV@ifkeydefined[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \XKV@knftrue
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@ifk@ydefined\expandafter{\SKV@tempa}{#2}{#3}%
  }%
  \ifXKV@knf
    \expandafter\@secondoftwo
  \else
    \expandafter\@firstoftwo
  \fi
}
\SKV@def*\SKV@ifk@ydefined#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \KV@@sp@def\XKV@tkey{#3}%
  \XKV@whilist\XKV@fams\XKV@tfam\ifXKV@knf\fi{%
    \XKV@makehd\XKV@tfam
    \SKV@ifnamedef{\XKV@header\XKV@tkey}{\XKV@knffalse}{}%
  }%
}
\SKV@def*\SKV@disabledkey@err{%
  \SKV@err{%
    Key '\SKV@disabledkey' with prefix '\SKV@pref' in family
    \MessageBreak '\XKV@tfam' was disabled\on@line
  }{%
    You can't set or reset '\SKV@disabledkey' at this\MessageBreak
    late stage. Perhaps you're required to set it \MessageBreak
    earlier, in the document's preamble.
  }%
}
\protected\def\disable@keys{%
  \SKV@ifstar{\@testopt\XKV@disable@keys{KV}}%
    {\@testopt\SKV@disable@keys{KV}}%
}
\SKV@def*\SKV@disable@keys[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@dis@ble@keys\expandafter{\SKV@tempa}{#2}{#3}%
  }%
}
\SKV@def*\SKV@dis@ble@keys#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \SKV@for@b\XKV@fams\XKV@tfam{%
    \XKV@makehd\XKV@tfam
    \SKV@dis@ble@k@ys{#3}%
  }%
}
\SKV@def*\SKV@dis@ble@k@ys#1{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@ifnameundef{\XKV@header\SKV@tempa}{%
      \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref'
        \MessageBreak is undefined in family '\XKV@tfam':
        \MessageBreak can't be disabled\on@line}%
    }{%
      \SKV@dis@ble@k@y@\SKV@tempa
    }%
  }%
}
\SKV@def*\SKV@dis@ble@k@y@#1{%
  \edef\SKV@disabledkey{#1}%
  \SKV@ifnameundef{\XKV@header#1@default}{%
    \edef#1{\noexpand\XKV@define@key{#1}}%
  }{%
    \edef#1{\noexpand\XKV@define@key{#1}[]}%
  }%
  \SKV@expandargs{0}#1\SKV@disabledkey@err\SKV@nil
  \SKV@info{Key '\SKV@disabledkey' with prefix '\SKV@pref' in family '\XKV@tfam'
    \MessageBreak was disabled\on@line}%
}
\SKV@def*\SKV@suspendedkey@err#1{%
  \SKV@ifnamedef{\XKV@header#1@sus}{%
    \SKV@err{%
      Key '#1' was suspended from family '\XKV@tfam'
    }{%
      You can use \string\restore@key\space to restore '#1'.
    }%
  }{}%
}
\SKV@def*\SKV@suspendedkey@e@r{%
  \SKV@err{%
    Key '\SKV@suspendedkey' in family '\XKV@tfam' was
    \MessageBreak suspended\on@line
  }{%
    You can use \string\restore@key\space to restore '\SKV@suspendedkey'.
  }%
}
\SKV@pdef*\suspend@keys{\@testopt\SKV@suspend@keys{KV}}
\SKV@def*\SKV@suspend@keys[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@s@spend@keys\expandafter{\SKV@tempa}{#2}{#3}%
  }%
}
\SKV@def*\SKV@s@spend@keys#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \SKV@for@b\XKV@fams\XKV@tfam{%
    \XKV@makehd\XKV@tfam
    \SKV@s@sp@nd@keys{#3}%
  }%
}
\SKV@def*\SKV@s@sp@nd@keys#1{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@ifnameundef{\XKV@header\SKV@tempa}{%
      \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref'
        \MessageBreak is undefined in family '\XKV@tfam':
        \MessageBreak can't be suspended\on@line}%
    }{%
      \SKV@s@sp@nd@k@ys\SKV@tempa
    }%
  }%
}
\SKV@def*\SKV@s@sp@nd@k@ys#1{%
  \SKV@ifnamedef{\XKV@header#1@sus}{%
    \SKV@err{%
      Key '#1' with prefix '\SKV@pref' was suspended from family '\XKV@tfam'
    }{%
      You can use \string\restore@key\space to restore '#1'.
    }%
  }{%
    \edef\SKV@suspendedkey{#1}%
    \global\nameletname{\XKV@header#1@sus}{\XKV@header#1}%
    \SKV@nameedef{\XKV@header#1}{\SKV@suspendedkey@e@r}%
    \SKV@info{Key '\SKV@suspendedkey' with prefix '\SKV@pref' in
      \MessageBreak family '\XKV@tfam' was suspended\on@line}%
  }%
}
\SKV@pdef*\restore@keys{\@testopt\SKV@restore@keys{KV}}
\SKV@def*\SKV@restore@keys[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@r@store@keys\expandafter{\SKV@tempa}{#2}{#3}%
  }%
}
\SKV@def*\SKV@r@store@keys#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \SKV@for@b\XKV@fams\XKV@tfam{%
    \XKV@makehd\XKV@tfam
    \SKV@r@st@re@keys{#3}%
  }%
}
\SKV@def*\SKV@r@st@re@keys#1{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@ifnameundef{\XKV@header\SKV@tempa}{%
      \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref'
        \MessageBreak is undefined in family '\XKV@tfam':
        \MessageBreak can't be restored\on@line}%
    }{%
      \SKV@r@st@re@k@ys\SKV@tempa
    }%
  }%
}
\SKV@def*\SKV@r@st@re@k@ys#1{%
  \SKV@ifnameundef{\XKV@header#1@sus}{%
    \SKV@err{Key '#1' wasn't suspended from family
      \MessageBreak '\XKV@tfam': can't be restored\on@line}\@ehc
  }{%
    \edef\SKV@restoredkey{#1}%
    \nameletname{\XKV@header#1}{\XKV@header#1@sus}%
    \SKV@nameundef{\XKV@header#1@sus}%
    \SKV@info{Key '\SKV@restoredkey' with prefix '\SKV@pref' in family
      \MessageBreak '\XKV@tfam' restored\on@line}%
  }%
}
\SKV@pdef*\remove@keys{\@testopt\SKV@remove@keys{KV}}
\SKV@def*\SKV@remove@keys[#1]#2#3{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@CommandGenParser{,}%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \expandafter\SKV@r@move@keys\expandafter{\SKV@tempa}{#2}{#3}%
  }%
}
\SKV@def*\SKV@r@move@keys#1#2#3{%
  \XKV@makepf{#1}%
  \XKV@checksanitizeb{#2}\XKV@fams
  \SKV@expandargs{1}\XKV@sp@deflist\XKV@fams\XKV@fams\SKV@nil
  \SKV@for@b\XKV@fams\XKV@tfam{%
    \XKV@makehd\XKV@tfam
    \SKV@r@m@ve@keys{#3}%
  }%
}
\SKV@def*\SKV@r@m@ve@keys#1{%
  \XKV@checksanitizeb{#1}\SKV@tempa
  \SKV@expandargs{1}\XKV@sp@deflist\SKV@tempa\SKV@tempa\SKV@nil
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@ifnameundef{\XKV@header\SKV@tempa}{%
      \SKV@warn{Key '\SKV@tempa' with prefix '\SKV@pref'
        \MessageBreak is undefined in family '\XKV@tfam':
        \MessageBreak I can't remove or unreserve it\on@line}%
    }{%
      \SKV@r@m@ve@k@ys\SKV@tempa
    }%
  }%
}
\SKV@def*\SKV@r@m@ve@k@ys#1{%
  \begingroup
  \edef\SKV@tempa{\XKV@header#1,\XKV@header#1@default,
    \XKV@header#1@func,%\XKV@header#1@value,
    \XKV@header#1@altlist,\XKV@header#1@reser
  }%
  \SKV@for@b\SKV@tempa\SKV@tempa{%
    \SKV@expandargs{1}\KV@@sp@def\SKV@tempa\SKV@tempa\SKV@nil
    \SKV@namegundef{\SKV@tempa}%
  }%
  \endgroup
  \SKV@info{Key '#1' with prefix '\SKV@pref' in family '\XKV@tfam'
    \MessageBreak was removed\on@line}%
}
\SKV@newlet\unreserve@keys\remove@keys
\def\setkeys{%
  \def\fif##1{%
    \SKV@findescape{##1}{%
      \SKV@err{Bad argument '\string##1'}%
        {Backslash in '\string##1' not allowed.}%
    }{}%
    \csname if##1\endcsname
  }%
  \let\ffi\fi
  \XKV@testopta{\XKV@testoptc\XKV@setkeys}%
}
\def\XKV@setkeys[#1]#2{%
  \XKV@checksanitizea{#2}\XKV@resb
  \SKV@normalizea\XKV@resb
  \let\XKV@naa\@empty
  \XKV@for@o\XKV@resb\XKV@tempa{%
    \expandafter\XKV@g@tkeyname\XKV@tempa=\@nil\XKV@tempa
    \XKV@addtolist@x\XKV@naa\XKV@tempa
  }%
  \ifnum\XKV@depth=\z@\let\XKV@rm\@empty\fi
  \XKV@usepresetkeys{#1}{preseth}%
  \expandafter\XKV@s@tkeys\expandafter{\XKV@resb}{#1}%
  \XKV@usepresetkeys{#1}{presett}%
  \let\CurrentOption\@empty
}
\SKV@def*\SKV@remspaceletter#1#2{%
  \begingroup
  \XKV@toks\expandafter{#2 #1}%
  \def\SKV@tempa##1 #1##2\SKV@nil{%
    \SKV@ifblank{##2}{%
      \XKV@toks{##1}%
    }{%
      \XKV@toks{##1#1##2}%
      \expandafter\SKV@tempa\the\XKV@toks\SKV@nil
    }%
  }%
  \expandafter\SKV@tempa\the\XKV@toks\SKV@nil
  \xdef#2{\the\XKV@toks}%
  \endgroup
}
\SKV@def*\SKV@remletterspace#1#2{%
  \begingroup
  \XKV@toks\expandafter{#2#1 }%
  \def\SKV@tempa##1#1 ##2\SKV@nil{%
    \SKV@ifblank{##2}{%
      \XKV@toks{##1}%
    }{%
      \XKV@toks{##1#1##2}%
      \expandafter\SKV@tempa\the\XKV@toks\SKV@nil
    }%
  }%
  \expandafter\SKV@tempa\the\XKV@toks\SKV@nil
  \xdef#2{\the\XKV@toks}%
  \endgroup
}
\SKV@def*\SKV@remletterletter#1#2{%
  \begingroup
  \XKV@toks\expandafter{#2#1#1}%
  \def\SKV@tempa##1#1#1##2\SKV@nil{%
    \XKV@toks{##1#1##2}%
    \SKV@ifblank{##2}{}{\expandafter\SKV@tempa\the\XKV@toks\SKV@nil}%
  }%
  \expandafter\SKV@tempa\the\XKV@toks\SKV@nil
  \def\SKV@tempa##1#1#1\SKV@nil{\gdef#2{##1}}%
  \expandafter\SKV@tempa\the\XKV@toks#1\SKV@nil
  \endgroup
}
\def\SKV@remcommaequal#1#2{%
  \begingroup
  \XKV@toks\expandafter{#2#1}%
  \def\SKV@tempa##1#1##2\SKV@nil{%
    \SKV@ifblank{##2}{%
      \XKV@toks{##1}%
    }{%
      \XKV@toks{##1=##2}%
      \expandafter\SKV@tempa\the\XKV@toks\SKV@nil
    }%
  }%
  \expandafter\SKV@tempa\the\XKV@toks\SKV@nil
  \xdef#2{\the\XKV@toks}%
  \endgroup
}
\SKV@def*\SKV@normalizea#1{%
  \@expandtwoargs\in@{ ,}{\SKV@expandox{#1}}%
  \ifin@\SKV@remspaceletter{,}#1\fi
  \@expandtwoargs\in@{, }{\SKV@expandox{#1}}%
  \ifin@\SKV@remletterspace{,}#1\fi
  \@expandtwoargs\in@{,,}{\SKV@expandox{#1}}%
  \ifin@\SKV@remletterletter{,}#1\fi
  \@expandtwoargs\in@{ =}{\SKV@expandox{#1}}%
  \ifin@\SKV@remspaceletter{=}#1\fi
  \@expandtwoargs\in@{= }{\SKV@expandox{#1}}%
  \ifin@\SKV@remletterspace{=}#1\fi
  \@expandtwoargs\in@{==}{\SKV@expandox{#1}}%
  \ifin@\SKV@remletterletter{=}#1\fi
  \@expandtwoargs\in@{,=}{\SKV@expandox{#1}}%
  \ifin@\SKV@remcommaequal{,=}#1\fi
  \@expandtwoargs\in@{=,}{\SKV@expandox{#1}}%
  \ifin@\SKV@remcommaequal{=,}#1\fi
}
\SKV@pdef\AtStartOfDocument{\AtBeginDocument}
\SKV@pdef\BeforeStartOfDocument{\SKV@gapptomacro@a\SKV@beforestartdocument}
\SKV@def*\SKV@beforestartdocument{}
\SKV@preptomacro@a\document{%
  \endgroup
  \let\BeforeStartOfDocument\@firstofone
  \SKV@beforestartdocument
  \protected\long\def\BeforeStartOfDocument{\expandafter\@notprerr\@gobble}%
  \SKV@undef\SKV@beforestartdocument
  \begingroup
}
\SKV@pdef\AfterStartOfDocument{\SKV@gapptomacro@a\SKV@afterstartdocument}
\SKV@def*\SKV@afterstartdocument{}
\SKV@apptomacro@a\document{%
  \let\AfterStartOfDocument\@firstofone
  \SKV@afterstartdocument
  \protected\long\def\AfterStartOfDocument{\expandafter\@notprerr\@gobble}%
  \SKV@undef\SKV@afterstartdocument\ignorespaces
}
\SKV@def*\SKV@gobblescape{%
  \ifnum\escapechar>255\else
  \ifnum\escapechar<0\else
    \expandafter\expandafter\csname @gobble\ifnum\escapechar=32 space\fi
    \expandafter\expandafter\expandafter\endcsname
  \fi\fi
  \string
}
\SKV@def*\SKV@save#1{%
  \SKV@findescape{#1}{}{\SKV@err{'#1' not a control sequence}\@ehc}
  \SKV@ifnamedef{Saved\SKV@gobblescape#1}{%
    \SKV@err{%
      \string#1\space already saved. You've to restore\MessageBreak
      it or undefine \SKV@noexpandcs{Saved\SKV@gobblescape#1}%
      before\MessageBreak you can save \string#1\space again
    }\@ehc
  }{%
    \nameletcs{Saved\SKV@gobblescape#1}{#1}%
  }%
}
\SKV@def*\SKV@restore#1{%
  \SKV@findescape{#1}{}{\SKV@err{'#1' not a control sequence}\@ehc}
  \SKV@ifnamedef{Saved\SKV@gobblescape#1}{%
    \csletname{#1}{Saved\SKV@gobblescape#1}%
    \SKV@nameundef{Saved\SKV@gobblescape#1}%
  }{%
    \SKV@warn{%
      \@nameuse{Saved\SKV@gobblescape#1} undefined: can't be restored\on@line.
      \MessageBreak Note that each call of \string\SKV@restore\space undefines
      \MessageBreak the saved command
    }%
  }%
}
\providecommand*\input@path{}
\SKV@pdef*\InputFileOnce{%
  \edef\SKV@no{\z@}\SKV@save\input@path
  \SKV@testopt\SKV@InputFileOnce{.}%
}
\SKV@def*\SKV@InputFileOnce[#1]#2{%
  \SKV@gapptomacro@a\input@path{{#1/}}%
  \if X\SKV@nameuse{#2@read}\relax
    \ifSKV@inputonce
      \SKV@afterelsefi
      \SKV@err{! File '#2' already read}{File '#2' can't be read again.}%
    \fi
  \else
    \SKV@namegdef{#2@read}{X}%
    \InputIfFileExists{#2}{}{%
      \typein[\Answer]{^^J! File '\string#2' does not exist.^^J
      Enter filename or 'n' and <return> to continue.}%
      \if n\Answer\relax\else
        \SKV@expandargs{0}{\SKV@InputFileOnce[#1]}\Answer\SKV@nil
      \fi
    }%
  \fi
  \ifnum\SKV@no=\z@\SKV@restore\input@path\fi
  \edef\SKV@no{\@ne}%
}

\endinput

%%% End of file skeyval.sty %%%