Support.AddUserInputListener("\069\110\100\101\100","\077\111\117\115\101\066\117\116\116\111\110\049",true,function(p)if not HandleDragging then return end HandleDragging=false ClearConnection("\072\097\110\100\108\101\082\101\108\101\097\115\101")for p,A in pairs(InitialState)do p:MakeJoints()Core.RestoreJoints(A.Joints)p.CanCollide=A.CanCollide p.Anchored=A.Anchored end RegisterChange()BoundingBox.RecalculateStaticExtents()BoundingBox.ResumeMonitoring()end)function HideHandles()if not Handles or not Handles.Visible then return end Handles.Visible=false Handles.Parent=nil ClearConnection("\065\117\116\111\102\111\099\117\115\072\097\110\100\108\101")end function MovePartsAlongAxesByFace(p,A,l,G,c)local X=AxisMultipliers[p]local f=c[G]for p,G in pairs(c)do if l=="\071\108\111\098\097\108"then p.CFrame=G.CFrame+A*X elseif l=="\076\111\099\097\108"then p.CFrame=G.CFrame*CFrame.new(A*X)elseif l=="\076\097\115\116"then local l=f.CFrame*CFrame.new(A*X)local c=f.CFrame:toObjectSpace(G.CFrame)p.CFrame=l*c end end end function BindShortcutKeys()table.insert(Connections,UserInputService.InputBegan:connect(function(p,A)if A then return end if p.UserInputType~=Enum.UserInputType.Keyboard then return end if UserInputService:GetFocusedTextBox()then return end if p.KeyCode==Enum.KeyCode.Return or p.KeyCode==Enum.KeyCode.KeypadEnter then if MoveTool.Axes=="\071\108\111\098\097\108"then SetAxes("\076\111\099\097\108")elseif MoveTool.Axes=="\076\111\099\097\108"then SetAxes("\076\097\115\116")elseif MoveTool.Axes=="\076\097\115\116"then SetAxes("\071\108\111\098\097\108")end elseif p.KeyCode==Enum.KeyCode.Minus or p.KeyCode==Enum.KeyCode.KeypadMinus then if MoveTool.UI then MoveTool.UI.IncrementOption.Increment.TextBox:CaptureFocus()end elseif p.KeyCode==Enum.KeyCode.R and not Selection.Multiselecting then StartSnapping()elseif p.KeyCode==Enum.KeyCode.KeypadEight then NudgeSelectionByFace(Enum.NormalId.Top)elseif p.KeyCode==Enum.KeyCode.KeypadTwo then NudgeSelectionByFace(Enum.NormalId.Bottom)elseif p.KeyCode==Enum.KeyCode.KeypadNine then NudgeSelectionByFace(Enum.NormalId.Front)elseif p.KeyCode==Enum.KeyCode.KeypadOne then NudgeSelectionByFace(Enum.NormalId.Back)elseif p.KeyCode==Enum.KeyCode.KeypadFour then NudgeSelectionByFace(Enum.NormalId.Left)elseif p.KeyCode==Enum.KeyCode.KeypadSix then NudgeSelectionByFace(Enum.NormalId.Right)elseif p.KeyCode==Enum.KeyCode.T then AlignSelectionToTarget()end end))table.insert(Connections,UserInputService.InputEnded:connect(function(p,A)if A then return end if p.UserInputType~=Enum.UserInputType.Keyboard then return end if p.KeyCode==Enum.KeyCode.R then if UserInputService:GetFocusedTextBox()then return end if not Dragging then SetAxes(MoveTool.Axes)end SnapTracking.StopTracking()end end))end
-- Finalize changes to parts when the handle is let go
Support.AddUserInputListener("Ended", "MouseButton1", true, function(Input)
	-- Ensure handle dragging is ongoing
	if not HandleDragging then
		return
	end

	-- Disable dragging
	HandleDragging = false

	-- Clear this connection to prevent it from firing again
	ClearConnection("HandleRelease")

	-- Make joints, restore original anchor and collision states
	for Part, State in pairs(InitialState) do
		Part:MakeJoints()
		Core.RestoreJoints(State.Joints)
		Part.CanCollide = State.CanCollide
		Part.Anchored = State.Anchored
	end

	-- Register the change
	RegisterChange()

	-- Resume normal bounding box updating
	BoundingBox.RecalculateStaticExtents()
	BoundingBox.ResumeMonitoring()
end)

function HideHandles()
	-- Hides the resizing handles

	-- Make sure handles exist and are visible
	if not Handles or not Handles.Visible then
		return
	end

	-- Hide the handles
	Handles.Visible = false
	Handles.Parent = nil

	-- Disable handle autofocus
	ClearConnection("AutofocusHandle")
end

function MovePartsAlongAxesByFace(Face, Distance, Axes, BasePart, InitialStates)
	-- Moves the given parts in `InitialStates`, along the given axis mode, in the given face direction, by the given distance

	-- Get the axis multiplier for this face
	local AxisMultiplier = AxisMultipliers[Face]

	-- Get starting state for `BasePart`
	local InitialBasePartState = InitialStates[BasePart]

	-- Move each part
	for Part, InitialState in pairs(InitialStates) do
		-- Move along standard axes
		if Axes == "Global" then
			Part.CFrame = InitialState.CFrame + (Distance * AxisMultiplier)

		-- Move along item's axes
		elseif Axes == "Local" then
			Part.CFrame = InitialState.CFrame * CFrame.new(Distance * AxisMultiplier)

		-- Move along focused part's axes
		elseif Axes == "Last" then
			-- Calculate the focused part's position
			local RelativeTo = InitialBasePartState.CFrame * CFrame.new(Distance * AxisMultiplier)

			-- Calculate how far apart we should be from the focused part
			local Offset = InitialBasePartState.CFrame:toObjectSpace(InitialState.CFrame)

			-- Move relative to the focused part by this part's offset from it
			Part.CFrame = RelativeTo * Offset
		end
	end
end

function BindShortcutKeys()
	-- Enables useful shortcut keys for this tool

	-- Track user input while this tool is equipped
	table.insert(
		Connections,
		UserInputService.InputBegan:connect(function(InputInfo, GameProcessedEvent)
			-- Make sure this is an intentional event
			if GameProcessedEvent then
				return
			end

			-- Make sure this input is a key press
			if InputInfo.UserInputType ~= Enum.UserInputType.Keyboard then
				return
			end

			-- Make sure it wasn't pressed while typing
			if UserInputService:GetFocusedTextBox() then
				return
			end

			-- Check if the enter key was pressed
			if InputInfo.KeyCode == Enum.KeyCode.Return or InputInfo.KeyCode == Enum.KeyCode.KeypadEnter then
				-- Toggle the current axis mode
				if MoveTool.Axes == "Global" then
					SetAxes("Local")
				elseif MoveTool.Axes == "Local" then
					SetAxes("Last")
				elseif MoveTool.Axes == "Last" then
					SetAxes("Global")
				end

			-- Check if the - key was pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.Minus or InputInfo.KeyCode == Enum.KeyCode.KeypadMinus then
				-- Focus on the increment input
				if MoveTool.UI then
					MoveTool.UI.IncrementOption.Increment.TextBox:CaptureFocus()
				end

			-- Check if the R key was pressed down, and it's not the selection clearing hotkey
			elseif InputInfo.KeyCode == Enum.KeyCode.R and not Selection.Multiselecting then
				-- Start tracking snap points nearest to the mouse
				StartSnapping()

			-- Nudge up if the 8 button on the keypad is pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.KeypadEight then
				NudgeSelectionByFace(Enum.NormalId.Top)

			-- Nudge down if the 2 button on the keypad is pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.KeypadTwo then
				NudgeSelectionByFace(Enum.NormalId.Bottom)

			-- Nudge forward if the 9 button on the keypad is pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.KeypadNine then
				NudgeSelectionByFace(Enum.NormalId.Front)

			-- Nudge backward if the 1 button on the keypad is pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.KeypadOne then
				NudgeSelectionByFace(Enum.NormalId.Back)

			-- Nudge left if the 4 button on the keypad is pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.KeypadFour then
				NudgeSelectionByFace(Enum.NormalId.Left)

			-- Nudge right if the 6 button on the keypad is pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.KeypadSix then
				NudgeSelectionByFace(Enum.NormalId.Right)

			-- Align the selection to the current target surface if T is pressed
			elseif InputInfo.KeyCode == Enum.KeyCode.T then
				AlignSelectionToTarget()
			end
		end)
	)

	-- Track ending user input while this tool is equipped
	table.insert(
		Connections,
		UserInputService.InputEnded:connect(function(InputInfo, GameProcessedEvent)
			-- Make sure this is an intentional event
			if GameProcessedEvent then
				return
			end

			-- Make sure this is input from the keyboard
			if InputInfo.UserInputType ~= Enum.UserInputType.Keyboard then
				return
			end

			-- Check if the R key was let go
			if InputInfo.KeyCode == Enum.KeyCode.R then
				-- Make sure it wasn't pressed while typing
				if UserInputService:GetFocusedTextBox() then
					return
				end

				-- Reset handles if not dragging
				if not Dragging then
					SetAxes(MoveTool.Axes)
				end

				-- Stop snapping point tracking if it was enabled
				SnapTracking.StopTracking()
			end
		end)
	)
end
