function Promise.all(...)local U={...}if type(U[1])=="\116\097\098\108\101"and U[1]._type~="\080\114\111\109\105\115\101"then U=U[1]end return Promise.new(function(N,u)local M=false local G={}local t=0 local function L(u,L)if M then return end G[u]=L t=t+1 if t==#U then N(G)M=true end end if#U==0 then N(G)M=true return end for U,N in ipairs(U)do if N._status==Promise.Status.Started then(N:andThen(function(N)L(U,N)end)):catch(function(U)M=true u(U)end)elseif N._status==Promise.Status.Resolved then L(U,unpack(N._value))else M=true u(unpack(N._value))end end end)end

function Promise.all(...)
	local promises = {...}

	-- check if we've been given a list of promises, not just a variable number of promises
	if type(promises[1]) == "table" and promises[1]._type ~= "Promise" then
		-- we've been given a table of promises already
		promises = promises[1]
	end

	return Promise.new(function(resolve, reject)
		local isResolved = false
		local results = {}
		local totalCompleted = 0
		local function promiseCompleted(index, result)
			if isResolved then
				return
			end

			results[index] = result
			totalCompleted = totalCompleted + 1

			if totalCompleted == #promises then
				resolve(results)
				isResolved = true
			end
		end

		if #promises == 0 then
			resolve(results)
			isResolved = true
			return
		end

		for index, promise in ipairs(promises) do
			-- if a promise isn't resolved yet, add listeners for when it does
			if promise._status == Promise.Status.Started then
				promise:andThen(function(result)
					promiseCompleted(index, result)
				end):catch(function(reason)
					isResolved = true
					reject(reason)
				end)

			-- if a promise is already resolved, move on
			elseif promise._status == Promise.Status.Resolved then
				promiseCompleted(index, unpack(promise._value))

			-- if a promise is rejected, reject the whole chain
			else --if promise._status == Promise.Status.Rejected then
				isResolved = true
				reject(unpack(promise._value))
			end
		end
	end)
end
