Roblox/luau_corpus huggingface dataset:
--[[
	 Builds a map that allows us to find Attachment0/Attachment1 when we have the other,
		and keep track of the joint that connects them. Format is
		{
			["WaistRigAttachment"] = {
				Joint = UpperTorso.Waist<Motor6D>,
				Attachment0 = LowerTorso.WaistRigAttachment<Attachment>,
				Attachment1 = UpperToros.WaistRigAttachment<Attachment>,
			},
			...
		}
--]]
function buildAttachmentMap(character)
	local attachmentMap = {}
	
	-- NOTE: GetConnectedParts doesn't work until parts have been parented to Workspace, so
	-- we can't use it (unless we want to have that silly restriction for creating ragdolls)
	for _,part in pairs(character:GetChildren()) do
		if part:IsA("BasePart") then
			for _,attachment in pairs(part:GetChildren()) do
				if attachment:IsA("Attachment") then
					local jointName = attachment.Name:match("^(.+)RigAttachment$")
					local joint = jointName and attachment.Parent:FindFirstChild(jointName) or nil
					
					if joint then
						attachmentMap[attachment.Name] = {
							Joint = joint,
							Attachment0=joint.Part0[attachment.Name]; 
							Attachment1=joint.Part1[attachment.Name];
						}
					end
				end
			end
		end
	end
	
	return attachmentMap
end

return function(humanoid)
	local character = humanoid.Parent
	
	-- Trying to recover from broken joints is not fun. It's impossible to reattach things like
	-- armor and tools in a generic way that works across all games, so we just prevent that
	-- from happening in the first place.
	humanoid.BreakJointsOnDeath = false
	
	-- Roblox decided to make the ghost HumanoidRootPart CanCollide=true for some reason, so
	-- we correct this and disable collisions. This prevents the invisible part from colliding
	-- with the world and ruining the physics simulation (e.g preventing a roundish torso from
	-- rolling)
	local rootPart = character:FindFirstChild("HumanoidRootPart")
	if rootPart then
		rootPart.CanCollide = false
	end
	
	local player = game.Players:GetPlayerFromCharacter(character)

	local attachmentMap = buildAttachmentMap(character)
	local ragdollConstraints = buildConstraints(attachmentMap)
	local collisionFilters = buildCollisionFilters(attachmentMap, character.PrimaryPart)

	collisionFilters.Parent = ragdollConstraints
	ragdollConstraints.Parent = character
	
	game:GetService("CollectionService"):AddTag(humanoid, "Ragdoll")
end
-- Don't edit below unless you know what you're doing.

local O = 1
function onClicked() 
if O == 1 then
	O = 2
	One()

elseif O == 2 then
	O = 3
    Two()

elseif O == 3 then
	O = 1
    Three()
end
end

script.Parent.MouseButton1Down:connect(onClicked)
--// Functions \\--
function PartSetup (center,Name)
center.Parent = workspace.CurrentCamera
center.Size = Vector3.new(7, 5, 0.05)
center.Anchored = false
center.CanCollide = false
center.Name = Name.."Menu"
center.CustomPhysicalProperties=  PhysicalProperties.new(0, 0, 0)
center.Transparency = .8
center.BrickColor = BrickColor.White()
center.Material = Enum.Material.Neon
end
function WeldSetup (centerWeld,center,C0info)
centerWeld.Part0 = workspace:WaitForChild(Player.Name).HumanoidRootPart
centerWeld.Part1 = center
centerWeld.C0 = CFrame.new(0,1.5,-5)
centerWeld.Parent = workspace:WaitForChild(Player.Name).HumanoidRootPart
end
--[[
	Returns first value (success), and packs all following values.
]]
local function packResult(success, ...)
	return success, select("#", ...), { ... }
end


local function makeErrorHandler(traceback)
	assert(traceback ~= nil)

	return function(err)
		-- If the error object is already a table, forward it directly.
		-- Should we extend the error here and add our own trace?

		if type(err) == "table" then
			return err
		end

		return Error.new({
			error = err,
			kind = Error.Kind.ExecutionError,
			trace = debug.traceback(tostring(err), 2),
			context = "Promise created at:\n\n" .. traceback,
		})
	end
end
-- Decompiled with the Synapse X Luau decompiler.

local l__Pets__1 = game.Players.LocalPlayer:WaitForChild("Pets");
local l__Background__2 = script.Parent.Background;
l__Background__2.MouseButton1Click:Connect(function()
	local l__Value__3 = script.Parent.Parent.Parent.DefaultButtonColor.Value;
	local l__SideFrame__4 = script.Parent.Parent.Parent.Parent.SideFrame;
	if l__SideFrame__4.MassDelete.Value ~= false then
		if script.Parent.MassDeleteIndicator.Visible == false then
			script.Parent.MassDeleteIndicator.Visible = true;
			script.Parent.Background.BackgroundColor3 = script.Parent.Parent.Parent.MassDeleteButtonColor.Value;
			return;
		else
			script.Parent.MassDeleteIndicator.Visible = false;
			script.Parent.Background.BackgroundColor3 = l__Value__3;
			return;
		end;
	end;
	for v5, v6 in pairs(script.Parent.Parent:GetChildren()) do
		if v6:IsA("Frame") then
			v6.Background.BackgroundColor3 = l__Value__3;
		end;
	end;
	l__Background__2.BackgroundColor3 = script.Parent.Parent.Parent.SelectButtonColor.Value;
	l__SideFrame__4.PetID.Value = script.Parent.PetID.Value;
end);
-- RayPlaneIntersection (shortened)
-- http://www.siggraph.org/education/materials/HyperGraph/raytrace/rayplane_intersection.htm
function moduleApiTable:RayPlaneIntersection(ray, planeNormal, pointOnPlane)
	planeNormal = planeNormal.unit
	ray = ray.Unit

	local Vd = planeNormal:Dot(ray.Direction)
	if Vd == 0 then -- parallel, no intersection
		return nil
	end

	local V0 = planeNormal:Dot(pointOnPlane - ray.Origin)
	local t = V0 / Vd
	if t < 0 then --plane is behind ray origin, and thus there is no intersection
		return nil
	end

	return ray.Origin + ray.Direction * t
end

function moduleApiTable:GetEaseLinear()
	return Linear
end
function moduleApiTable:GetEaseOutQuad()
	return EaseOutQuad
end
function moduleApiTable:GetEaseInOutQuad()
	return EaseInOutQuad
end

function moduleApiTable:CreateNewSlider(numOfSteps, startStep, minStep)
	return CreateNewSlider(numOfSteps, startStep, minStep)
end

function moduleApiTable:CreateNewSelector(selectionStringTable, startPosition)
	return CreateSelector(selectionStringTable, startPosition)
end

function moduleApiTable:CreateNewDropDown(dropDownStringTable, startPosition)
	return CreateDropDown(dropDownStringTable, startPosition, nil)
end

function moduleApiTable:AddNewRow(pageToAddTo, rowDisplayName, selectionType, rowValues, rowDefault, extraSpacing)
	return AddNewRow(pageToAddTo, rowDisplayName, selectionType, rowValues, rowDefault, extraSpacing)
end

function moduleApiTable:AddNewRowObject(pageToAddTo, rowDisplayName, rowObject, extraSpacing)
	return AddNewRowObject(pageToAddTo, rowDisplayName, rowObject, extraSpacing)
end

function moduleApiTable:ShowAlert(alertMessage, okButtonText, settingsHub, okPressedFunc, hasBackground)
	ShowAlert(alertMessage, okButtonText, settingsHub, okPressedFunc, hasBackground)
end

function moduleApiTable:IsSmallTouchScreen()
	return isSmallTouchScreen()
end

function moduleApiTable:IsPortrait()
	return isPortrait()
end

function moduleApiTable:MakeStyledButton(name, text, size, clickFunc, pageRef, hubRef)
	return MakeButton(name, text, size, clickFunc, pageRef, hubRef)
end

function moduleApiTable:MakeStyledImageButton(name, image, size, imageSize, clickFunc, pageRef, hubRef)
	return MakeImageButton(name, image, size, imageSize, clickFunc, pageRef, hubRef)
end

function moduleApiTable:AddButtonRow(pageToAddTo, name, text, size, clickFunc, hubRef)
	return AddButtonRow(pageToAddTo, name, text, size, clickFunc, hubRef)
end

function moduleApiTable:CreateSignal()
	return CreateSignal()
end

function  moduleApiTable:UsesSelectedObject()
	return usesSelectedObject()
end

function moduleApiTable:TweenProperty(instance, prop, start, final, duration, easingFunc, cbFunc)
	return PropertyTweener(instance, prop, start, final, duration, easingFunc, cbFunc)
end

function moduleApiTable:OnResized(key, callback)
	return addOnResizedCallback(key, callback)
end

function moduleApiTable:FireOnResized()
	local newSize = getViewportSize()
	local portrait = moduleApiTable:IsPortrait()

	for key, callback in pairs(onResizedCallbacks) do
		callback(newSize, portrait)
	end
end
--Create suggestion labels
local function createSuggestionLabels(props)
	for i = 1,props.maxSuggestions do
		local label = props.rframe.LabelTemplate:Clone()
		label.Name = "Label"..i
		label.Visible = false
		label.Parent = props.rframe
		label.MouseEnter:Connect(function()
			props.suggestionPos = i
		end)
		label.MouseButton1Up:Connect(function()
			props.suggestionPos = i
			selectSuggestion(props)
		end)
	end
end
-- Connects the given collision function to the object's "Touched" event, but only if that object is a Part
-- Otherwise, it tries this function on all of the object's children
local function attachCollisionFunction(item, collisionFunction)

    if item:IsA("BasePart") then
        item.Touched:Connect(collisionFunction)
    else
        for _, child in ipairs(item:GetChildren()) do
            attachCollisionFunction(child, collisionFunction)
        end
    end
end
--	====================
--	BASIC
--	A basic settings for the gun
--	====================

		Auto = false;
		MuzzleOffset = Vector3.new(0, 0.625, 1.25);
		BaseDamage = 60;
		FireRate = 0.3; --In second
		ReloadTime = 2.5; --In second
		AmmoPerClip = 6; --Put "math.huge" to make this gun has infinite ammo and never reload
		Spread = 1.25; --In degree
		HeadshotEnabled = true; --Enable the gun to do extra damage on headshot
		HeadshotDamageMultiplier = 3;
		MouseIconID = "316279304";
		HitSoundIDs = {186809061,186809249,186809250,186809252};
		IdleAnimationID = 94331086; --Set to "nil" if you don't want to animate
		IdleAnimationSpeed = 1;
		FireAnimationID = 94332152; --Set to "nil" if you don't want to animate
		FireAnimationSpeed = 6;
		ReloadAnimationID = nil; --Set to "nil" if you don't want to animate
		ReloadAnimationSpeed = 1;
--[[Installation Directories]]--

install(dir:WaitForChild("Config"), c:WaitForChild("Music Gui"))
install(c:WaitForChild("Music Gui"), game:GetService("StarterGui"))
-- CONSTANTS

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

local INCREMENT_BUTTON = Defaults:WaitForChild("IncrementButton")
local DECREMENT_BUTTON = Defaults:WaitForChild("DecrementButton")

local WARN_MSG = "%s is not a valid mask. Defaulting to 'String' mask."

local MASKS = {}
for _, module in pairs(script:GetChildren()) do
	MASKS[module.Name] = require(module)
end
-- Wait for game to load:
if (not game:IsLoaded()) then
	game.Loaded:Wait()
end

local guis = game:GetService("ReplicatedStorage"):FindFirstChild(REP_STORAGE_FOLDER_NAME)
local player = game:GetService("Players").LocalPlayer
local playerGui = player.PlayerGui

if (not guis) then
	warn("UI loader failed to find " .. REP_STORAGE_FOLDER_NAME .. " folder in ReplicatedStorage")
	return
end
-- Libraries
local Roact = require(Vendor:WaitForChild('Roact'))
local new = Roact.createElement

local function ExportDialog(props)
    return new('ScreenGui', {}, {
        Dialog = new('Frame', {
            AnchorPoint = Vector2.new(0.5, 0.5);
            BackgroundColor3 = Color3.fromRGB(31, 31, 31);
            BackgroundTransparency = 0.6;
            BorderSizePixel = 0;
            Position = UDim2.new(0.5, 0, 0.5, 0);
            Size = UDim2.new(0, 200, 0, 0);
        }, {
            Corners = new('UICorner', {
                CornerRadius = UDim.new(0, 4);
            });
            CloseButton = new('TextButton', {
                AnchorPoint = Vector2.new(0, 1);
                BackgroundColor3 = Color3.fromRGB(0, 0, 0);
                BackgroundTransparency = 0.5;
                Modal = true;
                Position = UDim2.new(0, 0, 1, 0);
                Size = UDim2.new(1, 0, 0, 23);
                Text = 'Close';
                Font = Enum.Font.GothamSemibold;
                TextColor3 = Color3.fromRGB(255, 255, 255);
                TextSize = 11;
                [Roact.Event.Activated] = function (rbx)
                    props.OnDismiss()
                end;
            }, {
                Corners = new('UICorner', {
                    CornerRadius = UDim.new(0, 4);
                });
            });
            Text = new('TextLabel', {
                BackgroundTransparency = 1;
                Size = UDim2.new(1, 0, 1, -23);
                Font = Enum.Font.GothamSemibold;
                RichText = true;
                Text = props.Text;
                TextColor3 = Color3.fromRGB(255, 255, 255);
                TextSize = 11;
                TextWrapped = true;
                [Roact.Change.TextBounds] = function (rbx)
                    rbx.Parent.Size = UDim2.new(0, 200, 0, rbx.TextBounds.Y + 23 + 26)
                end;
            }, {
                Padding = new('UIPadding', {
                    PaddingLeft = UDim.new(0, 10);
                    PaddingRight = UDim.new(0, 10);
                });
            });
        });
    })
end

return ExportDialog
-- Called when any relevant values of GameSettings or LocalPlayer change, forcing re-evalulation of
-- current control scheme
function ControlModule:OnComputerMovementModeChange()
	local controlModule, success =  self:SelectComputerMovementModule()
	if success then
		self:SwitchToController(controlModule)
	end
end

function ControlModule:OnTouchMovementModeChange()
	local touchModule, success = self:SelectTouchModule()
	if success then
		while not self.touchControlFrame do
			wait()
		end
		self:SwitchToController(touchModule)
	end
end

function ControlModule:CreateTouchGuiContainer()
	if self.touchGui then self.touchGui:Destroy() end

	-- Container for all touch device guis
	self.touchGui = Instance.new('ScreenGui')
	self.touchGui.Name = "TouchGui"
	self.touchGui.ResetOnSpawn = false

	self.touchControlFrame = Instance.new("Frame")
	self.touchControlFrame.Name = "TouchControlFrame"
	self.touchControlFrame.Size = UDim2.new(1, 0, 1, 0)
	self.touchControlFrame.BackgroundTransparency = 1
	self.touchControlFrame.Parent = self.touchGui

	self.touchGui.Parent = self.playerGui
end

return ControlModule.new()
--[[ Psst! If you want to use a space in the name of a function, here's an example of how you could do that:

attacks["Cool Enemy"] = function()
	-- cool code here
end

]]

return attacks
-- << Functions >> --


function lerp(a, b, c)
	return a + (b - a) * c
end

bobbing = game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
	if script.Parent.Humanoid.MoveDirection.Magnitude > 0 then
		deltaTime = deltaTime * (script.Parent.Humanoid.WalkSpeed * 3.75)	
	else
		deltaTime = deltaTime * 60
	end
	print(deltaTime)
	if Humanoid.Health <= 0 then
		bobbing:Disconnect()
		return
	end
	local rootMagnitude = Humanoid.RootPart and Vector3.new(Humanoid.RootPart.Velocity.X, 0, Humanoid.RootPart.Velocity.Z).Magnitude or 0
	local calcRootMagnitude = math.min(rootMagnitude, 50)
	if deltaTime > 3 then
		func1 = 0
		func2 = 0
	else
		func1 = lerp(func1, math.cos(tick() * 0.5 * math.random(10, 15)) * (math.random(5, 20) / 200) * deltaTime, 0.05 * deltaTime)
		func2 = lerp(func2, math.cos(tick() * 0.5 * math.random(5, 10)) * (math.random(2, 10) / 200) * deltaTime, 0.05 * deltaTime)
	end
	Camera.CFrame = Camera.CFrame * (CFrame.fromEulerAnglesXYZ(0, 0, math.rad(func3)) * CFrame.fromEulerAnglesXYZ(math.rad(func4 * deltaTime), math.rad(val * deltaTime), val2) * CFrame.Angles(0, 0, math.rad(func4 * deltaTime * (calcRootMagnitude / 5))) * CFrame.fromEulerAnglesXYZ(math.rad(func1), math.rad(func2), math.rad(func2 * 10)))
	val2 = math.clamp(lerp(val2, -Camera.CFrame:VectorToObjectSpace((Humanoid.RootPart and Humanoid.RootPart.Velocity or Vector3.new()) / math.max(Humanoid.WalkSpeed, 0.01)).X * 0.08, 0.1 * deltaTime), -0.35, 0.2)
	func3 = lerp(func3, math.clamp(UserInputService:GetMouseDelta().X, -5, 5), 0.25 * deltaTime)
	func4 = lerp(func4, math.sin(tick() * int) / 5 * math.min(1, int2 / 10), 0.25 * deltaTime)
	if rootMagnitude > 1 then
		val = lerp(val, math.cos(tick() * 0.5 * math.floor(int)) * (int / 200), 0.25 * deltaTime)
	else
		val = lerp(val, 0, 0.05 * deltaTime)
	end
	if rootMagnitude > 12 then
		int = 20
		int2 = 18
	elseif rootMagnitude > 0.1 then
		int = 12
		int2 = 14
	else
		int2 = 0
	end
	vect3 = lerp(vect3, Camera.CFrame.LookVector, 0.125 * deltaTime)
end)
--Format: 	[GroupId] = { [RankNumber] = "PermissionName" OR PermissionNumber };
local Groups ={
	[3204047] = { [255]="HeadAdmin", [1]="VIP" };
	[1202458] = { [2]="VIP", [6]=3 };
}
--[=[
	Manages the cleaning of events and other things. Useful for
	encapsulating state and make deconstructors easy.

	See the [Five Powerful Code Patterns talk](https://developer.roblox.com/en-us/videos/5-powerful-code-patterns-behind-top-roblox-games)
	for a more in-depth look at Maids in top games.

	```lua
	local maid = Maid.new()

	maid:GiveTask(function()
		print("Cleaning up")
	end)

	maid:GiveTask(workspace.ChildAdded:Connect(print))

	-- Disconnects all events, and executes all functions
	maid:DoCleaning()
	```

	@class Maid
]=]
-- luacheck: pop

local Maid = {}
Maid.ClassName = "Maid"
--	
	script.Parent.Handle3.Hinge1.Transparency = 1
	script.Parent.Handle3.Interactive1.Transparency = 1
	script.Parent.Handle3.Part1.Transparency = 1
	wait(0.06)
	script.Parent.Handle1.Hinge1.Transparency = 1
	script.Parent.Handle1.Interactive1.Transparency = 1
	script.Parent.Handle1.Part1.Transparency = 1
-- ScreenSpace -> WorldSpace. Raw function taking a screen position and a depth and 
-- converting it into a world position.
function ScreenSpace.ScreenToWorld(x, y, depth)
	local aspectRatio = ScreenSpace.AspectRatio()
	local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
	local wfactor = aspectRatio*hfactor
	--
	local xf, yf = x/ScreenSpace.ViewSizeX()*2 - 1, y/ScreenSpace.ViewSizeY()*2 - 1
	local xpos = xf * -wfactor * depth
	local ypos = yf *  hfactor * depth
	--
	return Vector3.new(xpos, ypos, depth)
end
-- Reset broken glass
function ResetGlass()
	for i, gData in pairs(dParts.Glass) do
		gData[1].Parent = gData[2]

		for _, shard in pairs(gData[3]) do
			if shard then shard:Destroy() end
		end

		dParts.Glass[i] = nil
	end
end
-- Volume Functions --

function VolumeUp()
	volumeValue.Value = volumeValue.Value + 0.1
end

TV.VButtonUp.ClickDetector.MouseClick:Connect(VolumeUp)

function VolumeDown()
	volumeValue.Value = volumeValue.Value - 0.1
end

TV.VButtonDown.ClickDetector.MouseClick:Connect(VolumeDown)

function VolumeChanged()
	if volumeValue.Value < 0 then
		volumeValue.Value = 0
	elseif volumeValue.Value > 1.2 then
		volumeValue.Value = 1.2 -- I don't recommend any value higher than 1, it's annoying.
	else
		music.Volume = volumeValue.Value
	end
end

volumeValue.Changed:Connect(VolumeChanged)
--// KeyBindings
	FireSelectKey = Enum.KeyCode.V;
	CycleSightKey = Enum.KeyCode.T;
	LaserKey = Enum.KeyCode.G;
	LightKey = Enum.KeyCode.B;
	InteractKey = Enum.KeyCode.E;
-- ROBLOX FIXME: Can we define ClientChatModules statically in the project config
pcall(function() ChatLocalization = require((game:GetService("Chat") :: any).ClientChatModules.ChatLocalization :: any) end)
ChatLocalization = ChatLocalization or {}

if not ChatLocalization.FormatMessageToSend or not ChatLocalization.LocalizeFormattedMessage then
	function ChatLocalization:FormatMessageToSend(key,default) return default end
end

local function allSpaces(inputString)
	local testString = string.gsub(inputString, " ", "")
	return string.len(testString) == 0
end
--[[Transmission]]
	Tune.TransModes		={"Auto"}												--[[
	[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													]]
	
	--Automatic Settings
	Tune.AutoShiftMode	= "RPM"												--[[
	[Modes]
		"Speed"		: Shifts based on wheel speed
		"RPM"		: Shifts based on RPM											]]	
	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)
	
	--Gear Ratios
	Tune.FinalDrive		= 3.20			-- Gearing determines top speed and wheel torque
	Tune.Ratios			= {				-- Higher ratio = more torque, Lower ratio = higher top speed
		--[[Reverse]]	3.42		,	-- Copy and paste a ratio to add a gear
		--[[Neutral]]	0			,	-- Ratios can also be deleted
		--[[ 1 ]]		3.75		,	-- Reverse, Neutral, and 1st gear are required
		--[[ 2 ]]		2.38		,
		--[[ 3 ]]		1.72		,
		--[[ 4 ]]		1.34		,
		--[[ 5 ]]		1.11		,
		--[[ 6 ]]		.78			,
	}
	Tune.FDMult			= 1			-- Ratio multiplier (Change this value instead of FinalDrive if car is struggling with torque ; Default = 1)
--// Handling Settings		
	Firerate = 60 / 200; -- 60 = 1 Minute, 700 = Rounds per that 60 seconds. DO NOT TOUCH THE 60!
	
	FireMode = 5; -- 1 = Semi, 2 = Auto, 3 = Burst, 4 = Bolt Action, 5 = Shot, 6 = Explosive
--[=[
	@private

	@param onFulfilled function?
	@param onRejected function?
	@param promise2 Promise<T>? -- May be nil. If it is, then we have the option to return self
	@return Promise
]=]
function Promise:_executeThen(onFulfilled, onRejected, promise2)
	if self._fulfilled then
		if type(onFulfilled) == "function" then
			-- If either onFulfilled or onRejected returns a value x, run
			-- the Promise Resolution Procedure [[Resolve]](promise2, x).
			if promise2 then
				promise2:Resolve(onFulfilled(unpack(self._fulfilled, 1, self._valuesLength)))
				return promise2
			else
				local results = table.pack(onFulfilled(unpack(self._fulfilled, 1, self._valuesLength)))
				if results.n == 0 then
					return _emptyFulfilledPromise
				elseif results.n == 1 and Promise.isPromise(results[1]) then
					return results[1]
				else
					local promise = Promise.new()
					-- Technically undefined behavior from A+, but we'll resolve to nil like ES6 promises
					promise:Resolve(table.unpack(results, 1, results.n))
					return promise
				end
			end
		else
			-- If onFulfilled is not a function, it must be ignored.
			-- If onFulfilled is not a function and promise1 is fulfilled,
			-- promise2 must be fulfilled with the same value as promise1.
			if promise2 then
				promise2:_fulfill(self._fulfilled, self._valuesLength)
				return promise2
			else
				return self
			end
		end
	elseif self._rejected then
		if type(onRejected) == "function" then
			-- If either onFulfilled or onRejected returns a value x, run
			-- the Promise Resolution Procedure [[Resolve]](promise2, x).
			if promise2 then
				promise2:Resolve(onRejected(unpack(self._rejected, 1, self._valuesLength)))
				return promise2
			else
				local results = table.pack(onRejected(unpack(self._rejected, 1, self._valuesLength)))
				if results.n == 0 then
					return _emptyFulfilledPromise
				elseif results.n == 1 and Promise.isPromise(results[1]) then
					return results[1]
				else
					local promise = Promise.new()
					-- Technically undefined behavior from A+, but we'll resolve to nil like ES6 promises
					promise:Resolve(table.unpack(results, 1, results.n))
					return promise
				end
			end
		else
			-- If onRejected is not a function, it must be ignored.
			-- If onRejected is not a function and promise1 is rejected, promise2 must be
			-- rejected with the same reason as promise1.
			if promise2 then
				promise2:_reject(self._rejected, self._valuesLength)

				return promise2
			else
				return self
			end
		end
	else
		error("Internal error: still pending")
	end
end