Module:ro-verb

From Wiktionary, the free dictionary
Jump to navigation Jump to search

This module needs documentation.
Please document this module by describing its purpose and usage on the documentation page.

local dbg = false

local export = {}
local data = {}
data.forms = {}
		
data.pronouns = {
	["Latn"] = {
		["1"] = {
			["s"] = "eu",
			["p"] = "noi",
		},
		["2"] = {
			["s"] = "tu",
			["p"] = "voi",
		},
		["3"] = {
			["s"] = "el/ea",
			["p"] = "ei/ele",
		},
	},

	["Cyrl"] = {
		["1"] = {
			["s"] = "еу",
			["p"] = "ной",
		},
		["2"] = {
			["s"] = "ту",
			["p"] = "вой",
		},
		["3"] = {
			["s"] = "ел/я",
			["p"] = "ей/еле",
		},
	},
}

local form_names = {
	"inf"         ,
	"ger"         ,
	"pp"          ,
	
	"indc_pres_1s",
	"indc_pres_2s",
	"indc_pres_3s",
	"indc_pres_1p",
	"indc_pres_2p",
	"indc_pres_3p",
	
	"indc_impf_1s",
	"indc_impf_2s",
	"indc_impf_3s",
	"indc_impf_1p",
	"indc_impf_2p",
	"indc_impf_3p",
	
	"indc_perf_1s",
	"indc_perf_2s",
	"indc_perf_3s",
	"indc_perf_1p",
	"indc_perf_2p",
	"indc_perf_3p",
	
	"indc_plup_1s",
	"indc_plup_2s",
	"indc_plup_3s",
	"indc_plup_1p",
	"indc_plup_2p",
	"indc_plup_3p",
	
	"subj_pres_1s",
	"subj_pres_2s",
	"subj_pres_3s",
	"subj_pres_1p",
	"subj_pres_2p",
	"subj_pres_3p",
	
	"impr_aff_2s" ,
	"impr_aff_2p" ,
	"impr_neg_2s" ,
	"impr_neg_2p" ,
}

local consonants = {
	["i_"] = {
		{"[sș][ct]$", "șt"},
		{"^d$", "z"},
		{"^t$", "ț"},
		{"([^șj])d$", "%1z"},
		{"([^șj])t$", "%1ț"},
		{"s$", "ș"},
		{"x$", "cș"},
	},
	
	["i"] = {
		{"[sș]c$", "șt"},
		{"x$", "cș"},
	},

	["e"] = {
		{"[sș]c$", "șt"},
	},
}

local consonants_23 = {
	["i_"] = {
		{"^n$", ""},
	},
	
	["u"] = {
		{"^d$", "z"},
	},

	["â"] = {
		{"d$", "z"},
		-- {"t$", "ț"}, -- inconsistent
	}
}

-- stressed stems for null, ă, e and i endings
-- the given stems should not include the unstressed stem (unless it happens to
-- coincide with one of the other forms)
local vow_changes = {
	-- sort order: aeiouâîă
	
	["a-e"] = {	-- zbiera/așeza, a variant of e-ea below
		["-"] = "e",
		["ă"] = "a",
		["e"] = "e",
		["i"] = "e",
	},

	["a-e-ă"] = {	-- spăla
		["-"] = "ă",
		["ă"] = "a",
		["e"] = "e",
		["i"] = "e",
	},

	["a-ă"] = {	-- arăta
		["-"] = "ă",
		["ă"] = "a",
		["e"] = "a",
		["i"] = "ă",
	},

	["e-ea"] = {	-- încerca
		["-"] = "e",
		["ă"] = "ea",
		["e"] = "e",
		["i"] = "e",
	},

	["e-ea-2"] = {	-- lepăda
		["-"] = {"e", "ea"},
		["ă"] = "ea",
		["e"] = "e",
		["i"] = "e",
	},

	["e-ă"] = {		-- supăra
		["-"] = "ă",
		["ă"] = "ă",
		["e"] = "e",
		["i"] = "e",
	},

	["i-â"] = {		-- vinde (might be the only one)
		["-"] = "â",
		["ă"] = "â",
		["e"] = "i",
		["i"] = "i",
	},

	["o-oa"] = {	-- toca
		["-"] = "o",
		["ă"] = "oa",
		["e"] = "oa",
		["i"] = "o",
	},
}

-- format: conj = {lemma, stems, stem}
local template_defaults = {
	["a"] = {"aduna"},
	["a-ez"] = {"lucra"},
	["i"] = {"dormi", "dorm/doarm"},
	["i-esc"] = {"munci"},
	["î"] = {"coborî", "cobor/coboar"},
	["î-ăsc"] = {"hotărî"},
	["e-s"] = {"ajunge"},
	["e-t"] = {"sparge", "sparg", "spărg"},
	["e-pt"] = {"rupe"},
	["e-ut"] = {"trece", "trec/treac"},
	["ea-ut"] = {"cădea", "cad"},
}

local m_links = require("Module:links")
local lang = require("Module:languages").getByCode("ro")

local PAGENAME = mw.title.getCurrentTitle().text

local vowels = "aeiouăâî"

local function split(word)
	local stem, vow, cons
	
	if mw.ustring.match(word, "[" .. vowels .. "][iu]$") then
		stem, vow, cons = mw.ustring.match(word, "^(.-)([" .. vowels .. "]-)([iu])$")
	else
		stem, vow, cons = mw.ustring.match(word, "^(.-)([" .. vowels .. "]-)([^" .. vowels .. "]-)$")
	end
	
	return stem, vow, cons
end

local function split_vow(vow)
	local pre, post = "", ""
	
	if mw.ustring.len(vow) > 1 then
		pre, vow, post = mw.ustring.match(vow, "^([iu]?)(.-)([iu]?)$")
	end
	
	return pre, vow, post
end

-- todo: somehow account for hiatus (deochea)
local function get_vow_changes(words, result)
	local all_dupes = true
	
	for _, val in ipairs(words) do
		if val ~= words[1] then
			all_dupes = false
			break
		end
	end
	
	if all_dupes then
		table.insert(result, words[1])
		
		return
	else
		local split_words = {}
		
		for _, val in ipairs(words) do
			if val == "" then
				error("Cannot match stems, should only have different vowels")
			end
			
			local stem, pre, vow, post, cons
			local res = {}
			
			stem, vow, cons = split(val)
			pre, vow, post = split_vow(vow)
			
			table.insert(res, stem)
			table.insert(res, pre)
			table.insert(res, vow)
			table.insert(res, post)
			table.insert(res, cons)
			
			table.insert(split_words, res)
		end
		
		local vowel_appearances, found_vowels = {}, {}
		
		for i, val in ipairs(split_words) do
			-- compare pre-vowel, post-vowel, cons
			if val[5] ~= split_words[1][5] then
				error("Stems differ in something other than main vowels: " 
					.. words[1] .. ", " .. words[i] .. ", "
					.. (val[5] or "fjdfl") .. ", " .. (split_words[1][5] or " fda"))
			end
			
			if val[4] ~= split_words[1][4] then
				error("Stems differ in something other than main vowels: " 
					.. words[1] .. ", " .. words[i] .. ", "
					.. val[4] .. ", " .. split_words[1][4])
			end
			
			if val[2] ~= split_words[1][2] then
				error("Stems differ in something other than main vowels: " 
					.. words[1] .. ", " .. words[i] .. ", "
					.. val[2] .. ", " .. split_words[1][2])
			end
			
			-- add the vowel
			vowel_appearances[val[3]] = true
		end
		
		for vow, _ in pairs(vowel_appearances) do
			table.insert(found_vowels, vow)
		end
		
		table.sort(found_vowels)
		
		-- replace words with stems
		for key, _ in ipairs(words) do
			words[key] = split_words[key][1]
		end
		
		get_vow_changes(words, result)
		
		-- join pre-vowel to last consonant
		result[#result] = result[#result] .. split_words[1][2]
		
		-- add all the vowel variations
		table.insert(result, table.concat(found_vowels, "-"))
		
		-- add post-vowel + last cons
		table.insert(result, split_words[1][4] .. split_words[1][5])
		
		return
	end
end

local get_stem_a = function()
	local stem
	
	if mw.ustring.match(data.lemma, "[cg]hea$") then
		stem = mw.ustring.match(data.lemma, "^(.*)ea$")
	else
		stem = mw.ustring.match(data.lemma, "^(.*)a$")
	end
	
	return stem
	or error("The given conjugation type does not match the infinitive ending")
end

local get_stem_e = function()
	return mw.ustring.match(data.lemma, "^(.*)e$")
	or error("The given conjugation type does not match the infinitive ending")
end

local get_stem_ea = function()
	return mw.ustring.match(data.lemma, "^(.*)ea$")
	or error("The given conjugation type does not match the infinitive ending")
end

local get_stem_i = function()
	return mw.ustring.match(data.lemma, "^(.*[" .. vowels .. "]i)$")
	or mw.ustring.match(data.lemma, "^(.*)i$")
	or error("The given conjugation type does not match the infinitive ending")
end

local get_stem_ih = function()
	return mw.ustring.match(data.lemma, "^(.*)î$")
	or error("The given conjugation type does not match the infinitive ending")
end

-- todo: don't do this
local get_inf_stem = function()
	if mw.ustring.find(data.type, "^a") then
		return get_stem_a()
	elseif mw.ustring.find(data.type, "^i") then
		return get_stem_i()
	elseif mw.ustring.find(data.type, "^î") then
		return get_stem_ih()
	elseif mw.ustring.find(data.type, "^ea") then
		return get_stem_ea()
	elseif mw.ustring.find(data.type, "^e") then
		return get_stem_e()
	end
end

-- given a comma-separated list of slash-separated lists of stems
-- get a list of stems for each ending
local function get_stems(stems)
	local stem_types = {"-", "ă", "e", "i"}
	
	local res = {}
	
	for _, stype in ipairs(stem_types) do
		res[stype] = {}
	end
	
	if not stems then
		local stem = get_inf_stem()
		
		for _, val in ipairs(stem_types) do
			res[val] = stem
		end
	else
		local stem_lists = mw.text.split(stems, " *, *")
		
		for _, stem_set in ipairs(stem_lists) do
			-- make a new resi table to hold all the stems
			local resi = {}
			local stems2, stem_parts = mw.text.split(stem_set, " */ *"), {}
			
			get_vow_changes(stems2, stem_parts)
			
			for _, stype in ipairs(stem_types) do
				resi[stype] = {""}
				
				for i = 1, #stem_parts, 2 do
					for j, _ in ipairs(resi[stype]) do
	                    resi[stype][j] = resi[stype][j] .. stem_parts[i]
	                end
	                
	                -- which syllable this is, counting from the end
	                local syln = (#stem_parts - i) / 2
					
					if stem_parts[i + 1] then
						local vc = vow_changes[stem_parts[i + 1] .. "-" .. syln] 
	                    or vow_changes[stem_parts[i + 1]]
	                    
						if not vc then
	                    -- no vowel alternation found for these vowels
	                    
							if not mw.ustring.find(stem_parts[i + 1], "\-") then
							-- there's only one vowel, so use it
							
								for k, stem in ipairs(resi[stype]) do
									resi[stype][k] = stem .. stem_parts[i + 1]
								end
							else
							-- multiple vowels not matching a known vowel alternation
								
								error(stem_parts[i + 1] ..
								" is not a valid vowel change")
		                    end
						elseif type(vc[stype]) == "string" then
						-- only one vowel can be used with that ending
						
							for k, stem in ipairs(resi[stype]) do
								resi[stype][k] = stem .. vc[stype]
							end
						elseif type(vc[stype]) == "table" then
						-- multiple vowels for that ending, so make a copy
						-- of the partial stem for each one
							
							local copy = resi[stype]
							resi[stype] = {}
							
							for _, vow in ipairs(vc[stype]) do
								for _, stem in ipairs(copy) do
									table.insert(resi[stype], stem .. vow)
								end
							end
						end
					end
				end
			end
			
			-- add only the stems that are not already in res
			for _, stype in ipairs(stem_types) do
				for _, stemi in ipairs(resi[stype]) do
					local is_new = true
					
					for _, stem in ipairs(res[stype]) do
						if stem == stemi then
							is_new = false
							
							break
						end
					end
					
					if is_new then
						table.insert(res[stype], stemi)
					end
				end
			end
		end
	end
	
	return res
end

local function find_cons(cons, mode, conj_23, vow)
	local n
	
	-- ugly hack
	if conj_23 and mode == "â" and cons == "t" 
	and mw.ustring.find(vow, "[eio]$") then
		cons = "ț"
		
		return cons
	end
	
	if conj_23 and consonants_23[mode] then
		for _, p in ipairs(consonants_23[mode]) do
			cons, n = mw.ustring.gsub(cons, p[1], p[2], 1)
			
			if n >= 1 then
				return cons
			end
		end
	end
	
	if consonants[mode] then
		for _, p in pairs(consonants[mode]) do
			cons, n = mw.ustring.gsub(cons, p[1], p[2], 1)
			
			if n >= 1 then
				return cons
			end
		end
	end

	return cons
end

local tsub = function(t, i, j)
	local res = mw.clone(t)
	
	for k, form in ipairs(res) do
		res[k] = mw.ustring.sub(form, i, j)
	end
	
	return res
end

-- compare two arrays, ignoring order
-- might not work if there are duplicates
local tequals = function(t1, t2)
	if #t1 ~= #t2 then
		return false
	else
		local a = {}
		
		for _, val in ipairs(t1) do
			a[val] = true
		end
		
		for _, val in ipairs(t2) do
			if not a[val] then
				return false
			end
		end
		
		return true
	end
end

-- common for both functions below
local join_ending_common = function(stem, ending)
	ending = ending or ""
	local res = {}
	
	if type(stem) == "string" then
		stem = {stem}
	end
	
	for _, s in ipairs(stem) do
		if ending == "" then
			if mw.ustring.match(s, "[cg]h$") or mw.ustring.match(s, "[^" .. vowels .. "]i$") then
				table.insert(res, s .. "i")
			elseif mw.ustring.match(s, "[^" .. vowels .. "][lr]$") then
				table.insert(res, s .. "u")
			end
		elseif mw.ustring.match(s, "[cg]h$") then
			if mw.ustring.match(ending, "^a") then
				table.insert(res, s .. "e" .. ending)
			elseif mw.ustring.match(ending, "^ă") then
				table.insert(res, s .. mw.ustring.gsub(ending, "^ă", "e"))
			elseif mw.ustring.match(ending, "^[âî]") then
				table.insert(res, s .. mw.ustring.gsub(ending, "^[âî]", "i"))
			end
		elseif mw.ustring.match(s, "i$") then
			if mw.ustring.match(ending, "^ă") then
				table.insert(res, s .. mw.ustring.gsub(ending, "^ă", "e"))
			elseif mw.ustring.match(ending, "^ea") then
				table.insert(res, s .. mw.ustring.gsub(ending, "^e", ""))
			elseif mw.ustring.match(ending, "^[âi]") then
				if mw.ustring.match(s, "[" .. vowels .. "]i$") then
					table.insert(res, s .. mw.ustring.gsub(ending, "^[âi]", ""))
				else
					table.insert(res, s .. mw.ustring.gsub(ending, "^[âi]", "i"))
				end
			end
		end
	end
	
	return res
end

-- no consonant change
local join_ending_2 = function(stem, ending)
	ending = ending or ""
	local res = join_ending_common(stem, ending)
	
	if #res == 0 then
		if type(stem) == "string" then
			stem = {stem}
		end
		
		for _, s in ipairs(stem) do
			if mw.ustring.match(ending, "^[ei]") and mw.ustring.match(s, "[cg]$") then
				table.insert(res, s .. "h" .. ending)
			else
				table.insert(res, s .. ending)
			end
		end
	end
	
	for i, form in ipairs(res) do
		res[i] = mw.ustring.match(form, "^(.-)_?$")
	end
	
	return res
end

-- consonant change
local join_ending = function(stem, ending, conj_23)
	ending = ending or ""
	local res = join_ending_common(stem, ending)
	
	if #res == 0 then
		if type(stem) == "string" then
			stem = {stem}
		end
		
		for _, s in ipairs(stem) do
			if mw.ustring.match(ending, "^[ei]") or 
			(conj_23 and mw.ustring.match(ending, "^[uâ]")) then
				local st, vow, cons = split(s)
				local ending_vow = ending == "i_" and "i_" or mw.ustring.sub(ending, 1, 1)
				
				cons = find_cons(cons, ending_vow, conj_23, vow)
				
				table.insert(res, st .. vow .. cons .. ending)
			else
				table.insert(res, s .. ending)
			end
		end
	end
	
	for i, form in ipairs(res) do
		res[i] = mw.ustring.match(form, "^(.-)_?$")
	end
	
	return res
end

local add_form = function(t, name, new_form)
	if not t[name] then
		t[name] = new_form
	end
end

local add_repeated_forms_new = function(t)
	add_form(t, "inf", {data.lemma})
	
	add_form(t, "indc_impf_1s", join_ending(t.impf_stem, "am"))
	add_form(t, "indc_impf_2s", join_ending(t.impf_stem, "ai"))
	add_form(t, "indc_impf_3s", join_ending(t.impf_stem, "a"))
	add_form(t, "indc_impf_1p", join_ending(t.impf_stem, "am"))
	add_form(t, "indc_impf_2p", join_ending(t.impf_stem, "ați"))
	add_form(t, "indc_impf_3p", join_ending(t.impf_stem, "au"))
	
	add_form(t, "indc_plup_1s", join_ending(t.plup_stem, "sem"))
	add_form(t, "indc_plup_2s", join_ending(t.plup_stem, "seși"))
	add_form(t, "indc_plup_3s", join_ending(t.plup_stem, "se"))
	add_form(t, "indc_plup_1p", join_ending(t.plup_stem, "serăm"))
	add_form(t, "indc_plup_2p", join_ending(t.plup_stem, "serăți"))
	add_form(t, "indc_plup_3p", join_ending(t.plup_stem, "seră"))
	
	add_form(t, "subj_pres_1s", mw.clone(t.indc_pres_1s))
	add_form(t, "subj_pres_2s", mw.clone(t.indc_pres_2s))
	add_form(t, "subj_pres_1p", mw.clone(t.indc_pres_1p))
	add_form(t, "subj_pres_2p", mw.clone(t.indc_pres_2p))
	
	add_form(t, "subj_pres_3p", mw.clone(t.subj_pres_3s))
	
	add_form(t, "impr_aff_2p", mw.clone(t.indc_pres_2p))
	add_form(t, "impr_neg_2s", mw.clone(t.inf))
	add_form(t, "impr_neg_2p", mw.clone(t.indc_pres_2p))
end

local conjugations_new = {}

conjugations_new["a"] = function(t, stem, stems, ez)
	data.conj = 1
	
	stem = stem or get_stem_a() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before ă ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before i ending
	
	add_form(t, "ger", join_ending(stem, "ând"))
	add_form(t, "pp", join_ending(stem, "at"))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_"))
	add_form(t, "indc_pres_3s", join_ending(stem_ah, "ă"))
	add_form(t, "indc_pres_1p", join_ending(stem, "ăm"))
	add_form(t, "indc_pres_2p", join_ending(stem, "ați"))
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_3s))
	
	t.impf_stem = stem
	
	add_form(t, "indc_perf_1s", join_ending(stem, "ai"))
	add_form(t, "indc_perf_2s", join_ending(stem, "ași"))
	add_form(t, "indc_perf_3s", join_ending(stem, "ă"))
	add_form(t, "indc_perf_1p", join_ending(stem, "arăm"))
	add_form(t, "indc_perf_2p", join_ending(stem, "arăți"))
	add_form(t, "indc_perf_3p", join_ending(stem, "ară"))
	
	t.plup_stem = join_ending(stem, "a")
	
	add_form(t, "subj_pres_3s", join_ending(stem_e, "e"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

conjugations_new["a-ez"] = function(t, stem)
	stem = stem or get_stem_a()
	local stem_ez = join_ending_2(stem, "ez")
	local stem_eaz = join_ending_2(stem, "eaz")
	
	conjugations_new["a"](t, stem, {["-"] = stem_ez,
								 ["ă"] = stem_eaz,
								 ["e"] = stem_ez,
								 ["i"] = stem_ez}, true)
end

conjugations_new["i"] = function(t, stem, stems, esc)
	data.conj = 4
	
	stem = stem or get_stem_i() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before ă ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before i ending
	
	add_form(t, "ger", join_ending(stem, "ind"))
	add_form(t, "pp", join_ending(stem, "it"))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_"))
	add_form(t, "indc_pres_3s", join_ending(stem_e, "e"))
	add_form(t, "indc_pres_1p", join_ending(stem, "im"))
	add_form(t, "indc_pres_2p", join_ending(stem, "iți"))
	-- todo: this is probably based on stress
	add_form(t, "indc_pres_3p", mw.clone(mw.ustring.match(stem_[1], "[" .. vowels .. "]i$"))
							  and t.indc_pres_3s or t.indc_pres_1s)
	
	t.impf_stem = tsub(join_ending(stem, "ea"), 1, -2)
	
	add_form(t, "indc_perf_1s", join_ending(stem, "ii"))
	add_form(t, "indc_perf_2s", join_ending(stem, "iși"))
	add_form(t, "indc_perf_3s", join_ending(stem, "i"))
	add_form(t, "indc_perf_1p", join_ending(stem, "irăm"))
	add_form(t, "indc_perf_2p", join_ending(stem, "irăți"))
	add_form(t, "indc_perf_3p", join_ending(stem, "iră"))
	
	t.plup_stem = join_ending(stem, "i")
	
	add_form(t, "subj_pres_3s", join_ending(stem_ah, "ă"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

conjugations_new["i-esc"] = function(t, stem)
	stem = stem or get_stem_i()
	local stem_esc = join_ending(stem, "esc")
	local stem_easc = join_ending(stem, "easc")
	
	conjugations_new["i"](t, stem, {["-"] = stem_esc,
								 ["ă"] = stem_easc,
								 ["e"] = stem_esc,
								 ["i"] = stem_esc}, true)
end

conjugations_new["î"] = function(t, stem, stems)
	data.conj = 4
	
	stem = stem or get_stem_ih() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before ă ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before i ending
	
	add_form(t, "ger", join_ending(stem, "ând"))
	add_form(t, "pp", join_ending(stem, "ât"))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_"))
	add_form(t, "indc_pres_3s", join_ending(stem_ah, "ă"))
	add_form(t, "indc_pres_1p", join_ending(stem, "âm"))
	add_form(t, "indc_pres_2p", join_ending(stem, "âți"))
	-- todo: change this
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_3s))
	
	t.impf_stem = stem
	
	add_form(t, "indc_perf_1s", join_ending(stem, "âi"))
	add_form(t, "indc_perf_2s", join_ending(stem, "âși"))
	add_form(t, "indc_perf_3s", join_ending(stem, "î"))
	add_form(t, "indc_perf_1p", join_ending(stem, "ârăm"))
	add_form(t, "indc_perf_2p", join_ending(stem, "ârăți"))
	add_form(t, "indc_perf_3p", join_ending(stem, "âră"))
	
	t.plup_stem = join_ending(stem, "â")
	
	add_form(t, "subj_pres_3s", join_ending(stem_e, "e"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

conjugations_new["î-ăsc"] = function(t, stem)
	data.conj = 4
	
	stem = stem or get_stem_ih()
	stem_ = join_ending(stem, "ăsc") -- stressed stem before zero ending
	stem_ah = join_ending(stem, "asc") -- stressed stem before ă ending
	stem_e = stem_ -- stressed stem before e ending
	stem_i = stem_ -- stressed stem before i ending
	
	add_form(t, "ger", join_ending(stem, "ând"))
	add_form(t, "pp", join_ending(stem, "ât"))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_"))
	add_form(t, "indc_pres_3s", join_ending(stem_e, "e"))
	add_form(t, "indc_pres_1p", join_ending(stem, "âm"))
	add_form(t, "indc_pres_2p", join_ending(stem, "âți"))
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_1s))
	
	t.impf_stem = stem
	
	add_form(t, "indc_perf_1s", join_ending(stem, "âi"))
	add_form(t, "indc_perf_2s", join_ending(stem, "âși"))
	add_form(t, "indc_perf_3s", join_ending(stem, "î"))
	add_form(t, "indc_perf_1p", join_ending(stem, "ârăm"))
	add_form(t, "indc_perf_2p", join_ending(stem, "ârăți"))
	add_form(t, "indc_perf_3p", join_ending(stem, "âră"))
	
	t.plup_stem = join_ending(stem, "â")
	
	add_form(t, "subj_pres_3s", join_ending(stem_ah, "ă"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

conjugations_new["e-s"] = function(t, stem, stems)
	data.conj = 3
	
	stem = stem or get_stem_e() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before i ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before ă ending
	
	local pp_stem = tsub(stem, 1, -2)
	local pp_stem_ = tsub(stem_, 1, -2)
	local pp_stem_e = tsub(stem_e, 1, -2)
	
	add_form(t, "ger", join_ending(stem, "ând", true))
	add_form(t, "pp", join_ending(pp_stem_, "s"))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_", true))
	add_form(t, "indc_pres_3s", join_ending(stem_e, "e"))
	add_form(t, "indc_pres_1p", join_ending(stem_e, "em"))
	add_form(t, "indc_pres_2p", join_ending(stem_e, "eți"))
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_1s))
	
	t.impf_stem = tsub(join_ending(stem, "ea"), 1, -2)
	
	add_form(t, "indc_perf_1s", join_ending(pp_stem, "sei"))
	add_form(t, "indc_perf_2s", join_ending(pp_stem, "seși"))
	add_form(t, "indc_perf_3s", join_ending(pp_stem_e, "se"))
	add_form(t, "indc_perf_1p", join_ending(pp_stem_e, "serăm"))
	add_form(t, "indc_perf_2p", join_ending(pp_stem_e, "serăți"))
	add_form(t, "indc_perf_3p", join_ending(pp_stem_e, "seră"))
	
	t.plup_stem = join_ending(pp_stem, "se")
	
	add_form(t, "subj_pres_3s", join_ending(stem_ah, "ă"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

-- same as e-s except for the past participle
conjugations_new["e-t"] = function(t, stem, stems)
	data.conj = 3
	
	stem = stem or get_stem_e() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before i ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before ă ending
	
	local pp_stem = tsub(stem, 1, -2)
	local pp_stem_ = tsub(stem_, 1, -2)
	local pp_stem_e = tsub(stem_e, 1, -2)
	
	add_form(t, "ger", join_ending(stem, "ând", true))
	add_form(t, "pp", join_ending(pp_stem_, "t"))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_", true))
	add_form(t, "indc_pres_3s", join_ending(stem_e, "e"))
	add_form(t, "indc_pres_1p", join_ending(stem_e, "em"))
	add_form(t, "indc_pres_2p", join_ending(stem_e, "eți"))
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_1s))
	
	t.impf_stem = tsub(join_ending(stem, "ea"), 1, -2)
	
	add_form(t, "indc_perf_1s", join_ending(pp_stem, "sei"))
	add_form(t, "indc_perf_2s", join_ending(pp_stem, "seși"))
	add_form(t, "indc_perf_3s", join_ending(pp_stem_e, "se"))
	add_form(t, "indc_perf_1p", join_ending(pp_stem_e, "serăm"))
	add_form(t, "indc_perf_2p", join_ending(pp_stem_e, "serăți"))
	add_form(t, "indc_perf_3p", join_ending(pp_stem_e, "seră"))
	
	t.plup_stem = join_ending(pp_stem, "se")
	
	add_form(t, "subj_pres_3s", join_ending(stem_ah, "ă"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

conjugations_new["e-pt"] = function(t, stem, stems)
	data.conj = 3
	
	stem = stem or get_stem_e() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before i ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before ă ending
	
	local pp_stem = tsub(stem, 1, -2)
	local pp_stem_ = tsub(stem_, 1, -2)
	local pp_stem_e = tsub(stem_e, 1, -2)
	
	add_form(t, "ger", join_ending(stem, "ând", true))
	add_form(t, "pp", join_ending(pp_stem_, "pt"))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_", true))
	add_form(t, "indc_pres_3s", join_ending(stem_e, "e"))
	add_form(t, "indc_pres_1p", join_ending(stem_e, "em"))
	add_form(t, "indc_pres_2p", join_ending(stem_e, "eți"))
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_1s))
	
	t.impf_stem = tsub(join_ending(stem, "ea"), 1, -2)
	
	add_form(t, "indc_perf_1s", join_ending(pp_stem, "psei"))
	add_form(t, "indc_perf_2s", join_ending(pp_stem, "pseși"))
	add_form(t, "indc_perf_3s", join_ending(pp_stem_e, "pse"))
	add_form(t, "indc_perf_1p", join_ending(pp_stem_e, "pserăm"))
	add_form(t, "indc_perf_2p", join_ending(pp_stem_e, "pserăți"))
	add_form(t, "indc_perf_3p", join_ending(pp_stem_e, "pseră"))
	
	t.plup_stem = join_ending(pp_stem, "pse")
	
	add_form(t, "subj_pres_3s", join_ending(stem_ah, "ă"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

conjugations_new["e-ut"] = function(t, stem, stems)
	data.conj = 3
	
	stem = stem or get_stem_e() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before i ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before ă ending
	
	add_form(t, "ger", join_ending(stem, "ând", true))
	add_form(t, "pp", join_ending(stem, "ut", true))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_", true))
	add_form(t, "indc_pres_3s", join_ending(stem_e, "e"))
	add_form(t, "indc_pres_1p", join_ending(stem_e, "em"))
	add_form(t, "indc_pres_2p", join_ending(stem_e, "eți"))
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_1s))
	
	t.impf_stem = tsub(join_ending(stem, "ea"), 1, -2)
	
	add_form(t, "indc_perf_1s", join_ending(stem, "ui", true))
	add_form(t, "indc_perf_2s", join_ending(stem, "uși", true))
	add_form(t, "indc_perf_3s", join_ending(stem, "u", true))
	add_form(t, "indc_perf_1p", join_ending(stem, "urăm", true))
	add_form(t, "indc_perf_2p", join_ending(stem, "urăți", true))
	add_form(t, "indc_perf_3p", join_ending(stem, "ură", true))
	
	t.plup_stem = join_ending(stem, "u", true)
	
	add_form(t, "subj_pres_3s", join_ending(stem_ah, "ă"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

conjugations_new["ea-ut"] = function(t, stem, stems)
	data.conj = 2
	
	stem = stem or get_stem_ea() -- unstressed stem
	stem_ = stems["-"] or stem -- stressed stem before zero ending
	stem_ah = stems["ă"] or stem -- stressed stem before i ending
	stem_e = stems["e"] or stem -- stressed stem before e ending
	stem_i = stems["i"] or stem -- stressed stem before ă ending
	
	add_form(t, "ger", join_ending(stem, "ând", true))
	add_form(t, "pp", join_ending(stem, "ut", true))
	
	add_form(t, "indc_pres_1s", join_ending(stem_, ""))
	add_form(t, "indc_pres_2s", join_ending(stem_i, "i_", true))
	add_form(t, "indc_pres_3s", join_ending(stem_e, "e"))
	add_form(t, "indc_pres_1p", join_ending(stem, "em"))
	add_form(t, "indc_pres_2p", join_ending(stem, "eți"))
	add_form(t, "indc_pres_3p", mw.clone(t.indc_pres_1s))
	
	t.impf_stem = tsub(join_ending(stem, "ea"), 1, -2)
	
	add_form(t, "indc_perf_1s", join_ending(stem, "ui", true))
	add_form(t, "indc_perf_2s", join_ending(stem, "uși", true))
	add_form(t, "indc_perf_3s", join_ending(stem, "u", true))
	add_form(t, "indc_perf_1p", join_ending(stem, "urăm", true))
	add_form(t, "indc_perf_2p", join_ending(stem, "urăți", true))
	add_form(t, "indc_perf_3p", join_ending(stem, "ură", true))
	
	t.plup_stem = join_ending(stem, "u", true)
	
	add_form(t, "subj_pres_3s", join_ending(stem_ah, "ă"))
	
	add_form(t, "impr_aff_2s", mw.clone(t.indc_pres_3s))
end

local add_repeated_forms = function()
	add_form(data.forms, "inf", {data.lemma})
	
	local impf_stem = mw.ustring.match(data.forms.indc_impf_1s[1], "^(.*)am$")
	
	add_form(data.forms, "indc_impf_2s", {impf_stem .. "ai"})
	add_form(data.forms, "indc_impf_3s", {impf_stem .. "a"})
	add_form(data.forms, "indc_impf_1p", {impf_stem .. "am"})
	add_form(data.forms, "indc_impf_2p", {impf_stem .. "ați"})
	add_form(data.forms, "indc_impf_3p", {impf_stem .. "au"})
	
	local plup_stem = mw.ustring.match(data.forms.indc_plup_1s[1], "^(.*)sem$")
	
	add_form(data.forms, "indc_perf_1s", {plup_stem .. "i"})
	add_form(data.forms, "indc_perf_2s", {plup_stem .. "și"})
	
	local pl_perf_stem = mw.ustring.match(data.forms.indc_perf_1p[1], "^(.*)răm$")
	
	add_form(data.forms, "indc_perf_2p", {pl_perf_stem .. "răți"})
	add_form(data.forms, "indc_perf_3p", {pl_perf_stem .. "ră"})
	
	add_form(data.forms, "indc_plup_2s", {plup_stem .. "seși"})
	add_form(data.forms, "indc_plup_3s", {plup_stem .. "se"})
	add_form(data.forms, "indc_plup_1p", {plup_stem .. "serăm"})
	add_form(data.forms, "indc_plup_2p", {plup_stem .. "serăți"})
	add_form(data.forms, "indc_plup_3p", {plup_stem .. "seră"})
	
	add_form(data.forms, "subj_pres_1s", mw.clone(data.forms.indc_pres_1s))
	add_form(data.forms, "subj_pres_2s", mw.clone(data.forms.indc_pres_2s))
	add_form(data.forms, "subj_pres_1p", mw.clone(data.forms.indc_pres_1p))
	add_form(data.forms, "subj_pres_2p", mw.clone(data.forms.indc_pres_2p))
	
	add_form(data.forms, "impr_aff_2p", mw.clone(data.forms.indc_pres_2p))
	add_form(data.forms, "impr_neg_2s", mw.clone(data.forms.inf))
	add_form(data.forms, "impr_neg_2p", mw.clone(data.forms.impr_aff_2p))
end

local conjugations = {}

-- First conjugation
conjugations["a-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "aduna"
	end
	
	local conj
	
	if (mw.ustring.match(data.lemma, "[" .. vowels .. "]ia$")) then
		conj = "Via"
	elseif (mw.ustring.match(data.lemma, "ia$")) then
		conj = "Cia"
	elseif (mw.ustring.match(data.lemma, "hea$")) then
		conj = "chea"
	else
		conj = "a"
	end
	
	data.conj = 1
	data.infix = "no"
	
	conjugations[conj](stem)
end

conjugations["a"] = function(stem)
	stem = stem or data.lemma:match("^(.*)a$")

	add_form(data.forms, "inf", {stem .. "a"})
	add_form(data.forms, "ger", {stem .. "ând"})
	add_form(data.forms, "pp", {stem .. "at"})
	
	add_form(data.forms, "indc_pres_1s", {stem})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ă"})
	add_form(data.forms, "indc_pres_1p", {stem .. "ăm"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ați"})
	add_form(data.forms, "indc_pres_3p", mw.clone(data.forms.indc_pres_3s))
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "ă"})
	add_form(data.forms, "indc_perf_1p", {stem .. "arăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "asem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "e"})
	add_form(data.forms, "subj_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "impr_aff_2s", mw.clone(data.forms.indc_pres_3s))
end

conjugations["chea"] = function(stem)
	stem = stem or data.lemma:match("^(.*)ea$")

	add_form(data.forms, "inf", {stem .. "ea"})
	add_form(data.forms, "ger", {stem .. "ind"})
	add_form(data.forms, "pp", {stem .. "eat"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "i"})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "eați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "eam"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "e"})
	add_form(data.forms, "indc_perf_1p", {stem .. "earăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "easem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "e"})
	add_form(data.forms, "subj_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "e"})
end

conjugations["Cia"] = function(stem)
	stem = stem or data.lemma:match("^(.*)a$")

	add_form(data.forms, "inf", {stem .. "a"})
	add_form(data.forms, "ger", {stem .. "ind"})
	add_form(data.forms, "pp", {stem .. "at"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "i"})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "e"})
	add_form(data.forms, "indc_perf_1p", {stem .. "arăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "asem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "e"})
	add_form(data.forms, "subj_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "e"})
end
	
conjugations["Via"] = function(stem)
	stem = stem or data.lemma:match("^(.*)a$")

	add_form(data.forms, "inf", {stem .. "a"})
	add_form(data.forms, "ger", {stem .. "nd"})
	add_form(data.forms, "pp", {stem .. "at"})
	
	add_form(data.forms, "indc_pres_1s", {stem})
	add_form(data.forms, "indc_pres_2s", {stem})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "e"})
	add_form(data.forms, "indc_perf_1p", {stem .. "arăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "asem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "e"})
	add_form(data.forms, "subj_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "e"})
end

conjugations["a-ez-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "lucra"
	end
	
	local conj
	
	if (mw.ustring.match(data.lemma, "[" .. vowels .. "]ia$")) then
		conj = "Via-ez"
	elseif (mw.ustring.match(data.lemma, "ia$")) then
		conj = "Cia-ez"
	elseif (mw.ustring.match(data.lemma, "hea$")) then
		conj = "chea-ez"
	elseif (mw.ustring.match(data.lemma, "[cg]a$")) then
		conj = "ca-ez"
	else
		conj = "a-ez"
	end
	
	data.conj = 1
	data.infix = "-ez-"
	
	conjugations[conj](stem)
end

conjugations["a-ez"] = function(stem)
	stem = stem or data.lemma:match("^(.*)a$")

	add_form(data.forms, "inf", {stem .. "a"})
	add_form(data.forms, "ger", {stem .. "ând"})
	add_form(data.forms, "pp", {stem .. "at"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "ez"})
	add_form(data.forms, "indc_pres_2s", {stem .. "ezi"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ează"})
	add_form(data.forms, "indc_pres_1p", {stem .. "ăm"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "ează"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "ă"})
	add_form(data.forms, "indc_perf_1p", {stem .. "arăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "asem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "eze"})
	add_form(data.forms, "subj_pres_3p", {stem .. "eze"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "ează"})
end

conjugations["ca-ez"] = function(stem)
	stem = stem or data.lemma:match("^(.*)a$")

	add_form(data.forms, "inf", {stem .. "a"})
	add_form(data.forms, "ger", {stem .. "ând"})
	add_form(data.forms, "pp", {stem .. "at"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "hez"})
	add_form(data.forms, "indc_pres_2s", {stem .. "hezi"})
	add_form(data.forms, "indc_pres_3s", {stem .. "hează"})
	add_form(data.forms, "indc_pres_1p", {stem .. "ăm"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "hează"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "ă"})
	add_form(data.forms, "indc_perf_1p", {stem .. "arăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "asem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "heze"})
	add_form(data.forms, "subj_pres_3p", {stem .. "heze"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "hează"})
end

conjugations["chea-ez"] = function(stem)
	stem = stem or data.lemma:match("^(.*)ea$")

	add_form(data.forms, "inf", {stem .. "ea"})
	add_form(data.forms, "ger", {stem .. "ind"})
	add_form(data.forms, "pp", {stem .. "eat"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "ez"})
	add_form(data.forms, "indc_pres_2s", {stem .. "ezi"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ează"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "eați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "ează"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "eam"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "e"})
	add_form(data.forms, "indc_perf_1p", {stem .. "earăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "easem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "eze"})
	add_form(data.forms, "subj_pres_3p", {stem .. "eze"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "ează"})
end

conjugations["Cia-ez"] = function(stem)
	stem = stem or data.lemma:match("^(.*)a$")

	add_form(data.forms, "inf", {stem .. "a"})
	add_form(data.forms, "ger", {stem .. "ind"})
	add_form(data.forms, "pp", {stem .. "at"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "ez"})
	add_form(data.forms, "indc_pres_2s", {stem .. "ezi"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ază"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "ază"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "e"})
	add_form(data.forms, "indc_perf_1p", {stem .. "arăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "asem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "eze"})
	add_form(data.forms, "subj_pres_3p", {stem .. "eze"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "ază"})
end
	
conjugations["Via-ez"] = function(stem)
	stem = stem or data.lemma:match("^(.*)a$")

	add_form(data.forms, "inf", {stem .. "a"})
	add_form(data.forms, "ger", {stem .. "nd"})
	add_form(data.forms, "pp", {stem .. "at"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "ez"})
	add_form(data.forms, "indc_pres_2s", {stem .. "ezi"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ază"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ați"})
	add_form(data.forms, "indc_pres_3p", {stem .. "ază"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})

	add_form(data.forms, "indc_perf_3s", {stem .. "e"})
	add_form(data.forms, "indc_perf_1p", {stem .. "arăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "asem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "eze"})
	add_form(data.forms, "subj_pres_3p", {stem .. "eze"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "ază"})
end

-- Second conjugation
conjugations["ea-ut-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "" -- todo
	end
	
	data.conj = 2
	
	stem = stem or data.lemma:match("^(.*)ea$")

	add_form(data.forms, "inf", {stem .. "ea"})
	add_form(data.forms, "ger", {stem .. "ând"})
	add_form(data.forms, "pp", {stem .. "ut"})
	
	add_form(data.forms, "indc_pres_1s", {stem})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "eți"})
	add_form(data.forms, "indc_pres_3p", mw.clone(data.forms.indc_pres_1s))
	
	add_form(data.forms, "indc_impf_1s", {stem .. "eam"})

	add_form(data.forms, "indc_perf_3s", {stem .. "u"})
	add_form(data.forms, "indc_perf_1p", {stem .. "urăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "usem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "ă"})
	add_form(data.forms, "subj_pres_3p", {stem .. "ă"})
	
	add_form(data.forms, "impr_aff_2s", mw.clone(data.forms.indc_pres_3s))
end

-- Third conjugation
conjugations["e-s-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "stinge"
	end
	
	data.conj = 3
	
	-- ste is the stem without the last letter... yeah
	local ste, last = data.lemma:match("^(.*)(.)e$")

	add_form(data.forms, "inf", {ste .. last .. "e"})
	add_form(data.forms, "ger", {ste .. last .. "ând"})
	add_form(data.forms, "pp", {ste .. "s"})
	
	add_form(data.forms, "indc_pres_1s", {ste .. last})
	add_form(data.forms, "indc_pres_2s", {ste .. last .. "i"})
	add_form(data.forms, "indc_pres_3s", {ste .. last .. "e"})
	add_form(data.forms, "indc_pres_1p", {ste .. last .. "em"})
	add_form(data.forms, "indc_pres_2p", {ste .. last .. "eți"})
	add_form(data.forms, "indc_pres_3p", mw.clone(data.forms.indc_pres_1s))
	
	add_form(data.forms, "indc_impf_1s", {ste .. last .. "eam"})

	add_form(data.forms, "indc_perf_3s", {ste .. "se"})
	add_form(data.forms, "indc_perf_1p", {ste .. "serăm"})
	
	add_form(data.forms, "indc_plup_1s", {ste .. "sesem"})

	add_form(data.forms, "subj_pres_3s", {ste .. last .. "ă"})
	add_form(data.forms, "subj_pres_3p", {ste .. last .. "ă"})
	
	add_form(data.forms, "impr_aff_2s", mw.clone(data.forms.indc_pres_3s))
end

conjugations["e-ut-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "" -- todo
	end
	
	data.conj = 3
	
	stem = stem or data.lemma:match("^(.*)e$")

	add_form(data.forms, "inf", {stem .. "e"})
	add_form(data.forms, "ger", {stem .. "ând"})
	add_form(data.forms, "pp", {stem .. "ut"})
	
	add_form(data.forms, "indc_pres_1s", {stem})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "em"})
	add_form(data.forms, "indc_pres_2p", {stem .. "eți"})
	add_form(data.forms, "indc_pres_3p", mw.clone(data.forms.indc_pres_1s))
	
	add_form(data.forms, "indc_impf_1s", {stem .. "eam"})

	add_form(data.forms, "indc_perf_3s", {stem .. "u"})
	add_form(data.forms, "indc_perf_1p", {stem .. "urăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "usem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "ă"})
	add_form(data.forms, "subj_pres_3p", {stem .. "ă"})
	
	add_form(data.forms, "impr_aff_2s", mw.clone(data.forms.indc_pres_3s))
end

-- Fourth conjugation
conjugations["i-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "" --todo
	end
	
	local conj
	
	if (mw.ustring.match(data.lemma, "hi$")) then
		conj = "chi"
	elseif (mw.ustring.match(data.lemma, "[" .. vowels .. "]i$")) then
		conj = "Vi"
	elseif (mw.ustring.match(data.lemma, "i$")) then
		conj = "Ci"
	end
	
	data.conj = 4
	data.infix = "no"
	
	conjugations[conj](stem)
end

conjugations["Ci"] = function(stem)
	stem = stem or data.lemma:match("^(.*)i$")

	add_form(data.forms, "inf", {stem .. "i"})
	add_form(data.forms, "ger", {stem .. "ind"})
	add_form(data.forms, "pp", {stem .. "it"})
	
	add_form(data.forms, "indc_pres_1s", {stem})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "im"})
	add_form(data.forms, "indc_pres_2p", {stem .. "iți"})
	add_form(data.forms, "indc_pres_3p", {stem})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "eam"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "i"})
	add_form(data.forms, "indc_perf_1p", {stem .. "irăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "isem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "ă"})
	add_form(data.forms, "subj_pres_3p", {stem .. "ă"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "e"})
end

conjugations["Vi"] = function(stem)
	stem = stem or data.lemma
	
	-- todo: remove ugly hack
	if stem .. "i" == data.lemma then
		stem = data.lemma
	end

	add_form(data.forms, "inf", {stem})
	add_form(data.forms, "ger", {stem .. "nd"})
	add_form(data.forms, "pp", {stem .. "t"})
	
	add_form(data.forms, "indc_pres_1s", {stem})
	add_form(data.forms, "indc_pres_2s", {stem})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "m"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ți"})
	add_form(data.forms, "indc_pres_3p", mw.clone(data.forms.indc_pres_3s))
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem})
	add_form(data.forms, "indc_perf_1p", {stem .. "răm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "sem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "e"})
	add_form(data.forms, "subj_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "impr_aff_2s", mw.clone(data.forms.indc_pres_3s))
end

conjugations["chi"] = function(stem)
	stem = stem or data.lemma:match("^(.*)i$")

	add_form(data.forms, "inf", {stem .. "i"})
	add_form(data.forms, "ger", {stem .. "ind"})
	add_form(data.forms, "pp", {stem .. "it"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "i"})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "e"})
	add_form(data.forms, "indc_pres_1p", {stem .. "im"})
	add_form(data.forms, "indc_pres_2p", {stem .. "iți"})
	add_form(data.forms, "indc_pres_3p", {stem .. "i"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "eam"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "i"})
	add_form(data.forms, "indc_perf_1p", {stem .. "irăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "isem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "e"})
	add_form(data.forms, "subj_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "e"})
end

conjugations["i-esc-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "munci"
	end
	
	local conj
	
	if (mw.ustring.match(data.lemma, "[" .. vowels .. "]i$")) then
		conj = "Vi-esc"
	elseif (mw.ustring.match(data.lemma, "i$")) then
		conj = "Ci-esc"
	end
	
	data.conj = 4
	data.infix = "-esc-"
	
	conjugations[conj](stem)
end

conjugations["Ci-esc"] = function(stem)
	stem = stem or data.lemma:match("^(.*)i$")

	add_form(data.forms, "inf", {stem .. "i"})
	add_form(data.forms, "ger", {stem .. "ind"})
	add_form(data.forms, "pp", {stem .. "it"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "esc"})
	add_form(data.forms, "indc_pres_2s", {stem .. "ești"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ește"})
	add_form(data.forms, "indc_pres_1p", {stem .. "im"})
	add_form(data.forms, "indc_pres_2p", {stem .. "iți"})
	add_form(data.forms, "indc_pres_3p", {stem .. "esc"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "eam"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "i"})
	add_form(data.forms, "indc_perf_1p", {stem .. "irăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "isem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "ească"})
	add_form(data.forms, "subj_pres_3p", {stem .. "ească"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "ește"})
end

conjugations["Vi-esc"] = function(stem)
	stem = stem or data.lemma
	
	-- todo: remove
	if not mw.ustring.find(stem, "i$") then
		stem = stem .. "i"
	end

	add_form(data.forms, "inf", {stem})
	add_form(data.forms, "ger", {stem .. "nd"})
	add_form(data.forms, "pp", {stem .. "t"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "esc"})
	add_form(data.forms, "indc_pres_2s", {stem .. "ești"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ește"})
	add_form(data.forms, "indc_pres_1p", {stem .. "m"})
	add_form(data.forms, "indc_pres_2p", {stem .. "ți"})
	add_form(data.forms, "indc_pres_3p", {stem .. "esc"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem})
	add_form(data.forms, "indc_perf_1p", {stem .. "răm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "sem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "ască"})
	add_form(data.forms, "subj_pres_3p", {stem .. "ască"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "ește"})
end

conjugations["î-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "" --todo
	end
	
	data.conj = 4
	data.infix = "no"
	
	stem = stem or data.lemma:match("^(.*)î$")

	add_form(data.forms, "inf", {stem .. "î"})
	add_form(data.forms, "ger", {stem .. "ând"})
	add_form(data.forms, "pp", {stem .. "ât"})
	
	add_form(data.forms, "indc_pres_1s", {stem})
	add_form(data.forms, "indc_pres_2s", {stem .. "i"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ă"})
	add_form(data.forms, "indc_pres_1p", {stem .. "âm"})
	add_form(data.forms, "indc_pres_2p", {stem .. "âți"})
	add_form(data.forms, "indc_pres_3p", mw.clone(data.forms.indc_pres_3s))
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "î"})
	add_form(data.forms, "indc_perf_1p", {stem .. "ârăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "âsem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "e"})
	add_form(data.forms, "subj_pres_3p", {stem .. "e"})
	
	add_form(data.forms, "impr_aff_2s", mw.clone(data.forms.indc_pres_3s))
end

conjugations["î-ăsc-generic"] = function(stem)
	if mw.title.getCurrentTitle().nsText == "Template" then
		data.lemma = "hotărî" --todo
	end
	
	data.conj = 4
	data.infix = "-ăsc-"
	
	stem = stem or data.lemma:match("^(.*)î$")

	add_form(data.forms, "inf", {stem .. "î"})
	add_form(data.forms, "ger", {stem .. "ând"})
	add_form(data.forms, "pp", {stem .. "ât"})
	
	add_form(data.forms, "indc_pres_1s", {stem .. "ăsc"})
	add_form(data.forms, "indc_pres_2s", {stem .. "ăști"})
	add_form(data.forms, "indc_pres_3s", {stem .. "ăște"})
	add_form(data.forms, "indc_pres_1p", {stem .. "âm"})
	add_form(data.forms, "indc_pres_2p", {stem .. "âți"})
	add_form(data.forms, "indc_pres_3p", {stem .. "ăsc"})
	
	add_form(data.forms, "indc_impf_1s", {stem .. "am"})
	
	add_form(data.forms, "indc_perf_3s", {stem .. "î"})
	add_form(data.forms, "indc_perf_1p", {stem .. "ârăm"})
	
	add_form(data.forms, "indc_plup_1s", {stem .. "âsem"})

	add_form(data.forms, "subj_pres_3s", {stem .. "ască"})
	add_form(data.forms, "subj_pres_3p", {stem .. "ască"})
	
	add_form(data.forms, "impr_aff_2s", {stem .. "ăște"})
end

local add_given_forms = function(args)
	local add_form = function(form_name, arg_name, appendix)
		appendix = appendix or ""
		
		if args[arg_name] then
			data.forms[form_name] = mw.text.split(args[arg_name], " *, *")
			
			for i, val in ipairs(data.forms[form_name]) do
				data.forms[form_name][i] = val .. appendix
			end
		end
	end
	
	add_form("ger", "ger")
	add_form("pp", "past")
	
	add_form("indc_pres_1s", "1s")
	add_form("indc_pres_2s", "2s")
	add_form("indc_pres_3s", "3s")
	add_form("indc_pres_1p", "1p")
	add_form("indc_pres_2p", "2p")
	add_form("indc_pres_3p", "3p")
	
	add_form("indc_impf_1s", "imp", "am")
	add_form("indc_impf_3s", "3imp")
	
	add_form("indc_perf_3s", "3perf")
	add_form("indc_perf_1p", args["plperf"] and "plperf" or "perf", "răm")
	
	add_form("indc_plup_1s", "perf", "sem")
	
	add_form("subj_pres_3s", "3sub")
	add_form("subj_pres_3p", "3sub")
	
	add_form("impr_aff_2s", "2imp")
end

local function get_conj_type()
	local conj_type
	
	if data.conj == 1 then
		if data.forms.indc_pres_1s[1] == join_ending_2(get_stem_a(), "ez")[1] then
			conj_type = "a-ez"
		else
			conj_type = "a"
		end
	elseif data.conj == 4 then
		if mw.ustring.find(data.lemma, "i$") then
			if data.forms.indc_pres_1s[1] == get_stem_i() .. "esc" or data.forms.indc_pres_1s[1] == mw.ustring.gsub(get_stem_i(), "ii$", "iesc") then
				conj_type = "i-esc"
			else
				conj_type = "i"
			end
		else
			if data.forms.indc_pres_1s[1] == get_stem_ih() .. "ăsc" then
				conj_type = "î-ăsc"
			else
				conj_type = "î"
			end
		end
	elseif data.conj == 3 then
		if mw.ustring.find(data.forms.pp[1], "ut$") then
			conj_type = "e-ut"
		elseif mw.ustring.find(data.forms.pp[1], "pt$") then
			conj_type = "e-pt"
		elseif mw.ustring.find(data.forms.pp[1], "t$") then
			conj_type = "e-t"
		else
			conj_type = "e-s"
		end
	elseif data.conj == 2 then
		if mw.ustring.find(data.forms.pp[1], "ut$") then
			conj_type = "ea-ut"
		elseif mw.ustring.find(data.forms.pp[1], "pt$") then
			conj_type = "ea-pt"
		elseif mw.ustring.find(data.forms.pp[1], "t$") then
			conj_type = "ea-t"
		else
			conj_type = "ea-s"
		end
	else
		error("No conjugation type given")
	end
	
	return conj_type
end

local function get_stem_1s()
	local res
	
	if data.type == "a" then
		if mw.ustring.find(data.lemma, "[" .. vowels .. "]ia$") then
			res = data.forms.indc_pres_1s[1]
		elseif mw.ustring.find(data.lemma, "ia$") then
			res = mw.ustring.match(data.forms.indc_pres_1s[1], "^(.*)i$")
		elseif mw.ustring.find(data.lemma, "[cg]hea$") then
			res = mw.ustring.match(data.forms.indc_pres_1s[1], "^(.*)i$")
		elseif mw.ustring.find(data.lemma, "[^" .. vowels .. "][lr]a$") then
			res = mw.ustring.match(data.forms.indc_pres_1s[1], "^(.*)u$")
		else
			res = data.forms.indc_pres_1s[1]
		end
	else
		res = data.forms.indc_pres_1s[1]
	end
	
	return res
end

local function replace_stem_cons(res, ending, conj_23)
	local stem1, vow1, cons1 = split(data.forms.indc_pres_1s[1])
	local stem2, vow2, cons2 = split(res)
	
	if cons1 ~= cons2 then
		local consf = find_cons(cons1, ending, conj_23)
		
		if consf == cons2 then
			res = stem2 .. vow2 .. cons1
		end
	end
	
	return res
end

local function get_stem_2s(conj_23)
	local res
	
	if data.type == "a" then
		if mw.ustring.find(data.lemma, "[" .. vowels .. "]ia$") then
			res = data.forms.indc_pres_2s[1]
		else
			res = mw.ustring.match(data.forms.indc_pres_2s[1], "^(.*)i$")
		end
	elseif data.type == "i" then
		if mw.ustring.find(data.lemma, "[" .. vowels .. "]i$") then
			res = data.forms.indc_pres_2s[1]
		else
			res = mw.ustring.match(data.forms.indc_pres_2s[1], "^(.*)i$")
		end
	else
		res = mw.ustring.match(data.forms.indc_pres_2s[1], "^(.*)i$")
	end
	
	if not mw.ustring.find(data.forms.indc_pres_1s[1], "[" .. vowels .. "]$") then
		res = replace_stem_cons(res, "i_", conj_23)
	end
	
	return res
end

local function get_stem_3s()
	local res = mw.ustring.match(data.forms.indc_pres_3s[1], "^(.*)[ăe]$")
	
	if not mw.ustring.find(data.forms.indc_pres_1s[1], "[" .. vowels .. "]$") 
	and mw.ustring.find(data.forms.indc_pres_3s[1], "e$") then
		res = replace_stem_cons(res, "e")
	end
	
	return res
end

local function get_stem_3sub()
	local res = mw.ustring.match(data.forms.subj_pres_3s[1], "^(.*)[ăe]$")
	
	if not mw.ustring.find(data.forms.indc_pres_1s[1], "[" .. vowels .. "]$") 
	and mw.ustring.find(data.forms.subj_pres_3s[1], "e$") then
		res = replace_stem_cons(res, "e")
	end
	
	return res
end

local function compare_conj()
	local stem_appearances, stems, inf_stem = {}, {}
	local forms_new = {}
	
	local conj_type = get_conj_type()
	
	if data.type and data.type ~= conj_type then
		require("Module:debug").track("ro-verb/different conj type")
	end
	
	data.type = conj_type
	
	if data.conj == 3 then
		inf_stem = {mw.ustring.match(data.forms.ger[1], "^(.*)ând$")}
		local stemi, vowi, consi = split(inf_stem[1])
		local stem1, vow1, cons1 = split(data.forms.indc_pres_1s[1])
		
		if consi ~= cons1 and find_cons(cons1, "â", true, vowi) == consi then
			inf_stem[1] = stemi .. vowi .. cons1
		end
	else
		inf_stem = {get_inf_stem()}
	end
	
	local ok, errtext = true
	
	if conj_type == "a-ez" or conj_type == "i-esc" or conj_type == "î-ăsc" then
		stems = nil
	else
		local conj_23
		
		if data.conj == 2 or data.conj == 3 then
			conj_23 = true
		end
		
		ok, errtext = pcall(function()
			stem_appearances[get_stem_1s()] = true
			stem_appearances[get_stem_2s(conj_23)] = true
			stem_appearances[get_stem_3s()] = true
			stem_appearances[get_stem_3sub()] = true
		end)
	
		if ok then
			for key, _ in pairs(stem_appearances) do
				table.insert(stems, key)
			end
		
			stems = table.concat(stems, "/")
		
			ok, errtext = pcall(get_stems, stems)
		end
	end
	
	local equal = true
	local equal_except_impr = false
	local wrong_form = ""
	
	if ok then
		stems = errtext
		ok, errtext = pcall(conjugations_new[data.type], forms_new, inf_stem, stems)
	end
	
	if not ok then
		equal = false
		wrong_form = "error: " .. errtext
	else
		equal_except_impr = true
		add_repeated_forms_new(forms_new)
		
		for _, val in ipairs(form_names) do
			if #forms_new[val] >= 2 or #data.forms[val] >= 2 then
				if not tequals(forms_new[val], data.forms[val]) then
					equal = false
					wrong_form = wrong_form .. val .. ":" 
					.. table.concat(forms_new[val], ",") .. "~="	
					.. table.concat(data.forms[val], ",") .. ";"
					
					if val ~= "impr_aff_2s" then
						equal_except_impr = false
					end
				end
			elseif forms_new[val][1] ~= data.forms[val][1] then
				equal = false
				wrong_form = wrong_form .. val .. ":" 
				.. (forms_new[val][1] or "nil") .. "~="
				.. (data.forms[val][1] or "nil") .. ";"
				
				if val ~= "impr_aff_2s" then
					equal_except_impr = false
				end
			end
		end
	end
	
	if equal then
		require("Module:debug").track("ro-verb/matches_new/yes")
		
		if dbg then
			table.insert(data.info, "same")
		end
	else
		require("Module:debug").track("ro-verb/matches_new/no")
		
		if dbg then
			table.insert(data.info, "different: " .. wrong_form)
		end
	
		if equal_except_impr then
			require("Module:debug").track("ro-verb/matches_new/no/impr")
		else
			require("Module:debug").track("ro-verb/matches_new/no/others")
		end
	end
end

local function make_table()
	data.info = table.concat(data.info, ", ")
	if data.info == "" then data.info = nil end
	
	local function show_form(form)
		if not form then
			return "—"
		elseif type(form) ~= "table" then
			error("a non-table value was given in the list of inflected forms.")
		elseif #form == 0 then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(form) do
			table.insert(ret, m_links.full_link({lang = lang, term = subform}))
		end
		
		return table.concat(ret, "<br/>")
	end
	
	local function repl(param)
		if param == "lemma" then
			return m_links.full_link({lang = lang, alt = data.lemma}, "term")
		elseif param == "info" then
			return #data.info > 0 and " (" .. data.info .. ")" or ""
		elseif param:match("^pronoun") then
			local person, number = param:match("^pronoun_(.)(.)")
			return data.pronouns[data.sc][person][number]
		else
			return show_form(data.forms[param])
		end
	end
	
	local result = [=[
<div class="NavFrame">
<div class="NavHead" style="background:#CDC3CA">&nbsp; &nbsp; conjugation of {{{lemma}}} <small>{{{info}}}</small></div>
<div class="NavContent">

{| width=100% style="text-align:center;background:#F0F0F0" class="inflection-table"
|-
! colspan="3" style="background:#DED4DB" | <span title="infinitiv">infinitive</span>
| colspan="5" | {{{inf}}}

|-
! colspan="3"  style="background:#DED4DB" | <span title="gerunziu">gerund</span>
| colspan="5" | {{{ger}}}

|-
! colspan="3" style="background:#DED4DB" | <span title="participiu">past participle</span>
| colspan="5" | {{{pp}}}

|-
! colspan="2" style="background:#C0C0C0" | number
! colspan="3" style="background:#C0C0C0" | singular
! colspan="3" style="background:#C0C0C0" | plural

|-
! colspan="2" style="background:#C0C0C0" | person
! style="background:#C0C0C0" | 1st person
! style="background:#C0C0C0" | 2nd person
! style="background:#C0C0C0" | 3rd person
! style="background:#C0C0C0" | 1st person
! style="background:#C0C0C0" | 2nd person
! style="background:#C0C0C0" | 3rd person

|-
! rowspan="5" style="background:#BCB2B9" | <span title="indicativ">indicative</span>
! style="background:#BCB2B9" | 
! style="background:#BCB2B9" | {{{pronoun_1s}}}
! style="background:#BCB2B9" | {{{pronoun_2s}}}
! style="background:#BCB2B9" | {{{pronoun_3s}}}
! style="background:#BCB2B9" | {{{pronoun_1p}}}
! style="background:#BCB2B9" | {{{pronoun_2p}}}
! style="background:#BCB2B9" | {{{pronoun_3p}}}

|-
! style="background:#BCB2B9" | <span title="prezent">present</span>
| {{{indc_pres_1s}}}
| {{{indc_pres_2s}}}
| {{{indc_pres_3s}}}
| {{{indc_pres_1p}}}
| {{{indc_pres_2p}}}
| {{{indc_pres_3p}}}

|-
! style="background:#BCB2B9" | <span title="imperfect">imperfect</span>
| {{{indc_impf_1s}}}
| {{{indc_impf_2s}}}
| {{{indc_impf_3s}}}
| {{{indc_impf_1p}}}
| {{{indc_impf_2p}}}
| {{{indc_impf_3p}}}

|-
! style="background:#BCB2B9" | <span title="perfect simplu">simple perfect</span>
| {{{indc_perf_1s}}}
| {{{indc_perf_2s}}}
| {{{indc_perf_3s}}}
| {{{indc_perf_1p}}}
| {{{indc_perf_2p}}}
| {{{indc_perf_3p}}}

|-
! style="background:#BCB2B9" | <span title="mai mult ca perfect">pluperfect</span>
| {{{indc_plup_1s}}}
| {{{indc_plup_2s}}}
| {{{indc_plup_3s}}}
| {{{indc_plup_1p}}}
| {{{indc_plup_2p}}}
| {{{indc_plup_3p}}}

|-
! rowspan="2" style="background:#CDC3CA" | <span title="conjunctiv">subjunctive</span>
! style="background:#CDC3CA" | 
! style="background:#CDC3CA" | {{{pronoun_1s}}}
! style="background:#CDC3CA" | {{{pronoun_2s}}}
! style="background:#CDC3CA" | {{{pronoun_3s}}}
! style="background:#CDC3CA" | {{{pronoun_1p}}}
! style="background:#CDC3CA" | {{{pronoun_2p}}}
! style="background:#CDC3CA" | {{{pronoun_3p}}}

|-
! style="background:#CDC3CA" | <span title="prezent">present</span>
| {{{subj_pres_1s}}}
| {{{subj_pres_2s}}}
| {{{subj_pres_3s}}}
| {{{subj_pres_1p}}}
| {{{subj_pres_2p}}}
| {{{subj_pres_3p}}}

|-
! rowspan="3" style="background:#DED4DB" | <span title="imperativ">imperative</span>
! style="background:#DED4DB" | 
! style="background:#DED4DB" | —
! style="background:#DED4DB" | {{{pronoun_2s}}}
! style="background:#DED4DB" | —
! style="background:#DED4DB" | —
! style="background:#DED4DB" | {{{pronoun_2p}}}
! style="background:#DED4DB" | —

|-
! style="background:#DED4DB" | affirmative
| 
| {{{impr_aff_2s}}}
| 
| 
| {{{impr_aff_2p}}}
| 

|-
! style="background:#DED4DB" | negative
| 
| {{{impr_neg_2s}}}
| 
| 
| {{{impr_neg_2p}}}
| 
|}</div></div>]=]

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

local function add_particle(form_table, particle)
	if form_table then
		for i, form in ipairs(form_table) do
			form_table[i] = particle .. " [[" .. form .. "]]"
		end
	end
end

local function add_particles()
	add_particle(data.forms.inf, data.sc == "Cyrl" and "а" or "a")
	
	local sa = data.sc == "Cyrl" and "сэ" or "să"
	
	for i = 1, 3 do
		add_particle(data.forms["subj_pres_" .. i .. "s"], sa)
		add_particle(data.forms["subj_pres_" .. i .. "p"], sa)
	end
	
	local nu = data.sc == "Cyrl" and "ну" or "nu"
	
	add_particle(data.forms.impr_neg_2s, nu)
	add_particle(data.forms.impr_neg_2p, nu)
end

local function is_new_conj(args)
	if args.new then
		return true
	elseif not args[1] then
		return true
	elseif args[2] then
		if data.type == "e-s" and mw.ustring.len(args[2]) == 1 then
			return false
		else
			return true
		end
	elseif mw.ustring.find(args[1], "[/,]") then
		return true
	elseif not mw.ustring.find(data.lemma, "^" .. args[1]) then
		return true
	else
		return false
	end
end

local function get_type_info()
	if data.type == "e" then
		return "past participle in -s"
	elseif data.type == "ea" then
		return "past participle in -ut"
	elseif mw.ustring.match(data.type, "^[aiî]") then
		local infix = mw.ustring.match(data.type, "^.*\-(.*)$")
		return (infix and "-" .. infix .. "-" or "no") .. " infix"
	else
		local pp = mw.ustring.match(data.type, "^.*\-(.*)$")
		
		if pp then
			return "past participle in -" .. pp
		else
			return "past participle not used"
		end
	end
end

function export.show(frame)
	local args = frame:getParent().args
		
	local params = {
		--["sc"] = {},
		[1] = {},		-- stressed stem(s)
		[2] = {},		-- unstressed stem
		["lemma"] = {},
		["conjtype"] = {}, -- todo: remove this
		["type"] = {},
		["new"] = {type = "boolean"},
		["only"] = {},
	}
	
	local override_params = {
		"ger",
		"past",
		"1s",
		"2s",
		"3s",
		"1p",
		"2p",
		"3p",
		"imp",
		"3imp",
		"perf",
		"3perf",
		"plperf",
		"3sub",
		"2imp",
	}
	
	local no_overrides = true
	
	for _, param in ipairs(override_params) do
		params[param] = {}
		
		if args[param] then
			no_overrides = false
		end
	end
	
	if not no_overrides then
		require("Module:debug").track("ro-verb/overrides")
	end
	
	args = require("Module:parameters").process(args, params)
	
	data.info = {}
	data.only = {}
		
	if args.only then
		if args.only:match("^[1-3]?[sp]?$") then
			for i, val in ipairs(mw.text.split(args.only, "")) do
				data.only[val] = true
			end
		else
			error("Parameter \"only\" has an incorrect value, see documentation for details")
		end
	end
		
	local only_modes = {
		["1"] = "first-person",
		["2"] = "second-person",
		["3"] = "third-person",
		["s"] = "singular",
		["p"] = "plural",
	}
	
	local ordinals = {
		[1] = "first",
		[2] = "second",
		[3] = "third",
		[4] = "fourth",
	}
	
	data.lemma = args.lemma or (mw.title.getCurrentTitle().nsText == "" and PAGENAME)
	data.sc = frame.args.sc or "Latn"
	data.type = args.conjtype or frame.args.type
	
	if data.type == "e" then
		data.type = "e-s"
	elseif data.type == "ea" then
		data.type = "ea-ut"
	end
	
	if data.type == "conj-2" then
		if mw.title.getCurrentTitle().nsText ~= "Template" then
			add_given_forms(args)
			data.conj = tonumber(args.type)
			
			add_repeated_forms()
			
			-- todo: get data.type outside of compare_conj()
			compare_conj()
			
			if dbg then
				table.insert(data.info, "old")
			end
			
			require("Module:debug").track("ro-verb/old")
		end
	else
		if mw.title.getCurrentTitle().nsText == "Template" and
		template_defaults[data.type] and not data.lemma then
			data.lemma = template_defaults[data.type][1]
			args[1] = template_defaults[data.type][2]
			args[2] = template_defaults[data.type][3]
			
			args.new = true
		end
		
		if is_new_conj(args) then	-- new functions
			local inf_stem = args[2] and {args[2]} or {get_inf_stem()}
			local stems = get_stems(args[1] or inf_stem[1])
			
			add_given_forms(args)
			
			conjugations_new[(data.type)](data.forms, inf_stem, stems)
			
			add_repeated_forms_new(data.forms)
			
			if dbg then
				table.insert(data.info, "new")
			end
		
			require("Module:debug").track("ro-verb/new")
		else
			add_given_forms(args)
			
			conjugations[(data.type) .. "-generic"](args[1] and (args[1] .. (args[2] or "")))
			
			add_repeated_forms()
			
			compare_conj()
			
			if dbg then
				table.insert(data.info, "old")
			end
		
			require("Module:debug").track("ro-verb/old")
		end
	end
	
	if mw.title.getCurrentTitle().nsText ~= "Template" and
	data.lemma ~= data.forms.inf[1] then
		require("Module:debug").track("ro-verb/different pagename")
	end
	
	if data.conj then
		table.insert(data.info, "[[Appendix:Romanian " .. ordinals[data.conj] .. " conjugation|" .. ordinals[data.conj] .. " conjugation]]")
	else
		table.insert(data.info, "unknown conjugation")
	end
	
	table.insert(data.info, get_type_info())
	
	add_particles()

	if args.only then
		local only_info = {}
		
		for key, name in pairs(only_modes) do
			if data.only[key] then
				table.insert(only_info, name)
				
				if key:match("^[1-3]$") then	-- person
					for i, form in ipairs(form_names) do
						-- finite form, but different person
						if not form:find(key) and form:find("[1-3]") then
							data.forms[form] = nil
						end
					end
				else							-- number
					for i, form in ipairs(form_names) do
						-- finite form, but different number
						if not form:find(key .. "$") and form:find("[1-3]") then
							data.forms[form] = nil
						end
					end
				end
			end
		end
		
		table.insert(data.info, table.concat(only_info, " ") .. " only")
	end
	
	return make_table()
end

return export