-- This is a data module for [[Module:sa-verb]].

local conj_data = {}

local sa_utils = require("Module:sa-utilities")
local to_IAST = require("Module:sa-utilities/translit/SLP1-to-IAST").tr
local to_SLP = require("Module:sa-utilities/translit/IAST-to-SLP1").tr

local sub = mw.ustring.sub
local gsub = mw.ustring.gsub
local gasub = string.gsub -- For when byte by byte comparison is good enough.
local match = mw.ustring.match
local split = mw.text.split

-- Returns { form, stem } if the stem is explicity provided in the form (i.e. form = "riṇakti<riṇac>" or form = "rincanti<riñc>")
local function split_xs(form)
    if form == nil then
        return nil
    end
    local s = split(form, "<")
    if s[2] ~= nil then
        local sanitized_s2 = sub(s[2], 1, -2)
        return {s[1], sanitized_s2}
    else
        return {form, nil}
    end
end

-- Splits "stem1,stem2" into { stem1, stem2 }
local function split_stems(form)
    -- TODO: in the older system, we'd have entries where multiple stems could be supplied and show up side-by-side in the same table.
    -- I.e. "áricat" and "áraikṣīt" as two aorist variants of "riṇakti". The current system is to make them both separate entries altogether
    -- so their conjugation systems don't overlap and cause confusion.
    -- Older entries using the older version of this module need to be updated—right now, any extra stems that are supplied are just ignored
    -- Note: this doesn't affect manually provided forms, like irregular third-person singular active perfects having long/short-vowel forms
	return split(form, ",")[1]
end

local function apply_ending(args, data, tag, stem, es, is_part)
    if type(es) == "string" then
        es = {es}
    end
    local forms = data.forms[tag] or {}
    local i = #forms + 1
    for _, e in ipairs(es) do
        local note
        if type(e) == "table" then
            note = e.note
            e = e[1]
        end
		
		-- reduce Vedic forms to zero in case of novedic parameter
		if args.novedic == true and note and match(note, "[vV]edic$") then
			stem = ""; e = ""; note = ""
		else
			args.has_accent = match(stem, sa_utils.accent)
			local set_stem = stem
			-- if 'set', add 'i' between consonants, except before 'y' (optative)
        	if args.set == true and match(stem, sa_utils.consonant .. "$") and match(e, "^[tTDmrvshQz]") then 
        	    set_stem = sa_utils.internal_sandhi({
    	            stem = stem,
                	ending = "i",
            	    has_accent = args.has_accent,
        	        non_final = true,
    	            mono = args.mono,
    	            accent_override = args.accent_override,
    	            no_retroflex_root_s = args.no_retroflex_root_s
            	})
        	end
			
        	if args.auto_sandhi == true then
            	forms[i] = sa_utils.internal_sandhi({
                	stem = set_stem,
            	    ending = e,
					has_accent = args.has_accent,
                	non_final = is_part,
            	    mono = args.mono,
        	        j_to_z = args.j_to_z,
                	h_to_g = args.h_to_g,
                	ambig_final = args.ambig_final,
					diaspirate = args.diaspirate,
					no_syncope = args.no_syncope,
					accent_override = args.accent_override,
					no_retroflex_root_s = args.no_retroflex_root_s -- for roots 'pis'/'niṃs'/'hiṃs' and 'tresur' from 'tras')
            	})
        	else
            	forms[i] = set_stem .. e
        	end
			-- Apply special tagging, currently just Ⓛ.
			forms[i] = gasub(forms[i],
				"a("..sa_utils.accent.."?)("..sa_utils.consonant.."a)Ⓛ", "A%1%2")
			forms[i] = gasub(forms[i], "Ⓛ", "") -- Clean up.
			
        	if note then
            	forms["note" .. i] = note
        	end
        	i = i + 1
        end
    end
    data.forms[tag] = forms
end

local function make_forms(args, data, stem, forms)
    for mood, mood_forms in pairs(forms) do
    	if args.tense == "nonf" then
    		local tag = mood
    		apply_ending(args, data, tag, stem, mood_forms, false)
    	else
	        for voice, voice_forms in pairs(mood_forms) do
	            if mood == "part" then
	                local tag = mood .. "_" .. voice
	                apply_ending(args, data, tag, stem, voice_forms, true)
	            else
	                for person_number, es in pairs(voice_forms) do
	                    local tag = mood .. "_" .. voice .. "_" .. person_number
	                    apply_ending(args, data, tag, stem, es, false)
	                end
	            end
	        end
        end
    end
end

local function validate(stem, lemma)
    if stem == nil then
        error("could not detect stem from " .. to_IAST(lemma) .. "; set args.o to fill in values manually")
    end
end

local function detect(t, lemma, match_pattern, oxy_match_pattern, strong)
    local prefix = "weak_"
    if strong then prefix = "strong_" end

    if not t[prefix .. "did_lemma"] then
        lemma = split_stems(lemma)
        local splitted = split_xs(lemma)
        if splitted == nil then return nil end
        t[prefix .. "3s"] = splitted[1]

        t[prefix .. "stem"] = splitted[2]
        t[prefix .. "oxy"] = ""
        t[prefix .. "did_lemma"] = true
    end

    local detected_stem = match(t[prefix .. "3s"], match_pattern)
    if detected_stem ~= nil then
        if oxy_match_pattern ~= nil then
            t[prefix .. "oxy"] = match(t[prefix .. "3s"], oxy_match_pattern)
        end
        if t[prefix .. "stem"] == nil then
            t[prefix .. "stem"] = detected_stem
        end
        return true
    end
    return false
end

local function detect_strong(t, lemma, match_pattern, oxy_match_pattern)
    return detect(t, lemma, match_pattern, oxy_match_pattern, true)
end

local function detect_weak(t, lemma, match_pattern, oxy_match_pattern)
    return detect(t, lemma, match_pattern, oxy_match_pattern, false)
end

local function use_strong_for_weak(t, weak_lemma)
    if weak_lemma ~= nil then return false end
    t["weak_stem"] = t["strong_stem"]
    t["weak_oxy"] = t["strong_oxy"]
    return true
end

 -- Only for verbs with 3p on -ati, override with 'class=' parameter.
 -- Does not detect 'iyāy' and 'alar' (Whitney §1002e).
local function detect_intensive(args, t)
	-- anchoring detection pattern at the end to allow for prefixes
	if match(t.strong_stem, sa_utils.consonant.."a/?[nrlv][iI]"..sa_utils.consonant.."+"..sa_utils.vowel.."M?"..sa_utils.consonant.."*$") then
		if match(t.strong_stem, "vivy?"..sa_utils.vowel..sa_utils.consonant.."$") then
			-- prefixed class 3 verb like 'upaviveṣṭi'
			return false
		else
			-- dissyllabic reduplication
			return true
		end
	elseif match(t.strong_stem, sa_utils.consonant.."[Aeo]/?"..sa_utils.consonant.."+"..sa_utils.vowel_with_accent.."M?"..sa_utils.consonant.."*$") 
	or match(t.strong_stem, sa_utils.consonant.."a/?[rlNYRnmMd]"..sa_utils.consonant.."+[aiufx]M?"..sa_utils.consonant.."*$")  -- avoiding 'saṃśās'
	or args.class == "int" then
		t["intensive"] = "1"
		return true
	end
end

local function change_to_inj_strong(args, t)
	if args.inj_strong_stem then
		t["inj_strong"] = "1"
		t.inj_strong_stem = to_SLP(args.inj_strong_stem)
		return true
	elseif match(t.strong_stem, "^a/?"..sa_utils.consonant.."+"..sa_utils.vowel.."M?"..sa_utils.consonant.."*$") then
		t["inj_strong"] = "2"
		t.inj_strong_stem = gasub(t.strong_stem, "^a(/?)("..sa_utils.consonant.."+"
            ..sa_utils.vowel..")(M?"..sa_utils.consonant.."*)$", "%2%1%3")
        t.inj_strong_stem = gasub(t.inj_strong_stem, "c(C.+)$", "%1")
		return true
	end
end

-- for a- and sa-aorist (+ reduplicated)
local function change_to_inj_strong_oxy(args, t)
	if args.inj_strong_stem then
		t["inj_strong"] = "1"
		t.inj_strong_stem = to_SLP(args.inj_strong_stem)
		t.inj_strong_oxy = gasub(t.strong_stem, "^[^/]+(/?).+$", "%1")
		return true
	elseif match(t.strong_stem, "^a/?"..sa_utils.consonant.."+"..sa_utils.vowel.."M?"..sa_utils.consonant.."*$") then
		t["inj_strong"] = "2"
		if match(t.strong_stem, "^a/?[sk]ar$") or match(t.strong_stem, "^a/?sa[dn]$") then -- Whitney §853
			t.inj_strong_stem = gasub(t.strong_stem, "^a(/?)("..sa_utils.consonant.."a)("..sa_utils.consonant..")$", "%2%1%3")
			t.inj_strong_oxy = ""
		else
			t.inj_strong_stem = gasub(t.strong_stem, "^a/?(.+)$", "%1")
        	t.inj_strong_oxy = gasub(t.strong_stem, "^a(/?).+$", "%1")
		end
    	t.inj_strong_stem = gasub(t.inj_strong_stem, "c(C.+)$", "%1")
		return true
	-- also look for reduplicated aorists
	elseif match(t.strong_stem, "^a/?"..sa_utils.consonant.."[IUaiu]"..sa_utils.consonant.."+"..sa_utils.vowel.."M?"..sa_utils.consonant.."+$") then
		t["inj_strong"] = "3"
		t.inj_strong_stem = gasub(t.strong_stem, "^a/?(.+)$", "%1")
		t.inj_strong_oxy = ""  -- for now giving no accent as the position isn't fully clear, see Whitney §869c
		return true
	end
end

local function change_to_inj_weak(args, t)
    if args.inj_weak_stem then
        t["inj_weak"] = "1"
        t.inj_weak_stem = to_SLP(args.inj_weak_stem)
        return true
	-- sometimes no vowel in weak root aorist stem
	elseif match(t.weak_stem, "^a/?"..sa_utils.consonant.."+"..sa_utils.vowel.."?M?"..sa_utils.consonant.."*$") then
		t["inj_weak"] = "2"
		t.inj_weak_stem = gasub(t.weak_stem, "^a(/?)("..sa_utils.consonant.."+"
			..sa_utils.vowel..")(M?"..sa_utils.consonant.."*)$", "%2%1%3")
		t.inj_weak_stem = gasub(t.inj_weak_stem, "c(C.+)$", "%1")
		return true
	end
end

local function change_to_inj_weak_oxy(args, t)
    if args.inj_weak_stem then
        t["inj_weak"] = "1"
        t.inj_weak_stem = to_SLP(args.inj_weak_stem)
        t.inj_weak_oxy = gasub(t.weak_stem, "^[^/]+(/?).+$", "%1")
        return true
	-- sometimes no vowel in weak root aorist stem
	elseif match(t.weak_stem, "^a/?"..sa_utils.consonant.."+"..sa_utils.vowel.."?M?"..sa_utils.consonant.."*$") then
		t["inj_weak"] = "2"
		t.inj_weak_stem = gasub(t.weak_stem, "^a/?(.+)$", "%1")
		t.inj_weak_stem = gasub(t.inj_weak_stem, "c(C.+)$", "%1")
        t.inj_weak_oxy = gasub(t.weak_stem, "^a(/?).+$", "%1")
		return true
	end
end

conj_data["pres"] = {}
setmetatable(conj_data["pres"], {
    __call = function (self, args, data)
        local make_thematic_forms = function (oxy)
            return {
                ["indic"] = {
                    ["av"] = {
                        ["1_s"] = "A" .. oxy .. "mi",
                        ["2_s"] = "a" .. oxy .. "si",
                        ["3_s"] = "a" .. oxy .. "ti",
                        ["1_d"] = "A" .. oxy .. "vas",
                        ["2_d"] = "a" .. oxy .. "Tas",
                        ["3_d"] = "a" .. oxy .. "tas",
                        ["1_p"] = {"A" .. oxy .. "mas", {"A" .. oxy .. "masi", note = "Vedic"}},
                        ["2_p"] = "a" .. oxy .. "Ta",
                        ["3_p"] = "a" .. oxy .. "nti"
                    },
                    ["mv"] = {
                        ["1_s"] = "e" .. oxy,
                        ["2_s"] = "a" .. oxy .. "se",
                        ["3_s"] = "a" .. oxy .. "te",
                        ["1_d"] = "A" .. oxy .. "vahe",
                        ["2_d"] = "e" .. oxy .. "Te",
                        ["3_d"] = "e" .. oxy .. "te",
                        ["1_p"] = "A" .. oxy .. "mahe",
                        ["2_p"] = "a" .. oxy .. "Dve",
                        ["3_p"] = "a" .. oxy .. "nte"
                    }
                },
                ["imper"] = {
                    ["av"] = {
                        ["1_s"] = "A" .. oxy .. "ni",
--                        ["2_s"] = {"a" .. oxy, "a" .. oxy .. "tAt"},
						["2_s"] = "a" .. oxy,
                        ["3_s"] = "a" .. oxy .. "tu",
                        ["1_d"] = "A" .. oxy .. "va",
                        ["2_d"] = "a" .. oxy .. "tam",
                        ["3_d"] = "a" .. oxy .. "tAm",
                        ["1_p"] = "A" .. oxy .. "ma",
                        ["2_p"] = "a" .. oxy .. "ta",
                        ["3_p"] = "a" .. oxy .. "ntu"
                    },
                    ["mv"] = {
                        ["1_s"] = "E" .. oxy,
                        ["2_s"] = "a" .. oxy .. "sva",
                        ["3_s"] = "a" .. oxy .. "tAm",
                        ["1_d"] = "A" .. oxy .. "vahE",
                        ["2_d"] = "e" .. oxy .. "TAm",
                        ["3_d"] = "e" .. oxy .. "tAm",
                        ["1_p"] = "A" .. oxy .. "mahE",
                        ["2_p"] = "a" .. oxy .. "Dvam",
                        ["3_p"] = "a" .. oxy .. "ntAm"
                    },
                },
                ["optat"] = {
                    ["av"] = {
                        ["1_s"] = "e" .. oxy .. "yam",
                        ["2_s"] = "e" .. oxy .. "s",
                        ["3_s"] = "e" .. oxy .. "t",
                        ["1_d"] = "e" .. oxy .. "va",
                        ["2_d"] = "e" .. oxy .. "tam",
                        ["3_d"] = "e" .. oxy .. "tAm",
                        ["1_p"] = "e" .. oxy .. "ma",
                        ["2_p"] = "e" .. oxy .. "ta",
                        ["3_p"] = "e" .. oxy .. "yur"
                    },
                    ["mv"] = {
                        ["1_s"] = "e" .. oxy .. "ya",
                        ["2_s"] = "e" .. oxy .. "TAs",
                        ["3_s"] = "e" .. oxy .. "ta",
                        ["1_d"] = "e" .. oxy .. "vahi",
                        ["2_d"] = "e" .. oxy .. "yATAm",
                        ["3_d"] = "e" .. oxy .. "yAtAm",
                        ["1_p"] = "e" .. oxy .. "mahi",
                        ["2_p"] = "e" .. oxy .. "Dvam",
                        ["3_p"] = "e" .. oxy .. "ran"
                    },
                },
                ["subj"] = {
                	["av"] = {
                        ["1_s"] = "A" .. oxy .. "ni",
                        ["2_s"] = {"A" .. oxy .. "s", "A" .. oxy .. "si"},
                        ["3_s"] = {"A" .. oxy .. "t", "A" .. oxy .. "ti"},
                        ["1_d"] = "A" .. oxy .. "va",
                        ["2_d"] = "A" .. oxy .. "Tas",
                        ["3_d"] = "A" .. oxy .. "tas",
                        ["1_p"] = "A" .. oxy .. "ma",
                        ["2_p"] = "A" .. oxy .. "Ta",
                        ["3_p"] = "A" .. oxy .. "n"
                    },
                    ["mv"] = {
                        ["1_s"] = "E" .. oxy,
                        ["2_s"] = {"A" .. oxy .. "se", "A" .. oxy .. "sE"},
                        ["3_s"] = {"A" .. oxy .. "te", "A" .. oxy .. "tE"},
                        ["1_d"] = "A" .. oxy .. "vahE",
                        ["2_d"] = "E" .. oxy .. "Te",
                        ["3_d"] = "E" .. oxy .. "te",
                        ["1_p"] = "A" .. oxy .. "mahE",
                        ["2_p"] = "A" .. oxy .. "DvE",
                        ["3_p"] = {"a" .. oxy .. "nta", "A" .. oxy .. "ntE"},
                    },
                },
                ["part"] = {
                    ["av"] = "a" .. oxy .. "t",
                    ["mv"] = "a" .. oxy .. "mAna"
                }
            }
        end

        local make_athematic_strong_forms_cons = function ()
            return {
                ["indic"] = {
                    ["av"] = {
                        ["1_s"] = "mi",
                        ["2_s"] = "si",
                        ["3_s"] = "ti",
                    },
                },
                ["imper"] = {
                    ["av"] = {
						["3_s"] = "tu",
                    }
                }
            }
        end
		
		local make_athematic_strong_forms_vow = function ()
            return {
                ["imper"] = {
                    ["av"] = {
                        ["1_s"] = "Ani",
                        ["1_d"] = "Ava",
                        ["1_p"] = "Ama",
                    },
                    ["mv"] = {
                        ["1_s"] = "E",
                        ["1_d"] = "AvahE",
                        ["1_p"] = "AmahE",
                    }
                },
                ["subj"] = {
                	["av"] = {
                        ["1_s"] = {"Ani", "A"},
                        ["2_s"] = {"as", "asi"},
                        ["3_s"] = {"at", "ati"},
                        ["1_d"] = "Ava",
                        ["2_d"] = "aTas",
                        ["3_d"] = "atas",
                        ["1_p"] = "Ama",
                        ["2_p"] = "aTa",
                        ["3_p"] = "an"
                    },
                    ["mv"] = {
                        ["1_s"] = "E",
                        ["2_s"] = {"ase", "AsE"},
                        ["3_s"] = {"ate", "AtE"},
                        ["1_d"] = "AvahE",
                        ["2_d"] = "ETe",
                        ["3_d"] = "Ete",
                        ["1_p"] = "AmahE",
                        -- example of -adhve is 'śayadhve' (RV 10.108.4), see 'Stativ und Passivaorist im Indoiranischen' p.110
                        ["2_p"] = {"aDve", "ADvE"},
                        ["3_p"] = {"anta", "AntE"},
                    }
                }
            }
		end
    	
        local make_athematic_weak_forms_cons = function (oxy)  -- endings starting with consonant not m/v/y
            return {
                ["indic"] = {
                    ["av"] = {
                        ["2_d"] = "Ta" .. oxy .. "s",
                        ["3_d"] = "ta" .. oxy .. "s",
                        ["2_p"] = "Ta" .. oxy,
                    },
                    ["mv"] = {
                        ["2_s"] = "se" .. oxy,
                        ["3_s"] = "te" .. oxy,
                        ["2_p"] = "Dve" .. oxy,
                    }
                },
                ["imper"] = {
                    ["av"] = {
--                        ["2_s"] = {"Di" .. oxy, "tA" .. oxy .. "t"},
                        ["2_d"] = "ta" .. oxy .. "m",
                        ["3_d"] = "tA" .. oxy .. "m",
                        ["2_p"] = "ta" .. oxy,
                    },
                    ["mv"] = {
                        ["2_s"] = "sva" .. oxy,
                        ["3_s"] = "tA" .. oxy .. "m",
                        ["2_p"] = "Dva" .. oxy .. "m",
                    }
                }
            }
        end
        
        local make_athematic_weak_forms_mvy = function (oxy)  -- endings starting with m/v/y
            return {
                ["indic"] = {
                    ["av"] = {
                        ["1_d"] = "va" .. oxy .. "s",
                        ["1_p"] = {"ma" .. oxy .. "s", {"ma" .. oxy .. "si", note = "Vedic"}},
                    },
                    ["mv"] = {
                        ["1_d"] = "va" .. oxy .. "he",
                        ["1_p"] = "ma" .. oxy .. "he",
                    }
                },
                ["optat"] = {
                    ["av"] = {
                        ["1_s"] = "yA" .. oxy .. "m",
                        ["2_s"] = "yA" .. oxy .. "s",
                        ["3_s"] = "yA" .. oxy .. "t",
                        ["1_d"] = "yA" .. oxy .. "va",
                        ["2_d"] = "yA" .. oxy .. "tam",
                        ["3_d"] = "yA" .. oxy .. "tAm",
                        ["1_p"] = "yA" .. oxy .. "ma",
                        ["2_p"] = "yA" .. oxy .. "ta",
                        ["3_p"] = "yu" .. oxy .. "s"
                    }
                }
            }
        end
        
        local make_athematic_weak_forms_vow = function (oxy)  -- endings starting with vowels
            return {
                ["indic"] = {
                    ["av"] = {
                        ["3_p"] = "a" .. oxy .. "nti"
                    },
                    ["mv"] = {
                        ["1_s"] = "e" .. oxy,
                        ["2_d"] = "A" .. oxy .. "Te",
                        ["3_d"] = "A" .. oxy .. "te",
                        ["3_p"] = "a" .. oxy .. "te"
                    }
                },
                ["imper"] = {
                    ["av"] = {
                        ["3_p"] = "a" .. oxy .. "ntu"
                    },
                    ["mv"] = {
                        ["2_d"] = "A" .. oxy .. "TAm",
                        ["3_d"] = "A" .. oxy .. "tAm",
                        ["3_p"] = "a" .. oxy .. "tAm"
                    }
                },
                ["optat"] = {
                    ["mv"] = {
                        ["1_s"] = "Iya" .. oxy,
                        ["2_s"] = "ITA" .. oxy .. "s",
                        ["3_s"] = "Ita" .. oxy,
                        ["1_d"] = "Iva" .. oxy .. "hi",
                        ["2_d"] = "IyA" .. oxy .. "TAm",
                        ["3_d"] = "IyA" .. oxy .. "tAm",
                        ["1_p"] = "Ima" .. oxy .. "hi",
                        ["2_p"] = "IDva" .. oxy .. "m",
                        ["3_p"] = "Ira" .. oxy .. "n"
                    }
                },
                ["part"] = {
                    ["av"] = "a" .. oxy .. "t",
                    ["mv"] = "Ana" .. oxy,
                }
            }
        end
        
        local make_athematic_class_3_forms_vow = function()  -- endings starting with vowel for class 3 (no oxy)
        	return {
        		["indic"] = {
                    ["av"] = {
                        ["3_p"] = "ati"
                    },
                    ["mv"] = {
                        ["1_s"] = "e",
                        ["2_d"] = "ATe",
                        ["3_d"] = "Ate",
                        ["3_p"] = "ate"
                    }
                },
                ["imper"] = {
                    ["av"] = {
                        ["3_p"] = "atu"
                    },
                    ["mv"] = {
                        ["2_d"] = "ATAm",
                        ["3_d"] = "AtAm",
                        ["3_p"] = "atAm"
                    }
                },
                ["optat"] = {
                    ["mv"] = {
                        ["1_s"] = "Iya",
                        ["2_s"] = "ITAs",
                        ["3_s"] = "Ita",
                        ["1_d"] = "Ivahi",
                        ["2_d"] = "IyATAm",
                        ["3_d"] = "IyAtAm",
                        ["1_p"] = "Imahi",
                        ["2_p"] = "IDvam",
                        ["3_p"] = "Iran"
                    }
                },
                ["part"] = {
                    ["av"] = "at",
                    ["mv"] = "Ana",
                }
        	}
        end
		
		local make_extra_class_5_8_forms = function(oxy)
           	return {
           		["indic"] = {
           			["av"] = {
           				["1_d"] = "va" .. oxy .. "s",
                       	["1_p"] = {"ma" .. oxy .. "s", {"ma" .. oxy .. "si", note = "Vedic"}},
           			},
           			["mv"] = {
           				["1_d"] = "va" .. oxy .. "he",
                       	["1_p"] = "ma" .. oxy .. "he",
           			}
           		},
           		["imper"] = {
                   	["av"] = {
                       	["2_s"] = {"u" .. oxy, {"uhi" .. oxy, note = "Vedic"}}
               		}
               	}
           	}
        end
    	
        local make_intensive_weak_forms_extra = function()  -- not in case of dissyllabic reduplication (Whitney §1007a)
           	return {
           		["indic"] = {
           			["av"] = {
           				["1_s"] = "Imi",
           				["2_s"] = "Izi",
           				["3_s"] = "Iti",
					}
               	},
                ["imper"] = {
                    ["av"] = {
						["3_s"] = "Itu",
                    }
                } 
           	}
        end
		
		local make_athematic_imper_2s_Di = function(oxy)
			return {
				["imper"] = {
                    ["av"] = {
						["2_s"] = "Di" .. oxy
                    }
                }
			}
		end
		
		local make_athematic_imper_2s_hi = function(oxy)
			return {
				["imper"] = {
                    ["av"] = {
						["2_s"] = "hi" .. oxy
                    }
                }
			}
		end
		
		local make_class_9_cons_imper_2s = function(oxy)
			return {
				["imper"] = {
                    ["av"] = {
						["2_s"] = "Ana" .. oxy
                    }
                }
			}
		end
		
		local t = {}
		local is_thematic = args.weak_lemma == nil
		if is_thematic then
            if not detect_strong(t, args.strong_lemma, "(.+)a" .. sa_utils.accent .. "?ti$", "a(" .. sa_utils.accent .. "?)ti$") then
                if not detect_strong(t, args.strong_lemma, "(.+)a" .. sa_utils.accent .. "?te$", "a(" .. sa_utils.accent .. "?)te$") then
                    validate(t["strong_stem"], args.strong_lemma)
                else
                    args.n = "m" -- deponent
                end
            end
            make_forms(args, data, t["strong_stem"], make_thematic_forms(t["strong_oxy"]))
            
            -- class 10 (Whitney §1043f)
            if (args.class == "10" or not args.class) and match(t.strong_stem, sa_utils.vowel
            	.."M?"..sa_utils.consonant.."+a" .. sa_utils.accent .. "?y$") then
            	args.accent_override = true
            	make_forms(args, data, t["strong_stem"], {
					["part"] = {
						["mv"] = {{ "Ana", note = "Later Sanskrit" }},
					}
        		})
            end
        -- active athematic verbs
		elseif detect_strong(t, args.strong_lemma, "(.+)[tDwQ]i$") or match(args.strong_lemma, "^<.+>$") then
           	if not detect_weak(t, args.weak_lemma, "(.+)a" .. sa_utils.accent .. "?nti$", "a(" .. sa_utils.accent .. "?)nti$") then
    			if not detect_weak(t, args.weak_lemma, "(.+A)" .. sa_utils.accent .. "?nti$", "A(" .. sa_utils.accent .. "?)nti$") then
    				if not detect_weak(t, args.weak_lemma, "(.+)ati$", sa_utils.vowel .. "(" .. sa_utils.accent .. "?).+ati$") then
    					validate(t["weak_stem"], args.weak_lemma)
    				else
    					t.ati_3p = true
    				end
    			end
    		end
			
           	-- if no strong stem supplied, check weak stem in case of possible sandhi
           	if match(args.strong_lemma, "[ktp]ti$")	then
           		t.strong_stem = gasub(t.strong_stem, ".$", gasub(t.weak_stem, ".+(.)$", "%1"))
           	-- if 3s ends on -dhi/-ṭi
            elseif match(args.strong_lemma, "[Dw]i$") then
               	if match(t.weak_stem, "kz$") then
               		t.strong_stem = gasub(t.strong_stem, "z$", "kz")
               	else
               		t.strong_stem = gasub(t.strong_stem, ".$", gasub(t.weak_stem, ".+(.)$", "%1"))
               		if match(t.strong_stem, "h$") then
               			args.h_to_g = true
               		elseif match(t.strong_stem, "j$") then
               			args.j_to_z = true
               		end
               	end
            -- if 3s ends on -ḍhi
            elseif match(args.strong_lemma, "Qi$") then
               	t.strong_stem = gasub(t.strong_stem, "^(.*)$", "%1h")
            -- error for roots on -i/ī/u/ū when no weak stem provided
            elseif match(args.weak_lemma, sa_utils.consonant.."i?ya/?n?ti$") 
            or ( match(args.weak_lemma, "uva/?n?ti$") and not match(t.strong_stem, "[nR]o/?")) then
               	error("Please add weak stem for roots on -i/-ī and -u/-ū.")
            end
            
            make_forms(args, data, t["strong_stem"], make_athematic_strong_forms_cons())
            
            -- assuming 3s on -īti is intensive (as a normal class 3 root on -ī would have -eti)
            if t.ati_3p == true and (not args.class or args.class == "int") and ( match (t.strong_stem, "I$") or detect_intensive(args, t) ) then 
            	args.n = "a"   -- no middle  (maybe add middle participle?)
            	t.strong_stem_before_vow = gasub(t.strong_stem, "I$", "")
            	if match(t.strong_stem_before_vow, sa_utils.vowel.."[yrlv]?$") then
            		make_forms(args, data, t["strong_stem_before_vow"], make_athematic_strong_forms_vow())
            	else
            		make_forms(args, data, t["weak_stem"], make_athematic_strong_forms_vow()) -- using weak stem with (normally) strong endings
            	end
				
            	if t.intensive == "1" then	-- no dissyllabic reduplication and not on -īti
            		if match(t.strong_stem, sa_utils.vowel_with_accent.."[rl]?$") then -- Whitney §1004a
            			make_forms(args, data, t["strong_stem"], make_intensive_weak_forms_extra())
            		else
		            	make_forms(args, data, t["weak_stem"], make_intensive_weak_forms_extra())
		            end
            	end
            else
            	if match(t.strong_stem, "O/?$") and match(t.weak_stem, "u$") then  -- Whitney §626
               		t.strong_stem = gasub(t.strong_stem, "O(/?)$", "a%1v")
            	elseif match(t.strong_stem, "a/?vI$") and match(t.weak_stem, "[uU]v?$") then -- e.g. 'brū', see Whitney §632-3
            		t.strong_stem = gasub(t.strong_stem, "I$", "")
            	elseif match(t.strong_stem, "i$") and match(t.weak_stem, "[^iy]$") then -- for 'set' verbs (Whitney §631)
               		t.strong_stem = gasub(t.strong_stem, "i$", "")
        		end
            	make_forms(args, data, t["strong_stem"], make_athematic_strong_forms_vow())
            end
            
            if match(args.weak_lemma, "ati$") then -- if 3p on -ati and no weak stem provided
                args.accent_override = true
            -- for class 5/8 verbs on vowel + -noti
            elseif match(t.strong_stem, sa_utils.vowel .. "[nR]o/?$") then
               	t.temp_stem = gasub(t.strong_stem, "o/?$", "")
            	make_forms(args, data, t["temp_stem"], make_extra_class_5_8_forms(t["weak_oxy"])) -- includes active imper. 2s
               	t.imper_2s_created = true
            -- for verbs like āpnoti
            elseif match(t.strong_stem, sa_utils.consonant .. "[nR]o/?$") then
                args.no_syncope = true
                t.weak_stem = gasub(t.weak_stem, "uv$", "u")
            -- class 9
            elseif match(t.strong_stem, "[nR]A/?$") and match(t.weak_stem, "[nR]$") then
               	t.weak_stem = gasub(t.weak_stem, "^.*$", "%1I")
            end
			
			if t.imper_2s_created == true then
				-- do nothing
			elseif match(t.weak_stem, sa_utils.consonant .."[nR]I$") then -- Whitney §722
				t.temp_stem = gasub(t.weak_stem, "[nR]I$", "")
				make_forms(args, data, t["temp_stem"], make_class_9_cons_imper_2s(t["weak_oxy"]))
			elseif match(t.weak_stem, sa_utils.vowel .. "$") or match(t.weak_stem, sa_utils.consonant.."[yrv]$")
			or match(t.weak_stem, "^y$") or args.set == true then
				make_forms(args, data, t["weak_stem"], make_athematic_imper_2s_hi(t["weak_oxy"]))
			else
				make_forms(args, data, t["weak_stem"], make_athematic_imper_2s_Di(t["weak_oxy"]))
			end
            
            make_forms(args, data, t["weak_stem"], make_athematic_weak_forms_cons(t["weak_oxy"]))
            if args.extra_1p_stem then  -- optional extra stem for endings starting with m/v/y
                t.weak_stem = to_SLP(args.extra_1p_stem)
            end
            make_forms(args, data, t["weak_stem"], make_athematic_weak_forms_mvy(t["weak_oxy"]))
            
            if match(args.weak_lemma, ".<.*>$") then
                t.weak_stem = gasub(args.weak_lemma, "a?" .. sa_utils.accent .. "?n?ti<.*>$", "")
            elseif args.extra_1p_stem or match(t.weak_stem, "[nR]I$") then
               	t.weak_stem = gasub(args.weak_lemma, "a?" .. sa_utils.accent .. "?nti$", "")
            end
            if t.ati_3p == true then
            	args.accent_override = false
            	make_forms(args, data, t["weak_stem"], make_athematic_class_3_forms_vow())
            else
               	make_forms(args, data, t["weak_stem"], make_athematic_weak_forms_vow(t["weak_oxy"]))
            end
        -- deponent verbs
        elseif detect_strong(t, args.strong_lemma, "(.+)[tDwQ]e/?$", "[tDwQ]e(/?)$") then
            args.n = "m" -- deponent
            if not detect_weak(t, args.weak_lemma, "(.+"..sa_utils.accent..".+)ate$", sa_utils.vowel.."("..sa_utils.accent..").+ate$") then
            	if not detect_weak(t, args.weak_lemma, "(.+)a"..sa_utils.accent.."?te$", "a("..sa_utils.accent.."?)te$") then
            		if not detect_weak(t, args.weak_lemma, "(.+A/?)te$") then
            			validate(t["weak_stem"], args.weak_lemma)
            		end
            	end
            elseif t.strong_oxy ~= "" then
            	t.accented_class_3 = true
            end
            
            -- for class 5/8 verbs on vowel + -nute (+ tarute)
            -- adding '-no' for detection as this might be the strong stem supplied to form 1st person imperative
            if match(t.strong_stem, sa_utils.vowel .. "[nRr][uo]/?$") 
            and (not args.class or match(args.class, "^[58]$")) and not args.extra_1p_stem then
            	t.temp_stem = gasub(t.strong_stem, "[uo]/?$", "")
            	make_forms(args, data, t["temp_stem"], make_extra_class_5_8_forms(t["weak_oxy"]))
            -- for verbs like āpnoti, but middle (the regex also includes hnute, but this is ok)
            elseif match(t.strong_stem, sa_utils.consonant .. "[nR][uo]/?$") then
            	args.no_syncope = true
            end	
            
            -- produce 1st person imperative if strong stem is supplied with 3sg
            if match(args.strong_lemma, "<.*>$") then
            	make_forms(args, data, t["strong_stem"], make_athematic_strong_forms_vow())
            -- or if root has 'a/ā' (when guṇa would be the same),
            -- and not accented class 3 (accent on strong stem unpredictable) or potentially class 7
            elseif match(t.strong_stem, "[aA]"..sa_utils.accent.."?"..sa_utils.consonant.."*$") 
            and not t.accented_class_3 == true and not match(t.strong_stem, "[NYRnm]"..sa_utils.consonant.."$") then
            	-- look at 3p to avoid possible sandhi before 3s -te
            	t.strong_stem = gasub(t.weak_stem, "([aA])("..sa_utils.consonant.."*)$", "%1"..t.strong_oxy.."%2")
            	make_forms(args, data, t["strong_stem"], make_athematic_strong_forms_vow())
			-- or if stem ends on -[nṇ]u (including hnu/snu is ok)
            elseif match(t.strong_stem, "[nR]u$") then
            	t.strong_stem = gasub(t.strong_stem, "u$", "o"..t.strong_oxy)
            	make_forms(args, data, t["strong_stem"], make_athematic_strong_forms_vow())
        	-- or class 9
           	elseif match(t.strong_stem, "[nR]I$") and match(t.weak_stem, "[nR]$") then
           		t.strong_stem = gasub(t.strong_stem, "I$", "A"..t.strong_oxy)
            	make_forms(args, data, t["strong_stem"], make_athematic_strong_forms_vow())
            end
            
            if match(args.strong_lemma, sa_utils.vowel_with_accent .. "te/?$") then
            	t.weak_stem_before_cons = gasub(args.strong_lemma, "te/?$", "")
           	elseif match(args.strong_lemma, sa_utils.vowel_with_accent .. "te/?<.*>$") then
            	t.weak_stem_before_cons = gasub(args.strong_lemma, "te/?<.*>$", "")
            else
            	t.weak_stem_before_cons = t.weak_stem
			end
            if t.accented_class_3 == true then
            	args.accent_override = true  -- no accent on class 3 stem if ending starts with consonant
            end
            		
            make_forms(args, data, t["weak_stem_before_cons"], make_athematic_weak_forms_cons(t["strong_oxy"]))
            if args.extra_1p_stem then
                t.weak_stem_before_cons = to_SLP(args.extra_1p_stem)
            end
            make_forms(args, data, t["weak_stem_before_cons"], make_athematic_weak_forms_mvy(t["strong_oxy"]))
            if match(args.weak_lemma, ".<.*>$") then
                t.weak_stem = gasub(args.weak_lemma, "a?" .. sa_utils.accent .. "?te<.*>$", "")
            end
            
            if t.accented_class_3 == true then
            	args.accent_override = false
                make_forms(args, data, t["weak_stem"], make_athematic_class_3_forms_vow())
            else
	            make_forms(args, data, t["weak_stem"], make_athematic_weak_forms_vow(t["weak_oxy"]))
            end
        else
        	validate(t["strong_stem"], args.strong_lemma)
        end
    end
})

conj_data["impf"] = {}
setmetatable(conj_data["impf"], {
    __call = function (self, args, data)
    	-- accent for augmentless forms
    	local make_thematic_impf_forms = function(oxy) 
    		return {
               	["indic"] = {
                   	["av"] = {
                       	["1_s"] = "a" .. oxy .. "m",
                       	["2_s"] = "a" .. oxy .. "s",
               	        ["3_s"] = "a" .. oxy .. "t",
                   	    ["1_d"] = "A" .. oxy .. "va",
                       	["2_d"] = "a" .. oxy .. "tam",
                        ["3_d"] = "a" .. oxy .. "tAm",
               	        ["1_p"] = "A" .. oxy .. "ma",
                   	    ["2_p"] = "a" .. oxy .. "ta",
                       	["3_p"] = "a" .. oxy .. "n"
                   	},
                   	["mv"] = {
                       	["1_s"] = "e" .. oxy,
                       	["2_s"] = "a" .. oxy .. "TAs",
                       	["3_s"] = "a" .. oxy .. "ta",
                       	["1_d"] = "A" .. oxy .. "vahi",
                       	["2_d"] = "e" .. oxy .. "TAm",
                       	["3_d"] = "e" .. oxy .. "tAm",
                       	["1_p"] = "A" .. oxy .. "mahi",
                       	["2_p"] = "a" .. oxy .. "Dvam",
                       	["3_p"] = "a" .. oxy .. "nta"
                   	},
               	}
            }
    	end
    	
    	local athematic_impf_strong_endings_cons = {
            ["indic"] = {
                ["av"] = {
                   	["2_s"] = "s",
                   	["3_s"] = "t",
                },
            },
        }
    	
    	local athematic_impf_strong_endings_vow = {
            ["indic"] = {
                ["av"] = {
                    ["1_s"] = "am",
                },
            },
        }
        
    	-- accent for augmentless forms
    	local make_athematic_impf_weak_forms_cons = function(oxy) -- endings starting with consonants not m/v/y
    		return {  
            	["indic"] = {
                	["av"] = {
            	        ["2_d"] = "ta" .. oxy .. "m",
        	            ["3_d"] = "tA" .. oxy .. "m",
                    	["2_p"] = "ta" .. oxy,
                	},
    	            ["mv"] = {
            	        ["2_s"] = "TA" .. oxy .. "s",
                	    ["3_s"] = "ta" .. oxy,
                    	["2_p"] = "Dva" .. oxy .. "m",
                	}
            	}
        	}
    	end
    	
    	local make_athematic_impf_weak_forms_mvy = function(oxy) -- endings starting with m/v/y
    		return {  
            	["indic"] = {
                	["av"] = {
                    	["1_d"] = "va" .. oxy,
    	                ["1_p"] = "ma" .. oxy,
                	},
    	            ["mv"] = {
                   		["1_d"] = "va" .. oxy .. "hi",
                	    ["1_p"] = "ma" .. oxy .. "hi",
                	}
            	}
        	}
    	end
    	
    	local make_athematic_impf_weak_forms_vow = function(oxy) -- endings starting with vowels (without active 3p)
    		return {  
            	["indic"] = {
    	            ["mv"] = {
        	          	["1_s"] = "i" .. oxy,
        	            ["2_d"] = "A" .. oxy .. "TAm",
            	        ["3_d"] = "A" .. oxy .. "tAm",
                	    ["3_p"] = "a" .. oxy .. "ta"
                	}
            	}
        	}
    	end
    	
    	local make_athematic_impf_3p_an = function(oxy) 
        	return {
        		["indic"] = {
        			["av"] = {
        				["3_p"] = "a" .. oxy .. "n"
        			}
        		}
        	}
    	end
    	
    	local make_athematic_impf_3p_ur = function(oxy) 
        	return {
        		["indic"] = {
        			["av"] = {
        				["3_p"] = "u" .. oxy .. "r"
        			}
        		}
        	}
    	end
    	
        local intensive_impf_endings_extra = {
            ["indic"] = {
                ["av"] = {
                   	["2_s"] = "Is",
                   	["3_s"] = "It",
                },
            },
        }
       	
    	local t = {}
    	local is_thematic = args.weak_lemma == nil
    	if is_thematic then
            if not detect_strong(t, args.strong_lemma, "(.+)a/?t$", "a(/?)t$") then
                if not detect_strong(t, args.strong_lemma, "(.+)a/?ta$", "a(/?)ta$") then
                    validate(t["strong_stem"], args.strong_lemma)
                else
                    args.n = "m" -- deponent
                end
            end
            make_forms(args, data, t["strong_stem"], make_thematic_impf_forms(t["strong_oxy"]))
        -- active verbs
    	elseif detect_strong(t, args.strong_lemma, "(.*" .. sa_utils.vowel_with_accent .. ")t$") 
    	or detect_strong(t, args.strong_lemma, "(.+[kNwRtnprlsH])$") or match(args.strong_lemma, "^<.+>$") then
    		if not detect_weak(t, args.weak_lemma, "(.+)a/?n$", "a(/?)n$") then
    			if not detect_weak(t, args.weak_lemma, "(.+A)/?n$", "A(/?)n$") then
    				if not detect_weak(t, args.weak_lemma, "(.+)u[Hrs]$") then
    					validate(t["weak_stem"], args.weak_lemma)
    				else
    					t.ur_3p = true
    				end
    			end
    		end
    		
    		-- look at weak stem if 3s '-t' disappeared and no strong stem is supplied
    		if match(args.strong_lemma, "[kwpH]$") then
    			if args.diaspirate == true then
    				t.strong_stem = gasub(t.strong_stem, "([GDB])(.+)$", function(cons, post) return sa_utils.deaspirate[cons] .. post end)
    			end
    			if match(args.strong_lemma, "k$") then
    				t.strong_stem = gasub(t.strong_stem, ".$", gasub(t.weak_stem, ".+(.)$", "%1"))
    				if match(t.strong_stem, "h$") then
                		args.h_to_g = true
                	end
    			elseif match(t.weak_stem, "kz$") then
               		t.strong_stem = gasub(t.strong_stem, ".$", "kz")
               	else
                	t.strong_stem = gasub(t.strong_stem, ".$", gasub(t.weak_stem, ".+(.)$", "%1"))
               		if match(t.strong_stem, "j$") then
               			args.j_to_z = true
               		elseif match(t.strong_stem, "f$") then
               			t.strong_stem = gasub(t.strong_stem, ".$", "r")
               		end
    			end
    		elseif match(t.weak_stem, "[tTdD]$") 
    		and match(args.strong_lemma, "[^tTdD]" .. sa_utils.vowel_with_accent.."t$") then
				t.strong_stem = gasub(t.strong_stem, "^(.+)$", "%1" .. gasub(t.weak_stem, ".+(.)$", "%1"))
			-- error for roots on -i/ī/u/ū when no weak stem provided
    		elseif match(args.weak_lemma, sa_utils.consonant.."i?ya/?n$") 
    		or ( match(args.weak_lemma, "uva/?n$") and not match(t.strong_stem, "[nR]o/?")) then
                error("Please add weak stem for roots on -i/-ī and -u/-ū.")
    		end
    		
    		-- intensive verbs (assuming 3s on -īt is intensive, as a normal class 3 root on -ī would have -et)
    		if t.ur_3p == true and (not args.class or args.class == "int") and ( match(t.strong_stem, "I$") or detect_intensive(args, t) ) then
    			args.n = "a"
    			t.strong_stem_before_vow = gasub(t.strong_stem, "I$", "")
    			if match(t.strong_stem_before_vow, sa_utils.vowel.."[yrlv]?$") then
    				make_forms(args, data, t["strong_stem_before_vow"], athematic_impf_strong_endings_vow)
            	else
            		make_forms(args, data, t["weak_stem"], athematic_impf_strong_endings_vow) -- weak stem with normally strong ending
            	end
            else -- non-intensive
            	if match(args.strong_lemma, "O/?t$") and match(t.weak_stem, "u$") then  -- Whitney §626
    				t.strong_stem_before_vow = gasub(t.strong_stem, "O(/?)$", "a%1v")
    			-- verbs with inserted 'ī' in 2/3 sg., see Whitney §631-3 (roots on -ī should have -e in strong stem)
    			elseif match(args.strong_lemma, "It$") then
            		t.strong_stem_before_vow = gasub(t.strong_stem, "I$", "")
            	else
            		t.strong_stem_before_vow = t.strong_stem
    			end
            	make_forms(args, data, t["strong_stem_before_vow"], athematic_impf_strong_endings_vow)
            end
    		
    		-- use 3s form for 2s and 3s (if appropriate)
    		local syllable = sa_utils.vowel_with_accent..sa_utils.consonant.."+"
    		if match(args.strong_lemma, "^"..syllable..sa_utils.vowel_with_accent
    		.."t<"..syllable..sa_utils.vowel_with_accent.."[tTdD]>$") 
    		or match(args.strong_lemma, "^"..syllable..syllable..sa_utils.vowel_with_accent.."t<"
    		..syllable..syllable..sa_utils.vowel_with_accent.."[tTdD]>$") then
    			-- do nothing
    		elseif match(args.strong_lemma, sa_utils.vowel_with_accent.."t<.+>$") then
    			t.strong_stem = gasub(args.strong_lemma, "t<.+>$", "")
    		end
    		make_forms(args, data, t["strong_stem"], athematic_impf_strong_endings_cons)
    		-- if intensive without dissyllabic reduplication
            if t.intensive == "1" then
            	if match(t.strong_stem, sa_utils.vowel_with_accent.."[rl]?$") then -- Whitney §1004a
            		make_forms(args, data, t["strong_stem"], intensive_impf_endings_extra)
            	else
		           	make_forms(args, data, t["weak_stem"], intensive_impf_endings_extra)
		    	end
           	end
			
    		-- e.g. āpnot
        	if match(t.strong_stem, sa_utils.consonant .. "[nR]o/?$") then 
           		args.no_syncope = true
           		t.weak_stem = gasub(t.weak_stem, "uv$", "u")
           	-- extra forms for verbs on vowel + -noti
        	elseif match(t.strong_stem, sa_utils.vowel .. "[nR]o/?$") then
       			t.temp_stem = gasub(t.strong_stem, "o/?$", "")
        		make_forms(args, data, t["temp_stem"], make_athematic_impf_weak_forms_mvy(t["weak_oxy"]))
        	-- class 9
           	elseif match(t.strong_stem, "[nR]A/?$") and match(t.weak_stem, "[nR]$") then
               	t.weak_stem = gasub(t.weak_stem, "^.*$", "%1I")
            -- class 3 roots on -ṛ
            elseif match(args.weak_lemma, ".aru[Hrs]$") and not match(t.strong_stem, "A/?$") then
            	t.weak_stem = gasub(t.weak_stem, "ar$", "f")
            -- class 3 roots on -i/ī/u/ū with no weak stem provided
            elseif match(args.weak_lemma, ".a[vy]u[Hrs]$") and not match(t.strong_stem, "A/?$") then
            	error("Please add weak stem for class 3 roots on -i/-ī and -u/-ū.")
           	end
           	make_forms(args, data, t["weak_stem"], make_athematic_impf_weak_forms_cons(t["weak_oxy"]))
           	
           	if args.extra_1p_stem then
               	t.weak_stem = to_SLP(args.extra_1p_stem)
           	end
    		make_forms(args, data, t["weak_stem"], make_athematic_impf_weak_forms_mvy(t["weak_oxy"]))
    		
    		if match(args.weak_lemma, "n<.*>$") then
           	 	t.weak_stem = gasub(args.weak_lemma, "a?/?n<.*>$", "")
           	-- class 3 verbs on -ā with weak stem supplied
    		elseif match(args.weak_lemma, "u[Hrs]<.*>$") and match(t.strong_stem, "A$") then
       			t.weak_stem = gasub(args.weak_lemma, "u[Hrs]<.*>$", "")
    		elseif args.extra_1p_stem or match(t.weak_stem, "[nR]I$") then
               	t.weak_stem = gasub(args.weak_lemma, "a/?n$", "")
           	end
    		make_forms(args, data, t["weak_stem"], make_athematic_impf_weak_forms_vow(t["weak_oxy"]))
    		
    		if t.ur_3p == true then
    			-- active 3p for class 3 verbs is often not from the weak stem
    			if match(args.weak_lemma, ".<.*>$") then
    				t.weak_stem = gasub(args.weak_lemma, 'u[Hrs]<.*>$', '')
    			else
    				t.weak_stem = gasub(t.weak_stem, "f$", "ar")
    			end
    			make_forms(args, data, t["weak_stem"], make_athematic_impf_3p_ur(t["weak_oxy"]))
    		else
    			if match(t.strong_stem, "A$") and match(t.weak_stem, "A$") then	-- Whitney §621a
           			t.temp_stem = gasub(t.weak_stem, "A$", "")
           			make_forms(args, data, t["temp_stem"], make_athematic_impf_3p_ur(t["weak_oxy"]))
				end
           		make_forms(args, data, t["weak_stem"], make_athematic_impf_3p_an(t["weak_oxy"]))
    		end
       	-- deponent verbs
    	elseif detect_strong(t, args.strong_lemma, "(.+)[tDwQ]a/?$") then
    		if detect_weak(t, args.weak_lemma, "(.+)a/?ta$", "a(/?)ta$") or detect_weak(t, args.weak_lemma, "(.+A/?)ta$") then
        		args.n = "m" -- deponent
        		-- for verbs on vowel + -nuta (+ impf. of tarute)
           		if match(t.strong_stem, sa_utils.vowel .. "[nRr]u$")
           		and (not args.class or match(args.class, "^[58]$")) and not args.extra_1p_stem then
           			t.temp_stem = gasub(t.strong_stem, "u$", "")
        			make_forms(args, data, t["temp_stem"], make_athematic_impf_weak_forms_mvy(t["weak_oxy"]))
        		-- e.g. āpnot, but middle
            	elseif match(t.strong_stem, sa_utils.consonant .. "[nR]u?$") then 
           			args.no_syncope = true
        		end
        		
        		if match(args.strong_lemma, sa_utils.vowel_with_accent .. "ta$") then
            		t.weak_stem_before_cons = gasub(args.strong_lemma, "ta$", "")
            	else
            		t.weak_stem_before_cons = t.weak_stem
				end
        		
        		make_forms(args, data, t["weak_stem_before_cons"], make_athematic_impf_weak_forms_cons(t["weak_oxy"]))
        		if args.extra_1p_stem then
                	t.weak_stem_before_cons = to_SLP(args.extra_1p_stem)
            	end
        		make_forms(args, data, t["weak_stem_before_cons"], make_athematic_impf_weak_forms_mvy(t["weak_oxy"]))
        		if match(args.weak_lemma, ".<.*>$") then
                	t.weak_stem = gasub(args.weak_lemma, "a?/?ta<.*>$", "")
            	end
        		make_forms(args, data, t["weak_stem"], make_athematic_impf_weak_forms_vow(t["weak_oxy"]))
        	else
        		validate(t["weak_stem"], args.weak_lemma)
        	end
    	else
    		validate(t["strong_stem"], args.strong_lemma)
    	end
    end
})

conj_data["fut"] = {}
setmetatable(conj_data["fut"], {
    __call = function (self, args, data)
        local make_strong_forms = function (oxy)
            return {
                ["indic"] = {
                    ["av"] = {
                        ["1_s"] = "syA" .. oxy .. "mi",
                        ["2_s"] = "sya" .. oxy .. "si",
                        ["3_s"] = "sya" .. oxy .. "ti",
                        ["1_d"] = "syA" .. oxy .. "vas",
                        ["2_d"] = "sya" .. oxy .. "Tas",
                        ["3_d"] = "sya" .. oxy .. "tas",
                        ["1_p"] = {"syA" .. oxy .. "mas", {"syA" .. oxy .. "masi", note = "Vedic"}},
                        ["2_p"] = "sya" .. oxy .. "Ta",
                        ["3_p"] = "sya" .. oxy .. "nti"
                    },
                    ["mv"] = {
                        ["1_s"] = "sye" .. oxy,
                        ["2_s"] = "sya" .. oxy .. "se",
                        ["3_s"] = "sya" .. oxy .. "te",
                        ["1_d"] = "syA" .. oxy .. "vahe",
                        ["2_d"] = "sye" .. oxy .. "Te",
                        ["3_d"] = "sye" .. oxy .. "te",
                        ["1_p"] = "syA" .. oxy .. "mahe",
                        ["2_p"] = "sya" .. oxy .. "Dve",
                        ["3_p"] = "sya" .. oxy .. "nte"
                    }
                },
                ["part"] = {
                    ["av"] = "sya" .. oxy .. "t",
                    ["mv"] = "sya" .. oxy .. "mAna"
                }
            }
        end
        
        local t = {}
        if not detect_strong(t, args.strong_lemma, "(.+).ya" .. sa_utils.accent .. "?ti$", "(" .. sa_utils.accent .. "?)ti$") then
            if not detect_strong(t, args.strong_lemma, "(.+).ya" .. sa_utils.accent .. "?te$", "(" .. sa_utils.accent .. "?)te$") then
                validate(t["strong_stem"], args.strong_lemma)
            else
                args.n = "m" -- deponent
            end
        end
        make_forms(args, data, t["strong_stem"], make_strong_forms(t["strong_oxy"]))
        table.insert(data.categories, "Sanskrit verbs with s-future")
    end
})

conj_data["pfut"] = {}
setmetatable(conj_data["pfut"], {
	__call = function (self, args, data)
		local pfut_endings =  {
            ["indic"] = {
            	["av"] = {
                    ["1_s"] = "smi",
                    ["2_s"] = "si",
                    ["3_s"] = "",
                    ["1_d"] = "svas",
                    ["2_d"] = "sTas",
                    ["3_d"] = {"rO", {"rA", note = "Vedic"}}, -- 'gantārā' occurs in Rigveda 8.13.10
                    ["1_p"] = {"smas", {"smasi", note = "Vedic"}},
                    ["2_p"] = "sTa",
                    ["3_p"] = "ras"
                },
                ["mv"] = {
                    ["1_s"] = "he",
                    ["2_s"] = "se",
                    ["3_s"] = "",
                    ["1_d"] = "svahe",
                    ["2_d"] = "sATe",
                    ["3_d"] = "rO",
                    ["1_p"] = "smahe",
                    ["2_p"] = "Dve",
                    ["3_p"] = "ras"
                }
            }
        }

        
        local t = {}
        if not detect_strong(t, args.strong_lemma, "(.+[tDwQ]A" .. sa_utils.accent .. "?)$") then
            validate(t["strong_stem"], args.strong_lemma)
            -- for the periphrastic future, there is no way to tell if the verb is deponent from the lemma (third-person singular form)
            -- atmanepada verbs require the "n=m" argument to avoid showing the active forms
        end
    	make_forms(args, data, t["strong_stem"], pfut_endings)
		table.insert(data.categories, "Sanskrit verbs with periphrastic future")
	end
})

conj_data["cond"] = {}
setmetatable(conj_data["cond"], {
    __call = function (self, args, data)
        local t = {}
        if not detect_strong(t, args.strong_lemma, "(.+).yat$") then
            if not detect_strong(t, args.strong_lemma, "(.+).yata$") then
                validate(t["strong_stem"], args.strong_lemma)
            else
                args.n = "m" -- deponent
            end
        end
        make_forms(args, data, t["strong_stem"], {
            ["indic"] = {
                ["av"] = {
                    ["1_s"] = "syam",
                    ["2_s"] = "syas",
                    ["3_s"] = "syat",
                    ["1_d"] = "syAva",
                    ["2_d"] = "syatam",
                    ["3_d"] = "syatAm",
                    ["1_p"] = "syAma",
                    ["2_p"] = "syata",
                    ["3_p"] = "syan"
                },
                ["mv"] = {
                    ["1_s"] = "sye",
                    ["2_s"] = "syaTAs",
                    ["3_s"] = "syata",
                    ["1_d"] = "syAvahi",
                    ["2_d"] = "syeTAm",
                    ["3_d"] = "syetAm",
                    ["1_p"] = "syAmahi",
                    ["2_p"] = "syaDvam",
                    ["3_p"] = "syanta"
                }
            }
        })
    end
})

conj_data["aor"] = {}
setmetatable(conj_data["aor"], {
    __call = function (self, args, data)
        -- there is some added complexity here compared to the other tenses due to the number of aorist types in Sanskrit
        local make_strong_is_forms = function(var_i)
            return { 
                ["indic"] = {
                    ["av"] = {
                        ["1_s"] = var_i .. "zam",
                        ["2_s"] = "Is",
                        ["3_s"] = "It",
                        ["1_d"] = var_i .. "zva",
                        ["2_d"] = var_i .. "zwam",
                        ["3_d"] = var_i .. "zwAm",
                        ["1_p"] = var_i .. "zma",
                        ["2_p"] = var_i .. "zwa",
                        ["3_p"] = var_i .. "zur"
                    },
                }
            }
        end
        
        local make_strong_is_inj_forms = function(var_i)
            return { 
                ["inj"] = {
                    ["av"] = {
                        ["1_s"] = var_i .. "zam",
                        ["2_s"] = "Is",
                        ["3_s"] = "It",
                        ["1_d"] = var_i .. "zva",
                        ["2_d"] = var_i .. "zwam",
                        ["3_d"] = var_i .. "zwAm",
                        ["1_p"] = var_i .. "zma",
                        ["2_p"] = var_i .. "zwa",
                        ["3_p"] = var_i .. "zur"
                    },
                },
                ["subj"] = {
                    ["av"] = {
                        ["1_s"] = var_i .. "zAni",
                        ["2_s"] = { var_i .. "zas", var_i .. "zasi"},
                        ["3_s"] = { var_i .. "zat", var_i .. "zati"},
                        ["1_d"] = var_i .. "zAva",
                        ["2_d"] = var_i .. "zaTas",
                        ["3_d"] = var_i .. "zatas",
                        ["1_p"] = var_i .. "zAma",
                        ["2_p"] = var_i .. "zaTa",
                        ["3_p"] = var_i .. "zan",
                    }
                }
            }
        end
        
        local make_weak_is_forms = function(var_i)
            return { 
                ["indic"] = {
                    ["mv"] = {
                        ["1_s"] = var_i .. "zi",
                        ["2_s"] = var_i .. "zWAs",
                        ["3_s"] = var_i .. "zwa",
                        ["1_d"] = var_i .. "zvahi",
                        ["2_d"] = var_i .. "zATAm",
                        ["3_d"] = var_i .. "zAtAm",
                        ["1_p"] = var_i .. "zmahi",
                        ["2_p"] = var_i .. "Qvam",
                        ["3_p"] = var_i .. "zata"
                    },
                }
            }
        end
		
		local make_weak_is_inj_forms = function(var_i)
            return { 
            	["inj"] = {
                	["mv"] = {
                	    ["1_s"] = var_i .. "zi",
                    	["2_s"] = var_i .. "zWAs",
	                    ["3_s"] = var_i .. "zwa",
    	                ["1_d"] = var_i .. "zvahi",
        	            ["2_d"] = var_i .. "zATAm",
            	        ["3_d"] = var_i .. "zAtAm",
                	    ["1_p"] = var_i .. "zmahi",
                    	["2_p"] = var_i .. "Qvam",
	                    ["3_p"] = var_i .. "zata"
            		},
            	},
                ["subj"] = {
                    ["mv"] = {
                        ["1_s"] = var_i .. "zE",
                        ["2_s"] = { var_i .. "zase", var_i .. "zAsE"},
                        ["3_s"] = { var_i .. "zate", var_i .. "zAtE"},
                        ["1_d"] = var_i .. "zAvahe",
                        ["2_d"] = var_i .. "zETe",
                        ["3_d"] = var_i .. "zEte",
                        ["1_p"] = { var_i .. "zAmahe", var_i .. "zAmahE"},
                        ["2_p"] = { var_i .. "zaDve", var_i .. "zADvE"},
                        ["3_p"] = var_i .. "zanta",
                    }
                }
            }
        end
        
        local strong_s_endings = {
            ["indic"] = {
                ["av"] = {
                    ["1_s"] = "sam",
                    ["2_s"] = {"sIs", {"s", note = "Vedic"}},
                    ["3_s"] = {"sIt", {"s", note = "Vedic"}},
                    ["1_d"] = "sva",
                    ["2_d"] = "stam",
                    ["3_d"] = "stAm",
                    ["1_p"] = "sma",
                    ["2_p"] = "sta",
                    ["3_p"] = "sur"
                },
            }
        }
        
        local strong_s_inj_endings = {
            ["inj"] = {
                ["av"] = {
                    ["1_s"] = "sam",
                    ["2_s"] = {"sIs", {"s", note = "Vedic"}},
                    ["3_s"] = {"sIt", {"s", note = "Vedic"}},
                    ["1_d"] = "sva",
                    ["2_d"] = "stam",
                    ["3_d"] = "stAm",
                    ["1_p"] = "sma",
                    ["2_p"] = "sta",
                    ["3_p"] = "sur"
                }
            }
        }
		
		local active_s_subj_endings = {
            ["subj"] = {
                ["av"] = {
                    ["1_s"] = "sAni",
                    ["2_s"] = {"sas", "sasi"},
                    ["3_s"] = {"sat", "sati"},
                    ["1_d"] = "sAva",
                    ["2_d"] = "saTas",
                    ["3_d"] = "satas",
                    ["1_p"] = "sAma",
                    ["2_p"] = "saTa",
                    ["3_p"] = "san",
                }
            }
        }
        
        local weak_s_endings = {
            ["indic"] = {
                ["mv"] = {
                    ["1_s"] = "si",
                    ["2_s"] = "sTAs",
                    ["3_s"] = "sta",
                    ["1_d"] = "svahi",
                    ["2_d"] = "sATAm",
                    ["3_d"] = "sAtAm",
                    ["1_p"] = "smahi",
                    ["2_p"] = "sDvam", -- further treated by sandhi module
                    ["3_p"] = "sata"
                },
            }
        }
        
        local weak_s_inj_endings = {
            ["inj"] = {
                ["mv"] = {
                    ["1_s"] = "si",
                    ["2_s"] = "sTAs",
                    ["3_s"] = "sta",
                    ["1_d"] = "svahi",
                    ["2_d"] = "sATAm",
                    ["3_d"] = "sAtAm",
                    ["1_p"] = "smahi",
                    ["2_p"] = "sDvam", -- further treated by sandhi module
                    ["3_p"] = "sata"
                },
            }
        }
        
        local middle_s_subj_endings = {
            ["subj"] = {
                ["mv"] = {
                    ["1_s"] = "sE",
                    ["2_s"] = {"sase", "sAsE"},
                    ["3_s"] = {"sate", "sAtE"},
                    ["1_d"] = "sAvahE",
                    ["2_d"] = "sETe",
                    ["3_d"] = "sEte",
                    ["1_p"] = {"sAmahe", "sAmahE"},
                    ["2_p"] = {"saDve", "sADvE"}, -- speculative
                    ["3_p"] = "santa"
        		}
            }
        }
        
        -- for a- + sa-aorist
        local make_strong_thematic_forms = function(oxy)
        	return {
            	["indic"] = {
                	["av"] = {
                    	["1_s"] = "a" .. oxy .. "m",
	                    ["2_s"] = "a" .. oxy .. "s",
    	                ["3_s"] = "a" .. oxy .. "t",
        	            ["1_d"] = "A" .. oxy .. "va",
                	    ["2_d"] = "a" .. oxy .. "tam",
            	        ["3_d"] = "a" .. oxy .. "tAm",
                    	["1_p"] = "A" .. oxy .. "ma",
                	    ["2_p"] = "a" .. oxy .. "ta",
                    	["3_p"] = "a" .. oxy .. "n"
                	},
            	}
        	}
        end
        
		local make_strong_thematic_inj_forms = function(oxy) 
        	return {
            	["inj"] = {
                	["av"] = {
                    	["1_s"] = "a" .. oxy .. "m",
	                    ["2_s"] = "a" .. oxy .. "s",
        	            ["3_s"] = "a" .. oxy .. "t",
    	                ["1_d"] = "A" .. oxy .. "va",
            	        ["2_d"] = "a" .. oxy .. "tam",
                	    ["3_d"] = "a" .. oxy .. "tAm",
                    	["1_p"] = "A" .. oxy .. "ma",
                	    ["2_p"] = "a" .. oxy .. "ta",
                    	["3_p"] = "a" .. oxy .. "n"
                	},
            	},
            	["subj"] = {
        		    ["av"] = {
                	    ["1_s"] = "A" .. oxy .. "ni",
                    	["2_s"] = {"A" .. oxy .. "s", "A" .. oxy .. "si"},
	                    ["3_s"] = {"A" .. oxy .. "t", "A" .. oxy .. "ti"},
    	                ["1_d"] = "A" .. oxy .. "va",
        	            ["2_d"] = "A" .. oxy .. "Tas",
            	        ["3_d"] = "A" .. oxy .. "tas",
                	    ["1_p"] = "A" .. oxy .. "ma",
                    	["2_p"] = "A" .. oxy .. "Ta",
                	    ["3_p"] = "A" .. oxy .. "n",
                	}
            	}
        	}
		end
        
        local make_weak_sa_forms = function (oxy)
        	return {
            	["indic"] = {
            	    ["mv"] = {
                	    ["1_s"] = "i" .. oxy,
    	                ["2_d"] = "A" .. oxy .. "TAm",
            	        ["3_d"] = "A" .. oxy .. "tAm",
                	},
            	}
        	}
        end
		
		local make_weak_sa_inj_forms = function (oxy)
        	return {
            	["inj"] = {
            	    ["mv"] = {
                	    ["1_s"] = "i" .. oxy,
    	                ["2_d"] = "A" .. oxy .. "TAm",
            	        ["3_d"] = "A" .. oxy .. "tAm",
                    }
            	}
        	}
		end
    	
    	local make_weak_a_forms = function(oxy)
        	return {
	            ["indic"] = {
    	            ["mv"] = {
        	            ["1_s"] = "e" .. oxy,
	                    ["2_d"] = "e" .. oxy .. "TAm",
    	                ["3_d"] = "e" .. oxy .. "tAm",
                	}
            	}
        	}
    	end
    	
		local make_weak_a_inj_forms = function(oxy)
        	return {
	            ["inj"] = {
    	            ["mv"] = {
        	            ["1_s"] = "e" .. oxy,
	                    ["2_d"] = "e" .. oxy .. "TAm",
    	                ["3_d"] = "e" .. oxy .. "tAm",
                	}
                }
        	}
		end
		
        local make_weak_thematic_forms = function(oxy)
        	return {
	            ["indic"] = {
    	            ["mv"] = {
            	        ["2_s"] = "a" .. oxy .. "TAs",
                	    ["3_s"] = "a" .. oxy .. "ta",
                    	["1_d"] = "A" .. oxy .. "vahi",
        	            ["1_p"] = "A" .. oxy .. "mahi",
            	        ["2_p"] = "a" .. oxy .. "Dvam",
                	    ["3_p"] = "a" .. oxy .. "nta"
                	}
            	}
        	}
        end
		
		local make_weak_thematic_inj_forms = function(oxy)
        	return {
	            ["inj"] = {
    	            ["mv"] = {
            	        ["2_s"] = "a" .. oxy .. "TAs",
                	    ["3_s"] = "a" .. oxy .. "ta",
                    	["1_d"] = "A" .. oxy .. "vahi",
        	            ["1_p"] = "A" .. oxy .. "mahi",
            	        ["2_p"] = "a" .. oxy .. "Dvam",
                	    ["3_p"] = "a" .. oxy .. "nta"
                	}
                },
                ["subj"] = {
                	["mv"] = {
                        ["1_s"] = "E" .. oxy,
                        ["2_s"] = {"A" .. oxy .. "se", "A" .. oxy .. "sE"},
                        ["3_s"] = {"A" .. oxy .. "te", "A" .. oxy .. "tE"},
                        ["1_d"] = "A" .. oxy .. "vahE",
                        ["2_d"] = "E" .. oxy .. "Te",
                        ["3_d"] = "E" .. oxy .. "te",
                        ["1_p"] = {"A" .. oxy .. "mahe", "A" .. oxy .. "mahE"},
                        ["2_p"] = {"A" .. oxy .. "Dve", "A" .. oxy .. "DvE"},
                        ["3_p"] = "a" .. oxy .. "nta",  -- speculative (maybe also -ānte in Rigvedic period)
                    },
            	}
        	}
		end

        local strong_root_endings = { -- without 3p
            ["indic"] = {
                ["av"] = {
                    ["1_s"] = "am",
                    ["2_s"] = "s",
                    ["3_s"] = "t",
                    ["1_d"] = "va",
                    ["2_d"] = "tam",
                    ["3_d"] = "tAm",
                    ["1_p"] = "ma",
                    ["2_p"] = "ta",
                }
            }
        }
        
        local strong_root_inj_endings = { -- without 3p
            ["inj"] = {
                ["av"] = {
                    ["1_s"] = "am",
                    ["2_s"] = "s",
                    ["3_s"] = "t",
                    ["1_d"] = "va",
                    ["2_d"] = "tam",
                    ["3_d"] = "tAm",
                    ["1_p"] = "ma",
                    ["2_p"] = "ta",
                }
            },
            ["subj"] = {
                ["av"] = {
                    ["1_s"] = "Ani", -- subjunctives on -am have been suggested by Hoffmann, 'Der Injunktiv im Veda', p.248
                    ["2_s"] = {"as", "asi"},
                    ["3_s"] = {"at", "ati"},
                    ["1_d"] = "Ava",
                    ["2_d"] = "aTas",
                    ["3_d"] = "atas",
                    ["1_p"] = "Ama",
                    ["2_p"] = "aTa",
                    ["3_p"] = {"an", "anti"}, -- for ending '-anti', see for example 'Aufsätze zur Indoiranisch' p.385
                }
            }
        }
        
        local an_3p_root_ending = {
            ["indic"] = {
                ["av"] = {
                    ["3_p"] = "an",
                }
            }
        }
        
        local make_an_3p_root_inj = function(oxy)
        	return {
	            ["inj"] = {
    	            ["av"] = {
                	    ["3_p"] = "a" .. oxy .. "n"
                	}
            	}
        	}
        end
		
        local ur_3p_root_ending = {
            ["indic"] = {
                ["av"] = {
                    ["3_p"] = "ur",
                }
            }
        }
        
        local make_ur_3p_root_inj = function(oxy)
        	return {
	            ["inj"] = {
    	            ["av"] = {
                	    ["3_p"] = "u" .. oxy .. "r"
                	}
            	}
        	}
        end
    	
        -- middle only for some Vedic forms, the root-aorist can only be in active voice in Classical Sanskrit
        local middle_root_endings_vow = {
            ["indic"] = {
                ["mv"] = {
                    ["1_s"] = "i",
                    ["2_d"] = "ATAm",
                    ["3_d"] = "AtAm",
                    ["3_p"] = "ata"  -- but '-ran' frequently occurs, see Whitney §834b (probably originally a passive form)
                }
            }
        }
        
        local middle_root_endings_cons = {
            ["indic"] = {
                ["mv"] = {
                    ["2_s"] = "TAs",
                    ["3_s"] = "ta",
                    ["2_p"] = "Dvam",
                }
            }
        }
        
        local middle_root_endings_mvy = {
            ["indic"] = {
                ["mv"] = {
                    ["1_d"] = "vahi",
                    ["1_p"] = "mahi",
                }
            }
        }
        
        local make_middle_root_inj_forms_vow = function(oxy)
        	return {
	            ["inj"] = {
                	["mv"] = {
                		["1_s"] = "i" .. oxy,
            	    	["2_d"] = "A" .. oxy .. "TAm",
            	    	["3_d"] = "A" .. oxy .. "tAm",
            	    	["3_p"] = "a" .. oxy .. "nta"  -- not '-ata', see 'Aufsätze zur Indoiranistik' (Hoffmann), p.362
                	}
        		}
        	}
		end
        
        local make_middle_root_inj_forms_cons = function(oxy)
        	return {
	            ["inj"] = {
                	["mv"] = {
            	        ["2_s"] = "TA" .. oxy .. "s",
                	    ["3_s"] = "ta" .. oxy,
                    	["2_p"] = "Dva" .. oxy .. "m",
                	}
        		}
        	}
        end
		
		local make_middle_root_inj_forms_mvy = function(oxy)
        	return {
	            ["inj"] = {
                	["mv"] = {
                   		["1_d"] = "va" .. oxy .. "hi",
                	    ["1_p"] = "ma" .. oxy .. "hi",
                	}
        		}
        	}
		end
    	
    	-- the endings '-āsai', '-ātai' would rather occur in the Atharvaveda (which doesn't have many attestations of subjunctive middle aorists)
    	local middle_root_subj_endings = {
            ["subj"] = {
                ["mv"] = {
                    ["1_s"] = "E",
                    ["2_s"] = {"ase", "AsE"},
                    ["3_s"] = {"ate", "AtE"},
                    ["1_d"] = "AvahE",
                    ["2_d"] = "ETe",
                    ["3_d"] = "Ete",
                    ["1_p"] = {"Amahe", "AmahE"},
                    ["2_p"] = {"aDve", "ADvE"}, -- speculative
                    ["3_p"] = "anta"
        		}
            }
        }
        
        local t = {}
        local weak_lemma = args.weak_lemma or args.passive_lemma
        if (not args.aor or args.aor == "s" or args.aor == "ṣ") and detect_strong(t, args.strong_lemma, "(.+)[sz]It$") then
           	table.insert(data.categories, "Sanskrit verbs with s-aorist")
           	make_forms(args, data, t["strong_stem"], strong_s_endings)
           	
           	if change_to_inj_strong(args, t) then
           		make_forms(args, data, t["inj_strong_stem"], strong_s_inj_endings)
           	end
           	
           	if t["inj_strong"] then
           		-- root on ā, or hard-coded 'rādh' or '(av)āp' (Whitney gives no other roots with medial 'ā' for s-aorist) 
           		if match(t.inj_strong_stem, "A/?$") or match(t.inj_strong_stem, "rA/?D$") 
           		or match(t.inj_strong_stem, "^A/?p$") or match(t.inj_strong_stem, "^avA/?p$") then
           			t.subj_strong_stem = t.inj_strong_stem
           			make_forms(args, data, t["subj_strong_stem"], active_s_subj_endings)
           		elseif match(t.inj_strong_stem, "[AEOaeo]/?M?"..sa_utils.consonant.."*$") then
           			local vow_change = { ['A'] = 'a' , ['E'] = 'e', ['O'] = 'o', ['a'] = 'a', ['e'] = 'e', ['o'] = 'o' } 
           			t.subj_strong_stem = gasub(t.inj_strong_stem, "("..sa_utils.vowel..")(/?M?"..sa_utils.consonant.."*)$", 
           				function(a,b) return vow_change[a].. b end)
           			make_forms(args, data, t["subj_strong_stem"], active_s_subj_endings)
           		end
           	end
       	elseif (not args.aor or args.aor == "iṣ" or args.aor == "siṣ" or args.aor == "īṣ") and detect_strong(t, args.strong_lemma, "(.+)It$") then
        	if args.aor == "siṣ" then
        		table.insert(data.categories, "Sanskrit verbs with siṣ-aorist")
        		t.var_i = "i"
        		make_forms(args, data, t["strong_stem"], make_strong_is_forms(t["var_i"]))
        		if change_to_inj_strong(args, t) then
           			make_forms(args, data, t["inj_strong_stem"], make_strong_is_inj_forms(t["var_i"]))
           		end
        		-- middle forms for siṣ-aorist are not allowed by the grammarians (but might have existed: Whitney §915)
        	else
        		table.insert(data.categories, "Sanskrit verbs with iṣ-aorist")
        		if args.aor == "īṣ" then   -- in case of 'gra(b)h', see Whitney §900b
        			t.var_i = "I"
        		else
        			t.var_i = "i"
        		end
           		make_forms(args, data, t["strong_stem"], make_strong_is_forms(t["var_i"]))
           		
           		if change_to_inj_strong(args, t) then
           			-- the subjunctive stem for the iṣ-aorist is usually the same as the ind./inj. stem (Whitney §906b)
           			-- exception: san- vs. sān-
           			make_forms(args, data, t["inj_strong_stem"], make_strong_is_inj_forms(t["var_i"]))
           		end
           		
           		if use_strong_for_weak(t, weak_lemma) then
               		make_forms(args, data, t["weak_stem"], make_weak_is_forms(t["var_i"]))
               		if t["inj_strong"] then
               			make_forms(args, data, t["inj_strong_stem"], make_weak_is_inj_forms(t["var_i"]))
               		end
           		end
        	end
       	-- detection of oxytone accent in case of injunctive
       	elseif (not args.aor or args.aor == "sa") and detect_strong(t, args.strong_lemma, "(.+kz)a/?t$", "kza(/?)t$") then
       		table.insert(data.categories, "Sanskrit verbs with sa-aorist")
       		make_forms(args, data, t["strong_stem"], make_strong_thematic_forms(t["strong_oxy"]))
       		if change_to_inj_strong_oxy(args, t) then
           		make_forms(args, data, t["inj_strong_stem"], make_strong_thematic_inj_forms(t["inj_strong_oxy"]))
       		end
       		if use_strong_for_weak(t, weak_lemma) then
       			make_forms(args, data, t["weak_stem"], make_weak_sa_forms(t["weak_oxy"]))
       			make_forms(args, data, t["weak_stem"], make_weak_thematic_forms(t["weak_oxy"]))
       			if t["inj_strong"] then
       				make_forms(args, data, t["inj_strong_stem"], make_weak_sa_inj_forms(t["inj_strong_oxy"]))
       				make_forms(args, data, t["inj_strong_stem"], make_weak_thematic_inj_forms(t["inj_strong_oxy"]))
       			end
       		end
        elseif (not args.aor or args.aor == "a") and detect_strong(t, args.strong_lemma, "(.+)a/?t$", "a(/?)t$") then
        	table.insert(data.categories, "Sanskrit verbs with a-aorist")
        	make_forms(args, data, t["strong_stem"], make_strong_thematic_forms(t["strong_oxy"]))
           	if change_to_inj_strong_oxy(args, t) then
           		make_forms(args, data, t["inj_strong_stem"], make_strong_thematic_inj_forms(t["inj_strong_oxy"]))
           	end
           	if use_strong_for_weak(t, weak_lemma) then
               	make_forms(args, data, t["weak_stem"], make_weak_a_forms(t["weak_oxy"]))
           		make_forms(args, data, t["weak_stem"], make_weak_thematic_forms(t["weak_oxy"]))
               	if t["inj_strong"] then
               		make_forms(args, data, t["inj_strong_stem"], make_weak_a_inj_forms(t["inj_strong_oxy"]))
               		make_forms(args, data, t["inj_strong_stem"], make_weak_thematic_inj_forms(t["inj_strong_oxy"]))
               	end
           	end
       	-- the 't' of 'avart' should be detected as part of the stem
       	elseif (not args.aor or args.aor == "root") and ( detect_strong(t, args.strong_lemma, "(.+" .. sa_utils.vowel .. ")t$")
        or detect_strong(t, args.strong_lemma, "(.+[kNwRtnprlsH])$") or match(args.strong_lemma, "^<.+>$") ) then
            table.insert(data.categories, "Sanskrit verbs with root-aorist")
            make_forms(args, data, t["strong_stem"], strong_root_endings)
            
            if change_to_inj_strong(args, t) then
           		make_forms(args, data, t["inj_strong_stem"], strong_root_inj_endings)
           	end
            
            t.root_3p_stem = t.strong_stem
           	-- for active 3p, remove final ā from stem
			if match(t.strong_stem, "A$") then
				t.root_3p_stem = gasub(t.root_3p_stem, "A$", "")
				make_forms(args, data, t["root_3p_stem"], ur_3p_root_ending)
				t["ur_3p"] = true
           	elseif match(t.strong_stem, "U$") then -- for bhū
           		t.root_3p_stem = gasub(t.root_3p_stem, "U$", "Uv")
           		make_forms(args, data, t["root_3p_stem"], an_3p_root_ending)
       		-- else Vedic root-aorist, reconstructed to have strong stem in active forms, except 3p
       		-- attested forms (in Whitney) not following this pattern: 
       		-- 1) 'arudhma' (but this is probably rather an imperfect, from 'arundhma') and 2) 'aśravan'
           	else
           		t.root_3p_stem = gasub(t.root_3p_stem, "e("..sa_utils.consonant..")$", "i%1")
           		t.root_3p_stem = gasub(t.root_3p_stem, "o("..sa_utils.consonant..")$", "u%1")
           		t.root_3p_stem = gasub(t.root_3p_stem, "ar("..sa_utils.consonant..")$", "f%1")
           		t.root_3p_stem = gasub(t.root_3p_stem, "ar$", "r")
           		t.root_3p_stem = gasub(t.root_3p_stem, "("..sa_utils.consonant..sa_utils.consonant..")e$", "%1iy")
           		t.root_3p_stem = gasub(t.root_3p_stem, "e$", "y")
           		t.root_3p_stem = gasub(t.root_3p_stem, "("..sa_utils.consonant..sa_utils.consonant..")o$", "%1uv")
           		t.root_3p_stem = gasub(t.root_3p_stem, "o$", "v")
                t.root_3p_stem = gasub(t.root_3p_stem, "(a/?[tgm])a([mn])$", "%1%2")
                t.root_3p_stem = gasub(t.root_3p_stem, "(a/?j)an$", "%1Y")
                t.root_3p_stem = gasub(t.root_3p_stem, "(a/?)Gas$", "%1kz")
                if t.root_3p_stem == t.strong_stem then
                    make_forms(args, data, t["root_3p_stem"], ur_3p_root_ending)
                    t["ur_3p"] = true
                else
                    make_forms(args, data, t["root_3p_stem"], an_3p_root_ending)
           		end
           	end
           	if t["inj_strong"] then
           		if args.inj_weak_stem then
           			t.inj_root_3p_stem = to_SLP(args.inj_weak_stem)
           		elseif not args.inj_strong_stem then
           			t.inj_root_3p_stem = gasub(t.root_3p_stem, "^a/?(.+)$", "%1")
           			t.inj_root_3p_stem = gasub(t.inj_root_3p_stem, "^c(C.+)$", "%1")
           		else
           			t.inj_root_3p_stem = t.inj_strong_stem
           		end
           		t.inj_root_3p_oxy = gasub(t.root_3p_stem, "^[^/]+(/?).+$", "%1")
           		args.accent_override = true
           		if t["ur_3p"] then
           			make_forms(args, data, t["inj_root_3p_stem"], make_ur_3p_root_inj(t["inj_root_3p_oxy"]))
           		else
               		make_forms(args, data, t["inj_root_3p_stem"], make_an_3p_root_inj(t["inj_root_3p_oxy"]))
           		end
           		args.accent_override = false
            end
       	elseif args.strong_lemma ~= "-" then 
           	error("Could not detect aorist type from " .. to_IAST(args.strong_lemma)) -- failed to recognize an aorist type
       	end
        if weak_lemma then
        	-- if ends on -gdha, -ddha or -bdha, then the stem necessarily ends on resp. -h/dh/bh  (except '(a)gdha')
        	local aspirate = { ['g'] = 'h', ['d'] = 'D', ['b'] = 'B' }
        	weak_lemma = gasub(weak_lemma, '(.+)([gdb])(Da)$', function(a,b,c) return a .. aspirate[b].. c end)
        	if match(weak_lemma, "hDa$") then 
        		args.h_to_g = true
        	end
        	if (not args.aor or args.aor == "iṣ" or args.aor == "īṣ") and detect_weak(t, weak_lemma, "(.+)[iI]zwa$") then
                table.insert(data.categories, "Sanskrit verbs with iṣ-aorist")
                if args.aor == "īṣ" or match(args.weak_lemma, "Izwa$") then
                	t.var_i = "I"
                else
                	t.var_i = "i"
                end
                make_forms(args, data, t["weak_stem"], make_weak_is_forms(t["var_i"]))
                if change_to_inj_weak(args, t) then
           			make_forms(args, data, t["inj_weak_stem"], make_weak_is_inj_forms(t["var_i"]))
           		end
            elseif (not args.aor or args.aor == "s" or args.aor == "ṣ") and (detect_weak(t, weak_lemma, "(.+)sta$") or detect_weak(t, weak_lemma, "(.+)zwa$")
            or detect_weak(t, weak_lemma, "(.+[ktp])ta$") or detect_weak(t, weak_lemma, "(.+[ghdDbB])Da$")) then
                table.insert(data.categories, "Sanskrit verbs with s-aorist")
                make_forms(args, data, t["weak_stem"], weak_s_endings)
                if change_to_inj_weak(args, t) then
           			make_forms(args, data, t["inj_weak_stem"], weak_s_inj_endings)
           			-- for now only middle subjunctive for roots with guna in ind./inj.
           			if match(t.inj_weak_stem, "[Aeoa]/?M?"..sa_utils.consonant.."*$") then
           				t.subj_weak_stem = t.inj_weak_stem
           				make_forms(args, data, t["subj_weak_stem"], middle_s_subj_endings)
           			end
                end
       		elseif (not args.aor or args.aor == "sa") and detect_weak(t, weak_lemma, "(.+kz)a/?ta$", "kza(/?)ta$") then
                table.insert(data.categories, "Sanskrit verbs with sa-aorist")
                make_forms(args, data, t["weak_stem"], make_weak_sa_forms(t["weak_oxy"]))
                make_forms(args, data, t["weak_stem"], make_weak_thematic_forms(t["weak_oxy"]))
                if change_to_inj_weak_oxy(args, t) then
           			make_forms(args, data, t["inj_weak_stem"], make_weak_sa_inj_forms(t["inj_weak_oxy"]))
           			make_forms(args, data, t["inj_weak_stem"], make_weak_thematic_inj_forms(t["inj_weak_oxy"]))
           		end
            elseif (not args.aor or args.aor == "a") and detect_weak(t, weak_lemma, "(.+)a/?ta$", "a(/?)ta$") then
                table.insert(data.categories, "Sanskrit verbs with a-aorist")
                make_forms(args, data, t["weak_stem"], make_weak_a_forms(t["weak_oxy"]))
                make_forms(args, data, t["weak_stem"], make_weak_thematic_forms(t["weak_oxy"]))
                if change_to_inj_weak_oxy(args, t) then
           			make_forms(args, data, t["inj_weak_stem"], make_weak_a_inj_forms(t["inj_weak_oxy"]))
           			make_forms(args, data, t["inj_weak_stem"], make_weak_thematic_inj_forms(t["inj_weak_oxy"]))
           		end
            elseif (not args.aor or args.aor == "root") and detect_weak(t, weak_lemma, "(.+)[tDw]a$") then
                table.insert(data.categories, "Sanskrit verbs with root-aorist")
                make_forms(args, data, t["weak_stem"], middle_root_endings_vow)
                if change_to_inj_weak_oxy(args, t) then
           			make_forms(args, data, t["inj_weak_stem"], make_middle_root_inj_forms_vow(t["inj_weak_oxy"]))
                end
                
                if match(args.weak_lemma, sa_utils.vowel.."ta<.*>$") then  -- basically for roots gam/tan/man 
           	 		t.weak_stem = gasub(args.weak_lemma, "ta<.*>$", "")
                elseif match(args.weak_lemma, "^a/?gDa<.*>$") then		-- for 'gdha'
       	 			t.weak_stem = gasub(args.weak_lemma, "gDa<.*>$", "G")
           	 	end
                make_forms(args, data, t["weak_stem"], middle_root_endings_cons)
                if t["inj_weak"] then
                	if t["inj_weak"] == "2" then
                		t.inj_weak_stem = gasub(t.weak_stem, "^a/?(.+)$", "%1")
                	end
           			make_forms(args, data, t["inj_weak_stem"], make_middle_root_inj_forms_cons(t["inj_weak_oxy"]))
                end
                
                if args.extra_1p_stem then
                	t.weak_stem = to_SLP(args.extra_1p_stem)
            	end
                make_forms(args, data, t["weak_stem"], middle_root_endings_mvy)
                if t["inj_weak"] then
                	if t["inj_weak"] == "2" then
                		t.inj_weak_stem = gasub(t.weak_stem, "^a/?(.+)$", "%1")
                	end
           			make_forms(args, data, t["inj_weak_stem"], make_middle_root_inj_forms_mvy(t["inj_weak_oxy"]))
                end
                
                if args.inj_strong_stem then
                	t.inj_strong_stem = to_SLP(args.inj_strong_stem)
                	make_forms(args, data, t["inj_strong_stem"], middle_root_subj_endings)
                elseif t["inj_strong"] then
                	make_forms(args, data, t["inj_strong_stem"], middle_root_subj_endings)
                end
            else
                error("Could not detect aorist type from " .. to_IAST(weak_lemma)) -- failed to recognize an aorist type
            end
        end
    end
})

conj_data["bene"] = {}
setmetatable(conj_data["bene"], {
    __call = function (self, args, data)
        local make_strong_forms = function (oxy)
            return {
                ["optat"] = {
                    ["av"] = {
                        ["1_s"] = "yA" .. oxy .. "sam",
                        ["2_s"] = "yA" .. oxy .. "s",
                        ["3_s"] = {"yA" .. oxy .. "t", {"yA" .. oxy .. "s", note = "Vedic"}}, -- Whitney §838 for Vedic ending
                        ["1_d"] = "yA" .. oxy .. "sva",
                        ["2_d"] = "yA" .. oxy .. "stam",
                        ["3_d"] = "yA" .. oxy .. "stAm",
                        ["1_p"] = "yA" .. oxy .. "sma",
                        ["2_p"] = "yA" .. oxy .. "sta",
                        ["3_p"] = "yA" .. oxy .. "sur"
                    }
                }
            }
        end

        local make_weak_forms = function (oxy)
            return {
                ["optat"] = {
                    ["mv"] = {
                        ["1_s"] = "sIya" .. oxy,
                        ["2_s"] = "sIzWA" .. oxy .. "s",
                        ["3_s"] = "sIzwa" .. oxy,
                        ["1_d"] = "sIva" .. oxy .. "hi",
                        ["2_d"] = {{"sIyA" .. oxy .. "sTAm", note = "Uncertain"}}, -- Whitney §924a: "of very questionable value"
                        ["3_d"] = {{"sIyA" .. oxy .. "stAm", note = "Uncertain"}},
                        ["1_p"] = "sIma" .. oxy .. "hi",
                        ["2_p"] = "sIQva" .. oxy .. "m",
                        ["3_p"] = "sIra" .. oxy .. "n"
                    }
                }
            }
        end
		
        local t = {}
        if detect_strong(t, args.strong_lemma, "(.+)yA" .. sa_utils.accent .. "?t$", "yA(" .. sa_utils.accent .. "?)t$") then
            make_forms(args, data, t["strong_stem"], make_strong_forms(t["strong_oxy"]))
        elseif args.strong_lemma ~= "-" then
            validate(t["strong_stem"], args.strong_lemma)
        end
        
        local weak_lemma = args.weak_lemma or args.passive_lemma
        if weak_lemma then
			if detect_weak(t, weak_lemma, "(.+)[sz]Izwa" .. sa_utils.accent .. "?$", "[sz]Izwa(" .. sa_utils.accent .. "?)$") then
            	make_forms(args, data, t["weak_stem"], make_weak_forms(t["weak_oxy"]))
        	else
            	validate(t["weak_stem"], weak_lemma)
            end
        end
    end
})

conj_data["perf"] = {}
setmetatable(conj_data["perf"], {
    __call = function (self, args, data)
        local make_weak_forms_cons = function (oxy)   -- endings starting with consonant (except act. part.)
            return {
                ["indic"] = {
                    ["av"] = {
                        ["1_d"] = "va" .. oxy,
                        ["1_p"] = "ma" .. oxy,
                    },
                    ["mv"] = {
                        ["2_s"] = "se" .. oxy,
                        ["1_d"] = "va" .. oxy .. "he",
                        ["1_p"] = "ma" .. oxy .. "he",
                        ["2_p"] = "Dve" .. oxy,
                    }
                },
            }
        end
        
        local make_weak_forms_vow = function (oxy)		-- endings starting with vowel
            return {
                ["indic"] = {
                    ["av"] = {
                        ["2_d"] = "a" .. oxy .. "Tur",
                        ["3_d"] = "a" .. oxy .. "tur",
                        ["2_p"] = "a" .. oxy,
                        ["3_p"] = "u" .. oxy .. "s"
                    },
                    ["mv"] = {
                        ["1_s"] = "e" .. oxy,
                        ["3_s"] = "e" .. oxy,
                        ["2_d"] = "A" .. oxy .. "Te",
                        ["3_d"] = "A" .. oxy .. "te",
                        ["3_p"] = "ire" .. oxy
                    }
                },
                ["part"] = {
                    ["mv"] = "Ana" .. oxy
                }
            }
        end
        
        local make_vedic_anit_forms = function (oxy)
            return {
                ["indic"] = {
                    ["av"] = {
                        ["1_d"] = {{"va" .. oxy, note = "Vedic"}},
                        ["1_p"] = {{"ma" .. oxy, note = "Vedic"}},
                    },
                    ["mv"] = {
                        ["2_s"] = {{"se" .. oxy, note = "Vedic"}},
                        ["1_d"] = {{"va" .. oxy .. "he", note = "Vedic"}},
                        ["1_p"] = {{"ma" .. oxy .. "he", note = "Vedic"}},
                        ["2_p"] = {{"Dve" .. oxy, note = "Vedic"}},
                        ["3_p"] = {{"re" .. oxy, note = "Vedic"}},
                    }
                }
            }
        end
        
        local make_vedic_anit_mid_3p = function (oxy)
            return {
                ["indic"] = {
                    ["mv"] = {
                        ["3_p"] = {{"re" .. oxy, note = "Vedic"}},
                    }
                }
            }
        end
        
        local make_anit_perf_participle = function(oxy) 
        	return { ["part"] = { ["av"] = "vA" .. oxy .. "Ms" } }
        end
        
        local make_set_perf_participle = function(oxy) 
        	return { ["part"] = { ["av"] = "ivA" .. oxy .. "Ms" } }
        end
        
        local make_strong_au_forms = function(oxy) 
        	return {
				["indic"] = {
					["av"] = {
						["1_s"] = "O" .. oxy,
						["2_s"] = {"A" .. oxy .. "Ta", {"iTa" .. oxy, note = "Later Sanskrit"}},
						["3_s"] = "O" .. oxy,
					},
				}
       		}
        end
        
        local anit_perf_2s_ending = {
            ["indic"] = {
                ["av"] = {
                    ["2_s"] = "Ta"
                }
            }
        }
        
        local set_perf_2s_ending = {
            ["indic"] = {
                ["av"] = {
                    ["2_s"] = "iTa"
                }
            }
        }
        
        local set_perf_2s_ending_later_skt = {
            ["indic"] = {
                ["av"] = {
                    ["2_s"] = {{"iTa", note = "Later Sanskrit"}}
                }
            }
        }
        
        local make_weak_perf_2s = function(oxy)
        	return {
            	["indic"] = {
                	["av"] = {
                    	["2_s"] = {{"iTa" .. oxy, note = "Later Sanskrit"}}
                	}
            	}
        	}
        end
		
        local t = {}
        if detect_strong(t, args.strong_lemma, "(.+)O/?$", "O(/?)$") then
        	make_forms(args, data, t["strong_stem"], make_strong_au_forms(t["strong_oxy"]))
        	args.set = true
        	make_forms(args, data, t["strong_stem"], make_weak_forms_cons(t["strong_oxy"]))
        	make_forms(args, data, t["strong_stem"], make_set_perf_participle(t["strong_oxy"]))
        	make_forms(args, data, t["strong_stem"], make_weak_forms_vow(t["strong_oxy"]))
        else
        	if not detect_strong(t, args.strong_lemma, "(.+)a$") then
            	if not detect_strong(t, args.strong_lemma, "(.+)e" .. sa_utils.accent .. "?$", "e(" .. sa_utils.accent .. "?)$") then
                	validate(t["strong_stem"], args.strong_lemma)
            	else
                	args.n = "m" -- deponent
            	end
        	end
			
        	local weak_lemma = args.weak_lemma or args.passive_lemma
        	if not use_strong_for_weak(t, weak_lemma) then
            	if not detect_weak(t, weak_lemma, "(.+)u" .. sa_utils.accent .. "?[Hrs]$", "u(" .. sa_utils.accent .. "?)[Hrs]$") then
                	validate(t["weak_stem"], weak_lemma)
            	end
        	end
			
			-- if no strong stem supplied in case of e.g. cakāra, look at weak stem
			if match(args.strong_lemma, "A"..sa_utils.accent.."?"..sa_utils.consonant.."a$")
			and not match(t.weak_stem, "A"..sa_utils.accent.."?"..sa_utils.consonant.."$") then
				t.strong_stem = gasub(t.strong_stem, "A("..sa_utils.accent.."?.)$", "a%1")
			end
			
			-- if Brugmann's law is applicable
			if match(t.strong_stem, "a"..sa_utils.accent.."?"..sa_utils.consonant.."$")
			or match(t.strong_stem, "[eo]"..sa_utils.accent.."?$") then 
				make_forms(args, data, t["strong_stem"], {
					["indic"] = {
                		["av"] = {
                    		["1_s"] = {"a", {"aⓁ", note = "Later Sanskrit"}}, -- only 3 verbs with vriddhi-form in Vedic (Whitney §793d)
                			["3_s"] = "aⓁ",
                		},
            		}
            	})
			else
				make_forms(args, data, t["strong_stem"], {
					["indic"] = {
						["av"] = {
							["1_s"] = "a",
							["3_s"] = "a",
						},
					}
        		})
			end
			
			if args.weak_lemma and ( match(args.weak_lemma, sa_utils.consonant.."i?yu/?[Hrs]$") or match(args.weak_lemma, "uvu/?[Hrs]$") ) then
				error("Please add weak stem for active participle for roots on -i/-ī and -u/-ū.")
			elseif match(t.weak_stem, sa_utils.consonant .. 'r$') then
				t.weak_stem = gasub(t.weak_stem, 'r$', 'f')  -- change -r of weak stem to -ṛ if after consonant
			elseif match(t.weak_stem, "[uU]$") or match(t.weak_stem, sa_utils.consonant..sa_utils.consonant.."[iI]$") then
				args.no_syncope = true
			end
			
			-- anit roots (on -ṛ or -u) + 'vid'
			if ( match(t.weak_stem, "[uf]$") or match(t.weak_stem, "^vid$") or match(t.weak_stem, "[^sz]vid$") ) and not args.set == true then
				make_forms(args, data, t["strong_stem"], anit_perf_2s_ending)
				make_forms(args, data, t["weak_stem"], make_weak_forms_cons(t["weak_oxy"]))
				make_forms(args, data, t["weak_stem"], make_anit_perf_participle(t["weak_oxy"]))
				if match(args.weak_lemma, ".<.*>$") then
                	t.weak_stem = gasub(args.weak_lemma, "u/?[Hrs]<.*>$", "")
				end
        		make_forms(args, data, t["weak_stem"], make_weak_forms_vow(t["weak_oxy"]))
        		if match(t.weak_stem, "vid$") then
        			make_forms(args, data, t["weak_stem"], make_vedic_anit_mid_3p(t["weak_oxy"]))
        		end
			else
				args.set = false -- as this interferes with adding -tha
				-- rules for 2s
				if (match(t.strong_stem, "uva/?.$") and match(t.weak_stem, "U.$"))  -- e.g. uvac-
				or (match(t.strong_stem, "iya/?.$") and match(t.weak_stem, "I.$"))  -- iyaj-
				or (match(t.strong_stem, "[aA]/?[NYRnmM]?[^yrv]$") and (match(t.weak_stem, "e.$")	-- e.g. tatan- / ten-
					or match(t.weak_stem, sa_utils.consonant..sa_utils.consonant.."$")))  -- e.g. jajan- / jajñ-
				or match(t.strong_stem, "U/?v$")  -- babhūv-
				or match(t.strong_stem, "a/?[yvr]$") or match(t.strong_stem, "[eo]/?$") then -- e.g. ninay-, dadhar-
					make_forms(args, data, t["strong_stem"], anit_perf_2s_ending)  -- add -tha
					t["Ta_added"] = true
				end
				if match(t.strong_stem, "a/?[^yrlv]$") and match(t.weak_stem, "e.$") then
--				or match(t.weak_stem, sa_utils.consonant..sa_utils.consonant.."$")) then  -- this specific line might be wrong
					make_forms(args, data, t["weak_stem"], make_weak_perf_2s(t["weak_oxy"]))
				elseif match(t.strong_stem, "a/?[kKgGNcCjJYwWqQRtTdDnpPbBmLSzsh]$") then
					make_forms(args, data, t["strong_stem"], set_perf_2s_ending_later_skt)  -- add -itha (post-Vedic)
				else
					make_forms(args, data, t["strong_stem"], set_perf_2s_ending)  -- add -itha
				end
				if match(t.strong_stem, "a"..sa_utils.accent.."?"..sa_utils.consonant.."$") and not t.Ta_added then
					make_forms(args, data, t["strong_stem"], {
                		["indic"] = {
                    		["av"] = {
                        		["2_s"] = {{"Ta", note = "Vedic"}}
                    		}
                		}
            		})
				end
				
				-- use (supplied) weak stem for participle
				if sa_utils.is_monosyllabic(t.weak_stem) or args.mono == true then	-- not accurate for some verbs (Whitney §803a)
        			make_forms(args, data, t["weak_stem"], make_set_perf_participle(t["weak_oxy"]))
        		else
        			make_forms(args, data, t["weak_stem"], make_anit_perf_participle(t["weak_oxy"]))
				end
				
				-- change weak stem to form used in 3p
				if args.weak_lemma then
					if match(args.weak_lemma, ".<.*>$") then
						t.weak_stem = gasub(args.weak_lemma, "u/?[Hrs]<.*>$", "")
					else 
						t.weak_stem = gasub(t.weak_stem, "("..sa_utils.consonant..")f$", "%1r")
						t.weak_stem = gasub(t.weak_stem, "[uU]$", "uv")
						t.weak_stem = gasub(t.weak_stem, "("..sa_utils.vowel..sa_utils.consonant..")[iI]$", "%1y")
						t.weak_stem = gasub(t.weak_stem, "("..sa_utils.consonant..sa_utils.consonant..")[iI]$", "%1iy")
					end
				end
				args.set = true
				make_forms(args, data, t["weak_stem"], make_weak_forms_cons(t["weak_oxy"]))
				make_forms(args, data, t["weak_stem"], make_weak_forms_vow(t["weak_oxy"]))
				
				-- Vedic rules from Whitney §798a (omitting y/r/l/v from the consonants 
				-- as r+r is not allowed and none of them are among Wh.'s examples)
				if match(t.weak_stem, "[aiufx][kKgGNcCjJYwWqQRtTdDnpPbBmLSzsh]$") then
					args.set = false
					if args.weak_lemma and match(args.weak_lemma, "<.*>$") then
						t.weak_stem = gasub(args.weak_lemma, "^.*<(.*)>$", "%1")
					end
					make_forms(args, data, t["weak_stem"], make_vedic_anit_forms(t["weak_oxy"]))
				end
			end
        end
    end
})

local function legacy_split_stems(form)
	return split(form, ",")
end

-- Gets stems for COMPLEX_FORM given a pattern in MATCH_RE
local function legacy_get_stem(complex_form, match_re)
    local s = split_xs(complex_form)
    if s[2] ~= nil then return s[2] end
    return match(s[1], match_re)
end


-- Returns { stems, accents }
local function legacy_get_stems_from_lemmas(lemma, match_pattern, oxy_match_pattern)
	local strong_lemmas = legacy_split_stems(lemma)
    local strong_stems = {}
    local oxys = nil
    if oxy_match_pattern ~= nil then
    	oxys = {}
    end
    for i, strong_lemma in ipairs(strong_lemmas) do
        local prov = split_xs(strong_lemma)[1]
        if oxy_match_pattern ~= nil then
        	oxys[i] = match(prov, oxy_match_pattern)
        end
        strong_stems[i] = legacy_get_stem(strong_lemma, match_pattern)
        validate(strong_stems[i], strong_lemma)
    end
    return { strong_stems, oxys }
end

conj_data["nonf"] = {}
setmetatable(conj_data["nonf"], {
    -- TODO: this whole system needs to be removed
    -- it's kept just so as to not break verbal entries which use this module, but non-finite forms
    -- should now be part of the root derivations and not tied to the verbal conjugation
    __call = function (self, args, data)
        local make_strong_forms = function (oxy)
            return {
                ["gerundive_mn"] = { "ya", "tavya" .. oxy, "anI" .. oxy .. "ya" },
                ["gerundive_f"] = { "yA", "tavyA" .. oxy, "anI" .. oxy .. "yA" } 
            }
        end

        local make_weak_forms = function (oxy)
            return {
                ["gerund"] = "tvA" .. oxy,
                ["part_mn"] = "ta" .. oxy,
                ["part_f"] = "tA" .. oxy
            }
        end
        
        local strong_stems = legacy_get_stems_from_lemmas(
        	args.strong_lemma,
        	"(.+)ya$",
        	"(" .. sa_utils.accent .. "?)"
        )
        
        for i, strong_stem in ipairs(strong_stems[1]) do
        	make_forms(args, data, strong_stem, {
	        	["inf"] = "tum"
	        })
	        
	        strong_stem = gsub(strong_stem, sa_utils.accent, "")
	        make_forms(args, data, strong_stem, make_strong_forms(strong_stems[2][i]))
	        local ya_form = #(data.forms["gerundive_mn"]) - 2 -- TODO: This is not a great way of doing this
	        local prov = split_xs(legacy_split_stems(args.strong_lemma)[i])[1]
	        data.forms["gerundive_mn"][1] = prov
	        data.forms["gerundive_f"][1] = match(prov, "(.+)a$") .. "A"
        end

        local weak_lemma = args.weak_lemma or args.passive_lemma
        if weak_lemma == nil then
        	for i, strong_stem in ipairs(strong_stems[1]) do
            	make_forms(args, data, gsub(strong_stem, sa_utils.accent, ""), make_weak_forms(strong_stems[2][i]))
            end
        else
        	local weak_stems = legacy_get_stems_from_lemmas(
        		weak_lemma,
        		"(.+).a" .. sa_utils.accent .. "?$",
        		"a(" .. sa_utils.accent .. "?)$"
        	)
        	
        	for i, weak_stem in ipairs(weak_stems[1]) do
        		make_forms(args, data, weak_stem, make_weak_forms(weak_stems[2][i]))
        	end
        end
    end
})

return conj_data
"https://si.wiktionary.org/w/index.php?title=Module:sa-verb/data&oldid=199786" වෙතින් සම්ප්‍රවේශනය කෙරිණි