_G.BTLibraryList=_G.BTLibraryList or{}local j=_G.BTLibraryList function GetLibrary(Z)local h,n=Z:match(NamePattern)local W,S,f,x=Z:match(VersionPattern)local a,V,v=tonumber(S),tonumber(f),tonumber(x)assert(W and(a and(V and v)),"\073\110\118\097\108\105\100 \118\101\114\115\105\111\110")if not(h and n)then return end if not W then for j,Z in ipairs(j)do if Z.Creator:lower()==h:lower()and Z.Name:lower()==n:lower()then return Z.Library end end elseif W==""then for j,Z in ipairs(j)do if Z.Creator:lower()==h:lower()and(Z.Name:lower()==n:lower()and(Z.Version.Major==a and(Z.Version.Minor==V and Z.Version.Patch==v)))then return Z.Library end end elseif W=="~"then for j,Z in ipairs(j)do if Z.Creator:lower()==h:lower()and(Z.Name:lower()==n:lower()and(Z.Version.Major==a and Z.Version.Minor==V))then return Z.Library end end elseif W=="\094"then for j,Z in ipairs(j)do if Z.Creator:lower()==h:lower()and(Z.Name:lower()==n:lower()and Z.Version.Major==a)then return Z.Library end end end end function GetLibraries(...)local j={...}local Z={}for j,h in ipairs(j)do Z[j]=GetLibrary(h)end return unpack(Z,1,table.maxn(Z))end function RegisterLibrary(Z,h)assert(type(Z.Name)=="\115\116\114\105\110\103","\076\105\098\114\097\114\121 \110\097\109\101 \109\117\115\116 \098\101 \097 \115\116\114\105\110\103")assert(type(Z.Creator)=="\115\116\114\105\110\103","\076\105\098\114\097\114\121 \099\114\101\097\116\111\114 \109\117\115\116 \098\101 \097 \115\116\114\105\110\103")assert(Z.Name:match("\094\091\065-\090\097-\122\048-\057\095-\093\043\036"),"\076\105\098\114\097\114\121 \110\097\109\101 \099\111\110\116\097\105\110\115 \105\110\118\097\108\105\100 \099\104\097\114\097\099\116\101\114\115")assert(Z.Creator:match("\094\091\065-\090\097-\122\048-\057\095-\093\043\036"),"\076\105\098\114\097\114\121 \099\114\101\097\116\111\114 \099\111\110\116\097\105\110\115 \105\110\118\097\108\105\100 \099\104\097\114\097\099\116\101\114\115")assert(type(Z.Version)=="\116\097\098\108\101","\073\110\118\097\108\105\100 \108\105\098\114\097\114\121 \118\101\114\115\105\111\110 \100\097\116\097")assert(type(Z.Version.Major)=="\110\117\109\098\101\114","\073\110\118\097\108\105\100 \108\105\098\114\097\114\121 \118\101\114\115\105\111\110 \100\097\116\097")assert(type(Z.Version.Minor)=="\110\117\109\098\101\114","\073\110\118\097\108\105\100 \108\105\098\114\097\114\121 \118\101\114\115\105\111\110 \100\097\116\097")assert(type(Z.Version.Patch)=="\110\117\109\098\101\114","\073\110\118\097\108\105\100 \108\105\098\114\097\114\121 \118\101\114\115\105\111\110 \100\097\116\097")local n={Name=Z.Name;Creator=Z.Creator,Version={Major=Z.Version.Major,Minor=Z.Version.Minor;Patch=Z.Version.Patch},Library=h}table.insert(j,n)table.sort(j,function(j,Z)if j.Version.Major>Z.Version.Major then return true elseif j.Version.Major==Z.Version.Major then if j.Version.Minor>Z.Version.Minor then return true elseif j.Version.Minor==Z.Version.Minor then return j.Version.Patch>Z.Version.Patch else return false end else return false end end)end
-- Initialize cached library list
_G.BTLibraryList = _G.BTLibraryList or {}
local LibraryList = _G.BTLibraryList

function GetLibrary(LibraryID)
	-- Returns the requested library

	-- Parse library ID
	local Creator, Name = LibraryID:match(NamePattern)
	local VersionRange, Major, Minor, Patch = LibraryID:match(VersionPattern)

	-- Convert version data to numbers
	local Major, Minor, Patch = tonumber(Major), tonumber(Minor), tonumber(Patch)

	-- Validate version information
	assert(VersionRange and (Major and Minor and Patch), "Invalid version")

	-- Ensure library ID was given
	if not (Creator and Name) then
		return
	end

	-- If no version provided, return latest
	if not VersionRange then
		for _, Library in ipairs(LibraryList) do
			if (Library.Creator:lower() == Creator:lower()) and (Library.Name:lower() == Name:lower()) then
				return Library.Library
			end
		end

	-- If exact version provided, return that version
	elseif VersionRange == "" then
		for _, Library in ipairs(LibraryList) do
			if
				(Library.Creator:lower() == Creator:lower())
				and (Library.Name:lower() == Name:lower())
				and (Library.Version.Major == Major)
				and (Library.Version.Minor == Minor)
				and (Library.Version.Patch == Patch)
			then
				return Library.Library
			end
		end

	-- If minor version specified, return latest compatible patch version
	elseif VersionRange == "~" then
		for _, Library in ipairs(LibraryList) do
			if
				(Library.Creator:lower() == Creator:lower())
				and (Library.Name:lower() == Name:lower())
				and (Library.Version.Major == Major)
				and (Library.Version.Minor == Minor)
			then
				return Library.Library
			end
		end

	-- If major version specified, return latest compatible minor or patch version
	elseif VersionRange == "^" then
		for _, Library in ipairs(LibraryList) do
			if
				(Library.Creator:lower() == Creator:lower())
				and (Library.Name:lower() == Name:lower())
				and (Library.Version.Major == Major)
			then
				return Library.Library
			end
		end
	end
end

function GetLibraries(...)
	-- Returns the requested libraries by their IDs

	local RequestedLibraries = { ... }
	local FoundLibraries = {}

	-- Get each library
	for Index, LibraryID in ipairs(RequestedLibraries) do
		FoundLibraries[Index] = GetLibrary(LibraryID)
	end

	-- Return the found libraries
	return unpack(FoundLibraries, 1, table.maxn(FoundLibraries))
end

function RegisterLibrary(Metadata, Library)
	-- Registers the given library with its metadata into the cache list

	-- Validate metadata
	assert(type(Metadata.Name) == "string", "Library name must be a string")
	assert(type(Metadata.Creator) == "string", "Library creator must be a string")
	assert(Metadata.Name:match("^[A-Za-z0-9_-]+$"), "Library name contains invalid characters")
	assert(Metadata.Creator:match("^[A-Za-z0-9_-]+$"), "Library creator contains invalid characters")
	assert(type(Metadata.Version) == "table", "Invalid library version data")
	assert(type(Metadata.Version.Major) == "number", "Invalid library version data")
	assert(type(Metadata.Version.Minor) == "number", "Invalid library version data")
	assert(type(Metadata.Version.Patch) == "number", "Invalid library version data")

	-- Structure metadata
	local Metadata = {
		Name = Metadata.Name,
		Creator = Metadata.Creator,
		Version = {
			Major = Metadata.Version.Major,
			Minor = Metadata.Version.Minor,
			Patch = Metadata.Version.Patch,
		},
		Library = Library,
	}

	-- Insert the library and its metadata into the list
	table.insert(LibraryList, Metadata)

	-- Sort the list by version (from latest to earliest)
	table.sort(LibraryList, function(A, B)
		-- Sort by major version
		if A.Version.Major > B.Version.Major then
			return true

		-- Sort by minor version when major version is same
		elseif A.Version.Major == B.Version.Major then
			if A.Version.Minor > B.Version.Minor then
				return true

			-- Sort by patch version when same major and minor version
			elseif A.Version.Minor == B.Version.Minor then
				return A.Version.Patch > B.Version.Patch
			else
				return false
			end

		-- Sort A after B if earlier version
		else
			return false
		end
	end)
end
