function Rx.withLatestFrom(v)assert(v,"\066\097\100 \105\110\112\117\116\079\098\115\101\114\118\097\098\108\101\115")for v,S in pairs(v)do assert(Observable.isObservable(S),"\066\097\100 \111\098\115\101\114\118\097\098\108\101")end return function(S)assert(Observable.isObservable(S),"\066\097\100 \111\098\115\101\114\118\097\098\108\101")return Observable.new(function(f)local H=Maid.new()local u={}for v,S in pairs(v)do u[v]=UNSET_VALUE H:GiveTask(S:Subscribe(function(S)u[v]=S end,nil,nil))end H:GiveTask(S:Subscribe(function(v)for v,S in pairs(u)do if S==UNSET_VALUE then return end end f:Fire({v;unpack(u)})end,f:GetFailComplete()))return H end)end end

function Rx.withLatestFrom(inputObservables)
	assert(inputObservables, "Bad inputObservables")

	for _, observable in pairs(inputObservables) do
		assert(Observable.isObservable(observable), "Bad observable")
	end

	return function(source)
		assert(Observable.isObservable(source), "Bad observable")

		return Observable.new(function(sub)
			local maid = Maid.new()

			local latest = {}

			for key, observable in pairs(inputObservables) do
				latest[key] = UNSET_VALUE

				maid:GiveTask(observable:Subscribe(function(value)
					latest[key] = value
				end, nil, nil))
			end

			maid:GiveTask(source:Subscribe(function(value)
				for _, item in pairs(latest) do
					if item == UNSET_VALUE then
						return
					end
				end

				sub:Fire({value, unpack(latest)})
			end, sub:GetFailComplete()))

			return maid
		end)
	end
end
