local a={}function a.Class(x,B)x=x or{}local Z={__metatable=a.DeepCopy(B),__index=a.DeepCopy(B)}return setmetatable(x,Z)end function a.MakeClass(...)local x={...}assert(#x>0,"\069\082\082\079\082\058 \099\108\097\115\115 \110\101\101\100\115 \049 \097\114\103\117\109\101\110\116 \111\114 \109\111\114\101")local B=x[1]for a=2,#x,1 do if type(x[a])=="\116\097\098\108\101"then for a,x in pairs(x[a])do if not B[a]then B[a]=x end end end end local function Z(x)return a.Class(x or{},B)end local function q(a,...)local B=a:New(unpack(x))for a,x in pairs(a)do B[a]=x end return B end B.New=Z B.Copy=q return mt end function a.DeepCopy(x)local B=type(x)local Z if B=="\116\097\098\108\101"then Z={}for x,B in next,x,nil do Z[a.DeepCopy(x)]=a.DeepCopy(B)end setmetatable(Z,a.DeepCopy(getmetatable(x)))else Z=x end return Z end function a.Instantiate(a)return function(x)local B=Instance.new(a)for a,x in pairs(x)do if type(a)=="\110\117\109\098\101\114"then x.Parent=B else B[a]=x end end return B end end function a.RetroRegister(a,...)a()for x,B in ipairs({...})do B:connect(a)end end

local UTIL = {}
 
function UTIL.Class(tableIn,template)
        tableIn = tableIn or {}
        local mt = {
        __metatable = UTIL.DeepCopy(template);
        __index     = UTIL.DeepCopy(template);
        }
        return setmetatable(tableIn, mt)
end
function UTIL.MakeClass(...)
        local arg = {...}
        assert(#arg>0, 'ERROR: class needs 1 argument or more')
        local members = arg[1]
        for i=2,#arg,1 do
                if type(arg[i])=='table' then
                        for key,val in pairs(arg[i]) do
                                if not members[key] then
                                        members[key] = val
                                end
                        end
                end
        end
        local function New(init)
                return UTIL.Class(init or {},members)
        end
        local function Copy(obj, ...)
                local newobj = obj:New(unpack(arg))
                for n,v in pairs(obj) do newobj[n] = v end
                return newobj
        end
        members.New  = New
        members.Copy = Copy
        return mt
end
 
function UTIL.DeepCopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[UTIL.DeepCopy(orig_key)] = UTIL.DeepCopy(orig_value)
        end
        setmetatable(copy, UTIL.DeepCopy(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

function UTIL.Instantiate(guiType)
	return function(data)
		local obj = Instance.new(guiType)
		for k, v in pairs(data) do
			if type(k) == 'number' then
				v.Parent = obj
			else
				obj[k] = v
			end
		end
		return obj
	end
end 

function UTIL.RetroRegister(func,...)
	func()
	for _,i in ipairs({...}) do
		i:connect(func)
	end
end
