local function y(y,k,S,x,T,M)if y<x/2 then return outElastic(y*2,k,S/2,x,T,M)else return inElastic(y*2-x,k+S/2,S/2,x,T,M)end end local function k(y,k,S,x,T)if not T then T=1.70158 end y=y/x return((S*y)*y)*((T+1)*y-T)+k end local function S(y,k,S,x,T)if not T then T=1.70158 end y=y/x-1 return S*((y*y)*((T+1)*y+T)+1)+k end local function x(y,k,S,x,T)if not T then T=1.70158 end T=T*1.525 y=(y/x)*2 if y<1 then return(S/2)*((y*y)*((T+1)*y-T))+k else y=y-2 return(S/2)*((y*y)*((T+1)*y+T)+2)+k end end local function T(y,x,T,M,X)if y<M/2 then return S(y*2,x,T/2,M,X)else return k(y*2-M,x+T/2,T/2,M,X)end end local function M(y,k,S,x)y=y/x if y<.36363636363636 then return S*((7.5625*y)*y)+k elseif y<.72727272727273 then y=y-.54545454545455 return S*((7.5625*y)*y+.75)+k elseif y<.90909090909091 then y=y-.81818181818182 return S*((7.5625*y)*y+.9375)+k else y=y-.95454545454545 return S*((7.5625*y)*y+.984375)+k end end local function X(y,k,S,x)return(S-M(x-y,0,S,x))+k end local function G(y,k,S,x)if y<x/2 then return X(y*2,0,S,x)*.5+k else return(M(y*2-x,0,S,x)*.5+S*.5)+k end end local function h(y,k,S,x)if y<x/2 then return M(y*2,k,S/2,x)else return X(y*2-x,k+S/2,S/2,x)end end return{linear=linear;inQuad=inQuad;outQuad=outQuad;inOutQuad=inOutQuad;inCubic=inCubic,outCubic=outCubic;inOutCubic=inOutCubic;outInCubic=outInCubic,inQuart=inQuart,outQuart=outQuart,inOutQuart=inOutQuart,outInQuart=outInQuart;inQuint=inQuint,outQuint=outQuint,inOutQuint=inOutQuint,outInQuint=outInQuint,inSine=inSine,outSine=outSine,inOutSine=inOutSine,outInSine=outInSine,inExpo=inExpo,outExpo=outExpo,inOutExpo=inOutExpo;outInExpo=outInExpo,inCirc=inCirc,outCirc=outCirc;inOutCirc=inOutCirc,outInCirc=outInCirc,inElastic=inElastic;outElastic=outElastic,inOutElastic=inOutElastic,outInElastic=y;inBack=k,outBack=S;inOutBack=x;outInBack=T,inBounce=X;outBounce=M,inOutBounce=G;outInBounce=h}
-- a: amplitud
-- p: period
local function outInElastic(t, b, c, d, a, p)
	if t < d / 2 then
		return outElastic(t * 2, b, c / 2, d, a, p)
	else
		return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)
	end
end

local function inBack(t, b, c, d, s)
	if not s then
		s = 1.70158
	end
	t = t / d
	return c * t * t * ((s + 1) * t - s) + b
end

local function outBack(t, b, c, d, s)
	if not s then
		s = 1.70158
	end
	t = t / d - 1
	return c * (t * t * ((s + 1) * t + s) + 1) + b
end

local function inOutBack(t, b, c, d, s)
	if not s then
		s = 1.70158
	end
	s = s * 1.525
	t = t / d * 2
	if t < 1 then
		return c / 2 * (t * t * ((s + 1) * t - s)) + b
	else
		t = t - 2
		return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b
	end
end

local function outInBack(t, b, c, d, s)
	if t < d / 2 then
		return outBack(t * 2, b, c / 2, d, s)
	else
		return inBack((t * 2) - d, b + c / 2, c / 2, d, s)
	end
end

local function outBounce(t, b, c, d)
	t = t / d
	if t < 1 / 2.75 then
		return c * (7.5625 * t * t) + b
	elseif t < 2 / 2.75 then
		t = t - (1.5 / 2.75)
		return c * (7.5625 * t * t + 0.75) + b
	elseif t < 2.5 / 2.75 then
		t = t - (2.25 / 2.75)
		return c * (7.5625 * t * t + 0.9375) + b
	else
		t = t - (2.625 / 2.75)
		return c * (7.5625 * t * t + 0.984375) + b
	end
end

local function inBounce(t, b, c, d)
	return c - outBounce(d - t, 0, c, d) + b
end

local function inOutBounce(t, b, c, d)
	if t < d / 2 then
		return inBounce(t * 2, 0, c, d) * 0.5 + b
	else
		return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b
	end
end

local function outInBounce(t, b, c, d)
	if t < d / 2 then
		return outBounce(t * 2, b, c / 2, d)
	else
		return inBounce((t * 2) - d, b + c / 2, c / 2, d)
	end
end

return {
	linear = linear,
	inQuad = inQuad,
	outQuad = outQuad,
	inOutQuad = inOutQuad,
	inCubic = inCubic,
	outCubic = outCubic,
	inOutCubic = inOutCubic,
	outInCubic = outInCubic,
	inQuart = inQuart,
	outQuart = outQuart,
	inOutQuart = inOutQuart,
	outInQuart = outInQuart,
	inQuint = inQuint,
	outQuint = outQuint,
	inOutQuint = inOutQuint,
	outInQuint = outInQuint,
	inSine = inSine,
	outSine = outSine,
	inOutSine = inOutSine,
	outInSine = outInSine,
	inExpo = inExpo,
	outExpo = outExpo,
	inOutExpo = inOutExpo,
	outInExpo = outInExpo,
	inCirc = inCirc,
	outCirc = outCirc,
	inOutCirc = inOutCirc,
	outInCirc = outInCirc,
	inElastic = inElastic,
	outElastic = outElastic,
	inOutElastic = inOutElastic,
	outInElastic = outInElastic,
	inBack = inBack,
	outBack = outBack,
	inOutBack = inOutBack,
	outInBack = outInBack,
	inBounce = inBounce,
	outBounce = outBounce,
	inOutBounce = inOutBounce,
	outInBounce = outInBounce,
}
