Модуль:Картка

{{i}} Документація модуля[перегляд] [редагувати] [історія] [очистити кеш]

Модуль для реалізації шаблону {{Картка}}. Документація з використання модуля розташована на сторінці відповідного шаблону.

Щоб використати модуль напряму замість виклику через шаблон Картка, потрібно зробити виклик через функцію infoboxTemplate. Наприклад, {{#invoke:Картка|infoboxTemplate.

Категорії спостереження

-- -- Модуль для реалізації шаблону {{Картка}} --  local p = {} local args = {} local argsAliases = {} local origArgs = {} local root local yesno = require("Модуль:Yesno") local empty_row_categories = {} local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]' local category_in_empty_row_pattern_uk = '%[%[%s*[Кк][Аа][Тт][Ее][Гг][Оо][Рр][Іі][Яя]%s*:[^]]*]]' local has_rows = false local has_error = false local error_message = '<span class="error" style="font-size:100%"><kbd>{{[[Шаблон:Картка|Картка]]}}</kbd>: ' local lists = { 	plainlist_t = { 		patterns = { 			'^plainlist$', 			'%splainlist$', 			'^plainlist%s', 			'%splainlist%s' 		}, 		found = false, 		styles = 'Plainlist/styles.css' 	}, 	hlist_t = { 		patterns = { 			'^hlist$', 			'%shlist$', 			'^hlist%s', 			'%shlist%s' 		}, 		found = false, 		styles = 'Hlist/styles.css' 	} }  local function has_list_class(args_to_check) 	for _, list in pairs(lists) do 		if not list.found then 			for _, arg in pairs(args_to_check) do 				for _, pattern in ipairs(list.patterns) do 					if mw.ustring.find(arg or '', pattern) then 						list.found = true 						break 					end 				end 				if list.found then break end 			end 		end 	end end  local function fixChildBoxes(sval, tt) 	local function notempty( s ) return s and s:match( '%S' ) end 	 	if notempty(sval) then 		local marker = '<span class=special_infobox_marker>' 		local s = sval 		-- start moving templatestyles and categories inside of table rows 		local slast = '' 		while slast ~= s do 			slast = s 			s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])', '%2%1') 			s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Кк][Аа][Тт][Ее][Гг][Оо][Рр][Іі][Яя]%s*:[^]]*%]%])', '%2%1') 			s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)', '%2%1') 		end 		-- end moving templatestyles and categories inside of table rows 		s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1') 		s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker) 		if s:match(marker) then 			s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '') 			s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1') 			s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1') 			s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1') 			s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1') 			s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') 			s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1') 			s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1') 			s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1') 		end 		if s:match(marker) then 			local subcells = mw.text.split(s, marker) 			s = '' 			for k = 1, #subcells do 				if k == 1 then 					s = s .. subcells[k] .. '</' .. tt .. '></tr>' 				elseif k == #subcells then 					local rowstyle = ' style="display:none"' 					if notempty(subcells[k]) then rowstyle = ''	end 					s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' .. 						subcells[k] 				elseif notempty(subcells[k]) then 					if (k % 2) == 0 then 						s = s .. subcells[k] 					else 						s = s .. '<tr><' .. tt .. ' colspan=2>\n' .. 							subcells[k] .. '</' .. tt .. '></tr>' 					end 				end 			end 		end 		-- the next two lines add a newline at the end of lists for the PHP parser 		-- [[Special:Diff/849054481]] 		-- remove when [[:phab:T191516]] is fixed or OBE 		s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n') 		s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n') 		s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1') 		s = mw.ustring.gsub(s, '^(%{%|)', '\n%1') 		return s 	else 		return sval 	end end  -- Cleans empty tables local function cleanInfobox() 	root = tostring(root) 	if has_rows == false then 		root = mw.ustring.gsub(root, '<table[^<>]*>%s*</table>', '') 	end end  -- Returns the union of the values of two tables, as a sequence. local function union(t1, t2, t3)  	local vals = {} 	for k, v in pairs(t1) do 		vals[v] = true 	end 	for k, v in pairs(t2) do 		vals[v] = true 	end 	if t3 then 		for k, v in pairs(t3) do 			vals[v] = true 		end 	end 	local ret = {} 	for k, v in pairs(vals) do 		table.insert(ret, k) 	end 	return ret end  local function processParamsFromArg (paramList, paramType, is_global) 	local paramName = ('wikidata' == paramType) and 'параметри_вікіданих' or 'параметри_зображення_картки' 	 	local paramsArgs = {} 	if paramList and paramList ~= '' then --		local allowedParams = getAllowedList(paramType) 		 		for item in paramList:gmatch("(%S+%s*%S+);%s*") do 			local param, arg = mw.ustring.match(item, "^(%S+):%s*(%S+)") --			for k, v in ipairs(allowedParams) do								--чи тут потрібна взагалі перевірка на підтримувані параметри? --				if v == param then 					paramsArgs[param] = arg --				end --			end	 		end 		 		if is_global then 			args[paramName] = paramsArgs 			return '' 		end 	end  	if args[paramName] and args[paramName] ~= '' then 		for param, arg in pairs(args[paramName]) do 			if not paramsArgs[param] or paramsArgs[param] == '' then 				paramsArgs[param] = arg 			end	 		end	 	end	 	 	return is_global and '' or paramsArgs end  local function processWikidata(text, element, wdParams) 	 	if element then 		 		if args['назва_модуля_вікіданих'] and args['назва_модуля_вікіданих']:lower() == 'wikidataib' then 			local wikidata = require("Модуль:WikidataIB") 			 			local wdArgs = processParamsFromArg(wdParams, 'wikidata') 				 			wdArgs[1] = element:upper() 			wdArgs[2] = text 			 			local temptext 			 			if wdArgs['function'] and wdArgs['function'] ~= 'getValue' then 				local wdFrame = mw.getCurrentFrame() 				if wdArgs['function'] == 'getCoords' then 					wdArgs[1] = text 					wdArgs[2] = '' 				end	 				wdFrame.args = wdArgs 				temptext = wikidata[wdArgs['function']](wdFrame) 			else 				temptext = wikidata._getValue(wdArgs) 			end	 			 			if temptext and wdArgs.ref == "yes" then 				local wd = require("Модуль:wd") 				 				temptext = temptext .. wd._references({'normal+', wdArgs.qid or '', element}) 			end	 			 			text = temptext 			 		elseif args['назва_модуля_вікіданих'] and args['назва_модуля_вікіданих']:lower() == 'wikidata1' then 			local wdFrame = mw.getCurrentFrame() 			local wikidata = require("Модуль:Wikidata1") 			wdFrame.args = {} 			local wdfunction 			 			if origArgs['qid'] and origArgs['qid'] ~= '' then 				wdFrame.args[1] = origArgs['qid'] 				wdFrame.args[2] = element:upper() 				wdFrame.args[3] = text 				wdfunction = 'getValueFromID' 			else	 				wdFrame.args[1] = element:upper() 				wdFrame.args[2] = text 				wdfunction = 'getValue' 			end	 			 			text = wikidata[wdfunction](wdFrame) 		else 			local wdFrame = mw.getCurrentFrame() 			local wikidata = require("Модуль:Wikidata") 		 			wdFrame.args = { 				property = element, 				value = text, 				from = origArgs[ 'from' ] or '' 			} 		 			text = wikidata.formatProperty(wdFrame) 		end	 	end 	 	return text end  -- Returns a table containing the numbers of the arguments that exist -- for the specified prefix. For example, if the prefix was 'data', and -- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}. local function getArgNums(prefix) 	local nums = {} 	for k, v in pairs(args) do 		local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$') 		if num then table.insert(nums, tonumber(num)) end 	end 	table.sort(nums) 	return nums end  -- Adds a row to the infobox, with either a header cell -- or a label/data cell combination. local function addRow(rowArgs) 	 	if rowArgs.header and rowArgs.header ~= '_BLANK_' then 		has_rows = true 		has_list_class({ rowArgs.rowclass, rowArgs.class, args['клас_заголовків'] }) 		 		root 			:tag('tr') 				:addClass(rowArgs.rowclass) 				:cssText(rowArgs.rowstyle) 				:tag('th') 					:attr('colspan', '2') 					:addClass('infobox-header') 					:addClass(rowArgs.class) 					:addClass(args['клас_заголовків']) 					-- @deprecated next; target .infobox-<name> .infobox-header 					:cssText(args['стиль_заголовків']) 					:cssText(rowArgs.rowcellstyle) 					:wikitext(fixChildBoxes(rowArgs.header, 'th')) 		if rowArgs.data then 			root:wikitext( 				'[[Категорія:Сторінки, що використовують шаблони картка з проігнорованими комірками параметра текст]]' 			) 		end 	elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, ''):gsub(category_in_empty_row_pattern_uk, ''):match('^%S') then 		has_rows = true 		has_list_class({ rowArgs.rowclass, rowArgs.class }) 		 		local row = root:tag('tr') 		row:addClass(rowArgs.rowclass) 		row:cssText(rowArgs.rowstyle) 		if rowArgs.label then 			row 				:tag('th') 					:attr('scope', 'row') 					:addClass('infobox-label') 					-- @deprecated next; target .infobox-<name> .infobox-label 					:cssText(args['стиль_міток']) 					:cssText(rowArgs.rowcellstyle) 					:wikitext(rowArgs.label) 					:done() 		end 		 		if rowArgs.data == '----' then											--Так як при переході на модуль перестали працювати чотири дефіси 			rowArgs.data = '<hr/>'												--тому робимо їхню заміну на '<hr/>' 		end	  		local dataCell = row:tag('td') 		dataCell 			:attr('colspan', not rowArgs.label and '2' or nil) 			:addClass(not rowArgs.label and 'infobox-full-data' or 'infobox-data') 			:addClass(rowArgs.class) 			-- @deprecated next; target .infobox-<name> .infobox(-full)-data 			:cssText(rowArgs.datastyle) 			:cssText(rowArgs.rowcellstyle) 			:wikitext(fixChildBoxes(rowArgs.data, 'td')) 	else 		table.insert(empty_row_categories, rowArgs.data or '') 	end end  local function renderError() 	if not has_error then return end 	 	local errorText = error_message .. '</span><br/>' 	 	root 		:tag('caption') 			:addClass('infobox-title') 			:wikitext(errorText) end	  local function renderTitle() 	if not args['назва'] then return end  	has_rows = true 	has_list_class({args['клас_назви']}) 	 	root 		:tag('caption') 			:addClass('infobox-title') 			:addClass(args['клас_назви']) 			-- @deprecated next; target .infobox-<name> .infobox-title 			:cssText(args['стиль_назви']) 			:wikitext(args['назва']) 	 end  local function renderAboveRow() 	if not args['угорі'] then return end  	has_rows = true 	has_list_class({ args['клас_угорі'] }) 	 	root 		:tag('tr') 			:tag('th') 				:attr('colspan', '2') 				:addClass('infobox-above') 				:addClass(args['клас_угорі']) 				-- @deprecated next; target .infobox-<name> .infobox-above 				:cssText(args['стиль_угорі']) 				:wikitext(fixChildBoxes(args['угорі'],'th')) end  local function renderAboveRow2() 	if not args['угорі2'] then return end  	has_rows = true 	has_list_class({ args['клас_угорі2'] }) 	 	root 		:tag('tr') 			:tag('th') 				:attr('colspan', '2') 				:addClass('infobox-above') 				:addClass(args['клас_угорі2']) 				-- @deprecated next; target .infobox-<name> .infobox-above 				:cssText(args['стиль_угорі2']) 				:wikitext(fixChildBoxes(args['угорі2'],'th')) end  local function renderBelowRow() 	if not args['внизу'] then return end  	has_rows = true 	has_list_class({ args['клас_внизу'] }) 	 	root 		:tag('tr') 			:tag('td') 				:attr('colspan', '2') 				:addClass('infobox-below') 				:addClass(args['клас_внизу']) 				-- @deprecated next; target .infobox-<name> .infobox-below 				:cssText(args['стиль_внизу']) 				:wikitext(fixChildBoxes(args['внизу'],'td')) end  local function renderBelowRow2() 	if not args['внизу2'] then return end  	has_rows = true 	has_list_class({ args['клас_внизу2'] }) 	 	root 		:tag('tr') 			:tag('td') 				:attr('colspan', '2') 				:addClass('infobox-below') 				:addClass(args['клас_внизу2']) 				-- @deprecated next; target .infobox-<name> .infobox-below 				:cssText(args['стиль_внизу2']) 				:wikitext(fixChildBoxes(args['внизу2'],'td')) end  local function addSubheaderRow(subheaderArgs) 	if subheaderArgs.data and 		subheaderArgs.data:gsub(category_in_empty_row_pattern, ''):gsub(category_in_empty_row_pattern_uk, ''):match('^%S') then 		has_rows = true 		has_list_class({ subheaderArgs.rowclass, subheaderArgs.class }) 		 		local row = root:tag('tr') 		row:addClass(subheaderArgs.rowclass)  		local dataCell = row:tag('td') 		dataCell 			:attr('colspan', '2') 			:addClass('infobox-subheader') 			:addClass(subheaderArgs.class) 			:cssText(subheaderArgs.datastyle) 			:cssText(subheaderArgs.rowcellstyle) 			:wikitext(fixChildBoxes(subheaderArgs.data, 'td')) 	else 		table.insert(empty_row_categories, subheaderArgs.data or '') 	end end  local function renderSubheaders() 	if args['підзаголовок'] then 		args['підзаголовок1'] = args['підзаголовок'] 	end 	if args['клас_рядка_підзаголовок'] then 		args['клас_рядка_підзаголовок1'] = args['клас_рядка_підзаголовок']  	end 	local subheadernums = getArgNums('підзаголовок') 	for k, num in ipairs(subheadernums) do 		addSubheaderRow({ 			data = args['підзаголовок' .. tostring(num)], 			-- @deprecated next; target .infobox-<name> .infobox-subheader 			datastyle = args['стиль_підзаголовок'] or args['стиль_підзаголовоків'], 			rowcellstyle = args['стиль_підзаголовок' .. tostring(num)], 			class = args['клас_підзаголовоків'], 			rowclass = args['клас_рядка_підзаголовок' .. tostring(num)] 		}) 	end end  local function addImageRow(imageArgs)  	if imageArgs.data and 		imageArgs.data:gsub(category_in_empty_row_pattern, ''):gsub(category_in_empty_row_pattern_uk, ''):match('^%S') then  		has_rows = true 		has_list_class({ imageArgs.rowclass, imageArgs.class }) 		 		local row = root:tag('tr') 		row:addClass(imageArgs.rowclass)  		local dataCell = row:tag('td') 		dataCell 			:attr('colspan', '2') 			:addClass('infobox-image') 			:addClass(imageArgs.class) 			:cssText(imageArgs.datastyle) 			:wikitext(fixChildBoxes(imageArgs.data, 'td')) 	else 		table.insert(empty_row_categories, imageArgs.data or '') 	end end  local function renderImages() 	if args['зображення'] then 		args['зображення1'] = args['зображення'] 	end 	if args['підпис'] then 		args['підпис1'] = args['підпис'] 	end 	local imagenums = getArgNums('зображення') 	for k, num in ipairs(imagenums) do 		local caption = args['підпис' .. tostring(num)] 		local data = mw.html.create():wikitext(args['зображення' .. tostring(num)]) 		if caption then 			data 				:tag('div') 					:addClass('infobox-caption') 					-- @deprecated next; target .infobox-<name> .infobox-caption 					:cssText(args['стиль_підпису']) 					:wikitext(caption) 		end 		addImageRow({ 			data = tostring(data), 			-- @deprecated next; target .infobox-<name> .infobox-image 			datastyle = args['стиль_зображення'], 			class = args['клас_зображення'], 			rowclass = args['клас_рядка_зображення' .. tostring(num)] 		}) 	end end  -- When autoheaders are turned on, preprocesses the rows local function preprocessRows() 	if not args['автозаголовки'] then return end 	 	local rownums = union(getArgNums('заголовок'), getArgNums('текст'), getArgNums('вікідані')) 	table.sort(rownums) 	local lastheader 	for k, num in ipairs(rownums) do 		if args['заголовок' .. tostring(num)] then 			if lastheader then 				args['заголовок' .. tostring(lastheader)] = nil 			end 			lastheader = num 		elseif (args['текст' .. tostring(num)] and 			args['текст' .. tostring(num)]:gsub( 				category_in_empty_row_pattern, '' 			):gsub( 				category_in_empty_row_pattern_uk, '' 			):match('^%S')) or (args['вікідані' .. tostring(num)] 		and args['вікідані' .. tostring(num)]:gsub( 				category_in_empty_row_pattern, '' 			):gsub( 				category_in_empty_row_pattern_uk, '' 			):match('^%S')) 		then 			local data = processWikidata(args['текст' .. tostring(num)], args['вікідані' .. tostring(num)], args['параметри_рядка_вікіданих' .. tostring(num)]) 			if data and data:gsub(category_in_empty_row_pattern, ''):gsub(category_in_empty_row_pattern_uk, ''):match('%S') then 				lastheader = nil 			end 		end 	end 	if lastheader then 		args['заголовок' .. tostring(lastheader)] = nil 	end end  -- Gets the union of the header and data argument numbers, -- and renders them all in order local function renderRows()  	local rownums = union(getArgNums('заголовок'), getArgNums('текст'), getArgNums('вікідані')) 	table.sort(rownums) 	for k, num in ipairs(rownums) do 		addRow({ 			header = args['заголовок' .. tostring(num)], 			label = args['мітка' .. tostring(num)], 			data = processWikidata(args['текст' .. tostring(num)], args['вікідані' .. tostring(num)], args['параметри_рядка_вікіданих' .. tostring(num)]), 			datastyle = args['стиль_тексту'], 			class = args['клас' .. tostring(num)], 			rowclass = args['клас_рядка' .. tostring(num)], 			-- @deprecated next; target .infobox-<name> rowclass 			rowstyle = args['стиль_рядка' .. tostring(num)], 			rowcellstyle = args['стиль_комірки_рядка' .. tostring(num)] 		}) 	end end  local function renderNavBar() 	if not args['ім\'я'] then return end  	has_rows = true 	root 		:tag('tr') 			:tag('td') 				:attr('colspan', '2') 				:addClass('infobox-navbar') 				:wikitext(require('Модуль:Navbar')._navbar{ 					args['ім\'я'], 					mini = 1, 				}) end  local function renderItalicTitle() 	local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title']) 	if italicTitle == '' or italicTitle == 'force' or italicTitle == 'примусово' or italicTitle == 'yes' or italicTitle == 'так' then 		root:wikitext(require('Модуль:Заголовок курсивом')._main({})) 	end end  -- Categories in otherwise empty rows are collected in empty_row_categories. -- This function adds them to the module output. It is not affected by -- args.decat because this module should not prevent module-external categories -- from rendering. local function renderEmptyRowCategories() 	for _, s in ipairs(empty_row_categories) do 		root:wikitext(s) 	end end  -- Render tracking categories. args.nocat == turns off tracking categories. local function renderTrackingCategories() 	if yesno(args.nocat) then return end 	if yesno(args['вбудовування']) then 		if args['назва'] then 			root:wikitext( 				'[[Категорія:Сторінки, що використовують шаблони вбудованої картки з параметром назва]]' 			) 		end 	elseif #(getArgNums('текст')) == 0 and #(getArgNums('вікідані')) == 0 and mw.title.getCurrentTitle().namespace == 0 then 		root:wikitext('[[Категорія:Статті, що використовують шаблони картка без рядків параметра текст]]') 	end 	if args['ім\'я'] then 		root:wikitext('[[Категорія:Сторінки, що використовують шаблони картка з параметром ім\'я' .. (mw.title.getCurrentTitle().namespace == 10 and '|{' or '') .. ']]') 	end	 	if has_error then 		root:wikitext('[[Категорія:Сторінки, що використовують шаблони картка з двома однаковими параметрами]]') 	end end  --[=[ Loads the templatestyles for the infobox.  TODO: FINISH loading base templatestyles here rather than in MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables. See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :). When we do this we should clean up the inline CSS below too. Will have to do some bizarre conversion category like with sidebar.  ]=] local function loadTemplateStyles() 	local frame = mw.getCurrentFrame() 	 	local hlist_templatestyles = '' 	if lists.hlist_t.found then 		hlist_templatestyles = frame:extensionTag{ 			name = 'templatestyles', args = { src = lists.hlist_t.styles } 		} 	end 	 	local plainlist_templatestyles = '' 	if lists.plainlist_t.found then 		plainlist_templatestyles = frame:extensionTag{ 			name = 'templatestyles', args = { src = lists.plainlist_t.styles } 		} 	end 	 	-- See function description 	local base_templatestyles = frame:extensionTag{ 		name = 'templatestyles', args = { src = 'Модуль:Картка/styles.css' } 	}  	local templatestyles = '' 	if args['стилі_шаблону'] then 		templatestyles = frame:extensionTag{ 			name = 'templatestyles', args = { src = args['стилі_шаблону'] } 		} 	end 	 	local child_templatestyles = '' 	if args['стилі_шаблону вбудовування'] then 		child_templatestyles = frame:extensionTag{ 			name = 'templatestyles', args = { src = args['стилі_шаблону вбудовування'] } 		} 	end 	 	local grandchild_templatestyles = '' 	if args['стилі_шаблону вторинного_вбудовування'] then 		grandchild_templatestyles = frame:extensionTag{ 			name = 'templatestyles', args = { src = args['стилі_шаблону вторинного_вбудовування'] } 		} 	end 	 	return table.concat({ 		-- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering. 		-- this ordering is not a guarantee because the rows of interest invoking 		-- each class may not be on a specific page 		hlist_templatestyles, 		plainlist_templatestyles, 		base_templatestyles, 		templatestyles, 		child_templatestyles, 		grandchild_templatestyles 	}) end  -- common functions between the child and non child cases local function structure_infobox_common() 	renderSubheaders() 	renderImages() 	preprocessRows() 	renderRows() 	renderBelowRow() 	renderBelowRow2() 	--	renderNavBar() (тимчасово поки закоментував) 	renderItalicTitle() 	renderEmptyRowCategories() 	renderTrackingCategories() 	cleanInfobox() end  -- Specify the overall layout of the infobox, with special settings if the -- infobox is used as a 'child' inside another infobox. local function _infobox() 	if not yesno(args['вбудовування']) then 		root = mw.html.create('table') 		 		local infoboxWidth = '' 		if args['ширина-картки'] then 			infoboxWidth = "width:" .. args['ширина-картки'] 		end 		 		root 			:addClass(yesno(args['підкартка']) and 'infobox-subbox' or 'infobox') 			:addClass(args['клас_тіла']) 			-- @deprecated next; target .infobox-<name> 			:cssText(args['стиль_тіла']) 			-- infobox width from a parameter 			:cssText(infoboxWidth) 		 		has_list_class({ args['клас_тіла'] })  		renderError() 		renderTitle() 		renderAboveRow() 		renderAboveRow2() 	else 		root = mw.html.create()  		local errorText = has_error and (error_message .. '</span><br/>') or ''  		root 			:wikitext(errorText) 			:wikitext(args['назва']) 	end 	structure_infobox_common() 	 	return loadTemplateStyles() .. root end  -- If the argument exists and isn't blank, add it to the argument table. -- Blank arguments are treated as nil to match the behaviour of ParserFunctions. local function preprocessSingleArg(argName) 	if origArgs[argName] and origArgs[argName] ~= '' then 		args[argName] = origArgs[argName] 	end end  local function translateArg(aliasArgName,localArgName) 	-- Функція додає підтримку аліасів параметрів (наприклад, іншою мовою) 	 	-- Додаєм аліас параметра в таблицю аліасів 	-- Для одного параметра може бути кілька аліасів 	-- Нумеровані параметри(текст1 і т.д.) заносяться без номера 	if not 	argsAliases[localArgName] then 		argsAliases[localArgName] = {} 	end 	table.insert(argsAliases[localArgName], aliasArgName) 	 	-- Значення аліасів додаются в таблицю аргументів     if origArgs[localArgName] and origArgs[localArgName] ~= '' then     	-- параметр вже заданий на локальній мові     	-- якщо аліас заданий і не пустий     	if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then     		local message_addon = 'Вказано два однакових параметри <code class="infobox-code">&#124;$1=</code> та <code class="infobox-code">&#124;$2=</code>, тому виведено значення параметра <code class="infobox-code">&#124;$1=</code> ([[Шаблон:Картка#Помилки|довідка]])'     		error_message = error_message .. (has_error and '; ' or '') .. mw.message.newRawMessage(message_addon, localArgName, aliasArgName):plain()     		has_error = true     	end	     else     	-- якщо аліас заданий і не пустий 	    if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then 	        origArgs[localArgName] = origArgs[aliasArgName] 	    end     end end  -- Assign the parameters with the given prefixes to the args table, in order, in -- batches of the step size specified. This is to prevent references etc. from -- appearing in the wrong order. The prefixTable should be an array containing -- tables, each of which has two possible fields, a "prefix" string and a -- "depend" table. The function always parses parameters containing the "prefix" -- string, but only parses parameters in the "depend" table if the prefix -- parameter is present and non-blank. local function preprocessArgs(prefixTable, step) 	if type(prefixTable) ~= 'table' then 		error("Виявлено нетабличне значення для таблиці префіксів", 2) 	end 	if type(step) ~= 'number' then 		error("Виявлено недійсне значення параметра кроку", 2) 	end  	-- Get arguments without a number suffix, and check for bad input. 	for i,v in ipairs(prefixTable) do 		if type(v) ~= 'table' or type(v.prefix) ~= "string" or  			(v.prefix_trans and type(v.prefix_trans) ~= "string") or 			(v.depend and type(v.depend) ~= 'table') or 			(v.depend_trans and type(v.depend_trans) ~= 'table') then 			error('Виявлено недійсне значення в таблиці префіксів preprocessArgs', 2) 		end 		 		-- якщо потрібен переклад параметрів, то викликається відповідна функція 		--якщо ні, то відбувається обрабка змінної 		if v.prefix_trans then 			translateArg(v.prefix_trans,v.prefix) 		else 			preprocessSingleArg(v.prefix) 		end	 		-- Only parse the depend parameter if the prefix parameter is present 		-- and not blank. 		if args[v.prefix] and v.depend then 			for j, dependValue in ipairs(v.depend) do 				if type(dependValue) ~= 'string' then 					error('Виявлено недійсне значення «обов\'язкового» параметра в preprocessArgs') 				end 					preprocessSingleArg(dependValue) 			end 		--якщо потрібен переклад обов'язкових параметрів, то викликається відповідна функція 		elseif origArgs[v.prefix] and v.depend_trans then 			for j, dependValue in ipairs(v.depend) do 				for k, depend_transValue in ipairs(v.depend_trans) do 					if type(depend_transValue) ~= 'string' or type(dependValue) ~= 'string' then 							error('Виявлено недійсне значення «обов\'язкового» параметра в preprocessArgs') 					end 					translateArg(depend_transValue,dependValue) 				end 			end 		end 	end  	-- Get arguments with number suffixes. 	local a = 1 -- Counter variable. 	local moreArgumentsExist = true 	while moreArgumentsExist == true do 		moreArgumentsExist = false 		for i = a, a + step - 1 do 			for j,v in ipairs(prefixTable) do 				local prefixArgName = v.prefix .. tostring(i) 				-- якщо потрібен переклад параметрів, то викликається відповідна функція 				--якщо ні, то відбувається обрабка змінної 				if v.prefix_trans then 					local prefix_transArgName = v.prefix_trans .. tostring(i) 					if origArgs[prefix_transArgName] then 						moreArgumentsExist = true 						translateArg(prefix_transArgName,prefixArgName) 					end	 				else	 					if origArgs[prefixArgName] then 						-- Do another loop if any arguments are found, even blank ones. 						moreArgumentsExist = true 						preprocessSingleArg(prefixArgName) 					end 				end	 				-- Process the depend table if the prefix argument is present 				-- and not blank, or we are processing "prefix1" and "prefix" is 				-- present and not blank, and if the depend table is present. 				if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then 					for j,dependValue in ipairs(v.depend) do 						local dependArgName = dependValue .. tostring(i) 						preprocessSingleArg(dependArgName) 					end 				--якщо потрібен переклад обов'язкових параметрів, то викликається відповідна функція	 				elseif v.depend_trans and (origArgs[prefixArgName] or (i == 1 and origArgs[v.prefix])) then 					for j,dependValue in ipairs(v.depend) do 						for k,depend_transValue in ipairs(v.depend_trans)  do 							local dependArgName = dependValue .. tostring(i) 							local depend_transArgName = depend_transValue .. tostring(i) 							translateArg(depend_transArgName, dependArgName) 						end	 					end 				end	 			end 		end 		a = a + step 	end end  -- Parse the data parameters in the same order that the old {{infobox}} did, so -- that references etc. will display in the expected places. Parameters that -- depend on another parameter are only processed if that parameter is present, -- to avoid phantom references appearing in article reference lists. local function parseDataParameters()  	translateArg('autoheaders','автозаголовки') 	translateArg('child', 'вбудовування') 	translateArg('infobox-width', 'ширина-картки') 	translateArg('bodyclass', 'клас_тіла') 	translateArg('subbox', 'підкартка') 	translateArg('bodystyle', 'стиль_тіла') 	translateArg('title', 'назва') 	translateArg('titleclass', 'клас_назви') 	translateArg('titlestyle', 'стиль_назви') 	translateArg('above', 'угорі') 	translateArg('aboveclass', 'клас_угорі') 	translateArg('abovestyle', 'стиль_угорі') 	translateArg('above2', 'угорі2') 	translateArg('aboveclass2', 'клас_угорі2') 	translateArg('abovestyle2', 'стиль_угорі2') 	preprocessArgs({ 		{prefix_trans = 'subheader', prefix = 'підзаголовок', depend_trans = {'subheaderstyle', 'subheaderrowclass'}, depend = {'стиль_підзаголовок', 'клас_рядка_підзаголовок'}} 	}, 10) 	translateArg('subheaderstyle', 'стиль_підзаголовків') 	translateArg('subheaderclass','клас_підзаголовків') 	preprocessArgs({ 		{prefix_trans = 'image', prefix = 'зображення', depend_trans = {'caption', 'imagerowclass'}, depend = {'підпис', 'клас_рядка_зображення'}} 	}, 10) 	translateArg('captionstyle', 'стиль_підпису') 	translateArg('imagestyle', 'стиль_зображення') 	translateArg('imageclass', 'клас_зображення') 	translateArg('wikidatamodulename','назва_модуля_вікіданих') 	translateArg('parameterswikidata','параметри_вікіданих') 	preprocessArgs({ 		{prefix_trans = 'header', prefix = 'заголовок'}, 		{prefix_trans = 'data', prefix = 'текст', depend_trans = {'label'}, depend = {'мітка'}}, 		{prefix_trans = 'wikidata', prefix = 'вікідані', depend_trans = {'label', 'parametersrowwikidata'}, depend = {'мітка', 'параметри_рядка_вікіданих' }}, 		{prefix_trans = 'rowclass', prefix = 'клас_рядка'}, 		{prefix_trans = 'rowstyle', prefix = 'стиль_рядка'}, 		{prefix_trans = 'rowcellstyle', prefix = 'стиль_комірки_рядка'}, 		{prefix_trans = 'class', prefix = 'клас'} 	}, 100) 	translateArg('headerclass', 'клас_заголовків') 	translateArg('headerstyle', 'стиль_заголовків') 	translateArg('labelstyle', 'стиль_міток') 	translateArg('datastyle', 'стиль_тексту') 	translateArg('below', 'внизу') 	translateArg('belowclass', 'клас_внизу') 	translateArg('belowstyle', 'стиль_внизу') 	translateArg('below2', 'внизу2') 	translateArg('belowclass2', 'клас_внизу2') 	translateArg('belowstyle2', 'стиль_внизу2') 	translateArg('name', 'ім\'я') 	translateArg('decat', 'nocat') 	translateArg('templatestyles', 'стилі_шаблону') 	translateArg('child templatestyles', 'стилі_шаблону вбудовування') 	translateArg('grandchild templatestyles', 'стилі_шаблону вторинного_вбудовування')   	preprocessSingleArg('автозаголовки') 	preprocessSingleArg('вбудовування') 	preprocessSingleArg('ширина-картки') 	preprocessSingleArg('клас_тіла') 	preprocessSingleArg('підкартка') 	preprocessSingleArg('стиль_тіла') 	preprocessSingleArg('назва') 	preprocessSingleArg('клас_назви') 	preprocessSingleArg('стиль_назви') 	preprocessSingleArg('угорі') 	preprocessSingleArg('клас_угорі') 	preprocessSingleArg('стиль_угорі') 	preprocessSingleArg('угорі2') 	preprocessSingleArg('клас_угорі2') 	preprocessSingleArg('стиль_угорі2') 	preprocessArgs({ 		{prefix = 'підзаголовок', depend = {'стиль_підзаголовок', 'клас_рядка_підзаголовок'}} 	}, 10) 	preprocessSingleArg('стиль_підзаголовків') 	preprocessSingleArg('клас_підзаголовків') 	preprocessArgs({ 		{prefix = 'зображення', depend = {'підпис', 'клас_рядка_зображення'}} 	}, 10) 	preprocessSingleArg('стиль_підпису') 	preprocessSingleArg('стиль_зображення') 	preprocessSingleArg('клас_зображення') 	preprocessSingleArg('назва_модуля_вікіданих') 	processParamsFromArg(origArgs['параметри_вікіданих'], 'wikidata', true) 	preprocessArgs({ 		{prefix = 'заголовок'}, 		{prefix = 'текст', depend = {'мітка'}}, 		{prefix = 'вікідані', depend = {'мітка', 'параметри_рядка_вікіданих'}}, 		{prefix = 'клас_рядка'}, 		{prefix = 'стиль_рядка'}, 		{prefix = 'стиль_комірки_рядка'}, 		{prefix = 'клас'} 	}, 100) 	preprocessSingleArg('клас_заголовків') 	preprocessSingleArg('стиль_заголовків') 	preprocessSingleArg('стиль_міток') 	preprocessSingleArg('стиль_тексту') 	preprocessSingleArg('внизу') 	preprocessSingleArg('клас_внизу') 	preprocessSingleArg('стиль_внизу') 	preprocessSingleArg('внизу2') 	preprocessSingleArg('клас_внизу2') 	preprocessSingleArg('стиль_внизу2') 	preprocessSingleArg('ім\'я') 	-- different behaviour for italics if blank or absent 	args['italic title'] = origArgs['назва_курсивом'] or origArgs['italic title'] 	preprocessSingleArg('nocat') 	preprocessSingleArg('стилі_шаблону') 	preprocessSingleArg('стилі_шаблону вбудовування') 	preprocessSingleArg('стилі_шаблону вторинного_вбудовування') end  -- If called via #invoke, use the args passed into the invoking template. -- Otherwise, for testing purposes, assume args are being passed directly in. function p.infobox(frame) 	if frame == mw.getCurrentFrame() then 		origArgs = frame:getParent().args 	else 		origArgs = frame 	end 	 	parseDataParameters() 	 	return _infobox() end  -- For calling via #invoke within a template function p.infoboxTemplate(frame) 	origArgs = {} 	for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end 	 	parseDataParameters() 	 	return _infobox() end return p