_G.BTLibraryList=_G.BTLibraryList or{}local c=_G.BTLibraryList function GetLibrary(f)local V,Y=f:match(NamePattern)local W,y,M,v=f:match(VersionPattern)local G,E,P=tonumber(y),tonumber(M),tonumber(v)assert(W and(G and(E and P)),"\073\110\118\097\108\105\100 \118\101\114\115\105\111\110")if not(V and Y)then return end if not W then for c,f in ipairs(c)do if f.Creator:lower()==V:lower()and f.Name:lower()==Y:lower()then return f.Library end end elseif W==""then for c,f in ipairs(c)do if f.Creator:lower()==V:lower()and(f.Name:lower()==Y:lower()and(f.Version.Major==G and(f.Version.Minor==E and f.Version.Patch==P)))then return f.Library end end elseif W=="~"then for c,f in ipairs(c)do if f.Creator:lower()==V:lower()and(f.Name:lower()==Y:lower()and(f.Version.Major==G and f.Version.Minor==E))then return f.Library end end elseif W=="\094"then for c,f in ipairs(c)do if f.Creator:lower()==V:lower()and(f.Name:lower()==Y:lower()and f.Version.Major==G)then return f.Library end end end end function GetLibraries(...)local c={...}local f={}for c,V in ipairs(c)do f[c]=GetLibrary(V)end return unpack(f,1,table.maxn(f))end function RegisterLibrary(f,V)assert(type(f.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(f.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(f.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(f.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(f.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(f.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(f.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(f.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 Y={Name=f.Name;Creator=f.Creator;Version={Major=f.Version.Major,Minor=f.Version.Minor;Patch=f.Version.Patch};Library=V}table.insert(c,Y)table.sort(c,function(c,f)if c.Version.Major>f.Version.Major then return true elseif c.Version.Major==f.Version.Major then if c.Version.Minor>f.Version.Minor then return true elseif c.Version.Minor==f.Version.Minor then return c.Version.Patch>f.Version.Patch else return false end else return false end end)end

_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;
