<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Acategory_tree%2Fposcatboiler</id>
	<title>Module:category tree/poscatboiler - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://linguifex.com/w/index.php?action=history&amp;feed=atom&amp;title=Module%3Acategory_tree%2Fposcatboiler"/>
	<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;action=history"/>
	<updated>2026-04-22T10:07:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=496670&amp;oldid=prev</id>
		<title>Sware at 14:55, 21 April 2026</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=496670&amp;oldid=prev"/>
		<updated>2026-04-21T14:55:02Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 14:55, 21 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l280&quot;&gt;Line 280:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 280:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			if &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;not self._data and &lt;/del&gt;not self._lang then&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;			if not self._lang then&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				-- Check family-specific labels for umbrella handler.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				-- Check family-specific labels for umbrella handler.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				local families_with_modules = require(family_specific_module)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;				local families_with_modules = require(family_specific_module)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=496513&amp;oldid=prev</id>
		<title>Sware at 13:53, 21 April 2026</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=496513&amp;oldid=prev"/>
		<updated>2026-04-21T13:53:54Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 13:53, 21 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l947&quot;&gt;Line 947:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 947:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		return nil&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;		return nil&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	local appendix = make_title(100, lang:getCanonicalName() .. &quot; &quot; .. label)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;--&lt;/ins&gt;local appendix = make_title(100, lang:getCanonicalName() .. &quot; &quot; .. label)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return appendix.exists and appendix.fullText or nil&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;	return &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;nil --&lt;/ins&gt;appendix.exists and appendix.fullText or nil&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;end&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=494646&amp;oldid=prev</id>
		<title>Sware: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=494646&amp;oldid=prev"/>
		<updated>2026-04-21T11:21:28Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 11:21, 21 April 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Sware</name></author>
	</entry>
	<entry>
		<id>https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=494645&amp;oldid=prev</id>
		<title>wikt&gt;Benwing2: allow etym langs as specified lang for categories like Category:Hazaragi reference templates</title>
		<link rel="alternate" type="text/html" href="https://linguifex.com/w/index.php?title=Module:category_tree/poscatboiler&amp;diff=494645&amp;oldid=prev"/>
		<updated>2026-02-16T05:03:55Z</updated>

		<summary type="html">&lt;p&gt;allow etym langs as specified lang for categories like &lt;a href=&quot;/w/index.php?title=Category:Hazaragi_reference_templates&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Category:Hazaragi reference templates (page does not exist)&quot;&gt;Category:Hazaragi reference templates&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local lang_independent_data = require(&amp;quot;Module:category tree/data&amp;quot;)&lt;br /&gt;
local lang_specific_module = &amp;quot;Module:category tree/lang&amp;quot;&lt;br /&gt;
local lang_specific_module_prefix = lang_specific_module .. &amp;quot;/&amp;quot;&lt;br /&gt;
local family_specific_module = &amp;quot;Module:category tree/fam&amp;quot;&lt;br /&gt;
local family_specific_module_prefix = family_specific_module .. &amp;quot;/&amp;quot;&lt;br /&gt;
local labels_utilities_module = &amp;quot;Module:labels/utilities&amp;quot;&lt;br /&gt;
local template_parser_module = &amp;quot;Module:template parser&amp;quot;&lt;br /&gt;
&lt;br /&gt;
local concat = table.concat&lt;br /&gt;
local dump = mw.dumpObject&lt;br /&gt;
local expand_template = require(&amp;quot;Module:frame&amp;quot;).expandTemplate&lt;br /&gt;
local insert = table.insert&lt;br /&gt;
local is_callable = require(&amp;quot;Module:fun&amp;quot;).is_callable&lt;br /&gt;
local lcfirst = require(&amp;quot;Module:string utilities&amp;quot;).lcfirst&lt;br /&gt;
local list_to_set = require(&amp;quot;Module:table&amp;quot;).listToSet&lt;br /&gt;
local make_title = mw.title.makeTitle&lt;br /&gt;
local new_title = mw.title.new&lt;br /&gt;
local parse = require(template_parser_module).parse&lt;br /&gt;
local sparse_concat = require(&amp;quot;Module:table&amp;quot;).sparseConcat&lt;br /&gt;
local tostring = tostring&lt;br /&gt;
local type = type&lt;br /&gt;
local ucfirst = require(&amp;quot;Module:string utilities&amp;quot;).ucfirst&lt;br /&gt;
local uupper = require(&amp;quot;Module:string utilities&amp;quot;).upper&lt;br /&gt;
&lt;br /&gt;
local function internal_error(msg)&lt;br /&gt;
	error(&amp;quot;Internal error: &amp;quot; .. msg)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function get_lang(...)&lt;br /&gt;
	local _get_lang = require(&amp;quot;Module:languages&amp;quot;).getByCode&lt;br /&gt;
	function get_lang(...)&lt;br /&gt;
		return _get_lang(...) or require(&amp;quot;Module:languages/errorGetBy&amp;quot;).code(...)&lt;br /&gt;
	end&lt;br /&gt;
	return get_lang(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function get_script(...)&lt;br /&gt;
	local _get_script = require(&amp;quot;Module:scripts&amp;quot;).getByCode&lt;br /&gt;
	function get_script(code)&lt;br /&gt;
		return _get_script(code) or require(&amp;quot;Module:languages/error&amp;quot;)(code, true, &amp;quot;script code&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	return get_script(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Category object&lt;br /&gt;
&lt;br /&gt;
local Category = {}&lt;br /&gt;
Category.__index = Category&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:get_originating_info()&lt;br /&gt;
	local originating_info = &amp;quot;&amp;quot;&lt;br /&gt;
	if self._info.originating_label then&lt;br /&gt;
		originating_info = &amp;quot; (originating from label \&amp;quot;&amp;quot; .. self._info.originating_label .. &amp;quot;\&amp;quot; in module [[&amp;quot; .. self._info.originating_module .. &amp;quot;]])&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return originating_info&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local valid_keys = list_to_set{&amp;quot;code&amp;quot;, &amp;quot;label&amp;quot;, &amp;quot;sc&amp;quot;, &amp;quot;raw&amp;quot;, &amp;quot;args&amp;quot;, &amp;quot;also&amp;quot;, &amp;quot;called_from_inside&amp;quot;, &amp;quot;originating_label&amp;quot;, &amp;quot;originating_module&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
function Category.new(info)&lt;br /&gt;
	for key in pairs(info) do&lt;br /&gt;
		if not valid_keys[key] then&lt;br /&gt;
			internal_error(&amp;quot;The parameter \&amp;quot;&amp;quot; .. key .. &amp;quot;\&amp;quot; was not recognized.&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local self = setmetatable({}, Category)&lt;br /&gt;
	self._info = info&lt;br /&gt;
&lt;br /&gt;
	if not self._info.label then&lt;br /&gt;
		internal_error(&amp;quot;No label was specified.&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	self:initCommon()&lt;br /&gt;
&lt;br /&gt;
	if not self._data then&lt;br /&gt;
		internal_error(&amp;quot;The &amp;quot; .. (self._info.raw and &amp;quot;raw &amp;quot; or &amp;quot;&amp;quot;) .. &amp;quot;label \&amp;quot;&amp;quot; .. self._info.label .. &amp;quot;\&amp;quot; does not exist&amp;quot; .. self:get_originating_info() .. &amp;quot;.&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return self&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:initCommon()&lt;br /&gt;
	local function patch_args(args)&lt;br /&gt;
		-- This fixes the issue with Scribunto automatically converting keys&lt;br /&gt;
		-- in a table as numbers to strings, which in turn causes a circular&lt;br /&gt;
		-- error for having argument parameter names as numbers as strings.&lt;br /&gt;
		&lt;br /&gt;
		if type(args) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
			return args&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local new_args = {}&lt;br /&gt;
		for k, v in pairs(args) do&lt;br /&gt;
			if type(k) == &amp;quot;string&amp;quot; and string.len(k) &amp;lt; 10 and not string.match(k, &amp;quot;^0&amp;quot;) and string.match(k, &amp;quot;^%d+$&amp;quot;) then&lt;br /&gt;
				new_args[tonumber(k)] = patch_args(v)&lt;br /&gt;
			else&lt;br /&gt;
				new_args[k] = patch_args(v)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return new_args&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
	local args_handled = false&lt;br /&gt;
	if self._info.raw then&lt;br /&gt;
		-- Check if the category exists&lt;br /&gt;
		local raw_categories = lang_independent_data[&amp;quot;RAW_CATEGORIES&amp;quot;]&lt;br /&gt;
		self._data = raw_categories[self._info.label]&lt;br /&gt;
&lt;br /&gt;
		if self._data then&lt;br /&gt;
			if self._data.lang then&lt;br /&gt;
				self._lang = get_lang(self._data.lang, nil, true)&lt;br /&gt;
				self._info.code = self._lang:getCode()&lt;br /&gt;
			end&lt;br /&gt;
			if self._data.sc then&lt;br /&gt;
				self._sc = get_script(self._data.sc)&lt;br /&gt;
				self._info.sc = self._sc:getCode()&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			-- Go through raw handlers&lt;br /&gt;
			local data = {&lt;br /&gt;
				category = self._info.label,&lt;br /&gt;
				args = patch_args(self._info.args) or {},&lt;br /&gt;
				called_from_inside = self._info.called_from_inside,&lt;br /&gt;
			}&lt;br /&gt;
			for _, handler in ipairs(lang_independent_data[&amp;quot;RAW_HANDLERS&amp;quot;]) do&lt;br /&gt;
				self._data, args_handled = handler.handler(data)&lt;br /&gt;
				if self._data then&lt;br /&gt;
					self._data.module = self._data.module or handler.module&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if self._data then&lt;br /&gt;
				-- Update the label if the handler specified a canonical name for it.&lt;br /&gt;
				if self._data.canonical_name then&lt;br /&gt;
					self._info.canonical_name = self._data.canonical_name&lt;br /&gt;
				end&lt;br /&gt;
				if self._data.lang then&lt;br /&gt;
					if type(self._data.lang) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
						internal_error(&amp;quot;Received non-string value &amp;quot; .. dump(self._data.lang) .. &amp;quot; for self._data.lang, label \&amp;quot;&amp;quot; .. self._info.label .. &amp;quot;\&amp;quot;&amp;quot; .. self:get_originating_info() .. &amp;quot;.&amp;quot;)&lt;br /&gt;
					end&lt;br /&gt;
					self._lang = get_lang(self._data.lang, nil, true)&lt;br /&gt;
					self._info.code = self._lang:getCode()&lt;br /&gt;
				end&lt;br /&gt;
				if self._data.sc then&lt;br /&gt;
					if type(self._data.sc) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
						internal_error(&amp;quot;Received non-string value &amp;quot; .. dump(self._data.sc) .. &amp;quot; for self._data.sc, label \&amp;quot;&amp;quot; .. self._info.label .. &amp;quot;\&amp;quot;&amp;quot; .. self:get_originating_info() .. &amp;quot;.&amp;quot;)&lt;br /&gt;
					end&lt;br /&gt;
					self._sc = get_script(self._data.sc)&lt;br /&gt;
					self._info.sc = self._sc:getCode()&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		-- Already parsed into language + label&lt;br /&gt;
		if self._info.code then&lt;br /&gt;
			self._lang = get_lang(self._info.code, nil, true)&lt;br /&gt;
		else&lt;br /&gt;
			self._lang = nil&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if self._info.sc then&lt;br /&gt;
			self._sc = get_script(self._info.sc)&lt;br /&gt;
		else&lt;br /&gt;
			self._sc = nil&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		self._info.orig_label = self._info.label&lt;br /&gt;
		if not self._lang then&lt;br /&gt;
			-- Umbrella categories without a preceding language always begin with a capital letter, but the actual label may be&lt;br /&gt;
			-- lowercase (cf. [[:Category:Nouns by language]] with label &amp;#039;nouns&amp;#039; with per-language [[:Category:English nouns]];&lt;br /&gt;
			-- but [[:Category:Reddit slang by language]] with label &amp;#039;Reddit slang&amp;#039; with per-language&lt;br /&gt;
			-- [[:Category:English Reddit slang]]). Since the label is almost always lowercase, we lowercase it for umbrella&lt;br /&gt;
			-- categories, storing the original into `orig_label`, and correct it later if needed.&lt;br /&gt;
			self._info.label = lcfirst(self._info.label)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- First, check lang-specific labels and handlers if this is not an umbrella category.&lt;br /&gt;
		if self._lang then&lt;br /&gt;
			local objects_with_modules = require(lang_specific_module)&lt;br /&gt;
			local obj, seen = self._lang, {}&lt;br /&gt;
			local object_specific_module_prefix = lang_specific_module_prefix&lt;br /&gt;
			local is_family = false&lt;br /&gt;
			repeat&lt;br /&gt;
				if objects_with_modules[obj:getCode()] then&lt;br /&gt;
					local module = object_specific_module_prefix .. obj:getCode()&lt;br /&gt;
					local labels_and_handlers = require(module)&lt;br /&gt;
					if labels_and_handlers.LABELS then&lt;br /&gt;
						self._data = labels_and_handlers.LABELS[self._info.label]&lt;br /&gt;
						if self._data then&lt;br /&gt;
							if not is_family and self._data.umbrella == nil and self._data.umbrella_parents == nil then&lt;br /&gt;
								self._data.umbrella = false&lt;br /&gt;
							end&lt;br /&gt;
							self._data.module = self._data.module or module&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					if not self._data and labels_and_handlers.HANDLERS then&lt;br /&gt;
						for _, handler in ipairs(labels_and_handlers.HANDLERS) do&lt;br /&gt;
							local data = {&lt;br /&gt;
								label = self._info.label,&lt;br /&gt;
								lang = self._lang,&lt;br /&gt;
								sc = self._sc,&lt;br /&gt;
								args = patch_args(self._info.args) or {},&lt;br /&gt;
								called_from_inside = self._info.called_from_inside,&lt;br /&gt;
							}&lt;br /&gt;
							self._data, args_handled = handler(data)&lt;br /&gt;
							if self._data then&lt;br /&gt;
								if not is_family and self._data.umbrella == nil and&lt;br /&gt;
									self._data.umbrella_parents == nil then&lt;br /&gt;
									self._data.umbrella = false&lt;br /&gt;
								end&lt;br /&gt;
								self._data.module = self._data.module or module&lt;br /&gt;
								break&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					if self._data then&lt;br /&gt;
						break&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
				seen[obj:getCode()] = true&lt;br /&gt;
				obj = obj:getFamily()&lt;br /&gt;
				if not is_family then&lt;br /&gt;
					is_family = true&lt;br /&gt;
					object_specific_module_prefix = family_specific_module_prefix&lt;br /&gt;
					objects_with_modules = require(family_specific_module)&lt;br /&gt;
				end&lt;br /&gt;
			until not obj or seen[obj:getCode()]&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local function fetch_label_data(labels)&lt;br /&gt;
			self._data = labels[self._info.label]&lt;br /&gt;
			-- See comment above about uppercase- vs. lowercase-initial labels, which are indistinguishable&lt;br /&gt;
			-- in umbrella categories.&lt;br /&gt;
			if not self._data then&lt;br /&gt;
				self._data = labels[self._info.orig_label]&lt;br /&gt;
				if self._data then&lt;br /&gt;
					self._info.label = self._info.orig_label&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		-- Then check lang-independent labels.&lt;br /&gt;
		if not self._data then&lt;br /&gt;
			-- lang_independent_data.LABELS should always exist.&lt;br /&gt;
			fetch_label_data(lang_independent_data.LABELS)&lt;br /&gt;
			if not self._data and not self._lang then&lt;br /&gt;
				-- Check family-specific labels for umbrella label.&lt;br /&gt;
				local families_with_modules = require(family_specific_module)&lt;br /&gt;
				for famcode, _ in pairs(families_with_modules) do&lt;br /&gt;
					local module = family_specific_module_prefix .. famcode&lt;br /&gt;
					local labels_and_handlers = require(module)&lt;br /&gt;
					if labels_and_handlers.LABELS then&lt;br /&gt;
						fetch_label_data(labels_and_handlers.LABELS)&lt;br /&gt;
						if self._data then&lt;br /&gt;
							self._data.module = self._data.module or module&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;
&lt;br /&gt;
		-- Then check lang-independent handlers.&lt;br /&gt;
		if not self._data then&lt;br /&gt;
			local data = {&lt;br /&gt;
				label = self._info.label,&lt;br /&gt;
				lang = self._lang,&lt;br /&gt;
				sc = self._sc,&lt;br /&gt;
				args = patch_args(self._info.args) or {},&lt;br /&gt;
				called_from_inside = self._info.called_from_inside,&lt;br /&gt;
			}&lt;br /&gt;
			for _, handler in ipairs(lang_independent_data[&amp;quot;HANDLERS&amp;quot;]) do&lt;br /&gt;
				self._data, args_handled = handler.handler(data)&lt;br /&gt;
				if self._data then&lt;br /&gt;
					self._data.module = self._data.module or handler.module&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if not self._data and not self._lang then&lt;br /&gt;
				-- Check family-specific labels for umbrella handler.&lt;br /&gt;
				local families_with_modules = require(family_specific_module)&lt;br /&gt;
				for famcode, _ in pairs(families_with_modules) do&lt;br /&gt;
					local module = family_specific_module_prefix .. famcode&lt;br /&gt;
					local labels_and_handlers = require(module)&lt;br /&gt;
					if labels_and_handlers.HANDLERS then&lt;br /&gt;
						for _, handler in ipairs(labels_and_handlers.HANDLERS) do&lt;br /&gt;
							local data = {&lt;br /&gt;
								label = self._info.label,&lt;br /&gt;
								sc = self._sc,&lt;br /&gt;
								args = patch_args(self._info.args) or {},&lt;br /&gt;
								called_from_inside = self._info.called_from_inside,&lt;br /&gt;
							}&lt;br /&gt;
							self._data, args_handled = handler(data)&lt;br /&gt;
							if self._data then&lt;br /&gt;
								self._data.module = self._data.module or module&lt;br /&gt;
								break&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
					if self._data then&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;
&lt;br /&gt;
	if not args_handled and self._data and self._info.args and next(self._info.args) then&lt;br /&gt;
		local module_text = &amp;quot; (handled in [[&amp;quot; .. (self._data.module or &amp;quot;UNKNOWN&amp;quot;).. &amp;quot;]])&amp;quot;&lt;br /&gt;
		local args_text = {}&lt;br /&gt;
		for k, v in pairs(self._info.args) do&lt;br /&gt;
			insert(args_text, k .. &amp;quot;=&amp;quot; .. ((type(v) == &amp;quot;string&amp;quot; or type(v) == &amp;quot;number&amp;quot;) and v or dump(v)))&lt;br /&gt;
		end&lt;br /&gt;
		error(&amp;quot;poscatboiler label &amp;#039;&amp;quot; .. self._info.label .. &amp;quot;&amp;#039; &amp;quot; .. module_text .. &amp;quot; doesn&amp;#039;t accept extra args &amp;quot; ..&lt;br /&gt;
			concat(args_text, &amp;quot;, &amp;quot;))&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if self._sc and not self._lang then&lt;br /&gt;
		internal_error(&amp;quot;Umbrella categories cannot have a script specified.&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:convert_spec_to_string(desc)&lt;br /&gt;
	if not desc then&lt;br /&gt;
		return desc&lt;br /&gt;
	end&lt;br /&gt;
	local desc_type = type(desc)&lt;br /&gt;
	if desc_type == &amp;quot;string&amp;quot; then&lt;br /&gt;
		return desc&lt;br /&gt;
	elseif desc_type == &amp;quot;number&amp;quot; then&lt;br /&gt;
		return tostring(desc)&lt;br /&gt;
	elseif not is_callable(desc) then&lt;br /&gt;
		internal_error(&amp;quot;`desc` must be a string, number, function, callable table or nil; received &amp;quot; .. dump(desc))&lt;br /&gt;
	end&lt;br /&gt;
	desc = desc {&lt;br /&gt;
		lang = self._lang,&lt;br /&gt;
		sc = self._sc,&lt;br /&gt;
		label = self._info.label,&lt;br /&gt;
		raw = self._info.raw,&lt;br /&gt;
	}&lt;br /&gt;
	if not desc then&lt;br /&gt;
		return desc&lt;br /&gt;
	end&lt;br /&gt;
	desc_type = type(desc)&lt;br /&gt;
	if desc_type == &amp;quot;string&amp;quot; then&lt;br /&gt;
		return desc&lt;br /&gt;
	end&lt;br /&gt;
	internal_error(&amp;quot;The value returned by `desc` must be a string or nil; received &amp;quot; .. dump(desc))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function add_obj_args(args, obj, obj_type)&lt;br /&gt;
	if obj then&lt;br /&gt;
		args[obj_type .. &amp;quot;code&amp;quot;] = obj:getCode()&lt;br /&gt;
		args[obj_type .. &amp;quot;name&amp;quot;] = obj:getCanonicalName()&lt;br /&gt;
		args[obj_type .. &amp;quot;disp&amp;quot;] = obj:getDisplayForm()&lt;br /&gt;
		args[obj_type .. &amp;quot;cat&amp;quot;] = obj:getCategoryName()&lt;br /&gt;
		args[obj_type .. &amp;quot;link&amp;quot;] = obj:makeCategoryLink()&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Expands `desc` like a template, passing values for specs like {{{langname}}}.&lt;br /&gt;
function Category:substitute_template_specs(desc)&lt;br /&gt;
	-- This may end up happening twice but that&amp;#039;s OK as the function is (usually) idempotent.&lt;br /&gt;
		-- FIXME: Not idempotent if a preprocessed template returns wikicode.&lt;br /&gt;
	desc = self:convert_spec_to_string(desc)&lt;br /&gt;
	if not desc then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Populate the substitution arguments.&lt;br /&gt;
	local args = {}&lt;br /&gt;
&lt;br /&gt;
	args.umbrella_msg = &amp;quot;This is an umbrella category. It contains no dictionary entries, but only other, language-specific categories, which in turn contain relevant terms in a given language.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	args.umbrella_meta_msg = &amp;quot;This is an umbrella metacategory, covering a general area such as \&amp;quot;lemmas\&amp;quot;, \&amp;quot;names\&amp;quot; or \&amp;quot;terms by etymology\&amp;quot;. It contains no dictionary entries, but holds only umbrella (\&amp;quot;by language\&amp;quot;) categories covering specific subtopics, which in turn contain language-specific categories holding terms in a given language for that same topic.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	add_obj_args(args, self._lang, &amp;quot;lang&amp;quot;)&lt;br /&gt;
	add_obj_args(args, self._sc, &amp;quot;sc&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	return parse(desc, true):expand(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Category:substitute_template_specs_in_args(args)&lt;br /&gt;
	if not args then&lt;br /&gt;
		return args&lt;br /&gt;
	end&lt;br /&gt;
	local pinfo = {}&lt;br /&gt;
	for k, v in pairs(args) do&lt;br /&gt;
		pinfo[self:substitute_template_specs(k)] = self:substitute_template_specs(v)&lt;br /&gt;
	end&lt;br /&gt;
	return pinfo&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:make_new(info)&lt;br /&gt;
	info.originating_label = self._info.label&lt;br /&gt;
	info.originating_module = self._data.module&lt;br /&gt;
	info.called_from_inside = true&lt;br /&gt;
	return Category.new(info)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getBreadcrumbName()&lt;br /&gt;
	local ret&lt;br /&gt;
&lt;br /&gt;
	if self._lang or self._info.raw then&lt;br /&gt;
		ret = self._data.breadcrumb or self._data.breadcrumb_and_first_sort_key or&lt;br /&gt;
			self._data.breadcrumb_and_first_sort_base or nil&lt;br /&gt;
	else&lt;br /&gt;
		ret = self._data.umbrella and (self._data.umbrella.breadcrumb or&lt;br /&gt;
			self._data.umbrella.breadcrumb_and_first_sort_key or self._data.umbrella.breadcrumb_and_first_sort_base) or&lt;br /&gt;
			nil&lt;br /&gt;
	end&lt;br /&gt;
	if not ret then&lt;br /&gt;
		ret = self._info.label&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if type(ret) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		ret = {name = ret}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local name = self:substitute_template_specs(ret.name)&lt;br /&gt;
	local nocap = ret.nocap&lt;br /&gt;
&lt;br /&gt;
	if self._sc then&lt;br /&gt;
		name = name .. &amp;quot; in &amp;quot; .. self._sc:getDisplayForm()&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return name, nocap&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function expand_toc_template_if(template)&lt;br /&gt;
	local template_obj = new_title(template, 10)&lt;br /&gt;
	if template_obj.exists then&lt;br /&gt;
		return expand_template{title = template_obj.text}&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Return the textual expansion of the first existing template among the given templates, first performing&lt;br /&gt;
-- substitutions on the template name such as replacing {{{langcode}}} with the current language&amp;#039;s code (if any).&lt;br /&gt;
-- If no templates exist after expansion, or if nil is passed in, return nil. If a single string is passed in,&lt;br /&gt;
-- treat it like a one-element list consisting of that string.&lt;br /&gt;
function Category:get_template_text(templates)&lt;br /&gt;
	if templates == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	elseif type(templates) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
		templates = {templates}&lt;br /&gt;
	end&lt;br /&gt;
	for _, template in ipairs(templates) do&lt;br /&gt;
		if template == false then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
		template = self:substitute_template_specs(template)&lt;br /&gt;
		return expand_toc_template_if(template)&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getTOC(toc_type)&lt;br /&gt;
	-- Type &amp;quot;none&amp;quot; means everything fits on a single page; in that case, display nothing.&lt;br /&gt;
	if toc_type == &amp;quot;none&amp;quot; then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local templates, fallback_templates&lt;br /&gt;
&lt;br /&gt;
	-- If TOC type is &amp;quot;full&amp;quot; (more than 2500 entries), do the following, in order:&lt;br /&gt;
	-- 1. look up and expand the `toc_template_full` templates (normal or umbrella, depending on whether there is&lt;br /&gt;
	--    a current language);&lt;br /&gt;
	-- 2. look up and expand the `toc_template` templates (normal or umbrella, as above);&lt;br /&gt;
	-- 3. do the default behavior, which is as follows:&lt;br /&gt;
	-- 3a. look up a language-specific &amp;quot;full&amp;quot; template according to the current language (using English if there&lt;br /&gt;
	--     is no current language);&lt;br /&gt;
	-- 3b. look up a script-specific &amp;quot;full&amp;quot; template according to the first script of current language (using English&lt;br /&gt;
	--     if there is no current language);&lt;br /&gt;
	-- 3c. look up a language-specific &amp;quot;normal&amp;quot; template according to the current language (using English if there&lt;br /&gt;
	--     is no current language);&lt;br /&gt;
	-- 3d. look up a script-specific &amp;quot;normal&amp;quot; template according to the first script of the current language (using&lt;br /&gt;
	--     English if there is no current language);&lt;br /&gt;
	-- 3e. display nothing.&lt;br /&gt;
	--&lt;br /&gt;
	-- If TOC type is &amp;quot;normal&amp;quot; (between 200 and 2500 entries), do the following, in order:&lt;br /&gt;
	-- 1. look up and expand the `toc_template` templates (normal or umbrella, depending on whether there is&lt;br /&gt;
	--    a current language);&lt;br /&gt;
	-- 2. do the default behavior, which is as follows:&lt;br /&gt;
	-- 2a. look up a language-specific &amp;quot;normal&amp;quot; template according to the current language (using English if there&lt;br /&gt;
	--     is no current language);&lt;br /&gt;
	-- 2b. look up a script-specific &amp;quot;normal&amp;quot; template according to the first script of the current language (using&lt;br /&gt;
	--     English if there is no current language);&lt;br /&gt;
	-- 2c. display nothing.&lt;br /&gt;
&lt;br /&gt;
	local data_source&lt;br /&gt;
	if self._lang or self._info.raw then&lt;br /&gt;
		data_source = self._data&lt;br /&gt;
	else&lt;br /&gt;
		data_source = self._data.umbrella&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if data_source then&lt;br /&gt;
		if toc_type == &amp;quot;full&amp;quot; then&lt;br /&gt;
			templates = data_source.toc_template_full&lt;br /&gt;
			fallback_templates = data_source.toc_template&lt;br /&gt;
		else&lt;br /&gt;
			templates = data_source.toc_template&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local text = self:get_template_text(templates)&lt;br /&gt;
	if text then&lt;br /&gt;
		return text&lt;br /&gt;
	elseif text == false then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	text = self:get_template_text(fallback_templates)&lt;br /&gt;
	if text then&lt;br /&gt;
		return text&lt;br /&gt;
	elseif text == false then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local default_toc_templates_to_check = {}&lt;br /&gt;
&lt;br /&gt;
	local lang, sc = self:getCatfixInfo()&lt;br /&gt;
	local langcode = lang and lang:getCode() or &amp;quot;en&amp;quot;&lt;br /&gt;
	local sccode = sc and sc:getCode() or lang and lang:getScriptCodes()[1] or &amp;quot;Latn&amp;quot;&lt;br /&gt;
	-- FIXME: What is toctemplateprefix used for?&lt;br /&gt;
	local tocname = (self._data.toctemplateprefix or &amp;quot;&amp;quot;) .. &amp;quot;categoryTOC&amp;quot;&lt;br /&gt;
	if toc_type == &amp;quot;full&amp;quot; then&lt;br /&gt;
		insert(default_toc_templates_to_check, (&amp;quot;%s-%s/full&amp;quot;):format(langcode, tocname))&lt;br /&gt;
		insert(default_toc_templates_to_check, (&amp;quot;%s-%s/full&amp;quot;):format(sccode, tocname))&lt;br /&gt;
	end&lt;br /&gt;
	insert(default_toc_templates_to_check, (&amp;quot;%s-%s&amp;quot;):format(langcode, tocname))&lt;br /&gt;
	insert(default_toc_templates_to_check, (&amp;quot;%s-%s&amp;quot;):format(sccode, tocname))&lt;br /&gt;
&lt;br /&gt;
	for _, toc_template in ipairs(default_toc_templates_to_check) do&lt;br /&gt;
		local toc_template_text = expand_toc_template_if(toc_template)&lt;br /&gt;
		if toc_template_text then&lt;br /&gt;
			return toc_template_text&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getInfo()&lt;br /&gt;
	return self._info&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getDataModule()&lt;br /&gt;
	return self._data.module&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:canBeEmpty()&lt;br /&gt;
	if self._lang or self._info.raw then&lt;br /&gt;
		return self._data.can_be_empty&lt;br /&gt;
	end&lt;br /&gt;
	return self._data.umbrella and self._data.umbrella.can_be_empty&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:isHidden()&lt;br /&gt;
	if self._lang or self._info.raw then&lt;br /&gt;
		return self._data.hidden&lt;br /&gt;
	end&lt;br /&gt;
	return self._data.umbrella and self._data.umbrella.hidden&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getCategoryName()&lt;br /&gt;
	if self._info.raw then&lt;br /&gt;
		return self._info.canonical_name or self._info.label&lt;br /&gt;
	elseif self._lang then&lt;br /&gt;
		local ret = self._lang:getCanonicalName() .. &amp;quot; &amp;quot; .. self._info.label&lt;br /&gt;
		if self._sc then&lt;br /&gt;
			ret = ret .. &amp;quot; in &amp;quot; .. self._sc:getDisplayForm()&lt;br /&gt;
		end&lt;br /&gt;
		return ucfirst(ret)&lt;br /&gt;
	end&lt;br /&gt;
	local ret = ucfirst(self._info.label)&lt;br /&gt;
	if not (self._data.no_by_language or self._data.umbrella and self._data.umbrella.no_by_language) then&lt;br /&gt;
		ret = ret .. &amp;quot; by language&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getTopright()&lt;br /&gt;
	if self._lang or self._info.raw then&lt;br /&gt;
		return self:substitute_template_specs(self._data.topright)&lt;br /&gt;
	end&lt;br /&gt;
	return self._data.umbrella and self:substitute_template_specs(self._data.umbrella.topright)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:display_title(displaytitle, lang)&lt;br /&gt;
	if type(displaytitle) == &amp;quot;string&amp;quot; then&lt;br /&gt;
		displaytitle = self:substitute_template_specs(displaytitle)&lt;br /&gt;
	else&lt;br /&gt;
		displaytitle = displaytitle(self:getCategoryName(), lang)&lt;br /&gt;
	end&lt;br /&gt;
	mw.getCurrentFrame():callParserFunction(&amp;quot;DISPLAYTITLE&amp;quot;, &amp;quot;Category:&amp;quot; .. displaytitle)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:get_labels_categorizing()&lt;br /&gt;
	local m_labels_utilities = require(labels_utilities_module)&lt;br /&gt;
	local pos_cat_labels, sense_cat_labels, use_tlb&lt;br /&gt;
	pos_cat_labels = m_labels_utilities.find_labels_for_category(self._info.label, &amp;quot;pos&amp;quot;, self._lang)&lt;br /&gt;
	local sense_label = self._info.label:match(&amp;quot;^(.*) terms$&amp;quot;)&lt;br /&gt;
	if sense_label then&lt;br /&gt;
		use_tlb = true&lt;br /&gt;
	else&lt;br /&gt;
		sense_label = self._info.label:match(&amp;quot;^terms with (.*) senses$&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	if not sense_label then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	sense_cat_labels = m_labels_utilities.find_labels_for_category(sense_label, &amp;quot;sense&amp;quot;, self._lang)&lt;br /&gt;
	if use_tlb then&lt;br /&gt;
		return m_labels_utilities.format_labels_categorizing(pos_cat_labels, sense_cat_labels, self._lang)&lt;br /&gt;
	end&lt;br /&gt;
	local all_labels = pos_cat_labels&lt;br /&gt;
	for k, v in pairs(sense_cat_labels) do&lt;br /&gt;
		all_labels[k] = v&lt;br /&gt;
	end&lt;br /&gt;
	return m_labels_utilities.format_labels_categorizing(all_labels, nil, self._lang)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- FIXME: this is clunky.&lt;br /&gt;
local function remove_lang_params(desc)&lt;br /&gt;
	-- Simply remove a language name/code/category from the beginning of the string, but replace the language name&lt;br /&gt;
	-- in the middle of the string with either &amp;quot;specific languages&amp;quot; or &amp;quot;specific-language&amp;quot; depending on whether the&lt;br /&gt;
	-- language name appears to be an attributive qualifier of another noun or to stand by itself. This may be wrong,&lt;br /&gt;
	-- in which case the category in question should supply its own umbrella description.&lt;br /&gt;
	desc = desc:gsub(&amp;quot;^{{{langname}}} &amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
		:gsub(&amp;quot;{{{langname}}} %(&amp;quot;, &amp;quot;specific languages (&amp;quot;)&lt;br /&gt;
		:gsub(&amp;quot;{{{langname}}}([.,])&amp;quot;, &amp;quot;specific languages%1&amp;quot;)&lt;br /&gt;
		:gsub(&amp;quot;{{{langname}}} &amp;quot;, &amp;quot;specific-language &amp;quot;)&lt;br /&gt;
		:gsub(&amp;quot;{{{langdisp}}}&amp;quot;, &amp;quot;specific languages&amp;quot;)&lt;br /&gt;
		:gsub(&amp;quot;{{{langlink}}}&amp;quot;, &amp;quot;specific languages&amp;quot;)&lt;br /&gt;
	return desc&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getDescription(isChild)&lt;br /&gt;
	-- Allows different text in the list of a category&amp;#039;s children&lt;br /&gt;
	local isChild = isChild == &amp;quot;child&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if self._lang or self._info.raw then&lt;br /&gt;
		if not isChild and self._data.displaytitle then&lt;br /&gt;
			self:display_title(self._data.displaytitle, self._lang)&lt;br /&gt;
		end&lt;br /&gt;
		if self._sc then&lt;br /&gt;
			return self:getCategoryName() .. &amp;quot;.&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		local desc = self:substitute_template_specs(self._data.description)&lt;br /&gt;
		if not desc then&lt;br /&gt;
			return nil&lt;br /&gt;
		elseif isChild then&lt;br /&gt;
			return desc&lt;br /&gt;
		end&lt;br /&gt;
		return sparse_concat({&lt;br /&gt;
			self:substitute_template_specs(self._data.preceding),&lt;br /&gt;
			desc,&lt;br /&gt;
			self:substitute_template_specs(self._data.additional),&lt;br /&gt;
			self:substitute_template_specs(self:get_labels_categorizing()),&lt;br /&gt;
		}, &amp;quot;\n\n&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local umbrella = self._data.umbrella&lt;br /&gt;
	if not isChild and umbrella and umbrella.displaytitle then&lt;br /&gt;
		self:display_title(umbrella.displaytitle)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local desc = self:substitute_template_specs(umbrella and umbrella.description)&lt;br /&gt;
	local has_umbrella_desc = not not desc&lt;br /&gt;
	if not desc then&lt;br /&gt;
		desc = self:convert_spec_to_string(self._data.description)&lt;br /&gt;
		if desc then&lt;br /&gt;
			desc = remove_lang_params(desc)&lt;br /&gt;
			desc = lcfirst(desc)&lt;br /&gt;
			desc = desc:gsub(&amp;quot;%.$&amp;quot;, &amp;quot;&amp;quot;)&lt;br /&gt;
			desc = &amp;quot;Categories with &amp;quot; .. desc .. &amp;quot;.&amp;quot;&lt;br /&gt;
		else&lt;br /&gt;
			desc = &amp;quot;Categories with &amp;quot; .. self._info.label .. &amp;quot; in various specific languages.&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
		desc = self:substitute_template_specs(desc)&lt;br /&gt;
	end&lt;br /&gt;
	if isChild then&lt;br /&gt;
		return desc&lt;br /&gt;
	end&lt;br /&gt;
	return sparse_concat({&lt;br /&gt;
		self:substitute_template_specs(umbrella and umbrella.preceding or not has_umbrella_desc and self._data.preceding),&lt;br /&gt;
		desc,&lt;br /&gt;
		self:substitute_template_specs(umbrella and umbrella.additional or not has_umbrella_desc and self._data.additional),&lt;br /&gt;
		self:substitute_template_specs(&amp;quot;{{{umbrella_msg}}}&amp;quot;),&lt;br /&gt;
		self:substitute_template_specs(self:get_labels_categorizing()),&lt;br /&gt;
	}, &amp;quot;\n\n&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Category:new_sortkey(sortkey)&lt;br /&gt;
	local sortkey_type = type(sortkey)&lt;br /&gt;
	if sortkey_type == &amp;quot;string&amp;quot; then&lt;br /&gt;
		sortkey = uupper(sortkey)&lt;br /&gt;
	elseif sortkey_type == &amp;quot;table&amp;quot; then&lt;br /&gt;
		function sortkey:makeSortKey()&lt;br /&gt;
			local sort_func = self.sort_func&lt;br /&gt;
			if sort_func ~= nil then&lt;br /&gt;
				return sort_func(self.sort_base)&lt;br /&gt;
			end&lt;br /&gt;
			local lang = self.lang&lt;br /&gt;
			if lang == nil then&lt;br /&gt;
				return self.sort_base&lt;br /&gt;
			end&lt;br /&gt;
			lang = get_lang(lang, nil, true)&lt;br /&gt;
			if lang == nil then&lt;br /&gt;
				return self.sort_base&lt;br /&gt;
			end&lt;br /&gt;
			local sc = self.sc&lt;br /&gt;
			if sc ~= nil then&lt;br /&gt;
				sc = get_script(sc)&lt;br /&gt;
			end&lt;br /&gt;
			return lang:makeSortKey(self.sort_base, sc)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return sortkey&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Category:inherit_spec(spec, parent_spec, substitute_result)&lt;br /&gt;
	if spec == false then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local retval = spec or parent_spec&lt;br /&gt;
	if substitute_result then&lt;br /&gt;
		retval = self:substitute_template_specs(retval)&lt;br /&gt;
	end&lt;br /&gt;
	return retval&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function Category:canonicalize_parents_children(cats, is_children, fallback_sort_key, fallback_sort_base)&lt;br /&gt;
	if not cats then&lt;br /&gt;
		return nil&lt;br /&gt;
	elseif type(cats) == &amp;quot;table&amp;quot; then&lt;br /&gt;
		if cats.name or cats.module then&lt;br /&gt;
			cats = {cats}&lt;br /&gt;
		elseif #cats == 0 then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		cats = {cats}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ret = {}&lt;br /&gt;
&lt;br /&gt;
	for _, cat in ipairs(cats) do&lt;br /&gt;
		if type(cat) ~= &amp;quot;table&amp;quot; or not cat.name and not cat.module then&lt;br /&gt;
			cat = {name = cat}&lt;br /&gt;
		end&lt;br /&gt;
		insert(ret, cat)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local is_umbrella = not self._lang and not self._info.raw&lt;br /&gt;
	local table_type = is_children and &amp;quot;extra_children&amp;quot; or &amp;quot;parents&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	for i, cat in ipairs(ret) do&lt;br /&gt;
		local raw&lt;br /&gt;
		if self._info.raw or is_umbrella then&lt;br /&gt;
			raw = not cat.is_label&lt;br /&gt;
		else&lt;br /&gt;
			raw = cat.raw&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local lang = self:inherit_spec(cat.lang, not raw and self._info.code or nil, &amp;quot;substitute&amp;quot;)&lt;br /&gt;
		local sc = self:inherit_spec(cat.sc, not raw and self._info.sc or nil, &amp;quot;substitute&amp;quot;)&lt;br /&gt;
		&lt;br /&gt;
		-- Get the sortkey.&lt;br /&gt;
		local sortkey = self:inherit_spec(cat.sort, i == 1 and (fallback_sort_key or fallback_sort_base and {sort_base = fallback_sort_base}) or nil)&lt;br /&gt;
		if type(sortkey) == &amp;quot;table&amp;quot; then&lt;br /&gt;
			sortkey.sort_base = self:substitute_template_specs(sortkey.sort_base) or&lt;br /&gt;
				internal_error(&amp;quot;Missing .sort_base in &amp;#039;&amp;quot; .. table_type .. &amp;quot;&amp;#039; .sort table for &amp;#039;&amp;quot; ..&lt;br /&gt;
					self._info.label .. &amp;quot;&amp;#039; category entry in module &amp;#039;&amp;quot; .. (self._data.module or &amp;quot;unknown&amp;quot;) .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
			if sortkey.sort_func then&lt;br /&gt;
				-- Not allowed to give a lang and/or script if sort_func is given.&lt;br /&gt;
				local bad_spec = sortkey.lang and &amp;quot;lang&amp;quot; or sortkey.sc and &amp;quot;sc&amp;quot; or nil&lt;br /&gt;
				if bad_spec then&lt;br /&gt;
					internal_error(&amp;quot;Cannot specify both .&amp;quot; .. bad_spec .. &amp;quot; and .sort_func in &amp;#039;&amp;quot; .. table_type ..&lt;br /&gt;
						&amp;quot;&amp;#039; .sort table for &amp;#039;&amp;quot; .. self._info.label .. &amp;quot;&amp;#039; category entry in module &amp;#039;&amp;quot; ..&lt;br /&gt;
						(self._data.module or &amp;quot;unknown&amp;quot;) .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				sortkey.lang = self:inherit_spec(sortkey.lang, lang, &amp;quot;substitute&amp;quot;)&lt;br /&gt;
				sortkey.sc = self:inherit_spec(sortkey.sc, sc, &amp;quot;substitute&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			sortkey = self:substitute_template_specs(sortkey)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		local name&lt;br /&gt;
		if cat.module then&lt;br /&gt;
			-- A reference to a category using another category tree module.&lt;br /&gt;
			if not cat.args then&lt;br /&gt;
				internal_error(&amp;quot;Missing .args in &amp;#039;&amp;quot; .. table_type .. &amp;quot;&amp;#039; table with module=\&amp;quot;&amp;quot; .. cat.module .. &amp;quot;\&amp;quot; for &amp;#039;&amp;quot; ..&lt;br /&gt;
					self._info.label .. &amp;quot;&amp;#039; category entry in module &amp;#039;&amp;quot; .. (self._data.module or &amp;quot;unknown&amp;quot;) .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
			end&lt;br /&gt;
			name = require(&amp;quot;Module:category tree/&amp;quot; .. cat.module).new(self:substitute_template_specs_in_args(cat.args))&lt;br /&gt;
		else&lt;br /&gt;
			name = cat.name&lt;br /&gt;
			if not name then&lt;br /&gt;
				internal_error(&amp;quot;Missing .name in &amp;quot; .. (is_umbrella and &amp;quot;umbrella &amp;quot; or &amp;quot;&amp;quot;) .. &amp;quot;&amp;#039;&amp;quot; .. table_type .. &amp;quot;&amp;#039; table for &amp;#039;&amp;quot; ..&lt;br /&gt;
					self._info.label .. &amp;quot;&amp;#039; category entry in module &amp;#039;&amp;quot; .. (self._data.module or &amp;quot;unknown&amp;quot;) .. &amp;quot;&amp;#039;&amp;quot;)&lt;br /&gt;
			elseif type(name) == &amp;quot;string&amp;quot; then -- otherwise, assume it&amp;#039;s a category object and use it directly&lt;br /&gt;
				name = self:substitute_template_specs(name)&lt;br /&gt;
				if name:find(&amp;quot;^Category:&amp;quot;) then&lt;br /&gt;
					-- It&amp;#039;s a non-poscatboiler category name.&lt;br /&gt;
					sortkey = sortkey or is_children and name:gsub(&amp;quot;^Category:&amp;quot;, &amp;quot;&amp;quot;) or self:getCategoryName()&lt;br /&gt;
				else&lt;br /&gt;
					-- It&amp;#039;s a label.&lt;br /&gt;
					sortkey = sortkey or is_children and name or self._info.label&lt;br /&gt;
					name = self:make_new{&lt;br /&gt;
						label = name, code = lang, sc = sc,&lt;br /&gt;
						raw = raw, args = self:substitute_template_specs_in_args(cat.args)&lt;br /&gt;
					}&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		sortkey = sortkey or is_children and &amp;quot; &amp;quot; or self._info.label&lt;br /&gt;
		&lt;br /&gt;
		ret[i] = {&lt;br /&gt;
			name = name,&lt;br /&gt;
			description = is_children and self:substitute_template_specs(cat.description) or nil,&lt;br /&gt;
			sort = self:new_sortkey(sortkey)&lt;br /&gt;
		}&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getParents()&lt;br /&gt;
	local is_umbrella, ret = not self._lang and not self._info.raw&lt;br /&gt;
	if self._sc then&lt;br /&gt;
		local parent1 = self:make_new{code = self._info.code, label = &amp;quot;terms in &amp;quot; .. self._sc:getCanonicalName() .. &amp;quot; script&amp;quot;}&lt;br /&gt;
		local parent2 = self:make_new{code = self._info.code, label = self._info.label, raw = self._info.raw, args = self._info.args}&lt;br /&gt;
&lt;br /&gt;
		ret = {&lt;br /&gt;
			{name = parent1, sort = self._sc:getCanonicalName()},&lt;br /&gt;
			{name = parent2, sort = self._sc:getCanonicalName()},&lt;br /&gt;
		}&lt;br /&gt;
	else&lt;br /&gt;
		local parents, fallback_sort_key, fallback_sort_base&lt;br /&gt;
		if is_umbrella then&lt;br /&gt;
			parents = self._data.umbrella and self._data.umbrella.parents or self._data.umbrella_parents&lt;br /&gt;
			fallback_sort_key = self._data.umbrella and self._data.umbrella.breadcrumb_and_first_sort_key or nil&lt;br /&gt;
			fallback_sort_base = self._data.umbrella and self._data.umbrella.breadcrumb_and_first_sort_base or nil&lt;br /&gt;
		else&lt;br /&gt;
			parents = self._data.parents&lt;br /&gt;
			fallback_sort_key = self._data.breadcrumb_and_first_sort_key&lt;br /&gt;
			fallback_sort_base = self._data.breadcrumb_and_first_sort_base&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		ret = self:canonicalize_parents_children(parents, nil, fallback_sort_key, fallback_sort_base)&lt;br /&gt;
		if not ret then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local self_cat = self:getCategoryName()&lt;br /&gt;
	for _, parent in ipairs(ret) do&lt;br /&gt;
		local parent_cat = parent.name.getCategoryName and parent.name:getCategoryName()&lt;br /&gt;
		if self_cat == parent_cat then&lt;br /&gt;
			internal_error((&amp;quot;Infinite loop would occur, as parent category &amp;#039;%s&amp;#039; is the same as the child category&amp;quot;):format(self_cat))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getChildren()&lt;br /&gt;
	local is_umbrella = not self._lang and not self._info.raw&lt;br /&gt;
	local children = self._data.children&lt;br /&gt;
&lt;br /&gt;
	local ret = {}&lt;br /&gt;
&lt;br /&gt;
	if not is_umbrella and children then&lt;br /&gt;
		for _, child in ipairs(children) do&lt;br /&gt;
			child = mw.clone(child)&lt;br /&gt;
&lt;br /&gt;
			if type(child) ~= &amp;quot;table&amp;quot; then&lt;br /&gt;
				child = {name = child}&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if not child.sort then&lt;br /&gt;
				child.sort = child.name&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			-- FIXME, is preserving the script correct?&lt;br /&gt;
			child.name = self:make_new{code = self._info.code, label = child.name, raw = child.raw, sc = self._info.sc}&lt;br /&gt;
&lt;br /&gt;
			insert(ret, child)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local extra_children&lt;br /&gt;
	if is_umbrella then&lt;br /&gt;
		extra_children = self._data.umbrella and self._data.umbrella.extra_children&lt;br /&gt;
	else&lt;br /&gt;
		extra_children = self._data.extra_children&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	extra_children = self:canonicalize_parents_children(extra_children, &amp;quot;children&amp;quot;)&lt;br /&gt;
	if extra_children then&lt;br /&gt;
		for _, child in ipairs(extra_children) do&lt;br /&gt;
			insert(ret, child)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return #ret &amp;gt; 0 and ret or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getUmbrella()&lt;br /&gt;
	local umbrella = self._data.umbrella&lt;br /&gt;
	if umbrella == false or self._info.raw or not self._lang or self._sc then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	-- If `umbrella` is a string, use that; otherwise, use the label.&lt;br /&gt;
	return self:make_new({label = type(umbrella) == &amp;quot;string&amp;quot; and umbrella or self._info.label})&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getAppendix()&lt;br /&gt;
	-- FIXME, this should be customizable.&lt;br /&gt;
	local lang, label = self._lang, self._info.label&lt;br /&gt;
	if self._info.raw or not (lang and label) then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	local appendix = make_title(100, lang:getCanonicalName() .. &amp;quot; &amp;quot; .. label)&lt;br /&gt;
	return appendix.exists and appendix.fullText or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getCatfixInfo()&lt;br /&gt;
	if self._lang or self._sc or self._info.raw then&lt;br /&gt;
		local langcode, sccode = self._data.catfix, self._data.catfix_sc&lt;br /&gt;
		local lang, sc&lt;br /&gt;
		if langcode then&lt;br /&gt;
			langcode = self:substitute_template_specs(langcode)&lt;br /&gt;
			lang = get_lang(langcode, nil, true)&lt;br /&gt;
		elseif langcode == nil then -- not false&lt;br /&gt;
			lang = self._lang&lt;br /&gt;
		end&lt;br /&gt;
		if sccode then&lt;br /&gt;
			sccode = self:substitute_template_specs(sccode)&lt;br /&gt;
			sc = get_script(sccode)&lt;br /&gt;
		elseif sccode == nil then -- not false&lt;br /&gt;
			sc = self._sc&lt;br /&gt;
		end&lt;br /&gt;
		if lang then&lt;br /&gt;
			lang = lang:getFull()&lt;br /&gt;
		end&lt;br /&gt;
		return lang, sc&lt;br /&gt;
	elseif not self._data.umbrella then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	-- umbrella&lt;br /&gt;
	local langcode, sccode = self._data.umbrella.catfix, self._data.umbrella.catfix_sc&lt;br /&gt;
	local lang, sc&lt;br /&gt;
	if langcode then&lt;br /&gt;
		langcode = self:substitute_template_specs(langcode)&lt;br /&gt;
		lang = get_lang(langcode, nil, true)&lt;br /&gt;
	end&lt;br /&gt;
	if sccode then&lt;br /&gt;
		sccode = self:substitute_template_specs(sccode)&lt;br /&gt;
		sc = get_script(sccode)&lt;br /&gt;
	end&lt;br /&gt;
	if lang then&lt;br /&gt;
		lang = lang:getFull()&lt;br /&gt;
	end&lt;br /&gt;
	return lang, sc&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Category:getTOCTemplateName()&lt;br /&gt;
	-- This should only be invoked if getTOC() returns true, meaning to do the default algorithm, but getTOC()&lt;br /&gt;
	-- implements its own default algorithm.&lt;br /&gt;
	internal_error(&amp;quot;This should never get called&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local export = {}&lt;br /&gt;
&lt;br /&gt;
function export.main(info)&lt;br /&gt;
	local self = setmetatable({_info = info}, Category)&lt;br /&gt;
	&lt;br /&gt;
	self:initCommon()&lt;br /&gt;
	&lt;br /&gt;
	return self._data and self or nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
export.new = Category.new&lt;br /&gt;
&lt;br /&gt;
return export&lt;/div&gt;</summary>
		<author><name>wikt&gt;Benwing2</name></author>
	</entry>
</feed>