local function c(c,g,o,p)if c>=p then return g+o end return(o*c)/p+g end local function g(c,g,o,p)if c>=p then return g+o end c=c/p return g-(o*c)*(c-2)end local function o(c,g,o,p)if c>=p then return g+o end c=c/p if c<.5 then return((2*o)*c)*c+g end return g+o*((2*(2-c))*c-1)end function PropertyTweener(c,g,o,p,w,R,J)local Y={}Y.StartTime=tick()Y.EndTime=Y.StartTime+w Y.Cancelled=false local y=false local v=0 local function G()if c then c[g]=R(1,o,p-o,1)end y=true v=1 if J then J()end end c[g]=R(0,o,p-o,w);(coroutine.wrap(function()local J=tick()while J<Y.EndTime and c do if Y.Cancelled then return end c[g]=R(J-Y.StartTime,o,p-o,w)v=clamp(0,1,(J-Y.StartTime)/w)RunService.RenderStepped:wait()J=tick()end if Y.Cancelled==false and c then G()end end))()function Y.GetFinal(c)return p end function Y.GetPercentComplete(c)return v end function Y.IsFinished(c)return y end function Y.Finish(c)if not y then c:Cancel()G()end end function Y.Cancel(c)Y.Cancelled=true end return Y end

local function Linear(t, b, c, d)
	if t >= d then
		return b + c
	end

	return c*t/d + b
end

local function EaseOutQuad(t, b, c, d)
	if t >= d then
		return b + c
	end

	t = t/d
	return b - c*t*(t - 2)
end

local function EaseInOutQuad(t, b, c, d)
	if t >= d then
		return b + c
	end

	t = t/d
	if t < 1/2 then
		return 2*c*t*t + b
	end
	return b + c*(2*(2 - t)*t - 1)
end

function PropertyTweener(instance, prop, start, final, duration, easingFunc, cbFunc)
	local this = {}
	this.StartTime = tick()
	this.EndTime = this.StartTime + duration
	this.Cancelled = false

	local finished = false
	local percentComplete = 0

	local function finalize()
		if instance then
			instance[prop] = easingFunc(1, start, final - start, 1)
		end
		finished = true
		percentComplete = 1
		if cbFunc then
			cbFunc()
		end
	end

	-- Initial set
	instance[prop] = easingFunc(0, start, final - start, duration)
	coroutine.wrap(function()
		local now = tick()
		while now < this.EndTime and instance do
			if this.Cancelled then
				return
			end
			instance[prop] = easingFunc(now - this.StartTime, start, final - start, duration)
			percentComplete = clamp(0, 1, (now - this.StartTime) / duration)
			RunService.RenderStepped:wait()
			now = tick()
		end
		if this.Cancelled == false and instance then
			finalize()
		end
	end)()

	function this:GetFinal()
		return final
	end

	function this:GetPercentComplete()
		return percentComplete
	end

	function this:IsFinished()
		return finished
	end

	function this:Finish()
		if not finished then
			self:Cancel()
			finalize()
		end
	end

	function this:Cancel()
		this.Cancelled = true
	end

	return this
end
