local B={}do local r={}function r.Create()local B={}local r=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")local z=nil local n=nil function B.fire(B,...)z={...}n=select("\035",...)r:Fire()end function B.connect(t,B)if not B then error("\099\111\110\110\101\099\116\040\110\105\108\041",2)end return r.Event:connect(function()B(unpack(z,1,n))end)end function B.wait(B)r.Event:wait()assert(z,"\077\105\115\115\105\110\103 \097\114\103 \100\097\116\097\044 \108\105\107\101\108\121 \100\117\101 \116\111 \058\084\119\101\101\110\083\105\122\101\047\080\111\115\105\116\105\111\110 \099\111\114\114\117\112\116\105\110\103 \116\104\114\101\097\100\114\101\102\115\046")return unpack(z,1,n)end return B end B.Signal=r function B.Create(B)return function(r)local z=Instance.new(B)for B,r in pairs(r)do if type(B)=="\110\117\109\098\101\114"then r.Parent=z else z[B]=r end end return z end end local function z()local B=workspace.CurrentCamera local r=B and B.ViewportSize.X or 0 local z=B and B.ViewportSize.Y or 0 if r==0 then return 1024 else if r>z then return r else return z end end end B.ViewSizeX=z local function n()local B=workspace.CurrentCamera local r=B and B.ViewportSize.X or 0 local z=B and B.ViewportSize.Y or 0 if z==0 then return 768 else if r>z then return z else return r end end end B.ViewSizeY=n local function t()return z()/n()end B.AspectRatio=t local function J(B)if B then local r=B:FindFirstChild("\072\117\109\097\110\111\105\100")if r then return B,r else return J(B.Parent)end end end B.FindChacterAncestor=J local function m(B,r,z,n,t)return t:ScreenPointToRay(B,r)end B.GetUnitRay=m local function w(B,r,z)local n=z or{}local t,J=RayCastIgnoreList(workspace,B,n)if t then if r and t.CanCollide==false then table.insert(n,t)return w(B,r,n)end return t,J end return nil,nil end B.Raycast=w B.Round=function(B,r)r=r or 1 return math_floor((B+r/2)/r)*r end local function x(B)local r=ZERO_VECTOR2 if#B>0 then for z=1,#B,1 do r=r+B[z]end r=r/#B end return r end B.AveragePoints=x local function u(B,r)return B+.1>r and B-.1<r end B.FuzzyEquals=u local D=0 UIS.InputBegan:connect(function(B,r)if not r then if B.UserInputType==Enum.UserInputType.Touch or B.UserInputType==Enum.UserInputType.MouseButton1 or B.UserInputType==Enum.UserInputType.MouseButton2 then D=tick()end end end)B.GetLastInput=function()return D end end local r={}local function z(B)local z=B and B.Character if z then local n=r[B]if n and n.Parent==z then return n else r[B]=nil local n=z:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")if n then r[B]=n end return n end end end local n do local B=(CFrame.new()).components local r=(CFrame.new()).inverse local z=math.acos n=function(n,t)local J,m,w,x,u,D,I,O,R,M,V,H=B(r(n)*t)local q=(((x+O)+H)-1)/2 if q>=.999 then return 0 elseif q<=-0.999 then return math_pi else return z(q)end end end

local Utility = {}
do
	local Signal = {}

	function Signal.Create()
		local sig = {}

		local mSignaler = Instance.new('BindableEvent')

		local mArgData = nil
		local mArgDataCount = nil

		function sig:fire(...)
			mArgData = {...}
			mArgDataCount = select('#', ...)
			mSignaler:Fire()
		end

		function sig:connect(f)
			if not f then error("connect(nil)", 2) end
			return mSignaler.Event:connect(function()
				f(unpack(mArgData, 1, mArgDataCount))
			end)
		end

		function sig:wait()
			mSignaler.Event:wait()
			assert(mArgData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
			return unpack(mArgData, 1, mArgDataCount)
		end

		return sig
	end
	Utility.Signal = Signal

	function Utility.Create(instanceType)
		return function(data)
			local obj = Instance.new(instanceType)
			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

	local function ViewSizeX()
		local camera = workspace.CurrentCamera
		local x = camera and camera.ViewportSize.X or 0
		local y = camera and camera.ViewportSize.Y or 0
		if x == 0 then
			return 1024
		else
			if x > y then
				return x
			else
				return y
			end
		end
	end
	Utility.ViewSizeX = ViewSizeX

	local function ViewSizeY()
		local camera = workspace.CurrentCamera
		local x = camera and camera.ViewportSize.X or 0
		local y = camera and camera.ViewportSize.Y or 0
		if y == 0 then
			return 768
		else
			if x > y then
				return y
			else
				return x
			end
		end
	end
	Utility.ViewSizeY = ViewSizeY

	local function AspectRatio()
		return ViewSizeX() / ViewSizeY()
	end
	Utility.AspectRatio = AspectRatio

	local function FindChacterAncestor(part)
		if part then
			local humanoid = part:FindFirstChild("Humanoid")
			if humanoid then
				return part, humanoid
			else
				return FindChacterAncestor(part.Parent)
			end
		end
	end
	Utility.FindChacterAncestor = FindChacterAncestor


	local function GetUnitRay(x, y, viewWidth, viewHeight, camera)
		return camera:ScreenPointToRay(x, y)
	end
	Utility.GetUnitRay = GetUnitRay

	local function Raycast(ray, ignoreNonCollidable, ignoreList)
		local ignoreList = ignoreList or {}
		local hitPart, hitPos = RayCastIgnoreList(workspace, ray, ignoreList)
		if hitPart then
			if ignoreNonCollidable and hitPart.CanCollide == false then
				table.insert(ignoreList, hitPart)
				return Raycast(ray, ignoreNonCollidable, ignoreList)
			end
			return hitPart, hitPos
		end
		return nil, nil
	end
	Utility.Raycast = Raycast


	Utility.Round = function(num, roundToNearest)
		roundToNearest = roundToNearest or 1
		return math_floor((num + roundToNearest/2) / roundToNearest) * roundToNearest
	end

	local function AveragePoints(positions)
		local avgPos = ZERO_VECTOR2
		if #positions > 0 then
			for i = 1, #positions do
				avgPos = avgPos + positions[i]
			end
			avgPos = avgPos / #positions
		end
		return avgPos
	end
	Utility.AveragePoints = AveragePoints

	local function FuzzyEquals(numa, numb)
		return numa + 0.1 > numb and numa - 0.1 < numb
	end
	Utility.FuzzyEquals = FuzzyEquals

	local LastInput = 0
	UIS.InputBegan:connect(function(inputObject, wasSunk)
		if not wasSunk then
			if inputObject.UserInputType == Enum.UserInputType.Touch or
					inputObject.UserInputType == Enum.UserInputType.MouseButton1 or
					inputObject.UserInputType == Enum.UserInputType.MouseButton2 then
				LastInput = tick()
			end
		end
	end)
	Utility.GetLastInput = function()
		return LastInput
	end
end

local humanoidCache = {}
local function findPlayerHumanoid(player)
	local character = player and player.Character
	if character then
		local resultHumanoid = humanoidCache[player]
		if resultHumanoid and resultHumanoid.Parent == character then
			return resultHumanoid
		else
			humanoidCache[player] = nil -- Bust Old Cache
			local humanoid = character:FindFirstChildOfClass("Humanoid")
			if humanoid then
				humanoidCache[player] = humanoid
			end
			return humanoid
		end
	end
end

local GetThetaBetweenCFrames; do
	local components = CFrame.new().components
	local inverse = CFrame.new().inverse
	local acos = math.acos
	
	GetThetaBetweenCFrames = function(c0, c1) -- (CFrame from, CFrame to) -> (float theta)
		local _, _, _, xx, yx, zx,
		               xy, yy, zy,
		               xz, yz, zz = components(inverse(c0)*c1)
		local cosTheta = (xx + yy + zz - 1)/2
	
		if cosTheta >= 0.999 then
			-- Same rotation
			return 0
		elseif cosTheta <= -0.999 then
			-- Oposite rotations
			return math_pi
		else
			return acos(cosTheta)
		end
	end
end
