local w={}w.__index=w function w.new()local n=setmetatable({_bindable=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116"),_connections={},_args={},_threads=0,_id=0},w)return n end function w.Is(n)return type(n)=="\116\097\098\108\101"and getmetatable(n)==w end function w.Fire(w,...)local n=w._id w._id=w._id+1 w._args[n]={#w._connections+w._threads;{n=select("\035",...);...}}w._threads=0 w._bindable:Fire(n)end function w.Wait(w)w._threads=w._threads+1 local n=w._bindable.Event:Wait()local a=w._args[n]a[1]=a[1]-1 if a[1]<=0 then w._args[n]=nil end return table.unpack(a[2],1,a[2].n)end function w.Connect(n,w)local a=Connection.new(n,n._bindable.Event:Connect(function(a)local g=n._args[a]g[1]=g[1]-1 if g[1]<=0 then n._args[a]=nil end w(table.unpack(g[2],1,g[2].n))end))table.insert(n._connections,a)return a end function w.DisconnectAll(w)for w,n in ipairs(w._connections)do if n._conn then n._conn:Disconnect()end end w._connections={}w._args={}end function w.Destroy(w)w:DisconnectAll()w._bindable:Destroy()end return w
--------------------------------------------

local Signal = {}
Signal.__index = Signal

function Signal.new()
	local self = setmetatable({
		_bindable = Instance.new("BindableEvent"),
		_connections = {},
		_args = {},
		_threads = 0,
		_id = 0,
	}, Signal)
	return self
end

function Signal.Is(obj)
	return (type(obj) == "table" and getmetatable(obj) == Signal)
end

function Signal:Fire(...)
	local id = self._id
	self._id = self._id + 1
	self._args[id] = { #self._connections + self._threads, { n = select("#", ...), ... } }
	self._threads = 0
	self._bindable:Fire(id)
end

function Signal:Wait()
	self._threads = self._threads + 1
	local id = self._bindable.Event:Wait()
	local args = self._args[id]
	args[1] = args[1] - 1
	if args[1] <= 0 then
		self._args[id] = nil
	end
	return table.unpack(args[2], 1, args[2].n)
end

function Signal:Connect(handler)
	local connection = Connection.new(
		self,
		self._bindable.Event:Connect(function(id)
			local args = self._args[id]
			args[1] = args[1] - 1
			if args[1] <= 0 then
				self._args[id] = nil
			end
			handler(table.unpack(args[2], 1, args[2].n))
		end)
	)
	table.insert(self._connections, connection)
	return connection
end

function Signal:DisconnectAll()
	for _, c in ipairs(self._connections) do
		if c._conn then
			c._conn:Disconnect()
		end
	end
	self._connections = {}
	self._args = {}
end

function Signal:Destroy()
	self:DisconnectAll()
	self._bindable:Destroy()
end

return Signal
