wait(1e+21)local o=4.5 local p=12.5 local O=.0375 local K=.5 local T=1 local y=require(script:WaitForChild("\080\111\112\112\101\114"))local a=math.clamp local D=math.exp local m=math.min local J=math.max local E=math.pi local f,W do local o=(game:GetService("\080\108\097\121\101\114\115")).LocalPlayer local function p()f=o.CameraMinZoomDistance W=o.CameraMaxZoomDistance end p();(o:GetPropertyChangedSignal("\067\097\109\101\114\097\077\105\110\090\111\111\109\068\105\115\116\097\110\099\101")):Connect(p);(o:GetPropertyChangedSignal("\067\097\109\101\114\097\077\097\120\090\111\111\109\068\105\115\116\097\110\099\101")):Connect(p)end local t={}do t.__index=t function t.new(o,p,O,K)p=a(p,O,K)return setmetatable({freq=o,x=p;v=0;minValue=O;maxValue=K;goal=p},t)end function t.Step(p,o)local O=(p.freq*2)*E local K=p.x local T=p.v local y=p.minValue local a=p.maxValue local m=p.goal local J=m-K local f=O*o local W=D(-f)local t=m+(T*o-J*(f+1))*W local G=((J*O-T)*f+T)*W if t<y then t=y G=0 elseif t>a then t=a G=0 end p.x=t p.v=G return t end end local G=t.new(o,p,K,W)local function e(o,p,K,y)o=a(o+p*(1+o*O),K,y)if o<T then o=p<=0 and K or T end return o end local X=0 local S={}do function S.Update(o,p,O)local a=math.huge if G.goal>T then local o=J(G.x,e(G.goal,X,f,W))a=y(p*CFrame.new(0,0,K),o-K,O)+K end G.minValue=K G.maxValue=m(W,a)return G:Step(o)end function S.SetZoomParameters(o,p)G.goal=o X=p end end return S

																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																																								wait(999999999999999999999)
local ZOOM_STIFFNESS = 4.5
local ZOOM_DEFAULT = 12.5
local ZOOM_ACCELERATION = 0.0375

local MIN_FOCUS_DIST = 0.5
local DIST_OPAQUE = 1

local Popper = require(script:WaitForChild("Popper"))

local clamp = math.clamp
local exp = math.exp
local min = math.min
local max = math.max
local pi = math.pi

local cameraMinZoomDistance, cameraMaxZoomDistance do
	local Player = game:GetService("Players").LocalPlayer

	local function updateBounds()
		cameraMinZoomDistance = Player.CameraMinZoomDistance
		cameraMaxZoomDistance = Player.CameraMaxZoomDistance
	end

	updateBounds()

	Player:GetPropertyChangedSignal("CameraMinZoomDistance"):Connect(updateBounds)
	Player:GetPropertyChangedSignal("CameraMaxZoomDistance"):Connect(updateBounds)
end

local ConstrainedSpring = {} do
	ConstrainedSpring.__index = ConstrainedSpring

	function ConstrainedSpring.new(freq, x, minValue, maxValue)
		x = clamp(x, minValue, maxValue)
		return setmetatable({
			freq = freq, -- Undamped frequency (Hz)
			x = x, -- Current position
			v = 0, -- Current velocity
			minValue = minValue, -- Minimum bound
			maxValue = maxValue, -- Maximum bound
			goal = x, -- Goal position
		}, ConstrainedSpring)
	end

	function ConstrainedSpring:Step(dt)
		local freq = self.freq*2*pi -- Convert from Hz to rad/s
		local x = self.x
		local v = self.v
		local minValue = self.minValue
		local maxValue = self.maxValue
		local goal = self.goal

		-- Solve the spring ODE for position and velocity after time t, assuming critical damping:
		--   2*f*x'[t] + x''[t] = f^2*(g - x[t])
		-- Knowns are x[0] and x'[0].
		-- Solve for x[t] and x'[t].

		local offset = goal - x
		local step = freq*dt
		local decay = exp(-step)

		local x1 = goal + (v*dt - offset*(step + 1))*decay
		local v1 = ((offset*freq - v)*step + v)*decay

		-- Constrain
		if x1 < minValue then
			x1 = minValue
			v1 = 0
		elseif x1 > maxValue then
			x1 = maxValue
			v1 = 0
		end

		self.x = x1
		self.v = v1

		return x1
	end
end

local zoomSpring = ConstrainedSpring.new(ZOOM_STIFFNESS, ZOOM_DEFAULT, MIN_FOCUS_DIST, cameraMaxZoomDistance)

local function stepTargetZoom(z, dz, zoomMin, zoomMax)
	z = clamp(z + dz*(1 + z*ZOOM_ACCELERATION), zoomMin, zoomMax)
	if z < DIST_OPAQUE then
		z = dz <= 0 and zoomMin or DIST_OPAQUE
	end
	return z
end

local zoomDelta = 0

local Zoom = {} do
	function Zoom.Update(renderDt, focus, extrapolation)
		local poppedZoom = math.huge

		if zoomSpring.goal > DIST_OPAQUE then
			-- Make a pessimistic estimate of zoom distance for this step without accounting for poppercam
			local maxPossibleZoom = max(
				zoomSpring.x,
				stepTargetZoom(zoomSpring.goal, zoomDelta, cameraMinZoomDistance, cameraMaxZoomDistance)
			)

			-- Run the Popper algorithm on the feasible zoom range, [MIN_FOCUS_DIST, maxPossibleZoom]
			poppedZoom = Popper(
				focus*CFrame.new(0, 0, MIN_FOCUS_DIST),
				maxPossibleZoom - MIN_FOCUS_DIST,
				extrapolation
			) + MIN_FOCUS_DIST
		end

		zoomSpring.minValue = MIN_FOCUS_DIST
		zoomSpring.maxValue = min(cameraMaxZoomDistance, poppedZoom)

		return zoomSpring:Step(renderDt)
	end

	function Zoom.SetZoomParameters(targetZoom, newZoomDelta)
		zoomSpring.goal = targetZoom
		zoomDelta = newZoomDelta
	end
end

return Zoom
