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()

        local isDynamicThumbstickUsingThisInput = false
        if isDynamicThumbstickEnabled then
            local ControlScript = CameraScript.Parent:FindFirstChild("ControlScript")
            if ControlScript then
                local MasterControl = ControlScript:FindFirstChild("MasterControl")
                if MasterControl then
                    local DynamicThumbstickModule = MasterControl:FindFirstChild("DynamicThumbstick")
                    if DynamicThumbstickModule then
                        DynamicThumbstickModule = require(DynamicThumbstickModule)
                        local dynamicInputObject = DynamicThumbstickModule:GetInputObject()
                        isDynamicThumbstickUsingThisInput = (dynamicInputObject == input)
                    end
                end
            end
        end

		if not isDynamicThumbstickUsingThisInput 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 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
			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: -- same as jump for now

Response:
function moveFreeFall()
	RightShoulder.MaxVelocity = jumpMaxLimbVelocity
	LeftShoulder.MaxVelocity = jumpMaxLimbVelocity
	RightShoulder:SetDesiredAngle(3.14)
	LeftShoulder:SetDesiredAngle(-3.14)
	RightHip:SetDesiredAngle(0)
	LeftHip:SetDesiredAngle(0)
end

function moveSit()
	RightShoulder.MaxVelocity = 0.15
	LeftShoulder.MaxVelocity = 0.15
	RightShoulder:SetDesiredAngle(3.14 /2)
	LeftShoulder:SetDesiredAngle(-3.14 /2)
	RightHip:SetDesiredAngle(3.14 /2)
	LeftHip:SetDesiredAngle(-3.14 /2)
end

function getTool()
	for _, kid in ipairs(Figure:GetChildren()) do
		if kid.className == "Tool" then return kid end
	end
	return nil
end

function getToolAnim(tool)
	for _, c in ipairs(tool:GetChildren()) do
		if c.Name == "toolanim" and c.className == "StringValue" then
			return c
		end
	end
	return nil
end

function animateTool()

	if (toolAnim == "None") then
		RightShoulder:SetDesiredAngle(1.57)
		return
	end

	if (toolAnim == "Slash") then
		RightShoulder.MaxVelocity = 0.5
		RightShoulder:SetDesiredAngle(0)
		return
	end

	if (toolAnim == "Lunge") then
		RightShoulder.MaxVelocity = 0.5
		LeftShoulder.MaxVelocity = 0.5
		RightHip.MaxVelocity = 0.5
		LeftHip.MaxVelocity = 0.5
		RightShoulder:SetDesiredAngle(1.57)
		LeftShoulder:SetDesiredAngle(1.0)
		RightHip:SetDesiredAngle(1.57)
		LeftHip:SetDesiredAngle(1.0)
		return
	end
end

function move(time)
	local amplitude
	local frequency

	if (pose == "Jumping") then
		moveJump()
		return
	end

	if (pose == "FreeFall") then
		moveFreeFall()
		return
	end

	if (pose == "Seated") then
		moveSit()
		return
	end

	local climbFudge = 0

	if (pose == "Running") then
    if (RightShoulder.CurrentAngle > 1.5 or RightShoulder.CurrentAngle < -1.5) then
			RightShoulder.MaxVelocity = jumpMaxLimbVelocity
		else
			RightShoulder.MaxVelocity = 0.15
		end
		if (LeftShoulder.CurrentAngle > 1.5 or LeftShoulder.CurrentAngle < -1.5) then
			LeftShoulder.MaxVelocity = jumpMaxLimbVelocity
		else
			LeftShoulder.MaxVelocity = 0.15
		end
		amplitude = 1
		frequency = 9
	elseif (pose == "Climbing") then
		RightShoulder.MaxVelocity = 0.5
		LeftShoulder.MaxVelocity = 0.5
		amplitude = 1
		frequency = 9
		climbFudge = 3.14
	else
		amplitude = 0.1
		frequency = 1
	end

	desiredAngle = amplitude * math.sin(time*frequency)

	RightShoulder:SetDesiredAngle(desiredAngle + climbFudge)
	LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge)
	RightHip:SetDesiredAngle(-desiredAngle)
	LeftHip:SetDesiredAngle(-desiredAngle)

	local tool = getTool()

	if tool then

		animStringValueObject = getToolAnim(tool)

		if animStringValueObject then
			toolAnim = animStringValueObject.Value
			-- message recieved, delete StringValue
			animStringValueObject.Parent = nil
			toolAnimTime = time + .3
		end

		if time > toolAnimTime then
			toolAnimTime = 0
			toolAnim = "None"
		end

		animateTool()

	else
		toolAnim = "None"
		toolAnimTime = 0
	end
end


Response:
function onClicked()
Car.BodyVelocity.velocity = Vector3.new(0, 8, 0)
end
script.Parent.ClickDetector.MouseClick:connect(onClicked)


Prompt: ----- water handler -----

Response:
while true do
	if script.Parent.HotOn.Value == true and script.Parent.ColdOn.Value == true and script.Parent.Plugged.Value == true and water.Scale.Y <= 0.6 then -- if BOTH ON and PLUGGED
		water.Scale = water.Scale + Vector3.new(0, 0.01, 0)
		water.Offset = Vector3.new(0, water.Scale.Y/2, 0)
		hotWater = hotWater + 1
		coldWater = coldWater + 1
		drainSound:Stop()
	elseif (script.Parent.HotOn.Value == true or script.Parent.ColdOn.Value == true) and script.Parent.Plugged.Value == true and water.Scale.Y <= 0.6 then -- if ON and PLUGGED
		water.Scale = water.Scale + Vector3.new(0, 0.01, 0)
		water.Offset = Vector3.new(0, water.Scale.Y/2, 0)
		if script.Parent.HotOn.Value == true then
			hotWater = hotWater + 1
		else
			coldWater = coldWater + 1
		end
		drainSound:Stop()
	elseif (script.Parent.HotOn.Value == true or script.Parent.ColdOn.Value == true) and script.Parent.Plugged.Value == false and water.Scale.Y <= 0.6 then -- if ON and NOT PLUGGED
		if script.Parent.HotOn.Value == true then
			coldWater = coldWater - 1
		else
			hotWater = hotWater - 1
		end
		drainSound:Stop()
	elseif (script.Parent.HotOn.Value == false and script.Parent.ColdOn.Value == false) and script.Parent.Plugged.Value == false and water.Scale.Y > 0 then -- if NOT ON and NOT PLUGGED
		water.Scale = water.Scale + Vector3.new(0, -0.01, 0)
		water.Offset = Vector3.new(0, water.Scale.Y/2, 0)
		coldWater = coldWater - 1
		hotWater = hotWater - 1
		drainSound.TimePosition = 0
		drainSound:Play()
	end

	if coldWater < 1 then
		coldWater = 1
	end
	if hotWater < 1 then
		hotWater = 1
	end

	waterTemp = hotWater/coldWater

	if waterTemp > 1 then
		water.Parent.SteamEmitter.Enabled = true
	else
		water.Parent.SteamEmitter.Enabled = false
	end
	wait(0.1)

	if script.Parent.ColdOn.Value == true or script.Parent.HotOn.Value == true then
		script.Parent.Splash.ParticleEmitter.Enabled = true
	else
		script.Parent.Splash.ParticleEmitter.Enabled = false
	end

	if water.Scale.Y <= 0 then
		drainSound:Stop()
	end
end


Prompt:
--[[
	Performs a fold over the entries in the given dictionary.
]]

Response:
function Functional.FoldDictionary(dictionary, initial, callback)
	local accum = initial

	for key, value in pairs(dictionary) do
		accum = callback(accum, key, value)
	end

	return accum
end


Prompt: --- Skill

Response:
local UIS = game:GetService("UserInputService")
local plr = game.Players.LocalPlayer
local Mouse = plr:GetMouse()
local Debounce = true
Player = game.Players.LocalPlayer
Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://4835590095"

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.C and Debounce == true and Tool.Equip.Value == true and Tool.Active.Value == "None" then
		Debounce = false
		Tool.Active.Value = "FloorSand"
		wait(0.1)
		Track1 = Player.Character.Humanoid:LoadAnimation(Animation)
		Track1:Play()
		wait(0.15)
		script.Fire:FireServer(plr)
	local hum =  Player.Character.Humanoid
	for i = 1,30 do
		wait()
		hum.CameraOffset = Vector3.new(
			math.random(-1,1),
			math.random(-1,1),
			math.random(-1,1)
		)
	end
	hum.CameraOffset = Vector3.new(0,0,0)
	    wait(0.15)
		Tool.Active.Value = "None"
		wait(2)
		Debounce = true
	end
end)


Prompt: --game.ReplicatedStorage.PurchaseCrate.OnClientEvent:connect(CrateOpen);


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

Response:
local v1 = {};
local l__LocalPlayer__2 = game.Players.LocalPlayer;
local u1 = nil;
function v1.init(p1)
	u1 = p1;
end;
local l__TweenService__2 = game:GetService("TweenService");
function v1.flickerLights(p2, p3)
	local u3 = p2;
	spawn(function()
		if typeof(u3) ~= "Instance" then
			if typeof(u3) == "number" then
				u3 = workspace.CurrentRooms:FindFirstChild(u3);
			else
				u3 = nil;
			end;
		end;
		if u3 == nil then
			warn("Cannot find room");
		end;
		local v3 = workspace.CurrentRooms[p2]:WaitForChild("Assets").Light_Fixtures;
		--[[for v4, v5 in pairs(u3:GetDescendants()) do
			if v5:IsA("Model") and (v5.Name == "LightStand" or v5.Name == "Chandelier") then
				table.insert(v3, v5);
			end;
		end;]]
		for v6, v7 in pairs(v3:GetDescendants()) do
			for v8, v9 in pairs(v7:GetDescendants()) do
				if v9:IsA("Light") then
					v9:SetAttribute("B", v9.Brightness);
				end;
			end;
		end;
		l__TweenService__2:Create(game.Lighting, TweenInfo.new(p3 / 2, Enum.EasingStyle.Quart, Enum.EasingDirection.Out, 0, true), {
			Ambient = Color3.new(0, 0, 0)
		}):Play();
		local v10 = tick();
		for v11, v12 in pairs(v3:GetDescendants()) do
			task.spawn(function()
				for v13 = 1, 10000000 do
					task.wait(math.random(24, 70) / 100);
					if v10 + p3 <= tick() then
						break;
					end;
					local v14 = v12.PrimaryPart:FindFirstChild("BulbZap", true);
					if not v14 then
						v14 = game:GetService("ReplicatedStorage").Sounds.BulbZap:Clone();
						v14.Parent = v12.PrimaryPart;
					end;
					if v14 then
						v14.TimePosition = math.random(0, 13) / 20;
						v14.Pitch = v14.Pitch + math.random(-100, 100) / 5000;
						v14:Play();
					end;
					for v15, v16 in pairs(v12:GetDescendants()) do
						if v16:IsA("Light") then
							v16.Brightness = v16:GetAttribute("B");
							l__TweenService__2:Create(v16, TweenInfo.new(0.06, Enum.EasingStyle.Back, Enum.EasingDirection.InOut, 2, true, 0), {
								Brightness = 0
							}):Play();
						end;
					end;
					local l__Neon__17 = v12:FindFirstChild("Neon", true);
					if l__Neon__17 and l__Neon__17.Name == "Neon" then
						l__TweenService__2:Create(l__Neon__17, TweenInfo.new(0.06, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 2, true, 0), {
							Transparency = 1
						}):Play();
					end;
				end;
			end);
		end;
		task.wait(p3 + 0.1);
		for v18, v19 in pairs(v3:GetDescendants()) do
			local v20, v21, v22 = pairs(v19:GetDescendants());
			while true do
				local v23, v24 = v20(v21, v22);
				if not v23 then
					break;
				end;
				if v24:IsA("Light") then
					l__TweenService__2:Create(v24, TweenInfo.new(0.06, Enum.EasingStyle.Back, Enum.EasingDirection.InOut, 2), {
						Brightness = v24:GetAttribute("B")
					}):Play();
				end;
				if v24.Name == "Neon" then
					l__TweenService__2:Create(v24, TweenInfo.new(0.06, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 2), {
						Transparency = 0
					}):Play();
				end;
			end;
		end;
	end);
end;
function v1.tryp(p4, p5)
	spawn(function()
		for v25, v26 in pairs(p4:GetDescendants()) do
			if v26:IsA("BasePart") then
				spawn(function()
					local l__Material__27 = v26.Material;
					v26.Color = Color3.new(0.2, 0, 0);
					l__TweenService__2:Create(v26, TweenInfo.new(p5, Enum.EasingStyle.Quart, Enum.EasingDirection.In), {
						Color = v26.Color
					}):Play();
				end);
			end;
		end;
	end);
	spawn(function()
		for v28, v29 in pairs(p4:GetDescendants()) do
			if v29:IsA("BasePart") and (v29.Name == "Wall" or v29.Name == "Wall_Strip" or v29.Name == "WallAlt" or v29.Name == "Floor" or v29.Name == "Carpet" or v29.Name == "Ceiling") then
				local v30 = { Enum.NormalId.Front, Enum.NormalId.Back, Enum.NormalId.Right, Enum.NormalId.Left, Enum.NormalId.Top, Enum.NormalId.Bottom };
				if v29.Name == "Wall" or v29.Name == "Wall_Strip" or v29.Name == "WallAlt" then
					v30 = { Enum.NormalId.Front, Enum.NormalId.Back, Enum.NormalId.Right, Enum.NormalId.Left };
				end;
				if v29.Name == "Floor" or v29.Name == "Carpet" then
					v30 = { Enum.NormalId.Top };
				end;
				if v29.Name == "Ceiling" then
					v30 = { Enum.NormalId.Bottom };
				end;
				for v31, v32 in pairs(v30) do
					local v33 = game:GetService("ReplicatedStorage").Misc.TryTexture:Clone();
					v33.Face = v32;
					v33.Parent = v29;
					l__TweenService__2:Create(v33, TweenInfo.new(p5 + math.random(0, 100) / 500, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), {
						OffsetStudsU = 10,
						OffsetStudsV = 10,
						Transparency = 1
					}):Play();
					game.Debris:AddItem(v33, p5 + 1);
				end;
			end;
		end;
	end);
end;
function v1.turnOffLights(p6, p7)
	local u4 = p6;
	local u5 = p7;
	spawn(function()
		--[[or v34, v35 in pairs(u4:GetDescendants()) do
			if v35:IsA("Light") and v35:GetAttribute("ToTurnOn") == true then
				v35.Enabled = true;
			end;
		end;]]
		wait(0.2);
		u5 = 0.4;
		if typeof(u4) ~= "Instance" then
			if typeof(u4) == "number" then
				u4 = workspace.CurrentRooms:FindFirstChild(u4);
			else
				u4 = nil;
			end;
		end;
		if u4 == nil then
			warn("Cannot find room");
		end;
		print(u4);
		local v36 = workspace.CurrentRooms[p6]:WaitForChild("Assets").Light_Fixtures;
		--[[for v37, v38 in pairs(u4:GetDescendants()) do
			if v38:IsA("Model") and (v38.Name == "LightStand" or v38.Name == "Chandelier") then
				table.insert(v36, v38);
			end;
		end;]]
		for v39, v40 in pairs(v36:GetDescendants()) do
			for v41, v42 in pairs(v40:GetDescendants()) do
				if v42:IsA("Light") then
					v42:SetAttribute("B", v42.Brightness);
				end;
			end;
		end;
		print("Hello everybody; my name is Markiplier, and here are the amount of light bulbs I own:", #v36);
		l__TweenService__2:Create(game.Lighting, TweenInfo.new(4, Enum.EasingStyle.Quart, Enum.EasingDirection.InOut), {
			Ambient = Color3.new(0, 0, 0)
		}):Play();
		local v43 = tick();
		for v44, v45 in pairs(v36:GetDescendants()) do
			task.spawn(function()
				for v46 = 1, 10000000 do
					task.wait(math.random(24, 70) / 100);
					if v43 + u5 <= tick() then
						break;
					end;
					local v47 = v45.PrimaryPart:FindFirstChild("BulbZap", true);
					if not v47 then
						v47 = game:GetService("ReplicatedStorage").Sounds.BulbZap:Clone();
						v47.Parent = v45.PrimaryPart;
					end;
					if v47 then
						v47.TimePosition = math.random(0, 13) / 20;
						v47.Pitch = v47.Pitch + math.random(-100, 100) / 5000;
						v47:Play();
					end;
					for v48, v49 in pairs(v45:GetDescendants()) do
						if v49:IsA("Light") then
							v49.Brightness = v49:GetAttribute("B");
							l__TweenService__2:Create(v49, TweenInfo.new(0.06, Enum.EasingStyle.Back, Enum.EasingDirection.InOut, 2, true, 0), {
								Brightness = 0
							}):Play();
						end;
					end;
					local l__Neon__50 = v45:FindFirstChild("Neon", true);
					if l__Neon__50 and l__Neon__50.Name == "Neon" then
						l__TweenService__2:Create(l__Neon__50, TweenInfo.new(0.06, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut, 2, true, 0), {
							Transparency = 1
						}):Play();
					end;
				end;
			end);
		end;
		task.wait(u5 + 0.6);
		for v51, v52 in pairs(v36) do
			local v53, v54, v55 = pairs(v52:GetDescendants());
			while true do
				local v56, v57 = v53(v54, v55);
				if not v56 then
					break;
				end;
				if v57:IsA("Light") then
					v57.Brightness = 0.4;
					l__TweenService__2:Create(v57, TweenInfo.new(math.random(1, 10) / 10, Enum.EasingStyle.Elastic, Enum.EasingDirection.InOut, 1), {
						Brightness = 0
					}):Play();
				end;
				if v57.Name == "Neon" then
					v57.Material = Enum.Material.Glass;
				end;
			end;
		end;
		local v58, v59, v60 = pairs(u4:GetDescendants());
		while true do
			local v61, v62 = v58(v59, v60);
			if not v61 then
				break;
			end;
			if v62:IsA("Light") and v62:GetAttribute("ForceOn") ~= true then
				v62.Brightness = 0.4;
				l__TweenService__2:Create(v62, TweenInfo.new(math.random(1, 10) / 15, Enum.EasingStyle.Elastic, Enum.EasingDirection.InOut, math.random(0, 2)), {
					Brightness = 0
				}):Play();
			end;
			if v62:IsA("ParticleEmitter") and v62:GetAttribute("Light") == true then
				v62.Enabled = false;
			elseif v62:IsA("Sound") and v62:GetAttribute("Light") == true then
				v62.Volume = 0;
				v62:Stop();
			end;
		end;
	end);
end;
local u6 = game:GetService("ReplicatedStorage").Shards:GetChildren();
function v1.breakLights(p8, p9, p10)
	local u7 = p10;
	spawn(function()
		wait(0.1);
		if not u7 then
			u7 = 60;
		end;
		local v63 = {};
		for v64, v65 in pairs(p8:GetDescendants()) do
			if (not (not v65:IsA("Model")) and v65.Name == "LightStand" or v65.Name == "Chandelier") and v65:WaitForChild("LightFixture", 0.5):WaitForChild("PointLight", 0.5).Enabled == true then
				table.insert(v63, v65);
			end;
		end;
		for v66, v67 in pairs(p8:GetDescendants()) do
			delay((p8.RoomStart.Position - v67.PrimaryPart.Position).Magnitude / u7 + math.random(0, 10) / 100, function()
				local v68 = v67.PrimaryPart:FindFirstChild("BulbBreak", true);
				if not v68 then
					v68 = game:GetService("ReplicatedStorage").Sounds.BulbBreak:Clone();
					v68.Parent = v67.PrimaryPart;
				end;
				v68.Pitch = v68.Pitch + math.random(-140, 140) / 1000;
				v68.TimePosition = math.random(0, 7) * 3;
				v68:Play();
				game.Debris:AddItem(v68, 2);
				pcall(function()
					u1.shakerel(v67.PrimaryPart.Position, 6, 15, 0, 0.3, Vector3.new(0, 0, 0));
				end);
				for v69 = 1, 4 do
					local v70 = u6[math.random(1, #u6)]:Clone();
					v70.CFrame = v67.PrimaryPart.CFrame + Vector3.new(math.random(-3, 3) / 5, math.random(-3, 3) / 5, math.random(-3, 3) / 5);
					v70.Velocity = Vector3.new(math.random(-6, 6), math.random(-6, 6), math.random(-6, 6));
					v70.RotVelocity = Vector3.new(math.random(-3, 3) / 5, math.random(-3, 3) / 5, math.random(-3, 3) / 5);
					v70.Parent = workspace.CurrentCamera;
					game.Debris:AddItem(v70, math.random(20, 35));
				end;
				for v71, v72 in pairs(v67:GetDescendants()) do
					if v72:IsA("Light") then
						l__TweenService__2:Create(v72, TweenInfo.new(0.06, Enum.EasingStyle.Quart, Enum.EasingDirection.Out, math.random(0, 2), false, 0), {
							Brightness = 0
						}):Play();
						if v72.Parent:FindFirstChild("Neon") then
							v72.Parent:FindFirstChild("Neon").Material = Enum.Material.Glass;
							v72.Parent:FindFirstChild("Neon").Transparency = 1;
						end;
					end;
				end;
			end);
		end;
		local v73, v74, v75 = pairs(p8:GetDescendants());
		while true do
			local v76, v77 = v73(v74, v75);
			if not v76 then
				break;
			end;
			if v77:IsA("Light") and v77:GetAttribute("ForceOn") ~= true then
				if v77.Parent.Name == "LightBase" then
					v77.Brightness = 0.5;
				else
					v77.Enabled = false;
				end;
			end;
			if v77:IsA("ParticleEmitter") and v77:GetAttribute("Light") == true then
				v77.Enabled = false;
			elseif v77:IsA("Sound") and v77:GetAttribute("Light") == true then
				v77.Volume = 0;
				v77:Stop();
			end;
		end;
	end);
end;
local u8 = l__LocalPlayer__2.PlayerGui.MainUI;
local u9 = {
	Seek = { "I SEE YOU", "RUN", "RUN", "YOU CAN'T HIDE", "I'M COMING" }
};
function v1.subtext(p11, p12)
	local u10 = p11;
	spawn(function()
		u8 = l__LocalPlayer__2.PlayerGui.MainUI;
		u10 = u9[u10];
		local v78 = tick();
		for v79 = 1, 10000 do
			local v80 = u8.SubliminalText:Clone();
			v80.Name = "LiveST";
			v80.Text = u10[math.random(1, #u10)];
			v80.Position = UDim2.new(0.5 + math.random(-25, 25) / 100, 0, 0.5 + math.random(-25, 25) / 100, 0);
			v80.Visible = true;
			v80.Parent = u8;
			script.Hitmarker.Pitch = math.random(50, 200) / 10;
			script.Hitmarker:Play();
			game.Debris:AddItem(v80, 0.18);
			wait(math.random(10, 100) / 150);
			if v78 + p12 <= tick() then
				break;
			end;
		end;
	end);
end;
return v1;


Prompt:
--------------------
--| Script Logic |--
--------------------

Response:
MakeSkeleton()
Tool.Equipped:connect(OnEquipped)
Tool.Unequipped:connect(OnUnequipped)


Prompt:
--[=[
	@class Shake
	Create realistic shake effects, such as camera or object shakes.

	Creating a shake is very simple with this module. For every shake,
	simply create a shake instance by calling `Shake.new()`. From
	there, configure the shake however desired. Once configured,
	call `shake:Start()` and then bind a function to it with either
	`shake:OnSignal(...)` or `shake:BindToRenderStep(...)`.

	The shake will output its values to the connected function, and then
	automatically stop and clean up its connections once completed.

	Shake instances can be reused indefinitely. However, only one shake
	operation per instance can be running. If more than one is needed
	of the same configuration, simply call `shake:Clone()` to duplicate
	it.

	Example of a simple camera shake:
	```lua
	local priority = Enum.RenderPriority.Last.Value

	local shake = Shake.new()
	shake.FadeInTime = 0
	shake.Frequency = 0.1
	shake.Amplitude = 5
	shake.RotationInfluence = Vector3.new(0.1, 0.1, 0.1)

	shake:Start()
	shake:BindToRenderStep(Shake.NextRenderName(), priority, function(pos, rot, isDone)
		camera.CFrame *= CFrame.new(pos) * CFrame.Angles(rot.X, rot.Y, rot.Z)
	end)
	```

	Shakes will automatically stop once the shake has been completed. Shakes can
	also be used continuously if the `Sustain` property is set to `true`.

	Here are some more helpful configuration examples:

	```lua
	local shake = Shake.new()

	-- The magnitude of the shake. Larger numbers means larger shakes.
	shake.Amplitude = 5

	-- The speed of the shake. Smaller frequencies mean faster shakes.
	shake.Frequency = 0.1

	 -- Fade-in time before max amplitude shake. Set to 0 for immediate shake.
	shake.FadeInTime = 0

	-- Fade-out time. Set to 0 for immediate cutoff.
	shake.FadeOutTime = 0

	-- How long the shake sustains full amplitude before fading out
	shake.SustainTime = 1

	-- Set to true to never end the shake. Call shake:StopSustain() to start the fade-out.
	shake.Sustain = true

	-- Multiplies against the shake vector to control the final amplitude of the position.
	-- Can be seen internally as: position = shakeVector * fadeInOut * positionInfluence
	shake.PositionInfluence = Vector3.new(1, 1, 1)

	-- Multiplies against the shake vector to control the final amplitude of the rotation.
	-- Can be seen internally as: position = shakeVector * fadeInOut * rotationInfluence
	shake.RotationInfluence = Vector3.new(0.1, 0.1, 0.1)

	```
]=]

Response:
local Shake = {}
Shake.__index = Shake


Prompt:
--[=[
	Takes in a brio and returns an observable that emits the brio, and then completes
	on death.

	@since 3.6.0
	@param project (value: TBrio) -> TProject | Brio<TProject>
	@return (Brio<TBrio>) -> Brio<TProject>
]=]

Response:
function RxBrioUtils.mapBrioBrio(project)
	assert(type(project) == "function", "Bad project")

	return function(brio)
		assert(Brio.isBrio(brio), "Not a brio")

		if brio:IsDead() then
			return Rx.EMPTY
		end

		local observable = project(brio:GetValue())
		assert(Observable.isObservable(observable), "Not an observable")

		return RxBrioUtils.completeOnDeath(brio, observable):Pipe({
			Rx.map(RxBrioUtils._mapResult(brio))
		})
	end
end


Prompt: -- MATH --

Response:
function clamp(low, high, input)
	return math.max(low, math.min(high, input))
end

function ClampVector2(low, high, input)
	return Vector2.new(clamp(low.x, high.x, input.x), clamp(low.y, high.y, input.y))
end


Prompt:
--[=[
	Utility functions involving attributes.
	@class RxAttributeUtils
]=]

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

local Brio = require("Brio")
local Maid = require("Maid")
local Observable = require("Observable")
local Symbol = require("Symbol")

local UNSET_VALUE = Symbol.named("unsetValue")

local RxAttributeUtils = {}


Prompt:
--Not in use but keep here
--[[
function waitForTycoonsPurchaseHandlerNew()
	local tycoons = Tycoons:GetChildren()
	if tycoons[1]then
		if #tycoons[1]:WaitForChild("Purchases"):GetChildren() <= 10 then
			local purchaseHandlerNew = tycoons[1]:FindFirstChild("PurchaseHandlerNew")
			if purchaseHandlerNew ~= nil then
				return purchaseHandlerNew
			else
				wait(0.1)
				return waitForTycoonsPurchaseHandlerNew()
			end
		else
			wait(0.1)
			return waitForTycoonsPurchaseHandlerNew()
		end
	else
		wait(0.1)
		return waitForTycoonsPurchaseHandlerNew()
	end
end

local savedPurchasesNames = {}
spawn(function()
	local purchaseHandlerNew = waitForTycoonsPurchaseHandlerNew()
	local Objects = require(purchaseHandlerNew)
	--Adding purchases names for saves
	for key,value in pairs(Objects) do
		table.insert(savedPurchasesNames,value.Name)
	end
end)
]]


Prompt: --local Screen = carSeat.Parent.AudioPlayerScreen.SurfaceGui <-- soon

Response:
local Song = script.Parent.AudioPlayerGui.Song
local Audio = carSeat.Audio

vol = 1000

function changeSong()

	local effect = carSeat.Audio.EqualizerSoundEffect
	if effect.HighGain == 5 then
		effect.HighGain = -80
		effect.MidGain = -25
		onOff.Text = "IN"
	else
		effect.HighGain = 5
		effect.MidGain = 7
		onOff.Text = "OUT"
	end

end

function playSong()

	local id = player.PlayerGui.AudioPlayer.AudioPlayerGui.TextBox.Text
	Audio:Stop()
	Audio.SoundId = "http://www.roblox.com/asset/?id="..id
	Audio:Play()
	--Screen.Song.Text = game:GetService("MarketplaceService"):GetProductInfo(id).Name
	Song.Text = game:GetService("MarketplaceService"):GetProductInfo(id).Name
	--Screen.ID.Text = id

end

function stopSong()

	Audio:Stop()

end

function volUp()

	if vol + 0.1 <= 5 then
		vol = vol + 0.1
		Audio.Volume = vol
		player.PlayerGui.AudioPlayer.AudioPlayerGui.Vol.Text = tostring(vol*100) .. "%"
		--Screen.Vol.Text = tostring(vol*100) .. "%"
	end

end

function volDown()

	if vol - 0.1 >= 0 then
		vol = vol - 0.1
		Audio.Volume = vol
		player.PlayerGui.AudioPlayer.AudioPlayerGui.Vol.Text = tostring(vol*100) .. "%"
		--Screen.Vol.Text = tostring(vol*100) .. "%"
	end

end

ChangeButton.MouseButton1Click:connect(function()

	changeSong()

end)

VolUpButton.MouseButton1Click:connect(function()

	volUp()

end)

VolDownButton.MouseButton1Click:connect(function()

	volDown()

end)

PlayButton.MouseButton1Click:connect(function()

	playSong()

end)

PauseButton.MouseButton1Click:connect(function()

	stopSong()

end)


Prompt: --- Skill

Response:
repeat wait() until game.Players.LocalPlayer.Character

local Player = game.Players.LocalPlayer
local char = Player.Character
local hum = char:WaitForChild("Humanoid")
local Torso = char:WaitForChild("LowerTorso")
local UIS = game:GetService("UserInputService")
local Mouse = Player:GetMouse()
local toggle = false
local Debounce = true
local Speed = 5
local prevdir = Player.Character.HumanoidRootPart.Orientation.Y

local Anim = Instance.new("Animation")
Anim.AnimationId = script.Anim01.AnimationId
local PlayAnim = hum:LoadAnimation(Anim)

local Tween = game:GetService("TweenService")
local Gui = Player.PlayerGui:WaitForChild("Mochi_Skill_List".. Player.Name):WaitForChild("Frame")

local Cooldown = 7

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.F and Debounce == true and Tool.Equip.Value == true and Tool.Active.Value == "None" then

		PlayAnim:Play()
		toggle = true
		Tool.Active.Value = "5RollerDonut"
		script.Fire:FireServer("Start")
		Gui:FindFirstChild(Tool.Active.Value).Frame.Size = UDim2.new(1, 0, 1, 0)
		local BV = Instance.new("BodyVelocity",Torso)
		BV.Name = "BodyVelocityRollDough"
		BV.MaxForce = Vector3.new(math.huge,0,math.huge)
		prevdir = Player.Character.HumanoidRootPart.Orientation.Y
		while script.Parent.Equip.Value == true and toggle == true do
			Player.Character.HumanoidRootPart.CFrame = CFrame.new(Player.Character.HumanoidRootPart.Position, Vector3.new(Mouse.Hit.p.x,Player.Character.HumanoidRootPart.Position.y,Mouse.Hit.p.z))
			BV.Velocity = Player.Character.HumanoidRootPart.CFrame.lookVector * Speed
			if Speed < 80 then
				Speed = Speed + 1.25
			end
			local MaxAngle = 45
			if (Player.Character.HumanoidRootPart.Orientation.Y - prevdir) >= MaxAngle or (Player.Character.HumanoidRootPart.Orientation.Y - prevdir) <= -MaxAngle  then
				Speed = Speed - (Speed/2)
			end
			wait()
			prevdir = Player.Character.HumanoidRootPart.Orientation.Y
		end
	end
end)

UIS.InputEnded:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.F and Debounce == true and Tool.Equip.Value == true and Tool.Active.Value == "5RollerDonut" then
		PlayAnim:Stop()
		Debounce = false
		toggle = false
		script.Fire:FireServer("Release")
		local BV = Torso:FindFirstChild("BodyVelocityRollDough")
		BV.MaxForce = Vector3.new(5000, 0, 5000)
		wait(0.5)
		BV:Destroy()
		Tween:Create(Gui:FindFirstChild(Tool.Active.Value).Frame, TweenInfo.new(Cooldown), {Size = UDim2.new(0, 0, 1, 0)}):Play()
		Tool.Active.Value = "None"
		wait(Cooldown)
		Speed = 5
		Debounce = true
	end
end)


Prompt:
-- Trove
-- Stephen Leitnick
-- October 16, 2021

Response:
local FN_MARKER = newproxy()
local THREAD_MARKER = newproxy()

local RunService = game:GetService("RunService")

local function GetObjectCleanupFunction(object, cleanupMethod)
	local t = typeof(object)
	if t == "function" then
		return FN_MARKER
	elseif t == "thread" then
		return THREAD_MARKER
	end
	if cleanupMethod then
		return cleanupMethod
	end
	if t == "Instance" then
		return "Destroy"
	elseif t == "RBXScriptConnection" then
		return "Disconnect"
	elseif t == "table" then
		if typeof(object.Destroy) == "function" then
			return "Destroy"
		elseif typeof(object.Disconnect) == "function" then
			return "Disconnect"
		end
	end
	error("Failed to get cleanup function for object " .. t .. ": " .. tostring(object))
end


Prompt: --[[Engine]]

Response:
	--Torque Curve
	Tune.Horsepower		= 500		--	[TORQUE CURVE VISUAL]
	Tune.IdleRPM		= 1000		--		https://www.desmos.com/calculator/2uo3hqwdhf
	Tune.PeakRPM		= 11000		--		Use sliders to manipulate values
	Tune.Redline		= 12000		--		Copy and paste slider values into the respective tune values
	Tune.EqPoint		= 5500
	Tune.PeakSharpness	= 7.5
	Tune.CurveMult		= 0.16

	--Incline Compensation
	Tune.InclineComp	= 1.7			-- Torque compensation multiplier for inclines (applies gradient from 0-90 degrees)

	--Misc
	Tune.RevAccel		= 150		-- RPM acceleration when clutch is off
	Tune.RevDecay		= 75		-- RPM decay when clutch is off
	Tune.RevBounce		= 500		-- RPM kickback from redline
	Tune.IdleThrottle	= 3			-- Percent throttle at idle
	Tune.ClutchTol		= 500		-- Clutch engagement threshold (higher = faster response)


Prompt: -- @ModuleDescription Library for debug functions.

Response:
local Debug = {}
Debug.Replicated = true


Prompt: --Made by Luckymaxer

Response:
Mouse_Icon = "rbxasset://textures/GunCursor.png"
Reloading_Icon = "rbxasset://textures/GunWaitCursor.png"

Tool = script.Parent

Mouse = nil

function UpdateIcon()
	if Mouse then
		Mouse.Icon = Tool.Enabled and Mouse_Icon or Reloading_Icon
	end
end

function OnEquipped(ToolMouse)
	Mouse = ToolMouse
	UpdateIcon()
end

function OnChanged(Property)
	if Property == "Enabled" then
		UpdateIcon()
	end
end

Tool.Equipped:Connect(OnEquipped)
Tool.Changed:connect(OnChanged)


Prompt: -- Initialize resize tool

Response:
local ResizeTool = require(CoreTools:WaitForChild 'Resize')
Core.AssignHotkey('X', Core.Support.Call(Core.EquipTool, ResizeTool));
Core.AddToolButton(Core.Assets.ResizeIcon, 'X', ResizeTool)


Prompt: --PUT THIS SCRIPT IN STARTERPACK, STOP DISLIKING IT BECAUSE YOU DIDN'T USE IT RIGHT

Response:
local sounds = game:GetService('SoundService')
local runtime = game:GetService('RunService')
script:WaitForChild('FootstepSounds').Parent = sounds
local materials = sounds:WaitForChild('FootstepSounds')
local plr = game:GetService("Players").LocalPlayer
repeat wait() until plr.Character
local char = plr.Character
local hrp = char.HumanoidRootPart
local hum = char.Humanoid
local walking

hum.Running:connect(function(speed)
	if speed > hum.WalkSpeed/2 then
		walking = true
	else
		walking = false
	end
end)

function getMaterial()
	local floormat = hum.FloorMaterial
	if not floormat then floormat = 'Air' end
	local matstring = string.split(tostring(floormat),'Enum.Material.')[2]
	local material = matstring
	return material
end

local lastmat
runtime.Heartbeat:connect(function()
	if walking then
		local material = getMaterial()
		if material ~= lastmat and lastmat ~= nil then
			materials[lastmat].Playing = false
		end
		local materialSound = materials[material]
		materialSound.PlaybackSpeed = hum.WalkSpeed/12
		materialSound.Playing = true
		lastmat = material
	else
		for _,sound in pairs(materials:GetChildren()) do
			sound.Playing = false
		end
	end
end)


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)
	if plrData.Money.Gold.Value > 12 then
		return true
	end
	return false
end


Response:
game.Workspace.crewview1.Decal.Texture = "http://www.roblox.com/asset/?id="..(game.Workspace.CurrentLogo.Value)..""
game.Workspace.crew1.Decal.Texture = "http://www.roblox.com/asset/?id="..(game.Workspace.CurrentLogo.Value)..""
game.Workspace.crew2.Decal.Texture = "http://www.roblox.com/asset/?id="..(game.Workspace.CurrentLogo.Value)..""
game.Workspace.crew3.Decal.Texture = "http://www.roblox.com/asset/?id="..(game.Workspace.CurrentLogo.Value)..""


Prompt: --// States

Response:
local L_63_ = false
local L_64_ = false
local L_65_ = false
local L_66_ = false
local L_67_ = false
local L_68_ = true
local L_69_ = false
local L_70_ = false
local L_71_ = false
local L_72_ = false
local L_73_ = false
local L_74_ = false
local L_75_ = false
local L_76_ = false
local L_77_ = false
local L_78_ = false

local L_79_ = false
local L_80_ = false
local L_81_ = false

local L_82_ = false
local L_83_ = true
local L_84_ = true

local L_85_ = false

local L_86_
local L_87_

local L_88_
local L_89_
local L_90_

local L_91_ = L_24_.FireMode

local L_92_ = 0
local L_93_ = false
local L_94_ = true
local L_95_ = false

local L_96_ = 70


Prompt: -- Setup Remote Events

Response:
local function createEvent(eventName)
	local event = game.ReplicatedStorage:FindFirstChild(eventName)
	if not event then
		event = Instance.new("RemoteEvent", game.ReplicatedStorage)
		event.Name = eventName
	end
	return event
end

local updateEvent = createEvent("ROBLOX_PistolUpdateEvent")
local equipEvent = createEvent("ROBLOX_PistolEquipEvent")
local unequipEvent = createEvent("ROBLOX_PistolUnequipEvent")
local fireEvent = createEvent("ROBLOX_PistolFireEvent")
local shotEvent = createEvent("ROBLOX_PistolShotEvent")
local reloadEvent = createEvent("ROBLOX_PistolReloadEvent")
local hitEvent = createEvent("ROBLOX_PistolHitEvent")


Prompt: --now, create the functor:

Response: Create = setmetatable({}, {__call = function(tb, ...) return Create_PrivImpl(...) end})


Prompt:
---------------------------
--Seat Offset (Make copies of this block for passenger seats)

Response:
car.DriveSeat.ChildAdded:connect(function(child)
	if child.Name=="SeatWeld" and child:IsA("Weld") and game.Players:GetPlayerFromCharacter(child.Part1.Parent)~=nil then
		child.C0=CFrame.new(0,-10,0)*CFrame.fromEulerAnglesXYZ(-(math.pi/2),0,0)
	end
end)


Prompt: --// Declarables

Response:
local L_15_ = false

local L_16_ = false
local L_17_ = true

local L_18_ = L_1_:WaitForChild('Resource')
local L_19_ = L_18_:WaitForChild('FX')
local L_20_ = L_18_:WaitForChild('Events')
local L_21_ = L_18_:WaitForChild('HUD')
local L_22_ = L_18_:WaitForChild('Modules')
local L_23_ = L_18_:WaitForChild('SettingsModule')
local L_24_ = require(L_23_:WaitForChild("ClientConfig"))
local L_25_ = L_18_:WaitForChild('Vars')
local L_26_
local L_27_
local L_28_
local L_29_
local L_30_
local L_33_
local L_34_
local L_35_
local L_36_
local L_37_
local L_38_
local L_39_
local L_40_
local L_41_
local L_42_
local L_43_
local L_44_
local L_45_
local L_46_
local L_47_
local L_48_
local L_49_

local L_50_ = L_24_.AimZoom

local L_51_ = L_24_.MouseSensitivity
local L_52_ = L_12_.MouseDeltaSensitivity


Response:
		if script.Parent:FindFirstChild("Face") then
			local g = script.Parent.Face:Clone()
			g.Parent = File
			for _,i in pairs(g:GetChildren()) do
				if i:IsA("Part") or i:IsA("UnionOperation") or i:IsA("MeshPart") then
					i.CanCollide = false
					i.Anchored = false
					local Y = Instance.new("Weld")
					Y.Part0 = Player.Character.Head
					Y.Part1 = g.Middle
					Y.C0 = CFrame.new(0, 0, 0)
					Y.Parent = Player.Character.Head
				end
			end
		end


Prompt: -- Horsepower

Response:
Tune.E_Horsepower	= 223
Tune.EH_FrontMult	= 0.15
Tune.EH_EndMult		= 2.9
Tune.EH_EndPercent	= 7


Prompt: -- params : ...

Response:
wait(1)
frame = script.Parent.Parent.Parent
local children = (script.Parent:GetChildren())
local call = nil
local picture = false
for i = 1, #children do
	if children[i].ClassName == "StringValue" then
		call = children[i]
	else
		if children[i].ClassName == "IntValue" then
			call = children[i]
			picture = true
		end
	end
end
print(call.Name)
click = function()

	local board = frame.SmartboardObj.Value
	board.SurfaceGui.RemoteEvents.Post:FireServer(call.Name, call.Value)
end

script.Parent.MouseButton1Click:connect(click)


Prompt:
--[[for n = 1,80 do
wait(0.005)
script.Parent.Parent.Parent.Grabber.Claw.Body.Rope.Length = script.Parent.Parent.Claw.Body.Rope.Length + 0.175
end]]

Response:
script.Parent.Parent.Parent.Grabber.Claw.Body.Rope.WinchTarget = 15
wait(3)
script.Parent.Parent.Prong1.Motor.HingeConstraint.TargetAngle = -5
script.Parent.Parent.Prong2.Motor.HingeConstraint.TargetAngle = -5
script.Parent.Parent.Prong3.Motor.HingeConstraint.TargetAngle = -5
wait(0.25)
script.Parent.Parent.Parent.Grabber.Claw.Body.Rope.WinchTarget = 0.1
wait(4)


Prompt: --[[Brakes]]

Response:
	Tune.ABSEnabled		= true		-- Implements ABS
	Tune.ABSThreshold	= 20		-- Slip speed allowed before ABS starts working (in SPS)

	Tune.FBrakeForce	= 1500		-- Front brake force
	Tune.RBrakeForce	= 1090		-- Rear brake force
	Tune.PBrakeForce	= 5000		-- Handbrake force

	Tune.FLgcyBForce	= 15000		-- Front brake force [PGS OFF]
	Tune.RLgcyBForce	= 10000		-- Rear brake force [PGS OFF]
	Tune.LgcyPBForce	= 25000		-- Handbrake force [PGS OFF]


Prompt:
--[[
	Defines utilities for working with 'list-like' tables.
]]

Response:
return {
	filter = require(script.filter),
	filterMap = require(script.filterMap),
	find = require(script.find),
	findWhere = require(script.findWhere),
	foldLeft = require(script.foldLeft),
	foldRight = require(script.foldRight),
	getRange = require(script.getRange),
	join = require(script.join),
	map = require(script.map),
	removeIndex = require(script.removeIndex),
	removeRange = require(script.removeRange),
	removeValue = require(script.removeValue),
	replaceIndex = require(script.replaceIndex),
	reverse = require(script.reverse),
	sort = require(script.sort),
	toSet = require(script.toSet),
}


Response:
local  Paint = false

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


Prompt:
-- ROBLOX deviation START chalk_chainable: Lua Chalk doesn't support chainable calls. Using nested calls instead
-- Explicitly reset for these messages since they can get written out in the
-- middle of error logging

Response:
local LONG_TEST_COLOR = function(...)
	return chalk.reset(chalk.bold(chalk.bgRed(...)))
end
local FAIL_TEXT = "FAIL"
local PASS_TEXT = "PASS"


Response:
local superLongLength = 2.85
local longLength = 2
local shortLength = 0.85

local ts = game.TweenService
local ti = TweenInfo.new(shortLength, Enum.EasingStyle.Circular, Enum.EasingDirection.InOut)
local ti2 = TweenInfo.new(longLength, Enum.EasingStyle.Circular, Enum.EasingDirection.InOut)
local ti3 = TweenInfo.new(superLongLength, Enum.EasingStyle.Circular, Enum.EasingDirection.InOut)


Prompt: --Creates a client-side buffer.

Response:
function BufferCreator:CreateClientBuffer(BufferName)
	return CreateBuffer(Tool:WaitForChild(BufferName))
end

return BufferCreator


Prompt: --[[Transmission]]

Response:
	Tune.Clutch			= true		-- Implements a realistic clutch, change to "false" for the chassis to act like AC6.81T.

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

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

	Tune.ClutchMode		= "New"												--[[
	[Modes]
		"New"		: Speed controls clutch engagement			(AC6C V1.2)
		"Old"		: Speed and RPM control clutch engagement	(AC6C V1.1)		]]

	Tune.ClutchType 	= "Clutch"										--[[
	[Types]
		"Clutch"			: Standard clutch, recommended
		"TorqueConverter"	: Torque converter, keeps RPM up
		"CVT"				: CVT, found in scooters
																		]]
	--[[Transmission]]
	--Transmission Settings
	Tune.Stall			= true		-- Stalling, enables the car to stall. An ignition plugin would be necessary. Disables if Tune.Clutch is false.
	Tune.ClutchRel		= false		-- If true, the driver must let off the gas before shifting to a higher gear. Recommended false for beginners.
	Tune.ClutchEngage	= 10		-- How fast engagement is (0 = instant, 99 = super slow)
	Tune.SpeedEngage 	= 20		-- Speed the clutch fully engages at (Based on SPS)

	Tune.ClutchKick			= true	-- (LuaInt)
	Tune.KickMult			= 15	-- Torque multiplier on launch
	Tune.KickSpeedThreshold = 40	-- Speed limit on launch (SPS)
	Tune.KickRPMThreshold 	= 1000	-- RPM limit on launch, range is created below redline

	--Clutch: "Old" mode
	Tune.ClutchRPMMult	= 1.0		-- Clutch RPM multiplier, recommended to leave at 1.0

	--Torque Converter:
	Tune.TQLock 		= false		-- Torque converter starts locking at a certain RPM

	--Torque Converter and CVT:
	Tune.RPMEngage 		= 3500		-- Keeps RPMs to this level until passed

	--Neutral Rev Limiter (Avxnturador)
	Tune.NeutralLimit	= false		-- Enables a different redline RPM for when the car is in neutral
	Tune.NeutralRevRPM	= 5000		-- The rev limiter when the car is in neutral
	Tune.LimitClutch	= false		-- Will also limit RPMs while the clutch is pressed down

	--Automatic Settings
	Tune.AutoShiftMode	= "RPM"												--[[
	[Modes]
		"Speed"		: Shifts based on wheel speed
		"RPM"		: Shifts based on RPM										]]
	Tune.AutoShiftType	= "DCT"												--[[
	[Types]
		"Rev"		: Clutch engages fully once RPM reached			(AC6C V1)
		"DCT"		: Clutch engages after a set time has passed	(AC6.81T)	]]
	Tune.AutoShiftVers	= "New"												--[[
	[Versions]
		"New"		: Shift from Reverse, Neutral, and Drive		(AC6.81T)
		"Old"		: Auto shifts into R or D when stopped.			(AC6.52S2)	]]
	Tune.AutoUpThresh	= -200		-- Automatic upshift point 	(relative to peak RPM, positive = Over-rev)
	Tune.AutoDownThresh = 1400		-- Automatic downshift point (relative to peak RPM, positive = Under-rev)

	--Automatic: Revmatching
	Tune.ShiftThrot		= 100		-- Throttle level when shifting down to revmatch, 0 - 100%

	--Automatic: DCT
	Tune.ShiftUpTime	= 0.25		-- Time required to shift into next gear, from a lower gear to a higher one.
	Tune.ShiftDnTime	= 0.125		-- Time required to shift into next gear, from a higher gear to a lower one.

	--Gear Ratios

	Tune.FinalDrive		= 3.545
	Tune.Ratios			= {
		--[[Reverse]]	3.28		,
		--[[Neutral]]	0			,
		--[[ 1 ]]		3.827		,
		--[[ 2 ]]		2.36		,
		--[[ 3 ]]		1.685		,
		--[[ 4 ]]		1.313		,
		--[[ 5 ]]		1			,
		--[[ 6 ]]		.793		,
	}
	Tune.FDMult			= 1			-- Ratio multiplier (keep this at 1 if car is not struggling with torque)


Prompt: --Method to find the teleporters

Response:
function Register:GetTeleporter(name)
	return info[name] --Simply return the value we stored
end


Prompt: -- RANK, RANK NAMES & SPECIFIC USERS

Response:
Ranks = {
	{5,	"Owner",		};
	{4,	"Co-owner",	{"",0},	};
	{3,	"Staff",		{"",0},	};
	{2,	"Moderator",			{"",0},	};
	{1,	"VIP",			{"",0},	};
	{0,	"NonAdmin",		};
};