<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://cyclopedia.btz.alsace/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin</id>
	<title>Cyclopédia - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://cyclopedia.btz.alsace/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin"/>
	<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php/Sp%C3%A9cial:Contributions/Admin"/>
	<updated>2026-04-11T21:24:11Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:High_use&amp;diff=339</id>
		<title>Modèle:High use</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:High_use&amp;diff=339"/>
		<updated>2024-07-31T17:35:10Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#Redirect [[Template:High-use]]&lt;br /&gt;
&lt;br /&gt;
{{Redirect category shell|{{R from modification}}{{R from template shortcut}}}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Message_box/tmbox.css&amp;diff=337</id>
		<title>Module:Message box/tmbox.css</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Message_box/tmbox.css&amp;diff=337"/>
		<updated>2024-07-31T17:35:10Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* {{pp|small=y}} */&lt;br /&gt;
.tmbox {&lt;br /&gt;
	margin: 4px 0;&lt;br /&gt;
	border-collapse: collapse;&lt;br /&gt;
	border: 1px solid #c0c090;    /* Default &amp;quot;notice&amp;quot; gray-brown */&lt;br /&gt;
	background-color: #f8eaba;&lt;br /&gt;
	box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* For the &amp;quot;small=yes&amp;quot; option. */&lt;br /&gt;
.tmbox.mbox-small {&lt;br /&gt;
	font-size: 88%;&lt;br /&gt;
	line-height: 1.25em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox-speedy {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
	background-color: #fee7e6;    /* Pink */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox-delete {&lt;br /&gt;
	border: 2px solid #b32424;    /* Red */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox-content {&lt;br /&gt;
	border: 2px solid #f28500;    /* Orange */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox-style {&lt;br /&gt;
	border: 2px solid #fc3;       /* Yellow */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox-move {&lt;br /&gt;
	border: 2px solid #9932cc;    /* Purple */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox .mbox-text {&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 0.25em 0.9em;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox .mbox-image {&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0 2px 0.9em;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox .mbox-imageright {&lt;br /&gt;
	border: none;&lt;br /&gt;
	/* @noflip */&lt;br /&gt;
	padding: 2px 0.9em 2px 0;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* An empty narrow cell */&lt;br /&gt;
.tmbox .mbox-empty-cell {           &lt;br /&gt;
	border: none;&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	width: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tmbox .mbox-invalid-type {&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (min-width: 720px) {&lt;br /&gt;
	.tmbox {&lt;br /&gt;
		margin: 4px 10%;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	.tmbox.mbox-small {&lt;br /&gt;
		/* @noflip */&lt;br /&gt;
		clear: right;&lt;br /&gt;
		/* @noflip */&lt;br /&gt;
		float: right;&lt;br /&gt;
		/* @noflip */&lt;br /&gt;
		margin: 4px 0 4px 1em;&lt;br /&gt;
		width: 238px;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html.skin-theme-clientpref-night .tmbox {&lt;br /&gt;
	background-color: #2e2505;    /* Dark brown, same hue/saturation as light */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
html.skin-theme-clientpref-night .tmbox-speedy {&lt;br /&gt;
	background-color: #310402;    /* Dark red, same hue/saturation as light */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
	html.skin-theme-clientpref-os .tmbox {&lt;br /&gt;
		background-color: #2e2505; /* Dark brown, same hue/saturation as light */&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	html.skin-theme-clientpref-os .tmbox-speedy {&lt;br /&gt;
		background-color: #310402; /* Dark red, same hue/saturation as light */&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/** T367463 */&lt;br /&gt;
body.skin--responsive table.tmbox img {&lt;br /&gt;
	max-width: none !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Old_TfD&amp;diff=335</id>
		<title>Modèle:Old TfD</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Old_TfD&amp;diff=335"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ {{{|safesubst:}}}#invoke:Unsubst||$B={{Tmbox&lt;br /&gt;
| small = {{{small|}}}&lt;br /&gt;
| image = [[File:Clipboard.svg|{{#ifeq:{{{small|}}}|yes|30x20|50x40}}px]]&lt;br /&gt;
| text  = This {{#switch:{{{demospace|{{NAMESPACE}}}}}&lt;br /&gt;
 | {{ns:Category_talk}} = category&lt;br /&gt;
 | {{ns:Module_talk}} = module&lt;br /&gt;
 | template&lt;br /&gt;
}} {{#if:{{{1|}}}|([[{{{1}}}]])}} was considered for {{#if:{{{merge|}}}|[[Wikipedia:Merging|merging]]|[[Wikipedia:Deletion policy|deletion]]}}{{#if:{{{merge|}}}|{{#ifeq:{{{merge}}}|self||&amp;amp;#32;with [[{{{merge}}}]]}} {{#if:{{{more_merge|}}}|&amp;amp;#32;{{{more_merge}}}}}}} on {{#formatdate:{{{date}}}}}. The result of the &amp;lt;!-- IF OLD LOG --&amp;gt;{{#ifexist:Wikipedia:Templates for deletion/Log/{{#if:{{{link|}}}|{{{link}}}|{{Date|{{{date}}}|ymd}}}}&lt;br /&gt;
|&amp;lt;!-- Listed in Templates for deletion   --&amp;gt;&#039;&#039;&#039;[[Wikipedia:Templates for deletion/Log/{{#if:{{{link|}}}|{{{link}}}|{{Date|{{{date|}}}|ymd}}}}#{{{talk|{{{disc|{{{discuss|{{{1|Template:{{PAGENAME}}}}}}}}}}}}}}|discussion]]&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;!-- Listed in Templates for discussion --&amp;gt;&#039;&#039;&#039;[[Wikipedia:Templates for discussion/Log/{{#if:{{{link|}}}|{{{link}}}|{{Date|{{{date|}}}|ymd}}}}#{{{talk|{{{disc|{{{discuss|{{{1|Template:{{PAGENAME}}}}}}}}}}}}}}|discussion]]&#039;&#039;&#039;}}&amp;lt;!-- END IF --&amp;gt; was &amp;quot;&#039;&#039;&#039;{{{result|keep}}}&#039;&#039;&#039;&amp;quot;.&lt;br /&gt;
}}}}&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Oldtfdfull&amp;diff=333</id>
		<title>Modèle:Oldtfdfull</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Oldtfdfull&amp;diff=333"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Template:Old TfD]]&lt;br /&gt;
&lt;br /&gt;
{{XFDcloser standard installation}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:FULLBASEPAGENAME&amp;diff=331</id>
		<title>Modèle:FULLBASEPAGENAME</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:FULLBASEPAGENAME&amp;diff=331"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#if: {{Ns has subpages | {{#if:{{{1|}}}|{{NAMESPACE:{{{1}}}}}|{{NAMESPACE}}}} }} &lt;br /&gt;
  | {{#if: {{#titleparts:{{#if:{{{1|}}}|{{{1}}}|{{FULLPAGENAME}}}}|-1}}&lt;br /&gt;
    | {{#titleparts:{{#if:{{{1|}}}|{{{1}}}|{{FULLPAGENAME}}}}|-1}}&lt;br /&gt;
    | {{#if:{{{1|}}}|{{{1}}}|{{FULLPAGENAME}}}}&lt;br /&gt;
    }}&lt;br /&gt;
  | {{#if:{{{1|}}}|{{{1}}}|{{FULLPAGENAME}}}}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_for_discussion/dated&amp;diff=329</id>
		<title>Modèle:Template for discussion/dated</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_for_discussion/dated&amp;diff=329"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SAFESUBST:&amp;lt;noinclude /&amp;gt;#invoke:Unsubst||type= |page= |link= |help= |$B={{#ifeq:{{{bigbox|&amp;lt;noinclude&amp;gt;yes&amp;lt;/noinclude&amp;gt;}}}|yes|{{Ombox&lt;br /&gt;
  |class = mbox-tfd&lt;br /&gt;
  |type  = delete&lt;br /&gt;
  |image = none&lt;br /&gt;
  |small = {{{small|no}}}&lt;br /&gt;
  |text  = This {{#ifeq:{{lc:{{{type}}}}}|module|[[Help:Module|module]]|[[Help:Template|template]]}} is being discussed {{#if:{{{action|}}}|for {{{action}}}|in accordance with Wikipedia&#039;s [[Wikipedia:Deletion policy|deletion policy]]}}. Help reach a consensus at [[{{{link}}}|&#039;&#039;&#039;its entry&#039;&#039;&#039;]].&lt;br /&gt;
{{#ifeq:{{{help}}}|off||----&lt;br /&gt;
&#039;&#039;&amp;lt;small class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;line-height:1.3em;&amp;quot;&amp;gt;[[Wikipedia:Maintenance|Maintenance]] use only:&amp;lt;br /&amp;gt;1. [{{fullurl:{{{link}}}|action=edit&amp;amp;editintro=Wikipedia:Templates_for_discussion/editnotice&amp;amp;section=1}} Edit the TfD log] to create the discussion entry.&amp;lt;br /&amp;gt;2. Please consider notifying the [{{fullurl:{{FULLPAGENAME}}|action=history}} author(s)] by placing &amp;lt;span class=&amp;quot;nowrap&amp;quot;&amp;gt;{{tlsx|{{#ifeq:{{lc:{{{action}}}}}|rename|TfR|{{#ifeq:{{lc:{{{action}}}}}|renaming|TfR|{{#ifeq:{{lc:{{{action}}}}}|move|TfR|{{#ifeq:{{lc:{{{action}}}}}|moving|TfR|TfD}}}}}}}} notice|{{PAGENAME}}{{#ifeq:{{lc:{{{type}}}}}|module|{{!}}module=yes}}}} &amp;lt;nowiki&amp;gt;~~~~&amp;lt;/nowiki&amp;gt;&amp;lt;/span&amp;gt; on their talk page(s).&amp;lt;/small&amp;gt;&#039;&#039;&lt;br /&gt;
 }}}}{{category handler&lt;br /&gt;
  | all = [[Category:Templates for deletion]]&lt;br /&gt;
  | nocat = {{{nocat|{{#ifeq:{{Template:FULLBASEPAGENAME|{{FULLBASEPAGENAME}}}}|Template:Template for discussion|true}}|true}}}&lt;br /&gt;
  | category2 = {{{category|¬}}}&lt;br /&gt;
 }}|{{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |tiny = &amp;lt;span style=&amp;quot;padding: 0; font-size: 85%; font-weight: bold; color: #000000; background-color: #f9f9f9;&amp;quot; class=&amp;quot;tfd&amp;quot;&amp;gt;[[{{{link}}}|‹See Tfd›]]&amp;lt;/span&amp;gt;&lt;br /&gt;
 |inline = &amp;lt;span style=&amp;quot;padding: 0; font-size: 85%; color: #000; border: 1px solid #aaa; background-color: #f9f9f9;&amp;quot; class=&amp;quot;tfd&amp;quot;&amp;gt;‹The [[Help:Template|template]] &#039;&#039;[[Template:{{{page}}}|{{{page}}}]]&#039;&#039; is being [[{{{link}}}|considered for {{if empty|{{{action|}}}|deletion}}]].›&amp;lt;/span&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
 |infobox|box|sidebar = &amp;lt;div class=&amp;quot;boilerplate metadata plainlinks tfd navigation-not-searchable&amp;quot; id=&amp;quot;tfd&amp;quot; style=&amp;quot;background-color: transparent; padding: 0; font-size: 85%; color:#000000; text-align: center; position: relative; float: right; clear:right; border-bottom: 1px solid #AAAAAA; width: {{#if:{{{width|}}}|{{px|{{{width}}}}}|27em}}&amp;quot;&amp;gt;‹&amp;amp;nbsp;The [[Help:Template|template]] &#039;&#039;[[Template:{{{page}}}|{{{page}}}]]&#039;&#039; is being [[{{{link}}}|considered for {{if empty|{{{action|}}}|deletion}}]].&amp;amp;nbsp;›&amp;lt;/div&amp;gt;&lt;br /&gt;
 |hide|disabled = &amp;lt;!-- No output --&amp;gt;&lt;br /&gt;
 |#default = &amp;lt;div class=&amp;quot;boilerplate metadata plainlinks tfd navigation-not-searchable&amp;quot; id=&amp;quot;tfd&amp;quot; style=&amp;quot;background-color: transparent; padding: 0; font-size: 85%; color:#000000; text-align: center; border-bottom:1px solid #AAAAAA;&amp;quot;&amp;gt;‹&amp;amp;nbsp;The [[Help:Template|template]] below (&#039;&#039;[[Template:{{{page}}}|{{{page}}}]]&#039;&#039;) is being considered for {{if empty|{{{action|}}}|deletion}}{{#if:{{{otherpage|}}}|&amp;amp;#32;to {{{otherpage|}}}}}. See [[{{{link}}}|templates for discussion]] to help reach a consensus.&amp;amp;nbsp;›&amp;lt;/div&amp;gt;&lt;br /&gt;
}}}}}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc subpage, please, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Date&amp;diff=327</id>
		<title>Modèle:Date</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Date&amp;diff=327"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#switch:none&lt;br /&gt;
 |{{safesubst:&amp;lt;noinclude/&amp;gt;#iferror: {{safesubst:&amp;lt;noinclude/&amp;gt;#time:Y_M_d|{{{1|}}} }} | none }} &amp;lt;noinclude&amp;gt;&amp;lt;!-- #time: can&#039;t handle --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
 |{{safesubst:&amp;lt;noinclude/&amp;gt;#iferror: {{safesubst:&amp;lt;noinclude/&amp;gt;#expr: {{{1|}}}+0 }}&lt;br /&gt;
    |&amp;lt;noinclude&amp;gt;&amp;lt;!--not a pure number--&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
    |{{safesubst:&amp;lt;noinclude/&amp;gt;#ifexpr: {{{1|}}}+0 &amp;gt; 10000000000000&lt;br /&gt;
       |&amp;lt;noinclude&amp;gt;&amp;lt;!-- a yyyymmddhhmmss timestamp --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
       |{{safesubst:&amp;lt;noinclude/&amp;gt;#ifeq: {{safesubst:&amp;lt;noinclude/&amp;gt;#expr:{{{1|}}}+0}} | {{{1|}}}&lt;br /&gt;
          | none &amp;lt;noinclude&amp;gt;&amp;lt;!-- pure number eg 123.456 --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
          | &amp;lt;noinclude&amp;gt;&amp;lt;!-- assume yy-mm-dd --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
        }}&lt;br /&gt;
     }}&lt;br /&gt;
  }}&lt;br /&gt;
 |{{safesubst:&amp;lt;noinclude/&amp;gt;#switch:  {{safesubst:&amp;lt;noinclude/&amp;gt;lc:{{{2|}}}}} | none | asis | link | lnone =none }}&lt;br /&gt;
 |{{safesubst:&amp;lt;noinclude/&amp;gt;#ifexpr:  {{safesubst:&amp;lt;noinclude/&amp;gt;#time:Y|{{{1|}}} }} &amp;lt; 1000 | none }}&lt;br /&gt;
 |{{safesubst:&amp;lt;noinclude/&amp;gt;#switch:  {{safesubst:&amp;lt;noinclude/&amp;gt;#time:Ynj|{{{1|}}} }}|100031|110031|130031|140031|150031=none}}&lt;br /&gt;
 |= {{safesubst:&amp;lt;noinclude/&amp;gt;#if:{{{1|}}}&lt;br /&gt;
      |{{safesubst:&amp;lt;noinclude/&amp;gt;#switch:{{{2}}}&lt;br /&gt;
         |link|lnone|l=[[{{{1}}}]]&lt;br /&gt;
         |{{{1}}}&lt;br /&gt;
       }}&lt;br /&gt;
    }}&amp;lt;noinclude&amp;gt;&amp;lt;!-- error or &amp;quot;none&amp;quot;, so no formatting --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
 |&amp;lt;noinclude&amp;gt;&amp;lt;!-- continue with formatting --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
  {{safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:&amp;lt;noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
    --&amp;gt;&amp;lt;/noinclude&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#time:Y|{{{1}}} 2008}}&amp;lt;noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
    --&amp;gt;&amp;lt;/noinclude&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#iferror: {{safesubst:&amp;lt;noinclude/&amp;gt;#ifexpr: {{{1}}}&amp;gt;10000000000000 | no }} | }}&amp;lt;noinclude&amp;gt;&amp;lt;!--&lt;br /&gt;
    --&amp;gt;&amp;lt;/noinclude&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#time:Y|{{{1}}} 2004}}&lt;br /&gt;
  |20082004&lt;br /&gt;
  |&amp;lt;noinclude&amp;gt;&amp;lt;!-- no year --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
    {{safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{safesubst:&amp;lt;noinclude/&amp;gt;#time:d|{{{1}}} 2036}}|{{safesubst:&amp;lt;noinclude/&amp;gt;#time:d|{{{1}}} }}&lt;br /&gt;
    |&amp;lt;noinclude&amp;gt;&amp;lt;!-- month+day --&amp;gt;&amp;lt;/noinclude&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#time:&lt;br /&gt;
      {{safesubst:&amp;lt;noinclude/&amp;gt;#switch: {{safesubst:&amp;lt;noinclude/&amp;gt;lc: {{safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{{3|}}}|y|L}}{{{2|}}} }}&lt;br /&gt;
      | lmdy | liso | lymd      = [[:F j]]&lt;br /&gt;
      | mdy  | iso  | ymd       = F j&lt;br /&gt;
      | ldmy | l                = [[:j F]]&lt;br /&gt;
      | #default                = j F&lt;br /&gt;
      }}|{{{1}}} 2000 }}&amp;lt;noinclude&amp;gt;&amp;lt;!-- default=&#039;dmy&#039; or null or &amp;quot;&amp;quot; or unsupported option --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
    |&amp;lt;noinclude&amp;gt;&amp;lt;!-- month only --&amp;gt;&amp;lt;/noinclude&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#time:&lt;br /&gt;
      {{safesubst:&amp;lt;noinclude/&amp;gt;#switch: {{safesubst:&amp;lt;noinclude/&amp;gt;lc: {{safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{{3|}}}|y|L}}{{{2|}}} }}&lt;br /&gt;
      | lmdy | liso | lymd &lt;br /&gt;
      | ldmy | l                = [[F]]&lt;br /&gt;
      | #default                = F&lt;br /&gt;
      }}|{{{1}}} 2000 }}&amp;lt;noinclude&amp;gt;&amp;lt;!-- default=&#039;dmy&#039;/&#039;mdy&#039;/&#039;ymd&#039;/&#039;iso&#039;/null/&amp;quot;&amp;quot;/unsupported opt --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
    }}&lt;br /&gt;
  |&amp;lt;noinclude&amp;gt;&amp;lt;!-- with year--&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
    {{safesubst:&amp;lt;noinclude/&amp;gt;#if: {{safesubst:&amp;lt;noinclude/&amp;gt;#iferror:{{safesubst:&amp;lt;noinclude/&amp;gt;#time:j|2 {{{1|}}}}}|*D*|{{safesubst:&amp;lt;noinclude/&amp;gt;#iferror:{{safesubst:&amp;lt;noinclude/&amp;gt;#time:j|2000 {{{1|}}}}}|*D*| }}}}&lt;br /&gt;
    |&amp;lt;noinclude&amp;gt;&amp;lt;!-- day+month+year --&amp;gt;&amp;lt;/noinclude&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#time:&lt;br /&gt;
      {{safesubst:&amp;lt;noinclude/&amp;gt;#switch: {{safesubst:&amp;lt;noinclude/&amp;gt;lc: {{safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{{3|}}}|y|L}}{{{2|}}} }}&lt;br /&gt;
      | lmdy                    = [[:F j]], [[Y]]&lt;br /&gt;
      | mdy                     = F j, Y&lt;br /&gt;
      | liso                    = [[Y|Y-]][[F j|m-d]]&amp;lt;noinclude&amp;gt;&amp;lt;!-- i.e. [[Y-m-d]] --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
      | iso                     = Y-m-d&lt;br /&gt;
      | lymd                    = [[Y]] [[:F j]]&lt;br /&gt;
      | ymd                     = Y F j&lt;br /&gt;
      | ldmy | l                = [[:j F]] [[Y]]&lt;br /&gt;
      | #default                = j F Y&lt;br /&gt;
      }}|{{{1|}}} }}&amp;lt;noinclude&amp;gt;&amp;lt;!-- #default=&#039;dmy&#039; or null or &amp;quot;&amp;quot; or unsupported option --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
    |&amp;lt;noinclude&amp;gt;&amp;lt;!-- month+year --&amp;gt;&amp;lt;/noinclude&amp;gt;{{safesubst:&amp;lt;noinclude/&amp;gt;#time:&lt;br /&gt;
      {{safesubst:&amp;lt;noinclude/&amp;gt;#switch: {{safesubst:&amp;lt;noinclude/&amp;gt;lc: {{safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{{3|}}}|y|L}}{{{2|}}} }}&lt;br /&gt;
      | lmdy | liso | lymd | ldmy | l  = [[:F Y]]&lt;br /&gt;
      | #default                = F Y&lt;br /&gt;
      }}|{{{1|}}} }}&amp;lt;noinclude&amp;gt;&amp;lt;!-- default=&#039;dmy&#039;/&#039;iso&#039;/&#039;mdy&#039;/null/&amp;quot;&amp;quot;/unsupported option --&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
    }}&lt;br /&gt;
  }}    &lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/blacklist&amp;diff=325</id>
		<title>Module:Category handler/blacklist</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/blacklist&amp;diff=325"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module contains the blacklist used by [[Module:Category handler]].&lt;br /&gt;
-- Pages that match Lua patterns in this list will not be categorised unless&lt;br /&gt;
-- categorisation is explicitly requested.&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	&#039;^Main Page$&#039;, -- don&#039;t categorise the main page.&lt;br /&gt;
&lt;br /&gt;
	-- Don&#039;t categorise the following pages or their subpages.&lt;br /&gt;
	-- &amp;quot;%f[/\0]&amp;quot; matches if the next character is &amp;quot;/&amp;quot; or the end of the string.&lt;br /&gt;
	&#039;^Wikipedia:Cascade%-protected items%f[/\0]&#039;,&lt;br /&gt;
	&#039;^User:UBX%f[/\0]&#039;, -- The userbox &amp;quot;template&amp;quot; space.&lt;br /&gt;
	&#039;^User talk:UBX%f[/\0]&#039;,&lt;br /&gt;
&lt;br /&gt;
	-- Don&#039;t categorise subpages of these pages, but allow&lt;br /&gt;
	-- categorisation of the base page.&lt;br /&gt;
	&#039;^Wikipedia:Template index/.*$&#039;,&lt;br /&gt;
&lt;br /&gt;
	-- Don&#039;t categorise archives.&lt;br /&gt;
	&#039;/[aA]rchive&#039;,&lt;br /&gt;
	&amp;quot;^Wikipedia:Administrators&#039; noticeboard/IncidentArchive%d+$&amp;quot;,&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/shared&amp;diff=323</id>
		<title>Module:Category handler/shared</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/shared&amp;diff=323"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module contains shared functions used by [[Module:Category handler]]&lt;br /&gt;
-- and its submodules.&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.matchesBlacklist(page, blacklist)&lt;br /&gt;
	for i, pattern in ipairs(blacklist) do&lt;br /&gt;
		local match = mw.ustring.match(page, pattern)&lt;br /&gt;
		if match then&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getParamMappings(useLoadData)&lt;br /&gt;
	local dataPage = &#039;Module:Namespace detect/data&#039;&lt;br /&gt;
	if useLoadData then&lt;br /&gt;
		return mw.loadData(dataPage).mappings&lt;br /&gt;
	else&lt;br /&gt;
		return require(dataPage).mappings&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.getNamespaceParameters(titleObj, mappings)&lt;br /&gt;
	-- We don&#039;t use title.nsText for the namespace name because it adds&lt;br /&gt;
	-- underscores.&lt;br /&gt;
	local mappingsKey&lt;br /&gt;
	if titleObj.isTalkPage then&lt;br /&gt;
		mappingsKey = &#039;talk&#039;&lt;br /&gt;
	else&lt;br /&gt;
		mappingsKey = mw.site.namespaces[titleObj.namespace].name&lt;br /&gt;
	end&lt;br /&gt;
	mappingsKey = mw.ustring.lower(mappingsKey)&lt;br /&gt;
	return mappings[mappingsKey] or {}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/config&amp;diff=321</id>
		<title>Module:Category handler/config</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/config&amp;diff=321"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--            [[Module:Category handler]] configuration data                  --&lt;br /&gt;
--       Language-specific parameter names and values can be set here.        --&lt;br /&gt;
--       For blacklist config, see [[Module:Category handler/blacklist]].     --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local cfg = {} -- Don&#039;t edit this line.&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                       Start configuration data                             --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                              Parameter names                               --&lt;br /&gt;
-- These configuration items specify custom parameter names.                  --&lt;br /&gt;
-- To add one extra name, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- foo = &#039;parameter name&#039;,                                                    --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- To add multiple names, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- foo = {&#039;parameter name 1&#039;, &#039;parameter name 2&#039;, &#039;parameter name 3&#039;},        --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
cfg.parameters = {&lt;br /&gt;
	&lt;br /&gt;
	-- The nocat and categories parameter suppress&lt;br /&gt;
	-- categorisation. They are used with Module:Yesno, and work as follows:&lt;br /&gt;
	--&lt;br /&gt;
	-- cfg.nocat:&lt;br /&gt;
	-- Result of yesno()                        Effect&lt;br /&gt;
	-- true                                     Categorisation is suppressed&lt;br /&gt;
	-- false                                    Categorisation is allowed, and&lt;br /&gt;
	--                                          the blacklist check is skipped&lt;br /&gt;
	-- nil                                      Categorisation is allowed&lt;br /&gt;
	--&lt;br /&gt;
	-- cfg.categories:&lt;br /&gt;
	-- Result of yesno()                        Effect&lt;br /&gt;
	-- true                                     Categorisation is allowed, and&lt;br /&gt;
	--                                          the blacklist check is skipped&lt;br /&gt;
	-- false                                    Categorisation is suppressed&lt;br /&gt;
	-- nil                                      Categorisation is allowed&lt;br /&gt;
	nocat = &#039;nocat&#039;,&lt;br /&gt;
	categories = &#039;categories&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter name for the legacy &amp;quot;category2&amp;quot; parameter. This skips the&lt;br /&gt;
	-- blacklist if set to the cfg.category2Yes value, and suppresses&lt;br /&gt;
	-- categorisation if present but equal to anything other than&lt;br /&gt;
	-- cfg.category2Yes or cfg.category2Negative.&lt;br /&gt;
	category2 = &#039;category2&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- cfg.subpage is the parameter name to specify how to behave on subpages.&lt;br /&gt;
	subpage = &#039;subpage&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter for data to return in all namespaces.&lt;br /&gt;
	all = &#039;all&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter name for data to return if no data is specified for the&lt;br /&gt;
	-- namespace that is detected.&lt;br /&gt;
	other = &#039;other&#039;,&lt;br /&gt;
	&lt;br /&gt;
	-- The parameter name used to specify a page other than the current page;&lt;br /&gt;
	-- used for testing and demonstration.&lt;br /&gt;
	demopage = &#039;page&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                              Parameter values                              --&lt;br /&gt;
-- These are set values that can be used with certain parameters. Only one    --&lt;br /&gt;
-- value can be specified, like this:                                         --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- cfg.foo = &#039;value name&#039;                                                     --                                               --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- The following settings are used with the cfg.category2 parameter. Setting&lt;br /&gt;
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2&lt;br /&gt;
-- is present but equal to anything other than cfg.category2Yes or&lt;br /&gt;
-- cfg.category2Negative then it supresses cateogrisation.&lt;br /&gt;
cfg.category2Yes = &#039;yes&#039;&lt;br /&gt;
cfg.category2Negative = &#039;¬&#039;&lt;br /&gt;
&lt;br /&gt;
-- The following settings are used with the cfg.subpage parameter.&lt;br /&gt;
-- cfg.subpageNo is the value to specify to not categorise on subpages;&lt;br /&gt;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.&lt;br /&gt;
cfg.subpageNo = &#039;no&#039;&lt;br /&gt;
cfg.subpageOnly = &#039;only&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                           Default namespaces                               --&lt;br /&gt;
-- This is a table of namespaces to categorise by default. The keys are the   --&lt;br /&gt;
-- namespace numbers.                                                         --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
cfg.defaultNamespaces = {&lt;br /&gt;
	[  0] = true, -- main&lt;br /&gt;
	[  6] = true, -- file&lt;br /&gt;
	[ 12] = true, -- help&lt;br /&gt;
	[ 14] = true, -- category&lt;br /&gt;
	[100] = true, -- portal&lt;br /&gt;
	[108] = true, -- book&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                                Wrappers                                    --&lt;br /&gt;
-- This is a wrapper template or a list of wrapper templates to be passed to  --&lt;br /&gt;
-- [[Module:Arguments]].                                                      --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
cfg.wrappers = &#039;Template:Category handler&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                           End configuration data                           --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
return cfg -- Don&#039;t edit this line.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/data&amp;diff=319</id>
		<title>Module:Category handler/data</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler/data&amp;diff=319"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module assembles data to be passed to [[Module:Category handler]] using&lt;br /&gt;
-- mw.loadData. This includes the configuration data and whether the current&lt;br /&gt;
-- page matches the title blacklist.&lt;br /&gt;
&lt;br /&gt;
local data = require(&#039;Module:Category handler/config&#039;)&lt;br /&gt;
local mShared = require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
local blacklist = require(&#039;Module:Category handler/blacklist&#039;)&lt;br /&gt;
local title = mw.title.getCurrentTitle()&lt;br /&gt;
&lt;br /&gt;
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(&lt;br /&gt;
	title.prefixedText,&lt;br /&gt;
	blacklist&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(&lt;br /&gt;
	title,&lt;br /&gt;
	mShared.getParamMappings()&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
return data&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler&amp;diff=317</id>
		<title>Module:Category handler</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Category_handler&amp;diff=317"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                                                                            --&lt;br /&gt;
--                              CATEGORY HANDLER                              --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
--      This module implements the {{category handler}} template in Lua,      --&lt;br /&gt;
--      with a few improvements: all namespaces and all namespace aliases     --&lt;br /&gt;
--      are supported, and namespace names are detected automatically for     --&lt;br /&gt;
--      the local wiki. This module requires [[Module:Namespace detect]]      --&lt;br /&gt;
--      and [[Module:Yesno]] to be available on the local wiki. It can be     --&lt;br /&gt;
--      configured for different wikis by altering the values in              --&lt;br /&gt;
--      [[Module:Category handler/config]], and pages can be blacklisted      --&lt;br /&gt;
--      from categorisation by using [[Module:Category handler/blacklist]].   --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
-- Load required modules&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
&lt;br /&gt;
-- Lazily load things we don&#039;t always need&lt;br /&gt;
local mShared, mappings&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Helper functions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function trimWhitespace(s, removeBlanks)&lt;br /&gt;
	if type(s) ~= &#039;string&#039; then&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
	s = s:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
	if removeBlanks then&lt;br /&gt;
		if s ~= &#039;&#039; then&lt;br /&gt;
			return s&lt;br /&gt;
		else&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return s&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- CategoryHandler class&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local CategoryHandler = {}&lt;br /&gt;
CategoryHandler.__index = CategoryHandler&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler.new(data, args)&lt;br /&gt;
	local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)&lt;br /&gt;
	&lt;br /&gt;
	-- Set the title object&lt;br /&gt;
	do&lt;br /&gt;
		local pagename = obj:parameter(&#039;demopage&#039;)&lt;br /&gt;
		local success, titleObj&lt;br /&gt;
		if pagename then&lt;br /&gt;
			success, titleObj = pcall(mw.title.new, pagename)&lt;br /&gt;
		end&lt;br /&gt;
		if success and titleObj then&lt;br /&gt;
			obj.title = titleObj&lt;br /&gt;
			if titleObj == mw.title.getCurrentTitle() then&lt;br /&gt;
				obj._usesCurrentTitle = true&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			obj.title = mw.title.getCurrentTitle()&lt;br /&gt;
			obj._usesCurrentTitle = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set suppression parameter values&lt;br /&gt;
	for _, key in ipairs{&#039;nocat&#039;, &#039;categories&#039;} do&lt;br /&gt;
		local value = obj:parameter(key)&lt;br /&gt;
		value = trimWhitespace(value, true)&lt;br /&gt;
		obj[&#039;_&#039; .. key] = yesno(value)&lt;br /&gt;
	end&lt;br /&gt;
	do&lt;br /&gt;
		local subpage = obj:parameter(&#039;subpage&#039;)&lt;br /&gt;
		local category2 = obj:parameter(&#039;category2&#039;)&lt;br /&gt;
		if type(subpage) == &#039;string&#039; then&lt;br /&gt;
			subpage = mw.ustring.lower(subpage)&lt;br /&gt;
		end&lt;br /&gt;
		if type(category2) == &#039;string&#039; then&lt;br /&gt;
			subpage = mw.ustring.lower(category2)&lt;br /&gt;
		end&lt;br /&gt;
		obj._subpage = trimWhitespace(subpage, true)&lt;br /&gt;
		obj._category2 = trimWhitespace(category2) -- don&#039;t remove blank values&lt;br /&gt;
	end&lt;br /&gt;
	return obj&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:parameter(key)&lt;br /&gt;
	local parameterNames = self._data.parameters[key]&lt;br /&gt;
	local pntype = type(parameterNames)&lt;br /&gt;
	if pntype == &#039;string&#039; or pntype == &#039;number&#039; then&lt;br /&gt;
		return self._args[parameterNames]&lt;br /&gt;
	elseif pntype == &#039;table&#039; then&lt;br /&gt;
		for _, name in ipairs(parameterNames) do&lt;br /&gt;
			local value = self._args[name]&lt;br /&gt;
			if value ~= nil then&lt;br /&gt;
				return value&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return nil&lt;br /&gt;
	else&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&#039;invalid config key &amp;quot;%s&amp;quot;&#039;,&lt;br /&gt;
			tostring(key)&lt;br /&gt;
		), 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:isSuppressedByArguments()&lt;br /&gt;
	return&lt;br /&gt;
		-- See if a category suppression argument has been set.&lt;br /&gt;
		self._nocat == true&lt;br /&gt;
		or self._categories == false&lt;br /&gt;
		or (&lt;br /&gt;
			self._category2&lt;br /&gt;
			and self._category2 ~= self._data.category2Yes&lt;br /&gt;
			and self._category2 ~= self._data.category2Negative&lt;br /&gt;
		)&lt;br /&gt;
&lt;br /&gt;
		-- Check whether we are on a subpage, and see if categories are&lt;br /&gt;
		-- suppressed based on our subpage status.&lt;br /&gt;
		or self._subpage == self._data.subpageNo and self.title.isSubpage&lt;br /&gt;
		or self._subpage == self._data.subpageOnly and not self.title.isSubpage&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:shouldSkipBlacklistCheck()&lt;br /&gt;
	-- Check whether the category suppression arguments indicate we&lt;br /&gt;
	-- should skip the blacklist check.&lt;br /&gt;
	return self._nocat == false&lt;br /&gt;
		or self._categories == true&lt;br /&gt;
		or self._category2 == self._data.category2Yes&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:matchesBlacklist()&lt;br /&gt;
	if self._usesCurrentTitle then&lt;br /&gt;
		return self._data.currentTitleMatchesBlacklist&lt;br /&gt;
	else&lt;br /&gt;
		mShared = mShared or require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
		return mShared.matchesBlacklist(&lt;br /&gt;
			self.title.prefixedText,&lt;br /&gt;
			mw.loadData(&#039;Module:Category handler/blacklist&#039;)&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:isSuppressed()&lt;br /&gt;
	-- Find if categories are suppressed by either the arguments or by&lt;br /&gt;
	-- matching the blacklist.&lt;br /&gt;
	return self:isSuppressedByArguments()&lt;br /&gt;
		or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:getNamespaceParameters()&lt;br /&gt;
	if self._usesCurrentTitle then&lt;br /&gt;
		return self._data.currentTitleNamespaceParameters&lt;br /&gt;
	else&lt;br /&gt;
		if not mappings then&lt;br /&gt;
			mShared = mShared or require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
			mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData&lt;br /&gt;
		end&lt;br /&gt;
		return mShared.getNamespaceParameters(&lt;br /&gt;
			self.title,&lt;br /&gt;
			mappings&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:namespaceParametersExist()&lt;br /&gt;
	-- Find whether any namespace parameters have been specified.&lt;br /&gt;
	-- We use the order &amp;quot;all&amp;quot; --&amp;gt; namespace params --&amp;gt; &amp;quot;other&amp;quot; as this is what&lt;br /&gt;
	-- the old template did.&lt;br /&gt;
	if self:parameter(&#039;all&#039;) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	if not mappings then&lt;br /&gt;
		mShared = mShared or require(&#039;Module:Category handler/shared&#039;)&lt;br /&gt;
		mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData&lt;br /&gt;
	end&lt;br /&gt;
	for ns, params in pairs(mappings) do&lt;br /&gt;
		for i, param in ipairs(params) do&lt;br /&gt;
			if self._args[param] then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if self:parameter(&#039;other&#039;) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
	return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function CategoryHandler:getCategories()&lt;br /&gt;
	local params = self:getNamespaceParameters()&lt;br /&gt;
	local nsCategory&lt;br /&gt;
	for i, param in ipairs(params) do&lt;br /&gt;
		local value = self._args[param]&lt;br /&gt;
		if value ~= nil then&lt;br /&gt;
			nsCategory = value&lt;br /&gt;
			break&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if nsCategory ~= nil or self:namespaceParametersExist() then&lt;br /&gt;
		-- Namespace parameters exist - advanced usage.&lt;br /&gt;
		if nsCategory == nil then&lt;br /&gt;
			nsCategory = self:parameter(&#039;other&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		local ret = {self:parameter(&#039;all&#039;)}&lt;br /&gt;
		local numParam = tonumber(nsCategory)&lt;br /&gt;
		if numParam and numParam &amp;gt;= 1 and math.floor(numParam) == numParam then&lt;br /&gt;
			-- nsCategory is an integer&lt;br /&gt;
			ret[#ret + 1] = self._args[numParam]&lt;br /&gt;
		else&lt;br /&gt;
			ret[#ret + 1] = nsCategory&lt;br /&gt;
		end&lt;br /&gt;
		if #ret &amp;lt; 1 then&lt;br /&gt;
			return nil&lt;br /&gt;
		else&lt;br /&gt;
			return table.concat(ret)&lt;br /&gt;
		end&lt;br /&gt;
	elseif self._data.defaultNamespaces[self.title.namespace] then&lt;br /&gt;
		-- Namespace parameters don&#039;t exist, simple usage.&lt;br /&gt;
		return self._args[1]&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Exports&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p._exportClasses()&lt;br /&gt;
	-- Used for testing purposes.&lt;br /&gt;
	return {&lt;br /&gt;
		CategoryHandler = CategoryHandler&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args, data)&lt;br /&gt;
	data = data or mw.loadData(&#039;Module:Category handler/data&#039;)&lt;br /&gt;
	local handler = CategoryHandler.new(data, args)&lt;br /&gt;
	if handler:isSuppressed() then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	return handler:getCategories()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame, data)&lt;br /&gt;
	data = data or mw.loadData(&#039;Module:Category handler/data&#039;)&lt;br /&gt;
	local args = require(&#039;Module:Arguments&#039;).getArgs(frame, {&lt;br /&gt;
		wrappers = data.wrappers,&lt;br /&gt;
		valueFunc = function (k, v)&lt;br /&gt;
			v = trimWhitespace(v)&lt;br /&gt;
			if type(k) == &#039;number&#039; then&lt;br /&gt;
				if v ~= &#039;&#039; then&lt;br /&gt;
					return v&lt;br /&gt;
				else&lt;br /&gt;
					return nil&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				return v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	})&lt;br /&gt;
	return p._main(args, data)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Tmbox&amp;diff=315</id>
		<title>Modèle:Tmbox</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Tmbox&amp;diff=315"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:Message box|tmbox}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Category_handler&amp;diff=313</id>
		<title>Modèle:Category handler</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Category_handler&amp;diff=313"/>
		<updated>2024-07-31T17:35:09Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:Category handler|main}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories to the /doc subpage, and interwikis to Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Namespace_detect/config&amp;diff=311</id>
		<title>Module:Namespace detect/config</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Namespace_detect/config&amp;diff=311"/>
		<updated>2024-07-31T17:35:08Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                    Namespace detect configuration data                     --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- This module stores configuration data for Module:Namespace detect. Here    --&lt;br /&gt;
-- you can localise the module to your wiki&#039;s language.                       --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- To activate a configuration item, you need to uncomment it. This means     --&lt;br /&gt;
-- that you need to remove the text &amp;quot;-- &amp;quot; at the start of the line.           --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local cfg = {} -- Don&#039;t edit this line.&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                              Parameter names                               --&lt;br /&gt;
-- These configuration items specify custom parameter names. Values added     --&lt;br /&gt;
-- here will work in addition to the default English parameter names.         --&lt;br /&gt;
-- To add one extra name, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- cfg.foo = &#039;parameter name&#039;                                                 --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- To add multiple names, you can use this format:                            --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- cfg.foo = {&#039;parameter name 1&#039;, &#039;parameter name 2&#039;, &#039;parameter name 3&#039;}     --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
---- This parameter displays content for the main namespace:&lt;br /&gt;
-- cfg.main = &#039;main&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter displays in talk namespaces:&lt;br /&gt;
-- cfg.talk = &#039;talk&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter displays content for &amp;quot;other&amp;quot; namespaces (namespaces for which&lt;br /&gt;
---- parameters have not been specified):&lt;br /&gt;
-- cfg.other = &#039;other&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter makes talk pages behave as though they are the corresponding&lt;br /&gt;
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].&lt;br /&gt;
---- Edit that module to change the default values of &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, etc.&lt;br /&gt;
-- cfg.subjectns = &#039;subjectns&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter sets a demonstration namespace:&lt;br /&gt;
-- cfg.demospace = &#039;demospace&#039;&lt;br /&gt;
&lt;br /&gt;
---- This parameter sets a specific page to compare:&lt;br /&gt;
cfg.demopage = &#039;page&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                           Table configuration                              --&lt;br /&gt;
-- These configuration items allow customisation of the &amp;quot;table&amp;quot; function,     --&lt;br /&gt;
-- used to generate a table of possible parameters in the module              --&lt;br /&gt;
-- documentation.                                                             --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
---- The header for the namespace column in the wikitable containing the list of&lt;br /&gt;
---- possible subject-space parameters.&lt;br /&gt;
-- cfg.wikitableNamespaceHeader = &#039;Namespace&#039;&lt;br /&gt;
&lt;br /&gt;
---- The header for the wikitable containing the list of possible subject-space&lt;br /&gt;
---- parameters.&lt;br /&gt;
-- cfg.wikitableAliasesHeader = &#039;Aliases&#039;&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
--                        End of configuration data                           --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
return cfg -- Don&#039;t edit this line.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Namespace_detect/data&amp;diff=309</id>
		<title>Module:Namespace detect/data</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Namespace_detect/data&amp;diff=309"/>
		<updated>2024-07-31T17:35:08Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                          Namespace detect data                             --&lt;br /&gt;
-- This module holds data for [[Module:Namespace detect]] to be loaded per    --&lt;br /&gt;
-- page, rather than per #invoke, for performance reasons.                    --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local cfg = require(&#039;Module:Namespace detect/config&#039;)&lt;br /&gt;
&lt;br /&gt;
local function addKey(t, key, defaultKey)&lt;br /&gt;
	if key ~= defaultKey then&lt;br /&gt;
		t[#t + 1] = key&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get a table of parameters to query for each default parameter name.&lt;br /&gt;
-- This allows wikis to customise parameter names in the cfg table while&lt;br /&gt;
-- ensuring that default parameter names will always work. The cfg table&lt;br /&gt;
-- values can be added as a string, or as an array of strings.&lt;br /&gt;
&lt;br /&gt;
local defaultKeys = {&lt;br /&gt;
	&#039;main&#039;,&lt;br /&gt;
	&#039;talk&#039;,&lt;br /&gt;
	&#039;other&#039;,&lt;br /&gt;
	&#039;subjectns&#039;,&lt;br /&gt;
	&#039;demospace&#039;,&lt;br /&gt;
	&#039;demopage&#039;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local argKeys = {}&lt;br /&gt;
for i, defaultKey in ipairs(defaultKeys) do&lt;br /&gt;
	argKeys[defaultKey] = {defaultKey}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
for defaultKey, t in pairs(argKeys) do&lt;br /&gt;
	local cfgValue = cfg[defaultKey]&lt;br /&gt;
	local cfgValueType = type(cfgValue)&lt;br /&gt;
	if cfgValueType == &#039;string&#039; then&lt;br /&gt;
		addKey(t, cfgValue, defaultKey)&lt;br /&gt;
	elseif cfgValueType == &#039;table&#039; then&lt;br /&gt;
		for i, key in ipairs(cfgValue) do&lt;br /&gt;
			addKey(t, key, defaultKey)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	cfg[defaultKey] = nil -- Free the cfg value as we don&#039;t need it any more.&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getParamMappings()&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Returns a table of how parameter names map to namespace names. The keys&lt;br /&gt;
	-- are the actual namespace names, in lower case, and the values are the&lt;br /&gt;
	-- possible parameter names for that namespace, also in lower case. The&lt;br /&gt;
	-- table entries are structured like this:&lt;br /&gt;
	-- {&lt;br /&gt;
	--   [&#039;&#039;] = {&#039;main&#039;},&lt;br /&gt;
	--   [&#039;wikipedia&#039;] = {&#039;wikipedia&#039;, &#039;project&#039;, &#039;wp&#039;},&lt;br /&gt;
	--   ...&lt;br /&gt;
	-- }&lt;br /&gt;
	--]]&lt;br /&gt;
	local mappings = {}&lt;br /&gt;
	local mainNsName = mw.site.subjectNamespaces[0].name&lt;br /&gt;
	mainNsName = mw.ustring.lower(mainNsName)&lt;br /&gt;
	mappings[mainNsName] = mw.clone(argKeys.main)&lt;br /&gt;
	mappings[&#039;talk&#039;] = mw.clone(argKeys.talk)&lt;br /&gt;
	for nsid, ns in pairs(mw.site.subjectNamespaces) do&lt;br /&gt;
		if nsid ~= 0 then -- Exclude main namespace.&lt;br /&gt;
			local nsname = mw.ustring.lower(ns.name)&lt;br /&gt;
			local canonicalName = mw.ustring.lower(ns.canonicalName)&lt;br /&gt;
			mappings[nsname] = {nsname}&lt;br /&gt;
			if canonicalName ~= nsname then&lt;br /&gt;
				table.insert(mappings[nsname], canonicalName)&lt;br /&gt;
			end&lt;br /&gt;
			for _, alias in ipairs(ns.aliases) do&lt;br /&gt;
				table.insert(mappings[nsname], mw.ustring.lower(alias))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return mappings&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	argKeys = argKeys,&lt;br /&gt;
	cfg = cfg,&lt;br /&gt;
	mappings = getParamMappings()&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Ns_has_subpages&amp;diff=307</id>
		<title>Module:Ns has subpages</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Ns_has_subpages&amp;diff=307"/>
		<updated>2024-07-31T17:35:08Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module implements [[Template:Ns has subpages]].&lt;br /&gt;
-- While the template is fairly simple, this information is made available to&lt;br /&gt;
-- Lua directly, so using a module means that we don&#039;t have to update the&lt;br /&gt;
-- template as new namespaces are added.&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p._main(ns, frame)&lt;br /&gt;
	-- Get the current namespace if we were not passed one.&lt;br /&gt;
	if not ns then&lt;br /&gt;
		ns = mw.title.getCurrentTitle().namespace&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Look up the namespace table from mw.site.namespaces. This should work&lt;br /&gt;
	-- for a majority of cases.&lt;br /&gt;
	local nsTable = mw.site.namespaces[ns]&lt;br /&gt;
&lt;br /&gt;
	-- Try using string matching to get the namespace from page names.&lt;br /&gt;
	-- Do a quick and dirty bad title check to try and make sure we do the same&lt;br /&gt;
	-- thing as {{NAMESPACE}} in most cases.&lt;br /&gt;
	if not nsTable and type(ns) == &#039;string&#039; and not ns:find(&#039;[&amp;lt;&amp;gt;|%[%]{}]&#039;) then&lt;br /&gt;
		local nsStripped = ns:gsub(&#039;^[_%s]*:&#039;, &#039;&#039;)&lt;br /&gt;
		nsStripped = nsStripped:gsub(&#039;:.*$&#039;, &#039;&#039;)&lt;br /&gt;
		nsTable = mw.site.namespaces[nsStripped]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- If we still have no match then try the {{NAMESPACE}} parser function,&lt;br /&gt;
	-- which should catch the remainder of cases. Don&#039;t use a mw.title object,&lt;br /&gt;
	-- as this would increment the expensive function count for each new page&lt;br /&gt;
	-- tested.&lt;br /&gt;
	if not nsTable then&lt;br /&gt;
		frame = frame or mw.getCurrentFrame()&lt;br /&gt;
		local nsProcessed = frame:callParserFunction(&#039;NAMESPACE&#039;, ns)&lt;br /&gt;
		nsTable = nsProcessed and mw.site.namespaces[nsProcessed]&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return nsTable and nsTable.hasSubpages&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local ns = frame:getParent().args[1]&lt;br /&gt;
	if ns then&lt;br /&gt;
		ns = ns:match(&#039;^%s*(.-)%s*$&#039;) -- trim whitespace&lt;br /&gt;
		ns = tonumber(ns) or ns&lt;br /&gt;
	end&lt;br /&gt;
	local hasSubpages = p._main(ns, frame)&lt;br /&gt;
	return hasSubpages and &#039;yes&#039; or &#039;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Unsubst&amp;diff=305</id>
		<title>Module:Unsubst</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Unsubst&amp;diff=305"/>
		<updated>2024-07-31T17:35:08Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local checkType = require(&#039;libraryUtil&#039;).checkType&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local BODY_PARAM = &#039;$B&#039;&lt;br /&gt;
&lt;br /&gt;
local specialParams = {&lt;br /&gt;
	[&#039;$params&#039;] = &#039;parameter list&#039;,&lt;br /&gt;
	[&#039;$aliases&#039;] = &#039;parameter aliases&#039;,&lt;br /&gt;
	[&#039;$flags&#039;] = &#039;flags&#039;,&lt;br /&gt;
	[&#039;$B&#039;] = &#039;template content&#039;,&lt;br /&gt;
	[&#039;$template-name&#039;] = &#039;template invocation name override&#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function p.main(frame, body)&lt;br /&gt;
	-- If we are substing, this function returns a template invocation, and if&lt;br /&gt;
	-- not, it returns the template body. The template body can be specified in&lt;br /&gt;
	-- the body parameter, or in the template parameter defined in the&lt;br /&gt;
	-- BODY_PARAM variable. This function can be called from Lua or from&lt;br /&gt;
	-- #invoke.&lt;br /&gt;
&lt;br /&gt;
	-- Return the template body if we aren&#039;t substing.&lt;br /&gt;
	if not mw.isSubsting() then&lt;br /&gt;
		if body ~= nil then&lt;br /&gt;
			return body&lt;br /&gt;
		elseif frame.args[BODY_PARAM] ~= nil then&lt;br /&gt;
			return frame.args[BODY_PARAM]&lt;br /&gt;
		else&lt;br /&gt;
			error(string.format(&lt;br /&gt;
				&amp;quot;no template content specified (use parameter &#039;%s&#039; from #invoke)&amp;quot;,&lt;br /&gt;
				BODY_PARAM&lt;br /&gt;
			), 2)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Sanity check for the frame object.&lt;br /&gt;
	if type(frame) ~= &#039;table&#039;&lt;br /&gt;
		or type(frame.getParent) ~= &#039;function&#039;&lt;br /&gt;
		or not frame:getParent()&lt;br /&gt;
	then&lt;br /&gt;
		error(&lt;br /&gt;
			&amp;quot;argument #1 to &#039;main&#039; must be a frame object with a parent &amp;quot; ..&lt;br /&gt;
			&amp;quot;frame available&amp;quot;,&lt;br /&gt;
			2&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Find the invocation name.&lt;br /&gt;
	local mTemplateInvocation = require(&#039;Module:Template invocation&#039;)&lt;br /&gt;
	local name&lt;br /&gt;
&lt;br /&gt;
	if frame.args[&#039;$template-name&#039;] and &#039;&#039; ~= frame.args[&#039;$template-name&#039;] then&lt;br /&gt;
		name = frame.args[&#039;$template-name&#039;]										-- override whatever the template name is with this name&lt;br /&gt;
	else&lt;br /&gt;
		name = mTemplateInvocation.name(frame:getParent():getTitle())&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Combine passed args with passed defaults&lt;br /&gt;
	local args = {}&lt;br /&gt;
	if string.find( &#039;,&#039;..(frame.args[&#039;$flags&#039;] or &#039;&#039;)..&#039;,&#039;, &#039;,%s*override%s*,&#039; ) then&lt;br /&gt;
		for k, v in pairs( frame:getParent().args ) do&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
		for k, v in pairs( frame.args ) do&lt;br /&gt;
			if not specialParams[k] then&lt;br /&gt;
				if v == &#039;__DATE__&#039; then&lt;br /&gt;
					v = mw.getContentLanguage():formatDate( &#039;F Y&#039; )&lt;br /&gt;
				end&lt;br /&gt;
				args[k] = v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		for k, v in pairs( frame.args ) do&lt;br /&gt;
			if not specialParams[k] then&lt;br /&gt;
				if v == &#039;__DATE__&#039; then&lt;br /&gt;
					v = mw.getContentLanguage():formatDate( &#039;F Y&#039; )&lt;br /&gt;
				end&lt;br /&gt;
				args[k] = v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		for k, v in pairs( frame:getParent().args ) do&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Trim parameters, if not specified otherwise&lt;br /&gt;
	if not string.find( &#039;,&#039;..(frame.args[&#039;$flags&#039;] or &#039;&#039;)..&#039;,&#039;, &#039;,%s*keep%-whitespace%s*,&#039; ) then&lt;br /&gt;
		for k, v in pairs( args ) do args[k] = mw.ustring.match(v, &#039;^%s*(.*)%s*$&#039;) or &#039;&#039; end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Pull information from parameter aliases&lt;br /&gt;
	local aliases = {}&lt;br /&gt;
	if frame.args[&#039;$aliases&#039;] then&lt;br /&gt;
		local list = mw.text.split( frame.args[&#039;$aliases&#039;], &#039;%s*,%s*&#039; )&lt;br /&gt;
		for k, v in ipairs( list ) do&lt;br /&gt;
			local tmp = mw.text.split( v, &#039;%s*&amp;gt;%s*&#039; )&lt;br /&gt;
			aliases[tonumber(mw.ustring.match(tmp[1], &#039;^[1-9][0-9]*$&#039;)) or tmp[1]] = ((tonumber(mw.ustring.match(tmp[2], &#039;^[1-9][0-9]*$&#039;))) or tmp[2])&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for k, v in pairs( aliases ) do&lt;br /&gt;
		if args[k] and ( not args[v] or args[v] == &#039;&#039; ) then&lt;br /&gt;
			args[v] = args[k]&lt;br /&gt;
		end&lt;br /&gt;
		args[k] = nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Remove empty parameters, if specified&lt;br /&gt;
	if string.find( &#039;,&#039;..(frame.args[&#039;$flags&#039;] or &#039;&#039;)..&#039;,&#039;, &#039;,%s*remove%-empty%s*,&#039; ) then&lt;br /&gt;
		local tmp = 0&lt;br /&gt;
		for k, v in ipairs( args ) do&lt;br /&gt;
			if v ~= &#039;&#039; or ( args[k+1] and args[k+1] ~= &#039;&#039; ) or ( args[k+2] and args[k+2] ~= &#039;&#039; ) then&lt;br /&gt;
				tmp = k&lt;br /&gt;
			else&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		for k, v in pairs( args ) do&lt;br /&gt;
			if v == &#039;&#039; then&lt;br /&gt;
				if not (type(k) == &#039;number&#039; and k &amp;lt; tmp) then args[k] = nil end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Order parameters&lt;br /&gt;
	if frame.args[&#039;$params&#039;] then&lt;br /&gt;
		local params, tmp = mw.text.split( frame.args[&#039;$params&#039;], &#039;%s*,%s*&#039; ), {}&lt;br /&gt;
		for k, v in ipairs(params) do&lt;br /&gt;
			v = tonumber(mw.ustring.match(v, &#039;^[1-9][0-9]*$&#039;)) or v&lt;br /&gt;
			if args[v] then tmp[v], args[v] = args[v], nil end&lt;br /&gt;
		end&lt;br /&gt;
		for k, v in pairs(args) do tmp[k], args[k] = args[k], nil end&lt;br /&gt;
		args = tmp&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mTemplateInvocation.invocation(name, args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p[&#039;&#039;] = p.main -- For backwards compatibility&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Ns_has_subpages&amp;diff=303</id>
		<title>Modèle:Ns has subpages</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Ns_has_subpages&amp;diff=303"/>
		<updated>2024-07-31T17:35:08Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;#invoke:Ns has subpages|main}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Cite_web/doc&amp;diff=301</id>
		<title>Module:Cite web/doc</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Cite_web/doc&amp;diff=301"/>
		<updated>2024-07-31T17:35:08Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Module rating |release}}&lt;br /&gt;
{{High-use}}&lt;br /&gt;
&amp;lt;!-- Please place categories where indicated at the bottom of this page and interwikis at Wikidata (see [[Wikipedia:Wikidata]]) --&amp;gt;&lt;br /&gt;
{{Notice|This module should &#039;&#039;only&#039;&#039; be used on articles which are near the [[WP:PEIS|post-expand include size]] limit, in order to prevent them exceeding it. Unless there is a pressing technical need, use {{tl|{{BASEPAGENAME}}}} like normal.}}&lt;br /&gt;
{{Lua|Module:Citation/CS1}}&lt;br /&gt;
{{Infobox&lt;br /&gt;
|title       = {{cs1}} modules&lt;br /&gt;
|labelstyle  = width:50%; font-size:85%&lt;br /&gt;
|label10  = {{ml|Cite arXiv|}}&lt;br /&gt;
|data10   = [[arXiv]] preprints&lt;br /&gt;
|label20  = {{ml|Cite AV media|}}&lt;br /&gt;
|data20   = audio and visual media&lt;br /&gt;
|label30  = {{ml|Cite AV media notes|}}&lt;br /&gt;
|data30   = AV media liner notes&lt;br /&gt;
|label40  = {{ml|Cite bioRxiv|}}&lt;br /&gt;
|data40   = [[bioRxiv]] preprints&lt;br /&gt;
|label50  = {{ml|Cite book|}}&lt;br /&gt;
|data50   = books and chapters&lt;br /&gt;
|label60  = {{ml|Cite CiteSeerX|}}&lt;br /&gt;
|data60   = [[CiteSeerX]] papers&lt;br /&gt;
|label70  = {{ml|Cite conference|}}&lt;br /&gt;
|data70   = conference papers&lt;br /&gt;
|label75  = {{ml|cite document|}}&lt;br /&gt;
|data75   = short, stand-alone, offline documents&lt;br /&gt;
|label80  = {{ml|Cite encyclopedia|}}&lt;br /&gt;
|data80   = edited collections&lt;br /&gt;
|label90  = {{ml|Cite episode|}}&lt;br /&gt;
|data90   = radio or TV episodes&lt;br /&gt;
|label100 = {{ml|Cite interview|}}&lt;br /&gt;
|data100  = interviews&lt;br /&gt;
|label110 = {{ml|Cite journal|}}&lt;br /&gt;
|data110  = academic journals&lt;br /&gt;
|label120 = {{ml|Cite magazine|}}&lt;br /&gt;
|data120  = magazines, periodicals&lt;br /&gt;
|label130 = {{ml|Cite mailing list|}}&lt;br /&gt;
|data130  = public mailing lists&lt;br /&gt;
|label140 = {{ml|Cite map|}}&lt;br /&gt;
|data140  = maps&lt;br /&gt;
|label145 = {{ml|Cite medRxiv|}}&lt;br /&gt;
|data145  = [[medRxiv]] preprints&lt;br /&gt;
|label150 = {{ml|Cite news|}}&lt;br /&gt;
|data150  = news articles&lt;br /&gt;
|label160 = {{ml|Cite newsgroup|}}&lt;br /&gt;
|data160  = online newsgroups&lt;br /&gt;
|label170 = {{ml|Cite podcast|}}&lt;br /&gt;
|data170  = podcasts&lt;br /&gt;
|label180 = {{ml|Cite press release|}}&lt;br /&gt;
|data180  = press releases&lt;br /&gt;
|label190 = {{ml|Cite report|}}&lt;br /&gt;
|data190  = reports&lt;br /&gt;
|label200 = {{ml|Cite serial|}}&lt;br /&gt;
|data200  = audio or video serials&lt;br /&gt;
|label210 = {{ml|Cite sign|}}&lt;br /&gt;
|data210  = signs, plaques&lt;br /&gt;
|label220 = {{ml|Cite speech|}}&lt;br /&gt;
|data220  = speeches&lt;br /&gt;
|label230 = {{ml|Cite SSRN|}}&lt;br /&gt;
|data230  = [[Social Science Research Network|SSRN]] papers&lt;br /&gt;
|label240 = {{ml|Cite tech report|}}&lt;br /&gt;
|data240  = technical reports&lt;br /&gt;
|label250 = {{ml|Cite thesis|}}&lt;br /&gt;
|data250  = theses&lt;br /&gt;
|label260 = {{ml|Cite web|}}&lt;br /&gt;
|data260  = web sources not covered by the above&lt;br /&gt;
|label270 = See also&lt;br /&gt;
|data270  =&lt;br /&gt;
{{nowrap|&#039;&#039;[[:Category:Specific-source templates|Specific-source templates]]&#039;&#039;}}&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;[[:Category:Citation templates that wrap CS1 templates|Citation Style 1 wrapper templates]]&#039;&#039;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
This module may be placed directly on articles by replacing &amp;lt;code&amp;gt;{{((}}{{BASEPAGENAME}}|&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;{{((}}#invoke:{{BASEPAGENAME}}||&amp;lt;/code&amp;gt; (note the double pipe). This is likely to be unclear to other editors and should only be done to prevent pages exceeding the [[WP:PEIS|post-expand include size]] limit. It is also fine to use in templates that wrap {{tl|{{BASEPAGENAME}}}}.&lt;br /&gt;
&lt;br /&gt;
For the module that actually implements {{tl|{{BASEPAGENAME}}}}, see [[Module:Citation/CS1]].&lt;br /&gt;
&lt;br /&gt;
==TemplateData==&lt;br /&gt;
{{TemplateData header}}&lt;br /&gt;
{{#tag:templatedata|&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;description&amp;quot;: &amp;quot;This module is like {{((}}{{BASEPAGENAME}}{{))}} with two exceptions. It is only for use on pages with lots of citations (e.g. several hundred) where that is causing technical problems, and you must pass an empty first parameter. For all other usage information, see [[Template:{{BASEPAGENAME}}]].&amp;quot;,&lt;br /&gt;
&amp;quot;params&amp;quot;: { &amp;quot;1&amp;quot;: {&lt;br /&gt;
  &amp;quot;label&amp;quot;: &amp;quot;Required blank parameter&amp;quot;&lt;br /&gt;
} }&lt;br /&gt;
} }}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;includeonly&amp;gt;{{#ifeq:{{SUBPAGENAME}}|sandbox | |&lt;br /&gt;
&amp;lt;!-- Categories below this line, please; interwikis at Wikidata --&amp;gt;&lt;br /&gt;
[[Category:Templates based on the Citation/CS1 Lua module]]&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Module_link&amp;diff=299</id>
		<title>Modèle:Module link</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Module_link&amp;diff=299"/>
		<updated>2024-07-31T17:35:07Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;amp;#123;&amp;amp;#123;{{{{{|safesubst:}}}#invoke:Separated entries|main|[[Module:{{{1}}}{{{section|}}}|#invoke:{{{1}}}]]|{{{2|&#039;&#039;function&#039;&#039;}}}|separator=&amp;amp;#124;}}&amp;amp;#125;&amp;amp;#125;&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;{{documentation}}&amp;lt;!-- Categories go on the /doc subpage and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Ml&amp;diff=297</id>
		<title>Modèle:Ml</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Ml&amp;diff=297"/>
		<updated>2024-07-31T17:35:07Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Template:Module link]]&lt;br /&gt;
&lt;br /&gt;
{{Redirect category shell|&lt;br /&gt;
{{R from move}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Lua&amp;diff=295</id>
		<title>Modèle:Lua</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Lua&amp;diff=295"/>
		<updated>2024-07-31T17:35:07Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{#invoke:Lua banner|main}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Lua|Module:Lua banner}}&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Lua_banner&amp;diff=293</id>
		<title>Module:Lua banner</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Lua_banner&amp;diff=293"/>
		<updated>2024-07-31T17:35:07Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module implements the {{lua}} template.&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
local mList = require(&#039;Module:List&#039;)&lt;br /&gt;
local mTableTools = require(&#039;Module:TableTools&#039;)&lt;br /&gt;
local mMessageBox = require(&#039;Module:Message box&#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local origArgs = frame:getParent().args&lt;br /&gt;
	local args = {}&lt;br /&gt;
	for k, v in pairs(origArgs) do&lt;br /&gt;
		v = v:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
		if v ~= &#039;&#039; then&lt;br /&gt;
			args[k] = v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local modules = mTableTools.compressSparseArray(args)&lt;br /&gt;
	local box = p.renderBox(modules)&lt;br /&gt;
	local trackingCategories = p.renderTrackingCategories(args, modules)&lt;br /&gt;
	return box .. trackingCategories&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderBox(modules)&lt;br /&gt;
	local boxArgs = {}&lt;br /&gt;
	if #modules &amp;lt; 1 then&lt;br /&gt;
		boxArgs.text = &#039;&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Error: no modules specified&amp;lt;/strong&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		local moduleLinks = {}&lt;br /&gt;
		for i, module in ipairs(modules) do&lt;br /&gt;
			moduleLinks[i] = string.format(&#039;[[:%s]]&#039;, module)&lt;br /&gt;
			local maybeSandbox = mw.title.new(module .. &#039;/sandbox&#039;)&lt;br /&gt;
			if maybeSandbox and maybeSandbox.exists then&lt;br /&gt;
				moduleLinks[i] = moduleLinks[i] .. string.format(&#039; ([[:%s|sandbox]])&#039;, maybeSandbox.fullText)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local moduleList = mList.makeList(&#039;bulleted&#039;, moduleLinks)&lt;br /&gt;
		local title = mw.title.getCurrentTitle()&lt;br /&gt;
		if title.subpageText == &amp;quot;doc&amp;quot; then&lt;br /&gt;
			title = title.basePageTitle&lt;br /&gt;
		end&lt;br /&gt;
		if title.contentModel == &amp;quot;Scribunto&amp;quot; then&lt;br /&gt;
			boxArgs.text = &#039;This module depends on the following other modules:&#039; .. moduleList&lt;br /&gt;
		else&lt;br /&gt;
			boxArgs.text = &#039;This template  uses [[Wikipedia:Lua|Lua]]:\n&#039; .. moduleList&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	boxArgs.type = &#039;notice&#039;&lt;br /&gt;
	boxArgs.small = true&lt;br /&gt;
	boxArgs.image = &#039;[[File:Lua-Logo.svg|30px|alt=|link=]]&#039;&lt;br /&gt;
	return mMessageBox.main(&#039;mbox&#039;, boxArgs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.renderTrackingCategories(args, modules, titleObj)&lt;br /&gt;
	if yesno(args.nocat) then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local cats = {}&lt;br /&gt;
&lt;br /&gt;
	-- Error category&lt;br /&gt;
	if #modules &amp;lt; 1 then&lt;br /&gt;
		cats[#cats + 1] = &#039;Lua templates with errors&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Lua templates category&lt;br /&gt;
	titleObj = titleObj or mw.title.getCurrentTitle()&lt;br /&gt;
	local subpageBlacklist = {&lt;br /&gt;
		doc = true,&lt;br /&gt;
		sandbox = true,&lt;br /&gt;
		sandbox2 = true,&lt;br /&gt;
		testcases = true&lt;br /&gt;
	}&lt;br /&gt;
	if not subpageBlacklist[titleObj.subpageText] then&lt;br /&gt;
		local protCatName&lt;br /&gt;
		if titleObj.namespace == 10 then&lt;br /&gt;
			local category = args.category&lt;br /&gt;
			if not category then&lt;br /&gt;
				local categories = {&lt;br /&gt;
					[&#039;Module:String&#039;] = &#039;Templates based on the String Lua module&#039;,&lt;br /&gt;
					[&#039;Module:Math&#039;] = &#039;Templates based on the Math Lua module&#039;,&lt;br /&gt;
					[&#039;Module:BaseConvert&#039;] = &#039;Templates based on the BaseConvert Lua module&#039;,&lt;br /&gt;
					[&#039;Module:Citation/CS1&#039;] = &#039;Templates based on the Citation/CS1 Lua module&#039;&lt;br /&gt;
				}&lt;br /&gt;
				category = modules[1] and categories[modules[1]]&lt;br /&gt;
				category = category or &#039;Lua-based templates&#039;&lt;br /&gt;
			end	&lt;br /&gt;
			cats[#cats + 1] = category&lt;br /&gt;
			protCatName = &amp;quot;Templates using under-protected Lua modules&amp;quot;&lt;br /&gt;
		elseif titleObj.namespace == 828 then&lt;br /&gt;
			protCatName = &amp;quot;Modules depending on under-protected modules&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		if not args.noprotcat and protCatName then&lt;br /&gt;
			local protLevels = {&lt;br /&gt;
				autoconfirmed = 1,&lt;br /&gt;
				extendedconfirmed = 2,&lt;br /&gt;
				templateeditor = 3,&lt;br /&gt;
				sysop = 4&lt;br /&gt;
			}&lt;br /&gt;
			local currentProt&lt;br /&gt;
			if titleObj.id ~= 0 then&lt;br /&gt;
				-- id is 0 (page does not exist) if am previewing before creating a template.&lt;br /&gt;
				currentProt = titleObj.protectionLevels[&amp;quot;edit&amp;quot;][1]&lt;br /&gt;
			end&lt;br /&gt;
			if currentProt == nil then currentProt = 0 else currentProt = protLevels[currentProt] end&lt;br /&gt;
			for i, module in ipairs(modules) do&lt;br /&gt;
				if module ~= &amp;quot;WP:libraryUtil&amp;quot; then&lt;br /&gt;
					local moduleTitle = mw.title.new(module)&lt;br /&gt;
					local moduleProt = moduleTitle and moduleTitle.protectionLevels[&amp;quot;edit&amp;quot;][1]&lt;br /&gt;
					if moduleProt == nil then moduleProt = 0 else moduleProt = protLevels[moduleProt] end&lt;br /&gt;
					if moduleProt &amp;lt; currentProt then&lt;br /&gt;
						cats[#cats + 1] = protCatName&lt;br /&gt;
						break&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i, cat in ipairs(cats) do&lt;br /&gt;
		cats[i] = string.format(&#039;[[Category:%s]]&#039;, cat)&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(cats)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_parameter_usage&amp;diff=291</id>
		<title>Modèle:Template parameter usage</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_parameter_usage&amp;diff=291"/>
		<updated>2024-07-31T17:35:07Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#switch:{{{label|}}}&lt;br /&gt;
 |=[https://bambots.brucemyers.com/TemplateParam.php?wiki=enwiki&amp;amp;template={{Urlencode:{{#if:{{{1|}}}|{{ROOTPAGENAME:{{{1|}}}}}|{{ROOTPAGENAME}}}}}} {{#ifeq:{{yesno-no|{{{lc}}}}}|no|S|s}}ee a monthly parameter usage report] for {{#if:{{{1|}}}|[[Template:{{ROOTPAGENAME:{{{1|}}}}}]]|this template}} in articles{{#ifeq:{{yesno-no|{{{based}}}}}|yes|&amp;amp;#32;based on {{#if:{{{1|}}}|its|this}} TemplateData}}.&lt;br /&gt;
 |None|none=[https://bambots.brucemyers.com/TemplateParam.php?wiki=enwiki&amp;amp;template={{Urlencode:{{#if:{{{1|}}}|{{ROOTPAGENAME:{{{1|}}}}}|{{ROOTPAGENAME}}}}}} {{#ifeq:{{yesno-no|{{{lc}}}}}|no|P|p}}arameter usage report]{{#ifeq:{{yesno-no|{{{based}}}}}|yes|&amp;amp;#32;based on {{#if:{{{1|}}}|its|this}} TemplateData}}&lt;br /&gt;
 |for|For=[https://bambots.brucemyers.com/TemplateParam.php?wiki=enwiki&amp;amp;template={{Urlencode:{{#if:{{{1|}}}|{{ROOTPAGENAME:{{{1|}}}}}|{{ROOTPAGENAME}}}}}} {{#ifeq:{{yesno-no|{{{lc}}}}}|no|P|p}}arameter usage report] for {{#if:{{{1|}}}|[[Template:{{ROOTPAGENAME:{{{1|}}}}}]]|[[Template:{{ROOTPAGENAME}}]]}}{{#ifeq:{{yesno-no|{{{based}}}}}|yes|&amp;amp;#32;based on {{#if:{{{1|}}}|its|this}} TemplateData}}.&lt;br /&gt;
 |#default=[https://bambots.brucemyers.com/TemplateParam.php?wiki=enwiki&amp;amp;template={{Urlencode:{{#if:{{{1|}}}|{{ROOTPAGENAME:{{{1|}}}}}|{{ROOTPAGENAME}}}}}} {{{label|}}}]{{#ifeq:{{yesno-no|{{{based}}}}}|yes|&amp;amp;#32;based on {{#if:{{{1|}}}|its|this}} TemplateData}}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:TemplateData_header&amp;diff=289</id>
		<title>Modèle:TemplateData header</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:TemplateData_header&amp;diff=289"/>
		<updated>2024-07-31T17:35:07Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;templatedata-header&amp;quot;&amp;gt;{{#if:{{{noheader|}}}|&amp;lt;!--&lt;br /&gt;
 noheader:&lt;br /&gt;
--&amp;gt;{{Template parameter usage|{{{1|{{BASEPAGENAME}}}}}|based=y}}|&amp;lt;!--&lt;br /&gt;
 +header:&lt;br /&gt;
--&amp;gt;This is the {{#if:{{{nolink|}}}|&amp;lt;!--&lt;br /&gt;
  +header, nolink TD&lt;br /&gt;
  --&amp;gt;TemplateData|&amp;lt;!--&lt;br /&gt;
  +header,  +link [[TD]]; DEFAULT:&lt;br /&gt;
--&amp;gt;[[Wikipedia:TemplateData|TemplateData]]}}&amp;lt;!--&lt;br /&gt;
   e.o. #if:nolink; DEFAULT:&lt;br /&gt;
--&amp;gt; for this template used by [[mw:Extension:TemplateWizard|TemplateWizard]], [[Wikipedia:VisualEditor|VisualEditor]] and other tools. {{Template parameter usage|{{{1|{{BASEPAGENAME}}}}}|based=y}}&amp;lt;!--&lt;br /&gt;
   e.o. #if:noheader&lt;br /&gt;
--&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TemplateData for {{{1|{{BASEPAGENAME}}}}}&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
 check parameters&lt;br /&gt;
--&amp;gt;{{#invoke:Check for unknown parameters|check&lt;br /&gt;
|unknown={{template other|1=[[Category:Pages using TemplateData header with unknown parameters|_VALUE_]]}}&lt;br /&gt;
|template=Template:TemplateData header&lt;br /&gt;
|1 |nolink |noheader&lt;br /&gt;
|preview=&amp;lt;div class=&amp;quot;error&amp;quot; style=&amp;quot;font-weight:normal&amp;quot;&amp;gt;Unknown parameter &#039;_VALUE_&#039; in [[Template:TemplateData header]].&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&amp;lt;!--&lt;br /&gt;
--&amp;gt;{{template other|{{sandbox other||&lt;br /&gt;
[[Category:Templates using TemplateData]]&lt;br /&gt;
&lt;br /&gt;
}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;!--&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&amp;lt;noinclude&amp;gt;{{Documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:))&amp;diff=287</id>
		<title>Modèle:))</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:))&amp;diff=287"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:((&amp;diff=285</id>
		<title>Modèle:((</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:((&amp;diff=285"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Notice&amp;diff=283</id>
		<title>Modèle:Notice</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Notice&amp;diff=283"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Mbox&lt;br /&gt;
| name       = Notice&lt;br /&gt;
| demospace  = {{{demospace|}}}&lt;br /&gt;
| style      = {{#if:{{{style|}}} |{{{style}}} }}&lt;br /&gt;
| subst      = &amp;lt;includeonly&amp;gt;{{subst:substcheck}}&amp;lt;/includeonly&amp;gt;&lt;br /&gt;
| type       = notice&lt;br /&gt;
| image      = {{#if:{{{image|}}} |[[File:{{{image}}}|40px|Notice|alt={{{imagealt|}}}]]}}&lt;br /&gt;
| small      = {{{small|}}}&lt;br /&gt;
| smallimage = {{#if:{{{image|}}} |[[File:{{{image}}}|30px|Notice|alt={{{imagealt|}}}]]}}&lt;br /&gt;
| imageright = {{#if:{{{imageright|}}} |{{{imageright}}} |{{#if:{{{shortcut|{{{shortcut1|}}}}}} |{{Ombox/shortcut|{{{shortcut|{{{shortcut1|}}}}}}|{{{shortcut2|}}}|{{{shortcut3|}}}|{{{shortcut4|}}}|{{{shortcut5|}}}}}}} }}&lt;br /&gt;
| textstyle  = {{{textstyle|text-align: {{#if:{{{center|}}}|center|{{{align|left}}}}};}}}&lt;br /&gt;
| text       = {{#if:{{{header|{{{heading|{{{title|}}}}}}}}} |&amp;lt;div style=&amp;quot;{{{headstyle|text-align: {{#if:{{{center|}}}|center|left}};}}}&amp;quot;&amp;gt;&#039;&#039;&#039;{{{header|{{{heading|{{{title|}}}}}}}}}&#039;&#039;&#039;&amp;lt;/div&amp;gt;}}&amp;lt;!--&lt;br /&gt;
            --&amp;gt;{{{text|{{{content|{{{reason|{{{1}}}}}}}}}}}}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Yesno-no&amp;diff=281</id>
		<title>Modèle:Yesno-no</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Yesno-no&amp;diff=281"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{safesubst:&amp;lt;noinclude /&amp;gt;yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|no}}}|¬={{{¬|no}}}|def={{{def|no}}}}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation|Template:Yesno/doc}}&lt;br /&gt;
&amp;lt;!--Categories go in the doc page referenced above; interwikis go in Wikidata.--&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_other&amp;diff=279</id>
		<title>Modèle:Template other</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_other&amp;diff=279"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#switch:&lt;br /&gt;
  &amp;lt;!--If no or empty &amp;quot;demospace&amp;quot; parameter then detect namespace--&amp;gt;&lt;br /&gt;
  {{#if:{{{demospace|}}}&lt;br /&gt;
  | {{lc: {{{demospace}}} }}    &amp;lt;!--Use lower case &amp;quot;demospace&amp;quot;--&amp;gt;&lt;br /&gt;
  | {{#ifeq:{{NAMESPACE}}|{{ns:Template}}&lt;br /&gt;
    | template&lt;br /&gt;
    | other&lt;br /&gt;
    }}&lt;br /&gt;
  }}&lt;br /&gt;
| template = {{{1|}}}&lt;br /&gt;
| other&lt;br /&gt;
| #default = {{{2|}}}&lt;br /&gt;
}}&amp;lt;!--End switch--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Infobox&amp;diff=277</id>
		<title>Modèle:Infobox</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Infobox&amp;diff=277"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:Infobox|infobox}}&amp;lt;includeonly&amp;gt;{{template other|{{#ifeq:{{PAGENAME}}|Infobox||{{#ifeq:{{str left|{{SUBPAGENAME}}|7}}|Infobox|[[Category:Infobox templates|{{remove first word|{{SUBPAGENAME}}}}]]}}}}|}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go in the /doc subpage, and interwikis go in Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Separated_entries&amp;diff=275</id>
		<title>Module:Separated entries</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Separated_entries&amp;diff=275"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module takes positional parameters as input and concatenates them with&lt;br /&gt;
-- an optional separator. The final separator (the &amp;quot;conjunction&amp;quot;) can be&lt;br /&gt;
-- specified independently, enabling natural-language lists like&lt;br /&gt;
-- &amp;quot;foo, bar, baz and qux&amp;quot;. The starting parameter can also be specified.&lt;br /&gt;
&lt;br /&gt;
local compressSparseArray = require(&#039;Module:TableTools&#039;).compressSparseArray&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local separator = args.separator&lt;br /&gt;
		-- Decode (convert to Unicode) HTML escape sequences, such as &amp;quot;&amp;amp;#32;&amp;quot; for space.&lt;br /&gt;
		and mw.text.decode(args.separator) or &#039;&#039;&lt;br /&gt;
	local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator&lt;br /&gt;
	-- Discard values before the starting parameter.&lt;br /&gt;
	local start = tonumber(args.start)&lt;br /&gt;
	if start then&lt;br /&gt;
		for i = 1, start - 1 do args[i] = nil end&lt;br /&gt;
	end&lt;br /&gt;
	-- Discard named parameters.&lt;br /&gt;
	local values = compressSparseArray(args)&lt;br /&gt;
	return mw.text.listToText(values, separator, conjunction)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function makeInvokeFunction(separator, conjunction, first)&lt;br /&gt;
	return function (frame)&lt;br /&gt;
		local args = require(&#039;Module:Arguments&#039;).getArgs(frame)&lt;br /&gt;
		args.separator = separator or args.separator&lt;br /&gt;
		args.conjunction = conjunction or args.conjunction&lt;br /&gt;
		args.first = first or args.first&lt;br /&gt;
		return p._main(args)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.main = makeInvokeFunction()&lt;br /&gt;
p.br = makeInvokeFunction(&#039;&amp;lt;br /&amp;gt;&#039;)&lt;br /&gt;
p.comma = makeInvokeFunction(mw.message.new(&#039;comma-separator&#039;):plain())&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Infobox/styles.css&amp;diff=273</id>
		<title>Module:Infobox/styles.css</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Infobox/styles.css&amp;diff=273"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* {{pp|small=y}} */&lt;br /&gt;
/*&lt;br /&gt;
 * This TemplateStyles sheet deliberately does NOT include the full set of&lt;br /&gt;
 * infobox styles. We are still working to migrate all of the manual&lt;br /&gt;
 * infoboxes. See [[MediaWiki talk:Common.css/to do#Infobox]]&lt;br /&gt;
 * DO NOT ADD THEM HERE&lt;br /&gt;
 */&lt;br /&gt;
/*&lt;br /&gt;
 * not strictly certain these styles are necessary since the modules now&lt;br /&gt;
 * exclusively output infobox-subbox or infobox, not both&lt;br /&gt;
 * just replicating the module faithfully&lt;br /&gt;
 */&lt;br /&gt;
.infobox-subbox {&lt;br /&gt;
	padding: 0;&lt;br /&gt;
	border: none;&lt;br /&gt;
	margin: -3px;&lt;br /&gt;
	width: auto;&lt;br /&gt;
	min-width: 100%;&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
	clear: none;&lt;br /&gt;
	float: none;&lt;br /&gt;
	background-color: transparent;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox-3cols-child {&lt;br /&gt;
	margin: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.infobox .navbar {&lt;br /&gt;
	font-size: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* T281642 */&lt;br /&gt;
body.skin-minerva .infobox-header,&lt;br /&gt;
body.skin-minerva .infobox-subheader,&lt;br /&gt;
body.skin-minerva  .infobox-above,&lt;br /&gt;
body.skin-minerva .infobox-title,&lt;br /&gt;
body.skin-minerva  .infobox-image,&lt;br /&gt;
body.skin-minerva  .infobox-full-data,&lt;br /&gt;
body.skin-minerva .infobox-below {&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Dark theme: [[William_Wragg]], [[Coral_Castle]] */&lt;br /&gt;
html.skin-theme-clientpref-night .infobox-full-data:not(.notheme) &amp;gt; div:not(.notheme)[style] {&lt;br /&gt;
    background: #1f1f23 !important;&lt;br /&gt;
      /* switch with var( --color-base ) when supported. */&lt;br /&gt;
      color: #f8f9fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (prefers-color-scheme: dark) {&lt;br /&gt;
    html.skin-theme-clientpref-os .infobox-full-data:not(.notheme) div:not(.notheme) {&lt;br /&gt;
      background: #1f1f23 !important;&lt;br /&gt;
      /* switch with var( --color-base ) when supported. */&lt;br /&gt;
      color: #f8f9fa;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Since infobox is a table, many infobox templates take advantage of this to add columns and rows to the infobox itself rather than as part of a new table inside them. This class should be discouraged and removed on the long term, but allows us to at least identify these tables going forward&lt;br /&gt;
Currently in use on: [[Module:Infobox3cols]]&lt;br /&gt;
Fixes issue described in https://phabricator.wikimedia.org/F55300125 on Vector 2022.&lt;br /&gt;
*/&lt;br /&gt;
@media (min-width: 640px) {&lt;br /&gt;
  body.skin--responsive .infobox-table {&lt;br /&gt;
    display: table !important;&lt;br /&gt;
  }&lt;br /&gt;
  body.skin--responsive .infobox-table &amp;gt; caption {&lt;br /&gt;
    display: table-caption !important;&lt;br /&gt;
  }&lt;br /&gt;
  body.skin--responsive .infobox-table &amp;gt; tbody {&lt;br /&gt;
    display: table-row-group;&lt;br /&gt;
  }&lt;br /&gt;
  body.skin--responsive .infobox-table tr {&lt;br /&gt;
    display: table-row !important;&lt;br /&gt;
  }&lt;br /&gt;
  body.skin--responsive .infobox-table th,&lt;br /&gt;
  body.skin--responsive .infobox-table td {&lt;br /&gt;
    padding-left: inherit;&lt;br /&gt;
    padding-right: inherit;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Infobox&amp;diff=271</id>
		<title>Module:Infobox</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Infobox&amp;diff=271"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
local args = {}&lt;br /&gt;
local origArgs = {}&lt;br /&gt;
local root&lt;br /&gt;
local empty_row_categories = {}&lt;br /&gt;
local category_in_empty_row_pattern = &#039;%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]&#039;&lt;br /&gt;
local has_rows = false&lt;br /&gt;
local lists = {&lt;br /&gt;
	plainlist_t = {&lt;br /&gt;
		patterns = {&lt;br /&gt;
			&#039;^plainlist$&#039;,&lt;br /&gt;
			&#039;%splainlist$&#039;,&lt;br /&gt;
			&#039;^plainlist%s&#039;,&lt;br /&gt;
			&#039;%splainlist%s&#039;&lt;br /&gt;
		},&lt;br /&gt;
		found = false,&lt;br /&gt;
		styles = &#039;Plainlist/styles.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	hlist_t = {&lt;br /&gt;
		patterns = {&lt;br /&gt;
			&#039;^hlist$&#039;,&lt;br /&gt;
			&#039;%shlist$&#039;,&lt;br /&gt;
			&#039;^hlist%s&#039;,&lt;br /&gt;
			&#039;%shlist%s&#039;&lt;br /&gt;
		},&lt;br /&gt;
		found = false,&lt;br /&gt;
		styles = &#039;Hlist/styles.css&#039;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function has_list_class(args_to_check)&lt;br /&gt;
	for _, list in pairs(lists) do&lt;br /&gt;
		if not list.found then&lt;br /&gt;
			for _, arg in pairs(args_to_check) do&lt;br /&gt;
				for _, pattern in ipairs(list.patterns) do&lt;br /&gt;
					if mw.ustring.find(arg or &#039;&#039;, pattern) then&lt;br /&gt;
						list.found = true&lt;br /&gt;
						break&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				if list.found then break end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function fixChildBoxes(sval, tt)&lt;br /&gt;
	local function notempty( s ) return s and s:match( &#039;%S&#039; ) end&lt;br /&gt;
	&lt;br /&gt;
	if notempty(sval) then&lt;br /&gt;
		local marker = &#039;&amp;lt;span class=special_infobox_marker&amp;gt;&#039;&lt;br /&gt;
		local s = sval&lt;br /&gt;
		-- start moving templatestyles and categories inside of table rows&lt;br /&gt;
		local slast = &#039;&#039;&lt;br /&gt;
		while slast ~= s do&lt;br /&gt;
			slast = s&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Tt][Rr]%s*&amp;gt;%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])&#039;, &#039;%2%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Tt][Rr]%s*&amp;gt;%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)&#039;, &#039;%2%1&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		-- end moving templatestyles and categories inside of table rows&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;(&amp;lt;%s*[Tt][Rr])&#039;, marker .. &#039;%1&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Tt][Rr]%s*&amp;gt;)&#039;, &#039;%1&#039; .. marker)&lt;br /&gt;
		if s:match(marker) then&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;%s*&#039; .. marker, &#039;&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;([\r\n]|-[^\r\n]*[\r\n])%s*&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;%s*([\r\n]|-)&#039;, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;/[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*&amp;gt;%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;(&amp;lt;%s*[Tt][Aa][Bb][Ll][Ee][^&amp;lt;&amp;gt;]*&amp;gt;%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;^(%{|[^\r\n]*[\r\n]%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, &#039;([\r\n]%{|[^\r\n]*[\r\n]%s*)&#039; .. marker, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;(%s*&amp;lt;/[Tt][Aa][Bb][Ll][Ee]%s*&amp;gt;)&#039;, &#039;%1&#039;)&lt;br /&gt;
			s = mw.ustring.gsub(s, marker .. &#039;(%s*\n|%})&#039;, &#039;%1&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		if s:match(marker) then&lt;br /&gt;
			local subcells = mw.text.split(s, marker)&lt;br /&gt;
			s = &#039;&#039;&lt;br /&gt;
			for k = 1, #subcells do&lt;br /&gt;
				if k == 1 then&lt;br /&gt;
					s = s .. subcells[k] .. &#039;&amp;lt;/&#039; .. tt .. &#039;&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
				elseif k == #subcells then&lt;br /&gt;
					local rowstyle = &#039; style=&amp;quot;display:none&amp;quot;&#039;&lt;br /&gt;
					if notempty(subcells[k]) then rowstyle = &#039;&#039;	end&lt;br /&gt;
					s = s .. &#039;&amp;lt;tr&#039; .. rowstyle ..&#039;&amp;gt;&amp;lt;&#039; .. tt .. &#039; colspan=2&amp;gt;\n&#039; ..&lt;br /&gt;
						subcells[k]&lt;br /&gt;
				elseif notempty(subcells[k]) then&lt;br /&gt;
					if (k % 2) == 0 then&lt;br /&gt;
						s = s .. subcells[k]&lt;br /&gt;
					else&lt;br /&gt;
						s = s .. &#039;&amp;lt;tr&amp;gt;&amp;lt;&#039; .. tt .. &#039; colspan=2&amp;gt;\n&#039; ..&lt;br /&gt;
							subcells[k] .. &#039;&amp;lt;/&#039; .. tt .. &#039;&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		-- the next two lines add a newline at the end of lists for the PHP parser&lt;br /&gt;
		-- [[Special:Diff/849054481]]&lt;br /&gt;
		-- remove when [[:phab:T191516]] is fixed or OBE&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;([\r\n][%*#;:][^\r\n]*)$&#039;, &#039;%1\n&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;^([%*#;:][^\r\n]*)$&#039;, &#039;%1\n&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;^([%*#;:])&#039;, &#039;\n%1&#039;)&lt;br /&gt;
		s = mw.ustring.gsub(s, &#039;^(%{%|)&#039;, &#039;\n%1&#039;)&lt;br /&gt;
		return s&lt;br /&gt;
	else&lt;br /&gt;
		return sval&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Cleans empty tables&lt;br /&gt;
local function cleanInfobox()&lt;br /&gt;
	root = tostring(root)&lt;br /&gt;
	if has_rows == false then&lt;br /&gt;
		root = mw.ustring.gsub(root, &#039;&amp;lt;table[^&amp;lt;&amp;gt;]*&amp;gt;%s*&amp;lt;/table&amp;gt;&#039;, &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns the union of the values of two tables, as a sequence.&lt;br /&gt;
local function union(t1, t2)&lt;br /&gt;
&lt;br /&gt;
	local vals = {}&lt;br /&gt;
	for k, v in pairs(t1) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	for k, v in pairs(t2) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k, v in pairs(vals) do&lt;br /&gt;
		table.insert(ret, k)&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns a table containing the numbers of the arguments that exist&lt;br /&gt;
-- for the specified prefix. For example, if the prefix was &#039;data&#039;, and&lt;br /&gt;
-- &#039;data1&#039;, &#039;data2&#039;, and &#039;data5&#039; exist, it would return {1, 2, 5}.&lt;br /&gt;
local function getArgNums(prefix)&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		local num = tostring(k):match(&#039;^&#039; .. prefix .. &#039;([1-9]%d*)$&#039;)&lt;br /&gt;
		if num then table.insert(nums, tonumber(num)) end&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(nums)&lt;br /&gt;
	return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Adds a row to the infobox, with either a header cell&lt;br /&gt;
-- or a label/data cell combination.&lt;br /&gt;
local function addRow(rowArgs)&lt;br /&gt;
	&lt;br /&gt;
	if rowArgs.header and rowArgs.header ~= &#039;_BLANK_&#039; then&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass })&lt;br /&gt;
		&lt;br /&gt;
		root&lt;br /&gt;
			:tag(&#039;tr&#039;)&lt;br /&gt;
				:addClass(rowArgs.rowclass)&lt;br /&gt;
				:cssText(rowArgs.rowstyle)&lt;br /&gt;
				:tag(&#039;th&#039;)&lt;br /&gt;
					:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
					:addClass(&#039;infobox-header&#039;)&lt;br /&gt;
					:addClass(rowArgs.class)&lt;br /&gt;
					:addClass(args.headerclass)&lt;br /&gt;
					-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-header&lt;br /&gt;
					:cssText(args.headerstyle)&lt;br /&gt;
					:cssText(rowArgs.rowcellstyle)&lt;br /&gt;
					:wikitext(fixChildBoxes(rowArgs.header, &#039;th&#039;))&lt;br /&gt;
		if rowArgs.data then&lt;br /&gt;
			root:wikitext(&lt;br /&gt;
				&#039;[[Category:Pages using infobox templates with ignored data cells]]&#039;&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;^%S&#039;) then&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ rowArgs.rowclass, rowArgs.class })&lt;br /&gt;
		&lt;br /&gt;
		local row = root:tag(&#039;tr&#039;)&lt;br /&gt;
		row:addClass(rowArgs.rowclass)&lt;br /&gt;
		row:cssText(rowArgs.rowstyle)&lt;br /&gt;
		if rowArgs.label then&lt;br /&gt;
			row&lt;br /&gt;
				:tag(&#039;th&#039;)&lt;br /&gt;
					:attr(&#039;scope&#039;, &#039;row&#039;)&lt;br /&gt;
					:addClass(&#039;infobox-label&#039;)&lt;br /&gt;
					-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-label&lt;br /&gt;
					:cssText(args.labelstyle)&lt;br /&gt;
					:cssText(rowArgs.rowcellstyle)&lt;br /&gt;
					:wikitext(rowArgs.label)&lt;br /&gt;
					:done()&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local dataCell = row:tag(&#039;td&#039;)&lt;br /&gt;
		dataCell&lt;br /&gt;
			:attr(&#039;colspan&#039;, not rowArgs.label and &#039;2&#039; or nil)&lt;br /&gt;
			:addClass(not rowArgs.label and &#039;infobox-full-data&#039; or &#039;infobox-data&#039;)&lt;br /&gt;
			:addClass(rowArgs.class)&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox(-full)-data&lt;br /&gt;
			:cssText(rowArgs.datastyle)&lt;br /&gt;
			:cssText(rowArgs.rowcellstyle)&lt;br /&gt;
			:wikitext(fixChildBoxes(rowArgs.data, &#039;td&#039;))&lt;br /&gt;
	else&lt;br /&gt;
		table.insert(empty_row_categories, rowArgs.data or &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderTitle()&lt;br /&gt;
	if not args.title then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	has_list_class({args.titleclass})&lt;br /&gt;
	&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;caption&#039;)&lt;br /&gt;
			:addClass(&#039;infobox-title&#039;)&lt;br /&gt;
			:addClass(args.titleclass)&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-title&lt;br /&gt;
			:cssText(args.titlestyle)&lt;br /&gt;
			:wikitext(args.title)&lt;br /&gt;
	&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderAboveRow()&lt;br /&gt;
	if not args.above then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	has_list_class({ args.aboveclass })&lt;br /&gt;
	&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;th&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;infobox-above&#039;)&lt;br /&gt;
				:addClass(args.aboveclass)&lt;br /&gt;
				-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-above&lt;br /&gt;
				:cssText(args.abovestyle)&lt;br /&gt;
				:wikitext(fixChildBoxes(args.above,&#039;th&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderBelowRow()&lt;br /&gt;
	if not args.below then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	has_list_class({ args.belowclass })&lt;br /&gt;
	&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;td&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;infobox-below&#039;)&lt;br /&gt;
				:addClass(args.belowclass)&lt;br /&gt;
				-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-below&lt;br /&gt;
				:cssText(args.belowstyle)&lt;br /&gt;
				:wikitext(fixChildBoxes(args.below,&#039;td&#039;))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function addSubheaderRow(subheaderArgs)&lt;br /&gt;
	if subheaderArgs.data and&lt;br /&gt;
		subheaderArgs.data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;^%S&#039;) then&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ subheaderArgs.rowclass, subheaderArgs.class })&lt;br /&gt;
		&lt;br /&gt;
		local row = root:tag(&#039;tr&#039;)&lt;br /&gt;
		row:addClass(subheaderArgs.rowclass)&lt;br /&gt;
&lt;br /&gt;
		local dataCell = row:tag(&#039;td&#039;)&lt;br /&gt;
		dataCell&lt;br /&gt;
			:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
			:addClass(&#039;infobox-subheader&#039;)&lt;br /&gt;
			:addClass(subheaderArgs.class)&lt;br /&gt;
			:cssText(subheaderArgs.datastyle)&lt;br /&gt;
			:cssText(subheaderArgs.rowcellstyle)&lt;br /&gt;
			:wikitext(fixChildBoxes(subheaderArgs.data, &#039;td&#039;))&lt;br /&gt;
	else&lt;br /&gt;
		table.insert(empty_row_categories, subheaderArgs.data or &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderSubheaders()&lt;br /&gt;
	if args.subheader then&lt;br /&gt;
		args.subheader1 = args.subheader&lt;br /&gt;
	end&lt;br /&gt;
	if args.subheaderrowclass then&lt;br /&gt;
		args.subheaderrowclass1 = args.subheaderrowclass&lt;br /&gt;
	end&lt;br /&gt;
	local subheadernums = getArgNums(&#039;subheader&#039;)&lt;br /&gt;
	for k, num in ipairs(subheadernums) do&lt;br /&gt;
		addSubheaderRow({&lt;br /&gt;
			data = args[&#039;subheader&#039; .. tostring(num)],&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-subheader&lt;br /&gt;
			datastyle = args.subheaderstyle,&lt;br /&gt;
			rowcellstyle = args[&#039;subheaderstyle&#039; .. tostring(num)],&lt;br /&gt;
			class = args.subheaderclass,&lt;br /&gt;
			rowclass = args[&#039;subheaderrowclass&#039; .. tostring(num)]&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function addImageRow(imageArgs)&lt;br /&gt;
&lt;br /&gt;
	if imageArgs.data and&lt;br /&gt;
		imageArgs.data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;^%S&#039;) then&lt;br /&gt;
&lt;br /&gt;
		has_rows = true&lt;br /&gt;
		has_list_class({ imageArgs.rowclass, imageArgs.class })&lt;br /&gt;
		&lt;br /&gt;
		local row = root:tag(&#039;tr&#039;)&lt;br /&gt;
		row:addClass(imageArgs.rowclass)&lt;br /&gt;
&lt;br /&gt;
		local dataCell = row:tag(&#039;td&#039;)&lt;br /&gt;
		dataCell&lt;br /&gt;
			:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
			:addClass(&#039;infobox-image&#039;)&lt;br /&gt;
			:addClass(imageArgs.class)&lt;br /&gt;
			:cssText(imageArgs.datastyle)&lt;br /&gt;
			:wikitext(fixChildBoxes(imageArgs.data, &#039;td&#039;))&lt;br /&gt;
	else&lt;br /&gt;
		table.insert(empty_row_categories, imageArgs.data or &#039;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderImages()&lt;br /&gt;
	if args.image then&lt;br /&gt;
		args.image1 = args.image&lt;br /&gt;
	end&lt;br /&gt;
	if args.caption then&lt;br /&gt;
		args.caption1 = args.caption&lt;br /&gt;
	end&lt;br /&gt;
	local imagenums = getArgNums(&#039;image&#039;)&lt;br /&gt;
	for k, num in ipairs(imagenums) do&lt;br /&gt;
		local caption = args[&#039;caption&#039; .. tostring(num)]&lt;br /&gt;
		local data = mw.html.create():wikitext(args[&#039;image&#039; .. tostring(num)])&lt;br /&gt;
		if caption then&lt;br /&gt;
			data&lt;br /&gt;
				:tag(&#039;div&#039;)&lt;br /&gt;
					:addClass(&#039;infobox-caption&#039;)&lt;br /&gt;
					-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-caption&lt;br /&gt;
					:cssText(args.captionstyle)&lt;br /&gt;
					:wikitext(caption)&lt;br /&gt;
		end&lt;br /&gt;
		addImageRow({&lt;br /&gt;
			data = tostring(data),&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; .infobox-image&lt;br /&gt;
			datastyle = args.imagestyle,&lt;br /&gt;
			class = args.imageclass,&lt;br /&gt;
			rowclass = args[&#039;imagerowclass&#039; .. tostring(num)]&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- When autoheaders are turned on, preprocesses the rows&lt;br /&gt;
local function preprocessRows()&lt;br /&gt;
	if not args.autoheaders then return end&lt;br /&gt;
	&lt;br /&gt;
	local rownums = union(getArgNums(&#039;header&#039;), getArgNums(&#039;data&#039;))&lt;br /&gt;
	table.sort(rownums)&lt;br /&gt;
	local lastheader&lt;br /&gt;
	for k, num in ipairs(rownums) do&lt;br /&gt;
		if args[&#039;header&#039; .. tostring(num)] then&lt;br /&gt;
			if lastheader then&lt;br /&gt;
				args[&#039;header&#039; .. tostring(lastheader)] = nil&lt;br /&gt;
			end&lt;br /&gt;
			lastheader = num&lt;br /&gt;
		elseif args[&#039;data&#039; .. tostring(num)] and&lt;br /&gt;
			args[&#039;data&#039; .. tostring(num)]:gsub(&lt;br /&gt;
				category_in_empty_row_pattern, &#039;&#039;&lt;br /&gt;
			):match(&#039;^%S&#039;) then&lt;br /&gt;
			local data = args[&#039;data&#039; .. tostring(num)]&lt;br /&gt;
			if data:gsub(category_in_empty_row_pattern, &#039;&#039;):match(&#039;%S&#039;) then&lt;br /&gt;
				lastheader = nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if lastheader then&lt;br /&gt;
		args[&#039;header&#039; .. tostring(lastheader)] = nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Gets the union of the header and data argument numbers,&lt;br /&gt;
-- and renders them all in order&lt;br /&gt;
local function renderRows()&lt;br /&gt;
&lt;br /&gt;
	local rownums = union(getArgNums(&#039;header&#039;), getArgNums(&#039;data&#039;))&lt;br /&gt;
	table.sort(rownums)&lt;br /&gt;
	for k, num in ipairs(rownums) do&lt;br /&gt;
		addRow({&lt;br /&gt;
			header = args[&#039;header&#039; .. tostring(num)],&lt;br /&gt;
			label = args[&#039;label&#039; .. tostring(num)],&lt;br /&gt;
			data = args[&#039;data&#039; .. tostring(num)],&lt;br /&gt;
			datastyle = args.datastyle,&lt;br /&gt;
			class = args[&#039;class&#039; .. tostring(num)],&lt;br /&gt;
			rowclass = args[&#039;rowclass&#039; .. tostring(num)],&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt; rowclass&lt;br /&gt;
			rowstyle = args[&#039;rowstyle&#039; .. tostring(num)],&lt;br /&gt;
			rowcellstyle = args[&#039;rowcellstyle&#039; .. tostring(num)]&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderNavBar()&lt;br /&gt;
	if not args.name then return end&lt;br /&gt;
&lt;br /&gt;
	has_rows = true&lt;br /&gt;
	root&lt;br /&gt;
		:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;td&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;infobox-navbar&#039;)&lt;br /&gt;
				:wikitext(require(&#039;Module:Navbar&#039;)._navbar{&lt;br /&gt;
					args.name,&lt;br /&gt;
					mini = 1,&lt;br /&gt;
				})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function renderItalicTitle()&lt;br /&gt;
	local italicTitle = args[&#039;italic title&#039;] and mw.ustring.lower(args[&#039;italic title&#039;])&lt;br /&gt;
	if italicTitle == &#039;&#039; or italicTitle == &#039;force&#039; or italicTitle == &#039;yes&#039; then&lt;br /&gt;
		root:wikitext(require(&#039;Module:Italic title&#039;)._main({}))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Categories in otherwise empty rows are collected in empty_row_categories.&lt;br /&gt;
-- This function adds them to the module output. It is not affected by&lt;br /&gt;
-- args.decat because this module should not prevent module-external categories&lt;br /&gt;
-- from rendering.&lt;br /&gt;
local function renderEmptyRowCategories()&lt;br /&gt;
	for _, s in ipairs(empty_row_categories) do&lt;br /&gt;
		root:wikitext(s)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Render tracking categories. args.decat == turns off tracking categories.&lt;br /&gt;
local function renderTrackingCategories()&lt;br /&gt;
	if args.decat == &#039;yes&#039; then return end&lt;br /&gt;
	if args.child == &#039;yes&#039; then&lt;br /&gt;
		if args.title then&lt;br /&gt;
			root:wikitext(&lt;br /&gt;
				&#039;[[Category:Pages using embedded infobox templates with the title parameter]]&#039;&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	elseif #(getArgNums(&#039;data&#039;)) == 0 and mw.title.getCurrentTitle().namespace == 0 then&lt;br /&gt;
		root:wikitext(&#039;[[Category:Articles using infobox templates with no data rows]]&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[=[&lt;br /&gt;
Loads the templatestyles for the infobox.&lt;br /&gt;
&lt;br /&gt;
TODO: FINISH loading base templatestyles here rather than in&lt;br /&gt;
MediaWiki:Common.css. There are 4-5000 pages with &#039;raw&#039; infobox tables.&lt;br /&gt;
See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).&lt;br /&gt;
When we do this we should clean up the inline CSS below too.&lt;br /&gt;
Will have to do some bizarre conversion category like with sidebar.&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
local function loadTemplateStyles()&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	&lt;br /&gt;
	local hlist_templatestyles = &#039;&#039;&lt;br /&gt;
	if lists.hlist_t.found then&lt;br /&gt;
		hlist_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = lists.hlist_t.styles }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local plainlist_templatestyles = &#039;&#039;&lt;br /&gt;
	if lists.plainlist_t.found then&lt;br /&gt;
		plainlist_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = lists.plainlist_t.styles }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- See function description&lt;br /&gt;
	local base_templatestyles = frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = &#039;Module:Infobox/styles.css&#039; }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local templatestyles = &#039;&#039;&lt;br /&gt;
	if args[&#039;templatestyles&#039;] then&lt;br /&gt;
		templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = args[&#039;templatestyles&#039;] }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local child_templatestyles = &#039;&#039;&lt;br /&gt;
	if args[&#039;child templatestyles&#039;] then&lt;br /&gt;
		child_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = args[&#039;child templatestyles&#039;] }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local grandchild_templatestyles = &#039;&#039;&lt;br /&gt;
	if args[&#039;grandchild templatestyles&#039;] then&lt;br /&gt;
		grandchild_templatestyles = frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;, args = { src = args[&#039;grandchild templatestyles&#039;] }&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return table.concat({&lt;br /&gt;
		-- hlist -&amp;gt; plainlist -&amp;gt; base is best-effort to preserve old Common.css ordering.&lt;br /&gt;
		-- this ordering is not a guarantee because the rows of interest invoking&lt;br /&gt;
		-- each class may not be on a specific page&lt;br /&gt;
		hlist_templatestyles,&lt;br /&gt;
		plainlist_templatestyles,&lt;br /&gt;
		base_templatestyles,&lt;br /&gt;
		templatestyles,&lt;br /&gt;
		child_templatestyles,&lt;br /&gt;
		grandchild_templatestyles&lt;br /&gt;
	})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- common functions between the child and non child cases&lt;br /&gt;
local function structure_infobox_common()&lt;br /&gt;
	renderSubheaders()&lt;br /&gt;
	renderImages()&lt;br /&gt;
	preprocessRows()&lt;br /&gt;
	renderRows()&lt;br /&gt;
	renderBelowRow()&lt;br /&gt;
	renderNavBar()&lt;br /&gt;
	renderItalicTitle()&lt;br /&gt;
	renderEmptyRowCategories()&lt;br /&gt;
	renderTrackingCategories()&lt;br /&gt;
	cleanInfobox()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Specify the overall layout of the infobox, with special settings if the&lt;br /&gt;
-- infobox is used as a &#039;child&#039; inside another infobox.&lt;br /&gt;
local function _infobox()&lt;br /&gt;
	if args.child ~= &#039;yes&#039; then&lt;br /&gt;
		root = mw.html.create(&#039;table&#039;)&lt;br /&gt;
&lt;br /&gt;
		root&lt;br /&gt;
			:addClass(args.subbox == &#039;yes&#039; and &#039;infobox-subbox&#039; or &#039;infobox&#039;)&lt;br /&gt;
			:addClass(args.bodyclass)&lt;br /&gt;
			-- @deprecated next; target .infobox-&amp;lt;name&amp;gt;&lt;br /&gt;
			:cssText(args.bodystyle)&lt;br /&gt;
		&lt;br /&gt;
		has_list_class({ args.bodyclass })&lt;br /&gt;
&lt;br /&gt;
		renderTitle()&lt;br /&gt;
		renderAboveRow()&lt;br /&gt;
	else&lt;br /&gt;
		root = mw.html.create()&lt;br /&gt;
&lt;br /&gt;
		root&lt;br /&gt;
			:wikitext(args.title)&lt;br /&gt;
	end&lt;br /&gt;
	structure_infobox_common()&lt;br /&gt;
	&lt;br /&gt;
	return loadTemplateStyles() .. root&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- If the argument exists and isn&#039;t blank, add it to the argument table.&lt;br /&gt;
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.&lt;br /&gt;
local function preprocessSingleArg(argName)&lt;br /&gt;
	if origArgs[argName] and origArgs[argName] ~= &#039;&#039; then&lt;br /&gt;
		args[argName] = origArgs[argName]&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Assign the parameters with the given prefixes to the args table, in order, in&lt;br /&gt;
-- batches of the step size specified. This is to prevent references etc. from&lt;br /&gt;
-- appearing in the wrong order. The prefixTable should be an array containing&lt;br /&gt;
-- tables, each of which has two possible fields, a &amp;quot;prefix&amp;quot; string and a&lt;br /&gt;
-- &amp;quot;depend&amp;quot; table. The function always parses parameters containing the &amp;quot;prefix&amp;quot;&lt;br /&gt;
-- string, but only parses parameters in the &amp;quot;depend&amp;quot; table if the prefix&lt;br /&gt;
-- parameter is present and non-blank.&lt;br /&gt;
local function preprocessArgs(prefixTable, step)&lt;br /&gt;
	if type(prefixTable) ~= &#039;table&#039; then&lt;br /&gt;
		error(&amp;quot;Non-table value detected for the prefix table&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if type(step) ~= &#039;number&#039; then&lt;br /&gt;
		error(&amp;quot;Invalid step value detected&amp;quot;, 2)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Get arguments without a number suffix, and check for bad input.&lt;br /&gt;
	for i,v in ipairs(prefixTable) do&lt;br /&gt;
		if type(v) ~= &#039;table&#039; or type(v.prefix) ~= &amp;quot;string&amp;quot; or&lt;br /&gt;
			(v.depend and type(v.depend) ~= &#039;table&#039;) then&lt;br /&gt;
			error(&#039;Invalid input detected to preprocessArgs prefix table&#039;, 2)&lt;br /&gt;
		end&lt;br /&gt;
		preprocessSingleArg(v.prefix)&lt;br /&gt;
		-- Only parse the depend parameter if the prefix parameter is present&lt;br /&gt;
		-- and not blank.&lt;br /&gt;
		if args[v.prefix] and v.depend then&lt;br /&gt;
			for j, dependValue in ipairs(v.depend) do&lt;br /&gt;
				if type(dependValue) ~= &#039;string&#039; then&lt;br /&gt;
					error(&#039;Invalid &amp;quot;depend&amp;quot; parameter value detected in preprocessArgs&#039;)&lt;br /&gt;
				end&lt;br /&gt;
				preprocessSingleArg(dependValue)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Get arguments with number suffixes.&lt;br /&gt;
	local a = 1 -- Counter variable.&lt;br /&gt;
	local moreArgumentsExist = true&lt;br /&gt;
	while moreArgumentsExist == true do&lt;br /&gt;
		moreArgumentsExist = false&lt;br /&gt;
		for i = a, a + step - 1 do&lt;br /&gt;
			for j,v in ipairs(prefixTable) do&lt;br /&gt;
				local prefixArgName = v.prefix .. tostring(i)&lt;br /&gt;
				if origArgs[prefixArgName] then&lt;br /&gt;
					-- Do another loop if any arguments are found, even blank ones.&lt;br /&gt;
					moreArgumentsExist = true&lt;br /&gt;
					preprocessSingleArg(prefixArgName)&lt;br /&gt;
				end&lt;br /&gt;
				-- Process the depend table if the prefix argument is present&lt;br /&gt;
				-- and not blank, or we are processing &amp;quot;prefix1&amp;quot; and &amp;quot;prefix&amp;quot; is&lt;br /&gt;
				-- present and not blank, and if the depend table is present.&lt;br /&gt;
				if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then&lt;br /&gt;
					for j,dependValue in ipairs(v.depend) do&lt;br /&gt;
						local dependArgName = dependValue .. tostring(i)&lt;br /&gt;
						preprocessSingleArg(dependArgName)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		a = a + step&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Parse the data parameters in the same order that the old {{infobox}} did, so&lt;br /&gt;
-- that references etc. will display in the expected places. Parameters that&lt;br /&gt;
-- depend on another parameter are only processed if that parameter is present,&lt;br /&gt;
-- to avoid phantom references appearing in article reference lists.&lt;br /&gt;
local function parseDataParameters()&lt;br /&gt;
&lt;br /&gt;
	preprocessSingleArg(&#039;autoheaders&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;child&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;bodyclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;subbox&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;bodystyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;title&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;titleclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;titlestyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;above&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;aboveclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;abovestyle&#039;)&lt;br /&gt;
	preprocessArgs({&lt;br /&gt;
		{prefix = &#039;subheader&#039;, depend = {&#039;subheaderstyle&#039;, &#039;subheaderrowclass&#039;}}&lt;br /&gt;
	}, 10)&lt;br /&gt;
	preprocessSingleArg(&#039;subheaderstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;subheaderclass&#039;)&lt;br /&gt;
	preprocessArgs({&lt;br /&gt;
		{prefix = &#039;image&#039;, depend = {&#039;caption&#039;, &#039;imagerowclass&#039;}}&lt;br /&gt;
	}, 10)&lt;br /&gt;
	preprocessSingleArg(&#039;captionstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;imagestyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;imageclass&#039;)&lt;br /&gt;
	preprocessArgs({&lt;br /&gt;
		{prefix = &#039;header&#039;},&lt;br /&gt;
		{prefix = &#039;data&#039;, depend = {&#039;label&#039;}},&lt;br /&gt;
		{prefix = &#039;rowclass&#039;},&lt;br /&gt;
		{prefix = &#039;rowstyle&#039;},&lt;br /&gt;
		{prefix = &#039;rowcellstyle&#039;},&lt;br /&gt;
		{prefix = &#039;class&#039;}&lt;br /&gt;
	}, 50)&lt;br /&gt;
	preprocessSingleArg(&#039;headerclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;headerstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;labelstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;datastyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;below&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;belowclass&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;belowstyle&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;name&#039;)&lt;br /&gt;
	-- different behaviour for italics if blank or absent&lt;br /&gt;
	args[&#039;italic title&#039;] = origArgs[&#039;italic title&#039;]&lt;br /&gt;
	preprocessSingleArg(&#039;decat&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;templatestyles&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;child templatestyles&#039;)&lt;br /&gt;
	preprocessSingleArg(&#039;grandchild templatestyles&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- If called via #invoke, use the args passed into the invoking template.&lt;br /&gt;
-- Otherwise, for testing purposes, assume args are being passed directly in.&lt;br /&gt;
function p.infobox(frame)&lt;br /&gt;
	if frame == mw.getCurrentFrame() then&lt;br /&gt;
		origArgs = frame:getParent().args&lt;br /&gt;
	else&lt;br /&gt;
		origArgs = frame&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	parseDataParameters()&lt;br /&gt;
	&lt;br /&gt;
	return _infobox()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- For calling via #invoke within a template&lt;br /&gt;
function p.infoboxTemplate(frame)&lt;br /&gt;
	origArgs = {}&lt;br /&gt;
	for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end&lt;br /&gt;
	&lt;br /&gt;
	parseDataParameters()&lt;br /&gt;
	&lt;br /&gt;
	return _infobox()&lt;br /&gt;
end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Check_for_unknown_parameters&amp;diff=269</id>
		<title>Module:Check for unknown parameters</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Check_for_unknown_parameters&amp;diff=269"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module may be used to compare the arguments passed to the parent&lt;br /&gt;
-- with a list of arguments, returning a specified result if an argument is&lt;br /&gt;
-- not on the list&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function trim(s)&lt;br /&gt;
	return s:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isnotempty(s)&lt;br /&gt;
	return s and s:match(&#039;%S&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function clean(text)&lt;br /&gt;
	-- Return text cleaned for display and truncated if too long.&lt;br /&gt;
	-- Strip markers are replaced with dummy text representing the original wikitext.&lt;br /&gt;
	local pos, truncated&lt;br /&gt;
	local function truncate(text)&lt;br /&gt;
		if truncated then&lt;br /&gt;
			return &#039;&#039;&lt;br /&gt;
		end&lt;br /&gt;
		if mw.ustring.len(text) &amp;gt; 25 then&lt;br /&gt;
			truncated = true&lt;br /&gt;
			text = mw.ustring.sub(text, 1, 25) .. &#039;...&#039;&lt;br /&gt;
		end&lt;br /&gt;
		return mw.text.nowiki(text)&lt;br /&gt;
	end&lt;br /&gt;
	local parts = {}&lt;br /&gt;
	for before, tag, remainder in text:gmatch(&#039;([^\127]*)\127[^\127]*%-(%l+)%-[^\127]*\127()&#039;) do&lt;br /&gt;
		pos = remainder&lt;br /&gt;
		table.insert(parts, truncate(before) .. &#039;&amp;amp;lt;&#039; .. tag .. &#039;&amp;amp;gt;...&amp;amp;lt;/&#039; .. tag .. &#039;&amp;amp;gt;&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(parts, truncate(text:sub(pos or 1)))&lt;br /&gt;
	return table.concat(parts)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._check(args, pargs)&lt;br /&gt;
	if type(args) ~= &amp;quot;table&amp;quot; or type(pargs) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		-- TODO: error handling&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- create the list of known args, regular expressions, and the return string&lt;br /&gt;
	local knownargs = {}&lt;br /&gt;
	local regexps = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		if type(k) == &#039;number&#039; then&lt;br /&gt;
			v = trim(v)&lt;br /&gt;
			knownargs[v] = 1&lt;br /&gt;
		elseif k:find(&#039;^regexp[1-9][0-9]*$&#039;) then&lt;br /&gt;
			table.insert(regexps, &#039;^&#039; .. v .. &#039;$&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- loop over the parent args, and make sure they are on the list&lt;br /&gt;
	local ignoreblank = isnotempty(args[&#039;ignoreblank&#039;])&lt;br /&gt;
	local showblankpos = isnotempty(args[&#039;showblankpositional&#039;])&lt;br /&gt;
	local values = {}&lt;br /&gt;
	for k, v in pairs(pargs) do&lt;br /&gt;
		if type(k) == &#039;string&#039; and knownargs[k] == nil then&lt;br /&gt;
			local knownflag = false&lt;br /&gt;
			for _, regexp in ipairs(regexps) do&lt;br /&gt;
				if mw.ustring.match(k, regexp) then&lt;br /&gt;
					knownflag = true&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if not knownflag and ( not ignoreblank or isnotempty(v) )  then&lt;br /&gt;
				table.insert(values, clean(k))&lt;br /&gt;
			end&lt;br /&gt;
		elseif type(k) == &#039;number&#039; and knownargs[tostring(k)] == nil then&lt;br /&gt;
			local knownflag = false&lt;br /&gt;
			for _, regexp in ipairs(regexps) do&lt;br /&gt;
				if mw.ustring.match(tostring(k), regexp) then&lt;br /&gt;
					knownflag = true&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if not knownflag and ( showblankpos or isnotempty(v) ) then&lt;br /&gt;
				table.insert(values, k .. &#039; = &#039; .. clean(v))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- add results to the output tables&lt;br /&gt;
	local res = {}&lt;br /&gt;
	if #values &amp;gt; 0 then&lt;br /&gt;
		local unknown_text = args[&#039;unknown&#039;] or &#039;Found _VALUE_, &#039;&lt;br /&gt;
&lt;br /&gt;
		if mw.getCurrentFrame():preprocess( &amp;quot;{{REVISIONID}}&amp;quot; ) == &amp;quot;&amp;quot; then&lt;br /&gt;
			local preview_text = args[&#039;preview&#039;]&lt;br /&gt;
			if isnotempty(preview_text) then&lt;br /&gt;
				preview_text = require(&#039;Module:If preview&#039;)._warning({preview_text})&lt;br /&gt;
			elseif preview == nil then&lt;br /&gt;
				preview_text = unknown_text&lt;br /&gt;
			end&lt;br /&gt;
			unknown_text = preview_text&lt;br /&gt;
		end&lt;br /&gt;
		for _, v in pairs(values) do&lt;br /&gt;
			-- Fix odd bug for | = which gets stripped to the empty string and&lt;br /&gt;
			-- breaks category links&lt;br /&gt;
			if v == &#039;&#039; then v = &#039; &#039; end&lt;br /&gt;
&lt;br /&gt;
			-- avoid error with v = &#039;example%2&#039; (&amp;quot;invalid capture index&amp;quot;)&lt;br /&gt;
			local r = unknown_text:gsub(&#039;_VALUE_&#039;, {_VALUE_ = v})&lt;br /&gt;
			table.insert(res, r)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat(res)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.check(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local pargs = frame:getParent().args&lt;br /&gt;
	return p._check(args, pargs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:ScribuntoUnit/config&amp;diff=267</id>
		<title>Module:ScribuntoUnit/config</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:ScribuntoUnit/config&amp;diff=267"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- The cfg table, created by this module, contains all localisable strings and&lt;br /&gt;
-- configuration, to make it easier to port this module to another wiki.&lt;br /&gt;
local cfg = {} -- Do not edit this line.&lt;br /&gt;
&lt;br /&gt;
-- The successIndicator and failureIndicator are in the first column of the&lt;br /&gt;
-- wikitable produced as output and indicate whether the test passed.  These two&lt;br /&gt;
-- strings are preprocessed by frame.preprocess.&lt;br /&gt;
-- successIndicator: if the test passes&lt;br /&gt;
-- failureIndicator: if the test fails&lt;br /&gt;
cfg.successIndicator = &amp;quot;{{tick}}&amp;quot;&lt;br /&gt;
cfg.failureIndicator = &amp;quot;{{cross}}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- The names of the columns Name, Expected and Actual (the other three columns,&lt;br /&gt;
-- in this order)&lt;br /&gt;
cfg.nameString = &amp;quot;Name&amp;quot;&lt;br /&gt;
cfg.expectedString = &amp;quot;Expected&amp;quot;&lt;br /&gt;
cfg.actualString = &amp;quot;Actual&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- The string at the top used to indicate all tests passed.&lt;br /&gt;
cfg.successSummary = &amp;quot;All tests passed.&amp;quot;&lt;br /&gt;
-- The string at the top used to indicate one or more tests failed. $1 is&lt;br /&gt;
-- replaced by the number of tests that failed.  This string is preprocessed by&lt;br /&gt;
-- frame.preprocess.&lt;br /&gt;
cfg.failureSummary = &amp;quot;&#039;&#039;&#039;$1 {{PLURAL:$1|test|tests}} failed&#039;&#039;&#039;.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Format string for a short display of the tests in displayResultsAsShort.&lt;br /&gt;
-- This format string is passed directly to string.format.&lt;br /&gt;
cfg.shortResultsFormat = &amp;quot;success: %d, error: %d, skipped: %d&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Category added to pages that fail one or more tests. Set to nil to disable&lt;br /&gt;
-- categorisation of pages that fail one or more tests.&lt;br /&gt;
cfg.failureCategory = &amp;quot;[[Category:Failed Lua testcases using Module:ScribuntoUnit]]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- Finally, return the configuration table.&lt;br /&gt;
return cfg -- Do not edit this line.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:ScribuntoUnit&amp;diff=265</id>
		<title>Module:ScribuntoUnit</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:ScribuntoUnit&amp;diff=265"/>
		<updated>2024-07-31T17:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-------------------------------------------------------------------------------&lt;br /&gt;
-- Unit tests for Scribunto.&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
require(&#039;strict&#039;)&lt;br /&gt;
&lt;br /&gt;
local DebugHelper = {}&lt;br /&gt;
local ScribuntoUnit = {}&lt;br /&gt;
&lt;br /&gt;
-- The cfg table contains all localisable strings and configuration, to make it&lt;br /&gt;
-- easier to port this module to another wiki.&lt;br /&gt;
local cfg = mw.loadData(&#039;Module:ScribuntoUnit/config&#039;)&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Concatenates keys and values, ideal for displaying a template or parser function argument table.&lt;br /&gt;
-- @param keySeparator glue between key and value (defaults to &amp;quot; = &amp;quot;)&lt;br /&gt;
-- @param separator glue between different key-value pairs (defaults to &amp;quot;, &amp;quot;)&lt;br /&gt;
-- @example concatWithKeys({a = 1, b = 2, c = 3}, &#039; =&amp;gt; &#039;, &#039;, &#039;) =&amp;gt; &amp;quot;a =&amp;gt; 1, b =&amp;gt; 2, c =&amp;gt; 3&amp;quot;&lt;br /&gt;
-- &lt;br /&gt;
function DebugHelper.concatWithKeys(table, keySeparator, separator)&lt;br /&gt;
    keySeparator = keySeparator or &#039; = &#039;&lt;br /&gt;
    separator = separator or &#039;, &#039;&lt;br /&gt;
    local concatted = &#039;&#039;&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local first = true&lt;br /&gt;
    local unnamedArguments = true&lt;br /&gt;
    for k, v in pairs(table) do&lt;br /&gt;
        if first then&lt;br /&gt;
            first = false&lt;br /&gt;
        else&lt;br /&gt;
            concatted = concatted .. separator&lt;br /&gt;
        end&lt;br /&gt;
        if k == i and unnamedArguments then&lt;br /&gt;
            i = i + 1&lt;br /&gt;
            concatted = concatted .. tostring(v)&lt;br /&gt;
        else&lt;br /&gt;
            unnamedArguments = false&lt;br /&gt;
            concatted = concatted .. tostring(k) .. keySeparator .. tostring(v)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return concatted&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Compares two tables recursively (non-table values are handled correctly as well).&lt;br /&gt;
-- @param ignoreMetatable if false, t1.__eq is used for the comparison&lt;br /&gt;
-- &lt;br /&gt;
function DebugHelper.deepCompare(t1, t2, ignoreMetatable)&lt;br /&gt;
    local type1 = type(t1)&lt;br /&gt;
    local type2 = type(t2)&lt;br /&gt;
&lt;br /&gt;
    if type1 ~= type2 then &lt;br /&gt;
        return false &lt;br /&gt;
    end&lt;br /&gt;
    if type1 ~= &#039;table&#039; then &lt;br /&gt;
        return t1 == t2 &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local metatable = getmetatable(t1)&lt;br /&gt;
    if not ignoreMetatable and metatable and metatable.__eq then &lt;br /&gt;
        return t1 == t2 &lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    for k1, v1 in pairs(t1) do&lt;br /&gt;
        local v2 = t2[k1]&lt;br /&gt;
        if v2 == nil or not DebugHelper.deepCompare(v1, v2) then &lt;br /&gt;
            return false &lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    for k2, v2 in pairs(t2) do&lt;br /&gt;
        if t1[k2] == nil then &lt;br /&gt;
            return false &lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Raises an error with stack information&lt;br /&gt;
-- @param details a table with error details&lt;br /&gt;
--        - should have a &#039;text&#039; key which is the error message to display&lt;br /&gt;
--        - a &#039;trace&#039; key will be added with the stack data&lt;br /&gt;
--        - and a &#039;source&#039; key with file/line number&lt;br /&gt;
--        - a metatable will be added for error handling&lt;br /&gt;
-- &lt;br /&gt;
function DebugHelper.raise(details, level)&lt;br /&gt;
    level = (level or 1) + 1&lt;br /&gt;
    details.trace = debug.traceback(&#039;&#039;, level)&lt;br /&gt;
    details.source = string.match(details.trace, &#039;^%s*stack traceback:%s*(%S*: )&#039;)&lt;br /&gt;
&lt;br /&gt;
--    setmetatable(details, {&lt;br /&gt;
--        __tostring: function() return details.text end&lt;br /&gt;
--    })&lt;br /&gt;
&lt;br /&gt;
    error(details, level)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- when used in a test, that test gets ignored, and the skipped count increases by one.&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:markTestSkipped()&lt;br /&gt;
    DebugHelper.raise({ScribuntoUnit = true, skipped = true}, 3)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Unconditionally fail a test&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:fail(message)&lt;br /&gt;
    DebugHelper.raise({ScribuntoUnit = true, text = &amp;quot;Test failed&amp;quot;, message = message}, 2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that the input is true&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertTrue(actual, message)&lt;br /&gt;
    if not actual then&lt;br /&gt;
        DebugHelper.raise({ScribuntoUnit = true, text = string.format(&amp;quot;Failed to assert that %s is true&amp;quot;, tostring(actual)), message = message}, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that the input is false&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertFalse(actual, message)&lt;br /&gt;
    if actual then&lt;br /&gt;
        DebugHelper.raise({ScribuntoUnit = true, text = string.format(&amp;quot;Failed to assert that %s is false&amp;quot;, tostring(actual)), message = message}, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks an input string contains the expected string&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @param plain search is made with a plain string instead of a ustring pattern&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertStringContains(pattern, s, plain, message)&lt;br /&gt;
	if type(pattern) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;Pattern type error (expected string, got %s)&amp;quot;, type(pattern)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if type(s) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;String type error (expected string, got %s)&amp;quot;, type(s)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if not mw.ustring.find(s, pattern, nil, plain) then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&#039;Failed to find %s &amp;quot;%s&amp;quot; in string &amp;quot;%s&amp;quot;&#039;, plain and &amp;quot;plain string&amp;quot; or &amp;quot;pattern&amp;quot;, pattern, s),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks an input string doesn&#039;t contain the expected string&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @param plain search is made with a plain string instead of a ustring pattern&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertNotStringContains(pattern, s, plain, message)&lt;br /&gt;
	if type(pattern) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;Pattern type error (expected string, got %s)&amp;quot;, type(pattern)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	if type(s) ~= &#039;string&#039; then&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&amp;quot;String type error (expected string, got %s)&amp;quot;, type(s)),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
	local i, j = mw.ustring.find(s, pattern, nil, plain)&lt;br /&gt;
	if i then&lt;br /&gt;
		local match = mw.ustring.sub(s, i, j)&lt;br /&gt;
		DebugHelper.raise({&lt;br /&gt;
			ScribuntoUnit = true,&lt;br /&gt;
			text = mw.ustring.format(&#039;Found match &amp;quot;%s&amp;quot; for %s &amp;quot;%s&amp;quot;&#039;, match, plain and &amp;quot;plain string&amp;quot; or &amp;quot;pattern&amp;quot;, pattern),&lt;br /&gt;
			message = message&lt;br /&gt;
		}, 2)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that an input has the expected value.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertEquals(4, add(2,2), &amp;quot;2+2 should be 4&amp;quot;)&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertEquals(expected, actual, message)&lt;br /&gt;
	if type(expected) == &#039;number&#039; and type(actual) == &#039;number&#039; then&lt;br /&gt;
        self:assertWithinDelta(expected, actual, 1e-8, message)&lt;br /&gt;
	elseif expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s&amp;quot;, tostring(actual), tostring(expected)), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that an input does not have the expected value.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertNotEquals(5, add(2,2), &amp;quot;2+2 should not be 5&amp;quot;)&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:assertNotEquals(expected, actual, message)&lt;br /&gt;
	if type(expected) == &#039;number&#039; and type(actual) == &#039;number&#039; then&lt;br /&gt;
        self:assertNotWithinDelta(expected, actual, 1e-8, message)&lt;br /&gt;
	elseif expected == actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s does not equal expected %s&amp;quot;, tostring(actual), tostring(expected)), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Validates that both the expected and actual values are numbers&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- &lt;br /&gt;
local function validateNumbers(expected, actual, message)&lt;br /&gt;
    if type(expected) ~= &amp;quot;number&amp;quot; then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            text = string.format(&amp;quot;Expected value %s is not a number&amp;quot;, tostring(expected)),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 3)&lt;br /&gt;
    end&lt;br /&gt;
    if type(actual) ~= &amp;quot;number&amp;quot; then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            text = string.format(&amp;quot;Actual value %s is not a number&amp;quot;, tostring(actual)),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 3)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that &#039;actual&#039; is within &#039;delta&#039; of &#039;expected&#039;.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertWithinDelta(1/3, 3/9, 0.000001, &amp;quot;3/9 should be 1/3&amp;quot;)&lt;br /&gt;
function ScribuntoUnit:assertWithinDelta(expected, actual, delta, message)&lt;br /&gt;
    validateNumbers(expected, actual, message)&lt;br /&gt;
    local diff = expected - actual&lt;br /&gt;
    if diff &amp;lt; 0 then diff = - diff end  -- instead of importing math.abs&lt;br /&gt;
    if diff &amp;gt; delta then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %f is within %f of expected %f&amp;quot;, actual, delta, expected), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that &#039;actual&#039; is not within &#039;delta&#039; of &#039;expected&#039;.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertNotWithinDelta(1/3, 2/3, 0.000001, &amp;quot;1/3 should not be 2/3&amp;quot;)&lt;br /&gt;
function ScribuntoUnit:assertNotWithinDelta(expected, actual, delta, message)&lt;br /&gt;
    validateNumbers(expected, actual, message)&lt;br /&gt;
    local diff = expected - actual&lt;br /&gt;
    if diff &amp;lt; 0 then diff = - diff end  -- instead of importing math.abs&lt;br /&gt;
    if diff &amp;lt;= delta then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %f is not within %f of expected %f&amp;quot;, actual, delta, expected), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a table has the expected value (including sub-tables).&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertDeepEquals({{1,3}, {2,4}}, partition(odd, {1,2,3,4}))&lt;br /&gt;
function ScribuntoUnit:assertDeepEquals(expected, actual, message)&lt;br /&gt;
    if not DebugHelper.deepCompare(expected, actual) then&lt;br /&gt;
        if type(expected) == &#039;table&#039; then&lt;br /&gt;
            expected = mw.dumpObject(expected)&lt;br /&gt;
        end&lt;br /&gt;
        if type(actual) == &#039;table&#039; then&lt;br /&gt;
            actual = mw.dumpObject(actual)&lt;br /&gt;
        end&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s&amp;quot;, tostring(actual), tostring(expected)), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a wikitext gives the expected result after processing.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertResultEquals(&amp;quot;Hello world&amp;quot;, &amp;quot;{{concat|Hello|world}}&amp;quot;)&lt;br /&gt;
function ScribuntoUnit:assertResultEquals(expected, text, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local actual = frame:preprocess(text)&lt;br /&gt;
    if expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s after preprocessing&amp;quot;, text, tostring(expected)), &lt;br /&gt;
            actual = actual,&lt;br /&gt;
            actualRaw = text,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that two wikitexts give the same result after processing.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertSameResult(&amp;quot;{{concat|Hello|world}}&amp;quot;, &amp;quot;{{deleteLastChar|Hello world!}}&amp;quot;)&lt;br /&gt;
function ScribuntoUnit:assertSameResult(text1, text2, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local processed1 = frame:preprocess(text1)&lt;br /&gt;
    local processed2 = frame:preprocess(text2)&lt;br /&gt;
    if processed1 ~= processed2 then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s equals expected %s after preprocessing&amp;quot;, processed1, processed2), &lt;br /&gt;
            actual = processed1,&lt;br /&gt;
            actualRaw = text1,&lt;br /&gt;
            expected = processed2,&lt;br /&gt;
            expectedRaw = text2,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a parser function gives the expected output.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertParserFunctionEquals(&amp;quot;Hello world&amp;quot;, &amp;quot;msg:concat&amp;quot;, {&amp;quot;Hello&amp;quot;, &amp;quot; world&amp;quot;})&lt;br /&gt;
function ScribuntoUnit:assertParserFunctionEquals(expected, pfname, args, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local actual = frame:callParserFunction{ name = pfname, args = args}&lt;br /&gt;
    if expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s with args %s equals expected %s after preprocessing&amp;quot;, &lt;br /&gt;
                                 DebugHelper.concatWithKeys(args), pfname, expected),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            actualRaw = pfname,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks that a template gives the expected output.&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
-- @example assertTemplateEquals(&amp;quot;Hello world&amp;quot;, &amp;quot;concat&amp;quot;, {&amp;quot;Hello&amp;quot;, &amp;quot; world&amp;quot;})&lt;br /&gt;
function ScribuntoUnit:assertTemplateEquals(expected, template, args, message)&lt;br /&gt;
    local frame = self.frame&lt;br /&gt;
    local actual = frame:expandTemplate{ title = template, args = args}&lt;br /&gt;
    if expected ~= actual then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true, &lt;br /&gt;
            text = string.format(&amp;quot;Failed to assert that %s with args %s equals expected %s after preprocessing&amp;quot;, &lt;br /&gt;
                                 DebugHelper.concatWithKeys(args), template, expected),&lt;br /&gt;
            actual = actual,&lt;br /&gt;
            actualRaw = template,&lt;br /&gt;
            expected = expected,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks whether a function throws an error&lt;br /&gt;
-- @param fn the function to test&lt;br /&gt;
-- @param expectedMessage optional the expected error message&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
function ScribuntoUnit:assertThrows(fn, expectedMessage, message)&lt;br /&gt;
    local succeeded, actualMessage = pcall(fn)&lt;br /&gt;
    if succeeded then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            text = &#039;Expected exception but none was thrown&#039;,&lt;br /&gt;
            message = message,&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
	-- For strings, strip the line number added to the error message&lt;br /&gt;
    actualMessage = type(actualMessage) == &#039;string&#039; &lt;br /&gt;
    	and string.match(actualMessage, &#039;Module:[^:]*:[0-9]*: (.*)&#039;)&lt;br /&gt;
    	or actualMessage&lt;br /&gt;
    local messagesMatch = DebugHelper.deepCompare(expectedMessage, actualMessage)&lt;br /&gt;
    if expectedMessage and not messagesMatch then&lt;br /&gt;
        DebugHelper.raise({&lt;br /&gt;
            ScribuntoUnit = true,&lt;br /&gt;
            expected = expectedMessage,&lt;br /&gt;
            actual = actualMessage,&lt;br /&gt;
            text = string.format(&#039;Expected exception with message %s, but got message %s&#039;, &lt;br /&gt;
                tostring(expectedMessage), tostring(actualMessage)&lt;br /&gt;
            ),&lt;br /&gt;
            message = message&lt;br /&gt;
        }, 2)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Checks whether a function doesn&#039;t throw an error&lt;br /&gt;
-- @param fn the function to test&lt;br /&gt;
-- @param message optional description of the test&lt;br /&gt;
function ScribuntoUnit:assertDoesNotThrow(fn, message)&lt;br /&gt;
	local succeeded, actualMessage = pcall(fn)&lt;br /&gt;
	if succeeded then&lt;br /&gt;
	    return&lt;br /&gt;
	end&lt;br /&gt;
	-- For strings, strip the line number added to the error message&lt;br /&gt;
	actualMessage = type(actualMessage) == &#039;string&#039; &lt;br /&gt;
		and string.match(actualMessage, &#039;Module:[^:]*:[0-9]*: (.*)&#039;)&lt;br /&gt;
		or actualMessage&lt;br /&gt;
	DebugHelper.raise({&lt;br /&gt;
		ScribuntoUnit = true,&lt;br /&gt;
		actual = actualMessage,&lt;br /&gt;
		text = string.format(&#039;Expected no exception, but got exception with message %s&#039;,&lt;br /&gt;
			tostring(actualMessage)&lt;br /&gt;
		),&lt;br /&gt;
		message = message&lt;br /&gt;
	}, 2)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Creates a new test suite.&lt;br /&gt;
-- @param o a table with test functions (alternatively, the functions can be added later to the returned suite)&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:new(o)&lt;br /&gt;
    o = o or {}&lt;br /&gt;
    o._tests = {}&lt;br /&gt;
    setmetatable(o, {&lt;br /&gt;
    	__index = self,&lt;br /&gt;
    	__newindex = function (t, k, v)&lt;br /&gt;
    		if type(k) == &amp;quot;string&amp;quot; and k:find(&#039;^test&#039;) and type(v) == &amp;quot;function&amp;quot; then&lt;br /&gt;
    			-- Store test functions in the order they were defined&lt;br /&gt;
    			table.insert(o._tests, {name = k, test = v})&lt;br /&gt;
    		else&lt;br /&gt;
    			rawset(t, k, v)&lt;br /&gt;
    		end&lt;br /&gt;
    	end&lt;br /&gt;
    })&lt;br /&gt;
    o.run = function(frame) return self:run(o, frame) end&lt;br /&gt;
    return o&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Resets global counters&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:init(frame)&lt;br /&gt;
    self.frame = frame or mw.getCurrentFrame()&lt;br /&gt;
    self.successCount = 0&lt;br /&gt;
    self.failureCount = 0&lt;br /&gt;
    self.skipCount = 0&lt;br /&gt;
    self.results = {}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Runs a single testcase&lt;br /&gt;
-- @param name test nume&lt;br /&gt;
-- @param test function containing assertions&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:runTest(suite, name, test)&lt;br /&gt;
    local success, details = pcall(test, suite)&lt;br /&gt;
    &lt;br /&gt;
    if success then&lt;br /&gt;
        self.successCount = self.successCount + 1&lt;br /&gt;
        table.insert(self.results, {name = name, success = true})&lt;br /&gt;
    elseif type(details) ~= &#039;table&#039; or not details.ScribuntoUnit then -- a real error, not a failed assertion&lt;br /&gt;
        self.failureCount = self.failureCount + 1&lt;br /&gt;
        table.insert(self.results, {name = name, error = true, message = &#039;Lua error -- &#039; .. tostring(details)})&lt;br /&gt;
    elseif details.skipped then&lt;br /&gt;
        self.skipCount = self.skipCount + 1&lt;br /&gt;
        table.insert(self.results, {name = name, skipped = true})&lt;br /&gt;
    else&lt;br /&gt;
        self.failureCount = self.failureCount + 1&lt;br /&gt;
        local message = details.source or &amp;quot;&amp;quot;&lt;br /&gt;
        if details.message then&lt;br /&gt;
            message = message .. details.message .. &amp;quot;\n&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        message = message .. details.text&lt;br /&gt;
        table.insert(self.results, {name = name, error = true, message = message, expected = details.expected, actual = details.actual, testname = details.message})&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Runs all tests and displays the results.&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:runSuite(suite, frame)&lt;br /&gt;
    self:init(frame)&lt;br /&gt;
	for i, testDetails in ipairs(suite._tests) do&lt;br /&gt;
		self:runTest(suite, testDetails.name, testDetails.test)&lt;br /&gt;
	end&lt;br /&gt;
    return {&lt;br /&gt;
        successCount = self.successCount,&lt;br /&gt;
        failureCount = self.failureCount,&lt;br /&gt;
        skipCount = self.skipCount,&lt;br /&gt;
        results = self.results,&lt;br /&gt;
    }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- #invoke entry point for running the tests.&lt;br /&gt;
-- Can be called without a frame, in which case it will use mw.log for output&lt;br /&gt;
-- @param displayMode see displayResults()&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:run(suite, frame)&lt;br /&gt;
    local testData = self:runSuite(suite, frame)&lt;br /&gt;
    if frame and frame.args then&lt;br /&gt;
        return self:displayResults(testData, frame.args.displayMode or &#039;table&#039;)&lt;br /&gt;
    else&lt;br /&gt;
        return self:displayResults(testData, &#039;log&#039;)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
-- Displays test results &lt;br /&gt;
-- @param displayMode: &#039;table&#039;, &#039;log&#039; or &#039;short&#039;&lt;br /&gt;
-- &lt;br /&gt;
function ScribuntoUnit:displayResults(testData, displayMode)&lt;br /&gt;
    if displayMode == &#039;table&#039; then&lt;br /&gt;
        return self:displayResultsAsTable(testData)&lt;br /&gt;
    elseif displayMode == &#039;log&#039; then&lt;br /&gt;
        return self:displayResultsAsLog(testData)&lt;br /&gt;
    elseif displayMode == &#039;short&#039; then&lt;br /&gt;
        return self:displayResultsAsShort(testData)&lt;br /&gt;
    else&lt;br /&gt;
        error(&#039;unknown display mode&#039;)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ScribuntoUnit:displayResultsAsLog(testData)&lt;br /&gt;
    if testData.failureCount &amp;gt; 0 then&lt;br /&gt;
        mw.log(&#039;FAILURES!!!&#039;)&lt;br /&gt;
    elseif testData.skipCount &amp;gt; 0 then&lt;br /&gt;
        mw.log(&#039;Some tests could not be executed without a frame and have been skipped. Invoke this test suite as a template to run all tests.&#039;)&lt;br /&gt;
    end&lt;br /&gt;
    mw.log(string.format(&#039;Assertions: success: %d, error: %d, skipped: %d&#039;, testData.successCount, testData.failureCount, testData.skipCount))&lt;br /&gt;
    mw.log(&#039;-------------------------------------------------------------------------------&#039;)&lt;br /&gt;
    for _, result in ipairs(testData.results) do&lt;br /&gt;
        if result.error then&lt;br /&gt;
            mw.log(string.format(&#039;%s: %s&#039;, result.name, result.message))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ScribuntoUnit:displayResultsAsShort(testData)&lt;br /&gt;
    local text = string.format(cfg.shortResultsFormat, testData.successCount, testData.failureCount, testData.skipCount)&lt;br /&gt;
    if testData.failureCount &amp;gt; 0 then&lt;br /&gt;
        text = &#039;&amp;lt;span class=&amp;quot;error&amp;quot;&amp;gt;&#039; .. text .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
    end&lt;br /&gt;
    return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function ScribuntoUnit:displayResultsAsTable(testData)&lt;br /&gt;
    local successIcon, failIcon = self.frame:preprocess(cfg.successIndicator), self.frame:preprocess(cfg.failureIndicator)&lt;br /&gt;
    local text = &#039;&#039;&lt;br /&gt;
	if testData.failureCount &amp;gt; 0 then&lt;br /&gt;
		local msg = mw.message.newRawMessage(cfg.failureSummary, testData.failureCount):plain()&lt;br /&gt;
		msg = self.frame:preprocess(msg)&lt;br /&gt;
		if cfg.failureCategory then&lt;br /&gt;
			msg = cfg.failureCategory .. msg&lt;br /&gt;
		end&lt;br /&gt;
		text = text .. failIcon .. &#039; &#039; .. msg .. &#039;\n&#039;&lt;br /&gt;
	else&lt;br /&gt;
		text = text .. successIcon .. &#039; &#039; .. cfg.successSummary .. &#039;\n&#039;&lt;br /&gt;
	end&lt;br /&gt;
    text = text .. &#039;{| class=&amp;quot;wikitable scribunto-test-table&amp;quot;\n&#039;&lt;br /&gt;
    text = text .. &#039;!\n! &#039; .. cfg.nameString .. &#039;\n! &#039; .. cfg.expectedString .. &#039;\n! &#039; .. cfg.actualString .. &#039;\n&#039;&lt;br /&gt;
    for _, result in ipairs(testData.results) do&lt;br /&gt;
        text = text .. &#039;|-\n&#039;&lt;br /&gt;
        if result.error then&lt;br /&gt;
            text = text .. &#039;| &#039; .. failIcon .. &#039;\n| &#039;&lt;br /&gt;
            if (result.expected and result.actual) then&lt;br /&gt;
            	local name = result.name&lt;br /&gt;
            	if result.testname then&lt;br /&gt;
            		name = name .. &#039; / &#039; .. result.testname&lt;br /&gt;
            	end&lt;br /&gt;
                text = text .. mw.text.nowiki(name) .. &#039;\n| &#039; .. mw.text.nowiki(tostring(result.expected)) .. &#039;\n| &#039; .. mw.text.nowiki(tostring(result.actual)) .. &#039;\n&#039;&lt;br /&gt;
            else&lt;br /&gt;
                text = text .. mw.text.nowiki(result.name) .. &#039;\n| &#039; .. &#039; colspan=&amp;quot;2&amp;quot; | &#039; .. mw.text.nowiki(result.message) .. &#039;\n&#039;&lt;br /&gt;
            end&lt;br /&gt;
        else&lt;br /&gt;
            text = text .. &#039;| &#039; .. successIcon .. &#039;\n| &#039; .. mw.text.nowiki(result.name) .. &#039;\n|\n|\n&#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    text = text .. &#039;|}\n&#039;&lt;br /&gt;
    return text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return ScribuntoUnit&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:UnitTests&amp;diff=263</id>
		<title>Module:UnitTests</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:UnitTests&amp;diff=263"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit_testing]].&lt;br /&gt;
-- For user documentation see talk page.&lt;br /&gt;
local UnitTester = {}&lt;br /&gt;
&lt;br /&gt;
local frame, tick, cross, should_highlight&lt;br /&gt;
local result_table_header = &amp;quot;{|class=\&amp;quot;wikitable unit-tests-result\&amp;quot;\n|+ %s\n! !! Text !! Expected !! Actual&amp;quot;&lt;br /&gt;
local result_table_live_sandbox_header = &amp;quot;{|class=\&amp;quot;wikitable unit-tests-result\&amp;quot;\n|+ %s\n! !! Test !! Live !! Sandbox !! Expected&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local result_table = { n = 0 }&lt;br /&gt;
local result_table_mt = {&lt;br /&gt;
	insert = function (self, ...)&lt;br /&gt;
		local n = self.n&lt;br /&gt;
		for i = 1, select(&#039;#&#039;, ...) do&lt;br /&gt;
			local val = select(i, ...)&lt;br /&gt;
			if val ~= nil then&lt;br /&gt;
				n = n + 1&lt;br /&gt;
				self[n] = val&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		self.n = n&lt;br /&gt;
	end,&lt;br /&gt;
	insert_format = function (self, ...)&lt;br /&gt;
		self:insert(string.format(...))&lt;br /&gt;
	end,&lt;br /&gt;
	concat = table.concat&lt;br /&gt;
}&lt;br /&gt;
result_table_mt.__index = result_table_mt&lt;br /&gt;
setmetatable(result_table, result_table_mt)&lt;br /&gt;
&lt;br /&gt;
local num_failures = 0&lt;br /&gt;
local num_runs = 0&lt;br /&gt;
&lt;br /&gt;
local function first_difference(s1, s2)&lt;br /&gt;
	s1, s2 = tostring(s1), tostring(s2)&lt;br /&gt;
    if s1 == s2 then return &#039;&#039; end&lt;br /&gt;
    local max = math.min(#s1, #s2)&lt;br /&gt;
    for i = 1, max do&lt;br /&gt;
        if s1:sub(i,i) ~= s2:sub(i,i) then return i end&lt;br /&gt;
    end&lt;br /&gt;
    return max + 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function return_varargs(...)&lt;br /&gt;
	return ...&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:calculate_output(text, expected, actual, options)&lt;br /&gt;
	-- Set up some variables for throughout for ease&lt;br /&gt;
	num_runs = num_runs + 1&lt;br /&gt;
	local options = options or {}&lt;br /&gt;
	&lt;br /&gt;
	-- Fix any stripmarkers if asked to do so to prevent incorrect fails&lt;br /&gt;
	local compared_expected = expected&lt;br /&gt;
	local compared_actual = actual&lt;br /&gt;
	if options.templatestyles then&lt;br /&gt;
		local pattern = &#039;(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)&#039;&lt;br /&gt;
		local _, expected_stripmarker_id = compared_expected:match(pattern)				-- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail&lt;br /&gt;
		if expected_stripmarker_id then&lt;br /&gt;
			compared_actual = compared_actual:gsub(pattern, &#039;%1&#039; .. expected_stripmarker_id .. &#039;%3&#039;)	-- replace actual id with expected id; ignore second capture in pattern&lt;br /&gt;
			compared_expected = compared_expected:gsub(pattern, &#039;%1&#039; .. expected_stripmarker_id .. &#039;%3&#039;)		-- account for other strip markers&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if options.stripmarker then&lt;br /&gt;
		local pattern = &#039;(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)&#039;&lt;br /&gt;
		local _, expected_stripmarker_id = compared_expected:match(pattern)&lt;br /&gt;
		if expected_stripmarker_id then&lt;br /&gt;
			compared_actual = compared_actual:gsub(pattern, &#039;%1&#039; .. expected_stripmarker_id .. &#039;%3&#039;)&lt;br /&gt;
			compared_expected = compared_expected:gsub(pattern, &#039;%1&#039; .. expected_stripmarker_id .. &#039;%3&#039;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Perform the comparison&lt;br /&gt;
	local success = compared_actual == compared_expected&lt;br /&gt;
	if not success then&lt;br /&gt;
		num_failures = num_failures + 1&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Sort the wikitext for displaying the results&lt;br /&gt;
	if options.combined then&lt;br /&gt;
		-- We need 2 rows available for the expected and actual columns&lt;br /&gt;
		-- Top one is parsed, bottom is unparsed&lt;br /&gt;
		local differs_at = self.differs_at and (&#039; \n| rowspan=2|&#039; .. first_difference(compared_expected, compared_actual)) or &#039;&#039;&lt;br /&gt;
		-- Local copies of tick/cross to allow for highlighting&lt;br /&gt;
		local highlight = (should_highlight and not success and &#039;style=&amp;quot;background:#fc0;&amp;quot; &#039;) or &#039;&#039;&lt;br /&gt;
		result_table:insert(													-- Start output&lt;br /&gt;
			&#039;| &#039;, highlight, &#039;rowspan=2|&#039;, success and tick or cross,			-- Tick/Cross (2 rows)&lt;br /&gt;
			&#039; \n| rowspan=2|&#039;, mw.text.nowiki(text), &#039; \n| &#039;,					-- Text used for the test (2 rows)&lt;br /&gt;
			expected, &#039; \n| &#039;, actual,											-- The parsed outputs (in the 1st row)&lt;br /&gt;
			differs_at, &#039; \n|-\n| &#039;,											-- Where any relevant difference was (2 rows)&lt;br /&gt;
			mw.text.nowiki(expected), &#039; \n| &#039;, mw.text.nowiki(actual),			-- The unparsed outputs (in the 2nd row)&lt;br /&gt;
			&#039;\n|-\n&#039;															-- End output&lt;br /&gt;
		)&lt;br /&gt;
	else&lt;br /&gt;
		-- Display normally with whichever option was preferred (nowiki/parsed)&lt;br /&gt;
		local differs_at = self.differs_at and (&#039; \n| &#039; .. first_difference(compared_expected, compared_actual)) or &#039;&#039;&lt;br /&gt;
		local formatting = options.nowiki and mw.text.nowiki or return_varargs&lt;br /&gt;
		local highlight = (should_highlight and not success and &#039;style=&amp;quot;background:#fc0;&amp;quot;|&#039;) or &#039;&#039;&lt;br /&gt;
		result_table:insert(													-- Start output&lt;br /&gt;
			&#039;| &#039;, highlight, success and tick or cross,							-- Tick/Cross&lt;br /&gt;
			&#039; \n| &#039;, mw.text.nowiki(text), &#039; \n| &#039;,								-- Text used for the test&lt;br /&gt;
			formatting(expected), &#039; \n| &#039;, formatting(actual),					-- The formatted outputs&lt;br /&gt;
			differs_at,															-- Where any relevant difference was&lt;br /&gt;
			&#039;\n|-\n&#039;															-- End output&lt;br /&gt;
		)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:preprocess_equals(text, expected, options)&lt;br /&gt;
    local actual = frame:preprocess(text)&lt;br /&gt;
    self:calculate_output(text, expected, actual, options)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:preprocess_equals_many(prefix, suffix, cases, options)&lt;br /&gt;
    for _, case in ipairs(cases) do&lt;br /&gt;
        self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:preprocess_equals_preprocess(text1, text2, options)&lt;br /&gt;
	local actual = frame:preprocess(text1)&lt;br /&gt;
	local expected = frame:preprocess(text2)&lt;br /&gt;
	self:calculate_output(text1, expected, actual, options)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:preprocess_equals_compare(live, sandbox, expected, options)&lt;br /&gt;
	local live_text = frame:preprocess(live)&lt;br /&gt;
	local sandbox_text = frame:preprocess(sandbox)&lt;br /&gt;
	local highlight_live = false&lt;br /&gt;
	local highlight_sandbox = false&lt;br /&gt;
	num_runs = num_runs + 1&lt;br /&gt;
	if live_text == expected and sandbox_text == expected then&lt;br /&gt;
		result_table:insert(&#039;| &#039;, tick)&lt;br /&gt;
	else&lt;br /&gt;
		result_table:insert(&#039;| &#039;, cross)&lt;br /&gt;
		num_failures = num_failures + 1&lt;br /&gt;
&lt;br /&gt;
		if live_text ~= expected then&lt;br /&gt;
			highlight_live = true&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if sandbox_text ~= expected then&lt;br /&gt;
			highlight_sandbox = true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
    local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs&lt;br /&gt;
    local differs_at = self.differs_at and (&#039; \n| &#039; .. first_difference(expected, live_text) or first_difference(expected, sandbox_text)) or &#039;&#039;&lt;br /&gt;
    result_table:insert(&lt;br /&gt;
			&#039; \n| &#039;,&lt;br /&gt;
			mw.text.nowiki(live),&lt;br /&gt;
			should_highlight and highlight_live and &#039; \n|style=&amp;quot;background: #fc0;&amp;quot;| &#039; or &#039; \n| &#039;,&lt;br /&gt;
			formatting(live_text),&lt;br /&gt;
			should_highlight and highlight_sandbox and &#039; \n|style=&amp;quot;background: #fc0;&amp;quot;| &#039; or &#039; \n| &#039;,&lt;br /&gt;
			formatting(sandbox_text),&lt;br /&gt;
			&#039; \n| &#039;,&lt;br /&gt;
			formatting(expected),&lt;br /&gt;
			differs_at,&lt;br /&gt;
			&amp;quot;\n|-\n&amp;quot;&lt;br /&gt;
	)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options)&lt;br /&gt;
    for _, case in ipairs(cases) do&lt;br /&gt;
        self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:preprocess_equals_sandbox_many(module, function_name, cases, options)&lt;br /&gt;
    for _, case in ipairs(cases) do&lt;br /&gt;
		local live = module .. &amp;quot;|&amp;quot; .. function_name .. &amp;quot;|&amp;quot; .. case[1] .. &amp;quot;}}&amp;quot;&lt;br /&gt;
		local sandbox = module .. &amp;quot;/sandbox|&amp;quot; .. function_name .. &amp;quot;|&amp;quot; .. case[1] .. &amp;quot;}}&amp;quot;&lt;br /&gt;
        self:preprocess_equals_compare(live, sandbox, case[2], options)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:equals(name, actual, expected, options)&lt;br /&gt;
	num_runs = num_runs + 1&lt;br /&gt;
    if actual == expected then&lt;br /&gt;
        result_table:insert(&#039;| &#039;, tick)&lt;br /&gt;
    else&lt;br /&gt;
        result_table:insert(&#039;| &#039;, cross)&lt;br /&gt;
        num_failures = num_failures + 1&lt;br /&gt;
    end&lt;br /&gt;
    local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs&lt;br /&gt;
    local differs_at = self.differs_at and (&#039; \n| &#039; .. first_difference(expected, actual)) or &#039;&#039;&lt;br /&gt;
    local display = options and options.display or return_varargs&lt;br /&gt;
    result_table:insert(&#039; \n| &#039;, name, &#039; \n| &#039;,&lt;br /&gt;
    	formatting(tostring(display(expected))), &#039; \n| &#039;,&lt;br /&gt;
    	formatting(tostring(display(actual))), differs_at, &amp;quot;\n|-\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function deep_compare(t1, t2, ignore_mt)&lt;br /&gt;
    local ty1 = type(t1)&lt;br /&gt;
    local ty2 = type(t2)&lt;br /&gt;
    if ty1 ~= ty2 then return false end&lt;br /&gt;
    if ty1 ~= &#039;table&#039; and ty2 ~= &#039;table&#039; then return t1 == t2 end&lt;br /&gt;
&lt;br /&gt;
    local mt = getmetatable(t1)&lt;br /&gt;
    if not ignore_mt and mt and mt.__eq then return t1 == t2 end&lt;br /&gt;
&lt;br /&gt;
    for k1, v1 in pairs(t1) do&lt;br /&gt;
        local v2 = t2[k1]&lt;br /&gt;
        if v2 == nil or not deep_compare(v1, v2) then return false end&lt;br /&gt;
    end&lt;br /&gt;
    for k2, v2 in pairs(t2) do&lt;br /&gt;
        local v1 = t1[k2]&lt;br /&gt;
        if v1 == nil or not deep_compare(v1, v2) then return false end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function val_to_str(obj)&lt;br /&gt;
    local function table_key_to_str(k)&lt;br /&gt;
        if type(k) == &#039;string&#039; and mw.ustring.match(k, &#039;^[_%a][_%a%d]*$&#039;) then&lt;br /&gt;
            return k&lt;br /&gt;
        else&lt;br /&gt;
            return &#039;[&#039; .. val_to_str(k) .. &#039;]&#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if type(obj) == &amp;quot;string&amp;quot; then&lt;br /&gt;
        obj = mw.ustring.gsub(obj, &amp;quot;\n&amp;quot;, &amp;quot;\\n&amp;quot;)&lt;br /&gt;
        if mw.ustring.match(mw.ustring.gsub(obj, &#039;[^\&#039;&amp;quot;]&#039;, &#039;&#039;), &#039;^&amp;quot;+$&#039;) then&lt;br /&gt;
            return &amp;quot;&#039;&amp;quot; .. obj .. &amp;quot;&#039;&amp;quot;&lt;br /&gt;
        end&lt;br /&gt;
        return &#039;&amp;quot;&#039; .. mw.ustring.gsub(obj, &#039;&amp;quot;&#039;, &#039;\\&amp;quot;&#039; ) .. &#039;&amp;quot;&#039;&lt;br /&gt;
&lt;br /&gt;
    elseif type(obj) == &amp;quot;table&amp;quot; then&lt;br /&gt;
        local result, checked = {}, {}&lt;br /&gt;
        for k, v in ipairs(obj) do&lt;br /&gt;
            table.insert(result, val_to_str(v))&lt;br /&gt;
            checked[k] = true&lt;br /&gt;
        end&lt;br /&gt;
        for k, v in pairs(obj) do&lt;br /&gt;
            if not checked[k] then&lt;br /&gt;
                table.insert(result, table_key_to_str(k) .. &#039;=&#039; .. val_to_str(v))&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        return &#039;{&#039; .. table.concat(result, &#039;,&#039;) .. &#039;}&#039;&lt;br /&gt;
&lt;br /&gt;
    else&lt;br /&gt;
        return tostring(obj)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:equals_deep(name, actual, expected, options)&lt;br /&gt;
	num_runs = num_runs + 1&lt;br /&gt;
    if deep_compare(actual, expected) then&lt;br /&gt;
        result_table:insert(&#039;| &#039;, tick)&lt;br /&gt;
    else&lt;br /&gt;
        result_table:insert(&#039;| &#039;, cross)&lt;br /&gt;
        num_failures = num_failures + 1&lt;br /&gt;
    end&lt;br /&gt;
    local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs&lt;br /&gt;
    local actual_str = val_to_str(actual)&lt;br /&gt;
    local expected_str = val_to_str(expected)&lt;br /&gt;
    local differs_at = self.differs_at and (&#039; \n| &#039; .. first_difference(expected_str, actual_str)) or &#039;&#039;&lt;br /&gt;
    result_table:insert(&#039; \n| &#039;, name, &#039; \n| &#039;, formatting(expected_str),&lt;br /&gt;
    	&#039; \n| &#039;, formatting(actual_str), differs_at, &amp;quot;\n|-\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:iterate(examples, func)&lt;br /&gt;
	require &#039;libraryUtil&#039;.checkType(&#039;iterate&#039;, 1, examples, &#039;table&#039;)&lt;br /&gt;
	if type(func) == &#039;string&#039; then&lt;br /&gt;
		func = self[func]&lt;br /&gt;
	elseif type(func) ~= &#039;function&#039; then&lt;br /&gt;
		error((&amp;quot;bad argument #2 to &#039;iterate&#039; (expected function or string, got %s)&amp;quot;)&lt;br /&gt;
			:format(type(func)), 2)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for i, example in ipairs(examples) do&lt;br /&gt;
		if type(example) == &#039;table&#039; then&lt;br /&gt;
			func(self, unpack(example))&lt;br /&gt;
		elseif type(example) == &#039;string&#039; then&lt;br /&gt;
			self:heading(example)&lt;br /&gt;
		else&lt;br /&gt;
			error((&#039;bad example #%d (expected table, got %s)&#039;)&lt;br /&gt;
				:format(i, type(example)), 2)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:heading(text)&lt;br /&gt;
	result_table:insert_format(&#039; ! colspan=&amp;quot;%u&amp;quot; style=&amp;quot;text-align: left&amp;quot; | %s \n |- \n &#039;,&lt;br /&gt;
		self.columns, text)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:run(frame_arg)&lt;br /&gt;
    frame = frame_arg&lt;br /&gt;
    self.frame = frame&lt;br /&gt;
    self.differs_at = frame.args[&#039;differs_at&#039;]&lt;br /&gt;
    tick = frame:preprocess(&#039;{{Tick}}&#039;)&lt;br /&gt;
    cross = frame:preprocess(&#039;{{Cross}}&#039;)&lt;br /&gt;
&lt;br /&gt;
	local table_header = result_table_header&lt;br /&gt;
	if frame.args[&#039;live_sandbox&#039;] then&lt;br /&gt;
		table_header = result_table_live_sandbox_header&lt;br /&gt;
	end&lt;br /&gt;
	if frame.args.highlight then&lt;br /&gt;
		should_highlight = true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self.columns = 4&lt;br /&gt;
    if self.differs_at then&lt;br /&gt;
        table_header = table_header .. &#039; !! Differs at&#039;&lt;br /&gt;
        self.columns = self.columns + 1&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Sort results into alphabetical order.&lt;br /&gt;
    local self_sorted = {}&lt;br /&gt;
    for key, _ in pairs(self) do&lt;br /&gt;
        if key:find(&#039;^test&#039;) then&lt;br /&gt;
            table.insert(self_sorted, key)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    table.sort(self_sorted)&lt;br /&gt;
    -- Add results to the results table.&lt;br /&gt;
    for _, value in ipairs(self_sorted) do&lt;br /&gt;
        result_table:insert_format(table_header .. &amp;quot;\n|-\n&amp;quot;, value)&lt;br /&gt;
        self[value](self)&lt;br /&gt;
        result_table:insert(&amp;quot;|}\n&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    return (num_runs == 0 and &amp;quot;&amp;lt;b&amp;gt;No tests were run.&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
    	or num_failures == 0 and &amp;quot;&amp;lt;b style=\&amp;quot;color:#008000\&amp;quot;&amp;gt;All &amp;quot; .. num_runs .. &amp;quot; tests passed.&amp;lt;/b&amp;gt;&amp;quot;&lt;br /&gt;
    	or &amp;quot;&amp;lt;b style=\&amp;quot;color:#800000\&amp;quot;&amp;gt;&amp;quot; .. num_failures .. &amp;quot; of &amp;quot; .. num_runs .. &amp;quot; tests failed.&amp;lt;/b&amp;gt;[[Category:Failed Lua testcases using Module:UnitTests]]&amp;quot;&lt;br /&gt;
    ) .. &amp;quot;\n\n&amp;quot; .. frame:preprocess(result_table:concat())&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function UnitTester:new()&lt;br /&gt;
    local o = {}&lt;br /&gt;
    setmetatable(o, self)&lt;br /&gt;
    self.__index = self&lt;br /&gt;
    return o&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local p = UnitTester:new()&lt;br /&gt;
function p.run_tests(frame) return p:run(frame) end&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Pp-template&amp;diff=261</id>
		<title>Modèle:Pp-template</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Pp-template&amp;diff=261"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{#invoke:Protection banner|main}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Catalog_lookup_link&amp;diff=259</id>
		<title>Module:Catalog lookup link</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Catalog_lookup_link&amp;diff=259"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[&lt;br /&gt;
|1=, |2=, |3=, |4=, |5=, |6=, |7=, |8=, |9=: Optional unnamed parameters for 0 to 9 items to be listed.&lt;br /&gt;
	Whitespace is trimmed off both ends and the strings are urlencoded as if they were query strings.&lt;br /&gt;
|article-link=: Optional Wikipedia article name to link to.&lt;br /&gt;
|article-name=: Optional alternative text to be displayed for |article-link= link in front of catalog link.&lt;br /&gt;
	If not specified, |article-link= is used for display as well. If both parameters are not specified, the prefix is omitted completely.&lt;br /&gt;
|article-suffix=: Optional symbol to be displayed after article name or link (f.e. &amp;quot;:&amp;quot;; omitted, if not defined).&lt;br /&gt;
|link-prefix=: Optional prefix portion of url to external catalog item(s).&lt;br /&gt;
|link-suffix=: Optional suffix portion of url to external catalog item(s).&lt;br /&gt;
|item-prefix=: Optional text displayed in front of each external link (omitted, if not defined)&lt;br /&gt;
|item-suffix=: Optional text displayed immediately after each external link (omitted, if not defined)&lt;br /&gt;
|list-separator=: Optional alternative separator displayed between list items (default: &amp;quot;, &amp;quot;, if not specified). Whitespace must be encoded.&lt;br /&gt;
|list-leadout=: Optional alternative leadout text displayed between the last two list items (f.e. &amp;quot;and&amp;quot;, &amp;quot;or&amp;quot;, &amp;quot;as well as&amp;quot;, etc., default is the |list-separator= or &amp;quot;, &amp;quot;.)&lt;br /&gt;
|leadout-suffix=: Optional alternative suffix text of the leadout (see |list-leadout=) displayed between the last two list items.&lt;br /&gt;
	This gets added in front of the last list item instead of the default whitespace which is added without this parameter.&lt;br /&gt;
	This may be necessary if |list-separator= is used not only to define the list separator but also parts of the item prefix&lt;br /&gt;
	(except for the first one). (At present, this is used only to cope with format oddities of the {{MR}} template.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
new parameters that support access icons:&lt;br /&gt;
|allowed_icons= – comma-separated list of keywords: free, limited, registration, subscription, none, all (default; &#039;all&#039; implied when this parameter empty or omitted)&lt;br /&gt;
	the icons specified in the following parameters are checked agains the list in |allowed-icons=; not in the list? not displayed&lt;br /&gt;
|url-access-all= – applies specified icon to all items in the list; accepted keywords: free, limited, registration, subscription;&lt;br /&gt;
|url-accessn= – applies specified icon to item n of the list (the nth positional parameter); accepted keywords: free, limited, registration, subscription;&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
require(&#039;strict&#039;);&lt;br /&gt;
local getArgs = require (&#039;Module:Arguments&#039;).getArgs;&lt;br /&gt;
local lock_icons = {															--icon classes are defined in Module:Citation/CS1/styles.css&lt;br /&gt;
	[&#039;free&#039;] = {&#039;id-lock-free&#039;, &#039;Freely accessible&#039;},&lt;br /&gt;
	[&#039;registration&#039;] = {&#039;id-lock-registration&#039;, &#039;Free registration required&#039;},&lt;br /&gt;
	[&#039;limited&#039;] = {&#039;id-lock-limited&#039;, &#039;Free access subject to limited trial, subscription normally required&#039;},&lt;br /&gt;
	[&#039;subscription&#039;] = {&#039;id-lock-subscription&#039;, &#039;Paid subscription required&#039;},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ S E T &amp;gt;------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Returns true if argument is set; false otherwise. Argument is &#039;set&#039; when it exists (not nil) or when it is not an empty string.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function is_set( var )&lt;br /&gt;
	return not (var == nil or var == &#039;&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[-------------------------&amp;lt; M A K E _ L A B E L &amp;gt;----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Makes a wikilinked or plain text label from arguments; when both link and display text is provided, makes a&lt;br /&gt;
wikilink in the form [[L|D]]; if only link is provided, makes a wikilinked label in the form [[L]]; if only display&lt;br /&gt;
is provided, makes a plain-text label; if neither are provided makes a label from suffix, returns an empty string else.&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function make_label (link, display, suffix)&lt;br /&gt;
local label = &#039;&#039;;&lt;br /&gt;
	if is_set (link) then&lt;br /&gt;
		if is_set (display) then&lt;br /&gt;
			label = table.concat ({&#039;[[&#039;, link, &#039;|&#039;, display, &#039;]]&#039;});			-- make [[L|D]] wikilinked label&lt;br /&gt;
		else&lt;br /&gt;
			label = table.concat ({&#039;[[&#039;, link, &#039;]]&#039;});							-- make [[L]] wikilinked label&lt;br /&gt;
		end&lt;br /&gt;
	elseif is_set (display) then&lt;br /&gt;
		label = display;														-- plain-text label&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if is_set (label) then														&lt;br /&gt;
		return table.concat ({label, suffix, &#039;&amp;amp;nbsp;&#039;});						-- assemble the complete label&lt;br /&gt;
	else&lt;br /&gt;
		return suffix;															-- no space after suffix if no label&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I C O N _ I N D E X _ G E T &amp;gt;--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
returns index into lock_icons[] if value assigned to |url-access= or |url-access-all= is a valid icon selector&lt;br /&gt;
(free, limited, registration, subscription)&lt;br /&gt;
&lt;br /&gt;
icon selection may be limited to a subset of the icons with:&lt;br /&gt;
	|allow_icons=&amp;lt;comma-separated list of allowed icons&amp;gt;&lt;br /&gt;
&amp;lt;comma-separated list of allowed icons&amp;gt; may be any of the keywords: free, limited, registration, subscription, none, all&lt;br /&gt;
&lt;br /&gt;
keyword &#039;all&#039; is default condition; &#039;all&#039; is implied when |allowed=icons= is empty or omitted&lt;br /&gt;
&lt;br /&gt;
keyword &#039;none&#039; for use with identifiers where icons are inappropriate (isbn, issn, oclc)&lt;br /&gt;
&lt;br /&gt;
Templates using this module should set:&lt;br /&gt;
	|allow_icons=free for most identifiers;&lt;br /&gt;
	|allow_icons=none for isbn, issn, oclc, etc&lt;br /&gt;
&lt;br /&gt;
|url-access= is alias of |url-access1=&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function icon_index_get (args, k)&lt;br /&gt;
	local icon;&lt;br /&gt;
	local param_name = (1 == k and is_set (args[&#039;url-access&#039;]) and &#039;url-access&#039;) or table.concat ({&#039;url-access&#039;, k});	-- make an enumerated parameter name&lt;br /&gt;
&lt;br /&gt;
	if is_set (args[&#039;url-access-all&#039;]) and lock_icons[args[&#039;url-access-all&#039;]] then	-- if set and valid&lt;br /&gt;
		icon = args[&#039;url-access-all&#039;];											-- tentatively &lt;br /&gt;
&lt;br /&gt;
	elseif is_set (args[param_name]) and lock_icons[args[param_name]] then		-- if set and valid&lt;br /&gt;
		icon = args[param_name];												-- tentatively&lt;br /&gt;
&lt;br /&gt;
	else&lt;br /&gt;
		return nil;																-- neither |url-access-all= nor |url-accessn= set so return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if args[&#039;allow_icons&#039;] and args[&#039;allow_icons&#039;]:find (&#039;none&#039;) then			-- if &#039;none&#039; keyword is present&lt;br /&gt;
		return nil;																-- icons display not allowed&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not is_set (args[&#039;allow_icons&#039;]) or args[&#039;allow_icons&#039;]:find (&#039;all&#039;) or args[&#039;allow_icons&#039;]:find (icon) then	--if all allowed or specified icon is allowed&lt;br /&gt;
		return icon;															-- return selected icon as index into icon table&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; M A I N &amp;gt;----------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Template entrypoint to this module; arguments come primarily from the parent frame though in templates that use&lt;br /&gt;
this module, |allowed-icons= is typically set, if needed, in the {{#invoke:}}.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function main (frame)&lt;br /&gt;
	local args = getArgs (frame);&lt;br /&gt;
	local out_text = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
	if is_set(args[1]) then&lt;br /&gt;
		local result = {};&lt;br /&gt;
		local label;&lt;br /&gt;
		&lt;br /&gt;
		local article_suffix = args[&#039;article-suffix&#039;] or args[&#039;article-postfix&#039;] or &#039;&#039;;&lt;br /&gt;
		local link_prefix = args[&#039;link-prefix&#039;] or &#039;&#039;;&lt;br /&gt;
		local link_suffix = args[&#039;link-suffix&#039;] or args[&#039;link-postfix&#039;] or &#039;&#039;;&lt;br /&gt;
		local item_prefix = args[&#039;item-prefix&#039;] or &#039;&#039;;&lt;br /&gt;
		local item_suffix = args[&#039;item-suffix&#039;] or args[&#039;item-postfix&#039;] or &#039;&#039;;&lt;br /&gt;
		local list_separator = args[&#039;list-separator&#039;] or &#039;, &#039;;&lt;br /&gt;
		local leadout_suffix = args[&#039;leadout-suffix&#039;] or args[&#039;leadout-postfix&#039;] or &#039; &#039;;&lt;br /&gt;
		local list_leadout;&lt;br /&gt;
&lt;br /&gt;
		local icon_index;&lt;br /&gt;
		&lt;br /&gt;
		if is_set (args[&#039;list-leadout&#039;]) then&lt;br /&gt;
			list_leadout = table.concat ({&lt;br /&gt;
				mw.ustring.gsub (args[&#039;list-leadout&#039;], &#039;^(%a)&#039;, &#039; %1&#039;),			-- insert leading space if first character is a letter&lt;br /&gt;
				leadout_suffix,&lt;br /&gt;
			});&lt;br /&gt;
		else&lt;br /&gt;
			list_leadout = &#039;&#039;;&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		label = make_label (args[&#039;article-link&#039;], args[&#039;article-name&#039;], article_suffix);&lt;br /&gt;
&lt;br /&gt;
		for k, item in ipairs (args) do											-- for each of the positional parameters&lt;br /&gt;
			item = mw.text.trim (item);											-- remove extraneous whitespace&lt;br /&gt;
			if is_set (link_prefix) then										-- if there is link prefix...&lt;br /&gt;
				item = table.concat ({											-- create an external link item&lt;br /&gt;
					&#039;[&#039;,														-- open ext link markup&lt;br /&gt;
					link_prefix,												-- url prefix&lt;br /&gt;
					mw.uri.encode (item),										-- item is part of url&lt;br /&gt;
					link_suffix,												-- url suffix&lt;br /&gt;
					&#039; &#039;,														-- required space between url and label&lt;br /&gt;
					item_prefix,												-- label prefix&lt;br /&gt;
					item,														-- item as label&lt;br /&gt;
					item_suffix,												-- item suffix&lt;br /&gt;
					&#039;]&#039;															-- close ext link markup&lt;br /&gt;
				});&lt;br /&gt;
&lt;br /&gt;
				icon_index = icon_index_get (args, k);							-- set if icon specified and allowed for this item; nil else&lt;br /&gt;
				if icon_index then&lt;br /&gt;
					item = table.concat ({										-- add access icon markup to this item&lt;br /&gt;
						&#039;&amp;lt;span class=&amp;quot;&#039;,										-- open the opening span tag; icon classes are defined in Module:Citation/CS1/styles.css&lt;br /&gt;
						lock_icons[icon_index][1],								-- add the appropriate lock icon class&lt;br /&gt;
						&#039;&amp;quot; title=&amp;quot;&#039;,											-- and the title attribute&lt;br /&gt;
						lock_icons[icon_index][2],								-- for an appropriate tool tip&lt;br /&gt;
						&#039;&amp;quot;&amp;gt;&#039;,													-- close the opening span tag&lt;br /&gt;
						item,&lt;br /&gt;
						&#039;&amp;lt;/span&amp;gt;&#039;,												-- and close the span&lt;br /&gt;
					});&lt;br /&gt;
				end	&lt;br /&gt;
			else&lt;br /&gt;
				item = table.concat ({											-- create an unlinked item&lt;br /&gt;
					item_prefix,												-- label prefix&lt;br /&gt;
					item,														-- item as label&lt;br /&gt;
					item_suffix,												-- item suffix&lt;br /&gt;
				});&lt;br /&gt;
			end&lt;br /&gt;
	&lt;br /&gt;
			table.insert (result, item);										-- add the item to the result list&lt;br /&gt;
		end&lt;br /&gt;
	&lt;br /&gt;
		out_text = frame:callParserFunction(&#039;#tag&#039;, {&#039;templatestyles&#039;, &#039;&#039;, src=table.concat({&lt;br /&gt;
			&#039;Module:Citation/CS1&#039;,&lt;br /&gt;
			mw.ustring.match(frame:getTitle(), &#039;/sandbox$&#039;) or &#039;&#039;,&lt;br /&gt;
			&#039;/styles.css&#039;,&lt;br /&gt;
		})});&lt;br /&gt;
		if is_set (args[&#039;list-leadout&#039;]) then&lt;br /&gt;
			out_text = table.concat ({out_text, label, mw.text.listToText (result, list_separator, list_leadout)});&lt;br /&gt;
		else&lt;br /&gt;
			out_text = table.concat ({out_text, label, table.concat (result, list_separator)});&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	end	--is_set (args[1])&lt;br /&gt;
&lt;br /&gt;
	return out_text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return {main = main};&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Catalog_lookup_link&amp;diff=257</id>
		<title>Modèle:Catalog lookup link</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Catalog_lookup_link&amp;diff=257"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#invoke:Catalog lookup link|main}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Nutshell&amp;diff=255</id>
		<title>Modèle:Nutshell</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Nutshell&amp;diff=255"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{mbox&lt;br /&gt;
| class = nutshell&lt;br /&gt;
| image = [[File:Walnut.png|30px|link=|alt=]]&lt;br /&gt;
| text = &#039;&#039;&#039;{{{title|This page}}} in a nutshell:&#039;&#039;&#039; {{#if:{{{2|}}}&lt;br /&gt;
  | {{unordered list|{{{1|}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}}}&lt;br /&gt;
  | {{{1}}}&lt;br /&gt;
  }}&lt;br /&gt;
| imageright = {{#if:{{{shortcut|{{{shortcut1|}}}}}} | {{Ombox/shortcut|{{{shortcut|{{{shortcut1|}}}}}}|{{{shortcut2|}}}|{{{shortcut3|}}}|{{{shortcut4|}}}|{{{shortcut5|}}} }} }}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage, and interwikis go on Wikidata.  --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Para&amp;diff=253</id>
		<title>Modèle:Para</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Para&amp;diff=253"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code class=&amp;quot;tpl-para&amp;quot; style=&amp;quot;word-break:break-word;{{SAFESUBST:&amp;lt;noinclude /&amp;gt;#if:{{{plain|}}}|border: none; background-color: inherit;}} {{SAFESUBST:&amp;lt;noinclude /&amp;gt;#if:{{{plain|}}}{{{mxt|}}}{{{green|}}}{{{!mxt|}}}{{{red|}}}|color: {{SAFESUBST:&amp;lt;noinclude /&amp;gt;#if:{{{mxt|}}}{{{green|}}}|#006400|{{SAFESUBST:&amp;lt;noinclude /&amp;gt;#if:{{{!mxt|}}}{{{red|}}}|#8B0000|inherit}}}};}} {{SAFESUBST:&amp;lt;noinclude /&amp;gt;#if:{{{style|}}}|{{{style}}}}}&amp;quot;&amp;gt;&amp;amp;#124;{{SAFESUBST:&amp;lt;noinclude /&amp;gt;#if:{{{1|}}}|{{{1}}}&amp;amp;#61;}}{{{2|}}}&amp;lt;/code&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!--Categories and interwikis go near the bottom of the /doc subpage.--&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Cite_web&amp;diff=251</id>
		<title>Modèle:Cite web</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Cite_web&amp;diff=251"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{#invoke:citation/CS1|citation&lt;br /&gt;
|CitationClass=web&lt;br /&gt;
}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_link&amp;diff=249</id>
		<title>Modèle:Template link</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Template_link&amp;diff=249"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{nowrap|&amp;amp;#123;&amp;amp;#123;}}[[Template:{{{1}}}|{{{1}}}]]{{nowrap|&amp;amp;#125;&amp;amp;#125;}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc subpage and interwikis go on Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Tl&amp;diff=247</id>
		<title>Modèle:Tl</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Tl&amp;diff=247"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Template:Template link]]&lt;br /&gt;
&lt;br /&gt;
{{Redirect category shell|&lt;br /&gt;
{{R from move}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Nowrap&amp;diff=245</id>
		<title>Modèle:Nowrap</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Nowrap&amp;diff=245"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;span class=&amp;quot;nowrap&amp;quot;&amp;gt;{{{1}}}&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Categories go on the /doc page; interwikis go to Wikidata. --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Category_link/core&amp;diff=243</id>
		<title>Modèle:Category link/core</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Mod%C3%A8le:Category_link/core&amp;diff=243"/>
		<updated>2024-07-31T17:35:05Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[:Category:{{{1}}}|{{{2}}}]]{{#if:{{Yesno|1={{{count|no}}}}}|&amp;amp;nbsp;&amp;lt;small style=&amp;quot;{{#ifexpr:{{{page_count}}}&amp;gt;={{{backlog}}}|font-weight: bold; color: #DD0000;}}&amp;quot;&amp;gt;(&amp;amp;thinsp;{{formatnum:{{{page_count}}}}}&amp;amp;thinsp;)&amp;lt;/small&amp;gt;}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Documentation|Template:Category link/doc}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://cyclopedia.btz.alsace/index.php?title=Module:Cs1_documentation_support&amp;diff=241</id>
		<title>Module:Cs1 documentation support</title>
		<link rel="alternate" type="text/html" href="https://cyclopedia.btz.alsace/index.php?title=Module:Cs1_documentation_support&amp;diff=241"/>
		<updated>2024-07-31T17:35:04Z</updated>

		<summary type="html">&lt;p&gt;Admin : 1 version importée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;require(&#039;strict&#039;);&lt;br /&gt;
local getArgs = require (&#039;Module:Arguments&#039;).getArgs;&lt;br /&gt;
&lt;br /&gt;
local cfg = mw.loadData (&#039;Module:Citation/CS1/Configuration&#039;);					-- load the configuration module&lt;br /&gt;
local whitelist = mw.loadData (&#039;Module:Citation/CS1/Whitelist&#039;);				-- load the whitelist module&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local exclusion_lists = {														-- TODO: move these tables into a separate ~/data module and mw.loadData() it&lt;br /&gt;
	[&#039;cite book&#039;] = {&lt;br /&gt;
		[&#039;agency&#039;] = true,&lt;br /&gt;
		[&#039;air-date&#039;] = true,&lt;br /&gt;
		[&#039;arxiv&#039;] = true,&lt;br /&gt;
		[&#039;biorxiv&#039;] = true,&lt;br /&gt;
		[&#039;citeseerx&#039;] = true,&lt;br /&gt;
		[&#039;class&#039;] = true,&lt;br /&gt;
		[&#039;conference&#039;] = true,&lt;br /&gt;
		[&#039;conference-format&#039;] = true,&lt;br /&gt;
		[&#039;conference-url&#039;] = true,&lt;br /&gt;
		[&#039;degree&#039;] = true,&lt;br /&gt;
		[&#039;department&#039;] = true,&lt;br /&gt;
		[&#039;display-interviewers&#039;] = true,&lt;br /&gt;
		[&#039;docket&#039;] = true,&lt;br /&gt;
		[&#039;episode&#039;] = true,&lt;br /&gt;
		[&#039;interviewer#&#039;] = true,&lt;br /&gt;
		[&#039;interviewer-first#&#039;] = true,&lt;br /&gt;
		[&#039;interviewer-link#&#039;] = true,&lt;br /&gt;
		[&#039;interviewer-mask#&#039;] = true,&lt;br /&gt;
		[&#039;ismn&#039;] = true,&lt;br /&gt;
		[&#039;issn&#039;] = true,&lt;br /&gt;
		[&#039;issue&#039;] = true,&lt;br /&gt;
		[&#039;jfm&#039;] = true,&lt;br /&gt;
		[&#039;journal&#039;] = true,&lt;br /&gt;
		[&#039;jstor&#039;] = true,&lt;br /&gt;
		[&#039;mailinglist&#039;] = true,&lt;br /&gt;
		[&#039;message-id&#039;] = true,&lt;br /&gt;
		[&#039;minutes&#039;] = true,&lt;br /&gt;
		[&#039;MR&#039;] = true,&lt;br /&gt;
		[&#039;network&#039;] = true,&lt;br /&gt;
		[&#039;number&#039;] = true,&lt;br /&gt;
		[&#039;RFC&#039;] = true,&lt;br /&gt;
		[&#039;script-journal&#039;] = true,&lt;br /&gt;
		[&#039;season&#039;] = true,&lt;br /&gt;
		[&#039;section&#039;] = true,&lt;br /&gt;
		[&#039;sections&#039;] = true,&lt;br /&gt;
		[&#039;series-link&#039;] = true,&lt;br /&gt;
		[&#039;series-number&#039;] = true,&lt;br /&gt;
		[&#039;series-separator&#039;] = true,&lt;br /&gt;
		[&#039;sheet&#039;] = true,&lt;br /&gt;
		[&#039;sheets&#039;] = true,&lt;br /&gt;
		[&#039;SSRN&#039;] = true,&lt;br /&gt;
		[&#039;station&#039;] = true,&lt;br /&gt;
		[&#039;time&#039;] = true,&lt;br /&gt;
		[&#039;time-caption&#039;] = true,&lt;br /&gt;
		[&#039;trans-article&#039;] = true,&lt;br /&gt;
		[&#039;trans-journal&#039;] = true,&lt;br /&gt;
		[&#039;transcript&#039;] = true,&lt;br /&gt;
		[&#039;transcript-format&#039;] = true,&lt;br /&gt;
		[&#039;transcript-url&#039;] = true,&lt;br /&gt;
		[&#039;ZBL&#039;] = true,&lt;br /&gt;
		},&lt;br /&gt;
	[&#039;cite journal&#039;] = {&lt;br /&gt;
		[&#039;agency&#039;] = true,&lt;br /&gt;
		[&#039;air-date&#039;] = true,&lt;br /&gt;
		[&#039;book-title&#039;] = true,&lt;br /&gt;
		[&#039;chapter&#039;] = true,&lt;br /&gt;
		[&#039;chapter-format&#039;] = true,&lt;br /&gt;
		[&#039;chapter-url&#039;] = true,&lt;br /&gt;
		[&#039;chapter-url-access&#039;] = true,&lt;br /&gt;
		[&#039;class&#039;] = true,&lt;br /&gt;
		[&#039;conference&#039;] = true,&lt;br /&gt;
		[&#039;conference-format&#039;] = true,&lt;br /&gt;
		[&#039;conference-url&#039;] = true,&lt;br /&gt;
		[&#039;contribution&#039;] = true,&lt;br /&gt;
		[&#039;contributor#&#039;] = true,&lt;br /&gt;
		[&#039;contributor-first#&#039;] = true,&lt;br /&gt;
		[&#039;contributor-link#&#039;] = true,&lt;br /&gt;
		[&#039;contributor-mask#&#039;] = true,&lt;br /&gt;
		[&#039;degree&#039;] = true,&lt;br /&gt;
		[&#039;department&#039;] = true,&lt;br /&gt;
		[&#039;display-interviewers&#039;] = true,&lt;br /&gt;
		[&#039;docket&#039;] = true,&lt;br /&gt;
		[&#039;edition&#039;] = true,&lt;br /&gt;
		[&#039;editor#&#039;] = true,&lt;br /&gt;
		[&#039;editor-first#&#039;] = true,&lt;br /&gt;
		[&#039;editor-link#&#039;] = true,&lt;br /&gt;
		[&#039;editor-mask#&#039;] = true,&lt;br /&gt;
		[&#039;editors&#039;] = true,&lt;br /&gt;
		[&#039;encyclopedia&#039;] = true,&lt;br /&gt;
		[&#039;episode&#039;] = true,&lt;br /&gt;
		[&#039;ignore-isbn-error&#039;] = true,&lt;br /&gt;
		[&#039;interviewer#&#039;] = true,&lt;br /&gt;
		[&#039;interviewer-first#&#039;] = true,&lt;br /&gt;
		[&#039;interviewer-link#&#039;] = true,&lt;br /&gt;
		[&#039;interviewer-mask#&#039;] = true,&lt;br /&gt;
		[&#039;isbn&#039;] = true,&lt;br /&gt;
		[&#039;ismn&#039;] = true,&lt;br /&gt;
		[&#039;LCCN&#039;] = true,&lt;br /&gt;
		[&#039;mailinglist&#039;] = true,&lt;br /&gt;
		[&#039;message-id&#039;] = true,&lt;br /&gt;
		[&#039;minutes&#039;] = true,&lt;br /&gt;
		[&#039;network&#039;] = true,&lt;br /&gt;
		[&#039;script-chapter&#039;] = true,&lt;br /&gt;
		[&#039;season&#039;] = true,&lt;br /&gt;
		[&#039;section&#039;] = true,&lt;br /&gt;
		[&#039;sections&#039;] = true,&lt;br /&gt;
		[&#039;series-link&#039;] = true,&lt;br /&gt;
		[&#039;series-number&#039;] = true,&lt;br /&gt;
		[&#039;series-separator&#039;] = true,&lt;br /&gt;
		[&#039;sheet&#039;] = true,&lt;br /&gt;
		[&#039;sheets&#039;] = true,&lt;br /&gt;
		[&#039;station&#039;] = true,&lt;br /&gt;
		[&#039;time&#039;] = true,&lt;br /&gt;
		[&#039;time-caption&#039;] = true,&lt;br /&gt;
		[&#039;trans-article&#039;] = true,&lt;br /&gt;
		[&#039;transcript&#039;] = true,&lt;br /&gt;
		[&#039;transcript-format&#039;] = true,&lt;br /&gt;
		[&#039;transcript-url&#039;] = true,&lt;br /&gt;
		},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
--[[-------------------------&amp;lt; A D D _ T O _ L I S T &amp;gt;---------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
adds code/name pair to code_list and name/code pair to name_list; code/name pairs in override_list replace those&lt;br /&gt;
taken from the MediaWiki list; these are marked with a superscripted dagger.&lt;br /&gt;
&lt;br /&gt;
|script-&amp;lt;param&amp;gt;= lang codes always use override names so dagger is omitted&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function add_to_list (code_list, name_list, override_list, code, name, dagger)&lt;br /&gt;
	if false == dagger then&lt;br /&gt;
		dagger = &#039;&#039;;															-- no dagger for |script-&amp;lt;param&amp;gt;= codes and names&lt;br /&gt;
	else&lt;br /&gt;
		dagger = &#039;&amp;lt;sup&amp;gt;†&amp;lt;/sup&amp;gt;&#039;;												-- dagger for all other lists using override&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if override_list[code] then													-- look in the override table for this code&lt;br /&gt;
		code_list[code] = override_list[code] .. dagger;						-- use the name from the override table; mark with dagger&lt;br /&gt;
		name_list[override_list[code]] = code .. dagger;&lt;br /&gt;
	else&lt;br /&gt;
		code_list[code] = name;													-- use the MediaWiki name and code&lt;br /&gt;
		name_list[name] = code;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[-------------------------&amp;lt; L I S T _ F O R M A T &amp;gt;---------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
formats key/value pair into a string for rendering&lt;br /&gt;
	[&#039;k&#039;] = &#039;v&#039;	→ k: v&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function list_format (result, list)&lt;br /&gt;
	for k, v in pairs (list)	do&lt;br /&gt;
		table.insert (result, k .. &#039;: &#039; .. v);&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[-------------------------&amp;lt; L A N G _ L I S T E R &amp;gt;---------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Module entry point&lt;br /&gt;
&lt;br /&gt;
Crude documentation tool that returns one of several lists of language codes and names.&lt;br /&gt;
&lt;br /&gt;
Used in Template:Citation Style documentation/language/doc&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|lang_lister|list=&amp;lt;selector&amp;gt;|lang=&amp;lt;code&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;selector&amp;gt; is one of the values:&lt;br /&gt;
	2char – list of ISO 639-1 codes and names sorted by code&lt;br /&gt;
	3char – list of ISO 639-2, -3 codes and names sorted by code&lt;br /&gt;
	ietf – list of IETF language tags and names sorted by tag&lt;br /&gt;
	ietf2 – list of ISO 639-1 based IETF language tags and names sorted by tag&lt;br /&gt;
	ietf3 – list of list of ISO 639-2, -3 based IETF language tags and names sorted by tag&lt;br /&gt;
	name – list of language names and codes sorted by name&lt;br /&gt;
	all - list all language codes/tags and names sorted by code/tag&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;code&amp;gt; is a MediaWiki supported 2, 3, or ietf-like language code; because of fall-back, language names may&lt;br /&gt;
be the English-language names.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function lang_lister (frame)&lt;br /&gt;
	local lang = (frame.args.lang and &#039;&#039; ~= frame.args.lang) and frame.args.lang or mw.getContentLanguage():getCode()&lt;br /&gt;
	local source_list = mw.language.fetchLanguageNames(lang, &#039;all&#039;);&lt;br /&gt;
	local override = cfg.lang_tag_remap;&lt;br /&gt;
	local code_1_list={};&lt;br /&gt;
	local code_2_list={};&lt;br /&gt;
	local ietf_list={};&lt;br /&gt;
	local ietf_list2={};&lt;br /&gt;
	local ietf_list3={};&lt;br /&gt;
	local name_list={};&lt;br /&gt;
	&lt;br /&gt;
	if not ({[&#039;2char&#039;]=true, [&#039;3char&#039;]=true, [&#039;ietf&#039;]=true, [&#039;ietf2&#039;]=true, [&#039;ietf3&#039;]=true, [&#039;name&#039;]=true, [&#039;all&#039;]=true})[frame.args.list] then&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;unknown list selector: &#039; .. frame.args.list .. &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for code, name in pairs (source_list) do&lt;br /&gt;
		if &#039;all&#039; == frame.args.list then&lt;br /&gt;
			add_to_list (code_1_list, name_list, override, code, name);			-- use the code_1_list because why not?&lt;br /&gt;
		elseif 2 == code:len() then&lt;br /&gt;
			add_to_list (code_1_list, name_list, override, code, name);&lt;br /&gt;
		elseif 3 == code:len() then&lt;br /&gt;
			add_to_list (code_2_list, name_list, override, code, name);&lt;br /&gt;
		elseif code:match (&#039;^%a%a%-.+&#039;) then									-- ietf with 2-character language tag&lt;br /&gt;
			add_to_list (ietf_list, name_list, override, code, name);			-- add to main ietf list for |list=ietf&lt;br /&gt;
			add_to_list (ietf_list2, name_list, override, code, name);			-- add to ietf2 list&lt;br /&gt;
		elseif code:match (&#039;^%a%a%a%-.+&#039;) then									-- ietf with 3-character language tag&lt;br /&gt;
			add_to_list (ietf_list, name_list, override, code, name);			-- add to main ietf list for |list=ietf&lt;br /&gt;
			add_to_list (ietf_list3, name_list, override, code, name);			-- add to ietf3 list&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local result = {};&lt;br /&gt;
	local out = {};&lt;br /&gt;
&lt;br /&gt;
	if &#039;2char&#039; == frame.args.list or &#039;all&#039; == frame.args.list then				-- iso 639-1&lt;br /&gt;
		list_format (result, code_1_list);&lt;br /&gt;
	elseif &#039;3char&#039; == frame.args.list then										-- iso 639-2, 3&lt;br /&gt;
		list_format (result, code_2_list);&lt;br /&gt;
	elseif &#039;ietf&#039; == frame.args.list then										-- all ietf tags&lt;br /&gt;
		list_format (result, ietf_list);&lt;br /&gt;
	elseif &#039;ietf2&#039; == frame.args.list then										-- 2-character ietf tags&lt;br /&gt;
		list_format (result, ietf_list2);&lt;br /&gt;
	elseif &#039;ietf3&#039; == frame.args.list then										-- 3 character ietf tags&lt;br /&gt;
		list_format (result, ietf_list3);&lt;br /&gt;
	else																		--must be &#039;name&#039;&lt;br /&gt;
		list_format (result, name_list);&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local templatestyles = frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = &amp;quot;Div col/styles.css&amp;quot; }&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	table.sort (result);&lt;br /&gt;
	table.insert (result, 1, templatestyles .. &#039;&amp;lt;div class=&amp;quot;div-col&amp;quot; style=&amp;quot;column-width:16em&amp;quot;&amp;gt;&#039;);&lt;br /&gt;
	table.insert (out, table.concat (result, &#039;\n*&#039;));&lt;br /&gt;
	table.insert (out, &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
	&lt;br /&gt;
	return table.concat (out, &#039;\n&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S C R I P T _ L A N G _ L I S T E R &amp;gt;------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Module entry point&lt;br /&gt;
&lt;br /&gt;
Crude documentation tool that returns list of language codes and names supported by the various |script-&amp;lt;param&amp;gt;= parameters.&lt;br /&gt;
&lt;br /&gt;
used in Help:CS1 errors&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|script_lang_lister}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function script_lang_lister (frame)&lt;br /&gt;
	local lang_code_src = cfg.script_lang_codes ;								-- get list of allowed script language codes&lt;br /&gt;
	local override = cfg.lang_tag_remap;&lt;br /&gt;
	local this_wiki_lang = mw.language.getContentLanguage().code;				-- get this wiki&#039;s language&lt;br /&gt;
&lt;br /&gt;
	local code_list = {};														-- interim list of aliases&lt;br /&gt;
	local name_list={};															-- not used; defined here so that we can reuse add_to_list() &lt;br /&gt;
	local out = {};																-- final output (for now an unordered list)&lt;br /&gt;
	&lt;br /&gt;
	for _, code in ipairs (lang_code_src) do									-- loop through the list of codes&lt;br /&gt;
		local name = mw.language.fetchLanguageName (code, this_wiki_lang);		-- get the language name associated with this code&lt;br /&gt;
		add_to_list (code_list, name_list, override, code, name, false);		-- name_list{} not used but provided so that we can reuse add_to_list(); don&#039;t add superscript dagger&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local result = {};&lt;br /&gt;
	local out = {};&lt;br /&gt;
&lt;br /&gt;
	list_format (result, code_list);&lt;br /&gt;
	&lt;br /&gt;
	local templatestyles = frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = &amp;quot;Div col/styles.css&amp;quot; }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	table.sort (result);&lt;br /&gt;
	table.insert (result, 1, templatestyles .. &#039;&amp;lt;div class=&amp;quot;div-col&amp;quot; style=&amp;quot;column-width:16em&amp;quot;&amp;gt;&#039;);&lt;br /&gt;
	table.insert (out, table.concat (result, &#039;\n*&#039;));&lt;br /&gt;
	table.insert (out, &#039;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
	&lt;br /&gt;
	return table.concat (out, &#039;\n&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; A L I A S _ L I S T E R &amp;gt;------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
experimental code that lists parameters and their aliases.  Perhaps basis for some sort of documentation?&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|alias_lister}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function alias_lister ()&lt;br /&gt;
	local alias_src = cfg.aliases;												-- get master list of aliases&lt;br /&gt;
	local key;																	-- key for k/v in a new table&lt;br /&gt;
	local list = {};															-- interim list of aliases&lt;br /&gt;
	local out = {};																-- final output (for now an unordered list)&lt;br /&gt;
	&lt;br /&gt;
	for _, aliases in pairs (alias_src) do										-- loop throu the master list of aliases&lt;br /&gt;
		if &#039;table&#039; == type (aliases) then										-- table only when there are aliases&lt;br /&gt;
			for i, alias in ipairs (aliases) do									-- loop through all of the aliases&lt;br /&gt;
				if 1 == i then													-- first &#039;alias&#039; is the canonical parameter name&lt;br /&gt;
					key = alias;												-- so it becomes the key in list&lt;br /&gt;
				else&lt;br /&gt;
					list[key] = list[key] and (list[key] .. &#039;, &#039; .. alias) or alias;	-- make comma-separated list of aliases&lt;br /&gt;
					list[alias] = &#039;see &#039; .. key;								-- make a back reference from this alias to the canonical parameter&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for k, v in pairs (list) do													-- loop through the list to make a simple unordered list&lt;br /&gt;
		table.insert (out, table.concat ({&#039;*&#039;, k, &#039;: &#039;, v}));&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	table.sort (out);															-- sort it&lt;br /&gt;
	return table.concat (out, &#039;\010&#039;);											-- concatenate with \n&lt;br /&gt;
--	return (mw.dumpObject (list))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C A N O N I C A L _ P A R A M _ L I S T E R &amp;gt;----------------------------------&lt;br /&gt;
&lt;br /&gt;
experimental code that lists canonical parameter names.  Perhaps basis for some sort of documentation?&lt;br /&gt;
&lt;br /&gt;
returns a comma separated, alpha sorted, list of the canonical parameters.  If given a template name, excludes&lt;br /&gt;
parameters listed in that template&#039;s exclusion_list[&amp;lt;template&amp;gt;]{} table (if a table has been defined).&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|canonical_param_lister|&amp;lt;template&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function canonical_param_lister (frame)&lt;br /&gt;
	local template = frame.args[1];&lt;br /&gt;
	if &#039;&#039; == template then&lt;br /&gt;
		template = nil;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if template then&lt;br /&gt;
		template = mw.text.trim (template:lower());&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local alias_src = cfg.aliases;												-- get master list of aliases&lt;br /&gt;
	local id_src = cfg.id_handlers;												-- get master list of identifiers&lt;br /&gt;
	&lt;br /&gt;
	local list = {};															-- interim list of aliases&lt;br /&gt;
	local out = {};																-- final output (for now an unordered list)&lt;br /&gt;
	&lt;br /&gt;
	for _, aliases in pairs (alias_src) do										-- loop through the master list of aliases&lt;br /&gt;
		local name;&lt;br /&gt;
		if &#039;table&#039; == type (aliases) then										-- table only when there are aliases&lt;br /&gt;
			name = aliases[1];													-- first member of an aliases table is declared canonical&lt;br /&gt;
		else&lt;br /&gt;
			name = aliases;														-- for those parameters that do not have any aliases, the parameter is declared canonical&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if not template then													-- no template name, add this parameter&lt;br /&gt;
			table.insert (list, name);&lt;br /&gt;
		elseif not exclusion_lists[template] then								-- template name but no exclusion list&lt;br /&gt;
			table.insert (list, name);&lt;br /&gt;
		elseif not exclusion_lists[template][name] then							-- template name and exclusion list but name not in list&lt;br /&gt;
			table.insert (list, name);&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for k, ids in pairs (id_src) do												-- spin through the list of identifiers&lt;br /&gt;
		local name = id_src[k].parameters[1];									-- get the first (left-most) parameter name&lt;br /&gt;
		local access = id_src[k].custom_access;									-- get the access-icon parameter if it exists for this identifier&lt;br /&gt;
		if not template then													-- no template name&lt;br /&gt;
			table.insert (list, name);											-- add this parameter&lt;br /&gt;
			if access then&lt;br /&gt;
				table.insert (list, access);									-- add this access-icon parameter&lt;br /&gt;
			end&lt;br /&gt;
		elseif not exclusion_lists[template] then								-- template name but no exclusion list&lt;br /&gt;
			table.insert (list, name);&lt;br /&gt;
			if access then&lt;br /&gt;
				table.insert (list, access);&lt;br /&gt;
			end&lt;br /&gt;
		elseif not exclusion_lists[template][name] then							-- template name and exclusion list but name not in list&lt;br /&gt;
			table.insert (list, name);&lt;br /&gt;
			if access then&lt;br /&gt;
				table.insert (list, access);&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for _, param in ipairs (list) do											-- loop through the list to make a simple unordered list&lt;br /&gt;
		table.insert (out, table.concat ({&#039;*&#039;, param}));&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local function comp( a, b )													-- used in following table.sort()&lt;br /&gt;
		return a:lower() &amp;lt; b:lower();&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	table.sort (out, comp);														-- sort the list&lt;br /&gt;
	return table.concat (out, &#039;\010&#039;);											-- concatenate with \n&lt;br /&gt;
--	return (mw.dumpObject (list))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C A N O N I C A L _ N A M E _ G E T &amp;gt;------------------------------------------&lt;br /&gt;
&lt;br /&gt;
returns first (canonical) name when metaparameter is assigned a table of names&lt;br /&gt;
returns name when metaparameter is assigned a single name&lt;br /&gt;
returns empty string when metaparameter name not found in alias_src{}, id_src{}, or id_src[meta].custom_access&lt;br /&gt;
&lt;br /&gt;
metaparameter &amp;lt;metaparam&amp;gt; is the key in Module:Citation/CS1 aliases{} table or id_handlers{} table.  Because access-icon&lt;br /&gt;
don&#039;t have &amp;lt;metaparam&amp;gt; keys, per se, we create pseudo &amp;lt;metaparam&amp;gt; keys by appending &#039;access&#039; to the identifier &amp;lt;metaparam&amp;gt;:&lt;br /&gt;
	the &amp;lt;metaparam&amp;gt; for |doi-access= is, for the purposes of this function, DOIaccess, etc&lt;br /&gt;
&lt;br /&gt;
Some lists of aliases might be better served when a particular alias is identified as the canonical alias for a &lt;br /&gt;
particular use case.  If, for example, &amp;lt;metaparam&amp;gt; Perodical lists:&lt;br /&gt;
	&#039;journal&#039;, &#039;magazine&#039;, &#039;newspaper&#039;, &#039;periodical&#039;, &#039;website&#039;, &#039;work&#039;&lt;br /&gt;
that order works fine for {{cite journal}} documentation but doesn&#039;t work so well for {{cite magazine}}, {{cite news}},&lt;br /&gt;
or {{cite web}}.  So, for using this function to document {{cite magazine}} the returned value should be the&lt;br /&gt;
parameter best suited for that template so we can specify magazine in the override (frame.args[2])&lt;br /&gt;
&lt;br /&gt;
While for this function, it would be just as simple to not use the function, this mechanism is implemented here &lt;br /&gt;
to match similar functionality in alias_names_get() (there are slight differences)&lt;br /&gt;
	&amp;lt;override&amp;gt; must exist in the alias list&lt;br /&gt;
	does not apply to the access icon parameters (ignored - these have no aliases)&lt;br /&gt;
&lt;br /&gt;
(and which would be best for {{cite news}}? |newspaper= or |work=? can&#039;t solve all of the worlds problems at once).&lt;br /&gt;
&lt;br /&gt;
output format is controlled by |format=&lt;br /&gt;
	plain - renders in plain text in a &amp;lt;span&amp;gt; tag; may have id attribute&lt;br /&gt;
	para - renders as it would in {{para|&amp;lt;param&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|canonical_name_get|&amp;lt;metaparam&amp;gt;|&amp;lt;override&amp;gt;|id=&amp;lt;attribute&amp;gt;|format=[plain|para]}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function canonical_name_get (frame)&lt;br /&gt;
	local alias_src = cfg.aliases;												-- get master list of aliases&lt;br /&gt;
	local id_src = cfg.id_handlers;												-- get master list of identifiers&lt;br /&gt;
	local args = getArgs (frame);&lt;br /&gt;
&lt;br /&gt;
	local name;&lt;br /&gt;
	local meta = args[1]&lt;br /&gt;
	local override = args[2];&lt;br /&gt;
&lt;br /&gt;
	local access;																-- for id-access parameters&lt;br /&gt;
	if meta:match (&#039;^(%u+)access&#039;) then											-- the metaparameter (which is not used in ~/Configuration) is id_handlers key concatenated with access: BIBCODEaccess&lt;br /&gt;
		meta, access = meta:gsub (&#039;^(%u+)access&#039;, &#039;%1&#039;);						-- strip &#039;access&#039; text from meta and use returned count value as a flag&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if alias_src[meta] then&lt;br /&gt;
		name = alias_src[meta];													-- name is a string or a table&lt;br /&gt;
		if &#039;table&#039; == type (name) then											-- table only when there are aliases&lt;br /&gt;
			if not override then&lt;br /&gt;
				name = name[1];													-- first member of an aliases table is declared canonical&lt;br /&gt;
			else&lt;br /&gt;
				for _, v in ipairs (name) do									-- here when override is set; spin throu the aliases to make sure override matches alias in table&lt;br /&gt;
					if v == override then&lt;br /&gt;
						name = v;												-- declare override to be the canonical param for this use case&lt;br /&gt;
						break;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
	elseif id_src[meta]then														-- if there is an id handler&lt;br /&gt;
		if access then															-- and if this is a request for the handler&#039;s custom access parameter&lt;br /&gt;
			if id_src[meta].custom_access then									-- if there is a custom access parameter&lt;br /&gt;
				name = id_src[meta].custom_access;								-- use it&lt;br /&gt;
			else&lt;br /&gt;
				return &#039;&#039;;														-- nope, return empty string&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			if not override then&lt;br /&gt;
				name = id_src[meta].parameters[1];								-- get canonical id handler parameter&lt;br /&gt;
			else&lt;br /&gt;
				for _, v in ipairs (id_src[meta].parameters) do					-- here when override is set; spin throu the aliases to make sure override matches alias in table&lt;br /&gt;
					if v == override then&lt;br /&gt;
						name = v;												-- declare override to be the canonical param for this use case&lt;br /&gt;
						break;&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;&#039;;																-- metaparameter not specified, or no such metaparameter&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if &#039;plain&#039; == args.format then												-- format and return the output&lt;br /&gt;
		if args.id then&lt;br /&gt;
			return string.format (&#039;&amp;lt;span id=&amp;quot;%s&amp;quot;&amp;gt;%s&amp;lt;/span&amp;gt;&#039;, args.id, name);	-- plain text with id attribute&lt;br /&gt;
		else&lt;br /&gt;
			return name;														-- plain text&lt;br /&gt;
		end&lt;br /&gt;
	elseif &#039;para&#039; == args.format then&lt;br /&gt;
		return string.format (&#039;&amp;lt;code class=&amp;quot;nowrap&amp;quot;&amp;gt;|%s=&amp;lt;/code&amp;gt;&#039;, name);		-- same as {{para|&amp;lt;param&amp;gt;}}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return string.format (&#039;&amp;lt;b id=&amp;quot;%s&amp;quot;&amp;gt;%s&amp;lt;/b&amp;gt;&#039;, args.id or &#039;&#039;, name);			-- because {{csdoc}} bolds param names&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; A L I A S _ N A M E S _ G E T &amp;gt;------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
returns list of aliases for metaparameter &amp;lt;metaparam&amp;gt;&lt;br /&gt;
returns empty string when there are no aliases&lt;br /&gt;
returns empty string when &amp;lt;metaparam&amp;gt; name not found in alias_src{} or id_src{}; access icon parameters have no aliases so ignored&lt;br /&gt;
&lt;br /&gt;
metaparameter &amp;lt;metaparam&amp;gt; is the key in Module:Citation/CS1 aliases{} table or id_handlers{} table.&lt;br /&gt;
&lt;br /&gt;
Some lists of aliases might be better served when a particular alias is identified as the canonical alias for a &lt;br /&gt;
particular use case.  If, for example, &amp;lt;metaparam&amp;gt; Perodical lists:&lt;br /&gt;
	&#039;journal&#039;, &#039;magazine&#039;, &#039;newspaper&#039;, &#039;periodical&#039;, &#039;website&#039;, &#039;work&#039;&lt;br /&gt;
that order works fine for {{cite journal}} documentation but doesn&#039;t work so well for {{cite magazine}}, {{cite news}},&lt;br /&gt;
or {{cite web}}.  So, for using this function to document {{cite magazine}} the returned value should be the&lt;br /&gt;
aliases that are not best suited for that template so we can specify magazine in the override (frame.args[2])&lt;br /&gt;
to be the canonical parameter so it won&#039;t be listed with the rest of the aliases (normal canonical journal will be)&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;override&amp;gt; must exist in the alias list except:&lt;br /&gt;
		when &amp;lt;override&amp;gt; value is &#039;all&#039;, returns the canonical parameter plus all of the aliases&lt;br /&gt;
&lt;br /&gt;
output format is controlled by |format=&lt;br /&gt;
	plain - renders in plain text in a &amp;lt;span&amp;gt; tag; may have id attribute&lt;br /&gt;
	para - renders as it would in {{para|&amp;lt;param&amp;gt;}}&lt;br /&gt;
	when not specified, refurns the default bold format used for {{csdoc}}&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|alias_name_get|&amp;lt;metaparam&amp;gt;|&amp;lt;override&amp;gt;|format=[plain|para]}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function alias_names_get (frame)&lt;br /&gt;
	local alias_src = cfg.aliases;												-- get master list of aliases&lt;br /&gt;
	local id_src = cfg.id_handlers;												-- get master list of identifiers&lt;br /&gt;
	local args = getArgs (frame);&lt;br /&gt;
	&lt;br /&gt;
	local meta = args[1];&lt;br /&gt;
	local override = args[2];&lt;br /&gt;
&lt;br /&gt;
	local out = {};&lt;br /&gt;
	local source;																-- selected parameter or id aliases list&lt;br /&gt;
	local aliases;&lt;br /&gt;
&lt;br /&gt;
	source = alias_src[meta] or (id_src[meta] and id_src[meta].parameters);&lt;br /&gt;
	if not source then&lt;br /&gt;
		if meta:match (&#039;%u+access&#039;) then&lt;br /&gt;
			return &#039;no&#039; == args.none and &#039;&#039; or &#039;none&#039;;							-- custom access parameters don&#039;t have aliases&lt;br /&gt;
		else&lt;br /&gt;
			return &#039;&#039;;															-- no such meta&lt;br /&gt;
		end&lt;br /&gt;
	elseif not source[2] then													-- id_source[meta] is always a table; if no second member, no aliases&lt;br /&gt;
		return &#039;no&#039; == args.none and &#039;&#039; or &#039;none&#039;;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if not override then&lt;br /&gt;
		aliases = source;														-- normal skip-canonical param case&lt;br /&gt;
	else&lt;br /&gt;
		local flag = &#039;all&#039; == override and true or nil;							-- so that we know that &amp;lt;override&amp;gt; parameter is a valid alias; spoof when override == &#039;all&#039;&lt;br /&gt;
		aliases = {[1] = &#039;&#039;};													-- spoof to push alias_src[meta][1] and id_src[meta][1] into aliases[2]&lt;br /&gt;
		for _, v in ipairs (source) do											-- here when override is set; spin through the aliases to make sure override matches alias in table&lt;br /&gt;
			if v ~= override then&lt;br /&gt;
				table.insert (aliases, v);										-- add all but overridden param to the the aliases list for this use case&lt;br /&gt;
			else&lt;br /&gt;
				flag = true;													-- set the flag so we know that &amp;lt;override&amp;gt; is a valid alias&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if not flag then&lt;br /&gt;
			aliases = {}														-- unset the table as error indicator&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if &#039;table&#039; == type (aliases) then											-- table only when there are aliases&lt;br /&gt;
		for i, alias in ipairs (aliases) do&lt;br /&gt;
			if 1 ~= i then														-- aliases[1] is the canonical name; don&#039;t include it&lt;br /&gt;
				if &#039;plain&#039; == args.format then									-- format and return the output&lt;br /&gt;
					table.insert (out, alias);									-- plain text&lt;br /&gt;
				elseif &#039;para&#039; == args.format then&lt;br /&gt;
					table.insert (out, string.format (&#039;&amp;lt;code class=&amp;quot;nowrap&amp;quot;&amp;gt;|%s=&amp;lt;/code&amp;gt;&#039;, alias));	-- same as {{para|&amp;lt;param&amp;gt;}}&lt;br /&gt;
				else&lt;br /&gt;
					table.insert (out, string.format (&amp;quot;&#039;&#039;&#039;%s&#039;&#039;&#039;&amp;quot;, alias));		-- because csdoc bolds param names&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		return table.concat (out, &#039;, &#039;);										-- make pretty list and quit&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return &#039;no&#039; == args.none and &#039;&#039; or &#039;none&#039;;									-- no metaparameter with that name or no aliases&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ B O O K _ C I T E _ T E M P L A T E &amp;gt;------------------------------------&lt;br /&gt;
&lt;br /&gt;
fetch the title of the current page; if it is a preprint template, return true; empty string else&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local book_cite_templates = {&lt;br /&gt;
	[&#039;citation&#039;] = true,&lt;br /&gt;
	[&#039;cite book&#039;] = true,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
local function is_book_cite_template ()&lt;br /&gt;
	local title = mw.title.getCurrentTitle().rootText;							-- get title of current page without namespace and without sub-pages; from Template:Cite book/new -&amp;gt; Cite book&lt;br /&gt;
	&lt;br /&gt;
	title = title and title:lower() or &#039;&#039;;&lt;br /&gt;
	return book_cite_templates[title] or &#039;&#039;;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I S _ L I M I T E D _ P A R A M _ T E M P L A T E &amp;gt;----------------------------&lt;br /&gt;
&lt;br /&gt;
fetch the title of the current page; if it is a preprint template, return true; empty string else&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local limited_param_templates = {												-- if ever there is a need to fetch info from ~/Whitelist then&lt;br /&gt;
	[&#039;cite arxiv&#039;] = true,														-- this list could also be fetched from there&lt;br /&gt;
	[&#039;cite biorxiv&#039;] = true,&lt;br /&gt;
	[&#039;citeseerx&#039;] = true,&lt;br /&gt;
	[&#039;ssrn&#039;] = true,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
local function is_limited_param_template ()&lt;br /&gt;
	local title = mw.title.getCurrentTitle().rootText;							-- get title of current page without namespace and without sub-pages; from Template:Cite book/new -&amp;gt; Cite book&lt;br /&gt;
	&lt;br /&gt;
	title = title and title:lower() or &#039;&#039;;&lt;br /&gt;
	return limited_param_templates[title] or &#039;&#039;;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; H E A D E R _ M A K E &amp;gt;--------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
makes a section header from &amp;lt;header_text&amp;gt; and &amp;lt;level&amp;gt;; &amp;lt;level&amp;gt; defaults to 2; cannot be less than 2&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function _header_make (args)&lt;br /&gt;
	if not args[1] then&lt;br /&gt;
		return &#039;&#039;;																-- no header text&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local level = args[2] and tonumber (args[2]) or 2;&lt;br /&gt;
	&lt;br /&gt;
	level = string.rep (&#039;=&#039;, level);&lt;br /&gt;
	return level .. args[1] .. level;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; H E A D E R _ M A K E &amp;gt;--------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
Entry from an {{#invoke:}}&lt;br /&gt;
makes a section header from &amp;lt;header_text&amp;gt; and &amp;lt;level&amp;gt;; &amp;lt;level&amp;gt; defaults to 2; cannot be less than 2&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function header_make (frame)&lt;br /&gt;
	local args = getArgs (frame);&lt;br /&gt;
	return _header_make (args);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I D _ L I M I T S _ G E T &amp;gt;----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
return the limit values for named identifier parameters that have &amp;lt;id&amp;gt; limits (pmc, pmid, ssrn, s2cid, oclc, osti, rfc); the return&lt;br /&gt;
value used in template documentation and error message help-text&lt;br /&gt;
&lt;br /&gt;
{{#invoke:Cs1 documentation support|id_limits_get|&amp;lt;id&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function id_limits_get (frame)&lt;br /&gt;
	local args = getArgs (frame);&lt;br /&gt;
	local handlers = cfg.id_handlers;											-- get id_handlers {} table from ~/Configuration&lt;br /&gt;
&lt;br /&gt;
	return args[1] and handlers[args[1]:upper()].id_limit or (&#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;No limit defined for identifier: &#039; .. (args[1] or &#039;&amp;lt;unknown name&amp;gt;&#039;) .. &#039;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C A T _ L I N K _ M A K E &amp;gt;----------------------------------------------------&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function cat_link_make (cat)&lt;br /&gt;
	return table.concat ({&#039;[[:Category:&#039;, cat, &#039;]]&#039;});&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S C R I P T _ C A T _ L I S T E R &amp;gt;--------------------------------------------&lt;br /&gt;
&lt;br /&gt;
utility function to get script-language categories&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local lang_list_t = mw.language.fetchLanguageNames (&#039;en&#039;, &#039;all&#039;);&lt;br /&gt;
 &lt;br /&gt;
local function script_cat_lister (script_lang_codes_t, lang_tag_remap_t, cats_list_t)&lt;br /&gt;
	for _, lang_code in ipairs (script_lang_codes_t) do&lt;br /&gt;
		local lang_name = lang_tag_remap_t[lang_code] or lang_list_t[lang_code];	-- use remap table to get Bengali instead of Bangla and the like; else use standard MediaWiki names&lt;br /&gt;
		local cat = &#039;CS1 uses &#039; .. lang_name .. &#039;-language script (&#039; .. lang_code .. &#039;)&#039;;	-- build a category name&lt;br /&gt;
		cats_list_t[cat] = 1;													-- and save it&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C S 1 _ C A T _ L I S T E R &amp;gt;--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
This is a crude tool that reads the category names from Module:Citation/CS1/Configuration, makes links of them,&lt;br /&gt;
and then lists them in sorted lists.  A couple of parameters control the rendering of the output:&lt;br /&gt;
	|select=	-- (required) takes one of three values: error, maint, prop&lt;br /&gt;
	|sandbox=	-- takes one value: no&lt;br /&gt;
	|hdr-lvl=	-- base header level (number of == that make a header); default:2 min:2&lt;br /&gt;
&lt;br /&gt;
This tool will automatically attempt to load a sandbox version of ~/Configuration if one exists.&lt;br /&gt;
Setting |sandbox=no will defeat this.&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|cat_lister|select=&amp;lt;error|maint|prop&amp;gt;|sandbox=&amp;lt;no&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function cat_lister (frame)&lt;br /&gt;
	local args = getArgs (frame);&lt;br /&gt;
&lt;br /&gt;
	local list_live_cats = {};													-- list of live categories&lt;br /&gt;
	local list_sbox_cats = {};													-- list of sandbox categories&lt;br /&gt;
	&lt;br /&gt;
	local live_sbox_out = {}													-- list of categories that are common to live and sandbox modules&lt;br /&gt;
	local live_not_in_sbox_out = {}												-- list of categories in live but not sandbox&lt;br /&gt;
	local sbox_not_in_live_out = {}												-- list of categories in sandbox but not live&lt;br /&gt;
	&lt;br /&gt;
	local out = {};																-- final output assembled here&lt;br /&gt;
	&lt;br /&gt;
	local sandbox;																-- boolean; true: evaluate the sandbox module&lt;br /&gt;
	local hdr_lvl;																-- &lt;br /&gt;
	&lt;br /&gt;
	local sb_cfg;&lt;br /&gt;
	local sandbox, sb_cfg = pcall (mw.loadData, &#039;Module:Citation/CS1/Configuration/sandbox&#039;);	-- get sandbox configuration&lt;br /&gt;
&lt;br /&gt;
	local cat;&lt;br /&gt;
&lt;br /&gt;
	local select = args.select;&lt;br /&gt;
	if &#039;no&#039; == args.sandbox then												-- list sandbox?&lt;br /&gt;
		sandbox = false;														-- no, live only&lt;br /&gt;
	end&lt;br /&gt;
	if hdr_lvl then																-- if set and&lt;br /&gt;
		if tonumber (hdr_lvl) then												-- can be converted to number&lt;br /&gt;
			if 2 &amp;gt; tonumber (hdr_lvl) then										-- min is 2&lt;br /&gt;
				hdr_lvl = 2;													-- so set to min&lt;br /&gt;
			end&lt;br /&gt;
		else																	-- can&#039;t be converted&lt;br /&gt;
			hdr_lvl = 2;														-- so default to min&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		hdr_lvl = 2;															-- not set so default to min&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if &#039;error&#039; == select or &#039;maint&#039; == select then								-- error and main categorys handling different from poperties cats&lt;br /&gt;
		for _, t in pairs (cfg.error_conditions) do								-- get the live module&#039;s categories&lt;br /&gt;
			if (&#039;error&#039; == select and t.message) or (&#039;maint&#039; == select and not t.message) then&lt;br /&gt;
				cat = t.category:gsub (&#039;|(.*)$&#039;, &#039;&#039;);							-- strip sort key if any&lt;br /&gt;
				list_live_cats[cat] = 1;										-- add to the list&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		if sandbox then															-- if ~/sandbox module exists and |sandbox= not set to &#039;no&#039;&lt;br /&gt;
			for _, t in pairs (sb_cfg.error_conditions) do						-- get the sandbox module&#039;s categories&lt;br /&gt;
				if (&#039;error&#039; == select and t.message) or (&#039;maint&#039; == select and not t.message) then&lt;br /&gt;
					cat = t.category:gsub (&#039;|(.*)$&#039;, &#039;&#039;);						-- strip sort key if any&lt;br /&gt;
					list_sbox_cats[cat] = 1;									-- add to the list&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
	elseif &#039;prop&#039; == select then												-- prop cats&lt;br /&gt;
		for _, cat in pairs (cfg.prop_cats) do									-- get the live module&#039;s categories&lt;br /&gt;
			cat = cat:gsub (&#039;|(.*)$&#039;, &#039;&#039;);										-- strip sort key if any&lt;br /&gt;
			list_live_cats[cat] = 1;											-- add to the list&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		script_cat_lister (cfg.script_lang_codes, cfg.lang_tag_remap, list_live_cats);	-- get live module&#039;s foriegn language script cats&lt;br /&gt;
&lt;br /&gt;
		if sandbox then															-- if ~/sandbox module exists and |sandbox= not set to &#039;no&#039;&lt;br /&gt;
			for _, cat in pairs (sb_cfg.prop_cats) do							-- get the sandbox module&#039;s categories&lt;br /&gt;
				cat = cat:gsub (&#039;|(.*)$&#039;, &#039;&#039;);									-- strip sort key if any&lt;br /&gt;
				list_sbox_cats[cat] = 1;										-- add to the list&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			script_cat_lister (sb_cfg.script_lang_codes, sb_cfg.lang_tag_remap, list_sbox_cats);	-- get sandbox module&#039;s foriegn language script cats&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;color:#d33; font-style:normal;&amp;quot;&amp;gt;error: unknown selector: &#039; .. select .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
	end	&lt;br /&gt;
&lt;br /&gt;
	for k, _ in pairs (list_live_cats) do										-- separate live/sbox common cats from cats not in sbox&lt;br /&gt;
		if not list_sbox_cats[k] and sandbox then&lt;br /&gt;
			table.insert (live_not_in_sbox_out, cat_link_make (k));				-- in live but not in sbox&lt;br /&gt;
		else&lt;br /&gt;
			table.insert (live_sbox_out, cat_link_make (k));					-- in both live and sbox&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for k, _ in pairs (list_sbox_cats) do										-- separate sbox/live common cats from cats not in live&lt;br /&gt;
		if not list_live_cats[k] then&lt;br /&gt;
			table.insert (sbox_not_in_live_out, cat_link_make (k));				-- in sbox but not in live&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function comp (a, b)													-- local function for case-agnostic category name sorting&lt;br /&gt;
		return a:lower() &amp;lt; b:lower();&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local header;																-- initialize section header with name of selected category list&lt;br /&gt;
	if &#039;error&#039; == select then&lt;br /&gt;
		header = &#039;error&#039;;&lt;br /&gt;
	elseif &#039;maint&#039; == select then&lt;br /&gt;
		header = &#039;maintenance&#039;;&lt;br /&gt;
	else&lt;br /&gt;
		header = &#039;properties&#039;;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	header = table.concat ({													-- build the main header&lt;br /&gt;
		&#039;Live &#039;,																-- always include this&lt;br /&gt;
		((sandbox and &#039;and sandbox &#039;) or &#039;&#039;),									-- if sandbox evaluated, mention that&lt;br /&gt;
		header,																	-- add the list name&lt;br /&gt;
		&#039; categories (&#039;,														-- finish the name and add&lt;br /&gt;
		#live_sbox_out,															-- count of categories listed&lt;br /&gt;
		&#039;)&#039;																		-- close&lt;br /&gt;
	})&lt;br /&gt;
&lt;br /&gt;
	local templatestyles = frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;, args = { src = &amp;quot;Div col/styles.css&amp;quot; }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	header = table.concat ({													-- make a useable header&lt;br /&gt;
		_header_make ({header, hdr_lvl}),&lt;br /&gt;
		&#039;\n&#039; .. templatestyles .. &#039;&amp;lt;div class=&amp;quot;div-col&amp;quot;&amp;gt;&#039;	-- opening &amp;lt;div&amp;gt; for columns&lt;br /&gt;
		});&lt;br /&gt;
&lt;br /&gt;
	table.sort (live_sbox_out, comp);											-- sort case agnostic acsending&lt;br /&gt;
	table.insert (live_sbox_out, 1, header);									-- insert the header at the top&lt;br /&gt;
	table.insert (out, table.concat (live_sbox_out, &#039;\n*&#039;));					-- make a big string of unordered list markup&lt;br /&gt;
	table.insert (out, &#039;&amp;lt;/div&amp;gt;\n&#039;);												-- close the &amp;lt;/div&amp;gt; and add new line so the next header works&lt;br /&gt;
&lt;br /&gt;
	if 0 ~= #live_not_in_sbox_out then											-- when there is something in the table&lt;br /&gt;
		header = table.concat ({												-- build header for subsection&lt;br /&gt;
			&#039;In live but not in sandbox (&#039;,&lt;br /&gt;
			#live_not_in_sbox_out,&lt;br /&gt;
			&#039;)&#039;&lt;br /&gt;
			});&lt;br /&gt;
	&lt;br /&gt;
		header = table.concat ({												-- make a useable header&lt;br /&gt;
			_header_make ({header, hdr_lvl+1}),&lt;br /&gt;
			&#039;\n&#039; .. templatestyles .. &#039;&amp;lt;div class=&amp;quot;div-col&amp;quot;&amp;gt;&#039;&lt;br /&gt;
			});&lt;br /&gt;
	&lt;br /&gt;
		table.sort (live_not_in_sbox_out, comp);&lt;br /&gt;
		table.insert (live_not_in_sbox_out, 1, header);&lt;br /&gt;
		table.insert (out, table.concat (live_not_in_sbox_out, &#039;\n*&#039;));&lt;br /&gt;
		table.insert (out, &#039;&amp;lt;/div&amp;gt;\n&#039;);&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if 0 ~= #sbox_not_in_live_out then											-- when there is something in the table&lt;br /&gt;
		header = table.concat ({												-- build header for subsection&lt;br /&gt;
			&#039;In sandbox but not in live (&#039;,&lt;br /&gt;
			#sbox_not_in_live_out,&lt;br /&gt;
			&#039;)&#039;&lt;br /&gt;
			});&lt;br /&gt;
	&lt;br /&gt;
		header = table.concat ({												-- make a useable header&lt;br /&gt;
			_header_make ({header, hdr_lvl+1}),&lt;br /&gt;
			&#039;\n&#039; .. templatestyles .. &#039;&amp;lt;div class=&amp;quot;div-col&amp;quot;&amp;gt;&#039;&lt;br /&gt;
			});&lt;br /&gt;
	&lt;br /&gt;
		table.sort (sbox_not_in_live_out, comp);&lt;br /&gt;
		table.insert (sbox_not_in_live_out, 1, header);&lt;br /&gt;
		table.insert (out, table.concat (sbox_not_in_live_out, &#039;\n*&#039;));&lt;br /&gt;
		table.insert (out, &#039;&amp;lt;/div&amp;gt;\n&#039;);&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return table.concat (out);													-- concat into a huge string and done&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[=[--------------------------&amp;lt; H E L P _ T E X T _ C A T S &amp;gt;--------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
To create category links at the bottom of each error help text section and on the individual error category pages;&lt;br /&gt;
fetches category names from ~/Configuration; replaces this:&lt;br /&gt;
	{{#ifeq:{{FULLPAGENAME}}|Category:CS1 errors: bioRxiv|Category:CS1 errors: bioRxiv|[[:Category:CS1 errors: bioRxiv]]}}&lt;br /&gt;
with this:&lt;br /&gt;
	{{#invoke:Cs1 documentation support|help_text_cats|err_bad_biorxiv}}&lt;br /&gt;
where {{{1}}} is the error_conditions key from Module:Citation/CS1/Configuration&lt;br /&gt;
&lt;br /&gt;
add |pages=yes to append the number of pages in the category&lt;br /&gt;
&lt;br /&gt;
]=]&lt;br /&gt;
&lt;br /&gt;
local function help_text_cats (frame)&lt;br /&gt;
	local args_t = getArgs (frame);&lt;br /&gt;
	local error_conditions_t = cfg.error_conditions;							-- get the table of error conditions&lt;br /&gt;
	local replacements_t = {};													-- table to hold replacement parameters for $1 etc placeholders in category names&lt;br /&gt;
	for k, v in pairs (args_t) do												-- look for |$1=&amp;lt;replacement&amp;gt; parameters&lt;br /&gt;
		if &#039;string&#039; == type (k) and k:match (&#039;^$%d+$&#039;) then						-- if found&lt;br /&gt;
			replacements_t[k] = v;												-- save key and value&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if args_t[1] and error_conditions_t[args_t[1]] then							-- must have error_condition key and it must exist&lt;br /&gt;
		local error_cat = error_conditions_t[args_t[1]].category;				-- get error category from cs1|2 configuration&lt;br /&gt;
		if error_cat:match (&#039;$%d&#039;) then											-- look for placeholders in &amp;lt;error_cat&amp;gt;&lt;br /&gt;
			error_cat = error_cat:gsub (&#039;$%d&#039;, replacements_t)					-- replace place holders with matching value from replacements_t&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local title_obj = mw.title.getCurrentTitle();							-- get a title object for the currently displayed page&lt;br /&gt;
		local name_space = title_obj.nsText;&lt;br /&gt;
		if (&#039;Category&#039; == name_space) and (error_cat == title_obj.text) then	-- if this is the category page for the error message&lt;br /&gt;
			return table.concat ({&#039;Category:&#039;, error_cat});						-- no link; just category name&lt;br /&gt;
		else																	-- here when currently displayed page is other than the error message category&lt;br /&gt;
			local pages = &#039;&#039;;													-- default empty strin for concatenation&lt;br /&gt;
			if &#039;yes&#039; == args_t.pages then										-- if we should display category page count: TODO: do we need to keep this?&lt;br /&gt;
				pages = mw.site.stats.pagesInCategory (error_cat, &#039;all&#039;);		-- get category page count&lt;br /&gt;
				pages = table.concat ({&#039; (&#039;, mw.language.getContentLanguage():formatNum (pages), &#039; page&#039;, (1 == pages) and &#039;)&#039; or &#039;s)&#039;});	-- make renderable text&lt;br /&gt;
			end&lt;br /&gt;
			return table.concat ({&#039;[[:Category:&#039;, error_cat, &#039;]]&#039;, pages});		-- link to category with or without page count&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;unknown error_conditions key: &#039; .. (args_t[1] or &#039;key missing&#039;) .. &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; H E L P _ T E X T _ E R R O R _ M E S S A G E &amp;gt;--------------------------------&lt;br /&gt;
&lt;br /&gt;
to render help text example error messages&lt;br /&gt;
	{{#invoke:Cs1 documentation support|help_text_error_messages|err_bad_biorxiv}}&lt;br /&gt;
&lt;br /&gt;
assign a single underscore to any of the |$n= parameters to insert an empty string in the error message:&lt;br /&gt;
	{{#invoke:Cs1 documentation support|help_text_error_messages|err_bad_issn|$1=_}} -&amp;gt; Check |issn= value&lt;br /&gt;
	{{#invoke:Cs1 documentation support|help_text_error_messages|err_bad_issn|$1=e}} -&amp;gt; Check |eissn= value&lt;br /&gt;
&lt;br /&gt;
error message is rendered at 120% font size; to specify another font size use |size=; must include unit specifier (%, em, etc)&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function help_text_error_messages (frame)&lt;br /&gt;
	local args_t = getArgs (frame);&lt;br /&gt;
	local error_conditions = mw.loadData (&#039;Module:Citation/CS1/Configuration&#039;).error_conditions;&lt;br /&gt;
--	local span_o = &#039;&amp;lt;span class=&amp;quot;cs1-visible-error citation-comment&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
	local span_o = &#039;&amp;lt;span class=&amp;quot;citation-comment&amp;quot; style=&amp;quot;color:#d33; font-size:&#039; .. ((args_t.size and args_t.size) or &#039;120%&#039;) .. &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
	local span_c = &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
	local message;&lt;br /&gt;
	local out = {};																-- output goes here&lt;br /&gt;
	&lt;br /&gt;
	if args_t[1] and error_conditions[args_t[1]] then								-- must have error_condition key and it must exist&lt;br /&gt;
		message = error_conditions[args_t[1]].message;&lt;br /&gt;
		local i=1;&lt;br /&gt;
		local count;&lt;br /&gt;
		local rep;&lt;br /&gt;
		repeat&lt;br /&gt;
			rep = &#039;$&#039;..i&lt;br /&gt;
			args_t[rep] = args_t[rep] and args_t[rep]:gsub (&#039;^%s*_%s*$&#039;, &#039;&#039;) or nil;	-- replace empty string marker with actual empty string&lt;br /&gt;
			message, count = message:gsub (rep, args_t[rep] or rep)&lt;br /&gt;
			i = i + 1;&lt;br /&gt;
			until (0 == count);&lt;br /&gt;
&lt;br /&gt;
		table.insert (out, span_o);&lt;br /&gt;
		table.insert (out, message);&lt;br /&gt;
		table.insert (out, span_c);&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;unknown error_conditions key: &#039; .. (args_t[1] or &#039;key missing&#039;) .. &#039;&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local out_str = table.concat (out);&lt;br /&gt;
	return table.concat ({frame:extensionTag (&#039;templatestyles&#039;, &#039;&#039;, {src=&#039;Module:Citation/CS1/styles.css&#039;}), out_str});&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; T E M P L A T E S _ T &amp;gt;--------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
This table is a k/v table of sequence tables.  The keys in this table are collapsed lowercase form of the cs1|2&lt;br /&gt;
template names ({{ROOTPAGENAME}}):&lt;br /&gt;
	Template:Cite AV media -&amp;gt; citeavmedia&lt;br /&gt;
	&lt;br /&gt;
Each subsequence table holds:&lt;br /&gt;
	[1] documentation page where the TemplateData json is stored ({{cite book}} is the oddball)&lt;br /&gt;
	[2] key to &#039;preprint_arguments_t&#039; and unique_arguments_t&#039; tables in Module:Citation/CS1/Whitelist; these keys&lt;br /&gt;
		dictate which of the basic or limited arguments and numbered arguments tables will be used to validate&lt;br /&gt;
		the content of the TemplateData&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local templates_t = {&lt;br /&gt;
	citearxiv = {&#039;Template:Cite_arXiv/doc&#039;, &#039;arxiv&#039;},							-- preprint arguments &lt;br /&gt;
	citeavmedia = {&#039;Template:Cite AV media/doc&#039;, &#039;audio-visual&#039;},				-- unique arguments&lt;br /&gt;
	citeavmedianotes = {&#039;Template:Cite AV media notes/doc&#039;},					-- no template data&lt;br /&gt;
	citebiorxiv = {&#039;Template:Cite bioRxiv/doc&#039;, &#039;biorxiv&#039;},						-- preprint arguments&lt;br /&gt;
	citebook = {&#039;Template:Cite book/TemplateData&#039;},&lt;br /&gt;
	citeciteseerx = {&#039;Template:Cite CiteSeerX/doc&#039;, &#039;citeseerx&#039;},				-- no template data; preprint uses limited arguments&lt;br /&gt;
	citeconference = {&#039;Template:Cite conference/doc&#039;, &#039;conference&#039;},			-- unique arguments&lt;br /&gt;
	citedocument = {&#039;Template:Cite document/doc&#039;, &#039;document&#039;},					-- special case; uses whitelist.document_parameters_t&lt;br /&gt;
	citeencyclopedia = {&#039;Template:Cite encyclopedia/doc&#039;},&lt;br /&gt;
	citeepisode = {&#039;Template:Cite episode/doc&#039;, &#039;episode&#039;},						-- unique arguments&lt;br /&gt;
	citeinterview = {&#039;Template:Cite interview/doc&#039;},&lt;br /&gt;
	citejournal = {&#039;Template:Cite journal/doc&#039;},&lt;br /&gt;
	citemagazine = {&#039;Template:Cite magazine/doc&#039;},&lt;br /&gt;
	citemailinglist = {&#039;Template:Cite mailing list/doc&#039;, &#039;mailinglist&#039;},		-- unique arguments			-- no template data&lt;br /&gt;
	citemap = {&#039;Template:Cite map/TemplateData&#039;, &#039;map&#039;},						-- unique arguments&lt;br /&gt;
	citemedrxiv = {&#039;Template:Cite medRxiv/doc&#039;, &#039;medrxiv&#039;},						-- preprint arguments&lt;br /&gt;
	citenews = {&#039;Template:Cite news/doc&#039;},&lt;br /&gt;
	citenewsgroup = {&#039;Template:Cite newsgroup/doc&#039;, &#039;newsgroup&#039;},				-- unique arguments&lt;br /&gt;
	citepodcast = {&#039;Template:Cite podcast/doc&#039;},&lt;br /&gt;
	citepressrelease = {&#039;Template:Cite press release/doc&#039;},&lt;br /&gt;
	citereport = {&#039;Template:Cite report/doc&#039;, &#039;report&#039;},						-- unique arguments&lt;br /&gt;
	citeserial = {&#039;Template:Cite serial/doc&#039;, &#039;serial&#039;},						-- unique arguments			-- no template data&lt;br /&gt;
	citesign = {&#039;Template:Cite sign/doc&#039;},&lt;br /&gt;
	citespeech = {&#039;Template:Cite speech/doc&#039;, &#039;speech&#039;},						-- unique arguments			-- no template data&lt;br /&gt;
	citessrn = {&#039;Template:Cite SSRN/doc&#039;, &#039;ssrn&#039;},								-- preprint arguments		-- no template data&lt;br /&gt;
	citetechreport = {&#039;Template:Cite techreport/doc&#039;},&lt;br /&gt;
	citethesis = {&#039;Template:Cite thesis/doc&#039;, &#039;thesis&#039;},						-- unique arguments&lt;br /&gt;
	citeweb = {&#039;Template:Cite web/doc&#039;},&lt;br /&gt;
	citation = {&#039;Template:Citation/doc&#039;},&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; N O _ P A G E _ T E M P L A T E S _ T &amp;gt;----------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local no_page_templates_t = {};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; I D E N T I F I E R _ A L I A S E S _ T &amp;gt;--------------------------------------&lt;br /&gt;
&lt;br /&gt;
a table of the identifier aliases&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local identifier_aliases_t = {}&lt;br /&gt;
for identifier, handler in pairs (cfg.id_handlers) do							-- for each identifier&lt;br /&gt;
	local aliases_t = {};														-- create a table&lt;br /&gt;
	for _, alias in ipairs (handler.parameters) do								-- get the alaises&lt;br /&gt;
		aliases_t[alias] = true;												-- and add them to the table in a form that mimics the whitelist tables&lt;br /&gt;
	end&lt;br /&gt;
	identifier_aliases_t[identifier:lower()] = aliases_t;						-- add new table to the identifier aliases table; use lowercase identifier base name for the key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; T E M P L A T E _ D A T A _ J S O N _ G E T &amp;gt;----------------------------------&lt;br /&gt;
&lt;br /&gt;
get template doc page content and extract the content of the TemplateData tags (case insensitive)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;template&amp;gt; is the canonical name of the template doc page (with namespace) that holds the template data; usually&lt;br /&gt;
Template:Cite xxx/doc (except Template:Cite book/TemplateData)&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function template_data_json_get (template)&lt;br /&gt;
	local json = mw.title.new (template):getContent() or &#039;&#039;;					-- get the content of the article or &#039;&#039;; new pages edited w/ve do not have &#039;content&#039; until saved; ve does not preview; phab:T221625&lt;br /&gt;
	json = json:match (&#039;&amp;lt;[Tt]emplate[Dd]ata&amp;gt;(.-)&amp;lt;/[Tt]emplate[Dd]ata&amp;gt;&#039;);		-- remove everything exept the content of the TemplatData tags&lt;br /&gt;
	return json and mw.text.jsonDecode (json);									-- decode the json string and return as a table; nil if not found&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; V A L I D A T E _ D O C U M E N T _ P A R A M &amp;gt;--------------------------------&lt;br /&gt;
&lt;br /&gt;
looks for &amp;lt;param&amp;gt; (can be the canonical parameter name or can be an alias) in whitelist.document_parameters_t.&lt;br /&gt;
When found, returns true; nil else&lt;br /&gt;
&lt;br /&gt;
&amp;lt;param&amp;gt; is the parameter&#039;s name as listed in the TemplateData&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function validate_document_param (param)&lt;br /&gt;
	if true == whitelist.document_parameters_t[param] then&lt;br /&gt;
		return true;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; V A L I D A T E _ U N I Q U E _ P A R A M &amp;gt;------------------------------------&lt;br /&gt;
&lt;br /&gt;
looks for &amp;lt;param&amp;gt; (can be the canonical parameter name or can be an alias) in whitelist.basic_arguments{} and if&lt;br /&gt;
necessary in whitelist.numbered_arguments{}.  When found, returns true; nil else&lt;br /&gt;
&lt;br /&gt;
&amp;lt;param&amp;gt; is the parameter&#039;s name as listed in the TemplateData&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function validate_basic_param (param)&lt;br /&gt;
	if true == whitelist.common_parameters_t[param] then&lt;br /&gt;
		return true;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; V A L I D A T E _ P R E P R I N T _ P A R A M &amp;gt;--------------------------------&lt;br /&gt;
&lt;br /&gt;
looks for &amp;lt;param&amp;gt; (can be the canonical parameter name or can be an alias) in whitelist.preprint_arguments_t{} or&lt;br /&gt;
whitelist.limited_basic_arguments{} or whitelist.limited_numbered_arguments{}.  When found, returns true; nil else&lt;br /&gt;
&lt;br /&gt;
&amp;lt;param&amp;gt; is the parameter&#039;s name as listed in the TemplateData&lt;br /&gt;
&amp;lt;key&amp;gt; is key neccessary to look in the appropriate subtable of whitelist.preprint_arguments_t{}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function validate_preprint_param (param, key)&lt;br /&gt;
	if true == whitelist.preprint_arguments_t[key][param] or&lt;br /&gt;
		true == whitelist.limited_parameters_t[param] then&lt;br /&gt;
--		true == whitelist.limited_basic_arguments_t[param] or&lt;br /&gt;
--		true == whitelist.limited_numbered_arguments_t[param] then&lt;br /&gt;
			return true;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; V A L I D A T E _ U N I Q U E _ P A R A M &amp;gt;------------------------------------&lt;br /&gt;
&lt;br /&gt;
looks for &amp;lt;param&amp;gt; (can be the canonical parameter name or can be an alias) in whitelist.unique_arguments_t{} or&lt;br /&gt;
whitelist.basic_arguments{} or whitelist.numbered_arguments{}.  When found, returns true; nil else&lt;br /&gt;
&lt;br /&gt;
&amp;lt;param&amp;gt; is the parameter&#039;s name as listed in the TemplateData&lt;br /&gt;
&amp;lt;key&amp;gt; is key neccessary to look in the appropriate subtable of whitelist.unique_arguments_t{}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function validate_unique_param (param, key, cfg_aliases_t)&lt;br /&gt;
	if true == whitelist.unique_arguments_t[key][param] or true == validate_basic_param (param) then&lt;br /&gt;
		return true;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; V A L I D A T E _ I D _ P A R A M &amp;gt;--------------------------------------------&lt;br /&gt;
&lt;br /&gt;
looks for &amp;lt;param&amp;gt; &amp;lt;alias&amp;gt; in identifier_aliases_t{}.  When found, returns true; nil else&lt;br /&gt;
&lt;br /&gt;
&amp;lt;param&amp;gt; is the parameter&#039;s name as listed in the TemplateData&lt;br /&gt;
&amp;lt;alias&amp;gt; is the alias that we&#039;re looking for&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function validate_id_alias (param, alias)&lt;br /&gt;
	return identifier_aliases_t[param] and identifier_aliases_t[param][alias];&lt;br /&gt;
end&lt;br /&gt;
	&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; P A R A M _ E R R O R_ M S G &amp;gt;-------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function param_error_msg (param)&lt;br /&gt;
	return &#039;&amp;lt;code style=&amp;quot;color: inherit; background: inherit; border: none; padding: inherit&amp;quot;&amp;gt;|&#039; .. param .. &#039;=&amp;lt;/code&amp;gt; is not a valid parameter&#039;;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; A L I A S _ E R R O R_ M S G &amp;gt;-------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function alias_error_msg (param, alias)&lt;br /&gt;
	return &#039;&amp;lt;code style=&amp;quot;color: inherit; background: inherit; border: none; padding: inherit&amp;quot;&amp;gt;|&#039; .. alias .. &#039;=&amp;lt;/code&amp;gt; is not a valid alias of: &amp;lt;code style=&amp;quot;color: inherit; background: inherit; border: none; padding: inherit&amp;quot;&amp;gt;|&#039; .. param .. &#039;=&amp;lt;/code&amp;gt;&#039;;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; C F G _ A L I A S E S _ T _ M A K E &amp;gt;------------------------------------------&lt;br /&gt;
&lt;br /&gt;
convert this from cfg.aliases{}:&lt;br /&gt;
	[&#039;AccessDate&#039;] = {&#039;access-date&#039;, &#039;accessdate&#039;}&lt;br /&gt;
&lt;br /&gt;
to this in out_t{}&lt;br /&gt;
	[&#039;access-date&#039;] = &#039;AccessDate&#039;,&lt;br /&gt;
	[&#039;accessdate&#039;] = &#039;AccessDate&#039;,&lt;br /&gt;
&lt;br /&gt;
to test if |accessdate= is an aliases of |access-date=:&lt;br /&gt;
	if out_t[&#039;access-date&#039;] == out_t[&#039;accessdate&#039;]&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function cfg_aliasts_t_make ()&lt;br /&gt;
	local out_t = {};&lt;br /&gt;
	for meta, params_t in pairs (cfg.aliases) do&lt;br /&gt;
		if &#039;table&#039; == type (params_t) then										-- metaparameters that are assigned string values do not have aliases&lt;br /&gt;
			for _, param in ipairs (params_t) do								-- for each alias&lt;br /&gt;
				param = param:gsub (&#039;#&#039;, &#039;&#039;);									-- get rid of enumerators&lt;br /&gt;
				out_t[param] = meta;											-- add it to the output table&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
--error (mw.dumpObject (out_t))&lt;br /&gt;
	return out_t;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; T E M P L A T E _ D A T A _ V A L I D A T E &amp;gt;----------------------------------&lt;br /&gt;
&lt;br /&gt;
compairs parameter names listed in a cs1|2 template&#039;s TemplateData structure (everything between &amp;lt;TemplateData&amp;gt;&lt;br /&gt;
and &amp;lt;/TemplateData&amp;gt; tag case insensitive).  Returns error messages when errors found, empty string else.&lt;br /&gt;
&lt;br /&gt;
	{{#invoke:Cs1 documentation support|template_data_validate|{{ROOTPAGENAME}}}}&lt;br /&gt;
&lt;br /&gt;
When called from a different page:&lt;br /&gt;
	{{#invoke:cs1 documentation support|template_data_validate|&amp;lt;canonical template name&amp;gt;}}&lt;br /&gt;
where the &amp;lt;canonical template name&amp;gt; is the template&#039;s canonical name with or without namespace and or subpages&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function template_data_validate (frame)&lt;br /&gt;
	local args_t = getArgs (frame);&lt;br /&gt;
&lt;br /&gt;
	if not args_t[1] then&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;Error: cs1|2 template name required&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local template_idx = args_t[1]:lower():match (&#039;cit[ae][^/]+&#039;);				-- args_t[1] has something&lt;br /&gt;
	if not template_idx then													-- but if not a cs1|2 template abandon with error message&lt;br /&gt;
		return &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;Error: cs1|2 template name required&amp;lt;/span&amp;gt;&#039;;&lt;br /&gt;
	else&lt;br /&gt;
		template_idx = template_idx:gsub (&#039; &#039;, &#039;&#039;);								-- is what appears to be a cs1|2 template so strip spaces&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local cfg_aliases_t = cfg_aliasts_t_make ();&lt;br /&gt;
&lt;br /&gt;
	local template_t = templates_t[template_idx];&lt;br /&gt;
	local out = {};&lt;br /&gt;
&lt;br /&gt;
	local template_doc = template_t[1];&lt;br /&gt;
	local json_t = template_data_json_get (template_doc);&lt;br /&gt;
	&lt;br /&gt;
	if not json_t then&lt;br /&gt;
		 table.insert (out, &#039;Error: can\&#039;t find TemplateData&#039;);&lt;br /&gt;
	else&lt;br /&gt;
		for param, param_t in pairs (json_t[&#039;params&#039;]) do&lt;br /&gt;
			local param_i;														-- this will be the parameter name that gets validated&lt;br /&gt;
			if param:find (&#039;[Ss]2[Cc][Ii][Dd]&#039;) then							-- |s2cid*= parameters are not enumerated ...&lt;br /&gt;
				param_i = param;												-- ... so don&#039;t convert the &#039;2&#039; to &#039;#&#039;&lt;br /&gt;
			else&lt;br /&gt;
				param_i = param:gsub (&#039;%d+&#039;, &#039;#&#039;);								-- for enumerated parameters, convert the enumerator digits to a single &#039;#&#039; character; all others unmolested&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local param_is_valid;												-- boolean true when param is valid; nil else&lt;br /&gt;
			if template_t[2] then												-- if template is a preprint or uses unique parameters of &#039;document&#039; parameters&lt;br /&gt;
				if &#039;document&#039; == template_t[2] then								-- if a {{cite document}} template&lt;br /&gt;
					param_is_valid = validate_document_param (param_i, template_t[2]);&lt;br /&gt;
					if param_is_valid then&lt;br /&gt;
						if param_t[&#039;aliases&#039;] then&lt;br /&gt;
							for _, alias in ipairs (param_t[&#039;aliases&#039;]) do&lt;br /&gt;
								local alias_i = alias:gsub (&#039;%d+&#039;, &#039;#&#039;);		-- in case an enumerated parameter, convert the enumerator digits to a single &#039;#&#039; character&lt;br /&gt;
								if not validate_document_param (alias_i, template_t[2]) then	-- is &#039;alias&#039; a known parameter?&lt;br /&gt;
	 								table.insert (out, alias_error_msg (param, alias));			-- may be known but is not supported&lt;br /&gt;
								elseif cfg_aliases_t[param_i:gsub (&#039;#&#039;, &#039;&#039;)] ~= cfg_aliases_t[alias_i:gsub (&#039;#&#039;, &#039;&#039;)] then	-- is &#039;alias&#039; known to be an alias of &#039;param&#039;?&lt;br /&gt;
									table.insert (out, alias_error_msg (param, alias));&lt;br /&gt;
 								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					else														-- here when param not valid preprint param&lt;br /&gt;
						table.insert (out, param_error_msg (param))&lt;br /&gt;
 					end&lt;br /&gt;
				elseif whitelist.preprint_arguments_t[template_t[2]] then			-- if a preprint template&lt;br /&gt;
					param_is_valid = validate_preprint_param (param_i, template_t[2]);&lt;br /&gt;
					if param_is_valid then&lt;br /&gt;
						if param_t[&#039;aliases&#039;] then&lt;br /&gt;
							for _, alias in ipairs (param_t[&#039;aliases&#039;]) do&lt;br /&gt;
								local alias_i = alias:gsub (&#039;%d+&#039;, &#039;#&#039;);		-- in case an enumerated parameter, convert the enumerator digits to a single &#039;#&#039; character&lt;br /&gt;
								if not validate_preprint_param (alias_i, template_t[2]) then	-- is &#039;alias&#039; a known parameter?&lt;br /&gt;
	 								table.insert (out, alias_error_msg (param, alias));			-- may be known but is not supported&lt;br /&gt;
								elseif cfg_aliases_t[param_i:gsub (&#039;#&#039;, &#039;&#039;)] ~= cfg_aliases_t[alias_i:gsub (&#039;#&#039;, &#039;&#039;)] then	-- is &#039;alias&#039; known to be an alias of &#039;param&#039;?&lt;br /&gt;
									table.insert (out, alias_error_msg (param, alias));&lt;br /&gt;
 								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					else														-- here when param not valid preprint param&lt;br /&gt;
						table.insert (out, param_error_msg (param))&lt;br /&gt;
 					end&lt;br /&gt;
				elseif whitelist.unique_arguments_t[template_t[2]] then			-- if a unique parameters template&lt;br /&gt;
					param_is_valid = validate_unique_param (param_i, template_t[2]);&lt;br /&gt;
					if param_is_valid then&lt;br /&gt;
						if param_t[&#039;aliases&#039;] then&lt;br /&gt;
							for _, alias in ipairs (param_t[&#039;aliases&#039;]) do&lt;br /&gt;
								local alias_i = alias:gsub (&#039;%d+&#039;, &#039;#&#039;);		-- in case an enumerated parameter, convert the enumerate digits to a single &#039;#&#039; character&lt;br /&gt;
								if not validate_unique_param (alias_i, template_t[2]) then	-- is &#039;alias&#039; a known parameter?&lt;br /&gt;
									table.insert (out, alias_error_msg (param, alias));&lt;br /&gt;
								elseif cfg_aliases_t[param_i:gsub (&#039;#&#039;, &#039;&#039;)] ~= cfg_aliases_t[alias_i:gsub (&#039;#&#039;, &#039;&#039;)] then	-- is &#039;alias&#039; known to be an alias of &#039;param&#039;?&lt;br /&gt;
									table.insert (out, alias_error_msg (param, alias));&lt;br /&gt;
 								end&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					else														-- here when param not valid unique parameter&lt;br /&gt;
						table.insert (out, param_error_msg (param))&lt;br /&gt;
 					end&lt;br /&gt;
				else															-- should never be here if coder is doing the right thing ...&lt;br /&gt;
					table.insert (out, &#039;internal error: unexpected keyword in templates_t: &#039; .. template_t[2]);&lt;br /&gt;
					break;&lt;br /&gt;
				end&lt;br /&gt;
			else																-- here when not unique or preprint&lt;br /&gt;
				param_is_valid = validate_basic_param (param_i);&lt;br /&gt;
				if param_is_valid then&lt;br /&gt;
					if param_t[&#039;aliases&#039;] then&lt;br /&gt;
						for _, alias in ipairs (param_t[&#039;aliases&#039;]) do&lt;br /&gt;
							local alias_i = alias:gsub (&#039;%d+&#039;, &#039;#&#039;);			-- in case an enumerated parameter, convert the enumerate digits to a single &#039;#&#039; character&lt;br /&gt;
							if not validate_basic_param (alias_i) and not validate_id_alias (param, alias) then	-- for isbn13 (while still supported) must not mask the digits&lt;br /&gt;
 								table.insert (out, alias_error_msg (param, alias));&lt;br /&gt;
							elseif cfg_aliases_t[param_i:gsub (&#039;#&#039;, &#039;&#039;)] ~= cfg_aliases_t[alias_i:gsub (&#039;#&#039;, &#039;&#039;)] then	-- is &#039;alias&#039; known to be an alias of &#039;param&#039;?&lt;br /&gt;
								table.insert (out, alias_error_msg (param, alias));&lt;br /&gt;
 							end&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				else															-- here when param not valid&lt;br /&gt;
					table.insert (out, param_error_msg (param))&lt;br /&gt;
 				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
---------- this emits errors when page/pages/at listed in templatedata of templates that don&#039;t support those parameters ----------&lt;br /&gt;
--	if json_t then&lt;br /&gt;
--		if ({[&#039;citeavmedia&#039;]=true, [&#039;citeepisode&#039;]=true, [&#039;citemailinglist&#039;]=true, [&#039;citenewsgroup&#039;]=true, [&#039;citepodcast&#039;]=true, [&#039;citeserial&#039;]=true, [&#039;citesign&#039;]=true, [&#039;citespeech&#039;]=true})[template_idx] then&lt;br /&gt;
--			local insource_params_t = {};										-- build sequence of pagination params not supported by these templates&lt;br /&gt;
--			for _, meta_param in ipairs ({&#039;At&#039;, &#039;Page&#039;, &#039;Pages&#039;, &#039;QuotePage&#039;, &#039;QuotePages&#039;}) do&lt;br /&gt;
--				if &#039;table&#039; == type (cfg.aliases[meta_param]) then&lt;br /&gt;
--					for _, alias in ipairs (cfg.aliases[meta_param]) do			-- metaparameter is a sequence&lt;br /&gt;
--						table.insert (insource_params_t, alias);				-- add the aliases from the metaparameter sequence to the table&lt;br /&gt;
--					end&lt;br /&gt;
--				else															-- metaparameter is plain text&lt;br /&gt;
--					table.insert (insource_params_t, cfg.aliases[meta_param]);	-- add the alias to the table&lt;br /&gt;
--				end&lt;br /&gt;
--			end&lt;br /&gt;
--		&lt;br /&gt;
--			for _, param in ipairs (insource_params_t) do&lt;br /&gt;
--				if json_t.params[param] then&lt;br /&gt;
--					table.insert (out, param_error_msg (param));				-- error; this parameter not supported by this template&lt;br /&gt;
--				end&lt;br /&gt;
--			end&lt;br /&gt;
--		end&lt;br /&gt;
--	end&lt;br /&gt;
---------- end page/pages/at error detection ----------&lt;br /&gt;
&lt;br /&gt;
	if 0 ~= #out then&lt;br /&gt;
		table.sort (out);&lt;br /&gt;
		out[1] = &#039;*&#039; .. out[1];													-- add a splat to the first error message&lt;br /&gt;
&lt;br /&gt;
--		return table.concat ({&#039;[[&#039; .. template_doc .. &#039;]] TemplateData has errors:&amp;lt;div style=&amp;quot;color:#d33; font-style: normal&amp;quot;&amp;gt;\n&#039;, table.concat (out, &#039;\n*&#039;), &#039;&amp;lt;/div&amp;gt;&#039;});&lt;br /&gt;
		return table.concat ({&lt;br /&gt;
			&#039;[[Template:&#039; .. args_t[1] .. &#039;]]  uses &#039;,&lt;br /&gt;
			whitelist.preprint_arguments_t[template_t[2]] and &#039;preprint and limited parameter sets&#039; or (whitelist.unique_arguments_t[template_t[2]] and &#039;unique and standard parameter sets&#039; or &#039;standard parameter set&#039;),&lt;br /&gt;
			&#039;; TemplateData has errors:\n&#039;,&lt;br /&gt;
			&#039;&amp;lt;div style=&amp;quot;color:#d33; font-style: normal&amp;quot;&amp;gt;\n&#039;, table.concat (out, &#039;\n*&#039;), &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
			});&lt;br /&gt;
	else&lt;br /&gt;
		return;																	-- no errors detected; return nothing&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; E R R O R _ C A T _ P A G E _ T A L L Y &amp;gt;--------------------------------------&lt;br /&gt;
&lt;br /&gt;
loop through Module:Citation/CS1/Configuration error_conditions {} fetching error category names.  For each error&lt;br /&gt;
category add the number of pages in the category to the tally.  Render the number when done.&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|error_cat_page_tally}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function error_cat_page_tally ()&lt;br /&gt;
	local error_conditions_t = cfg.error_conditions;							-- get the table of error conditions&lt;br /&gt;
	local tally = 0;&lt;br /&gt;
	local cat_t = {};															-- some error message share a category; save tallied cats here so we don&#039;t recount the already counted&lt;br /&gt;
	local i = 0;																-- number of categories&lt;br /&gt;
	&lt;br /&gt;
	for k, v_t in pairs (error_conditions_t) do&lt;br /&gt;
		if k:match (&#039;^err&#039;) then&lt;br /&gt;
			if not cat_t[v_t.category] then&lt;br /&gt;
				cat_t[v_t.category] = true;&lt;br /&gt;
				tally = tally +  mw.site.stats.pagesInCategory (v_t.category, &#039;pages&#039;);		-- get category page count; ignore subcats and files&lt;br /&gt;
				i = i + 1;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.language.getContentLanguage():formatNum (tally)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; M A I N T _ C A T _ P A G E _ T A L L Y &amp;gt;--------------------------------------&lt;br /&gt;
&lt;br /&gt;
loop through Module:Citation/CS1/Configuration error_conditions {} fetching error category names.  For each error&lt;br /&gt;
category add the number of pages in the category to the tally.  Render the number when done.&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|maint_cat_page_tally}}&lt;br /&gt;
&lt;br /&gt;
Dynamic subcats of CS1 maint: DOI inactive not counted because these names come and go as time goes by.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function maint_cat_page_tally ()&lt;br /&gt;
	local error_conditions_t = cfg.error_conditions;							-- get the table of error conditions&lt;br /&gt;
	local tally = 0;&lt;br /&gt;
	local cat_t = {};															-- some error message share a category; save tallied cats here so we don&#039;t recount the already counted&lt;br /&gt;
	local i = 0;																-- number of categories&lt;br /&gt;
	&lt;br /&gt;
	for k, v_t in pairs (error_conditions_t) do&lt;br /&gt;
		if not k:match (&#039;^err&#039;) then											-- if not an error key its a maint key&lt;br /&gt;
			if not cat_t[v_t.category] then&lt;br /&gt;
				cat_t[v_t.category] = true;&lt;br /&gt;
				if &#039;maint_mult_names&#039; == k or &#039;maint_numeric_names&#039; == k then&lt;br /&gt;
					local special_case_translation_t = cfg.special_case_translation;&lt;br /&gt;
					for _, name in ipairs ({&#039;AuthorList&#039;, &#039;ContributorList&#039;, &#039;EditorList&#039;, &#039;InterviewerList&#039;, &#039;TranslatorList&#039;}) do&lt;br /&gt;
						local cat_name = v_t.category:gsub (&#039;$1&#039;, special_case_translation_t[name]);	-- replace $1 with translated list name&lt;br /&gt;
						tally = tally +  mw.site.stats.pagesInCategory (cat_name, &#039;pages&#039;);		-- get category page count; ignore subcats and files&lt;br /&gt;
						i = i + 1;&lt;br /&gt;
					end&lt;br /&gt;
				else	&lt;br /&gt;
					tally = tally +  mw.site.stats.pagesInCategory (v_t.category, &#039;pages&#039;);		-- get category page count; ignore subcats and files&lt;br /&gt;
					i = i + 1;&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return mw.language.getContentLanguage():formatNum (tally)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; U N C A T E G O R I Z E D _ N A M E S P A C E _ L I S T E R &amp;gt;------------------&lt;br /&gt;
&lt;br /&gt;
For use in the Help:CS1 error §Notes&lt;br /&gt;
&lt;br /&gt;
Get namespace names and identifiers from MediaWiki.  Make a human readable list of namespace names and identifiers&lt;br /&gt;
that cs1|2 does not categorize.&lt;br /&gt;
&lt;br /&gt;
{{#invoke:cs1 documentation support|uncategorized_namespace_lister}}&lt;br /&gt;
&lt;br /&gt;
For convenience, &lt;br /&gt;
{{#invoke:cs1 documentation support|uncategorized_namespace_lister|all=&amp;lt;anything&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
returns a list of all namespace names and identifiers used on the current wiki.  Any namespace with an&lt;br /&gt;
identifier less than 1, currently Mainspace (0), Special (-1), and Media (-2), is excluded from the list.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function uncategorized_namespace_lister (frame)&lt;br /&gt;
	local list_t = {};&lt;br /&gt;
	local function compare (a, b)												-- local function to sort namespaces numerically by the identifiers&lt;br /&gt;
		local a_num = tonumber (a:match (&#039;%d+&#039;));								-- get identifiers and convert to numbers&lt;br /&gt;
		local b_num = tonumber (b:match (&#039;%d+&#039;));&lt;br /&gt;
		return a_num &amp;lt; b_num;													-- do the comparison&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for i, _ in pairs (mw.site.namespaces) do									-- for each namespace in the table&lt;br /&gt;
		if &#039;&#039; == frame.args.all or not frame.args.all then						-- when |all= not set, make a list of uncategorized namespaces&lt;br /&gt;
			if cfg.uncategorized_namespaces[i] then								-- if the identifier is listed in our uncategorized namespace list&lt;br /&gt;
				table.insert (list_t, table.concat ({mw.site.namespaces[i].name, &#039; (&#039;, i, &#039;)&#039;}))	-- add name and identifier to our local list&lt;br /&gt;
			end&lt;br /&gt;
		elseif 0 &amp;lt; i then														-- |all=&amp;lt;anything&amp;gt;: all namespace names and identifiers; ignore identifiers less than 1&lt;br /&gt;
			table.insert (list_t, table.concat ({&#039;*&#039;, mw.site.namespaces[i].name, &#039; (&#039;, i, &#039;)&#039;}))	-- add name and identifier as an unordered list item&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	table.sort (list_t, compare);												-- ascending numerical sort by identifier&lt;br /&gt;
&lt;br /&gt;
	if not frame.args.all then													-- when |all= not set, format list of uncategorized namespaces and identifiers&lt;br /&gt;
		list_t[#list_t] = &#039;and &#039; .. list_t[#list_t];							-- add &#039;and &#039; to the last name/identifier pair&lt;br /&gt;
		return table.concat (list_t, &#039;, &#039;);										-- make a big string and done&lt;br /&gt;
	else																		-- make list of all namespaces and identifiers&lt;br /&gt;
		return table.concat (list_t, &#039;\n&#039;);									-- make a big string and done&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[--------------------------&amp;lt; S I N G L E _ L T R _ 2 N D _ L V L _ D O M A I N  _ L I S T E R &amp;gt;-------------&lt;br /&gt;
&lt;br /&gt;
for Help:CS1_errors#bad_url, list the supported top level domains that support single-letter 2nd level names&lt;br /&gt;
&lt;br /&gt;
	{{#invoke:Module:cs1 documentation support|single_ltr_2nd_lvl_domain_lister}}&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local function single_ltr_2nd_lvl_domain_lister ()&lt;br /&gt;
	local out_t = {};															-- output goes here&lt;br /&gt;
	for _, tld in ipairs (cfg.single_letter_2nd_lvl_domains_t) do				-- fetch each tld&lt;br /&gt;
		table.insert (out_t, &#039;.&#039; .. tld);										-- prefix with a dot and save in out_t{}&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat (out_t, &#039;, &#039;);											-- make a big string and done&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
--[[--------------------------&amp;lt; E X P O R T E D   F U N C T I O N S &amp;gt;------------------------------------------&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	alias_lister = alias_lister,&lt;br /&gt;
	alias_names_get = alias_names_get,&lt;br /&gt;
	canonical_param_lister = canonical_param_lister,&lt;br /&gt;
	canonical_name_get = canonical_name_get,&lt;br /&gt;
	cat_lister = cat_lister,&lt;br /&gt;
	error_cat_page_tally = error_cat_page_tally,&lt;br /&gt;
	header_make = header_make,&lt;br /&gt;
	help_text_cats = help_text_cats,&lt;br /&gt;
	help_text_error_messages = help_text_error_messages,&lt;br /&gt;
	id_limits_get = id_limits_get,&lt;br /&gt;
	is_book_cite_template = is_book_cite_template,&lt;br /&gt;
	is_limited_param_template = is_limited_param_template,&lt;br /&gt;
	lang_lister = lang_lister,&lt;br /&gt;
	maint_cat_page_tally = maint_cat_page_tally,&lt;br /&gt;
	script_lang_lister = script_lang_lister,&lt;br /&gt;
	single_ltr_2nd_lvl_domain_lister = single_ltr_2nd_lvl_domain_lister,&lt;br /&gt;
	template_data_validate = template_data_validate,&lt;br /&gt;
	uncategorized_namespace_lister = uncategorized_namespace_lister,&lt;br /&gt;
	};&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>