<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://www.digitalcellulose.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ACountries</id>
	<title>Module:Countries - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://www.digitalcellulose.com/wiki/index.php?action=history&amp;feed=atom&amp;title=Module%3ACountries"/>
	<link rel="alternate" type="text/html" href="http://www.digitalcellulose.com/wiki/index.php?title=Module:Countries&amp;action=history"/>
	<updated>2026-05-13T18:00:37Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>http://www.digitalcellulose.com/wiki/index.php?title=Module:Countries&amp;diff=152297&amp;oldid=prev</id>
		<title>Adminsuzy: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="http://www.digitalcellulose.com/wiki/index.php?title=Module:Countries&amp;diff=152297&amp;oldid=prev"/>
		<updated>2020-09-13T20:46:23Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&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: #222; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;Revision as of 20:46, 13 September 2020&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>Adminsuzy</name></author>
		
	</entry>
	<entry>
		<id>http://www.digitalcellulose.com/wiki/index.php?title=Module:Countries&amp;diff=152296&amp;oldid=prev</id>
		<title>Imported&gt;Verdy p at 07:06, 21 July 2020</title>
		<link rel="alternate" type="text/html" href="http://www.digitalcellulose.com/wiki/index.php?title=Module:Countries&amp;diff=152296&amp;oldid=prev"/>
		<updated>2020-07-21T07:06:37Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- This module implements templates that output a countries navbox.&lt;br /&gt;
-- First usage was at [[Template:Countries of Europe]].&lt;br /&gt;
&lt;br /&gt;
local _langSwitch -- cache for loading the Fallback module lazily&lt;br /&gt;
-- used by getList():getCodes() and _main()&lt;br /&gt;
local function langSwitch(translations, lang)&lt;br /&gt;
	if translations[lang] then&lt;br /&gt;
		return translations[lang]&lt;br /&gt;
	end&lt;br /&gt;
	-- Note: the sandbox version handles BCP 47 rules more strictly for fallbacks.&lt;br /&gt;
	-- In addition it is a bit faster, uses less temporary memory than the&lt;br /&gt;
	-- current non-sandbox version of Module:Fallback&lt;br /&gt;
	_langSwitch = _langSwitch or require('Module:Fallback/sandbox')._langSwitch&lt;br /&gt;
	return _langSwitch(translations, lang) or ''&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- used by getList():getTitle() and getGroupData()&lt;br /&gt;
-- If text is a non-empty string (not just containing spaces), return its trimmed content.&lt;br /&gt;
-- Otherwise, return nil (text is an empty string or is not a string).&lt;br /&gt;
local function stripToNil(text)&lt;br /&gt;
	if type(text) == 'string' then&lt;br /&gt;
		text = text:match('^%s*(.-)%s*$')&lt;br /&gt;
		if text ~= '' then -- not nil and not empty&lt;br /&gt;
			return text:gsub('%s+', ' ') -- compress and normalize internal spaces&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- used by getList()&lt;br /&gt;
local _makeSortKey -- cache for loading the MakeSortKey module lazily&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
Detect soft redirect in wiki page content of 'Category:' pages using template&lt;br /&gt;
	{{Category redirect|target}}&lt;br /&gt;
or one of its known aliases on Commons. Loaded lazily from 'Module:Redirect'.&lt;br /&gt;
]]&lt;br /&gt;
local function getTargetFromCatRedirect(...)&lt;br /&gt;
	getTargetFromCatRedirect = require('Module:Redirect').getTargetFromCatRedirect&lt;br /&gt;
	return getTargetFromCatRedirect(...)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- used by _main()&lt;br /&gt;
local function getList(lists, exclude, options, infos)&lt;br /&gt;
	-- Return:&lt;br /&gt;
	-- * title of redirect target (prefixed by ':' if it's a category), if specified page is a redirect and target exists;&lt;br /&gt;
	-- * false if specified page is not a suitable target, try next page if any;&lt;br /&gt;
	-- * nil if specified page should be used as the target&lt;br /&gt;
	local function getRedirectTarget(titleObj)&lt;br /&gt;
		if titleObj.isRedirect then&lt;br /&gt;
			local target = titleObj.redirectTarget.prefixedText -- false if target does not exist&lt;br /&gt;
			return type(target) == 'string' and target:match('^%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:') and (':' .. target) or&lt;br /&gt;
				target&lt;br /&gt;
		end&lt;br /&gt;
		local content = titleObj:getContent()&lt;br /&gt;
		if content then&lt;br /&gt;
			local target = getTargetFromCatRedirect(content)&lt;br /&gt;
			if target then&lt;br /&gt;
				return ':' .. target&lt;br /&gt;
			end&lt;br /&gt;
			if content:match('{{%s*[Dd]isambig%s*}}') or content:match('{{%s*[Dd]ab%s*}}') then&lt;br /&gt;
				return false&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	-- Avoid overhead of checking target for a country with no alternative name.&lt;br /&gt;
	-- LATER It appears the extra overhead may be low; perhaps remove this?&lt;br /&gt;
	local function getNilTarget(titleObj)&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local info -- table used by getTitle() and makeItem() and set as info = codes[code]&lt;br /&gt;
	local function getTitle(tryThe) -- uses (info, options) from getList()&lt;br /&gt;
		-- Return the title of a link to an existing page (if not 'all'), or nil if none.&lt;br /&gt;
		local pfx = (stripToNil(options.prefix) or '') .. options.presep&lt;br /&gt;
		-- Enforce a single leading ':' for links to special namespaces (namespace names are not case-significant)&lt;br /&gt;
		local ns, name = pfx:match('^:*%s-(%w+)%s*:%s*(.-)$')&lt;br /&gt;
		if ns then&lt;br /&gt;
			-- TODO: should we recognize interwiki prefixes here (e.g. &amp;quot;fr:&amp;quot; or &amp;quot;de:&amp;quot; which are also special namespaces)&lt;br /&gt;
			-- to enforce an inline link to the other wiki, instead of generating an interwiki on the side bar ?&lt;br /&gt;
			-- This is for not needed on international wikis like Commons, but may be needed on Wikipedia.&lt;br /&gt;
			for _, special in ipairs({'Category', 'File', 'Special'}) do&lt;br /&gt;
				if special:lower() == ns:lower() then&lt;br /&gt;
					pfx = ':' .. special .. ':' .. name&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local sfx = stripToNil(options.suffix) or ''&lt;br /&gt;
		-- replace final parts found in (option.suffix), according to the optional (subst) table&lt;br /&gt;
		-- defined in the (info) taken from the entry defined for the country code in (lists)&lt;br /&gt;
		sfx = options.sufsep .. (type(info.subst) == 'table' and sfx:gsub('%S.+$', info.subst) or sfx)&lt;br /&gt;
		local getTarget = #info &amp;gt; 1 and getRedirectTarget or getNilTarget&lt;br /&gt;
		for i, name in ipairs(info) do&lt;br /&gt;
			if tryThe then&lt;br /&gt;
				if i &amp;gt; 1 then&lt;br /&gt;
					return nil&lt;br /&gt;
				end&lt;br /&gt;
				name = 'the ' .. name&lt;br /&gt;
			end&lt;br /&gt;
			-- compress whitespaces in excess possibly introduced by (option.presep, option.sufsep)&lt;br /&gt;
			-- in (pfx) or (sfx), or left after applying (info.subst) to the (option.suffix)&lt;br /&gt;
			local title = stripToNil(pfx .. name .. sfx) or ''&lt;br /&gt;
			if options.all then&lt;br /&gt;
				return title&lt;br /&gt;
			end&lt;br /&gt;
			local titleObj = mw.title.new(title)&lt;br /&gt;
			if titleObj and titleObj.exists then&lt;br /&gt;
				local t = getTarget(titleObj)&lt;br /&gt;
				if t ~= false then&lt;br /&gt;
					return t or title&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local itemPattern = '[[{title}|&amp;lt;bdi&amp;gt;{label}&amp;lt;/bdi&amp;gt;]]{post}{bullet}'&lt;br /&gt;
	local head, trail = '&amp;lt;span style=&amp;quot;white-space:nowrap&amp;quot;&amp;gt;', '&amp;lt;/span&amp;gt;'&lt;br /&gt;
	-- these bullets are used by makeItem(), but also after processing all items&lt;br /&gt;
	-- to remove the last bullet==stdBullet&lt;br /&gt;
	local altBullet, stdBullet = ' ≈', &amp;quot; '''·'''&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	-- trail is used here, but also after processing all items&lt;br /&gt;
	-- to remove the last bullet==stdBullet&lt;br /&gt;
	itemPattern = head .. itemPattern .. trail -- string used by makeItem()&lt;br /&gt;
&lt;br /&gt;
	local post -- string used by makeItem() and set according to info&lt;br /&gt;
	local function makeItem(tryThe) -- uses (info, options, itemPattern, suffix) from getList()&lt;br /&gt;
		local pretitle = ''&lt;br /&gt;
		local itemLabel&lt;br /&gt;
		local bullet = stdBullet&lt;br /&gt;
		local second = ''&lt;br /&gt;
		if tryThe then&lt;br /&gt;
			-- LATER This assumes 'the' applies to the first name, and only the first.&lt;br /&gt;
			if not info.the then&lt;br /&gt;
				return nil&lt;br /&gt;
			end&lt;br /&gt;
			if options.all then&lt;br /&gt;
				pretitle = 'the '&lt;br /&gt;
				itemLabel, second = makeItem()&lt;br /&gt;
				bullet = altBullet&lt;br /&gt;
				second = ' ' .. second&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		local title = getTitle(tryThe)&lt;br /&gt;
		if not title then&lt;br /&gt;
			return nil&lt;br /&gt;
		end&lt;br /&gt;
		itemLabel =&lt;br /&gt;
			not options.all and mw.wikibase.getLabelByLang(info.qid, options.lang) or&lt;br /&gt;
			(pretitle .. info[1])&lt;br /&gt;
		return itemLabel,&lt;br /&gt;
			(itemPattern:gsub('{(%a+)}', {&lt;br /&gt;
				title = title,&lt;br /&gt;
				label = itemLabel,&lt;br /&gt;
				post = post,&lt;br /&gt;
				bullet = bullet,&lt;br /&gt;
				})&lt;br /&gt;
			) .. second&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	--[=[ Language selection.&lt;br /&gt;
	The following works with a list that defines results for various languages.&lt;br /&gt;
	It also handles the special entries illustrated in the following.&lt;br /&gt;
	If the provided list does not contain an entry for the provided lang,&lt;br /&gt;
	langSwitch() will look for fallbacks defined in that list: assume 'LX' and&lt;br /&gt;
	'LY' are language codes that are not defined in the list, and 'LX' falls back&lt;br /&gt;
	to 'en', while 'LY' falls back to 'default'. Currently, the latter cannot&lt;br /&gt;
	occur, but it conceivably could.&lt;br /&gt;
		list = {&lt;br /&gt;
			automatic = 'AB CD EF GH',      -- country codes&lt;br /&gt;
			english = 'automatic',          -- uselang=en → 'AB CD EF GH' without sort&lt;br /&gt;
			default = 'automatic sorted',   -- uselang=LY → 'AB CD EF GH' after sorting&lt;br /&gt;
			en = 'automatic sorted',        -- uselang=LX → 'AB CD EF GH' after sorting&lt;br /&gt;
		},&lt;br /&gt;
	We'll use codes = the space-separated codes which are the most appropriate order for lang.&lt;br /&gt;
	We'll use getSortKey = nil or a function to make a sort key, if the entry was 'automatic sorted'.&lt;br /&gt;
	The two entries 'automatic' and 'english' override what langSwitch alone would return.&lt;br /&gt;
	But a specific language may be set to use.&lt;br /&gt;
	As an optimization, lang=='en' uses the 'english' entry setting, if defined:&lt;br /&gt;
	when english=='automatic', the result is the automatic setting, which may or may not&lt;br /&gt;
	use the overhead of sorting.&lt;br /&gt;
	Sorting applies to country names obtained from Wikidata in the user's language.&lt;br /&gt;
	The sorting is crude (language neutral) and will often be unhelpful for specific languages.&lt;br /&gt;
	It is based on sort keys computed in Module:MakeSortKey.&lt;br /&gt;
	]=]&lt;br /&gt;
	local codes&lt;br /&gt;
	if lang == 'en' and lists.english then&lt;br /&gt;
		codes = lists.english&lt;br /&gt;
	else&lt;br /&gt;
		codes = langSwitch(lists, options.lang)&lt;br /&gt;
	end&lt;br /&gt;
	local getSortKey&lt;br /&gt;
	if codes == 'automatic' or codes == 'automatic sorted' then&lt;br /&gt;
		if codes == 'automatic sorted' then&lt;br /&gt;
			if not _makeSortKey then&lt;br /&gt;
				_makeSortKey = require('Module:MakeSortKey').makeSortKey&lt;br /&gt;
			end&lt;br /&gt;
			getSortKey = _makeSortKey&lt;br /&gt;
		end&lt;br /&gt;
		codes = lists.automatic or error('Codes list uses &amp;quot;' .. codes .. '&amp;quot; but &amp;quot;automatic&amp;quot; is not defined')&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Split the space-separated list of codes, find and process their info to build the unsorted items to display.&lt;br /&gt;
	-- Items will be actually sorted, if wanted, once they are complete.&lt;br /&gt;
	local items, wantSort = {}, getSortKey and not options.all&lt;br /&gt;
	for code in codes:gmatch('%S+') do&lt;br /&gt;
		if not exclude[code] then&lt;br /&gt;
			info = infos[code]&lt;br /&gt;
			if info then&lt;br /&gt;
				post =&lt;br /&gt;
					(options.showcode and ' &amp;lt;bdi&amp;gt;[&amp;lt;tt&amp;gt;' .. code .. '&amp;lt;/tt&amp;gt;]&amp;lt;/bdi&amp;gt;' or '') ..&lt;br /&gt;
					(type(info.mark) == 'string' and ('&amp;lt;sup&amp;gt;&amp;lt;bdi&amp;gt;' .. info.mark .. '&amp;lt;/bdi&amp;gt;&amp;lt;/sup&amp;gt;') or '') ..&lt;br /&gt;
					(type(info.note) == 'string' and (' &amp;lt;bdi&amp;gt;' .. info.note .. '&amp;lt;/bdi&amp;gt;') or '')&lt;br /&gt;
				post = post ~= '' and '&amp;lt;small style=&amp;quot;font-size:87%&amp;quot;&amp;gt;' .. post .. '&amp;lt;/small&amp;gt;' or ''&lt;br /&gt;
				local itemLabel, result = makeItem(true)&lt;br /&gt;
				if not result then&lt;br /&gt;
					itemLabel, result = makeItem()&lt;br /&gt;
				end&lt;br /&gt;
				if result then&lt;br /&gt;
					table.insert(items,&lt;br /&gt;
						wantSort and { getSortKey(itemLabel, options.lang), result } or result)&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				options.message = options.message or ('no info about code &amp;quot;' .. code .. '&amp;quot;')&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Sort the items, if wanted, using the sort key (precomputed above) with which they were associated.&lt;br /&gt;
	if wantSort then&lt;br /&gt;
		table.sort(items, function (a, b) return a[1] &amp;lt; b[1] end)&lt;br /&gt;
		for i, v in ipairs(items) do&lt;br /&gt;
			items[i] = v[2]&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Pack the items into a single string, and remove the last bullet==stdBullet just before trail.&lt;br /&gt;
	local result = table.concat(items, ' ')&lt;br /&gt;
	local stdBulletTrail = stdBullet .. trail&lt;br /&gt;
	local stdBulletTrailLen = #stdBulletTrail&lt;br /&gt;
	if result:sub(-stdBulletTrailLen) == stdBulletTrail then&lt;br /&gt;
		result = result:sub(1, -stdBulletTrailLen - 1) .. trail  -- omit trailing bullet from last item&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- used by _main() and main()&lt;br /&gt;
local function isnonempty(text)&lt;br /&gt;
	return text and text ~= ''&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- used by main()&lt;br /&gt;
-- exported by this module, for usage in Lua&lt;br /&gt;
local function _main(options, data)&lt;br /&gt;
	-- Caller must provide a valid language code in options.lang.&lt;br /&gt;
	local lang = options.lang&lt;br /&gt;
	local langObj = mw.language.new(lang)&lt;br /&gt;
	-- generate the table of variable names supported in placeholders (inside patterns or subpatterns), or in simple conditions&lt;br /&gt;
	local var = {&lt;br /&gt;
		lang = lang,&lt;br /&gt;
		dir = langObj:getDir(), -- 'ltr' or 'rtl'&lt;br /&gt;
		colon = options.colon or ': ',&lt;br /&gt;
	}&lt;br /&gt;
	local wantSimple = options.simple and data.simple&lt;br /&gt;
	local exceptions = data.simple or {}&lt;br /&gt;
	local sections = exceptions.sections or {}&lt;br /&gt;
	for section, titles in pairs(data.titles) do&lt;br /&gt;
		if not wantSimple or sections[section] then -- add support for the variable named like '{section}title'&lt;br /&gt;
			var[section .. 'title'] = '&amp;lt;bdi&amp;gt;' .. langSwitch(titles, lang) .. '&amp;lt;/bdi&amp;gt;'&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for section, lists in pairs(data.lists) do&lt;br /&gt;
		if not wantSimple or sections[section] then -- add support for the variable named like '{section}list'&lt;br /&gt;
			local exclude = wantSimple and {} or sections[section] or {}&lt;br /&gt;
			var[section .. 'list'] = getList(lists, exclude, options, data.infos)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	-- pattern contains '{variablename}' placeholders to replace by var['variablename']&lt;br /&gt;
	local pattern = wantSimple and exceptions.pattern or data.pattern&lt;br /&gt;
	local usedpattern&lt;br /&gt;
	if type(pattern) == 'string' then&lt;br /&gt;
		-- this is an unconditional pattern, represented as a simple string&lt;br /&gt;
		usedpattern = pattern&lt;br /&gt;
	elseif type(pattern) == 'table' then&lt;br /&gt;
		-- pattern is an array containing an ordered array of conditional patterns, added&lt;br /&gt;
		-- in the same order to the result (non-integer keys in this table are ignored).&lt;br /&gt;
		usedpattern = ''&lt;br /&gt;
		for _, condpattern in ipairs(pattern) do	-- Elements with keys outside the numbered sequence are ignored.&lt;br /&gt;
			--[=[&lt;br /&gt;
			Each conditional pattern is represented either:&lt;br /&gt;
			- as a simple string when there's no condition (this unconditional pattern will be always added to the result), or&lt;br /&gt;
			- as an ordered table, whose first element is a subpattern string and the other elements represent an union of several (non-exclusive) conditions&lt;br /&gt;
			  (if any one of the conditions evaluates to true (OR), the conditional subpattern will be used).&lt;br /&gt;
			Each condition may itself be represented either:&lt;br /&gt;
			- as a simple string for simple conditions, or&lt;br /&gt;
			- as an ordered table of subconditions, i.e. a conjunction of several (non-exclusive) simple conditions&lt;br /&gt;
						  (if any one of the subconditions evaluates to false (AND), the conditional subpattern will NOT be used.&lt;br /&gt;
			Simple conditions are represented as strings, used to evaluate tests based on names of variables (usable in placeholders of patterns or subpatterns).&lt;br /&gt;
			The variable names used in simple conditions don't need to be present within the pattern or subpattern strings.&lt;br /&gt;
			A simple condition can currently take one the following forms:&lt;br /&gt;
			- 'variablename'  : the simple condition is true if the variable with that name is non-empty&lt;br /&gt;
			- '!variablename' : the simple condition is true if the variable with that name is empty&lt;br /&gt;
			--]=]&lt;br /&gt;
			local subpattern, condition&lt;br /&gt;
			if type(condpattern) == 'string' then		-- This is an unconditional subpattern.&lt;br /&gt;
				subpattern, condition = condpattern, true&lt;br /&gt;
			elseif type(condpattern) == 'table' then	-- This is a conditional subpattern.&lt;br /&gt;
				subpattern, condition = '', false&lt;br /&gt;
				for i, v in ipairs(condpattern) do	-- Elements with keys outside the numbered sequence are ignored.&lt;br /&gt;
					-- The first element is the subpattern, other numbered elements are its conditions (forming an union).&lt;br /&gt;
					if i == 1 then&lt;br /&gt;
						subpattern = v&lt;br /&gt;
					-- Handle conditions that are simple strings.&lt;br /&gt;
					elseif type(v) == 'string' then&lt;br /&gt;
						-- Evaluate the condition string which is for now a simple variable name:&lt;br /&gt;
						-- * the condition '!variablename' is true if this variable has an empty string value;&lt;br /&gt;
						-- * the condition 'variablename'  is true if this variable has a non-empty string value;&lt;br /&gt;
						-- * the supported variable names are defined above (e.g. {section}..'title' and {section}..'list').&lt;br /&gt;
						if v:sub(1, 1) == '!' and not isnonempty(var[v:sub(2)])&lt;br /&gt;
						or v:sub(1, 1) ~= '!' and     isnonempty(var[v]) then&lt;br /&gt;
							condition = true	-- The subpattern will EFFECTIVELY be used.&lt;br /&gt;
							break			-- Don't need to evaluate other conditions.&lt;br /&gt;
						--else	-- Other string values of v evaluate are ignored.&lt;br /&gt;
							-- Condition evaluates as false, other conditions must be evaluated.&lt;br /&gt;
						end&lt;br /&gt;
					-- Handle conditions that are arrays of subconditions (AND).&lt;br /&gt;
					-- If any one subcondition evaluates to false, the condition also evaluates to false,&lt;br /&gt;
					-- and other conditions must be checked to evaluate them as OR).&lt;br /&gt;
					elseif type(v) == 'table' then&lt;br /&gt;
						condition = true	-- The subpattern will then be used unless a subcondition evaluates to false&lt;br /&gt;
						for _, w in ipairs(v) do	-- Elements with keys outside the numbered sequence are ignored&lt;br /&gt;
							-- handle subconditions that are simple strings&lt;br /&gt;
							if type(w) == 'string' then&lt;br /&gt;
								-- Evaluate the subcondition string which is for now a simple variable name (like above).&lt;br /&gt;
								if w:sub(1, 1) == '!' and     isnonempty(var[w:sub(2)])&lt;br /&gt;
								or w:sub(1, 1) ~= '!' and not isnonempty(var[w]) then&lt;br /&gt;
									condition = false	-- The subcondition evaluated as false.&lt;br /&gt;
									break			-- The subpattern may still be used, but need to evaluate other conditions.&lt;br /&gt;
								--else	-- Other string values of v are ignored. Subcondition evaluates as false.&lt;br /&gt;
									-- Other subconditions must be evaluated.&lt;br /&gt;
								end&lt;br /&gt;
							else	-- Don't know what to do with this type of subcondition. And because this is part of a conjonction (AND):&lt;br /&gt;
								condition = false	-- The subcondition evaluated as false.&lt;br /&gt;
								break			-- The subpattern may still be used, but need to evaluate other conditions.&lt;br /&gt;
							end&lt;br /&gt;
						end&lt;br /&gt;
						-- if the array of subconditions (AND) is still true, the main condition (OR) evaluates as true immediately&lt;br /&gt;
						if condition then	-- The subpattern will EFFECTIVELY be used.&lt;br /&gt;
							break		-- Don't need to evaluate other conditions.&lt;br /&gt;
						end&lt;br /&gt;
					--else	-- Don't know what to do with this type of condition. And because this is part of an union (OR):&lt;br /&gt;
						-- Ignored, evaluate other conditions.&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			if condition then&lt;br /&gt;
				usedpattern = usedpattern .. subpattern&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else -- don't know what to do with this type of pattern (not used in the final pattern)&lt;br /&gt;
	end&lt;br /&gt;
	return usedpattern:gsub('{(%a+)}', var)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- used by getGroupData() and show()&lt;br /&gt;
-- If there's no ':' in the id, it is assumed to be in a subpage of Module:Countries;&lt;br /&gt;
-- Otherwise it can be the full page name of any other module stored anywhere.&lt;br /&gt;
-- Autodetect also the /sandbox version according to the parent page name.&lt;br /&gt;
local function getDataModuleName(frame, id)&lt;br /&gt;
	return	(id:find(':', 1, true) and id or 'Module:Countries/' .. id) ..&lt;br /&gt;
		(frame and frame:getTitle():find('sandbox', 1, true) and '/sandbox' or '')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- used by main()&lt;br /&gt;
local function getGroupData(frame)&lt;br /&gt;
	-- Return table of data defining a group of items for the first template parameter.&lt;br /&gt;
	-- The data will rarely be used more than once on a page so mw.loadData is not useful.&lt;br /&gt;
	local data&lt;br /&gt;
	local id = stripToNil(frame.args[1]) -- identifies the group, for example 'Europe' (case sensitive) or 'Module:CustomData'&lt;br /&gt;
	if id then&lt;br /&gt;
		local module, status = getDataModuleName(frame, id), nil&lt;br /&gt;
		status, data = pcall(require, module)&lt;br /&gt;
		if not status then&lt;br /&gt;
			error('Data could not be loaded from [[:' .. module ..']]')&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if type(data) ~= 'table' then&lt;br /&gt;
		error('First template parameter must specify a defined data module')&lt;br /&gt;
	end&lt;br /&gt;
	if data.infos == nil and data.countries ~= nil then -- compatiblity: infos is preferred, countries is legacy&lt;br /&gt;
		data.infos = data.countries&lt;br /&gt;
		data.countries = nil&lt;br /&gt;
	end&lt;br /&gt;
	if type(data.titles) ~= 'table' or&lt;br /&gt;
		type(data.lists) ~= 'table' or&lt;br /&gt;
		type(data.infos)  ~= 'table' or type(data.countries) ~= 'nil' or -- It's not possible to define both (ambiguous): infos is preferred, countries is legacy&lt;br /&gt;
		type(data.pattern) ~= 'string' and type(data.pattern) ~= 'table' or&lt;br /&gt;
		type(data.simple) ~= 'nil' and type(data.simple) ~= 'table' or&lt;br /&gt;
		type(data.simple) == 'table' and (&lt;br /&gt;
			type(data.simple.pattern) ~= 'string' and type(data.simple.pattern) ~= 'table' or&lt;br /&gt;
			type(data.simple.sections) ~= 'table'&lt;br /&gt;
		) then&lt;br /&gt;
		error('The specified data module (' .. id .. ') is not validly defined')&lt;br /&gt;
	end&lt;br /&gt;
	return data&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- exported by this module, for usage in wiki templates&lt;br /&gt;
local function main(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local options = {&lt;br /&gt;
	-- use default args set by &amp;quot;{{#invoke:}}&amp;quot; used in any page or in the main template&lt;br /&gt;
		prefix   = args.prefix or '',&lt;br /&gt;
		presep   = args.presep or args.sep or ' ',&lt;br /&gt;
		sufsep   = args.sufsep or args.sep or ' ',&lt;br /&gt;
		suffix   = args.suffix or '',&lt;br /&gt;
		simple   = args.simple,&lt;br /&gt;
		showcode = args.showcode,&lt;br /&gt;
		all      = args.all,&lt;br /&gt;
		nocat    = args.nocat,&lt;br /&gt;
		lang     = args.lang or frame:callParserFunction('Int', 'Lang'),&lt;br /&gt;
	}&lt;br /&gt;
	local lang = options.lang&lt;br /&gt;
	-- override args with those passed to the main template (and check them verbosely)&lt;br /&gt;
	args = frame:getParent().args&lt;br /&gt;
	if args then&lt;br /&gt;
		options.prefix   = args.prefix             or options.prefix&lt;br /&gt;
		options.presep   = args.presep or args.sep or options.presep&lt;br /&gt;
		options.sufsep   = args.sufsep or args.sep or options.presep&lt;br /&gt;
		options.suffix   = args.suffix             or options.suffix&lt;br /&gt;
		options.simple   = args.simple             or options.simple&lt;br /&gt;
		options.showcode = args.showcode           or options.showcode&lt;br /&gt;
		options.all      = args.all                or options.all&lt;br /&gt;
		options.nocat    = args.nocat              or options.nocat&lt;br /&gt;
		local goodArgs, badArgs = {&lt;br /&gt;
			prefix = true,&lt;br /&gt;
			presep = true,&lt;br /&gt;
			sufsep = true,&lt;br /&gt;
			suffix = true,&lt;br /&gt;
			sep = true,&lt;br /&gt;
			simple = true,&lt;br /&gt;
			showcode = true,&lt;br /&gt;
			all = true,&lt;br /&gt;
			nocat = true,&lt;br /&gt;
		}, {}&lt;br /&gt;
		for k, v in pairs(args) do&lt;br /&gt;
			if not goodArgs[k] then&lt;br /&gt;
				table.insert(badArgs, k .. '=' .. v)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if #badArgs &amp;gt; 0 then&lt;br /&gt;
			options.message = 'invalid parameter &amp;quot;|' .. mw.text.nowiki(table.concat(badArgs, '|')) .. '&amp;quot;'&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	options.colon    = frame:expandTemplate({title = 'colon', args = {lang = lang}})&lt;br /&gt;
	options.simple   = isnonempty(options.simple) &lt;br /&gt;
	options.showcode = isnonempty(options.showcode)&lt;br /&gt;
	options.all      = isnonempty(options.all)&lt;br /&gt;
	options.nocat    = isnonempty(options.nocat)&lt;br /&gt;
	local result = _main(options, getGroupData(frame))&lt;br /&gt;
	if options.message then&lt;br /&gt;
		-- Check if a warning should be displayed for invalid input.&lt;br /&gt;
		local success, revid = pcall(function ()&lt;br /&gt;
			return frame:preprocess('{{REVISIONID}}')&lt;br /&gt;
		end)&lt;br /&gt;
		if success and revid == '' then&lt;br /&gt;
			result = result .. '&amp;lt;strong class=&amp;quot;error&amp;quot;&amp;gt;Error: ' .. options.message .. '&amp;lt;/strong&amp;gt;'&lt;br /&gt;
		end&lt;br /&gt;
		if not options.nocat then&lt;br /&gt;
			result = result .. '[[Category:Countries template with invalid parameters]]'&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- exported by this module, for usage by {{#invoke:thisModule|show}} in wiki&lt;br /&gt;
-- For documentation, return wikitext listing data from the country modules. See [[Module_talk:Countries/show]] for results.&lt;br /&gt;
local function show(frame)&lt;br /&gt;
	local templateids = {&lt;br /&gt;
		-- Template                                      Data module id (without any &amp;quot;:&amp;quot;, uses &amp;quot;Module:Countries/(id)&amp;quot; by default)&lt;br /&gt;
		{ 'Countries of Africa'                       , 'Africa' },&lt;br /&gt;
		{ 'Countries of the Americas'                 , 'Americas' },&lt;br /&gt;
		{ 'Countries of the Arab world'               , 'Arab world' },&lt;br /&gt;
		{ 'Countries of Asia'                         , 'Asia' },&lt;br /&gt;
		{ 'Countries of the Caribbean'                , 'Caribbean' },&lt;br /&gt;
		{ 'Countries of Central America'              , 'Central America' },&lt;br /&gt;
		{ 'Countries of Europe'                       , 'Europe' },&lt;br /&gt;
		{ 'Countries of the European Union'           , 'European Union' },&lt;br /&gt;
		{ 'Countries of North America'                , 'North America' },&lt;br /&gt;
		{ 'Countries of North America (subcontinent)' , 'North America (subcontinent)' },&lt;br /&gt;
		{ 'Countries of Oceania'                      , 'Oceania' },&lt;br /&gt;
		{ 'Countries of South America'                , 'South America' },&lt;br /&gt;
		{ 'Countries in the United Kingdom'           , 'United Kingdom' },&lt;br /&gt;
		{ 'Copyright rules by territory'              , 'CRT other' },&lt;br /&gt;
		{ 'Olympic teams'                             , 'Olympic teams' },&lt;br /&gt;
		{ 'Departments of France'                     , 'Module:Departments of France' },&lt;br /&gt;
		{ 'Regions of France'                         , 'Module:Regions of France' },&lt;br /&gt;
		{ 'Most populous cities of the world'         , 'Module:Most populous cities of the world' },&lt;br /&gt;
	}&lt;br /&gt;
	local lines = {}&lt;br /&gt;
	local function output(line)&lt;br /&gt;
		lines[#lines + 1] = line&lt;br /&gt;
	end&lt;br /&gt;
	for _, templateid in ipairs(templateids) do&lt;br /&gt;
		local template, id = templateid[1], templateid[2]&lt;br /&gt;
		local module = getDataModuleName(frame, id)&lt;br /&gt;
		local data = require(module)&lt;br /&gt;
		local infos = data.infos or data.countries -- infos is prefered, countries is legacy&lt;br /&gt;
		if infos then&lt;br /&gt;
			local codes, maxnames, usethe = {}, 0, false&lt;br /&gt;
			for code, info in pairs(infos) do&lt;br /&gt;
				codes[#codes + 1] = '' .. code&lt;br /&gt;
				maxnames = math.max(#info, maxnames)&lt;br /&gt;
				usethe = usethe or info.the&lt;br /&gt;
			end&lt;br /&gt;
			table.sort(codes, function (a, b) return a &amp;lt; b end)&lt;br /&gt;
			output('== ' .. template .. ' ==')&lt;br /&gt;
			output('* [[Template:' .. template .. ']]')&lt;br /&gt;
			output('* [[' .. module .. ']]')&lt;br /&gt;
			output('{|class=&amp;quot;wikitable sortable&amp;quot;')&lt;br /&gt;
			output('|-')&lt;br /&gt;
			output('!scope=&amp;quot;col&amp;quot;| Code')&lt;br /&gt;
			output('!scope=&amp;quot;col&amp;quot;| Wikidata')&lt;br /&gt;
			if usethe then&lt;br /&gt;
				output('!scope=&amp;quot;col&amp;quot;| the')&lt;br /&gt;
			end&lt;br /&gt;
			output('!scope=&amp;quot;col&amp;quot; colspan=&amp;quot;' .. (maxnames &amp;lt; 2 and maxnames or 2) .. '&amp;quot;| Name' ..&lt;br /&gt;
				(maxnames &amp;lt;= 1 and '' or maxnames == 2 and ' and alias' or ' and aliases') ..&lt;br /&gt;
				' on Commons')&lt;br /&gt;
			for _, code in ipairs(codes) do&lt;br /&gt;
				local info = infos[code]&lt;br /&gt;
				output('|-')&lt;br /&gt;
				output('!scope=&amp;quot;row&amp;quot; style=&amp;quot;text-align:left&amp;quot;| &amp;lt;tt style=&amp;quot;font-size:smaller&amp;quot;&amp;gt;' .. code .. '&amp;lt;/tt&amp;gt;')&lt;br /&gt;
				output('| &amp;lt;small&amp;gt;' .. (info.qid and ('[[d:' .. info.qid  .. '|' .. info.qid  .. ']]') or '') .. '&amp;lt;/small&amp;gt;')&lt;br /&gt;
				if usethe then&lt;br /&gt;
					output(info.the and ('| [[The ' .. info[1] .. '|the]] &amp;lt;small&amp;gt;([[:Category:The ' .. info[1] .. '|cat]])&amp;lt;/small&amp;gt;')&lt;br /&gt;
						or '|style=&amp;quot;background:#CCC&amp;quot;| &amp;amp;nbsp;')&lt;br /&gt;
				end&lt;br /&gt;
				output(info[1] and ('| [[' .. info[1] .. ']] &amp;lt;small&amp;gt;([[:Category:' .. info[1] .. '|cat]])&amp;lt;/small&amp;gt;')&lt;br /&gt;
					or '|style=&amp;quot;background:#CCC&amp;quot;| &amp;amp;nbsp;')&lt;br /&gt;
				if maxnames &amp;gt;= 2 then&lt;br /&gt;
					local aliases = {}&lt;br /&gt;
					for i = 2, #info do&lt;br /&gt;
						aliases[#aliases + 1] = '[[' .. info[i] .. ']] &amp;lt;small&amp;gt;([[:Category:' .. info[i] .. '|cat]])&amp;lt;/small&amp;gt;'&lt;br /&gt;
					end&lt;br /&gt;
					output(#aliases &amp;gt; 0 and ('| ' .. table.concat(aliases, ', '))&lt;br /&gt;
						or '|style=&amp;quot;background:#CCC&amp;quot;| &amp;amp;nbsp;')&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
			output('|}')&lt;br /&gt;
			output('')&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return table.concat(lines, '\n')&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- exports&lt;br /&gt;
return {&lt;br /&gt;
	main = main, -- for use in a MediaWiki template&lt;br /&gt;
	_main = _main, -- for use in Lua only&lt;br /&gt;
	show = show, -- only for the documentation of this module&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Imported&gt;Verdy p</name></author>
		
	</entry>
</feed>