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

local lang = require("Module:languages").getByCode("gmw-pro")

local export = {}

local function degeminate(stem)
	stem = mw.ustring.gsub(stem, "uw$", "w")
	stem = mw.ustring.gsub(stem, "([bdfghklmnpstþ])%1$", "%1")
	return stem
end

local function str_degeminate(pres_stem)
	pres_stem = mw.ustring.gsub(pres_stem, "uw$", "w")
	pres_stem = mw.ustring.gsub(pres_stem, "([bdfghklmnpstþ])%1$", "%1")
	return pres_stem
end

-- Inflection functions

function export.st(frame)
	local params = {
		[1] = {default = mw.title.getCurrentTitle().nsText == "Template" and "geban" or mw.title.getCurrentTitle().subpageText},
		["class"] = {},
		["str_jpres"] = {type = "boolean"} 
	}

	local args = require("Module:parameters").process(frame:getParent().args, params)

	local data = {
		forms = {},
		info = nil,
		categories = {},
		past_p = true,
		past_ptcp = true,
	}
    
    if not args["str_jpres"] then
		pres_stem, suffix = mw.ustring.match(args[1], "^(.-)(an)$")
		rest, nucleus, coda = mw.ustring.match(pres_stem, "^(.-)([aeiouāēīōū]+)([bdfghjklmnprʀstþw]*)$")
		if suffix ~= "an" then
			error("Strong verbs must end in -an")
		end
    elseif args["str_jpres"] then
		pres_stem, suffix = mw.ustring.match(args[1], "^(.-)(i?jan)$")
	    if suffix == "jan" then
			pres_stem_i = str_degeminate(pres_stem)
			pres_stem = pres_stem .. "j"
			pres_stem_u = pres_stem
			rest, nucleus, coda = mw.ustring.match(pres_stem_i, "^(.-)([aeiouāēīōū]+)([bdfghjklmnprʀstþw]*)$")
		elseif suffix == "ijan" then
			pres_stem_i = pres_stem
			rest, nucleus, coda = mw.ustring.match(pres_stem, "^(.-)([aeiouāēīōū]+)([bdfghjklmnprʀstþw]*)$")
			pres_stem = pres_stem .. "ij"
		else
			error("J-present strong verbs must end in -jan")
		end
    end
	
	local coda_voiced = coda
	coda_voiced = mw.ustring.gsub((mw.ustring.gsub(coda_voiced, "^f$", "b")), "([jlmnrw])f$", "%1b")
	coda_voiced = mw.ustring.gsub((mw.ustring.gsub(coda_voiced, "^h$", "g")), "([jlmnrw])h$", "%1g")
	coda_voiced = mw.ustring.gsub((mw.ustring.gsub(coda_voiced, "^hw$", "gw")), "([jlmnrw])hw$", "%1gw")
	coda_voiced = mw.ustring.gsub((mw.ustring.gsub(coda_voiced, "^s$", "ʀ")), "([jlmnrw])s$", "%1ʀ")
	coda_voiced = mw.ustring.gsub((mw.ustring.gsub(coda_voiced, "^þ$", "d")), "([jlmnrw])þ$", "%1d")

	if not args["class"] then
		if nucleus == "ī" then
			args["class"] = "1"
		elseif nucleus == "eu" or nucleus == "ū" then
			args["class"] = "2"
		elseif nucleus == "i" or nucleus == "e" and mw.ustring.find(coda, "^[bdfghjklmnprʀstþw][bdfghjklmnprʀstþw]") and not mw.ustring.find(coda, "^[ghk]w$") then
			args["class"] = "3"
		elseif nucleus == "e" and mw.ustring.find(coda, "^[lmnr]$") then
			args["class"] = "4"
		elseif nucleus == "e" and (mw.ustring.find(coda, "^[bdfghkpstþ]$") or mw.ustring.find(coda, "^[ghk]w$")) then
			args["class"] = "5"
		elseif nucleus == "a" and mw.ustring.find(coda, "^[bdfghkpʀstþ]?[bdfghjklmnprʀstþw]$") then
			args["class"] = "6"
		elseif nucleus == "ai" then
			args["class"] = "7a"
		elseif nucleus == "au" then
			args["class"] = "7b"
		elseif nucleus == "a" and mw.ustring.find(coda, "^[lmnr][bdfghjklmnprʀstþw]") then
			args["class"] = "7c"
		elseif nucleus == "ā" then
			args["class"] = "7d"
		elseif nucleus == "ō" then
			args["class"] = "7e"
		else
			error("Could not determine strong verb class")
		end
	end

	if not args["str_jpres"] then
		data.info = "strong class " .. args["class"]
		table.insert(data.categories, lang:getCanonicalName() .. " " .. "class " .. args["class"] .. " strong verbs")
	elseif args["str_jpres"] then
		data.info = "strong class " .. args["class"] .. " j-present"
		table.insert(data.categories, lang:getCanonicalName() .. " " .. "class " .. args["class"] .. " strong j-present verbs")
	end
		
	local past_s_stem
	local past_p_stem
	local past_ptcp_stem

	if args["class"] == "1" then
		past_s_stem = rest .. "ai" .. coda
		past_p_stem = rest .. "i" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. "i" .. coda_voiced .. "an"}
	elseif args["class"] == "2" then
		pres_stem_i = rest .. mw.ustring.gsub(nucleus, "e", "i") .. coda
		past_s_stem = rest .. "au" .. coda
		past_p_stem = rest .. "u" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. "o" .. coda_voiced .. "an"}
	elseif args["class"] == "3" then
		pres_stem_i = rest .. mw.ustring.gsub(nucleus, "e", "i") .. coda
		past_s_stem = rest .. "a" .. coda
		past_p_stem = rest .. "u" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. (nucleus == "i" and "u" or "o") .. coda_voiced .. "an"}
	elseif args["class"] == "4" then
		pres_stem_i = rest .. mw.ustring.gsub(nucleus, "e", "i") .. coda
		past_s_stem = rest .. "a" .. coda
		past_p_stem = rest .. "ā" .. coda_voiced
		if mw.ustring.find(coda, "[mn]$") then
			data.forms["past|ptcp"] = {rest .. "u" .. coda_voiced .. "an"}
		else
			data.forms["past|ptcp"] = {rest .. "o" .. coda_voiced .. "an"}
		end
	elseif args["class"] == "5" then
		if not args["str_jpres"] then
			pres_stem_i = rest .. mw.ustring.gsub(nucleus, "e", "i") .. coda
			past_s_stem = rest .. "a" .. coda
			past_p_stem = rest .. "ā" .. coda_voiced
			data.forms["past|ptcp"] = {rest .. nucleus .. coda_voiced .. "an"}
		elseif args["str_jpres"] then
			past_s_stem = rest .. "a" .. coda
			past_p_stem = rest .. "ā" .. coda_voiced
			data.forms["past|ptcp"] = {rest .. "e" .. coda_voiced .. "an"}
		end
	elseif args["class"] == "6" then
		past_s_stem = rest .. "ō" .. coda
		past_p_stem = rest .. "ō" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. nucleus .. coda_voiced .. "an"}
	elseif args["class"] == "7a" then
		past_s_stem = rest .. "ē" .. coda
		past_p_stem = rest .. "ē" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. nucleus .. coda_voiced .. "an"}
	elseif args["class"] == "7b" then
		past_s_stem = rest .. "eō" .. coda
		past_p_stem = rest .. "eō" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. nucleus .. coda_voiced .. "an"}
	elseif args["class"] == "7c" then
		past_s_stem = rest .. "ea" .. coda
		past_p_stem = rest .. "ea" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. nucleus .. coda_voiced .. "an"}
	elseif args["class"] == "7d" then
		past_s_stem = rest .. "ē" .. coda
		past_p_stem = rest .. "ē" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. nucleus .. coda_voiced .. "an"}
	elseif args["class"] == "7e" then
		past_s_stem = rest .. "eō" .. coda
		past_p_stem = rest .. "eō" .. coda_voiced
		data.forms["past|ptcp"] = {rest .. nucleus .. coda_voiced .. "an"}
    elseif args["str_jpres"] and args["class"] == "7" then
		if coda == 'r' then
			past_s_stem = rest .. "ē" .. coda
		    past_p_stem = rest .. "ē" .. coda
		    data.forms["past|ptcp"] = {rest .. nucleus .. coda .. "an"}
  		elseif coda == 'w' then
  			past_s_stem = rest .. "eō" .. coda
		    past_p_stem = rest .. "eō" .. coda
		    data.forms["past|ptcp"] = {rest .. nucleus .. coda .. "an"}
	   	elseif coda == 'p' then
			past_s_stem = rest .. "eō" .. coda
		    past_p_stem = rest .. "eō" .. coda
		   	data.forms["past|ptcp"] = {rest .. nucleus .. coda .. "an"}
	   	end
	end
	
	pres_stem_i = pres_stem_i or pres_stem
	local pres_stem_u = mw.ustring.gsub(pres_stem, "([ghk])w$", "%1")
	local past_p_stem_u = mw.ustring.gsub(past_p_stem, "([ghk])w$", "%1")
	past_p_stem_u = mw.ustring.gsub(past_p_stem_u, "([ghk])w([ou])", "%1%2")
	
	past_p_stem = mw.ustring.gsub(past_p_stem, "([ghk])w([ou])", "%1%2")
	past_p_stem = mw.ustring.gsub(past_p_stem, "([ou]n?[kg])w", "%1")
	past_p_stem = mw.ustring.gsub(past_p_stem, "([^n])gw", "%1w")
	
	for i, stem in ipairs(data.forms["past|ptcp"]) do
		stem = mw.ustring.gsub(stem, "([ghk])w([ou])", "%1%2")
		stem = mw.ustring.gsub(stem, "([ou]n?[kg])w", "%1")
		stem = mw.ustring.gsub(stem, "([^n])gw", "%1w")
		data.forms["past|ptcp"][i] = stem
	end

	data.forms["inf"] = {pres_stem .. "an"}
	data.forms["gen|inf"] = {pres_stem .. "annjas"}
	data.forms["dat|inf"] = {pres_stem .. "annjē"}
	data.forms["ins|inf"] = {pres_stem .. "annju"}
	data.forms["pres|ptcp"] = {pres_stem .. "andī"}

	data.forms["1|s|pres|indc"] = {pres_stem_u .. "u"}
	data.forms["2|s|pres|indc"] = {pres_stem_i .. "iʀi"}
	data.forms["3|s|pres|indc"] = {pres_stem_i .. "idi"}
	data.forms["1|p|pres|indc"] = {pres_stem_u .. "um"}
	data.forms["2|p|pres|indc"] = {pres_stem_i .. "id"}
	data.forms["3|p|pres|indc"] = {pres_stem .. "and"}
	
	data.forms["1|s|pres|subj"] = {pres_stem .. "ē"}
	data.forms["2|s|pres|subj"] = {pres_stem .. "ēs"}
	data.forms["3|s|pres|subj"] = {pres_stem .. "ē"}
	data.forms["1|p|pres|subj"] = {pres_stem .. "ēm"}
	data.forms["2|p|pres|subj"] = {pres_stem .. "ēþ"}
	data.forms["3|p|pres|subj"] = {pres_stem .. "ēn"}
	
	bare_stem, bare_suffix = mw.ustring.match(pres_stem, "^(.-)(i?j)$")
	if bare_suffix == "j" then
		data.forms["s|impr"] = {pres_stem_i .. "i"}
	elseif bare_suffix == "ij" then
		data.forms["s|impr"] = {pres_stem_i .. "ī"}
	else
		data.forms["s|impr"] = {pres_stem_i}
	end
	data.forms["p|impr"] = {pres_stem_i .. "id"}

	data.forms["1|s|past|indc"] = {past_s_stem}
	data.forms["2|s|past|indc"] = {past_p_stem .. "ī"}
	data.forms["3|s|past|indc"] = {past_s_stem}
	data.forms["1|p|past|indc"] = {past_p_stem_u .. "um"}
	data.forms["2|p|past|indc"] = {past_p_stem_u .. "ud"}
	data.forms["3|p|past|indc"] = {past_p_stem_u .. "un"}

	data.forms["1|s|past|subj"] = {past_p_stem .. "ī"}
	data.forms["2|s|past|subj"] = {past_p_stem .. "ī"}
	data.forms["3|s|past|subj"] = {past_p_stem .. "ī"}
	data.forms["1|p|past|subj"] = {past_p_stem .. "īm"}
	data.forms["2|p|past|subj"] = {past_p_stem .. "īd"}
	data.forms["3|p|past|subj"] = {past_p_stem .. "īn"}

	return make_table(data)
end

function export.wk1(frame)
	local params = {
		[1] = {default = mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}jan" or mw.title.getCurrentTitle().subpageText},
		["jpres"] = {type = "boolean"}
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)

	local data = {
		forms = {},
		info = "class 1 weak",
		categories = {lang:getCanonicalName() .. " class 1 weak verbs"},
	}

	if args["jpres"] then
		data.info = data.info .. " j-present"
		table.insert(data.categories, lang:getCanonicalName() .. " class 1 weak j-present verbs")
	end

	local stem, suffix = mw.ustring.match(args[1], "^(.-)(i?jan)$")
	local stem_i
	local stem_past

	if suffix == "jan" then
		stem_i = degeminate(stem)

		if mw.ustring.find(stem, "[dt]$")  then
			stem_past = stem
		elseif mw.ustring.find(stem, "l$")  then
			stem_past = stem_i .. "d"
		end

		stem = stem .. "j"
	elseif suffix == "ijan" then
		stem_i = stem
		stem = stem .. "ij"
	else
		error("Class 1 weak verbs must end in -jan")
	end

	if args["jpres"] then
		stem_past = stem_i
		stem_past = mw.ustring.gsub(stem_past, "[gk]$", "h") .. "t"
		stem_past = mw.ustring.toNFC(mw.ustring.gsub(stem_past, "([aiu])nh([^aeiouāēīōū]+)$", "%1" .. mw.ustring.char(0x0304) .. mw.ustring.char(0x0328) .. "h%2"))
		stem_past = mw.ustring.gsub(stem_past, "u([^aeiouāēīōū]+)$", "o%1")
	end

	stem_past = stem_past or stem_i .. "id"

	data.forms["inf"] = {stem .. "an"}
	data.forms["gen|inf"] = {stem .. "annjas"}
	data.forms["dat|inf"] = {stem .. "annjē"}
	data.forms["ins|inf"] = {stem .. "annju"}
	data.forms["pres|ptcp"] = {stem .. "andī"}

	data.forms["1|s|pres|indc"] = {stem .. "u"}
	data.forms["2|s|pres|indc"] = {stem_i .. "isi"}
	data.forms["3|s|pres|indc"] = {stem_i .. "iþi"}
	data.forms["1|p|pres|indc"] = {stem .. "um"}
	data.forms["2|p|pres|indc"] = {stem_i .. "iþ"}
	data.forms["3|p|pres|indc"] = {stem .. "anþ"}
	
	data.forms["1|s|pres|subj"] = {stem .. "ē"}
	data.forms["2|s|pres|subj"] = {stem .. "ēs"}
	data.forms["3|s|pres|subj"] = {stem .. "ē"}
	data.forms["1|p|pres|subj"] = {stem .. "ēm"}
	data.forms["2|p|pres|subj"] = {stem .. "ēþ"}
	data.forms["3|p|pres|subj"] = {stem .. "ēn"}
	
	data.forms["s|impr"] = {stem_i .. "i"}
	data.forms["p|impr"] = {stem_i .. "iþ"}

	data.forms["1|s|past|indc"] = {stem_past .. "ā"}
	data.forms["2|s|past|indc"] = {stem_past .. "ēs", stem_past .. "ōs"}
	data.forms["3|s|past|indc"] = {stem_past .. "ē", stem_past .. "ā"}
	data.forms["1|p|past|indc"] = {stem_past .. "um"}
	data.forms["2|p|past|indc"] = {stem_past .. "ud"}
	data.forms["3|p|past|indc"] = {stem_past .. "un"}

	data.forms["1|s|past|subj"] = {stem_past .. "ī"}
	data.forms["2|s|past|subj"] = {stem_past .. "ī"}
	data.forms["3|s|past|subj"] = {stem_past .. "ī"}
	data.forms["1|p|past|subj"] = {stem_past .. "īm"}
	data.forms["2|p|past|subj"] = {stem_past .. "īd"}
	data.forms["3|p|past|subj"] = {stem_past .. "īn"}
	
	data.forms["past|ptcp"] = {stem_past}

	return make_table(data)
end

function export.wk2(frame)
	local params = {
		[1] = {default = mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}ōn" or mw.title.getCurrentTitle().subpageText},
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)

	local data = {
		forms = {},
		info = "class 2 weak",
		categories = {lang:getCanonicalName() .. " class 2 weak verbs"},
	}

	local stem, suffix = mw.ustring.match(args[1], "^(.-)(ōn)$")

	if suffix ~= "ōn" then
		error("Class 2 weak verbs must end in -ōn")
	end

	data.forms["inf"] = {stem .. "ōn"}
	data.forms["gen|inf"] = {stem .. "ōnijas"}
	data.forms["dat|inf"] = {stem .. "ōnijē"}
	data.forms["ins|inf"] = {stem .. "ōniju"}
	data.forms["pres|ptcp"] = {stem .. "ōndī"}

	data.forms["1|s|pres|indc"] = {stem .. "ō"}
	data.forms["2|s|pres|indc"] = {stem .. "ōs"}
	data.forms["3|s|pres|indc"] = {stem .. "ōþ"}
	data.forms["1|p|pres|indc"] = {stem .. "ōm"}
	data.forms["2|p|pres|indc"] = {stem .. "ōþ"}
	data.forms["3|p|pres|indc"] = {stem .. "ōnþ"}
	
	data.forms["1|s|pres|subj"] = {stem .. "ō"}
	data.forms["2|s|pres|subj"] = {stem .. "ōs"}
	data.forms["3|s|pres|subj"] = {stem .. "ō"}
	data.forms["1|p|pres|subj"] = {stem .. "ōm"}
	data.forms["2|p|pres|subj"] = {stem .. "ōþ"}
	data.forms["3|p|pres|subj"] = {stem .. "ōn"}
	
	data.forms["s|impr"] = {stem .. "ō"}
	data.forms["p|impr"] = {stem .. "ōþ"}

	data.forms["1|s|past|indc"] = {stem .. "ōdā"}
	data.forms["2|s|past|indc"] = {stem .. "ōdēs", stem .. "ōdōs"}
	data.forms["3|s|past|indc"] = {stem .. "ōdē", stem .. "ōdā"}
	data.forms["1|p|past|indc"] = {stem .. "ōdum"}
	data.forms["2|p|past|indc"] = {stem .. "ōdud"}
	data.forms["3|p|past|indc"] = {stem .. "ōdun"}

	data.forms["1|s|past|subj"] = {stem .. "ōdī"}
	data.forms["2|s|past|subj"] = {stem .. "ōdī"}
	data.forms["3|s|past|subj"] = {stem .. "ōdī"}
	data.forms["1|p|past|subj"] = {stem .. "ōdīm"}
	data.forms["2|p|past|subj"] = {stem .. "ōdīd"}
	data.forms["3|p|past|subj"] = {stem .. "ōdīn"}
	
	data.forms["past|ptcp"] = {stem .. "ōd"}

	return make_table(data)
end

function export.wk3(frame)
	local params = {
		[1] = {default = mw.title.getCurrentTitle().nsText == "Template" and "{{{1}}}ēn" or mw.title.getCurrentTitle().subpageText},
	}
	
	local args = require("Module:parameters").process(frame:getParent().args, params)

	local data = {
		forms = {},
		info = "class 3 weak",
		categories = {lang:getCanonicalName() .. " class 3 weak verbs"},
	}

	local stem, suffix = mw.ustring.match(args[1], "^(.-)(ēn)$")
	
	if not stem then
		stem, suffix = mw.ustring.match(args[1], "^(.-)(jan)$")
	end
	
	if suffix == "jan" then
		data.info = data.info .. " j-present"
		table.insert(data.categories, lang:getCanonicalName() .. " class 3 weak j-present verbs")
        
		local stem_i = degeminate(stem)
        local stem_i_o = mw.ustring.gsub(stem_i , "u([^aeiouāēīōū]+)$", "o%1")
		stem = stem .. "j"
		
		data.forms["inf"] = {stem .. "an"}
		data.forms["gen|inf"] = {stem .. "annjas"}
		data.forms["dat|inf"] = {stem .. "annjē"}
		data.forms["ins|inf"] = {stem .. "annju"}
		data.forms["pres|ptcp"] = {stem .. "andī"}
	
		data.forms["1|s|pres|indc"] = {stem .. "u"}
		data.forms["2|s|pres|indc"] = {stem_i_o .. "ēs"}
		data.forms["3|s|pres|indc"] = {stem_i_o .. "ēþ"}
		data.forms["1|p|pres|indc"] = {stem .. "um"}
		data.forms["2|p|pres|indc"] = {stem_i_o .. "ēþ"}
		data.forms["3|p|pres|indc"] = {stem .. "anþ"}
		
		data.forms["1|s|pres|subj"] = {stem .. "ē"}
		data.forms["2|s|pres|subj"] = {stem .. "ēs"}
		data.forms["3|s|pres|subj"] = {stem .. "ē"}
		data.forms["1|p|pres|subj"] = {stem .. "ēm"}
		data.forms["2|p|pres|subj"] = {stem .. "ēþ"}
		data.forms["3|p|pres|subj"] = {stem .. "ēn"}
		
		data.forms["s|impr"] = {stem_i_o .. "ē"}
		data.forms["p|impr"] = {stem_i_o .. "ēþ"}
	
		data.forms["1|s|past|indc"] = {stem_i_o .. "dā"}
		data.forms["2|s|past|indc"] = {stem_i_o .. "dēs", stem_i_o .. "dōs"}
		data.forms["3|s|past|indc"] = {stem_i_o .. "dē", stem_i_o .. "dā"}
		data.forms["1|p|past|indc"] = {stem_i .. "dum"}
		data.forms["2|p|past|indc"] = {stem_i .. "dud"}
		data.forms["3|p|past|indc"] = {stem_i .. "dun"}
	
		data.forms["1|s|past|subj"] = {stem_i .. "dī"}
		data.forms["2|s|past|subj"] = {stem_i .. "dī"}
		data.forms["3|s|past|subj"] = {stem_i .. "dī"}
		data.forms["1|p|past|subj"] = {stem_i .. "dīm"}
		data.forms["2|p|past|subj"] = {stem_i .. "dīd"}
		data.forms["3|p|past|subj"] = {stem_i .. "dīn"}
		
		data.forms["past|ptcp"] = {stem_i_o .. "d"}
	elseif suffix == "ēn" then
		data.forms["inf"] = {stem .. "ēn"}
		data.forms["gen|inf"] = {stem .. "ēnijas"}
		data.forms["dat|inf"] = {stem .. "ēnijē"}
		data.forms["ins|inf"] = {stem .. "ēniju"}
		data.forms["pres|ptcp"] = {stem .. "ēndī"}
	
		data.forms["1|s|pres|indc"] = {stem .. "ē"}
		data.forms["2|s|pres|indc"] = {stem .. "ēs"}
		data.forms["3|s|pres|indc"] = {stem .. "ēþ"}
		data.forms["1|p|pres|indc"] = {stem .. "ēm"}
		data.forms["2|p|pres|indc"] = {stem .. "ēþ"}
		data.forms["3|p|pres|indc"] = {stem .. "ēnþ"}
		
		data.forms["1|s|pres|subj"] = {stem .. "ē"}
		data.forms["2|s|pres|subj"] = {stem .. "ēs"}
		data.forms["3|s|pres|subj"] = {stem .. "ē"}
		data.forms["1|p|pres|subj"] = {stem .. "ēm"}
		data.forms["2|p|pres|subj"] = {stem .. "ēþ"}
		data.forms["3|p|pres|subj"] = {stem .. "ēn"}
		
		data.forms["s|impr"] = {stem .. "ē"}
		data.forms["p|impr"] = {stem .. "ēþ"}
	
		data.forms["1|s|past|indc"] = {stem .. "?dā"}
		data.forms["2|s|past|indc"] = {stem .. "?dēs", stem .. "?dēs"}
		data.forms["3|s|past|indc"] = {stem .. "?dē", stem .. "?dā"}
		data.forms["1|p|past|indc"] = {stem .. "?dum"}
		data.forms["2|p|past|indc"] = {stem .. "?dud"}
		data.forms["3|p|past|indc"] = {stem .. "?dun"}
	
		data.forms["1|s|past|subj"] = {stem .. "?dī"}
		data.forms["2|s|past|subj"] = {stem .. "?dī"}
		data.forms["3|s|past|subj"] = {stem .. "?dī"}
		data.forms["1|p|past|subj"] = {stem .. "?dīm"}
		data.forms["2|p|past|subj"] = {stem .. "?dīd"}
		data.forms["3|p|past|subj"] = {stem .. "?dīn"}
		
		data.forms["past|ptcp"] = {stem .. "?d"}
	else
		error("Class 3 weak verbs must end in -ēn or -jan")
	end

	return make_table(data)
end

-- Make the table
function make_table(data)
	local function repl(param)
		if param == "info" then
			return mw.getContentLanguage():ucfirst(data.info or "")
		end
		
		local forms = data.forms[param]
		
		if not forms then
			return "—"
		end
		
		local ret = {}
		
		for key, subform in ipairs(forms) do
			table.insert(ret, require("Module:links").full_link({lang = lang, alt = "*" .. subform}))
		end
		
		return table.concat(ret, ", ")
	end
	
	local wikicode = {}
	table.insert(wikicode, [=[
{| class="inflection-table vsSwitcher" data-toggle-category="inflection" style="border: solid 1px #CCCCCC;"
|- style="background: #CCCCCC; text-align: left;"
! class="vsToggleElement" colspan="3" | {{{info}}}
|- class="vsShow"
! style="min-width: 9em; background: #EEEEEE" | Infinitive
| style="min-width: 15em;" colspan="2" | {{{inf}}}
|- class="vsShow"
! style="background: #EEEEEE" | 1st sg. past
| colspan="2" | {{{1|s|past|indc}}}]=])

	if data.past_p then
		table.insert(wikicode, [=[
|- class="vsShow"
! style="background: #EEEEEE" | 3rd pl. past
| colspan="2" | {{{3|p|past|indc}}}]=])
	end

	if data.past_ptcp then
		table.insert(wikicode, [=[
|- class="vsShow"
! style="background: #EEEEEE" | Past ptcple
| colspan="2" | {{{past|ptcp}}}]=])
	end

	table.insert(wikicode, [=[
|- class="vsHide"
! style="background: #EEEEEE" | Infinitive
| colspan="2" | {{{inf}}}
|- class="vsHide"
! style="background: #EEEEEE" | Genitive infin.
| colspan="2" | {{{gen|inf}}}
|- class="vsHide"
! style="background: #EEEEEE" | Dative infin.
| colspan="2" | {{{dat|inf}}}
|- class="vsHide"
! style="background: #EEEEEE" | Instrum. infin.
| colspan="2" | {{{ins|inf}}}
|- class="vsHide"
! style="min-width: 9em; background: #DDDDDD;" | Indicative
! style="min-width: 15em; background: #DDDDDD;" | Present
! style="min-width: 15em; background: #DDDDDD;" | Past
|- class="vsHide"
! style="background: #EEEEEE" | 1st singular
| {{{1|s|pres|indc}}}
| {{{1|s|past|indc}}}
|- class="vsHide"
! style="background: #EEEEEE" | 2nd singular
| {{{2|s|pres|indc}}}
| {{{2|s|past|indc}}}
|- class="vsHide"
! style="background: #EEEEEE" | 3rd singular
| {{{3|s|pres|indc}}}
| {{{3|s|past|indc}}}
|- class="vsHide"
! style="background: #EEEEEE" | 1st plural
| {{{1|p|pres|indc}}}
| {{{1|p|past|indc}}}
|- class="vsHide"
! style="background: #EEEEEE" | 2nd plural
| {{{2|p|pres|indc}}}
| {{{2|p|past|indc}}}
|- class="vsHide"
! style="background: #EEEEEE" | 3rd plural
| {{{3|p|pres|indc}}}
| {{{3|p|past|indc}}}
|- class="vsHide"
! style="background: #DDDDDD;" | Subjunctive
! style="background: #DDDDDD;" | Present
! style="background: #DDDDDD;" | Past
|- class="vsHide"
! style="background: #EEEEEE" | 1st singular
| {{{1|s|pres|subj}}}
| {{{1|s|past|subj}}}
|- class="vsHide"
! style="background: #EEEEEE" | 2nd singular
| {{{2|s|pres|subj}}}
| {{{2|s|past|subj}}}
|- class="vsHide"
! style="background: #EEEEEE" | 3rd singular
| {{{3|s|pres|subj}}}
| {{{3|s|past|subj}}}
|- class="vsHide"
! style="background: #EEEEEE" | 1st plural
| {{{1|p|pres|subj}}}
| {{{1|p|past|subj}}}
|- class="vsHide"
! style="background: #EEEEEE" | 2nd plural
| {{{2|p|pres|subj}}}
| {{{2|p|past|subj}}}
|- class="vsHide"
! style="background: #EEEEEE" | 3rd plural
| {{{3|p|pres|subj}}}
| {{{3|p|past|subj}}}
|- class="vsHide"
! style="background: #DDDDDD;" | Imperative
! style="background: #DDDDDD;" | Present
| rowspan="3" |
|- class="vsHide"
! style="background: #EEEEEE" | Singular
| {{{s|impr}}}
|- class="vsHide"
! style="background: #EEEEEE" | Plural
| {{{p|impr}}}
|- class="vsHide"
! style="background: #DDDDDD;" |
! style="background: #DDDDDD;" | Present
! style="background: #DDDDDD;" | Past
|- class="vsHide"
! style="background: #EEEEEE" | Participle
| ]=] .. require("Module:links").full_link({lang = lang, term = "*" .. table.concat(data.forms["pres|ptcp"])}) .. [=[

| ]=] .. require("Module:links").full_link({lang = lang, term = "*" .. table.concat(data.forms["past|ptcp"])}) .. [=[

|}]=])

	return mw.ustring.gsub(table.concat(wikicode, "\n"), "{{{([#!]?[a-z0-9|]+)}}}", repl) .. require("Module:utilities").format_categories(data.categories, lang)
end

return export