local x=utf8.len local t=utf8.codes local function Z(Z,o)if Z==o then return 0 end local b=x(Z)local V=x(o)if b==0 then return V elseif V==0 then return b end local y={}for x=0,b,1 do y[x]={[0]=x}end for x=0,V,1 do y[0][x]=x end local j=1 local v for x,Z in t(Z)do local b=1 local V for x,t in t(o)do local o=Z==t and 0 or 1 v=j-1 V=b-1 y[j][b]=math.min(y[v][b]+1,y[j][V]+1,y[v][V]+o)b=b+1 end j=j+1 end return y[b][V]end local function o(x,t)return x.Distance<t.Distance end local function b(x,t,b)local V=table.create(#t)for t,o in ipairs(t)do V[t]={String=o,Distance=Z(x,o)}end table.sort(V,o)return V end return b
-- Returns the Levenshtein distance between the two given strings
local utf8_len = utf8.len -- I'm not even sure if this is faster localized, thanks Luau and your massive inconsistency.
local utf8_codes = utf8.codes

local function Levenshtein(String1, String2)
	if String1 == String2 then
		return 0
	end

	local Length1 = utf8_len(String1)
	local Length2 = utf8_len(String2)

	if Length1 == 0 then
		return Length2
	elseif Length2 == 0 then
		return Length1
	end

	local Matrix = {} -- Would love to use table.create for this, but it starts at 0.
	for Index = 0, Length1 do
		Matrix[Index] = { [0] = Index }
	end

	for Index = 0, Length2 do
		Matrix[0][Index] = Index
	end

	local Index = 1
	local IndexSub1

	for _, Code1 in utf8_codes(String1) do
		local Jndex = 1
		local JndexSub1

		for _, Code2 in utf8_codes(String2) do
			local Cost = Code1 == Code2 and 0 or 1
			IndexSub1 = Index - 1
			JndexSub1 = Jndex - 1

			Matrix[Index][Jndex] = math.min(
				Matrix[IndexSub1][Jndex] + 1,
				Matrix[Index][JndexSub1] + 1,
				Matrix[IndexSub1][JndexSub1] + Cost
			)
			Jndex = Jndex + 1
		end

		Index = Index + 1
	end

	return Matrix[Length1][Length2]
end

local function SortResults(A, B)
	return A.Distance < B.Distance
end

local function FuzzySearch(String, ArrayOfStrings, MaxResults)
	local Results = table.create(#ArrayOfStrings)

	for Index, Value in ipairs(ArrayOfStrings) do
		Results[Index] = {
			String = Value,
			Distance = Levenshtein(String, Value),
		}
	end

	table.sort(Results, SortResults)
	return Results
end

return FuzzySearch
