<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://travis.lentzsystems.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Saml</id>
	<title>Travel Information System (TravIS) - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://travis.lentzsystems.net/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Saml"/>
	<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Special:Contributions/Saml"/>
	<updated>2026-04-10T14:34:46Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.0</generator>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Template:Ifsubst&amp;diff=26</id>
		<title>Template:Ifsubst</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Template:Ifsubst&amp;diff=26"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ safesubst:&amp;lt;noinclude/&amp;gt;#if:{{{demo|}}}&lt;br /&gt;
|{{ safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{{demo}}} |no&lt;br /&gt;
 |{{{no|{{{2|}}}}}}&lt;br /&gt;
 |{{{yes|{{{1|}}}}}}&lt;br /&gt;
}}&lt;br /&gt;
|{{ safesubst:&amp;lt;noinclude/&amp;gt;#ifeq:{{ safesubst:&amp;lt;noinclude/&amp;gt;NAMESPACE}}|{{NAMESPACE}}&lt;br /&gt;
 |{{{no|{{{2|}}}}}}&lt;br /&gt;
 |{{{yes|{{{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>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Template:Mono&amp;diff=24</id>
		<title>Template:Mono</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Template:Mono&amp;diff=24"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&amp;lt;includeonly&amp;gt;safesubst:&amp;lt;/includeonly&amp;gt;ifsubst|1=|2=&amp;lt;templatestyles src=&amp;quot;Mono/styles.css&amp;quot; /&amp;gt;}}&amp;lt;span class=&amp;quot;monospaced&amp;quot;&amp;gt;{{{2|{{{1}}}}}}&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&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>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Module:Redirect&amp;diff=22</id>
		<title>Module:Redirect</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Module:Redirect&amp;diff=22"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module provides functions for getting the target of a redirect page.&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Gets a mw.title object, using pcall to avoid generating script errors if we&lt;br /&gt;
-- are over the expensive function count limit (among other possible causes).&lt;br /&gt;
local function getTitle(...)&lt;br /&gt;
	local success, titleObj = pcall(mw.title.new, ...)&lt;br /&gt;
	if success then&lt;br /&gt;
		return titleObj&lt;br /&gt;
	else&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Gets the name of a page that a redirect leads to, or nil if it isn&#039;t a&lt;br /&gt;
-- redirect.&lt;br /&gt;
function p.getTargetFromText(text)&lt;br /&gt;
	local target = string.match(&lt;br /&gt;
		text,&lt;br /&gt;
		&amp;quot;^%s*#[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]%s*:?%s*%[%[([^%[%]|]-)%]%]&amp;quot;&lt;br /&gt;
	) or string.match(&lt;br /&gt;
		text,&lt;br /&gt;
		&amp;quot;^%s*#[Rr][Ee][Dd][Ii][Rr][Ee][Cc][Tt]%s*:?%s*%[%[([^%[%]|]-)|[^%[%]]-%]%]&amp;quot;&lt;br /&gt;
	)&lt;br /&gt;
	return target and mw.uri.decode(target, &#039;PATH&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Gets the target of a redirect. If the page specified is not a redirect,&lt;br /&gt;
-- returns nil.&lt;br /&gt;
function p.getTarget(page, fulltext)&lt;br /&gt;
	-- Get the title object. Both page names and title objects are allowed&lt;br /&gt;
	-- as input.&lt;br /&gt;
	local titleObj&lt;br /&gt;
	if type(page) == &#039;string&#039; or type(page) == &#039;number&#039; then&lt;br /&gt;
		titleObj = getTitle(page)&lt;br /&gt;
	elseif type(page) == &#039;table&#039; and type(page.getContent) == &#039;function&#039; then&lt;br /&gt;
		titleObj = page&lt;br /&gt;
	else&lt;br /&gt;
		error(string.format(&lt;br /&gt;
			&amp;quot;bad argument #1 to &#039;getTarget&#039;&amp;quot;&lt;br /&gt;
				.. &amp;quot; (string, number, or title object expected, got %s)&amp;quot;,&lt;br /&gt;
			type(page)&lt;br /&gt;
		), 2)&lt;br /&gt;
	end&lt;br /&gt;
	if not titleObj then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local targetTitle = titleObj.redirectTarget&lt;br /&gt;
	if targetTitle then&lt;br /&gt;
		if fulltext then&lt;br /&gt;
			return targetTitle.fullText&lt;br /&gt;
		else&lt;br /&gt;
			return targetTitle.prefixedText&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
-- Given a single page name determines what page it redirects to and returns the&lt;br /&gt;
-- target page name, or the passed page name when not a redirect. The passed&lt;br /&gt;
-- page name can be given as plain text or as a page link.&lt;br /&gt;
--&lt;br /&gt;
-- Returns page name as plain text, or when the bracket parameter is given, as a&lt;br /&gt;
-- page link. Returns an error message when page does not exist or the redirect&lt;br /&gt;
-- target cannot be determined for some reason.&lt;br /&gt;
--]]&lt;br /&gt;
function p.luaMain(rname, bracket, fulltext)&lt;br /&gt;
	if type(rname) ~= &amp;quot;string&amp;quot; or not rname:find(&amp;quot;%S&amp;quot;) then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	bracket = bracket and &amp;quot;[[%s]]&amp;quot; or &amp;quot;%s&amp;quot;&lt;br /&gt;
	rname = rname:match(&amp;quot;%[%[(.+)%]%]&amp;quot;) or rname&lt;br /&gt;
	local target = p.getTarget(rname, fulltext)&lt;br /&gt;
	local ret = target or rname&lt;br /&gt;
	ret = getTitle(ret)&lt;br /&gt;
	if ret then&lt;br /&gt;
		if fulltext then&lt;br /&gt;
			ret = ret.fullText&lt;br /&gt;
		else&lt;br /&gt;
			ret = ret.prefixedText&lt;br /&gt;
		end&lt;br /&gt;
		return bracket:format(ret)&lt;br /&gt;
	else&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Provides access to the luaMain function from wikitext.&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = require(&#039;Module:Arguments&#039;).getArgs(frame, {frameOnly = true})&lt;br /&gt;
	return p.luaMain(args[1], args.bracket, args.fulltext) or &#039;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Returns true if the specified page is a redirect, and false otherwise.&lt;br /&gt;
function p.luaIsRedirect(page)&lt;br /&gt;
	local titleObj = getTitle(page)&lt;br /&gt;
	if not titleObj then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	if titleObj.isRedirect then&lt;br /&gt;
		return true&lt;br /&gt;
	else&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Provides access to the luaIsRedirect function from wikitext, returning &#039;yes&#039;&lt;br /&gt;
-- if the specified page is a redirect, and the blank string otherwise.&lt;br /&gt;
function p.isRedirect(frame)&lt;br /&gt;
	local args = require(&#039;Module:Arguments&#039;).getArgs(frame, {frameOnly = true})&lt;br /&gt;
	if p.luaIsRedirect(args[1]) then&lt;br /&gt;
		return &#039;yes&#039;&lt;br /&gt;
	else&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Module:Message_box/configuration&amp;diff=20</id>
		<title>Module:Message box/configuration</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Module:Message_box/configuration&amp;diff=20"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--------------------------------------------------------------------------------&lt;br /&gt;
--                          Message box configuration                         --&lt;br /&gt;
--                                                                            --&lt;br /&gt;
-- This module contains configuration data for [[Module:Message box]].        --&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	ambox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;ambox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;ambox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;ambox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;ambox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;ambox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;ambox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle-keyhole.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;ambox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default                     = &#039;notice&#039;,&lt;br /&gt;
		allowBlankParams            = {&#039;talk&#039;, &#039;sect&#039;, &#039;date&#039;, &#039;issue&#039;, &#039;fix&#039;, &#039;subst&#039;, &#039;hidden&#039;},&lt;br /&gt;
		allowSmall                  = true,&lt;br /&gt;
		smallParam                  = &#039;left&#039;,&lt;br /&gt;
		smallClass                  = &#039;mbox-small-left&#039;,&lt;br /&gt;
		substCheck                  = true,&lt;br /&gt;
		classes                     = {&#039;metadata&#039;, &#039;ambox&#039;},&lt;br /&gt;
		imageEmptyCell              = true,&lt;br /&gt;
		imageCheckBlank             = true,&lt;br /&gt;
		imageSmallSize              = &#039;20x20px&#039;,&lt;br /&gt;
		imageCellDiv                = true,&lt;br /&gt;
		useCollapsibleTextFields    = true,&lt;br /&gt;
		imageRightNone              = true,&lt;br /&gt;
		sectionDefault              = &#039;article&#039;,&lt;br /&gt;
		allowMainspaceCategories    = true,&lt;br /&gt;
		templateCategory            = &#039;Article message templates&#039;,&lt;br /&gt;
	        templateCategoryRequireName = true,&lt;br /&gt;
		templateErrorCategory       = &#039;Article message templates with missing parameters&#039;,&lt;br /&gt;
		templateErrorParamsToCheck  = {&#039;issue&#039;, &#039;fix&#039;, &#039;subst&#039;},&lt;br /&gt;
		removalNotice               = &#039;&amp;lt;small&amp;gt;[[Help:Maintenance template removal|Learn how and when to remove this template message]]&amp;lt;/small&amp;gt;&#039;,&lt;br /&gt;
		templatestyles              = &#039;Module:Message box/ambox.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	cmbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;cmbox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;cmbox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;cmbox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;cmbox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;cmbox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;cmbox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle-keyhole.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;cmbox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;cmbox&#039;},&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		templatestyles       = &#039;Module:Message box/cmbox.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	fmbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			warning = {&lt;br /&gt;
				class = &#039;fmbox-warning&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			editnotice = {&lt;br /&gt;
				class = &#039;fmbox-editnotice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			system = {&lt;br /&gt;
				class = &#039;fmbox-system&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;system&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;fmbox&#039;},&lt;br /&gt;
		imageEmptyCell       = false,&lt;br /&gt;
		imageRightNone       = false,&lt;br /&gt;
		templatestyles       = &#039;Module:Message box/fmbox.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	imbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;imbox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;imbox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;imbox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;imbox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;imbox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;imbox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle-keyhole.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			license = {&lt;br /&gt;
				class = &#039;imbox-license licensetpl&#039;,&lt;br /&gt;
				image = &#039;Imbox license.png&#039; -- @todo We need an SVG version of this&lt;br /&gt;
			},&lt;br /&gt;
			featured = {&lt;br /&gt;
				class = &#039;imbox-featured&#039;,&lt;br /&gt;
				image = &#039;Cscr-featured.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;imbox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;imbox&#039;},&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		below                = true,&lt;br /&gt;
		templateCategory     = &#039;File message boxes&#039;,&lt;br /&gt;
		templatestyles       = &#039;Module:Message box/imbox.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	ombox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;ombox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;ombox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;ombox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;ombox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;ombox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;ombox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle-keyhole.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;ombox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;ombox&#039;},&lt;br /&gt;
		allowSmall           = true,&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		imageRightNone       = true,&lt;br /&gt;
		templatestyles       = &#039;Module:Message box/ombox.css&#039;&lt;br /&gt;
	},&lt;br /&gt;
	&lt;br /&gt;
	tmbox = {&lt;br /&gt;
		types = {&lt;br /&gt;
			speedy = {&lt;br /&gt;
				class = &#039;tmbox-speedy&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			delete = {&lt;br /&gt;
				class = &#039;tmbox-delete&#039;,&lt;br /&gt;
				image = &#039;Ambox warning pn.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			content = {&lt;br /&gt;
				class = &#039;tmbox-content&#039;,&lt;br /&gt;
				image = &#039;Ambox important.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			style = {&lt;br /&gt;
				class = &#039;tmbox-style&#039;,&lt;br /&gt;
				image = &#039;Edit-clear.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			move = {&lt;br /&gt;
				class = &#039;tmbox-move&#039;,&lt;br /&gt;
				image = &#039;Merge-split-transwiki default.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			protection = {&lt;br /&gt;
				class = &#039;tmbox-protection&#039;,&lt;br /&gt;
				image = &#039;Semi-protection-shackle-keyhole.svg&#039;&lt;br /&gt;
			},&lt;br /&gt;
			notice = {&lt;br /&gt;
				class = &#039;tmbox-notice&#039;,&lt;br /&gt;
				image = &#039;Information icon4.svg&#039;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
		default              = &#039;notice&#039;,&lt;br /&gt;
		showInvalidTypeError = true,&lt;br /&gt;
		classes              = {&#039;tmbox&#039;},&lt;br /&gt;
		allowSmall           = true,&lt;br /&gt;
		imageRightNone       = true,&lt;br /&gt;
		imageEmptyCell       = true,&lt;br /&gt;
		templateCategory     = &#039;Talk message boxes&#039;,&lt;br /&gt;
		templatestyles       = &#039;Module:Message box/tmbox.css&#039;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Module:Message_box&amp;diff=18</id>
		<title>Module:Message box</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Module:Message_box&amp;diff=18"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;require(&#039;strict&#039;)&lt;br /&gt;
local getArgs&lt;br /&gt;
local yesno = require(&#039;Module:Yesno&#039;)&lt;br /&gt;
local lang = mw.language.getContentLanguage()&lt;br /&gt;
&lt;br /&gt;
local CONFIG_MODULE = &#039;Module:Message box/configuration&#039;&lt;br /&gt;
local DEMOSPACES = {talk = &#039;tmbox&#039;, image = &#039;imbox&#039;, file = &#039;imbox&#039;, category = &#039;cmbox&#039;, article = &#039;ambox&#039;, main = &#039;ambox&#039;}&lt;br /&gt;
&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Helper functions&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local function getTitleObject(...)&lt;br /&gt;
	-- Get the title object, passing the function through pcall&lt;br /&gt;
	-- in case we are over the expensive function count limit.&lt;br /&gt;
	local success, title = pcall(mw.title.new, ...)&lt;br /&gt;
	if success then&lt;br /&gt;
		return title&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function union(t1, t2)&lt;br /&gt;
	-- Returns the union of two arrays.&lt;br /&gt;
	local vals = {}&lt;br /&gt;
	for i, v in ipairs(t1) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	for i, v in ipairs(t2) do&lt;br /&gt;
		vals[v] = true&lt;br /&gt;
	end&lt;br /&gt;
	local ret = {}&lt;br /&gt;
	for k in pairs(vals) do&lt;br /&gt;
		table.insert(ret, k)&lt;br /&gt;
	end&lt;br /&gt;
	table.sort(ret)&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getArgNums(args, prefix)&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		local num = mw.ustring.match(tostring(k), &#039;^&#039; .. prefix .. &#039;([1-9]%d*)$&#039;)&lt;br /&gt;
		if num then&lt;br /&gt;
			table.insert(nums, tonumber(num))&lt;br /&gt;
		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;
--------------------------------------------------------------------------------&lt;br /&gt;
-- Box class definition&lt;br /&gt;
--------------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
local MessageBox = {}&lt;br /&gt;
MessageBox.__index = MessageBox&lt;br /&gt;
&lt;br /&gt;
function MessageBox.new(boxType, args, cfg)&lt;br /&gt;
	args = args or {}&lt;br /&gt;
	local obj = {}&lt;br /&gt;
&lt;br /&gt;
	-- Set the title object and the namespace.&lt;br /&gt;
	obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()&lt;br /&gt;
&lt;br /&gt;
	-- Set the config for our box type.&lt;br /&gt;
	obj.cfg = cfg[boxType]&lt;br /&gt;
	if not obj.cfg then&lt;br /&gt;
		local ns = obj.title.namespace&lt;br /&gt;
		-- boxType is &amp;quot;mbox&amp;quot; or invalid input&lt;br /&gt;
		if args.demospace and args.demospace ~= &#039;&#039; then&lt;br /&gt;
			-- implement demospace parameter of mbox&lt;br /&gt;
			local demospace = string.lower(args.demospace)&lt;br /&gt;
			if DEMOSPACES[demospace] then&lt;br /&gt;
				-- use template from DEMOSPACES&lt;br /&gt;
				obj.cfg = cfg[DEMOSPACES[demospace]]&lt;br /&gt;
			elseif string.find( demospace, &#039;talk&#039; ) then&lt;br /&gt;
				-- demo as a talk page&lt;br /&gt;
				obj.cfg = cfg.tmbox&lt;br /&gt;
			else&lt;br /&gt;
				-- default to ombox&lt;br /&gt;
				obj.cfg = cfg.ombox&lt;br /&gt;
			end&lt;br /&gt;
		elseif ns == 0 then&lt;br /&gt;
			obj.cfg = cfg.ambox -- main namespace&lt;br /&gt;
		elseif ns == 6 then&lt;br /&gt;
			obj.cfg = cfg.imbox -- file namespace&lt;br /&gt;
		elseif ns == 14 then&lt;br /&gt;
			obj.cfg = cfg.cmbox -- category namespace&lt;br /&gt;
		else&lt;br /&gt;
			local nsTable = mw.site.namespaces[ns]&lt;br /&gt;
			if nsTable and nsTable.isTalk then&lt;br /&gt;
				obj.cfg = cfg.tmbox -- any talk namespace&lt;br /&gt;
			else&lt;br /&gt;
				obj.cfg = cfg.ombox -- other namespaces or invalid input&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set the arguments, and remove all blank arguments except for the ones&lt;br /&gt;
	-- listed in cfg.allowBlankParams.&lt;br /&gt;
	do&lt;br /&gt;
		local newArgs = {}&lt;br /&gt;
		for k, v in pairs(args) do&lt;br /&gt;
			if v ~= &#039;&#039; then&lt;br /&gt;
				newArgs[k] = v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		for i, param in ipairs(obj.cfg.allowBlankParams or {}) do&lt;br /&gt;
			newArgs[param] = args[param]&lt;br /&gt;
		end&lt;br /&gt;
		obj.args = newArgs&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Define internal data structure.&lt;br /&gt;
	obj.categories = {}&lt;br /&gt;
	obj.classes = {}&lt;br /&gt;
	-- For lazy loading of [[Module:Category handler]].&lt;br /&gt;
	obj.hasCategories = false&lt;br /&gt;
&lt;br /&gt;
	return setmetatable(obj, MessageBox)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:addCat(ns, cat, sort)&lt;br /&gt;
	if not cat then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	if sort then&lt;br /&gt;
		cat = string.format(&#039;[[Category:%s|%s]]&#039;, cat, sort)&lt;br /&gt;
	else&lt;br /&gt;
		cat = string.format(&#039;[[Category:%s]]&#039;, cat)&lt;br /&gt;
	end&lt;br /&gt;
	self.hasCategories = true&lt;br /&gt;
	self.categories[ns] = self.categories[ns] or {}&lt;br /&gt;
	table.insert(self.categories[ns], cat)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:addClass(class)&lt;br /&gt;
	if not class then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	table.insert(self.classes, class)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:setParameters()&lt;br /&gt;
	local args = self.args&lt;br /&gt;
	local cfg = self.cfg&lt;br /&gt;
&lt;br /&gt;
	-- Get type data.&lt;br /&gt;
	self.type = args.type&lt;br /&gt;
	local typeData = cfg.types[self.type]&lt;br /&gt;
	self.invalidTypeError = cfg.showInvalidTypeError&lt;br /&gt;
		and self.type&lt;br /&gt;
		and not typeData&lt;br /&gt;
	typeData = typeData or cfg.types[cfg.default]&lt;br /&gt;
	self.typeClass = typeData.class&lt;br /&gt;
	self.typeImage = typeData.image&lt;br /&gt;
&lt;br /&gt;
	-- Find if the box has been wrongly substituted.&lt;br /&gt;
	self.isSubstituted = cfg.substCheck and args.subst == &#039;SUBST&#039;&lt;br /&gt;
&lt;br /&gt;
	-- Find whether we are using a small message box.&lt;br /&gt;
	self.isSmall = cfg.allowSmall and (&lt;br /&gt;
		cfg.smallParam and args.small == cfg.smallParam&lt;br /&gt;
		or not cfg.smallParam and yesno(args.small)&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	-- Add attributes, classes and styles.&lt;br /&gt;
	self.id = args.id&lt;br /&gt;
	self.name = args.name&lt;br /&gt;
	if self.name then&lt;br /&gt;
		self:addClass(&#039;box-&#039; .. string.gsub(self.name,&#039; &#039;,&#039;_&#039;))&lt;br /&gt;
	end&lt;br /&gt;
	if yesno(args.plainlinks) ~= false then&lt;br /&gt;
		self:addClass(&#039;plainlinks&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	for _, class in ipairs(cfg.classes or {}) do&lt;br /&gt;
		self:addClass(class)&lt;br /&gt;
	end&lt;br /&gt;
	if self.isSmall then&lt;br /&gt;
		self:addClass(cfg.smallClass or &#039;mbox-small&#039;)&lt;br /&gt;
	end&lt;br /&gt;
	self:addClass(self.typeClass)&lt;br /&gt;
	self:addClass(args.class)&lt;br /&gt;
	self.style = args.style&lt;br /&gt;
	self.attrs = args.attrs&lt;br /&gt;
&lt;br /&gt;
	-- Set text style.&lt;br /&gt;
	self.textstyle = args.textstyle&lt;br /&gt;
&lt;br /&gt;
	-- Find if we are on the template page or not. This functionality is only&lt;br /&gt;
	-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory&lt;br /&gt;
	-- and cfg.templateCategoryRequireName are set.&lt;br /&gt;
	self.useCollapsibleTextFields = cfg.useCollapsibleTextFields&lt;br /&gt;
	if self.useCollapsibleTextFields&lt;br /&gt;
		or cfg.templateCategory&lt;br /&gt;
		and cfg.templateCategoryRequireName&lt;br /&gt;
	then&lt;br /&gt;
		if self.name then&lt;br /&gt;
			local templateName = mw.ustring.match(&lt;br /&gt;
				self.name,&lt;br /&gt;
				&#039;^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$&#039;&lt;br /&gt;
			) or self.name&lt;br /&gt;
			templateName = &#039;Template:&#039; .. templateName&lt;br /&gt;
			self.templateTitle = getTitleObject(templateName)&lt;br /&gt;
		end&lt;br /&gt;
		self.isTemplatePage = self.templateTitle&lt;br /&gt;
			and mw.title.equals(self.title, self.templateTitle)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Process data for collapsible text fields. At the moment these are only&lt;br /&gt;
	-- used in {{ambox}}.&lt;br /&gt;
	if self.useCollapsibleTextFields then&lt;br /&gt;
		-- Get the self.issue value.&lt;br /&gt;
		if self.isSmall and args.smalltext then&lt;br /&gt;
			self.issue = args.smalltext&lt;br /&gt;
		else&lt;br /&gt;
			local sect&lt;br /&gt;
			if args.sect == &#039;&#039; then&lt;br /&gt;
				sect = &#039;This &#039; .. (cfg.sectionDefault or &#039;page&#039;)&lt;br /&gt;
			elseif type(args.sect) == &#039;string&#039; then&lt;br /&gt;
				sect = &#039;This &#039; .. args.sect&lt;br /&gt;
			end&lt;br /&gt;
			local issue = args.issue&lt;br /&gt;
			issue = type(issue) == &#039;string&#039; and issue ~= &#039;&#039; and issue or nil&lt;br /&gt;
			local text = args.text&lt;br /&gt;
			text = type(text) == &#039;string&#039; and text or nil&lt;br /&gt;
			local issues = {}&lt;br /&gt;
			table.insert(issues, sect)&lt;br /&gt;
			table.insert(issues, issue)&lt;br /&gt;
			table.insert(issues, text)&lt;br /&gt;
			self.issue = table.concat(issues, &#039; &#039;)&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Get the self.talk value.&lt;br /&gt;
		local talk = args.talk&lt;br /&gt;
		-- Show talk links on the template page or template subpages if the talk&lt;br /&gt;
		-- parameter is blank.&lt;br /&gt;
		if talk == &#039;&#039;&lt;br /&gt;
			and self.templateTitle&lt;br /&gt;
			and (&lt;br /&gt;
				mw.title.equals(self.templateTitle, self.title)&lt;br /&gt;
				or self.title:isSubpageOf(self.templateTitle)&lt;br /&gt;
			)&lt;br /&gt;
		then&lt;br /&gt;
			talk = &#039;#&#039;&lt;br /&gt;
		elseif talk == &#039;&#039; then&lt;br /&gt;
			talk = nil&lt;br /&gt;
		end&lt;br /&gt;
		if talk then&lt;br /&gt;
			-- If the talk value is a talk page, make a link to that page. Else&lt;br /&gt;
			-- assume that it&#039;s a section heading, and make a link to the talk&lt;br /&gt;
			-- page of the current page with that section heading.&lt;br /&gt;
			local talkTitle = getTitleObject(talk)&lt;br /&gt;
			local talkArgIsTalkPage = true&lt;br /&gt;
			if not talkTitle or not talkTitle.isTalkPage then&lt;br /&gt;
				talkArgIsTalkPage = false&lt;br /&gt;
				talkTitle = getTitleObject(&lt;br /&gt;
					self.title.text,&lt;br /&gt;
					mw.site.namespaces[self.title.namespace].talk.id&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
			if talkTitle and talkTitle.exists then&lt;br /&gt;
                local talkText&lt;br /&gt;
                if self.isSmall then&lt;br /&gt;
                    local talkLink = talkArgIsTalkPage and talk or (talkTitle.prefixedText .. &#039;#&#039; .. talk)&lt;br /&gt;
                    talkText = string.format(&#039;([[%s|talk]])&#039;, talkLink)&lt;br /&gt;
                else&lt;br /&gt;
                    talkText = &#039;Relevant discussion may be found on&#039;&lt;br /&gt;
                    if talkArgIsTalkPage then&lt;br /&gt;
                        talkText = string.format(&lt;br /&gt;
                            &#039;%s [[%s|%s]].&#039;,&lt;br /&gt;
                            talkText,&lt;br /&gt;
                            talk,&lt;br /&gt;
                            talkTitle.prefixedText&lt;br /&gt;
                        )&lt;br /&gt;
                    else&lt;br /&gt;
                        talkText = string.format(&lt;br /&gt;
                            &#039;%s the [[%s#%s|talk page]].&#039;,&lt;br /&gt;
                            talkText,&lt;br /&gt;
                            talkTitle.prefixedText,&lt;br /&gt;
                            talk&lt;br /&gt;
                        )&lt;br /&gt;
                    end&lt;br /&gt;
                end&lt;br /&gt;
				self.talk = talkText&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		-- Get other values.&lt;br /&gt;
		self.fix = args.fix ~= &#039;&#039; and args.fix or nil&lt;br /&gt;
		local date&lt;br /&gt;
		if args.date and args.date ~= &#039;&#039; then&lt;br /&gt;
			date = args.date&lt;br /&gt;
		elseif args.date == &#039;&#039; and self.isTemplatePage then&lt;br /&gt;
			date = lang:formatDate(&#039;F Y&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		if date then&lt;br /&gt;
			self.date = string.format(&amp;quot; &amp;lt;span class=&#039;date-container&#039;&amp;gt;&amp;lt;i&amp;gt;(&amp;lt;span class=&#039;date&#039;&amp;gt;%s&amp;lt;/span&amp;gt;)&amp;lt;/i&amp;gt;&amp;lt;/span&amp;gt;&amp;quot;, date)&lt;br /&gt;
		end&lt;br /&gt;
		self.info = args.info&lt;br /&gt;
		if yesno(args.removalnotice) then&lt;br /&gt;
			self.removalNotice = cfg.removalNotice&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set the non-collapsible text field. At the moment this is used by all box&lt;br /&gt;
	-- types other than ambox, and also by ambox when small=yes.&lt;br /&gt;
	if self.isSmall then&lt;br /&gt;
		self.text = args.smalltext or args.text&lt;br /&gt;
	else&lt;br /&gt;
		self.text = args.text&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set the below row.&lt;br /&gt;
	self.below = cfg.below and args.below&lt;br /&gt;
&lt;br /&gt;
	-- General image settings.&lt;br /&gt;
	self.imageCellDiv = not self.isSmall and cfg.imageCellDiv&lt;br /&gt;
	self.imageEmptyCell = cfg.imageEmptyCell&lt;br /&gt;
&lt;br /&gt;
	-- Left image settings.&lt;br /&gt;
	local imageLeft = self.isSmall and args.smallimage or args.image&lt;br /&gt;
	if cfg.imageCheckBlank and imageLeft ~= &#039;blank&#039; and imageLeft ~= &#039;none&#039;&lt;br /&gt;
		or not cfg.imageCheckBlank and imageLeft ~= &#039;none&#039;&lt;br /&gt;
	then&lt;br /&gt;
		self.imageLeft = imageLeft&lt;br /&gt;
		if not imageLeft then&lt;br /&gt;
			local imageSize = self.isSmall&lt;br /&gt;
				and (cfg.imageSmallSize or &#039;30x30px&#039;)&lt;br /&gt;
				or &#039;40x40px&#039;&lt;br /&gt;
			self.imageLeft = string.format(&#039;[[File:%s|%s|link=|alt=]]&#039;, self.typeImage&lt;br /&gt;
				or &#039;Imbox notice.png&#039;, imageSize)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Right image settings.&lt;br /&gt;
	local imageRight = self.isSmall and args.smallimageright or args.imageright&lt;br /&gt;
	if not (cfg.imageRightNone and imageRight == &#039;none&#039;) then&lt;br /&gt;
		self.imageRight = imageRight&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- set templatestyles&lt;br /&gt;
	self.base_templatestyles = cfg.templatestyles&lt;br /&gt;
	self.templatestyles = args.templatestyles&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:setMainspaceCategories()&lt;br /&gt;
	local args = self.args&lt;br /&gt;
	local cfg = self.cfg&lt;br /&gt;
&lt;br /&gt;
	if not cfg.allowMainspaceCategories then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local nums = {}&lt;br /&gt;
	for _, prefix in ipairs{&#039;cat&#039;, &#039;category&#039;, &#039;all&#039;} do&lt;br /&gt;
		args[prefix .. &#039;1&#039;] = args[prefix]&lt;br /&gt;
		nums = union(nums, getArgNums(args, prefix))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- The following is roughly equivalent to the old {{Ambox/category}}.&lt;br /&gt;
	local date = args.date&lt;br /&gt;
	date = type(date) == &#039;string&#039; and date&lt;br /&gt;
	local preposition = &#039;from&#039;&lt;br /&gt;
	for _, num in ipairs(nums) do&lt;br /&gt;
		local mainCat = args[&#039;cat&#039; .. tostring(num)]&lt;br /&gt;
			or args[&#039;category&#039; .. tostring(num)]&lt;br /&gt;
		local allCat = args[&#039;all&#039; .. tostring(num)]&lt;br /&gt;
		mainCat = type(mainCat) == &#039;string&#039; and mainCat&lt;br /&gt;
		allCat = type(allCat) == &#039;string&#039; and allCat&lt;br /&gt;
		if mainCat and date and date ~= &#039;&#039; then&lt;br /&gt;
			local catTitle = string.format(&#039;%s %s %s&#039;, mainCat, preposition, date)&lt;br /&gt;
			self:addCat(0, catTitle)&lt;br /&gt;
			catTitle = getTitleObject(&#039;Category:&#039; .. catTitle)&lt;br /&gt;
			if not catTitle or not catTitle.exists then&lt;br /&gt;
				self:addCat(0, &#039;Articles with invalid date parameter in template&#039;)&lt;br /&gt;
			end&lt;br /&gt;
		elseif mainCat and (not date or date == &#039;&#039;) then&lt;br /&gt;
			self:addCat(0, mainCat)&lt;br /&gt;
		end&lt;br /&gt;
		if allCat then&lt;br /&gt;
			self:addCat(0, allCat)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:setTemplateCategories()&lt;br /&gt;
	local args = self.args&lt;br /&gt;
	local cfg = self.cfg&lt;br /&gt;
&lt;br /&gt;
	-- Add template categories.&lt;br /&gt;
	if cfg.templateCategory then&lt;br /&gt;
		if cfg.templateCategoryRequireName then&lt;br /&gt;
			if self.isTemplatePage then&lt;br /&gt;
				self:addCat(10, cfg.templateCategory)&lt;br /&gt;
			end&lt;br /&gt;
		elseif not self.title.isSubpage then&lt;br /&gt;
			self:addCat(10, cfg.templateCategory)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add template error categories.&lt;br /&gt;
	if cfg.templateErrorCategory then&lt;br /&gt;
		local templateErrorCategory = cfg.templateErrorCategory&lt;br /&gt;
		local templateCat, templateSort&lt;br /&gt;
		if not self.name and not self.title.isSubpage then&lt;br /&gt;
			templateCat = templateErrorCategory&lt;br /&gt;
		elseif self.isTemplatePage then&lt;br /&gt;
			local paramsToCheck = cfg.templateErrorParamsToCheck or {}&lt;br /&gt;
			local count = 0&lt;br /&gt;
			for i, param in ipairs(paramsToCheck) do&lt;br /&gt;
				if not args[param] then&lt;br /&gt;
					count = count + 1&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if count &amp;gt; 0 then&lt;br /&gt;
				templateCat = templateErrorCategory&lt;br /&gt;
				templateSort = tostring(count)&lt;br /&gt;
			end&lt;br /&gt;
			if self.categoryNums and #self.categoryNums &amp;gt; 0 then&lt;br /&gt;
				templateCat = templateErrorCategory&lt;br /&gt;
				templateSort = &#039;C&#039;&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		self:addCat(10, templateCat, templateSort)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:setAllNamespaceCategories()&lt;br /&gt;
	-- Set categories for all namespaces.&lt;br /&gt;
	if self.invalidTypeError then&lt;br /&gt;
		local allSort = (self.title.namespace == 0 and &#039;Main:&#039; or &#039;&#039;) .. self.title.prefixedText&lt;br /&gt;
		self:addCat(&#039;all&#039;, &#039;Wikipedia message box parameter needs fixing&#039;, allSort)&lt;br /&gt;
	end&lt;br /&gt;
	if self.isSubstituted then&lt;br /&gt;
		self:addCat(&#039;all&#039;, &#039;Pages with incorrectly substituted templates&#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:setCategories()&lt;br /&gt;
	if self.title.namespace == 0 then&lt;br /&gt;
		self:setMainspaceCategories()&lt;br /&gt;
	elseif self.title.namespace == 10 then&lt;br /&gt;
		self:setTemplateCategories()&lt;br /&gt;
	end&lt;br /&gt;
	self:setAllNamespaceCategories()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:renderCategories()&lt;br /&gt;
	if not self.hasCategories then&lt;br /&gt;
		-- No categories added, no need to pass them to Category handler so,&lt;br /&gt;
		-- if it was invoked, it would return the empty string.&lt;br /&gt;
		-- So we shortcut and return the empty string.&lt;br /&gt;
		return &amp;quot;&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	-- Convert category tables to strings and pass them through&lt;br /&gt;
	-- [[Module:Category handler]].&lt;br /&gt;
	return require(&#039;Module:Category handler&#039;)._main{&lt;br /&gt;
		main = table.concat(self.categories[0] or {}),&lt;br /&gt;
		template = table.concat(self.categories[10] or {}),&lt;br /&gt;
		all = table.concat(self.categories.all or {}),&lt;br /&gt;
		nocat = self.args.nocat,&lt;br /&gt;
		page = self.args.page&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function MessageBox:export()&lt;br /&gt;
	local root = mw.html.create()&lt;br /&gt;
&lt;br /&gt;
	-- Add the subst check error.&lt;br /&gt;
	if self.isSubstituted and self.name then&lt;br /&gt;
		root:tag(&#039;b&#039;)&lt;br /&gt;
			:addClass(&#039;error&#039;)&lt;br /&gt;
			:wikitext(string.format(&lt;br /&gt;
				&#039;Template &amp;lt;code&amp;gt;%s[[Template:%s|%s]]%s&amp;lt;/code&amp;gt; has been incorrectly substituted.&#039;,&lt;br /&gt;
				mw.text.nowiki(&#039;{{&#039;), self.name, self.name, mw.text.nowiki(&#039;}}&#039;)&lt;br /&gt;
			))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local frame = mw.getCurrentFrame()&lt;br /&gt;
	root:wikitext(frame:extensionTag{&lt;br /&gt;
		name = &#039;templatestyles&#039;,&lt;br /&gt;
		args = { src = self.base_templatestyles },&lt;br /&gt;
	})&lt;br /&gt;
	-- Add support for a single custom templatestyles sheet. Undocumented as&lt;br /&gt;
	-- need should be limited and many templates using mbox are substed; we&lt;br /&gt;
	-- don&#039;t want to spread templatestyles sheets around to arbitrary places&lt;br /&gt;
	if self.templatestyles then&lt;br /&gt;
		root:wikitext(frame:extensionTag{&lt;br /&gt;
			name = &#039;templatestyles&#039;,&lt;br /&gt;
			args = { src = self.templatestyles },&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Create the box table.&lt;br /&gt;
	local boxTable = root:tag(&#039;table&#039;)&lt;br /&gt;
	boxTable:attr(&#039;id&#039;, self.id or nil)&lt;br /&gt;
	for i, class in ipairs(self.classes or {}) do&lt;br /&gt;
		boxTable:addClass(class or nil)&lt;br /&gt;
	end&lt;br /&gt;
	boxTable&lt;br /&gt;
		:cssText(self.style or nil)&lt;br /&gt;
		:attr(&#039;role&#039;, &#039;presentation&#039;)&lt;br /&gt;
&lt;br /&gt;
	if self.attrs then&lt;br /&gt;
		boxTable:attr(self.attrs)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the left-hand image.&lt;br /&gt;
	local row = boxTable:tag(&#039;tr&#039;)&lt;br /&gt;
	if self.imageLeft then&lt;br /&gt;
		local imageLeftCell = row:tag(&#039;td&#039;):addClass(&#039;mbox-image&#039;)&lt;br /&gt;
		if self.imageCellDiv then&lt;br /&gt;
			-- If we are using a div, redefine imageLeftCell so that the image&lt;br /&gt;
			-- is inside it. Divs use style=&amp;quot;width: 52px;&amp;quot;, which limits the&lt;br /&gt;
			-- image width to 52px. If any images in a div are wider than that,&lt;br /&gt;
			-- they may overlap with the text or cause other display problems.&lt;br /&gt;
			imageLeftCell = imageLeftCell:tag(&#039;div&#039;):addClass(&#039;mbox-image-div&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		imageLeftCell:wikitext(self.imageLeft or nil)&lt;br /&gt;
	elseif self.imageEmptyCell then&lt;br /&gt;
		-- Some message boxes define an empty cell if no image is specified, and&lt;br /&gt;
		-- some don&#039;t. The old template code in templates where empty cells are&lt;br /&gt;
		-- specified gives the following hint: &amp;quot;No image. Cell with some width&lt;br /&gt;
		-- or padding necessary for text cell to have 100% width.&amp;quot;&lt;br /&gt;
		row:tag(&#039;td&#039;)&lt;br /&gt;
			:addClass(&#039;mbox-empty-cell&#039;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the text.&lt;br /&gt;
	local textCell = row:tag(&#039;td&#039;):addClass(&#039;mbox-text&#039;)&lt;br /&gt;
	if self.useCollapsibleTextFields then&lt;br /&gt;
		-- The message box uses advanced text parameters that allow things to be&lt;br /&gt;
		-- collapsible. At the moment, only ambox uses this.&lt;br /&gt;
		textCell:cssText(self.textstyle or nil)&lt;br /&gt;
		local textCellDiv = textCell:tag(&#039;div&#039;)&lt;br /&gt;
		textCellDiv&lt;br /&gt;
			:addClass(&#039;mbox-text-span&#039;)&lt;br /&gt;
			:wikitext(self.issue or nil)&lt;br /&gt;
		if (self.talk or self.fix) then&lt;br /&gt;
			textCellDiv:tag(&#039;span&#039;)&lt;br /&gt;
				:addClass(&#039;hide-when-compact&#039;)&lt;br /&gt;
				:wikitext(self.talk and (&#039; &#039; .. self.talk) or nil)&lt;br /&gt;
				:wikitext(self.fix and (&#039; &#039; .. self.fix) or nil)&lt;br /&gt;
		end&lt;br /&gt;
		textCellDiv:wikitext(self.date and (&#039; &#039; .. self.date) or nil)&lt;br /&gt;
		if self.info and not self.isSmall then&lt;br /&gt;
			textCellDiv&lt;br /&gt;
				:tag(&#039;span&#039;)&lt;br /&gt;
				:addClass(&#039;hide-when-compact&#039;)&lt;br /&gt;
				:wikitext(self.info and (&#039; &#039; .. self.info) or nil)&lt;br /&gt;
		end&lt;br /&gt;
		if self.removalNotice then&lt;br /&gt;
			textCellDiv:tag(&#039;span&#039;)&lt;br /&gt;
				:addClass(&#039;hide-when-compact&#039;)&lt;br /&gt;
				:tag(&#039;i&#039;)&lt;br /&gt;
					:wikitext(string.format(&amp;quot; (%s)&amp;quot;, self.removalNotice))&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- Default text formatting - anything goes.&lt;br /&gt;
		textCell&lt;br /&gt;
			:cssText(self.textstyle or nil)&lt;br /&gt;
			:wikitext(self.text or nil)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the right-hand image.&lt;br /&gt;
	if self.imageRight then&lt;br /&gt;
		local imageRightCell = row:tag(&#039;td&#039;):addClass(&#039;mbox-imageright&#039;)&lt;br /&gt;
		if self.imageCellDiv then&lt;br /&gt;
			-- If we are using a div, redefine imageRightCell so that the image&lt;br /&gt;
			-- is inside it.&lt;br /&gt;
			imageRightCell = imageRightCell:tag(&#039;div&#039;):addClass(&#039;mbox-image-div&#039;)&lt;br /&gt;
		end&lt;br /&gt;
		imageRightCell&lt;br /&gt;
			:wikitext(self.imageRight or nil)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add the below row.&lt;br /&gt;
	if self.below then&lt;br /&gt;
		boxTable:tag(&#039;tr&#039;)&lt;br /&gt;
			:tag(&#039;td&#039;)&lt;br /&gt;
				:attr(&#039;colspan&#039;, self.imageRight and &#039;3&#039; or &#039;2&#039;)&lt;br /&gt;
				:addClass(&#039;mbox-text&#039;)&lt;br /&gt;
				:cssText(self.textstyle or nil)&lt;br /&gt;
				:wikitext(self.below or nil)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add error message for invalid type parameters.&lt;br /&gt;
	if self.invalidTypeError then&lt;br /&gt;
		root:tag(&#039;div&#039;)&lt;br /&gt;
			:addClass(&#039;mbox-invalid-type&#039;)&lt;br /&gt;
			:wikitext(string.format(&lt;br /&gt;
				&#039;This message box is using an invalid &amp;quot;type=%s&amp;quot; parameter and needs fixing.&#039;,&lt;br /&gt;
				self.type or &#039;&#039;&lt;br /&gt;
			))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Add categories.&lt;br /&gt;
	root:wikitext(self:renderCategories() or nil)&lt;br /&gt;
&lt;br /&gt;
	return tostring(root)&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, mt = {}, {}&lt;br /&gt;
&lt;br /&gt;
function p._exportClasses()&lt;br /&gt;
	-- For testing.&lt;br /&gt;
	return {&lt;br /&gt;
		MessageBox = MessageBox&lt;br /&gt;
	}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(boxType, args, cfgTables)&lt;br /&gt;
	local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))&lt;br /&gt;
	box:setParameters()&lt;br /&gt;
	box:setCategories()&lt;br /&gt;
	return box:export()&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function mt.__index(t, k)&lt;br /&gt;
	return function (frame)&lt;br /&gt;
		if not getArgs then&lt;br /&gt;
			getArgs = require(&#039;Module:Arguments&#039;).getArgs&lt;br /&gt;
		end&lt;br /&gt;
		return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return setmetatable(p, mt)&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Template:Template_link&amp;diff=16</id>
		<title>Template:Template link</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Template:Template_link&amp;diff=16"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;amp;#123;&amp;amp;#123;[[Template:{{{1}}}|{{{1}}}]]&amp;amp;#125;&amp;amp;#125;&amp;lt;noinclude&amp;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>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Template:Tl&amp;diff=14</id>
		<title>Template:Tl</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Template:Tl&amp;diff=14"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&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>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Module:Arguments&amp;diff=12</id>
		<title>Module:Arguments</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Module:Arguments&amp;diff=12"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- This module provides easy processing of arguments passed to Scribunto from&lt;br /&gt;
-- #invoke. It is intended for use by other Lua modules, and should not be&lt;br /&gt;
-- called from #invoke directly.&lt;br /&gt;
&lt;br /&gt;
local libraryUtil = require(&#039;libraryUtil&#039;)&lt;br /&gt;
local checkType = libraryUtil.checkType&lt;br /&gt;
&lt;br /&gt;
local arguments = {}&lt;br /&gt;
&lt;br /&gt;
-- Generate four different tidyVal functions, so that we don&#039;t have to check the&lt;br /&gt;
-- options every time we call it.&lt;br /&gt;
&lt;br /&gt;
local function tidyValDefault(key, val)&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		val = val:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
		if val == &#039;&#039; then&lt;br /&gt;
			return nil&lt;br /&gt;
		else&lt;br /&gt;
			return val&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tidyValTrimOnly(key, val)&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		return val:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
	else&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tidyValRemoveBlanksOnly(key, val)&lt;br /&gt;
	if type(val) == &#039;string&#039; then&lt;br /&gt;
		if val:find(&#039;%S&#039;) then&lt;br /&gt;
			return val&lt;br /&gt;
		else&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		return val&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function tidyValNoChange(key, val)&lt;br /&gt;
	return val&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function matchesTitle(given, title)&lt;br /&gt;
	local tp = type( given )&lt;br /&gt;
	return (tp == &#039;string&#039; or tp == &#039;number&#039;) and mw.title.new( given ).prefixedText == title&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local translate_mt = { __index = function(t, k) return k end }&lt;br /&gt;
&lt;br /&gt;
function arguments.getArgs(frame, options)&lt;br /&gt;
	checkType(&#039;getArgs&#039;, 1, frame, &#039;table&#039;, true)&lt;br /&gt;
	checkType(&#039;getArgs&#039;, 2, options, &#039;table&#039;, true)&lt;br /&gt;
	frame = frame or {}&lt;br /&gt;
	options = options or {}&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Set up argument translation.&lt;br /&gt;
	--]]&lt;br /&gt;
	options.translate = options.translate or {}&lt;br /&gt;
	if getmetatable(options.translate) == nil then&lt;br /&gt;
		setmetatable(options.translate, translate_mt)&lt;br /&gt;
	end&lt;br /&gt;
	if options.backtranslate == nil then&lt;br /&gt;
		options.backtranslate = {}&lt;br /&gt;
		for k,v in pairs(options.translate) do&lt;br /&gt;
			options.backtranslate[v] = k&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if options.backtranslate and getmetatable(options.backtranslate) == nil then&lt;br /&gt;
		setmetatable(options.backtranslate, {&lt;br /&gt;
			__index = function(t, k)&lt;br /&gt;
				if options.translate[k] ~= k then&lt;br /&gt;
					return nil&lt;br /&gt;
				else&lt;br /&gt;
					return k&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Get the argument tables. If we were passed a valid frame object, get the&lt;br /&gt;
	-- frame arguments (fargs) and the parent frame arguments (pargs), depending&lt;br /&gt;
	-- on the options set and on the parent frame&#039;s availability. If we weren&#039;t&lt;br /&gt;
	-- passed a valid frame object, we are being called from another Lua module&lt;br /&gt;
	-- or from the debug console, so assume that we were passed a table of args&lt;br /&gt;
	-- directly, and assign it to a new variable (luaArgs).&lt;br /&gt;
	--]]&lt;br /&gt;
	local fargs, pargs, luaArgs&lt;br /&gt;
	if type(frame.args) == &#039;table&#039; and type(frame.getParent) == &#039;function&#039; then&lt;br /&gt;
		if options.wrappers then&lt;br /&gt;
			--[[&lt;br /&gt;
			-- The wrappers option makes Module:Arguments look up arguments in&lt;br /&gt;
			-- either the frame argument table or the parent argument table, but&lt;br /&gt;
			-- not both. This means that users can use either the #invoke syntax&lt;br /&gt;
			-- or a wrapper template without the loss of performance associated&lt;br /&gt;
			-- with looking arguments up in both the frame and the parent frame.&lt;br /&gt;
			-- Module:Arguments will look up arguments in the parent frame&lt;br /&gt;
			-- if it finds the parent frame&#039;s title in options.wrapper;&lt;br /&gt;
			-- otherwise it will look up arguments in the frame object passed&lt;br /&gt;
			-- to getArgs.&lt;br /&gt;
			--]]&lt;br /&gt;
			local parent = frame:getParent()&lt;br /&gt;
			if not parent then&lt;br /&gt;
				fargs = frame.args&lt;br /&gt;
			else&lt;br /&gt;
				local title = parent:getTitle():gsub(&#039;/sandbox$&#039;, &#039;&#039;)&lt;br /&gt;
				local found = false&lt;br /&gt;
				if matchesTitle(options.wrappers, title) then&lt;br /&gt;
					found = true&lt;br /&gt;
				elseif type(options.wrappers) == &#039;table&#039; then&lt;br /&gt;
					for _,v in pairs(options.wrappers) do&lt;br /&gt;
						if matchesTitle(v, title) then&lt;br /&gt;
							found = true&lt;br /&gt;
							break&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				-- We test for false specifically here so that nil (the default) acts like true.&lt;br /&gt;
				if found or options.frameOnly == false then&lt;br /&gt;
					pargs = parent.args&lt;br /&gt;
				end&lt;br /&gt;
				if not found or options.parentOnly == false then&lt;br /&gt;
					fargs = frame.args&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- options.wrapper isn&#039;t set, so check the other options.&lt;br /&gt;
			if not options.parentOnly then&lt;br /&gt;
				fargs = frame.args&lt;br /&gt;
			end&lt;br /&gt;
			if not options.frameOnly then&lt;br /&gt;
				local parent = frame:getParent()&lt;br /&gt;
				pargs = parent and parent.args or nil&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if options.parentFirst then&lt;br /&gt;
			fargs, pargs = pargs, fargs&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		luaArgs = frame&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Set the order of precedence of the argument tables. If the variables are&lt;br /&gt;
	-- nil, nothing will be added to the table, which is how we avoid clashes&lt;br /&gt;
	-- between the frame/parent args and the Lua args.&lt;br /&gt;
	local argTables = {fargs}&lt;br /&gt;
	argTables[#argTables + 1] = pargs&lt;br /&gt;
	argTables[#argTables + 1] = luaArgs&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Generate the tidyVal function. If it has been specified by the user, we&lt;br /&gt;
	-- use that; if not, we choose one of four functions depending on the&lt;br /&gt;
	-- options chosen. This is so that we don&#039;t have to call the options table&lt;br /&gt;
	-- every time the function is called.&lt;br /&gt;
	--]]&lt;br /&gt;
	local tidyVal = options.valueFunc&lt;br /&gt;
	if tidyVal then&lt;br /&gt;
		if type(tidyVal) ~= &#039;function&#039; then&lt;br /&gt;
			error(&lt;br /&gt;
				&amp;quot;bad value assigned to option &#039;valueFunc&#039;&amp;quot;&lt;br /&gt;
					.. &#039;(function expected, got &#039;&lt;br /&gt;
					.. type(tidyVal)&lt;br /&gt;
					.. &#039;)&#039;,&lt;br /&gt;
				2&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
	elseif options.trim ~= false then&lt;br /&gt;
		if options.removeBlanks ~= false then&lt;br /&gt;
			tidyVal = tidyValDefault&lt;br /&gt;
		else&lt;br /&gt;
			tidyVal = tidyValTrimOnly&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		if options.removeBlanks ~= false then&lt;br /&gt;
			tidyVal = tidyValRemoveBlanksOnly&lt;br /&gt;
		else&lt;br /&gt;
			tidyVal = tidyValNoChange&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Set up the args, metaArgs and nilArgs tables. args will be the one&lt;br /&gt;
	-- accessed from functions, and metaArgs will hold the actual arguments. Nil&lt;br /&gt;
	-- arguments are memoized in nilArgs, and the metatable connects all of them&lt;br /&gt;
	-- together.&lt;br /&gt;
	--]]&lt;br /&gt;
	local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}&lt;br /&gt;
	setmetatable(args, metatable)&lt;br /&gt;
&lt;br /&gt;
	local function mergeArgs(tables)&lt;br /&gt;
		--[[&lt;br /&gt;
		-- Accepts multiple tables as input and merges their keys and values&lt;br /&gt;
		-- into one table. If a value is already present it is not overwritten;&lt;br /&gt;
		-- tables listed earlier have precedence. We are also memoizing nil&lt;br /&gt;
		-- values, which can be overwritten if they are &#039;s&#039; (soft).&lt;br /&gt;
		--]]&lt;br /&gt;
		for _, t in ipairs(tables) do&lt;br /&gt;
			for key, val in pairs(t) do&lt;br /&gt;
				if metaArgs[key] == nil and nilArgs[key] ~= &#039;h&#039; then&lt;br /&gt;
					local tidiedVal = tidyVal(key, val)&lt;br /&gt;
					if tidiedVal == nil then&lt;br /&gt;
						nilArgs[key] = &#039;s&#039;&lt;br /&gt;
					else&lt;br /&gt;
						metaArgs[key] = tidiedVal&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[[&lt;br /&gt;
	-- Define metatable behaviour. Arguments are memoized in the metaArgs table,&lt;br /&gt;
	-- and are only fetched from the argument tables once. Fetching arguments&lt;br /&gt;
	-- from the argument tables is the most resource-intensive step in this&lt;br /&gt;
	-- module, so we try and avoid it where possible. For this reason, nil&lt;br /&gt;
	-- arguments are also memoized, in the nilArgs table. Also, we keep a record&lt;br /&gt;
	-- in the metatable of when pairs and ipairs have been called, so we do not&lt;br /&gt;
	-- run pairs and ipairs on the argument tables more than once. We also do&lt;br /&gt;
	-- not run ipairs on fargs and pargs if pairs has already been run, as all&lt;br /&gt;
	-- the arguments will already have been copied over.&lt;br /&gt;
	--]]&lt;br /&gt;
&lt;br /&gt;
	metatable.__index = function (t, key)&lt;br /&gt;
		--[[&lt;br /&gt;
		-- Fetches an argument when the args table is indexed. First we check&lt;br /&gt;
		-- to see if the value is memoized, and if not we try and fetch it from&lt;br /&gt;
		-- the argument tables. When we check memoization, we need to check&lt;br /&gt;
		-- metaArgs before nilArgs, as both can be non-nil at the same time.&lt;br /&gt;
		-- If the argument is not present in metaArgs, we also check whether&lt;br /&gt;
		-- pairs has been run yet. If pairs has already been run, we return nil.&lt;br /&gt;
		-- This is because all the arguments will have already been copied into&lt;br /&gt;
		-- metaArgs by the mergeArgs function, meaning that any other arguments&lt;br /&gt;
		-- must be nil.&lt;br /&gt;
		--]]&lt;br /&gt;
		if type(key) == &#039;string&#039; then&lt;br /&gt;
			key = options.translate[key]&lt;br /&gt;
		end&lt;br /&gt;
		local val = metaArgs[key]&lt;br /&gt;
		if val ~= nil then&lt;br /&gt;
			return val&lt;br /&gt;
		elseif metatable.donePairs or nilArgs[key] then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		for _, argTable in ipairs(argTables) do&lt;br /&gt;
			local argTableVal = tidyVal(key, argTable[key])&lt;br /&gt;
			if argTableVal ~= nil then&lt;br /&gt;
				metaArgs[key] = argTableVal&lt;br /&gt;
				return argTableVal&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		nilArgs[key] = &#039;h&#039;&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	metatable.__newindex = function (t, key, val)&lt;br /&gt;
		-- This function is called when a module tries to add a new value to the&lt;br /&gt;
		-- args table, or tries to change an existing value.&lt;br /&gt;
		if type(key) == &#039;string&#039; then&lt;br /&gt;
			key = options.translate[key]&lt;br /&gt;
		end&lt;br /&gt;
		if options.readOnly then&lt;br /&gt;
			error(&lt;br /&gt;
				&#039;could not write to argument table key &amp;quot;&#039;&lt;br /&gt;
					.. tostring(key)&lt;br /&gt;
					.. &#039;&amp;quot;; the table is read-only&#039;,&lt;br /&gt;
				2&lt;br /&gt;
			)&lt;br /&gt;
		elseif options.noOverwrite and args[key] ~= nil then&lt;br /&gt;
			error(&lt;br /&gt;
				&#039;could not write to argument table key &amp;quot;&#039;&lt;br /&gt;
					.. tostring(key)&lt;br /&gt;
					.. &#039;&amp;quot;; overwriting existing arguments is not permitted&#039;,&lt;br /&gt;
				2&lt;br /&gt;
			)&lt;br /&gt;
		elseif val == nil then&lt;br /&gt;
			--[[&lt;br /&gt;
			-- If the argument is to be overwritten with nil, we need to erase&lt;br /&gt;
			-- the value in metaArgs, so that __index, __pairs and __ipairs do&lt;br /&gt;
			-- not use a previous existing value, if present; and we also need&lt;br /&gt;
			-- to memoize the nil in nilArgs, so that the value isn&#039;t looked&lt;br /&gt;
			-- up in the argument tables if it is accessed again.&lt;br /&gt;
			--]]&lt;br /&gt;
			metaArgs[key] = nil&lt;br /&gt;
			nilArgs[key] = &#039;h&#039;&lt;br /&gt;
		else&lt;br /&gt;
			metaArgs[key] = val&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function translatenext(invariant)&lt;br /&gt;
		local k, v = next(invariant.t, invariant.k)&lt;br /&gt;
		invariant.k = k&lt;br /&gt;
		if k == nil then&lt;br /&gt;
			return nil&lt;br /&gt;
		elseif type(k) ~= &#039;string&#039; or not options.backtranslate then&lt;br /&gt;
			return k, v&lt;br /&gt;
		else&lt;br /&gt;
			local backtranslate = options.backtranslate[k]&lt;br /&gt;
			if backtranslate == nil then&lt;br /&gt;
				-- Skip this one. This is a tail call, so this won&#039;t cause stack overflow&lt;br /&gt;
				return translatenext(invariant)&lt;br /&gt;
			else&lt;br /&gt;
				return backtranslate, v&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	metatable.__pairs = function ()&lt;br /&gt;
		-- Called when pairs is run on the args table.&lt;br /&gt;
		if not metatable.donePairs then&lt;br /&gt;
			mergeArgs(argTables)&lt;br /&gt;
			metatable.donePairs = true&lt;br /&gt;
		end&lt;br /&gt;
		return translatenext, { t = metaArgs }&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local function inext(t, i)&lt;br /&gt;
		-- This uses our __index metamethod&lt;br /&gt;
		local v = t[i + 1]&lt;br /&gt;
		if v ~= nil then&lt;br /&gt;
			return i + 1, v&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	metatable.__ipairs = function (t)&lt;br /&gt;
		-- Called when ipairs is run on the args table.&lt;br /&gt;
		return inext, t, 0&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return args&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return arguments&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Module:Yesno&amp;diff=10</id>
		<title>Module:Yesno</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Module:Yesno&amp;diff=10"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Function allowing for consistent treatment of boolean-like wikitext input.&lt;br /&gt;
-- It works similarly to the template {{yesno}}.&lt;br /&gt;
&lt;br /&gt;
return function (val, default)&lt;br /&gt;
	-- If your wiki uses non-ascii characters for any of &amp;quot;yes&amp;quot;, &amp;quot;no&amp;quot;, etc., you&lt;br /&gt;
	-- should replace &amp;quot;val:lower()&amp;quot; with &amp;quot;mw.ustring.lower(val)&amp;quot; in the&lt;br /&gt;
	-- following line.&lt;br /&gt;
	val = type(val) == &#039;string&#039; and val:lower() or val&lt;br /&gt;
	if val == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	elseif val == true &lt;br /&gt;
		or val == &#039;yes&#039;&lt;br /&gt;
		or val == &#039;y&#039;&lt;br /&gt;
		or val == &#039;true&#039;&lt;br /&gt;
		or val == &#039;t&#039;&lt;br /&gt;
		or val == &#039;on&#039;&lt;br /&gt;
		or tonumber(val) == 1&lt;br /&gt;
	then&lt;br /&gt;
		return true&lt;br /&gt;
	elseif val == false&lt;br /&gt;
		or val == &#039;no&#039;&lt;br /&gt;
		or val == &#039;n&#039;&lt;br /&gt;
		or val == &#039;false&#039;&lt;br /&gt;
		or val == &#039;f&#039;&lt;br /&gt;
		or val == &#039;off&#039;&lt;br /&gt;
		or tonumber(val) == 0&lt;br /&gt;
	then&lt;br /&gt;
		return false&lt;br /&gt;
	else&lt;br /&gt;
		return default&lt;br /&gt;
	end&lt;br /&gt;
end&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Template:Nowrap&amp;diff=8</id>
		<title>Template:Nowrap</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Template:Nowrap&amp;diff=8"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&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>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Template:Routemap&amp;diff=6</id>
		<title>Template:Routemap</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Template:Routemap&amp;diff=6"/>
		<updated>2022-12-17T20:03:55Z</updated>

		<summary type="html">&lt;p&gt;Saml: 1 revision imported&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;&amp;lt;templatestyles src=&amp;quot;Routemap/styles.css&amp;quot;/&amp;gt;{{#invoke:Routemap|infobox}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Main_Page&amp;diff=3</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Main_Page&amp;diff=3"/>
		<updated>2019-08-10T04:02:13Z</updated>

		<summary type="html">&lt;p&gt;Saml: /* Interstate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome ==&lt;br /&gt;
I know that welcome is an old thing. I will be changing this, but this is to test changes to this page.&amp;lt;br&amp;gt;&lt;br /&gt;
=== About ===&lt;br /&gt;
This is a wiki for Travel information along highways.  Yes, you can use Google Maps, Waze or something, but when you just wand a glance of what is at the next exit, would it be ease just to look at a static page.  That is what this site will be for.  An easy to use guide that you don&#039;t have to search for &#039;fast food&#039; or &#039;gas&#039;.  This is based off of the old road guides that list what services are at each exit.  Only I want this to be and open and community driven. No need to wait for a new guide to be published, or a suggestion to be approved thew an app. Make the change and let everyone know of the change.&lt;br /&gt;
&lt;br /&gt;
Enough of my rambling. Start by selecting a State, Interstate, or Highway below.&lt;br /&gt;
&lt;br /&gt;
== States ==&lt;br /&gt;
Virginia&lt;br /&gt;
&lt;br /&gt;
== Interstates ==&lt;br /&gt;
&lt;br /&gt;
== US Highways ==&lt;br /&gt;
&amp;lt;small&amp;gt;State Highways will be listed under State&#039;s Page&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
This is hidden for the time until I have ahold of everything. &lt;br /&gt;
&amp;lt;strong&amp;gt;MediaWiki has been installed.&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents User&#039;s Guide] for information on using the wiki software.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
	<entry>
		<id>https://travis.lentzsystems.net/wiki/index.php?title=Main_Page&amp;diff=2</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://travis.lentzsystems.net/wiki/index.php?title=Main_Page&amp;diff=2"/>
		<updated>2019-08-10T04:01:38Z</updated>

		<summary type="html">&lt;p&gt;Saml: Initial Setup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Welcome ==&lt;br /&gt;
I know that welcome is an old thing. I will be changing this, but this is to test changes to this page.&amp;lt;br&amp;gt;&lt;br /&gt;
=== About ===&lt;br /&gt;
This is a wiki for Travel information along highways.  Yes, you can use Google Maps, Waze or something, but when you just wand a glance of what is at the next exit, would it be ease just to look at a static page.  That is what this site will be for.  An easy to use guide that you don&#039;t have to search for &#039;fast food&#039; or &#039;gas&#039;.  This is based off of the old road guides that list what services are at each exit.  Only I want this to be and open and community driven. No need to wait for a new guide to be published, or a suggestion to be approved thew an app. Make the change and let everyone know of the change.&lt;br /&gt;
&lt;br /&gt;
Enough of my rambling. Start by selecting a State, Interstate, or Highway below.&lt;br /&gt;
&lt;br /&gt;
== States ==&lt;br /&gt;
Virginia&lt;br /&gt;
&lt;br /&gt;
== Interstate ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== US Highways ==&lt;br /&gt;
&amp;lt;small&amp;gt;State Highways will be listed under State&#039;s Page&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
This is hidden for the time until I have ahold of everything. &lt;br /&gt;
&amp;lt;strong&amp;gt;MediaWiki has been installed.&amp;lt;/strong&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Consult the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents User&#039;s Guide] for information on using the wiki software.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Configuration settings list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki FAQ]&lt;br /&gt;
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localise MediaWiki for your language]&lt;br /&gt;
* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Learn how to combat spam on your wiki]&lt;br /&gt;
--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Saml</name></author>
	</entry>
</feed>