local T={pretty=false;robloxFullName=false;robloxProperFullName=true;robloxClassName=true,tabs=false;semicolons=false,spaces=3,sortKeys=true}local N={["\097\110\100"]=true;["\098\114\101\097\107"]=true;["\100\111"]=true;["\101\108\115\101"]=true,["\101\108\115\101\105\102"]=true;["\101\110\100"]=true,["\102\097\108\115\101"]=true;["\102\111\114"]=true,["\102\117\110\099\116\105\111\110"]=true;["\105\102"]=true,["\105\110"]=true,["\108\111\099\097\108"]=true;["\110\105\108"]=true,["\110\111\116"]=true,["\111\114"]=true,["\114\101\112\101\097\116"]=true;["\114\101\116\117\114\110"]=true,["\116\104\101\110"]=true;["\116\114\117\101"]=true,["\117\110\116\105\108"]=true;["\119\104\105\108\101"]=true}local function Z(T)if type(T)~="\115\116\114\105\110\103"then return false end if T:len()==0 then return false end if T:find("\091\094\037\100\037\097\095\093")then return false end if tonumber(T:sub(1,1))then return false end if N[T]then return false end return true end local function E(T,N)if T==nil or T==game then return""end local S=T.Name local t=true if not Z(S)then S=("\091\037\113\093"):format(S)t=false end if not T.Parent or T.Parent==game then return S else return E(T.Parent)..((t and"\046"or"")..S)end end local S=0 local t local g local Y local function P(N,Y)Y=Y or T g=(" "):rep(Y.spaces or T.spaces)if Y.tabs then g="\t"end local O=N local G=g:rep(S)if S==0 then t={}end if type(O)=="\115\116\114\105\110\103"then return("\037\113"):format(O)elseif type(O)=="\110\117\109\098\101\114"then if O==math.huge then return"\109\097\116\104\046\104\117\103\101"end if O==-math.huge then return"-\109\097\116\104\046\104\117\103\101"end return tonumber(O)elseif type(O)=="\098\111\111\108\101\097\110"then return tostring(O)elseif type(O)=="\110\105\108"then return"\110\105\108"elseif type(O)=="\116\097\098\108\101"and type(O.__tostring)=="\102\117\110\099\116\105\111\110"then return tostring(O.__tostring(O))elseif type(O)=="\116\097\098\108\101"and(getmetatable(O)and type((getmetatable(O)).__tostring)=="\102\117\110\099\116\105\111\110")then return tostring((getmetatable(O)).__tostring(O))elseif type(O)=="\116\097\098\108\101"then if t[O]then return"\123\067\089\067\076\073\067\125"end t[O]=true local T="\123"..(Y.pretty and"\n"..(g..G)or"")local N=true for T,Z in pairs(O)do if type(T)~="\110\117\109\098\101\114"then N=false break end end if N then for N=1,#O,1 do if N~=1 then T=T..((Y.semicolons and"\059"or"\044")..(Y.pretty and"\n"..(g..G)or" "))end S=S+1 T=T..P(O[N],Y)S=S-1 end else local N={}local E={}for T,t in pairs(O)do S=S+1 local g=Z(T)and T or"\091"..(P(T,Y).."\093")local O=P(t,Y)table.insert(N,g)E[g]=O S=S-1 end if Y.sortKeys then table.sort(N)end local t=true for N,Z in pairs(N)do if not t then T=T..((Y.semicolons and"\059"or"\044")..(Y.pretty and"\n"..(g..G)or" "))end T=T..("\037\115 \061 \037\115"):format(Z,E[Z])t=false end end t[O]=false if Y.pretty then T=T..("\n"..G)end T=T.."\125"return T elseif typeof then if typeof(O)=="\073\110\115\116\097\110\099\101"then return(Y.robloxFullName and(Y.robloxProperFullName and E(O)or O:GetFullName())or O.Name)..(Y.robloxClassName and(" \040\037\115\041"):format(O.ClassName)or"")elseif typeof(O)=="\065\120\101\115"then local T={}if O.X then table.insert(T,P(Enum.Axis.X,Y))end if O.Y then table.insert(T,P(Enum.Axis.Y,Y))end if O.Z then table.insert(T,P(Enum.Axis.Z,Y))end return("\065\120\101\115\046\110\101\119\040\037\115\041"):format(table.concat(T,"\044 "))elseif typeof(O)=="\066\114\105\099\107\067\111\108\111\114"then return("\066\114\105\099\107\067\111\108\111\114\046\110\101\119\040\037\113\041"):format(O.Name)elseif typeof(O)=="\067\070\114\097\109\101"then return("\067\070\114\097\109\101\046\110\101\119\040\037\115\041"):format(table.concat({O:GetComponents()},"\044 "))elseif typeof(O)=="\067\111\108\111\114\051"then return("\067\111\108\111\114\051\046\110\101\119\040\037\100\044 \037\100\044 \037\100\041"):format(O.r,O.g,O.b)elseif typeof(O)=="\067\111\108\111\114\083\101\113\117\101\110\099\101"then if#O.Keypoints>2 then return("\067\111\108\111\114\083\101\113\117\101\110\099\101\046\110\101\119\040\037\115\041"):format(P(O.Keypoints,Y))else if O.Keypoints[1].Value==O.Keypoints[2].Value then return("\067\111\108\111\114\083\101\113\117\101\110\099\101\046\110\101\119\040\037\115\041"):format(P(O.Keypoints[1].Value,Y))else return("\067\111\108\111\114\083\101\113\117\101\110\099\101\046\110\101\119\040\037\115\044 \037\115\041"):format(P(O.Keypoints[1].Value,Y),P(O.Keypoints[2].Value,Y))end end elseif typeof(O)=="\067\111\108\111\114\083\101\113\117\101\110\099\101\075\101\121\112\111\105\110\116"then return("\067\111\108\111\114\083\101\113\117\101\110\099\101\075\101\121\112\111\105\110\116\046\110\101\119\040\037\100\044 \037\115\041"):format(O.Time,P(O.Value,Y))elseif typeof(O)=="\068\111\099\107\087\105\100\103\101\116\080\108\117\103\105\110\071\117\105\073\110\102\111"then return("\068\111\099\107\087\105\100\103\101\116\080\108\117\103\105\110\071\117\105\073\110\102\111\046\110\101\119\040\037\115\044 \037\115\044 \037\115\044 \037\115\044 \037\115\044 \037\115\044 \037\115\041"):format(P(O.InitialDockState,Y),P(O.InitialEnabled,Y),P(O.InitialEnabledShouldOverrideRestore,Y),P(O.FloatingXSize,Y),P(O.FloatingYSize,Y),P(O.MinWidth,Y),P(O.MinHeight,Y))elseif typeof(O)=="\069\110\117\109\115"then return"\069\110\117\109\115"elseif typeof(O)=="\069\110\117\109"then return("\069\110\117\109\046\037\115"):format(tostring(O))elseif typeof(O)=="\069\110\117\109\073\116\101\109"then return("\069\110\117\109\046\037\115\046\037\115"):format(tostring(O.EnumType),O.Name)elseif typeof(O)=="\070\097\099\101\115"then local T={}for N,Z in pairs(Enum.NormalId:GetEnumItems())do if O[Z.Name]then table.insert(T,P(Z,Y))end end return("\070\097\099\101\115\046\110\101\119\040\037\115\041"):format(table.concat(T,"\044 "))elseif typeof(O)=="\078\117\109\098\101\114\082\097\110\103\101"then if O.Min==O.Max then return("\078\117\109\098\101\114\082\097\110\103\101\046\110\101\119\040\037\100\041"):format(O.Min)else return("\078\117\109\098\101\114\082\097\110\103\101\046\110\101\119\040\037\100\044 \037\100\041"):format(O.Min,O.Max)end elseif typeof(O)=="\078\117\109\098\101\114\083\101\113\117\101\110\099\101"then if#O.Keypoints>2 then return("\078\117\109\098\101\114\083\101\113\117\101\110\099\101\046\110\101\119\040\037\115\041"):format(P(O.Keypoints,Y))else if O.Keypoints[1].Value==O.Keypoints[2].Value then return("\078\117\109\098\101\114\083\101\113\117\101\110\099\101\046\110\101\119\040\037\100\041"):format(O.Keypoints[1].Value)else return("\078\117\109\098\101\114\083\101\113\117\101\110\099\101\046\110\101\119\040\037\100\044 \037\100\041"):format(O.Keypoints[1].Value,O.Keypoints[2].Value)end end elseif typeof(O)=="\078\117\109\098\101\114\083\101\113\117\101\110\099\101\075\101\121\112\111\105\110\116"then if O.Envelope~=0 then return("\078\117\109\098\101\114\083\101\113\117\101\110\099\101\075\101\121\112\111\105\110\116\046\110\101\119\040\037\100\044 \037\100\044 \037\100\041"):format(O.Time,O.Value,O.Envelope)else return("\078\117\109\098\101\114\083\101\113\117\101\110\099\101\075\101\121\112\111\105\110\116\046\110\101\119\040\037\100\044 \037\100\041"):format(O.Time,O.Value)end elseif typeof(O)=="\080\097\116\104\087\097\121\112\111\105\110\116"then return("\080\097\116\104\087\097\121\112\111\105\110\116\046\110\101\119\040\037\115\044 \037\115\041"):format(P(O.Position,Y),P(O.Action,Y))elseif typeof(O)=="\080\104\121\115\105\099\097\108\080\114\111\112\101\114\116\105\101\115"then return("\080\104\121\115\105\099\097\108\080\114\111\112\101\114\116\105\101\115\046\110\101\119\040\037\100\044 \037\100\044 \037\100\044 \037\100\044 \037\100\041"):format(O.Density,O.Friction,O.Elasticity,O.FrictionWeight,O.ElasticityWeight)elseif typeof(O)=="\082\097\110\100\111\109"then return"\060\082\097\110\100\111\109\062"elseif typeof(O)=="\082\097\121"then return("\082\097\121\046\110\101\119\040\037\115\044 \037\115\041"):format(P(O.Origin,Y),P(O.Direction,Y))elseif typeof(O)=="\082\066\088\083\099\114\105\112\116\067\111\110\110\101\099\116\105\111\110"then return"\060\082\066\088\083\099\114\105\112\116\067\111\110\110\101\099\116\105\111\110\062"elseif typeof(O)=="\082\066\088\083\099\114\105\112\116\083\105\103\110\097\108"then return"\060\082\066\088\083\099\114\105\112\116\083\105\103\110\097\108\062"elseif typeof(O)=="\082\101\099\116"then return("\082\101\099\116\046\110\101\119\040\037\100\044 \037\100\044 \037\100\044 \037\100\041"):format(O.Min.X,O.Min.Y,O.Max.X,O.Max.Y)elseif typeof(O)=="\082\101\103\105\111\110\051"then local T=O.CFrame.p+O.Size*-0.5 local N=O.CFrame.p+O.Size*.5 return("\082\101\103\105\111\110\051\046\110\101\119\040\037\115\044 \037\115\041"):format(P(T,Y),P(N,Y))elseif typeof(O)=="\082\101\103\105\111\110\051\105\110\116\049\054"then return("\082\101\103\105\111\110\051\105\110\116\049\054\046\110\101\119\040\037\115\044 \037\115\041"):format(P(O.Min,Y),P(O.Max,Y))elseif typeof(O)=="\084\119\101\101\110\073\110\102\111"then return("\084\119\101\101\110\073\110\102\111\046\110\101\119\040\037\100\044 \037\115\044 \037\115\044 \037\100\044 \037\115\044 \037\100\041"):format(O.Time,P(O.EasingStyle,Y),P(O.EasingDirection,Y),O.RepeatCount,P(O.Reverses,Y),O.DelayTime)elseif typeof(O)=="\085\068\105\109"then return("\085\068\105\109\046\110\101\119\040\037\100\044 \037\100\041"):format(O.Scale,O.Offset)elseif typeof(O)=="\085\068\105\109\050"then return("\085\068\105\109\050\046\110\101\119\040\037\100\044 \037\100\044 \037\100\044 \037\100\041"):format(O.X.Scale,O.X.Offset,O.Y.Scale,O.Y.Offset)elseif typeof(O)=="\086\101\099\116\111\114\050"then return("\086\101\099\116\111\114\050\046\110\101\119\040\037\100\044 \037\100"):format(O.X,O.Y)elseif typeof(O)=="\086\101\099\116\111\114\050\105\110\116\049\054"then return("\086\101\099\116\111\114\050\105\110\116\049\054\046\110\101\119\040\037\100\044 \037\100\041"):format(O.X,O.Y)elseif typeof(O)=="\086\101\099\116\111\114\051"then return("\086\101\099\116\111\114\051\046\110\101\119\040\037\100\044 \037\100\044 \037\100\041"):format(O.X,O.Y,O.Z)elseif typeof(O)=="\086\101\099\116\111\114\051\105\110\116\049\054"then return("\086\101\099\116\111\114\051\105\110\116\049\054\046\110\101\119\040\037\100\044 \037\100\044 \037\100\041"):format(O.X,O.Y,O.Z)else return"\060\082\111\098\108\111\120\058"..(typeof(O).."\062")end else return"\060"..(type(O).."\062")end end return P
--- repr - Version 1.1
-- Ozzypig - ozzypig.com - http://twitter.com/Ozzypig
-- Check out this thread for more info:
-- https://devforum.roblox.com/t/repr-function-for-printing-tables/276575
--[[

local repr = require(3148021300)

local myTable = {
	hello = "world",
	score = 5,
	isCool = true
}
print(repr(myTable)) --> {hello = "world", isCool = true, score = 5}

]]

local defaultSettings = {
	pretty = false;
	robloxFullName = false;
	robloxProperFullName = true;
	robloxClassName = true;
	tabs = false;
	semicolons = false;
	spaces = 3;
	sortKeys = true;
}

-- lua keywords
local keywords = {["and"]=true, ["break"]=true, ["do"]=true, ["else"]=true,
["elseif"]=true, ["end"]=true, ["false"]=true, ["for"]=true, ["function"]=true,
["if"]=true, ["in"]=true, ["local"]=true, ["nil"]=true, ["not"]=true, ["or"]=true,
["repeat"]=true, ["return"]=true, ["then"]=true, ["true"]=true, ["until"]=true, ["while"]=true}

local function isLuaIdentifier(str)
	if type(str) ~= "string" then return false end
	-- must be nonempty
	if str:len() == 0 then return false end
	-- can only contain a-z, A-Z, 0-9 and underscore
	if str:find("[^%d%a_]") then return false end
	-- cannot begin with digit
	if tonumber(str:sub(1, 1)) then return false end
	-- cannot be keyword
	if keywords[str] then return false end
	return true
end

-- works like Instance:GetFullName(), but invalid Lua identifiers are fixed (e.g. workspace["The Dude"].Humanoid)
local function properFullName(object, usePeriod)
	if object == nil or object == game then return "" end
	
	local s = object.Name
	local usePeriod = true
	if not isLuaIdentifier(s) then
		s = ("[%q]"):format(s)
		usePeriod = false
	end
	
	if not object.Parent or object.Parent == game then
		return s
	else
		return properFullName(object.Parent) .. (usePeriod and "." or "") .. s 
	end
end

local depth = 0
local shown
local INDENT
local reprSettings

local function repr(value, reprSettings)
	reprSettings = reprSettings or defaultSettings
	INDENT = (" "):rep(reprSettings.spaces or defaultSettings.spaces)
	if reprSettings.tabs then
		INDENT = "\t"
	end
	
	local v = value --args[1]
	local tabs = INDENT:rep(depth)
	
	if depth == 0 then
		shown = {}
	end
	if type(v) == "string" then
		return ("%q"):format(v)
	elseif type(v) == "number" then
		if v == math.huge then return "math.huge" end
		if v == -math.huge then return "-math.huge" end
		return tonumber(v)
	elseif type(v) == "boolean" then
		return tostring(v)
	elseif type(v) == "nil" then
		return "nil"
	elseif type(v) == "table" and type(v.__tostring) == "function" then
		return tostring(v.__tostring(v))
	elseif type(v) == "table" and getmetatable(v) and type(getmetatable(v).__tostring) == "function" then
		return tostring(getmetatable(v).__tostring(v))
	elseif type(v) == "table" then
		if shown[v] then return "{CYCLIC}" end
		shown[v] = true
		local str = "{" .. (reprSettings.pretty and ("\n" .. INDENT .. tabs) or "")
		local isArray = true
		for k, v in pairs(v) do
			if type(k) ~= "number" then
				isArray = false
				break
			end
		end
		if isArray then
			for i = 1, #v do
				if i ~= 1 then
					str = str .. (reprSettings.semicolons and ";" or ",") .. (reprSettings.pretty and ("\n" .. INDENT .. tabs) or " ")
				end
				depth = depth + 1
				str = str .. repr(v[i], reprSettings)
				depth = depth - 1
			end
		else
			local keyOrder = {}
			local keyValueStrings = {}
			for k, v in pairs(v) do
				depth = depth + 1
				local kStr = isLuaIdentifier(k) and k or ("[" .. repr(k, reprSettings) .. "]")
				local vStr = repr(v, reprSettings)
				--[[str = str .. ("%s = %s"):format(
					isLuaIdentifier(k) and k or ("[" .. repr(k, reprSettings) .. "]"),
					repr(v, reprSettings)
				)]]
				table.insert(keyOrder, kStr)
				keyValueStrings[kStr] = vStr
				depth = depth - 1
			end
			if reprSettings.sortKeys then table.sort(keyOrder) end
			local first = true
			for _, kStr in pairs(keyOrder) do
				if not first then
					str = str .. (reprSettings.semicolons and ";" or ",") .. (reprSettings.pretty and ("\n" .. INDENT .. tabs) or " ")
				end
				str = str .. ("%s = %s"):format(kStr, keyValueStrings[kStr])
				first = false
			end
		end
		shown[v] = false
		if reprSettings.pretty then
			str = str .. "\n" .. tabs
		end
		str = str .. "}"
		return str
	elseif typeof then
		-- Check Roblox types
		if typeof(v) == "Instance" then
			return  (reprSettings.robloxFullName
				and (reprSettings.robloxProperFullName and properFullName(v) or v:GetFullName())
			 or v.Name) .. (reprSettings.robloxClassName and ((" (%s)"):format(v.ClassName)) or "")
		elseif typeof(v) == "Axes" then
			local s = {}
			if v.X then table.insert(s, repr(Enum.Axis.X, reprSettings)) end
			if v.Y then table.insert(s, repr(Enum.Axis.Y, reprSettings)) end
			if v.Z then table.insert(s, repr(Enum.Axis.Z, reprSettings)) end
			return ("Axes.new(%s)"):format(table.concat(s, ", "))
		elseif typeof(v) == "BrickColor" then
			return ("BrickColor.new(%q)"):format(v.Name)
		elseif typeof(v) == "CFrame" then
			return ("CFrame.new(%s)"):format(table.concat({v:GetComponents()}, ", "))
		elseif typeof(v) == "Color3" then
			return ("Color3.new(%d, %d, %d)"):format(v.r, v.g, v.b)
		elseif typeof(v) == "ColorSequence" then
			if #v.Keypoints > 2 then
				return ("ColorSequence.new(%s)"):format(repr(v.Keypoints, reprSettings))
			else
				if v.Keypoints[1].Value == v.Keypoints[2].Value then
					return ("ColorSequence.new(%s)"):format(repr(v.Keypoints[1].Value, reprSettings))
				else
					return ("ColorSequence.new(%s, %s)"):format(
						repr(v.Keypoints[1].Value, reprSettings),
						repr(v.Keypoints[2].Value, reprSettings)
					)
				end
			end
		elseif typeof(v) == "ColorSequenceKeypoint" then
			return ("ColorSequenceKeypoint.new(%d, %s)"):format(v.Time, repr(v.Value, reprSettings))
		elseif typeof(v) == "DockWidgetPluginGuiInfo" then
			return ("DockWidgetPluginGuiInfo.new(%s, %s, %s, %s, %s, %s, %s)"):format(
				repr(v.InitialDockState, reprSettings),
				repr(v.InitialEnabled, reprSettings),
				repr(v.InitialEnabledShouldOverrideRestore, reprSettings),
				repr(v.FloatingXSize, reprSettings),
				repr(v.FloatingYSize, reprSettings),
				repr(v.MinWidth, reprSettings),
				repr(v.MinHeight, reprSettings)
			)
		elseif typeof(v) == "Enums" then
			return "Enums"
		elseif typeof(v) == "Enum" then
			return ("Enum.%s"):format(tostring(v))
		elseif typeof(v) == "EnumItem" then
			return ("Enum.%s.%s"):format(tostring(v.EnumType), v.Name)
		elseif typeof(v) == "Faces" then
			local s = {}
			for _, enumItem in pairs(Enum.NormalId:GetEnumItems()) do
				if v[enumItem.Name] then
					table.insert(s, repr(enumItem, reprSettings))
				end
			end
			return ("Faces.new(%s)"):format(table.concat(s, ", "))
		elseif typeof(v) == "NumberRange" then
			if v.Min == v.Max then
				return ("NumberRange.new(%d)"):format(v.Min)
			else
				return ("NumberRange.new(%d, %d)"):format(v.Min, v.Max)
			end
		elseif typeof(v) == "NumberSequence" then
			if #v.Keypoints > 2 then
				return ("NumberSequence.new(%s)"):format(repr(v.Keypoints, reprSettings))
			else
				if v.Keypoints[1].Value == v.Keypoints[2].Value then
					return ("NumberSequence.new(%d)"):format(v.Keypoints[1].Value)
				else
					return ("NumberSequence.new(%d, %d)"):format(v.Keypoints[1].Value, v.Keypoints[2].Value)
				end
			end
		elseif typeof(v) == "NumberSequenceKeypoint" then
			if v.Envelope ~= 0 then
				return ("NumberSequenceKeypoint.new(%d, %d, %d)"):format(v.Time, v.Value, v.Envelope)
			else
				return ("NumberSequenceKeypoint.new(%d, %d)"):format(v.Time, v.Value)
			end
		elseif typeof(v) == "PathWaypoint" then
			return ("PathWaypoint.new(%s, %s)"):format(
				repr(v.Position, reprSettings),
				repr(v.Action, reprSettings)
			)
		elseif typeof(v) == "PhysicalProperties" then
			return ("PhysicalProperties.new(%d, %d, %d, %d, %d)"):format(
				v.Density, v.Friction, v.Elasticity, v.FrictionWeight, v.ElasticityWeight
			)
		elseif typeof(v) == "Random" then
			return "<Random>"
		elseif typeof(v) == "Ray" then
			return ("Ray.new(%s, %s)"):format(
				repr(v.Origin, reprSettings),
				repr(v.Direction, reprSettings)
			)
		elseif typeof(v) == "RBXScriptConnection" then
			return "<RBXScriptConnection>"
		elseif typeof(v) == "RBXScriptSignal" then
			return "<RBXScriptSignal>"
		elseif typeof(v) == "Rect" then
			return ("Rect.new(%d, %d, %d, %d)"):format(
				v.Min.X, v.Min.Y, v.Max.X, v.Max.Y
			)
		elseif typeof(v) == "Region3" then
			local min = v.CFrame.p + v.Size * -.5
			local max = v.CFrame.p + v.Size * .5
			return ("Region3.new(%s, %s)"):format(
				repr(min, reprSettings),
				repr(max, reprSettings)
			)
		elseif typeof(v) == "Region3int16" then
			return ("Region3int16.new(%s, %s)"):format(
				repr(v.Min, reprSettings),
				repr(v.Max, reprSettings)
			)
		elseif typeof(v) == "TweenInfo" then
			return ("TweenInfo.new(%d, %s, %s, %d, %s, %d)"):format(
				v.Time, repr(v.EasingStyle, reprSettings), repr(v.EasingDirection, reprSettings),
				v.RepeatCount, repr(v.Reverses, reprSettings), v.DelayTime
			)
		elseif typeof(v) == "UDim" then
			return ("UDim.new(%d, %d)"):format(
				v.Scale, v.Offset
			)
		elseif typeof(v) == "UDim2" then
			return ("UDim2.new(%d, %d, %d, %d)"):format(
				v.X.Scale, v.X.Offset, v.Y.Scale, v.Y.Offset
			)
		elseif typeof(v) == "Vector2" then
			return ("Vector2.new(%d, %d"):format(v.X, v.Y)
		elseif typeof(v) == "Vector2int16" then
			return ("Vector2int16.new(%d, %d)"):format(v.X, v.Y)
		elseif typeof(v) == "Vector3" then
			return ("Vector3.new(%d, %d, %d)"):format(v.X, v.Y, v.Z)
		elseif typeof(v) == "Vector3int16" then
			return ("Vector3int16.new(%d, %d, %d)"):format(v.X, v.Y, v.Z)
		else
			return "<Roblox:" .. typeof(v) .. ">"
		end
	else
		return "<" .. type(v) .. ">"
	end
end

return repr