local N=game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")local C=game:GetService("\071\117\105\083\101\114\118\105\099\101")local F=require((game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")):WaitForChild("\078\101\118\101\114\109\111\114\101"))local h=F("\073\110\112\117\116\077\111\100\101")local d=F("\073\110\112\117\116\077\111\100\101\080\114\111\099\101\115\115\111\114")local K=F("\077\097\105\100")local a=setmetatable({},{__index=function(N,C)error(("\'\037\115\' \105\115 \110\111\116 \097 \118\097\108\105\100 \073\110\112\117\116\077\111\100\101"):format(tostring(C)))end})a.THUMBSTICK_DEADZONE=.14 do local C="\075\101\121\112\097\100\090\101\114\111\044\075\101\121\112\097\100\079\110\101\044\075\101\121\112\097\100\084\119\111\044\075\101\121\112\097\100\084\104\114\101\101\044\075\101\121\112\097\100\070\111\117\114\044\075\101\121\112\097\100\070\105\118\101\044\075\101\121\112\097\100\083\105\120\044\075\101\121\112\097\100\083\101\118\101\110\044\075\101\121\112\097\100\069\105\103\104\116\044\075\101\121\112\097\100\078\105\110\101\044\075\101\121\112\097\100\080\101\114\105\111\100\044\075\101\121\112\097\100\068\105\118\105\100\101\044\075\101\121\112\097\100\077\117\108\116\105\112\108\121\044\075\101\121\112\097\100\077\105\110\117\115\044\075\101\121\112\097\100\080\108\117\115\044\075\101\121\112\097\100\069\110\116\101\114\044\075\101\121\112\097\100\069\113\117\097\108\115"local F="\065\044\066\044\067\044\068\044\069\044\070\044\071\044\072\044\073\044\074\044\075\044\076\044\077\044\078\044\079\044\080\044\081\044\082\044\083\044\084\044\085\044\086\044\087\044\088\044\089\044\090"local d="\076\101\102\116\044\082\105\103\104\116\044\085\112\044\068\111\119\110"a.Keyboard=(((((((h.new("\075\101\121\098\111\097\114\100")):AddKeys("\075\101\121\098\111\097\114\100",Enum.UserInputType)):AddKeys("\066\097\099\107\115\112\097\099\101\044\084\097\098\044\067\108\101\097\114\044\082\101\116\117\114\110\044\080\097\117\115\101\044\069\115\099\097\112\101\044\083\112\097\099\101\044\081\117\111\116\101\100\068\111\117\098\108\101\044\072\097\115\104\044\068\111\108\108\097\114\044\080\101\114\099\101\110\116\044\065\109\112\101\114\115\097\110\100\044\081\117\111\116\101\044\076\101\102\116\080\097\114\101\110\116\104\101\115\105\115\044\082\105\103\104\116\080\097\114\101\110\116\104\101\115\105\115\044\065\115\116\101\114\105\115\107\044\080\108\117\115\044\067\111\109\109\097\044\077\105\110\117\115\044\080\101\114\105\111\100\044\083\108\097\115\104\044\090\101\114\111\044\079\110\101\044\084\119\111\044\084\104\114\101\101\044\070\111\117\114\044\070\105\118\101\044\083\105\120\044\083\101\118\101\110\044\069\105\103\104\116\044\078\105\110\101\044\067\111\108\111\110\044\083\101\109\105\099\111\108\111\110\044\076\101\115\115\084\104\097\110\044\069\113\117\097\108\115\044\071\114\101\097\116\101\114\084\104\097\110\044\081\117\101\115\116\105\111\110\044\065\116\044\076\101\102\116\066\114\097\099\107\101\116\044\066\097\099\107\083\108\097\115\104\044\082\105\103\104\116\066\114\097\099\107\101\116\044\067\097\114\101\116\044\085\110\100\101\114\115\099\111\114\101\044\066\097\099\107\113\117\111\116\101",Enum.KeyCode)):AddKeys(F,Enum.KeyCode)):AddKeys("\076\101\102\116\067\117\114\108\121\044\080\105\112\101\044\082\105\103\104\116\067\117\114\108\121\044\084\105\108\100\101\044\068\101\108\101\116\101\044\073\110\115\101\114\116\044\072\111\109\101\044\069\110\100\044\080\097\103\101\085\112\044\080\097\103\101\068\111\119\110\044\070\049\044\070\050\044\070\051\044\070\052\044\070\053\044\070\054\044\070\055\044\070\056\044\070\057\044\070\049\048\044\070\049\049\044\070\049\050\044\070\049\051\044\070\049\052",Enum.KeyCode)):AddKeys("\078\117\109\076\111\099\107\044\067\097\112\115\076\111\099\107\044\083\099\114\111\108\108\076\111\099\107\044\082\105\103\104\116\083\104\105\102\116\044\076\101\102\116\083\104\105\102\116\044\082\105\103\104\116\067\111\110\116\114\111\108\044\076\101\102\116\067\111\110\116\114\111\108\044\082\105\103\104\116\065\108\116\044\076\101\102\116\065\108\116\044\082\105\103\104\116\077\101\116\097\044\076\101\102\116\077\101\116\097\044\076\101\102\116\083\117\112\101\114\044\082\105\103\104\116\083\117\112\101\114\044\077\111\100\101\044\067\111\109\112\111\115\101\044\072\101\108\112\044\080\114\105\110\116\044\083\121\115\082\101\113\044\066\114\101\097\107",Enum.KeyCode)):AddKeys(C,Enum.KeyCode)):AddKeys(d)if N.KeyboardEnabled then a.Keyboard:Enable()end end do a.Mouse=(h.new("\077\111\117\115\101")):AddKeys("\077\111\117\115\101\066\117\116\116\111\110\049\044\077\111\117\115\101\066\117\116\116\111\110\050\044\077\111\117\115\101\066\117\116\116\111\110\051\044\077\111\117\115\101\087\104\101\101\108\044\077\111\117\115\101\077\111\118\101\109\101\110\116",Enum.UserInputType)if N.MouseEnabled then a.Mouse:Enable()end end do a.KeyboardAndMouse=((h.new("\075\101\121\098\111\097\114\100\065\110\100\077\111\117\115\101")):AddInputMode(a.Mouse)):AddInputMode(a.Keyboard)if N.KeyboardEnabled and N.MouseEnabled then a.KeyboardAndMouse:Enable()end end do a.Touch=(h.new("\084\111\117\099\104")):AddKeys("\084\111\117\099\104",Enum.UserInputType)if N.TouchEnabled then a.Touch:Enable()end end do local F="\084\104\117\109\098\115\116\105\099\107\049\044\084\104\117\109\098\115\116\105\099\107\050"local d="\066\117\116\116\111\110\082\050\044\066\117\116\116\111\110\076\050\044\066\117\116\116\111\110\082\049\044\066\117\116\116\111\110\076\049"local K="\066\117\116\116\111\110\065\044\066\117\116\116\111\110\066\044\066\117\116\116\111\110\088\044\066\117\116\116\111\110\089\044\066\117\116\116\111\110\082\051\044\066\117\116\116\111\110\076\051\044\066\117\116\116\111\110\083\116\097\114\116\044\066\117\116\116\111\110\083\101\108\101\099\116\044\068\080\097\100\076\101\102\116\044\068\080\097\100\082\105\103\104\116\044\068\080\097\100\085\112\044\068\080\097\100\068\111\119\110"a.Gamepads=((((h.new("\071\097\109\101\112\097\100")):AddKeys(F,Enum.KeyCode)):AddKeys(K,Enum.KeyCode)):AddKeys(d,Enum.KeyCode)):AddKeys("\071\097\109\101\112\097\100\049\044\071\097\109\101\112\097\100\050\044\071\097\109\101\112\097\100\051\044\071\097\109\101\112\097\100\052\044\071\097\109\101\112\097\100\053\044\071\097\109\101\112\097\100\054\044\071\097\109\101\112\097\100\055\044\071\097\109\101\112\097\100\056",Enum.UserInputType)if N.GamepadEnabled then a.Gamepads:Enable()end if#N:GetConnectedGamepads()>0 then a.Gamepads:Enable()end if C:IsTenFootInterface()then a.Gamepads:Enable()end end local function I()local C=(((((d.new()):AddState(a.Keyboard)):AddState(a.Gamepads)):AddState(a.Mouse)):AddState(a.Touch)):AddState(a.KeyboardAndMouse)N.InputBegan:Connect(function(N)C:Evaluate(N)end)local F=K.new()N.GamepadConnected:Connect(function(h)a.Gamepads:Enable()F._inputChanged=N.InputChanged:Connect(function(N)if N.KeyCode.Name:find("\084\104\117\109\098\115\116\105\099\107")then if N.Position.Magnitude>a.THUMBSTICK_DEADZONE then C:Evaluate(N)end end end)end)N.GamepadDisconnected:Connect(function(N)a.Mouse:Enable()a.Keyboard:Enable()F._inputChanged=nil end)end I()return a
--- Holds input states for Keyboard, Mouse, et cetera. Mostly useful for providing UI input hints to the user by
-- identifying the most recent input state provided.
-- @module INPUT_MODES

local UserInputService = game:GetService("UserInputService")
local GuiService = game:GetService("GuiService")
local require = require(game:GetService("ReplicatedStorage"):WaitForChild("Nevermore"))

local InputMode = require("InputMode")
local InputModeProcessor = require("InputModeProcessor")
local Maid = require("Maid")

--[[

API:
	INPUT_MODES.Keyboard
		Returns an input state for keyboard
	INPUT_MODES.Mouse
		Returns an input state for Mouse
	INPUT_MODES.Touch
		Returns an input state for Touch
	INPUT_MODES.Gamepad
		Returns an input state for Gamepad
	INPUT_MODES.KeyboardAndMouse
]]

local INPUT_MODES = setmetatable({}, {
	__index = function(self, key)
		error(("'%s' is not a valid InputMode"):format(tostring(key)))
	end;
})

---
-- @field
INPUT_MODES.THUMBSTICK_DEADZONE = 0.14

do
	local KEYBOARD = "KeypadZero,KeypadOne,KeypadTwo,KeypadThree,KeypadFour,KeypadFive,KeypadSix,KeypadSeven,KeypadEight,"
		.. "KeypadNine,KeypadPeriod,KeypadDivide,KeypadMultiply,KeypadMinus,KeypadPlus,KeypadEnter,KeypadEquals"
	local ALPHABET = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"
	local ARROW_KEYS = "Left,Right,Up,Down"

	--- Keyboard InputMode
	-- @field
	INPUT_MODES.Keyboard = InputMode.new("Keyboard")
		:AddKeys("Keyboard", Enum.UserInputType) -- Incase we miss anything
		:AddKeys("Backspace,Tab,Clear,Return,Pause,Escape,Space,QuotedDouble,Hash,Dollar,Percent,Ampersand,Quote,"
			.. "LeftParenthesis,RightParenthesis,Asterisk,Plus,Comma,Minus,Period,Slash,Zero,One,Two,Three,Four,Five,Six,Seven,"
			.. "Eight,Nine,Colon,Semicolon,LessThan,Equals,GreaterThan,Question,At,LeftBracket,BackSlash,RightBracket,Caret,"
			.. "Underscore,Backquote", Enum.KeyCode)
		:AddKeys(ALPHABET, Enum.KeyCode)
		:AddKeys("LeftCurly,Pipe,RightCurly,Tilde,Delete,Insert,Home,End,PageUp,PageDown,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,"
			.. "F12,F13,F14", Enum.KeyCode)
		:AddKeys("NumLock,CapsLock,ScrollLock,RightShift,LeftShift,RightControl,LeftControl,RightAlt,LeftAlt,RightMeta,"
			.. "LeftMeta,LeftSuper,RightSuper,Mode,Compose,Help,Print,SysReq,Break", Enum.KeyCode)
		:AddKeys(KEYBOARD, Enum.KeyCode)
		:AddKeys(ARROW_KEYS)

	if UserInputService.KeyboardEnabled then
		INPUT_MODES.Keyboard:Enable()
	end
end

do
	--- Mouse InputMode
	-- @field
	INPUT_MODES.Mouse = InputMode.new("Mouse"):AddKeys("MouseButton1,MouseButton2,MouseButton3,MouseWheel,MouseMovement",
		Enum.UserInputType)

	if UserInputService.MouseEnabled then
		INPUT_MODES.Mouse:Enable()
	end
end

do
	--- KeyboardAndMouse InputMode
	-- @field
	INPUT_MODES.KeyboardAndMouse = InputMode.new("KeyboardAndMouse")
		:AddInputMode(INPUT_MODES.Mouse)
		:AddInputMode(INPUT_MODES.Keyboard)

	if UserInputService.KeyboardEnabled and UserInputService.MouseEnabled then
		INPUT_MODES.KeyboardAndMouse:Enable()
	end
end

do
	--- Touch InputMode
	-- @field
	INPUT_MODES.Touch = InputMode.new("Touch"):AddKeys("Touch", Enum.UserInputType)

	if UserInputService.TouchEnabled then
		INPUT_MODES.Touch:Enable()
	end
end

do
	local GAMEPAD_THUMBSTICKS = "Thumbstick1,Thumbstick2"
	local GAMEPAD_TRIGGERS = "ButtonR2,ButtonL2,ButtonR1,ButtonL1"
	local GAMEPAD_BUTTONS = "ButtonA,ButtonB,ButtonX,ButtonY,ButtonR3,ButtonL3,ButtonStart,ButtonSelect,DPadLeft,"
		.. "DPadRight,DPadUp,DPadDown"

	--- Gamepad InputMode
	-- @field
	INPUT_MODES.Gamepads = InputMode.new("Gamepad")
		:AddKeys(GAMEPAD_THUMBSTICKS, Enum.KeyCode)
		:AddKeys(GAMEPAD_BUTTONS, Enum.KeyCode)
		:AddKeys(GAMEPAD_TRIGGERS, Enum.KeyCode)
		:AddKeys("Gamepad1,Gamepad2,Gamepad3,Gamepad4,Gamepad5,Gamepad6,Gamepad7,Gamepad8", Enum.UserInputType)

	if UserInputService.GamepadEnabled then
		INPUT_MODES.Gamepads:Enable()
	end
	if #UserInputService:GetConnectedGamepads() > 0 then
		INPUT_MODES.Gamepads:Enable()
	end
	if GuiService:IsTenFootInterface() then
		INPUT_MODES.Gamepads:Enable()
	end
end

--- Construct Processor
-- @local
local function bindProcessor()
	local inputProcessor = InputModeProcessor.new()
		:AddState(INPUT_MODES.Keyboard)
		:AddState(INPUT_MODES.Gamepads)
		:AddState(INPUT_MODES.Mouse)
		:AddState(INPUT_MODES.Touch)
		:AddState(INPUT_MODES.KeyboardAndMouse)

	UserInputService.InputBegan:Connect(function(inputObject)
		inputProcessor:Evaluate(inputObject)
	end)

	local maid = Maid.new()

	UserInputService.GamepadConnected:Connect(function(gamepad)
		INPUT_MODES.Gamepads:Enable()

		-- Bind thumbsticks
		maid._inputChanged = UserInputService.InputChanged:Connect(function(inputObject)
			if inputObject.KeyCode.Name:find("Thumbstick") then
				if inputObject.Position.Magnitude > INPUT_MODES.THUMBSTICK_DEADZONE then
					inputProcessor:Evaluate(inputObject)
				end
			end
		end)
	end)

	UserInputService.GamepadDisconnected:Connect(function(gamepad)
		-- TODO: Stop assuming state is mouse/keyboard
		INPUT_MODES.Mouse:Enable()
		INPUT_MODES.Keyboard:Enable()

		maid._inputChanged = nil
	end)
end

bindProcessor()

return INPUT_MODES