Hotkeys={}function AssignHotkey(L,C)if type(L)=="\117\115\101\114\100\097\116\097"then L={L}elseif type(L)=="\115\116\114\105\110\103"then L={Enum.KeyCode[L]}elseif type(L)=="\116\097\098\108\101"then for C,u in ipairs(L)do if type(u)=="\115\116\114\105\110\103"then L[C]=Enum.KeyCode[u]end end end table.insert(Hotkeys,{Keys=L;Callback=C})end function EnableHotkeys()Connections.Hotkeys=Support.AddUserInputListener("\066\101\103\097\110","\075\101\121\098\111\097\114\100",false,function(L)local C=Support.GetListMembers(UserInputService:GetKeysPressed(),"\075\101\121\067\111\100\101")local u={}local M=Support.FlipTable({"\076\101\102\116\065\108\116";"\087";"\083","\065","\068","\083\112\097\099\101"})for L,C in ipairs(C)do if not M[C.Name]then table.insert(u,C)end end local a=#u table.sort(Hotkeys,function(L,C)if#L.Keys>#C.Keys then return true end end)for L,C in ipairs(Hotkeys)do if a==#C.Keys then local L=Support.FlipTable(C.Keys)local M=0 for C,u in pairs(u)do if L[u]then M=M+1 end end if M==a then C.Callback()break end end end end)end Enabling=RbxUtility.CreateSignal()Disabling=RbxUtility.CreateSignal()Enabled=RbxUtility.CreateSignal()Disabled=RbxUtility.CreateSignal()function Enable(L)if IsEnabled and not IsDisabling or IsEnabling then return elseif IsDisabling then Disabled:Wait()return Enable(L)end IsEnabling=true Enabling:Fire();(getfenv(0)).Mouse=L UserInputService.MouseBehavior=Enum.MouseBehavior.Default if Mode=="\084\111\111\108"then SyncAPI:Invoke("\083\101\116\077\111\117\115\101\076\111\099\107\069\110\097\098\108\101\100",false)end while not UI do wait(.1)end UI.Parent=UIContainer if not StartupNotificationsDisplayed then(Cheer(Tool.Interfaces.Notifications,UI)).Start(getfenv(0))StartupNotificationsDisplayed=true end EnableHotkeys()Targeting.EnableTargeting()Selection.EnableOutlines()Selection.EnableMultiselectionHotkeys()EquipTool(CurrentTool or require(Tool.Tools.MoveTool))IsEnabled=true IsEnabling=false Enabled:Fire()end function Disable()if not IsEnabled and not IsEnabling or IsDisabling then return elseif IsEnabling then Enabled:Wait()return Disable()end IsDisabling=true Disabling:Fire()if Mode=="\084\111\111\108"then pcall(SyncAPI.Invoke,SyncAPI,"\083\101\116\077\111\117\115\101\076\111\099\107\069\110\097\098\108\101\100",true)end if UI then UI.Parent=script end if CurrentTool then CurrentTool.Unequip()CurrentTool.Equipped=false end ClearConnections()IsEnabled=false IsDisabling=false Disabled:Fire()end

Hotkeys = {};

function AssignHotkey(Hotkey, Callback)
	-- Assigns the given hotkey to `Callback`

	-- Standardize enum-described hotkeys
	if type(Hotkey) == 'userdata' then
		Hotkey = { Hotkey };

	-- Standardize string-described hotkeys
	elseif type(Hotkey) == 'string' then
		Hotkey = { Enum.KeyCode[Hotkey] };

	-- Standardize string table-described hotkeys
	elseif type(Hotkey) == 'table' then
		for Index, Key in ipairs(Hotkey) do
			if type(Key) == 'string' then
				Hotkey[Index] = Enum.KeyCode[Key];
			end;
		end;
	end;

	-- Register the hotkey
	table.insert(Hotkeys, { Keys = Hotkey, Callback = Callback });

end;

function EnableHotkeys()
	-- Begins to listen for hotkey triggering

	-- Listen for pressed keys
	Connections.Hotkeys = Support.AddUserInputListener('Began', 'Keyboard', false, function (Input)
		local _PressedKeys = Support.GetListMembers(UserInputService:GetKeysPressed(), 'KeyCode');

		-- Filter out problematic keys
		local PressedKeys = {};
		local FilteredKeys = Support.FlipTable { 'LeftAlt', 'W', 'S', 'A', 'D', 'Space' };
		for _, Key in ipairs(_PressedKeys) do
			if not FilteredKeys[Key.Name] then
				table.insert(PressedKeys, Key);
			end;
		end;

		-- Count pressed keys
		local KeyCount = #PressedKeys;

		-- Prioritize hotkeys based on # of required keys
		table.sort(Hotkeys, function (A, B)
			if #A.Keys > #B.Keys then
				return true;
			end;
		end);

		-- Identify matching hotkeys
		for _, Hotkey in ipairs(Hotkeys) do
			if KeyCount == #Hotkey.Keys then

				-- Get the hotkey's key index
				local Keys = Support.FlipTable(Hotkey.Keys)
				local MatchingKeys = 0;

				-- Check matching pressed keys
				for _, PressedKey in pairs(PressedKeys) do
					if Keys[PressedKey] then
						MatchingKeys = MatchingKeys + 1;
					end;
				end;

				-- Trigger the first matching hotkey's callback
				if MatchingKeys == KeyCount then
					Hotkey.Callback();
					break;
				end;

			end;
		end;
	end);

end;

Enabling = RbxUtility.CreateSignal();
Disabling = RbxUtility.CreateSignal();
Enabled = RbxUtility.CreateSignal();
Disabled = RbxUtility.CreateSignal();

function Enable(Mouse)

	-- Ensure tool is disabled or disabling, and not already enabling
	if (IsEnabled and not IsDisabling) or IsEnabling then
		return;

	-- If tool is disabling, enable it once fully disabled
	elseif IsDisabling then
		Disabled:Wait();
		return Enable(Mouse);
	end;

	-- Indicate that tool is enabling
	IsEnabling = true;
	Enabling:Fire();

	-- Update the core mouse
	getfenv(0).Mouse = Mouse;

	-- Use default mouse behavior
	UserInputService.MouseBehavior = Enum.MouseBehavior.Default;

	-- Disable mouse lock in tool mode
	if Mode == 'Tool' then
		SyncAPI:Invoke('SetMouseLockEnabled', false);
	end;

	-- Wait for UI to initialize asynchronously
	while not UI do
		wait(0.1);
	end;

	-- Show UI
	UI.Parent = UIContainer;

	-- Display startup notifications
	if not StartupNotificationsDisplayed then
		Cheer(Tool.Interfaces.Notifications, UI).Start(getfenv(0));
		StartupNotificationsDisplayed = true;
	end;

	-- Start systems
	EnableHotkeys();
	Targeting.EnableTargeting();
	Selection.EnableOutlines();
	Selection.EnableMultiselectionHotkeys();

	-- Equip current tool
	EquipTool(CurrentTool or require(Tool.Tools.MoveTool));

	-- Indicate that tool is now enabled
	IsEnabled = true;
	IsEnabling = false;
	Enabled:Fire();

end;

function Disable()

	-- Ensure tool is enabled or enabling, and not already disabling
	if (not IsEnabled and not IsEnabling) or IsDisabling then
		return;

	-- If tool is enabling, disable it once fully enabled
	elseif IsEnabling then
		Enabled:Wait();
		return Disable();
	end;

	-- Indicate that tool is now disabling
	IsDisabling = true;
	Disabling:Fire();

	-- Reenable mouse lock option in tool mode
	if Mode == 'Tool' then
		pcall(SyncAPI.Invoke, SyncAPI, 'SetMouseLockEnabled', true);
	end;

	-- Hide UI
	if UI then
		UI.Parent = script;
	end;

	-- Unequip current tool
	if CurrentTool then
		CurrentTool.Unequip();
		CurrentTool.Equipped = false;
	end;

	-- Clear temporary connections
	ClearConnections();

	-- Indicate that tool is now disabled
	IsEnabled = false;
	IsDisabling = false;
	Disabled:Fire();

end;

