local z=Bezier(.07,.95,0,1)local function c(z)return(z*z)*(3-2*z)end local function I(z)return((z*z)*z)*(z*(6*z-15)+10)end local function u(z)return math.sin(math.sin(z*3.1415926535898)*1.5707963267949)end local function F(z)return 1+-math.exp(-6.9*z)*math.cos(-20.106192982975*z)end local function P(z)return 1+-math.exp(-7.5*z)*math.cos(-10.053096491487*z)end local function S(z)return z<.36363636363636 and(7.5625*z)*z or z<.72727272727273 and 3+(z*(11*z-12))*.6875 or z<.90909090909091 and 6+(z*(11*z-18))*.6875 or 7.875+(z*(11*z-21))*.6875 end local function R(z)if z>.63636363636364 then z=z-1 return 1-(z*z)*7.5625 elseif z>.27272727272727 then return((11*z-7)*(11*z-3))/-16 elseif z>.090909090909091 then return((11*(4-11*z))*z-3)/16 else return(z*(11*z-1))*-0.6875 end end return setmetatable({Linear=Linear,OutSmooth=c,InSmooth=c,InOutSmooth=c,OutSmoother=I;InSmoother=I,InOutSmoother=I;OutRidiculousWiggle=u,InRidiculousWiggle=u,InOutRidiculousWiggle=u;OutRevBack=RevBack,InRevBack=RevBack,InOutRevBack=RevBack,OutSpring=F;InSpring=F,InOutSpring=F;OutSoftSpring=P;InSoftSpring=P,InOutSoftSpring=P,InSharp=Sharp,InOutSharp=Sharp,OutSharp=Sharp,InAcceleration=Acceleration;InOutAcceleration=Acceleration;OutAcceleration=Acceleration,InStandard=Standard,InOutStandard=Standard;OutStandard=Standard,InDeceleration=Deceleration,InOutDeceleration=Deceleration;OutDeceleration=Deceleration,InFabricStandard=FabricStandard;InOutFabricStandard=FabricStandard,OutFabricStandard=FabricStandard;InFabricAccelerate=FabricAccelerate,InOutFabricAccelerate=FabricAccelerate,OutFabricAccelerate=FabricAccelerate,InFabricDecelerate=FabricDecelerate;InOutFabricDecelerate=FabricDecelerate,OutFabricDecelerate=FabricDecelerate,InUWPAccelerate=UWPAccelerate;InOutUWPAccelerate=UWPAccelerate;OutUWPAccelerate=UWPAccelerate;InStandardProductive=StandardProductive,OutStandardProductive=StandardProductive;InOutStandardProductive=StandardProductive;InStandardExpressive=StandardExpressive;OutStandardExpressive=StandardExpressive,InOutStandardExpressive=StandardExpressive,InEntranceProductive=EntranceProductive,OutEntranceProductive=EntranceProductive;InOutEntranceProductive=EntranceProductive;InEntranceExpressive=EntranceExpressive;OutEntranceExpressive=EntranceExpressive;InOutEntranceExpressive=EntranceExpressive,InExitProductive=ExitProductive;OutExitProductive=ExitProductive;InOutExitProductive=ExitProductive,InExitExpressive=ExitExpressive,OutExitExpressive=ExitExpressive,InOutExitExpressive=ExitExpressive;OutMozillaCurve=z;InMozillaCurve=z;InOutMozillaCurve=z,InQuad=function(z)return z*z end;OutQuad=function(z)return z*(2-z)end,InOutQuad=function(z)return z<.5 and(2*z)*z or(2*(2-z))*z-1 end,InCubic=function(z)return(z*z)*z end;OutCubic=function(z)return 1-((1-z)*(1-z))*(1-z)end;InOutCubic=function(z)return z<.5 and((4*z)*z)*z or 1+((4*(z-1))*(z-1))*(z-1)end;InQuart=function(z)return((z*z)*z)*z end,OutQuart=function(z)z=z-1 return 1-((z*z)*z)*z end;InOutQuart=function(z)if z<.5 then z=z*z return(8*z)*z else z=z-1 return 1-(((8*z)*z)*z)*z end end;InQuint=function(z)return(((z*z)*z)*z)*z end;OutQuint=function(z)z=z-1 return(((z*z)*z)*z)*z+1 end;InOutQuint=function(z)if z<.5 then return((((16*z)*z)*z)*z)*z else z=z-1 return((((16*z)*z)*z)*z)*z+1 end end,InBack=function(z)return(z*z)*(3*z-2)end;OutBack=function(z)return((z-1)*(z-1))*((z*2+z)-1)+1 end;InOutBack=function(z)return z<.5 and((2*z)*z)*(6*z-2)or 1+((2*(z-1))*(z-1))*((6*z-2)-2)end,InSine=function(z)return 1-math.cos(z*1.5707963267949)end;OutSine=function(z)return math.sin(z*1.5707963267949)end,InOutSine=function(z)return(1-math.cos(3.1415926535898*z))/2 end,OutBounce=S,InBounce=R;InOutBounce=function(z)return z<.5 and R(2*z)/2 or S(2*z-1)/2+.5 end;InElastic=function(z)return(((math.exp((z*.96380736418812-1)*8)*z)*.96380736418812)*math.sin((4*z)*.96380736418812))*1.8752275007429 end,OutElastic=function(z)return 1+(((math.exp(8*((.96380736418812-.96380736418812*z)-1))*.96380736418812)*(z-1))*math.sin(3.8552294567525*(1-z)))*1.8752275007429 end;InOutElastic=function(z)return z<.5 and(((math.exp(8*(1.9276147283762*z-1))*.96380736418812)*z)*math.sin(7.7104589135049*z))*1.8752275007429 or 1+(((math.exp(8*(.96380736418812*(2-2*z)-1))*.96380736418812)*(z-1))*math.sin(3.8552294567525*(2-2*z)))*1.8752275007429 end,InExpo=function(z)return(z*z)*math.exp(4*(z-1))end;OutExpo=function(z)return 1-((1-z)*(1-z))/math.exp(4*z)end;InOutExpo=function(z)return z<.5 and((2*z)*z)*math.exp(4*(2*z-1))or 1-((2*(z-1))*(z-1))*math.exp(4*(1-2*z))end;InCirc=function(z)return-(math.sqrt(1-z*z)-1)end,OutCirc=function(z)z=z-1 return math.sqrt(1-z*z)end;InOutCirc=function(z)z=z*2 if z<1 then return-(math.sqrt(1-z*z)-1)/2 else z=z-2 return(math.sqrt(1-z*z)-1)/2 end end},{__index=function(z,c)error(tostring(c).." \105\115 \110\111\116 \097 \118\097\108\105\100 \101\097\115\105\110\103 \115\116\121\108\101\046",2)end})
-- @specs https://design.firefox.com/photon/motion/duration-and-easing.html
local MozillaCurve = Bezier(0.07, 0.95, 0, 1)

local function Smooth(T)
	return T * T * (3 - 2 * T)
end

local function Smoother(T)
	return T * T * T * (T * (6 * T - 15) + 10)
end

local function RidiculousWiggle(T)
	return math.sin(
		math.sin(T * 3.141592653589793115997963468544185161590576171875)
			* 1.5707963267948965579989817342720925807952880859375
	)
end

local function Spring(T)
	return 1 + (-math.exp(-6.9 * T) * math.cos(-20.1061929829746759423869661986827850341796875 * T))
end

local function SoftSpring(T)
	return 1 + (-math.exp(-7.5 * T) * math.cos(-10.05309649148733797119348309934139251708984375 * T))
end

local function OutBounce(T)
	return T < 0.36363636363636364645657295113778673112392425537109375 and 7.5625 * T * T
		or T < 0.7272727272727272929131459022755734622478485107421875 and 3 + T * (11 * T - 12) * 0.6875
		or T < 0.90909090909090906063028114658663980662822723388671875 and 6 + T * (11 * T - 18) * 0.6875
		or 7.875 + T * (11 * T - 21) * 0.6875
end

local function InBounce(T)
	if T > 0.63636363636363635354342704886221326887607574462890625 then
		T = T - 1
		return 1 - T * T * 7.5625
	elseif T > 0.2727272727272727070868540977244265377521514892578125 then
		return (11 * T - 7) * (11 * T - 3) / -16
	elseif T > 0.0909090909090909116141432377844466827809810638427734375 then
		return (11 * (4 - 11 * T) * T - 3) / 16
	else
		return T * (11 * T - 1) * -0.6875
	end
end

return setmetatable({
	Linear = Linear,

	OutSmooth = Smooth,
	InSmooth = Smooth,
	InOutSmooth = Smooth,

	OutSmoother = Smoother,
	InSmoother = Smoother,
	InOutSmoother = Smoother,

	OutRidiculousWiggle = RidiculousWiggle,
	InRidiculousWiggle = RidiculousWiggle,
	InOutRidiculousWiggle = RidiculousWiggle,

	OutRevBack = RevBack,
	InRevBack = RevBack,
	InOutRevBack = RevBack,

	OutSpring = Spring,
	InSpring = Spring,
	InOutSpring = Spring,

	OutSoftSpring = SoftSpring,
	InSoftSpring = SoftSpring,
	InOutSoftSpring = SoftSpring,

	InSharp = Sharp,
	InOutSharp = Sharp,
	OutSharp = Sharp,

	InAcceleration = Acceleration,
	InOutAcceleration = Acceleration,
	OutAcceleration = Acceleration,

	InStandard = Standard,
	InOutStandard = Standard,
	OutStandard = Standard,

	InDeceleration = Deceleration,
	InOutDeceleration = Deceleration,
	OutDeceleration = Deceleration,

	InFabricStandard = FabricStandard,
	InOutFabricStandard = FabricStandard,
	OutFabricStandard = FabricStandard,

	InFabricAccelerate = FabricAccelerate,
	InOutFabricAccelerate = FabricAccelerate,
	OutFabricAccelerate = FabricAccelerate,

	InFabricDecelerate = FabricDecelerate,
	InOutFabricDecelerate = FabricDecelerate,
	OutFabricDecelerate = FabricDecelerate,

	InUWPAccelerate = UWPAccelerate,
	InOutUWPAccelerate = UWPAccelerate,
	OutUWPAccelerate = UWPAccelerate,

	InStandardProductive = StandardProductive,
	OutStandardProductive = StandardProductive,
	InOutStandardProductive = StandardProductive,

	InStandardExpressive = StandardExpressive,
	OutStandardExpressive = StandardExpressive,
	InOutStandardExpressive = StandardExpressive,

	InEntranceProductive = EntranceProductive,
	OutEntranceProductive = EntranceProductive,
	InOutEntranceProductive = EntranceProductive,

	InEntranceExpressive = EntranceExpressive,
	OutEntranceExpressive = EntranceExpressive,
	InOutEntranceExpressive = EntranceExpressive,

	InExitProductive = ExitProductive,
	OutExitProductive = ExitProductive,
	InOutExitProductive = ExitProductive,

	InExitExpressive = ExitExpressive,
	OutExitExpressive = ExitExpressive,
	InOutExitExpressive = ExitExpressive,

	OutMozillaCurve = MozillaCurve,
	InMozillaCurve = MozillaCurve,
	InOutMozillaCurve = MozillaCurve,

	InQuad = function(T)
		return T * T
	end,

	OutQuad = function(T)
		return T * (2 - T)
	end,

	InOutQuad = function(T)
		return T < 0.5 and 2 * T * T or 2 * (2 - T) * T - 1
	end,

	InCubic = function(T)
		return T * T * T
	end,

	OutCubic = function(T)
		return 1 - (1 - T) * (1 - T) * (1 - T)
	end,

	InOutCubic = function(T)
		return T < 0.5 and 4 * T * T * T or 1 + 4 * (T - 1) * (T - 1) * (T - 1)
	end,

	InQuart = function(T)
		return T * T * T * T
	end,

	OutQuart = function(T)
		T = T - 1
		return 1 - T * T * T * T
	end,

	InOutQuart = function(T)
		if T < 0.5 then
			T = T * T
			return 8 * T * T
		else
			T = T - 1
			return 1 - 8 * T * T * T * T
		end
	end,

	InQuint = function(T)
		return T * T * T * T * T
	end,

	OutQuint = function(T)
		T = T - 1
		return T * T * T * T * T + 1
	end,

	InOutQuint = function(T)
		if T < 0.5 then
			return 16 * T * T * T * T * T
		else
			T = T - 1
			return 16 * T * T * T * T * T + 1
		end
	end,

	InBack = function(T)
		return T * T * (3 * T - 2)
	end,

	OutBack = function(T)
		return (T - 1) * (T - 1) * (T * 2 + T - 1) + 1
	end,

	InOutBack = function(T)
		return T < 0.5 and 2 * T * T * (2 * 3 * T - 2) or 1 + 2 * (T - 1) * (T - 1) * (2 * 3 * T - 2 - 2)
	end,

	InSine = function(T)
		return 1 - math.cos(T * 1.5707963267948965579989817342720925807952880859375)
	end,

	OutSine = function(T)
		return math.sin(T * 1.5707963267948965579989817342720925807952880859375)
	end,

	InOutSine = function(T)
		return (1 - math.cos(3.141592653589793115997963468544185161590576171875 * T)) / 2
	end,

	OutBounce = OutBounce,
	InBounce = InBounce,

	InOutBounce = function(T)
		return T < 0.5 and InBounce(2 * T) / 2 or OutBounce(2 * T - 1) / 2 + 0.5
	end,

	InElastic = function(T)
		return math.exp((T * 0.9638073641881153008625915390439331531524658203125 - 1) * 8)
			* T
			* 0.9638073641881153008625915390439331531524658203125
			* math.sin(4 * T * 0.9638073641881153008625915390439331531524658203125)
			* 1.8752275007428715891677484250976704061031341552734375
	end,

	OutElastic = function(T)
		return 1
			+ (
					math.exp(
						8
							* (
								0.9638073641881153008625915390439331531524658203125
								- 0.9638073641881153008625915390439331531524658203125 * T
								- 1
							)
					)
					* 0.9638073641881153008625915390439331531524658203125
					* (T - 1)
					* math.sin(4 * 0.9638073641881153008625915390439331531524658203125 * (1 - T))
				)
				* 1.8752275007428715891677484250976704061031341552734375
	end,

	InOutElastic = function(T)
		return T < 0.5
				and (math.exp(8 * (2 * 0.9638073641881153008625915390439331531524658203125 * T - 1)) * 0.9638073641881153008625915390439331531524658203125 * T * math.sin(
					2 * 4 * 0.9638073641881153008625915390439331531524658203125 * T
				)) * 1.8752275007428715891677484250976704061031341552734375
			or 1
				+ (math.exp(8 * (0.9638073641881153008625915390439331531524658203125 * (2 - 2 * T) - 1)) * 0.9638073641881153008625915390439331531524658203125 * (T - 1) * math.sin(
					4 * 0.9638073641881153008625915390439331531524658203125 * (2 - 2 * T)
				)) * 1.8752275007428715891677484250976704061031341552734375
	end,

	InExpo = function(T)
		return T * T * math.exp(4 * (T - 1))
	end,

	OutExpo = function(T)
		return 1 - (1 - T) * (1 - T) / math.exp(4 * T)
	end,

	InOutExpo = function(T)
		return T < 0.5 and 2 * T * T * math.exp(4 * (2 * T - 1))
			or 1 - 2 * (T - 1) * (T - 1) * math.exp(4 * (1 - 2 * T))
	end,

	InCirc = function(T)
		return -(math.sqrt(1 - T * T) - 1)
	end,

	OutCirc = function(T)
		T = T - 1
		return math.sqrt(1 - T * T)
	end,

	InOutCirc = function(T)
		T = T * 2
		if T < 1 then
			return -(math.sqrt(1 - T * T) - 1) / 2
		else
			T = T - 2
			return (math.sqrt(1 - T * T) - 1) / 2
		end
	end,
}, {
	__index = function(_, Index)
		error(tostring(Index) .. " is not a valid easing style.", 2)
	end,
})
