Prompt: -- Setup gesture area that camera uses while DynamicThumbstick is enabled

Response:
local function OnCharacterAdded(character)
	if UserInputService.TouchEnabled then
		for _, child in ipairs(LocalPlayer.Character:GetChildren()) do
			if child:IsA("Tool") then
				IsAToolEquipped = true
			end
		end
		character.ChildAdded:Connect(function(child)
			if child:IsA("Tool") then
				IsAToolEquipped = true
			end
		end)
		character.ChildRemoved:Connect(function(child)
			if child:IsA("Tool") then
				IsAToolEquipped = false
			end
		end)

		if PlayerGui then
			local TouchGui = PlayerGui:FindFirstChild("TouchGui")
			if TouchGui and TouchGui:WaitForChild("GestureArea", 0.5) then
				GestureArea = TouchGui.GestureArea
				GestureAreaManagedByControlScript = true
			else
				GestureAreaManagedByControlScript = false
				local ScreenGui = Instance.new("ScreenGui")
				ScreenGui.Name = "GestureArea"
				ScreenGui.Parent = PlayerGui

				GestureArea = Instance.new("Frame")
				GestureArea.BackgroundTransparency = 1.0
				GestureArea.Visible = true
				GestureArea.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
				layoutGestureArea(PortraitMode)
				GestureArea.Parent = ScreenGui
			end
		end
	end
end

if LocalPlayer then
	if LocalPlayer.Character ~= nil then
		OnCharacterAdded(LocalPlayer.Character)
	end
	LocalPlayer.CharacterAdded:connect(function(character)
		OnCharacterAdded(character)
	end)
end

local function positionIntersectsGuiObject(position, guiObject)
	if position.X < guiObject.AbsolutePosition.X + guiObject.AbsoluteSize.X
		and position.X > guiObject.AbsolutePosition.X
		and position.Y < guiObject.AbsolutePosition.Y + guiObject.AbsoluteSize.Y
		and position.Y > guiObject.AbsolutePosition.Y then
		return true
	end
	return false
end

local function GetRenderCFrame(part)
	return part:GetRenderCFrame()
end

local function CreateCamera()
	local this = {}
	local R15HeadHeight = R15_HEAD_OFFSET
	function this:GetActivateValue()
		return 0.7
	end

	function this:IsPortraitMode()
		return PortraitMode
	end

	function this:GetRotateAmountValue(vrRotationIntensity)
		vrRotationIntensity = vrRotationIntensity or StarterGui:GetCore("VRRotationIntensity")
		if vrRotationIntensity then
			if vrRotationIntensity == "Low" then
				return VR_LOW_INTENSITY_ROTATION
			elseif vrRotationIntensity == "High" then
				return VR_HIGH_INTENSITY_ROTATION
			end
		end
		return ZERO_VECTOR2
	end
	function this:GetRepeatDelayValue(vrRotationIntensity)
		vrRotationIntensity = vrRotationIntensity or StarterGui:GetCore("VRRotationIntensity")
		if vrRotationIntensity then
			if vrRotationIntensity == "Low" then
				return VR_LOW_INTENSITY_REPEAT
			elseif vrRotationIntensity == "High" then
				return VR_HIGH_INTENSITY_REPEAT
			end
		end
		return 0
	end

	this.ShiftLock = false
	this.Enabled = false
	local isFirstPerson = false
	local isRightMouseDown = false
	local isMiddleMouseDown = false
	this.RotateInput = ZERO_VECTOR2
	this.DefaultZoom = LANDSCAPE_DEFAULT_ZOOM
	this.activeGamepad = nil

	local tweens = {}

	this.lastSubject = nil
	this.lastSubjectPosition = Vector3.new(0, 5, 0)

	local lastVRRotation = 0
	local vrRotateKeyCooldown = {}

	local isDynamicThumbstickEnabled = false
	local dynamicThumbstickFrame = nil

	local function getDynamicThumbstickFrame()
		if dynamicThumbstickFrame and dynamicThumbstickFrame:IsDescendantOf(game) then
			return dynamicThumbstickFrame
		else
			local touchGui = PlayerGui:FindFirstChild("TouchGui")
			if not touchGui then return nil end

			local touchControlFrame = touchGui:FindFirstChild("TouchControlFrame")
			if not touchControlFrame then return nil end

			dynamicThumbstickFrame = touchControlFrame:FindFirstChild("DynamicThumbstickFrame")
			return dynamicThumbstickFrame
		end
	end

	-- Check for changes in ViewportSize to decide if PortraitMode
	local CameraChangedConn = nil
	local workspaceCameraChangedConn = nil
	local function onWorkspaceCameraChanged()
		if UserInputService.TouchEnabled then
			if CameraChangedConn then
				CameraChangedConn:Disconnect()
				CameraChangedConn = nil
			end
			local newCamera = workspace.CurrentCamera
			if newCamera then
				local size = newCamera.ViewportSize
				PortraitMode = size.X < size.Y
				layoutGestureArea(PortraitMode)
				DefaultZoom = PortraitMode and PORTRAIT_DEFAULT_ZOOM or LANDSCAPE_DEFAULT_ZOOM
				CameraChangedConn = newCamera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
					size = newCamera.ViewportSize
					PortraitMode = size.X < size.Y
					layoutGestureArea(PortraitMode)
					DefaultZoom = PortraitMode and PORTRAIT_DEFAULT_ZOOM or LANDSCAPE_DEFAULT_ZOOM
				end)
			end
		end
	end
	workspaceCameraChangedConn = workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(onWorkspaceCameraChanged)
	if workspace.CurrentCamera then
		onWorkspaceCameraChanged()
	end

	function this:GetShiftLock()
		return ShiftLockController:IsShiftLocked()
	end

	function this:GetHumanoid()
		local player = PlayersService.LocalPlayer
		return findPlayerHumanoid(player)
	end

	function this:GetHumanoidRootPart()
		local humanoid = this:GetHumanoid()
		return humanoid and humanoid.Torso
	end

	function this:GetRenderCFrame(part)
		GetRenderCFrame(part)
	end

	local STATE_DEAD = Enum.HumanoidStateType.Dead

	-- HumanoidRootPart when alive, Head part when dead
	local function getHumanoidPartToFollow(humanoid, humanoidStateType)
		if humanoidStateType == STATE_DEAD then
			local character = humanoid.Parent
			if character then
				return character:FindFirstChild("Head") or humanoid.Torso
			else
				return humanoid.Torso
			end
		else
			return humanoid.Torso
		end
	end

	local HUMANOID_STATE_DEAD = Enum.HumanoidStateType.Dead

	function this:GetSubjectPosition()
		local result = nil
		local camera = workspace.CurrentCamera
		local cameraSubject = camera and camera.CameraSubject
		if cameraSubject then
			if cameraSubject:IsA('Humanoid') then
				local humanoidStateType = cameraSubject:GetState()
				if VRService.VREnabled and humanoidStateType == STATE_DEAD and cameraSubject == this.lastSubject then
					result = this.lastSubjectPosition
				else
					local humanoidRootPart = getHumanoidPartToFollow(cameraSubject, humanoidStateType)
					if humanoidRootPart and humanoidRootPart:IsA('BasePart') then
						local subjectCFrame = GetRenderCFrame(humanoidRootPart)
						local heightOffset = ZERO_VECTOR3
						if humanoidStateType ~= STATE_DEAD then
							heightOffset = cameraSubject.RigType == Enum.HumanoidRigType.R15 and R15HeadHeight or HEAD_OFFSET
						end

						if PortraitMode then
							heightOffset = heightOffset + Vector3.new(0, PORTRAIT_MODE_CAMERA_OFFSET, 0)
						end

						result = subjectCFrame.p +
							subjectCFrame:vectorToWorldSpace(heightOffset + cameraSubject.CameraOffset)
					end
				end
			elseif cameraSubject:IsA('VehicleSeat') then
				local subjectCFrame = GetRenderCFrame(cameraSubject)
				local offset = SEAT_OFFSET
				if VRService.VREnabled then
					offset = VR_SEAT_OFFSET
				end
				result = subjectCFrame.p + subjectCFrame:vectorToWorldSpace(offset)
			elseif cameraSubject:IsA('SkateboardPlatform') then
				local subjectCFrame = GetRenderCFrame(cameraSubject)
				result = subjectCFrame.p + SEAT_OFFSET
			elseif cameraSubject:IsA('BasePart') then
				local subjectCFrame = GetRenderCFrame(cameraSubject)
				result = subjectCFrame.p
			elseif cameraSubject:IsA('Model') then
				result = cameraSubject:GetModelCFrame().p
			end
		end
		this.lastSubject = cameraSubject
		this.lastSubjectPosition = result
		return result
	end

	function this:ResetCameraLook()
	end

	function this:GetCameraLook()
		return workspace.CurrentCamera and workspace.CurrentCamera.CoordinateFrame.lookVector or Vector3.new(0,0,1)
	end

	function this:GetCameraZoom()
		if this.currentZoom == nil then
			local player = PlayersService.LocalPlayer
			this.currentZoom = player and clamp(player.CameraMinZoomDistance, player.CameraMaxZoomDistance, this.DefaultZoom) or this.DefaultZoom
		end
		return this.currentZoom
	end

	function this:GetCameraActualZoom()
		local camera = workspace.CurrentCamera
		if camera then
			return (camera.CoordinateFrame.p - camera.Focus.p).magnitude
		end
	end

	function this:GetCameraHeight()
		if VRService.VREnabled and not this:IsInFirstPerson() then
			local zoom = this:GetCameraZoom()
			return math.sin(VR_ANGLE) * zoom
		end
		return 0
	end

	function this:ViewSizeX()
		local result = 1024
		local camera = workspace.CurrentCamera
		if camera then
			result = camera.ViewportSize.X
		end
		return result
	end

	function this:ViewSizeY()
		local result = 768
		local camera = workspace.CurrentCamera
		if camera then
			result = camera.ViewportSize.Y
		end
		return result
	end

	local math_asin = math.asin
	local math_atan2 = math.atan2
	local math_floor = math.floor
	local math_max = math.max
	local math_pi = math.pi
	local Vector2_new = Vector2.new
	local Vector3_new = Vector3.new
	local CFrame_Angles = CFrame.Angles
	local CFrame_new = CFrame.new

	function this:ScreenTranslationToAngle(translationVector)
		local screenX = this:ViewSizeX()
		local screenY = this:ViewSizeY()
		local xTheta = (translationVector.x / screenX)
		local yTheta = (translationVector.y / screenY)
		return Vector2_new(xTheta, yTheta)
	end

	function this:MouseTranslationToAngle(translationVector)
		local xTheta = (translationVector.x / 1920)
		local yTheta = (translationVector.y / 1200)
		return Vector2_new(xTheta, yTheta)
	end

	function this:RotateVector(startVector, xyRotateVector)
		local startCFrame = CFrame_new(ZERO_VECTOR3, startVector)
		local resultLookVector = (CFrame_Angles(0, -xyRotateVector.x, 0) * startCFrame * CFrame_Angles(-xyRotateVector.y,0,0)).lookVector
		return resultLookVector, Vector2_new(xyRotateVector.x, xyRotateVector.y)
	end

	function this:RotateCamera(startLook, xyRotateVector)
		if VRService.VREnabled then
			local yawRotatedVector, xyRotateVector = self:RotateVector(startLook, Vector2.new(xyRotateVector.x, 0))
			return Vector3_new(yawRotatedVector.x, 0, yawRotatedVector.z).unit, xyRotateVector
		else
			local startVertical = math_asin(startLook.y)
			local yTheta = clamp(-MAX_Y + startVertical, -MIN_Y + startVertical, xyRotateVector.y)
			return self:RotateVector(startLook, Vector2_new(xyRotateVector.x, yTheta))
		end
	end

	function this:IsInFirstPerson()
		return isFirstPerson
	end

	-- there are several cases to consider based on the state of input and camera rotation mode
	function this:UpdateMouseBehavior()
		-- first time transition to first person mode or shiftlock
		local camera = workspace.CurrentCamera
		if camera.CameraType == Enum.CameraType.Scriptable then
			return
		end

		if isFirstPerson or self:GetShiftLock() then
			pcall(function() GameSettings.RotationType = Enum.RotationType.CameraRelative end)
			if UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then
				UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
			end
		else
			pcall(function() GameSettings.RotationType = Enum.RotationType.MovementRelative end)
			if isRightMouseDown or isMiddleMouseDown then
				UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
			else
				UserInputService.MouseBehavior = Enum.MouseBehavior.Default
			end
		end
	end

	function this:ZoomCamera(desiredZoom)
		local player = PlayersService.LocalPlayer
		if player then
			if player.CameraMode == Enum.CameraMode.LockFirstPerson then
				this.currentZoom = 0
			else
				this.currentZoom = clamp(player.CameraMinZoomDistance, player.CameraMaxZoomDistance, desiredZoom)
			end
		end

		isFirstPerson = self:GetCameraZoom() < 2

		ShiftLockController:SetIsInFirstPerson(isFirstPerson)
		-- set mouse behavior
		self:UpdateMouseBehavior()
		return self:GetCameraZoom()
	end

	function this:rk4Integrator(position, velocity, t)
		local direction = velocity < 0 and -1 or 1
		local function acceleration(p, v)
			local accel = direction * math_max(1, (p / 3.3) + 0.5)
			return accel
		end

		local p1 = position
		local v1 = velocity
		local a1 = acceleration(p1, v1)
		local p2 = p1 + v1 * (t / 2)
		local v2 = v1 + a1 * (t / 2)
		local a2 = acceleration(p2, v2)
		local p3 = p1 + v2 * (t / 2)
		local v3 = v1 + a2 * (t / 2)
		local a3 = acceleration(p3, v3)
		local p4 = p1 + v3 * t
		local v4 = v1 + a3 * t
		local a4 = acceleration(p4, v4)

		local positionResult = position + (v1 + 2 * v2 + 2 * v3 + v4) * (t / 6)
		local velocityResult = velocity + (a1 + 2 * a2 + 2 * a3 + a4) * (t / 6)
		return positionResult, velocityResult
	end

	function this:ZoomCameraBy(zoomScale)
		local zoom = this:GetCameraActualZoom()

		if zoom then
			-- Can break into more steps to get more accurate integration
            zoom = self:rk4Integrator(zoom, zoomScale, 1)
			self:ZoomCamera(zoom)
		end
		return self:GetCameraZoom()
	end

	function this:ZoomCameraFixedBy(zoomIncrement)
		return self:ZoomCamera(self:GetCameraZoom() + zoomIncrement)
	end

	function this:Update()
	end

	----- VR STUFF ------

	function this:ApplyVRTransform()
		if not VRService.VREnabled then
			return
		end
		--we only want this to happen in first person VR
		local player = PlayersService.LocalPlayer
		if not (player and player.Character
				and player.Character:FindFirstChild("HumanoidRootPart")
				and player.Character.HumanoidRootPart:FindFirstChild("RootJoint")) then
			return
		end

		local camera = workspace.CurrentCamera
		local cameraSubject = camera.CameraSubject
		local isInVehicle = cameraSubject and cameraSubject:IsA('VehicleSeat')

		if this:IsInFirstPerson() and not isInVehicle then
			local vrFrame = VRService:GetUserCFrame(Enum.UserCFrame.Head)
			local vrRotation = vrFrame - vrFrame.p
			local rootJoint = player.Character.HumanoidRootPart.RootJoint
			rootJoint.C0 = CFrame.new(vrRotation:vectorToObjectSpace(vrFrame.p)) * CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
		else
			local rootJoint = player.Character.HumanoidRootPart.RootJoint
			rootJoint.C0 = CFrame.new(0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 1, 0)
		end
	end

	local vrRotationIntensityExists = true
	local lastVrRotationCheck = 0
	function this:ShouldUseVRRotation()
		if not VRService.VREnabled then
			return false
		end
		if not vrRotationIntensityExists and tick() - lastVrRotationCheck < 1 then return false end

		local success, vrRotationIntensity = pcall(function() return StarterGui:GetCore("VRRotationIntensity") end)
		vrRotationIntensityExists = success and vrRotationIntensity ~= nil
		lastVrRotationCheck = tick()

		return success and vrRotationIntensity ~= nil and vrRotationIntensity ~= "Smooth"
	end

	function this:GetVRRotationInput()
		local vrRotateSum = ZERO_VECTOR2

		local vrRotationIntensity = StarterGui:GetCore("VRRotationIntensity")

		local vrGamepadRotation = self.GamepadPanningCamera or ZERO_VECTOR2
		local delayExpired = (tick() - lastVRRotation) >= self:GetRepeatDelayValue(vrRotationIntensity)

		if math.abs(vrGamepadRotation.x) >= self:GetActivateValue() then
			if (delayExpired or not vrRotateKeyCooldown[Enum.KeyCode.Thumbstick2]) then
				local sign = 1
				if vrGamepadRotation.x < 0 then
					sign = -1
				end
				vrRotateSum = vrRotateSum + self:GetRotateAmountValue(vrRotationIntensity) * sign
				vrRotateKeyCooldown[Enum.KeyCode.Thumbstick2] = true
			end
		elseif math.abs(vrGamepadRotation.x) < self:GetActivateValue() - 0.1 then
			vrRotateKeyCooldown[Enum.KeyCode.Thumbstick2] = nil
		end
		if self.TurningLeft then
			if delayExpired or not vrRotateKeyCooldown[Enum.KeyCode.Left] then
				vrRotateSum = vrRotateSum - self:GetRotateAmountValue(vrRotationIntensity)
				vrRotateKeyCooldown[Enum.KeyCode.Left] = true
			end
		else
			vrRotateKeyCooldown[Enum.KeyCode.Left] = nil
		end
		if self.TurningRight then
			if (delayExpired or not vrRotateKeyCooldown[Enum.KeyCode.Right]) then
				vrRotateSum = vrRotateSum + self:GetRotateAmountValue(vrRotationIntensity)
				vrRotateKeyCooldown[Enum.KeyCode.Right] = true
			end
		else
			vrRotateKeyCooldown[Enum.KeyCode.Right] = nil
		end

		if vrRotateSum ~= ZERO_VECTOR2 then
			lastVRRotation = tick()
		end

		return vrRotateSum
	end

	local cameraTranslationConstraints = Vector3.new(1, 1, 1)
	local humanoidJumpOrigin = nil
	local trackingHumanoid = nil
	local cameraFrozen = false
	local subjectStateChangedConn = nil
	local cameraSubjectChangedConn = nil
	local workspaceChangedConn = nil
	local humanoidChildAddedConn = nil
	local humanoidChildRemovedConn = nil

	local function cancelCameraFreeze(keepConstraints)
		if not keepConstraints then
			cameraTranslationConstraints = Vector3.new(cameraTranslationConstraints.x, 1, cameraTranslationConstraints.z)
		end
		if cameraFrozen then
			trackingHumanoid = nil
			cameraFrozen = false
		end
	end

	local function startCameraFreeze(subjectPosition, humanoidToTrack)
		if not cameraFrozen then
			humanoidJumpOrigin = subjectPosition
			trackingHumanoid = humanoidToTrack
			cameraTranslationConstraints = Vector3.new(cameraTranslationConstraints.x, 0, cameraTranslationConstraints.z)
			cameraFrozen = true
		end
	end

	local function rescaleCameraOffset(newScaleFactor)
		R15HeadHeight = R15_HEAD_OFFSET*newScaleFactor
	end

	local function onHumanoidSubjectChildAdded(child)
		if child.Name == "BodyHeightScale" and child:IsA("NumberValue") then
			if heightScaleChangedConn then
				heightScaleChangedConn:disconnect()
			end
			heightScaleChangedConn = child.Changed:connect(rescaleCameraOffset)
			rescaleCameraOffset(child.Value)
		end
	end

	local function onHumanoidSubjectChildRemoved(child)
		if child.Name == "BodyHeightScale" then
			rescaleCameraOffset(1)
			if heightScaleChangedConn then
				heightScaleChangedConn:disconnect()
				heightScaleChangedConn = nil
			end
		end
	end

	local function onNewCameraSubject()
		if subjectStateChangedConn then
			subjectStateChangedConn:disconnect()
			subjectStateChangedConn = nil
		end
		if humanoidChildAddedConn then
			humanoidChildAddedConn:disconnect()
			humanoidChildAddedConn = nil
		end
		if humanoidChildRemovedConn then
			humanoidChildRemovedConn:disconnect()
			humanoidChildRemovedConn = nil
		end
		if heightScaleChangedConn then
			heightScaleChangedConn:disconnect()
			heightScaleChangedConn = nil
		end

		local humanoid = workspace.CurrentCamera and workspace.CurrentCamera.CameraSubject
		if trackingHumanoid ~= humanoid then
			cancelCameraFreeze()
		end
		if humanoid and humanoid:IsA('Humanoid') then
			humanoidChildAddedConn = humanoid.ChildAdded:connect(onHumanoidSubjectChildAdded)
			humanoidChildRemovedConn = humanoid.ChildRemoved:connect(onHumanoidSubjectChildRemoved)
			for _, child in pairs(humanoid:GetChildren()) do
				onHumanoidSubjectChildAdded(child)
			end

			subjectStateChangedConn = humanoid.StateChanged:connect(function(oldState, newState)
				if VRService.VREnabled and newState == Enum.HumanoidStateType.Jumping and not this:IsInFirstPerson() then
					startCameraFreeze(this:GetSubjectPosition(), humanoid)
				elseif newState ~= Enum.HumanoidStateType.Jumping and newState ~= Enum.HumanoidStateType.Freefall then
					cancelCameraFreeze(true)
				end
			end)
		end
	end

 	local function onCurrentCameraChanged()
		if cameraSubjectChangedConn then
			cameraSubjectChangedConn:disconnect()
			cameraSubjectChangedConn = nil
		end
  		local camera = workspace.CurrentCamera
  		if camera then
			cameraSubjectChangedConn = camera:GetPropertyChangedSignal("CameraSubject"):connect(onNewCameraSubject)
			onNewCameraSubject()
  		end
  	end

	function this:GetVRFocus(subjectPosition, timeDelta)
		local newFocus = nil

		local camera = workspace.CurrentCamera
		local lastFocus = self.LastCameraFocus or subjectPosition
		if not cameraFrozen then
			cameraTranslationConstraints = Vector3.new(cameraTranslationConstraints.x, math.min(1, cameraTranslationConstraints.y + 0.42 * timeDelta), cameraTranslationConstraints.z)
		end
		if cameraFrozen and humanoidJumpOrigin and humanoidJumpOrigin.y > lastFocus.y then
			newFocus = CFrame.new(Vector3.new(subjectPosition.x, math.min(humanoidJumpOrigin.y, lastFocus.y + 5 * timeDelta), subjectPosition.z))
		else
			newFocus = CFrame.new(Vector3.new(subjectPosition.x, lastFocus.y, subjectPosition.z):lerp(subjectPosition, cameraTranslationConstraints.y))
		end

		if cameraFrozen then
			-- No longer in 3rd person
			if self:IsInFirstPerson() then -- not VRService.VREnabled
				cancelCameraFreeze()
			end
			-- This case you jumped off a cliff and want to keep your character in view
			-- 0.5 is to fix floating point error when not jumping off cliffs
			if humanoidJumpOrigin and subjectPosition.y < (humanoidJumpOrigin.y - 0.5) then
				cancelCameraFreeze()
			end
		end

		return newFocus
	end

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

	---- Input Events ----
	local startPos = nil
	local lastPos = nil
	local panBeginLook = nil
	local lastTapTime = nil

	local fingerTouches = {}
	local NumUnsunkTouches = 0

	local inputStartPositions = {}
	local inputStartTimes = {}

	local StartingDiff = nil
	local pinchBeginZoom = nil

	this.ZoomEnabled = true
	this.PanEnabled = true
	this.KeyPanEnabled = true

	local function OnTouchBegan(input, processed)
		--If isDynamicThumbstickEnabled, then only process TouchBegan event if it starts in GestureArea

		local dtFrame = getDynamicThumbstickFrame()
		if (not touchWorkspaceEventEnabled and not isDynamicThumbstickEnabled) or positionIntersectsGuiObject(input.Position, GestureArea) and (not dtFrame or not positionIntersectsGuiObject(input.Position, dtFrame)) then
			fingerTouches[input] = processed
			if not processed then
				inputStartPositions[input] = input.Position
				inputStartTimes[input] = tick()
				NumUnsunkTouches = NumUnsunkTouches + 1
			end
		end
	end

	local function OnTouchChanged(input, processed)

		if fingerTouches[input] == nil then
			if isDynamicThumbstickEnabled then
				return
			end
			fingerTouches[input] = processed
			if not processed then
				NumUnsunkTouches = NumUnsunkTouches + 1
			end
		end

		if NumUnsunkTouches == 1 then
			if fingerTouches[input] == false then
				panBeginLook = panBeginLook or this:GetCameraLook()
				startPos = startPos or input.Position
				lastPos = lastPos or startPos
				this.UserPanningTheCamera = true

				local delta = input.Position - lastPos

				delta = Vector2.new(delta.X, delta.Y * GameSettings:GetCameraYInvertValue())

				if this.PanEnabled then
					local desiredXYVector = this:ScreenTranslationToAngle(delta) * TOUCH_SENSITIVTY
					this.RotateInput = this.RotateInput + desiredXYVector
				end

				lastPos = input.Position
			end
		else
			panBeginLook = nil
			startPos = nil
			lastPos = nil
			this.UserPanningTheCamera = false
		end
		if NumUnsunkTouches == 2 then
			local unsunkTouches = {}
			for touch, wasSunk in pairs(fingerTouches) do
				if not wasSunk then
					table.insert(unsunkTouches, touch)
				end
			end
			if #unsunkTouches == 2 then
				local difference = (unsunkTouches[1].Position - unsunkTouches[2].Position).magnitude
				if StartingDiff and pinchBeginZoom then
					local scale = difference / math_max(0.01, StartingDiff)
					local clampedScale = clamp(0.1, 10, scale)
					if this.ZoomEnabled then
						this:ZoomCamera(pinchBeginZoom / clampedScale)
					end
				else
					StartingDiff = difference
					pinchBeginZoom = this:GetCameraActualZoom()
				end
			end
		else
			StartingDiff = nil
			pinchBeginZoom = nil
		end
	end

	local function calcLookBehindRotateInput(torso)
		if torso then
			local newDesiredLook = (torso.CFrame.lookVector - Vector3.new(0, math.sin(math.rad(DEFAULT_CAMERA_ANGLE), 0))).unit
			local horizontalShift = findAngleBetweenXZVectors(newDesiredLook, this:GetCameraLook())
			local vertShift = math.asin(this:GetCameraLook().y) - math.asin(newDesiredLook.y)
			if not IsFinite(horizontalShift) then
				horizontalShift = 0
			end
			if not IsFinite(vertShift) then
				vertShift = 0
			end

			return Vector2.new(horizontalShift, vertShift)
		end
		return nil
	end

	local OnTouchTap = nil
	if not touchWorkspaceEventEnabled then
		OnTouchTap = function(position)
			if isDynamicThumbstickEnabled and not IsAToolEquipped then
				if lastTapTime and tick() - lastTapTime < MAX_TIME_FOR_DOUBLE_TAP then
					local tween = {
						from = this:GetCameraZoom(),
						to = DefaultZoom,
						start = tick(),
						duration = 0.2,
						func = function(from, to, alpha)
							this:ZoomCamera(from + (to - from)*alpha)
							return to
						end
					}
					tweens["Zoom"] = tween
				else
					local humanoid = this:GetHumanoid()
					if humanoid then
						local player = PlayersService.LocalPlayer
						if player and player.Character then
							if humanoid and humanoid.Torso then
								local tween = {
									from = this.RotateInput,
									to = calcLookBehindRotateInput(humanoid.Torso),
									start = tick(),
									duration = 0.2,
									func = function(from, to, alpha)
										to = calcLookBehindRotateInput(humanoid.Torso)
										if to then
											this.RotateInput = from + (to - from)*alpha
										end
										return to
									end
								}
								tweens["Rotate"] = tween

								-- reset old camera info so follow cam doesn't rotate us
								this.LastCameraTransform = nil
							end
						end
					end
				end
				lastTapTime = tick()
			end
		end
	end

	local function IsTouchTap(input)
		-- We can't make the assumption that the input exists in the inputStartPositions because we may have switched from a different camera type.
		if inputStartPositions[input] then
			local posDelta = (inputStartPositions[input] - input.Position).magnitude
			if posDelta < MAX_TAP_POS_DELTA then
				local timeDelta = inputStartTimes[input] - tick()
				if timeDelta < MAX_TAP_TIME_DELTA then
					return true
				end
			end
		end
		return false
	end

	local function OnTouchEnded(input, processed)
		if fingerTouches[input] == false then
			if NumUnsunkTouches == 1 then
				panBeginLook = nil
				startPos = nil
				lastPos = nil
				this.UserPanningTheCamera = false
				if not touchWorkspaceEventEnabled and IsTouchTap(input) then
					OnTouchTap(input.Position)
				end
			elseif NumUnsunkTouches == 2 then
				StartingDiff = nil
				pinchBeginZoom = nil
			end
		end

		if fingerTouches[input] ~= nil and fingerTouches[input] == false then
			NumUnsunkTouches = NumUnsunkTouches - 1
		end
		fingerTouches[input] = nil
		inputStartPositions[input] = nil
		inputStartTimes[input] = nil
	end

	local function OnMousePanButtonPressed(input, processed)
		if processed then return end
		this:UpdateMouseBehavior()
		panBeginLook = panBeginLook or this:GetCameraLook()
		startPos = startPos or input.Position
		lastPos = lastPos or startPos
		this.UserPanningTheCamera = true
	end

	local function OnMousePanButtonReleased(input, processed)
		this:UpdateMouseBehavior()
		if not (isRightMouseDown or isMiddleMouseDown) then
			panBeginLook = nil
			startPos = nil
			lastPos = nil
			this.UserPanningTheCamera = false
		end
	end

	local function OnMouse2Down(input, processed)
		if processed then return end

		isRightMouseDown = true
		OnMousePanButtonPressed(input, processed)
	end

	local function OnMouse2Up(input, processed)
		isRightMouseDown = false
		OnMousePanButtonReleased(input, processed)
	end

	local function OnMouse3Down(input, processed)
		if processed then return end

		isMiddleMouseDown = true
		OnMousePanButtonPressed(input, processed)
	end

	local function OnMouse3Up(input, processed)
		isMiddleMouseDown = false
		OnMousePanButtonReleased(input, processed)
	end

	local function OnMouseMoved(input, processed)
		if not hasGameLoaded and VRService.VREnabled then
			return
		end

		local inputDelta = input.Delta
		inputDelta = Vector2.new(inputDelta.X, inputDelta.Y * GameSettings:GetCameraYInvertValue())

		if startPos and lastPos and panBeginLook then
			local currPos = lastPos + input.Delta
			local totalTrans = currPos - startPos
			if this.PanEnabled then
				local desiredXYVector = this:MouseTranslationToAngle(inputDelta) * MOUSE_SENSITIVITY
				this.RotateInput = this.RotateInput + desiredXYVector
			end
			lastPos = currPos
		elseif this:IsInFirstPerson() or this:GetShiftLock() then
			if this.PanEnabled then
				local desiredXYVector = this:MouseTranslationToAngle(inputDelta) * MOUSE_SENSITIVITY
				this.RotateInput = this.RotateInput + desiredXYVector
			end
		end
	end

	local function OnMouseWheel(input, processed)
		if not hasGameLoaded and VRService.VREnabled then
			return
		end
		if not processed then
			if this.ZoomEnabled then
                this:ZoomCameraBy(clamp(-1, 1, -input.Position.Z) * 1.4)
			end
		end
	end

	local function round(num)
		return math_floor(num + 0.5)
	end

	local eight2Pi = math_pi / 4

	local function rotateVectorByAngleAndRound(camLook, rotateAngle, roundAmount)
		if camLook ~= ZERO_VECTOR3 then
			camLook = camLook.unit
			local currAngle = math_atan2(camLook.z, camLook.x)
			local newAngle = round((math_atan2(camLook.z, camLook.x) + rotateAngle) / roundAmount) * roundAmount
			return newAngle - currAngle
		end
		return 0
	end

	local function OnKeyDown(input, processed)
		if not hasGameLoaded and VRService.VREnabled then
			return
		end
		if processed then return end
		if this.ZoomEnabled then
			if input.KeyCode == Enum.KeyCode.I then
				this:ZoomCameraBy(-5)
			elseif input.KeyCode == Enum.KeyCode.O then
				this:ZoomCameraBy(5)
			end
		end
		if panBeginLook == nil and this.KeyPanEnabled then
			if input.KeyCode == Enum.KeyCode.Left then
				this.TurningLeft = true
			elseif input.KeyCode == Enum.KeyCode.Right then
				this.TurningRight = true
			elseif input.KeyCode == Enum.KeyCode.Comma then
				local angle = rotateVectorByAngleAndRound(this:GetCameraLook() * Vector3.new(1,0,1), -eight2Pi * (3/4), eight2Pi)
				if angle ~= 0 then
					this.RotateInput = this.RotateInput + Vector2.new(angle, 0)
					this.LastUserPanCamera = tick()
					this.LastCameraTransform = nil
				end
			elseif input.KeyCode == Enum.KeyCode.Period then
				local angle = rotateVectorByAngleAndRound(this:GetCameraLook() * Vector3.new(1,0,1), eight2Pi * (3/4), eight2Pi)
				if angle ~= 0 then
					this.RotateInput = this.RotateInput + Vector2.new(angle, 0)
					this.LastUserPanCamera = tick()
					this.LastCameraTransform = nil
				end
			elseif input.KeyCode == Enum.KeyCode.PageUp then
			--elseif input.KeyCode == Enum.KeyCode.Home then
				this.RotateInput = this.RotateInput + Vector2.new(0,math.rad(15))
				this.LastCameraTransform = nil
			elseif input.KeyCode == Enum.KeyCode.PageDown then
			--elseif input.KeyCode == Enum.KeyCode.End then
				this.RotateInput = this.RotateInput + Vector2.new(0,math.rad(-15))
				this.LastCameraTransform = nil
			end
		end
	end

	local function OnKeyUp(input, processed)
		if input.KeyCode == Enum.KeyCode.Left then
			this.TurningLeft = false
		elseif input.KeyCode == Enum.KeyCode.Right then
			this.TurningRight = false
		end
	end

	local function onWindowFocusReleased()
		this:ResetInputStates()
	end

	local lastThumbstickRotate = nil
	local numOfSeconds = 0.7
	local currentSpeed = 0
	local maxSpeed = 6
	local vrMaxSpeed = 4
	local lastThumbstickPos = Vector2.new(0,0)
	local ySensitivity = 0.65
	local lastVelocity = nil

	-- K is a tunable parameter that changes the shape of the S-curve
	-- the larger K is the more straight/linear the curve gets
	local k = 0.35
	local lowerK = 0.8
	local function SCurveTranform(t)
		t = clamp(-1,1,t)
		if t >= 0 then
			return (k*t) / (k - t + 1)
		end
		return -((lowerK*-t) / (lowerK + t + 1))
	end

	-- DEADZONE
	local DEADZONE = 0.1
	local function toSCurveSpace(t)
		return (1 + DEADZONE) * (2*math.abs(t) - 1) - DEADZONE
	end

	local function fromSCurveSpace(t)
		return t/2 + 0.5
	end

	local function gamepadLinearToCurve(thumbstickPosition)
		local function onAxis(axisValue)
			local sign = 1
			if axisValue < 0 then
				sign = -1
			end
			local point = fromSCurveSpace(SCurveTranform(toSCurveSpace(math.abs(axisValue))))
			point = point * sign
			return clamp(-1, 1, point)
		end
		return Vector2_new(onAxis(thumbstickPosition.x), onAxis(thumbstickPosition.y))
	end

	function this:UpdateGamepad()
		local gamepadPan = this.GamepadPanningCamera
		if gamepadPan and (hasGameLoaded or not VRService.VREnabled) then
			gamepadPan = gamepadLinearToCurve(gamepadPan)
			local currentTime = tick()
			if gamepadPan.X ~= 0 or gamepadPan.Y ~= 0 then
				this.userPanningTheCamera = true
			elseif gamepadPan == ZERO_VECTOR2 then
				lastThumbstickRotate = nil
				if lastThumbstickPos == ZERO_VECTOR2 then
					currentSpeed = 0
				end
			end

			local finalConstant = 0

			if lastThumbstickRotate then
				if VRService.VREnabled then
					currentSpeed = vrMaxSpeed
				else
					local elapsedTime = (currentTime - lastThumbstickRotate) * 10
					currentSpeed = currentSpeed + (maxSpeed * ((elapsedTime*elapsedTime)/numOfSeconds))

					if currentSpeed > maxSpeed then currentSpeed = maxSpeed end

					if lastVelocity then
						local velocity = (gamepadPan - lastThumbstickPos)/(currentTime - lastThumbstickRotate)
						local velocityDeltaMag = (velocity - lastVelocity).magnitude

						if velocityDeltaMag > 12 then
							currentSpeed = currentSpeed * (20/velocityDeltaMag)
							if currentSpeed > maxSpeed then currentSpeed = maxSpeed end
						end
					end
				end

				local success, gamepadCameraSensitivity = pcall(function() return GameSettings.GamepadCameraSensitivity end)
				finalConstant = success and (gamepadCameraSensitivity * currentSpeed) or currentSpeed
				lastVelocity = (gamepadPan - lastThumbstickPos)/(currentTime - lastThumbstickRotate)
			end

			lastThumbstickPos = gamepadPan
			lastThumbstickRotate = currentTime

			return Vector2_new( gamepadPan.X * finalConstant, gamepadPan.Y * finalConstant * ySensitivity * GameSettings:GetCameraYInvertValue())
		end

		return ZERO_VECTOR2
	end

	local InputBeganConn, InputChangedConn, InputEndedConn, WindowUnfocusConn, MenuOpenedConn, ShiftLockToggleConn, GamepadConnectedConn, GamepadDisconnectedConn, TouchActivateConn = nil, nil, nil, nil, nil, nil, nil, nil, nil

	function this:DisconnectInputEvents()
		if InputBeganConn then
			InputBeganConn:disconnect()
			InputBeganConn = nil
		end
		if InputChangedConn then
			InputChangedConn:disconnect()
			InputChangedConn = nil
		end
		if InputEndedConn then
			InputEndedConn:disconnect()
			InputEndedConn = nil
		end
		if WindowUnfocusConn then
			WindowUnfocusConn:disconnect()
			WindowUnfocusConn = nil
		end
		if MenuOpenedConn then
			MenuOpenedConn:disconnect()
			MenuOpenedConn = nil
		end
		if ShiftLockToggleConn then
			ShiftLockToggleConn:disconnect()
			ShiftLockToggleConn = nil
		end
		if GamepadConnectedConn then
			GamepadConnectedConn:disconnect()
			GamepadConnectedConn = nil
		end
		if GamepadDisconnectedConn then
			GamepadDisconnectedConn:disconnect()
			GamepadDisconnectedConn = nil
		end
		if subjectStateChangedConn then
			subjectStateChangedConn:disconnect()
			subjectStateChangedConn = nil
		end
		if workspaceChangedConn then
			workspaceChangedConn:disconnect()
			workspaceChangedConn = nil
		end
		if TouchActivateConn then
			TouchActivateConn:disconnect()
			TouchActivateConn = nil
		end

		this.TurningLeft = false
		this.TurningRight = false
		this.LastCameraTransform = nil
		self.LastSubjectCFrame = nil
		this.UserPanningTheCamera = false
		this.RotateInput = Vector2.new()
		this.GamepadPanningCamera = Vector2.new(0,0)

		-- Reset input states
		startPos = nil
		lastPos = nil
		panBeginLook = nil
		isRightMouseDown = false
		isMiddleMouseDown = false

		fingerTouches = {}
		NumUnsunkTouches = 0

		StartingDiff = nil
		pinchBeginZoom = nil

		-- Unlock mouse for example if right mouse button was being held down
		if UserInputService.MouseBehavior ~= Enum.MouseBehavior.LockCenter then
			UserInputService.MouseBehavior = Enum.MouseBehavior.Default
		end
	end

	function this:ResetInputStates()
		isRightMouseDown = false
		isMiddleMouseDown = false
		this.TurningRight = false
		this.TurningLeft = false
		OnMousePanButtonReleased() -- this function doesn't seem to actually need parameters

		if UserInputService.TouchEnabled then
			--[[menu opening was causing serious touch issues
			this should disable all active touch events if
			they're active when menu opens.]]
			for inputObject, value in pairs(fingerTouches) do
				fingerTouches[inputObject] = nil
			end
			panBeginLook = nil
			startPos = nil
			lastPos = nil
			this.UserPanningTheCamera = false
			StartingDiff = nil
			pinchBeginZoom = nil
			NumUnsunkTouches = 0
		end
	end

	function this.getGamepadPan(name, state, input)
		if state == Enum.UserInputState.Cancel then
			this.GamepadPanningCamera = ZERO_VECTOR2
			return
		end

		if input.UserInputType == this.activeGamepad and input.KeyCode == Enum.KeyCode.Thumbstick2 then
			local inputVector = Vector2.new(input.Position.X, -input.Position.Y)
			if inputVector.magnitude > THUMBSTICK_DEADZONE then
				this.GamepadPanningCamera = Vector2_new(input.Position.X, -input.Position.Y)
			else
				this.GamepadPanningCamera = ZERO_VECTOR2
			end
		end
	end

	function this.doGamepadZoom(name, state, input)
		if input.UserInputType == this.activeGamepad and input.KeyCode == Enum.KeyCode.ButtonR3 and state == Enum.UserInputState.Begin then
			if this.ZoomEnabled then
				if this:GetCameraZoom() > 0.5 then
					this:ZoomCamera(0)
				else
					this:ZoomCamera(10)
				end
			end
		end
	end

	function this:BindGamepadInputActions()
		ContextActionService:BindAction("RootCamGamepadPan", this.getGamepadPan, false, Enum.KeyCode.Thumbstick2)
		ContextActionService:BindAction("RootCamGamepadZoom", this.doGamepadZoom, false, Enum.KeyCode.ButtonR3)
	end

	function this:ConnectInputEvents()
		InputBeganConn = UserInputService.InputBegan:connect(function(input, processed)
			if input.UserInputType == Enum.UserInputType.Touch then
				OnTouchBegan(input, processed)
			elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
				OnMouse2Down(input, processed)
			elseif input.UserInputType == Enum.UserInputType.MouseButton3 then
				OnMouse3Down(input, processed)
			end
			-- Keyboard
			if input.UserInputType == Enum.UserInputType.Keyboard then
				OnKeyDown(input, processed)
			end
		end)

		InputChangedConn = UserInputService.InputChanged:connect(function(input, processed)
			if input.UserInputType == Enum.UserInputType.Touch then
				OnTouchChanged(input, processed)
			elseif input.UserInputType == Enum.UserInputType.MouseMovement then
				OnMouseMoved(input, processed)
			elseif input.UserInputType == Enum.UserInputType.MouseWheel then
				OnMouseWheel(input, processed)
			end
		end)

		InputEndedConn = UserInputService.InputEnded:connect(function(input, processed)
			if input.UserInputType == Enum.UserInputType.Touch then
				OnTouchEnded(input, processed)
			elseif input.UserInputType == Enum.UserInputType.MouseButton2 then
				OnMouse2Up(input, processed)
			elseif input.UserInputType == Enum.UserInputType.MouseButton3 then
				OnMouse3Up(input, processed)
			end
			-- Keyboard
			if input.UserInputType == Enum.UserInputType.Keyboard then
				OnKeyUp(input, processed)
			end
		end)

		WindowUnfocusConn = UserInputService.WindowFocusReleased:connect(onWindowFocusReleased)

		MenuOpenedConn = GuiService.MenuOpened:connect(function()
			this:ResetInputStates()
		end)

		workspaceChangedConn = workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(onCurrentCameraChanged)
		if workspace.CurrentCamera then
			onCurrentCameraChanged()
		end

		ShiftLockToggleConn = ShiftLockController.OnShiftLockToggled.Event:connect(function()
			this:UpdateMouseBehavior()
		end)

		this.RotateInput = Vector2.new()

		this.activeGamepad = nil
		local function assignActivateGamepad()
			local connectedGamepads = UserInputService:GetConnectedGamepads()
			if #connectedGamepads > 0 then
				for i = 1, #connectedGamepads do
					if this.activeGamepad == nil then
						this.activeGamepad = connectedGamepads[i]
					elseif connectedGamepads[i].Value < this.activeGamepad.Value then
						this.activeGamepad = connectedGamepads[i]
					end
				end
			end

			if this.activeGamepad == nil then -- nothing is connected, at least set up for gamepad1
				this.activeGamepad = Enum.UserInputType.Gamepad1
			end
		end

		GamepadConnectedConn = UserInputService.GamepadDisconnected:connect(function(gamepadEnum)
			if this.activeGamepad ~= gamepadEnum then return end
			this.activeGamepad = nil
			assignActivateGamepad()
		end)

		GamepadDisconnectedConn = UserInputService.GamepadConnected:connect(function(gamepadEnum)
			if this.activeGamepad == nil then
				assignActivateGamepad()
			end
		end)

		self:BindGamepadInputActions()

		assignActivateGamepad()

		-- set mouse behavior
		self:UpdateMouseBehavior()
	end

	--Process tweens related to tap-to-recenter and double-tap-to-zoom
	--Needs to be called from specific cameras on each update
	function this:ProcessTweens()
		for name, tween in pairs(tweens) do
			local alpha = math.min(1.0, (tick() - tween.start)/tween.duration)
			tween.to = tween.func(tween.from, tween.to, alpha)
			if math.abs(1 - alpha) < 0.0001 then
				tweens[name] = nil
			end
		end
	end

	function this:SetEnabled(newState)
		if newState ~= self.Enabled then
			self.Enabled = newState
			if self.Enabled then
				self:ConnectInputEvents()
				self.cframe = workspace.CurrentCamera.CFrame
			else
				self:DisconnectInputEvents()
			end
		end
	end

	local function OnPlayerAdded(player)
		player.Changed:connect(function(prop)
			if this.Enabled then
				if prop == "CameraMode" or prop == "CameraMaxZoomDistance" or prop == "CameraMinZoomDistance" then
					 this:ZoomCameraFixedBy(0)
				end
			end
		end)

		local function OnCharacterAdded(newCharacter)

			local humanoid = findPlayerHumanoid(player)
			local start = tick()
			while tick() - start < 0.3 and (humanoid == nil or humanoid.Torso == nil) do
				wait()
				humanoid = findPlayerHumanoid(player)
			end

			if humanoid and humanoid.Torso and player.Character == newCharacter then
				local newDesiredLook = (humanoid.Torso.CFrame.lookVector - Vector3.new(0, math.sin(math.rad(DEFAULT_CAMERA_ANGLE)), 0)).unit
				local horizontalShift = findAngleBetweenXZVectors(newDesiredLook, this:GetCameraLook())
				local vertShift = math.asin(this:GetCameraLook().y) - math.asin(newDesiredLook.y)
				if not IsFinite(horizontalShift) then
					horizontalShift = 0
				end
				if not IsFinite(vertShift) then
					vertShift = 0
				end
				this.RotateInput = Vector2.new(horizontalShift, vertShift)

				-- reset old camera info so follow cam doesn't rotate us
				this.LastCameraTransform = nil
			end

			-- Need to wait for camera cframe to update before we zoom in
			-- Not waiting will force camera to original cframe
			wait()
			this:ZoomCamera(this.DefaultZoom)
		end

		player.CharacterAdded:connect(function(character)
			if this.Enabled or SetCameraOnSpawn then
				OnCharacterAdded(character)
				SetCameraOnSpawn = false
			end
		end)
		if player.Character then
			spawn(function() OnCharacterAdded(player.Character) end)
		end
	end
	if PlayersService.LocalPlayer then
		OnPlayerAdded(PlayersService.LocalPlayer)
	end
	PlayersService.ChildAdded:connect(function(child)
		if child and PlayersService.LocalPlayer == child then
			OnPlayerAdded(PlayersService.LocalPlayer)
		end
	end)

	local function OnGameLoaded()
		hasGameLoaded = true
	end

	spawn(function()
		if game:IsLoaded() then
			OnGameLoaded()
		else
			game.Loaded:wait()
			OnGameLoaded()
		end
	end)

	local function OnDynamicThumbstickEnabled()
		if UserInputService.TouchEnabled then
			isDynamicThumbstickEnabled = true
		end
	end

	local function OnDynamicThumbstickDisabled()
		isDynamicThumbstickEnabled = false
	end

	local function OnGameSettingsTouchMovementModeChanged()
		if LocalPlayer.DevTouchMovementMode == Enum.DevTouchMovementMode.UserChoice then
			if GameSettings.TouchMovementMode.Name == "DynamicThumbstick" then
				OnDynamicThumbstickEnabled()
			else
				OnDynamicThumbstickDisabled()
			end
		end
	end

	local function OnDevTouchMovementModeChanged()
		if LocalPlayer.DevTouchMovementMode.Name == "DynamicThumbstick" then
			OnDynamicThumbstickEnabled()
		else
			OnGameSettingsTouchMovementModeChanged()
		end
	end

	if PlayersService.LocalPlayer then
		PlayersService.LocalPlayer.Changed:Connect(function(prop)
			if prop == "DevTouchMovementMode" then
				OnDevTouchMovementModeChanged()
			end
		end)
		OnDevTouchMovementModeChanged()
	end

	GameSettings.Changed:Connect(function(prop)
		if prop == "TouchMovementMode" then
			OnGameSettingsTouchMovementModeChanged()
		end
	end)
	OnGameSettingsTouchMovementModeChanged()
	GameSettings:SetCameraYInvertVisible()
	pcall(function() GameSettings:SetGamepadCameraSensitivityVisible() end)

	return this
end

return CreateCamera


Prompt:
--edit the function below to return true when you want this response/prompt to be valid
--player is the player speaking to the dialogue, and dialogueFolder is the object containing the dialogue data

Response:
return function(player, dialogueFolder)
	local plrData = require(game.ReplicatedStorage.Source.Modules.Util):GetPlayerData(player)
	return plrData.Classes.Base.Smasher.SpokeToJex.Value
end


Prompt: --Made by Luckymaxer

Response:
Character = script.Parent
Humanoid = Character:FindFirstChild("Humanoid")

Players = game:GetService("Players")
Debris = game:GetService("Debris")

BaseUrl = "http://www.roblox.com/asset/?id="

WindDirection = script:WaitForChild("WindDirection")
Force = script:WaitForChild("Force")
Functions = require(script:WaitForChild("Functions"))

Gravity = 196.20

BasePart = Instance.new("Part")
BasePart.Shape = Enum.PartType.Block
BasePart.Material = Enum.Material.Plastic
BasePart.TopSurface = Enum.SurfaceType.Smooth
BasePart.BottomSurface = Enum.SurfaceType.Smooth
BasePart.FormFactor = Enum.FormFactor.Custom
BasePart.Size = Vector3.new(0.2, 0.2, 0.2)
BasePart.CanCollide = true
BasePart.Locked = true
BasePart.Anchored = false

DisplayParts = {}

Rate = (1 / 60)

function DestroyScript()
	Debris:AddItem(script, 0.5)
end

if not Humanoid then
	DestroyScript()
	return
end

local FakeModel = Instance.new("Model")
FakeModel.Name = "Ghost"

Objects = Functions.Redesign(Character)

for i, v in pairs(Objects) do
	v = v.Object
	if v:IsA("BasePart") then
		local FakePart = v:Clone()
		FakePart.CanCollide = false
		for ii, vv in pairs(FakePart:GetChildren()) do
			if vv:IsA("JointInstance") then
				vv:Destroy()
			end
		end
		for ii, vv in pairs(Objects) do
			vv = vv.Object
			if vv:IsA("CharacterMesh") and string.gsub(v.Name, " ", "") == vv.BodyPart.Name then
				local Mesh = Instance.new("SpecialMesh")
				Mesh.MeshType = Enum.MeshType.FileMesh
				Mesh.MeshId = (BaseUrl .. vv.MeshId)
				Mesh.TextureId = (BaseUrl .. vv.BaseTextureId)
				Mesh.Scale = Vector3.new(1, 1, 1)
				Mesh.Offset = Vector3.new(0, 0, 0)
				Mesh.VertexColor = Vector3.new(1, 1, 1)
				Mesh.Parent = FakePart
			end
		end
		FakePart.Parent = FakeModel
		v:Destroy()
	end
end

Objects = Functions.Redesign(FakeModel)

for i, v in pairs(Objects) do
	v = v.Object
	if v:IsA("BasePart") then
		local Mass = (v:GetMass() * Gravity ^ 2)
		local BodyVelocity = Instance.new("BodyVelocity")
		BodyVelocity.maxForce = Vector3.new(Mass, Mass, Mass)
		BodyVelocity.velocity = (WindDirection.Value * Force.Value)
		BodyVelocity.Parent = v
		if v.Name == "Torso" then
		end
		v.Name = "Effect"
		if v.Transparency < 1 then
			table.insert(DisplayParts, v)
		end
	elseif v:IsA("Decal") or v:IsA("Texture") then
		if v.Transparency < 1 then
			table.insert(DisplayParts, v)
		end
	end
end

Delay(0.1, (function()
	local FadeRate = 30
	for i = 1, ((1 - Functions.DarkProperties.All.Transparency) * (1 * FadeRate)) do
		for ii, vv in pairs(DisplayParts) do
			if vv and vv.Parent then
				vv.Transparency = (vv.Transparency + (1 / FadeRate))
			end
		end
		wait(Rate)
	end
	if FakeModel and FakeModel.Parent then
		FakeModel:Destroy()
	end
end))

BoundaryBox = BasePart:Clone()
BoundaryBox.Name = "Effect"
BoundaryBox.Transparency = 1
BoundaryBox.CanCollide = false
BoundaryBox.Size = FakeModel:GetModelSize()
BoundaryBox.CFrame = FakeModel:GetModelCFrame()
BoundaryBox.Parent = FakeModel

Functions.Weld(FakeModel, BoundaryBox)

Debris:AddItem(FakeModel, 10)
FakeModel.Parent = game:GetService("Workspace")


Prompt:
--[[

# Explorer Panel

A GUI panel that displays the game hierarchy.

## Selection Bindables

- `Function GetSelection ( )`

	Returns an array of objects representing the objects currently
	selected in the panel.

- `Function SetSelection ( Objects selection )`

	Sets the objects that are selected in the panel. `selection` is an array
	of objects.

- `Event SelectionChanged ( )`

	Fired after the selection changes.

## Option Bindables

- `Function GetOption ( string optionName )`

	If `optionName` is given, returns the value of that option. Otherwise,
	returns a table of options and their current values.

- `Function SetOption ( string optionName, bool value )`

	Sets `optionName` to `value`.

	Options:

	- Modifiable

		Whether objects can be modified by the panel.

		Note that modifying objects depends on being able to select them. If
		Selectable is false, then Actions will not be available. Reparenting
		is still possible, but only for the dragged object.

	- Selectable

		Whether objects can be selected.

		If Modifiable is false, then left-clicking will perform a drag
		selection.

## Updates

- 2013-09-18
	- Fixed explorer icons to match studio explorer.

- 2013-09-14
	- Added GetOption and SetOption bindables.
		- Option: Modifiable; sets whether objects can be modified by the panel.
		- Option: Selectable; sets whether objects can be selected.
	- Slight modification to left-click selection behavior.
	- Improved layout and scaling.

- 2013-09-13
	- Added drag to reparent objects.
		- Left-click to select/deselect object.
		- Left-click and drag unselected object to reparent single object.
		- Left-click and drag selected object to move reparent entire selection.
		- Right-click while dragging to cancel.

- 2013-09-11
	- Added explorer panel header with actions.
		- Added Cut action.
		- Added Copy action.
		- Added Paste action.
		- Added Delete action.
	- Added drag selection.
		- Left-click: Add to selection on drag.
		- Right-click: Add to or remove from selection on drag.
	- Ensured SelectionChanged fires only when the selection actually changes.
	- Added documentation and change log.
	- Fixed thread issue.

- 2013-09-09
	- Added basic multi-selection.
		- Left-click to set selection.
		- Right-click to add to or remove from selection.
	- Removed "Selection" ObjectValue.
		- Added GetSelection BindableFunction.
		- Added SetSelection BindableFunction.
		- Added SelectionChanged BindableEvent.
	- Changed font to SourceSans.

- 2013-08-31
	- Improved GUI sizing based off of `GUI_SIZE` constant.
	- Automatic font size detection.

- 2013-08-27
	- Initial explorer panel.

## Todo

- Sorting
	- by ExplorerOrder
	- by children
	- by name
- Drag objects to reparent

]]

Response:
local ENTRY_SIZE = GUI_SIZE + ENTRY_PADDING*2
local ENTRY_BOUND = ENTRY_SIZE + ENTRY_MARGIN
local HEADER_SIZE = ENTRY_SIZE*2

local FONT = 'SourceSans'
local FONT_SIZE do
	local size = {8,9,10,11,12,14,18,24,36,48}
	local s
	local n = math.huge
	for i = 1,#size do
		if size[i] <= GUI_SIZE then
			FONT_SIZE = i - 1
		end
	end
end

local GuiColor = {
	Background = Color3_fromRGB(37, 37, 42),
	Border = Color3_fromRGB(20, 20, 25),
	Selected = Color3_fromRGB(5, 100, 145),
	BorderSelected = Color3_fromRGB(2, 125, 145),
	Text = Color3_fromRGB(245, 245, 250),
	TextDisabled = Color3_fromRGB(190, 190, 195),
	TextSelected = Color3_fromRGB(255, 255, 255),
	Button = Color3_fromRGB(31, 31, 35),
	ButtonBorder = Color3_fromRGB(135, 135, 140),
	ButtonSelected = Color3_fromRGB(0, 170, 155),
	Field = Color3_fromRGB(37, 37, 42),
	FieldBorder = Color3_fromRGB(50, 50, 55),
	TitleBackground = Color3_fromRGB(10, 10, 15)
}


Prompt:
--[[
	Implementation
]]

Response:
local function isAlive()
	return maid.humanoid.Health > 0 and maid.humanoid:GetState() ~= Enum.HumanoidStateType.Dead
end

local function destroy()
	maid:destroy()
end

local function patrol()
	while isAlive() do
		if not attacking then
			local position = getRandomPointInCircle(startPosition, PATROL_RADIUS)
			maid.humanoid.WalkSpeed = PATROL_WALKSPEED
			maid.humanoid:MoveTo(position)
		end

		wait(random:NextInteger(MIN_REPOSITION_TIME, MAX_REPOSITION_TIME))
	end
end

local function isInstaceAttackable(targetInstance)
	local targetHumanoid = targetInstance and targetInstance.Parent and targetInstance.Parent:FindFirstChild("Humanoid")
	if not targetHumanoid then
		return false
	end

	-- Determine if they are attackable, depening on the attack mode
	local isEnemy = false
	if ATTACK_MODE == 1 then
		-- Attack characters with the SoldierEnemy tag
		if
			CollectionService:HasTag(targetInstance.Parent, "SoldierEnemy") and
			not CollectionService:HasTag(targetInstance.Parent, "SoldierFriend") then
			isEnemy = true
		end
	elseif ATTACK_MODE == 2 then
		-- Attack all humanoids without the SoldierFriend tag
		if not CollectionService:HasTag(targetInstance.Parent, "SoldierFriend") then
			isEnemy = true
		end
	elseif ATTACK_MODE == 3 then
		-- Attack all humanoids
		isEnemy = true
	end

	local isAttackable = false
	local distance = (maid.humanoidRootPart.Position - targetInstance.Position).Magnitude

	if distance <= ATTACK_RADIUS then
		local ray = Ray.new(
			maid.humanoidRootPart.Position,
			(targetInstance.Parent.HumanoidRootPart.Position - maid.humanoidRootPart.Position).Unit * distance
		)

		local part = Workspace:FindPartOnRayWithIgnoreList(ray, {
			targetInstance.Parent, maid.instance,
		}, false, true)

		if
			isEnemy and
			targetInstance ~= maid.instance and
			targetInstance:IsDescendantOf(Workspace) and
			targetHumanoid.Health > 0 and
			targetHumanoid:GetState() ~= Enum.HumanoidStateType.Dead and
			not part
		then
			isAttackable = true
		end
	end

	return isAttackable
end

local function fireGun()
	-- Do damage to the target
	local targetHunanoid = target.Parent:FindFirstChild("Humanoid")
	targetHunanoid:TakeDamage(ATTACK_DAMAGE)

	-- Play the pistol firing animation
	maid.attackAnimation:Play()

	-- Play the pistol firing sound effect
	maid.gunFireSound:Play()

	-- Muzzle flash
	local firingPositionAttachment = maid.instance.Pistol.Handle.FiringPositionAttachment
	firingPositionAttachment.FireEffect:Emit(10)
	firingPositionAttachment.PointLight.Enabled = true

	wait(0.1)

	firingPositionAttachment.PointLight.Enabled = false
end

local function findTargets()
	-- Do a new search region if we are not already searching through an existing search region
	if not searchingForTargets and tick() - timeSearchEnded >= SEARCH_DELAY then
		searchingForTargets = true

		-- Create a new region
		local centerPosition = maid.humanoidRootPart.Position
		local topCornerPosition = centerPosition + Vector3.new(ATTACK_RADIUS, ATTACK_RADIUS, ATTACK_RADIUS)
		local bottomCornerPosition = centerPosition + Vector3.new(-ATTACK_RADIUS, -ATTACK_RADIUS, -ATTACK_RADIUS)

		searchRegion = Region3.new(bottomCornerPosition, topCornerPosition)
		searchParts = Workspace:FindPartsInRegion3(searchRegion, maid.instance, math.huge)

		newTarget = nil
		newTargetDistance = nil

		-- Reset to defaults
		searchIndex = 1
	end

	if searchingForTargets then
		-- Search through our list of parts and find attackable humanoids
		local checkedParts = 0
		while searchingForTargets and searchIndex <= #searchParts and checkedParts < MAX_PARTS_PER_HEARTBEAT do
			local currentPart = searchParts[searchIndex]
			if currentPart and isInstaceAttackable(currentPart) then
				local character = currentPart.Parent
				local distance = (character.HumanoidRootPart.Position - maid.humanoidRootPart.Position).magnitude

				-- Determine if the charater is the closest
				if not newTargetDistance or distance < newTargetDistance then
					newTarget = character.HumanoidRootPart
					newTargetDistance = distance
				end
			end

			searchIndex = searchIndex + 1

			checkedParts = checkedParts + 1
		end

		if searchIndex >= #searchParts then
			target = newTarget
			searchingForTargets = false
			timeSearchEnded = tick()
		end
	end
end

local function attack()
	attacking = true

	local originalWalkSpeed = maid.humanoid.WalkSpeed
	maid.humanoid.WalkSpeed = 16

	maid.attackIdleAnimation:Play()

	local shotsFired = 0
	while attacking and isInstaceAttackable(target) and isAlive() do
		fireGun()

		shotsFired = (shotsFired + 1) % CLIP_CAPACITY

		if shotsFired == CLIP_CAPACITY - 1 then
			maid.reloadAnimation:Play()
			wait(RELOAD_DELAY)
		else
			wait(ATTACK_DELAY)
		end
	end

	maid.humanoid.WalkSpeed = originalWalkSpeed

	maid.attackIdleAnimation:Stop()

	attacking = false
end


Prompt: -- The comments below explain what the code does, so that you can have a better understanding about exactly how it works.

Response:
plrs = game:GetService("Players") -- Get Players; this service allows us to know when a player joins the game and other player-related things
ps = game:GetService("PhysicsService") -- Get PhysicsService; this service allows us to manage collision groups

ps:RegisterCollisionGroup("plrs") -- Create collision group for players only
ps:CollisionGroupSetCollidable("plrs","plrs",false) -- Make the group not collide with other parts in that same group (This is why we create a new, seperate collision group for players; if we did this with the normal collision group, the players would fall through the world!)

plrs.PlayerAdded:Connect(function(plr) -- When a player joins,
	plr.CharacterAdded:Connect(function(chr) -- wait for their character to load. Once it does,
		for key,value in pairs(chr:GetDescendants()) do -- loop through the character's descendants/parts.
			if value:IsA("BasePart") then -- If a descendant is found to be eligable for collision groups (If this part of the character is a body part),
				value.CollisionGroup = "plrs" -- set its collision group to the players only group
			end
		end
	end)
end)


Prompt: --// Load Order List

Response:
local CORE_LOADING_ORDER = table.freeze({
	--// Required by most modules
	"Variables",
	"Functions",

	--// Core functionality
	"Core",
	"Remote",
	"UI",
	"Process",

	--// Misc
	"Anti",
})


Prompt:
--[[INSTRUCCIONES
* Tiempo entre que toca SENSOR y PARADA: 20 segundos
]]

Response:
function onTouched(hit)
	campana.Playing = true
	ondear.Value = 0.1
	chimenea1.Enabled = false
	chimenea2.Enabled = false
	ruedaderecha1.AngularVelocity = -2
	ruedaderecha2.AngularVelocity = -2

	wait(10)
	ondear.Value = 0.2
	campana.TimePosition = 0
	ruedaderecha1.AngularVelocity = -1
	ruedaderecha2.AngularVelocity = -1
	wait(10)
	ruedaderecha1.AngularVelocity = 0
	ruedaderecha2.AngularVelocity = 0
	ondear.Value = 50
	campana.Playing = false
	wait(parada) --PARADA
	ondear.Value = 0.2
	humoi.Enabled = true
	humod.Enabled = true
	chimenea1.Enabled = true
	chimenea2.Enabled = true
	ruedaderecha1.AngularVelocity = -0.5
	ruedaderecha2.AngularVelocity = -0.5
	wait(1)
	ondear.Value = 0.1
	ruedaderecha1.AngularVelocity = -1
	ruedaderecha2.AngularVelocity = -1
	humoi.Enabled = false
	humod.Enabled = false
	wait(1)
	ondear.Value = 0.05
	ruedaderecha1.AngularVelocity = -2
	ruedaderecha2.AngularVelocity = -2
	humoi.Enabled = true
	humod.Enabled = true
	wait(1)
	ruedaderecha1.AngularVelocity = -3
	ruedaderecha2.AngularVelocity = -3
	humoi.Enabled = false
	humod.Enabled = false
end
script.Parent.Touched:connect(onTouched)


Prompt: -- / Configurations / --

Response:
local Configurations = GameAssets.Configurations
local GameConfiguration = Configurations.GameConfiguration


Prompt: -- Fire with blacklist

Response:
function FastCast:FireWithBlacklist(origin, directionWithMagnitude, velocity, blacklist, cosmeticBulletObject, ignoreWater, bulletAcceleration, bulletData, whizData, hitData, penetrationData)
	assert(getmetatable(self) == FastCast, ERR_NOT_INSTANCE:format("FireWithBlacklist", "FastCast.new()"))
	BaseFireMethod(self, origin, directionWithMagnitude, velocity, cosmeticBulletObject, nil, ignoreWater, bulletAcceleration, bulletData, whizData, hitData, blacklist, false, penetrationData)
end

TargetEvent:Connect(function(dt)
	for i, v in next, Projectiles, nil do
      	if RemoveList[i] then
			RemoveList[i] = nil
        	Projectiles[i] = nil
      	else
        	i.Update(dt)
      	end
	end
end)


Prompt: -- SERVICES --

Response:
local CS = game:GetService("CollectionService")
local RS = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")


Response:
local  Paint = false

script.Parent.MouseButton1Click:connect(function()
	Paint = not Paint
	handler:FireServer("Beige",Paint)
end)


Prompt:
--local BG = Missile.BodyGyro
-------------------------------------------

Response:
while true do
	if Target.Value then
		if Target.Value.Parent then
			Missile.CFrame = CFrame.new(Missile.Position,Target.Value.Torso.Position)
			BV.velocity = Missile.CFrame.lookVector * 1500
		else
			break
		end
	else
		break
	end
	wait()
end


Prompt:
--// All global vars will be wiped/replaced except script
--// All guis are autonamed client.Variables.CodeName..gui.Name

Response:
return function(data, env)
	if env then
		setfenv(1, env)
	end

	local gui = script.Parent.Parent
	local playergui = service.PlayerGui
	local str = data.Message
	local time = data.Time or 15

	--client.UI.Make("HintHolder")
	local container = client.UI.Get("HintHolder",nil,true)
	if not container then
		local holder = service.New("ScreenGui")
		local hTable = client.UI.Register(holder)
		local frame = service.New("ScrollingFrame", holder)
		client.UI.Prepare(holder)
		hTable.Name = "HintHolder"
		frame.Name = "Frame"
		frame.BackgroundTransparency = 1
		frame.Size = UDim2.new(1, 0, 0,150)
		frame.CanvasSize = UDim2.new(0, 0, 0, 0)
		frame.ChildAdded:Connect(function(c)
			if #frame:GetChildren() == 0 then
				frame.Visible = false
			else
				frame.Visible = true
			end
		end)

		frame.ChildRemoved:Connect(function(c)
			if #frame:GetChildren() == 0 then
				frame.Visible = false
			else
				frame.Visible = true
			end
		end)

		container = hTable
		hTable:Ready()
	end
	container = container.Object.Frame

	--// First things first account for notif :)
	local notif = client.UI.Get("Notif")
	local topbar = client.UI.Get("TopBar")

	container.Position = UDim2.new(0,0,0,((notif and 30) or 0) + ((topbar and 40) or 0) - 35)

	local children = container:children()

	gui.Position = UDim2.new(0,0,0,-100)
	gui.Frame.msg.Text = str
	local bounds = gui.Frame.msg.TextBounds.X

	spawn(function()
		local sound = Instance.new("Sound",service.LocalContainer())
		sound.SoundId = "rbxassetid://255881176"
		sound.Volume = 0.25
		wait(0.1)
		sound:Play()
		wait(0.8)
		sound:Destroy()
	end)

	local function moveGuis(m,ignore)
		m = m or 0
		local max = #container:children()
		for i,v in pairs(container:children()) do
			if v~=ignore then
				local y = (i+m)*28
				v.Position = UDim2.new(0,0,0,y)
				if i~=max then v.Size = UDim2.new(1,0,0,28) end
			end
		end
	end

	local lom = -1
	moveGuis(-1)
	gui.Parent = container
	if #container:children()>5 then lom = -2 end
	UDim2.new(0,0,0,(#container:children()+lom)*28)
	moveGuis(-1)
	--gui:TweenPosition(UDim2.new(0,0,0,(#container:children()+lom)*28),nil,nil,0.3,true,function() if gui and gui.Parent then moveGuis(-1) end end)

	if #container:children()>5 then
		local gui = container:children()[1]
		moveGuis(-2,gui)
		gui:Destroy()
		--gui:TweenPosition(UDim2.new(0,0,0,-100),nil,nil,0.2,true,function() if gui and gui.Parent then gui:Destroy() end end)
	end

	wait(data.Time or 5)

	if gui and gui.Parent then
		moveGuis(-2,gui)
		gui:Destroy()
		--gui:TweenPosition(UDim2.new(0,0,0,-100),nil,nil,0.2,true,function() if gui and gui.Parent then gui:Destroy() end end)
	end
end


Prompt: --// Functions

Response:
function UpdateTag(plr)
	if plr ~= L_1_ and plr.Character and plr.Character:FindFirstChild("TeamTagUI") then
		local Tag = plr.Character:FindFirstChild("TeamTagUI")
		if plr.Team == L_1_.Team then
			Tag.Enabled = true
			if plr.Character:FindFirstChild("ACS_Client") and plr.Character.ACS_Client:FindFirstChild("FireTeam") and plr.Character.ACS_Client.FireTeam.SquadName.Value ~= "" then
				Tag.Frame.Icon.ImageColor3 = plr.Character.ACS_Client.FireTeam.SquadColor.Value
			else
				Tag.Frame.Icon.ImageColor3 = Color3.fromRGB(255,255,255)
			end
		else
			Tag.Enabled = false
		end
	end
end


Prompt:
--// Use the below table to define "pre-set" command aliases
--// Command aliases; Format: {[":alias <arg1> <arg2> ..."] = ":command <arg1> <arg2> ..."}

Response:
settings.Aliases = {
	[":examplealias <player> <fireColor>"] = ":ff <player> | :fling <player> | :fire <player> <fireColor>" --// Order arguments appear in alias string determines their required order in the command message when ran later
};

settings.Banned = {}		-- List of people banned from the game 		  Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";}
settings.Muted = {}			-- List of people muted (cannot send chat messages)				 		  Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";}
settings.Blacklist = {}		-- List of people banned from running commands 	  Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";}
settings.Whitelist = {}		-- People who can join if whitelist enabled	  Format: {"Username"; "Username:UserId"; UserId; "Group:GroupId:GroupRank"; "Group:GroupId"; "Item:ItemID"; "GamePass:GamePassID";}

settings.MusicList = {} 	-- List of songs to appear in the :musiclist	  Format: {{Name = "somesong", ID = 1234567}, {Name = "anotherone", ID = 1243562}}
settings.CapeList = {}		-- List of capes							  Format: {{Name = "somecape", Material = "Fabric", Color = "Bright yellow", ID = 12345567, Reflectance = 1}; {etc more stuff here}}
settings.InsertList = {} 	-- List of models to appear in the :insertlist and can be inserted using ':insert <name>'	  Format: {{Name = "somemodel", ID = 1234567}; {Name = "anotherone", ID = 1243562}}

settings.OnStartup = {}		-- List of commands ran at server start								Format: {":notif TestNotif"}
settings.OnJoin = {}		-- List of commands ran as player on join (ignores adminlevel)		Format: {":cmds"}
settings.OnSpawn = {}		-- List off commands ran as player on spawn (ignores adminlevel)	Format: {"!fire Really red",":ff me"}

settings.SaveAdmins = true		  -- If true anyone you :admin or :headadmin in-game will save
settings.LoadAdminsFromDS = true  -- If false, any admins saved in your DataStores will not load
settings.WhitelistEnabled = false -- If true enables the whitelist/server lock; Only lets admins & whitelisted users join

settings.Prefix = ";"				-- The : in :kill me
settings.PlayerPrefix = "!"			-- The ! in !donate; Mainly used for commands that any player can run; Do not make it the same as settings.Prefix
settings.SpecialPrefix = ""			-- Used for things like "all", "me" and "others" (If changed to ! you would do :kill !me)
settings.SplitKey = " "				-- The space in :kill me (eg if you change it to / :kill me would be :kill/me)
settings.BatchKey = "|"				-- :kill me | :ff bob | :explode scel
settings.ConsoleKeyCode = "Quote"	-- Keybind to open the console; Rebindable per player in userpanel; KeyCodes: https://developer.roblox.com/en-us/api-reference/enum/KeyCode


Prompt: -- Container for temporary connections (disconnected automatically)

Response:
local Connections = {};

function CollisionTool.Equip()
	-- Enables the tool's equipped functionality

	-- Start up our interface
	ShowUI();
	BindShortcutKeys();

end;

function CollisionTool.Unequip()
	-- Disables the tool's equipped functionality

	-- Clear unnecessary resources
	HideUI();
	ClearConnections();

end;

function ClearConnections()
	-- Clears out temporary connections

	for ConnectionKey, Connection in pairs(Connections) do
		Connection:disconnect();
		Connections[ConnectionKey] = nil;
	end;

end;

function ShowUI()
	-- Creates and reveals the UI

	-- Reveal UI if already created
	if UI then

		-- Reveal the UI
		UI.Visible = true;

		-- Update the UI every 0.1 seconds
		UIUpdater = Support.ScheduleRecurringTask(UpdateUI, 0.1);

		-- Skip UI creation
		return;

	end;

	-- Create the UI
	UI = Core.Tool.Interfaces.BTCollisionToolGUI:Clone();
	UI.Parent = Core.UI;
	UI.Visible = true;

	-- References to UI elements
	local OnButton = UI.Status.On.Button;
	local OffButton = UI.Status.Off.Button;

	-- Enable the collision status switch
	OnButton.MouseButton1Click:connect(function ()
		SetProperty('CanCollide', true);
	end);
	OffButton.MouseButton1Click:connect(function ()
		SetProperty('CanCollide', false);
	end);

	-- Update the UI every 0.1 seconds
	UIUpdater = Support.ScheduleRecurringTask(UpdateUI, 0.1);

end;

function UpdateUI()
	-- Updates information on the UI

	-- Make sure the UI's on
	if not UI then
		return;
	end;

	-- Check the common collision status of selection
	local Collision = Support.IdentifyCommonProperty(Selection.Items, 'CanCollide');

	-- Update the collision option switch
	if Collision == true then
		Core.ToggleSwitch('On', UI.Status);

	-- If the selection has collision disabled
	elseif Collision == false then
		Core.ToggleSwitch('Off', UI.Status);

	-- If the collision status varies, don't select a current switch
	elseif Collision == nil then
		Core.ToggleSwitch(nil, UI.Status);
	end;

end;

function HideUI()
	-- Hides the tool UI

	-- Make sure there's a UI
	if not UI then
		return;
	end;

	-- Hide the UI
	UI.Visible = false;

	-- Stop updating the UI
	UIUpdater:Stop();

end;

function SetProperty(Property, Value)

	-- Make sure the given value is valid
	if Value == nil then
		return;
	end;

	-- Start a history record
	TrackChange();

	-- Go through each part
	for _, Part in pairs(Selection.Items) do

		-- Store the state of the part before modification
		table.insert(HistoryRecord.Before, { Part = Part, [Property] = Part[Property] });

		-- Create the change request for this part
		table.insert(HistoryRecord.After, { Part = Part, [Property] = Value });

	end;

	-- Register the changes
	RegisterChange();

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 selection's collision status
			ToggleCollision();

		end;

	end));

end;

function ToggleCollision()
	-- Toggles the collision status of the selection

	-- Change the collision status to the opposite of the common collision status
	SetProperty('CanCollide', not Support.IdentifyCommonProperty(Selection.Items, 'CanCollide'));

end;

function TrackChange()

	-- Start the record
	HistoryRecord = {
		Before = {};
		After = {};

		Unapply = function (Record)
			-- Reverts this change

			-- Select the changed parts
			Selection.Replace(Support.GetListMembers(Record.Before, 'Part'));

			-- Send the change request
			Core.SyncAPI:Invoke('SyncCollision', Record.Before);

		end;

		Apply = function (Record)
			-- Applies this change

			-- Select the changed parts
			Selection.Replace(Support.GetListMembers(Record.After, 'Part'));

			-- Send the change request
			Core.SyncAPI:Invoke('SyncCollision', Record.After);

		end;

	};

end;

function RegisterChange()
	-- Finishes creating the history record and registers it

	-- Make sure there's an in-progress history record
	if not HistoryRecord then
		return;
	end;

	-- Send the change to the server
	Core.SyncAPI:Invoke('SyncCollision', HistoryRecord.After);

	-- Register the record and clear the staging
	Core.History.Add(HistoryRecord);
	HistoryRecord = nil;

end;


Prompt: -- MEMBER and LEADER AFFECTORS

Response:
function TribeModule:ChangeMemberRole(playerName)

end

function TribeModule:TransferTribe(tribeName,playerName)

end

function TribeModule:AddMember(playerName)

end

function TribeModule:RemoveMember(tribeName,playerName)

end

function TribeModule:AddLeader(playerName)

end

function TribeModule:RemoveLeader(tribeName,playerName)

end

function TribeModule:RemoveLeader()

end


Prompt: --Quenty's qPerfectionWeld script remade into a module.

Response:
local NEVER_BREAK_JOINTS = false;

local function CallOnChildren(Instance, FunctionToCall)
	FunctionToCall(Instance)
	for _, Child in next, Instance:GetChildren() do
		CallOnChildren(Child, FunctionToCall)
end end

local function GetNearestParent(Instance, ClassName)
	local Ancestor = Instance
	repeat Ancestor = Ancestor.Parent
		if Ancestor == nil then return nil end
	until Ancestor:IsA(ClassName)
	return Ancestor
end

local function GetBricks(StartInstance)
	local List = {}
	CallOnChildren(StartInstance, function(Item)
		if Item:IsA('BasePart') then
			List[#List+1] = Item;
	end end)
return List end

local function Modify(Instance, Values)
	assert(type(Values) == 'table', 'Values is not a table');
	for Index, Value in next, Values do
		if type(Index) == 'number' then
			Value.Parent = Instance
		else
			Instance[Index] = Value
	end end
return Instance end

local function Make(ClassType, Properties) return Modify(Instance.new(ClassType), Properties) end

local Surfaces = {'TopSurface','BottomSurface','LeftSurface','RightSurface','FrontSurface','BackSurface'};
local HingSurfaces = {'Hinge','Motor','SteppingMotor'};

local function HasWheelJoint(Part)
	for _, SurfaceName in pairs(Surfaces) do
		for _, HingSurfaceName in pairs(HingSurfaces) do
			if Part[SurfaceName].Name == HingSurfaceName then
				return true
		end end end
return false end

local function ShouldBreakJoints(Part)
	if NEVER_BREAK_JOINTS then return false end
	if HasWheelJoint(Part) then return false end
	local Connected = Part:GetConnectedParts()
	if #Connected == 1 then return false end
	for _, Item in pairs(Connected) do
		if HasWheelJoint(Item) then return false
		elseif not Item:IsDescendantOf(script.Parent) then return false
	end end
return true end

local function WeldTogether(Part0, Part1, JointType, WeldParent)
	JointType = JointType or 'Weld'
	local RelativeValue = Part1:FindFirstChild('qRelativeCFrameWeldValue')
	local NewWeld = Part1:FindFirstChild('qCFrameWeldThingy') or Instance.new(JointType)
	Modify(NewWeld, {
		Name = 'qCFrameWeldThingy';
		Part0  = Part0;
		Part1  = Part1;
		C0     = CFrame.new();
		C1     = RelativeValue and RelativeValue.Value or Part1.CFrame:toObjectSpace(Part0.CFrame); --Part1.CFrame:inverse() * Part0.CFrame;-- Part1.CFrame:inverse();
		Parent = Part1;
	})
	if not RelativeValue then
		RelativeValue = Make('CFrameValue', {
			Parent     = Part1;
			Name       = 'qRelativeCFrameWeldValue';
			Archivable = true;
			Value      = NewWeld.C1;
		})
	end
	return NewWeld
end

local function WeldParts(Parts, MainPart, JointType, DoNotUnanchor)
	for _, Part in pairs(Parts) do
		if ShouldBreakJoints(Part) then
			Part:BreakJoints()
	end end
	for _, Part in pairs(Parts) do
		if Part ~= MainPart then
			WeldTogether(MainPart, Part, JointType, MainPart)
	end end
	if not DoNotUnanchor then
		for _, Part in pairs(Parts) do
			Part.Anchored = false
		end
	MainPart.Anchored = false;
	end
end

local _M = {}

function _M.PerfectionWeld(Model)
	local Tool = GetNearestParent(script, 'Tool')
	local Parts = GetBricks(Model)
	local PrimaryPart = Tool and Tool:FindFirstChild('Handle') and Tool.Handle:IsA('BasePart') and Tool.Handle or Model:IsA('Model') and Model.PrimaryPart or Parts[1]
	if PrimaryPart then
		WeldParts(Parts, PrimaryPart, 'Weld', false)
	end
return Tool
end

return _M


Prompt:
--[=[
	Returns whether the service bag has fully started or not.
	@return boolean
]=]

Response:
function ServiceBag:IsStarted()
	return self._serviceTypesToStart == nil
end


Prompt:
--[=[
	Observes the translated value
	@param key string
	@param argData table? -- May have observables (or convertable to observables) in it.
	@return Observable<string>
]=]

Response:
function JSONTranslator:ObserveFormatByKey(key, argData)
	assert(self ~= JSONTranslator, "Construct a new version of this class to use it")
	assert(type(key) == "string", "Key must be a string")

	local argObservable
	if argData then
		local args = {}
		for argKey, value in pairs(argData) do
			args[argKey] = Blend.toPropertyObservable(value) or Rx.of(value)
		end

		argObservable = Rx.combineLatest(args)
	else
		argObservable = nil
	end

	return Observable.new(function(sub)
		local maid = Maid.new()

		maid:GivePromise(self._promiseTranslator:Then(function()
			if argObservable then
				maid:GiveTask(argObservable:Subscribe(function(args)
					sub:Fire(self:FormatByKey(key, args))
				end))
			else
				sub:Fire(self:FormatByKey(key, nil))
			end
		end))

		return maid
	end)
end


Prompt: -- Only works on ordinal. yada yada.

Response:
Table.insertAndGetIndexOf = function (tbl, value)
	tbl[#tbl + 1] = value
	return #tbl
end


Prompt: ----  \/Cruise\/

Response:
model = script.Parent
wait(0.5)
currentP = "Off"
script.Parent.Events.Cruise.OnServerEvent:Connect( function(player, pattern)
	if script.Parent.Values.Cruise.Value == true then
		script.Parent.Values.Cruise.Value = false
	else
		script.Parent.Values.Cruise.Value = true
	end
end)


Response:
function onChildAdded(something)
	if something.Name == "SeatWeld" then
		local human = something.part1.Parent:findFirstChild("Humanoid")
		if (human ~= nil) then
			script.Parent.Parent.Parent.RWD.Anchored = false
			wait(.5)
			script.Parent.Parent.Parent.lightbar1.middle.Yelp:Stop()
			script.Parent.Parent.Parent.lightbar1.middle.Wail:Stop()
			script.Parent.Parent.Parent.lightbar1.middle.Manual:Stop()
		end
	end
end

function onChildRemoved(something)
	if (something.Name == "SeatWeld") then
		local human = something.part1.Parent:findFirstChild("Humanoid")
		if (human ~= nil) then
			print("Human Found")
			script.Parent.Parent.Parent.RWD.Anchored = true
			wait(.2)
			script.Parent.Parent.Parent.lightbar1.middle.Yelp:Stop()
			script.Parent.Parent.Parent.lightbar1.middle.Wail:Stop()
			script.Parent.Parent.Parent.lightbar1.middle.Manual:Stop()

		end
	end
end

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


Prompt:
--[[

	Ser is a serialization/deserialization utility module that is used
	by Knit to automatically serialize/deserialize values passing
	through remote functions and remote events.

	Ser.Classes = {
		[ClassName] = {
			Serialize = (value) -> serializedValue
			Deserialize = (value) => deserializedValue
		}
	}

	Ser.SerializeArgs(...)            -> table
	Ser.SerializeArgsAndUnpack(...)   -> Tuple
	Ser.DeserializeArgs(...)          -> table
	Ser.DeserializeArgsAndUnpack(...) -> Tuple
	Ser.Serialize(value: any)         -> any
	Ser.Deserialize(value: any)       -> any
	Ser.UnpackArgs(args: table)       -> Tuple

--]]

Response:
type Args = {
	n: number,
	[any]: any,
}

local Option = require(script.Parent.Option)

local Ser = {}

Ser.Classes = {
	Option = {
		Serialize = function(opt) return opt:Serialize() end;
		Deserialize = Option.Deserialize;
	};
}

function Ser.SerializeArgs(...: any): Args
	local args = table.pack(...)
	for i,arg in ipairs(args) do
		if type(arg) == "table" then
			local ser = Ser.Classes[arg.ClassName]
			if ser then
				args[i] = ser.Serialize(arg)
			end
		end
	end
	return args
end

function Ser.SerializeArgsAndUnpack(...: any): ...any
	local args = Ser.SerializeArgs(...)
	return table.unpack(args, 1, args.n)
end

function Ser.DeserializeArgs(...: any): Args
	local args = table.pack(...)
	for i,arg in ipairs(args) do
		if type(arg) == "table" then
			local ser = Ser.Classes[arg.ClassName]
			if ser then
				args[i] = ser.Deserialize(arg)
			end
		end
	end
	return args
end

function Ser.DeserializeArgsAndUnpack(...: any): ...any
	local args = Ser.DeserializeArgs(...)
	return table.unpack(args, 1, args.n)
end

function Ser.Serialize(value: any): any
	if type(value) == "table" then
		local ser = Ser.Classes[value.ClassName]
		if ser then
			value = ser.Serialize(value)
		end
	end
	return value
end

function Ser.Deserialize(value: any): any
	if type(value) == "table" then
		local ser = Ser.Classes[value.ClassName]
		if ser then
			value = ser.Deserialize(value)
		end
	end
	return value
end

function Ser.UnpackArgs(args: Args): ...any
	return table.unpack(args, 1, args.n)
end

return Ser


Prompt:
-- Connections
-- Set initial level and progress

Response:
Level.Text = upgrades.Value
ProgressBarContainer.Position = UDim2.fromScale(-1 + math.min(1,
		points.Value % GameSettings.upgradeCost(upgrades.Value) / 3), 0)
ProgressBarFill.Position = UDim2.fromScale(1 - math.min(1,
		points.Value % GameSettings.upgradeCost(upgrades.Value) / 3), 0)


Prompt: --remove any of the following parts that say "(parts[i].className == [className])" if you want to exclude that particular className type from the Weld

Response:
	if ((parts[i].className == "Part") or (parts[i].className == "Seat") or (parts[i].className == "TrussPart") or (parts[i].className == "VehicleSeat") or (parts[i].className == "SkateboardPlatform")) then
		if (prev ~= nil) then
			local weld = Instance.new("Weld")
			weld.Part0 = prev
			weld.Part1 = parts[i]
			weld.C0 = prev.CFrame:inverse()
			weld.C1 = parts[i].CFrame:inverse()
			weld.Parent = prev
			parts[i].Anchored = false
		end
		prev = parts[i]
	end
end
wait(3)


Prompt: -- Simulate camera shake (not great, but works well enough for this):

Response:
local function GetCameraShake()
	local dragAngle = Angle(seat.CFrame.lookVector, seat.Velocity)
	local speed = seat.Velocity.Magnitude

	local shakeMagnitude = (speed * 0.02) * dragAngle * 0.1

	local theta = RAND() * TAU
	local x = COS(theta) * shakeMagnitude
	local y = SIN(theta) * shakeMagnitude
	--                   ^
	-- THE STARS ALIGN   ^   DUN DUN DUN
	--                   ^

	return V3(x, y, 0)
end

local function GetCameraRotation()

	-- Relative rotational velocity:
	dampCam.Goal = -seat.CFrame:vectorToObjectSpace(seat.RotVelocity) * 0.1
	local relRotVel = dampCam:Update()

	-- Camera shake offset:
	dampShake.Goal = GetCameraShake()
	local shake = CF(dampShake:Update())

	-- User view rotation:
	local viewRotation = dampRot:Update()
	viewRotation = ANG(0, viewRotation.X, 0) * ANG(viewRotation.Y, 0, 0)

	return ANG(0, 0, mobileDeviceBank) * viewRotation * ANG(relRotVel.X, relRotVel.Y, relRotVel.Z) * shake

end


Prompt:
--[[
	Indent a potentially multi-line string with the given number of tabs, in
	addition to any indentation the string already has.
]]

Response:
local function indent(source, indentLevel)
	local indentString = ("\t"):rep(indentLevel)

	return indentString .. source:gsub("\n", "\n" .. indentString)
end


Prompt: -- Hook events

Response:
Entry.TextBox.FocusLost:Connect(function(submit)
	return Window:LoseFocus(submit)
end)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	return Window:BeginInput(input, gameProcessed)
end)

Entry.TextBox:GetPropertyChangedSignal("Text"):Connect(function()
	Gui.CanvasPosition = Vector2.new(0, Gui.AbsoluteCanvasSize.Y)

	if string.match(Entry.TextBox.Text, '\t') then -- Eat \t
		Entry.TextBox.Text = Entry.TextBox.Text:gsub("\t", "")
		return
	end

	if Window.OnTextChanged then
		return Window.OnTextChanged(Entry.TextBox.Text)
	end
end)

Gui.ChildAdded:Connect(function()
	task.defer(Window.UpdateWindowHeight)
end)

return Window


Prompt:
--[=[
	Prepends the value onto the emitted brio
	@since 3.6.0
	@param ... T
	@return (source: Observable<Brio<U>>) -> Observable<Brio<U | T>>
]=]

Response:
function RxBrioUtils.prepend(...)
	local args = table.pack(...)

	return Rx.map(function(brio)
		assert(Brio.isBrio(brio), "Bad brio")

		return BrioUtils.prepend(brio, table.unpack(args, 1, args.n))
	end)
end


Prompt: --"False" = Not Acceptable Keycard To Open. "True" = Acceptable Keycard To Open.--

Response:
local bool = true
local bool2 = true
local clearance = {
	["[SCP] Card-Omni"] = true,
	["[SCP] Card-L5"] = false,
	["[SCP] Card-L4"] = false,
	["[SCP] Card-L3"] = false,
	["[SCP] Card-L2"] = false,
	["[SCP] Card-L1"] = false
}

						--DO NOT EDIT BEYOND THIS LINE--
local LeftDoor = script.Parent
local RightDoor = script.Parent.Parent.RightDoor
local Open = false

local OpenSound = script.Parent.DoorOpen
local CloseSound = script.Parent.DoorClose

local Debounce = false
function openDoor()
	if not Debounce then
		Debounce = true
		if Open then
			Open = false
			CloseSound:Play()
			Spawn(function()
				for i = 1, 60 do
					LeftDoor.CFrame = LeftDoor.CFrame + (LeftDoor.CFrame.lookVector * 0.1)
					wait(0.05)
				end
			end)
			Spawn(function()
				for i = 1, 60 do
					RightDoor.CFrame = RightDoor.CFrame + (RightDoor.CFrame.lookVector * 0.1)
					wait(0.05)
				end
			end)
		else
			Open = true
			OpenSound:Play()
			Spawn(function()
				for i = 1, 60 do
					LeftDoor.CFrame = LeftDoor.CFrame - (LeftDoor.CFrame.lookVector * 0.1)
					wait(0.05)
				end
			end)
			Spawn(function()
				for i = 1, 60 do
					RightDoor.CFrame = RightDoor.CFrame - (RightDoor.CFrame.lookVector * 0.1)
					wait(0.05)
				end
			end)
		end
		wait(2.5)
		Debounce = false
	end
end

script.Parent.Parent.KeycardReader1.touched:connect(function(touch)
	if touch.Name == "Handle" and clearance[touch.Parent.Name] and bool then
		bool = false
		script.Parent.AccessGranted:play()
		wait(0.75)
		openDoor()
		wait(3)
		bool = true
	elseif touch.Name == "Handle" and not clearance[touch.Parent.Name] and bool2 then
		bool2 = false
		script.Parent.AccessDenied:play()
		wait(1)
		bool2 = true
	end
end)

script.Parent.Parent.KeycardReader2.touched:connect(function(touch)
	if touch.Name == "Handle" and clearance[touch.Parent.Name] and bool then
		bool = false
		script.Parent.AccessGranted:play()
		wait(0.75)
		openDoor()
		wait(3)
		bool = true
	elseif touch.Name == "Handle" and not clearance[touch.Parent.Name] and bool2 then
		bool2 = false
		script.Parent.AccessDenied:play()
		wait(1)
		bool2 = true
	end
end)


Prompt:
-- Given diffs from expected and received strings,
-- return new array of diffs split or joined into lines.
--
-- To correctly align a change line at the end, the algorithm:
-- * assumes that a newline was appended to the strings
-- * omits the last newline from the output array
--
-- Assume the function is not called:
-- * if either expected or received is empty string
-- * if neither expected nor received is multiline string

Response:
return function(diffs: Array<Diff>, changeColor: DiffOptionsColor): Array<Diff>
	local deleteBuffer = ChangeBuffer.new(DIFF_DELETE, changeColor)
	local insertBuffer = ChangeBuffer.new(DIFF_INSERT, changeColor)
	-- ROBLOX FIXME Luau: another issue with normalization: Property 'deleteBuffer' is not compatible
	local commonBuffer = CommonBuffer.new(deleteBuffer, insertBuffer) :: any

	for _, diff in ipairs(diffs) do
		local case = diff[1]
		if case == DIFF_DELETE then
			deleteBuffer:align(diff)
		elseif case == DIFF_INSERT then
			insertBuffer:align(diff)
		else
			commonBuffer:align(diff)
		end
	end

	return commonBuffer:getLines()
end


Prompt: --[[Susupension]]

Response:
	Tune.SusEnabled		= true		-- works only in with PGSPhysicsSolverEnabled, defaults to false when PGS is disabled

	--Front Suspension
	Tune.FSusDamping	= 300		-- Spring Dampening
	Tune.FSusStiffness	= 4000		-- Spring Force
	Tune.FAntiRoll 		= 50		-- Anti-Roll (Gyro Dampening)

	Tune.FSusLength		= 2			-- Suspension length (in studs)
	Tune.FPreCompress	= .7		-- Pre-compression adds resting length force
	Tune.FExtensionLim	= .3		-- Max Extension Travel (in studs)
	Tune.FCompressLim	= .1		-- Max Compression Travel (in studs)
	Tune.FSusAngle		= 80		-- Suspension Angle (degrees from horizontal)

	Tune.FWsBoneLen		= 5			-- Wishbone Length
	Tune.FWsBoneAngle	= 0			-- Wishbone angle (degrees from horizontal)
	Tune.FAnchorOffset	= {			-- Suspension anchor point offset (relative to center of wheel)
	 --[[Lateral]]		-.4		,	-- positive = outward
	 --[[Vertical]]		-.5		,	-- positive = upward
	 --[[Forward]]		0		}	-- positive = forward

	--Rear Suspension
	Tune.RSusDamping	= 300		-- Spring Dampening
	Tune.RSusStiffness	= 4000		-- Spring Force
	Tune.FAntiRoll 		= 50		-- Anti-Roll (Gyro Dampening)

	Tune.RSusLength		= 2			-- Suspension length (in studs)
	Tune.RPreCompress	= .7		-- Pre-compression adds resting length force
	Tune.RExtensionLim	= .3		-- Max Extension Travel (in studs)
	Tune.RCompressLim	= .1		-- Max Compression Travel (in studs)
	Tune.RSusAngle		= 80		-- Suspension Angle (degrees from horizontal)

	Tune.RWsBoneLen		= 5			-- Wishbone Length
	Tune.RWsBoneAngle	= 0			-- Wishbone angle (degrees from horizontal)
	Tune.RAnchorOffset	= {			-- Suspension anchor point offset (relative to center of wheel)
	 --[[Lateral]]		-.4		,	-- positive = outward
	 --[[Vertical]]		-.5		,	-- positive = upward
	 --[[Forward]]		0		}	-- positive = forward

	--Aesthetics
	Tune.SusVisible		= true			-- Spring Visible
	Tune.WsBVisible		= false			-- Wishbone Visible
	Tune.SusRadius		= .2			-- Suspension Coil Radius
	Tune.SusThickness	= .1			-- Suspension Coil Thickness
	Tune.SusColor		= "Bright red"	-- Suspension Color [BrickColor]
	Tune.SusCoilCount	= 6				-- Suspension Coil Count
	Tune.WsColor		= "Black"		-- Wishbone Color [BrickColor]
	Tune.WsThickness	= .1			-- Wishbone Rod Thickness


Prompt:
--[=[
	Wraps :UpdateAsync() in a promise
	@param robloxDataStore DataStore
	@param key string
	@param updateFunc (T) -> T?
	@return Promise<boolean>
]=]

Response:
function DataStorePromises.updateAsync(robloxDataStore, key, updateFunc)
	assert(typeof(robloxDataStore) == "Instance", "Bad robloxDataStore")
	assert(type(key) == "string", "Bad key")
	assert(type(updateFunc) == "function", "Bad updateFunc")

	return Promise.spawn(function(resolve, reject)
		local result = nil
		local ok, err = pcall(function()
			result = { robloxDataStore:UpdateAsync(key, updateFunc) }
		end)
		if not ok then
			return reject(err)
		end
		if not result then
			return reject("No result loaded")
		end
		return resolve(unpack(result))
	end)
end


Prompt: -- [ SETTINGS ] --

Response:
local StatsName = "Gems" -- Your stats name
local MaxItems = 25 -- Max number of items to be displayed on the leaderboard
local MinValueDisplay = 1 -- Any numbers lower than this will be excluded
local MaxValueDisplay = 10e15 -- (10 ^ 15) Any numbers higher than this will be excluded
local UpdateEvery = 65 -- (in seconds) How often the leaderboard has to update


Prompt:
--[=[
	Utility functions to ensure that content is preloaded (wrapping calls in promises)
	@class ContentProviderUtils
]=]

Response:
local require = require(script.Parent.loader).load(script)

local ContentProvider = game:GetService("ContentProvider")

local Promise = require("Promise")

local ContentProviderUtils = {}


Prompt: -- Mouse

Response:
Mouse.Move:connect(function()
	gui.FakeC.Position = UDim2.new(0,Mouse.x-gui.FakeC.Size.X.Offset/2,0,Mouse.y-gui.FakeC.Size.Y.Offset/2)

	if Mouse.Target then
		if game.Players:FindFirstChild(Mouse.Target.Parent.Name) and Mouse.Target.Parent.Name ~= plr.Name then
			if game.Players[Mouse.Target.Parent.Name].TeamColor == plr.TeamColor then
				gui.FakeC.BackgroundColor3 = Color3.fromRGB(0,255,0)
			else
				gui.FakeC.BackgroundColor3 = Color3.fromRGB(255,0,0)
			end
		elseif game.Players:FindFirstChild(Mouse.Target.Parent.Parent.Name) and Mouse.Target.Parent.Parent.Name ~= plr.Name then
			if game.Players[Mouse.Target.Parent.Parent.Name].TeamColor == plr.TeamColor then
				gui.FakeC.BackgroundColor3 = Color3.fromRGB(0,255,0)
			else
				gui.FakeC.BackgroundColor3 = Color3.fromRGB(255,0,0)
			end
		elseif Mouse.Target.Parent:FindFirstChild("HumanoidLink") and Mouse.Target.Parent.HumanoidLink.Value.Parent.Name ~= plr.Name then
			if game.Players[Mouse.Target.Parent.HumanoidLink.Value.Parent.Name].TeamColor == plr.TeamColor then
				gui.FakeC.BackgroundColor3 = Color3.fromRGB(0,255,0)
			else
				gui.FakeC.BackgroundColor3 = Color3.fromRGB(255,0,0)
			end
		else
			gui.FakeC.BackgroundColor3 = Color3.fromRGB(255,255,255)
		end
	end
end)

local UserInputService = game:GetService("UserInputService")
UserInputService.InputBegan:connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton3 then
		if script.Parent.MainGui.FakeC.Size == UDim2.new(0,4,0,4) then
		   script.Parent.MainGui.FakeC.Size = UDim2.new(0,2,0,2)
		else
		   script.Parent.MainGui.FakeC.Size = UDim2.new(0,4,0,4)
		end
		gui.FakeC.Position = UDim2.new(0,Mouse.x-gui.FakeC.Size.X.Offset/2,0,Mouse.y-gui.FakeC.Size.Y.Offset/2)
	end
end)


Prompt:
--- An expensive way to spawn a function. However, unlike spawn(), it executes on the same frame, and
-- unlike coroutines, does not obscure errors
-- @module fastSpawn

Response:
return function(func, ...)
	assert(type(func) == "function")

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

	local bindable = Instance.new("BindableEvent")
	bindable.Event:Connect(function()
		func(unpack(args, 1, count))
	end)

	bindable:Fire()
	bindable:Destroy()
end


Prompt: -- check if the player is moving and not climbing

Response:
humanoid.Running:Connect(function(speed)
	if humanoid.MoveDirection.Magnitude > 0 and speed > 0 and humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then
		if oldWalkSpeed ~= humanoid.WalkSpeed then
			getSoundProperties()
			update()
		end
		currentSound.Playing = true
		currentSound.Looped = true
	else
		currentSound:Stop()
	end
end)


Prompt:
--s.Pitch = 0.7
--[[for x = 1, 50 do
s.Pitch = s.Pitch + 0.20 1.900
s:play()
wait(0.001)
end]]
--[[Chopper level 5=1.2, Chopper level 4=1.04]]

Response:
	s.Volume=1
while s.Pitch<1 do
s.Pitch=s.Pitch+0.010
s:Play()
if s.Pitch>1 then
	s.Pitch=1
end
wait(-9)
end

while true do
for x = 1, 500 do
s:play()
wait(-9)
end
end


Prompt: --[[Weld functions]]

Response:
	local JS = game:GetService("JointsService")
	local PGS_ON = workspace:PGSIsEnabled()

	function MakeWeld(x,y,type,s)
		if type==nil then type="Weld" end
		local W=Instance.new(type,JS)
		W.Part0=x W.Part1=y
		W.C0=x.CFrame:inverse()*x.CFrame
		W.C1=y.CFrame:inverse()*x.CFrame
		if type=="Motor" and s~=nil then
			W.MaxVelocity=s
		end
		return W
	end

	function ModelWeld(a,b)
		if a:IsA("BasePart") and
			a.Parent.Name ~= ("Hood") then
			MakeWeld(b,a,"Weld")
			for i,v in pairs(a:GetChildren()) do
				if v ~= nil and v:IsA("BasePart") then
					ModelWeld(v,b)
				end
			end
		elseif a:IsA("Model") then
			for i,v in pairs(a:GetChildren()) do
				ModelWeld(v,b)
			end
		end
	end

	function UnAnchor(a)
		if a:IsA("BasePart") then a.Anchored=false  end for i,v in pairs(a:GetChildren()) do UnAnchor(v) end
	end


Prompt: --- Get (or create) BindableEvent

Response:
function GetEvent(eventName)
	--- Variables
	eventName = string.lower(eventName)
	local event = events[eventName]

	--- Check if event already exists
	if not event then
		--- Create event
		event = Instance.new("BindableEvent")
		event.Name = eventName
		events[eventName] = event
	end

	--
	return event
end


Prompt: --// Modules

Response:
local Zone = require(script['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: --Change sound id to the id you want to play

Response:
debounce = false

script.Parent.Touched:connect(function(hit)
if not debounce then
debounce = true
if(hit.Parent:FindFirstChild("Humanoid")~=nil)then
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
local sound = script.Parent.Sound:Clone()
sound.Parent = player.PlayerGui
sound:Play()
wait(10)--change to how long before the sound plays again after retouching it
end
debounce = false
end
end)


Prompt: -- SETUP ICON TEMPLATE

Response:
local topbarPlusGui = Instance.new("ScreenGui")
topbarPlusGui.Enabled = true
topbarPlusGui.DisplayOrder = 0
topbarPlusGui.IgnoreGuiInset = true
topbarPlusGui.ResetOnSpawn = false
topbarPlusGui.Name = "TopbarPlus"

local activeItems = Instance.new("Folder")
activeItems.Name = "ActiveItems"
activeItems.Parent = topbarPlusGui

local topbarContainer = Instance.new("Frame")
topbarContainer.BackgroundTransparency = 1
topbarContainer.Name = "TopbarContainer"
topbarContainer.Position = UDim2.new(0, 0, 0, 0)
topbarContainer.Size = UDim2.new(1, 0, 0, 36)
topbarContainer.Visible = true
topbarContainer.ZIndex = 1
topbarContainer.Parent = topbarPlusGui
topbarContainer.Active = false

local iconContainer = Instance.new("Frame")
iconContainer.BackgroundTransparency = 1
iconContainer.Name = "IconContainer"
iconContainer.Position = UDim2.new(0, 104, 0, 4)
iconContainer.Visible = false
iconContainer.ZIndex = 1
iconContainer.Parent = topbarContainer
iconContainer.Active = false

local iconButton = Instance.new("TextButton")
iconButton.Name = "IconButton"
iconButton.Visible = true
iconButton.Text = ""
iconButton.ZIndex = 10--2
iconButton.BorderSizePixel = 0
iconButton.AutoButtonColor = false
iconButton.Parent = iconContainer
iconButton.Active = true
iconButton.TextTransparency = 1
iconButton.RichText = true

local iconImage = Instance.new("ImageLabel")
iconImage.BackgroundTransparency = 1
iconImage.Name = "IconImage"
iconImage.AnchorPoint = Vector2.new(0, 0.5)
iconImage.Visible = true
iconImage.ZIndex = 11--3
iconImage.ScaleType = Enum.ScaleType.Fit
iconImage.Parent = iconButton
iconImage.Active = false

local iconLabel = Instance.new("TextLabel")
iconLabel.BackgroundTransparency = 1
iconLabel.Name = "IconLabel"
iconLabel.AnchorPoint = Vector2.new(0, 0.5)
iconLabel.Position = UDim2.new(0.5, 0, 0.5, 0)
iconLabel.Text = ""
iconLabel.RichText = true
iconLabel.TextScaled = false
iconLabel.ClipsDescendants = true
iconLabel.ZIndex = 11--3
iconLabel.Active = false
iconLabel.AutoLocalize = true
iconLabel.Parent = iconButton

local fakeIconLabel = iconLabel:Clone()
fakeIconLabel.Name = "FakeIconLabel"
fakeIconLabel.AnchorPoint = Vector2.new(0, 0)
fakeIconLabel.Position = UDim2.new(0, 0, 0, 0)
fakeIconLabel.Size = UDim2.new(1, 0, 1, 0)
fakeIconLabel.TextTransparency = 1
fakeIconLabel.AutoLocalize = false
fakeIconLabel.Parent = iconLabel.Parent

local iconGradient = Instance.new("UIGradient")
iconGradient.Name = "IconGradient"
iconGradient.Enabled = true
iconGradient.Parent = iconButton

local iconCorner = Instance.new("UICorner")
iconCorner.Name = "IconCorner"
iconCorner.Parent = iconButton

local iconOverlay = Instance.new("Frame")
iconOverlay.Name = "IconOverlay"
iconOverlay.BackgroundTransparency = 1
iconOverlay.Position = iconButton.Position
iconOverlay.Size = UDim2.new(1, 0, 1, 0)
iconOverlay.Visible = true
iconOverlay.ZIndex = iconButton.ZIndex + 1
iconOverlay.BorderSizePixel = 0
iconOverlay.Parent = iconContainer
iconOverlay.Active = false

local iconOverlayCorner = iconCorner:Clone()
iconOverlayCorner.Name = "IconOverlayCorner"
iconOverlayCorner.Parent = iconOverlay