Pinkstack/roblox-luau-corpus-text huggingface dataset:
--- Skip forwards in now
-- @param delta now to skip forwards


function Spring:TimeSkip(delta)
	local now = self._clock()
	local position, velocity = self:_positionVelocity(now+delta)
	self._position0 = position
	self._velocity0 = velocity
	self._time0 = now
end

function Spring:__index(index)
	if Spring[index] then
		return Spring[index]
	elseif index == "Value" or index == "Position" or index == "p" then
		local position, _ = self:_positionVelocity(self._clock())
		return position
	elseif index == "Velocity" or index == "v" then
		local _, velocity = self:_positionVelocity(self._clock())
		return velocity
	elseif index == "Target" or index == "t" then
		return self._target
	elseif index == "Damper" or index == "d" then
		return self._damper
	elseif index == "Speed" or index == "s" then
		return self._speed
	elseif index == "Clock" then
		return self._clock
	else
		error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
	end
end

function Spring:__newindex(index, value)
	local now = self._clock()

	if index == "Value" or index == "Position" or index == "p" then
		local _, velocity = self:_positionVelocity(now)
		self._position0 = value
		self._velocity0 = velocity
		self._time0 = now
	elseif index == "Velocity" or index == "v" then
		local position, _ = self:_positionVelocity(now)
		self._position0 = position
		self._velocity0 = value
		self._time0 = now
	elseif index == "Target" or index == "t" then
		local position, velocity = self:_positionVelocity(now)
		self._position0 = position
		self._velocity0 = velocity
		self._target = value
		self._time0 = now
	elseif index == "Damper" or index == "d" then
		local position, velocity = self:_positionVelocity(now)
		self._position0 = position
		self._velocity0 = velocity
		self._damper = math.clamp(value, 0, 1)
		self._time0 = now
	elseif index == "Speed" or index == "s" then
		local position, velocity = self:_positionVelocity(now)
		self._position0 = position
		self._velocity0 = velocity
		self._speed = value < 0 and 0 or value
		self._time0 = now
	elseif index == "Clock" then
		local position, velocity = self:_positionVelocity(now)
		self._position0 = position
		self._velocity0 = velocity
		self._clock = value
		self._time0 = value()
	else
		error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
	end
end

function Spring:_positionVelocity(now)
	local p0 = self._position0
	local v0 = self._velocity0
	local p1 = self._target
	local d = self._damper
	local s = self._speed

	local t = s*(now - self._time0)
	local d2 = d*d

	local h, si, co
	if d2 < 1 then
		h = math.sqrt(1 - d2)
		local ep = math.exp(-d*t)/h
		co, si = ep*math.cos(h*t), ep*math.sin(h*t)
	elseif d2 == 1 then
		h = 1
		local ep = math.exp(-d*t)/h
		co, si = ep, ep*t
	else
		h = math.sqrt(d2 - 1)
		local u = math.exp((-d + h)*t)/(2*h)
		local v = math.exp((-d - h)*t)/(2*h)
		co, si = u + v, u - v
	end

	local a0 = h*co + d*si
	local a1 = 1 - (h*co + d*si)
	local a2 = si/s

	local b0 = -s*si
	local b1 = s*si
	local b2 = h*co - d*si

	return
		a0*p0 + a1*p1 + a2*v0,
		b0*p0 + b1*p1 + b2*v0
end

return Spring
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------




function onRunning(speed)
	if speed>0 then
		playAnimation("walk", 0.1, Humanoid)
		pose = "Running"
	else
		playAnimation("idle", 0.1, Humanoid)
		pose = "Standing"
	end
end

function onDied()
	pose = "Dead"
end

function onJumping()
	playAnimation("jump", 0.1, Humanoid)
	jumpAnimTime = jumpAnimDuration
	pose = "Jumping"
end

function onClimbing()
	playAnimation("climb", 0.1, Humanoid)
	pose = "Climbing"
end

function onGettingUp()
	pose = "GettingUp"
end

function onFreeFall()
	if (jumpAnimTime <= 0) then
		playAnimation("fall", fallTransitionTime, Humanoid)
	end
	pose = "FreeFall"
end

function onFallingDown()
	pose = "FallingDown"
end

function onSeated()
	pose = "Seated"
end

function onPlatformStanding()
	pose = "PlatformStanding"
end

function onSwimming(speed)
	if speed>0 then
		pose = "Running"
	else
		pose = "Standing"
	end
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
		playToolAnimation("toolnone", toolTransitionTime, Humanoid)
		return
	end

	if (toolAnim == "Slash") then
		playToolAnimation("toolslash", 0, Humanoid)
		return
	end

	if (toolAnim == "Lunge") then
		playToolAnimation("toollunge", 0, Humanoid)
		return
	end
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

local lastTick = 0

function move(time)
	local amplitude = 1
	local frequency = 1
  	local deltaTime = time - lastTick
  	lastTick = time

	local climbFudge = 0
	local setAngles = false

  	if (jumpAnimTime > 0) then
  		jumpAnimTime = jumpAnimTime - deltaTime
  	end

	if (pose == "FreeFall" and jumpAnimTime <= 0) then
		playAnimation("fall", fallTransitionTime, Humanoid)
	elseif (pose == "Seated") then
		stopAllAnimations()
		moveSit()
		return
	elseif (pose == "Running") then
		playAnimation("walk", 0.1, Humanoid)
	elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then
--local Screen = carSeat.Parent.AudioPlayerScreen.SurfaceGui <-- soon


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

vol = 0.2

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.2 <= 100 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

VolUpButton.MouseButton1Click:connect(function()
	
	volUp()
	
end)

VolDownButton.MouseButton1Click:connect(function()
	
	volDown()
	
end)

PlayButton.MouseButton1Click:connect(function()
	
	playSong()
	
end)

PauseButton.MouseButton1Click:connect(function()
	
	stopSong()
	
end)
-- CONSTANTS



local GuiLib = script.Parent.Parent
local Lazy = require(GuiLib:WaitForChild("LazyLoader"))
local Defaults = GuiLib:WaitForChild("Defaults")

local UIS = game:GetService("UserInputService")

local VALID_PRESS = {
	[Enum.UserInputType.MouseButton1] = true;
	[Enum.UserInputType.Touch] = true;
}

local ARROW_UP = "rbxassetid://5154078925"
local ARROW_DOWN = "rbxassetid://5143165549"

local DROP_BUTTON = Defaults:WaitForChild("DropdownButton")
--[[**
	ensures value is a number where value <= max

	@param max The maximum to use

	@returns A function that will return true iff the condition is passed
**--]]


function t.numberMax(max)
	return function(value)
		local success, errMsg = t.number(value)
		if not success then
			return false, errMsg
		end

		if value <= max then
			return true
		else
			return false, string.format("number <= %s expected, got %s", max, value)
		end
	end
end
---------------------------------------------------------------


function onChildAdded(something)
	if something.Name == "SeatWeld" then
		local human = something.part1.Parent:findFirstChild("Humanoid") 
		if (human ~= nil) then
			s.carName.Value = s.Parent.Parent.Name
			s.carName:clone().Parent = game.Players:findFirstChild(human.Parent.Name).PlayerGui
		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")
			game.Players:findFirstChild(human.Parent.Name).PlayerGui.carName:remove()
		end
	end
end


script.Parent.ChildAdded:connect(onChildAdded)
script.Parent.ChildRemoved:connect(onChildRemoved)
--[=[
	Switch map but for brios. The resulting observable will be
	disconnected on the end of the brio's life.

	Like [RxBrioUtils.switchMap] but emitted values are wrapped in brios.
	The lifetime of this brio is limited by the lifetime of the
	input brios, which are unwrapped and repackaged.

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


function RxBrioUtils.switchMapBrio(project)
	assert(type(project) == "function", "Bad project")

	return Rx.switchMap(RxBrioUtils.mapBrioBrio(project))
end
-- same as jump for now



function moveFreeFall()
	RightShoulder.MaxVelocity = 0.5
	LeftShoulder.MaxVelocity = 0.5
	RightShoulder.DesiredAngle = 3.14
	LeftShoulder.DesiredAngle = -3.14 
	RightHip.DesiredAngle = 0
	LeftHip.DesiredAngle = 0	
end

function moveSit()
	RightShoulder.MaxVelocity = 0.15
	LeftShoulder.MaxVelocity = 0.15
	RightShoulder.DesiredAngle = 3.14/2
	LeftShoulder.DesiredAngle = -3.14/2
	RightHip.DesiredAngle = 3.14/2
	LeftHip.DesiredAngle = -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
		RightShoulderdDesiredAngle = 1.57
		return
	end

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

	if (toolAnim == "Lunge") then
		RightShoulder.MaxVelocity = 0.5
		LeftShoulder.MaxVelocity = 0.5
		RightHip.MaxVelocity = 0.5
		LeftHip.MaxVelocity = 0.5
		RightShoulder.DesiredAngle = 1.57
		LeftShoulder.DesiredAngle = 0 
		RightHip.DesiredAngle = 1.57
		LeftHip.DesiredAngle = 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
		RightShoulder.MaxVelocity = 0.15
		LeftShoulder.MaxVelocity = 0.15
		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.DesiredAngle = desiredAngle + climbFudge
	LeftShoulder.DesiredAngle = desiredAngle - climbFudge 
	RightHip.DesiredAngle = -desiredAngle
	LeftHip.DesiredAngle = -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
-- connect up



function stopLoopedSounds()
sRunning:Stop() 
sClimbing:Stop()
sSwimming:Stop()
end

if hasPlayer == nil then
Humanoid.Died:connect(onDied)
Humanoid.Running:connect(onRunning)
Humanoid.Swimming:connect(onSwimming)
Humanoid.Climbing:connect(onClimbing)
Humanoid.Jumping:connect(function(state) onStateNoStop(state, sJumping) prevState = "Jump" end)
Humanoid.GettingUp:connect(function(state) stopLoopedSounds() onStateNoStop(state, sGettingUp) prevState = "GetUp" end)
Humanoid.FreeFalling:connect(function(state) stopLoopedSounds() onStateFall(state, sFreeFalling) prevState = "FreeFall" end)
Humanoid.FallingDown:connect(function(state) stopLoopedSounds() end)
Humanoid.StateChanged:connect(function(old, new) 
if not (new.Name == "Dead" or 
new.Name == "Running" or 
new.Name == "RunningNoPhysics" or 
new.Name == "Swimming" or 
new.Name == "Jumping" or 
new.Name == "GettingUp" or 
new.Name == "Freefall" or 
new.Name == "FallingDown") then
stopLoopedSounds()
end
end)
end
--Close/Store Wear Data


car.DriveSeat.ChildRemoved:connect(function(child)
	if child.Name=="SeatWeld" then
		local wD=car:FindFirstChild("WearData")
		if car:FindFirstChild("WearData")==nil then
			wD = script.Parent.WearData:Clone()
			wD.Parent=car
		end
		for i,v in pairs(Wheels) do
			wD[v.wheel.Name].Value = v.Heat
		end
		wD.STime.Value=tick()
	end
end)
--// Easily add new custom commands below (without needing to create a plugin module)
--// You can also use this to overwrite existing commands if you know the command's index (found in the command's respective module within the Adonis MainModule)


settings.Commands = {
	ExampleCommand1 = {								--// The index & table of the command
		Prefix = Settings.Prefix;				--// The prefix the command will use, this is the ':' in ':ff me'
		Commands = {"examplecommand1", "examplealias1", "examplealias2"};	--// A table containing the command strings (the things you chat in-game to run the command, the 'ff' in ':ff me')
		Args = {"arg1", "arg2", "etc"};	--// Command arguments, these will be available in order as args[1], args[2], args[3], etc; This is the 'me' in ':ff me'
		Description = "Example command";--// The description of the command
		AdminLevel = 100; -- Moderators	--// The commands minimum admin level; This can also be a table containing specific levels rather than a minimum level: {124, 152, "HeadAdmins", etc};
		-- Alternative option: AdminLevel = "Moderators"
		Filter = true;									--// Should user-supplied text passed to this command be filtered automatically? Use this if you plan to display a user-defined message to other players
		Hidden = true;									--// Should this command be hidden from the command list?
		Disabled = true;								--// If set to true this command won't be usable.
		Function = function(plr: Player, args: {string}, data)	--// The command's function; This is the actual code of the command which runs when you run the command
			--// "plr" is the player running the command
			--// "args" is an array of strings containing command arguments supplied by the user
			--// "data" is a table containing information related to the command and the player running it, such as data.PlayerData.Level (the player's admin level) [Refer to API docs]
			print("This is 'arg1':", tostring(args[1]))
			print("This is 'arg2':", tostring(args[2]))
			print("This is 'etc'(arg 3):", tostring(args[3]))
			error("this is an example error :o !") --// Errors raised in the function during command execution will be displayed to the user.
		end
	};
}

settings.CommandCooldowns = {
-- Navigation 


for _,NavButton in pairs(Navigation.Main:GetChildren()) do
	if NavButton:IsA("TextButton") then
		NavButton.MouseButton1Click:connect(function()
			if not Tweening then
				Tweening = true;
				Navigation:TweenPosition(UDim2.new(-1,0,0,0),Direction,Style,Time);
				Main[NavButton.Name]:TweenPosition(UDim2.new(0,0,0,0),Direction,Style,Time);
				wait(Time);
				Tweening = false;
			end;
		end)
	end;
end

for _,Frame in pairs(Main:GetChildren()) do
	Frame.Back.MouseButton1Click:connect(function()
		if not Tweening then
			Tweening = true;
			Navigation:TweenPosition(UDim2.new(0,0,0,0),Direction,Style,Time);
			Main[Frame.Name]:TweenPosition(UDim2.new(1,0,0,0),Direction,Style,Time);
			wait(Time);
			Tweening = false;
		end;
	end)
end
--[[INSTALL PROCESS]]--
-- Place the brick in the body group, where your radiator would be, and place the "Temperature" GUI in the plugin folder!
-- This plugin is Filtering Enabled compatible




script:WaitForChild("Celsius")
script:WaitForChild("Blown")
local car = script.Parent.Parent.Car.Value
local radiator = car.Body.Smoke
local mouse = game.Players.LocalPlayer:GetMouse()
local handler = car.EngineOverheat
local FE = workspace.FilteringEnabled
-- access point for easily setting render settings such as default lighting properties, camera, etc



local References = require(game:GetService("ReplicatedStorage"):WaitForChild("Utilities"):WaitForChild("Services"):WaitForChild("References"))
local Utilities = References.Utilities
local Services = Utilities.Services

local Player = require(References.PlayerScripts.Main:WaitForChild("Player"))

local Gameplay = {}
	Gameplay.Camera = workspace.CurrentCamera
	
	Gameplay.HUDPositions = {}
	Gameplay.HUD_ENABLED = true
		
	function Gameplay:UpdateHUDPositions()
		local hud_elements = References.HUD:GetChildren()
		for i=1,#hud_elements do
			local hud_element = hud_elements[i]
			if hud_element:IsA("GuiObject") then
				Gameplay.HUDPositions[hud_element] = {}
				Gameplay.HUDPositions[hud_element].Show = hud_element.Position
				
				local axis = {X=0,Y=0}
				
				local hidden = {}
				for a in pairs(axis) do
					hidden[a] = {Offset = 0; Scale = 0;};
					if hud_element.Position[a].Scale <= .25 then
						hidden[a].Scale = 0;
						hidden[a].Offset = -(hud_element.AbsoluteSize.X*2)
						--hidden_x_scale = -.5
					elseif hud_element.Position[a].Scale > .25 and hud_element.Position[a].Scale < .75 then
						hidden[a].Scale = hud_element.Position[a].Scale
						hidden[a].Offset = hud_element.Position[a].Offset
					--	hidden_x_scale = hud_element.Position[a].Scale
					else
						hidden[a].Scale = 0;
						hidden[a].Offset = References.HUD.AbsoluteSize.X + (hud_element.AbsoluteSize.X*2)
						--hidden_x_scale = 1.5
					end
				end
				
				
				Gameplay.HUDPositions[hud_element].Hide = UDim2.new(hidden.X.Scale,hidden.X.Offset,hidden.Y.Scale,hidden.Y.Offset)
			end
		end
	end
	Gameplay:UpdateHUDPositions()
	
	References.HUD:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
		if Gameplay.HUD_ENABLED then
			Gameplay:UpdateHUDPositions()
		end
	end)
	
	
	function Gameplay:TweenHUD(on_off)
		local desc = References.HUD:GetChildren()
		for i=1,#desc do
			local d = desc[i]
			if d:IsA("GuiObject") then
				local positions = self.HUDPositions[d]
				if positions then
					d:TweenPosition(on_off and positions.Show or positions.Hide, "Out", "Quint", 1, true)
				end
			end
		end
	end
	
	function Gameplay:ToggleHUD(on_off)
		if on_off then
			self:SetDefaultCore()
		else
			Services.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.All, false)
		end
		self:TweenHUD(on_off)
		self.HUD_ENABLED = on_off
	end
	
	-- sets all of our preferred core ui settings (topbar stuff, coreguitypes, etc)
	function Gameplay:SetDefaultCore()
		References.PlayerGui:SetTopbarTransparency(1)
		Services.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack, false)
		Services.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, true)
		Services.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health, true)
		Services.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.PlayerList, true)
		--Services.StarterGui:SetCore("ResetButtonCallback",false)
		Player.Player.CameraMaxZoomDistance = 65;
	end
	
	Gameplay:SetDefaultCore()

return Gameplay
-- Make sure the script is in the starterpack



Player = game.Players.LocalPlayer
MuteTime = 10 -- Put the time you want them to be muted in seconds here

ChatTime = 0 -- Dont change that
Player.Chatted:connect(function()
	if ChatTime < 0.5 then
		game:GetService("StarterGui"):SetCoreGuiEnabled(3,false)
		wait(MuteTime)
		game:GetService("StarterGui"):SetCoreGuiEnabled(3,true)
	end
	ChatTime = 0
end)
while wait(0.1) do
	ChatTime = ChatTime +0.1
end
--Connect any players that are added to the game to above 'NewPlayer' function


Players.PlayerAdded:connect(function(Player)
 Player.CharacterAdded:Connect(function(Character)
  --Run on every part that is added to the character
  local function ChangeGroup(Part)
   if Part:IsA("BasePart") then --Make sure we're dealing with any type of part
    PhysicsService:SetPartCollisionGroup(Part, "RaceCars") --Set the part's collision group
   end
  end
  
  --Run above function on any parts that are added to the character from this point
  Character.ChildAdded:Connect(ChangeGroup)
  script.Parent.ChildAdded:Connect(ChangeGroup)
  
  --Run above function on any parts that may already exist
  for _, Object in pairs(Character:GetChildren()) do
   ChangeGroup(Object)
  end
 end)
end)
-- ROBLOX deviation: we do not have the BabelTraverse or Prettier types defined in the
-- types file


type SnapshotData = types.SnapshotData

type SnapshotStateOptions = {
	updateSnapshot: ConfigSnapshotUpdateState,
	-- ROBLOX deviation: the function return is defined as any instead of null | Prettier
	-- prettierPath: ConfigPath;
	expand: boolean?,
	snapshotFormat: PrettyFormatOptions,
}

type SnapshotMatchOptions = {
	testName: string,
	received: any?,
	key: string?,
	inlineSnapshot: string?,
	isInline: boolean,
	-- ROBLOX deviation: error type defined as any instead of Error
	error_: any,
}

type SnapshotReturnOptions = {
	actual: string,
	count: number,
	expected: string?,
	key: string,
	pass: boolean,
}

type SaveStatus = {
	deleted: boolean,
	saved: boolean,
}

type SnapshotState = {
	_counters: { [string]: number },
	_dirty: boolean,
	_index: number,
	_updateSnapshot: ConfigSnapshotUpdateState,
	_snapshotData: SnapshotData,
	_initialData: SnapshotData,
	_snapshotPath: ConfigPath,
	-- ROBLOX TODO: ADO-1552 align this type as Array<InlineSnapshot> when we support inlineSnapshot testing
	_inlineSnapshots: { any },
	-- ROBLOX deviation: defined as any for now because LuauPolyfill.Set<string> and Set.Set<string>
	-- both didn't seem to be working
	_uncheckedKeys: any,
	-- _uncheckedKeys: LuauPolyfill.Set<string>,
	-- ROBLOX deviation: omitting field _prettierPath
	-- _prettierPath: ConfigPath;
	_snapshotFormat: PrettyFormatOptions,

	added: number,
	expand: boolean,
	matched: number,
	unmatched: number,
	updated: number,

	_addSnapshot: (
		self: SnapshotState,
		key: string,
		receivedSerialized: string,
		options: { isInline: boolean, error: Error? }
	) -> (),
}

local SnapshotState = {}
SnapshotState.__index = SnapshotState

function SnapshotState.new(snapshotPath: ConfigPath, options: SnapshotStateOptions): SnapshotState
	local returnValue = getSnapshotData(snapshotPath, options.updateSnapshot)
	local data = returnValue.data
	local dirty = returnValue.dirty

	local self = {
		_snapshotPath = snapshotPath,
		_initialData = data,
		_snapshotData = data,
		_dirty = dirty,
		-- ROBLOX deviation: omitting assignment for getBabelTraverse, getPrettier
		_inlineSnapshots = {},
		_uncheckedKeys = Set.new(Object.keys(data)),
		_counters = {},
		_index = 0,
		expand = options.expand or false,
		added = 0,
		matched = 0,
		unmatched = 0,
		_updateSnapshot = options.updateSnapshot,
		updated = 0,
		_snapshotFormat = options.snapshotFormat,
	}

	return (setmetatable(self, SnapshotState) :: any) :: SnapshotState
end

function SnapshotState:markSnapshotsAsCheckedForTest(testName: string): ()
	for index, uncheckedKey in self._uncheckedKeys:ipairs() do
		if keyToTestName(uncheckedKey) == testName then
			self._uncheckedKeys:delete(uncheckedKey)
		end
	end
end