local G do G=setmetatable({},{__tostring=function()return"\083\105\103\110\097\108"end})G.__index=G function G.new(...)local t=setmetatable({},G)return t:constructor(...)or t end function G.constructor(G)G.waitingThreads={}G._handlerListHead=nil end function G.Connect(t,G)local q=Connection.new(t,G)if t._handlerListHead~=nil then q._next=t._handlerListHead end t._handlerListHead=q return q end function G.Once(t,G)local q=false local U U=t:Connect(function(...)local t={...}if q then return nil end q=true U:Disconnect()G(unpack(t))end)return U end function G.Fire(G,...)local t={...}local q=G._handlerListHead while q do if q.Connected then task.spawn(q._fn,unpack(t))end q=q._next end end function G.FireDeferred(G,...)local t={...}local q=G._handlerListHead while q do if q.Connected then task.defer(q._fn,unpack(t))end q=q._next end end function G.Wait(G)local t=coroutine.running()G.waitingThreads[t]=true G:Once(function(...)local q={...}G.waitingThreads[t]=nil task.spawn(t,unpack(q))end)return coroutine.yield()end function G.DisconnectAll(G)local t=G._handlerListHead while t do t.Connected=false t=t._next end G._handlerListHead=nil local q=G.waitingThreads local U=function(G)return task.cancel(G)end for G in q do U(G,G,q)end table.clear(G.waitingThreads)end function G.Destroy(G)G:DisconnectAll()end end return{Connection=Connection;Signal=G}
--[[
	*
	* Signals allow events to be dispatched to any number of listeners.
]]
local Signal
do
	Signal = setmetatable({}, {
		__tostring = function()
			return "Signal"
		end,
	})
	Signal.__index = Signal
	function Signal.new(...)
		local self = setmetatable({}, Signal)
		return self:constructor(...) or self
	end
	function Signal:constructor()
		self.waitingThreads = {}
		self._handlerListHead = nil
	end
	function Signal:Connect(callback)
		local connection = Connection.new(self, callback)
		if self._handlerListHead ~= nil then
			connection._next = self._handlerListHead
		end
		self._handlerListHead = connection
		return connection
	end
	function Signal:Once(callback)
		local done = false
		local c
		c = self:Connect(function(...)
			local args = { ... }
			if done then
				return nil
			end
			done = true
			c:Disconnect()
			callback(unpack(args))
		end)
		return c
	end
	function Signal:Fire(...)
		local args = { ... }
		local item = self._handlerListHead
		while item do
			if item.Connected then
				task.spawn(item._fn, unpack(args))
			end
			item = item._next
		end
	end
	function Signal:FireDeferred(...)
		local args = { ... }
		local item = self._handlerListHead
		while item do
			if item.Connected then
				task.defer(item._fn, unpack(args))
			end
			item = item._next
		end
	end
	function Signal:Wait()
		local running = coroutine.running()
		self.waitingThreads[running] = true
		self:Once(function(...)
			local args = { ... }
			self.waitingThreads[running] = nil
			task.spawn(running, unpack(args))
		end)
		return coroutine.yield()
	end
	function Signal:DisconnectAll()
		local item = self._handlerListHead
		while item do
			item.Connected = false
			item = item._next
		end
		self._handlerListHead = nil
		local _waitingThreads = self.waitingThreads
		local _arg0 = function(thread)
			return task.cancel(thread)
		end
		for _v in _waitingThreads do
			_arg0(_v, _v, _waitingThreads)
		end
		table.clear(self.waitingThreads)
	end
	function Signal:Destroy()
		self:DisconnectAll()
	end
end
return {
	Connection = Connection,
	Signal = Signal,
}
