% \iffalse meta-comment
%
% Copyright (C) 1993-2025
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
% This file is part of the LaTeX base system.
% -------------------------------------------
%
% It may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%    https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008 or later.
%
% This file has the LPPL maintenance status "maintained".
%
% The list of all files belonging to the LaTeX base distribution is
% given in the file `manifest.txt'. See also `legal.txt' for additional
% information.
%
% The list of derived (unpacked) files belonging to the distribution
% and covered by LPPL is defined by the unpacking scripts (with
% extension .ins) which are part of the distribution.
%
% \fi
%
% \iffalse
%%% From File: ltfinal.dtx
%
%<*driver>
% \fi
\ProvidesFile{ltfinal.dtx}
             [2025/07/01 v2.3g LaTeX Kernel (Final Settings)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltfinal.dtx}
\title{\filename}
\date{\filedate}
\author{%
  Johannes Braams\and
  David Carlisle\and
  Alan Jeffrey\and
  Leslie Lamport\and
  Frank Mittelbach\and
  Chris Rowley\and
  Rainer Sch\"opf}
\begin{document}
 \MaintainedByLaTeXTeam{latex}
 \maketitle
 \DocInput{ltfinal.dtx}
\end{document}
%</driver>
% \fi
%
%
% \section{Final settings}
%
%    This section contains the final settings for \LaTeX.  It initializes
%    some debugging and typesetting parameters, sets the default
%    |\catcode|s and uc/lc codes, and inputs the hyphenation file.
%
%
%
% \MaybeStop{}
%
% \changes{v0.1a}{1994/03/07}{Initial version, split from latex.dtx}
% \changes{v0.1a}{1994/03/07}{Remove oldcomments environment}
% \changes{v0.1c}{1994/04/21}{Added comments, set the catcodes of
%    128--255.}
% \changes{v0.1d}{1994/04/23}{Check that \cs{font@submax} is still zero}
% \changes{v0.1e}{1994/05/02}{Set all the catcodes}
% \changes{v0.1f}{1994/05/03}{Set the catcode of control-J to be
%    `other', for use in messages.}
% \changes{v0.1g}{1994/05/05}{Added empty errhelp.}
% \changes{v0.1h}{1994/05/13}{Added package ot1enc, and defined
%    \cs{@acci}, \cs{@accii} and \cs{@acciii}.}
% \changes{v0.1j}{1994/05/18}{Corrected the lccode for d-bar.}
% \changes{v0.1k}{1994/05/19}{Removed \cs{makeat...}}
% \changes{v1.0n}{1994/05/31}{Renamed lthyphen.* to lthyphen.*.}
% \changes{v1.0o}{1994/11/17}
%         {\cs{@tempa} to \cs{reserved@a}}
% \changes{v1.0p}{1994/12/01}
%         {Renamed lthyphen.* to hyphen.*.}
% \changes{v1.0r}{1995/06/05}
%         {Added \cs{MakeUppercase} and \cs{MakeLowercase}.}
% \changes{v1.0s}{1995/06/06}
%         {Made \cs{MakeUppercase} and \cs{MakeLowercase} brace their
%         argument.}
% \changes{v2.0r}{2016/10/15}{Require e\TeX{}}
% \changes{v2.0s}{2016/10/15}{Tidy up status of char 127}
% \changes{v2.2i}{2020/08/21}{Integration of new hook management interface}
%
%
%
%
% \subsection{Debugging}
%
% By default, \LaTeX{} shows statistics:
%    \begin{macrocode}
%<*2ekernel>
\tracingstats1
%    \end{macrocode}
%
% \subsection{Typesetting parameters}
%
% \begin{macro}{\@lowpenalty}
% \begin{macro}{\@medpenalty}
% \begin{macro}{\@highpenalty}
%    These are penalties used internally.
%    \begin{macrocode}
\newcount\@lowpenalty
\newcount\@medpenalty
\newcount\@highpenalty
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%\begin{macro}{\newmarks}
% \changes{v2.0a}{2014/12/30}{macro added}
% \changes{v2.0b}{2015/01/23}{use reserved count 256}
% \changes{v2.0g}{2015/06/19}{Use $-1$ for first range to get contiguous allocation}
% Allocate extended marks types if etex is active.
% Placed here at the end of the format
% to increase compatibility with count allocations
% in earlier releases.
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>                 {\newmarks}{Extended Allocation}%
%    \end{macrocode}
%
%    \begin{macrocode}
\ifx\marks\@undefined\else
\def\newmarks{%
  \e@alloc\marks \e@alloc@chardef{\count256}\m@ne\e@alloc@top}
\fi
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\newmarks}{Extended Allocation}%
%<latexrelease>\let\newmarks\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%
%    
%    Allocate 3 mark classes to be used in \cs{markboth} and
%    \cs{markright}. Should be done earlier but for that definition of
%    \cs{newmarks} needs moving (which it should I guess).
% \changes{v2.2s}{2022/04/03}{Integration of new mark management interface}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2022/06/01}%
%<latexrelease>                 {2e-left}{Delayed legacy marks}%
\NewMarkClass {2e-left}     
\NewMarkClass {2e-right}     
\NewMarkClass {2e-right-nonempty}
%    \end{macrocode}
%    No rollback really, the marks will remain.
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {2e-left}{Delayed legacy marks}%
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}


%
%\begin{macro}{\newXeTeXintercharclass}
% \changes{v2.0a}{2014/12/30}{macro added}
% \changes{v2.0b}{2015/01/23}{use reserved count 257}
% \changes{v2.0f}{2015/04/28}{define \cs{xe@alloc@intercharclass} for compatibility with older xelatex initialization}
%\begin{macro}{\xe@alloc@intercharclass}
%\begin{macro}{\e@alloc@intercharclass@top}
% \changes{v2.0j}{2016/01/04}{Start allocation at one not three}
% \changes{v2.0k}{2016/01/05}{Remove duplicated code}
% Allocate |\XeTeXintercharclass|  types if xetex is active.
% previously defined in |xetex.ini|.
%
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>              {\newXeTeXintercharclass}{Extended Allocation}%
%    \end{macrocode}
%
% Classes allocated 1 to 4094 (or 254 on older xetex)
% (In earlier XeLaTeX versions 1, 2 and 3 were pre-set for CJK).
% \changes{v2.0g}{2015/06/19}{Use $-1$ for first range to get contiguous allocation}
% \changes{v2.0q}{2016/04/22}{XeTeX 0.99996 has 4096 char classes not 256}
%    \begin{macrocode}
\ifx\XeTeXcharclass\@undefined
\else
%    \end{macrocode}
%    \begin{macrocode}
\ifdim\the\XeTeXversion\XeTeXrevision\p@>0.99993\p@
  \chardef\e@alloc@intercharclass@top=4095
\else
  \chardef\e@alloc@intercharclass@top=255
\fi
%    \end{macrocode}
%    \begin{macrocode}
\def\newXeTeXintercharclass{%
 \e@alloc\XeTeXcharclass
   \chardef\xe@alloc@intercharclass\m@ne\e@alloc@intercharclass@top}
\fi
%    \end{macrocode}
%
%    \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>              {\newXeTeXintercharclass}{Extended Allocation}%
%<latexrelease> \ifx\XeTeXcharclass\@undefined
%<latexrelease> \else
%<latexrelease>    \def\xe@alloc@#1#2#3#4#5{\global\advance#1\@ne
%<latexrelease>     \xe@ch@ck#1#4#2%
%<latexrelease>     \allocationnumber#1%
%<latexrelease>     \global#3#5\allocationnumber
%<latexrelease>     \wlog{\string#5=\string#2\the\allocationnumber}}
%<latexrelease>    \def\xe@ch@ck#1#2#3{%
%<latexrelease>     \ifnum#1<#2\else
%<latexrelease>      \errmessage{No room for a new #3}%
%<latexrelease>     \fi}
%<latexrelease>    \def\newXeTeXintercharclass{%
%<latexrelease>     \xe@alloc@\xe@alloc@intercharclass
%<latexrelease>                    \XeTeXcharclass\chardef\@cclv}
%<latexrelease> \fi
%<latexrelease>\EndIncludeInRelease
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2016/02/01}%
%<latexrelease>  {\xe@alloc@intercharclass}{Start of XeTeX class allocator}%
\ifx\XeTeXcharclass\@undefined
\else
  \countdef\xe@alloc@intercharclass=257
  \xe@alloc@intercharclass=\z@
\fi
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2015/01/01}%
%<latexrelease>  {\xe@alloc@intercharclass}{Start of XeTeX class allocator}%
%<latexrelease> \ifx\XeTeXcharclass\@undefined
%<latexrelease> \else
%<latexrelease>   \xe@alloc@intercharclass=\thr@@
%<latexrelease> \fi
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>  {\xe@alloc@intercharclass}{Start of XeTeX class allocator}%
%<latexrelease> \ifx\XeTeXcharclass\@undefined
%<latexrelease> \else
%<latexrelease>   \newcount\xe@alloc@intercharclass
%<latexrelease>   \xe@alloc@intercharclass=\thr@@
%<latexrelease> \fi
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{trace_stack_levels}
%   Now define the Lua function to emulate \cs{tracingstacklevels} and
%   install it in the |input_level_string| callback.
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%    \end{macrocode}
%   In \texttt{latexrelease} mode we always remove the function from
%   the callback, then add the correct version later.
%    \begin{macrocode}
%<latexrelease>\ifx\directlua\@undefined
%<latexrelease>\else
%<latexrelease>  \directlua{%
%<latexrelease>    if luatexbase.callbacktypes['input_level_string'] and %
%<latexrelease>       luatexbase.in_callback('input_level_string','tracingstacklevels') then
%<latexrelease>        luatexbase.remove_from_callback('input_level_string','tracingstacklevels')
%<latexrelease>    end}%
%<latexrelease>\fi
%<latexrelease>\IncludeInRelease{2021/06/01}{trace_stack_levels}%
%<latexrelease>                 {Lua trace_stack_levels function}%
\ifx\directlua\@undefined
\else
%<*2ekernel>
  \expanded{%
    \everyjob{\the\everyjob
    \noexpand%\directlua
%</2ekernel>
    \directlua{%
      local function trace_stack_levels (input_ptr)
        local tracingstacklevels = tex.count.tracingstacklevels
        if tex.tracingmacros > 0 or input_ptr < tracingstacklevels then
          if tracingstacklevels > 0 then
            if input_ptr < tracingstacklevels then
              return "\string\n\string~" .. string.rep(".",input_ptr)
            else
              return "\string~\string~"
            end
          else
            return "\string\n"
          end
        else
          return ""
        end
      end
%<latexrelease>    if luatexbase.callbacktypes['input_level_string'] then
      luatexbase.add_to_callback('input_level_string',
        trace_stack_levels,'tracingstacklevels')
%<latexrelease>    end
    }%
%<*2ekernel>
  }}%
%</2ekernel>
\fi
%<latexrelease>\EndIncludeInRelease
%<latexrelease>
%    \end{macrocode}
%   Then for the full rollback, just do nothing, since the function
%   was already taken out of the rollback above.
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}{trace_stack_levels}%
%<latexrelease>                 {Lua trace_stack_levels function}%
%<latexrelease>% Nothing here
%<latexrelease>\EndIncludeInRelease
%</2ekernel|latexrelease>
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
% The default values of the picture and |\fbox| parameters:
%    \begin{macrocode}
\unitlength = 1pt
\fboxsep = 3pt
\fboxrule = .4pt
%    \end{macrocode}
% The saved value of \TeX's |\maxdepth|:
%    \begin{macrocode}
\@maxdepth       = \maxdepth
%    \end{macrocode}
% |\vsize| initialized because a |\clearpage| with |\vsize < \topskip|
%  causes trouble.
% |\@colroom| and |\@colht| also initialized because |\vsize| may be
%  set to them if a |\clearpage| is done before the |\begin{document}|
%
%    \begin{macrocode}
\vsize = 1000pt
\@colroom = \vsize
\@colht = \vsize
%    \end{macrocode}
% Initialise |\textheight| |\textwidth| and page style, to avoid
% internal errors if they are not set by the class.
% \changes{v0.1b}{1994/04/18}
%         {Initialise \cs{textheight}, \cs{textwidth} and page style}
%    \begin{macrocode}
\textheight=.5\maxdimen
\textwidth=\textheight
\ps@empty
%    \end{macrocode}
%
% \subsection{Lccodes for hyphenation}
%
% \changes{v2.0a}{2015/01/03}{Unicode data loading added}
% \changes{v2.0c}{2015/01/24}{Skip T1-code entirely with Unicode engines}
% \changes{v2.0d}{2015/03/26}{Use renamed
%   \texttt{unicode-letters.def}}
% \changes{v2.0i}{2015/12/10}{Use new common Unicode data loaders}
% \changes{v2.0j}{2016/01/04}{Do not set up inter character classes for
%   XeTeX}
%  \changes{v2.0l}{2016/01/05}{Correct \textsf{latexrelease} guards}
%  \changes{v2.0l}{2016/01/05}{Ensure old definitions for inter-character
%    class toks are available using \textsf{latexrelease}}
%  \changes{v2.0m}{2016/01/05}{Undefine XeTeX classes when using patching
%    an older kernel}
%  \changes{v2.0l}{2016/01/05}{Missing brace}
%  \changes{v2.0p}{2016/01/05}{Only apply XeTeX change if XeTeX is in use}
%  For $7$- and $8$-bit engines the assumption of T1 encodings is the
%  basis for the hyphenation patterns. That's not the case for the Unicode
%  engines, where the assumption is engine-native working. The common
%  loader system provides access to data from the Unicode Consortium
%  covering not only |\lccode| but also other related data. The
%  |\lccode| part of that at least needs to be loaded before hyphenation is
%  tackled: Xe\TeX{} follows the standard \TeX{} route of building patterns
%  into the format. Lua\TeX{} doesn't require this data be loaded \emph{here}
%  but it does need to be loaded somewhere. Rather than test for the Unicode
%  engines by name, the approach here is to look for the extended math mode
%  handling both provide: any other engine developed in this area will
%  presumably also provide |\Umathcode|.
%    \begin{macrocode}
\ifnum 0%
  \ifx\Umathcode\@undefined\else 1\fi
  \ifx\XeTeXmathcode\@undefined\else 1\fi
  >\z@
  \message{ Unicode character data,}
  \input{load-unicode-data}
%</2ekernel>
%<latexrelease>\IncludeInRelease{2016/02/01}%
%<latexrelease>  {\XeTeXintercharclasses}{XeTeX character classes}%
%<latexrelease>  \ifx\XeTeXinterchartoks\undefined
%<latexrelease>  \else
%<latexrelease>    \begingroup
%<latexrelease>      \chardef\XeTeXcharclassID = 0 %
%<latexrelease>      \chardef\XeTeXcharclassOP = 0 %
%<latexrelease>      \chardef\XeTeXcharclassCL = 0 %
%<latexrelease>      \chardef\XeTeXcharclassEX = 0 %
%<latexrelease>      \chardef\XeTeXcharclassIS = 0 %
%<latexrelease>      \chardef\XeTeXcharclassNS = 0 %
%<latexrelease>      \chardef\XeTeXcharclassCM = 0 %
%<latexrelease>      \input{load-unicode-xetex-classes}
%<latexrelease>    \endgroup
%<latexrelease>    \global\let\xtxHanGlue\undefined
%<latexrelease>    \global\let\xtxHanSpace\undefined
%<latexrelease>    \global\XeTeXinterchartoks 0 1 = {}
%<latexrelease>    \global\XeTeXinterchartoks 0 2 = {}
%<latexrelease>    \global\XeTeXinterchartoks 0 3 = {}
%<latexrelease>    \global\XeTeXinterchartoks 1 0 = {}
%<latexrelease>    \global\XeTeXinterchartoks 2 0 = {}
%<latexrelease>    \global\XeTeXinterchartoks 3 0 = {}
%<latexrelease>    \global\XeTeXinterchartoks 1 1 = {}
%<latexrelease>    \global\XeTeXinterchartoks 1 2 = {}
%<latexrelease>    \global\XeTeXinterchartoks 1 3 = {}
%<latexrelease>    \global\XeTeXinterchartoks 2 1 = {}
%<latexrelease>    \global\XeTeXinterchartoks 2 2 = {}
%<latexrelease>    \global\XeTeXinterchartoks 2 3 = {}
%<latexrelease>    \global\XeTeXinterchartoks 3 1 = {}
%<latexrelease>    \global\XeTeXinterchartoks 3 2 = {}
%<latexrelease>    \global\XeTeXinterchartoks 3 3 = {}
%<latexrelease>  \fi
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>  {\XeTeXintercharclasses}{XeTeX character classes}%
%<latexrelease>  \ifx\XeTeXinterchartoks\undefined
%<latexrelease>  \else
%<latexrelease>   \input{load-unicode-xetex-classes}
%<latexrelease>   \gdef\xtxHanGlue{\hskip0pt plus 0.1em\relax}
%<latexrelease>   \gdef\xtxHanSpace{\hskip0.2em plus 0.2em minus 0.1em\relax}
%<latexrelease>   \global\XeTeXinterchartoks 0 1 = {\xtxHanSpace}
%<latexrelease>   \global\XeTeXinterchartoks 0 2 = {\xtxHanSpace}
%<latexrelease>   \global\XeTeXinterchartoks 0 3 = {\nobreak\xtxHanSpace}
%<latexrelease>   \global\XeTeXinterchartoks 1 0 = {\xtxHanSpace}
%<latexrelease>   \global\XeTeXinterchartoks 2 0 = {\nobreak\xtxHanSpace}
%<latexrelease>   \global\XeTeXinterchartoks 3 0 = {\xtxHanSpace}
%<latexrelease>   \global\XeTeXinterchartoks 1 1 = {\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 1 2 = {\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 1 3 = {\nobreak\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 2 1 = {\nobreak\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 2 2 = {\nobreak\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 2 3 = {\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 3 1 = {\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 3 2 = {\xtxHanGlue}
%<latexrelease>   \global\XeTeXinterchartoks 3 3 = {\nobreak\xtxHanGlue}
%<latexrelease>  \fi
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \changes{v2.0d}{2015/02/03}{Set \cs{lccode} for \texttt{-} with Unicode
%   engines}
% There is one over-ride that makes sense here (see below for the same for
% $8$-bit engines): setting the lccode for |-| to itself.
%    \begin{macrocode}
  \lccode`\- =`\- % default hyphen char
%    \end{macrocode}
% The alternative is that a ``traditional'' engine is in use.
%    \begin{macrocode}
\else
%    \end{macrocode}
% \changes{v1.1b}{1998/05/20}{Set up lccodes before loading
%    hyphenation files: pr/2639}
%    We set things up so that hyphenation files can assume that the
%    default (T1) lccodes are in use (at present this also sets up the
%    uccodes).
%    We temporarily define |\reserved@a| to apply |\reserved@c| to
%    all the numbers in the range of its arguments.
%    \begin{macrocode}
\def\reserved@a#1#2{%
   \@tempcnta#1\relax
   \@tempcntb#2\relax
   \reserved@b
}
\def\reserved@b{%
   \ifnum\@tempcnta>\@tempcntb\else
      \reserved@c\@tempcnta
      \advance\@tempcnta\@ne
      \expandafter\reserved@b
   \fi
}
%    \end{macrocode}
%    Depending on the \TeX{} version, we might not be allowed to do
%    this for non-ASCII characters.
% \changes{v1.0n}{1994/06/09}{For \TeX2, do not set codes for higher
%                   half of character table.}
%    \begin{macrocode}
\def\reserved@c#1{%
   \count@=#1\advance\count@ by -"20
   \uccode#1=\count@
   \lccode#1=#1
}
\reserved@a{`\a}{`\z}
\reserved@a{"A0}{"BC}
\reserved@a{"E0}{"FF}
%    \end{macrocode}
% The upper case characters need their |\uccode| and |\lccode| values
% set, and their |\sfcode| set to 999.
%    \begin{macrocode}
\def\reserved@c#1{%
   \count@=#1\advance\count@ by "20
   \uccode#1=#1
   \lccode#1=\count@
   \sfcode#1=999
}
\reserved@a{`\A}{`\Z}
\reserved@a{"80}{"9C}
\reserved@a{"C0}{"DF}
%    \end{macrocode}
% Well, it would be nice if that were correct, but unfortunately, the
% Cork encoding contains some odd slots whose uccode or lccode isn't
% quite what you'd expect.
%    \begin{macrocode}
\uccode`\^^Y=`\I     % dotless i
\lccode`\^^Y=`\^^Y   % dotless i
\uccode`\^^Z=`\J     % dotless j, ae in OT1
\lccode`\^^Z=`\^^Z   % dotless j, ae in OT1
\lccode`\^^9d=`\i    % dotted I
\uccode`\^^9d=`\^^9d % dotted I
\lccode`\^^9e=`\^^9e % d-bar
\uccode`\^^9e=`\^^d0 % d-bar
%    \end{macrocode}
% Finally here is one that helps hyphenation in the OT1 encoding.
% \changes{v1.0z}{1996/10/31}
%    {Added extra \cs{lcode}, hoping it does no harm in T1 (pr/1969)}
%    \begin{macrocode}
\lccode`\^^[=`\^^[   % oe in OT1
%    \end{macrocode}
%
% And we also set the |\lccode| of |\-| and |\textcompwordmark| so
% that they do not prevent hyphenation in the remainder of the word
% (as suggested by Lars Helstr\"om).
% \changes{v1.1e}{2003/10/13}
%    {Added extra \cs{lccode} for \cs{-} and \cs{textcompwordmark}}
%    \begin{macrocode}
\lccode`\- =`\-   % default hyphen char
\lccode 127=127   % alternate hyphen char
\lccode 23 =23    % textcompwordmark in T1
%    \end{macrocode}
%
% End of the conditional to select either Unicode or T1 encoding defaults.
%    \begin{macrocode}
\fi
%    \end{macrocode}
%
% \changes{v2.2b}{2020/07/08}
%         {Add a last-minute hook for \textsf{expl3}}
% At this stage, we can install any last-minute \textsf{expl3} set-up.
%    \begin{macrocode}
\@expl@finalise@setup@@
\def\@expl@finalise@setup@@{}
%    \end{macrocode}
%
%  This is as good a place as any to active a few Xe\TeX{}-specific
%  settings
%    \begin{macrocode}
\ifx\XeTeXuseglyphmetrics\@undefined
\else
  \XeTeXuseglyphmetrics=1 %
  \XeTeXdashbreakstate=1 %
\fi
%    \end{macrocode}
%
% \subsection{Hyphenation}
%
% \changes{v0.1a}{1994/03/07}{move code here from lhyphen.dtx}
% \changes{v0.1a}{1994/03/07}
%         {use \cs{InputIfFileExists} not \cs{IfFileExists}}
% \changes{v1.0x}{1995/11/01}
%      {(DPC) Switch meaning of \cs{@addtofilelist} for cfg files}%
% The following code will be compiled into the format file. It checks
% for the existence of \texttt{hyphen.cfg} in inputs that file if
% found. Otherwise it inputs \texttt{hyphen.ltx}.  Note that these
% are loaded in \emph{before} the |\catcode|s are set, so local
% hyphenation files can use 8-bit input.
%
% We try to load the customized hyphenation description file.
%    \begin{macrocode}
\InputIfFileExists{hyphen.cfg}
           {\typeout{===========================================^^J%
                      Local configuration file hyphen.cfg used^^J%
                     ===========================================}%
             \def\@addtofilelist##1{\xdef\@filelist{\@filelist,##1}}%
           }
           {\input{hyphen.ltx}}
\let\@addtofilelist\@gobble
%    \end{macrocode}
%
% \begin{macro}{\l@nohyphenation}
% \changes{v2.0t}{2017/03/09}{ensure \cs{l@nohyphenation} is defined.}
%    \begin{macrocode}
\ifx\l@nohyphenation \@undefined
  \newlanguage\l@nohyphenation
\fi
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\document@default@language}
% Default document language. -1 acts as language 0, but used as a flag in |\document|
% to see if it has been set in the preamble.
% \changes{v2.1f}{2018/08/24}{Add to latexrelease (github/68)}
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2017/04/15}%
%<latexrelease>       {\document@default@language}{Save language for hyphenation}%
\let\document@default@language\m@ne
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>       {\document@default@language}{Save language for hyphenation}%
%
%<latexrelease>\let\document@default@language\@undefined
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
% \end{macro}
%
%
%
% \subsection{Font loading}
%    Fonts loaded during the formatting process might already have
%    changed the |\font@submax| from |0pt| to something higher.
%    If so, we put out a bold warning.
% \changes{v0.1l}{1994/05/20}{Use new font warning commands}
% \changes{v1.1c}{2000/08/23}{Fix typo in warning}
%    \begin{macrocode}
\ifdim \font@submax >\z@
   \@font@warning{Size substitutions with differences\MessageBreak
                 up to \font@submax\space have occurred.\MessageBreak
                \MessageBreak
                Please check the transcript file
                carefully\MessageBreak
                and redo the format generation if necessary!
                \@gobbletwo}%
   \errhelp{Only stopped, to give you time to
            read the above message.}
   \errmessage{}
%    \end{macrocode}
%    We reset the macro. Otherwise every user will get a warning on
%    every job.
%    \begin{macrocode}
\def\font@submax{0pt}
\fi
%    \end{macrocode}
%
%   For pdf\TeX\ preload and enable automatic glyph to Unicode mapping
%   for more reliable copy and paste support.
%   \changes{v2.2l}{2021/01/21}{Load glyphtounicode.tex for pdf\TeX}
%   \changes{v2.2m}{2021/02/25}{Improve speed of ToUnicode everyjob loading code}
%
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease>                 {\pdfgentounicode}{Preload glyphtounicode}%
\ifx \pdfgentounicode \@undefined \else
%<*2ekernel>
  \ifnum 0=0%
    \ifdefined\pdftexversion
% \pdftexversion<140 does not have \pdfgentounicode, so we only check higher values
      \ifnum \pdftexversion=140 \ifnum\pdftexrevision<22 1\fi\fi
    \fi
    \relax
%</2ekernel>
    \input glyphtounicode
%<*2ekernel>
  \else
    \begingroup
      \everyeof{\noexpand}\endlinechar-1
      \edef\x{\endgroup
        \everyjob{\the\everyjob\@@input glyphtounicode }%
    }\x
  \fi
%</2ekernel>
  \pdfgentounicode=1
\fi
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%   When rolling back we can't unload the glyphtounicode mappings, but we
%   can reset |\pdfgentounicode| to ensure that they aren't used.
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\pdfgentounicode}{Preload glyphtounicode}%
%<latexrelease>\ifx \pdfgentounicode \@undefined \else
%<latexrelease>  \pdfgentounicode=0
%<latexrelease>\fi
%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
%    \end{macrocode}
%
% \subsection{Input encoding}
%
% \changes{v2.1a}{2018/03/25}{default to UTF-8}
% Starting with the 2018 \LaTeX\ release default the inputencoding
% to UTF-8. Unless the format is being used with luatex, xetex, enctex or mltex.
%
% This is done in a way largely compatible with older releases: |utf8.def| is input just as if\\
% |\usepackage[utf8]{inputenc}|\\
% had been used, however rather than input the whole package a minimal core part just enough to support
% loading the UTF-8 encoding files is defined here.
%
% If a document re-specifies UTF-8 this is silently ignored.
%
%    \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
%    \end{macrocode}
%
% Check that a classic 8-bit tex engine is being used (LaTeX or PDFLaTeX).
%
%    \begin{macrocode}
%<latexrelease>\IncludeInRelease{2018/04/01}%
%<latexrelease>                 {\UTFviii@invalid}{UTF-8 default}%
%    \end{macrocode}
%
%
% Skip this section in Unicode TeX, or if  MLTeX and EncTeX are enabled.
%    \begin{macrocode}
\ifnum0%
  \ifx\Umathcode\@undefined\else 1\fi
  \ifx\mubyte\@undefined\else 1\fi
  \ifx\charsubdef\@undefined\else 1\fi
  =\z@
%    \end{macrocode}
%
%    \begin{macrocode}
\def\saved@space@catcode{10}
\let\@inpenc@test\relax
\def\IeC{%
  \ifx\protect\@typeset@protect
    \expandafter\@firstofone
  \else
    \noexpand\IeC
  \fi
}
%    \end{macrocode}
%
% Make characters active for UTF-8 input formats
%    \begin{macrocode}
\@tempcnta=1
\loop
  \catcode\@tempcnta=13  %
  \advance\@tempcnta\@ne %
\ifnum\@tempcnta<32      %
\repeat                  %
\catcode0=15  % null
\catcode9=10  % tab
\catcode10=12 % ctrl J
\catcode12=13 % ctrl L
\catcode13=5  % newline
\@tempcnta=128
\loop
  \catcode\@tempcnta=13
  \advance\@tempcnta\@ne
\ifnum\@tempcnta<256
\repeat
%    \end{macrocode}
%
% \begin{macro}{\UseRawInputEncoding}
% \changes{v2.1a}{2018/03/25}{Macro added}
% Reset 8 bit characters to catcode 12 so the input encoding matches the ``Raw''
% font encoding.
% Useful for special behaviours, or for compatibility with older \LaTeX\ formats.
% \changes{v2.1b}{2018/04/06}{Undo changes to \cs{DeclareFontEncoding@} and
%                             definition of \cs{DeclareUnicodeCharacter}}
% \changes{v2.1c}{2018/04/07}{Undefine \cs{inputencodingname}}
%    \begin{macrocode}
\def\UseRawInputEncoding{%
\let\inputencodingname\@undefined                     % revert
\let\DeclareFontEncoding@\DeclareFontEncoding@saved   % revert
\let\DeclareUnicodeCharacter\@undefined               % revert
\@tempcnta=1
\loop
  \catcode\@tempcnta=15  %
  \advance\@tempcnta\@ne %
\ifnum\@tempcnta<32      %
\repeat                  %
\catcode0=15  % null
\catcode9=10  % tab
\catcode10=12 % ctrl J
\catcode12=13 % ctrl L
\catcode13=5  % newline
\@tempcnta=128
\loop
  \catcode\@tempcnta=12
  \advance\@tempcnta\@ne
\ifnum\@tempcnta<256
\repeat
}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\DeclareFontEncoding@saved}
%    Saved version of |\DeclareFontEncoding@| before \texttt{utf8.def}
%    modifies it for use in |\UseRawInputEncoding| above.
%    \begin{macrocode}
\let\DeclareFontEncoding@saved\DeclareFontEncoding@
%    \end{macrocode}
%  \end{macro}
%
% \changes{v2.1d}{2018/04/08}{Delay full UTF-8 handling to \cs{everyjob}}
% \changes{v2.18}{2018/05/11}{Make invalid UTF-8 also safe, for legacy filesystem encodings}
%    \begin{macrocode}
\edef\inputencodingname{utf8}%
\input{utf8.def}
\let\UTFviii@undefined@err@@\UTFviii@undefined@err
\let\UTFviii@invalid@err@@\UTFviii@invalid@err
\let\UTFviii@two@octets@@\UTFviii@two@octets
\let\UTFviii@three@octets@@\UTFviii@three@octets
\let\UTFviii@four@octets@@\UTFviii@four@octets
%<2ekernel>\def\UTFviii@undefined@err#1{\@gobble#1}%
%<2ekernel>\let\UTFviii@invalid@err\string
%<2ekernel>\let\UTFviii@two@octets\string
%<2ekernel>\let\UTFviii@three@octets\string
%<2ekernel>\let\UTFviii@four@octets\string
%<2ekernel>\everyjob\expandafter{\the\everyjob
%<2ekernel>\let\UTFviii@undefined@err\UTFviii@undefined@err@@
%<2ekernel>\let\UTFviii@invalid@err\UTFviii@invalid@err@@
%<2ekernel>\let\UTFviii@two@octets\UTFviii@two@octets@@
%<2ekernel>\let\UTFviii@three@octets\UTFviii@three@octets@@
%<2ekernel>\let\UTFviii@four@octets\UTFviii@four@octets@@
%<2ekernel>}
\let\@inpenc@test\@undefined
\let\saved@space@catcode\@undefined
%    \end{macrocode}
%
% For formats not set up for UTF-8 default, set the C0 controls to catcode 15.
%    \begin{macrocode}
\else
\@tempcnta=0
\loop
  \catcode\@tempcnta=15  %
  \advance\@tempcnta\@ne %
\ifnum\@tempcnta<32      %
\repeat                  %
\catcode0=15  % null
\catcode9=10  % tab
\catcode10=12 % ctrl J
\catcode12=13 % ctrl L
\catcode13=5  % newline
%    \end{macrocode}
%
%    \begin{macrocode}
\let\UseRawInputEncoding\relax
%    \end{macrocode}
%
%    This ends the skipped code in Unicode engines:
%    \begin{macrocode}
\fi
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease>                 {\UTFviii@invalid}{UTF-8 default}%
%    \end{macrocode}
%
%    The first block of commands got only introduced in 2019 but we
%    revert all of Unicode support  in one go not jump to the
%    intermediate version.
%    \begin{macrocode}
%<latexrelease>  \let\UTFviii@two@octets@combine\@undefined
%<latexrelease>  \let\UTFviii@three@octets@combine\@undefined
%<latexrelease>  \let\UTFviii@four@octets@combine\@undefined
%<latexrelease>  \let\UTFviii@two@octets@string\@undefined
%<latexrelease>  \let\UTFviii@three@octets@string\@undefined
%<latexrelease>  \let\UTFviii@four@octets@string\@undefined
%<latexrelease>  \let\UTFviii@two@octets@noexpand\@undefined
%<latexrelease>  \let\UTFviii@three@octets@noexpand\@undefined
%<latexrelease>  \let\UTFviii@four@octets@noexpand\@undefined
%    \end{macrocode}
%
%    \begin{macrocode}
%<latexrelease>\@tempcnta=0
%<latexrelease>\loop
%<latexrelease>  \catcode\@tempcnta=15
%<latexrelease>  \advance\@tempcnta\@ne
%<latexrelease>\ifnum\@tempcnta<32
%<latexrelease>\repeat       %
%<latexrelease>\catcode9=10  % tab
%<latexrelease>\catcode10=12 % ctrl J
%<latexrelease>\catcode12=13 % ctrl L
%<latexrelease>\catcode13=5  % newline
%<latexrelease>\@tempcnta=128
%<latexrelease>\loop
%<latexrelease>\catcode\@tempcnta=12
%<latexrelease>\advance\@tempcnta\@ne
%<latexrelease>\ifnum\@tempcnta<256
%<latexrelease>\repeat
%<latexrelease>\let\IeC\@undefined
%<latexrelease>\def\DeclareFontEncoding@#1#2#3{%
%<latexrelease>  \expandafter
%<latexrelease>  \ifx\csname T@#1\endcsname\relax
%<latexrelease>     \def\cdp@elt{\noexpand\cdp@elt}%
%<latexrelease>     \xdef\cdp@list{\cdp@list\cdp@elt{#1}%
%<latexrelease>                    {\default@family}{\default@series}%
%<latexrelease>                    {\default@shape}}%
%<latexrelease>     \expandafter\let\csname#1-cmd\endcsname\@changed@cmd
%<latexrelease>  \else
%<latexrelease>     \@font@info{Redeclaring font encoding #1}%
%<latexrelease>  \fi
%<latexrelease>  \global\@namedef{T@#1}{#2}%
%<latexrelease>  \global\@namedef{M@#1}{\default@M#3}%
%<latexrelease>  \xdef\LastDeclaredEncoding{#1}%
%<latexrelease>  }
%<latexrelease>  \let\UseRawInputEncoding\@undefined
%<latexrelease>  \let\DeclareFontEncoding@saved\@undefined
%<latexrelease>  \let\inputencodingname\@undefined
%<latexrelease>\EndIncludeInRelease
%    \end{macrocode}
%
%    \begin{macrocode}
%<*2ekernel>
%    \end{macrocode}
%
% We temporarily define |\reserved@a| to apply |\reserved@c| to all the
% numbers in the range of its arguments.
%    \begin{macrocode}
\def\reserved@a#1#2{%
   \@tempcnta#1\relax
   \@tempcntb#2\relax
   \reserved@b
}
\def\reserved@b{%
   \ifnum\@tempcnta>\@tempcntb\else
      \reserved@c\@tempcnta
      \advance\@tempcnta\@ne
      \expandafter\reserved@b
   \fi
}
%    \end{macrocode}
% \changes{v0.1e}{1994/05/02}{Added setting the special catcodes.}
% \changes{v0.1f}{1994/05/02}{Set the catcode of control-J.}
% Set the special catcodes (although some of these are useless, since an
% error will have occurred if the catcodes have changed).  Note that
% |^^J| has catcode `other' for use in warning messages.
%    \begin{macrocode}
\catcode`\ =10
\catcode`\#=6
\catcode`\$=3
\catcode`\%=14
\catcode`\&=4
\catcode`\\=0
\catcode`\^=7
\catcode`\_=8
\catcode`\{=1
\catcode`\}=2
\catcode`\~=13
\catcode`\@=11
\catcode`\^^I=10
\catcode`\^^J=12
\catcode`\^^L=13
\catcode`\^^M=5
%    \end{macrocode}
% \changes{v0.1e}{1994/05/02}{Added setting the `other' catcodes.}
% Set the `other' catcodes.
%    \begin{macrocode}
\def\reserved@c#1{\catcode#1=12\relax}
\reserved@c{`\!}
\reserved@c{`\"}
\reserved@a{`\'}{`\?}
\reserved@c{`\[}
\reserved@c{`\]}
\reserved@c{`\`}
\reserved@c{`\|}
%    \end{macrocode}
% \changes{v0.1e}{1994/05/02}{Added setting the `letter' catcodes.}
% Set the `letter' catcodes.
%    \begin{macrocode}
\def\reserved@c#1{\catcode#1=11\relax}
\reserved@a{`\A}{`\Z}
\reserved@a{`\a}{`\z}
%    \end{macrocode}
% \changes{v0.1e}{1994/05/02}{Made slot 127 illegal}
% \changes{v1.0n}{1994/11/18}
%         {re-allow slots 127--255}
% All the characters in the range 0--31 and 127--255 are illegal,
% \emph{except} tab (|^^I|), nl (|^^J|), ff (|^^L|) and cr (|^^M|).
%
%
% \subsection{Lccodes and uccodes}
%
% \changes{v1.1b}{1998/05/20}{Set up uc/lccodes after loading
%    hyphenation files: pr/2639}
%    We now again set up the default (T1) uc/lccodes.
%    The lower case characters need their |\uccode| and |\lccode| values
%    set. Some of this is a repeat of the set-up before loading
%    hyphenation files.
%    Depending on the \TeX{} version, we might not be allowed to do
%    this for non-ASCII characters.
% \changes{v1.0n}{1994/06/09}{For \TeX2, do not set codes for higher
%                   half of character table.}
% \changes{v2.0a}{2015/01/03}{Skip resetting codes with Unicode engines}
%   For the Unicode engines (Xe\TeX{} and Lua\TeX{}) there is no need to
%   do any of this: they use hyphenation data which does not alter any
%   of the set up and so this entire block is skipped.
%    \begin{macrocode}
\ifnum 0%
  \ifx\Umathcode\@undefined\else 1\fi
  \ifx\XeTeXmathcode\@undefined\else 1\fi
  >\z@
\else
\def\reserved@c#1{%
   \count@=#1\advance\count@ by -"20
   \uccode#1=\count@
   \lccode#1=#1
}
\reserved@a{`\a}{`\z}
\reserved@a{"A0}{"BC}
\reserved@a{"E0}{"FF}
%    \end{macrocode}
% The upper case characters need their |\uccode| and |\lccode| values
% set, and their |\sfcode| set to 999.
%    \begin{macrocode}
\def\reserved@c#1{%
   \count@=#1\advance\count@ by "20
   \uccode#1=#1
   \lccode#1=\count@
   \sfcode#1=999
}
\reserved@a{`\A}{`\Z}
\reserved@a{"80}{"9C}
\reserved@a{"C0}{"DF}
%    \end{macrocode}
% Well, it would be nice if that were correct, but unfortunately, the
% Cork encoding contains some odd slots whose uccode or lccode isn't
% quite what you'd expect.
%    \begin{macrocode}
\uccode`\^^Y=`\I     % dotless i
\lccode`\^^Y=`\^^Y   % dotless i
\uccode`\^^Z=`\J     % dotless j, ae in OT1
\lccode`\^^Z=`\^^Z   % dotless j, ae in OT1
\lccode`\^^9d=`\i    % dotted I
\uccode`\^^9d=`\^^9d % dotted I
\lccode`\^^9e=`\^^9e % d-bar
\uccode`\^^9e=`\^^d0 % d-bar
%    \end{macrocode}
% Finally here is one that helps hyphenation in the OT1 encoding.
% \changes{v1.0z}{1996/10/31}
%    {Added extra \cs{lcode}, hoping it does no harm in T1 (pr/1969)}
%    \begin{macrocode}
\lccode`\^^[=`\^^[   % oe in OT1
\fi % End of reset block for 8-bit engines
%    \end{macrocode}
%
% \begin{macro}{\BCPdata}
% \changes{v2.3a}{2023/04/16}{Command added}
%   A stub for use by \pkg{babel}, \pkg{polyglossia}, etc.
%    \begin{macrocode}
\ExplSyntaxOn
\newcommand*\BCPdata[1]{
  \str_case:nn {#1}
    {
      { language } { en }
      { region }   { US }
      { script }   { Latn }
      { tag }      { en-US }
    }
}
\ExplSyntaxOff
%    \end{macrocode}
% \end{macro}
%
% \subsection{Case changing}
%
% \begin{macro}{\MakeUppercase}
% \begin{macro}{\MakeLowercase}
% \begin{macro}{\MakeTitlecase}
% \begin{macro}{\NoCaseChange}
% \begin{macro}{\AddToNoCaseChangeList}
% \begin{macro}{\CaseSwitch}
% \begin{macro}{\DeclareCaseChangeEquivalent}
% \begin{macro}{\DeclareLowercaseMapping}
% \begin{macro}{\DeclareTitlecaseMapping}
% \begin{macro}{\DeclareUppercaseMapping}
% \begin{macro}{\DeclareLowercaseExclusions}
% \begin{macro}{\DeclareTitlecaseExclusions}
% \begin{macro}{\DeclareUppercaseExclusions}
% \begin{macro}{\@uclclist}
%
%
% \changes{v1.1a}{1997/10/20}{Removed \cs{aa} and \cs{AA} from
%    \cs{@uclclist} as these are macros.}
% \changes{v2.2r}{2022/02/20}{use \cs{text_lowercase:n}}%
%    And whilst we're doing things with uc/lc tables, here are two
%    commands to upper- and lower-case a string.
%
%
% \changes{v2.1h}{2019/09/14}{Expand UTF8 chars when case changing (github/177)}
% \changes{v2.2r}{2022/02/20}
%                {Use \cs{@expl@text@uppercase@@n}, removing local redefinition of \cs{UTF@two@octets@noexpand}}%
% \changes{v2.2t}{2022/04/21}{Support \cs{noexpand} in argument of \cs{@expl@text@uppercase@@n}}
% \changes{v2.2v}{2022/06/30}{Just use \cs{text_lowercase:n} without \cs{protectd@edf} gh/881x}%
% \changes{v2.2w}{2022/07/04}{Introduced \cs{CaseSwitch}, \cs{DeclareCaseChangeEquivalent} and \cs{MakeTitlecase} to support hooking into case changing gh/889}%
% \changes{v2.2x}{2022/10/26}{Introduce optional argument for case-changing commands}
% \changes{v2.2x}{2022/10/26}{Make case changing commands language-aware}
% \changes{v2.2x}{2022/10/26}{Auto-detect \pkg{babel} locale}
% \changes{v2.3a}{2023/04/11}{Use new generic mechanism to detect locale}
% \changes{v2.3d}{2024/11/12}{Use updated titlecase-first function in \pkg{expl3}}
% \changes{v2.3d}{2024/11/12}{Add option to titlecase first or all words}
% \changes{v2.3f}{2025/06/04}{Add default for titlecasing}
% Wrappers around the L3 case changing functions.
% |\protected| to make them mostly safe as replacements for |uppercase|
% and |\lowercase|.  
%
% In
%\begin{verbatim}
%    \markboth{\MakeUppercase\contentsname}
%             {\MakeUppercase\contentsname}
%\end{verbatim}
%    then the uppercasing is only done to the first letter of the
%    contents name, since the mark expands out to:
%\begin{verbatim}
%    \mark{\MakeUppercase Table of Contents}
%         {\MakeUppercase Table of Contents}
%\end{verbatim}
%    In order to get round this, we redefine |\MakeUppercase| and
% |\MakeLowercase| to grab their argument and brace it. 
%
% Earlier versions needed to process |\@uclclist| in an |\edef|
% to handle legacy input encodings, but recent (2022) expl3 versions
% handle non-UTF8 text natively so we simply call the |\text_...case:n|
% functions.
%    \begin{macrocode}
\ExplSyntaxOn
\keys_define:nn { __kernel }
  {
    lang   .str_set:N = \reserved@a ,
    locale .str_set:N = \reserved@a ,
    words .choices:nn =
      { all , first }
      { \str_set:Nn \reserved@b {#1} }
  }
\cs_new_protected:Npn \@@text@case@aux #1#2#3
  {
    \cs_set_nopar:Npn \reserved@a { }
    \cs_set_nopar:Npn \reserved@b { first }
    \tl_if_blank:nTF {#2}
      {
        \str_set:Nx \reserved@a
          { \BCPdata { casing } }
        \str_if_empty:NT \reserved@a
          {
            \str_set:Nx \reserved@a
              { \BCPdata { language } }
          }
      }
      { \keys_set:nn { __kernel } {#2} }
    \use:c { text_ #1 :Vn } \reserved@a {#3}
  }
%    \end{macrocode}
% The odd use of \emph{three} spaces here is needed as \pkg{ltcmd} uses the
% name with one and two spaces to give a `friendly' error message for a runaway
% argument: that means we can't use it here.
%    \begin{macrocode}
\exp_args_generate:n { cnx }
\cs_set_protected:Npn \reserved@a #1
  {
    \cs_generate_variant:cn { text_ \str_lowercase:n {#1} case:nn } { V }
    \ExpandArgs { cnx } \NewExpandableDocumentCommand
       { Make#1case }
       { O{} +m }
       { \exp_not:c { Make#1case \c_space_tl \c_space_tl \c_space_tl } [####1] {####2} }
  }
\reserved@a { Upper }
\reserved@a { Lower }
\reserved@a { Title }
%    \end{macrocode}
%   These don't get covered above so we do them manually.
%    \begin{macrocode}
\cs_generate_variant:Nn \text_titlecase_all:nn { V }
\cs_generate_variant:Nn \text_titlecase_first:nn { V }
%    \end{macrocode}
% \changes{v2.2y}{2022/11/30}{Set \cs{oe}/\cs{OE} equal to act as a marker for \pkg{babel}}
% \changes{v2.2z}{2023/03/28}{Use groups for gh/1021}
% Currently, \pkg{babel} uses the equivalence of \cs{oe} and \cs{OE} to force casing of
% some material, most notably in \cs{today}. To enable that to work, we have to set those
% commands equal even though the current case changing code does not work using this
% approach.
%    \begin{macrocode}
\cs_new_protected:cpn { MakeLowercase \c_space_tl \c_space_tl \c_space_tl } [#1] #2
  {{
    \let \OE \oe
    \@@text@case@aux { lowercase } {#1} {#2}
  }}
\cs_new_protected:cpn { MakeUppercase \c_space_tl \c_space_tl \c_space_tl } [#1] #2
  {{
    \let \oe \OE
    \@@text@case@aux { uppercase } {#1} {#2}
  }}
\cs_new_protected:cpn { MakeTitlecase \c_space_tl \c_space_tl \c_space_tl } [#1] #2
  {{
    \let \oe \OE
    \@@text@case@aux { titlecase_ \reserved@b } {#1} {#2}
  }}
%    \end{macrocode}
%
% \changes{v2.2u}{2022/06/02}{Add \cs{NoCaseChange}}
% \changes{v2.2u}{2022/06/30}{Add \cs{AddToNoCaseChangeList}}
% \changes{v2.3b}{2023/04/19}{Add \cs{DeclareLowercaseMapping},
%   \cs{DeclareTitlecaseMapping} and \cs{DeclareUppercaseMapping}}
% \changes{v2.3c}{2023/05/30}{Fix a typo in implementation of
%   \cs{DeclareLowercaseMapping}, etc.}
% |\NoCaseChange| protects its argument from the case change functions.
%
% |\AddToNoCaseChangeList| Allows new commands to protect their arguments, eg
% |AddToNoCaseChangeList{\eqref}| would protect the argument of |\eqref|
% in the same way as the argument of |\ref|.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn\AddToNoCaseChangeList
         {\tl_put_right:Nn \l_text_case_exclude_arg_tl}
\AddToNoCaseChangeList{ \NoCaseChange }
\cs_new_protected:Npn \NoCaseChange #1 {#1}
\cs_new_eq:NN \CaseSwitch \text_case_switch:nnnn
\cs_new_eq:NN \DeclareCaseChangeEquivalent
  \text_declare_case_equivalent:Nn
\NewDocumentCommand \DeclareLowercaseMapping { o m m }
  {
    \IfNoValueTF {#1}
      { \text_declare_lowercase_mapping:nn }
      { \text_declare_lowercase_mapping:nnn {#1} }
        {#2} {#3}
  }
\NewDocumentCommand \DeclareTitlecaseMapping { o m m }
  {
    \IfNoValueTF {#1}
      { \text_declare_titlecase_mapping:nn }
      { \text_declare_titlecase_mapping:nnn {#1} }
        {#2} {#3}
  }
\NewDocumentCommand \DeclareUppercaseMapping { o m m }
  {
    \IfNoValueTF {#1}
      { \text_declare_uppercase_mapping:nn }
      { \text_declare_uppercase_mapping:nnn {#1} }
        {#2} {#3}
  }
%    \end{macrocode}
%
% \changes{v2.3g}{2025-07-01}{Add \cs{DeclareLowercaseExclusions},
%   \cs{DeclareTitlecaseExclusions} and \cs{DeclareUppercaseExclusions}}
%    \begin{macrocode}
\cs_new_protected:Npn \DeclareLowercaseExclusions #1
  {
    \clist_map_inline:nn {#1}
      { \text_declare_lowercase_exclusion:n {##1} }
  }
\cs_new_protected:Npn \DeclareTitlecaseExclusions #1
  {
    \clist_map_inline:nn {#1}
      { \text_declare_titlecase_exclusion:n {##1} }
  }
\cs_new_protected:Npn \DeclareUppercaseExclusions #1
  {
    \clist_map_inline:nn {#1}
      { \text_declare_uppercase_exclusion:n {##1} }
  }
\ExplSyntaxOff
%    \end{macrocode}
%
% \changes{v2.2q}{2021/09/06}{Correctly upper and lowercase
%                             \cs{ij} and \cs{IJ} (gh/658)}
%    \begin{macrocode}
\def\@uclclist{\oe\OE\o\O\ae\AE
      \dh\DH\dj\DJ\l\L\ng\NG\ss\SS\ij\IJ\th\TH}
%    \end{macrocode}
%
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \changes{v1.0h}{1994/05/13}{Added output enc stuff}
% \changes{v1.0i}{1994/05/16}{moved output enc stuff to lfonts}
%
% \changes{v0.1a}{1994/03/07}{Add code from the old dump.dtx}
%
% \subsection{Applying Patch files}
% Between major releases, small patches will be distributed in
% files |ltpatch.ltx| which must be added at this point.
% \changes{v1.0m}{1994/06/08}{Add patch file system}
% \changes{v2.0h}{2015/06/23}
%     {set \cs{patch@level} in ltvers rather than in ltfinal/ltpatch}
%
% Patch file code removed.
%    \begin{macrocode}
%\IfFileExists{ltpatch.ltx}
%  {\typeout{=================================^^J%
%             Applying patch file ltpatch.ltx^^J%
%            =================================}
%   \def\fmtversion@topatch{unknown}
%   \input{ltpatch.ltx}
%   \ifx\fmtversion\fmtversion@topatch
%      \ifx\patch@level\@undefined
%        \typeout{^^J^^J^^J%
%         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
%         !! Patch file `ltpatch.ltx' not suitable for this^^J%
%         !! version of LaTeX.^^J^^J%
%         !! Please check if initex found an old patch file:^^J%
%         !! --- if so, rename it or delete it, and redo the^^J%
%         !! initex run.^^J%
%         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
%        \batchmode \@@end
%      \else
%    \end{macrocode}
% \changes{v1.0q}{1995/04/21}
%         {Allow initial patch level 0}
% \changes{v1.0t}{1995/06/13}
%         {Add patch level string more carefully}
% The code below adds the `patch level' string to the first |\typeout|
% in the startup banner.
%    \begin{macrocode}
%        \def\fmtversion@topatch{0}%
%        \ifx\fmtversion@topatch\patch@level\else
%          \def\reserved@a\typeout##1##2\reserved@a{%
%                 \typeout{##1 patch level \patch@level}##2}
%          \everyjob\expandafter\expandafter\expandafter{%
%             \expandafter\reserved@a\the\everyjob\reserved@a}
%          \let\reserved@a\relax
%          \the\everyjob
%        \fi
%      \fi
%   \else
%      \typeout{^^J^^J^^J%
%    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J%
%    !! Patch file `ltpatch.ltx' (for version <\fmtversion@topatch>)^^J%
%    !! is not suitable for version <\fmtversion> of LaTeX.^^J^^J%
%    !! Please check if initex found an old patch file:^^J%
%    !! --- if so, rename it or delete it, and redo the^^J%
%    !!     initex run.^^J%
%    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J}%
%       \batchmode \@@end
%   \fi
%   \let\fmtversion@topatch\relax
%  }{}
%    \end{macrocode}
%
% \changes{v2.2}{2019-10-02}{Load \textsf{ltexpl}}
% \changes{v2.2a}{2020-06-04}{Load \textsf{ltexpl} in \texttt{ltdefns}}
%
% \subsection{Freeing Memory}
%
% \begin{macro}{\reserved@a}
% \begin{macro}{\reserved@b}
% \changes{v1.0v}{1995/10/17}{reset here after the \cs{input} above}
% And just to make sure nobody relies on those definitions of
% |\reserved@b| and friends.
% These macros are reserved for use in the kernel. \emph{Do not use
% them as general scratch macros}.
%    \begin{macrocode}
\let\reserved@a\@filelist
\let\reserved@b=\@undefined
\let\reserved@c=\@undefined
\let\reserved@d=\@undefined
\let\reserved@e=\@undefined
\let\reserved@f=\@undefined
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\toks}
% \changes{v1.0y}{1996/07/10}
%      {Free up memory from scratch registers /2213}
%    \begin{macrocode}
\toks0{}
\toks2{}
\toks4{}
\toks6{}
\toks8{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\errhelp}
% \changes{v0.1g}{1994/05/05}{Set error help empty.}
% \changes{v1.1d}{2000/09/01}{Set error help empty at very end
%                             (pr/449 done correctly).}
% Empty the error help message, which may have some rubbish:
%    \begin{macrocode}
\errhelp{}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Initialise file list}
%
% \begin{macro}{\@providesfile}
% \changes{v1.0v}{1995/10/17}{reset macro}
% Initialise for use in the document. During initex a modified version
% has been used which leaves debugging information for |latexbug.tex|.
%    \begin{macrocode}
\def\@providesfile#1[#2]{%
    \wlog{File: #1 #2}%
    \expandafter\xdef\csname ver@#1\endcsname{#2}%
  \endgroup}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@filelist}
% \changes{v1.0w}{1995/10/19}{Move after \cs{reserved@a} setting}
% \begin{macro}{\@addtofilelist}
% Reset |\@filelist| so files input while making the format are not
% listed. The list built up so far may take up a lot of memory and so
% it is moved to |\reserved@a| where it will be overwritten as soon
% as almost any \LaTeX\ command is issued in a class file.
% However the |latexbug.tex| program will be able to access this
% information and insert it into a bug report.
%    \begin{macrocode}
\let\@filelist\@gobble
\def\@addtofilelist#1{\xdef\@filelist{\@filelist,#1}}%
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%  \subsection{Preparation for supporting PDF in backends}
%
%    At the current point in time, basic support for PDF in
%    backends is not part of \LaTeX{} core; it is provided by external
%    packages. At some time in the future that work will be placed
%    into the kernel but for now it is separate and has to be
%    explicitly loaded in the document.
%
%    In that code there is a command \cs{IfPDFManagementActiveTF} 
%    which can be used by packages in order to execute different 
%    code depending on the whether this basic backend support is loaded.
%
%    To make this also work properly when this external package is not
%    loaded at all, we here add this command already in the
%    kernel (with a trivial definition); thus any package can
%    query this loading state in all circumstances.  
%    Once this basic PDF backend
%    support gets moved to the kernel, this definition will vanish
%    again from here or, rather, it will be replaced by a real test.
%
%  \begin{macro}{\IfPDFManagementActiveTF}
%    So long as the code for the basic backend support for PDF is not 
%    loaded, the test that is implicit here will
%    always return the false branch. 
%    Once this code is loaded, this definition will get
%    replaced by a real test (as it is then possible that the
%    management code is either activated or not activated).
% \changes{v2.2p}{2021/08/08}{Default definition added (gh/640)}
%    \begin{macrocode}
\let \IfPDFManagementActiveTF \@secondoftwo
%    \end{macrocode}
%    
%    The T/F variants are defined in a way that they continue to work
%    when the main definition changes.
% \changes{v2.3e}{2025/03/01}{Provide T F variants of
%                             \cs{IfPDFManagementActiveTF} (gh/1522)}
%    \begin{macrocode}
\long\def\IfPDFManagementActiveT#1{\IfPDFManagementActiveTF{#1}{}}
\def\IfPDFManagementActiveF{\IfPDFManagementActiveTF{}}
%    \end{macrocode}
%  \end{macro}
%
%
%
% \subsection{Do some temporary work for pre-release}
%
%    This is a good place to load code that hasn't yet been
%    integrated into the other files \ldots
%    \begin{macrocode}
%    \end{macrocode}
%
% \subsection{Some last minute initializations \ldots}
%
%    Load the first aid set of definitions for external packages that await updates.
% \changes{v2.2j}{2020/09/26}
%         {Load first aid file if existing}
%    \begin{macrocode}
\@input{latex2e-first-aid-for-external-files.ltx}
%    \end{macrocode}
%
%
% \subsection{Dumping the format}
%    Finally we make |@| into a letter, ensure the format will
% be in the `normal' error mode, and dump everything into the
%    format file.
% \changes{v1.0t}{1995/06/13}
%         {Call \cs{errorstopmode}}
%    \begin{macrocode}
\makeatother
\errorstopmode
\dump
%</2ekernel>
%    \end{macrocode}
%
% \Finale
%
