diff options
Diffstat (limited to 'support')
237 files changed, 28492 insertions, 8851 deletions
diff --git a/support/TeX4ht/source/ChangeLog b/support/TeX4ht/source/ChangeLog index 890eef5005..382d834693 100644 --- a/support/TeX4ht/source/ChangeLog +++ b/support/TeX4ht/source/ChangeLog @@ -1,3 +1,233 @@ +2024-11-10 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (caption.4ht): declare caption hooks only if they + are undefined. + https://tex.stackexchange.com/a/730529/2891 + +2024-11-05 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex ( + bigfoot.4ht, usepackage.4ht, bigfoot-hooks.4ht + ): added support for the Manyfoot package. + https://tex.stackexchange.com/a/729975/2891 + +2024-11-03 Karl Berry <karl@freefriends.org> + + * tex4ht-4ht.tex (amsfonts.4ht, french.4ht, mempatch.4ht): + \write-1 version. + +2024-11-01 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex ( + usepackage.4ht, manyfoot.4ht, manyfoot-hooks.4ht + ): added support for the Manyfoot package. + https://tex.stackexchange.com/a/729975/2891 + +2024-10-29 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (french.4ht), + * tex4ht-html4.tex (html4.4ht): configure \part to omit the part + number. + https://github.com/michal-h21/make4ht/issues/155 + +2024-10-25 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathjax.tex (mathjax-latex-4ht.4ht): restore math + environments before \tikz@installcommands, to fix issues with + the matrix environment. + + * tex4ht-4ht.tex (french.4ht): fixed \part command in TOC. + https://github.com/michal-h21/make4ht/issues/155 + +2024-10-18 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (caption.4ht): fixed support for the \caption + command in classes where we don't provide \Configure{caption}. Found + in Svjour3. + + * tex4ht-4ht.tex (nicematrix.4ht): added basic support for the + Nicematrix package. + +2024-10-14 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-html4.tex (html4.4ht): fixed formatting of the \rtitlex + command of Ltugboat class. + http://puszcza.gnu.org.ua/bugs/?639 + +2024-10-13 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (latex.4ht): fixed support for LaTeX cmd hooks in + \@sect and \@ssect commands. + http://puszcza.gnu.org.ua/bugs/?639 + +2024-10-10 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathml.tex (mathml.4ht): removed spurious space after + \left. + https://tex.stackexchange.com/a/728351/2891 + + * tex4ht-4ht.tex (stmaryrd.4ht), + * tex4ht-mathml.tex (mathml.4ht): added support for \llbracket and + \rrbracket in MathML. + https://tex.stackexchange.com/a/728351/2891 + + * tex4ht-html4.tex (html4.4ht): added support for colored \cline. + https://tug.org/pipermail/tex4ht/2024q4/003598.html + +2024-10-09 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (makecell.4ht): added support for the Makecell + package. + https://tug.org/pipermail/tex4ht/2024q4/003596.html + +2024-10-08 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-html4.tex (html4.4ht): don't override \hline:color in + booktabs if it is already defined. + https://tug.org/pipermail/tex4ht/2024q4/003594.html + +2024-10-06 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-html4.tex (html4.4ht): use Colortbl's \arrayrulecolor also + for vertical table lines. + https://tug.org/pipermail/tex4ht/2024q4/003589.html + +2024-10-04 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (fancyvrb.4ht): added extra check for the + definition of \FancyVerbBackgroundColor. + +2024-10-03 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (lua-ul.4ht), + * tex4ht-html4.tex (html4.4ht): added support for the Lua-ul + package. + +2024-10-01 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (piton.4ht): prevent default use of visible space + characters. + + * tex4ht-4ht.tex (piton.4ht): load Xcolor if not already loaded. + +2024-09-30 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (colortbl-hooks.4ht, colortbl.4ht): added support + for the \arrayrulecolor command used in the document preamble. + https://puszcza.gnu.org.ua/bugs/?636 + + * tex4ht-html4.tex (html4.4ht): don't add extra black rule at the + first \hline in table. + https://puszcza.gnu.org.ua/bugs/?636 + + * tex4ht-4ht.tex (longtable.4ht): fixed support for the Colortbl + \hline. + https://puszcza.gnu.org.ua/bugs/?636 + +2024-09-27 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-html4.tex (html4-math.4ht), + * tex4ht-mathjax.tex (mathjax-latex-4ht.4ht): enclose math elements + in MathJax in HTML tags. + https://tex.stackexchange.com/a/727413/2891 + + * tex4ht-html4.tex (html4-math.4ht): don't add link to the MathJax + script if the address is empty. + +2024-09-26 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (fancyvrb.4ht): fixed support for background + colors. + + * tex4ht-4ht.tex (minted.4ht): removed minted@colorbg env, to fix + support for Minted 3.0. + +2024-09-24 Karl Berry <karl@freefriends.org> + + * wripro.tex: copyright 2024. + * Makefile (tex4ht_sty_derived): depends on wripro.tex. + +2024-09-23 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (amsmath.4ht): fixed support for superscripts and + subscripts in equation tags (like \tag{$e_{1}$}). + + * tex4ht-4ht.tex (th4.4ht), + * tex4ht-info.tex (info4ht.4ht), + * tex4ht-sty.tex (tex4ht.sty), + * wripro.tex: renamed internal TeX4ht command \Ref to \XRef, to + prevent clashes with \Ref provided by LaTeX. + + * tex4ht-4ht.tex (latex.4ht): fixed support for superscripts and + subscripts that are used values in labels (like in + \tag{$e_{1}$}\label{eq1}). Thanks to Linas Stonys. + +2024-09-11 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathjax.tex (mathjax-latex-4ht.4ht): prevent insertion of + spaces after \begin and \end in \VerbMath. + +2024-09-10 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathjax.tex (mathjax-latex-4ht.4ht): use \detokenize again, + the alternative method could lead to commands joined with the + following text (\int A to \intA). + +2024-09-09 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (usepackage.4ht, enumitem-hooks.4ht, enumitem.4ht), + * tex4ht-html4.tex (html4.4ht): added support for environments + defined using \newlist. + https://github.com/michal-h21/make4ht/issues/150 + +2024-09-03 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-fonts-noncjk.tex ( + ./tex4ht.dir/texmf/tex4ht/ht-fonts/unicode/bbm/bbm.htf + ): added support for the BBM font. Thanks to Arkady Benediktov. + * tex4ht-fonts-noncjk.tex ( + ./tex4ht.dir/texmf/tex4ht/ht-fonts/unicode/TeXvect10/vect10.htf + ./tex4ht.dir/texmf/tex4ht/ht-fonts/unicode/TeXvect10/vect.htf + ): fixed Esvect fonts characters. Thanks to Arkady Benediktov. + * tex4ht-mathml.tex (mathml.4ht): use actual arrow symbol defined in + the vect10.htf font. + +2024-08-27 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathml.tex (mathml.4ht): fixed support of upper case Greek + letters inside pictures. + https://tex.stackexchange.com/q/725157/2891 + +2024-08-19 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (moderncv.4ht), + * tex4ht-html4.tex (html4.4ht): added support for the Moderncv + package. + https://tex.stackexchange.com/q/721180/2891 + +2024-08-13 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-4ht.tex (amsfonts.4ht): fixed support for \mathbb and + \mathfrak. + + * tex4ht-jats.tex (jats.4ht): added support for LaTeX + bibliographies. + +2024-08-11 Karl Berry <karl@freefriends.org> + + * tex4ht-mathml.tex (html-mml.4ht): copyright 2024. + +2024-08-02 Michal Hoftich <michal.h21@gmail.com> + + * tex4ht-mathml.tex (mathml.4ht): added "texsource" option. It will + keep the original LaTeX code as an annotation in MathML. + https://chat.stackexchange.com/rooms/154333/discussion-on-question-by-yannisl-alternatives-to-mathml-for-pdf-tagging + + * tex4ht-4ht.tex (esvect.4ht), + * tex4ht-mathml.tex (mathml.4ht): added support for the Esvect + package. + https://tex.stackexchange.com/a/723587/2891 + 2024-07-31 Michal Hoftich <michal.h21@gmail.com> * tex4ht-fonts-noncjk.tex ( diff --git a/support/TeX4ht/source/Makefile b/support/TeX4ht/source/Makefile index 5328185f78..16da59e03c 100644 --- a/support/TeX4ht/source/Makefile +++ b/support/TeX4ht/source/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile 1538 2024-07-07 15:55:16Z karl $ +# $Id: Makefile 1558 2024-09-24 17:22:45Z karl $ # This file is public domain. Originally written 2010, Karl Berry. # Assumes GNU make. @@ -385,8 +385,6 @@ endif derived += $(tex4ht_mathjax_derived) tex4ht_mathjax_derived = mathjax-latex-4ht.4ht -# wripro.tex generates nothing (not literate). - ifneq ($(do_java),2) derived += $(xtpipes_derived) xtpipes_derived = \ @@ -577,7 +575,7 @@ $(tex4ht_ooimpress_derived): tex4ht-ooimpress.tex $(common) $(tex4ht_options_derived): tex4ht-options.tex $(common) htlatex $< "html,3,sections+" "" "" $(tex_1opt) -$(tex4ht_sty_derived): tex4ht-sty.tex $(common_no_tex4ht_sty) +$(tex4ht_sty_derived): tex4ht-sty.tex wripro.tex $(common_no_tex4ht_sty) $(HTTEX) $< "" $(tex4ht_svg_derived): tex4ht-svg.tex $(common) diff --git a/support/TeX4ht/source/mktex4ht-cnf.tex b/support/TeX4ht/source/mktex4ht-cnf.tex index 7bc692fff6..5f8283d707 100644 --- a/support/TeX4ht/source/mktex4ht-cnf.tex +++ b/support/TeX4ht/source/mktex4ht-cnf.tex @@ -1,4 +1,4 @@ -% $Id: mktex4ht-cnf.tex 1523 2024-05-27 14:16:04Z michal_h21 $ +% $Id: mktex4ht-cnf.tex 1594 2024-11-05 10:24:06Z michal_h21 $ % Manually-maintained file, listing *.4ht files created by tex4ht-4ht.tex. % Read by tex4ht-cond4ht. % @@ -47,6 +47,7 @@ \AddFile{7}{supertabular} \AddFile{7}{array} \AddFile{9}{dcolumn} +\AddFile{9}{makecell} \AddFile{7}{longtable} \AddFile{7}{pctable} \AddFile{8}{tabulary} @@ -57,6 +58,7 @@ \AddFile{7}{arydshln} \AddFile{9}{threeparttable} \AddFile{9}{tabularray} +\AddFile{9}{nicematrix} \AddFile{9}{mdwtab} \AddFile{9}{tabto} \AddFile{9}{multirow} @@ -227,6 +229,7 @@ \AddFile{7}{dvipsnam} \AddFile{7}{svgnam} \AddFile{7}{colortbl} +\AddFile{7}{colortbl-hooks} \AddFile{6}{dvips} \AddFile{9}{textures} \AddFile{9}{dvipdf} @@ -238,8 +241,10 @@ \AddFile{9}{europecv} \AddFile{9}{resume} \AddFile{9}{curve} +\AddFile{9}{moderncv} \AddFile{9}{vowel} \AddFile{9}{enumitem} +\AddFile{9}{enumitem-hooks} \AddFile{9}{esperanto} \AddFile{9}{IEEEtran} \AddFile{9}{enumerate} @@ -325,6 +330,7 @@ \AddFile{9}{hyperxmp} \AddFile{9}{breqn} \AddFile{9}{nicefrac} +\AddFile{9}{stmaryrd} \AddFile{9}{multicol} \AddFile{2}{lettrine} \AddFile{9}{osudeG} @@ -334,11 +340,16 @@ \AddFile{9}{footmisc} \AddFile{9}{tablefootnote} \AddFile{9}{marginnote} +\AddFile{9}{manyfoot} +\AddFile{9}{manyfoot-hooks} +\AddFile{9}{bigfoot} +\AddFile{9}{bigfoot-hooks} \AddFile{9}{writer} \AddFile{9}{mdwlist} \AddFile{9}{sverb} \AddFile{9}{syntax} \AddFile{9}{soul} +\AddFile{9}{lua-ul} \AddFile{5}{plain} \AddFile{9}{manmac} \AddFile{8}{mex} @@ -415,4 +426,5 @@ \AddFile{9}{fontawesome5} \AddFile{9}{mhchem} \AddFile{9}{chemfig} +\AddFile{9}{esvect} % \AddFile{9}{mktex4ht} diff --git a/support/TeX4ht/source/tex4ht-4ht.tex b/support/TeX4ht/source/tex4ht-4ht.tex index 60536c1c1f..e5fd10f33d 100644 --- a/support/TeX4ht/source/tex4ht-4ht.tex +++ b/support/TeX4ht/source/tex4ht-4ht.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-4ht.tex 1539 2024-07-26 15:53:24Z michal_h21 $ +% $Id: tex4ht-4ht.tex 1595 2024-11-10 19:20:38Z michal_h21 $ % tex tex4ht-4ht or ht tex tex4ht-4ht % % Copyright 2009-2024 TeX Users Group @@ -1526,6 +1526,13 @@ A better def is given to \''\l:bel' in AmsLaTeX . \let\o:ref|=\:ref \def\::ref#1{{\:SUBOff\:SUPOff\xdef\RefArg{#1}}\expandafter\o:ref \expandafter{\RefArg}} +\ExplSyntaxOn +\def\::ref#1{{\:SUBOff\:SUPOff\xdef\RefArg{#1}% + \SUBOn\SUPOn% + \def\rEfLiNK##1##2{\Link{##1}{}\tl_rescan:nn{}{##2}\EndLink}% + \expandafter\o:ref\expandafter{\RefArg}% +}} +\ExplSyntaxOff \DeclareDocumentCommand\:ref{s}{\IfBooleanTF{#1}{\Protect\::ref}{\Protect\::ref}} \let\ref|=\:ref >>> @@ -1535,12 +1542,14 @@ Support for the \''\Ref' command. It is variant of \''\ref' that uppercases first letter of the referenced label. \<sub/sup in labels/refs\><<< -\def\::Ref#1{% - \let\olda:rEfLiNK\rEfLiNK%% - \def\rEfLiNK##1##2{\Link{##1}{}\edef\:ref:currentlabel{##2}\expandafter\MakeUppercase\:ref:currentlabel\EndLink}% - \::ref{#1}% - \let\rEfLiNK\olda:rEfLiNK% -} +\ExplSyntaxOn +\def\::Ref#1{{% + \:SUBOff\:SUPOff\xdef\RefArg{#1}% + \SUBOn\SUPOn% + \def\rEfLiNK##1##2{\tl_set_rescan:Nnn\l_tmpa_tl{}{##2}\Link{##1}{}\expandafter\MakeUppercase\l_tmpa_tl\EndLink}% + \expandafter\o:ref\expandafter{\RefArg}% +}} +\ExplSyntaxOff \DeclareDocumentCommand\:Ref{s}{\IfBooleanTF{#1}{\Protect\::Ref}{\Protect\::Ref}} \let\Ref\:Ref >>> @@ -10514,6 +10523,36 @@ new way. Don't globalize ar:cnt!!!! \NewConfigure{dcolumn}{2} >>> +%%%%%%%%%%%%%%%%%%%%%%%% +\Section{makecell} +%%%%%%%%%%%%%%%%%%%%%%%% + +\<makecell.4ht\><<< +% makecell.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> + +|<makecell makegapedcells|> + +\Hinput{makecell} +\endinput +>>> \AddFile{9}{makecell} + +These commands redefine internall tabular macros, which can lead +to errors. We need to disable them. User can provide an alternative +configurations for them, but it is most likely unnecessary. + +\<makecell makegapedcells\><<< +\NewConfigure{makegapedcells}{1} +\def\:tempa{\a:makegapedcells} +\HLet\makegapedcells\:tempa + +\NewConfigure{nomakegapedcells}{1} +\def\:tempa{\a:nomakegapedcells} +\HLet\nomakegapedcells\:tempa +>>> + + %%%%%%%%%%%%%%%%%%%%%%%%% \Section{longtable.sty} %%%%%%%%%%%%%%%%%%%%%%%%% @@ -10744,13 +10783,32 @@ Fix for the \Link[https://puszcza.gnu.org.ua/bugs/?437]{}{}starred linebreak iss {\LT@t@bularcr}} >>> -\<longtable hline\><<< + + +This code doesn't work well with Colortbl, so we will ignore it. +\Link[https://puszcza.gnu.org.ua/bugs/?636]{}{}More info here\EndLink. + +\<longtable nohline\><<< \def\:tempc{% \o:noalign:{\ifnum0=`}\fi \penalty\@M \futurelet\@let@token\LT@@hline} +>>> + +The original code for longtable hline was complex, but it doesn't work +with the Colortbl package. I've found that the default hline works just +fine, so we probably don't need to change it at all. + +\<longtable hline\><<< +\def\:tempc{\a:hline} \HLet\LT@hline\:tempc +>>> + +This code is not used as well. + +\<longtable nohline\><<< \def\:tempc{% + \typeout{} \ifx\@let@token\hline \global\let\@gtempa\@gobble \gdef\LT@sep{\penalty-\@medpenalty\vskip\doublerulesep}% @@ -10791,7 +10849,7 @@ Captions in Longtable are placed inside of the table structure. We need to use special configuration to produce correct rendering, normal code for caption will not work. -\Link[https://tex.stackexchange.com/a/642350/2891] More details\EndLink +\Link[https://tex.stackexchange.com/a/642350/2891]{}{} More details\EndLink \<longtable captions\><<< \NewConfigure{longtablecaption}{4} @@ -10802,7 +10860,7 @@ normal code for caption will not work. \HLet\LT@makecaption\:tempc >>> -\Link[https://puszcza.gnu.org.ua/bugs/?313] +\Link[https://puszcza.gnu.org.ua/bugs/?313]{}{} Write table info to the LOT \EndLink \<longtable captions\><<< @@ -11251,7 +11309,7 @@ compilation errors %%%%%%%%%%%%%%%%%%%%%%%% Some details are -\Link[https://tex.stackexchange.com/a/467126/2891]{}{here}\EndLink. I +\Link[https://tex.stackexchange.com/a/467126/2891]{}{}here\EndLink. I was not able to fix all tabu issues, it is too aggressive in basic table handling. Michal @@ -11516,6 +11574,31 @@ for horizontal and vertical alignment, background color and rules. >>> %%%%%%%%%%%%%%%%%%%%%%%% +\Section{nicematrix} +%%%%%%%%%%%%%%%%%%%%%%%% + +\<nicematrix.4ht\><<< +% nicematrix.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +\ExplSyntaxOn +|<nicematrix suppress error message|> +\ExplSyntaxOff + +\Hinput{nicematrix} +\endinput +>>> \AddFile{9}{nicematrix} + +Nicematrix detects if the array environment was changed +and prints error message if it was. As TeX4ht changes the environment, +it caused an error message. This boolean should suppress it. + +\<nicematrix suppress error message\><<< +\bool_set_true:N\g__nicematrix_no_test_for_array_bool +>>> + + +%%%%%%%%%%%%%%%%%%%%%%%% \Section{mdwtab} %%%%%%%%%%%%%%%%%%%%%%%% @@ -12009,14 +12092,32 @@ such as counter numbers. \def\no@sect#1#2#3#4#5{\no:sect{#1}{#2}{#3}{#4}{0ex}} >>> +The LaTeX command hook mechanism doesn't like our redefinitions of +\''\@sect' and \''\@ssect', so we need to declare and use them explicitly. +Otherwise, packages that try to add hooks to these commands may cause errors. +See \Link[http://puszcza.gnu.org.ua/bugs/?639]{}{} this bug report\EndLink. + +\<latex ltsect\><<< +\NewHookWithArguments{cmd/@sect/before}{8} +\NewReversedHookWithArguments{cmd/@sect/after}{8} +\NewHookWithArguments{cmd/@ssect/before}{5} +\NewReversedHookWithArguments{cmd/@ssect/after}{5} +>>> + \<latex ltsect\><<< \let\no@ssect|=\@ssect -\def\@ssect#1#2#3#4#5{\:Sc3 - \no@ssect{#1}{#2}{#3}{#4}{\:Sc4#5\:Sc2}\HtmlEnv} +\def\@ssect#1#2#3#4#5{% + \UseHookWithArguments{cmd/@ssect/before}{5}{##1}{##2}{##3}{##4}{##5}% + \:Sc3\no@ssect{#1}{#2}{#3}{#4}{\:Sc4#5\:Sc2}\HtmlEnv% + \UseHookWithArguments{cmd/@ssect/after}{5}{##1}{##2}{##3}{##4}{##5}% +} \let\no@sect|=\@sect \def\@sect#1#2#3#4#5#6[#7]#8{% - \xdef\c:secnumdepth{#2}\:Sc3 - \no@sect{#1}{#2}{#3}{#4}{#5}{#6}[#7]{\:Sc4#8\:Sc2}\HtmlEnv} + \UseHookWithArguments{cmd/@sect/before}{8}{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}% + \xdef\c:secnumdepth{#2}\:Sc3% + \no@sect{#1}{#2}{#3}{#4}{#5}{#6}[#7]{\:Sc4#8\:Sc2}\HtmlEnv% + \UseHookWithArguments{cmd/@sect/after}{8}{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}% + } \let\:startsection|=\@startsection \def\@startsection#1{\@ifstar{\Configure{secType}{like#1}}% {\Configure{secType}{#1}}% @@ -12061,13 +12162,16 @@ The following is need for \''\@seccntformat'. \<redf sec\><<< \def\@sect##1##2##3##4##5##6[##7]##8{% + \UseHookWithArguments{cmd/@sect/before}{8}{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}% |<disable @seccntformat|>% \let\@sect|=\no@sect \xdef\c:secnumdepth{##2}% {\SkipRefstepAnchor \let\addcontentsline|=\:gobbleIII \let\mark|=\:gobble \no@sect{##1}{##2}{##3}{##4}{##5}{##6}[{##7}]{}}% |<recall Sc, sec, ssec|>% |<restore @seccntformat|>% - \HtmlEnv \Toc:Title{##7}\csname no:#1\endcsname{##8}}% + \HtmlEnv \Toc:Title{##7}\csname no:#1\endcsname{##8}% + \UseHookWithArguments{cmd/@sect/after}{8}{##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}% + }% >>> In the above we want \`'[{##7}]' instead of \`'[##7]', in case `]' is @@ -12077,12 +12181,15 @@ The following is for the star option. \<redf ssec\><<< \def\@ssect##1##2##3##4##5{% + \UseHookWithArguments{cmd/@ssect/before}{5}{##1}{##2}{##3}{##4}{##5}% |<star sec title|>% \let\@ssect|=\no@ssect {\def\addcontentsline####1####2####3{}% \no@ssect{##1}{##2}{##3}{##4}{}}% |<recall Sc, sec, ssec|>% - \HtmlEnv \csname :like#1\endcsname{##5}}% + \HtmlEnv \csname :like#1\endcsname{##5}% + \UseHookWithArguments{cmd/@ssect/after}{5}{##1}{##2}{##3}{##4}{##5}% + }% >>> \<sv Sc, sec, ssec\><<< @@ -12926,11 +13033,25 @@ Foo } >>> +Define default values for commands used in caption configuration. +This configuration is defined in configuration files for particular +classes, so if the class is unsupported by TeX4ht (like Svjour3, +for example), the configuration is not defined and these missing +commands would cause compilation errors. + +\<caption redefine makecaption\><<< +\ifdefined\cptA:\else +\c:def\cptA:{}\c:def\cptB:{}% +\c:def\cptC:{}\c:def\cptD:{} +\fi +>>> + Handle redefined caption command. We ignore the second parameter of \''\Configure{caption}'. It contains the separator between caption number and label. It is colon by default, but user can configure to use something different. We should keep the separator selected by the user. + \<caption redefine makecaption\><<< \long\def\@makecaption#1#2{% |<fix continued float|>% @@ -16538,7 +16659,6 @@ DIV.right \<memoir.4ht\><<< % memoir.4ht (|version), generated from |jobname.tex % Copyright |CopyYear.2003. Eitan M. Gurari -% Copyright 2003-2024 TeX Users Group |<TeX4ht copywrite|> \input book.4ht \input verse.4ht @@ -16751,10 +16871,9 @@ they were stripped by the literate programming system. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \<mempatch.4ht\><<< -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% mempatch.4ht |version % -% Copyright (C) |CopyYear.2003. Eitan M. Gurari % -|<TeX4ht copyright|> +% mempatch.4ht (|version), generated from |jobname.tex +% Copyright |CopyYear.2003. Eitan M. Gurari +|<TeX4ht copywrite|> |<mempatch cfg|> \Hinput{mempatch} \endinput @@ -22112,11 +22231,13 @@ $$ |<def :currentlabel for make@df@tag|>% \anc:lbl r{}% }} -\def\make@df@tag@@@#1{\gdef\df@tag{\tagform@{#1}% +\ExplSyntaxOn +\def\make@df@tag@@@#1{\gdef\df@tag{\tagform@{\tl_rescan:nn{}{#1}}% \toks@\@xp{\p@equation{#1}}\edef\@currentlabel{\the\toks@}% |<def :currentlabel for make@df@tag|>% \anc:lbl r{}% }} +\ExplSyntaxOff >>> %%%%%%%%%%%%% @@ -22268,10 +22389,9 @@ $$ %%%%%%%%%%%%%%% \<amsfonts.4ht\><<< -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% amsfonts.4ht |version % -% Copyright (C) |CopyYear.2001. Eitan M. Gurari % -|<TeX4ht copyright|> +% amsfonts.4ht (|version), generated from |jobname.tex +% Copyright |CopyYear.2001. Eitan M. Gurari +|<TeX4ht copywrite|> |<amsfonts sty|> \Hinput{amsfonts} \endinput @@ -22279,14 +22399,14 @@ $$ \<amsfonts sty\><<<< \NewConfigure{mathbb}{2} -\def\:temp#1{{\a:mathbb \o:@mathbb:{#1}\b:mathbb}} -\HLet\@mathbb\:temp +\def\:temp#1{{\a:mathbb \o:mathbb:{#1}\b:mathbb}} +\HLet\mathbb\:temp >>> \<amsfonts sty\><<<< \NewConfigure{mathfrak}{2} -\def\:temp#1{{\a:mathfrak \o:@mathfrak:{#1}\b:mathfrak}} -\HLet\@mathfrak\:temp +\def\:temp#1{{\a:mathfrak \o:mathfrak:{#1}\b:mathfrak}} +\HLet\mathfrak\:temp >>> Commands like \''\rm' need low level implemetation through @@ -25913,15 +26033,15 @@ CTAN:language/mongolian/montex/examples %%%%%%%%%%%%%%%% \<french.4ht\><<< -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% french.4ht |version % -% Copyright (C) |CopyYear.1999. Eitan M. Gurari % -|<TeX4ht copyright|> +% french.4ht |version, generated from |jobname.tex +% Copyright |CopyYear.1999. Eitan M. Gurari +|<TeX4ht copywrite|> \expandafter\ifx \csname @s@ORI\endcsname \relax \else |<french 4ht|> \Configure{special}{\csname @s@ORI\endcsname} \fi +|<french part|> \Hinput{french} \endinput >>> \AddFile{7}{french} @@ -25956,6 +26076,13 @@ CTAN:language/mongolian/montex/examples \fi >>> +This should fix part commands in TOC. Bug report is +\Link[https://github.com/michal-h21/make4ht/issues/155]{}{}here\EndLink + +\<french part\><<< +\DeclareRobustCommand*{\FB@emptypart}{} +>>> + %%%%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Verbatim} %%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -26183,7 +26310,11 @@ See \Link[://github.com/michal-h21/make4ht/issues/141]{}{}this issue\EndLink. \ifx \fv:color\empty \else{% \let\HColor\fv:color \a:fancyvrbcolor% }\fi - \ifx \FancyVerbFillColor\relax \else% + \ifx \FancyVerbFillColor\relax \ifx\FancyVerbBackgroundColor\relax\else% + \ifdefined\FancyVerbBackgroundColor% this extra check is needed for \BVerbatimInput + \:fvcolor \b:fancyvrbcolor \color{\FancyVerbBackgroundColor}|<par del|>% + \fi% + \fi\else% \:fvcolor \b:fancyvrbcolor \FancyVerbFillColor|<par del|>% \fi \ifx \FancyVerbRuleColor\relax \else% @@ -26329,12 +26460,11 @@ of LaTeX. The \''\:gobbleII' is for getting rid of the \<minted.4ht\><<< % minted.4ht (|version), generated from |jobname.tex -% Copyright 2022 TeX Users Group +% Copyright 2022-2024 TeX Users Group |<TeX4ht license text|> |<minted inline fixes|> |<minted background color|> -|<minted background color|> |<minted input fixes|> \Hinput{minted} @@ -26369,9 +26499,18 @@ in the generated HTML. \HLet\minted@inline@iii\:tempa >>> +Minted 3.0 changed the way it works with the background color. +It now uses Fancyvrb, so the minted@colorbg environment is not used anymore. +We need to remove the redefinition, to prevent compilation error. +The MintedColorbg configuration can stay here, to prevent errors in +user config files that use it, but it doesn't have any effect. + \<minted background color\><<< % support for background color in Minted listings \NewConfigure{MintedColorbg}{2} +>>> + +\<minted background color not used\><<< \renewenvironment{minted@colorbg}[1]{% \colorlet{shadecolor}{#1}% \extractcolorspec{shadecolor}{\:tempa}% @@ -26452,10 +26591,12 @@ Minted, it turns the breaklines option to false when it is used. \<piton.4ht\><<< % piton.4ht (|version), generated from |jobname.tex -% Copyright 2023 TeX Users Group +% Copyright 2023-2024 TeX Users Group |<TeX4ht license text|> \ExplSyntaxOn +|<piton xcolor|> +|<piton spaces|> |<piton env|> |<piton inlines|> \ExplSyntaxOff @@ -26463,6 +26604,51 @@ Minted, it turns the breaklines option to false when it is used. \endinput >>> \AddFile{9}{piton} +If Xcolor is not loaded earlier, Piton loads it in the begindocument/before hook. +It leads to a compilation error caused by catcodes mismatch. We can prevent it +by loading Xcolor earlier. + +\<piton xcolor\><<< +\IfPackageLoadedTF{xcolor}{}{\RequirePackage{xcolor}} +>>> + +The current version of Piton started to show visible space character (U+2423) instead +of spaces even if they are not requested using the show-spaces option. This code should +prevent that. + +\<piton spaces\><<< +\def\:pitonvisiblespace{ \HCode{\string&\#x2423;} } +\cs_new_protected:Npn \:__piton_replace_spaces:n #1 + { + \tl_set:Nn \l_tmpa_tl { #1 } + \bool_if:NTF \l__piton_show_spaces_bool + { + \tl_set:Nn \l__piton_space_tl {\:pitonvisiblespace} % U+2423 + \regex_replace_all:nnN { \x20 } {\c{:pitonvisiblespace}} \l_tmpa_tl + } + { + \bool_if:NTF \l__piton_break_lines_in_Piton_bool + { + \regex_replace_all:nnN + { \x20 } + { \c { __piton_breakable_space: } } + \l_tmpa_tl + \regex_replace_all:nnN + { \c { l__piton_space_tl } } + { \c { __piton_breakable_space: } } + \l_tmpa_tl + } + { + \regex_replace_all:nnN { \x20 } { \x20 } \l_tmpa_tl + } + } + \l_tmpa_tl + } + + +\HLet\__piton_replace_spaces:n\:__piton_replace_spaces:n +>>> + \<piton env\><<< \NewConfigure{pitonline}{3} @@ -29223,6 +29409,21 @@ The same is true for array.sty. \endinput >>> \AddFile{7}{colortbl} + +\<add to usepackage\><<< +\Configure{PackageHooks}{colortbl.sty}{colortbl-hooks.4ht} +>>> + +\<colortbl-hooks.4ht\><<< +% colortbl-hooks.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +\:AtEndOfPackage{% +|<colortbl arrayrulecolor|> +} +>>> \AddFile{7}{colortbl-hooks} + + color.sty is obsoleted by xcolor, so we will load the latter package in order to get access to the color space conversion commands. @@ -29364,8 +29565,10 @@ need also a treatment similar to \''\CT@column@color'? >>> Fixes for colored hlines. The \`|\hline:color| can be used in CSS, for instance. +We need to use early hooks file, because this command can be used in the preamble, +and we want to catch the defined color. -\<fix colortbl\><<< +\<colortbl arrayrulecolor\><<< % default hline color is black \def\hline:color{000} % save rule color in format usable in CSS @@ -29376,14 +29579,10 @@ Fixes for colored hlines. The \`|\hline:color| can be used in CSS, for instance. \noalign{\convertcolorspec{#1}{#2}{HTML}\:tmp\global\let\hline:color\:tmp}% we are \fi } -\HLet\arrayrulecolor\tmp:arrayrulecolor ->>> - -\SubSection{Utilities} - -This should enable use of \`|\color| command in array declaration +% \HLet doesn't work in the preamble, so we need to work around it +\let\o:arrayrulecolor:\arrayrulecolor +\let\arrayrulecolor\tmp:arrayrulecolor -\<fix colortbl\><<< \def\convert:colorspec#1 #2 #3 #4{% \edef\current:color{% \ifx\relax#1\relax\else% @@ -29398,6 +29597,21 @@ This should enable use of \`|\color| command in array declaration }% } +>>> + +This version of arrayrulecolor will be used after preamble. +It supports pictures. + +\<fix colortbl\><<< +\HRestore\arrayrulecolor +\HLet\arrayrulecolor\tmp:arrayrulecolor +>>> + +\SubSection{Utilities} + +This should enable use of \`|\color| command in array declaration + +\<fix colortbl\><<< \def\save:color#1 #2//{% \convert:colorspec#2 {} {} {} {} \convertcolorspec{#1}{\current:color}{HTML}\tmp:col @@ -30147,6 +30361,173 @@ A style file for resumes. >>> %%%%%%%%%%%%%%%%%%%%%%%%% +\Section{moderncv} +%%%%%%%%%%%%%%%%%%%%%%%%% + +\<moderncv.4ht\><<< +% moderncv.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +|<moderncv configs|> +\Hinput{moderncv} +\endinput +>>>\AddFile{9}{moderncv} + +This is a bit messy. We had to redefine a bunch of commands from various +files that Moderncv uses, mostly to prevent compilation errors and to +insert some basic formatting. + +\<moderncv configs\><<< +\NewConfigure{section}{2} +\RenewDocumentCommand\section{sm}{\a:section #2\b:section} + +\NewConfigure{subsection}{2} +\RenewDocumentCommand\subsection{sm}{\a:subsection #2\b:subsection} + + +\NewConfigure{cvitem}{3} +\renewcommand*{\cvitem}[3][.25em]{ +\a:cvitem #2\b:cvitem #3\c:cvitem +} + +\NewConfigure{cvdoubleitem}{2} +\renewcommand*{\cvdoubleitem}[5][.25em]{% +\a:cvdoubleitem +\cvitem{#2}{#3} +\cvitem{#4}{#5} +\b:cvdoubleitem +} + +\NewConfigure{cvlistitem}{2} +\renewcommand*{\cvlistitem}[2][.25em]{% + \a:cvlistitem\cvitem[#1]{\listitemsymbol}{#2}\b:cvlistitem +} + +\NewConfigure{cvlistdoubleitem}{2} +\renewcommand*{\cvlistdoubleitem}[3][.25em]{% + \a:cvlistdoubleitem% + \cvitem[#1]{\listitemsymbol}{#2}% + \cvitem[#1]{\listitemsymbol}{#3}% + \b:cvlistdoubleitem% +} + +\NewConfigure{cvhead}{2} +\NewConfigure{cvphoto}{2} + + +\renewcommand*{\makecvhead}{% + \a:cvhead + % recompute lengths (in case we are switching from letter to resume, or vice versa) + \recomputecvlengths% + % optional detailed information (pre-rendering) + \@initializebox{\makecvheaddetailsbox}% + \if@details% + \def\phonesdetails{}% + \collectionloop{phones}{% the key holds the phone type (=symbol command prefix), the item holds the number + \protected@edef\phonesdetails{\phonesdetails\protect\makenewline\csname\collectionloopkey phonesymbol\endcsname\collectionloopitem}}% + \def\socialsdetails{}% + \collectionloop{socials}{% the key holds the social type (=symbol command prefix), the item holds the link + \protected@edef\socialsdetails{\socialsdetails\protect\makenewline\csname\collectionloopkey socialsymbol\endcsname\collectionloopitem}}% + \savebox{\makecvheaddetailsbox}{% + \addressfont\color{color2}% + \if@left\begin{tabular}[b]{@{}r@{}}\fi% + \if@right\begin{tabular}[b]{@{}l@{}}\fi% + \ifthenelse{\isundefined{\@addressstreet}}{}{\makenewline\addresssymbol\@addressstreet% + \ifthenelse{\equal{\@addresscity}{}}{}{\makenewline\@addresscity}% if \addresstreet is defined, \addresscity and addresscountry will always be defined but could be empty + \ifthenelse{\equal{\@addresscountry}{}}{}{\makenewline\@addresscountry}}% + \ifthenelse{\isundefined{\@born}}{}{\makenewline\bornsymbol\@born}% + \phonesdetails% needs to be pre-rendered as loops and tabulars seem to conflict + \ifthenelse{\isundefined{\@email}}{}{\makenewline\emailsymbol\emaillink{\@email}}% + \ifthenelse{\isundefined{\@homepage}}{}{\makenewline\homepagesymbol\httpslink{\@homepage}}% + \socialsdetails% needs to be pre-rendered as loops and tabulars seem to conflict + \ifthenelse{\isundefined{\@extrainfo}}{}{\makenewline\@extrainfo}% + \end{tabular} + }\fi% + % optional photo (pre-rendering) + \@initializebox{\makecvheadpicturebox}% + \savebox{\makecvheadpicturebox}{% + \ifthenelse{\isundefined{\@photo}}% + {}% + {% + \a:cvphoto\includegraphics[]{\@photo}\b:cvphoto}% + }% + % name and title (pre-rendering) + \@initializelength{\makecvheaddetailswidth}\settowidth{\makecvheaddetailswidth}{\usebox{\makecvheaddetailsbox}}% + \@initializelength{\makecvheadpicturewidth}\settowidth{\makecvheadpicturewidth}{\usebox{\makecvheadpicturebox}}% + \ifthenelse{\lengthtest{\makecvheadnamewidth=0pt}}% check for dummy value (equivalent to \ifdim\makecvheadnamewidth=0pt) + {\setlength{\makecvheadnamewidth}{\textwidth-\makecvheaddetailswidth-\makecvheadpicturewidth}}% + {}% + \@initializebox{\makecvheadnamebox}% + \savebox{\makecvheadnamebox}{% + \begin{minipage}[b]{\makecvheadnamewidth}% + \if@left\raggedright\fi% + \if@right\raggedleft\fi% + \namestyle{\@firstname\ \@lastname}% + \ifthenelse{\equal{\@title}{}}{}{\\[1.25em]\titlestyle{\@title}}% + \end{minipage}}% + % rendering + \if@left% + \usebox{\makecvheadnamebox}% + \hfill% + \llap{\usebox{\makecvheaddetailsbox}}% \llap is used to suppress the width of the box, allowing overlap if the value of makecvheadnamewidth is forced + \usebox{\makecvheadpicturebox}\fi% + \if@right% + \usebox{\makecvheadpicturebox}% + \rlap{\usebox{\makecvheaddetailsbox}}% \llap is used to suppress the width of the box, allowing overlap if the value of makecvheadnamewidth is forced + \hfill% + \usebox{\makecvheadnamebox}\fi% + \\[2.5em]% + % optional quote + \ifthenelse{\isundefined{\@quote}}% + {}% + {{\centering\begin{minipage}{\quotewidth}\centering\quotestyle{\@quote}\end{minipage}\\[2.5em]}}% + \b:cvhead\par}% to avoid weird spacing bug at the first section if no blank line is left after \makecvhead + + +\RenewDocumentCommand\cvskilllegend{s +O{.25em} +O{\skillLegend@defaultLevelOne} +O{\skillLegend@defaultLevelTwo} +O{\skillLegend@defaultLevelThree} +O{\skillLegend@defaultLevelFour} +O{\skillLegend@defaultLevelFive} +m}{% +\begin{tabular}{l l l l l l} + \raggedleft\hintstyle{#8} & \cvskill{1}\, & \,{\skillLegend@FontSize #3} & \cvskill{3}\, &\,{\skillLegend@FontSize #5 } \\% + % + & \cvskill{2}\, & \,\multirow{2}{\cvskilllegend@leftdescriptorwidth}{{\skillLegend@FontSize #4}} & \cvskill{4}\, &\,{\skillLegend@FontSize #6 } \\% + % + & & & \cvskill{5}\, &\,{\skillLegend@FontSize #7 }% + \end{tabular}% +}% + + +\NewConfigure{cvskill}{2} +\def\:tempa#1{\def\:cvskillamount{#1}\a:cvskill\o:cvskill:{#1}\b:cvskill} +\HLet\cvskill\:tempa + +\NewConfigure{cvskillhead}{2} +\NewConfigure{cvskillentry}{2} +\RenewDocumentCommand\cvskillhead{O{.25em} +O{\skillMatrix@HeaderDefaultOne} +O{\skillMatrix@HeaderDefaultTwo} +O{\skillMatrix@HeaderDefaultThree} +O{\skillMatrix@HeaderDefaultFour}}{% + \begingroup + \a:cvskillhead + \begin{tabular}{ p{6em} p{12em} p{4em} p{20em}}% + { #2} & { #3} & { #4} & { #5} + \end{tabular}% + \b:cvskillhead + \endgroup + \par\addvspace{#1} +} + +\RenewDocumentCommand\cvskillentry{s +O{.25em} +m +m +m +m +m}{% +\a:cvskillentry +\cvitem{#3}{ + \begin{tabular}{ p{6em} p{12em} p{4em} p{20em}} + \centering \cvskill{#4} &\centering {#5} & \centering {#6} &{\itshape#7}% + \end{tabular}}% + \b:cvskillentry + \par\addvspace{#2} +} + +>>> + +%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Small Ones} %%%%%%%%%%%%%%%%%%%%%%%%% @@ -30173,6 +30554,7 @@ A style file for resumes. % Copyright |CopyYear.2009. Eitan M. Gurari |<TeX4ht copywrite|> |<enumitem config|> +|<enumitem newlist|> \Hinput{enumitem} \endinput >>> \AddFile{9}{enumitem} @@ -30207,6 +30589,61 @@ See \Link[https://github.com/hendricius/the-sourdough-framework/pull/312]{}{}for \def\enit@postlabel{} >>> +We need to provide a configuration for environments defined using \Verb+\newlist+. +Because they are defined in the preamble, we must catch them using the early hooks +file. + +The test file and report can be found \Link[https://github.com/michal-h21/make4ht/issues/150]{}{}here\EndLink. + + +\<add to usepackage\><<< +\Configure{PackageHooks}{enumitem.sty}{enumitem-hooks.4ht} +>>> + +\<enumitem-hooks.4ht\><<< +% enumitem-hooks.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +\:AtEndOfPackage{% +|<enumitem patch newlist|> +} +>>> \AddFile{9}{enumitem-hooks} + + +We save all defined environments in \Verb+\enumitem:newlist+. This command +is then called in the \Verb+\Configure{enumitemnewlist}+, which can +be used in the output format configuration. + +\<enumitem patch newlist\><<< +\def\enumitem:newlist{} +\def\:tempa#1#2#3#4{\concat:config\enumitem:newlist{\Configure{enumitemenv}{#2}}\o:enit@newlist{#1}{#2}{#3}{#4}} +\let\o:enit@newlist\enit@newlist +\let\enit@newlist\:tempa +>>> + + +This configuration is called automatically by \Verb+\Configure{enumitenewlist}+ for each +declared environment. The environment name is saved in \Verb+\a:enumitemenv+, +and then we call \Verb+\enumitem:newlist+, which should provide a configuration for lists +in the current output format. + +\<enumitem newlist\><<< +\NewConfigure{enumitemenv}[1]{% +\def\a:enumitemenv{#1}% +\enumitem:newlistconfig +} +>>> + +This configuration should provide a configuration for a list in the current output format. +Name of the configured environment is saved in \Verb+\a:enumitemenv+. + +\<enumitem newlist\><<< +\NewConfigure{enumitemnewlist}[1]{ + \def\enumitem:newlistconfig{#1} + \enumitem:newlist +} +>>> + %%%%%%%%%%%%% \Section{esperanto.sty} @@ -31410,6 +31847,25 @@ for output formats. \ExplSyntaxOff >>> +%%%%%%%%%%%%%%% +\Section{Esvect} +%%%%%%%%%%%%%%% + +\<esvect.4ht\><<< +% esvect.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +|<esvect redefinitions|> + +\Hinput{esvect} +\endinput +>>> \AddFile{9}{esvect} + + +\<esvect redefinitions\><<< +>>> + + %%%%%%%%%%%%% \Section{Ushort} %%%%%%%%%%%%% @@ -34973,6 +35429,21 @@ but fatal error is a worse possibility. \Configure{nicefrac}{}{/}{} >>> + +%%%%%%%%%%%%%%%%%%%%%%%% +\Section{stmaryrd} +%%%%%%%%%%%%%%%%%%%%%%%% + +\<stmaryrd.4ht\><<< +% stmaryrd.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> + + +\Hinput{stmaryrd} +\endinput +>>> \AddFile{9}{stmaryrd} + \Section{fontmath.ltx} \<config fontmath.ltx utilities\><<< @@ -36872,25 +37343,25 @@ is not a font). \<non-html TeX4ht divs\><<< \def\TagCh#1{\Tag{#1|<Ch tag|>}{\theChapterCounter}} -\def\RefCh#1{Chapter\ \Ref{#1|<Ch tag|>}} +\def\RefCh#1{Chapter\ \XRef{#1|<Ch tag|>}} \def\TagApp#1{\Tag{#1|<Ap tag|>}{\theChapterCounter}} -\def\RefApp#1{Appendix\ \Ref{#1|<Ap tag|>}} +\def\RefApp#1{Appendix\ \XRef{#1|<Ap tag|>}} \def\TagSec#1{\Tag{#1|<Sec tag|>}{\theSectionCounter}} -\def\RefSec#1{Section\ \Ref{#1|<Sec tag|>}} +\def\RefSec#1{Section\ \XRef{#1|<Sec tag|>}} >>> \<html TeX4ht divs\><<< \def\TagCh#1{\Tag{#1|<Ch tag|>}{\theChapterCounter}\Tag {#1|<hCh tag|>}{\:curch}} -\def\RefCh#1{\Link{\LikeRef{#1|<hCh tag|>}}{}Chapter\ \Ref +\def\RefCh#1{\Link{\LikeRef{#1|<hCh tag|>}}{}Chapter\ \XRef {#1|<Ch tag|>}\EndLink} \def\TagApp#1{\Tag{#1|<Ap tag|>}{\theChapterCounter}\Tag {#1|<hAp tag|>}{\:curch}} -\def\RefApp#1{\Link{\LikeRef{#1|<hAp tag|>}}{}Appendix\ \Ref +\def\RefApp#1{\Link{\LikeRef{#1|<hAp tag|>}}{}Appendix\ \XRef {#1|<Ap tag|>}\EndLink} \def\TagSec#1{\Tag{#1|<Sec tag|>}{\theSectionCounter}\Tag {#1|<hSec tag|>}{\:cursec}} -\def\RefSec#1{\Link{\LikeRef{#1|<hSec tag|>}}{}Section\ \Ref +\def\RefSec#1{\Link{\LikeRef{#1|<hSec tag|>}}{}Section\ \XRef {#1|<Sec tag|>}\EndLink} >>> @@ -36902,12 +37373,12 @@ is not a font). \<html TeX4ht divs\><<< \def\TagPage#1{% \Link{}{page#1}\EndLink\Tag{#1}{}} -\def\RefPage#1{\Link{page#1}{}\Ref{#1}\EndLink} +\def\RefPage#1{\Link{page#1}{}\XRef{#1}\EndLink} >>> \<non-html TeX4ht divs\><<< \def\TagPage#1{\Tag{#1}{}} -\def\RefPage{\Ref} +\def\RefPage{\XRef} >>> %\SubSection{Standard} @@ -38018,6 +38489,98 @@ instead. \HLet\@mn@@@marginnote\:tempa >>> +%%%%%%%%%%%%%%%%%%%%%%%% +\Section{manyfoot} +%%%%%%%%%%%%%%%%%%%%%%%% + +\<manyfoot.4ht\><<< +% manyfoot.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> + + +\Hinput{manyfoot} +\endinput +>>> \AddFile{9}{manyfoot} + + +\<add to usepackage\><<< +\Configure{PackageHooks}{manyfoot.sty}{manyfoot-hooks.4ht} +>>> + +\<manyfoot-hooks.4ht\><<< +% manyfoot-hooks.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> + +\:AtEndOfPackage{% +|<declare manyfoot footnote|> +} + +\endinput +>>> \AddFile{9}{manyfoot-hooks} + +The Manyfoot package provides the \''\DeclareNewFootnote' command to +declare new footnote types. The following code catches these new +commands, and redefines them to produce normal footnotes, just with +changed footnote mark. + +See \Link[https://tex.stackexchange.com/a/729975/2891]{}{} this answer\EndLink +for an example. + +\<declare manyfoot footnote\><<< +\let\o:MFL@declare:\MFL@declare +\def\manyfoot:declarefn#1{% + \expandafter\renewcommand\csname footnote#1\endcsname[1]{% + \stepcounter{footnote#1}% + \renewcommand\thefootnote{\csname thefootnote#1\endcsname}% + \footnote{##1}% + }% +} +\def\MFL@declare#1#2[#3]{% + \o:MFL@declare:{#1}{#2}[#3]% + \manyfoot:declarefn{#2}% +}% + +>>> + +%%%%%%%%%%%%%%%%%%%%%%%% +\Section{bigfoot} +%%%%%%%%%%%%%%%%%%%%%%%% + +\<bigfoot.4ht\><<< +% bigfoot.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> + + +\Hinput{bigfoot} +\endinput +>>> \AddFile{9}{bigfoot} + +\<add to usepackage\><<< +\Configure{PackageHooks}{bigfoot.sty}{bigfoot-hooks.4ht} +>>> + +The Bigfoot package redefines the output routine in a way which +crashes TeX4ht. It basically just loads the Manyfoot package and +then redefines its commands. As the changes are mostly just in +how the notes are displayed on the page, which doesn't matter +with TeX4ht, I think we can safely block the package from loading +and just use the Manyfoot package directly. + +One feature that doesn't work though is nested footnotes. I may look +into this issue in the future. + +\<bigfoot-hooks.4ht\><<< +% bigfoot-hooks.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +\:dontusepackage{bigfoot} +\RequirePackage{manyfoot} +\endinput +>>> \AddFile{9}{bigfoot-hooks} + %%%%%%%%%%%%%%% \Section{Other} %%%%%%%%%%%%%%%%% @@ -38784,6 +39347,95 @@ Type 6 is for punctuation (\''\mathpunc', in LaTeX), and type 7 is \NewConfigure{textul}{2} >>> +%%%%%%%%%%%%%%%%%%%%% +\Section{Lua-ul} +%%%%%%%%%%%%%%%%%%%%% + +\<lua-ul.4ht\><<< +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% lua-ul.4ht (|version), generated from |jobname.tex +% Copyright 2024 TeX Users Group +|<TeX4ht license text|> +|<lua-ul getxcolor|> +\ExplSyntaxOn +|<lua-ul hooks|> +\ExplSyntaxOff +\Hinput{lua-ul} +\endinput +>>> \AddFile{9}{lua-ul} + +If Xcolor is not loaded explicitly in the document, the \Verb+\get:xcolorcss+ command +is not available. We want to be able to save colors of underlines etc, so we need +to provide a variant that will work regardless of Xcolor\dots + +\<lua-ul getxcolor\><<< +\def\lua:ul:get:xcolorcss#1#2{% + \expandafter\extractcolorspec\expandafter{#1}{\tsf:color}% + \expandafter\convertcolorspec\tsf:color{HTML}\tsf:color% + \edef#2{\#\tsf:color}% +} +>>> + +\<lua-ul hooks\><<< + +\NewConfigure{highLight}{2} +\NewDocumentCommand \:highLight {O{\l__luaul_highlight_color_tl} +m} { + \group_begin: + \lua:ul:get:xcolorcss{#1}\:highLightColor% + \a:highLight#2\b:highLight% + \group_end: +} + +\HLet\highLight\:highLight + +\NewConfigure{strikeThrough}{2} +\NewDocumentCommand \:strikeThrough {o +m} { + \group_begin: + \IfValueTF {#1} { + \lua:ul:get:xcolorcss{#1}\:strikeThroughColor% + }{\def\:strikeThroughColor{inherit}} + \a:strikeThrough#2\b:strikeThrough + \group_end: + } + +\HLet\strikeThrough\:strikeThrough + +\NewConfigure{underLine}{2} +\NewDocumentCommand \:underLine {o +m} { + \group_begin: + \IfValueTF {#1} { + \__luaul_parse_generic_keys:n { + #1 + } + }{} + \bool_if:NTF \l__luaul_color_set_bool { + % the \l__luaul_current_color_tl contains color in a format suitable for \convertcolorspec, + % so we cannot use \lua:ul:get:xcolorcss here + \expandafter\convertcolorspec\l__luaul_current_color_tl{HTML}\:tempa + \edef\:underLineColor{\#\:tempa}% + }{\def\:underLineColor{inherit}} + \a:underLine#2\b:underLine + \group_end: +} + +\HLet\underLine\:underLine + + +>>> + +Lua-ul can emulate commands defined by Soul, in that case we need to use our +redefinitions of Lua-ul commands. + +\<lua-ul hooks\><<< +\bool_if:NT \l__luaul_soulnames_bool { + \cs_set_eq:NN \textul \underLine \cs_set_eq:NN \ul \textul + \cs_set_eq:NN \textst \strikeThrough \cs_set_eq:NN \st \textst + \cs_set_eq:NN \texthl \highLight \cs_set_eq:NN \hl \texthl +} +>>> + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Underline and Overline} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/support/TeX4ht/source/tex4ht-fonts-noncjk.tex b/support/TeX4ht/source/tex4ht-fonts-noncjk.tex index 0e22004638..91e506635d 100644 --- a/support/TeX4ht/source/tex4ht-fonts-noncjk.tex +++ b/support/TeX4ht/source/tex4ht-fonts-noncjk.tex @@ -1,8 +1,8 @@ -% $Id: tex4ht-fonts-noncjk.tex 1541 2024-07-31 10:01:14Z michal_h21 $ +% $Id: tex4ht-fonts-noncjk.tex 1551 2024-09-03 22:26:09Z karl $ % tex tex4ht-fonts-noncjk % or ht tex tex4ht-fonts-noncjk % -% Copyright 2009-2023 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright 1997-2009 Eitan M. Gurari % Released under LPPL 1.3c+. % See tex4ht-cpright.tex for license text. @@ -24490,62 +24490,161 @@ Font file for the Esvect package. % writing vect10.htf hash: d9018d0b41b7639bd8c3bf0419c3b8a5 \<vect10\><<< vect10 0 47 -'`' '' grave 0 % generated from vect10.tfm, 2024-07-31-11:51 -'´' '' acute 1 % Copyright 2024 TeX Users Group -'ˆ' '' circumflex 2 % -'˜' '' tilde 3 % This work may be distributed and/or modified under the -'¨' '' dieresis 4 % conditions of the LaTeX Project Public License, either -'˝' '' hungarumlaut 5 % version 1.3c of this license or (at your option) any -'˚' '' ring 6 % later version. The latest version of this license is in -'ˇ' '' caron 7 % http://www.latex-project.org/lppl.txt -'˘' '' breve 8 % and version 1.3c or later is part of all distributions -'' '' % of LaTeX version 2005/12/01 or later. -'' '' % -'' '' % This work has the LPPL maintenance status "maintained". -'' '' % -'' '' % The Current Maintainer of this work -'' '' % is the TeX4ht Project <http://tug.org/tex4ht>. -'' '' % -'“' '' quotedblleft 16 % If you modify this program, changing the -'”' '' quotedblright 17 % version identification would be appreciated. -'„' '' quotedblbase 18 -'«' '' guillemotleft 19 -'»' '' guillemotright 20 -'–' '' endash 21 -'—' '' emdash 22 -'‌' '' cwm 23 -'‰' '' perthousand 24 -'' '' -'' '' -'' '' -'' '' -'' '' -'' '' -'' '' -' ' '' space 32 -'!' '' exclam 33 -'"' '' quotedbl 34 -'#' '' numbersign 35 -'$' '' dollar 36 -'%' '' percent 37 -'&' '' ampersand 38 -'’' '' quoteright 39 -'(' '' parenleft 40 -')' '' parenright 41 -'*' '' asterisk 42 -'+' '' plus 43 -',' '' comma 44 -'-' '' hyphen 45 -'.' '' period 46 -'/' '' slash 47 +'→' '' 0000 0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +'→' '' 0001 1 %% vect.htf (unicode) % +'→' '' 0002 2 %% generated from vect10.tfm, 2024-07-31-11:51 % +'→' '' 0003 3 %% Copyright 2024 TeX Users Group, Arkady Benediktov % +'→' '' 0004 4 %% % +'→' '' 0005 5 %% This work may be distributed and/or modified under the % +'→' '' 0006 6 %% conditions of the LaTeX Project Public License, either % +'→' '' 0007 7 %% version 1.3c of this license or (at your option) any % +'→' '' 0008 8 %% later version. The latest version of this license is in % +'	' '' 0009 9 %% http://www.latex-project.org/lppl.txt % +'
' '' 000A 10 %% and version 1.3c or later is part of all distributions % +'' '' 000B 11 %% of LaTeX version 2005/12/01 or later. % +'' '' 000C 12 %% % +'
' '' 000D 13 %% This work has the LPPL maintenance status "maintained". % +'' '' 000E 14 %% % +'' '' 000F 15 %% The Current Maintainer of this work % +'→' '' 0010 16 %% is the TeX4ht Project <http://tug.org/tex4ht>. % +'→' '' 0011 17 %% % +'→' '' 0012 18 %% If you modify this program, changing the % +'→' '' 0013 19 % % version identification would be appreciated. % +'→' '' 0014 20 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +'→' '' 0015 21 +'→' '' 0016 22 +'→' '' 0017 23 +'→' '' 0018 24 +'' '' 0019 25 +'' '' 001A 26 +'' '' 001B 27 +'' '' 001C 28 +'' '' 001D 29 +'' '' 001E 30 +'' '' 001F 31 +'⎯' '' 0020 32 +'⎯' '' 0021 33 +'⎯' '' 0022 34 +'⎯' '' 0023 35 +'⎯' '' 0024 36 +'⎯' '' 0025 37 +'⎯' '' 0026 38 +'⎯' '' 0027 39 +'⎯' '' 0028 40 +'⎯' '' 0029 41 +'⎯' '' 002A 42 +'⎯' '' 002B 43 +'⎯' '' 002C 44 +'⎯' '' 002D 45 +'⎯' '' 002E 46 +'⎯' '' 002F 47 vect10 0 47 -htfcss: vect10 font-family: 'TeXvect10', serif; + >>> \AddFont{vect10}{unicode/TeXvect10/vect10}{} - - +\<vect\><<< +.vect10 +htfcss: vect10 font-family: 'TeXvect10', serif; +htfcss: vect5 font-family: 'TeXvect10', serif; +>>> + +\AddFont{vect}{unicode/TeXvect10/vect}{} + + + +\Section{BBM} + +\<bbm\><<< +bbm 8 90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +'⦅' '' 8 %% bbm.htf (unicode) % +'⦆' '' 9 %% generated from bbm.tfm, 2024-09-03 % +'' '1' 10 %% Copyright 2024 TeX Users Group, Arkady Benediktov % +'' '1' 11 %% % +'' '1' 12 %% This work may be distributed and/or modified under the % +'' '1' 13 %% conditions of the LaTeX Project Public License, either % +'' '1' 14 %% version 1.3c of this license or (at your option) any % +'' '1' 15 %% later version. The latest version of this license is in % +'' '1' 16 %% http://www.latex-project.org/lppl.txt % +'𝟙' '' 17 %% and version 1.3c or later is part of all distributions % +'𝟚' '' 18 %% of LaTeX version 2005/12/01 or later. % +'' '1' 19 %% % +'' '1' 20 %% This work has the LPPL maintenance status "maintained". % +'' '1' 21 %% % +'' '1' 22 %% The Current Maintainer of this work % +'' '1' 23 %% is the TeX4ht Project <http://tug.org/tex4ht>. % +'' '1' 24 %% % +'' '1' 25 %% If you modify this program, changing the % +'' '1' 26 % % version identification would be appreciated. % +'' '1' 27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +'' '1' 28 +'' '1' 29 +'' '1' 30 +'' '1' 31 +'' '1' 32 +'𝔸' '' 33 +'𝔹' '' 34 +'ℂ' '' 35 +'𝔻' '' 36 +'𝔼' '' 37 +'𝔽' '' 38 +'𝔾' '' 39 +'ℍ' '' 40 +'𝕀' '' 41 +'𝕁' '' 42 +'𝕂' '' 43 +'𝕃' '' 44 +'𝕄' '' 45 +'ℕ' '' 46 +'𝕆' '' 47 +'ℙ' '' 48 +'ℚ' '' 49 +'ℝ' '' 50 +'𝕊' '' 51 +'𝕋' '' 52 +'𝕌' '' 53 +'𝕍' '' 54 +'𝕎' '' 55 +'𝕏' '' 56 +'𝕐' '' 57 +'ℤ' '' 58 +'⟦' '' 59 +'' '1' 60 +'⟧' '' 61 +'' '1' 62 +'' '1' 63 +'' '1' 64 +'𝕒' '' 65 +'𝕓' '' 66 +'𝕔' '' 67 +'𝕕' '' 68 +'𝕖' '' 69 +'𝕗' '' 70 +'𝕘' '' 71 +'𝕙' '' 72 +'𝕚' '' 73 +'𝕛' '' 74 +'𝕜' '' 75 +'𝕝' '' 76 +'𝕞' '' 77 +'𝕟' '' 78 +'𝕠' '' 79 +'𝕡' '' 80 +'𝕢' '' 81 +'𝕣' '' 82 +'𝕤' '' 83 +'𝕥' '' 84 +'𝕦' '' 85 +'𝕧' '' 86 +'𝕨' '' 87 +'𝕩' '' 88 +'𝕪' '' 89 +'𝕫' '' 90 +bbm 8 90 +>>> + +\AddFont{bbm}{unicode/bbm/bbm}{} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/support/TeX4ht/source/tex4ht-html4.tex b/support/TeX4ht/source/tex4ht-html4.tex index 13bf280c88..012883e471 100644 --- a/support/TeX4ht/source/tex4ht-html4.tex +++ b/support/TeX4ht/source/tex4ht-html4.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-html4.tex 1537 2024-07-06 19:48:42Z michal_h21 $ +% $Id: tex4ht-html4.tex 1591 2024-10-29 13:48:36Z michal_h21 $ % Compile 4 times: latex tex4ht-html4 % Copy html4.4ht into the work directory before all but the last compilation. % @@ -73,7 +73,7 @@ \<html4-math\><<< % html4-math.4ht (|version), generated from |jobname.tex -% Copyright 2009-2023 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright |CopyYear.1999. Eitan M. Gurari |<TeX4ht copywrite|> >>> @@ -5996,7 +5996,7 @@ thanks author date and>>> \<tug boat maketitle\><<< \@ifclassloaded{ltugproc}{}{% - \@ifpackageloaded{ltugproc}{}{\Configure{@BODY}{\rtitlex}} + \@ifpackageloaded{ltugproc}{}{\Configure{@BODY}{\@ifundefined{:rtitlexused}{\rtitlex}{}\def\:rtitlexused{}}} } \Configure{maketitle} {\ifvmode \IgnorePar\fi \EndP @@ -7661,7 +7661,7 @@ consecutive \verb+<br />+ tags. {} {\xdef\col:Css{\col:Css border-\ifnum \ar:cnt=0 left\else right\fi - :solid black 0.4pt;}% + :1px solid \VBorder:color;}% }{}{}% } {\ifx \col:Css\empty \else @@ -7809,6 +7809,7 @@ Currently, we either have empty \verb'\VBorder', or one defined to \<html latex array/tabular Config 4.0t\><<< \let\VBorder|=\empty \let\AllColMargins|=\empty +\def\VBorder:color{black} \Configure{VBorder} {\let\VBorder|=\empty \let\AllColMargins|=\empty \global\let\GROUPS|=\empty \HAssign\NewGroup = 0 @@ -7818,10 +7819,10 @@ Currently, we either have empty \verb'\VBorder', or one defined to % put vertical border for a column \ifnum\ar:cnt > 0% % in all other cases, we should put right border - \Css{\#TBL-\TableNo-\ar:cnt {border-right:1px solid black;}}% + \Css{\#TBL-\TableNo-\ar:cnt {border-right:1px solid \VBorder:color;}}% \else% % columns are numbered from 1. if \ar:cnt == 0 then it is the left border - \Css{\#TBL-\TableNo-1{border-left: 1px solid black;}}% + \Css{\#TBL-\TableNo-1{border-left: 1px solid \VBorder:color;}}% \fi% } {\Advance:\NewGroup by 1 @@ -7832,8 +7833,8 @@ Currently, we either have empty \verb'\VBorder', or one defined to {\xdef\AllColMargins{\AllColMargins 0}} \Configure{HBorder} {<tr\Hnewline class="hline">} {<td><hr\xml:empty></td>} {</tr>} - {<tr\Hnewline class="cline">} - {<td></td>} {<td><hr\xml:empty></td>} {</tr>} + {<tr\Hnewline class="cline">} + {<td></td>} {<td style="border-top:1px solid \#\hline:color;"></td>} {</tr>} {<tr\Hnewline class="vspace" style="font-size:\HBorderspace">} {<td\Hnewline>\string </td>} {</tr>} @@ -7844,7 +7845,8 @@ Currently, we either have empty \verb'\VBorder', or one defined to \Css{.hline hr, .cline hr{border:none;border-top:1px solid black;}} \Css{.hline {border-top: 1px solid black;}} \Css{.hline + .vspace:last-child{display:none;}} -\Css{.hline:first-child{border-bottom:1px solid black;border-top:none;}} +% why was there this rule? it adds unnecessary extra rule at the top of tables +% \Css{.hline:first-child{border-bottom:1px solid black;border-top:none;}} >>> When \verb'\putVBorder' is call in \verb'\VBorder' @@ -8790,16 +8792,22 @@ The hbox is for avoiding the start of a new paragraph, if in vmode. }; } \fi +\NewConfigure{MathjaxInline}{2} +\NewConfigure{MathjaxBlock}{2} +\Configure{MathjaxInline}{\HCode{<span class="mathjax-inline">}}{\HCode{</span>}} +\Configure{MathjaxBlock}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="mathjax-block">}}{\HCode{</div>}} +\Configure{MathjaxEnv}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="mathjax-env mathjax-\@currenvir">}}{\HCode{</div>}} + \Configure{@HEAD}{\HCode{<script>window.MathJax = \a:MathJaxConfig</script>\Hnewline}} \Configure{MathjaxSource}{https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js} -\Configure{@HEAD}{\HCode{ <script type="text/javascript" async="async" id="MathJax-script" src="\a:MathjaxSource"></script> \Hnewline}} +\Configure{@HEAD}{\ifx\a:MathjaxSource\@empty\else\HCode{<script type="text/javascript" async="async" id="MathJax-script" src="\a:MathjaxSource"></script> \Hnewline}\fi} \edef\:RestoreMathjaxCatcodes{\catcode`\noexpand \&=\the\catcode`\&} \def\:HandleMathjaxCatcodes{\edef\:RestoreMathjaxCatcodes{\catcode`\noexpand \&=\the\catcode`\&}\catcode`\&=11} -\Configure{$}{\:HandleMathjaxCatcodes}{\:RestoreMathjaxCatcodes}{\expandafter\AltMathOne} -\Configure{$$}{\:HandleMathjaxCatcodes}{\:RestoreMathjaxCatcodes}{\expandafter\AltlDisplayDollars} -% for some reason, it is necessary to specify the catcode change directly in the configuration -\Configure{()}{\:HandleMathjaxCatcodes\catcode`\&=11\AltlMath}{\:RestoreMathjaxCatcodes} -\Configure{[]}{\:HandleMathjaxCatcodes\catcode`\&=11\AltlDisplay}{\:RestoreMathjaxCatcodes} +\Configure{$}{\a:MathjaxInline\:HandleMathjaxCatcodes}{\:RestoreMathjaxCatcodes\b:MathjaxInline}{\expandafter\AltMathOne} +\Configure{()}{\a:MathjaxInline\:HandleMathjaxCatcodes\catcode`\&=11\AltlMath}{\:RestoreMathjaxCatcodes\b:MathjaxInline} +\Configure{$$}{\a:MathjaxBlock\:HandleMathjaxCatcodes}{\:RestoreMathjaxCatcodes\b:MathjaxBlock}{\expandafter\AltlDisplayDollars} +\Configure{[]}{\a:MathjaxBlock\:HandleMathjaxCatcodes\catcode`\&=11\AltlDisplay}{\:RestoreMathjaxCatcodes\b:MathjaxBlock} + \fi >>> @@ -16472,6 +16480,9 @@ Blue = 1-minimum(1,Yellow *(1-Black)+Black) % redefine default table configuration and put the color rule \def\a:HBorder{<tr class="hline" style="border-top:1px solid \#\hline:color">} + +% use the hline color also for vertial lines +\def\VBorder:color{\#\hline:color} % don't display <hr> elements in colored \hline \Css{tr.hline td hr{display:none}} >>> @@ -16540,6 +16551,18 @@ Blue = 1-minimum(1,Yellow *(1-Black)+Black) >>> %%%%%%%%%%%%%%%% +\section{lua-ul} +%%%%%%%%%%%%%%%% + +\<configure html4 lua-ul\><<< +\Configure{highLight}{\HCode{<span class="highLight" style="background-color:\:highLightColor;">}}{\HCode{</span>}} +\Configure{strikeThrough}{\HCode{<span class="strikeThrough" style="text-decoration-color:\:strikeThroughColor;" >}}{\HCode{</span>}} +\Css{.strikeThrough{text-decoration: line-through;}} +\Configure{underLine}{\HCode{<span class="underLine" style="text-decoration-color:\:underLineColor;">}}{\HCode{</span>}} +\Css{.underLine{text-decoration: underline;}} +>>> + +%%%%%%%%%%%%%%%% \section{framed} \<configure html4 framed\><<< @@ -16846,9 +16869,26 @@ Blue = 1-minimum(1,Yellow *(1-Black)+Black) {\end:itm \global\def\end:itm{\EndP\Tg</dd>}\HCode{<dt class="enumerate-enumitem">}\bgroup \bf} {\egroup\EndP\HCode{</dt><dd\Hnewline class="enumerate-enumitem">}} + \Css{dl.enumerate-enumitem{display:grid; grid-template-columns: 3ch 1fr; align-items: top; row-gap:1ch;}} >>> +Configurations for new list environments. + +\<configure html4 enumitem\><<< +\Configure{enumitemnewlist}{% +\ConfigureList{\a:enumitemenv}% + {\EndP\HCode{<dl \a:LRdir class="enumerate-enumitem enumitem-\a:enumitemenv">}% + |<save end:itm|>\global\let\end:itm=\empty} + {|<recall end:itm|>\EndP\HCode{</dd></dl>}\ShowPar} + {\end:itm \global\def\end:itm{\EndP\Tg</dd>}\HCode{<dt + class="enumerate-enumitem enumitem-\a:enumitemenv">}\bgroup \bf} + {\egroup\EndP\HCode{</dt><dd\Hnewline class="enumerate-enumitem">}} +} + + +>>> + %%%%%%%%%%%%% \subsection{IEEEtran} @@ -17806,6 +17846,45 @@ Blue = 1-minimum(1,Yellow *(1-Black)+Black) >>> %%%%%%%%%%%%%%%%%% +\section{moderncv} +%%%%%%%%%%%%%%%%%% + +\<configure html4 moderncv\><<< +\Configure{cvhead}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvhead">}}{\ifvmode\IgnorePar\fi\EndP\HCode{</div>}} +\Configure{cvphoto}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvphoto">}}{\ifvmode\IgnorePar\fi\EndP\HCode{</div>}} + +\Configure{section}{\ifvmode\IgnorePar\fi\EndP\HCode{<h2>}}{\HCode{</h2>}} +\Configure{subsection}{\ifvmode\IgnorePar\fi\EndP\HCode{<h3>}}{\HCode{</h3>}} +\Configure{cvitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvitem"><span class="cvitemhead">}}{\HCode{</span><span class="cvitembody">}}{\HCode{</span></div>}} +\Configure{cvdoubleitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvdoubleitem">}}{\HCode{</div>}} +\Configure{cvlistitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvlistitem">}}{\HCode{</div>}} +\Configure{cvlistdoubleitem}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvlistdoubleitem">}}{\HCode{</div>}} + +\Configure{cvskillhead}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvskillhead">}}{\HCode{</div>}} +\Configure{cvskillentry}{\ifvmode\IgnorePar\fi\EndP\HCode{<div class="cvskillentry">}}{\HCode{</div>}} + +\Configure{cvskill}{\Picture*[skill level: \:cvskillamount]{}}{\EndPicture} + +\Css{.cvskillentry .tabular, .cvskillhead .tabular {margin:0pt;}} +\Css{.cvskillentry .tabular td:nth-child(1), .cvskillhead .tabular td:nth-child(1){width: 8ch}} +\Css{.cvskillentry .tabular td:nth-child(2), .cvskillhead .tabular td:nth-child(2){width: 12ch}} +\Css{.cvskillentry .tabular td:nth-child(3), .cvskillhead .tabular td:nth-child(3){width: 6ch}} +\Css{.cvskillentry .tabular td:nth-child(4), .cvskillhead .tabular td:nth-child(4){width: 54ch}} + +\Css{.cvitemhead{margin-right: 1em;}} + +\Css{ +@media (min-width:94ch) { +.cvitemhead{ + margin-left: -14ch; + width: 12ch; + float: left; + text-align: right; + } +}} +>>> + +%%%%%%%%%%%%%%%%%% \section{CSS} %%%%%%%%%%%%%%%%%% @@ -18355,6 +18434,19 @@ font-size:70\%; >>> +This should remove part number in French Babel, because +the number is a part of the partname. +\Link[https://github.com/michal-h21/make4ht/issues/155]{}{}Bug report\EndLink. + +\<configure html4 french\><<< +\Configure{part}{}{} + {\IgnorePar \EndP\HCode{<h1 class="partHead"\a:LRdir>}% + \HCode{<span class="titlemark">}\partname + \HCode{</span><br />}} + {\HCode{</h1>}\IgnoreIndent\par} +>>> + + \<configure html4 galician\><<< @@ -19902,9 +19994,10 @@ chess notation as an alt text. \<configure html4 ltugboat\><<< |<tug boat maketitle|> \Configure{titlex} - {\HCode{<div class="titlex">}} + {\ifvmode\IgnorePar\fi\EndP\HCode{<div class="titlex">}} {\HCode{</div>}} \Css{div.titlex p{margin-bottom:1em;}} +\Css{div.titlex {text-align: center;}} |<ltugboat congif|> >>> @@ -22869,7 +22962,9 @@ The \verb|\hline:color| macro is defined by TeX4ht configuration for colortbl.st We reuse it to support change of rule colors. It is initialized as black. \<booktabs default hline color\><<< +\ifdefined\hline:color\else \def\hline:color{000} +\fi >>> diff --git a/support/TeX4ht/source/tex4ht-info.tex b/support/TeX4ht/source/tex4ht-info.tex index 75c784f811..339cfaae87 100644 --- a/support/TeX4ht/source/tex4ht-info.tex +++ b/support/TeX4ht/source/tex4ht-info.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-info.tex 905 2021-04-18 15:30:06Z karl $ +% $Id: tex4ht-info.tex 1564 2024-09-29 14:56:20Z karl $ % Compile with the command `ht latex tex4ht-info' % or % compile 3 times: latex tex4ht-info @@ -33,7 +33,7 @@ \<info4ht\><<< % info4ht.4ht (|version), generated from |jobname.tex -% Copyright 2009-2021 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright |CopyYear.2000. Eitan M. Gurari % % This work may be distributed and/or modified under the @@ -654,15 +654,15 @@ Cross-Linking #1 label #2 content -\Ref.....................................1 +\XRef.....................................1 \LikeRef.................................1 #1 label - \Tag and \Ref are tex4ht.sty commands introduced cross-referencing + \Tag and \XRef are tex4ht.sty commands introduced cross-referencing content through .xref auxiliary files. - \LikeRef is a variant of \Ref which doesn't verify whether the + \LikeRef is a variant of \XRef which doesn't verify whether the labels exit. It is mainly used in \Link and \edef environments. \ifTag ..................................3 @@ -676,7 +676,7 @@ Cross-Linking Load the named xref-type file .xref optional--`.xref' is assume for a default - + optional-- asks \Ref and \LikeRef commands + + optional-- asks \XRef and \LikeRef commands to use expanded tags `filename::tag', instead of just `tag' [prefix] optional--asks just for tags starting with the specified prefix. @@ -688,7 +688,7 @@ Cross-Linking Example: % a.tex - \LoadRef-[to:]{b}{from:#1} \Ref{from:filename} + \LoadRef-[to:]{b}{from:#1} \XRef{from:filename} \LikeRef{from:filename} % b.tex diff --git a/support/TeX4ht/source/tex4ht-jats.tex b/support/TeX4ht/source/tex4ht-jats.tex index e54de5ad20..16182ba8f5 100644 --- a/support/TeX4ht/source/tex4ht-jats.tex +++ b/support/TeX4ht/source/tex4ht-jats.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-jats.tex 1473 2024-02-23 12:26:51Z michal_h21 $ +% $Id: tex4ht-jats.tex 1545 2024-08-13 19:02:54Z michal_h21 $ % compile 3 times: latex tex4ht-jats % or xhlatex tex4ht-jats "html,3,sections+" % @@ -201,6 +201,7 @@ Configurations that are shared only for article and report |<latex footnotes|> |<latex quotes|> |<latex lists|> +|<latex bibliography|> >>> \<shared article,report\><<< @@ -841,6 +842,29 @@ them separatelly. {\EndNoFonts\HCode{</term><def>}\HtmlParOn|<list par|>} >>> + +We cannot create a structured bibliographic record for plain LaTeX references, so we +at least mark individual entries. + +Entry id is set on the label element. The id comes from a child xref element that is removed +by make4ht. Ideally, it should be set on ref, but we need to use label here, to catch +potential entry number. + + +\<latex bibliography\><<< +\ConfigureList{thebibliography}% + {\ifvmode\IgnorePar\fi \EndP \HCode{<ref-list>}\let\en:bib=\empty} + {\en:bib \ifvmode\IgnorePar\fi \EndP \HCode{</ref-list>}} + {\en:bib\def\en:bib{\HCode{</mixed-citation></ref>}}% + \HCode{<ref><label>}% + \Configure{HtmlPar}% + {\EndP}% + {\EndP}% + {} {}% + } + {\HCode{</label><mixed-citation>}} +>>> + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Packages} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/support/TeX4ht/source/tex4ht-mathjax.tex b/support/TeX4ht/source/tex4ht-mathjax.tex index 25f324ab7f..0e96e2b270 100644 --- a/support/TeX4ht/source/tex4ht-mathjax.tex +++ b/support/TeX4ht/source/tex4ht-mathjax.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-mathjax.tex 1540 2024-07-28 17:10:17Z michal_h21 $ +% $Id: tex4ht-mathjax.tex 1589 2024-10-25 14:47:14Z michal_h21 $ % compile: latex tex4ht-mathjax % % Copyright 2018-2024 TeX Users Group @@ -54,24 +54,35 @@ The original code was this: % % replace \\:{ back to \\ { -- this can be introduced by the previous regex % \regex_replace_all:nnN { \x{5C} \x{5C} \x{3A} \x{7B} } { \x{5C} \x{5C} \x{20} \x{7B} } \l_tmpa_tl -Now (July 2024), when I researched another issue, I've found that it is actually possible to avoid these + +In July 2024, when I researched another issue, I've found that it is actually possible to avoid these extra spaces using LaTeX 3 commands. The inspiration comes from \Link[https://tex.stackexchange.com/a/44444/2891]this Bruno Le Foch\EndLink. One ongoing issue is that newlines are not presented. But they weren't preserved with \verb|\detokenize| either, so it shouldn't be a problem. +In September 2024 I found that the LaTeX 3 method of preserving spaces didn't work correctly for +code like this: \verb|$\int A f(x)\;dx$| -- the space between \verb|\int| and \verb|A| was removed, +so it ended like command \verb|\intA|. So we are moving back to \verb|\detokenize|. -We still use regular expressions to escape invalid XML characters to entities, so it works only with LaTeX. +This is the code that was promising, but didn't work in the end: -\<defined commands\><<< -\ExplSyntaxOn -\cs_new_protected:Npn \alteqtoks #1 -{ +\begin{verbatim} % save tokens, but preserve spaces % https://tex.stackexchange.com/a/44444/2891 \tl_set:Nn \l_tmpa_tl {#1} \regex_replace_all:nnN { . } { \c{string} \0 } \l_tmpa_tl \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl } +\end{verbatim} + + +We still use regular expressions to escape invalid XML characters to entities, so it works only with LaTeX. + +\<defined commands\><<< +\ExplSyntaxOn +\cs_new_protected:Npn \alteqtoks #1 +{ + \tl_set:Ne \l_tmpa_tl {\detokenize{#1}} % % replace < > and & with xml entities \regex_replace_all:nnN { \x{26} } { & } \l_tmpa_tl \regex_replace_all:nnN { \x{3C} } { < } \l_tmpa_tl @@ -120,10 +131,14 @@ environments. They will then keep the LaTeX code unchanged. % beginning of each display math \long\def\AltlDisplayDollars#1$${\alteqtoks{\[#1\]}$$} +\NewConfigure{MathjaxEnv}{2} + \newcommand\VerbMathToks[2]{% - \alteqtoks{\begin{#2} - #1 - \end{#2}}% + \a:MathjaxEnv% + \HCode{\string\begin{#2}}% + \alteqtoks{#1}% + \HCode{\string\end{#2}}% + \b:MathjaxEnv% } >>> @@ -294,7 +309,8 @@ inside TikZ etc. \<restore environments\><<< \@ifpackageloaded{tikz}{% -\tikzset{every picture/.append code={\:ignoretikzmatrix\RestoreMathJaxEnvironments}} +%\tikzset{every picture/.append code={\:ignoretikzmatrix\RestoreMathJaxEnvironments}} +\pend:def\tikz@installcommands{\RestoreMathJaxEnvironments} }{} >>> diff --git a/support/TeX4ht/source/tex4ht-mathml.tex b/support/TeX4ht/source/tex4ht-mathml.tex index e7f496d6bf..672530a27c 100644 --- a/support/TeX4ht/source/tex4ht-mathml.tex +++ b/support/TeX4ht/source/tex4ht-mathml.tex @@ -1,8 +1,8 @@ -% $Id: tex4ht-mathml.tex 1495 2024-03-21 16:39:31Z michal_h21 $$ +% $Id: tex4ht-mathml.tex 1580 2024-10-10 21:27:16Z michal_h21 $$ % compile 3 times: latex tex4ht-mathltx % or xhlatex tex4ht-mathltx "html,3,sections+" % -% Copyright 2009-2023 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright 1999-2009 Eitan M. Gurari % Released under LPPL 1.3c+. % See tex4ht-cpright.tex for license text. @@ -584,7 +584,7 @@ in italic and without space that would separate it from the following element. \<html-mml\><<< % html-mml.4ht (|version), generated from |jobname.tex -% Copyright 2009-2022 TeX Users Group +% Copyright 2009-2024 TeX Users Group % Copyright |CopyYear.1999. Eitan M. Gurari |<TeX4ht copywrite|> >>> @@ -1939,6 +1939,189 @@ primes. \fi >>> + +We may want to include LaTeX source as an annotation in MathML. In particular LaTeX PDF tagging code can use +this feature. We will not use it by default, but only with texsource option, as it can potentially +break some functionality. + +The code is based on the LaTeX MathJax code, but heavily modified. + +\<configure html-mml latex\><<< +\:CheckOption{texsource}\if:Option + +\newtoks\mmleqtoks +\ExplSyntaxOn +\cs_new_protected:Npn \mmlalteqtoks #1 +{ + % save tokens, but preserve spaces + % https://tex.stackexchange.com/a/44444/2891 + \tl_set:Nn \l_tmpa_tl {#1} + \regex_replace_all:nnN { . } { \c{string} \0 } \l_tmpa_tl + \tl_set:Nx \l_tmpa_tl { \l_tmpa_tl } + % % replace < > and & with xml entities + \regex_replace_all:nnN { \x{26} } { & } \l_tmpa_tl + \regex_replace_all:nnN { \x{3C} } { < } \l_tmpa_tl + \regex_replace_all:nnN { \x{3E} } { > } \l_tmpa_tl + % \regex_replace_all:nnN { \n } {\HCode{ \Hnewline }} \l_tmpa_tl + % replace \par command with blank lines + \regex_replace_all:nnN { \x{5C}par\b } {\x{A}\x{A}} \l_tmpa_tl + \tl_set:Nx \mmleqtoks{ \l_tmpa_tl } + + %\HCode{\l_tmpb_tl} +} +\ExplSyntaxOff + + +\def\AltMath#1${\mmlalteqtoks{#1}% + #1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}$} +\Configure{$}{\Configure{@math}{display="inline"}\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}}{\HCode{</\a:mathml semantics>}\EndDviMath}{\expandafter\AltMath} + +\def\AltMathParen#1\){\mmlalteqtoks{#1}% + #1\HCode{</\a:mathml mrow><a\a:mathml nnotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}$} + +\def\AltMathParen#1\){\mmlalteqtoks{#1}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}\)} +%\Configure{()}{\Configure{@math}{display="inline"}\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}\AltMathParen$}{\EndDviMath\HCode{</\a:mathml semantics>}} +\Configure{()} + {\Configure{@math}{%\a:mathml + display="inline" +}\csname a:mathml()\endcsname +\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}$\expandafter\AltMathParen} +{$\HCode{</\a:mathml semantics>}\EndDviMath\csname b:mathml()\endcsname} + + +\long\def\AltDisplay#1\]{\mmlalteqtoks{#1}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation></\a:mathml semantics>}\]} +\Configure{[]}{\Configure{@math}{display="block"}\DviMath$$\DisplayMathtrue\HCode{<\a:mathml semantics><\a:mathml mrow>}\AltDisplay}{$$\EndDviMath} + + +% \long\def\MMLAltlDisplayDollars#1$${\mmlalteqtoks{\[#1\]}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation>}$$} + +% configuarartion of display math doesn't work yet. need to investigate it. +% \Configure{$$} +% {\Configure{@math}{%\a:mathml +% display="block" +% }\IgnorePar +% \ifvmode\else \HCode{<!--tex4ht:inline-->}\fi +% \EndP\DviMath\HCode{<\a:mathml semantics><\a:mathml mrow>}} +% {\HCode{</\a:mathml semantics>}\EndDviMath\ShowPar\par{\csname HCondtrue\endcsname\noindent}} +% {\DisplayMathtrue\expandafter\MMLAltlDisplayDollars} + + +% \renewcommand\eqannotate[1]{\mmlalteqtoks{#1}\HCode{<\a:mathml semantics><\a:mathml mrow>}#1\HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">\mmleqtoks</\a:mathml annotation></\a:mathml semantics>}} + + +% environment support +\newcommand\MMLVerbMathToks[2]{% + \mmlalteqtoks{\begin{#2} + #1 + \end{#2}}% + \begingroup% + \ifvmode\IgnorePar\fi\EndP\Configure{@math}{display="block"}\DviMath\DisplayMathtrue\HCode{<\a:mathml semantics><\a:mathml mrow>} + \Configure{$$}{}{}{} + \begin{old#2} + #1 + \end{old#2} + \HCode{</\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">} + \HCode{\mmleqtoks} + \HCode{</\a:mathml annotation></\a:mathml semantics>} + \EndDviMath + \endgroup +} + +% we must handle equations separatelly. +% it is a bit messy +\newcommand\MMLVerbMathToksEquation[2]{% + \mmlalteqtoks{\begin{#2} + #1 + \end{#2}}% + \begingroup% + \def\@tempa{#2}% + \def\@equationname{equation}% + \def\mlabeledtr{mtr} + \ifx\@equationname\@tempa% + \def\mlabeledtr{mlabeledtr} % this element can be used to print the equation number, but it is supported only by MathJax + \fi + \ifvmode\IgnorePar\fi\EndP\Configure{@math}{display="block"}\DviMath\DisplayMathtrue\HCode{<\a:mathml semantics><\a:mathml mrow><\a:mathml mtable><\a:mathml \mlabeledtr><\a:mathml mtd>}% + \ifx\@equationname\@tempa% + \incr@eqnum% + \print@eqnum% + \HCode{</\a:mathml mtd><\a:mathml mtd>}% + \fi + #1% + \HCode{</\a:mathml mtd></\a:mathml \mlabeledtr></\a:mathml mtable></\a:mathml mrow><\a:mathml annotation encoding="application/x-tex">}% + \HCode{\mmleqtoks}% + \HCode{</\a:mathml annotation></\a:mathml semantics>}% + \EndDviMath% + \endgroup% +} + +\ExplSyntaxOn +\newcommand\MMLVerbMath[1]{% + \cs_if_exist:cTF{#1}{ + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname endold#1\expandafter\endcsname\csname end#1\endcsname + \RenewDocumentEnvironment{#1}{+!b}{% + \NoFonts\expandafter\MMLVerbMathToks\expandafter{##1}{#1}\EndNoFonts% + }{} + }{}% +} + +\newcommand\MMLVerbEquation[1]{% + \cs_if_exist:cTF{#1}{ + \expandafter\let\csname old#1\expandafter\endcsname\csname #1\endcsname + \expandafter\let\csname endold#1\expandafter\endcsname\csname end#1\endcsname + \RenewDocumentEnvironment{#1}{+!b}{% + \NoFonts\expandafter\MMLVerbMathToksEquation\expandafter{##1}{#1}\EndNoFonts% + }{} + }{}% +} +\ExplSyntaxOff + +% \MMLVerbEquation{equation} +% \MMLVerbEquation{equation*} + +\fi +>>> + +\<configure html-mml amsmath\><<< +\:CheckOption{texsource}\if:Option +\MMLVerbMath{subarray} +\MMLVerbMath{smallmatrix} +\MMLVerbMath{matrix} +\MMLVerbMath{pmatrix} +\MMLVerbMath{bmatrix} +\MMLVerbMath{Bmatrix} +\MMLVerbMath{vmatrix} +\MMLVerbMath{Vmatrix} +\MMLVerbMath{cases} +\MMLVerbMath{subequations} +\MMLVerbMath{aligned} +\MMLVerbMath{alignedat} +\MMLVerbMath{gathered} +\MMLVerbMath{gather} +\MMLVerbMath{gather*} +\MMLVerbMath{alignat} +\MMLVerbMath{alignat*} +\MMLVerbMath{xalignat} +\MMLVerbMath{xalignat*} +\MMLVerbMath{xxalignat} +\MMLVerbMath{align} +\MMLVerbMath{align*} +\MMLVerbMath{flalign} +\MMLVerbMath{flalign*} +\MMLVerbMath{split} +\MMLVerbMath{multline} +\MMLVerbMath{multline*} +% equations fails with errors, even though it worked in a .cfg +% I will need to investigate it more +% \MMLVerbEquation{equation} +% \MMLVerbEquation{equation*} +\MMLVerbMath{math} +\MMLVerbMath{displaymath} +\MMLVerbMath{eqnarray} +\MMLVerbMath{eqnarray*} +\fi +>>> + %%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{plain.sty} %%%%%%%%%%%%%%%%%%%%%%%%%% @@ -1971,7 +2154,7 @@ subformulas. Hence, the `'.' below is needed. \def\:temp#1{\a:right{#1}\o:right:.\b:right{#1}}\HLet\right|=\:temp \Configure{left} {} - {\HCode{<\a:mathml mrow><\a:mathml mo \a:mathml fence="true" \a:mathml form="prefix"> + {\HCode{<\a:mathml mrow><\a:mathml mo \a:mathml fence="true" \a:mathml form="prefix">% |<lr del 1|></\a:mathml mo>}\bgroup \HCode{<\a:mathml mrow>}\bgroup} \Configure{right} @@ -3584,14 +3767,19 @@ charactes. Extra brackets are used in order to support subscripts and superscripts. \<configure mathml latex\><<< -\def\:temp#1#2{\def#1{\PauseMathClass{\HCode{<mi mathvariant="normal">}\ht:special{t4ht@+\string&{35}x#2{59}}\a:HChar\HCode{</mi>}}\EndPauseMathClass}} -\:temp\Psi{03A8} +\def\:temp#1#2{\def\:tempa{\PauseMathClass{\HCode{<mi mathvariant="normal">}\ht:special{t4ht@+\string&{35}x#2{59}}\a:HChar\HCode{</mi>}}\EndPauseMathClass}\HLet#1\:tempa} +\:temp\Gamma{0393} \:temp\Delta{0394} +\:temp\Theta{0398} +\:temp\Lambda{039B} \:temp\Xi{039E} \:temp\Pi{03A0} \:temp\Sigma{03A3} \:temp\Upsilon{03A5} +\:temp\Phi{03A6} +\:temp\Psi{03A8} \:temp\Omega{03A9} + >>> @@ -5468,6 +5656,26 @@ latex.ltx, fontmath.ltx, plain.tex \fi} >>> +%%%%%%%%%%%%%% +\subsection{stmaryrd} +%%%%%%%%%%%%%% + + +\<configure mathml stmaryrd\><<< + +\def\:tempa{\HCode{<\a:mathml mo fence="false">\string&\#x27E6;</\a:mathml mo>}} +\HLet\llbracket\:tempa +\def\:tempa{\HCode{<\a:mathml mo fence="false">\string&\#x27E7;</\a:mathml mo>}} +\HLet\rrbracket\:tempa +>>> + +Fix for some commands used with \verb|\left| or \verb|\right|. + +\<configure mathml stmaryrd\><<< +\Configure{mfenced}{\llbracket}{\string&\#x27E6;} +\Configure{mfenced}{\rrbracket}{\string&\#x27E7;} +>>> + %%%%%%%%%%%%% \subsection{subeqnarray} @@ -5703,6 +5911,23 @@ elements that are printed to support the munderover element easily. >>> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{esvec} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +We need to redefine these commands only for MathML. By default, Esvect produces images, which is OK. + +\<configure mathml esvect\><<< +\def\:tempa#1{% +\bgroup\HCode{<\a:mathml mover><\a:mathml mrow>}#1\HCode{</\a:mathml mrow><\a:mathml mo \a:mathml stretchy="true">} +\PauseMathClass\fldr\EndPauseMathClass% +\HCode{</\a:mathml mo></\a:mathml mover>}\egroup +} + +\HRestore\ESV@vecteur +\HLet\ESV@vecteur\:tempa +>>> + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Notes} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/support/TeX4ht/source/tex4ht-sty.tex b/support/TeX4ht/source/tex4ht-sty.tex index e713134f7e..34fa75425a 100644 --- a/support/TeX4ht/source/tex4ht-sty.tex +++ b/support/TeX4ht/source/tex4ht-sty.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-sty.tex 1514 2024-05-06 14:50:21Z michal_h21 $ +% $Id: tex4ht-sty.tex 1556 2024-09-23 10:50:11Z michal_h21 $ % tex tex4ht-sty or ht tex tex4ht-sty % % Copyright 2009-2022 TeX Users Group @@ -2162,11 +2162,11 @@ Should be consistent with the corresponding features in ProTeX. \SubSection{Ref} -The implementations of \''\Ref' and \''\Tag' view the crosswords $\alpha$ as +The implementations of \''\XRef' and \''\Tag' view the crosswords $\alpha$ as pointers to macros that carry the names `\''\cw:'$\alpha$'. \<common cross references\><<< -\def\Ref#1{\expandafter\ifx +\def\XRef#1{\expandafter\ifx \csname |<tag of Tag|>#1\endcsname \relax \:NoTag{#1}% \else \csname |<tag of Tag|>#1\endcsname \fi} >>> @@ -2186,7 +2186,7 @@ pointers to macros that carry the names `\''\cw:'$\alpha$'. \SubSection{LikeRef} The \`'\:LikeRef' command is a stripped down version of -\`'\Ref'; it doesn't check whether the tag is defined. +\`'\XRef'; it doesn't check whether the tag is defined. The space in \`'\space' is needed for carrying MAME tags in (mosaic) html files. @@ -2272,7 +2272,7 @@ probably in latex.4ht. \openin15=\jobname.xref \ifeof15 \def\:NoTag#1{\hbox{$???$}} \else \def\:NoTag#1{\hbox{$???$} - \:warning{\string\Ref\string{\string#1\string}?}} + \:warning{\string\XRef\string{\string#1\string}?}} |<warnings for missing /Link|> \fi \closein15 @@ -2312,11 +2312,11 @@ optional. A missing \`'.ext' stands for \`'.xref'. When \`'-[prefix]+' is empty the component \`'{...}' should also be omitted (and the comamnd assume the form \`'\LoadRef{filename.ext}'). -A \`'+' asks that \`'\Ref' and \`'LikeRef' commands will refer to +A \`'+' asks that \`'\XRef' and \`'LikeRef' commands will refer to expanded tags of the form \`'filename::tag' instead of just \`'tag'. A \`'[prefix]' asks that only tags which start with the given prefix will be loaded. When \`'[prefix]' is omitted, an empty prefix is -assumed and all the tags are loaded. A \`'-' asks that \`'\Ref' and +assumed and all the tags are loaded. A \`'-' asks that \`'\XRef' and \`'LikeRef' commands will refer to truncated tags in which the specified prefixes are omitted. @@ -2920,7 +2920,7 @@ restricted environments (\`'\edef', \`'\write'). >>> -\`'\def\RefFile#1{\Ref{#1|<File tag|>}} +\`'\def\RefFile#1{\XRef{#1|<File tag|>}} \def\LikeRefFile#1{\LikeRef{#1|<File tag|>}}' \<html file commands\><<< diff --git a/support/TeX4ht/source/tex4ht-t4ht.tex b/support/TeX4ht/source/tex4ht-t4ht.tex index 9b534c9490..44833a5512 100644 --- a/support/TeX4ht/source/tex4ht-t4ht.tex +++ b/support/TeX4ht/source/tex4ht-t4ht.tex @@ -1,4 +1,4 @@ -% $Id: tex4ht-t4ht.tex 418 2018-07-03 17:37:07Z karl $ +% $Id: tex4ht-t4ht.tex 1556 2024-09-23 10:50:11Z michal_h21 $ % tex tex4ht-t4ht or ht tex tex4ht-t4ht % % Copyright 2009-2018 TeX Users Group @@ -2351,7 +2351,7 @@ From log files \`'l. # --- needs --- "command" ---' The htfcss records are stored in the following linked list, and used when the font entries `Font("key","...","...","...")' are loaded -(Section~'\Link{usehtfcc}{}\Ref{usehtfcc}\EndLink'). +(Section~'\Link{usehtfcc}{}\XRef{usehtfcc}\EndLink'). \<vars\><<< static struct htf_struct *htf_rec = (struct htf_struct *) 0; diff --git a/support/TeX4ht/source/wripro.tex b/support/TeX4ht/source/wripro.tex index 30d0c025f2..d583c8ced0 100644 --- a/support/TeX4ht/source/wripro.tex +++ b/support/TeX4ht/source/wripro.tex @@ -1,8 +1,8 @@ -% $Id: wripro.tex 414 2018-06-12 23:04:41Z karl $ +% $Id: wripro.tex 1558 2024-09-24 17:22:45Z karl $ % Used in tex4ht.sty. Not installed in runtime. % -% Copyright (C)) 2009-2010 TeX Users Group -% Copyright (C) 1996-2009, 2018 Eitan M. Gurari +% Copyright 2009-2024 TeX Users Group +% Copyright 1996-2009 Eitan M. Gurari % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either @@ -19,6 +19,7 @@ % % If you modify this program, changing the % version identification would be appreciated. +\immediate\write-1{version 2024-09-23-15:43} %\openin15= wripro.tex %\ifeof15 \closein15 \else \closein15 \input wripro.tex \fi @@ -181,9 +182,9 @@ For instance, in {\tt A \`'\Link-{..}{b}' asks that a \''\Tag' will not be produced for `b'. -A \`'\Link[\empty]{b}{..}' asks that a \''\Ref' will not be produced for +A \`'\Link[\empty]{b}{..}' asks that a \''\XRef' will not be produced for `a'. The same is true for any other non-empty replacement to \''\empty' -A `b' for which we neither have a \''\Tag' and a \''\Ref' provides +A `b' for which we neither have a \''\Tag' and a \''\XRef' provides a memory save in `strings out of', `string characters out of', and `multiletter control sequences' (see log files). diff --git a/support/bibtexperllibs/BibTeX-Parser/Changes b/support/bibtexperllibs/BibTeX-Parser/Changes deleted file mode 100644 index da5c2afb8e..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/Changes +++ /dev/null @@ -1,86 +0,0 @@ -Revision history for BibTeX::Parser - -1.04 2023-08-20 New release - -1.03 2022-11-06 - Avoid extra spaces with von part. (Author.pm) - Add ' to re_namechar. (Parser.pm) - -1.02 2018-04-29 03:19:56 +0000 - Corrected the bug when Jr is not accompanied by von. - -1.01 2017-11-19 03:12:34 +0000 - New options for to_string: - - print_pre - whether to print text preceding the entry - - type_capitalization ('Uppercase', 'Lowercase', - 'Titlecase') - - field_capitalization ('Uppercase', 'Lowercase', - 'Titlecase') - -1.00 2017-03-18 21:53:15+00:00 - Typo corrected: editors -> editor - -0.70 2016-11-23 02:28:35+00:00 - Compatibility with perl 5.25 (Alexandr Ciornii) - -0.69 2016-03-24 15:13:50-04:00 - Added option canonize_names to Entry::to_string - -0.68 2016-03-10 13:45:31-05:00 - Now we preserve the order of entries - -0.67 2015-12-28 22:36:42+00:00 - Corrected test t/13_output.t - -0.66 2015-12-23 19:52:55-05:00 - Corrected bug 67419. - Added $entry->to_string function - No Do not remove braces from the authors' names - -0.65 2013-09-03 21:04:43 - Add links in documentation. - -0.64 2012-03-10 22:23:50 - Remove a warning about undefined value. - -0.63 2011-03-15 23:08:18 - Parse files with errors (no keys, spaces in wrong positions). Bug #66325 - -0.62 2010-10-15 08:52:53 - Declare Test::More minimum version with done_testing - -0.61 2010-07-19 16:37:49 - Add methods $entry->cleaned_author / cleaned_editor - -0.6 2010-07-19 14:43:15 - Add method $entry->cleaned_field( 'name' ) - Add prerequisite LaTeX::ToUnicode >= 0.02 - -0.5 2010-07-06 13:17:45 Europe/Berlin - Do not attempt to clean up returned values - Author names with braces are split correctly - -0.4 2010-02-09 - Parsing of quoted author names (e.g. "{Foo and Bar, Inc.}") - -0.3.2 2009-07-26 - Removed dependency on Text::Balanced - -0.3.1 2009-07-19 - No changes, removed huge test file from dist - -0.3 2009-07-18 - Better parsing of author names, - new Method B::P::Entry->raw_bibtex - Removed Module::Install from package - -0.21 2009-01-23 - Fixed errors in synopsis. - -0.2 2008-12-30 - First public release. - -0.1 2008-03-14 - First version, internal - - diff --git a/support/bibtexperllibs/BibTeX-Parser/LICENSE b/support/bibtexperllibs/BibTeX-Parser/LICENSE deleted file mode 100644 index 1a50e57d4d..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/LICENSE +++ /dev/null @@ -1,379 +0,0 @@ -This software is copyright (c) 2013-2022 by Gerhard Gossen and Boris Veytsman and Karl Berry - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. - -Terms of the Perl programming language system itself - -a) the GNU General Public License as published by the Free - Software Foundation; either version 1, or (at your option) any - later version, or -b) the "Artistic License" - ---- The GNU General Public License, Version 1, February 1989 --- - -This software is copyright (c) 2013-2016 by Gerhard Gossen and Boris Veytsman - -This is free software, licensed under: - - The GNU General Public License, Version 1, February 1989 - - GNU GENERAL PUBLIC LICENSE - Version 1, February 1989 - - Copyright (C) 1989 Free Software Foundation, Inc. - 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The license agreements of most software companies try to keep users -at the mercy of those companies. By contrast, our General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. The -General Public License applies to the Free Software Foundation's -software and to any other program whose authors commit to using it. -You can use it for your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Specifically, the General Public License is designed to make -sure that you have the freedom to give away or sell copies of free -software, that you receive source code or can get it if you want it, -that you can change the software or use pieces of it in new free -programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of a such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any program or other work which -contains a notice placed by the copyright holder saying it may be -distributed under the terms of this General Public License. The -"Program", below, refers to any such program or work, and a "work based -on the Program" means either the Program or any work containing the -Program or a portion of it, either verbatim or with modifications. Each -licensee is addressed as "you". - - 1. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this -General Public License and to the absence of any warranty; and give any -other recipients of the Program a copy of this General Public License -along with the Program. You may charge a fee for the physical act of -transferring a copy. - - 2. You may modify your copy or copies of the Program or any portion of -it, and copy and distribute such modifications under the terms of Paragraph -1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating that - you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, that - in whole or in part contains the Program or any part thereof, either - with or without modifications, to be licensed at no charge to all - third parties under the terms of this General Public License (except - that you may choose to grant warranty protection to some or all - third parties, at your option). - - c) If the modified program normally reads commands interactively when - run, you must cause it, when started running for such interactive use - in the simplest and most usual way, to print or display an - announcement including an appropriate copyright notice and a notice - that there is no warranty (or else, saying that you provide a - warranty) and that users may redistribute the program under these - conditions, and telling the user how to view a copy of this General - Public License. - - d) You may charge a fee for the physical act of transferring a - copy, and you may at your option offer warranty protection in - exchange for a fee. - -Mere aggregation of another independent work with the Program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other work under the scope of these terms. - - 3. You may copy and distribute the Program (or a portion or derivative of -it, under Paragraph 2) in object code or executable form under the terms of -Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal charge - for the cost of distribution) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - -Source code for a work means the preferred form of the work for making -modifications to it. For an executable file, complete source code means -all the source code for all modules it contains; but, as a special -exception, it need not include source code for modules which are standard -libraries that accompany the operating system on which the executable -file runs, or for standard header files or definitions files that -accompany that operating system. - - 4. You may not copy, modify, sublicense, distribute or transfer the -Program except as expressly provided under this General Public License. -Any attempt otherwise to copy, modify, sublicense, distribute or transfer -the Program is void, and will automatically terminate your rights to use -the Program under this License. However, parties who have received -copies, or rights to use copies, from you under this General Public -License will not have their licenses terminated so long as such parties -remain in full compliance. - - 5. By copying, distributing or modifying the Program (or any work based -on the Program) you indicate your acceptance of this license to do so, -and all its terms and conditions. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the original -licensor to copy, distribute or modify the Program subject to these -terms and conditions. You may not impose any further restrictions on the -recipients' exercise of the rights granted herein. - - 7. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of the license which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -the license, you may choose any version ever published by the Free Software -Foundation. - - 8. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS 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. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to humanity, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19xx name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items--whatever suits your -program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - program `Gnomovision' (a program to direct compilers to make passes - at assemblers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -That's all there is to it! - - ---- The Artistic License 1.0 --- - -This software is Copyright (c) 2013 by Gerhard Gossen. - -This is free software, licensed under: - - The Artistic License 1.0 - -The Artistic License - -Preamble - -The intent of this document is to state the conditions under which a Package -may be copied, such that the Copyright Holder maintains some semblance of -artistic control over the development of the package, while giving the users of -the package the right to use and distribute the Package in a more-or-less -customary fashion, plus the right to make reasonable modifications. - -Definitions: - - - "Package" refers to the collection of files distributed by the Copyright - Holder, and derivatives of that collection of files created through - textual modification. - - "Standard Version" refers to such a Package if it has not been modified, - or has been modified in accordance with the wishes of the Copyright - Holder. - - "Copyright Holder" is whoever is named in the copyright or copyrights for - the package. - - "You" is you, if you're thinking about copying or distributing this Package. - - "Reasonable copying fee" is whatever you can justify on the basis of media - cost, duplication charges, time of people involved, and so on. (You will - not be required to justify it to the Copyright Holder, but only to the - computing community at large as a market that must bear the fee.) - - "Freely Available" means that no fee is charged for the item itself, though - there may be fees involved in handling the item. It also means that - recipients of the item may redistribute it under the same conditions they - received it. - -1. You may make and give away verbatim copies of the source form of the -Standard Version of this Package without restriction, provided that you -duplicate all of the original copyright notices and associated disclaimers. - -2. You may apply bug fixes, portability fixes and other modifications derived -from the Public Domain or from the Copyright Holder. A Package modified in such -a way shall still be considered the Standard Version. - -3. You may otherwise modify your copy of this Package in any way, provided that -you insert a prominent notice in each changed file stating how and when you -changed that file, and provided that you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise make them - Freely Available, such as by posting said modifications to Usenet or an - equivalent medium, or placing the modifications on a major archive site - such as ftp.uu.net, or by allowing the Copyright Holder to include your - modifications in the Standard Version of the Package. - - b) use the modified Package only within your corporation or organization. - - c) rename any non-standard executables so the names do not conflict with - standard executables, which must also be provided, and provide a separate - manual page for each non-standard executable that clearly documents how it - differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -4. You may distribute the programs of this Package in object code or executable -form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library files, - together with instructions (in the manual page or equivalent) on where to - get the Standard Version. - - b) accompany the distribution with the machine-readable source of the Package - with your modifications. - - c) accompany any non-standard executables with their corresponding Standard - Version executables, giving the non-standard executables non-standard - names, and clearly documenting the differences in manual pages (or - equivalent), together with instructions on where to get the Standard - Version. - - d) make other distribution arrangements with the Copyright Holder. - -5. You may charge a reasonable copying fee for any distribution of this -Package. You may charge any fee you choose for support of this Package. You -may not charge a fee for this Package itself. However, you may distribute this -Package in aggregate with other (possibly commercial) programs as part of a -larger (possibly commercial) software distribution provided that you do not -advertise this Package as a product of your own. - -6. The scripts and library files supplied as input to or produced as output -from the programs of this Package do not automatically fall under the copyright -of this Package, but belong to whomever generated them, and may be sold -commercially, and may be aggregated with this Package. - -7. C or perl subroutines supplied by you and linked into this Package shall not -be considered part of this Package. - -8. The name of the Copyright Holder may not be used to endorse or promote -products derived from this software without specific prior written permission. - -9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -The End - diff --git a/support/bibtexperllibs/BibTeX-Parser/MANIFEST b/support/bibtexperllibs/BibTeX-Parser/MANIFEST deleted file mode 100644 index 032eea6a15..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/MANIFEST +++ /dev/null @@ -1,44 +0,0 @@ -LICENSE -Changes -MANIFEST -t/pod.t -t/cleaned_field.t -t/release-pod-coverage.t -t/bug67419.t -t/09-complex.t -t/bug66325.t -t/07-parse_englishbib.t -t/13_output.t -t/01-parse.t -t/14-extratext.t -t/05-author.t -t/08-parse_large.t -t/release-pod-syntax.t -t/12-von_token.t -t/00-load.t -t/11-split_braced.t -t/02-parse_string.t -t/04-entry.t -t/03-parse_entry.t -t/bibs/mathscinet.txt -t/bibs/10-funnyname.bib -t/bibs/english.bib -t/bibs/braces.bib -t/bibs/endnote.txt -t/bibs/14-extratext.bib -t/bibs/01.bib -t/bibs/engineering_village.txt -t/bibs/09-complex.bib -t/bibs/06.bib -t/pod-coverage.t -t/10-funnyname.t -t/15-capitalization.t -t/06-parse_complex.t -README -notes -lib/BibTeX/Parser/Author.pm -lib/BibTeX/Parser/Entry.pm -lib/BibTeX/Parser.pm -Makefile.PL -Makefile.TDS -dist.ini diff --git a/support/bibtexperllibs/BibTeX-Parser/Makefile.PL b/support/bibtexperllibs/BibTeX-Parser/Makefile.PL deleted file mode 100644 index e095f253b0..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/Makefile.PL +++ /dev/null @@ -1,71 +0,0 @@ - -use strict; -use warnings; - - - -use ExtUtils::MakeMaker 6.30; - - - -my %WriteMakefileArgs = ( - "ABSTRACT" => "A pure perl BibTeX parser", - "AUTHOR" => 'Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.org', - "BUILD_REQUIRES" => {}, - "CONFIGURE_REQUIRES" => { - "ExtUtils::MakeMaker" => "6.31" - }, - "DISTNAME" => "BibTeX-Parser", - "EXE_FILES" => [], - "LICENSE" => "perl", - "NAME" => "BibTeX::Parser", - "PREREQ_PM" => { - "File::Spec" => 0, - "IO::File" => 0, - "IO::String" => 0, - "LaTeX::ToUnicode" => "0.52", - "Test::More" => "0.88" - }, - "TEST_REQUIRES" => { - "Test::More" => "0.88" - }, - 'VERSION_FROM' => 'lib/BibTeX/Parser.pm', - "test" => { - "TESTS" => "t/*.t" - } -); - - -unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { - my $tr = delete $WriteMakefileArgs{TEST_REQUIRES}; - my $br = $WriteMakefileArgs{BUILD_REQUIRES}; - for my $mod ( keys %$tr ) { - if ( exists $br->{$mod} ) { - $br->{$mod} = $tr->{$mod} if $tr->{$mod} > $br->{$mod}; - } - else { - $br->{$mod} = $tr->{$mod}; - } - } -} - -unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) { - my $br = delete $WriteMakefileArgs{BUILD_REQUIRES}; - my $pp = $WriteMakefileArgs{PREREQ_PM}; - for my $mod ( keys %$br ) { - if ( exists $pp->{$mod} ) { - $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod}; - } - else { - $pp->{$mod} = $br->{$mod}; - } - } -} - -delete $WriteMakefileArgs{CONFIGURE_REQUIRES} - unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; - -WriteMakefile(%WriteMakefileArgs); - - - diff --git a/support/bibtexperllibs/BibTeX-Parser/Makefile.TDS b/support/bibtexperllibs/BibTeX-Parser/Makefile.TDS deleted file mode 100644 index 780ebc0af1..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/Makefile.TDS +++ /dev/null @@ -1,35 +0,0 @@ -# This is Makefile for TDS-compliant TeX distributions -# Written by Boris Veytsman, boris@varphi.com -# -# This file is in public domain -# -PREFIX = /usr/local - -LIBDIR = $(PREFIX)/scripts/bibtexperllibs - -DOCDIR = $(PREFIX)/doc/bibtex/bibtexperllibs - -all: - -docs: - -install: - mkdir -p $(LIBDIR) - cp -r lib/* $(LIBDIR) - mkdir -p $(DOCDIR) - cp -r man/man3/* $(DOCDIR) - -check test: Makefile -# need bash pipefail so exit status is from the make, not the tr. -# the -f Makefile is because of possible GNUmakefile -> Makefile.TDS symlink. - bash -c "set -o pipefail; \ - env PERL5LIB=../LaTeX-ToUnicode/lib \ - make -f Makefile test | tr '\r' '\n'" - -Makefile MYMETA.json MYMeta.yml: Makefile.PL force - perl Makefile.PL || rm -f $@ - -clean distclean: - $(RM) Makefile MYMETA.* blib pm_to_blib *.tar.gz - -force: diff --git a/support/bibtexperllibs/BibTeX-Parser/README b/support/bibtexperllibs/BibTeX-Parser/README deleted file mode 100644 index cb6f19b576..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/README +++ /dev/null @@ -1,9 +0,0 @@ -This is the BibTeX::Parser Perl package: - - A pure Perl BibTeX parser - -Copyright 2013--2023 Gerhard Gossen, Boris Veytsman, Karl Berry - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. - diff --git a/support/bibtexperllibs/BibTeX-Parser/dist.ini b/support/bibtexperllibs/BibTeX-Parser/dist.ini deleted file mode 100644 index bc60ca9352..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/dist.ini +++ /dev/null @@ -1,28 +0,0 @@ -name = BibTeX-Parser -version = 1.04 -author = Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.org> -license = Perl_5 -copyright_holder = Gerhard Gossen and Boris Veytsman and Karl Berry - -[@Classic] - -[NextRelease] -format = %-7v %{yyyy-MM-dd HH:mm:ss}d - -[PodWeaver] - -[Prereqs] -Test::More = 0 -IO::String = 0 -IO::File = 0 -File::Spec = 0 -LaTeX::ToUnicode = 0.11 - -[Prereqs / TestRequires] -Test::More = 0.88 ; for done_testing - -[PruneFiles] -filenames = t/bibs/java.bib - -[Repository] -[@Git] diff --git a/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser.pm b/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser.pm deleted file mode 100644 index 2897d8495d..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser.pm +++ /dev/null @@ -1,366 +0,0 @@ -package BibTeX::Parser; -{ - $BibTeX::Parser::VERSION = '1.04'; -} -# ABSTRACT: A pure perl BibTeX parser -use warnings; -use strict; - -use BibTeX::Parser::Entry; - - -my $re_namechar = qr/[a-zA-Z0-9\!\$\&\*\+\-\.\/\:\;\<\>\?\[\]\^\_\`\|\']/o; -my $re_name = qr/$re_namechar+/o; - - -sub new { - my ( $class, $fh ) = @_; - - return bless { - fh => $fh, - strings => { - jan => "January", - feb => "February", - mar => "March", - apr => "April", - may => "May", - jun => "June", - jul => "July", - aug => "August", - sep => "September", - oct => "October", - nov => "November", - dec => "December", - - }, - line => -1, - buffer => "", - }, $class; -} - -sub _slurp_close_bracket; - -sub _parse_next { - my $self = shift; - - while (1) { # loop until regular entry is finished - return 0 if $self->{fh}->eof; - local $_ = $self->{buffer}; - - until (/@/m) { - my $line = $self->{fh}->getline; - return 0 unless defined $line; - $line =~ s/^%.*$//; - $_ .= $line; - } - - my $current_entry = new BibTeX::Parser::Entry; - if (/@($re_name)/cgo) { - my $type = uc $1; - $current_entry->type( $type ); - my $start_pos = pos($_) - length($type) - 1; - - # read rest of entry (matches braces) - my $bracelevel = 0; - $bracelevel += tr/\{/\{/; #count braces - $bracelevel -= tr/\}/\}/; - while ( $bracelevel != 0 ) { - my $position = pos($_); - my $line = $self->{fh}->getline; - last unless defined $line; - $bracelevel = - $bracelevel + ( $line =~ tr/\{/\{/ ) - ( $line =~ tr/\}/\}/ ); - $_ .= $line; - pos($_) = $position; - } - - # Remember text before the entry - my $pre = substr($_, 0, $start_pos-1); - if ($start_pos == 0) { - $pre = ''; - } - $current_entry->pre($pre); - - - # Remember raw bibtex code - my $raw = substr($_, $start_pos); - $raw =~ s/^\s+//; - $raw =~ s/\s+$//; - $current_entry->raw_bibtex($raw); - - my $pos = pos $_; - tr/\n/ /; - pos($_) = $pos; - - if ( $type eq "STRING" ) { - if (/\G\{\s*($re_name)\s*=\s*/cgo) { - my $key = $1; - my $value = _parse_string( $self->{strings} ); - if ( defined $self->{strings}->{$key} ) { - warn("Redefining string $key!"); - } - $self->{strings}->{$key} = $value; - /\G[\s\n]*\}/cg; - } else { - $current_entry->error("Malformed string!"); - return $current_entry; - } - } elsif ( $type eq "COMMENT" or $type eq "PREAMBLE" ) { - /\G\{./cgo; - _slurp_close_bracket; - } else { # normal entry - $current_entry->parse_ok(1); - - # parse key - if (/\G\s*\{(?:\s*($re_name)\s*,[\s\n]*|\s+\r?\s*)/cgo) { - $current_entry->key($1); - - # fields - while (/\G[\s\n]*($re_name)[\s\n]*=[\s\n]*/cgo) { - $current_entry->field( - $1 => _parse_string( $self->{strings} ) ); - my $idx = index( $_, ',', pos($_) ); - pos($_) = $idx + 1 if $idx > 0; - } - - return $current_entry; - - } else { - - $current_entry->error("Malformed entry (key contains illegal characters) at " . substr($_, pos($_) || 0, 20) . ", ignoring"); - _slurp_close_bracket; - return $current_entry; - } - } - - $self->{buffer} = substr $_, pos($_); - - } else { - $current_entry->error("Did not find type at " . substr($_, pos($_) || 0, 20)); - return $current_entry; - } - - } -} - - -sub next { - my $self = shift; - - return $self->_parse_next; -} - -# slurp everything till the next closing brace. Handles -# nested brackets -sub _slurp_close_bracket { - my $bracelevel = 0; - BRACE: { - /\G[^\}]*\{/cg && do { $bracelevel++; redo BRACE }; - /\G[^\{]*\}/cg - && do { - if ( $bracelevel > 0 ) { - $bracelevel--; - redo BRACE; - } else { - return; - } - } - } -} - -# parse bibtex string in $_ and return. A BibTeX string is either enclosed -# in double quotes '"' or matching braces '{}'. The braced form may contain -# nested braces. -sub _parse_string { - my $strings_ref = shift; - - my $value = ""; - - PART: { - if (/\G(\d+)/cg) { - $value .= $1; - } elsif (/\G($re_name)/cgo) { - warn("Using undefined string $1") unless defined $strings_ref->{$1}; - $value .= $strings_ref->{$1} || ""; - } elsif (/\G"(([^"\\]*(\\.)*[^\\"]*)*)"/cgs) - { # quoted string with embeded escapes - $value .= $1; - } else { - my $part = _extract_bracketed( $_ ); - $value .= substr $part, 1, length($part) - 2; # strip quotes - } - - if (/\G\s*#\s*/cg) { # string concatenation by # - redo PART; - } - } - $value =~ s/[\s\n]+/ /g; - return $value; -} - -sub _extract_bracketed -{ - for($_[0]) # alias to $_ - { - /\G\s+/cg; - my $start = pos($_); - my $depth = 0; - while(1) - { - /\G\\./cg && next; - /\G\{/cg && (++$depth, next); - /\G\}/cg && (--$depth > 0 ? next : last); - /\G([^\\\{\}]+)/cg && next; - last; # end of string - } - return substr($_, $start, pos($_)-$start); - } -} - -# Split the $string using $pattern as a delimiter with -# each part having balanced braces (so "{$pattern}" -# does NOT split). -# Return empty list if unmatched braces - -sub _split_braced_string { - my $string = shift; - my $pattern = shift; - my @tokens; - return () if $string eq ''; - my $buffer; - while (!defined pos $string || pos $string < length $string) { - if ( $string =~ /\G(.*?)(\{|$pattern)/cgi ) { - my $match = $1; - if ( $2 =~ /$pattern/i ) { - $buffer .= $match; - push @tokens, $buffer; - $buffer = ""; - } elsif ( $2 =~ /\{/ ) { - $buffer .= $match . "{"; - my $numbraces=1; - while ($numbraces !=0 && pos $string < length $string) { - my $symbol = substr($string, pos $string, 1); - $buffer .= $symbol; - if ($symbol eq '{') { - $numbraces ++; - } elsif ($symbol eq '}') { - $numbraces --; - } - pos($string) ++; - } - if ($numbraces != 0) { - return (); - } - } else { - $buffer .= $match; - } - } else { - $buffer .= substr $string, (pos $string || 0); - last; - } - } - push @tokens, $buffer if $buffer; - return @tokens; -} - - -1; # End of BibTeX::Parser - - -__END__ -=pod - -=head1 NAME - -BibTeX::Parser - A pure perl BibTeX parser - - -=head1 SYNOPSIS - -Parses BibTeX files. - - use BibTeX::Parser; - use IO::File; - - my $fh = IO::File->new("filename"); - - # Create parser object ... - my $parser = BibTeX::Parser->new($fh); - - # ... and iterate over entries - while (my $entry = $parser->next ) { - if ($entry->parse_ok) { - my $type = $entry->type; - my $title = $entry->field("title"); - - my @authors = $entry->author; - # or: - my @editors = $entry->editor; - - foreach my $author (@authors) { - print $author->first . " " - . $author->von . " " - . $author->last . ", " - . $author->jr; - } - } else { - warn "Error parsing file: " . $entry->error; - } - } - - - -=head1 FUNCTIONS - -=head2 new - -Creates new parser object. - -Parameters: - - * fh: A filehandle - -=head2 next - -Returns the next parsed entry or undef. - -=head1 NOTES - -The fields C<author> and C<editor> are canonized, see -L<BibTeX::Parser::Author> - - -=head1 SEE ALSO - -=over 4 - -=item - -L<BibTeX::Parser::Entry> - -=item - -L<BibTeX::Parser::Author> - -=back - -=head1 VERSION - -version 1.04 - - -=head1 AUTHOR - -Gerhard Gossen <gerhard.gossen@googlemail.com> and -Boris Veytsman <boris@varphi.com> and -Karl Berry <karl@freefriends.org> - -=head1 COPYRIGHT AND LICENSE - -This software is copyright (c) 2013-2023 by Gerhard Gossen and Boris Veytsman and Karl Berry. - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. - -=cut - diff --git a/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Author.pm b/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Author.pm deleted file mode 100644 index a35e2073a6..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Author.pm +++ /dev/null @@ -1,429 +0,0 @@ -package BibTeX::Parser::Author; -{ - $BibTeX::Parser::Author::VERSION = '1.04'; -} - -use warnings; -use strict; - -use BibTeX::Parser; - - -use overload - '""' => \&to_string; - - - -sub new { - my $class = shift; - - if (@_) { - my $self = [ $class->split(@_) ]; - return bless $self, $class; - } else { - return bless [], $class; - } -} - -sub _get_or_set_field { - my ($self, $field, $value) = @_; - if (defined $value) { - $self->[$field] = $value; - } else { - return $self->[$field]; - } -} - - -sub first { - shift->_get_or_set_field(0, @_); -} - - -sub von { - shift->_get_or_set_field(1, @_); -} - - -sub last { - shift->_get_or_set_field(2, @_); -} - - -sub jr { - shift->_get_or_set_field(3, @_); -} - - -# Take a string and create an array [first, von, last, jr] -sub split { - my ($self_or_class, $name) = @_; - - # remove whitespace at start and end of string - $name =~ s/^\s*(.*)\s*$/$1/s; - - - - if (!length($name)) { - return (undef, undef, undef, undef); - } - - my @comma_separated = - BibTeX::Parser::_split_braced_string($name, - '\s*,\s*'); - if (scalar(@comma_separated) == 0) { - # Error? - return (undef, undef, undef, undef); - } - - my $first=undef; - my $von=undef; - my $last=undef; - my $jr=undef; - - if (scalar(@comma_separated) == 1) { - # First von Last form - my @tokens = - BibTeX::Parser::_split_braced_string($name, '\s+'); - if (!scalar (@tokens)) { - return (undef, undef, undef, undef); - } - my ($start_von, $start_last) = _getStartVonLast (@tokens); - if ($start_von >0) { - $first = join(' ', splice(@tokens,0,$start_von)); - } - if (($start_last-$start_von) >0) { - $von = join(' ', splice(@tokens,0,$start_last-$start_von)); - } - $last = join(' ',@tokens); - return ($first, $von, $last, $jr); - } - # Now we work with von Last, [Jr,] First form - if (scalar @comma_separated == 2) { # no jr - my @tokens= - BibTeX::Parser::_split_braced_string($comma_separated[1], '\s+'); - $first = join(' ', @tokens); - } else { # jr is present - my @tokens= - BibTeX::Parser::_split_braced_string($comma_separated[1], '\s+'); - $jr = join(' ', @tokens); - @tokens= - BibTeX::Parser::_split_braced_string($comma_separated[2], '\s+'); - $first = join(' ', @tokens); - } - my @tokens = - BibTeX::Parser::_split_braced_string($comma_separated[0], '\s+'); - my $start_last = _getStartLast(@tokens); - if ($start_last > 0) { - $von=join(' ', splice(@tokens,0,$start_last)); - } - $last = join(' ',@tokens); - return ($first, $von, $last, $jr); - -} - -# Return the index of the first von element and the first lastname -# element. If no von element, von=last - -sub _getStartVonLast { - my $length=scalar(@_); - if ($length==1) { - return (0,0); - } - my $start_von=-1; - my $start_last=$length-1; - for (my $i=0; $i<$length; $i++) { - if (_is_von_token($_[$i])) { - $start_von=$i; - last; - } - } - if ($start_von== -1) { # no von part - return($length-1, $length-1); - } - if ($start_von== $length-1) { # all parts but last are upper case? - return($length-1, $length-1); - } - for (my $i=$start_von+1; $i<$length; $i++) { - if (!_is_von_token($_[$i])) { - $start_last=$i; - last; - } - } - return($start_von, $start_last); -} - - -# Return the index of the first lastname -# element provided no first name elements are present - -sub _getStartLast { - my $length=scalar(@_); - if ($length==1) { - return 0; - } - my $start_last=$length-1; - for (my $i=0; $i<$length; $i++) { - if (!_is_von_token($_[$i])) { - $start_last=$i; - last; - } - } - return $start_last; -} - - -sub _split_name_parts { - my $name = shift; - - if ( $name !~ /\{/ ) { - return split /\s+/, $name; - } else { - my @parts; - my $cur_token = ''; - while ( scalar( $name =~ /\G ( [^\s\{]* ) ( \s+ | \{ | \s* $ ) /xgc ) ) { - $cur_token .= $1; - if ( $2 =~ /\{/ ) { - if ( scalar( $name =~ /\G([^\}]*)\}/gc ) ) { - $cur_token .= "{$1}"; - } else { - die "Unmatched brace in name '$name'"; - } - } else { - if ( $cur_token =~ /^{(.*)}$/ ) { - $cur_token = $1; - } - push @parts, $cur_token; - $cur_token = ''; - } - } - return @parts; - } - -} - - -sub _get_single_author_from_tokens { - my (@tokens) = @_; - if (@tokens == 0) { - return (undef, undef, undef, undef); - } elsif (@tokens == 1) { # name without comma - if ( $tokens[0] =~ /(^|\s)[[:lower:]]/) { # name has von part or has only lowercase names - my @name_parts = _split_name_parts $tokens[0]; - - my $first; - while (@name_parts && ucfirst($name_parts[0]) eq $name_parts[0] ) { - $first .= $first ? ' ' . shift @name_parts : shift @name_parts; - } - - my $von; - # von part are lowercase words - while ( @name_parts && lc($name_parts[0]) eq $name_parts[0] ) { - $von .= $von ? ' ' . shift @name_parts : shift @name_parts; - } - - if (@name_parts) { - return ($first, $von, join(" ", @name_parts), undef); - } else { - return (undef, undef, $tokens[0], undef); - } - } else { - if ( $tokens[0] !~ /\{/ && $tokens[0] =~ /^((.*)\s+)?\b(\S+)$/) { - return ($2, undef, $3, undef); - } else { - my @name_parts = _split_name_parts $tokens[0]; - return ($name_parts[0], undef, $name_parts[1], undef); - } - } - - } elsif (@tokens == 2) { - my @von_last_parts = _split_name_parts $tokens[0]; - my $von; - # von part are lowercase words - while ( @von_last_parts && lc($von_last_parts[0]) eq $von_last_parts[0] ) { - $von .= $von ? ' ' . shift @von_last_parts : shift @von_last_parts; - } - return ($tokens[1], $von, join(" ", @von_last_parts), undef); - } else { - my @von_last_parts = _split_name_parts $tokens[0]; - my $von; - # von part are lowercase words - while ( @von_last_parts && lc($von_last_parts[0]) eq $von_last_parts[0] ) { - $von .= $von ? ' ' . shift @von_last_parts : shift @von_last_parts; - } - return ($tokens[2], $von, join(" ", @von_last_parts), $tokens[1]); - } - -} - - - -# The goal is to return a name in form -# von Last, Jr, First -# where any of the parts except Last may be empty. -# -sub to_string { - my $self = shift; - - my $last = $self->last; # assume always present - my $first = $self->first ? (", " . $self->first) : ''; # ", first" - my $von = $self->von ? ($self->von . " ") : ''; # "von " - my $jr = $self->jr ? (", " . $self->jr ) : ''; # ", jr" - # - my $ret = "${von}${last}${jr}${first}"; - #warn "returning name: $ret\n"; - return $ret; - -# original code, which introduced a spurious space with a von part. -# https://github.com/borisveytsman/crossrefware/issues/11 -# -# if ($self->jr) { -# return () . " " . $self->last . ", " . $self->jr . ", " . $self->first; -# } else { -# return ($self->von ? $self->von . " " : '') . $self->last . ($self->first ? ", " . $self->first : ''); -# } -# -} - - -# Return 1 if the first letter on brace level 0 is lowercase -sub _is_von_token { - my $string = shift; - while ($string =~ - s/^(\\[[:alpha:]]+\{|\{|\\[[:^alpha:]]?|[[:^alpha:]])//) { - if ($1 eq '{' ) { - my $numbraces=1; - while ($numbraces !=0 && length($string)) { - my $symbol = substr($string, 0, 1); - if ($symbol eq '{') { - $numbraces ++; - } elsif ($symbol eq '}') { - $numbraces --; - } - $string = substr($string,1); - } - } - } - - if (length $string ) { - my $symbol = substr($string, 0, 1); - if (lc($symbol) eq $symbol) { - return 1; - } else { - return 0; - } - } else { - return 1; - } - -} - -1; # End of BibTeX::Entry - -__END__ -=pod - -=head1 NAME - -BibTeX::Author - Contains a single author for a BibTeX document. - -=head1 SYNOPSIS - -This class ist a wrapper for a single BibTeX author. It is usually created -by a BibTeX::Parser. - - use BibTeX::Parser::Author; - - my $entry = BibTeX::Parser::Author->new($full_name); - - my $firstname = $author->first; - my $von = $author->von; - my $last = $author->last; - my $jr = $author->jr; - - # or ... - - my ($first, $von, $last, $jr) = BibTeX::Author->split($fullname); - - - -=head1 FUNCTIONS - -=head2 new - -Create new author object. Expects full name as parameter. - -=head2 first - -Set or get first name(s). - -=head2 von - -Set or get 'von' part of name. - -=head2 last - -Set or get last name(s). - -=head2 jr - -Set or get 'jr' part of name. - -=head2 split - -Split name into (firstname, von part, last name, jr part). Returns array -with four strings, some of them possibly empty. - -=head2 to_string - -Return string representation of the name. - -=head1 NOTES - -BibTeX allows three representations of a person's name: - -=over 4 - -=item 1. - -First von Last - -=item 2. - -von Last, First - -=item 3. - -von Last, Jr, First - -=back - -The module always converts the first form to the second of third one -to allow simple string comparisons. - -The algorithm to determine the von part is the following: von part -consists of tokens where the first letter at brace level 0 is in lower case. -Anything in a "special characters" is on brace level 0. Thus the following -tokens are considered von parts: C<von>, C<\NOOP{von}Von>, and -the following token is not: C<{von}> - -=head1 VERSION - -version 1.04 - - -=head1 AUTHOR - -Gerhard Gossen <gerhard.gossen@googlemail.com> and -Boris Veytsman <boris@varphi.com> and -Karl Berry <karl@freefriends.org> - -=head1 COPYRIGHT AND LICENSE - -This software is copyright (c) 2013--2023 by Gerhard Gossen and Boris Veytsman and Karl Berry. - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. - -=cut - diff --git a/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Entry.pm b/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Entry.pm deleted file mode 100644 index d0bc9cc80b..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/lib/BibTeX/Parser/Entry.pm +++ /dev/null @@ -1,435 +0,0 @@ -package BibTeX::Parser::Entry; -{ - $BibTeX::Parser::Entry::VERSION = '1.04'; -} - -use warnings; -use strict; - -use BibTeX::Parser; -use BibTeX::Parser::Author; - - - -sub new { - my ($class, $type, $key, $parse_ok, $fieldsref) = @_; - - my %fields = defined $fieldsref ? %$fieldsref : (); - my $i=0; - foreach my $field (keys %fields) { - if ($field !~ /^_/) { - $fields{_fieldnums}->{$field}=$i; - $i++; - } - } - if (defined $type) { - $fields{_type} = uc($type); - } - $fields{_key} = $key; - $fields{_parse_ok} = $parse_ok; - $fields{_raw} = ''; - return bless \%fields, $class; -} - - - -sub parse_ok { - my $self = shift; - if (@_) { - $self->{_parse_ok} = shift; - } - $self->{_parse_ok}; -} - - -sub error { - my $self = shift; - if (@_) { - $self->{_error} = shift; - $self->parse_ok(0); - } - return $self->parse_ok ? undef : $self->{_error}; -} - - -sub type { - if (scalar @_ == 1) { - # get - my $self = shift; - return $self->{_type}; - } else { - # set - my ($self, $newval) = @_; - $self->{_type} = uc($newval); - } -} - - -sub key { - if (scalar @_ == 1) { - # get - my $self = shift; - return $self->{_key}; - } else { - # set - my ($self, $newval) = @_; - $self->{_key} = $newval; - } - -} - - -sub field { - if (scalar @_ == 2) { - # get - my ($self, $field) = @_; - return $self->{ lc( $field ) }; - } else { - my ($self, $key, $value) = @_; - my $field = lc ($key); - $self->{$field} = $value; #_sanitize_field($value); - if (!exists($self->{_fieldnums}->{$field})) { - my $num = scalar keys %{$self->{_fieldnums}}; - $self->{_fieldnums}->{$field} = $num; - } - } - -} - -use LaTeX::ToUnicode qw( convert ); - - -sub cleaned_field { - my ( $self, $field, @options ) = @_; - if ( $field =~ /author|editor/i ) { - return $self->field( $field ); - } else { - return convert( $self->field( lc $field ), @options ); - } -} - - -sub cleaned_author { - my $self = shift; - $self->_handle_cleaned_author_editor( [ $self->author ], @_ ); -} - - -sub cleaned_editor { - my $self = shift; - $self->_handle_cleaned_author_editor( [ $self->editor ], @_ ); -} - -sub _handle_cleaned_author_editor { - my ( $self, $authors, @options ) = @_; - map { - my $author = $_; - my $new_author = BibTeX::Parser::Author->new; - map { - $new_author->$_( convert( $author->$_, @options ) ) - } grep { defined $author->$_ } qw( first von last jr ); - $new_author; - } @$authors; -} - -no LaTeX::ToUnicode; - -sub _handle_author_editor { - my $type = shift; - my $self = shift; - if (@_) { - if (@_ == 1) { #single string - # my @names = split /\s+and\s+/i, $_[0]; - $_[0] =~ s/^\s*//; - $_[0] =~ s/\s*$//; - my @names = BibTeX::Parser::_split_braced_string($_[0], - '\s+and\s+'); - if (!scalar @names) { - $self->error('Bad names in author/editor field'); - return; - } - $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names]; - $self->field($type, join " and ", @{$self->{"_$type"}}); - } else { - $self->{"_$type"} = []; - foreach my $param (@_) { - if (ref $param eq "BibTeX::Author") { - push @{$self->{"_$type"}}, $param; - } else { - push @{$self->{"_$type"}}, new BibTeX::Parser::Author $param; - } - - $self->field($type, join " and ", @{$self->{"_$type"}}); - } - } - } else { - unless ( defined $self->{"_$type"}) { - my @names = BibTeX::Parser::_split_braced_string($self->{$type} || "", '\s+and\s+' ); - $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names]; - } - return @{$self->{"_$type"}}; - } -} - - - -sub author { - _handle_author_editor('author', @_); -} - - -sub editor { - _handle_author_editor('editor', @_); -} - - -sub fieldlist { - my $self = shift; - - return grep {!/^_/} keys %$self; -} - - -sub has { - my ($self, $field) = @_; - - return defined $self->{$field}; -} - -sub _sanitize_field { - my $value = shift; - for ($value) { - tr/\{\}//d; - s/\\(?!=[ \\])//g; - s/\\\\/\\/g; - } - return $value; -} - - - -sub raw_bibtex { - my $self = shift; - if (@_) { - $self->{_raw} = shift; - } - return $self->{_raw}; -} - -sub pre { - my $self = shift; - if (@_) { - $self->{_pre} = shift; - } - return $self->{_pre}; -} - - -sub to_string { - my $self = shift; - my %options=@_; - if (!exists($options{canonize_names})) { - $options{canonize_names}=1; - } - my @fields = grep {!/^_/} keys %$self; - @fields = sort { - $self->{_fieldnums}->{$a} <=> - $self->{_fieldnums}->{$b}} @fields; - my $result = ''; - if ($options{print_pre}) { - $result .= $self->pre()."\n"; - } - my $type = $self->type; - if (exists($options{type_capitalization})) { - if ($options{type_capitalization} eq 'Lowercase') { - $type = lc $type; - } - if ($options{type_capitalization} eq 'Titlecase') { - $type = ucfirst lc $type; - } - } - print STDERR $self->key, "\n"; - $result .= '@'.$type."{".$self->key.",\n"; - foreach my $field (@fields) { - my $value = $self->field($field); - if ($field eq 'author' && $options{canonize_names}) { - my @names = ($self->author); - $value = join(' and ', @names); - } - if ($field eq 'editor' && $options{canonize_names}) { - my @names = ($self->editor); - $value = join(' and ', @names); - } - if (exists($options{field_capitalization})) { - if ($options{field_capitalization} eq 'Uppercase') { - $field = uc $field; - } - if ($options{field_capitalization} eq 'Titlecase') { - $field = ucfirst $field; - } - } - $result .= " $field = {"."$value"."},\n"; - } - $result .= "}"; - return $result; -} - -1; # End of BibTeX::Entry - -__END__ -=pod - -=head1 NAME - -BibTeX::Parser::Entry - Contains a single entry of a BibTeX document. - -=head1 SYNOPSIS - -This class ist a wrapper for a single BibTeX entry. It is usually created -by a BibTeX::Parser. - - use BibTeX::Parser::Entry; - - my $entry = BibTeX::Parser::Entry->new($type, $key, $parse_ok, \%fields); - - if ($entry->parse_ok) { - my $type = $entry->type; - my $key = $enty->key; - print $entry->field("title"); - my @authors = $entry->author; - my @editors = $entry->editor; - - ... - - print $entry->to_string; - } - - - - - -=head1 FUNCTIONS - -=head2 new - -Create new entry. - -=head2 parse_ok - -If the entry was correctly parsed, this method returns a true value, false otherwise. - -=head2 error - -Return the error message, if the entry could not be parsed or undef otherwise. - -=head2 type - -Get or set the type of the entry, eg. 'ARTICLE' or 'BOOK'. Return value is -always uppercase. - -=head2 key - -Get or set the reference key of the entry. - -=head2 field($name [, $value]) - -Get or set the contents of a field. The first parameter is the name of the -field, the second (optional) value is the new value. - -=head2 cleaned_field($name) - -Retrieve the contents of a field in a format that is cleaned of TeX markup. - -=head2 cleaned_author - -Get an array of L<BibTeX::Parser::Author> objects for the authors of this -entry. Each name has been cleaned of accents and braces. - -=head2 cleaned_editor - -Get an array of L<BibTeX::Parser::Author> objects for the editors of this -entry. Each name has been cleaned of accents and braces. - -=head2 author([@authors]) - -Get or set the authors. Returns an array of L<BibTeX::Author|BibTeX::Author> -objects. The parameters can either be L<BibTeX::Author|BibTeX::Author> objects -or strings. - -Note: You can also change the authors with $entry->field('author', $authors_string) - -=head2 editor([@editors]) - -Get or set the editors. Returns an array of L<BibTeX::Author|BibTeX::Author> -objects. The parameters can either be L<BibTeX::Author|BibTeX::Author> objects -or strings. - -Note: You can also change the authors with $entry->field('editor', $editors_string) - -=head2 fieldlist () - -Returns a list of all the fields used in this entry. - -=head2 has($fieldname) - -Returns a true value if this entry has a value for $fieldname. - -=head2 pre () - -Return the text in BibTeX file before the entry - -=head2 raw_bibtex () - -Return raw BibTeX entry (if available). - -=head2 to_string ([options]) - -Returns a text of the BibTeX entry in BibTeX format. Options are -a hash. - -=over 4 - -=item C<canonize_names> - -If true (the default), authors' and editors' -names are translated into canonical bibtex form. The command -C<$entry-E<gt>to_string(canonize_names=E<gt>0)> overrides this behavior. - -=item C<field_capitalization> - -Capitalization of the field names. -Can take values 'Uppercase', 'Lowercase' (the default) or 'Titlecase' - -=item C<print_pre> - -False by default. If true, the text in the Bib file before the -entry is printed. Note that at present we assume the text -before the entry NEVER has the @ symbol inside - -=item C<type_capitalization> - -Capitalization of the type names. -Can take values 'Uppercase' (the default), 'Lowercase' or 'Titlecase' - - -=back - -=head1 VERSION - -version 1.04 - -=head1 AUTHOR - -Gerhard Gossen <gerhard.gossen@googlemail.com> and -Boris Veytsman <boris@varphi.com> and -Karl Berry <karl@freefriends.org> - -=head1 COPYRIGHT AND LICENSE - -This software is copyright (c) 2013-2023 by Gerhard Gossen and Boris Veytsman and Karl Berry - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. - -=cut - diff --git a/support/bibtexperllibs/BibTeX-Parser/notes b/support/bibtexperllibs/BibTeX-Parser/notes deleted file mode 100644 index 5e41df4090..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/notes +++ /dev/null @@ -1,26 +0,0 @@ -from Biblio::Catalog::BibTeX : - -sub tex2html { - my $latex = shift; - return "" unless defined($latex); - - for ($latex) { - s/\\textit\{([^{]+)\}/<i>$1<\/i>/g; - s/\\textbf\{([^{]+)\}/<b>$1<\/b>/g; - s/\\texttt\{([^{]+)\}/<tt>$1<\/tt>/g; - s/\\emph{([^{]+)}/<i>$1<\/i>/g; - s/\\item\b/<li>/g; - s/\\_/_/g; - s/\\mbox{([^}]+)}/$1/g; - s/{\\it\s([^}]+)}/<i>$1<\/i>/g; - s/\\LaTeX/LaTeX/g; - s/\\begin{itemize}/<ul>/g; - s/\\begin{quote}/<blockquote><i>/g; - s/\\end{quote}/<\/i><\/blockquote>/g; - s/\\end{itemize}/<\/ul>/g; - s/[}{]//g; - } - - return $latex; -} - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/00-load.t b/support/bibtexperllibs/BibTeX-Parser/t/00-load.t deleted file mode 100644 index 9862dc7986..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/00-load.t +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 3; - -BEGIN { - use_ok( 'BibTeX::Parser' ); - use_ok( 'BibTeX::Parser::Author' ); - use_ok( 'BibTeX::Parser::Entry' ); -} - -diag( "Testing BibTeX::Parser $BibTeX::Parser::VERSION, Perl $], $^X" ); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/01-parse.t b/support/bibtexperllibs/BibTeX-Parser/t/01-parse.t deleted file mode 100644 index 70e298d4be..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/01-parse.t +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 11; - -use BibTeX::Parser; -use IO::File; - -use constant ENTRIES => 1; - -my $fh = new IO::File "t/bibs/01.bib", "r" ; - -if (defined $fh) { - my $parser = new BibTeX::Parser $fh; - - isa_ok($parser, "BibTeX::Parser"); - - my $count = 0; - - while (my $entry = $parser->next) { - $count++; - isa_ok($entry, "BibTeX::Parser::Entry"); - is($entry->key, "key01", "key"); - is($entry->type, "ARTICLE", "type"); - ok($entry->parse_ok, "parse_ok"); - is($entry->field("year"), 1950, "field"); - is($entry->field("month"), "January~1", "field"); - - my @authors = $entry->author; - is(scalar @authors, 2, "#authors"); - isa_ok($authors[0], "BibTeX::Parser::Author"); - is("$authors[0]", "Duck, Donald", "correct author"); - } - - is($count, ENTRIES, "number of entries"); -} - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/02-parse_string.t b/support/bibtexperllibs/BibTeX-Parser/t/02-parse_string.t deleted file mode 100644 index 90b87eba14..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/02-parse_string.t +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 7; - -use BibTeX::Parser; - -my %strings = (); - -$_ = 1234; -parse_ok("parse digit string"); - -$_ = '"simple double quoted string"'; -parse_is("simple double quoted string", "- double quoted string"); - -$_ = '"double quotes { with embeded } brackets"'; -parse_is("double quotes { with embeded } brackets", "- with embeded brackets"); - -$_ = '"string 1 " # "string 2"'; -parse_is("string 1 string 2", "- concatenation"); - -$strings{test} = "string"; -$strings{other} = "text"; - -$_ = "test"; -parse_is("string", "- string variable"); - -$_ = "test # other"; -parse_is("stringtext", "- concatenation of string variables"); - -$_ = '"M{\"{u}}nchen"'; -parse_is('M{\"{u}}nchen', "- escaped quote"); - -sub parse_ok { - is(BibTeX::Parser::_parse_string(\%strings), $_, shift); -} - -sub parse_is { - is(BibTeX::Parser::_parse_string(\%strings), shift, shift); -} diff --git a/support/bibtexperllibs/BibTeX-Parser/t/03-parse_entry.t b/support/bibtexperllibs/BibTeX-Parser/t/03-parse_entry.t deleted file mode 100644 index 6b4e4632bc..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/03-parse_entry.t +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 3; - -use IO::String; -use BibTeX::Parser; - -{ - my $string = q|@article{lin1973, - author = "Shen Lin and Brian W. Kernighan", - title = "An Effective Heuristic Algorithm for the Travelling-Salesman Problem", - journal = "Operations Research", - volume = 21, - year = 1973, - pages = "498--516" - }|; - my $fh = IO::String->new($string); - - my $parser = BibTeX::Parser->new( $fh ); - -#my @result = BibTeX::Parser->_parse($fh); - - my $entry = $parser->next; - - is_deeply($entry, {_type => 'ARTICLE', _key => 'lin1973', author => "Shen Lin and Brian W. Kernighan", - title => "An Effective Heuristic Algorithm for the Travelling-Salesman Problem", - journal => "Operations Research", - volume => 21, - year => 1973, - pages => "498--516", _parse_ok => 1, - _fieldnums => {'author' => 0, 'title' => 1, - 'journal' => 2, 'volume' => 3, - 'year' => 4, 'pages' => 5}, - _pre => '', - _raw => $string}, "parse \@ARTICLE"); - -} -{ - my $string1 = q|@article{lin1973, - author = "Shen Lin and Brian W. Kernighan", - title = "An Effective Heuristic Algorithm for the Travelling-Salesman Problem", - journal = "Operations Research", - volume = 21, - year = 1973, - pages = "498--516" - }|; - my $string = "some -text -$string1"; - my $fh = IO::String->new($string); - - my $parser = BibTeX::Parser->new( $fh ); - -#my @result = BibTeX::Parser->_parse($fh); - - my $entry = $parser->next; - - is_deeply($entry, {_type => 'ARTICLE', _key => 'lin1973', author => "Shen Lin and Brian W. Kernighan", - title => "An Effective Heuristic Algorithm for the Travelling-Salesman Problem", - journal => "Operations Research", - volume => 21, - year => 1973, - pages => "498--516", _parse_ok => 1, - _fieldnums => {'author' => 0, 'title' => 1, - 'journal' => 2, 'volume' => 3, - 'year' => 4, 'pages' => 5}, - _pre => "some\ntext", - _raw => $string1}, "parse \@ARTICLE"); - -} -{ - my $string = q|@InProceedings{Herper:2001:MVS, - author = {Henry Herper}, - title = {{M}odellierung von {S}ystemen: ein
- {A}pplikationsgebiet im {I}nformatikunterricht}, - booktitle = {Informatikunterricht und Medienbildung, INFOS 2001
- (9. Fachtagung Informatik und Schule, Paderborn
- 17.-20- September 2001) -- Tagungsband}, - editor = {Reinhard Keil-Slavik and Johannes Magenheim}, - year = {2001}, -}|; - my $fh = IO::String->new($string); - - my $parser = BibTeX::Parser->new( $fh ); - - my $entry = $parser->next; - - is_deeply($entry, { - _type => 'INPROCEEDINGS', - _key => 'Herper:2001:MVS', - _fieldnums => {'author' => 0, 'title' => 1, - 'booktitle' => 2, 'editor' => 3, - 'year' => 4}, - author => "Henry Herper", - title => "{M}odellierung von {S}ystemen: ein {A}pplikationsgebiet im {I}nformatikunterricht", - booktitle => "Informatikunterricht und Medienbildung, INFOS 2001 (9. Fachtagung Informatik und Schule, Paderborn 17.-20- September 2001) -- Tagungsband", - editor => "Reinhard Keil-Slavik and Johannes Magenheim", - year => 2001, - _parse_ok => 1, - _pre => '', - _raw => $string}, "parse \@ARTICLE"); -} diff --git a/support/bibtexperllibs/BibTeX-Parser/t/04-entry.t b/support/bibtexperllibs/BibTeX-Parser/t/04-entry.t deleted file mode 100644 index 3ca9797011..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/04-entry.t +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 13; - -use BibTeX::Parser::Entry; - - -my $entry = new BibTeX::Parser::Entry("type", "key", 1, {title => "title"}); - -isa_ok($entry, "BibTeX::Parser::Entry"); - -is($entry->type, "TYPE", "Entry::type get"); - -$entry->type("newtype"); - -is($entry->type, "NEWTYPE", "Entry::type set"); - -is($entry->key, "key", "Entry::key get"); - -$entry->key("newkey"); - -is($entry->key, "newkey", "Entry::key set"); - -is($entry->field("title"), "title", "Entry::field with new"); - -$entry->field("title" => "newtitle"); - -is($entry->field("title"), "newtitle", "Entry::field overwrite"); - -$entry->field("year" => 2008); - -is($entry->field("year"), 2008, "Entry::field set"); - -is($entry->field("pages"), undef, "Entry::field undef on unknown value"); - -is($entry->fieldlist, 2, "size of fieldlist"); - -ok($entry->has("title"), "Entry::has true on known value"); - -ok($entry->has("year"), "Entry::has true on known value"); - -ok( ! $entry->has("pages"), "Entry::has false on unknown value"); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/05-author.t b/support/bibtexperllibs/BibTeX-Parser/t/05-author.t deleted file mode 100644 index 45bc5413df..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/05-author.t +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/perl - -use Test::More; - -use BibTeX::Parser::Author; - -# Names from Mittelbach, Goossens: The LaTeX Companion, Second Edition. -my %names = ( - "Donald E. Knuth" => ["Donald E.", undef, "Knuth", undef], - "John Chris Smith" => ["John Chris", undef, "Smith", undef], - "Smith, John Chris" => ["John Chris", undef, "Smith", undef], - "Thomas von Neumann" => ["Thomas", "von", "Neumann", undef], - "von Neumann, Thomas" => ["Thomas", "von", "Neumann", undef], - "Lopez Fernandez, Miguel" => ["Miguel", undef, "Lopez Fernandez", undef], - "Pierre de la Porte" => ["Pierre", "de la", "Porte", undef], - "Smith, Jr., Robert" => ["Robert", undef, "Smith", "Jr."], - "von Smith, Jr., Robert" => ["Robert", "von", "Smith", "Jr."], - "Johannes Martinus Albertus van de Groene Heide" => ["Johannes Martinus Albertus", "van de", "Groene Heide", undef], - "Maria-Victoria Delgrande" => ["Maria-Victoria", undef, "Delgrande", undef], - "Anonymous" => [undef, undef, "Anonymous", undef], - "von Neumann" => [undef, "von", "Neumann", undef], - "N. Tetteh-Lartey" => ["N.", undef, "Tetteh-Lartey", undef], - "von Tetteh-Lartey, N." => ["N.", "von", "Tetteh-Lartey", undef], - "von Tetteh-Lartey, Jr., N." => ["N.", "von", "Tetteh-Lartey", "Jr."], - "" => [undef, undef, undef, undef], - " " => [undef, undef, undef, undef], - "\n" => [undef, undef, undef, undef], - "al." => [undef, undef, "al.", undef], - "et.~al." => [undef, undef, "et.~al.", undef], - "O'Malley, A." => ["A.", undef, "O'Malley", undef], - "A. O'Malley" => ["A.", undef, "O'Malley", undef], - "Arthur O'Malley" => ["Arthur", undef, "O'Malley", undef], - "O'Malley, Arthur" => ["Arthur", undef, "O'Malley", undef], - 'L.M. M\"uller' => ["L.M.", undef, 'M\"uller', undef], - 'M\"uller, L.M.' => ["L.M.", undef, 'M\"uller', undef], - 'L.M. M"uller' => ["L.M.", undef, 'M"uller', undef], - 'M"uller, L.M.' => ["L.M.", undef, 'M"uller', undef], - 'van Beethoven, Ludwig' => ["Ludwig", "van", "Beethoven", undef ], - '{Barnes and Noble, Inc.}' => [undef, undef, '{Barnes and Noble, Inc.}', undef], - "Ludwigg {van Beethoven}" => ["Ludwigg", undef, "{van Beethoven}", undef], - '{van Beethoven}, Ludwig' => ["Ludwig", undef, "{van Beethoven}", undef ], -); - -plan tests => (keys(%names) * 6 + 5); - -my $author = new BibTeX::Parser::Author; - -isa_ok($author, "BibTeX::Parser::Author", "Correct type"); - -is($author->first, undef, "Initial state 'first'"); -is($author->von, undef, "Initial state 'von'"); -is($author->last, undef, "Initial state 'last'"); -is($author->jr, undef, "Initial state 'jr'"); - - -foreach my $name (keys %names) { - - is_deeply([BibTeX::Parser::Author->split($name)], $names{$name}, $name =~ /\w/ ? $name : "whitespace name: '$name'" ); - - $author = new BibTeX::Parser::Author $name; - - isa_ok($author, "BibTeX::Parser::Author"); - - is($author->first, $names{$name}->[0] ); - is($author->von, $names{$name}->[1]); - is($author->last, $names{$name}->[2]); - is($author->jr, $names{$name}->[3]); -} diff --git a/support/bibtexperllibs/BibTeX-Parser/t/06-parse_complex.t b/support/bibtexperllibs/BibTeX-Parser/t/06-parse_complex.t deleted file mode 100644 index 95a5848a71..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/06-parse_complex.t +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/perl - -use Test::More tests => 19; - -use strict; -use IO::File; -use BibTeX::Parser; - -my $fh = IO::File->new("t/bibs/06.bib"); - -my $parser = new BibTeX::Parser $fh; - - -my $entry = $parser->next; - -isa_ok($entry, 'BibTeX::Parser::Entry', "Correct type"); -ok($entry->parse_ok, "Entry parsed correctly"); -is($entry->type, "ARTICLE", "BibTeX type is correct"); -is($entry->field("title"), "Paper title", "Title attribute"); -is($entry->field("year"), 2008); -is($entry->field("month"), "August", "Month expansion"); -is($entry->key, 'key1', "key"); - -my @authors = $entry->author; -is(scalar @authors, 2, "number of authors correct"); -my $author = shift @authors; -is_deeply( - [$author->first, $author->von, $author->last, $author->jr], - ['Gerhard', undef, 'Gossen', undef], "author correct"); - -$author = shift @authors; -is_deeply( - [$author->first, $author->von, $author->last, $author->jr], - ['Ludwig', 'van', 'Beethoven', undef], "author correct"); - -$entry = $parser->next; -isa_ok($entry, 'BibTeX::Parser::Entry', "Correct type"); -ok($entry->parse_ok, "Entry parsed correctly"); -is($entry->type, "BOOK", "BibTeX type is correct"); -is($entry->field("title"), "Book title", "Title attribute"); -is($entry->field("year"), 2008); -is($entry->field("month"), "August", "Month expansion"); -is($entry->key, 'key2', "key"); -@authors = $entry->author; -is(scalar @authors, 1, "number of authors"); -is(scalar $entry->editor, 0, "number of editors"); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/07-parse_englishbib.t b/support/bibtexperllibs/BibTeX-Parser/t/07-parse_englishbib.t deleted file mode 100644 index 3348a55248..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/07-parse_englishbib.t +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl - -use Test::More tests => 8; - -use strict; -use IO::File; -use BibTeX::Parser; - - -my $fh = IO::File->new("t/bibs/english.bib"); - -my $parser = new BibTeX::Parser $fh; - -my $count = 0; - -my $entry = $parser->next; - -is($entry->parse_ok, 0, "Ignore spurious @ before parenthesis"); - -$entry = $parser->next; - -is($entry->parse_ok, 0, "Ignore spurious @ in email address"); - -$entry = $parser->next; - -is(scalar $entry->author, 1, "# authors"); -#@BOOK{Carey, -# AUTHOR="G. V. Carey", -is($entry->field("title"), "Mind the Stop: A Brief Guide to Punctuation", "title"); -is($entry->field("publisher"), "Penguin", "publisher"); -is($entry->field("year"), 1958, "year"); -$count++; - -while ($entry = $parser->next) { - $count++; - if ($count == 8) { - is( scalar $entry->author, 4, 'Last entry has 4 authors'); - } -} - - -is($count, 8, "number of entries"); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/08-parse_large.t b/support/bibtexperllibs/BibTeX-Parser/t/08-parse_large.t deleted file mode 100644 index 5375d9a062..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/08-parse_large.t +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More skip_all => "Performance test", tests => 1; - -use IO::File; -use BibTeX::Parser; - -my $starttime = time; - -my $fh = IO::File->new('t/bibs/java.bib'); #cl-nlp8x.bib'); - -my $parser = new BibTeX::Parser $fh; -my $entries = 0; - -#my @result = BibTeX::Parser->_parse($fh); - -while(my $entry = $parser->next) { - $entries++; -} - -my $parsetime = time - $starttime; - -warn "Parsed $entries entries in $parsetime seconds"; -ok(1, "Parsed $entries entries in $parsetime seconds"); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/09-complex.t b/support/bibtexperllibs/BibTeX-Parser/t/09-complex.t deleted file mode 100644 index 56ce75cceb..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/09-complex.t +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 1; - -use IO::File; -use BibTeX::Parser; - - -my $fh = IO::File->new('t/bibs/09-complex.bib'); - -my $parser = new BibTeX::Parser $fh; - -#my @result = BibTeX::Parser->_parse($fh); - -my $entry = $parser->next; - -is_deeply($entry, {_type => 'ARTICLE', _key => 'Ahrenberg88', - author => "L. Ahrenberg and A. Jonsson", - title => "An interactive system for tagging dialogues", - journal => 'Literary \& Linguistic Computing', - volume => 3, - number => "2", - pages => "66--70", - year => "1988", - keywords => "conver", - _fieldnums => {'author' => 0, 'title' => 1, - 'journal' => 2, 'volume' => 3, - 'number' => 4, 'pages'=> 5, - 'year' => 6, 'keywords' => 7}, - _parse_ok => 1, - _raw => '@Article{Ahrenberg88, - author = "L. Ahrenberg and A. Jonsson", - title = "An interactive system for tagging dialogues", - journal = "Literary \& Linguistic Computing", - volume = "3", - number = "2", - pages = "66--70", - year = "1988", - keywords = "conver", -}', - _pre => '' - }, "parse \@ARTICLE"); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/10-funnyname.t b/support/bibtexperllibs/BibTeX-Parser/t/10-funnyname.t deleted file mode 100644 index 8ab48396e9..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/10-funnyname.t +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 11; - -use IO::File; -use BibTeX::Parser; - -my $fh = IO::File->new('t/bibs/10-funnyname.bib'); - -my $parser = BibTeX::Parser->new($fh); - -#my @result = BibTeX::Parser->_parse($fh); - -my $entry = $parser->next; - -is_deeply( - $entry, - { - _type => 'ARTICLE', - _key => 'testkey', - author => 'A. Bar and L.M. M\"uller', - title => 'foo', - journal => 'journal', - volume => 1, - number => 1, - pages => 1, - year => 2008, - _parse_ok => 1, - _fieldnums => {'year' => 0, 'title' => 1, - 'author' => 2, 'journal' => 3, - 'volume' => 4, 'number'=> 5, - 'pages' => 6}, - _raw => '@article{testkey, - year = {2008}, - title = "foo", - author = {A. Bar and L.M. M\"uller}, - journal = {journal}, - volume = {1}, - number = {1}, - pages = {1}, -}', - _pre => '' - }, - "parse \@ARTICLE" -); - -my @authors = $entry->author; - -pass("->author didn't loop forever"); -ok(@authors == 2, "Two authors"); - -is($authors[0]->first, 'A.', "A1 first name"); -is($authors[0]->last, 'Bar', "A1 last name"); -ok(!$authors[0]->von, "A1 no 'von'"); -ok(!$authors[0]->jr, "A1 no 'jr'"); - -is($authors[1]->first, 'L.M.', "A2 first name"); -is($authors[1]->last, 'M\"uller', "A2 last name"); -ok(!$authors[1]->von, "A2 no 'von'"); -ok(!$authors[1]->jr, "A2 no 'jr'"); - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/11-split_braced.t b/support/bibtexperllibs/BibTeX-Parser/t/11-split_braced.t deleted file mode 100644 index 85a29be86f..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/11-split_braced.t +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 12; - -use BibTeX::Parser; -use IO::File; - -my @tokens = BibTeX::Parser::_split_braced_string("a and b", '\s+and\s+'); -is(scalar @tokens,2); -is($tokens[0],'a'); -is($tokens[1],'b'); - -@tokens = BibTeX::Parser::_split_braced_string("a {and} b", '\s+and\s+'); -is(scalar @tokens,1); -is($tokens[0],'a {and} b'); - -@tokens = BibTeX::Parser::_split_braced_string("a {and b", '\s+and\s+'); -is(scalar @tokens,0); - -@tokens = BibTeX::Parser::_split_braced_string("} a {", '\s+'); -is(scalar @tokens,0); - -@tokens = BibTeX::Parser::_split_braced_string("{a b} c {d}e u", '\s+'); -is(scalar @tokens,4); -is($tokens[0],'{a b}'); -is($tokens[1],'c'); -is($tokens[2],'{d}e'); -is($tokens[3],'u'); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/12-von_token.t b/support/bibtexperllibs/BibTeX-Parser/t/12-von_token.t deleted file mode 100644 index 6daceafa96..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/12-von_token.t +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests => 5; - -use BibTeX::Parser::Author; -use IO::File; - -is(BibTeX::Parser::Author::_is_von_token('von'),1); -is(BibTeX::Parser::Author::_is_von_token('Von'),0); -is(BibTeX::Parser::Author::_is_von_token('\noop{von}Von'),1); -is(BibTeX::Parser::Author::_is_von_token('\noop{Von}von'),0); -is(BibTeX::Parser::Author::_is_von_token('\noop{AE}{\AE}schylus'),0); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/13_output.t b/support/bibtexperllibs/BibTeX-Parser/t/13_output.t deleted file mode 100644 index 02fb1cd26f..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/13_output.t +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More; - -use BibTeX::Parser; -use IO::File; - - -my $fh = new IO::File "t/bibs/01.bib", "r" ; - -my $parser = new BibTeX::Parser $fh; - - - - -while (my $entry = $parser->next) { - if($entry->key eq 'key01') { - my $result1='@ARTICLE{key01, - year = {1950}, - author = {Duck, Donald and Else, Someone}, - editor = {Itor, E. D. and Other, A. N.}, - title = {Title text}, - month = {January~1}, -}'; - my $result2='@ARTICLE{key01, - year = {1950}, - author = {Donald Duck and Someone Else}, - editor = {E. D. Itor and A. N. Other}, - title = {Title text}, - month = {January~1}, -}'; - is($entry->to_string,$result1); - is($entry->to_string(canonize_names=>0),$result2); - } - -} - -done_testing(); - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/14-extratext.t b/support/bibtexperllibs/BibTeX-Parser/t/14-extratext.t deleted file mode 100644 index 0a663b043a..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/14-extratext.t +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/perl -w - - -use Test::More tests => 6; - -use BibTeX::Parser; -use IO::File; - - -my $fh = new IO::File "t/bibs/14-extratext.bib", "r" ; - -my $parser = new BibTeX::Parser $fh; - - - - -while (my $entry = $parser->next) { - - if($entry->key eq 'Partridge') { - my $result1= '@BOOK{Partridge, - author = {Partridge, Eric}, - title = {Use and Abuse: a Guide to Good {E}nglish}, - publisher = {Hamish Hamilton}, - edition = {4}, - year = {1970}, -}'; - my $result2 = "First published in 1947\n$result1"; - is($entry->to_string,$result1); - is($entry->to_string(print_pre=>1),$result2); - } - - if ($entry->key eq 'Cooper') { - my $result1 = '@BOOK{Cooper, - author = {Cooper, Bruce M.}, - title = {Writing Technical Reports}, - publisher = {Penguin}, - year = {1964}, -}'; - my $result2 = "\n\n$result1"; - is($entry->to_string,$result1); - is($entry->to_string(print_pre=>1),$result2); - } - - - if ($entry->key eq 'Fowler-ModernEnglish') { - - my $result1 = '@BOOK{Fowler-ModernEnglish, - author = {Fowler, H. W.}, - title = {[A Dictionary of] Modern {E}nglish Usage}, - publisher = {Oxford University Press}, - edition = {2}, - year = {1965}, -}'; - my $result2 = ' - - -First published in 1926 -'. $result1; - is($entry->to_string,$result1); - is($entry->to_string(print_pre=>1),$result2); - } -} - -done_testing(); - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/15-capitalization.t b/support/bibtexperllibs/BibTeX-Parser/t/15-capitalization.t deleted file mode 100644 index 4254f5c12f..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/15-capitalization.t +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More tests=>7; - -use BibTeX::Parser; -use IO::File; - - -my $fh = new IO::File "t/bibs/01.bib", "r" ; - -my $parser = new BibTeX::Parser $fh; - - - - -while (my $entry = $parser->next) { - if($entry->key eq 'key01') { - my $result1='@ARTICLE{key01, - year = {1950}, - author = {Duck, Donald and Else, Someone}, - editor = {Itor, E. D. and Other, A. N.}, - title = {Title text}, - month = {January~1}, -}'; - my $result2='@ARTICLE{key01, - YEAR = {1950}, - AUTHOR = {Duck, Donald and Else, Someone}, - EDITOR = {Itor, E. D. and Other, A. N.}, - TITLE = {Title text}, - MONTH = {January~1}, -}'; - my $result3='@ARTICLE{key01, - Year = {1950}, - Author = {Duck, Donald and Else, Someone}, - Editor = {Itor, E. D. and Other, A. N.}, - Title = {Title text}, - Month = {January~1}, -}'; - my $result4='@article{key01, - year = {1950}, - author = {Duck, Donald and Else, Someone}, - editor = {Itor, E. D. and Other, A. N.}, - title = {Title text}, - month = {January~1}, -}'; - my $result5='@Article{key01, - year = {1950}, - author = {Duck, Donald and Else, Someone}, - editor = {Itor, E. D. and Other, A. N.}, - title = {Title text}, - month = {January~1}, -}'; - is($entry->to_string,$result1); - is($entry->to_string(field_capitalization=>'Lowercase'), - $result1); - is($entry->to_string(field_capitalization=>'Uppercase'), - $result2); - is($entry->to_string(field_capitalization=>'Titlecase'), - $result3); - - is($entry->to_string(type_capitalization=>'Lowercase'), - $result4); - is($entry->to_string(type_capitalization=>'Uppercase'), - $result1); - is($entry->to_string(type_capitalization=>'Titlecase'), - $result5); - } - -} - -done_testing(); - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/01.bib b/support/bibtexperllibs/BibTeX-Parser/t/bibs/01.bib deleted file mode 100644 index 7f6233d177..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/01.bib +++ /dev/null @@ -1,7 +0,0 @@ -@ARTICLE{key01, - year = 1950, - author = {Donald Duck and Someone Else}, - editor = {E. D. Itor and A. N. Other}, - title = {Title text}, - month = jan # "~1" -} diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/06.bib b/support/bibtexperllibs/BibTeX-Parser/t/bibs/06.bib deleted file mode 100644 index 242ae662cc..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/06.bib +++ /dev/null @@ -1,27 +0,0 @@ -this is text, which is ignored by bibtex. - -@PREAMBLE{ - This is only used for BibTeX files used in LaTeX documents -} - -@Comment{ - Comments are ignored too. -} - -@ARTICLE{key1, - author = {Gerhard Gossen and Ludwig van Beethoven}, - title = "Paper title", - year = 2008, - month = aug, -} - -@STRING{ gerhard = "Gerhard" } - -@STRING{ gossen = "Gossen" } - -@BOOK{ key2, - author = gerhard # " " # gossen, - title = "Book title", - year = "2008", - month = aug, -} diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/09-complex.bib b/support/bibtexperllibs/BibTeX-Parser/t/bibs/09-complex.bib deleted file mode 100644 index cacf322723..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/09-complex.bib +++ /dev/null @@ -1,11 +0,0 @@ -@Article{Ahrenberg88, - author = "L. Ahrenberg and A. Jonsson", - title = "An interactive system for tagging dialogues", - journal = "Literary \& Linguistic Computing", - volume = "3", - number = "2", - pages = "66--70", - year = "1988", - keywords = "conver", -} - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/10-funnyname.bib b/support/bibtexperllibs/BibTeX-Parser/t/bibs/10-funnyname.bib deleted file mode 100644 index 050fbc0534..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/10-funnyname.bib +++ /dev/null @@ -1,10 +0,0 @@ -@article{testkey, - year = {2008}, - title = "foo", - author = {A. Bar and L.M. M\"uller}, - journal = {journal}, - volume = {1}, - number = {1}, - pages = {1}, -} - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/14-extratext.bib b/support/bibtexperllibs/BibTeX-Parser/t/bibs/14-extratext.bib deleted file mode 100644 index 56f96aa01b..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/14-extratext.bib +++ /dev/null @@ -1,22 +0,0 @@ -First published in 1947 -@BOOK{Partridge, - AUTHOR="Eric Partridge", - TITLE="Use and Abuse: a Guide to Good {E}nglish", - PUBLISHER="Hamish Hamilton", - EDITION="4", YEAR="1970"} - - -@BOOK{Cooper, - AUTHOR="Bruce M. Cooper", - TITLE="Writing Technical Reports", - PUBLISHER="Penguin", YEAR="1964"} - - - -First published in 1926 -@BOOK{Fowler-ModernEnglish, - AUTHOR="H. W. Fowler", - TITLE="[A Dictionary of] Modern {E}nglish Usage", - PUBLISHER="Oxford University Press", - EDITION="2", YEAR="1965"} - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/braces.bib b/support/bibtexperllibs/BibTeX-Parser/t/bibs/braces.bib deleted file mode 100644 index 3791fb5760..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/braces.bib +++ /dev/null @@ -1,21 +0,0 @@ -@Article{scholkopf98kpca, - author = {Bernhard {Sch\"olkopf} and Alex Smola and K.R. Muller}, - title = {Nonlinear component analysis as a kernel eigenvalue -problem}, - journal = {Neural Computation}, - year = {1998}, - volume = {10}, - pages = {1299--1319} -} - -@article{brownetal93, - author = {Peter F. Brown and Stephen A. {Della Pietra} and - Vincent J. {Della Pietra} and Robert~L. Mercer}, - title = {The Mathematics of Statistical Machine Translation: - Parameter Estimation}, - journal = {Computational Linguistics}, - year = 1993, - volume = 19, - number = 2, - pages = {263-311} -} diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/endnote.txt b/support/bibtexperllibs/BibTeX-Parser/t/bibs/endnote.txt deleted file mode 100644 index e75f1d2050..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/endnote.txt +++ /dev/null @@ -1,6 +0,0 @@ -@article{ - volume = {59}, - number = {6}, - year = {1999} -} - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/engineering_village.txt b/support/bibtexperllibs/BibTeX-Parser/t/bibs/engineering_village.txt deleted file mode 100644 index 256f5a853d..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/engineering_village.txt +++ /dev/null @@ -1,24 +0,0 @@ -@inproceedings{1997493856789 , -language = {English}, -year = {1997}, -} - - -@inproceedings{1998043944915 , -language = {English}, -year = {1997}, -} - - -@article{2003137419501 , -language = {English}, -year = {2002}, -} - - -@inproceedings{2002367072517 , -language = {English}, -year = {2002}, -} - - diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/english.bib b/support/bibtexperllibs/BibTeX-Parser/t/bibs/english.bib deleted file mode 100644 index f0f097409f..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/english.bib +++ /dev/null @@ -1,55 +0,0 @@ -$Id: @(#) english.bib 1.0 23-OCT-1989 17:10:00 Aston archive$ - -Please notify Adrian F Clark <alien@uk.ac.essex.ese> of any additions -or corrections to this list. - -@BOOK{Carey, - AUTHOR="G. V. Carey", - TITLE="Mind the Stop: A Brief Guide to Punctuation", - PUBLISHER="Penguin", YEAR="1958"} - -@BOOK{Cooper, - AUTHOR="Bruce M. Cooper", - TITLE="Writing Technical Reports", - PUBLISHER="Penguin", YEAR="1964"} - -@BOOK{Fowler-ModernEnglish, - AUTHOR="H. W. Fowler", - TITLE="[A Dictionary of] Modern {E}nglish Usage", - PUBLISHER="Oxford University Press", - EDITION="2", YEAR="1965"} - (but first published in 1926) - -@BOOK{Fowler-KingsEnglish, - AUTHOR="H. W. Fowler and F. G. Fowler", - TITLE="The {K}ing's {E}nglish", - PUBLISHER="Oxford University Press", - EDITION="3", YEAR="1931"} - (but first published in 1906) - -@BOOK{Gowers, - AUTHOR="Sir Ernest Gowers", - TITLE="The Complete Plain Words", - PUBLISHER="Penguin", YEAR="1954"} - (but first published by HMSO) - -@BOOK{Hart, - AUTHOR="Horace Hart", - TITLE="[Hart's] Rules for Compositors and Readers - [at the Oxford University Press]", - PUBLISHER="Oxford University Press", - EDITION="39", YEAR="1983"} - (but first published in 1893) - -@BOOK{Partridge, - AUTHOR="Eric Partridge", - TITLE="Use and Abuse: a Guide to Good {E}nglish", - PUBLISHER="Hamish Hamilton", - EDITION="4", YEAR="1970"} - (but first published in 1947) - -@BOOK{Quirk-CompGram, - AUTHOR="Randolph Quirk and Sydney Greenbaum and Geoffrey Leach and - Jan Svartnik", - TITLE="A Comprehensive Grammar of the {E}nglish Language", - PUBLISHER="Longman", YEAR="1985"} diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bibs/mathscinet.txt b/support/bibtexperllibs/BibTeX-Parser/t/bibs/mathscinet.txt deleted file mode 100644 index eea5a05a70..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bibs/mathscinet.txt +++ /dev/null @@ -1,40 +0,0 @@ -MathSciNet </mathscinet/index.html> - - * - Clipboard </mathscinet/clipboard.html> - * Home </mathscinet/index.html> - * Preferences </mathscinet/preferences.html> - * Help </mathscinet/help/headline_review_help_full.html> - * Support Mail </mathscinet/support_mail.html> - * Terms of Use </mathscinet/help/mathscinet_terms_of_use.html> - * University of Southampton - -@article {MR2254280, - VOLUME = {23}, - YEAR = {2006}, -} - - -@article {MR2254274, - VOLUME = {23}, - YEAR = {2006}, -} - - -@article {MR2248052, - VOLUME = {23}, - YEAR = {2006}, -} - - -*Matches:* 3 -Mirror Sites - - -© Copyright 2011, American Mathematical Society -<http://www.ams.org/ams/copyright.html> -Privacy Statement <http://www.ams.org/ams/privacy.html> -American Mathematical Society <http://www.ams.org> -American Mathematical Society -201 Charles Street -Providence, RI 02904-2294 diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bug66325.t b/support/bibtexperllibs/BibTeX-Parser/t/bug66325.t deleted file mode 100644 index ac83b43aa9..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bug66325.t +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More; - -use BibTeX::Parser; -use IO::File; - -{ - my $fh = new IO::File "t/bibs/endnote.txt", "r" ; - - if (defined $fh) { - my $parser = new BibTeX::Parser $fh; - - while (my $entry = $parser->next) { - isa_ok($entry, "BibTeX::Parser::Entry"); - ok($entry->parse_ok, "parse_ok"); - is($entry->key, undef, "key"); - is($entry->type, "ARTICLE", "type"); - is($entry->field("year"), 1999, "field"); - is($entry->field("volume"), 59, "first field"); - } - } -} - -{ - my $fh = new IO::File "t/bibs/mathscinet.txt", "r" ; - my @keys = qw(MR2254280 MR2254274 MR2248052); - - if (defined $fh) { - my $parser = new BibTeX::Parser $fh; - my $count = 0; - - while (my $entry = $parser->next) { - isa_ok($entry, "BibTeX::Parser::Entry"); - ok($entry->parse_ok, "parse_ok"); - is($entry->key, $keys[$count], "key"); - is($entry->type, "ARTICLE", "type"); - is($entry->field("volume"), 23, "first field"); - is($entry->field("year"), 2006, "field"); - $count++; - } - - is($count, 3, "number of entries"); - } -} - -{ - my $fh = new IO::File "t/bibs/engineering_village.txt", "r" ; - - my @types = qw( inproceedings inproceedings article inproceedings ); - my @keys = qw( 1997493856789 1998043944915 2003137419501 2002367072517 ); - my @years = qw( 1997 1997 2002 2002 ); - - if (defined $fh) { - my $parser = new BibTeX::Parser $fh; - my $count = 0; - - while (my $entry = $parser->next) { - isa_ok($entry, "BibTeX::Parser::Entry"); - ok($entry->parse_ok, "parse_ok"); - is($entry->key, $keys[$count], "key"); - is($entry->type, uc $types[$count], "type"); - is($entry->field("language"), "English", "first field"); - is($entry->field("year"), $years[$count], "field"); - $count++; - } - - is($count, 4, "number of entries"); - } -} -done_testing; diff --git a/support/bibtexperllibs/BibTeX-Parser/t/bug67419.t b/support/bibtexperllibs/BibTeX-Parser/t/bug67419.t deleted file mode 100644 index 0f944f373a..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/bug67419.t +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/perl -w - -use Test::More; - -use BibTeX::Parser; -use IO::File; - -my $fh = new IO::File "t/bibs/braces.bib", "r" ; -my $parser = new BibTeX::Parser $fh; -while (my $entry=$parser->next) { - is($entry->parse_ok,1); - if ($entry->key eq 'scholkopf98kpca') { - @authors=$entry->author; - is(scalar @authors,3); - is("$authors[0]", '{Sch\"olkopf}, Bernhard'); - is("$authors[1]", 'Smola, Alex'); - is("$authors[2]", 'Muller, K.R.'); - } - if ($entry->key eq 'brownetal93') { - @authors=$entry->author; - is(scalar @authors,4); - is("$authors[0]", 'Brown, Peter F.'); - is("$authors[1]", '{Della Pietra}, Stephen A.'); - is("$authors[2]", '{Della Pietra}, Vincent J.'); - is("$authors[3]", 'Mercer, Robert~L.'); - } -} - -done_testing(); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/cleaned_field.t b/support/bibtexperllibs/BibTeX-Parser/t/cleaned_field.t deleted file mode 100644 index 980fb1d60d..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/cleaned_field.t +++ /dev/null @@ -1,143 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use utf8; - -use Test::More; -use BibTeX::Parser::Entry; - -sub new_entry { - BibTeX::Parser::Entry->new( 'ARTICLE', 'Foo2010', 1, { @_ } ); -} -{ - my @german_tests = ( - [ '"a' => 'ä' ], - ['"`' => '„' ], - ["\"'" => '“' ], - ); - - foreach my $test ( @german_tests ) { - my $entry = new_entry( foo => $test->[0] ); - is( $entry->cleaned_field( 'foo', german => 1 ), $test->[1], "Convert $test->[0], german => 1" ); - } -} - -{ - binmode( DATA, ':utf8' ); - while (<DATA>) { - chomp; - my ( $tex, $result ) = split /\t/; - is( new_entry( foo => $tex )->cleaned_field( 'foo' ), $result, "Convert $tex" ); - } - close DATA; -} - -{ - my $entry_with_authors = new_entry( author => 'F{\"o}o Bar and B"ar, F.' ); - my @authors = $entry_with_authors->author; - is( scalar @authors, 2, "Number of authors is correct"); - is( $authors[0]->first, 'F{\"o}o', "non-cleaned version of first" ); - is( $authors[0]->last, 'Bar', "non-cleaned version of last" ); - - is( $authors[1]->first, 'F.', "non-cleaned version of first" ); - is( $authors[1]->last, 'B"ar', "non-cleaned version of last" ); - - my @clean_authors = $entry_with_authors->cleaned_author; - is( $clean_authors[0]->first, 'Föo', "cleaned version of first" ); - is( $clean_authors[0]->last, 'Bar', "cleaned version of last" ); - - is( $clean_authors[1]->first, 'F.', "cleaned version of first" ); - is( $clean_authors[1]->last, 'B"ar', "cleaned version of last" ); -} -done_testing; - -__DATA__ -\# # -\& & -{\`a} à -{\^a} â -{\~a} ã -{\'a} á -{\'{a}} á -{\"a} ä -{\`A} À -{\'A} Á -{\"A} Ä -{\aa} å -{\AA} Å -{\ae} æ -{\bf 12} 12 -{\'c} ć -{\cal P} P -{\c{c}} ç -{\c{C}} Ç -{\c{e}} ȩ -{\c{s}} ş -{\c{S}} Ş -{\c{t}} ţ -{\-d} d -{\`e} è -{\^e} ê -{\'e} é -{\"e} ë -{\'E} É -{\em bits} bits -{\H{o}} ő -{\`i} ì -{\^i} î -{\i} ı -{\`i} ì -{\'i} í -{\"i} ï -{\`\i} ì -{\'\i} í -{\"\i} ï -{\`{\i}} ì -{\'{\i}} í -{\"{\i}} ï -{\it Note} Note -{\k{e}} ę -{\l} ł -{\-l} l -{\log} log -{\~n} ñ -{\'n} ń -{\^o} ô -{\o} ø -{\'o} ó -{\"o} ö -{\"{o}} ö -{\'O} Ó -{\"O} Ö -{\"{O}} Ö -{\rm always} always -{\-s} s -{\'s} ś -{\sc JoiN} JoiN -{\sl bit\/ \bf 7} bit 7 -{\sl L'Informatique Nouvelle} L’Informatique Nouvelle -{\small and} and -{\ss} ß -{\TeX} TeX -{\TM} ™ -{\tt awk} awk -{\^u} û -{\'u} ú -{\"u} ü -{\"{u}} ü -{\'U} Ú -{\"U} Ü -{\u{a}} ă -{\u{g}} ğ -{\v{c}} č -{\v{C}} Č -{\v{e}} ě -{\v{n}} ň -{\v{r}} ř -{\v{s}} š -{\v{S}} Š -{\v{z}} ž -{\v{Z}} Ž -{\'y} ý -{\.{z}} ż diff --git a/support/bibtexperllibs/BibTeX-Parser/t/pod-coverage.t b/support/bibtexperllibs/BibTeX-Parser/t/pod-coverage.t deleted file mode 100644 index fc40a57c2a..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/pod-coverage.t +++ /dev/null @@ -1,18 +0,0 @@ -use strict; -use warnings; -use Test::More; - -# Ensure a recent version of Test::Pod::Coverage -my $min_tpc = 1.08; -eval "use Test::Pod::Coverage $min_tpc"; -plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" - if $@; - -# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, -# but older versions don't recognize some common documentation styles -my $min_pc = 0.18; -eval "use Pod::Coverage $min_pc"; -plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" - if $@; - -all_pod_coverage_ok(); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/pod.t b/support/bibtexperllibs/BibTeX-Parser/t/pod.t deleted file mode 100644 index e22a39b524..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/pod.t +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -use warnings; -use Test::More; - -# Ensure a recent version of Test::Pod -my $min_tp = 1.22; -eval "use Test::Pod $min_tp"; -plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; - -all_pod_files_ok(); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/release-pod-coverage.t b/support/bibtexperllibs/BibTeX-Parser/t/release-pod-coverage.t deleted file mode 100644 index 3a818499f0..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/release-pod-coverage.t +++ /dev/null @@ -1,21 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - - -use Test::More; - -eval "use Test::Pod::Coverage 1.08"; -plan skip_all => "Test::Pod::Coverage 1.08 required for testing POD coverage" - if $@; - -eval "use Pod::Coverage::TrustPod"; -plan skip_all => "Pod::Coverage::TrustPod required for testing POD coverage" - if $@; - -all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); diff --git a/support/bibtexperllibs/BibTeX-Parser/t/release-pod-syntax.t b/support/bibtexperllibs/BibTeX-Parser/t/release-pod-syntax.t deleted file mode 100644 index d46a955694..0000000000 --- a/support/bibtexperllibs/BibTeX-Parser/t/release-pod-syntax.t +++ /dev/null @@ -1,15 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - -use Test::More; - -eval "use Test::Pod 1.41"; -plan skip_all => "Test::Pod 1.41 required for testing POD" if $@; - -all_pod_files_ok(); diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/Changes b/support/bibtexperllibs/LaTeX-ToUnicode/Changes deleted file mode 100644 index 3db5c19724..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/Changes +++ /dev/null @@ -1,27 +0,0 @@ -Changes for LaTeX::ToUnicode - -0.54 2023-11-17 Better handling of \{ \}. New release - -0.53 2023-08-20 Tests fixed, new release - -0.52 2022-11-07 Support many more control sequences, \kern removal, - \<newline>, etc. Add ltxunitxt script to access functionality - from command line. - -0.11 2020-12-12 Updates and cleaing - -0.05 2016-11-23 02:28:35+00:00 - Compatibility with perl 5.25 (Alexandr Ciornii) - -0.04 2015-12-25 19:16:41+00:00 - Macrons are handled properly - -0.03 2010-10-18 18:04:14 - Specify minimal perl version (5.8.0) for UTF-8 support - -0.02 2010/07/09 - Handle accents with \i - Add script used to generate accents table - -0.01 2010/07/09 - First release. diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/LICENSE b/support/bibtexperllibs/LaTeX-ToUnicode/LICENSE deleted file mode 100644 index c3402b3869..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/LICENSE +++ /dev/null @@ -1,375 +0,0 @@ -Copyright 2010-2023 Gerhard Gossen, Boris Veytsman, Karl Berry - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. - -Terms of the Perl programming language system itself - -a) the GNU General Public License as published by the Free - Software Foundation; either version 1, or (at your option) any - later version, or -b) the "Artistic License" - ---- The GNU General Public License, Version 1, February 1989 --- - -This is free software, licensed under: - - The GNU General Public License, Version 1, February 1989 - - GNU GENERAL PUBLIC LICENSE - Version 1, February 1989 - - Copyright (C) 1989 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The license agreements of most software companies try to keep users -at the mercy of those companies. By contrast, our General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. The -General Public License applies to the Free Software Foundation's -software and to any other program whose authors commit to using it. -You can use it for your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Specifically, the General Public License is designed to make -sure that you have the freedom to give away or sell copies of free -software, that you receive source code or can get it if you want it, -that you can change the software or use pieces of it in new free -programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of a such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any program or other work which -contains a notice placed by the copyright holder saying it may be -distributed under the terms of this General Public License. The -"Program", below, refers to any such program or work, and a "work based -on the Program" means either the Program or any work containing the -Program or a portion of it, either verbatim or with modifications. Each -licensee is addressed as "you". - - 1. You may copy and distribute verbatim copies of the Program's source -code as you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and -disclaimer of warranty; keep intact all the notices that refer to this -General Public License and to the absence of any warranty; and give any -other recipients of the Program a copy of this General Public License -along with the Program. You may charge a fee for the physical act of -transferring a copy. - - 2. You may modify your copy or copies of the Program or any portion of -it, and copy and distribute such modifications under the terms of Paragraph -1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating that - you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, that - in whole or in part contains the Program or any part thereof, either - with or without modifications, to be licensed at no charge to all - third parties under the terms of this General Public License (except - that you may choose to grant warranty protection to some or all - third parties, at your option). - - c) If the modified program normally reads commands interactively when - run, you must cause it, when started running for such interactive use - in the simplest and most usual way, to print or display an - announcement including an appropriate copyright notice and a notice - that there is no warranty (or else, saying that you provide a - warranty) and that users may redistribute the program under these - conditions, and telling the user how to view a copy of this General - Public License. - - d) You may charge a fee for the physical act of transferring a - copy, and you may at your option offer warranty protection in - exchange for a fee. - -Mere aggregation of another independent work with the Program (or its -derivative) on a volume of a storage or distribution medium does not bring -the other work under the scope of these terms. - - 3. You may copy and distribute the Program (or a portion or derivative of -it, under Paragraph 2) in object code or executable form under the terms of -Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal charge - for the cost of distribution) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - -Source code for a work means the preferred form of the work for making -modifications to it. For an executable file, complete source code means -all the source code for all modules it contains; but, as a special -exception, it need not include source code for modules which are standard -libraries that accompany the operating system on which the executable -file runs, or for standard header files or definitions files that -accompany that operating system. - - 4. You may not copy, modify, sublicense, distribute or transfer the -Program except as expressly provided under this General Public License. -Any attempt otherwise to copy, modify, sublicense, distribute or transfer -the Program is void, and will automatically terminate your rights to use -the Program under this License. However, parties who have received -copies, or rights to use copies, from you under this General Public -License will not have their licenses terminated so long as such parties -remain in full compliance. - - 5. By copying, distributing or modifying the Program (or any work based -on the Program) you indicate your acceptance of this license to do so, -and all its terms and conditions. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the original -licensor to copy, distribute or modify the Program subject to these -terms and conditions. You may not impose any further restrictions on the -recipients' exercise of the rights granted herein. - - 7. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of the license which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -the license, you may choose any version ever published by the Free Software -Foundation. - - 8. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS 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. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to humanity, the best way to achieve this is to make it -free software which everyone can redistribute and change under these -terms. - - To do so, attach the following notices to the program. It is safest to -attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 1, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19xx name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the -appropriate parts of the General Public License. Of course, the -commands you use may be called something other than `show w' and `show -c'; they could even be mouse-clicks or menu items--whatever suits your -program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - program `Gnomovision' (a program to direct compilers to make passes - at assemblers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -That's all there is to it! - - ---- The Artistic License 1.0 --- - -This software is Copyright (c) 2010 by Gerhard Gossen. - -This is free software, licensed under: - - The Artistic License 1.0 - -The Artistic License - -Preamble - -The intent of this document is to state the conditions under which a Package -may be copied, such that the Copyright Holder maintains some semblance of -artistic control over the development of the package, while giving the users of -the package the right to use and distribute the Package in a more-or-less -customary fashion, plus the right to make reasonable modifications. - -Definitions: - - - "Package" refers to the collection of files distributed by the Copyright - Holder, and derivatives of that collection of files created through - textual modification. - - "Standard Version" refers to such a Package if it has not been modified, - or has been modified in accordance with the wishes of the Copyright - Holder. - - "Copyright Holder" is whoever is named in the copyright or copyrights for - the package. - - "You" is you, if you're thinking about copying or distributing this Package. - - "Reasonable copying fee" is whatever you can justify on the basis of media - cost, duplication charges, time of people involved, and so on. (You will - not be required to justify it to the Copyright Holder, but only to the - computing community at large as a market that must bear the fee.) - - "Freely Available" means that no fee is charged for the item itself, though - there may be fees involved in handling the item. It also means that - recipients of the item may redistribute it under the same conditions they - received it. - -1. You may make and give away verbatim copies of the source form of the -Standard Version of this Package without restriction, provided that you -duplicate all of the original copyright notices and associated disclaimers. - -2. You may apply bug fixes, portability fixes and other modifications derived -from the Public Domain or from the Copyright Holder. A Package modified in such -a way shall still be considered the Standard Version. - -3. You may otherwise modify your copy of this Package in any way, provided that -you insert a prominent notice in each changed file stating how and when you -changed that file, and provided that you do at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise make them - Freely Available, such as by posting said modifications to Usenet or an - equivalent medium, or placing the modifications on a major archive site - such as ftp.uu.net, or by allowing the Copyright Holder to include your - modifications in the Standard Version of the Package. - - b) use the modified Package only within your corporation or organization. - - c) rename any non-standard executables so the names do not conflict with - standard executables, which must also be provided, and provide a separate - manual page for each non-standard executable that clearly documents how it - differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -4. You may distribute the programs of this Package in object code or executable -form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library files, - together with instructions (in the manual page or equivalent) on where to - get the Standard Version. - - b) accompany the distribution with the machine-readable source of the Package - with your modifications. - - c) accompany any non-standard executables with their corresponding Standard - Version executables, giving the non-standard executables non-standard - names, and clearly documenting the differences in manual pages (or - equivalent), together with instructions on where to get the Standard - Version. - - d) make other distribution arrangements with the Copyright Holder. - -5. You may charge a reasonable copying fee for any distribution of this -Package. You may charge any fee you choose for support of this Package. You -may not charge a fee for this Package itself. However, you may distribute this -Package in aggregate with other (possibly commercial) programs as part of a -larger (possibly commercial) software distribution provided that you do not -advertise this Package as a product of your own. - -6. The scripts and library files supplied as input to or produced as output -from the programs of this Package do not automatically fall under the copyright -of this Package, but belong to whomever generated them, and may be sold -commercially, and may be aggregated with this Package. - -7. C or perl subroutines supplied by you and linked into this Package shall not -be considered part of this Package. - -8. The name of the Copyright Holder may not be used to endorse or promote -products derived from this software without specific prior written permission. - -9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -The End - diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/MANIFEST b/support/bibtexperllibs/LaTeX-ToUnicode/MANIFEST deleted file mode 100644 index 2aa0688c10..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/MANIFEST +++ /dev/null @@ -1,17 +0,0 @@ -LICENSE -Changes -MANIFEST -t/release-pod-coverage.t -t/release-pod-syntax.t -t/convert.t -t/release-synopsis.t -README -script/ltx2unitxt -script/convert.pl -lib/LaTeX/ToUnicode/Tables.pm -lib/LaTeX/ToUnicode.pm -Makefile.PL -head.ltx -Makefile.TDS -weaver.ini -dist.ini diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/Makefile.PL b/support/bibtexperllibs/LaTeX-ToUnicode/Makefile.PL deleted file mode 100644 index 7aa2b21234..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/Makefile.PL +++ /dev/null @@ -1,51 +0,0 @@ - -use strict; -use warnings; - -BEGIN { require 5.8.0; } - -use ExtUtils::MakeMaker 6.31; - - - -my %WriteMakefileArgs = ( - 'ABSTRACT' => 'Convert LaTeX commands to Unicode', - 'AUTHOR' => 'Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.com>', - 'BUILD_REQUIRES' => { - 'Pod-LaTeX' => '0.61' - }, - 'CONFIGURE_REQUIRES' => { - 'ExtUtils::MakeMaker' => '6.31' - }, - 'DISTNAME' => 'LaTeX-ToUnicode', - 'EXE_FILES' => ['script/ltx2unitxt'], - 'LICENSE' => 'perl', - 'NAME' => 'LaTeX::ToUnicode', - 'PREREQ_PM' => {}, - 'VERSION_FROM' => 'lib/LaTeX/ToUnicode.pm', - 'test' => { - 'TESTS' => 't/*.t' - } -); - - -unless ( eval { ExtUtils::MakeMaker->VERSION(6.56) } ) { - my $br = delete $WriteMakefileArgs{BUILD_REQUIRES}; - my $pp = $WriteMakefileArgs{PREREQ_PM}; - for my $mod ( keys %$br ) { - if ( exists $pp->{$mod} ) { - $pp->{$mod} = $br->{$mod} if $br->{$mod} > $pp->{$mod}; - } - else { - $pp->{$mod} = $br->{$mod}; - } - } -} - -delete $WriteMakefileArgs{CONFIGURE_REQUIRES} - unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; - -WriteMakefile(%WriteMakefileArgs); - - - diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/Makefile.TDS b/support/bibtexperllibs/LaTeX-ToUnicode/Makefile.TDS deleted file mode 100644 index 4255cfa6b6..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/Makefile.TDS +++ /dev/null @@ -1,53 +0,0 @@ -# -# This is Makefile for TDS-compliant TeX distributions -# Written by Boris Veytsman, boris@varphi.com -# -# This file is in public domain -# -PREFIX = /usr/local - -LIBDIR = $(PREFIX)/scripts/bibtexperllibs - -DOCDIR = $(PREFIX)/doc/bibtex/bibtexperllibs - -DOCS = latex-tounicode.pdf ltx2unitxt.pdf ltx2unitxt.1 - -all: - -docs: $(DOCS) - -latex-tounicode.pdf: latex-tounicode.tex ltx2unitxt.pdf - texfot pdflatex $< || { rm -f $@; exit 1; } - -ToUnicode = lib/LaTeX/ToUnicode - -latex-tounicode.tex: $(ToUnicode).pm $(ToUnicode)/Tables.pm - pod2latex -modify -full -prefile head.ltx -out $@ $^ - -latex-tounicode.tex: head.ltx -# unfortunately pod2latex doesn't recognize =encoding, so there -# are two warnings of "Command encoding not recognised ...". Oh well. - -ltx2unitxt.1: script/ltx2unitxt -# don't run --version since the --help message includes --version output. - help2man --no-info --version-string=" " \ ---name="convert LaTeX source fragment to plain (Unicode) text or simple html" \ - $< >$@ \ - || { rm -f $@; exit 1; } -ltx2unitxt.pdf: ltx2unitxt.1 - sed 's/^Releases:/\nReleases:/' $< | groff -man -t -rS11 - | ps2pdf - $@ - -force: - -install: all docs - mkdir -p $(LIBDIR) - cp -r lib/* $(LIBDIR) - mkdir -p $(DOCDIR) - cp -r man/man3/* $(DOCDIR) - cp -r latex-tounicode.pdf ltx2unitxt.pdf ltx2unitxt.1 $(DOCDIR) - -clean: - $(RM) *.log *.aux *.out *.toc latex-tounicode.tex *.tar.gz - -distclean: clean - $(RM) $(DOCS)
\ No newline at end of file diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/README b/support/bibtexperllibs/LaTeX-ToUnicode/README deleted file mode 100644 index 1f241e3979..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/README +++ /dev/null @@ -1,13 +0,0 @@ -This is the LaTeX::ToUnicode Perl package: - - Convert LaTeX source fragments to Unicode plain text or simple html - -Dev sources, bug tracker: https://github.com/borisveytsman/bibtexperllibs -Releases: https://ctan.org/pkg/bibtexperllibs - -Copyright 2010-2022 Gerhard Gossen, Boris Veytsman, Karl Berry - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl5 programming language system itself. - - diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/dist.ini b/support/bibtexperllibs/LaTeX-ToUnicode/dist.ini deleted file mode 100644 index 5c038d1985..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/dist.ini +++ /dev/null @@ -1,16 +0,0 @@ -name = LaTeX-ToUnicode -author = Gerhard Gossen <gerhard.gossen@googlemail.com> and Boris Veytsman <boris@varphi.com> and Karl Berry <karl@freefriends.org> -license = Perl_5 -copyright_holder = Gerhard Gossen and Boris Veytsman -copyright_year = 2010-2023 -version = 0.53 - -[@Classic] -[Prereqs] -perl = 5.8.0 -[NextRelease] -format = %-7v %{yyyy-MM-dd HH:mm:ss}d -[PodWeaver] -[Repository] -[@Git] -[SynopsisTests] diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/head.ltx b/support/bibtexperllibs/LaTeX-ToUnicode/head.ltx deleted file mode 100644 index 3f946fcba0..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/head.ltx +++ /dev/null @@ -1,28 +0,0 @@ -% documentation for LaTeX::ToUnicode. -% head.ltx file public domain. -% -\documentclass[11pt]{article} -\usepackage{fullpage,pdfpages} -\usepackage[hidelinks]{hyperref} -\let\printindex=\empty % index is not useful -\sloppy \hbadness=3000 % not aiming for good typesetting - -% Silence useless font warning about braces in cmsy instead of cmtt: -\makeatletter\def\@font@warning#1{}\makeatother - -% https://tex.stackexchange.com/questions/68272 -\newcommand\invisiblesection[1]{% - \refstepcounter{section}% - \addcontentsline{toc}{section}{\protect\numberline{\thesection}#1}% - \sectionmark{#1}% -} - -\begin{document} -\title{\texttt{LaTeX::ToUnicode} documentation} -\author{Boris Veytsman\thanks{borisv@lk.net}} -\maketitle -\tableofcontents - -\invisiblesection{ltx2unitxt---convert \LaTeX\ source fragments} - -\includepdf[pages=-]{ltx2unitxt} diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/latex-tounicode.pdf b/support/bibtexperllibs/LaTeX-ToUnicode/latex-tounicode.pdf Binary files differdeleted file mode 100644 index b319b6ebcb..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/latex-tounicode.pdf +++ /dev/null diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode.pm b/support/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode.pm deleted file mode 100644 index 1759a6acd6..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode.pm +++ /dev/null @@ -1,778 +0,0 @@ -use strict; -use warnings; -package LaTeX::ToUnicode; -BEGIN { - $LaTeX::ToUnicode::VERSION = '0.54'; -} -#ABSTRACT: Convert LaTeX commands to Unicode (simplistically) - -require Exporter; -our @ISA = qw(Exporter); -our @EXPORT_OK = qw( convert debuglevel $endcw ); - -use utf8; -use Encode; -use LaTeX::ToUnicode::Tables; - -# Terminating a control word (not symbol) the way TeX does: at the -# boundary between a letter (lookbehind) and a nonletter (lookahead), -# and then ignore any following whitespace. -our $endcw = qr/(?<=[a-zA-Z])(?=[^a-zA-Z]|$)\s*/; - -# all we need for is debugging being on and off. And it's pretty random -# what gets output. -my $debug = 0; - -sub debuglevel { $debug = shift; } -sub _debug { - return unless $debug; - # The backtrace info is split between caller(0) and caller(1), sigh. - # We don't need the package name, it's included in $subr in practice. - my (undef,$filename,$line,undef) = caller(0); - my (undef,undef,undef,$subr) = caller(1); - warn @_, " at $filename:$line ($subr)\n"; -} - -# The main conversion function. -# -sub convert { - my ($string, %options) = @_; - #warn debug_hash_as_string("starting with: $string", %options); - - # First, remove leading and trailing horizontal whitespace - # on each line of the possibly-multiline string we're given. - $string =~ s/^[ \t]*//m; - $string =~ s/[ \t]*$//m; - - # For HTML output, must convert special characters that were in the - # TeX text (&<>) to their entities to avoid misparsing. We want to - # do this first, because conversion of the markup commands might - # output HTML tags like <tt>, and we don't want to convert those <>. - # Although <tt> works, better to keep the output HTML as - # human-readable as we can. - # - if ($options{html}) { - $string =~ s/([^\\]|^)&/$1&/g; - $string =~ s/</</g; - $string =~ s/>/>/g; - } - - my $user_hook = $options{hook}; - if ($user_hook) { - $string = &$user_hook($string, \%options); - _debug("after user hook: $string"); - } - - # Convert general commands that take arguments, since (1) they might - # insert TeX commands that need to be converted, and (2) because - # their arguments could well contain constructs that will map to a - # Perl string \x{nnnn} for Unicode character nnnn; those Perl braces - # for the \x will confuse further parsing of the TeX. - # - $string = _convert_commands_with_arg($string); - _debug("after commands with arg: $string"); - - # Convert markups (\texttt, etc.); they have the same brace-parsing issue. - $string = _convert_markups($string, \%options); - _debug("after markups: $string"); - - # And urls, a special case of commands with arguments. - $string = _convert_urls($string, \%options); - _debug("after urls: $string"); - - $string = _convert_control_words($string); - _debug("after control words: $string"); - - $string = _convert_control_symbols($string); - _debug("after control symbols: $string"); - - $string = _convert_accents($string); - $string = _convert_german($string) if $options{german}; - $string = _convert_symbols($string); - $string = _convert_ligatures($string); - - # Let's handle ties here, after all the other conversions, since - # they don't fit well with any of the tables. - # - # /~, or ~ at the beginning of a line, is probably part of a url or - # path, not a tie. Otherwise, consider it a space, since a no-break - # spot in TeX is most likely fine to break in text or HTML. - # - $string =~ s,([^/])~,$1 ,g; - - # Remove kerns. Clearly needs generalizing/sharpening to recognize - # dimens better, and plenty of other commands could use it. - #_debug("before kern: $string"); - my $dimen_re = qr/[-+]?[0-9., ]+[a-z][a-z]\s*/; - $string =~ s!\\kern${endcw}${dimen_re}!!g; - - # What the heck, let's do \hfuzz and \vfuzz too. They come up pretty - # often and practically the same thing (plus ignore optional =).. - $string =~ s!\\[hv]fuzz${endcw}=?\s*${dimen_re}!!g; - - # After all the conversions, $string contains \x{....} constructs - # (Perl Unicode characters) where translations have happened. Change - # those to the desired output format. Thus we assume that the - # Unicode \x{....}'s are not themselves involved in further - # translations, which is, so far, true. - # - if (! $options{entities}) { - # Convert our \x strings from Tables.pm to the binary characters. - - # As an extra-special case, we want to preserve the translation of - # \{ and \} as 007[bd] entities even if the --entities option is - # not give; otherwise they'd get eliminated like all other braces. - # Use a temporary cs \xx to keep them marked, and don't use braces - # to delimit the argument since they'll get deleted. - $string =~ s/\\x\{(007[bd])\}/\\xx($1)/g; - - # Convert all other characters to characters. - # Assume exactly four hex digits, since we wrote Tables.pm that way. - $string =~ s/\\x\{(....)\}/ pack('U*', hex($1))/eg; - - } elsif ($options{entities}) { - # Convert the XML special characters that appeared in the input, - # e.g., from a TeX \&. Unless we're generating HTML output, in - # which case they have already been converted. - if (! $options{html}) { - $string =~ s/&/&/g; - $string =~ s/</</g; - $string =~ s/>/>/g; - } - - # Our values in Tables.pm are simple ASCII strings \x{....}, - # so we can replace them with hex entities with no trouble. - # Fortunately TeX does not have a standard \x control sequence. - $string =~ s/\\x\{(....)\}/&#x$1;/g; - - # The rest of the job is about binary Unicode characters in the - # input. We want to transform them into entities also. As always - # in Perl, there's more than one way to do it, and several are - # described here, just for the fun of it. - my $ret = ""; - # - # decode_utf8 is described in https://perldoc.perl.org/Encode. - # Without the decode_utf8, all of these methods output each byte - # separately; apparently $string is a byte string at this point, - # not a Unicode string. I don't know why that is. - $ret = decode_utf8($string); - # - # Transform everything that's not printable ASCII or newline into - # entities. - $ret =~ s/([^ -~\n])/ sprintf("&#x%04x;", ord($1)) /eg; - # - # This method leaves control characters as literal; doesn't matter - # for XML output, since control characters aren't allowed, but - # let's use the regexp method anyway. - #$ret = encode("ascii", decode_utf8($string), Encode::FB_XMLCREF); - # - # The nice_string function from perluniintro also works. - # - # This fails, just outputs numbers (that is, ord values): - # foreach my $c (unpack("U*", $ret)) { - # - # Without the decode_utf8, outputs each byte separately. - # With the decode_utf8, works, but the above seems cleaner. - #foreach my $c (split(//, $ret)) { - # if (ord($c) <= 31 || ord($c) >= 128) { - # $ret .= sprintf("&#x%04x;", ord($c)); - # } else { - # $ret .= $c; - # } - #} - # - $string = $ret; # assigned from above. - } - - if ($string =~ /\\x\{/) { - warn "LaTeX::ToUnicode::convert: untranslated \\x remains: $string\n"; - warn "LaTeX::ToUnicode::convert: please report as bug.\n"; - } - - # Drop all remaining braces. - $string =~ s/[{}]//g; - - if (! $options{entities}) { - # With all the other braces gone, now we can convert the preserved - # brace entities from \{ and \} to actual braces. - $string =~ s/\\xx\((007[bd])\)/ pack('U*', hex($1))/eg; - } - - # Backslashes might remain. Don't remove them, as it makes for a - # useful way to find unhandled commands. - - # leave newlines alone, but trim spaces and tabs. - $string =~ s/^[ \t]+//s; # remove leading whitespace - $string =~ s/[ \t]+$//s; # remove trailing whitespace - $string =~ s/[ \t]+/ /gs; # collapse all remaining whitespace to one space - - $string; -} - -# Convert commands that take a single braced argument. The table -# defines text we're supposed to insert before and after the argument. -# We let future processing handle conversion of both the inserted text -# and the argument. -# -sub _convert_commands_with_arg { - my $string = shift; - - foreach my $cmd ( keys %LaTeX::ToUnicode::Tables::ARGUMENT_COMMANDS ) { - my $repl = $LaTeX::ToUnicode::Tables::ARGUMENT_COMMANDS{$cmd}; - my $lft = $repl->[0]; # ref to two-element list - my $rht = $repl->[1]; - # \cmd{foo} -> LFT foo RHT - $string =~ s/\\$cmd${endcw}\{(.*?)\}/$lft$1$rht/g; - #warn "replaced arg $cmd, yielding $string\n"; - } - - $string; -} - -# Convert url commands in STRING. This is a special case of commands -# with arguments: \url{u} and \href{u}{desc text}. The HTML output -# (generated if $OPTIONS{html} is set) is just too special to be handled -# in a table; further, \href is the only two-argument command we are -# currently handling. -# -sub _convert_urls { - my ($string,$options) = @_; - - if ($options->{html}) { - # HTML output. - # \url{URL} -> <a href="URL">URL</a> - $string =~ s,\\url$endcw\{([^}]*)\} - ,<a href="$1">$1</a>,gx; - # - # \href{URL}{TEXT} -> <a href="URL">TEXT</a> - $string =~ s,\\href$endcw\{([^}]*)\}\s*\{([^}]*)\} - ,<a href="$1">$2</a>,gx; - - } else { - # plain text output. - # \url{URL} -> URL - $string =~ s/\\url$endcw\{([^}]*)\}/$1/g; - # - # \href{URL}{TEXT} -> TEXT (URL) - # but, as a special case, if URL ends with TEXT, just output URL, - # as in: - # \href{https://doi.org/10/fjzzc8}{10/fjzzc8} - # -> - # https://doi.org/10/fjzzc8 - # - # Yet more specialness: the TEXT might have extra braces, as in - # \href{https://doi.org/10/fjzzc8}{{10/fjzzc8}} - # left over from previous markup commands (\path) which got - # removed. We want to accept and ignore such extra braces, - # hence the \{+ ... \}+ in recognizing TEXT. - # -#warn "txt url: starting with $string\n"; - if ($string =~ m/\\href$endcw\{([^}]*)\}\s*\{+([^}]*)\}+/) { - my $url = $1; - my $text = $2; -#warn " url: $url\n"; -#warn " text: $text\n"; - my $repl = ($url =~ m!$text$!) ? $url : "$text ($url)"; -#warn " repl: $repl\n"; - $string =~ s/\\href$endcw\{([^}]*)\}\s*\{+([^}]*)\}+/$repl/; -#warn " str: $string\n"; - } - } - - $string; -} - -# Convert control words (not symbols), that is, a backslash and an -# alphabetic sequence of characters terminated by a non-alphabetic -# character. Following whitespace is ignored. -# -sub _convert_control_words { - my $string = shift; - - foreach my $command ( keys %LaTeX::ToUnicode::Tables::CONTROL_WORDS ) { - my $repl = $LaTeX::ToUnicode::Tables::CONTROL_WORDS{$command}; - # replace {\CMD}, whitespace ignored after \CMD. - $string =~ s/\{\\$command$endcw\}/$repl/g; - - # replace \CMD, preceded by not-consumed non-backslash. - $string =~ s/(?<=[^\\])\\$command$endcw/$repl/g; - - # replace \CMD at beginning of whole string, which otherwise - # wouldn't be matched. Two separate regexps to avoid - # variable-length lookbehind. - $string =~ s/^\\$command$endcw/$repl/g; - } - - $string; -} - -# Convert control symbols, other than accents. Much simpler than -# control words, since are self-delimiting, don't take arguments, and -# don't consume any following text. -# -sub _convert_control_symbols { - my $string = shift; - - foreach my $symbol ( keys %LaTeX::ToUnicode::Tables::CONTROL_SYMBOLS ) { - my $repl = $LaTeX::ToUnicode::Tables::CONTROL_SYMBOLS{$symbol}; - - # because these are not alphabetic, we can quotemeta them, - # and we need to because "\" is one of the symbols. - my $rx = quotemeta($symbol); - - # the preceding character must not be a backslash, else "\\ " - # could have the "\ " seen first as a control space, leaving - # a spurious \ behind. Don't consume the preceding. - # Or it could be at the beginning of a line. - # - $string =~ s/(^|(?<=[^\\]))\\$rx/$repl/g; - #warn "after sym $symbol (\\$rx -> $repl), have: $string\n"; - } - - $string; -} - -# Convert accents. -# -sub _convert_accents { - my $string = shift; - - # first the non-alphabetic accent commands, like \". - my %tbl = %LaTeX::ToUnicode::Tables::ACCENT_SYMBOLS; - $string =~ s/(\{\\(.)\s*\{(\\?\w{1,2})\}\})/$tbl{$2}{$3} || $1/eg; #{\"{a}} - $string =~ s/(\{\\(.)\s*(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # {\"a} - $string =~ s/(\\(.)\s*(\\?\w{1,1}))/ $tbl{$2}{$3} || $1/eg; # \"a - $string =~ s/(\\(.)\s*\{(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # \"{a} - - # second the alphabetic commands, like \c. They have to be handled - # differently because \cc is not \c{c}! The only difference in the - # regular expressions is using $endcw instead of just \s*. - # - %tbl = %LaTeX::ToUnicode::Tables::ACCENT_LETTERS; - $string =~ s/(\{\\(.)$endcw\{(\\?\w{1,2})\}\})/$tbl{$2}{$3} || $1/eg; #{\"{a}} - $string =~ s/(\{\\(.)$endcw(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # {\"a} - $string =~ s/(\\(.)$endcw(\\?\w{1,1}))/ $tbl{$2}{$3} || $1/eg; # \"a - $string =~ s/(\\(.)$endcw\{(\\?\w{1,2})\})/ $tbl{$2}{$3} || $1/eg; # \"{a} - - - # The argument is just one \w character for the \"a case, not two, - # because otherwise we might consume a following character that is - # not part of the accent, e.g., a backslash (\"a\'e). - # - # Others can be two because of the \t tie-after accent. Even {\t oo} is ok. - # - # Allow whitespace after the \CMD in all cases, e.g., "\c c". Even - # for the control symbols, it turns out spaces are ignored there - # (as in \" o), unlike the usual syntax. - # - # Some non-word constituents would work, but in practice we hope - # everyone just uses letters. - - $string; -} - -# For the [n]german package. -sub _convert_german { - my $string = shift; - - foreach my $symbol ( keys %LaTeX::ToUnicode::Tables::GERMAN ) { - $string =~ s/\Q$symbol\E/$LaTeX::ToUnicode::Tables::GERMAN{$symbol}/g; - } - $string; -} - -# Control words that produce printed symbols (and letters in languages -# other than English), that is. -# -sub _convert_symbols { - my $string = shift; - - foreach my $symbol ( keys %LaTeX::ToUnicode::Tables::SYMBOLS ) { - my $repl = $LaTeX::ToUnicode::Tables::SYMBOLS{$symbol}; - # preceded by a (non-consumed) non-backslash, - # usual termination for a control word. - # These commands don't take arguments. - $string =~ s/(?<=[^\\])\\$symbol$endcw/$repl/g; - - # or the beginning of the whole string: - $string =~ s/^\\$symbol$endcw/$repl/g; - } - $string; -} - -# Special character sequences, not \commands. They aren't all -# technically ligatures, but no matter. -# -sub _convert_ligatures { - my $string = shift; - - # have to convert these in order specified. - my @ligs = @LaTeX::ToUnicode::Tables::LIGATURES; - for (my $i = 0; $i < @ligs; $i+=2) { - my $in = $ligs[$i]; - my $out = $ligs[$i+1]; - $string =~ s/\Q$in\E/$out/g; - } - $string; -} - -# -# Convert LaTeX markup commands in STRING like \textbf{...} and -# {\bfshape ...} and {\bf ...}. -# -# If we're aiming for plain text output, they are just cleared away (the -# braces are not removed). -# -# If we're generating HTML output ("html" key is set in $OPTIONS hash -# ref), we use the value in the hash, so that \textbf{foo} becomes -# <b>foo</b>. Nested markup doesn't work. -# -sub _convert_markups { - my ($string, $options) = @_; - - # HTML is different. - return _convert_markups_html($string) if $options->{html}; - - # Not HTML, so here we'll "convert" to plain text by removing the - # markup commands. - - # we can do all the markup commands at once. - my $markups = join('|', keys %LaTeX::ToUnicode::Tables::MARKUPS); - - # Remove \textMARKUP{...}, leaving just the {...} - $string =~ s/\\text($markups)$endcw//g; - - # Similarly remove \MARKUPshape, plus remove \upshape. - $string =~ s/\\($markups|up)shape$endcw//g; - - # Remove braces and \command in: {... \MARKUP ...} - $string =~ s/(\{[^{}]+)\\(?:$markups)$endcw([^{}]+\})/$1$2/g; - - # Remove braces and \command in: {\MARKUP ...} - $string =~ s/\{\\(?:$markups)$endcw([^{}]*)\}/$1/g; - - # Remove: {\MARKUP - # Although this will leave unmatched } chars behind, there's no - # alternative without full parsing, since the bib entry will often - # look like: {\em {The TeX{}book}}. Also might, in principle, be - # at the end of a line. - $string =~ s/\{\\(?:$markups)$endcw//g; - - # Ultimately we remove all braces in ltx2crossrefxml SanitizeText fns, - # so the unmatched braces don't matter ... that code should be moved. - - $string; -} - -# Convert \markup in STRING to html. We can't always figure out where to -# put the end tag, but we always put it somewhere. We don't even attempt -# to handle nested markup. -# -sub _convert_markups_html { - my ($string) = @_; - - my %MARKUPS = %LaTeX::ToUnicode::Tables::MARKUPS; - # have to consider each markup \command separately. - for my $markup (keys %MARKUPS) { - my $hcmd = $MARKUPS{$markup}; # some TeX commands don't translate - my $tag = $hcmd ? "<$hcmd>" : ""; - my $end_tag = $hcmd ? "</$hcmd>" : ""; - - # The easy one: \textMARKUP{...} - $string =~ s/\\text$markup$endcw\{(.*?)\}/$tag$1$end_tag/g; - - # {x\MARKUP(shape) y} -> x<mk>y</mk> (leave out braces) - $string =~ s/\{([^{}]+)\\$markup(shape)?$endcw([^{}]+)\} - /$1$tag$3$end_tag/gx; - - # {\MARKUP(shape) y} -> <mk>y</mk>. Same as previous but without - # the x part. Could do it in one regex but this seems clearer. - $string =~ s/\{\\$markup(shape)?$endcw([^{}]+)\} - /$tag$2$end_tag/gx; - - # for {\MARKUP(shape) ... with no matching brace, we don't know - # where to put the end tag, so seems best to do nothing. - } - - $string; -} - - -############################################################## -# debug_hash_as_string($LABEL, HASH) -# -# Return LABEL followed by HASH elements, followed by a newline, as a -# single string. If HASH is a reference, it is followed (but no recursive -# derefencing). -############################################################### -sub debug_hash_as_string { - my ($label) = shift; - my (%hash) = (ref $_[0] && $_[0] =~ /.*HASH.*/) ? %{$_[0]} : @_; - - my $str = "$label: {"; - my @items = (); - for my $key (sort keys %hash) { - my $val = $hash{$key}; - $val = ".undef" if ! defined $val; - $key =~ s/\n/\\n/g; - $val =~ s/\n/\\n/g; - push (@items, "$key:$val"); - } - $str .= join (",", @items); - $str .= "}"; - - return "$str\n"; -} - -1; - -__END__ -=pod - -=encoding UTF-8 - -=head1 NAME - -LaTeX::ToUnicode - Convert LaTeX commands to Unicode - -=head1 VERSION - -version 0.54 - -=head1 SYNOPSIS - - use LaTeX::ToUnicode qw( convert debuglevel $endcw ); - - # simple examples: - convert( '{\"a}' ) eq 'ä'; # true - convert( '{\"a}', entities=>1 ) eq '�EF;'; # true - convert( '"a', german=>1 ) eq 'ä'; # true, `german' package syntax - convert( '"a', ) eq '"a'; # false, not enabled by default - - # more generally: - my $latexstr; - my $unistr = convert($latexstr); # get literal (binary) Unicode characters - - my $entstr = convert($latexstr, entities=>1); # get &#xUUUU; - - my $htmstr = convert($latexstr, entities=>1, html=>1); # also html markup - - my $unistr = convert($latexstr, hook=>\&my_hook); # user-defined hook - - # if nonzero, dumps various info; perhaps other levels in the future. - LaTeX::ToUnicode::debuglevel($verbose); - - # regexp for terminating TeX control words, e.g., in hooks. - my $endcw = $LaTeX::ToUnicode::endcw; - $string =~ s/\\newline$endcw/ /g; # translate \newline to space - -=head1 DESCRIPTION - -This module provides a method to convert LaTeX markups for accents etc. -into their Unicode equivalents. It translates some commands for special -characters or accents into their Unicode (or HTML) equivalents and -removes formatting commands. It is not at all bulletproof or complete. - -This module is intended to convert fragments of LaTeX source, such as -bibliography entries and abstracts, into plain text (or, optionally, -simplistic HTML). It is not a document conversion system. Math, tables, -figures, sectioning, etc., are not handled in any way, and mostly left -in their TeX form in the output. The translations assume standard LaTeX -meanings for characters and control sequences; macros in the input are -not considered. - -The aim for all the output is utter simplicity and minimalism, not -faithful translation. For example, although Unicode has a code point for -a thin space, the LaTeX C<\thinspace> (etc.) command is translated to -the empty string; such spacing refinements desirable in the TeX output -are, in our experience, generally not desired in the HTML output from -this tool. - -As another example, TeX C<%> comments are not removed, even on lines by -themselves, because they may be inside verbatim blocks, and we don't -attempt to keep any such context. In practice, TeX comments are rare in -the text fragments intended to be handled, so removing them in advance -has not been a great burden. - -As another example, LaTeX ties, C<~> characters, are replaced with -normal spaces (exception: unless they follow a C</> character or at the -beginning of a line, when they're assumed to be part of a url or a -pathname), rather than a no-break space character, because in our -experience most ties intended for the TeX output would just cause -trouble in plain text or HTML. - -Regarding normal whitespace: all leading and trailing horizontal -whitespace (that is, SPC and TAB) is removed. All internal horizontal -whitespace sequences are collapsed to a single space. - -After the conversions, all brace characters (C<{}>) are simply removed -from the returned string. This turns out to be a significant convenience -in practice, since many LaTeX commands which take arguments don't need -to do anything for our purposes except output the argument. - -On the other hand, backslashes are not removed. This is so the caller -can check for C<\\> and thus discover untranslated commands. Of course -there are many other constructs that might not be translated, or -translated wrongly. There is no escaping the need to carefully look at -the output. - -Suggestions and bug reports are welcome for practical needs; we know -full well that there are hundreds of commands not handled that could be. -Virtually all the behavior mentioned here would be easily made -customizable, if there is a need to do so. - -=head1 FUNCTIONS - -=head2 convert( $latex_string, %options ) - -Convert the text in C<$latex_string> into a plain(er) Unicode string. -Escape sequences for accented and special characters (e.g., C<\i>, -C<\"a>, ...) are converted. A few basic formatting commands (e.g., -C<{\it ...}>) are removed. See the L<LaTeX::ToUnicode::Tables> submodule -for the full conversion tables. - -These keys are recognized in C<%options>: - -=over - -=item C<entities> - -Output C<&#xUUUU;> entities (valid in XML); in this case, also convert -the E<lt>, E<gt>, C<&> metacharacters to entities. Recognized non-ASCII -Unicode characters in the original input are also converted to entities, -not only the translations from TeX commands. - -The default is to output literal (binary) Unicode characters, and -not change any metacharacters. - -=item C<german> - -If this option is set, the commands introduced by the package `german' -(e.g. C<"a> eq C<ä>, note the missing backslash) are also -handled. - -=item C<html> - -If this option is set, the output is simplistic html rather than plain -text. This affects only a few things: S<1) the> output of urls from -C<\url> and C<\href>; S<2) the> output of markup commands like -C<\textbf> (but nested markup commands don't work); S<3) two> other -random commands, C<\enquote> and C<\path>, because they are needed. - -=item C<hook> - -The value must be a function that takes two arguments and returns a -string. The first argument is the incoming string (may be multiple -lines), and the second argument is a hash reference of options, exactly -what was passed to this C<convert> function. Thus the hook can detect -whether html is needed. - -The hook is called (almost) right away, before any of the other -conversions have taken place. That way the hook can make use of the -predefined conversions instead of repeating them. The only changes made -to the input string before the hook is called are trivial: leading and -trailing whitespace (space and tab) on each line are removed, and, for -HTML output, incoming ampersand, less-than, and greater-than characters -are replaced with their entities. - -Any substitutions that result in Unicode code points must use -C<\\x{nnnn}> on the right hand side: that's two backslashes and a -four-digit hex number. - -As an example, here is a skeleton of the hook function for TUGboat: - - sub LaTeX_ToUnicode_convert_hook { - my ($string,$options) = @_; - - my $endcw = $LaTeX::ToUnicode::endcw; - die "no endcw regexp in LaTeX::ToUnicode??" if ! $endcw; - - ... - $string =~ s/\\newline$endcw/ /g; - - # TUB's \acro{} takes an argument, but we do nothing with it. - # The braces will be removed by convert(). - $string =~ s/\\acro$endcw//g; - ... - $string =~ s/\\CTAN$endcw/CTAN/g; - $string =~ s/\\Dash$endcw/\\x{2014}/g; # em dash; replacement is string - ... - - # ignore \begin{abstract} and \end{abstract} commands. - $string =~ s,\\(begin|end)$endcw\{abstract\}\s*,,g; - - # Output for our url abbreviations, and other commands, depends on - # whether we're generating plain text or HTML. - if ($options->{html}) { - # HTML. - # \tbsurl{URLBASE} -> <a href="https://URLBASE">URLBASE</a> - $string =~ s,\\tbsurl$endcw\{([^}]*)\} - ,<a href="https://$1">$1</a>,gx; - ... - # varepsilon, and no line break at hyphen. - $string =~ s,\\eTeX$endcw,\\x{03B5}<nobr>-</nobr>TeX,g; - - } else { - # for plain text, we can just prepend the protocol://. - $string =~ s,\\tbsurl$endcw,https://,g; - ... - $string =~ s,\\eTeX$endcw,\\x{03B5}-TeX,g; - } - ... - return $string; - } - -As shown here for C<\eTeX> (an abbreviation macro defined in the -TUGboat style files), if markup is desired in the output, the -substitutions must be different for HTML and plain text. Otherwise, the -desired HTML markup is transliterated as if it were plain text. Or else -the translations must be extended so that TeX markup can be used on the -rhs to be replaced with the desired HTML (C<<nobr>> in this case). - -For the full definition (and plenty of additional information), -see the file C<ltx2crossrefxml-tugboat.cfg> in the TUGboat source -repository at -<https://github.com/TeXUsersGroup/tugboat/tree/trunk/capsules/crossref>. - -The hook function is specified in the C<convert()> call like this: - - LaTeX::ToUnicode::convert(..., { hook => \&LaTeX_ToUnicode_convert_hook }) - -=back - -=head2 debuglevel( $level ) - -Output debugging information if C<$level> is nonzero. - -=head2 $endcw - -A predefined regexp for terminating TeX control words (not control -symbols!). Can be used in, for example, hook functions: - - my $endcw = $LaTeX::ToUnicode::endcw; - $string =~ s/\\newline$endcw/ /g; # translate \newline to space - -It's defined as follows: - - our $endcw = qr/(?<=[a-zA-Z])(?=[^a-zA-Z]|$)\s*/; - -That is, look behind for an alphabetic character, then look ahead for a -non-alphabetic character (or end of line), then consume whitespace. -Fingers crossed. - -=head1 AUTHOR - -Gerhard Gossen <gerhard.gossen@googlemail.com>, -Boris Veytsman <boris@varphi.com>, -Karl Berry <karl@freefriends.org> - -L<https://github.com/borisveytsman/bibtexperllibs> - -=head1 COPYRIGHT AND LICENSE - -Copyright 2010-2023 Gerhard Gossen, Boris Veytsman, Karl Berry - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl5 programming language system itself. - -=cut diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode/Tables.pm b/support/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode/Tables.pm deleted file mode 100644 index dd02926e03..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/lib/LaTeX/ToUnicode/Tables.pm +++ /dev/null @@ -1,726 +0,0 @@ -package LaTeX::ToUnicode::Tables; -BEGIN { - $LaTeX::ToUnicode::Tables::VERSION = '0.54'; -} -use strict; -use warnings; -#ABSTRACT: Character tables for LaTeX::ToUnicode - -use utf8; # just for the german support - -# Technically not all of these are ligatures, but close enough. -# Order is important, so has to be a list, not a hash. -# -our @LIGATURES = ( - "---" => '\x{2014}', # em dash - "--" => '\x{2013}', # en dash - "!`" => '\x{00A1}', # inverted exclam - "?`" => '\x{00A1}', # inverted question - "``" => '\x{201c}', # left double - "''" => '\x{201d}', # right double - "`" => '\x{2018}', # left single - "'" => '\x{2019}', # right single -); -# test text: em---dash, en--dash, exc!`am, quest?`ion, ``ld, rd'', `ls, rs'. -# -# Some additional ligatures supported in T1 encoding, but we won't (from -# tex-text.map): -# U+002C U+002C <> U+201E ; ,, -> DOUBLE LOW-9 QUOTATION MARK -# U+003C U+003C <> U+00AB ; << -> LEFT POINTING GUILLEMET -# U+003E U+003E <> U+00BB ; >> -> RIGHT POINTING GUILLEMET - -# for {\MARKUP(shape) ...} and \textMARKUP{...}; although not all -# command names are defined in LaTeX for all markups, we translate them -# anyway. Also, LaTeX has more font axes not included here: md, ulc, sw, -# ssc, etc. See ltfntcmd.dtx and ltfssaxes.dtx if we ever want to try -# for completeness. -# -our %MARKUPS = ( - 'bf' => 'b', - 'cal' => '', - 'em' => 'em', - 'it' => 'i', - 'rm' => '', - 'sc' => '', # qqq should uppercasify - 'sf' => '', - 'sl' => 'i', - 'small' => '', - 'subscript' => 'sub', - 'superscript' => 'sup', - 'tt' => 'tt', -); - -# More commands taking arguments that we want to handle. -# -our %ARGUMENT_COMMANDS = ( - 'emph' => ['\textem{', '}'], # \textem doesn't exist, but we handle it - 'enquote' => ["`", "'"], - 'path' => ['\texttt{', '}'], # ugh, might not be a braced argument -); - -# Non-alphabetic \COMMANDs, other than accents and special cases. -# -our %CONTROL_SYMBOLS = ( - ' ' => ' ', # control space - "\t" => ' ', # control space - "\n" => '\x{0020}', # control space; use entity to avoid being trimmed - '!' => '', # negative thin space - # " umlaut - '#' => '#', # sharp sign - '$' => '$', # dollar sign - '%' => '%', # percent sign - '&' => '\x{0026}', # ampersand, entity to avoid html conflict - # ' acute accent - '(' => '', # start inline math - ')' => '', # end inline math - '*' => '', # discretionary multiplication - '+' => '', # tabbing: tab stop to right - ',' => '', # thin space - '-' => '', # discretionary hyphenation - # . overdot accent - '/' => '', # italic correction - # 0..9 undefined - ':' => '', # medium space - ';' => ' ', # thick space - '<' => '', # tabbing: text to left of margin - # = macron accent - '>' => '', # tabbing: next tab stop - # ? undefined - '@' => '#', # end of sentence - # A..Z control words, not symbols - '[' => '', # start display math - '\\' => ' ', # line break - ']' => '', # end display math - # ^ circumflex accent - '_' => '_', # underscore - # ` grave accent - # a..z control words, not symbols - '{' => '\x{007b}', # lbrace - '|' => '\x{2225}', # parallel - '}' => '\x{007d}', # rbrace - # ~ tilde accent -); - -# Alphabetic \COMMANDs that map to nothing. This is simply -# interpolated into %CONTROL_WORDS (next), not used directly, so we -# redundantly specify the '' on every line. -# -our %CONTROL_WORDS_EMPTY = ( - 'begingroup' => '', - 'bgroup' => '', - 'checkcomma' => '', - #'cite' => '', # keep \cite undefined since it needs manual work - 'clearpage' => '', - 'doi' => '', - 'egroup' => '', - 'endgroup' => '', - 'ensuremath' => '', - 'hbox' => '', - 'ignorespaces' => '', - 'mbox' => '', - 'medspace' => '', - 'negmedspace' => '', - 'negthickspace' => '', - 'negthinspace' => '', - 'newblock' => '', - 'newpage' => '', - 'noindent' => '', - 'nolinkurl' => '', - 'oldstylenums' => '', - 'pagebreak' => '', - 'protect' => '', - 'raggedright' => '', - 'relax' => '', - 'thinspace' => '', - 'unskip' => '', - 'urlprefix' => '', -); - -# Alphabetic commands, that expand to nothing (above) and to -# something (below). -# -our %CONTROL_WORDS = ( - %CONTROL_WORDS_EMPTY, - 'BibLaTeX' => 'BibLaTeX', - 'BibTeX' => 'BibTeX', - 'LaTeX' => 'LaTeX', - 'LuaLaTeX' => 'LuaLaTeX', - 'LuaTeX' => 'LuaTeX', - 'MF' => 'Metafont', - 'MP' => 'MetaPost', - 'Omega' => '\x{03A9}', - 'TeX' => 'TeX', - 'XeLaTeX' => 'XeLaTeX', - 'XeTeX' => 'XeTeX', - 'bullet' => '\x{2022}', - 'dag' => '\x{2020}', - 'ddag' => '\x{2021}', - 'dots' => '\x{2026}', - 'epsilon' => '\x{03F5}', - 'hookrightarrow' => '\x{2194}', - 'ldots' => '\x{2026}', - 'log' => 'log', - 'omega' => '\x{03C9}', - 'par' => "\n\n", - 'qquad' => ' ', # 2em space - 'quad' => ' ', # em space - 'textbackslash' => '\x{005C}', # entities so \ in output indicates - # untranslated TeX source - 'textbraceleft' => '\x{007B}', # entities so our bare-brace removal - 'textbraceright' => '\x{007D}', # skips them - 'textgreater' => '\x{003E}', - 'textless' => '\x{003C}', - 'textquotedbl' => '"', - 'thickspace' => ' ', - 'varepsilon' => '\x{03B5}', -); - -# Control words (not symbols) that generate various non-English -# letters and symbols. Lots more could be added. -# -our %SYMBOLS = ( # Table 3.2 in Lamport, plus more - 'AA' => '\x{00C5}', # A with ring - 'aa' => '\x{00E5}', - 'AE' => '\x{00C6}', # AE - 'ae' => '\x{00E6}', - 'DH' => '\x{00D0}', # ETH - 'dh' => '\x{00F0}', - 'DJ' => '\x{0110}', # D with stroke - 'dj' => '\x{0111}', - 'i' => '\x{0131}', # small dotless i - 'L' => '\x{0141}', # L with stroke - 'l' => '\x{0142}', - 'NG' => '\x{014A}', # ENG - 'ng' => '\x{014B}', - 'OE' => '\x{0152}', # OE - 'oe' => '\x{0153}', - 'O' => '\x{00D8}', # O with stroke - 'o' => '\x{00F8}', - 'SS' => 'SS', # lately also U+1E9E, but SS seems good enough - 'ss' => '\x{00DF}', - 'TH' => '\x{00DE}', # THORN - 'textordfeminine' => '\x{00AA}', - 'textordmasculine' => '\x{00BA}', - 'textregistered' => '\x{00AE}', - 'th' => '\x{00FE}', - 'TM' => '\x{2122}', # trade mark sign -); - -# Accent commands that are not alphabetic. -# -our %ACCENT_SYMBOLS = ( - "\"" => { # with diaresis - A => '\x{00C4}', - E => '\x{00CB}', - H => '\x{1E26}', - I => '\x{00CF}', - O => '\x{00D6}', - U => '\x{00DC}', - W => '\x{1E84}', - X => '\x{1E8c}', - Y => '\x{0178}', - "\\I" => '\x{00CF}', - "\\i" => '\x{00EF}', - a => '\x{00E4}', - e => '\x{00EB}', - h => '\x{1E27}', - i => '\x{00EF}', - o => '\x{00F6}', - t => '\x{1E97}', - u => '\x{00FC}', - w => '\x{1E85}', - x => '\x{1E8d}', - y => '\x{00FF}', - }, - "'" => { # with acute - A => '\x{00C1}', - AE => '\x{01FC}', - C => '\x{0106}', - E => '\x{00C9}', - G => '\x{01F4}', - I => '\x{00CD}', - K => '\x{1E30}', - L => '\x{0139}', - M => '\x{1E3E}', - N => '\x{0143}', - O => '\x{00D3}', - P => '\x{1E54}', - R => '\x{0154}', - S => '\x{015A}', - U => '\x{00DA}', - W => '\x{1E82}', - Y => '\x{00DD}', - Z => '\x{0179}', - "\\I" => '\x{00CD}', - "\\i" => '\x{00ED}', - a => '\x{00E1}', - ae => '\x{01FD}', - c => '\x{0107}', - e => '\x{00E9}', - g => '\x{01F5}', - i => '\x{00ED}', - k => '\x{1E31}', - l => '\x{013A}', - m => '\x{1E3f}', - n => '\x{0144}', - o => '\x{00F3}', - p => '\x{1E55}', - r => '\x{0155}', - s => '\x{015B}', - u => '\x{00FA}', - w => '\x{1E83}', - y => '\x{00FD}', - z => '\x{017A}', - }, - "^" => { # with circumflex - A => '\x{00C2}', - C => '\x{0108}', - E => '\x{00CA}', - G => '\x{011C}', - H => '\x{0124}', - I => '\x{00CE}', - J => '\x{0134}', - O => '\x{00D4}', - R => 'R\x{0302}', - S => '\x{015C}', - U => '\x{00DB}', - W => '\x{0174}', - Y => '\x{0176}', - Z => '\x{1E90}', - "\\I" => '\x{00CE}', - "\\J" => '\x{0134}', - "\\i" => '\x{00EE}', - "\\j" => '\x{0135}', - a => '\x{00E2}', - c => '\x{0109}', - e => '\x{00EA}', - g => '\x{011D}', - h => '\x{0125}', - i => '\x{00EE}', - j => '\x{0135}', - o => '\x{00F4}', - s => '\x{015D}', - u => '\x{00FB}', - w => '\x{0175}', - y => '\x{0177}', - z => '\x{1E91}', - }, - "`" => { # with grave - A => '\x{00C0}', - E => '\x{00C8}', - I => '\x{00CC}', - N => '\x{01F8}', - O => '\x{00D2}', - U => '\x{00D9}', - W => '\x{1E80}', - Y => '\x{1Ef2}', - "\\I" => '\x{00CC}', - "\\i" => '\x{00EC}', - a => '\x{00E0}', - e => '\x{00E8}', - i => '\x{00EC}', - n => '\x{01F9}', - o => '\x{00F2}', - u => '\x{00F9}', - w => '\x{1E81}', - y => '\x{1EF3}', - }, - "." => { # with dot above - A => '\x{0226}', - B => '\x{1E02}', - C => '\x{010A}', - D => '\x{1E0A}', - E => '\x{0116}', - F => '\x{1E1E}', - G => '\x{0120}', - H => '\x{1E22}', - I => '\x{0130}', - M => '\x{1E40}', - N => '\x{1E44}', - O => '\x{022E}', - P => '\x{1E56}', - R => '\x{1E58}', - S => '\x{1E60}', - T => '\x{1E6a}', - W => '\x{1E86}', - X => '\x{1E8A}', - Y => '\x{1E8E}', - Z => '\x{017B}', - "\\I" => '\x{0130}', - a => '\x{0227}', - b => '\x{1E03}', - c => '\x{010B}', - d => '\x{1E0B}', - e => '\x{0117}', - f => '\x{1e1f}', - g => '\x{0121}', - h => '\x{1E23}', - m => '\x{1E41}', - n => '\x{1E45}', - o => '\x{022F}', - p => '\x{1E57}', - r => '\x{1E59}', - s => '\x{1E61}', - t => '\x{1E6b}', - w => '\x{1E87}', - x => '\x{1E8b}', - y => '\x{1E8f}', - z => '\x{017C}', - }, - '=' => { # with macron - A => '\x{0100}', - AE => '\x{01E2}', - E => '\x{0112}', - G => '\x{1E20}', - I => '\x{012A}', - O => '\x{014C}', - U => '\x{016A}', - Y => '\x{0232}', - "\\I" => '\x{012A}', - "\\i" => '\x{012B}', - a => '\x{0101}', - ae => '\x{01E3}', - e => '\x{0113}', - g => '\x{1E21}', - i => '\x{012B}', - o => '\x{014D}', - u => '\x{016B}', - y => '\x{0233}', - }, - "~" => { # with tilde - A => '\x{00C3}', - E => '\x{1EBC}', - I => '\x{0128}', - N => '\x{00D1}', - O => '\x{00D5}', - U => '\x{0168}', - V => '\x{1E7C}', - Y => '\x{1EF8}', - "\\I" => '\x{0128}', - "\\i" => '\x{0129}', - a => '\x{00E3}', - e => '\x{1EBD}', - i => '\x{0129}', - n => '\x{00F1}', - o => '\x{00F5}', - u => '\x{0169}', - v => '\x{1E7D}', - y => '\x{1EF9}', - }, -); - -# Accent commands that are alphabetic. -# -our %ACCENT_LETTERS = ( - "H" => { # with double acute - O => '\x{0150}', - U => '\x{0170}', - o => '\x{0151}', - u => '\x{0171}', - }, - "c" => { # with cedilla - C => '\x{00C7}', - D => '\x{1E10}', - E => '\x{0228}', - G => '\x{0122}', - H => '\x{1E28}', - K => '\x{0136}', - L => '\x{013B}', - N => '\x{0145}', - R => '\x{0156}', - S => '\x{015E}', - T => '\x{0162}', - c => '\x{00E7}', - d => '\x{1E11}', - e => '\x{0229}', - g => '\x{0123}', - h => '\x{1E29}', - k => '\x{0137}', - l => '\x{013C}', - n => '\x{0146}', - r => '\x{0157}', - s => '\x{015F}', - t => '\x{0163}', - }, - "d" => { # with dot below - A => '\x{1EA0}', - B => '\x{1E04}', - D => '\x{1E0C}', - E => '\x{1EB8}', - H => '\x{1E24}', - I => '\x{1ECA}', - K => '\x{1E32}', - L => '\x{1E36}', - M => '\x{1E42}', - N => '\x{1E46}', - O => '\x{1ECC}', - R => '\x{1E5A}', - S => '\x{1E62}', - T => '\x{1E6C}', - U => '\x{1EE4}', - V => '\x{1E7E}', - W => '\x{1E88}', - Y => '\x{1Ef4}', - Z => '\x{1E92}', - "\\I" => '\x{1ECA}', - "\\i" => '\x{1ECB}', - a => '\x{1EA1}', - b => '\x{1E05}', - d => '\x{1E0D}', - e => '\x{1EB9}', - h => '\x{1E25}', - i => '\x{1ECB}', - k => '\x{1E33}', - l => '\x{1E37}', - m => '\x{1E43}', - n => '\x{1E47}', - o => '\x{1ECD}', - r => '\x{1E5b}', - s => '\x{1E63}', - t => '\x{1E6D}', - u => '\x{1EE5}', - v => '\x{1E7F}', - w => '\x{1E89}', - y => '\x{1EF5}', - z => '\x{1E93}', - }, - "h" => { # with hook above - A => '\x{1EA2}', - E => '\x{1EBA}', - I => '\x{1EC8}', - O => '\x{1ECe}', - U => '\x{1EE6}', - Y => '\x{1EF6}', - "\\I" => '\x{1EC8}', - "\\i" => '\x{1EC9}', - a => '\x{1EA3}', - e => '\x{1EBB}', - i => '\x{1EC9}', - o => '\x{1ECF}', - u => '\x{1EE7}', - y => '\x{1EF7}', - }, - "k" => { # with ogonek - A => '\x{0104}', - E => '\x{0118}', - I => '\x{012E}', - O => '\x{01EA}', - U => '\x{0172}', - "\\I" => '\x{012E}', - "\\i" => '\x{012F}', - a => '\x{0105}', - e => '\x{0119}', - i => '\x{012F}', - o => '\x{01EB}', - u => '\x{0173}', - }, - "r" => { # with ring above - A => '\x{00C5}', - U => '\x{016E}', - a => '\x{00E5}', - u => '\x{016F}', - w => '\x{1E98}', - y => '\x{1E99}', - }, - "u" => { # with breve - A => '\x{0102}', - E => '\x{0114}', - G => '\x{011E}', - I => '\x{012C}', - O => '\x{014E}', - U => '\x{016C}', - "\\I" => '\x{012C}', - "\\i" => '\x{012D}', - a => '\x{0103}', - e => '\x{0115}', - g => '\x{011F}', - i => '\x{012D}', - o => '\x{014F}', - u => '\x{016D}', - }, - "v" => { # with caron - A => '\x{01CD}', - C => '\x{010C}', - D => '\x{010E}', - DZ => '\x{01C4}', - E => '\x{011A}', - G => '\x{01E6}', - H => '\x{021E}', - I => '\x{01CF}', - K => '\x{01E8}', - L => '\x{013D}', - N => '\x{0147}', - O => '\x{01D1}', - R => '\x{0158}', - S => '\x{0160}', - T => '\x{0164}', - U => '\x{01D3}', - Z => '\x{017D}', - "\\I" => '\x{01CF}', - "\\i" => '\x{01D0}', - "\\j" => '\x{01F0}', - a => '\x{01CE}', - c => '\x{010D}', - d => '\x{010F}', - dz => '\x{01C6}', - e => '\x{011B}', - g => '\x{01E7}', - h => '\x{021F}', - i => '\x{01D0}', - j => '\x{01F0}', - k => '\x{01E9}', - l => '\x{013E}', - n => '\x{0148}', - o => '\x{01D2}', - r => '\x{0159}', - s => '\x{0161}', - t => '\x{0165}', - u => '\x{01D4}', - z => '\x{017E}', - }, -); - -# -our %GERMAN = ( # for package `german'/`ngerman' - '"a' => 'ä', - '"A' => 'Ä', - '"e' => 'ë', - '"E' => 'Ë', - '"i' => 'ï', - '"I' => 'Ï', - '"o' => 'ö', - '"O' => 'Ö', - '"u' => 'ü', - '"U' => 'Ü', - '"s' => 'ß', - '"S' => 'SS', - '"z' => 'ß', - '"Z' => 'SZ', - '"ck' => 'ck', # old spelling: ck -> k-k - '"ff' => 'ff', # old spelling: ff -> ff-f - '"`' => '„', - "\"'" => '“', - '"<' => '«', - '">' => '»', - '"-' => '\x{00AD}', # soft hyphen - '""' => '\x{200B}', # zero width space - '"~' => '\x{2011}', # non-breaking hyphen - '"=' => '-', - '\glq' => '‚', # left german single quote - '\grq' => '‘', # right german single quote - '\flqq' => '«', - '\frqq' => '»', - '\dq' => '"', -); - -1; - -__END__ -=pod - -=encoding UTF-8 - -=head1 NAME - -LaTeX::ToUnicode::Tables - Character tables for LaTeX::ToUnicode - -=head1 VERSION - -version 0.54 - -=head1 CONSTANTS - -=head2 @LIGATURES - -Standard TeX character sequences (not \commands) which need to be -replaced: C<---> with U+2014 (em dash), etc. Includes: em dash, en -dash, inverted exclamation, inverted question, left double quote, right -double quote, left single quote, right single quote. They are replaced -in that order. - -=head2 %MARKUPS - -Hash where keys are the names of formatting commands like C<\tt>, -without the backslash, namely: C<bf cal em it rm sc sf sl small tt>. Values -are the obvious HTML equivalent where one exists, given as the tag name -without the angle brackets: C<b em i tt>. Otherwise the value is the empty -string. - -=head2 %ARGUMENT_COMMANDS - -Hash where keys are the names of TeX commands taking arguments that we -handle, without the backslash, such as C<enquote>. Each value is a -reference to a list of two strings, the first being the text to insert -before the argument, the second being the text to insert after. For -example, for C<enquote> the value is C<["`", "'"]>. The inserted text is -subject to further replacements. - -Only three such commands are currently handled: C<\emph>, C<\enquote>, -and C<\path>. - -=head2 %CONTROL_SYMBOLS - -A hash where the keys are non-alphabetic C<\command>s (without the -backslash), other than accents and special cases. These don't take -arguments. Although some of these have Unicode equivalents, such as the -C<\,> thin space, it seems better to keep the output as simple as -possible; small spacing tweaks in TeX aren't usually desirable in plain -text or HTML. - -The values are single-quoted strings C<'\x{...}'>, not double-quoted -literal characters <"\x{...}">, to ease future parsing of the -TeX/text/HTML. - -This hash is necessary because TeX's parsing rules for control symbols -are different from control words: no space or other token is needed to -terminate control symbols. - -=head2 %CONTROL_WORDS - -Keys are names of argument-less commands, such as C<\LaTeX> (without the -backslash). Values are the replacements, often the empty string. - -=head2 %SYMBOLS - -Keys are the commands for extended characters, such as C<\AA> (without -the backslash.) - -=head2 %ACCENT_SYMBOLS - -Two-level hash of accented characters like C<\'{a}>. The keys of this -hash are the accent symbols (without the backslash), such as C<`> and -C<'>. The corresponding values are hash references where the keys are -the base letters and the values are single-quoted C<'\x{....}'> strings. - -=head2 %ACCENT_LETTERS - -Same as %ACCENT_SYMBOLS, except the keys are accents that are -alphabetic, such as C<\c> (without the backslash as always). - -As with control sequences, it's necessary to distinguish symbols and -alphabetic commands because of the different parsing rules. - -=head2 %GERMAN - -Character sequences (not necessarily commands) as defined by the package -`german'/`ngerman', e.g. C<"a> (a with umlaut), C<"s> (german sharp s) -or C<"`"> (german left quote). Note the missing backslash. - -The keys of this hash are the literal character sequences. - -=head1 AUTHOR - -Gerhard Gossen <gerhard.gossen@googlemail.com>, -Boris Veytsman <boris@varphi.com>, -Karl Berry <karl@freefriends.org> - -L<https://github.com/borisveytsman/bibtexperllibs> - -=head1 COPYRIGHT AND LICENSE - -Copyright 2010-2023 Gerhard Gossen, Boris Veytsman, Karl Berry - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl5 programming language system itself. - -=cut diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.1 b/support/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.1 deleted file mode 100644 index 8dc8e71426..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.1 +++ /dev/null @@ -1,73 +0,0 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3. -.TH LTX2UNITXT "1" "November 2023" "ltx2unitxt " "User Commands" -.SH NAME -ltx2unitxt \- convert LaTeX source fragment to plain (Unicode) text or simple html -.SH SYNOPSIS -.B ltx2unitxt -[\fI\,-c CONFIG\/\fR] [\fI\,-o OUTPUT\/\fR] [\fI\,--html\/\fR] [...] [\fI\,INFILE\/\fR]... -.SH DESCRIPTION -Convert the LaTeX source in INFILE (or standard input) to plain text -using Unicode code points for accents and other special characters; or, -optionally, output HTML with simple translations for font changes and url -commands. -.PP -Common accent sequences, special characters, and simple markup commands -are translated, but there is no attempt at completeness. Math, tables, -figures, sectioning, etc., are not handled in any way, and mostly left -in their TeX form in the output. The translations assume standard LaTeX -meanings for characters and control sequences; macros in the input are -not considered. -.PP -The input can be a fragment of text, not a full document, as the purpose -of this script was to handle bibliography entries and abstracts (for the -ltx2crossrefxml script that is part of the crossrefware package). -Patches to extend this script are welcome. It uses the LaTeX::ToUnicode -Perl library for the conversion; see its documentation for details. -.PP -Conversion is currently done line by line, so TeX constructs that cross -multiple lines are not handled properly. If it turns out to be useful, -conversion could be done by paragraph instead. -.PP -The config file is read as a Perl source file. It can define a function -`LaTeX_ToUnicode_convert_hook()' which will be called early; the value -it returns (which must be a string) will then be subject to the standard -conversion. -.PP -For an example of using this script and associated code, see the TUGboat -processing at -https://github.com/TeXUsersGroup/tugboat/tree/trunk/capsules/crossref. -.SH OPTIONS -.TP -\fB\-c\fR, \fB\-\-config\fR=\fI\,FILE\/\fR -read (Perl) config FILE for a hook, as explained above -.TP -\fB\-e\fR, \fB\-\-entities\fR -output entities &#xNNNN; instead of literal characters -.TP -\fB\-g\fR, \fB\-\-german\fR -handle some features of the german package -.TP -\fB\-h\fR, \fB\-\-html\fR -output simplistic HTML instead of plain text -.TP -\fB\-o\fR, \fB\-\-output\fR=\fI\,FILE\/\fR -output to FILE instead of stdout -.TP -\fB\-v\fR, \fB\-\-verbose\fR -be verbose -.TP -\fB\-V\fR, \fB\-\-version\fR -output version information and exit -.TP -\-?, \fB\-\-help\fR -display this help and exit -.PP -Options can be abbreviated unambiguously, and start with either \- or \fB\-\-\fR. -.PP -Dev sources, bug tracker: https://github.com/borisveytsman/bibtexperllibs -Releases: https://ctan.org/pkg/bibtexperllibs -.PP -ltx2unitxt (bibtexperllibs) 0.51 -Copyright 2023 Karl Berry. -This is free software: you can redistribute it and/or -modify it under the same terms as Perl itself. diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.pdf b/support/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.pdf Binary files differdeleted file mode 100644 index 7dfae7f396..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/ltx2unitxt.pdf +++ /dev/null diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/script/convert.pl b/support/bibtexperllibs/LaTeX-ToUnicode/script/convert.pl deleted file mode 100644 index 70cc0bda84..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/script/convert.pl +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use utf8; - -use feature 'say'; -use FindBin; - -my $UNICODE_DATA_URL = "http://www.unicode.org/Public/UNIDATA/UnicodeData.txt"; - - -my $stream; -if ( -f "$FindBin::Bin/UnicodeData.txt" ) { - open $stream, "<", "$FindBin::Bin/UnicodeData.txt" or die; -} else { - open $stream, "-|", "curl $UNICODE_DATA_URL" or die; -} -my %data; - -my %chars = ( - 'ACUTE' => "'", - 'ACUTE AND DOT ABOVE' => '', - 'BAR' => '', - 'BELT' => '', - 'BREVE' => 'u', - 'BREVE AND ACUTE' => '', - 'BREVE AND DOT BELOW' => '', - 'BREVE AND GRAVE' => '', - 'BREVE AND HOOK ABOVE' => '', - 'BREVE AND TILDE' => '', - 'BREVE BELOW' => '', - 'CARON' => 'v', - 'CARON AND DOT ABOVE' => '', - 'CEDILLA' => 'c', - 'CEDILLA AND ACUTE' => '', - 'CEDILLA AND BREVE' => '', - 'CIRCUMFLEX' => '^', - 'CIRCUMFLEX AND ACUTE' => '', - 'CIRCUMFLEX AND DOT BELOW' => '', - 'CIRCUMFLEX AND GRAVE' => '', - 'CIRCUMFLEX AND HOOK ABOVE' => '', - 'CIRCUMFLEX AND TILDE' => '', - 'CIRCUMFLEX BELOW' => '', - 'COMMA' => '', - 'COMMA BELOW' => '', - 'CROSSED-TAIL' => '', - 'CURL' => '', - 'DESCENDER' => '', - 'DIAERESIS' => '"', - 'DIAERESIS AND ACUTE' => '', - 'DIAERESIS AND CARON' => '', - 'DIAERESIS AND GRAVE' => '', - 'DIAERESIS AND MACRON' => '', - 'DIAERESIS BELOW' => '', - 'DIAGONAL STROKE' => '', - 'DOT ABOVE' => '.', - 'DOT ABOVE AND MACRON' => '', - 'DOT BELOW' => 'd', - 'DOT BELOW AND DOT ABOVE' => '', - 'DOT BELOW AND MACRON' => '', - 'DOUBLE ACUTE' => 'H', - 'DOUBLE BAR' => '', - 'DOUBLE GRAVE' => '', - 'FISHHOOK' => '', - 'FISHHOOK AND MIDDLE TILDE' => '', - 'FLOURISH' => '', - 'GRAVE' => '`', - 'HIGH STROKE' => '', - 'HOOK' => '', - 'HOOK ABOVE' => 'h', - 'HOOK AND TAIL' => '', - 'HOOK TAIL' => '', - 'HORIZONTAL BAR' => '', - 'HORN' => '', - 'HORN AND ACUTE' => '', - 'HORN AND DOT BELOW' => '', - 'HORN AND GRAVE' => '', - 'HORN AND HOOK ABOVE' => '', - 'HORN AND TILDE' => '', - 'INVERTED BREVE' => '', - 'LEFT HOOK' => '', - 'LINE BELOW' => '', - 'LONG LEG' => '', - 'LONG RIGHT LEG' => '', - 'LONG STROKE OVERLAY' => '', - 'LOOP' => '', - 'LOW RING INSIDE' => '', - 'MACRON' => '=', - 'MACRON AND ACUTE' => '', - 'MACRON AND DIAERESIS' => '', - 'MACRON AND GRAVE' => '', - 'MIDDLE DOT' => '', - 'MIDDLE TILDE' => '', - 'NOTCH' => '', - 'OGONEK' => 'k', - 'OGONEK AND MACRON' => '', - 'PALATAL HOOK' => '', - 'RETROFLEX HOOK' => '', - 'RIGHT HALF RING' => '', - 'RIGHT HOOK' => '', - 'RING ABOVE' => 'r', - 'RING ABOVE AND ACUTE' => '', - 'RING BELOW' => '', - 'SMALL LETTER J' => '', - 'SMALL LETTER Z' => '', - 'SMALL LETTER Z WITH CARON' => '', - 'SQUIRREL TAIL' => '', - 'STRIKETHROUGH' => '', - 'STROKE' => '', - 'STROKE AND ACUTE' => '', - 'STROKE AND DIAGONAL STROKE' => '', - 'STROKE THROUGH DESCENDER' => '', - 'SWASH TAIL' => '', - 'TAIL' => '', - 'TILDE' => '~', - 'TILDE AND ACUTE' => '', - 'TILDE AND DIAERESIS' => '', - 'TILDE AND MACRON' => '', - 'TILDE BELOW' => '', - 'TOPBAR' => '', -); - -my %missing; - -while(<$stream>) { - chomp; - my @F = split /;/; - my $hex = $F[0]; - if ( $F[1] =~ /LATIN (SMALL|CAPITAL) LETTER ((?:\w+ )*\w{1,2}) WITH (.+)$/ ) { - my $case = $1; - my $letter = $2; - my $accent = $3; - - if ( $case eq 'SMALL' ) { - $letter = lc $letter; - } - if ( $chars{$accent} && $letter !~ / / ) { - my $char = chr( eval "0x$hex" ); - $data{ $chars{$accent} }->{ $letter } = $char; - if ( lc( $letter ) eq 'i' ) { - my $additional_letter = "\\$letter"; - $data{ $chars{$accent} }->{ $additional_letter } = $char; - } - } else { - push @{ $missing{$accent} }, $letter; - } - } -} - -use Data::Dumper::Concise; - -binmode(STDOUT, ":utf8"); - -say Dumper( \%data ); -#say Dumper( \%missing ); diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/script/ltx2unitxt b/support/bibtexperllibs/LaTeX-ToUnicode/script/ltx2unitxt deleted file mode 100755 index 661ea40417..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/script/ltx2unitxt +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env perl -# Use the LaTeX::ToUnicode module (also in the bibtexperllibs -# repository/package, like this script) to convert LaTeX to Unicode. -# -# We work on fragments of text, not whole documents, the goal being to -# replace LaTeX commands and syntax with obvious plain text equivalents, -# or remove them. - -use strict; -use warnings; - -use Cwd; -use File::Basename; -use File::Spec; - -BEGIN { - # find files relative to our installed location within TeX Live - chomp(my $TLMaster = `kpsewhich -var-value=SELFAUTOPARENT`); # TL root - if (length($TLMaster)) { - unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs"; - } - # find development bibtexperllibs in sibling checkout to this script, - # even if $0 is a symlink. Irrelevant when using from an installation. - my $real0 = Cwd::abs_path($0); - my $scriptdir = File::Basename::dirname($real0); - my $dev_btxperllibs = Cwd::abs_path("$scriptdir/../.."); - - # we need the lib/ subdirectories inside ... - unshift (@INC, glob ("$dev_btxperllibs/*/lib")) if -d $dev_btxperllibs; - -} - -use LaTeX::ToUnicode; - -our %opts; -local *OUT; # output filehandle - -exit(main()); - -sub main { - init(); - - # by paragraph? - while (<>) { - print OUT (convert($_)); - } - - return 0; -} - -sub convert { - my ($in) = @_; - - my @args = (); # what we'll pass to the convert() fn. - # - if (defined(&{"LaTeX_ToUnicode_convert_hook"})) { - push (@args, "hook" => \&LaTeX_ToUnicode_convert_hook); } - if ($opts{e}) { push (@args, "entities" => 1); } - if ($opts{g}) { push (@args, "german" => 1); } - if ($opts{h}) { push (@args, "html" => 1); } - - LaTeX::ToUnicode::debuglevel($opts{v}); - my $out = LaTeX::ToUnicode::convert($in, @args); - - #warn "out=$out"; - return $out; -} - - -# Command line options, etc. -# -sub init { - my $USAGE = <<END; -Usage: $0 [-c CONFIG] [-o OUTPUT] [--html] [...] [INFILE]... - -Convert the LaTeX source in INFILE (or standard input) to plain text -using Unicode code points for accents and other special characters; or, -optionally, output HTML with simple translations for font changes and url -commands. - -Common accent sequences, special characters, and simple markup commands -are translated, but there is no attempt at completeness. Math, tables, -figures, sectioning, etc., are not handled in any way, and mostly left -in their TeX form in the output. The translations assume standard LaTeX -meanings for characters and control sequences; macros in the input are -not considered. - -The input can be a fragment of text, not a full document, as the purpose -of this script was to handle bibliography entries and abstracts (for the -ltx2crossrefxml script that is part of the crossrefware package). -Patches to extend this script are welcome. It uses the LaTeX::ToUnicode -Perl library for the conversion; see its documentation for details. - -Conversion is currently done line by line, so TeX constructs that cross -multiple lines are not handled properly. If it turns out to be useful, -conversion could be done by paragraph instead. - -The config file is read as a Perl source file. It can define a function -`LaTeX_ToUnicode_convert_hook()' which will be called early; the value -it returns (which must be a string) will then be subject to the standard -conversion. - -For an example of using this script and associated code, see the TUGboat -processing at -https://github.com/TeXUsersGroup/tugboat/tree/trunk/capsules/crossref. - -Options: - -c, --config=FILE read (Perl) config FILE for a hook, as explained above - -e, --entities output entities &#xNNNN; instead of literal characters - -g, --german handle some features of the german package - -h, --html output simplistic HTML instead of plain text - -o, --output=FILE output to FILE instead of stdout - -v, --verbose be verbose - -V, --version output version information and exit - -?, --help display this help and exit - -Options can be abbreviated unambiguously, and start with either - or --. - -Dev sources, bug tracker: https://github.com/borisveytsman/bibtexperllibs -Releases: https://ctan.org/pkg/bibtexperllibs -END - - my $VERSION = <<END; -ltx2unitxt (bibtexperllibs) 0.51 -Copyright 2023 Karl Berry. -This is free software: you can redistribute it and/or -modify it under the same terms as Perl itself. -END - - use Getopt::Long qw(:config no_ignore_case); # otherwise v|V is the same - - GetOptions( - "config|c=s" => \($opts{c}), - "entities|e" => \($opts{e}), - "german|g" => \($opts{g}), - "html|h" => \($opts{h}), - "output|o=s" => \($opts{o}), - "verbose|v" => \($opts{v}), - "version|V" => \($opts{V}), - "help|?" => \($opts{help})) - || die "Try $0 --help for more information.\n"; - - if ($opts{help}) { print "$USAGE\n$VERSION"; exit 0; } - if ($opts{V}) { print $VERSION; exit 0; } - - binmode(STDOUT, ":utf8"); - *OUT = *STDOUT; - - if (defined($opts{o})) { - open(OUT, ">$opts{o}") || die "open(>$opts{o}) failed: $!\n"; - binmode(OUT, ":utf8") - } - - if ($opts{c}) { - if (-r $opts{c}) { - # if config arg is absolute, fine; if not, prepend "./" as slightly - # less troublesome than putting "." in the @INC path. - my $rel = (File::Spec->file_name_is_absolute($opts{c}) ? "" : "./"); - my $cnffile = "$rel$opts{c}"; - verbose("requiring config file: $cnffile"); - require $cnffile; - } else { - die "open config file ($opts{c}) for reading failed: $!\n"; - } - } -} - - -sub verbose { print @_ if $::opts{v}; } diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/t/convert.t b/support/bibtexperllibs/LaTeX-ToUnicode/t/convert.t deleted file mode 100644 index 9bd7a4f3d4..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/t/convert.t +++ /dev/null @@ -1,136 +0,0 @@ -use strict; -use warnings; - -use Test::More; -use utf8; - -BEGIN{ use_ok( 'LaTeX::ToUnicode', qw( convert ) ); } - -binmode( STDOUT, ':utf8' ); -my @tests = ( - [ '\LaTeX' => 'LaTeX' ], - [ '\$ \% \& \_ \{ \} \#' => '$ % & _ { } #' ], - [ '{\"{a}}' => 'ä' ], - [ '{\"a}' => 'ä' ], - [ '{\`{a}}' => 'à' ], - [ '{\`a}' => 'à' ], - [ '\ae' => 'æ' ], - [ '\L' => 'Ł' ], - [ "{\\'e}" => 'é'], - ['\={a}' => 'ā'], - ['{\=a}' => 'ā'], -); - -foreach my $test ( @tests ) { - is( convert( $test->[0] ), $test->[1], "Convert $test->[0]" ); -} - -my @german_tests = ( - [ '"a' => 'ä' ], - ['"`' => '„' ], - ["\"'" => '“' ], -); - -foreach my $test ( @german_tests ) { - is( convert( $test->[0], german => 1 ), $test->[1], "Convert $test->[0], german => 1" ); -} - -binmode( DATA, ':utf8' ); -while (<DATA>) { - chomp; - my ( $tex, $result ) = split /\t/; - is( convert( $tex ), $result, "Convert $tex" ); -} -close DATA; - -done_testing; - -__DATA__ -\& & -{\`a} à -{\^a} â -{\~a} ã -{\'a} á -{\'{a}} á -{\"a} ä -{\`A} À -{\'A} Á -{\"A} Ä -{\aa} å -{\AA} Å -{\ae} æ -{\bf 12} 12 -{\'c} ć -{\cal P} P -{\c{c}} ç -{\c{C}} Ç -{\c{e}} ȩ -{\c{s}} ş -{\c{S}} Ş -{\c{t}} ţ -{\-d} d -{\`e} è -{\^e} ê -{\'e} é -{\"e} ë -{\'E} É -{\em bits} bits -{\H{o}} ő -{\`i} ì -{\^i} î -{\i} ı -{\`i} ì -{\'i} í -{\"i} ï -{\`\i} ì -{\'\i} í -{\"\i} ï -{\`{\i}} ì -{\'{\i}} í -{\"{\i}} ï -{\it Note} Note -{\k{e}} ę -{\l} ł -{\-l} l -{\log} log -{\~n} ñ -{\'n} ń -{\^o} ô -{\o} ø -{\'o} ó -{\"o} ö -{\"{o}} ö -{\'O} Ó -{\"O} Ö -{\"{O}} Ö -{\rm always} always -{\-s} s -{\'s} ś -{\sc JoiN} JoiN -{\sl bit\/ \bf 7} bit 7 -{\sl L'Informatique Nouvelle} L’Informatique Nouvelle -{\small and} and -{\ss} ß -{\TeX} TeX -{\TM} ™ -{\tt awk} awk -{\^u} û -{\'u} ú -{\"u} ü -{\"{u}} ü -{\'U} Ú -{\"U} Ü -{\u{a}} ă -{\u{g}} ğ -{\v{c}} č -{\v{C}} Č -{\v{e}} ě -{\v{n}} ň -{\v{r}} ř -{\v{s}} š -{\v{S}} Š -{\v{z}} ž -{\v{Z}} Ž -{\'y} ý -{\.{z}} ż -Herv{\`e} Br{\"o}nnimann Hervè Brönnimann diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-coverage.t b/support/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-coverage.t deleted file mode 100644 index 3a818499f0..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-coverage.t +++ /dev/null @@ -1,21 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - - -use Test::More; - -eval "use Test::Pod::Coverage 1.08"; -plan skip_all => "Test::Pod::Coverage 1.08 required for testing POD coverage" - if $@; - -eval "use Pod::Coverage::TrustPod"; -plan skip_all => "Pod::Coverage::TrustPod required for testing POD coverage" - if $@; - -all_pod_coverage_ok({ coverage_class => 'Pod::Coverage::TrustPod' }); diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-syntax.t b/support/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-syntax.t deleted file mode 100644 index d46a955694..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/t/release-pod-syntax.t +++ /dev/null @@ -1,15 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - -use Test::More; - -eval "use Test::Pod 1.41"; -plan skip_all => "Test::Pod 1.41 required for testing POD" if $@; - -all_pod_files_ok(); diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/t/release-synopsis.t b/support/bibtexperllibs/LaTeX-ToUnicode/t/release-synopsis.t deleted file mode 100644 index 7a83682539..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/t/release-synopsis.t +++ /dev/null @@ -1,16 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - - -use Test::More; - -eval "use Test::Synopsis"; -plan skip_all => "Test::Synopsis required for testing synopses" - if $@; -all_synopsis_ok('lib'); diff --git a/support/bibtexperllibs/LaTeX-ToUnicode/weaver.ini b/support/bibtexperllibs/LaTeX-ToUnicode/weaver.ini deleted file mode 100644 index 1cc341ff23..0000000000 --- a/support/bibtexperllibs/LaTeX-ToUnicode/weaver.ini +++ /dev/null @@ -1,24 +0,0 @@ -[-Encoding] -[@CorePrep] - -[Name] -[Version] - -[Region / prelude] - -[Generic / SYNOPSIS] -[Generic / DESCRIPTION] -[Generic / OVERVIEW] - -[Collect / ATTRIBUTES] -command = attr - -[Collect / METHODS] -command = method - -[Leftovers] - -[Region / postlude] - -[Authors] -[Legal] diff --git a/support/bibtexperllibs/Makefile b/support/bibtexperllibs/Makefile deleted file mode 100644 index d1b0bdc84d..0000000000 --- a/support/bibtexperllibs/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# This is Makefile for TDS-compliant TeX distributions -# Written by Boris Veytsman, boris@varphi.com -# -# This file is in public domain -# - -PACKAGE = bibtexperllibs - -DIRS = BibTeX-Parser LaTeX-ToUnicode - -all: - -clean: - for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS clean); done - - -distclean: clean - for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS distclean); done - -install: - for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS install); done - -archive: - for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS docs); done - for dir in ${DIRS}; do (cd $$dir && ${MAKE} -f Makefile.TDS clean); done - COPYFILE_DISABLE=1 tar -czvf ../$(PACKAGE).tgz -C .. --exclude '*~' --exclude '*.tgz' --exclude CVS --exclude .git --exclude .gitignore --exclude blib --exclude "*.tar.gz" --exclude pm_to_blib $(PACKAGE) diff --git a/support/bibtexperllibs/README b/support/bibtexperllibs/README deleted file mode 100644 index fef3d0b276..0000000000 --- a/support/bibtexperllibs/README +++ /dev/null @@ -1,49 +0,0 @@ - BibTeX Perl Libs - Version 1.9 - Gerhard Gossen, Boris Veytsman, Karl Berry - -This package provides BibTeX-related Perl libraries by Gerhard Gossen, -maintained and repackaged by Boris Veytsman for TeX Live and other -TDS-compliant distributions. The libraries are written in pure Perl, -so shoud work out of the box on any architecture. - -To use them in your scripts, add to the @INC variable the directory -scripts/bibtexperllibs inside your TeX distribution. A script ltx2unitxt -packages the conversion libraries for use from the command line. - -Bug reports, source code: https://github.com/borisveytsman/bibtexperllibs -Releases: https://ctan.org/pkg/bibtexperllibs - -For an example of using the LaTeX::ToUnicode module, see the -crossrefware package (which is also the reason for continued development). - -Changes: - - version 1.9 2023-11-18 Now braces are rendered correctly by - LaTeX-ToUnicode - - version 1.8 2023-08-20 Tests updates, timestamp updates. - - version 1.7 2021-01-20 LaTeX::ToUnicode 0.51 for still more - ltx2crossrefxml support, including simple html output. - (No changes to BibTeX::Parser.) - - version 1.6 2020-12-10 LaTeX::ToUnicode 0.11 for more ltx2crossrefxml - support. (No changes to BibTeX::Parser.) - - version 1.5 Upgraded BibTeX::Parser to 1.02 (bugfixes) - - version 1.4 Upgraded BibTeX::Parser to 1.01 - - version 1.3 Upgraded BibTeX::Parser to 1.00 - - version 1.2 Upgraded BibTeX::Parser to v0.70 and LaTeX::ToUnicode to 0.05 - - version 1.1 Upgraded BibTeX::Parser to v0.69 - - version 1.0 Upgraded BibTeX::Parser to v0.68 and LaTeX::ToUnicode to 0.04 - - version 0.2 New upstream version for BibTeX::Parser (0.66) - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. diff --git a/support/crossrefware/Makefile b/support/crossrefware/Makefile index c8caf35d60..fb54525cba 100644 --- a/support/crossrefware/Makefile +++ b/support/crossrefware/Makefile @@ -25,6 +25,11 @@ check: pod2man -c "LATEX CROSSREFWARE" -n $* -s 1 -r "" $< > $@ +lastrel = /home/ftp/tex-archive/support/crossrefware +reldiff: + diff -u0r $(lastrel) . +gitdiff: + git diff clean: $(RM) *.aux *.toc *.log *.tex *.idx *.ilg *.ind *.out *.zip *.tgz *~ diff --git a/support/crossrefware/README b/support/crossrefware/README index 05d375253e..d2de384b79 100644 --- a/support/crossrefware/README +++ b/support/crossrefware/README @@ -1,5 +1,5 @@ Crossrefware Bundle - version 2024-01-31 + version 2024-08-27 Scripts useful for working with Crossref, MathSciNet and Zentralblatt MATH. @@ -30,9 +30,14 @@ Princeton University (Mathematics Department). Thank you! Changes: +2024-08-27 - output crossref schema 5.3.1: + https://www.crossref.org/documentation/schema-library/schema-versions/ + (and update various doc urls that crossref broke.) + - more documentation on the bib*add scripts. + 2024-01-31 - exit with bad status if no \end{thebibliography}. -2022-09-11 - add "***" prefix to bib warnings. +2022-09-11 - add "*** " prefix to bib warnings. 2022-07-28 - find dev checkout of bibtexperllibs. diff --git a/support/crossrefware/bibdoiadd.1 b/support/crossrefware/bibdoiadd.1 index 737f4f2a4b..1425b1e08d 100644 --- a/support/crossrefware/bibdoiadd.1 +++ b/support/crossrefware/bibdoiadd.1 @@ -55,7 +55,7 @@ .\" ======================================================================== .\" .IX Title "bibdoiadd 1" -.TH bibdoiadd 1 2023-08-20 "" "LATEX CROSSREFWARE" +.TH bibdoiadd 1 2024-09-02 "" "LATEX CROSSREFWARE" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -73,7 +73,7 @@ Configuration file. If this file is absent, some defaults are used. See below for its format. .IP "\fB\-C\fR 1|0" 4 .IX Item "-C 1|0" -Whether to canonize names in the output (1) or not (0). By default, 1. +Whether to canonicalize names in the output (1) or not (0). By default, 1. .IP \fB\-e\fR 4 .IX Item "-e" If 1 (default), add empty doi if a doi cannot be found. This prevents @@ -96,19 +96,29 @@ corresponding DOI. The result is a BibTeX file with the fields The name of the output file is either set by the \fB\-o\fR option or is derived by adding the suffix \f(CW\*(C`_doi\*(C'\fR to the output file. .PP -There are two options for making queries with Crossref: free account -and paid membership. In the first case you still must register with -Crossref and are limited to a small number of queries, see the +Every BibTeX record in the input is parsed, using BibTeX::Parser, but +only the ones that do not have the \f(CW\*(C`doi\*(C'\fR field (or \f(CW\*(C`mrnumber\*(C'\fR or +\&\f(CW\*(C`zblnumber\*(C'\fR for the sibling scripts) are processed. These entries +without the requested field are written back, as described in +BibTeX::Parser::Entry. +.PP +The bib records that are not processed (because they already have the +requested field) are written back as-is, without any reformatting. +.PP +There are (were?) two options for making queries with Crossref: free +account and paid membership. In the first case you still must register +with Crossref and are limited to a small number of queries, see the agreement at -\&\f(CW\*(C`http://www.crossref.org/01company/free_services_agreement.html\*(C'\fR. In +\&\f(CW\*(C`http://www.crossref.org/01company/free_services_agreement.html\*(C'\fR. In the second case you have a username and password, and can use them for -automatic queries. I am not sure whether the use of this script is -allowed for the free account holders. Anyway if you try to add DOI -to a large number of entries, you should register as a paid member. +automatic queries. I am not sure whether the use of this script is +allowed for the free account holders. At any rate, if you want to add +DOIs to a large number of entries, you should register as a paid member. .SH "CONFIGURATION FILE" .IX Header "CONFIGURATION FILE" -The configuration file is mostly self-explanatory: it has comments -(starting with \f(CW\*(C`#\*(C'\fR) and assginments in the form +The configuration file relates to the Crossref queries, and is mostly +self-explanatory: it has comments (starting with \f(CW\*(C`#\*(C'\fR) and assginments +in the form .PP .Vb 1 \& $field = value ; @@ -128,7 +138,7 @@ members. Boris Veytsman .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" -Copyright (C) 2014\-2021 Boris Veytsman +Copyright (C) 2014\-2024 Boris Veytsman .PP This is free software. You may redistribute copies of it under the terms of the GNU General Public License diff --git a/support/crossrefware/bibdoiadd.pl b/support/crossrefware/bibdoiadd.pl index bace84c000..91222af008 100755 --- a/support/crossrefware/bibdoiadd.pl +++ b/support/crossrefware/bibdoiadd.pl @@ -21,7 +21,7 @@ See below for its format. =item B<-C> 1|0 -Whether to canonize names in the output (1) or not (0). By default, 1. +Whether to canonicalize names in the output (1) or not (0). By default, 1. =item B<-e> @@ -50,22 +50,31 @@ C<doi=...> added. The name of the output file is either set by the B<-o> option or is derived by adding the suffix C<_doi> to the output file. -There are two options for making queries with Crossref: free account -and paid membership. In the first case you still must register with -Crossref and are limited to a small number of queries, see the +Every BibTeX record in the input is parsed, using BibTeX::Parser, but +only the ones that do not have the C<doi> field (or C<mrnumber> or +C<zblnumber> for the sibling scripts) are processed. These entries +without the requested field are written back, as described in +BibTeX::Parser::Entry. + +The bib records that are not processed (because they already have the +requested field) are written back as-is, without any reformatting. + +There are (were?) two options for making queries with Crossref: free +account and paid membership. In the first case you still must register +with Crossref and are limited to a small number of queries, see the agreement at -C<http://www.crossref.org/01company/free_services_agreement.html>. In +C<http://www.crossref.org/01company/free_services_agreement.html>. In the second case you have a username and password, and can use them for -automatic queries. I am not sure whether the use of this script is -allowed for the free account holders. Anyway if you try to add DOI -to a large number of entries, you should register as a paid member. - +automatic queries. I am not sure whether the use of this script is +allowed for the free account holders. At any rate, if you want to add +DOIs to a large number of entries, you should register as a paid member. =head1 CONFIGURATION FILE -The configuration file is mostly self-explanatory: it has comments -(starting with C<#>) and assginments in the form +The configuration file relates to the Crossref queries, and is mostly +self-explanatory: it has comments (starting with C<#>) and assginments +in the form $field = value ; @@ -85,7 +94,7 @@ Boris Veytsman =head1 COPYRIGHT AND LICENSE -Copyright (C) 2014-2021 Boris Veytsman +Copyright (C) 2014-2024 Boris Veytsman This is free software. You may redistribute copies of it under the terms of the GNU General Public License @@ -113,7 +122,7 @@ $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0; my $USAGE="USAGE: $0 [-c config] [-C 1|0] [-e 1|0] [-f] [-o output] file\n"; my $VERSION = <<END; -bibdoiadd v2.2 +bibdoiadd v2.3 This is free software. You may redistribute copies of it under the terms of the GNU General Public License http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the @@ -258,7 +267,7 @@ sub GetDoi { if ($entry->has('pages')) { my $pages=$entry->field('pages'); $pages =~ s/-.*$//; - $url .= "&spage=".uri_escape_utf8($pages); + $url .= "&spage=".uri_escape_utf8($pages); } if ($entry->has('year')) { $url .= "&date=".uri_escape_utf8($entry->field('year')); @@ -296,4 +305,3 @@ sub SanitizeText { $string =~ s/[\{\}]//g; return $string; } - diff --git a/support/crossrefware/bibmradd.1 b/support/crossrefware/bibmradd.1 index ee49fd5238..54e5c43095 100644 --- a/support/crossrefware/bibmradd.1 +++ b/support/crossrefware/bibmradd.1 @@ -55,7 +55,7 @@ .\" ======================================================================== .\" .IX Title "bibmradd 1" -.TH bibmradd 1 2023-08-20 "" "LATEX CROSSREFWARE" +.TH bibmradd 1 2024-09-02 "" "LATEX CROSSREFWARE" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -84,19 +84,20 @@ Output file. If this option is not used, the name for the output file is formed by adding \f(CW\*(C`_mr\*(C'\fR to the input file .SH DESCRIPTION .IX Header "DESCRIPTION" -The script reads a BibTeX file. It checks whether the entries have -mrnumberss. If not, tries to contact internet to get the numbers. The -result is a BibTeX file with the fields -\&\f(CW\*(C`mrnumber=...\*(C'\fR added. +The script reads a BibTeX file. It checks whether the entries have +mrnumbers. If not, it tries to find the numbers from Internet sites. The +result is a BibTeX file with \f(CW\*(C`mrnumber=...\*(C'\fR fields added. .PP The name of the output file is either set by the \fB\-o\fR option or is derived by adding the suffix \f(CW\*(C`_mr\*(C'\fR to the output file. +.PP +See the \f(CW\*(C`bibdoiadd\*(C'\fR script for more details on the processing. .SH AUTHOR .IX Header "AUTHOR" Boris Veytsman .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" -Copyright (C) 2014\-2022 Boris Veytsman +Copyright (C) 2014\-2024 Boris Veytsman .PP This is free software. You may redistribute copies of it under the terms of the GNU General Public License diff --git a/support/crossrefware/bibmradd.pl b/support/crossrefware/bibmradd.pl index 3fea62e3c5..5a0b5a30f7 100755 --- a/support/crossrefware/bibmradd.pl +++ b/support/crossrefware/bibmradd.pl @@ -38,21 +38,22 @@ output file is formed by adding C<_mr> to the input file =head1 DESCRIPTION -The script reads a BibTeX file. It checks whether the entries have -mrnumberss. If not, tries to contact internet to get the numbers. The -result is a BibTeX file with the fields -C<mrnumber=...> added. +The script reads a BibTeX file. It checks whether the entries have +mrnumbers. If not, it tries to find the numbers from Internet sites. The +result is a BibTeX file with C<mrnumber=...> fields added. The name of the output file is either set by the B<-o> option or is derived by adding the suffix C<_mr> to the output file. +See the C<bibdoiadd> script for more details on the processing. + =head1 AUTHOR Boris Veytsman =head1 COPYRIGHT AND LICENSE -Copyright (C) 2014-2022 Boris Veytsman +Copyright (C) 2014-2024 Boris Veytsman This is free software. You may redistribute copies of it under the terms of the GNU General Public License @@ -91,7 +92,7 @@ $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0; my $USAGE="USAGE: $0 [-d] [-e 1|0] [-f] [-o output] file\n"; my $VERSION = <<END; -bibmradd v2.2 +bibmradd v2.3 This is free software. You may redistribute copies of it under the terms of the GNU General Public License http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the @@ -220,4 +221,3 @@ sub GetMr { } } - diff --git a/support/crossrefware/bibzbladd.1 b/support/crossrefware/bibzbladd.1 index 755536c73b..ce4240144e 100644 --- a/support/crossrefware/bibzbladd.1 +++ b/support/crossrefware/bibzbladd.1 @@ -55,7 +55,7 @@ .\" ======================================================================== .\" .IX Title "bibzbladd 1" -.TH bibzbladd 1 2023-08-20 "" "LATEX CROSSREFWARE" +.TH bibzbladd 1 2024-09-02 "" "LATEX CROSSREFWARE" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -85,18 +85,19 @@ output file is formed by adding \f(CW\*(C`_zbl\*(C'\fR to the input file .SH DESCRIPTION .IX Header "DESCRIPTION" The script reads a BibTeX file. It checks whether the entries have -Zbls. If not, tries to contact internet to get the numbers. The -result is a BibTeX file with the fields -\&\f(CW\*(C`zblnumber=...\*(C'\fR added. +Zbls. If not, it tries to find the numbers from Internet sites. The +result is a BibTeX file with \f(CW\*(C`zblnumber=...\*(C'\fR fields added. .PP The name of the output file is either set by the \fB\-o\fR option or is derived by adding the suffix \f(CW\*(C`_zbl\*(C'\fR to the output file. +.PP +See the \f(CW\*(C`bibdoiadd\*(C'\fR script for more details on the processing. .SH AUTHOR .IX Header "AUTHOR" Boris Veytsman .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" -Copyright (C) 2014\-2021 Boris Veytsman +Copyright (C) 2014\-2024 Boris Veytsman .PP This is free software. You may redistribute copies of it under the terms of the GNU General Public License diff --git a/support/crossrefware/bibzbladd.pl b/support/crossrefware/bibzbladd.pl index c05a1137f7..549d1cb0db 100755 --- a/support/crossrefware/bibzbladd.pl +++ b/support/crossrefware/bibzbladd.pl @@ -24,7 +24,6 @@ If 1 (default), add an empty zblnumber if a zbl cannot be found. This prevents repeated searches for the same entries if you add new entries to the file. Calling C<-e 0> suppresses this behavior. - =item B<-f> Force searching for Zbl numbers even if the entry already has one. @@ -39,20 +38,21 @@ output file is formed by adding C<_zbl> to the input file =head1 DESCRIPTION The script reads a BibTeX file. It checks whether the entries have -Zbls. If not, tries to contact internet to get the numbers. The -result is a BibTeX file with the fields -C<zblnumber=...> added. +Zbls. If not, it tries to find the numbers from Internet sites. The +result is a BibTeX file with C<zblnumber=...> fields added. The name of the output file is either set by the B<-o> option or is derived by adding the suffix C<_zbl> to the output file. +See the C<bibdoiadd> script for more details on the processing. + =head1 AUTHOR Boris Veytsman =head1 COPYRIGHT AND LICENSE -Copyright (C) 2014-2021 Boris Veytsman +Copyright (C) 2014-2024 Boris Veytsman This is free software. You may redistribute copies of it under the terms of the GNU General Public License @@ -78,7 +78,7 @@ $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0; my $USAGE="USAGE: $0 [-d] [-e 1|0] [-f] [-o output] file\n"; my $VERSION = <<END; -bibzbladd v2.2 +bibzbladd v2.3 This is free software. You may redistribute copies of it under the terms of the GNU General Public License http://www.gnu.org/licenses/gpl.html. There is NO WARRANTY, to the @@ -202,4 +202,3 @@ sub GetZbl { } } - diff --git a/support/crossrefware/crossrefware.pdf b/support/crossrefware/crossrefware.pdf Binary files differindex 83b8d3e8a3..18c39074d5 100644 --- a/support/crossrefware/crossrefware.pdf +++ b/support/crossrefware/crossrefware.pdf diff --git a/support/crossrefware/head.ltx b/support/crossrefware/head.ltx index 72ae89028e..21d2b2d9bb 100644 --- a/support/crossrefware/head.ltx +++ b/support/crossrefware/head.ltx @@ -30,13 +30,15 @@ upload the submission, just outputs XML. This \path{.rpi} file is a plain text representation of the metadata for one article. It is written by the \path{resphilosophica} package -(\url{https://ctan.org/pkg/resphilosophica}). It can also be created by -hand. +(\url{https://ctan.org/pkg/resphilosophica}) and the TUGboat publication +procedure (\url{https://tug.org/TUGboat/repository.html}). It can also +be created by hand. Several scripts, \path{bibdoiadd}, \path{bibmradd} and \path{bibzbladd} take a \path{bib} file, and add to each entry a DOI, MR or ZBL number correspondingly, if they can find this entry in the corresponding -database. +database. The output of these scripts reformats the BibTeX entries +where the respective fields were not already present. The \path{bbl2bib} script tries to reconstruct a \path{bib} file from the corresponding \path{thebibliography} environment. One can argue that @@ -44,7 +46,10 @@ this operation is akin to reconstructing the cow from a steak. The way the script does it is by searching for the entry in the MR database, and creating the corresponding Bib\TeX\ fields. -I am grateful to Josko Plazonic from Princeton Math Dept whose -(unpublished) Python script was an inspiration for this suite. +I am grateful to Josko Plazonic from the Princeton mathematics +department whose (unpublished) Python script was an inspiration for this +suite. -Following are manual pages for these scripts. +Following are manual pages for these scripts. See also the +\texttt{BibTeX::Parser} package +(\url{https://ctan.org/pkg/bibtexperllibs}). diff --git a/support/crossrefware/ltx2crossrefxml.1 b/support/crossrefware/ltx2crossrefxml.1 index 9f6800d8b7..5c9fc681e2 100644 --- a/support/crossrefware/ltx2crossrefxml.1 +++ b/support/crossrefware/ltx2crossrefxml.1 @@ -55,7 +55,7 @@ .\" ======================================================================== .\" .IX Title "ltx2crossrefxml 1" -.TH ltx2crossrefxml 1 2024-02-03 "" "LATEX CROSSREFWARE" +.TH ltx2crossrefxml 1 2024-09-02 "" "LATEX CROSSREFWARE" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -91,8 +91,10 @@ ignored, and \fIlatex_file\fR itself is not read (and need not even exist). Each \f(CW\*(C`.rpi\*(C'\fR file specifies the metadata for a single article to be uploaded to Crossref (a \f(CW\*(C`journal_article\*(C'\fR element in their schema); an example is below. These files are output by the \f(CW\*(C`resphilosophica\*(C'\fR -package (<https://ctan.org/pkg/resphilosophica>), but (as always) can -also be created by hand or by whatever other method you implement. +package (<https://ctan.org/pkg/resphilosophica>) and the TUGboat +publication procedure (<https://tug.org/TUGboat/repository.html>), but +(as always) can also be created by hand or by whatever other method you +implement. .PP Any \f(CW\*(C`.bbl\*(C'\fR files present are used for the citation information in the output XML. See the CITATIONS section below. @@ -102,18 +104,25 @@ citations), standard TeX control sequences are replaced with plain text or UTF\-8 or eliminated, as appropriate. The \f(CW\*(C`LaTeX::ToUnicode::convert\*(C'\fR routine is used for this (<https://ctan.org/pkg/bibtexperllibs>). Tricky TeX control sequences will almost surely not be handled -correctly. If \f(CW\*(C`\-\-rpi\-is\-xml\*(C'\fR is given, the author and title strings -from the rpi files are output as-is, assuming they are valid XML; no -checking is done. Citation text from \f(CW\*(C`.bbl\*(C'\fR files is always converted -from LaTeX to plain text. +correctly. .PP -This script just writes an XML file. It's up to you to actually do the +If \f(CW\*(C`\-\-rpi\-is\-xml\*(C'\fR is given, the author and title strings from the rpi +files are output as-is, assuming they are valid XML; no checking is +done. +.PP +Citation text from \f(CW\*(C`.bbl\*(C'\fR files is always converted from LaTeX to plain +text. +.PP +This script just writes an XML file. It's up to you to do the uploading to Crossref; for example, you can use their Java tool \&\f(CW\*(C`crossref\-upload\-tool.jar\*(C'\fR (<https://www.crossref.org/education/member\-setup/direct\-deposit\-xml/https\-post>). -For the definition of their schema, see -<https://data.crossref.org/reports/help/schema_doc/4.4.2/index.html> -(this is the schema version currently followed by this script). +.PP +For the definition of the Crossref schema currently output by this +script, see +<https://data.crossref.org/reports/help/schema_doc/5.3.1/index.html> +with additional links and information at +<https://www.crossref.org/documentation/schema\-library/metadata\-deposit\-schema\-5\-3\-1/>. .SH "CONFIGURATION FILE FORMAT" .IX Header "CONFIGURATION FILE FORMAT" The configuration file is read as Perl code. Thus, comment lines @@ -188,7 +197,8 @@ Any other journal must always specify this. The \f(CW%authors\fR field is split at \f(CW\*(C`\eand\*(C'\fR (ignoring whitespace before and after), and output as the \f(CW\*(C`contributors\*(C'\fR element, using \&\f(CW\*(C`sequence="first"\*(C'\fR for the first listed, \f(CW\*(C`sequence="additional"\*(C'\fR for -the remainder. +the remainder. The authors are parsed using \f(CW\*(C`BibTeX::Parser::Author\*(C'\fR +(<https://ctan.org/pkg/bibtexperllibs>). .PP If the \f(CW%publicationType\fR is not specified, it defaults to \&\f(CW\*(C`full_text\*(C'\fR, since that has historically been the case; \f(CW\*(C`full_text\*(C'\fR @@ -200,8 +210,7 @@ from the given \f(CW\*(C`journal_article\*(C'\fR element. Each \f(CW\*(C`.rpi\*(C'\fR must contain information for only one article, but multiple files can be read in a single run. It would not be difficult to support multiple articles in a single \f(CW\*(C`.rpi\*(C'\fR file, but it makes debugging and -error correction easier when each uploaded XML contains a single -article. +error correction easier to keep the input to one article per file. .SS "MORE ABOUT AUTHOR NAMES" .IX Subsection "MORE ABOUT AUTHOR NAMES" The three formats for names recognized are (not coincidentally) the same @@ -220,7 +229,8 @@ separators are not supported, unlike BibTeX. In short, you may almost always use the first form; you shouldn't if either there's a Jr part, or the Last part has multiple tokens but there's no von part. See the \f(CW\*(C`btxdoc\*(C'\fR (``BibTeXing'' by Oren Patashnik) -document for details. +document for details. The authors are parsed using +\&\f(CW\*(C`BibTeX::Parser::Author\*(C'\fR (<https://ctan.org/pkg/bibtexperllibs>). .PP In the \f(CW%authors\fR line of a \f(CW\*(C`.rpi\*(C'\fR file, some secondary directives are recognized, indicated by \f(CW\*(C`|\*(C'\fR characters. Easiest to explain with an @@ -284,12 +294,17 @@ this same format. .PP Feature request: if anyone is interested in figuring out how to generate structured citations -(<https://data.crossref.org/reports/help/schema_doc/5.3.1/schema_5_3_1.html#citation>) -instead of these flat text dumps, that would be great. Except the schema -seems to support much less than described at -<https://www.crossref.org/documentation/principles\-practices/best\-practices/bibliographic/>? -Anyway, the most viable approach is probably to change tugboat.bst to -output no-op TeX commands like \etubibauthor, \etubibtitle, etc. (a la +(<https://data.crossref.org/reports/help/schema_doc/5.3.1/common5_3_1_xsd.html#citation>), +that would be great. The schema does not support many useful fields, so +we also want to keep the unstructured text output. +.PP +Norman Gray's beastie program (<https://heptapod.host/nxg/beastie>) +supports this, via \f(CW\*(C`beastie extract\-bib.scm \-O crossref $(doc).aux\*(C'\fR, +as invoked in the TUGboat \f(CW\*(C`Common.mak\*(C'\fR file. Work in progress. +.PP +By the way, if for some reason we have to switch away from using +beastie, the most viable approach is probably to change \f(CW\*(C`tugboat.bst\*(C'\fR +to output no-op TeX commands like \etubibauthor, \etubibtitle, etc. (a la biblatex), and use those commands to discern the various crossref field values. We can't start from the .bib because then we'd have to reimplement Bib(La)TeX. diff --git a/support/crossrefware/ltx2crossrefxml.pl b/support/crossrefware/ltx2crossrefxml.pl index 5d8e16b383..80c7218758 100755 --- a/support/crossrefware/ltx2crossrefxml.pl +++ b/support/crossrefware/ltx2crossrefxml.pl @@ -43,8 +43,10 @@ ignored, and I<latex_file> itself is not read (and need not even exist). Each C<.rpi> file specifies the metadata for a single article to be uploaded to Crossref (a C<journal_article> element in their schema); an example is below. These files are output by the C<resphilosophica> -package (L<https://ctan.org/pkg/resphilosophica>), but (as always) can -also be created by hand or by whatever other method you implement. +package (L<https://ctan.org/pkg/resphilosophica>) and the TUGboat +publication procedure (L<https://tug.org/TUGboat/repository.html>), but +(as always) can also be created by hand or by whatever other method you +implement. Any C<.bbl> files present are used for the citation information in the output XML. See the L<CITATIONS> section below. @@ -54,18 +56,25 @@ citations), standard TeX control sequences are replaced with plain text or UTF-8 or eliminated, as appropriate. The C<LaTeX::ToUnicode::convert> routine is used for this (L<https://ctan.org/pkg/bibtexperllibs>). Tricky TeX control sequences will almost surely not be handled -correctly. If C<--rpi-is-xml> is given, the author and title strings -from the rpi files are output as-is, assuming they are valid XML; no -checking is done. Citation text from C<.bbl> files is always converted -from LaTeX to plain text. +correctly. -This script just writes an XML file. It's up to you to actually do the +If C<--rpi-is-xml> is given, the author and title strings from the rpi +files are output as-is, assuming they are valid XML; no checking is +done. + +Citation text from C<.bbl> files is always converted from LaTeX to plain +text. + +This script just writes an XML file. It's up to you to do the uploading to Crossref; for example, you can use their Java tool C<crossref-upload-tool.jar> (L<https://www.crossref.org/education/member-setup/direct-deposit-xml/https-post>). -For the definition of their schema, see -L<https://data.crossref.org/reports/help/schema_doc/4.4.2/index.html> -(this is the schema version currently followed by this script). + +For the definition of the Crossref schema currently output by this +script, see +L<https://data.crossref.org/reports/help/schema_doc/5.3.1/index.html> +with additional links and information at +L<https://www.crossref.org/documentation/schema-library/metadata-deposit-schema-5-3-1/>. =head1 CONFIGURATION FILE FORMAT @@ -136,7 +145,8 @@ Any other journal must always specify this. The C<%authors> field is split at C<\and> (ignoring whitespace before and after), and output as the C<contributors> element, using C<sequence="first"> for the first listed, C<sequence="additional"> for -the remainder. +the remainder. The authors are parsed using C<BibTeX::Parser::Author> +(L<https://ctan.org/pkg/bibtexperllibs>). If the C<%publicationType> is not specified, it defaults to C<full_text>, since that has historically been the case; C<full_text> @@ -148,8 +158,7 @@ from the given C<journal_article> element. Each C<.rpi> must contain information for only one article, but multiple files can be read in a single run. It would not be difficult to support multiple articles in a single C<.rpi> file, but it makes debugging and -error correction easier when each uploaded XML contains a single -article. +error correction easier to keep the input to one article per file. =head2 MORE ABOUT AUTHOR NAMES @@ -167,7 +176,8 @@ separators are not supported, unlike BibTeX. In short, you may almost always use the first form; you shouldn't if either there's a Jr part, or the Last part has multiple tokens but there's no von part. See the C<btxdoc> (``BibTeXing'' by Oren Patashnik) -document for details. +document for details. The authors are parsed using +C<BibTeX::Parser::Author> (L<https://ctan.org/pkg/bibtexperllibs>). In the C<%authors> line of a C<.rpi> file, some secondary directives are recognized, indicated by C<|> characters. Easiest to explain with an @@ -230,12 +240,17 @@ this same format. Feature request: if anyone is interested in figuring out how to generate structured citations -(L<https://data.crossref.org/reports/help/schema_doc/5.3.1/schema_5_3_1.html#citation>) -instead of these flat text dumps, that would be great. Except the schema -seems to support much less than described at -L<https://www.crossref.org/documentation/principles-practices/best-practices/bibliographic/>? -Anyway, the most viable approach is probably to change tugboat.bst to -output no-op TeX commands like \tubibauthor, \tubibtitle, etc. (a la +(L<https://data.crossref.org/reports/help/schema_doc/5.3.1/common5_3_1_xsd.html#citation>), +that would be great. The schema does not support many useful fields, so +we also want to keep the unstructured text output. + +Norman Gray's beastie program (L<https://heptapod.host/nxg/beastie>) +supports this, via C<beastie extract-bib.scm -O crossref $(doc).aux>, +as invoked in the TUGboat C<Common.mak> file. Work in progress. + +By the way, if for some reason we have to switch away from using +beastie, the most viable approach is probably to change C<tugboat.bst> +to output no-op TeX commands like \tubibauthor, \tubibtitle, etc. (a la biblatex), and use those commands to discern the various crossref field values. We can't start from the .bib because then we'd have to reimplement Bib(La)TeX. @@ -273,7 +288,7 @@ extent permitted by law. # find files relative to our installed location within TeX Live chomp(my $TLMaster = `kpsewhich -var-value=TEXMFROOT`); # TL root if (length($TLMaster)) { - unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs"; + unshift @INC, "$TLMaster/texmf-dist/scripts/bibtexperllibs"; } # find development bibtexperllibs in sibling checkout to this script, # even if $0 is a symlink. All irrelevant when using from an installation. @@ -292,15 +307,17 @@ extent permitted by law. my $USAGE = <<END; Usage: $0 [-c CONFIG] [-o OUTPUT] [--rpi-is-xml] LTXFILE... -Convert .rpi and (if any are present) .bbl files corresponding to each -LTXFILE to xml, for submitting to crossref.org. The LTXFILE is not read -(and need not even exist); any extension it has is replaced by .rpi and -.bbl. +Convert .rpi and (if any are present) .bbl and .crbib files +corresponding to each LTXFILE to xml, for submitting to crossref.org. +The LTXFILE is not read, and need not even exist; any extension given is +replaced by .rpi, .bbl, .crbib. The .rpi files are plain text, with values on lines beginning with %, as output by (for example) the resphilosophica LaTeX package. The .bbl -files are as output by BibTeX. Both are also commonly created by hand. -The documentation for this script has examples. +files are as output by BibTeX. The .crbib files are xml files ready for +incorporation in the final xml, as output by the beastie program. All +may also be created by other methods. The documentation for this script +has examples. The xml is written to standard output by default; the -o (--output) option overrides this. @@ -314,6 +331,8 @@ For an example of using this script and associatd code, see the TUGboat processing at https://github.com/TeXUsersGroup/tugboat/tree/trunk/capsules/crossref. +This script depends on https://github.com/borisveytsman/bibtexperllibs. + Development sources, bug tracker: https://github.com/borisveytsman/crossrefware Releases: https://ctan.org/pkg/crossrefware END @@ -343,6 +362,7 @@ END use utf8; binmode(STDOUT, ":utf8"); + ################################################################ # Defaults and parameters ################################################################ @@ -365,7 +385,7 @@ END our $timestamp = strftime("%Y%m%d%H%M%S", gmtime); # use timestamp in batchid, since the value is supposed to be unique # for every submission to crossref by a given publisher. - # https://data.crossref.org/reports/help/schema_doc/4.4.2/schema_4_4_2.html#doi_batch_id + # https://data.crossref.org/reports/help/schema_doc/5.3.1/common5_3_1_xsd.html#doi_batch_id our $batchId="ltx2crossref-$timestamp-$$"; if ($opts{c}) { @@ -373,9 +393,9 @@ END # if config arg is absolute, fine; if not, prepend "./" as slightly # less troublesome than putting "." in the @INC path. my $rel = (File::Spec->file_name_is_absolute($opts{c}) ? "" : "./"); - require "$rel$opts{c}"; + require "$rel$opts{c}"; } else { - die "Cannot read config file $opts{c}. Goodbye."; + die "Cannot read config file $opts{c}. Goodbye."; } } @@ -386,30 +406,32 @@ END # my %papers; + # Read the papers. foreach my $file (@ARGV) { AddPaper($file); } + # Write the papers. foreach my $year (keys %papers) { foreach my $volume (keys %{$papers{$year}}) { - foreach my $issue (keys %{$papers{$year}->{$volume}}) { - PrintIssueHead($year, $volume, $issue); - my $paperList = $papers{$year}->{$volume}->{$issue}; + foreach my $issue (keys %{$papers{$year}->{$volume}}) { + PrintIssueHead($year, $volume, $issue); + my $paperList = $papers{$year}->{$volume}->{$issue}; #warn "papers for year=$year, volume=$volume, issue=$issue\n"; # Nice to have the issue.xml in some stable order, so sort # by starting page. Doesn't matter if it's not perfect. - foreach my $paper (sort { $a->{startpage} <=> $b->{startpage} } - @{$paperList}) { - PrintPaper($paper); - } - } + foreach my $paper (sort { $a->{startpage} <=> $b->{startpage} } + @{$paperList}) { + PrintPaper($paper); + } + } } } PrintTail(); exit($ERROR_COUNT); - + ##################################################### # Printing the head and the tail ##################################################### @@ -422,12 +444,10 @@ sub PrintHead { ? "\n$indent<abbrev_title>$abbrevTitle</abbrev_title>" : ""; - # as of schema version 4.3.4, crossref renamed the <name> element - # inside <depositor> to <depositor_name>. Sigh. Something to take - # into account with older schemas. - # https://www.crossref.org/education/content-registration/crossrefs-metadata-deposit-schema/schema-versions/ + # Crossref schema info: + # https://www.crossref.org/documentation/schema-library/schema-versions/ print OUT <<END; -<doi_batch xmlns="http://www.crossref.org/schema/4.4.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="4.4.2" xsi:schemaLocation="http://www.crossref.org/schema/4.4.2 http://www.crossref.org/schema/deposit/crossref4.4.2.xsd"> +<doi_batch xmlns="http://www.crossref.org/schema/5.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5.3.1" xsi:schemaLocation="http://www.crossref.org/schema/5.3.1 http://www.crossref.org/schema/deposit/crossref5.3.1.xsd"> <head> <doi_batch_id>$batchId</doi_batch_id> <timestamp>$timestamp</timestamp> @@ -440,7 +460,7 @@ sub PrintHead { <body><journal> <journal_metadata language="en"> <full_title>$fullTitle</full_title>$abbrev_title_out - <issn>$issn</issn>$coden_out + <issn>$issn</issn>$coden_out </journal_metadata> END } @@ -454,20 +474,20 @@ END return; } - + ####################################################### -# Adding one paper from $file.rpi and .bbl to global %papers. +# Adding one paper from $file.rpi and .bbl and .crbib to global %papers. ####################################################### sub AddPaper { my $file = shift; my ($name,$path,$suffix) = fileparse($file, '\.[^\.]*$'); my $rpifile = File::Spec->catfile($path, "$name.rpi"); open (RPI, $rpifile) - or die "open($rpifile) failed: $! (did you process $file?)\n"; + or die "$0: open($rpifile) failed: $! (did you process $file?)\n"; my %data; #warn "reading rpi file: $rpifile\n"; while (<RPI>) { - chomp; + chomp; if (/^%([^=]*)\s*=\s*(.*)\s*$/) { if (exists $data{$1}) { warn "$rpifile:$.: already saw data{$1}=$data{$1};" @@ -479,12 +499,15 @@ sub AddPaper { } close RPI; - # look for bibliographies in both the .rpi and any .bbl file. + # also look for bibliographies in FILE.bbl and FILE.crbib files. my @bibliography; - foreach my $bibfile ($file, File::Spec->catfile($path, "$name.bbl")) { - @bibliography = (@bibliography, AddBibliography($bibfile)); + foreach my $bblfile ($rpifile, File::Spec->catfile($path, "$name.bbl")) { + push (@bibliography, AddBibliography($bblfile)); } $data{'bibliography'} = \@bibliography; + # + $data{'crbib'} + = AddCrossrefBib (File::Spec->catfile($path, "$name.crbib")); # Die if the fields we use unconditionally are empty. Not all of # them are required by the schema, but we can wait to generalize. @@ -500,13 +523,15 @@ sub AddPaper { push @{$papers{$data{year}}->{$data{volume}}->{$data{issue}}}, \%data; } + ############################################################## -# Reading a list of papers from BIBFILE and adding it to the +# Read a list of references from BIBFILE and adding it to the # bibliography. Each item is assumed to start with # \bibitem{KEY} and the whole bib to end with \end{thebibliography}. # # We return a list of hashes, each hash with a single key, the citation -# key, and its value a flat string of the entry. +# key with an integer (starting at 1), and its value a flat string of +# the entry. # # No conversion of the text is done here. ############################################################## @@ -515,59 +540,59 @@ sub AddBibliography { open (BIB, $bibfile) or return; my $insidebibliography = 0; - my $currpaper = ""; # that is, the current bib entry + my $currpaper = ""; # the current bib entry my $bibno = 0; my @result; my $key; while (<BIB>) { - chomp; - next if /^\s*%/; # TeX comment line - s/[ \t]%.*//; # remove TeX comment - # - # allow empty \bibitem key for the sake of handwritten bbls. - # Similarly, might be more stuff on the line when handwritten. - # Ignore a TeX %comment following. - if (s/^\s*\\bibitem(?:\[.*?\])?+\s*\{(.*?)\}\s*(%.*$)?//) { - my $newkey = $1; - if ($insidebibliography) { - if ($currpaper) { + chomp; + next if /^\s*%/; # TeX comment line + s/[ \t]%.*//; # remove TeX comment + # + # allow empty \bibitem key for the sake of handwritten bbls. + # Similarly, might be more stuff on the line when handwritten. + # Ignore a TeX %comment following. + if (s/^\s*\\bibitem(?:\[.*?\])?+\s*\{(.*?)\}\s*(%.*$)?//) { + my $newkey = $1; + if ($insidebibliography) { + if ($currpaper) { # Append the current sequence number for this citation, # since that's what Crossref recommends (sort of). # For prettiness, if the key is otherwise empty, # don't include a dash beforehand. - $bibno++; + $bibno++; $key .= ($key ? "-" : "") . $bibno; # my %paperhash; - $paperhash{$key} = $currpaper; - push @result, \%paperhash; - } - } - # The citation key (required by schema) starts as the bibitem key. - $key = $newkey; - - $currpaper = $_; - $insidebibliography = 1; - next; - } - if (/^\s*\\end\{thebibliography\}/) { - if ($currpaper) { - $bibno++; + $paperhash{$key} = $currpaper; + push @result, \%paperhash; + } + } + # The citation key (required by schema) starts as the bibitem key. + $key = $newkey; + + $currpaper = $_; + $insidebibliography = 1; + next; + } + if (/^\s*\\end\{thebibliography\}/) { + if ($currpaper) { + $bibno++; $key .= ($key ? "-" : "") . $bibno; # - my %paperhash; - $paperhash{$key} = $currpaper; - push @result, \%paperhash; - } - $currpaper = ""; - $insidebibliography = 0; - next; - } - if ($insidebibliography) { - $currpaper .= " $_"; - } + my %paperhash; + $paperhash{$key} = $currpaper; + push @result, \%paperhash; + } + $currpaper = ""; + $insidebibliography = 0; + next; + } + if ($insidebibliography) { + $currpaper .= " $_"; + } } - close BIB; + close BIB or warn "close($bibfile) failed: $!"; # We look in the .rpi files too, which will generally have none. if (@result == 0 && $bibfile =~ /\.bbl$/) { @@ -580,6 +605,75 @@ sub AddBibliography { return @result; } + +############################################################## +# Read an XML <citation_list> element from CRBIBFILE, if it exists. +# No error if it doesn't exist; it often won't, even if there is a bbl file. +# +# Return a hash reference, with each element's key being the citation +# key plus an integer, the same keys as in AddBibliography from the .bbl +# file.# Each value is a flat string, the structured citation items for +# that element. +# +# We ignore any <unstructured_citation> element, since we generate our +# own (which we prefer). +# +# We don't parse XML, just extract the pieces with regexps. +# This is generated by Norman Gray's beastie program. Example: +# <citation_list> +# <citation key="bookshelf"> +# <author>Peter Flynn</author> +# <volume_title>The bookshelf package</volume_title> +# <cYear>2020</cYear> +# <unstructured_citation>Flynn, Peter (manual): The bookshelf package[...] +# </citation> +# <citation key="Calibre"> +# <author>Kovid Goyal</author> +# <volume_title>calibre User Manual</volume_title> +# <cYear>2024</cYear> +# <unstructured_citation>Kovid Goyal (manual): calibre User Manual[...] +# </citation> +# </citation_list> +############################################################## +sub AddCrossrefBib { + my ($crbibfile,$refs) = @_; + my %result; + + #warn "crbibfile=$crbibfile\n"; + open (CRBIB, $crbibfile) or return; + + # read whole file. + my $crbib_as_string = join("", <CRBIB>); + #warn "doing crbib $crbibfile; $crbib_as_string\n"; + close (CRBIB) or warn "close($crbibfile) failed: $!"; + + my $bibno = 0; + + # We're matching each <citation> here by virtue of .*? to be a + # non-greedy match, the /s modifier to treat the whole thing as one + # string, and the /g modifier to return an array of all matches. + my @crbib = ($crbib_as_string =~ m,<citation\s+(key=.*?)</citation>,sg); + for my $crb (@crbib) { + $bibno++; + + # wipe out the unstructured text. + $crb =~ s,\s*<unstructured_citation>.*</unstructured_citation>\s*,,; + + $crb = SanitizeTextNoEntities($crb); + + # qqq undone - must save by key, then write by key into the xml. + # need to be able to clean the text, beastie removes braces. + warn "crb $bibno: $crb\n"; + } + + if ($bibno == 0) { + warn "$0: *** no crossref cites found in: $crbibfile; check if ok\n"; + } + + return %result; +} + + ################################################################# # Printing information about one issue ################################################################# @@ -596,8 +690,9 @@ sub PrintIssueHead { END } + ############################################################### -# Printing information about one paper +# Printing information about one paper ############################################################### sub PrintPaper { my $paper = shift; @@ -617,7 +712,7 @@ END my @authors = split /\s*\\and\s*/, $paper->{authors}; my $seq = 'first'; foreach my $author (@authors) { - PrintAuthor($author, $seq); + PrintAuthor($author, $seq); $seq = 'additional'; } @@ -638,15 +733,7 @@ END END if (scalar(@{$paper->{bibliography}})) { - print OUT <<END; - <citation_list> -END - foreach my $citation (@{$paper->{bibliography}}) { - PrintCitation($citation); - } - print OUT <<END; - </citation_list> -END + PrintCitationList($paper->{bibliography}, $paper->{crbib}); } print OUT <<END; @@ -654,16 +741,15 @@ END END } - + ############################################################### # Crossref <title> strings can contain a few so-called "face" HTML # commands. Complain if they have anything anything else. -# schema doc: https://data.crossref.org/reports/help/schema_doc/4.4.2/schema_4_4_2.html#title -# face doc: https://www.crossref.org/education/content-registration/crossrefs-metadata-deposit-schema/face-markup/ -# mathml doc: https://www.crossref.org/education/content-registration/crossrefs-metadata-deposit-schema/including-mathml-in-deposits/ +# schema doc: https://data.crossref.org/reports/help/schema_doc/5.3.1/crossref5_3_1_xsd.html#title +# face doc: https://www.crossref.org/documentation/schema-library/markup-guide-metadata-segments/face-markup/ # # We don't technically validate the string, e.g., mismatched tags will -# go unnoticed here. The real validator at Crossref will catch whatever. +# go unnoticed here. The real validator at Crossref should catch everything. ############################################################### sub TitleCheck { my $title = shift; @@ -686,33 +772,7 @@ sub TitleCheck { } } -############################################################### -# Simplistic TeX-to-html -# (no-op for rpi text if --input-is-xml was given). -############################################################### -sub SanitizeText { - my $string = shift; - return $string if $opts{xi}; # do nothing if --rpi-is-xml - return SanitizeTextAlways($string); -} - -# Split into two functions so we can sanitize bbl but not rpi. -sub SanitizeTextAlways { - my $string = shift; - - # pass user hook subroutine if defined. - my @hook = (defined(&{"LaTeX_ToUnicode_convert_hook"})) - ? ("hook" => \&LaTeX_ToUnicode_convert_hook) - : (); - - # conversion of accented control sequences to characters, etc. - # Let's use &#uuuu; entities instead of literal UTF-8; Crossref - # recommends it, and it's easier for postprocessing. - $string = LaTeX::ToUnicode::convert($string, entities => 1, @hook); - - return $string; -} - + ################################################################ # Printing one author in arg ORIG_AUTHOR, in sequence SEQ. ################################################################ @@ -809,27 +869,45 @@ END END } + ############################################################# -# Printing citations +# Print citations in order from BIBLIOGRAPHY, a list reference, and +# CRBIB, a hash reference. Each element in BIBLIOGRAPHY is a +# one-element hash, with the key being the citation key and the value +# the (original) bbl text. We sanitize (de-texify) the text. +# Each element in CRBIB has key the citation key (from the same set) +# and value the structured citation string from any .crbib file. +# ############################################################# -sub PrintCitation { - my $paperhash=shift; - - foreach my $key (keys (%{$paperhash})) { - my $citation = $paperhash->{$key}; - $citation = SanitizeTextAlways($citation); - - print OUT <<END; - <citation key="$key"><unstructured_citation> - $citation - </unstructured_citation></citation> +sub PrintCitationList { + my ($bibliography,$crbib) = shift; + + print OUT " <citation_list>\n"; + foreach my $citation_hash (@$bibliography) { + foreach my $citekey (keys (%{$citation_hash})) { # only one key + my $citation_text = $citation_hash->{$citekey}; + $citation_text = SanitizeTextAlways($citation_text); + + #warn " printing citation $citekey: $citation_text\n"; + my $structured_citation = ""; + if ($crbib->{$citekey}) { + $structured_citation = "\n" . " "x10 . $crbib->{$citekey}; + warn " with structured citation: $structured_citation\n"; + } + print OUT <<END; + <citation key="$citekey">$structured_citation + <unstructured_citation>$citation_text</unstructured_citation> + </citation> END + } } + print OUT " </citation_list>\n"; } + ############################################################## # Return publication_type attribute for <journal_article>, given $PUBTYPE. -# https://data.crossref.org/reports/help/schema_doc/4.4.2/schema_4_4_2.html#publication_type.atts +# https://data.crossref.org/reports/help/schema_doc/5.3.1/crossref5_3_1_xsd.html#publication_type.atts_publication_type # # If not specified in input, return " publication_type=full_text" since # it was hardwired that way before. If set to "omit", return empty @@ -862,11 +940,11 @@ sub GetURL { my $result; if ($paper->{paperUrl}) { - $result = $paper->{paperUrl} + $result = $paper->{paperUrl} } elsif ($paper->{doi} =~ m,^10\.11612/resphil,) { - my $doi = $paper->{doi}; - $result = 'http://www.pdcnet.org/oom/service?url_ver=Z39.88-2004&rft_val_fmt=&rft.imuse_synonym=resphilosophica&rft.DOI='.$doi.'&svc_id=info:www.pdcnet.org/collection'; + my $doi = $paper->{doi}; + $result = 'http://www.pdcnet.org/oom/service?url_ver=Z39.88-2004&rft_val_fmt=&rft.imuse_synonym=resphilosophica&rft.DOI='.$doi.'&svc_id=info:www.pdcnet.org/collection'; } else { die ("$0: paperUrl field is required\n " @@ -877,7 +955,41 @@ sub GetURL { return $result; } + +############################################################### +# Simplistic TeX-to-html +# (no-op for rpi text if --input-is-xml was given). +############################################################### +sub SanitizeText { + my $string = shift; + return $string if $opts{xi}; # do nothing if --rpi-is-xml + return SanitizeTextEntities($string); +} + +# Conversion of accented control sequences to characters, etc. +# This uses &#uuuu; entities instead of literal UTF-8; Crossref +# recommends it, and it's easier for postprocessing. +# +sub SanitizeTextEntities { + my $string = shift; + return SanitizeTextNoEntities($string, entities => 1, @_); +} + +# Generic sanitize text. +sub SanitizeTextNoEntities { + my $string = shift; + + # pass user hook subroutine if defined. + my @hook = (defined(&{"LaTeX_ToUnicode_convert_hook"})) + ? ("hook" => \&LaTeX_ToUnicode_convert_hook) + : (); + + $string = LaTeX::ToUnicode::convert($string, @hook, @_); + + return $string; +} + ############################################################## # debug_hash_as_string($LABEL, HASH) # diff --git a/support/digestif/INSTALL.md b/support/digestif/INSTALL.md index f99f4b286a..ff4ac037e0 100644 --- a/support/digestif/INSTALL.md +++ b/support/digestif/INSTALL.md @@ -59,12 +59,12 @@ Packaging for a TeX distribution -------------------------------- For an installation depending only on the `texlua` interpreter from -LuaTeX (which already includes all other dependencies except cjson), +LuaTeX (which bundles all dependencies except the optional cjson), create a zip file containing `digestif/*.lua` and `data/*.tags` (no subdirectories), place it anywhere kpathsearch will find it and use the `bin/digestif.texlua` executable script. For instance: - zip -j digestif.zip digestif/*.lua tags/*.tags + zip -j digestif.zip digestif/*.lua data/*.tags install -Dt $TEXMF/scripts digestif.zip install bin/digestif.texlua $PREFIX/bin/digestif diff --git a/support/digestif/LICENSE.md b/support/digestif/LICENSE.md index 55165a272d..2b19eb74af 100644 --- a/support/digestif/LICENSE.md +++ b/support/digestif/LICENSE.md @@ -119,6 +119,20 @@ latex.tags: Adapted from the LaTeX2e Unofficial Reference Manual, which can be found at https://latexref.xyz/. +natbib.sty.tags: + + Copyright 1993-2010 Patrick W Daly + + This file may be distributed and/or modified under the conditions of the + LaTeX Project Public License, either version 1.3 of this license or (at + your option) any later version. The latest version of this license is in + http://www.latex-project.org/lppl.txt + and version 1.3 or later is part of all distributions of LaTeX version + 2005/12/01 or later. + + Adapted from the natbib package documentation, which can be found at + https://ctan.org/pkg/natbib + pgf.tags: Copyright 2007-2013 Till Tantau diff --git a/support/digestif/README.md b/support/digestif/README.md index a7528020ec..25b4fe4920 100644 --- a/support/digestif/README.md +++ b/support/digestif/README.md @@ -2,7 +2,7 @@ Digestif ======== <p align="center"> -<a href="https://app.travis-ci.com/astoff/digestif"><img src="https://app.travis-ci.com/astoff/digestif.svg?branch=main" alt="Build Status"></a> +<a href="https://github.com/astoff/digestif/actions/workflows/test.yml"><img src="https://github.com/astoff/digestif/actions/workflows/test.yml/badge.svg"></a> <a href="https://ctan.org/pkg/digestif"><img alt="CTAN" src="https://img.shields.io/ctan/v/digestif?color=blue"></a> <a href="https://luarocks.org/modules/astoff/digestif"><img alt="LuaRocks" src="https://img.shields.io/luarocks/v/astoff/digestif?color=blue"></a> </p> @@ -12,18 +12,20 @@ ConTeXt et caterva. It provides context-sensitive completion, documentation, code navigation, and related functionality to any text editor that speaks the LSP protocol. -<p align="center"><img src="https://raw.githubusercontent.com/astoff/digestif/images/screenshot.gif" alt="Madatory GIF"></p> - Features -------- - Completion for commands, environments, key-value options (for instance, TikZ options), cross-references and citations. + <p align="center"><img src="https://raw.githubusercontent.com/astoff/digestif/images/completion.png"></p> + - Popup help messages, including command signature and documentation. For the best results, make sure you have the [LaTeX reference manual][latexref] installed as an [info node][info-issues]. + <p align="center"><img src="https://raw.githubusercontent.com/astoff/digestif/images/help.png"></p> + - Find definition and references to labels and citations. - Document outline. @@ -37,12 +39,16 @@ Features - Digestif is fuzzy! For citations, it tries an exact match against the BibTeX identifier and a fuzzy match against author and title. - In the GIF above, the user types `groalhom`, which matches + In the picture below, the user typed `groalhom`, which matches **Gro**thendieck's “Sur quelques points d'**al**gébre **hom**ologique”; selecting this inserts the BibTeX identifier - `Tohoku`. Similarly, for cross-references, Digestif tries an exact - match against the label and a fuzzy match against the text around - the label. + `Tohoku`. + + <p align="center"><img src="https://raw.githubusercontent.com/astoff/digestif/images/cite.png"></p> + + Similarly, for cross-references, Digestif tries an exact match + against the label and a fuzzy match against the text around the + label. - Support for LaTeX, ConTeXt, plain TeX, DocTeX (`.dtx` files) and Texinfo. @@ -112,6 +118,10 @@ To ensure that Digestif is used, add the following to your init file: See instructions [here](https://github.com/neoclide/coc.nvim/wiki/Language-servers#latex). +### Sublime Text with the [LSP](https://packagecontrol.io/packages/LSP) package + +See instructions [here](https://lsp.sublimetext.io/language_servers/#digestif). + ### Other editors It shouldn't be hard to set up other editors to use Digestif. Please diff --git a/support/digestif/bin/digestif b/support/digestif/bin/digestif index 818d5b355a..73b51457b4 100755 --- a/support/digestif/bin/digestif +++ b/support/digestif/bin/digestif @@ -1,2 +1,5 @@ #!/usr/bin/env lua +-- Remove relative directories from package path +package.path = package.path:gsub("%f[^\0;]%.[^;]*", ""):gsub(";+", ";"):gsub("^;", ""):gsub(";$", "") +package.cpath = package.cpath:gsub("%f[^\0;]%.[^;]*", ""):gsub(";+", ";"):gsub("^;", ""):gsub(";$", "") require "digestif.langserver".main(arg) diff --git a/support/digestif/bin/digestif.texlua b/support/digestif/bin/digestif.texlua index 5f22a17e12..f0f6c9e84f 100755 --- a/support/digestif/bin/digestif.texlua +++ b/support/digestif/bin/digestif.texlua @@ -1,4 +1,7 @@ #!/usr/bin/env texlua +-- Remove relative directories from package path +package.path = package.path:gsub("%f[^\0;]%.[^;]*", ""):gsub(";+", ";"):gsub("^;", ""):gsub(";$", "") +package.cpath = package.cpath:gsub("%f[^\0;]%.[^;]*", ""):gsub(";+", ";"):gsub("^;", ""):gsub(";$", "") -- Use an invalid directory name in order not to allow kpse to search -- in the current directory. os.setenv("TEXMFDOTDIR", package.config:find("^\\") and "NUL" or "/dev/null") diff --git a/support/digestif/data/natbib.sty.tags b/support/digestif/data/natbib.sty.tags index fc62570636..5cf757d7c6 100644 --- a/support/digestif/data/natbib.sty.tags +++ b/support/digestif/data/natbib.sty.tags @@ -1,34 +1,616 @@ +-- Copyright 1993-2010 Patrick W Daly +-- SPDX-License-Identifier: LPPL-1.3c+ +-- +-- Adapted from the natbib package documentation, which can be found at +-- https://ctan.org/pkg/natbib ctan_package = "natbib" + +-- 5 Package Options +options = { + round = { + summary = "for round parentheses (default)" + }, + square = { + summary = "for square brackets" + }, + angle = { + summary = "for angle brackets" + }, + semicolon = { + summary = "separate multiple citations with semi-colons (default)" + }, + colon = { + summary = "same as `semicolon`" + }, + comma = { + summary = "use commas as separators" + }, + authoryear = { + summary = "for author-year citations (default)" + }, + numbers = { + summary = "for numerical citations" + }, + super = { + summary = "for superscripted numerical citations" + }, + sort = { + summary = "orders multiple citations into the sequence of the list of references" + }, + ["sort&compress"] = { + summary = "as `sort` but multiple numerical citations are compressed if possible" + }, + compress = { + summary = "compress without sorting" + }, + longnamesfirst = { + summary = "makes the first citation of any reference the equivalent of the starred variant" + }, + sectionbib = { + "redefines `\\thebibliography` to issue `\\section*` instead of `\\chapter*`" + }, + nonamebreak = { + summary = "keeps all the authors' names in a citation on one line" + }, + merge = { + summary = "allow the * prefix to the citation key and for merging" + }, + elide = { + summary = "elide common elements of merged references" + }, + mcite = { + summary = "elide common elements of merged references" + } +} + commands = { - Citealp = "$ref:natbib.sty#/commands/cite", - Citealt = "$ref:natbib.sty#/commands/cite", - Citeauthor = "$ref:natbib.sty#/commands/cite", - Citep = "$ref:natbib.sty#/commands/cite", - Citet = "$ref:natbib.sty#/commands/cite", + + -- 2.3 Basic Citation Commands cite = { action = "cite", arguments = { + {literal = "*", optional = true}, {delimiters = {"[", "]"}, meta = "prenote", optional = true}, {delimiters = {"[", "]"}, meta = "postnote", optional = true}, {list = true, meta = "keys"} }, - summary = "Refer to a bibliography item." - }, - citealp = "$ref:natbib.sty#/commands/cite", - citealt = "$ref:natbib.sty#/commands/cite", - citeauthor = "$ref:natbib.sty#/commands/cite", - citeauthoryear = "$ref:natbib.sty#/commands/cite", - citefullauthor = "$ref:natbib.sty#/commands/cite", - citename = "$ref:natbib.sty#/commands/cite", - citenum = "$ref:natbib.sty#/commands/cite", - citep = "$ref:natbib.sty#/commands/cite", - citepalias = "$ref:natbib.sty#/commands/cite", - citestarts = "$ref:natbib.sty#/commands/cite", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\cite[prenote][postnote]{key} +\cite*[prenote][postnote]{key} +``` + +`\cite` (without notes) is the same as `\citet` in author-year mode, +whereas in numerical mode, it is the same as `\citep`. The starred +version, as well as the one or two optional notes, may also be used. +This syntax has been retained for compatibility, but is no longer +encouraged. + +* `\cite{jon90}` => Jones et al., (1990) +* `\cite[]{jon90}` => (Jones et al., 1990) +* `\cite[chap.~2]{jon90}` => (Jones et al., 1990, chap. 2) +* `\cite*{jon90}` => Jones, Baker, and Williams, (1990) +* `\cite*[]{jon90}` => (Jones, Baker, and Williams, 1990)]] + }, + + citep = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item in parenthetical form.", + details = [[ +```latex +\citep[prenote][postnote]{key} +\citep*[prenote][postnote]{key} +``` + +Basic command for a parenthetical citation. The starred version prints +the full author list, and not just the abbreviated one. These macros +may take one or two optional arguments to add some text before and +after the citation. Multiple citations may be made by including more +than one citation key in the \cite command argument. + +* `\citep{jon90}` => (Jones et al., 1990) +* `\citep[chap.~2]{jon90}` => (Jones et al., 1990, chap. 2) +* `\citep[see][]{jon90}` => (see Jones et al., 1990) +* `\citep[see][chap.~2]{jon90}` => (see Jones et al., 1990, chap. 2) +* `\citep*{jon90}` => (Jones, Baker, and Williams, 1990) +* `\citep{jon90,jam91}` => (Jones et al., 1990; James et al. 1991) +* `\citep{jon90,jon91}` => (Jones et al., 1990, 1991) +* `\citep{jon90a,jon90b}` => (Jones et al., 1990a,b) + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text, as shown above.]] + }, + + citet = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item in textual form.", + details = [[ +```latex +\citet[prenote][postnote]{key} +\citet*[prenote][postnote]{key} +``` + +Basic command for a textual citation. The starred version prints the +full author list, and not just the abbreviated one. These macros may +take one or two optional arguments to add some text before and after +the citation. Multiple citations may be made by including more than +one citation key in the \cite command argument. + +* `\citet{jon90}` => Jones et al. (1990) +* `\citet[chap.~2]{jon90}` => Jones et al. (1990, chap. 2) +* `\citet[see][]{jon90}` => Jones et al. (see 1990) +* `\citet[see][chap.~2]{jon90}` => Jones et al. (see 1990, chap. 2) +* `\citet*{jon90}` => Jones, Baker, and Williams (1990) +* `\citet{jon90,jam91}` => Jones et al. (1990); James et al. (1991) + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text, as shown above.]] + }, + + -- 2.4 Extended Citation Commands + + citealp = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\citalp[prenote][postnote]{key} +\citalp*[prenote][postnote]{key} +``` + +Alternative from of `\citep` without parentheses. The starred version +prints the full author list, and not just the abbreviated one. These +macros may take one or two optional arguments to add some text before +and after the citation. Multiple citations may be made by including +more than one citation key in the \cite command argument. + +* `\citealp{jon90}` => Jones et al., 1990 +* `\citealp*{jon90}` => Jones, Baker, and Williams, 1990 +* `\citealp{jon90,jam91}` => Jones et al., 1990; James et al. 1991 +* `\citealp[pg.~32]{jon90}` => Jones et al., 1990, pg. 32 + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + citealt = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\citealt[prenote][postnote]{key} +\citealt*[prenote][postnote]{key} +``` + +Alternative from of `\citet` without parentheses. The starred version +prints the full author list, and not just the abbreviated one. These +macros may take one or two optional arguments to add some text before +and after the citation. Multiple citations may be made by including +more than one citation key in the \cite command argument. + +* `\citealt{jon90}` => Jones et al. 1990 +* `\citealt*{jon90}` => Jones et al. 1990 + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + citenum = { + action = "cite", + arguments = {{meta = "key"}}, + summary = "Print the citation number.", + details = [[ +```latex +\citenum{key} +``` + +This command prints the citation number, without parentheses, even in +author-year mode, and without raising it in superscript mode. This is +intended to be able to refer to citation numbers without +superscripting them. + +`\citenum{jon90}` => 11]] + }, + + citetext = { + arguments = {{meta = "text"}}, + summary = "Insert text in the current citation parentheses.", + details = [[ +```latex +\citetext{text} +``` + +This command allows arbitrary text to be placed in the current +citation parentheses. This may be used in combination with +`\citealp`. For example, + +* `\citetext{see \citealp{jon90}, or even better \citealp{jam91}}` +=> (see Jones et al., 1990, or even better James et al., 1991)]] + }, + + citeauthor = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\citeauthor[prenote][postnote]{key} +\citeauthor*[prenote][postnote]{key} +``` + +Refer to the authors without the year. Mostly useful in author-year +schemes. The starred version prints the full author list, and not +just the abbreviated one. These macros may take one or two optional +arguments to add some text before and after the citation. Multiple +citations may be made by including more than one citation key in the +\cite command argument. + +* `\citeauthor{jon90}` => Jones et al. +* `\citeauthor*{jon90}` => Jones, Baker, and Williams + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + citefullauthor = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/citeyear/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\citefullauthor[prenote][postnote]{key} +``` + +Refer to the full list of authors without the year. Mostly useful in +author-year schemes. This macro is equivalent to `\citeauthor*`: + +`\citefullauthor{jon90}` => Jones, Baker, and Williams + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + citeyear = { + action = "cite", + arguments = { + {delimiters = {"[", "]"}, meta = "prenote", optional = true}, + {delimiters = {"[", "]"}, meta = "postnote", optional = true}, + {list = true, meta = "key"} + }, + summary = "Refer to a bibliography item.", + details = [[ +```latex +\citeyear[prenote][postnote]{key} +``` + +Refer to the year of a citation. Mostly useful in author-year +schemes.: + +`\citeyear{jon90}` => 1990 + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + citeyearpar = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/citeyear/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\citeyearpar[prenote][postnote]{key} +``` + +Refer to the year of a citation printed in parentheses. Mostly useful +in author-year schemes.: + +`\citeyearpar{jon90}` => (1990) + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + -- 2.5 Forcing Upper Cased Name + + Citep = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item in parenthetical form.", + details = [[ +```latex +\Citep[prenote][postnote]{key} +\Citep*[prenote][postnote]{key} +``` + +Like `\citep` with the first letter uppercased. The starred version +prints the full author list, and not just the abbreviated one. These +macros may take one or two optional arguments to add some text before +and after the citation. Multiple citations may be made by including +more than one citation key in the \cite command argument. + +* `\citep{dRob98}` => (della Robbia, 1990) +* `\Citep{dRob98}` => (Della Robbia, 1990) + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + Citet = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item in textual form.", + details = [[ +```latex +\Citet[prenote][postnote]{key} +\Citet*[prenote][postnote]{key} +``` + +Like `\citet` with the first letter uppercased. The starred version +prints the full author list, and not just the abbreviated one. These +macros may take one or two optional arguments to add some text before +and after the citation. Multiple citations may be made by including +more than one citation key in the \cite command argument. + +* `\citet{dRob98}` => della Robbia (1998) +* `\Citet{dRob98}` => Della Robbia (1998) + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + Citealp = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\Citealp[prenote][postnote]{key} +\Citealp*[prenote][postnote]{key} +``` + +Like `\citealp` with the first letter uppercased. The starred version +prints the full author list, and not just the abbreviated one. These +macros may take one or two optional arguments to add some text before +and after the citation. Multiple citations may be made by including +more than one citation key in the \cite command argument. + +* `\citealp{dRob98}` => della Robbia, 1998 +* `\Citealp{dRob98}` => Della Robbia, 1998 + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + Citealt = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\Citealt[prenote][postnote]{key} +\Citealt*[prenote][postnote]{key} +``` + +Like `\citealt` with the first letter uppercased. The starred version +prints the full author list, and not just the abbreviated one. These +macros may take one or two optional arguments to add some text before +and after the citation. Multiple citations may be made by including +more than one citation key in the \cite command argument. + +* `\citealt{dRob98}` => della Robbia 1998 +* `\Citealt{dRob98}` => Della Robbia 1998 + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + Citeauthor = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography item.", + details = [[ +```latex +\Citeauthor[prenote][postnote]{key} +\Citeauthor*[prenote][postnote]{key} +``` + +Like `\citeauthor` with the first letter uppercased. Mostly useful in +author-year schemes. The starred version prints the full author list, +and not just the abbreviated one. These macros may take one or two +optional arguments to add some text before and after the citation. +Multiple citations may be made by including more than one citation key +in the \cite command argument. + +* `\citeauthor{dRob98}` => della Robbia +* `\Citeauthor{dRob98}` => Della Robbia + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + -- 2.6 Citation Aliasing + + defcitealias = { + action = "bibitem", + arguments = { + {meta = "key"}, + {meta = "replacement"} + }, + summary = "Create an alias to a bibliography item.", + details = [[ +```latex +\defcitealias{key}{replacement} +``` + +This command creates a special designation for a reference, i.e. Paper I. +Such aliases can be defined like this: + +`\defcitealias{jon90}{Paper~I}`]] + }, + + citetalias = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/citeyear/arguments", + summary = "Refer to a bibliography alias in textual form.", + details = [[ +```latex +\citetalias[prenote][postnote]{key} + +``` + +Like `\citet` but for aliases. This macro may take one or two +optional arguments to add some text before and after the citation. +Multiple citations may be made by including more than one citation key +in the \cite command argument. + +* `\defcitealias{jon90}{Paper~I}` +* `\citetalias{jon90}` => Paper I + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text.]] + }, + + citepalias = { + action = "cite", + arguments = "$ref:natbib.sty#/commands/cite/arguments", + summary = "Refer to a bibliography alias in parenthetical form.", + details = [[ +```latex +\citepalias[prenote][postnote]{key} +``` + +Like `\citep` but for aliases. This macro may take one or two +optional arguments to add some text before and after the citation. +Multiple citations may be made by including more than one citation key +in the \cite command argument. + +* `\defcitealias{jon90}{Paper~I}` +* `\citepalias{jon90}` => (Paper I) + +Note that a single optional text is a post-note, while two are the pre- +and post-notes. To have only a pre-note, it is necessary to provide +an empty post-note text, as shown above.]] + }, + + -- 2.9 Selecting Citation Punctuation + + setcitestyle = { + arguments = { + {meta = "citestyle", + keys = { + authoryear = { + summary = "citation mode, corresponds to fourth argument of `\\bibpunct`." + }, + numbers = { + summary = "citation mode, corresponds to fourth argument of `\\bibpunct`." + }, + super = { + summary = "citation mode, corresponds to fourth argument of `\\bibpunct`." + }, + round = { + summary = "braces, corresponds to first and second arguments of `\\bibpunct`" + }, + square = { + summary = "braces, corresponds to first and second arguments of `\\bibpunct`" + }, + open = { + summary = "braces, corresponds to first and second arguments of `\\bibpunct`" + }, + close = { + summary = "braces, corresponds to first and second arguments of `\\bibpunct`" + }, + semicolon = { + summary = "between citations, corresponds to third argument of `\\bibpunct`" + }, + comma = { + summary = "between citations, corresponds to third argument of `\\bibpunct`" + }, + citesep = { + summary = "between citations, corresponds to third argument of `\\bibpunct`" + }, + aysep = { + summary = "between years with common author, corresponds to fifth argument of `\\bibpunct`" + }, + yysep = { + summary = "between years with common author, corresponds to sixth argument of `\\bibpunct`" + }, + notesep = { + summary = "Text before post-note, corresponds to optional argument of `\\bibpunct`" + } + } + } + }, + summary = "Command for setting the citation style.", + details = [[ +```latex +\setcitestyle{key=val} +``` + +Command for setting the citation style with key=val pairs.]] + }, + + bibpunct = { + arguments = { + {meta = "before postnote", + optional = true, delimiters = {"[", "]"}}, + {meta = "opening bracket"}, + {meta = "closing bracket"}, + {meta = "between citations"}, + {meta = "style"}, + {meta = "between names&year"}, + {meta = "between years for suppressed author lists"} + }, + summary = "Older command for setting the citation style.", + details = [[ +```latex +\bibpunct[before-postnote]{open}{close]{between}{style}{author-year}{between-years} +``` + +Command for setting the citation style. This command is superseded by +`\setcitestyle`.]] + }, + + -- 2.10 Predefining a citation style citestyle = {arguments = {{meta = "style"}}}, - citet = "$ref:natbib.sty#/commands/cite", - citetalias = "$ref:natbib.sty#/commands/cite", - citetext = {arguments = {{meta = "text"}}}, - citeyear = "$ref:natbib.sty#/commands/cite", - citeyearpar = "$ref:natbib.sty#/commands/cite", - shortcites = "$ref:natbib.sty#/commands/cite" + + -- 2.18 Long Author List on First Citation + shortcites = { + action = "cite", + arguments = {{meta = "key", list = true,}}, + summary = "Print short list of authors on first citation.", + details = [[ +```latex +\shortcites{key} +``` + +When the package option `longnamesfirst` is given, the full author +list is printed with the first citation of any reference, and +afterwards only the abbreviated list. Some references have so many +authors that you want to suppress the automatic long list only for +them. In this case, issue + +`\shortcites{key}` + +before the first citations, and those included in key-list will have a +short list on their first citation.]] + } } diff --git a/support/digestif/data/tikz.tags b/support/digestif/data/tikz.tags index f14f8093f9..2c20853bca 100644 --- a/support/digestif/data/tikz.tags +++ b/support/digestif/data/tikz.tags @@ -2103,7 +2103,8 @@ Sections ?? to ??. documentation = "texmf:doc/generic/pgf/pgfmanual.pdf#pgf.back/usegdlibrary" }, usetikzlibrary = { - arguments = {{meta = "list of libraries"}}, + arguments = {{meta = "list of libraries", list=true}}, + action="input", filename="tikzlibrary?.code.tex", details = [[ Once TikZ has been loaded, you can use this command to load further libraries. The list of libraries should contain the names of libraries diff --git a/support/digestif/digestif/Cache.lua b/support/digestif/digestif/Cache.lua index d7e3e16f85..303e6d34b9 100644 --- a/support/digestif/digestif/Cache.lua +++ b/support/digestif/digestif/Cache.lua @@ -78,7 +78,7 @@ local search_magic_comment_patt = util.choice( -- Determine the root path of a document from magic comments. function Cache:rootname(filename) - local _, cookie = self(filename) -- warm up + local _, cookie = self(filename) -- luacheck: ignore cookie (warm up the cache) local props = assert(self.store[filename]) local rootname = props.rootname if rootname == nil then diff --git a/support/digestif/digestif/Manuscript.lua b/support/digestif/digestif/Manuscript.lua index d9101d8c07..e358a70b47 100644 --- a/support/digestif/digestif/Manuscript.lua +++ b/support/digestif/digestif/Manuscript.lua @@ -1,12 +1,14 @@ -- Manuscript class +local lfs = require "lfs" local config = require "digestif.config" local util = require "digestif.util" local require_data = require "digestif.data".require +local ctan_package_of = require "digestif.data".ctan_package_of local get_info = require "digestif.data".get_info local resolve_doc_items = require "digestif.data".resolve_doc_items -local path_join, path_split = util.path_join, util.path_split +local path_split = util.path_split local path_normalize = util.path_normalize local find_file = util.find_file local format_filename_template = util.format_filename_template @@ -244,23 +246,23 @@ end -- Compute the line and column number (both 1-based) at the given -- position. --- --- TODO: make len function a parameter -function Manuscript:line_column_at(pos) - -- Out ranges are excluside on the right, Lua is inclusive, so we +-- `length_fun` should be utf8.len or a similar function adapted to +-- other text encodings. +function Manuscript:line_column_at(pos, length_fun) + -- Our ranges are exclusive on the right, Lua is inclusive, so we -- may have pos == 1 + #self.src. pos = min(pos, #self.src) local l, line_pos = self:line_number_at(pos) - local c = utf8_len(self.src, line_pos, pos) or error("Invalid UTF-8") + local c = length_fun(self.src, line_pos, pos) or error("Invalid offset") return l, c end -- Compute the source position at the given line an column. --- --- TODO: make offset function a parameter -function Manuscript:position_at(line, col) +-- `offset_fun` should be utf8.offset or a similar function adapted to +-- other text encodings. +function Manuscript:position_at(line, col, offset_fun) local line_pos = self.lines[line] or error("Position out of bounds") - return utf8_offset(self.src, col, line_pos) or error("Position out of bounds") + return offset_fun(self.src, col, line_pos) or error("Position out of bounds") end @@ -679,7 +681,7 @@ end -- (of length twice that of args) indicating the positions of each -- argument within that string. -- -function Manuscript:signature_args(args, before) +function Manuscript:signature_args(args, before) -- luacheck: ignore self if not args then return before or "", {} end local t, p, pos = {before}, {}, 1 + (before and #before or 0) for i = 1, #args do @@ -727,7 +729,7 @@ Manuscript.signature_env = Manuscript.signature_cmd -- Returns: -- The formatted snippet, as a string, without the $0 placeholder. -- -function Manuscript:snippet_args(args, i) +function Manuscript:snippet_args(args, i) -- luacheck: ignore self if not args then return "" end i = i or 1 local t = {} @@ -809,6 +811,7 @@ end Manuscript.completion_handlers = {} +--** Command and environment name completion function Manuscript.completion_handlers.cs(self, ctx) local commands, environments = self.commands, self.environments local extra_snippets = config.extra_snippets @@ -845,6 +848,28 @@ function Manuscript.completion_handlers.cs(self, ctx) return ret end +function Manuscript.completion_handlers.begin(self, ctx, pos) + local environments = self.environments + local prefix = self:substring(ctx.pos, pos - 1) + local has_prefix = matcher(prefix) + local r = { + pos = ctx.pos, + prefix = prefix, + kind = "environment" + } + for env in pairs(map_keys(has_prefix, environments)) do + local cmd = environments[env] + r[#r+1] = { + text = env, + summary = cmd.summary, + } + end + return r +end + +Manuscript.completion_handlers["end"] = Manuscript.completion_handlers.begin + +--** Key/value completion function Manuscript.completion_handlers.key(self, ctx, pos) local prefix = self:substring(ctx.pos, pos - 1) local len = #prefix @@ -887,26 +912,7 @@ function Manuscript.completion_handlers.value(self, ctx, pos) return r end -function Manuscript.completion_handlers.begin(self, ctx, pos) - local environments = self.environments - local prefix = self:substring(ctx.pos, pos - 1) - local has_prefix = matcher(prefix) - local r = { - pos = ctx.pos, - prefix = prefix, - kind = "environment" - } - for env in pairs(map_keys(has_prefix, environments)) do - local cmd = environments[env] - r[#r+1] = { - text = env, - summary = cmd.summary, - } - end - return r -end - -Manuscript.completion_handlers["end"] = Manuscript.completion_handlers.begin +--** Cross-reference and citation completion -- Get a short piece of text around a label. If there is a recognized -- command ending right before the label, the context starts there. @@ -990,6 +996,58 @@ function Manuscript.completion_handlers.cite(self, ctx, pos) return r end +--** File name completion +function Manuscript.completion_handlers.input(self, ctx, pos) + local template + if ctx.arg then + template = nested_get(ctx, "parent", "data", "filename") or "?" + elseif ctx.item then + template = nested_get(ctx, "parent", "parent", "data", "filename") or "?" + else + return + end + local pre, post = template:match("([^?]*)%?(.*)") + local i_pre, i_post = #pre + 1, -1 - #post + local prefix = self:substring(ctx.pos, pos - 1) + local has_prefix = matcher(pre..prefix) + local has_suffix = matcher(post) + local match = function(s) + return has_suffix(s, -#post) and has_prefix(s) + end + local r = { + pos = ctx.pos, + prefix = prefix, + kind = "file" + } + -- Candidate from TeX directories. Don't try that if the command + -- expects the literal file name. + if template ~= "?" then + for name, _ in pairs(require "digestif.data".texmf_index) do + if match(name) then + local pkg = ctan_package_of(name) + r[#r+1] = { + text = name:sub(i_pre, i_post), + summary = pkg and pkg.summary + } + end + end + end + -- Candidates from current directory + local ok, iter, dir_obj = pcall(lfs.dir, ".") + if ok then + for name in iter, dir_obj do + if match(name) and lfs.attributes(name, "mode") == "file" then + r[#r+1] = { + text = name:sub(i_pre, i_post) + } + end + end + end + -- Sort candidates + table.sort(r, function(a, b) return a.text < b.text end) + return r +end + --* Context help -- Get information about the thing at the given position. @@ -1102,6 +1160,30 @@ function Manuscript.help_handlers.ref(self, ctx) } end +function Manuscript.help_handlers.input(self, ctx) + local name = self:substring(ctx) + local template + if ctx.arg then + template = nested_get(ctx, "parent", "data", "filename") or "?" + elseif ctx.item then + template = nested_get(ctx, "parent", "parent", "data", "filename") or "?" + else + return + end + local pre, post = template:match("([^?]*)%?(.*)") + local filename = pre .. name .. post + local data = ctan_package_of(filename) + if not data then return end + local docstring = self:make_docstring("file", filename, data) + return { + pos = ctx.pos, + cont = ctx.cont, + kind = "file", + summary = data.summary, + details = docstring, + } +end + function Manuscript.help_handlers.begin(self, ctx) local env_name = self:substring(ctx) local data = self.environments[env_name] @@ -1186,6 +1268,9 @@ function Manuscript:make_docstring_header(kind, name, data) ret = self:signature_env(name, data.arguments) elseif kind == "key" and data.meta then ret = ret .. " = " .. data.meta + elseif kind == "file" then + local pkg = ctan_package_of(name) + ret = pkg and pkg.ctan_package or name end if data.summary then ret = "`" .. ret .. "`: " .. data.summary @@ -1231,11 +1316,11 @@ local function make_docstring_details(data) local details = data.details local doc_field = data.documentation if details then - return "# Details\n\n" .. details + return "# Details\n\n" .. details .. (details:sub(-1) == "\n" and "" or "\n") elseif type(doc_field) == "string" and doc_field:match"^info:" then local str, node, subnode = get_info(doc_field) if str then - return format("# Info: (%s)%s\n\n```Info\n%s```", node, subnode, str) + return format("# Info: (%s)%s\n\n```Info\n%s```\n", node, subnode, str) end else return @@ -1243,8 +1328,8 @@ local function make_docstring_details(data) end function Manuscript:make_docstring_docs(kind, name, data) - local item_doc = data.documentation - local pkg = data.package + local item_doc = kind ~= "file" and data.documentation + local pkg = kind == "file" and data or data.package local pkg_doc = pkg and pkg.documentation local t = {"# Documentation\n"} if pkg and pkg.ctan_package then @@ -1253,10 +1338,17 @@ function Manuscript:make_docstring_docs(kind, name, data) elseif kind == "cs" then name = self:signature_cmd(name) end - t[#t+1] = format( - "`%s` is defined in the [%s](https://www.ctan.org/pkg/%s) package.\n", - name, pkg.ctan_package, pkg.ctan_package - ) + if kind == "file" then + t[#t+1] = format( + "`%s` is part of the [%s](https://www.ctan.org/pkg/%s) package.\n", + name, pkg.ctan_package, pkg.ctan_package + ) + else + t[#t+1] = format( + "`%s` is defined in the [%s](https://www.ctan.org/pkg/%s) package.\n", + name, pkg.ctan_package, pkg.ctan_package + ) + end end if item_doc then extend(t, resolve_doc_items(item_doc)) diff --git a/support/digestif/digestif/ManuscriptBibTeX.lua b/support/digestif/digestif/ManuscriptBibTeX.lua index 219f4552b4..659c3d5ec9 100644 --- a/support/digestif/digestif/ManuscriptBibTeX.lua +++ b/support/digestif/digestif/ManuscriptBibTeX.lua @@ -1,13 +1,8 @@ -local lpeg = require "lpeg" local util = require "digestif.util" local Manuscript = require "digestif.Manuscript" local Parser = require "digestif.Parser" local bibtex = require "digestif.bibtex" -local path_join, path_split = util.path_join, util.path_split -local nested_get, nested_put = util.nested_get, util.nested_put -local map, update, merge = util.map, util.update, util.merge - local ManuscriptBibtex = util.class(Manuscript) ManuscriptBibtex.parser = Parser() diff --git a/support/digestif/digestif/ManuscriptConTeXt.lua b/support/digestif/digestif/ManuscriptConTeXt.lua index 2243d3a9fc..4ee33b5df4 100644 --- a/support/digestif/digestif/ManuscriptConTeXt.lua +++ b/support/digestif/digestif/ManuscriptConTeXt.lua @@ -28,7 +28,7 @@ local function collect(s) local top = {} table.insert(stack, top) local ni,c,label,xarg, empty - local i, j = 1, 1 + local i, j = 1, 1 -- luacheck: ignore j while true do ni,j,c,label,xarg, empty = string.find(s, "<(%/?)([%w:]+)(.-)(%/?)>", i) if not ni then break end @@ -290,7 +290,7 @@ end local function tags_from_xml(file, pkg) local ok, str = util.find_file(file, nil, true) if not ok then return end - local ok, data = pcall(collect, str) + local ok, data = pcall(collect, str) -- luacheck: ignore ok if not ok then return end return setmetatable(gen_tags(data), {__index = pkg}) end diff --git a/support/digestif/digestif/ManuscriptLaTeX.lua b/support/digestif/digestif/ManuscriptLaTeX.lua index 1366b0e146..22df3e9980 100644 --- a/support/digestif/digestif/ManuscriptLaTeX.lua +++ b/support/digestif/digestif/ManuscriptLaTeX.lua @@ -5,8 +5,7 @@ local Parser = require "digestif.Parser" local path_join, path_split = util.path_join, util.path_split local path_normalize = util.path_normalize -local nested_get, nested_put = util.nested_get, util.nested_put -local map, update, merge = util.map, util.update, util.merge +local merge = util.merge local format_filename_template = util.format_filename_template local ManuscriptLatex = util.class(Manuscript) @@ -49,7 +48,7 @@ local function first_mand(args) end end -local function first_opt(args) +local function first_opt(args) -- luacheck: ignore first_opt for i, v in ipairs(args) do if v.optional then return i end end diff --git a/support/digestif/digestif/Schema.lua b/support/digestif/digestif/Schema.lua index b59a95157d..0ce26199a5 100644 --- a/support/digestif/digestif/Schema.lua +++ b/support/digestif/digestif/Schema.lua @@ -151,7 +151,7 @@ function Schema:assert_fail(obj) assert(not self:validate(obj)) end -local schema_of_schema = Schema { +local schema_of_schema = Schema { -- luacheck: ignore schema_of_schema fields = { description = { type = "string", diff --git a/support/digestif/digestif/bibtex.lua b/support/digestif/digestif/bibtex.lua index f1430474e3..277db0d364 100644 --- a/support/digestif/digestif/bibtex.lua +++ b/support/digestif/digestif/bibtex.lua @@ -1,10 +1,8 @@ local lpeg = require "lpeg" local util = require "digestif.util" -local B, P, R, S, V - = lpeg.B, lpeg.P, lpeg.R, lpeg.S, lpeg.V -local C, Cc, Cp, Ct, Cmt, Cg - = lpeg.C, lpeg.Cc, lpeg.Cp, lpeg.Ct, lpeg.Cmt, lpeg.Cg +local B, P, R, S = lpeg.B, lpeg.P, lpeg.R, lpeg.S +local C, Cp, Ct, Cg = lpeg.C, lpeg.Cp, lpeg.Ct, lpeg.Cg local concat = table.concat local merge = util.merge local search, gobble_until, case_fold = util.search, util.gobble_until, util.case_fold @@ -34,7 +32,6 @@ local rparen = P")" * whitespace local equals = P"=" * whitespace local hash = P"#" * whitespace local comma = P"," * whitespace -local quote = P'"' * whitespace local lit_string = C(case_fold "string") * whitespace local lit_comment = C(case_fold "comment") * whitespace local lit_preamble = C(case_fold "preamble") * whitespace @@ -54,7 +51,6 @@ local fields = field * (comma * field)^0 local token = curly_braced_string/0 + char local nonspace = token - space local author_sep = space * "and" * space -local etal_marker = P("et al") * whitespace * P(-1) -- either curly or round braced local function braced(patt) @@ -114,9 +110,7 @@ function bibtex.parse(src, options) } for _, t in ipairs(entries) do local entry_type = t[1]:lower() - if entry_type == "comment" then - -- pass - elseif entry_type == "preamble" then + if entry_type == "preamble" then preambles[#preambles + 1] = t[2] elseif entry_type == "string" then for _, u in ipairs_from(t, 2) do @@ -124,9 +118,9 @@ function bibtex.parse(src, options) local val = process_value(u, strings) strings[key] = val end - else + elseif entry_type ~= "comment" then local id = t[2] - local fields = {} + local fields = {} -- luacheck: ignore fields for _, u in ipairs_from(t, 3) do local key = u[1]:lower() local val = process_value(u, strings) @@ -203,7 +197,6 @@ local detexify_symbols = replace(tex_cs_patt, tex_symbols, tex_char_or_math) local detexify_accents = replace(tex_accent_patt, repl_accents_fun, tex_char_or_math) local debracify = replace(curly_braced_string, 1, tex_char_or_math) local detitlify = replace(B(space) * C(tex_letter), string.lower, tex_char_or_math) -local trim = util.trim(space) local clean = util.clean(space) local function deuglify_name (s) @@ -231,11 +224,11 @@ local split_last = search(Cp() * C(nonspace^1) * whitespace * P(-1)) function BibItem:authors() local t = {} - local author = self.fields.author - if not author then return {} end - for _, name in ipairs(split_authors(author)) do + local authors = self.fields.author + if not authors then return {} end + for _, author in ipairs(split_authors(authors)) do local u = {} - local parts = split_name(name) + local parts = split_name(author) if #parts == 3 then u.first = parts[3] u.last = parts[1] @@ -244,12 +237,12 @@ function BibItem:authors() u.first = parts[2] u.last = parts[1] else - local p, l = split_last:match(name) + local p, l = split_last:match(author) if p then - u.first = name:sub(1, p - 1) + u.first = author:sub(1, p - 1) u.last = l else - u.last = name + u.last = author end end t[#t + 1] = u @@ -259,8 +252,8 @@ end function BibItem:pretty_print() local t, a = {}, {} - for _, name in ipairs(self:authors()) do - a[#a + 1] = deuglify_name(name.last) + for _, author in ipairs(self:authors()) do + a[#a + 1] = deuglify_name(author.last) end t[#t + 1] = concat(a, ", ") t[#t + 1] = (self.fields.year or self.fields.date or "(n.d.)") .. ";" diff --git a/support/digestif/digestif/config.lua b/support/digestif/digestif/config.lua index 43b7971094..edad15b317 100644 --- a/support/digestif/digestif/config.lua +++ b/support/digestif/digestif/config.lua @@ -3,7 +3,7 @@ local format = string.format local config = {} -config.version = "0.5.1" +config.version = "0.6" local pre_version = os.getenv("DIGESTIF_PRERELEASE") if pre_version then config.version = config.version .. "-" .. pre_version @@ -142,8 +142,8 @@ end function config.check_data(dir) if not dir then - for _, dir in ipairs(config.data_dirs) do - if config.check_data(dir) then return true end + for _, data_dir in ipairs(config.data_dirs) do + if config.check_data(data_dir) then return true end end end local f = io.open(util.path_join(dir, "primitives.tags")) diff --git a/support/digestif/digestif/data.lua b/support/digestif/digestif/data.lua index 621048f4a9..c9a094536b 100644 --- a/support/digestif/digestif/data.lua +++ b/support/digestif/digestif/data.lua @@ -1,3 +1,4 @@ +local lfs = require "lfs" local lpeg = require "lpeg" local util = require "digestif.util" local config = require "digestif.config" @@ -9,11 +10,11 @@ local P, C, Cg, Ct = lpeg.P, lpeg.C, lpeg.Cg, lpeg.Ct local match = lpeg.match local many, sequence = util.many, util.sequence local gobble, search = util.gobble, util.search -local nested_get, extend = util.nested_get, util.extend +local nested_get = util.nested_get local find_file = util.find_file local parse_uri, make_uri = util.parse_uri, util.make_uri local log = util.log -local path_split, path_join = util.path_split, util.path_join +local path_join, path_split = util.path_join, util.path_split local data = {} local loaded_tags = {} @@ -123,51 +124,63 @@ else if config.verbose then log("TLPDB not found") end end - ---* kpathsea emulation - --- function kpsewhich(name) --- --- Like the kpsewhich command, return the full path of tex input file --- name. We use luatex's kpse bindings if available, and parse the --- system's ls-R files otherwise. --- -local kpsewhich - -if kpse then -- we're on luatex - - local kpse_obj = kpse.new("luatex") - - function kpsewhich(name) - return kpse_obj:find_file(name, "tex") - end - -else -- on plain lua, we look for ls-R files - - local texmf_files = {} - local texmf_dirs = config.texmf_dirs - local dir_patt = P"./" * C(gobble(":" * P(-1))) - for i = 1, #texmf_dirs do - local texmf_dir = texmf_dirs[i] - local listing_path = find_file(texmf_dir, "ls-R") - if listing_path then +data.ctan_package_of = ctan_package_of + +--* Indexing of TeX input files + +-- Table mapping TeX input file names to the directory where it is +-- located. +local texmf_index = {} +do + local dir_patt = C(P"."^-2 * P"/" * gobble(":" * P(-1))) + for _, texmf_dir in ipairs(config.texmf_dirs) do + local clock = config.verbose and os.clock() + local ls_file = io.open(path_join(texmf_dir, "ls-R")) + if ls_file then local current_dir - for line in io.lines(listing_path) do - local subdir = match(dir_patt, line) - if subdir then - current_dir = path_join(texmf_dir, subdir) - elseif current_dir and not texmf_files[line] then - texmf_files[line] = path_join(current_dir, line) + for name in ls_file:lines() do + if name ~= "" then + local subdir = match(dir_patt, name) + if subdir then + current_dir = path_join(texmf_dir, subdir) + elseif current_dir and not texmf_index[name] then + texmf_index[name] = current_dir + end end end + ls_file:close() + else + local function recur(current_dir, max_depth) + local ok, iter, dir_obj = pcall(lfs.dir, current_dir) + if not ok then return end + for name in iter, dir_obj do + if name ~= "." and name ~= ".." then + local path = path_join(current_dir, name) + local mode = lfs.attributes(path, "mode") + if mode == "directory" then + if max_depth > 0 then + recur(path, max_depth - 1) + end + elseif mode == "file" then + if not texmf_index[name] then + texmf_index[name] = current_dir + end + end + end + end + end + recur(texmf_dir, 10) + end + if clock then + log( + "Scanned %s%s in %0.3f ms", + texmf_dir, ls_file and "/ls-R" or "", + 1000*(os.clock() - clock) + ) end end - - function kpsewhich(name) - return texmf_files[name] - end - end +data.texmf_index = texmf_index --* Generate tags from the user's TeX installation @@ -213,12 +226,13 @@ local function tags_from_manuscript(script, ctan_data) end -- Generate tags from TeX source code (or ConTeXt interface XML file, --- if applicable). The argument is a file name found by kpsewhich. +-- if applicable). The argument is TeX input file name. -- local function generate_tags(name) - local path = kpsewhich(name) - path = path and find_file(config.texmf_dirs, path) - if not path then return end + local dir = texmf_index[name] + local path = dir and path_join(dir, name) + local f = path and io.open(path) + if f then f:close() else return end local texformat = infer_format(path) if not texformat then return end if config.verbose then log("Generating tags: %s", path) end @@ -251,7 +265,7 @@ local parse_ref = util.matcher( P"$ref:", C(gobble"#") * P"#", Ct(many(P"/" * C(gobble"/"))))) -p=parse_ref + local function resolve_refs(tbl, seen) seen = seen or {} for k, v in pairs(tbl) do @@ -310,8 +324,6 @@ data.require_tags = require_tags -- for debugging and testing only, and depends on luafilesystem. local function load_all_tags() local t = {} - local ok, lfs = pcall(require, "lfs") - assert(ok, "Function data.load_all() need the luafilesystem library.") for _, data_dir in ipairs(config.data_dirs) do for path in lfs.dir(data_dir) do local pkg = path:match("(.*)%.tags") @@ -352,7 +364,16 @@ local function resolve_doc_items(items) local t = {} for _, item in ipairs(items) do if type(item) == "string" then - t[#t+1] = format("- <%s>", resolve_uri(item)) + local uri = resolve_uri(item) + local scheme, _, location, _, fragment = parse_uri(uri) + if scheme == "info" then + t[#t+1] = format("- Info node [%s(%s)](%s)", location, fragment, uri) + elseif scheme == "file" then + local _, filename = path_split(location) + t[#t+1] = format("- [%s](%s)", filename, uri) + else + t[#t+1] = format("- <%s>", uri) + end else t[#t+1] = format("- [%s](%s)", item.summary, resolve_uri(item.uri)) end diff --git a/support/digestif/digestif/langserver.lua b/support/digestif/digestif/langserver.lua index bbda819f11..ac460d758d 100644 --- a/support/digestif/digestif/langserver.lua +++ b/support/digestif/digestif/langserver.lua @@ -21,6 +21,7 @@ else end --* Convert LSP API objects to/from internal representations +local length_fun, offset_fun = utf8.len, utf8.offset -- This will be a digestif.Cache object. Its initialization is -- deferred to `initialized` method. @@ -61,7 +62,7 @@ local function from_Position(str, position, p0, l0) if l0 and l0 > l then p0, l0 = nil, nil end for n, i in lines(str, p0, l0) do if n == l then - return utf8.offset(str, c, i), i, l + return offset_fun(str, c, i), i, l end end end @@ -85,13 +86,13 @@ local function from_TextDocumentPositionParams(arg) local texformat = open_documents[filename] local script = cache:manuscript(filename, texformat) local l, c = arg.position.line + 1, arg.position.character + 1 - return script, script:position_at(l, c) + return script, script:position_at(l, c, offset_fun) end local function to_Range(item) local script = item.manuscript - local l1, c1 = script:line_column_at(item.pos) - local l2, c2 = script:line_column_at(item.cont) + local l1, c1 = script:line_column_at(item.pos, length_fun) + local l2, c2 = script:line_column_at(item.cont, length_fun) return { start = {line = l1 - 1, character = c1 - 1}, ["end"] = {line = l2 - 1, character = c2 - 1}, @@ -110,8 +111,8 @@ local function to_MarkupContent(str) end local function to_TextEdit(script, pos, old, new) - local l, c_start = script:line_column_at(pos) - local c_end = c_start + utf8.len(old) + local l, c_start = script:line_column_at(pos, length_fun) + local c_end = c_start + length_fun(old) return { range = { start = {line = l - 1, character = c_start - 1}, @@ -185,8 +186,37 @@ methods["initialize"] = function(params) if params.initializationOptions then config.load_from_table(params.initializationOptions) end + local enc, encodings = nil, nested_get(params.capabilities, "general", "positionEncodings") + for _, e in ipairs(encodings or {}) do + if e == "utf-32" then + enc = e + break + elseif e == "utf-8" then + enc = e + length_fun = function(s, i, j) + if i then + j = j or #s + if i < 1 or j < i then error("Invalid offset") end + return j - i + 1 + else + return #s + end + end + offset_fun = function(s, n, i) + i = i or n < 0 and #s + 1 or 1 + local v = n + (i or 1) - 1 + if v < 1 or v > #s + 1 then error("Invalid offset") end + return v + end + break + end + end + if not enc and config.verbose then + log("Digestif and you editor couldn't agree on a fully supported position encoding") + end return { capabilities = { + positionEncoding = enc, textDocumentSync = { openClose = true, change = 2 diff --git a/support/digestif/digestif/util.lua b/support/digestif/digestif/util.lua index 2e042ebd70..c33756cdf0 100644 --- a/support/digestif/digestif/util.lua +++ b/support/digestif/digestif/util.lua @@ -301,7 +301,7 @@ local line_patt = I * (search(I * eol) * I + P(true)) local function lines(s, i, n) return co_wrap(function() - local n, i, j, k = n or 1, match(line_patt, s, i) + local n, i, j, k = n or 1, match(line_patt, s, i) -- luacheck: ignore n i while k do co_yield(n, i, j - 1) n, i, j, k = n + 1, match(line_patt, s, k) @@ -641,10 +641,10 @@ do t[n] = encode_number(obj) return n + 1 elseif obj_type == "table" then - local v = obj[1] - if v ~= nil then + local v1 = obj[1] + if v1 ~= nil then t[n] = "[" - n = do_encode(v, t, n + 1) + n = do_encode(v1, t, n + 1) for i = 2, #obj do t[n] = "," n = do_encode(obj[i], t, n + 1) @@ -658,7 +658,7 @@ do t[n + 1] = encode_string(k) t[n + 2] = "\":" n = do_encode(v, t, n + 3) - for k, v in next, obj, k do + for k, v in next, obj, k do -- luacheck: ignore k v t[n] = ",\"" t[n + 1] = encode_string(k) t[n + 2] = "\":" diff --git a/support/latexdiff/README b/support/latexdiff/README index 6f4d1a280a..f0310ce32d 100644 --- a/support/latexdiff/README +++ b/support/latexdiff/README @@ -1,4 +1,13 @@ +latexdiff +========= + +Compares two latex files and marks up significant differences between them. Releases on https://ctan.org/pkg/latexdiff and mirrors. + +Link to full manual: http://mirrors.ctan.org/support/latexdiff/doc/latexdiff-man.pdf + + INTRODUCTION +------------ latexdiff is a Perl script, which compares two latex files and marks up significant differences between them (i.e. a diff for latex files). @@ -16,11 +25,9 @@ behaviour and accept or reject selected changes only. The author is F Tilmann. -Project webpage: https://github.com/ftilmann/latexdiff/ -CTAN page: http://www.ctan.org/pkg/latexdiff - REQUIREMENTS +------------ Perl 5.8 or higher must be installed. The latexdiff script makes use of the Perl package Algorithm::Diff (available @@ -38,6 +45,7 @@ UNIX-diff mean that the resulting set of differences will generally not be the s for the standard latexdiff. In most practical cases, these differences are minor, though. INSTALLATION UNIX/LINUX +----------------------- The basic installation procedure is almost trivial: @@ -53,34 +61,40 @@ The basic installation procedure is almost trivial: The attached trivial Makefile contains example commands to carry out above steps as root for a typical UNIX installation. Type - make install (for the stand alone version) + `make install` (for the stand alone version) + or - make install-ext (for the version using the external Algorithm::Diff) + + `make install-ext` (for the version using the external Algorithm::Diff) + or - make install-fast (for the version using the UNIX 'diff' function for fast differencing) + + `make install-fast` (for the version using the UNIX 'diff' function for fast differencing) to get it rolling. You can type - make test -or - make test-ext -or - make test-fast + `make test` or + + `make test-ext` or + + `make test-fast` to test the respective versions on a brief example before installation. It will often be as easy to carry out these steps manually instead of using the Makefile. -DOCUMENTATION: +DOCUMENTATION +------------- Usage instructions are in the manual latexdiff-man.pdf as well as the man pages. -CHANGELOGS: - +CHANGELOGS +---------- Check out the comment lines at the beginning of the perl scripts (latexdiff, latexdiff-vc, latexrevise) CONTRIBUTIONS +------------- The directory contrib contains code written by others relating to latexdiff. Currently this directory contains: @@ -97,15 +111,19 @@ Contributions by the following authors were incorporated into the latexdiff code extend latexdiff in a similar way: J. Paisley, N. Becker, K. Huebner EXTERNAL LATEXDIFF SUPPORT PROGRAMS +----------------------------------- + +LATEXDIDFFR (Author: David Hugh-Jones) is a small library that uses the latexdiff command to create a diff of two Rmarkdown, .Rnw or TeX files. +https://github.com/hughjonesd/latexdiffr LATEXDIFFCITE (Author: Christer van der Meeren) is a wrapper around latexdiff to make citations diff properly. It works by expanding \cite type commands using the bbl or bib file, such that citations are treated just like normal text rather than as atomic in the plain latexdiff. -https://latexdiffcite.readthedocs.org +https://github.com/twilsonco/latexdiffcite GIT-LATEXDIFF (lead author: Matthieu Moy) is a wrapper (bash script) around latexdiff that allows using it to diff two revisions of a LaTeX file under git revision control (similar functionality is provided by latexdiff-vc --git with --flatten option included with this distribution but git-latexdiff allows more fine-grained control on (not to be confused with latexdiff-git, which is normally installed as a soft link to latexdiff-vc) https://gitorious.org/git-latexdiff/ -LICENSE (also see file COPYING) - +LICENSE +------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 as published by the Free Software Foundation. @@ -116,3 +134,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details (file LICENSE in the distribution). + + + diff --git a/support/latexdiff/doc/example-diff.tex b/support/latexdiff/doc/example-diff.tex index 8eda2a43aa..b68c11aff9 100644 --- a/support/latexdiff/doc/example-diff.tex +++ b/support/latexdiff/doc/example-diff.tex @@ -22,7 +22,7 @@ \RequirePackage[normalem]{ulem} %DIF PREAMBLE \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} %DIF PREAMBLE \providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}} %DIF PREAMBLE -\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} %DIF PREAMBLE +\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} %DIF PREAMBLE %DIF SAFE PREAMBLE %DIF PREAMBLE \providecommand{\DIFaddbegin}{} %DIF PREAMBLE \providecommand{\DIFaddend}{} %DIF PREAMBLE @@ -53,6 +53,8 @@ } %DIF PREAMBLE \lstnewenvironment{DIFverbatim}{\lstset{style=DIFverbatimstyle}}{} %DIF PREAMBLE \lstnewenvironment{DIFverbatim*}{\lstset{style=DIFverbatimstyle,showspaces=true}}{} %DIF PREAMBLE +\lstset{extendedchars=\true,inputencoding=utf8} + %DIF END PREAMBLE EXTENSION ADDED BY LATEXDIFF \begin{document} diff --git a/support/latexdiff/doc/latexdiff-man.pdf b/support/latexdiff/doc/latexdiff-man.pdf Binary files differindex 2ea00571b3..d0e57ad5c9 100644 --- a/support/latexdiff/doc/latexdiff-man.pdf +++ b/support/latexdiff/doc/latexdiff-man.pdf diff --git a/support/latexdiff/latexdiff b/support/latexdiff/latexdiff index a032ae23b5..5df02b753f 100755 --- a/support/latexdiff/latexdiff +++ b/support/latexdiff/latexdiff @@ -25,6 +25,21 @@ # # Note references to issue numbers are for the github repository of latexdiff: https://github.com/ftilmann/latexdiff # +# Version 1.3.4: +# New features: +# - Option to use lua-ul instead of ulem (for use with LuaLaTeX) (fix #17, #60, #188, #255, #270) +# Enhancement +# - If amsmath is detected as one of the included (based on idea in PR #263 contributed by github user xlucn +# Bug fix +# - sometimes the introduction of aux commands to show deleted lists or descriptions leaves in place empty auxiliary +# list environments, which would cause error messages (though skipping messages would result in a correct output pdf). +# These are now removed. +# - add more mboxsafecmd and safecmd commands for SIunitx to stay compatible with newer versionsof SIunitx (PR #283, fixing issue #282, contributed by github user joe6302413) +# - File added via --preamble option is no longer assumed to be ASCII, but read either with encoding as defined by --encoding option or using the encoding of the LOCALE (fixes issue #285 ) +# - multicolumn argument is now treated as text +# - when tikz-dependency package is used, \& is no longer a safe command as it has special meaning inside dependency environment. The fix is a little of a hack as really it should only be considered unsafe within dependency environment (fixes (mostly) issue #303 ) +# - listings package had trouble with non-ASCII chars. The encoding is now set (thanks to github user anka-213 for finding this). Fixes #304 +# # Version 1.3.3: # New features: # - Option --no-del to remove all deleted text (merge contributed by github user tdegeus PR #252, fixing issue #66 @@ -33,22 +48,22 @@ # - Abbreviations involving punctuations within them. They need special treatment because otherwise in some # circumstances the gnoring of white space differences in conjunction with merging according to MINWORDSBLOCK rule # could turn 'i.e.' into 'i.\PAR e.' (see https://github.com/ftilmann/latexdiff/issues/269). A few abbreviations -# are now hard-coded and treated as atomic: +# are now hard-coded and treated as atomic: # English: i.e., e.g. Deutsch: z.B. # (fixes issue #269) # - In WHOLE and COARSE math modes, now properly treat math environments with arguments such as \alignat. Fixes #251 -# - For FINE math mode, multiple improvments to the processing work flow yield more robust outcomes. In particular, changes -# to the equation type, e.g. \begin{displaymath} -> \begin{equation} without modifications now usually no longer result -# in errors. (Partially) fixes issues #235 and #244. -# - When encountering deleted math array environments such as align or eqnarray, rather than replacing them with a -# fixed replacement environment (e.g. align* or eqnarray*), an asterisk is now added to the original command, which +# - For FINE math mode, multiple improvments to the processing work flow yield more robust outcomes. In particular, changes +# to the equation type, e.g. \begin{displaymath} -> \begin{equation} without modifications now usually no longer result +# in errors. (Partially) fixes issues #235 and #244. +# - When encountering deleted math array environments such as align or eqnarray, rather than replacing them with a +# fixed replacement environment (e.g. align* or eqnarray*), an asterisk is now added to the original command, which # in amsmath (and with eqnarray) will result in the same environment but without line numbers. Config variable MATHARRREPL # is therefore (nearly) redundant, and a depracation warning is given when it is set. Reference to MATHARRREPL are have # been removed from the manual (there is one exception, when it's still being used: sometimes latexdiff can figure out # that there is a deleted array environment, but does not know which one. In this case, MATHARRREPL is still being used -# to encapsulate these parts of the source, and therefore it is still set internally. But this is a quite rare situation). +# to encapsulate these parts of the source, and therefore it is still set internally. But this is a quite rare situation). # Fixes issue #216 -# - Unlike 'array' environment, 'split' (amsmath) does not work in argument of \DIFadd or \DIFdl in UNDERLINE modes; therefore remove it from ARRENV configuration variable. +# - Unlike 'array' environment, 'split' (amsmath) does not work in argument of \DIFadd or \DIFdl in UNDERLINE modes; therefore remove it from ARRENV configuration variable. # Exclude \begin and \end in math environments in COARSE and WHOLE modes. Fixes #258. Fixes #109 # - --flatten now works for empty files. Fixes issue #242 # - improved processing of Chinese and Japanese texts in that splitting is done based on characters. Thanks to LuXu (Oliver Lew) in git for working this out. Fixes #229, fixes #145 @@ -65,7 +80,7 @@ # Bug fixes: # - fix issue #206 affecting proper markup of text commands which are not also safe cmd's and have multiple arguments # - fix issue #210 by adding \eqref (amsmath package) to the list of safe commands -# - fix bug reported in issue #168 mangled verbatim line environment +# - fix bug reported in issue #168 mangled verbatim line environment # - fix bug reported in issue #218 by replacing \hspace{0pt} after \mbox{..} auxiliary commands with \hskip0pt. # - more ways to process \frac correctly with atomic arguments (committed by julianuu PR #246 # - fix a bug in biblatex mode, which prevented proper processing of modified \textcite (see: https://tex.stackexchange.com/questions/555157/latexdiff-and-biblatex-citation-commands) @@ -74,10 +89,10 @@ # Version 1.3.1.1 # - remove spurious \n to fix error: Unknown regexp modifier "/n" at .../latexdiff line 1974, near "=~ " (see github issue #201) # -# Version 1.3.1 +# Version 1.3.1 # Bug fixes: # - remove some uninitialised variable $2 warnings in string substitution in flatten function in case included file is not found -# - add minimal postprocessing to diff processing of preamble commands (replace \RIGHTBRACE by \} ) +# - add minimal postprocessing to diff processing of preamble commands (replace \RIGHTBRACE by \} ) # - pre-processing: replace (contributed) routine take_comments_and_enter_from_frac() with take_comments_and_newline_from_frac(), which does the same thing # (remove whitespace characters and comments between the argument of \frac commands) in an easier and more robust way. In addition, it # will replace commands like \frac12 with \frac{1}{2} as pre-processing step. Fixes issue #184 @@ -95,15 +110,15 @@ # Version 1.3.0 (7 October 2018): # - treat options to \documentclass as potential package names (some packages allow implicit loading of or imply selected packages # - improved pattern matching: now allows nested angular brackets, and is no longer confused by escaped curly braces -# - improved pattern matching in COARSE mode: occasionally, the closing bracket or some other elements would be matched in an 'unnatural' way due to another sequence being more minimal in the computational sense, sometimes even causing errors due to tokens moving in or out of the scope of math environments. This is now discouraged by adding internal \DIFANCHOR commands (which are removed again in post-processing) (fixes issues reported via email by li_ruomeng . +# - improved pattern matching in COARSE mode: occasionally, the closing bracket or some other elements would be matched in an 'unnatural' way due to another sequence being more minimal in the computational sense, sometimes even causing errors due to tokens moving in or out of the scope of math environments. This is now discouraged by adding internal \DIFANCHOR commands (which are removed again in post-processing) (fixes issues reported via email by li_ruomeng . # - verbatim and lstlisting environments are marked-up with line-by-line in a similar style to non-verbatim text (requires the listing package to be installed) # (see new configuration variable VERBATIMLINEENV) (several issues and pull requests by jprotze) -# - --flatten: now supports \verbatiminput and \lstlistinput +# - --flatten: now supports \verbatiminput and \lstlistinput # - --flatten: if file is not found, do not fail, simply warn and leave command unexpanded (inspired by issue #112). Don't warn if file name contains #[0-9] as it is then most likely an argument within a command definition rather than an actual file (applies to \input, \subfile, \include commands) # - added to textcmds: \intertext # - new config variable CUSTOMDIFCMD to allow defining special versions of commands in added or deleted blocks (Pull request by github user jprotze) # - added option -no-links (mostly for use by latexdiff-vc in only-changes modes) (Pull request by github user jprotze) -# - new option --filter-script to run both input through a pre-processing script (PR jasonmccsmith #167) +# - new option --filter-script to run both input through a pre-processing script (PR jasonmccsmith #167) # new option --no-filter-stderr to hide stderr output from filter-script (potentially dangerous, as this might hide malfunctioning of filter scripts) # - --flatten now can deal with imports made using the import package {PR jasonmccsmith #173) # Bug fixes: @@ -122,12 +137,12 @@ # make environments that are treated like verbatim environments configurable (config variable VERBATIMENV) # treat lstinlne as equivalent to verb command # partially addresses issue #38 -# - refactoring: set default configuration variables in a hash, and those that correspond to lists +# - refactoring: set default configuration variables in a hash, and those that correspond to lists # - feature: option --add-to-config used to amend configuration variables, which are regex pattern lists # - bug fix: deleted figures when endfloat package is activated # - bug fix: alignat environment now always processed correctly (fix issues #65) # - bug fix: avoid processing of commands as potential files in routine init_regex_arr (fix issue #70 ) -# - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be +# - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be # @ a letter if it is part of a command name will usually lead to the correct behaviour (see http://tex.stackexchange.com/questions/346651/latexdiff-and-let) # - new feature/bug fix: --flatten option \endinput in included files now respected but only if \endinput stands right at the beginning of the line (issue #77) # - bug fix: flatten would incorrectly attempt to process commented out \include commands (from discussion in issue #77 ) @@ -165,7 +180,7 @@ # - introduce list UNSAFEMATHCMD, which holds list of commands which cannot be marked up with \DIFadd or \DIFdel commands (only relevant for WHOLE and COARSE math markup modes) # - new subtype LABEL which gives each change a label. This can later be used to only display pages where changes # have been made (instructions for that are put as comments into the diff'ed file) inspired by answer on http://tex.stackexchange.com/questions/166049/invisible-markers-in-pdfs-using-pdflatex -# - Configuration variables take into accout some commands from additional packages: +# - Configuration variables take into accout some commands from additional packages: # tikzpicture environment now treated as PICTUREENV, and \smallmatrix in ARRENV (amsmath) # - --flatten: support for \subfile command (subfiles package) (in response to http://tex.stackexchange.com/questions/167620/latexdiff-with-subfiles ) # - --flatten: \bibliography commands expand if corresponding bbl file present @@ -179,11 +194,11 @@ # - \% in one-letter sub/Superscripts was not converted correctly # # Version 1.0.3 -# - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator +# - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator # command in preamble # - \(..\) inline math expressions were not parsed correctly, if they contained a linebreak # - applied patch contributed by tomflannaghan via Berlios: [ Patch #3431 ] Adds correct handling of \left< and \right> -# - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug +# - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug # and sketching out the solution) # - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript # (thanks to Wail Yahyaoui for pointing out this bug) @@ -191,19 +206,19 @@ # Version 1.0.1 - treat \big,\bigg etc. equivalently to \left and # \right - include starred version in MATHENV - apply # - flatten recursively and --flatten expansion is now -# aware of comments (thanks to Tim Connors for patch) +# aware of comments (thanks to Tim Connors for patch) # - Change to post-processing for more reliability for # deleted math environments -# - On linux systems, recognise and remove DOS style newlines +# - On linux systems, recognise and remove DOS style newlines # - Provide markup for some special preamble commands (\title, -# \author,\date, -# - configurable by setting context2cmd +# \author,\date, +# - configurable by setting context2cmd # - for styles using ulem package, remove \emph and \text.. from list of # safe commands in order to allow linebreaks within the -# highlighted sections. -# - for ulem style, now show citations by enclosing them in \mbox commands. -# This unfortunately implies linebreaks within citations no longer function, -# so this functionality can be turned off (Option --disable-citation-markup). +# highlighted sections. +# - for ulem style, now show citations by enclosing them in \mbox commands. +# This unfortunately implies linebreaks within citations no longer function, +# so this functionality can be turned off (Option --disable-citation-markup). # With --enable-citation-markup, the mbox markup is forced for other styles) # - new substyle COLOR. This is particularly useful for marking up citations # and some special post-processing is implemented to retain cite @@ -211,11 +226,11 @@ # - four different levels of math-markup # - Option --driver for choosing driver for modes employing changebar package # - accept \\* as valid command (and other commands of form \.*). Also accept -# \<nl> (backslashed newline) +# \<nl> (backslashed newline) # - some typo fixes, include commands defined in preamble as safe commands -# (Sebastian Gouezel) +# (Sebastian Gouezel) # - include compared filenames as comments as line 2 and 3 of -# the preamble (can be modified with option --label, and suppressed with +# the preamble (can be modified with option --label, and suppressed with # --no-label), option --visible-label to show files in generated pdf or dvi # at the beginning of main document # @@ -231,7 +246,7 @@ # # Version 0.4 March 06 option for fast differencing using UNIX diff command, several minor bug fixes (\par bug, improved highlighting of textcmds) # -# Version 0.3 August 05 improved parsing of displayed math, --allow-spaces +# Version 0.3 August 05 improved parsing of displayed math, --allow-spaces # option, several minor bug fixes # # Version 0.25 October 04 Fix bug with deleted equations, add math mode commands to safecmd, add | to allowed interpunctuation signs @@ -247,12 +262,13 @@ use utf8 ; use File::Spec ; + my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION); my ($versionstring)=<<EOF ; -This is LATEXDIFF 1.3.3 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) - (c) 2004-2022 F J Tilmann +This is LATEXDIFF 1.3.4 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) + (c) 2004-2024 F J Tilmann EOF # Hash with defaults for configuration variables. These marked undef have default values constructed from list defined in the DATA block @@ -343,9 +359,9 @@ my $DELCMDOPEN='%DIFDELCMD < '; # To mark begin of deleted commands (must begin my $DELCMDCLOSE="%%%\n"; # To mark end of deleted commands (must end with a new line) my $AUXCMD='%DIFAUXCMD' ; # follows auxiliary commands put in by latexdiff to make difference file legal # auxiliary commands must be on a line of their own - # Note that for verbatim environment openings the %DIFAUXCMD cannot be placed in + # Note that for verbatim environment openings the %DIFAUXCMD cannot be placed in # the same line as this would mean they are shown - # so the special form "%DIFAUXCMD NEXT" is used to indicate that the next line + # so the special form "%DIFAUXCMD NEXT" is used to indicate that the next line # is an auxiliary command # Similarly "%DIFAUXCMD LAST" would indicate the auxiliary command is in previous line (not currently used) my $DELCOMMENT='DIF < '; # To mark deleted comment line @@ -356,21 +372,21 @@ my @TEXTCMDLIST=(); # array containing patterns of commands with text arguments my @TEXTCMDEXCL=(); # array containing patterns of commands without text arguments (if a pattern # matches both TEXTCMDLIST and TEXTCMDEXCL it is excluded) my @CONTEXT1CMDLIST=(); # array containing patterns of commands with text arguments (subset of text commands), - # but which cause confusion if used out of context (e.g. \caption). + # but which cause confusion if used out of context (e.g. \caption). # In deleted passages, the command will be disabled but its argument is marked up - # Otherwise they behave exactly like TEXTCMD's + # Otherwise they behave exactly like TEXTCMD's my @CONTEXT1CMDEXCL=(); # exclude list for above, but always empty my @CONTEXT2CMDLIST=(); # array containing patterns of commands with text arguments, but which fail or cause confusion # if used out of context (e.g. \title). They and their arguments will be disabled in deleted # passages my @CONTEXT2CMDEXCL=(); # exclude list for above, but always empty my @MATHTEXTCMDLIST=(); # treat like textcmd. If a textcmd is in deleted or added block, just wrap the - # whole content with \DIFadd or \DIFdel irrespective of content. This functionality + # whole content with \DIFadd or \DIFdel irrespective of content. This functionality # is useful for pseudo commands \MATHBLOCK.. into which math environments are being - # transformed -my @MATHTEXTCMDEXCL=(); # + # transformed +my @MATHTEXTCMDEXCL=(); # -# Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these +# Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these our @SAFECMDLIST=(); # array containing patterns of safe commands (which do not break when in the argument of DIFadd or DIFDEL) our @SAFECMDEXCL=(); my @MBOXCMDLIST=(); # patterns for commands which are in principle safe but which need to be surrounded by an \mbox @@ -435,7 +451,7 @@ $mathmarkup=COARSE; $verbose=0; $onlyadditions=0; # output debug and intermediate files, set to 0 in final distribution -$debug=0; +$debug=0; # insert preamble directly after documentclass - experimental feature, set to 0 in final distribution # Note that this failed with mini example (or other files, where packages used in latexdiff preamble # are called again with incompatible options in preamble of resulting file) @@ -458,9 +474,9 @@ END my %verbhash; Getopt::Long::Configure('bundling'); -GetOptions('type|t=s' => \$type, - 'subtype|s=s' => \$subtype, - 'floattype|f=s' => \$floattype, +GetOptions('type|t=s' => \$type, + 'subtype|s=s' => \$subtype, + 'floattype|f=s' => \$floattype, 'config|c=s' => \@configlist, 'add-to-config=s' => \@addtoconfiglist, 'preamble|p=s' => \$preamblefile, @@ -509,11 +525,11 @@ if ( $help ) { if ( $version ) { - print STDERR $versionstring ; + print STDERR $versionstring ; exit 0; } -print STDERR $versionstring if $verbose; +print STDERR $versionstring if $verbose; if (defined($showall)){ $showpreamble=$showsafe=$showtext=$showconfig=1; @@ -531,7 +547,7 @@ if (defined($mathmarkup)) { $mathmarkup=~tr/a-z/A-Z/; if ( $mathmarkup eq 'OFF' ){ $mathmarkup=OFF; - } elsif ( $mathmarkup eq 'WHOLE' ){ + } elsif ( $mathmarkup eq 'WHOLE' ){ $mathmarkup=WHOLE; } elsif ( $mathmarkup eq 'COARSE' ){ $mathmarkup=COARSE; @@ -634,7 +650,7 @@ foreach $config ( @configlist ) { } } foreach $assign ( @config ) { - $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; + $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}=$2; } @@ -671,7 +687,7 @@ foreach $key ( keys(%CONFIG) ) { foreach $assign ( @addtoconfig ) { ###print STDERR "assign:|$assign|\n"; - $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; + $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}.=";$2"; } @@ -686,8 +702,8 @@ foreach ( keys(%CONFIG) ) { elsif ( $_ eq "MATHENV" ) { $MATHENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "MATHREPL" ) { $MATHREPL = $CONFIG{$_} ; } elsif ( $_ eq "MATHARRENV" ) { $MATHARRENV = liststringtoregex($CONFIG{$_}) ; } - elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; - print STDERR "WARNING: Setting MATHARRREPL is depracated. Generally deleted math array environments will be set to their starred varieties and the setting of MATHARREPL is ignored.\n\n" unless $MATHARRREPL =~ /eqnarray\*/ ; + elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; + print STDERR "WARNING: Setting MATHARRREPL is depracated. Generally deleted math array environments will be set to their starred varieties and the setting of MATHARREPL is ignored.\n\n" unless $MATHARRREPL =~ /eqnarray\*/ ; } elsif ( $_ eq "ARRENV" ) { $ARRENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "VERBATIMENV" ) { $VERBATIMENV = liststringtoregex($CONFIG{$_}) ; } @@ -714,11 +730,11 @@ foreach $pkg ( @packagelist ) { if ($showconfig || $showtext || $showsafe || $showpreamble) { show_configuration(); - exit 0; + exit 0; } -if ( @ARGV != 2 ) { +if ( @ARGV != 2 ) { print STDERR "2 and only 2 non-option arguments required. Write latexdiff -h to get help\n"; exit(2); } @@ -726,7 +742,7 @@ if ( @ARGV != 2 ) { # Are extra spaces between command arguments permissible? my $extraspace; if ($allowspaces) { - $extraspace='\s*'; + $extraspace='\s*'; } else { $extraspace=''; } @@ -749,14 +765,14 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # if you get "undefined control sequence MATHBLOCKmath" error, increase the maximum value in this loop for (my $i_pat = 0; $i_pat < 20; ++$i_pat){ $pat_n = '(?:[^{}]|\{'.$pat_n.'\}|\\\\\{|\\\\\})*'; - # Actually within the text body, quoted braces are replaced in pre-processing. The only place where + # Actually within the text body, quoted braces are replaced in pre-processing. The only place where # the last part of the pattern matters is when processing the arguments of context2cmds in the preamble # and these contain a \{ or \} combination, probably rare. # It should thus be fine to use the simpler version below. ### $pat_n = '(?:[^{}]|\{'.$pat_n.'\})*'; } - my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; + my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; my $brat_n = $brat0; for (my $i_pat = 0; $i_pat < 4; ++$i_pat){ $brat_n = '(?:[^\[\]]|\['.$brat_n.'\]|\\\[|\\\])*'; @@ -773,7 +789,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # could turn 'i.e.' into 'i.\PAR e.' (see https://github.com/ftilmann/latexdiff/issues/269) # English: i.e., e.g. Deutsch: z.B. my $abbreviation='(?:i\. ?e\.|e\. ?g\.|z\. ?B\.)' ; - my $number='-?\d*\.\d*'; + my $number='-?\d*\.\d*'; # word: sequence of letters or accents followed by letter my $word_cj='\p{Han}|\p{InHiragana}|\p{InKatakana}'; @@ -801,7 +817,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # inline math $....$ or \(..\) ### the commented out version is simpler but for some reason cannot cope with newline (in spite of s option) - need to include \newline explicitly ### my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(].*?\\\\[)]'; - my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; + my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; ### test version (this seems to give the same results as version above) ## the current maths command cannot cope with newline within the math expression ### my $math='\$(?:[^$]|\\\$)*?\$|\\[(].*?\\[)]'; @@ -819,7 +835,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); -# now we are done setting up and can start working +# now we are done setting up and can start working my ($oldfile, $newfile) = @ARGV; # check for existence of input files if ( ! -e $oldfile ) { @@ -847,7 +863,7 @@ my ($oldtime,$newtime,$oldlabel,$newlabel); if (defined($labels[0])) { $oldlabel=$labels[0] ; } else { - $oldtime=localtime((stat($oldfile))[9]); + $oldtime=localtime((stat($oldfile))[9]); $oldlabel="$oldfile " . " "x($oldlabel_n_spaces) . $oldtime; } if (defined($labels[1])) { @@ -860,6 +876,7 @@ if (defined($labels[1])) { $encoding=guess_encoding($newfile) unless defined($encoding); $encoding = "utf8" if $encoding =~ m/^utf8/i ; +print STDERR "Encoding $encoding\n" if $verbose; if (lc($encoding) eq "utf8" ) { binmode(STDOUT, ":utf8"); binmode(STDERR, ":utf8"); @@ -943,7 +960,7 @@ my @auxlines; my ($ulem)=0; if ( length $oldpreamble && length $newpreamble ) { - # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) + # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) # and marking up content with latexdiff markup @auxlines=preprocess_preamble($oldpreamble,$newpreamble); @@ -975,7 +992,7 @@ if (defined($graphicsmarkup)) { } else { # Default: no explicit setting in menu if ( defined $packages{"graphicx"} or defined $packages{"graphics"} ) { - $graphicsmarkup=NEWONLY; + $graphicsmarkup=NEWONLY; } else { $graphicsmarkup=NONE; } @@ -1008,7 +1025,7 @@ if ($graphicsmarkup != NONE ) { @matches=( $latexdiffpreamble =~ m/command\{\\DIFaddbeginFL}\{($pat_n)}/sg ) ; # we look at the last one of the list to take into account possible redefinition but almost always matches should have exactly one element if ( $matches[$#matches] =~ m/\\DIFaddbegin/ ) { - die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style."; + die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style."; exit 10; } ###} @@ -1022,6 +1039,11 @@ if ($graphicsmarkup != NONE ) { $ulem = ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{ulem\}/ || defined $packages{"ulem"}); +# If amsmath is defined and $ulem is used for markup, redefine the \sout command to also work (mostly) in math mode +# See stack exchange https://tex.stackexchange.com/questions/20609/strikeout-in-math-mode/308647#308647 based on comment by Taylor Raine +if ( defined($packages{'amsmath'}) and $ulem ) { + $latexdiffpreamble .= join "\n",(extrapream('AMSMATHULEM'),""); +} # If listings is being used or can be found in the latexdiff search path, add to the preamble auxiliary code to enable line-by-line markup if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { @@ -1031,7 +1053,7 @@ if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { } my @listingDIFcode=(); my $replaced; - # note that in case user supplies preamblefile the type might not reflect well the + # note that in case user supplies preamblefile the type might not reflect well the actual markup style @listingDIFcode=extrapream("-nofail","DIFCODE_" . $type) unless defined($preamblefile); if (!(@listingDIFcode)) { # if listingDIFcode is empty try to guess a suitable one from the preamble @@ -1045,13 +1067,17 @@ if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { @listingDIFcode=extrapream("DIFCODE_BOLD"); } } - # now splice it in + # add configuration so that listings work with utf-8 + push @listingpreamble, '\lstset{extendedchars=\true,inputencoding='.$encoding."}\n"; + + + # now splice it in $replaced=0; ###print STDERR "DEBUG: listingDIFcode: ",join("\n",@listingDIFcode),"|||\n" if $debug; - @listingpreamble=grep { + @listingpreamble=grep { # only replace if this has not been done already (use short-circuit property of and) - if (!$replaced and $_ =~ s/^.*%DIFCODE TEMPLATE.*$/join("\n",@listingDIFcode)/e ) { + if (!$replaced and $_ =~ s/^.*%DIFCODE TEMPLATE.*$/join("\n",@listingDIFcode)/e ) { ###print STDERR "DEBUG: Replaced text $_\n" if $debug; $replaced=1; 1; @@ -1081,7 +1107,7 @@ if ( length $oldpreamble && length $newpreamble ) { unshift @oldpreamble,''; @diffpreamble = linediff(\@oldpreamble, \@newpreamble); # remove dummy line again - shift @diffpreamble; + shift @diffpreamble; # add filenames, modification time and latexdiff mark defined($nolabel) or splice @diffpreamble,1,0, "%DIF LATEXDIFF DIFFERENCE FILE", @@ -1130,8 +1156,8 @@ if (defined $packages{"siunitx"} ) { # protect SI command by surrounding them with an \mbox # this is done to get around an incompatibility between the ulem and siunitx package print STDERR "siunitx package detected.\n" if $verbose ; - my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange'; - init_regex_arr_list(\@SAFECMDLIST,'num,si'); + my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange,qty,qtylist,qtyproduct,qtyrange,complexqty'; + init_regex_arr_list(\@SAFECMDLIST,'num,si,numproduct,unit,complexnum'); if ( $enablecitmark || ( $ulem && ! $disablecitmark )) { init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds); } else { @@ -1153,7 +1179,7 @@ if (defined $packages{"cleveref"} ) { if (defined $packages{"glossaries"} ) { # protect selected command by surrounding them with an \mbox - # this is done to get around an incompatibility between ulem and glossaries package + # this is done to get around an incompatibility between ulem and glossaries package print STDERR "glossaries package detected.\n" if $verbose ; my $mboxcmds='[gG][lL][sS](?:|pl|disp|link|first|firstplural|desc|user[iv][iv]?[iv]?),[aA][cC][rR](?:long|longpl|full|fullpl),[aA][cC][lfp]?[lfp]?'; init_regex_arr_list(\@SAFECMDLIST,'[gG][lL][sS](?:(?:entry)?(?:text|plural|name|symbol)|displaynumberlist|entryfirst|entryfirstplural|entrydesc|entrydescplural|entrysymbolplural|entryuser[iv][iv]?[iv]?|entrynumberlist|entrydisplaynumberlist|entrylong|entrylongpl|entryshort|entryshortpl|entryfull|entryfullpl),[gG]lossentry(?:name|desc|symbol),[aA][cC][rR](?:short|shortpl),[aA]csp?'); @@ -1182,6 +1208,10 @@ if (defined $packages{"mhchem"} ) { # push(@MATHTEXTCMDLIST,'cee'); } +if ( defined $packages{"tikz-dependency"} ) { + init_regex_arr_ext(\@SAFECMDEXCL, 'AMPERSAND'); +} + my ( $citpat); @@ -1269,7 +1299,7 @@ print STDERR "(",exetime()," s)\n","Done.\n" if $verbose; # liststringtoregex(liststring) -# expands string with semi-colon separated list into a regular expression corresponding +# expands string with semi-colon separated list into a regular expression corresponding # matching any of the elements sub liststringtoregex { my ($liststring)=@_; @@ -1282,7 +1312,7 @@ sub liststringtoregex { } # show_configuration -# note that this is not encapsulated but uses variables from the main program +# note that this is not encapsulated but uses variables from the main program # It is provided for convenience because in the future it is planned to allow output # to be modified based on what packages are read etc - this works only if the input files are actually read # whether or not additional files are provided @@ -1309,7 +1339,7 @@ sub show_configuration { print "\nContext1 commands (last argument textual, command will be disabled in deleted passages, last argument will be shown as plain text):\n"; print_regex_arr(@CONTEXT1CMDLIST); print "\nContext2 commands (last argument textual, command and its argument will be disabled in deleted passages):\n"; - print_regex_arr(@CONTEXT2CMDLIST); + print_regex_arr(@CONTEXT2CMDLIST); print "\nExclude list of Commands with last argument not textual (overrides patterns above):\n"; print_regex_arr(@TEXTCMDEXCL); } @@ -1417,7 +1447,7 @@ sub list_packages { my %packages=(); my $pkg; - # remove comments + # remove comments $preamble=~s/(?<!\\)%.*$//mg ; while ( $preamble =~ m/\\(?:documentclass|usepackage|RequirePackage)(?:\[($brat_n)\])?\{(.*?)\}/gs ) { @@ -1522,7 +1552,7 @@ sub flatten { my ($includeonly,$dirname,$fname,$newpage,$fullfile,$filecontent,$replacement,$begline,$inputcmd,$bblfile,$subfile,$command,$verbenv,$verboptions,$ignore,$fileonly); my ($subpreamble,$subbody,$subpost); my ($subdir,$subdirfull,$importfilepath); - require File::Basename ; + require File::Basename ; ### require File::Spec ; # now this is needed even if flatten option not given $filename = File::Spec->rel2abs( $filename ) ; ($ignore, $dirname, $fileonly) = File::Spec->splitpath($filename) ; @@ -1562,15 +1592,15 @@ sub flatten { $subdirfull = (defined($3) ? File::Spec->catdir($dirname,$subdir) : $subdir); $importfilepath = File::Spec->catfile($subdirfull, $fname); - + print STDERR "importing importfilepath:", $importfilepath,"\n" if $verbose; if ( -f $importfilepath ) { # If file exists, replace input or include command with expanded input #TODO: need remove_endinput & newpage similar to other replacements inside flatten - $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding); + $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding); } else { # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition - # and is not meant to be expanded directly + # and is not meant to be expanded directly print STDERR "WARNING: Could not find included file ",$importfilepath,". I will continue but not expand |$2|\n"; $replacement = $2; $replacement .= "{$subdir}{$fname} % Processed"; @@ -1579,13 +1609,13 @@ sub flatten { }/exgm; # recursively replace \\input and \\include files - $text =~ s/(^(?:[^%\n]|\\%)*)(\\input\{(.*?)\}|\\include\{(${includeonly}(?:\.tex)?)\})/{ + $text =~ s/(^(?:[^%\n]|\\%)*)(\\input\{(.*?)\}|\\include\{(${includeonly}(?:\.tex)?)\})/{ $begline=(defined($1)? $1 : "") ; $inputcmd=$2; $fname = $3 if defined($3) ; $fname = $4 if defined($4) ; $newpage=(defined($4)? " \\newpage " : "") ; - # # add tex extension unless there is a three or four letter extension already + # # add tex extension unless there is a three or four letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3,4}$|; $fullfile = File::Spec->catfile($dirname,$fname); print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ; @@ -1594,12 +1624,12 @@ sub flatten { # content of file becomes replacement value (use recursion), add \newpage if the command was include if ( -f $fullfile ) { # If file exists, replace input or include command with expanded input - $replacement=flatten(read_file_with_encoding($fullfile, $encoding), $preamble,$filename,$encoding); - $replacement = remove_endinput($replacement); + $replacement=flatten(read_file_with_encoding($fullfile, $encoding), $preamble,$filename,$encoding); + $replacement = remove_endinput($replacement); # \include always starts a new page; use explicit \newpage command to simulate this } else { # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition - # and is not meant to be expanded directly + # and is not meant to be expanded directly print STDERR "WARNING: Could not find included file ",$fullfile,". I will continue but not expand |$inputcmd|\n" unless $fname =~ m(#[0-9]) ; $replacement = $inputcmd ; # i.e. just the original command again -> make no change file does not exist $newpage=""; @@ -1608,7 +1638,7 @@ sub flatten { }/exgm; # replace bibliography with bbl file if it exists - $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{ if ( -f $bblfile ){ $replacement=read_file_with_encoding(File::Spec->catfile($bblfile), $encoding); } else { @@ -1620,10 +1650,10 @@ sub flatten { }/exgm; # replace subfile with contents (subfile package) - $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{ $begline=(defined($1)? $1 : "") ; - $fname = $2; - # # add tex extension unless there is a three or four letter extension already + $fname = $2; + # # add tex extension unless there is a three or four letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3,4}|; print STDERR "Include file as subfile $fname\n" if $verbose; # content of file becomes replacement value (use recursion) @@ -1634,10 +1664,10 @@ sub flatten { # if file exists, expand \subfile command by contents of file $subfile=read_file_with_encoding($fullfile,$encoding) or die "Could not open included subfile ",$fullfile,": $!"; ($subpreamble,$subbody,$subpost)=splitdoc($subfile,'\\\\begin\{document\}','\\\\end\{document\}'); - ### $subfile=~s|^.*\\begin{document}||s; + ### $subfile=~s|^.*\\begin{document}||s; ### $subfile=~s|\\end{document}.*$||s; $replacement=flatten($subbody, $preamble,$fullfile,$encoding); - ### $replacement = remove_endinput($replacement); + ### $replacement = remove_endinput($replacement); } else { # if file does not exist, do not expand subfile print STDERR "WARNING: Could not find subfile ",$fullfile,". I will continue but not expand |$2|\n" unless $fname =~ m(#[0-9]) ; @@ -1648,11 +1678,11 @@ sub flatten { }/exgm; # replace \verbatiminput and \lstlistinginput - $text=~s/(^(?:[^%\n]|\\%)*)\\(verbatiminput\*?|lstinputlisting)$extraspace(\[$brat_n\])?$extraspace\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\(verbatiminput\*?|lstinputlisting)$extraspace(\[$brat_n\])?$extraspace\{(.*?)\}/{ $begline=(defined($1)? $1 : "") ; $command = $2 ; $fname = $4 ; - $verboptions = defined($3)? $3 : "" ; + $verboptions = defined($3)? $3 : "" ; if ($command eq 'verbatiminput' ) { $verbenv = "verbatim" ; } elsif ($command eq 'verbatiminput*' ) { @@ -1661,7 +1691,7 @@ sub flatten { $verbenv = "lstlisting" ; } else { die "Internal errorL Unexpected verbatim input type $command.\n"; - } + } print STDERR "DEBUG Beg of line match |$begline|\n" if $debug ; print STDERR "Include file $fname verbatim\n" if $verbose; print STDERR "DEBUG looking for file ",File::Spec->catfile($dirname,$fname), "\n" if $debug; @@ -1693,8 +1723,8 @@ sub print_regex_arr { # if $type is a filename, it will read the file instead of reading from the appendix # otherwise it will screen appendix for line "%DIF $TYPE" and copy everything up to line # '%DIF END $TYPE' (where $TYPE is upcased version of $type) -# extrapream('-nofail',$type) will---instead of failing---simply return nothing if -# it does not find the matching line in a appendix (do not use -nofail option with multiple types!) +# extrapream('-nofail',$type) will---instead of failing---simply return nothing if +# it does not find the matching line in appendix (do not use -nofail option with multiple types!) sub extrapream { my @types=@_; my ($type,$arg); @@ -1711,14 +1741,20 @@ sub extrapream { $type=$arg; $copy=0; if ( -f $type || lc $type eq '/dev/null' ) { - open (FILE,$type) or die "Cannot open preamble file $type: $!"; print STDERR "Reading preamble file $type\n" if $verbose ; + open (FILE,$type) or die "Cannot open preamble file $type: $!"; + if (defined($encoding)) { + binmode(FILE,":encoding($encoding)"); + } else { + require Encode::Locale; + binmode(FILE,":encoding(locale)"); + } while (<FILE>) { chomp ; if ( $_ =~ m/%DIF PREAMBLE/ ) { - push (@retval,"$_"); + push (@retval,"$_"); } else { - push (@retval,"$_ %DIF PREAMBLE"); + push (@retval,"$_ %DIF PREAMBLE"); } } } else { # not (-f $type) @@ -1730,9 +1766,9 @@ sub extrapream { my $data_start = tell DATA; while (<DATA>) { if ( m/^%DIF $type/ ) { - $copy=1; + $copy=1; } elsif ( m/^%DIF END $type/ ) { - last; + last; } chomp; push (@retval,"$_ %DIF PREAMBLE") if $copy; @@ -1772,7 +1808,7 @@ sub splitdoc { $pos=pos $rest; $part2=substr($rest,0,$pos-length($2)); $part3=substr($rest,$pos); - } + } else { die "$word1 and $word2 not in the correct order or not present as a pair." ; } @@ -1844,7 +1880,7 @@ sub splitlatex { my $leadin=$1; length($string)>0 or return ($leadin); - my @retval=($string =~ m/$pat/osg); + my @retval=($string =~ m/$pat/osg); if (length($string) != length(join("",@retval))) { print STDERR "\nWARNING: Inconsistency in length of input string and parsed string:\n This often indicates faulty or non-standard latex code.\n In many cases you can ignore this and the following warning messages.\n Note that character numbers in the following are counted beginning after \\begin{document} and are only approximate." unless $ignorewarnings; @@ -1888,17 +1924,17 @@ sub splitlatex { # pass1( \@seq1,\@seq2) # Look for differences between seq1 and seq2. -# Where an common-subsequence block is flanked by deleted or appended blocks, +# Where an common-subsequence block is flanked by deleted or appended blocks, # and is shorter than $MINWORDSBLOCK words it is appended -# to the last deleted or appended word. If the block contains tokens other than words +# to the last deleted or appended word. If the block contains tokens other than words # or punctuation it is not merged. # Deleted or appended block consisting of words and safe commands only are # also merged, to prevent break-up in pass2 (after previous isolated words have been removed) -# If there are commands with textual arguments (e.g. \caption) both in corresponding -# appended and deleted blocks split them such that the command and opening bracket -# are one token, then the rest is split up following standard rules, and the closing +# If there are commands with textual arguments (e.g. \caption) both in corresponding +# appended and deleted blocks split them such that the command and opening bracket +# are one token, then the rest is split up following standard rules, and the closing # bracket is a separate token, ie. turn -# "\caption{This is a textual argument}" into +# "\caption{This is a textual argument}" into # ("\caption{","This ","is ","a ","textual ","argument","}") # No return value. Destructively changes sequences sub pass1 { @@ -1927,15 +1963,15 @@ sub pass1 { my $adddiscard = sub { if ($cnt > 0 ) { $matblkcnt++; - # just after an unchanged block + # just after an unchanged block # print STDERR "Unchanged block $cnt, $last1,$last2 \n"; - if ($cnt < $MINWORDSBLOCK + if ($cnt < $MINWORDSBLOCK && $cnt==scalar ( - grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat_n\]|\{$pat_n\})*)/o - && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) + grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat_n\]|\{$pat_n\})*)/o + && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && scalar(@dummy=split(" ",$2))<3 ) } @$block) ) { - # merge identical blocks shorter than $MINWORDSBLOCK + # merge identical blocks shorter than $MINWORDSBLOCK # and only containing ordinary words # with preceding different word # We cannot carry out this merging immediately as this @@ -1943,23 +1979,23 @@ sub pass1 { # the algorithm, instead we store in @$todo where we have to merge push(@$todo, [ $last1,$last2,$cnt,@$block ]); } - $block = []; + $block = []; $cnt=0; $last1=-1; $last2=-1; } }; my $discard=sub { $deltokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$delblock,[ $seq1->[$_[0]],$_[0] ]); - $last1=$_[0] }; + $last1=$_[0] }; my $add = sub { $addtokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$addblock,[ $seq2->[$_[1]],$_[1] ]); - $last2=$_[1] }; + $last2=$_[1] }; my $match = sub { $mattokcnt++; if ($cnt==0) { # first word of matching sequence after changed sequence or at beginning of word sequence - $deltextblocks = extracttextblocks($delblock); + $deltextblocks = extracttextblocks($delblock); $delblkcnt++ if scalar @$delblock; $addtextblocks = extracttextblocks($addblock); $addblkcnt++ if scalar @$addblock; @@ -1975,7 +2011,7 @@ sub pass1 { ### Algorithm::Diff 1.19 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, 0, sub { $_[0]->[0] } ); } else { - ### Algorithm::Diff 1.15 + ### Algorithm::Diff 1.15 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, sub { $_[0]->[0] } ); } @@ -2006,11 +2042,11 @@ sub pass1 { my ($index,$block,$cnt)=@{ shift(@$addtextblocks) }; push(@$todo, [-1,$index,$cnt,@$block]); } - + $addblock=[]; $delblock=[]; } - push(@$block,$seq2->[$_[1]]); + push(@$block,$seq2->[$_[1]]); $cnt++ }; my $keyfunc = sub { join(" ",split(" ",shift())) }; @@ -2018,7 +2054,7 @@ sub pass1 { traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); - # now carry out the merging/splitting. Refer to elements relative from + # now carry out the merging/splitting. Refer to elements relative from # the end (with negative indices) as these offsets don't change before the instruction is executed # cnt>0: merged small unchanged groups with previous changed blocks # cnt==-1: split textual commands into components @@ -2033,7 +2069,7 @@ sub pass1 { } } - if ($verbose) { + if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens in $matblkcnt blocks.\n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; @@ -2043,10 +2079,10 @@ sub pass1 { # extracttextblocks(\@blockindex) -# $blockindex has the following format -# [ [ token1, index1 ], [token2, index2],.. ] -# where index refers to the index in the original old or new word sequence -# Returns: reference to an array of the form +# $blockindex has the following format +# [ [ token1, index1 ], [token2, index2],.. ] +# where index refers to the index in the original old or new word sequence +# Returns: reference to an array of the form # [[ $index, $textblock, $cnt ], .. # where $index index of block to be merged # $textblock contains all the words to be merged with the word at $index (but does not contain this word) @@ -2054,7 +2090,7 @@ sub pass1 { # # requires: iscmd # -sub extracttextblocks { +sub extracttextblocks { my $block=shift; my ($i,$token,$index); my $textblock=[]; @@ -2064,13 +2100,13 @@ sub extracttextblocks { # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace='\s*'; + my $extraspace='\s*'; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # store pure text blocks - if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*)/ - && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) + if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*)/ + && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && !iscmd($1,\@TEXTCMDLIST,\@TEXTCMDEXCL))) { # we have text or a command which can be treated as text if ($last<0) { @@ -2078,7 +2114,7 @@ sub extracttextblocks { $last=$index; } else { # add to pure-text block - push(@$textblock, $token); + push(@$textblock, $token); } } else { # it is not text @@ -2099,29 +2135,29 @@ sub extracttextblocks { # extractcommands( \@blockindex ) -# $blockindex has the following format -# [ [ token1, index1 ], [token2, index2],.. ] -# where index refers to the index in the original old or new word sequence -# Returns: reference to an array of the form -# [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],.. -# where index is just taken from input array -# command must have a textual argument as last argument -# -# requires: iscmd -# -sub extractcommands { +# $blockindex has the following format +# [ [ token1, index1 ], [token2, index2],.. ] +# where index refers to the index in the original old or new word sequence +# Returns: reference to an array of the form +# [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],.. +# where index is just taken from input array +# command must have a textual argument as last argument +# +# requires: iscmd +# +sub extractcommands { my $block=shift; my ($i,$token,$index,$cmd,$open,$mid,$closing); my $retval=[]; # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace='\s*'; + my $extraspace='\s*'; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # check if token is an alphanumeric command sequence with at least one non-optional argument - # \cmd[...]{...}{last argument} + # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: \cmd @@ -2129,7 +2165,7 @@ sub extractcommands { # $4: } + trailing spaces if ( ( $token =~ m/^(\\([\w\d\*]+)(?:${extraspace}\[$brat_n\]|${extraspace}\{$pat_n\})*${extraspace}\{)($pat_n)(\}\s*)$/so ) && iscmd($2,\@TEXTCMDLIST,\@TEXTCMDEXCL) ) { - print STDERR "DEBUG EXTRACTCOMMANDS Match |$1|$2|$3|$4|$index \n" if $debug; + print STDERR "DEBUG EXTRACTCOMMANDS Match |$1|$2|$3|$4|$index \n" if $debug; # push(@$retval,[ $2,$index,$1,$3,$4 ]); ($cmd,$open,$mid,$closing) = ($2,$1,$3,$4) ; $closing =~ s/\}/\\RIGHTBRACE/ ; @@ -2140,7 +2176,7 @@ sub extractcommands { } # iscmd($cmd,\@regexarray,\@regexexcl) checks -# return 1 if $cmd matches any of the patterns in the +# return 1 if $cmd matches any of the patterns in the # array $@regexarray, and none of the patterns in \@regexexcl, otherwise return 0 sub iscmd { my ($cmd,$regexar,$regexexcl)=@_; @@ -2148,7 +2184,7 @@ sub iscmd { ### print STDERR "DEBUG: iscmd($cmd)=" if $debug; foreach $pat ( @$regexar ) { if ( $cmd =~ m/^${pat}$/ ) { - $ret=1 ; + $ret=1 ; last; } } @@ -2164,13 +2200,13 @@ sub iscmd { # pass2( \@seq1,\@seq2) -# Look for differences between seq1 and seq2. +# Look for differences between seq1 and seq2. # Mark begin and end of deleted and appended sequences with tags $DELOPEN and $DELCLOSE # and $ADDOPEN and $ADDCLOSE, respectively, however exclude { } & and all comands, unless # they match an element of the whitelist (SAFECMD) # For words in TEXTCMD but not in SAFECMD, enclose interior with $ADDOPEN and $ADDCLOSE brackets -# Deleted comment lines are marked with %DIF < -# Added comment lines are marked with %DIF > +# Deleted comment lines are marked with %DIF < +# Added comment lines are marked with %DIF > sub pass2 { my $seq1 = shift ; my $seq2 = shift ; @@ -2202,7 +2238,7 @@ sub pass2 { $addhunk = []; } push(@$retval,$seq2->[$_[1]]) }; - + my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); @@ -2211,7 +2247,7 @@ sub pass2 { push @$retval,marktags($ADDMARKOPEN,$ADDMARKCLOSE,$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,$addhunk) if scalar @$addhunk; - if ($verbose) { + if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens. \n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; @@ -2233,7 +2269,7 @@ sub marktags { my (@argtext); my $retval=[]; my $noncomment=0; - my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word + my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word # 1: last token written is a command # for keeping track whether we are just in a command sequence or in a word sequence my $cmdcomment= ($opencmd =~ m/^%/); # Flag to indicate whether opencmd is a comment (i.e. if we intend to simply comment out changed commands) @@ -2249,31 +2285,31 @@ sub marktags { # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace_mt='\s*'; + my $extraspace_mt='\s*'; foreach (@$block) { - $word=$_; + $word=$_; if ( $word =~ s/^%/%$comment/ ) { # a comment if ($cmd==1) { push (@$retval,$closecmd) ; $cmd=-1; } - push (@$retval,$word); + push (@$retval,$word); next; } if ( $word =~ m/^\s*$/ ) { ### print STDERR "DEBUG MARKTAGS: whitespace detected |$word| cmdcom |$cmdcomment| |$opencmd|\n" if $debug; # a sequence of white-space characters - this should only ever happen for the first element of block. - # in deleted block, omit, otherwise just copy it in + # in deleted block, omit, otherwise just copy it in if ( ! $cmdcomment) { # ignore in deleted blocks push(@$retval,$word); } next; } if (! $noncomment) { - push (@$retval,$openmark); + push (@$retval,$openmark); $noncomment=1; } # negative lookahead pattern (?!) in second clause is put in to avoid matching \( .. \) patterns @@ -2283,7 +2319,7 @@ sub marktags { # word is a command or other significant token (not in SAFECMDLIST) ## same conditions as in subroutine extractcommand: # check if token is an alphanumeric command sequence with at least one non-optional argument - # \cmd[...]{...}{last argument} + # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: cmd @@ -2300,11 +2336,11 @@ sub marktags { # Condition 3: But if we are in a deleted block ($cmdcomment=1) and # $2 (the command) is in context2, just treat it as an ordinary command (i.e. comment it open with $opencmd) # Because we do not want to disable this command - # here we do not use $opencmd and $closecmd($opencmd is empty) + # here we do not use $opencmd and $closecmd($opencmd is empty) print STDERR "DEBUG: Detected text |$word| but not safe command \$2: $2 \$3: $3\n." if $debug; if ($cmd==1) { push (@$retval,$closecmd) ; - } elsif ($cmd==0) { + } elsif ($cmd==0) { push (@$retval,$close) ; } $command=$1; $commandword=$2; $closingbracket=$4; @@ -2320,16 +2356,16 @@ sub marktags { # for latexrevise push (@$retval,$command,"%\n{$AUXCMD\n",marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } elsif ( iscmd($commandword,,\@MATHTEXTCMDLIST, \@MATHTEXTCMDEXCL) ) { - # MATHBLOCK pseudo command: consider all commands safe, except & and \\, \begin and \end and a few package sprcific one (look at UNSAFEMATHCMD definition) - # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to + # MATHBLOCK pseudo command: consider all commands safe, except & and \\, \begin and \end and a few package sprcific one (look at UNSAFEMATHCMD definition) + # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to # "" - local @SAFECMDLIST=(".*"); + local @SAFECMDLIST=(".*"); local @SAFECMDEXCL=('\\','\\\\',@UNSAFEMATHCMD); push(@$retval,$command,marktags("","",$open,$close,"","",$comment,\@argtext)#@argtext ,$closingbracket); } else { # normal textcmd or context1cmd in an added block - push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); + push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } push (@$retval,$AUXCMD,"\n") if $cmdcomment ; $cmd=-1 ; @@ -2415,10 +2451,10 @@ sub take_comments_and_newline_from_frac() { # names or labels but it does not matter because they are converted back in the postprocessing step # Returns: leading white space removed in step 1 sub preprocess { - for (@_) { + for (@_) { - # change in \verb and similar commands - note that I introduce an extra space here so that the + # change in \verb and similar commands - note that I introduce an extra space here so that the # already hashed variants do not trigger again # transform \lstinline{...} # s/\\lstinline(\[$brat0\])?(\{(?:.*?)\})/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg; @@ -2448,7 +2484,7 @@ sub preprocess { 1 while s/(?<!\\)_(\s*{($pat_n)})/\\SUBSCRIPT$1/g ; # Convert ^n into \SUPERSCRIPTNB{n} and ^{nnn} into \SUPERSCRIPT{nn} 1 while s/(?<!\\)\^(\s*([^{\\\s]|\\\w+))/\\SUPERSCRIPTNB{$1}/g ; - 1 while s/(?<!\\)\^(\s*{($pat_n)})/\\SUPERSCRIPT$1/g ; + 1 while s/(?<!\\)\^(\s*{($pat_n)})/\\SUPERSCRIPT$1/g ; # Convert \sqrt{n} into \SQRT{n} and \sqrt nn into SQRTNB{nn} 1 while s/(?<!\\)\\sqrt(\s*([^{\\\s]|\\\w+))/\\SQRTNB{$1}/g ; 1 while s/(?<!\\)\\sqrt(\s*{($pat_n)})/\\SQRT$1/g ; @@ -2468,16 +2504,16 @@ sub preprocess { if ( $mathmarkup != FINE ) { # DIFANCHORARRB and DIFANCHORARRE, DIFANCHORMATHB and DIFANCHORMATHE markers are inserted here to encourage the matching algorithm # to always match up the closing brace. Otherwise sometimes one ends up with a situation where - # the closing brace is deleted and added at another point. The deleted closing brace is then + # the closing brace is deleted and added at another point. The deleted closing brace is then # prevented by a %DIFDELCMD, leading to material leaking in or out of the math environment. # The anchors are removed in post-processing again. (note that they are simple text to cause least amount of complications - # Admittedly, this is something of a hack and will not always work. If it does not, then one needs to + # Admittedly, this is something of a hack and will not always work. If it does not, then one needs to # resort to WHOLE or FINE, or NONE math mode processing. s/\\begin\{($ARRENV)}(.*?)\\end\{\1}/\\ARRAYBLOCK$1\{$2\\DIFANCHORARRB \}\\DIFANCHORARRE /sg; take_comments_and_newline_from_frac(); - # Convert Math environments with arguments + # Convert Math environments with arguments s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}((?:\[$brat_n\])|(?:\{$pat_n\}))+(.*?)\\end\{\1\}/\\MATHBLOCK$1\[$2\]\{$3\\DIFANCHORMATHB \}\\DIFANCHORMATHE /sg; # Convert Math environments without arguments s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)\\end\{\1\}/\\MATHBLOCK$1\{$2\\DIFANCHORMATHB \}\\DIFANCHORMATHE /sg; @@ -2491,7 +2527,7 @@ sub preprocess { # $expanded=linecomment($string) #preface all lines with verbatim marker (usually DIFVRB) -sub linecomment { +sub linecomment { my @verbatimlines=split("\n",$_[0]); # the first line needs special treatment - we do want to retain optional arguments as is but wrap the remainder also with VERBCOMMENT ### print STDERR "DEBUG: before verbatimlines[0] = ",$verbatimlines[0],"\n"; @@ -2501,7 +2537,7 @@ sub linecomment { } # $simple=reverselinecomment($env $string) -# remove DIFVRB comments but leave changed lines marked +# remove DIFVRB comments but leave changed lines marked sub reverselinecomment { my ($environment, $verbatimtext)=@_; ### print STDERR "DEBUG REVERSELINECOMMENT input: $environment,|$verbatimtext|\n" if $debug; @@ -2516,7 +2552,7 @@ sub reverselinecomment { $verbatimtext =~ s/\\DIFdelend //g; $verbatimtext =~ s/$DELCMDOPEN.*//g; - # remove DIFVRB mark + # remove DIFVRB mark $verbatimtext=~ s/%$VERBCOMMENT//g; # remove part of the markup in changed lines @@ -2607,7 +2643,7 @@ sub writedebugfile { # * Remove STOP token from the end # * Replace \RIGHTBRACE by } # * If option --no-del is set delete all deleted blocks -# 1. Check all deleted blocks: +# 1. Check all deleted blocks: # a.where a deleted block contains a matching \begin and # \end environment (these will be disabled by a %DIFDELCMD statements), for selected environments enable # these commands again (such that for example displayed math in a deleted equation @@ -2628,14 +2664,14 @@ sub writedebugfile { # For added blocks: # c. If in-line math mode contains array environment, enclose the whole environment in \mbox'es # d. place \cite commands in mbox'es (for UNDERLINE style) -# +# # 2. If math-mode COARSE,WHOLE or NONE option set: Convert \MATHBLOCKmath{..} commands back to environments # # Convert all PICTUREblock{..} commands back to the appropriate environments # 3. Convert DIFadd, DIFdel, DIFaddbegin , ... into FL varieties # within floats (currently recognised float environments: plate,table,figure # plus starred varieties). -# 4. Remove empty %DIFDELCMD < lines +# 4. Remove empty %DIFDELCMD < lines # 4. Convert \begin{SQUAREBRACKET} \end{SQUAREBRACKET} into \[ \] # Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$ # 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn} @@ -2648,7 +2684,7 @@ sub writedebugfile { # 4, undo renaming of the \begin, \end,{,} in comments # Change \QLEFTBRACE, \QRIGHTBRACE,\AMPERSAND to \{,\},\& # -# Note have to manually synchronize substitution commands below and +# Note have to manually synchronize substitution commands below and # DIF.. command names in the header sub postprocess { my ($begin,$len,$float,$delblock,$addblock); ### $cnt @@ -2660,7 +2696,7 @@ sub postprocess { my (@itemargs, $itemarg); - for (@_) { + for (@_) { # change $'s in comments to something harmless 1 while s/(%.*)\$/$1DOLLARDIF/mg ; @@ -2670,7 +2706,7 @@ sub postprocess { # the only way to get these is as %DIFDELCMD < \RIGHTBRACE construction # This essentially marks closing right braces of MATHBLOCK environments, which did not get matched # up. This case should be rare, so I just leave this in the diff file output. Not really elegant - # but can still be dealt with later if it results in problems. + # but can still be dealt with later if it results in problems. s/%DIFDELCMD < \\RIGHTBRACE/%DIFDELCMD < \\MBLOCKRIGHTBRACE/g ; # Replace \RIGHTBRACE by } s/\\RIGHTBRACE/}/g; @@ -2698,7 +2734,7 @@ sub postprocess { $len=length($&); $begin=pos($_) - $len; $delblock=$&; - ### A much simpler method for math replacement might follow this strategy (can recycle part of the commands below for following + ### A much simpler method for math replacement might follow this strategy (can recycle part of the commands below for following ### this strategy: ### 1. a Insert aux commands \begin{MATHMODE} or \end{MATHMODE} for all deleted commands opening or closing displayed math mode ### b Insert aux commands \begin{MATHARRMODE} or \end{MATHARRMODE} for all deleted commands opening or closing math array mode @@ -2724,14 +2760,14 @@ sub postprocess { ###0.5: $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg; $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}.*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{\2\})/\\end\{MATHMODE\}$AUXCMD\n$1$3\n\\begin\{MATHMODE\}$AUXCMD\n$4/sg; - # now look for unpaired %DIFDELCMD < \begin{MATHENV}; if found add \begin{$MATHREPL} and insert \end{$MATHREPL} + # now look for unpaired %DIFDELCMD < \begin{MATHENV}; if found add \begin{$MATHREPL} and insert \end{$MATHREPL} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\begin{$MATHREPL}$AUXCMD\n/sg ) { ### print STDERR "BINGO: begin block: \nBefore: |" . substr($_,$begin,$len) . "|\n" if $debug ; $delblock =~ s/(\\DIFdelend$)/\\end{$MATHREPL}$AUXCMD\n$1/s ; ### print STDERR "After: |" . $delblock . "|\n\n" if $debug ; } - # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} + # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end\{MATHMODE\}$AUXCMD\n/sg ) { ### print STDERR "BINGO: end block:\nBefore: |" . substr($_,$begin,$len) . "|\n" if $debug; @@ -2754,15 +2790,15 @@ sub postprocess { $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg; ### print STDERR "STEP1: |" . $delblock . "|\n\n" if $debug ; - # now look for unpaired %DIFDELCMD < \begin{MATHARRENV}; if found add \begin{$MATHARRREPL} and insert \end{$MATHARRREPL} + # now look for unpaired %DIFDELCMD < \begin{MATHARRENV}; if found add \begin{$MATHARRREPL} and insert \end{$MATHARRREPL} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{($MATHARRENV)\}(.*?)(?:$DELCMDCLOSE|\n))/$1\\begin{$2*}$3$AUXCMD\n/sg ) { $arrenv=$2; - $delblock =~ s/(\\DIFdelend$)/\\end{$arrenv*}}$AUXCMD\n$1/s ; + $delblock =~ s/(\\DIFdelend$)/\\end{$arrenv*}$AUXCMD\n$1/s ; } ### print STDERR "STEP2: |" . $delblock . "|\n\n" if $debug ; - # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} + # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end{MATHMODE}$AUXCMD\n/sg ) { $delblock =~ s/(\\DIFdelend$)/\\begin{MATHMODE}$AUXCMD\n$1/s ; @@ -2780,7 +2816,7 @@ sub postprocess { ### $eqarrayblock=~ s/(\%DIFDELCMD < \s*(\&|\\\\)\s*?(?:$DELCMDCLOSE|\n))/$1$2$AUXCMD\n/sg ; $eqarrayblock =~ s/(\%DIFDELCMD < (.*?(?:\&|\\\\).*)(?:$DELCMDCLOSE|\n))/ # The pattern captures comments with at least one of & or \\ - @symbols= split(m@((?:&|\\\\)\s*)@,$2); # extract & and \\ and other material from sequence + @symbols= split(m@((?:&|\\\\)\s*)@,$2); # extract & and \\ and other material from sequence @symbols= grep ( m@&|\\\\\s*@, @symbols); # select & and \\ (and subsequent spaces) "$1@symbols$AUXCMD\n" /eg ; @@ -2793,7 +2829,7 @@ sub postprocess { } elsif ( $mathmarkup == COARSE || $mathmarkup == WHOLE ) { # Convert MATHBLOCKmath commands to their uncounted numbers (e.g. convert equation -> displaymath # (environments defined in $MATHENV will be replaced by $MATHREPL, and environments in $MATHARRENV - # will be replaced by their starred variety + # will be replaced by their starred variety $delblock=~ s/\\MATHBLOCK($MATHENV)((?:\[$brat_n\])?)\{($pat_n)\}/\\MATHBLOCK$MATHREPL$2\{$3\}/sg; $delblock=~ s/\\MATHBLOCK($MATHARRENV)((?:\[$brat_n\])?)\{($pat_n)\}/\\MATHBLOCK$1\*$2\{$3\}/sg; } @@ -2807,10 +2843,10 @@ sub postprocess { print STDERR "DELBLOCK after maths processing: |" . $delblock . "|\n\n" if $debug ; - # Reinstate completely deleted list environments. note that items within the + # Reinstate completely deleted list environments. note that items within the # environment will still be commented out. They will be restored later $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($LISTENV)\}\s*?(?:\n|$DELCMDCLOSE))(.*?)(\%DIFDELCMD < \s*\\end\{\2\})/{ - ### # block within the search; replacement environment + ### # block within the search; replacement environment ### "$1\\begin{$2}$AUXCMD\n". restore_item_commands($3). "\n\\end{$2}$AUXCMD\n$4"; "$1\\begin{$2}$AUXCMD\n$3\n\\end{$2}$AUXCMD\n$4"; }/esg; @@ -2844,7 +2880,7 @@ sub postprocess { ### if ($CITE2CMD) { ###### ${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})) .*?%%%\n ### $delblock=~s/($DELCMDOPEN\s*\\($CITE2CMD)(.*)$DELCMDCLOSE)/ - ### # Replacement code + ### # Replacement code ### {my ($aux,$all); ### $aux=$all=$1; ### $aux=~s#\n?($DELCMDOPEN|$DELCMDCLOSE)##g; @@ -2854,7 +2890,7 @@ sub postprocess { ### if ($CITECMD) { ###### $delblock=~s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; ### $delblock=~s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; - ### } + ### } # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox @@ -2862,7 +2898,7 @@ sub postprocess { # note additional \newline after command is omitted from output if right at the end of deleted block (otherwise a spurious empty line is generated) $delblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } - ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/)) { + ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/)) { ### # change included verbatim environments ### $delblock =~ s/\\DIFverb\{/\\DIFDIFdelverb\{/g; ### $delblock =~ s/\\DIFlstinline/\\DIFDIFdellstinline/g; @@ -2904,7 +2940,7 @@ sub postprocess { ##$addblock=~s/($math)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; $addblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } - ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { + ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { # mark added verbatim commands $addblock =~ s/\\DIFverb/\\DIFDIFaddverb/g; $addblock =~ s/\\DIFlstinline/\\DIFDIFaddlstinline/g; @@ -2922,11 +2958,11 @@ sub postprocess { pos = $begin + length($addblock); } - # Go through whole text, and by counting list environment commands, find out when we are within a list environment. + # Go through whole text, and by counting list environment commands, find out when we are within a list environment. # Within those restore deleted \item commands - @textparts=split /(?<!$DELCMDOPEN)(\\(?:begin|end)\{$LISTENV\})/ ; + @textparts=split /(?<!$DELCMDOPEN)(\\(?:begin|end)\{$LISTENV\})/ ; @liststack=(); - @newtextparts=map { + @newtextparts=map { ### print STDERR ":::::::: $_\n"; if ( ($listtype) = m/^\\begin\{($LISTENV)\}$/ ) { print STDERR "DEBUG: postprocess \\begin{$listtype}\n" if $debug; @@ -2942,7 +2978,7 @@ sub postprocess { } else { print STDERR "DEBUG: postprocess \@liststack=(",join(",",@liststack),")\n" if $debug; if (scalar @liststack > 0 ) { - # we are within a list environment and should replace all item commands + # we are within a list environment and should replace all item commands $_=restore_item_commands($_); } # else: we are outside a list environment and do not need to do anything @@ -2955,17 +2991,17 @@ sub postprocess { # Replace MATHMODE environments from step 1a above by the correct Math environment and remove unncessary pairings - + if ( $mathmarkup == FINE ) { # look for AUXCMD math-mode pairs which have only comments (or empty lines between them), and remove the added commands # \begin{..} ... \end{..} pairs - s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\end\{\1\}$AUXCMD\n/$2/sg; + s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\end\{\1\}$AUXCMD\n/$2/sg; # \end{..} .... \begin{..} pairs - s/\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\begin\{\1\}$AUXCMD\n/$2/sg; + s/\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\begin\{\1\}$AUXCMD\n/$2/sg; writedebugfile($_,'postprocess15'); # The next line is complicated. The negative look-ahead insertion makes sure that no \end{$MATHENV} (or other mathematical - # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching + # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching # is not globally minimal but only 'locally' (matching is beginning from the left side of the string) # [NB: Do not be tempted to prettify the expression with /x modified. It seems this is applied after strings are expanded so will ignore spaces in strings 1 while s/(?<!$DELCMDOPEN)\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}((?:${DELCMDOPEN}[^\n]*|.(?!(?:\\end\{(?:(?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}|\\begin\{MATHMODE})))*?)\\end\{MATHMODE}/\\begin{$1}$2\\end{$1}/s; @@ -3040,7 +3076,7 @@ sub postprocess { # remove empty DIFCMD < lines s/^\Q${DELCMDOPEN}\E\n//msg; - # Expand hashes of verb and verbatim environments + # Expand hashes of verb and verbatim environments s/${DELCMDOPEN}\\($VERBATIMENV)\{([-\d]*?)\}/"${DELCMDOPEN}\\begin{${1}}".fromhash(\%verbhash,$2,$DELCMDOPEN)."${DELCMDOPEN}\\end{${1}}"/esg; # revert changes to verbatim environments for line diffs (and add code to mark up changes) (note negative look behind assertions to not leak out of DIFDELCMD comments) # Example: @@ -3066,8 +3102,8 @@ sub postprocess { ((?:\%\Q$DELCOMMENT$VERBCOMMENT\E[^\n]*?\n)*) # Deleted \end command of verbatim environment. Note that the type is forced to match the opening. Captures: $5: Whole deleted environment (previous way this line was written: (\Q$DELCMDOPEN\E\\end\{\2\}(?:\n|\s|\Q$DELCMDOPEN\E)*\Q$DELCMDCLOSE\E) (\Q$DELCMDOPEN\E\\end\{\2\}) - / # Substitution part - $1 # Leave expression as is + / # Substitution part + $1 # Leave expression as is . "$AUXCMD NEXT\n" # Mark the following line as an auxiliary command . "" # reinstate the original environment without options . reverselinecomment($2, "$3$4") # modify the body to change the markup; reverselinecomment parses for options @@ -3076,7 +3112,7 @@ sub postprocess { /esgx; # Modifiers of substitution command writedebugfile($_,'postprocess2'); # where changes have occurred in verbatim environment, change verbatim to DIFverbatim to allow mark-up - # (I use the presence of optional paramater to verbatim environment as the marker - normal verbatim + # (I use the presence of optional paramater to verbatim environment as the marker - normal verbatim # environment does not take optional arguments) s/(?<!$DELCMDOPEN)\\begin\{(verbatim[*]?)\}(\[$brat_n\].*?)\\end\{\1\}/\\begin{DIF$1}$2\\end{DIF$1}/sg; @@ -3090,7 +3126,7 @@ sub postprocess { # convert remaining PAR commands (which are preceded by non-white space characters, usually "}" ($ADDCLOSE) s/\\PAR\n/\n\n/sg; - # package specific processing: + # package specific processing: if ( defined($packages{"endfloat"})) { #endfloat: make sure \begin{figure} and \end{figure} are always # on a line by themselves, similarly for table environment @@ -3103,12 +3139,16 @@ sub postprocess { s/^((?:[^%]+)\\(?:begin|end)\{(?:figure|table)\}(?:\[[a-zA-Z]+\])?)(.+)((?:%.*)?)$/$1\n$2$3/mg; } - # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated + # Remove empty auxiliary LISTENV (sometmes these are generated if list environment occurs within the argument of a deleted comment) + # (slightly hacky but I could not see an easy way to see if in argument of another command when this extra markup is added) + s/\\begin\{($LISTENV)\}$AUXCMD\n((?:\s*\%[^\n]*\n)*\n?)\\end\{\1\}$AUXCMD\n/$2\n/msg ; + + # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated s/\\PERCENTAGE ?/\\%/g; - # Convert '\DOLLAR ' back into '\$' + # Convert '\DOLLAR ' back into '\$' s/\\DOLLAR /\\\$/g; - # undo renaming of the \begin and \end,{,} and dollars in comments + # undo renaming of the \begin and \end,{,} and dollars in comments # although we only renamed $ in comments to DOLLARDIFF, we might have lost the % in unchanged verbatim blocks, so rename all s/DOLLARDIF/\$/g; @@ -3126,7 +3166,7 @@ sub postprocess { # Convert \SQRT{n} into \sqrt{n} and \SQRTNB{nn} into \sqrt nn 1 while s/\\SQRT(\s*\{($pat_n)\})/\\sqrt$1/g ; 1 while s/\\SQRTNB\{(\s*$pat0)\}/\\sqrt$1/g ; - + 1 while s/(%.*)\\CFRAC (.*)$/$1\\frac$2/mg ; 1 while s/(%.*)\\CRIGHTBRACE (.*)$/$1\}$2/mg ; 1 while s/(%.*)\\CLEFTBRACE (.*)$/$1\{$2/mg ; @@ -3137,7 +3177,7 @@ sub postprocess { s/\\QRIGHTBRACE /\\\}/sg; s/\\AMPERSAND /\\&/sg; # Highlight added inline verbatim commands if possible - if ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) { + if ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) { # wrap added verb commands with color commands s/\\DIFDIFadd((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*)/\{\\color{blue}$AUXCMD\n\\DIF$1%\n\}$AUXCMD\n/sg; s/\\DIFDIFdel((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*$AUXCMD)/\{\\color{red}${AUXCMD}\n\\DIF$1\n\}${AUXCMD}/sg; @@ -3152,8 +3192,8 @@ sub postprocess { # finally add the comment to the ones not having an optional argument before ###s/\\DIFaddlstinline(?!\[)/\\lstinline\n[basicstyle=\\color{blue}]$AUXCMD\n/g; - return; } + return; } # $out = restore_item_commands($listenviron) @@ -3177,13 +3217,13 @@ sub restore_item_commands { # @auxlines=preprocess_preamble($oldpreamble,$newpreamble); - # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) - # the list of commands is defined in CONTEXT2CMD - # if found then use a bodydiff to mark up content, and replace the corresponding commands + # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) + # the list of commands is defined in CONTEXT2CMD + # if found then use a bodydiff to mark up content, and replace the corresponding commands # in both preambles by marked up version to 'fool' the linediff (such that only body is marked up). # A special case are e.g. author commands being added (or removed) # 1. If commands are added, then the entire content is marked up as new, but also the lines are marked as new in the linediff - # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns + # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns # with $auxlines a text to be appended at the end of the preamble, which shows the respective fields as deleted sub preprocess_preamble { my ($oldpreambleref,$newpreambleref)=(\$_[0],\$_[1]) ; @@ -3205,7 +3245,7 @@ EOF $titlecmd = "(?:".join("|",@CONTEXT2CMDLIST).")"; # as context2cmdlist is stored as regex, e.g. ((?-xism:^title$), we need to remove ^- fo # resue in a more complex regex - $titlecmd =~ s/[\$\^]//g; + $titlecmd =~ s/[\$\^]//g; # make sure to not match on comment lines: $titlecmdpat=qr/^(?:[^%\n]|\\%)*(\\($titlecmd)$extraspace(?:\[($brat_n)\])?(?:\{($pat_n)\}))/ms; ###print STDERR "DEBUG:",$titlecmdpat,"\n"; @@ -3231,7 +3271,7 @@ EOF $cmd=shift @newtitlecommands; $optarg=shift @newtitlecommands; $arg=shift @newtitlecommands; - + if ( defined($newhash{$cmd})) { warn "$cmd is used twice in preamble of new file. Reverting to pure line diff mode for preamble.\n"; print STDERR $warnmsgdetail; @@ -3258,7 +3298,7 @@ EOF } $argnew=$newhash{$cmd}->[2]; $argdiff="{" . join("",bodydiff($argold,$argnew)) ."}"; - # Replace \RIGHTBRACE by } + # Replace \RIGHTBRACE by } $argdiff =~ s/\\RIGHTBRACE/}/g; if ( length $optargnew ) { @@ -3273,7 +3313,7 @@ EOF $optargdiff=""; } ### print STDERR "DEBUG s/\\Q$newhash{$cmd}->[0]\\E/\\$cmd$optargdiff$argdiff/s\n"; - # Note: \Q and \E force literal interpretation of what it between them but allow + # Note: \Q and \E force literal interpretation of what it between them but allow # variable interpolation, such that e.g. \title matches just that and not TAB-itle $$newpreambleref=~s/\Q$newhash{$cmd}->[0]\E/\\$cmd$optargdiff$argdiff/s; # replace this in old preamble if necessary @@ -3313,7 +3353,7 @@ EOF #%< old deleted line(s) #%DIF ------- #%DIF mmann-nn -#new appended line %< +#new appended line %< #%DIF ------- # Future extension: mark change explicitly # Assumes: traverse_sequence traverses deletions before insertions in changed sequences @@ -3325,9 +3365,9 @@ sub linediff { my $block = []; my $retseq = []; my @begin=('','',''); # dummy initialisation - my $instring ; + my $instring ; - my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ; + my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ; push(@$block, "%DIF < " . $seq1->[$_[0]]) }; my $add = sub { if (! scalar @$block) { @begin=('a',$_[0],$_[1]) ;} @@ -3342,12 +3382,12 @@ sub linediff { $instring = sprintf "%%DIF %da%d-%d",$begin[1],$begin[2],$_[1]-1; } elsif ( $begin[0] eq 'c' ) { $instring = sprintf "%%DIF %sc%s", - ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) , + ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) , ($begin[2]==$_[1]-1) ? "$begin[2]" : $begin[2]."-".($_[1]-1) ; } else { $instring = sprintf "%%DIF %d%s%d",$begin[1],$begin[0],$begin[2]; } - push @$retseq, $instring,@$block, "%DIF -------" ; - $block = []; + push @$retseq, $instring,@$block, "%DIF -------" ; + $block = []; } push @$retseq, $seq2->[$_[1]] }; @@ -3355,7 +3395,7 @@ sub linediff { my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); - push @$retseq, @$block if scalar @$block; + push @$retseq, @$block if scalar @$block; return wantarray ? @$retseq : $retseq ; } @@ -3365,23 +3405,23 @@ sub linediff { # init_regex_arr_data(\@array,"TOKEN INIT") # scans DATA file handel for line "%% TOKEN INIT" line # then appends each line not beginning with % into array (as a quoted regex) -# This is used for command lists and configuration variables, but the processing is slightly -# different: +# This is used for command lists and configuration variables, but the processing is slightly +# different: # For lists, the regular expression is extended to include beginning (^) and end ($) markers, to require full-string matching # For configuration variables (and all others), simply an unadorned list is copied sub init_regex_arr_data { my ($arr,$token)=@_; my $copy=0; my ($mode); - if ($token =~ m/COMMANDS/ ) { - $mode=0; # Reading command list + if ($token =~ m/COMMANDS/ ) { + $mode=0; # Reading command list } else { $mode=1; # Reading configuration variables } while (<DATA>) { if ( m/^%%BEGIN $token\s*$/ ) { - $copy=1; + $copy=1; next; } elsif ( m/^%%END $token\s*$/ ) { last; } @@ -3462,17 +3502,18 @@ sub exetime { sub usage { - print STDERR <<"EOF"; + print STDERR <<"EOF"; Usage: $0 [options] old.tex new.tex > diff.tex -Compares two latex files and writes tex code to stdout, which has the same format as new.tex but +Compares two latex files and writes tex code to stdout, which has the same format as new.tex but has all changes relative to old.tex marked up or commented. Note that old.tex and new.tex need to -be real files (not pipes or similar) as they are opened twice. +be real files (not pipes or similar) as they are opened twice. --type=markupstyle -t markupstyle Add code to preamble for selected markup style - Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE + Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT + LUAUNDERLINE [ Default: UNDERLINE ] --subtype=markstyle @@ -3483,7 +3524,7 @@ be real files (not pipes or similar) as they are opened twice. * LABEL subtype is deprecated --floattype=markstyle --f markstyle Add code to preamble for selected style which +-f markstyle Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats so marginal marking can be disabled thus) @@ -3492,11 +3533,11 @@ be real files (not pipes or similar) as they are opened twice. --encoding=enc -e enc Specify encoding of old.tex and new.tex. Typical encodings are - ascii, utf8, latin1, latin9. A list of available encodings can be - obtained by executing + ascii, utf8, latin1, latin9. A list of available encodings can be + obtained by executing perl -MEncode -e 'print join ("\\n",Encode->encodings( ":all" )) ;' [Default encoding is utf8 unless the first few lines of the preamble contain - an invocation "\\usepackage[..]{inputenc} in which case the + an invocation "\\usepackage[..]{inputenc} in which case the encoding chosen by this command is asssumed. Note that ASCII (standard latex) is a subset of utf8] @@ -3513,22 +3554,22 @@ be real files (not pipes or similar) as they are opened twice. --exclude-safecmd=exclude-file --exclude-safecmd="cmd1,cmd2,..." --A exclude-file +-A exclude-file --replace-safecmd=replace-file --append-safecmd=append-file --append-safecmd="cmd1,cmd2,..." -a append-file Exclude from, replace or append to the list of regex - matching commands which are safe to use within the + matching commands which are safe to use within the scope of a \\DIFadd or \\DIFdel command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are ignored). A literal comma within the comma-separated list must be - escaped thus "\\,", Note that the RegEx needs to match the whole of + escaped thus "\\,", Note that the RegEx needs to match the whole of the token, i.e., /^regex\$/ is implied and that the initial "\\" of the command is not included. The --exclude-safecmd - and --append-safecmd options can be combined with the --replace-safecmd + and --append-safecmd options can be combined with the --replace-safecmd option and can be used repeatedly to add cumulatively to the lists. ---exclude-textcmd=exclude-file +--exclude-textcmd=exclude-file --exclude-textcmd="cmd1,cmd2,..." -X exclude-file --replace-textcmd=replace-file @@ -3544,7 +3585,7 @@ be real files (not pipes or similar) as they are opened twice. Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. \\caption will only work within a figure - or table. These commands behave like text commands, except when + or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. @@ -3554,7 +3595,7 @@ be real files (not pipes or similar) as they are opened twice. As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. - context2 commands are also the only commands in the preamble, whose argument will + context2 commands are also the only commands in the preamble, whose argument will be processed in word-by-word mode (which only works, if they occur no more than once in the preamble). @@ -3563,15 +3604,15 @@ be real files (not pipes or similar) as they are opened twice. --append-mboxsafecmd=append-file --append-mboxsafecmd="cmd1,cmd2,..." Define safe commands, which additionally need to be protected by encapsulating - in an \\mbox{..}. This is sometimes needed to get around incompatibilities + in an \\mbox{..}. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE - + --config var1=val1,var2=val2,... -c var1=val1,.. Set configuration variables. --c configfile Available variables: +-c configfile Available variables: ARRENV (RegEx) COUNTERCMD (RegEx) FLOATENV (RegEx) @@ -3590,15 +3631,15 @@ be real files (not pipes or similar) as they are opened twice. --add-to-config varenv1=pattern1,varenv2=pattern2 For configuration variables containing a regular expression (essentially those ending - in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration + in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. varenv must be one of the variables listed above that take a regular - expression as argument, and pattern is any regular expression (which might need to be + expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. --add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote" --packages=pkg1,pkg2,.. - Tell latexdiff that .tex file is processed with the packages in list + Tell latexdiff that .tex file is processed with the packages in list loaded. This is normally not necessary if the .tex file includes the preamble, as the preamble is automatically scanned for \\usepackage commands. Use of the --packages option disables automatic scanning, so if for any @@ -3619,57 +3660,57 @@ be real files (not pipes or similar) as they are opened twice. --show-all Show all of the above - NB For all --show commands, no old.tex or new.tex file needs to be given, and no + NB For all --show commands, no old.tex or new.tex file needs to be given, and no differencing takes place. Other configuration options: --allow-spaces Allow spaces between bracketed or braced arguments to commands - [Default requires arguments to directly follow each other without + [Default requires arguments to directly follow each other without intervening spaces] --math-markup=level Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): - off or 0: suppress markup for math environments. Deleted equations will not - appear in diff file. This mode can be used if all the other modes + off or 0: suppress markup for math environments. Deleted equations will not + appear in diff file. This mode can be used if all the other modes cause invalid latex code. whole or 1: Differencing on the level of whole equations. Even trivial changes - to equations cause the whole equation to be marked changed. This - mode can be used if processing in coarse or fine mode results in + to equations cause the whole equation to be marked changed. This + mode can be used if processing in coarse or fine mode results in invalid latex code. coarse or 2: Detect changes within equations marked up with a coarse - granularity; changes in equation type (e.g.displaymath to equation) + granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] fine or 3: Detect small change in equations and mark up and fine granularity. This mode is most suitable, if only minor changes to equations are - expected, e.g. correction of typos. + expected, e.g. correction of typos. --graphics-markup=level Change highlight style for graphics embedded with \\includegraphics commands Possible values for level: none,off or 0: no highlighting for figures new-only or 1: surround newly added or changed figures with a blue frame [Default] - both or 2: highlight new figures with a blue frame and show deleted figures + both or 2: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable SCALEDELGRAPHICS to set size of deleted figures. - Note that changes to the optional parameters will make the figure appear as changed + Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. In some circumstances "Misplaced \\noalign" errors can occur if there are certain types - of changes in tables. In this case please use option --graphics-markup=none as a - work-around. + of changes in tables. In this case please use option --graphics-markup=none as a + work-around. ---no-del Suppress deleted text from the diff. It is similar in effect to the BOLD style, +--no-del Suppress deleted text from the diff. It is similar in effect to the BOLD style, but the deleted text ist not just invisible in the output, it is also not included in the - diff text file. This can be more robust than just making it invisible. + diff text file. This can be more robust than just making it invisible. ---disable-citation-markup ---disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles +--disable-citation-markup +--disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR) (the two options are identical and are simply aliases) --enable-citation-markup ---enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections +--enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections with \\mbox command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) @@ -3685,14 +3726,14 @@ Miscellaneous options --no-label Suppress inclusion of old and new file names as comment in output file ---visible-label Include old and new filenames (or labels set with --label option) as +--visible-label Include old and new filenames (or labels set with --label option) as visible output --flatten Replace \\input and \\include commands within body by the content of the files in their argument. If \\includeonly is present in the - preamble, only those files are expanded into the document. However, - no recursion is done, i.e. \\input and \\include commands within - included sections are not expanded. The included files are assumed to + preamble, only those files are expanded into the document. However, + no recursion is done, i.e. \\input and \\include commands within + included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, respectively, making it possible to organise files into old and new directories. --flatten is applied recursively, so inputted files can contain further @@ -3715,7 +3756,7 @@ Miscellaneous options -h Show this help text. --ignore-warnings Suppress warnings about inconsistencies in length between input - and parsed strings and missing characters. + and parsed strings and missing characters. --verbose -V Output various status information to stderr during processing. @@ -3727,10 +3768,10 @@ Internal options: These options are mostly for automated use by latexdiff-vc. They can be used directly, but the API should be considered less stable than for the other options. ---no-links Suppress generation of hyperreferences, used for minimal diffs +--no-links Suppress generation of hyperreferences, used for minimal diffs (option --only-changes of latexdiff-vc). EOF - exit 0; + exit 0; } =head1 NAME @@ -3756,8 +3797,8 @@ be real files (not pipes or similar) as they are opened twice (unless C<--encodi The program treats the preamble differently from the main document. Differences between the preambles are found using line-based differencing (similarly to the Unix diff command, but ignoring white -spaces). A comment, "S<C<%DIF E<gt>>>" is appended to each added line, i.e. a -line present in C<new.tex> but not in C<old.tex>. Discarded lines +spaces). A comment, "S<C<%DIF E<gt>>>" is appended to each added line, i.e. a +line present in C<new.tex> but not in C<old.tex>. Discarded lines are deactivated by prepending "S<C<%DIF E<lt>>>". Changed blocks are preceded by comment lines giving information about line numbers in the original files. Where there are insignificant differences, the resulting file C<diff.tex> will be similar to @@ -3810,7 +3851,7 @@ curly braces immediately following a command (i.e. a sequence of letters beginning with a backslash) are arguments for that command. As a restriction to condition 1 above it is thus necessary to surround all arguments with curly braces, and to not insert -extraneous spaces. For example, write +extraneous spaces. For example, write \section{\textem{This is an emphasized section title}} @@ -3842,7 +3883,7 @@ but the choice is yours. Any markup within the environment will be removed, and generally everything within the environment will just be taken from the new file. -It is also possible to difference files which do not have a preamble. +It is also possible to difference files which do not have a preamble. In this case, the file is processed in the main document mode, but the definitions of the markup commands are not inserted. @@ -3860,7 +3901,7 @@ the scope of C<\DIFadd>. Added comments are marked by prepending Within deleted blocks text is highlighted with C<\DIFdel>. Deleted comments are marked by prepending "S<C<%DIF E<lt> >>". Non-safe command -and curly braces within deleted blocks are commented out with +and curly braces within deleted blocks are commented out with "S<C<%DIFDELCMD E<lt> >>". @@ -3870,7 +3911,7 @@ and curly braces within deleted blocks are commented out with =head2 Preamble The following options determine the visual markup style by adding the appropriate -command definitions to the preamble. See the end of this section for a description of +command definitions to the preamble. See the end of this section for a description of available styles. =over 4 @@ -3880,15 +3921,16 @@ B<-t markupstyle> Add code to preamble for selected markup style. This option defines C<\DIFadd> and C<\DIFdel> commands. -Available styles: +Available styles: -C<UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE -CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT> +C<UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE +CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT +LUAUNDERLINE> [ Default: C<UNDERLINE> ] =item B<--subtype=markstyle> or -B<-s markstyle> +B<-s markstyle> Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin). This option defines @@ -3901,27 +3943,27 @@ Available styles: C<SAFE MARGIN COLOR DVIPSCOL ZLABEL ONLYCHANGEDPAGE (LABEL)*> =item B<--floattype=markstyle> or B<-f markstyle> -Add code to preamble for selected style which +Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats -so marginal marking can be disabled thus). This option defines all +so marginal marking can be disabled thus). This option defines all C<\DIF...FL> commands. Available styles: C<FLOATSAFE TRADITIONALSAFE IDENTICAL> [ Default: C<FLOATSAFE> ] -=item B<--encoding=enc> or +=item B<--encoding=enc> or B<-e enc> Specify encoding of old.tex and new.tex. Typical encodings are -C<ascii>, C<utf8>, C<latin1>, C<latin9>. A list of available encodings can be -obtained by executing +C<ascii>, C<utf8>, C<latin1>, C<latin9>. A list of available encodings can be +obtained by executing C<perl -MEncode -e 'print join ("\n",Encode->encodings( ":all" )) ;' > If this option is used, then old.tex, new.tex are only opened once. [Default encoding is utf8 unless the first few lines of the preamble contain -an invocation C<\usepackage[..]{inputenc}> in which case the +an invocation C<\usepackage[..]{inputenc}> in which case the encoding chosen by this command is asssumed. Note that ASCII (standard latex) is a subset of utf8] @@ -3938,7 +3980,7 @@ C<\DIFaddbeginFL, \DIFaddendFL, \DIFaddFL{..}, (If this option is set B<-t>, B<-s>, and B<-f> options are ignored.) -=item B<--packages=pkg1,pkg2,..> +=item B<--packages=pkg1,pkg2,..> Tell latexdiff that .tex file is processed with the packages in list loaded. This is normally not necessary if the .tex file includes the @@ -3949,13 +3991,13 @@ The following packages trigger special behaviour: =over 8 -=item C<endfloat> +=item C<endfloat> Ensure that C<\begin{figure}> and C<\end{figure}> always appear by themselves on a line. =item C<hyperref> -Change name of C<\DIFadd> and C<\DIFdel> commands to C<\DIFaddtex> and C<\DIFdeltex> and +Change name of C<\DIFadd> and C<\DIFdel> commands to C<\DIFaddtex> and C<\DIFdeltex> and define new C<\DIFadd> and C<\DIFdel> commands, which provide a wrapper for these commands, using them for the text but not for the link defining command (where any markup would cause errors). @@ -4007,17 +4049,17 @@ B<-A exclude-file> or B<--exclude-safecmd="cmd1,cmd2,..."> =item B<--replace-safecmd=replace-file> -=item B<--append-safecmd=append-file> or +=item B<--append-safecmd=append-file> or B<-a append-file> or B<--append-safecmd="cmd1,cmd2,..."> Exclude from, replace or append to the list of regular expressions (RegEx) -matching commands which are safe to use within the +matching commands which are safe to use within the scope of a C<\DIFadd> or C<\DIFdel> command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are -ignored). Note that the RegEx needs to match the whole of +ignored). Note that the RegEx needs to match the whole of the token, i.e., /^regex$/ is implied and that the initial -"\" of the command is not included. -The B<--exclude-safecmd> and B<--append-safecmd> options can be combined with the -B<--replace-safecmd> +"\" of the command is not included. +The B<--exclude-safecmd> and B<--append-safecmd> options can be combined with the -B<--replace-safecmd> option and can be used repeatedly to add cumulatively to the lists. B<--exclude-safecmd> and B<--append-safecmd> can also take a comma separated list as input. If a @@ -4030,7 +4072,7 @@ B<-X exclude-file> or B<--exclude-textcmd="cmd1,cmd2,..."> =item B<--replace-textcmd=replace-file> -=item B<--append-textcmd=append-file> or +=item B<--append-textcmd=append-file> or B<-x append-file> or B<--append-textcmd="cmd1,cmd2,..."> Exclude from, replace or append to the list of regular expressions @@ -4038,7 +4080,7 @@ matching commands whose last argument is text. See entry for B<--exclude-safecmd> directly above for further details. -=item B<--replace-context1cmd=replace-file> +=item B<--replace-context1cmd=replace-file> =item B<--append-context1cmd=append-file> or @@ -4047,11 +4089,11 @@ entry for B<--exclude-safecmd> directly above for further details. Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. C<\caption> will only work within a figure -or table. These commands behave like text commands, except when +or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. -=item B<--replace-context2cmd=replace-file> +=item B<--replace-context2cmd=replace-file> =item B<--append-context2cmd=append-file> or @@ -4061,9 +4103,9 @@ As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. -context2 commands are also the only commands in the preamble, whose argument will be processed in +context2 commands are also the only commands in the preamble, whose argument will be processed in word-by-word mode (which only works, if they occur no more than once in the preamble). The algorithm currently cannot cope with repeated context2 commands in the preamble, as they occur e.g. for the C<\author> argument in some journal styles (not in the standard styles, though -If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use C<--replace-context2cmd> option to just select the commands, which should be processed and are not used repeatedly in the preamble. +If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use C<--replace-context2cmd> option to just select the commands, which should be processed and are not used repeatedly in the preamble. @@ -4072,7 +4114,7 @@ If such a repetition is detected, the whole preamble will be processed in line-b =item B<--append-mboxsafecmd=append-file> or B<--append-mboxsafecmd="cmd1,cmd2,..."> Define safe commands, which additionally need to be protected by encapsulating -in an C<\mbox{..}>. This is sometimes needed to get around incompatibilities +in an C<\mbox{..}>. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE @@ -4086,7 +4128,7 @@ in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE Set configuration variables. The option can be repeated to set different variables (as an alternative to the comma-separated list). -Available variables (see below for further explanations): +Available variables (see below for further explanations): C<ARRENV> (RegEx) @@ -4116,10 +4158,10 @@ C<SCALEDELGRAPHICS> (Float) =item B<--add-to-config varenv1=pattern1,varenv2=pattern2,...> For configuration variables, which are a regular expression (essentially those ending -in ENV, COUNTERCMD and CUSTOMDIFCMD, see list above) this option provides an alternative way to modify the configuration +in ENV, COUNTERCMD and CUSTOMDIFCMD, see list above) this option provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. C<varenv> must be one of the variables listed above that take a regular -expression as argument, and pattern is any regular expression (which might need to be +expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. C<--add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote"> @@ -4139,7 +4181,7 @@ Show values of configuration variables. Combine all --show commands. -NB For all --show commands, no C<old.tex> or C<new.tex> file needs to be specified, and no +NB For all --show commands, no C<old.tex> or C<new.tex> file needs to be specified, and no differencing takes place. =back @@ -4156,29 +4198,29 @@ might get lumpeded with preceding commands) so should only be used if the default produces erroneous results. (Default requires arguments to directly follow each other without intervening spaces). -=item B<--math-markup=level> +=item B<--math-markup=level> -Determine granularity of markup in displayed math environments: +Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): -C<off> or C<0>: suppress markup for math environments. Deleted equations will not -appear in diff file. This mode can be used if all the other modes +C<off> or C<0>: suppress markup for math environments. Deleted equations will not +appear in diff file. This mode can be used if all the other modes cause invalid latex code. C<whole> or C<1>: Differencing on the level of whole equations. Even trivial changes -to equations cause the whole equation to be marked changed. This -mode can be used if processing in coarse or fine mode results in +to equations cause the whole equation to be marked changed. This +mode can be used if processing in coarse or fine mode results in invalid latex code. C<coarse> or C<2>: Detect changes within equations marked up with a coarse -granularity; changes in equation type (e.g.displaymath to equation) +granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] C<fine> or C<3>: Detect small change in equations and mark up at fine granularity. This mode is most suitable, if only minor changes to equations are -expected, e.g. correction of typos. +expected, e.g. correction of typos. =item B<--graphics-markup=level> @@ -4190,33 +4232,33 @@ C<none>, C<off> or C<0>: no highlighting for figures C<new-only> or C<1>: surround newly added or changed figures with a blue frame [Default if graphicx package loaded] -C<both> or C<2>: highlight new figures with a blue frame and show deleted figures at reduced +C<both> or C<2>: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable SCALEDELGRAPHICS to set size of deleted figures. -Note that changes to the optional parameters will make the figure appear as changed +Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. In some circumstances "Misplaced \noalign" error can occur if there are certain types -of changes in tables. In this case please use C<--graphics-markup=none> as a -work-around. +of changes in tables. In this case please use C<--graphics-markup=none> as a +work-around. -=item B<--no-del> +=item B<--no-del> -Suppress deleted text from the diff. It is similar in effect to the BOLD style, -but the deleted text ist not just invisible in the output, it is also not included in the diff text file. -This can be more robust than just making it invisible. +Suppress deleted text from the diff. It is similar in effect to the BOLD style, +but the deleted text ist not just invisible in the output, it is also not included in the diff text file. +This can be more robust than just making it invisible. =item B<--disable-citation-markup> or B<--disable-auto-mbox> -Suppress citation markup and markup of other vulnerable commands in styles +Suppress citation markup and markup of other vulnerable commands in styles using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR) (the two options are identical and are simply aliases) =item B<--enable-citation-markup> or B<--enforce-auto-mbox> -Protect citation commands and other vulnerable commands in changed sections +Protect citation commands and other vulnerable commands in changed sections with C<\mbox> command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) @@ -4262,18 +4304,18 @@ Suppress inclusion of old and new file names as comment in output file =item B<--visible-label> -Include old and new filenames (or labels set with C<--label> option) as +Include old and new filenames (or labels set with C<--label> option) as visible output. =item B<--flatten> Replace C<\input> and C<\include> commands within body by the content of the files in their argument. If C<\includeonly> is present in the -preamble, only those files are expanded into the document. However, -no recursion is done, i.e. C<\input> and C<\include> commands within -included sections are not expanded. The included files are assumed to +preamble, only those files are expanded into the document. However, +no recursion is done, i.e. C<\input> and C<\include> commands within +included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, -respectively, making it possible to organise files into old and new directories. +respectively, making it possible to organise files into old and new directories. --flatten is applied recursively, so inputted files can contain further C<\input> statements. Also handles files included by the import package (C<\import> and C<\subimport>), and C<\subfile> command. @@ -4320,7 +4362,7 @@ Suppress generation of hyperreferences, used for minimal diffs (option --only-ch =back -=head2 Predefined styles +=head2 Predefined styles =head2 Major types @@ -4333,9 +4375,14 @@ The major type determine the markup of plain text and some selected latex comman Added text is wavy-underlined and blue, discarded text is struck out and red (Requires color and ulem packages). Overstriking does not work in displayed math equations such that deleted parts of equation are underlined, not struck out (this is a shortcoming inherent to the ulem package). +=item C<LUAUNDERLINE> + +Added text is underlined and blue, discarded text is struck out and red +(Requires lua-ul package + LuaLaTeX). + =item C<CTRADITIONAL> -Added text is blue and set in sans-serif, and a red footnote is created for each discarded +Added text is blue and set in sans-serif, and a red footnote is created for each discarded piece of text. (Requires color package) =item C<TRADITIONAL> @@ -4376,13 +4423,13 @@ Added text is set in bold face, discarded is not shown. (also see --no-del optio =item C<PDFCOMMENT> -The pdfcomment package is used to underline new text, and mark deletions with a PDF comment. Note that this markup might appear differently or not at all based on the pdf viewer used. The viewer with best support for pdf markup is probably acroread. This style is only recommended if the number of differences is small. +The pdfcomment package is used to underline new text, and mark deletions with a PDF comment. Note that this markup might appear differently or not at all based on the pdf viewer used. The viewer with best support for pdf markup is probably acroread. This style is only recommended if the number of differences is small. =back =head2 Subtypes -The subtype defines the commands that are inserted at the begin and end of added or discarded blocks, irrespectively of whether these blocks contain text or commands (Defined commands: C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>) +The subtype defines the commands that are inserted at the begin and end of added or discarded blocks, irrespectively of whether these blocks contain text or commands (Defined commands: C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>) =over 10 @@ -4400,7 +4447,7 @@ from the intended position. An alternative way of marking added passages in blue, and deleted ones in red. (It is recommeneded to use instead the main types to effect colored markup, -although in some cases coloring with dvipscol can be more complete, for example +although in some cases coloring with dvipscol can be more complete, for example with citation commands). =item C<DVIPSCOL> @@ -4415,12 +4462,12 @@ although in some cases coloring with dvipscol can be more complete). can be used to highlight only changed pages, but requires post-processing. It is recommend to not call this option manually but use C<latexdiff-vc> with C<--only-changes> option. Alternatively, use the script given within preamble of diff files made using this style. -=item C<ONLYCHANGEDPAGE> +=item C<ONLYCHANGEDPAGE> also highlights changed pages, without the need for post-processing, but might not work reliably if there is floating material (figures, tables). -=item C<LABEL> +=item C<LABEL> is similar to C<ZLABEL>, but does not need the zref package and works less reliably (deprecated). @@ -4428,7 +4475,7 @@ is similar to C<ZLABEL>, but does not need the zref package and works less relia =head2 Float Types -Some of the markup used in the main text might cause problems when used within +Some of the markup used in the main text might cause problems when used within floats (e.g. figures or tables). For this reason alternative versions of all markup commands are used within floats. The float type defines these alternative commands. @@ -4455,7 +4502,7 @@ Make no difference between the main text and floats. =item C<ARRENV> -If a match to C<ARRENV> is found within an inline math environment within a deleted or added block, then the inlined math +If a match to C<ARRENV> is found within an inline math environment within a deleted or added block, then the inlined math is surrounded by C<\mbox{>...C<}>. This is necessary as underlining does not work within inlined array environments. [ Default: C<ARRENV>=S<C<(?:array|[pbvBV]matrix)> > @@ -4475,9 +4522,9 @@ C<|subsubsection|paragraph|subparagraph)> ] This option is for advanced users and allows definition of special versions of commands, which do not work as safe commands. Commands in C<CUSTOMDIFCMD> that occur in added or deleted blocks will be given an ADD or DEL prefix. -The prefixed versions of the command must be defined in the preamble, either by putting them +The prefixed versions of the command must be defined in the preamble, either by putting them in the preamble of at least the new file, or by creating a custom preamble file (Option --preamble). -For example the command C<\blindtext> (from package blindtext) does not interact well with underlining, so that +For example the command C<\blindtext> (from package blindtext) does not interact well with underlining, so that for the standard markup type, it is not satisfactory to define it as a safe command. Instead, a customised versions without underlining can be defined in the preamble: @@ -4491,7 +4538,7 @@ and then latexdiff should be invoked with the option C<-c CUSTOMDIFCMD=blindtext =item C<FLOATENV> -Environments whose name matches the regular expression in C<FLOATENV> are +Environments whose name matches the regular expression in C<FLOATENV> are considered floats. Within these environments, the I<latexdiff> markup commands are replaced by their FL variaties. @@ -4540,17 +4587,17 @@ If C<--graphics-markup=both> is chosen, C<SCALEDELGRAPHICS> is the factor, by wh =item C<VERBATIMENV> -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: deleted content is commented out, new content is not marked up [ Default: S<C<comment> > ] =item C<VERBATIMLINEENV> -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by VERBATIMLINEENV are compared in +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by VERBATIMLINEENV are compared in line mode, and changes are marked up using the listings package. The markup style is set based on the chosen mains markup type (Option -t), or on an analysis of the preamble. -Note that "listings.sty" must be installed. If this file is not found the fallback solution is to +Note that "listings.sty" must be installed. If this file is not found the fallback solution is to treat VERBATIMLINEENV environments treated exactly the same way as VERBATIMENV environments. [ Default: S<C<(?:verbatim[*]?|lstlisting> > ] @@ -4561,30 +4608,40 @@ treat VERBATIMLINEENV environments treated exactly the same way as VERBATIMENV e =over 10 -=item Citations result in overfull boxes +=item Changed citations result in overfull boxes There is an incompatibility between the C<ulem> package, which C<latexdiff> uses for underlining and striking out in the UNDERLINE style, -the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an C<\mbox> -command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have two possibilities. +the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an C<\mbox> +command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have several possibilities. 1. Use C<CFONT> type markup (option C<-t CFONT>): If this markup is chosen, then changed citations are no longer marked up -with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the C<ulem> package will also work. +with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the C<ulem> package will also work. 2. Choose option C<--disable-citation-markup> which turns off the marking up of citations: deleted citations are no longer shown, and -added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older) - +added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older). For custom packages you can define the commands which need to be protected by C<\mbox> with C<--append-mboxsafecmd> and C<--excludemboxsafecmd> options (submit your lists of command as feature request at github page to set the default behaviour of future versions, see section 6) -=item Changes in complicated mathematical equations result in latex processing errors +3. If you are using luatex >= 1.12.0 you can use option LUAUNDERLINE that uses lua-ul instead of ulem for underlining, which does not have this problem (experimental feature). + +=item Changes in complicated mathematical equations result in latex processing errors. + +Try option C<--math-markup=whole>. If even that fails, you can turn off mark up for equations with C<--math-markup=off>. -Try options C<--math-markup=whole>. If even that fails, you can turn off mark up for equations with C<--math-markup=off>. +=item Deleted parts in equations are not struck out but underlined. -=item How can I just show the pages where changes had been made +This is a limitation of the ulem package that implements the strike-out. If you use the amsmath package, then the strike-out command is redefined in such a way that deleted passages are wrapped with C<\text> command; adding C<\usepackage{amsmath}> to your preamble will trigger this behaviour. (If amsmath is not included directly, but imported by another package, latexdiff will not be able to detect its availability; in this case you can give latexdiff a hint with option C<--packages=amsmath>. -Use options -C<-s ZLABEL> (some postprocessing required) or C<-s ONLYCHANGEDPAGE>. C<latexdiff-vc --ps|--pdf> with C<--only-changes> option takes care of + +=item How can I just show the pages where changes had been made? + +Use options C<--s ZLABEL> (some postprocessing required) or C<-s ONLYCHANGEDPAGE>. C<latexdiff-vc --ps|--pdf> with C<--only-changes> option takes care of the post-processing for you (requires zref package to be installed). +=item The character encoding breaks when running latexdiff from powershell. + +This problem is not limited to C<latexdiff> and has to do with the default settings of C<powershell> in Windows. It is recommended to use C<cmd> instead. + =back =head1 BUGS @@ -4597,13 +4654,13 @@ different numbers of inter-argument spaces are treated as significant. =back -Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, +Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, or send them to I<tilmann -- AT -- gfz-potsdam.de>. Include the version number of I<latexdiff> (from comments at the top of the source or use B<--version>). If you come across latex files that are error-free and conform to the specifications set out above, and whose differencing still does not result in error-free latex, please send me those files, ideally edited to only contain the -offending passage as long as that still reproduces the problem. If your +offending passage as long as that still reproduces the problem. If your file relies on non-standard class files, you must include those. I will not look at examples where I have trouble to latex the original files. @@ -4614,24 +4671,24 @@ L<latexrevise>, L<latexdiff-vc> =head1 PORTABILITY I<latexdiff> does not make use of external commands and thus should run -on any platform supporting Perl 5.6 or higher. If files with encodings +on any platform supporting Perl 5.6 or higher. If files with encodings other than ASCII or UTF-8 are processed, Perl 5.8 or higher is required. The standard version of I<latexdiff> requires installation of the Perl package -C<Algorithm::Diff> (available from I<www.cpan.org> - +C<Algorithm::Diff> (available from I<www.cpan.org> - I<http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15>) but a stand-alone version, I<latexdiff-so>, which has this package inlined, is available, too. I<latexdiff-fast> requires the I<diff> command to be present. =head1 AUTHOR -Version 1.3.3 -Copyright (C) 2004-2022 Frederik Tilmann +Version 1.3.4 +Copyright (C) 2004-2024 Frederik Tilmann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 -Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, +Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, T. Connors, Sebastian Gouezel and many others. Thanks to the many people who sent in bug reports, feature suggestions, and other feedback. @@ -4902,13 +4959,14 @@ value underline sqrt (SUPER|SUB)SCRIPT -%%END TEXT COMMANDS +%%END TEXT COMMANDS %%BEGIN CONTEXT1 COMMANDS % Regex matching commands with a text argument (leave out the \), which will fail out of context. These commands behave like text commands, except when they occur in a deleted section, where they are disabled, but their argument is shown as deleted text. caption subcaption -%%END CONTEXT1 COMMANDS +multicolumn +%%END CONTEXT1 COMMANDS %%BEGIN CONTEXT2 COMMANDS % Regex matching commands with a text argument (leave out the \), which will fail out of context. As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. @@ -4916,7 +4974,7 @@ title author date institute -%%END CONTEXT2 COMMANDS +%%END CONTEXT2 COMMANDS %% CONFIGURATION variabe defaults %%BEGIN LISTENV CONFIG @@ -4994,9 +5052,16 @@ verbatim[*]? \RequirePackage[normalem]{ulem} \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} \providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}} -\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} +\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} %DIF END UNDERLINE PREAMBLE +%DIF LUAUNDERLINE PREAMBLE +\RequirePackage{lua-ul} +\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} +\providecommand{\DIFadd}[1]{{\protect\color{blue}\underLine{#1}}} +\providecommand{\DIFdel}[1]{{\protect\color{red}\strikeThrough{#1}}} +%DIF END LUAUNDERLINE PREAMBLE + %DIF CTRADITIONAL PREAMBLE \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} \RequirePackage[stable]{footmisc} @@ -5168,7 +5233,7 @@ verbatim[*]? % To show only pages with changes (dvips/dvipdf) % latex diff.tex % latex diff.tex -% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi +% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi \typeout{Check comments in preamble of output for instructions how to show only pages where changes have been made} \usepackage[user,abspage]{zref} \newcount\DIFcounterb @@ -5188,10 +5253,10 @@ verbatim[*]? \RequirePackage{etoolbox} \RequirePackage{zref} % redefine label command to write immediately to aux file - page references will be lost -\makeatletter \let\oldlabel\label% Store \label -\renewcommand{\label}[1]{% Update \label to write to the .aux immediately -\zref@wrapper@immediate{\oldlabel{#1}}} -\makeatother +\makeatletter \let\oldlabel\label% Store \label +\renewcommand{\label}[1]{% Update \label to write to the .aux immediately +\zref@wrapper@immediate{\oldlabel{#1}}} +\makeatother \newbool{DIFkeeppage} \newbool{DIFchange} \boolfalse{DIFkeeppage} @@ -5209,7 +5274,7 @@ verbatim[*]? \providecommand{\DIFmodend}{\global\booltrue{DIFkeeppage}\global\boolfalse{DIFchange}} %DIF END ONLYCHANGEDPAGE PREAMBLE -%% FLOAT TYPES +%% FLOAT TYPES %DIF FLOATSAFE PREAMBLE \providecommand{\DIFaddFL}[1]{\DIFadd{#1}} @@ -5241,7 +5306,7 @@ verbatim[*]? %DIF END TRADITIONALSAFE PREAMBLE % see: -% http://tex.stackexchange.com/questions/47351/can-i-redefine-a-command-to-contain-itself +% http://tex.stackexchange.com/questions/47351/can-i-redefine-a-command-to-contain-itself %DIF HIGHLIGHTGRAPHICS PREAMBLE \RequirePackage{settobox} @@ -5287,6 +5352,15 @@ verbatim[*]? %% SPECIAL PACKAGE PREAMBLE COMMANDS +%% Redefine strike out command to wrap in text box if amsmath is used and markup style with ulem is used +%DIF AMSMATHULEM PREAMBLE +\makeatletter +\let\sout@orig\sout +\renewcommand{\sout}[1]{\ifmmode\text{\sout@orig{\ensuremath{#1}}}\else\sout@orig{#1}\fi} +\makeatother +%DIF END AMSMATHULEM PREAMBLE + + % Standard \DIFadd and \DIFdel are redefined as \DIFaddtex and \DIFdeltex % when hyperref package is included. %DIF HYPERREF PREAMBLE @@ -5389,7 +5463,7 @@ verbatim[*]? %DIF END DIFCODE_BOLD %DIF DIFCODE_PDFCOMMENT - + moredelim=[il][\color{white}\tiny]{\%DIF\ <\ }, moredelim=[il][\sffamily\bfseries]{\%DIF\ >\ } %DIF END DIFCODE_PDFCOMMENT diff --git a/support/latexdiff/latexdiff-fast b/support/latexdiff/latexdiff-fast index ff9a732bac..44d6005845 100755 --- a/support/latexdiff/latexdiff-fast +++ b/support/latexdiff/latexdiff-fast @@ -25,6 +25,21 @@ # # Note references to issue numbers are for the github repository of latexdiff: https://github.com/ftilmann/latexdiff # +# Version 1.3.4: +# New features: +# - Option to use lua-ul instead of ulem (for use with LuaLaTeX) (fix #17, #60, #188, #255, #270) +# Enhancement +# - If amsmath is detected as one of the included (based on idea in PR #263 contributed by github user xlucn +# Bug fix +# - sometimes the introduction of aux commands to show deleted lists or descriptions leaves in place empty auxiliary +# list environments, which would cause error messages (though skipping messages would result in a correct output pdf). +# These are now removed. +# - add more mboxsafecmd and safecmd commands for SIunitx to stay compatible with newer versionsof SIunitx (PR #283, fixing issue #282, contributed by github user joe6302413) +# - File added via --preamble option is no longer assumed to be ASCII, but read either with encoding as defined by --encoding option or using the encoding of the LOCALE (fixes issue #285 ) +# - multicolumn argument is now treated as text +# - when tikz-dependency package is used, \& is no longer a safe command as it has special meaning inside dependency environment. The fix is a little of a hack as really it should only be considered unsafe within dependency environment (fixes (mostly) issue #303 ) +# - listings package had trouble with non-ASCII chars. The encoding is now set (thanks to github user anka-213 for finding this). Fixes #304 +# # Version 1.3.3: # New features: # - Option --no-del to remove all deleted text (merge contributed by github user tdegeus PR #252, fixing issue #66 @@ -33,22 +48,22 @@ # - Abbreviations involving punctuations within them. They need special treatment because otherwise in some # circumstances the gnoring of white space differences in conjunction with merging according to MINWORDSBLOCK rule # could turn 'i.e.' into 'i.\PAR e.' (see https://github.com/ftilmann/latexdiff/issues/269). A few abbreviations -# are now hard-coded and treated as atomic: +# are now hard-coded and treated as atomic: # English: i.e., e.g. Deutsch: z.B. # (fixes issue #269) # - In WHOLE and COARSE math modes, now properly treat math environments with arguments such as \alignat. Fixes #251 -# - For FINE math mode, multiple improvments to the processing work flow yield more robust outcomes. In particular, changes -# to the equation type, e.g. \begin{displaymath} -> \begin{equation} without modifications now usually no longer result -# in errors. (Partially) fixes issues #235 and #244. -# - When encountering deleted math array environments such as align or eqnarray, rather than replacing them with a -# fixed replacement environment (e.g. align* or eqnarray*), an asterisk is now added to the original command, which +# - For FINE math mode, multiple improvments to the processing work flow yield more robust outcomes. In particular, changes +# to the equation type, e.g. \begin{displaymath} -> \begin{equation} without modifications now usually no longer result +# in errors. (Partially) fixes issues #235 and #244. +# - When encountering deleted math array environments such as align or eqnarray, rather than replacing them with a +# fixed replacement environment (e.g. align* or eqnarray*), an asterisk is now added to the original command, which # in amsmath (and with eqnarray) will result in the same environment but without line numbers. Config variable MATHARRREPL # is therefore (nearly) redundant, and a depracation warning is given when it is set. Reference to MATHARRREPL are have # been removed from the manual (there is one exception, when it's still being used: sometimes latexdiff can figure out # that there is a deleted array environment, but does not know which one. In this case, MATHARRREPL is still being used -# to encapsulate these parts of the source, and therefore it is still set internally. But this is a quite rare situation). +# to encapsulate these parts of the source, and therefore it is still set internally. But this is a quite rare situation). # Fixes issue #216 -# - Unlike 'array' environment, 'split' (amsmath) does not work in argument of \DIFadd or \DIFdl in UNDERLINE modes; therefore remove it from ARRENV configuration variable. +# - Unlike 'array' environment, 'split' (amsmath) does not work in argument of \DIFadd or \DIFdl in UNDERLINE modes; therefore remove it from ARRENV configuration variable. # Exclude \begin and \end in math environments in COARSE and WHOLE modes. Fixes #258. Fixes #109 # - --flatten now works for empty files. Fixes issue #242 # - improved processing of Chinese and Japanese texts in that splitting is done based on characters. Thanks to LuXu (Oliver Lew) in git for working this out. Fixes #229, fixes #145 @@ -65,7 +80,7 @@ # Bug fixes: # - fix issue #206 affecting proper markup of text commands which are not also safe cmd's and have multiple arguments # - fix issue #210 by adding \eqref (amsmath package) to the list of safe commands -# - fix bug reported in issue #168 mangled verbatim line environment +# - fix bug reported in issue #168 mangled verbatim line environment # - fix bug reported in issue #218 by replacing \hspace{0pt} after \mbox{..} auxiliary commands with \hskip0pt. # - more ways to process \frac correctly with atomic arguments (committed by julianuu PR #246 # - fix a bug in biblatex mode, which prevented proper processing of modified \textcite (see: https://tex.stackexchange.com/questions/555157/latexdiff-and-biblatex-citation-commands) @@ -74,10 +89,10 @@ # Version 1.3.1.1 # - remove spurious \n to fix error: Unknown regexp modifier "/n" at .../latexdiff line 1974, near "=~ " (see github issue #201) # -# Version 1.3.1 +# Version 1.3.1 # Bug fixes: # - remove some uninitialised variable $2 warnings in string substitution in flatten function in case included file is not found -# - add minimal postprocessing to diff processing of preamble commands (replace \RIGHTBRACE by \} ) +# - add minimal postprocessing to diff processing of preamble commands (replace \RIGHTBRACE by \} ) # - pre-processing: replace (contributed) routine take_comments_and_enter_from_frac() with take_comments_and_newline_from_frac(), which does the same thing # (remove whitespace characters and comments between the argument of \frac commands) in an easier and more robust way. In addition, it # will replace commands like \frac12 with \frac{1}{2} as pre-processing step. Fixes issue #184 @@ -95,15 +110,15 @@ # Version 1.3.0 (7 October 2018): # - treat options to \documentclass as potential package names (some packages allow implicit loading of or imply selected packages # - improved pattern matching: now allows nested angular brackets, and is no longer confused by escaped curly braces -# - improved pattern matching in COARSE mode: occasionally, the closing bracket or some other elements would be matched in an 'unnatural' way due to another sequence being more minimal in the computational sense, sometimes even causing errors due to tokens moving in or out of the scope of math environments. This is now discouraged by adding internal \DIFANCHOR commands (which are removed again in post-processing) (fixes issues reported via email by li_ruomeng . +# - improved pattern matching in COARSE mode: occasionally, the closing bracket or some other elements would be matched in an 'unnatural' way due to another sequence being more minimal in the computational sense, sometimes even causing errors due to tokens moving in or out of the scope of math environments. This is now discouraged by adding internal \DIFANCHOR commands (which are removed again in post-processing) (fixes issues reported via email by li_ruomeng . # - verbatim and lstlisting environments are marked-up with line-by-line in a similar style to non-verbatim text (requires the listing package to be installed) # (see new configuration variable VERBATIMLINEENV) (several issues and pull requests by jprotze) -# - --flatten: now supports \verbatiminput and \lstlistinput +# - --flatten: now supports \verbatiminput and \lstlistinput # - --flatten: if file is not found, do not fail, simply warn and leave command unexpanded (inspired by issue #112). Don't warn if file name contains #[0-9] as it is then most likely an argument within a command definition rather than an actual file (applies to \input, \subfile, \include commands) # - added to textcmds: \intertext # - new config variable CUSTOMDIFCMD to allow defining special versions of commands in added or deleted blocks (Pull request by github user jprotze) # - added option -no-links (mostly for use by latexdiff-vc in only-changes modes) (Pull request by github user jprotze) -# - new option --filter-script to run both input through a pre-processing script (PR jasonmccsmith #167) +# - new option --filter-script to run both input through a pre-processing script (PR jasonmccsmith #167) # new option --no-filter-stderr to hide stderr output from filter-script (potentially dangerous, as this might hide malfunctioning of filter scripts) # - --flatten now can deal with imports made using the import package {PR jasonmccsmith #173) # Bug fixes: @@ -122,12 +137,12 @@ # make environments that are treated like verbatim environments configurable (config variable VERBATIMENV) # treat lstinlne as equivalent to verb command # partially addresses issue #38 -# - refactoring: set default configuration variables in a hash, and those that correspond to lists +# - refactoring: set default configuration variables in a hash, and those that correspond to lists # - feature: option --add-to-config used to amend configuration variables, which are regex pattern lists # - bug fix: deleted figures when endfloat package is activated # - bug fix: alignat environment now always processed correctly (fix issues #65) # - bug fix: avoid processing of commands as potential files in routine init_regex_arr (fix issue #70 ) -# - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be +# - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be # @ a letter if it is part of a command name will usually lead to the correct behaviour (see http://tex.stackexchange.com/questions/346651/latexdiff-and-let) # - new feature/bug fix: --flatten option \endinput in included files now respected but only if \endinput stands right at the beginning of the line (issue #77) # - bug fix: flatten would incorrectly attempt to process commented out \include commands (from discussion in issue #77 ) @@ -165,7 +180,7 @@ # - introduce list UNSAFEMATHCMD, which holds list of commands which cannot be marked up with \DIFadd or \DIFdel commands (only relevant for WHOLE and COARSE math markup modes) # - new subtype LABEL which gives each change a label. This can later be used to only display pages where changes # have been made (instructions for that are put as comments into the diff'ed file) inspired by answer on http://tex.stackexchange.com/questions/166049/invisible-markers-in-pdfs-using-pdflatex -# - Configuration variables take into accout some commands from additional packages: +# - Configuration variables take into accout some commands from additional packages: # tikzpicture environment now treated as PICTUREENV, and \smallmatrix in ARRENV (amsmath) # - --flatten: support for \subfile command (subfiles package) (in response to http://tex.stackexchange.com/questions/167620/latexdiff-with-subfiles ) # - --flatten: \bibliography commands expand if corresponding bbl file present @@ -179,11 +194,11 @@ # - \% in one-letter sub/Superscripts was not converted correctly # # Version 1.0.3 -# - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator +# - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator # command in preamble # - \(..\) inline math expressions were not parsed correctly, if they contained a linebreak # - applied patch contributed by tomflannaghan via Berlios: [ Patch #3431 ] Adds correct handling of \left< and \right> -# - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug +# - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug # and sketching out the solution) # - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript # (thanks to Wail Yahyaoui for pointing out this bug) @@ -191,19 +206,19 @@ # Version 1.0.1 - treat \big,\bigg etc. equivalently to \left and # \right - include starred version in MATHENV - apply # - flatten recursively and --flatten expansion is now -# aware of comments (thanks to Tim Connors for patch) +# aware of comments (thanks to Tim Connors for patch) # - Change to post-processing for more reliability for # deleted math environments -# - On linux systems, recognise and remove DOS style newlines +# - On linux systems, recognise and remove DOS style newlines # - Provide markup for some special preamble commands (\title, -# \author,\date, -# - configurable by setting context2cmd +# \author,\date, +# - configurable by setting context2cmd # - for styles using ulem package, remove \emph and \text.. from list of # safe commands in order to allow linebreaks within the -# highlighted sections. -# - for ulem style, now show citations by enclosing them in \mbox commands. -# This unfortunately implies linebreaks within citations no longer function, -# so this functionality can be turned off (Option --disable-citation-markup). +# highlighted sections. +# - for ulem style, now show citations by enclosing them in \mbox commands. +# This unfortunately implies linebreaks within citations no longer function, +# so this functionality can be turned off (Option --disable-citation-markup). # With --enable-citation-markup, the mbox markup is forced for other styles) # - new substyle COLOR. This is particularly useful for marking up citations # and some special post-processing is implemented to retain cite @@ -211,11 +226,11 @@ # - four different levels of math-markup # - Option --driver for choosing driver for modes employing changebar package # - accept \\* as valid command (and other commands of form \.*). Also accept -# \<nl> (backslashed newline) +# \<nl> (backslashed newline) # - some typo fixes, include commands defined in preamble as safe commands -# (Sebastian Gouezel) +# (Sebastian Gouezel) # - include compared filenames as comments as line 2 and 3 of -# the preamble (can be modified with option --label, and suppressed with +# the preamble (can be modified with option --label, and suppressed with # --no-label), option --visible-label to show files in generated pdf or dvi # at the beginning of main document # @@ -231,7 +246,7 @@ # # Version 0.4 March 06 option for fast differencing using UNIX diff command, several minor bug fixes (\par bug, improved highlighting of textcmds) # -# Version 0.3 August 05 improved parsing of displayed math, --allow-spaces +# Version 0.3 August 05 improved parsing of displayed math, --allow-spaces # option, several minor bug fixes # # Version 0.25 October 04 Fix bug with deleted equations, add math mode commands to safecmd, add | to allowed interpunctuation signs @@ -808,12 +823,13 @@ use utf8 ; use File::Spec ; + my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION); my ($versionstring)=<<EOF ; -This is LATEXDIFF 1.3.3 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) - (c) 2004-2022 F J Tilmann +This is LATEXDIFF 1.3.4 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) + (c) 2004-2024 F J Tilmann EOF # Hash with defaults for configuration variables. These marked undef have default values constructed from list defined in the DATA block @@ -904,9 +920,9 @@ my $DELCMDOPEN='%DIFDELCMD < '; # To mark begin of deleted commands (must begin my $DELCMDCLOSE="%%%\n"; # To mark end of deleted commands (must end with a new line) my $AUXCMD='%DIFAUXCMD' ; # follows auxiliary commands put in by latexdiff to make difference file legal # auxiliary commands must be on a line of their own - # Note that for verbatim environment openings the %DIFAUXCMD cannot be placed in + # Note that for verbatim environment openings the %DIFAUXCMD cannot be placed in # the same line as this would mean they are shown - # so the special form "%DIFAUXCMD NEXT" is used to indicate that the next line + # so the special form "%DIFAUXCMD NEXT" is used to indicate that the next line # is an auxiliary command # Similarly "%DIFAUXCMD LAST" would indicate the auxiliary command is in previous line (not currently used) my $DELCOMMENT='DIF < '; # To mark deleted comment line @@ -917,21 +933,21 @@ my @TEXTCMDLIST=(); # array containing patterns of commands with text arguments my @TEXTCMDEXCL=(); # array containing patterns of commands without text arguments (if a pattern # matches both TEXTCMDLIST and TEXTCMDEXCL it is excluded) my @CONTEXT1CMDLIST=(); # array containing patterns of commands with text arguments (subset of text commands), - # but which cause confusion if used out of context (e.g. \caption). + # but which cause confusion if used out of context (e.g. \caption). # In deleted passages, the command will be disabled but its argument is marked up - # Otherwise they behave exactly like TEXTCMD's + # Otherwise they behave exactly like TEXTCMD's my @CONTEXT1CMDEXCL=(); # exclude list for above, but always empty my @CONTEXT2CMDLIST=(); # array containing patterns of commands with text arguments, but which fail or cause confusion # if used out of context (e.g. \title). They and their arguments will be disabled in deleted # passages my @CONTEXT2CMDEXCL=(); # exclude list for above, but always empty my @MATHTEXTCMDLIST=(); # treat like textcmd. If a textcmd is in deleted or added block, just wrap the - # whole content with \DIFadd or \DIFdel irrespective of content. This functionality + # whole content with \DIFadd or \DIFdel irrespective of content. This functionality # is useful for pseudo commands \MATHBLOCK.. into which math environments are being - # transformed -my @MATHTEXTCMDEXCL=(); # + # transformed +my @MATHTEXTCMDEXCL=(); # -# Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these +# Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these our @SAFECMDLIST=(); # array containing patterns of safe commands (which do not break when in the argument of DIFadd or DIFDEL) our @SAFECMDEXCL=(); my @MBOXCMDLIST=(); # patterns for commands which are in principle safe but which need to be surrounded by an \mbox @@ -996,7 +1012,7 @@ $mathmarkup=COARSE; $verbose=0; $onlyadditions=0; # output debug and intermediate files, set to 0 in final distribution -$debug=0; +$debug=0; # insert preamble directly after documentclass - experimental feature, set to 0 in final distribution # Note that this failed with mini example (or other files, where packages used in latexdiff preamble # are called again with incompatible options in preamble of resulting file) @@ -1019,9 +1035,9 @@ END my %verbhash; Getopt::Long::Configure('bundling'); -GetOptions('type|t=s' => \$type, - 'subtype|s=s' => \$subtype, - 'floattype|f=s' => \$floattype, +GetOptions('type|t=s' => \$type, + 'subtype|s=s' => \$subtype, + 'floattype|f=s' => \$floattype, 'config|c=s' => \@configlist, 'add-to-config=s' => \@addtoconfiglist, 'preamble|p=s' => \$preamblefile, @@ -1070,11 +1086,11 @@ if ( $help ) { if ( $version ) { - print STDERR $versionstring ; + print STDERR $versionstring ; exit 0; } -print STDERR $versionstring if $verbose; +print STDERR $versionstring if $verbose; if (defined($showall)){ $showpreamble=$showsafe=$showtext=$showconfig=1; @@ -1092,7 +1108,7 @@ if (defined($mathmarkup)) { $mathmarkup=~tr/a-z/A-Z/; if ( $mathmarkup eq 'OFF' ){ $mathmarkup=OFF; - } elsif ( $mathmarkup eq 'WHOLE' ){ + } elsif ( $mathmarkup eq 'WHOLE' ){ $mathmarkup=WHOLE; } elsif ( $mathmarkup eq 'COARSE' ){ $mathmarkup=COARSE; @@ -1195,7 +1211,7 @@ foreach $config ( @configlist ) { } } foreach $assign ( @config ) { - $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; + $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}=$2; } @@ -1232,7 +1248,7 @@ foreach $key ( keys(%CONFIG) ) { foreach $assign ( @addtoconfig ) { ###print STDERR "assign:|$assign|\n"; - $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; + $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}.=";$2"; } @@ -1247,8 +1263,8 @@ foreach ( keys(%CONFIG) ) { elsif ( $_ eq "MATHENV" ) { $MATHENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "MATHREPL" ) { $MATHREPL = $CONFIG{$_} ; } elsif ( $_ eq "MATHARRENV" ) { $MATHARRENV = liststringtoregex($CONFIG{$_}) ; } - elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; - print STDERR "WARNING: Setting MATHARRREPL is depracated. Generally deleted math array environments will be set to their starred varieties and the setting of MATHARREPL is ignored.\n\n" unless $MATHARRREPL =~ /eqnarray\*/ ; + elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; + print STDERR "WARNING: Setting MATHARRREPL is depracated. Generally deleted math array environments will be set to their starred varieties and the setting of MATHARREPL is ignored.\n\n" unless $MATHARRREPL =~ /eqnarray\*/ ; } elsif ( $_ eq "ARRENV" ) { $ARRENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "VERBATIMENV" ) { $VERBATIMENV = liststringtoregex($CONFIG{$_}) ; } @@ -1275,11 +1291,11 @@ foreach $pkg ( @packagelist ) { if ($showconfig || $showtext || $showsafe || $showpreamble) { show_configuration(); - exit 0; + exit 0; } -if ( @ARGV != 2 ) { +if ( @ARGV != 2 ) { print STDERR "2 and only 2 non-option arguments required. Write latexdiff -h to get help\n"; exit(2); } @@ -1287,7 +1303,7 @@ if ( @ARGV != 2 ) { # Are extra spaces between command arguments permissible? my $extraspace; if ($allowspaces) { - $extraspace='\s*'; + $extraspace='\s*'; } else { $extraspace=''; } @@ -1310,14 +1326,14 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # if you get "undefined control sequence MATHBLOCKmath" error, increase the maximum value in this loop for (my $i_pat = 0; $i_pat < 20; ++$i_pat){ $pat_n = '(?:[^{}]|\{'.$pat_n.'\}|\\\\\{|\\\\\})*'; - # Actually within the text body, quoted braces are replaced in pre-processing. The only place where + # Actually within the text body, quoted braces are replaced in pre-processing. The only place where # the last part of the pattern matters is when processing the arguments of context2cmds in the preamble # and these contain a \{ or \} combination, probably rare. # It should thus be fine to use the simpler version below. ### $pat_n = '(?:[^{}]|\{'.$pat_n.'\})*'; } - my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; + my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; my $brat_n = $brat0; for (my $i_pat = 0; $i_pat < 4; ++$i_pat){ $brat_n = '(?:[^\[\]]|\['.$brat_n.'\]|\\\[|\\\])*'; @@ -1334,7 +1350,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # could turn 'i.e.' into 'i.\PAR e.' (see https://github.com/ftilmann/latexdiff/issues/269) # English: i.e., e.g. Deutsch: z.B. my $abbreviation='(?:i\. ?e\.|e\. ?g\.|z\. ?B\.)' ; - my $number='-?\d*\.\d*'; + my $number='-?\d*\.\d*'; # word: sequence of letters or accents followed by letter my $word_cj='\p{Han}|\p{InHiragana}|\p{InKatakana}'; @@ -1362,7 +1378,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # inline math $....$ or \(..\) ### the commented out version is simpler but for some reason cannot cope with newline (in spite of s option) - need to include \newline explicitly ### my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(].*?\\\\[)]'; - my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; + my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; ### test version (this seems to give the same results as version above) ## the current maths command cannot cope with newline within the math expression ### my $math='\$(?:[^$]|\\\$)*?\$|\\[(].*?\\[)]'; @@ -1380,7 +1396,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); -# now we are done setting up and can start working +# now we are done setting up and can start working my ($oldfile, $newfile) = @ARGV; # check for existence of input files if ( ! -e $oldfile ) { @@ -1408,7 +1424,7 @@ my ($oldtime,$newtime,$oldlabel,$newlabel); if (defined($labels[0])) { $oldlabel=$labels[0] ; } else { - $oldtime=localtime((stat($oldfile))[9]); + $oldtime=localtime((stat($oldfile))[9]); $oldlabel="$oldfile " . " "x($oldlabel_n_spaces) . $oldtime; } if (defined($labels[1])) { @@ -1421,6 +1437,7 @@ if (defined($labels[1])) { $encoding=guess_encoding($newfile) unless defined($encoding); $encoding = "utf8" if $encoding =~ m/^utf8/i ; +print STDERR "Encoding $encoding\n" if $verbose; if (lc($encoding) eq "utf8" ) { binmode(STDOUT, ":utf8"); binmode(STDERR, ":utf8"); @@ -1504,7 +1521,7 @@ my @auxlines; my ($ulem)=0; if ( length $oldpreamble && length $newpreamble ) { - # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) + # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) # and marking up content with latexdiff markup @auxlines=preprocess_preamble($oldpreamble,$newpreamble); @@ -1536,7 +1553,7 @@ if (defined($graphicsmarkup)) { } else { # Default: no explicit setting in menu if ( defined $packages{"graphicx"} or defined $packages{"graphics"} ) { - $graphicsmarkup=NEWONLY; + $graphicsmarkup=NEWONLY; } else { $graphicsmarkup=NONE; } @@ -1569,7 +1586,7 @@ if ($graphicsmarkup != NONE ) { @matches=( $latexdiffpreamble =~ m/command\{\\DIFaddbeginFL}\{($pat_n)}/sg ) ; # we look at the last one of the list to take into account possible redefinition but almost always matches should have exactly one element if ( $matches[$#matches] =~ m/\\DIFaddbegin/ ) { - die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style."; + die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style."; exit 10; } ###} @@ -1583,6 +1600,11 @@ if ($graphicsmarkup != NONE ) { $ulem = ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{ulem\}/ || defined $packages{"ulem"}); +# If amsmath is defined and $ulem is used for markup, redefine the \sout command to also work (mostly) in math mode +# See stack exchange https://tex.stackexchange.com/questions/20609/strikeout-in-math-mode/308647#308647 based on comment by Taylor Raine +if ( defined($packages{'amsmath'}) and $ulem ) { + $latexdiffpreamble .= join "\n",(extrapream('AMSMATHULEM'),""); +} # If listings is being used or can be found in the latexdiff search path, add to the preamble auxiliary code to enable line-by-line markup if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { @@ -1592,7 +1614,7 @@ if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { } my @listingDIFcode=(); my $replaced; - # note that in case user supplies preamblefile the type might not reflect well the + # note that in case user supplies preamblefile the type might not reflect well the actual markup style @listingDIFcode=extrapream("-nofail","DIFCODE_" . $type) unless defined($preamblefile); if (!(@listingDIFcode)) { # if listingDIFcode is empty try to guess a suitable one from the preamble @@ -1606,13 +1628,17 @@ if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { @listingDIFcode=extrapream("DIFCODE_BOLD"); } } - # now splice it in + # add configuration so that listings work with utf-8 + push @listingpreamble, '\lstset{extendedchars=\true,inputencoding='.$encoding."}\n"; + + + # now splice it in $replaced=0; ###print STDERR "DEBUG: listingDIFcode: ",join("\n",@listingDIFcode),"|||\n" if $debug; - @listingpreamble=grep { + @listingpreamble=grep { # only replace if this has not been done already (use short-circuit property of and) - if (!$replaced and $_ =~ s/^.*%DIFCODE TEMPLATE.*$/join("\n",@listingDIFcode)/e ) { + if (!$replaced and $_ =~ s/^.*%DIFCODE TEMPLATE.*$/join("\n",@listingDIFcode)/e ) { ###print STDERR "DEBUG: Replaced text $_\n" if $debug; $replaced=1; 1; @@ -1642,7 +1668,7 @@ if ( length $oldpreamble && length $newpreamble ) { unshift @oldpreamble,''; @diffpreamble = linediff(\@oldpreamble, \@newpreamble); # remove dummy line again - shift @diffpreamble; + shift @diffpreamble; # add filenames, modification time and latexdiff mark defined($nolabel) or splice @diffpreamble,1,0, "%DIF LATEXDIFF DIFFERENCE FILE", @@ -1691,8 +1717,8 @@ if (defined $packages{"siunitx"} ) { # protect SI command by surrounding them with an \mbox # this is done to get around an incompatibility between the ulem and siunitx package print STDERR "siunitx package detected.\n" if $verbose ; - my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange'; - init_regex_arr_list(\@SAFECMDLIST,'num,si'); + my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange,qty,qtylist,qtyproduct,qtyrange,complexqty'; + init_regex_arr_list(\@SAFECMDLIST,'num,si,numproduct,unit,complexnum'); if ( $enablecitmark || ( $ulem && ! $disablecitmark )) { init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds); } else { @@ -1714,7 +1740,7 @@ if (defined $packages{"cleveref"} ) { if (defined $packages{"glossaries"} ) { # protect selected command by surrounding them with an \mbox - # this is done to get around an incompatibility between ulem and glossaries package + # this is done to get around an incompatibility between ulem and glossaries package print STDERR "glossaries package detected.\n" if $verbose ; my $mboxcmds='[gG][lL][sS](?:|pl|disp|link|first|firstplural|desc|user[iv][iv]?[iv]?),[aA][cC][rR](?:long|longpl|full|fullpl),[aA][cC][lfp]?[lfp]?'; init_regex_arr_list(\@SAFECMDLIST,'[gG][lL][sS](?:(?:entry)?(?:text|plural|name|symbol)|displaynumberlist|entryfirst|entryfirstplural|entrydesc|entrydescplural|entrysymbolplural|entryuser[iv][iv]?[iv]?|entrynumberlist|entrydisplaynumberlist|entrylong|entrylongpl|entryshort|entryshortpl|entryfull|entryfullpl),[gG]lossentry(?:name|desc|symbol),[aA][cC][rR](?:short|shortpl),[aA]csp?'); @@ -1743,6 +1769,10 @@ if (defined $packages{"mhchem"} ) { # push(@MATHTEXTCMDLIST,'cee'); } +if ( defined $packages{"tikz-dependency"} ) { + init_regex_arr_ext(\@SAFECMDEXCL, 'AMPERSAND'); +} + my ( $citpat); @@ -1830,7 +1860,7 @@ print STDERR "(",exetime()," s)\n","Done.\n" if $verbose; # liststringtoregex(liststring) -# expands string with semi-colon separated list into a regular expression corresponding +# expands string with semi-colon separated list into a regular expression corresponding # matching any of the elements sub liststringtoregex { my ($liststring)=@_; @@ -1843,7 +1873,7 @@ sub liststringtoregex { } # show_configuration -# note that this is not encapsulated but uses variables from the main program +# note that this is not encapsulated but uses variables from the main program # It is provided for convenience because in the future it is planned to allow output # to be modified based on what packages are read etc - this works only if the input files are actually read # whether or not additional files are provided @@ -1870,7 +1900,7 @@ sub show_configuration { print "\nContext1 commands (last argument textual, command will be disabled in deleted passages, last argument will be shown as plain text):\n"; print_regex_arr(@CONTEXT1CMDLIST); print "\nContext2 commands (last argument textual, command and its argument will be disabled in deleted passages):\n"; - print_regex_arr(@CONTEXT2CMDLIST); + print_regex_arr(@CONTEXT2CMDLIST); print "\nExclude list of Commands with last argument not textual (overrides patterns above):\n"; print_regex_arr(@TEXTCMDEXCL); } @@ -1978,7 +2008,7 @@ sub list_packages { my %packages=(); my $pkg; - # remove comments + # remove comments $preamble=~s/(?<!\\)%.*$//mg ; while ( $preamble =~ m/\\(?:documentclass|usepackage|RequirePackage)(?:\[($brat_n)\])?\{(.*?)\}/gs ) { @@ -2083,7 +2113,7 @@ sub flatten { my ($includeonly,$dirname,$fname,$newpage,$fullfile,$filecontent,$replacement,$begline,$inputcmd,$bblfile,$subfile,$command,$verbenv,$verboptions,$ignore,$fileonly); my ($subpreamble,$subbody,$subpost); my ($subdir,$subdirfull,$importfilepath); - require File::Basename ; + require File::Basename ; ### require File::Spec ; # now this is needed even if flatten option not given $filename = File::Spec->rel2abs( $filename ) ; ($ignore, $dirname, $fileonly) = File::Spec->splitpath($filename) ; @@ -2123,15 +2153,15 @@ sub flatten { $subdirfull = (defined($3) ? File::Spec->catdir($dirname,$subdir) : $subdir); $importfilepath = File::Spec->catfile($subdirfull, $fname); - + print STDERR "importing importfilepath:", $importfilepath,"\n" if $verbose; if ( -f $importfilepath ) { # If file exists, replace input or include command with expanded input #TODO: need remove_endinput & newpage similar to other replacements inside flatten - $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding); + $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding); } else { # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition - # and is not meant to be expanded directly + # and is not meant to be expanded directly print STDERR "WARNING: Could not find included file ",$importfilepath,". I will continue but not expand |$2|\n"; $replacement = $2; $replacement .= "{$subdir}{$fname} % Processed"; @@ -2140,13 +2170,13 @@ sub flatten { }/exgm; # recursively replace \\input and \\include files - $text =~ s/(^(?:[^%\n]|\\%)*)(\\input\{(.*?)\}|\\include\{(${includeonly}(?:\.tex)?)\})/{ + $text =~ s/(^(?:[^%\n]|\\%)*)(\\input\{(.*?)\}|\\include\{(${includeonly}(?:\.tex)?)\})/{ $begline=(defined($1)? $1 : "") ; $inputcmd=$2; $fname = $3 if defined($3) ; $fname = $4 if defined($4) ; $newpage=(defined($4)? " \\newpage " : "") ; - # # add tex extension unless there is a three or four letter extension already + # # add tex extension unless there is a three or four letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3,4}$|; $fullfile = File::Spec->catfile($dirname,$fname); print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ; @@ -2155,12 +2185,12 @@ sub flatten { # content of file becomes replacement value (use recursion), add \newpage if the command was include if ( -f $fullfile ) { # If file exists, replace input or include command with expanded input - $replacement=flatten(read_file_with_encoding($fullfile, $encoding), $preamble,$filename,$encoding); - $replacement = remove_endinput($replacement); + $replacement=flatten(read_file_with_encoding($fullfile, $encoding), $preamble,$filename,$encoding); + $replacement = remove_endinput($replacement); # \include always starts a new page; use explicit \newpage command to simulate this } else { # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition - # and is not meant to be expanded directly + # and is not meant to be expanded directly print STDERR "WARNING: Could not find included file ",$fullfile,". I will continue but not expand |$inputcmd|\n" unless $fname =~ m(#[0-9]) ; $replacement = $inputcmd ; # i.e. just the original command again -> make no change file does not exist $newpage=""; @@ -2169,7 +2199,7 @@ sub flatten { }/exgm; # replace bibliography with bbl file if it exists - $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{ if ( -f $bblfile ){ $replacement=read_file_with_encoding(File::Spec->catfile($bblfile), $encoding); } else { @@ -2181,10 +2211,10 @@ sub flatten { }/exgm; # replace subfile with contents (subfile package) - $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{ $begline=(defined($1)? $1 : "") ; - $fname = $2; - # # add tex extension unless there is a three or four letter extension already + $fname = $2; + # # add tex extension unless there is a three or four letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3,4}|; print STDERR "Include file as subfile $fname\n" if $verbose; # content of file becomes replacement value (use recursion) @@ -2195,10 +2225,10 @@ sub flatten { # if file exists, expand \subfile command by contents of file $subfile=read_file_with_encoding($fullfile,$encoding) or die "Could not open included subfile ",$fullfile,": $!"; ($subpreamble,$subbody,$subpost)=splitdoc($subfile,'\\\\begin\{document\}','\\\\end\{document\}'); - ### $subfile=~s|^.*\\begin{document}||s; + ### $subfile=~s|^.*\\begin{document}||s; ### $subfile=~s|\\end{document}.*$||s; $replacement=flatten($subbody, $preamble,$fullfile,$encoding); - ### $replacement = remove_endinput($replacement); + ### $replacement = remove_endinput($replacement); } else { # if file does not exist, do not expand subfile print STDERR "WARNING: Could not find subfile ",$fullfile,". I will continue but not expand |$2|\n" unless $fname =~ m(#[0-9]) ; @@ -2209,11 +2239,11 @@ sub flatten { }/exgm; # replace \verbatiminput and \lstlistinginput - $text=~s/(^(?:[^%\n]|\\%)*)\\(verbatiminput\*?|lstinputlisting)$extraspace(\[$brat_n\])?$extraspace\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\(verbatiminput\*?|lstinputlisting)$extraspace(\[$brat_n\])?$extraspace\{(.*?)\}/{ $begline=(defined($1)? $1 : "") ; $command = $2 ; $fname = $4 ; - $verboptions = defined($3)? $3 : "" ; + $verboptions = defined($3)? $3 : "" ; if ($command eq 'verbatiminput' ) { $verbenv = "verbatim" ; } elsif ($command eq 'verbatiminput*' ) { @@ -2222,7 +2252,7 @@ sub flatten { $verbenv = "lstlisting" ; } else { die "Internal errorL Unexpected verbatim input type $command.\n"; - } + } print STDERR "DEBUG Beg of line match |$begline|\n" if $debug ; print STDERR "Include file $fname verbatim\n" if $verbose; print STDERR "DEBUG looking for file ",File::Spec->catfile($dirname,$fname), "\n" if $debug; @@ -2254,8 +2284,8 @@ sub print_regex_arr { # if $type is a filename, it will read the file instead of reading from the appendix # otherwise it will screen appendix for line "%DIF $TYPE" and copy everything up to line # '%DIF END $TYPE' (where $TYPE is upcased version of $type) -# extrapream('-nofail',$type) will---instead of failing---simply return nothing if -# it does not find the matching line in a appendix (do not use -nofail option with multiple types!) +# extrapream('-nofail',$type) will---instead of failing---simply return nothing if +# it does not find the matching line in appendix (do not use -nofail option with multiple types!) sub extrapream { my @types=@_; my ($type,$arg); @@ -2272,14 +2302,20 @@ sub extrapream { $type=$arg; $copy=0; if ( -f $type || lc $type eq '/dev/null' ) { - open (FILE,$type) or die "Cannot open preamble file $type: $!"; print STDERR "Reading preamble file $type\n" if $verbose ; + open (FILE,$type) or die "Cannot open preamble file $type: $!"; + if (defined($encoding)) { + binmode(FILE,":encoding($encoding)"); + } else { + require Encode::Locale; + binmode(FILE,":encoding(locale)"); + } while (<FILE>) { chomp ; if ( $_ =~ m/%DIF PREAMBLE/ ) { - push (@retval,"$_"); + push (@retval,"$_"); } else { - push (@retval,"$_ %DIF PREAMBLE"); + push (@retval,"$_ %DIF PREAMBLE"); } } } else { # not (-f $type) @@ -2291,9 +2327,9 @@ sub extrapream { my $data_start = tell DATA; while (<DATA>) { if ( m/^%DIF $type/ ) { - $copy=1; + $copy=1; } elsif ( m/^%DIF END $type/ ) { - last; + last; } chomp; push (@retval,"$_ %DIF PREAMBLE") if $copy; @@ -2333,7 +2369,7 @@ sub splitdoc { $pos=pos $rest; $part2=substr($rest,0,$pos-length($2)); $part3=substr($rest,$pos); - } + } else { die "$word1 and $word2 not in the correct order or not present as a pair." ; } @@ -2405,7 +2441,7 @@ sub splitlatex { my $leadin=$1; length($string)>0 or return ($leadin); - my @retval=($string =~ m/$pat/osg); + my @retval=($string =~ m/$pat/osg); if (length($string) != length(join("",@retval))) { print STDERR "\nWARNING: Inconsistency in length of input string and parsed string:\n This often indicates faulty or non-standard latex code.\n In many cases you can ignore this and the following warning messages.\n Note that character numbers in the following are counted beginning after \\begin{document} and are only approximate." unless $ignorewarnings; @@ -2449,17 +2485,17 @@ sub splitlatex { # pass1( \@seq1,\@seq2) # Look for differences between seq1 and seq2. -# Where an common-subsequence block is flanked by deleted or appended blocks, +# Where an common-subsequence block is flanked by deleted or appended blocks, # and is shorter than $MINWORDSBLOCK words it is appended -# to the last deleted or appended word. If the block contains tokens other than words +# to the last deleted or appended word. If the block contains tokens other than words # or punctuation it is not merged. # Deleted or appended block consisting of words and safe commands only are # also merged, to prevent break-up in pass2 (after previous isolated words have been removed) -# If there are commands with textual arguments (e.g. \caption) both in corresponding -# appended and deleted blocks split them such that the command and opening bracket -# are one token, then the rest is split up following standard rules, and the closing +# If there are commands with textual arguments (e.g. \caption) both in corresponding +# appended and deleted blocks split them such that the command and opening bracket +# are one token, then the rest is split up following standard rules, and the closing # bracket is a separate token, ie. turn -# "\caption{This is a textual argument}" into +# "\caption{This is a textual argument}" into # ("\caption{","This ","is ","a ","textual ","argument","}") # No return value. Destructively changes sequences sub pass1 { @@ -2488,15 +2524,15 @@ sub pass1 { my $adddiscard = sub { if ($cnt > 0 ) { $matblkcnt++; - # just after an unchanged block + # just after an unchanged block # print STDERR "Unchanged block $cnt, $last1,$last2 \n"; - if ($cnt < $MINWORDSBLOCK + if ($cnt < $MINWORDSBLOCK && $cnt==scalar ( - grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat_n\]|\{$pat_n\})*)/o - && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) + grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat_n\]|\{$pat_n\})*)/o + && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && scalar(@dummy=split(" ",$2))<3 ) } @$block) ) { - # merge identical blocks shorter than $MINWORDSBLOCK + # merge identical blocks shorter than $MINWORDSBLOCK # and only containing ordinary words # with preceding different word # We cannot carry out this merging immediately as this @@ -2504,23 +2540,23 @@ sub pass1 { # the algorithm, instead we store in @$todo where we have to merge push(@$todo, [ $last1,$last2,$cnt,@$block ]); } - $block = []; + $block = []; $cnt=0; $last1=-1; $last2=-1; } }; my $discard=sub { $deltokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$delblock,[ $seq1->[$_[0]],$_[0] ]); - $last1=$_[0] }; + $last1=$_[0] }; my $add = sub { $addtokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$addblock,[ $seq2->[$_[1]],$_[1] ]); - $last2=$_[1] }; + $last2=$_[1] }; my $match = sub { $mattokcnt++; if ($cnt==0) { # first word of matching sequence after changed sequence or at beginning of word sequence - $deltextblocks = extracttextblocks($delblock); + $deltextblocks = extracttextblocks($delblock); $delblkcnt++ if scalar @$delblock; $addtextblocks = extracttextblocks($addblock); $addblkcnt++ if scalar @$addblock; @@ -2536,7 +2572,7 @@ sub pass1 { ### Algorithm::Diff 1.19 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, 0, sub { $_[0]->[0] } ); } else { - ### Algorithm::Diff 1.15 + ### Algorithm::Diff 1.15 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, sub { $_[0]->[0] } ); } @@ -2567,11 +2603,11 @@ sub pass1 { my ($index,$block,$cnt)=@{ shift(@$addtextblocks) }; push(@$todo, [-1,$index,$cnt,@$block]); } - + $addblock=[]; $delblock=[]; } - push(@$block,$seq2->[$_[1]]); + push(@$block,$seq2->[$_[1]]); $cnt++ }; my $keyfunc = sub { join(" ",split(" ",shift())) }; @@ -2579,7 +2615,7 @@ sub pass1 { traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); - # now carry out the merging/splitting. Refer to elements relative from + # now carry out the merging/splitting. Refer to elements relative from # the end (with negative indices) as these offsets don't change before the instruction is executed # cnt>0: merged small unchanged groups with previous changed blocks # cnt==-1: split textual commands into components @@ -2594,7 +2630,7 @@ sub pass1 { } } - if ($verbose) { + if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens in $matblkcnt blocks.\n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; @@ -2604,10 +2640,10 @@ sub pass1 { # extracttextblocks(\@blockindex) -# $blockindex has the following format -# [ [ token1, index1 ], [token2, index2],.. ] -# where index refers to the index in the original old or new word sequence -# Returns: reference to an array of the form +# $blockindex has the following format +# [ [ token1, index1 ], [token2, index2],.. ] +# where index refers to the index in the original old or new word sequence +# Returns: reference to an array of the form # [[ $index, $textblock, $cnt ], .. # where $index index of block to be merged # $textblock contains all the words to be merged with the word at $index (but does not contain this word) @@ -2615,7 +2651,7 @@ sub pass1 { # # requires: iscmd # -sub extracttextblocks { +sub extracttextblocks { my $block=shift; my ($i,$token,$index); my $textblock=[]; @@ -2625,13 +2661,13 @@ sub extracttextblocks { # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace='\s*'; + my $extraspace='\s*'; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # store pure text blocks - if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*)/ - && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) + if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*)/ + && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && !iscmd($1,\@TEXTCMDLIST,\@TEXTCMDEXCL))) { # we have text or a command which can be treated as text if ($last<0) { @@ -2639,7 +2675,7 @@ sub extracttextblocks { $last=$index; } else { # add to pure-text block - push(@$textblock, $token); + push(@$textblock, $token); } } else { # it is not text @@ -2660,29 +2696,29 @@ sub extracttextblocks { # extractcommands( \@blockindex ) -# $blockindex has the following format -# [ [ token1, index1 ], [token2, index2],.. ] -# where index refers to the index in the original old or new word sequence -# Returns: reference to an array of the form -# [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],.. -# where index is just taken from input array -# command must have a textual argument as last argument -# -# requires: iscmd -# -sub extractcommands { +# $blockindex has the following format +# [ [ token1, index1 ], [token2, index2],.. ] +# where index refers to the index in the original old or new word sequence +# Returns: reference to an array of the form +# [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],.. +# where index is just taken from input array +# command must have a textual argument as last argument +# +# requires: iscmd +# +sub extractcommands { my $block=shift; my ($i,$token,$index,$cmd,$open,$mid,$closing); my $retval=[]; # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace='\s*'; + my $extraspace='\s*'; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # check if token is an alphanumeric command sequence with at least one non-optional argument - # \cmd[...]{...}{last argument} + # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: \cmd @@ -2690,7 +2726,7 @@ sub extractcommands { # $4: } + trailing spaces if ( ( $token =~ m/^(\\([\w\d\*]+)(?:${extraspace}\[$brat_n\]|${extraspace}\{$pat_n\})*${extraspace}\{)($pat_n)(\}\s*)$/so ) && iscmd($2,\@TEXTCMDLIST,\@TEXTCMDEXCL) ) { - print STDERR "DEBUG EXTRACTCOMMANDS Match |$1|$2|$3|$4|$index \n" if $debug; + print STDERR "DEBUG EXTRACTCOMMANDS Match |$1|$2|$3|$4|$index \n" if $debug; # push(@$retval,[ $2,$index,$1,$3,$4 ]); ($cmd,$open,$mid,$closing) = ($2,$1,$3,$4) ; $closing =~ s/\}/\\RIGHTBRACE/ ; @@ -2701,7 +2737,7 @@ sub extractcommands { } # iscmd($cmd,\@regexarray,\@regexexcl) checks -# return 1 if $cmd matches any of the patterns in the +# return 1 if $cmd matches any of the patterns in the # array $@regexarray, and none of the patterns in \@regexexcl, otherwise return 0 sub iscmd { my ($cmd,$regexar,$regexexcl)=@_; @@ -2709,7 +2745,7 @@ sub iscmd { ### print STDERR "DEBUG: iscmd($cmd)=" if $debug; foreach $pat ( @$regexar ) { if ( $cmd =~ m/^${pat}$/ ) { - $ret=1 ; + $ret=1 ; last; } } @@ -2725,13 +2761,13 @@ sub iscmd { # pass2( \@seq1,\@seq2) -# Look for differences between seq1 and seq2. +# Look for differences between seq1 and seq2. # Mark begin and end of deleted and appended sequences with tags $DELOPEN and $DELCLOSE # and $ADDOPEN and $ADDCLOSE, respectively, however exclude { } & and all comands, unless # they match an element of the whitelist (SAFECMD) # For words in TEXTCMD but not in SAFECMD, enclose interior with $ADDOPEN and $ADDCLOSE brackets -# Deleted comment lines are marked with %DIF < -# Added comment lines are marked with %DIF > +# Deleted comment lines are marked with %DIF < +# Added comment lines are marked with %DIF > sub pass2 { my $seq1 = shift ; my $seq2 = shift ; @@ -2763,7 +2799,7 @@ sub pass2 { $addhunk = []; } push(@$retval,$seq2->[$_[1]]) }; - + my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); @@ -2772,7 +2808,7 @@ sub pass2 { push @$retval,marktags($ADDMARKOPEN,$ADDMARKCLOSE,$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,$addhunk) if scalar @$addhunk; - if ($verbose) { + if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens. \n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; @@ -2794,7 +2830,7 @@ sub marktags { my (@argtext); my $retval=[]; my $noncomment=0; - my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word + my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word # 1: last token written is a command # for keeping track whether we are just in a command sequence or in a word sequence my $cmdcomment= ($opencmd =~ m/^%/); # Flag to indicate whether opencmd is a comment (i.e. if we intend to simply comment out changed commands) @@ -2810,31 +2846,31 @@ sub marktags { # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace_mt='\s*'; + my $extraspace_mt='\s*'; foreach (@$block) { - $word=$_; + $word=$_; if ( $word =~ s/^%/%$comment/ ) { # a comment if ($cmd==1) { push (@$retval,$closecmd) ; $cmd=-1; } - push (@$retval,$word); + push (@$retval,$word); next; } if ( $word =~ m/^\s*$/ ) { ### print STDERR "DEBUG MARKTAGS: whitespace detected |$word| cmdcom |$cmdcomment| |$opencmd|\n" if $debug; # a sequence of white-space characters - this should only ever happen for the first element of block. - # in deleted block, omit, otherwise just copy it in + # in deleted block, omit, otherwise just copy it in if ( ! $cmdcomment) { # ignore in deleted blocks push(@$retval,$word); } next; } if (! $noncomment) { - push (@$retval,$openmark); + push (@$retval,$openmark); $noncomment=1; } # negative lookahead pattern (?!) in second clause is put in to avoid matching \( .. \) patterns @@ -2844,7 +2880,7 @@ sub marktags { # word is a command or other significant token (not in SAFECMDLIST) ## same conditions as in subroutine extractcommand: # check if token is an alphanumeric command sequence with at least one non-optional argument - # \cmd[...]{...}{last argument} + # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: cmd @@ -2861,11 +2897,11 @@ sub marktags { # Condition 3: But if we are in a deleted block ($cmdcomment=1) and # $2 (the command) is in context2, just treat it as an ordinary command (i.e. comment it open with $opencmd) # Because we do not want to disable this command - # here we do not use $opencmd and $closecmd($opencmd is empty) + # here we do not use $opencmd and $closecmd($opencmd is empty) print STDERR "DEBUG: Detected text |$word| but not safe command \$2: $2 \$3: $3\n." if $debug; if ($cmd==1) { push (@$retval,$closecmd) ; - } elsif ($cmd==0) { + } elsif ($cmd==0) { push (@$retval,$close) ; } $command=$1; $commandword=$2; $closingbracket=$4; @@ -2881,16 +2917,16 @@ sub marktags { # for latexrevise push (@$retval,$command,"%\n{$AUXCMD\n",marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } elsif ( iscmd($commandword,,\@MATHTEXTCMDLIST, \@MATHTEXTCMDEXCL) ) { - # MATHBLOCK pseudo command: consider all commands safe, except & and \\, \begin and \end and a few package sprcific one (look at UNSAFEMATHCMD definition) - # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to + # MATHBLOCK pseudo command: consider all commands safe, except & and \\, \begin and \end and a few package sprcific one (look at UNSAFEMATHCMD definition) + # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to # "" - local @SAFECMDLIST=(".*"); + local @SAFECMDLIST=(".*"); local @SAFECMDEXCL=('\\','\\\\',@UNSAFEMATHCMD); push(@$retval,$command,marktags("","",$open,$close,"","",$comment,\@argtext)#@argtext ,$closingbracket); } else { # normal textcmd or context1cmd in an added block - push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); + push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } push (@$retval,$AUXCMD,"\n") if $cmdcomment ; $cmd=-1 ; @@ -2976,10 +3012,10 @@ sub take_comments_and_newline_from_frac() { # names or labels but it does not matter because they are converted back in the postprocessing step # Returns: leading white space removed in step 1 sub preprocess { - for (@_) { + for (@_) { - # change in \verb and similar commands - note that I introduce an extra space here so that the + # change in \verb and similar commands - note that I introduce an extra space here so that the # already hashed variants do not trigger again # transform \lstinline{...} # s/\\lstinline(\[$brat0\])?(\{(?:.*?)\})/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg; @@ -3009,7 +3045,7 @@ sub preprocess { 1 while s/(?<!\\)_(\s*{($pat_n)})/\\SUBSCRIPT$1/g ; # Convert ^n into \SUPERSCRIPTNB{n} and ^{nnn} into \SUPERSCRIPT{nn} 1 while s/(?<!\\)\^(\s*([^{\\\s]|\\\w+))/\\SUPERSCRIPTNB{$1}/g ; - 1 while s/(?<!\\)\^(\s*{($pat_n)})/\\SUPERSCRIPT$1/g ; + 1 while s/(?<!\\)\^(\s*{($pat_n)})/\\SUPERSCRIPT$1/g ; # Convert \sqrt{n} into \SQRT{n} and \sqrt nn into SQRTNB{nn} 1 while s/(?<!\\)\\sqrt(\s*([^{\\\s]|\\\w+))/\\SQRTNB{$1}/g ; 1 while s/(?<!\\)\\sqrt(\s*{($pat_n)})/\\SQRT$1/g ; @@ -3029,16 +3065,16 @@ sub preprocess { if ( $mathmarkup != FINE ) { # DIFANCHORARRB and DIFANCHORARRE, DIFANCHORMATHB and DIFANCHORMATHE markers are inserted here to encourage the matching algorithm # to always match up the closing brace. Otherwise sometimes one ends up with a situation where - # the closing brace is deleted and added at another point. The deleted closing brace is then + # the closing brace is deleted and added at another point. The deleted closing brace is then # prevented by a %DIFDELCMD, leading to material leaking in or out of the math environment. # The anchors are removed in post-processing again. (note that they are simple text to cause least amount of complications - # Admittedly, this is something of a hack and will not always work. If it does not, then one needs to + # Admittedly, this is something of a hack and will not always work. If it does not, then one needs to # resort to WHOLE or FINE, or NONE math mode processing. s/\\begin\{($ARRENV)}(.*?)\\end\{\1}/\\ARRAYBLOCK$1\{$2\\DIFANCHORARRB \}\\DIFANCHORARRE /sg; take_comments_and_newline_from_frac(); - # Convert Math environments with arguments + # Convert Math environments with arguments s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}((?:\[$brat_n\])|(?:\{$pat_n\}))+(.*?)\\end\{\1\}/\\MATHBLOCK$1\[$2\]\{$3\\DIFANCHORMATHB \}\\DIFANCHORMATHE /sg; # Convert Math environments without arguments s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)\\end\{\1\}/\\MATHBLOCK$1\{$2\\DIFANCHORMATHB \}\\DIFANCHORMATHE /sg; @@ -3052,7 +3088,7 @@ sub preprocess { # $expanded=linecomment($string) #preface all lines with verbatim marker (usually DIFVRB) -sub linecomment { +sub linecomment { my @verbatimlines=split("\n",$_[0]); # the first line needs special treatment - we do want to retain optional arguments as is but wrap the remainder also with VERBCOMMENT ### print STDERR "DEBUG: before verbatimlines[0] = ",$verbatimlines[0],"\n"; @@ -3062,7 +3098,7 @@ sub linecomment { } # $simple=reverselinecomment($env $string) -# remove DIFVRB comments but leave changed lines marked +# remove DIFVRB comments but leave changed lines marked sub reverselinecomment { my ($environment, $verbatimtext)=@_; ### print STDERR "DEBUG REVERSELINECOMMENT input: $environment,|$verbatimtext|\n" if $debug; @@ -3077,7 +3113,7 @@ sub reverselinecomment { $verbatimtext =~ s/\\DIFdelend //g; $verbatimtext =~ s/$DELCMDOPEN.*//g; - # remove DIFVRB mark + # remove DIFVRB mark $verbatimtext=~ s/%$VERBCOMMENT//g; # remove part of the markup in changed lines @@ -3168,7 +3204,7 @@ sub writedebugfile { # * Remove STOP token from the end # * Replace \RIGHTBRACE by } # * If option --no-del is set delete all deleted blocks -# 1. Check all deleted blocks: +# 1. Check all deleted blocks: # a.where a deleted block contains a matching \begin and # \end environment (these will be disabled by a %DIFDELCMD statements), for selected environments enable # these commands again (such that for example displayed math in a deleted equation @@ -3189,14 +3225,14 @@ sub writedebugfile { # For added blocks: # c. If in-line math mode contains array environment, enclose the whole environment in \mbox'es # d. place \cite commands in mbox'es (for UNDERLINE style) -# +# # 2. If math-mode COARSE,WHOLE or NONE option set: Convert \MATHBLOCKmath{..} commands back to environments # # Convert all PICTUREblock{..} commands back to the appropriate environments # 3. Convert DIFadd, DIFdel, DIFaddbegin , ... into FL varieties # within floats (currently recognised float environments: plate,table,figure # plus starred varieties). -# 4. Remove empty %DIFDELCMD < lines +# 4. Remove empty %DIFDELCMD < lines # 4. Convert \begin{SQUAREBRACKET} \end{SQUAREBRACKET} into \[ \] # Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$ # 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn} @@ -3209,7 +3245,7 @@ sub writedebugfile { # 4, undo renaming of the \begin, \end,{,} in comments # Change \QLEFTBRACE, \QRIGHTBRACE,\AMPERSAND to \{,\},\& # -# Note have to manually synchronize substitution commands below and +# Note have to manually synchronize substitution commands below and # DIF.. command names in the header sub postprocess { my ($begin,$len,$float,$delblock,$addblock); ### $cnt @@ -3221,7 +3257,7 @@ sub postprocess { my (@itemargs, $itemarg); - for (@_) { + for (@_) { # change $'s in comments to something harmless 1 while s/(%.*)\$/$1DOLLARDIF/mg ; @@ -3231,7 +3267,7 @@ sub postprocess { # the only way to get these is as %DIFDELCMD < \RIGHTBRACE construction # This essentially marks closing right braces of MATHBLOCK environments, which did not get matched # up. This case should be rare, so I just leave this in the diff file output. Not really elegant - # but can still be dealt with later if it results in problems. + # but can still be dealt with later if it results in problems. s/%DIFDELCMD < \\RIGHTBRACE/%DIFDELCMD < \\MBLOCKRIGHTBRACE/g ; # Replace \RIGHTBRACE by } s/\\RIGHTBRACE/}/g; @@ -3259,7 +3295,7 @@ sub postprocess { $len=length($&); $begin=pos($_) - $len; $delblock=$&; - ### A much simpler method for math replacement might follow this strategy (can recycle part of the commands below for following + ### A much simpler method for math replacement might follow this strategy (can recycle part of the commands below for following ### this strategy: ### 1. a Insert aux commands \begin{MATHMODE} or \end{MATHMODE} for all deleted commands opening or closing displayed math mode ### b Insert aux commands \begin{MATHARRMODE} or \end{MATHARRMODE} for all deleted commands opening or closing math array mode @@ -3285,14 +3321,14 @@ sub postprocess { ###0.5: $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg; $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}.*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{\2\})/\\end\{MATHMODE\}$AUXCMD\n$1$3\n\\begin\{MATHMODE\}$AUXCMD\n$4/sg; - # now look for unpaired %DIFDELCMD < \begin{MATHENV}; if found add \begin{$MATHREPL} and insert \end{$MATHREPL} + # now look for unpaired %DIFDELCMD < \begin{MATHENV}; if found add \begin{$MATHREPL} and insert \end{$MATHREPL} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\begin{$MATHREPL}$AUXCMD\n/sg ) { ### print STDERR "BINGO: begin block: \nBefore: |" . substr($_,$begin,$len) . "|\n" if $debug ; $delblock =~ s/(\\DIFdelend$)/\\end{$MATHREPL}$AUXCMD\n$1/s ; ### print STDERR "After: |" . $delblock . "|\n\n" if $debug ; } - # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} + # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end\{MATHMODE\}$AUXCMD\n/sg ) { ### print STDERR "BINGO: end block:\nBefore: |" . substr($_,$begin,$len) . "|\n" if $debug; @@ -3315,15 +3351,15 @@ sub postprocess { $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg; ### print STDERR "STEP1: |" . $delblock . "|\n\n" if $debug ; - # now look for unpaired %DIFDELCMD < \begin{MATHARRENV}; if found add \begin{$MATHARRREPL} and insert \end{$MATHARRREPL} + # now look for unpaired %DIFDELCMD < \begin{MATHARRENV}; if found add \begin{$MATHARRREPL} and insert \end{$MATHARRREPL} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{($MATHARRENV)\}(.*?)(?:$DELCMDCLOSE|\n))/$1\\begin{$2*}$3$AUXCMD\n/sg ) { $arrenv=$2; - $delblock =~ s/(\\DIFdelend$)/\\end{$arrenv*}}$AUXCMD\n$1/s ; + $delblock =~ s/(\\DIFdelend$)/\\end{$arrenv*}$AUXCMD\n$1/s ; } ### print STDERR "STEP2: |" . $delblock . "|\n\n" if $debug ; - # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} + # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end{MATHMODE}$AUXCMD\n/sg ) { $delblock =~ s/(\\DIFdelend$)/\\begin{MATHMODE}$AUXCMD\n$1/s ; @@ -3341,7 +3377,7 @@ sub postprocess { ### $eqarrayblock=~ s/(\%DIFDELCMD < \s*(\&|\\\\)\s*?(?:$DELCMDCLOSE|\n))/$1$2$AUXCMD\n/sg ; $eqarrayblock =~ s/(\%DIFDELCMD < (.*?(?:\&|\\\\).*)(?:$DELCMDCLOSE|\n))/ # The pattern captures comments with at least one of & or \\ - @symbols= split(m@((?:&|\\\\)\s*)@,$2); # extract & and \\ and other material from sequence + @symbols= split(m@((?:&|\\\\)\s*)@,$2); # extract & and \\ and other material from sequence @symbols= grep ( m@&|\\\\\s*@, @symbols); # select & and \\ (and subsequent spaces) "$1@symbols$AUXCMD\n" /eg ; @@ -3354,7 +3390,7 @@ sub postprocess { } elsif ( $mathmarkup == COARSE || $mathmarkup == WHOLE ) { # Convert MATHBLOCKmath commands to their uncounted numbers (e.g. convert equation -> displaymath # (environments defined in $MATHENV will be replaced by $MATHREPL, and environments in $MATHARRENV - # will be replaced by their starred variety + # will be replaced by their starred variety $delblock=~ s/\\MATHBLOCK($MATHENV)((?:\[$brat_n\])?)\{($pat_n)\}/\\MATHBLOCK$MATHREPL$2\{$3\}/sg; $delblock=~ s/\\MATHBLOCK($MATHARRENV)((?:\[$brat_n\])?)\{($pat_n)\}/\\MATHBLOCK$1\*$2\{$3\}/sg; } @@ -3368,10 +3404,10 @@ sub postprocess { print STDERR "DELBLOCK after maths processing: |" . $delblock . "|\n\n" if $debug ; - # Reinstate completely deleted list environments. note that items within the + # Reinstate completely deleted list environments. note that items within the # environment will still be commented out. They will be restored later $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($LISTENV)\}\s*?(?:\n|$DELCMDCLOSE))(.*?)(\%DIFDELCMD < \s*\\end\{\2\})/{ - ### # block within the search; replacement environment + ### # block within the search; replacement environment ### "$1\\begin{$2}$AUXCMD\n". restore_item_commands($3). "\n\\end{$2}$AUXCMD\n$4"; "$1\\begin{$2}$AUXCMD\n$3\n\\end{$2}$AUXCMD\n$4"; }/esg; @@ -3405,7 +3441,7 @@ sub postprocess { ### if ($CITE2CMD) { ###### ${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})) .*?%%%\n ### $delblock=~s/($DELCMDOPEN\s*\\($CITE2CMD)(.*)$DELCMDCLOSE)/ - ### # Replacement code + ### # Replacement code ### {my ($aux,$all); ### $aux=$all=$1; ### $aux=~s#\n?($DELCMDOPEN|$DELCMDCLOSE)##g; @@ -3415,7 +3451,7 @@ sub postprocess { ### if ($CITECMD) { ###### $delblock=~s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; ### $delblock=~s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; - ### } + ### } # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox @@ -3423,7 +3459,7 @@ sub postprocess { # note additional \newline after command is omitted from output if right at the end of deleted block (otherwise a spurious empty line is generated) $delblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } - ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/)) { + ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/)) { ### # change included verbatim environments ### $delblock =~ s/\\DIFverb\{/\\DIFDIFdelverb\{/g; ### $delblock =~ s/\\DIFlstinline/\\DIFDIFdellstinline/g; @@ -3465,7 +3501,7 @@ sub postprocess { ##$addblock=~s/($math)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; $addblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } - ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { + ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { # mark added verbatim commands $addblock =~ s/\\DIFverb/\\DIFDIFaddverb/g; $addblock =~ s/\\DIFlstinline/\\DIFDIFaddlstinline/g; @@ -3483,11 +3519,11 @@ sub postprocess { pos = $begin + length($addblock); } - # Go through whole text, and by counting list environment commands, find out when we are within a list environment. + # Go through whole text, and by counting list environment commands, find out when we are within a list environment. # Within those restore deleted \item commands - @textparts=split /(?<!$DELCMDOPEN)(\\(?:begin|end)\{$LISTENV\})/ ; + @textparts=split /(?<!$DELCMDOPEN)(\\(?:begin|end)\{$LISTENV\})/ ; @liststack=(); - @newtextparts=map { + @newtextparts=map { ### print STDERR ":::::::: $_\n"; if ( ($listtype) = m/^\\begin\{($LISTENV)\}$/ ) { print STDERR "DEBUG: postprocess \\begin{$listtype}\n" if $debug; @@ -3503,7 +3539,7 @@ sub postprocess { } else { print STDERR "DEBUG: postprocess \@liststack=(",join(",",@liststack),")\n" if $debug; if (scalar @liststack > 0 ) { - # we are within a list environment and should replace all item commands + # we are within a list environment and should replace all item commands $_=restore_item_commands($_); } # else: we are outside a list environment and do not need to do anything @@ -3516,17 +3552,17 @@ sub postprocess { # Replace MATHMODE environments from step 1a above by the correct Math environment and remove unncessary pairings - + if ( $mathmarkup == FINE ) { # look for AUXCMD math-mode pairs which have only comments (or empty lines between them), and remove the added commands # \begin{..} ... \end{..} pairs - s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\end\{\1\}$AUXCMD\n/$2/sg; + s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\end\{\1\}$AUXCMD\n/$2/sg; # \end{..} .... \begin{..} pairs - s/\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\begin\{\1\}$AUXCMD\n/$2/sg; + s/\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\begin\{\1\}$AUXCMD\n/$2/sg; writedebugfile($_,'postprocess15'); # The next line is complicated. The negative look-ahead insertion makes sure that no \end{$MATHENV} (or other mathematical - # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching + # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching # is not globally minimal but only 'locally' (matching is beginning from the left side of the string) # [NB: Do not be tempted to prettify the expression with /x modified. It seems this is applied after strings are expanded so will ignore spaces in strings 1 while s/(?<!$DELCMDOPEN)\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}((?:${DELCMDOPEN}[^\n]*|.(?!(?:\\end\{(?:(?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}|\\begin\{MATHMODE})))*?)\\end\{MATHMODE}/\\begin{$1}$2\\end{$1}/s; @@ -3601,7 +3637,7 @@ sub postprocess { # remove empty DIFCMD < lines s/^\Q${DELCMDOPEN}\E\n//msg; - # Expand hashes of verb and verbatim environments + # Expand hashes of verb and verbatim environments s/${DELCMDOPEN}\\($VERBATIMENV)\{([-\d]*?)\}/"${DELCMDOPEN}\\begin{${1}}".fromhash(\%verbhash,$2,$DELCMDOPEN)."${DELCMDOPEN}\\end{${1}}"/esg; # revert changes to verbatim environments for line diffs (and add code to mark up changes) (note negative look behind assertions to not leak out of DIFDELCMD comments) # Example: @@ -3627,8 +3663,8 @@ sub postprocess { ((?:\%\Q$DELCOMMENT$VERBCOMMENT\E[^\n]*?\n)*) # Deleted \end command of verbatim environment. Note that the type is forced to match the opening. Captures: $5: Whole deleted environment (previous way this line was written: (\Q$DELCMDOPEN\E\\end\{\2\}(?:\n|\s|\Q$DELCMDOPEN\E)*\Q$DELCMDCLOSE\E) (\Q$DELCMDOPEN\E\\end\{\2\}) - / # Substitution part - $1 # Leave expression as is + / # Substitution part + $1 # Leave expression as is . "$AUXCMD NEXT\n" # Mark the following line as an auxiliary command . "" # reinstate the original environment without options . reverselinecomment($2, "$3$4") # modify the body to change the markup; reverselinecomment parses for options @@ -3637,7 +3673,7 @@ sub postprocess { /esgx; # Modifiers of substitution command writedebugfile($_,'postprocess2'); # where changes have occurred in verbatim environment, change verbatim to DIFverbatim to allow mark-up - # (I use the presence of optional paramater to verbatim environment as the marker - normal verbatim + # (I use the presence of optional paramater to verbatim environment as the marker - normal verbatim # environment does not take optional arguments) s/(?<!$DELCMDOPEN)\\begin\{(verbatim[*]?)\}(\[$brat_n\].*?)\\end\{\1\}/\\begin{DIF$1}$2\\end{DIF$1}/sg; @@ -3651,7 +3687,7 @@ sub postprocess { # convert remaining PAR commands (which are preceded by non-white space characters, usually "}" ($ADDCLOSE) s/\\PAR\n/\n\n/sg; - # package specific processing: + # package specific processing: if ( defined($packages{"endfloat"})) { #endfloat: make sure \begin{figure} and \end{figure} are always # on a line by themselves, similarly for table environment @@ -3664,12 +3700,16 @@ sub postprocess { s/^((?:[^%]+)\\(?:begin|end)\{(?:figure|table)\}(?:\[[a-zA-Z]+\])?)(.+)((?:%.*)?)$/$1\n$2$3/mg; } - # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated + # Remove empty auxiliary LISTENV (sometmes these are generated if list environment occurs within the argument of a deleted comment) + # (slightly hacky but I could not see an easy way to see if in argument of another command when this extra markup is added) + s/\\begin\{($LISTENV)\}$AUXCMD\n((?:\s*\%[^\n]*\n)*\n?)\\end\{\1\}$AUXCMD\n/$2\n/msg ; + + # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated s/\\PERCENTAGE ?/\\%/g; - # Convert '\DOLLAR ' back into '\$' + # Convert '\DOLLAR ' back into '\$' s/\\DOLLAR /\\\$/g; - # undo renaming of the \begin and \end,{,} and dollars in comments + # undo renaming of the \begin and \end,{,} and dollars in comments # although we only renamed $ in comments to DOLLARDIFF, we might have lost the % in unchanged verbatim blocks, so rename all s/DOLLARDIF/\$/g; @@ -3687,7 +3727,7 @@ sub postprocess { # Convert \SQRT{n} into \sqrt{n} and \SQRTNB{nn} into \sqrt nn 1 while s/\\SQRT(\s*\{($pat_n)\})/\\sqrt$1/g ; 1 while s/\\SQRTNB\{(\s*$pat0)\}/\\sqrt$1/g ; - + 1 while s/(%.*)\\CFRAC (.*)$/$1\\frac$2/mg ; 1 while s/(%.*)\\CRIGHTBRACE (.*)$/$1\}$2/mg ; 1 while s/(%.*)\\CLEFTBRACE (.*)$/$1\{$2/mg ; @@ -3698,7 +3738,7 @@ sub postprocess { s/\\QRIGHTBRACE /\\\}/sg; s/\\AMPERSAND /\\&/sg; # Highlight added inline verbatim commands if possible - if ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) { + if ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) { # wrap added verb commands with color commands s/\\DIFDIFadd((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*)/\{\\color{blue}$AUXCMD\n\\DIF$1%\n\}$AUXCMD\n/sg; s/\\DIFDIFdel((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*$AUXCMD)/\{\\color{red}${AUXCMD}\n\\DIF$1\n\}${AUXCMD}/sg; @@ -3713,8 +3753,8 @@ sub postprocess { # finally add the comment to the ones not having an optional argument before ###s/\\DIFaddlstinline(?!\[)/\\lstinline\n[basicstyle=\\color{blue}]$AUXCMD\n/g; - return; } + return; } # $out = restore_item_commands($listenviron) @@ -3738,13 +3778,13 @@ sub restore_item_commands { # @auxlines=preprocess_preamble($oldpreamble,$newpreamble); - # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) - # the list of commands is defined in CONTEXT2CMD - # if found then use a bodydiff to mark up content, and replace the corresponding commands + # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) + # the list of commands is defined in CONTEXT2CMD + # if found then use a bodydiff to mark up content, and replace the corresponding commands # in both preambles by marked up version to 'fool' the linediff (such that only body is marked up). # A special case are e.g. author commands being added (or removed) # 1. If commands are added, then the entire content is marked up as new, but also the lines are marked as new in the linediff - # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns + # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns # with $auxlines a text to be appended at the end of the preamble, which shows the respective fields as deleted sub preprocess_preamble { my ($oldpreambleref,$newpreambleref)=(\$_[0],\$_[1]) ; @@ -3766,7 +3806,7 @@ EOF $titlecmd = "(?:".join("|",@CONTEXT2CMDLIST).")"; # as context2cmdlist is stored as regex, e.g. ((?-xism:^title$), we need to remove ^- fo # resue in a more complex regex - $titlecmd =~ s/[\$\^]//g; + $titlecmd =~ s/[\$\^]//g; # make sure to not match on comment lines: $titlecmdpat=qr/^(?:[^%\n]|\\%)*(\\($titlecmd)$extraspace(?:\[($brat_n)\])?(?:\{($pat_n)\}))/ms; ###print STDERR "DEBUG:",$titlecmdpat,"\n"; @@ -3792,7 +3832,7 @@ EOF $cmd=shift @newtitlecommands; $optarg=shift @newtitlecommands; $arg=shift @newtitlecommands; - + if ( defined($newhash{$cmd})) { warn "$cmd is used twice in preamble of new file. Reverting to pure line diff mode for preamble.\n"; print STDERR $warnmsgdetail; @@ -3819,7 +3859,7 @@ EOF } $argnew=$newhash{$cmd}->[2]; $argdiff="{" . join("",bodydiff($argold,$argnew)) ."}"; - # Replace \RIGHTBRACE by } + # Replace \RIGHTBRACE by } $argdiff =~ s/\\RIGHTBRACE/}/g; if ( length $optargnew ) { @@ -3834,7 +3874,7 @@ EOF $optargdiff=""; } ### print STDERR "DEBUG s/\\Q$newhash{$cmd}->[0]\\E/\\$cmd$optargdiff$argdiff/s\n"; - # Note: \Q and \E force literal interpretation of what it between them but allow + # Note: \Q and \E force literal interpretation of what it between them but allow # variable interpolation, such that e.g. \title matches just that and not TAB-itle $$newpreambleref=~s/\Q$newhash{$cmd}->[0]\E/\\$cmd$optargdiff$argdiff/s; # replace this in old preamble if necessary @@ -3874,7 +3914,7 @@ EOF #%< old deleted line(s) #%DIF ------- #%DIF mmann-nn -#new appended line %< +#new appended line %< #%DIF ------- # Future extension: mark change explicitly # Assumes: traverse_sequence traverses deletions before insertions in changed sequences @@ -3886,9 +3926,9 @@ sub linediff { my $block = []; my $retseq = []; my @begin=('','',''); # dummy initialisation - my $instring ; + my $instring ; - my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ; + my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ; push(@$block, "%DIF < " . $seq1->[$_[0]]) }; my $add = sub { if (! scalar @$block) { @begin=('a',$_[0],$_[1]) ;} @@ -3903,12 +3943,12 @@ sub linediff { $instring = sprintf "%%DIF %da%d-%d",$begin[1],$begin[2],$_[1]-1; } elsif ( $begin[0] eq 'c' ) { $instring = sprintf "%%DIF %sc%s", - ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) , + ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) , ($begin[2]==$_[1]-1) ? "$begin[2]" : $begin[2]."-".($_[1]-1) ; } else { $instring = sprintf "%%DIF %d%s%d",$begin[1],$begin[0],$begin[2]; } - push @$retseq, $instring,@$block, "%DIF -------" ; - $block = []; + push @$retseq, $instring,@$block, "%DIF -------" ; + $block = []; } push @$retseq, $seq2->[$_[1]] }; @@ -3916,7 +3956,7 @@ sub linediff { my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); - push @$retseq, @$block if scalar @$block; + push @$retseq, @$block if scalar @$block; return wantarray ? @$retseq : $retseq ; } @@ -3926,23 +3966,23 @@ sub linediff { # init_regex_arr_data(\@array,"TOKEN INIT") # scans DATA file handel for line "%% TOKEN INIT" line # then appends each line not beginning with % into array (as a quoted regex) -# This is used for command lists and configuration variables, but the processing is slightly -# different: +# This is used for command lists and configuration variables, but the processing is slightly +# different: # For lists, the regular expression is extended to include beginning (^) and end ($) markers, to require full-string matching # For configuration variables (and all others), simply an unadorned list is copied sub init_regex_arr_data { my ($arr,$token)=@_; my $copy=0; my ($mode); - if ($token =~ m/COMMANDS/ ) { - $mode=0; # Reading command list + if ($token =~ m/COMMANDS/ ) { + $mode=0; # Reading command list } else { $mode=1; # Reading configuration variables } while (<DATA>) { if ( m/^%%BEGIN $token\s*$/ ) { - $copy=1; + $copy=1; next; } elsif ( m/^%%END $token\s*$/ ) { last; } @@ -4023,17 +4063,18 @@ sub exetime { sub usage { - print STDERR <<"EOF"; + print STDERR <<"EOF"; Usage: $0 [options] old.tex new.tex > diff.tex -Compares two latex files and writes tex code to stdout, which has the same format as new.tex but +Compares two latex files and writes tex code to stdout, which has the same format as new.tex but has all changes relative to old.tex marked up or commented. Note that old.tex and new.tex need to -be real files (not pipes or similar) as they are opened twice. +be real files (not pipes or similar) as they are opened twice. --type=markupstyle -t markupstyle Add code to preamble for selected markup style - Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE + Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT + LUAUNDERLINE [ Default: UNDERLINE ] --subtype=markstyle @@ -4044,7 +4085,7 @@ be real files (not pipes or similar) as they are opened twice. * LABEL subtype is deprecated --floattype=markstyle --f markstyle Add code to preamble for selected style which +-f markstyle Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats so marginal marking can be disabled thus) @@ -4053,11 +4094,11 @@ be real files (not pipes or similar) as they are opened twice. --encoding=enc -e enc Specify encoding of old.tex and new.tex. Typical encodings are - ascii, utf8, latin1, latin9. A list of available encodings can be - obtained by executing + ascii, utf8, latin1, latin9. A list of available encodings can be + obtained by executing perl -MEncode -e 'print join ("\\n",Encode->encodings( ":all" )) ;' [Default encoding is utf8 unless the first few lines of the preamble contain - an invocation "\\usepackage[..]{inputenc} in which case the + an invocation "\\usepackage[..]{inputenc} in which case the encoding chosen by this command is asssumed. Note that ASCII (standard latex) is a subset of utf8] @@ -4074,22 +4115,22 @@ be real files (not pipes or similar) as they are opened twice. --exclude-safecmd=exclude-file --exclude-safecmd="cmd1,cmd2,..." --A exclude-file +-A exclude-file --replace-safecmd=replace-file --append-safecmd=append-file --append-safecmd="cmd1,cmd2,..." -a append-file Exclude from, replace or append to the list of regex - matching commands which are safe to use within the + matching commands which are safe to use within the scope of a \\DIFadd or \\DIFdel command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are ignored). A literal comma within the comma-separated list must be - escaped thus "\\,", Note that the RegEx needs to match the whole of + escaped thus "\\,", Note that the RegEx needs to match the whole of the token, i.e., /^regex\$/ is implied and that the initial "\\" of the command is not included. The --exclude-safecmd - and --append-safecmd options can be combined with the --replace-safecmd + and --append-safecmd options can be combined with the --replace-safecmd option and can be used repeatedly to add cumulatively to the lists. ---exclude-textcmd=exclude-file +--exclude-textcmd=exclude-file --exclude-textcmd="cmd1,cmd2,..." -X exclude-file --replace-textcmd=replace-file @@ -4105,7 +4146,7 @@ be real files (not pipes or similar) as they are opened twice. Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. \\caption will only work within a figure - or table. These commands behave like text commands, except when + or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. @@ -4115,7 +4156,7 @@ be real files (not pipes or similar) as they are opened twice. As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. - context2 commands are also the only commands in the preamble, whose argument will + context2 commands are also the only commands in the preamble, whose argument will be processed in word-by-word mode (which only works, if they occur no more than once in the preamble). @@ -4124,15 +4165,15 @@ be real files (not pipes or similar) as they are opened twice. --append-mboxsafecmd=append-file --append-mboxsafecmd="cmd1,cmd2,..." Define safe commands, which additionally need to be protected by encapsulating - in an \\mbox{..}. This is sometimes needed to get around incompatibilities + in an \\mbox{..}. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE - + --config var1=val1,var2=val2,... -c var1=val1,.. Set configuration variables. --c configfile Available variables: +-c configfile Available variables: ARRENV (RegEx) COUNTERCMD (RegEx) FLOATENV (RegEx) @@ -4151,15 +4192,15 @@ be real files (not pipes or similar) as they are opened twice. --add-to-config varenv1=pattern1,varenv2=pattern2 For configuration variables containing a regular expression (essentially those ending - in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration + in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. varenv must be one of the variables listed above that take a regular - expression as argument, and pattern is any regular expression (which might need to be + expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. --add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote" --packages=pkg1,pkg2,.. - Tell latexdiff that .tex file is processed with the packages in list + Tell latexdiff that .tex file is processed with the packages in list loaded. This is normally not necessary if the .tex file includes the preamble, as the preamble is automatically scanned for \\usepackage commands. Use of the --packages option disables automatic scanning, so if for any @@ -4180,57 +4221,57 @@ be real files (not pipes or similar) as they are opened twice. --show-all Show all of the above - NB For all --show commands, no old.tex or new.tex file needs to be given, and no + NB For all --show commands, no old.tex or new.tex file needs to be given, and no differencing takes place. Other configuration options: --allow-spaces Allow spaces between bracketed or braced arguments to commands - [Default requires arguments to directly follow each other without + [Default requires arguments to directly follow each other without intervening spaces] --math-markup=level Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): - off or 0: suppress markup for math environments. Deleted equations will not - appear in diff file. This mode can be used if all the other modes + off or 0: suppress markup for math environments. Deleted equations will not + appear in diff file. This mode can be used if all the other modes cause invalid latex code. whole or 1: Differencing on the level of whole equations. Even trivial changes - to equations cause the whole equation to be marked changed. This - mode can be used if processing in coarse or fine mode results in + to equations cause the whole equation to be marked changed. This + mode can be used if processing in coarse or fine mode results in invalid latex code. coarse or 2: Detect changes within equations marked up with a coarse - granularity; changes in equation type (e.g.displaymath to equation) + granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] fine or 3: Detect small change in equations and mark up and fine granularity. This mode is most suitable, if only minor changes to equations are - expected, e.g. correction of typos. + expected, e.g. correction of typos. --graphics-markup=level Change highlight style for graphics embedded with \\includegraphics commands Possible values for level: none,off or 0: no highlighting for figures new-only or 1: surround newly added or changed figures with a blue frame [Default] - both or 2: highlight new figures with a blue frame and show deleted figures + both or 2: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable SCALEDELGRAPHICS to set size of deleted figures. - Note that changes to the optional parameters will make the figure appear as changed + Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. In some circumstances "Misplaced \\noalign" errors can occur if there are certain types - of changes in tables. In this case please use option --graphics-markup=none as a - work-around. + of changes in tables. In this case please use option --graphics-markup=none as a + work-around. ---no-del Suppress deleted text from the diff. It is similar in effect to the BOLD style, +--no-del Suppress deleted text from the diff. It is similar in effect to the BOLD style, but the deleted text ist not just invisible in the output, it is also not included in the - diff text file. This can be more robust than just making it invisible. + diff text file. This can be more robust than just making it invisible. ---disable-citation-markup ---disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles +--disable-citation-markup +--disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR) (the two options are identical and are simply aliases) --enable-citation-markup ---enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections +--enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections with \\mbox command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) @@ -4246,14 +4287,14 @@ Miscellaneous options --no-label Suppress inclusion of old and new file names as comment in output file ---visible-label Include old and new filenames (or labels set with --label option) as +--visible-label Include old and new filenames (or labels set with --label option) as visible output --flatten Replace \\input and \\include commands within body by the content of the files in their argument. If \\includeonly is present in the - preamble, only those files are expanded into the document. However, - no recursion is done, i.e. \\input and \\include commands within - included sections are not expanded. The included files are assumed to + preamble, only those files are expanded into the document. However, + no recursion is done, i.e. \\input and \\include commands within + included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, respectively, making it possible to organise files into old and new directories. --flatten is applied recursively, so inputted files can contain further @@ -4276,7 +4317,7 @@ Miscellaneous options -h Show this help text. --ignore-warnings Suppress warnings about inconsistencies in length between input - and parsed strings and missing characters. + and parsed strings and missing characters. --verbose -V Output various status information to stderr during processing. @@ -4288,10 +4329,10 @@ Internal options: These options are mostly for automated use by latexdiff-vc. They can be used directly, but the API should be considered less stable than for the other options. ---no-links Suppress generation of hyperreferences, used for minimal diffs +--no-links Suppress generation of hyperreferences, used for minimal diffs (option --only-changes of latexdiff-vc). EOF - exit 0; + exit 0; } =head1 NAME @@ -4317,8 +4358,8 @@ be real files (not pipes or similar) as they are opened twice (unless C<--encodi The program treats the preamble differently from the main document. Differences between the preambles are found using line-based differencing (similarly to the Unix diff command, but ignoring white -spaces). A comment, "S<C<%DIF E<gt>>>" is appended to each added line, i.e. a -line present in C<new.tex> but not in C<old.tex>. Discarded lines +spaces). A comment, "S<C<%DIF E<gt>>>" is appended to each added line, i.e. a +line present in C<new.tex> but not in C<old.tex>. Discarded lines are deactivated by prepending "S<C<%DIF E<lt>>>". Changed blocks are preceded by comment lines giving information about line numbers in the original files. Where there are insignificant differences, the resulting file C<diff.tex> will be similar to @@ -4371,7 +4412,7 @@ curly braces immediately following a command (i.e. a sequence of letters beginning with a backslash) are arguments for that command. As a restriction to condition 1 above it is thus necessary to surround all arguments with curly braces, and to not insert -extraneous spaces. For example, write +extraneous spaces. For example, write \section{\textem{This is an emphasized section title}} @@ -4403,7 +4444,7 @@ but the choice is yours. Any markup within the environment will be removed, and generally everything within the environment will just be taken from the new file. -It is also possible to difference files which do not have a preamble. +It is also possible to difference files which do not have a preamble. In this case, the file is processed in the main document mode, but the definitions of the markup commands are not inserted. @@ -4421,7 +4462,7 @@ the scope of C<\DIFadd>. Added comments are marked by prepending Within deleted blocks text is highlighted with C<\DIFdel>. Deleted comments are marked by prepending "S<C<%DIF E<lt> >>". Non-safe command -and curly braces within deleted blocks are commented out with +and curly braces within deleted blocks are commented out with "S<C<%DIFDELCMD E<lt> >>". @@ -4431,7 +4472,7 @@ and curly braces within deleted blocks are commented out with =head2 Preamble The following options determine the visual markup style by adding the appropriate -command definitions to the preamble. See the end of this section for a description of +command definitions to the preamble. See the end of this section for a description of available styles. =over 4 @@ -4441,15 +4482,16 @@ B<-t markupstyle> Add code to preamble for selected markup style. This option defines C<\DIFadd> and C<\DIFdel> commands. -Available styles: +Available styles: -C<UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE -CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT> +C<UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE +CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT +LUAUNDERLINE> [ Default: C<UNDERLINE> ] =item B<--subtype=markstyle> or -B<-s markstyle> +B<-s markstyle> Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin). This option defines @@ -4462,27 +4504,27 @@ Available styles: C<SAFE MARGIN COLOR DVIPSCOL ZLABEL ONLYCHANGEDPAGE (LABEL)*> =item B<--floattype=markstyle> or B<-f markstyle> -Add code to preamble for selected style which +Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats -so marginal marking can be disabled thus). This option defines all +so marginal marking can be disabled thus). This option defines all C<\DIF...FL> commands. Available styles: C<FLOATSAFE TRADITIONALSAFE IDENTICAL> [ Default: C<FLOATSAFE> ] -=item B<--encoding=enc> or +=item B<--encoding=enc> or B<-e enc> Specify encoding of old.tex and new.tex. Typical encodings are -C<ascii>, C<utf8>, C<latin1>, C<latin9>. A list of available encodings can be -obtained by executing +C<ascii>, C<utf8>, C<latin1>, C<latin9>. A list of available encodings can be +obtained by executing C<perl -MEncode -e 'print join ("\n",Encode->encodings( ":all" )) ;' > If this option is used, then old.tex, new.tex are only opened once. [Default encoding is utf8 unless the first few lines of the preamble contain -an invocation C<\usepackage[..]{inputenc}> in which case the +an invocation C<\usepackage[..]{inputenc}> in which case the encoding chosen by this command is asssumed. Note that ASCII (standard latex) is a subset of utf8] @@ -4499,7 +4541,7 @@ C<\DIFaddbeginFL, \DIFaddendFL, \DIFaddFL{..}, (If this option is set B<-t>, B<-s>, and B<-f> options are ignored.) -=item B<--packages=pkg1,pkg2,..> +=item B<--packages=pkg1,pkg2,..> Tell latexdiff that .tex file is processed with the packages in list loaded. This is normally not necessary if the .tex file includes the @@ -4510,13 +4552,13 @@ The following packages trigger special behaviour: =over 8 -=item C<endfloat> +=item C<endfloat> Ensure that C<\begin{figure}> and C<\end{figure}> always appear by themselves on a line. =item C<hyperref> -Change name of C<\DIFadd> and C<\DIFdel> commands to C<\DIFaddtex> and C<\DIFdeltex> and +Change name of C<\DIFadd> and C<\DIFdel> commands to C<\DIFaddtex> and C<\DIFdeltex> and define new C<\DIFadd> and C<\DIFdel> commands, which provide a wrapper for these commands, using them for the text but not for the link defining command (where any markup would cause errors). @@ -4568,17 +4610,17 @@ B<-A exclude-file> or B<--exclude-safecmd="cmd1,cmd2,..."> =item B<--replace-safecmd=replace-file> -=item B<--append-safecmd=append-file> or +=item B<--append-safecmd=append-file> or B<-a append-file> or B<--append-safecmd="cmd1,cmd2,..."> Exclude from, replace or append to the list of regular expressions (RegEx) -matching commands which are safe to use within the +matching commands which are safe to use within the scope of a C<\DIFadd> or C<\DIFdel> command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are -ignored). Note that the RegEx needs to match the whole of +ignored). Note that the RegEx needs to match the whole of the token, i.e., /^regex$/ is implied and that the initial -"\" of the command is not included. -The B<--exclude-safecmd> and B<--append-safecmd> options can be combined with the -B<--replace-safecmd> +"\" of the command is not included. +The B<--exclude-safecmd> and B<--append-safecmd> options can be combined with the -B<--replace-safecmd> option and can be used repeatedly to add cumulatively to the lists. B<--exclude-safecmd> and B<--append-safecmd> can also take a comma separated list as input. If a @@ -4591,7 +4633,7 @@ B<-X exclude-file> or B<--exclude-textcmd="cmd1,cmd2,..."> =item B<--replace-textcmd=replace-file> -=item B<--append-textcmd=append-file> or +=item B<--append-textcmd=append-file> or B<-x append-file> or B<--append-textcmd="cmd1,cmd2,..."> Exclude from, replace or append to the list of regular expressions @@ -4599,7 +4641,7 @@ matching commands whose last argument is text. See entry for B<--exclude-safecmd> directly above for further details. -=item B<--replace-context1cmd=replace-file> +=item B<--replace-context1cmd=replace-file> =item B<--append-context1cmd=append-file> or @@ -4608,11 +4650,11 @@ entry for B<--exclude-safecmd> directly above for further details. Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. C<\caption> will only work within a figure -or table. These commands behave like text commands, except when +or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. -=item B<--replace-context2cmd=replace-file> +=item B<--replace-context2cmd=replace-file> =item B<--append-context2cmd=append-file> or @@ -4622,9 +4664,9 @@ As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. -context2 commands are also the only commands in the preamble, whose argument will be processed in +context2 commands are also the only commands in the preamble, whose argument will be processed in word-by-word mode (which only works, if they occur no more than once in the preamble). The algorithm currently cannot cope with repeated context2 commands in the preamble, as they occur e.g. for the C<\author> argument in some journal styles (not in the standard styles, though -If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use C<--replace-context2cmd> option to just select the commands, which should be processed and are not used repeatedly in the preamble. +If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use C<--replace-context2cmd> option to just select the commands, which should be processed and are not used repeatedly in the preamble. @@ -4633,7 +4675,7 @@ If such a repetition is detected, the whole preamble will be processed in line-b =item B<--append-mboxsafecmd=append-file> or B<--append-mboxsafecmd="cmd1,cmd2,..."> Define safe commands, which additionally need to be protected by encapsulating -in an C<\mbox{..}>. This is sometimes needed to get around incompatibilities +in an C<\mbox{..}>. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE @@ -4647,7 +4689,7 @@ in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE Set configuration variables. The option can be repeated to set different variables (as an alternative to the comma-separated list). -Available variables (see below for further explanations): +Available variables (see below for further explanations): C<ARRENV> (RegEx) @@ -4677,10 +4719,10 @@ C<SCALEDELGRAPHICS> (Float) =item B<--add-to-config varenv1=pattern1,varenv2=pattern2,...> For configuration variables, which are a regular expression (essentially those ending -in ENV, COUNTERCMD and CUSTOMDIFCMD, see list above) this option provides an alternative way to modify the configuration +in ENV, COUNTERCMD and CUSTOMDIFCMD, see list above) this option provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. C<varenv> must be one of the variables listed above that take a regular -expression as argument, and pattern is any regular expression (which might need to be +expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. C<--add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote"> @@ -4700,7 +4742,7 @@ Show values of configuration variables. Combine all --show commands. -NB For all --show commands, no C<old.tex> or C<new.tex> file needs to be specified, and no +NB For all --show commands, no C<old.tex> or C<new.tex> file needs to be specified, and no differencing takes place. =back @@ -4717,29 +4759,29 @@ might get lumpeded with preceding commands) so should only be used if the default produces erroneous results. (Default requires arguments to directly follow each other without intervening spaces). -=item B<--math-markup=level> +=item B<--math-markup=level> -Determine granularity of markup in displayed math environments: +Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): -C<off> or C<0>: suppress markup for math environments. Deleted equations will not -appear in diff file. This mode can be used if all the other modes +C<off> or C<0>: suppress markup for math environments. Deleted equations will not +appear in diff file. This mode can be used if all the other modes cause invalid latex code. C<whole> or C<1>: Differencing on the level of whole equations. Even trivial changes -to equations cause the whole equation to be marked changed. This -mode can be used if processing in coarse or fine mode results in +to equations cause the whole equation to be marked changed. This +mode can be used if processing in coarse or fine mode results in invalid latex code. C<coarse> or C<2>: Detect changes within equations marked up with a coarse -granularity; changes in equation type (e.g.displaymath to equation) +granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] C<fine> or C<3>: Detect small change in equations and mark up at fine granularity. This mode is most suitable, if only minor changes to equations are -expected, e.g. correction of typos. +expected, e.g. correction of typos. =item B<--graphics-markup=level> @@ -4751,33 +4793,33 @@ C<none>, C<off> or C<0>: no highlighting for figures C<new-only> or C<1>: surround newly added or changed figures with a blue frame [Default if graphicx package loaded] -C<both> or C<2>: highlight new figures with a blue frame and show deleted figures at reduced +C<both> or C<2>: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable SCALEDELGRAPHICS to set size of deleted figures. -Note that changes to the optional parameters will make the figure appear as changed +Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. In some circumstances "Misplaced \noalign" error can occur if there are certain types -of changes in tables. In this case please use C<--graphics-markup=none> as a -work-around. +of changes in tables. In this case please use C<--graphics-markup=none> as a +work-around. -=item B<--no-del> +=item B<--no-del> -Suppress deleted text from the diff. It is similar in effect to the BOLD style, -but the deleted text ist not just invisible in the output, it is also not included in the diff text file. -This can be more robust than just making it invisible. +Suppress deleted text from the diff. It is similar in effect to the BOLD style, +but the deleted text ist not just invisible in the output, it is also not included in the diff text file. +This can be more robust than just making it invisible. =item B<--disable-citation-markup> or B<--disable-auto-mbox> -Suppress citation markup and markup of other vulnerable commands in styles +Suppress citation markup and markup of other vulnerable commands in styles using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR) (the two options are identical and are simply aliases) =item B<--enable-citation-markup> or B<--enforce-auto-mbox> -Protect citation commands and other vulnerable commands in changed sections +Protect citation commands and other vulnerable commands in changed sections with C<\mbox> command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) @@ -4823,18 +4865,18 @@ Suppress inclusion of old and new file names as comment in output file =item B<--visible-label> -Include old and new filenames (or labels set with C<--label> option) as +Include old and new filenames (or labels set with C<--label> option) as visible output. =item B<--flatten> Replace C<\input> and C<\include> commands within body by the content of the files in their argument. If C<\includeonly> is present in the -preamble, only those files are expanded into the document. However, -no recursion is done, i.e. C<\input> and C<\include> commands within -included sections are not expanded. The included files are assumed to +preamble, only those files are expanded into the document. However, +no recursion is done, i.e. C<\input> and C<\include> commands within +included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, -respectively, making it possible to organise files into old and new directories. +respectively, making it possible to organise files into old and new directories. --flatten is applied recursively, so inputted files can contain further C<\input> statements. Also handles files included by the import package (C<\import> and C<\subimport>), and C<\subfile> command. @@ -4881,7 +4923,7 @@ Suppress generation of hyperreferences, used for minimal diffs (option --only-ch =back -=head2 Predefined styles +=head2 Predefined styles =head2 Major types @@ -4894,9 +4936,14 @@ The major type determine the markup of plain text and some selected latex comman Added text is wavy-underlined and blue, discarded text is struck out and red (Requires color and ulem packages). Overstriking does not work in displayed math equations such that deleted parts of equation are underlined, not struck out (this is a shortcoming inherent to the ulem package). +=item C<LUAUNDERLINE> + +Added text is underlined and blue, discarded text is struck out and red +(Requires lua-ul package + LuaLaTeX). + =item C<CTRADITIONAL> -Added text is blue and set in sans-serif, and a red footnote is created for each discarded +Added text is blue and set in sans-serif, and a red footnote is created for each discarded piece of text. (Requires color package) =item C<TRADITIONAL> @@ -4937,13 +4984,13 @@ Added text is set in bold face, discarded is not shown. (also see --no-del optio =item C<PDFCOMMENT> -The pdfcomment package is used to underline new text, and mark deletions with a PDF comment. Note that this markup might appear differently or not at all based on the pdf viewer used. The viewer with best support for pdf markup is probably acroread. This style is only recommended if the number of differences is small. +The pdfcomment package is used to underline new text, and mark deletions with a PDF comment. Note that this markup might appear differently or not at all based on the pdf viewer used. The viewer with best support for pdf markup is probably acroread. This style is only recommended if the number of differences is small. =back =head2 Subtypes -The subtype defines the commands that are inserted at the begin and end of added or discarded blocks, irrespectively of whether these blocks contain text or commands (Defined commands: C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>) +The subtype defines the commands that are inserted at the begin and end of added or discarded blocks, irrespectively of whether these blocks contain text or commands (Defined commands: C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>) =over 10 @@ -4961,7 +5008,7 @@ from the intended position. An alternative way of marking added passages in blue, and deleted ones in red. (It is recommeneded to use instead the main types to effect colored markup, -although in some cases coloring with dvipscol can be more complete, for example +although in some cases coloring with dvipscol can be more complete, for example with citation commands). =item C<DVIPSCOL> @@ -4976,12 +5023,12 @@ although in some cases coloring with dvipscol can be more complete). can be used to highlight only changed pages, but requires post-processing. It is recommend to not call this option manually but use C<latexdiff-vc> with C<--only-changes> option. Alternatively, use the script given within preamble of diff files made using this style. -=item C<ONLYCHANGEDPAGE> +=item C<ONLYCHANGEDPAGE> also highlights changed pages, without the need for post-processing, but might not work reliably if there is floating material (figures, tables). -=item C<LABEL> +=item C<LABEL> is similar to C<ZLABEL>, but does not need the zref package and works less reliably (deprecated). @@ -4989,7 +5036,7 @@ is similar to C<ZLABEL>, but does not need the zref package and works less relia =head2 Float Types -Some of the markup used in the main text might cause problems when used within +Some of the markup used in the main text might cause problems when used within floats (e.g. figures or tables). For this reason alternative versions of all markup commands are used within floats. The float type defines these alternative commands. @@ -5016,7 +5063,7 @@ Make no difference between the main text and floats. =item C<ARRENV> -If a match to C<ARRENV> is found within an inline math environment within a deleted or added block, then the inlined math +If a match to C<ARRENV> is found within an inline math environment within a deleted or added block, then the inlined math is surrounded by C<\mbox{>...C<}>. This is necessary as underlining does not work within inlined array environments. [ Default: C<ARRENV>=S<C<(?:array|[pbvBV]matrix)> > @@ -5036,9 +5083,9 @@ C<|subsubsection|paragraph|subparagraph)> ] This option is for advanced users and allows definition of special versions of commands, which do not work as safe commands. Commands in C<CUSTOMDIFCMD> that occur in added or deleted blocks will be given an ADD or DEL prefix. -The prefixed versions of the command must be defined in the preamble, either by putting them +The prefixed versions of the command must be defined in the preamble, either by putting them in the preamble of at least the new file, or by creating a custom preamble file (Option --preamble). -For example the command C<\blindtext> (from package blindtext) does not interact well with underlining, so that +For example the command C<\blindtext> (from package blindtext) does not interact well with underlining, so that for the standard markup type, it is not satisfactory to define it as a safe command. Instead, a customised versions without underlining can be defined in the preamble: @@ -5052,7 +5099,7 @@ and then latexdiff should be invoked with the option C<-c CUSTOMDIFCMD=blindtext =item C<FLOATENV> -Environments whose name matches the regular expression in C<FLOATENV> are +Environments whose name matches the regular expression in C<FLOATENV> are considered floats. Within these environments, the I<latexdiff> markup commands are replaced by their FL variaties. @@ -5101,17 +5148,17 @@ If C<--graphics-markup=both> is chosen, C<SCALEDELGRAPHICS> is the factor, by wh =item C<VERBATIMENV> -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: deleted content is commented out, new content is not marked up [ Default: S<C<comment> > ] =item C<VERBATIMLINEENV> -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by VERBATIMLINEENV are compared in +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by VERBATIMLINEENV are compared in line mode, and changes are marked up using the listings package. The markup style is set based on the chosen mains markup type (Option -t), or on an analysis of the preamble. -Note that "listings.sty" must be installed. If this file is not found the fallback solution is to +Note that "listings.sty" must be installed. If this file is not found the fallback solution is to treat VERBATIMLINEENV environments treated exactly the same way as VERBATIMENV environments. [ Default: S<C<(?:verbatim[*]?|lstlisting> > ] @@ -5122,30 +5169,40 @@ treat VERBATIMLINEENV environments treated exactly the same way as VERBATIMENV e =over 10 -=item Citations result in overfull boxes +=item Changed citations result in overfull boxes There is an incompatibility between the C<ulem> package, which C<latexdiff> uses for underlining and striking out in the UNDERLINE style, -the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an C<\mbox> -command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have two possibilities. +the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an C<\mbox> +command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have several possibilities. 1. Use C<CFONT> type markup (option C<-t CFONT>): If this markup is chosen, then changed citations are no longer marked up -with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the C<ulem> package will also work. +with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the C<ulem> package will also work. 2. Choose option C<--disable-citation-markup> which turns off the marking up of citations: deleted citations are no longer shown, and -added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older) - +added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older). For custom packages you can define the commands which need to be protected by C<\mbox> with C<--append-mboxsafecmd> and C<--excludemboxsafecmd> options (submit your lists of command as feature request at github page to set the default behaviour of future versions, see section 6) -=item Changes in complicated mathematical equations result in latex processing errors +3. If you are using luatex >= 1.12.0 you can use option LUAUNDERLINE that uses lua-ul instead of ulem for underlining, which does not have this problem (experimental feature). + +=item Changes in complicated mathematical equations result in latex processing errors. + +Try option C<--math-markup=whole>. If even that fails, you can turn off mark up for equations with C<--math-markup=off>. -Try options C<--math-markup=whole>. If even that fails, you can turn off mark up for equations with C<--math-markup=off>. +=item Deleted parts in equations are not struck out but underlined. -=item How can I just show the pages where changes had been made +This is a limitation of the ulem package that implements the strike-out. If you use the amsmath package, then the strike-out command is redefined in such a way that deleted passages are wrapped with C<\text> command; adding C<\usepackage{amsmath}> to your preamble will trigger this behaviour. (If amsmath is not included directly, but imported by another package, latexdiff will not be able to detect its availability; in this case you can give latexdiff a hint with option C<--packages=amsmath>. -Use options -C<-s ZLABEL> (some postprocessing required) or C<-s ONLYCHANGEDPAGE>. C<latexdiff-vc --ps|--pdf> with C<--only-changes> option takes care of + +=item How can I just show the pages where changes had been made? + +Use options C<--s ZLABEL> (some postprocessing required) or C<-s ONLYCHANGEDPAGE>. C<latexdiff-vc --ps|--pdf> with C<--only-changes> option takes care of the post-processing for you (requires zref package to be installed). +=item The character encoding breaks when running latexdiff from powershell. + +This problem is not limited to C<latexdiff> and has to do with the default settings of C<powershell> in Windows. It is recommended to use C<cmd> instead. + =back =head1 BUGS @@ -5158,13 +5215,13 @@ different numbers of inter-argument spaces are treated as significant. =back -Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, +Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, or send them to I<tilmann -- AT -- gfz-potsdam.de>. Include the version number of I<latexdiff> (from comments at the top of the source or use B<--version>). If you come across latex files that are error-free and conform to the specifications set out above, and whose differencing still does not result in error-free latex, please send me those files, ideally edited to only contain the -offending passage as long as that still reproduces the problem. If your +offending passage as long as that still reproduces the problem. If your file relies on non-standard class files, you must include those. I will not look at examples where I have trouble to latex the original files. @@ -5175,24 +5232,24 @@ L<latexrevise>, L<latexdiff-vc> =head1 PORTABILITY I<latexdiff> does not make use of external commands and thus should run -on any platform supporting Perl 5.6 or higher. If files with encodings +on any platform supporting Perl 5.6 or higher. If files with encodings other than ASCII or UTF-8 are processed, Perl 5.8 or higher is required. The standard version of I<latexdiff> requires installation of the Perl package -C<Algorithm::Diff> (available from I<www.cpan.org> - +C<Algorithm::Diff> (available from I<www.cpan.org> - I<http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15>) but a stand-alone version, I<latexdiff-so>, which has this package inlined, is available, too. I<latexdiff-fast> requires the I<diff> command to be present. =head1 AUTHOR -Version 1.3.3 -Copyright (C) 2004-2022 Frederik Tilmann +Version 1.3.4 +Copyright (C) 2004-2024 Frederik Tilmann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 -Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, +Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, T. Connors, Sebastian Gouezel and many others. Thanks to the many people who sent in bug reports, feature suggestions, and other feedback. @@ -5463,13 +5520,14 @@ value underline sqrt (SUPER|SUB)SCRIPT -%%END TEXT COMMANDS +%%END TEXT COMMANDS %%BEGIN CONTEXT1 COMMANDS % Regex matching commands with a text argument (leave out the \), which will fail out of context. These commands behave like text commands, except when they occur in a deleted section, where they are disabled, but their argument is shown as deleted text. caption subcaption -%%END CONTEXT1 COMMANDS +multicolumn +%%END CONTEXT1 COMMANDS %%BEGIN CONTEXT2 COMMANDS % Regex matching commands with a text argument (leave out the \), which will fail out of context. As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. @@ -5477,7 +5535,7 @@ title author date institute -%%END CONTEXT2 COMMANDS +%%END CONTEXT2 COMMANDS %% CONFIGURATION variabe defaults %%BEGIN LISTENV CONFIG @@ -5555,9 +5613,16 @@ verbatim[*]? \RequirePackage[normalem]{ulem} \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} \providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}} -\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} +\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} %DIF END UNDERLINE PREAMBLE +%DIF LUAUNDERLINE PREAMBLE +\RequirePackage{lua-ul} +\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} +\providecommand{\DIFadd}[1]{{\protect\color{blue}\underLine{#1}}} +\providecommand{\DIFdel}[1]{{\protect\color{red}\strikeThrough{#1}}} +%DIF END LUAUNDERLINE PREAMBLE + %DIF CTRADITIONAL PREAMBLE \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} \RequirePackage[stable]{footmisc} @@ -5729,7 +5794,7 @@ verbatim[*]? % To show only pages with changes (dvips/dvipdf) % latex diff.tex % latex diff.tex -% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi +% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi \typeout{Check comments in preamble of output for instructions how to show only pages where changes have been made} \usepackage[user,abspage]{zref} \newcount\DIFcounterb @@ -5749,10 +5814,10 @@ verbatim[*]? \RequirePackage{etoolbox} \RequirePackage{zref} % redefine label command to write immediately to aux file - page references will be lost -\makeatletter \let\oldlabel\label% Store \label -\renewcommand{\label}[1]{% Update \label to write to the .aux immediately -\zref@wrapper@immediate{\oldlabel{#1}}} -\makeatother +\makeatletter \let\oldlabel\label% Store \label +\renewcommand{\label}[1]{% Update \label to write to the .aux immediately +\zref@wrapper@immediate{\oldlabel{#1}}} +\makeatother \newbool{DIFkeeppage} \newbool{DIFchange} \boolfalse{DIFkeeppage} @@ -5770,7 +5835,7 @@ verbatim[*]? \providecommand{\DIFmodend}{\global\booltrue{DIFkeeppage}\global\boolfalse{DIFchange}} %DIF END ONLYCHANGEDPAGE PREAMBLE -%% FLOAT TYPES +%% FLOAT TYPES %DIF FLOATSAFE PREAMBLE \providecommand{\DIFaddFL}[1]{\DIFadd{#1}} @@ -5802,7 +5867,7 @@ verbatim[*]? %DIF END TRADITIONALSAFE PREAMBLE % see: -% http://tex.stackexchange.com/questions/47351/can-i-redefine-a-command-to-contain-itself +% http://tex.stackexchange.com/questions/47351/can-i-redefine-a-command-to-contain-itself %DIF HIGHLIGHTGRAPHICS PREAMBLE \RequirePackage{settobox} @@ -5848,6 +5913,15 @@ verbatim[*]? %% SPECIAL PACKAGE PREAMBLE COMMANDS +%% Redefine strike out command to wrap in text box if amsmath is used and markup style with ulem is used +%DIF AMSMATHULEM PREAMBLE +\makeatletter +\let\sout@orig\sout +\renewcommand{\sout}[1]{\ifmmode\text{\sout@orig{\ensuremath{#1}}}\else\sout@orig{#1}\fi} +\makeatother +%DIF END AMSMATHULEM PREAMBLE + + % Standard \DIFadd and \DIFdel are redefined as \DIFaddtex and \DIFdeltex % when hyperref package is included. %DIF HYPERREF PREAMBLE @@ -5950,7 +6024,7 @@ verbatim[*]? %DIF END DIFCODE_BOLD %DIF DIFCODE_PDFCOMMENT - + moredelim=[il][\color{white}\tiny]{\%DIF\ <\ }, moredelim=[il][\sffamily\bfseries]{\%DIF\ >\ } %DIF END DIFCODE_PDFCOMMENT diff --git a/support/latexdiff/latexdiff-so b/support/latexdiff/latexdiff-so index b3571d27b2..9ab8e4169b 100755 --- a/support/latexdiff/latexdiff-so +++ b/support/latexdiff/latexdiff-so @@ -25,6 +25,21 @@ # # Note references to issue numbers are for the github repository of latexdiff: https://github.com/ftilmann/latexdiff # +# Version 1.3.4: +# New features: +# - Option to use lua-ul instead of ulem (for use with LuaLaTeX) (fix #17, #60, #188, #255, #270) +# Enhancement +# - If amsmath is detected as one of the included (based on idea in PR #263 contributed by github user xlucn +# Bug fix +# - sometimes the introduction of aux commands to show deleted lists or descriptions leaves in place empty auxiliary +# list environments, which would cause error messages (though skipping messages would result in a correct output pdf). +# These are now removed. +# - add more mboxsafecmd and safecmd commands for SIunitx to stay compatible with newer versionsof SIunitx (PR #283, fixing issue #282, contributed by github user joe6302413) +# - File added via --preamble option is no longer assumed to be ASCII, but read either with encoding as defined by --encoding option or using the encoding of the LOCALE (fixes issue #285 ) +# - multicolumn argument is now treated as text +# - when tikz-dependency package is used, \& is no longer a safe command as it has special meaning inside dependency environment. The fix is a little of a hack as really it should only be considered unsafe within dependency environment (fixes (mostly) issue #303 ) +# - listings package had trouble with non-ASCII chars. The encoding is now set (thanks to github user anka-213 for finding this). Fixes #304 +# # Version 1.3.3: # New features: # - Option --no-del to remove all deleted text (merge contributed by github user tdegeus PR #252, fixing issue #66 @@ -33,22 +48,22 @@ # - Abbreviations involving punctuations within them. They need special treatment because otherwise in some # circumstances the gnoring of white space differences in conjunction with merging according to MINWORDSBLOCK rule # could turn 'i.e.' into 'i.\PAR e.' (see https://github.com/ftilmann/latexdiff/issues/269). A few abbreviations -# are now hard-coded and treated as atomic: +# are now hard-coded and treated as atomic: # English: i.e., e.g. Deutsch: z.B. # (fixes issue #269) # - In WHOLE and COARSE math modes, now properly treat math environments with arguments such as \alignat. Fixes #251 -# - For FINE math mode, multiple improvments to the processing work flow yield more robust outcomes. In particular, changes -# to the equation type, e.g. \begin{displaymath} -> \begin{equation} without modifications now usually no longer result -# in errors. (Partially) fixes issues #235 and #244. -# - When encountering deleted math array environments such as align or eqnarray, rather than replacing them with a -# fixed replacement environment (e.g. align* or eqnarray*), an asterisk is now added to the original command, which +# - For FINE math mode, multiple improvments to the processing work flow yield more robust outcomes. In particular, changes +# to the equation type, e.g. \begin{displaymath} -> \begin{equation} without modifications now usually no longer result +# in errors. (Partially) fixes issues #235 and #244. +# - When encountering deleted math array environments such as align or eqnarray, rather than replacing them with a +# fixed replacement environment (e.g. align* or eqnarray*), an asterisk is now added to the original command, which # in amsmath (and with eqnarray) will result in the same environment but without line numbers. Config variable MATHARRREPL # is therefore (nearly) redundant, and a depracation warning is given when it is set. Reference to MATHARRREPL are have # been removed from the manual (there is one exception, when it's still being used: sometimes latexdiff can figure out # that there is a deleted array environment, but does not know which one. In this case, MATHARRREPL is still being used -# to encapsulate these parts of the source, and therefore it is still set internally. But this is a quite rare situation). +# to encapsulate these parts of the source, and therefore it is still set internally. But this is a quite rare situation). # Fixes issue #216 -# - Unlike 'array' environment, 'split' (amsmath) does not work in argument of \DIFadd or \DIFdl in UNDERLINE modes; therefore remove it from ARRENV configuration variable. +# - Unlike 'array' environment, 'split' (amsmath) does not work in argument of \DIFadd or \DIFdl in UNDERLINE modes; therefore remove it from ARRENV configuration variable. # Exclude \begin and \end in math environments in COARSE and WHOLE modes. Fixes #258. Fixes #109 # - --flatten now works for empty files. Fixes issue #242 # - improved processing of Chinese and Japanese texts in that splitting is done based on characters. Thanks to LuXu (Oliver Lew) in git for working this out. Fixes #229, fixes #145 @@ -65,7 +80,7 @@ # Bug fixes: # - fix issue #206 affecting proper markup of text commands which are not also safe cmd's and have multiple arguments # - fix issue #210 by adding \eqref (amsmath package) to the list of safe commands -# - fix bug reported in issue #168 mangled verbatim line environment +# - fix bug reported in issue #168 mangled verbatim line environment # - fix bug reported in issue #218 by replacing \hspace{0pt} after \mbox{..} auxiliary commands with \hskip0pt. # - more ways to process \frac correctly with atomic arguments (committed by julianuu PR #246 # - fix a bug in biblatex mode, which prevented proper processing of modified \textcite (see: https://tex.stackexchange.com/questions/555157/latexdiff-and-biblatex-citation-commands) @@ -74,10 +89,10 @@ # Version 1.3.1.1 # - remove spurious \n to fix error: Unknown regexp modifier "/n" at .../latexdiff line 1974, near "=~ " (see github issue #201) # -# Version 1.3.1 +# Version 1.3.1 # Bug fixes: # - remove some uninitialised variable $2 warnings in string substitution in flatten function in case included file is not found -# - add minimal postprocessing to diff processing of preamble commands (replace \RIGHTBRACE by \} ) +# - add minimal postprocessing to diff processing of preamble commands (replace \RIGHTBRACE by \} ) # - pre-processing: replace (contributed) routine take_comments_and_enter_from_frac() with take_comments_and_newline_from_frac(), which does the same thing # (remove whitespace characters and comments between the argument of \frac commands) in an easier and more robust way. In addition, it # will replace commands like \frac12 with \frac{1}{2} as pre-processing step. Fixes issue #184 @@ -95,15 +110,15 @@ # Version 1.3.0 (7 October 2018): # - treat options to \documentclass as potential package names (some packages allow implicit loading of or imply selected packages # - improved pattern matching: now allows nested angular brackets, and is no longer confused by escaped curly braces -# - improved pattern matching in COARSE mode: occasionally, the closing bracket or some other elements would be matched in an 'unnatural' way due to another sequence being more minimal in the computational sense, sometimes even causing errors due to tokens moving in or out of the scope of math environments. This is now discouraged by adding internal \DIFANCHOR commands (which are removed again in post-processing) (fixes issues reported via email by li_ruomeng . +# - improved pattern matching in COARSE mode: occasionally, the closing bracket or some other elements would be matched in an 'unnatural' way due to another sequence being more minimal in the computational sense, sometimes even causing errors due to tokens moving in or out of the scope of math environments. This is now discouraged by adding internal \DIFANCHOR commands (which are removed again in post-processing) (fixes issues reported via email by li_ruomeng . # - verbatim and lstlisting environments are marked-up with line-by-line in a similar style to non-verbatim text (requires the listing package to be installed) # (see new configuration variable VERBATIMLINEENV) (several issues and pull requests by jprotze) -# - --flatten: now supports \verbatiminput and \lstlistinput +# - --flatten: now supports \verbatiminput and \lstlistinput # - --flatten: if file is not found, do not fail, simply warn and leave command unexpanded (inspired by issue #112). Don't warn if file name contains #[0-9] as it is then most likely an argument within a command definition rather than an actual file (applies to \input, \subfile, \include commands) # - added to textcmds: \intertext # - new config variable CUSTOMDIFCMD to allow defining special versions of commands in added or deleted blocks (Pull request by github user jprotze) # - added option -no-links (mostly for use by latexdiff-vc in only-changes modes) (Pull request by github user jprotze) -# - new option --filter-script to run both input through a pre-processing script (PR jasonmccsmith #167) +# - new option --filter-script to run both input through a pre-processing script (PR jasonmccsmith #167) # new option --no-filter-stderr to hide stderr output from filter-script (potentially dangerous, as this might hide malfunctioning of filter scripts) # - --flatten now can deal with imports made using the import package {PR jasonmccsmith #173) # Bug fixes: @@ -122,12 +137,12 @@ # make environments that are treated like verbatim environments configurable (config variable VERBATIMENV) # treat lstinlne as equivalent to verb command # partially addresses issue #38 -# - refactoring: set default configuration variables in a hash, and those that correspond to lists +# - refactoring: set default configuration variables in a hash, and those that correspond to lists # - feature: option --add-to-config used to amend configuration variables, which are regex pattern lists # - bug fix: deleted figures when endfloat package is activated # - bug fix: alignat environment now always processed correctly (fix issues #65) # - bug fix: avoid processing of commands as potential files in routine init_regex_arr (fix issue #70 ) -# - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be +# - minimal feature enhancement: treat '@' as allowed character in commands (strictly speaking requires prior \makeatletter statement, but always assuming it to be # @ a letter if it is part of a command name will usually lead to the correct behaviour (see http://tex.stackexchange.com/questions/346651/latexdiff-and-let) # - new feature/bug fix: --flatten option \endinput in included files now respected but only if \endinput stands right at the beginning of the line (issue #77) # - bug fix: flatten would incorrectly attempt to process commented out \include commands (from discussion in issue #77 ) @@ -165,7 +180,7 @@ # - introduce list UNSAFEMATHCMD, which holds list of commands which cannot be marked up with \DIFadd or \DIFdel commands (only relevant for WHOLE and COARSE math markup modes) # - new subtype LABEL which gives each change a label. This can later be used to only display pages where changes # have been made (instructions for that are put as comments into the diff'ed file) inspired by answer on http://tex.stackexchange.com/questions/166049/invisible-markers-in-pdfs-using-pdflatex -# - Configuration variables take into accout some commands from additional packages: +# - Configuration variables take into accout some commands from additional packages: # tikzpicture environment now treated as PICTUREENV, and \smallmatrix in ARRENV (amsmath) # - --flatten: support for \subfile command (subfiles package) (in response to http://tex.stackexchange.com/questions/167620/latexdiff-with-subfiles ) # - --flatten: \bibliography commands expand if corresponding bbl file present @@ -179,11 +194,11 @@ # - \% in one-letter sub/Superscripts was not converted correctly # # Version 1.0.3 -# - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator +# - fix bug in add_safe_commands that made latexdiff hang on DeclareMathOperator # command in preamble # - \(..\) inline math expressions were not parsed correctly, if they contained a linebreak # - applied patch contributed by tomflannaghan via Berlios: [ Patch #3431 ] Adds correct handling of \left< and \right> -# - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug +# - \$ is treated correctly as a literal dollar sign (thanks to Reed Cartwright and Joshua Miller for reporting this bug # and sketching out the solution) # - \^ and \_ are correctly interpreted as accent and underlined space, respectively, not as superscript of subscript # (thanks to Wail Yahyaoui for pointing out this bug) @@ -191,19 +206,19 @@ # Version 1.0.1 - treat \big,\bigg etc. equivalently to \left and # \right - include starred version in MATHENV - apply # - flatten recursively and --flatten expansion is now -# aware of comments (thanks to Tim Connors for patch) +# aware of comments (thanks to Tim Connors for patch) # - Change to post-processing for more reliability for # deleted math environments -# - On linux systems, recognise and remove DOS style newlines +# - On linux systems, recognise and remove DOS style newlines # - Provide markup for some special preamble commands (\title, -# \author,\date, -# - configurable by setting context2cmd +# \author,\date, +# - configurable by setting context2cmd # - for styles using ulem package, remove \emph and \text.. from list of # safe commands in order to allow linebreaks within the -# highlighted sections. -# - for ulem style, now show citations by enclosing them in \mbox commands. -# This unfortunately implies linebreaks within citations no longer function, -# so this functionality can be turned off (Option --disable-citation-markup). +# highlighted sections. +# - for ulem style, now show citations by enclosing them in \mbox commands. +# This unfortunately implies linebreaks within citations no longer function, +# so this functionality can be turned off (Option --disable-citation-markup). # With --enable-citation-markup, the mbox markup is forced for other styles) # - new substyle COLOR. This is particularly useful for marking up citations # and some special post-processing is implemented to retain cite @@ -211,11 +226,11 @@ # - four different levels of math-markup # - Option --driver for choosing driver for modes employing changebar package # - accept \\* as valid command (and other commands of form \.*). Also accept -# \<nl> (backslashed newline) +# \<nl> (backslashed newline) # - some typo fixes, include commands defined in preamble as safe commands -# (Sebastian Gouezel) +# (Sebastian Gouezel) # - include compared filenames as comments as line 2 and 3 of -# the preamble (can be modified with option --label, and suppressed with +# the preamble (can be modified with option --label, and suppressed with # --no-label), option --visible-label to show files in generated pdf or dvi # at the beginning of main document # @@ -231,7 +246,7 @@ # # Version 0.4 March 06 option for fast differencing using UNIX diff command, several minor bug fixes (\par bug, improved highlighting of textcmds) # -# Version 0.3 August 05 improved parsing of displayed math, --allow-spaces +# Version 0.3 August 05 improved parsing of displayed math, --allow-spaces # option, several minor bug fixes # # Version 0.25 October 04 Fix bug with deleted equations, add math mode commands to safecmd, add | to allowed interpunctuation signs @@ -704,12 +719,13 @@ use utf8 ; use File::Spec ; + my ($algodiffversion)=split(/ /,$Algorithm::Diff::VERSION); my ($versionstring)=<<EOF ; -This is LATEXDIFF 1.3.3 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) - (c) 2004-2022 F J Tilmann +This is LATEXDIFF 1.3.4 (Algorithm::Diff $Algorithm::Diff::VERSION, Perl $^V) + (c) 2004-2024 F J Tilmann EOF # Hash with defaults for configuration variables. These marked undef have default values constructed from list defined in the DATA block @@ -800,9 +816,9 @@ my $DELCMDOPEN='%DIFDELCMD < '; # To mark begin of deleted commands (must begin my $DELCMDCLOSE="%%%\n"; # To mark end of deleted commands (must end with a new line) my $AUXCMD='%DIFAUXCMD' ; # follows auxiliary commands put in by latexdiff to make difference file legal # auxiliary commands must be on a line of their own - # Note that for verbatim environment openings the %DIFAUXCMD cannot be placed in + # Note that for verbatim environment openings the %DIFAUXCMD cannot be placed in # the same line as this would mean they are shown - # so the special form "%DIFAUXCMD NEXT" is used to indicate that the next line + # so the special form "%DIFAUXCMD NEXT" is used to indicate that the next line # is an auxiliary command # Similarly "%DIFAUXCMD LAST" would indicate the auxiliary command is in previous line (not currently used) my $DELCOMMENT='DIF < '; # To mark deleted comment line @@ -813,21 +829,21 @@ my @TEXTCMDLIST=(); # array containing patterns of commands with text arguments my @TEXTCMDEXCL=(); # array containing patterns of commands without text arguments (if a pattern # matches both TEXTCMDLIST and TEXTCMDEXCL it is excluded) my @CONTEXT1CMDLIST=(); # array containing patterns of commands with text arguments (subset of text commands), - # but which cause confusion if used out of context (e.g. \caption). + # but which cause confusion if used out of context (e.g. \caption). # In deleted passages, the command will be disabled but its argument is marked up - # Otherwise they behave exactly like TEXTCMD's + # Otherwise they behave exactly like TEXTCMD's my @CONTEXT1CMDEXCL=(); # exclude list for above, but always empty my @CONTEXT2CMDLIST=(); # array containing patterns of commands with text arguments, but which fail or cause confusion # if used out of context (e.g. \title). They and their arguments will be disabled in deleted # passages my @CONTEXT2CMDEXCL=(); # exclude list for above, but always empty my @MATHTEXTCMDLIST=(); # treat like textcmd. If a textcmd is in deleted or added block, just wrap the - # whole content with \DIFadd or \DIFdel irrespective of content. This functionality + # whole content with \DIFadd or \DIFdel irrespective of content. This functionality # is useful for pseudo commands \MATHBLOCK.. into which math environments are being - # transformed -my @MATHTEXTCMDEXCL=(); # + # transformed +my @MATHTEXTCMDEXCL=(); # -# Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these +# Note I need to declare this with "our" instead of "my" because later in the code I have to "local"ise these our @SAFECMDLIST=(); # array containing patterns of safe commands (which do not break when in the argument of DIFadd or DIFDEL) our @SAFECMDEXCL=(); my @MBOXCMDLIST=(); # patterns for commands which are in principle safe but which need to be surrounded by an \mbox @@ -892,7 +908,7 @@ $mathmarkup=COARSE; $verbose=0; $onlyadditions=0; # output debug and intermediate files, set to 0 in final distribution -$debug=0; +$debug=0; # insert preamble directly after documentclass - experimental feature, set to 0 in final distribution # Note that this failed with mini example (or other files, where packages used in latexdiff preamble # are called again with incompatible options in preamble of resulting file) @@ -915,9 +931,9 @@ END my %verbhash; Getopt::Long::Configure('bundling'); -GetOptions('type|t=s' => \$type, - 'subtype|s=s' => \$subtype, - 'floattype|f=s' => \$floattype, +GetOptions('type|t=s' => \$type, + 'subtype|s=s' => \$subtype, + 'floattype|f=s' => \$floattype, 'config|c=s' => \@configlist, 'add-to-config=s' => \@addtoconfiglist, 'preamble|p=s' => \$preamblefile, @@ -966,11 +982,11 @@ if ( $help ) { if ( $version ) { - print STDERR $versionstring ; + print STDERR $versionstring ; exit 0; } -print STDERR $versionstring if $verbose; +print STDERR $versionstring if $verbose; if (defined($showall)){ $showpreamble=$showsafe=$showtext=$showconfig=1; @@ -988,7 +1004,7 @@ if (defined($mathmarkup)) { $mathmarkup=~tr/a-z/A-Z/; if ( $mathmarkup eq 'OFF' ){ $mathmarkup=OFF; - } elsif ( $mathmarkup eq 'WHOLE' ){ + } elsif ( $mathmarkup eq 'WHOLE' ){ $mathmarkup=WHOLE; } elsif ( $mathmarkup eq 'COARSE' ){ $mathmarkup=COARSE; @@ -1091,7 +1107,7 @@ foreach $config ( @configlist ) { } } foreach $assign ( @config ) { - $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; + $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}=$2; } @@ -1128,7 +1144,7 @@ foreach $key ( keys(%CONFIG) ) { foreach $assign ( @addtoconfig ) { ###print STDERR "assign:|$assign|\n"; - $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; + $assign=~ m/\s*(\w*)\s*=\s*(\S*)\s*$/ or die "Illegal assignment $assign in configuration list (must be variable=value)"; exists $CONFIG{$1} or die "Unknown configuration variable $1."; $CONFIG{$1}.=";$2"; } @@ -1143,8 +1159,8 @@ foreach ( keys(%CONFIG) ) { elsif ( $_ eq "MATHENV" ) { $MATHENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "MATHREPL" ) { $MATHREPL = $CONFIG{$_} ; } elsif ( $_ eq "MATHARRENV" ) { $MATHARRENV = liststringtoregex($CONFIG{$_}) ; } - elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; - print STDERR "WARNING: Setting MATHARRREPL is depracated. Generally deleted math array environments will be set to their starred varieties and the setting of MATHARREPL is ignored.\n\n" unless $MATHARRREPL =~ /eqnarray\*/ ; + elsif ( $_ eq "MATHARRREPL" ) { $MATHARRREPL = $CONFIG{$_} ; + print STDERR "WARNING: Setting MATHARRREPL is depracated. Generally deleted math array environments will be set to their starred varieties and the setting of MATHARREPL is ignored.\n\n" unless $MATHARRREPL =~ /eqnarray\*/ ; } elsif ( $_ eq "ARRENV" ) { $ARRENV = liststringtoregex($CONFIG{$_}) ; } elsif ( $_ eq "VERBATIMENV" ) { $VERBATIMENV = liststringtoregex($CONFIG{$_}) ; } @@ -1171,11 +1187,11 @@ foreach $pkg ( @packagelist ) { if ($showconfig || $showtext || $showsafe || $showpreamble) { show_configuration(); - exit 0; + exit 0; } -if ( @ARGV != 2 ) { +if ( @ARGV != 2 ) { print STDERR "2 and only 2 non-option arguments required. Write latexdiff -h to get help\n"; exit(2); } @@ -1183,7 +1199,7 @@ if ( @ARGV != 2 ) { # Are extra spaces between command arguments permissible? my $extraspace; if ($allowspaces) { - $extraspace='\s*'; + $extraspace='\s*'; } else { $extraspace=''; } @@ -1206,14 +1222,14 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # if you get "undefined control sequence MATHBLOCKmath" error, increase the maximum value in this loop for (my $i_pat = 0; $i_pat < 20; ++$i_pat){ $pat_n = '(?:[^{}]|\{'.$pat_n.'\}|\\\\\{|\\\\\})*'; - # Actually within the text body, quoted braces are replaced in pre-processing. The only place where + # Actually within the text body, quoted braces are replaced in pre-processing. The only place where # the last part of the pattern matters is when processing the arguments of context2cmds in the preamble # and these contain a \{ or \} combination, probably rare. # It should thus be fine to use the simpler version below. ### $pat_n = '(?:[^{}]|\{'.$pat_n.'\})*'; } - my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; + my $brat0 = '(?:[^\[\]]|\\\[|\\\])*'; my $brat_n = $brat0; for (my $i_pat = 0; $i_pat < 4; ++$i_pat){ $brat_n = '(?:[^\[\]]|\['.$brat_n.'\]|\\\[|\\\])*'; @@ -1230,7 +1246,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # could turn 'i.e.' into 'i.\PAR e.' (see https://github.com/ftilmann/latexdiff/issues/269) # English: i.e., e.g. Deutsch: z.B. my $abbreviation='(?:i\. ?e\.|e\. ?g\.|z\. ?B\.)' ; - my $number='-?\d*\.\d*'; + my $number='-?\d*\.\d*'; # word: sequence of letters or accents followed by letter my $word_cj='\p{Han}|\p{InHiragana}|\p{InKatakana}'; @@ -1258,7 +1274,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); # inline math $....$ or \(..\) ### the commented out version is simpler but for some reason cannot cope with newline (in spite of s option) - need to include \newline explicitly ### my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(].*?\\\\[)]'; - my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; + my $math='\$(?:[^$]|\\\$)*?\$|\\\\[(](?:.|\n)*?\\\\[)]'; ### test version (this seems to give the same results as version above) ## the current maths command cannot cope with newline within the math expression ### my $math='\$(?:[^$]|\\\$)*?\$|\\[(].*?\\[)]'; @@ -1276,7 +1292,7 @@ push(@SAFECMDLIST, qr/^QLEFTBRACE$/, qr/^QRIGHTBRACE$/); -# now we are done setting up and can start working +# now we are done setting up and can start working my ($oldfile, $newfile) = @ARGV; # check for existence of input files if ( ! -e $oldfile ) { @@ -1304,7 +1320,7 @@ my ($oldtime,$newtime,$oldlabel,$newlabel); if (defined($labels[0])) { $oldlabel=$labels[0] ; } else { - $oldtime=localtime((stat($oldfile))[9]); + $oldtime=localtime((stat($oldfile))[9]); $oldlabel="$oldfile " . " "x($oldlabel_n_spaces) . $oldtime; } if (defined($labels[1])) { @@ -1317,6 +1333,7 @@ if (defined($labels[1])) { $encoding=guess_encoding($newfile) unless defined($encoding); $encoding = "utf8" if $encoding =~ m/^utf8/i ; +print STDERR "Encoding $encoding\n" if $verbose; if (lc($encoding) eq "utf8" ) { binmode(STDOUT, ":utf8"); binmode(STDERR, ":utf8"); @@ -1400,7 +1417,7 @@ my @auxlines; my ($ulem)=0; if ( length $oldpreamble && length $newpreamble ) { - # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) + # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) # and marking up content with latexdiff markup @auxlines=preprocess_preamble($oldpreamble,$newpreamble); @@ -1432,7 +1449,7 @@ if (defined($graphicsmarkup)) { } else { # Default: no explicit setting in menu if ( defined $packages{"graphicx"} or defined $packages{"graphics"} ) { - $graphicsmarkup=NEWONLY; + $graphicsmarkup=NEWONLY; } else { $graphicsmarkup=NONE; } @@ -1465,7 +1482,7 @@ if ($graphicsmarkup != NONE ) { @matches=( $latexdiffpreamble =~ m/command\{\\DIFaddbeginFL}\{($pat_n)}/sg ) ; # we look at the last one of the list to take into account possible redefinition but almost always matches should have exactly one element if ( $matches[$#matches] =~ m/\\DIFaddbegin/ ) { - die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style."; + die "Cannot combine graphics markup with float styles defining \\DIFaddbeginFL in terms of \\DIFaddbegin. Use --graphics-markup=none option or choose a different float style."; exit 10; } ###} @@ -1479,6 +1496,11 @@ if ($graphicsmarkup != NONE ) { $ulem = ($latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{ulem\}/ || defined $packages{"ulem"}); +# If amsmath is defined and $ulem is used for markup, redefine the \sout command to also work (mostly) in math mode +# See stack exchange https://tex.stackexchange.com/questions/20609/strikeout-in-math-mode/308647#308647 based on comment by Taylor Raine +if ( defined($packages{'amsmath'}) and $ulem ) { + $latexdiffpreamble .= join "\n",(extrapream('AMSMATHULEM'),""); +} # If listings is being used or can be found in the latexdiff search path, add to the preamble auxiliary code to enable line-by-line markup if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { @@ -1488,7 +1510,7 @@ if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { } my @listingDIFcode=(); my $replaced; - # note that in case user supplies preamblefile the type might not reflect well the + # note that in case user supplies preamblefile the type might not reflect well the actual markup style @listingDIFcode=extrapream("-nofail","DIFCODE_" . $type) unless defined($preamblefile); if (!(@listingDIFcode)) { # if listingDIFcode is empty try to guess a suitable one from the preamble @@ -1502,13 +1524,17 @@ if ( defined($packages{"listings"}) or `kpsewhich listings.sty` ne "" ) { @listingDIFcode=extrapream("DIFCODE_BOLD"); } } - # now splice it in + # add configuration so that listings work with utf-8 + push @listingpreamble, '\lstset{extendedchars=\true,inputencoding='.$encoding."}\n"; + + + # now splice it in $replaced=0; ###print STDERR "DEBUG: listingDIFcode: ",join("\n",@listingDIFcode),"|||\n" if $debug; - @listingpreamble=grep { + @listingpreamble=grep { # only replace if this has not been done already (use short-circuit property of and) - if (!$replaced and $_ =~ s/^.*%DIFCODE TEMPLATE.*$/join("\n",@listingDIFcode)/e ) { + if (!$replaced and $_ =~ s/^.*%DIFCODE TEMPLATE.*$/join("\n",@listingDIFcode)/e ) { ###print STDERR "DEBUG: Replaced text $_\n" if $debug; $replaced=1; 1; @@ -1538,7 +1564,7 @@ if ( length $oldpreamble && length $newpreamble ) { unshift @oldpreamble,''; @diffpreamble = linediff(\@oldpreamble, \@newpreamble); # remove dummy line again - shift @diffpreamble; + shift @diffpreamble; # add filenames, modification time and latexdiff mark defined($nolabel) or splice @diffpreamble,1,0, "%DIF LATEXDIFF DIFFERENCE FILE", @@ -1587,8 +1613,8 @@ if (defined $packages{"siunitx"} ) { # protect SI command by surrounding them with an \mbox # this is done to get around an incompatibility between the ulem and siunitx package print STDERR "siunitx package detected.\n" if $verbose ; - my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange'; - init_regex_arr_list(\@SAFECMDLIST,'num,si'); + my $mboxcmds='SI,ang,numlist,numrange,SIlist,SIrange,qty,qtylist,qtyproduct,qtyrange,complexqty'; + init_regex_arr_list(\@SAFECMDLIST,'num,si,numproduct,unit,complexnum'); if ( $enablecitmark || ( $ulem && ! $disablecitmark )) { init_regex_arr_list(\@MBOXCMDLIST,$mboxcmds); } else { @@ -1610,7 +1636,7 @@ if (defined $packages{"cleveref"} ) { if (defined $packages{"glossaries"} ) { # protect selected command by surrounding them with an \mbox - # this is done to get around an incompatibility between ulem and glossaries package + # this is done to get around an incompatibility between ulem and glossaries package print STDERR "glossaries package detected.\n" if $verbose ; my $mboxcmds='[gG][lL][sS](?:|pl|disp|link|first|firstplural|desc|user[iv][iv]?[iv]?),[aA][cC][rR](?:long|longpl|full|fullpl),[aA][cC][lfp]?[lfp]?'; init_regex_arr_list(\@SAFECMDLIST,'[gG][lL][sS](?:(?:entry)?(?:text|plural|name|symbol)|displaynumberlist|entryfirst|entryfirstplural|entrydesc|entrydescplural|entrysymbolplural|entryuser[iv][iv]?[iv]?|entrynumberlist|entrydisplaynumberlist|entrylong|entrylongpl|entryshort|entryshortpl|entryfull|entryfullpl),[gG]lossentry(?:name|desc|symbol),[aA][cC][rR](?:short|shortpl),[aA]csp?'); @@ -1639,6 +1665,10 @@ if (defined $packages{"mhchem"} ) { # push(@MATHTEXTCMDLIST,'cee'); } +if ( defined $packages{"tikz-dependency"} ) { + init_regex_arr_ext(\@SAFECMDEXCL, 'AMPERSAND'); +} + my ( $citpat); @@ -1726,7 +1756,7 @@ print STDERR "(",exetime()," s)\n","Done.\n" if $verbose; # liststringtoregex(liststring) -# expands string with semi-colon separated list into a regular expression corresponding +# expands string with semi-colon separated list into a regular expression corresponding # matching any of the elements sub liststringtoregex { my ($liststring)=@_; @@ -1739,7 +1769,7 @@ sub liststringtoregex { } # show_configuration -# note that this is not encapsulated but uses variables from the main program +# note that this is not encapsulated but uses variables from the main program # It is provided for convenience because in the future it is planned to allow output # to be modified based on what packages are read etc - this works only if the input files are actually read # whether or not additional files are provided @@ -1766,7 +1796,7 @@ sub show_configuration { print "\nContext1 commands (last argument textual, command will be disabled in deleted passages, last argument will be shown as plain text):\n"; print_regex_arr(@CONTEXT1CMDLIST); print "\nContext2 commands (last argument textual, command and its argument will be disabled in deleted passages):\n"; - print_regex_arr(@CONTEXT2CMDLIST); + print_regex_arr(@CONTEXT2CMDLIST); print "\nExclude list of Commands with last argument not textual (overrides patterns above):\n"; print_regex_arr(@TEXTCMDEXCL); } @@ -1874,7 +1904,7 @@ sub list_packages { my %packages=(); my $pkg; - # remove comments + # remove comments $preamble=~s/(?<!\\)%.*$//mg ; while ( $preamble =~ m/\\(?:documentclass|usepackage|RequirePackage)(?:\[($brat_n)\])?\{(.*?)\}/gs ) { @@ -1979,7 +2009,7 @@ sub flatten { my ($includeonly,$dirname,$fname,$newpage,$fullfile,$filecontent,$replacement,$begline,$inputcmd,$bblfile,$subfile,$command,$verbenv,$verboptions,$ignore,$fileonly); my ($subpreamble,$subbody,$subpost); my ($subdir,$subdirfull,$importfilepath); - require File::Basename ; + require File::Basename ; ### require File::Spec ; # now this is needed even if flatten option not given $filename = File::Spec->rel2abs( $filename ) ; ($ignore, $dirname, $fileonly) = File::Spec->splitpath($filename) ; @@ -2019,15 +2049,15 @@ sub flatten { $subdirfull = (defined($3) ? File::Spec->catdir($dirname,$subdir) : $subdir); $importfilepath = File::Spec->catfile($subdirfull, $fname); - + print STDERR "importing importfilepath:", $importfilepath,"\n" if $verbose; if ( -f $importfilepath ) { # If file exists, replace input or include command with expanded input #TODO: need remove_endinput & newpage similar to other replacements inside flatten - $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding); + $replacement=flatten(read_file_with_encoding($importfilepath, $encoding), $preamble,$importfilepath,$encoding); } else { # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition - # and is not meant to be expanded directly + # and is not meant to be expanded directly print STDERR "WARNING: Could not find included file ",$importfilepath,". I will continue but not expand |$2|\n"; $replacement = $2; $replacement .= "{$subdir}{$fname} % Processed"; @@ -2036,13 +2066,13 @@ sub flatten { }/exgm; # recursively replace \\input and \\include files - $text =~ s/(^(?:[^%\n]|\\%)*)(\\input\{(.*?)\}|\\include\{(${includeonly}(?:\.tex)?)\})/{ + $text =~ s/(^(?:[^%\n]|\\%)*)(\\input\{(.*?)\}|\\include\{(${includeonly}(?:\.tex)?)\})/{ $begline=(defined($1)? $1 : "") ; $inputcmd=$2; $fname = $3 if defined($3) ; $fname = $4 if defined($4) ; $newpage=(defined($4)? " \\newpage " : "") ; - # # add tex extension unless there is a three or four letter extension already + # # add tex extension unless there is a three or four letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3,4}$|; $fullfile = File::Spec->catfile($dirname,$fname); print STDERR "DEBUG Beg of line match |$1|\n" if defined($1) && $debug ; @@ -2051,12 +2081,12 @@ sub flatten { # content of file becomes replacement value (use recursion), add \newpage if the command was include if ( -f $fullfile ) { # If file exists, replace input or include command with expanded input - $replacement=flatten(read_file_with_encoding($fullfile, $encoding), $preamble,$filename,$encoding); - $replacement = remove_endinput($replacement); + $replacement=flatten(read_file_with_encoding($fullfile, $encoding), $preamble,$filename,$encoding); + $replacement = remove_endinput($replacement); # \include always starts a new page; use explicit \newpage command to simulate this } else { # if file does not exist, do not expand include or input command (do not warn if fname contains #[0-9] as it is then likely part of a command definition - # and is not meant to be expanded directly + # and is not meant to be expanded directly print STDERR "WARNING: Could not find included file ",$fullfile,". I will continue but not expand |$inputcmd|\n" unless $fname =~ m(#[0-9]) ; $replacement = $inputcmd ; # i.e. just the original command again -> make no change file does not exist $newpage=""; @@ -2065,7 +2095,7 @@ sub flatten { }/exgm; # replace bibliography with bbl file if it exists - $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\bibliography\{(.*?)\}/{ if ( -f $bblfile ){ $replacement=read_file_with_encoding(File::Spec->catfile($bblfile), $encoding); } else { @@ -2077,10 +2107,10 @@ sub flatten { }/exgm; # replace subfile with contents (subfile package) - $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\subfile\{(.*?)\}/{ $begline=(defined($1)? $1 : "") ; - $fname = $2; - # # add tex extension unless there is a three or four letter extension already + $fname = $2; + # # add tex extension unless there is a three or four letter extension already $fname .= ".tex" unless $fname =~ m|\.\w{3,4}|; print STDERR "Include file as subfile $fname\n" if $verbose; # content of file becomes replacement value (use recursion) @@ -2091,10 +2121,10 @@ sub flatten { # if file exists, expand \subfile command by contents of file $subfile=read_file_with_encoding($fullfile,$encoding) or die "Could not open included subfile ",$fullfile,": $!"; ($subpreamble,$subbody,$subpost)=splitdoc($subfile,'\\\\begin\{document\}','\\\\end\{document\}'); - ### $subfile=~s|^.*\\begin{document}||s; + ### $subfile=~s|^.*\\begin{document}||s; ### $subfile=~s|\\end{document}.*$||s; $replacement=flatten($subbody, $preamble,$fullfile,$encoding); - ### $replacement = remove_endinput($replacement); + ### $replacement = remove_endinput($replacement); } else { # if file does not exist, do not expand subfile print STDERR "WARNING: Could not find subfile ",$fullfile,". I will continue but not expand |$2|\n" unless $fname =~ m(#[0-9]) ; @@ -2105,11 +2135,11 @@ sub flatten { }/exgm; # replace \verbatiminput and \lstlistinginput - $text=~s/(^(?:[^%\n]|\\%)*)\\(verbatiminput\*?|lstinputlisting)$extraspace(\[$brat_n\])?$extraspace\{(.*?)\}/{ + $text=~s/(^(?:[^%\n]|\\%)*)\\(verbatiminput\*?|lstinputlisting)$extraspace(\[$brat_n\])?$extraspace\{(.*?)\}/{ $begline=(defined($1)? $1 : "") ; $command = $2 ; $fname = $4 ; - $verboptions = defined($3)? $3 : "" ; + $verboptions = defined($3)? $3 : "" ; if ($command eq 'verbatiminput' ) { $verbenv = "verbatim" ; } elsif ($command eq 'verbatiminput*' ) { @@ -2118,7 +2148,7 @@ sub flatten { $verbenv = "lstlisting" ; } else { die "Internal errorL Unexpected verbatim input type $command.\n"; - } + } print STDERR "DEBUG Beg of line match |$begline|\n" if $debug ; print STDERR "Include file $fname verbatim\n" if $verbose; print STDERR "DEBUG looking for file ",File::Spec->catfile($dirname,$fname), "\n" if $debug; @@ -2150,8 +2180,8 @@ sub print_regex_arr { # if $type is a filename, it will read the file instead of reading from the appendix # otherwise it will screen appendix for line "%DIF $TYPE" and copy everything up to line # '%DIF END $TYPE' (where $TYPE is upcased version of $type) -# extrapream('-nofail',$type) will---instead of failing---simply return nothing if -# it does not find the matching line in a appendix (do not use -nofail option with multiple types!) +# extrapream('-nofail',$type) will---instead of failing---simply return nothing if +# it does not find the matching line in appendix (do not use -nofail option with multiple types!) sub extrapream { my @types=@_; my ($type,$arg); @@ -2168,14 +2198,20 @@ sub extrapream { $type=$arg; $copy=0; if ( -f $type || lc $type eq '/dev/null' ) { - open (FILE,$type) or die "Cannot open preamble file $type: $!"; print STDERR "Reading preamble file $type\n" if $verbose ; + open (FILE,$type) or die "Cannot open preamble file $type: $!"; + if (defined($encoding)) { + binmode(FILE,":encoding($encoding)"); + } else { + require Encode::Locale; + binmode(FILE,":encoding(locale)"); + } while (<FILE>) { chomp ; if ( $_ =~ m/%DIF PREAMBLE/ ) { - push (@retval,"$_"); + push (@retval,"$_"); } else { - push (@retval,"$_ %DIF PREAMBLE"); + push (@retval,"$_ %DIF PREAMBLE"); } } } else { # not (-f $type) @@ -2187,9 +2223,9 @@ sub extrapream { my $data_start = tell DATA; while (<DATA>) { if ( m/^%DIF $type/ ) { - $copy=1; + $copy=1; } elsif ( m/^%DIF END $type/ ) { - last; + last; } chomp; push (@retval,"$_ %DIF PREAMBLE") if $copy; @@ -2229,7 +2265,7 @@ sub splitdoc { $pos=pos $rest; $part2=substr($rest,0,$pos-length($2)); $part3=substr($rest,$pos); - } + } else { die "$word1 and $word2 not in the correct order or not present as a pair." ; } @@ -2301,7 +2337,7 @@ sub splitlatex { my $leadin=$1; length($string)>0 or return ($leadin); - my @retval=($string =~ m/$pat/osg); + my @retval=($string =~ m/$pat/osg); if (length($string) != length(join("",@retval))) { print STDERR "\nWARNING: Inconsistency in length of input string and parsed string:\n This often indicates faulty or non-standard latex code.\n In many cases you can ignore this and the following warning messages.\n Note that character numbers in the following are counted beginning after \\begin{document} and are only approximate." unless $ignorewarnings; @@ -2345,17 +2381,17 @@ sub splitlatex { # pass1( \@seq1,\@seq2) # Look for differences between seq1 and seq2. -# Where an common-subsequence block is flanked by deleted or appended blocks, +# Where an common-subsequence block is flanked by deleted or appended blocks, # and is shorter than $MINWORDSBLOCK words it is appended -# to the last deleted or appended word. If the block contains tokens other than words +# to the last deleted or appended word. If the block contains tokens other than words # or punctuation it is not merged. # Deleted or appended block consisting of words and safe commands only are # also merged, to prevent break-up in pass2 (after previous isolated words have been removed) -# If there are commands with textual arguments (e.g. \caption) both in corresponding -# appended and deleted blocks split them such that the command and opening bracket -# are one token, then the rest is split up following standard rules, and the closing +# If there are commands with textual arguments (e.g. \caption) both in corresponding +# appended and deleted blocks split them such that the command and opening bracket +# are one token, then the rest is split up following standard rules, and the closing # bracket is a separate token, ie. turn -# "\caption{This is a textual argument}" into +# "\caption{This is a textual argument}" into # ("\caption{","This ","is ","a ","textual ","argument","}") # No return value. Destructively changes sequences sub pass1 { @@ -2384,15 +2420,15 @@ sub pass1 { my $adddiscard = sub { if ($cnt > 0 ) { $matblkcnt++; - # just after an unchanged block + # just after an unchanged block # print STDERR "Unchanged block $cnt, $last1,$last2 \n"; - if ($cnt < $MINWORDSBLOCK + if ($cnt < $MINWORDSBLOCK && $cnt==scalar ( - grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat_n\]|\{$pat_n\})*)/o - && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) + grep { /^$wpat/ || ( /^\\((?:[`'^"~=.]|[\w\d@*]+))((?:\[$brat_n\]|\{$pat_n\})*)/o + && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && scalar(@dummy=split(" ",$2))<3 ) } @$block) ) { - # merge identical blocks shorter than $MINWORDSBLOCK + # merge identical blocks shorter than $MINWORDSBLOCK # and only containing ordinary words # with preceding different word # We cannot carry out this merging immediately as this @@ -2400,23 +2436,23 @@ sub pass1 { # the algorithm, instead we store in @$todo where we have to merge push(@$todo, [ $last1,$last2,$cnt,@$block ]); } - $block = []; + $block = []; $cnt=0; $last1=-1; $last2=-1; } }; my $discard=sub { $deltokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$delblock,[ $seq1->[$_[0]],$_[0] ]); - $last1=$_[0] }; + $last1=$_[0] }; my $add = sub { $addtokcnt++; &$adddiscard; #($_[0],$_[1]); push(@$addblock,[ $seq2->[$_[1]],$_[1] ]); - $last2=$_[1] }; + $last2=$_[1] }; my $match = sub { $mattokcnt++; if ($cnt==0) { # first word of matching sequence after changed sequence or at beginning of word sequence - $deltextblocks = extracttextblocks($delblock); + $deltextblocks = extracttextblocks($delblock); $delblkcnt++ if scalar @$delblock; $addtextblocks = extracttextblocks($addblock); $addblkcnt++ if scalar @$addblock; @@ -2432,7 +2468,7 @@ sub pass1 { ### Algorithm::Diff 1.19 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, 0, sub { $_[0]->[0] } ); } else { - ### Algorithm::Diff 1.15 + ### Algorithm::Diff 1.15 $matchindex=Algorithm::Diff::_longestCommonSubsequence($delcmds,$addcmds, sub { $_[0]->[0] } ); } @@ -2463,11 +2499,11 @@ sub pass1 { my ($index,$block,$cnt)=@{ shift(@$addtextblocks) }; push(@$todo, [-1,$index,$cnt,@$block]); } - + $addblock=[]; $delblock=[]; } - push(@$block,$seq2->[$_[1]]); + push(@$block,$seq2->[$_[1]]); $cnt++ }; my $keyfunc = sub { join(" ",split(" ",shift())) }; @@ -2475,7 +2511,7 @@ sub pass1 { traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); - # now carry out the merging/splitting. Refer to elements relative from + # now carry out the merging/splitting. Refer to elements relative from # the end (with negative indices) as these offsets don't change before the instruction is executed # cnt>0: merged small unchanged groups with previous changed blocks # cnt==-1: split textual commands into components @@ -2490,7 +2526,7 @@ sub pass1 { } } - if ($verbose) { + if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens in $matblkcnt blocks.\n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; @@ -2500,10 +2536,10 @@ sub pass1 { # extracttextblocks(\@blockindex) -# $blockindex has the following format -# [ [ token1, index1 ], [token2, index2],.. ] -# where index refers to the index in the original old or new word sequence -# Returns: reference to an array of the form +# $blockindex has the following format +# [ [ token1, index1 ], [token2, index2],.. ] +# where index refers to the index in the original old or new word sequence +# Returns: reference to an array of the form # [[ $index, $textblock, $cnt ], .. # where $index index of block to be merged # $textblock contains all the words to be merged with the word at $index (but does not contain this word) @@ -2511,7 +2547,7 @@ sub pass1 { # # requires: iscmd # -sub extracttextblocks { +sub extracttextblocks { my $block=shift; my ($i,$token,$index); my $textblock=[]; @@ -2521,13 +2557,13 @@ sub extracttextblocks { # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace='\s*'; + my $extraspace='\s*'; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # store pure text blocks - if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*)/ - && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) + if ($token =~ /$wpat/ || ( $token =~/^\\((?:[`'^"~=.]|[\w\d@\*]+))((?:${extraspace}\[$brat_n\]${extraspace}|${extraspace}\{$pat_n\})*)/ + && iscmd($1,\@SAFECMDLIST,\@SAFECMDEXCL) && !iscmd($1,\@TEXTCMDLIST,\@TEXTCMDEXCL))) { # we have text or a command which can be treated as text if ($last<0) { @@ -2535,7 +2571,7 @@ sub extracttextblocks { $last=$index; } else { # add to pure-text block - push(@$textblock, $token); + push(@$textblock, $token); } } else { # it is not text @@ -2556,29 +2592,29 @@ sub extracttextblocks { # extractcommands( \@blockindex ) -# $blockindex has the following format -# [ [ token1, index1 ], [token2, index2],.. ] -# where index refers to the index in the original old or new word sequence -# Returns: reference to an array of the form -# [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],.. -# where index is just taken from input array -# command must have a textual argument as last argument -# -# requires: iscmd -# -sub extractcommands { +# $blockindex has the following format +# [ [ token1, index1 ], [token2, index2],.. ] +# where index refers to the index in the original old or new word sequence +# Returns: reference to an array of the form +# [ [ "\cmd1", index, "\cmd1[optarg]{arg1}{", "arg2" ,"} " ],.. +# where index is just taken from input array +# command must have a textual argument as last argument +# +# requires: iscmd +# +sub extractcommands { my $block=shift; my ($i,$token,$index,$cmd,$open,$mid,$closing); my $retval=[]; # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace='\s*'; + my $extraspace='\s*'; for ($i=0;$i< scalar @$block;$i++) { ($token,$index)=@{ $block->[$i] }; # check if token is an alphanumeric command sequence with at least one non-optional argument - # \cmd[...]{...}{last argument} + # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: \cmd @@ -2586,7 +2622,7 @@ sub extractcommands { # $4: } + trailing spaces if ( ( $token =~ m/^(\\([\w\d\*]+)(?:${extraspace}\[$brat_n\]|${extraspace}\{$pat_n\})*${extraspace}\{)($pat_n)(\}\s*)$/so ) && iscmd($2,\@TEXTCMDLIST,\@TEXTCMDEXCL) ) { - print STDERR "DEBUG EXTRACTCOMMANDS Match |$1|$2|$3|$4|$index \n" if $debug; + print STDERR "DEBUG EXTRACTCOMMANDS Match |$1|$2|$3|$4|$index \n" if $debug; # push(@$retval,[ $2,$index,$1,$3,$4 ]); ($cmd,$open,$mid,$closing) = ($2,$1,$3,$4) ; $closing =~ s/\}/\\RIGHTBRACE/ ; @@ -2597,7 +2633,7 @@ sub extractcommands { } # iscmd($cmd,\@regexarray,\@regexexcl) checks -# return 1 if $cmd matches any of the patterns in the +# return 1 if $cmd matches any of the patterns in the # array $@regexarray, and none of the patterns in \@regexexcl, otherwise return 0 sub iscmd { my ($cmd,$regexar,$regexexcl)=@_; @@ -2605,7 +2641,7 @@ sub iscmd { ### print STDERR "DEBUG: iscmd($cmd)=" if $debug; foreach $pat ( @$regexar ) { if ( $cmd =~ m/^${pat}$/ ) { - $ret=1 ; + $ret=1 ; last; } } @@ -2621,13 +2657,13 @@ sub iscmd { # pass2( \@seq1,\@seq2) -# Look for differences between seq1 and seq2. +# Look for differences between seq1 and seq2. # Mark begin and end of deleted and appended sequences with tags $DELOPEN and $DELCLOSE # and $ADDOPEN and $ADDCLOSE, respectively, however exclude { } & and all comands, unless # they match an element of the whitelist (SAFECMD) # For words in TEXTCMD but not in SAFECMD, enclose interior with $ADDOPEN and $ADDCLOSE brackets -# Deleted comment lines are marked with %DIF < -# Added comment lines are marked with %DIF > +# Deleted comment lines are marked with %DIF < +# Added comment lines are marked with %DIF > sub pass2 { my $seq1 = shift ; my $seq2 = shift ; @@ -2659,7 +2695,7 @@ sub pass2 { $addhunk = []; } push(@$retval,$seq2->[$_[1]]) }; - + my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); @@ -2668,7 +2704,7 @@ sub pass2 { push @$retval,marktags($ADDMARKOPEN,$ADDMARKCLOSE,$ADDOPEN,$ADDCLOSE,"","",$ADDCOMMENT,$addhunk) if scalar @$addhunk; - if ($verbose) { + if ($verbose) { print STDERR "\n"; print STDERR " $mattokcnt matching tokens. \n"; print STDERR " $deltokcnt discarded tokens in $delblkcnt blocks.\n"; @@ -2690,7 +2726,7 @@ sub marktags { my (@argtext); my $retval=[]; my $noncomment=0; - my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word + my $cmd=-1; # -1 at beginning 0: last token written is a ordinary word # 1: last token written is a command # for keeping track whether we are just in a command sequence or in a word sequence my $cmdcomment= ($opencmd =~ m/^%/); # Flag to indicate whether opencmd is a comment (i.e. if we intend to simply comment out changed commands) @@ -2706,31 +2742,31 @@ sub marktags { # we redefine locally $extraspace (shadowing the global definition) to capture command sequences with intervening spaces no matter what the global setting # this is done so we can capture those commands with a predefined number of arguments without having to introduce them again explicitly here - my $extraspace_mt='\s*'; + my $extraspace_mt='\s*'; foreach (@$block) { - $word=$_; + $word=$_; if ( $word =~ s/^%/%$comment/ ) { # a comment if ($cmd==1) { push (@$retval,$closecmd) ; $cmd=-1; } - push (@$retval,$word); + push (@$retval,$word); next; } if ( $word =~ m/^\s*$/ ) { ### print STDERR "DEBUG MARKTAGS: whitespace detected |$word| cmdcom |$cmdcomment| |$opencmd|\n" if $debug; # a sequence of white-space characters - this should only ever happen for the first element of block. - # in deleted block, omit, otherwise just copy it in + # in deleted block, omit, otherwise just copy it in if ( ! $cmdcomment) { # ignore in deleted blocks push(@$retval,$word); } next; } if (! $noncomment) { - push (@$retval,$openmark); + push (@$retval,$openmark); $noncomment=1; } # negative lookahead pattern (?!) in second clause is put in to avoid matching \( .. \) patterns @@ -2740,7 +2776,7 @@ sub marktags { # word is a command or other significant token (not in SAFECMDLIST) ## same conditions as in subroutine extractcommand: # check if token is an alphanumeric command sequence with at least one non-optional argument - # \cmd[...]{...}{last argument} + # \cmd[...]{...}{last argument} # Capturing in the following results in these associations # $1: \cmd[...]{...}{ # $2: cmd @@ -2757,11 +2793,11 @@ sub marktags { # Condition 3: But if we are in a deleted block ($cmdcomment=1) and # $2 (the command) is in context2, just treat it as an ordinary command (i.e. comment it open with $opencmd) # Because we do not want to disable this command - # here we do not use $opencmd and $closecmd($opencmd is empty) + # here we do not use $opencmd and $closecmd($opencmd is empty) print STDERR "DEBUG: Detected text |$word| but not safe command \$2: $2 \$3: $3\n." if $debug; if ($cmd==1) { push (@$retval,$closecmd) ; - } elsif ($cmd==0) { + } elsif ($cmd==0) { push (@$retval,$close) ; } $command=$1; $commandword=$2; $closingbracket=$4; @@ -2777,16 +2813,16 @@ sub marktags { # for latexrevise push (@$retval,$command,"%\n{$AUXCMD\n",marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } elsif ( iscmd($commandword,,\@MATHTEXTCMDLIST, \@MATHTEXTCMDEXCL) ) { - # MATHBLOCK pseudo command: consider all commands safe, except & and \\, \begin and \end and a few package sprcific one (look at UNSAFEMATHCMD definition) - # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to + # MATHBLOCK pseudo command: consider all commands safe, except & and \\, \begin and \end and a few package sprcific one (look at UNSAFEMATHCMD definition) + # Keep these commands even in deleted blocks, hence set $opencmd and $closecmd (5th and 6th argument of marktags) to # "" - local @SAFECMDLIST=(".*"); + local @SAFECMDLIST=(".*"); local @SAFECMDEXCL=('\\','\\\\',@UNSAFEMATHCMD); push(@$retval,$command,marktags("","",$open,$close,"","",$comment,\@argtext)#@argtext ,$closingbracket); } else { # normal textcmd or context1cmd in an added block - push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); + push (@$retval,$command,marktags("","",$open,$close,$opencmd,$closecmd,$comment,\@argtext),$closingbracket); } push (@$retval,$AUXCMD,"\n") if $cmdcomment ; $cmd=-1 ; @@ -2872,10 +2908,10 @@ sub take_comments_and_newline_from_frac() { # names or labels but it does not matter because they are converted back in the postprocessing step # Returns: leading white space removed in step 1 sub preprocess { - for (@_) { + for (@_) { - # change in \verb and similar commands - note that I introduce an extra space here so that the + # change in \verb and similar commands - note that I introduce an extra space here so that the # already hashed variants do not trigger again # transform \lstinline{...} # s/\\lstinline(\[$brat0\])?(\{(?:.*?)\})/"\\DIFlstinline". $1 ."{". tohash(\%verbhash,"$2") ."}"/esg; @@ -2905,7 +2941,7 @@ sub preprocess { 1 while s/(?<!\\)_(\s*{($pat_n)})/\\SUBSCRIPT$1/g ; # Convert ^n into \SUPERSCRIPTNB{n} and ^{nnn} into \SUPERSCRIPT{nn} 1 while s/(?<!\\)\^(\s*([^{\\\s]|\\\w+))/\\SUPERSCRIPTNB{$1}/g ; - 1 while s/(?<!\\)\^(\s*{($pat_n)})/\\SUPERSCRIPT$1/g ; + 1 while s/(?<!\\)\^(\s*{($pat_n)})/\\SUPERSCRIPT$1/g ; # Convert \sqrt{n} into \SQRT{n} and \sqrt nn into SQRTNB{nn} 1 while s/(?<!\\)\\sqrt(\s*([^{\\\s]|\\\w+))/\\SQRTNB{$1}/g ; 1 while s/(?<!\\)\\sqrt(\s*{($pat_n)})/\\SQRT$1/g ; @@ -2925,16 +2961,16 @@ sub preprocess { if ( $mathmarkup != FINE ) { # DIFANCHORARRB and DIFANCHORARRE, DIFANCHORMATHB and DIFANCHORMATHE markers are inserted here to encourage the matching algorithm # to always match up the closing brace. Otherwise sometimes one ends up with a situation where - # the closing brace is deleted and added at another point. The deleted closing brace is then + # the closing brace is deleted and added at another point. The deleted closing brace is then # prevented by a %DIFDELCMD, leading to material leaking in or out of the math environment. # The anchors are removed in post-processing again. (note that they are simple text to cause least amount of complications - # Admittedly, this is something of a hack and will not always work. If it does not, then one needs to + # Admittedly, this is something of a hack and will not always work. If it does not, then one needs to # resort to WHOLE or FINE, or NONE math mode processing. s/\\begin\{($ARRENV)}(.*?)\\end\{\1}/\\ARRAYBLOCK$1\{$2\\DIFANCHORARRB \}\\DIFANCHORARRE /sg; take_comments_and_newline_from_frac(); - # Convert Math environments with arguments + # Convert Math environments with arguments s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}((?:\[$brat_n\])|(?:\{$pat_n\}))+(.*?)\\end\{\1\}/\\MATHBLOCK$1\[$2\]\{$3\\DIFANCHORMATHB \}\\DIFANCHORMATHE /sg; # Convert Math environments without arguments s/\\begin\{($MATHENV|$MATHARRENV|SQUAREBRACKET)\}(.*?)\\end\{\1\}/\\MATHBLOCK$1\{$2\\DIFANCHORMATHB \}\\DIFANCHORMATHE /sg; @@ -2948,7 +2984,7 @@ sub preprocess { # $expanded=linecomment($string) #preface all lines with verbatim marker (usually DIFVRB) -sub linecomment { +sub linecomment { my @verbatimlines=split("\n",$_[0]); # the first line needs special treatment - we do want to retain optional arguments as is but wrap the remainder also with VERBCOMMENT ### print STDERR "DEBUG: before verbatimlines[0] = ",$verbatimlines[0],"\n"; @@ -2958,7 +2994,7 @@ sub linecomment { } # $simple=reverselinecomment($env $string) -# remove DIFVRB comments but leave changed lines marked +# remove DIFVRB comments but leave changed lines marked sub reverselinecomment { my ($environment, $verbatimtext)=@_; ### print STDERR "DEBUG REVERSELINECOMMENT input: $environment,|$verbatimtext|\n" if $debug; @@ -2973,7 +3009,7 @@ sub reverselinecomment { $verbatimtext =~ s/\\DIFdelend //g; $verbatimtext =~ s/$DELCMDOPEN.*//g; - # remove DIFVRB mark + # remove DIFVRB mark $verbatimtext=~ s/%$VERBCOMMENT//g; # remove part of the markup in changed lines @@ -3064,7 +3100,7 @@ sub writedebugfile { # * Remove STOP token from the end # * Replace \RIGHTBRACE by } # * If option --no-del is set delete all deleted blocks -# 1. Check all deleted blocks: +# 1. Check all deleted blocks: # a.where a deleted block contains a matching \begin and # \end environment (these will be disabled by a %DIFDELCMD statements), for selected environments enable # these commands again (such that for example displayed math in a deleted equation @@ -3085,14 +3121,14 @@ sub writedebugfile { # For added blocks: # c. If in-line math mode contains array environment, enclose the whole environment in \mbox'es # d. place \cite commands in mbox'es (for UNDERLINE style) -# +# # 2. If math-mode COARSE,WHOLE or NONE option set: Convert \MATHBLOCKmath{..} commands back to environments # # Convert all PICTUREblock{..} commands back to the appropriate environments # 3. Convert DIFadd, DIFdel, DIFaddbegin , ... into FL varieties # within floats (currently recognised float environments: plate,table,figure # plus starred varieties). -# 4. Remove empty %DIFDELCMD < lines +# 4. Remove empty %DIFDELCMD < lines # 4. Convert \begin{SQUAREBRACKET} \end{SQUAREBRACKET} into \[ \] # Convert \begin{DOLLARDOLLAR} \end{DOLLARDOLLAR} into $$ $$ # 5. Convert \SUPERSCRIPTNB{n} into ^n and \SUPERSCRIPT{nn} into ^{nnn} @@ -3105,7 +3141,7 @@ sub writedebugfile { # 4, undo renaming of the \begin, \end,{,} in comments # Change \QLEFTBRACE, \QRIGHTBRACE,\AMPERSAND to \{,\},\& # -# Note have to manually synchronize substitution commands below and +# Note have to manually synchronize substitution commands below and # DIF.. command names in the header sub postprocess { my ($begin,$len,$float,$delblock,$addblock); ### $cnt @@ -3117,7 +3153,7 @@ sub postprocess { my (@itemargs, $itemarg); - for (@_) { + for (@_) { # change $'s in comments to something harmless 1 while s/(%.*)\$/$1DOLLARDIF/mg ; @@ -3127,7 +3163,7 @@ sub postprocess { # the only way to get these is as %DIFDELCMD < \RIGHTBRACE construction # This essentially marks closing right braces of MATHBLOCK environments, which did not get matched # up. This case should be rare, so I just leave this in the diff file output. Not really elegant - # but can still be dealt with later if it results in problems. + # but can still be dealt with later if it results in problems. s/%DIFDELCMD < \\RIGHTBRACE/%DIFDELCMD < \\MBLOCKRIGHTBRACE/g ; # Replace \RIGHTBRACE by } s/\\RIGHTBRACE/}/g; @@ -3155,7 +3191,7 @@ sub postprocess { $len=length($&); $begin=pos($_) - $len; $delblock=$&; - ### A much simpler method for math replacement might follow this strategy (can recycle part of the commands below for following + ### A much simpler method for math replacement might follow this strategy (can recycle part of the commands below for following ### this strategy: ### 1. a Insert aux commands \begin{MATHMODE} or \end{MATHMODE} for all deleted commands opening or closing displayed math mode ### b Insert aux commands \begin{MATHARRMODE} or \end{MATHARRMODE} for all deleted commands opening or closing math array mode @@ -3181,14 +3217,14 @@ sub postprocess { ###0.5: $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \s*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg; $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}.*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{\2\})/\\end\{MATHMODE\}$AUXCMD\n$1$3\n\\begin\{MATHMODE\}$AUXCMD\n$4/sg; - # now look for unpaired %DIFDELCMD < \begin{MATHENV}; if found add \begin{$MATHREPL} and insert \end{$MATHREPL} + # now look for unpaired %DIFDELCMD < \begin{MATHENV}; if found add \begin{$MATHREPL} and insert \end{$MATHREPL} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\begin{$MATHREPL}$AUXCMD\n/sg ) { ### print STDERR "BINGO: begin block: \nBefore: |" . substr($_,$begin,$len) . "|\n" if $debug ; $delblock =~ s/(\\DIFdelend$)/\\end{$MATHREPL}$AUXCMD\n$1/s ; ### print STDERR "After: |" . $delblock . "|\n\n" if $debug ; } - # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} + # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{((?:$MATHENV)|SQUAREBRACKET)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end\{MATHMODE\}$AUXCMD\n/sg ) { ### print STDERR "BINGO: end block:\nBefore: |" . substr($_,$begin,$len) . "|\n" if $debug; @@ -3211,15 +3247,15 @@ sub postprocess { $delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))(.*?[^\n]?)\n?(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{\2\})/\\end{MATHMODE}$AUXCMD\n$1$3\n\\begin{MATHMODE}$AUXCMD\n$4/sg; ### print STDERR "STEP1: |" . $delblock . "|\n\n" if $debug ; - # now look for unpaired %DIFDELCMD < \begin{MATHARRENV}; if found add \begin{$MATHARRREPL} and insert \end{$MATHARRREPL} + # now look for unpaired %DIFDELCMD < \begin{MATHARRENV}; if found add \begin{$MATHARRREPL} and insert \end{$MATHARRREPL} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\begin\{($MATHARRENV)\}(.*?)(?:$DELCMDCLOSE|\n))/$1\\begin{$2*}$3$AUXCMD\n/sg ) { $arrenv=$2; - $delblock =~ s/(\\DIFdelend$)/\\end{$arrenv*}}$AUXCMD\n$1/s ; + $delblock =~ s/(\\DIFdelend$)/\\end{$arrenv*}$AUXCMD\n$1/s ; } ### print STDERR "STEP2: |" . $delblock . "|\n\n" if $debug ; - # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} + # now look for unpaired %DIFDELCMD < \end{MATHENV}; if found add \end{MATHMODE} and insert \begin{MATHMODE} # just before end of block; again we use look-behind assertion to avoid matching constructions which have already been converted if ($delblock=~ s/(?<!${AUXCMD}\n)(\%DIFDELCMD < \h*\\end\{($MATHARRENV)\}\s*?(?:$DELCMDCLOSE|\n))/$1\\end{MATHMODE}$AUXCMD\n/sg ) { $delblock =~ s/(\\DIFdelend$)/\\begin{MATHMODE}$AUXCMD\n$1/s ; @@ -3237,7 +3273,7 @@ sub postprocess { ### $eqarrayblock=~ s/(\%DIFDELCMD < \s*(\&|\\\\)\s*?(?:$DELCMDCLOSE|\n))/$1$2$AUXCMD\n/sg ; $eqarrayblock =~ s/(\%DIFDELCMD < (.*?(?:\&|\\\\).*)(?:$DELCMDCLOSE|\n))/ # The pattern captures comments with at least one of & or \\ - @symbols= split(m@((?:&|\\\\)\s*)@,$2); # extract & and \\ and other material from sequence + @symbols= split(m@((?:&|\\\\)\s*)@,$2); # extract & and \\ and other material from sequence @symbols= grep ( m@&|\\\\\s*@, @symbols); # select & and \\ (and subsequent spaces) "$1@symbols$AUXCMD\n" /eg ; @@ -3250,7 +3286,7 @@ sub postprocess { } elsif ( $mathmarkup == COARSE || $mathmarkup == WHOLE ) { # Convert MATHBLOCKmath commands to their uncounted numbers (e.g. convert equation -> displaymath # (environments defined in $MATHENV will be replaced by $MATHREPL, and environments in $MATHARRENV - # will be replaced by their starred variety + # will be replaced by their starred variety $delblock=~ s/\\MATHBLOCK($MATHENV)((?:\[$brat_n\])?)\{($pat_n)\}/\\MATHBLOCK$MATHREPL$2\{$3\}/sg; $delblock=~ s/\\MATHBLOCK($MATHARRENV)((?:\[$brat_n\])?)\{($pat_n)\}/\\MATHBLOCK$1\*$2\{$3\}/sg; } @@ -3264,10 +3300,10 @@ sub postprocess { print STDERR "DELBLOCK after maths processing: |" . $delblock . "|\n\n" if $debug ; - # Reinstate completely deleted list environments. note that items within the + # Reinstate completely deleted list environments. note that items within the # environment will still be commented out. They will be restored later $delblock=~ s/(\%DIFDELCMD < \s*\\begin\{($LISTENV)\}\s*?(?:\n|$DELCMDCLOSE))(.*?)(\%DIFDELCMD < \s*\\end\{\2\})/{ - ### # block within the search; replacement environment + ### # block within the search; replacement environment ### "$1\\begin{$2}$AUXCMD\n". restore_item_commands($3). "\n\\end{$2}$AUXCMD\n$4"; "$1\\begin{$2}$AUXCMD\n$3\n\\end{$2}$AUXCMD\n$4"; }/esg; @@ -3301,7 +3337,7 @@ sub postprocess { ### if ($CITE2CMD) { ###### ${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})) .*?%%%\n ### $delblock=~s/($DELCMDOPEN\s*\\($CITE2CMD)(.*)$DELCMDCLOSE)/ - ### # Replacement code + ### # Replacement code ### {my ($aux,$all); ### $aux=$all=$1; ### $aux=~s#\n?($DELCMDOPEN|$DELCMDCLOSE)##g; @@ -3311,7 +3347,7 @@ sub postprocess { ### if ($CITECMD) { ###### $delblock=~s/(\\($CITECMD)${extraspace}(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; ### $delblock=~s/(\\($CITECMD)${extraspace}(?:<$abrat0>${extraspace})?(?:\[$brat0\]${extraspace}){0,2}\{$pat_n\})(\s*)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/msg ; - ### } + ### } # if MBOXINLINEMATH is set, protect inlined math environments with an extra mbox @@ -3319,7 +3355,7 @@ sub postprocess { # note additional \newline after command is omitted from output if right at the end of deleted block (otherwise a spurious empty line is generated) $delblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } - ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/)) { + ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/)) { ### # change included verbatim environments ### $delblock =~ s/\\DIFverb\{/\\DIFDIFdelverb\{/g; ### $delblock =~ s/\\DIFlstinline/\\DIFDIFdellstinline/g; @@ -3361,7 +3397,7 @@ sub postprocess { ##$addblock=~s/($math)/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; $addblock=~s/($math)(?:[\s\n]*)?/\\mbox{$AUXCMD\n$1\n}$AUXCMD\n/sg; } - ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { + ###if ( defined($packages{"listings"} and $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat0\])?\{color\}/)) { # mark added verbatim commands $addblock =~ s/\\DIFverb/\\DIFDIFaddverb/g; $addblock =~ s/\\DIFlstinline/\\DIFDIFaddlstinline/g; @@ -3379,11 +3415,11 @@ sub postprocess { pos = $begin + length($addblock); } - # Go through whole text, and by counting list environment commands, find out when we are within a list environment. + # Go through whole text, and by counting list environment commands, find out when we are within a list environment. # Within those restore deleted \item commands - @textparts=split /(?<!$DELCMDOPEN)(\\(?:begin|end)\{$LISTENV\})/ ; + @textparts=split /(?<!$DELCMDOPEN)(\\(?:begin|end)\{$LISTENV\})/ ; @liststack=(); - @newtextparts=map { + @newtextparts=map { ### print STDERR ":::::::: $_\n"; if ( ($listtype) = m/^\\begin\{($LISTENV)\}$/ ) { print STDERR "DEBUG: postprocess \\begin{$listtype}\n" if $debug; @@ -3399,7 +3435,7 @@ sub postprocess { } else { print STDERR "DEBUG: postprocess \@liststack=(",join(",",@liststack),")\n" if $debug; if (scalar @liststack > 0 ) { - # we are within a list environment and should replace all item commands + # we are within a list environment and should replace all item commands $_=restore_item_commands($_); } # else: we are outside a list environment and do not need to do anything @@ -3412,17 +3448,17 @@ sub postprocess { # Replace MATHMODE environments from step 1a above by the correct Math environment and remove unncessary pairings - + if ( $mathmarkup == FINE ) { # look for AUXCMD math-mode pairs which have only comments (or empty lines between them), and remove the added commands # \begin{..} ... \end{..} pairs - s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\end\{\1\}$AUXCMD\n/$2/sg; + s/\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\end\{\1\}$AUXCMD\n/$2/sg; # \end{..} .... \begin{..} pairs - s/\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\begin\{\1\}$AUXCMD\n/$2/sg; + s/\\end\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET|MATHMODE)\}$AUXCMD\n((?:\s*%.[^\n]*\n)*)\\begin\{\1\}$AUXCMD\n/$2/sg; writedebugfile($_,'postprocess15'); # The next line is complicated. The negative look-ahead insertion makes sure that no \end{$MATHENV} (or other mathematical - # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching + # environments) are between the \begin{$MATHENV} and \end{MATHMODE} commands. This is necessary as the minimal matching # is not globally minimal but only 'locally' (matching is beginning from the left side of the string) # [NB: Do not be tempted to prettify the expression with /x modified. It seems this is applied after strings are expanded so will ignore spaces in strings 1 while s/(?<!$DELCMDOPEN)\\begin\{((?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}((?:${DELCMDOPEN}[^\n]*|.(?!(?:\\end\{(?:(?:$MATHENV)|(?:$MATHARRENV)|SQUAREBRACKET)}|\\begin\{MATHMODE})))*?)\\end\{MATHMODE}/\\begin{$1}$2\\end{$1}/s; @@ -3497,7 +3533,7 @@ sub postprocess { # remove empty DIFCMD < lines s/^\Q${DELCMDOPEN}\E\n//msg; - # Expand hashes of verb and verbatim environments + # Expand hashes of verb and verbatim environments s/${DELCMDOPEN}\\($VERBATIMENV)\{([-\d]*?)\}/"${DELCMDOPEN}\\begin{${1}}".fromhash(\%verbhash,$2,$DELCMDOPEN)."${DELCMDOPEN}\\end{${1}}"/esg; # revert changes to verbatim environments for line diffs (and add code to mark up changes) (note negative look behind assertions to not leak out of DIFDELCMD comments) # Example: @@ -3523,8 +3559,8 @@ sub postprocess { ((?:\%\Q$DELCOMMENT$VERBCOMMENT\E[^\n]*?\n)*) # Deleted \end command of verbatim environment. Note that the type is forced to match the opening. Captures: $5: Whole deleted environment (previous way this line was written: (\Q$DELCMDOPEN\E\\end\{\2\}(?:\n|\s|\Q$DELCMDOPEN\E)*\Q$DELCMDCLOSE\E) (\Q$DELCMDOPEN\E\\end\{\2\}) - / # Substitution part - $1 # Leave expression as is + / # Substitution part + $1 # Leave expression as is . "$AUXCMD NEXT\n" # Mark the following line as an auxiliary command . "" # reinstate the original environment without options . reverselinecomment($2, "$3$4") # modify the body to change the markup; reverselinecomment parses for options @@ -3533,7 +3569,7 @@ sub postprocess { /esgx; # Modifiers of substitution command writedebugfile($_,'postprocess2'); # where changes have occurred in verbatim environment, change verbatim to DIFverbatim to allow mark-up - # (I use the presence of optional paramater to verbatim environment as the marker - normal verbatim + # (I use the presence of optional paramater to verbatim environment as the marker - normal verbatim # environment does not take optional arguments) s/(?<!$DELCMDOPEN)\\begin\{(verbatim[*]?)\}(\[$brat_n\].*?)\\end\{\1\}/\\begin{DIF$1}$2\\end{DIF$1}/sg; @@ -3547,7 +3583,7 @@ sub postprocess { # convert remaining PAR commands (which are preceded by non-white space characters, usually "}" ($ADDCLOSE) s/\\PAR\n/\n\n/sg; - # package specific processing: + # package specific processing: if ( defined($packages{"endfloat"})) { #endfloat: make sure \begin{figure} and \end{figure} are always # on a line by themselves, similarly for table environment @@ -3560,12 +3596,16 @@ sub postprocess { s/^((?:[^%]+)\\(?:begin|end)\{(?:figure|table)\}(?:\[[a-zA-Z]+\])?)(.+)((?:%.*)?)$/$1\n$2$3/mg; } - # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated + # Remove empty auxiliary LISTENV (sometmes these are generated if list environment occurs within the argument of a deleted comment) + # (slightly hacky but I could not see an easy way to see if in argument of another command when this extra markup is added) + s/\\begin\{($LISTENV)\}$AUXCMD\n((?:\s*\%[^\n]*\n)*\n?)\\end\{\1\}$AUXCMD\n/$2\n/msg ; + + # Convert '\PERCENTAGE ' back into '\%' (the final question mark catches a special situation where due to a latter pre-processing step the ' ' becomes separated s/\\PERCENTAGE ?/\\%/g; - # Convert '\DOLLAR ' back into '\$' + # Convert '\DOLLAR ' back into '\$' s/\\DOLLAR /\\\$/g; - # undo renaming of the \begin and \end,{,} and dollars in comments + # undo renaming of the \begin and \end,{,} and dollars in comments # although we only renamed $ in comments to DOLLARDIFF, we might have lost the % in unchanged verbatim blocks, so rename all s/DOLLARDIF/\$/g; @@ -3583,7 +3623,7 @@ sub postprocess { # Convert \SQRT{n} into \sqrt{n} and \SQRTNB{nn} into \sqrt nn 1 while s/\\SQRT(\s*\{($pat_n)\})/\\sqrt$1/g ; 1 while s/\\SQRTNB\{(\s*$pat0)\}/\\sqrt$1/g ; - + 1 while s/(%.*)\\CFRAC (.*)$/$1\\frac$2/mg ; 1 while s/(%.*)\\CRIGHTBRACE (.*)$/$1\}$2/mg ; 1 while s/(%.*)\\CLEFTBRACE (.*)$/$1\{$2/mg ; @@ -3594,7 +3634,7 @@ sub postprocess { s/\\QRIGHTBRACE /\\\}/sg; s/\\AMPERSAND /\\&/sg; # Highlight added inline verbatim commands if possible - if ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) { + if ( $latexdiffpreamble =~ /\\RequirePackage(?:\[$brat_n\])?\{color\}/ ) { # wrap added verb commands with color commands s/\\DIFDIFadd((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*)/\{\\color{blue}$AUXCMD\n\\DIF$1%\n\}$AUXCMD\n/sg; s/\\DIFDIFdel((?:verb\*?|lstinline(?:\[$brat_n\])?)\{[-\d]*?\}[\s\n]*$AUXCMD)/\{\\color{red}${AUXCMD}\n\\DIF$1\n\}${AUXCMD}/sg; @@ -3609,8 +3649,8 @@ sub postprocess { # finally add the comment to the ones not having an optional argument before ###s/\\DIFaddlstinline(?!\[)/\\lstinline\n[basicstyle=\\color{blue}]$AUXCMD\n/g; - return; } + return; } # $out = restore_item_commands($listenviron) @@ -3634,13 +3674,13 @@ sub restore_item_commands { # @auxlines=preprocess_preamble($oldpreamble,$newpreamble); - # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) - # the list of commands is defined in CONTEXT2CMD - # if found then use a bodydiff to mark up content, and replace the corresponding commands + # pre-process preamble by looking for commands used in \maketitle (title, author, date etc commands) + # the list of commands is defined in CONTEXT2CMD + # if found then use a bodydiff to mark up content, and replace the corresponding commands # in both preambles by marked up version to 'fool' the linediff (such that only body is marked up). # A special case are e.g. author commands being added (or removed) # 1. If commands are added, then the entire content is marked up as new, but also the lines are marked as new in the linediff - # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns + # 2. If commands are removed, then the linediff will mark the line as deleted. The program returns # with $auxlines a text to be appended at the end of the preamble, which shows the respective fields as deleted sub preprocess_preamble { my ($oldpreambleref,$newpreambleref)=(\$_[0],\$_[1]) ; @@ -3662,7 +3702,7 @@ EOF $titlecmd = "(?:".join("|",@CONTEXT2CMDLIST).")"; # as context2cmdlist is stored as regex, e.g. ((?-xism:^title$), we need to remove ^- fo # resue in a more complex regex - $titlecmd =~ s/[\$\^]//g; + $titlecmd =~ s/[\$\^]//g; # make sure to not match on comment lines: $titlecmdpat=qr/^(?:[^%\n]|\\%)*(\\($titlecmd)$extraspace(?:\[($brat_n)\])?(?:\{($pat_n)\}))/ms; ###print STDERR "DEBUG:",$titlecmdpat,"\n"; @@ -3688,7 +3728,7 @@ EOF $cmd=shift @newtitlecommands; $optarg=shift @newtitlecommands; $arg=shift @newtitlecommands; - + if ( defined($newhash{$cmd})) { warn "$cmd is used twice in preamble of new file. Reverting to pure line diff mode for preamble.\n"; print STDERR $warnmsgdetail; @@ -3715,7 +3755,7 @@ EOF } $argnew=$newhash{$cmd}->[2]; $argdiff="{" . join("",bodydiff($argold,$argnew)) ."}"; - # Replace \RIGHTBRACE by } + # Replace \RIGHTBRACE by } $argdiff =~ s/\\RIGHTBRACE/}/g; if ( length $optargnew ) { @@ -3730,7 +3770,7 @@ EOF $optargdiff=""; } ### print STDERR "DEBUG s/\\Q$newhash{$cmd}->[0]\\E/\\$cmd$optargdiff$argdiff/s\n"; - # Note: \Q and \E force literal interpretation of what it between them but allow + # Note: \Q and \E force literal interpretation of what it between them but allow # variable interpolation, such that e.g. \title matches just that and not TAB-itle $$newpreambleref=~s/\Q$newhash{$cmd}->[0]\E/\\$cmd$optargdiff$argdiff/s; # replace this in old preamble if necessary @@ -3770,7 +3810,7 @@ EOF #%< old deleted line(s) #%DIF ------- #%DIF mmann-nn -#new appended line %< +#new appended line %< #%DIF ------- # Future extension: mark change explicitly # Assumes: traverse_sequence traverses deletions before insertions in changed sequences @@ -3782,9 +3822,9 @@ sub linediff { my $block = []; my $retseq = []; my @begin=('','',''); # dummy initialisation - my $instring ; + my $instring ; - my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ; + my $discard = sub { @begin=('d',$_[0],$_[1]) unless scalar @$block ; push(@$block, "%DIF < " . $seq1->[$_[0]]) }; my $add = sub { if (! scalar @$block) { @begin=('a',$_[0],$_[1]) ;} @@ -3799,12 +3839,12 @@ sub linediff { $instring = sprintf "%%DIF %da%d-%d",$begin[1],$begin[2],$_[1]-1; } elsif ( $begin[0] eq 'c' ) { $instring = sprintf "%%DIF %sc%s", - ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) , + ($begin[1]==$_[0]-1) ? "$begin[1]" : $begin[1]."-".($_[0]-1) , ($begin[2]==$_[1]-1) ? "$begin[2]" : $begin[2]."-".($_[1]-1) ; } else { $instring = sprintf "%%DIF %d%s%d",$begin[1],$begin[0],$begin[2]; } - push @$retseq, $instring,@$block, "%DIF -------" ; - $block = []; + push @$retseq, $instring,@$block, "%DIF -------" ; + $block = []; } push @$retseq, $seq2->[$_[1]] }; @@ -3812,7 +3852,7 @@ sub linediff { my $keyfunc = sub { join(" ",split(" ",shift())) }; traverse_sequences($seq1,$seq2, { MATCH=>$match, DISCARD_A=>$discard, DISCARD_B=>$add }, $keyfunc ); - push @$retseq, @$block if scalar @$block; + push @$retseq, @$block if scalar @$block; return wantarray ? @$retseq : $retseq ; } @@ -3822,23 +3862,23 @@ sub linediff { # init_regex_arr_data(\@array,"TOKEN INIT") # scans DATA file handel for line "%% TOKEN INIT" line # then appends each line not beginning with % into array (as a quoted regex) -# This is used for command lists and configuration variables, but the processing is slightly -# different: +# This is used for command lists and configuration variables, but the processing is slightly +# different: # For lists, the regular expression is extended to include beginning (^) and end ($) markers, to require full-string matching # For configuration variables (and all others), simply an unadorned list is copied sub init_regex_arr_data { my ($arr,$token)=@_; my $copy=0; my ($mode); - if ($token =~ m/COMMANDS/ ) { - $mode=0; # Reading command list + if ($token =~ m/COMMANDS/ ) { + $mode=0; # Reading command list } else { $mode=1; # Reading configuration variables } while (<DATA>) { if ( m/^%%BEGIN $token\s*$/ ) { - $copy=1; + $copy=1; next; } elsif ( m/^%%END $token\s*$/ ) { last; } @@ -3919,17 +3959,18 @@ sub exetime { sub usage { - print STDERR <<"EOF"; + print STDERR <<"EOF"; Usage: $0 [options] old.tex new.tex > diff.tex -Compares two latex files and writes tex code to stdout, which has the same format as new.tex but +Compares two latex files and writes tex code to stdout, which has the same format as new.tex but has all changes relative to old.tex marked up or commented. Note that old.tex and new.tex need to -be real files (not pipes or similar) as they are opened twice. +be real files (not pipes or similar) as they are opened twice. --type=markupstyle -t markupstyle Add code to preamble for selected markup style - Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE + Available styles: UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT + LUAUNDERLINE [ Default: UNDERLINE ] --subtype=markstyle @@ -3940,7 +3981,7 @@ be real files (not pipes or similar) as they are opened twice. * LABEL subtype is deprecated --floattype=markstyle --f markstyle Add code to preamble for selected style which +-f markstyle Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats so marginal marking can be disabled thus) @@ -3949,11 +3990,11 @@ be real files (not pipes or similar) as they are opened twice. --encoding=enc -e enc Specify encoding of old.tex and new.tex. Typical encodings are - ascii, utf8, latin1, latin9. A list of available encodings can be - obtained by executing + ascii, utf8, latin1, latin9. A list of available encodings can be + obtained by executing perl -MEncode -e 'print join ("\\n",Encode->encodings( ":all" )) ;' [Default encoding is utf8 unless the first few lines of the preamble contain - an invocation "\\usepackage[..]{inputenc} in which case the + an invocation "\\usepackage[..]{inputenc} in which case the encoding chosen by this command is asssumed. Note that ASCII (standard latex) is a subset of utf8] @@ -3970,22 +4011,22 @@ be real files (not pipes or similar) as they are opened twice. --exclude-safecmd=exclude-file --exclude-safecmd="cmd1,cmd2,..." --A exclude-file +-A exclude-file --replace-safecmd=replace-file --append-safecmd=append-file --append-safecmd="cmd1,cmd2,..." -a append-file Exclude from, replace or append to the list of regex - matching commands which are safe to use within the + matching commands which are safe to use within the scope of a \\DIFadd or \\DIFdel command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are ignored). A literal comma within the comma-separated list must be - escaped thus "\\,", Note that the RegEx needs to match the whole of + escaped thus "\\,", Note that the RegEx needs to match the whole of the token, i.e., /^regex\$/ is implied and that the initial "\\" of the command is not included. The --exclude-safecmd - and --append-safecmd options can be combined with the --replace-safecmd + and --append-safecmd options can be combined with the --replace-safecmd option and can be used repeatedly to add cumulatively to the lists. ---exclude-textcmd=exclude-file +--exclude-textcmd=exclude-file --exclude-textcmd="cmd1,cmd2,..." -X exclude-file --replace-textcmd=replace-file @@ -4001,7 +4042,7 @@ be real files (not pipes or similar) as they are opened twice. Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. \\caption will only work within a figure - or table. These commands behave like text commands, except when + or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. @@ -4011,7 +4052,7 @@ be real files (not pipes or similar) as they are opened twice. As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. - context2 commands are also the only commands in the preamble, whose argument will + context2 commands are also the only commands in the preamble, whose argument will be processed in word-by-word mode (which only works, if they occur no more than once in the preamble). @@ -4020,15 +4061,15 @@ be real files (not pipes or similar) as they are opened twice. --append-mboxsafecmd=append-file --append-mboxsafecmd="cmd1,cmd2,..." Define safe commands, which additionally need to be protected by encapsulating - in an \\mbox{..}. This is sometimes needed to get around incompatibilities + in an \\mbox{..}. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE - + --config var1=val1,var2=val2,... -c var1=val1,.. Set configuration variables. --c configfile Available variables: +-c configfile Available variables: ARRENV (RegEx) COUNTERCMD (RegEx) FLOATENV (RegEx) @@ -4047,15 +4088,15 @@ be real files (not pipes or similar) as they are opened twice. --add-to-config varenv1=pattern1,varenv2=pattern2 For configuration variables containing a regular expression (essentially those ending - in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration + in ENV, and COUNTERCMD) this provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. varenv must be one of the variables listed above that take a regular - expression as argument, and pattern is any regular expression (which might need to be + expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. --add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote" --packages=pkg1,pkg2,.. - Tell latexdiff that .tex file is processed with the packages in list + Tell latexdiff that .tex file is processed with the packages in list loaded. This is normally not necessary if the .tex file includes the preamble, as the preamble is automatically scanned for \\usepackage commands. Use of the --packages option disables automatic scanning, so if for any @@ -4076,57 +4117,57 @@ be real files (not pipes or similar) as they are opened twice. --show-all Show all of the above - NB For all --show commands, no old.tex or new.tex file needs to be given, and no + NB For all --show commands, no old.tex or new.tex file needs to be given, and no differencing takes place. Other configuration options: --allow-spaces Allow spaces between bracketed or braced arguments to commands - [Default requires arguments to directly follow each other without + [Default requires arguments to directly follow each other without intervening spaces] --math-markup=level Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): - off or 0: suppress markup for math environments. Deleted equations will not - appear in diff file. This mode can be used if all the other modes + off or 0: suppress markup for math environments. Deleted equations will not + appear in diff file. This mode can be used if all the other modes cause invalid latex code. whole or 1: Differencing on the level of whole equations. Even trivial changes - to equations cause the whole equation to be marked changed. This - mode can be used if processing in coarse or fine mode results in + to equations cause the whole equation to be marked changed. This + mode can be used if processing in coarse or fine mode results in invalid latex code. coarse or 2: Detect changes within equations marked up with a coarse - granularity; changes in equation type (e.g.displaymath to equation) + granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] fine or 3: Detect small change in equations and mark up and fine granularity. This mode is most suitable, if only minor changes to equations are - expected, e.g. correction of typos. + expected, e.g. correction of typos. --graphics-markup=level Change highlight style for graphics embedded with \\includegraphics commands Possible values for level: none,off or 0: no highlighting for figures new-only or 1: surround newly added or changed figures with a blue frame [Default] - both or 2: highlight new figures with a blue frame and show deleted figures + both or 2: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable SCALEDELGRAPHICS to set size of deleted figures. - Note that changes to the optional parameters will make the figure appear as changed + Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. In some circumstances "Misplaced \\noalign" errors can occur if there are certain types - of changes in tables. In this case please use option --graphics-markup=none as a - work-around. + of changes in tables. In this case please use option --graphics-markup=none as a + work-around. ---no-del Suppress deleted text from the diff. It is similar in effect to the BOLD style, +--no-del Suppress deleted text from the diff. It is similar in effect to the BOLD style, but the deleted text ist not just invisible in the output, it is also not included in the - diff text file. This can be more robust than just making it invisible. + diff text file. This can be more robust than just making it invisible. ---disable-citation-markup ---disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles +--disable-citation-markup +--disable-auto-mbox Suppress citation markup and markup of other vulnerable commands in styles using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR) (the two options are identical and are simply aliases) --enable-citation-markup ---enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections +--enforce-auto-mbox Protect citation commands and other vulnerable commands in changed sections with \\mbox command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) @@ -4142,14 +4183,14 @@ Miscellaneous options --no-label Suppress inclusion of old and new file names as comment in output file ---visible-label Include old and new filenames (or labels set with --label option) as +--visible-label Include old and new filenames (or labels set with --label option) as visible output --flatten Replace \\input and \\include commands within body by the content of the files in their argument. If \\includeonly is present in the - preamble, only those files are expanded into the document. However, - no recursion is done, i.e. \\input and \\include commands within - included sections are not expanded. The included files are assumed to + preamble, only those files are expanded into the document. However, + no recursion is done, i.e. \\input and \\include commands within + included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, respectively, making it possible to organise files into old and new directories. --flatten is applied recursively, so inputted files can contain further @@ -4172,7 +4213,7 @@ Miscellaneous options -h Show this help text. --ignore-warnings Suppress warnings about inconsistencies in length between input - and parsed strings and missing characters. + and parsed strings and missing characters. --verbose -V Output various status information to stderr during processing. @@ -4184,10 +4225,10 @@ Internal options: These options are mostly for automated use by latexdiff-vc. They can be used directly, but the API should be considered less stable than for the other options. ---no-links Suppress generation of hyperreferences, used for minimal diffs +--no-links Suppress generation of hyperreferences, used for minimal diffs (option --only-changes of latexdiff-vc). EOF - exit 0; + exit 0; } =head1 NAME @@ -4213,8 +4254,8 @@ be real files (not pipes or similar) as they are opened twice (unless C<--encodi The program treats the preamble differently from the main document. Differences between the preambles are found using line-based differencing (similarly to the Unix diff command, but ignoring white -spaces). A comment, "S<C<%DIF E<gt>>>" is appended to each added line, i.e. a -line present in C<new.tex> but not in C<old.tex>. Discarded lines +spaces). A comment, "S<C<%DIF E<gt>>>" is appended to each added line, i.e. a +line present in C<new.tex> but not in C<old.tex>. Discarded lines are deactivated by prepending "S<C<%DIF E<lt>>>". Changed blocks are preceded by comment lines giving information about line numbers in the original files. Where there are insignificant differences, the resulting file C<diff.tex> will be similar to @@ -4267,7 +4308,7 @@ curly braces immediately following a command (i.e. a sequence of letters beginning with a backslash) are arguments for that command. As a restriction to condition 1 above it is thus necessary to surround all arguments with curly braces, and to not insert -extraneous spaces. For example, write +extraneous spaces. For example, write \section{\textem{This is an emphasized section title}} @@ -4299,7 +4340,7 @@ but the choice is yours. Any markup within the environment will be removed, and generally everything within the environment will just be taken from the new file. -It is also possible to difference files which do not have a preamble. +It is also possible to difference files which do not have a preamble. In this case, the file is processed in the main document mode, but the definitions of the markup commands are not inserted. @@ -4317,7 +4358,7 @@ the scope of C<\DIFadd>. Added comments are marked by prepending Within deleted blocks text is highlighted with C<\DIFdel>. Deleted comments are marked by prepending "S<C<%DIF E<lt> >>". Non-safe command -and curly braces within deleted blocks are commented out with +and curly braces within deleted blocks are commented out with "S<C<%DIFDELCMD E<lt> >>". @@ -4327,7 +4368,7 @@ and curly braces within deleted blocks are commented out with =head2 Preamble The following options determine the visual markup style by adding the appropriate -command definitions to the preamble. See the end of this section for a description of +command definitions to the preamble. See the end of this section for a description of available styles. =over 4 @@ -4337,15 +4378,16 @@ B<-t markupstyle> Add code to preamble for selected markup style. This option defines C<\DIFadd> and C<\DIFdel> commands. -Available styles: +Available styles: -C<UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE -CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT> +C<UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE +CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT +LUAUNDERLINE> [ Default: C<UNDERLINE> ] =item B<--subtype=markstyle> or -B<-s markstyle> +B<-s markstyle> Add code to preamble for selected style for bracketing commands (e.g. to mark changes in margin). This option defines @@ -4358,27 +4400,27 @@ Available styles: C<SAFE MARGIN COLOR DVIPSCOL ZLABEL ONLYCHANGEDPAGE (LABEL)*> =item B<--floattype=markstyle> or B<-f markstyle> -Add code to preamble for selected style which +Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats -so marginal marking can be disabled thus). This option defines all +so marginal marking can be disabled thus). This option defines all C<\DIF...FL> commands. Available styles: C<FLOATSAFE TRADITIONALSAFE IDENTICAL> [ Default: C<FLOATSAFE> ] -=item B<--encoding=enc> or +=item B<--encoding=enc> or B<-e enc> Specify encoding of old.tex and new.tex. Typical encodings are -C<ascii>, C<utf8>, C<latin1>, C<latin9>. A list of available encodings can be -obtained by executing +C<ascii>, C<utf8>, C<latin1>, C<latin9>. A list of available encodings can be +obtained by executing C<perl -MEncode -e 'print join ("\n",Encode->encodings( ":all" )) ;' > If this option is used, then old.tex, new.tex are only opened once. [Default encoding is utf8 unless the first few lines of the preamble contain -an invocation C<\usepackage[..]{inputenc}> in which case the +an invocation C<\usepackage[..]{inputenc}> in which case the encoding chosen by this command is asssumed. Note that ASCII (standard latex) is a subset of utf8] @@ -4395,7 +4437,7 @@ C<\DIFaddbeginFL, \DIFaddendFL, \DIFaddFL{..}, (If this option is set B<-t>, B<-s>, and B<-f> options are ignored.) -=item B<--packages=pkg1,pkg2,..> +=item B<--packages=pkg1,pkg2,..> Tell latexdiff that .tex file is processed with the packages in list loaded. This is normally not necessary if the .tex file includes the @@ -4406,13 +4448,13 @@ The following packages trigger special behaviour: =over 8 -=item C<endfloat> +=item C<endfloat> Ensure that C<\begin{figure}> and C<\end{figure}> always appear by themselves on a line. =item C<hyperref> -Change name of C<\DIFadd> and C<\DIFdel> commands to C<\DIFaddtex> and C<\DIFdeltex> and +Change name of C<\DIFadd> and C<\DIFdel> commands to C<\DIFaddtex> and C<\DIFdeltex> and define new C<\DIFadd> and C<\DIFdel> commands, which provide a wrapper for these commands, using them for the text but not for the link defining command (where any markup would cause errors). @@ -4464,17 +4506,17 @@ B<-A exclude-file> or B<--exclude-safecmd="cmd1,cmd2,..."> =item B<--replace-safecmd=replace-file> -=item B<--append-safecmd=append-file> or +=item B<--append-safecmd=append-file> or B<-a append-file> or B<--append-safecmd="cmd1,cmd2,..."> Exclude from, replace or append to the list of regular expressions (RegEx) -matching commands which are safe to use within the +matching commands which are safe to use within the scope of a C<\DIFadd> or C<\DIFdel> command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are -ignored). Note that the RegEx needs to match the whole of +ignored). Note that the RegEx needs to match the whole of the token, i.e., /^regex$/ is implied and that the initial -"\" of the command is not included. -The B<--exclude-safecmd> and B<--append-safecmd> options can be combined with the -B<--replace-safecmd> +"\" of the command is not included. +The B<--exclude-safecmd> and B<--append-safecmd> options can be combined with the -B<--replace-safecmd> option and can be used repeatedly to add cumulatively to the lists. B<--exclude-safecmd> and B<--append-safecmd> can also take a comma separated list as input. If a @@ -4487,7 +4529,7 @@ B<-X exclude-file> or B<--exclude-textcmd="cmd1,cmd2,..."> =item B<--replace-textcmd=replace-file> -=item B<--append-textcmd=append-file> or +=item B<--append-textcmd=append-file> or B<-x append-file> or B<--append-textcmd="cmd1,cmd2,..."> Exclude from, replace or append to the list of regular expressions @@ -4495,7 +4537,7 @@ matching commands whose last argument is text. See entry for B<--exclude-safecmd> directly above for further details. -=item B<--replace-context1cmd=replace-file> +=item B<--replace-context1cmd=replace-file> =item B<--append-context1cmd=append-file> or @@ -4504,11 +4546,11 @@ entry for B<--exclude-safecmd> directly above for further details. Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. C<\caption> will only work within a figure -or table. These commands behave like text commands, except when +or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. -=item B<--replace-context2cmd=replace-file> +=item B<--replace-context2cmd=replace-file> =item B<--append-context2cmd=append-file> or @@ -4518,9 +4560,9 @@ As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. -context2 commands are also the only commands in the preamble, whose argument will be processed in +context2 commands are also the only commands in the preamble, whose argument will be processed in word-by-word mode (which only works, if they occur no more than once in the preamble). The algorithm currently cannot cope with repeated context2 commands in the preamble, as they occur e.g. for the C<\author> argument in some journal styles (not in the standard styles, though -If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use C<--replace-context2cmd> option to just select the commands, which should be processed and are not used repeatedly in the preamble. +If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use C<--replace-context2cmd> option to just select the commands, which should be processed and are not used repeatedly in the preamble. @@ -4529,7 +4571,7 @@ If such a repetition is detected, the whole preamble will be processed in line-b =item B<--append-mboxsafecmd=append-file> or B<--append-mboxsafecmd="cmd1,cmd2,..."> Define safe commands, which additionally need to be protected by encapsulating -in an C<\mbox{..}>. This is sometimes needed to get around incompatibilities +in an C<\mbox{..}>. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE @@ -4543,7 +4585,7 @@ in the default style UNDERLINE as well as CULINECHBAR CFONTSTRIKE Set configuration variables. The option can be repeated to set different variables (as an alternative to the comma-separated list). -Available variables (see below for further explanations): +Available variables (see below for further explanations): C<ARRENV> (RegEx) @@ -4573,10 +4615,10 @@ C<SCALEDELGRAPHICS> (Float) =item B<--add-to-config varenv1=pattern1,varenv2=pattern2,...> For configuration variables, which are a regular expression (essentially those ending -in ENV, COUNTERCMD and CUSTOMDIFCMD, see list above) this option provides an alternative way to modify the configuration +in ENV, COUNTERCMD and CUSTOMDIFCMD, see list above) this option provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. C<varenv> must be one of the variables listed above that take a regular -expression as argument, and pattern is any regular expression (which might need to be +expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. C<--add-to-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote"> @@ -4596,7 +4638,7 @@ Show values of configuration variables. Combine all --show commands. -NB For all --show commands, no C<old.tex> or C<new.tex> file needs to be specified, and no +NB For all --show commands, no C<old.tex> or C<new.tex> file needs to be specified, and no differencing takes place. =back @@ -4613,29 +4655,29 @@ might get lumpeded with preceding commands) so should only be used if the default produces erroneous results. (Default requires arguments to directly follow each other without intervening spaces). -=item B<--math-markup=level> +=item B<--math-markup=level> -Determine granularity of markup in displayed math environments: +Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): -C<off> or C<0>: suppress markup for math environments. Deleted equations will not -appear in diff file. This mode can be used if all the other modes +C<off> or C<0>: suppress markup for math environments. Deleted equations will not +appear in diff file. This mode can be used if all the other modes cause invalid latex code. C<whole> or C<1>: Differencing on the level of whole equations. Even trivial changes -to equations cause the whole equation to be marked changed. This -mode can be used if processing in coarse or fine mode results in +to equations cause the whole equation to be marked changed. This +mode can be used if processing in coarse or fine mode results in invalid latex code. C<coarse> or C<2>: Detect changes within equations marked up with a coarse -granularity; changes in equation type (e.g.displaymath to equation) +granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] C<fine> or C<3>: Detect small change in equations and mark up at fine granularity. This mode is most suitable, if only minor changes to equations are -expected, e.g. correction of typos. +expected, e.g. correction of typos. =item B<--graphics-markup=level> @@ -4647,33 +4689,33 @@ C<none>, C<off> or C<0>: no highlighting for figures C<new-only> or C<1>: surround newly added or changed figures with a blue frame [Default if graphicx package loaded] -C<both> or C<2>: highlight new figures with a blue frame and show deleted figures at reduced +C<both> or C<2>: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable SCALEDELGRAPHICS to set size of deleted figures. -Note that changes to the optional parameters will make the figure appear as changed +Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. In some circumstances "Misplaced \noalign" error can occur if there are certain types -of changes in tables. In this case please use C<--graphics-markup=none> as a -work-around. +of changes in tables. In this case please use C<--graphics-markup=none> as a +work-around. -=item B<--no-del> +=item B<--no-del> -Suppress deleted text from the diff. It is similar in effect to the BOLD style, -but the deleted text ist not just invisible in the output, it is also not included in the diff text file. -This can be more robust than just making it invisible. +Suppress deleted text from the diff. It is similar in effect to the BOLD style, +but the deleted text ist not just invisible in the output, it is also not included in the diff text file. +This can be more robust than just making it invisible. =item B<--disable-citation-markup> or B<--disable-auto-mbox> -Suppress citation markup and markup of other vulnerable commands in styles +Suppress citation markup and markup of other vulnerable commands in styles using ulem (UNDERLINE,FONTSTRIKE, CULINECHBAR) (the two options are identical and are simply aliases) =item B<--enable-citation-markup> or B<--enforce-auto-mbox> -Protect citation commands and other vulnerable commands in changed sections +Protect citation commands and other vulnerable commands in changed sections with C<\mbox> command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) @@ -4719,18 +4761,18 @@ Suppress inclusion of old and new file names as comment in output file =item B<--visible-label> -Include old and new filenames (or labels set with C<--label> option) as +Include old and new filenames (or labels set with C<--label> option) as visible output. =item B<--flatten> Replace C<\input> and C<\include> commands within body by the content of the files in their argument. If C<\includeonly> is present in the -preamble, only those files are expanded into the document. However, -no recursion is done, i.e. C<\input> and C<\include> commands within -included sections are not expanded. The included files are assumed to +preamble, only those files are expanded into the document. However, +no recursion is done, i.e. C<\input> and C<\include> commands within +included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, -respectively, making it possible to organise files into old and new directories. +respectively, making it possible to organise files into old and new directories. --flatten is applied recursively, so inputted files can contain further C<\input> statements. Also handles files included by the import package (C<\import> and C<\subimport>), and C<\subfile> command. @@ -4777,7 +4819,7 @@ Suppress generation of hyperreferences, used for minimal diffs (option --only-ch =back -=head2 Predefined styles +=head2 Predefined styles =head2 Major types @@ -4790,9 +4832,14 @@ The major type determine the markup of plain text and some selected latex comman Added text is wavy-underlined and blue, discarded text is struck out and red (Requires color and ulem packages). Overstriking does not work in displayed math equations such that deleted parts of equation are underlined, not struck out (this is a shortcoming inherent to the ulem package). +=item C<LUAUNDERLINE> + +Added text is underlined and blue, discarded text is struck out and red +(Requires lua-ul package + LuaLaTeX). + =item C<CTRADITIONAL> -Added text is blue and set in sans-serif, and a red footnote is created for each discarded +Added text is blue and set in sans-serif, and a red footnote is created for each discarded piece of text. (Requires color package) =item C<TRADITIONAL> @@ -4833,13 +4880,13 @@ Added text is set in bold face, discarded is not shown. (also see --no-del optio =item C<PDFCOMMENT> -The pdfcomment package is used to underline new text, and mark deletions with a PDF comment. Note that this markup might appear differently or not at all based on the pdf viewer used. The viewer with best support for pdf markup is probably acroread. This style is only recommended if the number of differences is small. +The pdfcomment package is used to underline new text, and mark deletions with a PDF comment. Note that this markup might appear differently or not at all based on the pdf viewer used. The viewer with best support for pdf markup is probably acroread. This style is only recommended if the number of differences is small. =back =head2 Subtypes -The subtype defines the commands that are inserted at the begin and end of added or discarded blocks, irrespectively of whether these blocks contain text or commands (Defined commands: C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>) +The subtype defines the commands that are inserted at the begin and end of added or discarded blocks, irrespectively of whether these blocks contain text or commands (Defined commands: C<\DIFaddbegin, \DIFaddend, \DIFdelbegin, \DIFdelend>) =over 10 @@ -4857,7 +4904,7 @@ from the intended position. An alternative way of marking added passages in blue, and deleted ones in red. (It is recommeneded to use instead the main types to effect colored markup, -although in some cases coloring with dvipscol can be more complete, for example +although in some cases coloring with dvipscol can be more complete, for example with citation commands). =item C<DVIPSCOL> @@ -4872,12 +4919,12 @@ although in some cases coloring with dvipscol can be more complete). can be used to highlight only changed pages, but requires post-processing. It is recommend to not call this option manually but use C<latexdiff-vc> with C<--only-changes> option. Alternatively, use the script given within preamble of diff files made using this style. -=item C<ONLYCHANGEDPAGE> +=item C<ONLYCHANGEDPAGE> also highlights changed pages, without the need for post-processing, but might not work reliably if there is floating material (figures, tables). -=item C<LABEL> +=item C<LABEL> is similar to C<ZLABEL>, but does not need the zref package and works less reliably (deprecated). @@ -4885,7 +4932,7 @@ is similar to C<ZLABEL>, but does not need the zref package and works less relia =head2 Float Types -Some of the markup used in the main text might cause problems when used within +Some of the markup used in the main text might cause problems when used within floats (e.g. figures or tables). For this reason alternative versions of all markup commands are used within floats. The float type defines these alternative commands. @@ -4912,7 +4959,7 @@ Make no difference between the main text and floats. =item C<ARRENV> -If a match to C<ARRENV> is found within an inline math environment within a deleted or added block, then the inlined math +If a match to C<ARRENV> is found within an inline math environment within a deleted or added block, then the inlined math is surrounded by C<\mbox{>...C<}>. This is necessary as underlining does not work within inlined array environments. [ Default: C<ARRENV>=S<C<(?:array|[pbvBV]matrix)> > @@ -4932,9 +4979,9 @@ C<|subsubsection|paragraph|subparagraph)> ] This option is for advanced users and allows definition of special versions of commands, which do not work as safe commands. Commands in C<CUSTOMDIFCMD> that occur in added or deleted blocks will be given an ADD or DEL prefix. -The prefixed versions of the command must be defined in the preamble, either by putting them +The prefixed versions of the command must be defined in the preamble, either by putting them in the preamble of at least the new file, or by creating a custom preamble file (Option --preamble). -For example the command C<\blindtext> (from package blindtext) does not interact well with underlining, so that +For example the command C<\blindtext> (from package blindtext) does not interact well with underlining, so that for the standard markup type, it is not satisfactory to define it as a safe command. Instead, a customised versions without underlining can be defined in the preamble: @@ -4948,7 +4995,7 @@ and then latexdiff should be invoked with the option C<-c CUSTOMDIFCMD=blindtext =item C<FLOATENV> -Environments whose name matches the regular expression in C<FLOATENV> are +Environments whose name matches the regular expression in C<FLOATENV> are considered floats. Within these environments, the I<latexdiff> markup commands are replaced by their FL variaties. @@ -4997,17 +5044,17 @@ If C<--graphics-markup=both> is chosen, C<SCALEDELGRAPHICS> is the factor, by wh =item C<VERBATIMENV> -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: deleted content is commented out, new content is not marked up [ Default: S<C<comment> > ] =item C<VERBATIMLINEENV> -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by VERBATIMLINEENV are compared in +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by VERBATIMLINEENV are compared in line mode, and changes are marked up using the listings package. The markup style is set based on the chosen mains markup type (Option -t), or on an analysis of the preamble. -Note that "listings.sty" must be installed. If this file is not found the fallback solution is to +Note that "listings.sty" must be installed. If this file is not found the fallback solution is to treat VERBATIMLINEENV environments treated exactly the same way as VERBATIMENV environments. [ Default: S<C<(?:verbatim[*]?|lstlisting> > ] @@ -5018,30 +5065,40 @@ treat VERBATIMLINEENV environments treated exactly the same way as VERBATIMENV e =over 10 -=item Citations result in overfull boxes +=item Changed citations result in overfull boxes There is an incompatibility between the C<ulem> package, which C<latexdiff> uses for underlining and striking out in the UNDERLINE style, -the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an C<\mbox> -command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have two possibilities. +the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an C<\mbox> +command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have several possibilities. 1. Use C<CFONT> type markup (option C<-t CFONT>): If this markup is chosen, then changed citations are no longer marked up -with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the C<ulem> package will also work. +with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the C<ulem> package will also work. 2. Choose option C<--disable-citation-markup> which turns off the marking up of citations: deleted citations are no longer shown, and -added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older) - +added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older). For custom packages you can define the commands which need to be protected by C<\mbox> with C<--append-mboxsafecmd> and C<--excludemboxsafecmd> options (submit your lists of command as feature request at github page to set the default behaviour of future versions, see section 6) -=item Changes in complicated mathematical equations result in latex processing errors +3. If you are using luatex >= 1.12.0 you can use option LUAUNDERLINE that uses lua-ul instead of ulem for underlining, which does not have this problem (experimental feature). + +=item Changes in complicated mathematical equations result in latex processing errors. + +Try option C<--math-markup=whole>. If even that fails, you can turn off mark up for equations with C<--math-markup=off>. -Try options C<--math-markup=whole>. If even that fails, you can turn off mark up for equations with C<--math-markup=off>. +=item Deleted parts in equations are not struck out but underlined. -=item How can I just show the pages where changes had been made +This is a limitation of the ulem package that implements the strike-out. If you use the amsmath package, then the strike-out command is redefined in such a way that deleted passages are wrapped with C<\text> command; adding C<\usepackage{amsmath}> to your preamble will trigger this behaviour. (If amsmath is not included directly, but imported by another package, latexdiff will not be able to detect its availability; in this case you can give latexdiff a hint with option C<--packages=amsmath>. -Use options -C<-s ZLABEL> (some postprocessing required) or C<-s ONLYCHANGEDPAGE>. C<latexdiff-vc --ps|--pdf> with C<--only-changes> option takes care of + +=item How can I just show the pages where changes had been made? + +Use options C<--s ZLABEL> (some postprocessing required) or C<-s ONLYCHANGEDPAGE>. C<latexdiff-vc --ps|--pdf> with C<--only-changes> option takes care of the post-processing for you (requires zref package to be installed). +=item The character encoding breaks when running latexdiff from powershell. + +This problem is not limited to C<latexdiff> and has to do with the default settings of C<powershell> in Windows. It is recommended to use C<cmd> instead. + =back =head1 BUGS @@ -5054,13 +5111,13 @@ different numbers of inter-argument spaces are treated as significant. =back -Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, +Please submit bug reports using the issue tracker of the github repository page I<https://github.com/ftilmann/latexdiff.git>, or send them to I<tilmann -- AT -- gfz-potsdam.de>. Include the version number of I<latexdiff> (from comments at the top of the source or use B<--version>). If you come across latex files that are error-free and conform to the specifications set out above, and whose differencing still does not result in error-free latex, please send me those files, ideally edited to only contain the -offending passage as long as that still reproduces the problem. If your +offending passage as long as that still reproduces the problem. If your file relies on non-standard class files, you must include those. I will not look at examples where I have trouble to latex the original files. @@ -5071,24 +5128,24 @@ L<latexrevise>, L<latexdiff-vc> =head1 PORTABILITY I<latexdiff> does not make use of external commands and thus should run -on any platform supporting Perl 5.6 or higher. If files with encodings +on any platform supporting Perl 5.6 or higher. If files with encodings other than ASCII or UTF-8 are processed, Perl 5.8 or higher is required. The standard version of I<latexdiff> requires installation of the Perl package -C<Algorithm::Diff> (available from I<www.cpan.org> - +C<Algorithm::Diff> (available from I<www.cpan.org> - I<http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15>) but a stand-alone version, I<latexdiff-so>, which has this package inlined, is available, too. I<latexdiff-fast> requires the I<diff> command to be present. =head1 AUTHOR -Version 1.3.3 -Copyright (C) 2004-2022 Frederik Tilmann +Version 1.3.4 +Copyright (C) 2004-2024 Frederik Tilmann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 -Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, +Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, T. Connors, Sebastian Gouezel and many others. Thanks to the many people who sent in bug reports, feature suggestions, and other feedback. @@ -5359,13 +5416,14 @@ value underline sqrt (SUPER|SUB)SCRIPT -%%END TEXT COMMANDS +%%END TEXT COMMANDS %%BEGIN CONTEXT1 COMMANDS % Regex matching commands with a text argument (leave out the \), which will fail out of context. These commands behave like text commands, except when they occur in a deleted section, where they are disabled, but their argument is shown as deleted text. caption subcaption -%%END CONTEXT1 COMMANDS +multicolumn +%%END CONTEXT1 COMMANDS %%BEGIN CONTEXT2 COMMANDS % Regex matching commands with a text argument (leave out the \), which will fail out of context. As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. @@ -5373,7 +5431,7 @@ title author date institute -%%END CONTEXT2 COMMANDS +%%END CONTEXT2 COMMANDS %% CONFIGURATION variabe defaults %%BEGIN LISTENV CONFIG @@ -5451,9 +5509,16 @@ verbatim[*]? \RequirePackage[normalem]{ulem} \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} \providecommand{\DIFadd}[1]{{\protect\color{blue}\uwave{#1}}} -\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} +\providecommand{\DIFdel}[1]{{\protect\color{red}\sout{#1}}} %DIF END UNDERLINE PREAMBLE +%DIF LUAUNDERLINE PREAMBLE +\RequirePackage{lua-ul} +\RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} +\providecommand{\DIFadd}[1]{{\protect\color{blue}\underLine{#1}}} +\providecommand{\DIFdel}[1]{{\protect\color{red}\strikeThrough{#1}}} +%DIF END LUAUNDERLINE PREAMBLE + %DIF CTRADITIONAL PREAMBLE \RequirePackage{color}\definecolor{RED}{rgb}{1,0,0}\definecolor{BLUE}{rgb}{0,0,1} \RequirePackage[stable]{footmisc} @@ -5625,7 +5690,7 @@ verbatim[*]? % To show only pages with changes (dvips/dvipdf) % latex diff.tex % latex diff.tex -% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi +% dvips -pp `perl -lne 'if (m/\\newlabel{DIFchg[be]\d*}{{.*}{(.*)}}/) { print $1 }' diff.aux | uniq | tr -s \\n ','` diff.dvi \typeout{Check comments in preamble of output for instructions how to show only pages where changes have been made} \usepackage[user,abspage]{zref} \newcount\DIFcounterb @@ -5645,10 +5710,10 @@ verbatim[*]? \RequirePackage{etoolbox} \RequirePackage{zref} % redefine label command to write immediately to aux file - page references will be lost -\makeatletter \let\oldlabel\label% Store \label -\renewcommand{\label}[1]{% Update \label to write to the .aux immediately -\zref@wrapper@immediate{\oldlabel{#1}}} -\makeatother +\makeatletter \let\oldlabel\label% Store \label +\renewcommand{\label}[1]{% Update \label to write to the .aux immediately +\zref@wrapper@immediate{\oldlabel{#1}}} +\makeatother \newbool{DIFkeeppage} \newbool{DIFchange} \boolfalse{DIFkeeppage} @@ -5666,7 +5731,7 @@ verbatim[*]? \providecommand{\DIFmodend}{\global\booltrue{DIFkeeppage}\global\boolfalse{DIFchange}} %DIF END ONLYCHANGEDPAGE PREAMBLE -%% FLOAT TYPES +%% FLOAT TYPES %DIF FLOATSAFE PREAMBLE \providecommand{\DIFaddFL}[1]{\DIFadd{#1}} @@ -5698,7 +5763,7 @@ verbatim[*]? %DIF END TRADITIONALSAFE PREAMBLE % see: -% http://tex.stackexchange.com/questions/47351/can-i-redefine-a-command-to-contain-itself +% http://tex.stackexchange.com/questions/47351/can-i-redefine-a-command-to-contain-itself %DIF HIGHLIGHTGRAPHICS PREAMBLE \RequirePackage{settobox} @@ -5744,6 +5809,15 @@ verbatim[*]? %% SPECIAL PACKAGE PREAMBLE COMMANDS +%% Redefine strike out command to wrap in text box if amsmath is used and markup style with ulem is used +%DIF AMSMATHULEM PREAMBLE +\makeatletter +\let\sout@orig\sout +\renewcommand{\sout}[1]{\ifmmode\text{\sout@orig{\ensuremath{#1}}}\else\sout@orig{#1}\fi} +\makeatother +%DIF END AMSMATHULEM PREAMBLE + + % Standard \DIFadd and \DIFdel are redefined as \DIFaddtex and \DIFdeltex % when hyperref package is included. %DIF HYPERREF PREAMBLE @@ -5846,7 +5920,7 @@ verbatim[*]? %DIF END DIFCODE_BOLD %DIF DIFCODE_PDFCOMMENT - + moredelim=[il][\color{white}\tiny]{\%DIF\ <\ }, moredelim=[il][\sffamily\bfseries]{\%DIF\ >\ } %DIF END DIFCODE_PDFCOMMENT diff --git a/support/latexdiff/latexdiff-vc b/support/latexdiff/latexdiff-vc index 697d1e29b7..31760ca14c 100755 --- a/support/latexdiff/latexdiff-vc +++ b/support/latexdiff/latexdiff-vc @@ -26,6 +26,12 @@ # Detailed usage information at the end of the file # # TODO/IDEAS: - option to call external pre-processing codes +# +# version 1.3.4: +# - Enhancement: if --flatten option is used, and no bbl file is included in the version management, then latexdiff-vc will try to run bibtex to generate the bbl file. Implements the suggestion of PR #127 (contributed by github user cousteaulecommandant ) +# - Efficiency boost: use -draftmode for non-interactive preliminary runs of latex (idea from # +# - bug fix: minor fix for --only-changed that makes detection of changed pages more reliable [ PR #297 contributed by user nelijuc ] +# # version 1.3.2: # - bug fix: when setting config variables with the command lines it is now possible to use quotes to includes spaces in the value, e.g. -c LATEX="pdflatex --shell-escape" # - bug fix: --only-changes is not compatible with graphics markup. --graphics-markup=none is now set automatically @@ -71,7 +77,7 @@ use Getopt::Long ; use Pod::Usage qw/pod2usage/ ; use File::Temp qw/tempdir/ ; -use File::Basename qw/dirname/; +use File::Basename qw/dirname fileparse/; use File::Copy; use File::Path; @@ -79,8 +85,8 @@ use strict ; use warnings ; my $versionstring=<<EOF ; -This is LATEXDIFF-VC 1.3.2 - (c) 2005-2021 F J Tilmann +This is LATEXDIFF-VC 1.3.4 + (c) 2005-2024 F J Tilmann EOF # output debug and intermediate files, set to 0 in final distribution @@ -98,6 +104,8 @@ my ($configlatexdiff,@config,$config,$assign); #my $latexcmd="latex"; # latex compiler if not further identified my $vc=""; my $tempdir=tempdir(CLEANUP => 1); # generate a temp dir, which will automatically be deleted at program exit +#printf STDERR "DEBUG: tempdir $tempdir\n"; + # Variables my ($file1,$file2,$diff,$diffbase,$rootdir,$answer,$options,$infile,$append,$dirname,$cwd); my (@files,@ldoptions,@tmpfiles,@ptmpfiles,@difffiles,$extracomp); # , @@ -419,30 +427,39 @@ while ( $infile=$file2=shift @files ) { print STDERR "Working on $infile \n"; if ( scalar(@revs) == 1 ) { if ( defined($flatten) ) { - my $olddir=$tempdir . "/latexdiff-vc-$revs[0]"; - print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n"; - checkout_dir($revs[0],$olddir); - $file1=$olddir ."/".$infile; - } else { - ($file1=$infile) =~ s/\.(tex|bbl|flt)/-oldtmp-$$.$1/ ; - push @tmpfiles,$file1; - # compare file with previous version ($revs[0]="") or specified version - ### system("$diffcmd$revs[0] $infile| $patchcmd -o$file1") ; - if (system("$diffcmd$revs[0] \"$infile\" | $patchcmd -o\"$file1\"")==0 and -z $file1 ) { - # no differences detected, i.e. file is equal to current version - copy($infile,$file1) || die "copy($infile,$file1) failed: $!"; - } - } + my $olddir=$tempdir . "/latexdiff-vc-$revs[0]"; + print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n"; + checkout_dir($revs[0],$olddir,$infile); + $file1=$olddir ."/".$infile; + + # generate bibliography for new file if + if ( greptex('^[^%]*\\\\bibliography\\{',$infile) == 0) { + my ($filebase,$filedir)=fileparse($infile,".tex"); + if ( ! -e "$filedir$filebase.bbl" ) { + system("$CFG{LATEX} -draftmode -interaction=batchmode '$infile'; $CFG{BIBTEX} '$filedir$filebase'") + or die "Something went wrong in executing: $CFG{LATEX} -draftmode -interaction=batchmode '$infile'; $CFG{BIBTEX} '$filedir$filebase'" ; + } + } + } else { + ($file1=$infile) =~ s/\.(tex|bbl|flt)/-oldtmp-$$.$1/ ; + push @tmpfiles,$file1; + # compare file with previous version ($revs[0]="") or specified version + ### system("$diffcmd$revs[0] $infile| $patchcmd -o$file1") ; + if (system("$diffcmd$revs[0] \"$infile\" | $patchcmd -o\"$file1\"")==0 and -z $file1 ) { + # no differences detected, i.e. file is equal to current version + copy($infile,$file1) || die "copy($infile,$file1) failed: $!"; + } + } } elsif ( scalar(@revs) == 2 ) { if ( defined($flatten) ) { my $olddir=$tempdir . "/latexdiff-vc-$revs[0]"; print STDERR "Checking out old dir into: $olddir (rev: $revs[0])\n"; - checkout_dir($revs[0],$olddir); + checkout_dir($revs[0],$olddir,$infile); $file1=$olddir ."/".$infile; my $newdir=$tempdir . "/latexdiff-vc-$revs[1]"; print STDERR "Checking out new dir into: $newdir\n"; - checkout_dir($revs[1],$newdir); + checkout_dir($revs[1],$newdir,$infile); $file2=$newdir ."/".$infile; } else { ($file1=$infile) =~ s/\.(tex|bbl|flt)/-oldtmp-$$.$1/ ; @@ -468,7 +485,7 @@ while ( $infile=$file2=shift @files ) { } else { ($diff=$infile) =~ s/\.(tex|bbl|flt)$/$append.$1/ ; } - + # make directories if needed $dirname=dirname($diff) ; system("mkdir -p $dirname") unless ( -e $dirname ); @@ -488,13 +505,14 @@ while ( $infile=$file2=shift @files ) { die "Abort ... " ; } } + print STDERR "Running: $CFG{LATEXDIFF} $options \"$file1\" \"$file2\" > \"$diff\"\n"; unless ( system("$CFG{LATEXDIFF} $options \"$file1\" \"$file2\" > \"$diff\"") == 0 ) { print STDERR "Something went wrong in $CFG{LATEXDIFF}. Deleting $diff and abort\n" ; unlink $diff ; exit(5) }; print "Generated difference file $diff\n"; - if ( $run and !( scalar(@revs) && greptex( qr/\\document(?:class|style)/ , $diff ) ) ) { + if ( $run and !( scalar(@revs) && greptex( qr/\\document(?:class|style)/ , $diff,25) ) ) { # save filename for later processing if postscript or pdf conversion is requested and either two-file mode was used (scalar(@revs)==0) or the diff file contains documentclass statement (ie. is a root document) push @difffiles, $diff ; } @@ -519,19 +537,20 @@ foreach $diff ( @difffiles ) { if ( $run ) { print STDERR "PDF: $pdf Postscript: $postscript cwd $cwd\n" if $debug; - if ( system("grep -q \'^[^%]*\\\\bibliography{\' \"$diff\"") == 0 ) { - system("$CFG{LATEX} --interaction=batchmode \"$diff\"; $CFG{BIBTEX} \"$diffbase\";"); +# if ( system("grep -q \'^[^%]*\\\\bibliography{\' \"$diff\"") == 0 ) { + if ( greptex('^[^%]*\\\\bibliography{',$diff ) == 0 ) { + system("$CFG{LATEX} -draftmode -interaction=batchmode \"$diff\"; $CFG{BIBTEX} \"$diffbase\";"); push @ptmpfiles, "$diffbase.bbl","$diffbase.bbl" ; } # if special needs, as CHANGEBAR if ( $extracomp ) { # print "Extracomp\n"; - system("$CFG{LATEX} --interaction=batchmode \"$diff\";"); + system("$CFG{LATEX} -draftmode -interaction=batchmode \"$diff\";"); } # final compilation - system("$CFG{LATEX} --interaction=batchmode \"$diff\";"); # needed if cross-refs + system("$CFG{LATEX} -draftmode -interaction=batchmode \"$diff\";"); # needed if cross-refs system("$CFG{LATEX} \"$diff\";"); # final, with possible error messages if ( $rundvi2 ) { @@ -586,10 +605,10 @@ sub findchangedpages { my %start; open(AUX,$auxfile) or die ("Could open aux file $auxfile . System error: $!"); while (<AUX>) { - if (m/\\zref\@newlabel\{DIFchgb(\d*)\}\{.*\\abspage\{(\d*)\}\}/ ) { + if (m/\\zref\@newlabel\{DIFchgb(\d*)\}\{.*\\abspage\{(\d*)\}.*\}/ ) { $start{$1}=$2; $pages{$2}=1; } - if (m/\\zref\@newlabel\{DIFchge(\d*)\}\{.*\\abspage\{(\d*)\}\}/) { + if (m/\\zref\@newlabel\{DIFchge(\d*)\}\{.*\\abspage\{(\d*)\}.*\}/) { if (defined($start{$1})) { for ($j=$start{$1}; $j<=$2; $j++) { $pages{$j}=1; @@ -643,12 +662,14 @@ sub compresspages { return @res; } -# checkout_dir(rev,dirname) +# checkout_dir(rev,dirname, <file>) # checks out revision rev and stores it in dirname -# uses global variables: $vc, $rootdir +# If argument <file> is provided, check if this file imports a bibliography and generate it if necessary +# uses global variables: $vc, $rootdir, $CFG sub checkout_dir { - my ($rev,$dirname)=@_; + my ($rev,$dirname,$file)=@_; + my ($filebase,$filedir); unless (-e $dirname) { mkpath([ $dirname ]) or die "Cannot mkdir $dirname ." ;} if ( $vc eq "SVN" ) { system("svn checkout -r $rev $rootdir $dirname")==0 or die "Something went wrong in executing: svn checkout -r $rev $rootdir $dirname"; @@ -660,13 +681,25 @@ sub checkout_dir { } else { die "checkout_dir: only works with SVN, HG and GIT VCS system (selected: $vc)"; } + # Check if the main file needs a bbl generated + if ( defined($file) and greptex('^[^%]*\\\\bibliography\\{',$file) == 0) { + ($filebase,$filedir)=fileparse($file,".tex"); + if ( ! -e "$filedir$filebase.bbl" ){ + printf STDERR "Running $CFG{BIBTEX} to generate $filedir$filebase.bbl.\n"; + system("cd '$dirname'; $CFG{LATEX} -draftmode -interaction=batchmode '$file'; $CFG{BIBTEX} '$filedir$filebase'")==0 + or die "Something went wrong in executing: cd '$dirname'; $CFG{LATEX} -draftmode -interaction=batchmode '$file'; $CFG{BIBTEX} '$filedir$filebase'" ; + } +# else { # DEBUG +# printf STDERR "DEBUG: Skipping bbl file generation as $filedir$filebase.bbl already exists.\n" +# } #DEBUG + } } -# greptex returns 1 if regex is not matched in filename -# only the 25 first non-comment lines are scanned +# greptex($regex,$filename, <lines>) returns 1 if regex is not matched in filename +# only the first <lines> non-comment lines are scanned; by default everythin is scanned # 0 if there is a match sub greptex { - my ($regex,$filename)=@_; + my ($regex,$filename,$nlines)=@_; my ($i)=0; open (FH, $filename) or die("Couldn't open $filename: $!"); while (<FH>) { @@ -675,9 +708,9 @@ sub greptex { close(FH); return(0); } - # only scan 25 lines + # only scan <nlines> lines, if optional parameter proviede $i++; - last if $i>25 ; + last if defined($nlines) and $i>$nlines ; } close(FH); return(1); @@ -761,7 +794,7 @@ complete directory hierarchy. Optionally, a pathname F<path> can be specified, =item B<--flatten,--flatten=keep-intermediate> If combined with C<--git>, C<--svn> or C<--hg> option or the corresponding modes, check out the revisions to compare in a separate temporary directory, and then pass on option C<--flatten> to latexdiff. The directory in which C<latexdiff-vc> is invoked defines the subtree which will be checked out. -Note that if additional files are needed which are not included in the flatten procedure (package files, included graphics), they need to be accessible in the current directory. If you use bibtex, it is recommended to include the C<.bbl> file in the version management. +Note that if additional files are needed which are not included in the flatten procedure (package files, included graphics), they need to be accessible in the current directory. If you use bibtex, it is recommended to include the C<.bbl> file in the version management. From latexdiff-vc >=1.3.4 there is an attempt to create the C<.bbl> file by running bibtex in the retrieved subdirectories; note that the bibtex is run in the temporary subdirectories so any .bib or .bst files either need to be under version management, or in the global search paths for bibtex (shell environment variables C<BIBINPUTS> and C<BSTINPUTS>). The generic usage of this function is : C<latexdiff-vc --flatten -r rev1 [-r rev2] master.tex> where master.tex is the project file containing the highest level of includes etc. @@ -798,7 +831,7 @@ Available variables for latexdiff-vc: =over 8 -=item C<LATEXDIFF> latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the option C<--interaction=batchmode> +=item C<LATEXDIFF> latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the options C<-draftmode> and C<-interaction=batchmode> =item C<LATEX> latex command (e.g. pdflatex, lualatex) @@ -847,7 +880,7 @@ Show version number =back -All other options are passed on to C<latexdiff>. +All other options are passed on to C<latexdiff>. Note that it is not always easy for latexdiff to correctly assign arguments to options when short form (single letter) options are used so it is recommended to use long-form options. =head1 SEE ALSO @@ -868,7 +901,7 @@ or send them to I<tilmann -- AT -- gfz-potsdam.de>. Include the version number =head1 AUTHOR -Version 1.3.2 +Version 1.3.4a Copyright (C) 2005-2017 Frederik Tilmann This program is free software; you can redistribute it and/or modify diff --git a/support/latexdiff/latexdiff-vc.1 b/support/latexdiff/latexdiff-vc.1 index 8b6c6f8db7..8ed1715873 100644 --- a/support/latexdiff/latexdiff-vc.1 +++ b/support/latexdiff/latexdiff-vc.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "LATEXDIFF-VC 1" -.TH LATEXDIFF-VC 1 "2022-03-05" "perl v5.30.0" " " +.TH LATEXDIFF-VC 1 "2024-07-20" "perl v5.34.0" " " .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -204,7 +204,7 @@ complete directory hierarchy. Optionally, a pathname \fIpath\fR can be specifie .IP "\fB\-\-flatten,\-\-flatten=keep\-intermediate\fR" 4 .IX Item "--flatten,--flatten=keep-intermediate" If combined with \f(CW\*(C`\-\-git\*(C'\fR, \f(CW\*(C`\-\-svn\*(C'\fR or \f(CW\*(C`\-\-hg\*(C'\fR option or the corresponding modes, check out the revisions to compare in a separate temporary directory, and then pass on option \f(CW\*(C`\-\-flatten\*(C'\fR to latexdiff. The directory in which \f(CW\*(C`latexdiff\-vc\*(C'\fR is invoked defines the subtree which will be checked out. -Note that if additional files are needed which are not included in the flatten procedure (package files, included graphics), they need to be accessible in the current directory. If you use bibtex, it is recommended to include the \f(CW\*(C`.bbl\*(C'\fR file in the version management. +Note that if additional files are needed which are not included in the flatten procedure (package files, included graphics), they need to be accessible in the current directory. If you use bibtex, it is recommended to include the \f(CW\*(C`.bbl\*(C'\fR file in the version management. From latexdiff-vc >=1.3.4 there is an attempt to create the \f(CW\*(C`.bbl\*(C'\fR file by running bibtex in the retrieved subdirectories; note that the bibtex is run in the temporary subdirectories so any .bib or .bst files either need to be under version management, or in the global search paths for bibtex (shell environment variables \f(CW\*(C`BIBINPUTS\*(C'\fR and \f(CW\*(C`BSTINPUTS\*(C'\fR). .Sp The generic usage of this function is : \f(CW\*(C`latexdiff\-vc \-\-flatten \-r rev1 [\-r rev2] master.tex\*(C'\fR where master.tex is the project file containing the highest level of includes etc. .Sp @@ -232,9 +232,9 @@ Set configuration variables for latexdiff and latexdiff-vc. The option can be r variables (as an alternative to the comma-separated list). Available variables for latexdiff-vc: .RS 4 -.ie n .IP """LATEXDIFF"" latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the option ""\-\-interaction=batchmode""" 8 -.el .IP "\f(CWLATEXDIFF\fR latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the option \f(CW\-\-interaction=batchmode\fR" 8 -.IX Item "LATEXDIFF latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the option --interaction=batchmode" +.ie n .IP """LATEXDIFF"" latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the options ""\-draftmode"" and ""\-interaction=batchmode""" 8 +.el .IP "\f(CWLATEXDIFF\fR latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the options \f(CW\-draftmode\fR and \f(CW\-interaction=batchmode\fR" 8 +.IX Item "LATEXDIFF latexdiff command (e.g. latexdiff-fast, latexdiff-so). This command should support the options -draftmode and -interaction=batchmode" .PD 0 .ie n .IP """LATEX"" latex command (e.g. pdflatex, lualatex)" 8 .el .IP "\f(CWLATEX\fR latex command (e.g. pdflatex, lualatex)" 8 @@ -280,7 +280,7 @@ Show help text .IX Item "--version" Show version number .PP -All other options are passed on to \f(CW\*(C`latexdiff\*(C'\fR. +All other options are passed on to \f(CW\*(C`latexdiff\*(C'\fR. Note that it is not always easy for latexdiff to correctly assign arguments to options when short form (single letter) options are used so it is recommended to use long-form options. .SH "SEE ALSO" .IX Header "SEE ALSO" latexdiff @@ -297,7 +297,7 @@ or send them to \fItilmann \*(-- \s-1AT\s0 \*(-- gfz\-potsdam.de\fR. Include th (option \f(CW\*(C`\-\-version\*(C'\fR). .SH "AUTHOR" .IX Header "AUTHOR" -Version 1.3.2 +Version 1.3.4a Copyright (C) 2005\-2017 Frederik Tilmann .PP This program is free software; you can redistribute it and/or modify diff --git a/support/latexdiff/latexdiff.1 b/support/latexdiff/latexdiff.1 index 53644f607e..a52d6f03ac 100644 --- a/support/latexdiff/latexdiff.1 +++ b/support/latexdiff/latexdiff.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "LATEXDIFF 1" -.TH LATEXDIFF 1 "2022-09-25" "perl v5.30.0" " " +.TH LATEXDIFF 1 "2024-07-20" "perl v5.34.0" " " .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -158,8 +158,8 @@ be real files (not pipes or similar) as they are opened twice (unless \f(CW\*(C` The program treats the preamble differently from the main document. Differences between the preambles are found using line-based differencing (similarly to the Unix diff command, but ignoring white -spaces). A comment, "\f(CW\*(C`%DIF\ >\*(C'\fR" is appended to each added line, i.e. a -line present in \f(CW\*(C`new.tex\*(C'\fR but not in \f(CW\*(C`old.tex\*(C'\fR. Discarded lines +spaces). A comment, "\f(CW\*(C`%DIF\ >\*(C'\fR" is appended to each added line, i.e. a +line present in \f(CW\*(C`new.tex\*(C'\fR but not in \f(CW\*(C`old.tex\*(C'\fR. Discarded lines are deactivated by prepending "\f(CW\*(C`%DIF\ <\*(C'\fR". Changed blocks are preceded by comment lines giving information about line numbers in the original files. Where there are insignificant differences, the resulting file \f(CW\*(C`diff.tex\*(C'\fR will be similar to @@ -238,7 +238,7 @@ but the choice is yours. Any markup within the environment will be removed, and generally everything within the environment will just be taken from the new file. .PP -It is also possible to difference files which do not have a preamble. +It is also possible to difference files which do not have a preamble. In this case, the file is processed in the main document mode, but the definitions of the markup commands are not inserted. .PP @@ -256,14 +256,14 @@ the scope of \f(CW\*(C`\eDIFadd\*(C'\fR. Added comments are marked by prependin .PP Within deleted blocks text is highlighted with \f(CW\*(C`\eDIFdel\*(C'\fR. Deleted comments are marked by prepending "\f(CW\*(C`%DIF\ <\ \*(C'\fR\*(L". Non-safe command -and curly braces within deleted blocks are commented out with +and curly braces within deleted blocks are commented out with \&\*(R"\f(CW\*(C`%DIFDELCMD\ <\ \*(C'\fR". .SH "OPTIONS" .IX Header "OPTIONS" .SS "Preamble" .IX Subsection "Preamble" The following options determine the visual markup style by adding the appropriate -command definitions to the preamble. See the end of this section for a description of +command definitions to the preamble. See the end of this section for a description of available styles. .IP "\fB\-\-type=markupstyle\fR or \fB\-t markupstyle\fR" 4 .IX Item "--type=markupstyle or -t markupstyle" @@ -271,8 +271,9 @@ Add code to preamble for selected markup style. This option defines \&\f(CW\*(C`\eDIFadd\*(C'\fR and \f(CW\*(C`\eDIFdel\*(C'\fR commands. Available styles: .Sp -\&\f(CW\*(C`UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE -CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT\*(C'\fR +\&\f(CW\*(C`UNDERLINE CTRADITIONAL TRADITIONAL CFONT FONTSTRIKE INVISIBLE +CHANGEBAR CCHANGEBAR CULINECHBAR CFONTCHBAR BOLD PDFCOMMENT +LUAUNDERLINE\*(C'\fR .Sp [ Default: \f(CW\*(C`UNDERLINE\*(C'\fR ] .IP "\fB\-\-subtype=markstyle\fR or \fB\-s markstyle\fR" 4 @@ -286,10 +287,10 @@ Available styles: \f(CW\*(C`SAFE MARGIN COLOR DVIPSCOL ZLABEL ONLYCHANGEDPAGE ( * Subtype \f(CW\*(C`LABEL\*(C'\fR is deprecated .IP "\fB\-\-floattype=markstyle\fR or \fB\-f markstyle\fR" 4 .IX Item "--floattype=markstyle or -f markstyle" -Add code to preamble for selected style which +Add code to preamble for selected style which replace standard marking and markup commands within floats (e.g., marginal remarks cause an error within floats -so marginal marking can be disabled thus). This option defines all +so marginal marking can be disabled thus). This option defines all \&\f(CW\*(C`\eDIF...FL\*(C'\fR commands. Available styles: \f(CW\*(C`FLOATSAFE TRADITIONALSAFE IDENTICAL\*(C'\fR .Sp @@ -297,14 +298,14 @@ Available styles: \f(CW\*(C`FLOATSAFE TRADITIONALSAFE IDENTICAL\*(C'\fR .IP "\fB\-\-encoding=enc\fR or \fB\-e enc\fR" 4 .IX Item "--encoding=enc or -e enc" Specify encoding of old.tex and new.tex. Typical encodings are -\&\f(CW\*(C`ascii\*(C'\fR, \f(CW\*(C`utf8\*(C'\fR, \f(CW\*(C`latin1\*(C'\fR, \f(CW\*(C`latin9\*(C'\fR. A list of available encodings can be +\&\f(CW\*(C`ascii\*(C'\fR, \f(CW\*(C`utf8\*(C'\fR, \f(CW\*(C`latin1\*(C'\fR, \f(CW\*(C`latin9\*(C'\fR. A list of available encodings can be obtained by executing .Sp \&\f(CW\*(C`perl \-MEncode \-e \*(Aqprint join ("\en",Encode\-\*(C'\fRencodings( \*(L":all\*(R" )) ;' > .Sp If this option is used, then old.tex, new.tex are only opened once. [Default encoding is utf8 unless the first few lines of the preamble contain -an invocation \f(CW\*(C`\eusepackage[..]{inputenc}\*(C'\fR in which case the +an invocation \f(CW\*(C`\eusepackage[..]{inputenc}\*(C'\fR in which case the encoding chosen by this command is asssumed. Note that \s-1ASCII\s0 (standard latex) is a subset of utf8] .IP "\fB\-\-preamble=file\fR or \fB\-p file\fR" 4 @@ -334,7 +335,7 @@ Ensure that \f(CW\*(C`\ebegin{figure}\*(C'\fR and \f(CW\*(C`\eend{figure}\*(C'\f .ie n .IP """hyperref""" 8 .el .IP "\f(CWhyperref\fR" 8 .IX Item "hyperref" -Change name of \f(CW\*(C`\eDIFadd\*(C'\fR and \f(CW\*(C`\eDIFdel\*(C'\fR commands to \f(CW\*(C`\eDIFaddtex\*(C'\fR and \f(CW\*(C`\eDIFdeltex\*(C'\fR and +Change name of \f(CW\*(C`\eDIFadd\*(C'\fR and \f(CW\*(C`\eDIFdel\*(C'\fR commands to \f(CW\*(C`\eDIFaddtex\*(C'\fR and \f(CW\*(C`\eDIFdeltex\*(C'\fR and define new \f(CW\*(C`\eDIFadd\*(C'\fR and \f(CW\*(C`\eDIFdel\*(C'\fR commands, which provide a wrapper for these commands, using them for the text but not for the link defining command (where any markup would cause errors). @@ -384,13 +385,13 @@ Print generated or included preamble commands to stdout. .IX Item "--append-safecmd=append-file or -a append-file or --append-safecmd=cmd1,cmd2,..." .PD Exclude from, replace or append to the list of regular expressions (RegEx) -matching commands which are safe to use within the +matching commands which are safe to use within the scope of a \f(CW\*(C`\eDIFadd\*(C'\fR or \f(CW\*(C`\eDIFdel\*(C'\fR command. The file must contain one Perl-RegEx per line (Comment lines beginning with # or % are -ignored). Note that the RegEx needs to match the whole of +ignored). Note that the RegEx needs to match the whole of the token, i.e., /^regex$/ is implied and that the initial -\&\*(L"\e\*(R" of the command is not included. -The \fB\-\-exclude\-safecmd\fR and \fB\-\-append\-safecmd\fR options can be combined with the \-\fB\-\-replace\-safecmd\fR +\&\*(L"\e\*(R" of the command is not included. +The \fB\-\-exclude\-safecmd\fR and \fB\-\-append\-safecmd\fR options can be combined with the \-\fB\-\-replace\-safecmd\fR option and can be used repeatedly to add cumulatively to the lists. \fB\-\-exclude\-safecmd\fR and \fB\-\-append\-safecmd\fR can also take a comma separated list as input. If a @@ -422,7 +423,7 @@ entry for \fB\-\-exclude\-safecmd\fR directly above for further details. Replace or append to the list of regex matching commands whose last argument is text but which require a particular context to work, e.g. \f(CW\*(C`\ecaption\*(C'\fR will only work within a figure -or table. These commands behave like text commands, except when +or table. These commands behave like text commands, except when they occur in a deleted section, when they are disabled, but their argument is shown as deleted text. .IP "\fB\-\-replace\-context2cmd=replace\-file\fR" 4 @@ -438,7 +439,7 @@ As corresponding commands for context1. The only difference is that context2 commands are completely disabled in deleted sections, including their arguments. .Sp -context2 commands are also the only commands in the preamble, whose argument will be processed in +context2 commands are also the only commands in the preamble, whose argument will be processed in word-by-word mode (which only works, if they occur no more than once in the preamble). The algorithm currently cannot cope with repeated context2 commands in the preamble, as they occur e.g. for the \f(CW\*(C`\eauthor\*(C'\fR argument in some journal styles (not in the standard styles, though If such a repetition is detected, the whole preamble will be processed in line-by-line mode. In such a case, use \f(CW\*(C`\-\-replace\-context2cmd\*(C'\fR option to just select the commands, which should be processed and are not used repeatedly in the preamble. .ie n .IP "\fB\-\-exclude\-mboxsafecmd=exclude\-file\fR or \fB\-\-exclude\-mboxsafecmd=""cmd1,cmd2,...""\fR" 4 @@ -450,7 +451,7 @@ If such a repetition is detected, the whole preamble will be processed in line-b .IX Item "--append-mboxsafecmd=append-file or --append-mboxsafecmd=cmd1,cmd2,..." .PD Define safe commands, which additionally need to be protected by encapsulating -in an \f(CW\*(C`\embox{..}\*(C'\fR. This is sometimes needed to get around incompatibilities +in an \f(CW\*(C`\embox{..}\*(C'\fR. This is sometimes needed to get around incompatibilities between external packages and the ulem package, which is used for highlighting in the default style \s-1UNDERLINE\s0 as well as \s-1CULINECHBAR CFONTSTRIKE\s0 .IP "\fB\-\-config var1=val1,var2=val2,...\fR or \fB\-c var1=val1,..\fR" 4 @@ -489,10 +490,10 @@ Available variables (see below for further explanations): .IP "\fB\-\-add\-to\-config varenv1=pattern1,varenv2=pattern2,...\fR" 4 .IX Item "--add-to-config varenv1=pattern1,varenv2=pattern2,..." For configuration variables, which are a regular expression (essentially those ending -in \s-1ENV, COUNTERCMD\s0 and \s-1CUSTOMDIFCMD,\s0 see list above) this option provides an alternative way to modify the configuration +in \s-1ENV, COUNTERCMD\s0 and \s-1CUSTOMDIFCMD,\s0 see list above) this option provides an alternative way to modify the configuration variables. Instead of setting the complete pattern, with this option it is possible to add an alternative pattern. \f(CW\*(C`varenv\*(C'\fR must be one of the variables listed above that take a regular -expression as argument, and pattern is any regular expression (which might need to be +expression as argument, and pattern is any regular expression (which might need to be protected from the shell by quotation). Several patterns can be added at once by using semi-colons to separate them, e.g. \f(CW\*(C`\-\-add\-to\-config "LISTENV=myitemize;myenumerate,COUNTERCMD=endnote"\*(C'\fR .IP "\fB\-\-show\-safecmd\fR" 4 @@ -508,7 +509,7 @@ Show values of configuration variables. .IX Item "--show-all" Combine all \-\-show commands. .Sp -\&\s-1NB\s0 For all \-\-show commands, no \f(CW\*(C`old.tex\*(C'\fR or \f(CW\*(C`new.tex\*(C'\fR file needs to be specified, and no +\&\s-1NB\s0 For all \-\-show commands, no \f(CW\*(C`old.tex\*(C'\fR or \f(CW\*(C`new.tex\*(C'\fR file needs to be specified, and no differencing takes place. .SS "Other configuration options:" .IX Subsection "Other configuration options:" @@ -521,20 +522,20 @@ default produces erroneous results. (Default requires arguments to directly follow each other without intervening spaces). .IP "\fB\-\-math\-markup=level\fR" 4 .IX Item "--math-markup=level" -Determine granularity of markup in displayed math environments: +Determine granularity of markup in displayed math environments: Possible values for level are (both numerical and text labels are acceptable): .Sp -\&\f(CW\*(C`off\*(C'\fR or \f(CW0\fR: suppress markup for math environments. Deleted equations will not -appear in diff file. This mode can be used if all the other modes +\&\f(CW\*(C`off\*(C'\fR or \f(CW0\fR: suppress markup for math environments. Deleted equations will not +appear in diff file. This mode can be used if all the other modes cause invalid latex code. .Sp \&\f(CW\*(C`whole\*(C'\fR or \f(CW1\fR: Differencing on the level of whole equations. Even trivial changes -to equations cause the whole equation to be marked changed. This -mode can be used if processing in coarse or fine mode results in +to equations cause the whole equation to be marked changed. This +mode can be used if processing in coarse or fine mode results in invalid latex code. .Sp \&\f(CW\*(C`coarse\*(C'\fR or \f(CW2\fR: Detect changes within equations marked up with a coarse -granularity; changes in equation type (e.g.displaymath to equation) +granularity; changes in equation type (e.g.displaymath to equation) appear as a change to the complete equation. This mode is recommended for situations where the content and order of some equations are still being changed. [Default] @@ -554,29 +555,29 @@ Possible values for level: .Sp \&\f(CW\*(C`new\-only\*(C'\fR or \f(CW1\fR: surround newly added or changed figures with a blue frame [Default if graphicx package loaded] .Sp -\&\f(CW\*(C`both\*(C'\fR or \f(CW2\fR: highlight new figures with a blue frame and show deleted figures at reduced +\&\f(CW\*(C`both\*(C'\fR or \f(CW2\fR: highlight new figures with a blue frame and show deleted figures at reduced scale, and crossed out with a red diagonal cross. Use configuration variable \s-1SCALEDELGRAPHICS\s0 to set size of deleted figures. .Sp -Note that changes to the optional parameters will make the figure appear as changed +Note that changes to the optional parameters will make the figure appear as changed to latexdiff, and this figure will thus be highlighted. .Sp In some circumstances \*(L"Misplaced \enoalign\*(R" error can occur if there are certain types -of changes in tables. In this case please use \f(CW\*(C`\-\-graphics\-markup=none\*(C'\fR as a +of changes in tables. In this case please use \f(CW\*(C`\-\-graphics\-markup=none\*(C'\fR as a work-around. .IP "\fB\-\-no\-del\fR" 4 .IX Item "--no-del" -Suppress deleted text from the diff. It is similar in effect to the \s-1BOLD\s0 style, -but the deleted text ist not just invisible in the output, it is also not included in the diff text file. +Suppress deleted text from the diff. It is similar in effect to the \s-1BOLD\s0 style, +but the deleted text ist not just invisible in the output, it is also not included in the diff text file. This can be more robust than just making it invisible. .IP "\fB\-\-disable\-citation\-markup\fR or \fB\-\-disable\-auto\-mbox\fR" 4 .IX Item "--disable-citation-markup or --disable-auto-mbox" -Suppress citation markup and markup of other vulnerable commands in styles +Suppress citation markup and markup of other vulnerable commands in styles using ulem (\s-1UNDERLINE,FONTSTRIKE, CULINECHBAR\s0) (the two options are identical and are simply aliases) .IP "\fB\-\-enable\-citation\-markup\fR or \fB\-\-enforce\-auto\-mbox\fR" 4 .IX Item "--enable-citation-markup or --enforce-auto-mbox" -Protect citation commands and other vulnerable commands in changed sections +Protect citation commands and other vulnerable commands in changed sections with \f(CW\*(C`\embox\*(C'\fR command, i.e. use default behaviour for ulem package for other packages (the two options are identical and are simply aliases) .SS "Miscellaneous" @@ -611,17 +612,17 @@ labels like this \f(CW\*(C`\-L labelold \-L labelnew\*(C'\fR. Suppress inclusion of old and new file names as comment in output file .IP "\fB\-\-visible\-label\fR" 4 .IX Item "--visible-label" -Include old and new filenames (or labels set with \f(CW\*(C`\-\-label\*(C'\fR option) as +Include old and new filenames (or labels set with \f(CW\*(C`\-\-label\*(C'\fR option) as visible output. .IP "\fB\-\-flatten\fR" 4 .IX Item "--flatten" Replace \f(CW\*(C`\einput\*(C'\fR and \f(CW\*(C`\einclude\*(C'\fR commands within body by the content of the files in their argument. If \f(CW\*(C`\eincludeonly\*(C'\fR is present in the -preamble, only those files are expanded into the document. However, -no recursion is done, i.e. \f(CW\*(C`\einput\*(C'\fR and \f(CW\*(C`\einclude\*(C'\fR commands within -included sections are not expanded. The included files are assumed to +preamble, only those files are expanded into the document. However, +no recursion is done, i.e. \f(CW\*(C`\einput\*(C'\fR and \f(CW\*(C`\einclude\*(C'\fR commands within +included sections are not expanded. The included files are assumed to be located in the same directories as the old and new master files, -respectively, making it possible to organise files into old and new directories. +respectively, making it possible to organise files into old and new directories. \&\-\-flatten is applied recursively, so inputted files can contain further \&\f(CW\*(C`\einput\*(C'\fR statements. Also handles files included by the import package (\f(CW\*(C`\eimport\*(C'\fR and \f(CW\*(C`\esubimport\*(C'\fR), and \f(CW\*(C`\esubfile\*(C'\fR command. @@ -660,10 +661,15 @@ The major type determine the markup of plain text and some selected latex comman .IX Item "UNDERLINE" Added text is wavy-underlined and blue, discarded text is struck out and red (Requires color and ulem packages). Overstriking does not work in displayed math equations such that deleted parts of equation are underlined, not struck out (this is a shortcoming inherent to the ulem package). +.ie n .IP """LUAUNDERLINE""" 10 +.el .IP "\f(CWLUAUNDERLINE\fR" 10 +.IX Item "LUAUNDERLINE" +Added text is underlined and blue, discarded text is struck out and red +(Requires lua-ul package + LuaLaTeX). .ie n .IP """CTRADITIONAL""" 10 .el .IP "\f(CWCTRADITIONAL\fR" 10 .IX Item "CTRADITIONAL" -Added text is blue and set in sans-serif, and a red footnote is created for each discarded +Added text is blue and set in sans-serif, and a red footnote is created for each discarded piece of text. (Requires color package) .ie n .IP """TRADITIONAL""" 10 .el .IP "\f(CWTRADITIONAL\fR" 10 @@ -723,7 +729,7 @@ from the intended position. .IX Item "COLOR" An alternative way of marking added passages in blue, and deleted ones in red. (It is recommeneded to use instead the main types to effect colored markup, -although in some cases coloring with dvipscol can be more complete, for example +although in some cases coloring with dvipscol can be more complete, for example with citation commands). .ie n .IP """DVIPSCOL""" 10 .el .IP "\f(CWDVIPSCOL\fR" 10 @@ -747,7 +753,7 @@ there is floating material (figures, tables). is similar to \f(CW\*(C`ZLABEL\*(C'\fR, but does not need the zref package and works less reliably (deprecated). .SS "Float Types" .IX Subsection "Float Types" -Some of the markup used in the main text might cause problems when used within +Some of the markup used in the main text might cause problems when used within floats (e.g. figures or tables). For this reason alternative versions of all markup commands are used within floats. The float type defines these alternative commands. .ie n .IP """FLOATSAFE""" 10 @@ -767,7 +773,7 @@ Make no difference between the main text and floats. .ie n .IP """ARRENV""" 10 .el .IP "\f(CWARRENV\fR" 10 .IX Item "ARRENV" -If a match to \f(CW\*(C`ARRENV\*(C'\fR is found within an inline math environment within a deleted or added block, then the inlined math +If a match to \f(CW\*(C`ARRENV\*(C'\fR is found within an inline math environment within a deleted or added block, then the inlined math is surrounded by \f(CW\*(C`\embox{\*(C'\fR...\f(CW\*(C`}\*(C'\fR. This is necessary as underlining does not work within inlined array environments. .Sp [ Default: \f(CW\*(C`ARRENV\*(C'\fR=\f(CW\*(C`(?:array|[pbvBV]matrix)\*(C'\fR\ @@ -787,9 +793,9 @@ numbering in the new file. This option is for advanced users and allows definition of special versions of commands, which do not work as safe commands. .Sp Commands in \f(CW\*(C`CUSTOMDIFCMD\*(C'\fR that occur in added or deleted blocks will be given an \s-1ADD\s0 or \s-1DEL\s0 prefix. -The prefixed versions of the command must be defined in the preamble, either by putting them +The prefixed versions of the command must be defined in the preamble, either by putting them in the preamble of at least the new file, or by creating a custom preamble file (Option \-\-preamble). -For example the command \f(CW\*(C`\eblindtext\*(C'\fR (from package blindtext) does not interact well with underlining, so that +For example the command \f(CW\*(C`\eblindtext\*(C'\fR (from package blindtext) does not interact well with underlining, so that for the standard markup type, it is not satisfactory to define it as a safe command. Instead, a customised versions without underlining can be defined in the preamble: .Sp @@ -803,7 +809,7 @@ and then latexdiff should be invoked with the option \f(CW\*(C`\-c CUSTOMDIFCMD= .ie n .IP """FLOATENV""" 10 .el .IP "\f(CWFLOATENV\fR" 10 .IX Item "FLOATENV" -Environments whose name matches the regular expression in \f(CW\*(C`FLOATENV\*(C'\fR are +Environments whose name matches the regular expression in \f(CW\*(C`FLOATENV\*(C'\fR are considered floats. Within these environments, the \fIlatexdiff\fR markup commands are replaced by their \s-1FL\s0 variaties. .Sp @@ -852,55 +858,62 @@ If \f(CW\*(C`\-\-graphics\-markup=both\*(C'\fR is chosen, \f(CW\*(C`SCALEDELGRAP .ie n .IP """VERBATIMENV""" 10 .el .IP "\f(CWVERBATIMENV\fR" 10 .IX Item "VERBATIMENV" -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of these environments will not be processed in any way: deleted content is commented out, new content is not marked up .Sp [ Default: \f(CW\*(C`comment\*(C'\fR\ ] .ie n .IP """VERBATIMLINEENV""" 10 .el .IP "\f(CWVERBATIMLINEENV\fR" 10 .IX Item "VERBATIMLINEENV" -RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by \s-1VERBATIMLINEENV\s0 are compared in +RegEx describing environments like verbatim, whose contents should be taken verbatim. The content of environments described by \s-1VERBATIMLINEENV\s0 are compared in line mode, and changes are marked up using the listings package. The markup style is set based on the chosen mains markup type (Option \-t), or on an analysis of the preamble. -Note that \*(L"listings.sty\*(R" must be installed. If this file is not found the fallback solution is to +Note that \*(L"listings.sty\*(R" must be installed. If this file is not found the fallback solution is to treat \s-1VERBATIMLINEENV\s0 environments treated exactly the same way as \s-1VERBATIMENV\s0 environments. .Sp [ Default: \f(CW\*(C`(?:verbatim[*]?|lstlisting\*(C'\fR\ ] .SH "COMMON PROBLEMS AND FAQ" .IX Header "COMMON PROBLEMS AND FAQ" -.IP "Citations result in overfull boxes" 10 -.IX Item "Citations result in overfull boxes" +.IP "Changed citations result in overfull boxes" 10 +.IX Item "Changed citations result in overfull boxes" There is an incompatibility between the \f(CW\*(C`ulem\*(C'\fR package, which \f(CW\*(C`latexdiff\*(C'\fR uses for underlining and striking out in the \s-1UNDERLINE\s0 style, -the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an \f(CW\*(C`\embox\*(C'\fR -command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have two possibilities. +the default style, and the way citations are generated. In order to be able to mark up citations properly, they are enclosed with an \f(CW\*(C`\embox\*(C'\fR +command. As mboxes cannot be broken across lines, this procedure frequently results in overfull boxes, possibly obscuring the content as it extends beyond the right margin. The same occurs for some other packages (e.g., siunitx). If this is a problem, you have several possibilities. .Sp 1. Use \f(CW\*(C`CFONT\*(C'\fR type markup (option \f(CW\*(C`\-t CFONT\*(C'\fR): If this markup is chosen, then changed citations are no longer marked up with the wavy line (additions) or struck out (deletions), but are still highlighted in the appropriate color, and deleted text is shown with a different font. Other styles not using the \f(CW\*(C`ulem\*(C'\fR package will also work. .Sp 2. Choose option \f(CW\*(C`\-\-disable\-citation\-markup\*(C'\fR which turns off the marking up of citations: deleted citations are no longer shown, and -added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older) -.Sp +added citations are shown without markup. (This was the default behaviour of latexdiff at versions 0.6 and older). For custom packages you can define the commands which need to be protected by \f(CW\*(C`\embox\*(C'\fR with \f(CW\*(C`\-\-append\-mboxsafecmd\*(C'\fR and \f(CW\*(C`\-\-excludemboxsafecmd\*(C'\fR options (submit your lists of command as feature request at github page to set the default behaviour of future versions, see section 6) -.IP "Changes in complicated mathematical equations result in latex processing errors" 10 -.IX Item "Changes in complicated mathematical equations result in latex processing errors" -Try options \f(CW\*(C`\-\-math\-markup=whole\*(C'\fR. If even that fails, you can turn off mark up for equations with \f(CW\*(C`\-\-math\-markup=off\*(C'\fR. -.IP "How can I just show the pages where changes had been made" 10 -.IX Item "How can I just show the pages where changes had been made" -Use options \-\f(CW\*(C`\-s ZLABEL\*(C'\fR (some postprocessing required) or \f(CW\*(C`\-s ONLYCHANGEDPAGE\*(C'\fR. \f(CW\*(C`latexdiff\-vc \-\-ps|\-\-pdf\*(C'\fR with \f(CW\*(C`\-\-only\-changes\*(C'\fR option takes care of +.Sp +3. If you are using luatex >= 1.12.0 you can use option \s-1LUAUNDERLINE\s0 that uses lua-ul instead of ulem for underlining, which does not have this problem (experimental feature). +.IP "Changes in complicated mathematical equations result in latex processing errors." 10 +.IX Item "Changes in complicated mathematical equations result in latex processing errors." +Try option \f(CW\*(C`\-\-math\-markup=whole\*(C'\fR. If even that fails, you can turn off mark up for equations with \f(CW\*(C`\-\-math\-markup=off\*(C'\fR. +.IP "Deleted parts in equations are not struck out but underlined." 10 +.IX Item "Deleted parts in equations are not struck out but underlined." +This is a limitation of the ulem package that implements the strike-out. If you use the amsmath package, then the strike-out command is redefined in such a way that deleted passages are wrapped with \f(CW\*(C`\etext\*(C'\fR command; adding \f(CW\*(C`\eusepackage{amsmath}\*(C'\fR to your preamble will trigger this behaviour. (If amsmath is not included directly, but imported by another package, latexdiff will not be able to detect its availability; in this case you can give latexdiff a hint with option \f(CW\*(C`\-\-packages=amsmath\*(C'\fR. +.IP "How can I just show the pages where changes had been made?" 10 +.IX Item "How can I just show the pages where changes had been made?" +Use options \f(CW\*(C`\-\-s ZLABEL\*(C'\fR (some postprocessing required) or \f(CW\*(C`\-s ONLYCHANGEDPAGE\*(C'\fR. \f(CW\*(C`latexdiff\-vc \-\-ps|\-\-pdf\*(C'\fR with \f(CW\*(C`\-\-only\-changes\*(C'\fR option takes care of the post-processing for you (requires zref package to be installed). +.IP "The character encoding breaks when running latexdiff from powershell." 10 +.IX Item "The character encoding breaks when running latexdiff from powershell." +This problem is not limited to \f(CW\*(C`latexdiff\*(C'\fR and has to do with the default settings of \f(CW\*(C`powershell\*(C'\fR in Windows. It is recommended to use \f(CW\*(C`cmd\*(C'\fR instead. .SH "BUGS" .IX Header "BUGS" .IP "Option allow-spaces not implemented entirely consistently. It breaks the rules that number and type of white space does not matter, as different numbers of inter-argument spaces are treated as significant." 10 .IX Item "Option allow-spaces not implemented entirely consistently. It breaks the rules that number and type of white space does not matter, as different numbers of inter-argument spaces are treated as significant." .PP -Please submit bug reports using the issue tracker of the github repository page \fIhttps://github.com/ftilmann/latexdiff.git\fR, +Please submit bug reports using the issue tracker of the github repository page \fIhttps://github.com/ftilmann/latexdiff.git\fR, or send them to \fItilmann \*(-- \s-1AT\s0 \*(-- gfz\-potsdam.de\fR. Include the version number of \fIlatexdiff\fR (from comments at the top of the source or use \fB\-\-version\fR). If you come across latex files that are error-free and conform to the specifications set out above, and whose differencing still does not result in error-free latex, please send me those files, ideally edited to only contain the -offending passage as long as that still reproduces the problem. If your +offending passage as long as that still reproduces the problem. If your file relies on non-standard class files, you must include those. I will not look at examples where I have trouble to latex the original files. .SH "SEE ALSO" @@ -909,22 +922,22 @@ latexrevise, latexdiff-vc .SH "PORTABILITY" .IX Header "PORTABILITY" \&\fIlatexdiff\fR does not make use of external commands and thus should run -on any platform supporting Perl 5.6 or higher. If files with encodings +on any platform supporting Perl 5.6 or higher. If files with encodings other than \s-1ASCII\s0 or \s-1UTF\-8\s0 are processed, Perl 5.8 or higher is required. .PP The standard version of \fIlatexdiff\fR requires installation of the Perl package -\&\f(CW\*(C`Algorithm::Diff\*(C'\fR (available from \fIwww.cpan.org\fR \- +\&\f(CW\*(C`Algorithm::Diff\*(C'\fR (available from \fIwww.cpan.org\fR \- \&\fIhttp://search.cpan.org/~nedkonz/Algorithm\-Diff\-1.15\fR) but a stand-alone version, \fIlatexdiff-so\fR, which has this package inlined, is available, too. \&\fIlatexdiff-fast\fR requires the \fIdiff\fR command to be present. .SH "AUTHOR" .IX Header "AUTHOR" -Version 1.3.3 -Copyright (C) 2004\-2022 Frederik Tilmann +Version 1.3.4 +Copyright (C) 2004\-2024 Frederik Tilmann .PP This program is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License Version 3 .PP -Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, +Contributors of fixes and additions: V. Kuhlmann, J. Paisley, N. Becker, T. Doerges, K. Huebner, T. Connors, Sebastian Gouezel and many others. Thanks to the many people who sent in bug reports, feature suggestions, and other feedback. diff --git a/support/latexdiff/latexrevise.1 b/support/latexdiff/latexrevise.1 index a67d09564f..d2d91dbe41 100644 --- a/support/latexdiff/latexrevise.1 +++ b/support/latexdiff/latexrevise.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "LATEXREVISE 1" -.TH LATEXREVISE 1 "2021-12-27" "perl v5.30.0" " " +.TH LATEXREVISE 1 "2021-12-27" "perl v5.34.0" " " .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff --git a/support/luafindfont/CHANGELOG b/support/luafindfont/CHANGELOG index 783f804f29..a629f6617a 100644 --- a/support/luafindfont/CHANGELOG +++ b/support/luafindfont/CHANGELOG @@ -1,3 +1,4 @@ +0.14 2024-08-25 - small changes to the output 0.13 2023-06-23 - add exrun:close() for every kpsewhich test 0.12 2023-06-21 - bugfix for undefined exrun (l. 251) - check for empty font list and given font number diff --git a/support/luafindfont/doc/luafindfont-doc.pdf b/support/luafindfont/doc/luafindfont-doc.pdf Binary files differindex 65be6ced10..f51c3478b8 100644 --- a/support/luafindfont/doc/luafindfont-doc.pdf +++ b/support/luafindfont/doc/luafindfont-doc.pdf diff --git a/support/luafindfont/doc/luafindfont-doc.tex b/support/luafindfont/doc/luafindfont-doc.tex index c10483ce5a..818cd16fbb 100644 --- a/support/luafindfont/doc/luafindfont-doc.tex +++ b/support/luafindfont/doc/luafindfont-doc.tex @@ -1,4 +1,4 @@ - %% $Id: luafindfont-doc.tex 648 2022-11-03 19:58:48Z herbert $ + %% $Id: luafindfont-doc.tex 962 2024-08-25 16:50:54Z herbert $ % \listfiles\setcounter{errorcontextlines}{100} \documentclass[paper=a4,fontsize=11pt,DIV=14,parskip=half-, @@ -81,7 +81,7 @@ \def\setVersion#1{\setVVersion#1!!} \def\setVVersion#1=#2!!{\def\luafindfontVersion{#2}} -\setVersion{version = 0.11}% can be automatically changed by perl +\setVersion{version = 0.14}% can be automatically changed by perl \setkeys{hv}{cleanup={},force} diff --git a/support/luafindfont/scripts/luafindfont.lua b/support/luafindfont/scripts/luafindfont.lua index a1d554b5ae..f77f913a7d 100755 --- a/support/luafindfont/scripts/luafindfont.lua +++ b/support/luafindfont/scripts/luafindfont.lua @@ -1,6 +1,6 @@ #!/usr/bin/env texlua -- --- $Id: luafindfont.lua 735 2023-06-22 19:12:29Z herbert $ +-- $Id: luafindfont.lua 961 2024-08-25 16:47:59Z herbert $ ----------------------------------------------------------------------- -- FILE: luafindfont.lua -- DESCRIPTION: search for fonts in the database @@ -8,7 +8,7 @@ -- AUTHOR: Herbert Voß (C) 2023-06-21 ----------------------------------------------------------------------- luafindfont = luafindfont or { } - local version = 0.13 + local version = 0.14 luafindfont.version = version --[[ @@ -31,6 +31,7 @@ Report bugs to hvoss@tug.org ]] +-- equivilant with ConTeXt, e.g. times -- mtxrun --script font --list --name --all --pattern=times kpse.set_program_name("luatex") @@ -38,8 +39,6 @@ local f = kpse.find_file("lualibs.lua") require("lualibs") -- all part of LuaTeX ---require("luafindfont-utflib") - if #arg == 0 then print("I need at least one argument or option! Will exit ...") os.exit() @@ -282,6 +281,13 @@ function compareEntries(f1, f2) end end +function centerText(text, width) + if text == nil then return "" end + local spaces = math.floor((width-string.len(text))/2) + local len = string.len(text) + return ((" "):rep(spaces)..text..(" "):rep(spaces)) +end + local fontData = {} local fontListFile = getFileLocation() if fontListFile == "" then @@ -375,20 +381,38 @@ if l_max[3] > maxStrLength then l_max[3] = maxStrLength end local minChars = 26 local Fontname = "Filename" local Path = "Path" -local SymbolicName = "Symbolic name" +local SymbolicName = "Symbolic" local lfdNr = "No." if (font_str ~= "*") and not noSymbolicNames then if args_xetex > 0 then - print(string.format("%5s %"..l_max[1].."s %"..l_max[2].."s %"..l_max[3].."s".."%4s",lfdNr,Fontname,SymbolicName,Path,"X")) +-- print(string.format("%5s %"..l_max[1].."s %"..l_max[2].."s %"..l_max[3].."s".."%4s",lfdNr,Fontname,SymbolicName,Path,"X")) + io.write(string.format("%5s",lfdNr)) + io.write(centerText(Fontname,l_max[1])) + io.write(centerText(SymbolicName,l_max[2])) + io.write(centerText(Path,l_max[3])) + print("X") else - print(string.format("%5s %"..l_max[1].."s %"..l_max[2].."s %"..l_max[3].."s",lfdNr,Fontname,SymbolicName,Path)) +-- print(string.format("%5s %"..l_max[1].."s %"..l_max[2].."s %"..l_max[3].."s",lfdNr,Fontname,SymbolicName,Path)) + io.write(string.format("%5s",lfdNr)) + io.write(centerText(Fontname,l_max[1])) + io.write(centerText(SymbolicName,l_max[2])) + print(centerText(Path,l_max[3])) end else if args_xetex > 0 then - print(string.format("%5s %"..l_max[1].."s %"..l_max[3].."s".."%4s",lfdNr,Fontname,Path,"X")) +-- print(string.format("%5s %"..l_max[1].."s %"..l_max[3].."s".."%4s",lfdNr,Fontname,Path,"X")) + io.write(string.format("%5s",lfdNr)) + io.write(centerText(Fontname,l_max[1])) + io.write(centerText(SymbolicName,l_max[2])) + io.write(centerText(Path,l_max[3])) + print("X") else - print(string.format("%5s %"..l_max[1].."s %"..l_max[3].."s",lfdNr,Fontname,Path)) +-- print(string.format("%5s %"..l_max[1].."s %"..l_max[3].."s",lfdNr,Fontname,Path)) + io.write(string.format("%5s",lfdNr)) + io.write(centerText(Fontname,l_max[1])) + io.write(centerText(SymbolicName,l_max[2])) + print(centerText(Path,l_max[3])) end end diff --git a/support/make4ht/README b/support/make4ht/README index 561d6bd14d..33ccdb5b81 100644 --- a/support/make4ht/README +++ b/support/make4ht/README @@ -1,4 +1,5 @@ % [![Build Status](https://travis-ci.org/michal-h21/make4ht.svg?branch=master)](https://travis-ci.org/michal-h21/make4ht) +% HTML version of the documentation can be found [here](https://www.kodymirus.cz/make4ht/make4ht-doc.html) # Introduction @@ -8,11 +9,12 @@ customized conversion tools. An example of such a tool is [tex4ebook](https://github.com/michal-h21/tex4ebook), a tool for conversion from \TeX\ to ePub and other e-book formats. -See section \ref{sec:htlatex} for some reasons why you should consider to use `make4ht` instead of `htlatex`, -section \ref{sec:output} talks about supported output formats and extensions and section \ref{sec:buildfiles} +See section \ref{sec:htlatex} for some reasons why you should consider to use `make4ht` instead +of `htlatex`, section \ref{sec:output} talks about supported output formats and extensions and section \ref{sec:buildfiles} describes build files, which can be used to execute additional commands or post-process the generated files. + # Usage The basic conversion from \LaTeX\ to `HTML` using `make4ht` can be executed using the following command: @@ -1162,12 +1164,23 @@ Example: options -: command line options for Dvisvgm. The default value is `-n --exact -c 1.15,1.15`. +: command line options for Dvisvgm. The default value is `-n --exact -c ${scale},${scale}`. cpu_cnt : the number of processor cores used for the conversion. The extension tries to detect the available cores automatically by default. +make_command + +: variant of the `make` command used for the parallel conversion of large +number of pages. It receives tvo variables, `process_count` and `make_file`. +Default value is "make -j ${process_count} -f ${make_file}". + +test_make_command + +: command that tests if the selected variant of the `make` command exists. Default value is `make -v`. + + parallel_size : the number of pages used in each Dvisvgm call. The extension detects changed @@ -1176,7 +1189,7 @@ pages. scale -: SVG scaling. +: amount of SVG scaling. The default value is 1.4. ## The `odttemplate` filter and extension diff --git a/support/make4ht/changelog.tex b/support/make4ht/changelog.tex index e17af6d5db..d60bfc51c3 100644 --- a/support/make4ht/changelog.tex +++ b/support/make4ht/changelog.tex @@ -3,6 +3,136 @@ \begin{itemize} \item + 2024/10/22 + + \begin{itemize} + \tightlist + \item + version \texttt{0.4b} released. + \item + test for the existence of the class atribute of tables before + performing string matches in the \texttt{tablerows} DOM filter. + \end{itemize} +\item + 2024/10/21 + + \begin{itemize} + \tightlist + \item + version \texttt{0.4a} released. + \end{itemize} +\item + 2024/09/30 + + \begin{itemize} + \tightlist + \item + remove last empty row in \texttt{longtable} environments. + \end{itemize} +\item + 2024/09/25 + + \begin{itemize} + \tightlist + \item + added \texttt{make4ht-char-def} library to remove dependency on + \texttt{char-def} from ConTeXt. It is used by the \texttt{sectionid} + DOM filter. The library is automatically created from + UnicodeData.txt by \texttt{tools/make\_chardata.lua}. + https://tex.stackexchange.com/q/727202/2891 + \end{itemize} +\item + 2024/09/18 + + \begin{itemize} + \tightlist + \item + print error messages from the \texttt{log} file. + \end{itemize} +\item + 2024/08/22 + + \begin{itemize} + \tightlist + \item + print debug message with XML parsing error context + \end{itemize} +\item + 2024/08/21 + + \begin{itemize} + \tightlist + \item + try the HTML parser for DOM filters if XML parser fails. + \end{itemize} +\item + 2024/06/18 + + \begin{itemize} + \tightlist + \item + changed default scaling in \texttt{dvisvgm\_hashes} to 1.4. + \end{itemize} +\item + 2024/06/17 + + \begin{itemize} + \tightlist + \item + fixed support for index entries that are broken over several lines. + \end{itemize} +\item + 2024/05/29 + + \begin{itemize} + \tightlist + \item + create temporary Lg file for Xtpipes. + https://github.com/michal-h21/make4ht/issues/148\#issuecomment-2136160818 + \item + fixed handling of the generated ODT file, don't copy it + unnecessarily and handle build and output directories. + https://github.com/michal-h21/make4ht/issues/148\#issuecomment-2136160818 + \end{itemize} +\item + 2024/04/23 + + \begin{itemize} + \tightlist + \item + test if referenced files are contained in the \texttt{build-dir} + directory, use the current dir otherwise. + https://github.com/michal-h21/tex4ebook/issues/126 + \end{itemize} +\item + 2024/04/16 + + \begin{itemize} + \tightlist + \item + fixed bug in \texttt{dvisvgm\_hashes} log parsing. On Windows, it + didn't expect \texttt{\textbackslash{}r} characters at the line + ends, they then ended in new SVG filenames. + \end{itemize} +\item + 2024/04/15 + + \begin{itemize} + \tightlist + \item + made the \texttt{make} command used in the \texttt{dvisvgm\_hashes} + extension configurable. https://tex.stackexchange.com/q/715633/2891 + \end{itemize} +\item + 2024/03/29 + + \begin{itemize} + \tightlist + \item + ignore numbers in braces in \texttt{make4ht-indexing} library. + https://tex.stackexchange.com/q/714247/2891 + \end{itemize} +\item 2024/02/22 \begin{itemize} diff --git a/support/make4ht/domfilters/make4ht-sectionid.lua b/support/make4ht/domfilters/make4ht-sectionid.lua index c8e9892bb1..25f54e6b44 100644 --- a/support/make4ht/domfilters/make4ht-sectionid.lua +++ b/support/make4ht/domfilters/make4ht-sectionid.lua @@ -2,13 +2,14 @@ local mkutils = require "mkutils" local log = logging.new("tocid") -- Unicode data distributed with ConTeXt -- defines "characters" table -if not mkutils.isModuleAvailable("char-def") then +if not mkutils.isModuleAvailable("make4ht-char-def") then log:warning("char-def module not found") log:warning("cannot fix section id's") return function(dom) return dom end end -require "char-def" -local chardata = characters.data or {} + +local chardata = require "make4ht-char-def" + local toc = nil diff --git a/support/make4ht/domfilters/make4ht-tablerows.lua b/support/make4ht/domfilters/make4ht-tablerows.lua index 11dbfcaa71..18d27b6b09 100644 --- a/support/make4ht/domfilters/make4ht-tablerows.lua +++ b/support/make4ht/domfilters/make4ht-tablerows.lua @@ -52,6 +52,19 @@ return function(dom) hr:remove_node() end end + local longrable_last_row = function(tbl) + -- longtable contains last row of empty cells + local rows= tbl:query_selector("tr") + local last_row = rows[#rows] + if not last_row then return end + for _, cell in ipairs(last_row:query_selector("td")) do + -- loop over cells in the last row a and detect that they are empty. break processing if they are not. + if has_child_elements(cell) or not cell:get_text():match("^%s*$") then + return + end + end + last_row:remove_node() + end local load_css_files = function() -- the empty rows can be styled using CSS, for example configuration for -- Booktabs does that. We shouldn't remove such rows. @@ -76,7 +89,9 @@ return function(dom) if is_empty_row(row) and is_not_styled(row, css) then row:remove_node() end hline_hr(row) end - + if tbl:get_attribute("class") and tbl:get_attribute("class"):match("longtable") then + longrable_last_row(tbl) + end end return dom end diff --git a/support/make4ht/extensions/make4ht-ext-dvisvgm_hashes.lua b/support/make4ht/extensions/make4ht-ext-dvisvgm_hashes.lua index 94183c7dbf..d0b1aae5c2 100644 --- a/support/make4ht/extensions/make4ht-ext-dvisvgm_hashes.lua +++ b/support/make4ht/extensions/make4ht-ext-dvisvgm_hashes.lua @@ -11,6 +11,8 @@ local M = {} local output_map = {} local dvisvgm_options = "-n --exact -c ${scale},${scale}" local parallel_size = 64 +local make_command = "make -j ${process_count} -f ${make_file}" +local test_make_command = "make -v" -- local parallel_size = 3 local function make_hashed_name(base, hash) @@ -47,7 +49,7 @@ local function get_generated_pages(output, pages) local pos = 1 local pos, finish, page = string.find(output, "processing page (%d+)", pos) while(pos) do - pos, finish, file = string.find(output, "output written to ([^\n]+)", finish) + pos, finish, file = string.find(output, "output written to ([^\n^\r]+)", finish) pages[tonumber(page)] = file if not finish then break end pos, finish, page = string.find(output, "processing page (%d+)", finish) @@ -88,11 +90,12 @@ end -- test the existence of GNU Make, which can execute tasks in parallel local function test_make() - local make = io.popen("make -v", "r") - if not make then return false end + local make = io.popen(test_make_command, "r") local content = make:read("*all") make:close() - return true + -- io.popen always returns valid handle, so we can find that the command doesn't exists only by checking that the + -- content is empty + return content~=nil and content ~= "" end local function save_file(filename, text) @@ -120,7 +123,8 @@ local function make_makefile_command(idvfile, page_sequences) -- construct makefile and save it local makefile = "all: " .. table.concat(all, " ") .. "\n\n" .. table.concat(targets, "\n") save_file(makefilename, makefile) - local command = "make -j" .. cpu_cnt .." -f " .. makefilename + local command = make_command % {process_count = cpu_cnt, make_file = makefilename} + log:debug("Makefile command: " .. command) return command, logs end @@ -169,8 +173,10 @@ local function get_dvi_pages(arg) dvisvgm_options = arg.options or extoptions.options or dvisvgm_options parallel_size = arg.parallel_size or extoptions.parallel_size or parallel_size cpu_cnt = arg.cpu_cnt or extoptions.cpu_cnt or cpu_cnt - dvisvgm_par.scale = arg.scale or extoptions.scale or 1.15 + dvisvgm_par.scale = arg.scale or extoptions.scale or 1.4 dvisvgm_options = dvisvgm_options % dvisvgm_par + make_command = arg.make_command or extoptions.make_command or make_command + test_make_command = arg.test_make_command or extoptions.test_make_command or test_make_command local f = io.open(idv_file, "rb") if not f then return nil, "Cannot open idv file: " .. idv_file end local content = f:read("*all") diff --git a/support/make4ht/extensions/make4ht-ext-preprocess_input.lua b/support/make4ht/extensions/make4ht-ext-preprocess_input.lua index 763c25ea7e..48d5ea85ee 100644 --- a/support/make4ht/extensions/make4ht-ext-preprocess_input.lua +++ b/support/make4ht/extensions/make4ht-ext-preprocess_input.lua @@ -84,7 +84,7 @@ end M.modify_build = function(make) - -- get access to the main argumens + -- get access to the main arguments local arg = make.params -- get the execution sequence for the input format local matched, msg = get_preprocessing_pipeline(arg.tex_file) diff --git a/support/make4ht/filters/make4ht-domfilter.lua b/support/make4ht/filters/make4ht-domfilter.lua index 68dd5a488c..fcd7b151bb 100644 --- a/support/make4ht/filters/make4ht-domfilter.lua +++ b/support/make4ht/filters/make4ht-domfilter.lua @@ -7,6 +7,19 @@ local function load_filter(filtername) return require("domfilters.make4ht-"..filtername) end +-- get snippet of the position where XML parsing failed +local function get_html_snippet(str, errmsg) + -- we can get position in bytes from message like this: + -- /home/mint/texmf/scripts/lua/LuaXML/luaxml-mod-xml.lua:175: Unbalanced Tag (/p) [char=1112] + local position = tonumber(errmsg:match("char=(%d+)") or "") + if not position then return "Cannot find error position" end + -- number of bytes around the error position that shoule be printed + local error_context = 100 + local start = position > error_context and position - error_context or 0 + local stop = (position + error_context) < str:len() and position + error_context or str:len() + return str:sub(start, stop) +end + -- save processed names, in order to block multiple executions of the filter -- sequence on a same file local processed = {} @@ -46,9 +59,19 @@ local function filter(filters, name) return dom.parse(input, void_elements) end) if not status then - log:warning("DOM parsing of " .. filename .. " failed:") + log:warning("XML DOM parsing of " .. filename .. " failed:") log:warning(domobject) - return nil, "DOM parsing failed" + log:debug("Error context:\n" .. (get_html_snippet(input, domobject) or "")) + log:debug("Trying HTML DOM parsing") + status, domobject = pcall(function() + return dom.html_parse(input) + end) + if not status then + log:warning("HTML DOM parsing failed as well") + return nil, "DOM parsing failed" + else + log:warning("HTML DOM parsing OK, DOM filters will be executed") + end end for _,f in pairs(sequence) do domobject = f(domobject,parameters) diff --git a/support/make4ht/formats/make4ht-odt.lua b/support/make4ht/formats/make4ht-odt.lua index 3479613c9d..211a4adc19 100644 --- a/support/make4ht/formats/make4ht-odt.lua +++ b/support/make4ht/formats/make4ht-odt.lua @@ -54,10 +54,14 @@ function Odtfile:create_dir(dir) lfs.mkdir(dir) lfs.chdir(currentdir) end - + function Odtfile:make_mimetype() self.mimetypename = "mimetype" - local m = io.open(self.mimetypename, "w") + local m, msg = io.open(self.mimetypename, "w") + if not m then + log:error(msg) + return nil, msg + end m:write("application/vnd.oasis.opendocument.text") m:close() end @@ -78,7 +82,7 @@ function Odtfile:pack() self:remove_mimetype() mkutils.execute(zip_command ..' -r "' .. self.name .. '" *') lfs.chdir(currentdir) - mkutils.cp(self.archivelocation .. "/" .. self.name, self.name) + mkutils.cp(self.archivelocation .. "/" .. self.name, mkutils.file_in_builddir(self.name, Make.params)) mkutils.delete_dir(self.archivelocation) end @@ -93,9 +97,9 @@ local function add_points(dimen) return dimen end -local function get_svg_dimensions(filename) +local function get_svg_dimensions(filename) local width, height - if mkutils.file_exists(filename) then + if mkutils.file_exists(filename) then for line in io.lines(filename) do width = line:match("width%s*=%s*[\"'](.-)[\"']") or width height = line:match("height%s*=%s*[\"'](.-)[\"']") or height @@ -121,7 +125,7 @@ end local function fix_picture_sizes(tmpdir) local filename = tmpdir .. "/content.xml" local f = io.open(filename, "r") - if not f then + if not f then log:warning("Cannot open ", filename, "for picture size fixes") return nil end @@ -130,7 +134,7 @@ local function fix_picture_sizes(tmpdir) local status, dom= pcall(function() return domobject.parse(content) end) - if not status then + if not status then log:warning("Cannot parse DOM, the resulting ODT file will be most likely corrupted") return nil end @@ -158,9 +162,13 @@ local function fix_picture_sizes(tmpdir) end -- save the modified DOM again log:debug("Fixed picture sizes") - local content = dom:serialize() - local f = io.open(filename, "w") - f:write(content) + local domcontent = dom:serialize() + local f, msg = io.open(filename, "w") + if not f then + log:error(msg) + return nil, msg + end + f:write(domcontent) f:close() end @@ -174,7 +182,7 @@ local function fix_lgfile_fonts(ignored_name, params) local lines = {} -- default font_size local font_size = "10" - if mkutils.file_exists(filename) then + if mkutils.file_exists(filename) then -- for line in io.lines(filename) do -- default font_size can be set in the .lg file @@ -304,6 +312,9 @@ function M.modify_build(make) if not executed then -- this is list of processed files local lgfiles = make.lgfile.files + for k,v in ipairs(lgfiles) do + if v:match("odt$") then table.remove(lgfiles, k) end + end -- find the last file and escape it so it can be used -- in filename match local lastfile = escape_file(lgfiles[#lgfiles]) .."$" @@ -312,7 +323,8 @@ function M.modify_build(make) make:match(lastfile, function(filename, par) local groups = prepare_output_files(make.lgfile.files) -- we must remove any path from the basename - local basename = groups.odt[1]:match("([^/]+)$") + -- local basename = groups.odt[1]:match("([^/]+)$") + local basename = make.params.input local odtname = basename .. ".odt" local odt,msg = Odtfile.new(odtname) if not odt then @@ -372,11 +384,13 @@ function M.modify_build(make) end) odt:pack() + local build_filename = mkutils.file_in_builddir(odt.name, make.params) if outdir and outdir ~= "" then - local filename = odt.name - local outfilename = outdir .. "/" .. filename + local outfilename = outdir .. "/" .. odt.name log:info("Copying ODT file to the output dir: " .. outfilename) - mkutils.copy(filename,outfilename) + mkutils.copy(build_filename,outfilename) + elseif build_filename ~= odt.name then + mkutils.cp(build_filename, odt.name) end end) end diff --git a/support/make4ht/make4ht b/support/make4ht/make4ht index 73a1978e5a..d9f7034bad 100755 --- a/support/make4ht/make4ht +++ b/support/make4ht/make4ht @@ -29,7 +29,7 @@ make4ht [options] filename ["tex4ht.sty op." "tex4ht op." "t4ht op" "latex op"] -- set version number. the template should be replaced by the -- actual version number by the build script -local version = "v0.4" +local version = "v0.4b" mkparams.version_number = version local args = mkparams.get_args() diff --git a/support/make4ht/make4ht-char-def.lua b/support/make4ht/make4ht-char-def.lua new file mode 100644 index 0000000000..8363225d66 --- /dev/null +++ b/support/make4ht/make4ht-char-def.lua @@ -0,0 +1,21786 @@ +return { +[32] = {category="zs"}, +[65] = {category="lu", lccode=97}, +[66] = {category="lu", lccode=98}, +[67] = {category="lu", lccode=99}, +[68] = {category="lu", lccode=100}, +[69] = {category="lu", lccode=101}, +[70] = {category="lu", lccode=102}, +[71] = {category="lu", lccode=103}, +[72] = {category="lu", lccode=104}, +[73] = {category="lu", lccode=105}, +[74] = {category="lu", lccode=106}, +[75] = {category="lu", lccode=107}, +[76] = {category="lu", lccode=108}, +[77] = {category="lu", lccode=109}, +[78] = {category="lu", lccode=110}, +[79] = {category="lu", lccode=111}, +[80] = {category="lu", lccode=112}, +[81] = {category="lu", lccode=113}, +[82] = {category="lu", lccode=114}, +[83] = {category="lu", lccode=115}, +[84] = {category="lu", lccode=116}, +[85] = {category="lu", lccode=117}, +[86] = {category="lu", lccode=118}, +[87] = {category="lu", lccode=119}, +[88] = {category="lu", lccode=120}, +[89] = {category="lu", lccode=121}, +[90] = {category="lu", lccode=122}, +[97] = {category="ll"}, +[98] = {category="ll"}, +[99] = {category="ll"}, +[100] = {category="ll"}, +[101] = {category="ll"}, +[102] = {category="ll"}, +[103] = {category="ll"}, +[104] = {category="ll"}, +[105] = {category="ll"}, +[106] = {category="ll"}, +[107] = {category="ll"}, +[108] = {category="ll"}, +[109] = {category="ll"}, +[110] = {category="ll"}, +[111] = {category="ll"}, +[112] = {category="ll"}, +[113] = {category="ll"}, +[114] = {category="ll"}, +[115] = {category="ll"}, +[116] = {category="ll"}, +[117] = {category="ll"}, +[118] = {category="ll"}, +[119] = {category="ll"}, +[120] = {category="ll"}, +[121] = {category="ll"}, +[122] = {category="ll"}, +[160] = {category="zs", shcode=11}, +[170] = {category="lo", shcode=14}, +[181] = {category="ll", shcode=12}, +[186] = {category="lo", shcode=14}, +[192] = {category="lu", lccode=224, shcode=65}, +[193] = {category="lu", lccode=225, shcode=65}, +[194] = {category="lu", lccode=226, shcode=65}, +[195] = {category="lu", lccode=227, shcode=65}, +[196] = {category="lu", lccode=228, shcode=65}, +[197] = {category="lu", lccode=229, shcode=65}, +[198] = {category="lu", lccode=230}, +[199] = {category="lu", lccode=231, shcode=67}, +[200] = {category="lu", lccode=232, shcode=69}, +[201] = {category="lu", lccode=233, shcode=69}, +[202] = {category="lu", lccode=234, shcode=69}, +[203] = {category="lu", lccode=235, shcode=69}, +[204] = {category="lu", lccode=236, shcode=73}, +[205] = {category="lu", lccode=237, shcode=73}, +[206] = {category="lu", lccode=238, shcode=73}, +[207] = {category="lu", lccode=239, shcode=73}, +[208] = {category="lu", lccode=240}, +[209] = {category="lu", lccode=241, shcode=78}, +[210] = {category="lu", lccode=242, shcode=79}, +[211] = {category="lu", lccode=243, shcode=79}, +[212] = {category="lu", lccode=244, shcode=79}, +[213] = {category="lu", lccode=245, shcode=79}, +[214] = {category="lu", lccode=246, shcode=79}, +[216] = {category="lu", lccode=248}, +[217] = {category="lu", lccode=249, shcode=85}, +[218] = {category="lu", lccode=250, shcode=85}, +[219] = {category="lu", lccode=251, shcode=85}, +[220] = {category="lu", lccode=252, shcode=85}, +[221] = {category="lu", lccode=253, shcode=89}, +[222] = {category="lu", lccode=254}, +[223] = {category="ll"}, +[224] = {category="ll", shcode=97}, +[225] = {category="ll", shcode=97}, +[226] = {category="ll", shcode=97}, +[227] = {category="ll", shcode=97}, +[228] = {category="ll", shcode=97}, +[229] = {category="ll", shcode=97}, +[230] = {category="ll"}, +[231] = {category="ll", shcode=99}, +[232] = {category="ll", shcode=101}, +[233] = {category="ll", shcode=101}, +[234] = {category="ll", shcode=101}, +[235] = {category="ll", shcode=101}, +[236] = {category="ll", shcode=105}, +[237] = {category="ll", shcode=105}, +[238] = {category="ll", shcode=105}, +[239] = {category="ll", shcode=105}, +[240] = {category="ll"}, +[241] = {category="ll", shcode=110}, +[242] = {category="ll", shcode=111}, +[243] = {category="ll", shcode=111}, +[244] = {category="ll", shcode=111}, +[245] = {category="ll", shcode=111}, +[246] = {category="ll", shcode=111}, +[248] = {category="ll"}, +[249] = {category="ll", shcode=117}, +[250] = {category="ll", shcode=117}, +[251] = {category="ll", shcode=117}, +[252] = {category="ll", shcode=117}, +[253] = {category="ll", shcode=121}, +[254] = {category="ll"}, +[255] = {category="ll", shcode=121}, +[256] = {category="lu", lccode=257, shcode=65}, +[257] = {category="ll", shcode=97}, +[258] = {category="lu", lccode=259, shcode=65}, +[259] = {category="ll", shcode=97}, +[260] = {category="lu", lccode=261, shcode=65}, +[261] = {category="ll", shcode=97}, +[262] = {category="lu", lccode=263, shcode=67}, +[263] = {category="ll", shcode=99}, +[264] = {category="lu", lccode=265, shcode=67}, +[265] = {category="ll", shcode=99}, +[266] = {category="lu", lccode=267, shcode=67}, +[267] = {category="ll", shcode=99}, +[268] = {category="lu", lccode=269, shcode=67}, +[269] = {category="ll", shcode=99}, +[270] = {category="lu", lccode=271, shcode=68}, +[271] = {category="ll", shcode=100}, +[272] = {category="lu", lccode=273}, +[273] = {category="ll"}, +[274] = {category="lu", lccode=275, shcode=69}, +[275] = {category="ll", shcode=101}, +[276] = {category="lu", lccode=277, shcode=69}, +[277] = {category="ll", shcode=101}, +[278] = {category="lu", lccode=279, shcode=69}, +[279] = {category="ll", shcode=101}, +[280] = {category="lu", lccode=281, shcode=69}, +[281] = {category="ll", shcode=101}, +[282] = {category="lu", lccode=283, shcode=69}, +[283] = {category="ll", shcode=101}, +[284] = {category="lu", lccode=285, shcode=71}, +[285] = {category="ll", shcode=103}, +[286] = {category="lu", lccode=287, shcode=71}, +[287] = {category="ll", shcode=103}, +[288] = {category="lu", lccode=289, shcode=71}, +[289] = {category="ll", shcode=103}, +[290] = {category="lu", lccode=291, shcode=71}, +[291] = {category="ll", shcode=103}, +[292] = {category="lu", lccode=293, shcode=72}, +[293] = {category="ll", shcode=104}, +[294] = {category="lu", lccode=295}, +[295] = {category="ll"}, +[296] = {category="lu", lccode=297, shcode=73}, +[297] = {category="ll", shcode=105}, +[298] = {category="lu", lccode=299, shcode=73}, +[299] = {category="ll", shcode=105}, +[300] = {category="lu", lccode=301, shcode=73}, +[301] = {category="ll", shcode=105}, +[302] = {category="lu", lccode=303, shcode=73}, +[303] = {category="ll", shcode=105}, +[304] = {category="lu", lccode=105, shcode=73}, +[305] = {category="ll"}, +[306] = {category="lu", lccode=307, shcode=12}, +[307] = {category="ll", shcode=12}, +[308] = {category="lu", lccode=309, shcode=74}, +[309] = {category="ll", shcode=106}, +[310] = {category="lu", lccode=311, shcode=75}, +[311] = {category="ll", shcode=107}, +[312] = {category="ll"}, +[313] = {category="lu", lccode=314, shcode=76}, +[314] = {category="ll", shcode=108}, +[315] = {category="lu", lccode=316, shcode=76}, +[316] = {category="ll", shcode=108}, +[317] = {category="lu", lccode=318, shcode=76}, +[318] = {category="ll", shcode=108}, +[319] = {category="lu", lccode=320, shcode=12}, +[320] = {category="ll", shcode=12}, +[321] = {category="lu", lccode=322}, +[322] = {category="ll"}, +[323] = {category="lu", lccode=324, shcode=78}, +[324] = {category="ll", shcode=110}, +[325] = {category="lu", lccode=326, shcode=78}, +[326] = {category="ll", shcode=110}, +[327] = {category="lu", lccode=328, shcode=78}, +[328] = {category="ll", shcode=110}, +[329] = {category="ll", shcode=12}, +[330] = {category="lu", lccode=331}, +[331] = {category="ll"}, +[332] = {category="lu", lccode=333, shcode=79}, +[333] = {category="ll", shcode=111}, +[334] = {category="lu", lccode=335, shcode=79}, +[335] = {category="ll", shcode=111}, +[336] = {category="lu", lccode=337, shcode=79}, +[337] = {category="ll", shcode=111}, +[338] = {category="lu", lccode=339}, +[339] = {category="ll"}, +[340] = {category="lu", lccode=341, shcode=82}, +[341] = {category="ll", shcode=114}, +[342] = {category="lu", lccode=343, shcode=82}, +[343] = {category="ll", shcode=114}, +[344] = {category="lu", lccode=345, shcode=82}, +[345] = {category="ll", shcode=114}, +[346] = {category="lu", lccode=347, shcode=83}, +[347] = {category="ll", shcode=115}, +[348] = {category="lu", lccode=349, shcode=83}, +[349] = {category="ll", shcode=115}, +[350] = {category="lu", lccode=351, shcode=83}, +[351] = {category="ll", shcode=115}, +[352] = {category="lu", lccode=353, shcode=83}, +[353] = {category="ll", shcode=115}, +[354] = {category="lu", lccode=355, shcode=84}, +[355] = {category="ll", shcode=116}, +[356] = {category="lu", lccode=357, shcode=84}, +[357] = {category="ll", shcode=116}, +[358] = {category="lu", lccode=359}, +[359] = {category="ll"}, +[360] = {category="lu", lccode=361, shcode=85}, +[361] = {category="ll", shcode=117}, +[362] = {category="lu", lccode=363, shcode=85}, +[363] = {category="ll", shcode=117}, +[364] = {category="lu", lccode=365, shcode=85}, +[365] = {category="ll", shcode=117}, +[366] = {category="lu", lccode=367, shcode=85}, +[367] = {category="ll", shcode=117}, +[368] = {category="lu", lccode=369, shcode=85}, +[369] = {category="ll", shcode=117}, +[370] = {category="lu", lccode=371, shcode=85}, +[371] = {category="ll", shcode=117}, +[372] = {category="lu", lccode=373, shcode=87}, +[373] = {category="ll", shcode=119}, +[374] = {category="lu", lccode=375, shcode=89}, +[375] = {category="ll", shcode=121}, +[376] = {category="lu", lccode=255, shcode=89}, +[377] = {category="lu", lccode=378, shcode=90}, +[378] = {category="ll", shcode=122}, +[379] = {category="lu", lccode=380, shcode=90}, +[380] = {category="ll", shcode=122}, +[381] = {category="lu", lccode=382, shcode=90}, +[382] = {category="ll", shcode=122}, +[383] = {category="ll", shcode=12}, +[384] = {category="ll"}, +[385] = {category="lu", lccode=595}, +[386] = {category="lu", lccode=387}, +[387] = {category="ll"}, +[388] = {category="lu", lccode=389}, +[389] = {category="ll"}, +[390] = {category="lu", lccode=596}, +[391] = {category="lu", lccode=392}, +[392] = {category="ll"}, +[393] = {category="lu", lccode=598}, +[394] = {category="lu", lccode=599}, +[395] = {category="lu", lccode=396}, +[396] = {category="ll"}, +[397] = {category="ll"}, +[398] = {category="lu", lccode=477}, +[399] = {category="lu", lccode=601}, +[400] = {category="lu", lccode=603}, +[401] = {category="lu", lccode=402}, +[402] = {category="ll"}, +[403] = {category="lu", lccode=608}, +[404] = {category="lu", lccode=611}, +[405] = {category="ll"}, +[406] = {category="lu", lccode=617}, +[407] = {category="lu", lccode=616}, +[408] = {category="lu", lccode=409}, +[409] = {category="ll"}, +[410] = {category="ll"}, +[411] = {category="ll"}, +[412] = {category="lu", lccode=623}, +[413] = {category="lu", lccode=626}, +[414] = {category="ll"}, +[415] = {category="lu", lccode=629}, +[416] = {category="lu", lccode=417, shcode=79}, +[417] = {category="ll", shcode=111}, +[418] = {category="lu", lccode=419}, +[419] = {category="ll"}, +[420] = {category="lu", lccode=421}, +[421] = {category="ll"}, +[422] = {category="lu", lccode=640}, +[423] = {category="lu", lccode=424}, +[424] = {category="ll"}, +[425] = {category="lu", lccode=643}, +[426] = {category="ll"}, +[427] = {category="ll"}, +[428] = {category="lu", lccode=429}, +[429] = {category="ll"}, +[430] = {category="lu", lccode=648}, +[431] = {category="lu", lccode=432, shcode=85}, +[432] = {category="ll", shcode=117}, +[433] = {category="lu", lccode=650}, +[434] = {category="lu", lccode=651}, +[435] = {category="lu", lccode=436}, +[436] = {category="ll"}, +[437] = {category="lu", lccode=438}, +[438] = {category="ll"}, +[439] = {category="lu", lccode=658}, +[440] = {category="lu", lccode=441}, +[441] = {category="ll"}, +[442] = {category="ll"}, +[443] = {category="lo"}, +[444] = {category="lu", lccode=445}, +[445] = {category="ll"}, +[446] = {category="ll"}, +[447] = {category="ll"}, +[448] = {category="lo"}, +[449] = {category="lo"}, +[450] = {category="lo"}, +[451] = {category="lo"}, +[452] = {category="lu", lccode=454, shcode=12}, +[453] = {category="lt", lccode=454, shcode=12}, +[454] = {category="ll", shcode=12}, +[455] = {category="lu", lccode=457, shcode=12}, +[456] = {category="lt", lccode=457, shcode=12}, +[457] = {category="ll", shcode=12}, +[458] = {category="lu", lccode=460, shcode=12}, +[459] = {category="lt", lccode=460, shcode=12}, +[460] = {category="ll", shcode=12}, +[461] = {category="lu", lccode=462, shcode=65}, +[462] = {category="ll", shcode=97}, +[463] = {category="lu", lccode=464, shcode=73}, +[464] = {category="ll", shcode=105}, +[465] = {category="lu", lccode=466, shcode=79}, +[466] = {category="ll", shcode=111}, +[467] = {category="lu", lccode=468, shcode=85}, +[468] = {category="ll", shcode=117}, +[469] = {category="lu", lccode=470, shcode=220}, +[470] = {category="ll", shcode=252}, +[471] = {category="lu", lccode=472, shcode=220}, +[472] = {category="ll", shcode=252}, +[473] = {category="lu", lccode=474, shcode=220}, +[474] = {category="ll", shcode=252}, +[475] = {category="lu", lccode=476, shcode=220}, +[476] = {category="ll", shcode=252}, +[477] = {category="ll"}, +[478] = {category="lu", lccode=479, shcode=196}, +[479] = {category="ll", shcode=228}, +[480] = {category="lu", lccode=481, shcode=550}, +[481] = {category="ll", shcode=551}, +[482] = {category="lu", lccode=483, shcode=198}, +[483] = {category="ll", shcode=230}, +[484] = {category="lu", lccode=485}, +[485] = {category="ll"}, +[486] = {category="lu", lccode=487, shcode=71}, +[487] = {category="ll", shcode=103}, +[488] = {category="lu", lccode=489, shcode=75}, +[489] = {category="ll", shcode=107}, +[490] = {category="lu", lccode=491, shcode=79}, +[491] = {category="ll", shcode=111}, +[492] = {category="lu", lccode=493, shcode=490}, +[493] = {category="ll", shcode=491}, +[494] = {category="lu", lccode=495, shcode=439}, +[495] = {category="ll", shcode=658}, +[496] = {category="ll", shcode=106}, +[497] = {category="lu", lccode=499, shcode=12}, +[498] = {category="lt", lccode=499, shcode=12}, +[499] = {category="ll", shcode=12}, +[500] = {category="lu", lccode=501, shcode=71}, +[501] = {category="ll", shcode=103}, +[502] = {category="lu", lccode=405}, +[503] = {category="lu", lccode=447}, +[504] = {category="lu", lccode=505, shcode=78}, +[505] = {category="ll", shcode=110}, +[506] = {category="lu", lccode=507, shcode=197}, +[507] = {category="ll", shcode=229}, +[508] = {category="lu", lccode=509, shcode=198}, +[509] = {category="ll", shcode=230}, +[510] = {category="lu", lccode=511, shcode=216}, +[511] = {category="ll", shcode=248}, +[512] = {category="lu", lccode=513, shcode=65}, +[513] = {category="ll", shcode=97}, +[514] = {category="lu", lccode=515, shcode=65}, +[515] = {category="ll", shcode=97}, +[516] = {category="lu", lccode=517, shcode=69}, +[517] = {category="ll", shcode=101}, +[518] = {category="lu", lccode=519, shcode=69}, +[519] = {category="ll", shcode=101}, +[520] = {category="lu", lccode=521, shcode=73}, +[521] = {category="ll", shcode=105}, +[522] = {category="lu", lccode=523, shcode=73}, +[523] = {category="ll", shcode=105}, +[524] = {category="lu", lccode=525, shcode=79}, +[525] = {category="ll", shcode=111}, +[526] = {category="lu", lccode=527, shcode=79}, +[527] = {category="ll", shcode=111}, +[528] = {category="lu", lccode=529, shcode=82}, +[529] = {category="ll", shcode=114}, +[530] = {category="lu", lccode=531, shcode=82}, +[531] = {category="ll", shcode=114}, +[532] = {category="lu", lccode=533, shcode=85}, +[533] = {category="ll", shcode=117}, +[534] = {category="lu", lccode=535, shcode=85}, +[535] = {category="ll", shcode=117}, +[536] = {category="lu", lccode=537, shcode=83}, +[537] = {category="ll", shcode=115}, +[538] = {category="lu", lccode=539, shcode=84}, +[539] = {category="ll", shcode=116}, +[540] = {category="lu", lccode=541}, +[541] = {category="ll"}, +[542] = {category="lu", lccode=543, shcode=72}, +[543] = {category="ll", shcode=104}, +[544] = {category="lu", lccode=414}, +[545] = {category="ll"}, +[546] = {category="lu", lccode=547}, +[547] = {category="ll"}, +[548] = {category="lu", lccode=549}, +[549] = {category="ll"}, +[550] = {category="lu", lccode=551, shcode=65}, +[551] = {category="ll", shcode=97}, +[552] = {category="lu", lccode=553, shcode=69}, +[553] = {category="ll", shcode=101}, +[554] = {category="lu", lccode=555, shcode=214}, +[555] = {category="ll", shcode=246}, +[556] = {category="lu", lccode=557, shcode=213}, +[557] = {category="ll", shcode=245}, +[558] = {category="lu", lccode=559, shcode=79}, +[559] = {category="ll", shcode=111}, +[560] = {category="lu", lccode=561, shcode=558}, +[561] = {category="ll", shcode=559}, +[562] = {category="lu", lccode=563, shcode=89}, +[563] = {category="ll", shcode=121}, +[564] = {category="ll"}, +[565] = {category="ll"}, +[566] = {category="ll"}, +[567] = {category="ll"}, +[568] = {category="ll"}, +[569] = {category="ll"}, +[570] = {category="lu", lccode=11365}, +[571] = {category="lu", lccode=572}, +[572] = {category="ll"}, +[573] = {category="lu", lccode=410}, +[574] = {category="lu", lccode=11366}, +[575] = {category="ll"}, +[576] = {category="ll"}, +[577] = {category="lu", lccode=578}, +[578] = {category="ll"}, +[579] = {category="lu", lccode=384}, +[580] = {category="lu", lccode=649}, +[581] = {category="lu", lccode=652}, +[582] = {category="lu", lccode=583}, +[583] = {category="ll"}, +[584] = {category="lu", lccode=585}, +[585] = {category="ll"}, +[586] = {category="lu", lccode=587}, +[587] = {category="ll"}, +[588] = {category="lu", lccode=589}, +[589] = {category="ll"}, +[590] = {category="lu", lccode=591}, +[591] = {category="ll"}, +[592] = {category="ll"}, +[593] = {category="ll"}, +[594] = {category="ll"}, +[595] = {category="ll"}, +[596] = {category="ll"}, +[597] = {category="ll"}, +[598] = {category="ll"}, +[599] = {category="ll"}, +[600] = {category="ll"}, +[601] = {category="ll"}, +[602] = {category="ll"}, +[603] = {category="ll"}, +[604] = {category="ll"}, +[605] = {category="ll"}, +[606] = {category="ll"}, +[607] = {category="ll"}, +[608] = {category="ll"}, +[609] = {category="ll"}, +[610] = {category="ll"}, +[611] = {category="ll"}, +[612] = {category="ll"}, +[613] = {category="ll"}, +[614] = {category="ll"}, +[615] = {category="ll"}, +[616] = {category="ll"}, +[617] = {category="ll"}, +[618] = {category="ll"}, +[619] = {category="ll"}, +[620] = {category="ll"}, +[621] = {category="ll"}, +[622] = {category="ll"}, +[623] = {category="ll"}, +[624] = {category="ll"}, +[625] = {category="ll"}, +[626] = {category="ll"}, +[627] = {category="ll"}, +[628] = {category="ll"}, +[629] = {category="ll"}, +[630] = {category="ll"}, +[631] = {category="ll"}, +[632] = {category="ll"}, +[633] = {category="ll"}, +[634] = {category="ll"}, +[635] = {category="ll"}, +[636] = {category="ll"}, +[637] = {category="ll"}, +[638] = {category="ll"}, +[639] = {category="ll"}, +[640] = {category="ll"}, +[641] = {category="ll"}, +[642] = {category="ll"}, +[643] = {category="ll"}, +[644] = {category="ll"}, +[645] = {category="ll"}, +[646] = {category="ll"}, +[647] = {category="ll"}, +[648] = {category="ll"}, +[649] = {category="ll"}, +[650] = {category="ll"}, +[651] = {category="ll"}, +[652] = {category="ll"}, +[653] = {category="ll"}, +[654] = {category="ll"}, +[655] = {category="ll"}, +[656] = {category="ll"}, +[657] = {category="ll"}, +[658] = {category="ll"}, +[659] = {category="ll"}, +[660] = {category="lo"}, +[661] = {category="ll"}, +[662] = {category="ll"}, +[663] = {category="ll"}, +[664] = {category="ll"}, +[665] = {category="ll"}, +[666] = {category="ll"}, +[667] = {category="ll"}, +[668] = {category="ll"}, +[669] = {category="ll"}, +[670] = {category="ll"}, +[671] = {category="ll"}, +[672] = {category="ll"}, +[673] = {category="ll"}, +[674] = {category="ll"}, +[675] = {category="ll"}, +[676] = {category="ll"}, +[677] = {category="ll"}, +[678] = {category="ll"}, +[679] = {category="ll"}, +[680] = {category="ll"}, +[681] = {category="ll"}, +[682] = {category="ll"}, +[683] = {category="ll"}, +[684] = {category="ll"}, +[685] = {category="ll"}, +[686] = {category="ll"}, +[687] = {category="ll"}, +[688] = {category="lm", shcode=14}, +[689] = {category="lm", shcode=14}, +[690] = {category="lm", shcode=14}, +[691] = {category="lm", shcode=14}, +[692] = {category="lm", shcode=14}, +[693] = {category="lm", shcode=14}, +[694] = {category="lm", shcode=14}, +[695] = {category="lm", shcode=14}, +[696] = {category="lm", shcode=14}, +[697] = {category="lm"}, +[698] = {category="lm"}, +[699] = {category="lm"}, +[700] = {category="lm"}, +[701] = {category="lm"}, +[702] = {category="lm"}, +[703] = {category="lm"}, +[704] = {category="lm"}, +[705] = {category="lm"}, +[710] = {category="lm"}, +[711] = {category="lm"}, +[712] = {category="lm"}, +[713] = {category="lm"}, +[714] = {category="lm"}, +[715] = {category="lm"}, +[716] = {category="lm"}, +[717] = {category="lm"}, +[718] = {category="lm"}, +[719] = {category="lm"}, +[720] = {category="lm"}, +[721] = {category="lm"}, +[736] = {category="lm", shcode=14}, +[737] = {category="lm", shcode=14}, +[738] = {category="lm", shcode=14}, +[739] = {category="lm", shcode=14}, +[740] = {category="lm", shcode=14}, +[748] = {category="lm"}, +[750] = {category="lm"}, +[880] = {category="lu", lccode=881}, +[881] = {category="ll"}, +[882] = {category="lu", lccode=883}, +[883] = {category="ll"}, +[884] = {category="lm", shcode=697}, +[886] = {category="lu", lccode=887}, +[887] = {category="ll"}, +[890] = {category="lm", shcode=12}, +[891] = {category="ll"}, +[892] = {category="ll"}, +[893] = {category="ll"}, +[895] = {category="lu", lccode=1011}, +[902] = {category="lu", lccode=940, shcode=913}, +[904] = {category="lu", lccode=941, shcode=917}, +[905] = {category="lu", lccode=942, shcode=919}, +[906] = {category="lu", lccode=943, shcode=921}, +[908] = {category="lu", lccode=972, shcode=927}, +[910] = {category="lu", lccode=973, shcode=933}, +[911] = {category="lu", lccode=974, shcode=937}, +[912] = {category="ll", shcode=970}, +[913] = {category="lu", lccode=945}, +[914] = {category="lu", lccode=946}, +[915] = {category="lu", lccode=947}, +[916] = {category="lu", lccode=948}, +[917] = {category="lu", lccode=949}, +[918] = {category="lu", lccode=950}, +[919] = {category="lu", lccode=951}, +[920] = {category="lu", lccode=952}, +[921] = {category="lu", lccode=953}, +[922] = {category="lu", lccode=954}, +[923] = {category="lu", lccode=955}, +[924] = {category="lu", lccode=956}, +[925] = {category="lu", lccode=957}, +[926] = {category="lu", lccode=958}, +[927] = {category="lu", lccode=959}, +[928] = {category="lu", lccode=960}, +[929] = {category="lu", lccode=961}, +[931] = {category="lu", lccode=963}, +[932] = {category="lu", lccode=964}, +[933] = {category="lu", lccode=965}, +[934] = {category="lu", lccode=966}, +[935] = {category="lu", lccode=967}, +[936] = {category="lu", lccode=968}, +[937] = {category="lu", lccode=969}, +[938] = {category="lu", lccode=970, shcode=921}, +[939] = {category="lu", lccode=971, shcode=933}, +[940] = {category="ll", shcode=945}, +[941] = {category="ll", shcode=949}, +[942] = {category="ll", shcode=951}, +[943] = {category="ll", shcode=953}, +[944] = {category="ll", shcode=971}, +[945] = {category="ll"}, +[946] = {category="ll"}, +[947] = {category="ll"}, +[948] = {category="ll"}, +[949] = {category="ll"}, +[950] = {category="ll"}, +[951] = {category="ll"}, +[952] = {category="ll"}, +[953] = {category="ll"}, +[954] = {category="ll"}, +[955] = {category="ll"}, +[956] = {category="ll"}, +[957] = {category="ll"}, +[958] = {category="ll"}, +[959] = {category="ll"}, +[960] = {category="ll"}, +[961] = {category="ll"}, +[962] = {category="ll"}, +[963] = {category="ll"}, +[964] = {category="ll"}, +[965] = {category="ll"}, +[966] = {category="ll"}, +[967] = {category="ll"}, +[968] = {category="ll"}, +[969] = {category="ll"}, +[970] = {category="ll", shcode=953}, +[971] = {category="ll", shcode=965}, +[972] = {category="ll", shcode=959}, +[973] = {category="ll", shcode=965}, +[974] = {category="ll", shcode=969}, +[975] = {category="lu", lccode=983}, +[976] = {category="ll", shcode=12}, +[977] = {category="ll", shcode=12}, +[978] = {category="lu", shcode=12}, +[979] = {category="lu", shcode=978}, +[980] = {category="lu", shcode=978}, +[981] = {category="ll", shcode=12}, +[982] = {category="ll", shcode=12}, +[983] = {category="ll"}, +[984] = {category="lu", lccode=985}, +[985] = {category="ll"}, +[986] = {category="lu", lccode=987}, +[987] = {category="ll"}, +[988] = {category="lu", lccode=989}, +[989] = {category="ll"}, +[990] = {category="lu", lccode=991}, +[991] = {category="ll"}, +[992] = {category="lu", lccode=993}, +[993] = {category="ll"}, +[994] = {category="lu", lccode=995}, +[995] = {category="ll"}, +[996] = {category="lu", lccode=997}, +[997] = {category="ll"}, +[998] = {category="lu", lccode=999}, +[999] = {category="ll"}, +[1000] = {category="lu", lccode=1001}, +[1001] = {category="ll"}, +[1002] = {category="lu", lccode=1003}, +[1003] = {category="ll"}, +[1004] = {category="lu", lccode=1005}, +[1005] = {category="ll"}, +[1006] = {category="lu", lccode=1007}, +[1007] = {category="ll"}, +[1008] = {category="ll", shcode=12}, +[1009] = {category="ll", shcode=12}, +[1010] = {category="ll", shcode=12}, +[1011] = {category="ll"}, +[1012] = {category="lu", lccode=952, shcode=12}, +[1013] = {category="ll", shcode=12}, +[1015] = {category="lu", lccode=1016}, +[1016] = {category="ll"}, +[1017] = {category="lu", lccode=1010, shcode=12}, +[1018] = {category="lu", lccode=1019}, +[1019] = {category="ll"}, +[1020] = {category="ll"}, +[1021] = {category="lu", lccode=891}, +[1022] = {category="lu", lccode=892}, +[1023] = {category="lu", lccode=893}, +[1024] = {category="lu", lccode=1104, shcode=1045}, +[1025] = {category="lu", lccode=1105, shcode=1045}, +[1026] = {category="lu", lccode=1106}, +[1027] = {category="lu", lccode=1107, shcode=1043}, +[1028] = {category="lu", lccode=1108}, +[1029] = {category="lu", lccode=1109}, +[1030] = {category="lu", lccode=1110}, +[1031] = {category="lu", lccode=1111, shcode=1030}, +[1032] = {category="lu", lccode=1112}, +[1033] = {category="lu", lccode=1113}, +[1034] = {category="lu", lccode=1114}, +[1035] = {category="lu", lccode=1115}, +[1036] = {category="lu", lccode=1116, shcode=1050}, +[1037] = {category="lu", lccode=1117, shcode=1048}, +[1038] = {category="lu", lccode=1118, shcode=1059}, +[1039] = {category="lu", lccode=1119}, +[1040] = {category="lu", lccode=1072}, +[1041] = {category="lu", lccode=1073}, +[1042] = {category="lu", lccode=1074}, +[1043] = {category="lu", lccode=1075}, +[1044] = {category="lu", lccode=1076}, +[1045] = {category="lu", lccode=1077}, +[1046] = {category="lu", lccode=1078}, +[1047] = {category="lu", lccode=1079}, +[1048] = {category="lu", lccode=1080}, +[1049] = {category="lu", lccode=1081, shcode=1048}, +[1050] = {category="lu", lccode=1082}, +[1051] = {category="lu", lccode=1083}, +[1052] = {category="lu", lccode=1084}, +[1053] = {category="lu", lccode=1085}, +[1054] = {category="lu", lccode=1086}, +[1055] = {category="lu", lccode=1087}, +[1056] = {category="lu", lccode=1088}, +[1057] = {category="lu", lccode=1089}, +[1058] = {category="lu", lccode=1090}, +[1059] = {category="lu", lccode=1091}, +[1060] = {category="lu", lccode=1092}, +[1061] = {category="lu", lccode=1093}, +[1062] = {category="lu", lccode=1094}, +[1063] = {category="lu", lccode=1095}, +[1064] = {category="lu", lccode=1096}, +[1065] = {category="lu", lccode=1097}, +[1066] = {category="lu", lccode=1098}, +[1067] = {category="lu", lccode=1099}, +[1068] = {category="lu", lccode=1100}, +[1069] = {category="lu", lccode=1101}, +[1070] = {category="lu", lccode=1102}, +[1071] = {category="lu", lccode=1103}, +[1072] = {category="ll"}, +[1073] = {category="ll"}, +[1074] = {category="ll"}, +[1075] = {category="ll"}, +[1076] = {category="ll"}, +[1077] = {category="ll"}, +[1078] = {category="ll"}, +[1079] = {category="ll"}, +[1080] = {category="ll"}, +[1081] = {category="ll", shcode=1080}, +[1082] = {category="ll"}, +[1083] = {category="ll"}, +[1084] = {category="ll"}, +[1085] = {category="ll"}, +[1086] = {category="ll"}, +[1087] = {category="ll"}, +[1088] = {category="ll"}, +[1089] = {category="ll"}, +[1090] = {category="ll"}, +[1091] = {category="ll"}, +[1092] = {category="ll"}, +[1093] = {category="ll"}, +[1094] = {category="ll"}, +[1095] = {category="ll"}, +[1096] = {category="ll"}, +[1097] = {category="ll"}, +[1098] = {category="ll"}, +[1099] = {category="ll"}, +[1100] = {category="ll"}, +[1101] = {category="ll"}, +[1102] = {category="ll"}, +[1103] = {category="ll"}, +[1104] = {category="ll", shcode=1077}, +[1105] = {category="ll", shcode=1077}, +[1106] = {category="ll"}, +[1107] = {category="ll", shcode=1075}, +[1108] = {category="ll"}, +[1109] = {category="ll"}, +[1110] = {category="ll"}, +[1111] = {category="ll", shcode=1110}, +[1112] = {category="ll"}, +[1113] = {category="ll"}, +[1114] = {category="ll"}, +[1115] = {category="ll"}, +[1116] = {category="ll", shcode=1082}, +[1117] = {category="ll", shcode=1080}, +[1118] = {category="ll", shcode=1091}, +[1119] = {category="ll"}, +[1120] = {category="lu", lccode=1121}, +[1121] = {category="ll"}, +[1122] = {category="lu", lccode=1123}, +[1123] = {category="ll"}, +[1124] = {category="lu", lccode=1125}, +[1125] = {category="ll"}, +[1126] = {category="lu", lccode=1127}, +[1127] = {category="ll"}, +[1128] = {category="lu", lccode=1129}, +[1129] = {category="ll"}, +[1130] = {category="lu", lccode=1131}, +[1131] = {category="ll"}, +[1132] = {category="lu", lccode=1133}, +[1133] = {category="ll"}, +[1134] = {category="lu", lccode=1135}, +[1135] = {category="ll"}, +[1136] = {category="lu", lccode=1137}, +[1137] = {category="ll"}, +[1138] = {category="lu", lccode=1139}, +[1139] = {category="ll"}, +[1140] = {category="lu", lccode=1141}, +[1141] = {category="ll"}, +[1142] = {category="lu", lccode=1143, shcode=1140}, +[1143] = {category="ll", shcode=1141}, +[1144] = {category="lu", lccode=1145}, +[1145] = {category="ll"}, +[1146] = {category="lu", lccode=1147}, +[1147] = {category="ll"}, +[1148] = {category="lu", lccode=1149}, +[1149] = {category="ll"}, +[1150] = {category="lu", lccode=1151}, +[1151] = {category="ll"}, +[1152] = {category="lu", lccode=1153}, +[1153] = {category="ll"}, +[1162] = {category="lu", lccode=1163}, +[1163] = {category="ll"}, +[1164] = {category="lu", lccode=1165}, +[1165] = {category="ll"}, +[1166] = {category="lu", lccode=1167}, +[1167] = {category="ll"}, +[1168] = {category="lu", lccode=1169}, +[1169] = {category="ll"}, +[1170] = {category="lu", lccode=1171}, +[1171] = {category="ll"}, +[1172] = {category="lu", lccode=1173}, +[1173] = {category="ll"}, +[1174] = {category="lu", lccode=1175}, +[1175] = {category="ll"}, +[1176] = {category="lu", lccode=1177}, +[1177] = {category="ll"}, +[1178] = {category="lu", lccode=1179}, +[1179] = {category="ll"}, +[1180] = {category="lu", lccode=1181}, +[1181] = {category="ll"}, +[1182] = {category="lu", lccode=1183}, +[1183] = {category="ll"}, +[1184] = {category="lu", lccode=1185}, +[1185] = {category="ll"}, +[1186] = {category="lu", lccode=1187}, +[1187] = {category="ll"}, +[1188] = {category="lu", lccode=1189}, +[1189] = {category="ll"}, +[1190] = {category="lu", lccode=1191}, +[1191] = {category="ll"}, +[1192] = {category="lu", lccode=1193}, +[1193] = {category="ll"}, +[1194] = {category="lu", lccode=1195}, +[1195] = {category="ll"}, +[1196] = {category="lu", lccode=1197}, +[1197] = {category="ll"}, +[1198] = {category="lu", lccode=1199}, +[1199] = {category="ll"}, +[1200] = {category="lu", lccode=1201}, +[1201] = {category="ll"}, +[1202] = {category="lu", lccode=1203}, +[1203] = {category="ll"}, +[1204] = {category="lu", lccode=1205}, +[1205] = {category="ll"}, +[1206] = {category="lu", lccode=1207}, +[1207] = {category="ll"}, +[1208] = {category="lu", lccode=1209}, +[1209] = {category="ll"}, +[1210] = {category="lu", lccode=1211}, +[1211] = {category="ll"}, +[1212] = {category="lu", lccode=1213}, +[1213] = {category="ll"}, +[1214] = {category="lu", lccode=1215}, +[1215] = {category="ll"}, +[1216] = {category="lu", lccode=1231}, +[1217] = {category="lu", lccode=1218, shcode=1046}, +[1218] = {category="ll", shcode=1078}, +[1219] = {category="lu", lccode=1220}, +[1220] = {category="ll"}, +[1221] = {category="lu", lccode=1222}, +[1222] = {category="ll"}, +[1223] = {category="lu", lccode=1224}, +[1224] = {category="ll"}, +[1225] = {category="lu", lccode=1226}, +[1226] = {category="ll"}, +[1227] = {category="lu", lccode=1228}, +[1228] = {category="ll"}, +[1229] = {category="lu", lccode=1230}, +[1230] = {category="ll"}, +[1231] = {category="ll"}, +[1232] = {category="lu", lccode=1233, shcode=1040}, +[1233] = {category="ll", shcode=1072}, +[1234] = {category="lu", lccode=1235, shcode=1040}, +[1235] = {category="ll", shcode=1072}, +[1236] = {category="lu", lccode=1237}, +[1237] = {category="ll"}, +[1238] = {category="lu", lccode=1239, shcode=1045}, +[1239] = {category="ll", shcode=1077}, +[1240] = {category="lu", lccode=1241}, +[1241] = {category="ll"}, +[1242] = {category="lu", lccode=1243, shcode=1240}, +[1243] = {category="ll", shcode=1241}, +[1244] = {category="lu", lccode=1245, shcode=1046}, +[1245] = {category="ll", shcode=1078}, +[1246] = {category="lu", lccode=1247, shcode=1047}, +[1247] = {category="ll", shcode=1079}, +[1248] = {category="lu", lccode=1249}, +[1249] = {category="ll"}, +[1250] = {category="lu", lccode=1251, shcode=1048}, +[1251] = {category="ll", shcode=1080}, +[1252] = {category="lu", lccode=1253, shcode=1048}, +[1253] = {category="ll", shcode=1080}, +[1254] = {category="lu", lccode=1255, shcode=1054}, +[1255] = {category="ll", shcode=1086}, +[1256] = {category="lu", lccode=1257}, +[1257] = {category="ll"}, +[1258] = {category="lu", lccode=1259, shcode=1256}, +[1259] = {category="ll", shcode=1257}, +[1260] = {category="lu", lccode=1261, shcode=1069}, +[1261] = {category="ll", shcode=1101}, +[1262] = {category="lu", lccode=1263, shcode=1059}, +[1263] = {category="ll", shcode=1091}, +[1264] = {category="lu", lccode=1265, shcode=1059}, +[1265] = {category="ll", shcode=1091}, +[1266] = {category="lu", lccode=1267, shcode=1059}, +[1267] = {category="ll", shcode=1091}, +[1268] = {category="lu", lccode=1269, shcode=1063}, +[1269] = {category="ll", shcode=1095}, +[1270] = {category="lu", lccode=1271}, +[1271] = {category="ll"}, +[1272] = {category="lu", lccode=1273, shcode=1067}, +[1273] = {category="ll", shcode=1099}, +[1274] = {category="lu", lccode=1275}, +[1275] = {category="ll"}, +[1276] = {category="lu", lccode=1277}, +[1277] = {category="ll"}, +[1278] = {category="lu", lccode=1279}, +[1279] = {category="ll"}, +[1280] = {category="lu", lccode=1281}, +[1281] = {category="ll"}, +[1282] = {category="lu", lccode=1283}, +[1283] = {category="ll"}, +[1284] = {category="lu", lccode=1285}, +[1285] = {category="ll"}, +[1286] = {category="lu", lccode=1287}, +[1287] = {category="ll"}, +[1288] = {category="lu", lccode=1289}, +[1289] = {category="ll"}, +[1290] = {category="lu", lccode=1291}, +[1291] = {category="ll"}, +[1292] = {category="lu", lccode=1293}, +[1293] = {category="ll"}, +[1294] = {category="lu", lccode=1295}, +[1295] = {category="ll"}, +[1296] = {category="lu", lccode=1297}, +[1297] = {category="ll"}, +[1298] = {category="lu", lccode=1299}, +[1299] = {category="ll"}, +[1300] = {category="lu", lccode=1301}, +[1301] = {category="ll"}, +[1302] = {category="lu", lccode=1303}, +[1303] = {category="ll"}, +[1304] = {category="lu", lccode=1305}, +[1305] = {category="ll"}, +[1306] = {category="lu", lccode=1307}, +[1307] = {category="ll"}, +[1308] = {category="lu", lccode=1309}, +[1309] = {category="ll"}, +[1310] = {category="lu", lccode=1311}, +[1311] = {category="ll"}, +[1312] = {category="lu", lccode=1313}, +[1313] = {category="ll"}, +[1314] = {category="lu", lccode=1315}, +[1315] = {category="ll"}, +[1316] = {category="lu", lccode=1317}, +[1317] = {category="ll"}, +[1318] = {category="lu", lccode=1319}, +[1319] = {category="ll"}, +[1320] = {category="lu", lccode=1321}, +[1321] = {category="ll"}, +[1322] = {category="lu", lccode=1323}, +[1323] = {category="ll"}, +[1324] = {category="lu", lccode=1325}, +[1325] = {category="ll"}, +[1326] = {category="lu", lccode=1327}, +[1327] = {category="ll"}, +[1329] = {category="lu", lccode=1377}, +[1330] = {category="lu", lccode=1378}, +[1331] = {category="lu", lccode=1379}, +[1332] = {category="lu", lccode=1380}, +[1333] = {category="lu", lccode=1381}, +[1334] = {category="lu", lccode=1382}, +[1335] = {category="lu", lccode=1383}, +[1336] = {category="lu", lccode=1384}, +[1337] = {category="lu", lccode=1385}, +[1338] = {category="lu", lccode=1386}, +[1339] = {category="lu", lccode=1387}, +[1340] = {category="lu", lccode=1388}, +[1341] = {category="lu", lccode=1389}, +[1342] = {category="lu", lccode=1390}, +[1343] = {category="lu", lccode=1391}, +[1344] = {category="lu", lccode=1392}, +[1345] = {category="lu", lccode=1393}, +[1346] = {category="lu", lccode=1394}, +[1347] = {category="lu", lccode=1395}, +[1348] = {category="lu", lccode=1396}, +[1349] = {category="lu", lccode=1397}, +[1350] = {category="lu", lccode=1398}, +[1351] = {category="lu", lccode=1399}, +[1352] = {category="lu", lccode=1400}, +[1353] = {category="lu", lccode=1401}, +[1354] = {category="lu", lccode=1402}, +[1355] = {category="lu", lccode=1403}, +[1356] = {category="lu", lccode=1404}, +[1357] = {category="lu", lccode=1405}, +[1358] = {category="lu", lccode=1406}, +[1359] = {category="lu", lccode=1407}, +[1360] = {category="lu", lccode=1408}, +[1361] = {category="lu", lccode=1409}, +[1362] = {category="lu", lccode=1410}, +[1363] = {category="lu", lccode=1411}, +[1364] = {category="lu", lccode=1412}, +[1365] = {category="lu", lccode=1413}, +[1366] = {category="lu", lccode=1414}, +[1369] = {category="lm"}, +[1376] = {category="ll"}, +[1377] = {category="ll"}, +[1378] = {category="ll"}, +[1379] = {category="ll"}, +[1380] = {category="ll"}, +[1381] = {category="ll"}, +[1382] = {category="ll"}, +[1383] = {category="ll"}, +[1384] = {category="ll"}, +[1385] = {category="ll"}, +[1386] = {category="ll"}, +[1387] = {category="ll"}, +[1388] = {category="ll"}, +[1389] = {category="ll"}, +[1390] = {category="ll"}, +[1391] = {category="ll"}, +[1392] = {category="ll"}, +[1393] = {category="ll"}, +[1394] = {category="ll"}, +[1395] = {category="ll"}, +[1396] = {category="ll"}, +[1397] = {category="ll"}, +[1398] = {category="ll"}, +[1399] = {category="ll"}, +[1400] = {category="ll"}, +[1401] = {category="ll"}, +[1402] = {category="ll"}, +[1403] = {category="ll"}, +[1404] = {category="ll"}, +[1405] = {category="ll"}, +[1406] = {category="ll"}, +[1407] = {category="ll"}, +[1408] = {category="ll"}, +[1409] = {category="ll"}, +[1410] = {category="ll"}, +[1411] = {category="ll"}, +[1412] = {category="ll"}, +[1413] = {category="ll"}, +[1414] = {category="ll"}, +[1415] = {category="ll", shcode=12}, +[1416] = {category="ll"}, +[1488] = {category="lo"}, +[1489] = {category="lo"}, +[1490] = {category="lo"}, +[1491] = {category="lo"}, +[1492] = {category="lo"}, +[1493] = {category="lo"}, +[1494] = {category="lo"}, +[1495] = {category="lo"}, +[1496] = {category="lo"}, +[1497] = {category="lo"}, +[1498] = {category="lo"}, +[1499] = {category="lo"}, +[1500] = {category="lo"}, +[1501] = {category="lo"}, +[1502] = {category="lo"}, +[1503] = {category="lo"}, +[1504] = {category="lo"}, +[1505] = {category="lo"}, +[1506] = {category="lo"}, +[1507] = {category="lo"}, +[1508] = {category="lo"}, +[1509] = {category="lo"}, +[1510] = {category="lo"}, +[1511] = {category="lo"}, +[1512] = {category="lo"}, +[1513] = {category="lo"}, +[1514] = {category="lo"}, +[1519] = {category="lo"}, +[1520] = {category="lo"}, +[1521] = {category="lo"}, +[1522] = {category="lo"}, +[1568] = {category="lo"}, +[1569] = {category="lo"}, +[1570] = {category="lo", shcode=1575}, +[1571] = {category="lo", shcode=1575}, +[1572] = {category="lo", shcode=1608}, +[1573] = {category="lo", shcode=1575}, +[1574] = {category="lo", shcode=1610}, +[1575] = {category="lo"}, +[1576] = {category="lo"}, +[1577] = {category="lo"}, +[1578] = {category="lo"}, +[1579] = {category="lo"}, +[1580] = {category="lo"}, +[1581] = {category="lo"}, +[1582] = {category="lo"}, +[1583] = {category="lo"}, +[1584] = {category="lo"}, +[1585] = {category="lo"}, +[1586] = {category="lo"}, +[1587] = {category="lo"}, +[1588] = {category="lo"}, +[1589] = {category="lo"}, +[1590] = {category="lo"}, +[1591] = {category="lo"}, +[1592] = {category="lo"}, +[1593] = {category="lo"}, +[1594] = {category="lo"}, +[1595] = {category="lo"}, +[1596] = {category="lo"}, +[1597] = {category="lo"}, +[1598] = {category="lo"}, +[1599] = {category="lo"}, +[1600] = {category="lm"}, +[1601] = {category="lo"}, +[1602] = {category="lo"}, +[1603] = {category="lo"}, +[1604] = {category="lo"}, +[1605] = {category="lo"}, +[1606] = {category="lo"}, +[1607] = {category="lo"}, +[1608] = {category="lo"}, +[1609] = {category="lo"}, +[1610] = {category="lo"}, +[1646] = {category="lo"}, +[1647] = {category="lo"}, +[1649] = {category="lo"}, +[1650] = {category="lo"}, +[1651] = {category="lo"}, +[1652] = {category="lo"}, +[1653] = {category="lo", shcode=12}, +[1654] = {category="lo", shcode=12}, +[1655] = {category="lo", shcode=12}, +[1656] = {category="lo", shcode=12}, +[1657] = {category="lo"}, +[1658] = {category="lo"}, +[1659] = {category="lo"}, +[1660] = {category="lo"}, +[1661] = {category="lo"}, +[1662] = {category="lo"}, +[1663] = {category="lo"}, +[1664] = {category="lo"}, +[1665] = {category="lo"}, +[1666] = {category="lo"}, +[1667] = {category="lo"}, +[1668] = {category="lo"}, +[1669] = {category="lo"}, +[1670] = {category="lo"}, +[1671] = {category="lo"}, +[1672] = {category="lo"}, +[1673] = {category="lo"}, +[1674] = {category="lo"}, +[1675] = {category="lo"}, +[1676] = {category="lo"}, +[1677] = {category="lo"}, +[1678] = {category="lo"}, +[1679] = {category="lo"}, +[1680] = {category="lo"}, +[1681] = {category="lo"}, +[1682] = {category="lo"}, +[1683] = {category="lo"}, +[1684] = {category="lo"}, +[1685] = {category="lo"}, +[1686] = {category="lo"}, +[1687] = {category="lo"}, +[1688] = {category="lo"}, +[1689] = {category="lo"}, +[1690] = {category="lo"}, +[1691] = {category="lo"}, +[1692] = {category="lo"}, +[1693] = {category="lo"}, +[1694] = {category="lo"}, +[1695] = {category="lo"}, +[1696] = {category="lo"}, +[1697] = {category="lo"}, +[1698] = {category="lo"}, +[1699] = {category="lo"}, +[1700] = {category="lo"}, +[1701] = {category="lo"}, +[1702] = {category="lo"}, +[1703] = {category="lo"}, +[1704] = {category="lo"}, +[1705] = {category="lo"}, +[1706] = {category="lo"}, +[1707] = {category="lo"}, +[1708] = {category="lo"}, +[1709] = {category="lo"}, +[1710] = {category="lo"}, +[1711] = {category="lo"}, +[1712] = {category="lo"}, +[1713] = {category="lo"}, +[1714] = {category="lo"}, +[1715] = {category="lo"}, +[1716] = {category="lo"}, +[1717] = {category="lo"}, +[1718] = {category="lo"}, +[1719] = {category="lo"}, +[1720] = {category="lo"}, +[1721] = {category="lo"}, +[1722] = {category="lo"}, +[1723] = {category="lo"}, +[1724] = {category="lo"}, +[1725] = {category="lo"}, +[1726] = {category="lo"}, +[1727] = {category="lo"}, +[1728] = {category="lo", shcode=1749}, +[1729] = {category="lo"}, +[1730] = {category="lo", shcode=1729}, +[1731] = {category="lo"}, +[1732] = {category="lo"}, +[1733] = {category="lo"}, +[1734] = {category="lo"}, +[1735] = {category="lo"}, +[1736] = {category="lo"}, +[1737] = {category="lo"}, +[1738] = {category="lo"}, +[1739] = {category="lo"}, +[1740] = {category="lo"}, +[1741] = {category="lo"}, +[1742] = {category="lo"}, +[1743] = {category="lo"}, +[1744] = {category="lo"}, +[1745] = {category="lo"}, +[1746] = {category="lo"}, +[1747] = {category="lo", shcode=1746}, +[1749] = {category="lo"}, +[1765] = {category="lm"}, +[1766] = {category="lm"}, +[1774] = {category="lo"}, +[1775] = {category="lo"}, +[1786] = {category="lo"}, +[1787] = {category="lo"}, +[1788] = {category="lo"}, +[1791] = {category="lo"}, +[1808] = {category="lo"}, +[1810] = {category="lo"}, +[1811] = {category="lo"}, +[1812] = {category="lo"}, +[1813] = {category="lo"}, +[1814] = {category="lo"}, +[1815] = {category="lo"}, +[1816] = {category="lo"}, +[1817] = {category="lo"}, +[1818] = {category="lo"}, +[1819] = {category="lo"}, +[1820] = {category="lo"}, +[1821] = {category="lo"}, +[1822] = {category="lo"}, +[1823] = {category="lo"}, +[1824] = {category="lo"}, +[1825] = {category="lo"}, +[1826] = {category="lo"}, +[1827] = {category="lo"}, +[1828] = {category="lo"}, +[1829] = {category="lo"}, +[1830] = {category="lo"}, +[1831] = {category="lo"}, +[1832] = {category="lo"}, +[1833] = {category="lo"}, +[1834] = {category="lo"}, +[1835] = {category="lo"}, +[1836] = {category="lo"}, +[1837] = {category="lo"}, +[1838] = {category="lo"}, +[1839] = {category="lo"}, +[1869] = {category="lo"}, +[1870] = {category="lo"}, +[1871] = {category="lo"}, +[1872] = {category="lo"}, +[1873] = {category="lo"}, +[1874] = {category="lo"}, +[1875] = {category="lo"}, +[1876] = {category="lo"}, +[1877] = {category="lo"}, +[1878] = {category="lo"}, +[1879] = {category="lo"}, +[1880] = {category="lo"}, +[1881] = {category="lo"}, +[1882] = {category="lo"}, +[1883] = {category="lo"}, +[1884] = {category="lo"}, +[1885] = {category="lo"}, +[1886] = {category="lo"}, +[1887] = {category="lo"}, +[1888] = {category="lo"}, +[1889] = {category="lo"}, +[1890] = {category="lo"}, +[1891] = {category="lo"}, +[1892] = {category="lo"}, +[1893] = {category="lo"}, +[1894] = {category="lo"}, +[1895] = {category="lo"}, +[1896] = {category="lo"}, +[1897] = {category="lo"}, +[1898] = {category="lo"}, +[1899] = {category="lo"}, +[1900] = {category="lo"}, +[1901] = {category="lo"}, +[1902] = {category="lo"}, +[1903] = {category="lo"}, +[1904] = {category="lo"}, +[1905] = {category="lo"}, +[1906] = {category="lo"}, +[1907] = {category="lo"}, +[1908] = {category="lo"}, +[1909] = {category="lo"}, +[1910] = {category="lo"}, +[1911] = {category="lo"}, +[1912] = {category="lo"}, +[1913] = {category="lo"}, +[1914] = {category="lo"}, +[1915] = {category="lo"}, +[1916] = {category="lo"}, +[1917] = {category="lo"}, +[1918] = {category="lo"}, +[1919] = {category="lo"}, +[1920] = {category="lo"}, +[1921] = {category="lo"}, +[1922] = {category="lo"}, +[1923] = {category="lo"}, +[1924] = {category="lo"}, +[1925] = {category="lo"}, +[1926] = {category="lo"}, +[1927] = {category="lo"}, +[1928] = {category="lo"}, +[1929] = {category="lo"}, +[1930] = {category="lo"}, +[1931] = {category="lo"}, +[1932] = {category="lo"}, +[1933] = {category="lo"}, +[1934] = {category="lo"}, +[1935] = {category="lo"}, +[1936] = {category="lo"}, +[1937] = {category="lo"}, +[1938] = {category="lo"}, +[1939] = {category="lo"}, +[1940] = {category="lo"}, +[1941] = {category="lo"}, +[1942] = {category="lo"}, +[1943] = {category="lo"}, +[1944] = {category="lo"}, +[1945] = {category="lo"}, +[1946] = {category="lo"}, +[1947] = {category="lo"}, +[1948] = {category="lo"}, +[1949] = {category="lo"}, +[1950] = {category="lo"}, +[1951] = {category="lo"}, +[1952] = {category="lo"}, +[1953] = {category="lo"}, +[1954] = {category="lo"}, +[1955] = {category="lo"}, +[1956] = {category="lo"}, +[1957] = {category="lo"}, +[1969] = {category="lo"}, +[1994] = {category="lo"}, +[1995] = {category="lo"}, +[1996] = {category="lo"}, +[1997] = {category="lo"}, +[1998] = {category="lo"}, +[1999] = {category="lo"}, +[2000] = {category="lo"}, +[2001] = {category="lo"}, +[2002] = {category="lo"}, +[2003] = {category="lo"}, +[2004] = {category="lo"}, +[2005] = {category="lo"}, +[2006] = {category="lo"}, +[2007] = {category="lo"}, +[2008] = {category="lo"}, +[2009] = {category="lo"}, +[2010] = {category="lo"}, +[2011] = {category="lo"}, +[2012] = {category="lo"}, +[2013] = {category="lo"}, +[2014] = {category="lo"}, +[2015] = {category="lo"}, +[2016] = {category="lo"}, +[2017] = {category="lo"}, +[2018] = {category="lo"}, +[2019] = {category="lo"}, +[2020] = {category="lo"}, +[2021] = {category="lo"}, +[2022] = {category="lo"}, +[2023] = {category="lo"}, +[2024] = {category="lo"}, +[2025] = {category="lo"}, +[2026] = {category="lo"}, +[2036] = {category="lm"}, +[2037] = {category="lm"}, +[2042] = {category="lm"}, +[2048] = {category="lo"}, +[2049] = {category="lo"}, +[2050] = {category="lo"}, +[2051] = {category="lo"}, +[2052] = {category="lo"}, +[2053] = {category="lo"}, +[2054] = {category="lo"}, +[2055] = {category="lo"}, +[2056] = {category="lo"}, +[2057] = {category="lo"}, +[2058] = {category="lo"}, +[2059] = {category="lo"}, +[2060] = {category="lo"}, +[2061] = {category="lo"}, +[2062] = {category="lo"}, +[2063] = {category="lo"}, +[2064] = {category="lo"}, +[2065] = {category="lo"}, +[2066] = {category="lo"}, +[2067] = {category="lo"}, +[2068] = {category="lo"}, +[2069] = {category="lo"}, +[2074] = {category="lm"}, +[2084] = {category="lm"}, +[2088] = {category="lm"}, +[2112] = {category="lo"}, +[2113] = {category="lo"}, +[2114] = {category="lo"}, +[2115] = {category="lo"}, +[2116] = {category="lo"}, +[2117] = {category="lo"}, +[2118] = {category="lo"}, +[2119] = {category="lo"}, +[2120] = {category="lo"}, +[2121] = {category="lo"}, +[2122] = {category="lo"}, +[2123] = {category="lo"}, +[2124] = {category="lo"}, +[2125] = {category="lo"}, +[2126] = {category="lo"}, +[2127] = {category="lo"}, +[2128] = {category="lo"}, +[2129] = {category="lo"}, +[2130] = {category="lo"}, +[2131] = {category="lo"}, +[2132] = {category="lo"}, +[2133] = {category="lo"}, +[2134] = {category="lo"}, +[2135] = {category="lo"}, +[2136] = {category="lo"}, +[2144] = {category="lo"}, +[2145] = {category="lo"}, +[2146] = {category="lo"}, +[2147] = {category="lo"}, +[2148] = {category="lo"}, +[2149] = {category="lo"}, +[2150] = {category="lo"}, +[2151] = {category="lo"}, +[2152] = {category="lo"}, +[2153] = {category="lo"}, +[2154] = {category="lo"}, +[2160] = {category="lo"}, +[2161] = {category="lo"}, +[2162] = {category="lo"}, +[2163] = {category="lo"}, +[2164] = {category="lo"}, +[2165] = {category="lo"}, +[2166] = {category="lo"}, +[2167] = {category="lo"}, +[2168] = {category="lo"}, +[2169] = {category="lo"}, +[2170] = {category="lo"}, +[2171] = {category="lo"}, +[2172] = {category="lo"}, +[2173] = {category="lo"}, +[2174] = {category="lo"}, +[2175] = {category="lo"}, +[2176] = {category="lo"}, +[2177] = {category="lo"}, +[2178] = {category="lo"}, +[2179] = {category="lo"}, +[2180] = {category="lo"}, +[2181] = {category="lo"}, +[2182] = {category="lo"}, +[2183] = {category="lo"}, +[2185] = {category="lo"}, +[2186] = {category="lo"}, +[2187] = {category="lo"}, +[2188] = {category="lo"}, +[2189] = {category="lo"}, +[2190] = {category="lo"}, +[2208] = {category="lo"}, +[2209] = {category="lo"}, +[2210] = {category="lo"}, +[2211] = {category="lo"}, +[2212] = {category="lo"}, +[2213] = {category="lo"}, +[2214] = {category="lo"}, +[2215] = {category="lo"}, +[2216] = {category="lo"}, +[2217] = {category="lo"}, +[2218] = {category="lo"}, +[2219] = {category="lo"}, +[2220] = {category="lo"}, +[2221] = {category="lo"}, +[2222] = {category="lo"}, +[2223] = {category="lo"}, +[2224] = {category="lo"}, +[2225] = {category="lo"}, +[2226] = {category="lo"}, +[2227] = {category="lo"}, +[2228] = {category="lo"}, +[2229] = {category="lo"}, +[2230] = {category="lo"}, +[2231] = {category="lo"}, +[2232] = {category="lo"}, +[2233] = {category="lo"}, +[2234] = {category="lo"}, +[2235] = {category="lo"}, +[2236] = {category="lo"}, +[2237] = {category="lo"}, +[2238] = {category="lo"}, +[2239] = {category="lo"}, +[2240] = {category="lo"}, +[2241] = {category="lo"}, +[2242] = {category="lo"}, +[2243] = {category="lo"}, +[2244] = {category="lo"}, +[2245] = {category="lo"}, +[2246] = {category="lo"}, +[2247] = {category="lo"}, +[2248] = {category="lo"}, +[2249] = {category="lm"}, +[2308] = {category="lo"}, +[2309] = {category="lo"}, +[2310] = {category="lo"}, +[2311] = {category="lo"}, +[2312] = {category="lo"}, +[2313] = {category="lo"}, +[2314] = {category="lo"}, +[2315] = {category="lo"}, +[2316] = {category="lo"}, +[2317] = {category="lo"}, +[2318] = {category="lo"}, +[2319] = {category="lo"}, +[2320] = {category="lo"}, +[2321] = {category="lo"}, +[2322] = {category="lo"}, +[2323] = {category="lo"}, +[2324] = {category="lo"}, +[2325] = {category="lo"}, +[2326] = {category="lo"}, +[2327] = {category="lo"}, +[2328] = {category="lo"}, +[2329] = {category="lo"}, +[2330] = {category="lo"}, +[2331] = {category="lo"}, +[2332] = {category="lo"}, +[2333] = {category="lo"}, +[2334] = {category="lo"}, +[2335] = {category="lo"}, +[2336] = {category="lo"}, +[2337] = {category="lo"}, +[2338] = {category="lo"}, +[2339] = {category="lo"}, +[2340] = {category="lo"}, +[2341] = {category="lo"}, +[2342] = {category="lo"}, +[2343] = {category="lo"}, +[2344] = {category="lo"}, +[2345] = {category="lo", shcode=2344}, +[2346] = {category="lo"}, +[2347] = {category="lo"}, +[2348] = {category="lo"}, +[2349] = {category="lo"}, +[2350] = {category="lo"}, +[2351] = {category="lo"}, +[2352] = {category="lo"}, +[2353] = {category="lo", shcode=2352}, +[2354] = {category="lo"}, +[2355] = {category="lo"}, +[2356] = {category="lo", shcode=2355}, +[2357] = {category="lo"}, +[2358] = {category="lo"}, +[2359] = {category="lo"}, +[2360] = {category="lo"}, +[2361] = {category="lo"}, +[2365] = {category="lo"}, +[2384] = {category="lo"}, +[2392] = {category="lo", shcode=2325}, +[2393] = {category="lo", shcode=2326}, +[2394] = {category="lo", shcode=2327}, +[2395] = {category="lo", shcode=2332}, +[2396] = {category="lo", shcode=2337}, +[2397] = {category="lo", shcode=2338}, +[2398] = {category="lo", shcode=2347}, +[2399] = {category="lo", shcode=2351}, +[2400] = {category="lo"}, +[2401] = {category="lo"}, +[2417] = {category="lm"}, +[2418] = {category="lo"}, +[2419] = {category="lo"}, +[2420] = {category="lo"}, +[2421] = {category="lo"}, +[2422] = {category="lo"}, +[2423] = {category="lo"}, +[2424] = {category="lo"}, +[2425] = {category="lo"}, +[2426] = {category="lo"}, +[2427] = {category="lo"}, +[2428] = {category="lo"}, +[2429] = {category="lo"}, +[2430] = {category="lo"}, +[2431] = {category="lo"}, +[2432] = {category="lo"}, +[2437] = {category="lo"}, +[2438] = {category="lo"}, +[2439] = {category="lo"}, +[2440] = {category="lo"}, +[2441] = {category="lo"}, +[2442] = {category="lo"}, +[2443] = {category="lo"}, +[2444] = {category="lo"}, +[2447] = {category="lo"}, +[2448] = {category="lo"}, +[2451] = {category="lo"}, +[2452] = {category="lo"}, +[2453] = {category="lo"}, +[2454] = {category="lo"}, +[2455] = {category="lo"}, +[2456] = {category="lo"}, +[2457] = {category="lo"}, +[2458] = {category="lo"}, +[2459] = {category="lo"}, +[2460] = {category="lo"}, +[2461] = {category="lo"}, +[2462] = {category="lo"}, +[2463] = {category="lo"}, +[2464] = {category="lo"}, +[2465] = {category="lo"}, +[2466] = {category="lo"}, +[2467] = {category="lo"}, +[2468] = {category="lo"}, +[2469] = {category="lo"}, +[2470] = {category="lo"}, +[2471] = {category="lo"}, +[2472] = {category="lo"}, +[2474] = {category="lo"}, +[2475] = {category="lo"}, +[2476] = {category="lo"}, +[2477] = {category="lo"}, +[2478] = {category="lo"}, +[2479] = {category="lo"}, +[2480] = {category="lo"}, +[2482] = {category="lo"}, +[2486] = {category="lo"}, +[2487] = {category="lo"}, +[2488] = {category="lo"}, +[2489] = {category="lo"}, +[2493] = {category="lo"}, +[2510] = {category="lo"}, +[2524] = {category="lo", shcode=2465}, +[2525] = {category="lo", shcode=2466}, +[2527] = {category="lo", shcode=2479}, +[2528] = {category="lo"}, +[2529] = {category="lo"}, +[2544] = {category="lo"}, +[2545] = {category="lo"}, +[2556] = {category="lo"}, +[2565] = {category="lo"}, +[2566] = {category="lo"}, +[2567] = {category="lo"}, +[2568] = {category="lo"}, +[2569] = {category="lo"}, +[2570] = {category="lo"}, +[2575] = {category="lo"}, +[2576] = {category="lo"}, +[2579] = {category="lo"}, +[2580] = {category="lo"}, +[2581] = {category="lo"}, +[2582] = {category="lo"}, +[2583] = {category="lo"}, +[2584] = {category="lo"}, +[2585] = {category="lo"}, +[2586] = {category="lo"}, +[2587] = {category="lo"}, +[2588] = {category="lo"}, +[2589] = {category="lo"}, +[2590] = {category="lo"}, +[2591] = {category="lo"}, +[2592] = {category="lo"}, +[2593] = {category="lo"}, +[2594] = {category="lo"}, +[2595] = {category="lo"}, +[2596] = {category="lo"}, +[2597] = {category="lo"}, +[2598] = {category="lo"}, +[2599] = {category="lo"}, +[2600] = {category="lo"}, +[2602] = {category="lo"}, +[2603] = {category="lo"}, +[2604] = {category="lo"}, +[2605] = {category="lo"}, +[2606] = {category="lo"}, +[2607] = {category="lo"}, +[2608] = {category="lo"}, +[2610] = {category="lo"}, +[2611] = {category="lo", shcode=2610}, +[2613] = {category="lo"}, +[2614] = {category="lo", shcode=2616}, +[2616] = {category="lo"}, +[2617] = {category="lo"}, +[2649] = {category="lo", shcode=2582}, +[2650] = {category="lo", shcode=2583}, +[2651] = {category="lo", shcode=2588}, +[2652] = {category="lo"}, +[2654] = {category="lo", shcode=2603}, +[2674] = {category="lo"}, +[2675] = {category="lo"}, +[2676] = {category="lo"}, +[2693] = {category="lo"}, +[2694] = {category="lo"}, +[2695] = {category="lo"}, +[2696] = {category="lo"}, +[2697] = {category="lo"}, +[2698] = {category="lo"}, +[2699] = {category="lo"}, +[2700] = {category="lo"}, +[2701] = {category="lo"}, +[2703] = {category="lo"}, +[2704] = {category="lo"}, +[2705] = {category="lo"}, +[2707] = {category="lo"}, +[2708] = {category="lo"}, +[2709] = {category="lo"}, +[2710] = {category="lo"}, +[2711] = {category="lo"}, +[2712] = {category="lo"}, +[2713] = {category="lo"}, +[2714] = {category="lo"}, +[2715] = {category="lo"}, +[2716] = {category="lo"}, +[2717] = {category="lo"}, +[2718] = {category="lo"}, +[2719] = {category="lo"}, +[2720] = {category="lo"}, +[2721] = {category="lo"}, +[2722] = {category="lo"}, +[2723] = {category="lo"}, +[2724] = {category="lo"}, +[2725] = {category="lo"}, +[2726] = {category="lo"}, +[2727] = {category="lo"}, +[2728] = {category="lo"}, +[2730] = {category="lo"}, +[2731] = {category="lo"}, +[2732] = {category="lo"}, +[2733] = {category="lo"}, +[2734] = {category="lo"}, +[2735] = {category="lo"}, +[2736] = {category="lo"}, +[2738] = {category="lo"}, +[2739] = {category="lo"}, +[2741] = {category="lo"}, +[2742] = {category="lo"}, +[2743] = {category="lo"}, +[2744] = {category="lo"}, +[2745] = {category="lo"}, +[2749] = {category="lo"}, +[2768] = {category="lo"}, +[2784] = {category="lo"}, +[2785] = {category="lo"}, +[2809] = {category="lo"}, +[2821] = {category="lo"}, +[2822] = {category="lo"}, +[2823] = {category="lo"}, +[2824] = {category="lo"}, +[2825] = {category="lo"}, +[2826] = {category="lo"}, +[2827] = {category="lo"}, +[2828] = {category="lo"}, +[2831] = {category="lo"}, +[2832] = {category="lo"}, +[2835] = {category="lo"}, +[2836] = {category="lo"}, +[2837] = {category="lo"}, +[2838] = {category="lo"}, +[2839] = {category="lo"}, +[2840] = {category="lo"}, +[2841] = {category="lo"}, +[2842] = {category="lo"}, +[2843] = {category="lo"}, +[2844] = {category="lo"}, +[2845] = {category="lo"}, +[2846] = {category="lo"}, +[2847] = {category="lo"}, +[2848] = {category="lo"}, +[2849] = {category="lo"}, +[2850] = {category="lo"}, +[2851] = {category="lo"}, +[2852] = {category="lo"}, +[2853] = {category="lo"}, +[2854] = {category="lo"}, +[2855] = {category="lo"}, +[2856] = {category="lo"}, +[2858] = {category="lo"}, +[2859] = {category="lo"}, +[2860] = {category="lo"}, +[2861] = {category="lo"}, +[2862] = {category="lo"}, +[2863] = {category="lo"}, +[2864] = {category="lo"}, +[2866] = {category="lo"}, +[2867] = {category="lo"}, +[2869] = {category="lo"}, +[2870] = {category="lo"}, +[2871] = {category="lo"}, +[2872] = {category="lo"}, +[2873] = {category="lo"}, +[2877] = {category="lo"}, +[2908] = {category="lo", shcode=2849}, +[2909] = {category="lo", shcode=2850}, +[2911] = {category="lo"}, +[2912] = {category="lo"}, +[2913] = {category="lo"}, +[2929] = {category="lo"}, +[2947] = {category="lo"}, +[2949] = {category="lo"}, +[2950] = {category="lo"}, +[2951] = {category="lo"}, +[2952] = {category="lo"}, +[2953] = {category="lo"}, +[2954] = {category="lo"}, +[2958] = {category="lo"}, +[2959] = {category="lo"}, +[2960] = {category="lo"}, +[2962] = {category="lo"}, +[2963] = {category="lo"}, +[2964] = {category="lo", shcode=2962}, +[2965] = {category="lo"}, +[2969] = {category="lo"}, +[2970] = {category="lo"}, +[2972] = {category="lo"}, +[2974] = {category="lo"}, +[2975] = {category="lo"}, +[2979] = {category="lo"}, +[2980] = {category="lo"}, +[2984] = {category="lo"}, +[2985] = {category="lo"}, +[2986] = {category="lo"}, +[2990] = {category="lo"}, +[2991] = {category="lo"}, +[2992] = {category="lo"}, +[2993] = {category="lo"}, +[2994] = {category="lo"}, +[2995] = {category="lo"}, +[2996] = {category="lo"}, +[2997] = {category="lo"}, +[2998] = {category="lo"}, +[2999] = {category="lo"}, +[3000] = {category="lo"}, +[3001] = {category="lo"}, +[3024] = {category="lo"}, +[3077] = {category="lo"}, +[3078] = {category="lo"}, +[3079] = {category="lo"}, +[3080] = {category="lo"}, +[3081] = {category="lo"}, +[3082] = {category="lo"}, +[3083] = {category="lo"}, +[3084] = {category="lo"}, +[3086] = {category="lo"}, +[3087] = {category="lo"}, +[3088] = {category="lo"}, +[3090] = {category="lo"}, +[3091] = {category="lo"}, +[3092] = {category="lo"}, +[3093] = {category="lo"}, +[3094] = {category="lo"}, +[3095] = {category="lo"}, +[3096] = {category="lo"}, +[3097] = {category="lo"}, +[3098] = {category="lo"}, +[3099] = {category="lo"}, +[3100] = {category="lo"}, +[3101] = {category="lo"}, +[3102] = {category="lo"}, +[3103] = {category="lo"}, +[3104] = {category="lo"}, +[3105] = {category="lo"}, +[3106] = {category="lo"}, +[3107] = {category="lo"}, +[3108] = {category="lo"}, +[3109] = {category="lo"}, +[3110] = {category="lo"}, +[3111] = {category="lo"}, +[3112] = {category="lo"}, +[3114] = {category="lo"}, +[3115] = {category="lo"}, +[3116] = {category="lo"}, +[3117] = {category="lo"}, +[3118] = {category="lo"}, +[3119] = {category="lo"}, +[3120] = {category="lo"}, +[3121] = {category="lo"}, +[3122] = {category="lo"}, +[3123] = {category="lo"}, +[3124] = {category="lo"}, +[3125] = {category="lo"}, +[3126] = {category="lo"}, +[3127] = {category="lo"}, +[3128] = {category="lo"}, +[3129] = {category="lo"}, +[3133] = {category="lo"}, +[3160] = {category="lo"}, +[3161] = {category="lo"}, +[3162] = {category="lo"}, +[3165] = {category="lo"}, +[3168] = {category="lo"}, +[3169] = {category="lo"}, +[3200] = {category="lo"}, +[3205] = {category="lo"}, +[3206] = {category="lo"}, +[3207] = {category="lo"}, +[3208] = {category="lo"}, +[3209] = {category="lo"}, +[3210] = {category="lo"}, +[3211] = {category="lo"}, +[3212] = {category="lo"}, +[3214] = {category="lo"}, +[3215] = {category="lo"}, +[3216] = {category="lo"}, +[3218] = {category="lo"}, +[3219] = {category="lo"}, +[3220] = {category="lo"}, +[3221] = {category="lo"}, +[3222] = {category="lo"}, +[3223] = {category="lo"}, +[3224] = {category="lo"}, +[3225] = {category="lo"}, +[3226] = {category="lo"}, +[3227] = {category="lo"}, +[3228] = {category="lo"}, +[3229] = {category="lo"}, +[3230] = {category="lo"}, +[3231] = {category="lo"}, +[3232] = {category="lo"}, +[3233] = {category="lo"}, +[3234] = {category="lo"}, +[3235] = {category="lo"}, +[3236] = {category="lo"}, +[3237] = {category="lo"}, +[3238] = {category="lo"}, +[3239] = {category="lo"}, +[3240] = {category="lo"}, +[3242] = {category="lo"}, +[3243] = {category="lo"}, +[3244] = {category="lo"}, +[3245] = {category="lo"}, +[3246] = {category="lo"}, +[3247] = {category="lo"}, +[3248] = {category="lo"}, +[3249] = {category="lo"}, +[3250] = {category="lo"}, +[3251] = {category="lo"}, +[3253] = {category="lo"}, +[3254] = {category="lo"}, +[3255] = {category="lo"}, +[3256] = {category="lo"}, +[3257] = {category="lo"}, +[3261] = {category="lo"}, +[3293] = {category="lo"}, +[3294] = {category="lo"}, +[3296] = {category="lo"}, +[3297] = {category="lo"}, +[3313] = {category="lo"}, +[3314] = {category="lo"}, +[3332] = {category="lo"}, +[3333] = {category="lo"}, +[3334] = {category="lo"}, +[3335] = {category="lo"}, +[3336] = {category="lo"}, +[3337] = {category="lo"}, +[3338] = {category="lo"}, +[3339] = {category="lo"}, +[3340] = {category="lo"}, +[3342] = {category="lo"}, +[3343] = {category="lo"}, +[3344] = {category="lo"}, +[3346] = {category="lo"}, +[3347] = {category="lo"}, +[3348] = {category="lo"}, +[3349] = {category="lo"}, +[3350] = {category="lo"}, +[3351] = {category="lo"}, +[3352] = {category="lo"}, +[3353] = {category="lo"}, +[3354] = {category="lo"}, +[3355] = {category="lo"}, +[3356] = {category="lo"}, +[3357] = {category="lo"}, +[3358] = {category="lo"}, +[3359] = {category="lo"}, +[3360] = {category="lo"}, +[3361] = {category="lo"}, +[3362] = {category="lo"}, +[3363] = {category="lo"}, +[3364] = {category="lo"}, +[3365] = {category="lo"}, +[3366] = {category="lo"}, +[3367] = {category="lo"}, +[3368] = {category="lo"}, +[3369] = {category="lo"}, +[3370] = {category="lo"}, +[3371] = {category="lo"}, +[3372] = {category="lo"}, +[3373] = {category="lo"}, +[3374] = {category="lo"}, +[3375] = {category="lo"}, +[3376] = {category="lo"}, +[3377] = {category="lo"}, +[3378] = {category="lo"}, +[3379] = {category="lo"}, +[3380] = {category="lo"}, +[3381] = {category="lo"}, +[3382] = {category="lo"}, +[3383] = {category="lo"}, +[3384] = {category="lo"}, +[3385] = {category="lo"}, +[3386] = {category="lo"}, +[3389] = {category="lo"}, +[3406] = {category="lo"}, +[3412] = {category="lo"}, +[3413] = {category="lo"}, +[3414] = {category="lo"}, +[3423] = {category="lo"}, +[3424] = {category="lo"}, +[3425] = {category="lo"}, +[3450] = {category="lo"}, +[3451] = {category="lo"}, +[3452] = {category="lo"}, +[3453] = {category="lo"}, +[3454] = {category="lo"}, +[3455] = {category="lo"}, +[3461] = {category="lo"}, +[3462] = {category="lo"}, +[3463] = {category="lo"}, +[3464] = {category="lo"}, +[3465] = {category="lo"}, +[3466] = {category="lo"}, +[3467] = {category="lo"}, +[3468] = {category="lo"}, +[3469] = {category="lo"}, +[3470] = {category="lo"}, +[3471] = {category="lo"}, +[3472] = {category="lo"}, +[3473] = {category="lo"}, +[3474] = {category="lo"}, +[3475] = {category="lo"}, +[3476] = {category="lo"}, +[3477] = {category="lo"}, +[3478] = {category="lo"}, +[3482] = {category="lo"}, +[3483] = {category="lo"}, +[3484] = {category="lo"}, +[3485] = {category="lo"}, +[3486] = {category="lo"}, +[3487] = {category="lo"}, +[3488] = {category="lo"}, +[3489] = {category="lo"}, +[3490] = {category="lo"}, +[3491] = {category="lo"}, +[3492] = {category="lo"}, +[3493] = {category="lo"}, +[3494] = {category="lo"}, +[3495] = {category="lo"}, +[3496] = {category="lo"}, +[3497] = {category="lo"}, +[3498] = {category="lo"}, +[3499] = {category="lo"}, +[3500] = {category="lo"}, +[3501] = {category="lo"}, +[3502] = {category="lo"}, +[3503] = {category="lo"}, +[3504] = {category="lo"}, +[3505] = {category="lo"}, +[3507] = {category="lo"}, +[3508] = {category="lo"}, +[3509] = {category="lo"}, +[3510] = {category="lo"}, +[3511] = {category="lo"}, +[3512] = {category="lo"}, +[3513] = {category="lo"}, +[3514] = {category="lo"}, +[3515] = {category="lo"}, +[3517] = {category="lo"}, +[3520] = {category="lo"}, +[3521] = {category="lo"}, +[3522] = {category="lo"}, +[3523] = {category="lo"}, +[3524] = {category="lo"}, +[3525] = {category="lo"}, +[3526] = {category="lo"}, +[3585] = {category="lo"}, +[3586] = {category="lo"}, +[3587] = {category="lo"}, +[3588] = {category="lo"}, +[3589] = {category="lo"}, +[3590] = {category="lo"}, +[3591] = {category="lo"}, +[3592] = {category="lo"}, +[3593] = {category="lo"}, +[3594] = {category="lo"}, +[3595] = {category="lo"}, +[3596] = {category="lo"}, +[3597] = {category="lo"}, +[3598] = {category="lo"}, +[3599] = {category="lo"}, +[3600] = {category="lo"}, +[3601] = {category="lo"}, +[3602] = {category="lo"}, +[3603] = {category="lo"}, +[3604] = {category="lo"}, +[3605] = {category="lo"}, +[3606] = {category="lo"}, +[3607] = {category="lo"}, +[3608] = {category="lo"}, +[3609] = {category="lo"}, +[3610] = {category="lo"}, +[3611] = {category="lo"}, +[3612] = {category="lo"}, +[3613] = {category="lo"}, +[3614] = {category="lo"}, +[3615] = {category="lo"}, +[3616] = {category="lo"}, +[3617] = {category="lo"}, +[3618] = {category="lo"}, +[3619] = {category="lo"}, +[3620] = {category="lo"}, +[3621] = {category="lo"}, +[3622] = {category="lo"}, +[3623] = {category="lo"}, +[3624] = {category="lo"}, +[3625] = {category="lo"}, +[3626] = {category="lo"}, +[3627] = {category="lo"}, +[3628] = {category="lo"}, +[3629] = {category="lo"}, +[3630] = {category="lo"}, +[3631] = {category="lo"}, +[3632] = {category="lo"}, +[3634] = {category="lo"}, +[3635] = {category="lo", shcode=12}, +[3648] = {category="lo"}, +[3649] = {category="lo"}, +[3650] = {category="lo"}, +[3651] = {category="lo"}, +[3652] = {category="lo"}, +[3653] = {category="lo"}, +[3654] = {category="lm"}, +[3713] = {category="lo"}, +[3714] = {category="lo"}, +[3716] = {category="lo"}, +[3718] = {category="lo"}, +[3719] = {category="lo"}, +[3720] = {category="lo"}, +[3721] = {category="lo"}, +[3722] = {category="lo"}, +[3724] = {category="lo"}, +[3725] = {category="lo"}, +[3726] = {category="lo"}, +[3727] = {category="lo"}, +[3728] = {category="lo"}, +[3729] = {category="lo"}, +[3730] = {category="lo"}, +[3731] = {category="lo"}, +[3732] = {category="lo"}, +[3733] = {category="lo"}, +[3734] = {category="lo"}, +[3735] = {category="lo"}, +[3736] = {category="lo"}, +[3737] = {category="lo"}, +[3738] = {category="lo"}, +[3739] = {category="lo"}, +[3740] = {category="lo"}, +[3741] = {category="lo"}, +[3742] = {category="lo"}, +[3743] = {category="lo"}, +[3744] = {category="lo"}, +[3745] = {category="lo"}, +[3746] = {category="lo"}, +[3747] = {category="lo"}, +[3749] = {category="lo"}, +[3751] = {category="lo"}, +[3752] = {category="lo"}, +[3753] = {category="lo"}, +[3754] = {category="lo"}, +[3755] = {category="lo"}, +[3756] = {category="lo"}, +[3757] = {category="lo"}, +[3758] = {category="lo"}, +[3759] = {category="lo"}, +[3760] = {category="lo"}, +[3762] = {category="lo"}, +[3763] = {category="lo", shcode=12}, +[3773] = {category="lo"}, +[3776] = {category="lo"}, +[3777] = {category="lo"}, +[3778] = {category="lo"}, +[3779] = {category="lo"}, +[3780] = {category="lo"}, +[3782] = {category="lm"}, +[3804] = {category="lo", shcode=12}, +[3805] = {category="lo", shcode=12}, +[3806] = {category="lo"}, +[3807] = {category="lo"}, +[3840] = {category="lo"}, +[3904] = {category="lo"}, +[3905] = {category="lo"}, +[3906] = {category="lo"}, +[3907] = {category="lo", shcode=3906}, +[3908] = {category="lo"}, +[3909] = {category="lo"}, +[3910] = {category="lo"}, +[3911] = {category="lo"}, +[3913] = {category="lo"}, +[3914] = {category="lo"}, +[3915] = {category="lo"}, +[3916] = {category="lo"}, +[3917] = {category="lo", shcode=3916}, +[3918] = {category="lo"}, +[3919] = {category="lo"}, +[3920] = {category="lo"}, +[3921] = {category="lo"}, +[3922] = {category="lo", shcode=3921}, +[3923] = {category="lo"}, +[3924] = {category="lo"}, +[3925] = {category="lo"}, +[3926] = {category="lo"}, +[3927] = {category="lo", shcode=3926}, +[3928] = {category="lo"}, +[3929] = {category="lo"}, +[3930] = {category="lo"}, +[3931] = {category="lo"}, +[3932] = {category="lo", shcode=3931}, +[3933] = {category="lo"}, +[3934] = {category="lo"}, +[3935] = {category="lo"}, +[3936] = {category="lo"}, +[3937] = {category="lo"}, +[3938] = {category="lo"}, +[3939] = {category="lo"}, +[3940] = {category="lo"}, +[3941] = {category="lo"}, +[3942] = {category="lo"}, +[3943] = {category="lo"}, +[3944] = {category="lo"}, +[3945] = {category="lo", shcode=3904}, +[3946] = {category="lo"}, +[3947] = {category="lo"}, +[3948] = {category="lo"}, +[3976] = {category="lo"}, +[3977] = {category="lo"}, +[3978] = {category="lo"}, +[3979] = {category="lo"}, +[3980] = {category="lo"}, +[4096] = {category="lo"}, +[4097] = {category="lo"}, +[4098] = {category="lo"}, +[4099] = {category="lo"}, +[4100] = {category="lo"}, +[4101] = {category="lo"}, +[4102] = {category="lo"}, +[4103] = {category="lo"}, +[4104] = {category="lo"}, +[4105] = {category="lo"}, +[4106] = {category="lo"}, +[4107] = {category="lo"}, +[4108] = {category="lo"}, +[4109] = {category="lo"}, +[4110] = {category="lo"}, +[4111] = {category="lo"}, +[4112] = {category="lo"}, +[4113] = {category="lo"}, +[4114] = {category="lo"}, +[4115] = {category="lo"}, +[4116] = {category="lo"}, +[4117] = {category="lo"}, +[4118] = {category="lo"}, +[4119] = {category="lo"}, +[4120] = {category="lo"}, +[4121] = {category="lo"}, +[4122] = {category="lo"}, +[4123] = {category="lo"}, +[4124] = {category="lo"}, +[4125] = {category="lo"}, +[4126] = {category="lo"}, +[4127] = {category="lo"}, +[4128] = {category="lo"}, +[4129] = {category="lo"}, +[4130] = {category="lo"}, +[4131] = {category="lo"}, +[4132] = {category="lo"}, +[4133] = {category="lo"}, +[4134] = {category="lo", shcode=4133}, +[4135] = {category="lo"}, +[4136] = {category="lo"}, +[4137] = {category="lo"}, +[4138] = {category="lo"}, +[4159] = {category="lo"}, +[4176] = {category="lo"}, +[4177] = {category="lo"}, +[4178] = {category="lo"}, +[4179] = {category="lo"}, +[4180] = {category="lo"}, +[4181] = {category="lo"}, +[4186] = {category="lo"}, +[4187] = {category="lo"}, +[4188] = {category="lo"}, +[4189] = {category="lo"}, +[4193] = {category="lo"}, +[4197] = {category="lo"}, +[4198] = {category="lo"}, +[4206] = {category="lo"}, +[4207] = {category="lo"}, +[4208] = {category="lo"}, +[4213] = {category="lo"}, +[4214] = {category="lo"}, +[4215] = {category="lo"}, +[4216] = {category="lo"}, +[4217] = {category="lo"}, +[4218] = {category="lo"}, +[4219] = {category="lo"}, +[4220] = {category="lo"}, +[4221] = {category="lo"}, +[4222] = {category="lo"}, +[4223] = {category="lo"}, +[4224] = {category="lo"}, +[4225] = {category="lo"}, +[4238] = {category="lo"}, +[4256] = {category="lu", lccode=11520}, +[4257] = {category="lu", lccode=11521}, +[4258] = {category="lu", lccode=11522}, +[4259] = {category="lu", lccode=11523}, +[4260] = {category="lu", lccode=11524}, +[4261] = {category="lu", lccode=11525}, +[4262] = {category="lu", lccode=11526}, +[4263] = {category="lu", lccode=11527}, +[4264] = {category="lu", lccode=11528}, +[4265] = {category="lu", lccode=11529}, +[4266] = {category="lu", lccode=11530}, +[4267] = {category="lu", lccode=11531}, +[4268] = {category="lu", lccode=11532}, +[4269] = {category="lu", lccode=11533}, +[4270] = {category="lu", lccode=11534}, +[4271] = {category="lu", lccode=11535}, +[4272] = {category="lu", lccode=11536}, +[4273] = {category="lu", lccode=11537}, +[4274] = {category="lu", lccode=11538}, +[4275] = {category="lu", lccode=11539}, +[4276] = {category="lu", lccode=11540}, +[4277] = {category="lu", lccode=11541}, +[4278] = {category="lu", lccode=11542}, +[4279] = {category="lu", lccode=11543}, +[4280] = {category="lu", lccode=11544}, +[4281] = {category="lu", lccode=11545}, +[4282] = {category="lu", lccode=11546}, +[4283] = {category="lu", lccode=11547}, +[4284] = {category="lu", lccode=11548}, +[4285] = {category="lu", lccode=11549}, +[4286] = {category="lu", lccode=11550}, +[4287] = {category="lu", lccode=11551}, +[4288] = {category="lu", lccode=11552}, +[4289] = {category="lu", lccode=11553}, +[4290] = {category="lu", lccode=11554}, +[4291] = {category="lu", lccode=11555}, +[4292] = {category="lu", lccode=11556}, +[4293] = {category="lu", lccode=11557}, +[4295] = {category="lu", lccode=11559}, +[4301] = {category="lu", lccode=11565}, +[4304] = {category="ll"}, +[4305] = {category="ll"}, +[4306] = {category="ll"}, +[4307] = {category="ll"}, +[4308] = {category="ll"}, +[4309] = {category="ll"}, +[4310] = {category="ll"}, +[4311] = {category="ll"}, +[4312] = {category="ll"}, +[4313] = {category="ll"}, +[4314] = {category="ll"}, +[4315] = {category="ll"}, +[4316] = {category="ll"}, +[4317] = {category="ll"}, +[4318] = {category="ll"}, +[4319] = {category="ll"}, +[4320] = {category="ll"}, +[4321] = {category="ll"}, +[4322] = {category="ll"}, +[4323] = {category="ll"}, +[4324] = {category="ll"}, +[4325] = {category="ll"}, +[4326] = {category="ll"}, +[4327] = {category="ll"}, +[4328] = {category="ll"}, +[4329] = {category="ll"}, +[4330] = {category="ll"}, +[4331] = {category="ll"}, +[4332] = {category="ll"}, +[4333] = {category="ll"}, +[4334] = {category="ll"}, +[4335] = {category="ll"}, +[4336] = {category="ll"}, +[4337] = {category="ll"}, +[4338] = {category="ll"}, +[4339] = {category="ll"}, +[4340] = {category="ll"}, +[4341] = {category="ll"}, +[4342] = {category="ll"}, +[4343] = {category="ll"}, +[4344] = {category="ll"}, +[4345] = {category="ll"}, +[4346] = {category="ll"}, +[4348] = {category="lm", shcode=14}, +[4349] = {category="ll"}, +[4350] = {category="ll"}, +[4351] = {category="ll"}, +[4352] = {category="lo"}, +[4353] = {category="lo"}, +[4354] = {category="lo"}, +[4355] = {category="lo"}, +[4356] = {category="lo"}, +[4357] = {category="lo"}, +[4358] = {category="lo"}, +[4359] = {category="lo"}, +[4360] = {category="lo"}, +[4361] = {category="lo"}, +[4362] = {category="lo"}, +[4363] = {category="lo"}, +[4364] = {category="lo"}, +[4365] = {category="lo"}, +[4366] = {category="lo"}, +[4367] = {category="lo"}, +[4368] = {category="lo"}, +[4369] = {category="lo"}, +[4370] = {category="lo"}, +[4371] = {category="lo"}, +[4372] = {category="lo"}, +[4373] = {category="lo"}, +[4374] = {category="lo"}, +[4375] = {category="lo"}, +[4376] = {category="lo"}, +[4377] = {category="lo"}, +[4378] = {category="lo"}, +[4379] = {category="lo"}, +[4380] = {category="lo"}, +[4381] = {category="lo"}, +[4382] = {category="lo"}, +[4383] = {category="lo"}, +[4384] = {category="lo"}, +[4385] = {category="lo"}, +[4386] = {category="lo"}, +[4387] = {category="lo"}, +[4388] = {category="lo"}, +[4389] = {category="lo"}, +[4390] = {category="lo"}, +[4391] = {category="lo"}, +[4392] = {category="lo"}, +[4393] = {category="lo"}, +[4394] = {category="lo"}, +[4395] = {category="lo"}, +[4396] = {category="lo"}, +[4397] = {category="lo"}, +[4398] = {category="lo"}, +[4399] = {category="lo"}, +[4400] = {category="lo"}, +[4401] = {category="lo"}, +[4402] = {category="lo"}, +[4403] = {category="lo"}, +[4404] = {category="lo"}, +[4405] = {category="lo"}, +[4406] = {category="lo"}, +[4407] = {category="lo"}, +[4408] = {category="lo"}, +[4409] = {category="lo"}, +[4410] = {category="lo"}, +[4411] = {category="lo"}, +[4412] = {category="lo"}, +[4413] = {category="lo"}, +[4414] = {category="lo"}, +[4415] = {category="lo"}, +[4416] = {category="lo"}, +[4417] = {category="lo"}, +[4418] = {category="lo"}, +[4419] = {category="lo"}, +[4420] = {category="lo"}, +[4421] = {category="lo"}, +[4422] = {category="lo"}, +[4423] = {category="lo"}, +[4424] = {category="lo"}, +[4425] = {category="lo"}, +[4426] = {category="lo"}, +[4427] = {category="lo"}, +[4428] = {category="lo"}, +[4429] = {category="lo"}, +[4430] = {category="lo"}, +[4431] = {category="lo"}, +[4432] = {category="lo"}, +[4433] = {category="lo"}, +[4434] = {category="lo"}, +[4435] = {category="lo"}, +[4436] = {category="lo"}, +[4437] = {category="lo"}, +[4438] = {category="lo"}, +[4439] = {category="lo"}, +[4440] = {category="lo"}, +[4441] = {category="lo"}, +[4442] = {category="lo"}, +[4443] = {category="lo"}, +[4444] = {category="lo"}, +[4445] = {category="lo"}, +[4446] = {category="lo"}, +[4447] = {category="lo"}, +[4448] = {category="lo"}, +[4449] = {category="lo"}, +[4450] = {category="lo"}, +[4451] = {category="lo"}, +[4452] = {category="lo"}, +[4453] = {category="lo"}, +[4454] = {category="lo"}, +[4455] = {category="lo"}, +[4456] = {category="lo"}, +[4457] = {category="lo"}, +[4458] = {category="lo"}, +[4459] = {category="lo"}, +[4460] = {category="lo"}, +[4461] = {category="lo"}, +[4462] = {category="lo"}, +[4463] = {category="lo"}, +[4464] = {category="lo"}, +[4465] = {category="lo"}, +[4466] = {category="lo"}, +[4467] = {category="lo"}, +[4468] = {category="lo"}, +[4469] = {category="lo"}, +[4470] = {category="lo"}, +[4471] = {category="lo"}, +[4472] = {category="lo"}, +[4473] = {category="lo"}, +[4474] = {category="lo"}, +[4475] = {category="lo"}, +[4476] = {category="lo"}, +[4477] = {category="lo"}, +[4478] = {category="lo"}, +[4479] = {category="lo"}, +[4480] = {category="lo"}, +[4481] = {category="lo"}, +[4482] = {category="lo"}, +[4483] = {category="lo"}, +[4484] = {category="lo"}, +[4485] = {category="lo"}, +[4486] = {category="lo"}, +[4487] = {category="lo"}, +[4488] = {category="lo"}, +[4489] = {category="lo"}, +[4490] = {category="lo"}, +[4491] = {category="lo"}, +[4492] = {category="lo"}, +[4493] = {category="lo"}, +[4494] = {category="lo"}, +[4495] = {category="lo"}, +[4496] = {category="lo"}, +[4497] = {category="lo"}, +[4498] = {category="lo"}, +[4499] = {category="lo"}, +[4500] = {category="lo"}, +[4501] = {category="lo"}, +[4502] = {category="lo"}, +[4503] = {category="lo"}, +[4504] = {category="lo"}, +[4505] = {category="lo"}, +[4506] = {category="lo"}, +[4507] = {category="lo"}, +[4508] = {category="lo"}, +[4509] = {category="lo"}, +[4510] = {category="lo"}, +[4511] = {category="lo"}, +[4512] = {category="lo"}, +[4513] = {category="lo"}, +[4514] = {category="lo"}, +[4515] = {category="lo"}, +[4516] = {category="lo"}, +[4517] = {category="lo"}, +[4518] = {category="lo"}, +[4519] = {category="lo"}, +[4520] = {category="lo"}, +[4521] = {category="lo"}, +[4522] = {category="lo"}, +[4523] = {category="lo"}, +[4524] = {category="lo"}, +[4525] = {category="lo"}, +[4526] = {category="lo"}, +[4527] = {category="lo"}, +[4528] = {category="lo"}, +[4529] = {category="lo"}, +[4530] = {category="lo"}, +[4531] = {category="lo"}, +[4532] = {category="lo"}, +[4533] = {category="lo"}, +[4534] = {category="lo"}, +[4535] = {category="lo"}, +[4536] = {category="lo"}, +[4537] = {category="lo"}, +[4538] = {category="lo"}, +[4539] = {category="lo"}, +[4540] = {category="lo"}, +[4541] = {category="lo"}, +[4542] = {category="lo"}, +[4543] = {category="lo"}, +[4544] = {category="lo"}, +[4545] = {category="lo"}, +[4546] = {category="lo"}, +[4547] = {category="lo"}, +[4548] = {category="lo"}, +[4549] = {category="lo"}, +[4550] = {category="lo"}, +[4551] = {category="lo"}, +[4552] = {category="lo"}, +[4553] = {category="lo"}, +[4554] = {category="lo"}, +[4555] = {category="lo"}, +[4556] = {category="lo"}, +[4557] = {category="lo"}, +[4558] = {category="lo"}, +[4559] = {category="lo"}, +[4560] = {category="lo"}, +[4561] = {category="lo"}, +[4562] = {category="lo"}, +[4563] = {category="lo"}, +[4564] = {category="lo"}, +[4565] = {category="lo"}, +[4566] = {category="lo"}, +[4567] = {category="lo"}, +[4568] = {category="lo"}, +[4569] = {category="lo"}, +[4570] = {category="lo"}, +[4571] = {category="lo"}, +[4572] = {category="lo"}, +[4573] = {category="lo"}, +[4574] = {category="lo"}, +[4575] = {category="lo"}, +[4576] = {category="lo"}, +[4577] = {category="lo"}, +[4578] = {category="lo"}, +[4579] = {category="lo"}, +[4580] = {category="lo"}, +[4581] = {category="lo"}, +[4582] = {category="lo"}, +[4583] = {category="lo"}, +[4584] = {category="lo"}, +[4585] = {category="lo"}, +[4586] = {category="lo"}, +[4587] = {category="lo"}, +[4588] = {category="lo"}, +[4589] = {category="lo"}, +[4590] = {category="lo"}, +[4591] = {category="lo"}, +[4592] = {category="lo"}, +[4593] = {category="lo"}, +[4594] = {category="lo"}, +[4595] = {category="lo"}, +[4596] = {category="lo"}, +[4597] = {category="lo"}, +[4598] = {category="lo"}, +[4599] = {category="lo"}, +[4600] = {category="lo"}, +[4601] = {category="lo"}, +[4602] = {category="lo"}, +[4603] = {category="lo"}, +[4604] = {category="lo"}, +[4605] = {category="lo"}, +[4606] = {category="lo"}, +[4607] = {category="lo"}, +[4608] = {category="lo"}, +[4609] = {category="lo"}, +[4610] = {category="lo"}, +[4611] = {category="lo"}, +[4612] = {category="lo"}, +[4613] = {category="lo"}, +[4614] = {category="lo"}, +[4615] = {category="lo"}, +[4616] = {category="lo"}, +[4617] = {category="lo"}, +[4618] = {category="lo"}, +[4619] = {category="lo"}, +[4620] = {category="lo"}, +[4621] = {category="lo"}, +[4622] = {category="lo"}, +[4623] = {category="lo"}, +[4624] = {category="lo"}, +[4625] = {category="lo"}, +[4626] = {category="lo"}, +[4627] = {category="lo"}, +[4628] = {category="lo"}, +[4629] = {category="lo"}, +[4630] = {category="lo"}, +[4631] = {category="lo"}, +[4632] = {category="lo"}, +[4633] = {category="lo"}, +[4634] = {category="lo"}, +[4635] = {category="lo"}, +[4636] = {category="lo"}, +[4637] = {category="lo"}, +[4638] = {category="lo"}, +[4639] = {category="lo"}, +[4640] = {category="lo"}, +[4641] = {category="lo"}, +[4642] = {category="lo"}, +[4643] = {category="lo"}, +[4644] = {category="lo"}, +[4645] = {category="lo"}, +[4646] = {category="lo"}, +[4647] = {category="lo"}, +[4648] = {category="lo"}, +[4649] = {category="lo"}, +[4650] = {category="lo"}, +[4651] = {category="lo"}, +[4652] = {category="lo"}, +[4653] = {category="lo"}, +[4654] = {category="lo"}, +[4655] = {category="lo"}, +[4656] = {category="lo"}, +[4657] = {category="lo"}, +[4658] = {category="lo"}, +[4659] = {category="lo"}, +[4660] = {category="lo"}, +[4661] = {category="lo"}, +[4662] = {category="lo"}, +[4663] = {category="lo"}, +[4664] = {category="lo"}, +[4665] = {category="lo"}, +[4666] = {category="lo"}, +[4667] = {category="lo"}, +[4668] = {category="lo"}, +[4669] = {category="lo"}, +[4670] = {category="lo"}, +[4671] = {category="lo"}, +[4672] = {category="lo"}, +[4673] = {category="lo"}, +[4674] = {category="lo"}, +[4675] = {category="lo"}, +[4676] = {category="lo"}, +[4677] = {category="lo"}, +[4678] = {category="lo"}, +[4679] = {category="lo"}, +[4680] = {category="lo"}, +[4682] = {category="lo"}, +[4683] = {category="lo"}, +[4684] = {category="lo"}, +[4685] = {category="lo"}, +[4688] = {category="lo"}, +[4689] = {category="lo"}, +[4690] = {category="lo"}, +[4691] = {category="lo"}, +[4692] = {category="lo"}, +[4693] = {category="lo"}, +[4694] = {category="lo"}, +[4696] = {category="lo"}, +[4698] = {category="lo"}, +[4699] = {category="lo"}, +[4700] = {category="lo"}, +[4701] = {category="lo"}, +[4704] = {category="lo"}, +[4705] = {category="lo"}, +[4706] = {category="lo"}, +[4707] = {category="lo"}, +[4708] = {category="lo"}, +[4709] = {category="lo"}, +[4710] = {category="lo"}, +[4711] = {category="lo"}, +[4712] = {category="lo"}, +[4713] = {category="lo"}, +[4714] = {category="lo"}, +[4715] = {category="lo"}, +[4716] = {category="lo"}, +[4717] = {category="lo"}, +[4718] = {category="lo"}, +[4719] = {category="lo"}, +[4720] = {category="lo"}, +[4721] = {category="lo"}, +[4722] = {category="lo"}, +[4723] = {category="lo"}, +[4724] = {category="lo"}, +[4725] = {category="lo"}, +[4726] = {category="lo"}, +[4727] = {category="lo"}, +[4728] = {category="lo"}, +[4729] = {category="lo"}, +[4730] = {category="lo"}, +[4731] = {category="lo"}, +[4732] = {category="lo"}, +[4733] = {category="lo"}, +[4734] = {category="lo"}, +[4735] = {category="lo"}, +[4736] = {category="lo"}, +[4737] = {category="lo"}, +[4738] = {category="lo"}, +[4739] = {category="lo"}, +[4740] = {category="lo"}, +[4741] = {category="lo"}, +[4742] = {category="lo"}, +[4743] = {category="lo"}, +[4744] = {category="lo"}, +[4746] = {category="lo"}, +[4747] = {category="lo"}, +[4748] = {category="lo"}, +[4749] = {category="lo"}, +[4752] = {category="lo"}, +[4753] = {category="lo"}, +[4754] = {category="lo"}, +[4755] = {category="lo"}, +[4756] = {category="lo"}, +[4757] = {category="lo"}, +[4758] = {category="lo"}, +[4759] = {category="lo"}, +[4760] = {category="lo"}, +[4761] = {category="lo"}, +[4762] = {category="lo"}, +[4763] = {category="lo"}, +[4764] = {category="lo"}, +[4765] = {category="lo"}, +[4766] = {category="lo"}, +[4767] = {category="lo"}, +[4768] = {category="lo"}, +[4769] = {category="lo"}, +[4770] = {category="lo"}, +[4771] = {category="lo"}, +[4772] = {category="lo"}, +[4773] = {category="lo"}, +[4774] = {category="lo"}, +[4775] = {category="lo"}, +[4776] = {category="lo"}, +[4777] = {category="lo"}, +[4778] = {category="lo"}, +[4779] = {category="lo"}, +[4780] = {category="lo"}, +[4781] = {category="lo"}, +[4782] = {category="lo"}, +[4783] = {category="lo"}, +[4784] = {category="lo"}, +[4786] = {category="lo"}, +[4787] = {category="lo"}, +[4788] = {category="lo"}, +[4789] = {category="lo"}, +[4792] = {category="lo"}, +[4793] = {category="lo"}, +[4794] = {category="lo"}, +[4795] = {category="lo"}, +[4796] = {category="lo"}, +[4797] = {category="lo"}, +[4798] = {category="lo"}, +[4800] = {category="lo"}, +[4802] = {category="lo"}, +[4803] = {category="lo"}, +[4804] = {category="lo"}, +[4805] = {category="lo"}, +[4808] = {category="lo"}, +[4809] = {category="lo"}, +[4810] = {category="lo"}, +[4811] = {category="lo"}, +[4812] = {category="lo"}, +[4813] = {category="lo"}, +[4814] = {category="lo"}, +[4815] = {category="lo"}, +[4816] = {category="lo"}, +[4817] = {category="lo"}, +[4818] = {category="lo"}, +[4819] = {category="lo"}, +[4820] = {category="lo"}, +[4821] = {category="lo"}, +[4822] = {category="lo"}, +[4824] = {category="lo"}, +[4825] = {category="lo"}, +[4826] = {category="lo"}, +[4827] = {category="lo"}, +[4828] = {category="lo"}, +[4829] = {category="lo"}, +[4830] = {category="lo"}, +[4831] = {category="lo"}, +[4832] = {category="lo"}, +[4833] = {category="lo"}, +[4834] = {category="lo"}, +[4835] = {category="lo"}, +[4836] = {category="lo"}, +[4837] = {category="lo"}, +[4838] = {category="lo"}, +[4839] = {category="lo"}, +[4840] = {category="lo"}, +[4841] = {category="lo"}, +[4842] = {category="lo"}, +[4843] = {category="lo"}, +[4844] = {category="lo"}, +[4845] = {category="lo"}, +[4846] = {category="lo"}, +[4847] = {category="lo"}, +[4848] = {category="lo"}, +[4849] = {category="lo"}, +[4850] = {category="lo"}, +[4851] = {category="lo"}, +[4852] = {category="lo"}, +[4853] = {category="lo"}, +[4854] = {category="lo"}, +[4855] = {category="lo"}, +[4856] = {category="lo"}, +[4857] = {category="lo"}, +[4858] = {category="lo"}, +[4859] = {category="lo"}, +[4860] = {category="lo"}, +[4861] = {category="lo"}, +[4862] = {category="lo"}, +[4863] = {category="lo"}, +[4864] = {category="lo"}, +[4865] = {category="lo"}, +[4866] = {category="lo"}, +[4867] = {category="lo"}, +[4868] = {category="lo"}, +[4869] = {category="lo"}, +[4870] = {category="lo"}, +[4871] = {category="lo"}, +[4872] = {category="lo"}, +[4873] = {category="lo"}, +[4874] = {category="lo"}, +[4875] = {category="lo"}, +[4876] = {category="lo"}, +[4877] = {category="lo"}, +[4878] = {category="lo"}, +[4879] = {category="lo"}, +[4880] = {category="lo"}, +[4882] = {category="lo"}, +[4883] = {category="lo"}, +[4884] = {category="lo"}, +[4885] = {category="lo"}, +[4888] = {category="lo"}, +[4889] = {category="lo"}, +[4890] = {category="lo"}, +[4891] = {category="lo"}, +[4892] = {category="lo"}, +[4893] = {category="lo"}, +[4894] = {category="lo"}, +[4895] = {category="lo"}, +[4896] = {category="lo"}, +[4897] = {category="lo"}, +[4898] = {category="lo"}, +[4899] = {category="lo"}, +[4900] = {category="lo"}, +[4901] = {category="lo"}, +[4902] = {category="lo"}, +[4903] = {category="lo"}, +[4904] = {category="lo"}, +[4905] = {category="lo"}, +[4906] = {category="lo"}, +[4907] = {category="lo"}, +[4908] = {category="lo"}, +[4909] = {category="lo"}, +[4910] = {category="lo"}, +[4911] = {category="lo"}, +[4912] = {category="lo"}, +[4913] = {category="lo"}, +[4914] = {category="lo"}, +[4915] = {category="lo"}, +[4916] = {category="lo"}, +[4917] = {category="lo"}, +[4918] = {category="lo"}, +[4919] = {category="lo"}, +[4920] = {category="lo"}, +[4921] = {category="lo"}, +[4922] = {category="lo"}, +[4923] = {category="lo"}, +[4924] = {category="lo"}, +[4925] = {category="lo"}, +[4926] = {category="lo"}, +[4927] = {category="lo"}, +[4928] = {category="lo"}, +[4929] = {category="lo"}, +[4930] = {category="lo"}, +[4931] = {category="lo"}, +[4932] = {category="lo"}, +[4933] = {category="lo"}, +[4934] = {category="lo"}, +[4935] = {category="lo"}, +[4936] = {category="lo"}, +[4937] = {category="lo"}, +[4938] = {category="lo"}, +[4939] = {category="lo"}, +[4940] = {category="lo"}, +[4941] = {category="lo"}, +[4942] = {category="lo"}, +[4943] = {category="lo"}, +[4944] = {category="lo"}, +[4945] = {category="lo"}, +[4946] = {category="lo"}, +[4947] = {category="lo"}, +[4948] = {category="lo"}, +[4949] = {category="lo"}, +[4950] = {category="lo"}, +[4951] = {category="lo"}, +[4952] = {category="lo"}, +[4953] = {category="lo"}, +[4954] = {category="lo"}, +[4992] = {category="lo"}, +[4993] = {category="lo"}, +[4994] = {category="lo"}, +[4995] = {category="lo"}, +[4996] = {category="lo"}, +[4997] = {category="lo"}, +[4998] = {category="lo"}, +[4999] = {category="lo"}, +[5000] = {category="lo"}, +[5001] = {category="lo"}, +[5002] = {category="lo"}, +[5003] = {category="lo"}, +[5004] = {category="lo"}, +[5005] = {category="lo"}, +[5006] = {category="lo"}, +[5007] = {category="lo"}, +[5024] = {category="lu", lccode=43888}, +[5025] = {category="lu", lccode=43889}, +[5026] = {category="lu", lccode=43890}, +[5027] = {category="lu", lccode=43891}, +[5028] = {category="lu", lccode=43892}, +[5029] = {category="lu", lccode=43893}, +[5030] = {category="lu", lccode=43894}, +[5031] = {category="lu", lccode=43895}, +[5032] = {category="lu", lccode=43896}, +[5033] = {category="lu", lccode=43897}, +[5034] = {category="lu", lccode=43898}, +[5035] = {category="lu", lccode=43899}, +[5036] = {category="lu", lccode=43900}, +[5037] = {category="lu", lccode=43901}, +[5038] = {category="lu", lccode=43902}, +[5039] = {category="lu", lccode=43903}, +[5040] = {category="lu", lccode=43904}, +[5041] = {category="lu", lccode=43905}, +[5042] = {category="lu", lccode=43906}, +[5043] = {category="lu", lccode=43907}, +[5044] = {category="lu", lccode=43908}, +[5045] = {category="lu", lccode=43909}, +[5046] = {category="lu", lccode=43910}, +[5047] = {category="lu", lccode=43911}, +[5048] = {category="lu", lccode=43912}, +[5049] = {category="lu", lccode=43913}, +[5050] = {category="lu", lccode=43914}, +[5051] = {category="lu", lccode=43915}, +[5052] = {category="lu", lccode=43916}, +[5053] = {category="lu", lccode=43917}, +[5054] = {category="lu", lccode=43918}, +[5055] = {category="lu", lccode=43919}, +[5056] = {category="lu", lccode=43920}, +[5057] = {category="lu", lccode=43921}, +[5058] = {category="lu", lccode=43922}, +[5059] = {category="lu", lccode=43923}, +[5060] = {category="lu", lccode=43924}, +[5061] = {category="lu", lccode=43925}, +[5062] = {category="lu", lccode=43926}, +[5063] = {category="lu", lccode=43927}, +[5064] = {category="lu", lccode=43928}, +[5065] = {category="lu", lccode=43929}, +[5066] = {category="lu", lccode=43930}, +[5067] = {category="lu", lccode=43931}, +[5068] = {category="lu", lccode=43932}, +[5069] = {category="lu", lccode=43933}, +[5070] = {category="lu", lccode=43934}, +[5071] = {category="lu", lccode=43935}, +[5072] = {category="lu", lccode=43936}, +[5073] = {category="lu", lccode=43937}, +[5074] = {category="lu", lccode=43938}, +[5075] = {category="lu", lccode=43939}, +[5076] = {category="lu", lccode=43940}, +[5077] = {category="lu", lccode=43941}, +[5078] = {category="lu", lccode=43942}, +[5079] = {category="lu", lccode=43943}, +[5080] = {category="lu", lccode=43944}, +[5081] = {category="lu", lccode=43945}, +[5082] = {category="lu", lccode=43946}, +[5083] = {category="lu", lccode=43947}, +[5084] = {category="lu", lccode=43948}, +[5085] = {category="lu", lccode=43949}, +[5086] = {category="lu", lccode=43950}, +[5087] = {category="lu", lccode=43951}, +[5088] = {category="lu", lccode=43952}, +[5089] = {category="lu", lccode=43953}, +[5090] = {category="lu", lccode=43954}, +[5091] = {category="lu", lccode=43955}, +[5092] = {category="lu", lccode=43956}, +[5093] = {category="lu", lccode=43957}, +[5094] = {category="lu", lccode=43958}, +[5095] = {category="lu", lccode=43959}, +[5096] = {category="lu", lccode=43960}, +[5097] = {category="lu", lccode=43961}, +[5098] = {category="lu", lccode=43962}, +[5099] = {category="lu", lccode=43963}, +[5100] = {category="lu", lccode=43964}, +[5101] = {category="lu", lccode=43965}, +[5102] = {category="lu", lccode=43966}, +[5103] = {category="lu", lccode=43967}, +[5104] = {category="lu", lccode=5112}, +[5105] = {category="lu", lccode=5113}, +[5106] = {category="lu", lccode=5114}, +[5107] = {category="lu", lccode=5115}, +[5108] = {category="lu", lccode=5116}, +[5109] = {category="lu", lccode=5117}, +[5112] = {category="ll"}, +[5113] = {category="ll"}, +[5114] = {category="ll"}, +[5115] = {category="ll"}, +[5116] = {category="ll"}, +[5117] = {category="ll"}, +[5121] = {category="lo"}, +[5122] = {category="lo"}, +[5123] = {category="lo"}, +[5124] = {category="lo"}, +[5125] = {category="lo"}, +[5126] = {category="lo"}, +[5127] = {category="lo"}, +[5128] = {category="lo"}, +[5129] = {category="lo"}, +[5130] = {category="lo"}, +[5131] = {category="lo"}, +[5132] = {category="lo"}, +[5133] = {category="lo"}, +[5134] = {category="lo"}, +[5135] = {category="lo"}, +[5136] = {category="lo"}, +[5137] = {category="lo"}, +[5138] = {category="lo"}, +[5139] = {category="lo"}, +[5140] = {category="lo"}, +[5141] = {category="lo"}, +[5142] = {category="lo"}, +[5143] = {category="lo"}, +[5144] = {category="lo"}, +[5145] = {category="lo"}, +[5146] = {category="lo"}, +[5147] = {category="lo"}, +[5148] = {category="lo"}, +[5149] = {category="lo"}, +[5150] = {category="lo"}, +[5151] = {category="lo"}, +[5152] = {category="lo"}, +[5153] = {category="lo"}, +[5154] = {category="lo"}, +[5155] = {category="lo"}, +[5156] = {category="lo"}, +[5157] = {category="lo"}, +[5158] = {category="lo"}, +[5159] = {category="lo"}, +[5160] = {category="lo"}, +[5161] = {category="lo"}, +[5162] = {category="lo"}, +[5163] = {category="lo"}, +[5164] = {category="lo"}, +[5165] = {category="lo"}, +[5166] = {category="lo"}, +[5167] = {category="lo"}, +[5168] = {category="lo"}, +[5169] = {category="lo"}, +[5170] = {category="lo"}, +[5171] = {category="lo"}, +[5172] = {category="lo"}, +[5173] = {category="lo"}, +[5174] = {category="lo"}, +[5175] = {category="lo"}, +[5176] = {category="lo"}, +[5177] = {category="lo"}, +[5178] = {category="lo"}, +[5179] = {category="lo"}, +[5180] = {category="lo"}, +[5181] = {category="lo"}, +[5182] = {category="lo"}, +[5183] = {category="lo"}, +[5184] = {category="lo"}, +[5185] = {category="lo"}, +[5186] = {category="lo"}, +[5187] = {category="lo"}, +[5188] = {category="lo"}, +[5189] = {category="lo"}, +[5190] = {category="lo"}, +[5191] = {category="lo"}, +[5192] = {category="lo"}, +[5193] = {category="lo"}, +[5194] = {category="lo"}, +[5195] = {category="lo"}, +[5196] = {category="lo"}, +[5197] = {category="lo"}, +[5198] = {category="lo"}, +[5199] = {category="lo"}, +[5200] = {category="lo"}, +[5201] = {category="lo"}, +[5202] = {category="lo"}, +[5203] = {category="lo"}, +[5204] = {category="lo"}, +[5205] = {category="lo"}, +[5206] = {category="lo"}, +[5207] = {category="lo"}, +[5208] = {category="lo"}, +[5209] = {category="lo"}, +[5210] = {category="lo"}, +[5211] = {category="lo"}, +[5212] = {category="lo"}, +[5213] = {category="lo"}, +[5214] = {category="lo"}, +[5215] = {category="lo"}, +[5216] = {category="lo"}, +[5217] = {category="lo"}, +[5218] = {category="lo"}, +[5219] = {category="lo"}, +[5220] = {category="lo"}, +[5221] = {category="lo"}, +[5222] = {category="lo"}, +[5223] = {category="lo"}, +[5224] = {category="lo"}, +[5225] = {category="lo"}, +[5226] = {category="lo"}, +[5227] = {category="lo"}, +[5228] = {category="lo"}, +[5229] = {category="lo"}, +[5230] = {category="lo"}, +[5231] = {category="lo"}, +[5232] = {category="lo"}, +[5233] = {category="lo"}, +[5234] = {category="lo"}, +[5235] = {category="lo"}, +[5236] = {category="lo"}, +[5237] = {category="lo"}, +[5238] = {category="lo"}, +[5239] = {category="lo"}, +[5240] = {category="lo"}, +[5241] = {category="lo"}, +[5242] = {category="lo"}, +[5243] = {category="lo"}, +[5244] = {category="lo"}, +[5245] = {category="lo"}, +[5246] = {category="lo"}, +[5247] = {category="lo"}, +[5248] = {category="lo"}, +[5249] = {category="lo"}, +[5250] = {category="lo"}, +[5251] = {category="lo"}, +[5252] = {category="lo"}, +[5253] = {category="lo"}, +[5254] = {category="lo"}, +[5255] = {category="lo"}, +[5256] = {category="lo"}, +[5257] = {category="lo"}, +[5258] = {category="lo"}, +[5259] = {category="lo"}, +[5260] = {category="lo"}, +[5261] = {category="lo"}, +[5262] = {category="lo"}, +[5263] = {category="lo"}, +[5264] = {category="lo"}, +[5265] = {category="lo"}, +[5266] = {category="lo"}, +[5267] = {category="lo"}, +[5268] = {category="lo"}, +[5269] = {category="lo"}, +[5270] = {category="lo"}, +[5271] = {category="lo"}, +[5272] = {category="lo"}, +[5273] = {category="lo"}, +[5274] = {category="lo"}, +[5275] = {category="lo"}, +[5276] = {category="lo"}, +[5277] = {category="lo"}, +[5278] = {category="lo"}, +[5279] = {category="lo"}, +[5280] = {category="lo"}, +[5281] = {category="lo"}, +[5282] = {category="lo"}, +[5283] = {category="lo"}, +[5284] = {category="lo"}, +[5285] = {category="lo"}, +[5286] = {category="lo"}, +[5287] = {category="lo"}, +[5288] = {category="lo"}, +[5289] = {category="lo"}, +[5290] = {category="lo"}, +[5291] = {category="lo"}, +[5292] = {category="lo"}, +[5293] = {category="lo"}, +[5294] = {category="lo"}, +[5295] = {category="lo"}, +[5296] = {category="lo"}, +[5297] = {category="lo"}, +[5298] = {category="lo"}, +[5299] = {category="lo"}, +[5300] = {category="lo"}, +[5301] = {category="lo"}, +[5302] = {category="lo"}, +[5303] = {category="lo"}, +[5304] = {category="lo"}, +[5305] = {category="lo"}, +[5306] = {category="lo"}, +[5307] = {category="lo"}, +[5308] = {category="lo"}, +[5309] = {category="lo"}, +[5310] = {category="lo"}, +[5311] = {category="lo"}, +[5312] = {category="lo"}, +[5313] = {category="lo"}, +[5314] = {category="lo"}, +[5315] = {category="lo"}, +[5316] = {category="lo"}, +[5317] = {category="lo"}, +[5318] = {category="lo"}, +[5319] = {category="lo"}, +[5320] = {category="lo"}, +[5321] = {category="lo"}, +[5322] = {category="lo"}, +[5323] = {category="lo"}, +[5324] = {category="lo"}, +[5325] = {category="lo"}, +[5326] = {category="lo"}, +[5327] = {category="lo"}, +[5328] = {category="lo"}, +[5329] = {category="lo"}, +[5330] = {category="lo"}, +[5331] = {category="lo"}, +[5332] = {category="lo"}, +[5333] = {category="lo"}, +[5334] = {category="lo"}, +[5335] = {category="lo"}, +[5336] = {category="lo"}, +[5337] = {category="lo"}, +[5338] = {category="lo"}, +[5339] = {category="lo"}, +[5340] = {category="lo"}, +[5341] = {category="lo"}, +[5342] = {category="lo"}, +[5343] = {category="lo"}, +[5344] = {category="lo"}, +[5345] = {category="lo"}, +[5346] = {category="lo"}, +[5347] = {category="lo"}, +[5348] = {category="lo"}, +[5349] = {category="lo"}, +[5350] = {category="lo"}, +[5351] = {category="lo"}, +[5352] = {category="lo"}, +[5353] = {category="lo"}, +[5354] = {category="lo"}, +[5355] = {category="lo"}, +[5356] = {category="lo"}, +[5357] = {category="lo"}, +[5358] = {category="lo"}, +[5359] = {category="lo"}, +[5360] = {category="lo"}, +[5361] = {category="lo"}, +[5362] = {category="lo"}, +[5363] = {category="lo"}, +[5364] = {category="lo"}, +[5365] = {category="lo"}, +[5366] = {category="lo"}, +[5367] = {category="lo"}, +[5368] = {category="lo"}, +[5369] = {category="lo"}, +[5370] = {category="lo"}, +[5371] = {category="lo"}, +[5372] = {category="lo"}, +[5373] = {category="lo"}, +[5374] = {category="lo"}, +[5375] = {category="lo"}, +[5376] = {category="lo"}, +[5377] = {category="lo"}, +[5378] = {category="lo"}, +[5379] = {category="lo"}, +[5380] = {category="lo"}, +[5381] = {category="lo"}, +[5382] = {category="lo"}, +[5383] = {category="lo"}, +[5384] = {category="lo"}, +[5385] = {category="lo"}, +[5386] = {category="lo"}, +[5387] = {category="lo"}, +[5388] = {category="lo"}, +[5389] = {category="lo"}, +[5390] = {category="lo"}, +[5391] = {category="lo"}, +[5392] = {category="lo"}, +[5393] = {category="lo"}, +[5394] = {category="lo"}, +[5395] = {category="lo"}, +[5396] = {category="lo"}, +[5397] = {category="lo"}, +[5398] = {category="lo"}, +[5399] = {category="lo"}, +[5400] = {category="lo"}, +[5401] = {category="lo"}, +[5402] = {category="lo"}, +[5403] = {category="lo"}, +[5404] = {category="lo"}, +[5405] = {category="lo"}, +[5406] = {category="lo"}, +[5407] = {category="lo"}, +[5408] = {category="lo"}, +[5409] = {category="lo"}, +[5410] = {category="lo"}, +[5411] = {category="lo"}, +[5412] = {category="lo"}, +[5413] = {category="lo"}, +[5414] = {category="lo"}, +[5415] = {category="lo"}, +[5416] = {category="lo"}, +[5417] = {category="lo"}, +[5418] = {category="lo"}, +[5419] = {category="lo"}, +[5420] = {category="lo"}, +[5421] = {category="lo"}, +[5422] = {category="lo"}, +[5423] = {category="lo"}, +[5424] = {category="lo"}, +[5425] = {category="lo"}, +[5426] = {category="lo"}, +[5427] = {category="lo"}, +[5428] = {category="lo"}, +[5429] = {category="lo"}, +[5430] = {category="lo"}, +[5431] = {category="lo"}, +[5432] = {category="lo"}, +[5433] = {category="lo"}, +[5434] = {category="lo"}, +[5435] = {category="lo"}, +[5436] = {category="lo"}, +[5437] = {category="lo"}, +[5438] = {category="lo"}, +[5439] = {category="lo"}, +[5440] = {category="lo"}, +[5441] = {category="lo"}, +[5442] = {category="lo"}, +[5443] = {category="lo"}, +[5444] = {category="lo"}, +[5445] = {category="lo"}, +[5446] = {category="lo"}, +[5447] = {category="lo"}, +[5448] = {category="lo"}, +[5449] = {category="lo"}, +[5450] = {category="lo"}, +[5451] = {category="lo"}, +[5452] = {category="lo"}, +[5453] = {category="lo"}, +[5454] = {category="lo"}, +[5455] = {category="lo"}, +[5456] = {category="lo"}, +[5457] = {category="lo"}, +[5458] = {category="lo"}, +[5459] = {category="lo"}, +[5460] = {category="lo"}, +[5461] = {category="lo"}, +[5462] = {category="lo"}, +[5463] = {category="lo"}, +[5464] = {category="lo"}, +[5465] = {category="lo"}, +[5466] = {category="lo"}, +[5467] = {category="lo"}, +[5468] = {category="lo"}, +[5469] = {category="lo"}, +[5470] = {category="lo"}, +[5471] = {category="lo"}, +[5472] = {category="lo"}, +[5473] = {category="lo"}, +[5474] = {category="lo"}, +[5475] = {category="lo"}, +[5476] = {category="lo"}, +[5477] = {category="lo"}, +[5478] = {category="lo"}, +[5479] = {category="lo"}, +[5480] = {category="lo"}, +[5481] = {category="lo"}, +[5482] = {category="lo"}, +[5483] = {category="lo"}, +[5484] = {category="lo"}, +[5485] = {category="lo"}, +[5486] = {category="lo"}, +[5487] = {category="lo"}, +[5488] = {category="lo"}, +[5489] = {category="lo"}, +[5490] = {category="lo"}, +[5491] = {category="lo"}, +[5492] = {category="lo"}, +[5493] = {category="lo"}, +[5494] = {category="lo"}, +[5495] = {category="lo"}, +[5496] = {category="lo"}, +[5497] = {category="lo"}, +[5498] = {category="lo"}, +[5499] = {category="lo"}, +[5500] = {category="lo"}, +[5501] = {category="lo"}, +[5502] = {category="lo"}, +[5503] = {category="lo"}, +[5504] = {category="lo"}, +[5505] = {category="lo"}, +[5506] = {category="lo"}, +[5507] = {category="lo"}, +[5508] = {category="lo"}, +[5509] = {category="lo"}, +[5510] = {category="lo"}, +[5511] = {category="lo"}, +[5512] = {category="lo"}, +[5513] = {category="lo"}, +[5514] = {category="lo"}, +[5515] = {category="lo"}, +[5516] = {category="lo"}, +[5517] = {category="lo"}, +[5518] = {category="lo"}, +[5519] = {category="lo"}, +[5520] = {category="lo"}, +[5521] = {category="lo"}, +[5522] = {category="lo"}, +[5523] = {category="lo"}, +[5524] = {category="lo"}, +[5525] = {category="lo"}, +[5526] = {category="lo"}, +[5527] = {category="lo"}, +[5528] = {category="lo"}, +[5529] = {category="lo"}, +[5530] = {category="lo"}, +[5531] = {category="lo"}, +[5532] = {category="lo"}, +[5533] = {category="lo"}, +[5534] = {category="lo"}, +[5535] = {category="lo"}, +[5536] = {category="lo"}, +[5537] = {category="lo"}, +[5538] = {category="lo"}, +[5539] = {category="lo"}, +[5540] = {category="lo"}, +[5541] = {category="lo"}, +[5542] = {category="lo"}, +[5543] = {category="lo"}, +[5544] = {category="lo"}, +[5545] = {category="lo"}, +[5546] = {category="lo"}, +[5547] = {category="lo"}, +[5548] = {category="lo"}, +[5549] = {category="lo"}, +[5550] = {category="lo"}, +[5551] = {category="lo"}, +[5552] = {category="lo"}, +[5553] = {category="lo"}, +[5554] = {category="lo"}, +[5555] = {category="lo"}, +[5556] = {category="lo"}, +[5557] = {category="lo"}, +[5558] = {category="lo"}, +[5559] = {category="lo"}, +[5560] = {category="lo"}, +[5561] = {category="lo"}, +[5562] = {category="lo"}, +[5563] = {category="lo"}, +[5564] = {category="lo"}, +[5565] = {category="lo"}, +[5566] = {category="lo"}, +[5567] = {category="lo"}, +[5568] = {category="lo"}, +[5569] = {category="lo"}, +[5570] = {category="lo"}, +[5571] = {category="lo"}, +[5572] = {category="lo"}, +[5573] = {category="lo"}, +[5574] = {category="lo"}, +[5575] = {category="lo"}, +[5576] = {category="lo"}, +[5577] = {category="lo"}, +[5578] = {category="lo"}, +[5579] = {category="lo"}, +[5580] = {category="lo"}, +[5581] = {category="lo"}, +[5582] = {category="lo"}, +[5583] = {category="lo"}, +[5584] = {category="lo"}, +[5585] = {category="lo"}, +[5586] = {category="lo"}, +[5587] = {category="lo"}, +[5588] = {category="lo"}, +[5589] = {category="lo"}, +[5590] = {category="lo"}, +[5591] = {category="lo"}, +[5592] = {category="lo"}, +[5593] = {category="lo"}, +[5594] = {category="lo"}, +[5595] = {category="lo"}, +[5596] = {category="lo"}, +[5597] = {category="lo"}, +[5598] = {category="lo"}, +[5599] = {category="lo"}, +[5600] = {category="lo"}, +[5601] = {category="lo"}, +[5602] = {category="lo"}, +[5603] = {category="lo"}, +[5604] = {category="lo"}, +[5605] = {category="lo"}, +[5606] = {category="lo"}, +[5607] = {category="lo"}, +[5608] = {category="lo"}, +[5609] = {category="lo"}, +[5610] = {category="lo"}, +[5611] = {category="lo"}, +[5612] = {category="lo"}, +[5613] = {category="lo"}, +[5614] = {category="lo"}, +[5615] = {category="lo"}, +[5616] = {category="lo"}, +[5617] = {category="lo"}, +[5618] = {category="lo"}, +[5619] = {category="lo"}, +[5620] = {category="lo"}, +[5621] = {category="lo"}, +[5622] = {category="lo"}, +[5623] = {category="lo"}, +[5624] = {category="lo"}, +[5625] = {category="lo"}, +[5626] = {category="lo"}, +[5627] = {category="lo"}, +[5628] = {category="lo"}, +[5629] = {category="lo"}, +[5630] = {category="lo"}, +[5631] = {category="lo"}, +[5632] = {category="lo"}, +[5633] = {category="lo"}, +[5634] = {category="lo"}, +[5635] = {category="lo"}, +[5636] = {category="lo"}, +[5637] = {category="lo"}, +[5638] = {category="lo"}, +[5639] = {category="lo"}, +[5640] = {category="lo"}, +[5641] = {category="lo"}, +[5642] = {category="lo"}, +[5643] = {category="lo"}, +[5644] = {category="lo"}, +[5645] = {category="lo"}, +[5646] = {category="lo"}, +[5647] = {category="lo"}, +[5648] = {category="lo"}, +[5649] = {category="lo"}, +[5650] = {category="lo"}, +[5651] = {category="lo"}, +[5652] = {category="lo"}, +[5653] = {category="lo"}, +[5654] = {category="lo"}, +[5655] = {category="lo"}, +[5656] = {category="lo"}, +[5657] = {category="lo"}, +[5658] = {category="lo"}, +[5659] = {category="lo"}, +[5660] = {category="lo"}, +[5661] = {category="lo"}, +[5662] = {category="lo"}, +[5663] = {category="lo"}, +[5664] = {category="lo"}, +[5665] = {category="lo"}, +[5666] = {category="lo"}, +[5667] = {category="lo"}, +[5668] = {category="lo"}, +[5669] = {category="lo"}, +[5670] = {category="lo"}, +[5671] = {category="lo"}, +[5672] = {category="lo"}, +[5673] = {category="lo"}, +[5674] = {category="lo"}, +[5675] = {category="lo"}, +[5676] = {category="lo"}, +[5677] = {category="lo"}, +[5678] = {category="lo"}, +[5679] = {category="lo"}, +[5680] = {category="lo"}, +[5681] = {category="lo"}, +[5682] = {category="lo"}, +[5683] = {category="lo"}, +[5684] = {category="lo"}, +[5685] = {category="lo"}, +[5686] = {category="lo"}, +[5687] = {category="lo"}, +[5688] = {category="lo"}, +[5689] = {category="lo"}, +[5690] = {category="lo"}, +[5691] = {category="lo"}, +[5692] = {category="lo"}, +[5693] = {category="lo"}, +[5694] = {category="lo"}, +[5695] = {category="lo"}, +[5696] = {category="lo"}, +[5697] = {category="lo"}, +[5698] = {category="lo"}, +[5699] = {category="lo"}, +[5700] = {category="lo"}, +[5701] = {category="lo"}, +[5702] = {category="lo"}, +[5703] = {category="lo"}, +[5704] = {category="lo"}, +[5705] = {category="lo"}, +[5706] = {category="lo"}, +[5707] = {category="lo"}, +[5708] = {category="lo"}, +[5709] = {category="lo"}, +[5710] = {category="lo"}, +[5711] = {category="lo"}, +[5712] = {category="lo"}, +[5713] = {category="lo"}, +[5714] = {category="lo"}, +[5715] = {category="lo"}, +[5716] = {category="lo"}, +[5717] = {category="lo"}, +[5718] = {category="lo"}, +[5719] = {category="lo"}, +[5720] = {category="lo"}, +[5721] = {category="lo"}, +[5722] = {category="lo"}, +[5723] = {category="lo"}, +[5724] = {category="lo"}, +[5725] = {category="lo"}, +[5726] = {category="lo"}, +[5727] = {category="lo"}, +[5728] = {category="lo"}, +[5729] = {category="lo"}, +[5730] = {category="lo"}, +[5731] = {category="lo"}, +[5732] = {category="lo"}, +[5733] = {category="lo"}, +[5734] = {category="lo"}, +[5735] = {category="lo"}, +[5736] = {category="lo"}, +[5737] = {category="lo"}, +[5738] = {category="lo"}, +[5739] = {category="lo"}, +[5740] = {category="lo"}, +[5743] = {category="lo"}, +[5744] = {category="lo"}, +[5745] = {category="lo"}, +[5746] = {category="lo"}, +[5747] = {category="lo"}, +[5748] = {category="lo"}, +[5749] = {category="lo"}, +[5750] = {category="lo"}, +[5751] = {category="lo"}, +[5752] = {category="lo"}, +[5753] = {category="lo"}, +[5754] = {category="lo"}, +[5755] = {category="lo"}, +[5756] = {category="lo"}, +[5757] = {category="lo"}, +[5758] = {category="lo"}, +[5759] = {category="lo"}, +[5760] = {category="zs"}, +[5761] = {category="lo"}, +[5762] = {category="lo"}, +[5763] = {category="lo"}, +[5764] = {category="lo"}, +[5765] = {category="lo"}, +[5766] = {category="lo"}, +[5767] = {category="lo"}, +[5768] = {category="lo"}, +[5769] = {category="lo"}, +[5770] = {category="lo"}, +[5771] = {category="lo"}, +[5772] = {category="lo"}, +[5773] = {category="lo"}, +[5774] = {category="lo"}, +[5775] = {category="lo"}, +[5776] = {category="lo"}, +[5777] = {category="lo"}, +[5778] = {category="lo"}, +[5779] = {category="lo"}, +[5780] = {category="lo"}, +[5781] = {category="lo"}, +[5782] = {category="lo"}, +[5783] = {category="lo"}, +[5784] = {category="lo"}, +[5785] = {category="lo"}, +[5786] = {category="lo"}, +[5792] = {category="lo"}, +[5793] = {category="lo"}, +[5794] = {category="lo"}, +[5795] = {category="lo"}, +[5796] = {category="lo"}, +[5797] = {category="lo"}, +[5798] = {category="lo"}, +[5799] = {category="lo"}, +[5800] = {category="lo"}, +[5801] = {category="lo"}, +[5802] = {category="lo"}, +[5803] = {category="lo"}, +[5804] = {category="lo"}, +[5805] = {category="lo"}, +[5806] = {category="lo"}, +[5807] = {category="lo"}, +[5808] = {category="lo"}, +[5809] = {category="lo"}, +[5810] = {category="lo"}, +[5811] = {category="lo"}, +[5812] = {category="lo"}, +[5813] = {category="lo"}, +[5814] = {category="lo"}, +[5815] = {category="lo"}, +[5816] = {category="lo"}, +[5817] = {category="lo"}, +[5818] = {category="lo"}, +[5819] = {category="lo"}, +[5820] = {category="lo"}, +[5821] = {category="lo"}, +[5822] = {category="lo"}, +[5823] = {category="lo"}, +[5824] = {category="lo"}, +[5825] = {category="lo"}, +[5826] = {category="lo"}, +[5827] = {category="lo"}, +[5828] = {category="lo"}, +[5829] = {category="lo"}, +[5830] = {category="lo"}, +[5831] = {category="lo"}, +[5832] = {category="lo"}, +[5833] = {category="lo"}, +[5834] = {category="lo"}, +[5835] = {category="lo"}, +[5836] = {category="lo"}, +[5837] = {category="lo"}, +[5838] = {category="lo"}, +[5839] = {category="lo"}, +[5840] = {category="lo"}, +[5841] = {category="lo"}, +[5842] = {category="lo"}, +[5843] = {category="lo"}, +[5844] = {category="lo"}, +[5845] = {category="lo"}, +[5846] = {category="lo"}, +[5847] = {category="lo"}, +[5848] = {category="lo"}, +[5849] = {category="lo"}, +[5850] = {category="lo"}, +[5851] = {category="lo"}, +[5852] = {category="lo"}, +[5853] = {category="lo"}, +[5854] = {category="lo"}, +[5855] = {category="lo"}, +[5856] = {category="lo"}, +[5857] = {category="lo"}, +[5858] = {category="lo"}, +[5859] = {category="lo"}, +[5860] = {category="lo"}, +[5861] = {category="lo"}, +[5862] = {category="lo"}, +[5863] = {category="lo"}, +[5864] = {category="lo"}, +[5865] = {category="lo"}, +[5866] = {category="lo"}, +[5873] = {category="lo"}, +[5874] = {category="lo"}, +[5875] = {category="lo"}, +[5876] = {category="lo"}, +[5877] = {category="lo"}, +[5878] = {category="lo"}, +[5879] = {category="lo"}, +[5880] = {category="lo"}, +[5888] = {category="lo"}, +[5889] = {category="lo"}, +[5890] = {category="lo"}, +[5891] = {category="lo"}, +[5892] = {category="lo"}, +[5893] = {category="lo"}, +[5894] = {category="lo"}, +[5895] = {category="lo"}, +[5896] = {category="lo"}, +[5897] = {category="lo"}, +[5898] = {category="lo"}, +[5899] = {category="lo"}, +[5900] = {category="lo"}, +[5901] = {category="lo"}, +[5902] = {category="lo"}, +[5903] = {category="lo"}, +[5904] = {category="lo"}, +[5905] = {category="lo"}, +[5919] = {category="lo"}, +[5920] = {category="lo"}, +[5921] = {category="lo"}, +[5922] = {category="lo"}, +[5923] = {category="lo"}, +[5924] = {category="lo"}, +[5925] = {category="lo"}, +[5926] = {category="lo"}, +[5927] = {category="lo"}, +[5928] = {category="lo"}, +[5929] = {category="lo"}, +[5930] = {category="lo"}, +[5931] = {category="lo"}, +[5932] = {category="lo"}, +[5933] = {category="lo"}, +[5934] = {category="lo"}, +[5935] = {category="lo"}, +[5936] = {category="lo"}, +[5937] = {category="lo"}, +[5952] = {category="lo"}, +[5953] = {category="lo"}, +[5954] = {category="lo"}, +[5955] = {category="lo"}, +[5956] = {category="lo"}, +[5957] = {category="lo"}, +[5958] = {category="lo"}, +[5959] = {category="lo"}, +[5960] = {category="lo"}, +[5961] = {category="lo"}, +[5962] = {category="lo"}, +[5963] = {category="lo"}, +[5964] = {category="lo"}, +[5965] = {category="lo"}, +[5966] = {category="lo"}, +[5967] = {category="lo"}, +[5968] = {category="lo"}, +[5969] = {category="lo"}, +[5984] = {category="lo"}, +[5985] = {category="lo"}, +[5986] = {category="lo"}, +[5987] = {category="lo"}, +[5988] = {category="lo"}, +[5989] = {category="lo"}, +[5990] = {category="lo"}, +[5991] = {category="lo"}, +[5992] = {category="lo"}, +[5993] = {category="lo"}, +[5994] = {category="lo"}, +[5995] = {category="lo"}, +[5996] = {category="lo"}, +[5998] = {category="lo"}, +[5999] = {category="lo"}, +[6000] = {category="lo"}, +[6016] = {category="lo"}, +[6017] = {category="lo"}, +[6018] = {category="lo"}, +[6019] = {category="lo"}, +[6020] = {category="lo"}, +[6021] = {category="lo"}, +[6022] = {category="lo"}, +[6023] = {category="lo"}, +[6024] = {category="lo"}, +[6025] = {category="lo"}, +[6026] = {category="lo"}, +[6027] = {category="lo"}, +[6028] = {category="lo"}, +[6029] = {category="lo"}, +[6030] = {category="lo"}, +[6031] = {category="lo"}, +[6032] = {category="lo"}, +[6033] = {category="lo"}, +[6034] = {category="lo"}, +[6035] = {category="lo"}, +[6036] = {category="lo"}, +[6037] = {category="lo"}, +[6038] = {category="lo"}, +[6039] = {category="lo"}, +[6040] = {category="lo"}, +[6041] = {category="lo"}, +[6042] = {category="lo"}, +[6043] = {category="lo"}, +[6044] = {category="lo"}, +[6045] = {category="lo"}, +[6046] = {category="lo"}, +[6047] = {category="lo"}, +[6048] = {category="lo"}, +[6049] = {category="lo"}, +[6050] = {category="lo"}, +[6051] = {category="lo"}, +[6052] = {category="lo"}, +[6053] = {category="lo"}, +[6054] = {category="lo"}, +[6055] = {category="lo"}, +[6056] = {category="lo"}, +[6057] = {category="lo"}, +[6058] = {category="lo"}, +[6059] = {category="lo"}, +[6060] = {category="lo"}, +[6061] = {category="lo"}, +[6062] = {category="lo"}, +[6063] = {category="lo"}, +[6064] = {category="lo"}, +[6065] = {category="lo"}, +[6066] = {category="lo"}, +[6067] = {category="lo"}, +[6103] = {category="lm"}, +[6108] = {category="lo"}, +[6176] = {category="lo"}, +[6177] = {category="lo"}, +[6178] = {category="lo"}, +[6179] = {category="lo"}, +[6180] = {category="lo"}, +[6181] = {category="lo"}, +[6182] = {category="lo"}, +[6183] = {category="lo"}, +[6184] = {category="lo"}, +[6185] = {category="lo"}, +[6186] = {category="lo"}, +[6187] = {category="lo"}, +[6188] = {category="lo"}, +[6189] = {category="lo"}, +[6190] = {category="lo"}, +[6191] = {category="lo"}, +[6192] = {category="lo"}, +[6193] = {category="lo"}, +[6194] = {category="lo"}, +[6195] = {category="lo"}, +[6196] = {category="lo"}, +[6197] = {category="lo"}, +[6198] = {category="lo"}, +[6199] = {category="lo"}, +[6200] = {category="lo"}, +[6201] = {category="lo"}, +[6202] = {category="lo"}, +[6203] = {category="lo"}, +[6204] = {category="lo"}, +[6205] = {category="lo"}, +[6206] = {category="lo"}, +[6207] = {category="lo"}, +[6208] = {category="lo"}, +[6209] = {category="lo"}, +[6210] = {category="lo"}, +[6211] = {category="lm"}, +[6212] = {category="lo"}, +[6213] = {category="lo"}, +[6214] = {category="lo"}, +[6215] = {category="lo"}, +[6216] = {category="lo"}, +[6217] = {category="lo"}, +[6218] = {category="lo"}, +[6219] = {category="lo"}, +[6220] = {category="lo"}, +[6221] = {category="lo"}, +[6222] = {category="lo"}, +[6223] = {category="lo"}, +[6224] = {category="lo"}, +[6225] = {category="lo"}, +[6226] = {category="lo"}, +[6227] = {category="lo"}, +[6228] = {category="lo"}, +[6229] = {category="lo"}, +[6230] = {category="lo"}, +[6231] = {category="lo"}, +[6232] = {category="lo"}, +[6233] = {category="lo"}, +[6234] = {category="lo"}, +[6235] = {category="lo"}, +[6236] = {category="lo"}, +[6237] = {category="lo"}, +[6238] = {category="lo"}, +[6239] = {category="lo"}, +[6240] = {category="lo"}, +[6241] = {category="lo"}, +[6242] = {category="lo"}, +[6243] = {category="lo"}, +[6244] = {category="lo"}, +[6245] = {category="lo"}, +[6246] = {category="lo"}, +[6247] = {category="lo"}, +[6248] = {category="lo"}, +[6249] = {category="lo"}, +[6250] = {category="lo"}, +[6251] = {category="lo"}, +[6252] = {category="lo"}, +[6253] = {category="lo"}, +[6254] = {category="lo"}, +[6255] = {category="lo"}, +[6256] = {category="lo"}, +[6257] = {category="lo"}, +[6258] = {category="lo"}, +[6259] = {category="lo"}, +[6260] = {category="lo"}, +[6261] = {category="lo"}, +[6262] = {category="lo"}, +[6263] = {category="lo"}, +[6264] = {category="lo"}, +[6272] = {category="lo"}, +[6273] = {category="lo"}, +[6274] = {category="lo"}, +[6275] = {category="lo"}, +[6276] = {category="lo"}, +[6279] = {category="lo"}, +[6280] = {category="lo"}, +[6281] = {category="lo"}, +[6282] = {category="lo"}, +[6283] = {category="lo"}, +[6284] = {category="lo"}, +[6285] = {category="lo"}, +[6286] = {category="lo"}, +[6287] = {category="lo"}, +[6288] = {category="lo"}, +[6289] = {category="lo"}, +[6290] = {category="lo"}, +[6291] = {category="lo"}, +[6292] = {category="lo"}, +[6293] = {category="lo"}, +[6294] = {category="lo"}, +[6295] = {category="lo"}, +[6296] = {category="lo"}, +[6297] = {category="lo"}, +[6298] = {category="lo"}, +[6299] = {category="lo"}, +[6300] = {category="lo"}, +[6301] = {category="lo"}, +[6302] = {category="lo"}, +[6303] = {category="lo"}, +[6304] = {category="lo"}, +[6305] = {category="lo"}, +[6306] = {category="lo"}, +[6307] = {category="lo"}, +[6308] = {category="lo"}, +[6309] = {category="lo"}, +[6310] = {category="lo"}, +[6311] = {category="lo"}, +[6312] = {category="lo"}, +[6314] = {category="lo"}, +[6320] = {category="lo"}, +[6321] = {category="lo"}, +[6322] = {category="lo"}, +[6323] = {category="lo"}, +[6324] = {category="lo"}, +[6325] = {category="lo"}, +[6326] = {category="lo"}, +[6327] = {category="lo"}, +[6328] = {category="lo"}, +[6329] = {category="lo"}, +[6330] = {category="lo"}, +[6331] = {category="lo"}, +[6332] = {category="lo"}, +[6333] = {category="lo"}, +[6334] = {category="lo"}, +[6335] = {category="lo"}, +[6336] = {category="lo"}, +[6337] = {category="lo"}, +[6338] = {category="lo"}, +[6339] = {category="lo"}, +[6340] = {category="lo"}, +[6341] = {category="lo"}, +[6342] = {category="lo"}, +[6343] = {category="lo"}, +[6344] = {category="lo"}, +[6345] = {category="lo"}, +[6346] = {category="lo"}, +[6347] = {category="lo"}, +[6348] = {category="lo"}, +[6349] = {category="lo"}, +[6350] = {category="lo"}, +[6351] = {category="lo"}, +[6352] = {category="lo"}, +[6353] = {category="lo"}, +[6354] = {category="lo"}, +[6355] = {category="lo"}, +[6356] = {category="lo"}, +[6357] = {category="lo"}, +[6358] = {category="lo"}, +[6359] = {category="lo"}, +[6360] = {category="lo"}, +[6361] = {category="lo"}, +[6362] = {category="lo"}, +[6363] = {category="lo"}, +[6364] = {category="lo"}, +[6365] = {category="lo"}, +[6366] = {category="lo"}, +[6367] = {category="lo"}, +[6368] = {category="lo"}, +[6369] = {category="lo"}, +[6370] = {category="lo"}, +[6371] = {category="lo"}, +[6372] = {category="lo"}, +[6373] = {category="lo"}, +[6374] = {category="lo"}, +[6375] = {category="lo"}, +[6376] = {category="lo"}, +[6377] = {category="lo"}, +[6378] = {category="lo"}, +[6379] = {category="lo"}, +[6380] = {category="lo"}, +[6381] = {category="lo"}, +[6382] = {category="lo"}, +[6383] = {category="lo"}, +[6384] = {category="lo"}, +[6385] = {category="lo"}, +[6386] = {category="lo"}, +[6387] = {category="lo"}, +[6388] = {category="lo"}, +[6389] = {category="lo"}, +[6400] = {category="lo"}, +[6401] = {category="lo"}, +[6402] = {category="lo"}, +[6403] = {category="lo"}, +[6404] = {category="lo"}, +[6405] = {category="lo"}, +[6406] = {category="lo"}, +[6407] = {category="lo"}, +[6408] = {category="lo"}, +[6409] = {category="lo"}, +[6410] = {category="lo"}, +[6411] = {category="lo"}, +[6412] = {category="lo"}, +[6413] = {category="lo"}, +[6414] = {category="lo"}, +[6415] = {category="lo"}, +[6416] = {category="lo"}, +[6417] = {category="lo"}, +[6418] = {category="lo"}, +[6419] = {category="lo"}, +[6420] = {category="lo"}, +[6421] = {category="lo"}, +[6422] = {category="lo"}, +[6423] = {category="lo"}, +[6424] = {category="lo"}, +[6425] = {category="lo"}, +[6426] = {category="lo"}, +[6427] = {category="lo"}, +[6428] = {category="lo"}, +[6429] = {category="lo"}, +[6430] = {category="lo"}, +[6480] = {category="lo"}, +[6481] = {category="lo"}, +[6482] = {category="lo"}, +[6483] = {category="lo"}, +[6484] = {category="lo"}, +[6485] = {category="lo"}, +[6486] = {category="lo"}, +[6487] = {category="lo"}, +[6488] = {category="lo"}, +[6489] = {category="lo"}, +[6490] = {category="lo"}, +[6491] = {category="lo"}, +[6492] = {category="lo"}, +[6493] = {category="lo"}, +[6494] = {category="lo"}, +[6495] = {category="lo"}, +[6496] = {category="lo"}, +[6497] = {category="lo"}, +[6498] = {category="lo"}, +[6499] = {category="lo"}, +[6500] = {category="lo"}, +[6501] = {category="lo"}, +[6502] = {category="lo"}, +[6503] = {category="lo"}, +[6504] = {category="lo"}, +[6505] = {category="lo"}, +[6506] = {category="lo"}, +[6507] = {category="lo"}, +[6508] = {category="lo"}, +[6509] = {category="lo"}, +[6512] = {category="lo"}, +[6513] = {category="lo"}, +[6514] = {category="lo"}, +[6515] = {category="lo"}, +[6516] = {category="lo"}, +[6528] = {category="lo"}, +[6529] = {category="lo"}, +[6530] = {category="lo"}, +[6531] = {category="lo"}, +[6532] = {category="lo"}, +[6533] = {category="lo"}, +[6534] = {category="lo"}, +[6535] = {category="lo"}, +[6536] = {category="lo"}, +[6537] = {category="lo"}, +[6538] = {category="lo"}, +[6539] = {category="lo"}, +[6540] = {category="lo"}, +[6541] = {category="lo"}, +[6542] = {category="lo"}, +[6543] = {category="lo"}, +[6544] = {category="lo"}, +[6545] = {category="lo"}, +[6546] = {category="lo"}, +[6547] = {category="lo"}, +[6548] = {category="lo"}, +[6549] = {category="lo"}, +[6550] = {category="lo"}, +[6551] = {category="lo"}, +[6552] = {category="lo"}, +[6553] = {category="lo"}, +[6554] = {category="lo"}, +[6555] = {category="lo"}, +[6556] = {category="lo"}, +[6557] = {category="lo"}, +[6558] = {category="lo"}, +[6559] = {category="lo"}, +[6560] = {category="lo"}, +[6561] = {category="lo"}, +[6562] = {category="lo"}, +[6563] = {category="lo"}, +[6564] = {category="lo"}, +[6565] = {category="lo"}, +[6566] = {category="lo"}, +[6567] = {category="lo"}, +[6568] = {category="lo"}, +[6569] = {category="lo"}, +[6570] = {category="lo"}, +[6571] = {category="lo"}, +[6576] = {category="lo"}, +[6577] = {category="lo"}, +[6578] = {category="lo"}, +[6579] = {category="lo"}, +[6580] = {category="lo"}, +[6581] = {category="lo"}, +[6582] = {category="lo"}, +[6583] = {category="lo"}, +[6584] = {category="lo"}, +[6585] = {category="lo"}, +[6586] = {category="lo"}, +[6587] = {category="lo"}, +[6588] = {category="lo"}, +[6589] = {category="lo"}, +[6590] = {category="lo"}, +[6591] = {category="lo"}, +[6592] = {category="lo"}, +[6593] = {category="lo"}, +[6594] = {category="lo"}, +[6595] = {category="lo"}, +[6596] = {category="lo"}, +[6597] = {category="lo"}, +[6598] = {category="lo"}, +[6599] = {category="lo"}, +[6600] = {category="lo"}, +[6601] = {category="lo"}, +[6656] = {category="lo"}, +[6657] = {category="lo"}, +[6658] = {category="lo"}, +[6659] = {category="lo"}, +[6660] = {category="lo"}, +[6661] = {category="lo"}, +[6662] = {category="lo"}, +[6663] = {category="lo"}, +[6664] = {category="lo"}, +[6665] = {category="lo"}, +[6666] = {category="lo"}, +[6667] = {category="lo"}, +[6668] = {category="lo"}, +[6669] = {category="lo"}, +[6670] = {category="lo"}, +[6671] = {category="lo"}, +[6672] = {category="lo"}, +[6673] = {category="lo"}, +[6674] = {category="lo"}, +[6675] = {category="lo"}, +[6676] = {category="lo"}, +[6677] = {category="lo"}, +[6678] = {category="lo"}, +[6688] = {category="lo"}, +[6689] = {category="lo"}, +[6690] = {category="lo"}, +[6691] = {category="lo"}, +[6692] = {category="lo"}, +[6693] = {category="lo"}, +[6694] = {category="lo"}, +[6695] = {category="lo"}, +[6696] = {category="lo"}, +[6697] = {category="lo"}, +[6698] = {category="lo"}, +[6699] = {category="lo"}, +[6700] = {category="lo"}, +[6701] = {category="lo"}, +[6702] = {category="lo"}, +[6703] = {category="lo"}, +[6704] = {category="lo"}, +[6705] = {category="lo"}, +[6706] = {category="lo"}, +[6707] = {category="lo"}, +[6708] = {category="lo"}, +[6709] = {category="lo"}, +[6710] = {category="lo"}, +[6711] = {category="lo"}, +[6712] = {category="lo"}, +[6713] = {category="lo"}, +[6714] = {category="lo"}, +[6715] = {category="lo"}, +[6716] = {category="lo"}, +[6717] = {category="lo"}, +[6718] = {category="lo"}, +[6719] = {category="lo"}, +[6720] = {category="lo"}, +[6721] = {category="lo"}, +[6722] = {category="lo"}, +[6723] = {category="lo"}, +[6724] = {category="lo"}, +[6725] = {category="lo"}, +[6726] = {category="lo"}, +[6727] = {category="lo"}, +[6728] = {category="lo"}, +[6729] = {category="lo"}, +[6730] = {category="lo"}, +[6731] = {category="lo"}, +[6732] = {category="lo"}, +[6733] = {category="lo"}, +[6734] = {category="lo"}, +[6735] = {category="lo"}, +[6736] = {category="lo"}, +[6737] = {category="lo"}, +[6738] = {category="lo"}, +[6739] = {category="lo"}, +[6740] = {category="lo"}, +[6823] = {category="lm"}, +[6917] = {category="lo"}, +[6918] = {category="lo", shcode=6917}, +[6919] = {category="lo"}, +[6920] = {category="lo", shcode=6919}, +[6921] = {category="lo"}, +[6922] = {category="lo", shcode=6921}, +[6923] = {category="lo"}, +[6924] = {category="lo", shcode=6923}, +[6925] = {category="lo"}, +[6926] = {category="lo", shcode=6925}, +[6927] = {category="lo"}, +[6928] = {category="lo"}, +[6929] = {category="lo"}, +[6930] = {category="lo", shcode=6929}, +[6931] = {category="lo"}, +[6932] = {category="lo"}, +[6933] = {category="lo"}, +[6934] = {category="lo"}, +[6935] = {category="lo"}, +[6936] = {category="lo"}, +[6937] = {category="lo"}, +[6938] = {category="lo"}, +[6939] = {category="lo"}, +[6940] = {category="lo"}, +[6941] = {category="lo"}, +[6942] = {category="lo"}, +[6943] = {category="lo"}, +[6944] = {category="lo"}, +[6945] = {category="lo"}, +[6946] = {category="lo"}, +[6947] = {category="lo"}, +[6948] = {category="lo"}, +[6949] = {category="lo"}, +[6950] = {category="lo"}, +[6951] = {category="lo"}, +[6952] = {category="lo"}, +[6953] = {category="lo"}, +[6954] = {category="lo"}, +[6955] = {category="lo"}, +[6956] = {category="lo"}, +[6957] = {category="lo"}, +[6958] = {category="lo"}, +[6959] = {category="lo"}, +[6960] = {category="lo"}, +[6961] = {category="lo"}, +[6962] = {category="lo"}, +[6963] = {category="lo"}, +[6981] = {category="lo"}, +[6982] = {category="lo"}, +[6983] = {category="lo"}, +[6984] = {category="lo"}, +[6985] = {category="lo"}, +[6986] = {category="lo"}, +[6987] = {category="lo"}, +[6988] = {category="lo"}, +[7043] = {category="lo"}, +[7044] = {category="lo"}, +[7045] = {category="lo"}, +[7046] = {category="lo"}, +[7047] = {category="lo"}, +[7048] = {category="lo"}, +[7049] = {category="lo"}, +[7050] = {category="lo"}, +[7051] = {category="lo"}, +[7052] = {category="lo"}, +[7053] = {category="lo"}, +[7054] = {category="lo"}, +[7055] = {category="lo"}, +[7056] = {category="lo"}, +[7057] = {category="lo"}, +[7058] = {category="lo"}, +[7059] = {category="lo"}, +[7060] = {category="lo"}, +[7061] = {category="lo"}, +[7062] = {category="lo"}, +[7063] = {category="lo"}, +[7064] = {category="lo"}, +[7065] = {category="lo"}, +[7066] = {category="lo"}, +[7067] = {category="lo"}, +[7068] = {category="lo"}, +[7069] = {category="lo"}, +[7070] = {category="lo"}, +[7071] = {category="lo"}, +[7072] = {category="lo"}, +[7086] = {category="lo"}, +[7087] = {category="lo"}, +[7098] = {category="lo"}, +[7099] = {category="lo"}, +[7100] = {category="lo"}, +[7101] = {category="lo"}, +[7102] = {category="lo"}, +[7103] = {category="lo"}, +[7104] = {category="lo"}, +[7105] = {category="lo"}, +[7106] = {category="lo"}, +[7107] = {category="lo"}, +[7108] = {category="lo"}, +[7109] = {category="lo"}, +[7110] = {category="lo"}, +[7111] = {category="lo"}, +[7112] = {category="lo"}, +[7113] = {category="lo"}, +[7114] = {category="lo"}, +[7115] = {category="lo"}, +[7116] = {category="lo"}, +[7117] = {category="lo"}, +[7118] = {category="lo"}, +[7119] = {category="lo"}, +[7120] = {category="lo"}, +[7121] = {category="lo"}, +[7122] = {category="lo"}, +[7123] = {category="lo"}, +[7124] = {category="lo"}, +[7125] = {category="lo"}, +[7126] = {category="lo"}, +[7127] = {category="lo"}, +[7128] = {category="lo"}, +[7129] = {category="lo"}, +[7130] = {category="lo"}, +[7131] = {category="lo"}, +[7132] = {category="lo"}, +[7133] = {category="lo"}, +[7134] = {category="lo"}, +[7135] = {category="lo"}, +[7136] = {category="lo"}, +[7137] = {category="lo"}, +[7138] = {category="lo"}, +[7139] = {category="lo"}, +[7140] = {category="lo"}, +[7141] = {category="lo"}, +[7168] = {category="lo"}, +[7169] = {category="lo"}, +[7170] = {category="lo"}, +[7171] = {category="lo"}, +[7172] = {category="lo"}, +[7173] = {category="lo"}, +[7174] = {category="lo"}, +[7175] = {category="lo"}, +[7176] = {category="lo"}, +[7177] = {category="lo"}, +[7178] = {category="lo"}, +[7179] = {category="lo"}, +[7180] = {category="lo"}, +[7181] = {category="lo"}, +[7182] = {category="lo"}, +[7183] = {category="lo"}, +[7184] = {category="lo"}, +[7185] = {category="lo"}, +[7186] = {category="lo"}, +[7187] = {category="lo"}, +[7188] = {category="lo"}, +[7189] = {category="lo"}, +[7190] = {category="lo"}, +[7191] = {category="lo"}, +[7192] = {category="lo"}, +[7193] = {category="lo"}, +[7194] = {category="lo"}, +[7195] = {category="lo"}, +[7196] = {category="lo"}, +[7197] = {category="lo"}, +[7198] = {category="lo"}, +[7199] = {category="lo"}, +[7200] = {category="lo"}, +[7201] = {category="lo"}, +[7202] = {category="lo"}, +[7203] = {category="lo"}, +[7245] = {category="lo"}, +[7246] = {category="lo"}, +[7247] = {category="lo"}, +[7258] = {category="lo"}, +[7259] = {category="lo"}, +[7260] = {category="lo"}, +[7261] = {category="lo"}, +[7262] = {category="lo"}, +[7263] = {category="lo"}, +[7264] = {category="lo"}, +[7265] = {category="lo"}, +[7266] = {category="lo"}, +[7267] = {category="lo"}, +[7268] = {category="lo"}, +[7269] = {category="lo"}, +[7270] = {category="lo"}, +[7271] = {category="lo"}, +[7272] = {category="lo"}, +[7273] = {category="lo"}, +[7274] = {category="lo"}, +[7275] = {category="lo"}, +[7276] = {category="lo"}, +[7277] = {category="lo"}, +[7278] = {category="lo"}, +[7279] = {category="lo"}, +[7280] = {category="lo"}, +[7281] = {category="lo"}, +[7282] = {category="lo"}, +[7283] = {category="lo"}, +[7284] = {category="lo"}, +[7285] = {category="lo"}, +[7286] = {category="lo"}, +[7287] = {category="lo"}, +[7288] = {category="lm"}, +[7289] = {category="lm"}, +[7290] = {category="lm"}, +[7291] = {category="lm"}, +[7292] = {category="lm"}, +[7293] = {category="lm"}, +[7296] = {category="ll"}, +[7297] = {category="ll"}, +[7298] = {category="ll"}, +[7299] = {category="ll"}, +[7300] = {category="ll"}, +[7301] = {category="ll"}, +[7302] = {category="ll"}, +[7303] = {category="ll"}, +[7304] = {category="ll"}, +[7312] = {category="lu", lccode=4304}, +[7313] = {category="lu", lccode=4305}, +[7314] = {category="lu", lccode=4306}, +[7315] = {category="lu", lccode=4307}, +[7316] = {category="lu", lccode=4308}, +[7317] = {category="lu", lccode=4309}, +[7318] = {category="lu", lccode=4310}, +[7319] = {category="lu", lccode=4311}, +[7320] = {category="lu", lccode=4312}, +[7321] = {category="lu", lccode=4313}, +[7322] = {category="lu", lccode=4314}, +[7323] = {category="lu", lccode=4315}, +[7324] = {category="lu", lccode=4316}, +[7325] = {category="lu", lccode=4317}, +[7326] = {category="lu", lccode=4318}, +[7327] = {category="lu", lccode=4319}, +[7328] = {category="lu", lccode=4320}, +[7329] = {category="lu", lccode=4321}, +[7330] = {category="lu", lccode=4322}, +[7331] = {category="lu", lccode=4323}, +[7332] = {category="lu", lccode=4324}, +[7333] = {category="lu", lccode=4325}, +[7334] = {category="lu", lccode=4326}, +[7335] = {category="lu", lccode=4327}, +[7336] = {category="lu", lccode=4328}, +[7337] = {category="lu", lccode=4329}, +[7338] = {category="lu", lccode=4330}, +[7339] = {category="lu", lccode=4331}, +[7340] = {category="lu", lccode=4332}, +[7341] = {category="lu", lccode=4333}, +[7342] = {category="lu", lccode=4334}, +[7343] = {category="lu", lccode=4335}, +[7344] = {category="lu", lccode=4336}, +[7345] = {category="lu", lccode=4337}, +[7346] = {category="lu", lccode=4338}, +[7347] = {category="lu", lccode=4339}, +[7348] = {category="lu", lccode=4340}, +[7349] = {category="lu", lccode=4341}, +[7350] = {category="lu", lccode=4342}, +[7351] = {category="lu", lccode=4343}, +[7352] = {category="lu", lccode=4344}, +[7353] = {category="lu", lccode=4345}, +[7354] = {category="lu", lccode=4346}, +[7357] = {category="lu", lccode=4349}, +[7358] = {category="lu", lccode=4350}, +[7359] = {category="lu", lccode=4351}, +[7401] = {category="lo"}, +[7402] = {category="lo"}, +[7403] = {category="lo"}, +[7404] = {category="lo"}, +[7406] = {category="lo"}, +[7407] = {category="lo"}, +[7408] = {category="lo"}, +[7409] = {category="lo"}, +[7410] = {category="lo"}, +[7411] = {category="lo"}, +[7413] = {category="lo"}, +[7414] = {category="lo"}, +[7418] = {category="lo"}, +[7424] = {category="ll"}, +[7425] = {category="ll"}, +[7426] = {category="ll"}, +[7427] = {category="ll"}, +[7428] = {category="ll"}, +[7429] = {category="ll"}, +[7430] = {category="ll"}, +[7431] = {category="ll"}, +[7432] = {category="ll"}, +[7433] = {category="ll"}, +[7434] = {category="ll"}, +[7435] = {category="ll"}, +[7436] = {category="ll"}, +[7437] = {category="ll"}, +[7438] = {category="ll"}, +[7439] = {category="ll"}, +[7440] = {category="ll"}, +[7441] = {category="ll"}, +[7442] = {category="ll"}, +[7443] = {category="ll"}, +[7444] = {category="ll"}, +[7445] = {category="ll"}, +[7446] = {category="ll"}, +[7447] = {category="ll"}, +[7448] = {category="ll"}, +[7449] = {category="ll"}, +[7450] = {category="ll"}, +[7451] = {category="ll"}, +[7452] = {category="ll"}, +[7453] = {category="ll"}, +[7454] = {category="ll"}, +[7455] = {category="ll"}, +[7456] = {category="ll"}, +[7457] = {category="ll"}, +[7458] = {category="ll"}, +[7459] = {category="ll"}, +[7460] = {category="ll"}, +[7461] = {category="ll"}, +[7462] = {category="ll"}, +[7463] = {category="ll"}, +[7464] = {category="ll"}, +[7465] = {category="ll"}, +[7466] = {category="ll"}, +[7467] = {category="ll"}, +[7468] = {category="lm", shcode=14}, +[7469] = {category="lm", shcode=14}, +[7470] = {category="lm", shcode=14}, +[7471] = {category="lm"}, +[7472] = {category="lm", shcode=14}, +[7473] = {category="lm", shcode=14}, +[7474] = {category="lm", shcode=14}, +[7475] = {category="lm", shcode=14}, +[7476] = {category="lm", shcode=14}, +[7477] = {category="lm", shcode=14}, +[7478] = {category="lm", shcode=14}, +[7479] = {category="lm", shcode=14}, +[7480] = {category="lm", shcode=14}, +[7481] = {category="lm", shcode=14}, +[7482] = {category="lm", shcode=14}, +[7483] = {category="lm"}, +[7484] = {category="lm", shcode=14}, +[7485] = {category="lm", shcode=14}, +[7486] = {category="lm", shcode=14}, +[7487] = {category="lm", shcode=14}, +[7488] = {category="lm", shcode=14}, +[7489] = {category="lm", shcode=14}, +[7490] = {category="lm", shcode=14}, +[7491] = {category="lm", shcode=14}, +[7492] = {category="lm", shcode=14}, +[7493] = {category="lm", shcode=14}, +[7494] = {category="lm", shcode=14}, +[7495] = {category="lm", shcode=14}, +[7496] = {category="lm", shcode=14}, +[7497] = {category="lm", shcode=14}, +[7498] = {category="lm", shcode=14}, +[7499] = {category="lm", shcode=14}, +[7500] = {category="lm", shcode=14}, +[7501] = {category="lm", shcode=14}, +[7502] = {category="lm"}, +[7503] = {category="lm", shcode=14}, +[7504] = {category="lm", shcode=14}, +[7505] = {category="lm", shcode=14}, +[7506] = {category="lm", shcode=14}, +[7507] = {category="lm", shcode=14}, +[7508] = {category="lm", shcode=14}, +[7509] = {category="lm", shcode=14}, +[7510] = {category="lm", shcode=14}, +[7511] = {category="lm", shcode=14}, +[7512] = {category="lm", shcode=14}, +[7513] = {category="lm", shcode=14}, +[7514] = {category="lm", shcode=14}, +[7515] = {category="lm", shcode=14}, +[7516] = {category="lm", shcode=14}, +[7517] = {category="lm", shcode=14}, +[7518] = {category="lm", shcode=14}, +[7519] = {category="lm", shcode=14}, +[7520] = {category="lm", shcode=14}, +[7521] = {category="lm", shcode=14}, +[7522] = {category="lm", shcode=11}, +[7523] = {category="lm", shcode=11}, +[7524] = {category="lm", shcode=11}, +[7525] = {category="lm", shcode=11}, +[7526] = {category="lm", shcode=11}, +[7527] = {category="lm", shcode=11}, +[7528] = {category="lm", shcode=11}, +[7529] = {category="lm", shcode=11}, +[7530] = {category="lm", shcode=11}, +[7531] = {category="ll"}, +[7532] = {category="ll"}, +[7533] = {category="ll"}, +[7534] = {category="ll"}, +[7535] = {category="ll"}, +[7536] = {category="ll"}, +[7537] = {category="ll"}, +[7538] = {category="ll"}, +[7539] = {category="ll"}, +[7540] = {category="ll"}, +[7541] = {category="ll"}, +[7542] = {category="ll"}, +[7543] = {category="ll"}, +[7544] = {category="lm", shcode=14}, +[7545] = {category="ll"}, +[7546] = {category="ll"}, +[7547] = {category="ll"}, +[7548] = {category="ll"}, +[7549] = {category="ll"}, +[7550] = {category="ll"}, +[7551] = {category="ll"}, +[7552] = {category="ll"}, +[7553] = {category="ll"}, +[7554] = {category="ll"}, +[7555] = {category="ll"}, +[7556] = {category="ll"}, +[7557] = {category="ll"}, +[7558] = {category="ll"}, +[7559] = {category="ll"}, +[7560] = {category="ll"}, +[7561] = {category="ll"}, +[7562] = {category="ll"}, +[7563] = {category="ll"}, +[7564] = {category="ll"}, +[7565] = {category="ll"}, +[7566] = {category="ll"}, +[7567] = {category="ll"}, +[7568] = {category="ll"}, +[7569] = {category="ll"}, +[7570] = {category="ll"}, +[7571] = {category="ll"}, +[7572] = {category="ll"}, +[7573] = {category="ll"}, +[7574] = {category="ll"}, +[7575] = {category="ll"}, +[7576] = {category="ll"}, +[7577] = {category="ll"}, +[7578] = {category="ll"}, +[7579] = {category="lm", shcode=14}, +[7580] = {category="lm", shcode=14}, +[7581] = {category="lm", shcode=14}, +[7582] = {category="lm", shcode=14}, +[7583] = {category="lm", shcode=14}, +[7584] = {category="lm", shcode=14}, +[7585] = {category="lm", shcode=14}, +[7586] = {category="lm", shcode=14}, +[7587] = {category="lm", shcode=14}, +[7588] = {category="lm", shcode=14}, +[7589] = {category="lm", shcode=14}, +[7590] = {category="lm", shcode=14}, +[7591] = {category="lm", shcode=14}, +[7592] = {category="lm", shcode=14}, +[7593] = {category="lm", shcode=14}, +[7594] = {category="lm", shcode=14}, +[7595] = {category="lm", shcode=14}, +[7596] = {category="lm", shcode=14}, +[7597] = {category="lm", shcode=14}, +[7598] = {category="lm", shcode=14}, +[7599] = {category="lm", shcode=14}, +[7600] = {category="lm", shcode=14}, +[7601] = {category="lm", shcode=14}, +[7602] = {category="lm", shcode=14}, +[7603] = {category="lm", shcode=14}, +[7604] = {category="lm", shcode=14}, +[7605] = {category="lm", shcode=14}, +[7606] = {category="lm", shcode=14}, +[7607] = {category="lm", shcode=14}, +[7608] = {category="lm", shcode=14}, +[7609] = {category="lm", shcode=14}, +[7610] = {category="lm", shcode=14}, +[7611] = {category="lm", shcode=14}, +[7612] = {category="lm", shcode=14}, +[7613] = {category="lm", shcode=14}, +[7614] = {category="lm", shcode=14}, +[7615] = {category="lm", shcode=14}, +[7680] = {category="lu", lccode=7681, shcode=65}, +[7681] = {category="ll", shcode=97}, +[7682] = {category="lu", lccode=7683, shcode=66}, +[7683] = {category="ll", shcode=98}, +[7684] = {category="lu", lccode=7685, shcode=66}, +[7685] = {category="ll", shcode=98}, +[7686] = {category="lu", lccode=7687, shcode=66}, +[7687] = {category="ll", shcode=98}, +[7688] = {category="lu", lccode=7689, shcode=199}, +[7689] = {category="ll", shcode=231}, +[7690] = {category="lu", lccode=7691, shcode=68}, +[7691] = {category="ll", shcode=100}, +[7692] = {category="lu", lccode=7693, shcode=68}, +[7693] = {category="ll", shcode=100}, +[7694] = {category="lu", lccode=7695, shcode=68}, +[7695] = {category="ll", shcode=100}, +[7696] = {category="lu", lccode=7697, shcode=68}, +[7697] = {category="ll", shcode=100}, +[7698] = {category="lu", lccode=7699, shcode=68}, +[7699] = {category="ll", shcode=100}, +[7700] = {category="lu", lccode=7701, shcode=274}, +[7701] = {category="ll", shcode=275}, +[7702] = {category="lu", lccode=7703, shcode=274}, +[7703] = {category="ll", shcode=275}, +[7704] = {category="lu", lccode=7705, shcode=69}, +[7705] = {category="ll", shcode=101}, +[7706] = {category="lu", lccode=7707, shcode=69}, +[7707] = {category="ll", shcode=101}, +[7708] = {category="lu", lccode=7709, shcode=552}, +[7709] = {category="ll", shcode=553}, +[7710] = {category="lu", lccode=7711, shcode=70}, +[7711] = {category="ll", shcode=102}, +[7712] = {category="lu", lccode=7713, shcode=71}, +[7713] = {category="ll", shcode=103}, +[7714] = {category="lu", lccode=7715, shcode=72}, +[7715] = {category="ll", shcode=104}, +[7716] = {category="lu", lccode=7717, shcode=72}, +[7717] = {category="ll", shcode=104}, +[7718] = {category="lu", lccode=7719, shcode=72}, +[7719] = {category="ll", shcode=104}, +[7720] = {category="lu", lccode=7721, shcode=72}, +[7721] = {category="ll", shcode=104}, +[7722] = {category="lu", lccode=7723, shcode=72}, +[7723] = {category="ll", shcode=104}, +[7724] = {category="lu", lccode=7725, shcode=73}, +[7725] = {category="ll", shcode=105}, +[7726] = {category="lu", lccode=7727, shcode=207}, +[7727] = {category="ll", shcode=239}, +[7728] = {category="lu", lccode=7729, shcode=75}, +[7729] = {category="ll", shcode=107}, +[7730] = {category="lu", lccode=7731, shcode=75}, +[7731] = {category="ll", shcode=107}, +[7732] = {category="lu", lccode=7733, shcode=75}, +[7733] = {category="ll", shcode=107}, +[7734] = {category="lu", lccode=7735, shcode=76}, +[7735] = {category="ll", shcode=108}, +[7736] = {category="lu", lccode=7737, shcode=7734}, +[7737] = {category="ll", shcode=7735}, +[7738] = {category="lu", lccode=7739, shcode=76}, +[7739] = {category="ll", shcode=108}, +[7740] = {category="lu", lccode=7741, shcode=76}, +[7741] = {category="ll", shcode=108}, +[7742] = {category="lu", lccode=7743, shcode=77}, +[7743] = {category="ll", shcode=109}, +[7744] = {category="lu", lccode=7745, shcode=77}, +[7745] = {category="ll", shcode=109}, +[7746] = {category="lu", lccode=7747, shcode=77}, +[7747] = {category="ll", shcode=109}, +[7748] = {category="lu", lccode=7749, shcode=78}, +[7749] = {category="ll", shcode=110}, +[7750] = {category="lu", lccode=7751, shcode=78}, +[7751] = {category="ll", shcode=110}, +[7752] = {category="lu", lccode=7753, shcode=78}, +[7753] = {category="ll", shcode=110}, +[7754] = {category="lu", lccode=7755, shcode=78}, +[7755] = {category="ll", shcode=110}, +[7756] = {category="lu", lccode=7757, shcode=213}, +[7757] = {category="ll", shcode=245}, +[7758] = {category="lu", lccode=7759, shcode=213}, +[7759] = {category="ll", shcode=245}, +[7760] = {category="lu", lccode=7761, shcode=332}, +[7761] = {category="ll", shcode=333}, +[7762] = {category="lu", lccode=7763, shcode=332}, +[7763] = {category="ll", shcode=333}, +[7764] = {category="lu", lccode=7765, shcode=80}, +[7765] = {category="ll", shcode=112}, +[7766] = {category="lu", lccode=7767, shcode=80}, +[7767] = {category="ll", shcode=112}, +[7768] = {category="lu", lccode=7769, shcode=82}, +[7769] = {category="ll", shcode=114}, +[7770] = {category="lu", lccode=7771, shcode=82}, +[7771] = {category="ll", shcode=114}, +[7772] = {category="lu", lccode=7773, shcode=7770}, +[7773] = {category="ll", shcode=7771}, +[7774] = {category="lu", lccode=7775, shcode=82}, +[7775] = {category="ll", shcode=114}, +[7776] = {category="lu", lccode=7777, shcode=83}, +[7777] = {category="ll", shcode=115}, +[7778] = {category="lu", lccode=7779, shcode=83}, +[7779] = {category="ll", shcode=115}, +[7780] = {category="lu", lccode=7781, shcode=346}, +[7781] = {category="ll", shcode=347}, +[7782] = {category="lu", lccode=7783, shcode=352}, +[7783] = {category="ll", shcode=353}, +[7784] = {category="lu", lccode=7785, shcode=7778}, +[7785] = {category="ll", shcode=7779}, +[7786] = {category="lu", lccode=7787, shcode=84}, +[7787] = {category="ll", shcode=116}, +[7788] = {category="lu", lccode=7789, shcode=84}, +[7789] = {category="ll", shcode=116}, +[7790] = {category="lu", lccode=7791, shcode=84}, +[7791] = {category="ll", shcode=116}, +[7792] = {category="lu", lccode=7793, shcode=84}, +[7793] = {category="ll", shcode=116}, +[7794] = {category="lu", lccode=7795, shcode=85}, +[7795] = {category="ll", shcode=117}, +[7796] = {category="lu", lccode=7797, shcode=85}, +[7797] = {category="ll", shcode=117}, +[7798] = {category="lu", lccode=7799, shcode=85}, +[7799] = {category="ll", shcode=117}, +[7800] = {category="lu", lccode=7801, shcode=360}, +[7801] = {category="ll", shcode=361}, +[7802] = {category="lu", lccode=7803, shcode=362}, +[7803] = {category="ll", shcode=363}, +[7804] = {category="lu", lccode=7805, shcode=86}, +[7805] = {category="ll", shcode=118}, +[7806] = {category="lu", lccode=7807, shcode=86}, +[7807] = {category="ll", shcode=118}, +[7808] = {category="lu", lccode=7809, shcode=87}, +[7809] = {category="ll", shcode=119}, +[7810] = {category="lu", lccode=7811, shcode=87}, +[7811] = {category="ll", shcode=119}, +[7812] = {category="lu", lccode=7813, shcode=87}, +[7813] = {category="ll", shcode=119}, +[7814] = {category="lu", lccode=7815, shcode=87}, +[7815] = {category="ll", shcode=119}, +[7816] = {category="lu", lccode=7817, shcode=87}, +[7817] = {category="ll", shcode=119}, +[7818] = {category="lu", lccode=7819, shcode=88}, +[7819] = {category="ll", shcode=120}, +[7820] = {category="lu", lccode=7821, shcode=88}, +[7821] = {category="ll", shcode=120}, +[7822] = {category="lu", lccode=7823, shcode=89}, +[7823] = {category="ll", shcode=121}, +[7824] = {category="lu", lccode=7825, shcode=90}, +[7825] = {category="ll", shcode=122}, +[7826] = {category="lu", lccode=7827, shcode=90}, +[7827] = {category="ll", shcode=122}, +[7828] = {category="lu", lccode=7829, shcode=90}, +[7829] = {category="ll", shcode=122}, +[7830] = {category="ll", shcode=104}, +[7831] = {category="ll", shcode=116}, +[7832] = {category="ll", shcode=119}, +[7833] = {category="ll", shcode=121}, +[7834] = {category="ll", shcode=12}, +[7835] = {category="ll", shcode=383}, +[7836] = {category="ll"}, +[7837] = {category="ll"}, +[7838] = {category="lu", lccode=223}, +[7839] = {category="ll"}, +[7840] = {category="lu", lccode=7841, shcode=65}, +[7841] = {category="ll", shcode=97}, +[7842] = {category="lu", lccode=7843, shcode=65}, +[7843] = {category="ll", shcode=97}, +[7844] = {category="lu", lccode=7845, shcode=194}, +[7845] = {category="ll", shcode=226}, +[7846] = {category="lu", lccode=7847, shcode=194}, +[7847] = {category="ll", shcode=226}, +[7848] = {category="lu", lccode=7849, shcode=194}, +[7849] = {category="ll", shcode=226}, +[7850] = {category="lu", lccode=7851, shcode=194}, +[7851] = {category="ll", shcode=226}, +[7852] = {category="lu", lccode=7853, shcode=7840}, +[7853] = {category="ll", shcode=7841}, +[7854] = {category="lu", lccode=7855, shcode=258}, +[7855] = {category="ll", shcode=259}, +[7856] = {category="lu", lccode=7857, shcode=258}, +[7857] = {category="ll", shcode=259}, +[7858] = {category="lu", lccode=7859, shcode=258}, +[7859] = {category="ll", shcode=259}, +[7860] = {category="lu", lccode=7861, shcode=258}, +[7861] = {category="ll", shcode=259}, +[7862] = {category="lu", lccode=7863, shcode=7840}, +[7863] = {category="ll", shcode=7841}, +[7864] = {category="lu", lccode=7865, shcode=69}, +[7865] = {category="ll", shcode=101}, +[7866] = {category="lu", lccode=7867, shcode=69}, +[7867] = {category="ll", shcode=101}, +[7868] = {category="lu", lccode=7869, shcode=69}, +[7869] = {category="ll", shcode=101}, +[7870] = {category="lu", lccode=7871, shcode=202}, +[7871] = {category="ll", shcode=234}, +[7872] = {category="lu", lccode=7873, shcode=202}, +[7873] = {category="ll", shcode=234}, +[7874] = {category="lu", lccode=7875, shcode=202}, +[7875] = {category="ll", shcode=234}, +[7876] = {category="lu", lccode=7877, shcode=202}, +[7877] = {category="ll", shcode=234}, +[7878] = {category="lu", lccode=7879, shcode=7864}, +[7879] = {category="ll", shcode=7865}, +[7880] = {category="lu", lccode=7881, shcode=73}, +[7881] = {category="ll", shcode=105}, +[7882] = {category="lu", lccode=7883, shcode=73}, +[7883] = {category="ll", shcode=105}, +[7884] = {category="lu", lccode=7885, shcode=79}, +[7885] = {category="ll", shcode=111}, +[7886] = {category="lu", lccode=7887, shcode=79}, +[7887] = {category="ll", shcode=111}, +[7888] = {category="lu", lccode=7889, shcode=212}, +[7889] = {category="ll", shcode=244}, +[7890] = {category="lu", lccode=7891, shcode=212}, +[7891] = {category="ll", shcode=244}, +[7892] = {category="lu", lccode=7893, shcode=212}, +[7893] = {category="ll", shcode=244}, +[7894] = {category="lu", lccode=7895, shcode=212}, +[7895] = {category="ll", shcode=244}, +[7896] = {category="lu", lccode=7897, shcode=7884}, +[7897] = {category="ll", shcode=7885}, +[7898] = {category="lu", lccode=7899, shcode=416}, +[7899] = {category="ll", shcode=417}, +[7900] = {category="lu", lccode=7901, shcode=416}, +[7901] = {category="ll", shcode=417}, +[7902] = {category="lu", lccode=7903, shcode=416}, +[7903] = {category="ll", shcode=417}, +[7904] = {category="lu", lccode=7905, shcode=416}, +[7905] = {category="ll", shcode=417}, +[7906] = {category="lu", lccode=7907, shcode=416}, +[7907] = {category="ll", shcode=417}, +[7908] = {category="lu", lccode=7909, shcode=85}, +[7909] = {category="ll", shcode=117}, +[7910] = {category="lu", lccode=7911, shcode=85}, +[7911] = {category="ll", shcode=117}, +[7912] = {category="lu", lccode=7913, shcode=431}, +[7913] = {category="ll", shcode=432}, +[7914] = {category="lu", lccode=7915, shcode=431}, +[7915] = {category="ll", shcode=432}, +[7916] = {category="lu", lccode=7917, shcode=431}, +[7917] = {category="ll", shcode=432}, +[7918] = {category="lu", lccode=7919, shcode=431}, +[7919] = {category="ll", shcode=432}, +[7920] = {category="lu", lccode=7921, shcode=431}, +[7921] = {category="ll", shcode=432}, +[7922] = {category="lu", lccode=7923, shcode=89}, +[7923] = {category="ll", shcode=121}, +[7924] = {category="lu", lccode=7925, shcode=89}, +[7925] = {category="ll", shcode=121}, +[7926] = {category="lu", lccode=7927, shcode=89}, +[7927] = {category="ll", shcode=121}, +[7928] = {category="lu", lccode=7929, shcode=89}, +[7929] = {category="ll", shcode=121}, +[7930] = {category="lu", lccode=7931}, +[7931] = {category="ll"}, +[7932] = {category="lu", lccode=7933}, +[7933] = {category="ll"}, +[7934] = {category="lu", lccode=7935}, +[7935] = {category="ll"}, +[7936] = {category="ll", shcode=945}, +[7937] = {category="ll", shcode=945}, +[7938] = {category="ll", shcode=7936}, +[7939] = {category="ll", shcode=7937}, +[7940] = {category="ll", shcode=7936}, +[7941] = {category="ll", shcode=7937}, +[7942] = {category="ll", shcode=7936}, +[7943] = {category="ll", shcode=7937}, +[7944] = {category="lu", lccode=7936, shcode=913}, +[7945] = {category="lu", lccode=7937, shcode=913}, +[7946] = {category="lu", lccode=7938, shcode=7944}, +[7947] = {category="lu", lccode=7939, shcode=7945}, +[7948] = {category="lu", lccode=7940, shcode=7944}, +[7949] = {category="lu", lccode=7941, shcode=7945}, +[7950] = {category="lu", lccode=7942, shcode=7944}, +[7951] = {category="lu", lccode=7943, shcode=7945}, +[7952] = {category="ll", shcode=949}, +[7953] = {category="ll", shcode=949}, +[7954] = {category="ll", shcode=7952}, +[7955] = {category="ll", shcode=7953}, +[7956] = {category="ll", shcode=7952}, +[7957] = {category="ll", shcode=7953}, +[7960] = {category="lu", lccode=7952, shcode=917}, +[7961] = {category="lu", lccode=7953, shcode=917}, +[7962] = {category="lu", lccode=7954, shcode=7960}, +[7963] = {category="lu", lccode=7955, shcode=7961}, +[7964] = {category="lu", lccode=7956, shcode=7960}, +[7965] = {category="lu", lccode=7957, shcode=7961}, +[7968] = {category="ll", shcode=951}, +[7969] = {category="ll", shcode=951}, +[7970] = {category="ll", shcode=7968}, +[7971] = {category="ll", shcode=7969}, +[7972] = {category="ll", shcode=7968}, +[7973] = {category="ll", shcode=7969}, +[7974] = {category="ll", shcode=7968}, +[7975] = {category="ll", shcode=7969}, +[7976] = {category="lu", lccode=7968, shcode=919}, +[7977] = {category="lu", lccode=7969, shcode=919}, +[7978] = {category="lu", lccode=7970, shcode=7976}, +[7979] = {category="lu", lccode=7971, shcode=7977}, +[7980] = {category="lu", lccode=7972, shcode=7976}, +[7981] = {category="lu", lccode=7973, shcode=7977}, +[7982] = {category="lu", lccode=7974, shcode=7976}, +[7983] = {category="lu", lccode=7975, shcode=7977}, +[7984] = {category="ll", shcode=953}, +[7985] = {category="ll", shcode=953}, +[7986] = {category="ll", shcode=7984}, +[7987] = {category="ll", shcode=7985}, +[7988] = {category="ll", shcode=7984}, +[7989] = {category="ll", shcode=7985}, +[7990] = {category="ll", shcode=7984}, +[7991] = {category="ll", shcode=7985}, +[7992] = {category="lu", lccode=7984, shcode=921}, +[7993] = {category="lu", lccode=7985, shcode=921}, +[7994] = {category="lu", lccode=7986, shcode=7992}, +[7995] = {category="lu", lccode=7987, shcode=7993}, +[7996] = {category="lu", lccode=7988, shcode=7992}, +[7997] = {category="lu", lccode=7989, shcode=7993}, +[7998] = {category="lu", lccode=7990, shcode=7992}, +[7999] = {category="lu", lccode=7991, shcode=7993}, +[8000] = {category="ll", shcode=959}, +[8001] = {category="ll", shcode=959}, +[8002] = {category="ll", shcode=8000}, +[8003] = {category="ll", shcode=8001}, +[8004] = {category="ll", shcode=8000}, +[8005] = {category="ll", shcode=8001}, +[8008] = {category="lu", lccode=8000, shcode=927}, +[8009] = {category="lu", lccode=8001, shcode=927}, +[8010] = {category="lu", lccode=8002, shcode=8008}, +[8011] = {category="lu", lccode=8003, shcode=8009}, +[8012] = {category="lu", lccode=8004, shcode=8008}, +[8013] = {category="lu", lccode=8005, shcode=8009}, +[8016] = {category="ll", shcode=965}, +[8017] = {category="ll", shcode=965}, +[8018] = {category="ll", shcode=8016}, +[8019] = {category="ll", shcode=8017}, +[8020] = {category="ll", shcode=8016}, +[8021] = {category="ll", shcode=8017}, +[8022] = {category="ll", shcode=8016}, +[8023] = {category="ll", shcode=8017}, +[8025] = {category="lu", lccode=8017, shcode=933}, +[8027] = {category="lu", lccode=8019, shcode=8025}, +[8029] = {category="lu", lccode=8021, shcode=8025}, +[8031] = {category="lu", lccode=8023, shcode=8025}, +[8032] = {category="ll", shcode=969}, +[8033] = {category="ll", shcode=969}, +[8034] = {category="ll", shcode=8032}, +[8035] = {category="ll", shcode=8033}, +[8036] = {category="ll", shcode=8032}, +[8037] = {category="ll", shcode=8033}, +[8038] = {category="ll", shcode=8032}, +[8039] = {category="ll", shcode=8033}, +[8040] = {category="lu", lccode=8032, shcode=937}, +[8041] = {category="lu", lccode=8033, shcode=937}, +[8042] = {category="lu", lccode=8034, shcode=8040}, +[8043] = {category="lu", lccode=8035, shcode=8041}, +[8044] = {category="lu", lccode=8036, shcode=8040}, +[8045] = {category="lu", lccode=8037, shcode=8041}, +[8046] = {category="lu", lccode=8038, shcode=8040}, +[8047] = {category="lu", lccode=8039, shcode=8041}, +[8048] = {category="ll", shcode=945}, +[8049] = {category="ll", shcode=940}, +[8050] = {category="ll", shcode=949}, +[8051] = {category="ll", shcode=941}, +[8052] = {category="ll", shcode=951}, +[8053] = {category="ll", shcode=942}, +[8054] = {category="ll", shcode=953}, +[8055] = {category="ll", shcode=943}, +[8056] = {category="ll", shcode=959}, +[8057] = {category="ll", shcode=972}, +[8058] = {category="ll", shcode=965}, +[8059] = {category="ll", shcode=973}, +[8060] = {category="ll", shcode=969}, +[8061] = {category="ll", shcode=974}, +[8064] = {category="ll", shcode=7936}, +[8065] = {category="ll", shcode=7937}, +[8066] = {category="ll", shcode=7938}, +[8067] = {category="ll", shcode=7939}, +[8068] = {category="ll", shcode=7940}, +[8069] = {category="ll", shcode=7941}, +[8070] = {category="ll", shcode=7942}, +[8071] = {category="ll", shcode=7943}, +[8072] = {category="lt", lccode=8064, shcode=7944}, +[8073] = {category="lt", lccode=8065, shcode=7945}, +[8074] = {category="lt", lccode=8066, shcode=7946}, +[8075] = {category="lt", lccode=8067, shcode=7947}, +[8076] = {category="lt", lccode=8068, shcode=7948}, +[8077] = {category="lt", lccode=8069, shcode=7949}, +[8078] = {category="lt", lccode=8070, shcode=7950}, +[8079] = {category="lt", lccode=8071, shcode=7951}, +[8080] = {category="ll", shcode=7968}, +[8081] = {category="ll", shcode=7969}, +[8082] = {category="ll", shcode=7970}, +[8083] = {category="ll", shcode=7971}, +[8084] = {category="ll", shcode=7972}, +[8085] = {category="ll", shcode=7973}, +[8086] = {category="ll", shcode=7974}, +[8087] = {category="ll", shcode=7975}, +[8088] = {category="lt", lccode=8080, shcode=7976}, +[8089] = {category="lt", lccode=8081, shcode=7977}, +[8090] = {category="lt", lccode=8082, shcode=7978}, +[8091] = {category="lt", lccode=8083, shcode=7979}, +[8092] = {category="lt", lccode=8084, shcode=7980}, +[8093] = {category="lt", lccode=8085, shcode=7981}, +[8094] = {category="lt", lccode=8086, shcode=7982}, +[8095] = {category="lt", lccode=8087, shcode=7983}, +[8096] = {category="ll", shcode=8032}, +[8097] = {category="ll", shcode=8033}, +[8098] = {category="ll", shcode=8034}, +[8099] = {category="ll", shcode=8035}, +[8100] = {category="ll", shcode=8036}, +[8101] = {category="ll", shcode=8037}, +[8102] = {category="ll", shcode=8038}, +[8103] = {category="ll", shcode=8039}, +[8104] = {category="lt", lccode=8096, shcode=8040}, +[8105] = {category="lt", lccode=8097, shcode=8041}, +[8106] = {category="lt", lccode=8098, shcode=8042}, +[8107] = {category="lt", lccode=8099, shcode=8043}, +[8108] = {category="lt", lccode=8100, shcode=8044}, +[8109] = {category="lt", lccode=8101, shcode=8045}, +[8110] = {category="lt", lccode=8102, shcode=8046}, +[8111] = {category="lt", lccode=8103, shcode=8047}, +[8112] = {category="ll", shcode=945}, +[8113] = {category="ll", shcode=945}, +[8114] = {category="ll", shcode=8048}, +[8115] = {category="ll", shcode=945}, +[8116] = {category="ll", shcode=940}, +[8118] = {category="ll", shcode=945}, +[8119] = {category="ll", shcode=8118}, +[8120] = {category="lu", lccode=8112, shcode=913}, +[8121] = {category="lu", lccode=8113, shcode=913}, +[8122] = {category="lu", lccode=8048, shcode=913}, +[8123] = {category="lu", lccode=8049, shcode=902}, +[8124] = {category="lt", lccode=8115, shcode=913}, +[8126] = {category="ll", shcode=953}, +[8130] = {category="ll", shcode=8052}, +[8131] = {category="ll", shcode=951}, +[8132] = {category="ll", shcode=942}, +[8134] = {category="ll", shcode=951}, +[8135] = {category="ll", shcode=8134}, +[8136] = {category="lu", lccode=8050, shcode=917}, +[8137] = {category="lu", lccode=8051, shcode=904}, +[8138] = {category="lu", lccode=8052, shcode=919}, +[8139] = {category="lu", lccode=8053, shcode=905}, +[8140] = {category="lt", lccode=8131, shcode=919}, +[8144] = {category="ll", shcode=953}, +[8145] = {category="ll", shcode=953}, +[8146] = {category="ll", shcode=970}, +[8147] = {category="ll", shcode=912}, +[8150] = {category="ll", shcode=953}, +[8151] = {category="ll", shcode=970}, +[8152] = {category="lu", lccode=8144, shcode=921}, +[8153] = {category="lu", lccode=8145, shcode=921}, +[8154] = {category="lu", lccode=8054, shcode=921}, +[8155] = {category="lu", lccode=8055, shcode=906}, +[8160] = {category="ll", shcode=965}, +[8161] = {category="ll", shcode=965}, +[8162] = {category="ll", shcode=971}, +[8163] = {category="ll", shcode=944}, +[8164] = {category="ll", shcode=961}, +[8165] = {category="ll", shcode=961}, +[8166] = {category="ll", shcode=965}, +[8167] = {category="ll", shcode=971}, +[8168] = {category="lu", lccode=8160, shcode=933}, +[8169] = {category="lu", lccode=8161, shcode=933}, +[8170] = {category="lu", lccode=8058, shcode=933}, +[8171] = {category="lu", lccode=8059, shcode=910}, +[8172] = {category="lu", lccode=8165, shcode=929}, +[8178] = {category="ll", shcode=8060}, +[8179] = {category="ll", shcode=969}, +[8180] = {category="ll", shcode=974}, +[8182] = {category="ll", shcode=969}, +[8183] = {category="ll", shcode=8182}, +[8184] = {category="lu", lccode=8056, shcode=927}, +[8185] = {category="lu", lccode=8057, shcode=908}, +[8186] = {category="lu", lccode=8060, shcode=937}, +[8187] = {category="lu", lccode=8061, shcode=911}, +[8188] = {category="lt", lccode=8179, shcode=937}, +[8192] = {category="zs", shcode=8194}, +[8193] = {category="zs", shcode=8195}, +[8194] = {category="zs", shcode=12}, +[8195] = {category="zs", shcode=12}, +[8196] = {category="zs", shcode=12}, +[8197] = {category="zs", shcode=12}, +[8198] = {category="zs", shcode=12}, +[8199] = {category="zs", shcode=11}, +[8200] = {category="zs", shcode=12}, +[8201] = {category="zs", shcode=12}, +[8202] = {category="zs", shcode=12}, +[8239] = {category="zs", shcode=11}, +[8287] = {category="zs", shcode=12}, +[8305] = {category="lm", shcode=14}, +[8319] = {category="lm", shcode=14}, +[8336] = {category="lm", shcode=11}, +[8337] = {category="lm", shcode=11}, +[8338] = {category="lm", shcode=11}, +[8339] = {category="lm", shcode=11}, +[8340] = {category="lm", shcode=11}, +[8341] = {category="lm", shcode=11}, +[8342] = {category="lm", shcode=11}, +[8343] = {category="lm", shcode=11}, +[8344] = {category="lm", shcode=11}, +[8345] = {category="lm", shcode=11}, +[8346] = {category="lm", shcode=11}, +[8347] = {category="lm", shcode=11}, +[8348] = {category="lm", shcode=11}, +[8450] = {category="lu", shcode=15}, +[8455] = {category="lu", shcode=12}, +[8458] = {category="ll", shcode=15}, +[8459] = {category="lu", shcode=15}, +[8460] = {category="lu", shcode=15}, +[8461] = {category="lu", shcode=15}, +[8462] = {category="ll", shcode=15}, +[8463] = {category="ll", shcode=15}, +[8464] = {category="lu", shcode=15}, +[8465] = {category="lu", shcode=15}, +[8466] = {category="lu", shcode=15}, +[8467] = {category="ll", shcode=15}, +[8469] = {category="lu", shcode=15}, +[8473] = {category="lu", shcode=15}, +[8474] = {category="lu", shcode=15}, +[8475] = {category="lu", shcode=15}, +[8476] = {category="lu", shcode=15}, +[8477] = {category="lu", shcode=15}, +[8484] = {category="lu", shcode=15}, +[8486] = {category="lu", lccode=969, shcode=937}, +[8488] = {category="lu", shcode=15}, +[8490] = {category="lu", lccode=107, shcode=75}, +[8491] = {category="lu", lccode=229, shcode=197}, +[8492] = {category="lu", shcode=15}, +[8493] = {category="lu", shcode=15}, +[8495] = {category="ll", shcode=15}, +[8496] = {category="lu", shcode=15}, +[8497] = {category="lu", shcode=15}, +[8498] = {category="lu", lccode=8526}, +[8499] = {category="lu", shcode=15}, +[8500] = {category="ll", shcode=15}, +[8501] = {category="lo", shcode=12}, +[8502] = {category="lo", shcode=12}, +[8503] = {category="lo", shcode=12}, +[8504] = {category="lo", shcode=12}, +[8505] = {category="ll", shcode=15}, +[8508] = {category="ll", shcode=15}, +[8509] = {category="ll", shcode=15}, +[8510] = {category="lu", shcode=15}, +[8511] = {category="lu", shcode=15}, +[8517] = {category="lu", shcode=15}, +[8518] = {category="ll", shcode=15}, +[8519] = {category="ll", shcode=15}, +[8520] = {category="ll", shcode=15}, +[8521] = {category="ll", shcode=15}, +[8526] = {category="ll"}, +[8579] = {category="lu", lccode=8580}, +[8580] = {category="ll"}, +[11264] = {category="lu", lccode=11312}, +[11265] = {category="lu", lccode=11313}, +[11266] = {category="lu", lccode=11314}, +[11267] = {category="lu", lccode=11315}, +[11268] = {category="lu", lccode=11316}, +[11269] = {category="lu", lccode=11317}, +[11270] = {category="lu", lccode=11318}, +[11271] = {category="lu", lccode=11319}, +[11272] = {category="lu", lccode=11320}, +[11273] = {category="lu", lccode=11321}, +[11274] = {category="lu", lccode=11322}, +[11275] = {category="lu", lccode=11323}, +[11276] = {category="lu", lccode=11324}, +[11277] = {category="lu", lccode=11325}, +[11278] = {category="lu", lccode=11326}, +[11279] = {category="lu", lccode=11327}, +[11280] = {category="lu", lccode=11328}, +[11281] = {category="lu", lccode=11329}, +[11282] = {category="lu", lccode=11330}, +[11283] = {category="lu", lccode=11331}, +[11284] = {category="lu", lccode=11332}, +[11285] = {category="lu", lccode=11333}, +[11286] = {category="lu", lccode=11334}, +[11287] = {category="lu", lccode=11335}, +[11288] = {category="lu", lccode=11336}, +[11289] = {category="lu", lccode=11337}, +[11290] = {category="lu", lccode=11338}, +[11291] = {category="lu", lccode=11339}, +[11292] = {category="lu", lccode=11340}, +[11293] = {category="lu", lccode=11341}, +[11294] = {category="lu", lccode=11342}, +[11295] = {category="lu", lccode=11343}, +[11296] = {category="lu", lccode=11344}, +[11297] = {category="lu", lccode=11345}, +[11298] = {category="lu", lccode=11346}, +[11299] = {category="lu", lccode=11347}, +[11300] = {category="lu", lccode=11348}, +[11301] = {category="lu", lccode=11349}, +[11302] = {category="lu", lccode=11350}, +[11303] = {category="lu", lccode=11351}, +[11304] = {category="lu", lccode=11352}, +[11305] = {category="lu", lccode=11353}, +[11306] = {category="lu", lccode=11354}, +[11307] = {category="lu", lccode=11355}, +[11308] = {category="lu", lccode=11356}, +[11309] = {category="lu", lccode=11357}, +[11310] = {category="lu", lccode=11358}, +[11311] = {category="lu", lccode=11359}, +[11312] = {category="ll"}, +[11313] = {category="ll"}, +[11314] = {category="ll"}, +[11315] = {category="ll"}, +[11316] = {category="ll"}, +[11317] = {category="ll"}, +[11318] = {category="ll"}, +[11319] = {category="ll"}, +[11320] = {category="ll"}, +[11321] = {category="ll"}, +[11322] = {category="ll"}, +[11323] = {category="ll"}, +[11324] = {category="ll"}, +[11325] = {category="ll"}, +[11326] = {category="ll"}, +[11327] = {category="ll"}, +[11328] = {category="ll"}, +[11329] = {category="ll"}, +[11330] = {category="ll"}, +[11331] = {category="ll"}, +[11332] = {category="ll"}, +[11333] = {category="ll"}, +[11334] = {category="ll"}, +[11335] = {category="ll"}, +[11336] = {category="ll"}, +[11337] = {category="ll"}, +[11338] = {category="ll"}, +[11339] = {category="ll"}, +[11340] = {category="ll"}, +[11341] = {category="ll"}, +[11342] = {category="ll"}, +[11343] = {category="ll"}, +[11344] = {category="ll"}, +[11345] = {category="ll"}, +[11346] = {category="ll"}, +[11347] = {category="ll"}, +[11348] = {category="ll"}, +[11349] = {category="ll"}, +[11350] = {category="ll"}, +[11351] = {category="ll"}, +[11352] = {category="ll"}, +[11353] = {category="ll"}, +[11354] = {category="ll"}, +[11355] = {category="ll"}, +[11356] = {category="ll"}, +[11357] = {category="ll"}, +[11358] = {category="ll"}, +[11359] = {category="ll"}, +[11360] = {category="lu", lccode=11361}, +[11361] = {category="ll"}, +[11362] = {category="lu", lccode=619}, +[11363] = {category="lu", lccode=7549}, +[11364] = {category="lu", lccode=637}, +[11365] = {category="ll"}, +[11366] = {category="ll"}, +[11367] = {category="lu", lccode=11368}, +[11368] = {category="ll"}, +[11369] = {category="lu", lccode=11370}, +[11370] = {category="ll"}, +[11371] = {category="lu", lccode=11372}, +[11372] = {category="ll"}, +[11373] = {category="lu", lccode=593}, +[11374] = {category="lu", lccode=625}, +[11375] = {category="lu", lccode=592}, +[11376] = {category="lu", lccode=594}, +[11377] = {category="ll"}, +[11378] = {category="lu", lccode=11379}, +[11379] = {category="ll"}, +[11380] = {category="ll"}, +[11381] = {category="lu", lccode=11382}, +[11382] = {category="ll"}, +[11383] = {category="ll"}, +[11384] = {category="ll"}, +[11385] = {category="ll"}, +[11386] = {category="ll"}, +[11387] = {category="ll"}, +[11388] = {category="lm", shcode=11}, +[11389] = {category="lm", shcode=14}, +[11390] = {category="lu", lccode=575}, +[11391] = {category="lu", lccode=576}, +[11392] = {category="lu", lccode=11393}, +[11393] = {category="ll"}, +[11394] = {category="lu", lccode=11395}, +[11395] = {category="ll"}, +[11396] = {category="lu", lccode=11397}, +[11397] = {category="ll"}, +[11398] = {category="lu", lccode=11399}, +[11399] = {category="ll"}, +[11400] = {category="lu", lccode=11401}, +[11401] = {category="ll"}, +[11402] = {category="lu", lccode=11403}, +[11403] = {category="ll"}, +[11404] = {category="lu", lccode=11405}, +[11405] = {category="ll"}, +[11406] = {category="lu", lccode=11407}, +[11407] = {category="ll"}, +[11408] = {category="lu", lccode=11409}, +[11409] = {category="ll"}, +[11410] = {category="lu", lccode=11411}, +[11411] = {category="ll"}, +[11412] = {category="lu", lccode=11413}, +[11413] = {category="ll"}, +[11414] = {category="lu", lccode=11415}, +[11415] = {category="ll"}, +[11416] = {category="lu", lccode=11417}, +[11417] = {category="ll"}, +[11418] = {category="lu", lccode=11419}, +[11419] = {category="ll"}, +[11420] = {category="lu", lccode=11421}, +[11421] = {category="ll"}, +[11422] = {category="lu", lccode=11423}, +[11423] = {category="ll"}, +[11424] = {category="lu", lccode=11425}, +[11425] = {category="ll"}, +[11426] = {category="lu", lccode=11427}, +[11427] = {category="ll"}, +[11428] = {category="lu", lccode=11429}, +[11429] = {category="ll"}, +[11430] = {category="lu", lccode=11431}, +[11431] = {category="ll"}, +[11432] = {category="lu", lccode=11433}, +[11433] = {category="ll"}, +[11434] = {category="lu", lccode=11435}, +[11435] = {category="ll"}, +[11436] = {category="lu", lccode=11437}, +[11437] = {category="ll"}, +[11438] = {category="lu", lccode=11439}, +[11439] = {category="ll"}, +[11440] = {category="lu", lccode=11441}, +[11441] = {category="ll"}, +[11442] = {category="lu", lccode=11443}, +[11443] = {category="ll"}, +[11444] = {category="lu", lccode=11445}, +[11445] = {category="ll"}, +[11446] = {category="lu", lccode=11447}, +[11447] = {category="ll"}, +[11448] = {category="lu", lccode=11449}, +[11449] = {category="ll"}, +[11450] = {category="lu", lccode=11451}, +[11451] = {category="ll"}, +[11452] = {category="lu", lccode=11453}, +[11453] = {category="ll"}, +[11454] = {category="lu", lccode=11455}, +[11455] = {category="ll"}, +[11456] = {category="lu", lccode=11457}, +[11457] = {category="ll"}, +[11458] = {category="lu", lccode=11459}, +[11459] = {category="ll"}, +[11460] = {category="lu", lccode=11461}, +[11461] = {category="ll"}, +[11462] = {category="lu", lccode=11463}, +[11463] = {category="ll"}, +[11464] = {category="lu", lccode=11465}, +[11465] = {category="ll"}, +[11466] = {category="lu", lccode=11467}, +[11467] = {category="ll"}, +[11468] = {category="lu", lccode=11469}, +[11469] = {category="ll"}, +[11470] = {category="lu", lccode=11471}, +[11471] = {category="ll"}, +[11472] = {category="lu", lccode=11473}, +[11473] = {category="ll"}, +[11474] = {category="lu", lccode=11475}, +[11475] = {category="ll"}, +[11476] = {category="lu", lccode=11477}, +[11477] = {category="ll"}, +[11478] = {category="lu", lccode=11479}, +[11479] = {category="ll"}, +[11480] = {category="lu", lccode=11481}, +[11481] = {category="ll"}, +[11482] = {category="lu", lccode=11483}, +[11483] = {category="ll"}, +[11484] = {category="lu", lccode=11485}, +[11485] = {category="ll"}, +[11486] = {category="lu", lccode=11487}, +[11487] = {category="ll"}, +[11488] = {category="lu", lccode=11489}, +[11489] = {category="ll"}, +[11490] = {category="lu", lccode=11491}, +[11491] = {category="ll"}, +[11492] = {category="ll"}, +[11499] = {category="lu", lccode=11500}, +[11500] = {category="ll"}, +[11501] = {category="lu", lccode=11502}, +[11502] = {category="ll"}, +[11506] = {category="lu", lccode=11507}, +[11507] = {category="ll"}, +[11520] = {category="ll"}, +[11521] = {category="ll"}, +[11522] = {category="ll"}, +[11523] = {category="ll"}, +[11524] = {category="ll"}, +[11525] = {category="ll"}, +[11526] = {category="ll"}, +[11527] = {category="ll"}, +[11528] = {category="ll"}, +[11529] = {category="ll"}, +[11530] = {category="ll"}, +[11531] = {category="ll"}, +[11532] = {category="ll"}, +[11533] = {category="ll"}, +[11534] = {category="ll"}, +[11535] = {category="ll"}, +[11536] = {category="ll"}, +[11537] = {category="ll"}, +[11538] = {category="ll"}, +[11539] = {category="ll"}, +[11540] = {category="ll"}, +[11541] = {category="ll"}, +[11542] = {category="ll"}, +[11543] = {category="ll"}, +[11544] = {category="ll"}, +[11545] = {category="ll"}, +[11546] = {category="ll"}, +[11547] = {category="ll"}, +[11548] = {category="ll"}, +[11549] = {category="ll"}, +[11550] = {category="ll"}, +[11551] = {category="ll"}, +[11552] = {category="ll"}, +[11553] = {category="ll"}, +[11554] = {category="ll"}, +[11555] = {category="ll"}, +[11556] = {category="ll"}, +[11557] = {category="ll"}, +[11559] = {category="ll"}, +[11565] = {category="ll"}, +[11568] = {category="lo"}, +[11569] = {category="lo"}, +[11570] = {category="lo"}, +[11571] = {category="lo"}, +[11572] = {category="lo"}, +[11573] = {category="lo"}, +[11574] = {category="lo"}, +[11575] = {category="lo"}, +[11576] = {category="lo"}, +[11577] = {category="lo"}, +[11578] = {category="lo"}, +[11579] = {category="lo"}, +[11580] = {category="lo"}, +[11581] = {category="lo"}, +[11582] = {category="lo"}, +[11583] = {category="lo"}, +[11584] = {category="lo"}, +[11585] = {category="lo"}, +[11586] = {category="lo"}, +[11587] = {category="lo"}, +[11588] = {category="lo"}, +[11589] = {category="lo"}, +[11590] = {category="lo"}, +[11591] = {category="lo"}, +[11592] = {category="lo"}, +[11593] = {category="lo"}, +[11594] = {category="lo"}, +[11595] = {category="lo"}, +[11596] = {category="lo"}, +[11597] = {category="lo"}, +[11598] = {category="lo"}, +[11599] = {category="lo"}, +[11600] = {category="lo"}, +[11601] = {category="lo"}, +[11602] = {category="lo"}, +[11603] = {category="lo"}, +[11604] = {category="lo"}, +[11605] = {category="lo"}, +[11606] = {category="lo"}, +[11607] = {category="lo"}, +[11608] = {category="lo"}, +[11609] = {category="lo"}, +[11610] = {category="lo"}, +[11611] = {category="lo"}, +[11612] = {category="lo"}, +[11613] = {category="lo"}, +[11614] = {category="lo"}, +[11615] = {category="lo"}, +[11616] = {category="lo"}, +[11617] = {category="lo"}, +[11618] = {category="lo"}, +[11619] = {category="lo"}, +[11620] = {category="lo"}, +[11621] = {category="lo"}, +[11622] = {category="lo"}, +[11623] = {category="lo"}, +[11631] = {category="lm", shcode=14}, +[11648] = {category="lo"}, +[11649] = {category="lo"}, +[11650] = {category="lo"}, +[11651] = {category="lo"}, +[11652] = {category="lo"}, +[11653] = {category="lo"}, +[11654] = {category="lo"}, +[11655] = {category="lo"}, +[11656] = {category="lo"}, +[11657] = {category="lo"}, +[11658] = {category="lo"}, +[11659] = {category="lo"}, +[11660] = {category="lo"}, +[11661] = {category="lo"}, +[11662] = {category="lo"}, +[11663] = {category="lo"}, +[11664] = {category="lo"}, +[11665] = {category="lo"}, +[11666] = {category="lo"}, +[11667] = {category="lo"}, +[11668] = {category="lo"}, +[11669] = {category="lo"}, +[11670] = {category="lo"}, +[11680] = {category="lo"}, +[11681] = {category="lo"}, +[11682] = {category="lo"}, +[11683] = {category="lo"}, +[11684] = {category="lo"}, +[11685] = {category="lo"}, +[11686] = {category="lo"}, +[11688] = {category="lo"}, +[11689] = {category="lo"}, +[11690] = {category="lo"}, +[11691] = {category="lo"}, +[11692] = {category="lo"}, +[11693] = {category="lo"}, +[11694] = {category="lo"}, +[11696] = {category="lo"}, +[11697] = {category="lo"}, +[11698] = {category="lo"}, +[11699] = {category="lo"}, +[11700] = {category="lo"}, +[11701] = {category="lo"}, +[11702] = {category="lo"}, +[11704] = {category="lo"}, +[11705] = {category="lo"}, +[11706] = {category="lo"}, +[11707] = {category="lo"}, +[11708] = {category="lo"}, +[11709] = {category="lo"}, +[11710] = {category="lo"}, +[11712] = {category="lo"}, +[11713] = {category="lo"}, +[11714] = {category="lo"}, +[11715] = {category="lo"}, +[11716] = {category="lo"}, +[11717] = {category="lo"}, +[11718] = {category="lo"}, +[11720] = {category="lo"}, +[11721] = {category="lo"}, +[11722] = {category="lo"}, +[11723] = {category="lo"}, +[11724] = {category="lo"}, +[11725] = {category="lo"}, +[11726] = {category="lo"}, +[11728] = {category="lo"}, +[11729] = {category="lo"}, +[11730] = {category="lo"}, +[11731] = {category="lo"}, +[11732] = {category="lo"}, +[11733] = {category="lo"}, +[11734] = {category="lo"}, +[11736] = {category="lo"}, +[11737] = {category="lo"}, +[11738] = {category="lo"}, +[11739] = {category="lo"}, +[11740] = {category="lo"}, +[11741] = {category="lo"}, +[11742] = {category="lo"}, +[11823] = {category="lm"}, +[12288] = {category="zs", shcode=222}, +[12293] = {category="lm"}, +[12294] = {category="lo"}, +[12337] = {category="lm"}, +[12338] = {category="lm"}, +[12339] = {category="lm"}, +[12340] = {category="lm"}, +[12341] = {category="lm"}, +[12347] = {category="lm"}, +[12348] = {category="lo"}, +[12353] = {category="lo"}, +[12354] = {category="lo"}, +[12355] = {category="lo"}, +[12356] = {category="lo"}, +[12357] = {category="lo"}, +[12358] = {category="lo"}, +[12359] = {category="lo"}, +[12360] = {category="lo"}, +[12361] = {category="lo"}, +[12362] = {category="lo"}, +[12363] = {category="lo"}, +[12364] = {category="lo", shcode=12363}, +[12365] = {category="lo"}, +[12366] = {category="lo", shcode=12365}, +[12367] = {category="lo"}, +[12368] = {category="lo", shcode=12367}, +[12369] = {category="lo"}, +[12370] = {category="lo", shcode=12369}, +[12371] = {category="lo"}, +[12372] = {category="lo", shcode=12371}, +[12373] = {category="lo"}, +[12374] = {category="lo", shcode=12373}, +[12375] = {category="lo"}, +[12376] = {category="lo", shcode=12375}, +[12377] = {category="lo"}, +[12378] = {category="lo", shcode=12377}, +[12379] = {category="lo"}, +[12380] = {category="lo", shcode=12379}, +[12381] = {category="lo"}, +[12382] = {category="lo", shcode=12381}, +[12383] = {category="lo"}, +[12384] = {category="lo", shcode=12383}, +[12385] = {category="lo"}, +[12386] = {category="lo", shcode=12385}, +[12387] = {category="lo"}, +[12388] = {category="lo"}, +[12389] = {category="lo", shcode=12388}, +[12390] = {category="lo"}, +[12391] = {category="lo", shcode=12390}, +[12392] = {category="lo"}, +[12393] = {category="lo", shcode=12392}, +[12394] = {category="lo"}, +[12395] = {category="lo"}, +[12396] = {category="lo"}, +[12397] = {category="lo"}, +[12398] = {category="lo"}, +[12399] = {category="lo"}, +[12400] = {category="lo", shcode=12399}, +[12401] = {category="lo", shcode=12399}, +[12402] = {category="lo"}, +[12403] = {category="lo", shcode=12402}, +[12404] = {category="lo", shcode=12402}, +[12405] = {category="lo"}, +[12406] = {category="lo", shcode=12405}, +[12407] = {category="lo", shcode=12405}, +[12408] = {category="lo"}, +[12409] = {category="lo", shcode=12408}, +[12410] = {category="lo", shcode=12408}, +[12411] = {category="lo"}, +[12412] = {category="lo", shcode=12411}, +[12413] = {category="lo", shcode=12411}, +[12414] = {category="lo"}, +[12415] = {category="lo"}, +[12416] = {category="lo"}, +[12417] = {category="lo"}, +[12418] = {category="lo"}, +[12419] = {category="lo"}, +[12420] = {category="lo"}, +[12421] = {category="lo"}, +[12422] = {category="lo"}, +[12423] = {category="lo"}, +[12424] = {category="lo"}, +[12425] = {category="lo"}, +[12426] = {category="lo"}, +[12427] = {category="lo"}, +[12428] = {category="lo"}, +[12429] = {category="lo"}, +[12430] = {category="lo"}, +[12431] = {category="lo"}, +[12432] = {category="lo"}, +[12433] = {category="lo"}, +[12434] = {category="lo"}, +[12435] = {category="lo"}, +[12436] = {category="lo", shcode=12358}, +[12437] = {category="lo"}, +[12438] = {category="lo"}, +[12445] = {category="lm"}, +[12446] = {category="lm", shcode=12445}, +[12447] = {category="lo", shcode=14}, +[12449] = {category="lo"}, +[12450] = {category="lo"}, +[12451] = {category="lo"}, +[12452] = {category="lo"}, +[12453] = {category="lo"}, +[12454] = {category="lo"}, +[12455] = {category="lo"}, +[12456] = {category="lo"}, +[12457] = {category="lo"}, +[12458] = {category="lo"}, +[12459] = {category="lo"}, +[12460] = {category="lo", shcode=12459}, +[12461] = {category="lo"}, +[12462] = {category="lo", shcode=12461}, +[12463] = {category="lo"}, +[12464] = {category="lo", shcode=12463}, +[12465] = {category="lo"}, +[12466] = {category="lo", shcode=12465}, +[12467] = {category="lo"}, +[12468] = {category="lo", shcode=12467}, +[12469] = {category="lo"}, +[12470] = {category="lo", shcode=12469}, +[12471] = {category="lo"}, +[12472] = {category="lo", shcode=12471}, +[12473] = {category="lo"}, +[12474] = {category="lo", shcode=12473}, +[12475] = {category="lo"}, +[12476] = {category="lo", shcode=12475}, +[12477] = {category="lo"}, +[12478] = {category="lo", shcode=12477}, +[12479] = {category="lo"}, +[12480] = {category="lo", shcode=12479}, +[12481] = {category="lo"}, +[12482] = {category="lo", shcode=12481}, +[12483] = {category="lo"}, +[12484] = {category="lo"}, +[12485] = {category="lo", shcode=12484}, +[12486] = {category="lo"}, +[12487] = {category="lo", shcode=12486}, +[12488] = {category="lo"}, +[12489] = {category="lo", shcode=12488}, +[12490] = {category="lo"}, +[12491] = {category="lo"}, +[12492] = {category="lo"}, +[12493] = {category="lo"}, +[12494] = {category="lo"}, +[12495] = {category="lo"}, +[12496] = {category="lo", shcode=12495}, +[12497] = {category="lo", shcode=12495}, +[12498] = {category="lo"}, +[12499] = {category="lo", shcode=12498}, +[12500] = {category="lo", shcode=12498}, +[12501] = {category="lo"}, +[12502] = {category="lo", shcode=12501}, +[12503] = {category="lo", shcode=12501}, +[12504] = {category="lo"}, +[12505] = {category="lo", shcode=12504}, +[12506] = {category="lo", shcode=12504}, +[12507] = {category="lo"}, +[12508] = {category="lo", shcode=12507}, +[12509] = {category="lo", shcode=12507}, +[12510] = {category="lo"}, +[12511] = {category="lo"}, +[12512] = {category="lo"}, +[12513] = {category="lo"}, +[12514] = {category="lo"}, +[12515] = {category="lo"}, +[12516] = {category="lo"}, +[12517] = {category="lo"}, +[12518] = {category="lo"}, +[12519] = {category="lo"}, +[12520] = {category="lo"}, +[12521] = {category="lo"}, +[12522] = {category="lo"}, +[12523] = {category="lo"}, +[12524] = {category="lo"}, +[12525] = {category="lo"}, +[12526] = {category="lo"}, +[12527] = {category="lo"}, +[12528] = {category="lo"}, +[12529] = {category="lo"}, +[12530] = {category="lo"}, +[12531] = {category="lo"}, +[12532] = {category="lo", shcode=12454}, +[12533] = {category="lo"}, +[12534] = {category="lo"}, +[12535] = {category="lo", shcode=12527}, +[12536] = {category="lo", shcode=12528}, +[12537] = {category="lo", shcode=12529}, +[12538] = {category="lo", shcode=12530}, +[12540] = {category="lm"}, +[12541] = {category="lm"}, +[12542] = {category="lm", shcode=12541}, +[12543] = {category="lo", shcode=14}, +[12549] = {category="lo"}, +[12550] = {category="lo"}, +[12551] = {category="lo"}, +[12552] = {category="lo"}, +[12553] = {category="lo"}, +[12554] = {category="lo"}, +[12555] = {category="lo"}, +[12556] = {category="lo"}, +[12557] = {category="lo"}, +[12558] = {category="lo"}, +[12559] = {category="lo"}, +[12560] = {category="lo"}, +[12561] = {category="lo"}, +[12562] = {category="lo"}, +[12563] = {category="lo"}, +[12564] = {category="lo"}, +[12565] = {category="lo"}, +[12566] = {category="lo"}, +[12567] = {category="lo"}, +[12568] = {category="lo"}, +[12569] = {category="lo"}, +[12570] = {category="lo"}, +[12571] = {category="lo"}, +[12572] = {category="lo"}, +[12573] = {category="lo"}, +[12574] = {category="lo"}, +[12575] = {category="lo"}, +[12576] = {category="lo"}, +[12577] = {category="lo"}, +[12578] = {category="lo"}, +[12579] = {category="lo"}, +[12580] = {category="lo"}, +[12581] = {category="lo"}, +[12582] = {category="lo"}, +[12583] = {category="lo"}, +[12584] = {category="lo"}, +[12585] = {category="lo"}, +[12586] = {category="lo"}, +[12587] = {category="lo"}, +[12588] = {category="lo"}, +[12589] = {category="lo"}, +[12590] = {category="lo"}, +[12591] = {category="lo"}, +[12593] = {category="lo", shcode=12}, +[12594] = {category="lo", shcode=12}, +[12595] = {category="lo", shcode=12}, +[12596] = {category="lo", shcode=12}, +[12597] = {category="lo", shcode=12}, +[12598] = {category="lo", shcode=12}, +[12599] = {category="lo", shcode=12}, +[12600] = {category="lo", shcode=12}, +[12601] = {category="lo", shcode=12}, +[12602] = {category="lo", shcode=12}, +[12603] = {category="lo", shcode=12}, +[12604] = {category="lo", shcode=12}, +[12605] = {category="lo", shcode=12}, +[12606] = {category="lo", shcode=12}, +[12607] = {category="lo", shcode=12}, +[12608] = {category="lo", shcode=12}, +[12609] = {category="lo", shcode=12}, +[12610] = {category="lo", shcode=12}, +[12611] = {category="lo", shcode=12}, +[12612] = {category="lo", shcode=12}, +[12613] = {category="lo", shcode=12}, +[12614] = {category="lo", shcode=12}, +[12615] = {category="lo", shcode=12}, +[12616] = {category="lo", shcode=12}, +[12617] = {category="lo", shcode=12}, +[12618] = {category="lo", shcode=12}, +[12619] = {category="lo", shcode=12}, +[12620] = {category="lo", shcode=12}, +[12621] = {category="lo", shcode=12}, +[12622] = {category="lo", shcode=12}, +[12623] = {category="lo", shcode=12}, +[12624] = {category="lo", shcode=12}, +[12625] = {category="lo", shcode=12}, +[12626] = {category="lo", shcode=12}, +[12627] = {category="lo", shcode=12}, +[12628] = {category="lo", shcode=12}, +[12629] = {category="lo", shcode=12}, +[12630] = {category="lo", shcode=12}, +[12631] = {category="lo", shcode=12}, +[12632] = {category="lo", shcode=12}, +[12633] = {category="lo", shcode=12}, +[12634] = {category="lo", shcode=12}, +[12635] = {category="lo", shcode=12}, +[12636] = {category="lo", shcode=12}, +[12637] = {category="lo", shcode=12}, +[12638] = {category="lo", shcode=12}, +[12639] = {category="lo", shcode=12}, +[12640] = {category="lo", shcode=12}, +[12641] = {category="lo", shcode=12}, +[12642] = {category="lo", shcode=12}, +[12643] = {category="lo", shcode=12}, +[12644] = {category="lo", shcode=12}, +[12645] = {category="lo", shcode=12}, +[12646] = {category="lo", shcode=12}, +[12647] = {category="lo", shcode=12}, +[12648] = {category="lo", shcode=12}, +[12649] = {category="lo", shcode=12}, +[12650] = {category="lo", shcode=12}, +[12651] = {category="lo", shcode=12}, +[12652] = {category="lo", shcode=12}, +[12653] = {category="lo", shcode=12}, +[12654] = {category="lo", shcode=12}, +[12655] = {category="lo", shcode=12}, +[12656] = {category="lo", shcode=12}, +[12657] = {category="lo", shcode=12}, +[12658] = {category="lo", shcode=12}, +[12659] = {category="lo", shcode=12}, +[12660] = {category="lo", shcode=12}, +[12661] = {category="lo", shcode=12}, +[12662] = {category="lo", shcode=12}, +[12663] = {category="lo", shcode=12}, +[12664] = {category="lo", shcode=12}, +[12665] = {category="lo", shcode=12}, +[12666] = {category="lo", shcode=12}, +[12667] = {category="lo", shcode=12}, +[12668] = {category="lo", shcode=12}, +[12669] = {category="lo", shcode=12}, +[12670] = {category="lo", shcode=12}, +[12671] = {category="lo", shcode=12}, +[12672] = {category="lo", shcode=12}, +[12673] = {category="lo", shcode=12}, +[12674] = {category="lo", shcode=12}, +[12675] = {category="lo", shcode=12}, +[12676] = {category="lo", shcode=12}, +[12677] = {category="lo", shcode=12}, +[12678] = {category="lo", shcode=12}, +[12679] = {category="lo", shcode=12}, +[12680] = {category="lo", shcode=12}, +[12681] = {category="lo", shcode=12}, +[12682] = {category="lo", shcode=12}, +[12683] = {category="lo", shcode=12}, +[12684] = {category="lo", shcode=12}, +[12685] = {category="lo", shcode=12}, +[12686] = {category="lo", shcode=12}, +[12704] = {category="lo"}, +[12705] = {category="lo"}, +[12706] = {category="lo"}, +[12707] = {category="lo"}, +[12708] = {category="lo"}, +[12709] = {category="lo"}, +[12710] = {category="lo"}, +[12711] = {category="lo"}, +[12712] = {category="lo"}, +[12713] = {category="lo"}, +[12714] = {category="lo"}, +[12715] = {category="lo"}, +[12716] = {category="lo"}, +[12717] = {category="lo"}, +[12718] = {category="lo"}, +[12719] = {category="lo"}, +[12720] = {category="lo"}, +[12721] = {category="lo"}, +[12722] = {category="lo"}, +[12723] = {category="lo"}, +[12724] = {category="lo"}, +[12725] = {category="lo"}, +[12726] = {category="lo"}, +[12727] = {category="lo"}, +[12728] = {category="lo"}, +[12729] = {category="lo"}, +[12730] = {category="lo"}, +[12731] = {category="lo"}, +[12732] = {category="lo"}, +[12733] = {category="lo"}, +[12734] = {category="lo"}, +[12735] = {category="lo"}, +[12784] = {category="lo"}, +[12785] = {category="lo"}, +[12786] = {category="lo"}, +[12787] = {category="lo"}, +[12788] = {category="lo"}, +[12789] = {category="lo"}, +[12790] = {category="lo"}, +[12791] = {category="lo"}, +[12792] = {category="lo"}, +[12793] = {category="lo"}, +[12794] = {category="lo"}, +[12795] = {category="lo"}, +[12796] = {category="lo"}, +[12797] = {category="lo"}, +[12798] = {category="lo"}, +[12799] = {category="lo"}, +[13312] = {category="lo"}, +[19903] = {category="lo"}, +[19968] = {category="lo"}, +[40959] = {category="lo"}, +[40960] = {category="lo"}, +[40961] = {category="lo"}, +[40962] = {category="lo"}, +[40963] = {category="lo"}, +[40964] = {category="lo"}, +[40965] = {category="lo"}, +[40966] = {category="lo"}, +[40967] = {category="lo"}, +[40968] = {category="lo"}, +[40969] = {category="lo"}, +[40970] = {category="lo"}, +[40971] = {category="lo"}, +[40972] = {category="lo"}, +[40973] = {category="lo"}, +[40974] = {category="lo"}, +[40975] = {category="lo"}, +[40976] = {category="lo"}, +[40977] = {category="lo"}, +[40978] = {category="lo"}, +[40979] = {category="lo"}, +[40980] = {category="lo"}, +[40981] = {category="lm"}, +[40982] = {category="lo"}, +[40983] = {category="lo"}, +[40984] = {category="lo"}, +[40985] = {category="lo"}, +[40986] = {category="lo"}, +[40987] = {category="lo"}, +[40988] = {category="lo"}, +[40989] = {category="lo"}, +[40990] = {category="lo"}, +[40991] = {category="lo"}, +[40992] = {category="lo"}, +[40993] = {category="lo"}, +[40994] = {category="lo"}, +[40995] = {category="lo"}, +[40996] = {category="lo"}, +[40997] = {category="lo"}, +[40998] = {category="lo"}, +[40999] = {category="lo"}, +[41000] = {category="lo"}, +[41001] = {category="lo"}, +[41002] = {category="lo"}, +[41003] = {category="lo"}, +[41004] = {category="lo"}, +[41005] = {category="lo"}, +[41006] = {category="lo"}, +[41007] = {category="lo"}, +[41008] = {category="lo"}, +[41009] = {category="lo"}, +[41010] = {category="lo"}, +[41011] = {category="lo"}, +[41012] = {category="lo"}, +[41013] = {category="lo"}, +[41014] = {category="lo"}, +[41015] = {category="lo"}, +[41016] = {category="lo"}, +[41017] = {category="lo"}, +[41018] = {category="lo"}, +[41019] = {category="lo"}, +[41020] = {category="lo"}, +[41021] = {category="lo"}, +[41022] = {category="lo"}, +[41023] = {category="lo"}, +[41024] = {category="lo"}, +[41025] = {category="lo"}, +[41026] = {category="lo"}, +[41027] = {category="lo"}, +[41028] = {category="lo"}, +[41029] = {category="lo"}, +[41030] = {category="lo"}, +[41031] = {category="lo"}, +[41032] = {category="lo"}, +[41033] = {category="lo"}, +[41034] = {category="lo"}, +[41035] = {category="lo"}, +[41036] = {category="lo"}, +[41037] = {category="lo"}, +[41038] = {category="lo"}, +[41039] = {category="lo"}, +[41040] = {category="lo"}, +[41041] = {category="lo"}, +[41042] = {category="lo"}, +[41043] = {category="lo"}, +[41044] = {category="lo"}, +[41045] = {category="lo"}, +[41046] = {category="lo"}, +[41047] = {category="lo"}, +[41048] = {category="lo"}, +[41049] = {category="lo"}, +[41050] = {category="lo"}, +[41051] = {category="lo"}, +[41052] = {category="lo"}, +[41053] = {category="lo"}, +[41054] = {category="lo"}, +[41055] = {category="lo"}, +[41056] = {category="lo"}, +[41057] = {category="lo"}, +[41058] = {category="lo"}, +[41059] = {category="lo"}, +[41060] = {category="lo"}, +[41061] = {category="lo"}, +[41062] = {category="lo"}, +[41063] = {category="lo"}, +[41064] = {category="lo"}, +[41065] = {category="lo"}, +[41066] = {category="lo"}, +[41067] = {category="lo"}, +[41068] = {category="lo"}, +[41069] = {category="lo"}, +[41070] = {category="lo"}, +[41071] = {category="lo"}, +[41072] = {category="lo"}, +[41073] = {category="lo"}, +[41074] = {category="lo"}, +[41075] = {category="lo"}, +[41076] = {category="lo"}, +[41077] = {category="lo"}, +[41078] = {category="lo"}, +[41079] = {category="lo"}, +[41080] = {category="lo"}, +[41081] = {category="lo"}, +[41082] = {category="lo"}, +[41083] = {category="lo"}, +[41084] = {category="lo"}, +[41085] = {category="lo"}, +[41086] = {category="lo"}, +[41087] = {category="lo"}, +[41088] = {category="lo"}, +[41089] = {category="lo"}, +[41090] = {category="lo"}, +[41091] = {category="lo"}, +[41092] = {category="lo"}, +[41093] = {category="lo"}, +[41094] = {category="lo"}, +[41095] = {category="lo"}, +[41096] = {category="lo"}, +[41097] = {category="lo"}, +[41098] = {category="lo"}, +[41099] = {category="lo"}, +[41100] = {category="lo"}, +[41101] = {category="lo"}, +[41102] = {category="lo"}, +[41103] = {category="lo"}, +[41104] = {category="lo"}, +[41105] = {category="lo"}, +[41106] = {category="lo"}, +[41107] = {category="lo"}, +[41108] = {category="lo"}, +[41109] = {category="lo"}, +[41110] = {category="lo"}, +[41111] = {category="lo"}, +[41112] = {category="lo"}, +[41113] = {category="lo"}, +[41114] = {category="lo"}, +[41115] = {category="lo"}, +[41116] = {category="lo"}, +[41117] = {category="lo"}, +[41118] = {category="lo"}, +[41119] = {category="lo"}, +[41120] = {category="lo"}, +[41121] = {category="lo"}, +[41122] = {category="lo"}, +[41123] = {category="lo"}, +[41124] = {category="lo"}, +[41125] = {category="lo"}, +[41126] = {category="lo"}, +[41127] = {category="lo"}, +[41128] = {category="lo"}, +[41129] = {category="lo"}, +[41130] = {category="lo"}, +[41131] = {category="lo"}, +[41132] = {category="lo"}, +[41133] = {category="lo"}, +[41134] = {category="lo"}, +[41135] = {category="lo"}, +[41136] = {category="lo"}, +[41137] = {category="lo"}, +[41138] = {category="lo"}, +[41139] = {category="lo"}, +[41140] = {category="lo"}, +[41141] = {category="lo"}, +[41142] = {category="lo"}, +[41143] = {category="lo"}, +[41144] = {category="lo"}, +[41145] = {category="lo"}, +[41146] = {category="lo"}, +[41147] = {category="lo"}, +[41148] = {category="lo"}, +[41149] = {category="lo"}, +[41150] = {category="lo"}, +[41151] = {category="lo"}, +[41152] = {category="lo"}, +[41153] = {category="lo"}, +[41154] = {category="lo"}, +[41155] = {category="lo"}, +[41156] = {category="lo"}, +[41157] = {category="lo"}, +[41158] = {category="lo"}, +[41159] = {category="lo"}, +[41160] = {category="lo"}, +[41161] = {category="lo"}, +[41162] = {category="lo"}, +[41163] = {category="lo"}, +[41164] = {category="lo"}, +[41165] = {category="lo"}, +[41166] = {category="lo"}, +[41167] = {category="lo"}, +[41168] = {category="lo"}, +[41169] = {category="lo"}, +[41170] = {category="lo"}, +[41171] = {category="lo"}, +[41172] = {category="lo"}, +[41173] = {category="lo"}, +[41174] = {category="lo"}, +[41175] = {category="lo"}, +[41176] = {category="lo"}, +[41177] = {category="lo"}, +[41178] = {category="lo"}, +[41179] = {category="lo"}, +[41180] = {category="lo"}, +[41181] = {category="lo"}, +[41182] = {category="lo"}, +[41183] = {category="lo"}, +[41184] = {category="lo"}, +[41185] = {category="lo"}, +[41186] = {category="lo"}, +[41187] = {category="lo"}, +[41188] = {category="lo"}, +[41189] = {category="lo"}, +[41190] = {category="lo"}, +[41191] = {category="lo"}, +[41192] = {category="lo"}, +[41193] = {category="lo"}, +[41194] = {category="lo"}, +[41195] = {category="lo"}, +[41196] = {category="lo"}, +[41197] = {category="lo"}, +[41198] = {category="lo"}, +[41199] = {category="lo"}, +[41200] = {category="lo"}, +[41201] = {category="lo"}, +[41202] = {category="lo"}, +[41203] = {category="lo"}, +[41204] = {category="lo"}, +[41205] = {category="lo"}, +[41206] = {category="lo"}, +[41207] = {category="lo"}, +[41208] = {category="lo"}, +[41209] = {category="lo"}, +[41210] = {category="lo"}, +[41211] = {category="lo"}, +[41212] = {category="lo"}, +[41213] = {category="lo"}, +[41214] = {category="lo"}, +[41215] = {category="lo"}, +[41216] = {category="lo"}, +[41217] = {category="lo"}, +[41218] = {category="lo"}, +[41219] = {category="lo"}, +[41220] = {category="lo"}, +[41221] = {category="lo"}, +[41222] = {category="lo"}, +[41223] = {category="lo"}, +[41224] = {category="lo"}, +[41225] = {category="lo"}, +[41226] = {category="lo"}, +[41227] = {category="lo"}, +[41228] = {category="lo"}, +[41229] = {category="lo"}, +[41230] = {category="lo"}, +[41231] = {category="lo"}, +[41232] = {category="lo"}, +[41233] = {category="lo"}, +[41234] = {category="lo"}, +[41235] = {category="lo"}, +[41236] = {category="lo"}, +[41237] = {category="lo"}, +[41238] = {category="lo"}, +[41239] = {category="lo"}, +[41240] = {category="lo"}, +[41241] = {category="lo"}, +[41242] = {category="lo"}, +[41243] = {category="lo"}, +[41244] = {category="lo"}, +[41245] = {category="lo"}, +[41246] = {category="lo"}, +[41247] = {category="lo"}, +[41248] = {category="lo"}, +[41249] = {category="lo"}, +[41250] = {category="lo"}, +[41251] = {category="lo"}, +[41252] = {category="lo"}, +[41253] = {category="lo"}, +[41254] = {category="lo"}, +[41255] = {category="lo"}, +[41256] = {category="lo"}, +[41257] = {category="lo"}, +[41258] = {category="lo"}, +[41259] = {category="lo"}, +[41260] = {category="lo"}, +[41261] = {category="lo"}, +[41262] = {category="lo"}, +[41263] = {category="lo"}, +[41264] = {category="lo"}, +[41265] = {category="lo"}, +[41266] = {category="lo"}, +[41267] = {category="lo"}, +[41268] = {category="lo"}, +[41269] = {category="lo"}, +[41270] = {category="lo"}, +[41271] = {category="lo"}, +[41272] = {category="lo"}, +[41273] = {category="lo"}, +[41274] = {category="lo"}, +[41275] = {category="lo"}, +[41276] = {category="lo"}, +[41277] = {category="lo"}, +[41278] = {category="lo"}, +[41279] = {category="lo"}, +[41280] = {category="lo"}, +[41281] = {category="lo"}, +[41282] = {category="lo"}, +[41283] = {category="lo"}, +[41284] = {category="lo"}, +[41285] = {category="lo"}, +[41286] = {category="lo"}, +[41287] = {category="lo"}, +[41288] = {category="lo"}, +[41289] = {category="lo"}, +[41290] = {category="lo"}, +[41291] = {category="lo"}, +[41292] = {category="lo"}, +[41293] = {category="lo"}, +[41294] = {category="lo"}, +[41295] = {category="lo"}, +[41296] = {category="lo"}, +[41297] = {category="lo"}, +[41298] = {category="lo"}, +[41299] = {category="lo"}, +[41300] = {category="lo"}, +[41301] = {category="lo"}, +[41302] = {category="lo"}, +[41303] = {category="lo"}, +[41304] = {category="lo"}, +[41305] = {category="lo"}, +[41306] = {category="lo"}, +[41307] = {category="lo"}, +[41308] = {category="lo"}, +[41309] = {category="lo"}, +[41310] = {category="lo"}, +[41311] = {category="lo"}, +[41312] = {category="lo"}, +[41313] = {category="lo"}, +[41314] = {category="lo"}, +[41315] = {category="lo"}, +[41316] = {category="lo"}, +[41317] = {category="lo"}, +[41318] = {category="lo"}, +[41319] = {category="lo"}, +[41320] = {category="lo"}, +[41321] = {category="lo"}, +[41322] = {category="lo"}, +[41323] = {category="lo"}, +[41324] = {category="lo"}, +[41325] = {category="lo"}, +[41326] = {category="lo"}, +[41327] = {category="lo"}, +[41328] = {category="lo"}, +[41329] = {category="lo"}, +[41330] = {category="lo"}, +[41331] = {category="lo"}, +[41332] = {category="lo"}, +[41333] = {category="lo"}, +[41334] = {category="lo"}, +[41335] = {category="lo"}, +[41336] = {category="lo"}, +[41337] = {category="lo"}, +[41338] = {category="lo"}, +[41339] = {category="lo"}, +[41340] = {category="lo"}, +[41341] = {category="lo"}, +[41342] = {category="lo"}, +[41343] = {category="lo"}, +[41344] = {category="lo"}, +[41345] = {category="lo"}, +[41346] = {category="lo"}, +[41347] = {category="lo"}, +[41348] = {category="lo"}, +[41349] = {category="lo"}, +[41350] = {category="lo"}, +[41351] = {category="lo"}, +[41352] = {category="lo"}, +[41353] = {category="lo"}, +[41354] = {category="lo"}, +[41355] = {category="lo"}, +[41356] = {category="lo"}, +[41357] = {category="lo"}, +[41358] = {category="lo"}, +[41359] = {category="lo"}, +[41360] = {category="lo"}, +[41361] = {category="lo"}, +[41362] = {category="lo"}, +[41363] = {category="lo"}, +[41364] = {category="lo"}, +[41365] = {category="lo"}, +[41366] = {category="lo"}, +[41367] = {category="lo"}, +[41368] = {category="lo"}, +[41369] = {category="lo"}, +[41370] = {category="lo"}, +[41371] = {category="lo"}, +[41372] = {category="lo"}, +[41373] = {category="lo"}, +[41374] = {category="lo"}, +[41375] = {category="lo"}, +[41376] = {category="lo"}, +[41377] = {category="lo"}, +[41378] = {category="lo"}, +[41379] = {category="lo"}, +[41380] = {category="lo"}, +[41381] = {category="lo"}, +[41382] = {category="lo"}, +[41383] = {category="lo"}, +[41384] = {category="lo"}, +[41385] = {category="lo"}, +[41386] = {category="lo"}, +[41387] = {category="lo"}, +[41388] = {category="lo"}, +[41389] = {category="lo"}, +[41390] = {category="lo"}, +[41391] = {category="lo"}, +[41392] = {category="lo"}, +[41393] = {category="lo"}, +[41394] = {category="lo"}, +[41395] = {category="lo"}, +[41396] = {category="lo"}, +[41397] = {category="lo"}, +[41398] = {category="lo"}, +[41399] = {category="lo"}, +[41400] = {category="lo"}, +[41401] = {category="lo"}, +[41402] = {category="lo"}, +[41403] = {category="lo"}, +[41404] = {category="lo"}, +[41405] = {category="lo"}, +[41406] = {category="lo"}, +[41407] = {category="lo"}, +[41408] = {category="lo"}, +[41409] = {category="lo"}, +[41410] = {category="lo"}, +[41411] = {category="lo"}, +[41412] = {category="lo"}, +[41413] = {category="lo"}, +[41414] = {category="lo"}, +[41415] = {category="lo"}, +[41416] = {category="lo"}, +[41417] = {category="lo"}, +[41418] = {category="lo"}, +[41419] = {category="lo"}, +[41420] = {category="lo"}, +[41421] = {category="lo"}, +[41422] = {category="lo"}, +[41423] = {category="lo"}, +[41424] = {category="lo"}, +[41425] = {category="lo"}, +[41426] = {category="lo"}, +[41427] = {category="lo"}, +[41428] = {category="lo"}, +[41429] = {category="lo"}, +[41430] = {category="lo"}, +[41431] = {category="lo"}, +[41432] = {category="lo"}, +[41433] = {category="lo"}, +[41434] = {category="lo"}, +[41435] = {category="lo"}, +[41436] = {category="lo"}, +[41437] = {category="lo"}, +[41438] = {category="lo"}, +[41439] = {category="lo"}, +[41440] = {category="lo"}, +[41441] = {category="lo"}, +[41442] = {category="lo"}, +[41443] = {category="lo"}, +[41444] = {category="lo"}, +[41445] = {category="lo"}, +[41446] = {category="lo"}, +[41447] = {category="lo"}, +[41448] = {category="lo"}, +[41449] = {category="lo"}, +[41450] = {category="lo"}, +[41451] = {category="lo"}, +[41452] = {category="lo"}, +[41453] = {category="lo"}, +[41454] = {category="lo"}, +[41455] = {category="lo"}, +[41456] = {category="lo"}, +[41457] = {category="lo"}, +[41458] = {category="lo"}, +[41459] = {category="lo"}, +[41460] = {category="lo"}, +[41461] = {category="lo"}, +[41462] = {category="lo"}, +[41463] = {category="lo"}, +[41464] = {category="lo"}, +[41465] = {category="lo"}, +[41466] = {category="lo"}, +[41467] = {category="lo"}, +[41468] = {category="lo"}, +[41469] = {category="lo"}, +[41470] = {category="lo"}, +[41471] = {category="lo"}, +[41472] = {category="lo"}, +[41473] = {category="lo"}, +[41474] = {category="lo"}, +[41475] = {category="lo"}, +[41476] = {category="lo"}, +[41477] = {category="lo"}, +[41478] = {category="lo"}, +[41479] = {category="lo"}, +[41480] = {category="lo"}, +[41481] = {category="lo"}, +[41482] = {category="lo"}, +[41483] = {category="lo"}, +[41484] = {category="lo"}, +[41485] = {category="lo"}, +[41486] = {category="lo"}, +[41487] = {category="lo"}, +[41488] = {category="lo"}, +[41489] = {category="lo"}, +[41490] = {category="lo"}, +[41491] = {category="lo"}, +[41492] = {category="lo"}, +[41493] = {category="lo"}, +[41494] = {category="lo"}, +[41495] = {category="lo"}, +[41496] = {category="lo"}, +[41497] = {category="lo"}, +[41498] = {category="lo"}, +[41499] = {category="lo"}, +[41500] = {category="lo"}, +[41501] = {category="lo"}, +[41502] = {category="lo"}, +[41503] = {category="lo"}, +[41504] = {category="lo"}, +[41505] = {category="lo"}, +[41506] = {category="lo"}, +[41507] = {category="lo"}, +[41508] = {category="lo"}, +[41509] = {category="lo"}, +[41510] = {category="lo"}, +[41511] = {category="lo"}, +[41512] = {category="lo"}, +[41513] = {category="lo"}, +[41514] = {category="lo"}, +[41515] = {category="lo"}, +[41516] = {category="lo"}, +[41517] = {category="lo"}, +[41518] = {category="lo"}, +[41519] = {category="lo"}, +[41520] = {category="lo"}, +[41521] = {category="lo"}, +[41522] = {category="lo"}, +[41523] = {category="lo"}, +[41524] = {category="lo"}, +[41525] = {category="lo"}, +[41526] = {category="lo"}, +[41527] = {category="lo"}, +[41528] = {category="lo"}, +[41529] = {category="lo"}, +[41530] = {category="lo"}, +[41531] = {category="lo"}, +[41532] = {category="lo"}, +[41533] = {category="lo"}, +[41534] = {category="lo"}, +[41535] = {category="lo"}, +[41536] = {category="lo"}, +[41537] = {category="lo"}, +[41538] = {category="lo"}, +[41539] = {category="lo"}, +[41540] = {category="lo"}, +[41541] = {category="lo"}, +[41542] = {category="lo"}, +[41543] = {category="lo"}, +[41544] = {category="lo"}, +[41545] = {category="lo"}, +[41546] = {category="lo"}, +[41547] = {category="lo"}, +[41548] = {category="lo"}, +[41549] = {category="lo"}, +[41550] = {category="lo"}, +[41551] = {category="lo"}, +[41552] = {category="lo"}, +[41553] = {category="lo"}, +[41554] = {category="lo"}, +[41555] = {category="lo"}, +[41556] = {category="lo"}, +[41557] = {category="lo"}, +[41558] = {category="lo"}, +[41559] = {category="lo"}, +[41560] = {category="lo"}, +[41561] = {category="lo"}, +[41562] = {category="lo"}, +[41563] = {category="lo"}, +[41564] = {category="lo"}, +[41565] = {category="lo"}, +[41566] = {category="lo"}, +[41567] = {category="lo"}, +[41568] = {category="lo"}, +[41569] = {category="lo"}, +[41570] = {category="lo"}, +[41571] = {category="lo"}, +[41572] = {category="lo"}, +[41573] = {category="lo"}, +[41574] = {category="lo"}, +[41575] = {category="lo"}, +[41576] = {category="lo"}, +[41577] = {category="lo"}, +[41578] = {category="lo"}, +[41579] = {category="lo"}, +[41580] = {category="lo"}, +[41581] = {category="lo"}, +[41582] = {category="lo"}, +[41583] = {category="lo"}, +[41584] = {category="lo"}, +[41585] = {category="lo"}, +[41586] = {category="lo"}, +[41587] = {category="lo"}, +[41588] = {category="lo"}, +[41589] = {category="lo"}, +[41590] = {category="lo"}, +[41591] = {category="lo"}, +[41592] = {category="lo"}, +[41593] = {category="lo"}, +[41594] = {category="lo"}, +[41595] = {category="lo"}, +[41596] = {category="lo"}, +[41597] = {category="lo"}, +[41598] = {category="lo"}, +[41599] = {category="lo"}, +[41600] = {category="lo"}, +[41601] = {category="lo"}, +[41602] = {category="lo"}, +[41603] = {category="lo"}, +[41604] = {category="lo"}, +[41605] = {category="lo"}, +[41606] = {category="lo"}, +[41607] = {category="lo"}, +[41608] = {category="lo"}, +[41609] = {category="lo"}, +[41610] = {category="lo"}, +[41611] = {category="lo"}, +[41612] = {category="lo"}, +[41613] = {category="lo"}, +[41614] = {category="lo"}, +[41615] = {category="lo"}, +[41616] = {category="lo"}, +[41617] = {category="lo"}, +[41618] = {category="lo"}, +[41619] = {category="lo"}, +[41620] = {category="lo"}, +[41621] = {category="lo"}, +[41622] = {category="lo"}, +[41623] = {category="lo"}, +[41624] = {category="lo"}, +[41625] = {category="lo"}, +[41626] = {category="lo"}, +[41627] = {category="lo"}, +[41628] = {category="lo"}, +[41629] = {category="lo"}, +[41630] = {category="lo"}, +[41631] = {category="lo"}, +[41632] = {category="lo"}, +[41633] = {category="lo"}, +[41634] = {category="lo"}, +[41635] = {category="lo"}, +[41636] = {category="lo"}, +[41637] = {category="lo"}, +[41638] = {category="lo"}, +[41639] = {category="lo"}, +[41640] = {category="lo"}, +[41641] = {category="lo"}, +[41642] = {category="lo"}, +[41643] = {category="lo"}, +[41644] = {category="lo"}, +[41645] = {category="lo"}, +[41646] = {category="lo"}, +[41647] = {category="lo"}, +[41648] = {category="lo"}, +[41649] = {category="lo"}, +[41650] = {category="lo"}, +[41651] = {category="lo"}, +[41652] = {category="lo"}, +[41653] = {category="lo"}, +[41654] = {category="lo"}, +[41655] = {category="lo"}, +[41656] = {category="lo"}, +[41657] = {category="lo"}, +[41658] = {category="lo"}, +[41659] = {category="lo"}, +[41660] = {category="lo"}, +[41661] = {category="lo"}, +[41662] = {category="lo"}, +[41663] = {category="lo"}, +[41664] = {category="lo"}, +[41665] = {category="lo"}, +[41666] = {category="lo"}, +[41667] = {category="lo"}, +[41668] = {category="lo"}, +[41669] = {category="lo"}, +[41670] = {category="lo"}, +[41671] = {category="lo"}, +[41672] = {category="lo"}, +[41673] = {category="lo"}, +[41674] = {category="lo"}, +[41675] = {category="lo"}, +[41676] = {category="lo"}, +[41677] = {category="lo"}, +[41678] = {category="lo"}, +[41679] = {category="lo"}, +[41680] = {category="lo"}, +[41681] = {category="lo"}, +[41682] = {category="lo"}, +[41683] = {category="lo"}, +[41684] = {category="lo"}, +[41685] = {category="lo"}, +[41686] = {category="lo"}, +[41687] = {category="lo"}, +[41688] = {category="lo"}, +[41689] = {category="lo"}, +[41690] = {category="lo"}, +[41691] = {category="lo"}, +[41692] = {category="lo"}, +[41693] = {category="lo"}, +[41694] = {category="lo"}, +[41695] = {category="lo"}, +[41696] = {category="lo"}, +[41697] = {category="lo"}, +[41698] = {category="lo"}, +[41699] = {category="lo"}, +[41700] = {category="lo"}, +[41701] = {category="lo"}, +[41702] = {category="lo"}, +[41703] = {category="lo"}, +[41704] = {category="lo"}, +[41705] = {category="lo"}, +[41706] = {category="lo"}, +[41707] = {category="lo"}, +[41708] = {category="lo"}, +[41709] = {category="lo"}, +[41710] = {category="lo"}, +[41711] = {category="lo"}, +[41712] = {category="lo"}, +[41713] = {category="lo"}, +[41714] = {category="lo"}, +[41715] = {category="lo"}, +[41716] = {category="lo"}, +[41717] = {category="lo"}, +[41718] = {category="lo"}, +[41719] = {category="lo"}, +[41720] = {category="lo"}, +[41721] = {category="lo"}, +[41722] = {category="lo"}, +[41723] = {category="lo"}, +[41724] = {category="lo"}, +[41725] = {category="lo"}, +[41726] = {category="lo"}, +[41727] = {category="lo"}, +[41728] = {category="lo"}, +[41729] = {category="lo"}, +[41730] = {category="lo"}, +[41731] = {category="lo"}, +[41732] = {category="lo"}, +[41733] = {category="lo"}, +[41734] = {category="lo"}, +[41735] = {category="lo"}, +[41736] = {category="lo"}, +[41737] = {category="lo"}, +[41738] = {category="lo"}, +[41739] = {category="lo"}, +[41740] = {category="lo"}, +[41741] = {category="lo"}, +[41742] = {category="lo"}, +[41743] = {category="lo"}, +[41744] = {category="lo"}, +[41745] = {category="lo"}, +[41746] = {category="lo"}, +[41747] = {category="lo"}, +[41748] = {category="lo"}, +[41749] = {category="lo"}, +[41750] = {category="lo"}, +[41751] = {category="lo"}, +[41752] = {category="lo"}, +[41753] = {category="lo"}, +[41754] = {category="lo"}, +[41755] = {category="lo"}, +[41756] = {category="lo"}, +[41757] = {category="lo"}, +[41758] = {category="lo"}, +[41759] = {category="lo"}, +[41760] = {category="lo"}, +[41761] = {category="lo"}, +[41762] = {category="lo"}, +[41763] = {category="lo"}, +[41764] = {category="lo"}, +[41765] = {category="lo"}, +[41766] = {category="lo"}, +[41767] = {category="lo"}, +[41768] = {category="lo"}, +[41769] = {category="lo"}, +[41770] = {category="lo"}, +[41771] = {category="lo"}, +[41772] = {category="lo"}, +[41773] = {category="lo"}, +[41774] = {category="lo"}, +[41775] = {category="lo"}, +[41776] = {category="lo"}, +[41777] = {category="lo"}, +[41778] = {category="lo"}, +[41779] = {category="lo"}, +[41780] = {category="lo"}, +[41781] = {category="lo"}, +[41782] = {category="lo"}, +[41783] = {category="lo"}, +[41784] = {category="lo"}, +[41785] = {category="lo"}, +[41786] = {category="lo"}, +[41787] = {category="lo"}, +[41788] = {category="lo"}, +[41789] = {category="lo"}, +[41790] = {category="lo"}, +[41791] = {category="lo"}, +[41792] = {category="lo"}, +[41793] = {category="lo"}, +[41794] = {category="lo"}, +[41795] = {category="lo"}, +[41796] = {category="lo"}, +[41797] = {category="lo"}, +[41798] = {category="lo"}, +[41799] = {category="lo"}, +[41800] = {category="lo"}, +[41801] = {category="lo"}, +[41802] = {category="lo"}, +[41803] = {category="lo"}, +[41804] = {category="lo"}, +[41805] = {category="lo"}, +[41806] = {category="lo"}, +[41807] = {category="lo"}, +[41808] = {category="lo"}, +[41809] = {category="lo"}, +[41810] = {category="lo"}, +[41811] = {category="lo"}, +[41812] = {category="lo"}, +[41813] = {category="lo"}, +[41814] = {category="lo"}, +[41815] = {category="lo"}, +[41816] = {category="lo"}, +[41817] = {category="lo"}, +[41818] = {category="lo"}, +[41819] = {category="lo"}, +[41820] = {category="lo"}, +[41821] = {category="lo"}, +[41822] = {category="lo"}, +[41823] = {category="lo"}, +[41824] = {category="lo"}, +[41825] = {category="lo"}, +[41826] = {category="lo"}, +[41827] = {category="lo"}, +[41828] = {category="lo"}, +[41829] = {category="lo"}, +[41830] = {category="lo"}, +[41831] = {category="lo"}, +[41832] = {category="lo"}, +[41833] = {category="lo"}, +[41834] = {category="lo"}, +[41835] = {category="lo"}, +[41836] = {category="lo"}, +[41837] = {category="lo"}, +[41838] = {category="lo"}, +[41839] = {category="lo"}, +[41840] = {category="lo"}, +[41841] = {category="lo"}, +[41842] = {category="lo"}, +[41843] = {category="lo"}, +[41844] = {category="lo"}, +[41845] = {category="lo"}, +[41846] = {category="lo"}, +[41847] = {category="lo"}, +[41848] = {category="lo"}, +[41849] = {category="lo"}, +[41850] = {category="lo"}, +[41851] = {category="lo"}, +[41852] = {category="lo"}, +[41853] = {category="lo"}, +[41854] = {category="lo"}, +[41855] = {category="lo"}, +[41856] = {category="lo"}, +[41857] = {category="lo"}, +[41858] = {category="lo"}, +[41859] = {category="lo"}, +[41860] = {category="lo"}, +[41861] = {category="lo"}, +[41862] = {category="lo"}, +[41863] = {category="lo"}, +[41864] = {category="lo"}, +[41865] = {category="lo"}, +[41866] = {category="lo"}, +[41867] = {category="lo"}, +[41868] = {category="lo"}, +[41869] = {category="lo"}, +[41870] = {category="lo"}, +[41871] = {category="lo"}, +[41872] = {category="lo"}, +[41873] = {category="lo"}, +[41874] = {category="lo"}, +[41875] = {category="lo"}, +[41876] = {category="lo"}, +[41877] = {category="lo"}, +[41878] = {category="lo"}, +[41879] = {category="lo"}, +[41880] = {category="lo"}, +[41881] = {category="lo"}, +[41882] = {category="lo"}, +[41883] = {category="lo"}, +[41884] = {category="lo"}, +[41885] = {category="lo"}, +[41886] = {category="lo"}, +[41887] = {category="lo"}, +[41888] = {category="lo"}, +[41889] = {category="lo"}, +[41890] = {category="lo"}, +[41891] = {category="lo"}, +[41892] = {category="lo"}, +[41893] = {category="lo"}, +[41894] = {category="lo"}, +[41895] = {category="lo"}, +[41896] = {category="lo"}, +[41897] = {category="lo"}, +[41898] = {category="lo"}, +[41899] = {category="lo"}, +[41900] = {category="lo"}, +[41901] = {category="lo"}, +[41902] = {category="lo"}, +[41903] = {category="lo"}, +[41904] = {category="lo"}, +[41905] = {category="lo"}, +[41906] = {category="lo"}, +[41907] = {category="lo"}, +[41908] = {category="lo"}, +[41909] = {category="lo"}, +[41910] = {category="lo"}, +[41911] = {category="lo"}, +[41912] = {category="lo"}, +[41913] = {category="lo"}, +[41914] = {category="lo"}, +[41915] = {category="lo"}, +[41916] = {category="lo"}, +[41917] = {category="lo"}, +[41918] = {category="lo"}, +[41919] = {category="lo"}, +[41920] = {category="lo"}, +[41921] = {category="lo"}, +[41922] = {category="lo"}, +[41923] = {category="lo"}, +[41924] = {category="lo"}, +[41925] = {category="lo"}, +[41926] = {category="lo"}, +[41927] = {category="lo"}, +[41928] = {category="lo"}, +[41929] = {category="lo"}, +[41930] = {category="lo"}, +[41931] = {category="lo"}, +[41932] = {category="lo"}, +[41933] = {category="lo"}, +[41934] = {category="lo"}, +[41935] = {category="lo"}, +[41936] = {category="lo"}, +[41937] = {category="lo"}, +[41938] = {category="lo"}, +[41939] = {category="lo"}, +[41940] = {category="lo"}, +[41941] = {category="lo"}, +[41942] = {category="lo"}, +[41943] = {category="lo"}, +[41944] = {category="lo"}, +[41945] = {category="lo"}, +[41946] = {category="lo"}, +[41947] = {category="lo"}, +[41948] = {category="lo"}, +[41949] = {category="lo"}, +[41950] = {category="lo"}, +[41951] = {category="lo"}, +[41952] = {category="lo"}, +[41953] = {category="lo"}, +[41954] = {category="lo"}, +[41955] = {category="lo"}, +[41956] = {category="lo"}, +[41957] = {category="lo"}, +[41958] = {category="lo"}, +[41959] = {category="lo"}, +[41960] = {category="lo"}, +[41961] = {category="lo"}, +[41962] = {category="lo"}, +[41963] = {category="lo"}, +[41964] = {category="lo"}, +[41965] = {category="lo"}, +[41966] = {category="lo"}, +[41967] = {category="lo"}, +[41968] = {category="lo"}, +[41969] = {category="lo"}, +[41970] = {category="lo"}, +[41971] = {category="lo"}, +[41972] = {category="lo"}, +[41973] = {category="lo"}, +[41974] = {category="lo"}, +[41975] = {category="lo"}, +[41976] = {category="lo"}, +[41977] = {category="lo"}, +[41978] = {category="lo"}, +[41979] = {category="lo"}, +[41980] = {category="lo"}, +[41981] = {category="lo"}, +[41982] = {category="lo"}, +[41983] = {category="lo"}, +[41984] = {category="lo"}, +[41985] = {category="lo"}, +[41986] = {category="lo"}, +[41987] = {category="lo"}, +[41988] = {category="lo"}, +[41989] = {category="lo"}, +[41990] = {category="lo"}, +[41991] = {category="lo"}, +[41992] = {category="lo"}, +[41993] = {category="lo"}, +[41994] = {category="lo"}, +[41995] = {category="lo"}, +[41996] = {category="lo"}, +[41997] = {category="lo"}, +[41998] = {category="lo"}, +[41999] = {category="lo"}, +[42000] = {category="lo"}, +[42001] = {category="lo"}, +[42002] = {category="lo"}, +[42003] = {category="lo"}, +[42004] = {category="lo"}, +[42005] = {category="lo"}, +[42006] = {category="lo"}, +[42007] = {category="lo"}, +[42008] = {category="lo"}, +[42009] = {category="lo"}, +[42010] = {category="lo"}, +[42011] = {category="lo"}, +[42012] = {category="lo"}, +[42013] = {category="lo"}, +[42014] = {category="lo"}, +[42015] = {category="lo"}, +[42016] = {category="lo"}, +[42017] = {category="lo"}, +[42018] = {category="lo"}, +[42019] = {category="lo"}, +[42020] = {category="lo"}, +[42021] = {category="lo"}, +[42022] = {category="lo"}, +[42023] = {category="lo"}, +[42024] = {category="lo"}, +[42025] = {category="lo"}, +[42026] = {category="lo"}, +[42027] = {category="lo"}, +[42028] = {category="lo"}, +[42029] = {category="lo"}, +[42030] = {category="lo"}, +[42031] = {category="lo"}, +[42032] = {category="lo"}, +[42033] = {category="lo"}, +[42034] = {category="lo"}, +[42035] = {category="lo"}, +[42036] = {category="lo"}, +[42037] = {category="lo"}, +[42038] = {category="lo"}, +[42039] = {category="lo"}, +[42040] = {category="lo"}, +[42041] = {category="lo"}, +[42042] = {category="lo"}, +[42043] = {category="lo"}, +[42044] = {category="lo"}, +[42045] = {category="lo"}, +[42046] = {category="lo"}, +[42047] = {category="lo"}, +[42048] = {category="lo"}, +[42049] = {category="lo"}, +[42050] = {category="lo"}, +[42051] = {category="lo"}, +[42052] = {category="lo"}, +[42053] = {category="lo"}, +[42054] = {category="lo"}, +[42055] = {category="lo"}, +[42056] = {category="lo"}, +[42057] = {category="lo"}, +[42058] = {category="lo"}, +[42059] = {category="lo"}, +[42060] = {category="lo"}, +[42061] = {category="lo"}, +[42062] = {category="lo"}, +[42063] = {category="lo"}, +[42064] = {category="lo"}, +[42065] = {category="lo"}, +[42066] = {category="lo"}, +[42067] = {category="lo"}, +[42068] = {category="lo"}, +[42069] = {category="lo"}, +[42070] = {category="lo"}, +[42071] = {category="lo"}, +[42072] = {category="lo"}, +[42073] = {category="lo"}, +[42074] = {category="lo"}, +[42075] = {category="lo"}, +[42076] = {category="lo"}, +[42077] = {category="lo"}, +[42078] = {category="lo"}, +[42079] = {category="lo"}, +[42080] = {category="lo"}, +[42081] = {category="lo"}, +[42082] = {category="lo"}, +[42083] = {category="lo"}, +[42084] = {category="lo"}, +[42085] = {category="lo"}, +[42086] = {category="lo"}, +[42087] = {category="lo"}, +[42088] = {category="lo"}, +[42089] = {category="lo"}, +[42090] = {category="lo"}, +[42091] = {category="lo"}, +[42092] = {category="lo"}, +[42093] = {category="lo"}, +[42094] = {category="lo"}, +[42095] = {category="lo"}, +[42096] = {category="lo"}, +[42097] = {category="lo"}, +[42098] = {category="lo"}, +[42099] = {category="lo"}, +[42100] = {category="lo"}, +[42101] = {category="lo"}, +[42102] = {category="lo"}, +[42103] = {category="lo"}, +[42104] = {category="lo"}, +[42105] = {category="lo"}, +[42106] = {category="lo"}, +[42107] = {category="lo"}, +[42108] = {category="lo"}, +[42109] = {category="lo"}, +[42110] = {category="lo"}, +[42111] = {category="lo"}, +[42112] = {category="lo"}, +[42113] = {category="lo"}, +[42114] = {category="lo"}, +[42115] = {category="lo"}, +[42116] = {category="lo"}, +[42117] = {category="lo"}, +[42118] = {category="lo"}, +[42119] = {category="lo"}, +[42120] = {category="lo"}, +[42121] = {category="lo"}, +[42122] = {category="lo"}, +[42123] = {category="lo"}, +[42124] = {category="lo"}, +[42192] = {category="lo"}, +[42193] = {category="lo"}, +[42194] = {category="lo"}, +[42195] = {category="lo"}, +[42196] = {category="lo"}, +[42197] = {category="lo"}, +[42198] = {category="lo"}, +[42199] = {category="lo"}, +[42200] = {category="lo"}, +[42201] = {category="lo"}, +[42202] = {category="lo"}, +[42203] = {category="lo"}, +[42204] = {category="lo"}, +[42205] = {category="lo"}, +[42206] = {category="lo"}, +[42207] = {category="lo"}, +[42208] = {category="lo"}, +[42209] = {category="lo"}, +[42210] = {category="lo"}, +[42211] = {category="lo"}, +[42212] = {category="lo"}, +[42213] = {category="lo"}, +[42214] = {category="lo"}, +[42215] = {category="lo"}, +[42216] = {category="lo"}, +[42217] = {category="lo"}, +[42218] = {category="lo"}, +[42219] = {category="lo"}, +[42220] = {category="lo"}, +[42221] = {category="lo"}, +[42222] = {category="lo"}, +[42223] = {category="lo"}, +[42224] = {category="lo"}, +[42225] = {category="lo"}, +[42226] = {category="lo"}, +[42227] = {category="lo"}, +[42228] = {category="lo"}, +[42229] = {category="lo"}, +[42230] = {category="lo"}, +[42231] = {category="lo"}, +[42232] = {category="lm"}, +[42233] = {category="lm"}, +[42234] = {category="lm"}, +[42235] = {category="lm"}, +[42236] = {category="lm"}, +[42237] = {category="lm"}, +[42240] = {category="lo"}, +[42241] = {category="lo"}, +[42242] = {category="lo"}, +[42243] = {category="lo"}, +[42244] = {category="lo"}, +[42245] = {category="lo"}, +[42246] = {category="lo"}, +[42247] = {category="lo"}, +[42248] = {category="lo"}, +[42249] = {category="lo"}, +[42250] = {category="lo"}, +[42251] = {category="lo"}, +[42252] = {category="lo"}, +[42253] = {category="lo"}, +[42254] = {category="lo"}, +[42255] = {category="lo"}, +[42256] = {category="lo"}, +[42257] = {category="lo"}, +[42258] = {category="lo"}, +[42259] = {category="lo"}, +[42260] = {category="lo"}, +[42261] = {category="lo"}, +[42262] = {category="lo"}, +[42263] = {category="lo"}, +[42264] = {category="lo"}, +[42265] = {category="lo"}, +[42266] = {category="lo"}, +[42267] = {category="lo"}, +[42268] = {category="lo"}, +[42269] = {category="lo"}, +[42270] = {category="lo"}, +[42271] = {category="lo"}, +[42272] = {category="lo"}, +[42273] = {category="lo"}, +[42274] = {category="lo"}, +[42275] = {category="lo"}, +[42276] = {category="lo"}, +[42277] = {category="lo"}, +[42278] = {category="lo"}, +[42279] = {category="lo"}, +[42280] = {category="lo"}, +[42281] = {category="lo"}, +[42282] = {category="lo"}, +[42283] = {category="lo"}, +[42284] = {category="lo"}, +[42285] = {category="lo"}, +[42286] = {category="lo"}, +[42287] = {category="lo"}, +[42288] = {category="lo"}, +[42289] = {category="lo"}, +[42290] = {category="lo"}, +[42291] = {category="lo"}, +[42292] = {category="lo"}, +[42293] = {category="lo"}, +[42294] = {category="lo"}, +[42295] = {category="lo"}, +[42296] = {category="lo"}, +[42297] = {category="lo"}, +[42298] = {category="lo"}, +[42299] = {category="lo"}, +[42300] = {category="lo"}, +[42301] = {category="lo"}, +[42302] = {category="lo"}, +[42303] = {category="lo"}, +[42304] = {category="lo"}, +[42305] = {category="lo"}, +[42306] = {category="lo"}, +[42307] = {category="lo"}, +[42308] = {category="lo"}, +[42309] = {category="lo"}, +[42310] = {category="lo"}, +[42311] = {category="lo"}, +[42312] = {category="lo"}, +[42313] = {category="lo"}, +[42314] = {category="lo"}, +[42315] = {category="lo"}, +[42316] = {category="lo"}, +[42317] = {category="lo"}, +[42318] = {category="lo"}, +[42319] = {category="lo"}, +[42320] = {category="lo"}, +[42321] = {category="lo"}, +[42322] = {category="lo"}, +[42323] = {category="lo"}, +[42324] = {category="lo"}, +[42325] = {category="lo"}, +[42326] = {category="lo"}, +[42327] = {category="lo"}, +[42328] = {category="lo"}, +[42329] = {category="lo"}, +[42330] = {category="lo"}, +[42331] = {category="lo"}, +[42332] = {category="lo"}, +[42333] = {category="lo"}, +[42334] = {category="lo"}, +[42335] = {category="lo"}, +[42336] = {category="lo"}, +[42337] = {category="lo"}, +[42338] = {category="lo"}, +[42339] = {category="lo"}, +[42340] = {category="lo"}, +[42341] = {category="lo"}, +[42342] = {category="lo"}, +[42343] = {category="lo"}, +[42344] = {category="lo"}, +[42345] = {category="lo"}, +[42346] = {category="lo"}, +[42347] = {category="lo"}, +[42348] = {category="lo"}, +[42349] = {category="lo"}, +[42350] = {category="lo"}, +[42351] = {category="lo"}, +[42352] = {category="lo"}, +[42353] = {category="lo"}, +[42354] = {category="lo"}, +[42355] = {category="lo"}, +[42356] = {category="lo"}, +[42357] = {category="lo"}, +[42358] = {category="lo"}, +[42359] = {category="lo"}, +[42360] = {category="lo"}, +[42361] = {category="lo"}, +[42362] = {category="lo"}, +[42363] = {category="lo"}, +[42364] = {category="lo"}, +[42365] = {category="lo"}, +[42366] = {category="lo"}, +[42367] = {category="lo"}, +[42368] = {category="lo"}, +[42369] = {category="lo"}, +[42370] = {category="lo"}, +[42371] = {category="lo"}, +[42372] = {category="lo"}, +[42373] = {category="lo"}, +[42374] = {category="lo"}, +[42375] = {category="lo"}, +[42376] = {category="lo"}, +[42377] = {category="lo"}, +[42378] = {category="lo"}, +[42379] = {category="lo"}, +[42380] = {category="lo"}, +[42381] = {category="lo"}, +[42382] = {category="lo"}, +[42383] = {category="lo"}, +[42384] = {category="lo"}, +[42385] = {category="lo"}, +[42386] = {category="lo"}, +[42387] = {category="lo"}, +[42388] = {category="lo"}, +[42389] = {category="lo"}, +[42390] = {category="lo"}, +[42391] = {category="lo"}, +[42392] = {category="lo"}, +[42393] = {category="lo"}, +[42394] = {category="lo"}, +[42395] = {category="lo"}, +[42396] = {category="lo"}, +[42397] = {category="lo"}, +[42398] = {category="lo"}, +[42399] = {category="lo"}, +[42400] = {category="lo"}, +[42401] = {category="lo"}, +[42402] = {category="lo"}, +[42403] = {category="lo"}, +[42404] = {category="lo"}, +[42405] = {category="lo"}, +[42406] = {category="lo"}, +[42407] = {category="lo"}, +[42408] = {category="lo"}, +[42409] = {category="lo"}, +[42410] = {category="lo"}, +[42411] = {category="lo"}, +[42412] = {category="lo"}, +[42413] = {category="lo"}, +[42414] = {category="lo"}, +[42415] = {category="lo"}, +[42416] = {category="lo"}, +[42417] = {category="lo"}, +[42418] = {category="lo"}, +[42419] = {category="lo"}, +[42420] = {category="lo"}, +[42421] = {category="lo"}, +[42422] = {category="lo"}, +[42423] = {category="lo"}, +[42424] = {category="lo"}, +[42425] = {category="lo"}, +[42426] = {category="lo"}, +[42427] = {category="lo"}, +[42428] = {category="lo"}, +[42429] = {category="lo"}, +[42430] = {category="lo"}, +[42431] = {category="lo"}, +[42432] = {category="lo"}, +[42433] = {category="lo"}, +[42434] = {category="lo"}, +[42435] = {category="lo"}, +[42436] = {category="lo"}, +[42437] = {category="lo"}, +[42438] = {category="lo"}, +[42439] = {category="lo"}, +[42440] = {category="lo"}, +[42441] = {category="lo"}, +[42442] = {category="lo"}, +[42443] = {category="lo"}, +[42444] = {category="lo"}, +[42445] = {category="lo"}, +[42446] = {category="lo"}, +[42447] = {category="lo"}, +[42448] = {category="lo"}, +[42449] = {category="lo"}, +[42450] = {category="lo"}, +[42451] = {category="lo"}, +[42452] = {category="lo"}, +[42453] = {category="lo"}, +[42454] = {category="lo"}, +[42455] = {category="lo"}, +[42456] = {category="lo"}, +[42457] = {category="lo"}, +[42458] = {category="lo"}, +[42459] = {category="lo"}, +[42460] = {category="lo"}, +[42461] = {category="lo"}, +[42462] = {category="lo"}, +[42463] = {category="lo"}, +[42464] = {category="lo"}, +[42465] = {category="lo"}, +[42466] = {category="lo"}, +[42467] = {category="lo"}, +[42468] = {category="lo"}, +[42469] = {category="lo"}, +[42470] = {category="lo"}, +[42471] = {category="lo"}, +[42472] = {category="lo"}, +[42473] = {category="lo"}, +[42474] = {category="lo"}, +[42475] = {category="lo"}, +[42476] = {category="lo"}, +[42477] = {category="lo"}, +[42478] = {category="lo"}, +[42479] = {category="lo"}, +[42480] = {category="lo"}, +[42481] = {category="lo"}, +[42482] = {category="lo"}, +[42483] = {category="lo"}, +[42484] = {category="lo"}, +[42485] = {category="lo"}, +[42486] = {category="lo"}, +[42487] = {category="lo"}, +[42488] = {category="lo"}, +[42489] = {category="lo"}, +[42490] = {category="lo"}, +[42491] = {category="lo"}, +[42492] = {category="lo"}, +[42493] = {category="lo"}, +[42494] = {category="lo"}, +[42495] = {category="lo"}, +[42496] = {category="lo"}, +[42497] = {category="lo"}, +[42498] = {category="lo"}, +[42499] = {category="lo"}, +[42500] = {category="lo"}, +[42501] = {category="lo"}, +[42502] = {category="lo"}, +[42503] = {category="lo"}, +[42504] = {category="lo"}, +[42505] = {category="lo"}, +[42506] = {category="lo"}, +[42507] = {category="lo"}, +[42508] = {category="lm"}, +[42512] = {category="lo"}, +[42513] = {category="lo"}, +[42514] = {category="lo"}, +[42515] = {category="lo"}, +[42516] = {category="lo"}, +[42517] = {category="lo"}, +[42518] = {category="lo"}, +[42519] = {category="lo"}, +[42520] = {category="lo"}, +[42521] = {category="lo"}, +[42522] = {category="lo"}, +[42523] = {category="lo"}, +[42524] = {category="lo"}, +[42525] = {category="lo"}, +[42526] = {category="lo"}, +[42527] = {category="lo"}, +[42538] = {category="lo"}, +[42539] = {category="lo"}, +[42560] = {category="lu", lccode=42561}, +[42561] = {category="ll"}, +[42562] = {category="lu", lccode=42563}, +[42563] = {category="ll"}, +[42564] = {category="lu", lccode=42565}, +[42565] = {category="ll"}, +[42566] = {category="lu", lccode=42567}, +[42567] = {category="ll"}, +[42568] = {category="lu", lccode=42569}, +[42569] = {category="ll"}, +[42570] = {category="lu", lccode=42571}, +[42571] = {category="ll"}, +[42572] = {category="lu", lccode=42573}, +[42573] = {category="ll"}, +[42574] = {category="lu", lccode=42575}, +[42575] = {category="ll"}, +[42576] = {category="lu", lccode=42577}, +[42577] = {category="ll"}, +[42578] = {category="lu", lccode=42579}, +[42579] = {category="ll"}, +[42580] = {category="lu", lccode=42581}, +[42581] = {category="ll"}, +[42582] = {category="lu", lccode=42583}, +[42583] = {category="ll"}, +[42584] = {category="lu", lccode=42585}, +[42585] = {category="ll"}, +[42586] = {category="lu", lccode=42587}, +[42587] = {category="ll"}, +[42588] = {category="lu", lccode=42589}, +[42589] = {category="ll"}, +[42590] = {category="lu", lccode=42591}, +[42591] = {category="ll"}, +[42592] = {category="lu", lccode=42593}, +[42593] = {category="ll"}, +[42594] = {category="lu", lccode=42595}, +[42595] = {category="ll"}, +[42596] = {category="lu", lccode=42597}, +[42597] = {category="ll"}, +[42598] = {category="lu", lccode=42599}, +[42599] = {category="ll"}, +[42600] = {category="lu", lccode=42601}, +[42601] = {category="ll"}, +[42602] = {category="lu", lccode=42603}, +[42603] = {category="ll"}, +[42604] = {category="lu", lccode=42605}, +[42605] = {category="ll"}, +[42606] = {category="lo"}, +[42623] = {category="lm"}, +[42624] = {category="lu", lccode=42625}, +[42625] = {category="ll"}, +[42626] = {category="lu", lccode=42627}, +[42627] = {category="ll"}, +[42628] = {category="lu", lccode=42629}, +[42629] = {category="ll"}, +[42630] = {category="lu", lccode=42631}, +[42631] = {category="ll"}, +[42632] = {category="lu", lccode=42633}, +[42633] = {category="ll"}, +[42634] = {category="lu", lccode=42635}, +[42635] = {category="ll"}, +[42636] = {category="lu", lccode=42637}, +[42637] = {category="ll"}, +[42638] = {category="lu", lccode=42639}, +[42639] = {category="ll"}, +[42640] = {category="lu", lccode=42641}, +[42641] = {category="ll"}, +[42642] = {category="lu", lccode=42643}, +[42643] = {category="ll"}, +[42644] = {category="lu", lccode=42645}, +[42645] = {category="ll"}, +[42646] = {category="lu", lccode=42647}, +[42647] = {category="ll"}, +[42648] = {category="lu", lccode=42649}, +[42649] = {category="ll"}, +[42650] = {category="lu", lccode=42651}, +[42651] = {category="ll"}, +[42652] = {category="lm", shcode=14}, +[42653] = {category="lm", shcode=14}, +[42656] = {category="lo"}, +[42657] = {category="lo"}, +[42658] = {category="lo"}, +[42659] = {category="lo"}, +[42660] = {category="lo"}, +[42661] = {category="lo"}, +[42662] = {category="lo"}, +[42663] = {category="lo"}, +[42664] = {category="lo"}, +[42665] = {category="lo"}, +[42666] = {category="lo"}, +[42667] = {category="lo"}, +[42668] = {category="lo"}, +[42669] = {category="lo"}, +[42670] = {category="lo"}, +[42671] = {category="lo"}, +[42672] = {category="lo"}, +[42673] = {category="lo"}, +[42674] = {category="lo"}, +[42675] = {category="lo"}, +[42676] = {category="lo"}, +[42677] = {category="lo"}, +[42678] = {category="lo"}, +[42679] = {category="lo"}, +[42680] = {category="lo"}, +[42681] = {category="lo"}, +[42682] = {category="lo"}, +[42683] = {category="lo"}, +[42684] = {category="lo"}, +[42685] = {category="lo"}, +[42686] = {category="lo"}, +[42687] = {category="lo"}, +[42688] = {category="lo"}, +[42689] = {category="lo"}, +[42690] = {category="lo"}, +[42691] = {category="lo"}, +[42692] = {category="lo"}, +[42693] = {category="lo"}, +[42694] = {category="lo"}, +[42695] = {category="lo"}, +[42696] = {category="lo"}, +[42697] = {category="lo"}, +[42698] = {category="lo"}, +[42699] = {category="lo"}, +[42700] = {category="lo"}, +[42701] = {category="lo"}, +[42702] = {category="lo"}, +[42703] = {category="lo"}, +[42704] = {category="lo"}, +[42705] = {category="lo"}, +[42706] = {category="lo"}, +[42707] = {category="lo"}, +[42708] = {category="lo"}, +[42709] = {category="lo"}, +[42710] = {category="lo"}, +[42711] = {category="lo"}, +[42712] = {category="lo"}, +[42713] = {category="lo"}, +[42714] = {category="lo"}, +[42715] = {category="lo"}, +[42716] = {category="lo"}, +[42717] = {category="lo"}, +[42718] = {category="lo"}, +[42719] = {category="lo"}, +[42720] = {category="lo"}, +[42721] = {category="lo"}, +[42722] = {category="lo"}, +[42723] = {category="lo"}, +[42724] = {category="lo"}, +[42725] = {category="lo"}, +[42775] = {category="lm"}, +[42776] = {category="lm"}, +[42777] = {category="lm"}, +[42778] = {category="lm"}, +[42779] = {category="lm"}, +[42780] = {category="lm"}, +[42781] = {category="lm"}, +[42782] = {category="lm"}, +[42783] = {category="lm"}, +[42786] = {category="lu", lccode=42787}, +[42787] = {category="ll"}, +[42788] = {category="lu", lccode=42789}, +[42789] = {category="ll"}, +[42790] = {category="lu", lccode=42791}, +[42791] = {category="ll"}, +[42792] = {category="lu", lccode=42793}, +[42793] = {category="ll"}, +[42794] = {category="lu", lccode=42795}, +[42795] = {category="ll"}, +[42796] = {category="lu", lccode=42797}, +[42797] = {category="ll"}, +[42798] = {category="lu", lccode=42799}, +[42799] = {category="ll"}, +[42800] = {category="ll"}, +[42801] = {category="ll"}, +[42802] = {category="lu", lccode=42803}, +[42803] = {category="ll"}, +[42804] = {category="lu", lccode=42805}, +[42805] = {category="ll"}, +[42806] = {category="lu", lccode=42807}, +[42807] = {category="ll"}, +[42808] = {category="lu", lccode=42809}, +[42809] = {category="ll"}, +[42810] = {category="lu", lccode=42811}, +[42811] = {category="ll"}, +[42812] = {category="lu", lccode=42813}, +[42813] = {category="ll"}, +[42814] = {category="lu", lccode=42815}, +[42815] = {category="ll"}, +[42816] = {category="lu", lccode=42817}, +[42817] = {category="ll"}, +[42818] = {category="lu", lccode=42819}, +[42819] = {category="ll"}, +[42820] = {category="lu", lccode=42821}, +[42821] = {category="ll"}, +[42822] = {category="lu", lccode=42823}, +[42823] = {category="ll"}, +[42824] = {category="lu", lccode=42825}, +[42825] = {category="ll"}, +[42826] = {category="lu", lccode=42827}, +[42827] = {category="ll"}, +[42828] = {category="lu", lccode=42829}, +[42829] = {category="ll"}, +[42830] = {category="lu", lccode=42831}, +[42831] = {category="ll"}, +[42832] = {category="lu", lccode=42833}, +[42833] = {category="ll"}, +[42834] = {category="lu", lccode=42835}, +[42835] = {category="ll"}, +[42836] = {category="lu", lccode=42837}, +[42837] = {category="ll"}, +[42838] = {category="lu", lccode=42839}, +[42839] = {category="ll"}, +[42840] = {category="lu", lccode=42841}, +[42841] = {category="ll"}, +[42842] = {category="lu", lccode=42843}, +[42843] = {category="ll"}, +[42844] = {category="lu", lccode=42845}, +[42845] = {category="ll"}, +[42846] = {category="lu", lccode=42847}, +[42847] = {category="ll"}, +[42848] = {category="lu", lccode=42849}, +[42849] = {category="ll"}, +[42850] = {category="lu", lccode=42851}, +[42851] = {category="ll"}, +[42852] = {category="lu", lccode=42853}, +[42853] = {category="ll"}, +[42854] = {category="lu", lccode=42855}, +[42855] = {category="ll"}, +[42856] = {category="lu", lccode=42857}, +[42857] = {category="ll"}, +[42858] = {category="lu", lccode=42859}, +[42859] = {category="ll"}, +[42860] = {category="lu", lccode=42861}, +[42861] = {category="ll"}, +[42862] = {category="lu", lccode=42863}, +[42863] = {category="ll"}, +[42864] = {category="lm", shcode=14}, +[42865] = {category="ll"}, +[42866] = {category="ll"}, +[42867] = {category="ll"}, +[42868] = {category="ll"}, +[42869] = {category="ll"}, +[42870] = {category="ll"}, +[42871] = {category="ll"}, +[42872] = {category="ll"}, +[42873] = {category="lu", lccode=42874}, +[42874] = {category="ll"}, +[42875] = {category="lu", lccode=42876}, +[42876] = {category="ll"}, +[42877] = {category="lu", lccode=7545}, +[42878] = {category="lu", lccode=42879}, +[42879] = {category="ll"}, +[42880] = {category="lu", lccode=42881}, +[42881] = {category="ll"}, +[42882] = {category="lu", lccode=42883}, +[42883] = {category="ll"}, +[42884] = {category="lu", lccode=42885}, +[42885] = {category="ll"}, +[42886] = {category="lu", lccode=42887}, +[42887] = {category="ll"}, +[42888] = {category="lm"}, +[42891] = {category="lu", lccode=42892}, +[42892] = {category="ll"}, +[42893] = {category="lu", lccode=613}, +[42894] = {category="ll"}, +[42895] = {category="lo"}, +[42896] = {category="lu", lccode=42897}, +[42897] = {category="ll"}, +[42898] = {category="lu", lccode=42899}, +[42899] = {category="ll"}, +[42900] = {category="ll"}, +[42901] = {category="ll"}, +[42902] = {category="lu", lccode=42903}, +[42903] = {category="ll"}, +[42904] = {category="lu", lccode=42905}, +[42905] = {category="ll"}, +[42906] = {category="lu", lccode=42907}, +[42907] = {category="ll"}, +[42908] = {category="lu", lccode=42909}, +[42909] = {category="ll"}, +[42910] = {category="lu", lccode=42911}, +[42911] = {category="ll"}, +[42912] = {category="lu", lccode=42913}, +[42913] = {category="ll"}, +[42914] = {category="lu", lccode=42915}, +[42915] = {category="ll"}, +[42916] = {category="lu", lccode=42917}, +[42917] = {category="ll"}, +[42918] = {category="lu", lccode=42919}, +[42919] = {category="ll"}, +[42920] = {category="lu", lccode=42921}, +[42921] = {category="ll"}, +[42922] = {category="lu", lccode=614}, +[42923] = {category="lu", lccode=604}, +[42924] = {category="lu", lccode=609}, +[42925] = {category="lu", lccode=620}, +[42926] = {category="lu", lccode=618}, +[42927] = {category="ll"}, +[42928] = {category="lu", lccode=670}, +[42929] = {category="lu", lccode=647}, +[42930] = {category="lu", lccode=669}, +[42931] = {category="lu", lccode=43859}, +[42932] = {category="lu", lccode=42933}, +[42933] = {category="ll"}, +[42934] = {category="lu", lccode=42935}, +[42935] = {category="ll"}, +[42936] = {category="lu", lccode=42937}, +[42937] = {category="ll"}, +[42938] = {category="lu", lccode=42939}, +[42939] = {category="ll"}, +[42940] = {category="lu", lccode=42941}, +[42941] = {category="ll"}, +[42942] = {category="lu", lccode=42943}, +[42943] = {category="ll"}, +[42944] = {category="lu", lccode=42945}, +[42945] = {category="ll"}, +[42946] = {category="lu", lccode=42947}, +[42947] = {category="ll"}, +[42948] = {category="lu", lccode=42900}, +[42949] = {category="lu", lccode=642}, +[42950] = {category="lu", lccode=7566}, +[42951] = {category="lu", lccode=42952}, +[42952] = {category="ll"}, +[42953] = {category="lu", lccode=42954}, +[42954] = {category="ll"}, +[42960] = {category="lu", lccode=42961}, +[42961] = {category="ll"}, +[42963] = {category="ll"}, +[42965] = {category="ll"}, +[42966] = {category="lu", lccode=42967}, +[42967] = {category="ll"}, +[42968] = {category="lu", lccode=42969}, +[42969] = {category="ll"}, +[42994] = {category="lm", shcode=14}, +[42995] = {category="lm", shcode=14}, +[42996] = {category="lm", shcode=14}, +[42997] = {category="lu", lccode=42998}, +[42998] = {category="ll"}, +[42999] = {category="lo"}, +[43000] = {category="lm", shcode=14}, +[43001] = {category="lm", shcode=14}, +[43002] = {category="ll"}, +[43003] = {category="lo"}, +[43004] = {category="lo"}, +[43005] = {category="lo"}, +[43006] = {category="lo"}, +[43007] = {category="lo"}, +[43008] = {category="lo"}, +[43009] = {category="lo"}, +[43011] = {category="lo"}, +[43012] = {category="lo"}, +[43013] = {category="lo"}, +[43015] = {category="lo"}, +[43016] = {category="lo"}, +[43017] = {category="lo"}, +[43018] = {category="lo"}, +[43020] = {category="lo"}, +[43021] = {category="lo"}, +[43022] = {category="lo"}, +[43023] = {category="lo"}, +[43024] = {category="lo"}, +[43025] = {category="lo"}, +[43026] = {category="lo"}, +[43027] = {category="lo"}, +[43028] = {category="lo"}, +[43029] = {category="lo"}, +[43030] = {category="lo"}, +[43031] = {category="lo"}, +[43032] = {category="lo"}, +[43033] = {category="lo"}, +[43034] = {category="lo"}, +[43035] = {category="lo"}, +[43036] = {category="lo"}, +[43037] = {category="lo"}, +[43038] = {category="lo"}, +[43039] = {category="lo"}, +[43040] = {category="lo"}, +[43041] = {category="lo"}, +[43042] = {category="lo"}, +[43072] = {category="lo"}, +[43073] = {category="lo"}, +[43074] = {category="lo"}, +[43075] = {category="lo"}, +[43076] = {category="lo"}, +[43077] = {category="lo"}, +[43078] = {category="lo"}, +[43079] = {category="lo"}, +[43080] = {category="lo"}, +[43081] = {category="lo"}, +[43082] = {category="lo"}, +[43083] = {category="lo"}, +[43084] = {category="lo"}, +[43085] = {category="lo"}, +[43086] = {category="lo"}, +[43087] = {category="lo"}, +[43088] = {category="lo"}, +[43089] = {category="lo"}, +[43090] = {category="lo"}, +[43091] = {category="lo"}, +[43092] = {category="lo"}, +[43093] = {category="lo"}, +[43094] = {category="lo"}, +[43095] = {category="lo"}, +[43096] = {category="lo"}, +[43097] = {category="lo"}, +[43098] = {category="lo"}, +[43099] = {category="lo"}, +[43100] = {category="lo"}, +[43101] = {category="lo"}, +[43102] = {category="lo"}, +[43103] = {category="lo"}, +[43104] = {category="lo"}, +[43105] = {category="lo"}, +[43106] = {category="lo"}, +[43107] = {category="lo"}, +[43108] = {category="lo"}, +[43109] = {category="lo"}, +[43110] = {category="lo"}, +[43111] = {category="lo"}, +[43112] = {category="lo"}, +[43113] = {category="lo"}, +[43114] = {category="lo"}, +[43115] = {category="lo"}, +[43116] = {category="lo"}, +[43117] = {category="lo"}, +[43118] = {category="lo"}, +[43119] = {category="lo"}, +[43120] = {category="lo"}, +[43121] = {category="lo"}, +[43122] = {category="lo"}, +[43123] = {category="lo"}, +[43138] = {category="lo"}, +[43139] = {category="lo"}, +[43140] = {category="lo"}, +[43141] = {category="lo"}, +[43142] = {category="lo"}, +[43143] = {category="lo"}, +[43144] = {category="lo"}, +[43145] = {category="lo"}, +[43146] = {category="lo"}, +[43147] = {category="lo"}, +[43148] = {category="lo"}, +[43149] = {category="lo"}, +[43150] = {category="lo"}, +[43151] = {category="lo"}, +[43152] = {category="lo"}, +[43153] = {category="lo"}, +[43154] = {category="lo"}, +[43155] = {category="lo"}, +[43156] = {category="lo"}, +[43157] = {category="lo"}, +[43158] = {category="lo"}, +[43159] = {category="lo"}, +[43160] = {category="lo"}, +[43161] = {category="lo"}, +[43162] = {category="lo"}, +[43163] = {category="lo"}, +[43164] = {category="lo"}, +[43165] = {category="lo"}, +[43166] = {category="lo"}, +[43167] = {category="lo"}, +[43168] = {category="lo"}, +[43169] = {category="lo"}, +[43170] = {category="lo"}, +[43171] = {category="lo"}, +[43172] = {category="lo"}, +[43173] = {category="lo"}, +[43174] = {category="lo"}, +[43175] = {category="lo"}, +[43176] = {category="lo"}, +[43177] = {category="lo"}, +[43178] = {category="lo"}, +[43179] = {category="lo"}, +[43180] = {category="lo"}, +[43181] = {category="lo"}, +[43182] = {category="lo"}, +[43183] = {category="lo"}, +[43184] = {category="lo"}, +[43185] = {category="lo"}, +[43186] = {category="lo"}, +[43187] = {category="lo"}, +[43250] = {category="lo"}, +[43251] = {category="lo"}, +[43252] = {category="lo"}, +[43253] = {category="lo"}, +[43254] = {category="lo"}, +[43255] = {category="lo"}, +[43259] = {category="lo"}, +[43261] = {category="lo"}, +[43262] = {category="lo"}, +[43274] = {category="lo"}, +[43275] = {category="lo"}, +[43276] = {category="lo"}, +[43277] = {category="lo"}, +[43278] = {category="lo"}, +[43279] = {category="lo"}, +[43280] = {category="lo"}, +[43281] = {category="lo"}, +[43282] = {category="lo"}, +[43283] = {category="lo"}, +[43284] = {category="lo"}, +[43285] = {category="lo"}, +[43286] = {category="lo"}, +[43287] = {category="lo"}, +[43288] = {category="lo"}, +[43289] = {category="lo"}, +[43290] = {category="lo"}, +[43291] = {category="lo"}, +[43292] = {category="lo"}, +[43293] = {category="lo"}, +[43294] = {category="lo"}, +[43295] = {category="lo"}, +[43296] = {category="lo"}, +[43297] = {category="lo"}, +[43298] = {category="lo"}, +[43299] = {category="lo"}, +[43300] = {category="lo"}, +[43301] = {category="lo"}, +[43312] = {category="lo"}, +[43313] = {category="lo"}, +[43314] = {category="lo"}, +[43315] = {category="lo"}, +[43316] = {category="lo"}, +[43317] = {category="lo"}, +[43318] = {category="lo"}, +[43319] = {category="lo"}, +[43320] = {category="lo"}, +[43321] = {category="lo"}, +[43322] = {category="lo"}, +[43323] = {category="lo"}, +[43324] = {category="lo"}, +[43325] = {category="lo"}, +[43326] = {category="lo"}, +[43327] = {category="lo"}, +[43328] = {category="lo"}, +[43329] = {category="lo"}, +[43330] = {category="lo"}, +[43331] = {category="lo"}, +[43332] = {category="lo"}, +[43333] = {category="lo"}, +[43334] = {category="lo"}, +[43360] = {category="lo"}, +[43361] = {category="lo"}, +[43362] = {category="lo"}, +[43363] = {category="lo"}, +[43364] = {category="lo"}, +[43365] = {category="lo"}, +[43366] = {category="lo"}, +[43367] = {category="lo"}, +[43368] = {category="lo"}, +[43369] = {category="lo"}, +[43370] = {category="lo"}, +[43371] = {category="lo"}, +[43372] = {category="lo"}, +[43373] = {category="lo"}, +[43374] = {category="lo"}, +[43375] = {category="lo"}, +[43376] = {category="lo"}, +[43377] = {category="lo"}, +[43378] = {category="lo"}, +[43379] = {category="lo"}, +[43380] = {category="lo"}, +[43381] = {category="lo"}, +[43382] = {category="lo"}, +[43383] = {category="lo"}, +[43384] = {category="lo"}, +[43385] = {category="lo"}, +[43386] = {category="lo"}, +[43387] = {category="lo"}, +[43388] = {category="lo"}, +[43396] = {category="lo"}, +[43397] = {category="lo"}, +[43398] = {category="lo"}, +[43399] = {category="lo"}, +[43400] = {category="lo"}, +[43401] = {category="lo"}, +[43402] = {category="lo"}, +[43403] = {category="lo"}, +[43404] = {category="lo"}, +[43405] = {category="lo"}, +[43406] = {category="lo"}, +[43407] = {category="lo"}, +[43408] = {category="lo"}, +[43409] = {category="lo"}, +[43410] = {category="lo"}, +[43411] = {category="lo"}, +[43412] = {category="lo"}, +[43413] = {category="lo"}, +[43414] = {category="lo"}, +[43415] = {category="lo"}, +[43416] = {category="lo"}, +[43417] = {category="lo"}, +[43418] = {category="lo"}, +[43419] = {category="lo"}, +[43420] = {category="lo"}, +[43421] = {category="lo"}, +[43422] = {category="lo"}, +[43423] = {category="lo"}, +[43424] = {category="lo"}, +[43425] = {category="lo"}, +[43426] = {category="lo"}, +[43427] = {category="lo"}, +[43428] = {category="lo"}, +[43429] = {category="lo"}, +[43430] = {category="lo"}, +[43431] = {category="lo"}, +[43432] = {category="lo"}, +[43433] = {category="lo"}, +[43434] = {category="lo"}, +[43435] = {category="lo"}, +[43436] = {category="lo"}, +[43437] = {category="lo"}, +[43438] = {category="lo"}, +[43439] = {category="lo"}, +[43440] = {category="lo"}, +[43441] = {category="lo"}, +[43442] = {category="lo"}, +[43471] = {category="lm"}, +[43488] = {category="lo"}, +[43489] = {category="lo"}, +[43490] = {category="lo"}, +[43491] = {category="lo"}, +[43492] = {category="lo"}, +[43494] = {category="lm"}, +[43495] = {category="lo"}, +[43496] = {category="lo"}, +[43497] = {category="lo"}, +[43498] = {category="lo"}, +[43499] = {category="lo"}, +[43500] = {category="lo"}, +[43501] = {category="lo"}, +[43502] = {category="lo"}, +[43503] = {category="lo"}, +[43514] = {category="lo"}, +[43515] = {category="lo"}, +[43516] = {category="lo"}, +[43517] = {category="lo"}, +[43518] = {category="lo"}, +[43520] = {category="lo"}, +[43521] = {category="lo"}, +[43522] = {category="lo"}, +[43523] = {category="lo"}, +[43524] = {category="lo"}, +[43525] = {category="lo"}, +[43526] = {category="lo"}, +[43527] = {category="lo"}, +[43528] = {category="lo"}, +[43529] = {category="lo"}, +[43530] = {category="lo"}, +[43531] = {category="lo"}, +[43532] = {category="lo"}, +[43533] = {category="lo"}, +[43534] = {category="lo"}, +[43535] = {category="lo"}, +[43536] = {category="lo"}, +[43537] = {category="lo"}, +[43538] = {category="lo"}, +[43539] = {category="lo"}, +[43540] = {category="lo"}, +[43541] = {category="lo"}, +[43542] = {category="lo"}, +[43543] = {category="lo"}, +[43544] = {category="lo"}, +[43545] = {category="lo"}, +[43546] = {category="lo"}, +[43547] = {category="lo"}, +[43548] = {category="lo"}, +[43549] = {category="lo"}, +[43550] = {category="lo"}, +[43551] = {category="lo"}, +[43552] = {category="lo"}, +[43553] = {category="lo"}, +[43554] = {category="lo"}, +[43555] = {category="lo"}, +[43556] = {category="lo"}, +[43557] = {category="lo"}, +[43558] = {category="lo"}, +[43559] = {category="lo"}, +[43560] = {category="lo"}, +[43584] = {category="lo"}, +[43585] = {category="lo"}, +[43586] = {category="lo"}, +[43588] = {category="lo"}, +[43589] = {category="lo"}, +[43590] = {category="lo"}, +[43591] = {category="lo"}, +[43592] = {category="lo"}, +[43593] = {category="lo"}, +[43594] = {category="lo"}, +[43595] = {category="lo"}, +[43616] = {category="lo"}, +[43617] = {category="lo"}, +[43618] = {category="lo"}, +[43619] = {category="lo"}, +[43620] = {category="lo"}, +[43621] = {category="lo"}, +[43622] = {category="lo"}, +[43623] = {category="lo"}, +[43624] = {category="lo"}, +[43625] = {category="lo"}, +[43626] = {category="lo"}, +[43627] = {category="lo"}, +[43628] = {category="lo"}, +[43629] = {category="lo"}, +[43630] = {category="lo"}, +[43631] = {category="lo"}, +[43632] = {category="lm"}, +[43633] = {category="lo"}, +[43634] = {category="lo"}, +[43635] = {category="lo"}, +[43636] = {category="lo"}, +[43637] = {category="lo"}, +[43638] = {category="lo"}, +[43642] = {category="lo"}, +[43646] = {category="lo"}, +[43647] = {category="lo"}, +[43648] = {category="lo"}, +[43649] = {category="lo"}, +[43650] = {category="lo"}, +[43651] = {category="lo"}, +[43652] = {category="lo"}, +[43653] = {category="lo"}, +[43654] = {category="lo"}, +[43655] = {category="lo"}, +[43656] = {category="lo"}, +[43657] = {category="lo"}, +[43658] = {category="lo"}, +[43659] = {category="lo"}, +[43660] = {category="lo"}, +[43661] = {category="lo"}, +[43662] = {category="lo"}, +[43663] = {category="lo"}, +[43664] = {category="lo"}, +[43665] = {category="lo"}, +[43666] = {category="lo"}, +[43667] = {category="lo"}, +[43668] = {category="lo"}, +[43669] = {category="lo"}, +[43670] = {category="lo"}, +[43671] = {category="lo"}, +[43672] = {category="lo"}, +[43673] = {category="lo"}, +[43674] = {category="lo"}, +[43675] = {category="lo"}, +[43676] = {category="lo"}, +[43677] = {category="lo"}, +[43678] = {category="lo"}, +[43679] = {category="lo"}, +[43680] = {category="lo"}, +[43681] = {category="lo"}, +[43682] = {category="lo"}, +[43683] = {category="lo"}, +[43684] = {category="lo"}, +[43685] = {category="lo"}, +[43686] = {category="lo"}, +[43687] = {category="lo"}, +[43688] = {category="lo"}, +[43689] = {category="lo"}, +[43690] = {category="lo"}, +[43691] = {category="lo"}, +[43692] = {category="lo"}, +[43693] = {category="lo"}, +[43694] = {category="lo"}, +[43695] = {category="lo"}, +[43697] = {category="lo"}, +[43701] = {category="lo"}, +[43702] = {category="lo"}, +[43705] = {category="lo"}, +[43706] = {category="lo"}, +[43707] = {category="lo"}, +[43708] = {category="lo"}, +[43709] = {category="lo"}, +[43712] = {category="lo"}, +[43714] = {category="lo"}, +[43739] = {category="lo"}, +[43740] = {category="lo"}, +[43741] = {category="lm"}, +[43744] = {category="lo"}, +[43745] = {category="lo"}, +[43746] = {category="lo"}, +[43747] = {category="lo"}, +[43748] = {category="lo"}, +[43749] = {category="lo"}, +[43750] = {category="lo"}, +[43751] = {category="lo"}, +[43752] = {category="lo"}, +[43753] = {category="lo"}, +[43754] = {category="lo"}, +[43762] = {category="lo"}, +[43763] = {category="lm"}, +[43764] = {category="lm"}, +[43777] = {category="lo"}, +[43778] = {category="lo"}, +[43779] = {category="lo"}, +[43780] = {category="lo"}, +[43781] = {category="lo"}, +[43782] = {category="lo"}, +[43785] = {category="lo"}, +[43786] = {category="lo"}, +[43787] = {category="lo"}, +[43788] = {category="lo"}, +[43789] = {category="lo"}, +[43790] = {category="lo"}, +[43793] = {category="lo"}, +[43794] = {category="lo"}, +[43795] = {category="lo"}, +[43796] = {category="lo"}, +[43797] = {category="lo"}, +[43798] = {category="lo"}, +[43808] = {category="lo"}, +[43809] = {category="lo"}, +[43810] = {category="lo"}, +[43811] = {category="lo"}, +[43812] = {category="lo"}, +[43813] = {category="lo"}, +[43814] = {category="lo"}, +[43816] = {category="lo"}, +[43817] = {category="lo"}, +[43818] = {category="lo"}, +[43819] = {category="lo"}, +[43820] = {category="lo"}, +[43821] = {category="lo"}, +[43822] = {category="lo"}, +[43824] = {category="ll"}, +[43825] = {category="ll"}, +[43826] = {category="ll"}, +[43827] = {category="ll"}, +[43828] = {category="ll"}, +[43829] = {category="ll"}, +[43830] = {category="ll"}, +[43831] = {category="ll"}, +[43832] = {category="ll"}, +[43833] = {category="ll"}, +[43834] = {category="ll"}, +[43835] = {category="ll"}, +[43836] = {category="ll"}, +[43837] = {category="ll"}, +[43838] = {category="ll"}, +[43839] = {category="ll"}, +[43840] = {category="ll"}, +[43841] = {category="ll"}, +[43842] = {category="ll"}, +[43843] = {category="ll"}, +[43844] = {category="ll"}, +[43845] = {category="ll"}, +[43846] = {category="ll"}, +[43847] = {category="ll"}, +[43848] = {category="ll"}, +[43849] = {category="ll"}, +[43850] = {category="ll"}, +[43851] = {category="ll"}, +[43852] = {category="ll"}, +[43853] = {category="ll"}, +[43854] = {category="ll"}, +[43855] = {category="ll"}, +[43856] = {category="ll"}, +[43857] = {category="ll"}, +[43858] = {category="ll"}, +[43859] = {category="ll"}, +[43860] = {category="ll"}, +[43861] = {category="ll"}, +[43862] = {category="ll"}, +[43863] = {category="ll"}, +[43864] = {category="ll"}, +[43865] = {category="ll"}, +[43866] = {category="ll"}, +[43868] = {category="lm", shcode=14}, +[43869] = {category="lm", shcode=14}, +[43870] = {category="lm", shcode=14}, +[43871] = {category="lm", shcode=14}, +[43872] = {category="ll"}, +[43873] = {category="ll"}, +[43874] = {category="ll"}, +[43875] = {category="ll"}, +[43876] = {category="ll"}, +[43877] = {category="ll"}, +[43878] = {category="ll"}, +[43879] = {category="ll"}, +[43880] = {category="ll"}, +[43881] = {category="lm", shcode=14}, +[43888] = {category="ll"}, +[43889] = {category="ll"}, +[43890] = {category="ll"}, +[43891] = {category="ll"}, +[43892] = {category="ll"}, +[43893] = {category="ll"}, +[43894] = {category="ll"}, +[43895] = {category="ll"}, +[43896] = {category="ll"}, +[43897] = {category="ll"}, +[43898] = {category="ll"}, +[43899] = {category="ll"}, +[43900] = {category="ll"}, +[43901] = {category="ll"}, +[43902] = {category="ll"}, +[43903] = {category="ll"}, +[43904] = {category="ll"}, +[43905] = {category="ll"}, +[43906] = {category="ll"}, +[43907] = {category="ll"}, +[43908] = {category="ll"}, +[43909] = {category="ll"}, +[43910] = {category="ll"}, +[43911] = {category="ll"}, +[43912] = {category="ll"}, +[43913] = {category="ll"}, +[43914] = {category="ll"}, +[43915] = {category="ll"}, +[43916] = {category="ll"}, +[43917] = {category="ll"}, +[43918] = {category="ll"}, +[43919] = {category="ll"}, +[43920] = {category="ll"}, +[43921] = {category="ll"}, +[43922] = {category="ll"}, +[43923] = {category="ll"}, +[43924] = {category="ll"}, +[43925] = {category="ll"}, +[43926] = {category="ll"}, +[43927] = {category="ll"}, +[43928] = {category="ll"}, +[43929] = {category="ll"}, +[43930] = {category="ll"}, +[43931] = {category="ll"}, +[43932] = {category="ll"}, +[43933] = {category="ll"}, +[43934] = {category="ll"}, +[43935] = {category="ll"}, +[43936] = {category="ll"}, +[43937] = {category="ll"}, +[43938] = {category="ll"}, +[43939] = {category="ll"}, +[43940] = {category="ll"}, +[43941] = {category="ll"}, +[43942] = {category="ll"}, +[43943] = {category="ll"}, +[43944] = {category="ll"}, +[43945] = {category="ll"}, +[43946] = {category="ll"}, +[43947] = {category="ll"}, +[43948] = {category="ll"}, +[43949] = {category="ll"}, +[43950] = {category="ll"}, +[43951] = {category="ll"}, +[43952] = {category="ll"}, +[43953] = {category="ll"}, +[43954] = {category="ll"}, +[43955] = {category="ll"}, +[43956] = {category="ll"}, +[43957] = {category="ll"}, +[43958] = {category="ll"}, +[43959] = {category="ll"}, +[43960] = {category="ll"}, +[43961] = {category="ll"}, +[43962] = {category="ll"}, +[43963] = {category="ll"}, +[43964] = {category="ll"}, +[43965] = {category="ll"}, +[43966] = {category="ll"}, +[43967] = {category="ll"}, +[43968] = {category="lo"}, +[43969] = {category="lo"}, +[43970] = {category="lo"}, +[43971] = {category="lo"}, +[43972] = {category="lo"}, +[43973] = {category="lo"}, +[43974] = {category="lo"}, +[43975] = {category="lo"}, +[43976] = {category="lo"}, +[43977] = {category="lo"}, +[43978] = {category="lo"}, +[43979] = {category="lo"}, +[43980] = {category="lo"}, +[43981] = {category="lo"}, +[43982] = {category="lo"}, +[43983] = {category="lo"}, +[43984] = {category="lo"}, +[43985] = {category="lo"}, +[43986] = {category="lo"}, +[43987] = {category="lo"}, +[43988] = {category="lo"}, +[43989] = {category="lo"}, +[43990] = {category="lo"}, +[43991] = {category="lo"}, +[43992] = {category="lo"}, +[43993] = {category="lo"}, +[43994] = {category="lo"}, +[43995] = {category="lo"}, +[43996] = {category="lo"}, +[43997] = {category="lo"}, +[43998] = {category="lo"}, +[43999] = {category="lo"}, +[44000] = {category="lo"}, +[44001] = {category="lo"}, +[44002] = {category="lo"}, +[44032] = {category="lo"}, +[55203] = {category="lo"}, +[55216] = {category="lo"}, +[55217] = {category="lo"}, +[55218] = {category="lo"}, +[55219] = {category="lo"}, +[55220] = {category="lo"}, +[55221] = {category="lo"}, +[55222] = {category="lo"}, +[55223] = {category="lo"}, +[55224] = {category="lo"}, +[55225] = {category="lo"}, +[55226] = {category="lo"}, +[55227] = {category="lo"}, +[55228] = {category="lo"}, +[55229] = {category="lo"}, +[55230] = {category="lo"}, +[55231] = {category="lo"}, +[55232] = {category="lo"}, +[55233] = {category="lo"}, +[55234] = {category="lo"}, +[55235] = {category="lo"}, +[55236] = {category="lo"}, +[55237] = {category="lo"}, +[55238] = {category="lo"}, +[55243] = {category="lo"}, +[55244] = {category="lo"}, +[55245] = {category="lo"}, +[55246] = {category="lo"}, +[55247] = {category="lo"}, +[55248] = {category="lo"}, +[55249] = {category="lo"}, +[55250] = {category="lo"}, +[55251] = {category="lo"}, +[55252] = {category="lo"}, +[55253] = {category="lo"}, +[55254] = {category="lo"}, +[55255] = {category="lo"}, +[55256] = {category="lo"}, +[55257] = {category="lo"}, +[55258] = {category="lo"}, +[55259] = {category="lo"}, +[55260] = {category="lo"}, +[55261] = {category="lo"}, +[55262] = {category="lo"}, +[55263] = {category="lo"}, +[55264] = {category="lo"}, +[55265] = {category="lo"}, +[55266] = {category="lo"}, +[55267] = {category="lo"}, +[55268] = {category="lo"}, +[55269] = {category="lo"}, +[55270] = {category="lo"}, +[55271] = {category="lo"}, +[55272] = {category="lo"}, +[55273] = {category="lo"}, +[55274] = {category="lo"}, +[55275] = {category="lo"}, +[55276] = {category="lo"}, +[55277] = {category="lo"}, +[55278] = {category="lo"}, +[55279] = {category="lo"}, +[55280] = {category="lo"}, +[55281] = {category="lo"}, +[55282] = {category="lo"}, +[55283] = {category="lo"}, +[55284] = {category="lo"}, +[55285] = {category="lo"}, +[55286] = {category="lo"}, +[55287] = {category="lo"}, +[55288] = {category="lo"}, +[55289] = {category="lo"}, +[55290] = {category="lo"}, +[55291] = {category="lo"}, +[63744] = {category="lo", shcode=35912}, +[63745] = {category="lo", shcode=26356}, +[63746] = {category="lo", shcode=36554}, +[63747] = {category="lo", shcode=36040}, +[63748] = {category="lo", shcode=28369}, +[63749] = {category="lo", shcode=20018}, +[63750] = {category="lo", shcode=21477}, +[63751] = {category="lo", shcode=40860}, +[63752] = {category="lo", shcode=40860}, +[63753] = {category="lo", shcode=22865}, +[63754] = {category="lo", shcode=37329}, +[63755] = {category="lo", shcode=21895}, +[63756] = {category="lo", shcode=22856}, +[63757] = {category="lo", shcode=25078}, +[63758] = {category="lo", shcode=30313}, +[63759] = {category="lo", shcode=32645}, +[63760] = {category="lo", shcode=34367}, +[63761] = {category="lo", shcode=34746}, +[63762] = {category="lo", shcode=35064}, +[63763] = {category="lo", shcode=37007}, +[63764] = {category="lo", shcode=27138}, +[63765] = {category="lo", shcode=27931}, +[63766] = {category="lo", shcode=28889}, +[63767] = {category="lo", shcode=29662}, +[63768] = {category="lo", shcode=33853}, +[63769] = {category="lo", shcode=37226}, +[63770] = {category="lo", shcode=39409}, +[63771] = {category="lo", shcode=20098}, +[63772] = {category="lo", shcode=21365}, +[63773] = {category="lo", shcode=27396}, +[63774] = {category="lo", shcode=29211}, +[63775] = {category="lo", shcode=34349}, +[63776] = {category="lo", shcode=40478}, +[63777] = {category="lo", shcode=23888}, +[63778] = {category="lo", shcode=28651}, +[63779] = {category="lo", shcode=34253}, +[63780] = {category="lo", shcode=35172}, +[63781] = {category="lo", shcode=25289}, +[63782] = {category="lo", shcode=33240}, +[63783] = {category="lo", shcode=34847}, +[63784] = {category="lo", shcode=24266}, +[63785] = {category="lo", shcode=26391}, +[63786] = {category="lo", shcode=28010}, +[63787] = {category="lo", shcode=29436}, +[63788] = {category="lo", shcode=37070}, +[63789] = {category="lo", shcode=20358}, +[63790] = {category="lo", shcode=20919}, +[63791] = {category="lo", shcode=21214}, +[63792] = {category="lo", shcode=25796}, +[63793] = {category="lo", shcode=27347}, +[63794] = {category="lo", shcode=29200}, +[63795] = {category="lo", shcode=30439}, +[63796] = {category="lo", shcode=32769}, +[63797] = {category="lo", shcode=34310}, +[63798] = {category="lo", shcode=34396}, +[63799] = {category="lo", shcode=36335}, +[63800] = {category="lo", shcode=38706}, +[63801] = {category="lo", shcode=39791}, +[63802] = {category="lo", shcode=40442}, +[63803] = {category="lo", shcode=30860}, +[63804] = {category="lo", shcode=31103}, +[63805] = {category="lo", shcode=32160}, +[63806] = {category="lo", shcode=33737}, +[63807] = {category="lo", shcode=37636}, +[63808] = {category="lo", shcode=40575}, +[63809] = {category="lo", shcode=35542}, +[63810] = {category="lo", shcode=22751}, +[63811] = {category="lo", shcode=24324}, +[63812] = {category="lo", shcode=31840}, +[63813] = {category="lo", shcode=32894}, +[63814] = {category="lo", shcode=29282}, +[63815] = {category="lo", shcode=30922}, +[63816] = {category="lo", shcode=36034}, +[63817] = {category="lo", shcode=38647}, +[63818] = {category="lo", shcode=22744}, +[63819] = {category="lo", shcode=23650}, +[63820] = {category="lo", shcode=27155}, +[63821] = {category="lo", shcode=28122}, +[63822] = {category="lo", shcode=28431}, +[63823] = {category="lo", shcode=32047}, +[63824] = {category="lo", shcode=32311}, +[63825] = {category="lo", shcode=38475}, +[63826] = {category="lo", shcode=21202}, +[63827] = {category="lo", shcode=32907}, +[63828] = {category="lo", shcode=20956}, +[63829] = {category="lo", shcode=20940}, +[63830] = {category="lo", shcode=31260}, +[63831] = {category="lo", shcode=32190}, +[63832] = {category="lo", shcode=33777}, +[63833] = {category="lo", shcode=38517}, +[63834] = {category="lo", shcode=35712}, +[63835] = {category="lo", shcode=25295}, +[63836] = {category="lo", shcode=27138}, +[63837] = {category="lo", shcode=35582}, +[63838] = {category="lo", shcode=20025}, +[63839] = {category="lo", shcode=23527}, +[63840] = {category="lo", shcode=24594}, +[63841] = {category="lo", shcode=29575}, +[63842] = {category="lo", shcode=30064}, +[63843] = {category="lo", shcode=21271}, +[63844] = {category="lo", shcode=30971}, +[63845] = {category="lo", shcode=20415}, +[63846] = {category="lo", shcode=24489}, +[63847] = {category="lo", shcode=19981}, +[63848] = {category="lo", shcode=27852}, +[63849] = {category="lo", shcode=25976}, +[63850] = {category="lo", shcode=32034}, +[63851] = {category="lo", shcode=21443}, +[63852] = {category="lo", shcode=22622}, +[63853] = {category="lo", shcode=30465}, +[63854] = {category="lo", shcode=33865}, +[63855] = {category="lo", shcode=35498}, +[63856] = {category="lo", shcode=27578}, +[63857] = {category="lo", shcode=36784}, +[63858] = {category="lo", shcode=27784}, +[63859] = {category="lo", shcode=25342}, +[63860] = {category="lo", shcode=33509}, +[63861] = {category="lo", shcode=25504}, +[63862] = {category="lo", shcode=30053}, +[63863] = {category="lo", shcode=20142}, +[63864] = {category="lo", shcode=20841}, +[63865] = {category="lo", shcode=20937}, +[63866] = {category="lo", shcode=26753}, +[63867] = {category="lo", shcode=31975}, +[63868] = {category="lo", shcode=33391}, +[63869] = {category="lo", shcode=35538}, +[63870] = {category="lo", shcode=37327}, +[63871] = {category="lo", shcode=21237}, +[63872] = {category="lo", shcode=21570}, +[63873] = {category="lo", shcode=22899}, +[63874] = {category="lo", shcode=24300}, +[63875] = {category="lo", shcode=26053}, +[63876] = {category="lo", shcode=28670}, +[63877] = {category="lo", shcode=31018}, +[63878] = {category="lo", shcode=38317}, +[63879] = {category="lo", shcode=39530}, +[63880] = {category="lo", shcode=40599}, +[63881] = {category="lo", shcode=40654}, +[63882] = {category="lo", shcode=21147}, +[63883] = {category="lo", shcode=26310}, +[63884] = {category="lo", shcode=27511}, +[63885] = {category="lo", shcode=36706}, +[63886] = {category="lo", shcode=24180}, +[63887] = {category="lo", shcode=24976}, +[63888] = {category="lo", shcode=25088}, +[63889] = {category="lo", shcode=25754}, +[63890] = {category="lo", shcode=28451}, +[63891] = {category="lo", shcode=29001}, +[63892] = {category="lo", shcode=29833}, +[63893] = {category="lo", shcode=31178}, +[63894] = {category="lo", shcode=32244}, +[63895] = {category="lo", shcode=32879}, +[63896] = {category="lo", shcode=36646}, +[63897] = {category="lo", shcode=34030}, +[63898] = {category="lo", shcode=36899}, +[63899] = {category="lo", shcode=37706}, +[63900] = {category="lo", shcode=21015}, +[63901] = {category="lo", shcode=21155}, +[63902] = {category="lo", shcode=21693}, +[63903] = {category="lo", shcode=28872}, +[63904] = {category="lo", shcode=35010}, +[63905] = {category="lo", shcode=35498}, +[63906] = {category="lo", shcode=24265}, +[63907] = {category="lo", shcode=24565}, +[63908] = {category="lo", shcode=25467}, +[63909] = {category="lo", shcode=27566}, +[63910] = {category="lo", shcode=31806}, +[63911] = {category="lo", shcode=29557}, +[63912] = {category="lo", shcode=20196}, +[63913] = {category="lo", shcode=22265}, +[63914] = {category="lo", shcode=23527}, +[63915] = {category="lo", shcode=23994}, +[63916] = {category="lo", shcode=24604}, +[63917] = {category="lo", shcode=29618}, +[63918] = {category="lo", shcode=29801}, +[63919] = {category="lo", shcode=32666}, +[63920] = {category="lo", shcode=32838}, +[63921] = {category="lo", shcode=37428}, +[63922] = {category="lo", shcode=38646}, +[63923] = {category="lo", shcode=38728}, +[63924] = {category="lo", shcode=38936}, +[63925] = {category="lo", shcode=20363}, +[63926] = {category="lo", shcode=31150}, +[63927] = {category="lo", shcode=37300}, +[63928] = {category="lo", shcode=38584}, +[63929] = {category="lo", shcode=24801}, +[63930] = {category="lo", shcode=20102}, +[63931] = {category="lo", shcode=20698}, +[63932] = {category="lo", shcode=23534}, +[63933] = {category="lo", shcode=23615}, +[63934] = {category="lo", shcode=26009}, +[63935] = {category="lo", shcode=27138}, +[63936] = {category="lo", shcode=29134}, +[63937] = {category="lo", shcode=30274}, +[63938] = {category="lo", shcode=34044}, +[63939] = {category="lo", shcode=36988}, +[63940] = {category="lo", shcode=40845}, +[63941] = {category="lo", shcode=26248}, +[63942] = {category="lo", shcode=38446}, +[63943] = {category="lo", shcode=21129}, +[63944] = {category="lo", shcode=26491}, +[63945] = {category="lo", shcode=26611}, +[63946] = {category="lo", shcode=27969}, +[63947] = {category="lo", shcode=28316}, +[63948] = {category="lo", shcode=29705}, +[63949] = {category="lo", shcode=30041}, +[63950] = {category="lo", shcode=30827}, +[63951] = {category="lo", shcode=32016}, +[63952] = {category="lo", shcode=39006}, +[63953] = {category="lo", shcode=20845}, +[63954] = {category="lo", shcode=25134}, +[63955] = {category="lo", shcode=38520}, +[63956] = {category="lo", shcode=20523}, +[63957] = {category="lo", shcode=23833}, +[63958] = {category="lo", shcode=28138}, +[63959] = {category="lo", shcode=36650}, +[63960] = {category="lo", shcode=24459}, +[63961] = {category="lo", shcode=24900}, +[63962] = {category="lo", shcode=26647}, +[63963] = {category="lo", shcode=29575}, +[63964] = {category="lo", shcode=38534}, +[63965] = {category="lo", shcode=21033}, +[63966] = {category="lo", shcode=21519}, +[63967] = {category="lo", shcode=23653}, +[63968] = {category="lo", shcode=26131}, +[63969] = {category="lo", shcode=26446}, +[63970] = {category="lo", shcode=26792}, +[63971] = {category="lo", shcode=27877}, +[63972] = {category="lo", shcode=29702}, +[63973] = {category="lo", shcode=30178}, +[63974] = {category="lo", shcode=32633}, +[63975] = {category="lo", shcode=35023}, +[63976] = {category="lo", shcode=35041}, +[63977] = {category="lo", shcode=37324}, +[63978] = {category="lo", shcode=38626}, +[63979] = {category="lo", shcode=21311}, +[63980] = {category="lo", shcode=28346}, +[63981] = {category="lo", shcode=21533}, +[63982] = {category="lo", shcode=29136}, +[63983] = {category="lo", shcode=29848}, +[63984] = {category="lo", shcode=34298}, +[63985] = {category="lo", shcode=38563}, +[63986] = {category="lo", shcode=40023}, +[63987] = {category="lo", shcode=40607}, +[63988] = {category="lo", shcode=26519}, +[63989] = {category="lo", shcode=28107}, +[63990] = {category="lo", shcode=33256}, +[63991] = {category="lo", shcode=31435}, +[63992] = {category="lo", shcode=31520}, +[63993] = {category="lo", shcode=31890}, +[63994] = {category="lo", shcode=29376}, +[63995] = {category="lo", shcode=28825}, +[63996] = {category="lo", shcode=35672}, +[63997] = {category="lo", shcode=20160}, +[63998] = {category="lo", shcode=33590}, +[63999] = {category="lo", shcode=21050}, +[64000] = {category="lo", shcode=20999}, +[64001] = {category="lo", shcode=24230}, +[64002] = {category="lo", shcode=25299}, +[64003] = {category="lo", shcode=31958}, +[64004] = {category="lo", shcode=23429}, +[64005] = {category="lo", shcode=27934}, +[64006] = {category="lo", shcode=26292}, +[64007] = {category="lo", shcode=36667}, +[64008] = {category="lo", shcode=34892}, +[64009] = {category="lo", shcode=38477}, +[64010] = {category="lo", shcode=35211}, +[64011] = {category="lo", shcode=24275}, +[64012] = {category="lo", shcode=20800}, +[64013] = {category="lo", shcode=21952}, +[64014] = {category="lo"}, +[64015] = {category="lo"}, +[64016] = {category="lo", shcode=22618}, +[64017] = {category="lo"}, +[64018] = {category="lo", shcode=26228}, +[64019] = {category="lo"}, +[64020] = {category="lo"}, +[64021] = {category="lo", shcode=20958}, +[64022] = {category="lo", shcode=29482}, +[64023] = {category="lo", shcode=30410}, +[64024] = {category="lo", shcode=31036}, +[64025] = {category="lo", shcode=31070}, +[64026] = {category="lo", shcode=31077}, +[64027] = {category="lo", shcode=31119}, +[64028] = {category="lo", shcode=38742}, +[64029] = {category="lo", shcode=31934}, +[64030] = {category="lo", shcode=32701}, +[64031] = {category="lo"}, +[64032] = {category="lo", shcode=34322}, +[64033] = {category="lo"}, +[64034] = {category="lo", shcode=35576}, +[64035] = {category="lo"}, +[64036] = {category="lo"}, +[64037] = {category="lo", shcode=36920}, +[64038] = {category="lo", shcode=37117}, +[64039] = {category="lo"}, +[64040] = {category="lo"}, +[64041] = {category="lo"}, +[64042] = {category="lo", shcode=39151}, +[64043] = {category="lo", shcode=39164}, +[64044] = {category="lo", shcode=39208}, +[64045] = {category="lo", shcode=40372}, +[64046] = {category="lo", shcode=37086}, +[64047] = {category="lo", shcode=38583}, +[64048] = {category="lo", shcode=20398}, +[64049] = {category="lo", shcode=20711}, +[64050] = {category="lo", shcode=20813}, +[64051] = {category="lo", shcode=21193}, +[64052] = {category="lo", shcode=21220}, +[64053] = {category="lo", shcode=21329}, +[64054] = {category="lo", shcode=21917}, +[64055] = {category="lo", shcode=22022}, +[64056] = {category="lo", shcode=22120}, +[64057] = {category="lo", shcode=22592}, +[64058] = {category="lo", shcode=22696}, +[64059] = {category="lo", shcode=23652}, +[64060] = {category="lo", shcode=23662}, +[64061] = {category="lo", shcode=24724}, +[64062] = {category="lo", shcode=24936}, +[64063] = {category="lo", shcode=24974}, +[64064] = {category="lo", shcode=25074}, +[64065] = {category="lo", shcode=25935}, +[64066] = {category="lo", shcode=26082}, +[64067] = {category="lo", shcode=26257}, +[64068] = {category="lo", shcode=26757}, +[64069] = {category="lo", shcode=28023}, +[64070] = {category="lo", shcode=28186}, +[64071] = {category="lo", shcode=28450}, +[64072] = {category="lo", shcode=29038}, +[64073] = {category="lo", shcode=29227}, +[64074] = {category="lo", shcode=29730}, +[64075] = {category="lo", shcode=30865}, +[64076] = {category="lo", shcode=31038}, +[64077] = {category="lo", shcode=31049}, +[64078] = {category="lo", shcode=31048}, +[64079] = {category="lo", shcode=31056}, +[64080] = {category="lo", shcode=31062}, +[64081] = {category="lo", shcode=31069}, +[64082] = {category="lo", shcode=31117}, +[64083] = {category="lo", shcode=31118}, +[64084] = {category="lo", shcode=31296}, +[64085] = {category="lo", shcode=31361}, +[64086] = {category="lo", shcode=31680}, +[64087] = {category="lo", shcode=32244}, +[64088] = {category="lo", shcode=32265}, +[64089] = {category="lo", shcode=32321}, +[64090] = {category="lo", shcode=32626}, +[64091] = {category="lo", shcode=32773}, +[64092] = {category="lo", shcode=33261}, +[64093] = {category="lo", shcode=33401}, +[64094] = {category="lo", shcode=33401}, +[64095] = {category="lo", shcode=33879}, +[64096] = {category="lo", shcode=35088}, +[64097] = {category="lo", shcode=35222}, +[64098] = {category="lo", shcode=35585}, +[64099] = {category="lo", shcode=35641}, +[64100] = {category="lo", shcode=36051}, +[64101] = {category="lo", shcode=36104}, +[64102] = {category="lo", shcode=36790}, +[64103] = {category="lo", shcode=36920}, +[64104] = {category="lo", shcode=38627}, +[64105] = {category="lo", shcode=38911}, +[64106] = {category="lo", shcode=38971}, +[64107] = {category="lo", shcode=24693}, +[64108] = {category="lo", shcode=148206}, +[64109] = {category="lo", shcode=33304}, +[64112] = {category="lo", shcode=20006}, +[64113] = {category="lo", shcode=20917}, +[64114] = {category="lo", shcode=20840}, +[64115] = {category="lo", shcode=20352}, +[64116] = {category="lo", shcode=20805}, +[64117] = {category="lo", shcode=20864}, +[64118] = {category="lo", shcode=21191}, +[64119] = {category="lo", shcode=21242}, +[64120] = {category="lo", shcode=21917}, +[64121] = {category="lo", shcode=21845}, +[64122] = {category="lo", shcode=21913}, +[64123] = {category="lo", shcode=21986}, +[64124] = {category="lo", shcode=22618}, +[64125] = {category="lo", shcode=22707}, +[64126] = {category="lo", shcode=22852}, +[64127] = {category="lo", shcode=22868}, +[64128] = {category="lo", shcode=23138}, +[64129] = {category="lo", shcode=23336}, +[64130] = {category="lo", shcode=24274}, +[64131] = {category="lo", shcode=24281}, +[64132] = {category="lo", shcode=24425}, +[64133] = {category="lo", shcode=24493}, +[64134] = {category="lo", shcode=24792}, +[64135] = {category="lo", shcode=24910}, +[64136] = {category="lo", shcode=24840}, +[64137] = {category="lo", shcode=24974}, +[64138] = {category="lo", shcode=24928}, +[64139] = {category="lo", shcode=25074}, +[64140] = {category="lo", shcode=25140}, +[64141] = {category="lo", shcode=25540}, +[64142] = {category="lo", shcode=25628}, +[64143] = {category="lo", shcode=25682}, +[64144] = {category="lo", shcode=25942}, +[64145] = {category="lo", shcode=26228}, +[64146] = {category="lo", shcode=26391}, +[64147] = {category="lo", shcode=26395}, +[64148] = {category="lo", shcode=26454}, +[64149] = {category="lo", shcode=27513}, +[64150] = {category="lo", shcode=27578}, +[64151] = {category="lo", shcode=27969}, +[64152] = {category="lo", shcode=28379}, +[64153] = {category="lo", shcode=28363}, +[64154] = {category="lo", shcode=28450}, +[64155] = {category="lo", shcode=28702}, +[64156] = {category="lo", shcode=29038}, +[64157] = {category="lo", shcode=30631}, +[64158] = {category="lo", shcode=29237}, +[64159] = {category="lo", shcode=29359}, +[64160] = {category="lo", shcode=29482}, +[64161] = {category="lo", shcode=29809}, +[64162] = {category="lo", shcode=29958}, +[64163] = {category="lo", shcode=30011}, +[64164] = {category="lo", shcode=30237}, +[64165] = {category="lo", shcode=30239}, +[64166] = {category="lo", shcode=30410}, +[64167] = {category="lo", shcode=30427}, +[64168] = {category="lo", shcode=30452}, +[64169] = {category="lo", shcode=30538}, +[64170] = {category="lo", shcode=30528}, +[64171] = {category="lo", shcode=30924}, +[64172] = {category="lo", shcode=31409}, +[64173] = {category="lo", shcode=31680}, +[64174] = {category="lo", shcode=31867}, +[64175] = {category="lo", shcode=32091}, +[64176] = {category="lo", shcode=32244}, +[64177] = {category="lo", shcode=32574}, +[64178] = {category="lo", shcode=32773}, +[64179] = {category="lo", shcode=33618}, +[64180] = {category="lo", shcode=33775}, +[64181] = {category="lo", shcode=34681}, +[64182] = {category="lo", shcode=35137}, +[64183] = {category="lo", shcode=35206}, +[64184] = {category="lo", shcode=35222}, +[64185] = {category="lo", shcode=35519}, +[64186] = {category="lo", shcode=35576}, +[64187] = {category="lo", shcode=35531}, +[64188] = {category="lo", shcode=35585}, +[64189] = {category="lo", shcode=35582}, +[64190] = {category="lo", shcode=35565}, +[64191] = {category="lo", shcode=35641}, +[64192] = {category="lo", shcode=35722}, +[64193] = {category="lo", shcode=36104}, +[64194] = {category="lo", shcode=36664}, +[64195] = {category="lo", shcode=36978}, +[64196] = {category="lo", shcode=37273}, +[64197] = {category="lo", shcode=37494}, +[64198] = {category="lo", shcode=38524}, +[64199] = {category="lo", shcode=38627}, +[64200] = {category="lo", shcode=38742}, +[64201] = {category="lo", shcode=38875}, +[64202] = {category="lo", shcode=38911}, +[64203] = {category="lo", shcode=38923}, +[64204] = {category="lo", shcode=38971}, +[64205] = {category="lo", shcode=39698}, +[64206] = {category="lo", shcode=40860}, +[64207] = {category="lo", shcode=141386}, +[64208] = {category="lo", shcode=141380}, +[64209] = {category="lo", shcode=144341}, +[64210] = {category="lo", shcode=15261}, +[64211] = {category="lo", shcode=16408}, +[64212] = {category="lo", shcode=16441}, +[64213] = {category="lo", shcode=152137}, +[64214] = {category="lo", shcode=154832}, +[64215] = {category="lo", shcode=163539}, +[64216] = {category="lo", shcode=40771}, +[64217] = {category="lo", shcode=40846}, +[64256] = {category="ll", shcode=12}, +[64257] = {category="ll", shcode=12}, +[64258] = {category="ll", shcode=12}, +[64259] = {category="ll", shcode=12}, +[64260] = {category="ll", shcode=12}, +[64261] = {category="ll", shcode=12}, +[64262] = {category="ll", shcode=12}, +[64275] = {category="ll", shcode=12}, +[64276] = {category="ll", shcode=12}, +[64277] = {category="ll", shcode=12}, +[64278] = {category="ll", shcode=12}, +[64279] = {category="ll", shcode=12}, +[64285] = {category="lo", shcode=1497}, +[64287] = {category="lo", shcode=1522}, +[64288] = {category="lo", shcode=15}, +[64289] = {category="lo", shcode=15}, +[64290] = {category="lo", shcode=15}, +[64291] = {category="lo", shcode=15}, +[64292] = {category="lo", shcode=15}, +[64293] = {category="lo", shcode=15}, +[64294] = {category="lo", shcode=15}, +[64295] = {category="lo", shcode=15}, +[64296] = {category="lo", shcode=15}, +[64298] = {category="lo", shcode=1513}, +[64299] = {category="lo", shcode=1513}, +[64300] = {category="lo", shcode=64329}, +[64301] = {category="lo", shcode=64329}, +[64302] = {category="lo", shcode=1488}, +[64303] = {category="lo", shcode=1488}, +[64304] = {category="lo", shcode=1488}, +[64305] = {category="lo", shcode=1489}, +[64306] = {category="lo", shcode=1490}, +[64307] = {category="lo", shcode=1491}, +[64308] = {category="lo", shcode=1492}, +[64309] = {category="lo", shcode=1493}, +[64310] = {category="lo", shcode=1494}, +[64312] = {category="lo", shcode=1496}, +[64313] = {category="lo", shcode=1497}, +[64314] = {category="lo", shcode=1498}, +[64315] = {category="lo", shcode=1499}, +[64316] = {category="lo", shcode=1500}, +[64318] = {category="lo", shcode=1502}, +[64320] = {category="lo", shcode=1504}, +[64321] = {category="lo", shcode=1505}, +[64323] = {category="lo", shcode=1507}, +[64324] = {category="lo", shcode=1508}, +[64326] = {category="lo", shcode=1510}, +[64327] = {category="lo", shcode=1511}, +[64328] = {category="lo", shcode=1512}, +[64329] = {category="lo", shcode=1513}, +[64330] = {category="lo", shcode=1514}, +[64331] = {category="lo", shcode=1493}, +[64332] = {category="lo", shcode=1489}, +[64333] = {category="lo", shcode=1499}, +[64334] = {category="lo", shcode=1508}, +[64335] = {category="lo", shcode=12}, +[64336] = {category="lo", shcode=10}, +[64337] = {category="lo", shcode=15}, +[64338] = {category="lo", shcode=10}, +[64339] = {category="lo", shcode=15}, +[64340] = {category="lo", shcode=10}, +[64341] = {category="lo", shcode=237}, +[64342] = {category="lo", shcode=10}, +[64343] = {category="lo", shcode=15}, +[64344] = {category="lo", shcode=10}, +[64345] = {category="lo", shcode=237}, +[64346] = {category="lo", shcode=10}, +[64347] = {category="lo", shcode=15}, +[64348] = {category="lo", shcode=10}, +[64349] = {category="lo", shcode=237}, +[64350] = {category="lo", shcode=10}, +[64351] = {category="lo", shcode=15}, +[64352] = {category="lo", shcode=10}, +[64353] = {category="lo", shcode=237}, +[64354] = {category="lo", shcode=10}, +[64355] = {category="lo", shcode=15}, +[64356] = {category="lo", shcode=10}, +[64357] = {category="lo", shcode=237}, +[64358] = {category="lo", shcode=10}, +[64359] = {category="lo", shcode=15}, +[64360] = {category="lo", shcode=10}, +[64361] = {category="lo", shcode=237}, +[64362] = {category="lo", shcode=10}, +[64363] = {category="lo", shcode=15}, +[64364] = {category="lo", shcode=10}, +[64365] = {category="lo", shcode=237}, +[64366] = {category="lo", shcode=10}, +[64367] = {category="lo", shcode=15}, +[64368] = {category="lo", shcode=10}, +[64369] = {category="lo", shcode=237}, +[64370] = {category="lo", shcode=10}, +[64371] = {category="lo", shcode=15}, +[64372] = {category="lo", shcode=10}, +[64373] = {category="lo", shcode=237}, +[64374] = {category="lo", shcode=10}, +[64375] = {category="lo", shcode=15}, +[64376] = {category="lo", shcode=10}, +[64377] = {category="lo", shcode=237}, +[64378] = {category="lo", shcode=10}, +[64379] = {category="lo", shcode=15}, +[64380] = {category="lo", shcode=10}, +[64381] = {category="lo", shcode=237}, +[64382] = {category="lo", shcode=10}, +[64383] = {category="lo", shcode=15}, +[64384] = {category="lo", shcode=10}, +[64385] = {category="lo", shcode=237}, +[64386] = {category="lo", shcode=10}, +[64387] = {category="lo", shcode=15}, +[64388] = {category="lo", shcode=10}, +[64389] = {category="lo", shcode=15}, +[64390] = {category="lo", shcode=10}, +[64391] = {category="lo", shcode=15}, +[64392] = {category="lo", shcode=10}, +[64393] = {category="lo", shcode=15}, +[64394] = {category="lo", shcode=10}, +[64395] = {category="lo", shcode=15}, +[64396] = {category="lo", shcode=10}, +[64397] = {category="lo", shcode=15}, +[64398] = {category="lo", shcode=10}, +[64399] = {category="lo", shcode=15}, +[64400] = {category="lo", shcode=10}, +[64401] = {category="lo", shcode=237}, +[64402] = {category="lo", shcode=10}, +[64403] = {category="lo", shcode=15}, +[64404] = {category="lo", shcode=10}, +[64405] = {category="lo", shcode=237}, +[64406] = {category="lo", shcode=10}, +[64407] = {category="lo", shcode=15}, +[64408] = {category="lo", shcode=10}, +[64409] = {category="lo", shcode=237}, +[64410] = {category="lo", shcode=10}, +[64411] = {category="lo", shcode=15}, +[64412] = {category="lo", shcode=10}, +[64413] = {category="lo", shcode=237}, +[64414] = {category="lo", shcode=10}, +[64415] = {category="lo", shcode=15}, +[64416] = {category="lo", shcode=10}, +[64417] = {category="lo", shcode=15}, +[64418] = {category="lo", shcode=10}, +[64419] = {category="lo", shcode=237}, +[64420] = {category="lo", shcode=10}, +[64421] = {category="lo", shcode=15}, +[64422] = {category="lo", shcode=10}, +[64423] = {category="lo", shcode=15}, +[64424] = {category="lo", shcode=10}, +[64425] = {category="lo", shcode=237}, +[64426] = {category="lo", shcode=10}, +[64427] = {category="lo", shcode=15}, +[64428] = {category="lo", shcode=10}, +[64429] = {category="lo", shcode=237}, +[64430] = {category="lo", shcode=10}, +[64431] = {category="lo", shcode=15}, +[64432] = {category="lo", shcode=10}, +[64433] = {category="lo", shcode=15}, +[64467] = {category="lo", shcode=10}, +[64468] = {category="lo", shcode=15}, +[64469] = {category="lo", shcode=10}, +[64470] = {category="lo", shcode=237}, +[64471] = {category="lo", shcode=10}, +[64472] = {category="lo", shcode=15}, +[64473] = {category="lo", shcode=10}, +[64474] = {category="lo", shcode=15}, +[64475] = {category="lo", shcode=10}, +[64476] = {category="lo", shcode=15}, +[64477] = {category="lo", shcode=10}, +[64478] = {category="lo", shcode=10}, +[64479] = {category="lo", shcode=15}, +[64480] = {category="lo", shcode=10}, +[64481] = {category="lo", shcode=15}, +[64482] = {category="lo", shcode=10}, +[64483] = {category="lo", shcode=15}, +[64484] = {category="lo", shcode=10}, +[64485] = {category="lo", shcode=15}, +[64486] = {category="lo", shcode=10}, +[64487] = {category="lo", shcode=237}, +[64488] = {category="lo", shcode=10}, +[64489] = {category="lo", shcode=237}, +[64490] = {category="lo", shcode=10}, +[64491] = {category="lo", shcode=15}, +[64492] = {category="lo", shcode=10}, +[64493] = {category="lo", shcode=15}, +[64494] = {category="lo", shcode=10}, +[64495] = {category="lo", shcode=15}, +[64496] = {category="lo", shcode=10}, +[64497] = {category="lo", shcode=15}, +[64498] = {category="lo", shcode=10}, +[64499] = {category="lo", shcode=15}, +[64500] = {category="lo", shcode=10}, +[64501] = {category="lo", shcode=15}, +[64502] = {category="lo", shcode=10}, +[64503] = {category="lo", shcode=15}, +[64504] = {category="lo", shcode=10}, +[64505] = {category="lo", shcode=10}, +[64506] = {category="lo", shcode=15}, +[64507] = {category="lo", shcode=10}, +[64508] = {category="lo", shcode=10}, +[64509] = {category="lo", shcode=15}, +[64510] = {category="lo", shcode=10}, +[64511] = {category="lo", shcode=237}, +[64512] = {category="lo", shcode=10}, +[64513] = {category="lo", shcode=10}, +[64514] = {category="lo", shcode=10}, +[64515] = {category="lo", shcode=10}, +[64516] = {category="lo", shcode=10}, +[64517] = {category="lo", shcode=10}, +[64518] = {category="lo", shcode=10}, +[64519] = {category="lo", shcode=10}, +[64520] = {category="lo", shcode=10}, +[64521] = {category="lo", shcode=10}, +[64522] = {category="lo", shcode=10}, +[64523] = {category="lo", shcode=10}, +[64524] = {category="lo", shcode=10}, +[64525] = {category="lo", shcode=10}, +[64526] = {category="lo", shcode=10}, +[64527] = {category="lo", shcode=10}, +[64528] = {category="lo", shcode=10}, +[64529] = {category="lo", shcode=10}, +[64530] = {category="lo", shcode=10}, +[64531] = {category="lo", shcode=10}, +[64532] = {category="lo", shcode=10}, +[64533] = {category="lo", shcode=10}, +[64534] = {category="lo", shcode=10}, +[64535] = {category="lo", shcode=10}, +[64536] = {category="lo", shcode=10}, +[64537] = {category="lo", shcode=10}, +[64538] = {category="lo", shcode=10}, +[64539] = {category="lo", shcode=10}, +[64540] = {category="lo", shcode=10}, +[64541] = {category="lo", shcode=10}, +[64542] = {category="lo", shcode=10}, +[64543] = {category="lo", shcode=10}, +[64544] = {category="lo", shcode=10}, +[64545] = {category="lo", shcode=10}, +[64546] = {category="lo", shcode=10}, +[64547] = {category="lo", shcode=10}, +[64548] = {category="lo", shcode=10}, +[64549] = {category="lo", shcode=10}, +[64550] = {category="lo", shcode=10}, +[64551] = {category="lo", shcode=10}, +[64552] = {category="lo", shcode=10}, +[64553] = {category="lo", shcode=10}, +[64554] = {category="lo", shcode=10}, +[64555] = {category="lo", shcode=10}, +[64556] = {category="lo", shcode=10}, +[64557] = {category="lo", shcode=10}, +[64558] = {category="lo", shcode=10}, +[64559] = {category="lo", shcode=10}, +[64560] = {category="lo", shcode=10}, +[64561] = {category="lo", shcode=10}, +[64562] = {category="lo", shcode=10}, +[64563] = {category="lo", shcode=10}, +[64564] = {category="lo", shcode=10}, +[64565] = {category="lo", shcode=10}, +[64566] = {category="lo", shcode=10}, +[64567] = {category="lo", shcode=10}, +[64568] = {category="lo", shcode=10}, +[64569] = {category="lo", shcode=10}, +[64570] = {category="lo", shcode=10}, +[64571] = {category="lo", shcode=10}, +[64572] = {category="lo", shcode=10}, +[64573] = {category="lo", shcode=10}, +[64574] = {category="lo", shcode=10}, +[64575] = {category="lo", shcode=10}, +[64576] = {category="lo", shcode=10}, +[64577] = {category="lo", shcode=10}, +[64578] = {category="lo", shcode=10}, +[64579] = {category="lo", shcode=10}, +[64580] = {category="lo", shcode=10}, +[64581] = {category="lo", shcode=10}, +[64582] = {category="lo", shcode=10}, +[64583] = {category="lo", shcode=10}, +[64584] = {category="lo", shcode=10}, +[64585] = {category="lo", shcode=10}, +[64586] = {category="lo", shcode=10}, +[64587] = {category="lo", shcode=10}, +[64588] = {category="lo", shcode=10}, +[64589] = {category="lo", shcode=10}, +[64590] = {category="lo", shcode=10}, +[64591] = {category="lo", shcode=10}, +[64592] = {category="lo", shcode=10}, +[64593] = {category="lo", shcode=10}, +[64594] = {category="lo", shcode=10}, +[64595] = {category="lo", shcode=10}, +[64596] = {category="lo", shcode=10}, +[64597] = {category="lo", shcode=10}, +[64598] = {category="lo", shcode=10}, +[64599] = {category="lo", shcode=10}, +[64600] = {category="lo", shcode=10}, +[64601] = {category="lo", shcode=10}, +[64602] = {category="lo", shcode=10}, +[64603] = {category="lo", shcode=10}, +[64604] = {category="lo", shcode=10}, +[64605] = {category="lo", shcode=10}, +[64606] = {category="lo", shcode=10}, +[64607] = {category="lo", shcode=10}, +[64608] = {category="lo", shcode=10}, +[64609] = {category="lo", shcode=10}, +[64610] = {category="lo", shcode=10}, +[64611] = {category="lo", shcode=10}, +[64612] = {category="lo", shcode=15}, +[64613] = {category="lo", shcode=15}, +[64614] = {category="lo", shcode=15}, +[64615] = {category="lo", shcode=15}, +[64616] = {category="lo", shcode=15}, +[64617] = {category="lo", shcode=15}, +[64618] = {category="lo", shcode=15}, +[64619] = {category="lo", shcode=15}, +[64620] = {category="lo", shcode=15}, +[64621] = {category="lo", shcode=15}, +[64622] = {category="lo", shcode=15}, +[64623] = {category="lo", shcode=15}, +[64624] = {category="lo", shcode=15}, +[64625] = {category="lo", shcode=15}, +[64626] = {category="lo", shcode=15}, +[64627] = {category="lo", shcode=15}, +[64628] = {category="lo", shcode=15}, +[64629] = {category="lo", shcode=15}, +[64630] = {category="lo", shcode=15}, +[64631] = {category="lo", shcode=15}, +[64632] = {category="lo", shcode=15}, +[64633] = {category="lo", shcode=15}, +[64634] = {category="lo", shcode=15}, +[64635] = {category="lo", shcode=15}, +[64636] = {category="lo", shcode=15}, +[64637] = {category="lo", shcode=15}, +[64638] = {category="lo", shcode=15}, +[64639] = {category="lo", shcode=15}, +[64640] = {category="lo", shcode=15}, +[64641] = {category="lo", shcode=15}, +[64642] = {category="lo", shcode=15}, +[64643] = {category="lo", shcode=15}, +[64644] = {category="lo", shcode=15}, +[64645] = {category="lo", shcode=15}, +[64646] = {category="lo", shcode=15}, +[64647] = {category="lo", shcode=15}, +[64648] = {category="lo", shcode=15}, +[64649] = {category="lo", shcode=15}, +[64650] = {category="lo", shcode=15}, +[64651] = {category="lo", shcode=15}, +[64652] = {category="lo", shcode=15}, +[64653] = {category="lo", shcode=15}, +[64654] = {category="lo", shcode=15}, +[64655] = {category="lo", shcode=15}, +[64656] = {category="lo", shcode=15}, +[64657] = {category="lo", shcode=15}, +[64658] = {category="lo", shcode=15}, +[64659] = {category="lo", shcode=15}, +[64660] = {category="lo", shcode=15}, +[64661] = {category="lo", shcode=15}, +[64662] = {category="lo", shcode=15}, +[64663] = {category="lo", shcode=10}, +[64664] = {category="lo", shcode=10}, +[64665] = {category="lo", shcode=10}, +[64666] = {category="lo", shcode=10}, +[64667] = {category="lo", shcode=10}, +[64668] = {category="lo", shcode=10}, +[64669] = {category="lo", shcode=10}, +[64670] = {category="lo", shcode=10}, +[64671] = {category="lo", shcode=10}, +[64672] = {category="lo", shcode=10}, +[64673] = {category="lo", shcode=10}, +[64674] = {category="lo", shcode=10}, +[64675] = {category="lo", shcode=10}, +[64676] = {category="lo", shcode=10}, +[64677] = {category="lo", shcode=10}, +[64678] = {category="lo", shcode=10}, +[64679] = {category="lo", shcode=10}, +[64680] = {category="lo", shcode=10}, +[64681] = {category="lo", shcode=10}, +[64682] = {category="lo", shcode=10}, +[64683] = {category="lo", shcode=10}, +[64684] = {category="lo", shcode=10}, +[64685] = {category="lo", shcode=10}, +[64686] = {category="lo", shcode=10}, +[64687] = {category="lo", shcode=10}, +[64688] = {category="lo", shcode=10}, +[64689] = {category="lo", shcode=10}, +[64690] = {category="lo", shcode=10}, +[64691] = {category="lo", shcode=10}, +[64692] = {category="lo", shcode=10}, +[64693] = {category="lo", shcode=10}, +[64694] = {category="lo", shcode=10}, +[64695] = {category="lo", shcode=10}, +[64696] = {category="lo", shcode=10}, +[64697] = {category="lo", shcode=10}, +[64698] = {category="lo", shcode=10}, +[64699] = {category="lo", shcode=10}, +[64700] = {category="lo", shcode=10}, +[64701] = {category="lo", shcode=10}, +[64702] = {category="lo", shcode=10}, +[64703] = {category="lo", shcode=10}, +[64704] = {category="lo", shcode=10}, +[64705] = {category="lo", shcode=10}, +[64706] = {category="lo", shcode=10}, +[64707] = {category="lo", shcode=10}, +[64708] = {category="lo", shcode=10}, +[64709] = {category="lo", shcode=10}, +[64710] = {category="lo", shcode=10}, +[64711] = {category="lo", shcode=10}, +[64712] = {category="lo", shcode=10}, +[64713] = {category="lo", shcode=10}, +[64714] = {category="lo", shcode=10}, +[64715] = {category="lo", shcode=10}, +[64716] = {category="lo", shcode=10}, +[64717] = {category="lo", shcode=10}, +[64718] = {category="lo", shcode=10}, +[64719] = {category="lo", shcode=10}, +[64720] = {category="lo", shcode=10}, +[64721] = {category="lo", shcode=10}, +[64722] = {category="lo", shcode=10}, +[64723] = {category="lo", shcode=10}, +[64724] = {category="lo", shcode=10}, +[64725] = {category="lo", shcode=10}, +[64726] = {category="lo", shcode=10}, +[64727] = {category="lo", shcode=10}, +[64728] = {category="lo", shcode=10}, +[64729] = {category="lo", shcode=10}, +[64730] = {category="lo", shcode=10}, +[64731] = {category="lo", shcode=10}, +[64732] = {category="lo", shcode=10}, +[64733] = {category="lo", shcode=10}, +[64734] = {category="lo", shcode=10}, +[64735] = {category="lo", shcode=237}, +[64736] = {category="lo", shcode=237}, +[64737] = {category="lo", shcode=237}, +[64738] = {category="lo", shcode=237}, +[64739] = {category="lo", shcode=237}, +[64740] = {category="lo", shcode=237}, +[64741] = {category="lo", shcode=237}, +[64742] = {category="lo", shcode=237}, +[64743] = {category="lo", shcode=237}, +[64744] = {category="lo", shcode=237}, +[64745] = {category="lo", shcode=237}, +[64746] = {category="lo", shcode=237}, +[64747] = {category="lo", shcode=237}, +[64748] = {category="lo", shcode=237}, +[64749] = {category="lo", shcode=237}, +[64750] = {category="lo", shcode=237}, +[64751] = {category="lo", shcode=237}, +[64752] = {category="lo", shcode=237}, +[64753] = {category="lo", shcode=237}, +[64754] = {category="lo", shcode=237}, +[64755] = {category="lo", shcode=237}, +[64756] = {category="lo", shcode=237}, +[64757] = {category="lo", shcode=10}, +[64758] = {category="lo", shcode=10}, +[64759] = {category="lo", shcode=10}, +[64760] = {category="lo", shcode=10}, +[64761] = {category="lo", shcode=10}, +[64762] = {category="lo", shcode=10}, +[64763] = {category="lo", shcode=10}, +[64764] = {category="lo", shcode=10}, +[64765] = {category="lo", shcode=10}, +[64766] = {category="lo", shcode=10}, +[64767] = {category="lo", shcode=10}, +[64768] = {category="lo", shcode=10}, +[64769] = {category="lo", shcode=10}, +[64770] = {category="lo", shcode=10}, +[64771] = {category="lo", shcode=10}, +[64772] = {category="lo", shcode=10}, +[64773] = {category="lo", shcode=10}, +[64774] = {category="lo", shcode=10}, +[64775] = {category="lo", shcode=10}, +[64776] = {category="lo", shcode=10}, +[64777] = {category="lo", shcode=10}, +[64778] = {category="lo", shcode=10}, +[64779] = {category="lo", shcode=10}, +[64780] = {category="lo", shcode=10}, +[64781] = {category="lo", shcode=10}, +[64782] = {category="lo", shcode=10}, +[64783] = {category="lo", shcode=10}, +[64784] = {category="lo", shcode=10}, +[64785] = {category="lo", shcode=15}, +[64786] = {category="lo", shcode=15}, +[64787] = {category="lo", shcode=15}, +[64788] = {category="lo", shcode=15}, +[64789] = {category="lo", shcode=15}, +[64790] = {category="lo", shcode=15}, +[64791] = {category="lo", shcode=15}, +[64792] = {category="lo", shcode=15}, +[64793] = {category="lo", shcode=15}, +[64794] = {category="lo", shcode=15}, +[64795] = {category="lo", shcode=15}, +[64796] = {category="lo", shcode=15}, +[64797] = {category="lo", shcode=15}, +[64798] = {category="lo", shcode=15}, +[64799] = {category="lo", shcode=15}, +[64800] = {category="lo", shcode=15}, +[64801] = {category="lo", shcode=15}, +[64802] = {category="lo", shcode=15}, +[64803] = {category="lo", shcode=15}, +[64804] = {category="lo", shcode=15}, +[64805] = {category="lo", shcode=15}, +[64806] = {category="lo", shcode=15}, +[64807] = {category="lo", shcode=15}, +[64808] = {category="lo", shcode=15}, +[64809] = {category="lo", shcode=15}, +[64810] = {category="lo", shcode=15}, +[64811] = {category="lo", shcode=15}, +[64812] = {category="lo", shcode=15}, +[64813] = {category="lo", shcode=10}, +[64814] = {category="lo", shcode=10}, +[64815] = {category="lo", shcode=10}, +[64816] = {category="lo", shcode=10}, +[64817] = {category="lo", shcode=10}, +[64818] = {category="lo", shcode=10}, +[64819] = {category="lo", shcode=10}, +[64820] = {category="lo", shcode=237}, +[64821] = {category="lo", shcode=237}, +[64822] = {category="lo", shcode=237}, +[64823] = {category="lo", shcode=237}, +[64824] = {category="lo", shcode=237}, +[64825] = {category="lo", shcode=237}, +[64826] = {category="lo", shcode=237}, +[64827] = {category="lo", shcode=237}, +[64828] = {category="lo", shcode=15}, +[64829] = {category="lo", shcode=10}, +[64848] = {category="lo", shcode=10}, +[64849] = {category="lo", shcode=15}, +[64850] = {category="lo", shcode=10}, +[64851] = {category="lo", shcode=10}, +[64852] = {category="lo", shcode=10}, +[64853] = {category="lo", shcode=10}, +[64854] = {category="lo", shcode=10}, +[64855] = {category="lo", shcode=10}, +[64856] = {category="lo", shcode=15}, +[64857] = {category="lo", shcode=10}, +[64858] = {category="lo", shcode=15}, +[64859] = {category="lo", shcode=15}, +[64860] = {category="lo", shcode=10}, +[64861] = {category="lo", shcode=10}, +[64862] = {category="lo", shcode=15}, +[64863] = {category="lo", shcode=15}, +[64864] = {category="lo", shcode=10}, +[64865] = {category="lo", shcode=10}, +[64866] = {category="lo", shcode=15}, +[64867] = {category="lo", shcode=10}, +[64868] = {category="lo", shcode=15}, +[64869] = {category="lo", shcode=10}, +[64870] = {category="lo", shcode=15}, +[64871] = {category="lo", shcode=15}, +[64872] = {category="lo", shcode=10}, +[64873] = {category="lo", shcode=15}, +[64874] = {category="lo", shcode=15}, +[64875] = {category="lo", shcode=10}, +[64876] = {category="lo", shcode=15}, +[64877] = {category="lo", shcode=10}, +[64878] = {category="lo", shcode=15}, +[64879] = {category="lo", shcode=15}, +[64880] = {category="lo", shcode=10}, +[64881] = {category="lo", shcode=15}, +[64882] = {category="lo", shcode=10}, +[64883] = {category="lo", shcode=10}, +[64884] = {category="lo", shcode=15}, +[64885] = {category="lo", shcode=15}, +[64886] = {category="lo", shcode=15}, +[64887] = {category="lo", shcode=10}, +[64888] = {category="lo", shcode=15}, +[64889] = {category="lo", shcode=15}, +[64890] = {category="lo", shcode=15}, +[64891] = {category="lo", shcode=15}, +[64892] = {category="lo", shcode=15}, +[64893] = {category="lo", shcode=10}, +[64894] = {category="lo", shcode=15}, +[64895] = {category="lo", shcode=15}, +[64896] = {category="lo", shcode=15}, +[64897] = {category="lo", shcode=15}, +[64898] = {category="lo", shcode=15}, +[64899] = {category="lo", shcode=10}, +[64900] = {category="lo", shcode=15}, +[64901] = {category="lo", shcode=15}, +[64902] = {category="lo", shcode=10}, +[64903] = {category="lo", shcode=15}, +[64904] = {category="lo", shcode=10}, +[64905] = {category="lo", shcode=10}, +[64906] = {category="lo", shcode=10}, +[64907] = {category="lo", shcode=15}, +[64908] = {category="lo", shcode=10}, +[64909] = {category="lo", shcode=10}, +[64910] = {category="lo", shcode=10}, +[64911] = {category="lo", shcode=10}, +[64914] = {category="lo", shcode=10}, +[64915] = {category="lo", shcode=10}, +[64916] = {category="lo", shcode=10}, +[64917] = {category="lo", shcode=10}, +[64918] = {category="lo", shcode=15}, +[64919] = {category="lo", shcode=15}, +[64920] = {category="lo", shcode=10}, +[64921] = {category="lo", shcode=15}, +[64922] = {category="lo", shcode=15}, +[64923] = {category="lo", shcode=15}, +[64924] = {category="lo", shcode=15}, +[64925] = {category="lo", shcode=10}, +[64926] = {category="lo", shcode=15}, +[64927] = {category="lo", shcode=15}, +[64928] = {category="lo", shcode=15}, +[64929] = {category="lo", shcode=15}, +[64930] = {category="lo", shcode=15}, +[64931] = {category="lo", shcode=15}, +[64932] = {category="lo", shcode=15}, +[64933] = {category="lo", shcode=15}, +[64934] = {category="lo", shcode=15}, +[64935] = {category="lo", shcode=15}, +[64936] = {category="lo", shcode=15}, +[64937] = {category="lo", shcode=15}, +[64938] = {category="lo", shcode=15}, +[64939] = {category="lo", shcode=15}, +[64940] = {category="lo", shcode=15}, +[64941] = {category="lo", shcode=15}, +[64942] = {category="lo", shcode=15}, +[64943] = {category="lo", shcode=15}, +[64944] = {category="lo", shcode=15}, +[64945] = {category="lo", shcode=15}, +[64946] = {category="lo", shcode=15}, +[64947] = {category="lo", shcode=15}, +[64948] = {category="lo", shcode=10}, +[64949] = {category="lo", shcode=10}, +[64950] = {category="lo", shcode=15}, +[64951] = {category="lo", shcode=15}, +[64952] = {category="lo", shcode=10}, +[64953] = {category="lo", shcode=15}, +[64954] = {category="lo", shcode=10}, +[64955] = {category="lo", shcode=15}, +[64956] = {category="lo", shcode=15}, +[64957] = {category="lo", shcode=15}, +[64958] = {category="lo", shcode=15}, +[64959] = {category="lo", shcode=15}, +[64960] = {category="lo", shcode=15}, +[64961] = {category="lo", shcode=15}, +[64962] = {category="lo", shcode=15}, +[64963] = {category="lo", shcode=10}, +[64964] = {category="lo", shcode=10}, +[64965] = {category="lo", shcode=10}, +[64966] = {category="lo", shcode=15}, +[64967] = {category="lo", shcode=15}, +[65008] = {category="lo", shcode=10}, +[65009] = {category="lo", shcode=10}, +[65010] = {category="lo", shcode=10}, +[65011] = {category="lo", shcode=10}, +[65012] = {category="lo", shcode=10}, +[65013] = {category="lo", shcode=10}, +[65014] = {category="lo", shcode=10}, +[65015] = {category="lo", shcode=10}, +[65016] = {category="lo", shcode=10}, +[65017] = {category="lo", shcode=10}, +[65018] = {category="lo", shcode=10}, +[65019] = {category="lo", shcode=10}, +[65136] = {category="lo", shcode=10}, +[65137] = {category="lo", shcode=237}, +[65138] = {category="lo", shcode=10}, +[65139] = {category="lo"}, +[65140] = {category="lo", shcode=10}, +[65142] = {category="lo", shcode=10}, +[65143] = {category="lo", shcode=237}, +[65144] = {category="lo", shcode=10}, +[65145] = {category="lo", shcode=237}, +[65146] = {category="lo", shcode=10}, +[65147] = {category="lo", shcode=237}, +[65148] = {category="lo", shcode=10}, +[65149] = {category="lo", shcode=237}, +[65150] = {category="lo", shcode=10}, +[65151] = {category="lo", shcode=237}, +[65152] = {category="lo", shcode=10}, +[65153] = {category="lo", shcode=10}, +[65154] = {category="lo", shcode=15}, +[65155] = {category="lo", shcode=10}, +[65156] = {category="lo", shcode=15}, +[65157] = {category="lo", shcode=10}, +[65158] = {category="lo", shcode=15}, +[65159] = {category="lo", shcode=10}, +[65160] = {category="lo", shcode=15}, +[65161] = {category="lo", shcode=10}, +[65162] = {category="lo", shcode=15}, +[65163] = {category="lo", shcode=10}, +[65164] = {category="lo", shcode=237}, +[65165] = {category="lo", shcode=10}, +[65166] = {category="lo", shcode=15}, +[65167] = {category="lo", shcode=10}, +[65168] = {category="lo", shcode=15}, +[65169] = {category="lo", shcode=10}, +[65170] = {category="lo", shcode=237}, +[65171] = {category="lo", shcode=10}, +[65172] = {category="lo", shcode=15}, +[65173] = {category="lo", shcode=10}, +[65174] = {category="lo", shcode=15}, +[65175] = {category="lo", shcode=10}, +[65176] = {category="lo", shcode=237}, +[65177] = {category="lo", shcode=10}, +[65178] = {category="lo", shcode=15}, +[65179] = {category="lo", shcode=10}, +[65180] = {category="lo", shcode=237}, +[65181] = {category="lo", shcode=10}, +[65182] = {category="lo", shcode=15}, +[65183] = {category="lo", shcode=10}, +[65184] = {category="lo", shcode=237}, +[65185] = {category="lo", shcode=10}, +[65186] = {category="lo", shcode=15}, +[65187] = {category="lo", shcode=10}, +[65188] = {category="lo", shcode=237}, +[65189] = {category="lo", shcode=10}, +[65190] = {category="lo", shcode=15}, +[65191] = {category="lo", shcode=10}, +[65192] = {category="lo", shcode=237}, +[65193] = {category="lo", shcode=10}, +[65194] = {category="lo", shcode=15}, +[65195] = {category="lo", shcode=10}, +[65196] = {category="lo", shcode=15}, +[65197] = {category="lo", shcode=10}, +[65198] = {category="lo", shcode=15}, +[65199] = {category="lo", shcode=10}, +[65200] = {category="lo", shcode=15}, +[65201] = {category="lo", shcode=10}, +[65202] = {category="lo", shcode=15}, +[65203] = {category="lo", shcode=10}, +[65204] = {category="lo", shcode=237}, +[65205] = {category="lo", shcode=10}, +[65206] = {category="lo", shcode=15}, +[65207] = {category="lo", shcode=10}, +[65208] = {category="lo", shcode=237}, +[65209] = {category="lo", shcode=10}, +[65210] = {category="lo", shcode=15}, +[65211] = {category="lo", shcode=10}, +[65212] = {category="lo", shcode=237}, +[65213] = {category="lo", shcode=10}, +[65214] = {category="lo", shcode=15}, +[65215] = {category="lo", shcode=10}, +[65216] = {category="lo", shcode=237}, +[65217] = {category="lo", shcode=10}, +[65218] = {category="lo", shcode=15}, +[65219] = {category="lo", shcode=10}, +[65220] = {category="lo", shcode=237}, +[65221] = {category="lo", shcode=10}, +[65222] = {category="lo", shcode=15}, +[65223] = {category="lo", shcode=10}, +[65224] = {category="lo", shcode=237}, +[65225] = {category="lo", shcode=10}, +[65226] = {category="lo", shcode=15}, +[65227] = {category="lo", shcode=10}, +[65228] = {category="lo", shcode=237}, +[65229] = {category="lo", shcode=10}, +[65230] = {category="lo", shcode=15}, +[65231] = {category="lo", shcode=10}, +[65232] = {category="lo", shcode=237}, +[65233] = {category="lo", shcode=10}, +[65234] = {category="lo", shcode=15}, +[65235] = {category="lo", shcode=10}, +[65236] = {category="lo", shcode=237}, +[65237] = {category="lo", shcode=10}, +[65238] = {category="lo", shcode=15}, +[65239] = {category="lo", shcode=10}, +[65240] = {category="lo", shcode=237}, +[65241] = {category="lo", shcode=10}, +[65242] = {category="lo", shcode=15}, +[65243] = {category="lo", shcode=10}, +[65244] = {category="lo", shcode=237}, +[65245] = {category="lo", shcode=10}, +[65246] = {category="lo", shcode=15}, +[65247] = {category="lo", shcode=10}, +[65248] = {category="lo", shcode=237}, +[65249] = {category="lo", shcode=10}, +[65250] = {category="lo", shcode=15}, +[65251] = {category="lo", shcode=10}, +[65252] = {category="lo", shcode=237}, +[65253] = {category="lo", shcode=10}, +[65254] = {category="lo", shcode=15}, +[65255] = {category="lo", shcode=10}, +[65256] = {category="lo", shcode=237}, +[65257] = {category="lo", shcode=10}, +[65258] = {category="lo", shcode=15}, +[65259] = {category="lo", shcode=10}, +[65260] = {category="lo", shcode=237}, +[65261] = {category="lo", shcode=10}, +[65262] = {category="lo", shcode=15}, +[65263] = {category="lo", shcode=10}, +[65264] = {category="lo", shcode=15}, +[65265] = {category="lo", shcode=10}, +[65266] = {category="lo", shcode=15}, +[65267] = {category="lo", shcode=10}, +[65268] = {category="lo", shcode=237}, +[65269] = {category="lo", shcode=10}, +[65270] = {category="lo", shcode=15}, +[65271] = {category="lo", shcode=10}, +[65272] = {category="lo", shcode=15}, +[65273] = {category="lo", shcode=10}, +[65274] = {category="lo", shcode=15}, +[65275] = {category="lo", shcode=10}, +[65276] = {category="lo", shcode=15}, +[65313] = {category="lu", lccode=65345, shcode=222}, +[65314] = {category="lu", lccode=65346, shcode=222}, +[65315] = {category="lu", lccode=65347, shcode=222}, +[65316] = {category="lu", lccode=65348, shcode=222}, +[65317] = {category="lu", lccode=65349, shcode=222}, +[65318] = {category="lu", lccode=65350, shcode=222}, +[65319] = {category="lu", lccode=65351, shcode=222}, +[65320] = {category="lu", lccode=65352, shcode=222}, +[65321] = {category="lu", lccode=65353, shcode=222}, +[65322] = {category="lu", lccode=65354, shcode=222}, +[65323] = {category="lu", lccode=65355, shcode=222}, +[65324] = {category="lu", lccode=65356, shcode=222}, +[65325] = {category="lu", lccode=65357, shcode=222}, +[65326] = {category="lu", lccode=65358, shcode=222}, +[65327] = {category="lu", lccode=65359, shcode=222}, +[65328] = {category="lu", lccode=65360, shcode=222}, +[65329] = {category="lu", lccode=65361, shcode=222}, +[65330] = {category="lu", lccode=65362, shcode=222}, +[65331] = {category="lu", lccode=65363, shcode=222}, +[65332] = {category="lu", lccode=65364, shcode=222}, +[65333] = {category="lu", lccode=65365, shcode=222}, +[65334] = {category="lu", lccode=65366, shcode=222}, +[65335] = {category="lu", lccode=65367, shcode=222}, +[65336] = {category="lu", lccode=65368, shcode=222}, +[65337] = {category="lu", lccode=65369, shcode=222}, +[65338] = {category="lu", lccode=65370, shcode=222}, +[65345] = {category="ll", shcode=222}, +[65346] = {category="ll", shcode=222}, +[65347] = {category="ll", shcode=222}, +[65348] = {category="ll", shcode=222}, +[65349] = {category="ll", shcode=222}, +[65350] = {category="ll", shcode=222}, +[65351] = {category="ll", shcode=222}, +[65352] = {category="ll", shcode=222}, +[65353] = {category="ll", shcode=222}, +[65354] = {category="ll", shcode=222}, +[65355] = {category="ll", shcode=222}, +[65356] = {category="ll", shcode=222}, +[65357] = {category="ll", shcode=222}, +[65358] = {category="ll", shcode=222}, +[65359] = {category="ll", shcode=222}, +[65360] = {category="ll", shcode=222}, +[65361] = {category="ll", shcode=222}, +[65362] = {category="ll", shcode=222}, +[65363] = {category="ll", shcode=222}, +[65364] = {category="ll", shcode=222}, +[65365] = {category="ll", shcode=222}, +[65366] = {category="ll", shcode=222}, +[65367] = {category="ll", shcode=222}, +[65368] = {category="ll", shcode=222}, +[65369] = {category="ll", shcode=222}, +[65370] = {category="ll", shcode=222}, +[65382] = {category="lo", shcode=10}, +[65383] = {category="lo", shcode=10}, +[65384] = {category="lo", shcode=10}, +[65385] = {category="lo", shcode=10}, +[65386] = {category="lo", shcode=10}, +[65387] = {category="lo", shcode=10}, +[65388] = {category="lo", shcode=10}, +[65389] = {category="lo", shcode=10}, +[65390] = {category="lo", shcode=10}, +[65391] = {category="lo", shcode=10}, +[65392] = {category="lm", shcode=10}, +[65393] = {category="lo", shcode=10}, +[65394] = {category="lo", shcode=10}, +[65395] = {category="lo", shcode=10}, +[65396] = {category="lo", shcode=10}, +[65397] = {category="lo", shcode=10}, +[65398] = {category="lo", shcode=10}, +[65399] = {category="lo", shcode=10}, +[65400] = {category="lo", shcode=10}, +[65401] = {category="lo", shcode=10}, +[65402] = {category="lo", shcode=10}, +[65403] = {category="lo", shcode=10}, +[65404] = {category="lo", shcode=10}, +[65405] = {category="lo", shcode=10}, +[65406] = {category="lo", shcode=10}, +[65407] = {category="lo", shcode=10}, +[65408] = {category="lo", shcode=10}, +[65409] = {category="lo", shcode=10}, +[65410] = {category="lo", shcode=10}, +[65411] = {category="lo", shcode=10}, +[65412] = {category="lo", shcode=10}, +[65413] = {category="lo", shcode=10}, +[65414] = {category="lo", shcode=10}, +[65415] = {category="lo", shcode=10}, +[65416] = {category="lo", shcode=10}, +[65417] = {category="lo", shcode=10}, +[65418] = {category="lo", shcode=10}, +[65419] = {category="lo", shcode=10}, +[65420] = {category="lo", shcode=10}, +[65421] = {category="lo", shcode=10}, +[65422] = {category="lo", shcode=10}, +[65423] = {category="lo", shcode=10}, +[65424] = {category="lo", shcode=10}, +[65425] = {category="lo", shcode=10}, +[65426] = {category="lo", shcode=10}, +[65427] = {category="lo", shcode=10}, +[65428] = {category="lo", shcode=10}, +[65429] = {category="lo", shcode=10}, +[65430] = {category="lo", shcode=10}, +[65431] = {category="lo", shcode=10}, +[65432] = {category="lo", shcode=10}, +[65433] = {category="lo", shcode=10}, +[65434] = {category="lo", shcode=10}, +[65435] = {category="lo", shcode=10}, +[65436] = {category="lo", shcode=10}, +[65437] = {category="lo", shcode=10}, +[65438] = {category="lm", shcode=10}, +[65439] = {category="lm", shcode=10}, +[65440] = {category="lo", shcode=10}, +[65441] = {category="lo", shcode=10}, +[65442] = {category="lo", shcode=10}, +[65443] = {category="lo", shcode=10}, +[65444] = {category="lo", shcode=10}, +[65445] = {category="lo", shcode=10}, +[65446] = {category="lo", shcode=10}, +[65447] = {category="lo", shcode=10}, +[65448] = {category="lo", shcode=10}, +[65449] = {category="lo", shcode=10}, +[65450] = {category="lo", shcode=10}, +[65451] = {category="lo", shcode=10}, +[65452] = {category="lo", shcode=10}, +[65453] = {category="lo", shcode=10}, +[65454] = {category="lo", shcode=10}, +[65455] = {category="lo", shcode=10}, +[65456] = {category="lo", shcode=10}, +[65457] = {category="lo", shcode=10}, +[65458] = {category="lo", shcode=10}, +[65459] = {category="lo", shcode=10}, +[65460] = {category="lo", shcode=10}, +[65461] = {category="lo", shcode=10}, +[65462] = {category="lo", shcode=10}, +[65463] = {category="lo", shcode=10}, +[65464] = {category="lo", shcode=10}, +[65465] = {category="lo", shcode=10}, +[65466] = {category="lo", shcode=10}, +[65467] = {category="lo", shcode=10}, +[65468] = {category="lo", shcode=10}, +[65469] = {category="lo", shcode=10}, +[65470] = {category="lo", shcode=10}, +[65474] = {category="lo", shcode=10}, +[65475] = {category="lo", shcode=10}, +[65476] = {category="lo", shcode=10}, +[65477] = {category="lo", shcode=10}, +[65478] = {category="lo", shcode=10}, +[65479] = {category="lo", shcode=10}, +[65482] = {category="lo", shcode=10}, +[65483] = {category="lo", shcode=10}, +[65484] = {category="lo", shcode=10}, +[65485] = {category="lo", shcode=10}, +[65486] = {category="lo", shcode=10}, +[65487] = {category="lo", shcode=10}, +[65490] = {category="lo", shcode=10}, +[65491] = {category="lo", shcode=10}, +[65492] = {category="lo", shcode=10}, +[65493] = {category="lo", shcode=10}, +[65494] = {category="lo", shcode=10}, +[65495] = {category="lo", shcode=10}, +[65498] = {category="lo", shcode=10}, +[65499] = {category="lo", shcode=10}, +[65500] = {category="lo", shcode=10}, +[65536] = {category="lo"}, +[65537] = {category="lo"}, +[65538] = {category="lo"}, +[65539] = {category="lo"}, +[65540] = {category="lo"}, +[65541] = {category="lo"}, +[65542] = {category="lo"}, +[65543] = {category="lo"}, +[65544] = {category="lo"}, +[65545] = {category="lo"}, +[65546] = {category="lo"}, +[65547] = {category="lo"}, +[65549] = {category="lo"}, +[65550] = {category="lo"}, +[65551] = {category="lo"}, +[65552] = {category="lo"}, +[65553] = {category="lo"}, +[65554] = {category="lo"}, +[65555] = {category="lo"}, +[65556] = {category="lo"}, +[65557] = {category="lo"}, +[65558] = {category="lo"}, +[65559] = {category="lo"}, +[65560] = {category="lo"}, +[65561] = {category="lo"}, +[65562] = {category="lo"}, +[65563] = {category="lo"}, +[65564] = {category="lo"}, +[65565] = {category="lo"}, +[65566] = {category="lo"}, +[65567] = {category="lo"}, +[65568] = {category="lo"}, +[65569] = {category="lo"}, +[65570] = {category="lo"}, +[65571] = {category="lo"}, +[65572] = {category="lo"}, +[65573] = {category="lo"}, +[65574] = {category="lo"}, +[65576] = {category="lo"}, +[65577] = {category="lo"}, +[65578] = {category="lo"}, +[65579] = {category="lo"}, +[65580] = {category="lo"}, +[65581] = {category="lo"}, +[65582] = {category="lo"}, +[65583] = {category="lo"}, +[65584] = {category="lo"}, +[65585] = {category="lo"}, +[65586] = {category="lo"}, +[65587] = {category="lo"}, +[65588] = {category="lo"}, +[65589] = {category="lo"}, +[65590] = {category="lo"}, +[65591] = {category="lo"}, +[65592] = {category="lo"}, +[65593] = {category="lo"}, +[65594] = {category="lo"}, +[65596] = {category="lo"}, +[65597] = {category="lo"}, +[65599] = {category="lo"}, +[65600] = {category="lo"}, +[65601] = {category="lo"}, +[65602] = {category="lo"}, +[65603] = {category="lo"}, +[65604] = {category="lo"}, +[65605] = {category="lo"}, +[65606] = {category="lo"}, +[65607] = {category="lo"}, +[65608] = {category="lo"}, +[65609] = {category="lo"}, +[65610] = {category="lo"}, +[65611] = {category="lo"}, +[65612] = {category="lo"}, +[65613] = {category="lo"}, +[65616] = {category="lo"}, +[65617] = {category="lo"}, +[65618] = {category="lo"}, +[65619] = {category="lo"}, +[65620] = {category="lo"}, +[65621] = {category="lo"}, +[65622] = {category="lo"}, +[65623] = {category="lo"}, +[65624] = {category="lo"}, +[65625] = {category="lo"}, +[65626] = {category="lo"}, +[65627] = {category="lo"}, +[65628] = {category="lo"}, +[65629] = {category="lo"}, +[65664] = {category="lo"}, +[65665] = {category="lo"}, +[65666] = {category="lo"}, +[65667] = {category="lo"}, +[65668] = {category="lo"}, +[65669] = {category="lo"}, +[65670] = {category="lo"}, +[65671] = {category="lo"}, +[65672] = {category="lo"}, +[65673] = {category="lo"}, +[65674] = {category="lo"}, +[65675] = {category="lo"}, +[65676] = {category="lo"}, +[65677] = {category="lo"}, +[65678] = {category="lo"}, +[65679] = {category="lo"}, +[65680] = {category="lo"}, +[65681] = {category="lo"}, +[65682] = {category="lo"}, +[65683] = {category="lo"}, +[65684] = {category="lo"}, +[65685] = {category="lo"}, +[65686] = {category="lo"}, +[65687] = {category="lo"}, +[65688] = {category="lo"}, +[65689] = {category="lo"}, +[65690] = {category="lo"}, +[65691] = {category="lo"}, +[65692] = {category="lo"}, +[65693] = {category="lo"}, +[65694] = {category="lo"}, +[65695] = {category="lo"}, +[65696] = {category="lo"}, +[65697] = {category="lo"}, +[65698] = {category="lo"}, +[65699] = {category="lo"}, +[65700] = {category="lo"}, +[65701] = {category="lo"}, +[65702] = {category="lo"}, +[65703] = {category="lo"}, +[65704] = {category="lo"}, +[65705] = {category="lo"}, +[65706] = {category="lo"}, +[65707] = {category="lo"}, +[65708] = {category="lo"}, +[65709] = {category="lo"}, +[65710] = {category="lo"}, +[65711] = {category="lo"}, +[65712] = {category="lo"}, +[65713] = {category="lo"}, +[65714] = {category="lo"}, +[65715] = {category="lo"}, +[65716] = {category="lo"}, +[65717] = {category="lo"}, +[65718] = {category="lo"}, +[65719] = {category="lo"}, +[65720] = {category="lo"}, +[65721] = {category="lo"}, +[65722] = {category="lo"}, +[65723] = {category="lo"}, +[65724] = {category="lo"}, +[65725] = {category="lo"}, +[65726] = {category="lo"}, +[65727] = {category="lo"}, +[65728] = {category="lo"}, +[65729] = {category="lo"}, +[65730] = {category="lo"}, +[65731] = {category="lo"}, +[65732] = {category="lo"}, +[65733] = {category="lo"}, +[65734] = {category="lo"}, +[65735] = {category="lo"}, +[65736] = {category="lo"}, +[65737] = {category="lo"}, +[65738] = {category="lo"}, +[65739] = {category="lo"}, +[65740] = {category="lo"}, +[65741] = {category="lo"}, +[65742] = {category="lo"}, +[65743] = {category="lo"}, +[65744] = {category="lo"}, +[65745] = {category="lo"}, +[65746] = {category="lo"}, +[65747] = {category="lo"}, +[65748] = {category="lo"}, +[65749] = {category="lo"}, +[65750] = {category="lo"}, +[65751] = {category="lo"}, +[65752] = {category="lo"}, +[65753] = {category="lo"}, +[65754] = {category="lo"}, +[65755] = {category="lo"}, +[65756] = {category="lo"}, +[65757] = {category="lo"}, +[65758] = {category="lo"}, +[65759] = {category="lo"}, +[65760] = {category="lo"}, +[65761] = {category="lo"}, +[65762] = {category="lo"}, +[65763] = {category="lo"}, +[65764] = {category="lo"}, +[65765] = {category="lo"}, +[65766] = {category="lo"}, +[65767] = {category="lo"}, +[65768] = {category="lo"}, +[65769] = {category="lo"}, +[65770] = {category="lo"}, +[65771] = {category="lo"}, +[65772] = {category="lo"}, +[65773] = {category="lo"}, +[65774] = {category="lo"}, +[65775] = {category="lo"}, +[65776] = {category="lo"}, +[65777] = {category="lo"}, +[65778] = {category="lo"}, +[65779] = {category="lo"}, +[65780] = {category="lo"}, +[65781] = {category="lo"}, +[65782] = {category="lo"}, +[65783] = {category="lo"}, +[65784] = {category="lo"}, +[65785] = {category="lo"}, +[65786] = {category="lo"}, +[66176] = {category="lo"}, +[66177] = {category="lo"}, +[66178] = {category="lo"}, +[66179] = {category="lo"}, +[66180] = {category="lo"}, +[66181] = {category="lo"}, +[66182] = {category="lo"}, +[66183] = {category="lo"}, +[66184] = {category="lo"}, +[66185] = {category="lo"}, +[66186] = {category="lo"}, +[66187] = {category="lo"}, +[66188] = {category="lo"}, +[66189] = {category="lo"}, +[66190] = {category="lo"}, +[66191] = {category="lo"}, +[66192] = {category="lo"}, +[66193] = {category="lo"}, +[66194] = {category="lo"}, +[66195] = {category="lo"}, +[66196] = {category="lo"}, +[66197] = {category="lo"}, +[66198] = {category="lo"}, +[66199] = {category="lo"}, +[66200] = {category="lo"}, +[66201] = {category="lo"}, +[66202] = {category="lo"}, +[66203] = {category="lo"}, +[66204] = {category="lo"}, +[66208] = {category="lo"}, +[66209] = {category="lo"}, +[66210] = {category="lo"}, +[66211] = {category="lo"}, +[66212] = {category="lo"}, +[66213] = {category="lo"}, +[66214] = {category="lo"}, +[66215] = {category="lo"}, +[66216] = {category="lo"}, +[66217] = {category="lo"}, +[66218] = {category="lo"}, +[66219] = {category="lo"}, +[66220] = {category="lo"}, +[66221] = {category="lo"}, +[66222] = {category="lo"}, +[66223] = {category="lo"}, +[66224] = {category="lo"}, +[66225] = {category="lo"}, +[66226] = {category="lo"}, +[66227] = {category="lo"}, +[66228] = {category="lo"}, +[66229] = {category="lo"}, +[66230] = {category="lo"}, +[66231] = {category="lo"}, +[66232] = {category="lo"}, +[66233] = {category="lo"}, +[66234] = {category="lo"}, +[66235] = {category="lo"}, +[66236] = {category="lo"}, +[66237] = {category="lo"}, +[66238] = {category="lo"}, +[66239] = {category="lo"}, +[66240] = {category="lo"}, +[66241] = {category="lo"}, +[66242] = {category="lo"}, +[66243] = {category="lo"}, +[66244] = {category="lo"}, +[66245] = {category="lo"}, +[66246] = {category="lo"}, +[66247] = {category="lo"}, +[66248] = {category="lo"}, +[66249] = {category="lo"}, +[66250] = {category="lo"}, +[66251] = {category="lo"}, +[66252] = {category="lo"}, +[66253] = {category="lo"}, +[66254] = {category="lo"}, +[66255] = {category="lo"}, +[66256] = {category="lo"}, +[66304] = {category="lo"}, +[66305] = {category="lo"}, +[66306] = {category="lo"}, +[66307] = {category="lo"}, +[66308] = {category="lo"}, +[66309] = {category="lo"}, +[66310] = {category="lo"}, +[66311] = {category="lo"}, +[66312] = {category="lo"}, +[66313] = {category="lo"}, +[66314] = {category="lo"}, +[66315] = {category="lo"}, +[66316] = {category="lo"}, +[66317] = {category="lo"}, +[66318] = {category="lo"}, +[66319] = {category="lo"}, +[66320] = {category="lo"}, +[66321] = {category="lo"}, +[66322] = {category="lo"}, +[66323] = {category="lo"}, +[66324] = {category="lo"}, +[66325] = {category="lo"}, +[66326] = {category="lo"}, +[66327] = {category="lo"}, +[66328] = {category="lo"}, +[66329] = {category="lo"}, +[66330] = {category="lo"}, +[66331] = {category="lo"}, +[66332] = {category="lo"}, +[66333] = {category="lo"}, +[66334] = {category="lo"}, +[66335] = {category="lo"}, +[66349] = {category="lo"}, +[66350] = {category="lo"}, +[66351] = {category="lo"}, +[66352] = {category="lo"}, +[66353] = {category="lo"}, +[66354] = {category="lo"}, +[66355] = {category="lo"}, +[66356] = {category="lo"}, +[66357] = {category="lo"}, +[66358] = {category="lo"}, +[66359] = {category="lo"}, +[66360] = {category="lo"}, +[66361] = {category="lo"}, +[66362] = {category="lo"}, +[66363] = {category="lo"}, +[66364] = {category="lo"}, +[66365] = {category="lo"}, +[66366] = {category="lo"}, +[66367] = {category="lo"}, +[66368] = {category="lo"}, +[66370] = {category="lo"}, +[66371] = {category="lo"}, +[66372] = {category="lo"}, +[66373] = {category="lo"}, +[66374] = {category="lo"}, +[66375] = {category="lo"}, +[66376] = {category="lo"}, +[66377] = {category="lo"}, +[66384] = {category="lo"}, +[66385] = {category="lo"}, +[66386] = {category="lo"}, +[66387] = {category="lo"}, +[66388] = {category="lo"}, +[66389] = {category="lo"}, +[66390] = {category="lo"}, +[66391] = {category="lo"}, +[66392] = {category="lo"}, +[66393] = {category="lo"}, +[66394] = {category="lo"}, +[66395] = {category="lo"}, +[66396] = {category="lo"}, +[66397] = {category="lo"}, +[66398] = {category="lo"}, +[66399] = {category="lo"}, +[66400] = {category="lo"}, +[66401] = {category="lo"}, +[66402] = {category="lo"}, +[66403] = {category="lo"}, +[66404] = {category="lo"}, +[66405] = {category="lo"}, +[66406] = {category="lo"}, +[66407] = {category="lo"}, +[66408] = {category="lo"}, +[66409] = {category="lo"}, +[66410] = {category="lo"}, +[66411] = {category="lo"}, +[66412] = {category="lo"}, +[66413] = {category="lo"}, +[66414] = {category="lo"}, +[66415] = {category="lo"}, +[66416] = {category="lo"}, +[66417] = {category="lo"}, +[66418] = {category="lo"}, +[66419] = {category="lo"}, +[66420] = {category="lo"}, +[66421] = {category="lo"}, +[66432] = {category="lo"}, +[66433] = {category="lo"}, +[66434] = {category="lo"}, +[66435] = {category="lo"}, +[66436] = {category="lo"}, +[66437] = {category="lo"}, +[66438] = {category="lo"}, +[66439] = {category="lo"}, +[66440] = {category="lo"}, +[66441] = {category="lo"}, +[66442] = {category="lo"}, +[66443] = {category="lo"}, +[66444] = {category="lo"}, +[66445] = {category="lo"}, +[66446] = {category="lo"}, +[66447] = {category="lo"}, +[66448] = {category="lo"}, +[66449] = {category="lo"}, +[66450] = {category="lo"}, +[66451] = {category="lo"}, +[66452] = {category="lo"}, +[66453] = {category="lo"}, +[66454] = {category="lo"}, +[66455] = {category="lo"}, +[66456] = {category="lo"}, +[66457] = {category="lo"}, +[66458] = {category="lo"}, +[66459] = {category="lo"}, +[66460] = {category="lo"}, +[66461] = {category="lo"}, +[66464] = {category="lo"}, +[66465] = {category="lo"}, +[66466] = {category="lo"}, +[66467] = {category="lo"}, +[66468] = {category="lo"}, +[66469] = {category="lo"}, +[66470] = {category="lo"}, +[66471] = {category="lo"}, +[66472] = {category="lo"}, +[66473] = {category="lo"}, +[66474] = {category="lo"}, +[66475] = {category="lo"}, +[66476] = {category="lo"}, +[66477] = {category="lo"}, +[66478] = {category="lo"}, +[66479] = {category="lo"}, +[66480] = {category="lo"}, +[66481] = {category="lo"}, +[66482] = {category="lo"}, +[66483] = {category="lo"}, +[66484] = {category="lo"}, +[66485] = {category="lo"}, +[66486] = {category="lo"}, +[66487] = {category="lo"}, +[66488] = {category="lo"}, +[66489] = {category="lo"}, +[66490] = {category="lo"}, +[66491] = {category="lo"}, +[66492] = {category="lo"}, +[66493] = {category="lo"}, +[66494] = {category="lo"}, +[66495] = {category="lo"}, +[66496] = {category="lo"}, +[66497] = {category="lo"}, +[66498] = {category="lo"}, +[66499] = {category="lo"}, +[66504] = {category="lo"}, +[66505] = {category="lo"}, +[66506] = {category="lo"}, +[66507] = {category="lo"}, +[66508] = {category="lo"}, +[66509] = {category="lo"}, +[66510] = {category="lo"}, +[66511] = {category="lo"}, +[66560] = {category="lu", lccode=66600}, +[66561] = {category="lu", lccode=66601}, +[66562] = {category="lu", lccode=66602}, +[66563] = {category="lu", lccode=66603}, +[66564] = {category="lu", lccode=66604}, +[66565] = {category="lu", lccode=66605}, +[66566] = {category="lu", lccode=66606}, +[66567] = {category="lu", lccode=66607}, +[66568] = {category="lu", lccode=66608}, +[66569] = {category="lu", lccode=66609}, +[66570] = {category="lu", lccode=66610}, +[66571] = {category="lu", lccode=66611}, +[66572] = {category="lu", lccode=66612}, +[66573] = {category="lu", lccode=66613}, +[66574] = {category="lu", lccode=66614}, +[66575] = {category="lu", lccode=66615}, +[66576] = {category="lu", lccode=66616}, +[66577] = {category="lu", lccode=66617}, +[66578] = {category="lu", lccode=66618}, +[66579] = {category="lu", lccode=66619}, +[66580] = {category="lu", lccode=66620}, +[66581] = {category="lu", lccode=66621}, +[66582] = {category="lu", lccode=66622}, +[66583] = {category="lu", lccode=66623}, +[66584] = {category="lu", lccode=66624}, +[66585] = {category="lu", lccode=66625}, +[66586] = {category="lu", lccode=66626}, +[66587] = {category="lu", lccode=66627}, +[66588] = {category="lu", lccode=66628}, +[66589] = {category="lu", lccode=66629}, +[66590] = {category="lu", lccode=66630}, +[66591] = {category="lu", lccode=66631}, +[66592] = {category="lu", lccode=66632}, +[66593] = {category="lu", lccode=66633}, +[66594] = {category="lu", lccode=66634}, +[66595] = {category="lu", lccode=66635}, +[66596] = {category="lu", lccode=66636}, +[66597] = {category="lu", lccode=66637}, +[66598] = {category="lu", lccode=66638}, +[66599] = {category="lu", lccode=66639}, +[66600] = {category="ll"}, +[66601] = {category="ll"}, +[66602] = {category="ll"}, +[66603] = {category="ll"}, +[66604] = {category="ll"}, +[66605] = {category="ll"}, +[66606] = {category="ll"}, +[66607] = {category="ll"}, +[66608] = {category="ll"}, +[66609] = {category="ll"}, +[66610] = {category="ll"}, +[66611] = {category="ll"}, +[66612] = {category="ll"}, +[66613] = {category="ll"}, +[66614] = {category="ll"}, +[66615] = {category="ll"}, +[66616] = {category="ll"}, +[66617] = {category="ll"}, +[66618] = {category="ll"}, +[66619] = {category="ll"}, +[66620] = {category="ll"}, +[66621] = {category="ll"}, +[66622] = {category="ll"}, +[66623] = {category="ll"}, +[66624] = {category="ll"}, +[66625] = {category="ll"}, +[66626] = {category="ll"}, +[66627] = {category="ll"}, +[66628] = {category="ll"}, +[66629] = {category="ll"}, +[66630] = {category="ll"}, +[66631] = {category="ll"}, +[66632] = {category="ll"}, +[66633] = {category="ll"}, +[66634] = {category="ll"}, +[66635] = {category="ll"}, +[66636] = {category="ll"}, +[66637] = {category="ll"}, +[66638] = {category="ll"}, +[66639] = {category="ll"}, +[66640] = {category="lo"}, +[66641] = {category="lo"}, +[66642] = {category="lo"}, +[66643] = {category="lo"}, +[66644] = {category="lo"}, +[66645] = {category="lo"}, +[66646] = {category="lo"}, +[66647] = {category="lo"}, +[66648] = {category="lo"}, +[66649] = {category="lo"}, +[66650] = {category="lo"}, +[66651] = {category="lo"}, +[66652] = {category="lo"}, +[66653] = {category="lo"}, +[66654] = {category="lo"}, +[66655] = {category="lo"}, +[66656] = {category="lo"}, +[66657] = {category="lo"}, +[66658] = {category="lo"}, +[66659] = {category="lo"}, +[66660] = {category="lo"}, +[66661] = {category="lo"}, +[66662] = {category="lo"}, +[66663] = {category="lo"}, +[66664] = {category="lo"}, +[66665] = {category="lo"}, +[66666] = {category="lo"}, +[66667] = {category="lo"}, +[66668] = {category="lo"}, +[66669] = {category="lo"}, +[66670] = {category="lo"}, +[66671] = {category="lo"}, +[66672] = {category="lo"}, +[66673] = {category="lo"}, +[66674] = {category="lo"}, +[66675] = {category="lo"}, +[66676] = {category="lo"}, +[66677] = {category="lo"}, +[66678] = {category="lo"}, +[66679] = {category="lo"}, +[66680] = {category="lo"}, +[66681] = {category="lo"}, +[66682] = {category="lo"}, +[66683] = {category="lo"}, +[66684] = {category="lo"}, +[66685] = {category="lo"}, +[66686] = {category="lo"}, +[66687] = {category="lo"}, +[66688] = {category="lo"}, +[66689] = {category="lo"}, +[66690] = {category="lo"}, +[66691] = {category="lo"}, +[66692] = {category="lo"}, +[66693] = {category="lo"}, +[66694] = {category="lo"}, +[66695] = {category="lo"}, +[66696] = {category="lo"}, +[66697] = {category="lo"}, +[66698] = {category="lo"}, +[66699] = {category="lo"}, +[66700] = {category="lo"}, +[66701] = {category="lo"}, +[66702] = {category="lo"}, +[66703] = {category="lo"}, +[66704] = {category="lo"}, +[66705] = {category="lo"}, +[66706] = {category="lo"}, +[66707] = {category="lo"}, +[66708] = {category="lo"}, +[66709] = {category="lo"}, +[66710] = {category="lo"}, +[66711] = {category="lo"}, +[66712] = {category="lo"}, +[66713] = {category="lo"}, +[66714] = {category="lo"}, +[66715] = {category="lo"}, +[66716] = {category="lo"}, +[66717] = {category="lo"}, +[66736] = {category="lu", lccode=66776}, +[66737] = {category="lu", lccode=66777}, +[66738] = {category="lu", lccode=66778}, +[66739] = {category="lu", lccode=66779}, +[66740] = {category="lu", lccode=66780}, +[66741] = {category="lu", lccode=66781}, +[66742] = {category="lu", lccode=66782}, +[66743] = {category="lu", lccode=66783}, +[66744] = {category="lu", lccode=66784}, +[66745] = {category="lu", lccode=66785}, +[66746] = {category="lu", lccode=66786}, +[66747] = {category="lu", lccode=66787}, +[66748] = {category="lu", lccode=66788}, +[66749] = {category="lu", lccode=66789}, +[66750] = {category="lu", lccode=66790}, +[66751] = {category="lu", lccode=66791}, +[66752] = {category="lu", lccode=66792}, +[66753] = {category="lu", lccode=66793}, +[66754] = {category="lu", lccode=66794}, +[66755] = {category="lu", lccode=66795}, +[66756] = {category="lu", lccode=66796}, +[66757] = {category="lu", lccode=66797}, +[66758] = {category="lu", lccode=66798}, +[66759] = {category="lu", lccode=66799}, +[66760] = {category="lu", lccode=66800}, +[66761] = {category="lu", lccode=66801}, +[66762] = {category="lu", lccode=66802}, +[66763] = {category="lu", lccode=66803}, +[66764] = {category="lu", lccode=66804}, +[66765] = {category="lu", lccode=66805}, +[66766] = {category="lu", lccode=66806}, +[66767] = {category="lu", lccode=66807}, +[66768] = {category="lu", lccode=66808}, +[66769] = {category="lu", lccode=66809}, +[66770] = {category="lu", lccode=66810}, +[66771] = {category="lu", lccode=66811}, +[66776] = {category="ll"}, +[66777] = {category="ll"}, +[66778] = {category="ll"}, +[66779] = {category="ll"}, +[66780] = {category="ll"}, +[66781] = {category="ll"}, +[66782] = {category="ll"}, +[66783] = {category="ll"}, +[66784] = {category="ll"}, +[66785] = {category="ll"}, +[66786] = {category="ll"}, +[66787] = {category="ll"}, +[66788] = {category="ll"}, +[66789] = {category="ll"}, +[66790] = {category="ll"}, +[66791] = {category="ll"}, +[66792] = {category="ll"}, +[66793] = {category="ll"}, +[66794] = {category="ll"}, +[66795] = {category="ll"}, +[66796] = {category="ll"}, +[66797] = {category="ll"}, +[66798] = {category="ll"}, +[66799] = {category="ll"}, +[66800] = {category="ll"}, +[66801] = {category="ll"}, +[66802] = {category="ll"}, +[66803] = {category="ll"}, +[66804] = {category="ll"}, +[66805] = {category="ll"}, +[66806] = {category="ll"}, +[66807] = {category="ll"}, +[66808] = {category="ll"}, +[66809] = {category="ll"}, +[66810] = {category="ll"}, +[66811] = {category="ll"}, +[66816] = {category="lo"}, +[66817] = {category="lo"}, +[66818] = {category="lo"}, +[66819] = {category="lo"}, +[66820] = {category="lo"}, +[66821] = {category="lo"}, +[66822] = {category="lo"}, +[66823] = {category="lo"}, +[66824] = {category="lo"}, +[66825] = {category="lo"}, +[66826] = {category="lo"}, +[66827] = {category="lo"}, +[66828] = {category="lo"}, +[66829] = {category="lo"}, +[66830] = {category="lo"}, +[66831] = {category="lo"}, +[66832] = {category="lo"}, +[66833] = {category="lo"}, +[66834] = {category="lo"}, +[66835] = {category="lo"}, +[66836] = {category="lo"}, +[66837] = {category="lo"}, +[66838] = {category="lo"}, +[66839] = {category="lo"}, +[66840] = {category="lo"}, +[66841] = {category="lo"}, +[66842] = {category="lo"}, +[66843] = {category="lo"}, +[66844] = {category="lo"}, +[66845] = {category="lo"}, +[66846] = {category="lo"}, +[66847] = {category="lo"}, +[66848] = {category="lo"}, +[66849] = {category="lo"}, +[66850] = {category="lo"}, +[66851] = {category="lo"}, +[66852] = {category="lo"}, +[66853] = {category="lo"}, +[66854] = {category="lo"}, +[66855] = {category="lo"}, +[66864] = {category="lo"}, +[66865] = {category="lo"}, +[66866] = {category="lo"}, +[66867] = {category="lo"}, +[66868] = {category="lo"}, +[66869] = {category="lo"}, +[66870] = {category="lo"}, +[66871] = {category="lo"}, +[66872] = {category="lo"}, +[66873] = {category="lo"}, +[66874] = {category="lo"}, +[66875] = {category="lo"}, +[66876] = {category="lo"}, +[66877] = {category="lo"}, +[66878] = {category="lo"}, +[66879] = {category="lo"}, +[66880] = {category="lo"}, +[66881] = {category="lo"}, +[66882] = {category="lo"}, +[66883] = {category="lo"}, +[66884] = {category="lo"}, +[66885] = {category="lo"}, +[66886] = {category="lo"}, +[66887] = {category="lo"}, +[66888] = {category="lo"}, +[66889] = {category="lo"}, +[66890] = {category="lo"}, +[66891] = {category="lo"}, +[66892] = {category="lo"}, +[66893] = {category="lo"}, +[66894] = {category="lo"}, +[66895] = {category="lo"}, +[66896] = {category="lo"}, +[66897] = {category="lo"}, +[66898] = {category="lo"}, +[66899] = {category="lo"}, +[66900] = {category="lo"}, +[66901] = {category="lo"}, +[66902] = {category="lo"}, +[66903] = {category="lo"}, +[66904] = {category="lo"}, +[66905] = {category="lo"}, +[66906] = {category="lo"}, +[66907] = {category="lo"}, +[66908] = {category="lo"}, +[66909] = {category="lo"}, +[66910] = {category="lo"}, +[66911] = {category="lo"}, +[66912] = {category="lo"}, +[66913] = {category="lo"}, +[66914] = {category="lo"}, +[66915] = {category="lo"}, +[66928] = {category="lu", lccode=66967}, +[66929] = {category="lu", lccode=66968}, +[66930] = {category="lu", lccode=66969}, +[66931] = {category="lu", lccode=66970}, +[66932] = {category="lu", lccode=66971}, +[66933] = {category="lu", lccode=66972}, +[66934] = {category="lu", lccode=66973}, +[66935] = {category="lu", lccode=66974}, +[66936] = {category="lu", lccode=66975}, +[66937] = {category="lu", lccode=66976}, +[66938] = {category="lu", lccode=66977}, +[66940] = {category="lu", lccode=66979}, +[66941] = {category="lu", lccode=66980}, +[66942] = {category="lu", lccode=66981}, +[66943] = {category="lu", lccode=66982}, +[66944] = {category="lu", lccode=66983}, +[66945] = {category="lu", lccode=66984}, +[66946] = {category="lu", lccode=66985}, +[66947] = {category="lu", lccode=66986}, +[66948] = {category="lu", lccode=66987}, +[66949] = {category="lu", lccode=66988}, +[66950] = {category="lu", lccode=66989}, +[66951] = {category="lu", lccode=66990}, +[66952] = {category="lu", lccode=66991}, +[66953] = {category="lu", lccode=66992}, +[66954] = {category="lu", lccode=66993}, +[66956] = {category="lu", lccode=66995}, +[66957] = {category="lu", lccode=66996}, +[66958] = {category="lu", lccode=66997}, +[66959] = {category="lu", lccode=66998}, +[66960] = {category="lu", lccode=66999}, +[66961] = {category="lu", lccode=67000}, +[66962] = {category="lu", lccode=67001}, +[66964] = {category="lu", lccode=67003}, +[66965] = {category="lu", lccode=67004}, +[66967] = {category="ll"}, +[66968] = {category="ll"}, +[66969] = {category="ll"}, +[66970] = {category="ll"}, +[66971] = {category="ll"}, +[66972] = {category="ll"}, +[66973] = {category="ll"}, +[66974] = {category="ll"}, +[66975] = {category="ll"}, +[66976] = {category="ll"}, +[66977] = {category="ll"}, +[66979] = {category="ll"}, +[66980] = {category="ll"}, +[66981] = {category="ll"}, +[66982] = {category="ll"}, +[66983] = {category="ll"}, +[66984] = {category="ll"}, +[66985] = {category="ll"}, +[66986] = {category="ll"}, +[66987] = {category="ll"}, +[66988] = {category="ll"}, +[66989] = {category="ll"}, +[66990] = {category="ll"}, +[66991] = {category="ll"}, +[66992] = {category="ll"}, +[66993] = {category="ll"}, +[66995] = {category="ll"}, +[66996] = {category="ll"}, +[66997] = {category="ll"}, +[66998] = {category="ll"}, +[66999] = {category="ll"}, +[67000] = {category="ll"}, +[67001] = {category="ll"}, +[67003] = {category="ll"}, +[67004] = {category="ll"}, +[67072] = {category="lo"}, +[67073] = {category="lo"}, +[67074] = {category="lo"}, +[67075] = {category="lo"}, +[67076] = {category="lo"}, +[67077] = {category="lo"}, +[67078] = {category="lo"}, +[67079] = {category="lo"}, +[67080] = {category="lo"}, +[67081] = {category="lo"}, +[67082] = {category="lo"}, +[67083] = {category="lo"}, +[67084] = {category="lo"}, +[67085] = {category="lo"}, +[67086] = {category="lo"}, +[67087] = {category="lo"}, +[67088] = {category="lo"}, +[67089] = {category="lo"}, +[67090] = {category="lo"}, +[67091] = {category="lo"}, +[67092] = {category="lo"}, +[67093] = {category="lo"}, +[67094] = {category="lo"}, +[67095] = {category="lo"}, +[67096] = {category="lo"}, +[67097] = {category="lo"}, +[67098] = {category="lo"}, +[67099] = {category="lo"}, +[67100] = {category="lo"}, +[67101] = {category="lo"}, +[67102] = {category="lo"}, +[67103] = {category="lo"}, +[67104] = {category="lo"}, +[67105] = {category="lo"}, +[67106] = {category="lo"}, +[67107] = {category="lo"}, +[67108] = {category="lo"}, +[67109] = {category="lo"}, +[67110] = {category="lo"}, +[67111] = {category="lo"}, +[67112] = {category="lo"}, +[67113] = {category="lo"}, +[67114] = {category="lo"}, +[67115] = {category="lo"}, +[67116] = {category="lo"}, +[67117] = {category="lo"}, +[67118] = {category="lo"}, +[67119] = {category="lo"}, +[67120] = {category="lo"}, +[67121] = {category="lo"}, +[67122] = {category="lo"}, +[67123] = {category="lo"}, +[67124] = {category="lo"}, +[67125] = {category="lo"}, +[67126] = {category="lo"}, +[67127] = {category="lo"}, +[67128] = {category="lo"}, +[67129] = {category="lo"}, +[67130] = {category="lo"}, +[67131] = {category="lo"}, +[67132] = {category="lo"}, +[67133] = {category="lo"}, +[67134] = {category="lo"}, +[67135] = {category="lo"}, +[67136] = {category="lo"}, +[67137] = {category="lo"}, +[67138] = {category="lo"}, +[67139] = {category="lo"}, +[67140] = {category="lo"}, +[67141] = {category="lo"}, +[67142] = {category="lo"}, +[67143] = {category="lo"}, +[67144] = {category="lo"}, +[67145] = {category="lo"}, +[67146] = {category="lo"}, +[67147] = {category="lo"}, +[67148] = {category="lo"}, +[67149] = {category="lo"}, +[67150] = {category="lo"}, +[67151] = {category="lo"}, +[67152] = {category="lo"}, +[67153] = {category="lo"}, +[67154] = {category="lo"}, +[67155] = {category="lo"}, +[67156] = {category="lo"}, +[67157] = {category="lo"}, +[67158] = {category="lo"}, +[67159] = {category="lo"}, +[67160] = {category="lo"}, +[67161] = {category="lo"}, +[67162] = {category="lo"}, +[67163] = {category="lo"}, +[67164] = {category="lo"}, +[67165] = {category="lo"}, +[67166] = {category="lo"}, +[67167] = {category="lo"}, +[67168] = {category="lo"}, +[67169] = {category="lo"}, +[67170] = {category="lo"}, +[67171] = {category="lo"}, +[67172] = {category="lo"}, +[67173] = {category="lo"}, +[67174] = {category="lo"}, +[67175] = {category="lo"}, +[67176] = {category="lo"}, +[67177] = {category="lo"}, +[67178] = {category="lo"}, +[67179] = {category="lo"}, +[67180] = {category="lo"}, +[67181] = {category="lo"}, +[67182] = {category="lo"}, +[67183] = {category="lo"}, +[67184] = {category="lo"}, +[67185] = {category="lo"}, +[67186] = {category="lo"}, +[67187] = {category="lo"}, +[67188] = {category="lo"}, +[67189] = {category="lo"}, +[67190] = {category="lo"}, +[67191] = {category="lo"}, +[67192] = {category="lo"}, +[67193] = {category="lo"}, +[67194] = {category="lo"}, +[67195] = {category="lo"}, +[67196] = {category="lo"}, +[67197] = {category="lo"}, +[67198] = {category="lo"}, +[67199] = {category="lo"}, +[67200] = {category="lo"}, +[67201] = {category="lo"}, +[67202] = {category="lo"}, +[67203] = {category="lo"}, +[67204] = {category="lo"}, +[67205] = {category="lo"}, +[67206] = {category="lo"}, +[67207] = {category="lo"}, +[67208] = {category="lo"}, +[67209] = {category="lo"}, +[67210] = {category="lo"}, +[67211] = {category="lo"}, +[67212] = {category="lo"}, +[67213] = {category="lo"}, +[67214] = {category="lo"}, +[67215] = {category="lo"}, +[67216] = {category="lo"}, +[67217] = {category="lo"}, +[67218] = {category="lo"}, +[67219] = {category="lo"}, +[67220] = {category="lo"}, +[67221] = {category="lo"}, +[67222] = {category="lo"}, +[67223] = {category="lo"}, +[67224] = {category="lo"}, +[67225] = {category="lo"}, +[67226] = {category="lo"}, +[67227] = {category="lo"}, +[67228] = {category="lo"}, +[67229] = {category="lo"}, +[67230] = {category="lo"}, +[67231] = {category="lo"}, +[67232] = {category="lo"}, +[67233] = {category="lo"}, +[67234] = {category="lo"}, +[67235] = {category="lo"}, +[67236] = {category="lo"}, +[67237] = {category="lo"}, +[67238] = {category="lo"}, +[67239] = {category="lo"}, +[67240] = {category="lo"}, +[67241] = {category="lo"}, +[67242] = {category="lo"}, +[67243] = {category="lo"}, +[67244] = {category="lo"}, +[67245] = {category="lo"}, +[67246] = {category="lo"}, +[67247] = {category="lo"}, +[67248] = {category="lo"}, +[67249] = {category="lo"}, +[67250] = {category="lo"}, +[67251] = {category="lo"}, +[67252] = {category="lo"}, +[67253] = {category="lo"}, +[67254] = {category="lo"}, +[67255] = {category="lo"}, +[67256] = {category="lo"}, +[67257] = {category="lo"}, +[67258] = {category="lo"}, +[67259] = {category="lo"}, +[67260] = {category="lo"}, +[67261] = {category="lo"}, +[67262] = {category="lo"}, +[67263] = {category="lo"}, +[67264] = {category="lo"}, +[67265] = {category="lo"}, +[67266] = {category="lo"}, +[67267] = {category="lo"}, +[67268] = {category="lo"}, +[67269] = {category="lo"}, +[67270] = {category="lo"}, +[67271] = {category="lo"}, +[67272] = {category="lo"}, +[67273] = {category="lo"}, +[67274] = {category="lo"}, +[67275] = {category="lo"}, +[67276] = {category="lo"}, +[67277] = {category="lo"}, +[67278] = {category="lo"}, +[67279] = {category="lo"}, +[67280] = {category="lo"}, +[67281] = {category="lo"}, +[67282] = {category="lo"}, +[67283] = {category="lo"}, +[67284] = {category="lo"}, +[67285] = {category="lo"}, +[67286] = {category="lo"}, +[67287] = {category="lo"}, +[67288] = {category="lo"}, +[67289] = {category="lo"}, +[67290] = {category="lo"}, +[67291] = {category="lo"}, +[67292] = {category="lo"}, +[67293] = {category="lo"}, +[67294] = {category="lo"}, +[67295] = {category="lo"}, +[67296] = {category="lo"}, +[67297] = {category="lo"}, +[67298] = {category="lo"}, +[67299] = {category="lo"}, +[67300] = {category="lo"}, +[67301] = {category="lo"}, +[67302] = {category="lo"}, +[67303] = {category="lo"}, +[67304] = {category="lo"}, +[67305] = {category="lo"}, +[67306] = {category="lo"}, +[67307] = {category="lo"}, +[67308] = {category="lo"}, +[67309] = {category="lo"}, +[67310] = {category="lo"}, +[67311] = {category="lo"}, +[67312] = {category="lo"}, +[67313] = {category="lo"}, +[67314] = {category="lo"}, +[67315] = {category="lo"}, +[67316] = {category="lo"}, +[67317] = {category="lo"}, +[67318] = {category="lo"}, +[67319] = {category="lo"}, +[67320] = {category="lo"}, +[67321] = {category="lo"}, +[67322] = {category="lo"}, +[67323] = {category="lo"}, +[67324] = {category="lo"}, +[67325] = {category="lo"}, +[67326] = {category="lo"}, +[67327] = {category="lo"}, +[67328] = {category="lo"}, +[67329] = {category="lo"}, +[67330] = {category="lo"}, +[67331] = {category="lo"}, +[67332] = {category="lo"}, +[67333] = {category="lo"}, +[67334] = {category="lo"}, +[67335] = {category="lo"}, +[67336] = {category="lo"}, +[67337] = {category="lo"}, +[67338] = {category="lo"}, +[67339] = {category="lo"}, +[67340] = {category="lo"}, +[67341] = {category="lo"}, +[67342] = {category="lo"}, +[67343] = {category="lo"}, +[67344] = {category="lo"}, +[67345] = {category="lo"}, +[67346] = {category="lo"}, +[67347] = {category="lo"}, +[67348] = {category="lo"}, +[67349] = {category="lo"}, +[67350] = {category="lo"}, +[67351] = {category="lo"}, +[67352] = {category="lo"}, +[67353] = {category="lo"}, +[67354] = {category="lo"}, +[67355] = {category="lo"}, +[67356] = {category="lo"}, +[67357] = {category="lo"}, +[67358] = {category="lo"}, +[67359] = {category="lo"}, +[67360] = {category="lo"}, +[67361] = {category="lo"}, +[67362] = {category="lo"}, +[67363] = {category="lo"}, +[67364] = {category="lo"}, +[67365] = {category="lo"}, +[67366] = {category="lo"}, +[67367] = {category="lo"}, +[67368] = {category="lo"}, +[67369] = {category="lo"}, +[67370] = {category="lo"}, +[67371] = {category="lo"}, +[67372] = {category="lo"}, +[67373] = {category="lo"}, +[67374] = {category="lo"}, +[67375] = {category="lo"}, +[67376] = {category="lo"}, +[67377] = {category="lo"}, +[67378] = {category="lo"}, +[67379] = {category="lo"}, +[67380] = {category="lo"}, +[67381] = {category="lo"}, +[67382] = {category="lo"}, +[67392] = {category="lo"}, +[67393] = {category="lo"}, +[67394] = {category="lo"}, +[67395] = {category="lo"}, +[67396] = {category="lo"}, +[67397] = {category="lo"}, +[67398] = {category="lo"}, +[67399] = {category="lo"}, +[67400] = {category="lo"}, +[67401] = {category="lo"}, +[67402] = {category="lo"}, +[67403] = {category="lo"}, +[67404] = {category="lo"}, +[67405] = {category="lo"}, +[67406] = {category="lo"}, +[67407] = {category="lo"}, +[67408] = {category="lo"}, +[67409] = {category="lo"}, +[67410] = {category="lo"}, +[67411] = {category="lo"}, +[67412] = {category="lo"}, +[67413] = {category="lo"}, +[67424] = {category="lo"}, +[67425] = {category="lo"}, +[67426] = {category="lo"}, +[67427] = {category="lo"}, +[67428] = {category="lo"}, +[67429] = {category="lo"}, +[67430] = {category="lo"}, +[67431] = {category="lo"}, +[67456] = {category="lm"}, +[67457] = {category="lm", shcode=14}, +[67458] = {category="lm", shcode=14}, +[67459] = {category="lm", shcode=14}, +[67460] = {category="lm", shcode=14}, +[67461] = {category="lm", shcode=14}, +[67463] = {category="lm", shcode=14}, +[67464] = {category="lm", shcode=14}, +[67465] = {category="lm", shcode=14}, +[67466] = {category="lm", shcode=14}, +[67467] = {category="lm", shcode=14}, +[67468] = {category="lm", shcode=14}, +[67469] = {category="lm", shcode=14}, +[67470] = {category="lm", shcode=14}, +[67471] = {category="lm", shcode=14}, +[67472] = {category="lm", shcode=14}, +[67473] = {category="lm", shcode=14}, +[67474] = {category="lm", shcode=14}, +[67475] = {category="lm", shcode=14}, +[67476] = {category="lm", shcode=14}, +[67477] = {category="lm", shcode=14}, +[67478] = {category="lm", shcode=14}, +[67479] = {category="lm", shcode=14}, +[67480] = {category="lm", shcode=14}, +[67481] = {category="lm", shcode=14}, +[67482] = {category="lm", shcode=14}, +[67483] = {category="lm", shcode=14}, +[67484] = {category="lm", shcode=14}, +[67485] = {category="lm", shcode=14}, +[67486] = {category="lm", shcode=14}, +[67487] = {category="lm", shcode=14}, +[67488] = {category="lm", shcode=14}, +[67489] = {category="lm", shcode=14}, +[67490] = {category="lm", shcode=14}, +[67491] = {category="lm", shcode=14}, +[67492] = {category="lm", shcode=14}, +[67493] = {category="lm", shcode=14}, +[67494] = {category="lm", shcode=14}, +[67495] = {category="lm", shcode=14}, +[67496] = {category="lm", shcode=14}, +[67497] = {category="lm", shcode=14}, +[67498] = {category="lm", shcode=14}, +[67499] = {category="lm", shcode=14}, +[67500] = {category="lm", shcode=14}, +[67501] = {category="lm", shcode=14}, +[67502] = {category="lm", shcode=14}, +[67503] = {category="lm", shcode=14}, +[67504] = {category="lm", shcode=14}, +[67506] = {category="lm", shcode=14}, +[67507] = {category="lm", shcode=14}, +[67508] = {category="lm", shcode=14}, +[67509] = {category="lm", shcode=14}, +[67510] = {category="lm", shcode=14}, +[67511] = {category="lm", shcode=14}, +[67512] = {category="lm", shcode=14}, +[67513] = {category="lm", shcode=14}, +[67514] = {category="lm", shcode=14}, +[67584] = {category="lo"}, +[67585] = {category="lo"}, +[67586] = {category="lo"}, +[67587] = {category="lo"}, +[67588] = {category="lo"}, +[67589] = {category="lo"}, +[67592] = {category="lo"}, +[67594] = {category="lo"}, +[67595] = {category="lo"}, +[67596] = {category="lo"}, +[67597] = {category="lo"}, +[67598] = {category="lo"}, +[67599] = {category="lo"}, +[67600] = {category="lo"}, +[67601] = {category="lo"}, +[67602] = {category="lo"}, +[67603] = {category="lo"}, +[67604] = {category="lo"}, +[67605] = {category="lo"}, +[67606] = {category="lo"}, +[67607] = {category="lo"}, +[67608] = {category="lo"}, +[67609] = {category="lo"}, +[67610] = {category="lo"}, +[67611] = {category="lo"}, +[67612] = {category="lo"}, +[67613] = {category="lo"}, +[67614] = {category="lo"}, +[67615] = {category="lo"}, +[67616] = {category="lo"}, +[67617] = {category="lo"}, +[67618] = {category="lo"}, +[67619] = {category="lo"}, +[67620] = {category="lo"}, +[67621] = {category="lo"}, +[67622] = {category="lo"}, +[67623] = {category="lo"}, +[67624] = {category="lo"}, +[67625] = {category="lo"}, +[67626] = {category="lo"}, +[67627] = {category="lo"}, +[67628] = {category="lo"}, +[67629] = {category="lo"}, +[67630] = {category="lo"}, +[67631] = {category="lo"}, +[67632] = {category="lo"}, +[67633] = {category="lo"}, +[67634] = {category="lo"}, +[67635] = {category="lo"}, +[67636] = {category="lo"}, +[67637] = {category="lo"}, +[67639] = {category="lo"}, +[67640] = {category="lo"}, +[67644] = {category="lo"}, +[67647] = {category="lo"}, +[67648] = {category="lo"}, +[67649] = {category="lo"}, +[67650] = {category="lo"}, +[67651] = {category="lo"}, +[67652] = {category="lo"}, +[67653] = {category="lo"}, +[67654] = {category="lo"}, +[67655] = {category="lo"}, +[67656] = {category="lo"}, +[67657] = {category="lo"}, +[67658] = {category="lo"}, +[67659] = {category="lo"}, +[67660] = {category="lo"}, +[67661] = {category="lo"}, +[67662] = {category="lo"}, +[67663] = {category="lo"}, +[67664] = {category="lo"}, +[67665] = {category="lo"}, +[67666] = {category="lo"}, +[67667] = {category="lo"}, +[67668] = {category="lo"}, +[67669] = {category="lo"}, +[67680] = {category="lo"}, +[67681] = {category="lo"}, +[67682] = {category="lo"}, +[67683] = {category="lo"}, +[67684] = {category="lo"}, +[67685] = {category="lo"}, +[67686] = {category="lo"}, +[67687] = {category="lo"}, +[67688] = {category="lo"}, +[67689] = {category="lo"}, +[67690] = {category="lo"}, +[67691] = {category="lo"}, +[67692] = {category="lo"}, +[67693] = {category="lo"}, +[67694] = {category="lo"}, +[67695] = {category="lo"}, +[67696] = {category="lo"}, +[67697] = {category="lo"}, +[67698] = {category="lo"}, +[67699] = {category="lo"}, +[67700] = {category="lo"}, +[67701] = {category="lo"}, +[67702] = {category="lo"}, +[67712] = {category="lo"}, +[67713] = {category="lo"}, +[67714] = {category="lo"}, +[67715] = {category="lo"}, +[67716] = {category="lo"}, +[67717] = {category="lo"}, +[67718] = {category="lo"}, +[67719] = {category="lo"}, +[67720] = {category="lo"}, +[67721] = {category="lo"}, +[67722] = {category="lo"}, +[67723] = {category="lo"}, +[67724] = {category="lo"}, +[67725] = {category="lo"}, +[67726] = {category="lo"}, +[67727] = {category="lo"}, +[67728] = {category="lo"}, +[67729] = {category="lo"}, +[67730] = {category="lo"}, +[67731] = {category="lo"}, +[67732] = {category="lo"}, +[67733] = {category="lo"}, +[67734] = {category="lo"}, +[67735] = {category="lo"}, +[67736] = {category="lo"}, +[67737] = {category="lo"}, +[67738] = {category="lo"}, +[67739] = {category="lo"}, +[67740] = {category="lo"}, +[67741] = {category="lo"}, +[67742] = {category="lo"}, +[67808] = {category="lo"}, +[67809] = {category="lo"}, +[67810] = {category="lo"}, +[67811] = {category="lo"}, +[67812] = {category="lo"}, +[67813] = {category="lo"}, +[67814] = {category="lo"}, +[67815] = {category="lo"}, +[67816] = {category="lo"}, +[67817] = {category="lo"}, +[67818] = {category="lo"}, +[67819] = {category="lo"}, +[67820] = {category="lo"}, +[67821] = {category="lo"}, +[67822] = {category="lo"}, +[67823] = {category="lo"}, +[67824] = {category="lo"}, +[67825] = {category="lo"}, +[67826] = {category="lo"}, +[67828] = {category="lo"}, +[67829] = {category="lo"}, +[67840] = {category="lo"}, +[67841] = {category="lo"}, +[67842] = {category="lo"}, +[67843] = {category="lo"}, +[67844] = {category="lo"}, +[67845] = {category="lo"}, +[67846] = {category="lo"}, +[67847] = {category="lo"}, +[67848] = {category="lo"}, +[67849] = {category="lo"}, +[67850] = {category="lo"}, +[67851] = {category="lo"}, +[67852] = {category="lo"}, +[67853] = {category="lo"}, +[67854] = {category="lo"}, +[67855] = {category="lo"}, +[67856] = {category="lo"}, +[67857] = {category="lo"}, +[67858] = {category="lo"}, +[67859] = {category="lo"}, +[67860] = {category="lo"}, +[67861] = {category="lo"}, +[67872] = {category="lo"}, +[67873] = {category="lo"}, +[67874] = {category="lo"}, +[67875] = {category="lo"}, +[67876] = {category="lo"}, +[67877] = {category="lo"}, +[67878] = {category="lo"}, +[67879] = {category="lo"}, +[67880] = {category="lo"}, +[67881] = {category="lo"}, +[67882] = {category="lo"}, +[67883] = {category="lo"}, +[67884] = {category="lo"}, +[67885] = {category="lo"}, +[67886] = {category="lo"}, +[67887] = {category="lo"}, +[67888] = {category="lo"}, +[67889] = {category="lo"}, +[67890] = {category="lo"}, +[67891] = {category="lo"}, +[67892] = {category="lo"}, +[67893] = {category="lo"}, +[67894] = {category="lo"}, +[67895] = {category="lo"}, +[67896] = {category="lo"}, +[67897] = {category="lo"}, +[67968] = {category="lo"}, +[67969] = {category="lo"}, +[67970] = {category="lo"}, +[67971] = {category="lo"}, +[67972] = {category="lo"}, +[67973] = {category="lo"}, +[67974] = {category="lo"}, +[67975] = {category="lo"}, +[67976] = {category="lo"}, +[67977] = {category="lo"}, +[67978] = {category="lo"}, +[67979] = {category="lo"}, +[67980] = {category="lo"}, +[67981] = {category="lo"}, +[67982] = {category="lo"}, +[67983] = {category="lo"}, +[67984] = {category="lo"}, +[67985] = {category="lo"}, +[67986] = {category="lo"}, +[67987] = {category="lo"}, +[67988] = {category="lo"}, +[67989] = {category="lo"}, +[67990] = {category="lo"}, +[67991] = {category="lo"}, +[67992] = {category="lo"}, +[67993] = {category="lo"}, +[67994] = {category="lo"}, +[67995] = {category="lo"}, +[67996] = {category="lo"}, +[67997] = {category="lo"}, +[67998] = {category="lo"}, +[67999] = {category="lo"}, +[68000] = {category="lo"}, +[68001] = {category="lo"}, +[68002] = {category="lo"}, +[68003] = {category="lo"}, +[68004] = {category="lo"}, +[68005] = {category="lo"}, +[68006] = {category="lo"}, +[68007] = {category="lo"}, +[68008] = {category="lo"}, +[68009] = {category="lo"}, +[68010] = {category="lo"}, +[68011] = {category="lo"}, +[68012] = {category="lo"}, +[68013] = {category="lo"}, +[68014] = {category="lo"}, +[68015] = {category="lo"}, +[68016] = {category="lo"}, +[68017] = {category="lo"}, +[68018] = {category="lo"}, +[68019] = {category="lo"}, +[68020] = {category="lo"}, +[68021] = {category="lo"}, +[68022] = {category="lo"}, +[68023] = {category="lo"}, +[68030] = {category="lo"}, +[68031] = {category="lo"}, +[68096] = {category="lo"}, +[68112] = {category="lo"}, +[68113] = {category="lo"}, +[68114] = {category="lo"}, +[68115] = {category="lo"}, +[68117] = {category="lo"}, +[68118] = {category="lo"}, +[68119] = {category="lo"}, +[68121] = {category="lo"}, +[68122] = {category="lo"}, +[68123] = {category="lo"}, +[68124] = {category="lo"}, +[68125] = {category="lo"}, +[68126] = {category="lo"}, +[68127] = {category="lo"}, +[68128] = {category="lo"}, +[68129] = {category="lo"}, +[68130] = {category="lo"}, +[68131] = {category="lo"}, +[68132] = {category="lo"}, +[68133] = {category="lo"}, +[68134] = {category="lo"}, +[68135] = {category="lo"}, +[68136] = {category="lo"}, +[68137] = {category="lo"}, +[68138] = {category="lo"}, +[68139] = {category="lo"}, +[68140] = {category="lo"}, +[68141] = {category="lo"}, +[68142] = {category="lo"}, +[68143] = {category="lo"}, +[68144] = {category="lo"}, +[68145] = {category="lo"}, +[68146] = {category="lo"}, +[68147] = {category="lo"}, +[68148] = {category="lo"}, +[68149] = {category="lo"}, +[68192] = {category="lo"}, +[68193] = {category="lo"}, +[68194] = {category="lo"}, +[68195] = {category="lo"}, +[68196] = {category="lo"}, +[68197] = {category="lo"}, +[68198] = {category="lo"}, +[68199] = {category="lo"}, +[68200] = {category="lo"}, +[68201] = {category="lo"}, +[68202] = {category="lo"}, +[68203] = {category="lo"}, +[68204] = {category="lo"}, +[68205] = {category="lo"}, +[68206] = {category="lo"}, +[68207] = {category="lo"}, +[68208] = {category="lo"}, +[68209] = {category="lo"}, +[68210] = {category="lo"}, +[68211] = {category="lo"}, +[68212] = {category="lo"}, +[68213] = {category="lo"}, +[68214] = {category="lo"}, +[68215] = {category="lo"}, +[68216] = {category="lo"}, +[68217] = {category="lo"}, +[68218] = {category="lo"}, +[68219] = {category="lo"}, +[68220] = {category="lo"}, +[68224] = {category="lo"}, +[68225] = {category="lo"}, +[68226] = {category="lo"}, +[68227] = {category="lo"}, +[68228] = {category="lo"}, +[68229] = {category="lo"}, +[68230] = {category="lo"}, +[68231] = {category="lo"}, +[68232] = {category="lo"}, +[68233] = {category="lo"}, +[68234] = {category="lo"}, +[68235] = {category="lo"}, +[68236] = {category="lo"}, +[68237] = {category="lo"}, +[68238] = {category="lo"}, +[68239] = {category="lo"}, +[68240] = {category="lo"}, +[68241] = {category="lo"}, +[68242] = {category="lo"}, +[68243] = {category="lo"}, +[68244] = {category="lo"}, +[68245] = {category="lo"}, +[68246] = {category="lo"}, +[68247] = {category="lo"}, +[68248] = {category="lo"}, +[68249] = {category="lo"}, +[68250] = {category="lo"}, +[68251] = {category="lo"}, +[68252] = {category="lo"}, +[68288] = {category="lo"}, +[68289] = {category="lo"}, +[68290] = {category="lo"}, +[68291] = {category="lo"}, +[68292] = {category="lo"}, +[68293] = {category="lo"}, +[68294] = {category="lo"}, +[68295] = {category="lo"}, +[68297] = {category="lo"}, +[68298] = {category="lo"}, +[68299] = {category="lo"}, +[68300] = {category="lo"}, +[68301] = {category="lo"}, +[68302] = {category="lo"}, +[68303] = {category="lo"}, +[68304] = {category="lo"}, +[68305] = {category="lo"}, +[68306] = {category="lo"}, +[68307] = {category="lo"}, +[68308] = {category="lo"}, +[68309] = {category="lo"}, +[68310] = {category="lo"}, +[68311] = {category="lo"}, +[68312] = {category="lo"}, +[68313] = {category="lo"}, +[68314] = {category="lo"}, +[68315] = {category="lo"}, +[68316] = {category="lo"}, +[68317] = {category="lo"}, +[68318] = {category="lo"}, +[68319] = {category="lo"}, +[68320] = {category="lo"}, +[68321] = {category="lo"}, +[68322] = {category="lo"}, +[68323] = {category="lo"}, +[68324] = {category="lo"}, +[68352] = {category="lo"}, +[68353] = {category="lo"}, +[68354] = {category="lo"}, +[68355] = {category="lo"}, +[68356] = {category="lo"}, +[68357] = {category="lo"}, +[68358] = {category="lo"}, +[68359] = {category="lo"}, +[68360] = {category="lo"}, +[68361] = {category="lo"}, +[68362] = {category="lo"}, +[68363] = {category="lo"}, +[68364] = {category="lo"}, +[68365] = {category="lo"}, +[68366] = {category="lo"}, +[68367] = {category="lo"}, +[68368] = {category="lo"}, +[68369] = {category="lo"}, +[68370] = {category="lo"}, +[68371] = {category="lo"}, +[68372] = {category="lo"}, +[68373] = {category="lo"}, +[68374] = {category="lo"}, +[68375] = {category="lo"}, +[68376] = {category="lo"}, +[68377] = {category="lo"}, +[68378] = {category="lo"}, +[68379] = {category="lo"}, +[68380] = {category="lo"}, +[68381] = {category="lo"}, +[68382] = {category="lo"}, +[68383] = {category="lo"}, +[68384] = {category="lo"}, +[68385] = {category="lo"}, +[68386] = {category="lo"}, +[68387] = {category="lo"}, +[68388] = {category="lo"}, +[68389] = {category="lo"}, +[68390] = {category="lo"}, +[68391] = {category="lo"}, +[68392] = {category="lo"}, +[68393] = {category="lo"}, +[68394] = {category="lo"}, +[68395] = {category="lo"}, +[68396] = {category="lo"}, +[68397] = {category="lo"}, +[68398] = {category="lo"}, +[68399] = {category="lo"}, +[68400] = {category="lo"}, +[68401] = {category="lo"}, +[68402] = {category="lo"}, +[68403] = {category="lo"}, +[68404] = {category="lo"}, +[68405] = {category="lo"}, +[68416] = {category="lo"}, +[68417] = {category="lo"}, +[68418] = {category="lo"}, +[68419] = {category="lo"}, +[68420] = {category="lo"}, +[68421] = {category="lo"}, +[68422] = {category="lo"}, +[68423] = {category="lo"}, +[68424] = {category="lo"}, +[68425] = {category="lo"}, +[68426] = {category="lo"}, +[68427] = {category="lo"}, +[68428] = {category="lo"}, +[68429] = {category="lo"}, +[68430] = {category="lo"}, +[68431] = {category="lo"}, +[68432] = {category="lo"}, +[68433] = {category="lo"}, +[68434] = {category="lo"}, +[68435] = {category="lo"}, +[68436] = {category="lo"}, +[68437] = {category="lo"}, +[68448] = {category="lo"}, +[68449] = {category="lo"}, +[68450] = {category="lo"}, +[68451] = {category="lo"}, +[68452] = {category="lo"}, +[68453] = {category="lo"}, +[68454] = {category="lo"}, +[68455] = {category="lo"}, +[68456] = {category="lo"}, +[68457] = {category="lo"}, +[68458] = {category="lo"}, +[68459] = {category="lo"}, +[68460] = {category="lo"}, +[68461] = {category="lo"}, +[68462] = {category="lo"}, +[68463] = {category="lo"}, +[68464] = {category="lo"}, +[68465] = {category="lo"}, +[68466] = {category="lo"}, +[68480] = {category="lo"}, +[68481] = {category="lo"}, +[68482] = {category="lo"}, +[68483] = {category="lo"}, +[68484] = {category="lo"}, +[68485] = {category="lo"}, +[68486] = {category="lo"}, +[68487] = {category="lo"}, +[68488] = {category="lo"}, +[68489] = {category="lo"}, +[68490] = {category="lo"}, +[68491] = {category="lo"}, +[68492] = {category="lo"}, +[68493] = {category="lo"}, +[68494] = {category="lo"}, +[68495] = {category="lo"}, +[68496] = {category="lo"}, +[68497] = {category="lo"}, +[68608] = {category="lo"}, +[68609] = {category="lo"}, +[68610] = {category="lo"}, +[68611] = {category="lo"}, +[68612] = {category="lo"}, +[68613] = {category="lo"}, +[68614] = {category="lo"}, +[68615] = {category="lo"}, +[68616] = {category="lo"}, +[68617] = {category="lo"}, +[68618] = {category="lo"}, +[68619] = {category="lo"}, +[68620] = {category="lo"}, +[68621] = {category="lo"}, +[68622] = {category="lo"}, +[68623] = {category="lo"}, +[68624] = {category="lo"}, +[68625] = {category="lo"}, +[68626] = {category="lo"}, +[68627] = {category="lo"}, +[68628] = {category="lo"}, +[68629] = {category="lo"}, +[68630] = {category="lo"}, +[68631] = {category="lo"}, +[68632] = {category="lo"}, +[68633] = {category="lo"}, +[68634] = {category="lo"}, +[68635] = {category="lo"}, +[68636] = {category="lo"}, +[68637] = {category="lo"}, +[68638] = {category="lo"}, +[68639] = {category="lo"}, +[68640] = {category="lo"}, +[68641] = {category="lo"}, +[68642] = {category="lo"}, +[68643] = {category="lo"}, +[68644] = {category="lo"}, +[68645] = {category="lo"}, +[68646] = {category="lo"}, +[68647] = {category="lo"}, +[68648] = {category="lo"}, +[68649] = {category="lo"}, +[68650] = {category="lo"}, +[68651] = {category="lo"}, +[68652] = {category="lo"}, +[68653] = {category="lo"}, +[68654] = {category="lo"}, +[68655] = {category="lo"}, +[68656] = {category="lo"}, +[68657] = {category="lo"}, +[68658] = {category="lo"}, +[68659] = {category="lo"}, +[68660] = {category="lo"}, +[68661] = {category="lo"}, +[68662] = {category="lo"}, +[68663] = {category="lo"}, +[68664] = {category="lo"}, +[68665] = {category="lo"}, +[68666] = {category="lo"}, +[68667] = {category="lo"}, +[68668] = {category="lo"}, +[68669] = {category="lo"}, +[68670] = {category="lo"}, +[68671] = {category="lo"}, +[68672] = {category="lo"}, +[68673] = {category="lo"}, +[68674] = {category="lo"}, +[68675] = {category="lo"}, +[68676] = {category="lo"}, +[68677] = {category="lo"}, +[68678] = {category="lo"}, +[68679] = {category="lo"}, +[68680] = {category="lo"}, +[68736] = {category="lu", lccode=68800}, +[68737] = {category="lu", lccode=68801}, +[68738] = {category="lu", lccode=68802}, +[68739] = {category="lu", lccode=68803}, +[68740] = {category="lu", lccode=68804}, +[68741] = {category="lu", lccode=68805}, +[68742] = {category="lu", lccode=68806}, +[68743] = {category="lu", lccode=68807}, +[68744] = {category="lu", lccode=68808}, +[68745] = {category="lu", lccode=68809}, +[68746] = {category="lu", lccode=68810}, +[68747] = {category="lu", lccode=68811}, +[68748] = {category="lu", lccode=68812}, +[68749] = {category="lu", lccode=68813}, +[68750] = {category="lu", lccode=68814}, +[68751] = {category="lu", lccode=68815}, +[68752] = {category="lu", lccode=68816}, +[68753] = {category="lu", lccode=68817}, +[68754] = {category="lu", lccode=68818}, +[68755] = {category="lu", lccode=68819}, +[68756] = {category="lu", lccode=68820}, +[68757] = {category="lu", lccode=68821}, +[68758] = {category="lu", lccode=68822}, +[68759] = {category="lu", lccode=68823}, +[68760] = {category="lu", lccode=68824}, +[68761] = {category="lu", lccode=68825}, +[68762] = {category="lu", lccode=68826}, +[68763] = {category="lu", lccode=68827}, +[68764] = {category="lu", lccode=68828}, +[68765] = {category="lu", lccode=68829}, +[68766] = {category="lu", lccode=68830}, +[68767] = {category="lu", lccode=68831}, +[68768] = {category="lu", lccode=68832}, +[68769] = {category="lu", lccode=68833}, +[68770] = {category="lu", lccode=68834}, +[68771] = {category="lu", lccode=68835}, +[68772] = {category="lu", lccode=68836}, +[68773] = {category="lu", lccode=68837}, +[68774] = {category="lu", lccode=68838}, +[68775] = {category="lu", lccode=68839}, +[68776] = {category="lu", lccode=68840}, +[68777] = {category="lu", lccode=68841}, +[68778] = {category="lu", lccode=68842}, +[68779] = {category="lu", lccode=68843}, +[68780] = {category="lu", lccode=68844}, +[68781] = {category="lu", lccode=68845}, +[68782] = {category="lu", lccode=68846}, +[68783] = {category="lu", lccode=68847}, +[68784] = {category="lu", lccode=68848}, +[68785] = {category="lu", lccode=68849}, +[68786] = {category="lu", lccode=68850}, +[68800] = {category="ll"}, +[68801] = {category="ll"}, +[68802] = {category="ll"}, +[68803] = {category="ll"}, +[68804] = {category="ll"}, +[68805] = {category="ll"}, +[68806] = {category="ll"}, +[68807] = {category="ll"}, +[68808] = {category="ll"}, +[68809] = {category="ll"}, +[68810] = {category="ll"}, +[68811] = {category="ll"}, +[68812] = {category="ll"}, +[68813] = {category="ll"}, +[68814] = {category="ll"}, +[68815] = {category="ll"}, +[68816] = {category="ll"}, +[68817] = {category="ll"}, +[68818] = {category="ll"}, +[68819] = {category="ll"}, +[68820] = {category="ll"}, +[68821] = {category="ll"}, +[68822] = {category="ll"}, +[68823] = {category="ll"}, +[68824] = {category="ll"}, +[68825] = {category="ll"}, +[68826] = {category="ll"}, +[68827] = {category="ll"}, +[68828] = {category="ll"}, +[68829] = {category="ll"}, +[68830] = {category="ll"}, +[68831] = {category="ll"}, +[68832] = {category="ll"}, +[68833] = {category="ll"}, +[68834] = {category="ll"}, +[68835] = {category="ll"}, +[68836] = {category="ll"}, +[68837] = {category="ll"}, +[68838] = {category="ll"}, +[68839] = {category="ll"}, +[68840] = {category="ll"}, +[68841] = {category="ll"}, +[68842] = {category="ll"}, +[68843] = {category="ll"}, +[68844] = {category="ll"}, +[68845] = {category="ll"}, +[68846] = {category="ll"}, +[68847] = {category="ll"}, +[68848] = {category="ll"}, +[68849] = {category="ll"}, +[68850] = {category="ll"}, +[68864] = {category="lo"}, +[68865] = {category="lo"}, +[68866] = {category="lo"}, +[68867] = {category="lo"}, +[68868] = {category="lo"}, +[68869] = {category="lo"}, +[68870] = {category="lo"}, +[68871] = {category="lo"}, +[68872] = {category="lo"}, +[68873] = {category="lo"}, +[68874] = {category="lo"}, +[68875] = {category="lo"}, +[68876] = {category="lo"}, +[68877] = {category="lo"}, +[68878] = {category="lo"}, +[68879] = {category="lo"}, +[68880] = {category="lo"}, +[68881] = {category="lo"}, +[68882] = {category="lo"}, +[68883] = {category="lo"}, +[68884] = {category="lo"}, +[68885] = {category="lo"}, +[68886] = {category="lo"}, +[68887] = {category="lo"}, +[68888] = {category="lo"}, +[68889] = {category="lo"}, +[68890] = {category="lo"}, +[68891] = {category="lo"}, +[68892] = {category="lo"}, +[68893] = {category="lo"}, +[68894] = {category="lo"}, +[68895] = {category="lo"}, +[68896] = {category="lo"}, +[68897] = {category="lo"}, +[68898] = {category="lo"}, +[68899] = {category="lo"}, +[69248] = {category="lo"}, +[69249] = {category="lo"}, +[69250] = {category="lo"}, +[69251] = {category="lo"}, +[69252] = {category="lo"}, +[69253] = {category="lo"}, +[69254] = {category="lo"}, +[69255] = {category="lo"}, +[69256] = {category="lo"}, +[69257] = {category="lo"}, +[69258] = {category="lo"}, +[69259] = {category="lo"}, +[69260] = {category="lo"}, +[69261] = {category="lo"}, +[69262] = {category="lo"}, +[69263] = {category="lo"}, +[69264] = {category="lo"}, +[69265] = {category="lo"}, +[69266] = {category="lo"}, +[69267] = {category="lo"}, +[69268] = {category="lo"}, +[69269] = {category="lo"}, +[69270] = {category="lo"}, +[69271] = {category="lo"}, +[69272] = {category="lo"}, +[69273] = {category="lo"}, +[69274] = {category="lo"}, +[69275] = {category="lo"}, +[69276] = {category="lo"}, +[69277] = {category="lo"}, +[69278] = {category="lo"}, +[69279] = {category="lo"}, +[69280] = {category="lo"}, +[69281] = {category="lo"}, +[69282] = {category="lo"}, +[69283] = {category="lo"}, +[69284] = {category="lo"}, +[69285] = {category="lo"}, +[69286] = {category="lo"}, +[69287] = {category="lo"}, +[69288] = {category="lo"}, +[69289] = {category="lo"}, +[69296] = {category="lo"}, +[69297] = {category="lo"}, +[69376] = {category="lo"}, +[69377] = {category="lo"}, +[69378] = {category="lo"}, +[69379] = {category="lo"}, +[69380] = {category="lo"}, +[69381] = {category="lo"}, +[69382] = {category="lo"}, +[69383] = {category="lo"}, +[69384] = {category="lo"}, +[69385] = {category="lo"}, +[69386] = {category="lo"}, +[69387] = {category="lo"}, +[69388] = {category="lo"}, +[69389] = {category="lo"}, +[69390] = {category="lo"}, +[69391] = {category="lo"}, +[69392] = {category="lo"}, +[69393] = {category="lo"}, +[69394] = {category="lo"}, +[69395] = {category="lo"}, +[69396] = {category="lo"}, +[69397] = {category="lo"}, +[69398] = {category="lo"}, +[69399] = {category="lo"}, +[69400] = {category="lo"}, +[69401] = {category="lo"}, +[69402] = {category="lo"}, +[69403] = {category="lo"}, +[69404] = {category="lo"}, +[69415] = {category="lo"}, +[69424] = {category="lo"}, +[69425] = {category="lo"}, +[69426] = {category="lo"}, +[69427] = {category="lo"}, +[69428] = {category="lo"}, +[69429] = {category="lo"}, +[69430] = {category="lo"}, +[69431] = {category="lo"}, +[69432] = {category="lo"}, +[69433] = {category="lo"}, +[69434] = {category="lo"}, +[69435] = {category="lo"}, +[69436] = {category="lo"}, +[69437] = {category="lo"}, +[69438] = {category="lo"}, +[69439] = {category="lo"}, +[69440] = {category="lo"}, +[69441] = {category="lo"}, +[69442] = {category="lo"}, +[69443] = {category="lo"}, +[69444] = {category="lo"}, +[69445] = {category="lo"}, +[69488] = {category="lo"}, +[69489] = {category="lo"}, +[69490] = {category="lo"}, +[69491] = {category="lo"}, +[69492] = {category="lo"}, +[69493] = {category="lo"}, +[69494] = {category="lo"}, +[69495] = {category="lo"}, +[69496] = {category="lo"}, +[69497] = {category="lo"}, +[69498] = {category="lo"}, +[69499] = {category="lo"}, +[69500] = {category="lo"}, +[69501] = {category="lo"}, +[69502] = {category="lo"}, +[69503] = {category="lo"}, +[69504] = {category="lo"}, +[69505] = {category="lo"}, +[69552] = {category="lo"}, +[69553] = {category="lo"}, +[69554] = {category="lo"}, +[69555] = {category="lo"}, +[69556] = {category="lo"}, +[69557] = {category="lo"}, +[69558] = {category="lo"}, +[69559] = {category="lo"}, +[69560] = {category="lo"}, +[69561] = {category="lo"}, +[69562] = {category="lo"}, +[69563] = {category="lo"}, +[69564] = {category="lo"}, +[69565] = {category="lo"}, +[69566] = {category="lo"}, +[69567] = {category="lo"}, +[69568] = {category="lo"}, +[69569] = {category="lo"}, +[69570] = {category="lo"}, +[69571] = {category="lo"}, +[69572] = {category="lo"}, +[69600] = {category="lo"}, +[69601] = {category="lo"}, +[69602] = {category="lo"}, +[69603] = {category="lo"}, +[69604] = {category="lo"}, +[69605] = {category="lo"}, +[69606] = {category="lo"}, +[69607] = {category="lo"}, +[69608] = {category="lo"}, +[69609] = {category="lo"}, +[69610] = {category="lo"}, +[69611] = {category="lo"}, +[69612] = {category="lo"}, +[69613] = {category="lo"}, +[69614] = {category="lo"}, +[69615] = {category="lo"}, +[69616] = {category="lo"}, +[69617] = {category="lo"}, +[69618] = {category="lo"}, +[69619] = {category="lo"}, +[69620] = {category="lo"}, +[69621] = {category="lo"}, +[69622] = {category="lo"}, +[69635] = {category="lo"}, +[69636] = {category="lo"}, +[69637] = {category="lo"}, +[69638] = {category="lo"}, +[69639] = {category="lo"}, +[69640] = {category="lo"}, +[69641] = {category="lo"}, +[69642] = {category="lo"}, +[69643] = {category="lo"}, +[69644] = {category="lo"}, +[69645] = {category="lo"}, +[69646] = {category="lo"}, +[69647] = {category="lo"}, +[69648] = {category="lo"}, +[69649] = {category="lo"}, +[69650] = {category="lo"}, +[69651] = {category="lo"}, +[69652] = {category="lo"}, +[69653] = {category="lo"}, +[69654] = {category="lo"}, +[69655] = {category="lo"}, +[69656] = {category="lo"}, +[69657] = {category="lo"}, +[69658] = {category="lo"}, +[69659] = {category="lo"}, +[69660] = {category="lo"}, +[69661] = {category="lo"}, +[69662] = {category="lo"}, +[69663] = {category="lo"}, +[69664] = {category="lo"}, +[69665] = {category="lo"}, +[69666] = {category="lo"}, +[69667] = {category="lo"}, +[69668] = {category="lo"}, +[69669] = {category="lo"}, +[69670] = {category="lo"}, +[69671] = {category="lo"}, +[69672] = {category="lo"}, +[69673] = {category="lo"}, +[69674] = {category="lo"}, +[69675] = {category="lo"}, +[69676] = {category="lo"}, +[69677] = {category="lo"}, +[69678] = {category="lo"}, +[69679] = {category="lo"}, +[69680] = {category="lo"}, +[69681] = {category="lo"}, +[69682] = {category="lo"}, +[69683] = {category="lo"}, +[69684] = {category="lo"}, +[69685] = {category="lo"}, +[69686] = {category="lo"}, +[69687] = {category="lo"}, +[69745] = {category="lo"}, +[69746] = {category="lo"}, +[69749] = {category="lo"}, +[69763] = {category="lo"}, +[69764] = {category="lo"}, +[69765] = {category="lo"}, +[69766] = {category="lo"}, +[69767] = {category="lo"}, +[69768] = {category="lo"}, +[69769] = {category="lo"}, +[69770] = {category="lo"}, +[69771] = {category="lo"}, +[69772] = {category="lo"}, +[69773] = {category="lo"}, +[69774] = {category="lo"}, +[69775] = {category="lo"}, +[69776] = {category="lo"}, +[69777] = {category="lo"}, +[69778] = {category="lo"}, +[69779] = {category="lo"}, +[69780] = {category="lo"}, +[69781] = {category="lo"}, +[69782] = {category="lo"}, +[69783] = {category="lo"}, +[69784] = {category="lo"}, +[69785] = {category="lo"}, +[69786] = {category="lo", shcode=69785}, +[69787] = {category="lo"}, +[69788] = {category="lo", shcode=69787}, +[69789] = {category="lo"}, +[69790] = {category="lo"}, +[69791] = {category="lo"}, +[69792] = {category="lo"}, +[69793] = {category="lo"}, +[69794] = {category="lo"}, +[69795] = {category="lo"}, +[69796] = {category="lo"}, +[69797] = {category="lo"}, +[69798] = {category="lo"}, +[69799] = {category="lo"}, +[69800] = {category="lo"}, +[69801] = {category="lo"}, +[69802] = {category="lo"}, +[69803] = {category="lo", shcode=69797}, +[69804] = {category="lo"}, +[69805] = {category="lo"}, +[69806] = {category="lo"}, +[69807] = {category="lo"}, +[69840] = {category="lo"}, +[69841] = {category="lo"}, +[69842] = {category="lo"}, +[69843] = {category="lo"}, +[69844] = {category="lo"}, +[69845] = {category="lo"}, +[69846] = {category="lo"}, +[69847] = {category="lo"}, +[69848] = {category="lo"}, +[69849] = {category="lo"}, +[69850] = {category="lo"}, +[69851] = {category="lo"}, +[69852] = {category="lo"}, +[69853] = {category="lo"}, +[69854] = {category="lo"}, +[69855] = {category="lo"}, +[69856] = {category="lo"}, +[69857] = {category="lo"}, +[69858] = {category="lo"}, +[69859] = {category="lo"}, +[69860] = {category="lo"}, +[69861] = {category="lo"}, +[69862] = {category="lo"}, +[69863] = {category="lo"}, +[69864] = {category="lo"}, +[69891] = {category="lo"}, +[69892] = {category="lo"}, +[69893] = {category="lo"}, +[69894] = {category="lo"}, +[69895] = {category="lo"}, +[69896] = {category="lo"}, +[69897] = {category="lo"}, +[69898] = {category="lo"}, +[69899] = {category="lo"}, +[69900] = {category="lo"}, +[69901] = {category="lo"}, +[69902] = {category="lo"}, +[69903] = {category="lo"}, +[69904] = {category="lo"}, +[69905] = {category="lo"}, +[69906] = {category="lo"}, +[69907] = {category="lo"}, +[69908] = {category="lo"}, +[69909] = {category="lo"}, +[69910] = {category="lo"}, +[69911] = {category="lo"}, +[69912] = {category="lo"}, +[69913] = {category="lo"}, +[69914] = {category="lo"}, +[69915] = {category="lo"}, +[69916] = {category="lo"}, +[69917] = {category="lo"}, +[69918] = {category="lo"}, +[69919] = {category="lo"}, +[69920] = {category="lo"}, +[69921] = {category="lo"}, +[69922] = {category="lo"}, +[69923] = {category="lo"}, +[69924] = {category="lo"}, +[69925] = {category="lo"}, +[69926] = {category="lo"}, +[69956] = {category="lo"}, +[69959] = {category="lo"}, +[69968] = {category="lo"}, +[69969] = {category="lo"}, +[69970] = {category="lo"}, +[69971] = {category="lo"}, +[69972] = {category="lo"}, +[69973] = {category="lo"}, +[69974] = {category="lo"}, +[69975] = {category="lo"}, +[69976] = {category="lo"}, +[69977] = {category="lo"}, +[69978] = {category="lo"}, +[69979] = {category="lo"}, +[69980] = {category="lo"}, +[69981] = {category="lo"}, +[69982] = {category="lo"}, +[69983] = {category="lo"}, +[69984] = {category="lo"}, +[69985] = {category="lo"}, +[69986] = {category="lo"}, +[69987] = {category="lo"}, +[69988] = {category="lo"}, +[69989] = {category="lo"}, +[69990] = {category="lo"}, +[69991] = {category="lo"}, +[69992] = {category="lo"}, +[69993] = {category="lo"}, +[69994] = {category="lo"}, +[69995] = {category="lo"}, +[69996] = {category="lo"}, +[69997] = {category="lo"}, +[69998] = {category="lo"}, +[69999] = {category="lo"}, +[70000] = {category="lo"}, +[70001] = {category="lo"}, +[70002] = {category="lo"}, +[70006] = {category="lo"}, +[70019] = {category="lo"}, +[70020] = {category="lo"}, +[70021] = {category="lo"}, +[70022] = {category="lo"}, +[70023] = {category="lo"}, +[70024] = {category="lo"}, +[70025] = {category="lo"}, +[70026] = {category="lo"}, +[70027] = {category="lo"}, +[70028] = {category="lo"}, +[70029] = {category="lo"}, +[70030] = {category="lo"}, +[70031] = {category="lo"}, +[70032] = {category="lo"}, +[70033] = {category="lo"}, +[70034] = {category="lo"}, +[70035] = {category="lo"}, +[70036] = {category="lo"}, +[70037] = {category="lo"}, +[70038] = {category="lo"}, +[70039] = {category="lo"}, +[70040] = {category="lo"}, +[70041] = {category="lo"}, +[70042] = {category="lo"}, +[70043] = {category="lo"}, +[70044] = {category="lo"}, +[70045] = {category="lo"}, +[70046] = {category="lo"}, +[70047] = {category="lo"}, +[70048] = {category="lo"}, +[70049] = {category="lo"}, +[70050] = {category="lo"}, +[70051] = {category="lo"}, +[70052] = {category="lo"}, +[70053] = {category="lo"}, +[70054] = {category="lo"}, +[70055] = {category="lo"}, +[70056] = {category="lo"}, +[70057] = {category="lo"}, +[70058] = {category="lo"}, +[70059] = {category="lo"}, +[70060] = {category="lo"}, +[70061] = {category="lo"}, +[70062] = {category="lo"}, +[70063] = {category="lo"}, +[70064] = {category="lo"}, +[70065] = {category="lo"}, +[70066] = {category="lo"}, +[70081] = {category="lo"}, +[70082] = {category="lo"}, +[70083] = {category="lo"}, +[70084] = {category="lo"}, +[70106] = {category="lo"}, +[70108] = {category="lo"}, +[70144] = {category="lo"}, +[70145] = {category="lo"}, +[70146] = {category="lo"}, +[70147] = {category="lo"}, +[70148] = {category="lo"}, +[70149] = {category="lo"}, +[70150] = {category="lo"}, +[70151] = {category="lo"}, +[70152] = {category="lo"}, +[70153] = {category="lo"}, +[70154] = {category="lo"}, +[70155] = {category="lo"}, +[70156] = {category="lo"}, +[70157] = {category="lo"}, +[70158] = {category="lo"}, +[70159] = {category="lo"}, +[70160] = {category="lo"}, +[70161] = {category="lo"}, +[70163] = {category="lo"}, +[70164] = {category="lo"}, +[70165] = {category="lo"}, +[70166] = {category="lo"}, +[70167] = {category="lo"}, +[70168] = {category="lo"}, +[70169] = {category="lo"}, +[70170] = {category="lo"}, +[70171] = {category="lo"}, +[70172] = {category="lo"}, +[70173] = {category="lo"}, +[70174] = {category="lo"}, +[70175] = {category="lo"}, +[70176] = {category="lo"}, +[70177] = {category="lo"}, +[70178] = {category="lo"}, +[70179] = {category="lo"}, +[70180] = {category="lo"}, +[70181] = {category="lo"}, +[70182] = {category="lo"}, +[70183] = {category="lo"}, +[70184] = {category="lo"}, +[70185] = {category="lo"}, +[70186] = {category="lo"}, +[70187] = {category="lo"}, +[70207] = {category="lo"}, +[70208] = {category="lo"}, +[70272] = {category="lo"}, +[70273] = {category="lo"}, +[70274] = {category="lo"}, +[70275] = {category="lo"}, +[70276] = {category="lo"}, +[70277] = {category="lo"}, +[70278] = {category="lo"}, +[70280] = {category="lo"}, +[70282] = {category="lo"}, +[70283] = {category="lo"}, +[70284] = {category="lo"}, +[70285] = {category="lo"}, +[70287] = {category="lo"}, +[70288] = {category="lo"}, +[70289] = {category="lo"}, +[70290] = {category="lo"}, +[70291] = {category="lo"}, +[70292] = {category="lo"}, +[70293] = {category="lo"}, +[70294] = {category="lo"}, +[70295] = {category="lo"}, +[70296] = {category="lo"}, +[70297] = {category="lo"}, +[70298] = {category="lo"}, +[70299] = {category="lo"}, +[70300] = {category="lo"}, +[70301] = {category="lo"}, +[70303] = {category="lo"}, +[70304] = {category="lo"}, +[70305] = {category="lo"}, +[70306] = {category="lo"}, +[70307] = {category="lo"}, +[70308] = {category="lo"}, +[70309] = {category="lo"}, +[70310] = {category="lo"}, +[70311] = {category="lo"}, +[70312] = {category="lo"}, +[70320] = {category="lo"}, +[70321] = {category="lo"}, +[70322] = {category="lo"}, +[70323] = {category="lo"}, +[70324] = {category="lo"}, +[70325] = {category="lo"}, +[70326] = {category="lo"}, +[70327] = {category="lo"}, +[70328] = {category="lo"}, +[70329] = {category="lo"}, +[70330] = {category="lo"}, +[70331] = {category="lo"}, +[70332] = {category="lo"}, +[70333] = {category="lo"}, +[70334] = {category="lo"}, +[70335] = {category="lo"}, +[70336] = {category="lo"}, +[70337] = {category="lo"}, +[70338] = {category="lo"}, +[70339] = {category="lo"}, +[70340] = {category="lo"}, +[70341] = {category="lo"}, +[70342] = {category="lo"}, +[70343] = {category="lo"}, +[70344] = {category="lo"}, +[70345] = {category="lo"}, +[70346] = {category="lo"}, +[70347] = {category="lo"}, +[70348] = {category="lo"}, +[70349] = {category="lo"}, +[70350] = {category="lo"}, +[70351] = {category="lo"}, +[70352] = {category="lo"}, +[70353] = {category="lo"}, +[70354] = {category="lo"}, +[70355] = {category="lo"}, +[70356] = {category="lo"}, +[70357] = {category="lo"}, +[70358] = {category="lo"}, +[70359] = {category="lo"}, +[70360] = {category="lo"}, +[70361] = {category="lo"}, +[70362] = {category="lo"}, +[70363] = {category="lo"}, +[70364] = {category="lo"}, +[70365] = {category="lo"}, +[70366] = {category="lo"}, +[70405] = {category="lo"}, +[70406] = {category="lo"}, +[70407] = {category="lo"}, +[70408] = {category="lo"}, +[70409] = {category="lo"}, +[70410] = {category="lo"}, +[70411] = {category="lo"}, +[70412] = {category="lo"}, +[70415] = {category="lo"}, +[70416] = {category="lo"}, +[70419] = {category="lo"}, +[70420] = {category="lo"}, +[70421] = {category="lo"}, +[70422] = {category="lo"}, +[70423] = {category="lo"}, +[70424] = {category="lo"}, +[70425] = {category="lo"}, +[70426] = {category="lo"}, +[70427] = {category="lo"}, +[70428] = {category="lo"}, +[70429] = {category="lo"}, +[70430] = {category="lo"}, +[70431] = {category="lo"}, +[70432] = {category="lo"}, +[70433] = {category="lo"}, +[70434] = {category="lo"}, +[70435] = {category="lo"}, +[70436] = {category="lo"}, +[70437] = {category="lo"}, +[70438] = {category="lo"}, +[70439] = {category="lo"}, +[70440] = {category="lo"}, +[70442] = {category="lo"}, +[70443] = {category="lo"}, +[70444] = {category="lo"}, +[70445] = {category="lo"}, +[70446] = {category="lo"}, +[70447] = {category="lo"}, +[70448] = {category="lo"}, +[70450] = {category="lo"}, +[70451] = {category="lo"}, +[70453] = {category="lo"}, +[70454] = {category="lo"}, +[70455] = {category="lo"}, +[70456] = {category="lo"}, +[70457] = {category="lo"}, +[70461] = {category="lo"}, +[70480] = {category="lo"}, +[70493] = {category="lo"}, +[70494] = {category="lo"}, +[70495] = {category="lo"}, +[70496] = {category="lo"}, +[70497] = {category="lo"}, +[70656] = {category="lo"}, +[70657] = {category="lo"}, +[70658] = {category="lo"}, +[70659] = {category="lo"}, +[70660] = {category="lo"}, +[70661] = {category="lo"}, +[70662] = {category="lo"}, +[70663] = {category="lo"}, +[70664] = {category="lo"}, +[70665] = {category="lo"}, +[70666] = {category="lo"}, +[70667] = {category="lo"}, +[70668] = {category="lo"}, +[70669] = {category="lo"}, +[70670] = {category="lo"}, +[70671] = {category="lo"}, +[70672] = {category="lo"}, +[70673] = {category="lo"}, +[70674] = {category="lo"}, +[70675] = {category="lo"}, +[70676] = {category="lo"}, +[70677] = {category="lo"}, +[70678] = {category="lo"}, +[70679] = {category="lo"}, +[70680] = {category="lo"}, +[70681] = {category="lo"}, +[70682] = {category="lo"}, +[70683] = {category="lo"}, +[70684] = {category="lo"}, +[70685] = {category="lo"}, +[70686] = {category="lo"}, +[70687] = {category="lo"}, +[70688] = {category="lo"}, +[70689] = {category="lo"}, +[70690] = {category="lo"}, +[70691] = {category="lo"}, +[70692] = {category="lo"}, +[70693] = {category="lo"}, +[70694] = {category="lo"}, +[70695] = {category="lo"}, +[70696] = {category="lo"}, +[70697] = {category="lo"}, +[70698] = {category="lo"}, +[70699] = {category="lo"}, +[70700] = {category="lo"}, +[70701] = {category="lo"}, +[70702] = {category="lo"}, +[70703] = {category="lo"}, +[70704] = {category="lo"}, +[70705] = {category="lo"}, +[70706] = {category="lo"}, +[70707] = {category="lo"}, +[70708] = {category="lo"}, +[70727] = {category="lo"}, +[70728] = {category="lo"}, +[70729] = {category="lo"}, +[70730] = {category="lo"}, +[70751] = {category="lo"}, +[70752] = {category="lo"}, +[70753] = {category="lo"}, +[70784] = {category="lo"}, +[70785] = {category="lo"}, +[70786] = {category="lo"}, +[70787] = {category="lo"}, +[70788] = {category="lo"}, +[70789] = {category="lo"}, +[70790] = {category="lo"}, +[70791] = {category="lo"}, +[70792] = {category="lo"}, +[70793] = {category="lo"}, +[70794] = {category="lo"}, +[70795] = {category="lo"}, +[70796] = {category="lo"}, +[70797] = {category="lo"}, +[70798] = {category="lo"}, +[70799] = {category="lo"}, +[70800] = {category="lo"}, +[70801] = {category="lo"}, +[70802] = {category="lo"}, +[70803] = {category="lo"}, +[70804] = {category="lo"}, +[70805] = {category="lo"}, +[70806] = {category="lo"}, +[70807] = {category="lo"}, +[70808] = {category="lo"}, +[70809] = {category="lo"}, +[70810] = {category="lo"}, +[70811] = {category="lo"}, +[70812] = {category="lo"}, +[70813] = {category="lo"}, +[70814] = {category="lo"}, +[70815] = {category="lo"}, +[70816] = {category="lo"}, +[70817] = {category="lo"}, +[70818] = {category="lo"}, +[70819] = {category="lo"}, +[70820] = {category="lo"}, +[70821] = {category="lo"}, +[70822] = {category="lo"}, +[70823] = {category="lo"}, +[70824] = {category="lo"}, +[70825] = {category="lo"}, +[70826] = {category="lo"}, +[70827] = {category="lo"}, +[70828] = {category="lo"}, +[70829] = {category="lo"}, +[70830] = {category="lo"}, +[70831] = {category="lo"}, +[70852] = {category="lo"}, +[70853] = {category="lo"}, +[70855] = {category="lo"}, +[71040] = {category="lo"}, +[71041] = {category="lo"}, +[71042] = {category="lo"}, +[71043] = {category="lo"}, +[71044] = {category="lo"}, +[71045] = {category="lo"}, +[71046] = {category="lo"}, +[71047] = {category="lo"}, +[71048] = {category="lo"}, +[71049] = {category="lo"}, +[71050] = {category="lo"}, +[71051] = {category="lo"}, +[71052] = {category="lo"}, +[71053] = {category="lo"}, +[71054] = {category="lo"}, +[71055] = {category="lo"}, +[71056] = {category="lo"}, +[71057] = {category="lo"}, +[71058] = {category="lo"}, +[71059] = {category="lo"}, +[71060] = {category="lo"}, +[71061] = {category="lo"}, +[71062] = {category="lo"}, +[71063] = {category="lo"}, +[71064] = {category="lo"}, +[71065] = {category="lo"}, +[71066] = {category="lo"}, +[71067] = {category="lo"}, +[71068] = {category="lo"}, +[71069] = {category="lo"}, +[71070] = {category="lo"}, +[71071] = {category="lo"}, +[71072] = {category="lo"}, +[71073] = {category="lo"}, +[71074] = {category="lo"}, +[71075] = {category="lo"}, +[71076] = {category="lo"}, +[71077] = {category="lo"}, +[71078] = {category="lo"}, +[71079] = {category="lo"}, +[71080] = {category="lo"}, +[71081] = {category="lo"}, +[71082] = {category="lo"}, +[71083] = {category="lo"}, +[71084] = {category="lo"}, +[71085] = {category="lo"}, +[71086] = {category="lo"}, +[71128] = {category="lo"}, +[71129] = {category="lo"}, +[71130] = {category="lo"}, +[71131] = {category="lo"}, +[71168] = {category="lo"}, +[71169] = {category="lo"}, +[71170] = {category="lo"}, +[71171] = {category="lo"}, +[71172] = {category="lo"}, +[71173] = {category="lo"}, +[71174] = {category="lo"}, +[71175] = {category="lo"}, +[71176] = {category="lo"}, +[71177] = {category="lo"}, +[71178] = {category="lo"}, +[71179] = {category="lo"}, +[71180] = {category="lo"}, +[71181] = {category="lo"}, +[71182] = {category="lo"}, +[71183] = {category="lo"}, +[71184] = {category="lo"}, +[71185] = {category="lo"}, +[71186] = {category="lo"}, +[71187] = {category="lo"}, +[71188] = {category="lo"}, +[71189] = {category="lo"}, +[71190] = {category="lo"}, +[71191] = {category="lo"}, +[71192] = {category="lo"}, +[71193] = {category="lo"}, +[71194] = {category="lo"}, +[71195] = {category="lo"}, +[71196] = {category="lo"}, +[71197] = {category="lo"}, +[71198] = {category="lo"}, +[71199] = {category="lo"}, +[71200] = {category="lo"}, +[71201] = {category="lo"}, +[71202] = {category="lo"}, +[71203] = {category="lo"}, +[71204] = {category="lo"}, +[71205] = {category="lo"}, +[71206] = {category="lo"}, +[71207] = {category="lo"}, +[71208] = {category="lo"}, +[71209] = {category="lo"}, +[71210] = {category="lo"}, +[71211] = {category="lo"}, +[71212] = {category="lo"}, +[71213] = {category="lo"}, +[71214] = {category="lo"}, +[71215] = {category="lo"}, +[71236] = {category="lo"}, +[71296] = {category="lo"}, +[71297] = {category="lo"}, +[71298] = {category="lo"}, +[71299] = {category="lo"}, +[71300] = {category="lo"}, +[71301] = {category="lo"}, +[71302] = {category="lo"}, +[71303] = {category="lo"}, +[71304] = {category="lo"}, +[71305] = {category="lo"}, +[71306] = {category="lo"}, +[71307] = {category="lo"}, +[71308] = {category="lo"}, +[71309] = {category="lo"}, +[71310] = {category="lo"}, +[71311] = {category="lo"}, +[71312] = {category="lo"}, +[71313] = {category="lo"}, +[71314] = {category="lo"}, +[71315] = {category="lo"}, +[71316] = {category="lo"}, +[71317] = {category="lo"}, +[71318] = {category="lo"}, +[71319] = {category="lo"}, +[71320] = {category="lo"}, +[71321] = {category="lo"}, +[71322] = {category="lo"}, +[71323] = {category="lo"}, +[71324] = {category="lo"}, +[71325] = {category="lo"}, +[71326] = {category="lo"}, +[71327] = {category="lo"}, +[71328] = {category="lo"}, +[71329] = {category="lo"}, +[71330] = {category="lo"}, +[71331] = {category="lo"}, +[71332] = {category="lo"}, +[71333] = {category="lo"}, +[71334] = {category="lo"}, +[71335] = {category="lo"}, +[71336] = {category="lo"}, +[71337] = {category="lo"}, +[71338] = {category="lo"}, +[71352] = {category="lo"}, +[71424] = {category="lo"}, +[71425] = {category="lo"}, +[71426] = {category="lo"}, +[71427] = {category="lo"}, +[71428] = {category="lo"}, +[71429] = {category="lo"}, +[71430] = {category="lo"}, +[71431] = {category="lo"}, +[71432] = {category="lo"}, +[71433] = {category="lo"}, +[71434] = {category="lo"}, +[71435] = {category="lo"}, +[71436] = {category="lo"}, +[71437] = {category="lo"}, +[71438] = {category="lo"}, +[71439] = {category="lo"}, +[71440] = {category="lo"}, +[71441] = {category="lo"}, +[71442] = {category="lo"}, +[71443] = {category="lo"}, +[71444] = {category="lo"}, +[71445] = {category="lo"}, +[71446] = {category="lo"}, +[71447] = {category="lo"}, +[71448] = {category="lo"}, +[71449] = {category="lo"}, +[71450] = {category="lo"}, +[71488] = {category="lo"}, +[71489] = {category="lo"}, +[71490] = {category="lo"}, +[71491] = {category="lo"}, +[71492] = {category="lo"}, +[71493] = {category="lo"}, +[71494] = {category="lo"}, +[71680] = {category="lo"}, +[71681] = {category="lo"}, +[71682] = {category="lo"}, +[71683] = {category="lo"}, +[71684] = {category="lo"}, +[71685] = {category="lo"}, +[71686] = {category="lo"}, +[71687] = {category="lo"}, +[71688] = {category="lo"}, +[71689] = {category="lo"}, +[71690] = {category="lo"}, +[71691] = {category="lo"}, +[71692] = {category="lo"}, +[71693] = {category="lo"}, +[71694] = {category="lo"}, +[71695] = {category="lo"}, +[71696] = {category="lo"}, +[71697] = {category="lo"}, +[71698] = {category="lo"}, +[71699] = {category="lo"}, +[71700] = {category="lo"}, +[71701] = {category="lo"}, +[71702] = {category="lo"}, +[71703] = {category="lo"}, +[71704] = {category="lo"}, +[71705] = {category="lo"}, +[71706] = {category="lo"}, +[71707] = {category="lo"}, +[71708] = {category="lo"}, +[71709] = {category="lo"}, +[71710] = {category="lo"}, +[71711] = {category="lo"}, +[71712] = {category="lo"}, +[71713] = {category="lo"}, +[71714] = {category="lo"}, +[71715] = {category="lo"}, +[71716] = {category="lo"}, +[71717] = {category="lo"}, +[71718] = {category="lo"}, +[71719] = {category="lo"}, +[71720] = {category="lo"}, +[71721] = {category="lo"}, +[71722] = {category="lo"}, +[71723] = {category="lo"}, +[71840] = {category="lu", lccode=71872}, +[71841] = {category="lu", lccode=71873}, +[71842] = {category="lu", lccode=71874}, +[71843] = {category="lu", lccode=71875}, +[71844] = {category="lu", lccode=71876}, +[71845] = {category="lu", lccode=71877}, +[71846] = {category="lu", lccode=71878}, +[71847] = {category="lu", lccode=71879}, +[71848] = {category="lu", lccode=71880}, +[71849] = {category="lu", lccode=71881}, +[71850] = {category="lu", lccode=71882}, +[71851] = {category="lu", lccode=71883}, +[71852] = {category="lu", lccode=71884}, +[71853] = {category="lu", lccode=71885}, +[71854] = {category="lu", lccode=71886}, +[71855] = {category="lu", lccode=71887}, +[71856] = {category="lu", lccode=71888}, +[71857] = {category="lu", lccode=71889}, +[71858] = {category="lu", lccode=71890}, +[71859] = {category="lu", lccode=71891}, +[71860] = {category="lu", lccode=71892}, +[71861] = {category="lu", lccode=71893}, +[71862] = {category="lu", lccode=71894}, +[71863] = {category="lu", lccode=71895}, +[71864] = {category="lu", lccode=71896}, +[71865] = {category="lu", lccode=71897}, +[71866] = {category="lu", lccode=71898}, +[71867] = {category="lu", lccode=71899}, +[71868] = {category="lu", lccode=71900}, +[71869] = {category="lu", lccode=71901}, +[71870] = {category="lu", lccode=71902}, +[71871] = {category="lu", lccode=71903}, +[71872] = {category="ll"}, +[71873] = {category="ll"}, +[71874] = {category="ll"}, +[71875] = {category="ll"}, +[71876] = {category="ll"}, +[71877] = {category="ll"}, +[71878] = {category="ll"}, +[71879] = {category="ll"}, +[71880] = {category="ll"}, +[71881] = {category="ll"}, +[71882] = {category="ll"}, +[71883] = {category="ll"}, +[71884] = {category="ll"}, +[71885] = {category="ll"}, +[71886] = {category="ll"}, +[71887] = {category="ll"}, +[71888] = {category="ll"}, +[71889] = {category="ll"}, +[71890] = {category="ll"}, +[71891] = {category="ll"}, +[71892] = {category="ll"}, +[71893] = {category="ll"}, +[71894] = {category="ll"}, +[71895] = {category="ll"}, +[71896] = {category="ll"}, +[71897] = {category="ll"}, +[71898] = {category="ll"}, +[71899] = {category="ll"}, +[71900] = {category="ll"}, +[71901] = {category="ll"}, +[71902] = {category="ll"}, +[71903] = {category="ll"}, +[71935] = {category="lo"}, +[71936] = {category="lo"}, +[71937] = {category="lo"}, +[71938] = {category="lo"}, +[71939] = {category="lo"}, +[71940] = {category="lo"}, +[71941] = {category="lo"}, +[71942] = {category="lo"}, +[71945] = {category="lo"}, +[71948] = {category="lo"}, +[71949] = {category="lo"}, +[71950] = {category="lo"}, +[71951] = {category="lo"}, +[71952] = {category="lo"}, +[71953] = {category="lo"}, +[71954] = {category="lo"}, +[71955] = {category="lo"}, +[71957] = {category="lo"}, +[71958] = {category="lo"}, +[71960] = {category="lo"}, +[71961] = {category="lo"}, +[71962] = {category="lo"}, +[71963] = {category="lo"}, +[71964] = {category="lo"}, +[71965] = {category="lo"}, +[71966] = {category="lo"}, +[71967] = {category="lo"}, +[71968] = {category="lo"}, +[71969] = {category="lo"}, +[71970] = {category="lo"}, +[71971] = {category="lo"}, +[71972] = {category="lo"}, +[71973] = {category="lo"}, +[71974] = {category="lo"}, +[71975] = {category="lo"}, +[71976] = {category="lo"}, +[71977] = {category="lo"}, +[71978] = {category="lo"}, +[71979] = {category="lo"}, +[71980] = {category="lo"}, +[71981] = {category="lo"}, +[71982] = {category="lo"}, +[71983] = {category="lo"}, +[71999] = {category="lo"}, +[72001] = {category="lo"}, +[72096] = {category="lo"}, +[72097] = {category="lo"}, +[72098] = {category="lo"}, +[72099] = {category="lo"}, +[72100] = {category="lo"}, +[72101] = {category="lo"}, +[72102] = {category="lo"}, +[72103] = {category="lo"}, +[72106] = {category="lo"}, +[72107] = {category="lo"}, +[72108] = {category="lo"}, +[72109] = {category="lo"}, +[72110] = {category="lo"}, +[72111] = {category="lo"}, +[72112] = {category="lo"}, +[72113] = {category="lo"}, +[72114] = {category="lo"}, +[72115] = {category="lo"}, +[72116] = {category="lo"}, +[72117] = {category="lo"}, +[72118] = {category="lo"}, +[72119] = {category="lo"}, +[72120] = {category="lo"}, +[72121] = {category="lo"}, +[72122] = {category="lo"}, +[72123] = {category="lo"}, +[72124] = {category="lo"}, +[72125] = {category="lo"}, +[72126] = {category="lo"}, +[72127] = {category="lo"}, +[72128] = {category="lo"}, +[72129] = {category="lo"}, +[72130] = {category="lo"}, +[72131] = {category="lo"}, +[72132] = {category="lo"}, +[72133] = {category="lo"}, +[72134] = {category="lo"}, +[72135] = {category="lo"}, +[72136] = {category="lo"}, +[72137] = {category="lo"}, +[72138] = {category="lo"}, +[72139] = {category="lo"}, +[72140] = {category="lo"}, +[72141] = {category="lo"}, +[72142] = {category="lo"}, +[72143] = {category="lo"}, +[72144] = {category="lo"}, +[72161] = {category="lo"}, +[72163] = {category="lo"}, +[72192] = {category="lo"}, +[72203] = {category="lo"}, +[72204] = {category="lo"}, +[72205] = {category="lo"}, +[72206] = {category="lo"}, +[72207] = {category="lo"}, +[72208] = {category="lo"}, +[72209] = {category="lo"}, +[72210] = {category="lo"}, +[72211] = {category="lo"}, +[72212] = {category="lo"}, +[72213] = {category="lo"}, +[72214] = {category="lo"}, +[72215] = {category="lo"}, +[72216] = {category="lo"}, +[72217] = {category="lo"}, +[72218] = {category="lo"}, +[72219] = {category="lo"}, +[72220] = {category="lo"}, +[72221] = {category="lo"}, +[72222] = {category="lo"}, +[72223] = {category="lo"}, +[72224] = {category="lo"}, +[72225] = {category="lo"}, +[72226] = {category="lo"}, +[72227] = {category="lo"}, +[72228] = {category="lo"}, +[72229] = {category="lo"}, +[72230] = {category="lo"}, +[72231] = {category="lo"}, +[72232] = {category="lo"}, +[72233] = {category="lo"}, +[72234] = {category="lo"}, +[72235] = {category="lo"}, +[72236] = {category="lo"}, +[72237] = {category="lo"}, +[72238] = {category="lo"}, +[72239] = {category="lo"}, +[72240] = {category="lo"}, +[72241] = {category="lo"}, +[72242] = {category="lo"}, +[72250] = {category="lo"}, +[72272] = {category="lo"}, +[72284] = {category="lo"}, +[72285] = {category="lo"}, +[72286] = {category="lo"}, +[72287] = {category="lo"}, +[72288] = {category="lo"}, +[72289] = {category="lo"}, +[72290] = {category="lo"}, +[72291] = {category="lo"}, +[72292] = {category="lo"}, +[72293] = {category="lo"}, +[72294] = {category="lo"}, +[72295] = {category="lo"}, +[72296] = {category="lo"}, +[72297] = {category="lo"}, +[72298] = {category="lo"}, +[72299] = {category="lo"}, +[72300] = {category="lo"}, +[72301] = {category="lo"}, +[72302] = {category="lo"}, +[72303] = {category="lo"}, +[72304] = {category="lo"}, +[72305] = {category="lo"}, +[72306] = {category="lo"}, +[72307] = {category="lo"}, +[72308] = {category="lo"}, +[72309] = {category="lo"}, +[72310] = {category="lo"}, +[72311] = {category="lo"}, +[72312] = {category="lo"}, +[72313] = {category="lo"}, +[72314] = {category="lo"}, +[72315] = {category="lo"}, +[72316] = {category="lo"}, +[72317] = {category="lo"}, +[72318] = {category="lo"}, +[72319] = {category="lo"}, +[72320] = {category="lo"}, +[72321] = {category="lo"}, +[72322] = {category="lo"}, +[72323] = {category="lo"}, +[72324] = {category="lo"}, +[72325] = {category="lo"}, +[72326] = {category="lo"}, +[72327] = {category="lo"}, +[72328] = {category="lo"}, +[72329] = {category="lo"}, +[72349] = {category="lo"}, +[72368] = {category="lo"}, +[72369] = {category="lo"}, +[72370] = {category="lo"}, +[72371] = {category="lo"}, +[72372] = {category="lo"}, +[72373] = {category="lo"}, +[72374] = {category="lo"}, +[72375] = {category="lo"}, +[72376] = {category="lo"}, +[72377] = {category="lo"}, +[72378] = {category="lo"}, +[72379] = {category="lo"}, +[72380] = {category="lo"}, +[72381] = {category="lo"}, +[72382] = {category="lo"}, +[72383] = {category="lo"}, +[72384] = {category="lo"}, +[72385] = {category="lo"}, +[72386] = {category="lo"}, +[72387] = {category="lo"}, +[72388] = {category="lo"}, +[72389] = {category="lo"}, +[72390] = {category="lo"}, +[72391] = {category="lo"}, +[72392] = {category="lo"}, +[72393] = {category="lo"}, +[72394] = {category="lo"}, +[72395] = {category="lo"}, +[72396] = {category="lo"}, +[72397] = {category="lo"}, +[72398] = {category="lo"}, +[72399] = {category="lo"}, +[72400] = {category="lo"}, +[72401] = {category="lo"}, +[72402] = {category="lo"}, +[72403] = {category="lo"}, +[72404] = {category="lo"}, +[72405] = {category="lo"}, +[72406] = {category="lo"}, +[72407] = {category="lo"}, +[72408] = {category="lo"}, +[72409] = {category="lo"}, +[72410] = {category="lo"}, +[72411] = {category="lo"}, +[72412] = {category="lo"}, +[72413] = {category="lo"}, +[72414] = {category="lo"}, +[72415] = {category="lo"}, +[72416] = {category="lo"}, +[72417] = {category="lo"}, +[72418] = {category="lo"}, +[72419] = {category="lo"}, +[72420] = {category="lo"}, +[72421] = {category="lo"}, +[72422] = {category="lo"}, +[72423] = {category="lo"}, +[72424] = {category="lo"}, +[72425] = {category="lo"}, +[72426] = {category="lo"}, +[72427] = {category="lo"}, +[72428] = {category="lo"}, +[72429] = {category="lo"}, +[72430] = {category="lo"}, +[72431] = {category="lo"}, +[72432] = {category="lo"}, +[72433] = {category="lo"}, +[72434] = {category="lo"}, +[72435] = {category="lo"}, +[72436] = {category="lo"}, +[72437] = {category="lo"}, +[72438] = {category="lo"}, +[72439] = {category="lo"}, +[72440] = {category="lo"}, +[72704] = {category="lo"}, +[72705] = {category="lo"}, +[72706] = {category="lo"}, +[72707] = {category="lo"}, +[72708] = {category="lo"}, +[72709] = {category="lo"}, +[72710] = {category="lo"}, +[72711] = {category="lo"}, +[72712] = {category="lo"}, +[72714] = {category="lo"}, +[72715] = {category="lo"}, +[72716] = {category="lo"}, +[72717] = {category="lo"}, +[72718] = {category="lo"}, +[72719] = {category="lo"}, +[72720] = {category="lo"}, +[72721] = {category="lo"}, +[72722] = {category="lo"}, +[72723] = {category="lo"}, +[72724] = {category="lo"}, +[72725] = {category="lo"}, +[72726] = {category="lo"}, +[72727] = {category="lo"}, +[72728] = {category="lo"}, +[72729] = {category="lo"}, +[72730] = {category="lo"}, +[72731] = {category="lo"}, +[72732] = {category="lo"}, +[72733] = {category="lo"}, +[72734] = {category="lo"}, +[72735] = {category="lo"}, +[72736] = {category="lo"}, +[72737] = {category="lo"}, +[72738] = {category="lo"}, +[72739] = {category="lo"}, +[72740] = {category="lo"}, +[72741] = {category="lo"}, +[72742] = {category="lo"}, +[72743] = {category="lo"}, +[72744] = {category="lo"}, +[72745] = {category="lo"}, +[72746] = {category="lo"}, +[72747] = {category="lo"}, +[72748] = {category="lo"}, +[72749] = {category="lo"}, +[72750] = {category="lo"}, +[72768] = {category="lo"}, +[72818] = {category="lo"}, +[72819] = {category="lo"}, +[72820] = {category="lo"}, +[72821] = {category="lo"}, +[72822] = {category="lo"}, +[72823] = {category="lo"}, +[72824] = {category="lo"}, +[72825] = {category="lo"}, +[72826] = {category="lo"}, +[72827] = {category="lo"}, +[72828] = {category="lo"}, +[72829] = {category="lo"}, +[72830] = {category="lo"}, +[72831] = {category="lo"}, +[72832] = {category="lo"}, +[72833] = {category="lo"}, +[72834] = {category="lo"}, +[72835] = {category="lo"}, +[72836] = {category="lo"}, +[72837] = {category="lo"}, +[72838] = {category="lo"}, +[72839] = {category="lo"}, +[72840] = {category="lo"}, +[72841] = {category="lo"}, +[72842] = {category="lo"}, +[72843] = {category="lo"}, +[72844] = {category="lo"}, +[72845] = {category="lo"}, +[72846] = {category="lo"}, +[72847] = {category="lo"}, +[72960] = {category="lo"}, +[72961] = {category="lo"}, +[72962] = {category="lo"}, +[72963] = {category="lo"}, +[72964] = {category="lo"}, +[72965] = {category="lo"}, +[72966] = {category="lo"}, +[72968] = {category="lo"}, +[72969] = {category="lo"}, +[72971] = {category="lo"}, +[72972] = {category="lo"}, +[72973] = {category="lo"}, +[72974] = {category="lo"}, +[72975] = {category="lo"}, +[72976] = {category="lo"}, +[72977] = {category="lo"}, +[72978] = {category="lo"}, +[72979] = {category="lo"}, +[72980] = {category="lo"}, +[72981] = {category="lo"}, +[72982] = {category="lo"}, +[72983] = {category="lo"}, +[72984] = {category="lo"}, +[72985] = {category="lo"}, +[72986] = {category="lo"}, +[72987] = {category="lo"}, +[72988] = {category="lo"}, +[72989] = {category="lo"}, +[72990] = {category="lo"}, +[72991] = {category="lo"}, +[72992] = {category="lo"}, +[72993] = {category="lo"}, +[72994] = {category="lo"}, +[72995] = {category="lo"}, +[72996] = {category="lo"}, +[72997] = {category="lo"}, +[72998] = {category="lo"}, +[72999] = {category="lo"}, +[73000] = {category="lo"}, +[73001] = {category="lo"}, +[73002] = {category="lo"}, +[73003] = {category="lo"}, +[73004] = {category="lo"}, +[73005] = {category="lo"}, +[73006] = {category="lo"}, +[73007] = {category="lo"}, +[73008] = {category="lo"}, +[73030] = {category="lo"}, +[73056] = {category="lo"}, +[73057] = {category="lo"}, +[73058] = {category="lo"}, +[73059] = {category="lo"}, +[73060] = {category="lo"}, +[73061] = {category="lo"}, +[73063] = {category="lo"}, +[73064] = {category="lo"}, +[73066] = {category="lo"}, +[73067] = {category="lo"}, +[73068] = {category="lo"}, +[73069] = {category="lo"}, +[73070] = {category="lo"}, +[73071] = {category="lo"}, +[73072] = {category="lo"}, +[73073] = {category="lo"}, +[73074] = {category="lo"}, +[73075] = {category="lo"}, +[73076] = {category="lo"}, +[73077] = {category="lo"}, +[73078] = {category="lo"}, +[73079] = {category="lo"}, +[73080] = {category="lo"}, +[73081] = {category="lo"}, +[73082] = {category="lo"}, +[73083] = {category="lo"}, +[73084] = {category="lo"}, +[73085] = {category="lo"}, +[73086] = {category="lo"}, +[73087] = {category="lo"}, +[73088] = {category="lo"}, +[73089] = {category="lo"}, +[73090] = {category="lo"}, +[73091] = {category="lo"}, +[73092] = {category="lo"}, +[73093] = {category="lo"}, +[73094] = {category="lo"}, +[73095] = {category="lo"}, +[73096] = {category="lo"}, +[73097] = {category="lo"}, +[73112] = {category="lo"}, +[73440] = {category="lo"}, +[73441] = {category="lo"}, +[73442] = {category="lo"}, +[73443] = {category="lo"}, +[73444] = {category="lo"}, +[73445] = {category="lo"}, +[73446] = {category="lo"}, +[73447] = {category="lo"}, +[73448] = {category="lo"}, +[73449] = {category="lo"}, +[73450] = {category="lo"}, +[73451] = {category="lo"}, +[73452] = {category="lo"}, +[73453] = {category="lo"}, +[73454] = {category="lo"}, +[73455] = {category="lo"}, +[73456] = {category="lo"}, +[73457] = {category="lo"}, +[73458] = {category="lo"}, +[73474] = {category="lo"}, +[73476] = {category="lo"}, +[73477] = {category="lo"}, +[73478] = {category="lo"}, +[73479] = {category="lo"}, +[73480] = {category="lo"}, +[73481] = {category="lo"}, +[73482] = {category="lo"}, +[73483] = {category="lo"}, +[73484] = {category="lo"}, +[73485] = {category="lo"}, +[73486] = {category="lo"}, +[73487] = {category="lo"}, +[73488] = {category="lo"}, +[73490] = {category="lo"}, +[73491] = {category="lo"}, +[73492] = {category="lo"}, +[73493] = {category="lo"}, +[73494] = {category="lo"}, +[73495] = {category="lo"}, +[73496] = {category="lo"}, +[73497] = {category="lo"}, +[73498] = {category="lo"}, +[73499] = {category="lo"}, +[73500] = {category="lo"}, +[73501] = {category="lo"}, +[73502] = {category="lo"}, +[73503] = {category="lo"}, +[73504] = {category="lo"}, +[73505] = {category="lo"}, +[73506] = {category="lo"}, +[73507] = {category="lo"}, +[73508] = {category="lo"}, +[73509] = {category="lo"}, +[73510] = {category="lo"}, +[73511] = {category="lo"}, +[73512] = {category="lo"}, +[73513] = {category="lo"}, +[73514] = {category="lo"}, +[73515] = {category="lo"}, +[73516] = {category="lo"}, +[73517] = {category="lo"}, +[73518] = {category="lo"}, +[73519] = {category="lo"}, +[73520] = {category="lo"}, +[73521] = {category="lo"}, +[73522] = {category="lo"}, +[73523] = {category="lo"}, +[73648] = {category="lo"}, +[73728] = {category="lo"}, +[73729] = {category="lo"}, +[73730] = {category="lo"}, +[73731] = {category="lo"}, +[73732] = {category="lo"}, +[73733] = {category="lo"}, +[73734] = {category="lo"}, +[73735] = {category="lo"}, +[73736] = {category="lo"}, +[73737] = {category="lo"}, +[73738] = {category="lo"}, +[73739] = {category="lo"}, +[73740] = {category="lo"}, +[73741] = {category="lo"}, +[73742] = {category="lo"}, +[73743] = {category="lo"}, +[73744] = {category="lo"}, +[73745] = {category="lo"}, +[73746] = {category="lo"}, +[73747] = {category="lo"}, +[73748] = {category="lo"}, +[73749] = {category="lo"}, +[73750] = {category="lo"}, +[73751] = {category="lo"}, +[73752] = {category="lo"}, +[73753] = {category="lo"}, +[73754] = {category="lo"}, +[73755] = {category="lo"}, +[73756] = {category="lo"}, +[73757] = {category="lo"}, +[73758] = {category="lo"}, +[73759] = {category="lo"}, +[73760] = {category="lo"}, +[73761] = {category="lo"}, +[73762] = {category="lo"}, +[73763] = {category="lo"}, +[73764] = {category="lo"}, +[73765] = {category="lo"}, +[73766] = {category="lo"}, +[73767] = {category="lo"}, +[73768] = {category="lo"}, +[73769] = {category="lo"}, +[73770] = {category="lo"}, +[73771] = {category="lo"}, +[73772] = {category="lo"}, +[73773] = {category="lo"}, +[73774] = {category="lo"}, +[73775] = {category="lo"}, +[73776] = {category="lo"}, +[73777] = {category="lo"}, +[73778] = {category="lo"}, +[73779] = {category="lo"}, +[73780] = {category="lo"}, +[73781] = {category="lo"}, +[73782] = {category="lo"}, +[73783] = {category="lo"}, +[73784] = {category="lo"}, +[73785] = {category="lo"}, +[73786] = {category="lo"}, +[73787] = {category="lo"}, +[73788] = {category="lo"}, +[73789] = {category="lo"}, +[73790] = {category="lo"}, +[73791] = {category="lo"}, +[73792] = {category="lo"}, +[73793] = {category="lo"}, +[73794] = {category="lo"}, +[73795] = {category="lo"}, +[73796] = {category="lo"}, +[73797] = {category="lo"}, +[73798] = {category="lo"}, +[73799] = {category="lo"}, +[73800] = {category="lo"}, +[73801] = {category="lo"}, +[73802] = {category="lo"}, +[73803] = {category="lo"}, +[73804] = {category="lo"}, +[73805] = {category="lo"}, +[73806] = {category="lo"}, +[73807] = {category="lo"}, +[73808] = {category="lo"}, +[73809] = {category="lo"}, +[73810] = {category="lo"}, +[73811] = {category="lo"}, +[73812] = {category="lo"}, +[73813] = {category="lo"}, +[73814] = {category="lo"}, +[73815] = {category="lo"}, +[73816] = {category="lo"}, +[73817] = {category="lo"}, +[73818] = {category="lo"}, +[73819] = {category="lo"}, +[73820] = {category="lo"}, +[73821] = {category="lo"}, +[73822] = {category="lo"}, +[73823] = {category="lo"}, +[73824] = {category="lo"}, +[73825] = {category="lo"}, +[73826] = {category="lo"}, +[73827] = {category="lo"}, +[73828] = {category="lo"}, +[73829] = {category="lo"}, +[73830] = {category="lo"}, +[73831] = {category="lo"}, +[73832] = {category="lo"}, +[73833] = {category="lo"}, +[73834] = {category="lo"}, +[73835] = {category="lo"}, +[73836] = {category="lo"}, +[73837] = {category="lo"}, +[73838] = {category="lo"}, +[73839] = {category="lo"}, +[73840] = {category="lo"}, +[73841] = {category="lo"}, +[73842] = {category="lo"}, +[73843] = {category="lo"}, +[73844] = {category="lo"}, +[73845] = {category="lo"}, +[73846] = {category="lo"}, +[73847] = {category="lo"}, +[73848] = {category="lo"}, +[73849] = {category="lo"}, +[73850] = {category="lo"}, +[73851] = {category="lo"}, +[73852] = {category="lo"}, +[73853] = {category="lo"}, +[73854] = {category="lo"}, +[73855] = {category="lo"}, +[73856] = {category="lo"}, +[73857] = {category="lo"}, +[73858] = {category="lo"}, +[73859] = {category="lo"}, +[73860] = {category="lo"}, +[73861] = {category="lo"}, +[73862] = {category="lo"}, +[73863] = {category="lo"}, +[73864] = {category="lo"}, +[73865] = {category="lo"}, +[73866] = {category="lo"}, +[73867] = {category="lo"}, +[73868] = {category="lo"}, +[73869] = {category="lo"}, +[73870] = {category="lo"}, +[73871] = {category="lo"}, +[73872] = {category="lo"}, +[73873] = {category="lo"}, +[73874] = {category="lo"}, +[73875] = {category="lo"}, +[73876] = {category="lo"}, +[73877] = {category="lo"}, +[73878] = {category="lo"}, +[73879] = {category="lo"}, +[73880] = {category="lo"}, +[73881] = {category="lo"}, +[73882] = {category="lo"}, +[73883] = {category="lo"}, +[73884] = {category="lo"}, +[73885] = {category="lo"}, +[73886] = {category="lo"}, +[73887] = {category="lo"}, +[73888] = {category="lo"}, +[73889] = {category="lo"}, +[73890] = {category="lo"}, +[73891] = {category="lo"}, +[73892] = {category="lo"}, +[73893] = {category="lo"}, +[73894] = {category="lo"}, +[73895] = {category="lo"}, +[73896] = {category="lo"}, +[73897] = {category="lo"}, +[73898] = {category="lo"}, +[73899] = {category="lo"}, +[73900] = {category="lo"}, +[73901] = {category="lo"}, +[73902] = {category="lo"}, +[73903] = {category="lo"}, +[73904] = {category="lo"}, +[73905] = {category="lo"}, +[73906] = {category="lo"}, +[73907] = {category="lo"}, +[73908] = {category="lo"}, +[73909] = {category="lo"}, +[73910] = {category="lo"}, +[73911] = {category="lo"}, +[73912] = {category="lo"}, +[73913] = {category="lo"}, +[73914] = {category="lo"}, +[73915] = {category="lo"}, +[73916] = {category="lo"}, +[73917] = {category="lo"}, +[73918] = {category="lo"}, +[73919] = {category="lo"}, +[73920] = {category="lo"}, +[73921] = {category="lo"}, +[73922] = {category="lo"}, +[73923] = {category="lo"}, +[73924] = {category="lo"}, +[73925] = {category="lo"}, +[73926] = {category="lo"}, +[73927] = {category="lo"}, +[73928] = {category="lo"}, +[73929] = {category="lo"}, +[73930] = {category="lo"}, +[73931] = {category="lo"}, +[73932] = {category="lo"}, +[73933] = {category="lo"}, +[73934] = {category="lo"}, +[73935] = {category="lo"}, +[73936] = {category="lo"}, +[73937] = {category="lo"}, +[73938] = {category="lo"}, +[73939] = {category="lo"}, +[73940] = {category="lo"}, +[73941] = {category="lo"}, +[73942] = {category="lo"}, +[73943] = {category="lo"}, +[73944] = {category="lo"}, +[73945] = {category="lo"}, +[73946] = {category="lo"}, +[73947] = {category="lo"}, +[73948] = {category="lo"}, +[73949] = {category="lo"}, +[73950] = {category="lo"}, +[73951] = {category="lo"}, +[73952] = {category="lo"}, +[73953] = {category="lo"}, +[73954] = {category="lo"}, +[73955] = {category="lo"}, +[73956] = {category="lo"}, +[73957] = {category="lo"}, +[73958] = {category="lo"}, +[73959] = {category="lo"}, +[73960] = {category="lo"}, +[73961] = {category="lo"}, +[73962] = {category="lo"}, +[73963] = {category="lo"}, +[73964] = {category="lo"}, +[73965] = {category="lo"}, +[73966] = {category="lo"}, +[73967] = {category="lo"}, +[73968] = {category="lo"}, +[73969] = {category="lo"}, +[73970] = {category="lo"}, +[73971] = {category="lo"}, +[73972] = {category="lo"}, +[73973] = {category="lo"}, +[73974] = {category="lo"}, +[73975] = {category="lo"}, +[73976] = {category="lo"}, +[73977] = {category="lo"}, +[73978] = {category="lo"}, +[73979] = {category="lo"}, +[73980] = {category="lo"}, +[73981] = {category="lo"}, +[73982] = {category="lo"}, +[73983] = {category="lo"}, +[73984] = {category="lo"}, +[73985] = {category="lo"}, +[73986] = {category="lo"}, +[73987] = {category="lo"}, +[73988] = {category="lo"}, +[73989] = {category="lo"}, +[73990] = {category="lo"}, +[73991] = {category="lo"}, +[73992] = {category="lo"}, +[73993] = {category="lo"}, +[73994] = {category="lo"}, +[73995] = {category="lo"}, +[73996] = {category="lo"}, +[73997] = {category="lo"}, +[73998] = {category="lo"}, +[73999] = {category="lo"}, +[74000] = {category="lo"}, +[74001] = {category="lo"}, +[74002] = {category="lo"}, +[74003] = {category="lo"}, +[74004] = {category="lo"}, +[74005] = {category="lo"}, +[74006] = {category="lo"}, +[74007] = {category="lo"}, +[74008] = {category="lo"}, +[74009] = {category="lo"}, +[74010] = {category="lo"}, +[74011] = {category="lo"}, +[74012] = {category="lo"}, +[74013] = {category="lo"}, +[74014] = {category="lo"}, +[74015] = {category="lo"}, +[74016] = {category="lo"}, +[74017] = {category="lo"}, +[74018] = {category="lo"}, +[74019] = {category="lo"}, +[74020] = {category="lo"}, +[74021] = {category="lo"}, +[74022] = {category="lo"}, +[74023] = {category="lo"}, +[74024] = {category="lo"}, +[74025] = {category="lo"}, +[74026] = {category="lo"}, +[74027] = {category="lo"}, +[74028] = {category="lo"}, +[74029] = {category="lo"}, +[74030] = {category="lo"}, +[74031] = {category="lo"}, +[74032] = {category="lo"}, +[74033] = {category="lo"}, +[74034] = {category="lo"}, +[74035] = {category="lo"}, +[74036] = {category="lo"}, +[74037] = {category="lo"}, +[74038] = {category="lo"}, +[74039] = {category="lo"}, +[74040] = {category="lo"}, +[74041] = {category="lo"}, +[74042] = {category="lo"}, +[74043] = {category="lo"}, +[74044] = {category="lo"}, +[74045] = {category="lo"}, +[74046] = {category="lo"}, +[74047] = {category="lo"}, +[74048] = {category="lo"}, +[74049] = {category="lo"}, +[74050] = {category="lo"}, +[74051] = {category="lo"}, +[74052] = {category="lo"}, +[74053] = {category="lo"}, +[74054] = {category="lo"}, +[74055] = {category="lo"}, +[74056] = {category="lo"}, +[74057] = {category="lo"}, +[74058] = {category="lo"}, +[74059] = {category="lo"}, +[74060] = {category="lo"}, +[74061] = {category="lo"}, +[74062] = {category="lo"}, +[74063] = {category="lo"}, +[74064] = {category="lo"}, +[74065] = {category="lo"}, +[74066] = {category="lo"}, +[74067] = {category="lo"}, +[74068] = {category="lo"}, +[74069] = {category="lo"}, +[74070] = {category="lo"}, +[74071] = {category="lo"}, +[74072] = {category="lo"}, +[74073] = {category="lo"}, +[74074] = {category="lo"}, +[74075] = {category="lo"}, +[74076] = {category="lo"}, +[74077] = {category="lo"}, +[74078] = {category="lo"}, +[74079] = {category="lo"}, +[74080] = {category="lo"}, +[74081] = {category="lo"}, +[74082] = {category="lo"}, +[74083] = {category="lo"}, +[74084] = {category="lo"}, +[74085] = {category="lo"}, +[74086] = {category="lo"}, +[74087] = {category="lo"}, +[74088] = {category="lo"}, +[74089] = {category="lo"}, +[74090] = {category="lo"}, +[74091] = {category="lo"}, +[74092] = {category="lo"}, +[74093] = {category="lo"}, +[74094] = {category="lo"}, +[74095] = {category="lo"}, +[74096] = {category="lo"}, +[74097] = {category="lo"}, +[74098] = {category="lo"}, +[74099] = {category="lo"}, +[74100] = {category="lo"}, +[74101] = {category="lo"}, +[74102] = {category="lo"}, +[74103] = {category="lo"}, +[74104] = {category="lo"}, +[74105] = {category="lo"}, +[74106] = {category="lo"}, +[74107] = {category="lo"}, +[74108] = {category="lo"}, +[74109] = {category="lo"}, +[74110] = {category="lo"}, +[74111] = {category="lo"}, +[74112] = {category="lo"}, +[74113] = {category="lo"}, +[74114] = {category="lo"}, +[74115] = {category="lo"}, +[74116] = {category="lo"}, +[74117] = {category="lo"}, +[74118] = {category="lo"}, +[74119] = {category="lo"}, +[74120] = {category="lo"}, +[74121] = {category="lo"}, +[74122] = {category="lo"}, +[74123] = {category="lo"}, +[74124] = {category="lo"}, +[74125] = {category="lo"}, +[74126] = {category="lo"}, +[74127] = {category="lo"}, +[74128] = {category="lo"}, +[74129] = {category="lo"}, +[74130] = {category="lo"}, +[74131] = {category="lo"}, +[74132] = {category="lo"}, +[74133] = {category="lo"}, +[74134] = {category="lo"}, +[74135] = {category="lo"}, +[74136] = {category="lo"}, +[74137] = {category="lo"}, +[74138] = {category="lo"}, +[74139] = {category="lo"}, +[74140] = {category="lo"}, +[74141] = {category="lo"}, +[74142] = {category="lo"}, +[74143] = {category="lo"}, +[74144] = {category="lo"}, +[74145] = {category="lo"}, +[74146] = {category="lo"}, +[74147] = {category="lo"}, +[74148] = {category="lo"}, +[74149] = {category="lo"}, +[74150] = {category="lo"}, +[74151] = {category="lo"}, +[74152] = {category="lo"}, +[74153] = {category="lo"}, +[74154] = {category="lo"}, +[74155] = {category="lo"}, +[74156] = {category="lo"}, +[74157] = {category="lo"}, +[74158] = {category="lo"}, +[74159] = {category="lo"}, +[74160] = {category="lo"}, +[74161] = {category="lo"}, +[74162] = {category="lo"}, +[74163] = {category="lo"}, +[74164] = {category="lo"}, +[74165] = {category="lo"}, +[74166] = {category="lo"}, +[74167] = {category="lo"}, +[74168] = {category="lo"}, +[74169] = {category="lo"}, +[74170] = {category="lo"}, +[74171] = {category="lo"}, +[74172] = {category="lo"}, +[74173] = {category="lo"}, +[74174] = {category="lo"}, +[74175] = {category="lo"}, +[74176] = {category="lo"}, +[74177] = {category="lo"}, +[74178] = {category="lo"}, +[74179] = {category="lo"}, +[74180] = {category="lo"}, +[74181] = {category="lo"}, +[74182] = {category="lo"}, +[74183] = {category="lo"}, +[74184] = {category="lo"}, +[74185] = {category="lo"}, +[74186] = {category="lo"}, +[74187] = {category="lo"}, +[74188] = {category="lo"}, +[74189] = {category="lo"}, +[74190] = {category="lo"}, +[74191] = {category="lo"}, +[74192] = {category="lo"}, +[74193] = {category="lo"}, +[74194] = {category="lo"}, +[74195] = {category="lo"}, +[74196] = {category="lo"}, +[74197] = {category="lo"}, +[74198] = {category="lo"}, +[74199] = {category="lo"}, +[74200] = {category="lo"}, +[74201] = {category="lo"}, +[74202] = {category="lo"}, +[74203] = {category="lo"}, +[74204] = {category="lo"}, +[74205] = {category="lo"}, +[74206] = {category="lo"}, +[74207] = {category="lo"}, +[74208] = {category="lo"}, +[74209] = {category="lo"}, +[74210] = {category="lo"}, +[74211] = {category="lo"}, +[74212] = {category="lo"}, +[74213] = {category="lo"}, +[74214] = {category="lo"}, +[74215] = {category="lo"}, +[74216] = {category="lo"}, +[74217] = {category="lo"}, +[74218] = {category="lo"}, +[74219] = {category="lo"}, +[74220] = {category="lo"}, +[74221] = {category="lo"}, +[74222] = {category="lo"}, +[74223] = {category="lo"}, +[74224] = {category="lo"}, +[74225] = {category="lo"}, +[74226] = {category="lo"}, +[74227] = {category="lo"}, +[74228] = {category="lo"}, +[74229] = {category="lo"}, +[74230] = {category="lo"}, +[74231] = {category="lo"}, +[74232] = {category="lo"}, +[74233] = {category="lo"}, +[74234] = {category="lo"}, +[74235] = {category="lo"}, +[74236] = {category="lo"}, +[74237] = {category="lo"}, +[74238] = {category="lo"}, +[74239] = {category="lo"}, +[74240] = {category="lo"}, +[74241] = {category="lo"}, +[74242] = {category="lo"}, +[74243] = {category="lo"}, +[74244] = {category="lo"}, +[74245] = {category="lo"}, +[74246] = {category="lo"}, +[74247] = {category="lo"}, +[74248] = {category="lo"}, +[74249] = {category="lo"}, +[74250] = {category="lo"}, +[74251] = {category="lo"}, +[74252] = {category="lo"}, +[74253] = {category="lo"}, +[74254] = {category="lo"}, +[74255] = {category="lo"}, +[74256] = {category="lo"}, +[74257] = {category="lo"}, +[74258] = {category="lo"}, +[74259] = {category="lo"}, +[74260] = {category="lo"}, +[74261] = {category="lo"}, +[74262] = {category="lo"}, +[74263] = {category="lo"}, +[74264] = {category="lo"}, +[74265] = {category="lo"}, +[74266] = {category="lo"}, +[74267] = {category="lo"}, +[74268] = {category="lo"}, +[74269] = {category="lo"}, +[74270] = {category="lo"}, +[74271] = {category="lo"}, +[74272] = {category="lo"}, +[74273] = {category="lo"}, +[74274] = {category="lo"}, +[74275] = {category="lo"}, +[74276] = {category="lo"}, +[74277] = {category="lo"}, +[74278] = {category="lo"}, +[74279] = {category="lo"}, +[74280] = {category="lo"}, +[74281] = {category="lo"}, +[74282] = {category="lo"}, +[74283] = {category="lo"}, +[74284] = {category="lo"}, +[74285] = {category="lo"}, +[74286] = {category="lo"}, +[74287] = {category="lo"}, +[74288] = {category="lo"}, +[74289] = {category="lo"}, +[74290] = {category="lo"}, +[74291] = {category="lo"}, +[74292] = {category="lo"}, +[74293] = {category="lo"}, +[74294] = {category="lo"}, +[74295] = {category="lo"}, +[74296] = {category="lo"}, +[74297] = {category="lo"}, +[74298] = {category="lo"}, +[74299] = {category="lo"}, +[74300] = {category="lo"}, +[74301] = {category="lo"}, +[74302] = {category="lo"}, +[74303] = {category="lo"}, +[74304] = {category="lo"}, +[74305] = {category="lo"}, +[74306] = {category="lo"}, +[74307] = {category="lo"}, +[74308] = {category="lo"}, +[74309] = {category="lo"}, +[74310] = {category="lo"}, +[74311] = {category="lo"}, +[74312] = {category="lo"}, +[74313] = {category="lo"}, +[74314] = {category="lo"}, +[74315] = {category="lo"}, +[74316] = {category="lo"}, +[74317] = {category="lo"}, +[74318] = {category="lo"}, +[74319] = {category="lo"}, +[74320] = {category="lo"}, +[74321] = {category="lo"}, +[74322] = {category="lo"}, +[74323] = {category="lo"}, +[74324] = {category="lo"}, +[74325] = {category="lo"}, +[74326] = {category="lo"}, +[74327] = {category="lo"}, +[74328] = {category="lo"}, +[74329] = {category="lo"}, +[74330] = {category="lo"}, +[74331] = {category="lo"}, +[74332] = {category="lo"}, +[74333] = {category="lo"}, +[74334] = {category="lo"}, +[74335] = {category="lo"}, +[74336] = {category="lo"}, +[74337] = {category="lo"}, +[74338] = {category="lo"}, +[74339] = {category="lo"}, +[74340] = {category="lo"}, +[74341] = {category="lo"}, +[74342] = {category="lo"}, +[74343] = {category="lo"}, +[74344] = {category="lo"}, +[74345] = {category="lo"}, +[74346] = {category="lo"}, +[74347] = {category="lo"}, +[74348] = {category="lo"}, +[74349] = {category="lo"}, +[74350] = {category="lo"}, +[74351] = {category="lo"}, +[74352] = {category="lo"}, +[74353] = {category="lo"}, +[74354] = {category="lo"}, +[74355] = {category="lo"}, +[74356] = {category="lo"}, +[74357] = {category="lo"}, +[74358] = {category="lo"}, +[74359] = {category="lo"}, +[74360] = {category="lo"}, +[74361] = {category="lo"}, +[74362] = {category="lo"}, +[74363] = {category="lo"}, +[74364] = {category="lo"}, +[74365] = {category="lo"}, +[74366] = {category="lo"}, +[74367] = {category="lo"}, +[74368] = {category="lo"}, +[74369] = {category="lo"}, +[74370] = {category="lo"}, +[74371] = {category="lo"}, +[74372] = {category="lo"}, +[74373] = {category="lo"}, +[74374] = {category="lo"}, +[74375] = {category="lo"}, +[74376] = {category="lo"}, +[74377] = {category="lo"}, +[74378] = {category="lo"}, +[74379] = {category="lo"}, +[74380] = {category="lo"}, +[74381] = {category="lo"}, +[74382] = {category="lo"}, +[74383] = {category="lo"}, +[74384] = {category="lo"}, +[74385] = {category="lo"}, +[74386] = {category="lo"}, +[74387] = {category="lo"}, +[74388] = {category="lo"}, +[74389] = {category="lo"}, +[74390] = {category="lo"}, +[74391] = {category="lo"}, +[74392] = {category="lo"}, +[74393] = {category="lo"}, +[74394] = {category="lo"}, +[74395] = {category="lo"}, +[74396] = {category="lo"}, +[74397] = {category="lo"}, +[74398] = {category="lo"}, +[74399] = {category="lo"}, +[74400] = {category="lo"}, +[74401] = {category="lo"}, +[74402] = {category="lo"}, +[74403] = {category="lo"}, +[74404] = {category="lo"}, +[74405] = {category="lo"}, +[74406] = {category="lo"}, +[74407] = {category="lo"}, +[74408] = {category="lo"}, +[74409] = {category="lo"}, +[74410] = {category="lo"}, +[74411] = {category="lo"}, +[74412] = {category="lo"}, +[74413] = {category="lo"}, +[74414] = {category="lo"}, +[74415] = {category="lo"}, +[74416] = {category="lo"}, +[74417] = {category="lo"}, +[74418] = {category="lo"}, +[74419] = {category="lo"}, +[74420] = {category="lo"}, +[74421] = {category="lo"}, +[74422] = {category="lo"}, +[74423] = {category="lo"}, +[74424] = {category="lo"}, +[74425] = {category="lo"}, +[74426] = {category="lo"}, +[74427] = {category="lo"}, +[74428] = {category="lo"}, +[74429] = {category="lo"}, +[74430] = {category="lo"}, +[74431] = {category="lo"}, +[74432] = {category="lo"}, +[74433] = {category="lo"}, +[74434] = {category="lo"}, +[74435] = {category="lo"}, +[74436] = {category="lo"}, +[74437] = {category="lo"}, +[74438] = {category="lo"}, +[74439] = {category="lo"}, +[74440] = {category="lo"}, +[74441] = {category="lo"}, +[74442] = {category="lo"}, +[74443] = {category="lo"}, +[74444] = {category="lo"}, +[74445] = {category="lo"}, +[74446] = {category="lo"}, +[74447] = {category="lo"}, +[74448] = {category="lo"}, +[74449] = {category="lo"}, +[74450] = {category="lo"}, +[74451] = {category="lo"}, +[74452] = {category="lo"}, +[74453] = {category="lo"}, +[74454] = {category="lo"}, +[74455] = {category="lo"}, +[74456] = {category="lo"}, +[74457] = {category="lo"}, +[74458] = {category="lo"}, +[74459] = {category="lo"}, +[74460] = {category="lo"}, +[74461] = {category="lo"}, +[74462] = {category="lo"}, +[74463] = {category="lo"}, +[74464] = {category="lo"}, +[74465] = {category="lo"}, +[74466] = {category="lo"}, +[74467] = {category="lo"}, +[74468] = {category="lo"}, +[74469] = {category="lo"}, +[74470] = {category="lo"}, +[74471] = {category="lo"}, +[74472] = {category="lo"}, +[74473] = {category="lo"}, +[74474] = {category="lo"}, +[74475] = {category="lo"}, +[74476] = {category="lo"}, +[74477] = {category="lo"}, +[74478] = {category="lo"}, +[74479] = {category="lo"}, +[74480] = {category="lo"}, +[74481] = {category="lo"}, +[74482] = {category="lo"}, +[74483] = {category="lo"}, +[74484] = {category="lo"}, +[74485] = {category="lo"}, +[74486] = {category="lo"}, +[74487] = {category="lo"}, +[74488] = {category="lo"}, +[74489] = {category="lo"}, +[74490] = {category="lo"}, +[74491] = {category="lo"}, +[74492] = {category="lo"}, +[74493] = {category="lo"}, +[74494] = {category="lo"}, +[74495] = {category="lo"}, +[74496] = {category="lo"}, +[74497] = {category="lo"}, +[74498] = {category="lo"}, +[74499] = {category="lo"}, +[74500] = {category="lo"}, +[74501] = {category="lo"}, +[74502] = {category="lo"}, +[74503] = {category="lo"}, +[74504] = {category="lo"}, +[74505] = {category="lo"}, +[74506] = {category="lo"}, +[74507] = {category="lo"}, +[74508] = {category="lo"}, +[74509] = {category="lo"}, +[74510] = {category="lo"}, +[74511] = {category="lo"}, +[74512] = {category="lo"}, +[74513] = {category="lo"}, +[74514] = {category="lo"}, +[74515] = {category="lo"}, +[74516] = {category="lo"}, +[74517] = {category="lo"}, +[74518] = {category="lo"}, +[74519] = {category="lo"}, +[74520] = {category="lo"}, +[74521] = {category="lo"}, +[74522] = {category="lo"}, +[74523] = {category="lo"}, +[74524] = {category="lo"}, +[74525] = {category="lo"}, +[74526] = {category="lo"}, +[74527] = {category="lo"}, +[74528] = {category="lo"}, +[74529] = {category="lo"}, +[74530] = {category="lo"}, +[74531] = {category="lo"}, +[74532] = {category="lo"}, +[74533] = {category="lo"}, +[74534] = {category="lo"}, +[74535] = {category="lo"}, +[74536] = {category="lo"}, +[74537] = {category="lo"}, +[74538] = {category="lo"}, +[74539] = {category="lo"}, +[74540] = {category="lo"}, +[74541] = {category="lo"}, +[74542] = {category="lo"}, +[74543] = {category="lo"}, +[74544] = {category="lo"}, +[74545] = {category="lo"}, +[74546] = {category="lo"}, +[74547] = {category="lo"}, +[74548] = {category="lo"}, +[74549] = {category="lo"}, +[74550] = {category="lo"}, +[74551] = {category="lo"}, +[74552] = {category="lo"}, +[74553] = {category="lo"}, +[74554] = {category="lo"}, +[74555] = {category="lo"}, +[74556] = {category="lo"}, +[74557] = {category="lo"}, +[74558] = {category="lo"}, +[74559] = {category="lo"}, +[74560] = {category="lo"}, +[74561] = {category="lo"}, +[74562] = {category="lo"}, +[74563] = {category="lo"}, +[74564] = {category="lo"}, +[74565] = {category="lo"}, +[74566] = {category="lo"}, +[74567] = {category="lo"}, +[74568] = {category="lo"}, +[74569] = {category="lo"}, +[74570] = {category="lo"}, +[74571] = {category="lo"}, +[74572] = {category="lo"}, +[74573] = {category="lo"}, +[74574] = {category="lo"}, +[74575] = {category="lo"}, +[74576] = {category="lo"}, +[74577] = {category="lo"}, +[74578] = {category="lo"}, +[74579] = {category="lo"}, +[74580] = {category="lo"}, +[74581] = {category="lo"}, +[74582] = {category="lo"}, +[74583] = {category="lo"}, +[74584] = {category="lo"}, +[74585] = {category="lo"}, +[74586] = {category="lo"}, +[74587] = {category="lo"}, +[74588] = {category="lo"}, +[74589] = {category="lo"}, +[74590] = {category="lo"}, +[74591] = {category="lo"}, +[74592] = {category="lo"}, +[74593] = {category="lo"}, +[74594] = {category="lo"}, +[74595] = {category="lo"}, +[74596] = {category="lo"}, +[74597] = {category="lo"}, +[74598] = {category="lo"}, +[74599] = {category="lo"}, +[74600] = {category="lo"}, +[74601] = {category="lo"}, +[74602] = {category="lo"}, +[74603] = {category="lo"}, +[74604] = {category="lo"}, +[74605] = {category="lo"}, +[74606] = {category="lo"}, +[74607] = {category="lo"}, +[74608] = {category="lo"}, +[74609] = {category="lo"}, +[74610] = {category="lo"}, +[74611] = {category="lo"}, +[74612] = {category="lo"}, +[74613] = {category="lo"}, +[74614] = {category="lo"}, +[74615] = {category="lo"}, +[74616] = {category="lo"}, +[74617] = {category="lo"}, +[74618] = {category="lo"}, +[74619] = {category="lo"}, +[74620] = {category="lo"}, +[74621] = {category="lo"}, +[74622] = {category="lo"}, +[74623] = {category="lo"}, +[74624] = {category="lo"}, +[74625] = {category="lo"}, +[74626] = {category="lo"}, +[74627] = {category="lo"}, +[74628] = {category="lo"}, +[74629] = {category="lo"}, +[74630] = {category="lo"}, +[74631] = {category="lo"}, +[74632] = {category="lo"}, +[74633] = {category="lo"}, +[74634] = {category="lo"}, +[74635] = {category="lo"}, +[74636] = {category="lo"}, +[74637] = {category="lo"}, +[74638] = {category="lo"}, +[74639] = {category="lo"}, +[74640] = {category="lo"}, +[74641] = {category="lo"}, +[74642] = {category="lo"}, +[74643] = {category="lo"}, +[74644] = {category="lo"}, +[74645] = {category="lo"}, +[74646] = {category="lo"}, +[74647] = {category="lo"}, +[74648] = {category="lo"}, +[74649] = {category="lo"}, +[74880] = {category="lo"}, +[74881] = {category="lo"}, +[74882] = {category="lo"}, +[74883] = {category="lo"}, +[74884] = {category="lo"}, +[74885] = {category="lo"}, +[74886] = {category="lo"}, +[74887] = {category="lo"}, +[74888] = {category="lo"}, +[74889] = {category="lo"}, +[74890] = {category="lo"}, +[74891] = {category="lo"}, +[74892] = {category="lo"}, +[74893] = {category="lo"}, +[74894] = {category="lo"}, +[74895] = {category="lo"}, +[74896] = {category="lo"}, +[74897] = {category="lo"}, +[74898] = {category="lo"}, +[74899] = {category="lo"}, +[74900] = {category="lo"}, +[74901] = {category="lo"}, +[74902] = {category="lo"}, +[74903] = {category="lo"}, +[74904] = {category="lo"}, +[74905] = {category="lo"}, +[74906] = {category="lo"}, +[74907] = {category="lo"}, +[74908] = {category="lo"}, +[74909] = {category="lo"}, +[74910] = {category="lo"}, +[74911] = {category="lo"}, +[74912] = {category="lo"}, +[74913] = {category="lo"}, +[74914] = {category="lo"}, +[74915] = {category="lo"}, +[74916] = {category="lo"}, +[74917] = {category="lo"}, +[74918] = {category="lo"}, +[74919] = {category="lo"}, +[74920] = {category="lo"}, +[74921] = {category="lo"}, +[74922] = {category="lo"}, +[74923] = {category="lo"}, +[74924] = {category="lo"}, +[74925] = {category="lo"}, +[74926] = {category="lo"}, +[74927] = {category="lo"}, +[74928] = {category="lo"}, +[74929] = {category="lo"}, +[74930] = {category="lo"}, +[74931] = {category="lo"}, +[74932] = {category="lo"}, +[74933] = {category="lo"}, +[74934] = {category="lo"}, +[74935] = {category="lo"}, +[74936] = {category="lo"}, +[74937] = {category="lo"}, +[74938] = {category="lo"}, +[74939] = {category="lo"}, +[74940] = {category="lo"}, +[74941] = {category="lo"}, +[74942] = {category="lo"}, +[74943] = {category="lo"}, +[74944] = {category="lo"}, +[74945] = {category="lo"}, +[74946] = {category="lo"}, +[74947] = {category="lo"}, +[74948] = {category="lo"}, +[74949] = {category="lo"}, +[74950] = {category="lo"}, +[74951] = {category="lo"}, +[74952] = {category="lo"}, +[74953] = {category="lo"}, +[74954] = {category="lo"}, +[74955] = {category="lo"}, +[74956] = {category="lo"}, +[74957] = {category="lo"}, +[74958] = {category="lo"}, +[74959] = {category="lo"}, +[74960] = {category="lo"}, +[74961] = {category="lo"}, +[74962] = {category="lo"}, +[74963] = {category="lo"}, +[74964] = {category="lo"}, +[74965] = {category="lo"}, +[74966] = {category="lo"}, +[74967] = {category="lo"}, +[74968] = {category="lo"}, +[74969] = {category="lo"}, +[74970] = {category="lo"}, +[74971] = {category="lo"}, +[74972] = {category="lo"}, +[74973] = {category="lo"}, +[74974] = {category="lo"}, +[74975] = {category="lo"}, +[74976] = {category="lo"}, +[74977] = {category="lo"}, +[74978] = {category="lo"}, +[74979] = {category="lo"}, +[74980] = {category="lo"}, +[74981] = {category="lo"}, +[74982] = {category="lo"}, +[74983] = {category="lo"}, +[74984] = {category="lo"}, +[74985] = {category="lo"}, +[74986] = {category="lo"}, +[74987] = {category="lo"}, +[74988] = {category="lo"}, +[74989] = {category="lo"}, +[74990] = {category="lo"}, +[74991] = {category="lo"}, +[74992] = {category="lo"}, +[74993] = {category="lo"}, +[74994] = {category="lo"}, +[74995] = {category="lo"}, +[74996] = {category="lo"}, +[74997] = {category="lo"}, +[74998] = {category="lo"}, +[74999] = {category="lo"}, +[75000] = {category="lo"}, +[75001] = {category="lo"}, +[75002] = {category="lo"}, +[75003] = {category="lo"}, +[75004] = {category="lo"}, +[75005] = {category="lo"}, +[75006] = {category="lo"}, +[75007] = {category="lo"}, +[75008] = {category="lo"}, +[75009] = {category="lo"}, +[75010] = {category="lo"}, +[75011] = {category="lo"}, +[75012] = {category="lo"}, +[75013] = {category="lo"}, +[75014] = {category="lo"}, +[75015] = {category="lo"}, +[75016] = {category="lo"}, +[75017] = {category="lo"}, +[75018] = {category="lo"}, +[75019] = {category="lo"}, +[75020] = {category="lo"}, +[75021] = {category="lo"}, +[75022] = {category="lo"}, +[75023] = {category="lo"}, +[75024] = {category="lo"}, +[75025] = {category="lo"}, +[75026] = {category="lo"}, +[75027] = {category="lo"}, +[75028] = {category="lo"}, +[75029] = {category="lo"}, +[75030] = {category="lo"}, +[75031] = {category="lo"}, +[75032] = {category="lo"}, +[75033] = {category="lo"}, +[75034] = {category="lo"}, +[75035] = {category="lo"}, +[75036] = {category="lo"}, +[75037] = {category="lo"}, +[75038] = {category="lo"}, +[75039] = {category="lo"}, +[75040] = {category="lo"}, +[75041] = {category="lo"}, +[75042] = {category="lo"}, +[75043] = {category="lo"}, +[75044] = {category="lo"}, +[75045] = {category="lo"}, +[75046] = {category="lo"}, +[75047] = {category="lo"}, +[75048] = {category="lo"}, +[75049] = {category="lo"}, +[75050] = {category="lo"}, +[75051] = {category="lo"}, +[75052] = {category="lo"}, +[75053] = {category="lo"}, +[75054] = {category="lo"}, +[75055] = {category="lo"}, +[75056] = {category="lo"}, +[75057] = {category="lo"}, +[75058] = {category="lo"}, +[75059] = {category="lo"}, +[75060] = {category="lo"}, +[75061] = {category="lo"}, +[75062] = {category="lo"}, +[75063] = {category="lo"}, +[75064] = {category="lo"}, +[75065] = {category="lo"}, +[75066] = {category="lo"}, +[75067] = {category="lo"}, +[75068] = {category="lo"}, +[75069] = {category="lo"}, +[75070] = {category="lo"}, +[75071] = {category="lo"}, +[75072] = {category="lo"}, +[75073] = {category="lo"}, +[75074] = {category="lo"}, +[75075] = {category="lo"}, +[77712] = {category="lo"}, +[77713] = {category="lo"}, +[77714] = {category="lo"}, +[77715] = {category="lo"}, +[77716] = {category="lo"}, +[77717] = {category="lo"}, +[77718] = {category="lo"}, +[77719] = {category="lo"}, +[77720] = {category="lo"}, +[77721] = {category="lo"}, +[77722] = {category="lo"}, +[77723] = {category="lo"}, +[77724] = {category="lo"}, +[77725] = {category="lo"}, +[77726] = {category="lo"}, +[77727] = {category="lo"}, +[77728] = {category="lo"}, +[77729] = {category="lo"}, +[77730] = {category="lo"}, +[77731] = {category="lo"}, +[77732] = {category="lo"}, +[77733] = {category="lo"}, +[77734] = {category="lo"}, +[77735] = {category="lo"}, +[77736] = {category="lo"}, +[77737] = {category="lo"}, +[77738] = {category="lo"}, +[77739] = {category="lo"}, +[77740] = {category="lo"}, +[77741] = {category="lo"}, +[77742] = {category="lo"}, +[77743] = {category="lo"}, +[77744] = {category="lo"}, +[77745] = {category="lo"}, +[77746] = {category="lo"}, +[77747] = {category="lo"}, +[77748] = {category="lo"}, +[77749] = {category="lo"}, +[77750] = {category="lo"}, +[77751] = {category="lo"}, +[77752] = {category="lo"}, +[77753] = {category="lo"}, +[77754] = {category="lo"}, +[77755] = {category="lo"}, +[77756] = {category="lo"}, +[77757] = {category="lo"}, +[77758] = {category="lo"}, +[77759] = {category="lo"}, +[77760] = {category="lo"}, +[77761] = {category="lo"}, +[77762] = {category="lo"}, +[77763] = {category="lo"}, +[77764] = {category="lo"}, +[77765] = {category="lo"}, +[77766] = {category="lo"}, +[77767] = {category="lo"}, +[77768] = {category="lo"}, +[77769] = {category="lo"}, +[77770] = {category="lo"}, +[77771] = {category="lo"}, +[77772] = {category="lo"}, +[77773] = {category="lo"}, +[77774] = {category="lo"}, +[77775] = {category="lo"}, +[77776] = {category="lo"}, +[77777] = {category="lo"}, +[77778] = {category="lo"}, +[77779] = {category="lo"}, +[77780] = {category="lo"}, +[77781] = {category="lo"}, +[77782] = {category="lo"}, +[77783] = {category="lo"}, +[77784] = {category="lo"}, +[77785] = {category="lo"}, +[77786] = {category="lo"}, +[77787] = {category="lo"}, +[77788] = {category="lo"}, +[77789] = {category="lo"}, +[77790] = {category="lo"}, +[77791] = {category="lo"}, +[77792] = {category="lo"}, +[77793] = {category="lo"}, +[77794] = {category="lo"}, +[77795] = {category="lo"}, +[77796] = {category="lo"}, +[77797] = {category="lo"}, +[77798] = {category="lo"}, +[77799] = {category="lo"}, +[77800] = {category="lo"}, +[77801] = {category="lo"}, +[77802] = {category="lo"}, +[77803] = {category="lo"}, +[77804] = {category="lo"}, +[77805] = {category="lo"}, +[77806] = {category="lo"}, +[77807] = {category="lo"}, +[77808] = {category="lo"}, +[77824] = {category="lo"}, +[77825] = {category="lo"}, +[77826] = {category="lo"}, +[77827] = {category="lo"}, +[77828] = {category="lo"}, +[77829] = {category="lo"}, +[77830] = {category="lo"}, +[77831] = {category="lo"}, +[77832] = {category="lo"}, +[77833] = {category="lo"}, +[77834] = {category="lo"}, +[77835] = {category="lo"}, +[77836] = {category="lo"}, +[77837] = {category="lo"}, +[77838] = {category="lo"}, +[77839] = {category="lo"}, +[77840] = {category="lo"}, +[77841] = {category="lo"}, +[77842] = {category="lo"}, +[77843] = {category="lo"}, +[77844] = {category="lo"}, +[77845] = {category="lo"}, +[77846] = {category="lo"}, +[77847] = {category="lo"}, +[77848] = {category="lo"}, +[77849] = {category="lo"}, +[77850] = {category="lo"}, +[77851] = {category="lo"}, +[77852] = {category="lo"}, +[77853] = {category="lo"}, +[77854] = {category="lo"}, +[77855] = {category="lo"}, +[77856] = {category="lo"}, +[77857] = {category="lo"}, +[77858] = {category="lo"}, +[77859] = {category="lo"}, +[77860] = {category="lo"}, +[77861] = {category="lo"}, +[77862] = {category="lo"}, +[77863] = {category="lo"}, +[77864] = {category="lo"}, +[77865] = {category="lo"}, +[77866] = {category="lo"}, +[77867] = {category="lo"}, +[77868] = {category="lo"}, +[77869] = {category="lo"}, +[77870] = {category="lo"}, +[77871] = {category="lo"}, +[77872] = {category="lo"}, +[77873] = {category="lo"}, +[77874] = {category="lo"}, +[77875] = {category="lo"}, +[77876] = {category="lo"}, +[77877] = {category="lo"}, +[77878] = {category="lo"}, +[77879] = {category="lo"}, +[77880] = {category="lo"}, +[77881] = {category="lo"}, +[77882] = {category="lo"}, +[77883] = {category="lo"}, +[77884] = {category="lo"}, +[77885] = {category="lo"}, +[77886] = {category="lo"}, +[77887] = {category="lo"}, +[77888] = {category="lo"}, +[77889] = {category="lo"}, +[77890] = {category="lo"}, +[77891] = {category="lo"}, +[77892] = {category="lo"}, +[77893] = {category="lo"}, +[77894] = {category="lo"}, +[77895] = {category="lo"}, +[77896] = {category="lo"}, +[77897] = {category="lo"}, +[77898] = {category="lo"}, +[77899] = {category="lo"}, +[77900] = {category="lo"}, +[77901] = {category="lo"}, +[77902] = {category="lo"}, +[77903] = {category="lo"}, +[77904] = {category="lo"}, +[77905] = {category="lo"}, +[77906] = {category="lo"}, +[77907] = {category="lo"}, +[77908] = {category="lo"}, +[77909] = {category="lo"}, +[77910] = {category="lo"}, +[77911] = {category="lo"}, +[77912] = {category="lo"}, +[77913] = {category="lo"}, +[77914] = {category="lo"}, +[77915] = {category="lo"}, +[77916] = {category="lo"}, +[77917] = {category="lo"}, +[77918] = {category="lo"}, +[77919] = {category="lo"}, +[77920] = {category="lo"}, +[77921] = {category="lo"}, +[77922] = {category="lo"}, +[77923] = {category="lo"}, +[77924] = {category="lo"}, +[77925] = {category="lo"}, +[77926] = {category="lo"}, +[77927] = {category="lo"}, +[77928] = {category="lo"}, +[77929] = {category="lo"}, +[77930] = {category="lo"}, +[77931] = {category="lo"}, +[77932] = {category="lo"}, +[77933] = {category="lo"}, +[77934] = {category="lo"}, +[77935] = {category="lo"}, +[77936] = {category="lo"}, +[77937] = {category="lo"}, +[77938] = {category="lo"}, +[77939] = {category="lo"}, +[77940] = {category="lo"}, +[77941] = {category="lo"}, +[77942] = {category="lo"}, +[77943] = {category="lo"}, +[77944] = {category="lo"}, +[77945] = {category="lo"}, +[77946] = {category="lo"}, +[77947] = {category="lo"}, +[77948] = {category="lo"}, +[77949] = {category="lo"}, +[77950] = {category="lo"}, +[77951] = {category="lo"}, +[77952] = {category="lo"}, +[77953] = {category="lo"}, +[77954] = {category="lo"}, +[77955] = {category="lo"}, +[77956] = {category="lo"}, +[77957] = {category="lo"}, +[77958] = {category="lo"}, +[77959] = {category="lo"}, +[77960] = {category="lo"}, +[77961] = {category="lo"}, +[77962] = {category="lo"}, +[77963] = {category="lo"}, +[77964] = {category="lo"}, +[77965] = {category="lo"}, +[77966] = {category="lo"}, +[77967] = {category="lo"}, +[77968] = {category="lo"}, +[77969] = {category="lo"}, +[77970] = {category="lo"}, +[77971] = {category="lo"}, +[77972] = {category="lo"}, +[77973] = {category="lo"}, +[77974] = {category="lo"}, +[77975] = {category="lo"}, +[77976] = {category="lo"}, +[77977] = {category="lo"}, +[77978] = {category="lo"}, +[77979] = {category="lo"}, +[77980] = {category="lo"}, +[77981] = {category="lo"}, +[77982] = {category="lo"}, +[77983] = {category="lo"}, +[77984] = {category="lo"}, +[77985] = {category="lo"}, +[77986] = {category="lo"}, +[77987] = {category="lo"}, +[77988] = {category="lo"}, +[77989] = {category="lo"}, +[77990] = {category="lo"}, +[77991] = {category="lo"}, +[77992] = {category="lo"}, +[77993] = {category="lo"}, +[77994] = {category="lo"}, +[77995] = {category="lo"}, +[77996] = {category="lo"}, +[77997] = {category="lo"}, +[77998] = {category="lo"}, +[77999] = {category="lo"}, +[78000] = {category="lo"}, +[78001] = {category="lo"}, +[78002] = {category="lo"}, +[78003] = {category="lo"}, +[78004] = {category="lo"}, +[78005] = {category="lo"}, +[78006] = {category="lo"}, +[78007] = {category="lo"}, +[78008] = {category="lo"}, +[78009] = {category="lo"}, +[78010] = {category="lo"}, +[78011] = {category="lo"}, +[78012] = {category="lo"}, +[78013] = {category="lo"}, +[78014] = {category="lo"}, +[78015] = {category="lo"}, +[78016] = {category="lo"}, +[78017] = {category="lo"}, +[78018] = {category="lo"}, +[78019] = {category="lo"}, +[78020] = {category="lo"}, +[78021] = {category="lo"}, +[78022] = {category="lo"}, +[78023] = {category="lo"}, +[78024] = {category="lo"}, +[78025] = {category="lo"}, +[78026] = {category="lo"}, +[78027] = {category="lo"}, +[78028] = {category="lo"}, +[78029] = {category="lo"}, +[78030] = {category="lo"}, +[78031] = {category="lo"}, +[78032] = {category="lo"}, +[78033] = {category="lo"}, +[78034] = {category="lo"}, +[78035] = {category="lo"}, +[78036] = {category="lo"}, +[78037] = {category="lo"}, +[78038] = {category="lo"}, +[78039] = {category="lo"}, +[78040] = {category="lo"}, +[78041] = {category="lo"}, +[78042] = {category="lo"}, +[78043] = {category="lo"}, +[78044] = {category="lo"}, +[78045] = {category="lo"}, +[78046] = {category="lo"}, +[78047] = {category="lo"}, +[78048] = {category="lo"}, +[78049] = {category="lo"}, +[78050] = {category="lo"}, +[78051] = {category="lo"}, +[78052] = {category="lo"}, +[78053] = {category="lo"}, +[78054] = {category="lo"}, +[78055] = {category="lo"}, +[78056] = {category="lo"}, +[78057] = {category="lo"}, +[78058] = {category="lo"}, +[78059] = {category="lo"}, +[78060] = {category="lo"}, +[78061] = {category="lo"}, +[78062] = {category="lo"}, +[78063] = {category="lo"}, +[78064] = {category="lo"}, +[78065] = {category="lo"}, +[78066] = {category="lo"}, +[78067] = {category="lo"}, +[78068] = {category="lo"}, +[78069] = {category="lo"}, +[78070] = {category="lo"}, +[78071] = {category="lo"}, +[78072] = {category="lo"}, +[78073] = {category="lo"}, +[78074] = {category="lo"}, +[78075] = {category="lo"}, +[78076] = {category="lo"}, +[78077] = {category="lo"}, +[78078] = {category="lo"}, +[78079] = {category="lo"}, +[78080] = {category="lo"}, +[78081] = {category="lo"}, +[78082] = {category="lo"}, +[78083] = {category="lo"}, +[78084] = {category="lo"}, +[78085] = {category="lo"}, +[78086] = {category="lo"}, +[78087] = {category="lo"}, +[78088] = {category="lo"}, +[78089] = {category="lo"}, +[78090] = {category="lo"}, +[78091] = {category="lo"}, +[78092] = {category="lo"}, +[78093] = {category="lo"}, +[78094] = {category="lo"}, +[78095] = {category="lo"}, +[78096] = {category="lo"}, +[78097] = {category="lo"}, +[78098] = {category="lo"}, +[78099] = {category="lo"}, +[78100] = {category="lo"}, +[78101] = {category="lo"}, +[78102] = {category="lo"}, +[78103] = {category="lo"}, +[78104] = {category="lo"}, +[78105] = {category="lo"}, +[78106] = {category="lo"}, +[78107] = {category="lo"}, +[78108] = {category="lo"}, +[78109] = {category="lo"}, +[78110] = {category="lo"}, +[78111] = {category="lo"}, +[78112] = {category="lo"}, +[78113] = {category="lo"}, +[78114] = {category="lo"}, +[78115] = {category="lo"}, +[78116] = {category="lo"}, +[78117] = {category="lo"}, +[78118] = {category="lo"}, +[78119] = {category="lo"}, +[78120] = {category="lo"}, +[78121] = {category="lo"}, +[78122] = {category="lo"}, +[78123] = {category="lo"}, +[78124] = {category="lo"}, +[78125] = {category="lo"}, +[78126] = {category="lo"}, +[78127] = {category="lo"}, +[78128] = {category="lo"}, +[78129] = {category="lo"}, +[78130] = {category="lo"}, +[78131] = {category="lo"}, +[78132] = {category="lo"}, +[78133] = {category="lo"}, +[78134] = {category="lo"}, +[78135] = {category="lo"}, +[78136] = {category="lo"}, +[78137] = {category="lo"}, +[78138] = {category="lo"}, +[78139] = {category="lo"}, +[78140] = {category="lo"}, +[78141] = {category="lo"}, +[78142] = {category="lo"}, +[78143] = {category="lo"}, +[78144] = {category="lo"}, +[78145] = {category="lo"}, +[78146] = {category="lo"}, +[78147] = {category="lo"}, +[78148] = {category="lo"}, +[78149] = {category="lo"}, +[78150] = {category="lo"}, +[78151] = {category="lo"}, +[78152] = {category="lo"}, +[78153] = {category="lo"}, +[78154] = {category="lo"}, +[78155] = {category="lo"}, +[78156] = {category="lo"}, +[78157] = {category="lo"}, +[78158] = {category="lo"}, +[78159] = {category="lo"}, +[78160] = {category="lo"}, +[78161] = {category="lo"}, +[78162] = {category="lo"}, +[78163] = {category="lo"}, +[78164] = {category="lo"}, +[78165] = {category="lo"}, +[78166] = {category="lo"}, +[78167] = {category="lo"}, +[78168] = {category="lo"}, +[78169] = {category="lo"}, +[78170] = {category="lo"}, +[78171] = {category="lo"}, +[78172] = {category="lo"}, +[78173] = {category="lo"}, +[78174] = {category="lo"}, +[78175] = {category="lo"}, +[78176] = {category="lo"}, +[78177] = {category="lo"}, +[78178] = {category="lo"}, +[78179] = {category="lo"}, +[78180] = {category="lo"}, +[78181] = {category="lo"}, +[78182] = {category="lo"}, +[78183] = {category="lo"}, +[78184] = {category="lo"}, +[78185] = {category="lo"}, +[78186] = {category="lo"}, +[78187] = {category="lo"}, +[78188] = {category="lo"}, +[78189] = {category="lo"}, +[78190] = {category="lo"}, +[78191] = {category="lo"}, +[78192] = {category="lo"}, +[78193] = {category="lo"}, +[78194] = {category="lo"}, +[78195] = {category="lo"}, +[78196] = {category="lo"}, +[78197] = {category="lo"}, +[78198] = {category="lo"}, +[78199] = {category="lo"}, +[78200] = {category="lo"}, +[78201] = {category="lo"}, +[78202] = {category="lo"}, +[78203] = {category="lo"}, +[78204] = {category="lo"}, +[78205] = {category="lo"}, +[78206] = {category="lo"}, +[78207] = {category="lo"}, +[78208] = {category="lo"}, +[78209] = {category="lo"}, +[78210] = {category="lo"}, +[78211] = {category="lo"}, +[78212] = {category="lo"}, +[78213] = {category="lo"}, +[78214] = {category="lo"}, +[78215] = {category="lo"}, +[78216] = {category="lo"}, +[78217] = {category="lo"}, +[78218] = {category="lo"}, +[78219] = {category="lo"}, +[78220] = {category="lo"}, +[78221] = {category="lo"}, +[78222] = {category="lo"}, +[78223] = {category="lo"}, +[78224] = {category="lo"}, +[78225] = {category="lo"}, +[78226] = {category="lo"}, +[78227] = {category="lo"}, +[78228] = {category="lo"}, +[78229] = {category="lo"}, +[78230] = {category="lo"}, +[78231] = {category="lo"}, +[78232] = {category="lo"}, +[78233] = {category="lo"}, +[78234] = {category="lo"}, +[78235] = {category="lo"}, +[78236] = {category="lo"}, +[78237] = {category="lo"}, +[78238] = {category="lo"}, +[78239] = {category="lo"}, +[78240] = {category="lo"}, +[78241] = {category="lo"}, +[78242] = {category="lo"}, +[78243] = {category="lo"}, +[78244] = {category="lo"}, +[78245] = {category="lo"}, +[78246] = {category="lo"}, +[78247] = {category="lo"}, +[78248] = {category="lo"}, +[78249] = {category="lo"}, +[78250] = {category="lo"}, +[78251] = {category="lo"}, +[78252] = {category="lo"}, +[78253] = {category="lo"}, +[78254] = {category="lo"}, +[78255] = {category="lo"}, +[78256] = {category="lo"}, +[78257] = {category="lo"}, +[78258] = {category="lo"}, +[78259] = {category="lo"}, +[78260] = {category="lo"}, +[78261] = {category="lo"}, +[78262] = {category="lo"}, +[78263] = {category="lo"}, +[78264] = {category="lo"}, +[78265] = {category="lo"}, +[78266] = {category="lo"}, +[78267] = {category="lo"}, +[78268] = {category="lo"}, +[78269] = {category="lo"}, +[78270] = {category="lo"}, +[78271] = {category="lo"}, +[78272] = {category="lo"}, +[78273] = {category="lo"}, +[78274] = {category="lo"}, +[78275] = {category="lo"}, +[78276] = {category="lo"}, +[78277] = {category="lo"}, +[78278] = {category="lo"}, +[78279] = {category="lo"}, +[78280] = {category="lo"}, +[78281] = {category="lo"}, +[78282] = {category="lo"}, +[78283] = {category="lo"}, +[78284] = {category="lo"}, +[78285] = {category="lo"}, +[78286] = {category="lo"}, +[78287] = {category="lo"}, +[78288] = {category="lo"}, +[78289] = {category="lo"}, +[78290] = {category="lo"}, +[78291] = {category="lo"}, +[78292] = {category="lo"}, +[78293] = {category="lo"}, +[78294] = {category="lo"}, +[78295] = {category="lo"}, +[78296] = {category="lo"}, +[78297] = {category="lo"}, +[78298] = {category="lo"}, +[78299] = {category="lo"}, +[78300] = {category="lo"}, +[78301] = {category="lo"}, +[78302] = {category="lo"}, +[78303] = {category="lo"}, +[78304] = {category="lo"}, +[78305] = {category="lo"}, +[78306] = {category="lo"}, +[78307] = {category="lo"}, +[78308] = {category="lo"}, +[78309] = {category="lo"}, +[78310] = {category="lo"}, +[78311] = {category="lo"}, +[78312] = {category="lo"}, +[78313] = {category="lo"}, +[78314] = {category="lo"}, +[78315] = {category="lo"}, +[78316] = {category="lo"}, +[78317] = {category="lo"}, +[78318] = {category="lo"}, +[78319] = {category="lo"}, +[78320] = {category="lo"}, +[78321] = {category="lo"}, +[78322] = {category="lo"}, +[78323] = {category="lo"}, +[78324] = {category="lo"}, +[78325] = {category="lo"}, +[78326] = {category="lo"}, +[78327] = {category="lo"}, +[78328] = {category="lo"}, +[78329] = {category="lo"}, +[78330] = {category="lo"}, +[78331] = {category="lo"}, +[78332] = {category="lo"}, +[78333] = {category="lo"}, +[78334] = {category="lo"}, +[78335] = {category="lo"}, +[78336] = {category="lo"}, +[78337] = {category="lo"}, +[78338] = {category="lo"}, +[78339] = {category="lo"}, +[78340] = {category="lo"}, +[78341] = {category="lo"}, +[78342] = {category="lo"}, +[78343] = {category="lo"}, +[78344] = {category="lo"}, +[78345] = {category="lo"}, +[78346] = {category="lo"}, +[78347] = {category="lo"}, +[78348] = {category="lo"}, +[78349] = {category="lo"}, +[78350] = {category="lo"}, +[78351] = {category="lo"}, +[78352] = {category="lo"}, +[78353] = {category="lo"}, +[78354] = {category="lo"}, +[78355] = {category="lo"}, +[78356] = {category="lo"}, +[78357] = {category="lo"}, +[78358] = {category="lo"}, +[78359] = {category="lo"}, +[78360] = {category="lo"}, +[78361] = {category="lo"}, +[78362] = {category="lo"}, +[78363] = {category="lo"}, +[78364] = {category="lo"}, +[78365] = {category="lo"}, +[78366] = {category="lo"}, +[78367] = {category="lo"}, +[78368] = {category="lo"}, +[78369] = {category="lo"}, +[78370] = {category="lo"}, +[78371] = {category="lo"}, +[78372] = {category="lo"}, +[78373] = {category="lo"}, +[78374] = {category="lo"}, +[78375] = {category="lo"}, +[78376] = {category="lo"}, +[78377] = {category="lo"}, +[78378] = {category="lo"}, +[78379] = {category="lo"}, +[78380] = {category="lo"}, +[78381] = {category="lo"}, +[78382] = {category="lo"}, +[78383] = {category="lo"}, +[78384] = {category="lo"}, +[78385] = {category="lo"}, +[78386] = {category="lo"}, +[78387] = {category="lo"}, +[78388] = {category="lo"}, +[78389] = {category="lo"}, +[78390] = {category="lo"}, +[78391] = {category="lo"}, +[78392] = {category="lo"}, +[78393] = {category="lo"}, +[78394] = {category="lo"}, +[78395] = {category="lo"}, +[78396] = {category="lo"}, +[78397] = {category="lo"}, +[78398] = {category="lo"}, +[78399] = {category="lo"}, +[78400] = {category="lo"}, +[78401] = {category="lo"}, +[78402] = {category="lo"}, +[78403] = {category="lo"}, +[78404] = {category="lo"}, +[78405] = {category="lo"}, +[78406] = {category="lo"}, +[78407] = {category="lo"}, +[78408] = {category="lo"}, +[78409] = {category="lo"}, +[78410] = {category="lo"}, +[78411] = {category="lo"}, +[78412] = {category="lo"}, +[78413] = {category="lo"}, +[78414] = {category="lo"}, +[78415] = {category="lo"}, +[78416] = {category="lo"}, +[78417] = {category="lo"}, +[78418] = {category="lo"}, +[78419] = {category="lo"}, +[78420] = {category="lo"}, +[78421] = {category="lo"}, +[78422] = {category="lo"}, +[78423] = {category="lo"}, +[78424] = {category="lo"}, +[78425] = {category="lo"}, +[78426] = {category="lo"}, +[78427] = {category="lo"}, +[78428] = {category="lo"}, +[78429] = {category="lo"}, +[78430] = {category="lo"}, +[78431] = {category="lo"}, +[78432] = {category="lo"}, +[78433] = {category="lo"}, +[78434] = {category="lo"}, +[78435] = {category="lo"}, +[78436] = {category="lo"}, +[78437] = {category="lo"}, +[78438] = {category="lo"}, +[78439] = {category="lo"}, +[78440] = {category="lo"}, +[78441] = {category="lo"}, +[78442] = {category="lo"}, +[78443] = {category="lo"}, +[78444] = {category="lo"}, +[78445] = {category="lo"}, +[78446] = {category="lo"}, +[78447] = {category="lo"}, +[78448] = {category="lo"}, +[78449] = {category="lo"}, +[78450] = {category="lo"}, +[78451] = {category="lo"}, +[78452] = {category="lo"}, +[78453] = {category="lo"}, +[78454] = {category="lo"}, +[78455] = {category="lo"}, +[78456] = {category="lo"}, +[78457] = {category="lo"}, +[78458] = {category="lo"}, +[78459] = {category="lo"}, +[78460] = {category="lo"}, +[78461] = {category="lo"}, +[78462] = {category="lo"}, +[78463] = {category="lo"}, +[78464] = {category="lo"}, +[78465] = {category="lo"}, +[78466] = {category="lo"}, +[78467] = {category="lo"}, +[78468] = {category="lo"}, +[78469] = {category="lo"}, +[78470] = {category="lo"}, +[78471] = {category="lo"}, +[78472] = {category="lo"}, +[78473] = {category="lo"}, +[78474] = {category="lo"}, +[78475] = {category="lo"}, +[78476] = {category="lo"}, +[78477] = {category="lo"}, +[78478] = {category="lo"}, +[78479] = {category="lo"}, +[78480] = {category="lo"}, +[78481] = {category="lo"}, +[78482] = {category="lo"}, +[78483] = {category="lo"}, +[78484] = {category="lo"}, +[78485] = {category="lo"}, +[78486] = {category="lo"}, +[78487] = {category="lo"}, +[78488] = {category="lo"}, +[78489] = {category="lo"}, +[78490] = {category="lo"}, +[78491] = {category="lo"}, +[78492] = {category="lo"}, +[78493] = {category="lo"}, +[78494] = {category="lo"}, +[78495] = {category="lo"}, +[78496] = {category="lo"}, +[78497] = {category="lo"}, +[78498] = {category="lo"}, +[78499] = {category="lo"}, +[78500] = {category="lo"}, +[78501] = {category="lo"}, +[78502] = {category="lo"}, +[78503] = {category="lo"}, +[78504] = {category="lo"}, +[78505] = {category="lo"}, +[78506] = {category="lo"}, +[78507] = {category="lo"}, +[78508] = {category="lo"}, +[78509] = {category="lo"}, +[78510] = {category="lo"}, +[78511] = {category="lo"}, +[78512] = {category="lo"}, +[78513] = {category="lo"}, +[78514] = {category="lo"}, +[78515] = {category="lo"}, +[78516] = {category="lo"}, +[78517] = {category="lo"}, +[78518] = {category="lo"}, +[78519] = {category="lo"}, +[78520] = {category="lo"}, +[78521] = {category="lo"}, +[78522] = {category="lo"}, +[78523] = {category="lo"}, +[78524] = {category="lo"}, +[78525] = {category="lo"}, +[78526] = {category="lo"}, +[78527] = {category="lo"}, +[78528] = {category="lo"}, +[78529] = {category="lo"}, +[78530] = {category="lo"}, +[78531] = {category="lo"}, +[78532] = {category="lo"}, +[78533] = {category="lo"}, +[78534] = {category="lo"}, +[78535] = {category="lo"}, +[78536] = {category="lo"}, +[78537] = {category="lo"}, +[78538] = {category="lo"}, +[78539] = {category="lo"}, +[78540] = {category="lo"}, +[78541] = {category="lo"}, +[78542] = {category="lo"}, +[78543] = {category="lo"}, +[78544] = {category="lo"}, +[78545] = {category="lo"}, +[78546] = {category="lo"}, +[78547] = {category="lo"}, +[78548] = {category="lo"}, +[78549] = {category="lo"}, +[78550] = {category="lo"}, +[78551] = {category="lo"}, +[78552] = {category="lo"}, +[78553] = {category="lo"}, +[78554] = {category="lo"}, +[78555] = {category="lo"}, +[78556] = {category="lo"}, +[78557] = {category="lo"}, +[78558] = {category="lo"}, +[78559] = {category="lo"}, +[78560] = {category="lo"}, +[78561] = {category="lo"}, +[78562] = {category="lo"}, +[78563] = {category="lo"}, +[78564] = {category="lo"}, +[78565] = {category="lo"}, +[78566] = {category="lo"}, +[78567] = {category="lo"}, +[78568] = {category="lo"}, +[78569] = {category="lo"}, +[78570] = {category="lo"}, +[78571] = {category="lo"}, +[78572] = {category="lo"}, +[78573] = {category="lo"}, +[78574] = {category="lo"}, +[78575] = {category="lo"}, +[78576] = {category="lo"}, +[78577] = {category="lo"}, +[78578] = {category="lo"}, +[78579] = {category="lo"}, +[78580] = {category="lo"}, +[78581] = {category="lo"}, +[78582] = {category="lo"}, +[78583] = {category="lo"}, +[78584] = {category="lo"}, +[78585] = {category="lo"}, +[78586] = {category="lo"}, +[78587] = {category="lo"}, +[78588] = {category="lo"}, +[78589] = {category="lo"}, +[78590] = {category="lo"}, +[78591] = {category="lo"}, +[78592] = {category="lo"}, +[78593] = {category="lo"}, +[78594] = {category="lo"}, +[78595] = {category="lo"}, +[78596] = {category="lo"}, +[78597] = {category="lo"}, +[78598] = {category="lo"}, +[78599] = {category="lo"}, +[78600] = {category="lo"}, +[78601] = {category="lo"}, +[78602] = {category="lo"}, +[78603] = {category="lo"}, +[78604] = {category="lo"}, +[78605] = {category="lo"}, +[78606] = {category="lo"}, +[78607] = {category="lo"}, +[78608] = {category="lo"}, +[78609] = {category="lo"}, +[78610] = {category="lo"}, +[78611] = {category="lo"}, +[78612] = {category="lo"}, +[78613] = {category="lo"}, +[78614] = {category="lo"}, +[78615] = {category="lo"}, +[78616] = {category="lo"}, +[78617] = {category="lo"}, +[78618] = {category="lo"}, +[78619] = {category="lo"}, +[78620] = {category="lo"}, +[78621] = {category="lo"}, +[78622] = {category="lo"}, +[78623] = {category="lo"}, +[78624] = {category="lo"}, +[78625] = {category="lo"}, +[78626] = {category="lo"}, +[78627] = {category="lo"}, +[78628] = {category="lo"}, +[78629] = {category="lo"}, +[78630] = {category="lo"}, +[78631] = {category="lo"}, +[78632] = {category="lo"}, +[78633] = {category="lo"}, +[78634] = {category="lo"}, +[78635] = {category="lo"}, +[78636] = {category="lo"}, +[78637] = {category="lo"}, +[78638] = {category="lo"}, +[78639] = {category="lo"}, +[78640] = {category="lo"}, +[78641] = {category="lo"}, +[78642] = {category="lo"}, +[78643] = {category="lo"}, +[78644] = {category="lo"}, +[78645] = {category="lo"}, +[78646] = {category="lo"}, +[78647] = {category="lo"}, +[78648] = {category="lo"}, +[78649] = {category="lo"}, +[78650] = {category="lo"}, +[78651] = {category="lo"}, +[78652] = {category="lo"}, +[78653] = {category="lo"}, +[78654] = {category="lo"}, +[78655] = {category="lo"}, +[78656] = {category="lo"}, +[78657] = {category="lo"}, +[78658] = {category="lo"}, +[78659] = {category="lo"}, +[78660] = {category="lo"}, +[78661] = {category="lo"}, +[78662] = {category="lo"}, +[78663] = {category="lo"}, +[78664] = {category="lo"}, +[78665] = {category="lo"}, +[78666] = {category="lo"}, +[78667] = {category="lo"}, +[78668] = {category="lo"}, +[78669] = {category="lo"}, +[78670] = {category="lo"}, +[78671] = {category="lo"}, +[78672] = {category="lo"}, +[78673] = {category="lo"}, +[78674] = {category="lo"}, +[78675] = {category="lo"}, +[78676] = {category="lo"}, +[78677] = {category="lo"}, +[78678] = {category="lo"}, +[78679] = {category="lo"}, +[78680] = {category="lo"}, +[78681] = {category="lo"}, +[78682] = {category="lo"}, +[78683] = {category="lo"}, +[78684] = {category="lo"}, +[78685] = {category="lo"}, +[78686] = {category="lo"}, +[78687] = {category="lo"}, +[78688] = {category="lo"}, +[78689] = {category="lo"}, +[78690] = {category="lo"}, +[78691] = {category="lo"}, +[78692] = {category="lo"}, +[78693] = {category="lo"}, +[78694] = {category="lo"}, +[78695] = {category="lo"}, +[78696] = {category="lo"}, +[78697] = {category="lo"}, +[78698] = {category="lo"}, +[78699] = {category="lo"}, +[78700] = {category="lo"}, +[78701] = {category="lo"}, +[78702] = {category="lo"}, +[78703] = {category="lo"}, +[78704] = {category="lo"}, +[78705] = {category="lo"}, +[78706] = {category="lo"}, +[78707] = {category="lo"}, +[78708] = {category="lo"}, +[78709] = {category="lo"}, +[78710] = {category="lo"}, +[78711] = {category="lo"}, +[78712] = {category="lo"}, +[78713] = {category="lo"}, +[78714] = {category="lo"}, +[78715] = {category="lo"}, +[78716] = {category="lo"}, +[78717] = {category="lo"}, +[78718] = {category="lo"}, +[78719] = {category="lo"}, +[78720] = {category="lo"}, +[78721] = {category="lo"}, +[78722] = {category="lo"}, +[78723] = {category="lo"}, +[78724] = {category="lo"}, +[78725] = {category="lo"}, +[78726] = {category="lo"}, +[78727] = {category="lo"}, +[78728] = {category="lo"}, +[78729] = {category="lo"}, +[78730] = {category="lo"}, +[78731] = {category="lo"}, +[78732] = {category="lo"}, +[78733] = {category="lo"}, +[78734] = {category="lo"}, +[78735] = {category="lo"}, +[78736] = {category="lo"}, +[78737] = {category="lo"}, +[78738] = {category="lo"}, +[78739] = {category="lo"}, +[78740] = {category="lo"}, +[78741] = {category="lo"}, +[78742] = {category="lo"}, +[78743] = {category="lo"}, +[78744] = {category="lo"}, +[78745] = {category="lo"}, +[78746] = {category="lo"}, +[78747] = {category="lo"}, +[78748] = {category="lo"}, +[78749] = {category="lo"}, +[78750] = {category="lo"}, +[78751] = {category="lo"}, +[78752] = {category="lo"}, +[78753] = {category="lo"}, +[78754] = {category="lo"}, +[78755] = {category="lo"}, +[78756] = {category="lo"}, +[78757] = {category="lo"}, +[78758] = {category="lo"}, +[78759] = {category="lo"}, +[78760] = {category="lo"}, +[78761] = {category="lo"}, +[78762] = {category="lo"}, +[78763] = {category="lo"}, +[78764] = {category="lo"}, +[78765] = {category="lo"}, +[78766] = {category="lo"}, +[78767] = {category="lo"}, +[78768] = {category="lo"}, +[78769] = {category="lo"}, +[78770] = {category="lo"}, +[78771] = {category="lo"}, +[78772] = {category="lo"}, +[78773] = {category="lo"}, +[78774] = {category="lo"}, +[78775] = {category="lo"}, +[78776] = {category="lo"}, +[78777] = {category="lo"}, +[78778] = {category="lo"}, +[78779] = {category="lo"}, +[78780] = {category="lo"}, +[78781] = {category="lo"}, +[78782] = {category="lo"}, +[78783] = {category="lo"}, +[78784] = {category="lo"}, +[78785] = {category="lo"}, +[78786] = {category="lo"}, +[78787] = {category="lo"}, +[78788] = {category="lo"}, +[78789] = {category="lo"}, +[78790] = {category="lo"}, +[78791] = {category="lo"}, +[78792] = {category="lo"}, +[78793] = {category="lo"}, +[78794] = {category="lo"}, +[78795] = {category="lo"}, +[78796] = {category="lo"}, +[78797] = {category="lo"}, +[78798] = {category="lo"}, +[78799] = {category="lo"}, +[78800] = {category="lo"}, +[78801] = {category="lo"}, +[78802] = {category="lo"}, +[78803] = {category="lo"}, +[78804] = {category="lo"}, +[78805] = {category="lo"}, +[78806] = {category="lo"}, +[78807] = {category="lo"}, +[78808] = {category="lo"}, +[78809] = {category="lo"}, +[78810] = {category="lo"}, +[78811] = {category="lo"}, +[78812] = {category="lo"}, +[78813] = {category="lo"}, +[78814] = {category="lo"}, +[78815] = {category="lo"}, +[78816] = {category="lo"}, +[78817] = {category="lo"}, +[78818] = {category="lo"}, +[78819] = {category="lo"}, +[78820] = {category="lo"}, +[78821] = {category="lo"}, +[78822] = {category="lo"}, +[78823] = {category="lo"}, +[78824] = {category="lo"}, +[78825] = {category="lo"}, +[78826] = {category="lo"}, +[78827] = {category="lo"}, +[78828] = {category="lo"}, +[78829] = {category="lo"}, +[78830] = {category="lo"}, +[78831] = {category="lo"}, +[78832] = {category="lo"}, +[78833] = {category="lo"}, +[78834] = {category="lo"}, +[78835] = {category="lo"}, +[78836] = {category="lo"}, +[78837] = {category="lo"}, +[78838] = {category="lo"}, +[78839] = {category="lo"}, +[78840] = {category="lo"}, +[78841] = {category="lo"}, +[78842] = {category="lo"}, +[78843] = {category="lo"}, +[78844] = {category="lo"}, +[78845] = {category="lo"}, +[78846] = {category="lo"}, +[78847] = {category="lo"}, +[78848] = {category="lo"}, +[78849] = {category="lo"}, +[78850] = {category="lo"}, +[78851] = {category="lo"}, +[78852] = {category="lo"}, +[78853] = {category="lo"}, +[78854] = {category="lo"}, +[78855] = {category="lo"}, +[78856] = {category="lo"}, +[78857] = {category="lo"}, +[78858] = {category="lo"}, +[78859] = {category="lo"}, +[78860] = {category="lo"}, +[78861] = {category="lo"}, +[78862] = {category="lo"}, +[78863] = {category="lo"}, +[78864] = {category="lo"}, +[78865] = {category="lo"}, +[78866] = {category="lo"}, +[78867] = {category="lo"}, +[78868] = {category="lo"}, +[78869] = {category="lo"}, +[78870] = {category="lo"}, +[78871] = {category="lo"}, +[78872] = {category="lo"}, +[78873] = {category="lo"}, +[78874] = {category="lo"}, +[78875] = {category="lo"}, +[78876] = {category="lo"}, +[78877] = {category="lo"}, +[78878] = {category="lo"}, +[78879] = {category="lo"}, +[78880] = {category="lo"}, +[78881] = {category="lo"}, +[78882] = {category="lo"}, +[78883] = {category="lo"}, +[78884] = {category="lo"}, +[78885] = {category="lo"}, +[78886] = {category="lo"}, +[78887] = {category="lo"}, +[78888] = {category="lo"}, +[78889] = {category="lo"}, +[78890] = {category="lo"}, +[78891] = {category="lo"}, +[78892] = {category="lo"}, +[78893] = {category="lo"}, +[78894] = {category="lo"}, +[78895] = {category="lo"}, +[78913] = {category="lo"}, +[78914] = {category="lo"}, +[78915] = {category="lo"}, +[78916] = {category="lo"}, +[78917] = {category="lo"}, +[78918] = {category="lo"}, +[82944] = {category="lo"}, +[82945] = {category="lo"}, +[82946] = {category="lo"}, +[82947] = {category="lo"}, +[82948] = {category="lo"}, +[82949] = {category="lo"}, +[82950] = {category="lo"}, +[82951] = {category="lo"}, +[82952] = {category="lo"}, +[82953] = {category="lo"}, +[82954] = {category="lo"}, +[82955] = {category="lo"}, +[82956] = {category="lo"}, +[82957] = {category="lo"}, +[82958] = {category="lo"}, +[82959] = {category="lo"}, +[82960] = {category="lo"}, +[82961] = {category="lo"}, +[82962] = {category="lo"}, +[82963] = {category="lo"}, +[82964] = {category="lo"}, +[82965] = {category="lo"}, +[82966] = {category="lo"}, +[82967] = {category="lo"}, +[82968] = {category="lo"}, +[82969] = {category="lo"}, +[82970] = {category="lo"}, +[82971] = {category="lo"}, +[82972] = {category="lo"}, +[82973] = {category="lo"}, +[82974] = {category="lo"}, +[82975] = {category="lo"}, +[82976] = {category="lo"}, +[82977] = {category="lo"}, +[82978] = {category="lo"}, +[82979] = {category="lo"}, +[82980] = {category="lo"}, +[82981] = {category="lo"}, +[82982] = {category="lo"}, +[82983] = {category="lo"}, +[82984] = {category="lo"}, +[82985] = {category="lo"}, +[82986] = {category="lo"}, +[82987] = {category="lo"}, +[82988] = {category="lo"}, +[82989] = {category="lo"}, +[82990] = {category="lo"}, +[82991] = {category="lo"}, +[82992] = {category="lo"}, +[82993] = {category="lo"}, +[82994] = {category="lo"}, +[82995] = {category="lo"}, +[82996] = {category="lo"}, +[82997] = {category="lo"}, +[82998] = {category="lo"}, +[82999] = {category="lo"}, +[83000] = {category="lo"}, +[83001] = {category="lo"}, +[83002] = {category="lo"}, +[83003] = {category="lo"}, +[83004] = {category="lo"}, +[83005] = {category="lo"}, +[83006] = {category="lo"}, +[83007] = {category="lo"}, +[83008] = {category="lo"}, +[83009] = {category="lo"}, +[83010] = {category="lo"}, +[83011] = {category="lo"}, +[83012] = {category="lo"}, +[83013] = {category="lo"}, +[83014] = {category="lo"}, +[83015] = {category="lo"}, +[83016] = {category="lo"}, +[83017] = {category="lo"}, +[83018] = {category="lo"}, +[83019] = {category="lo"}, +[83020] = {category="lo"}, +[83021] = {category="lo"}, +[83022] = {category="lo"}, +[83023] = {category="lo"}, +[83024] = {category="lo"}, +[83025] = {category="lo"}, +[83026] = {category="lo"}, +[83027] = {category="lo"}, +[83028] = {category="lo"}, +[83029] = {category="lo"}, +[83030] = {category="lo"}, +[83031] = {category="lo"}, +[83032] = {category="lo"}, +[83033] = {category="lo"}, +[83034] = {category="lo"}, +[83035] = {category="lo"}, +[83036] = {category="lo"}, +[83037] = {category="lo"}, +[83038] = {category="lo"}, +[83039] = {category="lo"}, +[83040] = {category="lo"}, +[83041] = {category="lo"}, +[83042] = {category="lo"}, +[83043] = {category="lo"}, +[83044] = {category="lo"}, +[83045] = {category="lo"}, +[83046] = {category="lo"}, +[83047] = {category="lo"}, +[83048] = {category="lo"}, +[83049] = {category="lo"}, +[83050] = {category="lo"}, +[83051] = {category="lo"}, +[83052] = {category="lo"}, +[83053] = {category="lo"}, +[83054] = {category="lo"}, +[83055] = {category="lo"}, +[83056] = {category="lo"}, +[83057] = {category="lo"}, +[83058] = {category="lo"}, +[83059] = {category="lo"}, +[83060] = {category="lo"}, +[83061] = {category="lo"}, +[83062] = {category="lo"}, +[83063] = {category="lo"}, +[83064] = {category="lo"}, +[83065] = {category="lo"}, +[83066] = {category="lo"}, +[83067] = {category="lo"}, +[83068] = {category="lo"}, +[83069] = {category="lo"}, +[83070] = {category="lo"}, +[83071] = {category="lo"}, +[83072] = {category="lo"}, +[83073] = {category="lo"}, +[83074] = {category="lo"}, +[83075] = {category="lo"}, +[83076] = {category="lo"}, +[83077] = {category="lo"}, +[83078] = {category="lo"}, +[83079] = {category="lo"}, +[83080] = {category="lo"}, +[83081] = {category="lo"}, +[83082] = {category="lo"}, +[83083] = {category="lo"}, +[83084] = {category="lo"}, +[83085] = {category="lo"}, +[83086] = {category="lo"}, +[83087] = {category="lo"}, +[83088] = {category="lo"}, +[83089] = {category="lo"}, +[83090] = {category="lo"}, +[83091] = {category="lo"}, +[83092] = {category="lo"}, +[83093] = {category="lo"}, +[83094] = {category="lo"}, +[83095] = {category="lo"}, +[83096] = {category="lo"}, +[83097] = {category="lo"}, +[83098] = {category="lo"}, +[83099] = {category="lo"}, +[83100] = {category="lo"}, +[83101] = {category="lo"}, +[83102] = {category="lo"}, +[83103] = {category="lo"}, +[83104] = {category="lo"}, +[83105] = {category="lo"}, +[83106] = {category="lo"}, +[83107] = {category="lo"}, +[83108] = {category="lo"}, +[83109] = {category="lo"}, +[83110] = {category="lo"}, +[83111] = {category="lo"}, +[83112] = {category="lo"}, +[83113] = {category="lo"}, +[83114] = {category="lo"}, +[83115] = {category="lo"}, +[83116] = {category="lo"}, +[83117] = {category="lo"}, +[83118] = {category="lo"}, +[83119] = {category="lo"}, +[83120] = {category="lo"}, +[83121] = {category="lo"}, +[83122] = {category="lo"}, +[83123] = {category="lo"}, +[83124] = {category="lo"}, +[83125] = {category="lo"}, +[83126] = {category="lo"}, +[83127] = {category="lo"}, +[83128] = {category="lo"}, +[83129] = {category="lo"}, +[83130] = {category="lo"}, +[83131] = {category="lo"}, +[83132] = {category="lo"}, +[83133] = {category="lo"}, +[83134] = {category="lo"}, +[83135] = {category="lo"}, +[83136] = {category="lo"}, +[83137] = {category="lo"}, +[83138] = {category="lo"}, +[83139] = {category="lo"}, +[83140] = {category="lo"}, +[83141] = {category="lo"}, +[83142] = {category="lo"}, +[83143] = {category="lo"}, +[83144] = {category="lo"}, +[83145] = {category="lo"}, +[83146] = {category="lo"}, +[83147] = {category="lo"}, +[83148] = {category="lo"}, +[83149] = {category="lo"}, +[83150] = {category="lo"}, +[83151] = {category="lo"}, +[83152] = {category="lo"}, +[83153] = {category="lo"}, +[83154] = {category="lo"}, +[83155] = {category="lo"}, +[83156] = {category="lo"}, +[83157] = {category="lo"}, +[83158] = {category="lo"}, +[83159] = {category="lo"}, +[83160] = {category="lo"}, +[83161] = {category="lo"}, +[83162] = {category="lo"}, +[83163] = {category="lo"}, +[83164] = {category="lo"}, +[83165] = {category="lo"}, +[83166] = {category="lo"}, +[83167] = {category="lo"}, +[83168] = {category="lo"}, +[83169] = {category="lo"}, +[83170] = {category="lo"}, +[83171] = {category="lo"}, +[83172] = {category="lo"}, +[83173] = {category="lo"}, +[83174] = {category="lo"}, +[83175] = {category="lo"}, +[83176] = {category="lo"}, +[83177] = {category="lo"}, +[83178] = {category="lo"}, +[83179] = {category="lo"}, +[83180] = {category="lo"}, +[83181] = {category="lo"}, +[83182] = {category="lo"}, +[83183] = {category="lo"}, +[83184] = {category="lo"}, +[83185] = {category="lo"}, +[83186] = {category="lo"}, +[83187] = {category="lo"}, +[83188] = {category="lo"}, +[83189] = {category="lo"}, +[83190] = {category="lo"}, +[83191] = {category="lo"}, +[83192] = {category="lo"}, +[83193] = {category="lo"}, +[83194] = {category="lo"}, +[83195] = {category="lo"}, +[83196] = {category="lo"}, +[83197] = {category="lo"}, +[83198] = {category="lo"}, +[83199] = {category="lo"}, +[83200] = {category="lo"}, +[83201] = {category="lo"}, +[83202] = {category="lo"}, +[83203] = {category="lo"}, +[83204] = {category="lo"}, +[83205] = {category="lo"}, +[83206] = {category="lo"}, +[83207] = {category="lo"}, +[83208] = {category="lo"}, +[83209] = {category="lo"}, +[83210] = {category="lo"}, +[83211] = {category="lo"}, +[83212] = {category="lo"}, +[83213] = {category="lo"}, +[83214] = {category="lo"}, +[83215] = {category="lo"}, +[83216] = {category="lo"}, +[83217] = {category="lo"}, +[83218] = {category="lo"}, +[83219] = {category="lo"}, +[83220] = {category="lo"}, +[83221] = {category="lo"}, +[83222] = {category="lo"}, +[83223] = {category="lo"}, +[83224] = {category="lo"}, +[83225] = {category="lo"}, +[83226] = {category="lo"}, +[83227] = {category="lo"}, +[83228] = {category="lo"}, +[83229] = {category="lo"}, +[83230] = {category="lo"}, +[83231] = {category="lo"}, +[83232] = {category="lo"}, +[83233] = {category="lo"}, +[83234] = {category="lo"}, +[83235] = {category="lo"}, +[83236] = {category="lo"}, +[83237] = {category="lo"}, +[83238] = {category="lo"}, +[83239] = {category="lo"}, +[83240] = {category="lo"}, +[83241] = {category="lo"}, +[83242] = {category="lo"}, +[83243] = {category="lo"}, +[83244] = {category="lo"}, +[83245] = {category="lo"}, +[83246] = {category="lo"}, +[83247] = {category="lo"}, +[83248] = {category="lo"}, +[83249] = {category="lo"}, +[83250] = {category="lo"}, +[83251] = {category="lo"}, +[83252] = {category="lo"}, +[83253] = {category="lo"}, +[83254] = {category="lo"}, +[83255] = {category="lo"}, +[83256] = {category="lo"}, +[83257] = {category="lo"}, +[83258] = {category="lo"}, +[83259] = {category="lo"}, +[83260] = {category="lo"}, +[83261] = {category="lo"}, +[83262] = {category="lo"}, +[83263] = {category="lo"}, +[83264] = {category="lo"}, +[83265] = {category="lo"}, +[83266] = {category="lo"}, +[83267] = {category="lo"}, +[83268] = {category="lo"}, +[83269] = {category="lo"}, +[83270] = {category="lo"}, +[83271] = {category="lo"}, +[83272] = {category="lo"}, +[83273] = {category="lo"}, +[83274] = {category="lo"}, +[83275] = {category="lo"}, +[83276] = {category="lo"}, +[83277] = {category="lo"}, +[83278] = {category="lo"}, +[83279] = {category="lo"}, +[83280] = {category="lo"}, +[83281] = {category="lo"}, +[83282] = {category="lo"}, +[83283] = {category="lo"}, +[83284] = {category="lo"}, +[83285] = {category="lo"}, +[83286] = {category="lo"}, +[83287] = {category="lo"}, +[83288] = {category="lo"}, +[83289] = {category="lo"}, +[83290] = {category="lo"}, +[83291] = {category="lo"}, +[83292] = {category="lo"}, +[83293] = {category="lo"}, +[83294] = {category="lo"}, +[83295] = {category="lo"}, +[83296] = {category="lo"}, +[83297] = {category="lo"}, +[83298] = {category="lo"}, +[83299] = {category="lo"}, +[83300] = {category="lo"}, +[83301] = {category="lo"}, +[83302] = {category="lo"}, +[83303] = {category="lo"}, +[83304] = {category="lo"}, +[83305] = {category="lo"}, +[83306] = {category="lo"}, +[83307] = {category="lo"}, +[83308] = {category="lo"}, +[83309] = {category="lo"}, +[83310] = {category="lo"}, +[83311] = {category="lo"}, +[83312] = {category="lo"}, +[83313] = {category="lo"}, +[83314] = {category="lo"}, +[83315] = {category="lo"}, +[83316] = {category="lo"}, +[83317] = {category="lo"}, +[83318] = {category="lo"}, +[83319] = {category="lo"}, +[83320] = {category="lo"}, +[83321] = {category="lo"}, +[83322] = {category="lo"}, +[83323] = {category="lo"}, +[83324] = {category="lo"}, +[83325] = {category="lo"}, +[83326] = {category="lo"}, +[83327] = {category="lo"}, +[83328] = {category="lo"}, +[83329] = {category="lo"}, +[83330] = {category="lo"}, +[83331] = {category="lo"}, +[83332] = {category="lo"}, +[83333] = {category="lo"}, +[83334] = {category="lo"}, +[83335] = {category="lo"}, +[83336] = {category="lo"}, +[83337] = {category="lo"}, +[83338] = {category="lo"}, +[83339] = {category="lo"}, +[83340] = {category="lo"}, +[83341] = {category="lo"}, +[83342] = {category="lo"}, +[83343] = {category="lo"}, +[83344] = {category="lo"}, +[83345] = {category="lo"}, +[83346] = {category="lo"}, +[83347] = {category="lo"}, +[83348] = {category="lo"}, +[83349] = {category="lo"}, +[83350] = {category="lo"}, +[83351] = {category="lo"}, +[83352] = {category="lo"}, +[83353] = {category="lo"}, +[83354] = {category="lo"}, +[83355] = {category="lo"}, +[83356] = {category="lo"}, +[83357] = {category="lo"}, +[83358] = {category="lo"}, +[83359] = {category="lo"}, +[83360] = {category="lo"}, +[83361] = {category="lo"}, +[83362] = {category="lo"}, +[83363] = {category="lo"}, +[83364] = {category="lo"}, +[83365] = {category="lo"}, +[83366] = {category="lo"}, +[83367] = {category="lo"}, +[83368] = {category="lo"}, +[83369] = {category="lo"}, +[83370] = {category="lo"}, +[83371] = {category="lo"}, +[83372] = {category="lo"}, +[83373] = {category="lo"}, +[83374] = {category="lo"}, +[83375] = {category="lo"}, +[83376] = {category="lo"}, +[83377] = {category="lo"}, +[83378] = {category="lo"}, +[83379] = {category="lo"}, +[83380] = {category="lo"}, +[83381] = {category="lo"}, +[83382] = {category="lo"}, +[83383] = {category="lo"}, +[83384] = {category="lo"}, +[83385] = {category="lo"}, +[83386] = {category="lo"}, +[83387] = {category="lo"}, +[83388] = {category="lo"}, +[83389] = {category="lo"}, +[83390] = {category="lo"}, +[83391] = {category="lo"}, +[83392] = {category="lo"}, +[83393] = {category="lo"}, +[83394] = {category="lo"}, +[83395] = {category="lo"}, +[83396] = {category="lo"}, +[83397] = {category="lo"}, +[83398] = {category="lo"}, +[83399] = {category="lo"}, +[83400] = {category="lo"}, +[83401] = {category="lo"}, +[83402] = {category="lo"}, +[83403] = {category="lo"}, +[83404] = {category="lo"}, +[83405] = {category="lo"}, +[83406] = {category="lo"}, +[83407] = {category="lo"}, +[83408] = {category="lo"}, +[83409] = {category="lo"}, +[83410] = {category="lo"}, +[83411] = {category="lo"}, +[83412] = {category="lo"}, +[83413] = {category="lo"}, +[83414] = {category="lo"}, +[83415] = {category="lo"}, +[83416] = {category="lo"}, +[83417] = {category="lo"}, +[83418] = {category="lo"}, +[83419] = {category="lo"}, +[83420] = {category="lo"}, +[83421] = {category="lo"}, +[83422] = {category="lo"}, +[83423] = {category="lo"}, +[83424] = {category="lo"}, +[83425] = {category="lo"}, +[83426] = {category="lo"}, +[83427] = {category="lo"}, +[83428] = {category="lo"}, +[83429] = {category="lo"}, +[83430] = {category="lo"}, +[83431] = {category="lo"}, +[83432] = {category="lo"}, +[83433] = {category="lo"}, +[83434] = {category="lo"}, +[83435] = {category="lo"}, +[83436] = {category="lo"}, +[83437] = {category="lo"}, +[83438] = {category="lo"}, +[83439] = {category="lo"}, +[83440] = {category="lo"}, +[83441] = {category="lo"}, +[83442] = {category="lo"}, +[83443] = {category="lo"}, +[83444] = {category="lo"}, +[83445] = {category="lo"}, +[83446] = {category="lo"}, +[83447] = {category="lo"}, +[83448] = {category="lo"}, +[83449] = {category="lo"}, +[83450] = {category="lo"}, +[83451] = {category="lo"}, +[83452] = {category="lo"}, +[83453] = {category="lo"}, +[83454] = {category="lo"}, +[83455] = {category="lo"}, +[83456] = {category="lo"}, +[83457] = {category="lo"}, +[83458] = {category="lo"}, +[83459] = {category="lo"}, +[83460] = {category="lo"}, +[83461] = {category="lo"}, +[83462] = {category="lo"}, +[83463] = {category="lo"}, +[83464] = {category="lo"}, +[83465] = {category="lo"}, +[83466] = {category="lo"}, +[83467] = {category="lo"}, +[83468] = {category="lo"}, +[83469] = {category="lo"}, +[83470] = {category="lo"}, +[83471] = {category="lo"}, +[83472] = {category="lo"}, +[83473] = {category="lo"}, +[83474] = {category="lo"}, +[83475] = {category="lo"}, +[83476] = {category="lo"}, +[83477] = {category="lo"}, +[83478] = {category="lo"}, +[83479] = {category="lo"}, +[83480] = {category="lo"}, +[83481] = {category="lo"}, +[83482] = {category="lo"}, +[83483] = {category="lo"}, +[83484] = {category="lo"}, +[83485] = {category="lo"}, +[83486] = {category="lo"}, +[83487] = {category="lo"}, +[83488] = {category="lo"}, +[83489] = {category="lo"}, +[83490] = {category="lo"}, +[83491] = {category="lo"}, +[83492] = {category="lo"}, +[83493] = {category="lo"}, +[83494] = {category="lo"}, +[83495] = {category="lo"}, +[83496] = {category="lo"}, +[83497] = {category="lo"}, +[83498] = {category="lo"}, +[83499] = {category="lo"}, +[83500] = {category="lo"}, +[83501] = {category="lo"}, +[83502] = {category="lo"}, +[83503] = {category="lo"}, +[83504] = {category="lo"}, +[83505] = {category="lo"}, +[83506] = {category="lo"}, +[83507] = {category="lo"}, +[83508] = {category="lo"}, +[83509] = {category="lo"}, +[83510] = {category="lo"}, +[83511] = {category="lo"}, +[83512] = {category="lo"}, +[83513] = {category="lo"}, +[83514] = {category="lo"}, +[83515] = {category="lo"}, +[83516] = {category="lo"}, +[83517] = {category="lo"}, +[83518] = {category="lo"}, +[83519] = {category="lo"}, +[83520] = {category="lo"}, +[83521] = {category="lo"}, +[83522] = {category="lo"}, +[83523] = {category="lo"}, +[83524] = {category="lo"}, +[83525] = {category="lo"}, +[83526] = {category="lo"}, +[92160] = {category="lo"}, +[92161] = {category="lo"}, +[92162] = {category="lo"}, +[92163] = {category="lo"}, +[92164] = {category="lo"}, +[92165] = {category="lo"}, +[92166] = {category="lo"}, +[92167] = {category="lo"}, +[92168] = {category="lo"}, +[92169] = {category="lo"}, +[92170] = {category="lo"}, +[92171] = {category="lo"}, +[92172] = {category="lo"}, +[92173] = {category="lo"}, +[92174] = {category="lo"}, +[92175] = {category="lo"}, +[92176] = {category="lo"}, +[92177] = {category="lo"}, +[92178] = {category="lo"}, +[92179] = {category="lo"}, +[92180] = {category="lo"}, +[92181] = {category="lo"}, +[92182] = {category="lo"}, +[92183] = {category="lo"}, +[92184] = {category="lo"}, +[92185] = {category="lo"}, +[92186] = {category="lo"}, +[92187] = {category="lo"}, +[92188] = {category="lo"}, +[92189] = {category="lo"}, +[92190] = {category="lo"}, +[92191] = {category="lo"}, +[92192] = {category="lo"}, +[92193] = {category="lo"}, +[92194] = {category="lo"}, +[92195] = {category="lo"}, +[92196] = {category="lo"}, +[92197] = {category="lo"}, +[92198] = {category="lo"}, +[92199] = {category="lo"}, +[92200] = {category="lo"}, +[92201] = {category="lo"}, +[92202] = {category="lo"}, +[92203] = {category="lo"}, +[92204] = {category="lo"}, +[92205] = {category="lo"}, +[92206] = {category="lo"}, +[92207] = {category="lo"}, +[92208] = {category="lo"}, +[92209] = {category="lo"}, +[92210] = {category="lo"}, +[92211] = {category="lo"}, +[92212] = {category="lo"}, +[92213] = {category="lo"}, +[92214] = {category="lo"}, +[92215] = {category="lo"}, +[92216] = {category="lo"}, +[92217] = {category="lo"}, +[92218] = {category="lo"}, +[92219] = {category="lo"}, +[92220] = {category="lo"}, +[92221] = {category="lo"}, +[92222] = {category="lo"}, +[92223] = {category="lo"}, +[92224] = {category="lo"}, +[92225] = {category="lo"}, +[92226] = {category="lo"}, +[92227] = {category="lo"}, +[92228] = {category="lo"}, +[92229] = {category="lo"}, +[92230] = {category="lo"}, +[92231] = {category="lo"}, +[92232] = {category="lo"}, +[92233] = {category="lo"}, +[92234] = {category="lo"}, +[92235] = {category="lo"}, +[92236] = {category="lo"}, +[92237] = {category="lo"}, +[92238] = {category="lo"}, +[92239] = {category="lo"}, +[92240] = {category="lo"}, +[92241] = {category="lo"}, +[92242] = {category="lo"}, +[92243] = {category="lo"}, +[92244] = {category="lo"}, +[92245] = {category="lo"}, +[92246] = {category="lo"}, +[92247] = {category="lo"}, +[92248] = {category="lo"}, +[92249] = {category="lo"}, +[92250] = {category="lo"}, +[92251] = {category="lo"}, +[92252] = {category="lo"}, +[92253] = {category="lo"}, +[92254] = {category="lo"}, +[92255] = {category="lo"}, +[92256] = {category="lo"}, +[92257] = {category="lo"}, +[92258] = {category="lo"}, +[92259] = {category="lo"}, +[92260] = {category="lo"}, +[92261] = {category="lo"}, +[92262] = {category="lo"}, +[92263] = {category="lo"}, +[92264] = {category="lo"}, +[92265] = {category="lo"}, +[92266] = {category="lo"}, +[92267] = {category="lo"}, +[92268] = {category="lo"}, +[92269] = {category="lo"}, +[92270] = {category="lo"}, +[92271] = {category="lo"}, +[92272] = {category="lo"}, +[92273] = {category="lo"}, +[92274] = {category="lo"}, +[92275] = {category="lo"}, +[92276] = {category="lo"}, +[92277] = {category="lo"}, +[92278] = {category="lo"}, +[92279] = {category="lo"}, +[92280] = {category="lo"}, +[92281] = {category="lo"}, +[92282] = {category="lo"}, +[92283] = {category="lo"}, +[92284] = {category="lo"}, +[92285] = {category="lo"}, +[92286] = {category="lo"}, +[92287] = {category="lo"}, +[92288] = {category="lo"}, +[92289] = {category="lo"}, +[92290] = {category="lo"}, +[92291] = {category="lo"}, +[92292] = {category="lo"}, +[92293] = {category="lo"}, +[92294] = {category="lo"}, +[92295] = {category="lo"}, +[92296] = {category="lo"}, +[92297] = {category="lo"}, +[92298] = {category="lo"}, +[92299] = {category="lo"}, +[92300] = {category="lo"}, +[92301] = {category="lo"}, +[92302] = {category="lo"}, +[92303] = {category="lo"}, +[92304] = {category="lo"}, +[92305] = {category="lo"}, +[92306] = {category="lo"}, +[92307] = {category="lo"}, +[92308] = {category="lo"}, +[92309] = {category="lo"}, +[92310] = {category="lo"}, +[92311] = {category="lo"}, +[92312] = {category="lo"}, +[92313] = {category="lo"}, +[92314] = {category="lo"}, +[92315] = {category="lo"}, +[92316] = {category="lo"}, +[92317] = {category="lo"}, +[92318] = {category="lo"}, +[92319] = {category="lo"}, +[92320] = {category="lo"}, +[92321] = {category="lo"}, +[92322] = {category="lo"}, +[92323] = {category="lo"}, +[92324] = {category="lo"}, +[92325] = {category="lo"}, +[92326] = {category="lo"}, +[92327] = {category="lo"}, +[92328] = {category="lo"}, +[92329] = {category="lo"}, +[92330] = {category="lo"}, +[92331] = {category="lo"}, +[92332] = {category="lo"}, +[92333] = {category="lo"}, +[92334] = {category="lo"}, +[92335] = {category="lo"}, +[92336] = {category="lo"}, +[92337] = {category="lo"}, +[92338] = {category="lo"}, +[92339] = {category="lo"}, +[92340] = {category="lo"}, +[92341] = {category="lo"}, +[92342] = {category="lo"}, +[92343] = {category="lo"}, +[92344] = {category="lo"}, +[92345] = {category="lo"}, +[92346] = {category="lo"}, +[92347] = {category="lo"}, +[92348] = {category="lo"}, +[92349] = {category="lo"}, +[92350] = {category="lo"}, +[92351] = {category="lo"}, +[92352] = {category="lo"}, +[92353] = {category="lo"}, +[92354] = {category="lo"}, +[92355] = {category="lo"}, +[92356] = {category="lo"}, +[92357] = {category="lo"}, +[92358] = {category="lo"}, +[92359] = {category="lo"}, +[92360] = {category="lo"}, +[92361] = {category="lo"}, +[92362] = {category="lo"}, +[92363] = {category="lo"}, +[92364] = {category="lo"}, +[92365] = {category="lo"}, +[92366] = {category="lo"}, +[92367] = {category="lo"}, +[92368] = {category="lo"}, +[92369] = {category="lo"}, +[92370] = {category="lo"}, +[92371] = {category="lo"}, +[92372] = {category="lo"}, +[92373] = {category="lo"}, +[92374] = {category="lo"}, +[92375] = {category="lo"}, +[92376] = {category="lo"}, +[92377] = {category="lo"}, +[92378] = {category="lo"}, +[92379] = {category="lo"}, +[92380] = {category="lo"}, +[92381] = {category="lo"}, +[92382] = {category="lo"}, +[92383] = {category="lo"}, +[92384] = {category="lo"}, +[92385] = {category="lo"}, +[92386] = {category="lo"}, +[92387] = {category="lo"}, +[92388] = {category="lo"}, +[92389] = {category="lo"}, +[92390] = {category="lo"}, +[92391] = {category="lo"}, +[92392] = {category="lo"}, +[92393] = {category="lo"}, +[92394] = {category="lo"}, +[92395] = {category="lo"}, +[92396] = {category="lo"}, +[92397] = {category="lo"}, +[92398] = {category="lo"}, +[92399] = {category="lo"}, +[92400] = {category="lo"}, +[92401] = {category="lo"}, +[92402] = {category="lo"}, +[92403] = {category="lo"}, +[92404] = {category="lo"}, +[92405] = {category="lo"}, +[92406] = {category="lo"}, +[92407] = {category="lo"}, +[92408] = {category="lo"}, +[92409] = {category="lo"}, +[92410] = {category="lo"}, +[92411] = {category="lo"}, +[92412] = {category="lo"}, +[92413] = {category="lo"}, +[92414] = {category="lo"}, +[92415] = {category="lo"}, +[92416] = {category="lo"}, +[92417] = {category="lo"}, +[92418] = {category="lo"}, +[92419] = {category="lo"}, +[92420] = {category="lo"}, +[92421] = {category="lo"}, +[92422] = {category="lo"}, +[92423] = {category="lo"}, +[92424] = {category="lo"}, +[92425] = {category="lo"}, +[92426] = {category="lo"}, +[92427] = {category="lo"}, +[92428] = {category="lo"}, +[92429] = {category="lo"}, +[92430] = {category="lo"}, +[92431] = {category="lo"}, +[92432] = {category="lo"}, +[92433] = {category="lo"}, +[92434] = {category="lo"}, +[92435] = {category="lo"}, +[92436] = {category="lo"}, +[92437] = {category="lo"}, +[92438] = {category="lo"}, +[92439] = {category="lo"}, +[92440] = {category="lo"}, +[92441] = {category="lo"}, +[92442] = {category="lo"}, +[92443] = {category="lo"}, +[92444] = {category="lo"}, +[92445] = {category="lo"}, +[92446] = {category="lo"}, +[92447] = {category="lo"}, +[92448] = {category="lo"}, +[92449] = {category="lo"}, +[92450] = {category="lo"}, +[92451] = {category="lo"}, +[92452] = {category="lo"}, +[92453] = {category="lo"}, +[92454] = {category="lo"}, +[92455] = {category="lo"}, +[92456] = {category="lo"}, +[92457] = {category="lo"}, +[92458] = {category="lo"}, +[92459] = {category="lo"}, +[92460] = {category="lo"}, +[92461] = {category="lo"}, +[92462] = {category="lo"}, +[92463] = {category="lo"}, +[92464] = {category="lo"}, +[92465] = {category="lo"}, +[92466] = {category="lo"}, +[92467] = {category="lo"}, +[92468] = {category="lo"}, +[92469] = {category="lo"}, +[92470] = {category="lo"}, +[92471] = {category="lo"}, +[92472] = {category="lo"}, +[92473] = {category="lo"}, +[92474] = {category="lo"}, +[92475] = {category="lo"}, +[92476] = {category="lo"}, +[92477] = {category="lo"}, +[92478] = {category="lo"}, +[92479] = {category="lo"}, +[92480] = {category="lo"}, +[92481] = {category="lo"}, +[92482] = {category="lo"}, +[92483] = {category="lo"}, +[92484] = {category="lo"}, +[92485] = {category="lo"}, +[92486] = {category="lo"}, +[92487] = {category="lo"}, +[92488] = {category="lo"}, +[92489] = {category="lo"}, +[92490] = {category="lo"}, +[92491] = {category="lo"}, +[92492] = {category="lo"}, +[92493] = {category="lo"}, +[92494] = {category="lo"}, +[92495] = {category="lo"}, +[92496] = {category="lo"}, +[92497] = {category="lo"}, +[92498] = {category="lo"}, +[92499] = {category="lo"}, +[92500] = {category="lo"}, +[92501] = {category="lo"}, +[92502] = {category="lo"}, +[92503] = {category="lo"}, +[92504] = {category="lo"}, +[92505] = {category="lo"}, +[92506] = {category="lo"}, +[92507] = {category="lo"}, +[92508] = {category="lo"}, +[92509] = {category="lo"}, +[92510] = {category="lo"}, +[92511] = {category="lo"}, +[92512] = {category="lo"}, +[92513] = {category="lo"}, +[92514] = {category="lo"}, +[92515] = {category="lo"}, +[92516] = {category="lo"}, +[92517] = {category="lo"}, +[92518] = {category="lo"}, +[92519] = {category="lo"}, +[92520] = {category="lo"}, +[92521] = {category="lo"}, +[92522] = {category="lo"}, +[92523] = {category="lo"}, +[92524] = {category="lo"}, +[92525] = {category="lo"}, +[92526] = {category="lo"}, +[92527] = {category="lo"}, +[92528] = {category="lo"}, +[92529] = {category="lo"}, +[92530] = {category="lo"}, +[92531] = {category="lo"}, +[92532] = {category="lo"}, +[92533] = {category="lo"}, +[92534] = {category="lo"}, +[92535] = {category="lo"}, +[92536] = {category="lo"}, +[92537] = {category="lo"}, +[92538] = {category="lo"}, +[92539] = {category="lo"}, +[92540] = {category="lo"}, +[92541] = {category="lo"}, +[92542] = {category="lo"}, +[92543] = {category="lo"}, +[92544] = {category="lo"}, +[92545] = {category="lo"}, +[92546] = {category="lo"}, +[92547] = {category="lo"}, +[92548] = {category="lo"}, +[92549] = {category="lo"}, +[92550] = {category="lo"}, +[92551] = {category="lo"}, +[92552] = {category="lo"}, +[92553] = {category="lo"}, +[92554] = {category="lo"}, +[92555] = {category="lo"}, +[92556] = {category="lo"}, +[92557] = {category="lo"}, +[92558] = {category="lo"}, +[92559] = {category="lo"}, +[92560] = {category="lo"}, +[92561] = {category="lo"}, +[92562] = {category="lo"}, +[92563] = {category="lo"}, +[92564] = {category="lo"}, +[92565] = {category="lo"}, +[92566] = {category="lo"}, +[92567] = {category="lo"}, +[92568] = {category="lo"}, +[92569] = {category="lo"}, +[92570] = {category="lo"}, +[92571] = {category="lo"}, +[92572] = {category="lo"}, +[92573] = {category="lo"}, +[92574] = {category="lo"}, +[92575] = {category="lo"}, +[92576] = {category="lo"}, +[92577] = {category="lo"}, +[92578] = {category="lo"}, +[92579] = {category="lo"}, +[92580] = {category="lo"}, +[92581] = {category="lo"}, +[92582] = {category="lo"}, +[92583] = {category="lo"}, +[92584] = {category="lo"}, +[92585] = {category="lo"}, +[92586] = {category="lo"}, +[92587] = {category="lo"}, +[92588] = {category="lo"}, +[92589] = {category="lo"}, +[92590] = {category="lo"}, +[92591] = {category="lo"}, +[92592] = {category="lo"}, +[92593] = {category="lo"}, +[92594] = {category="lo"}, +[92595] = {category="lo"}, +[92596] = {category="lo"}, +[92597] = {category="lo"}, +[92598] = {category="lo"}, +[92599] = {category="lo"}, +[92600] = {category="lo"}, +[92601] = {category="lo"}, +[92602] = {category="lo"}, +[92603] = {category="lo"}, +[92604] = {category="lo"}, +[92605] = {category="lo"}, +[92606] = {category="lo"}, +[92607] = {category="lo"}, +[92608] = {category="lo"}, +[92609] = {category="lo"}, +[92610] = {category="lo"}, +[92611] = {category="lo"}, +[92612] = {category="lo"}, +[92613] = {category="lo"}, +[92614] = {category="lo"}, +[92615] = {category="lo"}, +[92616] = {category="lo"}, +[92617] = {category="lo"}, +[92618] = {category="lo"}, +[92619] = {category="lo"}, +[92620] = {category="lo"}, +[92621] = {category="lo"}, +[92622] = {category="lo"}, +[92623] = {category="lo"}, +[92624] = {category="lo"}, +[92625] = {category="lo"}, +[92626] = {category="lo"}, +[92627] = {category="lo"}, +[92628] = {category="lo"}, +[92629] = {category="lo"}, +[92630] = {category="lo"}, +[92631] = {category="lo"}, +[92632] = {category="lo"}, +[92633] = {category="lo"}, +[92634] = {category="lo"}, +[92635] = {category="lo"}, +[92636] = {category="lo"}, +[92637] = {category="lo"}, +[92638] = {category="lo"}, +[92639] = {category="lo"}, +[92640] = {category="lo"}, +[92641] = {category="lo"}, +[92642] = {category="lo"}, +[92643] = {category="lo"}, +[92644] = {category="lo"}, +[92645] = {category="lo"}, +[92646] = {category="lo"}, +[92647] = {category="lo"}, +[92648] = {category="lo"}, +[92649] = {category="lo"}, +[92650] = {category="lo"}, +[92651] = {category="lo"}, +[92652] = {category="lo"}, +[92653] = {category="lo"}, +[92654] = {category="lo"}, +[92655] = {category="lo"}, +[92656] = {category="lo"}, +[92657] = {category="lo"}, +[92658] = {category="lo"}, +[92659] = {category="lo"}, +[92660] = {category="lo"}, +[92661] = {category="lo"}, +[92662] = {category="lo"}, +[92663] = {category="lo"}, +[92664] = {category="lo"}, +[92665] = {category="lo"}, +[92666] = {category="lo"}, +[92667] = {category="lo"}, +[92668] = {category="lo"}, +[92669] = {category="lo"}, +[92670] = {category="lo"}, +[92671] = {category="lo"}, +[92672] = {category="lo"}, +[92673] = {category="lo"}, +[92674] = {category="lo"}, +[92675] = {category="lo"}, +[92676] = {category="lo"}, +[92677] = {category="lo"}, +[92678] = {category="lo"}, +[92679] = {category="lo"}, +[92680] = {category="lo"}, +[92681] = {category="lo"}, +[92682] = {category="lo"}, +[92683] = {category="lo"}, +[92684] = {category="lo"}, +[92685] = {category="lo"}, +[92686] = {category="lo"}, +[92687] = {category="lo"}, +[92688] = {category="lo"}, +[92689] = {category="lo"}, +[92690] = {category="lo"}, +[92691] = {category="lo"}, +[92692] = {category="lo"}, +[92693] = {category="lo"}, +[92694] = {category="lo"}, +[92695] = {category="lo"}, +[92696] = {category="lo"}, +[92697] = {category="lo"}, +[92698] = {category="lo"}, +[92699] = {category="lo"}, +[92700] = {category="lo"}, +[92701] = {category="lo"}, +[92702] = {category="lo"}, +[92703] = {category="lo"}, +[92704] = {category="lo"}, +[92705] = {category="lo"}, +[92706] = {category="lo"}, +[92707] = {category="lo"}, +[92708] = {category="lo"}, +[92709] = {category="lo"}, +[92710] = {category="lo"}, +[92711] = {category="lo"}, +[92712] = {category="lo"}, +[92713] = {category="lo"}, +[92714] = {category="lo"}, +[92715] = {category="lo"}, +[92716] = {category="lo"}, +[92717] = {category="lo"}, +[92718] = {category="lo"}, +[92719] = {category="lo"}, +[92720] = {category="lo"}, +[92721] = {category="lo"}, +[92722] = {category="lo"}, +[92723] = {category="lo"}, +[92724] = {category="lo"}, +[92725] = {category="lo"}, +[92726] = {category="lo"}, +[92727] = {category="lo"}, +[92728] = {category="lo"}, +[92736] = {category="lo"}, +[92737] = {category="lo"}, +[92738] = {category="lo"}, +[92739] = {category="lo"}, +[92740] = {category="lo"}, +[92741] = {category="lo"}, +[92742] = {category="lo"}, +[92743] = {category="lo"}, +[92744] = {category="lo"}, +[92745] = {category="lo"}, +[92746] = {category="lo"}, +[92747] = {category="lo"}, +[92748] = {category="lo"}, +[92749] = {category="lo"}, +[92750] = {category="lo"}, +[92751] = {category="lo"}, +[92752] = {category="lo"}, +[92753] = {category="lo"}, +[92754] = {category="lo"}, +[92755] = {category="lo"}, +[92756] = {category="lo"}, +[92757] = {category="lo"}, +[92758] = {category="lo"}, +[92759] = {category="lo"}, +[92760] = {category="lo"}, +[92761] = {category="lo"}, +[92762] = {category="lo"}, +[92763] = {category="lo"}, +[92764] = {category="lo"}, +[92765] = {category="lo"}, +[92766] = {category="lo"}, +[92784] = {category="lo"}, +[92785] = {category="lo"}, +[92786] = {category="lo"}, +[92787] = {category="lo"}, +[92788] = {category="lo"}, +[92789] = {category="lo"}, +[92790] = {category="lo"}, +[92791] = {category="lo"}, +[92792] = {category="lo"}, +[92793] = {category="lo"}, +[92794] = {category="lo"}, +[92795] = {category="lo"}, +[92796] = {category="lo"}, +[92797] = {category="lo"}, +[92798] = {category="lo"}, +[92799] = {category="lo"}, +[92800] = {category="lo"}, +[92801] = {category="lo"}, +[92802] = {category="lo"}, +[92803] = {category="lo"}, +[92804] = {category="lo"}, +[92805] = {category="lo"}, +[92806] = {category="lo"}, +[92807] = {category="lo"}, +[92808] = {category="lo"}, +[92809] = {category="lo"}, +[92810] = {category="lo"}, +[92811] = {category="lo"}, +[92812] = {category="lo"}, +[92813] = {category="lo"}, +[92814] = {category="lo"}, +[92815] = {category="lo"}, +[92816] = {category="lo"}, +[92817] = {category="lo"}, +[92818] = {category="lo"}, +[92819] = {category="lo"}, +[92820] = {category="lo"}, +[92821] = {category="lo"}, +[92822] = {category="lo"}, +[92823] = {category="lo"}, +[92824] = {category="lo"}, +[92825] = {category="lo"}, +[92826] = {category="lo"}, +[92827] = {category="lo"}, +[92828] = {category="lo"}, +[92829] = {category="lo"}, +[92830] = {category="lo"}, +[92831] = {category="lo"}, +[92832] = {category="lo"}, +[92833] = {category="lo"}, +[92834] = {category="lo"}, +[92835] = {category="lo"}, +[92836] = {category="lo"}, +[92837] = {category="lo"}, +[92838] = {category="lo"}, +[92839] = {category="lo"}, +[92840] = {category="lo"}, +[92841] = {category="lo"}, +[92842] = {category="lo"}, +[92843] = {category="lo"}, +[92844] = {category="lo"}, +[92845] = {category="lo"}, +[92846] = {category="lo"}, +[92847] = {category="lo"}, +[92848] = {category="lo"}, +[92849] = {category="lo"}, +[92850] = {category="lo"}, +[92851] = {category="lo"}, +[92852] = {category="lo"}, +[92853] = {category="lo"}, +[92854] = {category="lo"}, +[92855] = {category="lo"}, +[92856] = {category="lo"}, +[92857] = {category="lo"}, +[92858] = {category="lo"}, +[92859] = {category="lo"}, +[92860] = {category="lo"}, +[92861] = {category="lo"}, +[92862] = {category="lo"}, +[92880] = {category="lo"}, +[92881] = {category="lo"}, +[92882] = {category="lo"}, +[92883] = {category="lo"}, +[92884] = {category="lo"}, +[92885] = {category="lo"}, +[92886] = {category="lo"}, +[92887] = {category="lo"}, +[92888] = {category="lo"}, +[92889] = {category="lo"}, +[92890] = {category="lo"}, +[92891] = {category="lo"}, +[92892] = {category="lo"}, +[92893] = {category="lo"}, +[92894] = {category="lo"}, +[92895] = {category="lo"}, +[92896] = {category="lo"}, +[92897] = {category="lo"}, +[92898] = {category="lo"}, +[92899] = {category="lo"}, +[92900] = {category="lo"}, +[92901] = {category="lo"}, +[92902] = {category="lo"}, +[92903] = {category="lo"}, +[92904] = {category="lo"}, +[92905] = {category="lo"}, +[92906] = {category="lo"}, +[92907] = {category="lo"}, +[92908] = {category="lo"}, +[92909] = {category="lo"}, +[92928] = {category="lo"}, +[92929] = {category="lo"}, +[92930] = {category="lo"}, +[92931] = {category="lo"}, +[92932] = {category="lo"}, +[92933] = {category="lo"}, +[92934] = {category="lo"}, +[92935] = {category="lo"}, +[92936] = {category="lo"}, +[92937] = {category="lo"}, +[92938] = {category="lo"}, +[92939] = {category="lo"}, +[92940] = {category="lo"}, +[92941] = {category="lo"}, +[92942] = {category="lo"}, +[92943] = {category="lo"}, +[92944] = {category="lo"}, +[92945] = {category="lo"}, +[92946] = {category="lo"}, +[92947] = {category="lo"}, +[92948] = {category="lo"}, +[92949] = {category="lo"}, +[92950] = {category="lo"}, +[92951] = {category="lo"}, +[92952] = {category="lo"}, +[92953] = {category="lo"}, +[92954] = {category="lo"}, +[92955] = {category="lo"}, +[92956] = {category="lo"}, +[92957] = {category="lo"}, +[92958] = {category="lo"}, +[92959] = {category="lo"}, +[92960] = {category="lo"}, +[92961] = {category="lo"}, +[92962] = {category="lo"}, +[92963] = {category="lo"}, +[92964] = {category="lo"}, +[92965] = {category="lo"}, +[92966] = {category="lo"}, +[92967] = {category="lo"}, +[92968] = {category="lo"}, +[92969] = {category="lo"}, +[92970] = {category="lo"}, +[92971] = {category="lo"}, +[92972] = {category="lo"}, +[92973] = {category="lo"}, +[92974] = {category="lo"}, +[92975] = {category="lo"}, +[92992] = {category="lm"}, +[92993] = {category="lm"}, +[92994] = {category="lm"}, +[92995] = {category="lm"}, +[93027] = {category="lo"}, +[93028] = {category="lo"}, +[93029] = {category="lo"}, +[93030] = {category="lo"}, +[93031] = {category="lo"}, +[93032] = {category="lo"}, +[93033] = {category="lo"}, +[93034] = {category="lo"}, +[93035] = {category="lo"}, +[93036] = {category="lo"}, +[93037] = {category="lo"}, +[93038] = {category="lo"}, +[93039] = {category="lo"}, +[93040] = {category="lo"}, +[93041] = {category="lo"}, +[93042] = {category="lo"}, +[93043] = {category="lo"}, +[93044] = {category="lo"}, +[93045] = {category="lo"}, +[93046] = {category="lo"}, +[93047] = {category="lo"}, +[93053] = {category="lo"}, +[93054] = {category="lo"}, +[93055] = {category="lo"}, +[93056] = {category="lo"}, +[93057] = {category="lo"}, +[93058] = {category="lo"}, +[93059] = {category="lo"}, +[93060] = {category="lo"}, +[93061] = {category="lo"}, +[93062] = {category="lo"}, +[93063] = {category="lo"}, +[93064] = {category="lo"}, +[93065] = {category="lo"}, +[93066] = {category="lo"}, +[93067] = {category="lo"}, +[93068] = {category="lo"}, +[93069] = {category="lo"}, +[93070] = {category="lo"}, +[93071] = {category="lo"}, +[93760] = {category="lu", lccode=93792}, +[93761] = {category="lu", lccode=93793}, +[93762] = {category="lu", lccode=93794}, +[93763] = {category="lu", lccode=93795}, +[93764] = {category="lu", lccode=93796}, +[93765] = {category="lu", lccode=93797}, +[93766] = {category="lu", lccode=93798}, +[93767] = {category="lu", lccode=93799}, +[93768] = {category="lu", lccode=93800}, +[93769] = {category="lu", lccode=93801}, +[93770] = {category="lu", lccode=93802}, +[93771] = {category="lu", lccode=93803}, +[93772] = {category="lu", lccode=93804}, +[93773] = {category="lu", lccode=93805}, +[93774] = {category="lu", lccode=93806}, +[93775] = {category="lu", lccode=93807}, +[93776] = {category="lu", lccode=93808}, +[93777] = {category="lu", lccode=93809}, +[93778] = {category="lu", lccode=93810}, +[93779] = {category="lu", lccode=93811}, +[93780] = {category="lu", lccode=93812}, +[93781] = {category="lu", lccode=93813}, +[93782] = {category="lu", lccode=93814}, +[93783] = {category="lu", lccode=93815}, +[93784] = {category="lu", lccode=93816}, +[93785] = {category="lu", lccode=93817}, +[93786] = {category="lu", lccode=93818}, +[93787] = {category="lu", lccode=93819}, +[93788] = {category="lu", lccode=93820}, +[93789] = {category="lu", lccode=93821}, +[93790] = {category="lu", lccode=93822}, +[93791] = {category="lu", lccode=93823}, +[93792] = {category="ll"}, +[93793] = {category="ll"}, +[93794] = {category="ll"}, +[93795] = {category="ll"}, +[93796] = {category="ll"}, +[93797] = {category="ll"}, +[93798] = {category="ll"}, +[93799] = {category="ll"}, +[93800] = {category="ll"}, +[93801] = {category="ll"}, +[93802] = {category="ll"}, +[93803] = {category="ll"}, +[93804] = {category="ll"}, +[93805] = {category="ll"}, +[93806] = {category="ll"}, +[93807] = {category="ll"}, +[93808] = {category="ll"}, +[93809] = {category="ll"}, +[93810] = {category="ll"}, +[93811] = {category="ll"}, +[93812] = {category="ll"}, +[93813] = {category="ll"}, +[93814] = {category="ll"}, +[93815] = {category="ll"}, +[93816] = {category="ll"}, +[93817] = {category="ll"}, +[93818] = {category="ll"}, +[93819] = {category="ll"}, +[93820] = {category="ll"}, +[93821] = {category="ll"}, +[93822] = {category="ll"}, +[93823] = {category="ll"}, +[93952] = {category="lo"}, +[93953] = {category="lo"}, +[93954] = {category="lo"}, +[93955] = {category="lo"}, +[93956] = {category="lo"}, +[93957] = {category="lo"}, +[93958] = {category="lo"}, +[93959] = {category="lo"}, +[93960] = {category="lo"}, +[93961] = {category="lo"}, +[93962] = {category="lo"}, +[93963] = {category="lo"}, +[93964] = {category="lo"}, +[93965] = {category="lo"}, +[93966] = {category="lo"}, +[93967] = {category="lo"}, +[93968] = {category="lo"}, +[93969] = {category="lo"}, +[93970] = {category="lo"}, +[93971] = {category="lo"}, +[93972] = {category="lo"}, +[93973] = {category="lo"}, +[93974] = {category="lo"}, +[93975] = {category="lo"}, +[93976] = {category="lo"}, +[93977] = {category="lo"}, +[93978] = {category="lo"}, +[93979] = {category="lo"}, +[93980] = {category="lo"}, +[93981] = {category="lo"}, +[93982] = {category="lo"}, +[93983] = {category="lo"}, +[93984] = {category="lo"}, +[93985] = {category="lo"}, +[93986] = {category="lo"}, +[93987] = {category="lo"}, +[93988] = {category="lo"}, +[93989] = {category="lo"}, +[93990] = {category="lo"}, +[93991] = {category="lo"}, +[93992] = {category="lo"}, +[93993] = {category="lo"}, +[93994] = {category="lo"}, +[93995] = {category="lo"}, +[93996] = {category="lo"}, +[93997] = {category="lo"}, +[93998] = {category="lo"}, +[93999] = {category="lo"}, +[94000] = {category="lo"}, +[94001] = {category="lo"}, +[94002] = {category="lo"}, +[94003] = {category="lo"}, +[94004] = {category="lo"}, +[94005] = {category="lo"}, +[94006] = {category="lo"}, +[94007] = {category="lo"}, +[94008] = {category="lo"}, +[94009] = {category="lo"}, +[94010] = {category="lo"}, +[94011] = {category="lo"}, +[94012] = {category="lo"}, +[94013] = {category="lo"}, +[94014] = {category="lo"}, +[94015] = {category="lo"}, +[94016] = {category="lo"}, +[94017] = {category="lo"}, +[94018] = {category="lo"}, +[94019] = {category="lo"}, +[94020] = {category="lo"}, +[94021] = {category="lo"}, +[94022] = {category="lo"}, +[94023] = {category="lo"}, +[94024] = {category="lo"}, +[94025] = {category="lo"}, +[94026] = {category="lo"}, +[94032] = {category="lo"}, +[94099] = {category="lm"}, +[94100] = {category="lm"}, +[94101] = {category="lm"}, +[94102] = {category="lm"}, +[94103] = {category="lm"}, +[94104] = {category="lm"}, +[94105] = {category="lm"}, +[94106] = {category="lm"}, +[94107] = {category="lm"}, +[94108] = {category="lm"}, +[94109] = {category="lm"}, +[94110] = {category="lm"}, +[94111] = {category="lm"}, +[94176] = {category="lm"}, +[94177] = {category="lm"}, +[94179] = {category="lm"}, +[94208] = {category="lo"}, +[100343] = {category="lo"}, +[100352] = {category="lo"}, +[100353] = {category="lo"}, +[100354] = {category="lo"}, +[100355] = {category="lo"}, +[100356] = {category="lo"}, +[100357] = {category="lo"}, +[100358] = {category="lo"}, +[100359] = {category="lo"}, +[100360] = {category="lo"}, +[100361] = {category="lo"}, +[100362] = {category="lo"}, +[100363] = {category="lo"}, +[100364] = {category="lo"}, +[100365] = {category="lo"}, +[100366] = {category="lo"}, +[100367] = {category="lo"}, +[100368] = {category="lo"}, +[100369] = {category="lo"}, +[100370] = {category="lo"}, +[100371] = {category="lo"}, +[100372] = {category="lo"}, +[100373] = {category="lo"}, +[100374] = {category="lo"}, +[100375] = {category="lo"}, +[100376] = {category="lo"}, +[100377] = {category="lo"}, +[100378] = {category="lo"}, +[100379] = {category="lo"}, +[100380] = {category="lo"}, +[100381] = {category="lo"}, +[100382] = {category="lo"}, +[100383] = {category="lo"}, +[100384] = {category="lo"}, +[100385] = {category="lo"}, +[100386] = {category="lo"}, +[100387] = {category="lo"}, +[100388] = {category="lo"}, +[100389] = {category="lo"}, +[100390] = {category="lo"}, +[100391] = {category="lo"}, +[100392] = {category="lo"}, +[100393] = {category="lo"}, +[100394] = {category="lo"}, +[100395] = {category="lo"}, +[100396] = {category="lo"}, +[100397] = {category="lo"}, +[100398] = {category="lo"}, +[100399] = {category="lo"}, +[100400] = {category="lo"}, +[100401] = {category="lo"}, +[100402] = {category="lo"}, +[100403] = {category="lo"}, +[100404] = {category="lo"}, +[100405] = {category="lo"}, +[100406] = {category="lo"}, +[100407] = {category="lo"}, +[100408] = {category="lo"}, +[100409] = {category="lo"}, +[100410] = {category="lo"}, +[100411] = {category="lo"}, +[100412] = {category="lo"}, +[100413] = {category="lo"}, +[100414] = {category="lo"}, +[100415] = {category="lo"}, +[100416] = {category="lo"}, +[100417] = {category="lo"}, +[100418] = {category="lo"}, +[100419] = {category="lo"}, +[100420] = {category="lo"}, +[100421] = {category="lo"}, +[100422] = {category="lo"}, +[100423] = {category="lo"}, +[100424] = {category="lo"}, +[100425] = {category="lo"}, +[100426] = {category="lo"}, +[100427] = {category="lo"}, +[100428] = {category="lo"}, +[100429] = {category="lo"}, +[100430] = {category="lo"}, +[100431] = {category="lo"}, +[100432] = {category="lo"}, +[100433] = {category="lo"}, +[100434] = {category="lo"}, +[100435] = {category="lo"}, +[100436] = {category="lo"}, +[100437] = {category="lo"}, +[100438] = {category="lo"}, +[100439] = {category="lo"}, +[100440] = {category="lo"}, +[100441] = {category="lo"}, +[100442] = {category="lo"}, +[100443] = {category="lo"}, +[100444] = {category="lo"}, +[100445] = {category="lo"}, +[100446] = {category="lo"}, +[100447] = {category="lo"}, +[100448] = {category="lo"}, +[100449] = {category="lo"}, +[100450] = {category="lo"}, +[100451] = {category="lo"}, +[100452] = {category="lo"}, +[100453] = {category="lo"}, +[100454] = {category="lo"}, +[100455] = {category="lo"}, +[100456] = {category="lo"}, +[100457] = {category="lo"}, +[100458] = {category="lo"}, +[100459] = {category="lo"}, +[100460] = {category="lo"}, +[100461] = {category="lo"}, +[100462] = {category="lo"}, +[100463] = {category="lo"}, +[100464] = {category="lo"}, +[100465] = {category="lo"}, +[100466] = {category="lo"}, +[100467] = {category="lo"}, +[100468] = {category="lo"}, +[100469] = {category="lo"}, +[100470] = {category="lo"}, +[100471] = {category="lo"}, +[100472] = {category="lo"}, +[100473] = {category="lo"}, +[100474] = {category="lo"}, +[100475] = {category="lo"}, +[100476] = {category="lo"}, +[100477] = {category="lo"}, +[100478] = {category="lo"}, +[100479] = {category="lo"}, +[100480] = {category="lo"}, +[100481] = {category="lo"}, +[100482] = {category="lo"}, +[100483] = {category="lo"}, +[100484] = {category="lo"}, +[100485] = {category="lo"}, +[100486] = {category="lo"}, +[100487] = {category="lo"}, +[100488] = {category="lo"}, +[100489] = {category="lo"}, +[100490] = {category="lo"}, +[100491] = {category="lo"}, +[100492] = {category="lo"}, +[100493] = {category="lo"}, +[100494] = {category="lo"}, +[100495] = {category="lo"}, +[100496] = {category="lo"}, +[100497] = {category="lo"}, +[100498] = {category="lo"}, +[100499] = {category="lo"}, +[100500] = {category="lo"}, +[100501] = {category="lo"}, +[100502] = {category="lo"}, +[100503] = {category="lo"}, +[100504] = {category="lo"}, +[100505] = {category="lo"}, +[100506] = {category="lo"}, +[100507] = {category="lo"}, +[100508] = {category="lo"}, +[100509] = {category="lo"}, +[100510] = {category="lo"}, +[100511] = {category="lo"}, +[100512] = {category="lo"}, +[100513] = {category="lo"}, +[100514] = {category="lo"}, +[100515] = {category="lo"}, +[100516] = {category="lo"}, +[100517] = {category="lo"}, +[100518] = {category="lo"}, +[100519] = {category="lo"}, +[100520] = {category="lo"}, +[100521] = {category="lo"}, +[100522] = {category="lo"}, +[100523] = {category="lo"}, +[100524] = {category="lo"}, +[100525] = {category="lo"}, +[100526] = {category="lo"}, +[100527] = {category="lo"}, +[100528] = {category="lo"}, +[100529] = {category="lo"}, +[100530] = {category="lo"}, +[100531] = {category="lo"}, +[100532] = {category="lo"}, +[100533] = {category="lo"}, +[100534] = {category="lo"}, +[100535] = {category="lo"}, +[100536] = {category="lo"}, +[100537] = {category="lo"}, +[100538] = {category="lo"}, +[100539] = {category="lo"}, +[100540] = {category="lo"}, +[100541] = {category="lo"}, +[100542] = {category="lo"}, +[100543] = {category="lo"}, +[100544] = {category="lo"}, +[100545] = {category="lo"}, +[100546] = {category="lo"}, +[100547] = {category="lo"}, +[100548] = {category="lo"}, +[100549] = {category="lo"}, +[100550] = {category="lo"}, +[100551] = {category="lo"}, +[100552] = {category="lo"}, +[100553] = {category="lo"}, +[100554] = {category="lo"}, +[100555] = {category="lo"}, +[100556] = {category="lo"}, +[100557] = {category="lo"}, +[100558] = {category="lo"}, +[100559] = {category="lo"}, +[100560] = {category="lo"}, +[100561] = {category="lo"}, +[100562] = {category="lo"}, +[100563] = {category="lo"}, +[100564] = {category="lo"}, +[100565] = {category="lo"}, +[100566] = {category="lo"}, +[100567] = {category="lo"}, +[100568] = {category="lo"}, +[100569] = {category="lo"}, +[100570] = {category="lo"}, +[100571] = {category="lo"}, +[100572] = {category="lo"}, +[100573] = {category="lo"}, +[100574] = {category="lo"}, +[100575] = {category="lo"}, +[100576] = {category="lo"}, +[100577] = {category="lo"}, +[100578] = {category="lo"}, +[100579] = {category="lo"}, +[100580] = {category="lo"}, +[100581] = {category="lo"}, +[100582] = {category="lo"}, +[100583] = {category="lo"}, +[100584] = {category="lo"}, +[100585] = {category="lo"}, +[100586] = {category="lo"}, +[100587] = {category="lo"}, +[100588] = {category="lo"}, +[100589] = {category="lo"}, +[100590] = {category="lo"}, +[100591] = {category="lo"}, +[100592] = {category="lo"}, +[100593] = {category="lo"}, +[100594] = {category="lo"}, +[100595] = {category="lo"}, +[100596] = {category="lo"}, +[100597] = {category="lo"}, +[100598] = {category="lo"}, +[100599] = {category="lo"}, +[100600] = {category="lo"}, +[100601] = {category="lo"}, +[100602] = {category="lo"}, +[100603] = {category="lo"}, +[100604] = {category="lo"}, +[100605] = {category="lo"}, +[100606] = {category="lo"}, +[100607] = {category="lo"}, +[100608] = {category="lo"}, +[100609] = {category="lo"}, +[100610] = {category="lo"}, +[100611] = {category="lo"}, +[100612] = {category="lo"}, +[100613] = {category="lo"}, +[100614] = {category="lo"}, +[100615] = {category="lo"}, +[100616] = {category="lo"}, +[100617] = {category="lo"}, +[100618] = {category="lo"}, +[100619] = {category="lo"}, +[100620] = {category="lo"}, +[100621] = {category="lo"}, +[100622] = {category="lo"}, +[100623] = {category="lo"}, +[100624] = {category="lo"}, +[100625] = {category="lo"}, +[100626] = {category="lo"}, +[100627] = {category="lo"}, +[100628] = {category="lo"}, +[100629] = {category="lo"}, +[100630] = {category="lo"}, +[100631] = {category="lo"}, +[100632] = {category="lo"}, +[100633] = {category="lo"}, +[100634] = {category="lo"}, +[100635] = {category="lo"}, +[100636] = {category="lo"}, +[100637] = {category="lo"}, +[100638] = {category="lo"}, +[100639] = {category="lo"}, +[100640] = {category="lo"}, +[100641] = {category="lo"}, +[100642] = {category="lo"}, +[100643] = {category="lo"}, +[100644] = {category="lo"}, +[100645] = {category="lo"}, +[100646] = {category="lo"}, +[100647] = {category="lo"}, +[100648] = {category="lo"}, +[100649] = {category="lo"}, +[100650] = {category="lo"}, +[100651] = {category="lo"}, +[100652] = {category="lo"}, +[100653] = {category="lo"}, +[100654] = {category="lo"}, +[100655] = {category="lo"}, +[100656] = {category="lo"}, +[100657] = {category="lo"}, +[100658] = {category="lo"}, +[100659] = {category="lo"}, +[100660] = {category="lo"}, +[100661] = {category="lo"}, +[100662] = {category="lo"}, +[100663] = {category="lo"}, +[100664] = {category="lo"}, +[100665] = {category="lo"}, +[100666] = {category="lo"}, +[100667] = {category="lo"}, +[100668] = {category="lo"}, +[100669] = {category="lo"}, +[100670] = {category="lo"}, +[100671] = {category="lo"}, +[100672] = {category="lo"}, +[100673] = {category="lo"}, +[100674] = {category="lo"}, +[100675] = {category="lo"}, +[100676] = {category="lo"}, +[100677] = {category="lo"}, +[100678] = {category="lo"}, +[100679] = {category="lo"}, +[100680] = {category="lo"}, +[100681] = {category="lo"}, +[100682] = {category="lo"}, +[100683] = {category="lo"}, +[100684] = {category="lo"}, +[100685] = {category="lo"}, +[100686] = {category="lo"}, +[100687] = {category="lo"}, +[100688] = {category="lo"}, +[100689] = {category="lo"}, +[100690] = {category="lo"}, +[100691] = {category="lo"}, +[100692] = {category="lo"}, +[100693] = {category="lo"}, +[100694] = {category="lo"}, +[100695] = {category="lo"}, +[100696] = {category="lo"}, +[100697] = {category="lo"}, +[100698] = {category="lo"}, +[100699] = {category="lo"}, +[100700] = {category="lo"}, +[100701] = {category="lo"}, +[100702] = {category="lo"}, +[100703] = {category="lo"}, +[100704] = {category="lo"}, +[100705] = {category="lo"}, +[100706] = {category="lo"}, +[100707] = {category="lo"}, +[100708] = {category="lo"}, +[100709] = {category="lo"}, +[100710] = {category="lo"}, +[100711] = {category="lo"}, +[100712] = {category="lo"}, +[100713] = {category="lo"}, +[100714] = {category="lo"}, +[100715] = {category="lo"}, +[100716] = {category="lo"}, +[100717] = {category="lo"}, +[100718] = {category="lo"}, +[100719] = {category="lo"}, +[100720] = {category="lo"}, +[100721] = {category="lo"}, +[100722] = {category="lo"}, +[100723] = {category="lo"}, +[100724] = {category="lo"}, +[100725] = {category="lo"}, +[100726] = {category="lo"}, +[100727] = {category="lo"}, +[100728] = {category="lo"}, +[100729] = {category="lo"}, +[100730] = {category="lo"}, +[100731] = {category="lo"}, +[100732] = {category="lo"}, +[100733] = {category="lo"}, +[100734] = {category="lo"}, +[100735] = {category="lo"}, +[100736] = {category="lo"}, +[100737] = {category="lo"}, +[100738] = {category="lo"}, +[100739] = {category="lo"}, +[100740] = {category="lo"}, +[100741] = {category="lo"}, +[100742] = {category="lo"}, +[100743] = {category="lo"}, +[100744] = {category="lo"}, +[100745] = {category="lo"}, +[100746] = {category="lo"}, +[100747] = {category="lo"}, +[100748] = {category="lo"}, +[100749] = {category="lo"}, +[100750] = {category="lo"}, +[100751] = {category="lo"}, +[100752] = {category="lo"}, +[100753] = {category="lo"}, +[100754] = {category="lo"}, +[100755] = {category="lo"}, +[100756] = {category="lo"}, +[100757] = {category="lo"}, +[100758] = {category="lo"}, +[100759] = {category="lo"}, +[100760] = {category="lo"}, +[100761] = {category="lo"}, +[100762] = {category="lo"}, +[100763] = {category="lo"}, +[100764] = {category="lo"}, +[100765] = {category="lo"}, +[100766] = {category="lo"}, +[100767] = {category="lo"}, +[100768] = {category="lo"}, +[100769] = {category="lo"}, +[100770] = {category="lo"}, +[100771] = {category="lo"}, +[100772] = {category="lo"}, +[100773] = {category="lo"}, +[100774] = {category="lo"}, +[100775] = {category="lo"}, +[100776] = {category="lo"}, +[100777] = {category="lo"}, +[100778] = {category="lo"}, +[100779] = {category="lo"}, +[100780] = {category="lo"}, +[100781] = {category="lo"}, +[100782] = {category="lo"}, +[100783] = {category="lo"}, +[100784] = {category="lo"}, +[100785] = {category="lo"}, +[100786] = {category="lo"}, +[100787] = {category="lo"}, +[100788] = {category="lo"}, +[100789] = {category="lo"}, +[100790] = {category="lo"}, +[100791] = {category="lo"}, +[100792] = {category="lo"}, +[100793] = {category="lo"}, +[100794] = {category="lo"}, +[100795] = {category="lo"}, +[100796] = {category="lo"}, +[100797] = {category="lo"}, +[100798] = {category="lo"}, +[100799] = {category="lo"}, +[100800] = {category="lo"}, +[100801] = {category="lo"}, +[100802] = {category="lo"}, +[100803] = {category="lo"}, +[100804] = {category="lo"}, +[100805] = {category="lo"}, +[100806] = {category="lo"}, +[100807] = {category="lo"}, +[100808] = {category="lo"}, +[100809] = {category="lo"}, +[100810] = {category="lo"}, +[100811] = {category="lo"}, +[100812] = {category="lo"}, +[100813] = {category="lo"}, +[100814] = {category="lo"}, +[100815] = {category="lo"}, +[100816] = {category="lo"}, +[100817] = {category="lo"}, +[100818] = {category="lo"}, +[100819] = {category="lo"}, +[100820] = {category="lo"}, +[100821] = {category="lo"}, +[100822] = {category="lo"}, +[100823] = {category="lo"}, +[100824] = {category="lo"}, +[100825] = {category="lo"}, +[100826] = {category="lo"}, +[100827] = {category="lo"}, +[100828] = {category="lo"}, +[100829] = {category="lo"}, +[100830] = {category="lo"}, +[100831] = {category="lo"}, +[100832] = {category="lo"}, +[100833] = {category="lo"}, +[100834] = {category="lo"}, +[100835] = {category="lo"}, +[100836] = {category="lo"}, +[100837] = {category="lo"}, +[100838] = {category="lo"}, +[100839] = {category="lo"}, +[100840] = {category="lo"}, +[100841] = {category="lo"}, +[100842] = {category="lo"}, +[100843] = {category="lo"}, +[100844] = {category="lo"}, +[100845] = {category="lo"}, +[100846] = {category="lo"}, +[100847] = {category="lo"}, +[100848] = {category="lo"}, +[100849] = {category="lo"}, +[100850] = {category="lo"}, +[100851] = {category="lo"}, +[100852] = {category="lo"}, +[100853] = {category="lo"}, +[100854] = {category="lo"}, +[100855] = {category="lo"}, +[100856] = {category="lo"}, +[100857] = {category="lo"}, +[100858] = {category="lo"}, +[100859] = {category="lo"}, +[100860] = {category="lo"}, +[100861] = {category="lo"}, +[100862] = {category="lo"}, +[100863] = {category="lo"}, +[100864] = {category="lo"}, +[100865] = {category="lo"}, +[100866] = {category="lo"}, +[100867] = {category="lo"}, +[100868] = {category="lo"}, +[100869] = {category="lo"}, +[100870] = {category="lo"}, +[100871] = {category="lo"}, +[100872] = {category="lo"}, +[100873] = {category="lo"}, +[100874] = {category="lo"}, +[100875] = {category="lo"}, +[100876] = {category="lo"}, +[100877] = {category="lo"}, +[100878] = {category="lo"}, +[100879] = {category="lo"}, +[100880] = {category="lo"}, +[100881] = {category="lo"}, +[100882] = {category="lo"}, +[100883] = {category="lo"}, +[100884] = {category="lo"}, +[100885] = {category="lo"}, +[100886] = {category="lo"}, +[100887] = {category="lo"}, +[100888] = {category="lo"}, +[100889] = {category="lo"}, +[100890] = {category="lo"}, +[100891] = {category="lo"}, +[100892] = {category="lo"}, +[100893] = {category="lo"}, +[100894] = {category="lo"}, +[100895] = {category="lo"}, +[100896] = {category="lo"}, +[100897] = {category="lo"}, +[100898] = {category="lo"}, +[100899] = {category="lo"}, +[100900] = {category="lo"}, +[100901] = {category="lo"}, +[100902] = {category="lo"}, +[100903] = {category="lo"}, +[100904] = {category="lo"}, +[100905] = {category="lo"}, +[100906] = {category="lo"}, +[100907] = {category="lo"}, +[100908] = {category="lo"}, +[100909] = {category="lo"}, +[100910] = {category="lo"}, +[100911] = {category="lo"}, +[100912] = {category="lo"}, +[100913] = {category="lo"}, +[100914] = {category="lo"}, +[100915] = {category="lo"}, +[100916] = {category="lo"}, +[100917] = {category="lo"}, +[100918] = {category="lo"}, +[100919] = {category="lo"}, +[100920] = {category="lo"}, +[100921] = {category="lo"}, +[100922] = {category="lo"}, +[100923] = {category="lo"}, +[100924] = {category="lo"}, +[100925] = {category="lo"}, +[100926] = {category="lo"}, +[100927] = {category="lo"}, +[100928] = {category="lo"}, +[100929] = {category="lo"}, +[100930] = {category="lo"}, +[100931] = {category="lo"}, +[100932] = {category="lo"}, +[100933] = {category="lo"}, +[100934] = {category="lo"}, +[100935] = {category="lo"}, +[100936] = {category="lo"}, +[100937] = {category="lo"}, +[100938] = {category="lo"}, +[100939] = {category="lo"}, +[100940] = {category="lo"}, +[100941] = {category="lo"}, +[100942] = {category="lo"}, +[100943] = {category="lo"}, +[100944] = {category="lo"}, +[100945] = {category="lo"}, +[100946] = {category="lo"}, +[100947] = {category="lo"}, +[100948] = {category="lo"}, +[100949] = {category="lo"}, +[100950] = {category="lo"}, +[100951] = {category="lo"}, +[100952] = {category="lo"}, +[100953] = {category="lo"}, +[100954] = {category="lo"}, +[100955] = {category="lo"}, +[100956] = {category="lo"}, +[100957] = {category="lo"}, +[100958] = {category="lo"}, +[100959] = {category="lo"}, +[100960] = {category="lo"}, +[100961] = {category="lo"}, +[100962] = {category="lo"}, +[100963] = {category="lo"}, +[100964] = {category="lo"}, +[100965] = {category="lo"}, +[100966] = {category="lo"}, +[100967] = {category="lo"}, +[100968] = {category="lo"}, +[100969] = {category="lo"}, +[100970] = {category="lo"}, +[100971] = {category="lo"}, +[100972] = {category="lo"}, +[100973] = {category="lo"}, +[100974] = {category="lo"}, +[100975] = {category="lo"}, +[100976] = {category="lo"}, +[100977] = {category="lo"}, +[100978] = {category="lo"}, +[100979] = {category="lo"}, +[100980] = {category="lo"}, +[100981] = {category="lo"}, +[100982] = {category="lo"}, +[100983] = {category="lo"}, +[100984] = {category="lo"}, +[100985] = {category="lo"}, +[100986] = {category="lo"}, +[100987] = {category="lo"}, +[100988] = {category="lo"}, +[100989] = {category="lo"}, +[100990] = {category="lo"}, +[100991] = {category="lo"}, +[100992] = {category="lo"}, +[100993] = {category="lo"}, +[100994] = {category="lo"}, +[100995] = {category="lo"}, +[100996] = {category="lo"}, +[100997] = {category="lo"}, +[100998] = {category="lo"}, +[100999] = {category="lo"}, +[101000] = {category="lo"}, +[101001] = {category="lo"}, +[101002] = {category="lo"}, +[101003] = {category="lo"}, +[101004] = {category="lo"}, +[101005] = {category="lo"}, +[101006] = {category="lo"}, +[101007] = {category="lo"}, +[101008] = {category="lo"}, +[101009] = {category="lo"}, +[101010] = {category="lo"}, +[101011] = {category="lo"}, +[101012] = {category="lo"}, +[101013] = {category="lo"}, +[101014] = {category="lo"}, +[101015] = {category="lo"}, +[101016] = {category="lo"}, +[101017] = {category="lo"}, +[101018] = {category="lo"}, +[101019] = {category="lo"}, +[101020] = {category="lo"}, +[101021] = {category="lo"}, +[101022] = {category="lo"}, +[101023] = {category="lo"}, +[101024] = {category="lo"}, +[101025] = {category="lo"}, +[101026] = {category="lo"}, +[101027] = {category="lo"}, +[101028] = {category="lo"}, +[101029] = {category="lo"}, +[101030] = {category="lo"}, +[101031] = {category="lo"}, +[101032] = {category="lo"}, +[101033] = {category="lo"}, +[101034] = {category="lo"}, +[101035] = {category="lo"}, +[101036] = {category="lo"}, +[101037] = {category="lo"}, +[101038] = {category="lo"}, +[101039] = {category="lo"}, +[101040] = {category="lo"}, +[101041] = {category="lo"}, +[101042] = {category="lo"}, +[101043] = {category="lo"}, +[101044] = {category="lo"}, +[101045] = {category="lo"}, +[101046] = {category="lo"}, +[101047] = {category="lo"}, +[101048] = {category="lo"}, +[101049] = {category="lo"}, +[101050] = {category="lo"}, +[101051] = {category="lo"}, +[101052] = {category="lo"}, +[101053] = {category="lo"}, +[101054] = {category="lo"}, +[101055] = {category="lo"}, +[101056] = {category="lo"}, +[101057] = {category="lo"}, +[101058] = {category="lo"}, +[101059] = {category="lo"}, +[101060] = {category="lo"}, +[101061] = {category="lo"}, +[101062] = {category="lo"}, +[101063] = {category="lo"}, +[101064] = {category="lo"}, +[101065] = {category="lo"}, +[101066] = {category="lo"}, +[101067] = {category="lo"}, +[101068] = {category="lo"}, +[101069] = {category="lo"}, +[101070] = {category="lo"}, +[101071] = {category="lo"}, +[101072] = {category="lo"}, +[101073] = {category="lo"}, +[101074] = {category="lo"}, +[101075] = {category="lo"}, +[101076] = {category="lo"}, +[101077] = {category="lo"}, +[101078] = {category="lo"}, +[101079] = {category="lo"}, +[101080] = {category="lo"}, +[101081] = {category="lo"}, +[101082] = {category="lo"}, +[101083] = {category="lo"}, +[101084] = {category="lo"}, +[101085] = {category="lo"}, +[101086] = {category="lo"}, +[101087] = {category="lo"}, +[101088] = {category="lo"}, +[101089] = {category="lo"}, +[101090] = {category="lo"}, +[101091] = {category="lo"}, +[101092] = {category="lo"}, +[101093] = {category="lo"}, +[101094] = {category="lo"}, +[101095] = {category="lo"}, +[101096] = {category="lo"}, +[101097] = {category="lo"}, +[101098] = {category="lo"}, +[101099] = {category="lo"}, +[101100] = {category="lo"}, +[101101] = {category="lo"}, +[101102] = {category="lo"}, +[101103] = {category="lo"}, +[101104] = {category="lo"}, +[101105] = {category="lo"}, +[101106] = {category="lo"}, +[101107] = {category="lo"}, +[101108] = {category="lo"}, +[101109] = {category="lo"}, +[101110] = {category="lo"}, +[101111] = {category="lo"}, +[101112] = {category="lo"}, +[101113] = {category="lo"}, +[101114] = {category="lo"}, +[101115] = {category="lo"}, +[101116] = {category="lo"}, +[101117] = {category="lo"}, +[101118] = {category="lo"}, +[101119] = {category="lo"}, +[101120] = {category="lo"}, +[101121] = {category="lo"}, +[101122] = {category="lo"}, +[101123] = {category="lo"}, +[101124] = {category="lo"}, +[101125] = {category="lo"}, +[101126] = {category="lo"}, +[101127] = {category="lo"}, +[101128] = {category="lo"}, +[101129] = {category="lo"}, +[101130] = {category="lo"}, +[101131] = {category="lo"}, +[101132] = {category="lo"}, +[101133] = {category="lo"}, +[101134] = {category="lo"}, +[101135] = {category="lo"}, +[101136] = {category="lo"}, +[101137] = {category="lo"}, +[101138] = {category="lo"}, +[101139] = {category="lo"}, +[101140] = {category="lo"}, +[101141] = {category="lo"}, +[101142] = {category="lo"}, +[101143] = {category="lo"}, +[101144] = {category="lo"}, +[101145] = {category="lo"}, +[101146] = {category="lo"}, +[101147] = {category="lo"}, +[101148] = {category="lo"}, +[101149] = {category="lo"}, +[101150] = {category="lo"}, +[101151] = {category="lo"}, +[101152] = {category="lo"}, +[101153] = {category="lo"}, +[101154] = {category="lo"}, +[101155] = {category="lo"}, +[101156] = {category="lo"}, +[101157] = {category="lo"}, +[101158] = {category="lo"}, +[101159] = {category="lo"}, +[101160] = {category="lo"}, +[101161] = {category="lo"}, +[101162] = {category="lo"}, +[101163] = {category="lo"}, +[101164] = {category="lo"}, +[101165] = {category="lo"}, +[101166] = {category="lo"}, +[101167] = {category="lo"}, +[101168] = {category="lo"}, +[101169] = {category="lo"}, +[101170] = {category="lo"}, +[101171] = {category="lo"}, +[101172] = {category="lo"}, +[101173] = {category="lo"}, +[101174] = {category="lo"}, +[101175] = {category="lo"}, +[101176] = {category="lo"}, +[101177] = {category="lo"}, +[101178] = {category="lo"}, +[101179] = {category="lo"}, +[101180] = {category="lo"}, +[101181] = {category="lo"}, +[101182] = {category="lo"}, +[101183] = {category="lo"}, +[101184] = {category="lo"}, +[101185] = {category="lo"}, +[101186] = {category="lo"}, +[101187] = {category="lo"}, +[101188] = {category="lo"}, +[101189] = {category="lo"}, +[101190] = {category="lo"}, +[101191] = {category="lo"}, +[101192] = {category="lo"}, +[101193] = {category="lo"}, +[101194] = {category="lo"}, +[101195] = {category="lo"}, +[101196] = {category="lo"}, +[101197] = {category="lo"}, +[101198] = {category="lo"}, +[101199] = {category="lo"}, +[101200] = {category="lo"}, +[101201] = {category="lo"}, +[101202] = {category="lo"}, +[101203] = {category="lo"}, +[101204] = {category="lo"}, +[101205] = {category="lo"}, +[101206] = {category="lo"}, +[101207] = {category="lo"}, +[101208] = {category="lo"}, +[101209] = {category="lo"}, +[101210] = {category="lo"}, +[101211] = {category="lo"}, +[101212] = {category="lo"}, +[101213] = {category="lo"}, +[101214] = {category="lo"}, +[101215] = {category="lo"}, +[101216] = {category="lo"}, +[101217] = {category="lo"}, +[101218] = {category="lo"}, +[101219] = {category="lo"}, +[101220] = {category="lo"}, +[101221] = {category="lo"}, +[101222] = {category="lo"}, +[101223] = {category="lo"}, +[101224] = {category="lo"}, +[101225] = {category="lo"}, +[101226] = {category="lo"}, +[101227] = {category="lo"}, +[101228] = {category="lo"}, +[101229] = {category="lo"}, +[101230] = {category="lo"}, +[101231] = {category="lo"}, +[101232] = {category="lo"}, +[101233] = {category="lo"}, +[101234] = {category="lo"}, +[101235] = {category="lo"}, +[101236] = {category="lo"}, +[101237] = {category="lo"}, +[101238] = {category="lo"}, +[101239] = {category="lo"}, +[101240] = {category="lo"}, +[101241] = {category="lo"}, +[101242] = {category="lo"}, +[101243] = {category="lo"}, +[101244] = {category="lo"}, +[101245] = {category="lo"}, +[101246] = {category="lo"}, +[101247] = {category="lo"}, +[101248] = {category="lo"}, +[101249] = {category="lo"}, +[101250] = {category="lo"}, +[101251] = {category="lo"}, +[101252] = {category="lo"}, +[101253] = {category="lo"}, +[101254] = {category="lo"}, +[101255] = {category="lo"}, +[101256] = {category="lo"}, +[101257] = {category="lo"}, +[101258] = {category="lo"}, +[101259] = {category="lo"}, +[101260] = {category="lo"}, +[101261] = {category="lo"}, +[101262] = {category="lo"}, +[101263] = {category="lo"}, +[101264] = {category="lo"}, +[101265] = {category="lo"}, +[101266] = {category="lo"}, +[101267] = {category="lo"}, +[101268] = {category="lo"}, +[101269] = {category="lo"}, +[101270] = {category="lo"}, +[101271] = {category="lo"}, +[101272] = {category="lo"}, +[101273] = {category="lo"}, +[101274] = {category="lo"}, +[101275] = {category="lo"}, +[101276] = {category="lo"}, +[101277] = {category="lo"}, +[101278] = {category="lo"}, +[101279] = {category="lo"}, +[101280] = {category="lo"}, +[101281] = {category="lo"}, +[101282] = {category="lo"}, +[101283] = {category="lo"}, +[101284] = {category="lo"}, +[101285] = {category="lo"}, +[101286] = {category="lo"}, +[101287] = {category="lo"}, +[101288] = {category="lo"}, +[101289] = {category="lo"}, +[101290] = {category="lo"}, +[101291] = {category="lo"}, +[101292] = {category="lo"}, +[101293] = {category="lo"}, +[101294] = {category="lo"}, +[101295] = {category="lo"}, +[101296] = {category="lo"}, +[101297] = {category="lo"}, +[101298] = {category="lo"}, +[101299] = {category="lo"}, +[101300] = {category="lo"}, +[101301] = {category="lo"}, +[101302] = {category="lo"}, +[101303] = {category="lo"}, +[101304] = {category="lo"}, +[101305] = {category="lo"}, +[101306] = {category="lo"}, +[101307] = {category="lo"}, +[101308] = {category="lo"}, +[101309] = {category="lo"}, +[101310] = {category="lo"}, +[101311] = {category="lo"}, +[101312] = {category="lo"}, +[101313] = {category="lo"}, +[101314] = {category="lo"}, +[101315] = {category="lo"}, +[101316] = {category="lo"}, +[101317] = {category="lo"}, +[101318] = {category="lo"}, +[101319] = {category="lo"}, +[101320] = {category="lo"}, +[101321] = {category="lo"}, +[101322] = {category="lo"}, +[101323] = {category="lo"}, +[101324] = {category="lo"}, +[101325] = {category="lo"}, +[101326] = {category="lo"}, +[101327] = {category="lo"}, +[101328] = {category="lo"}, +[101329] = {category="lo"}, +[101330] = {category="lo"}, +[101331] = {category="lo"}, +[101332] = {category="lo"}, +[101333] = {category="lo"}, +[101334] = {category="lo"}, +[101335] = {category="lo"}, +[101336] = {category="lo"}, +[101337] = {category="lo"}, +[101338] = {category="lo"}, +[101339] = {category="lo"}, +[101340] = {category="lo"}, +[101341] = {category="lo"}, +[101342] = {category="lo"}, +[101343] = {category="lo"}, +[101344] = {category="lo"}, +[101345] = {category="lo"}, +[101346] = {category="lo"}, +[101347] = {category="lo"}, +[101348] = {category="lo"}, +[101349] = {category="lo"}, +[101350] = {category="lo"}, +[101351] = {category="lo"}, +[101352] = {category="lo"}, +[101353] = {category="lo"}, +[101354] = {category="lo"}, +[101355] = {category="lo"}, +[101356] = {category="lo"}, +[101357] = {category="lo"}, +[101358] = {category="lo"}, +[101359] = {category="lo"}, +[101360] = {category="lo"}, +[101361] = {category="lo"}, +[101362] = {category="lo"}, +[101363] = {category="lo"}, +[101364] = {category="lo"}, +[101365] = {category="lo"}, +[101366] = {category="lo"}, +[101367] = {category="lo"}, +[101368] = {category="lo"}, +[101369] = {category="lo"}, +[101370] = {category="lo"}, +[101371] = {category="lo"}, +[101372] = {category="lo"}, +[101373] = {category="lo"}, +[101374] = {category="lo"}, +[101375] = {category="lo"}, +[101376] = {category="lo"}, +[101377] = {category="lo"}, +[101378] = {category="lo"}, +[101379] = {category="lo"}, +[101380] = {category="lo"}, +[101381] = {category="lo"}, +[101382] = {category="lo"}, +[101383] = {category="lo"}, +[101384] = {category="lo"}, +[101385] = {category="lo"}, +[101386] = {category="lo"}, +[101387] = {category="lo"}, +[101388] = {category="lo"}, +[101389] = {category="lo"}, +[101390] = {category="lo"}, +[101391] = {category="lo"}, +[101392] = {category="lo"}, +[101393] = {category="lo"}, +[101394] = {category="lo"}, +[101395] = {category="lo"}, +[101396] = {category="lo"}, +[101397] = {category="lo"}, +[101398] = {category="lo"}, +[101399] = {category="lo"}, +[101400] = {category="lo"}, +[101401] = {category="lo"}, +[101402] = {category="lo"}, +[101403] = {category="lo"}, +[101404] = {category="lo"}, +[101405] = {category="lo"}, +[101406] = {category="lo"}, +[101407] = {category="lo"}, +[101408] = {category="lo"}, +[101409] = {category="lo"}, +[101410] = {category="lo"}, +[101411] = {category="lo"}, +[101412] = {category="lo"}, +[101413] = {category="lo"}, +[101414] = {category="lo"}, +[101415] = {category="lo"}, +[101416] = {category="lo"}, +[101417] = {category="lo"}, +[101418] = {category="lo"}, +[101419] = {category="lo"}, +[101420] = {category="lo"}, +[101421] = {category="lo"}, +[101422] = {category="lo"}, +[101423] = {category="lo"}, +[101424] = {category="lo"}, +[101425] = {category="lo"}, +[101426] = {category="lo"}, +[101427] = {category="lo"}, +[101428] = {category="lo"}, +[101429] = {category="lo"}, +[101430] = {category="lo"}, +[101431] = {category="lo"}, +[101432] = {category="lo"}, +[101433] = {category="lo"}, +[101434] = {category="lo"}, +[101435] = {category="lo"}, +[101436] = {category="lo"}, +[101437] = {category="lo"}, +[101438] = {category="lo"}, +[101439] = {category="lo"}, +[101440] = {category="lo"}, +[101441] = {category="lo"}, +[101442] = {category="lo"}, +[101443] = {category="lo"}, +[101444] = {category="lo"}, +[101445] = {category="lo"}, +[101446] = {category="lo"}, +[101447] = {category="lo"}, +[101448] = {category="lo"}, +[101449] = {category="lo"}, +[101450] = {category="lo"}, +[101451] = {category="lo"}, +[101452] = {category="lo"}, +[101453] = {category="lo"}, +[101454] = {category="lo"}, +[101455] = {category="lo"}, +[101456] = {category="lo"}, +[101457] = {category="lo"}, +[101458] = {category="lo"}, +[101459] = {category="lo"}, +[101460] = {category="lo"}, +[101461] = {category="lo"}, +[101462] = {category="lo"}, +[101463] = {category="lo"}, +[101464] = {category="lo"}, +[101465] = {category="lo"}, +[101466] = {category="lo"}, +[101467] = {category="lo"}, +[101468] = {category="lo"}, +[101469] = {category="lo"}, +[101470] = {category="lo"}, +[101471] = {category="lo"}, +[101472] = {category="lo"}, +[101473] = {category="lo"}, +[101474] = {category="lo"}, +[101475] = {category="lo"}, +[101476] = {category="lo"}, +[101477] = {category="lo"}, +[101478] = {category="lo"}, +[101479] = {category="lo"}, +[101480] = {category="lo"}, +[101481] = {category="lo"}, +[101482] = {category="lo"}, +[101483] = {category="lo"}, +[101484] = {category="lo"}, +[101485] = {category="lo"}, +[101486] = {category="lo"}, +[101487] = {category="lo"}, +[101488] = {category="lo"}, +[101489] = {category="lo"}, +[101490] = {category="lo"}, +[101491] = {category="lo"}, +[101492] = {category="lo"}, +[101493] = {category="lo"}, +[101494] = {category="lo"}, +[101495] = {category="lo"}, +[101496] = {category="lo"}, +[101497] = {category="lo"}, +[101498] = {category="lo"}, +[101499] = {category="lo"}, +[101500] = {category="lo"}, +[101501] = {category="lo"}, +[101502] = {category="lo"}, +[101503] = {category="lo"}, +[101504] = {category="lo"}, +[101505] = {category="lo"}, +[101506] = {category="lo"}, +[101507] = {category="lo"}, +[101508] = {category="lo"}, +[101509] = {category="lo"}, +[101510] = {category="lo"}, +[101511] = {category="lo"}, +[101512] = {category="lo"}, +[101513] = {category="lo"}, +[101514] = {category="lo"}, +[101515] = {category="lo"}, +[101516] = {category="lo"}, +[101517] = {category="lo"}, +[101518] = {category="lo"}, +[101519] = {category="lo"}, +[101520] = {category="lo"}, +[101521] = {category="lo"}, +[101522] = {category="lo"}, +[101523] = {category="lo"}, +[101524] = {category="lo"}, +[101525] = {category="lo"}, +[101526] = {category="lo"}, +[101527] = {category="lo"}, +[101528] = {category="lo"}, +[101529] = {category="lo"}, +[101530] = {category="lo"}, +[101531] = {category="lo"}, +[101532] = {category="lo"}, +[101533] = {category="lo"}, +[101534] = {category="lo"}, +[101535] = {category="lo"}, +[101536] = {category="lo"}, +[101537] = {category="lo"}, +[101538] = {category="lo"}, +[101539] = {category="lo"}, +[101540] = {category="lo"}, +[101541] = {category="lo"}, +[101542] = {category="lo"}, +[101543] = {category="lo"}, +[101544] = {category="lo"}, +[101545] = {category="lo"}, +[101546] = {category="lo"}, +[101547] = {category="lo"}, +[101548] = {category="lo"}, +[101549] = {category="lo"}, +[101550] = {category="lo"}, +[101551] = {category="lo"}, +[101552] = {category="lo"}, +[101553] = {category="lo"}, +[101554] = {category="lo"}, +[101555] = {category="lo"}, +[101556] = {category="lo"}, +[101557] = {category="lo"}, +[101558] = {category="lo"}, +[101559] = {category="lo"}, +[101560] = {category="lo"}, +[101561] = {category="lo"}, +[101562] = {category="lo"}, +[101563] = {category="lo"}, +[101564] = {category="lo"}, +[101565] = {category="lo"}, +[101566] = {category="lo"}, +[101567] = {category="lo"}, +[101568] = {category="lo"}, +[101569] = {category="lo"}, +[101570] = {category="lo"}, +[101571] = {category="lo"}, +[101572] = {category="lo"}, +[101573] = {category="lo"}, +[101574] = {category="lo"}, +[101575] = {category="lo"}, +[101576] = {category="lo"}, +[101577] = {category="lo"}, +[101578] = {category="lo"}, +[101579] = {category="lo"}, +[101580] = {category="lo"}, +[101581] = {category="lo"}, +[101582] = {category="lo"}, +[101583] = {category="lo"}, +[101584] = {category="lo"}, +[101585] = {category="lo"}, +[101586] = {category="lo"}, +[101587] = {category="lo"}, +[101588] = {category="lo"}, +[101589] = {category="lo"}, +[101632] = {category="lo"}, +[101640] = {category="lo"}, +[110576] = {category="lm"}, +[110577] = {category="lm"}, +[110578] = {category="lm"}, +[110579] = {category="lm"}, +[110581] = {category="lm"}, +[110582] = {category="lm"}, +[110583] = {category="lm"}, +[110584] = {category="lm"}, +[110585] = {category="lm"}, +[110586] = {category="lm"}, +[110587] = {category="lm"}, +[110589] = {category="lm"}, +[110590] = {category="lm"}, +[110592] = {category="lo"}, +[110593] = {category="lo"}, +[110594] = {category="lo"}, +[110595] = {category="lo"}, +[110596] = {category="lo"}, +[110597] = {category="lo"}, +[110598] = {category="lo"}, +[110599] = {category="lo"}, +[110600] = {category="lo"}, +[110601] = {category="lo"}, +[110602] = {category="lo"}, +[110603] = {category="lo"}, +[110604] = {category="lo"}, +[110605] = {category="lo"}, +[110606] = {category="lo"}, +[110607] = {category="lo"}, +[110608] = {category="lo"}, +[110609] = {category="lo"}, +[110610] = {category="lo"}, +[110611] = {category="lo"}, +[110612] = {category="lo"}, +[110613] = {category="lo"}, +[110614] = {category="lo"}, +[110615] = {category="lo"}, +[110616] = {category="lo"}, +[110617] = {category="lo"}, +[110618] = {category="lo"}, +[110619] = {category="lo"}, +[110620] = {category="lo"}, +[110621] = {category="lo"}, +[110622] = {category="lo"}, +[110623] = {category="lo"}, +[110624] = {category="lo"}, +[110625] = {category="lo"}, +[110626] = {category="lo"}, +[110627] = {category="lo"}, +[110628] = {category="lo"}, +[110629] = {category="lo"}, +[110630] = {category="lo"}, +[110631] = {category="lo"}, +[110632] = {category="lo"}, +[110633] = {category="lo"}, +[110634] = {category="lo"}, +[110635] = {category="lo"}, +[110636] = {category="lo"}, +[110637] = {category="lo"}, +[110638] = {category="lo"}, +[110639] = {category="lo"}, +[110640] = {category="lo"}, +[110641] = {category="lo"}, +[110642] = {category="lo"}, +[110643] = {category="lo"}, +[110644] = {category="lo"}, +[110645] = {category="lo"}, +[110646] = {category="lo"}, +[110647] = {category="lo"}, +[110648] = {category="lo"}, +[110649] = {category="lo"}, +[110650] = {category="lo"}, +[110651] = {category="lo"}, +[110652] = {category="lo"}, +[110653] = {category="lo"}, +[110654] = {category="lo"}, +[110655] = {category="lo"}, +[110656] = {category="lo"}, +[110657] = {category="lo"}, +[110658] = {category="lo"}, +[110659] = {category="lo"}, +[110660] = {category="lo"}, +[110661] = {category="lo"}, +[110662] = {category="lo"}, +[110663] = {category="lo"}, +[110664] = {category="lo"}, +[110665] = {category="lo"}, +[110666] = {category="lo"}, +[110667] = {category="lo"}, +[110668] = {category="lo"}, +[110669] = {category="lo"}, +[110670] = {category="lo"}, +[110671] = {category="lo"}, +[110672] = {category="lo"}, +[110673] = {category="lo"}, +[110674] = {category="lo"}, +[110675] = {category="lo"}, +[110676] = {category="lo"}, +[110677] = {category="lo"}, +[110678] = {category="lo"}, +[110679] = {category="lo"}, +[110680] = {category="lo"}, +[110681] = {category="lo"}, +[110682] = {category="lo"}, +[110683] = {category="lo"}, +[110684] = {category="lo"}, +[110685] = {category="lo"}, +[110686] = {category="lo"}, +[110687] = {category="lo"}, +[110688] = {category="lo"}, +[110689] = {category="lo"}, +[110690] = {category="lo"}, +[110691] = {category="lo"}, +[110692] = {category="lo"}, +[110693] = {category="lo"}, +[110694] = {category="lo"}, +[110695] = {category="lo"}, +[110696] = {category="lo"}, +[110697] = {category="lo"}, +[110698] = {category="lo"}, +[110699] = {category="lo"}, +[110700] = {category="lo"}, +[110701] = {category="lo"}, +[110702] = {category="lo"}, +[110703] = {category="lo"}, +[110704] = {category="lo"}, +[110705] = {category="lo"}, +[110706] = {category="lo"}, +[110707] = {category="lo"}, +[110708] = {category="lo"}, +[110709] = {category="lo"}, +[110710] = {category="lo"}, +[110711] = {category="lo"}, +[110712] = {category="lo"}, +[110713] = {category="lo"}, +[110714] = {category="lo"}, +[110715] = {category="lo"}, +[110716] = {category="lo"}, +[110717] = {category="lo"}, +[110718] = {category="lo"}, +[110719] = {category="lo"}, +[110720] = {category="lo"}, +[110721] = {category="lo"}, +[110722] = {category="lo"}, +[110723] = {category="lo"}, +[110724] = {category="lo"}, +[110725] = {category="lo"}, +[110726] = {category="lo"}, +[110727] = {category="lo"}, +[110728] = {category="lo"}, +[110729] = {category="lo"}, +[110730] = {category="lo"}, +[110731] = {category="lo"}, +[110732] = {category="lo"}, +[110733] = {category="lo"}, +[110734] = {category="lo"}, +[110735] = {category="lo"}, +[110736] = {category="lo"}, +[110737] = {category="lo"}, +[110738] = {category="lo"}, +[110739] = {category="lo"}, +[110740] = {category="lo"}, +[110741] = {category="lo"}, +[110742] = {category="lo"}, +[110743] = {category="lo"}, +[110744] = {category="lo"}, +[110745] = {category="lo"}, +[110746] = {category="lo"}, +[110747] = {category="lo"}, +[110748] = {category="lo"}, +[110749] = {category="lo"}, +[110750] = {category="lo"}, +[110751] = {category="lo"}, +[110752] = {category="lo"}, +[110753] = {category="lo"}, +[110754] = {category="lo"}, +[110755] = {category="lo"}, +[110756] = {category="lo"}, +[110757] = {category="lo"}, +[110758] = {category="lo"}, +[110759] = {category="lo"}, +[110760] = {category="lo"}, +[110761] = {category="lo"}, +[110762] = {category="lo"}, +[110763] = {category="lo"}, +[110764] = {category="lo"}, +[110765] = {category="lo"}, +[110766] = {category="lo"}, +[110767] = {category="lo"}, +[110768] = {category="lo"}, +[110769] = {category="lo"}, +[110770] = {category="lo"}, +[110771] = {category="lo"}, +[110772] = {category="lo"}, +[110773] = {category="lo"}, +[110774] = {category="lo"}, +[110775] = {category="lo"}, +[110776] = {category="lo"}, +[110777] = {category="lo"}, +[110778] = {category="lo"}, +[110779] = {category="lo"}, +[110780] = {category="lo"}, +[110781] = {category="lo"}, +[110782] = {category="lo"}, +[110783] = {category="lo"}, +[110784] = {category="lo"}, +[110785] = {category="lo"}, +[110786] = {category="lo"}, +[110787] = {category="lo"}, +[110788] = {category="lo"}, +[110789] = {category="lo"}, +[110790] = {category="lo"}, +[110791] = {category="lo"}, +[110792] = {category="lo"}, +[110793] = {category="lo"}, +[110794] = {category="lo"}, +[110795] = {category="lo"}, +[110796] = {category="lo"}, +[110797] = {category="lo"}, +[110798] = {category="lo"}, +[110799] = {category="lo"}, +[110800] = {category="lo"}, +[110801] = {category="lo"}, +[110802] = {category="lo"}, +[110803] = {category="lo"}, +[110804] = {category="lo"}, +[110805] = {category="lo"}, +[110806] = {category="lo"}, +[110807] = {category="lo"}, +[110808] = {category="lo"}, +[110809] = {category="lo"}, +[110810] = {category="lo"}, +[110811] = {category="lo"}, +[110812] = {category="lo"}, +[110813] = {category="lo"}, +[110814] = {category="lo"}, +[110815] = {category="lo"}, +[110816] = {category="lo"}, +[110817] = {category="lo"}, +[110818] = {category="lo"}, +[110819] = {category="lo"}, +[110820] = {category="lo"}, +[110821] = {category="lo"}, +[110822] = {category="lo"}, +[110823] = {category="lo"}, +[110824] = {category="lo"}, +[110825] = {category="lo"}, +[110826] = {category="lo"}, +[110827] = {category="lo"}, +[110828] = {category="lo"}, +[110829] = {category="lo"}, +[110830] = {category="lo"}, +[110831] = {category="lo"}, +[110832] = {category="lo"}, +[110833] = {category="lo"}, +[110834] = {category="lo"}, +[110835] = {category="lo"}, +[110836] = {category="lo"}, +[110837] = {category="lo"}, +[110838] = {category="lo"}, +[110839] = {category="lo"}, +[110840] = {category="lo"}, +[110841] = {category="lo"}, +[110842] = {category="lo"}, +[110843] = {category="lo"}, +[110844] = {category="lo"}, +[110845] = {category="lo"}, +[110846] = {category="lo"}, +[110847] = {category="lo"}, +[110848] = {category="lo"}, +[110849] = {category="lo"}, +[110850] = {category="lo"}, +[110851] = {category="lo"}, +[110852] = {category="lo"}, +[110853] = {category="lo"}, +[110854] = {category="lo"}, +[110855] = {category="lo"}, +[110856] = {category="lo"}, +[110857] = {category="lo"}, +[110858] = {category="lo"}, +[110859] = {category="lo"}, +[110860] = {category="lo"}, +[110861] = {category="lo"}, +[110862] = {category="lo"}, +[110863] = {category="lo"}, +[110864] = {category="lo"}, +[110865] = {category="lo"}, +[110866] = {category="lo"}, +[110867] = {category="lo"}, +[110868] = {category="lo"}, +[110869] = {category="lo"}, +[110870] = {category="lo"}, +[110871] = {category="lo"}, +[110872] = {category="lo"}, +[110873] = {category="lo"}, +[110874] = {category="lo"}, +[110875] = {category="lo"}, +[110876] = {category="lo"}, +[110877] = {category="lo"}, +[110878] = {category="lo"}, +[110879] = {category="lo"}, +[110880] = {category="lo"}, +[110881] = {category="lo"}, +[110882] = {category="lo"}, +[110898] = {category="lo"}, +[110928] = {category="lo"}, +[110929] = {category="lo"}, +[110930] = {category="lo"}, +[110933] = {category="lo"}, +[110948] = {category="lo"}, +[110949] = {category="lo"}, +[110950] = {category="lo"}, +[110951] = {category="lo"}, +[110960] = {category="lo"}, +[110961] = {category="lo"}, +[110962] = {category="lo"}, +[110963] = {category="lo"}, +[110964] = {category="lo"}, +[110965] = {category="lo"}, +[110966] = {category="lo"}, +[110967] = {category="lo"}, +[110968] = {category="lo"}, +[110969] = {category="lo"}, +[110970] = {category="lo"}, +[110971] = {category="lo"}, +[110972] = {category="lo"}, +[110973] = {category="lo"}, +[110974] = {category="lo"}, +[110975] = {category="lo"}, +[110976] = {category="lo"}, +[110977] = {category="lo"}, +[110978] = {category="lo"}, +[110979] = {category="lo"}, +[110980] = {category="lo"}, +[110981] = {category="lo"}, +[110982] = {category="lo"}, +[110983] = {category="lo"}, +[110984] = {category="lo"}, +[110985] = {category="lo"}, +[110986] = {category="lo"}, +[110987] = {category="lo"}, +[110988] = {category="lo"}, +[110989] = {category="lo"}, +[110990] = {category="lo"}, +[110991] = {category="lo"}, +[110992] = {category="lo"}, +[110993] = {category="lo"}, +[110994] = {category="lo"}, +[110995] = {category="lo"}, +[110996] = {category="lo"}, +[110997] = {category="lo"}, +[110998] = {category="lo"}, +[110999] = {category="lo"}, +[111000] = {category="lo"}, +[111001] = {category="lo"}, +[111002] = {category="lo"}, +[111003] = {category="lo"}, +[111004] = {category="lo"}, +[111005] = {category="lo"}, +[111006] = {category="lo"}, +[111007] = {category="lo"}, +[111008] = {category="lo"}, +[111009] = {category="lo"}, +[111010] = {category="lo"}, +[111011] = {category="lo"}, +[111012] = {category="lo"}, +[111013] = {category="lo"}, +[111014] = {category="lo"}, +[111015] = {category="lo"}, +[111016] = {category="lo"}, +[111017] = {category="lo"}, +[111018] = {category="lo"}, +[111019] = {category="lo"}, +[111020] = {category="lo"}, +[111021] = {category="lo"}, +[111022] = {category="lo"}, +[111023] = {category="lo"}, +[111024] = {category="lo"}, +[111025] = {category="lo"}, +[111026] = {category="lo"}, +[111027] = {category="lo"}, +[111028] = {category="lo"}, +[111029] = {category="lo"}, +[111030] = {category="lo"}, +[111031] = {category="lo"}, +[111032] = {category="lo"}, +[111033] = {category="lo"}, +[111034] = {category="lo"}, +[111035] = {category="lo"}, +[111036] = {category="lo"}, +[111037] = {category="lo"}, +[111038] = {category="lo"}, +[111039] = {category="lo"}, +[111040] = {category="lo"}, +[111041] = {category="lo"}, +[111042] = {category="lo"}, +[111043] = {category="lo"}, +[111044] = {category="lo"}, +[111045] = {category="lo"}, +[111046] = {category="lo"}, +[111047] = {category="lo"}, +[111048] = {category="lo"}, +[111049] = {category="lo"}, +[111050] = {category="lo"}, +[111051] = {category="lo"}, +[111052] = {category="lo"}, +[111053] = {category="lo"}, +[111054] = {category="lo"}, +[111055] = {category="lo"}, +[111056] = {category="lo"}, +[111057] = {category="lo"}, +[111058] = {category="lo"}, +[111059] = {category="lo"}, +[111060] = {category="lo"}, +[111061] = {category="lo"}, +[111062] = {category="lo"}, +[111063] = {category="lo"}, +[111064] = {category="lo"}, +[111065] = {category="lo"}, +[111066] = {category="lo"}, +[111067] = {category="lo"}, +[111068] = {category="lo"}, +[111069] = {category="lo"}, +[111070] = {category="lo"}, +[111071] = {category="lo"}, +[111072] = {category="lo"}, +[111073] = {category="lo"}, +[111074] = {category="lo"}, +[111075] = {category="lo"}, +[111076] = {category="lo"}, +[111077] = {category="lo"}, +[111078] = {category="lo"}, +[111079] = {category="lo"}, +[111080] = {category="lo"}, +[111081] = {category="lo"}, +[111082] = {category="lo"}, +[111083] = {category="lo"}, +[111084] = {category="lo"}, +[111085] = {category="lo"}, +[111086] = {category="lo"}, +[111087] = {category="lo"}, +[111088] = {category="lo"}, +[111089] = {category="lo"}, +[111090] = {category="lo"}, +[111091] = {category="lo"}, +[111092] = {category="lo"}, +[111093] = {category="lo"}, +[111094] = {category="lo"}, +[111095] = {category="lo"}, +[111096] = {category="lo"}, +[111097] = {category="lo"}, +[111098] = {category="lo"}, +[111099] = {category="lo"}, +[111100] = {category="lo"}, +[111101] = {category="lo"}, +[111102] = {category="lo"}, +[111103] = {category="lo"}, +[111104] = {category="lo"}, +[111105] = {category="lo"}, +[111106] = {category="lo"}, +[111107] = {category="lo"}, +[111108] = {category="lo"}, +[111109] = {category="lo"}, +[111110] = {category="lo"}, +[111111] = {category="lo"}, +[111112] = {category="lo"}, +[111113] = {category="lo"}, +[111114] = {category="lo"}, +[111115] = {category="lo"}, +[111116] = {category="lo"}, +[111117] = {category="lo"}, +[111118] = {category="lo"}, +[111119] = {category="lo"}, +[111120] = {category="lo"}, +[111121] = {category="lo"}, +[111122] = {category="lo"}, +[111123] = {category="lo"}, +[111124] = {category="lo"}, +[111125] = {category="lo"}, +[111126] = {category="lo"}, +[111127] = {category="lo"}, +[111128] = {category="lo"}, +[111129] = {category="lo"}, +[111130] = {category="lo"}, +[111131] = {category="lo"}, +[111132] = {category="lo"}, +[111133] = {category="lo"}, +[111134] = {category="lo"}, +[111135] = {category="lo"}, +[111136] = {category="lo"}, +[111137] = {category="lo"}, +[111138] = {category="lo"}, +[111139] = {category="lo"}, +[111140] = {category="lo"}, +[111141] = {category="lo"}, +[111142] = {category="lo"}, +[111143] = {category="lo"}, +[111144] = {category="lo"}, +[111145] = {category="lo"}, +[111146] = {category="lo"}, +[111147] = {category="lo"}, +[111148] = {category="lo"}, +[111149] = {category="lo"}, +[111150] = {category="lo"}, +[111151] = {category="lo"}, +[111152] = {category="lo"}, +[111153] = {category="lo"}, +[111154] = {category="lo"}, +[111155] = {category="lo"}, +[111156] = {category="lo"}, +[111157] = {category="lo"}, +[111158] = {category="lo"}, +[111159] = {category="lo"}, +[111160] = {category="lo"}, +[111161] = {category="lo"}, +[111162] = {category="lo"}, +[111163] = {category="lo"}, +[111164] = {category="lo"}, +[111165] = {category="lo"}, +[111166] = {category="lo"}, +[111167] = {category="lo"}, +[111168] = {category="lo"}, +[111169] = {category="lo"}, +[111170] = {category="lo"}, +[111171] = {category="lo"}, +[111172] = {category="lo"}, +[111173] = {category="lo"}, +[111174] = {category="lo"}, +[111175] = {category="lo"}, +[111176] = {category="lo"}, +[111177] = {category="lo"}, +[111178] = {category="lo"}, +[111179] = {category="lo"}, +[111180] = {category="lo"}, +[111181] = {category="lo"}, +[111182] = {category="lo"}, +[111183] = {category="lo"}, +[111184] = {category="lo"}, +[111185] = {category="lo"}, +[111186] = {category="lo"}, +[111187] = {category="lo"}, +[111188] = {category="lo"}, +[111189] = {category="lo"}, +[111190] = {category="lo"}, +[111191] = {category="lo"}, +[111192] = {category="lo"}, +[111193] = {category="lo"}, +[111194] = {category="lo"}, +[111195] = {category="lo"}, +[111196] = {category="lo"}, +[111197] = {category="lo"}, +[111198] = {category="lo"}, +[111199] = {category="lo"}, +[111200] = {category="lo"}, +[111201] = {category="lo"}, +[111202] = {category="lo"}, +[111203] = {category="lo"}, +[111204] = {category="lo"}, +[111205] = {category="lo"}, +[111206] = {category="lo"}, +[111207] = {category="lo"}, +[111208] = {category="lo"}, +[111209] = {category="lo"}, +[111210] = {category="lo"}, +[111211] = {category="lo"}, +[111212] = {category="lo"}, +[111213] = {category="lo"}, +[111214] = {category="lo"}, +[111215] = {category="lo"}, +[111216] = {category="lo"}, +[111217] = {category="lo"}, +[111218] = {category="lo"}, +[111219] = {category="lo"}, +[111220] = {category="lo"}, +[111221] = {category="lo"}, +[111222] = {category="lo"}, +[111223] = {category="lo"}, +[111224] = {category="lo"}, +[111225] = {category="lo"}, +[111226] = {category="lo"}, +[111227] = {category="lo"}, +[111228] = {category="lo"}, +[111229] = {category="lo"}, +[111230] = {category="lo"}, +[111231] = {category="lo"}, +[111232] = {category="lo"}, +[111233] = {category="lo"}, +[111234] = {category="lo"}, +[111235] = {category="lo"}, +[111236] = {category="lo"}, +[111237] = {category="lo"}, +[111238] = {category="lo"}, +[111239] = {category="lo"}, +[111240] = {category="lo"}, +[111241] = {category="lo"}, +[111242] = {category="lo"}, +[111243] = {category="lo"}, +[111244] = {category="lo"}, +[111245] = {category="lo"}, +[111246] = {category="lo"}, +[111247] = {category="lo"}, +[111248] = {category="lo"}, +[111249] = {category="lo"}, +[111250] = {category="lo"}, +[111251] = {category="lo"}, +[111252] = {category="lo"}, +[111253] = {category="lo"}, +[111254] = {category="lo"}, +[111255] = {category="lo"}, +[111256] = {category="lo"}, +[111257] = {category="lo"}, +[111258] = {category="lo"}, +[111259] = {category="lo"}, +[111260] = {category="lo"}, +[111261] = {category="lo"}, +[111262] = {category="lo"}, +[111263] = {category="lo"}, +[111264] = {category="lo"}, +[111265] = {category="lo"}, +[111266] = {category="lo"}, +[111267] = {category="lo"}, +[111268] = {category="lo"}, +[111269] = {category="lo"}, +[111270] = {category="lo"}, +[111271] = {category="lo"}, +[111272] = {category="lo"}, +[111273] = {category="lo"}, +[111274] = {category="lo"}, +[111275] = {category="lo"}, +[111276] = {category="lo"}, +[111277] = {category="lo"}, +[111278] = {category="lo"}, +[111279] = {category="lo"}, +[111280] = {category="lo"}, +[111281] = {category="lo"}, +[111282] = {category="lo"}, +[111283] = {category="lo"}, +[111284] = {category="lo"}, +[111285] = {category="lo"}, +[111286] = {category="lo"}, +[111287] = {category="lo"}, +[111288] = {category="lo"}, +[111289] = {category="lo"}, +[111290] = {category="lo"}, +[111291] = {category="lo"}, +[111292] = {category="lo"}, +[111293] = {category="lo"}, +[111294] = {category="lo"}, +[111295] = {category="lo"}, +[111296] = {category="lo"}, +[111297] = {category="lo"}, +[111298] = {category="lo"}, +[111299] = {category="lo"}, +[111300] = {category="lo"}, +[111301] = {category="lo"}, +[111302] = {category="lo"}, +[111303] = {category="lo"}, +[111304] = {category="lo"}, +[111305] = {category="lo"}, +[111306] = {category="lo"}, +[111307] = {category="lo"}, +[111308] = {category="lo"}, +[111309] = {category="lo"}, +[111310] = {category="lo"}, +[111311] = {category="lo"}, +[111312] = {category="lo"}, +[111313] = {category="lo"}, +[111314] = {category="lo"}, +[111315] = {category="lo"}, +[111316] = {category="lo"}, +[111317] = {category="lo"}, +[111318] = {category="lo"}, +[111319] = {category="lo"}, +[111320] = {category="lo"}, +[111321] = {category="lo"}, +[111322] = {category="lo"}, +[111323] = {category="lo"}, +[111324] = {category="lo"}, +[111325] = {category="lo"}, +[111326] = {category="lo"}, +[111327] = {category="lo"}, +[111328] = {category="lo"}, +[111329] = {category="lo"}, +[111330] = {category="lo"}, +[111331] = {category="lo"}, +[111332] = {category="lo"}, +[111333] = {category="lo"}, +[111334] = {category="lo"}, +[111335] = {category="lo"}, +[111336] = {category="lo"}, +[111337] = {category="lo"}, +[111338] = {category="lo"}, +[111339] = {category="lo"}, +[111340] = {category="lo"}, +[111341] = {category="lo"}, +[111342] = {category="lo"}, +[111343] = {category="lo"}, +[111344] = {category="lo"}, +[111345] = {category="lo"}, +[111346] = {category="lo"}, +[111347] = {category="lo"}, +[111348] = {category="lo"}, +[111349] = {category="lo"}, +[111350] = {category="lo"}, +[111351] = {category="lo"}, +[111352] = {category="lo"}, +[111353] = {category="lo"}, +[111354] = {category="lo"}, +[111355] = {category="lo"}, +[113664] = {category="lo"}, +[113665] = {category="lo"}, +[113666] = {category="lo"}, +[113667] = {category="lo"}, +[113668] = {category="lo"}, +[113669] = {category="lo"}, +[113670] = {category="lo"}, +[113671] = {category="lo"}, +[113672] = {category="lo"}, +[113673] = {category="lo"}, +[113674] = {category="lo"}, +[113675] = {category="lo"}, +[113676] = {category="lo"}, +[113677] = {category="lo"}, +[113678] = {category="lo"}, +[113679] = {category="lo"}, +[113680] = {category="lo"}, +[113681] = {category="lo"}, +[113682] = {category="lo"}, +[113683] = {category="lo"}, +[113684] = {category="lo"}, +[113685] = {category="lo"}, +[113686] = {category="lo"}, +[113687] = {category="lo"}, +[113688] = {category="lo"}, +[113689] = {category="lo"}, +[113690] = {category="lo"}, +[113691] = {category="lo"}, +[113692] = {category="lo"}, +[113693] = {category="lo"}, +[113694] = {category="lo"}, +[113695] = {category="lo"}, +[113696] = {category="lo"}, +[113697] = {category="lo"}, +[113698] = {category="lo"}, +[113699] = {category="lo"}, +[113700] = {category="lo"}, +[113701] = {category="lo"}, +[113702] = {category="lo"}, +[113703] = {category="lo"}, +[113704] = {category="lo"}, +[113705] = {category="lo"}, +[113706] = {category="lo"}, +[113707] = {category="lo"}, +[113708] = {category="lo"}, +[113709] = {category="lo"}, +[113710] = {category="lo"}, +[113711] = {category="lo"}, +[113712] = {category="lo"}, +[113713] = {category="lo"}, +[113714] = {category="lo"}, +[113715] = {category="lo"}, +[113716] = {category="lo"}, +[113717] = {category="lo"}, +[113718] = {category="lo"}, +[113719] = {category="lo"}, +[113720] = {category="lo"}, +[113721] = {category="lo"}, +[113722] = {category="lo"}, +[113723] = {category="lo"}, +[113724] = {category="lo"}, +[113725] = {category="lo"}, +[113726] = {category="lo"}, +[113727] = {category="lo"}, +[113728] = {category="lo"}, +[113729] = {category="lo"}, +[113730] = {category="lo"}, +[113731] = {category="lo"}, +[113732] = {category="lo"}, +[113733] = {category="lo"}, +[113734] = {category="lo"}, +[113735] = {category="lo"}, +[113736] = {category="lo"}, +[113737] = {category="lo"}, +[113738] = {category="lo"}, +[113739] = {category="lo"}, +[113740] = {category="lo"}, +[113741] = {category="lo"}, +[113742] = {category="lo"}, +[113743] = {category="lo"}, +[113744] = {category="lo"}, +[113745] = {category="lo"}, +[113746] = {category="lo"}, +[113747] = {category="lo"}, +[113748] = {category="lo"}, +[113749] = {category="lo"}, +[113750] = {category="lo"}, +[113751] = {category="lo"}, +[113752] = {category="lo"}, +[113753] = {category="lo"}, +[113754] = {category="lo"}, +[113755] = {category="lo"}, +[113756] = {category="lo"}, +[113757] = {category="lo"}, +[113758] = {category="lo"}, +[113759] = {category="lo"}, +[113760] = {category="lo"}, +[113761] = {category="lo"}, +[113762] = {category="lo"}, +[113763] = {category="lo"}, +[113764] = {category="lo"}, +[113765] = {category="lo"}, +[113766] = {category="lo"}, +[113767] = {category="lo"}, +[113768] = {category="lo"}, +[113769] = {category="lo"}, +[113770] = {category="lo"}, +[113776] = {category="lo"}, +[113777] = {category="lo"}, +[113778] = {category="lo"}, +[113779] = {category="lo"}, +[113780] = {category="lo"}, +[113781] = {category="lo"}, +[113782] = {category="lo"}, +[113783] = {category="lo"}, +[113784] = {category="lo"}, +[113785] = {category="lo"}, +[113786] = {category="lo"}, +[113787] = {category="lo"}, +[113788] = {category="lo"}, +[113792] = {category="lo"}, +[113793] = {category="lo"}, +[113794] = {category="lo"}, +[113795] = {category="lo"}, +[113796] = {category="lo"}, +[113797] = {category="lo"}, +[113798] = {category="lo"}, +[113799] = {category="lo"}, +[113800] = {category="lo"}, +[113808] = {category="lo"}, +[113809] = {category="lo"}, +[113810] = {category="lo"}, +[113811] = {category="lo"}, +[113812] = {category="lo"}, +[113813] = {category="lo"}, +[113814] = {category="lo"}, +[113815] = {category="lo"}, +[113816] = {category="lo"}, +[113817] = {category="lo"}, +[119808] = {category="lu", shcode=15}, +[119809] = {category="lu", shcode=15}, +[119810] = {category="lu", shcode=15}, +[119811] = {category="lu", shcode=15}, +[119812] = {category="lu", shcode=15}, +[119813] = {category="lu", shcode=15}, +[119814] = {category="lu", shcode=15}, +[119815] = {category="lu", shcode=15}, +[119816] = {category="lu", shcode=15}, +[119817] = {category="lu", shcode=15}, +[119818] = {category="lu", shcode=15}, +[119819] = {category="lu", shcode=15}, +[119820] = {category="lu", shcode=15}, +[119821] = {category="lu", shcode=15}, +[119822] = {category="lu", shcode=15}, +[119823] = {category="lu", shcode=15}, +[119824] = {category="lu", shcode=15}, +[119825] = {category="lu", shcode=15}, +[119826] = {category="lu", shcode=15}, +[119827] = {category="lu", shcode=15}, +[119828] = {category="lu", shcode=15}, +[119829] = {category="lu", shcode=15}, +[119830] = {category="lu", shcode=15}, +[119831] = {category="lu", shcode=15}, +[119832] = {category="lu", shcode=15}, +[119833] = {category="lu", shcode=15}, +[119834] = {category="ll", shcode=15}, +[119835] = {category="ll", shcode=15}, +[119836] = {category="ll", shcode=15}, +[119837] = {category="ll", shcode=15}, +[119838] = {category="ll", shcode=15}, +[119839] = {category="ll", shcode=15}, +[119840] = {category="ll", shcode=15}, +[119841] = {category="ll", shcode=15}, +[119842] = {category="ll", shcode=15}, +[119843] = {category="ll", shcode=15}, +[119844] = {category="ll", shcode=15}, +[119845] = {category="ll", shcode=15}, +[119846] = {category="ll", shcode=15}, +[119847] = {category="ll", shcode=15}, +[119848] = {category="ll", shcode=15}, +[119849] = {category="ll", shcode=15}, +[119850] = {category="ll", shcode=15}, +[119851] = {category="ll", shcode=15}, +[119852] = {category="ll", shcode=15}, +[119853] = {category="ll", shcode=15}, +[119854] = {category="ll", shcode=15}, +[119855] = {category="ll", shcode=15}, +[119856] = {category="ll", shcode=15}, +[119857] = {category="ll", shcode=15}, +[119858] = {category="ll", shcode=15}, +[119859] = {category="ll", shcode=15}, +[119860] = {category="lu", shcode=15}, +[119861] = {category="lu", shcode=15}, +[119862] = {category="lu", shcode=15}, +[119863] = {category="lu", shcode=15}, +[119864] = {category="lu", shcode=15}, +[119865] = {category="lu", shcode=15}, +[119866] = {category="lu", shcode=15}, +[119867] = {category="lu", shcode=15}, +[119868] = {category="lu", shcode=15}, +[119869] = {category="lu", shcode=15}, +[119870] = {category="lu", shcode=15}, +[119871] = {category="lu", shcode=15}, +[119872] = {category="lu", shcode=15}, +[119873] = {category="lu", shcode=15}, +[119874] = {category="lu", shcode=15}, +[119875] = {category="lu", shcode=15}, +[119876] = {category="lu", shcode=15}, +[119877] = {category="lu", shcode=15}, +[119878] = {category="lu", shcode=15}, +[119879] = {category="lu", shcode=15}, +[119880] = {category="lu", shcode=15}, +[119881] = {category="lu", shcode=15}, +[119882] = {category="lu", shcode=15}, +[119883] = {category="lu", shcode=15}, +[119884] = {category="lu", shcode=15}, +[119885] = {category="lu", shcode=15}, +[119886] = {category="ll", shcode=15}, +[119887] = {category="ll", shcode=15}, +[119888] = {category="ll", shcode=15}, +[119889] = {category="ll", shcode=15}, +[119890] = {category="ll", shcode=15}, +[119891] = {category="ll", shcode=15}, +[119892] = {category="ll", shcode=15}, +[119894] = {category="ll", shcode=15}, +[119895] = {category="ll", shcode=15}, +[119896] = {category="ll", shcode=15}, +[119897] = {category="ll", shcode=15}, +[119898] = {category="ll", shcode=15}, +[119899] = {category="ll", shcode=15}, +[119900] = {category="ll", shcode=15}, +[119901] = {category="ll", shcode=15}, +[119902] = {category="ll", shcode=15}, +[119903] = {category="ll", shcode=15}, +[119904] = {category="ll", shcode=15}, +[119905] = {category="ll", shcode=15}, +[119906] = {category="ll", shcode=15}, +[119907] = {category="ll", shcode=15}, +[119908] = {category="ll", shcode=15}, +[119909] = {category="ll", shcode=15}, +[119910] = {category="ll", shcode=15}, +[119911] = {category="ll", shcode=15}, +[119912] = {category="lu", shcode=15}, +[119913] = {category="lu", shcode=15}, +[119914] = {category="lu", shcode=15}, +[119915] = {category="lu", shcode=15}, +[119916] = {category="lu", shcode=15}, +[119917] = {category="lu", shcode=15}, +[119918] = {category="lu", shcode=15}, +[119919] = {category="lu", shcode=15}, +[119920] = {category="lu", shcode=15}, +[119921] = {category="lu", shcode=15}, +[119922] = {category="lu", shcode=15}, +[119923] = {category="lu", shcode=15}, +[119924] = {category="lu", shcode=15}, +[119925] = {category="lu", shcode=15}, +[119926] = {category="lu", shcode=15}, +[119927] = {category="lu", shcode=15}, +[119928] = {category="lu", shcode=15}, +[119929] = {category="lu", shcode=15}, +[119930] = {category="lu", shcode=15}, +[119931] = {category="lu", shcode=15}, +[119932] = {category="lu", shcode=15}, +[119933] = {category="lu", shcode=15}, +[119934] = {category="lu", shcode=15}, +[119935] = {category="lu", shcode=15}, +[119936] = {category="lu", shcode=15}, +[119937] = {category="lu", shcode=15}, +[119938] = {category="ll", shcode=15}, +[119939] = {category="ll", shcode=15}, +[119940] = {category="ll", shcode=15}, +[119941] = {category="ll", shcode=15}, +[119942] = {category="ll", shcode=15}, +[119943] = {category="ll", shcode=15}, +[119944] = {category="ll", shcode=15}, +[119945] = {category="ll", shcode=15}, +[119946] = {category="ll", shcode=15}, +[119947] = {category="ll", shcode=15}, +[119948] = {category="ll", shcode=15}, +[119949] = {category="ll", shcode=15}, +[119950] = {category="ll", shcode=15}, +[119951] = {category="ll", shcode=15}, +[119952] = {category="ll", shcode=15}, +[119953] = {category="ll", shcode=15}, +[119954] = {category="ll", shcode=15}, +[119955] = {category="ll", shcode=15}, +[119956] = {category="ll", shcode=15}, +[119957] = {category="ll", shcode=15}, +[119958] = {category="ll", shcode=15}, +[119959] = {category="ll", shcode=15}, +[119960] = {category="ll", shcode=15}, +[119961] = {category="ll", shcode=15}, +[119962] = {category="ll", shcode=15}, +[119963] = {category="ll", shcode=15}, +[119964] = {category="lu", shcode=15}, +[119966] = {category="lu", shcode=15}, +[119967] = {category="lu", shcode=15}, +[119970] = {category="lu", shcode=15}, +[119973] = {category="lu", shcode=15}, +[119974] = {category="lu", shcode=15}, +[119977] = {category="lu", shcode=15}, +[119978] = {category="lu", shcode=15}, +[119979] = {category="lu", shcode=15}, +[119980] = {category="lu", shcode=15}, +[119982] = {category="lu", shcode=15}, +[119983] = {category="lu", shcode=15}, +[119984] = {category="lu", shcode=15}, +[119985] = {category="lu", shcode=15}, +[119986] = {category="lu", shcode=15}, +[119987] = {category="lu", shcode=15}, +[119988] = {category="lu", shcode=15}, +[119989] = {category="lu", shcode=15}, +[119990] = {category="ll", shcode=15}, +[119991] = {category="ll", shcode=15}, +[119992] = {category="ll", shcode=15}, +[119993] = {category="ll", shcode=15}, +[119995] = {category="ll", shcode=15}, +[119997] = {category="ll", shcode=15}, +[119998] = {category="ll", shcode=15}, +[119999] = {category="ll", shcode=15}, +[120000] = {category="ll", shcode=15}, +[120001] = {category="ll", shcode=15}, +[120002] = {category="ll", shcode=15}, +[120003] = {category="ll", shcode=15}, +[120005] = {category="ll", shcode=15}, +[120006] = {category="ll", shcode=15}, +[120007] = {category="ll", shcode=15}, +[120008] = {category="ll", shcode=15}, +[120009] = {category="ll", shcode=15}, +[120010] = {category="ll", shcode=15}, +[120011] = {category="ll", shcode=15}, +[120012] = {category="ll", shcode=15}, +[120013] = {category="ll", shcode=15}, +[120014] = {category="ll", shcode=15}, +[120015] = {category="ll", shcode=15}, +[120016] = {category="lu", shcode=15}, +[120017] = {category="lu", shcode=15}, +[120018] = {category="lu", shcode=15}, +[120019] = {category="lu", shcode=15}, +[120020] = {category="lu", shcode=15}, +[120021] = {category="lu", shcode=15}, +[120022] = {category="lu", shcode=15}, +[120023] = {category="lu", shcode=15}, +[120024] = {category="lu", shcode=15}, +[120025] = {category="lu", shcode=15}, +[120026] = {category="lu", shcode=15}, +[120027] = {category="lu", shcode=15}, +[120028] = {category="lu", shcode=15}, +[120029] = {category="lu", shcode=15}, +[120030] = {category="lu", shcode=15}, +[120031] = {category="lu", shcode=15}, +[120032] = {category="lu", shcode=15}, +[120033] = {category="lu", shcode=15}, +[120034] = {category="lu", shcode=15}, +[120035] = {category="lu", shcode=15}, +[120036] = {category="lu", shcode=15}, +[120037] = {category="lu", shcode=15}, +[120038] = {category="lu", shcode=15}, +[120039] = {category="lu", shcode=15}, +[120040] = {category="lu", shcode=15}, +[120041] = {category="lu", shcode=15}, +[120042] = {category="ll", shcode=15}, +[120043] = {category="ll", shcode=15}, +[120044] = {category="ll", shcode=15}, +[120045] = {category="ll", shcode=15}, +[120046] = {category="ll", shcode=15}, +[120047] = {category="ll", shcode=15}, +[120048] = {category="ll", shcode=15}, +[120049] = {category="ll", shcode=15}, +[120050] = {category="ll", shcode=15}, +[120051] = {category="ll", shcode=15}, +[120052] = {category="ll", shcode=15}, +[120053] = {category="ll", shcode=15}, +[120054] = {category="ll", shcode=15}, +[120055] = {category="ll", shcode=15}, +[120056] = {category="ll", shcode=15}, +[120057] = {category="ll", shcode=15}, +[120058] = {category="ll", shcode=15}, +[120059] = {category="ll", shcode=15}, +[120060] = {category="ll", shcode=15}, +[120061] = {category="ll", shcode=15}, +[120062] = {category="ll", shcode=15}, +[120063] = {category="ll", shcode=15}, +[120064] = {category="ll", shcode=15}, +[120065] = {category="ll", shcode=15}, +[120066] = {category="ll", shcode=15}, +[120067] = {category="ll", shcode=15}, +[120068] = {category="lu", shcode=15}, +[120069] = {category="lu", shcode=15}, +[120071] = {category="lu", shcode=15}, +[120072] = {category="lu", shcode=15}, +[120073] = {category="lu", shcode=15}, +[120074] = {category="lu", shcode=15}, +[120077] = {category="lu", shcode=15}, +[120078] = {category="lu", shcode=15}, +[120079] = {category="lu", shcode=15}, +[120080] = {category="lu", shcode=15}, +[120081] = {category="lu", shcode=15}, +[120082] = {category="lu", shcode=15}, +[120083] = {category="lu", shcode=15}, +[120084] = {category="lu", shcode=15}, +[120086] = {category="lu", shcode=15}, +[120087] = {category="lu", shcode=15}, +[120088] = {category="lu", shcode=15}, +[120089] = {category="lu", shcode=15}, +[120090] = {category="lu", shcode=15}, +[120091] = {category="lu", shcode=15}, +[120092] = {category="lu", shcode=15}, +[120094] = {category="ll", shcode=15}, +[120095] = {category="ll", shcode=15}, +[120096] = {category="ll", shcode=15}, +[120097] = {category="ll", shcode=15}, +[120098] = {category="ll", shcode=15}, +[120099] = {category="ll", shcode=15}, +[120100] = {category="ll", shcode=15}, +[120101] = {category="ll", shcode=15}, +[120102] = {category="ll", shcode=15}, +[120103] = {category="ll", shcode=15}, +[120104] = {category="ll", shcode=15}, +[120105] = {category="ll", shcode=15}, +[120106] = {category="ll", shcode=15}, +[120107] = {category="ll", shcode=15}, +[120108] = {category="ll", shcode=15}, +[120109] = {category="ll", shcode=15}, +[120110] = {category="ll", shcode=15}, +[120111] = {category="ll", shcode=15}, +[120112] = {category="ll", shcode=15}, +[120113] = {category="ll", shcode=15}, +[120114] = {category="ll", shcode=15}, +[120115] = {category="ll", shcode=15}, +[120116] = {category="ll", shcode=15}, +[120117] = {category="ll", shcode=15}, +[120118] = {category="ll", shcode=15}, +[120119] = {category="ll", shcode=15}, +[120120] = {category="lu", shcode=15}, +[120121] = {category="lu", shcode=15}, +[120123] = {category="lu", shcode=15}, +[120124] = {category="lu", shcode=15}, +[120125] = {category="lu", shcode=15}, +[120126] = {category="lu", shcode=15}, +[120128] = {category="lu", shcode=15}, +[120129] = {category="lu", shcode=15}, +[120130] = {category="lu", shcode=15}, +[120131] = {category="lu", shcode=15}, +[120132] = {category="lu", shcode=15}, +[120134] = {category="lu", shcode=15}, +[120138] = {category="lu", shcode=15}, +[120139] = {category="lu", shcode=15}, +[120140] = {category="lu", shcode=15}, +[120141] = {category="lu", shcode=15}, +[120142] = {category="lu", shcode=15}, +[120143] = {category="lu", shcode=15}, +[120144] = {category="lu", shcode=15}, +[120146] = {category="ll", shcode=15}, +[120147] = {category="ll", shcode=15}, +[120148] = {category="ll", shcode=15}, +[120149] = {category="ll", shcode=15}, +[120150] = {category="ll", shcode=15}, +[120151] = {category="ll", shcode=15}, +[120152] = {category="ll", shcode=15}, +[120153] = {category="ll", shcode=15}, +[120154] = {category="ll", shcode=15}, +[120155] = {category="ll", shcode=15}, +[120156] = {category="ll", shcode=15}, +[120157] = {category="ll", shcode=15}, +[120158] = {category="ll", shcode=15}, +[120159] = {category="ll", shcode=15}, +[120160] = {category="ll", shcode=15}, +[120161] = {category="ll", shcode=15}, +[120162] = {category="ll", shcode=15}, +[120163] = {category="ll", shcode=15}, +[120164] = {category="ll", shcode=15}, +[120165] = {category="ll", shcode=15}, +[120166] = {category="ll", shcode=15}, +[120167] = {category="ll", shcode=15}, +[120168] = {category="ll", shcode=15}, +[120169] = {category="ll", shcode=15}, +[120170] = {category="ll", shcode=15}, +[120171] = {category="ll", shcode=15}, +[120172] = {category="lu", shcode=15}, +[120173] = {category="lu", shcode=15}, +[120174] = {category="lu", shcode=15}, +[120175] = {category="lu", shcode=15}, +[120176] = {category="lu", shcode=15}, +[120177] = {category="lu", shcode=15}, +[120178] = {category="lu", shcode=15}, +[120179] = {category="lu", shcode=15}, +[120180] = {category="lu", shcode=15}, +[120181] = {category="lu", shcode=15}, +[120182] = {category="lu", shcode=15}, +[120183] = {category="lu", shcode=15}, +[120184] = {category="lu", shcode=15}, +[120185] = {category="lu", shcode=15}, +[120186] = {category="lu", shcode=15}, +[120187] = {category="lu", shcode=15}, +[120188] = {category="lu", shcode=15}, +[120189] = {category="lu", shcode=15}, +[120190] = {category="lu", shcode=15}, +[120191] = {category="lu", shcode=15}, +[120192] = {category="lu", shcode=15}, +[120193] = {category="lu", shcode=15}, +[120194] = {category="lu", shcode=15}, +[120195] = {category="lu", shcode=15}, +[120196] = {category="lu", shcode=15}, +[120197] = {category="lu", shcode=15}, +[120198] = {category="ll", shcode=15}, +[120199] = {category="ll", shcode=15}, +[120200] = {category="ll", shcode=15}, +[120201] = {category="ll", shcode=15}, +[120202] = {category="ll", shcode=15}, +[120203] = {category="ll", shcode=15}, +[120204] = {category="ll", shcode=15}, +[120205] = {category="ll", shcode=15}, +[120206] = {category="ll", shcode=15}, +[120207] = {category="ll", shcode=15}, +[120208] = {category="ll", shcode=15}, +[120209] = {category="ll", shcode=15}, +[120210] = {category="ll", shcode=15}, +[120211] = {category="ll", shcode=15}, +[120212] = {category="ll", shcode=15}, +[120213] = {category="ll", shcode=15}, +[120214] = {category="ll", shcode=15}, +[120215] = {category="ll", shcode=15}, +[120216] = {category="ll", shcode=15}, +[120217] = {category="ll", shcode=15}, +[120218] = {category="ll", shcode=15}, +[120219] = {category="ll", shcode=15}, +[120220] = {category="ll", shcode=15}, +[120221] = {category="ll", shcode=15}, +[120222] = {category="ll", shcode=15}, +[120223] = {category="ll", shcode=15}, +[120224] = {category="lu", shcode=15}, +[120225] = {category="lu", shcode=15}, +[120226] = {category="lu", shcode=15}, +[120227] = {category="lu", shcode=15}, +[120228] = {category="lu", shcode=15}, +[120229] = {category="lu", shcode=15}, +[120230] = {category="lu", shcode=15}, +[120231] = {category="lu", shcode=15}, +[120232] = {category="lu", shcode=15}, +[120233] = {category="lu", shcode=15}, +[120234] = {category="lu", shcode=15}, +[120235] = {category="lu", shcode=15}, +[120236] = {category="lu", shcode=15}, +[120237] = {category="lu", shcode=15}, +[120238] = {category="lu", shcode=15}, +[120239] = {category="lu", shcode=15}, +[120240] = {category="lu", shcode=15}, +[120241] = {category="lu", shcode=15}, +[120242] = {category="lu", shcode=15}, +[120243] = {category="lu", shcode=15}, +[120244] = {category="lu", shcode=15}, +[120245] = {category="lu", shcode=15}, +[120246] = {category="lu", shcode=15}, +[120247] = {category="lu", shcode=15}, +[120248] = {category="lu", shcode=15}, +[120249] = {category="lu", shcode=15}, +[120250] = {category="ll", shcode=15}, +[120251] = {category="ll", shcode=15}, +[120252] = {category="ll", shcode=15}, +[120253] = {category="ll", shcode=15}, +[120254] = {category="ll", shcode=15}, +[120255] = {category="ll", shcode=15}, +[120256] = {category="ll", shcode=15}, +[120257] = {category="ll", shcode=15}, +[120258] = {category="ll", shcode=15}, +[120259] = {category="ll", shcode=15}, +[120260] = {category="ll", shcode=15}, +[120261] = {category="ll", shcode=15}, +[120262] = {category="ll", shcode=15}, +[120263] = {category="ll", shcode=15}, +[120264] = {category="ll", shcode=15}, +[120265] = {category="ll", shcode=15}, +[120266] = {category="ll", shcode=15}, +[120267] = {category="ll", shcode=15}, +[120268] = {category="ll", shcode=15}, +[120269] = {category="ll", shcode=15}, +[120270] = {category="ll", shcode=15}, +[120271] = {category="ll", shcode=15}, +[120272] = {category="ll", shcode=15}, +[120273] = {category="ll", shcode=15}, +[120274] = {category="ll", shcode=15}, +[120275] = {category="ll", shcode=15}, +[120276] = {category="lu", shcode=15}, +[120277] = {category="lu", shcode=15}, +[120278] = {category="lu", shcode=15}, +[120279] = {category="lu", shcode=15}, +[120280] = {category="lu", shcode=15}, +[120281] = {category="lu", shcode=15}, +[120282] = {category="lu", shcode=15}, +[120283] = {category="lu", shcode=15}, +[120284] = {category="lu", shcode=15}, +[120285] = {category="lu", shcode=15}, +[120286] = {category="lu", shcode=15}, +[120287] = {category="lu", shcode=15}, +[120288] = {category="lu", shcode=15}, +[120289] = {category="lu", shcode=15}, +[120290] = {category="lu", shcode=15}, +[120291] = {category="lu", shcode=15}, +[120292] = {category="lu", shcode=15}, +[120293] = {category="lu", shcode=15}, +[120294] = {category="lu", shcode=15}, +[120295] = {category="lu", shcode=15}, +[120296] = {category="lu", shcode=15}, +[120297] = {category="lu", shcode=15}, +[120298] = {category="lu", shcode=15}, +[120299] = {category="lu", shcode=15}, +[120300] = {category="lu", shcode=15}, +[120301] = {category="lu", shcode=15}, +[120302] = {category="ll", shcode=15}, +[120303] = {category="ll", shcode=15}, +[120304] = {category="ll", shcode=15}, +[120305] = {category="ll", shcode=15}, +[120306] = {category="ll", shcode=15}, +[120307] = {category="ll", shcode=15}, +[120308] = {category="ll", shcode=15}, +[120309] = {category="ll", shcode=15}, +[120310] = {category="ll", shcode=15}, +[120311] = {category="ll", shcode=15}, +[120312] = {category="ll", shcode=15}, +[120313] = {category="ll", shcode=15}, +[120314] = {category="ll", shcode=15}, +[120315] = {category="ll", shcode=15}, +[120316] = {category="ll", shcode=15}, +[120317] = {category="ll", shcode=15}, +[120318] = {category="ll", shcode=15}, +[120319] = {category="ll", shcode=15}, +[120320] = {category="ll", shcode=15}, +[120321] = {category="ll", shcode=15}, +[120322] = {category="ll", shcode=15}, +[120323] = {category="ll", shcode=15}, +[120324] = {category="ll", shcode=15}, +[120325] = {category="ll", shcode=15}, +[120326] = {category="ll", shcode=15}, +[120327] = {category="ll", shcode=15}, +[120328] = {category="lu", shcode=15}, +[120329] = {category="lu", shcode=15}, +[120330] = {category="lu", shcode=15}, +[120331] = {category="lu", shcode=15}, +[120332] = {category="lu", shcode=15}, +[120333] = {category="lu", shcode=15}, +[120334] = {category="lu", shcode=15}, +[120335] = {category="lu", shcode=15}, +[120336] = {category="lu", shcode=15}, +[120337] = {category="lu", shcode=15}, +[120338] = {category="lu", shcode=15}, +[120339] = {category="lu", shcode=15}, +[120340] = {category="lu", shcode=15}, +[120341] = {category="lu", shcode=15}, +[120342] = {category="lu", shcode=15}, +[120343] = {category="lu", shcode=15}, +[120344] = {category="lu", shcode=15}, +[120345] = {category="lu", shcode=15}, +[120346] = {category="lu", shcode=15}, +[120347] = {category="lu", shcode=15}, +[120348] = {category="lu", shcode=15}, +[120349] = {category="lu", shcode=15}, +[120350] = {category="lu", shcode=15}, +[120351] = {category="lu", shcode=15}, +[120352] = {category="lu", shcode=15}, +[120353] = {category="lu", shcode=15}, +[120354] = {category="ll", shcode=15}, +[120355] = {category="ll", shcode=15}, +[120356] = {category="ll", shcode=15}, +[120357] = {category="ll", shcode=15}, +[120358] = {category="ll", shcode=15}, +[120359] = {category="ll", shcode=15}, +[120360] = {category="ll", shcode=15}, +[120361] = {category="ll", shcode=15}, +[120362] = {category="ll", shcode=15}, +[120363] = {category="ll", shcode=15}, +[120364] = {category="ll", shcode=15}, +[120365] = {category="ll", shcode=15}, +[120366] = {category="ll", shcode=15}, +[120367] = {category="ll", shcode=15}, +[120368] = {category="ll", shcode=15}, +[120369] = {category="ll", shcode=15}, +[120370] = {category="ll", shcode=15}, +[120371] = {category="ll", shcode=15}, +[120372] = {category="ll", shcode=15}, +[120373] = {category="ll", shcode=15}, +[120374] = {category="ll", shcode=15}, +[120375] = {category="ll", shcode=15}, +[120376] = {category="ll", shcode=15}, +[120377] = {category="ll", shcode=15}, +[120378] = {category="ll", shcode=15}, +[120379] = {category="ll", shcode=15}, +[120380] = {category="lu", shcode=15}, +[120381] = {category="lu", shcode=15}, +[120382] = {category="lu", shcode=15}, +[120383] = {category="lu", shcode=15}, +[120384] = {category="lu", shcode=15}, +[120385] = {category="lu", shcode=15}, +[120386] = {category="lu", shcode=15}, +[120387] = {category="lu", shcode=15}, +[120388] = {category="lu", shcode=15}, +[120389] = {category="lu", shcode=15}, +[120390] = {category="lu", shcode=15}, +[120391] = {category="lu", shcode=15}, +[120392] = {category="lu", shcode=15}, +[120393] = {category="lu", shcode=15}, +[120394] = {category="lu", shcode=15}, +[120395] = {category="lu", shcode=15}, +[120396] = {category="lu", shcode=15}, +[120397] = {category="lu", shcode=15}, +[120398] = {category="lu", shcode=15}, +[120399] = {category="lu", shcode=15}, +[120400] = {category="lu", shcode=15}, +[120401] = {category="lu", shcode=15}, +[120402] = {category="lu", shcode=15}, +[120403] = {category="lu", shcode=15}, +[120404] = {category="lu", shcode=15}, +[120405] = {category="lu", shcode=15}, +[120406] = {category="ll", shcode=15}, +[120407] = {category="ll", shcode=15}, +[120408] = {category="ll", shcode=15}, +[120409] = {category="ll", shcode=15}, +[120410] = {category="ll", shcode=15}, +[120411] = {category="ll", shcode=15}, +[120412] = {category="ll", shcode=15}, +[120413] = {category="ll", shcode=15}, +[120414] = {category="ll", shcode=15}, +[120415] = {category="ll", shcode=15}, +[120416] = {category="ll", shcode=15}, +[120417] = {category="ll", shcode=15}, +[120418] = {category="ll", shcode=15}, +[120419] = {category="ll", shcode=15}, +[120420] = {category="ll", shcode=15}, +[120421] = {category="ll", shcode=15}, +[120422] = {category="ll", shcode=15}, +[120423] = {category="ll", shcode=15}, +[120424] = {category="ll", shcode=15}, +[120425] = {category="ll", shcode=15}, +[120426] = {category="ll", shcode=15}, +[120427] = {category="ll", shcode=15}, +[120428] = {category="ll", shcode=15}, +[120429] = {category="ll", shcode=15}, +[120430] = {category="ll", shcode=15}, +[120431] = {category="ll", shcode=15}, +[120432] = {category="lu", shcode=15}, +[120433] = {category="lu", shcode=15}, +[120434] = {category="lu", shcode=15}, +[120435] = {category="lu", shcode=15}, +[120436] = {category="lu", shcode=15}, +[120437] = {category="lu", shcode=15}, +[120438] = {category="lu", shcode=15}, +[120439] = {category="lu", shcode=15}, +[120440] = {category="lu", shcode=15}, +[120441] = {category="lu", shcode=15}, +[120442] = {category="lu", shcode=15}, +[120443] = {category="lu", shcode=15}, +[120444] = {category="lu", shcode=15}, +[120445] = {category="lu", shcode=15}, +[120446] = {category="lu", shcode=15}, +[120447] = {category="lu", shcode=15}, +[120448] = {category="lu", shcode=15}, +[120449] = {category="lu", shcode=15}, +[120450] = {category="lu", shcode=15}, +[120451] = {category="lu", shcode=15}, +[120452] = {category="lu", shcode=15}, +[120453] = {category="lu", shcode=15}, +[120454] = {category="lu", shcode=15}, +[120455] = {category="lu", shcode=15}, +[120456] = {category="lu", shcode=15}, +[120457] = {category="lu", shcode=15}, +[120458] = {category="ll", shcode=15}, +[120459] = {category="ll", shcode=15}, +[120460] = {category="ll", shcode=15}, +[120461] = {category="ll", shcode=15}, +[120462] = {category="ll", shcode=15}, +[120463] = {category="ll", shcode=15}, +[120464] = {category="ll", shcode=15}, +[120465] = {category="ll", shcode=15}, +[120466] = {category="ll", shcode=15}, +[120467] = {category="ll", shcode=15}, +[120468] = {category="ll", shcode=15}, +[120469] = {category="ll", shcode=15}, +[120470] = {category="ll", shcode=15}, +[120471] = {category="ll", shcode=15}, +[120472] = {category="ll", shcode=15}, +[120473] = {category="ll", shcode=15}, +[120474] = {category="ll", shcode=15}, +[120475] = {category="ll", shcode=15}, +[120476] = {category="ll", shcode=15}, +[120477] = {category="ll", shcode=15}, +[120478] = {category="ll", shcode=15}, +[120479] = {category="ll", shcode=15}, +[120480] = {category="ll", shcode=15}, +[120481] = {category="ll", shcode=15}, +[120482] = {category="ll", shcode=15}, +[120483] = {category="ll", shcode=15}, +[120484] = {category="ll", shcode=15}, +[120485] = {category="ll", shcode=15}, +[120488] = {category="lu", shcode=15}, +[120489] = {category="lu", shcode=15}, +[120490] = {category="lu", shcode=15}, +[120491] = {category="lu", shcode=15}, +[120492] = {category="lu", shcode=15}, +[120493] = {category="lu", shcode=15}, +[120494] = {category="lu", shcode=15}, +[120495] = {category="lu", shcode=15}, +[120496] = {category="lu", shcode=15}, +[120497] = {category="lu", shcode=15}, +[120498] = {category="lu", shcode=15}, +[120499] = {category="lu", shcode=15}, +[120500] = {category="lu", shcode=15}, +[120501] = {category="lu", shcode=15}, +[120502] = {category="lu", shcode=15}, +[120503] = {category="lu", shcode=15}, +[120504] = {category="lu", shcode=15}, +[120505] = {category="lu", shcode=15}, +[120506] = {category="lu", shcode=15}, +[120507] = {category="lu", shcode=15}, +[120508] = {category="lu", shcode=15}, +[120509] = {category="lu", shcode=15}, +[120510] = {category="lu", shcode=15}, +[120511] = {category="lu", shcode=15}, +[120512] = {category="lu", shcode=15}, +[120514] = {category="ll", shcode=15}, +[120515] = {category="ll", shcode=15}, +[120516] = {category="ll", shcode=15}, +[120517] = {category="ll", shcode=15}, +[120518] = {category="ll", shcode=15}, +[120519] = {category="ll", shcode=15}, +[120520] = {category="ll", shcode=15}, +[120521] = {category="ll", shcode=15}, +[120522] = {category="ll", shcode=15}, +[120523] = {category="ll", shcode=15}, +[120524] = {category="ll", shcode=15}, +[120525] = {category="ll", shcode=15}, +[120526] = {category="ll", shcode=15}, +[120527] = {category="ll", shcode=15}, +[120528] = {category="ll", shcode=15}, +[120529] = {category="ll", shcode=15}, +[120530] = {category="ll", shcode=15}, +[120531] = {category="ll", shcode=15}, +[120532] = {category="ll", shcode=15}, +[120533] = {category="ll", shcode=15}, +[120534] = {category="ll", shcode=15}, +[120535] = {category="ll", shcode=15}, +[120536] = {category="ll", shcode=15}, +[120537] = {category="ll", shcode=15}, +[120538] = {category="ll", shcode=15}, +[120540] = {category="ll", shcode=15}, +[120541] = {category="ll", shcode=15}, +[120542] = {category="ll", shcode=15}, +[120543] = {category="ll", shcode=15}, +[120544] = {category="ll", shcode=15}, +[120545] = {category="ll", shcode=15}, +[120546] = {category="lu", shcode=15}, +[120547] = {category="lu", shcode=15}, +[120548] = {category="lu", shcode=15}, +[120549] = {category="lu", shcode=15}, +[120550] = {category="lu", shcode=15}, +[120551] = {category="lu", shcode=15}, +[120552] = {category="lu", shcode=15}, +[120553] = {category="lu", shcode=15}, +[120554] = {category="lu", shcode=15}, +[120555] = {category="lu", shcode=15}, +[120556] = {category="lu", shcode=15}, +[120557] = {category="lu", shcode=15}, +[120558] = {category="lu", shcode=15}, +[120559] = {category="lu", shcode=15}, +[120560] = {category="lu", shcode=15}, +[120561] = {category="lu", shcode=15}, +[120562] = {category="lu", shcode=15}, +[120563] = {category="lu", shcode=15}, +[120564] = {category="lu", shcode=15}, +[120565] = {category="lu", shcode=15}, +[120566] = {category="lu", shcode=15}, +[120567] = {category="lu", shcode=15}, +[120568] = {category="lu", shcode=15}, +[120569] = {category="lu", shcode=15}, +[120570] = {category="lu", shcode=15}, +[120572] = {category="ll", shcode=15}, +[120573] = {category="ll", shcode=15}, +[120574] = {category="ll", shcode=15}, +[120575] = {category="ll", shcode=15}, +[120576] = {category="ll", shcode=15}, +[120577] = {category="ll", shcode=15}, +[120578] = {category="ll", shcode=15}, +[120579] = {category="ll", shcode=15}, +[120580] = {category="ll", shcode=15}, +[120581] = {category="ll", shcode=15}, +[120582] = {category="ll", shcode=15}, +[120583] = {category="ll", shcode=15}, +[120584] = {category="ll", shcode=15}, +[120585] = {category="ll", shcode=15}, +[120586] = {category="ll", shcode=15}, +[120587] = {category="ll", shcode=15}, +[120588] = {category="ll", shcode=15}, +[120589] = {category="ll", shcode=15}, +[120590] = {category="ll", shcode=15}, +[120591] = {category="ll", shcode=15}, +[120592] = {category="ll", shcode=15}, +[120593] = {category="ll", shcode=15}, +[120594] = {category="ll", shcode=15}, +[120595] = {category="ll", shcode=15}, +[120596] = {category="ll", shcode=15}, +[120598] = {category="ll", shcode=15}, +[120599] = {category="ll", shcode=15}, +[120600] = {category="ll", shcode=15}, +[120601] = {category="ll", shcode=15}, +[120602] = {category="ll", shcode=15}, +[120603] = {category="ll", shcode=15}, +[120604] = {category="lu", shcode=15}, +[120605] = {category="lu", shcode=15}, +[120606] = {category="lu", shcode=15}, +[120607] = {category="lu", shcode=15}, +[120608] = {category="lu", shcode=15}, +[120609] = {category="lu", shcode=15}, +[120610] = {category="lu", shcode=15}, +[120611] = {category="lu", shcode=15}, +[120612] = {category="lu", shcode=15}, +[120613] = {category="lu", shcode=15}, +[120614] = {category="lu", shcode=15}, +[120615] = {category="lu", shcode=15}, +[120616] = {category="lu", shcode=15}, +[120617] = {category="lu", shcode=15}, +[120618] = {category="lu", shcode=15}, +[120619] = {category="lu", shcode=15}, +[120620] = {category="lu", shcode=15}, +[120621] = {category="lu", shcode=15}, +[120622] = {category="lu", shcode=15}, +[120623] = {category="lu", shcode=15}, +[120624] = {category="lu", shcode=15}, +[120625] = {category="lu", shcode=15}, +[120626] = {category="lu", shcode=15}, +[120627] = {category="lu", shcode=15}, +[120628] = {category="lu", shcode=15}, +[120630] = {category="ll", shcode=15}, +[120631] = {category="ll", shcode=15}, +[120632] = {category="ll", shcode=15}, +[120633] = {category="ll", shcode=15}, +[120634] = {category="ll", shcode=15}, +[120635] = {category="ll", shcode=15}, +[120636] = {category="ll", shcode=15}, +[120637] = {category="ll", shcode=15}, +[120638] = {category="ll", shcode=15}, +[120639] = {category="ll", shcode=15}, +[120640] = {category="ll", shcode=15}, +[120641] = {category="ll", shcode=15}, +[120642] = {category="ll", shcode=15}, +[120643] = {category="ll", shcode=15}, +[120644] = {category="ll", shcode=15}, +[120645] = {category="ll", shcode=15}, +[120646] = {category="ll", shcode=15}, +[120647] = {category="ll", shcode=15}, +[120648] = {category="ll", shcode=15}, +[120649] = {category="ll", shcode=15}, +[120650] = {category="ll", shcode=15}, +[120651] = {category="ll", shcode=15}, +[120652] = {category="ll", shcode=15}, +[120653] = {category="ll", shcode=15}, +[120654] = {category="ll", shcode=15}, +[120656] = {category="ll", shcode=15}, +[120657] = {category="ll", shcode=15}, +[120658] = {category="ll", shcode=15}, +[120659] = {category="ll", shcode=15}, +[120660] = {category="ll", shcode=15}, +[120661] = {category="ll", shcode=15}, +[120662] = {category="lu", shcode=15}, +[120663] = {category="lu", shcode=15}, +[120664] = {category="lu", shcode=15}, +[120665] = {category="lu", shcode=15}, +[120666] = {category="lu", shcode=15}, +[120667] = {category="lu", shcode=15}, +[120668] = {category="lu", shcode=15}, +[120669] = {category="lu", shcode=15}, +[120670] = {category="lu", shcode=15}, +[120671] = {category="lu", shcode=15}, +[120672] = {category="lu", shcode=15}, +[120673] = {category="lu", shcode=15}, +[120674] = {category="lu", shcode=15}, +[120675] = {category="lu", shcode=15}, +[120676] = {category="lu", shcode=15}, +[120677] = {category="lu", shcode=15}, +[120678] = {category="lu", shcode=15}, +[120679] = {category="lu", shcode=15}, +[120680] = {category="lu", shcode=15}, +[120681] = {category="lu", shcode=15}, +[120682] = {category="lu", shcode=15}, +[120683] = {category="lu", shcode=15}, +[120684] = {category="lu", shcode=15}, +[120685] = {category="lu", shcode=15}, +[120686] = {category="lu", shcode=15}, +[120688] = {category="ll", shcode=15}, +[120689] = {category="ll", shcode=15}, +[120690] = {category="ll", shcode=15}, +[120691] = {category="ll", shcode=15}, +[120692] = {category="ll", shcode=15}, +[120693] = {category="ll", shcode=15}, +[120694] = {category="ll", shcode=15}, +[120695] = {category="ll", shcode=15}, +[120696] = {category="ll", shcode=15}, +[120697] = {category="ll", shcode=15}, +[120698] = {category="ll", shcode=15}, +[120699] = {category="ll", shcode=15}, +[120700] = {category="ll", shcode=15}, +[120701] = {category="ll", shcode=15}, +[120702] = {category="ll", shcode=15}, +[120703] = {category="ll", shcode=15}, +[120704] = {category="ll", shcode=15}, +[120705] = {category="ll", shcode=15}, +[120706] = {category="ll", shcode=15}, +[120707] = {category="ll", shcode=15}, +[120708] = {category="ll", shcode=15}, +[120709] = {category="ll", shcode=15}, +[120710] = {category="ll", shcode=15}, +[120711] = {category="ll", shcode=15}, +[120712] = {category="ll", shcode=15}, +[120714] = {category="ll", shcode=15}, +[120715] = {category="ll", shcode=15}, +[120716] = {category="ll", shcode=15}, +[120717] = {category="ll", shcode=15}, +[120718] = {category="ll", shcode=15}, +[120719] = {category="ll", shcode=15}, +[120720] = {category="lu", shcode=15}, +[120721] = {category="lu", shcode=15}, +[120722] = {category="lu", shcode=15}, +[120723] = {category="lu", shcode=15}, +[120724] = {category="lu", shcode=15}, +[120725] = {category="lu", shcode=15}, +[120726] = {category="lu", shcode=15}, +[120727] = {category="lu", shcode=15}, +[120728] = {category="lu", shcode=15}, +[120729] = {category="lu", shcode=15}, +[120730] = {category="lu", shcode=15}, +[120731] = {category="lu", shcode=15}, +[120732] = {category="lu", shcode=15}, +[120733] = {category="lu", shcode=15}, +[120734] = {category="lu", shcode=15}, +[120735] = {category="lu", shcode=15}, +[120736] = {category="lu", shcode=15}, +[120737] = {category="lu", shcode=15}, +[120738] = {category="lu", shcode=15}, +[120739] = {category="lu", shcode=15}, +[120740] = {category="lu", shcode=15}, +[120741] = {category="lu", shcode=15}, +[120742] = {category="lu", shcode=15}, +[120743] = {category="lu", shcode=15}, +[120744] = {category="lu", shcode=15}, +[120746] = {category="ll", shcode=15}, +[120747] = {category="ll", shcode=15}, +[120748] = {category="ll", shcode=15}, +[120749] = {category="ll", shcode=15}, +[120750] = {category="ll", shcode=15}, +[120751] = {category="ll", shcode=15}, +[120752] = {category="ll", shcode=15}, +[120753] = {category="ll", shcode=15}, +[120754] = {category="ll", shcode=15}, +[120755] = {category="ll", shcode=15}, +[120756] = {category="ll", shcode=15}, +[120757] = {category="ll", shcode=15}, +[120758] = {category="ll", shcode=15}, +[120759] = {category="ll", shcode=15}, +[120760] = {category="ll", shcode=15}, +[120761] = {category="ll", shcode=15}, +[120762] = {category="ll", shcode=15}, +[120763] = {category="ll", shcode=15}, +[120764] = {category="ll", shcode=15}, +[120765] = {category="ll", shcode=15}, +[120766] = {category="ll", shcode=15}, +[120767] = {category="ll", shcode=15}, +[120768] = {category="ll", shcode=15}, +[120769] = {category="ll", shcode=15}, +[120770] = {category="ll", shcode=15}, +[120772] = {category="ll", shcode=15}, +[120773] = {category="ll", shcode=15}, +[120774] = {category="ll", shcode=15}, +[120775] = {category="ll", shcode=15}, +[120776] = {category="ll", shcode=15}, +[120777] = {category="ll", shcode=15}, +[120778] = {category="lu", shcode=15}, +[120779] = {category="ll", shcode=15}, +[122624] = {category="ll"}, +[122625] = {category="ll"}, +[122626] = {category="ll"}, +[122627] = {category="ll"}, +[122628] = {category="ll"}, +[122629] = {category="ll"}, +[122630] = {category="ll"}, +[122631] = {category="ll"}, +[122632] = {category="ll"}, +[122633] = {category="ll"}, +[122634] = {category="lo"}, +[122635] = {category="ll"}, +[122636] = {category="ll"}, +[122637] = {category="ll"}, +[122638] = {category="ll"}, +[122639] = {category="ll"}, +[122640] = {category="ll"}, +[122641] = {category="ll"}, +[122642] = {category="ll"}, +[122643] = {category="ll"}, +[122644] = {category="ll"}, +[122645] = {category="ll"}, +[122646] = {category="ll"}, +[122647] = {category="ll"}, +[122648] = {category="ll"}, +[122649] = {category="ll"}, +[122650] = {category="ll"}, +[122651] = {category="ll"}, +[122652] = {category="ll"}, +[122653] = {category="ll"}, +[122654] = {category="ll"}, +[122661] = {category="ll"}, +[122662] = {category="ll"}, +[122663] = {category="ll"}, +[122664] = {category="ll"}, +[122665] = {category="ll"}, +[122666] = {category="ll"}, +[122928] = {category="lm", shcode=14}, +[122929] = {category="lm", shcode=14}, +[122930] = {category="lm", shcode=14}, +[122931] = {category="lm", shcode=14}, +[122932] = {category="lm", shcode=14}, +[122933] = {category="lm", shcode=14}, +[122934] = {category="lm", shcode=14}, +[122935] = {category="lm", shcode=14}, +[122936] = {category="lm", shcode=14}, +[122937] = {category="lm", shcode=14}, +[122938] = {category="lm", shcode=14}, +[122939] = {category="lm", shcode=14}, +[122940] = {category="lm", shcode=14}, +[122941] = {category="lm", shcode=14}, +[122942] = {category="lm", shcode=14}, +[122943] = {category="lm", shcode=14}, +[122944] = {category="lm", shcode=14}, +[122945] = {category="lm", shcode=14}, +[122946] = {category="lm", shcode=14}, +[122947] = {category="lm", shcode=14}, +[122948] = {category="lm", shcode=14}, +[122949] = {category="lm", shcode=14}, +[122950] = {category="lm", shcode=14}, +[122951] = {category="lm", shcode=14}, +[122952] = {category="lm", shcode=14}, +[122953] = {category="lm", shcode=14}, +[122954] = {category="lm", shcode=14}, +[122955] = {category="lm", shcode=14}, +[122956] = {category="lm", shcode=14}, +[122957] = {category="lm", shcode=14}, +[122958] = {category="lm", shcode=14}, +[122959] = {category="lm", shcode=14}, +[122960] = {category="lm", shcode=14}, +[122961] = {category="lm", shcode=11}, +[122962] = {category="lm", shcode=11}, +[122963] = {category="lm", shcode=11}, +[122964] = {category="lm", shcode=11}, +[122965] = {category="lm", shcode=11}, +[122966] = {category="lm", shcode=11}, +[122967] = {category="lm", shcode=11}, +[122968] = {category="lm", shcode=11}, +[122969] = {category="lm", shcode=11}, +[122970] = {category="lm", shcode=11}, +[122971] = {category="lm", shcode=11}, +[122972] = {category="lm", shcode=11}, +[122973] = {category="lm", shcode=11}, +[122974] = {category="lm", shcode=11}, +[122975] = {category="lm", shcode=11}, +[122976] = {category="lm", shcode=11}, +[122977] = {category="lm", shcode=11}, +[122978] = {category="lm", shcode=11}, +[122979] = {category="lm", shcode=11}, +[122980] = {category="lm", shcode=11}, +[122981] = {category="lm", shcode=11}, +[122982] = {category="lm", shcode=11}, +[122983] = {category="lm", shcode=11}, +[122984] = {category="lm", shcode=11}, +[122985] = {category="lm", shcode=11}, +[122986] = {category="lm", shcode=11}, +[122987] = {category="lm", shcode=14}, +[122988] = {category="lm", shcode=14}, +[122989] = {category="lm", shcode=14}, +[123136] = {category="lo"}, +[123137] = {category="lo"}, +[123138] = {category="lo"}, +[123139] = {category="lo"}, +[123140] = {category="lo"}, +[123141] = {category="lo"}, +[123142] = {category="lo"}, +[123143] = {category="lo"}, +[123144] = {category="lo"}, +[123145] = {category="lo"}, +[123146] = {category="lo"}, +[123147] = {category="lo"}, +[123148] = {category="lo"}, +[123149] = {category="lo"}, +[123150] = {category="lo"}, +[123151] = {category="lo"}, +[123152] = {category="lo"}, +[123153] = {category="lo"}, +[123154] = {category="lo"}, +[123155] = {category="lo"}, +[123156] = {category="lo"}, +[123157] = {category="lo"}, +[123158] = {category="lo"}, +[123159] = {category="lo"}, +[123160] = {category="lo"}, +[123161] = {category="lo"}, +[123162] = {category="lo"}, +[123163] = {category="lo"}, +[123164] = {category="lo"}, +[123165] = {category="lo"}, +[123166] = {category="lo"}, +[123167] = {category="lo"}, +[123168] = {category="lo"}, +[123169] = {category="lo"}, +[123170] = {category="lo"}, +[123171] = {category="lo"}, +[123172] = {category="lo"}, +[123173] = {category="lo"}, +[123174] = {category="lo"}, +[123175] = {category="lo"}, +[123176] = {category="lo"}, +[123177] = {category="lo"}, +[123178] = {category="lo"}, +[123179] = {category="lo"}, +[123180] = {category="lo"}, +[123191] = {category="lm"}, +[123192] = {category="lm"}, +[123193] = {category="lm"}, +[123194] = {category="lm"}, +[123195] = {category="lm"}, +[123196] = {category="lm"}, +[123197] = {category="lm"}, +[123214] = {category="lo"}, +[123536] = {category="lo"}, +[123537] = {category="lo"}, +[123538] = {category="lo"}, +[123539] = {category="lo"}, +[123540] = {category="lo"}, +[123541] = {category="lo"}, +[123542] = {category="lo"}, +[123543] = {category="lo"}, +[123544] = {category="lo"}, +[123545] = {category="lo"}, +[123546] = {category="lo"}, +[123547] = {category="lo"}, +[123548] = {category="lo"}, +[123549] = {category="lo"}, +[123550] = {category="lo"}, +[123551] = {category="lo"}, +[123552] = {category="lo"}, +[123553] = {category="lo"}, +[123554] = {category="lo"}, +[123555] = {category="lo"}, +[123556] = {category="lo"}, +[123557] = {category="lo"}, +[123558] = {category="lo"}, +[123559] = {category="lo"}, +[123560] = {category="lo"}, +[123561] = {category="lo"}, +[123562] = {category="lo"}, +[123563] = {category="lo"}, +[123564] = {category="lo"}, +[123565] = {category="lo"}, +[123584] = {category="lo"}, +[123585] = {category="lo"}, +[123586] = {category="lo"}, +[123587] = {category="lo"}, +[123588] = {category="lo"}, +[123589] = {category="lo"}, +[123590] = {category="lo"}, +[123591] = {category="lo"}, +[123592] = {category="lo"}, +[123593] = {category="lo"}, +[123594] = {category="lo"}, +[123595] = {category="lo"}, +[123596] = {category="lo"}, +[123597] = {category="lo"}, +[123598] = {category="lo"}, +[123599] = {category="lo"}, +[123600] = {category="lo"}, +[123601] = {category="lo"}, +[123602] = {category="lo"}, +[123603] = {category="lo"}, +[123604] = {category="lo"}, +[123605] = {category="lo"}, +[123606] = {category="lo"}, +[123607] = {category="lo"}, +[123608] = {category="lo"}, +[123609] = {category="lo"}, +[123610] = {category="lo"}, +[123611] = {category="lo"}, +[123612] = {category="lo"}, +[123613] = {category="lo"}, +[123614] = {category="lo"}, +[123615] = {category="lo"}, +[123616] = {category="lo"}, +[123617] = {category="lo"}, +[123618] = {category="lo"}, +[123619] = {category="lo"}, +[123620] = {category="lo"}, +[123621] = {category="lo"}, +[123622] = {category="lo"}, +[123623] = {category="lo"}, +[123624] = {category="lo"}, +[123625] = {category="lo"}, +[123626] = {category="lo"}, +[123627] = {category="lo"}, +[124112] = {category="lo"}, +[124113] = {category="lo"}, +[124114] = {category="lo"}, +[124115] = {category="lo"}, +[124116] = {category="lo"}, +[124117] = {category="lo"}, +[124118] = {category="lo"}, +[124119] = {category="lo"}, +[124120] = {category="lo"}, +[124121] = {category="lo"}, +[124122] = {category="lo"}, +[124123] = {category="lo"}, +[124124] = {category="lo"}, +[124125] = {category="lo"}, +[124126] = {category="lo"}, +[124127] = {category="lo"}, +[124128] = {category="lo"}, +[124129] = {category="lo"}, +[124130] = {category="lo"}, +[124131] = {category="lo"}, +[124132] = {category="lo"}, +[124133] = {category="lo"}, +[124134] = {category="lo"}, +[124135] = {category="lo"}, +[124136] = {category="lo"}, +[124137] = {category="lo"}, +[124138] = {category="lo"}, +[124139] = {category="lm"}, +[124896] = {category="lo"}, +[124897] = {category="lo"}, +[124898] = {category="lo"}, +[124899] = {category="lo"}, +[124900] = {category="lo"}, +[124901] = {category="lo"}, +[124902] = {category="lo"}, +[124904] = {category="lo"}, +[124905] = {category="lo"}, +[124906] = {category="lo"}, +[124907] = {category="lo"}, +[124909] = {category="lo"}, +[124910] = {category="lo"}, +[124912] = {category="lo"}, +[124913] = {category="lo"}, +[124914] = {category="lo"}, +[124915] = {category="lo"}, +[124916] = {category="lo"}, +[124917] = {category="lo"}, +[124918] = {category="lo"}, +[124919] = {category="lo"}, +[124920] = {category="lo"}, +[124921] = {category="lo"}, +[124922] = {category="lo"}, +[124923] = {category="lo"}, +[124924] = {category="lo"}, +[124925] = {category="lo"}, +[124926] = {category="lo"}, +[124928] = {category="lo"}, +[124929] = {category="lo"}, +[124930] = {category="lo"}, +[124931] = {category="lo"}, +[124932] = {category="lo"}, +[124933] = {category="lo"}, +[124934] = {category="lo"}, +[124935] = {category="lo"}, +[124936] = {category="lo"}, +[124937] = {category="lo"}, +[124938] = {category="lo"}, +[124939] = {category="lo"}, +[124940] = {category="lo"}, +[124941] = {category="lo"}, +[124942] = {category="lo"}, +[124943] = {category="lo"}, +[124944] = {category="lo"}, +[124945] = {category="lo"}, +[124946] = {category="lo"}, +[124947] = {category="lo"}, +[124948] = {category="lo"}, +[124949] = {category="lo"}, +[124950] = {category="lo"}, +[124951] = {category="lo"}, +[124952] = {category="lo"}, +[124953] = {category="lo"}, +[124954] = {category="lo"}, +[124955] = {category="lo"}, +[124956] = {category="lo"}, +[124957] = {category="lo"}, +[124958] = {category="lo"}, +[124959] = {category="lo"}, +[124960] = {category="lo"}, +[124961] = {category="lo"}, +[124962] = {category="lo"}, +[124963] = {category="lo"}, +[124964] = {category="lo"}, +[124965] = {category="lo"}, +[124966] = {category="lo"}, +[124967] = {category="lo"}, +[124968] = {category="lo"}, +[124969] = {category="lo"}, +[124970] = {category="lo"}, +[124971] = {category="lo"}, +[124972] = {category="lo"}, +[124973] = {category="lo"}, +[124974] = {category="lo"}, +[124975] = {category="lo"}, +[124976] = {category="lo"}, +[124977] = {category="lo"}, +[124978] = {category="lo"}, +[124979] = {category="lo"}, +[124980] = {category="lo"}, +[124981] = {category="lo"}, +[124982] = {category="lo"}, +[124983] = {category="lo"}, +[124984] = {category="lo"}, +[124985] = {category="lo"}, +[124986] = {category="lo"}, +[124987] = {category="lo"}, +[124988] = {category="lo"}, +[124989] = {category="lo"}, +[124990] = {category="lo"}, +[124991] = {category="lo"}, +[124992] = {category="lo"}, +[124993] = {category="lo"}, +[124994] = {category="lo"}, +[124995] = {category="lo"}, +[124996] = {category="lo"}, +[124997] = {category="lo"}, +[124998] = {category="lo"}, +[124999] = {category="lo"}, +[125000] = {category="lo"}, +[125001] = {category="lo"}, +[125002] = {category="lo"}, +[125003] = {category="lo"}, +[125004] = {category="lo"}, +[125005] = {category="lo"}, +[125006] = {category="lo"}, +[125007] = {category="lo"}, +[125008] = {category="lo"}, +[125009] = {category="lo"}, +[125010] = {category="lo"}, +[125011] = {category="lo"}, +[125012] = {category="lo"}, +[125013] = {category="lo"}, +[125014] = {category="lo"}, +[125015] = {category="lo"}, +[125016] = {category="lo"}, +[125017] = {category="lo"}, +[125018] = {category="lo"}, +[125019] = {category="lo"}, +[125020] = {category="lo"}, +[125021] = {category="lo"}, +[125022] = {category="lo"}, +[125023] = {category="lo"}, +[125024] = {category="lo"}, +[125025] = {category="lo"}, +[125026] = {category="lo"}, +[125027] = {category="lo"}, +[125028] = {category="lo"}, +[125029] = {category="lo"}, +[125030] = {category="lo"}, +[125031] = {category="lo"}, +[125032] = {category="lo"}, +[125033] = {category="lo"}, +[125034] = {category="lo"}, +[125035] = {category="lo"}, +[125036] = {category="lo"}, +[125037] = {category="lo"}, +[125038] = {category="lo"}, +[125039] = {category="lo"}, +[125040] = {category="lo"}, +[125041] = {category="lo"}, +[125042] = {category="lo"}, +[125043] = {category="lo"}, +[125044] = {category="lo"}, +[125045] = {category="lo"}, +[125046] = {category="lo"}, +[125047] = {category="lo"}, +[125048] = {category="lo"}, +[125049] = {category="lo"}, +[125050] = {category="lo"}, +[125051] = {category="lo"}, +[125052] = {category="lo"}, +[125053] = {category="lo"}, +[125054] = {category="lo"}, +[125055] = {category="lo"}, +[125056] = {category="lo"}, +[125057] = {category="lo"}, +[125058] = {category="lo"}, +[125059] = {category="lo"}, +[125060] = {category="lo"}, +[125061] = {category="lo"}, +[125062] = {category="lo"}, +[125063] = {category="lo"}, +[125064] = {category="lo"}, +[125065] = {category="lo"}, +[125066] = {category="lo"}, +[125067] = {category="lo"}, +[125068] = {category="lo"}, +[125069] = {category="lo"}, +[125070] = {category="lo"}, +[125071] = {category="lo"}, +[125072] = {category="lo"}, +[125073] = {category="lo"}, +[125074] = {category="lo"}, +[125075] = {category="lo"}, +[125076] = {category="lo"}, +[125077] = {category="lo"}, +[125078] = {category="lo"}, +[125079] = {category="lo"}, +[125080] = {category="lo"}, +[125081] = {category="lo"}, +[125082] = {category="lo"}, +[125083] = {category="lo"}, +[125084] = {category="lo"}, +[125085] = {category="lo"}, +[125086] = {category="lo"}, +[125087] = {category="lo"}, +[125088] = {category="lo"}, +[125089] = {category="lo"}, +[125090] = {category="lo"}, +[125091] = {category="lo"}, +[125092] = {category="lo"}, +[125093] = {category="lo"}, +[125094] = {category="lo"}, +[125095] = {category="lo"}, +[125096] = {category="lo"}, +[125097] = {category="lo"}, +[125098] = {category="lo"}, +[125099] = {category="lo"}, +[125100] = {category="lo"}, +[125101] = {category="lo"}, +[125102] = {category="lo"}, +[125103] = {category="lo"}, +[125104] = {category="lo"}, +[125105] = {category="lo"}, +[125106] = {category="lo"}, +[125107] = {category="lo"}, +[125108] = {category="lo"}, +[125109] = {category="lo"}, +[125110] = {category="lo"}, +[125111] = {category="lo"}, +[125112] = {category="lo"}, +[125113] = {category="lo"}, +[125114] = {category="lo"}, +[125115] = {category="lo"}, +[125116] = {category="lo"}, +[125117] = {category="lo"}, +[125118] = {category="lo"}, +[125119] = {category="lo"}, +[125120] = {category="lo"}, +[125121] = {category="lo"}, +[125122] = {category="lo"}, +[125123] = {category="lo"}, +[125124] = {category="lo"}, +[125184] = {category="lu", lccode=125218}, +[125185] = {category="lu", lccode=125219}, +[125186] = {category="lu", lccode=125220}, +[125187] = {category="lu", lccode=125221}, +[125188] = {category="lu", lccode=125222}, +[125189] = {category="lu", lccode=125223}, +[125190] = {category="lu", lccode=125224}, +[125191] = {category="lu", lccode=125225}, +[125192] = {category="lu", lccode=125226}, +[125193] = {category="lu", lccode=125227}, +[125194] = {category="lu", lccode=125228}, +[125195] = {category="lu", lccode=125229}, +[125196] = {category="lu", lccode=125230}, +[125197] = {category="lu", lccode=125231}, +[125198] = {category="lu", lccode=125232}, +[125199] = {category="lu", lccode=125233}, +[125200] = {category="lu", lccode=125234}, +[125201] = {category="lu", lccode=125235}, +[125202] = {category="lu", lccode=125236}, +[125203] = {category="lu", lccode=125237}, +[125204] = {category="lu", lccode=125238}, +[125205] = {category="lu", lccode=125239}, +[125206] = {category="lu", lccode=125240}, +[125207] = {category="lu", lccode=125241}, +[125208] = {category="lu", lccode=125242}, +[125209] = {category="lu", lccode=125243}, +[125210] = {category="lu", lccode=125244}, +[125211] = {category="lu", lccode=125245}, +[125212] = {category="lu", lccode=125246}, +[125213] = {category="lu", lccode=125247}, +[125214] = {category="lu", lccode=125248}, +[125215] = {category="lu", lccode=125249}, +[125216] = {category="lu", lccode=125250}, +[125217] = {category="lu", lccode=125251}, +[125218] = {category="ll"}, +[125219] = {category="ll"}, +[125220] = {category="ll"}, +[125221] = {category="ll"}, +[125222] = {category="ll"}, +[125223] = {category="ll"}, +[125224] = {category="ll"}, +[125225] = {category="ll"}, +[125226] = {category="ll"}, +[125227] = {category="ll"}, +[125228] = {category="ll"}, +[125229] = {category="ll"}, +[125230] = {category="ll"}, +[125231] = {category="ll"}, +[125232] = {category="ll"}, +[125233] = {category="ll"}, +[125234] = {category="ll"}, +[125235] = {category="ll"}, +[125236] = {category="ll"}, +[125237] = {category="ll"}, +[125238] = {category="ll"}, +[125239] = {category="ll"}, +[125240] = {category="ll"}, +[125241] = {category="ll"}, +[125242] = {category="ll"}, +[125243] = {category="ll"}, +[125244] = {category="ll"}, +[125245] = {category="ll"}, +[125246] = {category="ll"}, +[125247] = {category="ll"}, +[125248] = {category="ll"}, +[125249] = {category="ll"}, +[125250] = {category="ll"}, +[125251] = {category="ll"}, +[125259] = {category="lm"}, +[126464] = {category="lo", shcode=15}, +[126465] = {category="lo", shcode=15}, +[126466] = {category="lo", shcode=15}, +[126467] = {category="lo", shcode=15}, +[126469] = {category="lo", shcode=15}, +[126470] = {category="lo", shcode=15}, +[126471] = {category="lo", shcode=15}, +[126472] = {category="lo", shcode=15}, +[126473] = {category="lo", shcode=15}, +[126474] = {category="lo", shcode=15}, +[126475] = {category="lo", shcode=15}, +[126476] = {category="lo", shcode=15}, +[126477] = {category="lo", shcode=15}, +[126478] = {category="lo", shcode=15}, +[126479] = {category="lo", shcode=15}, +[126480] = {category="lo", shcode=15}, +[126481] = {category="lo", shcode=15}, +[126482] = {category="lo", shcode=15}, +[126483] = {category="lo", shcode=15}, +[126484] = {category="lo", shcode=15}, +[126485] = {category="lo", shcode=15}, +[126486] = {category="lo", shcode=15}, +[126487] = {category="lo", shcode=15}, +[126488] = {category="lo", shcode=15}, +[126489] = {category="lo", shcode=15}, +[126490] = {category="lo", shcode=15}, +[126491] = {category="lo", shcode=15}, +[126492] = {category="lo", shcode=15}, +[126493] = {category="lo", shcode=15}, +[126494] = {category="lo", shcode=15}, +[126495] = {category="lo", shcode=15}, +[126497] = {category="lo", shcode=15}, +[126498] = {category="lo", shcode=15}, +[126500] = {category="lo", shcode=15}, +[126503] = {category="lo", shcode=15}, +[126505] = {category="lo", shcode=15}, +[126506] = {category="lo", shcode=15}, +[126507] = {category="lo", shcode=15}, +[126508] = {category="lo", shcode=15}, +[126509] = {category="lo", shcode=15}, +[126510] = {category="lo", shcode=15}, +[126511] = {category="lo", shcode=15}, +[126512] = {category="lo", shcode=15}, +[126513] = {category="lo", shcode=15}, +[126514] = {category="lo", shcode=15}, +[126516] = {category="lo", shcode=15}, +[126517] = {category="lo", shcode=15}, +[126518] = {category="lo", shcode=15}, +[126519] = {category="lo", shcode=15}, +[126521] = {category="lo", shcode=15}, +[126523] = {category="lo", shcode=15}, +[126530] = {category="lo", shcode=15}, +[126535] = {category="lo", shcode=15}, +[126537] = {category="lo", shcode=15}, +[126539] = {category="lo", shcode=15}, +[126541] = {category="lo", shcode=15}, +[126542] = {category="lo", shcode=15}, +[126543] = {category="lo", shcode=15}, +[126545] = {category="lo", shcode=15}, +[126546] = {category="lo", shcode=15}, +[126548] = {category="lo", shcode=15}, +[126551] = {category="lo", shcode=15}, +[126553] = {category="lo", shcode=15}, +[126555] = {category="lo", shcode=15}, +[126557] = {category="lo", shcode=15}, +[126559] = {category="lo", shcode=15}, +[126561] = {category="lo", shcode=15}, +[126562] = {category="lo", shcode=15}, +[126564] = {category="lo", shcode=15}, +[126567] = {category="lo", shcode=15}, +[126568] = {category="lo", shcode=15}, +[126569] = {category="lo", shcode=15}, +[126570] = {category="lo", shcode=15}, +[126572] = {category="lo", shcode=15}, +[126573] = {category="lo", shcode=15}, +[126574] = {category="lo", shcode=15}, +[126575] = {category="lo", shcode=15}, +[126576] = {category="lo", shcode=15}, +[126577] = {category="lo", shcode=15}, +[126578] = {category="lo", shcode=15}, +[126580] = {category="lo", shcode=15}, +[126581] = {category="lo", shcode=15}, +[126582] = {category="lo", shcode=15}, +[126583] = {category="lo", shcode=15}, +[126585] = {category="lo", shcode=15}, +[126586] = {category="lo", shcode=15}, +[126587] = {category="lo", shcode=15}, +[126588] = {category="lo", shcode=15}, +[126590] = {category="lo", shcode=15}, +[126592] = {category="lo", shcode=15}, +[126593] = {category="lo", shcode=15}, +[126594] = {category="lo", shcode=15}, +[126595] = {category="lo", shcode=15}, +[126596] = {category="lo", shcode=15}, +[126597] = {category="lo", shcode=15}, +[126598] = {category="lo", shcode=15}, +[126599] = {category="lo", shcode=15}, +[126600] = {category="lo", shcode=15}, +[126601] = {category="lo", shcode=15}, +[126603] = {category="lo", shcode=15}, +[126604] = {category="lo", shcode=15}, +[126605] = {category="lo", shcode=15}, +[126606] = {category="lo", shcode=15}, +[126607] = {category="lo", shcode=15}, +[126608] = {category="lo", shcode=15}, +[126609] = {category="lo", shcode=15}, +[126610] = {category="lo", shcode=15}, +[126611] = {category="lo", shcode=15}, +[126612] = {category="lo", shcode=15}, +[126613] = {category="lo", shcode=15}, +[126614] = {category="lo", shcode=15}, +[126615] = {category="lo", shcode=15}, +[126616] = {category="lo", shcode=15}, +[126617] = {category="lo", shcode=15}, +[126618] = {category="lo", shcode=15}, +[126619] = {category="lo", shcode=15}, +[126625] = {category="lo", shcode=15}, +[126626] = {category="lo", shcode=15}, +[126627] = {category="lo", shcode=15}, +[126629] = {category="lo", shcode=15}, +[126630] = {category="lo", shcode=15}, +[126631] = {category="lo", shcode=15}, +[126632] = {category="lo", shcode=15}, +[126633] = {category="lo", shcode=15}, +[126635] = {category="lo", shcode=15}, +[126636] = {category="lo", shcode=15}, +[126637] = {category="lo", shcode=15}, +[126638] = {category="lo", shcode=15}, +[126639] = {category="lo", shcode=15}, +[126640] = {category="lo", shcode=15}, +[126641] = {category="lo", shcode=15}, +[126642] = {category="lo", shcode=15}, +[126643] = {category="lo", shcode=15}, +[126644] = {category="lo", shcode=15}, +[126645] = {category="lo", shcode=15}, +[126646] = {category="lo", shcode=15}, +[126647] = {category="lo", shcode=15}, +[126648] = {category="lo", shcode=15}, +[126649] = {category="lo", shcode=15}, +[126650] = {category="lo", shcode=15}, +[126651] = {category="lo", shcode=15}, +[131072] = {category="lo"}, +[173791] = {category="lo"}, +[173824] = {category="lo"}, +[177977] = {category="lo"}, +[177984] = {category="lo"}, +[178205] = {category="lo"}, +[178208] = {category="lo"}, +[183969] = {category="lo"}, +[183984] = {category="lo"}, +[191456] = {category="lo"}, +[191472] = {category="lo"}, +[192093] = {category="lo"}, +[194560] = {category="lo", shcode=20029}, +[194561] = {category="lo", shcode=20024}, +[194562] = {category="lo", shcode=20033}, +[194563] = {category="lo", shcode=131362}, +[194564] = {category="lo", shcode=20320}, +[194565] = {category="lo", shcode=20398}, +[194566] = {category="lo", shcode=20411}, +[194567] = {category="lo", shcode=20482}, +[194568] = {category="lo", shcode=20602}, +[194569] = {category="lo", shcode=20633}, +[194570] = {category="lo", shcode=20711}, +[194571] = {category="lo", shcode=20687}, +[194572] = {category="lo", shcode=13470}, +[194573] = {category="lo", shcode=132666}, +[194574] = {category="lo", shcode=20813}, +[194575] = {category="lo", shcode=20820}, +[194576] = {category="lo", shcode=20836}, +[194577] = {category="lo", shcode=20855}, +[194578] = {category="lo", shcode=132380}, +[194579] = {category="lo", shcode=13497}, +[194580] = {category="lo", shcode=20839}, +[194581] = {category="lo", shcode=20877}, +[194582] = {category="lo", shcode=132427}, +[194583] = {category="lo", shcode=20887}, +[194584] = {category="lo", shcode=20900}, +[194585] = {category="lo", shcode=20172}, +[194586] = {category="lo", shcode=20908}, +[194587] = {category="lo", shcode=20917}, +[194588] = {category="lo", shcode=168415}, +[194589] = {category="lo", shcode=20981}, +[194590] = {category="lo", shcode=20995}, +[194591] = {category="lo", shcode=13535}, +[194592] = {category="lo", shcode=21051}, +[194593] = {category="lo", shcode=21062}, +[194594] = {category="lo", shcode=21106}, +[194595] = {category="lo", shcode=21111}, +[194596] = {category="lo", shcode=13589}, +[194597] = {category="lo", shcode=21191}, +[194598] = {category="lo", shcode=21193}, +[194599] = {category="lo", shcode=21220}, +[194600] = {category="lo", shcode=21242}, +[194601] = {category="lo", shcode=21253}, +[194602] = {category="lo", shcode=21254}, +[194603] = {category="lo", shcode=21271}, +[194604] = {category="lo", shcode=21321}, +[194605] = {category="lo", shcode=21329}, +[194606] = {category="lo", shcode=21338}, +[194607] = {category="lo", shcode=21363}, +[194608] = {category="lo", shcode=21373}, +[194609] = {category="lo", shcode=21375}, +[194610] = {category="lo", shcode=21375}, +[194611] = {category="lo", shcode=21375}, +[194612] = {category="lo", shcode=133676}, +[194613] = {category="lo", shcode=28784}, +[194614] = {category="lo", shcode=21450}, +[194615] = {category="lo", shcode=21471}, +[194616] = {category="lo", shcode=133987}, +[194617] = {category="lo", shcode=21483}, +[194618] = {category="lo", shcode=21489}, +[194619] = {category="lo", shcode=21510}, +[194620] = {category="lo", shcode=21662}, +[194621] = {category="lo", shcode=21560}, +[194622] = {category="lo", shcode=21576}, +[194623] = {category="lo", shcode=21608}, +[194624] = {category="lo", shcode=21666}, +[194625] = {category="lo", shcode=21750}, +[194626] = {category="lo", shcode=21776}, +[194627] = {category="lo", shcode=21843}, +[194628] = {category="lo", shcode=21859}, +[194629] = {category="lo", shcode=21892}, +[194630] = {category="lo", shcode=21892}, +[194631] = {category="lo", shcode=21913}, +[194632] = {category="lo", shcode=21931}, +[194633] = {category="lo", shcode=21939}, +[194634] = {category="lo", shcode=21954}, +[194635] = {category="lo", shcode=22294}, +[194636] = {category="lo", shcode=22022}, +[194637] = {category="lo", shcode=22295}, +[194638] = {category="lo", shcode=22097}, +[194639] = {category="lo", shcode=22132}, +[194640] = {category="lo", shcode=20999}, +[194641] = {category="lo", shcode=22766}, +[194642] = {category="lo", shcode=22478}, +[194643] = {category="lo", shcode=22516}, +[194644] = {category="lo", shcode=22541}, +[194645] = {category="lo", shcode=22411}, +[194646] = {category="lo", shcode=22578}, +[194647] = {category="lo", shcode=22577}, +[194648] = {category="lo", shcode=22700}, +[194649] = {category="lo", shcode=136420}, +[194650] = {category="lo", shcode=22770}, +[194651] = {category="lo", shcode=22775}, +[194652] = {category="lo", shcode=22790}, +[194653] = {category="lo", shcode=22810}, +[194654] = {category="lo", shcode=22818}, +[194655] = {category="lo", shcode=22882}, +[194656] = {category="lo", shcode=136872}, +[194657] = {category="lo", shcode=136938}, +[194658] = {category="lo", shcode=23020}, +[194659] = {category="lo", shcode=23067}, +[194660] = {category="lo", shcode=23079}, +[194661] = {category="lo", shcode=23000}, +[194662] = {category="lo", shcode=23142}, +[194663] = {category="lo", shcode=14062}, +[194664] = {category="lo", shcode=14076}, +[194665] = {category="lo", shcode=23304}, +[194666] = {category="lo", shcode=23358}, +[194667] = {category="lo", shcode=23358}, +[194668] = {category="lo", shcode=137672}, +[194669] = {category="lo", shcode=23491}, +[194670] = {category="lo", shcode=23512}, +[194671] = {category="lo", shcode=23527}, +[194672] = {category="lo", shcode=23539}, +[194673] = {category="lo", shcode=138008}, +[194674] = {category="lo", shcode=23551}, +[194675] = {category="lo", shcode=23558}, +[194676] = {category="lo", shcode=24403}, +[194677] = {category="lo", shcode=23586}, +[194678] = {category="lo", shcode=14209}, +[194679] = {category="lo", shcode=23648}, +[194680] = {category="lo", shcode=23662}, +[194681] = {category="lo", shcode=23744}, +[194682] = {category="lo", shcode=23693}, +[194683] = {category="lo", shcode=138724}, +[194684] = {category="lo", shcode=23875}, +[194685] = {category="lo", shcode=138726}, +[194686] = {category="lo", shcode=23918}, +[194687] = {category="lo", shcode=23915}, +[194688] = {category="lo", shcode=23932}, +[194689] = {category="lo", shcode=24033}, +[194690] = {category="lo", shcode=24034}, +[194691] = {category="lo", shcode=14383}, +[194692] = {category="lo", shcode=24061}, +[194693] = {category="lo", shcode=24104}, +[194694] = {category="lo", shcode=24125}, +[194695] = {category="lo", shcode=24169}, +[194696] = {category="lo", shcode=14434}, +[194697] = {category="lo", shcode=139651}, +[194698] = {category="lo", shcode=14460}, +[194699] = {category="lo", shcode=24240}, +[194700] = {category="lo", shcode=24243}, +[194701] = {category="lo", shcode=24246}, +[194702] = {category="lo", shcode=24266}, +[194703] = {category="lo", shcode=172946}, +[194704] = {category="lo", shcode=24318}, +[194705] = {category="lo", shcode=140081}, +[194706] = {category="lo", shcode=140081}, +[194707] = {category="lo", shcode=33281}, +[194708] = {category="lo", shcode=24354}, +[194709] = {category="lo", shcode=24354}, +[194710] = {category="lo", shcode=14535}, +[194711] = {category="lo", shcode=144056}, +[194712] = {category="lo", shcode=156122}, +[194713] = {category="lo", shcode=24418}, +[194714] = {category="lo", shcode=24427}, +[194715] = {category="lo", shcode=14563}, +[194716] = {category="lo", shcode=24474}, +[194717] = {category="lo", shcode=24525}, +[194718] = {category="lo", shcode=24535}, +[194719] = {category="lo", shcode=24569}, +[194720] = {category="lo", shcode=24705}, +[194721] = {category="lo", shcode=14650}, +[194722] = {category="lo", shcode=14620}, +[194723] = {category="lo", shcode=24724}, +[194724] = {category="lo", shcode=141012}, +[194725] = {category="lo", shcode=24775}, +[194726] = {category="lo", shcode=24904}, +[194727] = {category="lo", shcode=24908}, +[194728] = {category="lo", shcode=24910}, +[194729] = {category="lo", shcode=24908}, +[194730] = {category="lo", shcode=24954}, +[194731] = {category="lo", shcode=24974}, +[194732] = {category="lo", shcode=25010}, +[194733] = {category="lo", shcode=24996}, +[194734] = {category="lo", shcode=25007}, +[194735] = {category="lo", shcode=25054}, +[194736] = {category="lo", shcode=25074}, +[194737] = {category="lo", shcode=25078}, +[194738] = {category="lo", shcode=25104}, +[194739] = {category="lo", shcode=25115}, +[194740] = {category="lo", shcode=25181}, +[194741] = {category="lo", shcode=25265}, +[194742] = {category="lo", shcode=25300}, +[194743] = {category="lo", shcode=25424}, +[194744] = {category="lo", shcode=142092}, +[194745] = {category="lo", shcode=25405}, +[194746] = {category="lo", shcode=25340}, +[194747] = {category="lo", shcode=25448}, +[194748] = {category="lo", shcode=25475}, +[194749] = {category="lo", shcode=25572}, +[194750] = {category="lo", shcode=142321}, +[194751] = {category="lo", shcode=25634}, +[194752] = {category="lo", shcode=25541}, +[194753] = {category="lo", shcode=25513}, +[194754] = {category="lo", shcode=14894}, +[194755] = {category="lo", shcode=25705}, +[194756] = {category="lo", shcode=25726}, +[194757] = {category="lo", shcode=25757}, +[194758] = {category="lo", shcode=25719}, +[194759] = {category="lo", shcode=14956}, +[194760] = {category="lo", shcode=25935}, +[194761] = {category="lo", shcode=25964}, +[194762] = {category="lo", shcode=143370}, +[194763] = {category="lo", shcode=26083}, +[194764] = {category="lo", shcode=26360}, +[194765] = {category="lo", shcode=26185}, +[194766] = {category="lo", shcode=15129}, +[194767] = {category="lo", shcode=26257}, +[194768] = {category="lo", shcode=15112}, +[194769] = {category="lo", shcode=15076}, +[194770] = {category="lo", shcode=20882}, +[194771] = {category="lo", shcode=20885}, +[194772] = {category="lo", shcode=26368}, +[194773] = {category="lo", shcode=26268}, +[194774] = {category="lo", shcode=32941}, +[194775] = {category="lo", shcode=17369}, +[194776] = {category="lo", shcode=26391}, +[194777] = {category="lo", shcode=26395}, +[194778] = {category="lo", shcode=26401}, +[194779] = {category="lo", shcode=26462}, +[194780] = {category="lo", shcode=26451}, +[194781] = {category="lo", shcode=144323}, +[194782] = {category="lo", shcode=15177}, +[194783] = {category="lo", shcode=26618}, +[194784] = {category="lo", shcode=26501}, +[194785] = {category="lo", shcode=26706}, +[194786] = {category="lo", shcode=26757}, +[194787] = {category="lo", shcode=144493}, +[194788] = {category="lo", shcode=26766}, +[194789] = {category="lo", shcode=26655}, +[194790] = {category="lo", shcode=26900}, +[194791] = {category="lo", shcode=15261}, +[194792] = {category="lo", shcode=26946}, +[194793] = {category="lo", shcode=27043}, +[194794] = {category="lo", shcode=27114}, +[194795] = {category="lo", shcode=27304}, +[194796] = {category="lo", shcode=145059}, +[194797] = {category="lo", shcode=27355}, +[194798] = {category="lo", shcode=15384}, +[194799] = {category="lo", shcode=27425}, +[194800] = {category="lo", shcode=145575}, +[194801] = {category="lo", shcode=27476}, +[194802] = {category="lo", shcode=15438}, +[194803] = {category="lo", shcode=27506}, +[194804] = {category="lo", shcode=27551}, +[194805] = {category="lo", shcode=27578}, +[194806] = {category="lo", shcode=27579}, +[194807] = {category="lo", shcode=146061}, +[194808] = {category="lo", shcode=138507}, +[194809] = {category="lo", shcode=146170}, +[194810] = {category="lo", shcode=27726}, +[194811] = {category="lo", shcode=146620}, +[194812] = {category="lo", shcode=27839}, +[194813] = {category="lo", shcode=27853}, +[194814] = {category="lo", shcode=27751}, +[194815] = {category="lo", shcode=27926}, +[194816] = {category="lo", shcode=27966}, +[194817] = {category="lo", shcode=28023}, +[194818] = {category="lo", shcode=27969}, +[194819] = {category="lo", shcode=28009}, +[194820] = {category="lo", shcode=28024}, +[194821] = {category="lo", shcode=28037}, +[194822] = {category="lo", shcode=146718}, +[194823] = {category="lo", shcode=27956}, +[194824] = {category="lo", shcode=28207}, +[194825] = {category="lo", shcode=28270}, +[194826] = {category="lo", shcode=15667}, +[194827] = {category="lo", shcode=28363}, +[194828] = {category="lo", shcode=28359}, +[194829] = {category="lo", shcode=147153}, +[194830] = {category="lo", shcode=28153}, +[194831] = {category="lo", shcode=28526}, +[194832] = {category="lo", shcode=147294}, +[194833] = {category="lo", shcode=147342}, +[194834] = {category="lo", shcode=28614}, +[194835] = {category="lo", shcode=28729}, +[194836] = {category="lo", shcode=28702}, +[194837] = {category="lo", shcode=28699}, +[194838] = {category="lo", shcode=15766}, +[194839] = {category="lo", shcode=28746}, +[194840] = {category="lo", shcode=28797}, +[194841] = {category="lo", shcode=28791}, +[194842] = {category="lo", shcode=28845}, +[194843] = {category="lo", shcode=132389}, +[194844] = {category="lo", shcode=28997}, +[194845] = {category="lo", shcode=148067}, +[194846] = {category="lo", shcode=29084}, +[194847] = {category="lo", shcode=148395}, +[194848] = {category="lo", shcode=29224}, +[194849] = {category="lo", shcode=29237}, +[194850] = {category="lo", shcode=29264}, +[194851] = {category="lo", shcode=149000}, +[194852] = {category="lo", shcode=29312}, +[194853] = {category="lo", shcode=29333}, +[194854] = {category="lo", shcode=149301}, +[194855] = {category="lo", shcode=149524}, +[194856] = {category="lo", shcode=29562}, +[194857] = {category="lo", shcode=29579}, +[194858] = {category="lo", shcode=16044}, +[194859] = {category="lo", shcode=29605}, +[194860] = {category="lo", shcode=16056}, +[194861] = {category="lo", shcode=16056}, +[194862] = {category="lo", shcode=29767}, +[194863] = {category="lo", shcode=29788}, +[194864] = {category="lo", shcode=29809}, +[194865] = {category="lo", shcode=29829}, +[194866] = {category="lo", shcode=29898}, +[194867] = {category="lo", shcode=16155}, +[194868] = {category="lo", shcode=29988}, +[194869] = {category="lo", shcode=150582}, +[194870] = {category="lo", shcode=30014}, +[194871] = {category="lo", shcode=150674}, +[194872] = {category="lo", shcode=30064}, +[194873] = {category="lo", shcode=139679}, +[194874] = {category="lo", shcode=30224}, +[194875] = {category="lo", shcode=151457}, +[194876] = {category="lo", shcode=151480}, +[194877] = {category="lo", shcode=151620}, +[194878] = {category="lo", shcode=16380}, +[194879] = {category="lo", shcode=16392}, +[194880] = {category="lo", shcode=30452}, +[194881] = {category="lo", shcode=151795}, +[194882] = {category="lo", shcode=151794}, +[194883] = {category="lo", shcode=151833}, +[194884] = {category="lo", shcode=151859}, +[194885] = {category="lo", shcode=30494}, +[194886] = {category="lo", shcode=30495}, +[194887] = {category="lo", shcode=30495}, +[194888] = {category="lo", shcode=30538}, +[194889] = {category="lo", shcode=16441}, +[194890] = {category="lo", shcode=30603}, +[194891] = {category="lo", shcode=16454}, +[194892] = {category="lo", shcode=16534}, +[194893] = {category="lo", shcode=152605}, +[194894] = {category="lo", shcode=30798}, +[194895] = {category="lo", shcode=30860}, +[194896] = {category="lo", shcode=30924}, +[194897] = {category="lo", shcode=16611}, +[194898] = {category="lo", shcode=153126}, +[194899] = {category="lo", shcode=31062}, +[194900] = {category="lo", shcode=153242}, +[194901] = {category="lo", shcode=153285}, +[194902] = {category="lo", shcode=31119}, +[194903] = {category="lo", shcode=31211}, +[194904] = {category="lo", shcode=16687}, +[194905] = {category="lo", shcode=31296}, +[194906] = {category="lo", shcode=31306}, +[194907] = {category="lo", shcode=31311}, +[194908] = {category="lo", shcode=153980}, +[194909] = {category="lo", shcode=154279}, +[194910] = {category="lo", shcode=154279}, +[194911] = {category="lo", shcode=31470}, +[194912] = {category="lo", shcode=16898}, +[194913] = {category="lo", shcode=154539}, +[194914] = {category="lo", shcode=31686}, +[194915] = {category="lo", shcode=31689}, +[194916] = {category="lo", shcode=16935}, +[194917] = {category="lo", shcode=154752}, +[194918] = {category="lo", shcode=31954}, +[194919] = {category="lo", shcode=17056}, +[194920] = {category="lo", shcode=31976}, +[194921] = {category="lo", shcode=31971}, +[194922] = {category="lo", shcode=32000}, +[194923] = {category="lo", shcode=155526}, +[194924] = {category="lo", shcode=32099}, +[194925] = {category="lo", shcode=17153}, +[194926] = {category="lo", shcode=32199}, +[194927] = {category="lo", shcode=32258}, +[194928] = {category="lo", shcode=32325}, +[194929] = {category="lo", shcode=17204}, +[194930] = {category="lo", shcode=156200}, +[194931] = {category="lo", shcode=156231}, +[194932] = {category="lo", shcode=17241}, +[194933] = {category="lo", shcode=156377}, +[194934] = {category="lo", shcode=32634}, +[194935] = {category="lo", shcode=156478}, +[194936] = {category="lo", shcode=32661}, +[194937] = {category="lo", shcode=32762}, +[194938] = {category="lo", shcode=32773}, +[194939] = {category="lo", shcode=156890}, +[194940] = {category="lo", shcode=156963}, +[194941] = {category="lo", shcode=32864}, +[194942] = {category="lo", shcode=157096}, +[194943] = {category="lo", shcode=32880}, +[194944] = {category="lo", shcode=144223}, +[194945] = {category="lo", shcode=17365}, +[194946] = {category="lo", shcode=32946}, +[194947] = {category="lo", shcode=33027}, +[194948] = {category="lo", shcode=17419}, +[194949] = {category="lo", shcode=33086}, +[194950] = {category="lo", shcode=23221}, +[194951] = {category="lo", shcode=157607}, +[194952] = {category="lo", shcode=157621}, +[194953] = {category="lo", shcode=144275}, +[194954] = {category="lo", shcode=144284}, +[194955] = {category="lo", shcode=33281}, +[194956] = {category="lo", shcode=33284}, +[194957] = {category="lo", shcode=36766}, +[194958] = {category="lo", shcode=17515}, +[194959] = {category="lo", shcode=33425}, +[194960] = {category="lo", shcode=33419}, +[194961] = {category="lo", shcode=33437}, +[194962] = {category="lo", shcode=21171}, +[194963] = {category="lo", shcode=33457}, +[194964] = {category="lo", shcode=33459}, +[194965] = {category="lo", shcode=33469}, +[194966] = {category="lo", shcode=33510}, +[194967] = {category="lo", shcode=158524}, +[194968] = {category="lo", shcode=33509}, +[194969] = {category="lo", shcode=33565}, +[194970] = {category="lo", shcode=33635}, +[194971] = {category="lo", shcode=33709}, +[194972] = {category="lo", shcode=33571}, +[194973] = {category="lo", shcode=33725}, +[194974] = {category="lo", shcode=33767}, +[194975] = {category="lo", shcode=33879}, +[194976] = {category="lo", shcode=33619}, +[194977] = {category="lo", shcode=33738}, +[194978] = {category="lo", shcode=33740}, +[194979] = {category="lo", shcode=33756}, +[194980] = {category="lo", shcode=158774}, +[194981] = {category="lo", shcode=159083}, +[194982] = {category="lo", shcode=158933}, +[194983] = {category="lo", shcode=17707}, +[194984] = {category="lo", shcode=34033}, +[194985] = {category="lo", shcode=34035}, +[194986] = {category="lo", shcode=34070}, +[194987] = {category="lo", shcode=160714}, +[194988] = {category="lo", shcode=34148}, +[194989] = {category="lo", shcode=159532}, +[194990] = {category="lo", shcode=17757}, +[194991] = {category="lo", shcode=17761}, +[194992] = {category="lo", shcode=159665}, +[194993] = {category="lo", shcode=159954}, +[194994] = {category="lo", shcode=17771}, +[194995] = {category="lo", shcode=34384}, +[194996] = {category="lo", shcode=34396}, +[194997] = {category="lo", shcode=34407}, +[194998] = {category="lo", shcode=34409}, +[194999] = {category="lo", shcode=34473}, +[195000] = {category="lo", shcode=34440}, +[195001] = {category="lo", shcode=34574}, +[195002] = {category="lo", shcode=34530}, +[195003] = {category="lo", shcode=34681}, +[195004] = {category="lo", shcode=34600}, +[195005] = {category="lo", shcode=34667}, +[195006] = {category="lo", shcode=34694}, +[195007] = {category="lo", shcode=17879}, +[195008] = {category="lo", shcode=34785}, +[195009] = {category="lo", shcode=34817}, +[195010] = {category="lo", shcode=17913}, +[195011] = {category="lo", shcode=34912}, +[195012] = {category="lo", shcode=34915}, +[195013] = {category="lo", shcode=161383}, +[195014] = {category="lo", shcode=35031}, +[195015] = {category="lo", shcode=35038}, +[195016] = {category="lo", shcode=17973}, +[195017] = {category="lo", shcode=35066}, +[195018] = {category="lo", shcode=13499}, +[195019] = {category="lo", shcode=161966}, +[195020] = {category="lo", shcode=162150}, +[195021] = {category="lo", shcode=18110}, +[195022] = {category="lo", shcode=18119}, +[195023] = {category="lo", shcode=35488}, +[195024] = {category="lo", shcode=35565}, +[195025] = {category="lo", shcode=35722}, +[195026] = {category="lo", shcode=35925}, +[195027] = {category="lo", shcode=162984}, +[195028] = {category="lo", shcode=36011}, +[195029] = {category="lo", shcode=36033}, +[195030] = {category="lo", shcode=36123}, +[195031] = {category="lo", shcode=36215}, +[195032] = {category="lo", shcode=163631}, +[195033] = {category="lo", shcode=133124}, +[195034] = {category="lo", shcode=36299}, +[195035] = {category="lo", shcode=36284}, +[195036] = {category="lo", shcode=36336}, +[195037] = {category="lo", shcode=133342}, +[195038] = {category="lo", shcode=36564}, +[195039] = {category="lo", shcode=36664}, +[195040] = {category="lo", shcode=165330}, +[195041] = {category="lo", shcode=165357}, +[195042] = {category="lo", shcode=37012}, +[195043] = {category="lo", shcode=37105}, +[195044] = {category="lo", shcode=37137}, +[195045] = {category="lo", shcode=165678}, +[195046] = {category="lo", shcode=37147}, +[195047] = {category="lo", shcode=37432}, +[195048] = {category="lo", shcode=37591}, +[195049] = {category="lo", shcode=37592}, +[195050] = {category="lo", shcode=37500}, +[195051] = {category="lo", shcode=37881}, +[195052] = {category="lo", shcode=37909}, +[195053] = {category="lo", shcode=166906}, +[195054] = {category="lo", shcode=38283}, +[195055] = {category="lo", shcode=18837}, +[195056] = {category="lo", shcode=38327}, +[195057] = {category="lo", shcode=167287}, +[195058] = {category="lo", shcode=18918}, +[195059] = {category="lo", shcode=38595}, +[195060] = {category="lo", shcode=23986}, +[195061] = {category="lo", shcode=38691}, +[195062] = {category="lo", shcode=168261}, +[195063] = {category="lo", shcode=168474}, +[195064] = {category="lo", shcode=19054}, +[195065] = {category="lo", shcode=19062}, +[195066] = {category="lo", shcode=38880}, +[195067] = {category="lo", shcode=168970}, +[195068] = {category="lo", shcode=19122}, +[195069] = {category="lo", shcode=169110}, +[195070] = {category="lo", shcode=38923}, +[195071] = {category="lo", shcode=38923}, +[195072] = {category="lo", shcode=38953}, +[195073] = {category="lo", shcode=169398}, +[195074] = {category="lo", shcode=39138}, +[195075] = {category="lo", shcode=19251}, +[195076] = {category="lo", shcode=39209}, +[195077] = {category="lo", shcode=39335}, +[195078] = {category="lo", shcode=39362}, +[195079] = {category="lo", shcode=39422}, +[195080] = {category="lo", shcode=19406}, +[195081] = {category="lo", shcode=170800}, +[195082] = {category="lo", shcode=39698}, +[195083] = {category="lo", shcode=40000}, +[195084] = {category="lo", shcode=40189}, +[195085] = {category="lo", shcode=19662}, +[195086] = {category="lo", shcode=19693}, +[195087] = {category="lo", shcode=40295}, +[195088] = {category="lo", shcode=172238}, +[195089] = {category="lo", shcode=19704}, +[195090] = {category="lo", shcode=172293}, +[195091] = {category="lo", shcode=172558}, +[195092] = {category="lo", shcode=172689}, +[195093] = {category="lo", shcode=40635}, +[195094] = {category="lo", shcode=19798}, +[195095] = {category="lo", shcode=40697}, +[195096] = {category="lo", shcode=40702}, +[195097] = {category="lo", shcode=40709}, +[195098] = {category="lo", shcode=40719}, +[195099] = {category="lo", shcode=40726}, +[195100] = {category="lo", shcode=40763}, +[195101] = {category="lo", shcode=173568}, +[196608] = {category="lo"}, +[201546] = {category="lo"}, +[201552] = {category="lo"}, +[205743] = {category="lo"}, +} diff --git a/support/make4ht/make4ht-doc.pdf b/support/make4ht/make4ht-doc.pdf Binary files differindex 7eacc7bd95..ed8effdfe9 100644 --- a/support/make4ht/make4ht-doc.pdf +++ b/support/make4ht/make4ht-doc.pdf diff --git a/support/make4ht/make4ht-errorlogparser.lua b/support/make4ht/make4ht-errorlogparser.lua index 1d16c97650..f26585a136 100644 --- a/support/make4ht/make4ht-errorlogparser.lua +++ b/support/make4ht/make4ht-errorlogparser.lua @@ -18,13 +18,13 @@ local function get_chunks(text) local chunk = string.sub(a,2,-2) -- if no filename had been found in the chunk, it is probably not file chunk -- so just return the original text - local filename = get_filename(chunk) + local filename = get_filename(chunk) if not filename then return a end local children, text = get_chunks(chunk) table.insert(chunks, {filename = filename, text = text, children = children}) return "" end) - return chunks, newtext + return chunks, newtext end @@ -37,44 +37,85 @@ function print_chunks(chunks, level) end end -local function parse_errors(text) +local function parse_default_error(lines, i) + local line = lines[i] + -- get the error message "! msg text" + local err = line:match("^!(.+)") + -- the next line should contain line number where error happened + local next_line = lines[i+1] or "" + local msg = {} + -- get the line number and first line of the error context + local line_no, msg_start = next_line:match("^l%.(%d+)(.+)") + line_no = line_no or false + msg_start = msg_start or "" + msg[#msg+1] = msg_start .. " <-" + -- try to find rest of the error context. + for x = i+2, i+5 do + local next_line = lines[x] or "" + -- break on blank lines + if next_line:match("^%s*$") then break end + msg[#msg+1] = next_line:gsub("^%s*", ""):gsub("%s$", "") + end + return err, line_no, table.concat(msg, " ") +end + +local function parse_linenumber_error(lines, i) + -- parse errors from log created with the -file-line-number option + local line = lines[i] + local filename, line_no, err = line:match("^([^%:]+)%:(%d+)%:%s*(.*)") + local msg = {} + -- get error context + for x = i+1, i+2 do + local next_line = lines[x] or "" + -- break on blank lines + if next_line:match("^%s*$") then break end + msg[#msg+1] = next_line:gsub("^%s*", ""):gsub("%s$", "") + end + -- insert mark to the error + if #msg > 1 then + table.insert(msg, 2, "<-") + end + return err, line_no, table.concat(msg, " ") +end + +--- get error messages, linenumbers and contexts from a log file chunk +---@param text string chunk from the long file where we should find errors +---@return table errors error messages +---@return table error_lines error line number +---@return table error_messages error line contents +local function parse_errors(text) local lines = {} local errors = {} local find_line_no = false local error_lines = {} + local error_messages = {} for line in text:gmatch("([^\n]+)") do lines[#lines+1] = line end - for i = 1, #lines do + for i = 1, #lines do local line = lines[i] - -- error lines start with ! - local err = line:match("^!(.+)") - -- error lines can be on following lines - -- the format is l.number - local lineno = line:match("^l%.([0-9]+)") - if err then - errors[#errors+1] = err - -- we didn't find error line number since previous error, insert - if find_line_no then - error_lines[#error_lines+1] = false - end - find_line_no = true - elseif lineno then - find_line_no = false - error_lines[#error_lines+1] = tonumber(lineno) + local err, line_no, msg + if line:match("^!(.+)") then + err, line_no, msg = parse_default_error(lines, i) + elseif line:match("^[^%:]+%:%d+%:.+") then + err, line_no, msg = parse_linenumber_error(lines, i) + end + if err then + errors[#errors+1] = err + error_lines[#errors] = line_no + error_messages[#errors] = msg end - i = i + 1 end - return errors, error_lines + return errors, error_lines, error_messages end local function get_errors(chunks, errors) local errors = errors or {} for _, v in ipairs(chunks) do - local current_errors, error_lines = parse_errors(v.text) + local current_errors, error_lines, error_contexts = parse_errors(v.text) for i, err in ipairs(current_errors) do - table.insert(errors, {filename = v.filename, error = err, line = error_lines[i] }) + table.insert(errors, {filename = v.filename, error = err, line = error_lines[i], context = error_contexts[i] }) end errors = get_errors(v.children, errors) end @@ -95,8 +136,8 @@ function m.get_missing_4ht_files(log) used_4ht_files[filename] = true end end - for filename, _ in pairs(used_files) do - if not used_4ht_files[mkutils.remove_extension(filename)] then + for filename, _ in pairs(used_files) do + if not used_4ht_files[mkutils.remove_extension(filename)] then table.insert(missing_4ht_files, filename) end end @@ -113,7 +154,7 @@ function m.parse(log) -- for _,v in ipairs(errors) do -- print("error", v.filename, v.line, v.error) -- end - return errors, chunks + return errors, chunks end diff --git a/support/make4ht/make4ht-htlatex.lua b/support/make4ht/make4ht-htlatex.lua index 4975e947e6..ca5d9b8a1e 100644 --- a/support/make4ht/make4ht-htlatex.lua +++ b/support/make4ht/make4ht-htlatex.lua @@ -18,13 +18,15 @@ local function testlogfile(par) -- parse log file for all errors in non-interactive modes if par.interaction~="errorstopmode" then -- the error log parsing can be slow, so detect errors first - if content:match("\n!") then + -- detect both default error messages (! msg) and -file-line-number errors (filename:lineno:msg) + if content:match("\n!") or content:match("[^:]+%:%d+%:.+") then local errors, chunks = error_logparser.parse(content) if #errors > 0 then log:error("Compilation errors in the htlatex run") log:error("Filename", "Line", "Message") for _, err in ipairs(errors) do log:error(err.filename or "?", err.line or "?", err.error) + log:status(err.context) end end end diff --git a/support/make4ht/make4ht-indexing.lua b/support/make4ht/make4ht-indexing.lua index d5c0d07718..f122ef56f8 100644 --- a/support/make4ht/make4ht-indexing.lua +++ b/support/make4ht/make4ht-indexing.lua @@ -90,26 +90,41 @@ local parse_idx = function(content) return {map = map, idx = table.concat(buffer, "\n")} end + +-- replace numbers in .ind file with links back to text +local function replace_index_pages(rest, entries) + return rest:gsub("(%{?%d+%}?)", function(page) + local entry = entries[tonumber(page)] + if entry then + -- construct link to the index entry + return "\\Link[" .. entry.file .."]{".. entry.dest .."}{}" .. page .."\\EndLink{}" + else + return page + end + end) +end + + -- replace page numbers in the ind file with hyperlinks local fix_idx_pages = function(content, idxobj) local buffer = {} local entries = idxobj.map for line in content:gmatch("([^\n]+)") do - local line = line:gsub("(%s*\\%a+.-%,)(.+)$", function(start,rest) + local line, count = line:gsub("(%s*\\%a+.-%,)(.+)$", function(start,rest) -- there is a problem when index term itself contains numbers, like Bible verses (1:2), -- because they will be detected as page numbers too. I cannot find a good solution -- that wouldn't break something else. - return start .. rest:gsub("(%d+)", function(page) - local entry = entries[tonumber(page)] - if entry then - -- construct link to the index entry - return "\\Link[" .. entry.file .."]{".. entry.dest .."}{}" .. page .."\\EndLink{}" - else - return page - end + -- There can be also commands with numbers in braces. These numbers in braces will be ignored, + -- as they may be not page numbers + return start .. replace_index_pages(rest, entries) end) + -- longer index entries may be broken over several lines, in that case, we need to process only numbers + if count == 0 then + line = line:gsub("(%s*%d+.+)", function(rest) + return replace_index_pages(rest, entries) end) - end) - buffer[#buffer+1] = line + end + print(line) + buffer[#buffer+1] = line end return table.concat(buffer, "\n") end diff --git a/support/make4ht/make4ht-xtpipes.lua b/support/make4ht/make4ht-xtpipes.lua index 544663fb89..94b3f5679e 100644 --- a/support/make4ht/make4ht-xtpipes.lua +++ b/support/make4ht/make4ht-xtpipes.lua @@ -1,5 +1,7 @@ local M = {} +local mkutils = require "mkutils" + local log = logging.new "xtpipes" -- find if tex4ht.jar exists in a path local function find_tex4ht_jar(path) @@ -37,6 +39,22 @@ function M.get_selfautoparent() return get_texmfroot() or find_texmfroot() end +local function replace_lg_file() + -- xtpipes expects the lg file to be placed in the current working dir, but with the --build option, + -- it is saved in the build dir. So we need to copy that file to the place where it is expected. + local params = Make.params + local basename = params.input + local lg_name = basename .. ".lg" + local lg_in_builddir = mkutils.file_in_builddir(lg_name,params) + if lg_name ~= lg_in_builddir and mkutils.file_exists(lg_in_builddir) then + log:info("Creating temporary lg_file", lg_name) + mkutils.cp(lg_in_builddir, lg_name) + return true, lg_name + end + -- don't copy the Lg file if --build_fir option isn't used + return false, lg_name +end + function M.get_xtpipes(selfautoparent) -- make pattern using TeX distro path local pattern = string.format('java -classpath "%s/tex4ht/bin/tex4ht.jar" xtpipes -i "%s/tex4ht/xtpipes/" -o "${outputfile}" "${filename}"', selfautoparent, selfautoparent) @@ -45,10 +63,13 @@ function M.get_xtpipes(selfautoparent) -- move the matched file to a temporary file, xtpipes will write it back to the original file local basename = mkutils.remove_extension(filename) local tmpfile = basename ..".tmp" + local remove, lg_filename = replace_lg_file() mkutils.mv(filename, tmpfile) local command = pattern % {filename = tmpfile, outputfile = filename} log:info("execute: " ..command) local status, output = mkutils.execute(command) + -- remove temporary lg file if it was created + if remove then os.remove(lg_filename) end if status > 0 then -- if xtpipes failed to process the file, it may mean that it was bad-formed xml -- we can try to make it well-formed using Tidy diff --git a/support/make4ht/mkparams.lua b/support/make4ht/mkparams.lua index 10ddd04744..731248dbd8 100644 --- a/support/make4ht/mkparams.lua +++ b/support/make4ht/mkparams.lua @@ -52,7 +52,7 @@ local function get_args(parameters, optiontext) parameters.postfile = parameters.postfile or "" optiontext = optiontext .. parameters.postparams ..[[ <filename> (string) Input file name -Positional optional argumens: +Positional optional arguments: ["tex4ht.sty op."] Additional parameters for tex4ht.sty ["tex4ht op."] Options for tex4ht command ["t4ht op"] Options for t4ht command diff --git a/support/make4ht/mkutils.lua b/support/make4ht/mkutils.lua index ec5158d9d2..0a167eb7db 100644 --- a/support/make4ht/mkutils.lua +++ b/support/make4ht/mkutils.lua @@ -107,8 +107,11 @@ function parse_lg(filename, builddir) table.insert(outputimages,rec) end ) - line:gsub("File: (.*)", function(k) - k = dir .. k + line:gsub("File: (.*)", function(x) + local k = dir .. x + if not file_exists(k) then + k = x + end if not usedfiles[k] then table.insert(outputfiles,k) usedfiles[k] = true @@ -204,18 +207,18 @@ function find_directories(dirs, pos) path = table.concat(dirs,"/", 1,pos) .. "/" end if not lfs.chdir(path) then -- recursion until we succesfully changed dir - -- or there are no elements in the dir table - return find_directories(dirs,pos - 1) -elseif pos ~= #dirs then -- if we succesfully changed dir - -- and we have dirs to create - local p = {} - for i = pos+1, #dirs do - table.insert(p, dirs[i]) + -- or there are no elements in the dir table + return find_directories(dirs,pos - 1) + elseif pos ~= #dirs then -- if we succesfully changed dir + -- and we have dirs to create + local p = {} + for i = pos+1, #dirs do + table.insert(p, dirs[i]) + end + return p + else -- whole path exists + return {} end - return p -else -- whole path exists - return {} -end end function mkdirectories(dirs) @@ -244,7 +247,8 @@ end function file_in_builddir(filename, par) if par.builddir and par.builddir ~= "" then - return par.builddir .. "/" .. filename + local newname = par.builddir .. "/" .. filename + return newname end return filename end diff --git a/support/make4ht/readme.tex b/support/make4ht/readme.tex index 9cff4cbeea..d5392e5311 100644 --- a/support/make4ht/readme.tex +++ b/support/make4ht/readme.tex @@ -10,11 +10,10 @@ tools. An example of such a tool is conversion from \TeX~to ePub and other e-book formats. See section \ref{sec:htlatex} for some reasons why you should consider -to use \texttt{make4ht} instead of \texttt{htlatex},\\ -section \ref{sec:output} talks about supported output formats and -extensions and section \ref{sec:buildfiles} describes build files, which -can be used to execute additional commands or post-process the generated -files. +to use \texttt{make4ht} instead of \texttt{htlatex}, section +\ref{sec:output} talks about supported output formats and extensions and +section \ref{sec:buildfiles} describes build files, which can be used to +execute additional commands or post-process the generated files. \hypertarget{usage}{% \section{Usage}\label{usage}} @@ -1279,16 +1278,24 @@ extension}{The dvisvgm\_hashes extension}}\label{the-dvisvgm_hashes-extension}} \begin{description} \item[options] command line options for Dvisvgm. The default value is -\texttt{-n\ -\/-exact\ -c\ 1.15,1.15}. +\texttt{-n\ -\/-exact\ -c\ \$\{scale\},\$\{scale\}}. \item[cpu\_cnt] the number of processor cores used for the conversion. The extension tries to detect the available cores automatically by default. +\item[make\_command] +variant of the \texttt{make} command used for the parallel conversion of +large number of pages. It receives tvo variables, +\texttt{process\_count} and \texttt{make\_file}. Default value is ``make +-j \$\{process\_count\} -f \$\{make\_file\}''. +\item[test\_make\_command] +command that tests if the selected variant of the \texttt{make} command +exists. Default value is \texttt{make\ -v}. \item[parallel\_size] the number of pages used in each Dvisvgm call. The extension detects changed pages in the DVI file and constructs multiple calls to Dvisvgm with only changed pages. \item[scale] -SVG scaling. +amount of SVG scaling. The default value is 1.4. \end{description} \hypertarget{the-odttemplate-filter-and-extension}{% diff --git a/support/pdflatexpicscale/README b/support/pdflatexpicscale/README index 56b00b6b36..f95ecc2dd0 100644 --- a/support/pdflatexpicscale/README +++ b/support/pdflatexpicscale/README @@ -3,11 +3,11 @@ to a target resolution before creating a PDF document with PdfLaTeX. *Version* -2018-02-12 (version of bundle) +2024-10-18 (version of bundle) For version details check pdflatexpicscale.pdf. *Requirements* -Perl and ImageMagick have to be installed. +Perl and some Perl modules have to be installed - see pdflatexpicscale.pdf. *Basic usage* pdflatex article diff --git a/support/pdflatexpicscale/pdflatexpicscale.pdf b/support/pdflatexpicscale/pdflatexpicscale.pdf Binary files differindex 8e42d2a18f..729034176f 100644 --- a/support/pdflatexpicscale/pdflatexpicscale.pdf +++ b/support/pdflatexpicscale/pdflatexpicscale.pdf diff --git a/support/pdflatexpicscale/pdflatexpicscale.pl b/support/pdflatexpicscale/pdflatexpicscale.pl index ef16ea8639..22e608b33e 100755 --- a/support/pdflatexpicscale/pdflatexpicscale.pl +++ b/support/pdflatexpicscale/pdflatexpicscale.pl @@ -16,37 +16,71 @@ # with the documentation, even when the perl code does not change. # 2017-02-01 pdflatexpicscale did not work correct when log lines were # wrapped twice. This is fixed. +# 2024-10-18 Replaced dependency of external ImageMagick software in favor +# of GD library. # use strict; + +use GD; +use Image::ExifTool; + use File::Basename; use File::Spec; use File::Copy; + use Getopt::Long; -my $version = '0.32'; -my $versiondate = '2018-02-12'; #version %version +my $version = '0.50'; +my $versiondate = '2024-10-18'; #version %version my $showversion; -my $verbose; -my $help; +# command line inouts +my $verbose = 0; +my $help = 0; +my $draftoption = 0; +my $finaloption = 0; my $TeXproject; # folders for scaled graphics, relative names -my $printfolderprefix = 'printimg'; -my $previewfolderprefix = 'previewimg'; -my $srcfolder = ''; +my $outputfolderprefix = undef; +my $srcfolder = ''; -# final resolution. special b/w handling not implemented yet -my $printdpi = 300; -my $printbwdpi = 4 * $printdpi; -my $previewdpi = 72; -my $tolerance = 20; +my %customsettings = ( + 'name' => 'from command line', + 'outputdpi' => 300, + 'outputfolder' => 'printimg', + 'jpegquality' => 80, + 'outputbwdpi' => 1200 + ); -# file formats +my %finalsettings = ( + 'name' => 'final', + 'outputdpi' => 300, + 'jpegquality' => 80, + 'outputfolder' => 'finalimg', + 'outputbwdpi' => 1200 + ); + +my %draftsettings = ( + 'name' => 'draft', + 'outputdpi' => 96, + 'jpegquality' => 50, + 'outputfolder' => 'webimg', + 'outputbwdpi' => 300 + ); + +my $outputdpi = undef; # final resolution. +my $outputbwdpi = undef; # final resolution for pure b/w art +my $tolerance = 20; # avoid resampling of almost fitting images +my $jpegquality = undef; # 50 is mostly acceptable, 80 is fine. + +# supported file formats (by extension) my %canhandle = -( JPG => '1', - PNG => '1', -); + ( + 'JPEG' => '1', + 'JPG' => '1', + 'PNG' => '1', + ); # bookkeeping my %processedimages; @@ -54,17 +88,183 @@ my $copied = 0; my $scaled = 0; my $skipped = 0; -sub printInplaceError +# the following is required by Image::ExifTool +our $AUTOLOAD; +sub AUTOLOAD { + Image::ExifTool::DoAutoLoad($AUTOLOAD, @_); +} + +sub printError +{ + my $filename = shift; + my $kind = shift; + if ($kind eq 'i') { + print "I will not do inplace modification of graphics:\n" . + "($filename) will not be processed. (Missing path?)\n"; + } elsif ($kind eq 'm') { + print "I can't find ($filename). (What have you done?)\n"; + } elsif ($kind eq 'f') { + print "File $filename has an unexpected or wrong format.\n"; + } elsif ($kind eq 's') { + print "Trying to copy '$filename' leads to system error # $_.\n"; + } elsif ($kind eq 'd') { + print "Directory '$filename' does not exist\n" + . "in actual folder and I can't create it (sys error # $_).\n" + . "Please check permissions. Aborting.\n"; + } else { + print "I got trouble with '$filename'.\n"; + } +} + +sub getDestFilename +{ + my @dstdirs; my $filename = shift; - print "I will not do inplace modification of graphics:\n" . - "($filename) will not be processed. (Missing path?)\n"; + my $dstfilename = undef;; + $dstdirs[0] = '.'; + $dstdirs[1] = $outputfolderprefix; + $dstfilename = File::Spec->catfile(@dstdirs, basename($filename)); + return $dstfilename; } -sub printMissingError +sub getSourceFilename { + my @srcdirs; my $filename = shift; - print "I can not find ($filename). (What have you done?)\n"; + my $srcfilename = undef; + if (defined($srcfolder) and $srcfolder gt '') { + $srcdirs[0] = '$srcfolder'; + $srcfilename = File::Spec->catfile(@srcdirs, basename($filename)); + $filename = $srcfilename; + } + unless (-e $filename){ + printError($filename, 'm'); + return undef; + } + return $filename; +} + +sub fileYounger +{ + my @filename = @_; + my ($mtime1, $mtime2, $size1, $size2, $idstring2, $existwidth); + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, + $atime, $ctime, $blksize, $blocks); + ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, + $atime, $mtime1, $ctime, $blksize, $blocks) + = stat($filename[0]); + ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, + $atime, $mtime2, $ctime, $blksize, $blocks) + = stat($filename[1]); + if($mtime1 >= $mtime2) { + return 1; + } + return 0; + +} + +sub numberInRange +{ + my $realwidth = shift; + my $wantedwidth = shift; + if (($realwidth >= $wantedwidth * 100 / (100 + $tolerance)) and + ($realwidth <= $wantedwidth * (100 + $tolerance) / 100)) { + return 1; + } else { + return 0; + } +} + +sub loadImage +{ + my %result = ( + 'filename' => undef, + 'image' => undef, 'canhandle' => 0, + 'format' => undef, 'width' => 0, + 'height' => 0, 'monochrome' => 0, + 'quality' => 50 + ); + $result{'filename'} = shift; + my $maketruecolor = shift || 0; + my $exifTool = Image::ExifTool->new; + my $imageinfo = $exifTool->ImageInfo($result{'filename'}); +# foreach (sort keys %$imageinfo) { +# print "$_ => $$imageinfo{$_}\n"; +# } + $result{'image'} = GD::Image->new($result{'filename'}); + $result{'width'} = $$imageinfo{'ImageWidth'}; + $result{'height'} = $$imageinfo{'ImageHeight'}; + if ( ($$imageinfo{'FileType'} eq 'PNG') or + ($$imageinfo{'FileType'} eq 'JPEG')) { + $result{'format'} = $$imageinfo{'FileType'}; + $result{'canhandle'} = 1; + } + if (defined($$imageinfo{'BitDepth'}) and $$imageinfo{'BitDepth'} == 1) { + $result{'monochrome'} = 1; + } elsif (defined($result{'image'})) { + $result{'canhandle'} = 1; + if (defined ($result{'image'}->colorsTotal) and + $result{'image'}->colorsTotal < 3) { + $result{'monochrome'} = 1; + } + unless (defined($result{'width'})) { + $result{'width'} = $result{'image'}->width; + } + unless (defined($result{'height'})) { + $result{'height'} = $result{'image'}->height; + } + } + return %result; +} + +sub writeImage +{ + my %dst = @_; + my $imagedata = undef; + my $realfilename = $dst{'filename'}; + open(OUT, '>', $realfilename) or die; + binmode OUT; + if ($dst{'format'} eq 'PNG') { + $dst{'image'}->interlaced(undef); # else PFDTEX has to do it. + $imagedata = $dst{'image'}->png(9); + } elsif ($dst{'format'} eq 'JPEG') { + $imagedata = $dst{'image'}->jpeg($jpegquality); + } + print OUT $imagedata; + close(OUT); + return 1; +} + +sub GDscale +{ + my $srcfilename = shift; + my $dstfilename = shift; + my $dstwidth = shift; + my $dstheight = shift; + # my $interpolationmethod = GD_BICUBIC; + # Unfortunately not exported by GD and item of an enum. + # So I guess: + my $interpolationmethod = 4; + my %src = loadImage($srcfilename, 0); + $src{'destwidth'} = $dstwidth; + $src{'destheight'} = $dstheight; + $src{'image'}->interpolationMethod($interpolationmethod); + # what I will not copy: image, width, height, filename + my @properties = qw ( + canhandle format monochrome + ); + my %dstimage = (); + foreach (@properties) { + $dstimage{$_} = $src{$_}; + } + $dstimage{'width'} = $src{'destwidth'}; + $dstimage{'height'} = $src{'destheight'}; + $dstimage{'filename'} = $dstfilename; + $dstimage{'image'} = $src{'image'}->copyScaleInterpolated( + $dstimage{'width'}, $dstimage{'height'}); + writeImage(%dstimage); + return 1; } sub handleImage @@ -72,98 +272,90 @@ sub handleImage my $filename = shift; my $dstwidth = shift; my $dstheight = shift; - my ($srcwidth, $srcheight, $srcdepth); - my $dstfilename; - my $xfilename; - my @xsrcdirs; - my @dstdirs; + my ($srcwidth, $srcheight, $srcdepth, $monochrome, $existwidth); + my ($dstfilename, $xfilename); my @convertargs; - my $idstring; - print "$filename\n"; - $dstdirs[0] = '.'; - $dstdirs[1] = $printfolderprefix; - $dstfilename = File::Spec->catfile(@dstdirs, basename($filename)); - if($filename eq $dstfilename){ - unless ($srcfolder gt ' ') { - printInplaceError($filename); - $skipped++; - return; - } - $xsrcdirs[0] = $srcfolder; - $xfilename = File::Spec->catfile(@xsrcdirs, basename($filename)); - unless (-e $xfilename){ - printMissingError($xfilename); - $skipped++; - return; - } + my %srcimage = (); + my %dstimage = (); + print "$filename, " if $verbose; + $dstfilename = getDestFilename($filename); + $xfilename = getSourceFilename($filename); + if (defined($xfilename)) { $filename = $xfilename; + } else { + printError($filename, 'm'); + $skipped++; + return 0; + } + if($filename eq $dstfilename) { + printError($filename, 'i'); + $skipped++; + return 0; } # check for image width and height - $idstring = `identify -format "%w x %h %[depth] " $filename`; - return unless $idstring =~ /(\d+) x (\d+) (\d+)/; - $srcwidth = $1; $srcheight = $2; $srcdepth = $3; - if($srcdepth == 1) { # hires for bw pix - $dstwidth = int($dstwidth * $printbwdpi / 72.27 + .5); - $dstheight = int($dstheight * $printbwdpi / 72.27 + .5); - }else { # moderate res for any other - $dstwidth = int($dstwidth * $printdpi / 72.27 + .5); - $dstheight = int($dstheight * $printdpi / 72.27 + .5); + %srcimage = loadImage($filename); + if ($srcimage{'canhandle'} == 0 or ! defined($srcimage{'image'})) { + # copy from source to dest. + print "I Can't deal with $filename, so I will just\n" + . "copy it to $dstfilename\n" if $verbose; + copy($filename, $dstfilename); + $copied++; + return 1; } - if(-e $dstfilename){ - # if younger and requested size: skip - my ($mtime1, $mtime2, $size1, $size2, $idstring2, $existwidth); - my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, - $atime, $ctime, $blksize, $blocks); - ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, - $atime, $mtime1, $ctime, $blksize, $blocks) - = stat($dstfilename); - ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, - $atime, $mtime2, $ctime, $blksize, $blocks) - = stat($filename); - if($mtime1 >= $mtime2){ - $idstring2 = `identify -format "%w x %h %[depth] " $dstfilename`; - if($idstring2 =~ /(\d+) x (\d+) (\d+)/){ - $existwidth = $1; - if($existwidth == $dstwidth){ - $processedimages{$filename} = $existwidth; - $skipped++; - return; - } - } - } + $srcwidth = $srcimage{'width'}; + $srcheight = $srcimage{'height'}; + $monochrome = $srcimage{'monochrome'}; + if($monochrome == 1) { # hires for bw pix + $dstwidth = int($dstwidth * $outputbwdpi / 72.27 + .5); + $dstheight = int($dstheight * $outputbwdpi / 72.27 + .5); + }else { # moderate res for any other + $dstwidth = int($dstwidth * $outputdpi / 72.27 + .5); + $dstheight = int($dstheight * $outputdpi / 72.27 + .5); } - if(($dstwidth >= $srcwidth) || - ($dstwidth *(100 + $tolerance)/100 >= $srcwidth)) { - # we do no upscaling, but will probably copy the file. - if (defined $processedimages{$filename}){ - $skipped++; - }else { - $processedimages{$filename} = $srcwidth; - print "will copy $filename to $dstfilename\n" if $verbose; - copy($filename, $dstfilename); - $copied++; - return; - } - }else { + if(-e $dstfilename and fileYounger($dstfilename, $filename)) { + # if requested size already processed: skip if((defined $processedimages{$filename}) && ($processedimages{$filename} >= $dstwidth)) { + # if known, already processed and large enough: skip $skipped++; - return; + return 1; + } + %dstimage = loadImage($dstfilename); + $existwidth = $dstimage{'width'}; + # if requested size already there: make known and skip + if(numberInRange($existwidth, $dstwidth)) { + $processedimages{$filename} = $existwidth; + $skipped++; + return 1; } - # we do some downscaling - $processedimages{$filename} = $dstwidth; - $convertargs[0] = 'convert'; - $convertargs[1] = ${filename}; - $convertargs[2] = '-resize'; -# $convertargs[3] = "${dstwidth}x${dstheight}!"; - $convertargs[3] = "${dstwidth}x${dstheight}"; - $convertargs[4] = "-density"; - $convertargs[5] = $printdpi; - $convertargs[6] = ${dstfilename}; - print "will @convertargs\n" if $verbose; - system(@convertargs); + } + if (numberInRange($dstwidth, $srcwidth) or $dstwidth > $srcwidth) { + # we do no upscaling, but will probably copy the file. + $processedimages{$filename} = $srcwidth; + print "will copy $filename to $dstfilename\n" if $verbose; + copy($filename, $dstfilename); + $copied++; + return 1; + }else { + GDscale($xfilename, $dstfilename, $dstwidth, $dstheight); $scaled++; } + return 1; +} + +sub createOutputFolder +{ + my @dstdirs; + $dstdirs[0] = '.'; + my $dstdirname = File::Spec->catfile(@dstdirs, $outputfolderprefix); + if (mkdir($dstdirname) == 0) { + printError($dstdirname, 'd'); + return 0; + } + if ($verbose) { + print "Created directory $outputfolderprefix\n"; + } + return 1; } sub readlog @@ -172,10 +364,18 @@ sub readlog $logfilename .= '.log'; my ($picname, $picext, $picwidth, $picheight); my ($picextu, $state, $buffer); - open LOGFILE, "<$logfilename" or die "Cannot read $logfilename"; + open LOGFILE, "<$logfilename" or die "Cannot read $logfilename.\n" + . 'Please run pdfLaTeX before pdflatexpicscale.'; $state = 0; + unless (-d $outputfolderprefix) { + if (createOutputFolder() == 0) { + close LOGFILE; + return; + } + } + print "Processing " if $verbose; while (<LOGFILE>){ - if (/^Package pdftex\.def\sInfo\:\s/){ + if (/^Package\spdftex\.def\sInfo\:\s/){ $buffer = $_; unless ($buffer =~ /\sused/){ chomp $buffer; @@ -185,14 +385,16 @@ sub readlog chomp $buffer; $buffer .= <LOGFILE>; } - if($buffer =~ /Info:\s(\S*)\.(\w+)\sused/){ + if($buffer =~ /Info:\s(\S*)\.(\w+)\s+used/){ $picname = $1; $picext = $2; ($picextu = $picext) =~ tr/a-z/A-Z/; if(defined $canhandle{$picextu}){ $state = 1; - next; + next; # width/height information will follow } + } else { + print "Log file apparently damaged at line $.\n"; } } next unless ($state == 1); @@ -202,34 +404,84 @@ sub readlog handleImage("$picname.$picext", $picwidth, $picheight); $state = 0; } + close LOGFILE; +} + +sub initializeGlobals +{ + my $settinghash = undef; + if($draftoption == 1) { + $settinghash = \%draftsettings; + } elsif ($finaloption == 1) { + $settinghash = \%finalsettings; + } else { + $settinghash = \%customsettings; + } + if ($verbose != 0) { + print 'Using settings: ' . $$settinghash{'name'} . "\n"; + } + unless (defined ($outputdpi)) { + $outputdpi = $$settinghash{'outputdpi'} || 300; + } + unless (defined ($outputbwdpi)) { + $outputbwdpi = 4 * $outputdpi; + } + unless (defined ($outputfolderprefix)) { + $outputfolderprefix = $$settinghash{'outputfolder'} || 'printimg'; + } + unless (defined ($jpegquality)) { + $jpegquality = $$settinghash{'jpegquality'} || 80; + } } sub usage { - print <<'_endusage'; + print <<'_endusagehead'; pdflatexpicscale will downscale large raster images for your TeX project to reasonable size. Basic usage: pdflatexpicscale myarticle where your main LaTeX file is called 'myarticle.tex' and a log file exists. -Fine tuning: +General options: +--help (show this message) +--usage (show this message) +--verbose (let the script tell, what it attempts to do) +--version (show software version) +If you are comfortable with defaults (see manual), you may use one of the +following options: +_endusagehead + my %optiondumper = ( + 'name' => 'Option name', + 'outputfolder' => 'Output folder', + 'outputdpi' => 'Output density', + 'outputbwdpi' => 'same for B/W', + 'jpegquality' => 'JPEG quality' +); + print <<'_endusagefoot'; +Option name --final --draft +Output folder finalimg webimg +JPEG quality 80% 50% +output density 300 dpi 96 dpi +same for B/W 1200 dpi 300 dpi +tolerance 20% 20% +If not, you may do some fine tuning: --destdir=folder (relative path, must exist, defaults to 'printimg' subfolder of current folder) --srcdir=folder (folder to find original images, if this software can't figure it out on it's own, because you already - used the target directory.) + named the target directory inside your LaTex document.) --printdpi=XXX (default 300) ---tolerance=XX (default 20 Percents over printdpi to ignore scaling) ---verbose (if you want to know what the script attempts to do) ---version (show software version) -_endusage +--tolerance=XX (default 20 percent over printdpi to ignore scaling) +_endusagefoot } GetOptions('verbose' => \$verbose, - 'printdpi=i' => \$printdpi, - 'destdir=s' => \$printfolderprefix, + 'printdpi=i' => \$outputdpi, + 'destdir=s' => \$outputfolderprefix, 'tolerance=i' => \$tolerance, 'srcdir=s' => \$srcfolder, + 'draft' => \$draftoption, + 'final' => \$finaloption, 'version' => \$showversion, 'help' => \$help, 'usage' => \$help, @@ -242,17 +494,23 @@ if($showversion){ if($help){ usage(); + exit(0); } +my $settinghash = \%customsettings; + +initializeGlobals(); + $TeXproject = shift; if((defined $TeXproject) && ($TeXproject gt ' ')){ readlog($TeXproject); if($verbose) { - print "pdflatexpicscale Version $version:\n" + print "\npdflatexpicscale Version $version:\n" . "$copied file(s) copied, $scaled file(s) converted " . "and $skipped occurence(s) skipped for:\n${TeXproject}.log.\n"; } }else { usage(); + exit(1); } diff --git a/support/pdflatexpicscale/pdflatexpicscale.tex b/support/pdflatexpicscale/pdflatexpicscale.tex index e3b740a51a..a54bf283ec 100644 --- a/support/pdflatexpicscale/pdflatexpicscale.tex +++ b/support/pdflatexpicscale/pdflatexpicscale.tex @@ -5,7 +5,7 @@ \usepackage{url} \title{pdflatexpicscale} \author{Peter Willadt\footnote{willadt at t-online.de}} -\date{2018-02-12} %version #version +\date{2024-10-18} %version #version \begin{document} \maketitle @@ -54,39 +54,50 @@ scale graphics according to the output intent. \subsection{Prerequisites} -You have to install ImageMagick and Perl. If you are using Linux, please use -the tools of your distribution, if they are not already installed. As a -windows user, you may probably use the official ImageMagick distribution at -\url{http://www.imagemagick.org/script/download.php}. For Perl, you got more -options. I have tested pdflatexpicscale with ActiveState ActivePerl, but other -distributions should work too. -You also need the following Perl modules: \texttt{File::Basename}, -\texttt{File::Spec}, \texttt{File::Copy}, and \texttt{Getopt::Long}. There are -several ways to get these modules, if you have not got them already: +You \label{section:requisites} have to install Perl version~5, if it is not +installed already. If you are using Linux, I recommend to use the tools of +your distribution. As a windows user, you may probably use Strawberry Perl. +You also need the following Perl modules: +\begin{itemize} +\item \texttt{GD} (at least version 2.2), +\item \texttt{Image::ExifTool}, +\item \texttt{File::Basename}, +\item \texttt{File::Spec}, +\texttt{File::Copy}, and +\item \texttt{Getopt::Long}. +\end{itemize} + +There are no further requirements for the versions of the software to install, +but it may be wise to use recent releases. +There are several ways to get these modules, if you have not got them +already. The most popular are probably: \begin{itemize} \item use your Linux distribution's software manager \item use the Perl CPAN module -\item use ActiveState's \texttt{ppm} software, if you use ActivePerl. +\item use ActiveState's \texttt{ppm} software, if you happen to use + ActivePerl. \end{itemize} -Detailled description of these procedures is beyond the scope of this -document. +Detailed description of these procedures is beyond the scope of this +document. -There are no special requirements for the versions of the software to install, -but it may be wise to use recent versions, as there have been security flaws -with ImageMagick. +As of 2024, no further external software is needed, in contrast to earlier +versions. \subsection{Installation} -If the prerequisites have been fulfilled (which is perhaps standard for a -Linux computer), it is sufficient to move the file -\texttt{pdflatexpicscale.pl} to a place that is included in your PATH and to -make it executable. Of course, there are alternatives. You may perhaps -prefer to type\\ +If pdflatexpicscale.pl is part of your \TeX\ distribution, +chances are good that you only have to install missing Perl modules, if +any. Otherwise the following should apply: + +Having installed Perl and the required modules, it is sufficient to move +the file \texttt{pdflatexpicscale.pl} to a place that is included in your PATH +and to make it executable. Of course, there are alternatives. You may perhaps +prefer to type the following instead: + \texttt{perl /path/to/pdflatexpicscale.pl myarticle}\\ -instead. \section{Basic usage} @@ -127,7 +138,8 @@ Some other text... You hopefully do not have distinct pictures with the same name in the listed folders. With \verb|\graphicspath| you have to use double braces, even if you -use only one directory. +use only one directory. The best place for the \verb|\graphicspath| statement +is probably near the beginning of your \LaTeX\ file. \subsection{Preparing your \LaTeX\ file, Part~2} @@ -172,7 +184,7 @@ again on \texttt{myarticle}. I have told you to use double braces with \verb|\graphicspath|, haven't I? If you still are curious, you can again check the size of \texttt{myarticle.pdf}. -When it gets to preparing a print version, you create a directory for images +When it is time to prepare a print version, you create a directory for images with more detail, say \texttt{printpix}. You reset the \verb|\graphicspath|, run Pdf\LaTeX, issue\\ \texttt{pdflatexpicscale --printdpi=300 --destdir=printpix myarticle}\\ @@ -180,11 +192,10 @@ and set \verb|\graphicspath{{printpix/}}| before the next Pdf\LaTeX\ run. \section{Advanced usage} - \subsection{Excluding files from scaling} You will probably exclude files from scaling when you think that scaling will -do damage. You may achieve this by several means. Before you ask. Enumerating +harm. You may achieve this by several means. Before you ask: Enumerating files to exclude is not really cool, so this is not supported. \begin{enumerate} @@ -208,6 +219,19 @@ directories. Before the first \LaTeX\ run, you say\\ and after pdflatexpicscale is through, you change it to\\ \verb|\graphicspath{{hires/}{printimg/}}| +\subsection{Monochrome Images} + +While \label{section:monochrome}Pdf\TeX\ supports JBIG2 files, +pdflatexpicscale does not. Scaling JBIG2 files down looks like a bad idea, +anyway. + +Scaling monochrome\footnote{\emph{Monochrome} in the technical sense of one + bit per pixel as opposed to grayscale or color images that use only one + color.} images may lead to bad results. I recommend converting them to +grayscale before scaling, as blurred details are perhaps better than missing +details. pdflatexpicsacle will scale B/W images only if their resolution is at +least two times higher as requested. + \subsection{Gory details} pdflatexpicscale reads the log file, not the \LaTeX\ source. So you have to @@ -256,12 +280,16 @@ pictures remain unscaled because they are near the target resolution. Default is 20, that means 20~percent. If target resolution is 300~dpi, files up to 320~dpi get accepted too. Change to 0 if you want no tolerance. +\paragraph{draft/final} Setting one of these options will use reasonable +defaults, if you do not want to use any of the further options. +Please call \texttt{pdflatexpicscale.pl --help} to see concrete values. + \paragraph{verbose} entertains you by showing what the program is about to do. \paragraph{version} shows the software version. -Calling pdflatexpicscale without any options and without a project name will +Calling pdflatexpicscale.pl without any options and without a project name will display a short usage text. \subsection{Printer testing} @@ -335,5 +363,23 @@ this document, the option \texttt{tolerance} had been listed as As the TUGboat article corresponding to pdflatexpicscale is freely available now, the link on page~\pageref{tugboatart} has been adjusted. +\paragraph{2024-10-18} + +Added section~{section:monochrome} with hints for B/W images to +documentation. Also did some minor edits, especially to accompany the +following changes (see section~\ref{section:requisites}). + +As there have been issues with ImagMagick, pdflatexpicscale no longer uses +external software; Perl's GD and Image::ExifTool modules are used instead. + +Added new shortcut options \texttt{--draft} and \texttt{--final}. + +Refactored pdflatexpicscale.pl, hopefully without bad side effects. + % for file version please see line 8 \end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/support/pdflatexpicscale/testprinter.ps b/support/pdflatexpicscale/testprinter.ps index 900fe5dc8e..71856a45e4 100644 --- a/support/pdflatexpicscale/testprinter.ps +++ b/support/pdflatexpicscale/testprinter.ps @@ -4,7 +4,7 @@ % PostScript by Example. % First printing, 1992, P. 544 ff % Willadt 2016-07-27 -% version 2018-02-12 #version %version +% version 2024-10-18 #version %version % for information on usage and changes see pdflatexpicscale.pdf /prozente 20 string def diff --git a/support/SQLTeX/Makefile.am b/support/sqltex/Makefile.am index 82bde20e48..82bde20e48 100644 --- a/support/SQLTeX/Makefile.am +++ b/support/sqltex/Makefile.am diff --git a/support/SQLTeX/Makefile.in b/support/sqltex/Makefile.in index 2284b7696f..2284b7696f 100644 --- a/support/SQLTeX/Makefile.in +++ b/support/sqltex/Makefile.in diff --git a/support/SQLTeX/README.md b/support/sqltex/README.md index 37e4946bbf..a99022363a 100644 --- a/support/SQLTeX/README.md +++ b/support/sqltex/README.md @@ -1,4 +1,4 @@ -SQLTeX v2.2 +SQLTeX v3.0 =========== **SQLTeX** is a preprocessor to enable the use of SQL statements in LaTeX. It is a @@ -37,12 +37,16 @@ Others database (Ingres, mSQL, ...) '*should work*'™ but haven´t been te Installing SQLTeX ----------------- +Since version 3.0, **SQLTeX** is part of **TeX Live** and doesn't need further installation. + +If you are using a different LaTeX distro, please follow the steps below for your OS. + ### Linux ### On a linux system, download the archive and unpack: - $ tar vxzf sqltex-2.2.tar.gz - $ cd sqltex-2.2 + $ tar vxzf sqltex-3.0.tar.gz + $ cd sqltex-3.0 Next, install **SQLTeX** with the following commands: @@ -50,7 +54,7 @@ Next, install **SQLTeX** with the following commands: $ make $ sudo make install -The _`options`_ in `configure` are optional. For an overview of available options +The *options* in `configure` are optional. For an overview of available options type: $ ./configure --help @@ -61,12 +65,11 @@ type: #### Windows #### -This distribution contains an .EXE file that was generated using `PAR::Packer` -with Strawberry Perl. - -The files `sqltex-2.2\SQLTeX.EXE`, `sqltex-2.2\src\SQLTeX.cfg` and `sqltex-2.2\src\SQLTeX_r.dat` must be placed manually +The files `sqltex-3.0\sqltex`, `sqltex-3.0\src\SQLTeX.cfg` and `sqltex-3.0\src\SQLTeX_r.dat` must be placed manually in the directory of your choice, all in the same directory. +Since v3.0 the `SQLTeX.EXE` binary is no longer provided in the distribution. + #### OpenVMS #### For other operating systems, there is no install script, you will have to install @@ -74,9 +77,9 @@ it manually. On OpenVMS it would be something like: - $ COPY [.SQLTEX-2_2.SRC]SQLTEX.PL SYS$SYSTEM: - $ COPY [.SQLTEX-2_2.SRC]SQLTEX.CFG SYS$SYSTEM: - $ COPY [.SQLTEX-2_2.SRC]SQLTEX_R.DAT SYS$SYSTEM: + $ COPY [.SQLTEX-3_0.SRC]SQLTEX. SYS$SYSTEM:SQLTEX.PL + $ COPY [.SQLTEX-3_0.SRC]SQLTEX.CFG SYS$SYSTEM: + $ COPY [.SQLTEX-3_0.SRC]SQLTEX_R.DAT SYS$SYSTEM: $ SET FILE/PROTECTION=(W:R) SYS$SYSTEM:SQLTEX*.* However, on OpenVMS you also need to define the command SQLTEX by setting a @@ -108,6 +111,7 @@ installed in advance, since gcc is not available in a standard install of Mac OS Credits ------- +* **Karl Berry** for integration in TeX Live * **Ingo Reich** for the comment on Mac OS * **Johan W. Klüwer** for verifying the SyBase support * **Paolo Cavallini** for adding PostgreSQL support @@ -119,8 +123,9 @@ The **SQLTeX** project is available from [GitHub](https://github.com/oveas/sqlte For bugs, questions and comments, please use the [issue tracker](https://github.com/oveas/sqltex/issues) +Copyright (c) 2001-2024 - Oscar van Eijk, Oveas Functionality Provider + This software is subject to the terms of the LaTeX Project Public License; see [http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html](http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html) -Copyright (c) 2001-2024 - Oscar van Eijk, Oveas Functionality Provider diff --git a/support/SQLTeX/aclocal.m4 b/support/sqltex/aclocal.m4 index 6d04fca5b5..6d04fca5b5 100644 --- a/support/SQLTeX/aclocal.m4 +++ b/support/sqltex/aclocal.m4 diff --git a/support/SQLTeX/aclocal/ax_prog_perl_modules.m4 b/support/sqltex/aclocal/ax_prog_perl_modules.m4 index 11a326c930..11a326c930 100644 --- a/support/SQLTeX/aclocal/ax_prog_perl_modules.m4 +++ b/support/sqltex/aclocal/ax_prog_perl_modules.m4 diff --git a/support/SQLTeX/configure b/support/sqltex/configure index 345e365772..a5547a0926 100755 --- a/support/SQLTeX/configure +++ b/support/sqltex/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for SQLTeX 2.2. +# Generated by GNU Autoconf 2.71 for SQLTeX 3.0. # # Report bugs to <support@oveas.com>. # @@ -610,8 +610,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='SQLTeX' PACKAGE_TARNAME='sqltex' -PACKAGE_VERSION='2.2' -PACKAGE_STRING='SQLTeX 2.2' +PACKAGE_VERSION='3.0' +PACKAGE_STRING='SQLTeX 3.0' PACKAGE_BUGREPORT='support@oveas.com' PACKAGE_URL='' @@ -1243,7 +1243,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures SQLTeX 2.2 to adapt to many kinds of systems. +\`configure' configures SQLTeX 3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1310,7 +1310,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of SQLTeX 2.2:";; + short | recursive ) echo "Configuration of SQLTeX 3.0:";; esac cat <<\_ACEOF @@ -1385,7 +1385,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -SQLTeX configure 2.2 +SQLTeX configure 3.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1422,7 +1422,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by SQLTeX $as_me 2.2, which was +It was created by SQLTeX $as_me 3.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -2375,7 +2375,7 @@ fi # Define the identity of the package. PACKAGE='sqltex' - VERSION='2.2' + VERSION='3.0' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -3117,7 +3117,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by SQLTeX $as_me 2.2, which was +This file was extended by SQLTeX $as_me 3.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3172,7 +3172,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -SQLTeX config.status 2.2 +SQLTeX config.status 3.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/support/SQLTeX/configure.ac b/support/sqltex/configure.ac index ff773a4ae5..058032847b 100644 --- a/support/SQLTeX/configure.ac +++ b/support/sqltex/configure.ac @@ -16,7 +16,7 @@ AC_PREREQ([2.69]) # Ensure configure can check for the required perl modules. m4_include([aclocal/ax_prog_perl_modules.m4]) -AC_INIT([SQLTeX], [2.2], [support@oveas.com]) +AC_INIT([SQLTeX], [3.0], [support@oveas.com]) AM_INIT_AUTOMAKE diff --git a/support/SQLTeX/doc/Makefile.am b/support/sqltex/doc/Makefile.am index 56ee693ded..56ee693ded 100644 --- a/support/SQLTeX/doc/Makefile.am +++ b/support/sqltex/doc/Makefile.am diff --git a/support/SQLTeX/doc/Makefile.in b/support/sqltex/doc/Makefile.in index f42b41992e..f42b41992e 100644 --- a/support/SQLTeX/doc/Makefile.in +++ b/support/sqltex/doc/Makefile.in diff --git a/support/SQLTeX/doc/SQLTeX.pdf b/support/sqltex/doc/SQLTeX.pdf Binary files differindex 8d0b404360..050e48021d 100644 --- a/support/SQLTeX/doc/SQLTeX.pdf +++ b/support/sqltex/doc/SQLTeX.pdf diff --git a/support/SQLTeX/doc/SQLTeX.tex b/support/sqltex/doc/SQLTeX.tex index bc49991cb1..d3fbc8d667 100644 --- a/support/SQLTeX/doc/SQLTeX.tex +++ b/support/sqltex/doc/SQLTeX.tex @@ -1,6 +1,8 @@ \documentclass{article} \newcommand{\bs}{\ensuremath{\backslash}} \newcommand{\vs}{\vspace{3mm}} +\newcommand{\sqltexversion}{3.0} +\newcommand{\sqltexvmsversion}{3\_0} \usepackage{makeidx} \usepackage[pdftex ,pagebackref=true @@ -8,8 +10,8 @@ ,linkcolor=blue ,unicode]{hyperref} \begin{document} -\title{SQL\TeX\\v2.2} -\date{July 31, 2024} +\title{SQL\TeX\ v\sqltexversion} +\date{Sep 20, 2024} \author{Oscar van Eijk} \maketitle \hrulefill @@ -38,10 +40,13 @@ in the document. \section{Installing SQL\TeX} +Since v3.0, SQL\TeX\ is part of \TeX\ Live and doesn't need further installation. \\ +If you are using a different LaTeX distro, please follow the steps below for your OS. + Before installing SQL\TeX, you need to have it. The latest version can always be found at \url{https://github.com/oveas/sqltex}. The download consists of this do\-cumentation, an installation script for Unix -(\texttt{install}), and the Perl script \texttt{SQLTeX}, and a replace- file (\texttt{SQLTeX\_r.dat}) for manual installation +(\texttt{install}), and the Perl script \texttt{sqltex}, and a replace- file (\texttt{SQLTeX\_r.dat}) for manual installation on non- unix platforms\footnote{on Unix, this file will be generated by the install script}. \subsection{Requirements} @@ -58,11 +63,15 @@ SQL\TeX\ requires the following software: \subsection{Installation} -To install SQL\TeX, unpack the archive in a location of your choice and follow the steps below. +If you are using a \TeX\ Live distribution, SQL\TeX\ is already available. For all other distros, follow the steps in this section. + +\vs + +First unpack the archive in a location of your choice and continue with one if the subsections below depending on you operating system. \subsubsection{Linux} -Go to the top directory where the archive was unpacked (`\texttt{cd sqltex-2.2}') and execute the following commands: +Go to the top directory where the archive was unpacked (`\texttt{cd sqltex-\sqltexversion}') and execute the following commands: \vs @@ -100,19 +109,20 @@ After installation, the archive and unpack- directory can be removed. \subsubsection{Windows} -This distribution contains an \texttt{.EXE} file that was generated using \texttt{PAR::Packer} (\url{https://metacpan.org/pod/PAR::Packer}) with Strawberry Perl (\url{https://strawberryperl.com/}). +\noindent\hspace{-3mm}\textit{\underline{Note:}}Since v3.0, the binary \texttt{SQLTEX.EXE} for Windows is not included in the distribution anymore\footnote{ It can be generated with any (portable) perl version for Windows, like Strawberry Perl (\url{https://strawberryperl.com/}\label{winexe}), with \texttt{PAR::Packer} (\url{https://metacpan.org/pod/PAR::Packer}) using the command:\\ +\texttt{pp -o sqltex.exe sqltex}} \vs -The files \texttt{sqltex-2.2\ensuremath{\backslash}SQLTeX.EXE}, \texttt{sqltex-2.2\ensuremath{\backslash}src\ensuremath{\backslash}SQLTeX.cfg} and \\ \texttt{sqltex-2.2\ensuremath{\backslash}src\ensuremath{\backslash}SQLTeX\_r.dat} must be placed manually in the directory of your choice, all in the same direcrtory. +The files \texttt{sqltex-\sqltexversion\ensuremath{\backslash}sqltex}, \texttt{sqltex-\sqltexversion\ensuremath{\backslash}src\ensuremath{\backslash}SQLTeX.cfg} and \\ \texttt{sqltex-\sqltexversion\ensuremath{\backslash}src\ensuremath{\backslash}SQLTeX\_r.dat} must be placed manually in the directory of your choice, all in the same direcrtory. \subsubsection{OpenVMS} On \textsc{OpenVMS} the files must be copied manually to the destination. All files must reside in the same location:\\ -\texttt{\$ COPY [.SQLTEX-2\_2.SRC]SQLTEX.PL SYS\$SYSTEM:\\ -\$ COPY [.SQLTEX-2\_2.SRC]SQLTEX.CFG SYS\$SYSTEM:\\ -\$ COPY [.SQLTEX-2\_2.SRC]SQLTEX\_R.DAT SYS\$SYSTEM:\\ +\texttt{\$ COPY [.SQLTEX-\sqltexvmsversion.SRC]SQLTEX. SYS\$SYSTEM:SQLTEX.PL\\ +\$ COPY [.SQLTEX-\sqltexvmsversion.SRC]SQLTEX.CFG SYS\$SYSTEM:\\ +\$ COPY [.SQLTEX-\sqltexvmsversion.SRC]SQLTEX\_R.DAT SYS\$SYSTEM:\\ \$ SET FILE/PROTECTION=(W:RE) SYS\$SYSTEM:SQLTEX.PL} \vs @@ -124,15 +134,14 @@ system wide login procedure, with the command: \\ \subsection{Configuration}\label{config} -The configuration file \texttt{SQLTeX.cfg} is located in \texttt{/etc} (linux) or the same location where -SQL\TeX\ is installed (all other operating systems). +The configuration file \texttt{SQLTeX.cfg} is located in \texttt{/usr/local/etc} (linux) or the same location where SQL\TeX\ is installed (all other operating systems and in \TeX\ Live distros)\footnote{ If a 1.x version of SQL\TeX\ is installed on your system, make sure you save the configuration section, which was inline in older versions}. Multiple configuration files can be created, the command line option \texttt{--configfile} can be used to select the requested configuration. \vs -\noindent\hspace{-3mm}\textit{\underline{Note:}} If a 1.x version of SQL\TeX\ is installed on your system, -make sure you save the configuration section, which was inline in older versions. +\noindent\hspace{-3mm}\textit{\underline{Note:}}\label{cfg:disable} Use of the \texttt{--configfile} commandfile option can be disabled on system wide installations. To do so, the script \texttt{sqltex} must be modified.\\ +At the top of the file (line 4), set the value for \texttt{\$main::ext\_cfgfile\_allowed} to \texttt{0}. \vs @@ -164,6 +173,9 @@ outputfile with the name \texttt{db-docstx.tex}. \item[def\_out\_is\_in] By default, when no output file is specified or an output file without (relative) path is given, the output file will be generated in the current directory.\\ This behaviour changed in version 2.1. In older version, the location of the output file always was the same as the input file location. To revert to the old behaviour, set \texttt{def\_out\_is\_in} to `\texttt{1}'\footnote{ Note the pre-v2.1 implementation also contained a bug: if the output file name contained an absolute or relative path, this path was always taken as relative from the input file location. In the new implementation, \texttt{def\_out\_is\_in} is ignored if the output file name contains a path.}. + +\item[multi\_rfile]If the commandline option \texttt{--replacementfile} is given, by default the given replacement file will be parsed and after that the default replacement file will be parsed as well.\\ +If only the given replacement file should be parsed skipping the default file, set this value to \texttt{0}. \item[rfile\_comment] The comment-sign used in replace files. If this is empty, comments are not allowed in the replace files. @@ -207,7 +219,7 @@ With the default configuration this command is ``\texttt{\bs sqluse}''. \item[sql\_end] This string is appended to the \texttt{cmd\_prefix} to get the complete SQL\TeX\ command to end a loop context (see section~\ref{loops}).\\ With the default configuration this command is ``\texttt{\bs sqlend}''. -\item[sqlsystem\_allowed] Set this to ``1'' to allow the use of the \texttt{\bs sqlsystem} command (see section~\ref{sqlsystem}. +\item[sqlsystem\_allowed] Set this to ``1'' to allow the use of the \texttt{\bs sqlsystem} command (see section~\ref{sqlsystem}). \item[repl\_step] Replacing strings (see section~\ref{replfiles} below) is done two steps, to prevent values from being replaced twice. This setting---followed by a three-digit integer - ``000'' to ``999''---is used in the first step and replaces values from the first column. @@ -224,7 +236,7 @@ Normally, this setting should never change, but if the value for \texttt{cmd\_pr Replace files can be used to substitute values in the output of your SQL commands with a different value. This is especially useful when the database contains characters that are special characters in \LaTeX, like the percent sign (`\%'), underscore (`\_') etc. -When SQL\TeX\ is installed, it comes with a standard file---\texttt{SQLTeX\_r.dat}---which is located in \texttt{/usr/local/etc}\footnote{ if a replace file with that name already exists, it will be stored there as \texttt{SQLTeX\_r.dat.new}} (linux) or the same location where SQL\TeX\ is installed (all other operating systems). +When SQL\TeX\ is installed, it comes with a standard file---\texttt{SQLTeX\_r.dat}---which is located in \texttt{/usr/local/etc}\footnote{ if a replace file with that name already exists, it will be stored there as \texttt{SQLTeX\_r.dat.new}} (linux) or the same location where SQL\TeX\ is installed (all other operating systems and in \TeX\ Live distros). \vspace{3mm} @@ -416,6 +428,10 @@ this order:\\ Default host is localhost, the default user is the current user. +\vs + +\noindent\hspace{-3mm}\textit{\underline{Note:}} The \texttt{\bs sqldb} command cannot span multiple lines! + \subsubsection{Prompt for password and/or username} If a password is omitted, SQL\TeX\ will try connect to the database without a password, unless the commandline option \texttt{--password} is given (see section \ref{cmdline}). @@ -632,7 +648,7 @@ They will be replaced by the credentials for connecting to the database (see sec \vs \noindent Example:\\ -\texttt{\bs sqlsystem\{./add\_vat --usr <USR> --db <DB> --pwd <PWD> \\ +\texttt{\bs sqlsystem\{./add\_vat --usr <USR> --db <DB> --pwd <PWD> $\hookleftarrow$ \\ --inv \bs sqluse\{invoice\_nr\}\}} \vs @@ -641,6 +657,10 @@ By default, use of this command is disallowed. To enable it, set the value of \t If the command is disabled, occurances of this command will be replaced by the fixed text ``\texttt{use of the \bs sqlsystem command is disallowed in the configuration}''. +\vs + +\noindent\hspace{-3mm}\textit{\underline{Note:}} The \texttt{\bs sqlsystem} command cannot span multiple lines! + \subsection{Output multiple documents}\label{multidoc} @@ -708,8 +728,7 @@ parameter `0' cannot be used, since that contains the filename!}, it is replaced SQL\TeX\ accepts the following command- line options: \begin{description} -\item[\texttt{--configfile \textit{file}, -c \textit{file}}] SQL\TeX\ configuration file. Default is \texttt{SQLTeX.cfg} -in the same location where SQL\TeX\ is installed. +\item[\texttt{--configfile \textit{file}, -c \textit{file}}] SQL\TeX\ configuration file. Default is \texttt{SQLTeX.cfg} in the systems default location (see section \ref{config}). \item[\texttt{--file-extension \textit{string}, -E \textit{string}}] replace input file extension in outputfile: \texttt{input.tex} will be \texttt{input.\textit{string}}. \\ @@ -728,7 +747,7 @@ In \textit{string}, the values between curly braces \{\} will be substituted: \item[T] current time (\textit{hhmmss}) \end{description} e.g., the command\\ -\hspace*{1em}\texttt{SQLTeX --filename-extend \_\{P1\}\_\{W\} my\_file code}\\ +\hspace*{1em}\texttt{sqltex --filename-extend \_\{P1\}\_\{W\} my\_file code}\\ will read `\texttt{my\_file.tex}' and write `\texttt{myfile\_code\_Tue.tex}'.\\ The same command, but with option \texttt{---file-extension} would create the outputfile \texttt{my\_file.\_code\_Tue}\\ The options \texttt{--file-extension} and \texttt{--filename-extend} cannot be used together or with \texttt{--output}. @@ -749,22 +768,26 @@ query returns an empty set. \item[\texttt{--output \textit{file}, -o \textit{file}}] specify an output file. Cannot be used with \texttt{--file-extension}, \texttt{--filename-extend} or the \texttt{--multidoc} options. +\item[\texttt{--skip-empty-lines, -S}] All SQL\TeX\ commands will be removed from the input line or replaced by the corresponding value. The rest of the input line is written to the output file. +This includes lines that only contain a SQL\TeX\ command (and a newline character). This will result in an empty line in the output file.\\ +By specifying this option, these empty lines will be skipped. Lines that were empty in the input will be written. + +\item[\texttt{--write-comments, -C}] \LaTeX\ comments in the input file will be skipped by default. With this option, comments will also be copied to the output file. + \item[\texttt{--prefix \textit{prefix}, -p \textit{prefix}}] prefix used in the SQL\TeX\ file. Default is \texttt{sql} (see also section~\ref{config} on page~\pageref{prefix}. This overwrites the configurarion setting \texttt{cmd\_prefix}. -\item[\texttt{--password \textit{[password]}, -P} \textit{[password]}] database password. The value is optional; if omitted, SQL\TeX\ will prompt for a password. This overwrites the password in the input file.\\ +\item[\texttt{--password \textit{[password]}, -P} \textit{[password]}] database password. The value is optional; if omitted, SQL\TeX\ will prompt for a password. This overwrites the password in the input file. \item[\texttt{--quiet, -q}] run in quiet mode. \item[\texttt{--replacementfile \textit{replace}, -r \textit{replace}}] Specify a file that contains the replace characters (see section~\ref{replfiles}). \\ -Default is \texttt{SQLTeX{\_}r.dat} in the same location where SQL\TeX\ is installed. +Default is \texttt{SQLTeX{\_}r.dat} in the systems default location (see section \ref{replfiles}). This default file will always be used after the given replacement file, unless \texttt{multi\_rfile} is set to \texttt{0} in the configuration (see secion \ref{config}). \item[\texttt{--no-replacementfile, -R}] Do not use a replace file. \texttt{--no-replacementfile} and \texttt{--replacementfile \textit{file}} are handled in the same order as they appear on the command line, overwriting each other.\\ For backwards compatibility, \texttt{-rn} is also still supported. -\item[\texttt{--use-local-config, -l}]\footnote{ linux only} Use the current installation directory as default location for the config- and replacement files in stead of \texttt{/usr/local/etc}. - \item[\texttt{--sqlserver \textit{server}, -s \textit{server}}] SQL server to connect to. Default is \texttt{localhost}. \item[\texttt{--updates, -u}] if the input file contains updates, process them. @@ -943,6 +966,18 @@ see \url{http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html}. \section{History} \begin{description} +\item[v3.0] \textit{released: Sep 20, 2024} +\begin{itemize} +\item Made it possible to run SQL\TeX\ directly from the distribution without \texttt{configure} and \texttt{make [install]} to make integration in \TeX\ Live possible. +\item Renamed the script to \texttt{sqltex}. For backwards compatibility, during installation on linux a symbolic link \texttt{SQLTeX} is created. +\item The \texttt{SQLTeX.exe} binary is no longer included in the distribution (see footnote \footref{winexe} on page \pageref{winexe}). +\item Removed support for the \texttt{--use-local-config} commandline option. The options \texttt{--configfile} and \texttt{--replacementfile} can be used instead. +\item Added an option to disable the \texttt{--configfile} command line option (see note on page \pageref{cfg:disable}). +\item Added the \texttt{--skip-empty-lines} and \texttt{--write-comments} commandline options. +\item Added support for multiple replacement files. +\item Fix: ordering in the replacement file. +\end{itemize} + \item[v2.2] \textit{released: Jul 31, 2024} \begin{itemize} \item Extended the default replace file (see \ref{replfiles}) with more special characters (e.g. with diacritics) and HTML tags. diff --git a/support/SQLTeX/install-sh b/support/sqltex/install-sh index ec298b5374..ec298b5374 100755 --- a/support/SQLTeX/install-sh +++ b/support/sqltex/install-sh diff --git a/support/SQLTeX/man/Makefile.am b/support/sqltex/man/Makefile.am index f10c3cf610..59b7d84ee5 100644 --- a/support/SQLTeX/man/Makefile.am +++ b/support/sqltex/man/Makefile.am @@ -1,16 +1,16 @@ # Automake makefile for the linux manpage .PHONY: all distdir -DISTFILES = Makefile.am Makefile.in SQLTeX.man +DISTFILES = Makefile.am Makefile.in sqltex.man all : -SQLTeX.1 : SQLTeX.man +sqltex.1 : sqltex.man @cat $^ | sed -e 's#{BINDIR}#$(bindir)#;s#{SYSCONFDIR}#$(sysconfdir)#' > $@ distdir : ${DISTFILES} cp ${DISTFILES} $(distdir) -install: SQLTeX.1 +install: sqltex.1 @if [ ! -d ${mandir} ]; then mkdir -p ${mandir}; fi cp $^ ${mandir}/man1 diff --git a/support/SQLTeX/man/Makefile.in b/support/sqltex/man/Makefile.in index ff94a3a8af..d6cdd78baf 100644 --- a/support/SQLTeX/man/Makefile.in +++ b/support/sqltex/man/Makefile.in @@ -196,7 +196,7 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -DISTFILES = Makefile.am Makefile.in SQLTeX.man +DISTFILES = Makefile.am Makefile.in sqltex.man all: all-am .SUFFIXES: @@ -385,13 +385,13 @@ uninstall-am: all : -SQLTeX.1 : SQLTeX.man +sqltex.1 : sqltex.man @cat $^ | sed -e 's#{BINDIR}#$(bindir)#;s#{SYSCONFDIR}#$(sysconfdir)#' > $@ distdir : ${DISTFILES} cp ${DISTFILES} $(distdir) -install: SQLTeX.1 +install: sqltex.1 @if [ ! -d ${mandir} ]; then mkdir -p ${mandir}; fi cp $^ ${mandir}/man1 diff --git a/support/SQLTeX/man/SQLTeX.man b/support/sqltex/man/sqltex.man index daf9dfb4f7..8b2915fe77 100644 --- a/support/SQLTeX/man/SQLTeX.man +++ b/support/sqltex/man/sqltex.man @@ -5,7 +5,7 @@ - a preprocessor to enable the use of SQL statements in LaTeX documents. .SH SYNOPSIS -.B SQLTeX +.B sqltex .RB <INPUT-FILE> .RB [PARAMETERS] .RB [OPTIONS] @@ -37,7 +37,7 @@ These parameters are taken from the commandline. .SH OPTIONS .IP "\fB-c|--configfile\fP <file>" -SQLTeX configuration file. +SQLTeX configuration file. This option might be disallowed by your systems administrator. .IP "\fB-E|--file-extension\fP <string>" Replace input file extension in outputfile: 'input.tex' will be 'input.string'. @@ -93,6 +93,14 @@ Same as -m, but with the parameter in the filename i.s.o. a serial number .IP "\fB-o|--output\fP <file>" Specify an output file. Cannot be used with '--file-extension', '--filename-extend' or the '--multidoc' options. +.IP "\fB-S|--skip-empty-lines" +All SQLTeX commands will be removed from the input line or replaced by the corresponding value. The rest of the input line is written to the output file. +This includes lines that only contain a SQLTeX command (and a newline character). This will result in an empty line in the output file. +By specifying this option, these empty lines will be skipped. Lines that were empty in the input will be written. + +.IP "-C|--write-comments" +LaTeX comments in the input file will be skipped by default. With this option, comments will also be copied to the output file. + .IP "\fB-p|--prefix\fP <prefix>" Prefix used in the SQLTeX file. Default is 'sql' (see documentation) @@ -105,9 +113,6 @@ Specify a file that contains replace characters. This is a list with two tab-sep .IP "\fB-R|-rn|--no-replacementfile\fP" Do not use a replace file. '--replacementfile' '--no-replacementfile' are handled in the same order as they appear on the command line. -.IP "\fB-l|--use-local-config\fP" -Use the current installation directory as default location for the config- and replacement files in stead of '{SYSCONFDIR}' (linux only). - .IP "\fB-s|--sqlserver\fP <server>" SQL server to connect to. Default is \'localhost\' @@ -118,21 +123,24 @@ If the input file contains updates, execute them. .TP .I {SYSCONFDIR}/SQLTeX_r.dat +Default replacement file. If your installation is part of TEX Live the file will redisde in the same directory as the sqltex executable .TP .I {SYSCONFDIR}/SQLTeX.cfg +Default configuration file. If your installation is part of TEX Live the file will redisde in the same directory as the sqltex executable .TP .I -{BINDIR}/SQLTeX +{BINDIR}/sqltex +The sqltex executable. The location might differ depending on your installation type, e.g. as part if the TEX Live distribution. .SH EXAMPLES .TP -.BI SQLTeX\ --filename-extend\ _{P1}_{W}\ my_file\ code +.BI sqltex\ --filename-extend\ _{P1}_{W}\ my_file\ code .TP Read input file 'my_file.tex' and generate 'myfile_code_Tue.tex' with the processed results. .TP -.BI SQLTeX\ --file-extension\ _{P1}_{W}\ my_file\ code +.BI sqltex\ --file-extension\ _{P1}_{W}\ my_file\ code .TP Read input file 'my_file.tex' and generate 'myfile._code_Tue' with the processed results. @@ -149,6 +157,8 @@ SQLTeX ended with an error, check the last message. .SH COPYRIGHT .PP -Copyright 2001-2022 Oscar van Eijk, Oveas Functionality Provider. All rights reserved +Copyright 2001-2024 Oscar van Eijk, Oveas Functionality Provider. https://oveas.com +This software is subject to the terms of the LaTeX Project Public License; see http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html + diff --git a/support/SQLTeX/missing b/support/sqltex/missing index 1fe1611f18..1fe1611f18 100755 --- a/support/SQLTeX/missing +++ b/support/sqltex/missing diff --git a/support/SQLTeX/src/Makefile.am b/support/sqltex/src/Makefile.am index c15c25ba5b..bcf72fe6a1 100644 --- a/support/SQLTeX/src/Makefile.am +++ b/support/sqltex/src/Makefile.am @@ -2,23 +2,25 @@ .PHONY: distdir DATAFILES = SQLTeX_r.dat SQLTeX.cfg -DISTFILES = Makefile.am Makefile.in SQLTeX.pl ${DATAFILES} +DISTFILES = Makefile.am Makefile.in sqltex ${DATAFILES} PL=$(shell which perl) -all : SQLTeX +all : sqltex.pl distdir : ${DISTFILES} cp $(DISTFILES) $(distdir) -SQLTeX: SQLTeX.pl - cat $^ | sed -e 's#{PERLDIR}#!$(PL)#;s#{SYSCONFDIR}#$(sysconfdir)#' > $@ +sqltex.pl: sqltex + cat $^ | sed -e 's#!/usr/bin/env perl#!$(PL)#;s#/usr/local/etc#$(sysconfdir)#' > $@ @chmod +x $@ -install : SQLTeX ${DATAFILES} +install : sqltex.pl ${DATAFILES} @if [ ! -d ${bindir} ]; then mkdir -p ${bindir}; fi @if [ ! -d ${sysconfdir} ]; then mkdir -p ${sysconfdir}; fi - cp $< $(bindir) + @if [ -f $(bindir)/SQLTeX ]; then rm $(bindir)/SQLTeX; fi + cp $< $(bindir)/sqltex + ln -s $(bindir)/sqltex $(bindir)/SQLTeX @$(foreach datafile, $(DATAFILES), \ if [ -e $(sysconfdir)/$(datafile) ]; \ then echo 'cp $(datafile) $(sysconfdir)/$(datafile).new'; \ diff --git a/support/SQLTeX/src/Makefile.in b/support/sqltex/src/Makefile.in index bae98236db..588ef0464d 100644 --- a/support/SQLTeX/src/Makefile.in +++ b/support/sqltex/src/Makefile.in @@ -197,7 +197,7 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DATAFILES = SQLTeX_r.dat SQLTeX.cfg -DISTFILES = Makefile.am Makefile.in SQLTeX.pl ${DATAFILES} +DISTFILES = Makefile.am Makefile.in sqltex ${DATAFILES} PL = $(shell which perl) all: all-am @@ -385,19 +385,21 @@ uninstall-am: .PHONY: distdir -all : SQLTeX +all : sqltex.pl distdir : ${DISTFILES} cp $(DISTFILES) $(distdir) -SQLTeX: SQLTeX.pl - cat $^ | sed -e 's#{PERLDIR}#!$(PL)#;s#{SYSCONFDIR}#$(sysconfdir)#' > $@ +sqltex.pl: sqltex + cat $^ | sed -e 's#!/usr/bin/env perl#!$(PL)#;s#/usr/local/etc#$(sysconfdir)#' > $@ @chmod +x $@ -install : SQLTeX ${DATAFILES} +install : sqltex.pl ${DATAFILES} @if [ ! -d ${bindir} ]; then mkdir -p ${bindir}; fi @if [ ! -d ${sysconfdir} ]; then mkdir -p ${sysconfdir}; fi - cp $< $(bindir) + @if [ -f $(bindir)/SQLTeX ]; then rm $(bindir)/SQLTeX; fi + cp $< $(bindir)/sqltex + ln -s $(bindir)/sqltex $(bindir)/SQLTeX @$(foreach datafile, $(DATAFILES), \ if [ -e $(sysconfdir)/$(datafile) ]; \ then echo 'cp $(datafile) $(sysconfdir)/$(datafile).new'; \ diff --git a/support/SQLTeX/src/SQLTeX.cfg b/support/sqltex/src/SQLTeX.cfg index 1dd33f05d9..db6c507c2b 100644 --- a/support/SQLTeX/src/SQLTeX.cfg +++ b/support/sqltex/src/SQLTeX.cfg @@ -26,6 +26,13 @@ stx = _stx # def_out_is_in = 0 +# If the commandline option --replacementfile or -r is given, by default the given replacement file +# will be parsed and after that the default replacement file will be parsed as well. +# If only the given replacement file should be parsed skipping the default file, set the value +# below to 0. +# +multi_rfile = 1 + # Comment-sign used in the replace file(s). Leave empty to disable comments # rfile_comment = ; @@ -50,11 +57,9 @@ sql_update = update sql_start = start sql_end = end sql_use = use - -# Are the commands 'less' and/or 'more' available on this system ? -# -less_av = 1 -more_av = 1 +sql_system = system +sql_if = if +sql_endif = endif # Defines if the \sqlsystem{} command is allowed. # This is disabled by default, enable only if you are sure no SQLTeX files can be called that @@ -62,6 +67,15 @@ more_av = 1 # sqlsystem_allowed = 0 +# If the Term::ReadKey perl module is not installed, it is not possible to enter a password +# and hide it from the console when. In that case SQLTeX will abort if a password is specified +# as '?' in the LaTeX input file. +# To allow entering passwords that are readable from at the console, set the following to 1. +# NOTE: If you need to set this value to 1, you're strongly adviced to install the Term::ReadKey +# module instead: +# sudo cpan install Term::ReadKey +# +allow_readable_pwd = 0 # The values below are used internally only. There's no need to change these, # unless there are conflicts. Refer to the documentation for more info. diff --git a/support/SQLTeX/src/SQLTeX_r.dat b/support/sqltex/src/SQLTeX_r.dat index e71e66f82b..309d85b235 100644 --- a/support/SQLTeX/src/SQLTeX_r.dat +++ b/support/sqltex/src/SQLTeX_r.dat @@ -17,61 +17,11 @@ ; will replace all HTML <p> variants (<p style='font-size: normal'>, ; <p align='center'> etc) ; +; Order matters! +; We must start with the HTML code, since if the LaTeX special characters +; would be first, the characters '<' and '>' would be replaced already so +; HTML code is not recognised anymore. ; -; LaTeX special characters -; ------------------------ -; -$ \$ -_ \_ -% \% -& \& -< \texttt{<} -> \texttt{>} -{ \{ -} \} -# \# -~ \~{} -\ \ensuremath{\backslash} -; -; Diacretics -; ---------- -; -ñ \~{n} -â \^{a} -ä \"{a} -á \'{a} -à \`{a} -ç \c{c} -ê \^{e} -ë \"{e} -è \`{e} -é \'{e} -î \^{i} -ï \"{i} -í \'{i} -ì \`{i} -ô \^{o} -ö \"{o} -ó \'{o} -ò \`{o} -û \^{u} -ü \"{u} -ú \'{u} -ù \`{u} -ÿ \"{y} -; -; Other special characters -; ------------------------ -; -" '' -´ ' -
. - ' - ' - ' - ' - --- -± $\pm$ ; ; HTML special characters ; ----------------------- @@ -108,7 +58,7 @@ re(<h1.*?>) \section{ re(<h2.*?>) \subsection{ re(<h3.*?>) \subsubsection{ re(</h\d>) } -<br /> \\ +re(<br\s*/?>) \\ ; ; HTML lists ; ---------- @@ -132,3 +82,20 @@ re(</h\d>) } ;</td> & ;</table> \end{tabular} \\ ; +; +; LaTeX special characters +; ------------------------ +; +$ \$ +_ \_ +% \% +& \& +< \texttt{<} +> \texttt{>} +{ \{ +} \} +# \# +~ \~{} +\ \ensuremath{\backslash} +; + diff --git a/support/SQLTeX/src/SQLTeX.pl b/support/sqltex/src/sqltex index 29d1d2d20b..ea612c790f 100644..100755 --- a/support/SQLTeX/src/SQLTeX.pl +++ b/support/sqltex/src/sqltex @@ -1,10 +1,13 @@ -#{PERLDIR} +#!/usr/bin/env perl + +# To disable support for the --configfile option, set the value below to 0. +$main::ext_cfgfile_allowed = 1; ################################################################################ # # SQLTeX - SQL preprocessor for Latex # -# File: SQLTeX +# File: sqltex # ===== # # Purpose: This script is a preprocessor for LaTeX. It reads a LaTeX file @@ -15,6 +18,8 @@ # # Copyright: (c) 2001-2024, Oscar van Eijk, Oveas Functionality Provider # ========== oscar@oveas.com +# This software is subject to the terms of the LaTeX Project Public License; +# see http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html # # History: # ======== @@ -28,6 +33,7 @@ # v2.1-2 Jun 25, 2023 (test version parameter in sql_setparams(), no official release) # v2.1-3 Nov 30, 2023 (test version \sqlif-\sqlendif & \sqlsystem, no official release) # v2.2 Jul 31, 2024 +# v3.0 Sep 20, 202x # Refer to the documentation for changes per release # # TODO: @@ -39,23 +45,16 @@ #use strict; use DBI; use Getopt::Long; -use Term::ReadKey; Getopt::Long::Configure ("bundling"); +use Cwd; use feature 'state'; -##### -# Check if we're running on linux -# -sub is_linux { - return ($^O eq "linux"); -} - -##### -# Check if we're running on windows -# -sub is_windows { - return ($^O eq "MSWin32"); -} +$main::ReadKey_available = eval +{ + require Term::ReadKey; + Term::ReadKey->import(); + 1; +}; ##### # Find out if any command-line options have been given @@ -70,6 +69,8 @@ sub parse_options { , 'replacementfile|r=s' => \$main::options{'r'} , 'no-replacementfile|R' => \$main::options{'R'} , 'output|o=s' => \$main::options{'o'} + , 'skip-empty-lines|-S' => \$main::options{'S'} + , 'write-comments|-C' => \$main::options{'C'} , 'filename-extend|e=s' => \$main::options{'e'} , 'file-extension|E=s' => \$main::options{'E'} , 'sqlserver|s=s' => \$main::options{'s'} @@ -85,8 +86,8 @@ sub parse_options { , 'use-local-config|l' => \$main::options{'l'} , 'updates|u' => \$main::options{'u'} )) { - print "usage: $main::myself [options] <file[.$main::configuration{'texex'}]> [parameter...]\n" - . " type \"$main::myself --help\" for help\n"; + print "usage: sqltex [options] <file[.$main::configuration{'texex'}]> [parameter...]\n" + . " type \"sqltex --help\" for help\n"; exit(1); } @@ -130,8 +131,8 @@ sub parse_options { } } - if (defined $main::options{'l'} && !&is_linux) { - warn "Option \"-l\" is ignored on $^O"; + if (defined $main::options{'l'}) { + warn "Option '-l' is obsolete, use '-c <location>' instead"; delete $main::options{'l'}; } } @@ -141,8 +142,8 @@ sub parse_options { # sub short_help ($) { my $onerror = shift; - my $helptext = "usage: $main::myself [options] <file[.$main::configuration{'texex'}]> [parameter...]\n"; - $helptext .= " type \"$main::myself -h\" for help\n" if ($onerror); + my $helptext = "usage: sqltex [options] <file[.$main::configuration{'texex'}]> [parameter...]\n"; + $helptext .= " type \"sqltex -h\" for help\n" if ($onerror); return ($helptext); } @@ -153,30 +154,37 @@ sub short_help ($) { sub print_help { my $helptext = &short_help (0); - $helptext .= " Options:\n"; - $helptext .= " --configfile <file>\n"; - $helptext .= " -c <file>\n"; - $helptext .= " SQLTeX configuration file.\n"; - $helptext .= " Default is \'$main::config_location/SQLTeX.cfg\'.\n"; + $helptext .= " Options:\n"; + if ($main::ext_cfgfile_allowed) { + $helptext .= " --configfile <file>\n"; + $helptext .= " -c <file>\n"; + $helptext .= " SQLTeX configuration file.\n"; + $helptext .= " Default is \'$main::config_location/SQLTeX.cfg\'.\n\n"; + } $helptext .= " --file-extension <string>\n"; $helptext .= " -E <string>\n"; $helptext .= " replace input file extension in outputfile:\n"; $helptext .= " \'input.tex\' will be \'input.string\'\n"; - $helptext .= " For further notes, see option \'--filename-extend\' below\n"; + $helptext .= " For further notes, see option \'--filename-extend\' below\n\n"; + $helptext .= " --null-allowed\n"; $helptext .= " -N\n"; $helptext .= " NULL return values allowed. By default SQLTeX exits if a\n"; - $helptext .= " query returns an empty set\n"; + $helptext .= " query returns an empty set\n\n"; + $helptext .= " --password [password]\n"; $helptext .= " -P [password]\n"; $helptext .= " database password. The value is optional; if omitted, SQLTeX will prompt for\n"; - $helptext .= " a password. This overwrites the password in the input file.\n"; + $helptext .= " a password. This overwrites the password in the input file.\n\n"; + $helptext .= " --username <user>\n"; $helptext .= " -U <user>\n"; - $helptext .= " database username\n"; + $helptext .= " database username\n\n"; + $helptext .= " --version\n"; $helptext .= " -V\n"; - $helptext .= " print version number and exit\n"; + $helptext .= " print version number and exit\n\n"; + $helptext .= " --filename-extend <string>\n"; $helptext .= " -e <string>\n"; $helptext .= " add string to the output filename:\n"; @@ -189,70 +197,89 @@ sub print_help { $helptext .= " D current date (yyyymmdd)\n"; $helptext .= " DT current date and time (yyyymmddhhmmss)\n"; $helptext .= " T current time (hhmmss)\n"; - $helptext .= " e.g., the command \'$main::myself --filename-extend _{P1}_{W} my_file code\'\n"; + $helptext .= " e.g., the command \'sqltex --filename-extend _{P1}_{W} my_file code\'\n"; $helptext .= " will read \'my_file.tex\' and write \'myfile_code_Tue.tex\'\n"; $helptext .= " The same command, but with option \--file-extension\' would create the\n"; $helptext .= " outputfile \'myfile._code_Tue\'\n"; $helptext .= " By default the outputfile \'myfile_stx.tex\' would have been written.\n"; $helptext .= " The options \'--file-extension\' and \'--filename-extend\' cannot be used\n"; - $helptext .= " together or with \'--output\'.\n"; + $helptext .= " together or with \'--output\'.\n\n"; + $helptext .= " --force\n"; $helptext .= " -f\n"; - $helptext .= " force overwrite of existing files\n"; + $helptext .= " force overwrite of existing files\n\n"; + $helptext .= " --help\n"; $helptext .= " -h\n"; - $helptext .= " print this help message and exit\n"; + $helptext .= " print this help message and exit\n\n"; + $helptext .= " --multidoc-numbered\n"; $helptext .= " -m\n"; $helptext .= " Multidocument mode; create one document for each parameter that is retrieved\n"; $helptext .= " from the database in the input document (see documentation)\n"; - $helptext .= " This option cannot be used with \'--output\'.\n"; + $helptext .= " This option cannot be used with \'--output\'.\n\n"; + $helptext .= " --multidoc-named\n"; $helptext .= " -M\n"; - $helptext .= " Same as -m, but with the parameter in the filename i.s.o. a serial number\n"; + $helptext .= " Same as -m, but with the parameter in the filename i.s.o. a serial number\n\n"; + $helptext .= " --output <file>\n"; $helptext .= " -o <file>\n"; $helptext .= " specify an output file. Cannot be used with \'--file-extension\',\n"; - $helptext .= " \'--filename-extend\' or the \'--multidoc\' options.\n"; + $helptext .= " \'--filename-extend\' or the \'--multidoc\' options.\n\n"; + + $helptext .= " --skip-empty-lines\n"; + $helptext .= " -S\n"; + $helptext .= " All SQLTeX commands will be removed from the input line or replaced by the\n"; + $helptext .= " corresponding value. The rest of the input line is written to the output file.\n"; + $helptext .= " This includes lines that only contain a SQLTeX command (and a newline character).\n"; + $helptext .= " This will result in an empty line in the output file.\n"; + $helptext .= " By specifying this option, these empty lines will be skipped. Lines that were empty\n"; + $helptext .= " in the input will be written.\n\n"; + + $helptext .= " --write-comments\n"; + $helptext .= " -C\n"; + $helptext .= " LaTeX comments in the input file will be skipped by default. With this option,\n"; + $helptext .= " comments will also be copied to the output file.\n\n"; + $helptext .= " --prefix <prefix>\n"; $helptext .= " -p <prefix>\n"; $helptext .= " prefix used in the SQLTeX file. Default is \'sql\'\n"; $helptext .= " (e.g. \\sqldb[user]{database}), but this can be overwritten if it conflicts\n"; - $helptext .= " with other user-defined commands.\n"; + $helptext .= " with other user-defined commands.\n\n"; + $helptext .= " --quiet\n"; $helptext .= " -q\n"; - $helptext .= " run in quiet mode\n"; + $helptext .= " run in quiet mode\n\n"; + $helptext .= " --replacementfile <file>\n"; $helptext .= " -r <file>\n"; $helptext .= " specify a file that contains replace characters. This is a list with two tab-separated\n"; $helptext .= " fields per line. The first field holds a string that will be replaced in the SQL output\n"; $helptext .= " by the second string.\n"; $helptext .= " By default the file \'$main::config_location/SQLTeX_r.dat\' is used.\n"; + $helptext .= " This default file will still be read after the given replacement file, unless support for\n"; + $helptext .= " multiple replacement files is disabled in the configuration.\n\n"; + $helptext .= " --no-replacementfile\n"; $helptext .= " -R\n"; $helptext .= " do not use a replace file. \'--replacementfile\' \'--no-replacementfile\' are handled\n"; $helptext .= " in the same order as they appear on the command line.\n"; - $helptext .= " For backwards compatibility, -rn is also still supported.\n"; - - if (&is_linux) { - $helptext .= " --use-local-config\n"; - $helptext .= " -l\n"; - $helptext .= " use $main::my_location as default location for the config- and replacement files\n"; - $helptext .= " in stead of $main::config_location.\n"; - } + $helptext .= " For backwards compatibility, -rn is also still supported.\n\n"; $helptext .= " --sqlserver <server>\n"; $helptext .= " -s <server>\n"; - $helptext .= " SQL server to connect to. Default is \'localhost\'\n"; + $helptext .= " SQL server to connect to. Default is \'localhost\'\n\n"; + $helptext .= " --updates\n"; $helptext .= " -u\n"; - $helptext .= " If the input file contains updates, execute them.\n"; + $helptext .= " If the input file contains updates, execute them.\n\n"; - $helptext .= "\n file is the input file that should be read. By default,\n"; - $helptext .= " $main::myself looks for a file with extension \'.$main::configuration{'texex'}\'.\n"; - $helptext .= "\n parameter(s) are substituted in the SQL statements if they contain\n"; - $helptext .= " the string \$PAR[x] somewhere in the statement, where\n"; - $helptext .= " \'x\' is the number of the parameter.\n"; + $helptext .= " file is the input file that should be read. By default,\n"; + $helptext .= " sqltex looks for a file with extension \'.$main::configuration{'texex'}\'.\n\n"; + $helptext .= " parameter(s) are substituted in the SQL statements if they contain\n"; + $helptext .= " the string \$PAR[x] somewhere in the statement, where\n"; + $helptext .= " \'x\' is the number of the parameter.\n"; print $helptext; } @@ -261,7 +288,7 @@ sub print_help { # Print the version number # sub print_version { - print "$main::myself v$main::version - $main::rdate\n"; + print "sqltex v$main::version - $main::rdate\n"; } ##### @@ -283,21 +310,30 @@ sub get_password ($$) { my $pwd = ""; - print "Password for $usr\@$srv : "; - - ReadMode(4); - while(ord(my $keyStroke = ReadKey(0)) != 10) { - if(ord($keyStroke) == 127 || ord($keyStroke) == 8) { # DEL/Backspace - chop($pwd); - print "\b \b"; - } elsif(ord($keyStroke) >= 32) { # Skip control characters - $pwd = $pwd . $keyStroke; - print '*'; + my $q = "Password for $usr\@$srv : "; + if ($main::ReadKey_available) { + print $q; + ReadMode(4); + while(ord(my $keyStroke = ReadKey(0)) != 10) { + if(ord($keyStroke) == 127 || ord($keyStroke) == 8) { # DEL/Backspace + chop($pwd); + print "\b \b"; + } elsif(ord($keyStroke) >= 32) { # Skip control characters + $pwd = $pwd . $keyStroke; + print '*'; + } + } + ReadMode(0); + print "\n"; + } else { + if ($main::configuration{'allow_readable_pwd'}) { + print $q; + $pwd = <STDIN>; + chomp $pwd; + } else { + die "Cannot ask for password. Either install the Term::ReadKey module or set 'allow_readable_pwd' to 1 in the configuration"; } } - ReadMode(0); - print "\n"; - return $pwd; } @@ -361,6 +397,9 @@ sub file_extension ($) { # sub get_configfiles { if (defined $main::options{'c'}) { + if (!$main::ext_cfgfile_allowed) { + die "Use of the --configfile option is disallowed by your system administrator"; + } $main::configurationfile = $main::options{'c'}; } else { $main::configurationfile = $main::config_location @@ -370,20 +409,32 @@ sub get_configfiles { if (!-e $main::configurationfile) { die ("Configfile $main::configurationfile does not exist\n"); } - - if (defined $main::options{'r'}) { - $main::replacefile = $main::options{'r'}; - } else { - $main::replacefile = $main::config_location - . ($main::config_location eq '' ? '' : '/') - . 'SQLTeX_r.dat' - unless (defined $main::options{'R'}); - } - if (defined $main::replacefile && !-e $main::replacefile) { - warn ("replace file $main::replacefile does not exist\n") unless ($main::replacefile eq "n"); - undef $main::replacefile; + + @main::replacefiles = (); + if (!defined $main::options{'R'} && $main::options{'r'} ne "n") { + my $std_replacefile = $main::config_location + . ($main::config_location eq '' ? '' : '/') . 'SQLTeX_r.dat'; + if (!-e $std_replacefile) { + warn ("replace file $std_replacefile does not exist\n"); + $std_replacefile = ""; + } + my $adl_replacefile = ""; + if (defined $main::options{'r'}) { + if (!-e $main::options{'r'}) { + warn ("replace file $main::options{'r'} does not exist\n"); + } else { + $adl_replacefile = $main::options{'r'}; + } + } + my $rf_cnt = 0; + if ($adl_replacefile ne "") { + $main::replacefiles[$rf_cnt++] = $adl_replacefile; + } + if ($std_replacefile ne "") { + $main::replacefiles[$rf_cnt++] = $std_replacefile; + } } - + return; } @@ -440,9 +491,9 @@ sub get_filenames { ##### # Trim functions # -sub ltrim { my $s = shift; $s =~ s/^\s+//; return $s }; -sub rtrim { my $s = shift; $s =~ s/\s+$//; return $s }; -sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s }; +sub ltrim { my $s = shift; $s =~ s/^\s+//; return $s; } +sub rtrim { my $s = shift; $s =~ s/\s+$//; return $s; } +sub trim { my $s = shift; return ltrim(rtrim($s)); } ####### # Connect to the database @@ -545,7 +596,7 @@ sub db_connect($$) { ,'db' => $db ); } - $main::db_handle = DBI->connect ($data_source, $un, $pw, { RaiseError => 0, PrintError => 1 }) || &just_died (1); # TODO Proper errorhandling + $main::db_handle = DBI->connect ($data_source, $un, $pw, { RaiseError => 0, PrintError => 1 }) || &signal_message (1); return; } @@ -575,16 +626,10 @@ sub check_options ($) { if ($opt =~ /^fldsep=/i) { $main::fldsep = qq{$'}; $main::fldsep =~ s/NEWLINE/\n/; -# if ($main::fldsep eq 'NEWLINE') { -# $main::fldsep = "\n"; -# } } if ($opt =~ /^rowsep=/i) { $main::rowsep = qq{$'}; $main::rowsep =~ s/NEWLINE/\n/; -# if ($main::rowsep eq 'NEWLINE') { -# $main::rowsep = "\n"; -# } } } } @@ -635,7 +680,7 @@ sub sql_row ($$) { $stat_handle->execute (); if ($main::setarr) { - &just_died (7) if (defined $main::arr[$main::arr_no] && !$main::multidoc); # TODO Proper errorhandling + &signal_message (7) if (defined $main::arr[$main::arr_no] && !$main::multidoc); @main::arr[$main::arr_no] = (); while (my $ref = $stat_handle->fetchrow_hashref()) { foreach my $k (keys %$ref) { @@ -649,7 +694,7 @@ sub sql_row ($$) { while (@values = $stat_handle->fetchrow_array ()) { $fc = $#values + 1; - if (defined $main::replacefile) { + if ($#main::replacefiles >= 0) { my $list_cnt = 0; foreach (@values) { $values[$list_cnt] = replace_values ($values[$list_cnt]); @@ -661,7 +706,7 @@ sub sql_row ($$) { $stat_handle->finish (); if ($#return_values < 0) { - &just_died (4); # TODO Proper errorhandling + &signal_message (4); } $rc = $#return_values + 1; @@ -695,17 +740,17 @@ sub sql_field ($$) { $stat_handle->finish (); if ($#result < 0) { - &just_died (4); # TODO Proper errorhandling + &signal_message (4); } elsif ($#result > 0) { - &just_died (5); # TODO Proper errorhandling + &signal_message (5); } else { &print_message ("Found 1 value: \"$result[0]\""); if ($main::setvar) { - &just_died (7) if (defined $main::var[$main::var_no] && !$main::multidoc); # TODO Proper errorhandling + &signal_message (7) if (defined $main::var[$main::var_no] && !$main::multidoc); $main::var[$main::var_no] = $result[0]; return ''; } else { - if (defined $main::replacefile) { + if ($#main::replacefiles >= 0) { return (replace_values ($result[0])); } else { return ($result[0]); @@ -719,7 +764,7 @@ sub sql_field ($$) { # sub sql_start ($) { my $arr_no = shift; - &just_died (11) if (!defined $main::arr[$arr_no]); # TODO Proper errorhandling + &signal_message (11) if (!defined $main::arr[$arr_no]); if (@main::current_array) { @main::current_array = (); } @@ -733,7 +778,7 @@ sub sql_start ($) { sub sql_use ($$) { my ($field, $loop) = @_; my $return_value = $main::configuration{'no_such_used_fld'}; - if ($main::arr[$#main::current_array][$loop]->{$field}) { + if (defined $main::arr[$#main::current_array][$loop]->{$field}) { $return_value = $main::arr[$#main::current_array][$loop]->{$field}; } return $return_value; @@ -892,7 +937,7 @@ sub sql_setparams ($$) { $stat_handle->finish (); if ($#return_values < 0) { - &just_died (8); # TODO Proper errorhandling + &signal_message (8); } &print_message ('Multidocument parameters found; ' . $#return_values+1 ." documents will be created: handle document $main::multidoc_cnt") unless ($main::multidoc_cnt == 0); @@ -937,25 +982,17 @@ sub sql_system ($) { } ##### -# Some error handling (mainly cleanup stuff) +# Simple error handling # Files will be closed if opened, and if no sql output was written yet, # the outputfile will be removed. -# FIXME We need some decent errorhandling # -sub just_died ($) { +sub signal_message ($) { my $step = shift; - my $Resurect = 0; + my $can_continue = 0; - $Resurect = 1 if ($step == 4 && $main::NULLallowed); + $can_continue = 1 if ($step == 4 && $main::NULLallowed); - if ($step >= 1 && !$Resurect) { -# close FI; -# close FO; - } - if ($step > 2 && !$Resurect) { -# $main::db_handle->disconnect(); - } - if ($step >= 1 && $step <= 2 && !$Resurect) { + if ($step >= 1 && $step <= 2 && !$can_continue) { unlink ($main::outputfile); } @@ -963,7 +1000,9 @@ sub just_died ($) { # Step specific exit # my $msg; - if ($step == 2) { + if ($step == 1) { + $msg = "noerror opening database at line $main::lcount[$main::fcount]"; + } elsif ($step == 2) { $msg = "no database opened at line $main::lcount[$main::fcount]"; } elsif ($step == 3) { $msg = "insufficient parameters to substitute variable on line $main::lcount[$main::fcount]"; @@ -994,7 +1033,7 @@ sub just_died ($) { } } warn "$msg\n"; - return if ($Resurect); + return if ($can_continue); exit (1); } @@ -1049,7 +1088,7 @@ sub parse_command ($$$) { while ($statement =~ /\$VAR[0-9]/) { my $varno = $&; $varno =~ s/\$VAR//; - &just_died (6) if (!defined ($main::var[$varno])); # TODO Proper errorhandling + &signal_message (6) if (!defined ($main::var[$varno])); $statement =~ s/\$VAR$varno/$main::var[$varno]/g; } if ($statement =~ /\$PAR/ && ($main::multidoc_cnt > 0) && $main::multidoc) { @@ -1069,7 +1108,7 @@ sub parse_command ($$$) { return 0; } - &just_died (2) if (!$main::db_opened); # TODO Proper errorhandling + &signal_message (2) if (!$main::db_opened); if ($cmdfound eq $main::configuration{'sql_field'}) { $main::line = $lin1 . &sql_field($options, $statement) . $lin2; } elsif ($cmdfound eq $main::configuration{'sql_row'}) { @@ -1089,19 +1128,19 @@ sub parse_command ($$$) { &sql_start($statement); $main::line = $lin1 . $lin2; } elsif ($cmdfound eq $main::configuration{'sql_use'}) { - &just_died (12) if (!@main::current_array); # TODO Proper errorhandling + &signal_message (12) if (!@main::current_array); $main::line = $lin1 . "\\" . $main::configuration{'alt_cmd_prefix'} . $main::configuration{'sql_use'} . "{" . $statement . "}" . $lin2; # Restore the line, will be processed later } elsif ($cmdfound eq $main::configuration{'sql_end'}) { $main::line = $lin1 . &sql_end() . $lin2; } elsif ($cmdfound eq $main::configuration{'sql_endif'}) { $main::line = $lin1 . "\\" . $main::configuration{'alt_cmd_prefix'} . $main::configuration{'sql_endif'} . "{}" . $lin2; # Restore the line, will be processed later } elsif ($cmdfound eq $main::configuration{'sql_if'}) { - &just_died (13) if (!@main::current_array); # TODO Proper errorhandling + &signal_message (13) if (!@main::current_array); $main::line = $lin1 . "\\" . $main::configuration{'alt_cmd_prefix'} . $main::configuration{'sql_if'} . "{" . $statement . "}" . $lin2; # Restore the line, will be processed later } elsif ($cmdfound =~ /$main::configuration{'sql_system'}/) { $main::line = $lin1 . &sql_system($raw_statement) . $lin2; } else { - &just_died (10); # TODO Proper errorhandling + &signal_message (10); } return 0; } @@ -1120,27 +1159,34 @@ sub read_input($$$$) { while ($main::line = <$fileIn>) { $main::lcount[$main::fcount]++; + my $line_had_cmd = 0; - next if ($main::line =~ /^\s*%/); - if ($main::line =~ /(.*?)(\\in(put|clude))(\s*?)\{(.*?)\}(.*)/) { - print $output_handle "$1" unless ($output_handle == -1); - &read_input($5, $output_handle, $multidoc_par); - return if ($main::restart); - print $output_handle "$6\n" unless ($output_handle == -1); - } - my $cmdPrefix = $main::configuration{'cmd_prefix'}; - if (@main::current_array) { - # Inside loop contect the \sqlsystem{} command can contain \sqluse{} - $main::line =~ s/$cmdPrefix$main::configuration{'sql_system'}/$main::configuration{'last_cmd_prefix'}$main::configuration{'sql_system'}/; - } - while (($main::line =~ /\\$cmdPrefix[a-z]+(\[|\{)/) && !($main::line =~ /\\\\$cmdPrefix[a-z]+(\[|\{)/)) { - if (&parse_command($&, $multidoc_par, $fileIn) && $main::multidoc && ($main::multidoc_cnt == 0)) { - close $fileIn; - $main::fcount--; - $main::restart = 1; - return; + if ($main::line =~ /^\s*%/) { + next if (!$main::options{'C'}); + } else { + if ($main::line =~ /(.*?)(\\in(put|clude))(\s*?)\{(.*?)\}(.*)/) { + print $output_handle "$1" unless ($output_handle == -1); + &read_input($5, $output_handle, $multidoc_par); + return if ($main::restart); + print $output_handle "$6\n" unless ($output_handle == -1); + } + my $cmdPrefix = $main::configuration{'cmd_prefix'}; + if (@main::current_array) { + # Inside loop context the \sqlsystem{} command can contain \sqluse{} + $main::line =~ s/$cmdPrefix$main::configuration{'sql_system'}/$main::configuration{'last_cmd_prefix'}$main::configuration{'sql_system'}/; + } + while (($main::line =~ /\\$cmdPrefix[a-z]+(\[|\{)/) && !($main::line =~ /\\\\$cmdPrefix[a-z]+(\[|\{)/)) { + $line_had_cmd = 1; + if (&parse_command($&, $multidoc_par, $fileIn) && $main::multidoc && ($main::multidoc_cnt == 0)) { + close $fileIn; + $main::fcount--; + $main::restart = 1; + return; + } } } + next if ($line_had_cmd && $main::line eq "\n" && $main::options{'S'}); + if (@main::current_array && $#main::current_array >= 0) { push @{$main::loop_data[$#main::current_array]}, $main::line; } else { @@ -1199,66 +1245,64 @@ sub process_file { # Default config values, can be overwritten with SQLTeX.cfg # %main::configuration = ( - 'dbdriver' => 'mysql' - ,'oracle_sid' => 'ORASID' - ,'texex' => 'tex' - ,'stx' => '_stx' - ,'def_out_is_in' => 0 - ,'rfile_comment' => ';' - ,'rfile_regexploc' => '...' - ,'rfile_regexp' => 're(...)' - ,'cmd_prefix' => 'sql' - ,'sql_system' => 'system' - ,'sql_open' => 'db' - ,'sql_field' => 'field' - ,'sql_row' => 'row' - ,'sql_params' => 'setparams' - ,'sql_update' => 'update' - ,'sql_start' => 'start' - ,'sql_end' => 'end' - ,'sql_use' => 'use' - ,'sql_if' => 'if' - ,'sql_endif' => 'endif' - ,'sqlsystem_allowed'=> 0 - ,'repl_step' => 'OSTX' - ,'alt_cmd_prefix' => 'processedsqlcommand' - ,'last_cmd_prefix' => 'lastsqlcommand' - ,'no_such_used_fld' => '\textit{SQL\TeX\ use-field does not exist}' + 'dbdriver' => 'mysql' + ,'oracle_sid' => 'ORASID' + ,'texex' => 'tex' + ,'stx' => '_stx' + ,'def_out_is_in' => 0 + ,'rfile_comment' => ';' + ,'rfile_regexploc' => '...' + ,'rfile_regexp' => 're(...)' + ,'multi_rfile' => 1 + ,'cmd_prefix' => 'sql' + ,'sql_system' => 'system' + ,'sql_open' => 'db' + ,'sql_field' => 'field' + ,'sql_row' => 'row' + ,'sql_params' => 'setparams' + ,'sql_update' => 'update' + ,'sql_start' => 'start' + ,'sql_end' => 'end' + ,'sql_use' => 'use' + ,'sql_if' => 'if' + ,'sql_endif' => 'endif' + ,'sqlsystem_allowed' => 0 + ,'allow_readable_pwd'=> 0 + ,'repl_step' => 'OSTX' + ,'alt_cmd_prefix' => 'processedsqlcommand' + ,'last_cmd_prefix' => 'lastsqlcommand' + ,'no_such_used_fld' => '\textit{SQL\TeX\ use-field does not exist}' ); ##### # Some globals # { - my @dir_list = split /\//, $0; + my $realpath = Cwd::realpath($0); + + my @dir_list = split /\//, $realpath; pop @dir_list; $main::my_location = join '/', @dir_list; $main::if_enabled = 1; - - if (&is_linux) { - $main::config_location = '{SYSCONFDIR}'; - } else { + + if ($main::my_location =~ /texmf-dist\/scripts/) { + # Config location in a TeX Live distro $main::config_location = $main::my_location; + } else { + if ($^O eq "linux") { + # Default on linux, can be changed when running configure + $main::config_location = '/usr/local/etc'; + } else { + # Default on al other OSes + $main::config_location = $main::my_location; + } } } -# Check config -# Used for loops, should not start with $main::configuration{'cmd_prefix'} !! -if ($main::configuration{'alt_cmd_prefix'} =~ /^$main::configuration{'cmd_prefix'}/ - || $main::configuration{'last_cmd_prefix'} =~ /^$main::configuration{'cmd_prefix'}/) { - die "Configuration items 'alt_cmd_prefix' and ĺast_cnd_prefix' cannot start with $main::configuration{'cmd_prefix'}"; -} - -$main::myself = $0; - -$main::version = '2.2'; -$main::rdate = 'Jul 31, 2024'; +$main::version = '3.0'; +$main::rdate = 'Sep 20, 2024'; &parse_options; -if (defined $main::options{'l'}) { - $main::config_location = $main::my_location; -} - &get_configfiles; if (defined $main::configurationfile) { @@ -1277,6 +1321,13 @@ if (defined $main::configurationfile) { close CF; } +# Check config +# Used for loops, should not start with $main::configuration{'cmd_prefix'} !! +if ($main::configuration{'alt_cmd_prefix'} =~ /^$main::configuration{'cmd_prefix'}/ + || $main::configuration{'last_cmd_prefix'} =~ /^$main::configuration{'cmd_prefix'}/) { + die "Configuration items 'alt_cmd_prefix' and ĺast_cnd_prefix' cannot start with $main::configuration{'cmd_prefix'}"; +} + &get_filenames; if (!$main::multidoc && -e "$main::outputfile") { @@ -1284,23 +1335,28 @@ if (!$main::multidoc && -e "$main::outputfile") { unless (defined $main::options{'f'}); } -if (defined $main::replacefile) { +{ my $repl_cnt = '000'; @main::repl_order = (); - open (RF, "<$main::replacefile"); - while ($main::line = <RF>) { - next if ($main::line =~ /^\s*$main::configuration{'rfile_comment'}/); - chomp $main::line; - $main::line =~ s/\t+/\t/; - my ($rk, $rv) = split /\t/, $main::line; - if ($rk ne '') { - push @main::repl_order, $rk; - $main::repl_key{$rk} = "$main::configuration{'repl_step'}$repl_cnt"; - $main::repl_val{"$main::configuration{'repl_step'}$repl_cnt"} = $rv; - $repl_cnt++; + for (my $rf_cnt = 0; $rf_cnt <= $#main::replacefiles; $rf_cnt++) { + open (RF, "<$main::replacefiles[$rf_cnt]"); + while ($main::line = <RF>) { + next if ($main::line =~ /^\s*$main::configuration{'rfile_comment'}/); + chomp $main::line; + $main::line =~ s/\t+/\t/; + my ($rk, $rv) = split /\t/, $main::line; + if ($rk ne '') { + push @main::repl_order, $rk; + $main::repl_key{$rk} = "$main::configuration{'repl_step'}$repl_cnt"; + $main::repl_val{"$main::configuration{'repl_step'}$repl_cnt"} = $rv; + $repl_cnt++; + } + } + close RF; + if (!$main::configuration{'multi_rfile'}) { + last; } } - close RF; } # Start processing diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md index f2fa8d96cf..526ec6889c 100644 --- a/support/texlab/CHANGELOG.md +++ b/support/texlab/CHANGELOG.md @@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [5.21.0] - 2024-10-26 + +### Added + +- Support starred variants in "Go to References" ([#1234](https://github.com/latex-lsp/texlab/issues/1234)) +- Add `texlab.latexindent.replacement` setting to allow passing a replacement flag to `latexindent` ([#1222](https://github.com/latex-lsp/texlab/issues/1222)) +- Don't require a label to show section numbers for document symbols ([#910](https://github.com/latex-lsp/texlab/issues/910)) +- Support navigating to files that are part of the `TEXINPUTS` similar to `BIBINPUTS` ([#1228](https://github.com/latex-lsp/texlab/discussions/1228)) + +### Fixed + +- Fix opening `untitled` documents ([#1242](https://github.com/latex-lsp/texlab/issues/1242)) +- Handle `\bibitem` when checking for undefined references ([#1171](https://github.com/latex-lsp/texlab/issues/1171)) +- Fix false-positive syntax error when using a command inside a `\label` ([#879](https://github.com/latex-lsp/texlab/issues/879)) + +## [5.20.0] - 2024-10-08 + +### Added + +- Add `texlab.inlayHints.maxLength` setting to allow limiting inlay hint text length ([#1212](https://github.com/latex-lsp/texlab/issues/1212)) +- Allow suppressing diagnostics using `% texlab: ignore` magic comments ([#1211](https://github.com/latex-lsp/texlab/pull/1211)) + +### Fixed + +- Fix enabling `texlab.build.useFileList` setting +- Make "Goto Definition" work correctly with starred commands ([#1197](https://github.com/latex-lsp/texlab/issues/1197)) + ## [5.19.0] - 2024-07-08 ### Added diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock index ead2473278..aca7dcd943 100644 --- a/support/texlab/Cargo.lock +++ b/support/texlab/Cargo.lock @@ -3,10 +3,10 @@ version = 3 [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" @@ -73,9 +73,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "autocfg" @@ -152,9 +152,9 @@ checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "bstr" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", "regex-automata", @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.8" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -254,9 +254,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.8" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -266,9 +266,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.8" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", @@ -559,15 +559,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fern" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" +checksum = "69ff9c9d5fb3e6da8ac2f77ab76fe7e8087d512ce095200f8f29ac5b656cf6dc" dependencies = [ "log", ] @@ -595,9 +595,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -649,9 +649,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -683,6 +683,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] name = "highlights" version = "0.0.0" dependencies = [ @@ -708,9 +714,9 @@ dependencies = [ [[package]] name = "human_name" -version = "2.0.3" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d40d3a11bc31949eb1d5070deb0cbb481bbd17d9423ecd3afdb3db5d81499b9" +checksum = "fbd70ad9620f3a33a270cedfa47114c9566660c28ff8d0b3772b5c8dc1dac085" dependencies = [ "compact_str", "crossbeam-utils", @@ -781,13 +787,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", + "hermit-abi 0.4.0", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -861,9 +867,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "line-index" @@ -884,9 +890,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -906,18 +912,18 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logos" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e31badd9de5131fdf4921f6473d457e3dd85b11b7f091ceb50e4df7c3eeb12a" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" dependencies = [ "beef", "fnv", @@ -930,18 +936,18 @@ dependencies = [ [[package]] name = "logos-derive" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" dependencies = [ "logos-codegen", ] [[package]] name = "lsp-server" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248f65b78f6db5d8e1b1604b4098a28b43d21a8eb1deeca22b1c421b276c7095" +checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9" dependencies = [ "crossbeam-channel", "log", @@ -985,11 +991,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1044,9 +1050,9 @@ dependencies = [ [[package]] name = "notify-debouncer-full" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f5dab59c348b9b50cf7f261960a20e389feb2713636399cd9082cd4b536154" +checksum = "fb7fd166739789c9ff169e654dc1501373db9d80a4c3f972817c8a4d7cf8f34e" dependencies = [ "crossbeam-channel", "file-id", @@ -1071,15 +1077,15 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.3", "libc", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" @@ -1135,9 +1141,9 @@ dependencies = [ [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" [[package]] name = "percent-encoding" @@ -1306,9 +1312,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -1318,9 +1324,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -1329,9 +1335,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rename" @@ -1347,13 +1353,12 @@ dependencies = [ [[package]] name = "rowan" -version = "0.15.15" +version = "0.15.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" +checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d" dependencies = [ "countme", "hashbrown", - "memoffset", "rustc-hash 1.1.0", "text-size", ] @@ -1372,9 +1377,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.4.0", "errno", @@ -1412,18 +1417,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -1432,11 +1437,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.119" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8eddb61f0697cc3989c5d64b452f5488e2b8a60fd7d5076a3045076ffef8cb0" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1534,14 +1540,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1557,7 +1564,7 @@ dependencies = [ [[package]] name = "texlab" -version = "5.19.0" +version = "5.21.0" dependencies = [ "anyhow", "base-db", @@ -1610,18 +1617,18 @@ checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -1674,9 +1681,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "titlecase" -version = "3.0.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb3223c7b6ee54ec8521af7b060ad616cb90a66d0b94d05af340de30cf02c514" +checksum = "e0e20e744fbec1913fa168f3ffbef64324bbcb152c6cda8394baa79fa5ec9142" dependencies = [ "regex", ] @@ -1712,9 +1719,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -1733,9 +1740,9 @@ checksum = "402bb19d8e03f1d1a7450e2bd613980869438e0666331be3e073089124aa1adc" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -1751,9 +1758,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "versions" -version = "6.3.0" +version = "6.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc28d1172a20e32754969ea1a873c2c6e68e36c449c6056aa3e2ee5fe69a794" +checksum = "f25d498b63d1fdb376b4250f39ab3a5ee8d103957346abacd911e2d8b612c139" dependencies = [ "itertools 0.13.0", "nom", @@ -1777,9 +1784,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1787,9 +1794,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -1802,9 +1809,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1812,9 +1819,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -1825,9 +1832,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" @@ -1885,7 +1892,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -1905,17 +1921,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -1926,9 +1943,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -1938,9 +1955,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -1950,9 +1967,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -1962,9 +1985,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -1974,9 +1997,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -1986,9 +2009,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -1998,6 +2021,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/support/texlab/Cargo.toml b/support/texlab/Cargo.toml index 3894cb649f..c898466e4e 100644 --- a/support/texlab/Cargo.toml +++ b/support/texlab/Cargo.toml @@ -3,13 +3,33 @@ members = ["crates/*"] resolver = "2" [workspace.package] +version = "5.21.0" license = "GPL-3.0" authors = [ "Eric Förster <eric.foerster@outlook.com>", "Patrick Förster <patrick.foerster@outlook.de>", ] edition = "2021" -rust-version = "1.75" +rust-version = "1.80" + +[workspace.dependencies] +anyhow = "1.0.90" +criterion = "0.5.1" +crossbeam-channel = "0.5.13" +expect-test = "1.5.0" +itertools = "0.13.0" +log = "0.4.22" +notify = "6.1.1" +once_cell = "1.20.2" +regex = "1.11.0" +rowan = "0.15.16" +rustc-hash = "2.0.0" +serde = { version = "1.0.210", features = ["derive"] } +serde_json = "1.0.132" +tempfile = "3.13.0" +titlecase = "3.3.0" +unicode-normalization = "0.1.24" +url = "2.5.2" [profile.release] lto = "thin" diff --git a/support/texlab/crates/base-db/Cargo.toml b/support/texlab/crates/base-db/Cargo.toml index 547ba2ad77..04fde63b56 100644 --- a/support/texlab/crates/base-db/Cargo.toml +++ b/support/texlab/crates/base-db/Cargo.toml @@ -10,20 +10,20 @@ rust-version.workspace = true bibtex-utils = { path = "../bibtex-utils" } dirs = "5.0.1" distro = { path = "../distro" } -itertools = "0.13.0" +itertools.workspace = true line-index = { path = "../line-index" } -log = "0.4.22" -notify = "6.0.1" -once_cell = "1.19.0" +log.workspace = true +notify.workspace = true +once_cell.workspace = true parser = { path = "../parser" } percent-encoding = "2.3.0" -regex = "1.10.5" -rowan = "0.15.15" -rustc-hash = "2.0.0" +regex.workspace = true +rowan.workspace = true +rustc-hash.workspace = true shellexpand = "3.1.0" syntax = { path = "../syntax" } -titlecase = "3.0.0" -url = "2.5.0" +titlecase.workspace = true +url.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/base-db/src/config.rs b/support/texlab/crates/base-db/src/config.rs index e4c827e61c..5774f2a0ec 100644 --- a/support/texlab/crates/base-db/src/config.rs +++ b/support/texlab/crates/base-db/src/config.rs @@ -68,6 +68,7 @@ pub enum Formatter { pub struct LatexIndentConfig { pub local: Option<String>, pub modify_line_breaks: bool, + pub replacement: Option<String>, } #[derive(Debug, Default)] @@ -80,6 +81,7 @@ pub struct SymbolConfig { pub struct InlayHintConfig { pub label_definitions: bool, pub label_references: bool, + pub max_length: Option<usize>, } #[derive(Debug)] @@ -140,6 +142,7 @@ impl Default for InlayHintConfig { Self { label_definitions: true, label_references: true, + max_length: None, } } } diff --git a/support/texlab/crates/base-db/src/deps/discover.rs b/support/texlab/crates/base-db/src/deps/discover.rs index cbcab4d8fb..3039d7b0f4 100644 --- a/support/texlab/crates/base-db/src/deps/discover.rs +++ b/support/texlab/crates/base-db/src/deps/discover.rs @@ -15,7 +15,7 @@ pub fn watch( ) { let roots = workspace .iter() - .map(|document| &document.dir) + .filter_map(|document| document.dir.as_ref()) .filter(|dir| dir.scheme() == "file") .unique() .map(|dir| ProjectRoot::walk_and_find(workspace, dir)); diff --git a/support/texlab/crates/base-db/src/deps/graph.rs b/support/texlab/crates/base-db/src/deps/graph.rs index 0d8252688d..aec5cea92b 100644 --- a/support/texlab/crates/base-db/src/deps/graph.rs +++ b/support/texlab/crates/base-db/src/deps/graph.rs @@ -55,7 +55,11 @@ impl Graph { start: start.uri.clone(), }; - let root = ProjectRoot::walk_and_find(workspace, &start.dir); + let Some(start_dir) = &start.dir else { + return graph; + }; + + let root = ProjectRoot::walk_and_find(workspace, start_dir); let mut stack = vec![(start, Rc::new(root))]; let mut visited = FxHashSet::default(); @@ -135,7 +139,7 @@ impl Graph { .as_deref() .and_then(|dir| Url::from_directory_path(dir).ok()); - let working_dir = working_dir.as_ref().unwrap_or(&start.source.dir); + let working_dir = working_dir.as_ref().or(start.source.dir.as_ref())?; let new_root = Arc::new(ProjectRoot::from_config(workspace, working_dir)); for target_uri in file_list diff --git a/support/texlab/crates/base-db/src/deps/root.rs b/support/texlab/crates/base-db/src/deps/root.rs index 03fd41a9a0..aa3969353d 100644 --- a/support/texlab/crates/base-db/src/deps/root.rs +++ b/support/texlab/crates/base-db/src/deps/root.rs @@ -45,7 +45,7 @@ impl ProjectRoot { pub fn from_tectonic(workspace: &Workspace, dir: &Url) -> Option<Self> { let exists = workspace .iter() - .filter(|document| document.dir == *dir) + .filter(|document| document.dir.as_ref() == Some(dir)) .any(|document| matches!(document.data, DocumentData::Tectonic)); if !exists { @@ -77,7 +77,7 @@ impl ProjectRoot { let config = workspace.config(); let rcfile = workspace .iter() - .filter(|document| document.dir == *dir) + .filter(|document| document.dir.as_ref() == Some(dir)) .find_map(|document| document.data.as_latexmkrc())?; let compile_dir = dir.clone(); @@ -121,7 +121,7 @@ impl ProjectRoot { pub fn from_rootfile(workspace: &Workspace, dir: &Url) -> Option<Self> { let exists = workspace .iter() - .filter(|document| document.dir == *dir) + .filter(|document| document.dir.as_ref() == Some(dir)) .any(|document| matches!(document.data, DocumentData::Root)); if !exists { diff --git a/support/texlab/crates/base-db/src/document.rs b/support/texlab/crates/base-db/src/document.rs index 6fdcf30c16..0b81fa2871 100644 --- a/support/texlab/crates/base-db/src/document.rs +++ b/support/texlab/crates/base-db/src/document.rs @@ -28,7 +28,7 @@ pub struct DocumentParams<'a> { #[derive(Clone)] pub struct Document { pub uri: Url, - pub dir: Url, + pub dir: Option<Url>, pub path: Option<PathBuf>, pub text: String, pub line_index: LineIndex, @@ -42,7 +42,7 @@ impl Document { pub fn parse(params: DocumentParams) -> Self { let DocumentParams { uri, text, .. } = params; - let dir = uri.join(".").unwrap(); + let dir = uri.join(".").ok(); let path = if uri.scheme() == "file" { uri.to_file_path().ok() diff --git a/support/texlab/crates/base-db/src/semantics/auxiliary.rs b/support/texlab/crates/base-db/src/semantics/auxiliary.rs index 8c9fe012e6..bb9a2c065c 100644 --- a/support/texlab/crates/base-db/src/semantics/auxiliary.rs +++ b/support/texlab/crates/base-db/src/semantics/auxiliary.rs @@ -5,6 +5,7 @@ use syntax::latex::{self, HasCurly}; #[derive(Debug, Clone, Default)] pub struct Semantics { pub label_numbers: FxHashMap<String, String>, + pub section_numbers: FxHashMap<String, String>, } impl Semantics { @@ -18,6 +19,9 @@ impl Semantics { if let Some(label_number) = latex::LabelNumber::cast(node.clone()) { self.process_label_number(&label_number); } + if let Some(toc_line) = latex::TocContentsLine::cast(node.clone()) { + self.process_toc_line(&toc_line); + } } fn process_label_number(&mut self, label_number: &latex::LabelNumber) -> Option<()> { @@ -40,4 +44,36 @@ impl Semantics { self.label_numbers.insert(name, text); Some(()) } + + fn process_toc_line(&mut self, toc_line: &latex::TocContentsLine) -> Option<()> { + let unit = toc_line.unit().and_then(|u| u.content_text())?.to_string(); + + if [ + "part", + "chapter", + "section", + "subsection", + "subsubsection", + "paragraph", + "subparagraph", + ] + .contains(&unit.as_str()) + { + let line = toc_line.line()?; + let name = line.syntax().children().find_map(|child| { + latex::Text::cast(child.clone())?; + Some(child) + })?; + let name = name.to_string(); + + let num_line = line + .syntax() + .children() + .find_map(|child| latex::TocNumberLine::cast(child.clone()))?; + let number = num_line.number()?; + let number = number.content_text()?.replace(['{', '}'], ""); + self.section_numbers.insert(name, number); + } + Some(()) + } } diff --git a/support/texlab/crates/base-db/src/semantics/tex.rs b/support/texlab/crates/base-db/src/semantics/tex.rs index a1301091d4..7d150fc4b3 100644 --- a/support/texlab/crates/base-db/src/semantics/tex.rs +++ b/support/texlab/crates/base-db/src/semantics/tex.rs @@ -37,6 +37,8 @@ pub struct Semantics { pub graphics_paths: FxHashSet<String>, pub can_be_root: bool, pub can_be_compiled: bool, + pub diagnostic_suppressions: Vec<TextRange>, + pub bibitems: FxHashSet<Span>, } impl Semantics { @@ -46,11 +48,15 @@ impl Semantics { latex::SyntaxElement::Node(node) => { self.process_node(conf, &node); } - latex::SyntaxElement::Token(token) => { - if token.kind() == latex::COMMAND_NAME { - self.commands.push(Span::command(&token)); + latex::SyntaxElement::Token(token) => match token.kind() { + latex::COMMAND_NAME => { + self.commands.push(Span::command(&token)); } - } + latex::COMMENT if token.text().contains("texlab: ignore") => { + self.diagnostic_suppressions.push(token.text_range()); + } + _ => {} + }, }; } @@ -80,6 +86,8 @@ impl Semantics { self.process_theorem_definition(theorem_def); } else if let Some(graphics_path) = latex::GraphicsPath::cast(node.clone()) { self.process_graphics_path(graphics_path); + } else if let Some(bibitem) = latex::BibItem::cast(node.clone()) { + self.process_bibitem(bibitem); } } @@ -329,6 +337,16 @@ impl Semantics { self.graphics_paths.insert(path.to_string()); } } + + fn process_bibitem(&mut self, bibitem: latex::BibItem) { + if let Some(name) = bibitem.name() { + if let Some(key) = name.key() { + self.bibitems.insert( + Span::from(&key) + ); + } + } + } } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)] diff --git a/support/texlab/crates/bibfmt/Cargo.toml b/support/texlab/crates/bibfmt/Cargo.toml index a712908d7d..c4931f87bb 100644 --- a/support/texlab/crates/bibfmt/Cargo.toml +++ b/support/texlab/crates/bibfmt/Cargo.toml @@ -7,7 +7,7 @@ edition.workspace = true rust-version.workspace = true [dependencies] -rowan = "0.15.15" +rowan.workspace = true syntax = { path = "../syntax" } line-index = { path = "../line-index" } @@ -15,5 +15,5 @@ line-index = { path = "../line-index" } doctest = false [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true parser = { path = "../parser" } diff --git a/support/texlab/crates/bibtex-utils/Cargo.toml b/support/texlab/crates/bibtex-utils/Cargo.toml index 88ba2d3a37..1271823eac 100644 --- a/support/texlab/crates/bibtex-utils/Cargo.toml +++ b/support/texlab/crates/bibtex-utils/Cargo.toml @@ -8,16 +8,16 @@ rust-version.workspace = true [dependencies] chrono = { version = "0.4.38", default-features = false, features = ["std"] } -human_name = "2.0.3" -itertools = "0.13.0" -rowan = "0.15.15" -rustc-hash = "2.0.0" +human_name = "2.0.4" +itertools.workspace = true +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } -unicode-normalization = "0.1.23" +unicode-normalization.workspace = true [lib] doctest = false [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true parser = { path = "../parser" } diff --git a/support/texlab/crates/citeproc/Cargo.toml b/support/texlab/crates/citeproc/Cargo.toml index c87ab14b0e..9ad0c82e56 100644 --- a/support/texlab/crates/citeproc/Cargo.toml +++ b/support/texlab/crates/citeproc/Cargo.toml @@ -10,17 +10,17 @@ rust-version.workspace = true bibtex-utils = { path = "../bibtex-utils" } base-db = { path = "../base-db" } isocountry = "0.3.2" -itertools = "0.13.0" -rowan = "0.15.15" -rustc-hash = "2.0.0" +itertools.workspace = true +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } -titlecase = "3.0.0" -unicode-normalization = "0.1.23" -url = "2.5.0" +titlecase.workspace = true +unicode-normalization.workspace = true +url.workspace = true [lib] doctest = false [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true parser = { path = "../parser" } diff --git a/support/texlab/crates/commands/Cargo.toml b/support/texlab/crates/commands/Cargo.toml index 6507efb3b8..b348ad2b87 100644 --- a/support/texlab/crates/commands/Cargo.toml +++ b/support/texlab/crates/commands/Cargo.toml @@ -7,22 +7,22 @@ edition.workspace = true rust-version.workspace = true [dependencies] -anyhow = "1.0.86" +anyhow.workspace = true base-db = { path = "../base-db" } -bstr = "1.9.1" -crossbeam-channel = "0.5.13" -itertools = "0.13.0" -libc = "0.2.155" -log = "0.4.22" -rowan = "0.15.15" -rustc-hash = "2.0.0" +bstr = "1.10.0" +crossbeam-channel.workspace = true +itertools.workspace = true +libc = "0.2.161" +log.workspace = true +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } -thiserror = "1.0.61" -url = "2.5.0" +thiserror = "1.0.64" +url.workspace = true [dev-dependencies] distro = { path = "../distro" } -expect-test = "1.5.0" +expect-test.workspace = true test-utils = { path = "../test-utils" } [lib] diff --git a/support/texlab/crates/commands/src/build.rs b/support/texlab/crates/commands/src/build.rs index 34d39f26e4..23a6e16b7b 100644 --- a/support/texlab/crates/commands/src/build.rs +++ b/support/texlab/crates/commands/src/build.rs @@ -47,6 +47,10 @@ impl BuildCommand { .next() .unwrap_or(document); + let Some(document_dir) = &document.dir else { + return Err(BuildError::NotLocal(document.uri.clone())); + }; + let Some(path) = document.path.as_deref().and_then(Path::to_str) else { return Err(BuildError::NotLocal(document.uri.clone())); }; @@ -55,7 +59,7 @@ impl BuildCommand { let program = config.program.clone(); let args = replace_placeholders(&config.args, &[('f', path)]); - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let root = ProjectRoot::walk_and_find(workspace, document_dir); let Ok(working_dir) = root.compile_dir.to_file_path() else { return Err(BuildError::NotLocal(document.uri.clone())); diff --git a/support/texlab/crates/commands/src/clean.rs b/support/texlab/crates/commands/src/clean.rs index d4ec6b24f4..e429d1afa2 100644 --- a/support/texlab/crates/commands/src/clean.rs +++ b/support/texlab/crates/commands/src/clean.rs @@ -21,7 +21,11 @@ impl CleanCommand { anyhow::bail!("document '{}' is not a local file", document.uri) }; - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let Some(document_dir) = &document.dir else { + anyhow::bail!("document '{}' is not a local file", document.uri) + }; + + let root = ProjectRoot::walk_and_find(workspace, document_dir); let flag = match target { CleanTarget::Auxiliary => "-c", diff --git a/support/texlab/crates/commands/src/fwd_search.rs b/support/texlab/crates/commands/src/fwd_search.rs index f3480ef3e2..8b6227d8c2 100644 --- a/support/texlab/crates/commands/src/fwd_search.rs +++ b/support/texlab/crates/commands/src/fwd_search.rs @@ -84,7 +84,11 @@ impl ForwardSearch { } fn find_pdf(workspace: &Workspace, document: &Document) -> Result<PathBuf, ForwardSearchError> { - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let Some(document_dir) = &document.dir else { + return Err(ForwardSearchError::NotLocal(document.uri.clone())); + }; + + let root = ProjectRoot::walk_and_find(workspace, document_dir); log::debug!("[FwdSearch] root={root:#?}"); diff --git a/support/texlab/crates/completion-data/Cargo.toml b/support/texlab/crates/completion-data/Cargo.toml index 6dbb7d4086..c06a4994c8 100644 --- a/support/texlab/crates/completion-data/Cargo.toml +++ b/support/texlab/crates/completion-data/Cargo.toml @@ -7,12 +7,12 @@ edition.workspace = true rust-version.workspace = true [dependencies] -flate2 = "1.0.30" -itertools = "0.13.0" -once_cell = "1.19.0" -rustc-hash = "2.0.0" -serde = { version = "1.0.203", features = ["derive"] } -serde_json = "1.0.119" +flate2 = "1.0.34" +itertools.workspace = true +once_cell.workspace = true +rustc-hash.workspace = true +serde.workspace = true +serde_json.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/completion/Cargo.toml b/support/texlab/crates/completion/Cargo.toml index f98f12260b..e31f254e1c 100644 --- a/support/texlab/crates/completion/Cargo.toml +++ b/support/texlab/crates/completion/Cargo.toml @@ -12,15 +12,15 @@ completion-data = { path = "../completion-data" } fuzzy-matcher = { version = "0.3.7", features = ["compact"] } line-index = { path = "../line-index" } rayon = "1.10.0" -rowan = "0.15.15" -rustc-hash = "2.0.0" +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } -url = "2.5.0" +url.workspace = true [dev-dependencies] -criterion = "0.5.1" +criterion.workspace = true distro = { path = "../distro" } -expect-test = "1.5.0" +expect-test.workspace = true test-utils = { path = "../test-utils" } parser = { path = "../parser" } diff --git a/support/texlab/crates/completion/src/providers/include.rs b/support/texlab/crates/completion/src/providers/include.rs index d0a042252f..f3deb3a108 100644 --- a/support/texlab/crates/completion/src/providers/include.rs +++ b/support/texlab/crates/completion/src/providers/include.rs @@ -118,7 +118,7 @@ fn current_dir( .next() .map_or(params.document, Clone::clone); - let root = ProjectRoot::walk_and_find(workspace, &parent.dir); + let root = ProjectRoot::walk_and_find(workspace, parent.dir.as_ref()?); let mut path = PathBuf::new(); if let Some(graphics_path) = graphics_path { diff --git a/support/texlab/crates/definition/Cargo.toml b/support/texlab/crates/definition/Cargo.toml index 254bea0314..20bf3ed5fc 100644 --- a/support/texlab/crates/definition/Cargo.toml +++ b/support/texlab/crates/definition/Cargo.toml @@ -8,12 +8,12 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } -rowan = "0.15.15" -rustc-hash = "2.0.0" +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } [dev-dependencies] -itertools = "0.13.0" +itertools.workspace = true test-utils = { path = "../test-utils" } [lib] diff --git a/support/texlab/crates/definition/src/command.rs b/support/texlab/crates/definition/src/command.rs index ea7ef8c2c2..4892dad257 100644 --- a/support/texlab/crates/definition/src/command.rs +++ b/support/texlab/crates/definition/src/command.rs @@ -27,7 +27,7 @@ pub(super) fn goto_definition(context: &mut DefinitionContext) -> Option<()> { .filter_map(|node| { process_old_definition(node.clone()).or_else(|| process_new_definition(node)) }) - .filter(|(_, command)| command.text() == name.text()) + .filter(|(_, command)| command.text() == name.text().trim_end_matches("*")) .map(|(target_range, command)| DefinitionResult { origin_selection_range, target: document, diff --git a/support/texlab/crates/diagnostics/Cargo.toml b/support/texlab/crates/diagnostics/Cargo.toml index 37e39280ad..51bf19c0a3 100644 --- a/support/texlab/crates/diagnostics/Cargo.toml +++ b/support/texlab/crates/diagnostics/Cargo.toml @@ -10,19 +10,19 @@ rust-version.workspace = true base-db = { path = "../base-db" } encoding_rs = "0.8.34" encoding_rs_io = "0.1.7" -itertools = "0.13.0" +itertools.workspace = true line-index = { path = "../line-index" } -log = "0.4.22" +log.workspace = true multimap = "0.10.0" -once_cell = "1.19.0" -regex = "1.10.5" -rowan = "0.15.15" -rustc-hash = "2.0.0" +once_cell.workspace = true +regex.workspace = true +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } -url = "2.5.0" +url.workspace = true [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true test-utils = { path = "../test-utils" } [lib] diff --git a/support/texlab/crates/diagnostics/src/chktex.rs b/support/texlab/crates/diagnostics/src/chktex.rs index a3f539440d..b7cd80d67b 100644 --- a/support/texlab/crates/diagnostics/src/chktex.rs +++ b/support/texlab/crates/diagnostics/src/chktex.rs @@ -36,7 +36,7 @@ impl Command { return None; } - let root = ProjectRoot::walk_and_find(workspace, &parent.dir); + let root = ProjectRoot::walk_and_find(workspace, parent.dir.as_ref()?); let working_dir = root.src_dir.to_file_path().ok()?; log::debug!("Calling ChkTeX from directory: {}", working_dir.display()); diff --git a/support/texlab/crates/diagnostics/src/citations.rs b/support/texlab/crates/diagnostics/src/citations.rs index 43d5f495d2..2678d7e456 100644 --- a/support/texlab/crates/diagnostics/src/citations.rs +++ b/support/texlab/crates/diagnostics/src/citations.rs @@ -18,13 +18,17 @@ pub fn detect_undefined_citations<'a>( ) -> Option<()> { let data = document.data.as_tex()?; + let bibitems: FxHashSet<&str> = data.semantics.bibitems.iter() + .map(|bib| bib.text.as_str()) + .collect(); + let entries: FxHashSet<&str> = Entry::find_all(project) .map(|(_, entry)| entry.name_text()) .collect(); for citation in &data.semantics.citations { let name = citation.name_text(); - if name != "*" && !entries.contains(name) { + if name != "*" && !entries.contains(name) && !bibitems.contains(name) { let diagnostic = Diagnostic::Tex(citation.name.range, TexError::UndefinedCitation); results .entry(document.uri.clone()) @@ -41,24 +45,38 @@ pub fn detect_unused_entries<'a>( document: &'a Document, results: &mut FxHashMap<Url, Vec<Diagnostic>>, ) -> Option<()> { - let data = document.data.as_bib()?; - - // If this is a huge bibliography, then don't bother checking for unused entries. - if data.semantics.entries.len() > MAX_UNUSED_ENTRIES { - return None; - } let citations: FxHashSet<&str> = Citation::find_all(project) .map(|(_, citation)| citation.name_text()) .collect(); - for entry in &data.semantics.entries { - if !citations.contains(entry.name.text.as_str()) { - let diagnostic = Diagnostic::Bib(entry.name.range, BibError::UnusedEntry); - results - .entry(document.uri.clone()) - .or_default() - .push(diagnostic); + if let Some(data) = document.data.as_bib() + { + // If this is a huge bibliography, then don't bother checking for unused entries. + if data.semantics.entries.len() > MAX_UNUSED_ENTRIES { + return None; + } + + for entry in &data.semantics.entries { + if !citations.contains(entry.name.text.as_str()) { + let diagnostic = Diagnostic::Bib(entry.name.range, BibError::UnusedEntry); + results + .entry(document.uri.clone()) + .or_default() + .push(diagnostic); + } + } + }; + + if let Some(tex_data) = document.data.as_tex(){ + for bibitem in &tex_data.semantics.bibitems { + if !citations.contains(bibitem.text.as_str()) { + let diagnostic = Diagnostic::Bib(bibitem.range, BibError::UnusedEntry); + results + .entry(document.uri.clone()) + .or_default() + .push(diagnostic); + } } } diff --git a/support/texlab/crates/diagnostics/src/manager.rs b/support/texlab/crates/diagnostics/src/manager.rs index 500dc99c13..2829286a17 100644 --- a/support/texlab/crates/diagnostics/src/manager.rs +++ b/support/texlab/crates/diagnostics/src/manager.rs @@ -1,5 +1,8 @@ -use base_db::{deps::Project, util::filter_regex_patterns, Document, Owner, Workspace}; +use base_db::{ + deps::Project, util::filter_regex_patterns, Document, DocumentData, Owner, Workspace, +}; use multimap::MultiMap; +use rowan::TextRange; use rustc_hash::{FxHashMap, FxHashSet}; use url::Url; @@ -16,7 +19,7 @@ pub struct Manager { impl Manager { /// Updates the syntax-based diagnostics for the given document. pub fn update_syntax(&mut self, workspace: &Workspace, document: &Document) { - if !Self::is_relevant(document) { + if !Self::is_relevant_document(document) { return; } @@ -76,7 +79,7 @@ impl Manager { for document in workspace .iter() - .filter(|document| Self::is_relevant(document)) + .filter(|document| Self::is_relevant_document(document)) { let project = Project::from_child(workspace, document); super::citations::detect_undefined_citations(&project, document, &mut results); @@ -87,28 +90,78 @@ impl Manager { super::labels::detect_duplicate_labels(workspace, &mut results); super::labels::detect_undefined_and_unused_labels(workspace, &mut results); - let config = &workspace.config().diagnostics; - - results.retain(|uri, _| workspace.lookup(uri).map_or(false, Self::is_relevant)); + results.retain(|uri, _| { + workspace + .lookup(uri) + .map_or(false, Self::is_relevant_document) + }); - for diagnostics in results.values_mut() { - diagnostics.retain(|diagnostic| { - filter_regex_patterns( - diagnostic.message(), - &config.allowed_patterns, - &config.ignored_patterns, - ) - }); + for (uri, diagnostics) in results.iter_mut() { + diagnostics + .retain_mut(|diagnostic| Self::filter_diagnostic(workspace, uri, diagnostic)); } results } - fn is_relevant(document: &Document) -> bool { + fn is_relevant_document(document: &Document) -> bool { match document.owner { Owner::Client => true, Owner::Server => true, Owner::Distro => false, } } + + fn filter_diagnostic(workspace: &Workspace, uri: &Url, diagnostic: &mut Diagnostic) -> bool { + let config = &workspace.config().diagnostics; + + if !filter_regex_patterns( + diagnostic.message(), + &config.allowed_patterns, + &config.ignored_patterns, + ) { + return false; + } + + let Some(document) = workspace.lookup(uri) else { + return false; + }; + + let Some(primary_range) = diagnostic.range(&document.line_index) else { + return false; + }; + + if Self::is_ignored(workspace, &document.uri, &primary_range) { + return false; + } + + let Some(additional_locations) = diagnostic.additional_locations_mut() else { + return true; + }; + + additional_locations.retain(|(uri, range)| !Self::is_ignored(workspace, uri, range)); + if additional_locations.is_empty() { + return false; + } + + true + } + + fn is_ignored(workspace: &Workspace, uri: &Url, diag_range: &TextRange) -> bool { + let Some(document) = workspace.lookup(uri) else { + return false; + }; + + let DocumentData::Tex(data) = &document.data else { + return false; + }; + + let diag_line_col = document.line_index.line_col(diag_range.start()); + + data.semantics + .diagnostic_suppressions + .iter() + .map(|r| document.line_index.line_col(r.start())) + .any(|r| r.line == diag_line_col.line || r.line + 1 == diag_line_col.line) + } } diff --git a/support/texlab/crates/diagnostics/src/tests.rs b/support/texlab/crates/diagnostics/src/tests.rs index 05ad67fc8b..ff5f53ec3e 100644 --- a/support/texlab/crates/diagnostics/src/tests.rs +++ b/support/texlab/crates/diagnostics/src/tests.rs @@ -284,6 +284,33 @@ fn test_citation_undefined() { } #[test] +fn test_citation_undefined_ignore() { + check( + r#" +%! main.tex +% texlab: ignore +\cite{foo} +"#, + expect![[r#" + [] + "#]], + ) +} + +#[test] +fn test_citation_undefined_ignore_single_line() { + check( + r#" +%! main.tex +\cite{foo} % texlab: ignore +"#, + expect![[r#" + [] + "#]], + ) +} + +#[test] fn test_citation_unused() { check( r#" @@ -306,3 +333,46 @@ fn test_citation_unused() { "#]], ) } + +#[test] +fn test_label_duplicate() { + check( + r#" +%! main.tex +\label{foo} + ^^^ +\label{foo} + ^^^ +\label{foo} % texlab: ignore + +\ref{foo} +"#, + expect![[r#" + [ + ( + "file:///texlab/main.tex", + [ + Tex( + 7..10, + DuplicateLabel( + ( + "file:///texlab/main.tex", + 19..22, + ), + ), + ), + Tex( + 19..22, + DuplicateLabel( + ( + "file:///texlab/main.tex", + 7..10, + ), + ), + ), + ], + ), + ] + "#]], + ) +} diff --git a/support/texlab/crates/diagnostics/src/types.rs b/support/texlab/crates/diagnostics/src/types.rs index 9cbbf8936f..9cc195863b 100644 --- a/support/texlab/crates/diagnostics/src/types.rs +++ b/support/texlab/crates/diagnostics/src/types.rs @@ -1,9 +1,9 @@ -use line_index::LineCol; +use line_index::{LineCol, LineIndex}; use rowan::TextRange; use syntax::BuildError; use url::Url; -#[derive(Debug, PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone)] pub enum TexError { UnexpectedRCurly, ExpectingRCurly, @@ -14,7 +14,28 @@ pub enum TexError { DuplicateLabel(Vec<(Url, TextRange)>), } -#[derive(Debug, PartialEq, Eq, Clone)] +impl std::fmt::Debug for TexError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::UnexpectedRCurly => write!(f, "UnexpectedRCurly"), + Self::ExpectingRCurly => write!(f, "ExpectingRCurly"), + Self::MismatchedEnvironment => write!(f, "MismatchedEnvironment"), + Self::UnusedLabel => write!(f, "UnusedLabel"), + Self::UndefinedLabel => write!(f, "UndefinedLabel"), + Self::UndefinedCitation => write!(f, "UndefinedCitation"), + Self::DuplicateLabel(locations) => { + let mut t = f.debug_tuple("DuplicateLabel"); + for (uri, range) in locations { + t.field(&(uri.as_str(), range)); + } + + t.finish() + } + } + } +} + +#[derive(PartialEq, Eq, Clone)] pub enum BibError { ExpectingLCurly, ExpectingKey, @@ -25,6 +46,27 @@ pub enum BibError { DuplicateEntry(Vec<(Url, TextRange)>), } +impl std::fmt::Debug for BibError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::ExpectingLCurly => write!(f, "ExpectingLCurly"), + Self::ExpectingKey => write!(f, "ExpectingKey"), + Self::ExpectingRCurly => write!(f, "ExpectingRCurly"), + Self::ExpectingEq => write!(f, "ExpectingEq"), + Self::ExpectingFieldValue => write!(f, "ExpectingFieldValue"), + Self::UnusedEntry => write!(f, "UnusedEntry"), + Self::DuplicateEntry(locations) => { + let mut t = f.debug_tuple("DuplicateEntry"); + for (uri, range) in locations { + t.field(&(uri.as_str(), range)); + } + + t.finish() + } + } + } +} + #[derive(Debug, PartialEq, Eq, Clone)] pub struct ChktexError { pub start: LineCol, @@ -74,4 +116,42 @@ impl Diagnostic { Diagnostic::Chktex(error) => &error.message, } } + + pub fn range(&self, line_index: &LineIndex) -> Option<TextRange> { + Some(match self { + Diagnostic::Tex(range, _) => *range, + Diagnostic::Bib(range, _) => *range, + Diagnostic::Build(range, _) => *range, + Diagnostic::Chktex(error) => { + let start = line_index.offset(error.start)?; + let end = line_index.offset(error.end)?; + TextRange::new(start, end) + } + }) + } + + pub fn additional_locations_mut(&mut self) -> Option<&mut Vec<(Url, TextRange)>> { + match self { + Diagnostic::Tex(_, err) => match err { + TexError::UnexpectedRCurly + | TexError::ExpectingRCurly + | TexError::MismatchedEnvironment + | TexError::UnusedLabel + | TexError::UndefinedLabel + | TexError::UndefinedCitation => None, + TexError::DuplicateLabel(locations) => Some(locations), + }, + Diagnostic::Bib(_, err) => match err { + BibError::ExpectingLCurly + | BibError::ExpectingKey + | BibError::ExpectingRCurly + | BibError::ExpectingEq + | BibError::ExpectingFieldValue + | BibError::UnusedEntry => None, + BibError::DuplicateEntry(locations) => Some(locations), + }, + Diagnostic::Chktex(_) => None, + Diagnostic::Build(_, _) => None, + } + } } diff --git a/support/texlab/crates/distro/Cargo.toml b/support/texlab/crates/distro/Cargo.toml index c81288e86e..de89de935f 100644 --- a/support/texlab/crates/distro/Cargo.toml +++ b/support/texlab/crates/distro/Cargo.toml @@ -7,8 +7,8 @@ edition.workspace = true rust-version.workspace = true [dependencies] -anyhow = "1.0.86" -rustc-hash = "2.0.0" +anyhow.workspace = true +rustc-hash.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/distro/src/lib.rs b/support/texlab/crates/distro/src/lib.rs index 5c0dbe51fb..cf1420baa9 100644 --- a/support/texlab/crates/distro/src/lib.rs +++ b/support/texlab/crates/distro/src/lib.rs @@ -4,7 +4,10 @@ mod language; mod miktex; mod texlive; -use std::process::{Command, Stdio}; +use std::{ + env, + process::{Command, Stdio}, +}; use anyhow::Result; @@ -70,8 +73,14 @@ impl Distro { DistroKind::Tectonic | DistroKind::Unknown => FileNameDB::default(), }; - if let Some(bibinputs) = std::env::var_os("BIBINPUTS") { - for dir in std::env::split_paths(&bibinputs) { + Self::read_env_dir(&mut file_name_db, "TEXINPUTS"); + Self::read_env_dir(&mut file_name_db, "BIBINPUTS"); + Ok(Self { kind, file_name_db }) + } + + fn read_env_dir(file_name_db: &mut FileNameDB, env_var: &str) { + if let Some(paths) = env::var_os(env_var) { + for dir in env::split_paths(&paths) { if let Ok(entries) = std::fs::read_dir(dir) { for file in entries .flatten() @@ -83,7 +92,5 @@ impl Distro { } } } - - Ok(Self { kind, file_name_db }) } } diff --git a/support/texlab/crates/folding/Cargo.toml b/support/texlab/crates/folding/Cargo.toml index 684ddeb1b9..862f2301d1 100644 --- a/support/texlab/crates/folding/Cargo.toml +++ b/support/texlab/crates/folding/Cargo.toml @@ -8,11 +8,11 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } -rowan = "0.15.15" +rowan.workspace = true syntax = { path = "../syntax" } [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true test-utils = { path = "../test-utils" } [lib] diff --git a/support/texlab/crates/highlights/Cargo.toml b/support/texlab/crates/highlights/Cargo.toml index 785c282e3a..d509c7f89f 100644 --- a/support/texlab/crates/highlights/Cargo.toml +++ b/support/texlab/crates/highlights/Cargo.toml @@ -8,10 +8,10 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } -rowan = "0.15.15" +rowan.workspace = true [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true test-utils = { path = "../test-utils" } [lib] diff --git a/support/texlab/crates/hover/Cargo.toml b/support/texlab/crates/hover/Cargo.toml index 946ed734fe..683da15e43 100644 --- a/support/texlab/crates/hover/Cargo.toml +++ b/support/texlab/crates/hover/Cargo.toml @@ -11,11 +11,11 @@ base-db = { path = "../base-db" } bibtex-utils = { path = "../bibtex-utils" } citeproc = { path = "../citeproc" } completion-data = { path = "../completion-data" } -rowan = "0.15.15" +rowan.workspace = true syntax = { path = "../syntax" } [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true test-utils = { path = "../test-utils" } [lib] diff --git a/support/texlab/crates/inlay-hints/Cargo.toml b/support/texlab/crates/inlay-hints/Cargo.toml index 94651ef4c7..07e0172de2 100644 --- a/support/texlab/crates/inlay-hints/Cargo.toml +++ b/support/texlab/crates/inlay-hints/Cargo.toml @@ -8,12 +8,12 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } -rowan = "0.15.15" -rustc-hash = "2.0.0" +rowan.workspace = true +rustc-hash.workspace = true [dev-dependencies] test-utils = { path = "../test-utils" } -expect-test = "1.5.0" +expect-test.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/ipc/Cargo.toml b/support/texlab/crates/ipc/Cargo.toml index 92afbba876..c00b98ff12 100644 --- a/support/texlab/crates/ipc/Cargo.toml +++ b/support/texlab/crates/ipc/Cargo.toml @@ -7,15 +7,15 @@ edition.workspace = true rust-version.workspace = true [dependencies] -crossbeam-channel = "0.5.13" -serde = "1.0.203" -serde_json = "1.0.119" -log = "0.4.22" +crossbeam-channel.workspace = true +serde.workspace = true +serde_json.workspace = true +log.workspace = true uds_windows = "1.1.0" [lib] doctest = false [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true parser = { path = "../parser" } diff --git a/support/texlab/crates/line-index/Cargo.toml b/support/texlab/crates/line-index/Cargo.toml index 58e2fa9e16..3b385ca2bf 100644 --- a/support/texlab/crates/line-index/Cargo.toml +++ b/support/texlab/crates/line-index/Cargo.toml @@ -7,7 +7,7 @@ edition.workspace = true rust-version.workspace = true [dependencies] -rustc-hash = "2.0.0" +rustc-hash.workspace = true text-size = "1.1.1" [lib] diff --git a/support/texlab/crates/links/Cargo.toml b/support/texlab/crates/links/Cargo.toml index 74378483a9..f36edf1e20 100644 --- a/support/texlab/crates/links/Cargo.toml +++ b/support/texlab/crates/links/Cargo.toml @@ -11,7 +11,7 @@ base-db = { path = "../base-db" } [dev-dependencies] test-utils = { path = "../test-utils" } -expect-test = "1.5.0" +expect-test.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/parser/Cargo.toml b/support/texlab/crates/parser/Cargo.toml index 2faadcb262..e1edb782c5 100644 --- a/support/texlab/crates/parser/Cargo.toml +++ b/support/texlab/crates/parser/Cargo.toml @@ -7,19 +7,19 @@ edition.workspace = true rust-version.workspace = true [dependencies] -log = "0.4.22" -logos = "0.14.0" -once_cell = "1.19.0" -pathdiff = "0.2.1" -regex = "1.10.5" -rowan = "0.15.15" -rustc-hash = "2.0.0" +log.workspace = true +logos = "0.14.2" +once_cell.workspace = true +pathdiff = "0.2.2" +regex.workspace = true +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } -tempfile = "3.10.1" -versions = "6.3.0" +tempfile.workspace = true +versions = "6.3.2" [dev-dependencies] -expect-test = "1.5.0" +expect-test.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/parser/src/latex.rs b/support/texlab/crates/parser/src/latex.rs index 669ba82f99..8379d9c5ca 100644 --- a/support/texlab/crates/parser/src/latex.rs +++ b/support/texlab/crates/parser/src/latex.rs @@ -158,6 +158,9 @@ impl<'a> Parser<'a> { CommandName::EndBlockComment => self.generic_command(), CommandName::VerbatimBlock => self.verbatim_block(), CommandName::GraphicsPath => self.graphics_path(), + CommandName::BibItem => self.bibitem(), + CommandName::TocContentsLine => self.toc_contents_line(), + CommandName::TocNumberLine => self.toc_number_line(), }, } } @@ -862,7 +865,20 @@ impl<'a> Parser<'a> { } if self.lexer.peek() == Some(Token::LCurly) { - self.curly_group_word(); + self.builder.start_node(CURLY_GROUP_WORD.into()); + self.eat(); + self.trivia(); + + if self.peek() == Some(Token::Word) || self.peek() == Some(Token::Pipe) { + self.key(); + } + + if let Some(Token::CommandName(_)) = self.peek() { + self.content(ParserContext::default()); + } + + self.expect(Token::RCurly); + self.builder.finish_node(); } self.builder.finish_node(); @@ -1235,6 +1251,50 @@ impl<'a> Parser<'a> { } } } + + fn bibitem(&mut self) { + self.builder.start_node(BIBITEM.into()); + self.eat(); + self.trivia(); + + if self.lexer.peek() == Some(Token::LCurly) { + self.curly_group_word(); + } + + self.builder.finish_node(); + } + + fn toc_contents_line(&mut self) { + self.builder.start_node(TOC_CONTENTS_LINE.into()); + self.eat(); + self.trivia(); + + if self.lexer.peek() == Some(Token::LCurly) { + self.curly_group(); + } + + if self.lexer.peek() == Some(Token::LCurly) { + self.curly_group(); + } + + if self.lexer.peek() == Some(Token::LCurly) { + self.curly_group(); + } + + self.builder.finish_node(); + } + + fn toc_number_line(&mut self) { + self.builder.start_node(TOC_NUMBER_LINE.into()); + self.eat(); + self.trivia(); + + if self.lexer.peek() == Some(Token::LCurly) { + self.curly_group(); + } + + self.builder.finish_node(); + } } pub fn parse_latex(text: &str, config: &SyntaxConfig) -> GreenNode { diff --git a/support/texlab/crates/parser/src/latex/lexer.rs b/support/texlab/crates/parser/src/latex/lexer.rs index 47a6c43b06..19d5ddade5 100644 --- a/support/texlab/crates/parser/src/latex/lexer.rs +++ b/support/texlab/crates/parser/src/latex/lexer.rs @@ -27,7 +27,7 @@ impl<'a> Lexer<'a> { pub fn eat(&mut self) -> Option<(SyntaxKind, &'a str)> { let (kind, text) = self.tokens.pop()?; let kind = match kind { - Token::LineBreak => SyntaxKind::LINE_BREAK, + Token::LineBreak => SyntaxKind::WHITESPACE, Token::Whitespace => SyntaxKind::WHITESPACE, Token::LineComment => SyntaxKind::COMMENT, Token::LCurly => SyntaxKind::L_CURLY, diff --git a/support/texlab/crates/parser/src/latex/lexer/commands.rs b/support/texlab/crates/parser/src/latex/lexer/commands.rs index 4d1a7ca320..3f8b6e36ed 100644 --- a/support/texlab/crates/parser/src/latex/lexer/commands.rs +++ b/support/texlab/crates/parser/src/latex/lexer/commands.rs @@ -96,6 +96,9 @@ pub fn classify(name: &str, config: &SyntaxConfig) -> CommandName { "iffalse" => CommandName::BeginBlockComment, "fi" => CommandName::EndBlockComment, "verb" => CommandName::VerbatimBlock, + "bibitem" => CommandName::BibItem, + "contentsline" => CommandName::TocContentsLine, + "numberline" => CommandName::TocNumberLine, _ if config.citation_commands.contains(name) => CommandName::Citation, _ if config.label_definition_commands.contains(name) => CommandName::LabelDefinition, diff --git a/support/texlab/crates/parser/src/latex/lexer/types.rs b/support/texlab/crates/parser/src/latex/lexer/types.rs index 85e542792b..796378f671 100644 --- a/support/texlab/crates/parser/src/latex/lexer/types.rs +++ b/support/texlab/crates/parser/src/latex/lexer/types.rs @@ -95,6 +95,9 @@ pub enum CommandName { BeginBlockComment, EndBlockComment, VerbatimBlock, + BibItem, + TocContentsLine, + TocNumberLine, } #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)] diff --git a/support/texlab/crates/parser/src/latex/tests.rs b/support/texlab/crates/parser/src/latex/tests.rs index 2c9dc9335f..623c9329fb 100644 --- a/support/texlab/crates/parser/src/latex/tests.rs +++ b/support/texlab/crates/parser/src/latex/tests.rs @@ -24,24 +24,24 @@ Baz"#, PREAMBLE@0..48 TEXT@0..4 WORD@0..3 "Foo" - LINE_BREAK@3..4 "\n" + WHITESPACE@3..4 "\n" BLOCK_COMMENT@4..22 COMMAND_NAME@4..12 "\\iffalse" - LINE_BREAK@12..13 "\n" + WHITESPACE@12..13 "\n" WORD@13..18 "Test1" - LINE_BREAK@18..19 "\n" + WHITESPACE@18..19 "\n" COMMAND_NAME@19..22 "\\fi" - LINE_BREAK@22..23 "\n" + WHITESPACE@22..23 "\n" TEXT@23..27 WORD@23..26 "Bar" - LINE_BREAK@26..27 "\n" + WHITESPACE@26..27 "\n" BLOCK_COMMENT@27..44 COMMAND_NAME@27..35 "\\iffalse" - LINE_BREAK@35..36 "\n" + WHITESPACE@35..36 "\n" COMMAND_NAME@36..40 "\\fii" - LINE_BREAK@40..41 "\n" + WHITESPACE@40..41 "\n" COMMAND_NAME@41..44 "\\fi" - LINE_BREAK@44..45 "\n" + WHITESPACE@44..45 "\n" TEXT@45..48 WORD@45..48 "Baz" @@ -776,7 +776,7 @@ fn test_environment_asymptote() { KEY@7..10 WORD@7..10 "asy" R_CURLY@10..11 "}" - LINE_BREAK@11..12 "\n" + WHITESPACE@11..12 "\n" WHITESPACE@12..16 " " TEXT@16..22 WORD@16..22 "printf" @@ -793,7 +793,7 @@ fn test_environment_asymptote() { R_PAREN@38..39 ")" TEXT@39..41 WORD@39..40 ";" - LINE_BREAK@40..41 "\n" + WHITESPACE@40..41 "\n" END@41..50 COMMAND_NAME@41..45 "\\end" CURLY_GROUP_WORD@45..50 @@ -1289,7 +1289,7 @@ fn test_acronym_package() { WHITESPACE@26..27 " " WORD@27..33 "Second" R_CURLY@33..34 "}" - LINE_BREAK@34..35 "\n" + WHITESPACE@34..35 "\n" "#]], ); @@ -2384,7 +2384,7 @@ fn test_issue_568() { WHITESPACE@15..16 " " WORD@16..34 "scripts/test.ipynb" R_CURLY@34..35 "}" - LINE_BREAK@35..36 "\n" + WHITESPACE@35..36 "\n" LABEL_DEFINITION@36..51 COMMAND_NAME@36..42 "\\label" CURLY_GROUP_WORD@42..51 @@ -2433,7 +2433,7 @@ fn test_issue_745() { KEY@15..22 WORD@15..22 "article" R_CURLY@22..23 "}" - LINE_BREAK@23..24 "\n" + WHITESPACE@23..24 "\n" PACKAGE_INCLUDE@24..50 COMMAND_NAME@24..35 "\\usepackage" CURLY_GROUP_WORD_LIST@35..50 @@ -2442,10 +2442,10 @@ fn test_issue_745() { WORD@36..46 "tabularray" R_CURLY@46..47 "}" WHITESPACE@47..48 " " - LINE_BREAK@48..50 "\n\n" + WHITESPACE@48..50 "\n\n" GENERIC_COMMAND@50..64 COMMAND_NAME@50..63 "\\ExplSyntaxOn" - LINE_BREAK@63..64 "\n" + WHITESPACE@63..64 "\n" ENVIRONMENT_DEFINITION@64..200 COMMAND_NAME@64..87 "\\NewDocumentEnvironment" CURLY_GROUP_WORD@87..96 @@ -2463,19 +2463,19 @@ fn test_issue_745() { TEXT@100..101 WORD@100..101 "m" R_CURLY@101..102 "}" - LINE_BREAK@102..103 "\n" + WHITESPACE@102..103 "\n" WHITESPACE@103..107 " " CURLY_GROUP@107..200 L_CURLY@107..108 "{" - LINE_BREAK@108..109 "\n" + WHITESPACE@108..109 "\n" WHITESPACE@109..113 " " GENERIC_COMMAND@113..194 COMMAND_NAME@113..119 "\\use:x" - LINE_BREAK@119..120 "\n" + WHITESPACE@119..120 "\n" WHITESPACE@120..124 " " CURLY_GROUP@124..194 L_CURLY@124..125 "{" - LINE_BREAK@125..126 "\n" + WHITESPACE@125..126 "\n" WHITESPACE@126..130 " " GENERIC_COMMAND@130..141 COMMAND_NAME@130..140 "\\exp_not:N" @@ -2488,7 +2488,7 @@ fn test_issue_745() { KEY@148..152 WORD@148..152 "tblr" R_CURLY@152..153 "}" - LINE_BREAK@153..154 "\n" + WHITESPACE@153..154 "\n" WHITESPACE@154..158 " " BRACK_GROUP@158..179 L_BRACK@158..159 "[" @@ -2500,24 +2500,24 @@ fn test_issue_745() { WORD@170..172 "#1" R_CURLY@172..173 "}" R_BRACK@173..174 "]" - LINE_BREAK@174..175 "\n" + WHITESPACE@174..175 "\n" WHITESPACE@175..179 " " CURLY_GROUP@179..188 L_CURLY@179..180 "{" TEXT@180..182 WORD@180..182 "#2" R_CURLY@182..183 "}" - LINE_BREAK@183..184 "\n" + WHITESPACE@183..184 "\n" WHITESPACE@184..188 " " R_CURLY@188..189 "}" - LINE_BREAK@189..190 "\n" + WHITESPACE@189..190 "\n" WHITESPACE@190..194 " " R_CURLY@194..195 "}" - LINE_BREAK@195..196 "\n" + WHITESPACE@195..196 "\n" WHITESPACE@196..200 " " CURLY_GROUP@200..223 L_CURLY@200..201 "{" - LINE_BREAK@201..202 "\n" + WHITESPACE@201..202 "\n" WHITESPACE@202..206 " " GENERIC_COMMAND@206..221 COMMAND_NAME@206..210 "\\end" @@ -2526,13 +2526,13 @@ fn test_issue_745() { TEXT@211..215 WORD@211..215 "tblr" R_CURLY@215..216 "}" - LINE_BREAK@216..217 "\n" + WHITESPACE@216..217 "\n" WHITESPACE@217..221 " " R_CURLY@221..222 "}" - LINE_BREAK@222..223 "\n" + WHITESPACE@222..223 "\n" GENERIC_COMMAND@223..239 COMMAND_NAME@223..237 "\\ExplSyntaxOff" - LINE_BREAK@237..239 "\n\n" + WHITESPACE@237..239 "\n\n" ENVIRONMENT@239..271 BEGIN@239..257 COMMAND_NAME@239..245 "\\begin" @@ -2541,7 +2541,7 @@ fn test_issue_745() { KEY@246..254 WORD@246..254 "document" R_CURLY@254..255 "}" - LINE_BREAK@255..257 "\n\n" + WHITESPACE@255..257 "\n\n" END@257..271 COMMAND_NAME@257..261 "\\end" CURLY_GROUP_WORD@261..271 @@ -2620,7 +2620,7 @@ This is an asdf undefined command KEY@15..22 WORD@15..22 "minimal" R_CURLY@22..23 "}" - LINE_BREAK@23..24 "\n" + WHITESPACE@23..24 "\n" ENVIRONMENT@24..135 BEGIN@24..41 COMMAND_NAME@24..30 "\\begin" @@ -2629,7 +2629,7 @@ This is an asdf undefined command KEY@31..39 WORD@31..39 "document" R_CURLY@39..40 "}" - LINE_BREAK@40..41 "\n" + WHITESPACE@40..41 "\n" TEXT@41..75 WORD@41..45 "This" WHITESPACE@45..46 " " @@ -2642,24 +2642,24 @@ This is an asdf undefined command WORD@57..66 "undefined" WHITESPACE@66..67 " " WORD@67..74 "command" - LINE_BREAK@74..75 "\n" + WHITESPACE@74..75 "\n" BLOCK_COMMENT@75..120 COMMAND_NAME@75..83 "\\iffalse" - LINE_BREAK@83..84 "\n" + WHITESPACE@83..84 "\n" WHITESPACE@84..86 " " BLOCK_COMMENT@86..97 COMMAND_NAME@86..94 "\\iffalse" COMMAND_NAME@94..97 "\\fi" - LINE_BREAK@97..98 "\n" + WHITESPACE@97..98 "\n" WHITESPACE@98..100 " " COMMAND_NAME@100..104 "\\end" L_CURLY@104..105 "{" WORD@105..114 "enumerate" R_CURLY@114..115 "}" WHITESPACE@115..116 " " - LINE_BREAK@116..117 "\n" + WHITESPACE@116..117 "\n" COMMAND_NAME@117..120 "\\fi" - LINE_BREAK@120..121 "\n" + WHITESPACE@120..121 "\n" END@121..135 COMMAND_NAME@121..125 "\\end" CURLY_GROUP_WORD@125..135 @@ -2688,7 +2688,7 @@ fn test_issue_857() { CURLY_GROUP@14..17 L_CURLY@14..15 "{" R_CURLY@15..16 "}" - LINE_BREAK@16..17 "\n" + WHITESPACE@16..17 "\n" NEW_COMMAND_DEFINITION@17..38 COMMAND_NAME@17..28 "\\newcommand" CURLY_GROUP_COMMAND@28..35 @@ -2698,7 +2698,7 @@ fn test_issue_857() { CURLY_GROUP@35..38 L_CURLY@35..36 "{" R_CURLY@36..37 "}" - LINE_BREAK@37..38 "\n" + WHITESPACE@37..38 "\n" NEW_COMMAND_DEFINITION@38..49 COMMAND_NAME@38..49 "\\newcommand" GENERIC_COMMAND@49..55 @@ -2768,31 +2768,31 @@ fn test_issue_919() { KEY@15..22 WORD@15..22 "article" R_CURLY@22..23 "}" - LINE_BREAK@23..25 "\n\n" + WHITESPACE@23..25 "\n\n" PACKAGE_INCLUDE@25..173 COMMAND_NAME@25..36 "\\usepackage" CURLY_GROUP_WORD_LIST@36..173 L_CURLY@36..37 "{" - LINE_BREAK@37..38 "\n" + WHITESPACE@37..38 "\n" WHITESPACE@38..42 " " KEY@42..48 WORD@42..48 "lipsum" COMMA@48..49 "," WHITESPACE@49..50 " " COMMENT@50..70 "% provides blindtext" - LINE_BREAK@70..71 "\n" + WHITESPACE@70..71 "\n" WHITESPACE@71..75 " " KEY@75..83 WORD@75..83 "booktabs" COMMA@83..84 "," WHITESPACE@84..85 " " COMMENT@85..110 "% better rules for ta ..." - LINE_BREAK@110..111 "\n" + WHITESPACE@110..111 "\n" WHITESPACE@111..115 " " COMMENT@115..169 "%xcolor % easily defi ..." - LINE_BREAK@169..170 "\n" + WHITESPACE@169..170 "\n" R_CURLY@170..171 "}" - LINE_BREAK@171..173 "\n\n" + WHITESPACE@171..173 "\n\n" ENVIRONMENT@173..217 BEGIN@173..194 COMMAND_NAME@173..179 "\\begin" @@ -2801,11 +2801,11 @@ fn test_issue_919() { KEY@180..188 WORD@180..188 "document" R_CURLY@188..189 "}" - LINE_BREAK@189..190 "\n" + WHITESPACE@189..190 "\n" WHITESPACE@190..194 " " GENERIC_COMMAND@194..202 COMMAND_NAME@194..201 "\\lipsum" - LINE_BREAK@201..202 "\n" + WHITESPACE@201..202 "\n" END@202..217 COMMAND_NAME@202..206 "\\end" CURLY_GROUP_WORD@206..217 @@ -2813,7 +2813,7 @@ fn test_issue_919() { KEY@207..215 WORD@207..215 "document" R_CURLY@215..216 "}" - LINE_BREAK@216..217 "\n" + WHITESPACE@216..217 "\n" "#]], ); @@ -2853,7 +2853,7 @@ world}"#, L_CURLY@6..7 "{" KEY@7..13 WORD@7..12 "hello" - LINE_BREAK@12..13 "\n" + WHITESPACE@12..13 "\n" TEXT@13..18 WORD@13..18 "world" ERROR@18..19 @@ -3150,12 +3150,12 @@ Section 2"#, WHITESPACE@16..17 " " WORD@17..18 "1" R_CURLY@18..19 "}" - LINE_BREAK@19..20 "\n" + WHITESPACE@19..20 "\n" TEXT@20..31 WORD@20..27 "Section" WHITESPACE@27..28 " " WORD@28..29 "1" - LINE_BREAK@29..31 "\n\n" + WHITESPACE@29..31 "\n\n" PARAGRAPH@31..68 COMMAND_NAME@31..41 "\\paragraph" CURLY_GROUP@41..55 @@ -3165,12 +3165,12 @@ Section 2"#, WHITESPACE@51..52 " " WORD@52..53 "1" R_CURLY@53..54 "}" - LINE_BREAK@54..55 "\n" + WHITESPACE@54..55 "\n" TEXT@55..68 WORD@55..64 "Paragraph" WHITESPACE@64..65 " " WORD@65..66 "1" - LINE_BREAK@66..68 "\n\n" + WHITESPACE@66..68 "\n\n" PARAGRAPH@68..105 COMMAND_NAME@68..78 "\\paragraph" CURLY_GROUP@78..92 @@ -3180,12 +3180,12 @@ Section 2"#, WHITESPACE@88..89 " " WORD@89..90 "2" R_CURLY@90..91 "}" - LINE_BREAK@91..92 "\n" + WHITESPACE@91..92 "\n" TEXT@92..105 WORD@92..101 "Paragraph" WHITESPACE@101..102 " " WORD@102..103 "2" - LINE_BREAK@103..105 "\n\n" + WHITESPACE@103..105 "\n\n" SECTION@105..134 COMMAND_NAME@105..113 "\\section" CURLY_GROUP@113..125 @@ -3195,7 +3195,7 @@ Section 2"#, WHITESPACE@121..122 " " WORD@122..123 "2" R_CURLY@123..124 "}" - LINE_BREAK@124..125 "\n" + WHITESPACE@124..125 "\n" TEXT@125..134 WORD@125..132 "Section" WHITESPACE@132..133 " " diff --git a/support/texlab/crates/references/Cargo.toml b/support/texlab/crates/references/Cargo.toml index 8d4e3a6936..3b3abf0ecc 100644 --- a/support/texlab/crates/references/Cargo.toml +++ b/support/texlab/crates/references/Cargo.toml @@ -8,8 +8,8 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } -rowan = "0.15.15" -rustc-hash = "2.0.0" +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } [dev-dependencies] diff --git a/support/texlab/crates/references/src/command.rs b/support/texlab/crates/references/src/command.rs index f4504641f2..cf5849a136 100644 --- a/support/texlab/crates/references/src/command.rs +++ b/support/texlab/crates/references/src/command.rs @@ -32,7 +32,9 @@ pub(super) fn find_all(context: &mut ReferenceContext) -> Option<()> { .collect(); for command in &data.semantics.commands { - if command.text == token.text()[1..] { + let command_text = command.text.trim_end_matches('*'); + let token_text = token.text()[1..].trim_end_matches('*'); + if command_text == token_text { let kind = if defs.contains(command) { ReferenceKind::Definition } else { diff --git a/support/texlab/crates/references/src/tests.rs b/support/texlab/crates/references/src/tests.rs index 845282afb0..7131480699 100644 --- a/support/texlab/crates/references/src/tests.rs +++ b/support/texlab/crates/references/src/tests.rs @@ -260,3 +260,43 @@ fn test_new_command_definition_include_decl() { true, ); } + +#[test] +fn test_new_command_definition_starred() { + check( + r#" +%! main.tex +\foo + ^^^ +\foo* + | + ^^^^ + +\NewDocumentCommand{\foo}{s m}{% + \IfBooleanTF{#1}{\textbf{#2}}{#2}% +} +"#, + false, + ); +} + +#[test] +fn test_new_command_definition_starred_include_decl() { + check( + r#" +%! main.tex +\foo + ^^^ +\foo* + | + ^^^^ + +\NewDocumentCommand{\foo}{s m}{% + ^^^ + \IfBooleanTF{#1}{\textbf{#2}}{#2}% +} + +"#, + true, + ); +} diff --git a/support/texlab/crates/rename/Cargo.toml b/support/texlab/crates/rename/Cargo.toml index 592bafb474..bbc3487ccf 100644 --- a/support/texlab/crates/rename/Cargo.toml +++ b/support/texlab/crates/rename/Cargo.toml @@ -8,8 +8,8 @@ rust-version.workspace = true [dependencies] base-db = { path = "../base-db" } -rowan = "0.15.15" -rustc-hash = "2.0.0" +rowan.workspace = true +rustc-hash.workspace = true syntax = { path = "../syntax" } [dev-dependencies] diff --git a/support/texlab/crates/symbols/Cargo.toml b/support/texlab/crates/symbols/Cargo.toml index c44f120153..3ebc88fa50 100644 --- a/support/texlab/crates/symbols/Cargo.toml +++ b/support/texlab/crates/symbols/Cargo.toml @@ -12,14 +12,14 @@ doctest = false [dependencies] base-db = { path = "../base-db" } distro = { path = "../distro" } -itertools = "0.13.0" +itertools.workspace = true line-index = { path = "../line-index" } -rowan = "0.15.15" +rowan.workspace = true syntax = { path = "../syntax" } -titlecase = "3.0.0" -url = "2.5.0" +titlecase.workspace = true +url.workspace = true [dev-dependencies] -regex = "1.10.5" +regex.workspace = true test-utils = { path = "../test-utils" } -expect-test = "1.5.0" +expect-test.workspace = true diff --git a/support/texlab/crates/symbols/src/document/tests.rs b/support/texlab/crates/symbols/src/document/tests.rs index 25450a6cc5..cf599529fb 100644 --- a/support/texlab/crates/symbols/src/document/tests.rs +++ b/support/texlab/crates/symbols/src/document/tests.rs @@ -281,44 +281,44 @@ fn test_section() { check( &fixture, expect![[r#" - [ - Symbol { - name: "Foo", - kind: Section, - label: None, - full_range: 43..56, - selection_range: 43..56, - children: [], - }, - Symbol { - name: "2 Bar", - kind: Section, - label: Some( - Span( - "sec:bar", - 71..86, + [ + Symbol { + name: "1 Foo", + kind: Section, + label: None, + full_range: 43..56, + selection_range: 43..56, + children: [], + }, + Symbol { + name: "2 Bar", + kind: Section, + label: Some( + Span( + "sec:bar", + 71..86, + ), ), - ), - full_range: 58..119, - selection_range: 71..86, - children: [ - Symbol { - name: "Baz", - kind: Section, - label: Some( - Span( - "sec:baz", - 104..119, + full_range: 58..119, + selection_range: 71..86, + children: [ + Symbol { + name: "Baz", + kind: Section, + label: Some( + Span( + "sec:baz", + 104..119, + ), ), - ), - full_range: 88..119, - selection_range: 104..119, - children: [], - }, - ], - }, - ] - "#]], + full_range: 88..119, + selection_range: 104..119, + children: [], + }, + ], + }, + ] + "#]], ); } diff --git a/support/texlab/crates/symbols/src/document/tex.rs b/support/texlab/crates/symbols/src/document/tex.rs index e0df9c85c1..734335ef0e 100644 --- a/support/texlab/crates/symbols/src/document/tex.rs +++ b/support/texlab/crates/symbols/src/document/tex.rs @@ -67,16 +67,14 @@ impl<'a> SymbolBuilder<'a> { let group_text = group.content_text()?; let kind = SymbolKind::Section; - let symbol = match self.find_label(section.syntax()) { - Some(label) => { - let name = match self.find_label_number(&label.text) { - Some(number) => format!("{number} {group_text}"), - None => group_text, - }; + let name = match self.find_section_number(&group_text) { + Some(number) => format!("{number} {group_text}"), + None => group_text, + }; - Symbol::new_label(name, kind, range, label) - } - None => Symbol::new_simple(group_text, kind, range, range), + let symbol = match self.find_label(section.syntax()) { + Some(label) => Symbol::new_label(name, kind, range, label), + None => Symbol::new_simple(name, kind, range, range) }; Some(symbol) @@ -247,6 +245,15 @@ impl<'a> SymbolBuilder<'a> { Some(Span { text, range }) } + fn find_section_number(&self, name: &str) -> Option<&str> { + self.project + .documents + .iter() + .filter_map(|document| document.data.as_aux()) + .find_map(|data| data.semantics.section_numbers.get(name)) + .map(String::as_str) + } + fn find_label_number(&self, name: &str) -> Option<&str> { self.project .documents diff --git a/support/texlab/crates/syntax/Cargo.toml b/support/texlab/crates/syntax/Cargo.toml index 14dfffe380..5ae82f8bc5 100644 --- a/support/texlab/crates/syntax/Cargo.toml +++ b/support/texlab/crates/syntax/Cargo.toml @@ -7,9 +7,9 @@ edition.workspace = true rust-version.workspace = true [dependencies] -itertools = "0.13.0" -rowan = "0.15.15" -rustc-hash = "2.0.0" +itertools.workspace = true +rowan.workspace = true +rustc-hash.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/syntax/src/latex/cst.rs b/support/texlab/crates/syntax/src/latex/cst.rs index f16d703162..580ef6af12 100644 --- a/support/texlab/crates/syntax/src/latex/cst.rs +++ b/support/texlab/crates/syntax/src/latex/cst.rs @@ -12,7 +12,7 @@ pub fn small_range(node: &dyn AstNode<Language = LatexLanguage>) -> TextRange { let start = full_range.start(); let mut token = node.syntax().last_token(); while let Some(current) = token { - if !matches!(current.kind(), LINE_BREAK | WHITESPACE | COMMENT) { + if !matches!(current.kind(), WHITESPACE | COMMENT) { return TextRange::new(start, current.text_range().end()); } token = current.prev_token(); @@ -233,7 +233,7 @@ impl Key { self.syntax() .children_with_tokens() .filter_map(|node| node.into_token()) - .filter(|node| !matches!(node.kind(), WHITESPACE | LINE_BREAK | COMMENT)) + .filter(|node| !matches!(node.kind(), WHITESPACE | COMMENT)) } } @@ -258,7 +258,7 @@ impl ToString for Key { .children_with_tokens() .filter_map(|node| node.into_token()) { - if matches!(token.kind(), WHITESPACE | LINE_BREAK | COMMENT) { + if matches!(token.kind(), WHITESPACE | COMMENT) { buf.push(' '); } else { buf.push_str(token.text()); @@ -750,3 +750,43 @@ impl GraphicsPath { self.syntax().descendants().filter_map(CurlyGroupWord::cast) } } + +cst_node!(BibItem, BIBITEM); + +impl BibItem { + pub fn command(&self) -> Option<SyntaxToken> { + self.syntax().first_token() + } + + pub fn name(&self) -> Option<CurlyGroupWord> { + self.syntax().children().find_map(CurlyGroupWord::cast) + } +} + +cst_node!(TocContentsLine, TOC_CONTENTS_LINE); + +impl TocContentsLine { + pub fn command(&self) -> Option<SyntaxToken> { + self.syntax().first_token() + } + + pub fn unit(&self) -> Option<CurlyGroup> { + self.syntax().children().find_map(CurlyGroup::cast) + } + + pub fn line(&self) -> Option<CurlyGroup> { + self.syntax().children().filter_map(CurlyGroup::cast).nth(1) + } +} + +cst_node!(TocNumberLine, TOC_NUMBER_LINE); + +impl TocNumberLine { + pub fn command(&self) -> Option<SyntaxToken> { + self.syntax().first_token() + } + + pub fn number(&self) -> Option<CurlyGroup> { + self.syntax().children().find_map(CurlyGroup::cast) + } +} diff --git a/support/texlab/crates/syntax/src/latex/kind.rs b/support/texlab/crates/syntax/src/latex/kind.rs index 8b649b1f31..f67201e003 100644 --- a/support/texlab/crates/syntax/src/latex/kind.rs +++ b/support/texlab/crates/syntax/src/latex/kind.rs @@ -4,7 +4,6 @@ pub enum SyntaxKind { ERROR = 0, - LINE_BREAK, WHITESPACE, COMMENT, VERBATIM, @@ -83,6 +82,9 @@ pub enum SyntaxKind { ENVIRONMENT_DEFINITION, GRAPHICS_PATH, BLOCK_COMMENT, + BIBITEM, + TOC_CONTENTS_LINE, + TOC_NUMBER_LINE, ROOT, } diff --git a/support/texlab/crates/test-utils/Cargo.toml b/support/texlab/crates/test-utils/Cargo.toml index b08d9cc09f..581be2e6a2 100644 --- a/support/texlab/crates/test-utils/Cargo.toml +++ b/support/texlab/crates/test-utils/Cargo.toml @@ -10,8 +10,8 @@ rust-version.workspace = true base-db = { path = "../base-db" } distro = { path = "../distro" } line-index = { path = "../line-index" } -rowan = "0.15.15" -url = "2.5.0" +rowan.workspace = true +url.workspace = true [lib] doctest = false diff --git a/support/texlab/crates/texlab/Cargo.toml b/support/texlab/crates/texlab/Cargo.toml index f4cb2d3283..5f73cbf024 100644 --- a/support/texlab/crates/texlab/Cargo.toml +++ b/support/texlab/crates/texlab/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "texlab" description = "LaTeX Language Server" -version = "5.19.0" +version.workspace = true license.workspace = true readme = "README.md" authors.workspace = true @@ -22,19 +22,19 @@ test = false doctest = false [dependencies] -anyhow = "1.0.86" +anyhow.workspace = true base-db = { path = "../base-db" } bibfmt = { path = "../bibfmt" } citeproc = { path = "../citeproc" } -clap = { version = "4.5.8", features = ["derive"] } +clap = { version = "4.5.20", features = ["derive"] } commands = { path = "../commands" } completion = { path = "../completion" } completion-data = { path = "../completion-data" } -crossbeam-channel = "0.5.13" +crossbeam-channel.workspace = true definition = { path = "../definition" } diagnostics = { path = "../diagnostics" } distro = { path = "../distro" } -fern = "0.6.2" +fern = "0.7.0" folding = { path = "../folding" } highlights = { path = "../highlights" } hover = { path = "../hover" } @@ -42,29 +42,29 @@ inlay-hints = { path = "../inlay-hints" } ipc = { path = "../ipc" } line-index = { path = "../line-index" } links = { path = "../links" } -log = "0.4.22" -lsp-server = "0.7.6" +log.workspace = true +lsp-server = "0.7.7" lsp-types = "0.95.1" -notify = "6.1.1" -notify-debouncer-full = "0.3.1" +notify.workspace = true +notify-debouncer-full = "0.3.2" parking_lot = "0.12.3" parser = { path = "../parser" } references = { path = "../references" } -regex = "1.10.5" +regex.workspace = true rename = { path = "../rename" } -rowan = "0.15.15" -rustc-hash = "2.0.0" -serde = "1.0.203" -serde_json = "1.0.119" +rowan.workspace = true +rustc-hash.workspace = true +serde.workspace = true +serde_json.workspace = true serde_regex = "1.1.0" serde_repr = "0.1.19" symbols = { path = "../symbols" } syntax = { path = "../syntax" } -tempfile = "3.10.1" +tempfile.workspace = true threadpool = "1.8.1" [dev-dependencies] -criterion = { version = "0.5.1" } +criterion.workspace = true [[bench]] name = "bench_main" diff --git a/support/texlab/crates/texlab/src/features/formatting/latexindent.rs b/support/texlab/crates/texlab/src/features/formatting/latexindent.rs index d3fffc2050..b956378ed5 100644 --- a/support/texlab/crates/texlab/src/features/formatting/latexindent.rs +++ b/support/texlab/crates/texlab/src/features/formatting/latexindent.rs @@ -16,7 +16,7 @@ pub fn format_with_latexindent( ) -> Option<Vec<lsp_types::TextEdit>> { let config = workspace.config(); let target_dir = tempdir().ok()?; - let root = ProjectRoot::walk_and_find(workspace, &document.dir); + let root = ProjectRoot::walk_and_find(workspace, document.dir.as_ref()?); let source_dir = root.src_dir.to_file_path().ok()?; let target_file = target_dir @@ -72,6 +72,15 @@ fn build_arguments(config: &LatexIndentConfig, target_file: &Path) -> Vec<String args.push("--modifylinebreaks".to_string()); } + match &config.replacement { + Some(replacement_flag) => { + if ["-r", "-rv", "-rr"].contains(& replacement_flag.as_str()) { + args.push(replacement_flag.clone()); + } + }, + None => {} + } + args.push(target_file.display().to_string()); args } diff --git a/support/texlab/crates/texlab/src/features/inlay_hint.rs b/support/texlab/crates/texlab/src/features/inlay_hint.rs index ddd8ff26d8..0689f07af0 100644 --- a/support/texlab/crates/texlab/src/features/inlay_hint.rs +++ b/support/texlab/crates/texlab/src/features/inlay_hint.rs @@ -7,10 +7,11 @@ pub fn find_all( params: lsp_types::InlayHintParams, ) -> Option<Vec<lsp_types::InlayHint>> { let params = from_proto::inlay_hint_params(workspace, params)?; + let line_index = ¶ms.feature.document.line_index; + let max_length = workspace.config().inlay_hints.max_length; let hints = inlay_hints::find_all(¶ms)? .into_iter() - .filter_map(|hint| to_proto::inlay_hint(hint, ¶ms.feature.document.line_index)) - .collect(); + .filter_map(|hint| to_proto::inlay_hint(hint, line_index, max_length)); - Some(hints) + Some(hints.collect()) } diff --git a/support/texlab/crates/texlab/src/server/options.rs b/support/texlab/crates/texlab/src/server/options.rs index f4853d7cb9..fcb8e1ec60 100644 --- a/support/texlab/crates/texlab/src/server/options.rs +++ b/support/texlab/crates/texlab/src/server/options.rs @@ -56,6 +56,7 @@ impl Default for LatexFormatter { pub struct LatexindentOptions { pub local: Option<String>, pub modify_line_breaks: bool, + pub replacement: Option<String>, } #[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)] @@ -104,6 +105,7 @@ pub struct DiagnosticsOptions { pub struct InlayHintOptions { pub label_definitions: Option<bool>, pub label_references: Option<bool>, + pub max_length: Option<usize>, } #[derive(Debug, Clone, Default, Serialize, Deserialize)] diff --git a/support/texlab/crates/texlab/src/util/from_proto.rs b/support/texlab/crates/texlab/src/util/from_proto.rs index b55e3cb0e3..928b3d6d61 100644 --- a/support/texlab/crates/texlab/src/util/from_proto.rs +++ b/support/texlab/crates/texlab/src/util/from_proto.rs @@ -282,6 +282,7 @@ pub fn config(value: Options) -> Config { config.formatting.latex_indent.local = value.latexindent.local; config.formatting.latex_indent.modify_line_breaks = value.latexindent.modify_line_breaks; + config.formatting.latex_indent.replacement = value.latexindent.replacement; config.synctex = value .forward_search @@ -305,6 +306,7 @@ pub fn config(value: Options) -> Config { config.inlay_hints.label_definitions = value.inlay_hints.label_definitions.unwrap_or(true); config.inlay_hints.label_references = value.inlay_hints.label_references.unwrap_or(true); + config.inlay_hints.max_length = value.inlay_hints.max_length; config.completion.matcher = match value.completion.matcher { CompletionMatcher::Fuzzy => base_db::MatchingAlgo::Skim, @@ -313,6 +315,8 @@ pub fn config(value: Options) -> Config { CompletionMatcher::PrefixIgnoreCase => base_db::MatchingAlgo::PrefixIgnoreCase, }; + config.syntax.use_file_list = value.build.use_file_list; + config .syntax .math_environments diff --git a/support/texlab/crates/texlab/src/util/to_proto.rs b/support/texlab/crates/texlab/src/util/to_proto.rs index d2c261c8fb..82d0132434 100644 --- a/support/texlab/crates/texlab/src/util/to_proto.rs +++ b/support/texlab/crates/texlab/src/util/to_proto.rs @@ -191,13 +191,25 @@ pub fn diagnostic( }) } -pub fn inlay_hint(hint: InlayHint, line_index: &LineIndex) -> Option<lsp_types::InlayHint> { +pub fn inlay_hint( + hint: InlayHint, + line_index: &LineIndex, + max_length: Option<usize>, +) -> Option<lsp_types::InlayHint> { let position = line_index.line_col_lsp(hint.offset)?; + let trim_text = |text: &mut String| match max_length { + Some(max_length) if text.len() > max_length => { + text.truncate(max_length); + text.push('…'); + } + _ => {} + }; + Some(match hint.data { InlayHintData::LabelDefinition(label) => { let number = label.number?; - let text = match &label.object { + let mut text = match &label.object { RenderedObject::Section { prefix, .. } => { format!("{} {}", prefix, number) } @@ -211,9 +223,11 @@ pub fn inlay_hint(hint: InlayHint, line_index: &LineIndex) -> Option<lsp_types:: RenderedObject::EnumItem => format!("Item {}", number), }; + trim_text(&mut text); + lsp_types::InlayHint { position, - label: lsp_types::InlayHintLabel::String(format!(" {text} ")), + label: lsp_types::InlayHintLabel::String(format!(" {text} ",)), kind: None, text_edits: None, tooltip: None, @@ -223,7 +237,8 @@ pub fn inlay_hint(hint: InlayHint, line_index: &LineIndex) -> Option<lsp_types:: } } InlayHintData::LabelReference(label) => { - let text = label.reference(); + let mut text = label.reference(); + trim_text(&mut text); lsp_types::InlayHint { position, diff --git a/support/texlab/texlab.1 b/support/texlab/texlab.1 index 852d37051e..27fabe2066 100644 --- a/support/texlab/texlab.1 +++ b/support/texlab/texlab.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.1. -.TH TEXLAB "1" "July 2024" "texlab 5.19.0" "User Commands" +.TH TEXLAB "1" "October 2024" "texlab 5.21.0" "User Commands" .SH NAME -texlab \- manual page for texlab 5.19.0 +texlab \- manual page for texlab 5.21.0 .SH SYNOPSIS .B texlab [\fI\,OPTIONS\/\fR] [\fI\,COMMAND\/\fR] diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf Binary files differindex 55922ca427..152ab2bac4 100644 --- a/support/texlab/texlab.pdf +++ b/support/texlab/texlab.pdf diff --git a/support/texlive/texlive-dummy/openSUSE/README.md b/support/texlive/texlive-dummy/openSUSE/README.md index dba2b75a5c..f110b08118 100644 --- a/support/texlive/texlive-dummy/openSUSE/README.md +++ b/support/texlive/texlive-dummy/openSUSE/README.md @@ -11,7 +11,7 @@ the installation path "/usr/local/texlive"). Install this package with: -`zypper in --allow-unsigned-rpm texlive-dummy-2024.9999-1.noarch.rpm` +`zypper in --allow-unsigned-rpm texlive-dummy-2024.9999-2.noarch.rpm` The GIT repository of the package is: @@ -21,4 +21,4 @@ Permission is granted to copy, distribute and/or modify this software under the terms of the LaTeX Project Public License (LPPL), version 1.3. The LPPL maintenance status of this software is "maintained". -Rolf Niepraschk, 2023/03/17 +Rolf Niepraschk, 2024/11/14 diff --git a/support/texplate/doc/texplate-manual.pdf b/support/texplate/doc/texplate-manual.pdf Binary files differindex feaac3226d..96d574ace6 100644 --- a/support/texplate/doc/texplate-manual.pdf +++ b/support/texplate/doc/texplate-manual.pdf diff --git a/support/texplate/doc/texplate-manual.tex b/support/texplate/doc/texplate-manual.tex index 4bd1c8ea43..1de47ab149 100644 --- a/support/texplate/doc/texplate-manual.tex +++ b/support/texplate/doc/texplate-manual.tex @@ -17,7 +17,7 @@ \newcommand{\shortopt}[1]{{\ttfamily-#1}} \newcommand{\longopt}[1]{{\ttfamily{-}{-}#1}} \newcommand{\macro}[1]{{\ttfamily\textbackslash#1}} -\newcommand{\texplateversion}{1.0.5} +\newcommand{\texplateversion}{1.0.6} \title{A gentle introduction to \texplate:\\ a document structure creation tool} \author{Island of \TeX} @@ -624,7 +624,15 @@ Happy \TeX ing with \texplate! \chapter*{Changelog} -\section*{1.0.5 (current)} +\section*{1.0.6 (current)} + +\subsection*{Fixed} + +\begin{itemize} +\item Application version is now retrieved from the manifest (regression fix). +\end{itemize} + +\section*{1.0.5 (2024-08-01)} \subsection*{Changed} diff --git a/support/texplate/source/main/kotlin/org/islandoftex/texplate/util/MessageUtils.kt b/support/texplate/source/main/kotlin/org/islandoftex/texplate/util/MessageUtils.kt index 574bc1db7b..fbb68a819e 100644 --- a/support/texplate/source/main/kotlin/org/islandoftex/texplate/util/MessageUtils.kt +++ b/support/texplate/source/main/kotlin/org/islandoftex/texplate/util/MessageUtils.kt @@ -13,7 +13,8 @@ object MessageUtils { // the message width private const val WIDTH = 60 // the application version - private val VERSION = "1.0.5" + private val VERSION = MessageUtils::class.java.`package`.implementationVersion + ?: "DEVELOPMENT BUILD" /** * Prints a line in the terminal, without a line break. diff --git a/support/texshop/README.txt b/support/texshop/README.txt index f8c0d70436..8e09d03fb5 100644 --- a/support/texshop/README.txt +++ b/support/texshop/README.txt @@ -7,4 +7,4 @@ The main author is Richard Koch, koch@uoregon.edu, with supporting contributions Consult the program web site, https://pages.uoregon.edu/koch/texshop/texshop.html, for full source code, an extensive Changes document, and other information. -The current version, 5.36, was released on May 26, 2024.
\ No newline at end of file +The current version, 5.47, was released on November 6, 2024.
\ No newline at end of file diff --git a/support/texshop/texshop536.html b/support/texshop/texshop536.html deleted file mode 100644 index 705e6546b3..0000000000 --- a/support/texshop/texshop536.html +++ /dev/null @@ -1,64 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> - <title>TeXShop</title> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -</head> - -<body> - - -<!-- main content --> -<div id="main"> - -Version 5.36 has one minor bug fix and a major improvement of the PageNumber correction introduced in version 5.35. -<ul> -<p><li> In a document with over a thousand pages, the PageNumber box in the toolbar displays the number with a comma, as in 1,325. But users who want to go to a different page must enter the new page number without a comma. This makes it impossible to edit the existing number, say by changing 25 to 17 to go to page 1,317. This is fixed. -<p><li> Suppose a document has several pages of preliminary material before the main text begins. Perhaps these preliminary pages are numbered i, ii, iii, iv, v, ... and the main pages are numbered 1, 2, 3, 4, 5, ... Then entries in the PageNumber box will not be in sync with the actual page numbers in the text. The previous version of TeXShop introduced a fix for this problem, which required the user to insert a magic comment line and manually indicate the number of preliminary pages. The fix then numbered the preliminary pages 1#, 2#, 3#, ... and the main pages 1, 2, 3, ... -Moreover, users could enter a number like 17 in the box to go to main page 17, and 2# in the box to go to the second preliminary page. - -<p> This fix is still present in TeXShop 5.36, but the method of turning it on has been supplanted by a better method which does not require a magic comment line. The new method adds a macro to the source file which inserts an extra line in the console output and log file -during typesetting. That line reads "Start of main material: 3." Here 3 is replaced with the page number of the first main page. TeXShop looks for this line during typesetting; if it occurs, the PageNumber is modified as in the old method. A big advantage is that as the preliminary material grows during editing, the fix automatically adjusts without user intervention. - -<p> To activate this fix when using LaTeX and related engines, add the line -<pre> - \write128{Start of main material: \the\ReadonlyShipoutCounter.} -</pre> -to a spot in the source just after the main material is introduced. - -<p> If instead you are using plain TeX or related engines, add the line -<pre> - \write128{Start of main material: \the\pageno.} -</pre> -to a spot in the source just after the main material is introduced. - - -<p> TeXShop users need to find a way to remember these additional lines. Some may add items to the Macro -menu, while others may modify their templates. It is also possible to add appropriate items to the Command Completion dictionary. - -<p> After these lines have been added to the source, it is necessary to typeset to see changes in the PageNumber box. A lot of effort has gone into modifying the PageNumber whenever appropriate information is available in the log file. When TeXShop opens a new document, it checks to see if a log file is present, and if so it reads the log file to adjust the PageNumber box. If TeXShop is closed while documents are open, the documents will reappear the next time TeXShop starts with correct PageNumber entries. - -<p> Suppose a situation I did not anticipate causes the new code to crash the program when reading an old document, even when the extra lines above have not been added to the source. In that case, write me immediately and I'll fix the problem. But in the meantime, you can fix the crash. Add the magic comment below to the top of the source. This comment completely cancels all of the new code, and the number 0 in the comment tells it to make no changes in the numbering. -<pre> - % !TEX numberingCorrection = 0 + current - desired -</pre> - -<p> Fixing Page Number boxes is a standard feature of pdf display programs like Preview, Skim, and Adobe Acrobat. These programs do not have access to the source file, and often work by parsing the table of contents information in the pdf file. TeXShop is a program for authors rather than a pdf display program, so it is natural for it to find the information to fix the Page Number box in the source file. - -<p> Some users may prefer to view pdf files in TeXShop. If these users have access to the Log file associated with the pdf, they can get Number Box correction without using the source file. Just place the Log file in the same location as the pdf file, and TeXShop will automatically open and parse it, and adjust Page Numbers accordingly. - -<p> This feature is even available if you do not have access to the Log file. For example, the Driver Manual for my car is a pdf file with two preliminary pages and then the main pages numbered 1, 2, 3, ... Using Apple's Text Edit in plain text mode, I created a small file with the same name as the pdf manual, but extension ".log". The complete contents of this file were -<pre> - Start of main material: 3. -</pre> -After this file was placed in the location of the manual, opening the manual in TeXShop provided PageNumber boxes with the correct numbering. -</ul> - -<p> -<p> -</div> - - -</body> -</html>
\ No newline at end of file diff --git a/support/texshop/texshop547.html b/support/texshop/texshop547.html new file mode 100644 index 0000000000..f60830f7ad --- /dev/null +++ b/support/texshop/texshop547.html @@ -0,0 +1,31 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + <title>TeXShop</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +</head> + +<body> + + +<!-- main content --> +<div id="main"> + +Version 5.47 has a few minor changes: +<ul> +<p><li> A new version of Typst was released in October, 2024. This version has improved package management +that induces changes in TeXShop's support for the program. See ~/Library/TeXShop/Engines/Inactive/Typst for details. +<p><li> When TeXShop saved annotations with the option key down so only annotated pages were saved, annotations on these pages were duplicated. This is fixed. +<p><li> When the Experiment window is active, command-1 now switches between its source and preview windows. +<p><li> In Single Window Mode with line numbers visible in the Edit Panel, moving the split bar to the extreme left of the window so only the Preview Panel was visible caused a crash. This is fixed. +<p><li> The manual has new material on Typst and Experiments. +</ul> + +<p> +<p> +</div> + + +</body> +</html>
\ No newline at end of file |