local J={"\083\109\111\107\101";"\070\105\114\101";"\083\112\097\114\107\108\101\115"}function UpdateUI()if not DecorateTool.UI then return end for J,H in pairs(J)do local u=GetDecorations(H)local G=DecorateTool.UI[H]local y=G.Options local V=G.AddButton local f=G.RemoveButton if#u==0 and not G.ClipsDescendants then CloseOptions()end if#u==0 then V.Visible=true V.Position=UDim2.new(1,-V.AbsoluteSize.X-5,0,3)f.Visible=false elseif#u<#Selection.Items then V.Visible=true V.Position=UDim2.new(1,-V.AbsoluteSize.X-5,0,3)f.Visible=true f.Position=UDim2.new(1,((-V.AbsoluteSize.X-5)-f.AbsoluteSize.X)-2,0,3)elseif#u==#Selection.Items then f.Visible=true f.Position=UDim2.new(1,-f.AbsoluteSize.X-5,0,3)V.Visible=false end if H=="\083\109\111\107\101"then local J=y.SizeOption.Input.TextBox local H=y.VelocityOption.Input.TextBox local G=y.OpacityOption.Input.TextBox local V=y.ColorOption.Indicator UpdateDataInputs({[J]=Support.Round(Support.IdentifyCommonProperty(u,"\083\105\122\101"),2)or"\042";[H]=Support.Round(Support.IdentifyCommonProperty(u,"\082\105\115\101\086\101\108\111\099\105\116\121"),2)or"\042",[G]=Support.Round(Support.IdentifyCommonProperty(u,"\079\112\097\099\105\116\121"),2)or"\042"})UpdateColorIndicator(V,Support.IdentifyCommonProperty(u,"\067\111\108\111\114"))elseif H=="\070\105\114\101"then local J=y.SizeOption.Input.TextBox local H=y.HeatOption.Input.TextBox local G=y.SecondaryColorOption.Indicator local V=y.ColorOption.Indicator UpdateColorIndicator(V,Support.IdentifyCommonProperty(u,"\067\111\108\111\114"))UpdateColorIndicator(G,Support.IdentifyCommonProperty(u,"\083\101\099\111\110\100\097\114\121\067\111\108\111\114"))UpdateDataInputs({[H]=Support.Round(Support.IdentifyCommonProperty(u,"\072\101\097\116"),2)or"\042",[J]=Support.Round(Support.IdentifyCommonProperty(u,"\083\105\122\101"),2)or"\042"})elseif H=="\083\112\097\114\107\108\101\115"then local J=y.ColorOption.Indicator UpdateColorIndicator(J,Support.IdentifyCommonProperty(u,"\083\112\097\114\107\108\101\067\111\108\111\114"))end end end function HideUI()if not DecorateTool.UI then return end DecorateTool.UI.Visible=false UIUpdater:Stop()end function GetDecorations(J)local H={}for u,G in pairs(Selection.Items)do table.insert(H,Support.GetChildOfClass(G,J))end return H end function UpdateColorIndicator(J,H)if H then J.BackgroundColor3=H J.Varies.Text=""else J.BackgroundColor3=Color3.new(.87058823529412,.87058823529412,.87058823529412)J.Varies.Text="\042"end end function UpdateDataInputs(J)for J,H in pairs(J)do if not J:IsFocused()then J.Text=tostring(H)end end end function TrackChange()HistoryRecord={Before={},After={};Unapply=function(J)Selection.Replace(Support.GetListMembers(J.Before,"\080\097\114\116"))Core.SyncAPI:Invoke("\083\121\110\099\068\101\099\111\114\097\116\101",J.Before)end;Apply=function(J)Selection.Replace(Support.GetListMembers(J.After,"\080\097\114\116"))Core.SyncAPI:Invoke("\083\121\110\099\068\101\099\111\114\097\116\101",J.After)end}end function RegisterChange()if not HistoryRecord then return end Core.SyncAPI:Invoke("\083\121\110\099\068\101\099\111\114\097\116\101",HistoryRecord.After)Core.History.Add(HistoryRecord)HistoryRecord=nil end function EnableOptionsUI(J)local H=J.Name local u=J.Options local G=J.AddButton local y=J.RemoveButton local V=J.ArrowButton if H=="\083\109\111\107\101"then SyncInputToProperty("\067\111\108\111\114",H,"\067\111\108\111\114",u.ColorOption.HSVPicker)SyncInputToProperty("\083\105\122\101",H,"\078\117\109\098\101\114",u.SizeOption.Input.TextBox)SyncInputToProperty("\082\105\115\101\086\101\108\111\099\105\116\121",H,"\078\117\109\098\101\114",u.VelocityOption.Input.TextBox)SyncInputToProperty("\079\112\097\099\105\116\121",H,"\078\117\109\098\101\114",u.OpacityOption.Input.TextBox)elseif H=="\070\105\114\101"then SyncInputToProperty("\067\111\108\111\114",H,"\067\111\108\111\114",u.ColorOption.HSVPicker)SyncInputToProperty("\083\101\099\111\110\100\097\114\121\067\111\108\111\114",H,"\067\111\108\111\114",u.SecondaryColorOption.HSVPicker)SyncInputToProperty("\083\105\122\101",H,"\078\117\109\098\101\114",u.SizeOption.Input.TextBox)SyncInputToProperty("\072\101\097\116",H,"\078\117\109\098\101\114",u.HeatOption.Input.TextBox)elseif H=="\083\112\097\114\107\108\101\115"then SyncInputToProperty("\083\112\097\114\107\108\101\067\111\108\111\114",H,"\067\111\108\111\114",u.ColorOption.HSVPicker)end G.MouseButton1Click:connect(function()AddDecorations(H)end)y.MouseButton1Click:connect(function()RemoveDecorations(H)end)V.MouseButton1Click:connect(function()OpenOptions(H)end)end function OpenOptions(H)local u=DecorateTool.UI[H]local G=Core.Tool.Interfaces.BTDecorateToolGUI[H]CloseOptions(H)local y=UDim2.new(0,0,0,G.Options.Size.Y.Offset)u.Options.Size=UDim2.new(u.Options.Size.X.Scale,u.Options.Size.X.Offset,u.Options.Size.Y.Scale,0)u.ClipsDescendants=false u.Options:TweenSize(G.Options.Size+y,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,.5,true,function()u.Options.ClipsDescendants=false end)DecorateTool.UI:TweenSize(Core.Tool.Interfaces.BTDecorateToolGUI.Size+y,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,.5,true)local V=Support.FindTableOccurrence(J,H)for H=V+1,#J,1 do local u=J[H]local G=DecorateTool.UI[u]G:TweenPosition(UDim2.new(G.Position.X.Scale,G.Position.X.Offset,G.Position.Y.Scale,(30+30*(H-1))+y.Y.Offset),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,.5,true)end end function CloseOptions(H)for J,u in pairs(J)do local G=DecorateTool.UI[u]local y=Core.Tool.Interfaces.BTDecorateToolGUI[u]local V=y.Options.Size G:TweenPosition(UDim2.new(G.Position.X.Scale,G.Position.X.Offset,G.Position.Y.Scale,30+30*(J-1)),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,.5,true)if not H or H and u~=H then G.Options.ClipsDescendants=true G.Options:TweenSize(UDim2.new(G.Options.Size.X.Scale,G.Options.Size.X.Offset,G.Options.Size.Y.Scale,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,.5,true,function()G.ClipsDescendants=true G.Options.Size=V end)end end if not H then DecorateTool.UI:TweenSize(Core.Tool.Interfaces.BTDecorateToolGUI.Size,Enum.EasingDirection.Out,Enum.EasingStyle.Quad,.5,true)end end function SyncInputToProperty(J,H,u,G)if u=="\067\111\108\111\114"then G.MouseButton1Click:connect(function()(Core.Cheer(Core.Tool.Interfaces.BTHSVColorPicker,Core.UI)).Start(Support.IdentifyCommonProperty(GetDecorations(H),J)or Color3.new(0,0,1),function(u)SetProperty(H,J,u)end,Core.Targeting.CancelSelecting)end)elseif u=="\078\117\109\098\101\114"then G.FocusLost:connect(function()SetProperty(H,J,tonumber(G.Text))end)end end function SetProperty(J,H,u)if not u then return end TrackChange()for G,y in pairs(GetDecorations(J))do table.insert(HistoryRecord.Before,{Part=y.Parent,DecorationType=J;[H]=y[H]})table.insert(HistoryRecord.After,{Part=y.Parent,DecorationType=J;[H]=u})end RegisterChange()end function AddDecorations(J)local H={}for u,G in pairs(Selection.Items)do if not Support.GetChildOfClass(G,J)then table.insert(H,{Part=G;DecorationType=J})end end local u=Core.SyncAPI:Invoke("\067\114\101\097\116\101\068\101\099\111\114\097\116\105\111\110\115",H)local G={Decorations=u,Unapply=function(J)Selection.Replace(Support.GetListMembers(J.Decorations,"\080\097\114\101\110\116"))Core.SyncAPI:Invoke("\082\101\109\111\118\101",J.Decorations)end;Apply=function(J)Core.SyncAPI:Invoke("\085\110\100\111\082\101\109\111\118\101",J.Decorations)Selection.Replace(Support.GetListMembers(J.Decorations,"\080\097\114\101\110\116"))end}Core.History.Add(G)OpenOptions(J)end function RemoveDecorations(J)local H=GetDecorations(J)local u={Decorations=H;Unapply=function(J)Core.SyncAPI:Invoke("\085\110\100\111\082\101\109\111\118\101",J.Decorations)Selection.Replace(Support.GetListMembers(J.Decorations,"\080\097\114\101\110\116"))end,Apply=function(J)Selection.Replace(Support.GetListMembers(J.Decorations,"\080\097\114\101\110\116"))Core.SyncAPI:Invoke("\082\101\109\111\118\101",J.Decorations)end}Core.SyncAPI:Invoke("\082\101\109\111\118\101",H)Core.History.Add(u)end

local DecorationTypes = { 'Smoke', 'Fire', 'Sparkles' };

function UpdateUI()
	-- Updates information on the UI

	-- Make sure the UI's on
	if not DecorateTool.UI then
		return;
	end;

	-- Go through each decoration type and update each options UI
	for _, DecorationType in pairs(DecorationTypes) do

		local Decorations = GetDecorations(DecorationType);
		local DecorationSettingsUI = DecorateTool.UI[DecorationType];

		-- Option input references
		local Options = DecorationSettingsUI.Options;

		-- Add/remove button references
		local AddButton = DecorationSettingsUI.AddButton;
		local RemoveButton = DecorationSettingsUI.RemoveButton;

		-- Hide option UIs for decoration types not present in the selection
		if #Decorations == 0 and not DecorationSettingsUI.ClipsDescendants then
			CloseOptions();
		end;

		-------------------------------------------
		-- Show and hide "ADD" and "REMOVE" buttons
		-------------------------------------------

		-- If no selected parts have decorations
		if #Decorations == 0 then

			-- Show add button only
			AddButton.Visible = true;
			AddButton.Position = UDim2.new(1, -AddButton.AbsoluteSize.X - 5, 0, 3);
			RemoveButton.Visible = false;

		-- If only some selected parts have decorations
		elseif #Decorations < #Selection.Items then

			-- Show both add and remove buttons
			AddButton.Visible = true;
			AddButton.Position = UDim2.new(1, -AddButton.AbsoluteSize.X - 5, 0, 3);
			RemoveButton.Visible = true;
			RemoveButton.Position = UDim2.new(1, -AddButton.AbsoluteSize.X - 5 - RemoveButton.AbsoluteSize.X - 2, 0, 3);

		-- If all selected parts have decorations
		elseif #Decorations == #Selection.Items then

			-- Show remove button
			RemoveButton.Visible = true;
			RemoveButton.Position = UDim2.new(1, -RemoveButton.AbsoluteSize.X - 5, 0, 3);
			AddButton.Visible = false;

		end;

		--------------------
		-- Update each input
		--------------------

		-- Update smoke inputs
		if DecorationType == 'Smoke' then

			-- Get the inputs
			local SizeInput = Options.SizeOption.Input.TextBox;
			local VelocityInput = Options.VelocityOption.Input.TextBox;
			local OpacityInput = Options.OpacityOption.Input.TextBox;
			local ColorIndicator = Options.ColorOption.Indicator;

			-- Update the inputs
			UpdateDataInputs {
				[SizeInput] = Support.Round(Support.IdentifyCommonProperty(Decorations, 'Size'), 2) or '*';
				[VelocityInput] = Support.Round(Support.IdentifyCommonProperty(Decorations, 'RiseVelocity'), 2) or '*';
				[OpacityInput] = Support.Round(Support.IdentifyCommonProperty(Decorations, 'Opacity'), 2) or '*';
			};
			UpdateColorIndicator(ColorIndicator, Support.IdentifyCommonProperty(Decorations, 'Color'));

		-- Update fire inputs
		elseif DecorationType == 'Fire' then

			-- Get the inputs
			local SizeInput = Options.SizeOption.Input.TextBox;
			local HeatInput = Options.HeatOption.Input.TextBox;
			local SecondaryColorIndicator = Options.SecondaryColorOption.Indicator;
			local ColorIndicator = Options.ColorOption.Indicator;

			-- Update the inputs
			UpdateColorIndicator(ColorIndicator, Support.IdentifyCommonProperty(Decorations, 'Color'));
			UpdateColorIndicator(SecondaryColorIndicator, Support.IdentifyCommonProperty(Decorations, 'SecondaryColor'));
			UpdateDataInputs {
				[HeatInput] = Support.Round(Support.IdentifyCommonProperty(Decorations, 'Heat'), 2) or '*';
				[SizeInput] = Support.Round(Support.IdentifyCommonProperty(Decorations, 'Size'), 2) or '*';
			};

		-- Update sparkle inputs
		elseif DecorationType == 'Sparkles' then

			-- Get the inputs
			local ColorIndicator = Options.ColorOption.Indicator;

			-- Update the inputs
			UpdateColorIndicator(ColorIndicator, Support.IdentifyCommonProperty(Decorations, 'SparkleColor'));

		end;

	end;

end;

function HideUI()
	-- Hides the tool UI

	-- Make sure there's a UI
	if not DecorateTool.UI then
		return;
	end;

	-- Hide the UI
	DecorateTool.UI.Visible = false;

	-- Stop updating the UI
	UIUpdater:Stop();

end;

function GetDecorations(DecorationType)
	-- Returns all the decorations of the given type in the selection

	local Decorations = {};

	-- Get any decorations from any selected parts
	for _, Part in pairs(Selection.Items) do
		table.insert(Decorations, Support.GetChildOfClass(Part, DecorationType));
	end;

	-- Return the decorations
	return Decorations;

end;

function UpdateColorIndicator(Indicator, Color)
	-- Updates the given color indicator

	-- If there is a single color, just display it
	if Color then
		Indicator.BackgroundColor3 = Color;
		Indicator.Varies.Text = '';

	-- If the colors vary, display a * on a gray background
	else
		Indicator.BackgroundColor3 = Color3.new(222/255, 222/255, 222/255);
		Indicator.Varies.Text = '*';
	end;

end;

function UpdateDataInputs(Data)
	-- Updates the data in the given TextBoxes when the user isn't typing in them

	-- Go through the inputs and data
	for Input, UpdatedValue in pairs(Data) do

		-- Make sure the user isn't typing into the input
		if not Input:IsFocused() then

			-- Set the input's value
			Input.Text = tostring(UpdatedValue);

		end;

	end;

end;

function TrackChange()

	-- Start the record
	HistoryRecord = {
		Before = {};
		After = {};

		Unapply = function (Record)
			-- Reverts this change

			-- Select the changed parts
			Selection.Replace(Support.GetListMembers(Record.Before, 'Part'));

			-- Send the change request
			Core.SyncAPI:Invoke('SyncDecorate', Record.Before);

		end;

		Apply = function (Record)
			-- Applies this change

			-- Select the changed parts
			Selection.Replace(Support.GetListMembers(Record.After, 'Part'));

			-- Send the change request
			Core.SyncAPI:Invoke('SyncDecorate', Record.After);

		end;

	};

end;

function RegisterChange()
	-- Finishes creating the history record and registers it

	-- Make sure there's an in-progress history record
	if not HistoryRecord then
		return;
	end;

	-- Send the change to the server
	Core.SyncAPI:Invoke('SyncDecorate', HistoryRecord.After);

	-- Register the record and clear the staging
	Core.History.Add(HistoryRecord);
	HistoryRecord = nil;

end;

function EnableOptionsUI(SettingsUI)
	-- Sets up the UI for the given decoration type settings UI

	-- Get the type of decoration this options UI is for
	local DecorationType = SettingsUI.Name;

	-- Option input references
	local Options = SettingsUI.Options;
	
	-- Add/remove/show button references
	local AddButton = SettingsUI.AddButton;
	local RemoveButton = SettingsUI.RemoveButton;
	local ShowButton = SettingsUI.ArrowButton;

	-- Enable options for smoke decorations
	if DecorationType == 'Smoke' then
		SyncInputToProperty('Color', DecorationType, 'Color', Options.ColorOption.HSVPicker);
		SyncInputToProperty('Size', DecorationType, 'Number', Options.SizeOption.Input.TextBox);
		SyncInputToProperty('RiseVelocity', DecorationType, 'Number', Options.VelocityOption.Input.TextBox);
		SyncInputToProperty('Opacity', DecorationType, 'Number', Options.OpacityOption.Input.TextBox);

	-- Enable options for fire decorations
	elseif DecorationType == 'Fire' then
		SyncInputToProperty('Color', DecorationType, 'Color', Options.ColorOption.HSVPicker);
		SyncInputToProperty('SecondaryColor', DecorationType, 'Color', Options.SecondaryColorOption.HSVPicker);
		SyncInputToProperty('Size', DecorationType, 'Number', Options.SizeOption.Input.TextBox);
		SyncInputToProperty('Heat', DecorationType, 'Number', Options.HeatOption.Input.TextBox);

	-- Enable options for sparkle decorations
	elseif DecorationType == 'Sparkles' then
		SyncInputToProperty('SparkleColor', DecorationType, 'Color', Options.ColorOption.HSVPicker);

	end;

	-- Enable decoration addition button
	AddButton.MouseButton1Click:connect(function ()
		AddDecorations(DecorationType);
	end);

	-- Enable decoration removal button
	RemoveButton.MouseButton1Click:connect(function ()
		RemoveDecorations(DecorationType);
	end);

	-- Enable decoration options UI show button
	ShowButton.MouseButton1Click:connect(function ()
		OpenOptions(DecorationType);
	end);

end;

function OpenOptions(DecorationType)
	-- Opens the options UI for the given decoration type

	-- Get the UI
	local UI = DecorateTool.UI[DecorationType];
	local UITemplate = Core.Tool.Interfaces.BTDecorateToolGUI[DecorationType];

	-- Close up all decoration option UIs
	CloseOptions(DecorationType);

	-- Calculate how much to expand this options UI by
	local HeightExpansion = UDim2.new(0, 0, 0, UITemplate.Options.Size.Y.Offset);

	-- Start the options UI size from 0
	UI.Options.Size = UDim2.new(UI.Options.Size.X.Scale, UI.Options.Size.X.Offset, UI.Options.Size.Y.Scale, 0);

	-- Allow the options UI to be seen
	UI.ClipsDescendants = false;

	-- Perform the options UI resize animation
	UI.Options:TweenSize(
		UITemplate.Options.Size + HeightExpansion,
		Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true,
		function ()

			-- Allow visibility of overflowing UIs within the options UI
			UI.Options.ClipsDescendants = false;

		end
	);

	-- Expand the main UI to accommodate the expanded options UI
	DecorateTool.UI:TweenSize(
		Core.Tool.Interfaces.BTDecorateToolGUI.Size + HeightExpansion,
		Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true
	);

	-- Push any UIs below this one downwards
	local DecorationTypeIndex = Support.FindTableOccurrence(DecorationTypes, DecorationType);
	for DecorationTypeIndex = DecorationTypeIndex + 1, #DecorationTypes do

		-- Get the UI
		local DecorationType = DecorationTypes[DecorationTypeIndex];
		local UI = DecorateTool.UI[DecorationType];

		-- Perform the position animation
		UI:TweenPosition(
			UDim2.new(
				UI.Position.X.Scale,
				UI.Position.X.Offset,
				UI.Position.Y.Scale,
				30 + 30 * (DecorationTypeIndex - 1) + HeightExpansion.Y.Offset
			),
			Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true
		);

	end;

end;

function CloseOptions(Exception)
	-- Closes all decoration options, except the one for the given decoration type

	-- Go through each decoration type
	for DecorationTypeIndex, DecorationType in pairs(DecorationTypes) do

		-- Get the UI for each decoration type
		local UI = DecorateTool.UI[DecorationType];
		local UITemplate = Core.Tool.Interfaces.BTDecorateToolGUI[DecorationType];

		-- Remember the initial size for each options UI
		local InitialSize = UITemplate.Options.Size;

		-- Move each decoration type UI to its starting position
		UI:TweenPosition(
			UDim2.new(
				UI.Position.X.Scale,
				UI.Position.X.Offset,
				UI.Position.Y.Scale,
				30 + 30 * (DecorationTypeIndex - 1)
			),
			Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true
		);
		
		-- Make sure to not resize the exempt decoration type UI
		if not Exception or Exception and DecorationType ~= Exception then

			-- Allow the options UI to be resized
			UI.Options.ClipsDescendants = true;

			-- Perform the resize animation to close up
			UI.Options:TweenSize(
				UDim2.new(UI.Options.Size.X.Scale, UI.Options.Size.X.Offset, UI.Options.Size.Y.Scale, 0),
				Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true,
				function ()

					-- Hide the option UI
					UI.ClipsDescendants = true;

					-- Set the options UI's size to its initial size (for reexpansion)
					UI.Options.Size = InitialSize;

				end
			);

		end;

	end;

	-- Contract the main UI if no option UIs are being opened
	if not Exception then
		DecorateTool.UI:TweenSize(
			Core.Tool.Interfaces.BTDecorateToolGUI.Size,
			Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true
		);
	end;

end;

function SyncInputToProperty(Property, DecorationType, InputType, Input)
	-- Enables `Input` to change the given property

	-- Enable inputs
	if InputType == 'Color' then
		Input.MouseButton1Click:connect(function ()
			Core.Cheer(Core.Tool.Interfaces.BTHSVColorPicker, Core.UI).Start(
				Support.IdentifyCommonProperty(GetDecorations(DecorationType), Property) or Color3.new(0, 0, 1),
				function (Color) SetProperty(DecorationType, Property, Color) end,
				Core.Targeting.CancelSelecting
			);
		end);

	-- Enable number inputs
	elseif InputType == 'Number' then
		Input.FocusLost:connect(function ()
			SetProperty(DecorationType, Property, tonumber(Input.Text));
		end);

	end;

end;

function SetProperty(DecorationType, Property, Value)

	-- Make sure the given value is valid
	if not Value then
		return;
	end;

	-- Start a history record
	TrackChange();

	-- Go through each decoration
	for _, Decoration in pairs(GetDecorations(DecorationType)) do

		-- Store the state of the decoration before modification
		table.insert(HistoryRecord.Before, { Part = Decoration.Parent, DecorationType = DecorationType, [Property] = Decoration[Property] });

		-- Create the change request for this decoration
		table.insert(HistoryRecord.After, { Part = Decoration.Parent, DecorationType = DecorationType, [Property] = Value });

	end;

	-- Register the changes
	RegisterChange();

end;

function AddDecorations(DecorationType)

	-- Prepare the change request for the server
	local Changes = {};

	-- Go through the selection
	for _, Part in pairs(Selection.Items) do

		-- Make sure this part doesn't already have a decoration
		if not Support.GetChildOfClass(Part, DecorationType) then

			-- Queue a decoration to be created for this part
			table.insert(Changes, { Part = Part, DecorationType = DecorationType });

		end;

	end;

	-- Send the change request to the server
	local Decorations = Core.SyncAPI:Invoke('CreateDecorations', Changes);

	-- Put together the history record
	local HistoryRecord = {
		Decorations = Decorations;

		Unapply = function (HistoryRecord)
			-- Reverts this change

			-- Select changed parts
			Selection.Replace(Support.GetListMembers(HistoryRecord.Decorations, 'Parent'));

			-- Remove the decorations
			Core.SyncAPI:Invoke('Remove', HistoryRecord.Decorations);

		end;

		Apply = function (HistoryRecord)
			-- Reapplies this change

			-- Restore the decorations
			Core.SyncAPI:Invoke('UndoRemove', HistoryRecord.Decorations);

			-- Select changed parts
			Selection.Replace(Support.GetListMembers(HistoryRecord.Decorations, 'Parent'));

		end;

	};

	-- Register the history record
	Core.History.Add(HistoryRecord);

	-- Open the options UI for this decoration type
	OpenOptions(DecorationType);

end;

function RemoveDecorations(DecorationType)

	-- Get all the decorations in the selection
	local Decorations = GetDecorations(DecorationType);

	-- Create the history record
	local HistoryRecord = {
		Decorations = Decorations;

		Unapply = function (HistoryRecord)
			-- Reverts this change

			-- Restore the decorations
			Core.SyncAPI:Invoke('UndoRemove', HistoryRecord.Decorations);

			-- Select changed parts
			Selection.Replace(Support.GetListMembers(HistoryRecord.Decorations, 'Parent'));

		end;

		Apply = function (HistoryRecord)
			-- Reapplies this change

			-- Select changed parts
			Selection.Replace(Support.GetListMembers(HistoryRecord.Decorations, 'Parent'));

			-- Remove the decorations
			Core.SyncAPI:Invoke('Remove', HistoryRecord.Decorations);

		end;

	};

	-- Send the removal request
	Core.SyncAPI:Invoke('Remove', Decorations);

	-- Register the history record
	Core.History.Add(HistoryRecord);

end;
