function Blend.Spring(T,S,v)local t=Blend.toPropertyObservable(T)or Rx.of(T)local a=Blend.toNumberObservable(S)local u=Blend.toNumberObservable(v)local function R(T,S)local v=Spring.new(S)if a then T:GiveTask(a:Subscribe(function(T)assert(type(T)=="\110\117\109\098\101\114","\066\097\100 \118\097\108\117\101")v.Speed=T end))end if u then T:GiveTask(u:Subscribe(function(T)assert(type(T)=="\110\117\109\098\101\114","\066\097\100 \118\097\108\117\101")v.Damper=T end))end return v end return Observable.new(function(T)local S local v=Maid.new()local a,u=StepUtils.bindToRenderStep(function()local v,t=SpringUtils.animating(S)T:Fire(SpringUtils.fromLinearIfNeeded(t))return v end)v:GiveTask(u)v:GiveTask(t:Subscribe(function(T)if T then local t=SpringUtils.toLinearIfNeeded(T)S=S or R(v,t)S.t=SpringUtils.toLinearIfNeeded(T)a()else warn("\071\111\116 \110\105\108 \118\097\108\117\101 \102\114\111\109 \101\109\105\116\116\101\100 \115\111\117\114\099\101")end end))return v end)end

function Blend.Spring(source, speed, damper)
	local sourceObservable = Blend.toPropertyObservable(source) or Rx.of(source)
	local speedObservable = Blend.toNumberObservable(speed)
	local damperObservable = Blend.toNumberObservable(damper)

	local function createSpring(maid, initialValue)
		local spring = Spring.new(initialValue)

		if speedObservable then
			maid:GiveTask(speedObservable:Subscribe(function(value)
				assert(type(value) == "number", "Bad value")
				spring.Speed = value
			end))
		end

		if damperObservable then
			maid:GiveTask(damperObservable:Subscribe(function(value)
				assert(type(value) == "number", "Bad value")

				spring.Damper = value
			end))
		end

		return spring
	end

	-- TODO: Centralize and cache
	return Observable.new(function(sub)
		local spring
		local maid = Maid.new()

		local startAnimate, stopAnimate = StepUtils.bindToRenderStep(function()
			local animating, position = SpringUtils.animating(spring)
			sub:Fire(SpringUtils.fromLinearIfNeeded(position))
			return animating
		end)

		maid:GiveTask(stopAnimate)
		maid:GiveTask(sourceObservable:Subscribe(function(value)
			if value then
				local linearValue = SpringUtils.toLinearIfNeeded(value)
				spring = spring or createSpring(maid, linearValue)
				spring.t = SpringUtils.toLinearIfNeeded(value)
				startAnimate()
			else
				warn("Got nil value from emitted source")
			end
		end))

		return maid
	end)
end
