function AccelTween.__index(z,w)if AccelTween[w]then return AccelTween[w]elseif w=="\112"then local w,y=z:_getstate(tick())return w elseif w=="\118"then local w,y=z:_getstate(tick())return y elseif w=="\097"then return z._accel elseif w=="\116"then return z._y1 elseif w=="\114\116\105\109\101"then local w=tick()return w<z._t1 and z._t1-w or 0 else error(("\066\097\100 \105\110\100\101\120 \037\113"):format(tostring(w)))end end function AccelTween.__newindex(y,w,z)if w=="\112"then y:_setstate(z,nil,nil,nil)elseif w=="\118"then y:_setstate(nil,z,nil,nil)elseif w=="\097"then y:_setstate(nil,nil,z,nil)elseif w=="\116"then y:_setstate(nil,nil,nil,z)elseif w=="\112\116"then y:_setstate(z,0,nil,z)else error(("\066\097\100 \105\110\100\101\120 \037\113"):format(tostring(w)))end end function AccelTween._getstate(z,w)if w<(z._t0+z._t1)/2 then local y=w-z._t0 return z._y0+((y*y)/2)*z._a0,y*z._a0 elseif w<z._t1 then local y=w-z._t1 return z._y1+((y*y)/2)*z._a1,y*z._a1 else return z._y1,0 end end function AccelTween._setstate(c,w,z,y,o)local D=tick()local N,t=c:_getstate(D)N=w or N t=z or t c._accel=y or c._accel local L=o or c._y1 if c._accel*c._accel<1e-08 then c._t0,c._y0,c._a0=0,N,0 c._t1,c._y1,c._a1=math.huge,L,0 else local w=L<N local z=t<0 local y=N-(t*t)/(2*c._accel)<L local o=N+(t*t)/(2*c._accel)<L if w and(z and y)or not w and(z or not z and o)then c._a0=c._accel c._t1=D+(((2*t)*t+(4*c._accel)*(L-N))^.5-t)/c._accel else c._a0=-c._accel c._t1=D+(((2*t)*t-(4*c._accel)*(L-N))^.5+t)/c._accel end c._t0=D-t/c._a0 c._y0=N-(t*t)/(2*c._a0)c._y1=L c._a1=-c._a0 end end return AccelTween
--[=[
	Sets the current and target position, and sets the velocity to 0.
	@prop pt number
	@within AccelTween
]=]

function AccelTween:__index(index)
	if AccelTween[index] then
		return AccelTween[index]
	elseif index == "p" then
		local pos, _ = self:_getstate(tick())
		return pos
	elseif index == "v" then
		local _, vel = self:_getstate(tick())
		return vel
	elseif index == "a" then
		return self._accel
	elseif index == "t" then
		return self._y1
	elseif index == "rtime" then
		local time = tick()
		return time < self._t1 and self._t1 - time or 0
	else
		error(("Bad index %q"):format(tostring(index)))
	end
end

function AccelTween:__newindex(index, value)
	if index == "p" then
		self:_setstate(value, nil, nil, nil)
	elseif index == "v" then
		self:_setstate(nil, value, nil, nil)
	elseif index == "a" then
		self:_setstate(nil, nil, value, nil)
	elseif index == "t" then
		self:_setstate(nil, nil, nil, value)
	elseif index == "pt" then
		self:_setstate(value, 0, nil, value)
	else
		error(("Bad index %q"):format(tostring(index)))
	end
end

function AccelTween:_getstate(time)
	if time < (self._t0 + self._t1) / 2 then
		local t = time - self._t0
		return self._y0 + t * t / 2 * self._a0, t * self._a0
	elseif time < self._t1 then
		local t = time - self._t1
		return self._y1 + t * t / 2 * self._a1, t * self._a1
	else
		return self._y1, 0
	end
end

function AccelTween:_setstate(newpos, newvel, newaccel, newtarg)
	local time = tick()
	local pos, vel = self:_getstate(time)
	pos = newpos or pos
	vel = newvel or vel
	self._accel = newaccel or self._accel
	local targ = newtarg or self._y1

	if self._accel * self._accel < 1e-8 then
		self._t0, self._y0, self._a0 = 0, pos, 0
		self._t1, self._y1, self._a1 = math.huge, targ, 0
	else
		local conda = targ < pos
		local condb = vel < 0
		local condc = pos - vel * vel / (2 * self._accel) < targ
		local condd = pos + vel * vel / (2 * self._accel) < targ
		if conda and condb and condc or not conda and (condb or not condb and condd) then
			self._a0 = self._accel
			self._t1 = time + ((2 * vel * vel + 4 * self._accel * (targ - pos)) ^ 0.5 - vel) / self._accel
		else
			self._a0 = -self._accel
			self._t1 = time + ((2 * vel * vel - 4 * self._accel * (targ - pos)) ^ 0.5 + vel) / self._accel
		end
		self._t0 = time - vel / self._a0
		self._y0 = pos - vel * vel / (2 * self._a0)
		self._y1 = targ
		self._a1 = -self._a0
	end
end

return AccelTween
