local Q={}Q.__index=Q local M=string.sub local J=string.byte local w=string.char local v=string.gsub local a=string.find function Q.new()local M=setmetatable({IndexTable="\065\066\067\068\069\070\071\072\073\074\075\076\077\078\079\080\081\082\083\084\085\086\087\088\089\090\097\098\099\100\101\102\103\104\105\106\107\108\109\110\111\112\113\114\115\116\117\118\119\120\121\122\048\049\050\051\052\053\054\055\056\057\043\047"},Q)return M end function Q.__BinaryEncode(M,Q)local J=tonumber(Q)local w=""for Q=7,0,-1 do local M=2^Q if J>=M then w=w.."\049"J=J-M else w=w.."\048"end end return w end function Q.__BinaryDecode(M,Q)return tonumber(Q,2)end function Q.Encode(w,Q)local v=""local a=""local f=""for a=1,#Q,1 do v=v..w:__BinaryEncode(J(M(Q,a,a)))end if#v%3==2 then f="\061\061"v=v.."\048\048\048\048\048\048\048\048\048\048\048\048\048\048\048\048"elseif#v%3==1 then f="\061"v=v.."\048\048\048\048\048\048\048\048"end for Q=1,#v,6 do local J=M(v,Q,Q+5)local f=tonumber(w:__BinaryDecode(J))a=a..M(w.IndexTable,f+1,f+1)end return M(a,1,-1-#f)..f end function Q.Decode(J,Q)local f=v(Q,"\037\115","")local z=v(f,"\061","")local U=""local j=""for w=1,#z,1 do local v=M(Q,w,w)local f,z=a(J.IndexTable,v)if f==nil then error("\073\110\118\097\108\105\100 \099\104\097\114\097\099\116\101\114 \""..(v.."\" \102\111\117\110\100\046"))end U=U..M(J:__BinaryEncode(f-1),3)end for Q=1,#U,8 do local v=M(U,Q,Q+7)j=j..w(J:__BinaryDecode(v))end local K=#f-#z if K==1 or K==2 then j=M(j,1,-2)end return j end return Q
--- Base64
-- Encodes and decodes values to and from Base64
-- @author antifragileer <https://www.roblox.com/users/443282130/profile>
-- @see Developed for the Aero Game Framework <https://github.com/Sleitnick/AeroGameFramework>
-- @see Adapted from https://github.com/toastdriven/lua-base64 for the Roblox game.
-- @license BSD
-- July 15, 2018

--[[
	
	local base64 = Base64.new()
	
	Example:
	
	local myEncodedWord = base64:Encode("Hello")
	
	print(myEncodedWord)
	
	-- outputs: SGVsbG8=
	
	print(base64:Decode(myEncodedWord))
	
	-- outputs: Hello

--]]


local Base64 = {}
Base64.__index = Base64

local sub = string.sub
local byte = string.byte
local char = string.char
local gsub = string.gsub
local find = string.find

--- Object constructor
-- @return Base64
function Base64.new()
	
	local self = setmetatable({
		IndexTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
	}, Base64)
	
	return self
	
end

--- Converts an integer to binary
-- @private
-- @param number Integer
-- @return string
function Base64:__BinaryEncode(Integer)
	
	local Remaining = tonumber(Integer)
	local BinaryBits = ''

	for i = 7, 0, -1 do
		local CurrentPower = 2 ^ i

		if Remaining >= CurrentPower then
			BinaryBits = BinaryBits .. '1'
			Remaining = Remaining - CurrentPower
		else
			BinaryBits = BinaryBits .. '0'
		end
	end

	return BinaryBits
	
end

--- Converts a binary bit to a number
-- @private
-- @param string BinaryBits
-- @return number
function Base64:__BinaryDecode(BinaryBits)
	
	return tonumber(BinaryBits, 2)
	
end

--- Converts a string or number to a Base64 value
-- @public
-- @param string|number Value
-- @return string
function Base64:Encode(Value)

	local BitPattern = ''
	local Encoded = ''
	local Trailing = ''

	for i = 1, #Value do
		BitPattern = BitPattern .. self:__BinaryEncode(byte(sub(Value, i, i)))
	end

	-- Check the number of bytes. If it's not evenly divisible by three,
	-- zero-pad the ending & append on the correct number of ``=``s.
	if #BitPattern % 3 == 2 then
		Trailing = '=='
		BitPattern = BitPattern .. '0000000000000000'
	elseif #BitPattern % 3 == 1 then
		Trailing = '='
		BitPattern = BitPattern .. '00000000'
	end

	for i = 1, #BitPattern, 6 do
		local Byte = sub(BitPattern, i, i+5)
		local Offset = tonumber(self:__BinaryDecode(Byte))
		
		Encoded = Encoded .. sub(self.IndexTable, Offset+1, Offset+1)
	end

	return sub(Encoded, 1, -1 - #Trailing) .. Trailing

end

--- Converts a Base64 encoded string to its original value
-- @public
-- @param string Value
-- @return string
function Base64:Decode(Value)
	
	local Padded = gsub(Value, "%s", "")
	local Unpadded = gsub(Padded, "=", "")
	local BitPattern = ''
	local Decoded = ''

	for i = 1, #Unpadded do
		local Char = sub(Value, i, i)
		local Offset, _ = find(self.IndexTable, Char)

		if Offset == nil then
			error("Invalid character \"" .. Char .. "\" found.")
		end

		BitPattern = BitPattern .. sub(self:__BinaryEncode(Offset-1), 3)
	end

	for i = 1, #BitPattern, 8 do
		local Byte = sub(BitPattern, i, i+7)

		Decoded = Decoded .. char(self:__BinaryDecode(Byte))
	end

	local PaddingLength = #Padded-#Unpadded

	if (PaddingLength == 1 or PaddingLength == 2) then
		Decoded = sub(Decoded, 1,-2)
	end

	return Decoded

end


return Base64
