Module:Region

local p = {} local h = {} local Data = mw.loadData("Module:Region/Data")

local utilsArg = require("Module:UtilsArg")

local DEFAULT_FLAG_SIZE = "20px" local CATEGORY_INVALID_ARGS = "" local CLASS_TOOLTIP = require("Module:Constants/class/tooltip")

function p.Flag(frame) local args, err = utilsArg.parse(frame:getParent.args, p.Templates.Flag) if err then return err.categoryText else local region = Data.regions[args.code] local flags = h.flags(region, args) local result = table.concat(flags, " ") return result end end

function p.enum(options) local options = options or {} local sortBy = options.sortBy or "name" local enum = {} for k, v in pairs(Data.regions) do		if k ~= "jp" and k ~= "us" then table.insert(enum, {				code = k,				name = v.name,				abbr = v.abbr,				official = v.official or v.name,			}) end end -- We put the wiki's native region (us) first followed by Nintendo's native region (jp) -- followed by every other country ordred by a certain property (name by default) table.sort(enum, function(a, b)		return a[sortBy] < b[sortBy]	end) for i, v in ipairs(enum) do		enum[i] = v.code end table.insert(enum, 1, "jp") table.insert(enum, 1, "us") enum.reference = "Module:Region/Data" return enum end

--cache Template:Exp results for performance local exp = {} function p.getRegion(code, options) options = options or {} local flagSize = options.flagSize or DEFAULT_FLAG_SIZE local flagTooltip = options.flagTooltip or "official"

local region = Data.regions[code] if not region then local utilsError = require("Module:UtilsError") utilsError.warn(string.format("Invalid region . See Module:Region/Data for a list of supported regions.", code)) return nil, CATEGORY_INVALID_ARGS else local result = {} result.name = region.name result.flags = h.flags(region, {			size = flagSize,			tooltip = flagTooltip,		}) result.abbr = exp[code] or mw.getCurrentFrame:expandTemplate({			title = "Exp",			args = {region.name, region.abbr}		}) exp[code] = result.abbr return result, "" end end

function h.flags(region, options) options = options or {} local size = options.size local tooltip = options.tooltip

if not region then return nil, CATEGORY_INVALID_ARGS elseif region.flag then local name = region.official or region.name local flagFile = region.flag tooltip = region[tooltip] or region.name local flag = string.format(' %s|%s ', CLASS_TOOLTIP, tooltip, flagFile, size, tooltip) return {flag}, "" elseif region.countries then local flags = {} for i, country in ipairs(region.countries) do			local countryRegion = p.getRegion(country, {				flagSize = size,				flagTooltip = tooltip,			}) table.insert(flags, countryRegion.flags[1]) end return flags, "" else return {""}, "" end end

function p.Documentation(frame) return { enum = { params = {"options"}, returns = { "A list of region codes.", },			cases = { outputOnly = true, {					args = {}, },				{					args = },			},		},		getRegion = { params = {"code", "options"}, returns = { "An object containing the region's name and flag(s), or  if no region exists for the given code.", "An error category if no region exists for the given code.", },		},	} end

function p.Schemas(frame) return { enum = { options = { type = "record", properties = { {						name = "sortBy", type = "string", default = "name", desc = "Region property to sort by. Options are,  ,  , and   (default). By exception, USA and Japan are always placed first, as they are the native regions of this wiki and of Nintendo, respectively.", },				},			},		},		getRegion = { code = { required = true, type = "string", desc = "A region code from Module:Region/Data." },			options = { type = "record", properties = { {						name = "flagSize", type = "string", default = DEFAULT_FLAG_SIZE, desc = "The image size to use for the region's flag(s).", },					{						name = "flagTooltip", type = "string", default = "official", desc = " or  . Determines which name is used as the flag's tooltip.", },				},			},		},		Data = { type = "record", required = true, properties = { {					name = "regions", required = true, type = "map", desc = "A list of regions that Nintendo (or other Zelda-related companies) markets to.", keyPlaceholder = "code", keys = { type = "string", desc = "An country code, or a 3+ character code denoting a multi-country region forming a single market segment.", },					values = { type = "record", properties = { {								name = "name", required = true, type = "string", desc = "The name of the country or region.", },							{								name = "abbr", required = true, type = "string", desc = "Abbreviated name for the region, used by Template:Release. For countries, this should be the country code. For multi-country regions, use a 4+ character abbreviation, or else a 3-character abbreviation that is not a reserved ISO 3166-1 alpha-3 code.", },							{								name = "flag", type = "string", desc = "The file name of the region's flag", },							{								name = "official", type = "string", desc = "The official state name of the country, used as the flag's tooltip. Defaults to .", },							{								name = "countries", type = "array", items = { type = "string" }, desc = "For multi-country regions, a list of country codes that comprise the region.", },						},					},				},			},		}	} end

function p.Data(frame) local utilsLayout = require("Module:UtilsLayout") local utilsTable = require("Module:UtilsTable")

local countries = {} local multiCountryRegions = {} for code in pairs(Data.regions) do		local region = p.getRegion(code) local row = { id = code, cells = { " ",				table.concat(region.flags, " "), region.abbr, region.name, }		}		if code:len == 2 then table.insert(countries, row) else table.insert(multiCountryRegions, row) end end countries = utilsTable.sortBy(countries, "id") multiCountryRegions = utilsTable.sortBy(multiCountryRegions, "id") local countriesTable = utilsLayout.table({		caption = "Countries",		sortable = {1, 3, 4},		headers = {"", "Flag", "Abbr.", "Name"},		rows = countries,	}) local multiCountryRegionsTable = utilsLayout.table({		caption = "Multi-Country Regions",		sortable = {1, 3},		headers = {"Code", "Flags", "Abbr.", "Name"},		rows = multiCountryRegions,	})

local html = mw.html.create("div") :css({			["display"] = "flex",			["flex-wrap"] = "wrap",			["gap"] = "1rem",		}) :wikitext(countriesTable) :wikitext(multiCountryRegionsTable)

return tostring(html) end

p.Templates = { ["Flag"] = { purpose = "Displays a region's flag(s).", params = { [1] = {				name = "code", required = true, type = "string", enum = p.enum, desc = "A code representing a region. For countries, this is the code.", trim = true, nilIfEmpty = true, },			[2] = {				name = "size", type = "string", default = DEFAULT_FLAG_SIZE, desc = "An ." },		},	} }

return p