Modul:Infocaseta Nume străin

Implementează {{Infocaseta Chineză}} și câteva formate înrudite.

Este o variantă a modulului englez Module:Infobox multi-lingual name, adaptată la nevoile și condițiile de la Wikipedia în română. Multe funcții arată diferit; unele au funcționalități noi, iar altele au fost rescrise mai scurt, fiindcă urmau același șablon.


--[[
TODO:
		all non-English text wrapped in {{lang}}?
		distingush various scripts?  Kanji is ja-Hani ...
		every child infobox should support translit / transcription parameter(s)
		every child infobox should have a literal meaning parameter
		revise parameter names to be IETF language code or obvious derivations thereof
		for error messaging create a separate ibox? else messages are not necessarily visible
]]

require("Modul:No globals")
local data = mw.loadData("Modul:Infocaseta Nume străin/data")
local getArgs_ = require("Modul:Arguments").getArgs


--[[--------------------------< G E T A R G S >----------------------------------------------------------------

Returns a frame's arguments, but all keys are converted to lowercase.

]]

local function getArgs(frame)
	local args = getArgs_(frame, { removeBlanks = false })
	for k, v in pairs(args) do
		if type(k) ~= "number" then
			local lowercase = string.lower(k)
			if k ~= lowercase then
				if args[lowercase] == nil then args[lowercase] = v end
				args[k] = nil
			end
		end
	end
	return args
end


--[[--------------------------< I S _ S E T >------------------------------------------------------------------

Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.

]]

local function is_set(var)
	return not (var == nil or var == "")
end


--[[--------------------------< A N Y _ S E T >----------------------------------------------------------------

Returns true if any member of the table is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.

]]

local function any_set(t)
	for __, v in pairs(t) do
		if is_set(v) then return true end
	end
	return false
end

--[[--------------------------< I F _ S E T >------------------------------------------------------------------

Returns a value if it's set according to is_set. If not, then returns nil.

]]

local function if_set(val)
	if is_set(val) then return val end
	return nil
end

local _ = if_set


--[[--------------------------< _ L A N G >--------------------------------------------------------------------

Copy of fromArgs from Modul:Lang, except there's a size option instead of an italic option, which would go
unused here.

]]

local function _lang(langISOcode, languageDir, langText, size)
	if not is_set(langText) then return "" end
	local span = mw.html.create("span")
	if is_set(langISOcode) then
		span:attr("lang", langISOcode)
		span:attr("translate", "no")
	end
	if is_set(languageDir) then span:attr("dir", languageDir) end
	if is_set(size) then span:css("font-size", size) end
	span:wikitext(langText)
	return tostring(span)
end


--[[--------------------------< S H O W F L A G >--------------------------------------------------------------

This function handles the |showflag= parameter from the template {{Infobox Chinese}}.  That template passes the
value to {{Infobox Chinese/Chinese}} which calls this function.  This function does not take any frame parameters
but it does require a copy of the frame so that it can expand {{Infobox}}.  All arguments used by this function
come from the args table in the function call

returns a child infobox or an empty string

]]

local function showflag(frame, args)
	local show_flag = args.showflag

	if not is_set(show_flag) then return "" end									-- |showflag= not set so nothing to do; return empty string
	
	local infobox_args = {}														-- table to hold arguments for frame:expandTemplate()
	
	infobox_args.child = "yes"													-- showflag infoboxen are always children
	infobox_args.labelstyle = "padding:2px 0.1em;font-weight:bold"			-- and always have this label style
	
	if data.transl_map[show_flag] then
		local i = 1
		while (1) do
			local labeln = "label" .. i											-- make label index that matches |labeln= parameter
			local datan = "data" .. i											-- make data index that matches |datan= parameter
			if not data.transl_map[show_flag][labeln] then
				break															-- not found then done
			end
			infobox_args[labeln] = data.label_map[data.transl_map[show_flag][labeln]]	-- add |labeln=<label text / wikilink>
			infobox_args[datan] = _(args[data.transl_map[show_flag][datan]])	-- add |datan={{{data}}}
			i = i + 1															-- bump to next label / data pair
		end
	else
		return ""																-- |showflag= value invalid; TODO: return error message?
	end
	
	return frame:expandTemplate({ title = "Infocasetă", args = infobox_args })
end


--[[--------------------------< A D D _ L A B E L _ D A T A _ P A I R >----------------------------------------

Adds a label parameter and matching data parameter to infobox arguments table; bumps the enumerator on return

]]

local function add_label_data_pair(infobox_args, label, data, i, lh)
	if is_set(data) then
		infobox_args["label" .. i] = label										-- make an enumerated label parameter
		infobox_args["data" .. i] = data										-- make an enumerated data parameter
		if is_set(lh) then infobox_args["lblstyle" .. i] = "line-height:" .. lh end	-- fixes some (but not all) instances where a label will show up higher than its corresponding transcription due to different font sizes
		return i + 1															-- return bumped enumerator
	end
	return i																	-- if here, no data so no need to add label or bump enumerator
end


--[[--------------------------< A D D _ T R A N S C R I P T I O N >--------------------------------------------

This function does that repetitive work when assembling the parameter list for {{Infobox}} template

inputs are:
	infobox_args - table of infobox parameters
	args - args table from the {{#invoke:}} frame
	idx - index into xscript table
	show - pseudo-boolean (true or nil) header display flag; when true display the header
	i - enumerator for {{infobox}} parameters |headern=, |labeln=, |datan=; in this application i continually
		increments; there are no gaps as there are in the original template
	lang - language code - must be valid ISO code

returns i for the next time this function is called

]]

local function add_transcription(infobox_args, args, idx, show, i, lang)
	if show then
		local hdr = data.xscript[idx].header
		if is_set(hdr) then
			infobox_args["header" .. i] = hdr
			i = i + 1
		end
	end
	local def_lang_suffix = "-Latn"
	if data.xscript[idx].script ~= nil then
		if data.xscript[idx].script == "" then def_lang_suffix = ""
		else def_lang_suffix = "-" .. data.xscript[idx].script end
	end
	for __, v in ipairs(data.xscript[idx].t) do
		if is_set(args[v[2]]) then
			local lang_suffix
			local local_lang = nil
			local lang_final = nil
			if v.lang ~= "" then
				if v.lang == nil then
					local_lang = lang or nil
				else
					local_lang = v.lang
				end
				lang_suffix = def_lang_suffix
				if v.script ~= nil then
					if v.script == "" then lang_suffix = ""
					else lang_suffix = "-" .. v.script end
				end
				if local_lang ~= nil then lang_final = local_lang .. lang_suffix end
			end
			if is_set(lang_final) then
				lang_final = _lang(lang_final, nil, args[v[2]], v.size)
			else
				lang_final = args[v[2]]
			end
			i = add_label_data_pair(infobox_args, v[1], lang_final, i, v.size)
		end
	end
	return i
end


--[[--------------------------< T R A N S C R I P T I O N S _ Z H >--------------------------------------------

transcriptions support for {{Infobox Chinese/Chinese}}.  This function adds headers and label data pairs to
infobox_arg table according to which parameters are set

returns the enumerator in case it is needed

]]

local function transcriptions_zh(infobox_args, args, show, i)
	if any_set({args.p, args.bpmf, args.gr, args.w, args.tp, args.myr, args.mps, args.mi}) then
		i = add_transcription(infobox_args, args, "standard mandarin", show, i, "zh")
	end
	
	if any_set({args.xej, args["zh-dungan"], args.sic}) then
		i = add_transcription(infobox_args, args, "other mandarin", show, i, "zh")
	end
	
	if any_set({args.wuu, args.lmz, args.ouji, args.suz}) then
		i = add_transcription(infobox_args, args, "wu", show, i, "wuu")
	end
	
	if is_set(args.gan) then
		i = add_transcription(infobox_args, args, "gan", show, i, "gan")
	end
	
	if is_set(args.hsn) then
		i = add_transcription(infobox_args, args, "xiang", show, i, "hsn")
	end
	
	if any_set({args.h, args.phfs}) then
		i = add_transcription(infobox_args, args, "hakka", show, i, "hak")
	end
	
	if any_set({args.y, args.ci, args.j, args.sl, args.gd, args.hk, args.mo}) then
		i = add_transcription(infobox_args, args, "yue cantonese", show, i, "yue")
	end
	
	if is_set(args.toi) then
		i = add_transcription(infobox_args, args, "other yue", show, i, "yue")
	end
	
	if any_set({args.poj, args.tl, args.bp, args.teo, args.hain, args.lizu}) then
		i = add_transcription(infobox_args, args, "southern min", show, i, "nan")
	end
	
	if is_set(args.buc) then
		i = add_transcription(infobox_args, args, "eastern min", show, i, "cdo")
	end
	
	if is_set(args.hhbuc) then
		i = add_transcription(infobox_args, args, "pu-xian min", show, i, "cpx")
	end
	
	if is_set(args.mblmc) then
		i = add_transcription(infobox_args, args, "northern min", show, i, "mnp")
	end
	
	if is_set(args["phagspa-latin"]) then										-- phagspa is a script
		i = add_transcription(infobox_args, args, "old mandarin", show, i, "zh")
	end
	
	if any_set({args.mc, args.emc, args.lmc}) then
		i = add_transcription(infobox_args, args, "middle chinese", show, i, "ltc")
	end
	
	if any_set({args["oc-b92"], args["oc-bs"], args["oc-zz"]}) then
		i = add_transcription(infobox_args, args, "old chinese", show, i, "och")
	end
	
	return i																	-- return current state of the enumerator
end


--[[--------------------------< T R A N S C R I P T I O N S >--------------------------------------------------

This function handles the transcription infobox called by various {{Infobox Chinese/xxx}}.  Creates header and
label / data pairs according to the presence of certain parameters provided to {{Infobox Chinese}}

]]

local function transcriptions(frame, args, lang)
	if not args then args = getArgs(frame) end
	local show = (args.hide ~= "no") or nil										-- make boolean-ish for controlling display of headers; |hide=no means show transcriptions without collapsed header
	local fontstyle = _(args.fontstyle) or "bold"
	local infobox_args = {}														-- table to hold arguments for frame:expandTemplate()
	local i = 1																	-- enumerator used with {{infobox}} |headern=, |labeln=, and |datan= parameters
	
	infobox_args.child = "yes"
	infobox_args.labelstyle = "padding:2px 0.1em;font-weight:" .. fontstyle		-- fixes inconsistencies with how label/data pairs are displayed on the Romanian Wikipedia
	infobox_args["culoare cadru"] = "#dcffc9"									-- always yellow
	
	if lang == "zh" then
		transcriptions_zh(infobox_args, args, show, i)
	else
		add_transcription(infobox_args, args, data.keys[lang], show, i, lang)
	end
	
	local child_infobox = frame:expandTemplate({title = "Infocasetă", args = infobox_args})
	local infobox_parent
	
	if show then
		infobox_parent = mw.html.create("div")
		infobox_parent
			:addClass("NavFrame collapsed")
			:css("padding", "0")
			:css("border", "none")
			:css("text-align", "inherit")
			:css("font-size", "inherit")
		infobox_parent:tag("div")
			:addClass("NavHead")
			:css("background", "#dcffc9")
			:css("text-align", "left")
			:css("padding", "1px")
			:css("height", "auto")
			:wikitext("Transcrieri")
		infobox_parent:tag("div")
			:addClass("NavContent")
			:tag("table")
				:css("width", "100%")
				:css("border-spacing", "inherit")
				:css("margin", "0")
				:css("padding", "0")
				:wikitext(child_infobox)
		infobox_parent = tostring(infobox_parent)
	else
		infobox_parent = child_infobox
	end
	
	return infobox_parent
end


--[[--------------------------< I B O X _ B O I L E R P L A T E >----------------------------------------------

boilerplate style settings for the various child infoboxen (not for transcription infoboxen) beause they are
mostly the same child-infobox to child-infobox

TODO: |headercolor= is set to its default color in {{Infobox Chinese}}.  Better here than there isn't it?  less 
maintenence headache when a default value is set in only one place; override in the highest level appropriate
but leave the default here.  in the higher-level template(s) remove |headercolor= default values

]]

local function ibox_boilerplate(frame, infobox_args, args)
	infobox_args.child = "yes"
	infobox_args["culoare cadru"] = _(args.headercolor) or "#b0c4de"
	infobox_args["culoare text"] = _(args.fontcolor) or "#000000"
	infobox_args.headerstyle = _(args.headerstyle)
	infobox_args.parent_colspan = _(args.cols)
	infobox_args.labelstyle = "padding:2px 0.1em;font-weight:" .. (_(args.fontstyle) or "bold")
end


--[[-------------------------< I B O X _ Z H Z H _ E N U M _ P A R A M S _ G E T >-----------------------------

]]

local function ibox_zhzh_enum_params_get(args, i)
	local ibox_args = {}
	local count = 0																-- counts how many args got added to ibox_args {}

	for __, v in ipairs(data.ibox_zhzh_enum_params) do							-- add enumerated parameters
		if is_set(args[v .. i]) then											-- only when there is an assigned value
			ibox_args[v] = args[v .. i]											-- add
			count = count + 1													-- and tally
		end
	end

	return count ~= 0 and ibox_args or nil										-- if table is empty return nil as a flag
end


--[[-------------------------< I B O X _ N S _ B L A N K >-----------------------------------------------------

implements {{Infobox Chinese/Blank}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_blank}}

]]

local function ibox_ns_blank(frame, args)
	if not args then args = getArgs(frame) end
	local i = 1
	local infobox_args = {}														-- table to hold arguments for frame:expandTemplate()
	ibox_boilerplate(frame, infobox_args, args)
	
	-- cue workaround b/c Romanian Wikipedia doesn't have the IETF table that the English one has
	
	local lang_3_to_2 = require("Modul:Lang/ISO 639 synonyms")
	local iso_tag = args.lang
	local script_tag
	local name_from_tag = args.lang_label
	
	if is_set(iso_tag) then
		local dash_idx = mw.ustring.find(iso_tag, "-", nil, true)
		if (dash_idx ~= nil) and (dash_idx ~= 1) then
			script_tag = mw.ustring.sub(iso_tag, dash_idx)
			if (script_tag == "") then script_tag = nil end
			iso_tag = mw.ustring.sub(iso_tag, 1, dash_idx - 1)
		end
		if is_set(lang_3_to_2[iso_tag]) then iso_tag = lang_3_to_2[iso_tag] end
		if not is_set(name_from_tag) then
			local lang_2_to_ron = require("Modul:Lang/data/iana")
			if is_set(lang_2_to_ron[iso_tag]) then name_from_tag = lang_2_to_ron[iso_tag][1] end
			if not is_set(name_from_tag) then name_from_tag = iso_tag end
		end
	end
	iso_tag = iso_tag or "x-sic"
	
	local label = false
	local link = args.lang_article
	local data
	
	if (args.lang_hdr ~= "none") and (args.header ~= "none") and (args.blank_header ~= "none") then
		if any_set({ args.lang_hdr, args.header, args.blank_header }) then
			infobox_args.header1 = _(args.lang_hdr) or _(args.header) or _(args.blank_header)
		elseif is_set(args.lang_adj) then
			infobox_args.header1 = "Nume " .. args.lang_adj
			label = true
		elseif is_set(name_from_tag) then
			infobox_args.header1 = "Nume în " .. name_from_tag:lower()
			label = true
		else
			infobox_args.header1 = "Nume"
		end
		i = i + 1
	end
	
	if (args.lang_label ~= nil) and (name_from_tag ~= args.lang_label) then label = false end
	
	if label then
		local _capitalize = require("Modul:StringUtils")._capitalize
		label = _capitalize({_(args.lang_label) or name_from_tag})
	else
		label = _(args.lang_label) or name_from_tag or _(args.lang) or "Grafie originară"
	end
	
	if is_set(link) then
		label = "[[" .. link .. "|" .. label .. "]]"
	elseif label ~= "Grafie originară" then
		link = link or name_from_tag or label
		label = "[[Limba " .. link:lower() .. "|" .. label .. "]]"
	end
	
	if is_set(iso_tag) then data = _lang(args.lang, nil, args.lang_content, args.lang_content_size)
	else data = args.lang_content end
	
	i = add_label_data_pair(infobox_args, label, data, i, args.lang_content_size)
	if is_set(args.lang_rom) then
		local lang_rom_content
		if is_set(iso_tag) then lang_rom_content = _lang(iso_tag .. "-Latn", nil, args.lang_rom)
		else lang_rom_content = args.lang_rom end
		i = add_label_data_pair(infobox_args, _(args.lang_std) or "Romanizare", lang_rom_content, i)
	end
	i = add_label_data_pair(infobox_args, "[[Alfabetul Fonetic Internațional|AFI]]", args.lang_ipa, i)
	i = add_label_data_pair(infobox_args, "Sens literal", args.lang_lit, i)
	
	return frame:expandTemplate({title = "Infocasetă", args = infobox_args})
end

local function ibox_ns_generic(frame, args, data, force_header)
	if not args then args = getArgs(frame) end
	local orig_args = getArgs(frame)
	local i = 1
	local infobox_args = {}														-- table to hold arguments for frame:expandTemplate()
	ibox_boilerplate(frame, infobox_args, args)
	
	local any_args_present_out = false
	local any_args_present_in = false
	
	for k, v in ipairs(data.out or {}) do
		if is_set(args[v[1]]) then
			any_args_present_out = true
			break
		end
	end
	for k, v in ipairs(data["in"] or {}) do
		if is_set(args[v]) then
			any_args_present_in = true
			break
		end
	end
	
	-- determine whether to show the default header
	
	if (args.child == "yes") or (is_set(args[data.header]) and args[data.header] ~= "none") or any_set({orig_args.pic, orig_args.img, orig_args.image, orig_args.pic2, orig_args.img2, orig_args.image2}) then force_header = true end
	if (args[data.header] == "none") or ((not any_args_present_out) and (not any_args_present_in)) then force_header = nil end
	
	if not is_set(force_header) then args[data.header] = "none" end
	
	if (args.header ~= "none") and (args[data.header] ~= "none") then
		infobox_args.header1 = _(args.header) or _(args[data.header]) or data.default_header
		i = i + 1
	end
	
	-- takes explicit label/data pairs from the "out" table
	if data.out ~= nil then
		for __, v in ipairs(data.out) do
			local content
			if is_set(v.template) and is_set(v.template.title) and is_set(v.template.args) then
				content = frame:expandTemplate(v.template)
			else content = args[v[1]] end
			if is_set(content) then
				if is_set(v[3]) then content = _lang(v[3], v[4], content, v.size) end
				i = add_label_data_pair(infobox_args, v[2], content, i, v.size)
			end
		end
	end
	
	-- takes simple args from the "in" table and uses the /data module in order to show an optionally collapsed table of additional transcriptions
	if data["in"] ~= nil then
		if any_args_present_in then
			if args.hide == "no" then infobox_args["style" .. i] = "display:none" else infobox_args["style" .. i] = "padding:0;text-align:left" end
			infobox_args["data" .. i] = transcriptions(frame, args, data.lang)	-- needs frame so that it can frame:expandTemplate()
		end
	end
	
	return frame:expandTemplate({title = "Infocasetă", args = infobox_args})
end


--[[--------------------------< I B O X _ N S _ Z H >----------------------------------------------------------

bypasses {{Infobox Chinese/Chinese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_zh}}

]]

local function ibox_ns_zh(frame, args, force_header)
	if not args then args = getArgs(frame) end
	local i = 1
	local infobox_args = {}
	ibox_boilerplate(frame, infobox_args, args)									-- table to hold arguments for frame:expandTemplate()
	
	if (args.header ~= "none") and (args.chinese_header ~= "none") then
		infobox_args.header1 = _(args.header) or _(args.chinese_header) or "Nume chinezesc"
		i = i + 1
	end
	
	i = add_label_data_pair(infobox_args, "[[Limba chineză|Chineză]]", _lang("zh-Hani", nil, args.c, "1rem"), i, "1rem")
	
	if args.order == "st" then
		i = add_label_data_pair(infobox_args, "[[Chineză simplificată]]", _lang("zh-Hans", nil, args.s, "1rem"), i, "1rem")
		i = add_label_data_pair(infobox_args, "[[Chineză tradițională]]", _lang("zh-Hant", nil, args.t, "1rem"), i, "1rem")
	else
		i = add_label_data_pair(infobox_args, "[[Chineză tradițională]]", _lang("zh-Hant", nil, args.t, "1rem"), i, "1rem")
		i = add_label_data_pair(infobox_args, "[[Chineză simplificată]]", _lang("zh-Hans", nil, args.s, "1rem"), i, "1rem")
	end
	
	if is_set(args.phagspa) then												-- ???? this parameter isn't passed from {{Infobox Chinese}} to {{Infobox Chinese/Chinese}}
		i = add_label_data_pair(infobox_args, "[['Phags-pa]]", frame:expandTemplate({title="Phagspa", args = {"h", args.phagspa, args["phagspa-latin"], size = 12}}), i)
	end
	
	infobox_args["data" .. i] = showflag(frame, args)							-- needs frame so that it can frame:expandTemplate()
	infobox_args["style" .. i] = "display:none"
	i = i + 1
	
	i = add_label_data_pair(infobox_args, "[[Romanizarea poștală chinezească|Poștală]]", args.psp, i)
	i = add_label_data_pair(infobox_args, "Sens literal", args.l, i)
	
	if any_set({args.c, args.t, args.p, args.s, args.phagspa}) then				-- ???? phagspa not passed into {{infobox Chinese/Chinese}}  Why?
		if args.hide == "no" then infobox_args["style" .. i] = "display:none" else infobox_args["style" .. i] = "padding:0;text-align:left" end
		infobox_args["data" .. i] = transcriptions(frame, args, "zh")			-- needs frame so that it can frame:expandTemplate()
	end
	
	return frame:expandTemplate({title = "Infocasetă", args = infobox_args})
end


--[[--------------------------< I B O X _ N S _ Z H _ C O M P L E X >------------------------------------------

Skeleton used for bypassing {{Infobox Chinese}} (i.e. the header and the footer need to be added separately)

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_zh_complex}}

]]

local function ibox_ns_zh_complex(frame, args, force_header)
	if not args then args = getArgs(frame) end
	
	local children = {}
	
	if any_set({args.c, args.t, args.p, args.s}) then							-- first infobox zh/zh
		local ibox_args = ibox_zhzh_enum_params_get(args, "")					-- get the enumerated parameters (here enumerator is empty string)

		if ibox_args then
			ibox_args["hide"] = args.hide
			ibox_args["showflag"] = args.showflag
			ibox_args["order"] = args.order

			ibox_args["p"] = _(args.p) or args.hp								-- add special case parameters
			ibox_args["xej"] = _lang("zh-Arab", "rtl", args.xej)

			if args.child == "yes" then
				ibox_args["chinese_header"] = _(args["chinese_header"]) or args.name1	-- show the header name from parameter or default name from ibox_ns_zh()
			elseif any_set({													-- when any of these are set there will be other child infoboxen (or there's an image in the ibox) so ...
				args.hangul, args.hanja, args.kana, args.kanji, args.hiragana,
				args.katakana, args.kyujitai, args.shinjitai, args.tam, args.hin,
				args.san, args.pli, args.tgl, args.msa, args.mnc, args.mon, args.mong,
				args.por, args.rus, args.tha, args.tib, args.qn, args.uig, args.vie,
				args.chuhan, args.chunom, args.hn, args.zha, args["dungan-xej"],
				args.dungan, args.lao, args.khm, args.tet, args.lang1, args.lang2,
				args.lang3, args.lang4, args.lang5, args.lang6, args.lang7, args.lang8,
				args.lang9, args.lang10, args.lang11,
				args.pic, args.img, args.image, args.pic2, args.img2, args.image2
			}) then
				ibox_args["chinese_header"] = _(args["chinese_header"]) or args.name1		-- ... show the header name from parameter or default name from ibox_ns_zh()
			else
				ibox_args["chinese_header"] = _(args["chinese_header"]) or _(args.name1) or "none"	-- show the header name from parameter or no header (args.name1 missing or 'empty' - nil)
			end

			ibox_args["headercolor"] = _(args["child-hdr-color"]) or args.headercolor
			ibox_args["headerstyle"] = args.headerstyle
			ibox_args["fontcolor"] = args.fontcolor
			ibox_args["fontstyle"] = args.fontstyle
			ibox_args["cols"] = args.cols

			table.insert(children, ibox_ns_zh(frame, ibox_args, force_header))
		end
	end
	
	for i = 2, 6 do
		if any_set({args["c" .. i], args["t" .. i], args["p" .. i], args["s" .. i]}) then
			local ibox_args = ibox_zhzh_enum_params_get(args, i)				-- get the enumerated parameters

			if ibox_args then
				ibox_args["hide"] = args.hide
				ibox_args["showflag"] = args.showflag
				ibox_args["order"] = args.order 

				ibox_args["p"] = _(args["p" .. i]) or args["hp" .. i]			-- add special case parameters
				ibox_args["xej"] = _lang("zh-Arab", "rtl", args["xej" .. i])

				if is_set(args[data.zh_hdr_names[i][1]]) then
					ibox_args["chinese_header"] = args[data.zh_hdr_names[i][1]]	-- use value from parameter
				else
					ibox_args["chinese_header"] = _(args["chinese_header" .. i]) or data.zh_hdr_names[i][2]	-- use the default
				end

				ibox_args["headercolor"] = _(args["child-hdr-color"]) or args.headercolor
				ibox_args["headerstyle"] = args.headerstyle
				ibox_args["fontcolor"] = args.fontcolor
				ibox_args["fontstyle"] = args.fontstyle
				ibox_args["cols"] = args.cols
				
				table.insert(children, ibox_ns_zh(frame, ibox_args))
			end
		end
	end
	
	return table.concat(children) or ""											-- big string of zh infoboxen or an empty string if nothing was done here
end

	
--[[-------------------------< I B O X _ N S _ A R >-----------------------------------------------------------

implements {{Infobox Chinese/Arabic}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ar}}

Template:Infobox_Arabic_term/testcases

]]

local function ibox_ns_ar(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "ar",
		["header"] = "arabic_header",
		["default_header"] = "Nume arăbesc",
		["out"] = {
			{"arabic", "[[Limba arabă|Arabă]]", "ar-Arab", "rtl"},
			{"arabic_rom", "[[Romanizarea limbii arabe|Romanizare]]", "ar-Latn"},
			{"arabic_ipa", "[[Alfabetul Fonetic Internațional|AFI]]"},
			{"arabic_lit", "Sens literal"}
		},
		["in"] = {"chat", "ala-lc", "iso", "din"}
	}, force_header)
end

	
--[[-------------------------< I B O X _ N S _ A R _ N A M E >-------------------------------------------------

implements {{Infobox Arabic name}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ar_name}}

Template:Infobox_Arabic_name/testcases

]]

local function ibox_ns_ar_name(frame, args)
	if not args then
		args = getArgs(frame)
		args.arabic_headern = _(args.arabic_headern) or args.header
		args.child = _(args.child) or args.embed
	end
	local orig_args = getArgs(frame)
	local force_header = nil
	
	local data = {
		["lang"] = "ar",
		["header"] = "arabic_headern",
		["default_header"] = "Nume arăbesc",
		["out"] = {
			{{"ism", "ism-ar"}, {"Personal", "Ism"}, pair = true},
			{{"nasab", "nasab-ar"}, {"Patronim", "Nasab"}, pair = true},
			{{"kunya", "kunya-ar"}, {"Tecnonim", "Kunya"}, pair = true},
			{{"laqab", "laqab-ar"}, {"Epitet", "Laqab"}, pair = true},
			{{"nisba", "nisba-ar"}, {"Toponim", "Nisba"}, pair = true},
			{{"birthname", "birth_name"}, {"Nume la naștere"}, pair = false},
			{{"other"}, {"Alte nume"}, pair = false}
		}
	}
	
	local i = 1
	local infobox_args = {}														-- table to hold arguments for frame:expandTemplate()
	ibox_boilerplate(frame, infobox_args, args)
	
	local any_args_present_out = false
	
	for k, v in ipairs(data.out or {}) do
		if is_set(args[v[1]]) then
			any_args_present_out = true
			break
		end
	end
	
	-- determine whether to show the default header
	
	if (args.child == "yes") or (is_set(args[data.header]) and args[data.header] ~= "none") or any_set({orig_args.pic, orig_args.img, orig_args.image, orig_args.pic2, orig_args.img2, orig_args.image2}) then force_header = true end
	if (args[data.header] == "none") or (not any_args_present_out) then force_header = nil end
	
	if not is_set(force_header) then args[data.header] = "none" end
	
	if (args.header ~= "none") and (args[data.header] ~= "none") then
		infobox_args.header1 = _(args.header) or _(args[data.header]) or data.default_header
		i = i + 1
	end
	
	-- takes explicit label/data pairs from the "out" table
	for __, v in ipairs(data.out) do
		local label
		local content
		if v.pair then
			local separator = " "
			if is_set(args[v[1][1]]) and is_set(args[v[1][2]]) then
				separator = "<br>"
				content = _lang("ar-Latn", nil, args[v[1][1]]) .. separator .. _lang("ar-Arab", "rtl", args[v[1][2]])
			elseif is_set(args[v[1][1]]) then
				content = _lang("ar-Latn", nil, args[v[1][1]])
			elseif is_set(args[v[1][2]]) then
				content = _lang("ar-Arab", "rtl", args[v[1][2]])
			end
			label = v[2][1] .. separator .. "<small>(''" .. v[2][2] .. "'')</small>"
		else
			label = v[2][1]
			content = _(args[v[1][1]]) or args[v[1][2]]
		end
		if is_set(content) then i = add_label_data_pair(infobox_args, label, content, i) end
	end
	
	return frame:expandTemplate({title = "Infocasetă", args = infobox_args})
end


--[[-------------------------< I B O X _ N S _ A S >-----------------------------------------------------------

----< A S S A M E S E >----

]]

local function ibox_ns_as(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.as, args.asm }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["as-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "as",
			["lang_label"] = "Asameză",
			["lang_adj"] = "asamez",
			["lang_content"] = _(args.as) or args.asm,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["as-ipa"],
			["lang_rom"] = args["as-rom"],
			["lang_std"] = args["as-std"],
			["lang_lit"] = args["as-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ B N >-----------------------------------------------------------

----< B E N G A L I >----

]]

local function ibox_ns_bn(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.bn, args.ben }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["bn-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "bn",
			["lang_label"] = "Bengaleză",
			["lang_adj"] = "bengalez",
			["lang_content"] = _(args.bn) or args.ben,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["bn-ipa"],
			["lang_rom"] = args["bn-rom"],
			["lang_std"] = args["bn-std"],
			["lang_lit"] = args["bn-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ B O >-----------------------------------------------------------

implements {{Infobox Chinese/Tibetan}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_bo}}

]]

local function ibox_ns_bo(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "bo",
		["header"] = "tibetan_header",
		["default_header"] = "Nume tibetan",
		["out"] = {
			{"tib", "[[Limba tibetană|Tibetană]]", "bo-Tibt", size = "1.5rem"},
			{"literal_tibetan", "Sens literal"}
		},
		["in"] = {"wylie", "thdl", "zwpy", "lhasa"}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ D N G >---------------------------------------------------------

implements {{Infobox Chinese/Dunganese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_dng}}

]]

local function ibox_ns_dng(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "dng",
		["header"] = "dunganese_header",
		["default_header"] = "Nume dungan",
		["out"] = {
			{"dungan", "[[Limba dungană|Dungană]]", "dng-Cyrl"},
			{"dungan-xej", "[[Xiao'erjing]]", "dng-Arab", "rtl"},
			{"dungan-latin", "Romanizare", "dng-Latn"},
			{"dungan-han", "[[Hanzi]]", "dng-Hani", size = "1rem"}
		}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ H I >-----------------------------------------------------------

----< H I N D I >----

]]

local function ibox_ns_hi(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.hi, args.hin }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["hi-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "hi",
			["lang_label"] = "Hindi",
			["lang_content"] = _(args.hi) or args.hin,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["hi-ipa"],
			["lang_rom"] = args["hi-rom"],
			["lang_std"] = args["hi-std"],
			["lang_lit"] = args["hi-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ H O K K I E N >-------------------------------------------------

implements {{Infobox Chinese/Hokkien}}

Note that, at the time of writing this, Hokkien does not yet have a proper language code; "nan" simply
represents the parent language or language group (Southern Min)

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_hokkien}}

Template:Infobox Hokkien name/testcases

]]

local function ibox_ns_hokkien(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "hokkien",
		["header"] = "hokkien_header",
		["default_header"] = "Nume în hokkien",
		["out"] = {
			{"hanji", "[[Hàn-jī]]", "nan-Hani", size = "1rem"},
			{"poj", "[[Pe̍h-ōe-jī]]", "nan-Latn"},
			{"hanlo", "[[Hàn-lô]]", "nan"},
			{"lm", "Sens literal"}
		},
		["in"] = {"tl", "bp", "hokkienipa"}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ H O K K I E N _ C O M P L E X >---------------------------------

More complex version of ibox_ns_hokkien for use in {{Infobox Chinese}} and {{Infobox Hokkien name}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_hokkien_complex}}

]]

local function ibox_ns_hokkien_complex(frame, args, force_header)
	local directly_called = false
	
	if not args then
		args = getArgs(frame)
		directly_called = true
	end
	
	local children = {}
	local suf = { "", "pen", "born", "child", "courtesy", "stage", "dharma", "posthumous", 1, 2, 3 }
	
	for __, v in pairs(suf) do
		if any_set({args["hanji" .. v], args["poj" .. v]}) then
			local header_name
			local hokkien_header_value = args["hokkien_header" .. v]
			if directly_called then
				hokkien_header_value = _(hokkien_header_value) or args[data.hokkien_hdr_names.numbered[v]]
			end
			if v == "" and args.child ~= "yes" and not any_set({hokkien_header_value, args.pic, args.img, args.image, args.pic2, args.img2, args.image2, force_header}) then
				header_name = "none"
			else
				header_name = _(hokkien_header_value) or data.hokkien_hdr_names.special[v] or ("Nume" .. ((v ~= "") and " alternativ" or "") .. " în hokkien")
			end
			local ibox_args = {
				["hokkien_header"] = header_name,
				["headercolor"] = args.headercolor,
				["headerstyle"] = args.headerstyle,
				["fontcolor"] = args.fontcolor,
				["fontstyle"] = args.fontstyle,
				["hide"] = args.hide,
				["cols"] = args.cols,
				["hanji"] = args["hanji" .. v],
				["poj"] = args["poj" .. v],
				["hanlo"] = args["hanlo" .. v],
				["tl"] = args["tl" .. v],
				["bp"] = args["bp" .. v],
				["hokkienipa"] = args["hokkienipa" .. v],
				["lm"] = args["lm" .. v]
			}
			table.insert(children, ibox_ns_hokkien(frame, ibox_args, force_header))
		end
	end
	
	return table.concat(children) or ""
end


--[[-------------------------< I B O X _ N S _ I D >-----------------------------------------------------------

----< I N D O N E S I A N >----

]]

local function ibox_ns_id(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.id, args.ind }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["id-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "id",
			["lang_label"] = "Indoneziană",
			["lang_adj"] = "indonezian",
			["lang_content"] = _(args.id) or args.ind,
			["lang_ipa"] = args["id-ipa"],
			["lang_rom"] = args["id-rom"],
			["lang_std"] = args["id-std"],
			["lang_lit"] = args["id-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ J A >-----------------------------------------------------------

implements {{Infobox Chinese/Japanese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ja}}

]]

local function ibox_ns_ja(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "ja",
		["header"] = "japanese_header",
		["default_header"] = "Nume japonez",
		["out"] = {
			{"kanji", "[[Kanji]]", "ja-Jpan", size = "1rem"},
			{"kana", "[[Kana]]", "ja-Hrkt", size = "1rem"},
			{"hiragana", "[[Hiragana]]", "ja-Hira", size = "1rem"},
			{"katakana", "[[Katakana]]", "ja-Kana", size = "1rem"},
			{"kyujitai", "[[Kyūjitai]]", "ja-Hani", size = "1rem"},
			{"shinjitai", "[[Shinjitai]]", "ja-Hani", size = "1rem"},
			{"lja", "Sens literal"}
		},
		["in"] = {"romaji", "revhep", "tradhep", "kunrei", "nihon"}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ J A _ C O M P L E X >-------------------------------------------

More complex version of ibox_ns_ja for use in {{Infobox Chinese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ja_complex}}

]]

local function ibox_ns_ja_complex(frame, args, force_header)
	if not args then args = getArgs(frame) end
	
	local children = {}
	local suf = { "", 2, 3, 4, 5, 6 }
	
	for __, v in pairs(suf) do
		if any_set({args["kanji" .. v], args["kana" .. v], args["hiragana" .. v], args["katakana" .. v], args["kyujitai" .. v], args["shinjitai" .. v], args["lja" .. v]}) then
			local header_name
			if v == "" and args.child ~= "yes" and not any_set({args["japanese_header" .. v], args.pic, args.img, args.image, args.pic2, args.img2, args.image2, force_header}) then
				header_name = "none"
			else
				header_name = _(args["japanese_header" .. v]) or ("Nume japonez" .. ((v ~= "") and " alternativ" or ""))
			end
			local ibox_args = {
				["japanese_header"] = header_name,
				["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
				["headerstyle"] = args.headerstyle,
				["fontcolor"] = args.fontcolor,
				["fontstyle"] = args.fontstyle,
				["hide"] = args.hide,
				["cols"] = args.cols,
				["kanji"] = args["kanji" .. v],
				["kyujitai"] = args["kyujitai" .. v],
				["shinjitai"] = args["shinjitai" .. v],
				["kana"] = args["kana" .. v],
				["hiragana"] = args["hiragana" .. v],
				["katakana"] = args["katakana" .. v],
				["romaji"] = args["romaji" .. v],
				["revhep"] = args["revhep" .. v],
				["tradhep"] = args["tradhep" .. v],
				["kunrei"] = args["kunrei" .. v],
				["nihon"] = args["nihon" .. v],
				["lja"] = args["lja" .. v]
			}
			table.insert(children, ibox_ns_ja(frame, ibox_args, force_header))
		end
	end
	
	return table.concat(children) or ""											-- big string of ja infoboxen or an empty string if nothing was done here
end


--[[-------------------------< I B O X _ N S _ K M >-----------------------------------------------------------

----< K H M E R >----

]]

local function ibox_ns_km(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.km, args.khm }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["km-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "km",
			["lang_label"] = "Khmeră",
			["lang_adj"] = "khmer",
			["lang_content"] = _(args.km) or args.khm,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["km-ipa"],
			["lang_rom"] = args["km-rom"],
			["lang_std"] = args["km-std"],
			["lang_lit"] = args["km-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ K O >-----------------------------------------------------------

implements {{Infobox Chinese/Korean}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ko}}

]]

local function ibox_ns_ko(frame, args, force_header)
	if not args then
		args = getArgs(frame)
		--[[if is_set(args.context) then
			if args.context == "n" or args.context == "nk" or args.context:lower() == "north" or args.context:lower() == "dprk" then
				args.northkorea = "yes"
			elseif args.context:lower() == "old" then
				args.northkorea = "old"
			else
				args.northkorea = args.context
			end
		end--]]
	end
	local hangul_name = "[[Hangul]]"
	local hanja_name = "[[Hanja]]"
	if is_set(args.northkorea) then
		if args.northkorea == "yes" then
			hangul_name = "[[Hangul|Chosŏn'gŭl]]"
			hanja_name = "[[Hanja|Hancha]]"
		elseif args.northkorea == "old" then
			hangul_name = "[[Hangul|Hunminjeongeum]]"
		end
	end
	return ibox_ns_generic(frame, args, {
		["lang"] = "ko",
		["header"] = "korean_header",
		["default_header"] = "Nume coreean",
		["out"] = {
			{"hangul", hangul_name, "ko-Hang", size = "1rem"},
			{"hanja", hanja_name, "ko-Hani", size = "1rem"},
			{"lk", "Sens literal"}
		},
		["in"] = {"mr", "rr", "nr", "koreanipa"}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ K O _ C O M P L E X >-------------------------------------------

More complex version of ibox_ns_ko for use in {{Infobox Chinese}} and {{Infobox Korean name}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ko_complex}}

]]

local function ibox_ns_ko_complex(frame, args, force_header, override)
	local directly_called = false
	
	if not args then
		args = getArgs(frame)
		directly_called = true
	end
	
	local pref
	local def_hdr
	local def_nk
	local def_ctx
	
	if not override then
		pref = ""
		def_hdr = "Nume coreean"
	else
		pref = override.pref
		def_hdr = override.def_hdr
		def_nk = override.def_nk
		def_ctx = override.def_ctx
	end
	
	local children = {}
	local suf = { "", "ho", "born", "a", "ja", "stage", "gye", "ph", 1, 2, 3 }
	
	for __, v in pairs(suf) do
		if any_set({args[pref .. "hanja" .. v], args[pref .. "hangul" .. v]}) then
			local header_name
			local korean_header_value = args[pref .. "korean_header" .. v]
			if directly_called then
				korean_header_value = _(korean_header_value) or args[data.ko_hdr_names.numbered[v]]
			end
			if v == "" and args.child ~= "yes" and not any_set({korean_header_value, args.pic, args.img, args.image, args.pic2, args.img2, args.image2, force_header}) then
				header_name = "none"
			else
				header_name = _(korean_header_value) or data.ko_hdr_names.special[v] or (def_hdr .. ((v ~= "") and " alternativ" or ""))
			end
			local ibox_args = {
				["korean_header"] = header_name,
				["headercolor"] = args.headercolor,
				["headerstyle"] = args.headerstyle,
				["fontcolor"] = args.fontcolor,
				["fontstyle"] = args.fontstyle,
				["cols"] = args.cols,
				["hangul"] = args[pref .. "hangul" .. v],
				["hanja"] = args[pref .. "hanja" .. v],
				["rr"] = args[pref .. "rr" .. v],
				["mr"] = args[pref .. "mr" .. v],
				["nr"] = args[pref .. "nr" .. v],
				["koreanipa"] = args[pref .. "koreanipa" .. v],
				["lk"] = args[pref .. "lk" .. v]
			}
			if directly_called then
				local context_value = args[pref .. "context" .. v] or args[pref .. "context"] or def_ctx
				local nk_value = nil
				if is_set(context_value) then
					if context_value == "n" or context_value == "nk" or context_value:lower() == "north" or context_value:lower() == "dprk" then
						nk_value = "yes"
					elseif context_value:lower() == "old" then
						nk_value = "old"
					else
						nk_value = context_value
					end
				end
				ibox_args.northkorea = nk_value
				ibox_args.hide = _(args.hide) or "no"
			else
				ibox_args.northkorea = _(args[pref .. "northkorea" .. v]) or _(args[pref .. "northkorea"]) or def_nk
				ibox_args.hide = args.hide
			end
			table.insert(children, ibox_ns_ko(frame, ibox_args, force_header))
		end
	end
	
	return table.concat(children) or ""
end


--[[-------------------------< I B O X _ N S _ K O _ C O M P L E X _ 2 >---------------------------------------

Special version of ibox_ns_ko_complex specifically for Chinese-Korean names in {{Infobox Chinese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ko_complex_2}}

]]

local function ibox_ns_ko_complex_2(frame, args, force_header)
	return ibox_ns_ko_complex(frame, args, force_header, { pref = "cn", def_hdr = "Nume chino-coreean", def_nk = "yes", def_ctx = "n" })
end


--[[-------------------------< I B O X _ N S _ K O _ C O M P L E X _ 3 >---------------------------------------

Special version of ibox_ns_ko_complex specifically for North Korean names in {{Infobox Chinese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ko_complex_3}}

]]

local function ibox_ns_ko_complex_3(frame, args, force_header)
	return ibox_ns_ko_complex(frame, args, force_header, { pref = "nk", def_hdr = "Nume nord-coreean", def_nk = "yes", def_ctx = "n" })
end


--[[-------------------------< I B O X _ N S _ K O _ C O M P L E X _ 4 >---------------------------------------

Special version of ibox_ns_ko_complex specifically for South Korean names in {{Infobox Chinese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ko_complex_4}}

]]

local function ibox_ns_ko_complex_4(frame, args, force_header)
	return ibox_ns_ko_complex(frame, args, force_header, { pref = "sk", def_hdr = "Nume sud-coreean", def_nk = "no", def_ctx = "s" })
end


--[[-------------------------< I B O X _ N S _ L O >-----------------------------------------------------------

----< L A O >----

]]

local function ibox_ns_lo(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.lo, args.lao }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["lo-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "lo",
			["lang_label"] = "Laoțiană",
			["lang_adj"] = "laoțian",
			["lang_content"] = _(args.lo) or args.lao,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["lo-ipa"],
			["lang_rom"] = args["lo-rom"],
			["lang_std"] = args["lo-std"],
			["lang_lit"] = args["lo-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ M N >-----------------------------------------------------------

implements {{Infobox Chinese/Mongolian}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_mn}}

]]

local function ibox_ns_mn(frame, args, force_header)
	if not args then args = getArgs(frame) end
	return ibox_ns_generic(frame, args, {
		["lang"] = "mn",
		["header"] = "mongolian_header",
		["default_header"] = "Nume mongol",
		["out"] = {
			{"mon", "Grafie chirilică", "mn-Cyrl"},
			{"mong", "Grafie mongolă", template = _(args.mong) and {title = "MongolUnicode", args = {args.mong, lang = "mn-Mong", size = "1.5rem"}}},
			{"monr", "[[Romanizarea SASM/GNC#Mongoleză|SASM/GNC]]", "mn-Latn"}
		}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ M N C >---------------------------------------------------------

implements {{Infobox Chinese/Manchu}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_mnc}}

]]

local function ibox_ns_mnc(frame, args, force_header)
	if not args then args = getArgs(frame) end
	return ibox_ns_generic(frame, args, {
		["lang"] = "mnc",
		["header"] = "manchu_header",
		["default_header"] = "Nume manciurian",
		["out"] = {
			{"mnc", "Grafie manciuriană", template = _(args.mnc) and {title = "MongolUnicode", args = {args.mnc, lang = "mnc", size = "1.5rem"}}},
			{"mnc_rom", "Romanizare", "mnc-Latn"},
			{"mnc_a", "Abkai", "mnc-Latn"},
			{"mnc_v", "Möllendorff", "mnc-Latn"}
		}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ M S   >---------------------------------------------------------

----< M A L A Y >----

]]

local function ibox_ns_ms(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.ms, args.msa }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["ms-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "ms",
			["lang_label"] = "Malaeză",
			["lang_adj"] = "malaez",
			["lang_content"] = _(args.ms) or args.msa,
			["lang_ipa"] = args["ms-ipa"],
			["lang_rom"] = args["ms-rom"],
			["lang_std"] = args["ms-std"],
			["lang_lit"] = args["ms-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ M Y >-----------------------------------------------------------

implements {{Infobox Chinese/Burmese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_my}}

]]

local function ibox_ns_my(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "my",
		["header"] = "burmese_header",
		["default_header"] = "Nume birman",
		["out"] = {
			{"my", "[[Limba birmană|Birmană]]", "my-Mymr", size = "1rem"},
			{"bi", "[[Alfabetul Fonetic Internațional|AFI]]"}
		}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ N E >-----------------------------------------------------------

----< N E P A L I >----

]]

local function ibox_ns_ne(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.ne, args.nep }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["ne-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "ne",
			["lang_label"] = "Nepaleză",
			["lang_adj"] = "nepalez",
			["lang_content"] = _(args.ne) or args.nep,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["ne-ipa"],
			["lang_rom"] = args["ne-rom"],
			["lang_std"] = args["ne-std"],
			["lang_lit"] = args["ne-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ P I >-----------------------------------------------------------

----< P A L I >----

]]

local function ibox_ns_pi(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.pi, args.pli }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["pi-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "pi",
			["lang_label"] = "Pali",
			["lang_content"] = _(args.pi) or args.pli,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["pi-ipa"],
			["lang_rom"] = args["pi-rom"],
			["lang_std"] = args["pi-std"],
			["lang_lit"] = args["pi-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ P T >-----------------------------------------------------------

----< P O R T U G U E S E >----

]]

local function ibox_ns_pt(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.pt, args.por }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["pt-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "pt",
			["lang_label"] = "Portugheză",
			["lang_adj"] = "portughez",
			["lang_content"] = _(args.pt) or args.por,
			["lang_ipa"] = args["pt-ipa"],
			["lang_rom"] = args["pt-rom"],
			["lang_std"] = args["pt-std"],
			["lang_lit"] = args["pt-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ P R A >---------------------------------------------------------

----< P R A K R I T >----

]]

local function ibox_ns_pra(frame, args)
	if not args then args = getArgs(frame) end
	if is_set(args.pra) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["pra-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "pra",
			["lang_label"] = "Pracrită",
			["lang_adj"] = "pracrit",
			["lang_content"] = args.pra,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["pra-ipa"],
			["lang_rom"] = args["pra-rom"],
			["lang_std"] = args["pra-std"],
			["lang_lit"] = args["pra-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ R U >-----------------------------------------------------------

implements {{Infobox Chinese/Russian}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ru}}

]]

local function ibox_ns_ru(frame, args, force_header)
	if not args then args = getArgs(frame) end
	if is_set(args.rus) and (args.rusr == nil) then
		args.rusr = frame:expandTemplate({title = "Transliterează", args = { args.rus, "ru" }})
	end
	return ibox_ns_generic(frame, args, {
		["lang"] = "ru",
		["header"] = "russian_header",
		["default_header"] = "Nume rusesc",
		["out"] = {
			{"rus", "[[Limba rusă|Rusă]]", "ru-Cyrl"},
			{"rusr", "Romanizare", "ru-Latn"},
			{"rusipa", "[[Alfabetul Fonetic Internațional|AFI]]"},
			{"ruslit", "Sens literal"}
		},
		["in"] = {"scientific", "iso", "gost", "bgn/pcgn"}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ S A >-----------------------------------------------------------

----< S A N S K R I T >----

]]

local function ibox_ns_sa(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.sa, args.san }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["sa-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "sa",
			["lang_label"] = "Sanscrită",
			["lang_adj"] = "sanscrit",
			["lang_content"] = _(args.sa) or args.san,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["sa-ipa"],
			["lang_rom"] = args["sa-rom"],
			["lang_std"] = args["sa-std"],
			["lang_lit"] = args["sa-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ T A >-----------------------------------------------------------

----< T A M I L >----

]]

local function ibox_ns_ta(frame, args)
	if not args then args = getArgs(frame) end
	if any_set({ args.ta, args.tam }) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["ta-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "ta",
			["lang_label"] = "Tamilă",
			["lang_adj"] = "tamil",
			["lang_content"] = _(args.ta) or args.tam,
			["lang_content_size"] = "1rem",
			["lang_ipa"] = args["ta-ipa"],
			["lang_rom"] = args["ta-rom"],
			["lang_std"] = args["ta-std"],
			["lang_lit"] = args["ta-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ T E T >---------------------------------------------------------

----< T E T U M >----

]]

local function ibox_ns_tet(frame, args)
	if not args then args = getArgs(frame) end
	if is_set(args.tet) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["tet-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "tet",
			["lang_label"] = "Tetum",
			["lang_content"] = args.tet,
			["lang_ipa"] = args["tet-ipa"],
			["lang_rom"] = args["tet-rom"],
			["lang_std"] = args["tet-std"],
			["lang_lit"] = args["tet-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ T H >-----------------------------------------------------------

implements {{Infobox Chinese/Thai}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_th}}

]]

local function ibox_ns_th(frame, args, force_header)
	if not args then args = getArgs(frame) end
	args.th = _(args.th) or _(args.tha)
	return ibox_ns_generic(frame, args, {
		["lang"] = "th",
		["header"] = "thai_header",
		["default_header"] = "Nume thailandez",
		["out"] = {
			{"th", "[[Limba thailandeză|Thailandeză]]", "th-Thai", size = "1rem"},
			{"rtgs", "[[Sistemul regal general de transcriere a limbii thailandeze|RTGS]]", "th-Latn"},
			{"rom", "Romanizare", "th-Latn"},
			{"ipa", "[[Alfabetul Fonetic Internațional|AFI]]"},
			{"lit", "Sens literal"}
		}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ T L >-----------------------------------------------------------

----< F I L I P I N O >----

]]

local function ibox_ns_tl(frame, args)
	if not args then args = getArgs(frame) end
	if is_set(args.tgl) then
		return ibox_ns_blank(frame, {
			["lang_hdr"] = args["tl-hdr"],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["cols"] = args.cols,
			["lang"] = "tl",
			["lang_label"] = "Tagalog",
			["lang_content"] = args.tgl,
			["lang_ipa"] = args["tl-ipa"],
			["lang_rom"] = args["tl-rom"],
			["lang_std"] = args["tl-std"],
			["lang_lit"] = args["tl-lit"]
		})
	end
end


--[[-------------------------< I B O X _ N S _ U G >-----------------------------------------------------------

implements {{Infobox Chinese/Uyghur}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_ug}}

]]

local function ibox_ns_ug(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "ug",
		["header"] = "uyghur_header",
		["default_header"] = "Nume uigur",
		["out"] = {
			{"uig", "[[Limba uigură|Uigură]]", "ug-Arab"},
			{"lu", "Sens literal"}
		},
		["in"] = {"uly", "uyy", "sgs", "usy", "uipa"}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ U K >-----------------------------------------------------------

implements {{Infobox Chinese/Ukrainian}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_uk}}

]]

local function ibox_ns_uk(frame, args, force_header)
	if not args then args = getArgs(frame) end
	if is_set(args.ukr) and (args.ukrr == nil) then
		args.ukrr = frame:expandTemplate({title = "Transliterează", args = { args.ukr, "uk" }})
	end
	if is_set(args.dstu) then
		if string.sub(args.dstu, 1, 1) == "*" then
			args.dstu = string.sub(args.dstu, 2)
		else
			local dia = args.dstu
			local nodia = mw.ustring.gsub(dia, ".", {
				["ğ"] = "gh", ["ž"] = "zh", ["ï"] = "ji", ["x"] = "kh", ["č"] = "ch", ["š"] = "sh", ["ŝ"] = "shch",
				["Ğ"] = "Gh", ["Ž"] = "Zh", ["Ï"] = "Ji", ["X"] = "Kh", ["Č"] = "Ch", ["Š"] = "Sh", ["Ŝ"] = "Shch"
			})
			if dia ~= nodia then
				args.dstu = "'''A:''' " .. dia .. "<br>'''B:''' " .. nodia
			end
		end
	end
	return ibox_ns_generic(frame, args, {
		["lang"] = "uk",
		["header"] = "ukrainian_header",
		["default_header"] = "Nume ucrainean",
		["out"] = {
			{"ukr", "[[Limba ucraineană|Ucraineană]]", "uk-Cyrl"},
			{"ukrr", "Romanizare", "uk-Latn"},
			{"ukripa", "[[Alfabetul Fonetic Internațional|AFI]]"},
			{"ukrlit", "Sens literal"}
		},
		["in"] = {"ukrnat", "dstu", "ukrsci", "ukriso", "ukrbgn"}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ V I >-----------------------------------------------------------

implements {{Infobox Chinese/Vietnamese}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_vi}}

]]

local function ibox_ns_vi(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "vi",
		["header"] = "vietnamese_header",
		["default_header"] = "Nume vietnamez",
		["out"] = {
			{"vie", "[[Limba vietnameză|Vietnameză]]", "vi"},
			{"qn", "[[Alfabetul vietnamez]]", "vi-Latn"},
			{"hn", "[[Hán-Nôm]]", "vi-Hani", size = "1rem"},
			{"chuhan", "[[Chữ Hán]]", "vi-Hani", size = "1rem"},
			{"chunom", "[[Chữ Nôm]]", "vi-Hani", size = "1rem"},
			{"lqn", "Sens literal"}
		}
	}, force_header)
end


--[[-------------------------< I B O X _ N S _ Z A >-----------------------------------------------------------

implements {{Infobox Chinese/Zhuang}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_za}}

]]

local function ibox_ns_za(frame, args, force_header)
	return ibox_ns_generic(frame, args, {
		["lang"] = "za",
		["header"] = "zhuang_header",
		["default_header"] = "Nume în zhuang",
		["out"] = {
			{"zha", "[[Limba zhuang|Zhuang]]", "za-Latn"},
			{"zha57", "Ortografia din 1957", "za"},
			{"sd", "[[Sawndip]]", "za-Hani", size = "1rem"}
		}
	}, force_header)
end


--[[==========================<< I B O X _ N S >>==============================================================

implements {{Infobox Chinese}}

TODO: do a valueFunc () on getArgs() so that when they are blank we acknowledge the blank (|name1= present with
empty string or whitespace as assigned value)

]]

local function ibox_ns(frame, args)
	if not args then args = getArgs(frame) end									-- also gets parent frame params (there are no frame params for this function)
	local infobox_args = {}														-- table to hold arguments for ibox_ns frame:expandTemplate()
	local children = {}															-- table of returned infoboxen text

----------< L A N G U A G E   I N F O B O X E N >----------

	local lang_iboxen = {														-- table of codes used in |ibox-order= and their matching function pointers
		["ar"] = ibox_ns_ar, ["as"] = ibox_ns_as, ["bn"] = ibox_ns_bn, ["bo"] = ibox_ns_bo, ["dng"] = ibox_ns_dng,
		["hi"] = ibox_ns_hi, ["id"] = ibox_ns_id, ["ja"] = ibox_ns_ja_complex, ["km"] = ibox_ns_km, ["ko1"] = ibox_ns_ko_complex,
		["ko2"] = ibox_ns_ko_complex_2, ["ko3"] = ibox_ns_ko_complex_3, ["ko4"] = ibox_ns_ko_complex_4, ["lo"] = ibox_ns_lo, ["mn"] = ibox_ns_mn,
		["mnc"] = ibox_ns_mnc, ["ms"] = ibox_ns_ms, ["my"] = ibox_ns_my, ["ne"] = ibox_ns_ne, ["pi"] = ibox_ns_pi,
		["pra"] = ibox_ns_pra, ["pt"] = ibox_ns_pt, ["ru"] = ibox_ns_ru, ["sa"] = ibox_ns_sa, ["ta"] = ibox_ns_ta,
		["tet"] = ibox_ns_tet, ["th"] = ibox_ns_th, ["tl"] = ibox_ns_tl, ["ug"] = ibox_ns_ug, ["uk"] = ibox_ns_uk,
		["vi"] = ibox_ns_vi, ["za"] = ibox_ns_za, ["zh"] = ibox_ns_zh_complex
	}

	local lang_ibox_order = {													-- default list of lang ibox calling functions as used by legacy {{Infobox Chinese}}
		ibox_ns_zh_complex, ibox_ns_my, ibox_ns_bo, ibox_ns_dng, ibox_ns_vi, ibox_ns_th, ibox_ns_za, ibox_ns_ko_complex, ibox_ns_ko_complex_2, ibox_ns_ko_complex_3, ibox_ns_ko_complex_4, ibox_ns_mn, ibox_ns_ja_complex, ibox_ns_ms, ibox_ns_id, ibox_ns_tl,
		ibox_ns_ug, ibox_ns_mnc, ibox_ns_bn, ibox_ns_as, ibox_ns_ne, ibox_ns_pra, ibox_ns_ta, ibox_ns_hi, ibox_ns_sa, ibox_ns_pi, ibox_ns_pt, ibox_ns_ru, ibox_ns_uk, ibox_ns_lo, ibox_ns_km, ibox_ns_tet
	}
	
	if is_set(args["ibox-order"]) then											-- parameter value is comma-separated list of lang iboxen to render and their order
		local t = mw.text.split(args["ibox-order"], "%s*,%s*")					-- make a table from the list
		lang_ibox_order = {}													-- reset; don't use default list
		for __, v in ipairs(t) do												-- spin through the lang_ibox_order list in order and 
			if lang_iboxen[v] then												-- if there is a matching ibox function
				table.insert(lang_ibox_order, lang_iboxen[v])					-- add it to the list of functions to call; TODO: error message when specified language does not exist?
			end
		end
	end	

	for __, ibox_func in ipairs(lang_ibox_order) do								-- call each function in the list in the list order
		table.insert(children, ibox_func(frame, args, true) or "")				-- add ibox string (or empty string when there is no ibox string)
	end

----------< B L A N K #   I N F O B O X E N >----------

	local i = 1																	-- blank ibox enumerator
	while _(args["lang" .. i]) and (_(args["lang-content" .. i]) or _(args["lang" .. i .. "_content"])) do	-- for as many ibox blank as there are ...
		local ibox_args = {
			["lang_hdr"] = args["lang-hdr" .. i],
			["headercolor"] = _(args["child-hdr-color"]) or args.headercolor,
			["headerstyle"] = args.headerstyle,
			["fontcolor"] = args.fontcolor,
			["fontstyle"] = args.fontstyle,
			["lang"] = args["lang" .. i],
			["lang_label"] = args["lang-lbl" .. i],
			["lang_article"] = args["lang-article" .. i],
			["lang_adj"] = args["lang-adj" .. i],
			["lang_content"] = _(args["lang-content" .. i]) or args["lang" .. i .. "_content"],
			["lang_content_size"] = _(args["lang-content-size" .. i]) or args["lang" .. i .. "_content_size"],
			["lang_ipa"] = args["lang-ipa" .. i],
			["lang_rom"] = args["lang-rom" .. i],
			["lang_std"] = args["lang-std" .. i],
			["lang_lit"] = args["lang-lit" .. i],
			["cols"] = args.cols
		}
			
		table.insert(children, ibox_ns_blank(frame, ibox_args, true))
		i = i + 1																-- bump the enumerator
	end

----------< R E N D E R >----------

	return table.concat(children)												-- concatenate all of the children together into a ginormous string
end


--[[-------------------------< I B O X _ N S _ H E A D E R >---------------------------------------------------

bypasses {{Infobox Chinese/Header}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_header}}

]]

local function ibox_ns_header(frame, args)
	if not args then args = getArgs(frame) end
	
	if (args.child == "yes") then return "" end
	
	local bodyclass = "infocaseta"
	
	if is_set(args.collapse) then
		if args.collapse == "yes" then bodyclass = bodyclass .. " mw-collapsible mw-collapsed"
		elseif args.collapse == "no" then bodyclass = bodyclass .. " mw-collapsible"
		end
	end
	
	local infobox_args = {														-- table to hold arguments for frame:expandTemplate()
		decat = "yes",
		bodyclass = bodyclass,
		antet = "simplu",
		["culoare cadru"] = _(args.headercolor) or "#b0c4de",					-- TODO: #define various colors in a common config location; and function?
		headerstyle = args.headerstyle,
		["culoare text"] = args.fontcolor,
		labelstyle = "padding:2px 0.1em;",
		parent_colspan = args.cols
	}
	
	if args.title == nil then
		infobox_args.title = mw.title.getCurrentTitle().fullText
	elseif args.title == "" then
		infobox_args.title = "&#x20;"
		infobox_args.titlestyle = "display:none"
	else
		infobox_args.title = args.title
	end
	
	if any_set({args.pic, args.img, args.image}) then
		infobox_args.image = frame:callParserFunction({name = "#invoke:InfoboxImage",
		args = {
			"InfoboxImage",
			image = _(args.pic) or _(args.img) or args.image,
			sizedefault = "frameless",
			size = _(args.picsize) or _(args.imgwidth) or args.image_size,
			upright = args.picupright,
			alt = _(args.picalt) or args.pictooltip
		}})
		infobox_args.caption = _(args.piccap) or args.caption
	end
	
	if any_set({args.pic2, args.img2, args.image2}) then
		infobox_args.image2 = frame:callParserFunction({name = "#invoke:InfoboxImage",
		args = {
			"InfoboxImage",
			image = _(args.pic2) or _(args.img2) or args.image2,
			sizedefault = "frameless",
			size = _(args.picsize2) or _(args.imgwidth2) or args.image_size2,
			upright = args.picupright2,
			alt = _(args.picalt2) or args.pictooltip2
		}})
		infobox_args.caption2 = _(args.piccap2) or args.caption2
	end
	
	return tostring(frame:expandTemplate({ title = "Infocasetă", args = infobox_args })
		:gsub("\127'\"`UNIQ%-%-templatestyles%-[A-F0-9]+%-QINU`\"'\127$", "")
		:gsub("</table>$", "<tr><td colspan=\"" .. (_(args.cols) or 2) .. "\"></td></tr>")
	)
end


--[[-------------------------< I B O X _ N S _ F O O T E R >---------------------------------------------------

bypasses {{Infobox Chinese/Footer}}

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_ns_footer}}

]]

local function ibox_ns_footer(frame, args)
	if not args then args = getArgs(frame) end
	
	if (args.child == "yes") then return "" end
	
	local infobox_args = {														-- table to hold arguments for frame:expandTemplate()
		decat = "yes",
		titlestyle = "display:none",
		["culoare cadru"] = _(args.headercolor) or "#b0c4de",					-- TODO: #define various colors in a common config location; and function?
		headerstyle = args.headerstyle,
		["culoare text"] = args.fontcolor,
		below = args.footnote,
		doc = args.doc,
		parent_colspan = args.cols
	}
	
	return tostring(frame:expandTemplate({ title = "Infocasetă", args = infobox_args }):gsub("^<table[^>]*><td[^>]*></td>", ""))
end


--[[-------------------------< I B O X _ H R >-----------------------------------------------------------------

Adds a horizontal line if needed in custom infoboxes

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_hr}}

]]

local function ibox_hr(frame, args)
	if not args then args = getArgs(frame) end
	
	local headercolor = _(args.headercolor) or "#b0c4de"
	if headercolor:sub(1, 1) ~= "#" then headercolor = "#" .. headercolor end
	
	local infobox_args = {
		child = "yes",
		decat = "yes",
		parent_colspan = args.cols,
		data1 = tostring(mw.html.create("hr")
					:css("height", "2px")
					:css("background-color", headercolor)),
		style1 = "padding:0"
	}
	
	return frame:expandTemplate({ title = "Infocasetă", args = infobox_args })
end


--[[-------------------------< I B O X _ P I C >---------------------------------------------------------------

Used for dynamic addition of images in custom infoboxes

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_pic}}

]]

local function ibox_pic(frame, args)
	if not args then args = getArgs(frame) end
	
	local image = frame:callParserFunction({name = "#invoke:InfoboxImage",
	args = {
		"InfoboxImage",
		image = _(args.pic) or _(args.img) or args.image,
		sizedefault = "frameless",
		size = _(args.picsize) or _(args.imgwidth) or args.image_size,
		upright = args.picupright,
		alt = _(args.picalt) or args.pictooltip
	}})
	
	local caption = _(args.piccap) or args.caption
	if not is_set(caption) then
		caption = ""
	else
		caption = "<br><span>" .. caption .. "</span>"
	end
	
	local infobox_args = {
		child = "yes",
		decat = "yes",
		parent_colspan = args.cols,
		data1 = image .. caption
	}
	
	return frame:expandTemplate({ title = "Infocasetă", args = infobox_args })
end


--[[-------------------------< I B O X _ P L A I N >-----------------------------------------------------------

Used for dynamic addition of wiki- or plain text into a custom table

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_plain}}

]]

local function ibox_plain(frame, args)
	if not args then args = getArgs(frame) end
	
	local infobox_args = {
		child = "yes",
		decat = "yes",
		parent_colspan = args.cols,
		data1 = args.content,
		style1 = args.style
	}
	
	return frame:expandTemplate({ title = "Infocasetă", args = infobox_args })
end


--[[-------------------------< I B O X _ C O N S T R U C T O R >-----------------------------------------------

Helps create super custom infoboxes.

Each anonymous/numbered arg corresponds to a pre-defined submodule
f.ex. |ko or |1=ko means the first module will be a Korean name submodule

Arguments can be specified globally by not doing anything special (f.ex. |cols=3 will make all submodules span
over three columns), or locally by prefixing them with the name of the corresponding submodule and a colon
(f.ex. if |1=ko, then |1:hangul will specify a Hangul form in the first submodule only)

This dual system can be used to make sure that headers and horizontal lines will always have the correct color
and colspan, while multiple instances of the same language submodule (f.ex. multiple Korean names) can receive
different arguments.
(f.ex.
|ko|ja|ko|1:hangul=선배|kanji=先輩|3:hangul=전배
will make sure that the first and the third module will not be identical; |2:kanji can also be used, although
it's superfluous in this case)

Module entry point

{{#invoke:Infocaseta Nume străin|ibox_constructor}}

]]

local function ibox_constructor(frame, args)
	if not args then args = getArgs(frame) end
	
	local modules = {}
	local global_args = {}
	local parts = {}
	
	local funcs = {
		["blank"] = ibox_ns_blank,
		["m"] = ibox_ns,
		["zh"] = ibox_ns_zh,
		["zh-c"] = ibox_ns_zh_complex,
		["ar"] = ibox_ns_ar,
		["ar-n"] = ibox_ns_ar_name,
		["as"] = ibox_ns_as,
		["bn"] = ibox_ns_bn,
		["bo"] = ibox_ns_bo,
		["dng"] = ibox_ns_dng,
		["hi"] = ibox_ns_hi,
		["id"] = ibox_ns_id,
		["ja"] = ibox_ns_ja,
		["ja-c"] = ibox_ns_ja_complex,
		["km"] = ibox_ns_km,
		["ko"] = ibox_ns_ko,
		["ko-c"] = ibox_ns_ko_complex,
		["ko-c2"] = ibox_ns_ko_complex_2,
		["ko-c3"] = ibox_ns_ko_complex_3,
		["ko-c4"] = ibox_ns_ko_complex_4,
		["lo"] = ibox_ns_lo,
		["mn"] = ibox_ns_mn,
		["mnc"] = ibox_ns_mnc,
		["ms"] = ibox_ns_ms,
		["my"] = ibox_ns_my,
		["nan"] = ibox_ns_hokkien,
		["nan-c"] = ibox_ns_hokkien_complex,
		["ne"] = ibox_ns_ne,
		["pi"] = ibox_ns_pi,
		["pt"] = ibox_ns_pt,
		["pra"] = ibox_ns_pra,
		["ru"] = ibox_ns_ru,
		["sa"] = ibox_ns_sa,
		["ta"] = ibox_ns_ta,
		["tet"] = ibox_ns_tet,
		["th"] = ibox_ns_th,
		["tl"] = ibox_ns_tl,
		["ug"] = ibox_ns_ug,
		["uk"] = ibox_ns_uk,
		["vi"] = ibox_ns_vi,
		["za"] = ibox_ns_za,
		["-"] = ibox_hr,
		["pic"] = ibox_pic,
		["plain"] = ibox_plain
	}
	
	for k, v in pairs(args) do
		if type(k) == "number" then
			if modules[k] == nil then modules[k] = { args = {} } end
			modules[k].func = funcs[v] or funcs.plain
		else
			local colon_idx = string.find(k, ":", 1, true)
			if colon_idx == nil or colon_idx == 1 then
				global_args[k] = v
			else
				local pref = string.sub(k, 1, colon_idx - 1)
				if (pref:find("%D") ~= nil) or (pref ~= tostring(tonumber(pref))) then	-- roundtrip conversion check ensures that prefixes can't be zero-padded
					global_args[k] = v
				else
					local suf = string.sub(k, colon_idx + 1)
					pref = tonumber(pref)
					suf = tonumber(suf) or suf
					if modules[pref] == nil then modules[pref] = { args = {} } end
					modules[pref].args[suf] = v
				end
			end
		end
	end
	
	table.insert(parts, ibox_ns_header(frame, args))
	
	for k, v in pairs(modules) do
		if v.func == nil then v.func = funcs.plain end
		for q, w in pairs(global_args) do
			if v.args[q] == nil then v.args[q] = w end
		end
		v.args.child = "yes"
		table.insert(parts, v.func(frame, v.args))
	end
	
	table.insert(parts, ibox_ns_footer(frame, args))
	
	return table.concat(parts)
end


--[[-------------------------< P A S S T H R O U G H >---------------------------------------------------------

This is used in order to pass arguments to a nested template. Only use in templates. This could be turned into
a module of its own, maybe {{#invoke:pass||...}} would be less clunky.

Unfortunately, this can't be wrapped into a template, it needs to be invoked directly.

Module entry point

{{#invoke:Infocaseta Nume străin|pass|the name of the template to be called|any arguments on top of the
inherited ones}}

]]

local function passthrough(frame)
	local args = getArgs(frame)
	local new_args = {}
	
	for k, v in pairs(args) do
		local key = k
		if (type(k) == "number") and (k >= 2) then key = k - 1 end
		if (k ~= 1) then new_args[key] = v end
	end
	
	return frame:expandTemplate({ title = args[1], args = new_args })
end


--[[--------------------------< E X P O R T E D   F U N C T I O N S >------------------------------------------
]]

return {
	ibox_ns = ibox_ns,
	ibox_ns_blank = ibox_ns_blank,
	ibox_ns_ar = ibox_ns_ar,
	ibox_ns_ar_name = ibox_ns_ar_name,
	ibox_ns_as = ibox_ns_as,
	ibox_ns_bn = ibox_ns_bn,
	ibox_ns_bo = ibox_ns_bo,
	ibox_ns_dng = ibox_ns_dng,
	ibox_ns_hi = ibox_ns_hi,
	ibox_ns_hokkien = ibox_ns_hokkien,
	ibox_ns_hokkien_complex = ibox_ns_hokkien_complex,
	ibox_ns_id = ibox_ns_id,
	ibox_ns_ja = ibox_ns_ja,
	ibox_ns_ja_complex = ibox_ns_ja_complex,
	ibox_ns_km = ibox_ns_km,
	ibox_ns_ko = ibox_ns_ko,
	ibox_ns_ko_complex = ibox_ns_ko_complex,
	ibox_ns_lo = ibox_ns_lo,
	ibox_ns_mn = ibox_ns_mn,
	ibox_ns_mnc = ibox_ns_mnc,
	ibox_ns_ms = ibox_ns_ms,
	ibox_ns_my = ibox_ns_my,
	ibox_ns_ne = ibox_ns_ne,
	ibox_ns_pi = ibox_ns_pi,
	ibox_ns_pt = ibox_ns_pt,
	ibox_ns_pra = ibox_ns_pra,
	ibox_ns_ru = ibox_ns_ru,
	ibox_ns_sa = ibox_ns_sa,
	ibox_ns_ta = ibox_ns_ta,
	ibox_ns_tet = ibox_ns_tet,
	ibox_ns_th = ibox_ns_th,
	ibox_ns_tl = ibox_ns_tl,
	ibox_ns_ug = ibox_ns_ug,
	ibox_ns_uk = ibox_ns_uk,
	ibox_ns_vi = ibox_ns_vi,
	ibox_ns_za = ibox_ns_za,
	ibox_ns_zh = ibox_ns_zh,
	ibox_ns_zh_complex = ibox_ns_zh_complex,
	ibox_ns_header = ibox_ns_header,
	ibox_ns_footer = ibox_ns_footer,
	ibox_hr = ibox_hr,
	ibox_pic = ibox_pic,
	ibox_plain = ibox_plain,
	ibox_constructor = ibox_constructor,
	pass = passthrough
}