Pinkstack/roblox-luau-corpus-text huggingface dataset:
-- Returns all screen GUI objects


function GuiController:getOtherScreenGuis()
	local instances = Cryo.List.filter(self.player.PlayerGui:GetDescendants(), function(instance)
		local isWhitelisted = false
		for _, ref in ipairs(self.whitelist) do
			if ref:getValue() == instance then
				isWhitelisted = true
				break
			end
		end

		return instance:IsA("ScreenGui") and instance.Enabled and not isWhitelisted
	end)

	return instances
end

function GuiController:getShownCoreGuis()
	local shownCoreGuis = Cryo.List.filter(Enum.CoreGuiType:GetEnumItems(), function(coreGuiType)
		return self.StarterGui:GetCoreGuiEnabled(coreGuiType) and coreGuiType ~= Enum.CoreGuiType.All
	end)

	return shownCoreGuis
end

return GuiController
-- Image shortcuts: you can use these string instead of using image ids


richText.ImageShortcuts = {}
richText.ImageShortcuts.Eggplant = 639588687
richText.ImageShortcuts.Thinking = 955646496
richText.ImageShortcuts.Sad = 947900188
richText.ImageShortcuts.Happy = 414889555
richText.ImageShortcuts.Despicable = 711674643
-- Extracted this function from Connect as it results in the closure
-- made in Connect using less memory because this function can be static


local function Disconnect<T...>(self: Signal<T...>, Node: SignalNode<T...>)
	if self.Root == Node then
		self.Root = Node.Next
	else
		local Current = self.Root

		while Current do
			if Current.Next == Node then
				Current.Next = Node.Next
				break
			end

			Current = Current.Next
		end
	end
end

function Signal.Connect<T...>(self: Signal<T...>, Callback: (T...) -> ()): () -> ()
	local Node = {
		Next = self.Root,
		Callback = Callback,
	}

	self.Root = Node

	return function()
		Disconnect(self, Node)
	end
end

function Signal.Wait<T...>(self: Signal<T...>): T...
	local Thread = coroutine.running()
	local Disconnect

	Disconnect = self:Connect(function(...)
		Disconnect()
		coroutine.resume(Thread, ...)
	end)

	return coroutine.yield()
end

function Signal.Once<T...>(self: Signal<T...>, Callback: (T...) -> ()): () -> ()
	local Disconnect

	Disconnect = self:Connect(function(...)
		Disconnect()
		Callback(...)
	end)

	return Disconnect
end

function Signal.Fire<T...>(self: Signal<T...>, ...: T...)
	local Current = self.Root

	while Current do
		Spawn(Current.Callback, ...)
		Current = Current.Next
	end
end

function Signal.DisconnectAll<T...>(self: Signal<T...>)
	self.Root = nil
end

return function<T...>(): Signal<T...>
	return setmetatable({
		Root = nil,
	}, Signal) :: any
end
--[[Engine]]


	--Torque Curve
	Tune.Horsepower		= 268		--	[TORQUE CURVE VISUAL]
	Tune.IdleRPM		= 700		--		https://www.desmos.com/calculator/2uo3hqwdhf
	Tune.PeakRPM		= 7000		--		Use sliders to manipulate values
	Tune.Redline		= 7500		--		Copy and paste slider values into the respective tune values
	Tune.ComfortShift   = 5250
	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)
--[[Engine]]


	--Torque Curve
	Tune.Horsepower		= 325		--	[TORQUE CURVE VISUAL]
	Tune.IdleRPM		= 700		--		https://www.desmos.com/calculator/2uo3hqwdhf
	Tune.PeakRPM		= 6000		--		Use sliders to manipulate values
	Tune.Redline		= 6700		--		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	= 4.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)
--NOTE: speed may be slower than you want due to server lag


local waittime = speed/60

while true do
	for x=1,20 do
		color = Color3.new(color.r+.05,0,color.b-.05)
		particle.Color = ColorSequence.new(color)
		wait(waittime)
	end
	for x=1,20 do
		color = Color3.new(color.r-.05,color.g+.05,0)
		particle.Color = ColorSequence.new(color)
		wait(waittime)
	end
	for x=1,20 do
		color = Color3.new(0,color.g-.05,color.b+.05)
		particle.Color = ColorSequence.new(color)
		wait(waittime)
	end
end
--[[
===========================================================================
  Notes:
  (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
      and can be 0: OP_CALL then sets 'top' to last_result+1, so
      next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use 'top'.
  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
      set top (like in OP_CALL with C == 0).
  (*) In OP_RETURN, if (B == 0) then return up to 'top'
  (*) In OP_SETLIST, if (B == 0) then B = 'top';
      if (C == 0) then next 'instruction' is real C
  (*) For comparisons, A specifies what condition the test should accept
      (true or false).
  (*) All 'skips' (pc++) assume that next instruction is a jump
===========================================================================
--]]
--[[Weight and CG]]

--
Tune.Weight			= 450 + 150 -- Bike weight in LBS 
Tune.WeightBrickSize	= {		-- Size of weight brick (dimmensions in studs ; larger = more stable)
	--[[Width]]		3	,
	--[[Height]]	3	,
	--[[Length]]	8	}

Tune.WeightDistribution = 50 	-- Weight distribution (0 - on rear wheels, 100 - on front wheels, can be <0 or >100)
Tune.CGHeight		= 0.8 		-- Center of gravity height (studs relative to median of the wheels)
Tune.WBVisible		= false 	-- Makes the weight brick visible (Debug)
Tune.BalVisible		= false 	-- Makes the balance brick visible (Debug)
--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


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



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

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

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

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

Gravity = 196.20

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

DisplayParts = {}

Rate = (1 / 60)

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

if not Humanoid then
	DestroyScript()
	return
end

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

Objects = Functions.Redesign(Character)

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

Objects = Functions.Redesign(FakeModel)

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

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

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

Functions.Weld(FakeModel, BoundaryBox)

Debris:AddItem(FakeModel, 10)
FakeModel.Parent = game:GetService("Workspace")
-- The comments below explain what the code does, so that you can have a better understanding about exactly how it works.



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

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

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



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


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

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


while true do
	if Target.Value then
		if Target.Value.Parent then
			Missile.CFrame = CFrame.new(Missile.Position,Target.Value.Torso.Position)
			BV.velocity = Missile.CFrame.lookVector * 1500
		else
			break
		end
	else
		break
	end
	wait()
end
--// All global vars will be wiped/replaced except script
--// All guis are autonamed client.Variables.CodeName..gui.Name



return function(data, env)
	if env then
		setfenv(1, env)
	end
	
	local gui = script.Parent.Parent
	local playergui = service.PlayerGui
	local str = data.Message
	local time = data.Time or 15

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

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

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

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

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

	local children = container:children()

	gui.Position = UDim2.new(0,0,0,-100)
	gui.Frame.msg.Text = str
	local bounds = gui.Frame.msg.TextBounds.X
	
	spawn(function()
		local sound = Instance.new("Sound",service.LocalContainer())
		sound.SoundId = "rbxassetid://255881176"
		sound.Volume = 0.25
		wait(0.1)
		sound:Play()
		wait(0.8)
		sound:Destroy()
	end)

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

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

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

	wait(data.Time or 5)

	if gui and gui.Parent then
		moveGuis(-2,gui)
		gui:Destroy()
		--gui:TweenPosition(UDim2.new(0,0,0,-100),nil,nil,0.2,true,function() if gui and gui.Parent then gui:Destroy() end end)
	end
end
--// Use the below table to define "pre-set" command aliases
--// Command aliases; Format: {[":alias <arg1> <arg2> ..."] = ":command <arg1> <arg2> ..."}


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

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

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

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

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

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


function TribeModule:ChangeMemberRole(playerName)
	
end

function TribeModule:TransferTribe(tribeName,playerName)
	
end

function TribeModule:AddMember(playerName)
	
end

function TribeModule:RemoveMember(tribeName,playerName)
	
end

function TribeModule:AddLeader(playerName)
	
end

function TribeModule:RemoveLeader(tribeName,playerName)
	
end

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


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

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

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

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

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

		return maid
	end)
end
----  \/Cruise\/


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


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

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


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

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


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

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

--]]




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


local Option = require(script.Parent.Option)

local Ser = {}

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


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


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


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


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


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


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


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


return Ser
-- Connections
-- Set initial level and progress


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