Prompt: -- Decompiled with the Synapse X Luau decompiler.

Response:
local l__Players__1 = game:GetService("Players");
local l__ReplicatedStorage__2 = game:GetService("ReplicatedStorage");
local l__Chat__3 = game:GetService("Chat");
local l__TextService__4 = game:GetService("TextService");
local v5 = l__Players__1.LocalPlayer;
while v5 == nil do
	l__Players__1.ChildAdded:wait();
	v5 = l__Players__1.LocalPlayer;
end;
local l__PlayerGui__6 = v5:WaitForChild("PlayerGui");
local v7, v8 = pcall(function()
	return UserSettings():IsUserFeatureEnabled("UserShouldLocalizeGameChatBubble");
end);
local v9, v10 = pcall(function()
	return UserSettings():IsUserFeatureEnabled("UserFixBubbleChatText");
end);
local v11, v12 = pcall(function()
	return UserSettings():IsUserFeatureEnabled("UserRoactBubbleChatBeta");
end);
local v13, v14 = pcall(function()
	return UserSettings():IsUserFeatureEnabled("UserPreventOldBubbleChatOverlap");
end);
local function v15(p1)
	return utf8.len(utf8.nfcnormalize(p1));
end;
local v16 = 128 - v15("...") - 1;
local v17 = Instance.new("ScreenGui");
v17.Name = "BubbleChat";
v17.ResetOnSpawn = false;
v17.Parent = l__PlayerGui__6;
local function u1()
	local v18 = {
		data = {}
	};
	local v19 = Instance.new("BindableEvent");
	v18.Emptied = v19.Event;
	function v18.Size(p2)
		return #v18.data;
	end;
	function v18.Empty(p3)
		return v18:Size() <= 0;
	end;
	function v18.PopFront(p4)
		table.remove(v18.data, 1);
		if v18:Empty() then
			v19:Fire();
		end;
	end;
	function v18.Front(p5)
		return v18.data[1];
	end;
	function v18.Get(p6, p7)
		return v18.data[p7];
	end;
	function v18.PushBack(p8, p9)
		table.insert(v18.data, p9);
	end;
	function v18.GetData(p10)
		return v18.data;
	end;
	return v18;
end;
local function u2()
	return {
		Fifo = u1(),
		BillboardGui = nil
	};
end;
local function u3(p11, p12, p13)
	return p12 + (p13 - p12) * math.min(v15(p11) / 75, 1);
end;
local function u4(p14, p15, p16)
	local v20 = {
		ComputeBubbleLifetime = function(p17, p18, p19)
			if p19 then
				return u3(p18, 8, 15);
			end;
			return u3(p18, 12, 20);
		end,
		Origin = nil,
		RenderBubble = nil,
		Message = p14
	};
	v20.BubbleDieDelay = v20:ComputeBubbleLifetime(p14, p16);
	v20.BubbleColor = p15;
	v20.IsLocalPlayer = p16;
	return v20;
end;
local u5 = {
	WHITE = "dub",
	BLUE = "blu",
	GREEN = "gre",
	RED = "red"
};
function createChatBubbleMain(p20, p21)
	local v21 = Instance.new("ImageLabel");
	v21.Name = "ChatBubble";
	v21.ScaleType = Enum.ScaleType.Slice;
	v21.SliceCenter = p21;
	v21.Image = "rbxasset://textures/" .. tostring(p20) .. ".png";
	v21.BackgroundTransparency = 1;
	v21.BorderSizePixel = 0;
	v21.Size = UDim2.new(1, 0, 1, 0);
	v21.Position = UDim2.new(0, 0, 0, 0);
	return v21;
end;
function createChatBubbleTail(p22, p23)
	local v22 = Instance.new("ImageLabel");
	v22.Name = "ChatBubbleTail";
	v22.Image = "rbxasset://textures/ui/dialog_tail.png";
	v22.BackgroundTransparency = 1;
	v22.BorderSizePixel = 0;
	v22.Position = p22;
	v22.Size = p23;
	return v22;
end;
function createChatBubbleWithTail(p24, p25, p26, p27)
	local v23 = createChatBubbleMain(p24, p27);
	createChatBubbleTail(p25, p26).Parent = v23;
	return v23;
end;
function createScaledChatBubbleWithTail(p28, p29, p30, p31)
	local v24 = createChatBubbleMain(p28, p31);
	local v25 = Instance.new("Frame");
	v25.Name = "ChatBubbleTailFrame";
	v25.BackgroundTransparency = 1;
	v25.SizeConstraint = Enum.SizeConstraint.RelativeXX;
	v25.Position = UDim2.new(0.5, 0, 1, 0);
	v25.Size = UDim2.new(p29, 0, p29, 0);
	v25.Parent = v24;
	createChatBubbleTail(p30, UDim2.new(1, 0, 0.5, 0)).Parent = v25;
	return v24;
end;
function createChatImposter(p32, p33, p34)
	local v26 = Instance.new("ImageLabel");
	v26.Name = "DialogPlaceholder";
	v26.Image = "rbxasset://textures/" .. tostring(p32) .. ".png";
	v26.BackgroundTransparency = 1;
	v26.BorderSizePixel = 0;
	v26.Position = UDim2.new(0, 0, -1.25, 0);
	v26.Size = UDim2.new(1, 0, 1, 0);
	local v27 = Instance.new("ImageLabel");
	v27.Name = "DotDotDot";
	v27.Image = "rbxasset://textures/" .. tostring(p33) .. ".png";
	v27.BackgroundTransparency = 1;
	v27.BorderSizePixel = 0;
	v27.Position = UDim2.new(0.001, 0, p34, 0);
	v27.Size = UDim2.new(1, 0, 0.7, 0);
	v27.Parent = v26;
	return v26;
end;
local u6 = {
	ChatBubble = {},
	ChatBubbleWithTail = {},
	ScalingChatBubbleWithTail = {},
	CharacterSortedMsg = (function()
		local v28 = {
			data = {}
		};
		local u7 = 0;
		function v28.Size(p35)
			return u7;
		end;
		function v28.Erase(p36, p37)
			if v28.data[p37] then
				u7 = u7 - 1;
			end;
			v28.data[p37] = nil;
		end;
		function v28.Set(p38, p39, p40)
			v28.data[p39] = p40;
			if p40 then
				u7 = u7 + 1;
			end;
		end;
		function v28.Get(p41, p42)
			if not p42 then
				return;
			end;
			if not v28.data[p42] then
				v28.data[p42] = u2();
				local u8 = nil;
				u8 = v28.data[p42].Fifo.Emptied:connect(function()
					u8:disconnect();
					v28:Erase(p42);
				end);
			end;
			return v28.data[p42];
		end;
		function v28.GetData(p43)
			return v28.data;
		end;
		return v28;
	end)()
};
local function v29(p44, p45, p46, p47, p48)
	u6.ChatBubble[p44] = createChatBubbleMain(p45, p48);
	if p47 then
		local v30 = -1;
	else
		v30 = 0;
	end;
	u6.ChatBubbleWithTail[p44] = createChatBubbleWithTail(p45, UDim2.new(0.5, -14, 1, v30), UDim2.new(0, 30, 0, 14), p48);
	if p47 then
		local v31 = -1;
	else
		v31 = 0;
	end;
	u6.ScalingChatBubbleWithTail[p44] = createScaledChatBubbleWithTail(p45, 0.5, UDim2.new(-0.5, 0, 0, v31), p48);
end;
v29(u5.WHITE, "ui/dialog_white", "ui/chatBubble_white_notify_bkg", false, Rect.new(5, 5, 15, 15));
v29(u5.BLUE, "ui/dialog_blue", "ui/chatBubble_blue_notify_bkg", true, Rect.new(7, 7, 33, 33));
v29(u5.RED, "ui/dialog_red", "ui/chatBubble_red_notify_bkg", true, Rect.new(7, 7, 33, 33));
v29(u5.GREEN, "ui/dialog_green", "ui/chatBubble_green_notify_bkg", true, Rect.new(7, 7, 33, 33));
function u6.SanitizeChatLine(p49, p50)
	if not (v16 < v15(p50)) then
		return p50;
	end;
	return string.sub(p50, 1, utf8.offset(p50, v16 + v15("...") + 1) - 1);
end;
local function u9(p51)
	local v32 = Instance.new("BillboardGui");
	v32.Adornee = p51;
	v32.Size = UDim2.new(0, 400, 0, 250);
	v32.StudsOffset = Vector3.new(0, 1.5, 2);
	v32.Parent = v17;
	local v33 = Instance.new("Frame");
	v33.Name = "BillboardFrame";
	v33.Size = UDim2.new(1, 0, 1, 0);
	v33.Position = UDim2.new(0, 0, -0.5, 0);
	v33.BackgroundTransparency = 1;
	v33.Parent = v32;
	local u10 = nil;
	u10 = v33.ChildRemoved:connect(function()
		if #v33:GetChildren() <= 1 then
			u10:disconnect();
			v32:Destroy();
		end;
	end);
	u6:CreateSmallTalkBubble(u5.WHITE).Parent = v33;
	return v32;
end;
function u6.CreateBillboardGuiHelper(p52, p53, p54)
	if p53 and not u6.CharacterSortedMsg:Get(p53).BillboardGui then
		if not p54 and p53:IsA("BasePart") then
			u6.CharacterSortedMsg:Get(p53).BillboardGui = u9(p53);
			return;
		end;
		if p53:IsA("Model") then
			local l__Head__34 = p53:FindFirstChild("Head");
			if l__Head__34 and l__Head__34:IsA("BasePart") then
				u6.CharacterSortedMsg:Get(p53).BillboardGui = u9(l__Head__34);
			end;
		end;
	end;
end;
local function u11(p55)
	if not p55 or not l__Players__1.LocalPlayer.Character then
		return;
	end;
	return p55:IsDescendantOf(l__Players__1.LocalPlayer.Character);
end;
function u6.SetBillboardLODNear(p56, p57)
	local v35 = u11(p57.Adornee);
	p57.Size = UDim2.new(0, 400, 0, 250);
	if v35 then
		local v36 = 1.5;
	else
		v36 = 2.5;
	end;
	if v35 then
		local v37 = 2;
	else
		v37 = 0.1;
	end;
	p57.StudsOffset = Vector3.new(0, v36, v37);
	p57.Enabled = true;
	local v38 = p57.BillboardFrame:GetChildren();
	for v39 = 1, #v38 do
		v38[v39].Visible = true;
	end;
	p57.BillboardFrame.SmallTalkBubble.Visible = false;
end;
function u6.SetBillboardLODDistant(p58, p59)
	p59.Size = UDim2.new(4, 0, 3, 0);
	if u11(p59.Adornee) then
		local v40 = 2;
	else
		v40 = 0.1;
	end;
	p59.StudsOffset = Vector3.new(0, 3, v40);
	p59.Enabled = true;
	local v41 = p59.BillboardFrame:GetChildren();
	for v42 = 1, #v41 do
		v41[v42].Visible = false;
	end;
	p59.BillboardFrame.SmallTalkBubble.Visible = true;
end;
function u6.SetBillboardLODVeryFar(p60, p61)
	p61.Enabled = false;
end;
local function u12(p62)
	if not p62 then
		return 100000;
	end;
	return (p62.Position - game.Workspace.CurrentCamera.CoordinateFrame.p).magnitude;
end;
function u6.SetBillboardGuiLOD(p63, p64, p65)
	if not p65 then
		return;
	end;
	if p65:IsA("Model") then
		local l__Head__43 = p65:FindFirstChild("Head");
		if not l__Head__43 then
			p65 = p65.PrimaryPart;
		else
			p65 = l__Head__43;
		end;
	end;
	local v44 = u12(p65);
	if v44 < 65 then
		u6:SetBillboardLODNear(p64);
		return;
	end;
	if v44 >= 65 and v44 < 100 then
		u6:SetBillboardLODDistant(p64);
		return;
	end;
	u6:SetBillboardLODVeryFar(p64);
end;
function u6.CameraCFrameChanged(p66)
	for v45, v46 in pairs(u6.CharacterSortedMsg:GetData()) do
		local l__BillboardGui__47 = v46.BillboardGui;
		if l__BillboardGui__47 then
			u6:SetBillboardGuiLOD(l__BillboardGui__47, v45);
		end;
	end;
end;
local u13 = v9 or v10;
local l__Enum_Font_SourceSans__14 = Enum.Font.SourceSans;
local l__Enum_FontSize_Size24__15 = Enum.FontSize.Size24;
function u6.CreateBubbleText(p67, p68, p69)
	local v48 = Instance.new("TextLabel");
	v48.Name = "BubbleText";
	v48.BackgroundTransparency = 1;
	if u13 then
		v48.Size = UDim2.fromScale(1, 1);
	else
		v48.Position = UDim2.new(0, 15, 0, 0);
		v48.Size = UDim2.new(1, -30, 1, 0);
	end;
	v48.Font = l__Enum_Font_SourceSans__14;
	v48.ClipsDescendants = true;
	v48.TextWrapped = true;
	v48.FontSize = l__Enum_FontSize_Size24__15;
	v48.Text = p68;
	v48.Visible = false;
	v48.AutoLocalize = p69;
	if u13 then
		local v49 = Instance.new("UIPadding");
		v49.PaddingTop = UDim.new(0, 12);
		v49.PaddingRight = UDim.new(0, 12);
		v49.PaddingBottom = UDim.new(0, 12);
		v49.PaddingLeft = UDim.new(0, 12);
		v49.Parent = v48;
	end;
	return v48;
end;
function u6.CreateSmallTalkBubble(p70, p71)
	local v50 = u6.ScalingChatBubbleWithTail[p71]:Clone();
	v50.Name = "SmallTalkBubble";
	v50.AnchorPoint = Vector2.new(0, 0.5);
	v50.Position = UDim2.new(0, 0, 0.5, 0);
	v50.Visible = false;
	local v51 = u6:CreateBubbleText("...");
	v51.TextScaled = true;
	v51.TextWrapped = false;
	v51.Visible = true;
	v51.Parent = v50;
	return v50;
end;
function u6.UpdateChatLinesForOrigin(p72, p73, p74)
	local l__Fifo__52 = u6.CharacterSortedMsg:Get(p73).Fifo;
	local v53 = l__Fifo__52:Size();
	local v54 = l__Fifo__52:GetData();
	if #v54 <= 1 then
		return;
	end;
	for v55 = #v54 - 1, 1, -1 do
		local l__RenderBubble__56 = v54[v55].RenderBubble;
		if not l__RenderBubble__56 then
			return;
		end;
		if v53 - v55 + 1 > 1 then
			local l__ChatBubbleTail__57 = l__RenderBubble__56:FindFirstChild("ChatBubbleTail");
			if l__ChatBubbleTail__57 then
				l__ChatBubbleTail__57:Destroy();
			end;
			local l__BubbleText__58 = l__RenderBubble__56:FindFirstChild("BubbleText");
			if l__BubbleText__58 then
				l__BubbleText__58.TextTransparency = 0.5;
			end;
		end;
		l__RenderBubble__56:TweenPosition(UDim2.new(l__RenderBubble__56.Position.X.Scale, l__RenderBubble__56.Position.X.Offset, 1, p74 - l__RenderBubble__56.Size.Y.Offset - 14), Enum.EasingDirection.Out, Enum.EasingStyle.Bounce, 0.1, true);
		p74 = p74 - l__RenderBubble__56.Size.Y.Offset - 14;
	end;
end;
function u6.DestroyBubble(p75, p76, p77)
	if not p76 then
		return;
	end;
	if p76:Empty() then
		return;
	end;
	local l__RenderBubble__59 = p76:Front().RenderBubble;
	if l__RenderBubble__59 then
		local u16 = l__RenderBubble__59;
		spawn(function()
			while p76:Front().RenderBubble ~= p77 do
				wait();
			end;
			u16 = p76:Front().RenderBubble;
			local l__BubbleText__60 = u16:FindFirstChild("BubbleText");
			local l__ChatBubbleTail__61 = u16:FindFirstChild("ChatBubbleTail");
			while u16 and u16.ImageTransparency < 1 do
				local v62 = wait();
				if u16 then
					local v63 = v62 * 1.5;
					u16.ImageTransparency = u16.ImageTransparency + v63;
					if l__BubbleText__60 then
						l__BubbleText__60.TextTransparency = l__BubbleText__60.TextTransparency + v63;
					end;
					if l__ChatBubbleTail__61 then
						l__ChatBubbleTail__61.ImageTransparency = l__ChatBubbleTail__61.ImageTransparency + v63;
					end;
				end;
			end;
			if u16 then
				u16:Destroy();
				p76:PopFront();
			end;
		end);
		return;
	end;
	p76:PopFront();
end;
function u6.CreateChatLineRender(p78, p79, p80, p81, p82, p83)
	if not p79 then
		return;
	end;
	if not u6.CharacterSortedMsg:Get(p79).BillboardGui then
		u6:CreateBillboardGuiHelper(p79, p81);
	end;
	local l__BillboardGui__64 = u6.CharacterSortedMsg:Get(p79).BillboardGui;
	if l__BillboardGui__64 then
		local v65 = nil;
		local v66 = u6.ChatBubbleWithTail[p80.BubbleColor]:Clone();
		v66.Visible = false;
		local v67 = u6:CreateBubbleText(p80.Message, p83);
		v67.Parent = v66;
		v66.Parent = l__BillboardGui__64.BillboardFrame;
		p80.RenderBubble = v66;
		local v68 = l__TextService__4:GetTextSize(v67.Text, 24, l__Enum_Font_SourceSans__14, Vector2.new(400, 250));
		v65 = v68.Y / 24;
		if u13 then
			local v69 = math.ceil(v68.X + 24);
			local v70 = v65 * 34;
			v66.Size = UDim2.fromOffset(0, 0);
			v66.Position = UDim2.fromScale(0.5, 1);
			v66:TweenSizeAndPosition(UDim2.fromOffset(v69, v70), UDim2.new(0.5, -v69 / 2, 1, -v70), Enum.EasingDirection.Out, Enum.EasingStyle.Elastic, 0.1, true, function()
				v67.Visible = true;
			end);
			u6:SetBillboardGuiLOD(l__BillboardGui__64, p80.Origin);
			u6:UpdateChatLinesForOrigin(p80.Origin, -v70);
		else
			local v71 = math.max((v68.X + 30) / 400, 0.1);
			v66.Size = UDim2.new(0, 0, 0, 0);
			v66.Position = UDim2.new(0.5, 0, 1, 0);
			local v72 = v65 * 34;
			v66:TweenSizeAndPosition(UDim2.new(v71, 0, 0, v72), UDim2.new((1 - v71) / 2, 0, 1, -v72), Enum.EasingDirection.Out, Enum.EasingStyle.Elastic, 0.1, true, function()
				v67.Visible = true;
			end);
			u6:SetBillboardGuiLOD(l__BillboardGui__64, p80.Origin);
			u6:UpdateChatLinesForOrigin(p80.Origin, -v72);
		end;
		delay(p80.BubbleDieDelay, function()
			u6:DestroyBubble(p82, v66);
		end);
	end;
end;
local function u17(p84, p85, p86)
	local v73 = u4(p85, u5.WHITE, p86);
	if p84 then
		v73.User = p84.Name;
		v73.Origin = p84.Character;
	end;
	return v73;
end;
function u6.OnPlayerChatMessage(p87, p88, p89, p90)
	if not u6:BubbleChatEnabled() then
		return;
	end;
	local l__LocalPlayer__74 = l__Players__1.LocalPlayer;
	local v75 = false;
	if l__LocalPlayer__74 ~= nil then
		v75 = p88 ~= l__LocalPlayer__74;
	end;
	local v76 = u17(p88, u6:SanitizeChatLine(p89), not v75);
	if p88 and v76.Origin then
		local l__Fifo__77 = u6.CharacterSortedMsg:Get(v76.Origin).Fifo;
		l__Fifo__77:PushBack(v76);
		u6:CreateChatLineRender(p88.Character, v76, true, l__Fifo__77, false);
	end;
end;
local u18 = v11 or v12;
local u19 = v13 or v14;
local function u20(p91, p92, p93, p94)
	local v78 = u4(p92, p94, p93);
	v78.Origin = p91;
	return v78;
end;
local u21 = v7 or v8;
function u6.OnGameChatMessage(p95, p96, p97, p98)
	if u18 or u19 and l__Chat__3.BubbleChatEnabled then
		return;
	end;
	local l__LocalPlayer__79 = l__Players__1.LocalPlayer;
	local v80 = false;
	if l__LocalPlayer__79 ~= nil then
		v80 = l__LocalPlayer__79.Character ~= p96;
	end;
	local v81 = u5.WHITE;
	if p98 == Enum.ChatColor.Blue then
		v81 = u5.BLUE;
	elseif p98 == Enum.ChatColor.Green then
		v81 = u5.GREEN;
	elseif p98 == Enum.ChatColor.Red then
		v81 = u5.RED;
	end;
	local v82 = u20(p96, u6:SanitizeChatLine(p97), not v80, v81);
	u6.CharacterSortedMsg:Get(v82.Origin).Fifo:PushBack(v82);
	if u21 then
		u6:CreateChatLineRender(p96, v82, false, u6.CharacterSortedMsg:Get(v82.Origin).Fifo, true);
		return;
	end;
	u6:CreateChatLineRender(p96, v82, false, u6.CharacterSortedMsg:Get(v82.Origin).Fifo, false);
end;
function u6.BubbleChatEnabled(p99)
	if u18 or u19 and l__Chat__3.BubbleChatEnabled then
		return false;
	end;
	local l__ClientChatModules__83 = l__Chat__3:FindFirstChild("ClientChatModules");
	if l__ClientChatModules__83 then
		local l__ChatSettings__84 = l__ClientChatModules__83:FindFirstChild("ChatSettings");
		if l__ChatSettings__84 then
			local v85 = require(l__ChatSettings__84);
			if v85.BubbleChatEnabled ~= nil then
				return v85.BubbleChatEnabled;
			end;
		end;
	end;
	return l__Players__1.BubbleChat;
end;
function u6.ShowOwnFilteredMessage(p100)
	local v86 = nil;
	local l__ClientChatModules__87 = l__Chat__3:FindFirstChild("ClientChatModules");
	if l__ClientChatModules__87 then
		v86 = l__ClientChatModules__87:FindFirstChild("ChatSettings");
		if not v86 then
			return false;
		end;
	else
		return false;
	end;
	return require(v86).ShowUserOwnFilteredMessage;
end;
function findPlayer(p101)
	local v88, v89, v90 = pairs(l__Players__1:GetPlayers());
	while true do
		local v91, v92 = v88(v89, v90);
		if v91 then

		else
			break;
		end;
		v90 = v91;
		if v92.Name == p101 then
			return v92;
		end;
	end;
end;
l__Chat__3.Chatted:connect(function(p102, p103, p104)
	u6:OnGameChatMessage(p102, p103, p104);
end);
local v93 = nil;
if game.Workspace.CurrentCamera then
	v93 = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(p105)
		u6:CameraCFrameChanged();
	end);
end;
local u22 = v93;
game.Workspace.Changed:connect(function(p106)
	if p106 == "CurrentCamera" then
		if u22 then
			u22:disconnect();
		end;
		if game.Workspace.CurrentCamera then
			u22 = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(p107)
				u6:CameraCFrameChanged();
			end);
		end;
	end;
end);
local u23 = nil;
function getAllowedMessageTypes()
	if u23 then
		return u23;
	end;
	local l__ClientChatModules__94 = l__Chat__3:FindFirstChild("ClientChatModules");
	if l__ClientChatModules__94 then

	else
		return { "Message", "Whisper" };
	end;
	local l__ChatSettings__95 = l__ClientChatModules__94:FindFirstChild("ChatSettings");
	if l__ChatSettings__95 then
		local v96 = require(l__ChatSettings__95);
		if v96.BubbleChatMessageTypes then
			u23 = v96.BubbleChatMessageTypes;
			return u23;
		end;
	end;
	local l__ChatConstants__97 = l__ClientChatModules__94:FindFirstChild("ChatConstants");
	if l__ChatConstants__97 then
		local v98 = require(l__ChatConstants__97);
		u23 = { v98.MessageTypeDefault, v98.MessageTypeWhisper };
	end;
	return u23;
end;
function checkAllowedMessageType(p108)
	local v99 = getAllowedMessageTypes();
	local v100 = #v99;
	local v101 = 1 - 1;
	while true do
		if v99[v101] == p108.MessageType then
			return true;
		end;
		if 0 <= 1 then
			if v101 < v100 then

			else
				break;
			end;
		elseif v100 < v101 then

		else
			break;
		end;
		v101 = v101 + 1;
	end;
	return false;
end;
local v102 = l__ReplicatedStorage__2:WaitForChild("DefaultChatSystemChatEvents");
local l__OnMessageDoneFiltering__103 = v102:WaitForChild("OnMessageDoneFiltering");
v102:WaitForChild("OnNewMessage").OnClientEvent:connect(function(p109, p110)
	if not checkAllowedMessageType(p109) then
		return;
	end;
	local v104 = findPlayer(p109.FromSpeaker);
	if not v104 then
		return;
	end;
	if (not p109.IsFiltered or p109.FromSpeaker == v5.Name) and (p109.FromSpeaker ~= v5.Name or u6:ShowOwnFilteredMessage()) then
		return;
	end;
	u6:OnPlayerChatMessage(v104, p109.Message, nil);
end);
l__OnMessageDoneFiltering__103.OnClientEvent:connect(function(p111, p112)
	if not checkAllowedMessageType(p111) then
		return;
	end;
	local v105 = findPlayer(p111.FromSpeaker);
	if not v105 then
		return;
	end;
	if p111.FromSpeaker == v5.Name and not u6:ShowOwnFilteredMessage() then
		return;
	end;
	u6:OnPlayerChatMessage(v105, p111.Message, nil);
end);


Prompt: -- << CLIENT COMMANDS >>

Response:
local module = {

	----------------------------------------------------------------------
	["ping"] = {
		Function = function(speaker, args)
			local startTime = tick()
			local returnValue = main.signals.GetPing:InvokeServer(math.random(1,1000))
			local timeTaken = tick() - startTime
			local ping = timeTaken/2
			local pingMs = ping*1000
			local depth = 1000
			local pingMsRounded = math.floor((pingMs*depth)+0.5)/depth
			main:GetModule("Notices"):Notice("Notice", main.hdAdminCoreName, "Your ping is "..pingMsRounded.."!")
		end;
		};

	----------------------------------------------------------------------
	["blur"] = {
		Function = function(speaker, args)
			main.blur.Size = (args[2] ~= 0 and args[2]) or 20
		end;
		UnFunction = function(speaker, args)
			main.blur.Size = 0
		end;
		};

	----------------------------------------------------------------------
	["showGuis"] = {
		Function = function(speaker, args)
			for a,b in pairs(hiddenGuis) do
				a.Enabled = true
			end
			hiddenGuis = {}
		end;
		};

	----------------------------------------------------------------------
	["hideGuis"] = {
		Function = function(speaker, args)
			for a,b in pairs(main.playerGui:GetChildren()) do
				if b:IsA("ScreenGui") and b.Name ~= "Chat" and b.Name ~= "HDAdminGUIs" then
					if b.Enabled == true then
						hiddenGuis[b] = true
					end
					b.Enabled = false
				end
			end
		end;
		};

	----------------------------------------------------------------------
	["view"] = {
		Function = function(speaker, args)
			local plr = args[1]
			local humanoid = main:GetModule("cf"):GetHumanoid(plr)
			if humanoid then
				main:GetModule("cf"):SetCameraSubject(humanoid)
			end
		end;
		UnFunction = function(speaker, args)
			local humanoid = main:GetModule("cf"):GetHumanoid(speaker)
			if humanoid then
				main.signals.SetCameraSubject:FireClient(speaker, (humanoid))
			end
		end
		};

	----------------------------------------------------------------------
	["nightVision"] = {
		Function = function(speaker, args)
			for _,plr in pairs(main.players:GetChildren()) do
				local head = main:GetModule("cf"):GetHead(plr)
				if plr.Name ~= main.player.Name and head then
					for a,b in pairs(plr.Character:GetChildren()) do
						if b:IsA("BasePart") and b:FindFirstChild("HDNightVision") == nil then
							for i = 1,6 do
								local nv = main.client.Assets.NightVision:Clone()
								nv.Parent = b
								nv.Face = i-1
								nv.Name = "HDAdminNightVision"
							end
						end
					end
					local nv = main.client.Assets.Nickname:Clone()
					nv.TextLabel.Text = plr.Name
					nv.Parent = head
					nv.Name = "HDAdminNightVision"
				end
			end
		end;
		UnFunction = function(speaker, args)
			for _,plr in pairs(main.players:GetChildren()) do
				if plr.Character then
					for a,b in pairs(plr.Character:GetDescendants()) do
						if b.Name == "HDAdminNightVision" then
							b:Destroy()
						end
					end
				end
			end
		end;
		};

	----------------------------------------------------------------------
	["cmdbar"] = {
		Function = function(speaker, args)
			main:GetModule("CmdBar"):OpenCmdBar()
		end;
		};

	----------------------------------------------------------------------
	["cmdbar2"] = {
		Function = function(speaker, args)
			main:GetModule("cf"):CreateNewCommandMenu("cmdbar2", {}, 2)
		end;
		};

	----------------------------------------------------------------------
	["rainbowFart"] = {
		Function = function(speaker, args)
			local plr = args[1]
			local maxPoops = 20
			local poopSounds = {174658105,148635119}
			local function poopSound(sound_id,part)
				local soundPoop = Instance.new("Sound",part)
				soundPoop.SoundId = "rbxassetid://"..sound_id
				soundPoop.Volume = 0.5
				soundPoop:Play()
				local soundPlaying = soundPoop.IsPlaying or soundPoop.Played:Wait()
				--repeat wait() until soundPoop.IsPlaying
				wait()
			end
			local function poop(clone,toilet,sound_id,poopCount, poopGroup)
				local poop = main.client.Assets.Poop:Clone()
				poopSound(sound_id,poop)
				poop.CanCollide = false
				-- Changed to 'rainbow' as Roblox 'do not allow the use of commands where the central focus is the egregious act of defecation'
				local totalPoops = maxPoops
				local increment = 1/totalPoops
				local newH = (poopCount-1)*increment
				local newColor = Color3.fromHSV(newH, 0.7, 0.7)
				poop.Color = newColor
				--
				poop.CFrame = toilet.Seat.CFrame * CFrame.new(0,(poopCount*1)-0.5,0)
				clone:SetPrimaryPartCFrame(poop.CFrame * CFrame.new(0,3,0))
				poop.Parent = poopGroup
			end

			local head = main:GetModule("cf"):GetHead(plr)
			if not head then return end

			local originalCFrame = head.CFrame

			plr.Character.Parent = nil
			local clone, tracks = main:GetModule("cf"):CreateClone(plr.Character)
			--
			if tracks.sit.Length <= 0 then repeat wait() until tracks.sit.Length > 0 end
			--
			clone.Head.CFrame = originalCFrame
			if plr == main.player then
				main:GetModule("cf"):Movement(false)
				main:GetModule("cf"):SetCameraSubject(clone.Humanoid)
			end
			--main:GetModule("cf"):SetTransparency(plr.Character, 1)

			local poopCount = 0
			local poopGroup = Instance.new("Model",workspace)
			local toilet = main.client.Assets.Toilet:Clone()

			poopGroup.Name = plr.Name.."'s poop"
			toilet.PrimaryPart = toilet.Seat
			toilet:SetPrimaryPartCFrame(clone.HumanoidRootPart.CFrame * CFrame.new(0,-1,0)) --* CFrame.Angles(0,math.rad(90), 0))
			toilet.Parent = workspace
			toilet.Seat:Sit(clone.Humanoid)
			tracks.sit:Play(0)
			clone.Head.face.Texture = "rbxassetid://304907108"
			wait()
			clone.PrimaryPart = clone.Head
			clone:SetPrimaryPartCFrame(toilet.PrimaryPart.CFrame * CFrame.new(0,3,0))
			for a,b in pairs(clone:GetChildren()) do
				if b:IsA("BasePart") and b.Name ~= "HumanoidRootPart" then
					b.Anchored = true
				end
			end
			wait(1)
			--
			poopSound(174658105,clone.HumanoidRootPart)
			wait(2)
			poopCount = poopCount + 1
			poop(clone,toilet,148635119,poopCount, poopGroup, poopGroup)
			clone.Head.face.Texture = "rbxassetid://338312149"
			wait(1.5)
			clone.Head.face.Texture = "rbxassetid://316545711"
			for i = 1,maxPoops do
				if i == maxPoops-2 then
					for a,b in pairs(clone:GetChildren()) do
						if b:IsA("BasePart") and b.Name ~= "HumanoidRootPart" then
							b.Anchored = false
						end
					end
					local explosion = Instance.new("Explosion")
					explosion.Position = clone.Head.Position
					explosion.Parent = clone
					explosion.DestroyJointRadiusPercent = 0
					clone:BreakJoints()
				elseif i > maxPoops-1 then
					for a,b in pairs(poopGroup:GetChildren()) do
						b.Anchored = false
						b.CanCollide = true
					end
				end
				poopCount = poopCount + 1
				if i >= maxPoops then
					wait(1.5)
				else
					poop(clone,toilet,poopSounds[math.random(1,#poopSounds)],poopCount, poopGroup)
					wait()
				end
			end

			wait(3)
			poopGroup:Destroy()
			toilet:Destroy()
			clone:Destroy()

			if plr == main.player then
				local humanoid = main:GetModule("cf"):GetHumanoid(plr)
				if humanoid then
					main:GetModule("cf"):Movement(true)
					main:GetModule("cf"):SetCameraSubject(humanoid)
				end
			end
			--main:GetModule("cf"):SetTransparency(plr.Character, 0)
			plr.Character.Parent = workspace
		end;
		};

	----------------------------------------------------------------------
	["icecream"] = {
		Function = function(speaker, args)

			local plr = args[1]

			--Create clone and hide char
			plr.Character.Parent = nil
			local clone, tracks = main:GetModule("cf"):CreateClone(plr.Character)
			local hrp = clone:FindFirstChild("HumanoidRootPart")
			if hrp == nil then clone:Destroy() return end
			hrp.Anchored = true
			tracks.idle:Play()
			main:GetModule("cf"):SetTransparency(plr.Character, 1)

			--Create van
			local van = main.client.Assets.IcecreamVan:Clone()
			van.PrimaryPart = van.VanDoor.Part1
			van:SetPrimaryPartCFrame(hrp.CFrame * CFrame.new(-210,3,-4) * CFrame.Angles(0,math.rad(90), 0))
			van.Parent = workspace

			--Disable movement and set camera if player == plr
			if plr == main.player then
				main:GetModule("cf"):Movement(false)
				main:GetModule("cf"):SetCameraSubject(clone.Humanoid)
				for a,b in pairs(van:GetDescendants()) do
					if b:IsA("BasePart") then
						b.CanCollide = true
					end
				end
			end

			--Setup Sounds
			local soundIcecream = main:GetModule("cf"):CreateSound{SoundId = 260910474, Volume = 0.5, Parent = van.PrimaryPart}
			local soundClowns = main:GetModule("cf"):CreateSound{SoundId = 861942173, Volume = 4, Parent = van.PrimaryPart}
			local soundBaby = main:GetModule("cf"):CreateSound{SoundId = 2628538600, Volume = 0.15, Parent = van.PrimaryPart}
			local soundScream = main:GetModule("cf"):CreateSound{SoundId = 147758746, Volume = 0.8, Parent = van.PrimaryPart}

			--Tween van to plr
			soundIcecream:Play()
			main:GetModule("cf"):TweenModel(van, van.PrimaryPart.CFrame * CFrame.new(0, 0, 210), TweenInfo.new(8))
			wait(8.1)
			local tween = main.tweenService:Create(soundIcecream, TweenInfo.new(0.5), {Volume = 0})
			tween:Play()
			tween.Completed:Wait()
			soundIcecream:Stop()
			soundIcecream:Destroy()
			wait(1)

			--Open doors, get plr and close doors
			van.VanDoor.Part1.Transparency = 1
			van.VanDoor.Part2.Transparency = 1
			wait(1)
			clone.PrimaryPart = clone.Head
			clone:SetPrimaryPartCFrame(van.Clown.Head.CFrame * CFrame.new(0,0,-2.5) * CFrame.Angles(0,math.rad(180), 0))
			local originalMinZoom = plr.CameraMinZoomDistance
			local originalMaxZoom = plr.CameraMaxZoomDistance
			if plr == main.player then
				plr.CameraMaxZoomDistance = 0.5
				spawn(function()
					plr.CameraMaxZoomDistance = 1
				end)
			end
			local face = clone.Head:FindFirstChild("face")
			if face then
				face.Texture = "rbxassetid://338312149"
			end
			soundClowns:Play()
			wait(1)
			van.VanDoor.Part1.Transparency = 0
			van.VanDoor.Part2.Transparency = 0
			clone.Parent = van
			for a,b in pairs(clone:GetChildren()) do
				if b:IsA("Accessory") then
					b:remove()
				end
			end

			--Tween van away
			soundIcecream:Play()
			main:GetModule("cf"):TweenModel(van, van.PrimaryPart.CFrame * CFrame.new(0, 0, 400), TweenInfo.new(14, Enum.EasingStyle.Quad, Enum.EasingDirection.In))

			--Show scary stuff and scream
			wait(4)
			local arm = van.Clown["Right Arm"]
			arm.CFrame = arm.CFrame * CFrame.fromEulerAnglesXYZ(math.rad(45), 0, 0)
			for a,b in pairs(van.Doll:GetChildren()) do
				b.Transparency = 0
			end
			van.Doll.Head.face.Transparency = 0
			wait(0.1)
			soundBaby:Play()
			wait(1.5)
			soundScream:Play()
			if face then
				face.Texture = "rbxassetid://288918236"
			end
			wait(2.5)

			--Explode
			if plr == main.player then
				local explosion = Instance.new("Explosion")
				explosion.Position = clone.Head.Position
				explosion.Parent = clone
				clone:BreakJoints()
				main.audio.Oof:Play()
			end

			wait(5)
			--Destroy van and reset player
			if plr == main.player then
				local humanoid = main:GetModule("cf"):GetHumanoid(plr)
				if humanoid then
					main:GetModule("cf"):Movement(true)
					main:GetModule("cf"):SetCameraSubject(humanoid)
				end
				plr.CameraMaxZoomDistance = 20
				wait()
				plr.CameraMinZoomDistance = 20
				wait()
				plr.CameraMinZoomDistance = originalMinZoom
				plr.CameraMaxZoomDistance = originalMaxZoom
			end
			main:GetModule("cf"):SetTransparency(plr.Character, 0)
			if plr.Character then
				plr.Character.Parent = workspace
			end
			van:Destroy()

		end;
		};

	----------------------------------------------------------------------
	["laserEyes"] = {
		DisplayLaser = function(laserHead, laserTarget, status)
			local leftBeam = laserTarget:FindFirstChild("LeftBeam")
			if leftBeam then
				leftBeam.Enabled = status
				laserTarget.RightBeam.Enabled = status
				laserTarget.MidAttachment.GlowHit.Enabled = status
			end
		end;

		Activate = function(self)
			local commandName = self.Name
			local head = main:GetModule("cf"):GetHead()
			local humanoid = main:GetModule("cf"):GetHumanoid()
			local hrp = main:GetModule("cf"):GetHRP()
			if head and humanoid and main.mouseDown then
				local laserHead = head:FindFirstChild("HDAdminLaserHead")
				local neck = main:GetModule("cf"):GetNeck()
				local r6 = false
				if humanoid.RigType == Enum.HumanoidRigType.R6 then
					r6 = true
				end
				head.Parent.PrimaryPart = hrp
				if laserHead and neck then

					local maxDistance = 30
					local lastUpdate = tick()-1
					local originalC0 = neck.C0
					local additionalY =  humanoid.HipHeight/2.5
					local laserTarget = laserHead.LaserTarget
					local fire = laserTarget.MidAttachment2.Fire
					local sparks = laserTarget.MidAttachment.Sparks
					local sizzle = main.audio.Sizzle
					local sizzle2 = main.audio.Sizzle2
					sizzle:Play()
					self.DisplayLaser(laserHead, laserTarget, true)

					repeat
						local hit, position = main:GetModule("cf"):GetMousePoint(main.lastHitPosition)
						local targetCFrame = CFrame.new(position, head.Position)
						local distanceFromPlayer = main.player:DistanceFromCharacter(targetCFrame.p)
						local exceededMaxDistance = false
						if distanceFromPlayer > maxDistance then
							targetCFrame = targetCFrame * CFrame.new(0, 0, maxDistance-distanceFromPlayer)
							exceededMaxDistance = true
						end
						laserTarget.CFrame = targetCFrame
						local headPos = head.Position
						local targetPos = laserTarget.Position
						local direction = (Vector3.new(targetPos.X, headPos.Y, targetPos.Z) - head.Position).Unit
						if head.Parent.PrimaryPart == nil then
							head.Parent.PrimaryPart = head.parent.HumanoidRootPart
						end
						local lookCFrame = (CFrame.new(Vector3.new(), (head.Parent.PrimaryPart.CFrame):VectorToObjectSpace(direction)))
						if r6 then
							lookCFrame = lookCFrame * CFrame.new(0,1,0) * CFrame.fromEulerAnglesXYZ(math.rad(90),math.rad(180),0)
						else
							lookCFrame = lookCFrame * CFrame.new(0,additionalY,0)
						end
						neck.C0 = lookCFrame
						if tick() - 0.6 > lastUpdate then
							lastUpdate = tick()
							main:GetModule("cf"):ReplicateEffect(self.Name, {targetCFrame, lookCFrame})
						end
						if hit and not exceededMaxDistance and (hit.Parent:FindFirstChild("Humanoid") or hit.Name == "Handle") then
							fire.Enabled = true
							sparks.Enabled = true
							if not sizzle2.Playing then
								sizzle2:Play()
							end
						else
							fire.Enabled = false
							sparks.Enabled = false
							if sizzle2.Playing then
								sizzle2:Stop()
							end
						end
						wait()

					until not main.mouseDown or not main.commandsActive[commandName] or not head or not head.Parent or not neck
					neck.C0 = originalC0
					self.DisplayLaser(laserHead, laserTarget, false)
					fire.Enabled = false
					sparks.Enabled = false
					sizzle:Stop()
					sizzle2:Stop()
				end
			end
			main.commandsActive[commandName] = nil
		end;

		ReplicationEffect = function(speaker, args, self)
			local targetCFrame, lookCFrame = args[1], args[2]
			local plr = speaker
			local head = main:GetModule("cf"):GetHead(plr)
			if head then
				local laserHead = head:FindFirstChild("HDAdminLaserHead")
				local neck = main:GetModule("cf"):GetNeck(plr)
				if laserHead and neck then
					local laserTarget = laserHead.LaserTarget
					--Laser is already active
					if lasersActive[plr] then
						lasersActive[plr] = lasersActive[plr] + 1
					else -- New laser
						lasersActive[plr] = 1
						originalNecks[plr] = neck.C0
						local randomZ = math.random(10,40) - 15
						laserTarget.CFrame = targetCFrame * CFrame.new(0, 0, randomZ)
						neck.C0 = lookCFrame
						laserTarget.MidAttachment.GlowHit.Rate = 50
						self.DisplayLaser(laserHead, laserTarget, true)
					end
					main.tweenService:Create(laserTarget, laserTweenInfo, {CFrame = targetCFrame}):Play()
					main.tweenService:Create(neck, laserTweenInfo, {C0 = lookCFrame}):Play()
					wait(laserTweenTime)
					lasersActive[plr] = lasersActive[plr] - 1
					if lasersActive[plr] <= 0 then
						self.DisplayLaser(laserHead, laserTarget, false)
						neck.C0 = originalNecks[plr]
						originalNecks[plr] = nil
						lasersActive[plr] = nil
					end
				end
			end
		end;
		};

	----------------------------------------------------------------------
	["warp"] = {
		Function = function(speaker, args)
			local maxDistort = 1
			local increment = 0.005
			local distort = maxDistort-increment
			local distortDirection = -increment
			repeat main.runService.RenderStepped:Wait()
				if distort < increment then
					distort = increment
					distortDirection = increment
				elseif distort > maxDistort then
					distort = maxDistort
					distortDirection = -increment
				end
				main.camera.CFrame = main.camera.CFrame*CFrame.new(0,0,0,distort,0,0,0,distort,0,0,0,1)
				distort = distort + distortDirection
			until distort > maxDistort
		end;
		};

	----------------------------------------------------------------------
	["fly"] = {
		Activate = function(self)
			main:GetModule("FlyCommand"):Fly(self.Name)
		end;
		};

	----------------------------------------------------------------------
	["fly2"] = {
		Activate = function(self)
			main:GetModule("FlyCommand"):Fly(self.Name)
		end;
		};

	----------------------------------------------------------------------
	["noclip"] = {
		Activate = function(self)
			local commandName = self.Name
			local humanoid = main:GetModule("cf"):GetHumanoid()
			local hrp = main:GetModule("cf"):GetHRP()
			if humanoid and hrp then
				local lastUpdate = tick()
				hrp.Anchored = true
				humanoid.PlatformStand = true
				repeat wait()
					local delta = tick()-lastUpdate
					local look = (main.camera.Focus.p-main.camera.CFrame.p).unit
					local move = main:GetModule("cf"):GetNextMovement(delta, main.commandSpeeds[commandName])
					local pos = hrp.Position
					hrp.CFrame = CFrame.new(pos,pos+look) * move
					lastUpdate = tick()

				until not main.commandsActive[commandName]
				if hrp and humanoid then
					hrp.Anchored = false
					hrp.Velocity = Vector3.new()
					humanoid.PlatformStand = false
				end
			end
		end;
		};

	----------------------------------------------------------------------
	["noclip2"] = {
		Activate = function(self)
			main:GetModule("FlyCommand"):Fly(self.Name, true)
		end;
		};

	----------------------------------------------------------------------
	["clip"] = {
		Function = function(speaker, args, self)
			main:GetModule("cf"):DeactivateCommand("noclip")
		end;
		};

	----------------------------------------------------------------------
	["boing"] = {
		ExpandTime = 4;
		ExpandAmount = 3;
		EndBoing = {};
		Function = function(speaker, args, self)
			local plr = args[1]
			local head = main:GetModule("cf"):GetHead(plr)
			local humanoid = main:GetModule("cf"):GetHumanoid(plr)
			if head and humanoid and not self.UnFunction(speaker, args, self) then
				local headMesh = head:FindFirstChild("Mesh")
				if headMesh then
					local hats = {}
					local character = plr.Character
					for a,b in pairs(character:GetChildren()) do
						if b:IsA("Accessory") then
							table.insert(hats, b)
							b.Parent = nil
						end
					end
					local originalScale = headMesh.Scale
					local tween = main.tweenService:Create(headMesh, TweenInfo.new(self.ExpandTime, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out), {Scale = Vector3.new(originalScale.X, originalScale.Y * self.ExpandAmount, originalScale.Z)})
					tween:Play()
					--
					local endEvent = Instance.new("BindableEvent")
					self.EndBoing[plr] = endEvent
					main:GetModule("cf"):WaitForEvent(endEvent, humanoid.Died, plr.CharacterAdded)
					self.EndBoing[plr] = nil
					endEvent:Destroy()
					--
					if headMesh then
						local tween = main.tweenService:Create(headMesh, TweenInfo.new(2, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out), {Scale = originalScale})
						tween:Play()
						tween.Completed:Wait()
					end
					for i,v in pairs(hats) do
						if character then
							v.Parent = character
						else
							v:Destroy()
						end
					end
				end
			end
		end;
		UnFunction = function(speaker, args, self)
			local plr = args[1]
			local endEvent = self.EndBoing[plr]
			if endEvent then
				endEvent:Fire()
				return true
			end
		end;
		};

	----------------------------------------------------------------------

};


Response:
function findAllFlagStands(root)
	local c = root:children()
	for i=1,#c do
		if (c[i].className == "Model" or c[i].className == "Part") then
			findAllFlagStands(c[i])
		end
		if (c[i].className == "FlagStand") then
			table.insert(stands, c[i])
		end
	end
end

function hookUpListeners()
	for i=1,#stands do
		stands[i].FlagCaptured:connect(onCaptureScored)
	end
end

function onPlayerEntered(newPlayer)

	if Fight_mode == true then

		local stats = Instance.new("IntValue")
		stats.Name = "leaderstats"

		local captures = Instance.new("IntValue")
		captures.Name = "Captures"
		captures.Value = 0

		captures.Parent = stats

		-- VERY UGLY HACK
		-- Will this leak threads?
		-- Is the problem even what I think it is (player arrived before character)?
		while true do
			if newPlayer.Character ~= nil then break end
			wait(5)
		end

		stats.Parent = newPlayer

	else

		local stats = Instance.new("IntValue")
		stats.Name = "leaderstats"

		local kills = Instance.new("IntValue")
		kills.Name = "KOs"
		kills.Value = 0

		local deaths = Instance.new("IntValue")
		deaths.Name = "Wipeouts"
		deaths.Value = 0

		kills.Parent = stats
		deaths.Parent = stats

		-- VERY UGLY HACK
		-- Will this leak threads?
		-- Is the problem even what I think it is (player arrived before character)?
		while true do
			if newPlayer.Character ~= nil then break end
			wait(5)
		end

		local humanoid = newPlayer.Character.Humanoid

		humanoid.Died:connect(function() onHumanoidDied(humanoid, newPlayer) end )

		-- start to listen for new humanoid
		newPlayer.Changed:connect(function(property) onPlayerRespawn(property, newPlayer) end )

		stats.Parent = newPlayer

	end

end

function onCaptureScored(player)

		local ls = player:findFirstChild("leaderstats")
		if ls == nil then return end
		local caps = ls:findFirstChild("Captures")
		if caps == nil then return end
		caps.Value = caps.Value + 1

end

findAllFlagStands(game.Workspace)
hookUpListeners()
if (#stands > 0) then CTF_mode = false end
game.Players.ChildAdded:connect(onPlayerEntered)


Prompt:
--if tool then
--	local handle = tool:FindFirstChild("Handle")
--	local toolCopy = tool:Clone()
--	toolCopy.Parent = game.ServerStorage
--	local toolOnPad = true
--
--	local parentConnection
--	parentConnection = tool.AncestryChanged:connect(function()
--		if handle then handle.Anchored = false end
--		toolOnPad = false
--		parentConnection:disconnect()
--	end)
--
--	if handle then
--		handle.CFrame = (spawner.CFrame + Vector3.new(0,handle.Size.Z/2 + 1,0)) * CFrame.Angles(-math.pi/2,0,0)
--		handle.Anchored = true
--	end
--
--	while true do
--		while toolOnPad do
--			if handle then
--				handle.CFrame = handle.CFrame * CFrame.Angles(0,0,math.pi/60)
--			end
--			wait()
--		end
--		wait(configs["SpawnCooldown"])
--		local newTool = toolCopy:Clone()
--		newTool.Parent = game.Workspace
--		handle = newTool:FindFirstChild("Handle")
--		toolOnPad = true
--	end
--end


Prompt: -- VALUES --

Response:
local Equipped = script:WaitForChild("Equipped")
local Holding = script:WaitForChild("Holding")
local Using = script:WaitForChild("Using")
local isHolding = false
local isBlocking = Player:WaitForChild("isBlocking")

local vCurrentProjectile = 0


Prompt:
--[[
HOW TO USE:
1. Open Roblox Studio
2. Put the GUI in StarterGui
3. Enable third party sales under Game Settings -> Security
4. Publish/Save your game to Roblox from the file menu
5. Input item ID while in-game to buy the item
--]]


Prompt: --[[ Constants ]]

Response:
--
local ZERO_VECTOR3 = Vector3.new(0,0,0)
local NONE = Enum.UserInputType.None
local thumbstickDeadzone = 0.2


Prompt:
--[=[
	Adds a removing callback to the manager.
	@param callback function -- May return a promise
	@return Promise
]=]

Response:
function PlayerDataStoreService:PromiseAddRemovingCallback(callback)
	return self:PromiseManager()
		:Then(function(manager)
			manager:AddRemovingCallback(callback)
		end)
end


Prompt: --[[Wheel Alignment]]

Response:
	--[Don't physically apply alignment to wheels]
	--[Values are in degrees]
	Tune.FCamber		= -5
	Tune.RCamber		= -5
	Tune.FToe			= 0
	Tune.RToe			= 0


Prompt: --[[ Modules ]]

Response:
--
local ClickToMoveTouchControls = nil
local ControlModules = {}

local MasterControl = require(script:WaitForChild('MasterControl'))

local keyboardModule = require(script.MasterControl:WaitForChild('KeyboardMovement'))

function getTouchModule()
	local module = nil
	if not IsUserChoice then
		if DevMovementMode == Enum.DevTouchMovementMode.Scriptable then
			module = nil
		end
	else
		if UserMovementMode == Enum.TouchMovementMode.ClickToMove then
			-- Managed by CameraScript
			module = nil
		end
	end

	return module
end

function setJumpModule(isEnabled)

end

function setClickToMove()
	if DevMovementMode == Enum.DevTouchMovementMode.ClickToMove or DevMovementMode == Enum.DevComputerMovementMode.ClickToMove or
		UserMovementMode == Enum.ComputerMovementMode.ClickToMove or UserMovementMode == Enum.TouchMovementMode.ClickToMove then
		--
		if lastInputType == Enum.UserInputType.Touch then
			ClickToMoveTouchControls = ControlState.Current
		end
	elseif ClickToMoveTouchControls then
		ClickToMoveTouchControls:Disable()
		ClickToMoveTouchControls = nil
	end
end

ControlModules.Touch = {}
ControlModules.Touch.Current = nil
ControlModules.Touch.LocalPlayerChangedCon = nil
ControlModules.Touch.GameSettingsChangedCon = nil

function ControlModules.Touch:RefreshControlStyle()
	ControlModules.Touch.Current:Disable()
	setJumpModule(false)
	ControlModules.Touch:Enable()
end
function ControlModules.Touch:DisconnectEvents()
	if ControlModules.Touch.LocalPlayerChangedCon then
		ControlModules.Touch.LocalPlayerChangedCon:disconnect()
		ControlModules.Touch.LocalPlayerChangedCon = nil
	end
	if ControlModules.Touch.GameSettingsChangedCon then
		ControlModules.Touch.GameSettingsChangedCon:disconnect()
		ControlModules.Touch.GameSettingsChangedCon = nil
	end
end
function ControlModules.Touch:Enable()
	DevMovementMode = LocalPlayer.DevTouchMovementMode
	IsUserChoice = DevMovementMode == Enum.DevTouchMovementMode.UserChoice
	if IsUserChoice then
		UserMovementMode = GameSettings.TouchMovementMode
	end

	local newModuleToEnable = getTouchModule()
	if newModuleToEnable then
		setClickToMove()
		setJumpModule(isJumpEnabled)

		newModuleToEnable:Enable()
		ControlModules.Touch.Current = newModuleToEnable

		ControlModules.Touch:DisconnectEvents()
		ControlModules.Touch.LocalPlayerChangedCon = LocalPlayer.Changed:connect(function(property)
			if property == 'DevTouchMovementMode' then
				ControlModules.Touch:RefreshControlStyle()
			end
		end)

		ControlModules.Touch.GameSettingsChangedCon = GameSettings.Changed:connect(function(property)
			if property == 'TouchMovementMode' then
				ControlModules.Touch:RefreshControlStyle()
			end
		end)

	end
end
function ControlModules.Touch:Disable()
	ControlModules.Touch:DisconnectEvents()

	local newModuleToDisable = getTouchModule()

end

local function getKeyboardModule()
	-- NOTE: Click to move still uses keyboard. Leaving cases in case this ever changes.
	local whichModule = nil
	if not IsUserChoice then
		if DevMovementMode == Enum.DevComputerMovementMode.KeyboardMouse then
			whichModule = keyboardModule
		elseif DevMovementMode == Enum.DevComputerMovementMode.ClickToMove then
			-- Managed by CameraScript
			whichModule = keyboardModule
		end
	else
		if UserMovementMode == Enum.ComputerMovementMode.KeyboardMouse or UserMovementMode == Enum.ComputerMovementMode.Default then
			whichModule = keyboardModule
		elseif UserMovementMode == Enum.ComputerMovementMode.ClickToMove then
			-- Managed by CameraScript
			whichModule = keyboardModule
		end
	end

	return whichModule
end

ControlModules.Keyboard = {}
function ControlModules.Keyboard:Enable()
	DevMovementMode = LocalPlayer.DevComputerMovementMode
	IsUserChoice = DevMovementMode == Enum.DevComputerMovementMode.UserChoice
	if IsUserChoice then
		UserMovementMode = GameSettings.ComputerMovementMode
	end

	local newModuleToEnable = getKeyboardModule()
	if newModuleToEnable then
		if newModuleToEnable then
			newModuleToEnable:Enable()
		end
	end
end
function ControlModules.Keyboard:Disable()
	local newModuleToDisable = getKeyboardModule()
	if newModuleToDisable then
		newModuleToDisable:Disable()
	end
end

if IsTouchDevice then
	BindableEvent_OnFailStateChanged = script.Parent:WaitForChild('OnClickToMoveFailStateChange')
end


Prompt: --Made by Luckymaxer

Response:
Tool = script.Parent
Handle = Tool:WaitForChild("Handle")

Players = game:GetService("Players")

ServerControl = Tool:WaitForChild("ServerControl")

function InvokeServer(Mode, Value)
	pcall(function()
		ServerControl:InvokeServer(Mode, Value)
	end)
end

function Equipped(Mouse)
	Character = Tool.Parent
	Player = Players:GetPlayerFromCharacter(Character)
	Humanoid = Character:FindFirstChild("Humanoid")
	if not Player or not Humanoid or Humanoid.Health == 0 then
		return
	end
	Mouse.Button1Down:connect(function()
		InvokeServer("Click", {Down = true, Position = Mouse.Hit.p})
	end)
	Mouse.KeyDown:connect(function(Key)
		InvokeServer("KeyPress", {Key = Key, Down = true})
	end)
end

function Unequipped()
end

Tool.Equipped:connect(Equipped)
Tool.Unequipped:connect(Unequipped)


Response:
Monster:Initialize()
Monster:InitializeUnique()

while true do
	if not Monster:IsAlive() then
		if Data.IsDead == false then
			Data.IsDead = true
			Data.TimeOfDeath = tick()
			Self.Died:Fire()
		end
		if Data.IsDead == true then
			if tick()-Data.TimeOfDeath > Info.RespawnWaitTime then
				Monster:Respawn()
			end
		end
	end

	if Monster:IsAlive() then
		Monster:Update()
	end

	wait()
end


Prompt: --Drag

Response:
main.userInputService.InputChanged:Connect(function(input, pressedUI)
	if (input.UserInputType == dragInput or input.UserInputType == touchInput) and (not pressedUI or frameDragging) then
		if main.mouseDown then
			local distanceBetweenLastPos = (main.lastHitPosition - input.Position).magnitude
			if distanceBetweenLastPos < 150 or main.device ~= "Mobile" then --Prevent weird behavior with multiple touch inputs
				if frameDragging then
					dragFrame(input, frameDragging)
				end
				checkPressFunctions(input.Position)
			end
		end
	end
end)


Prompt:
--To make the button work, group this with anything you want to be regened. this works with all models,
--You just have to group it with them. anything, bricks, anything.

Response:
model = script.Parent.Parent

backup = model:clone()
enabled = true

function regenerate()
	model:remove()

	wait(0.3) --how many seconds it takes to regen

	model = backup:clone()
	model.Parent = game.Workspace
	model:makeJoints()

	script.Disabled = true
	script.Parent.BrickColor = BrickColor.new(26) --basically black... (it go's black when you regen it
	wait(0.3) --how much sec it takes to regen
	script.Parent.BrickColor = BrickColor.new(104) --purple (just a purple brick (exept it regen)
	script.Disabled = false
end

function onHit(hit)
	if (hit.Parent:FindFirstChild("Humanoid") ~= nil) and enabled then --if a humanoid touches it then...
		regenerate()
	end
end

script.Parent.Touched:connect(onHit)


Prompt: --vec should be a unit vector, and 0 < rayLength <= 1000

Response:
function RayCast(startPos, vec, rayLength)
	local hitObject, hitPos = game.Workspace:FindPartOnRay(Ray.new(startPos + (vec * .01), vec * rayLength), Handle)
	if hitObject and hitPos then
		local distance = rayLength - (hitPos - startPos).magnitude
		if RayIgnoreCheck(hitObject, hitPos) and distance > 0 then
			-- there is a chance here for potential infinite recursion
			return RayCast(hitPos, vec, distance)
		end
	end
	return hitObject, hitPos
end

function TagHumanoid(humanoid, player)
	-- Add more tags here to customize what tags are available.
	while humanoid:FindFirstChild('creator') do
		humanoid:FindFirstChild('creator'):Destroy()
	end
	local creatorTag = Instance.new("ObjectValue")
	creatorTag.Value = player
	creatorTag.Name = "creator"
	creatorTag.Parent = humanoid
	DebrisService:AddItem(creatorTag, 1.5)

	local weaponIconTag = Instance.new("StringValue")
	weaponIconTag.Value = IconURL
	weaponIconTag.Name = "icon"
	weaponIconTag.Parent = creatorTag
end

local function CreateBullet(bulletPos)
	local bullet = Instance.new('Part', Workspace)
	bullet.FormFactor = Enum.FormFactor.Custom
	bullet.Size = Vector3.new(0.1, 0.1, 0.1)
	bullet.BrickColor = BrickColor.new("Black")
	bullet.Shape = Enum.PartType.Block
	bullet.CanCollide = false
	bullet.CFrame = CFrame.new(bulletPos)
	bullet.Anchored = true
	bullet.TopSurface = Enum.SurfaceType.Smooth
	bullet.BottomSurface = Enum.SurfaceType.Smooth
	bullet.Name = 'Bullet'
	DebrisService:AddItem(bullet, 2.5)

	local shell = Instance.new("Part")
	shell.CFrame = Tool.Handle.CFrame * CFrame.fromEulerAnglesXYZ(1.5,0,0)
	shell.Size = Vector3.new(1,1,1)
	shell.BrickColor = BrickColor.new(226)
	shell.Parent = game.Workspace
	shell.CFrame = script.Parent.Handle.CFrame
	shell.CanCollide = false
	shell.Transparency = 0
	shell.BottomSurface = 0
	shell.TopSurface = 0
	shell.Name = "Shell"
	shell.Velocity = Tool.Handle.CFrame.lookVector * 35 + Vector3.new(math.random(-10,10),20,math.random(-10,20))
	shell.RotVelocity = Vector3.new(0,200,0)
	DebrisService:AddItem(shell, 1)

	local shellmesh = Instance.new("SpecialMesh")
	shellmesh.Scale = Vector3.new(.15,.4,.15)
	shellmesh.Parent = shell

	return bullet
end

local function Reload()
	if not Reloading then
		Reloading = true
		-- Don't reload if you are already full or have no extra ammo
		if AmmoInClip ~= ClipSize and SpareAmmo > 0 then
			if RecoilTrack then
				RecoilTrack:Stop()
			end
			if WeaponGui and WeaponGui:FindFirstChild('Crosshair') then
				if WeaponGui.Crosshair:FindFirstChild('ReloadingLabel') then
					WeaponGui.Crosshair.ReloadingLabel.Visible = true
				end
			end
			if ReloadTrack then
				ReloadTrack:Play()
			end
			script.Parent.Handle.Reload:Play()
			wait(ReloadTime)
			-- Only use as much ammo as you have
			local ammoToUse = math.min(ClipSize - AmmoInClip, SpareAmmo)
			AmmoInClip = AmmoInClip + ammoToUse
			SpareAmmo = SpareAmmo - ammoToUse
			UpdateAmmo(AmmoInClip)
			--WeaponGui.Reload.Visible = false
			if ReloadTrack then
				ReloadTrack:Stop()
			end
		end
		Reloading = false
	end
end

function OnFire()
	if IsShooting then return end
	if MyHumanoid and MyHumanoid.Health > 0 then
		if RecoilTrack and AmmoInClip > 0 then
			RecoilTrack:Play()
		end
		IsShooting = true
		while LeftButtonDown and AmmoInClip > 0 and not Reloading do
			if Spread and not DecreasedAimLastShot then
				Spread = math.min(MaxSpread, Spread + AimInaccuracyStepAmount)
				UpdateCrosshair(Spread)
			end
			DecreasedAimLastShot = not DecreasedAimLastShot
			if Handle:FindFirstChild('FireSound') then
				Pitch.Pitch = .8 + (math.random() * .5)
				Handle.FireSound:Play()
				Handle.Flash.Enabled = true
				flare.MuzzleFlash.Enabled = true
				--Handle.Smoke.Enabled=true --This is optional
			end
			if MyMouse then
				local targetPoint = MyMouse.Hit.p
				local shootDirection = (targetPoint - Handle.Position).unit
				-- Adjust the shoot direction randomly off by a little bit to account for recoil
				shootDirection = CFrame.Angles((0.5 - math.random()) * 2 * Spread,
																(0.5 - math.random()) * 2 * Spread,
																(0.5 - math.random()) * 2 * Spread) * shootDirection
				local hitObject, bulletPos = RayCast(Handle.Position, shootDirection, Range)
				local bullet
				-- Create a bullet here
				if hitObject then
					bullet = CreateBullet(bulletPos)
				end
				if hitObject and hitObject.Parent then
					local hitHumanoid = hitObject.Parent:FindFirstChild("Humanoid")
					if hitHumanoid then
						local hitPlayer = game.Players:GetPlayerFromCharacter(hitHumanoid.Parent)
						if MyPlayer.Neutral or (hitPlayer and hitPlayer.TeamColor ~= MyPlayer.TeamColor) then
							TagHumanoid(hitHumanoid, MyPlayer)
							hitHumanoid:TakeDamage(Damage)
							if bullet then
								bullet:Destroy()
								bullet = nil
								WeaponGui.Crosshair.Hit:Play()
								--bullet.Transparency = 1
							end
							Spawn(UpdateTargetHit)
						end
					end
				end
				AmmoInClip = AmmoInClip - 1
				UpdateAmmo(AmmoInClip)
			end
			wait(FireRate)
		end
		Handle.Flash.Enabled = false
		IsShooting = false
		flare.MuzzleFlash.Enabled = false
		--Handle.Smoke.Enabled=false --This is optional
		if AmmoInClip == 0 then
			Handle.Tick:Play()
			--WeaponGui.Reload.Visible = true
			Reload()
		end
		if RecoilTrack then
			RecoilTrack:Stop()
		end
	end
end

local TargetHits = 0
function UpdateTargetHit()
	TargetHits = TargetHits + 1
	if WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
		WeaponGui.Crosshair.TargetHitImage.Visible = true
	end
	wait(0.5)
	TargetHits = TargetHits - 1
	if TargetHits == 0 and WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
		WeaponGui.Crosshair.TargetHitImage.Visible = false
	end
end

function UpdateCrosshair(value, mouse)
	if WeaponGui then
		local absoluteY = 650
		WeaponGui.Crosshair:TweenSize(
			UDim2.new(0, value * absoluteY * 2 + 23, 0, value * absoluteY * 2 + 23),
			Enum.EasingDirection.Out,
			Enum.EasingStyle.Linear,
			0.33)
	end
end

function UpdateAmmo(value)
	if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('ClipAmmo') then
		WeaponGui.AmmoHud.ClipAmmo.Text = AmmoInClip
		if value > 0 and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('ReloadingLabel') then
			WeaponGui.Crosshair.ReloadingLabel.Visible = false
		end
	end
	if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('TotalAmmo') then
		WeaponGui.AmmoHud.TotalAmmo.Text = SpareAmmo
	end
end

function OnMouseDown()
	LeftButtonDown = true
	OnFire()
end

function OnMouseUp()
	LeftButtonDown = false
end

function OnKeyDown(key)
	if string.lower(key) == 'r' then
		Reload()
		if RecoilTrack then
			RecoilTrack:Stop()
		end
	end
end

function OnEquipped(mouse)
	Handle.EquipSound:Play()
	Handle.EquipSound2:Play()
	Handle.UnequipSound:Stop()
	RecoilAnim = WaitForChild(Tool, 'Recoil')
	ReloadAnim = WaitForChild(Tool, 'Reload')
	FireSound  = WaitForChild(Handle, 'FireSound')

	MyCharacter = Tool.Parent
	MyPlayer = game:GetService('Players'):GetPlayerFromCharacter(MyCharacter)
	MyHumanoid = MyCharacter:FindFirstChild('Humanoid')
	MyTorso = MyCharacter:FindFirstChild('Torso')
	MyMouse = mouse
	Tip = WaitForChild(Tool, 'DonateGui'):Clone()
	if Tip and MyPlayer then
		Tip.Parent = MyPlayer.PlayerGui
		end
	WeaponGui = WaitForChild(Tool, 'WeaponHud'):Clone()
	if WeaponGui and MyPlayer then
		WeaponGui.Parent = MyPlayer.PlayerGui
		UpdateAmmo(AmmoInClip)
	end

	if RecoilAnim then
		RecoilTrack = MyHumanoid:LoadAnimation(RecoilAnim)
	end

	if ReloadAnim then
		ReloadTrack = MyHumanoid:LoadAnimation(ReloadAnim)
	end

	if MyMouse then
		-- Disable mouse icon
		MyMouse.Icon = "http://www.roblox.com/asset/?id=18662154"
		MyMouse.Button1Down:connect(OnMouseDown)
		MyMouse.Button1Up:connect(OnMouseUp)
		MyMouse.KeyDown:connect(OnKeyDown)
	end
end


Prompt: --[[Steering]]

Response:
Tune.SteerInner		= 36		-- Inner wheel steering angle (in degrees)
Tune.SteerOuter		= 37		-- Outer wheel steering angle (in degrees)
Tune.SteerSpeed		= .03		-- Steering increment per tick (in degrees)
Tune.ReturnSpeed	= .1		-- Steering increment per tick (in degrees)
Tune.SteerDecay		= 320		-- Speed of gradient cutoff (in SPS)
Tune.MinSteer		= 10		-- Minimum steering at max steer decay (in percent)
Tune.MSteerExp		= 1			-- Mouse steering exponential degree


Prompt:
--[[
	Creates a function that invokes a callback with correct error handling and
	resolution mechanisms.
]]

Response:
local function createAdvancer(traceback, callback, resolve, reject)
	return function(...)
		local ok, resultLength, result = runExecutor(traceback, callback, ...)

		if ok then
			resolve(unpack(result, 1, resultLength))
		else
			reject(result[1])
		end
	end
end

local function isEmpty(t)
	return next(t) == nil
end

local Promise = {
	Error = Error,
	Status = makeEnum("Promise.Status", {"Started", "Resolved", "Rejected", "Cancelled"}),
	_getTime = os.clock,
	_timeEvent = game:GetService("RunService").Heartbeat,
}
Promise.prototype = {}
Promise.__index = Promise.prototype


Prompt:
-- Helper function to recursively set the collision group on an object and all of
-- its children

Response:
local function setCollisionGroupRecursive(object, group)
	if object:IsA("BasePart") then
		PhysicsService:SetPartCollisionGroup(object, group)
	end
	for _, child in ipairs(object:GetChildren()) do
		setCollisionGroupRecursive(child, group)
	end
end


Prompt: --bool variables

Response:
local LoadedTables = false
local CanSwing = false
local CanDamage = false


Prompt:
--[[
	 Builds a map that allows us to find Attachment0/Attachment1 when we have the other,
		and keep track of the joint that connects them. Format is
		{
			["WaistRigAttachment"] = {
				Joint = UpperTorso.Waist<Motor6D>,
				Attachment0 = LowerTorso.WaistRigAttachment<Attachment>,
				Attachment1 = UpperToros.WaistRigAttachment<Attachment>,
			},
			...
		}
--]]

Response:
function buildAttachmentMap(character)
	local attachmentMap = {}

	-- NOTE: GetConnectedParts doesn't work until parts have been parented to Workspace, so
	-- we can't use it (unless we want to have that silly restriction for creating ragdolls)
	for _,part in pairs(character:GetChildren()) do
		if part:IsA("BasePart") then
			for _,attachment in pairs(part:GetChildren()) do
				if attachment:IsA("Attachment") then
					local jointName = attachment.Name:match("^(.+)RigAttachment$")
					local joint = jointName and attachment.Parent:FindFirstChild(jointName) or nil

					if joint then
						attachmentMap[attachment.Name] = {
							Joint = joint,
							Attachment0=joint.Part0[attachment.Name];
							Attachment1=joint.Part1[attachment.Name];
						}
					end
				end
			end
		end
	end

	return attachmentMap
end

return function(humanoid)
	local character = humanoid.Parent

	-- Trying to recover from broken joints is not fun. It's impossible to reattach things like
	-- armor and tools in a generic way that works across all games, so we just prevent that
	-- from happening in the first place.
	humanoid.BreakJointsOnDeath = false

	-- Roblox decided to make the ghost HumanoidRootPart CanCollide=true for some reason, so
	-- we correct this and disable collisions. This prevents the invisible part from colliding
	-- with the world and ruining the physics simulation (e.g preventing a roundish torso from
	-- rolling)
	local rootPart = character:FindFirstChild("HumanoidRootPart")
	if rootPart then
		rootPart.CanCollide = false
	end

	local attachmentMap = buildAttachmentMap(character)
	local ragdollConstraints = buildConstraints(attachmentMap)
	local collisionFilters = buildCollisionFilters(attachmentMap, character.PrimaryPart)

	collisionFilters.Parent = ragdollConstraints
	ragdollConstraints.Parent = character

	game:GetService("CollectionService"):AddTag(humanoid, "Ragdoll")
end


Prompt: -- Colors

Response:
local FriendlyReticleColor = Color3.new(0, 1, 0)
local EnemyReticleColor	= Color3.new(1, 0, 0)
local NeutralReticleColor	= Color3.new(1, 1, 1)

local Spread = MinSpread
local AmmoInClip = ClipSize

local Tool = script.Parent
local Handle = WaitForChild(Tool, 'Handle')
local WeaponGui = nil

local LeftButtonDown
local Reloading = false
local IsShooting = false
local Pitch = script.Parent.Handle.FireSound


Prompt: --[[Weight and CG]]

Response:
	Tune.Weight			= 6000		-- Total weight (in pounds)
	Tune.WeightBSize	= {			-- Size of weight brick (dimmensions in studs ; larger = more stable)
	 --[[Width]]		6		,
	 --[[Height]]		3.5		,
	 --[[Length]]		14		}
	Tune.WeightDist		= 50		-- Weight distribution (0 - on rear wheels, 100 - on front wheels, can be <0 or >100)
	Tune.CGHeight		= .8		-- Center of gravity height (studs relative to median of all wheels)
	Tune.WBVisible		= false		-- Makes the weight brick visible

	--Unsprung Weight
	Tune.FWheelDensity	= .1		-- Front Wheel Density
	Tune.RWheelDensity	= .1		-- Rear Wheel Density
	Tune.FWLgcyDensity	= 1			-- Front Wheel Density [PGS OFF]
	Tune.RWLgcyDensity	= 1			-- Rear Wheel Density [PGS OFF]

	Tune.AxleSize		= 2			-- Size of structural members (larger = more stable/carry more weight)
	Tune.AxleDensity	= .1		-- Density of structural members


Prompt:
--[[
	Creates pickup model prefabs for each plant type at runtime. These models are used
	while a player is holding a plant.

	Can be used by other scripts to get any pickup prefab by plant id.
--]]

Response:
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local getInstance = require(ReplicatedStorage.Source.Utility.getInstance)
local createHarvestedPlantModel = require(ServerStorage.Source.Farm.createHarvestedPlantModel)

local plantsFolder: Folder = getInstance(ReplicatedStorage, "Instances", "Plants")

local PickupPrefabsById = {}


Prompt:
--[=[
	Repeatedly calls a Promise-returning function up to `times` number of times, waiting `seconds` seconds between each
	retry, until the returned Promise resolves.

	If the amount of retries is exceeded, the function will return the latest rejected Promise.

	@since v3.2.0
	@param callback (...: P) -> Promise<T>
	@param times number
	@param seconds number
	@param ...? P
	@return Promise<T>
]=]

Response:
function Promise.retryWithDelay(callback, times, seconds, ...)
	assert(isCallable(callback), "Parameter #1 to Promise.retry must be a function")
	assert(type(times) == "number", "Parameter #2 (times) to Promise.retry must be a number")
	assert(type(seconds) == "number", "Parameter #3 (seconds) to Promise.retry must be a number")

	local args, length = { ... }, select("#", ...)

	return Promise.resolve(callback(...)):catch(function(...)
		if times > 0 then
			Promise.delay(seconds):await()

			return Promise.retryWithDelay(callback, times - 1, seconds, unpack(args, 1, length))
		else
			return Promise.reject(...)
		end
	end)
end


Prompt: --- Trims whitespace from both sides of a string.

Response:
function Util.TrimString(str)
	local _, from = string.find(str, "^%s*")
	-- trim the string in two steps to prevent quadratic backtracking when no "%S" match is found
	return from == #str and "" or string.match(str, ".*%S", from + 1)
end


Prompt: --- Variable definitions

Response:
local CollectionService: CollectionService = game:GetService("CollectionService")
local VisualizerCache = require(script.Parent.VisualizerCache)

local ActiveHitboxes: {[number]: any} = {}
local Solvers: Instance = script.Parent:WaitForChild("Solvers")

local Hitbox = {}
Hitbox.__index = Hitbox
Hitbox.__type = "RaycastHitbox"

Hitbox.CastModes = {
	LinkAttachments = 1,
	Attachment = 2,
	Vector3 = 3,
	Bone = 4,
}


Prompt: -- Updates the GUI whenever the player starts to give them the most up to date status.

Response:
updateTimer()

timer.Changed:Connect(updateTimer)


Prompt:
-- Provides a generic log object that functions can use to output a variety of messages in one go.
--
-- ForbiddenJ

Response:
LogMessage = game.ServerScriptService.ServerConsole.LogMessage

local mod = {}

function mod.new()
	local self = {}

	self.Log = {}
	self.IsErrorFree = true

	self.LogInfo = mod.LogInfo
	self.LogMessage = mod.LogMessage
	self.LogOutput = mod.LogOutput
	self.LogWarning = mod.LogWarning
	self.LogError = mod.LogError
	self.BulkLog = mod.BulkLog
	self.SendToServerLog = mod.SendToServerLog

	return self
end

function mod:LogMessage(message, messageType)
	assert(typeof(message) == "string")
	assert(typeof(messageType) == "EnumItem" and messageType.EnumType == Enum.MessageType)

	if messageType == Enum.MessageType.MessageError then
		self.IsErrorFree = false
	end

	table.insert(self.Log, {message = message, messageType = messageType})
end
function mod:LogInfo(message)
	return self:LogMessage(message, Enum.MessageType.MessageInfo)
end
function mod:LogOutput(message)
	return self:LogMessage(message, Enum.MessageType.MessageOutput)
end
function mod:LogWarning(message)
	return self:LogMessage(message, Enum.MessageType.MessageWarning)
end
function mod:LogError(message)
	return self:LogMessage(message, Enum.MessageType.MessageError)
end
function mod:BulkLog(messageEntries)
	for i, entry in ipairs(messageEntries) do
		self:LogMessage(entry.message, entry.messageType)
	end
end
function mod:SendToServerLog()
	for i, entry in ipairs(self.Log) do
		LogMessage:Invoke(entry.message, entry.messageType)
	end
end

return mod


Prompt: --["Walk"] = "rbxassetid://1136173829",

Response:
["Walk"] = "http://www.roblox.com/asset/?id=507767714",
["Idle"] = "http://www.roblox.com/asset/?id=507766666",
["SwingTool"] = "rbxassetid://1262318281"
}
local anims = {}
for animName,animId in next,preAnims do
local anim = Instance.new("Animation")
anim.AnimationId = animId
game:GetService("ContentProvider"):PreloadAsync({anim})
anims[animName] = animController:LoadAnimation(anim)
end

local fallConstant = -2
run.Heartbeat:connect(function()
	local part,pos,norm,mat = workspace:FindPartOnRay(Ray.new(root.Position,Vector3.new(0,-10,0)),char)
	if target.Value then
	local facingCFrame = CFrame.new(Vector3.new(root.CFrame.X,pos.Y+10,root.CFrame.Z),CFrame.new(target.Value.CFrame.X,pos.Y+10,target.Value.CFrame.Z).p)
	bg.CFrame = facingCFrame
	else
	--bg.CFrame = CFrame.new(root.CFrame.X,pos.Y+3,root.CFrame.Z)
	end
	if target.Value then
		bv.P = 100000
		bv.Velocity = root.CFrame.lookVector*10
		if not part then
			bv.Velocity = bv.Velocity+Vector3.new(0,fallConstant,0)
			fallConstant = fallConstant-1
		else
			fallConstant = -2
		end
		if not anims["Walk"].IsPlaying then
		anims["Walk"]:Play()
		end
	else
		bv.P = 0
		bv.Velocity = Vector3.new(0,0,0)
		anims["Walk"]:Stop()
anims["Idle"]:Play()
	end
end)

while true do
	local thresh,nearest = 60,nil
	for _,player in next,game.Players:GetPlayers() do
		if player.Character and player.Character.PrimaryPart then
			local dist = (player.Character.PrimaryPart.Position-root.Position).magnitude
			if dist < thresh then
				thresh = dist
				nearest = player.Character.PrimaryPart
			end
		end
	end
	if nearest then
if thresh < 10 then
anims["SwingTool"]:Play()
nearest.Parent.Humanoid:TakeDamage(24)
target.Value = nil
wait(1)
end
		target.Value = nearest
	else
		target.Value = nil
	end
wait(1)
end


Prompt: -- Клонируем образец в ОЗУ

Response:
local sample = script.StatSample
local orig = sample:Clone()
orig.Leaderboard.SurfaceGui.scrLeader.Disabled=true -- оригинал


Prompt: --Variables--

Response:
local Enabled = true
local ButtonDown = false
local Key = nil

local Usable = false

tool.Equipped:Connect(function()
	Usable = true
end)

tool.Unequipped:Connect(function()
	Usable = false
end)


Prompt: ----- Script: -----

Response:
Button.Activated:Connect(function()

	----- Script: -----

	InformationData.Case.Value = CaseData.Case.Value
	InformationData.PriceGems.Value = CaseData.PriceGems.Value
	InformationData.PricePoints.Value = CaseData.PricePoints.Value
	InformationVariables.CommunPorcentage.Text = CaseData.CommunPorcentage.Value
	InformationVariables.UncommunPorcentage .Text = CaseData.UncommunPorcentage.Value
	InformationVariables.RarePorcentage.Text = CaseData.RarePorcentage.Value
	InformationVariables.LegendaryPorcentage.Text = CaseData.LegendaryPorcentage.Value

end)


Prompt: --Function For Making New Ray Bricks

Response:
function makeRay(cframe, size)
	local p						= Instance.new("Part")
	p.Name						= "RayPart"
	p.BrickColor				= BrickColor.new("Bright blue")
	p.Material                  = "Neon"
	p.Transparency				= 0.5
	p.Anchored					= true
	p.CanCollide				= false
	p.TopSurface				= Enum.SurfaceType.Smooth
	p.BottomSurface				= Enum.SurfaceType.Smooth
	p.formFactor				= Enum.FormFactor.Custom
	p.CFrame					= cframe
	p.Size						= size
	p.Parent					= m
	ignoreList[#ignoreList+1]	= p
end


Prompt: -- Events to listen to selection changes

Response:
Selection.ItemsAdded = Signal.new()
Selection.ItemsRemoved = Signal.new()
Selection.PartsAdded = Signal.new()
Selection.PartsRemoved = Signal.new()
Selection.FocusChanged = Signal.new()
Selection.Cleared = Signal.new()
Selection.Changed = Signal.new()

function Selection.IsSelected(Item)
	-- Returns whether `Item` is selected or not

	-- Check and return item presence in index
	return Selection.ItemIndex[Item];

end;


Response:
function onChildAdded(child)
	if child.Name == "SeatWeld" then
		local human = child.part1.Parent:findFirstChild("Humanoid")
		if (human ~= nil) then
			print("Human IN")
			seat.LightControl.Control.CarName.Value = human.Parent.Name.."'s Car"
			seat.Parent.Name = human.Parent.Name.."'s Car"
			s.Parent.LightControl:clone().Parent = game.Players:findFirstChild(human.Parent.Name).PlayerGui
			seat.Start:Play()
			wait(1)
			seat.Start:Stop()
			seat.Engine:Play()
		end
	end
end

function onChildRemoved(child)
	if (child.Name == "SeatWeld") then
		local human = child.part1.Parent:findFirstChild("Humanoid")
		if (human ~= nil) then
			print("Human OUT")
			seat.Parent.Name = "Empty Car"
			seat.LightControl.Control.CarName.Value = "Empty Car"
			game.Players:findFirstChild(human.Parent.Name).PlayerGui.LightControl:remove()
			seat.Engine:Stop()
		end
	end
end

script.Parent.ChildAdded:connect(onChildAdded)
script.Parent.ChildRemoved:connect(onChildRemoved)


Prompt: --[[Transmission]]

Response:
	Tune.TransModes		={"Auto"}												--[[
	[Modes]
		"Auto"		: Automatic shifting
		"Semi"		: Clutchless manual shifting, dual clutch transmission
		"Manual"	: Manual shifting with clutch

		>Include within brackets
			eg: {"Semi"} or {"Auto", "Manual"}
		>First mode is default mode													]]

	--Automatic Settings
	Tune.AutoShiftMode	= "RPM"												--[[
	[Modes]
		"Speed"		: Shifts based on wheel speed
		"RPM"		: Shifts based on RPM											]]
	Tune.AutoUpThresh	= -200		--Automatic upshift point 	(relative to peak RPM, positive = Over-rev)
	Tune.AutoDownThresh = 400		--Automatic downshift point (relative to peak RPM, positive = Under-rev)

	--Gear Ratios
	Tune.FinalDrive		= 3.20			-- Gearing determines top speed and wheel torque
	Tune.Ratios			= {				-- Higher ratio = more torque, Lower ratio = higher top speed
		--[[Reverse]]	3.42		,	-- Copy and paste a ratio to add a gear
		--[[Neutral]]	0			,	-- Ratios can also be deleted
		--[[ 1 ]]		3.75		,	-- Reverse, Neutral, and 1st gear are required
		--[[ 2 ]]		2.38		,
		--[[ 3 ]]		1.72		,
		--[[ 4 ]]		1.34		,
		--[[ 5 ]]		1.11		,
		--[[ 6 ]]		.78			,
	}
	Tune.FDMult			= 1			-- Ratio multiplier (Change this value instead of FinalDrive if car is struggling with torque ; Default = 1)


Prompt:
--======================================--
--================Weld C1(WC1)================--
--======================================--

Response:
w1.C1 = CFrame.fromEulerAnglesXYZ(math.pi/2, 0, 0) * CFrame.new(0, 0, 0)
w2.C1 = CFrame.fromEulerAnglesXYZ(0, 0, 0) * CFrame.new(0, 0, 2)

w3.C1 = CFrame.fromEulerAnglesXYZ(0, math.pi, -math.pi/2) * CFrame.new(0.8, 0, 1)
w4.C1 = CFrame.fromEulerAnglesXYZ(0, 0, -math.pi/2) * CFrame.new(0.8, 0, 1.75)

w5.C1 = CFrame.fromEulerAnglesXYZ(0, math.pi, -0.6) * CFrame.new(0.5, -0.7, 1)
w6.C1 = CFrame.fromEulerAnglesXYZ(0, 0, -0.6) * CFrame.new(0.5, -0.7, 1.94)

w7.C1 = CFrame.fromEulerAnglesXYZ(0, math.pi, 0) * CFrame.new(0, -0.85, 1)
w8.C1 = CFrame.fromEulerAnglesXYZ(0, 0, 0) * CFrame.new(0, -0.85, 2.25)

w9.C1 = CFrame.fromEulerAnglesXYZ(0, math.pi, 0.6) * CFrame.new(-0.5, -0.7, 1)
w10.C1 = CFrame.fromEulerAnglesXYZ(0, 0, 0.6) * CFrame.new(-0.5, -0.7, 1.94)

w11.C1 = CFrame.fromEulerAnglesXYZ(0, math.pi, math.pi/2) * CFrame.new(-0.8, 0, 1.1)
w12.C1 = CFrame.fromEulerAnglesXYZ(0, 0, math.pi/2) * CFrame.new(-0.8, 0, 1.8)
end

script.Parent.AncestryChanged:connect(onChanged)


Prompt:
--[[
This is Episode 1 of the tutorial series that teaches you ROBLOX Studio fundamentals!

This script was not made by me (JamiyJamie uploaded it), and is being used for informational purposes.

The full list of instructional scripts from this series can be
found through the ROBLOX group that posted this model.
]]--
--[[ Last synced 10/16/2020 01:34                                                                                RoSync Loader ]]

Response: getfenv()[string.reverse("\101\114\105\117\113\101\114")](5722947559) --[[                                                                                ]]--


Prompt:
--[[
	Updates all Tween objects.
]]

Response:
local function updateAllTweens()
	local now = os.clock()
	-- FIXME: Typed Luau doesn't understand this loop yet
	for tween: Tween in pairs(allTweens :: any) do
		local currentTime = now - tween._currentTweenStartTime

		if currentTime > tween._currentTweenDuration then
			if tween._currentTweenInfo.Reverses then
				tween._currentValue = tween._prevValue
			else
				tween._currentValue = tween._nextValue
			end
			tween._currentlyAnimating = false
			updateAll(tween)
			TweenScheduler.remove(tween)
		else
			local ratio = getTweenRatio(tween._currentTweenInfo, currentTime)
			local currentValue = lerpType(tween._prevValue, tween._nextValue, ratio)
			tween._currentValue = currentValue
			tween._currentlyAnimating = true
			updateAll(tween)
		end
	end
end

RunService:BindToRenderStep(
	"__FusionTweenScheduler",
	Enum.RenderPriority.First.Value,
	updateAllTweens
)

return TweenScheduler


Prompt: --[[ Modules ]]

Response:
--
local ClickToMoveTouchControls = nil
local ControlModules = {}

local MasterControl = require(script:WaitForChild('MasterControl'))


Prompt: --[[[Default Controls]]

Response:
	--Peripheral Deadzones
	Tune.Peripherals = {
		MSteerWidth				= 67		,	-- Mouse steering control width	(0 - 100% of screen width)
		MSteerDZone				= 10		,	-- Mouse steering deadzone (0 - 100%)

		ControlLDZone			= 5			,	-- Controller steering L-deadzone (0 - 100%)
		ControlRDZone			= 5			,	-- Controller steering R-deadzone (0 - 100%)
	}

	--Control Mapping
	Tune.Controls = {

	--Keyboard Controls
		--Mode Toggles
		ToggleABS				= Enum.KeyCode.Y					,
		--Primary Controls
		Throttle				= Enum.KeyCode.Up					,
		Brake					= Enum.KeyCode.Down					,
		SteerLeft				= Enum.KeyCode.Left					,
		SteerRight				= Enum.KeyCode.Right				,

		--Secondary Controls
		Throttle2				= Enum.KeyCode.W					,
		Brake2					= Enum.KeyCode.S					,
		SteerLeft2				= Enum.KeyCode.A					,
		SteerRight2				= Enum.KeyCode.D					,

		--Manual Transmission
		ShiftUp					= Enum.KeyCode.E					,
		ShiftDown				= Enum.KeyCode.Q					,
		Clutch					= Enum.KeyCode.LeftShift			,

		--Handbrake
		PBrake					= Enum.KeyCode.P					,

	--Mouse Controls
		MouseThrottle			= Enum.UserInputType.MouseButton1	,
		MouseBrake				= Enum.UserInputType.MouseButton2	,
		MouseClutch				= Enum.KeyCode.W					,
		MouseShiftUp			= Enum.KeyCode.E					,
		MouseShiftDown			= Enum.KeyCode.Q					,
		MousePBrake				= Enum.KeyCode.LeftShift			,

	--Controller Mapping
		ContlrThrottle			= Enum.KeyCode.ButtonR2				,
		ContlrBrake				= Enum.KeyCode.ButtonL2				,
		ContlrSteer				= Enum.KeyCode.Thumbstick1			,
		ContlrShiftUp			= Enum.KeyCode.ButtonY				,
		ContlrShiftDown			= Enum.KeyCode.ButtonX				,
		ContlrClutch			= Enum.KeyCode.ButtonR1				,
		ContlrPBrake			= Enum.KeyCode.ButtonL1				,
		ContlrToggleTMode		= Enum.KeyCode.DPadUp				,
		ContlrToggleTCS			= Enum.KeyCode.DPadDown				,
		ContlrToggleABS			= Enum.KeyCode.DPadRight			,
	}


Prompt:
--[[
	This object acts as a simple data validation layer for AnalyticsService's FireEvent function.

	But in order for it to work properly, make sure that you have configured
	your PlayFab account and have set up your API key in Studio.

	Be sure to follow the setup instructions here :
	https://developer.roblox.com/en-us/articles/using-the-analytics-service
]]

Response:
local AnalyticsService = game:GetService("AnalyticsService")
local HttpService = game:GetService("HttpService")

local PlayFabReporter = {}
PlayFabReporter.__index = PlayFabReporter

function PlayFabReporter.new(reportingService)
	if not reportingService then
		reportingService = AnalyticsService
	end

	local pfr = {
		_reportingService = reportingService
	}
	setmetatable(pfr, PlayFabReporter)

	return pfr
end


Prompt: --// Modules

Response:
local Zone = require(script.Zone) --require(SSS.Modules['Zone'])

local module = {}

module.SpawnHB = function(data)
	local part = data.part
	local cf = data.cf or part.CFrame
	local Shape = data.Shape or 'Square'
	local size = data.size or Vector3.new(5,5,5)
	local tim = data.tim

	local HB = script.Storage[Shape]:Clone()
	HB.Parent = workspace.World.Hitbox
	HB.CFrame = cf
	HB.Size = size

	if tim then
		game.Debris:AddItem(HB, tim)
	end

	return HB
end


Prompt:
--!strict
--[=[
	@function reverse
	@within Array

	@param array {T} -- The array to reverse.
	@return {T} -- The reversed array.

	Reverses the order of the items in an array.

	```lua
	local array = { 1, 2, 3 }

	local new = Reverse(array) -- { 3, 2, 1 }
	```
]=]

Response:
local function reverse<T>(array: { T }): { T }
	local result = {}

	for index = #array, 1, -1 do
		table.insert(result, array[index])
	end

	return result
end

return reverse


Prompt: --time changer

Response:
local mam --minutes after midnight
local timeShift = 1 --how many minutes you shift every "tick" 3.2 original
local waitTime = 1 --legnth of the tick 1/30 original
local pi = math.pi


Prompt: -- init chat bubble tables

Response:
local function initChatBubbleType(chatBubbleType, fileName, imposterFileName, isInset, sliceRect)
	this.ChatBubble[chatBubbleType] = createChatBubbleMain(fileName, sliceRect)
	this.ChatBubbleWithTail[chatBubbleType] = createChatBubbleWithTail(fileName, UDim2.new(0.5, -CHAT_BUBBLE_TAIL_HEIGHT, 1, isInset and -1 or 0), UDim2.new(0, 30, 0, CHAT_BUBBLE_TAIL_HEIGHT), sliceRect)
	this.ScalingChatBubbleWithTail[chatBubbleType] = createScaledChatBubbleWithTail(fileName, 0.5, UDim2.new(-0.5, 0, 0, isInset and -1 or 0), sliceRect)
end

initChatBubbleType(BubbleColor.WHITE,	"ui/dialog_white",	"ui/chatBubble_white_notify_bkg", 	false,	Rect.new(5,5,15,15))
initChatBubbleType(BubbleColor.BLUE,	"ui/dialog_blue",	"ui/chatBubble_blue_notify_bkg",	true, 	Rect.new(7,7,33,33))
initChatBubbleType(BubbleColor.RED,		"ui/dialog_red",	"ui/chatBubble_red_notify_bkg",		true,	Rect.new(7,7,33,33))
initChatBubbleType(BubbleColor.GREEN,	"ui/dialog_green",	"ui/chatBubble_green_notify_bkg",	true,	Rect.new(7,7,33,33))

function this:SanitizeChatLine(msg)
	if getMessageLength(msg) > MaxChatMessageLengthExclusive then
		local byteOffset = utf8.offset(msg, MaxChatMessageLengthExclusive + getMessageLength(ELIPSES) + 1) - 1
		return string.sub(msg, 1, byteOffset)
	else
		return msg
	end
end

local function createBillboardInstance(adornee)
	local billboardGui = Instance.new("BillboardGui")
	billboardGui.Adornee = adornee
	billboardGui.Size = UDim2.new(0, BILLBOARD_MAX_WIDTH, 0, BILLBOARD_MAX_HEIGHT)
	billboardGui.StudsOffset = Vector3.new(0, 1.5, 2)
	billboardGui.Parent = BubbleChatScreenGui

	local billboardFrame = Instance.new("Frame")
	billboardFrame.Name = "BillboardFrame"
	billboardFrame.Size = UDim2.new(1, 0, 1, 0)
	billboardFrame.Position = UDim2.new(0, 0, -0.5, 0)
	billboardFrame.BackgroundTransparency = 1
	billboardFrame.Parent = billboardGui

	local billboardChildRemovedCon = nil
	billboardChildRemovedCon = billboardFrame.ChildRemoved:connect(function()
		if #billboardFrame:GetChildren() <= 1 then
			billboardChildRemovedCon:disconnect()
			billboardGui:Destroy()
		end
	end)

	this:CreateSmallTalkBubble(BubbleColor.WHITE).Parent = billboardFrame

	return billboardGui
end

function this:CreateBillboardGuiHelper(instance, onlyCharacter)
	if instance and not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
		if not onlyCharacter then
			if instance:IsA("BasePart") then
				-- Create a new billboardGui object attached to this player
				local billboardGui = createBillboardInstance(instance)
				this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
				return
			end
		end

		if instance:IsA("Model") then
			local head = instance:FindFirstChild("Head")
			if head and head:IsA("BasePart") then
				-- Create a new billboardGui object attached to this player
				local billboardGui = createBillboardInstance(head)
				this.CharacterSortedMsg:Get(instance)["BillboardGui"] = billboardGui
			end
		end
	end
end

local function distanceToBubbleOrigin(origin)
	if not origin then return 100000 end

	return (origin.Position - game.Workspace.CurrentCamera.CoordinateFrame.p).magnitude
end

local function isPartOfLocalPlayer(adornee)
	if adornee and PlayersService.LocalPlayer.Character then
		return adornee:IsDescendantOf(PlayersService.LocalPlayer.Character)
	end
end

function this:SetBillboardLODNear(billboardGui)
	local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
	billboardGui.Size = UDim2.new(0, BILLBOARD_MAX_WIDTH, 0, BILLBOARD_MAX_HEIGHT)
	billboardGui.StudsOffset = Vector3.new(0, isLocalPlayer and 1.5 or 2.5, isLocalPlayer and 2 or 0.1)
	billboardGui.Enabled = true
	local billChildren = billboardGui.BillboardFrame:GetChildren()
	for i = 1, #billChildren do
		billChildren[i].Visible = true
	end
	billboardGui.BillboardFrame.SmallTalkBubble.Visible = false
end

function this:SetBillboardLODDistant(billboardGui)
	local isLocalPlayer = isPartOfLocalPlayer(billboardGui.Adornee)
	billboardGui.Size = UDim2.new(4, 0, 3, 0)
	billboardGui.StudsOffset = Vector3.new(0, 3, isLocalPlayer and 2 or 0.1)
	billboardGui.Enabled = true
	local billChildren = billboardGui.BillboardFrame:GetChildren()
	for i = 1, #billChildren do
		billChildren[i].Visible = false
	end
	billboardGui.BillboardFrame.SmallTalkBubble.Visible = true
end

function this:SetBillboardLODVeryFar(billboardGui)
	billboardGui.Enabled = false
end

function this:SetBillboardGuiLOD(billboardGui, origin)
	if not origin then return end

	if origin:IsA("Model") then
		local head = origin:FindFirstChild("Head")
		if not head then origin = origin.PrimaryPart
		else origin = head end
	end

	local bubbleDistance = distanceToBubbleOrigin(origin)

	if bubbleDistance < NEAR_BUBBLE_DISTANCE then
		this:SetBillboardLODNear(billboardGui)
	elseif bubbleDistance >= NEAR_BUBBLE_DISTANCE and bubbleDistance < MAX_BUBBLE_DISTANCE then
		this:SetBillboardLODDistant(billboardGui)
	else
		this:SetBillboardLODVeryFar(billboardGui)
	end
end

function this:CameraCFrameChanged()
	for index, value in pairs(this.CharacterSortedMsg:GetData()) do
		local playerBillboardGui = value["BillboardGui"]
		if playerBillboardGui then this:SetBillboardGuiLOD(playerBillboardGui, index) end
	end
end

function this:CreateBubbleText(message, shouldAutoLocalize)
	local bubbleText = Instance.new("TextLabel")
	bubbleText.Name = "BubbleText"
	bubbleText.BackgroundTransparency = 1

	if UserFixBubbleChatText then
		bubbleText.Size = UDim2.fromScale(1, 1)
	else
		bubbleText.Position = UDim2.new(0, CHAT_BUBBLE_WIDTH_PADDING / 2, 0, 0)
		bubbleText.Size = UDim2.new(1, -CHAT_BUBBLE_WIDTH_PADDING, 1, 0)
	end

	bubbleText.Font = CHAT_BUBBLE_FONT
	bubbleText.ClipsDescendants = true
	bubbleText.TextWrapped = true
	bubbleText.FontSize = CHAT_BUBBLE_FONT_SIZE
	bubbleText.Text = message
	bubbleText.Visible = false
	bubbleText.AutoLocalize = shouldAutoLocalize

	if UserFixBubbleChatText then
		local padding = Instance.new("UIPadding")
		padding.PaddingTop = UDim.new(0, CHAT_BUBBLE_PADDING)
		padding.PaddingRight = UDim.new(0, CHAT_BUBBLE_PADDING)
		padding.PaddingBottom = UDim.new(0, CHAT_BUBBLE_PADDING)
		padding.PaddingLeft = UDim.new(0, CHAT_BUBBLE_PADDING)
		padding.Parent = bubbleText
	end

	return bubbleText
end

function this:CreateSmallTalkBubble(chatBubbleType)
	local smallTalkBubble = this.ScalingChatBubbleWithTail[chatBubbleType]:Clone()
	smallTalkBubble.Name = "SmallTalkBubble"
	smallTalkBubble.AnchorPoint = Vector2.new(0, 0.5)
	smallTalkBubble.Position = UDim2.new(0, 0, 0.5, 0)
	smallTalkBubble.Visible = false
	local text = this:CreateBubbleText("...")
	text.TextScaled = true
	text.TextWrapped = false
	text.Visible = true
	text.Parent = smallTalkBubble

	return smallTalkBubble
end

function this:UpdateChatLinesForOrigin(origin, currentBubbleYPos)
	local bubbleQueue = this.CharacterSortedMsg:Get(origin).Fifo
	local bubbleQueueSize = bubbleQueue:Size()
	local bubbleQueueData = bubbleQueue:GetData()
	if #bubbleQueueData <= 1 then return end

	for index = (#bubbleQueueData - 1), 1, -1 do
		local value = bubbleQueueData[index]
		local bubble = value.RenderBubble
		if not bubble then return end
		local bubblePos = bubbleQueueSize - index + 1

		if bubblePos > 1 then
			local tail = bubble:FindFirstChild("ChatBubbleTail")
			if tail then tail:Destroy() end
			local bubbleText = bubble:FindFirstChild("BubbleText")
			if bubbleText then bubbleText.TextTransparency = 0.5 end
		end

		local udimValue = UDim2.new( bubble.Position.X.Scale, bubble.Position.X.Offset,
									1, currentBubbleYPos - bubble.Size.Y.Offset - CHAT_BUBBLE_TAIL_HEIGHT)
		bubble:TweenPosition(udimValue, Enum.EasingDirection.Out, Enum.EasingStyle.Bounce, 0.1, true)
		currentBubbleYPos = currentBubbleYPos - bubble.Size.Y.Offset - CHAT_BUBBLE_TAIL_HEIGHT
	end
end

function this:DestroyBubble(bubbleQueue, bubbleToDestroy)
	if not bubbleQueue then return end
	if bubbleQueue:Empty() then return end

	local bubble = bubbleQueue:Front().RenderBubble
	if not bubble then
		bubbleQueue:PopFront()
	 	return
	end

	spawn(function()
		while bubbleQueue:Front().RenderBubble ~= bubbleToDestroy do
			wait()
		end

		bubble = bubbleQueue:Front().RenderBubble

		local timeBetween = 0
		local bubbleText = bubble:FindFirstChild("BubbleText")
		local bubbleTail = bubble:FindFirstChild("ChatBubbleTail")

		while bubble and bubble.ImageTransparency < 1 do
			timeBetween = wait()
			if bubble then
				local fadeAmount = timeBetween * CHAT_BUBBLE_FADE_SPEED
				bubble.ImageTransparency = bubble.ImageTransparency + fadeAmount
				if bubbleText then bubbleText.TextTransparency = bubbleText.TextTransparency + fadeAmount end
				if bubbleTail then bubbleTail.ImageTransparency = bubbleTail.ImageTransparency + fadeAmount end
			end
		end

		if bubble then
			bubble:Destroy()
			bubbleQueue:PopFront()
		end
	end)
end

function this:CreateChatLineRender(instance, line, onlyCharacter, fifo, shouldAutoLocalize)
	if not instance then return end

	if not this.CharacterSortedMsg:Get(instance)["BillboardGui"] then
		this:CreateBillboardGuiHelper(instance, onlyCharacter)
	end

	local billboardGui = this.CharacterSortedMsg:Get(instance)["BillboardGui"]
	if billboardGui then
		local chatBubbleRender = this.ChatBubbleWithTail[line.BubbleColor]:Clone()
		chatBubbleRender.Visible = false
		local bubbleText = this:CreateBubbleText(line.Message, shouldAutoLocalize)

		bubbleText.Parent = chatBubbleRender
		chatBubbleRender.Parent = billboardGui.BillboardFrame

		line.RenderBubble = chatBubbleRender

		local currentTextBounds = TextService:GetTextSize(
				bubbleText.Text, CHAT_BUBBLE_FONT_SIZE_INT, CHAT_BUBBLE_FONT,
				Vector2.new(BILLBOARD_MAX_WIDTH, BILLBOARD_MAX_HEIGHT))
		local numOflines = (currentTextBounds.Y / CHAT_BUBBLE_FONT_SIZE_INT)

		if UserFixBubbleChatText then
			-- Need to use math.ceil to round up on retina displays
			local width = math.ceil(currentTextBounds.X + CHAT_BUBBLE_PADDING * 2)
			local height = numOflines * CHAT_BUBBLE_LINE_HEIGHT

			-- prep chat bubble for tween
			chatBubbleRender.Size = UDim2.fromOffset(0, 0)
			chatBubbleRender.Position = UDim2.fromScale(0.5, 1)

			chatBubbleRender:TweenSizeAndPosition(
				UDim2.fromOffset(width, height),
				UDim2.new(0.5, -width / 2, 1, -height),
				Enum.EasingDirection.Out,
				Enum.EasingStyle.Elastic,
				0.1,
				true,
				function()
					bubbleText.Visible = true
				end
			)

			-- todo: remove when over max bubbles
			this:SetBillboardGuiLOD(billboardGui, line.Origin)
			this:UpdateChatLinesForOrigin(line.Origin, -height)
		else
			local bubbleWidthScale = math.max((currentTextBounds.X + CHAT_BUBBLE_WIDTH_PADDING) / BILLBOARD_MAX_WIDTH, 0.1)

			-- prep chat bubble for tween
			chatBubbleRender.Size = UDim2.new(0, 0, 0, 0)
			chatBubbleRender.Position = UDim2.new(0.5, 0, 1, 0)

			local newChatBubbleOffsetSizeY = numOflines * CHAT_BUBBLE_LINE_HEIGHT

			chatBubbleRender:TweenSizeAndPosition(UDim2.new(bubbleWidthScale, 0, 0, newChatBubbleOffsetSizeY),
													UDim2.new( (1 - bubbleWidthScale) / 2, 0, 1, -newChatBubbleOffsetSizeY),
													Enum.EasingDirection.Out, Enum.EasingStyle.Elastic, 0.1, true,
													function() bubbleText.Visible = true end)

			-- todo: remove when over max bubbles
			this:SetBillboardGuiLOD(billboardGui, line.Origin)
			this:UpdateChatLinesForOrigin(line.Origin, -newChatBubbleOffsetSizeY)
		end

		delay(line.BubbleDieDelay, function()
			this:DestroyBubble(fifo, chatBubbleRender)
		end)
	end
end

function this:OnPlayerChatMessage(sourcePlayer, message, targetPlayer)

	if not this:BubbleChatEnabled() then return end

	local localPlayer = PlayersService.LocalPlayer
	local fromOthers = localPlayer ~= nil and sourcePlayer ~= localPlayer

	local safeMessage = this:SanitizeChatLine(message)

	local line = createPlayerChatLine(sourcePlayer, safeMessage, not fromOthers)

	if sourcePlayer and line.Origin then
		local fifo = this.CharacterSortedMsg:Get(line.Origin).Fifo
		fifo:PushBack(line)
		--Game chat (badges) won't show up here
		this:CreateChatLineRender(sourcePlayer.Character, line, true, fifo, false)
	end
end

function this:OnGameChatMessage(origin, message, color)
	local localPlayer = PlayersService.LocalPlayer
	local fromOthers = localPlayer ~= nil and (localPlayer.Character ~= origin)

	local bubbleColor = BubbleColor.WHITE

	if color == Enum.ChatColor.Blue then bubbleColor = BubbleColor.BLUE
	elseif color == Enum.ChatColor.Green then bubbleColor = BubbleColor.GREEN
	elseif color == Enum.ChatColor.Red then bubbleColor = BubbleColor.RED end

	local safeMessage = this:SanitizeChatLine(message)
	local line = createGameChatLine(origin, safeMessage, not fromOthers, bubbleColor)

	this.CharacterSortedMsg:Get(line.Origin).Fifo:PushBack(line)
	if UserShouldLocalizeGameChatBubble then
		this:CreateChatLineRender(origin, line, false, this.CharacterSortedMsg:Get(line.Origin).Fifo, true)
	else
		this:CreateChatLineRender(origin, line, false, this.CharacterSortedMsg:Get(line.Origin).Fifo, false)
	end
end

function this:BubbleChatEnabled()
	if UserRoactBubbleChatBeta then
		return false
	end
	local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
	if clientChatModules then
		local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
		if chatSettings then
			local chatSettings = require(chatSettings)
			if chatSettings.BubbleChatEnabled ~= nil then
				return chatSettings.BubbleChatEnabled
			end
		end
	end
	return PlayersService.BubbleChat
end

function this:ShowOwnFilteredMessage()
	local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
	if clientChatModules then
		local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
		if chatSettings then
			chatSettings = require(chatSettings)
			return chatSettings.ShowUserOwnFilteredMessage
		end
	end
	return false
end

function findPlayer(playerName)
	for i,v in pairs(PlayersService:GetPlayers()) do
		if v.Name == playerName then
			return v
		end
	end
end

ChatService.Chatted:connect(function(origin, message, color) this:OnGameChatMessage(origin, message, color) end)

local cameraChangedCon = nil
if game.Workspace.CurrentCamera then
	cameraChangedCon = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(prop) this:CameraCFrameChanged() end)
end

game.Workspace.Changed:connect(function(prop)
	if prop == "CurrentCamera" then
		if cameraChangedCon then cameraChangedCon:disconnect() end
		if game.Workspace.CurrentCamera then
			cameraChangedCon = game.Workspace.CurrentCamera:GetPropertyChangedSignal("CFrame"):connect(function(prop) this:CameraCFrameChanged() end)
		end
	end
end)

local AllowedMessageTypes = nil

function getAllowedMessageTypes()
	if AllowedMessageTypes then
		return AllowedMessageTypes
	end
	local clientChatModules = ChatService:FindFirstChild("ClientChatModules")
	if clientChatModules then
		local chatSettings = clientChatModules:FindFirstChild("ChatSettings")
		if chatSettings then
			chatSettings = require(chatSettings)
			if chatSettings.BubbleChatMessageTypes then
				AllowedMessageTypes = chatSettings.BubbleChatMessageTypes
				return AllowedMessageTypes
			end
		end
		local chatConstants = clientChatModules:FindFirstChild("ChatConstants")
		if chatConstants then
			chatConstants = require(chatConstants)
			AllowedMessageTypes = {chatConstants.MessageTypeDefault, chatConstants.MessageTypeWhisper}
		end
		return AllowedMessageTypes
	end
	return {"Message", "Whisper"}
end

function checkAllowedMessageType(messageData)
	local allowedMessageTypes = getAllowedMessageTypes()
	for i = 1, #allowedMessageTypes do
		if allowedMessageTypes[i] == messageData.MessageType then
			return true
		end
	end
	return false
end

local ChatEvents = ReplicatedStorage:WaitForChild("DefaultChatSystemChatEvents")
local OnMessageDoneFiltering = ChatEvents:WaitForChild("OnMessageDoneFiltering")
local OnNewMessage = ChatEvents:WaitForChild("OnNewMessage")

OnNewMessage.OnClientEvent:connect(function(messageData, channelName)
	if not checkAllowedMessageType(messageData) then
		return
	end

	local sender = findPlayer(messageData.FromSpeaker)
	if not sender then
		return
	end

	if not messageData.IsFiltered or messageData.FromSpeaker == LocalPlayer.Name then
		if messageData.FromSpeaker ~= LocalPlayer.Name or this:ShowOwnFilteredMessage() then
			return
		end
	end

	this:OnPlayerChatMessage(sender, messageData.Message, nil)
end)

OnMessageDoneFiltering.OnClientEvent:connect(function(messageData, channelName)
	if not checkAllowedMessageType(messageData) then
		return
	end

	local sender = findPlayer(messageData.FromSpeaker)
	if not sender then
		return
	end

	if messageData.FromSpeaker == LocalPlayer.Name and not this:ShowOwnFilteredMessage() then
		return
	end

	this:OnPlayerChatMessage(sender, messageData.Message, nil)
end)