local r=math.pi local N=math.abs local j=math.clamp local E=math.exp local L=math.rad local q=math.sign local v=math.sqrt local J=math.tan local V=game:GetService("\067\111\110\116\101\120\116\065\099\116\105\111\110\083\101\114\118\105\099\101")local y=game:GetService("\080\108\097\121\101\114\115")local k=game:GetService("\082\117\110\083\101\114\118\105\099\101")local T=game:GetService("\083\116\097\114\116\101\114\071\117\105")local A=game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")local F=game:GetService("\087\111\114\107\115\112\097\099\101")local x=y.LocalPlayer if not x then(y:GetPropertyChangedSignal("\076\111\099\097\108\080\108\097\121\101\114")):Wait()x=y.LocalPlayer end local X=F.CurrentCamera;(F:GetPropertyChangedSignal("\067\117\114\114\101\110\116\067\097\109\101\114\097")):Connect(function()local r=F.CurrentCamera if r then X=r end end)local t=Enum.ContextActionPriority.Low.Value local G=Enum.ContextActionPriority.High.Value local f={Enum.KeyCode.LeftShift,Enum.KeyCode.P}local O=(game:GetService("\072\116\116\112\083\101\114\118\105\099\101")):GenerateGUID(false)local W=Vector3.new(1,1,1)*64 local d=Vector2.new(.75,1)*8 local s=300 local B=L(90)local S=2.0 local w=3.0 local K=4.0 local u={}do u.__index=u function u.new(r,N)local j=setmetatable({},u)j.f=r j.p=N j.v=N*0 return j end function u.Update(L,N,j)local q=(L.f*2)*r local v=L.p local J=L.v local V=j-v local y=E(-q*N)local k=j+(J*N-V*(q*N+1))*y local T=((q*N)*(V*q-J)+J)*y L.p=k L.v=T return k end function u.Reset(N,r)N.p=r N.v=r*0 end end local H=Vector3.new()local D=Vector2.new()local m=0 local M=u.new(S,Vector3.new())local P=u.new(w,Vector2.new())local p=u.new(K,0)local U={}do local L do local r=2.0 local v=.15 local function J(N)return(E(r*N)-1)/(E(r)-1)end local function V(r)return J((r-v)/(1-v))end function L(r)return q(r)*j(V(N(r)),0,1)end end local v={ButtonX=0,ButtonY=0;DPadDown=0,DPadUp=0,ButtonL2=0,ButtonR2=0,Thumbstick1=Vector2.new(),Thumbstick2=Vector2.new()}local J={W=0;A=0,S=0;D=0,E=0,Q=0,U=0;H=0;J=0;K=0,I=0;Y=0,Up=0,Down=0;LeftShift=0;RightShift=0}local y={Delta=Vector2.new(),MouseWheel=0}local k=Vector3.new(1,1,1)local T=Vector3.new(1,1,1)local F=Vector2.new(1,1)*(r/64)local x=Vector2.new(1,1)*(r/8)local X=1.0 local t=.25 local f=.75 local W=.25 local d=1 function U.Vel(r)d=j(d+(r*(J.Up-J.Down))*f,.01,4)local N=Vector3.new(L(v.Thumbstick1.X),L(v.ButtonR2)-L(v.ButtonL2),L(-v.Thumbstick1.Y))*k local E=Vector3.new(((J.D-J.A)+J.K)-J.H,((J.E-J.Q)+J.I)-J.Y,((J.S-J.W)+J.J)-J.U)*T local q=A:IsKeyDown(Enum.KeyCode.LeftShift)or A:IsKeyDown(Enum.KeyCode.RightShift)return(N+E)*(d*(q and W or 1))end function U.Pan(r)local N=Vector2.new(L(v.Thumbstick2.Y),L(-v.Thumbstick2.X))*x local j=(y.Delta*F)/(r*60)y.Delta=Vector2.new()return N+j end function U.Fov(r)local N=(v.ButtonX-v.ButtonY)*t local j=y.MouseWheel*X y.MouseWheel=0 return N+j end do local function r(r,N,j)J[j.KeyCode.Name]=N==Enum.UserInputState.Begin and 1 or 0 return Enum.ContextActionResult.Sink end local function N(r,N,j)v[j.KeyCode.Name]=N==Enum.UserInputState.Begin and 1 or 0 return Enum.ContextActionResult.Sink end local function j(r,N,j)local E=j.Delta y.Delta=Vector2.new(-E.y,-E.x)return Enum.ContextActionResult.Sink end local function E(r,N,j)v[j.KeyCode.Name]=j.Position return Enum.ContextActionResult.Sink end local function L(r,N,j)v[j.KeyCode.Name]=j.Position.z return Enum.ContextActionResult.Sink end local function q(r,N,j)y[j.UserInputType.Name]=-j.Position.z return Enum.ContextActionResult.Sink end local function k(r)for N,j in pairs(r)do r[N]=j*0 end end function U.StartCapture()V:BindActionAtPriority(O.."\070\114\101\101\099\097\109\075\101\121\098\111\097\114\100",r,false,G,Enum.KeyCode.W,Enum.KeyCode.A,Enum.KeyCode.S,Enum.KeyCode.D,Enum.KeyCode.E,Enum.KeyCode.Q,Enum.KeyCode.Up,Enum.KeyCode.Down)V:BindActionAtPriority(O.."\070\114\101\101\099\097\109\077\111\117\115\101\080\097\110",j,false,G,Enum.UserInputType.MouseMovement)V:BindActionAtPriority(O.."\070\114\101\101\099\097\109\077\111\117\115\101\087\104\101\101\108",q,false,G,Enum.UserInputType.MouseWheel)V:BindActionAtPriority(O.."\070\114\101\101\099\097\109\071\097\109\101\112\097\100\066\117\116\116\111\110",N,false,G,Enum.KeyCode.ButtonX,Enum.KeyCode.ButtonY)V:BindActionAtPriority(O.."\070\114\101\101\099\097\109\071\097\109\101\112\097\100\084\114\105\103\103\101\114",L,false,G,Enum.KeyCode.ButtonR2,Enum.KeyCode.ButtonL2)V:BindActionAtPriority(O.."\070\114\101\101\099\097\109\071\097\109\101\112\097\100\084\104\117\109\098\115\116\105\099\107",E,false,G,Enum.KeyCode.Thumbstick1,Enum.KeyCode.Thumbstick2)end function U.StopCapture()d=1 k(v)k(J)k(y)V:UnbindAction(O.."\070\114\101\101\099\097\109\075\101\121\098\111\097\114\100")V:UnbindAction(O.."\070\114\101\101\099\097\109\077\111\117\115\101\080\097\110")V:UnbindAction(O.."\070\114\101\101\099\097\109\077\111\117\115\101\087\104\101\101\108")V:UnbindAction(O.."\070\114\101\101\099\097\109\071\097\109\101\112\097\100\066\117\116\116\111\110")V:UnbindAction(O.."\070\114\101\101\099\097\109\071\097\109\101\112\097\100\084\114\105\103\103\101\114")V:UnbindAction(O.."\070\114\101\101\099\097\109\071\097\109\101\112\097\100\084\104\117\109\098\115\116\105\099\107")end end end local function o(r)local N=.1 local j=X.ViewportSize local E=2*J(m/2)local L=(j.x/j.y)*E local q=r.rightVector local v=r.upVector local V=r.lookVector local y=Vector3.new()local k=512 for j=0,1,.5 do for J=0,1,.5 do local T=(j-.5)*L local A=(J-.5)*E local x=(q*T-v*A)+V local X=r.p+x*N local t,G=F:FindPartOnRay(Ray.new(X,x.unit*k))local f=(G-X).magnitude if k>f then k=f y=x.unit end end end return V:Dot(y)*k end local function g(N)local E=M:Update(N,U.Vel(N))local q=P:Update(N,U.Pan(N))local V=p:Update(N,U.Fov(N))local y=v(J(L(35.0))/J(L(m/2)))m=j(m+(V*s)*(N/y),1,120)D=D+(q*d)*(N/y)D=Vector2.new(j(D.x,-B,B),D.y%(2*r))local k=(CFrame.new(H)*CFrame.fromOrientation(D.x,D.y,0))*CFrame.new((E*W)*N)H=k.p X.CFrame=k X.Focus=k*CFrame.new(0,0,-o(k))X.FieldOfView=m end local c={}do local r local N local j local E local L local q local v={}local J={Backpack=true,Chat=true,Health=true;PlayerList=true}local V={BadgesNotificationsActive=true;PointsNotificationsActive=true}function c.Push()q=X.FieldOfView X.FieldOfView=70 L=X.CFrame E=X.Focus r=A.MouseBehavior A.MouseBehavior=Enum.MouseBehavior.Default end function c.Pop()X.FieldOfView=q q=nil X.CFrame=L L=nil X.Focus=E E=nil A.MouseBehavior=r r=nil end end local function e()local r=X.CFrame D=Vector2.new(r:toEulerAnglesYXZ())H=r.p m=X.FieldOfView M:Reset(Vector3.new())P:Reset(Vector2.new())p:Reset(0)c.Push()k:BindToRenderStep(O,Enum.RenderPriority.Camera.Value+1,g)U.StartCapture()end local function Z()U.StopCapture()k:UnbindFromRenderStep(O)c.Pop()end local b=false local function z()if not b then e()b=true end end local function I()if b then Z()b=false end end return{EnableFreecam=z,DisableFreecam=I}
-- https://raw.githubusercontent.com/richie0866/orca/320f43f28373864bb7cd1b9634c337ca77fcee03/src/jobs/helpers/freecam/init.lua
------------------------------------------------------------------------
-- Freecam
-- Cinematic free camera for spectating and video production.
------------------------------------------------------------------------

local pi = math.pi
local abs = math.abs
local clamp = math.clamp
local exp = math.exp
local rad = math.rad
local sign = math.sign
local sqrt = math.sqrt
local tan = math.tan

local ContextActionService = game:GetService("ContextActionService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local StarterGui = game:GetService("StarterGui")
local UserInputService = game:GetService("UserInputService")
local Workspace = game:GetService("Workspace")

local LocalPlayer = Players.LocalPlayer
if not LocalPlayer then
	Players:GetPropertyChangedSignal("LocalPlayer"):Wait()
	LocalPlayer = Players.LocalPlayer
end

local Camera = Workspace.CurrentCamera
Workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function()
	local newCamera = Workspace.CurrentCamera
	if newCamera then
		Camera = newCamera
	end
end)

------------------------------------------------------------------------

local TOGGLE_INPUT_PRIORITY = Enum.ContextActionPriority.Low.Value
local INPUT_PRIORITY = Enum.ContextActionPriority.High.Value
local FREECAM_MACRO_KB = { Enum.KeyCode.LeftShift, Enum.KeyCode.P }

local FREECAM_RENDER_ID = game:GetService("HttpService"):GenerateGUID(false)

local NAV_GAIN = Vector3.new(1, 1, 1) * 64
local PAN_GAIN = Vector2.new(0.75, 1) * 8
local FOV_GAIN = 300

local PITCH_LIMIT = rad(90)

local VEL_STIFFNESS = 2.0
local PAN_STIFFNESS = 3.0
local FOV_STIFFNESS = 4.0

------------------------------------------------------------------------

local Spring = {}
do
	Spring.__index = Spring

	function Spring.new(freq, pos)
		local self = setmetatable({}, Spring)
		self.f = freq
		self.p = pos
		self.v = pos * 0
		return self
	end

	function Spring:Update(dt, goal)
		local f = self.f * 2 * pi
		local p0 = self.p
		local v0 = self.v

		local offset = goal - p0
		local decay = exp(-f * dt)

		local p1 = goal + (v0 * dt - offset * (f * dt + 1)) * decay
		local v1 = (f * dt * (offset * f - v0) + v0) * decay

		self.p = p1
		self.v = v1

		return p1
	end

	function Spring:Reset(pos)
		self.p = pos
		self.v = pos * 0
	end
end

------------------------------------------------------------------------

local cameraPos = Vector3.new()
local cameraRot = Vector2.new()
local cameraFov = 0

local velSpring = Spring.new(VEL_STIFFNESS, Vector3.new())
local panSpring = Spring.new(PAN_STIFFNESS, Vector2.new())
local fovSpring = Spring.new(FOV_STIFFNESS, 0)

------------------------------------------------------------------------

local Input = {}
do
	local thumbstickCurve
	do
		local K_CURVATURE = 2.0
		local K_DEADZONE = 0.15

		local function fCurve(x)
			return (exp(K_CURVATURE * x) - 1) / (exp(K_CURVATURE) - 1)
		end

		local function fDeadzone(x)
			return fCurve((x - K_DEADZONE) / (1 - K_DEADZONE))
		end

		function thumbstickCurve(x)
			return sign(x) * clamp(fDeadzone(abs(x)), 0, 1)
		end
	end

	local gamepad = {
		ButtonX = 0,
		ButtonY = 0,
		DPadDown = 0,
		DPadUp = 0,
		ButtonL2 = 0,
		ButtonR2 = 0,
		Thumbstick1 = Vector2.new(),
		Thumbstick2 = Vector2.new(),
	}

	local keyboard = {
		W = 0,
		A = 0,
		S = 0,
		D = 0,
		E = 0,
		Q = 0,
		U = 0,
		H = 0,
		J = 0,
		K = 0,
		I = 0,
		Y = 0,
		Up = 0,
		Down = 0,
		LeftShift = 0,
		RightShift = 0,
	}

	local mouse = {
		Delta = Vector2.new(),
		MouseWheel = 0,
	}

	local NAV_GAMEPAD_SPEED = Vector3.new(1, 1, 1)
	local NAV_KEYBOARD_SPEED = Vector3.new(1, 1, 1)
	local PAN_MOUSE_SPEED = Vector2.new(1, 1) * (pi / 64)
	local PAN_GAMEPAD_SPEED = Vector2.new(1, 1) * (pi / 8)
	local FOV_WHEEL_SPEED = 1.0
	local FOV_GAMEPAD_SPEED = 0.25
	local NAV_ADJ_SPEED = 0.75
	local NAV_SHIFT_MUL = 0.25

	local navSpeed = 1

	function Input.Vel(dt)
		navSpeed = clamp(navSpeed + dt * (keyboard.Up - keyboard.Down) * NAV_ADJ_SPEED, 0.01, 4)

		local kGamepad = Vector3.new(
			thumbstickCurve(gamepad.Thumbstick1.X),
			thumbstickCurve(gamepad.ButtonR2) - thumbstickCurve(gamepad.ButtonL2),
			thumbstickCurve(-gamepad.Thumbstick1.Y)
		) * NAV_GAMEPAD_SPEED

		local kKeyboard = Vector3.new(
			keyboard.D - keyboard.A + keyboard.K - keyboard.H,
			keyboard.E - keyboard.Q + keyboard.I - keyboard.Y,
			keyboard.S - keyboard.W + keyboard.J - keyboard.U
		) * NAV_KEYBOARD_SPEED

		local shift = UserInputService:IsKeyDown(Enum.KeyCode.LeftShift)
			or UserInputService:IsKeyDown(Enum.KeyCode.RightShift)

		return (kGamepad + kKeyboard) * (navSpeed * (shift and NAV_SHIFT_MUL or 1))
	end

	function Input.Pan(dt)
		local kGamepad = Vector2.new(thumbstickCurve(gamepad.Thumbstick2.Y), thumbstickCurve(-gamepad.Thumbstick2.X))
			* PAN_GAMEPAD_SPEED
		local kMouse = mouse.Delta * PAN_MOUSE_SPEED / (dt * 60)
		mouse.Delta = Vector2.new()
		return kGamepad + kMouse
	end

	function Input.Fov(dt)
		local kGamepad = (gamepad.ButtonX - gamepad.ButtonY) * FOV_GAMEPAD_SPEED
		local kMouse = mouse.MouseWheel * FOV_WHEEL_SPEED
		mouse.MouseWheel = 0
		return kGamepad + kMouse
	end

	do
		local function Keypress(action, state, input)
			keyboard[input.KeyCode.Name] = state == Enum.UserInputState.Begin and 1 or 0
			return Enum.ContextActionResult.Sink
		end

		local function GpButton(action, state, input)
			gamepad[input.KeyCode.Name] = state == Enum.UserInputState.Begin and 1 or 0
			return Enum.ContextActionResult.Sink
		end

		local function MousePan(action, state, input)
			local delta = input.Delta
			mouse.Delta = Vector2.new(-delta.y, -delta.x)
			return Enum.ContextActionResult.Sink
		end

		local function Thumb(action, state, input)
			gamepad[input.KeyCode.Name] = input.Position
			return Enum.ContextActionResult.Sink
		end

		local function Trigger(action, state, input)
			gamepad[input.KeyCode.Name] = input.Position.z
			return Enum.ContextActionResult.Sink
		end

		local function MouseWheel(action, state, input)
			mouse[input.UserInputType.Name] = -input.Position.z
			return Enum.ContextActionResult.Sink
		end

		local function Zero(t)
			for k, v in pairs(t) do
				t[k] = v * 0
			end
		end

		function Input.StartCapture()
			ContextActionService:BindActionAtPriority(
				FREECAM_RENDER_ID .. "FreecamKeyboard",
				Keypress,
				false,
				INPUT_PRIORITY,
				Enum.KeyCode.W, -- Enum.KeyCode.U,
				Enum.KeyCode.A, -- Enum.KeyCode.H,
				Enum.KeyCode.S, -- Enum.KeyCode.J,
				Enum.KeyCode.D, -- Enum.KeyCode.K,
				Enum.KeyCode.E, -- Enum.KeyCode.I,
				Enum.KeyCode.Q, -- Enum.KeyCode.Y,
				Enum.KeyCode.Up,
				Enum.KeyCode.Down
			)
			ContextActionService:BindActionAtPriority(
				FREECAM_RENDER_ID .. "FreecamMousePan",
				MousePan,
				false,
				INPUT_PRIORITY,
				Enum.UserInputType.MouseMovement
			)
			ContextActionService:BindActionAtPriority(
				FREECAM_RENDER_ID .. "FreecamMouseWheel",
				MouseWheel,
				false,
				INPUT_PRIORITY,
				Enum.UserInputType.MouseWheel
			)
			ContextActionService:BindActionAtPriority(
				FREECAM_RENDER_ID .. "FreecamGamepadButton",
				GpButton,
				false,
				INPUT_PRIORITY,
				Enum.KeyCode.ButtonX,
				Enum.KeyCode.ButtonY
			)
			ContextActionService:BindActionAtPriority(
				FREECAM_RENDER_ID .. "FreecamGamepadTrigger",
				Trigger,
				false,
				INPUT_PRIORITY,
				Enum.KeyCode.ButtonR2,
				Enum.KeyCode.ButtonL2
			)
			ContextActionService:BindActionAtPriority(
				FREECAM_RENDER_ID .. "FreecamGamepadThumbstick",
				Thumb,
				false,
				INPUT_PRIORITY,
				Enum.KeyCode.Thumbstick1,
				Enum.KeyCode.Thumbstick2
			)
		end

		function Input.StopCapture()
			navSpeed = 1
			Zero(gamepad)
			Zero(keyboard)
			Zero(mouse)
			ContextActionService:UnbindAction(FREECAM_RENDER_ID .. "FreecamKeyboard")
			ContextActionService:UnbindAction(FREECAM_RENDER_ID .. "FreecamMousePan")
			ContextActionService:UnbindAction(FREECAM_RENDER_ID .. "FreecamMouseWheel")
			ContextActionService:UnbindAction(FREECAM_RENDER_ID .. "FreecamGamepadButton")
			ContextActionService:UnbindAction(FREECAM_RENDER_ID .. "FreecamGamepadTrigger")
			ContextActionService:UnbindAction(FREECAM_RENDER_ID .. "FreecamGamepadThumbstick")
		end
	end
end

local function GetFocusDistance(cameraFrame)
	local znear = 0.1
	local viewport = Camera.ViewportSize
	local projy = 2 * tan(cameraFov / 2)
	local projx = viewport.x / viewport.y * projy
	local fx = cameraFrame.rightVector
	local fy = cameraFrame.upVector
	local fz = cameraFrame.lookVector

	local minVect = Vector3.new()
	local minDist = 512

	for x = 0, 1, 0.5 do
		for y = 0, 1, 0.5 do
			local cx = (x - 0.5) * projx
			local cy = (y - 0.5) * projy
			local offset = fx * cx - fy * cy + fz
			local origin = cameraFrame.p + offset * znear
			local _, hit = Workspace:FindPartOnRay(Ray.new(origin, offset.unit * minDist))
			local dist = (hit - origin).magnitude
			if minDist > dist then
				minDist = dist
				minVect = offset.unit
			end
		end
	end

	return fz:Dot(minVect) * minDist
end

------------------------------------------------------------------------

local function StepFreecam(dt)
	local vel = velSpring:Update(dt, Input.Vel(dt))
	local pan = panSpring:Update(dt, Input.Pan(dt))
	local fov = fovSpring:Update(dt, Input.Fov(dt))

	local zoomFactor = sqrt(tan(rad(70 / 2)) / tan(rad(cameraFov / 2)))

	cameraFov = clamp(cameraFov + fov * FOV_GAIN * (dt / zoomFactor), 1, 120)
	cameraRot = cameraRot + pan * PAN_GAIN * (dt / zoomFactor)
	cameraRot = Vector2.new(clamp(cameraRot.x, -PITCH_LIMIT, PITCH_LIMIT), cameraRot.y % (2 * pi))

	local cameraCFrame = CFrame.new(cameraPos)
		* CFrame.fromOrientation(cameraRot.x, cameraRot.y, 0)
		* CFrame.new(vel * NAV_GAIN * dt)
	cameraPos = cameraCFrame.p

	Camera.CFrame = cameraCFrame
	Camera.Focus = cameraCFrame * CFrame.new(0, 0, -GetFocusDistance(cameraCFrame))
	Camera.FieldOfView = cameraFov
end

------------------------------------------------------------------------

local PlayerState = {}
do
	local mouseBehavior
	local mouseIconEnabled
	local cameraType
	local cameraFocus
	local cameraCFrame
	local cameraFieldOfView
	local screenGuis = {}
	local coreGuis = {
		Backpack = true,
		Chat = true,
		Health = true,
		PlayerList = true,
	}
	local setCores = {
		BadgesNotificationsActive = true,
		PointsNotificationsActive = true,
	}

	-- Save state and set up for freecam
	function PlayerState.Push()
		-- for name in pairs(coreGuis) do
		-- 	coreGuis[name] = StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType[name])
		-- 	StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType[name], false)
		-- end
		-- for name in pairs(setCores) do
		-- 	setCores[name] = StarterGui:GetCore(name)
		-- 	StarterGui:SetCore(name, false)
		-- end
		-- local playergui = LocalPlayer:FindFirstChildOfClass("PlayerGui")
		-- if playergui then
		-- 	for _, gui in pairs(playergui:GetChildren()) do
		-- 		if gui:IsA("ScreenGui") and gui.Enabled then
		-- 			screenGuis[#screenGuis + 1] = gui
		-- 			gui.Enabled = false
		-- 		end
		-- 	end
		-- end

		cameraFieldOfView = Camera.FieldOfView
		Camera.FieldOfView = 70

		-- cameraType = Camera.CameraType
		-- Camera.CameraType = Enum.CameraType.Custom

		cameraCFrame = Camera.CFrame
		cameraFocus = Camera.Focus

		-- mouseIconEnabled = UserInputService.MouseIconEnabled
		-- UserInputService.MouseIconEnabled = false

		mouseBehavior = UserInputService.MouseBehavior
		UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	end

	-- Restore state
	function PlayerState.Pop()
		-- for name, isEnabled in pairs(coreGuis) do
		-- 	StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType[name], isEnabled)
		-- end
		-- for name, isEnabled in pairs(setCores) do
		-- 	StarterGui:SetCore(name, isEnabled)
		-- end
		-- for _, gui in pairs(screenGuis) do
		-- 	if gui.Parent then
		-- 		gui.Enabled = true
		-- 	end
		-- end

		Camera.FieldOfView = cameraFieldOfView
		cameraFieldOfView = nil

		-- Camera.CameraType = cameraType
		-- cameraType = nil

		Camera.CFrame = cameraCFrame
		cameraCFrame = nil

		Camera.Focus = cameraFocus
		cameraFocus = nil

		-- UserInputService.MouseIconEnabled = mouseIconEnabled
		-- mouseIconEnabled = nil

		UserInputService.MouseBehavior = mouseBehavior
		mouseBehavior = nil
	end
end

local function StartFreecam()
	local cameraCFrame = Camera.CFrame
	cameraRot = Vector2.new(cameraCFrame:toEulerAnglesYXZ())
	cameraPos = cameraCFrame.p
	cameraFov = Camera.FieldOfView

	velSpring:Reset(Vector3.new())
	panSpring:Reset(Vector2.new())
	fovSpring:Reset(0)

	PlayerState.Push()
	RunService:BindToRenderStep(FREECAM_RENDER_ID, Enum.RenderPriority.Camera.Value + 1, StepFreecam)
	Input.StartCapture()
end

local function StopFreecam()
	Input.StopCapture()
	RunService:UnbindFromRenderStep(FREECAM_RENDER_ID)
	PlayerState.Pop()
end

------------------------------------------------------------------------

local enabled = false

local function EnableFreecam()
	if not enabled then
		StartFreecam()
		enabled = true
	end
end

local function DisableFreecam()
	if enabled then
		StopFreecam()
		enabled = false
	end
end

return {
	EnableFreecam = EnableFreecam,
	DisableFreecam = DisableFreecam,
}
