local function G()InfoFrame.Visible=true if not blurEffect then blurEffect=Instance.new("\066\108\117\114\069\102\102\101\099\116")blurEffect.Size=12 blurEffect.Parent=game.Lighting end end local function v()if blurEffect then blurEffect:Destroy()blurEffect=false end InfoFrame.Visible=false end local function S(G)G:MoveTo(MODEL_POSITION)G.PrimaryPart=G:FindFirstChild("\066\111\100\121")if G.PrimaryPart then G:SetPrimaryPartCFrame(MODEL_CFRAME)end end local function d(G)for v,S in ipairs(Container:GetChildren())do if S:IsA("\086\105\101\119\112\111\114\116\070\114\097\109\101")then if S==G then S.BorderColor3=Color3.new(.058823529411765,.50196078431373,1.0)else S.BorderColor3=Color3.new(1,1,1)end end end end local function u()local G=Container:GetChildren()for G,v in ipairs(G)do if v:IsA("\086\105\101\119\112\111\114\116\070\114\097\109\101")then local G=v:FindFirstChild("\066\117\116\116\111\110")if G~=nil then G.Image="\114\098\120\097\115\115\101\116\105\100\058\047\047\052\048\055\057\053\049\049\057\054\057"end end end end local function t()d(nil);(Selected:FindFirstChild("\071\097\114\097\103\101")).Value=nil local G=Selected:GetChildren()for G,v in ipairs(G)do if v:IsA("\077\111\100\101\108")then v:Destroy()end end SelectedName.Text=""end local function l()if InfoFrame.Visible==true then return end SelectionFrame.Visible=false u()d(nil)t()SelectedMode.Value=""end local function g()ContextActionService:UnbindAction("\069\120\105\116\083\112\101\101\100\101\114")RemoveActivePlayer:FireServer()local G=RaceManager:GetRaceStatus()if not TopBar.Enabled or G~=RaceManager.Status.WaitingForPlayers and G~=RaceManager.Status.WaitingForRaceToStart then PlayerConverter:SpeederToPlayer()end end local function h()local G=(Selected:FindFirstChild("\071\097\114\097\103\101")).Value if not G then return end if SelectedMode.Value=="\070\114\101\101\070\108\105\103\104\116"then PlayerConverter:PlayerToSpeeder(G)elseif SelectedMode.Value=="\082\097\099\105\110\103"then AddActivePlayer:FireServer(G)local v=player.PlayerGui local S=v:FindFirstChild("\084\111\112\066\097\114")S.Enabled=true end ContextActionService:BindAction("\069\120\105\116\083\112\101\101\100\101\114",g,false,KEY1)l()end local function W(G)local v=0 for G,d in ipairs(G:GetChildren())do if d:IsA("\077\111\100\101\108")then v=v+1 local G=Instance.new("\086\105\101\119\112\111\114\116\070\114\097\109\101")G.Name=tostring(v)G.Parent=Container G.LayoutOrder=5 G.ZIndex=2 G.BackgroundTransparency=1 G.ClipsDescendants=true local l=Instance.new("\067\097\109\101\114\097")l.Parent=G l.FieldOfView=30 G.CurrentCamera=l local g=Instance.new("\079\098\106\101\099\116\086\097\108\117\101")g.Parent=G g.Name="\071\097\114\097\103\101"g.Value=d local h=d:clone()h.Parent=G S(h)local W=h.PrimaryPart local c=W.Size local s=W.Position+Vector3.new(0,c.Y+10,-c.Z*1.8)l.CFrame=CFrame.new(s,h.PrimaryPart.Position)local L=Instance.new("\073\109\097\103\101\066\117\116\116\111\110")L.Name="\066\117\116\116\111\110"L.Parent=G L.Size=UDim2.new(1,0,1,0)L.BackgroundTransparency=1 L.Image="\114\098\120\097\115\115\101\116\105\100\058\047\047\052\048\055\057\053\049\049\057\054\057"L.HoverImage="\114\098\120\097\115\115\101\116\105\100\058\047\047\052\048\055\057\053\049\050\048\057\057"L.PressedImage="\114\098\120\097\115\115\101\116\105\100\058\047\047\052\048\055\057\053\049\050\048\057\057"L.Activated:Connect(function()local G=Selected:FindFirstChild(SelectedName.Text)local v=Selected:FindFirstChild("\071\097\114\097\103\101")t()u()L.Image="\114\098\120\097\115\115\101\116\105\100\058\047\047\052\048\055\057\053\049\050\048\057\057"v.Value=g.Value local S=h:clone()S.Parent=Selected SelectedName.Text=string.upper(S.Name)local d=S.PrimaryPart local l=d.Size local W=h.PrimaryPart.Position+Vector3.new(0,l.Y+15,-l.Z*1.8)SelectedCamera.CFrame=CFrame.new(W,h.PrimaryPart.Position)end)end Container.CanvasSize=UDim2.new(1*math.ceil(v/6),0,0,0)UIGridLayout.CellSize=UDim2.new(.33333333333333/math.ceil(v/6),-4,.5,-2)end end

local function openInfoGui()
	InfoFrame.Visible = true
	
	if not (blurEffect) then
		blurEffect = Instance.new("BlurEffect")
		blurEffect.Size = 12
		blurEffect.Parent = game.Lighting
	end
end -- openInfoGui()

local function exitInfoGui()
	if blurEffect then
		blurEffect:Destroy()
		blurEffect = false
	end
	InfoFrame.Visible = false
end -- exitInfoGui

local function moveModelForViewport(model)
	-- Performed only to reset model orientation, position does not matter
	model:MoveTo(MODEL_POSITION)
	
	-- Set position so that all models have the same orientation and position
	model.PrimaryPart = model:FindFirstChild("Body")
	if model.PrimaryPart then
		model:SetPrimaryPartCFrame(MODEL_CFRAME)
	end
end -- moveModelForViewport()

local function highlightViewport(viewport)
	for _, child in ipairs(Container:GetChildren()) do
		if child:IsA("ViewportFrame") then
			if child == viewport then
				child.BorderColor3 = Color3.new(15/255, 128/255, 255/255)
			else
				child.BorderColor3 = Color3.new(1, 1, 1)
			end
		end
	end
end

local function unselectButtons()
	local viewports = Container:GetChildren()
	
	for _, viewport in ipairs(viewports) do
		if viewport:IsA("ViewportFrame") then
			local button = viewport:FindFirstChild("Button")
			if button ~= nil then
				button.Image = "rbxassetid://4079511969"
			end
		end
	end
end -- unselectButton()

local function clearSelected()
	highlightViewport(nil)
	
	Selected:FindFirstChild("Garage").Value = nil
	
	local selectedModels = Selected:GetChildren()
	for _, child in ipairs(selectedModels) do
		if child:IsA("Model") then
			child:Destroy()
		end
	end
	
	SelectedName.Text = ""
end -- clearSelected()

local function exit()
	if InfoFrame.Visible == true then return end
	
	SelectionFrame.Visible = false
	
	unselectButtons()
	highlightViewport(nil)
	clearSelected()
	
	SelectedMode.Value = ""
end -- exit()

local function exitSpeeder()
	ContextActionService:UnbindAction("ExitSpeeder")
	RemoveActivePlayer:FireServer()
	
	local raceStatus = RaceManager:GetRaceStatus()
	if not TopBar.Enabled or (raceStatus ~= RaceManager.Status.WaitingForPlayers and
		raceStatus ~= RaceManager.Status.WaitingForRaceToStart) then
		PlayerConverter:SpeederToPlayer()
	end
end -- exit()

local function makeSelection()
	-- Get selection
	local selection = Selected:FindFirstChild("Garage").Value
	if not selection then return end
	
	-- Act according to selected game mode
	if SelectedMode.Value == "FreeFlight" then
		PlayerConverter:PlayerToSpeeder(selection)
	elseif SelectedMode.Value == "Racing" then
		-- Add player to ActivePlayer of PlayerManager for the RaceModules
		AddActivePlayer:FireServer(selection)
		
		-- Show racing GUIs
		local PlayerGui = player.PlayerGui
		local TopBar = PlayerGui:FindFirstChild("TopBar")
		TopBar.Enabled = true
	end
	
	-- Keybinding to exit
	ContextActionService:BindAction("ExitSpeeder", exitSpeeder, false, KEY1)
	
	-- Close window
	exit()
end -- makeSelection()

local function populateList(folder)
	local count = 0
	
	for index, item in ipairs(folder:GetChildren()) do
		if item:IsA("Model") then
			count = count + 1
			
			-- List is populated with ViewportFrames displaying the folder's models
			local viewport = Instance.new("ViewportFrame")
			viewport.Name = tostring(count)
			viewport.Parent = Container
			viewport.LayoutOrder = 5
			viewport.ZIndex = 2
			viewport.BackgroundTransparency = 1
			viewport.ClipsDescendants = true
			
			-- Create camera for ViewportFrame
			local camera = Instance.new("Camera")
			camera.Parent = viewport
			camera.FieldOfView = 30
			viewport.CurrentCamera = camera
		
			-- Point to (server-side) model
			local newGarageModel = Instance.new("ObjectValue")
			newGarageModel.Parent = viewport
			newGarageModel.Name = "Garage"
			newGarageModel.Value = item
			
			-- Clone model and part it to the ViewportFrame
			local newItem = item:clone()
			newItem.Parent = viewport
			
			-- Move model so that all model viewports are from the same angle
			moveModelForViewport(newItem)
			
			local primary = newItem.PrimaryPart
			local primarySize = primary.Size
			
			-- Adjust camera to look at the model
			local cameraPosition = primary.Position + Vector3.new(0, primarySize.Y + 10, -primarySize.Z*1.8)
			camera.CFrame = CFrame.new(cameraPosition, newItem.PrimaryPart.Position)
			
			-- Overlay viewport with a button
			local button = Instance.new("ImageButton")
			button.Name = "Button"
			button.Parent = viewport
			button.Size = UDim2.new(1,0,1,0)
			button.BackgroundTransparency = 1
			button.Image = "rbxassetid://4079511969"
			button.HoverImage = "rbxassetid://4079512099"
			button.PressedImage = "rbxassetid://4079512099"
			button.Activated:Connect(function()
				local selection = Selected:FindFirstChild(SelectedName.Text)
				local garageModel = Selected:FindFirstChild("Garage")
				clearSelected()
				
				unselectButtons()
				button.Image = "rbxassetid://4079512099"
				
				garageModel.Value = newGarageModel.Value
				
				local selectedItem = newItem:clone()
				selectedItem.Parent = Selected
				
				SelectedName.Text = string.upper(selectedItem.Name)
				
				local primary = selectedItem.PrimaryPart
				local primarySize = primary.Size
			
				local cameraPosition = newItem.PrimaryPart.Position + Vector3.new(0, primarySize.Y + 15, -primarySize.Z*1.8)
				SelectedCamera.CFrame = CFrame.new(cameraPosition, newItem.PrimaryPart.Position)
			end)
		end
		
		-- Scale ScrollingFrame to fit list
		Container.CanvasSize = UDim2.new(1*math.ceil(count/6), 0, 0, 0)
		UIGridLayout.CellSize = UDim2.new((1/3)/math.ceil(count/6), -4, 0.5, -2)
	end
end -- populateList()