function Promise.prototype._unwrap(m)if m._status==Promise.Status.Started then error("\080\114\111\109\105\115\101 \104\097\115 \110\111\116 \114\101\115\111\108\118\101\100 \111\114 \114\101\106\101\099\116\101\100\046",2)end local o=m._status==Promise.Status.Resolved return o,unpack(m._values,1,m._valuesLength)end function Promise.prototype._resolve(m,...)if m._status~=Promise.Status.Started then if Promise.is(...)then(...):_consumerCancelled(m)end return end if Promise.is(...)then if select("\035",...)>1 then local o=("\087\104\101\110 \114\101\116\117\114\110\105\110\103 \097 \080\114\111\109\105\115\101 \102\114\111\109 \097\110\100\084\104\101\110\044 \101\120\116\114\097 \097\114\103\117\109\101\110\116\115 \097\114\101 \100\105\115\099\097\114\100\101\100\033 \083\101\101\058\n\n\037\115"):format(m._source)warn(o)end local o=(...):andThen(function(...)m:_resolve(...)end,function(...)m:_reject(...)end)if o._status==Promise.Status.Cancelled then m:cancel()elseif o._status==Promise.Status.Started then m._parent=o o._consumers[m]=true end return end m._status=Promise.Status.Resolved m._valuesLength,m._values=pack(...)for m,o in ipairs(m._queuedResolve)do o(...)end m:_finalize()end function Promise.prototype._reject(m,...)if m._status~=Promise.Status.Started then return end m._status=Promise.Status.Rejected m._valuesLength,m._values=pack(...)if not isEmpty(m._queuedReject)then for m,o in ipairs(m._queuedReject)do o(...)end else local o=tostring(...)spawn(function()if not m._unhandledRejection then return end local j=("\085\110\104\097\110\100\108\101\100 \112\114\111\109\105\115\101 \114\101\106\101\099\116\105\111\110\058\n\n\037\115\n\n\037\115"):format(o,m._source)warn(j)end)end m:_finalize()end

function Promise.prototype:_unwrap()
	if self._status == Promise.Status.Started then
		error("Promise has not resolved or rejected.", 2)
	end

	local success = self._status == Promise.Status.Resolved

	return success, unpack(self._values, 1, self._valuesLength)
end

function Promise.prototype:_resolve(...)
	if self._status ~= Promise.Status.Started then
		if Promise.is((...)) then
			(...):_consumerCancelled(self)
		end
		return
	end

	-- If the resolved value was a Promise, we chain onto it!
	if Promise.is((...)) then
		-- Without this warning, arguments sometimes mysteriously disappear
		if select("#", ...) > 1 then
			local message = (
				"When returning a Promise from andThen, extra arguments are " ..
				"discarded! See:\n\n%s"
			):format(
				self._source
			)
			warn(message)
		end

		local promise = (...):andThen(
			function(...)
				self:_resolve(...)
			end,
			function(...)
				self:_reject(...)
			end
		)

		if promise._status == Promise.Status.Cancelled then
			self:cancel()
		elseif promise._status == Promise.Status.Started then
			-- Adopt ourselves into promise for cancellation propagation.
			self._parent = promise
			promise._consumers[self] = true
		end

		return
	end

	self._status = Promise.Status.Resolved
	self._valuesLength, self._values = pack(...)

	-- We assume that these callbacks will not throw errors.
	for _, callback in ipairs(self._queuedResolve) do
		callback(...)
	end

	self:_finalize()
end

function Promise.prototype:_reject(...)
	if self._status ~= Promise.Status.Started then
		return
	end

	self._status = Promise.Status.Rejected
	self._valuesLength, self._values = pack(...)

	-- If there are any rejection handlers, call those!
	if not isEmpty(self._queuedReject) then
		-- We assume that these callbacks will not throw errors.
		for _, callback in ipairs(self._queuedReject) do
			callback(...)
		end
	else
		-- At this point, no one was able to observe the error.
		-- An error handler might still be attached if the error occurred
		-- synchronously. We'll wait one tick, and if there are still no
		-- observers, then we should put a message in the console.

		local err = tostring((...))

		spawn(function()
			-- Someone observed the error, hooray!
			if not self._unhandledRejection then
				return
			end

			-- Build a reasonable message
			local message = ("Unhandled promise rejection:\n\n%s\n\n%s"):format(
				err,
				self._source
			)
			warn(message)
		end)
	end

	self:_finalize()
end
