Документация
local getArgs = require('Module:Arguments').getArgs
local p = {}

local tinsert = table.insert -- it is efficient to localize everything

-- cite_web includes categories depending on namespace
-- it is more efficient to find namespace once per page, not on each call
local pageTitle = mw.title.getCurrentTitle()
local pageNamespace = pageTitle.namespace

-- grey magic described in Module:Arguments
local function makeInvokeFunc(funcName)
	return function (frame)
		local args = getArgs(frame)
		return p[funcName](args)
	end
end

p.ref_info = makeInvokeFunc('_ref_info')
p.ref_lang = makeInvokeFunc('_ref_lang')
p.lang_by_code = makeInvokeFunc('_lang_by_code')
p.lang_by_code_ru = makeInvokeFunc('_lang_by_code_ru')
p.lang_by_code_en = makeInvokeFunc('_lang_by_code_en')
p.ref_lang_by_code = makeInvokeFunc('_ref_lang_by_code')
p.cite_web_lang = makeInvokeFunc('_cite_web_lang')
p.cite_web = makeInvokeFunc('_cite_web')

local langs = {
['aa'] = {'афар.', 'афарский язык', 'афарском языке', 'афарского языка'},
['ab'] = {'абх.', 'абхазский язык', 'абхазском языке', 'абхазского языка'},
['af'] = {'афр.', 'африкаанс', 'африкаанс', 'африкаанс'},
['am'] = {'амх.', 'амхарский язык', 'амхарском языке', 'амхарского языка'},
['an'] = {'араг.', 'арагонский язык', 'арагонском языке', 'арагонского языка'},
['ar'] = {'ар.', 'арабский язык', 'арабском языке', 'арабского языка'},
['arz'] = {'араб. егип.', 'египетский диалект арабского языка', 'египетском диалекте арабского языка', 'египетского диалекта арабского языка'},
['av'] = {'авар.', 'аварский язык', 'аварском языке', 'аварского языка'},
['az'] = {'азерб.', 'азербайджанский язык', 'азербайджанском языке', 'азербайджанского языка'},
['ba'] = {'башк.', 'башкирский язык', 'башкирском языке', 'башкирского языка'},
['bar'] = {'бав.', 'баварский язык', 'баварском языке', 'баварского языка'},
['be'] = {'белор.', 'белорусский язык', 'белорусском языке', 'белорусского языка'},
['be-tarask'] = {'белор.', 'белорусский язык (тарашкевица)', 'белорусском языке (тарашкевице)', 'белорусского языка (тарашкевицы)'},
['bg'] = {'болг.', 'болгарский язык', 'болгарском языке', 'болгарского языка'},
['bn'] = {'бенг.', 'бенгальский язык', 'бенгальском языке', 'бенгальского языка'},
['bo'] = {'тиб.', 'тибетский язык', 'тибетском языке', 'тибетского языка'},
['br'] = {'брет.', 'бретонский язык', 'бретонском языке', 'бретонского языка'},
['bs'] = {'босн.', 'боснийский язык', 'боснийском языке', 'боснийского языка'},
['ca'] = {'каталан.', 'каталанский язык', 'каталанском языке', 'каталанского языка'},
['ce'] = {'чеч.', 'чеченский язык', 'чеченском языке', 'чеченского языка'},
['ceb'] = {'себ.', 'себуанский язык', 'себуанском языке', 'себуанского языка'},
['chm'] = {'марий.', 'марийский язык', 'марийском языке', 'марийского языка'},
['cmn'] = {'сев. кит.', 'севернокитайский язык', 'севернокитайском языке', 'севернокитайского языка'},
['crh'] = {'кр.тат.', 'крымскотатарский язык', 'крымскотатарском языке', 'крымскотатарского языка'},
['cs'] = {'чешск.', 'чешский язык', 'чешском языке', 'чешского языка'},
['csb'] = {'кашуб.', 'кашубский язык', 'кашубском языке', 'кашубского языка'},
['cu'] = {'ст.-слав.', 'старославянский язык', 'старославянском языке', 'старославянского языка'},
['cv'] = {'чув.', 'чувашский язык', 'чувашском языке', 'чувашского языка'},
['cy'] = {'валл.', 'валлийский язык', 'валлийском языке', 'валлийского языка'},
['da'] = {'датск.', 'датский язык', 'датском языке', 'датского языка'},
['de'] = {'нем.', 'немецкий язык', 'немецком языке', 'немецкого языка'},
['el'] = {'греч.', 'греческий язык', 'греческом языке', 'греческого языка'},
['en'] = {'англ.', 'английский язык', 'английском языке', 'английского языка'},
['eo'] = {'эсп.', 'эсперанто', 'эсперанто', 'эсперанто'},
['es'] = {'исп.', 'испанский язык', 'испанском языке', 'испанского языка'},
['et'] = {'эст.', 'эстонский язык', 'эстонском языке', 'эстонского языка'},
['eu'] = {'баск.', 'баскский язык', 'баскском языке', 'баскского языка'},
['fa'] = {'фарси', 'фарси', 'фарси', 'фарси'},
['fi'] = {'фин.', 'финский язык', 'финском языке', 'финского языка'},
['vro'] = {'вырус.', 'выруский диалект', 'выруском диалекте', 'выруского диалекта'},
['fo'] = {'фарерск.', 'фарерский язык', 'фарерском языке', 'фарерского языка'},
['fr'] = {'фр.', 'французский язык', 'французском языке', 'французского языка'},
['fy'] = {'фриз.', 'западнофризский язык', 'западнофризском языке', 'западнофризского языка'},
['ga'] = {'ирл.', 'ирландский язык', 'ирландском языке', 'ирландского языка'},
['gag'] = {'гаг.', 'гагаузский язык', 'гагаузском языке', 'гагаузского языка'},
['gl'] = {'галис.', 'галисийский язык', 'галисийском языке', 'галисийского языка'},
['grc'] = {'др.-греч.', 'древнегреческий язык', 'древнегреческом языке', 'древнегреческого языка'},
['he'] = {'иврит', 'иврит', 'иврите', 'иврита'},
['hi'] = {'хинди', 'хинди', 'хинди', 'хинди'},
['hr'] = {'хорв.', 'хорватский язык', 'хорватском языке', 'хорватского языка'},
['hsb'] = {'верхнелуж.', 'верхнелужицкий язык', 'верхнелужицком языке', 'верхнелужицкого языка'},
['hu'] = {'венг.', 'венгерский язык', 'венгерском языке', 'венгерского языка'},
['hy'] = {'арм.', 'армянский язык', 'армянском языке', 'армянского языка'},
['id'] = {'индон.', 'индонезийский язык', 'индонезийском языке', 'индонезийского языка'},
['inh'] = {'ингуш.', 'ингушский язык', 'ингушском языке', 'ингушского языка'},
['io'] = {'идо', 'идо', 'идо', 'идо'},
['is'] = {'исланд.', 'исландский язык', 'исландском языке', 'исландского языка'},
['it'] = {'итал.', 'итальянский язык', 'итальянском языке', 'итальянского языка'},
['jbo'] = {'ложб.', 'ложбан', 'ложбане', 'ложбана'},
['ka'] = {'груз.', 'грузинский язык', 'грузинском языке', 'грузинского языка'},
['kbd'] = {'каб.-чер.', 'кабардино-черкесский язык', 'кабардино-черкесском языке', 'кабардино-черкесского языка'},
['kk'] = {'казах.', 'казахский язык', 'казахском языке', 'казахского языка'},
['km'] = {'кхм.', 'кхмерский язык', 'кхмерском языке', 'кхмерского языка'},
['ko'] = {'кор.', 'корейский язык', 'корейском языке', 'корейского языка'},
['ku'] = {'курдск.', 'курдский язык', 'курдском языке', 'курдского языка'},
['ky'] = {'киргиз.', 'киргизский язык', 'киргизском языке', 'киргизского языка'},
['la'] = {'лат.', 'латинский язык', 'латинском языке', 'латинского языка'},
['lad'] = {'', 'ладино', 'ладино', 'ладино'},
['lb'] = {'люксемб.', 'люксембургский язык', 'люксембургском языке', 'люксембургского языка'},
['lez'] = {'лезг.', 'лезгинский язык', 'лезгинском языке', 'лезгинского языка'},
['lt'] = {'лит.', 'литовский язык', 'литовском языке', 'литовского языка'},
['lv'] = {'латыш.', 'латышский язык', 'латышском языке', 'латышского языка'},
['mhr'] = {'луговомар.', 'луговомарийский язык', 'луговомарийском языке', 'луговомарийского языка'},
['mg'] = {'малаг.', 'малагасийский язык', 'малагасийском языке', 'малагасийского языка'},
['mic'] = {'микмак', 'язык микмак', 'языке микмак', 'языка микмак'},
['mk'] = {'макед.', 'македонский язык', 'македонском языке', 'македонского языка'},
['ml'] = {'малаял.', 'язык малаялам', 'языке малаялам', 'языка малаялам'},
['mn'] = {'монг.', 'монгольский язык', 'монгольском языке', 'монгольского языка'},
['mo'] = {'молд.', 'молдавский язык', 'молдавском языке', 'молдавского языка'},
['mrj'] = {'горномар.', 'горномарийский язык', 'горномарийском языке', 'горномарийского языка'},
['ms'] = {'малайск.', 'малайский язык', 'малайском языке', 'малайского языка'},
['mt'] = {'мальт.', 'мальтийский язык', 'мальтийском языке', 'мальтийского языка'},
['mwl'] = {'мирандск.', 'мирандский язык', 'мирандском языке', 'мирандского языка'},
['myv'] = {'эрз.', 'эрзянский язык', 'эрзянском языке', 'эрзянского языка'},
['ne'] = {'непальск.', 'непальский язык', 'непальском языке', 'непальского языка'},
['nb'] = {'норв.', 'норвежский язык', 'норвежском языке', 'норвежского языка'},
['nl'] = {'нид.', 'нидерландский язык', 'нидерландском языке', 'нидерландского языка'},
['nov'] = {'', 'новиаль', 'новиале', 'новиаля'},
['os'] = {'осет.', 'осетинский язык', 'осетинском языке', 'осетинского языка'},
['pa'] = {'пандж.', 'панджаби', 'панджаби', 'панджаби'},
['pi'] = {'пали', 'пали', 'пали', 'пали'},
['pl'] = {'польск.', 'польский язык', 'польском языке', 'польского языка'},
['pms'] = {'пьем.', 'пьемонтский язык', 'пьемонтском языке', 'пьемонтского языка'},
['pt'] = {'порт.', 'португальский язык', 'португальском языке', 'португальского языка'},
['qu'] = {'кечуа', 'язык кечуа', 'языке кечуа', 'языка кечуа'},
['ro'] = {'рум.', 'румынский язык', 'румынском языке', 'румынского языка'},
['ru'] = {'рус.', 'русский язык', 'русском языке', 'русского языка'},
['rue'] = {'русин.', 'русинский язык', 'русинском языке', 'русинского языка'},
['sa'] = {'санскрит', 'санскрит', 'санскрите', 'санскрита'},
['sah'] = {'якут.', 'якутский язык', 'якутском языке', 'якутского языка'},
['se'] = {'сев.-саам.', 'северносаамский язык', 'северносаамском языке', 'северносаамского языка'},
['sh'] = {'сербохорв.', 'сербохорватский язык', 'сербохорватском языке', 'сербохорватского языка'},
['sd'] = {'синдхи', 'язык синдхи', 'языке синдхи', 'языка синдхи'},
['simple'] = {'прост. англ.', 'упрощённый английский язык', 'упрощённом английском языке', 'упрощённого английского языка'},
['sk'] = {'словацк.', 'словацкий язык', 'словацком языке', 'словацкого языка'},
['sl'] = {'словенск.', 'словенский язык', 'словенском языке', 'словенского языка'},
['sq'] = {'алб.', 'албанский язык', 'албанском языке', 'албанского языка'},
['sr'] = {'серб.', 'сербский язык', 'сербском языке', 'сербского языка'},
['sv'] = {'швед.', 'шведский язык', 'шведском языке', 'шведского языка'},
['sw'] = {'суахили', 'суахили', 'суахили', 'суахили'},
['szl'] = {'силез.', 'силезский язык', 'силезском языке', 'силезского языка'},
['ta'] = {'там.', 'тамильский язык', 'тамильском языке', 'тамильского языка'},
['te'] = {'тел.', 'язык телугу', 'языке телугу', 'языка телугу'},
['tg'] = {'тадж.', 'таджикский язык', 'таджикском языке', 'таджикского языка'},
['th'] = {'тайск.', 'тайский язык', 'тайском языке', 'тайского языка'},
['tk'] = {'туркмен.', 'туркменский язык', 'туркменском языке', 'туркменского языка'},
['tr'] = {'тур.', 'турецкий язык', 'турецком языке', 'турецкого языка'},
['tt'] = {'татар.', 'татарский язык', 'татарском языке', 'татарского языка'},
['udm'] = {'удм.', 'удмуртский язык', 'удмуртском языке', 'удмуртского языка'},
['ug'] = {'уйг.', 'уйгурский язык', 'уйгурском языке', 'уйгурского языка'},
['uk'] = {'укр.', 'украинский язык', 'украинском языке', 'украинского языка'},
['ur'] = {'урду', 'язык урду', 'языке урду', 'языка урду'},
['uz'] = {'узб.', 'узбекский язык', 'узбекском языке', 'узбекского языка'},
['vi'] = {'вьетн.', 'вьетнамский язык', 'вьетнамском языке', 'вьетнамского языка'},
['vo'] = {'вол.', 'волапюк', 'волапюке', 'волапюка'},
['war'] = {'варайск.', 'варайский язык', 'варайском языке', 'варайского языка'},
['xal'] = {'калм.', 'калмыцкий язык', 'калмыцком языке', 'калмыцкого языка'},
['yi'] = {'идиш', 'идиш', 'идише', 'идиша'},
['yo'] = {'йоруба', 'язык йоруба', 'языке йоруба', 'языка йоруба'},
['zh'] = {'кит.', 'китайский язык', 'китайском языке', 'китайского языка'},
['mul'] = {'мн.', 'множество языков', 'множестве языков', 'множества языков'},
['und'] = {'неопр.', 'неопределённый язык', 'неопределённом языке', 'неопределённого языка'},
['ady'] = {'ады.', 'адыгейский язык', 'адыгейском языке', 'адыгейского языка'},
['akk'] = {'аккад.', 'аккадский язык', 'аккадском языке', 'аккадского языка'},
['alt'] = {'алт.', 'алтайский язык', 'алтайском языке', 'алтайского языка'},
['bm'] = {'бамана', 'язык бамана', 'языке бамана', 'языка бамана'},
['bpy'] = {'биш.-ман.', 'бишнуприя-манипури', 'бишнуприя-манипури', 'бишнуприя-манипури'},
['bua'] = {'бур.', 'бурятский язык', 'бурятском языке', 'бурятского языка'},
['bug'] = {'бугийск.', 'бугийский язык', 'бугийском языке', 'бугийского языка'},
['can'] = {'кантабр.', 'кантабрийский язык', 'кантабрийском языке', 'кантабрийского языка'},
['chu'] = {'церк.-сл.', 'церковнославянский язык', 'церковнославянском языке', 'церковнославянского языка'},
['cnr'] = {'черногор.', 'черногорский язык', 'черногорском языке', 'черногорского языка'},
['co'] = {'корс.', 'корсиканский язык', 'корсиканском языке', 'корсиканского языка'},
['cr'] = {'кри', 'язык кри', 'языке кри', 'языка кри'},
['crs'] = {'сеселва', 'сейшельский креольский язык', 'сейшельском креольском языке', 'сейшельского креольского языка'},
['de-at'] = {'австр.', 'австрийский вариант немецкого языка', 'австрийском варианте немецкого языка', 'австрийского варианта немецкого языка'},
['de-ch'] = {'швц-нем.', 'швейцарский вариант немецкого языка', 'швейцарском варианте немецкого языка', 'швейцарского варианта немецкого языка'},
['dsb'] = {'нижнелуж.', 'нижнелужицкий язык', 'нижнелужицком языке', 'нижнелужицкого языка'},
['dv'] = {'мальд.', 'мальдивский язык', 'мальдивском языке', 'мальдивского языка'},
['dz'] = {'дзонг-кэ', 'язык дзонг-кэ', 'языке дзонг-кэ', 'языка дзонг-кэ'},
['ee'] = {'эве', 'язык эве', 'языке эве', 'языка эве'},
['en-NZ'] = {'нз. англ.', 'новозеландский английский язык', 'новозеландском английском языке', 'новозеландского английского языка'},
['ff'] = {'фула', 'язык фула', 'языке фула', 'языка фула'},
['fro'] = {'ст.-фр.', 'старофранцузский язык', 'старофранцузском языке', 'старофранцузского языка'},
['fur'] = {'фриульск.', 'фриульский язык', 'фриульском языке', 'фриульского языка'},
['gld'] = {'нан.', 'нанайский язык', 'нанайском языке', 'нанайского языка'},
['gu'] = {'гудж.', 'язык гуджарати', 'языке гуджарати', 'языка гуджарати'},
['gv'] = {'мэнск.', 'мэнский язык', 'мэнском языке', 'мэнского языка'},
['ha'] = {'хауса', 'язык хауса', 'языке хауса', 'языка хауса'},
['hbo'] = {'др.-евр.', 'древнееврейский язык', 'древнееврейском языке', 'древнееврейского языка'},
['ht'] = {'гаит. кр.', 'гаитянский креольский язык', 'гаитянском креольском языке', 'гаитянского креольского языка'},
['ja'] = {'яп.', 'японский язык', 'японском языке', 'японского языка'},
['ig'] = {'игбо', 'язык игбо', 'языке игбо', 'языка игбо'},
['kaa'] = {'к.-калп.', 'каракалпакский язык', 'каракалпакском языке', 'каракалпакского языка'},
['kg'] = {'конго', 'язык конго', 'языке конго', 'языка конго'},
['khot'] = {'хот.-сак.', 'хотаносакский язык', 'хотаносакском языке', 'хотаносакского языка'},
['kl'] = {'гренл.', 'гренландский язык', 'гренландском языке', 'гренландского языка'},
['kn'] = {'канн.', 'язык каннада', 'языке каннада', 'языка каннада'},
['ko-kp'] = {'кор.', 'корейский язык', 'корейском языке', 'корейского языка'},
['koi'] = {'коми-перм.', 'коми-пермяцкий язык', 'коми-пермяцком языке', 'коми-пермяцкого языка'},
['krc'] = {'карач.-балк.', 'карачаево-балкарский язык', 'карачаево-балкарском языке', 'карачаево-балкарского языка'},
['kri'] = {'крио', 'язык крио', 'языке крио', 'языка крио'},
['krl'] = {'карел.', 'карельский язык', 'карельском языке', 'карельского языка'},
['ksh'] = {'рип.', 'рипуарский язык', 'рипуарском языке', 'рипуарского языка'},
['kum'] = {'кум.', 'кумыкский язык', 'кумыкском языке', 'кумыкского языка'},
['kv'] = {'ком.', 'коми язык', 'коми языке', 'коми языка'},
['kw'] = {'корн.', 'корнский язык', 'корнском языке', 'корнского языка'},
['lbe'] = {'лак.', 'лакский язык', 'лакском языке', 'лакского языка'},
['lg'] = {'луганда', 'язык луганда', 'языке луганда', 'языка луганда'},
['liv'] = {'лив.', 'ливский язык', 'ливском языке', 'ливского языка'},
['lld'] = {'лад.', 'ладинский язык', 'ладинском языке', 'ладинского языка'},
['lmo'] = {'ломбард.', 'ломбардийский язык', 'ломбардийском языке', 'ломбардийского языка'},
['ln'] = {'лингала', 'язык лингала', 'языке лингала', 'языка лингала'},
['lo'] = {'лаос.', 'лаосский язык', 'лаосском языке', 'лаосского языка'},
['ltg'] = {'латг.', 'латгальский язык', 'латгальском языке', 'латгальского языка'},
['bms'] = {'баньюм.', 'баньюмасанский язык', 'баньюмасанском языке', 'баньюмасанского языка'},
['mdf'] = {'мокш.', 'мокшанский язык', 'мокшанском языке', 'мокшанского языка'},
['mi'] = {'маори', 'язык маори', 'языке маори', 'языка маори'},
['mis'] = {'неизв.', 'неизвестный язык', 'неизвестном языке', 'неизвестного языка'},
['mr'] = {'мар.', 'язык маратхи', 'языке маратхи', 'языка маратхи'},
['my'] = {'бирм.', 'бирманский язык', 'бирманском языке', 'бирманского языка'},
['na'] = {'наур.', 'науруанский язык', 'науруанском языке', 'науруанского языка'},
['nan'] = {'южн.-минь.', 'южноминьский язык', 'южноминьском языке', 'южноминьского языка'},
['nds'] = {'нижненем.', 'нижненемецкий язык', 'нижненемецком языке', 'нижненемецкого языка'},
['nn'] = {'нюношк', 'новонорвежский язык', 'новонорвежском языке', 'новонорвежского языка'},
['no'] = {'норв.', 'норвежский язык', 'норвежском языке', 'норвежского языка'},
['nog'] = {'ног.', 'ногайский язык', 'ногайском языке', 'ногайского языка'},
['non'] = {'др.-исл.', 'древнеисландский язык', 'древнеисландском языке', 'древнеисландского языка'},
['ny'] = {'ньянджа', 'язык ньянджа', 'языке ньянджа', 'языка ньянджа'},
['oc'] = {'ок.', 'окситанский язык', 'окситанском языке', 'окситанского языка'},
['om'] = {'оромо', 'язык оромо', 'языке оромо', 'языка оромо'},
['orv'] = {'древнерусск.', 'древнерусский язык', 'древнерусском языке', 'древнерусского языка'},
['ota'] = {'осм.', 'османский язык', 'османском языке', 'османского языка'},
['otk'] = {'древнетюрк.', 'древнетюркский язык', 'древнетюркском языке', 'древнетюркского языка'},
['pap'] = {'пап.', 'язык папьяменто', 'языке папьяменто', 'языка папьяменто'},
['pdc'] = {'пенс. нем.', 'пенсильванско-немецкий язык', 'пенсильванско-немецком языке', 'пенсильванско-немецкого языка'},
['pem'] = {'коми-перм.', 'коми-пермяцкий язык', 'коми-пермяцком языке', 'коми-пермяцкого языка'},
['ps'] = {'пушту', 'язык пушту', 'языке пушту', 'языка пушту'},
['pt-BR'] = {'бр. порт.', 'бразильский португальский язык', 'бразильском португальском языке', 'бразильского португальского языка'},
['rap'] = {'рап.', 'рапануйский язык', 'рапануйском языке', 'рапануйского языка'},
['rm'] = {'рет.', 'ретороманский язык', 'ретороманском языке', 'ретороманского языка'},
['rn'] = {'рунди', 'язык рунди', 'языке рунди', 'языка рунди'},
['rom'] = {'цыг.', 'цыганский язык', 'цыганском языке', 'цыганского языка'},
['ru-old'] = {'рус. дореф.', 'русский язык в дореформенной орфографии', 'русском языке в дореформенной орфографии', 'русского языка в дореформенной орфографии'},
['rw'] = {'руанда', 'язык руанда', 'языке руанда', 'языка руанда'},
['sco'] = {'шотл. герм.', 'шотландский (германский) язык', 'шотландском (германском) языке', 'шотландского (германского) языка'},
['si'] = {'сингальский', 'сингальский язык', 'сингальском языке', 'сингальского языка'},
['sjd'] = {'кильд.-саам.', 'кильдинский саамский язык', 'кильдинском саамском языке', 'кильдинского саамского языка'},
['slovio'] = {'словио', 'язык словио', 'языке словио', 'языка словио'},
['sm'] = {'самоан.', 'самоанский язык', 'самоанском языке', 'самоанского языка'},
['sma'] = {'южносаамск.', 'южносаамский язык', 'южносаамском языке', 'южносаамского языка'},
['smj'] = {'луле-саам.', 'луле-саамский язык', 'луле-саамском языке', 'луле-саамского языка'},
['smn'] = {'инари-саам.', 'инари-саамский язык', 'инари-саамском языке', 'инари-саамского языка'},
['sms'] = {'колтта-саам.', 'колтта-саамский язык', 'колтта-саамском языке', 'колтта-саамского языка'},
['ss'] = {'свати', 'язык свати', 'языке свати', 'языка свати'},
['st'] = {'сесото', 'язык сесото', 'языке сесото', 'языка сесото'},
['su'] = {'сунд.', 'сунданский язык', 'сунданском языке', 'сунданского языка'},
['tab'] = {'таб.', 'табарасанский язык', 'табарасанском языке', 'табарасанского языка'},
['ti'] = {'тигр.', 'язык тигринья', 'языке тигринья', 'языка тигринья'},
['tl'] = {'таг.', 'тагальский язык', 'тагальском языке', 'тагальского языка'},
['tn'] = {'тсн.', 'язык тсвана', 'языке тсвана', 'языка тсвана'},
['to'] = {'тонг.', 'тонганский язык', 'тонганском языке', 'тонганского языка'},
['tt-ar'] = {'татар. (араб.)', 'татарский (арабица) язык', 'татарском (арабица) языке', 'татарского (арабица) языка'},
['tt-en'] = {'татар. ян.', 'татарский (яналиф) язык', 'татарском (яналиф) языке', 'татарского (яналиф) языка'},
['tyv'] = {'тувин.', 'тувинский язык', 'тувинском языке', 'тувинского языка'},
['vec'] = {'венет.', 'венетский (современный) язык', 'венетском (современном) языке', 'венетского (современного) языка'},
['vep'] = {'вепс.', 'вепсский язык', 'вепсском языке', 'вепсского языка'},
['wo'] = {'волоф', 'язык волоф', 'языке волоф', 'языка волоф'},
['xh'] = {'коса', 'язык коса', 'языке коса', 'языка коса'},
['lzh'] = {'вэньянь', 'классический китайский язык', 'классическом китайском языке', 'классического китайского языка'},
['zh-tw'] = {'кит. (Тайвань)', 'китайский язык (Тайваньский диалект)', 'китайском языке (Тайваньский диалект)', 'китайского языка (Тайваньский диалект)'},
['yue'] = {'кант.', 'кантонский язык', 'кантонском языке', 'кантонского языка'},
['zu'] = {'зулу', 'язык зулу', 'языке зулу', 'языка зулу'},
}

-- Псевдонимы (aliases)
langs['arm'] = langs['hy']
langs['bat-smg'] = langs['sgs'];
langs['be-x-old'] = langs['be-tarask'];
langs['bh'] = langs['bho'];
langs['bur'] = langs['my'];
langs['mya'] = langs['my'];
langs['bxm'] = langs['bua'];
langs['bxr'] = langs['bua'];
langs['bxu'] = langs['bua'];
langs['es2'] = langs['es'];
langs['fij'] = langs['fj'];
langs['fiu-vro'] = langs['vro'];
langs['kaz'] = langs['kk'];
langs['lat'] = langs['la']
langs['map-bms'] = langs['bms'];
langs['mri'] = langs['mi'];
langs['nep'] = langs['ne'];
langs['roa-nor'] = langs['nox'];
langs['roa-tara'] = langs['tara'];
langs['smi'] = langs['sjd'];
langs['sme'] = langs['se'];
langs['smo'] = langs['sm'];
langs['ton'] = langs['to'];
langs['zh2'] = langs['zh'];
langs['zh-classical'] = langs['lzh'];
langs['zh-min-nan'] = langs['nan'];
langs['zh-yue'] = langs['yue'];
langs['рус'] = langs['ru'];
langs['рус.'] = langs['ru'];
langs['en-GB'] = langs['en'];
langs['en-US'] = langs['en'];
langs['ru-RU'] = langs['ru'];

-- Legacy codes
langs['als'] = langs['gsw'];
langs['cz'] = langs['cs'];
langs['jp'] = langs['ja'];
langs['me'] = langs['cnr'];


local languages = langs -- здесь будет импорт

local ISO639_en = {
['aa'] = 'Afar',
['ab'] = 'Abkhazian',
['ae'] = 'Avestan',
['af'] = 'Afrikaans',
['ain'] = 'Ainu',
['ak'] = 'Akan',
['aln'] = 'Gheg Albanian',
['gsw'] = 'Alemannic',
['am'] = 'Amharic',
['an'] = 'Aragonese',
['ang'] = 'Old English',
['ar'] = 'Arabic',
['arc'] = 'Aramaic',
['arn'] = 'Mapudungun',
['arz'] = 'Egyptian Spoken Arabic',
['as'] = 'Assamese',
['ast'] = 'Asturian',
['av'] = 'Avar',
['avk'] = 'Kotava',
['ay'] = 'Aymara',
['az'] = 'Azerbaijani',
['ba'] = 'Bashkir',
['bar'] = 'Bavarian',
['bcc'] = 'Southern Balochi',
['bcl'] = 'Central Bicolano',
['be'] = 'Belarusian',
['be-tarask'] = 'Belarusian (Taraškievica)',
['bg'] = 'Bulgarian',
['bh'] = 'Bihari',
['bi'] = 'Bislama',
['bm'] = 'Bambara',
['bn'] = 'Bengali',
['bo'] = 'Tibetan',
['bpy'] = 'Bishnupriya Manipuri',
['br'] = 'Breton',
['bs'] = 'Bosnian',
['bto'] = 'Iriga Bicolano',
['bua'] = 'Buryat',
['bug'] = 'Buginese',
['bxr'] = 'Buryat (Russia)',
['ca'] = 'Catalan',
['cdo'] = 'Min Dong Chinese',
['ce'] = 'Chechen',
['ceb'] = 'Cebuano',
['ch'] = 'Chamorro',
['chm'] = 'Mari',
['cho'] = 'Choctaw',
['chr'] = 'Cherokee',
['chy'] = 'Cheyenne',
['co'] = 'Corsican',
['cop'] = 'Coptic',
['cr'] = 'Cree',
['crh'] = 'Crimean Turkish',
['cs'] = 'Czech',
['csb'] = 'Kashubian',
['cu'] = 'Church Slavic',
['cv'] = 'Chuvash',
['cy'] = 'Welsh',
['da'] = 'Danish',
['de'] = 'German',
['diq'] = 'Dimli',
['dsb'] = 'Lower Sorbian',
['dv'] = 'Divehi',
['dz'] = 'Dzongkha',
['ee'] = 'Ewe',
['el'] = 'Greek',
['eml'] = 'Emilian-Romagnol',
['en'] = 'English',
['eo'] = 'Esperanto',
['es'] = 'Spanish',
['et'] = 'Estonian',
['eu'] = 'Basque',
['ext'] = 'Extremaduran',
['fa'] = 'Persian',
['ff'] = 'Fulah',
['fi'] = 'Finnish',
['fil'] = 'Filipino',
['fj'] = 'Fijian',
['fo'] = 'Faroese',
['fr'] = 'French',
['frc'] = 'Cajun French',
['frp'] = 'Franco-Provençal',
['frr'] = 'North Frisian',
['fur'] = 'Friulian',
['fy'] = 'Frisian',
['ga'] = 'Irish',
['gaa'] = 'Ga',
['gag'] = 'Gagauz',
['gan'] = 'Gan Chineese',
['gd'] = 'Scottish Gaelic',
['gl'] = 'Galician',
['glk'] = 'Gilaki',
['gmh'] = 'Middle High German',
['gn'] = 'Guaraní',
['got'] = 'Gothic',
['grc'] = 'Ancient Greek',
['gsw'] = 'Swiss German',
['gu'] = 'Gujarati',
['gv'] = 'Manx',
['ha'] = 'Hausa',
['hak'] = 'Hakka Chinese',
['haw'] = 'Hawaiian',
['he'] = 'Hebrew',
['hi'] = 'Hindi',
['hif'] = 'Fiji Hindi',
['hil'] = 'Hiligaynon',
['ho'] = 'Hiri Motu',
['hr'] = 'Croatian',
['hsb'] = 'Upper Sorbian',
['ht'] = 'Haitian',
['hu'] = 'Hungarian',
['hy'] = 'Armenian',
['hz'] = 'Herero',
['ia'] = 'Interlingua',
['id'] = 'Indonesian',
['ie'] = 'Interlingue',
['ig'] = 'Igbo',
['ii'] = 'Sichuan Yi',
['ik'] = 'Inupiak',
['ilo'] = 'Iloko',
['inh'] = 'Ingush',
['io'] = 'Ido',
['is'] = 'Icelandic',
['it'] = 'Italian',
['iu'] = 'Inuktitut',
['ja'] = 'Japanese',
['jbo'] = 'Lojban',
['jut'] = 'Jutish',
['jv'] = 'Javanese',
['ka'] = 'Georgian',
['kaa'] = 'Kara-Kalpak',
['kar'] = 'Karen',
['kab'] = 'Kabyle',
['kbd'] = 'Kabardian',
['kg'] = 'Kongo',
['ki'] = 'Kikuyu',
['kj'] = 'Kwanyama',
['kk'] = 'Kazakh',
['kal'] = 'Greenlandic',
['km'] = 'Khmer',
['kn'] = 'Kannada',
['ko'] = 'Korean',
['kr'] = 'Kanuri',
['kri'] = 'Krio',
['krj'] = 'Kinaray-A',
['ks'] = 'Kashmiri',
['ksh'] = 'Kölsch',
['ku'] = 'Kurdish',
['kv'] = 'Komi',
['kw'] = 'Cornish',
['ky'] = 'Kirghiz',
['la'] = 'Latin',
['lad'] = 'Ladino',
['lb'] = 'Luxembourgish',
['lbe'] = 'Lak',
['lez'] = 'Lezghian',
['art'] = 'Lingua Franca Nova',
['lg'] = 'Ganda',
['li'] = 'Limburgish',
['lij'] = 'Ligurian',
['roa'] = 'Ladin',
['lmo'] = 'Lombard',
['ln'] = 'Lingala',
['lo'] = 'Lao',
['loz'] = 'Lozi',
['lt'] = 'Lithuanian',
['lu'] = 'Luba-Katanga',
['lv'] = 'Latvian',
['lzz'] = 'Laz',
['mad'] = 'Madurese',
['mai'] = 'Maithili',
['mc'] = 'Murcian',
['mdf'] = 'Moksha',
['mg'] = 'Malagasy',
['mh'] = 'Marshallese',
['mi'] = 'Māori',
['mk'] = 'Macedonian',
['ml'] = 'Malayalam',
['mn'] = 'Mongolian',
['mni'] = 'Manipuri',
['mo'] = 'Moldavian',
['mr'] = 'Marathi',
['ms'] = 'Malay',
['mt'] = 'Maltese',
['mus'] = 'Creek',
['mwl'] = 'Mirandese',
['my'] = 'Burmese',
['myv'] = 'Erzya',
['mzn'] = 'Mazanderani',
['na'] = 'Nauru',
['nah'] = 'Nahuatl languages',
['nap'] = 'Neapolitan',
['nb'] = 'Norwegian Bokmål',
['no'] = 'Norwegian',
['nd'] = 'North Ndebele',
['nds'] = 'Low Saxon',
['ne'] = 'Nepali',
['new'] = 'Newar / Nepal Bhasa',
['ng'] = 'Owambo',
['niu'] = 'Niuean',
['nl'] = 'Dutch',
['nn'] = 'Norwegian (Nynorsk)',
['non'] = 'Old Norse',
['nov'] = 'Novial',
['nr'] = 'South Ndebele',
['nrm'] = 'Narom',
['nso'] = 'Northern Sotho',
['nv'] = 'Navajo',
['ny'] = 'Chichewa',
['oc'] = 'Occitan',
['och'] = 'Classical Chinese',
['oj'] = 'Ojibwa',
['om'] = 'Oromo',
['or'] = 'Oriya',
['os'] = 'Ossetian',
['pa'] = 'Panjabi',
['pag'] = 'Pangasinan',
['pal'] = 'Pahlavi',
['pam'] = 'Kapampangan',
['pap'] = 'Papiamento',
['pdc'] = 'Pennsylvania German',
['pdt'] = 'Plautdietsch',
['pfl'] = 'Pfaelzisch',
['pi'] = 'Pali',
['pih'] = 'Pitcairn-Norfolk',
['pl'] = 'Polish',
['plm'] = 'Palembang',
['pms'] = 'Piemontese',
['pnt'] = 'Pontic',
['pra'] = 'Prakrit',
['ps'] = 'Pashto',
['pt'] = 'Portuguese',
['qu'] = 'Quechua',
['rif'] = 'Tarifit',
['rm'] = 'Raeto-Romance',
['rmy'] = 'Vlax Romani',
['rn'] = 'Kirundi',
['ro'] = 'Romanian',
['roh'] = 'Romansh',
['ru'] = 'Russian',
['rue'] = 'Rusyn',
['ruq'] = 'Romanian',
['rw'] = 'Kinyarwanda',
['sa'] = 'Sanskrit',
['sah'] = 'Yakut',
['sc'] = 'Sardinian',
['scn'] = 'Sicilian',
['sco'] = 'Scots',
['sd'] = 'Sindhi',
['sdc'] = 'Sardinian',
['se'] = 'Northern Sami',
['sei'] = 'Seri',
['sg'] = 'Sango',
['sh'] = 'Serbo-Croatian',
['shi'] = 'Tachelhit',
['si'] = 'Sinhala',
['simple'] = 'Simple English',
['sk'] = 'Slovak',
['sl'] = 'Slovene',
['sm'] = 'Samoan',
['sma'] = 'Southern Sami',
['sn'] = 'Shona',
['so'] = 'Somali',
['sq'] = 'Albanian',
['sr'] = 'Serbian',
['srn'] = 'Sranan Tongo',
['ss'] = 'Swati',
['st'] = 'Sotho',
['stq'] = 'Saterland Frisian',
['su'] = 'Sundanese',
['sux'] = 'Sumerian',
['sv'] = 'Swedish',
['sw'] = 'Swahili',
['syr'] = 'Syriac',
['szl'] = 'Silesian',
['ta'] = 'Tamil',
['te'] = 'Telugu',
['tet'] = 'Tetum',
['tg'] = 'Tajik',
['th'] = 'Thai',
['ti'] = 'Tigrinya',
['tk'] = 'Turkmen',
['tl'] = 'Tagalog',
['tlh'] = 'Klingon',
['tn'] = 'Tswana',
['to'] = 'Tonga',
['tpi'] = 'Tok Pisin',
['tr'] = 'Turkish',
['ts'] = 'Tsonga',
['tt'] = 'Tatar',
['tum'] = 'Tumbuka',
['tw'] = 'Twi',
['ty'] = 'Tahitian',
['tyv'] = 'Tyvan',
['tzm'] = 'Central Morocco Tamazight',
['udm'] = 'Udmurt',
['ug'] = 'Uighur',
['uk'] = 'Ukrainian',
['ur'] = 'Urdu',
['uz'] = 'Uzbek',
['ve'] = 'Venda',
['vec'] = 'Venetian',
['vi'] = 'Vietnamese',
['vls'] = 'Vlaams',
['vo'] = 'Volapük',
['vrm'] = 'Värmlandic',
['wa'] = 'Walloon',
['war'] = 'Waray',
['wo'] = 'Wolof',
['wuu'] = 'Wu Chinese',
['xal'] = 'Kalmyk',
['xh'] = 'Xhosa',
['xmf'] = 'Mingrelian',
['ydd'] = 'Eastern Yiddish',
['yi'] = 'Yiddish',
['yo'] = 'Yoruba',
['yue'] = 'Cantonese',
['za'] = 'Zhuang',
['zea'] = 'Zeeuws',
['zh'] = 'Chinese',
['cmn'] = 'Chinese',
['zu'] = 'Zulu',
['mul'] = 'Multiple languages',
}

function p._ref_info(args)
	local text = args[1]   -- text to format
	local hint = args[2]   -- text to include as a hint when approached with cursor
	local square = args[3] -- change parentheses () to brackets []
	
	local str = nil
	if (hint) then
		str = "&nbsp;<small class=\"ref-info\" style=\"cursor:help;\" title=\""..hint.."\">"
	else
		str = "&nbsp;<small class=\"ref-info\" >"
	end
	if (square == 'в') then
		str = str..'['..text..']</small>'
	else
		str = str..'('..text..')</small>'
	end
	return str
end

function p._ref_lang(args)
	local short_name   = args[1]   -- short name of language (рус., англ.)
	local before_name  = args[2]   -- name of language before "языке" (английском языке)
	local after_name   = args[3]   -- name of language after "языке" (языке Фарси)
	local replace_text = args[4]   -- full text instead of building around "языке" (на множестве языков)
	local square = args[5] or args['в'] -- change parentheses () to brackets []
	
	local t = {[1] = short_name}
	
	if replace_text then
		t[2] = "на "..replace_text
	else
		if before_name or after_name then
			t[2] = "на "..(before_name or "").." языке "..(after_name or "")
		end
	end
	
	if square then
		t[3] = 'в'
	end
	
	return p._ref_info(t)
end

function p._lang_by_code(args)
	local lang = args[1]
	local target_lang = args[2] or 'ru'
	local mode = args[3] or args['падеж'] -- использовался для хранения падежа, может теоретически хранить разные режимы вывода
	
	if target_lang == 'en' then
		return p._lang_by_code_en({[1]=lang,['падеж']=mode})
	else
		return p._lang_by_code_ru({[1]=lang,['падеж']=mode})
	end
end

function p._lang_by_code_ru(args)
	local lang = args[1]
	local mode = args[3] or args['падеж'] -- использовался для хранения падежа, может теоретически хранить разные режимы вывода
	
	if not lang then
		return "<span class=\"error\">Не указан языковой код</span>"
	end
	local extracted = languages[lang]
	if not extracted then
		return "<span class=\"error\">Не распознан языковой код</span>" -- отслеживающую категорию?
	end
	if not mode then
		return extracted[2]
	elseif mode=='р' then
		return extracted[4]
	elseif mode=='п' then
		return extracted[3]
	else
		return "<span class=\"error\">Не распознан падеж</span>" -- отслеживающую категорию?
	end
end

function p._lang_by_code_en(args)
	local lang = args[1]
	local mode = args[3] or args['падеж'] -- использовался для хранения падежа, может теоретически хранить разные режимы вывода; сейчас для английского не используется
	
	if not lang then
		return "<span class=\"error\">Не указан языковой код</span>"
	end
	local extracted = ISO639_en[lang]
	if not extracted then
		return "<span class=\"error\">Не распознан языковой код</span>" -- отслеживающую категорию?
	end
	return extracted
end

-- эмулирует шаблоны ref-aa и подобные
-- по сравнению с ними содержит обработку ошибок с кодом языка, аналогичную ЯзыкПоКоду
function p._ref_lang_by_code(args)
	local lang = args[1]
	local square = args[3] -- change parentheses () to brackets []
	                       -- we pass this argument further
	
	if not lang then
		return "<span class=\"error\">Не указан языковой код</span>"
	end
	local extracted = languages[lang]
	if not extracted then
		return "<span class=\"error\">Не распознан языковой код</span>" -- отслеживающую категорию?
	end
	local t = {}
	t[1] = extracted[1]
	t[4] = p._lang_by_code_ru({[1]=lang,[3]='п'})
	t[5] = square
	
	return p._ref_lang(t)
end

function p._cite_web_lang (args)
	local lang = args[1]
	local title = args[2]
	
	if not lang then
		local str = '<span class="hidden-ref" style="display:none">\'\'\''..p._ref_lang_by_code({'und'})..'\'\'\'</span>'
		if (mw.ustring.gmatch(title,'[0-9А-яЁё«»:;,…!?  \(\)\.—№\/\&\#+-]+') ~= title) and (pageNamespace == 0) then
			-- Логика из версии cite-web на 10.05.2022
			-- Идея в том, что если есть в заголовке (источника) что-то кроме кириллицы и препинания, то отбражаем категорию "не указан язык",
			-- но если только кириллицы и знаки препинания, то скорее всего всё равно это русский
			str = str..'[[Категория:Википедия:Cite web (не указан язык)]]'
		end
		return str
	else
		local extracted = languages[lang]
		if not extracted then
			local lang_list = {}
			local iterator = mw.ustring.gmatch(lang, "[^/]+");
			for w in iterator do
				tinsert(lang_list, w)
			end
			-- we have split string 'en/fr/aa' into table {en, fr, aa}    
			if #lang_list == 0 or #lang_list == 1 then
        		local str = '<span class="hidden-ref" style="display:none">\'\'\''..p._ref_lang_by_code({'und'})..'\'\'\'</span>'
				if pageNamespace == 0 then
					str = str..'[[Категория:Википедия:Cite web (неверный код языка)]]'
				end
				return str
			else
				local t = {}
				for _, w in ipairs(lang_list) do
					tinsert(t, p._cite_web_lang({w, title}))
					-- вызываем функцию ещё раз, передавая уже языки по отдельности
					-- это очень неэффективно, но эта ситуация в реальности почти не встречается
					--
					-- теоретически можно обменять местами условия, сначала разделив по разделителю, 
					-- а потом уже проверяя на наличие в таблице языков,
					-- но тогда будет сначала проверяться РЕДКОЕ условие с помощью дорогой функции gmatch
				end
				return table.concat(t)
			end
		else
			if lang=='ru' or lang=='ru-RU' then
				return '<span class="hidden-ref" style="display:none">&nbsp;<small class="ref-info" style="cursor:help;" title="на русском языке">(рус.)</small></span>'
			else
				return p._ref_lang_by_code({lang})
			end
		end
	end
end

function p._cite_web (args)
	local t = {}
	
	if args[1] then
		local tl = require('Module:Template call code').withoutParams -- this is {{tl| }}
		local tl_citeweb = tl({'cite web'})
		tinsert(t,'<strong class="error">Все параметры шаблона ')
		tinsert(t, tl_citeweb)
		tinsert(t, ' должны иметь имя.</strong>&32;')
		if pageNamespace == 0 then
			tinsert(t,'[[Категория:Википедия:Cite web (некорректное использование)]]')
		end
	end
	if not args['title'] then
		local tl = require('Module:Template call code').withoutParams -- this is {{tl| }}
		local tl_citeweb = tl({'cite web'})
		tinsert(t, '<strong class="error">Необходимо задать параметр ')
		tinsert(t, (mw.getCurrentFrame()):extensionTag('code','title='))
		tinsert(t, ' в шаблоне ')
		tinsert(t, tl_citeweb)
		tinsert(t, '.</strong>&32;')
		if pageNamespace == 0 then
			tinsert(t, '[[Категория:Википедия:Cite web (некорректное использование)]]')
		end
	end
	if not args['url'] then
		local tl = require('Module:Template call code').withoutParams -- this is {{tl| }}
		local tl_citeweb = tl({'cite web'})
		tinsert(t, '<strong class="error">Необходимо задать параметр ')
		tinsert(t, (mw.getCurrentFrame()):extensionTag('code','url='))
		tinsert(t, ' в шаблоне ')
		tinsert(t, tl_citeweb)
		tinsert(t, '.</strong>&32;')
		if pageNamespace == 0 then
			tinsert(t, '[[Категория:Википедия:Cite web (некорректное использование)]]')
		end
	end
	
	local ref = args['ref']
	local date = args['date'] or args['datepublished'] -- в этом месте в шаблоне было {{{date|}}}, но дальше по тексту был синоним, логично так
	if ref then
		tinsert(t, '<span class="citation" id="')
		tinsert(t, mw.uri.anchorEncode('CITEREF'..ref) )
		tinsert(t, '"><span class="citation" id="')
		local mwlang = mw.getContentLanguage()
		local res = mwlang:formatDate('Y', date)
		tinsert(t, mw.uri.anchorEncode('CITEREF'..ref..res) )
		tinsert(t, '">')
	else
		tinsert(t, '<span class="citation" ><span class="citation" >')
	end
	
	local deadlink = args['deadlink'] or args['deadurl'] or args['dead-url']
	-- просто первый непустой подавляет остальные - так же было в самом шаблоне, при желании можно потом усложнить логику
	
	local archiveurl = args['archiveurl'] or args['archive-url']
	local archivedate = args['archivedate'] or args['archive-date'] -- не уверен, надо ли так
	
	if (archiveurl or archivedate) then
		if not(archiveurl and archivedate) then
			local tl = require('Module:Template call code').withoutParams -- this is {{tl| }}
			local tl_citeweb = tl({'cite web'})
			tinsert(t, '<strong class=\"error\">Если в шаблоне ')
			tinsert(t, tl_citeweb)
			tinsert(t, 'задаётся параметр ')
			tinsert(t, (mw.getCurrentFrame()):extensionTag('code','archiveurl='))
			tinsert(t, ', должен задаваться и параметр')
			tinsert(t, (mw.getCurrentFrame()):extensionTag('code','archivedate='))
			tinsert(t, ', и наоборот.</strong>&32;')
			if pageNamespace == 0 then
				tinsert(t, '[[Категория:Википедия:Cite web (некорректное использование)]]')
			end
		end
	elseif (deadlink=='yes') then
		if pageNamespace == 0 then
			tinsert(t, '[[Категория:Википедия:Cite web (недоступные ссылки без архивной копии)]]')
		end
	end
	
	local author = args['author']
	local last1 = args['last'] or args['last1']
	local last2 = args['last2']
	local last3 = args['last3']
	local last4 = args['last4']
	local last5 = args['last5']
	local coauthors = args['coauthors']
	local authorlink = args['author-link'] or args['authorlink']
	if author or last1 then
		tinsert(t, '\'\'')
		if authorlink then
			tinsert(t, '[[')
			tinsert(t, authorlink)
			tinsert(t, '|')
		end
		
		
		if last1 then
			tinsert(t, last1)
			local first1 = args['first'] or args['first1']
			if first1 then
				tinsert(t, ', ')
				tinsert(t, first1)
			end
		else
			if last2 or coauthors then
				tinsert(t, author)
			else
				-- in this case author= may contain multiple
				local res = mw.ustring.gsub(author, '^(%[*)(.-[^%.%]])(%]*)$', '%1%2%3.')
				tinsert(t, res)
			end
		end
		if authorlink then
			tinsert(t, ']]')
		end
		
		-- эту логику естественно выделить в функцию, но t передавать нехорошо, а иначе проиграем на table.concat
		-- вариант -- сделать локальную функцию прямо здесь, чтобы t было для неё снаружи?
		-- проще -- написать изящный while так, чтобы поддерживалось неограниченное число аргументов?
		if last2 then
			tinsert(t, '<nowiki>;</nowiki>&#32;')
			tinsert(t, last2)
			local first2 = args['first2']
			if first2 then
				tinsert(t, ', ')
				tinsert(t, first2)
			end
		end
		if last3 then
			tinsert(t, '<nowiki>;</nowiki>&#32;')
			tinsert(t, last3)
			local first3 = args['first3']
			if first3 then
				tinsert(t, ', ')
				tinsert(t, first3)
			end
		end
		if last4 then
			tinsert(t, '<nowiki>;</nowiki>&#32;')
			tinsert(t, last2)
			local first4 = args['first4']
			if first4 then
				tinsert(t, ', ')
				tinsert(t, first4)
			end
		end
		if last5 then
			tinsert(t, '<nowiki>;</nowiki>&#32;')
			tinsert(t, last5)
			local first5 = args['first5']
			if first5 then
				tinsert(t, ', ')
				tinsert(t, first5)
			end
		end
		
		if coauthors then
			tinsert(t, '<nowiki>;</nowiki>&#32;')
			local res = mw.ustring.gsub(coauthors, '^(.-)%.?$', '%1.')
			tinsert(t, res)
		end
		
		tinsert(t, '\'\'&#32;')
	end
	
	local editor = args['editor']
	if editor then
		tinsert(t, editor)
		tinsert(t, ':&32;')
	end
	
	local url = args['url']
	local lang = args['lang'] or args['language']
	local title = args['title']
	local subtitle = args['subtitle']
	
	local dot = '.'
	if subtitle then
		dot = '<small>.</small>'
	end
	
	if url then
		-- здесь эмулируется поведение шаблона {{lang}} (не путать с производными от него {{lang-xyz}})
		local str = '['..url..' '..title..']'
		if subtitle then
			str = str..'.&#32;<small>'..subtitle..'</small>'
		end
		--local res = frame:expandTemplate{ title = 'lang', args = {lang or 'und', str} }
		tinsert(t, '<span lang="')
		tinsert(t, lang or 'und')
		tinsert(t, '" xml:lang="')
		tinsert(t, lang or 'und')
		tinsert(t, '">')
		tinsert(t, str)
		tinsert(t, '</span>')
	end
	
	tinsert(t, p._cite_web_lang({lang, title}))
	
	local format = args['format']
	if format then
		tinsert(t, '&#32;(')
		tinsert(t, format)
		tinsert(t, ')')
	end
	
	if deadlink=='none' then
		-- этот случай обрабатывается отдельно согласно https://ru.wikipedia.org/wiki/Обсуждение_шаблона:Cite_web/Архив/2006—2015#deadlink
		-- вставлю здесь раскрытие шаблона как временный хак
		local frame = mw.getCurrentFrame()
		local res = frame:expandTemplate{ title = 'недоступная ссылка' }
		tinsert(t, res)
	elseif deadlink and deadlink ~= 'no' then
		if archiveurl then
			tinsert(t, p._ref_info({'недоступная ссылка'}))
		else
			local str = 'недоступная ссылка&nbsp;— [//web.archive.org/web/*/'..url..' \'\'история\'\'] ' 
				-- в шаблоне было не url, а {{{url|{{{1|}}}}}}, но в случае параметра 1 он должен падать с ошибкой
			tinsert(t, p._ref_info({str}))
		end
	end
	
	local website = args['website'] or args['work'] -- в шаблоне странно они используются, но выходит по факту как синонимы
	if website then
		tinsert(t, dot)
		tinsert(t, '&#32;\'\'')
		tinsert(t, website)
		tinsert(t, '\'\'')
	end
	
	local pages = args['pages']
	local page  = args['page']
	if pages then
		tinsert(t, '&#32;')
		tinsert(t, pages)
	end
	if page then
		tinsert(t, '&#32;')
		tinsert(t, page)
	end
	
	local publisher = args['publisher']
	if publisher then
		local location = args['location']
		tinsert(t, dot)
		tinsert(t, '&#32;')
		if location then
			tinsert(t, location)
			tinsert(t, ':&#32;')
		end
		tinsert(t, ' ')
		tinsert(t, publisher)
	end
	
	if date then
		tinsert(t, '&#32;(')
		-- этот кусок будет переписан на вызов чего-нибудь из модуля Carn'a
		-- здесь получается ссылка на фрейм, я её не делаю снаружи, потому что она будет потом не нужна в хороших ветвях
		local frame = mw.getCurrentFrame()
		local res = frame:expandTemplate{ title = 'HumanizeDate', args = {date} }
		tinsert(t, res)
		tinsert(t, ')')
	else
		local year = args['year']
		if year then
			tinsert(t, '&#32;(')
			local month = args['month']
			if month then
				tinsert(t, month)
				tinsert(t, ' ')
			end
			tinsert(t, year)
			tinsert(t, ')')
		end
	end
	
	tinsert(t, dot)
	
	local doi = args['doi']
	if doi then
		tinsert(t, '&#32;[[Идентификатор цифрового объекта|doi]]:[http://dx.doi.org/')
		tinsert(t, doi)
		tinsert(t, ' ')
		tinsert(t, doi)
		tinsert(t, '].')
	end
	
	local description = args['description']
	if description then
		tinsert(t, '&nbsp;— ')
		tinsert(t, description)
		tinsert(t, '.')
	end
	
	local quote = args['quote']
	if quote then
		tinsert(t, '&nbsp;— «')
		tinsert(t, quote)
		tinsert(t, '».')
	end
	
	local accessdate = args['accessdate'] or args['access-date']
	if accessdate then
		tinsert(t, '&#32;<small>Дата обращения: ')
		-- сейчас будет совсем грязно, это НУЖНО переделать
		--local frame = mw.getCurrentFrame()
		--local res = frame:callParserFunction('#time',{'j xg Y', accessdate})
		local mwlang = mw.getContentLanguage()
		local res = mwlang:formatDate('j xg Y', accessdate)
		if mw.ustring.match( res, 'error' ) then
			res = accessdate
		end
		tinsert(t, res)
		tinsert(t, '.</small>')
	end
	
	if archivedate then
		tinsert(t, '&#32;<small>[')
		tinsert(t, archiveurl)
		tinsert(t, ' Архивировано] ')
		-- сейчас будет совсем грязно, это НУЖНО переделать
		--local frame = mw.getCurrentFrame()
		--local res = frame:callParserFunction('#time',{'j"&nbsp;"xg Y', archivedate})
		local mwlang = mw.getContentLanguage()
		local res = mwlang:formatDate('j"&nbsp;"xg Y', archivedate)
		if mw.ustring.match( res, 'error' ) then
			res = archivedate
		else
			res = res..'&nbsp;года'
		end
		tinsert(t, res)
		tinsert(t, '.</small>')
	end
	
	tinsert(t, '</span></span>')
	
	if pageNamespace==0 then
		if not (mw.ustring.match(url, '^https?://') or mw.ustring.match(url, '^ftp://')) then -- в шаблоне было с replace, но вроде бы логика идентична
			tinsert(t, '[[Категория:Википедия:Cite web (некорректный url)]]')
		elseif mw.ustring.match(url, ' ') then
			tinsert(t, '[[Категория:Википедия:Cite web (некорректный url)]]')
		end
	end
	
	return table.concat(t)
end

return p