local q=game:GetService("\080\108\097\121\101\114\115")local B=game:GetService("\068\097\116\097\083\116\111\114\101\083\101\114\118\105\099\101")local j=require(script.table)local S=false local D=300 local L=(game:GetService("\083\101\114\118\101\114\083\116\111\114\097\103\101")):FindFirstChild("\083\097\118\101\073\110\083\116\117\100\105\111")local E=L and L.Value local G=false local d={}function d.typeValid(q)return type(q)~="\117\115\101\114\100\097\116\097",typeof(q)end function d.scanValidity(q,B,j)if type(q)~="\116\097\098\108\101"then return d.scanValidity({input=q},{},{})end B,j=B or{},j or{"\105\110\112\117\116"}B[q]=true local S do local B,j=next(q)if type(B)=="\110\117\109\098\101\114"then S="\065\114\114\097\121"else S="\068\105\099\116\105\111\110\097\114\121"end end local D=0 for q,L in next,q do j[#j+1]=tostring(q)if type(q)=="\110\117\109\098\101\114"then if S=="\068\105\099\116\105\111\110\097\114\121"then return false,j,"\077\105\120\101\100 \065\114\114\097\121\047\068\105\099\116\105\111\110\097\114\121"elseif q%1~=0 then return false,j,"\078\111\110-\105\110\116\101\103\101\114 \105\110\100\101\120"elseif q==math.huge or q==-math.huge then return false,j,"\040-\041\073\110\102\105\110\105\116\121 \105\110\100\101\120"end elseif type(q)~="\115\116\114\105\110\103"then return false,j,"\078\111\110-\115\116\114\105\110\103 \107\101\121",typeof(q)elseif S=="\065\114\114\097\121"then return false,j,"\077\105\120\101\100 \065\114\114\097\121\047\068\105\099\116\105\111\110\097\114\121"end if S=="\065\114\114\097\121"then if D~=q-1 then return false,j,"\065\114\114\097\121 \119\105\116\104 \110\111\110-\115\101\113\117\101\110\116\105\097\108 \105\110\100\101\120\101\115"end D=q end local E,G=d.typeValid(L)if not E then return false,j,"\073\110\118\097\108\105\100 \116\121\112\101",G end if type(L)=="\116\097\098\108\101"then if B[L]then return false,j,"\067\121\099\108\105\099"end local q,S,D,E=d.scanValidity(L,B,j)if not q then return q,S,D,E end end j[#j]=nil end B[q]=nil return true end function d.getStringPath(q)return j.concat(q,"\046")end function d.warnIfInvalid(q)local B,j,S,D=d.scanValidity(q)if not B then if D then warn("\073\110\118\097\108\105\100 \097\116 "..(d.getStringPath(j)..(" \098\101\099\097\117\115\101\058 "..(S..(" \040"..(tostring(D).."\041"))))))else warn("\073\110\118\097\108\105\100 \097\116 "..(d.getStringPath(j)..(" \098\101\099\097\117\115\101\058 "..S)))end end return B end local function r(q)if typeof(q)=="\116\097\098\108\101"then return j.deep(q)else return q end end
--Required components
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local table = require(script.table) --If you're using this from GitHub, this is the table in the boilerplate folder.
local RegularSave = false
local RegularSaveNum = 300
local SaveInStudioObject = game:GetService("ServerStorage"):FindFirstChild("SaveInStudio")
local SaveInStudio = SaveInStudioObject and SaveInStudioObject.Value
local Debug = false

local Verifier = {}

function Verifier.typeValid(data)
	return type(data) ~= "userdata", typeof(data)
end

function Verifier.scanValidity(tbl, passed, path)
	if type(tbl) ~= "table" then
		return Verifier.scanValidity({ input = tbl }, {}, {})
	end
	passed, path = passed or {}, path or { "input" }
	passed[tbl] = true
	local tblType
	do
		local key, value = next(tbl)
		if type(key) == "number" then
			tblType = "Array"
		else
			tblType = "Dictionary"
		end
	end
	local last = 0
	for key, value in next, tbl do
		path[#path + 1] = tostring(key)
		if type(key) == "number" then
			if tblType == "Dictionary" then
				return false, path, "Mixed Array/Dictionary"
			elseif key % 1 ~= 0 then -- if not an integer
				return false, path, "Non-integer index"
			elseif key == math.huge or key == -math.huge then
				return false, path, "(-)Infinity index"
			end
		elseif type(key) ~= "string" then
			return false, path, "Non-string key", typeof(key)
		elseif tblType == "Array" then
			return false, path, "Mixed Array/Dictionary"
		end
		if tblType == "Array" then
			if last ~= key - 1 then
				return false, path, "Array with non-sequential indexes"
			end
			last = key
		end
		local isTypeValid, valueType = Verifier.typeValid(value)
		if not isTypeValid then
			return false, path, "Invalid type", valueType
		end
		if type(value) == "table" then
			if passed[value] then
				return false, path, "Cyclic"
			end
			local isValid, keyPath, reason, extra = Verifier.scanValidity(value, passed, path)
			if not isValid then
				return isValid, keyPath, reason, extra
			end
		end
		path[#path] = nil
	end
	passed[tbl] = nil
	return true
end

function Verifier.getStringPath(path)
	return table.concat(path, ".")
end

function Verifier.warnIfInvalid(input)
	local isValid, keyPath, reason, extra = Verifier.scanValidity(input)
	if not isValid then
		if extra then
			warn(
				"Invalid at "
					.. Verifier.getStringPath(keyPath)
					.. " because: "
					.. reason
					.. " ("
					.. tostring(extra)
					.. ")"
			)
		else
			warn("Invalid at " .. Verifier.getStringPath(keyPath) .. " because: " .. reason)
		end
	end

	return isValid
end

local function clone(value)
	if typeof(value) == "table" then
		return table.deep(value)
	else
		return value
	end
end
