function Blend.ComputedPairs(r,B)local p=Blend.toPropertyObservable(r)or Rx.of(r)return Observable.new(function(r)local y={}local h=Maid.new()local K=Maid.new()h:GiveTask(K)h:GiveTask(p:Subscribe(function(p)assert(type(p)=="\116\097\098\108\101","\066\097\100 \118\097\108\117\101 \101\109\105\116\116\101\100 \102\114\111\109 \115\111\117\114\099\101")local h={}for r,B in pairs(y)do h[r]=true end for p,k in pairs(p)do h[p]=nil if y[p]~=k then local h=Maid.new()local I=B(p,k,h)local j=Brio.new(I)h:GiveTask(j)r:Fire(j)K[p]=h y[p]=k end end for r,B in pairs(h)do K[r]=nil y[r]=nil end end),r:GetFailComplete())return h end)end
--[=[
	Similiar to Fusion's ComputedPairs, where the changes are cached, and the lifetime limited.
	@param source Observable<T> | any
	@param compute (key: any, value: any, innerMaid: Maid) -> Instance | Observable<Instance>
	@return Observable<Brio<Instance>>
]=]
function Blend.ComputedPairs(source, compute)
	local sourceObservable = Blend.toPropertyObservable(source) or Rx.of(source)

	return Observable.new(function(sub)
		local cache = {}
		local topMaid = Maid.new()

		local maidForKeys = Maid.new()
		topMaid:GiveTask(maidForKeys)

		topMaid:GiveTask(
			sourceObservable:Subscribe(function(newValue)
				-- It's gotta be a table
				assert(type(newValue) == "table", "Bad value emitted from source")

				local excluded = {}
				for key, _ in pairs(cache) do
					excluded[key] = true
				end

				for key, value in pairs(newValue) do
					excluded[key] = nil

					if cache[key] ~= value then
						local innerMaid = Maid.new()
						local result = compute(key, value, innerMaid)

						local brio = Brio.new(result)
						innerMaid:GiveTask(brio)

						sub:Fire(brio)

						maidForKeys[key] = innerMaid
						cache[key] = value
					end
				end

				for key, _ in pairs(excluded) do
					maidForKeys[key] = nil
					cache[key] = nil
				end
			end),
			sub:GetFailComplete()
		)

		return topMaid
	end)
end
