A modult a Modul:ar-verb2/doc lapon tudod dokumentálni

local m_headword = require("Module:headword")
local m_utilities = require("Module:utilities")
local m_links = require("Module:links")
local ar_translit = require("Module:ar-translit")
local ar_utilities = require("Module:ar-utilities")
local ar_nominals = require("Module:ar-nominals")

local lang = require("Module:languages").getByCode("ar")
local curtitle = mw.title.getCurrentTitle().fullText
local yesno = require("Module:yesno")

local rfind = mw.ustring.find
local rsubn = mw.ustring.gsub
local rmatch = mw.ustring.match
local rsplit = mw.text.split
local usub = mw.ustring.sub
local ulen = mw.ustring.len
local u = mw.ustring.char


local no_nominal_i3rab = true

local export = {}




local conjugations = {}

local HAMZA            = u(0x0621) 
local HAMZA_ON_ALIF    = u(0x0623)
local HAMZA_ON_W       = u(0x0624)
local HAMZA_UNDER_ALIF = u(0x0625)
local HAMZA_ON_Y       = u(0x0626)
local HAMZA_ANY        = "[" .. HAMZA .. HAMZA_ON_ALIF .. HAMZA_UNDER_ALIF .. HAMZA_ON_W .. HAMZA_ON_Y .. "]"
local HAMZA_PH         = u(0xFFF0) 


local A  = u(0x064E) 
local AN = u(0x064B) 
local U  = u(0x064F) 
local UN = u(0x064C) 
local I  = u(0x0650) 
local IN = u(0x064D) 
local SK = u(0x0652) 
local SH = u(0x0651) 
local DAGGER_ALIF = u(0x0670)
local DIACRITIC_ANY_BUT_SH = "[" .. A .. I .. U .. AN .. IN .. UN .. SK .. DAGGER_ALIF .. "]"

local AIU = "[" .. A .. I .. U .. "]"

local AIUSK = "[" .. A .. I .. U .. SK .. "]"

local DIACRITIC = SH .. "?" .. DIACRITIC_ANY_BUT_SH

local UNS = no_nominal_i3rab and "" or UN

local dia = {a = A, i = I, u = U}


local ALIF   = u(0x0627) 
local AMAQ   = u(0x0649) 
local AMAD   = u(0x0622) 
local TAM    = u(0x0629) 
local T      = u(0x062A) 
local HYPHEN = u(0x0640)
local N      = u(0x0646) 
local W      = u(0x0648) 
local Y      = u(0x064A) 
local S      = "س"
local M      = "م"
local LRM    = u(0x200e) 


local AH    = A .. TAM
local AT    = A .. T
local AA    = A .. ALIF
local AAMAQ = A .. AMAQ
local AAH   = AA .. TAM
local AAT   = AA .. T
local II    = I .. Y
local IY    = II
local UU    = U .. W
local AY    = A .. Y
local AW    = A .. W
local AYSK  = AY .. SK
local AWSK  = AW .. SK
local NA    = N .. A
local NI    = N .. I
local AAN   = AA .. N
local AANI  = AA .. NI
local AYNI  = AYSK .. NI
local AWNA  = AWSK .. NA
local AYNA  = AYSK .. NA
local AYAAT = AY .. AAT
local UNU   = "[" .. UN .. U .. "]"
local MA    = M .. A
local MU    = M .. U







local function ine(x)
	if x == nil then
		return nil
	elseif rfind(x, '^".*"$') then
		local ret = rmatch(x, '^"(.*)"$')
		return ret
	elseif rfind(x, "^'.*'$") then
		local ret = rmatch(x, "^'(.*)'$")
		return ret
	elseif x == "" then
		return nil
	else
		return x
	end
end


local function contains(tab, item)
	for _, value in pairs(tab) do
		if value == item then
			return true
		end
	end
	return false
end


local function append_array(tab, items)
	for _, item in ipairs(items) do
		table.insert(tab, item)
	end
end


local function insert_if_not(tab, item)
	if not contains(tab, item) then
		table.insert(tab, item)
	end
end


function rsub(term, foo, bar)
	local retval = rsubn(term, foo, bar)
	return retval
end

local function links(text, face, id)
	if text == "" or text == "?" or text == "—" or text == "—" then 
		return text
	else
		return m_links.full_link({lang = lang, term = text, tr = "-", id = id}, face)
	end
end

local function tag_text(text, tag, class)
	return m_links.full_link({lang = lang, alt = text, tr = "-"})
end

function track(page)
	require("Module:debug").track("ar-verb/" .. page)
	return true
end

function reorder_shadda(word)
	
	
	
	
	word = rsub(word, "(" .. DIACRITIC_ANY_BUT_SH .. ")" .. SH, SH .. "%1")
	return word
end



function debug_frame(parargs, args)
	return {args = args, getParent = function() return {args = parargs} end}
end


















local allowed_forms = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX",
	"X", "XI", "XII", "XIII", "XIV", "XV", "Iq", "IIq", "IIIq", "IVq"}

local function form_supports_final_weak(form)
	return form ~= "XI" and form ~= "XV" and form ~= "IVq"
end

local function form_supports_geminate(form)
	return form == "I" or form == "III" or form == "IV" or
		form == "VI" or form == "VII" or form == "VIII" or form == "X"
end

local function form_supports_hollow(form)
	return form == "I" or form == "IV" or form == "VII" or form == "VIII" or
		form == "X"
end

local function form_probably_impersonal_passive(form)
	return form == "VI"
end

local function form_probably_no_passive(form, weakness, past_vowel, nonpast_vowel)
	return form == "I" and weakness ~= "lyukas" and contains(past_vowel, "u") or
		form == "VII" or form == "IX" or form == "XI" or form == "XII" or
		form == "XIII" or form == "XIV" or form == "XV" or form == "IIq" or
		form == "IIIq" or form == "IVq"
end

local function form_is_quadriliteral(form)
	return form == "Iq" or form == "IIq" or form == "IIIq" or form == "IVq"
end


function prefix_vowel_from_form(form)
	if form == "II" or form == "III" or form == "IV" or form == "Iq" then
		return "u"
	else
		return "a"
	end
end



function form_nonpast_a_vowel(form)
	return form == "V" or form == "VI" or form == "XV" or form == "IIq"
end






local function axadh_radicals(rad1, rad2, rad3)
	return rad1 == HAMZA and rad2 == "خ" and rad3 == "ذ"
end


local function reduced_imperative_verb(rad1, rad2, rad3)
	return axadh_radicals(rad1, rad2, rad3) or rad1 == HAMZA and (
		rad2 == "ك" and rad3 == "ل" or
		rad2 == "م" and rad3 == "ر")
end


local function raa_radicals(rad1, rad2, rad3)
	return rad1 == "ر" and rad2 == HAMZA and rad3 == Y
end


local function saal_radicals(rad1, rad2, rad3)
	return rad1 == "س" and rad2 == HAMZA and rad3 == "ل"
end


local function hayy_radicals(rad1, rad2, rad3)
	return rad1 == "ح" and rad2 == Y and rad3 == Y
end






local past_endings = {
	
	SK .. "تُ", SK .. "تَ", SK .. "تِ", A, A .. "تْ",
	
	SK .. "تُمَا", AA, A .. "تَا",
	
	SK .. "نَا", SK .. "تُمْ",
	
	
	SK .. "تُن" .. SH .. A, UU .. ALIF, SK .. "نَ"
}



local function make_past_endings_ay_aw(ayaw, third_sg_masc)
	return {
	
	ayaw .. SK .. "تُ", ayaw ..  SK .. "تَ", ayaw .. SK .. "تِ",
	third_sg_masc, A .. "تْ",
	
	ayaw .. SK .. "تُمَا", ayaw .. AA, A .. "تَا",
	
	ayaw .. SK .. "نَا", ayaw .. SK .. "تُمْ",
	
	
	ayaw .. SK .. "تُن" .. SH .. A, AW .. SK .. ALIF, ayaw .. SK .. "نَ"
	}
end


local past_endings_ay = make_past_endings_ay_aw(AY, AAMAQ)

local past_endings_aw = make_past_endings_ay_aw(AW, AA)



local function make_past_endings_ii_uu(iiuu)
	return {
	
	iiuu .. "تُ", iiuu .. "تَ", iiuu .. "تِ", iiuu .. A, iiuu .. A .. "تْ",
	
	iiuu .. "تُمَا", iiuu .. AA, iiuu .. A .. "تَا",
	
	iiuu .. "نَا", iiuu .. "تُمْ",
	
	
	iiuu .. "تُن" .. SH .. A, UU .. ALIF, iiuu .. "نَ"
	}
end


local past_endings_ii = make_past_endings_ii_uu(II)

local past_endings_uu = make_past_endings_ii_uu(UU)






local nonpast_prefixes_a = {
	
	HAMZA .. A, "تَ", "تَ", "يَ", "تَ",
	
	"تَ", "يَ", "تَ",
	
	"نَ", "تَ", "تَ", "يَ", "يَ"
}


local nonpast_prefixes_u = {
	
	HAMZA .. U, "تُ", "تُ", "يُ", "تُ",
	
	"تُ", "يُ", "تُ",
	
	"نُ", "تُ", "تُ", "يُ", "يُ"
}



local function make_nonpast_endings(null, fem, dual, pl, fempl)
	return {
	
	null, null, fem, null, null,
	
	dual, dual, dual,
	
	null, pl, fempl, pl, fempl
	}
end


local indic_endings = make_nonpast_endings(
	U,
	II .. NA,
	AANI,
	UU .. NA,
	SK .. NA
)



local function make_subj_juss_endings(dia_null)
	return make_nonpast_endings(
	dia_null,
	II,
	AA,
	UU .. ALIF,
	SK .. NA
	)
end


local subj_endings = make_subj_juss_endings(A)


local juss_endings = make_subj_juss_endings(SK)


local juss_endings_alt_a = subj_endings


local juss_endings_alt_i = make_subj_juss_endings(I)



local indic_endings_aa = make_nonpast_endings(
	AAMAQ,
	AYSK .. NA,
	AY .. AANI,
	AWSK .. NA,
	AYSK .. NA
)



local function make_indic_endings_ii_uu(iiuu)
	return make_nonpast_endings(
	iiuu,
	II .. NA,
	iiuu .. AANI,
	UU .. NA,
	iiuu .. NA
	)
end


local indic_endings_ii = make_indic_endings_ii_uu(II)


local indic_endings_uu = make_indic_endings_ii_uu(UU)



local subj_endings_aa = make_nonpast_endings(
	AAMAQ,
	AYSK,
	AY .. AA,
	AWSK .. ALIF,
	AYSK .. NA
)



local function make_subj_endings_ii_uu(iiuu)
	return make_nonpast_endings(
	iiuu .. A,
	II,
	iiuu .. AA,
	UU .. ALIF,
	iiuu .. NA
	)
end


local subj_endings_ii = make_subj_endings_ii_uu(II)


local subj_endings_uu = make_subj_endings_ii_uu(UU)


local juss_endings_aa = make_nonpast_endings(
	A,
	AYSK,
	AY .. AA,
	AWSK .. ALIF,
	AYSK .. NA
)




local function make_juss_endings_ii_uu(iu, iiuu)
	return make_nonpast_endings(
	iu,
	II,
	iiuu .. AA,
	UU .. ALIF,
	iiuu .. NA
	)
end


local juss_endings_ii = make_juss_endings_ii_uu(I, II)


local juss_endings_uu = make_juss_endings_ii_uu(U, UU)







local function imperative_endings_from_jussive(endings)
	return {endings[2], endings[3], endings[6], endings[10], endings[11]}
end


local impr_endings = imperative_endings_from_jussive(juss_endings)

local impr_endings_alt_a = imperative_endings_from_jussive(juss_endings_alt_a)

local impr_endings_alt_i = imperative_endings_from_jussive(juss_endings_alt_i)

local impr_endings_aa = imperative_endings_from_jussive(juss_endings_aa)

local impr_endings_ii = imperative_endings_from_jussive(juss_endings_ii)

local impr_endings_uu = imperative_endings_from_jussive(juss_endings_uu)





function get_args(args)
	local origargs = args
	local args = {}
	
	for k, v in pairs(origargs) do
		args[k] = ine(v)
	end
	return origargs, args
end

function get_frame_args(frame)
	return get_args(frame:getParent().args)
end


function export.show(frame)
	local origargs, args = get_frame_args(frame)

	local data, form, weakness, past_vowel, nonpast_vowel = conjugate(args, 1)

	
	
	
	
	local intrans = args["intrans"]
	if not intrans then
		intrans = data.passive == false or data.passive == "impers" or data.passive == "only-impers"
	else
		intrans = yesno(intrans, "unknown")
		if intrans == "unknown" then
			error("Unrecognized value '" .. args["intrans"] ..
				"' to argument intrans=; use 'yes'/'y'/'true'/'1' or 'no'/'n'/'false'/'0'")
		end
	end
	if intrans then
		table.insert(data.categories, "arab tárgyatlan igék")
	else
		table.insert(data.categories, "arab tárgyas igék")
	end

	
	
	local title = form .. " igetörzs " .. weakness

	if data.passive == "only" or data.passive == "only-impers" then
		title = title .. " passziv"
	end

	if data.irregular then
		table.insert(data.categories, "arab rendhagyó igék")
		title = title .. " rendhagyó"
	end

	return make_table(data, title, form, intrans) ..
		m_utilities.format_categories(data.categories, lang)
end
















function export.show2(parargs, args)
	return export.show(debug_frame(parargs, args))
end



function export.headword(frame)
	local origargs, args = get_frame_args(frame)

	local data, form, weakness, past_vowel, nonpast_vowel = conjugate(args, 1)
	local use_params = form == "I" or args["useparam"]

	local arabic_3sm_perf, latin_3sm_perf
	local arabic_3sm_imperf, latin_3sm_imperf
	if data.passive == "only" or data.passive == "only-impers" then
		arabic_3sm_perf, latin_3sm_perf = get_spans(data.forms["3sm-ps-perf"])
		arabic_3sm_imperf, latin_3sm_imperf = get_spans(data.forms["3sm-ps-impf"])
	else
		arabic_3sm_perf, latin_3sm_perf = get_spans(data.forms["3sm-perf"])
		arabic_3sm_imperf, latin_3sm_imperf = get_spans(data.forms["3sm-impf"])
	end
	
	title = mw.title.getCurrentTitle()
	NAMESPACE = title.nsText
	PAGENAME = ( NAMESPACE == "Appendix" and title.subpageText ) or title.text
	
	
	local head, tr
	if use_params and form ~= "I" then
		
	end
	if use_params and args["head"] then
		head = {args["head"], args["head2"], args["head3"]}
		tr = {args["tr"], args["tr2"], args["tr3"]}
		if form == "I" then
			
		end
	elseif use_params and args["tr"] then
		head = PAGENAME
		tr = args["tr"]
		if form == "I" then
			
		end
	elseif form == "I" and #past_vowel == 0 then
		head = PAGENAME
		
	else
		
		
		
		headrev = {}
		for _, ar in ipairs(arabic_3sm_perf) do
			table.insert(headrev, 1, ar)
		end
		head = table.concat(headrev, " <small style=\"color: #888\">or</small> ")
		tr = table.concat(latin_3sm_perf, " <small style=\"color: #888\">or</small> ")
	end

	local form_text = ' <span class="gender">[[Függelék:Arab igék#Form ' .. form .. '|<abbr title="Verb form ' ..
	  form .. '">' .. form .. '</abbr>]]</span>'

	local impf_arabic, impf_tr
	if use_params and args["impf"] then
		impf_arabic = args["impfhead"] or args["impf"]
		impf_tr = args["impftr"] or ar_translit.tr(impf_arabic, nil, nil, nil)
		impf_arabic = {impf_arabic}
		if form == "I" then
			
		end
	elseif form == "I" and #nonpast_vowel == 0 then
		impf_arabic = {}
		
	else
		impf_arabic = arabic_3sm_imperf
		impf_tr = table.concat(latin_3sm_imperf, " <small style=\"color: #888\">or</small> ")
	end

	
	for i, entry in ipairs(impf_arabic) do
		impf_arabic[i] = links(entry, "bold")
	end
	
	
	
	local impf_text = ""
	if #impf_arabic > 0 then
		impf_text = ', <i>folyamatos</i> ' .. table.concat(impf_arabic, " <small style=\"color: #888\">or</small> ")
		if impf_tr then
			impf_text = impf_text .. LRM .. " (" .. impf_tr .. ")"
		end
	end

	return
		m_headword.full_headword({lang = lang, pos_category = "igék", categories = {}, heads = head, translits = tr, sort_key = args["sort"]}) ..
		form_text .. impf_text ..
		m_utilities.format_categories(data.headword_categories, lang)
end



function export.headword2(parargs, args)
	return export.headword(debug_frame(parargs, args))
end


function past3sm(frameargs, doall)
	local origargs, args = get_args(frameargs)

	local data, form, weakness, past_vowel, nonpast_vowel =	conjugate(args, 1)

	local arabic_3sm_perf, latin_3sm_perf
	if data.passive == "only" or data.passive == "only-impers" then
		arabic_3sm_perf, latin_3sm_perf = get_spans(data.forms["3sm-ps-perf"])
	else
		arabic_3sm_perf, latin_3sm_perf = get_spans(data.forms["3sm-perf"])
	end

	if doall then
		return table.concat(arabic_3sm_perf, ",")
	else
		return arabic_3sm_perf[1]
	end
end











function export.past3sm(frame)
	return past3sm(frame:getParent().args, false)
end



function export.past3sm2(parargs, args)
	return export.past3sm(debug_frame(parargs, args))
end





function export.past3sm_all(frame)
	return past3sm(frame:getParent().args, true)
end



function export.past3sm_all2(parargs, args)
	return export.past3sm_all(debug_frame(parargs, args))
end


function get_root(frameargs)
	local origargs, args = get_args(frameargs)
	local lemm = args[2]
	local form = args[1]
	local www, rr1, rr2, rr3 = 	export.infer_radicals(lemm, form)
	local root = rr1 .. rr2 .. rr3
		return root
end






function export.get_root(frame)
	return get_root(frame:getParent().args)
end



function export.verb_part2(parargs, args)
	return export.verb_part(debug_frame(parargs, args))
end






function export.verb_part_all(frame)
	return verb_part(frame:getParent().args, true)
end



function export.verb_part_all2(parargs, args)
	return export.verb_part_all(debug_frame(parargs, args))
end


function verb_prop(frameargs)
	local origargs, args = get_args(frameargs)

	local prop = args[1]
	local data, form, weakness, past_vowel, nonpast_vowel = conjugate(args, 2)
	if prop == "form" then
		return form
	elseif prop == "weakness" then
		return weakness
	elseif prop == "form-weakness" then
		return form .. "-" .. weakness
	elseif prop == "past-vowel" then
		return table.concat(past_vowel, ",")
	elseif prop == "nonpast-vowel" then
		return table.concat(nonpast_vowel, ",")
	elseif prop == "rad1" then
		return data.rad1 or ""
	elseif prop == "rad2" then
		return data.rad2 or ""
	elseif prop == "rad3" then
		return data.rad3 or ""
	elseif prop == "rad4" then
		return data.rad4 or ""
	elseif prop == "unreg-rad1" then
		return data.unreg_rad1 or ""
	elseif prop == "unreg-rad2" then
		return data.unreg_rad2 or ""
	elseif prop == "unreg-rad3" then
		return data.unreg_rad3 or ""
	elseif prop == "unreg-rad4" then
		return data.unreg_rad4 or ""
	elseif prop == "radicals" then
		return table.concat({data.rad1, data.rad2, data.rad3, data.rad4}, ",")
	elseif prop == "unreg-radicals" then
		return table.concat({data.unreg_rad1, data.unreg_rad2,
		data.unreg_rad3, data.unreg_rad4}, ",")
	elseif prop == "passive" then
		return data.passive == true and "yes" or not data.passive and "no"
			or data.passive
	elseif prop == "passive-uncertain" then
		return data.passive_uncertain and "yes" or "no"
	elseif prop == "vn-uncertain" then
		return data.vn_uncertain and "yes" or "no"
	elseif prop == "irregular" then
		return data.irregular and "yes" or "no"
	
	
	else
		error("Unrecognized property '" .. prop .. "'")
	end
end


function export.verb_prop(frame)
	return verb_prop(frame:getParent().args)
end



function export.verb_prop2(parargs, args)
	return export.verb_prop(debug_frame(parargs, args))
end

function export.verb_forms(frame)
	local origargs, args = get_frame_args(frame)
	local i = 1
	local past_vowel_re = "^[aui,]*$"
	local combined_root = nil
	if not args[i] or rfind(args[i], past_vowel_re) then
		combined_root = mw.title.getCurrentTitle().text
		if not rfind(combined_root, " ") then
			error("When inferring roots from page title, need spaces in page title: " .. combined_root)
		end
	elseif rfind(args[i], " ") then
		combined_root = args[i]
		i = i + 1
	else
		local separate_roots = {}
		while args[i] and not rfind(args[i], past_vowel_re) do
			table.insert(separate_roots, args[i])
			i = i + 1
		end
		combined_root = table.concat(separate_roots, " ")
	end
	local past_vowel = args[i]
	i = i + 1
	if past_vowel and not rfind(past_vowel, past_vowel_re) then
		error("Unrecognized past vowel, should be 'a', 'i', 'u', 'a,u', etc. or empty: " .. past_vowel)
	end
	if not past_vowel then
		past_vowel = ""
	end

	local split_root = rsplit(combined_root, " ")
	
	
	
	
	
	local verb_properties = {}
	for _, form in ipairs(allowed_forms) do
		local formpropslist = {}
		local derivs = {{"verb", ""}, {"vn", "-vn"}, {"ap", "-ap"}, {"pp", "-pp"}}
		local index = 1
		while true do
			local formprops = {}
			local prefix = index == 1 and form or form .. index
			if prefix == "I" then
				formprops["pv"] = past_vowel
			end
			if args[prefix .. "-pv"] then
				formprops["pv"] = args[prefix .. "-pv"]
			end
			for _, deriv in ipairs(derivs) do
				local prop = deriv[1]
				local extn = deriv[2]
				if args[prefix .. extn] == "+" then
					formprops[prop] = true
				elseif args[prefix .. extn] == "-" then
					formprops[prop] = false
				elseif args[prefix .. extn] then
					formprops[prop] = true
					formprops[prop .. "-gloss"] = args[prefix .. extn]
				end
				if args[prefix .. extn .. "-head"] then
					if formprops[prop] == nil then
						formprops[prop] = true
					end
					formprops[prop] = args[prefix .. extn .. "-head"]
				end
				if args[prefix .. extn .. "-gloss"] then
					if formprops[prop] == nil then
						formprops[prop] = true
					end
					formprops[prop .. "-gloss"] = args[prefix .. extn .. "-gloss"]
				end
			end
			if formprops["verb"] then
				
				
				
				
				if form ~= "I" and formprops["vn"] == nil then
					formprops["vn"] = true
				end
				if formprops["ap"] == nil then
					formprops["ap"] = true
				end
				local weakness = weakness_from_radicals(form, split_root[1],
					split_root[2], split_root[3], split_root[4])
				if formprops["pp"] == nil and not form_probably_no_passive(form,
						weakness, rsplit(formprops["pv"] or "", ","), {}) then
					formprops["pp"] = true
				end
				table.insert(formpropslist, formprops)
				index = index + 1
			else
				break
			end
		end
		table.insert(verb_properties, {form, formpropslist})
	end

	
	
	for _, vplist in ipairs(verb_properties) do
		local form = vplist[1]
		for _, props in ipairs(vplist[2]) do
			local args = {}
			function append_form_and_root()
				table.insert(args, form)
				if form == "I" then
					table.insert(args, props["pv"]) 
					table.insert(args, "")
				end
				append_array(args, split_root)
			end
			if props["verb"] == true then
				args = {}
				append_form_and_root()
				props["verb"] = past3sm(args, true)
			end
			for _, deriv in ipairs({"vn", "ap", "pp"}) do
				if props[deriv] == true then
					args = {deriv}
					append_form_and_root()
					props[deriv] = verb_part(args, true)
				end
			end
		end
	end

    
	local formtextarr = {}
	for _, vplist in ipairs(verb_properties) do
		local form = vplist[1]
		for _, props in ipairs(vplist[2]) do
			local textarr = {}
			if props["verb"] then
				local text = "* '''[[Függelék:Arab igék#Form " .. form .. "|" .. form .. ". igetörzs]]''': "
				local linktext = {}
				local splitheads = rsplit(props["verb"], "[,،]")
				for _, head in ipairs(splitheads) do
					table.insert(linktext, m_links.full_link({lang = lang, term = head, gloss = ine(props["verb-gloss"])}))
				end
				text = text .. table.concat(linktext, ", ")
				table.insert(textarr, text)
				for _, derivengl in ipairs({{"vn", "Maszdar"}, {"ap", "Aktív melléknévi igenév"}, {"pp", "Passzív melléknévi igenév"}}) do
					local deriv = derivengl[1]
					local engl = derivengl[2]
					if props[deriv] then
						local text = "** " .. engl .. ": "
						local linktext = {}
						local splitheads = rsplit(props[deriv], "[,،]")
						for _, head in ipairs(splitheads) do
							table.insert(linktext, m_links.full_link({lang = lang, term = head, gloss = ine(props[deriv .. "-gloss"])}))
						end
						text = text .. table.concat(linktext, ", ")
						table.insert(textarr, text)
					end
				end
				table.insert(formtextarr, table.concat(textarr, "\n"))
			end
		end
	end

	return table.concat(formtextarr, "\n")
end



function export.verb_forms2(parargs, args)
	return export.verb_forms(debug_frame(parargs, args))
end










function conjugate(args, argind)
	local data = {forms = {}, categories = {}, headword_categories = {}}

	title = mw.title.getCurrentTitle()
	NAMESPACE = title.nsText
	PAGENAME = ( NAMESPACE == "Appendix" and title.subpageText ) or title.text

	local conj_type = args[argind] or
		error("Form (conjugation type) has not been specified. " ..
			"Please pass a value to parameter " .. argind ..
			" in the template invocation.")

	
	local form, weakness
	if rfind(conj_type, "%-") then
		local form_weakness = rsplit(conj_type, "%-")
		form = form_weakness[1]
		table.remove(form_weakness, 1)
		weakness = table.concat(form_weakness, "-")
	else
		form = conj_type
		weakness = nil
	end

	
	
	

	
	local quadlit = rmatch(form, "q$")

	
	local rad1, rad2, rad3, rad4, past_vowel, nonpast_vowel
	if form == "I" then
		past_vowel = args[argind + 1]
		nonpast_vowel = args[argind + 2]
		local function splitvowel(vowelspec)
			if vowelspec == nil then
				vowelspec = {}
			else
				vowelspec = rsplit(vowelspec, ",")
			end
			return vowelspec
		end
		
		
		past_vowel = splitvowel(past_vowel)
		nonpast_vowel = splitvowel(nonpast_vowel)
		rad1 = args[argind + 3] or args["I"]
		rad2 = args[argind + 4] or args["II"]
		rad3 = args[argind + 5] or args["III"]
	else
		rad1 = args[argind + 1] or args["I"]
		rad2 = args[argind + 2] or args["II"]
		rad3 = args[argind + 3] or args["III"]
		if quadlit then
			rad4 = args[argind + 4] or args["IV"]
		end
	end

	
	
	
	
	
	
	
	
	
	if not rad1 or not rad2 or not rad3 or quadlit and not rad4 then
		local wkness, r1, r2, r3, r4 =
			export.infer_radicals(PAGENAME, form)
		
		
		
		
		
		
		local use_wkness = (not rad1 or rad1 == r1) and (not rad2 or rad2 == r2) and
			(not rad3 or rad3 == r3) and (not rad4 or rad4 == r4)
		rad1 = rad1 or r1
		rad2 = rad2 or r2
		rad3 = rad3 or r3
		rad4 = rad4 or r4

		
		
		
		
		
		
		
		
		
		
		
		if form == "I" and (rad2 == "w" or rad2 == "y") then
			if contains(nonpast_vowel, "i") then
				rad2 = Y
			elseif contains(nonpast_vowel, "u") then
				rad2 = W
			else
				error("Unable to guess middle radical of hollow form I verb; " ..
					"need to specify radical explicitly")
			end
		end

		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		if use_wkness then
			weakness = weakness or wkness
		end
	end

	
	data.unreg_rad1 = rad1
	data.unreg_rad2 = rad2
	data.unreg_rad3 = rad3
	data.unreg_rad4 = rad4

	
	
	local function regularize_inferred_radical(rad)
		if rad == "t" then
			return T
		elseif rad == "w" then
			return W
		elseif rad == "y" then
			return Y
		else
			return rad
		end
	end

	rad1 = regularize_inferred_radical(rad1)
	rad2 = regularize_inferred_radical(rad2)
	rad3 = regularize_inferred_radical(rad3)
	rad4 = regularize_inferred_radical(rad4)

	data.rad1 = rad1
	data.rad2 = rad2
	data.rad3 = rad3
	data.rad4 = rad4

	

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	

	if weakness == nil then
		weakness = weakness_from_radicals(form, rad1, rad2, rad3, rad4)
	end
	
	
	
	
	
	check_radicals(form, weakness, rad1, rad2, rad3, rad4)

	
	
	local function check_for_uncertainty(arg)
		if args[arg] and rfind(args[arg], "%?$") then
			args[arg] = rsub(args[arg], "%?$", "")
			if args[arg] == "" then
				args[arg] = nil
			end
			return true
		else
			return false
		end
	end

	
	
	
	
	if check_for_uncertainty("vn") or form == "I" and not args["vn"] then
		table.insert(data.categories, "arab ige - nincs maszdar")
		data.vn_uncertain = true 
	end
	if check_for_uncertainty("passive") then
		
		data.passive_uncertain = true
	end

	
	
	
	
	
	
	
	
	
	local passive = args["passive"]
	if passive == "impers" or passive == "only" or passive == "only-impers" then
	elseif not passive then
		passive = form_probably_impersonal_passive(form) and "impers" or
			not form_probably_no_passive(form, weakness, past_vowel,
				nonpast_vowel) and true or false
	else
		passive = yesno(passive, "unknown")
		if passive == "unknown" then
			error("Unrecognized value '" .. args["passive"] ..
				"' to argument passive=; use 'impers', 'only', 'only-impers', " ..
				"'yes'/'y'/'true'/'1' or 'no'/'n'/'false'/'0'")
		end
	end
	data.passive = passive

	
	initialize_categories(data,	form, weakness, rad1, rad2, rad3, rad4)

	
	conj_type = form .. "-" .. weakness

	
	if not conjugations[conj_type] then
		error("Unknown conjugation type '" .. conj_type .. "'")
	end

	
	
	
	
	
	
	
	
	
	
	
	if quadlit then
		conjugations[conj_type](data, args, rad1, rad2, rad3, rad4)
	elseif form ~= "I" then
		conjugations[conj_type](data, args, rad1, rad2, rad3)
	else
		
		
		
		
		

		
		
		
		
		
		
		
		
		
		local function convert_to_nested_array(array)
			if #array == 0 then
				return {{}}
			else
				local retval = {}
				for _, el in ipairs(array) do
					table.insert(retval, {el})
				end
				return retval
			end
		end
		local pv_nested = convert_to_nested_array(past_vowel)
		local npv_nested = convert_to_nested_array(nonpast_vowel)
		for i, pv in ipairs(pv_nested) do
			for j, npv in ipairs(npv_nested) do
				
				conjugations[conj_type](data, args, rad1, rad2, rad3, pv[1], npv[1])
			end
		end
	end

	return data, form, weakness, past_vowel, nonpast_vowel
end


function weakness_from_radicals(form, rad1, rad2, rad3, rad4)
	local weakness = nil
	local quadlit = rmatch(form, "q$")
	
	if not quadlit then
		if is_waw_ya(rad3) and rad1 == W and form == "I" then
			weakness = "asszimilált+gyenge"
		elseif is_waw_ya(rad3) and form_supports_final_weak(form) then
			weakness = "gyenge"
		elseif rad2 == rad3 and form_supports_geminate(form) then
			weakness = "duplázott"
		elseif is_waw_ya(rad2) and form_supports_hollow(form) then
			weakness = "lyukas"
		elseif rad1 == W and form == "I" then
			weakness = "asszimilált"
		else
			weakness = "erős"
		end
	else
		if is_waw_ya(rad4) then
			weakness = "gyenge"
		else
			weakness = "erős"
		end
	end
	return weakness
end




function export.infer_radicals(headword, form)
	local letters = {}
	
	headword = rsub(headword, AMAD, HAMZA .. ALIF)

	local len = ulen(headword)

	
	for i = 1, len do
		table.insert(letters, usub(headword, i, i))
	end

	
	
	local function check(index, must)
		local letter = letters[index]
		if type(must) == "string" then
			if letter == nil then
				error("Letter " .. index .. " is nil", 2)
			end
			if letter ~= must then
				error("For form " .. form .. ", letter " .. index ..
					" must be " .. must .. ", not " .. letter, 2)
			end
		elseif not contains(must, letter) then
			error("For form " .. form .. ", radical " .. index ..
				" must be one of " .. table.concat(must, " ") .. ", not " .. letter, 2)
		end
	end

	
	local function check_len(min, max)
		if len < min then
--			error("Not enough letters in headword " .. headword .. 				" for form " .. form .. ", expected at least " .. min)
		elseif len > max then
--			error("Too many letters in headword " .. headword .. 				" for form " .. form .. ", expected at most " .. max)
		end
	end

	local quadlit = rmatch(form, "q$")

	
	
	local radstart, rad1, rad2, rad3, rad4
	local weakness
	if form == "I" or form == "II" then
		rad1 = letters[1]
		radstart = 2
	elseif form == "III" then
		rad1 = letters[1]
		check(2, {ALIF, WAW}) 
		radstart = 3
	elseif form == "IV" then
		
		if letters[1] == HAMZA and letters[2] == ALIF then
			rad1 = HAMZA
		else
			check(1, HAMZA_ON_ALIF)
			rad1 = letters[2]
		end
		radstart = 3
	elseif form == "V" then
		check(1, T)
		rad1 = letters[2]
		radstart = 3
	elseif form == "VI" then
		check(1, T)
		if letters[2] == AMAD then
			rad1 = HAMZA
			radstart = 3
		else
			rad1 = letters[2]
			check(3, {ALIF, WAW}) 
			radstart = 4
		end
	elseif form == "VII" then
		check(1, ALIF)
		check(2, N)
		rad1 = letters[3]
		radstart = 4
	elseif form == "VIII" then
		check(1, ALIF)
		rad1 = letters[2]
		if rad1 == T or rad1 == "د" or rad1 == "ث" or rad1 == "ذ" or rad1 == "ط" or rad1 == "ظ" then
			radstart = 3
		elseif rad1 == "ز" then
			check(3, "د")
			radstart = 4
		elseif rad1 == "ص" or rad1 == "ض"  then
			check(3, "ط")
			radstart = 4
		else
			check(3, T)
			radstart = 4
		end
		if rad1 == T then
			
			
			rad1 = "t"
		end
	elseif form == "IX" then
		check(1, ALIF)
		rad1 = letters[2]
		radstart = 3
	elseif form == "X" then
		check(1, ALIF)
		check(2, S)
		check(3, T)
		rad1 = letters[4]
		radstart = 5
	elseif form == "Iq" then
		rad1 = letters[1]
		rad2 = letters[2]
		radstart = 3
	elseif form == "IIq" then
		check(1, T)
		rad1 = letters[2]
		rad2 = letters[3]
		radstart = 4
	elseif form == "IIIq" then
		check(1, ALIF)
		rad1 = letters[2]
		rad2 = letters[3]
		check(4, N)
		radstart = 5
	elseif form == "IVq" then
		check(1, ALIF)
		rad1 = letters[2]
		rad2 = letters[3]
		radstart = 4
	elseif form == "XI" then
		check_len(5, 5)
		check(1, ALIF)
		rad1 = letters[2]
		rad2 = letters[3]
		check(4, ALIF)
		rad3 = letters[5]
		weakness = "erős"
	elseif form == "XII" then
		check(1, ALIF)
		rad1 = letters[2]
		if letters[3] ~= letters[5] then
			error("For form XII, letters 3 and 5 of headword " .. headword ..
				" should be the same")
		end
		check(4, W)
		radstart = 5
	elseif form == "XIII" then
		check_len(5, 5)
		check(1, ALIF)
		rad1 = letters[2]
		rad2 = letters[3]
		check(4, W)
		rad3 = letters[5]
		if rad3 == AMAQ then
			weakness = "gyenge"
		else
			weakness = "erős"
		end
	elseif form == "XIV" then
		check_len(6, 6)
		check(1, ALIF)
		rad1 = letters[2]
		rad2 = letters[3]
		check(4, N)
		rad3 = letters[5]
		if letters[6] == AMAQ then
			check_waw_ya(rad3)
			weakness = "gyenge"
		else
			if letters[5] ~= letters[6] then
				error("For form XIV, letters 5 and 6 of headword " .. headword ..
					" should be the same")
			end
			weakness = "erős"
		end
	elseif form == "XV" then
		check_len(6, 6)
		check(1, ALIF)
		rad1 = letters[2]
		rad2 = letters[3]
		check(4, N)
		rad3 = letters[5]
		if rad3 == Y then
			check(6, ALIF)
		else
			check(6, AMAQ)
		end
		weakness = "erős"
	else
		error("Don't recognize form " .. form)
	end

	
	
	
	if radstart ~= nil then
		
		check_len(radstart, radstart + 1)
		if len == radstart then
			
			if form_supports_geminate(form) then
				weakness = "duplázott"
				rad2 = letters[len]
				rad3 = letters[len]
			else
				
				
				check_len(radstart + 1, radstart + 1)
			end
		elseif quadlit then
			
			rad3 = letters[radstart]
			rad4 = letters[radstart + 1]
			if rad4 == AMAQ or rad4 == ALIF and rad3 == Y or rad4 == Y then
				
				if form_supports_final_weak(form) then
					weakness = "gyenge"
					
					
					
					rad4 = rad3 == W and "y" or "w"
				else
					error("For headword " .. headword ..
						", last radical is " .. rad4 .. " but form " .. form ..
						" doesn't support final-weak verbs")
				end
			else
				weakness = "erős"
			end
		else
			
			rad2 = letters[radstart]
			rad3 = letters[radstart + 1]
			if form == "I" and (is_waw_ya(rad3) or rad3 == ALIF or rad3 == AMAQ) then
				
				
				
				
				if rad1 == W then
					weakness = "asszimilált+gyenge"
				else
					weakness = "gyenge"
				end
				if rad3 == ALIF then
					rad3 = W
				elseif rad3 == AMAQ then
					rad3 = Y
				else
					
					
					
					rad3 = (rad1 == W or rad2 == W) and "y" or "w" 
				end
		elseif rad3 == AMAQ or rad2 == Y and rad3 == ALIF or rad3 == Y then
				
				if form_supports_final_weak(form) then
					weakness = "gyenge"
				else
					error("For headword " .. headword ..
						", last radical is " .. rad3 .. " but form " .. form ..
						" doesn't support final-weak verbs")
				end
				
				
				
				rad3 = (rad1 == W or rad2 == W) and "y" or "w"
			elseif rad2 == ALIF then
				if form_supports_hollow(form) then
					weakness = "lyukas"
					
					
					
					
					rad2 = "w"
				else
					error("For headword " .. headword ..
						", second radical is alif but form " .. form ..
						" doesn't support hollow verbs")
				end
			elseif form == "I" and rad1 == W then
				weakness = "asszimilált"
			elseif rad2 == rad3 and (form == "III" or form == "VI") then
				weakness = "duplázott"
			else
				weakness = "erős"
			end
		end
	end

	
	
	
	local function convert(rad, index)
		if rad == HAMZA_ON_ALIF or rad == HAMZA_UNDER_ALIF or
			rad == HAMZA_ON_W or rad == HAMZA_ON_Y then
			return HAMZA
		elseif rad == AMAQ then
			error("For form " .. form .. ", headword " .. headword ..
				", radical " .. index .. " must not be alif maqṣūra")
		elseif rad == ALIF then
			error("For form " .. form .. ", headword " .. headword ..
				", radical " .. index .. " must not be alif")
		else
			return rad
		end
	end
	rad1 = convert(rad1, 1)
	rad2 = convert(rad2, 2)
	rad3 = convert(rad3, 3)
	rad4 = convert(rad4, 4)

	return weakness, rad1, rad2, rad3, rad4
end





function check_radicals(form, weakness, rad1, rad2, rad3, rad4)
	local function hamza_check(index, rad)
		if rad == HAMZA_ON_ALIF or rad == HAMZA_UNDER_ALIF or
			rad == HAMZA_ON_W or rad == HAMZA_ON_Y then
			error("Radical " .. index .. " is " .. rad .. " but should be ء (hamza on the line)")
		end
	end
	local function check_waw_ya(index, rad)
		if rad ~= W and rad ~= Y then
			error("Radical " .. index .. " is " .. rad .. " but should be و or ي")
		end
	end
	local function check_not_waw_ya(index, rad)
		if rad == W or rad == Y then
			error("In a sound verb, radical " .. index .. " should not be و or ي")
		end
	end
	hamza_check(rad1)
	hamza_check(rad2)
	hamza_check(rad3)
	hamza_check(rad4)
	if weakness == "asszimilált" or weakness == "asszimilált+gyenge" then
		if rad1 ~= W then
			error("Radical 1 is " .. rad1 .. " but should be و")
		end
	
	
	
	end
	if weakness == "gyenge" or weakness == "asszimilált+gyenge" then
		if rad4 then
			check_waw_ya(4, rad4)
		else
			check_waw_ya(3, rad3)
		end
	elseif form_supports_final_weak(form) then
		
		
		
		if rad4 then
			check_not_waw_ya(4, rad4)
		else
			check_not_waw_ya(3, rad3)
		end
	end
	if weakness == "lyukas" then
		check_waw_ya(2, rad2)
	
	
	
	
	end
	if weakness == "duplázott" then
		if rad4 then
			error("Internal error. No geminate quadrilaterals, should not be seen.")
		end
		if rad2 ~= rad3 then
			error("Weakness is geminate; radical 3 is " .. rad3 .. " but should be same as radical 2 " .. rad2 .. ".")
		end
	elseif form_supports_geminate(form) then
		
		
		
		
		if rad4 then
			error("Internal error. No quadrilaterals should support geminate verbs.")
		end
		if rad2 == rad3 and not is_waw_ya(rad2) then
			error("Weakness is '" .. weakness .. "'; radical 2 and 3 are same at " .. rad2 .. " but should not be; consider making weakness 'geminate'")
		end
	end
end

function initialize_categories(data, form, weakness, rad1, rad2, rad3, rad4)
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	table.insert(data.categories, "arab gyök: " .. rad1 .. " " .. rad2 .. " " .. rad3)
	table.insert(data.headword_categories, "arab gyök: " .. rad1 .. " " .. rad2 .. " " .. rad3)
	table.insert(data.categories, "arab " .. form .. " igetörzs")
	table.insert(data.headword_categories, "arab " .. form .. " igetörzs")
	
	
	if form_is_quadriliteral(form) then
		
		
	end
	local formweak = {}
	if is_waw_ya(rad1) then
		table.insert(formweak, "asszimilált")
	end
	if is_waw_ya(rad2) and rad4 == nil then
		table.insert(formweak, "lyukas")
	end
	if is_waw_ya(rad4) or rad4 == nil and is_waw_ya(rad3) then
		table.insert(formweak, "gyenge")
	end
	if rad4 == nil and rad2 == rad3 then
		table.insert(formweak, "duplázott")
	end
	if rad1 == HAMZA or rad2 == HAMZA or rad3 == HAMZA or rad4 == HAMZA then
		table.insert(formweak, "hamzated")
	end
	if #formweak == 0 then
		table.insert(formweak, "sound")
	end
	for _, fw in ipairs(formweak) do
		
		
		
		
	end


	local function radical_is_ambiguous(rad)
		return rad == "t" or rad == "w" or rad == "y"
	end
	local function radical_is_weak(rad)
		return rad == W or rad == Y or rad == HAMZA
	end

	local ur1, ur2, ur3, ur4 =
		data.unreg_rad1, data.unreg_rad2, data.unreg_rad3, data.unreg_rad4
	
	
	
	if radical_is_ambiguous(ur1) or radical_is_ambiguous(ur2) or
			radical_is_ambiguous(ur3) or radical_is_ambiguous(ur4) then
		
	end
	if radical_is_weak(ur1) then
		
	end
	if radical_is_weak(ur2) then
		
	end
	if radical_is_weak(ur3) then
		
	end
	if radical_is_weak(ur4) then
		
	end

	if data.passive == "only" then
		
		
	elseif data.passive == "only-impers" then
		
		
	elseif data.passive == "impers" then
		
	elseif data.passive then
		
	else
		
	end
end








function check_aiu(vtype, vowel)
	if vowel ~= "a" and vowel ~= "i" and vowel ~= "u" then
		error(vtype .. " vowel '" .. vowel .. "' should be a, i, or u")
	end
end


function is_waw_ya(rad)
	return rad == W or rad == Y
end


function check_waw_ya(rad)
	if not is_waw_ya(rad) then
		error("Expecting weak radical: '" .. rad .. "' should be " .. W .. " or " .. Y)
	end
end


function is_guttural(rad)
	return rad == HAMZA or rad == "ه" or rad == "ع" or rad == "ح"
end



function nonpast_from_past_vowel(past_vowel, rad2, rad3)
	return past_vowel == "i" and "a" or past_vowel == "u" and "u" or
		(is_guttural(rad2) or is_guttural(rad3)) and "a" or "u"
end


function imper_vowel_from_nonpast(nonpast_vowel)
	if nonpast_vowel == "a" or nonpast_vowel == "i" then
		return "i"
	elseif nonpast_vowel == "u" then
		return "u"
	else
		error("Non-past vowel '" .. nonpast_vowel .. "' isn't a, i, or u, should have been caught earlier")
	end
end


function short_to_long_vowel(vowel)
	if vowel == A then return ALIF
	elseif vowel == I then return Y
	elseif vowel == U then return W
	else
		error("Vowel '" .. vowel .. "' isn't a, i, or u, should have been caught earlier")
	end
end



local function make_form_i_sound_assimilated_verb(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel, assimilated)
	
	past_vowel = past_vowel or "a"
	nonpast_vowel = nonpast_vowel or nonpast_from_past_vowel(past_vowel, rad2, rad3)
	check_aiu("múlt", past_vowel)
	check_aiu("folyamatos", nonpast_vowel)

	
	insert_verbal_noun(data, args, {})

	
	local past_stem = rad1 .. A .. rad2 .. dia[past_vowel] .. rad3
	local nonpast_stem = assimilated and rad2 .. dia[nonpast_vowel] .. rad3 or
		rad1 .. SK .. rad2 .. dia[nonpast_vowel] .. rad3
	local ps_past_stem = rad1 .. U .. rad2 .. I .. rad3
	local ps_nonpast_stem = rad1 .. SK .. rad2 .. A .. rad3

	
	local imper_vowel = imper_vowel_from_nonpast(nonpast_vowel)

	
	
	local reducedimp = reduced_imperative_verb(rad1, rad2, rad3)
	if reducedimp then
		data.irregular = true
	end
	local imper_stem_suffix = rad2 .. dia[nonpast_vowel] .. rad3
	local imper_stem_base = (assimilated or reducedimp) and "" or
		ALIF .. dia[imper_vowel] ..
		(rad1 == HAMZA and short_to_long_vowel(dia[imper_vowel]) or rad1 .. SK)
	local imper_stem = imper_stem_base .. imper_stem_suffix

	
	make_sound_verb(data, past_stem, ps_past_stem, nonpast_stem,
		ps_nonpast_stem, imper_stem, "a")

	
	
	
	if saal_radicals(rad1, rad2, rad3) then
		data.irregular = true
		nonpast_1stem_conj(data, "juss", "a", "سَل")
		nonpast_1stem_conj(data, "ps-juss", "u", "سَل")
		make_1stem_imperative(data, "سَل")
	end

	
	insert_part(data, "ap", rad1 .. AA .. rad2 .. I .. rad3 .. UNS)
	
	insert_part(data, "pp", MA .. rad1 .. SK .. rad2 .. U .. "و" .. rad3 .. UNS)
end

conjugations["I-erős"] = function(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel)
	make_form_i_sound_assimilated_verb(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel, false)
end

conjugations["I-asszimilált"] = function(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel)
	make_form_i_sound_assimilated_verb(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel, "asszimilált")
end

local function make_form_i_hayy_verb(data, args)
	
	insert_verbal_noun(data, args, {})

	data.irregular = true

	
	local past_c_stem = "حَيِي"
	local past_v_stem_long = past_c_stem
	local past_v_stem_short = "حَيّ"
	local ps_past_c_stem = "حُيِي"
	local ps_past_v_stem_long = ps_past_c_stem
	local ps_past_v_stem_short = "حُيّ"

	local nonpast_stem = "حْي"
	local ps_nonpast_stem = nonpast_stem
	local imper_stem = "اِ" .. nonpast_stem

	

	past_2stem_conj(data, "perf", "-", past_c_stem)
	past_2stem_conj(data, "ps-perf", "-", ps_past_c_stem)
	local variant = args["variant"]
	if variant == "short" or variant == "both" then
		past_2stem_conj(data, "perf", past_v_stem_short, "-")
		past_2stem_conj(data, "ps-perf", ps_past_v_stem_short, "-")
	end
	function inflect_long_variant(tense, long_stem, short_stem)
		inflect_tense_1(data, tense, "",
			{long_stem, long_stem, long_stem, long_stem, short_stem},
			{past_endings[4], past_endings[5], past_endings[7], past_endings[8],
			 past_endings[12]},
			{"3sm", "3sf", "3dm", "3df", "3pm"})
	end
	if variant == "long" or variant == "both" then
		inflect_long_variant("perf", past_v_stem_long, past_v_stem_short)
		inflect_long_variant("ps-perf", ps_past_v_stem_long, ps_past_v_stem_short)
	end

	nonpast_1stem_conj(data, "impf", "a", nonpast_stem, indic_endings_aa)
	nonpast_1stem_conj(data, "subj", "a", nonpast_stem, subj_endings_aa)
	nonpast_1stem_conj(data, "juss", "a", nonpast_stem, juss_endings_aa)
	nonpast_1stem_conj(data, "ps-impf", "u", ps_nonpast_stem, indic_endings_aa)
	nonpast_1stem_conj(data, "ps-subj", "u", ps_nonpast_stem, subj_endings_aa)
	nonpast_1stem_conj(data, "ps-juss", "u", ps_nonpast_stem, juss_endings_aa)
	inflect_tense_impr(data, imper_stem, impr_endings_aa)

	
	insert_part(data, "ap", {})
	
	insert_part(data, "pp", {})
end



local function make_form_i_final_weak_verb(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel, assimilated)

	
	if hayy_radicals(rad1, rad2, rad3) then
		make_form_i_hayy_verb(data, args)
		return
	end

	
	local past_vowel = past_vowel or "a"
	local nonpast_vowel = nonpast_vowel or past_vowel == "i" and "a" or
		past_vowel == "u" and "u" or rad3 == Y and "i" or "u"
	check_aiu("múlt", past_vowel)
	check_aiu("folyamatos", nonpast_vowel)

	
	insert_verbal_noun(data, args, {})

	
	local past_stem = rad1 .. A .. rad2
	local ps_past_stem = rad1 .. U .. rad2
	local nonpast_stem, ps_nonpast_stem, imper_stem
	if raa_radicals(rad1, rad2, rad3) then
		data.irregular = true
		nonpast_stem = rad1
		ps_nonpast_stem = rad1
		imper_stem = rad1
	else
		ps_nonpast_stem = rad1 .. SK .. rad2
		if assimilated then
			nonpast_stem = rad2
			imper_stem = rad2
		else
			nonpast_stem = ps_nonpast_stem
			
			local imper_vowel = imper_vowel_from_nonpast(nonpast_vowel)
			imper_stem =  ALIF .. dia[imper_vowel] ..
				(rad1 == HAMZA and short_to_long_vowel(dia[imper_vowel])
					or rad1 .. SK) ..
				rad2
		end
	end

	
	local past_suffs =
		rad3 == Y and past_vowel == "a" and past_endings_ay or
		rad3 == W and past_vowel == "a" and past_endings_aw or
		past_vowel == "i" and past_endings_ii or
		past_endings_uu
	local indic_suffs, subj_suffs, juss_suffs, impr_suffs
	if nonpast_vowel == "a" then
		indic_suffs = indic_endings_aa
		subj_suffs = subj_endings_aa
		juss_suffs = juss_endings_aa
		impr_suffs = impr_endings_aa
	elseif nonpast_vowel == "i" then
		indic_suffs = indic_endings_ii
		subj_suffs = subj_endings_ii
		juss_suffs = juss_endings_ii
		impr_suffs = impr_endings_ii
	else
		assert(nonpast_vowel == "u")
		indic_suffs = indic_endings_uu
		subj_suffs = subj_endings_uu
		juss_suffs = juss_endings_uu
		impr_suffs = impr_endings_uu
	end
	make_final_weak_verb(data, past_stem, ps_past_stem, nonpast_stem,
		ps_nonpast_stem, imper_stem, past_suffs, indic_suffs,
		subj_suffs, juss_suffs, impr_suffs, "a")

	
	insert_part(data, "ap", rad1 .. AA .. rad2 .. IN)
	
	insert_part(data, "pp", MA .. rad1 .. SK .. rad2 ..
		(rad3 == Y and II or UU) .. SH .. UNS)
end

conjugations["I-gyenge"] = function(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel)
	make_form_i_final_weak_verb(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel, false)
end

conjugations["I-asszimilált+gyenge"] = function(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel)
	make_form_i_final_weak_verb(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel, "asszimilált")
end

conjugations["I-lyukas"] = function(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel)
	
	
	local past_vowel = past_vowel or rad2 == Y and "i" or "u"
	
	
	local nonpast_vowel = nonpast_vowel or past_vowel ~= "a" and past_vowel or
		rad2 == Y and "i" or "u"
	check_aiu("múlt", past_vowel)
	check_aiu("folyamatos", nonpast_vowel)
	
	
	
	
	
	if past_vowel == "a" then
		
		past_vowel = nonpast_vowel == "a" and "i" or nonpast_vowel
	end
	local lengthened_nonpast = nonpast_vowel == "u" and UU or
		nonpast_vowel == "i" and II or AA

	
	insert_verbal_noun(data, args, {})

	
	local past_v_stem = rad1 .. AA .. rad3
	local past_c_stem = rad1 .. dia[past_vowel] .. rad3

	
	local nonpast_v_stem = rad1 .. lengthened_nonpast .. rad3
	local nonpast_c_stem = rad1 .. dia[nonpast_vowel] .. rad3

	
	
	local ps_past_v_stem = rad1 .. II .. rad3
	local ps_past_c_stem = rad1 .. I .. rad3

	
	
	
	local ps_nonpast_v_stem = rad1 .. AA .. rad3
	local ps_nonpast_c_stem = rad1 .. A .. rad3

	
	local imper_v_stem = nonpast_v_stem
	local imper_c_stem = nonpast_c_stem

	
	make_hollow_geminate_verb(data, past_v_stem, past_c_stem, ps_past_v_stem,
		ps_past_c_stem, nonpast_v_stem, nonpast_c_stem, ps_nonpast_v_stem,
		ps_nonpast_c_stem, imper_v_stem, imper_c_stem, "a", false)

	
	insert_part(data, "ap", rad3 == HAMZA and rad1 .. AA .. HAMZA .. IN or
		rad1 .. AA .. HAMZA .. I .. rad3 .. UNS)
	
	insert_part(data, "pp", MA .. rad1 .. (rad2 == Y and II or UU) .. rad3 .. UNS)
end

conjugations["I-duplázott"] = function(data, args, rad1, rad2, rad3,
		past_vowel, nonpast_vowel)
	
	local past_vowel = past_vowel or "a"
	local nonpast_vowel = nonpast_vowel or nonpast_from_past_vowel(past_vowel, rad2, rad3)

	
	insert_verbal_noun(data, args, {})

	
	local past_v_stem = rad1 .. A .. rad2 .. SH
	local past_c_stem = rad1 .. A .. rad2 .. dia[past_vowel] .. rad2

	
	local nonpast_v_stem = rad1 .. dia[nonpast_vowel] .. rad2 .. SH
	local nonpast_c_stem = rad1 .. SK .. rad2 .. dia[nonpast_vowel] .. rad2

	
	
	local ps_past_v_stem = rad1 .. U .. rad2 .. SH
	local ps_past_c_stem = rad1 .. U .. rad2 .. I .. rad2

	
	
	
	local ps_nonpast_v_stem = rad1 .. A .. rad2 .. SH
	local ps_nonpast_c_stem = rad1 .. SK .. rad2 .. A .. rad2

	
	local imper_vowel = imper_vowel_from_nonpast(nonpast_vowel)

	
	local imper_v_stem = rad1 .. dia[nonpast_vowel] .. rad2 .. SH
	local imper_c_stem = ALIF .. dia[imper_vowel] ..
		(rad1 == HAMZA and short_to_long_vowel(dia[imper_vowel]) or rad1 .. SK) ..
		rad2 .. dia[nonpast_vowel] .. rad2

	
	make_hollow_geminate_verb(data, past_v_stem, past_c_stem, ps_past_v_stem,
		ps_past_c_stem, nonpast_v_stem, nonpast_c_stem, ps_nonpast_v_stem,
		ps_nonpast_c_stem, imper_v_stem, imper_c_stem, "a", "duplázott")

	
	insert_part(data, "ap", rad1 .. AA .. rad2 .. SH .. UNS)
	
	insert_part(data, "pp", MA .. rad1 .. SK .. rad2 .. U .. "و" .. rad2 .. UNS)
end



function make_form_ii_v_sound_final_weak_verb(data, args, rad1, rad2, rad3, form)
	local final_weak = rad3 == nil
	local vn = form == "V" and
		"تَ" .. rad1 .. A .. rad2 .. SH ..
			(final_weak and IN or U .. rad3 .. UNS) or
		"تَ" .. rad1 .. SK .. rad2 .. I .. "ي" ..
			(final_weak and AH or rad3) .. UNS
	local ta_pref = form == "V" and "تَ" or ""
	local tu_pref = form == "V" and "تُ" or ""

	
	local past_stem_base = ta_pref .. rad1 .. A .. rad2 .. SH
	local nonpast_stem_base = past_stem_base
	local ps_past_stem_base = tu_pref .. rad1 .. U .. rad2 .. SH

	
	make_augmented_sound_final_weak_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)
end

conjugations["II-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_ii_v_sound_final_weak_verb(data, args, rad1, rad2, rad3, "II")
end

conjugations["II-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_ii_v_sound_final_weak_verb(data, args, rad1, rad2, nil, "II")
end



function make_form_iii_vi_sound_final_weak_verb(data, args, rad1, rad2, rad3, form)
	local final_weak = rad3 == nil
	local vn = form == "VI" and
		"تَ" .. rad1 .. AA .. rad2 ..
			(final_weak and IN or U .. rad3 .. UNS) or
		{MU .. rad1 .. AA .. rad2 .. (final_weak and AAH or A .. rad3 .. AH) .. UNS,
			rad1 .. I .. rad2 .. AA .. (final_weak and HAMZA or rad3) .. UNS}
	local ta_pref = form == "VI" and "تَ" or ""
	local tu_pref = form == "VI" and "تُ" or ""

	
	local past_stem_base = ta_pref .. rad1 .. AA .. rad2
	local nonpast_stem_base = past_stem_base
	local ps_past_stem_base = tu_pref .. rad1 .. UU .. rad2

	
	make_augmented_sound_final_weak_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)
end

conjugations["III-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_iii_vi_sound_final_weak_verb(data, args, rad1, rad2, rad3, "III")
end

conjugations["III-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_iii_vi_sound_final_weak_verb(data, args, rad1, rad2, nil, "III")
end


function make_form_iii_vi_geminate_verb(data, args, rad1, rad2, form)
	
	local vn = form == "VI" and
		{"تَ" .. rad1 .. AA .. rad2 .. SH .. UNS} or
		{MU .. rad1 .. AA .. rad2 .. SH .. AH .. UNS}
	local ta_pref = form == "VI" and "تَ" or ""
	local tu_pref = form == "VI" and "تُ" or ""

	
	local past_stem_base = ta_pref .. rad1 .. AA
	local nonpast_stem_base = past_stem_base
	local ps_past_stem_base = tu_pref .. rad1 .. UU

	
	make_augmented_geminate_verb(data, args, rad2,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)

	
	
	make_form_iii_vi_sound_final_weak_verb(data, args, rad1, rad2, rad2, form)
end

conjugations["III-duplázott"] = function(data, args, rad1, rad2, rad3)
	make_form_iii_vi_geminate_verb(data, args, rad1, rad2, "III")
end



function make_form_iv_sound_final_weak_verb(data, args, rad1, rad2, rad3)
	local final_weak = rad3 == nil

	
	local stem_core

	
	if raa_radicals(rad1, rad2, final_weak and Y or rad3) then
		data.irregular = true
		stem_core = rad1
	else
		stem_core =	rad1 .. SK .. rad2
	end

	
	local vn = HAMZA .. I .. stem_core .. AA ..
		(final_weak and HAMZA or rad3) .. UNS

	
	local past_stem_base = HAMZA .. A .. stem_core
	local nonpast_stem_base = stem_core
	local ps_past_stem_base = HAMZA .. U .. stem_core

	
	make_augmented_sound_final_weak_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "IV")
end

conjugations["IV-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_iv_sound_final_weak_verb(data, args, rad1, rad2, rad3)
end

conjugations["IV-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_iv_sound_final_weak_verb(data, args, rad1, rad2, nil)
end

conjugations["IV-lyukas"] = function(data, args, rad1, rad2, rad3)
	
	local vn = HAMZA .. I .. rad1 .. AA .. rad3 .. AH .. UNS

	
	local past_stem_base = HAMZA .. A .. rad1
	local nonpast_stem_base = rad1
	local ps_past_stem_base = HAMZA .. U .. rad1

	
	make_augmented_hollow_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "IV")
end

conjugations["IV-duplázott"] = function(data, args, rad1, rad2, rad3)
	local vn = HAMZA .. I .. rad1 .. SK .. rad2 .. AA .. rad2 .. UNS

	
	local past_stem_base = HAMZA .. A .. rad1
	local nonpast_stem_base = rad1
	local ps_past_stem_base = HAMZA .. U .. rad1

	
	make_augmented_geminate_verb(data, args, rad2,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "IV")
end

conjugations["V-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_ii_v_sound_final_weak_verb(data, args, rad1, rad2, rad3, "V")
end

conjugations["V-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_ii_v_sound_final_weak_verb(data, args, rad1, rad2, nil, "V")
end

conjugations["VI-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_iii_vi_sound_final_weak_verb(data, args, rad1, rad2, rad3, "VI")
end

conjugations["VI-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_iii_vi_sound_final_weak_verb(data, args, rad1, rad2, nil, "VI")
end

conjugations["VI-duplázott"] = function(data, args, rad1, rad2, rad3)
	make_form_iii_vi_geminate_verb(data, args, rad1, rad2, "VI")
end





function high_form_verbal_noun(rad12, rad34, rad5)
	return "اِ" .. rad12 .. I .. rad34 .. AA ..
		(rad5 == nil and HAMZA or rad5) .. UNS
end












function make_high_form_sound_final_weak_verb(data, args, rad12, rad34, rad5, form)
	local final_weak = rad5 == nil
	local vn = high_form_verbal_noun(rad12, rad34, rad5)

	
	local nonpast_stem_base = rad12 .. A .. rad34
	local past_stem_base = "اِ" .. nonpast_stem_base
	local ps_past_stem_base = "اُ" .. rad12 .. U .. rad34

	
	make_augmented_sound_final_weak_verb(data, args, rad5,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)
end



function make_form_vii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
	make_high_form_sound_final_weak_verb(data, args, "نْ" .. rad1, rad2, rad3, "VII")
end

conjugations["VII-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_vii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
end

conjugations["VII-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_vii_sound_final_weak_verb(data, args, rad1, rad2, nil)
end

conjugations["VII-lyukas"] = function(data, args, rad1, rad2, rad3)
	local nrad1 = "نْ" .. rad1
	local vn = high_form_verbal_noun(nrad1, Y, rad3)

	
	local nonpast_stem_base = nrad1
	local past_stem_base = "اِ" ..nonpast_stem_base
	local ps_past_stem_base = "اُ" .. nrad1

	
	make_augmented_hollow_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "VII")
end

conjugations["VII-duplázott"] = function(data, args, rad1, rad2, rad3)
	local nrad1 = "نْ" .. rad1
	local vn = high_form_verbal_noun(nrad1, rad2, rad2)

	
	local nonpast_stem_base = nrad1 .. A
	local past_stem_base = "اِ" .. nonpast_stem_base
	local ps_past_stem_base = "اُ" .. nrad1 .. U

	
	make_augmented_geminate_verb(data, args, rad2,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "VII")
end




function join_ta(rad)
	if rad == W or rad == Y or rad == "ت" then return "تّ"
	elseif rad == "د" then return "دّ"
	elseif rad == "ث" then return "ثّ"
	elseif rad == "ذ" then return "ذّ"
	elseif rad == "ز" then return "زْد"
	elseif rad == "ص" then return "صْط"
	elseif rad == "ض" then return "ضْط"
	elseif rad == "ط" then return "طّ"
	elseif rad == "ظ" then return "ظّ"
	else return rad .. SK .. "ت"
	end
end



function form_viii_verbal_noun(rad1, rad2, rad3)
	local vn = high_form_verbal_noun(join_ta(rad1), rad2, rad3)
	if rad1 == HAMZA then
		return {vn, high_form_verbal_noun(Y .. T, rad2, rad3)}
	else
		return {vn}
	end
end



function make_form_viii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
	
	if axadh_radicals(rad1, rad2, rad3) then
		data.irregular = true
		rad1 = T
	end
	make_high_form_sound_final_weak_verb(data, args, join_ta(rad1), rad2, rad3,
		"VIII")

	
	
	if rad1 == HAMZA then
		local vn = form_viii_verbal_noun(rad1, rad2, rad3)
		local past_stem_base2 = "اِيتَ" .. rad2
		local nonpast_stem_base2 = join_ta(rad1) .. A .. rad2
		local ps_past_stem_base2 = "اُوتُ" .. rad2
		make_augmented_sound_final_weak_verb(data, args, rad3,
			past_stem_base2, nonpast_stem_base2, ps_past_stem_base2, vn, "VIII")
	end
end

conjugations["VIII-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_viii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
end

conjugations["VIII-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_viii_sound_final_weak_verb(data, args, rad1, rad2, nil)
end

conjugations["VIII-lyukas"] = function(data, args, rad1, rad2, rad3)
	local vn = form_viii_verbal_noun(rad1, Y, rad3)

	
	local nonpast_stem_base = join_ta(rad1)
	local past_stem_base = "اِ" .. nonpast_stem_base
	local ps_past_stem_base = "اُ" .. nonpast_stem_base

	
	make_augmented_hollow_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "VIII")

	
	
	if rad1 == HAMZA then
		local past_stem_base2 = "اِيت"
		local nonpast_stem_base2 = nonpast_stem_base
		local ps_past_stem_base2 = "اُوت"
		make_augmented_hollow_verb(data, args, rad3,
			past_stem_base2, nonpast_stem_base2, ps_past_stem_base2, vn, "VIII")
	end
end

conjugations["VIII-duplázott"] = function(data, args, rad1, rad2, rad3)
	local vn = form_viii_verbal_noun(rad1, rad2, rad2)

	
	local nonpast_stem_base = join_ta(rad1) .. A
	local past_stem_base = "اِ" .. nonpast_stem_base
	local ps_past_stem_base = "اُ" .. join_ta(rad1) .. U

	
	make_augmented_geminate_verb(data, args, rad2,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "VIII")

	
	
	if rad1 == HAMZA then
		local past_stem_base2 = "اِيتَ"
		local nonpast_stem_base2 = nonpast_stem_base
		local ps_past_stem_base2 = "اُوتُ"
		make_augmented_geminate_verb(data, args, rad2,
			past_stem_base2, nonpast_stem_base2, ps_past_stem_base2, vn, "VIII")
	end
end

conjugations["IX-erős"] = function(data, args, rad1, rad2, rad3)
	local ipref = "اِ"
	local vn = ipref .. rad1 .. SK .. rad2 .. I .. rad3 .. AA .. rad3 .. UNS

	
	local nonpast_stem_base = rad1 .. SK .. rad2 .. A
	local past_stem_base = ipref .. nonpast_stem_base
	local ps_past_stem_base = "اُ" .. rad1 .. SK .. rad2 .. U

	
	make_augmented_geminate_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "IX")
end

conjugations["IX-gyenge"] = function(data, args, rad1, rad2, rad3)
	error("FIXME: Not yet implemented")
end







function make_high5_form_sound_final_weak_verb(data, args, rad1, rad2, rad3, rad4, rad5, form)
	make_high_form_sound_final_weak_verb(data, args, rad1 .. SK .. rad2,
		rad3 .. SK .. rad4, rad5, form)
end



function make_form_x_sound_final_weak_verb(data, args, rad1, rad2, rad3)
	make_high5_form_sound_final_weak_verb(data, args, S, T, rad1, rad2, rad3, "X")
	
	if hayy_radicals(rad1, rad2, rad3 or Y) then
		data.irregular = true
		
		
		make_high_form_sound_final_weak_verb(data, args, S .. SK .. T, rad1, rad3, "X")
	end
end

conjugations["X-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_x_sound_final_weak_verb(data, args, rad1, rad2, rad3)
end

conjugations["X-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_x_sound_final_weak_verb(data, args, rad1, rad2, nil)
end

conjugations["X-lyukas"] = function(data, args, rad1, rad2, rad3)
	local vn = "اِسْتِ" .. rad1 .. AA .. rad3 .. AH .. UNS

	
	local past_stem_base = "اِسْتَ" .. rad1
	local nonpast_stem_base = "سْتَ" .. rad1
	local ps_past_stem_base = "اُسْتُ" .. rad1

	
	make_augmented_hollow_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "X")
end

conjugations["X-duplázott"] = function(data, args, rad1, rad2, rad3)
	local vn = "اِسْتِ" .. rad1 .. SK .. rad2 .. AA .. rad2 .. UNS

	
	local past_stem_base = "اِسْتَ" .. rad1
	local nonpast_stem_base = "سْتَ" .. rad1
	local ps_past_stem_base = "اُسْتُ" .. rad1

	
	make_augmented_geminate_verb(data, args, rad2,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "X")
end

conjugations["XI-erős"] = function(data, args, rad1, rad2, rad3)
	local ipref = "اِ"
	local vn = ipref .. rad1 .. SK .. rad2 .. II .. rad3 .. AA .. rad3 .. UNS

	
	local nonpast_stem_base = rad1 .. SK .. rad2 .. AA
	local past_stem_base = ipref .. nonpast_stem_base
	local ps_past_stem_base = "اُ" .. rad1 .. SK .. rad2 .. UU

	
	make_augmented_geminate_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "XI")
end





function make_form_xii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
	make_high5_form_sound_final_weak_verb(data, args, rad1, rad2, W, rad2, rad3, "XII")
end

conjugations["XII-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_xii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
end

conjugations["XII-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_xii_sound_final_weak_verb(data, args, rad1, rad2, nil)
end



function make_form_xiii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
	make_high5_form_sound_final_weak_verb(data, args, rad1, rad2, W, W, rad3, "XIII")
end

conjugations["XIII-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_xiii_sound_final_weak_verb(data, args, rad1, rad2, rad3)
end

conjugations["XIII-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_xiii_sound_final_weak_verb(data, args, rad1, rad2, nil)
end








function make_form_xiv_xv_sound_final_weak_verb(data, args, rad1, rad2, rad3, final_weak, form)
	local lastrad = not final_weak and rad3 or nil
	make_high5_form_sound_final_weak_verb(data, args, rad1, rad2, N, rad3, lastrad, form)
end

conjugations["XIV-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_xiv_xv_sound_final_weak_verb(data, args, rad1, rad2, rad3, false, "XIV")
end

conjugations["XIV-gyenge"] = function(data, args, rad1, rad2, rad3)
	make_form_xiv_xv_sound_final_weak_verb(data, args, rad1, rad2, rad3, true, "XIV")
end

conjugations["XV-erős"] = function(data, args, rad1, rad2, rad3)
	make_form_xiv_xv_sound_final_weak_verb(data, args, rad1, rad2, rad3, true, "XV")
end





function make_form_iq_iiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, rad4, form)
	local final_weak = rad4 == nil
	local vn = form == "IIq" and
		"تَ" .. rad1 .. A .. rad2 .. SK .. rad3 ..
			(final_weak and IN or U .. rad4 .. UNS) or
		rad1 .. A .. rad2 .. SK .. rad3 ..
			(final_weak and AAH or A .. rad4 .. AH) .. UNS
	local ta_pref = form == "IIq" and "تَ" or ""
	local tu_pref = form == "IIq" and "تُ" or ""

	
	local past_stem_base = ta_pref .. rad1 .. A .. rad2 .. SK .. rad3
	local nonpast_stem_base = past_stem_base
	local ps_past_stem_base = tu_pref .. rad1 .. U .. rad2 .. SK .. rad3

	
	make_augmented_sound_final_weak_verb(data, args, rad4,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)
end

conjugations["Iq-erős"] = function(data, args, rad1, rad2, rad3, rad4)
	make_form_iq_iiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, rad4, "Iq")
end

conjugations["Iq-gyenge"] = function(data, args, rad1, rad2, rad3, rad4)
	make_form_iq_iiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, nil, "Iq")
end

conjugations["IIq-erős"] = function(data, args, rad1, rad2, rad3, rad4)
	make_form_iq_iiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, rad4, "IIq")
end

conjugations["IIq-gyenge"] = function(data, args, rad1, rad2, rad3, rad4)
	make_form_iq_iiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, nil, "IIq")
end



function make_form_iiiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, rad4)
	make_high5_form_sound_final_weak_verb(data, args, rad1, rad2, N, rad3, rad4, "IIIq")
end

conjugations["IIIq-erős"] = function(data, args, rad1, rad2, rad3, rad4)
	make_form_iiiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, rad4)
end

conjugations["IIIq-gyenge"] = function(data, args, rad1, rad2, rad3, rad4)
	make_form_iiiq_sound_final_weak_verb(data, args, rad1, rad2, rad3, nil)
end

conjugations["IVq-erős"] = function(data, args, rad1, rad2, rad3, rad4)
	local ipref = "اِ"
	local vn = ipref .. rad1 .. SK .. rad2 .. I .. rad3 .. SK .. rad4 .. AA .. rad4 .. UNS

	
	local past_stem_base = ipref .. rad1 .. SK .. rad2 .. A .. rad3
	local nonpast_stem_base = rad1 .. SK .. rad2 .. A .. rad3
	local ps_past_stem_base = "اُ" .. rad1 .. SK .. rad2 .. U .. rad3

	
	make_augmented_geminate_verb(data, args, rad4,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, "IVq")
end









function inflect_tense_1(data, tense, prefixes, stems, endings, pnums)
	if prefixes == nil then
		error("For tense '" .. tense .. "', prefixes = nil")
	end
	if stems == nil then
		error("For tense '" .. tense .. "', stems = nil")
	end
	if endings == nil then
		error("For tense '" .. tense .. "', endings = nil")
	end
	if type(prefixes) == "table" and #pnums ~= #prefixes then
		error("For tense '" .. tense .. "', found " .. #prefixes .. " prefixes but expected " .. #pnums)
	end
	if type(stems) == "table" and #pnums ~= #stems then
		error("For tense '" .. tense .. "', found " .. #stems .. " stems but expected " .. #pnums)
	end
	if #pnums ~= #endings then
		error("For tense '" .. tense .. "', found " .. #endings .. " endings but expected " .. #pnums)
	end

	
	for i, pnum in ipairs(pnums) do
		if data.forms[pnum .. "-" .. tense] == nil then
			data.forms[pnum .. "-" .. tense] = {}
		end
	end

	
	for i = 1, #pnums do
		
		local ends = endings[i]
		if type(ends) == "string" then ends = {ends} end
		
		local prefix = prefixes
		if type(prefix) == "table" then prefix = prefix[i] end
		
		local stem = stems
		if type(stem) == "table" then stem = stem[i] end
		
		for j, ending in ipairs(ends) do
			
			
			if prefix ~= "-" and stem ~= "-" then
				local part = prefix .. stem .. ending
				if ine(part) and part ~= "-"
						
						then
					table.insert(data.forms[pnums[i] .. "-" .. tense], part)
				end
			end
		end
	end
end










function inflect_tense(data, tense, prefixes, stems, endings)
	local pnums = {"1s", "2sm", "2sf", "3sm", "3sf",
				   "2d", "3dm", "3df",
				   "1p", "2pm", "2pf", "3pm", "3pf"}
	inflect_tense_1(data, tense, prefixes, stems, endings, pnums)
end



function inflect_tense_impr(data, stems, endings)
	local pnums = {"2sm", "2sf", "2d", "2pm", "2pf"}
	inflect_tense_1(data, "impr", "", stems, endings, pnums)
end



function insert_part(data, name, value)
	if data.forms[name] == nil then
		data.forms[name] = {}
	end
	
	if type(value) == "table" then
		data.forms[name] = value
	else
		table.insert(data.forms[name], value)
	end
end



function insert_verbal_noun(data, args, vn)
	local vns = args["vn"] and rsplit(args["vn"], "[,،]") or vn
	if type(vns) ~= "table" then
		vns = {vns}
	end
	
	vns.ids = {}
	
	for i = 1, #vns do
		local id = args["vn-id" .. i]
		
		if id then
			vns.ids[i] = id
		end
	end

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	function vntrack(pagesuff)
		track("vn/" .. pagesuff)
		if args["vn"] then
			track("explicit-vn/" .. pagesuff)
		else
			track("auto-vn/" .. pagesuff)
		end
	end

	function track_i3rab(entry, arabic, tr)
		if rfind(entry, arabic .. "$") then
			vntrack("i3rab")
			vntrack("i3rab/" .. tr)
		end
	end

	for _, entry in ipairs(vns) do
		
		
		entry = reorder_shadda(entry)
		track_i3rab(entry, UN, "un")
		track_i3rab(entry, U, "u")
		track_i3rab(entry, IN, "in")
		track_i3rab(entry, I, "i")
		track_i3rab(entry, AN .. "[" .. ALIF .. AMAQ .. "]", "an")
		track_i3rab(entry, AN .. ALIF, "an-tall")
		track_i3rab(entry, A, "a")
		track_i3rab(entry, SK, "sk")
		if not rfind(entry, "[" .. A .. I .. U .. AN .. IN .. UN .. DAGGER_ALIF .. "]$") and
				not rfind(entry, AN .. "[" .. ALIF .. AMAQ .. "]") then
			vntrack("no-i3rab")
		end
		entry = rsub(entry, UNU .. "?$", "")
		
		
		
		local decltype = ar_nominals.detect_type(entry, false, "sg", "noun")
		vntrack("would-be-decl/" .. decltype)
	end
	

	if no_nominal_i3rab then
		vns_no_i3rab = {}
		for _, entry in ipairs(vns) do
			entry = reorder_shadda(entry)
			entry = rsub(entry, UNU .. "?$", "")
			table.insert(vns_no_i3rab, entry)
		end
		if vns.ids then
			vns_no_i3rab.ids = vns.ids
		end
		insert_part(data, "vn", vns_no_i3rab)
	else
		insert_part(data, "vn", vns)
	end
end







function past_2stem_conj(data, tense, v_stem, c_stem)
	inflect_tense(data, tense, "", {
		
		c_stem, c_stem, c_stem, v_stem, v_stem,
		
		c_stem, v_stem, v_stem,
		
		c_stem, c_stem, c_stem, v_stem, c_stem
	}, past_endings)
end



function past_1stem_conj(data, tense, stem)
	past_2stem_conj(data, tense, stem, stem)
end





















function nonpast_2stem_conj(data, tense, prefixes, v_stem, c_stem, endings, jussive)
	if prefixes == "a" then prefixes = nonpast_prefixes_a
	elseif prefixes == "u" then prefixes = nonpast_prefixes_u
	end
	if endings == nil then
		if tense == "impf" or tense == "ps-impf" then
			endings = indic_endings
		elseif tense == "subj" or tense == "ps-subj" then
			endings = subj_endings
		elseif tense == "juss" or tense == "ps-juss" then
			jussive = true
			endings = juss_endings
		else
			error("Unrecognized tense '" .. tense .."'")
		end
	end
	if not jussive then
		inflect_tense(data, tense, prefixes, {
			
			v_stem, v_stem, v_stem, v_stem, v_stem,
			
			v_stem, v_stem, v_stem,
			
			v_stem, v_stem, c_stem, v_stem, c_stem
		}, endings)
	else
		inflect_tense(data, tense, prefixes, {
			
			
			c_stem, c_stem, v_stem, c_stem, c_stem,
			
			
			v_stem, v_stem, v_stem,
			
			
			c_stem, v_stem, c_stem, v_stem, c_stem
		}, endings)
	end
end



function nonpast_1stem_conj(data, tense, prefixes, stem, endings, jussive)
	nonpast_2stem_conj(data, tense, prefixes, stem, stem, endings, jussive)
end





function jussive_gem_conj(data, tense, prefixes, v_stem, c_stem)
	
	nonpast_2stem_conj(data, tense, prefixes, v_stem, c_stem, juss_endings_alt_a)
	
	nonpast_2stem_conj(data, tense, prefixes, v_stem, c_stem, juss_endings_alt_i)
	
	
	
	
	nonpast_2stem_conj(data, tense, prefixes, v_stem, c_stem, juss_endings, "jussive")
end






function make_1stem_imperative(data, stem)
	inflect_tense_impr(data, stem, impr_endings)
end


function make_2stem_imperative(data, v_stem, c_stem)
	inflect_tense_impr(data,
		{c_stem, v_stem, v_stem, v_stem, c_stem}, impr_endings)
end


function make_gem_imperative(data, v_stem, c_stem)
	inflect_tense_impr(data,
		{v_stem, v_stem, v_stem, v_stem, c_stem}, impr_endings_alt_a)
	inflect_tense_impr(data,
		{v_stem, v_stem, v_stem, v_stem, c_stem}, impr_endings_alt_i)
	make_2stem_imperative(data, v_stem, c_stem)
end








function make_sound_verb(data, past_stem, ps_past_stem, nonpast_stem,
		ps_nonpast_stem, imper_stem, prefix_vowel)
	past_1stem_conj(data, "perf", past_stem)
	past_1stem_conj(data, "ps-perf", ps_past_stem)
	nonpast_1stem_conj(data, "impf", prefix_vowel, nonpast_stem)
	nonpast_1stem_conj(data, "subj", prefix_vowel, nonpast_stem)
	nonpast_1stem_conj(data, "juss", prefix_vowel, nonpast_stem)
	nonpast_1stem_conj(data, "ps-impf", "u", ps_nonpast_stem)
	nonpast_1stem_conj(data, "ps-subj", "u", ps_nonpast_stem)
	nonpast_1stem_conj(data, "ps-juss", "u", ps_nonpast_stem)
	make_1stem_imperative(data, imper_stem)
end





function make_final_weak_verb(data, past_stem, ps_past_stem, nonpast_stem,
		ps_nonpast_stem, imper_stem, past_suffs, indic_suffs,
		subj_suffs, juss_suffs, impr_suffs, prefix_vowel)
	inflect_tense(data, "perf", "", past_stem, past_suffs)
	inflect_tense(data, "ps-perf", "", ps_past_stem, past_endings_ii)
	nonpast_1stem_conj(data, "impf", prefix_vowel, nonpast_stem, indic_suffs)
	nonpast_1stem_conj(data, "subj", prefix_vowel, nonpast_stem, subj_suffs)
	nonpast_1stem_conj(data, "juss", prefix_vowel, nonpast_stem, juss_suffs)
	nonpast_1stem_conj(data, "ps-impf", "u", ps_nonpast_stem, indic_endings_aa)
	nonpast_1stem_conj(data, "ps-subj", "u", ps_nonpast_stem, subj_endings_aa)
	nonpast_1stem_conj(data, "ps-juss", "u", ps_nonpast_stem, juss_endings_aa)
	inflect_tense_impr(data, imper_stem, impr_suffs)
end





function make_augmented_final_weak_verb(data, past_stem, ps_past_stem,
		nonpast_stem, ps_nonpast_stem, imper_stem, prefix_vowel, form56)
	make_final_weak_verb(data, past_stem, ps_past_stem, nonpast_stem,
		ps_nonpast_stem, imper_stem, past_endings_ay,
		form56 and indic_endings_aa or indic_endings_ii,
		form56 and subj_endings_aa or subj_endings_ii,
		form56 and juss_endings_aa or juss_endings_ii,
		form56 and impr_endings_aa or impr_endings_ii,
		prefix_vowel)
end











function make_augmented_sound_final_weak_verb(data, args, rad3,
		past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)

	insert_verbal_noun(data, args, vn)

	local final_weak = rad3 == nil
	local prefix_vowel = prefix_vowel_from_form(form)
	local form56 = form_nonpast_a_vowel(form)
	local a_base_suffix = final_weak and "" or A .. rad3
	local i_base_suffix = final_weak and "" or I .. rad3

	
	local past_stem = past_stem_base .. a_base_suffix
	
	
	
	
	
	
	
	local nonpast_stem = nonpast_stem_base ..
		(form56 and a_base_suffix or i_base_suffix)
	local ap_stem = nonpast_stem_base .. i_base_suffix
	local ps_past_stem = ps_past_stem_base .. i_base_suffix
	local ps_nonpast_stem = nonpast_stem_base .. a_base_suffix
	
	local imper_stem = past_stem_base ..
		(form56 and a_base_suffix or i_base_suffix)

	
	if final_weak then
		make_augmented_final_weak_verb(data, past_stem, ps_past_stem, nonpast_stem,
			ps_nonpast_stem, imper_stem, prefix_vowel, form56)
	else
		make_sound_verb(data, past_stem, ps_past_stem, nonpast_stem,
			ps_nonpast_stem, imper_stem, prefix_vowel)
	end

	
	if final_weak then
		insert_part(data, "ap", MU .. ap_stem .. IN)
		insert_part(data, "pp", MU .. ps_nonpast_stem .. AN .. AMAQ)
	else
		insert_part(data, "ap", MU .. ap_stem .. UNS)
		insert_part(data, "pp", MU .. ps_nonpast_stem .. UNS)
	end
end





function make_hollow_geminate_verb(data, past_v_stem, past_c_stem, ps_past_v_stem,
	ps_past_c_stem, nonpast_v_stem, nonpast_c_stem, ps_nonpast_v_stem,
	ps_nonpast_c_stem, imper_v_stem, imper_c_stem, prefix_vowel, geminate)
	past_2stem_conj(data, "perf", past_v_stem, past_c_stem)
	past_2stem_conj(data, "ps-perf", ps_past_v_stem, ps_past_c_stem)
	nonpast_2stem_conj(data, "impf", prefix_vowel, nonpast_v_stem, nonpast_c_stem)
	nonpast_2stem_conj(data, "subj", prefix_vowel, nonpast_v_stem, nonpast_c_stem)
	nonpast_2stem_conj(data, "ps-impf", "u", ps_nonpast_v_stem, ps_nonpast_c_stem)
	nonpast_2stem_conj(data, "ps-subj", "u", ps_nonpast_v_stem, ps_nonpast_c_stem)
	if geminate then
		jussive_gem_conj(data, "juss", prefix_vowel, nonpast_v_stem, nonpast_c_stem)
		jussive_gem_conj(data, "ps-juss", "u", ps_nonpast_v_stem, ps_nonpast_c_stem)
		make_gem_imperative(data, imper_v_stem, imper_c_stem)
	else
		nonpast_2stem_conj(data, "juss", prefix_vowel, nonpast_v_stem, nonpast_c_stem)
		nonpast_2stem_conj(data, "ps-juss", "u", ps_nonpast_v_stem, ps_nonpast_c_stem)
		make_2stem_imperative(data, imper_v_stem, imper_c_stem)
	end
end











function make_augmented_hollow_verb(data, args, rad3,
	past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)
	insert_verbal_noun(data, args, vn)

	local form410 = form == "IV" or form == "X"
	local prefix_vowel = prefix_vowel_from_form(form)

	local a_base_suffix_v, a_base_suffix_c
	local i_base_suffix_v, i_base_suffix_c

	a_base_suffix_v = AA .. rad3         
	a_base_suffix_c = A .. rad3      
	i_base_suffix_v = II .. rad3         
	i_base_suffix_c = I .. rad3      

	
	
	local past_v_stem = past_stem_base .. a_base_suffix_v
	local past_c_stem = past_stem_base .. a_base_suffix_c
	
	local nonpast_v_stem = nonpast_stem_base ..
		(form410 and i_base_suffix_v or a_base_suffix_v)
	local nonpast_c_stem = nonpast_stem_base ..
		(form410 and i_base_suffix_c or a_base_suffix_c)
	local ps_past_v_stem = ps_past_stem_base .. i_base_suffix_v
	local ps_past_c_stem = ps_past_stem_base .. i_base_suffix_c
	local ps_nonpast_v_stem = nonpast_stem_base .. a_base_suffix_v
	local ps_nonpast_c_stem = nonpast_stem_base .. a_base_suffix_c

	
	local imper_v_stem = past_stem_base ..
		(form410 and i_base_suffix_v or a_base_suffix_v)
	local imper_c_stem = past_stem_base ..
		(form410 and i_base_suffix_c or a_base_suffix_c)

	
	make_hollow_geminate_verb(data, past_v_stem, past_c_stem, ps_past_v_stem,
		ps_past_c_stem, nonpast_v_stem, nonpast_c_stem, ps_nonpast_v_stem,
		ps_nonpast_c_stem, imper_v_stem, imper_c_stem, prefix_vowel, false)

	
	insert_part(data, "ap", MU .. nonpast_v_stem .. UNS)
	
	insert_part(data, "pp", MU .. ps_nonpast_v_stem .. UNS)
end













function make_augmented_geminate_verb(data, args, rad3,
	past_stem_base, nonpast_stem_base, ps_past_stem_base, vn, form)
	insert_verbal_noun(data, args, vn)

	local prefix_vowel = prefix_vowel_from_form(form)

	local a_base_suffix_v, a_base_suffix_c
	local i_base_suffix_v, i_base_suffix_c

	if form == "IV" or form == "X" or form == "IVq" then
		a_base_suffix_v = A .. rad3 .. SH         
		a_base_suffix_c = SK .. rad3 .. A .. rad3  
		i_base_suffix_v = I .. rad3 .. SH         
		i_base_suffix_c = SK .. rad3 .. I .. rad3  
	else
		a_base_suffix_v = rad3 .. SH         
		a_base_suffix_c = rad3 .. A .. rad3  
		i_base_suffix_v = rad3 .. SH         
		i_base_suffix_c = rad3 .. I .. rad3  
	end

	
	
	local past_v_stem = past_stem_base .. a_base_suffix_v
	local past_c_stem = past_stem_base .. a_base_suffix_c
	local nonpast_v_stem = nonpast_stem_base ..
		(form_nonpast_a_vowel(form) and a_base_suffix_v or i_base_suffix_v)
	local nonpast_c_stem = nonpast_stem_base ..
		(form_nonpast_a_vowel(form) and a_base_suffix_c or i_base_suffix_c)
	
	
	local ps_past_v_stem = (form == "III" or form == "VI") and "-" or
		ps_past_stem_base .. i_base_suffix_v
	local ps_past_c_stem = ps_past_stem_base .. i_base_suffix_c
	local ps_nonpast_v_stem = nonpast_stem_base .. a_base_suffix_v
	local ps_nonpast_c_stem = nonpast_stem_base .. a_base_suffix_c

	
	local imper_v_stem = past_stem_base ..
		(form_nonpast_a_vowel(form) and a_base_suffix_v or i_base_suffix_v)
	local imper_c_stem = past_stem_base ..
		(form_nonpast_a_vowel(form) and a_base_suffix_c or i_base_suffix_c)

	
	make_hollow_geminate_verb(data, past_v_stem, past_c_stem, ps_past_v_stem,
		ps_past_c_stem, nonpast_v_stem, nonpast_c_stem, ps_nonpast_v_stem,
		ps_nonpast_c_stem, imper_v_stem, imper_c_stem, prefix_vowel,
		"duplázott")

	
	insert_part(data, "ap", MU .. nonpast_v_stem .. UNS)
	
	insert_part(data, "pp", MU .. ps_nonpast_v_stem .. UNS)
end







local postprocess_subs = {
	
	{"(" .. AIU .. ")" .. SH, SH .. "%1"},

	
	
	{"(.)" .. SK .. "%1", "%1" .. SH},

	
	
	{I .. W .. SK, II},
	{I .. Y .. SK, II},
	
	{U .. W .. SK, UU},
	{U .. Y .. SK, UU},

    
	{"(" .. Y ..  SH .. "?" .. A .. ")" .. AMAQ, "%1" .. ALIF},

	
	
	{HAMZA .. A .. HAMZA .. SK, HAMZA .. A .. ALIF},
	{HAMZA .. I .. HAMZA .. SK, HAMZA .. I .. Y},
	{HAMZA .. U .. HAMZA .. SK, HAMZA .. U .. W}
}






function postprocess_term(term)
	
	if term == "-" or term == "–" or term == "—" then
		return {"—"} 
	elseif term == "?" then
		return {"?"}
	end
	
	
	for _, sub in ipairs(postprocess_subs) do
		term = rsub(term, sub[1], sub[2])
	end

	if not rfind(term, HAMZA) then
		return {term}
	end
	term = rsub(term, HAMZA, HAMZA_PH)
	return ar_utilities.process_hamza(term)
end




function get_spans(part)
	if type(part) == "string" then
		part = {part}
	end
	local part_nondup = {}
	
	
	
	for _, entry in ipairs(part) do
		for _, e in ipairs(postprocess_term(entry)) do
			insert_if_not(part_nondup, e)
		end
	end
	
	local arabic_spans = {}
	local latin_spans = {}
	for _, entry in ipairs(part_nondup) do
		table.insert(arabic_spans, entry)
		if entry ~= "—" and entry ~= "?" then
			
			
			insert_if_not(latin_spans, ar_translit.tr(entry, nil, nil, nil))
		end
	end
	return arabic_spans, latin_spans
end


function make_table(data, title, form, intrans)

	local forms = data.forms
	local arabic_spans_3sm_perf, _
	if data.passive == "only" or data.passive == "only-impers" then
		arabic_spans_3sm_perf, _ = get_spans(forms["3sm-ps-perf"])
	else
		arabic_spans_3sm_perf, _ = get_spans(forms["3sm-perf"])
	end
	
	for i, entry in ipairs(arabic_spans_3sm_perf) do
		arabic_spans_3sm_perf[i] = "<b lang=\"ar\" class=\"Arab\">" .. entry .. "</b>"
	end
	
	local part_3sm_perf = '<div style="display: inline-block">' ..
		table.concat(arabic_spans_3sm_perf, " <small style=\"color: #888\">or</small> ") .. "</div>"

	
	local num_vns = type(forms["vn"]) == "table" and #forms["vn"] or 1

	
	
	local vn_spans, _ = get_spans(forms["vn"])
	
	for i, entry in ipairs(vn_spans) do
		vn_spans[i] = '<span lang="ar" class="Arab" style="font-weight: normal">' .. entry .. '</span>'
	end
	local vn_list = #vn_spans == 0 and "?" or
		table.concat(vn_spans, " <small style=\"color: #888\">vagy</small> ")
	local vn_prefix = #vn_spans > 1 and "igéből képzett főnevek" or "igéből képzett főnév"
	local vn_text = vn_prefix .. " " .. vn_list

	
	local title =  part_3sm_perf .. ' ragozása' 
		.. (form == "I" and " (" .. title .. ", " .. vn_text .. ")" or " (" .. title .. ")")

	
	for key, part in pairs(forms) do
		
		if part and #part > 0 then
			local arabic_spans, latin_spans = get_spans(part)
			
			for i, entry in ipairs(arabic_spans) do
				local id
				if part.ids then
					id = part.ids[i]
				end
				
				arabic_spans[i] = links(entry, nil, id)
			end
			
			for i, translit in ipairs(latin_spans) do
				latin_spans[i] = require("Module:script utilities").tag_translit(translit, lang, "default")
			end
			
			
			forms[key] = '<div style="display: inline-block">' .. table.concat(arabic_spans, " <small style=\"color: #888\">or</small> ") .. "</div>" .. "<br/>" ..
				"<span style=\"color: #888\">" .. table.concat(latin_spans, " <small>or</small> ") .. "</span>"
		
		
		
		
		
		elseif key == "vn" then
			forms[key] = "?"
		else
			forms[key] = "—"
		end
	end

	local text = [=[<div class="NavFrame mw-collapsible mw-collapsed ar-conj">
<div class="NavHead" style="text-align:left; height:2.5em;">]=] .. title  .. [=[</div>
<div class="NavContent mw-collapsible-content">

{| class="inflection-table"
|-
! colspan="6" class="nonfinite-header" | igéből képzett ]=] .. (num_vns > 1 and "főnevek" or "főnév") .. "<br />" .. tag_text(num_vns > 1 and "الْمَصَادِر" or "الْمَصْدَر") .. [=[

| colspan="7" | {{{vn}}}
]=]

	if data.passive ~= "only" and data.passive ~= "only-impers" then
		text = text .. [=[
|-
! colspan="6" class="nonfinite-header" | aktív melléknévi igenév<br />{{{اِسْم الْفَاعِل}}}
| colspan="7" | {{{ap}}}
]=]
	end

	if data.passive then
		text = text .. [=[
|-
! colspan="6" class="nonfinite-header" | passzív melléknévi igenév<br />{{{اِسْم الْمَفْعُول}}}
| colspan="7" | {{{pp}}}
]=]
	end

	if data.passive ~= "only" and data.passive ~= "only-impers" then
		text = text .. [=[
|-
! colspan="12" class="voice-header" | aktív<br />{{{الْفِعْل الْمَعْلُوم}}}
|-
! colspan="2" class="empty-header" | 
! colspan="3" class="number-header" | egyes szám<br />{{{الْمُفْرَد}}}
! rowspan="12" class="divider" | 
! colspan="2" class="number-header" | kettes szám<br />{{{الْمُثَنَّى}}}
! rowspan="12" class="divider" | 
! colspan="3" class="number-header" | többes szám<br />{{{الْجَمْع}}}
|-
! colspan="2" class="empty-header" | 
! class="person-header" | 1. személy<br />{{{الْمُتَكَلِّم}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
! class="person-header" | 1. személy<br />{{{الْمُتَكَلِّم}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
|-
! rowspan="2" class="tam-header" | múlt (befejezett) kijelentő mód<br />{{{الْمَاضِي}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-perf}}}
| {{{2sm-perf}}}
| {{{3sm-perf}}}
| rowspan="2" | {{{2d-perf}}}
| {{{3dm-perf}}}
| rowspan="2" | {{{1p-perf}}}
| {{{2pm-perf}}}
| {{{3pm-perf}}}
|-
! class="gender-header" | nőnem
| {{{2sf-perf}}}
| {{{3sf-perf}}}
| {{{3df-perf}}}
| {{{2pf-perf}}}
| {{{3pf-perf}}}
|-
! rowspan="2" class="tam-header" | nem-múlt (folyamatos) kijelentő mód<br />{{{الْمُضَارِع}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-impf}}}
| {{{2sm-impf}}}
| {{{3sm-impf}}}
| rowspan="2" | {{{2d-impf}}}
| {{{3dm-impf}}}
| rowspan="2" | {{{1p-impf}}}
| {{{2pm-impf}}}
| {{{3pm-impf}}}
|-
! class="gender-header" | nőnem
| {{{2sf-impf}}}
| {{{3sf-impf}}}
| {{{3df-impf}}}
| {{{2pf-impf}}}
| {{{3pf-impf}}}
|-
! rowspan="2" class="tam-header" | kötőmód<br />{{{الْمُضَارِع الْمَنْصُوب}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-subj}}}
| {{{2sm-subj}}}
| {{{3sm-subj}}}
| rowspan="2" | {{{2d-subj}}}
| {{{3dm-subj}}}
| rowspan="2" | {{{1p-subj}}}
| {{{2pm-subj}}}
| {{{3pm-subj}}}
|-
! class="gender-header" | nőnem
| {{{2sf-subj}}}
| {{{3sf-subj}}}
| {{{3df-subj}}}
| {{{2pf-subj}}}
| {{{3pf-subj}}}
|-
! rowspan="2" class="tam-header" | parancsolómód<br />{{{الْمُضَارِع الْمَجْزُوم}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-juss}}}
| {{{2sm-juss}}}
| {{{3sm-juss}}}
| rowspan="2" | {{{2d-juss}}}
| {{{3dm-juss}}}
| rowspan="2" | {{{1p-juss}}}
| {{{2pm-juss}}}
| {{{3pm-juss}}}
|-
! class="gender-header" | nőnem
| {{{2sf-juss}}}
| {{{3sf-juss}}}
| {{{3df-juss}}}
| {{{2pf-juss}}}
| {{{3pf-juss}}}
|-
! rowspan="2" class="tam-header" | felszólítómód<br />{{{الْأَمْر}}}
! class="gender-header" | hímnem
| rowspan="2" | 
| {{{2sm-impr}}}
| rowspan="2" | 
| rowspan="2" | {{{2d-impr}}}
| rowspan="2" | 
| rowspan="2" | 
| {{{2pm-impr}}}
| rowspan="2" | 
|-
! class="gender-header" | nőnem
| {{{2sf-impr}}}
| {{{2pf-impr}}}
]=]
	end

	if data.passive == "impers" or data.passive == "only-impers" then
		text = text .. [=[
|-
! colspan="12" class="voice-header" | passzív<br />{{{الْفِعْل الْمَجْهُول}}}
|-
| colspan="2" class="empty-header" | 
! colspan="3" class="number-header" | egyes szám<br />{{{الْمُفْرَد}}}
| rowspan="10" class="divider" | 
! colspan="2" class="number-header" | kettes szám<br />{{{الْمُثَنَّى}}}
| rowspan="10" class="divider" | 
! colspan="3" class="number-header" | többes szám<br />{{{الْجَمْع}}}
|-
| colspan="2" class="empty-header" | 
! class="person-header" | 1. személy<br />{{{الْمُتَكَلِّم}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
! class="person-header" | 1. személy<br />{{{الْمُتَكَلِّم}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
|-
! rowspan="2" class="tam-header" | múlt (befejezett) kijelentő mód<br />{{{الْمَاضِي}}}
! class="gender-header" | hímnem
| rowspan="2" | &mdash;
| &mdash;
| {{{3sm-ps-perf}}}
| rowspan="2" | &mdash;
| &mdash;
| rowspan="2" | &mdash;
| &mdash;
| &mdash;
|-
! class="gender-header" | nőnem
| &mdash;
| &mdash;
| &mdash;
| &mdash;
| &mdash;
|-
! rowspan="2" class="tam-header" | nem-múlt (folyamatos) kijelentő mód<br />{{{الْمُضَارِع}}}
! class="gender-header" | hímnem
| rowspan="2" | &mdash;
| &mdash;
| {{{3sm-ps-impf}}}
| rowspan="2" | &mdash;
| &mdash;
| rowspan="2" | &mdash;
| &mdash;
| &mdash;
|-
! class="gender-header" | nőnem
| &mdash;
| &mdash;
| &mdash;
| &mdash;
| &mdash;
|-
! rowspan="2" class="tam-header" | kötőmód<br />{{{الْمُضَارِع الْمَنْصُوب}}}
! class="gender-header" | hímnem
| rowspan="2" | &mdash;
| &mdash;
| {{{3sm-ps-subj}}}
| rowspan="2" | &mdash;
| &mdash;
| rowspan="2" | &mdash;
| &mdash;
| &mdash;
|-
! class="gender-header" | nőnem
| &mdash;
| &mdash;
| &mdash;
| &mdash;
| &mdash;
|-
! rowspan="2" class="tam-header" | parancsolómód<br />{{{الْمُضَارِع الْمَجْزُوم}}}
! class="gender-header" | hímnem
| rowspan="2" | &mdash;
| &mdash;
| {{{3sm-ps-juss}}}
| rowspan="2" | &mdash;
| &mdash;
| rowspan="2" | &mdash;
| &mdash;
| &mdash;
|-
! class="gender-header" | nőnem
| &mdash;
| &mdash;
| &mdash;
| &mdash;
| &mdash;
]=]

	elseif data.passive then
		text = text .. [=[
|-
! colspan="12" class="voice-header" | passzív<br />{{{الْفِعْل الْمَجْهُول}}}
|-
| colspan="2" class="empty-header" | 
! colspan="3" class="number-header" | egyes szám<br />{{{الْمُفْرَد}}}
| rowspan="10" class="divider" | 
! colspan="2" class="number-header" | kettes szám<br />{{{الْمُثَنَّى}}}
| rowspan="10" class="divider" | 
! colspan="3" class="number-header" | többes szám<br />{{{الْجَمْع}}}
|-
| colspan="2" class="empty-header" | 
! class="person-header" | 1. személy<br />{{{الْمُتَكَلِّم}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
! class="person-header" | 1. személy<br />{{{الْمُتَكَلِّم}}}
! class="person-header" | 2. személy<br />{{{الْمُخَاطَب}}}
! class="person-header" | 3. személy<br />{{{الْغَائِب}}}
|-
! rowspan="2" class="tam-header" | múlt (befejezett) kijelentő mód<br />{{{الْمَاضِي}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-ps-perf}}}
| {{{2sm-ps-perf}}}
| {{{3sm-ps-perf}}}
| rowspan="2" | {{{2d-ps-perf}}}
| {{{3dm-ps-perf}}}
| rowspan="2" | {{{1p-ps-perf}}}
| {{{2pm-ps-perf}}}
| {{{3pm-ps-perf}}}
|-
! class="gender-header" | nőnem
| {{{2sf-ps-perf}}}
| {{{3sf-ps-perf}}}
| {{{3df-ps-perf}}}
| {{{2pf-ps-perf}}}
| {{{3pf-ps-perf}}}
|-
! rowspan="2" class="tam-header" | nem-múlt (folyamatos) kijelentő mód<br />{{{الْمُضَارِع}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-ps-impf}}}
| {{{2sm-ps-impf}}}
| {{{3sm-ps-impf}}}
| rowspan="2" | {{{2d-ps-impf}}}
| {{{3dm-ps-impf}}}
| rowspan="2" | {{{1p-ps-impf}}}
| {{{2pm-ps-impf}}}
| {{{3pm-ps-impf}}}
|-
! class="gender-header" | nőnem
| {{{2sf-ps-impf}}}
| {{{3sf-ps-impf}}}
| {{{3df-ps-impf}}}
| {{{2pf-ps-impf}}}
| {{{3pf-ps-impf}}}
|-
! rowspan="2" class="tam-header" | kötőmód<br />{{{الْمُضَارِع الْمَنْصُوب}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-ps-subj}}}
| {{{2sm-ps-subj}}}
| {{{3sm-ps-subj}}}
| rowspan="2" | {{{2d-ps-subj}}}
| {{{3dm-ps-subj}}}
| rowspan="2" | {{{1p-ps-subj}}}
| {{{2pm-ps-subj}}}
| {{{3pm-ps-subj}}}
|-
! class="gender-header" | nőnem
| {{{2sf-ps-subj}}}
| {{{3sf-ps-subj}}}
| {{{3df-ps-subj}}}
| {{{2pf-ps-subj}}}
| {{{3pf-ps-subj}}}
|-
! rowspan="2" class="tam-header" | parancsolómód<br />{{{الْمُضَارِع الْمَجْزُوم}}}
! class="gender-header" | hímnem
| rowspan="2" | {{{1s-ps-juss}}}
| {{{2sm-ps-juss}}}
| {{{3sm-ps-juss}}}
| rowspan="2" | {{{2d-ps-juss}}}
| {{{3dm-ps-juss}}}
| rowspan="2" | {{{1p-ps-juss}}}
| {{{2pm-ps-juss}}}
| {{{3pm-ps-juss}}}
|-
! class="gender-header" | nőnem
| {{{2sf-ps-juss}}}
| {{{3sf-ps-juss}}}
| {{{3df-ps-juss}}}
| {{{2pf-ps-juss}}}
| {{{3pf-ps-juss}}}
]=]
	end

	text = text .. [=[
|}
</div>
</div>]=]

	
	
	
	
	local function repl(param)
		if rfind(param, "^[A-Za-z0-9_-]+$") then
			return data.forms[param]
		else
			return tag_text(param)
		end
	end

	return rsub(text, "{{{([^{}]+)}}}", repl)
		.. mw.getCurrentFrame():extensionTag{
			name = "templatestyles", args = { src = "Template:ar-conj/style.css" }
		}
end

return export