Module:User:Surjection/vro-decl

This is a private module sandbox of Surjection, for their own experimentation. Items in this module may be added and removed at Surjection's discretion; do not rely on this module's stability.


local export = {}

local m_languages = require('Module:languages')
local m_links = require('Module:links')

local lang = m_languages.getByCode('vro')

local vowels = "aeiouäõyöü"
local consonants = "bcdfghjklmnpqrsštvwxyzžǵḿńṕŕśv́ź"



----------------------
-- COMMON UTILITIES --
----------------------



local RARE = mw.ustring.char(0x100000)

local function link(x, accel_form)
	return m_links.full_link({ lang = lang, term = x, accel = accel_form and { form = accel_form } or nil})
end

local function mention(x)
	return m_links.full_link({ lang = lang, term = x }, 'term')
end

local function append(t, s)
	if type(t) == 'table' then
		local r = {}
		for i, f in ipairs(t) do
			r[i] = f .. s
		end
		return r
	end
	return t .. s
end

local function append_d(t, s)
	if type(t) == 'table' then
		local r = {}
		for i, f in ipairs(t) do
			r[i] = append_d(f, s)
		end
		return r
	end
	if mw.ustring.find(t, '[kptshf]$') then
		t = t .. 't'
	else
		t = t .. 'd'
	end
	if s then t = t .. s end
	return t
end

local function gsub_all(t, s, d)
	if type(t) == 'table' then
		local r = {}
		for i, f in ipairs(t) do
			r[i] = gsub_all(f, s, d)
		end
		return r
	end
	return mw.ustring.gsub(t, s, d)
end

local function join(...)
	local t = {}
	local args = {...}
	for i, v in ipairs(args) do
		if type(v) == 'table' then
			for j, x in ipairs(v) do
				table.insert(t, x)
			end
		else
			table.insert(t, v)
		end
	end
	return t
end

local function detect_vh(word)
	if word == nil then return nil end

	local i = mw.ustring.len(word)

	while i > 0 do
		local c = mw.ustring.sub(word, i, i)
		if mw.ustring.find(c, '[aõou]') then
			return 'a'
		elseif mw.ustring.find(c, '[äeöü]') then
			return 'ä'
		end
		i = i - 1
	end

	return fallback
end

local vowels_back  = {['a'] = 'a', ['e'] = 'õ', ['o'] = 'o', ['u'] = 'u'}
local vowels_front = {['a'] = 'ä', ['e'] = 'e', ['o'] = 'ö', ['u'] = 'ü'}
local function get_vowels(data, v)
	if v == nil then
		-- automatic
		v = detect_vh(data.lemma)
		
		if v == nil then v = 'ä' end
	end

	if v == 'a' then
		data.vowels = vowels_back
	elseif v == 'ä' then
		data.vowels = vowels_front
	else
		error('Invalid vowel harmony specification (must be a/ä)')
	end
end



--------------------
-- STEMS TO FORMS --
--------------------



-- nominal stems:
--     NAME     DESCRIPTION                FALLBACK
--      sg       singular stem              - (required)
--      sg_nom   nominative singular form   sg
--      sg_par   partitive singular stem    sg_nom + t
--      sg_ill   illative singular stem     sg     + h
--      pl       plural stem                - (required)
--      pl_gen   genitive plural stem       pl     + DE
--      pl_par   partitive plural stem      pl     + t
--      pl_ill   illative plural stem       pl     + h

-- nominal forms:
--      nom         nominative
--      gen         genitive
--      par         partitive
--      ill         illative
--      ine         inessive
--      ela         elative
--      all         allative
--      ade         adessive
--      abl         ablative
--      tra         translative
--      ter         terminative
--      abe         abessive
--      com         comitative
--      +_sg singular  +_pl plural

local function make_forms(data, stems)
	local f      = {}
	local v      = data.vowels

	local sg     = stems.sg or error('sg is required')
	local sg_nom = stems.sg_nom or sg
	local sg_par = stems.sg_par or append(sg, 't')
	local sg_ill = stems.sg_ill or append(sg_par, 'h')

	local pl     = stems.pl or error('pl is required')
	local pl_gen = stems.pl_gen or append_d(pl, v.e)
	local pl_par = stems.pl_par or append(pl, 't')
	local pl_ill = stems.pl_ill or append(pl, 'h')

	if data.number ~= 'pl' then
		f.nom_sg = sg_nom
		f.gen_sg = sg
		f.par_sg = sg_par
		f.ill_sg = gsub_all(sg_ill, '([hdt])$', { ['h'] = 'he', ['d'] = 'd' .. v.e, ['t'] = 't' .. v.e })
		f.ine_sg = join(append(sg, 'n'), append(sg, 'hn'))
		f.ela_sg = append(sg, 'st')
		f.all_sg = append(sg, 'l' .. v.e)
		f.ade_sg = append(sg, 'l')
		f.abl_sg = append(sg, 'lt')
		f.tra_sg = append(sg, 's')
		f.ter_sg = append(sg, 'niq')
		f.abe_sg = append(sg, 'ld' .. v.a .. 'q')
		f.com_sg = append(sg, 'g' .. v.a .. 'q')
	end

	if data.number ~= 'sg' then
		f.nom_pl = append(sg, 'q')
		f.gen_pl = pl_gen
		f.par_pl = pl_par
		f.ill_pl = gsub_all(pl_ill, '([hdt])$', { ['h'] = 'he', ['d'] = 'd' .. v.e, ['t'] = 't' .. v.e })
		f.ine_pl = join(append(pl, 'n'), append(pl, 'hn'))
		f.ela_pl = append(pl, 'st')
		f.all_pl = append(pl, 'l' .. v.e)
		f.ade_pl = append(pl, 'l')
		f.abl_pl = append(pl, 'lt')
		f.tra_pl = append(pl, 's')
		f.ter_pl = append(pl, 'niq')
		f.abe_pl = append(pl, 'ld' .. v.a .. 'q')
		f.com_pl = append(pl_gen, 'g' .. v.a .. 'q')
	end

	-- deduplicate
	for fkey, forms in pairs(f) do
		local n_forms = #forms
		if type(forms) == 'table' then
			local found = {}
			local j = 1
			for i = 1, n_forms do
				local form = forms[i]
				if not found[form] then
					found[form] = true
					forms[j] = form
					j = j + 1
				end
			end
			forms[j] = nil
		end
	end

	return f
end

local function inflection_type_is(data, info)
	local info_text = 'like ' .. mention(data.class)

	if info.ves then
		if type(info.ves) == 'table' then
			info_text = info_text .. ', VES ' .. table.concat(info.ves, '/')
		else
			info_text = info_text .. ', VES ' .. tostring(info.ves)
		end
	end

	if info.kt then
		if type(info.kt) == 'table' then
			info_text = info_text .. ', KT ' .. table.concat(info.kt, '/')
		else
			info_text = info_text .. ', KT ' .. tostring(info.kt)
		end
	end

	data.info = info_text
end



------------------------
-- ARGUMENT INTERFACE --
------------------------



local function parse_grade(g)
	if not g then return '', '' end
	return mw.ustring.match(g, '(.-)/(.*)')
end

local function palatalize(x)
	return mw.ustring.gsub(x, "([gmnprsvz])'", {
		['g'] = 'ǵ', ['m'] = 'ḿ', ['n'] = 'ń', ['p'] = 'ṕ',
		['r'] = 'ŕ', ['s'] = 'ś', ['v'] = 'v́', ['z'] = 'ź'
	})
end

local function find_final_vowel(x)
	return mw.ustring.match(x, '([' .. vowels .. '])[^' .. vowels .. ']*$')
end

local function find_final_consonant(x)
	return mw.ustring.match(x, '([' .. consonants .. "]'?)[^" .. consonants .. ']*$')
end

local function find_final_liquid(x)
	local l = mw.ustring.match(x, "([lnrńŕ]'?)[^lnrńŕ]*$")
	return mw.ustring.gsub(l, "'ńŕ", { ["'"] = "", ["ń"] = "n", ["ŕ"] = "r" })
end

local function geminate(x)
	return mw.ustring.gsub(x, "([kptbdg])", {
		["b"] = "p", ["d"] = "t", ["g"] = "k",
		["k"] = "kk", ["p"] = "pp", ["t"] = "tt" 
	})
end

local function geminate_broad(x, d)
	if x and x ~= '' then
		return geminate(x)
	else
		return mw.ustring.match(d, '[hlmnrsv]') or ''
	end
end

local function altify(x)
	x = mw.ustring.gsub(x, "ii$", "ee")
	x = mw.ustring.gsub(x, "uu$", "oo")
	x = mw.ustring.gsub(x, "üü$", "öö")
	return x
end

local function args_base_vh(data)
	local vh = data.args['v']
	get_vowels(data, vh)
	return data.args[1], data.vowels
end

local function args_base_final_vh(data, default_final)
	local vh = data.args['v'] or detect_vh(data.args['f'])
	get_vowels(data, vh)
	local final
	if default_final == false then
		final = data.args['f']
		if not final then error('Final vowel must be specified with |f=') end
	else
		final = data.args['f'] or (default_final and data.vowels[default_final] or default_final) or find_final_vowel(data.lemma)
		if final == true then final = find_final_vowel(data.lemma) end
	end
	return data.args[1], data.vowels, final
end

local function args_base_grade_vh(data)
	local vh = data.args['v']
	get_vowels(data, vh)
	local g1, g2 = parse_grade(data.args['g'])
	return data.args[1], g1, g2, data.vowels
end

local function args_base_grade_final_vh(data, default_final)
	local vh = data.args['v'] or detect_vh(data.args['f'])
	get_vowels(data, vh)
	local g1, g2 = parse_grade(data.args['g'])
	local final
	if default_final == false then
		final = data.args['f']
		if not final then error('Final vowel must be specified with |f=') end
	else
		final = data.args['f'] or (default_final and data.vowels[default_final] or default_final) or find_final_vowel(data.lemma)
		if final == true then final = find_final_vowel(data.lemma) end
	end
	return data.args[1], g1, g2, final, data.vowels
end



------------------------
-- INFLECTION CLASSES --
------------------------



local inflections = {}

inflections['suhvli'] = function (data)
	inflection_type_is(data, { ves = 1, kt = { 2, 5 } })
	local base, v = args_base_vh(data)

	local pl
	if mw.ustring.find(base, 'i$') then
		pl = { base, base .. 'i' }
	else
		pl = { base .. 'i' }
	end

	return make_forms(data, {
		sg = base,
		pl = pl,
		pl_par = append(pl, 'd')
	})
end

inflections['perädü'] = function (data)
	inflection_type_is(data, { ves = 1, kt = 3 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final .. 'h',
		pl = base .. strong .. final .. 'i',
		pl_par = base .. strong .. final .. 'id',
	})
end

inflections['alostõt'] = function (data)
	inflection_type_is(data, { ves = 1 })
	local base, strong, weak, final, v = args_base_final_vh(data, 'u')
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		pl = { base .. weak .. final .. 'i', base .. weak .. final .. 'isi' },
		pl_gen = { base .. weak .. final .. 'id' .. v.e, base .. weak .. final .. 'isi' },
		pl_par = { base .. weak .. final .. 'id', base .. weak .. final .. 'isi' },
	})
end

inflections['hanśa'] = function (data)
	inflection_type_is(data, { ves = 2, kt = 1 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base,
		sg_ill = base .. 'ht',
		pl = append_d(base, v.e),
		pl_par = base .. 'sit',
	})
end

inflections['oppaja'] = function (data)
	inflection_type_is(data, { ves = 3, kt = 5 })
	local base, final, v = args_base_final_vh(data, 'a')
	return make_forms(data, {
		sg = base .. final,
		pl = base .. 'i',
	})
end

inflections['kerge'] = function (data)
	inflection_type_is(data, { ves = 3, kt = 5 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base,
		pl = mw.ustring.sub(base, 1, -2) .. 'i',
	})
end

inflections['füüsiga'] = function (data)
	inflection_type_is(data, { ves = 3, kt = 7 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_par = base .. strong .. final .. 't',
		sg_ill = base .. strong .. final .. 'h',
		pl = base .. strong .. 'i',
	})
end

inflections['kipõń'] = function (data)
	inflection_type_is(data, { ves = 4, kt = 9 })
	local base, final, v = args_base_final_vh(data, 'a')
	return make_forms(data, {
		sg = base .. final,
		sg_nom = data.lemma,
		pl = base .. 'i',
	})
end

inflections['elläi'] = inflections['kipõń']

inflections['häielm'] = function (data)
	inflection_type_is(data, { ves = 4, kt = 8 })
	local base, final, v = args_base_final_vh(data, 'a')
	return make_forms(data, {
		sg = base .. final,
		sg_nom = base,
		sg_par = base .. final .. 't',
		pl = base .. 'i',
	})
end

inflections['inemine'] = function (data)
	inflection_type_is(data, { ves = 5, kt = 16 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 's' .. v.e,
		sg_nom = base .. 'n' .. v.e,
		sg_par = base .. 'st',
		sg_ill = base .. 'st',
		pl = { base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_par = base .. 'isi',
		pl_ill = base .. 'isih',
	})
end

inflections['tialanõ'] = function (data)
	inflection_type_is(data, { ves = 5, kt = 16 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = { base .. 'ds' .. v.e, base .. 's' .. v.e },
		sg_nom = base .. 'n' .. v.e,
		sg_par = base .. 'st',
		sg_ill = base .. 'st',
		pl = { base .. 'idsi', base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'idsi', base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_par = { base .. 'idsi', base .. 'isi' },
		pl_ill = { base .. 'idsih', base .. 'isih' },
	})
end

inflections['alomanõ'] = function (data)
	inflection_type_is(data, { ves = 5, kt = 19 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 'ds' .. v.e,
		sg_nom = base .. 'n' .. v.e,
		sg_par = base .. 'st',
		sg_ill = base .. 'st',
		pl = { base .. 'idsi', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'idsi', RARE .. base .. 'st' .. v.e },
		pl_par = base .. 'idsi',
		pl_ill = base .. 'idsih',
	})
end

inflections['kuldnõ'] = function (data)
	inflection_type_is(data, { ves = 6, kt = 8 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 's' .. v.e,
		sg_nom = base .. 'n' .. v.e,
		sg_par = base .. 'st',
		pl = base .. 'si'
	})
end

inflections['alonõ'] = function (data)
	inflection_type_is(data, { ves = 7, kt = 13 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 'ds' .. v.e,
		sg_nom = base .. 'n' .. v.e,
		sg_par = base .. 'st',
		sg_ill = base .. 'ts' .. v.e .. 'h',
		pl = { base .. 'tsi', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'tsid' .. v.e, RARE .. base .. 'st' .. v.e },
		pl_par = base .. 'tsit',
	})
end

inflections['võrokõnõ'] = function (data)
	inflection_type_is(data, { ves = 8, kt = 22 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 's' .. v.e,
		sg_nom = base .. 'n' .. v.e,
		sg_par = base .. 'ist',
		sg_ill = base .. 'ist',
		pl = { base .. 'isi', RARE .. base .. 'ist' .. v.e },
		pl_gen = { base .. 'isi', RARE .. base .. 'ist' .. v.e },
		pl_par = base .. 'isi',
		pl_ill = base .. 'isih',
	})
end

inflections['ehitüs'] = function (data)
	inflection_type_is(data, { ves = 9, kt = 18 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 's' .. v.e,
		sg_nom = base .. 's',
		sg_par = base .. 'st',
		sg_ill = base .. 'st',
		pl = { base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_par = base .. 'isi',
		pl_ill = base .. 'isih',
	})
end

inflections['tervüs'] = function (data)
	inflection_type_is(data, { ves = 10, kt = 8 })
	local base, v = args_base_vh(data)
	local pl1 = base .. 'i'
	local pl2 = mw.ustring.sub(base, '[' .. vowels .. ']$', '') .. 'i'
	return make_forms(data, {
		sg = { base, base .. 's' .. v.e },
		sg_par = { base .. 't', base .. 'st' },
		sg_ill = { base .. 'h', base .. 'st' },
		pl = { pl1, pl2, base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_gen = { pl1 .. 'd' .. v.e, pl2 .. 'd' .. v.e, base .. 'isi', RARE .. base .. 'st' .. v.e },
		pl_par = { pl1 .. 'd', pl2 .. 't', base .. 'isi' },
	})
end

inflections['kotus'] = function (data)
	inflection_type_is(data, { ves = 11, kt = 15 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = { base .. 'ss', base .. 's' },
		sg_par = base .. 'st',
		sg_ill = base .. 'ss' .. v.e .. 'h',
		pl = { base .. 'ssi', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'ssid' .. v.e, RARE .. base .. 'st' .. v.e },
		pl_par = base .. 'ssit',
	})
end

inflections['repäń'] = function (data)
	inflection_type_is(data, { ves = 12, kt = 12 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 's' .. v.e,
		sg_nom = data.lemma,
		sg_par = base .. 'st',
		pl = { base .. 'si', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'sid' .. v.e, RARE .. base .. 'st' .. v.e },
		pl_par = base .. 'sit',
	})
end

inflections['hõrak'] = function (data)
	inflection_type_is(data, { ves = 13, kt = 10 })
	local base, strong, weak, v = args_base_grade_vh(data)
	return make_forms(data, {
		sg = { base .. weak .. v.a, base .. weak .. v.u },
		sg_nom = base .. strong,
		sg_par = base .. strong .. v.a .. 't',
		sg_ill = { base .. strong .. v.a, base .. strong .. v.u },
		pl = base .. strong .. 'i',
	})
end

inflections['esänd'] = function (data)
	inflection_type_is(data, { ves = 13, kt = 8 })
	local base, final, v = args_base_final_vh(data, 'a')
	return make_forms(data, {
		sg = base .. final,
		sg_nom = base,
		sg_par = base .. final .. 't',
		pl = base .. 'i',
	})
end

inflections['makõ'] = function (data)
	inflection_type_is(data, { ves = 14, kt = { 6, 9 } })
	local base, strong, weak, final, v = args_base_grade_final_vh(data)
	local gem = geminate_broad(strong, find_final_consonant(base))
	return make_forms(data, {
		sg = { base .. strong .. final, base .. weak .. final .. 'h' .. v.e },
		sg_nom = base .. strong .. final,
		sg_par = base .. strong .. v.a .. 't',
		sg_ill = { base .. gem .. final .. 'h', base .. weak .. final .. 'h' },
		pl = { base .. gem .. 'i', base .. weak .. final .. 'hi' },
	})
end

inflections['ritśkas'] = function (data)
	inflection_type_is(data, { ves = 15, kt = 14 })
	local base, v = args_base_vh(data)
	local pl = mw.ustring.sub(base, 1, -2) .. 'i'
	return make_forms(data, {
		sg = base,
		sg_nom = { base .. 't', base .. 'st' },
		pl = { pl, RARE .. base .. 'st' .. v.e },
		pl_gen = { pl .. 't', RARE .. base .. 'st' .. v.e },
		pl_par = pl .. 't',
	})
end

inflections['angõrjas'] = function (data)
	inflection_type_is(data, { ves = 15, kt = 8 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base,
		sg_nom = base .. 's',
		sg_par = base .. 't',
		pl = mw.ustring.gsub(base, '[' .. vowels .. ']$', '').. 'i'
	})
end

inflections['asõq'] = function (data)
	inflection_type_is(data, { ves = 16, kt = 25 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = { base .. 'm' .. v.e, base .. 'm' .. v.a },
		sg_nom = base .. 'q',
		sg_par = base .. 'nd',
		pl = { base .. 'mi', RARE .. base .. 'nd' .. v.e },
		pl_gen = { base .. 'mid' .. v.e, RARE .. base .. 'nd' .. v.e },
		pl_par = base .. 'mit',
	})
end

inflections['hepeḿ'] = function (data)
	inflection_type_is(data, { ves = 16, kt = 26 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	local pl = base .. gen .. 'mi'
	return make_forms(data, {
		sg = { base .. weak .. final .. 'm' .. v.e, base .. weak .. final .. 'm' .. v.a },
		sg_nom = base .. strong .. final .. 'ḿ',
		sg_par = base .. weak .. final .. 'nd',
		pl = { base .. weak .. final .. 'mi', RARE .. base .. weak .. final .. 'nd' .. v.e },
		pl_gen = { base .. weak .. final .. 'mid' .. v.e, RARE .. base .. weak .. final .. 'nd' .. v.e },
		pl_par = base .. weak .. final .. 'mit',
	})
end

inflections['eheq'] = function (data)
	inflection_type_is(data, { ves = 16, kt = 27 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	local pl = base .. gen .. 'mi'
	return make_forms(data, {
		sg = base .. gen .. 'm' .. v.e,
		sg_nom = base .. nom .. final .. 'q',
		sg_par = base .. nom .. final .. 'nd',
		sg_ill = { base .. gen .. 'm' .. v.e .. 'h', base .. gen .. 'm' .. v.a .. 'h' },
		pl = { pl, RARE .. base .. nom .. final .. 'nd' .. v.e },
		pl_gen = { pl .. 'd' .. v.e, RARE .. base .. nom .. final .. 'nd' .. v.e },
		pl_par = pl .. 't',
		pl_ill = { pl .. 'd', RARE .. base .. nom .. final .. 'nd' },
	})
end

inflections['hapu'] = function (data)
	inflection_type_is(data, { ves = 17, kt = 27 })
	local base, final, v = args_base_final_vh(data)
	return make_forms(data, {
		sg = { base .. 'n' .. v.e, base .. 'n' .. v.a },
		sg_nom = base .. final,
		sg_par = base .. final .. 'nd',
		pl = { base .. 'ni', RARE .. base .. final .. 'nd' .. v.e },
		pl_gen = { base .. 'nid' .. v.e, RARE .. base .. final .. 'nd' .. v.e },
		pl_par = base .. 'nit',
	})
end

inflections['läteq'] = function (data)
	inflection_type_is(data, { ves = 18, kt = 11 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. strong .. final,
		sg_nom = base .. weak ..  final .. 'q',
		sg_par = base .. weak ..  final .. 't',
		sg_ill = base .. strong .. final .. 'h',
		pl = { base .. strong .. 'i', RARE .. base .. weak .. final .. 't' .. v.e },
		pl_gen = { base .. strong .. 'id' .. v.e, RARE .. base .. weak .. final .. 't' .. v.e },
		pl_par = base .. strong .. 'it',
	})
end

inflections['kommõq'] = function (data)
	inflection_type_is(data, { ves = 19, kt = 11 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. strong .. final,
		sg_nom = base .. weak ..  final .. 'q',
		sg_par = base .. weak ..  final .. 't',
		sg_ill = base .. strong .. final .. 'h',
		pl = { base .. strong .. 'i', RARE .. base .. weak .. final .. 't' .. v.e },
		pl_gen = { base .. strong .. 'id' .. v.e, RARE .. base .. weak .. final .. 't' .. v.e },
		pl_par = base .. strong .. 'it',
	})
end

inflections['herneh'] = function (data)
	inflection_type_is(data, { ves = 20, kt = 14 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. strong .. final,
		sg_nom = base .. weak .. final .. 'h',
		sg_par = base .. weak .. final .. 'ht',
		sg_ill = base .. strong .. final .. 'h',
		pl = { base .. strong .. 'i', RARE .. base .. weak .. final .. 'ht' .. v.e },
		pl_gen = { base .. strong .. 'id' .. v.e, RARE .. base .. weak .. final .. 'ht' .. v.e },
		pl_par = base .. strong .. 'it',
	})
end

inflections['laiõh'] = function (data)
	inflection_type_is(data, { ves = 21, kt = 14 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. strong .. final,
		sg_nom = base .. weak .. final .. 'h',
		sg_par = base .. weak .. final .. 'ht',
		sg_ill = base .. strong .. final .. 'h',
		pl = { base .. strong .. 'i', RARE .. base .. weak .. final .. 'ht' .. v.e },
		pl_gen = { base .. strong .. 'id' .. v.e, RARE .. base .. weak .. final .. 'ht' .. v.e },
		pl_par = base .. strong .. 'it',
	})
end

inflections['saabas'] = function (data)
	inflection_type_is(data, { ves = 22, kt = 14 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. strong .. final,
		sg_nom = base .. weak .. final .. 's',
		sg_par = base .. weak .. final .. 'st',
		sg_ill = base .. strong .. final .. 'h',
		pl = { base .. strong .. 'i', RARE .. base .. weak .. final .. 'st' .. v.e },
		pl_gen = { base .. strong .. 'id' .. v.e, RARE .. base .. weak .. final .. 'st' .. v.e },
		pl_par = base .. strong .. 'it',
	})
end

inflections['hammas'] = function (data)
	inflection_type_is(data, { ves = 23, kt = 14 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. strong .. final,
		sg_nom = base .. weak .. final .. 's',
		sg_par = base .. weak .. final .. 'st',
		sg_ill = base .. strong .. final .. 'h',
		pl = { base .. strong .. 'i', RARE .. base .. weak .. final .. 'st' .. v.e },
		pl_gen = { base .. strong .. 'id' .. v.e, RARE .. base .. weak .. final .. 'st' .. v.e },
		pl_par = base .. strong .. 'it',
	})
end

inflections['tütäŕ'] = function (data)
	inflection_type_is(data, { ves = 22, kt = 28 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	local cons = find_final_liquid(data.lemma)
	return make_forms(data, {
		sg = base .. strong .. cons .. v.e,
		sg_nom = palatalize(base .. weak .. final .. cons .. "'"),
		sg_par = base .. weak .. final .. cons .. 'd',
		pl = { base .. strong .. cons .. 'i', RARE .. base .. weak .. final .. cons .. 'd' .. v.e },
		pl_gen = { base .. strong .. cons .. 'id' .. v.e, RARE .. base .. weak .. cons .. 'd' .. v.e },
		pl_par = base .. strong .. cons .. 'it',
	})
end

inflections["kannõl'"] = function (data)
	inflection_type_is(data, { ves = 23, kt = 28 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, true)
	local cons = data.args[2] or error("must specify final consonant")
	return make_forms(data, {
		sg = base .. strong .. cons .. v.e,
		sg_nom = palatalize(base .. weak .. final .. cons .. "'"),
		sg_par = base .. weak .. final .. cons .. 'd',
		pl = { base .. strong .. cons .. 'i', RARE .. base .. weak .. final .. cons .. 'd' .. v.e },
		pl_gen = { base .. strong .. cons .. 'id' .. v.e, RARE .. base .. weak .. cons .. 'd' .. v.e },
		pl_par = base .. strong .. cons .. 'it',
	})
end

inflections['tarõ'] = function (data)
	inflection_type_is(data, { ves = 24, kt = 35 })
	local base, final, v = args_base_final_vh(data, true)
	local cons = find_final_consonant(base)
	return make_forms(data, {
		sg = base .. final,
		sg_nom = base .. final,
		sg_par = base .. cons .. final,
		sg_ill = base .. rconsep .. final,
		pl = { base .. 'i', base .. cons .. 'i' },
		pl_gen = base .. cons .. 'i',
		pl_par = base .. cons .. 'i',
		pl_ill = { base .. cons .. 'i', base .. cons .. 'ih' }
	})
end

inflections['igä'] = function (data)
	inflection_type_is(data, { ves = 25, kt = 33 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	local cpar = geminate_broad(strong, find_final_consonant(base))
	local cill = geminate(cpar)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong .. final,
		sg_par = base .. cpar .. final,
		sg_ill = base .. cill .. final,
		pl = { base .. cpar .. 'i', RARE .. base .. weak .. 'i' },
		pl_gen = base .. cpar .. 'i',
		pl_par = base .. cpar .. 'i',
		pl_ill = { base .. cill .. 'i', base .. cill .. 'ih' }
	})
end

inflections['pini'] = function (data)
	inflection_type_is(data, { ves = 26, kt = 37 })
	local base, v = args_base_vh(data)
	local cons = find_final_consonant(base)
	return make_forms(data, {
		sg = base .. 'i',
		sg_nom = base .. 'i',
		sg_par = base .. cons .. 'i',
		sg_ill = base .. cons .. 'i',
		pl = { base .. cons .. v.e, base .. v.e },
		pl_gen = base .. cons .. v.e,
		pl_par = base .. cons .. v.e,
		pl_ill = { base .. cons .. v.e, base .. cons .. 'eh' }
	})
end

inflections['talo'] = function (data)
	inflection_type_is(data, { ves = 26, kt = 40 })
	local base, final, v = args_base_final_vh(data, true)
	local cons = find_final_consonant(base)
	return make_forms(data, {
		sg = base .. final,
		sg_nom = base .. final,
		sg_par = base .. cons .. final,
		sg_ill = base .. cons .. final,
		pl = { base .. v.e, base .. cons .. v.e, base .. v.a, base .. cons .. v.a },
		pl_gen = { base .. cons .. v.e, base .. cons .. v.a },
		pl_par = { base .. cons .. v.e, base .. cons .. v.a },
		pl_ill = { base .. cons .. v.e, base .. cons .. v.e .. 'h', base .. cons .. v.a, base .. cons .. v.a .. 'h' },
	})
end

inflections['häbü'] = function (data)
	inflection_type_is(data, { ves = 27, kt = 39 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	local cpar = geminate_broad(strong, find_final_consonant(base))
	local cill = geminate(cpar)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong .. final,
		sg_par = base .. cpar .. final,
		sg_ill = base .. cill .. final,
		pl = { base .. cpar .. v.e, base .. cpar .. v.a, RARE .. base .. weak .. v.e },
		pl_gen = { base .. cpar .. v.e, base .. cpar .. v.a },
		pl_par = { base .. cpar .. v.e, base .. cpar .. v.a },
		pl_ill = { base .. cill .. v.e, base .. cill .. v.e .. 'h', base .. cill .. v.a, base .. cill .. v.a .. 'h' }
	})
end

inflections['kana'] = function (data)
	inflection_type_is(data, { ves = 28, kt = 45 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	local cpar = geminate_broad(strong, find_final_consonant(base))
	local cill = geminate(cpar)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong .. final,
		sg_par = base .. cpar .. final,
		sg_ill = base .. cill .. final,
		pl = { base .. strong .. v.o, base .. cpar .. v.o },
		pl_gen = base .. cpar .. v.o,
		pl_par = base .. cpar .. v.o,
		pl_ill = { base .. cill .. v.o, base .. cill .. v.o .. 'h'}
	})
end

inflections['sõda'] = function (data)
	inflection_type_is(data, { ves = 29, kt = 45 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	local cpar = geminate_broad(strong, find_final_consonant(base))
	local cill = geminate(cpar)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong .. final,
		sg_par = base .. cpar .. final,
		sg_ill = base .. cill .. final,
		pl = { base .. cpar .. v.o, RRAE .. base .. weak .. v.o },
		pl_gen = base .. cpar .. v.o,
		pl_par = base .. cpar .. v.o,
		pl_ill = { base .. cill .. v.o, base .. cill .. v.o .. 'h'}
	})
end

inflections['hain'] = function (data)
	inflection_type_is(data, { ves = 30, kt = 46 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = base .. weak .. v.o,
		pl_gen = base .. strong .. v.o,
		pl_par = base .. strong .. v.o,
		pl_ill = { base .. strong .. v.o, base .. strong .. v.o .. 'h'}
	})
end

inflections['puhm'] = function (data)
	inflection_type_is(data, { ves = 31, kt = 38 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = base .. weak .. v.e,
		pl_gen = base .. strong .. v.e,
		pl_par = base .. strong .. v.e,
		pl_ill = { base .. strong .. v.e, base .. strong .. v.e .. 'h'}
	})
end

inflections['kuld'] = function (data)
	inflection_type_is(data, { ves = 32, kt = 38 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = base .. weak .. v.e,
		pl_gen = base .. strong .. v.e,
		pl_par = base .. strong .. v.e,
		pl_ill = { base .. strong .. v.e, base .. strong .. v.e .. 'h'}
	})
end

inflections['jalg'] = function (data)
	inflection_type_is(data, { ves = 33, kt = 46 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = base .. weak .. v.o,
		pl_gen = base .. strong .. v.o,
		pl_par = base .. strong .. v.o,
		pl_ill = { base .. strong .. v.o, base .. strong .. v.o .. 'h'}
	})
end

inflections['särǵ'] = function (data)
	inflection_type_is(data, { ves = 34, kt = 36 })
	local base, strong, weak, v = args_base_grade_vh(data)
	return make_forms(data, {
		sg = base .. weak .. v.e,
		sg_nom = palatalize(base .. strong .. "'"),
		sg_par = base .. strong .. v.e,
		sg_ill = base .. strong .. v.e,
		pl = base .. weak .. 'i',
		pl_gen = base .. strong .. 'i',
		pl_par = base .. strong .. 'i',
		pl_ill = { base .. strong .. 'i', base .. strong .. 'ih'}
	})
end

inflections['silm'] = function (data)
	inflection_type_is(data, { ves = 35, kt = 36 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, 'a')
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = base .. weak .. 'i',
		pl_gen = base .. strong .. 'i',
		pl_par = base .. strong .. 'i',
		pl_ill = { base .. strong .. 'i', base .. strong .. 'ih'}
	})
end

inflections['kand'] = function (data)
	inflection_type_is(data, { ves = 36, kt = 41 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, 'o')
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = { base .. weak .. v.e, base .. weak .. v.a },
		pl_gen = { base .. strong .. v.e, base .. strong .. v.a },
		pl_par = { base .. strong .. v.e, base .. strong .. v.a },
		pl_ill = { base .. strong .. v.e, base .. strong .. v.e .. 'h', base .. strong .. v.a }
	})
end

inflections['aig'] = function (data)
	inflection_type_is(data, { ves = 36, kt = 41 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, 'o')
	return make_forms(data, {
		sg = (weak == '' and mw.ustring.gsub(base, '[' .. vowels .. ']$', '') or base) .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = (weak == '' and mw.ustring.gsub(base, 'i$', 'e') or base) .. weak .. final,
		pl_gen = base .. strong .. v.e,
		pl_par = base .. strong .. v.e,
		pl_ill = { base .. strong .. v.e, base .. strong .. v.e .. 'h' }
	})
end

inflections['tükk'] = function (data)
	inflection_type_is(data, { ves = 37, kt = 41 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, false)
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = { base .. weak .. v.e, base .. weak .. v.a },
		pl_gen = { base .. strong .. v.e, base .. strong .. v.a },
		pl_par = { base .. strong .. v.e, base .. strong .. v.a },
		pl_ill = { base .. strong .. v.e, base .. strong .. v.e .. 'h', base .. strong .. v.a, base .. strong .. v.a .. 'h' },
	})
end

inflections["kuul'"] = function (data)
	inflection_type_is(data, { ves = 37, kt = 48 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, true)
	return make_forms(data, {
		sg = altify(base) .. weak .. final,
		sg_nom = base .. strong,
		sg_par = base .. strong .. final,
		sg_ill = base .. strong .. final,
		pl = altify(base) .. weak .. v.e,
		pl_gen = base .. strong .. v.e,
		pl_par = base .. strong .. v.e,
		pl_ill = { base .. strong .. v.e, base .. strong .. v.e .. 'h'}
	})
end

inflections['kanarik'] = function (data)
	inflection_type_is(data, { ves = 38, kt = 43 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, false)
	local gem = geminate_broad(strong, find_final_consonant(base))
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = palatalize(base .. strong .. (final == "i" and "'" or "")),
		sg_par = base .. gem .. final,
		sg_ill = base .. gem .. final,
		pl = { base .. weak .. v.e, base .. weak .. v.a },
		pl_gen = { base .. gem .. v.e, base .. gem .. v.a },
		pl_par = { base .. gem .. v.e, base .. gem .. v.a },
		pl_ill = { base .. gem .. v.e, base .. gem .. v.e .. 'h', base .. gem .. v.a, base .. gem .. v.a .. 'h' }
	})
end

inflections['telefoń'] = function (data)
	inflection_type_is(data, { ves = 38, kt = 43 })
	local base, strong, weak, final, v = args_base_grade_final_vh(data, false)
	local gem = geminate_broad(strong, find_final_consonant(base))
	return make_forms(data, {
		sg = base .. weak .. final,
		sg_nom = palatalize(base .. weak .. (final == "i" and "'" or "")),
		sg_par = base .. gem .. final,
		sg_ill = base .. gem .. final,
		pl = base .. weak .. v.e,
		pl_gen = base .. gem .. v.e,
		pl_par = base .. gem .. v.e,
		pl_ill = { base .. gem .. v.e, base .. gem .. v.e .. 'h' }
	})
end

inflections['väitś'] = function (data)
	inflection_type_is(data, { ves = 39, kt = 20 })
	local base, v = args_base_vh(data, true)
	return make_forms(data, {
		sg = base .. 'ds' .. v.e,
		sg_nom = base .. 'ts',
		sg_par = base .. 'st',
		sg_ill = base .. 'st' .. v.e,
		pl = { base .. 'dsi', base .. 'st' .. v.e },
		pl_gen = { base .. 'tsi', base .. 'st' .. v.e },
		pl_par = base .. 'tsi',
		pl_ill = base .. 'tsih'  
	})
end

inflections['kiil"'] = function (data)
	inflection_type_is(data, { ves = 40, kt = 23 })
	local base, v = args_base_vh(data)
	local cons = find_final_liquid(data.lemma)
	return make_forms(data, {
		sg = base .. v.e .. v.e .. cons .. v.e,
		sg_par = palatalize(base .. 'ii' .. cons .. "'"),
		sg_par = base .. 'ii' .. cons .. 't',
		sg_ill = base .. 'ii' .. cons .. 'd',
		pl = { base .. v.e .. v.e .. cons .. 'i', RARE .. base .. v.e .. v.e .. cons .. 't' .. v.e },
		pl_gen = { base .. 'ii' .. cons .. 'i', RARE .. base .. v.e .. v.e .. cons .. 't' .. v.e },
		pl_par = base .. 'ii' .. cons .. 'i',
		pl_ill = { base .. 'ii' .. cons .. 'i', base .. 'ii' .. cons .. 'ih' },
	})
end

inflections['hüdsi'] = function (data)
	inflection_type_is(data, { ves = 41, kt = 21 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. 'ds' .. v.e,
		sg_nom = base .. 'dsi',
		sg_par = base .. 'st',
		sg_ill = base .. 'st' .. v.e,
		pl = { base .. 'dsi', RARE .. base .. 'st' .. v.e },
		pl_gen = { base .. 'tsi', RARE .. base .. 'st' .. v.e },
		pl_par = base .. 'tsi',
		pl_ill = { base .. 'tsi', base .. 'tsih' },
	})
end

inflections['veri'] = function (data)
	inflection_type_is(data, { ves = 41, kt = 32 })
	local base, v = args_base_vh(data)
	local cons = find_final_liquid(data.lemma)
	return make_forms(data, {
		sg = base .. cons .. v.e,
		sg_nom = base .. cons .. 'i',
		sg_par = base .. cons .. 'd',
		sg_ill = base .. cons .. 'd' .. v.e,
		pl = { base .. cons .. 'i', base .. cons .. cons .. 'i' },
		pl_gen = base .. cons .. cons .. 'i',
		pl_par = base .. cons .. cons .. 'i',
		pl_ill = { base .. cons .. cons .. 'i', base .. cons .. cons .. 'ih' },
	})
end

inflections['tuli'] = function (data)
	inflection_type_is(data, { ves = 41, kt = 34 })
	local base, v = args_base_vh(data)
	local cons = find_final_liquid(data.lemma)
	return make_forms(data, {
		sg = base .. cons .. v.e,
		sg_nom = base .. cons .. 'i',
		sg_par = base .. cons .. 'd',
		sg_ill = base .. cons .. cons .. v.e,
		pl = { base .. cons .. 'i', base .. cons .. cons .. 'i' },
		pl_gen = base .. cons .. cons .. 'i',
		pl_par = base .. cons .. cons .. 'i',
		pl_ill = { base .. cons .. cons .. 'i', base .. cons .. cons .. 'ih' },
	})
end

inflections['käsi'] = function (data)
	inflection_type_is(data, { ves = 42, kt = 24 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base .. v.e,
		sg_nom = base .. 'si',
		sg_par = base .. 'tt',
		sg_ill = base .. 'tt' .. v.e,
		pl = { base .. 'si', base .. 'ssi', RARE .. base .. 't' .. v.e },
		pl_gen = { base .. 'ssi', RARE .. base .. 't' .. v.e },
		pl_par = base .. 'ssi',
		pl_ill = { base .. 'ssi', base .. 'ssih' },
	})
end

inflections['asi'] = function (data)
	inflection_type_is(data, { ves = 43, kt = 47 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = palatalize(base .. "'"),
		sg_nom = base .. 'i',
		sg_par = base .. 'j' .. v.a,
		sg_ill = base .. 'j' .. v.a,
		pl = palatalize(base .. "'") .. 'o',
		pl_gen = base .. 'j' .. v.o,
		pl_par = base .. 'j' .. v.o,
		pl_ill = { base .. 'j' .. v.o, base .. 'j' .. v.o .. 'h' },
	})
end

inflections['vari'] = function (data)
	inflection_type_is(data, { ves = 44, kt = 42 })
	local base, final, v = args_base_final_vh(data, false)
	return make_forms(data, {
		sg = palatalize(base .. "'") .. final,
		sg_nom = base .. 'i',
		sg_par = base .. 'j' .. final,
		sg_ill = base .. 'j' .. final,
		pl = { palatalize(base .. "'") .. v.e, RARE .. palatalize(base .. "'") .. v.a },
		pl_gen = { base .. 'j' .. v.e, RARE .. base .. 'j' .. v.a },
		pl_par = { base .. 'j' .. v.e, RARE .. base .. 'j' .. v.a },
		pl_ill = { base .. 'j' .. v.e, base .. 'j' .. v.e .. 'h', RARE .. base .. 'j' .. v.a, RARE .. base .. 'j' .. v.a .. 'h' },
	})
end

inflections['nagõl'] = function (data)
	inflection_type_is(data, { ves = 45, kt = 46 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, 'a')
	local cons = find_final_liquid(data.lemma)
	return make_forms(data, {
		sg = base .. weak .. cons .. final,
		sg_nom = { base .. weak .. v.e .. cons, base .. strong .. cons },
		sg_par = base .. strong .. cons .. final,
		sg_ill = base .. strong .. cons .. final,
		pl = base .. weak .. cons .. v.o,
		pl_gen = base .. strong .. cons .. v.o,
		pl_par = base .. strong .. cons .. v.o,
		pl_ill = { base .. strong .. cons .. v.o, base .. strong .. cons .. v.o .. 'h' },
	})
end

inflections['kogõr'] = function (data)
	inflection_type_is(data, { ves = 46, kt = 36 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, 'e')
	local cons = find_final_liquid(data.lemma)
	return make_forms(data, {
		sg = base .. weak .. cons .. final,
		sg_nom = { base .. weak .. v.e .. cons, base .. strong .. cons },
		sg_par = base .. strong .. cons .. final,
		sg_ill = base .. strong .. cons .. final,
		pl = base .. weak .. cons .. 'i',
		pl_gen = base .. strong .. cons .. 'i',
		pl_par = base .. strong .. cons .. 'i',
		pl_ill = { base .. strong .. cons .. 'i', base .. strong .. cons .. 'ih' },
	})
end

inflections['kubõl'] = function (data)
	inflection_type_is(data, { ves = 47, kt = 38 })
	local base, weak, strong, final, v = args_base_grade_final_vh(data, 'a')
	local cons = find_final_liquid(data.lemma)
	return make_forms(data, {
		sg = base .. weak .. cons .. final,
		sg_nom = { base .. weak .. v.e .. cons, base .. strong .. cons },
		sg_par = base .. strong .. cons .. final,
		sg_ill = base .. strong .. cons .. final,
		pl = base .. weak .. cons .. v.e,
		pl_gen = base .. strong .. cons .. v.e,
		pl_par = base .. strong .. cons .. v.e,
		pl_ill = { base .. strong .. cons .. v.e, base .. strong .. cons .. v.e .. 'h' },
	})
end

inflections['kask'] = function (data)
	inflection_type_is(data, { ves = 48, kt = 8 })
	local base, final, v = args_base_final_vh(data, 'a')
	return make_forms(data, {
		sg = base .. final,
		sg_nom = base,
		sg_par = base .. final .. 't',
		pl = base .. 'i',
	})
end

inflections["täüś"] = function (data)
	inflection_type_is(data, { ves = 49, kt = 20 })
	local base, v = args_base_vh(data, true)
	return make_forms(data, {
		sg = base .. 'vv' .. v.e,
		sg_nom = base .. v.u .. 'ś',
		sg_par = base .. v.u .. 't',
		sg_ill = base .. v.u .. 'd',
		pl = { base .. 'vvi', RARE .. base .. v.u .. 't' .. v.e },
		pl_gen = { base .. v.u .. 'si', RARE .. base .. v.u .. 't' .. v.e },
		pl_par = base .. v.u .. 'si',
		pl_ill = { base .. v.u .. 'si', base .. v.u .. 'sih' }
	})
end

inflections['kuu'] = function (data)
	inflection_type_is(data, { ves = 50, kt = 29 })
	local base, v = args_base_vh(data)
	local pl = mw.ustring.gsub(base, '[' .. vowels .. ']$', '') .. 'i'
	return make_forms(data, {
		sg = base,
		sg_ill = { base .. 'h', base .. 'ht' },
		pl = { pl, pl .. v.e },
		pl_gen = pl .. v.e,
		pl_par = pl .. 'd',
		pl_ill = { pl .. 'h', pl .. 'ht' },
	})
end

inflections['üü'] = function (data)
	inflection_type_is(data, { ves = 51, kt = 29 })
	local base, v = args_base_vh(data)
	local pl = mw.ustring.gsub(altify(base), '[' .. vowels .. ']$', '') .. 'i'
	return make_forms(data, {
		sg = base,
		sg_ill = { base .. 'h', base .. 'ht' },
		pl = { pl, pl .. v.e },
		pl_gen = pl .. v.e,
		pl_par = pl .. 'd',
		pl_ill = { pl .. 'h', pl .. 'ht' },
	})
end

inflections['tüü'] = function (data)
	inflection_type_is(data, { ves = 52, kt = 30 })
	local base, final, v = args_base_final_vh(data, true)
	local pl = mw.ustring.gsub(altify(base), '[' .. vowels .. ']$', '') .. 'i'
	return make_forms(data, {
		sg = base,
		sg_ill = { base .. 'h' .. final, mw.ustring.sub(base, 1, -2) .. 'h' .. final .. 'q'},
		pl = { pl, pl .. v.e },
		pl_gen = pl .. v.e,
		pl_par = pl .. 'd',
		pl_ill = { pl .. 'h', pl .. 'ht' },
	})
end

inflections['täi'] = function (data)
	inflection_type_is(data, { ves = 50, kt = 29 })
	local base, v = args_base_vh(data)
	return make_forms(data, {
		sg = base,
		sg_ill = { base .. 'h', base .. 'ht' },
		pl = { mw.ustring.sub(pl, 1, -2) .. v.e, pl .. v.e },
		pl_gen = { pl .. v.e, pl .. 'd' .. v.e },
		pl_par = { pl .. v.e, pl .. 'sit' },
		pl_ill = { pl .. 'h', pl .. 'ht' },
	})
end


------------------------
-- TEMPLATE INTERFACE --
------------------------



local infl_table = [=[<div class="inflection-table vsSwitcher NavFrame" data-toggle-category="declension" style="width: 40%">
<div class="NavHead" style="background:rgb(80%,80%,100%);">Standard Võro inflection of {{{lemma}}}{{{info}}}</div>
<div class="NavContent">
{| class="inflection-table" style="width:100%; border:solid 1px rgb(80%,80%,100%); text-align:left;" cellspacing="1" cellpadding="2"
|- style="background:rgb(80%,80%,100%);vertical-align:top;"
! style="width:30%;" |
! style="width:35%;" | singular
! style="width:35%;" | plural
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | nominative
| {{{nom_sg}}}
| {{{nom_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | accusative
| {{{gen_sg}}}
| {{{nom_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | genitive
| {{{gen_sg}}}
| {{{gen_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | partitive
| {{{par_sg}}}
| {{{par_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | illative
| {{{ill_sg}}}
| {{{ill_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | inessive
| {{{ine_sg}}}
| {{{ine_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | elative
| {{{ela_sg}}}
| {{{ela_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | allative
| {{{all_sg}}}
| {{{all_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | adessive
| {{{ade_sg}}}
| {{{ade_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | ablative
| {{{abl_sg}}}
| {{{abl_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | translative
| {{{tra_sg}}}
| {{{tra_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | terminative
| {{{ter_sg}}}
| {{{ter_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | abessive
| {{{abe_sg}}}
| {{{abe_pl}}}
|- style="background:rgb(95%,95%,100%);vertical-align:top;"
! style="background:rgb(80%,80%,100%);" | comitative
| {{{com_sg}}}
| {{{com_pl}}}
|}
</div>
</div>]=]

local function make_table(data)
	local function repl(form)
		if form == 'lemma' then
			return "'''" .. data.lemma .. "'''"
		elseif form == 'info' then
			if data.irregular then
				return ' (<span style="font-size:90%">irregular</span>)'
			elseif not data.info then
				return ''
			else
				return ' (<span style="font-size:90%">' .. data.info .. '</span>)'
			end
		else
			local value = data.forms[form]
			if not value then
				return '&mdash;'
			elseif type(value) == 'table' then
				local result = {}
				local rare = {}
				for _, f in ipairs(value) do
					if mw.ustring.find(f, RARE) then
						table.insert(rare, (mw.ustring.gsub(f, RARE, "")))
					else
						table.insert(result, link(f))
					end
				end
				for _, f in ipairs(rare) do
					table.insert(result, "(" .. link(f) .. ")" .. '<abbr title="rare">*</abbr>')
				end
				return table.concat(result, '<br>')
			else
				return link(value)
			end
		end
	end

	return mw.ustring.gsub(infl_table, '{{{([a-z0-9_:]+)}}}', repl)
end

function export.show(frame)
	local infl_type = frame.args[1] or error('inflection class not specified')
	local infl = inflections[infl_type] or error('unsupported inflection type ' .. infl_type)
	local args = frame:getParent().args
	local title = args['title'] or mw.title.getCurrentTitle().text
	local categories = {}

	local data = {forms = {}, title = title, lemma = title, categories = {}, class = infl_type, args = args}
	local word_prefix = prefix or ''

	if args['n'] then
		if args['n'] == 's' or args['n'] == 'sg' then
			data.number = 'sg'
			table.insert(data.categories, lang:getCanonicalName() .. ' singularia tantum')
		elseif args['n'] == 'p' or args['n'] == 'pl' then
			data.number = 'pl'
			table.insert(data.categories, lang:getCanonicalName() .. ' pluralia tantum')
		end
	end

	data.forms = infl(data)

	if mw.title.getCurrentTitle().namespace == 0 then
		table.insert(categories, lang:getCanonicalName() .. ' ' .. infl_type .. '-type nominals')
	end

	return make_table(data) .. require('Module:utilities').format_categories(data.categories, lang)
end

return export