local S={}do function S.Signal()local S={}local k=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")local F=nil local w=nil function S.fire(S,...)F={...}w=select("\035",...)k:Fire()end function S.connect(W,S)if not S then error("\099\111\110\110\101\099\116\040\110\105\108\041",2)end return k.Event:connect(function()S(unpack(F,1,w))end)end function S.wait(S)k.Event:wait()assert(F,"\077\105\115\115\105\110\103 \097\114\103 \100\097\116\097\044 \108\105\107\101\108\121 \100\117\101 \116\111 \058\084\119\101\101\110\083\105\122\101\047\080\111\115\105\116\105\111\110 \099\111\114\114\117\112\116\105\110\103 \116\104\114\101\097\100\114\101\102\115\046")return unpack(F,1,w)end return S end end function SetVisibility(S)ChatWindow:SetVisible(S)moduleApiTable.VisibilityStateChanged:fire(S)moduleApiTable.Visible=S if moduleApiTable.IsCoreGuiEnabled then if S then InstantFadeIn()else InstantFadeOut()end end end local k=nil do moduleApiTable.TopbarEnabled=true moduleApiTable.MessageCount=0 moduleApiTable.Visible=true moduleApiTable.IsCoreGuiEnabled=true function moduleApiTable.ToggleVisibility(S)SetVisibility(not ChatWindow:GetVisible())end function moduleApiTable.SetVisible(k,S)if ChatWindow:GetVisible()~=S then SetVisibility(S)end end function moduleApiTable.FocusChatBar(S)ChatBar:CaptureFocus()end function moduleApiTable.EnterWhisperState(k,S)ChatBar:EnterWhisperState(S)end function moduleApiTable.GetVisibility(S)return ChatWindow:GetVisible()end function moduleApiTable.GetMessageCount(S)return S.MessageCount end function moduleApiTable.TopbarEnabledChanged(k,S)k.TopbarEnabled=S k.CoreGuiEnabled:fire((game:GetService("\083\116\097\114\116\101\114\071\117\105")):GetCoreGuiEnabled(Enum.CoreGuiType.Chat))end function moduleApiTable.IsFocused(k,S)return ChatBar:IsFocused()end moduleApiTable.ChatBarFocusChanged=S.Signal()moduleApiTable.VisibilityStateChanged=S.Signal()moduleApiTable.MessagesChanged=S.Signal()moduleApiTable.MessagePosted=S.Signal()moduleApiTable.CoreGuiEnabled=S.Signal()moduleApiTable.ChatMakeSystemMessageEvent=S.Signal()moduleApiTable.ChatWindowPositionEvent=S.Signal()moduleApiTable.ChatWindowSizeEvent=S.Signal()moduleApiTable.ChatBarDisabledEvent=S.Signal()function moduleApiTable.fChatWindowPosition(S)return ChatWindow.GuiObject.Position end function moduleApiTable.fChatWindowSize(S)return ChatWindow.GuiObject.Size end function moduleApiTable.fChatBarDisabled(S)return not ChatBar:GetEnabled()end if FFlagUserHandleChatHotKeyWithContextActionService then local S="\084\111\103\103\108\101\067\104\097\116"local function F(F,w,W)if F==S and(w==Enum.UserInputState.Begin and(canChat and W.UserInputType==Enum.UserInputType.Keyboard))then k()end end ContextActionService:BindAction(S,F,true,Enum.KeyCode.Slash)else function moduleApiTable.SpecialKeyPressed(w,S,F)if S==Enum.SpecialKey.ChatHotkey then if canChat then k()end end end end end moduleApiTable.CoreGuiEnabled:connect(function(S)moduleApiTable.IsCoreGuiEnabled=S S=S and(moduleApiTable.TopbarEnabled or ChatSettings.ChatOnWithTopBarOff)ChatWindow:SetCoreGuiEnabled(S)if not S then ChatBar:ReleaseFocus()InstantFadeOut()else InstantFadeIn()end end)function trimTrailingSpaces(S)local k=#S while k>0 do if S:find("\094\037\115",k)then k=k-1 else break end end return S:sub(1,k)end moduleApiTable.ChatMakeSystemMessageEvent:connect(function(S)if S.Text and type(S.Text)=="\115\116\114\105\110\103"then while not DidFirstChannelsLoads do wait()end local k=ChatSettings.GeneralChannelName local F=ChatWindow:GetChannel(k)if F then local w={ID=-1,FromSpeaker=nil;SpeakerUserId=0;OriginalChannel=k,IsFiltered=true,MessageLength=string.len(S.Text),MessageLengthUtf8=utf8.len(utf8.nfcnormalize(S.Text));Message=trimTrailingSpaces(S.Text);MessageType=ChatConstants.MessageTypeSetCore,Time=os.time(),ExtraData=S}F:AddMessageToChannel(w)ChannelsBar:UpdateMessagePostedInChannel(k)moduleApiTable.MessageCount=moduleApiTable.MessageCount+1 moduleApiTable.MessagesChanged:fire(moduleApiTable.MessageCount)end end end)moduleApiTable.ChatBarDisabledEvent:connect(function(S)if canChat then ChatBar:SetEnabled(not S)if S then ChatBar:ReleaseFocus()end end end)moduleApiTable.ChatWindowSizeEvent:connect(function(S)ChatWindow.GuiObject.Size=S end)moduleApiTable.ChatWindowPositionEvent:connect(function(S)ChatWindow.GuiObject.Position=S end)
--////////////////////////////////////////////////////////////////////////////////////////////
--///////////// Code to talk to topbar and maintain set/get core backwards compatibility stuff
--////////////////////////////////////////////////////////////////////////////////////////////
local Util = {}
do
	function Util.Signal()
		local sig = {}

		local mSignaler = Instance.new("BindableEvent")

		local mArgData = nil
		local mArgDataCount = nil

		function sig:fire(...)
			mArgData = { ... }
			mArgDataCount = select("#", ...)
			mSignaler:Fire()
		end

		function sig:connect(f)
			if not f then
				error("connect(nil)", 2)
			end
			return mSignaler.Event:connect(function()
				f(unpack(mArgData, 1, mArgDataCount))
			end)
		end

		function sig:wait()
			mSignaler.Event:wait()
			assert(mArgData, "Missing arg data, likely due to :TweenSize/Position corrupting threadrefs.")
			return unpack(mArgData, 1, mArgDataCount)
		end

		return sig
	end
end

function SetVisibility(val)
	ChatWindow:SetVisible(val)
	moduleApiTable.VisibilityStateChanged:fire(val)
	moduleApiTable.Visible = val

	if moduleApiTable.IsCoreGuiEnabled then
		if val then
			InstantFadeIn()
		else
			InstantFadeOut()
		end
	end
end

local DoChatBarFocus = nil

do
	moduleApiTable.TopbarEnabled = true
	moduleApiTable.MessageCount = 0
	moduleApiTable.Visible = true
	moduleApiTable.IsCoreGuiEnabled = true

	function moduleApiTable:ToggleVisibility()
		SetVisibility(not ChatWindow:GetVisible())
	end

	function moduleApiTable:SetVisible(visible)
		if ChatWindow:GetVisible() ~= visible then
			SetVisibility(visible)
		end
	end

	function moduleApiTable:FocusChatBar()
		ChatBar:CaptureFocus()
	end

	function moduleApiTable:EnterWhisperState(player)
		ChatBar:EnterWhisperState(player)
	end

	function moduleApiTable:GetVisibility()
		return ChatWindow:GetVisible()
	end

	function moduleApiTable:GetMessageCount()
		return self.MessageCount
	end

	function moduleApiTable:TopbarEnabledChanged(enabled)
		self.TopbarEnabled = enabled
		self.CoreGuiEnabled:fire(game:GetService("StarterGui"):GetCoreGuiEnabled(Enum.CoreGuiType.Chat))
	end

	function moduleApiTable:IsFocused(useWasFocused)
		return ChatBar:IsFocused()
	end

	moduleApiTable.ChatBarFocusChanged = Util.Signal()
	moduleApiTable.VisibilityStateChanged = Util.Signal()
	moduleApiTable.MessagesChanged = Util.Signal()

	moduleApiTable.MessagePosted = Util.Signal()
	moduleApiTable.CoreGuiEnabled = Util.Signal()

	moduleApiTable.ChatMakeSystemMessageEvent = Util.Signal()
	moduleApiTable.ChatWindowPositionEvent = Util.Signal()
	moduleApiTable.ChatWindowSizeEvent = Util.Signal()
	moduleApiTable.ChatBarDisabledEvent = Util.Signal()

	function moduleApiTable:fChatWindowPosition()
		return ChatWindow.GuiObject.Position
	end

	function moduleApiTable:fChatWindowSize()
		return ChatWindow.GuiObject.Size
	end

	function moduleApiTable:fChatBarDisabled()
		return not ChatBar:GetEnabled()
	end

	if FFlagUserHandleChatHotKeyWithContextActionService then
		local TOGGLE_CHAT_ACTION_NAME = "ToggleChat"

		-- Callback when chat hotkey is pressed
		local function handleAction(actionName, inputState, inputObject)
			if
				actionName == TOGGLE_CHAT_ACTION_NAME
				and inputState == Enum.UserInputState.Begin
				and canChat
				and inputObject.UserInputType == Enum.UserInputType.Keyboard
			then
				DoChatBarFocus()
			end
		end
		ContextActionService:BindAction(TOGGLE_CHAT_ACTION_NAME, handleAction, true, Enum.KeyCode.Slash)
	else
		function moduleApiTable:SpecialKeyPressed(key, modifiers)
			if key == Enum.SpecialKey.ChatHotkey then
				if canChat then
					DoChatBarFocus()
				end
			end
		end
	end
end

moduleApiTable.CoreGuiEnabled:connect(function(enabled)
	moduleApiTable.IsCoreGuiEnabled = enabled

	enabled = enabled and (moduleApiTable.TopbarEnabled or ChatSettings.ChatOnWithTopBarOff)

	ChatWindow:SetCoreGuiEnabled(enabled)

	if not enabled then
		ChatBar:ReleaseFocus()
		InstantFadeOut()
	else
		InstantFadeIn()
	end
end)

function trimTrailingSpaces(str)
	local lastSpace = #str
	while lastSpace > 0 do
		--- The pattern ^%s matches whitespace at the start of the string. (Starting from lastSpace)
		if str:find("^%s", lastSpace) then
			lastSpace = lastSpace - 1
		else
			break
		end
	end
	return str:sub(1, lastSpace)
end

moduleApiTable.ChatMakeSystemMessageEvent:connect(function(valueTable)
	if valueTable["Text"] and type(valueTable["Text"]) == "string" then
		while not DidFirstChannelsLoads do
			wait()
		end

		local channel = ChatSettings.GeneralChannelName
		local channelObj = ChatWindow:GetChannel(channel)

		if channelObj then
			local messageObject = {
				ID = -1,
				FromSpeaker = nil,
				SpeakerUserId = 0,
				OriginalChannel = channel,
				IsFiltered = true,
				MessageLength = string.len(valueTable.Text),
				MessageLengthUtf8 = utf8.len(utf8.nfcnormalize(valueTable.Text)),
				Message = trimTrailingSpaces(valueTable.Text),
				MessageType = ChatConstants.MessageTypeSetCore,
				Time = os.time(),
				ExtraData = valueTable,
			}
			channelObj:AddMessageToChannel(messageObject)
			ChannelsBar:UpdateMessagePostedInChannel(channel)

			moduleApiTable.MessageCount = moduleApiTable.MessageCount + 1
			moduleApiTable.MessagesChanged:fire(moduleApiTable.MessageCount)
		end
	end
end)

moduleApiTable.ChatBarDisabledEvent:connect(function(disabled)
	if canChat then
		ChatBar:SetEnabled(not disabled)
		if disabled then
			ChatBar:ReleaseFocus()
		end
	end
end)

moduleApiTable.ChatWindowSizeEvent:connect(function(size)
	ChatWindow.GuiObject.Size = size
end)

moduleApiTable.ChatWindowPositionEvent:connect(function(position)
	ChatWindow.GuiObject.Position = position
end)
