local w=game:GetService("\077\101\115\115\097\103\105\110\103\083\101\114\118\105\099\101")local z={}local c={}c.__index=c function c.new(w)local z=setmetatable({Topic=w},c)return z end function c.Push(o,z,c)if c then w:PublishAsync("\082\101\100\101\102\105\110\101\065\053",{Topic=z,Data=c})else w:PublishAsync("\082\101\100\101\102\105\110\101\065\053",{Topic=o.Topic,Data=z})end end function c.Publish(o,z,c)w:PublishAsync("\082\101\100\101\102\105\110\101\065\053",{Topic=z;Data=c})end function c.Listen(o,w,c)if c then z[c]=w else z[o.Topic]=w end end function c.Subscribe(o,w,c)z[w]=c end function c.Unlisten(w)z[w.Topic]=nil end function c.Unsubscribe(c,w)z[w]=nil end function c.Once(c,w)z[c.Topic]=function(o)w(o)z[c.Topic]=nil end end function c.Promise(w)local c={Complete=false,Data=nil}z[w.Topic]=function(o)c.Complete=true c.Data=o z[w.Topic]=nil end return c end function c.Wait(w)local c={Complete=false,Data=nil}z[w.Topic]=function(o)c.Complete=true c.Data=o z[w.Topic]=nil end repeat task.wait()until c.Complete return c.Data end w:SubscribeAsync("\082\101\100\101\102\105\110\101\065\053",function(w)local c=w.Data local o=c.Topic local l=c.Data if z[o]then z[o](l)end end)return c
-- This module will act as a wrapper for MessagingService, and will allow for easier use of it all while using only a single topic rather than individually listening to each topic.

local MessagingService = game:GetService("MessagingService");
local Listeners = {};

local module = {};
module.__index = module;

function module.new(topic)
	local self = setmetatable({
		Topic = topic;
	}, module);
	return self;
end;

function module:Push(data, compatibility)
	if compatibility then
		-- In compatibility mode, 'data' is the topic and 'compatibility' is the message data.
		MessagingService:PublishAsync('RedefineA5', {Topic = data, Data = compatibility});
	else
		MessagingService:PublishAsync('RedefineA5', {Topic = self.Topic, Data = data});
	end;
end

function module:Publish(topic, data)
	MessagingService:PublishAsync('RedefineA5', {Topic = topic, Data = data});
end;

function module:Listen(callback, compatibility)
	if compatibility then
		-- Compatibility mode: first argument is the topic, second is the callback.
		Listeners[compatibility] = callback;
	else
		Listeners[self.Topic] = callback;
	end;
end;

function module:Subscribe(topic, callback)
	Listeners[topic] = callback;
end;

function module:Unlisten()
	Listeners[self.Topic] = nil;
end;

function module:Unsubscribe(topic)
	Listeners[topic] = nil;
end;

-- Unique functions
function module:Once(callback)
	Listeners[self.Topic] = function(data)
		callback(data);
		Listeners[self.Topic] = nil;
	end;
end;

function module:Promise()
	local result = {Complete = false, Data = nil};
	Listeners[self.Topic] = function(data)
		result.Complete = true;
		result.Data = data;
		Listeners[self.Topic] = nil;
	end;
	return result;
end;

function module:Wait()
	local result = {Complete = false, Data = nil};
	Listeners[self.Topic] = function(data)
		result.Complete = true;
		result.Data = data;
		Listeners[self.Topic] = nil;
	end;
	repeat task.wait() until result.Complete;
	return result.Data;
end

MessagingService:SubscribeAsync('RedefineA5', function(message)
	local payload = message.Data
	local topic = payload.Topic
	local data = payload.Data
	if Listeners[topic] then
		Listeners[topic](data)
	end
end);


return module;