Pinkstack/roblox-luau-corpus-text huggingface dataset:
--Creates a controller group.


function ControllerGroups:CreateControllerGroup()
	local ControllerGroup = {}
	local Frames = {}
	local Active = false
	local FirstFrame
	
	--Sets the group to be active.
	function ControllerGroup:SetActive(IsActive,IsPriority)
		if IsActive ~= Active then
			if IsActive then
				if IsPriority then
					table.insert(ActivePriorityControllerGroups,1,ControllerGroup)
				else
					table.insert(ActiveControllerGroups,1,ControllerGroup)
				end
			else
				for Id,Group in pairs(ActiveControllerGroups) do
					if Group == ControllerGroup then
						table.remove(ActiveControllerGroups,Id)
						break
					end
				end
				for Id,Group in pairs(ActivePriorityControllerGroups) do
					if Group == ControllerGroup then
						table.remove(ActivePriorityControllerGroups,Id)
						break
					end
				end
				
				UpdateActiveButton()
			end
			
			Active = IsActive
			UpdateActiveButton()
		end
	end
	
	--Set the first frame when the group is activated.
	function ControllerGroup:SetFirstFrame(Frame)
		if ControllerGroup:FrameInGroup(Frame) then
			FirstFrame = Frame
		else
			FirstFrame = nil
		end
	end
	
	--Returns if the frame is in the group.
	function ControllerGroup:FrameInGroup(Frame)
		for _,OtherFrame in pairs(Frames) do
			if Frame == OtherFrame then
				return true
			end
		end
		
		return false
	end
	
	--Adds a frame to the controller group.
	function ControllerGroup:AddFrame(Frame)
		if not ControllerGroup:FrameInGroup(Frame) then
			table.insert(Frames,Frame)
			
			if Active then UpdateActiveButton() end
		end
	end
	
	--Removes a frame from the controller.
	function ControllerGroup:RemoveFrame(Frame)
		for Id,OtherFrame in pairs(Frames) do
			if Frame == OtherFrame then
				table.remove(Frames,Id)
				
				if Active then UpdateActiveButton() end
				return
			end
		end
	end
	
	--Clears all frames in the controller group.
	function ControllerGroup:ClearFrames()
		Frames = {}
		if Active then UpdateActiveButton() end
	end
	
	--Returns if the group is active.
	function ControllerGroup:IsActive()
		return GetActiveGroup() == ControllerGroup
	end
	
	--Returns all the frames in the group.
	function ControllerGroup:GetFrames()
		return Frames
	end
	
	--Returns the first frame in teh group.
	function ControllerGroup:GetFirstFrame()
		return ((FirstFrame and ControllerGroup:FrameInGroup(FirstFrame)) and FirstFrame) or Frames[1]
	end
	
	return ControllerGroup
end
-- -- -- -- -- -- --
--DIRECTION SCROLL--
-- -- -- -- -- -- --




while true do
	wait()
	if Lift:WaitForChild("Direction").Value == 1 then
		This.Display.ARW1.UP.BrickColor = BrickColor.new(ActiveCol)
		This.Display.ARW1.UP.Material = "Neon"
		This.Display.ARW1.MID.BrickColor = BrickColor.new(ActiveCol)
		This.Display.ARW1.MID.Material = "Neon"
		This.Display.ARW1.DOWN.BrickColor = BrickColor.new(InactiveCol)
		This.Display.ARW1.DOWN.Material = "SmoothPlastic"
	elseif Lift:WaitForChild("Direction").Value == -1 then
		This.Display.ARW1.UP.BrickColor = BrickColor.new(InactiveCol)
		This.Display.ARW1.UP.Material = "SmoothPlastic"
		This.Display.ARW1.MID.BrickColor = BrickColor.new(ActiveCol)
		This.Display.ARW1.MID.Material = "Neon"
		This.Display.ARW1.DOWN.BrickColor = BrickColor.new(ActiveCol)
		This.Display.ARW1.DOWN.Material = "Neon"
	else
		This.Display.ARW1.UP.BrickColor = BrickColor.new(InactiveCol)
		This.Display.ARW1.UP.Material = "SmoothPlastic"
		This.Display.ARW1.MID.BrickColor = BrickColor.new(InactiveCol)
		This.Display.ARW1.MID.Material = "SmoothPlastic"
		This.Display.ARW1.DOWN.BrickColor = BrickColor.new(InactiveCol)
		This.Display.ARW1.DOWN.Material = "SmoothPlastic"
	end
end
--[[Engine]]


	--Torque Curve
	Tune.Horsepower		= 135		--	[TORQUE CURVE VISUAL]
	Tune.IdleRPM		= 800		--		https://www.desmos.com/calculator/2uo3hqwdhf
	Tune.PeakRPM		= 8000		--		Use sliders to manipulate values
	Tune.Redline		= 9000		--		Copy and paste slider values into the respective tune values
	Tune.EqPoint		= 6100
	Tune.PeakSharpness	= 3.8
	Tune.CurveMult		= 0.07
	
	--Incline Compensation
	Tune.InclineComp	= 1.5		-- Torque compensation multiplier for inclines (applies gradient from 0-90 degrees)
	
	--Misc
	Tune.RevAccel		= 450		-- RPM acceleration when clutch is off
	Tune.RevDecay		= 150		-- RPM decay when clutch is off
	Tune.RevBounce		= 500		-- RPM kickback from redline
	Tune.IdleThrottle	= 0			-- Percent throttle at idle
	Tune.ClutchTol		= 500		-- Clutch engagement threshold (higher = faster response, lower = more stable RPM)
-- BrailleGen 3D BETA



Align = true

This = script.Parent
Btn = This.Parent
Characters = require(script.Characters)

function ChangeFloor(SF)
	if Align == true then
		if string.len(SF) == 1 then
			SetLabel(1,SF,0.045)	
			SetLabel(2,"NIL",0)
			SetLabel(3,"NIL",0)
			SetLabel(4,"NIL",0)
		elseif string.len(SF) == 2 then
			SetLabel(1,SF:sub(1,1),0.03)	
			SetLabel(2,SF:sub(2,2),0.03)
			SetLabel(3,"NIL",0)
			SetLabel(4,"NIL",0)
		elseif string.len(SF) == 3 then
			SetLabel(1,SF:sub(1,1),0.015)	
			SetLabel(2,SF:sub(2,2),0.015)
			SetLabel(3,SF:sub(3,3),0.015)
			SetLabel(4,"NIL",0)
		elseif string.len(SF) == 4 then
			SetLabel(1,SF:sub(1,1),0)	
			SetLabel(2,SF:sub(2,2),0)
			SetLabel(3,SF:sub(3,3),0)
			SetLabel(4,SF:sub(4,4),0)
		end
	else
		if string.len(SF) == 1 then
			SetLabel(1,SF,0)	
			SetLabel(2,"NIL",0)
			SetLabel(3,"NIL",0)
			SetLabel(4,"NIL",0)
		elseif string.len(SF) == 2 then
			SetLabel(1,SF:sub(1,1),0)	
			SetLabel(2,SF:sub(2,2),0)
			SetLabel(3,"NIL",0)
			SetLabel(4,"NIL",0)
		elseif string.len(SF) == 3 then
			SetLabel(1,SF:sub(1,1),0)	
			SetLabel(2,SF:sub(2,2),0)
			SetLabel(3,SF:sub(3,3),0)
			SetLabel(4,"NIL",0)
		elseif string.len(SF) == 4 then
			SetLabel(1,SF:sub(1,1),0)	
			SetLabel(2,SF:sub(2,2),0)
			SetLabel(3,SF:sub(3,3),0)
			SetLabel(4,SF:sub(4,4),0)
		end
	end
end


function SetLabel(ID,CHAR,OFFSET)
	if This:FindFirstChild("BR"..ID) and Characters[CHAR] ~= nil then
		for i,l in pairs(Characters[CHAR]) do 
			This["BR"..ID].Mesh.MeshId = "rbxassetid://"..l
		end
		if CHAR == "A" or CHAR == "1" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET-0.006, 0, -0.014)
		elseif CHAR == "B" or CHAR == "2" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET-0.006, 0, -0.006)
		elseif CHAR == "C" or CHAR == "3" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET, 0, -0.014)
		elseif CHAR == "D" or CHAR == "4" or CHAR == "E" or CHAR == "5" or CHAR == "F" or CHAR == "6" or CHAR == "G" or CHAR == "7" or CHAR == "H" or CHAR == "8" or CHAR == "I" or CHAR == "9" or CHAR == "J" or CHAR == "0" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET, 0, -0.006)
		elseif CHAR == "K" or CHAR == "L" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET-0.006, 0, 0)
		elseif CHAR == "." or CHAR == "+" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET, 0, 0.006)
		elseif CHAR == "-" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET, 0, 0.014)
		elseif CHAR == ";" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET, 0, 0.006)
		elseif CHAR == "*" then
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET+0.006, 0, 0)
		else
			This["BR"..ID].Mesh.Offset = Vector3.new(OFFSET, 0, 0)
		end
	end
end


ChangeFloor("$"..Btn.Name)

script:Destroy()
-- FUNCTIONS --


Tool.Equipped:Connect(function()
	Character = Tool.Parent
equiped = true
Player.PlayerGui:FindFirstChild("Fists").Enabled = true

	Character.Humanoid.Running:Connect(function(speed)

		if speed == 0 and Equipped.Value == true then -- Walking
			equippedIdle:Play()

		else -- Idle
			equippedIdle:Stop()

		end
	end)
	HRP = Character:WaitForChild("HumanoidRootPart")
	Humanoid = Character:WaitForChild("Humanoid")

	
	
	
	attackRemote:FireServer("Equip")
	attackRemote:FireServer("Unblock")
	val.Value = false

end)

Tool.Unequipped:Connect(function()
	Player.PlayerGui:FindFirstChild("Fists").Enabled = false
	equiped = false
	equippedIdle:Stop()
	attackRemote:FireServer("Unequip")

	attackRemote:FireServer("Unblock")
	val.Value = false	

end)

UIS.InputBegan:Connect(function(Input, isTyping)
	if isTyping then return end

	if Player.Character:FindFirstChild("PBSTUN") then return end
	if Player.Character:FindFirstChild("Running").Value == true then return end
	if Input.UserInputType == Enum.UserInputType.MouseButton1 then
		if not Humanoid then return end
		if Humanoid.Health > 0 then
			local Disabled = Character:FindFirstChild("Disabled")
			if not Disabled then
				
				if UIS:IsKeyDown(Enum.KeyCode.Space) then
					attackRemote:FireServer("Attack", true)
				else
					attackRemote:FireServer("Attack", false)
				end
		
				coroutine.wrap(function()
					local noJumpValue = Instance.new("BoolValue")
					noJumpValue.Name = "noJump"
					noJumpValue.Parent = Character
					game.Debris:AddItem(noJumpValue, 1.4)
				end)()
			end
		end
	
	elseif Input.KeyCode == Enum.KeyCode.F then
		if deb == true then return end
		if not Humanoid then return end
		if Humanoid.Health > 0 then
			local Disabled = Character:FindFirstChild("Disabled")
			if not Disabled then
				val.Value = true
			deb = true
				attackRemote:FireServer("Block")
				wait(1)
				deb = false
			end
		end

	end
end)

UIS.InputEnded:Connect(function(Input, isTyping)
	if isTyping then return end

	if Input.KeyCode == Enum.KeyCode.F then
		attackRemote:FireServer("Unblock")
		val.Value = false
	
	end
end)
-- Define the function to handle the player's input


local function onInput(input, gameProcessed)
	-- Check if the input is a keyboard input and if the player is pressing LeftShift
	if input.UserInputType == Enum.UserInputType.Keyboard and input.KeyCode == Enum.KeyCode.LeftShift and input.UserInputState == Enum.UserInputState.Begin and not gameProcessed then
		dash()
	end
end
--//by wild
--//also hastily written i don't care about making this one look nice



local Sound = workspace.Audios

local vol = {}

vol.table = {}

vol.Reset = function()
	
	for _,v in pairs(Sound.FAAS:GetDescendants()) do
		if v:IsA("Sound") then
			v.PlaybackSpeed = 1
			v:Stop()
		end
	end
	
	for _,v in pairs(Sound.HumanAnnouncements:GetDescendants()) do
		if v:IsA("Sound") then
			v.PlaybackSpeed = 1
			v:Stop()
		end
	end
	
	if game.Players.LocalPlayer.PlayerGui:WaitForChild("UserInterface").GuiController.SettingsModule.PlayerMusicDisabled.Value == false then
		for _,v in pairs(Sound.Music:GetDescendants()) do
			if v:IsA("Sound") then
				v.PlaybackSpeed = 1
				v:Stop()
			end
		end
	end
	
end

vol.Mute = function()

	for _,v in pairs(Sound.FAAS:GetDescendants()) do
		if v:IsA("Sound") then
			v.PlaybackSpeed = 0
			v:Stop()
		end
	end
	
	for _,v in pairs(Sound.HumanAnnouncements:GetDescendants()) do
		if v:IsA("Sound") then
			v.PlaybackSpeed = 0
			v:Stop()
		end
	end
	
	if game.Players.LocalPlayer.PlayerGui:WaitForChild("UserInterface").GuiController.SettingsModule.PlayerMusicDisabled.Value == false then
		for _,v in pairs(Sound.Music:GetDescendants()) do
			if v:IsA("Sound") then
				v.PlaybackSpeed = 0
				v:Stop()
			end
		end
	end
end

return vol
-- A simple function to extend forward paths from (d - 1) to d changes
-- when forward and reverse paths cannot yet overlap.


local function extendPathsF(
	d: number,
	aEnd: number,
	bEnd: number,
	bF: number,
	isCommon: IsCommon,
	aIndexesF: Indexes,
	iMaxF: number
): number
	-- Unroll the first iteration.
	local iF = 0
	local kF = -d -- kF = 2 * iF - d
	-- ROBLOX FIXME? should the values inserted into aIndexesF be 1-based so we don't have to adjust in several places here?
	local aFirst = aIndexesF[iF + 1] -- in first iteration always insert
	local aIndexPrev1 = aFirst -- prev value of [iF - 1] in next iteration
	aIndexesF[iF + 1] += countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon)

	-- Optimization: skip diagonals in which paths cannot ever overlap.
	local nF = d < iMaxF and d or iMaxF

	-- The diagonals kF are odd when d is odd and even when d is even.
	iF += 1
	kF += 2
	while iF <= nF do
		-- To get first point of path segment, move one change in forward direction
		-- from last point of previous path segment in an adjacent diagonal.
		-- In last possible iteration when iF === d and kF === d always delete.
		-- ROBLOX deviation: add one to index for Lua 1-based arrays
		if iF ~= d and aIndexPrev1 < aIndexesF[iF + 1] then
			aFirst = aIndexesF[iF + 1] -- vertical to insert from b
		else
			aFirst = aIndexPrev1 + 1 -- horizontal to delete from a

			if aEnd <= aFirst then
				-- Optimization: delete moved past right of graph.
				return iF - 1
			end
		end

		-- To get last point of path segment, move along diagonal of common items.
		-- ROBLOX deviation: add one to index for Lua 1-based arrays
		aIndexPrev1 = aIndexesF[iF + 1]
		aIndexesF[iF + 1] = aFirst + countCommonItemsF(aFirst + 1, aEnd, bF + aFirst - kF + 1, bEnd, isCommon)

		iF += 1
		kF += 2
	end

	return iMaxF
end
--local BulbSet ={}


local children = model:GetChildren()
for i = 1, #children do
	if children[i].Name == "Light" then
		table.insert(LightSet, children[i])
		table.insert(LightStartingBrightnesses, children[i].SpotLight.Brightness)
	end
end

local function PlaySound()
	model["Sound"]:Play()
end

local function evalNS(ns, time)
	-- If we are at 0 or 1, return the first or last value respectively
	if time == 0 then return ns.Keypoints[1].Value end
	if time == 1 then return ns.Keypoints[#ns.Keypoints].Value end
	-- Step through each sequential pair of keypoints and see if alpha
	-- lies between the points' time values.
	for i = 1, #ns.Keypoints - 1 do
		local this = ns.Keypoints[i]
		local next = ns.Keypoints[i + 1]
		if time >= this.Time and time < next.Time then
			-- Calculate how far alpha lies between the points
			local alpha = (time - this.Time) / (next.Time - this.Time)
			-- Evaluate the real value between the points using alpha
			return (next.Value - this.Value) * alpha + this.Value
		end
	end
end

local function touched(otherPart)
	if(otherPart.Name == "HumanoidRootPart" ) then
		local player = game.Players:FindFirstChild(otherPart.Parent.Name)
		if(player) then
			trigger.CanTouch = false
			
			PlaySound()
			wait (.4)
			
			script.Parent.Light.ParticleEmitter.Enabled = true
			
			for i = 0,loopCount do
				local t = 0.0
				while t < 1.0 do
					for i = 1, #LightSet do
						--local randomized_t = math.round(t + i * 0.1)
						local spotlights = LightSet[i]:GetChildren()
						LightSet[i].Transparency = 1 - evalNS(trigger:GetAttribute("Flicker"), t)
						for j = 1, #spotlights do
							spotlights[j].Brightness = evalNS(trigger:GetAttribute("Flicker"), t) * 1 ---LightStartingBrightnesses[i]
						end
					end
					
					t += dt
					wait(0.01)
				end
			end
			
			for i = 1, #LightSet do
				LightSet[i].SpotLight.Brightness = .25 --LightStartingBrightnesses[i]
			end						
			
			wait(90)
			trigger.CanTouch = true
		end
	end
end

trigger.Touched:Connect(touched)
--[[
	Fires when the local player's MouseButton1 interacts with the
	`ExitButton` GUI. Sets `Interacting` BoolValue to false.
	Returns: None
]]

-- 
function hide()
	MainFrame.Visible = false
	InteractionButton.Visible = false
	InteractionBillboard.Enabled = true
	
	-- Unfreeze the player
	humanoid.WalkSpeed = prevWalkSpeed or humanoid.WalkSpeed
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
end

function show()
	MainFrame.Visible = true
	InteractionButton.Visible = false
	InteractionBillboard.Enabled = false
	
	-- Freeze the player
	prevWalkSpeed = humanoid.WalkSpeed
	humanoid.WalkSpeed = 0
	humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
end
--Casts a ray. It will ignore nearly transparent objects and the tool's parent.


function CastRay(StartPos,Direction,Length)
	local Hit,EndPos = game.Workspace:FindPartOnRay(Ray.new(StartPos,Direction * Length))
	if Hit then
		if (not Tool.Parent or Hit:IsDescendantOf(Tool.Parent)) or Hit.Transparency > 0.9 then
			return CastRay(EndPos + (Direction * 0.01),Direction,Length - ((StartPos - EndPos).magnitude))
		end
	end
	
	return EndPos
end
---------------------------------------------------



This = script.Parent
Lift = This.Parent.Parent.Parent
CustomLabel = require(Lift.CustomLabel)
Characters = require(script.Characters)

CustomText = CustomLabel["CUSTOMFLOORLABEL"]

Lift:WaitForChild("Floor").Changed:connect(function(floor)
  --custom indicator code--
  ChangeFloor(tostring(floor))
end)

function ChangeFloor(SF)
	if CustomText[tonumber(SF)] then
		SF = CustomText[tonumber(SF)]
	end
	SetDisplay(1,(string.len(SF) == 2 and SF:sub(1,1) or "NIL"))		
	SetDisplay(2,(string.len(SF) == 2 and SF:sub(2,2) or SF))
end



function SetDisplay(ID,CHAR)
	if This.Display:FindFirstChild("DIG"..ID) and Characters[CHAR] ~= nil then
 		for i,l in pairs(Characters[CHAR]) do 
			for r=1,7 do	
				This.Display["DIG"..ID]["D"..r].BrickColor = (l:sub(r,r) == "1" and BrickColor.new("Really red") or BrickColor.new("Really black"))
			end
		end
	end
end
------------


local y = (PlayerMouse.Y - Brightness.AbsolutePosition.Y) / Brightness.AbsoluteSize.Y
Brightness.Picker.Position = UDim2.new(.5, 0, y, 0)
v = 1 - y
Brightness.ImageColor3 = Color3.fromHSV(h, s, 1)
Preview.ImageColor3 = Color3.fromHSV(h, s, v)
ChangeColorEvent:FireServer(Preview.ImageColor3)
--[[
	Package link auto-generated by Rotriever
]]


local PackageIndex = script.Parent.Parent.Parent._Index

local Package = require(PackageIndex["JestConsole"]["JestConsole"])

export type Console = Package.Console
export type ConsoleOptions = Package.ConsoleOptions
export type BufferedConsole = Package.BufferedConsole
export type CustomConsole = Package.CustomConsole
export type ConsoleBuffer = Package.ConsoleBuffer
export type LogMessage = Package.LogMessage
export type LogType = Package.LogType
export type LogEntry = Package.LogEntry
export type InspectOptions = Package.InspectOptions


return Package
--[[
	~= EXAMPLE CODE =~
	return function(gui,gTable,guiData)
		local name = gTable.Name
		if name == "YesNoPrompt" then
			local new = Instance.new("ScreenGui")
			local frame = Instance.new("Frame",new)
			frame.Size = UDim2.new(0,400,0,400)
			local yes = Instance.new("TextButton",frame)
			yes.Size = UDim2.new(0.5,0,1,0)
			yes.Text = "Yes"
			local no = yes:Clone()
			no.Text = "No"
			no.Position = UDim2.new(0.5,0,0,0)
			
			local gTable,gIndex = client.UI.Register(new)
			
			local ans
			local waiting = true
			
			gTable.CustomDestroy = function()
				waiting = false
			end
			
			yes.MouseButton1Click:Connect(function()
				ans = "Yes"
				gTable:Destroy()
			end)
			
			no.MouseButton1Click:Connect(function()
				ans = "No"
				gTable:Destroy()
			end)
			
			repeat wait() until ans or not waiting  --// Wait until answer
			return ans or false
		end
	end
	
--]]



service = nil
client = nil

return function(gui: ScreenGui, guiData, gTable)
	local TWEEN_TIME = 2
	local SEQUENCE = {
		Color3.fromRGB(255, 85, 88), 
		Color3.fromRGB(78, 140, 255), 
		Color3.fromRGB(78, 255, 149)
	}
	local CLASSES = {
		Frame = true;
		TextBox = true;
		TextLabel = true;
		TextButton = true;
		ImageLabel = true;
		ImageButton = true; 
		ScrollingFrame = true;
	}
	
	local contents = {}
	local OrgColors = {}
	
	local function getCont(obj)
		for _, v in obj:GetChildren() do 
			if CLASSES[v.ClassName] then
				local OrgColor = {}
				OrgColor.Background = v.BackgroundColor3
				if v:IsA("ImageLabel") or v:IsA("ImageButton") then 
					OrgColor.Image = v.ImageColor3 
				end
				OrgColors[v] = OrgColor
				table.insert(contents, v)
				getCont(v)
			end
		end
	end
	
	getCont(gui)
	
	if gTable.Name == "List" then
		gui.Drag.Main.BackgroundTransparency = 0
	end
	
	local function tweenToColor(color1, color2, time)
		local Info = TweenInfo.new(time, Enum.EasingStyle.Linear)
		for _, v in contents do
			local orgcolor = OrgColors[v]
			v.BackgroundColor3 = color1:lerp(orgcolor.Background, 0.75)
			if orgcolor.Image then
				v.ImageColor3 = color1:lerp(orgcolor.Image, 0.75)
				service.TweenService:Create(v, Info, {
					BackgroundColor3 = color2:lerp(orgcolor.Background, 0.75),
					ImageColor3 = color2:lerp(orgcolor.Image, 0.75)
				}):Play()
			else
				service.TweenService:Create(v, Info, {
					BackgroundColor3 = color2:lerp(orgcolor.Background, 0.75)
				}):Play()
			end
		end
		task.wait(time)
	end
	
	service.TrackTask(`Thread: Colorize_{gTable.Name}`,function()
		repeat 
			for i in SEQUENCE do
				local one, two = SEQUENCE[i], SEQUENCE[i+1] or SEQUENCE[1]
				
				tweenToColor(one, two, TWEEN_TIME)
			end
		until not task.wait(if gTable.Active then 0 else 1) and gTable.Destroyed
		
	end)
end
--[[
function Thread:Wait(t)
	if t ~= nil then
		local TotalTime = 0
		TotalTime = TotalTime + RunService.Heartbeat:Wait()
		while TotalTime < t do
			TotalTime = TotalTime + RunService.Heartbeat:Wait()
		end
	else
		RunService.Heartbeat:Wait()
	end
end

function Thread:Spawn(callback)
	coroutine.resume(coroutine.create(callback))
end

function Thread:Delay(t, callback)
	local timer = Timer.new()
	timer:SetActive(true)
	timer:FireOnTimeReached(t, function()
		self:Spawn(callback)
		timer:Destroy()
	end)
end
]]



function Thread:Wait(t)
	if t ~= nil then
		task.wait(t)
	else
		task.wait()
	end
end

function Thread:Spawn(callback)
	task.spawn(callback)
end

function Thread:Delay(t, callback)
	task.delay(t, callback)
end

return Thread
--ignore table stuff



workspace.DescendantAdded:Connect(function(WHAT)
	if WHAT:IsA("Accessory") or WHAT:IsA("Hat") or WHAT.Name == "HumanoidRootPart" then
		--print("added "..WHAT.Name)
		table.insert(rayignore, WHAT)
	elseif WHAT:IsA("BasePart") and not WHAT.CanCollide and not WHAT.Parent:FindFirstChildOfClass("Humanoid") then
		--print("found nocollide")
		table.insert(rayignore, WHAT)
	end
end)
workspace.DescendantRemoving:Connect(function(WHAT)
	local findthing = table.find(rayignore, WHAT)
	if findthing then
		--print("removed "..WHAT.Name)
		table.remove(rayignore, findthing)
	end
end)

for i,v in pairs(workspace:GetDescendants()) do
	if v:IsA("Accessory") or v:IsA("Hat") or v.Name == "HumanoidRootPart" then
		--print("added "..v.Name.." on start")
		table.insert(rayignore, v)
	elseif v:IsA("BasePart") and not v.CanCollide and not v.Parent:FindFirstChildOfClass("Humanoid") then
		--print("found nocollide on start")
		table.insert(rayignore, v)
	end
end
--[[Engine]]



	--		[TORQUE CURVE VISUAL]
	--		Gas Engine: https://www.desmos.com/calculator/nap6stpjqf
	--		Electric Engine: https://www.desmos.com/calculator/ion9q7zp9t
	--		Use sliders to manipulate values
	--		Edit everything as if your car is NATURALLY aspirated, or as if it lacks a turbo.
	
	Tune.Engine 		= true		-- Enables or disables gas engine
									-- TORQUE CURVE: https://www.desmos.com/calculator/nap6stpjqf
	
	Tune.Horsepower		= 602
	Tune.IdleRPM		= 700
	Tune.PeakRPM		= 8000
	Tune.Redline		= 8250
	Tune.EqPoint		= 5252
	Tune.PeakSharpness	= 20
	Tune.CurveMult		= 0.2
	
	Tune.Electric		= false		-- Enables or disables electric engine
									-- TORQUE CURVE: https://www.desmos.com/calculator/ion9q7zp9t
	
	Tune.ElecHorsepower		= 223
	Tune.ElecMaxTorque		= 173
	
	Tune.ElecTransition1	= 4000
	Tune.ElecHpFrontMult	= 0.15
	
	Tune.ElecTransition2	= 9000
	Tune.ElecHpEndMult		= 2.9
	Tune.ElecHpEndPercent	= 10
	Tune.ElecTqEndMult		= 1.5
	Tune.ElecTqEndPercent	= 27
	
	Tune.ElecRedline		= 16000
	
	Tune.InclineComp	= 1.2		-- Torque compensation multiplier for inclines (applies gradient from 0-90 degrees)
	
	--Turbo Settings
	Tune.Aspiration		= "Natural"												--[[
	[Aspiration]
		"Natural"		: N/A, Naturally aspirated engine
		"Single"		: Single turbocharger
		"Double"		: Twin turbocharger
		"Super"			: Supercharger												]]
	
	Tune.Boost			= 5			-- Max PSI (If you have two turbos and this is 15, the PSI will be 30)
	Tune.TurboSize		= 80		-- Turbo size; the bigger it is, the more lag it has.
	Tune.CompressRatio	= 6			-- The compression ratio (look it up)
	Tune.Sensitivity	= 0.05		-- How quickly the Supercharger (if appllied) will bring boost when throttle is applied. (Increment applied per tick, suggested values from 0.05 to 0.1)
	
	--Misc
	Tune.RevAccel		= 250		-- 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.Flywheel		= 500		-- Flywheel weight (higher = faster response, lower = more stable RPM)