if Mode=="\084\111\111\108"then AssignHotkey({"\076\101\102\116\067\111\110\116\114\111\108","\090"},History.Undo)AssignHotkey({"\082\105\103\104\116\067\111\110\116\114\111\108";"\090"},History.Undo)AssignHotkey({"\076\101\102\116\067\111\110\116\114\111\108";"\089"},History.Redo)AssignHotkey({"\082\105\103\104\116\067\111\110\116\114\111\108";"\089"},History.Redo)end local function l(l,y)local S=0 while l~=y do S=S+1 l=l.Parent end return S end local function y(y)local S,T for y,s in ipairs(y)do local i=l(s,game)if not T or i<T then S=s T=i end end return S and S.Parent or nil end function CloneSelection()if#Selection.Items==0 then return end local l=SyncAPI:Invoke("\067\108\111\110\101",Selection.Items,y(Selection.Items))local S={Clones=l;Unapply=function(l)Selection.Remove(l.Clones,false)SyncAPI:Invoke("\082\101\109\111\118\101",l.Clones)end,Apply=function(l)SyncAPI:Invoke("\085\110\100\111\082\101\109\111\118\101",l.Clones)end}History.Add(S)Selection.Replace(l);(coroutine.wrap(Selection.FlashOutlines))()end function DeleteSelection()local l={Parts=Support.CloneTable(Selection.Items);Unapply=function(l)SyncAPI:Invoke("\085\110\100\111\082\101\109\111\118\101",l.Parts)Selection.Replace(l.Parts)end;Apply=function(l)Selection.Remove(l.Parts,false)SyncAPI:Invoke("\082\101\109\111\118\101",l.Parts)end}Selection.Remove(l.Parts,false)SyncAPI:Invoke("\082\101\109\111\118\101",l.Parts)History.Add(l)end
-- If in-game, enable ctrl hotkeys for undoing and redoing
if Mode == "Tool" then
	AssignHotkey({ "LeftControl", "Z" }, History.Undo)
	AssignHotkey({ "RightControl", "Z" }, History.Undo)
	AssignHotkey({ "LeftControl", "Y" }, History.Redo)
	AssignHotkey({ "RightControl", "Y" }, History.Redo)
end

local function GetDepthFromAncestor(Item, Ancestor)
	-- Returns the depth of `Item` from `Ancestor`

	local Depth = 0

	-- Go through ancestry until reaching `Ancestor`
	while Item ~= Ancestor do
		Depth = Depth + 1
		Item = Item.Parent
	end

	-- Return depth
	return Depth
end

local function GetHighestParent(Items)
	local HighestItem, HighestItemDepth

	-- Calculate depth of each item & keep highest
	for _, Item in ipairs(Items) do
		local Depth = GetDepthFromAncestor(Item, game)
		if (not HighestItemDepth) or (Depth < HighestItemDepth) then
			HighestItem = Item
			HighestItemDepth = Depth
		end
	end

	-- Return parent of highest item
	return HighestItem and HighestItem.Parent or nil
end

function CloneSelection()
	-- Clones selected parts

	-- Make sure that there are items in the selection
	if #Selection.Items == 0 then
		return
	end

	-- Send the cloning request to the server
	local Clones = SyncAPI:Invoke("Clone", Selection.Items, GetHighestParent(Selection.Items))

	-- Put together the history record
	local HistoryRecord = {
		Clones = Clones,

		Unapply = function(HistoryRecord)
			-- Reverts this change

			-- Deselect the clones
			Selection.Remove(HistoryRecord.Clones, false)

			-- Remove the clones
			SyncAPI:Invoke("Remove", HistoryRecord.Clones)
		end,

		Apply = function(HistoryRecord)
			-- Reapplies this change

			-- Restore the clones
			SyncAPI:Invoke("UndoRemove", HistoryRecord.Clones)
		end,
	}

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

	-- Select the clones
	Selection.Replace(Clones)

	-- Flash the outlines of the new parts
	coroutine.wrap(Selection.FlashOutlines)()
end

function DeleteSelection()
	-- Deletes selected items

	-- Put together the history record
	local HistoryRecord = {
		Parts = Support.CloneTable(Selection.Items),

		Unapply = function(HistoryRecord)
			-- Reverts this change

			-- Restore the parts
			SyncAPI:Invoke("UndoRemove", HistoryRecord.Parts)

			-- Select the restored parts
			Selection.Replace(HistoryRecord.Parts)
		end,

		Apply = function(HistoryRecord)
			-- Applies this change

			-- Deselect the parts
			Selection.Remove(HistoryRecord.Parts, false)

			-- Remove the parts
			SyncAPI:Invoke("Remove", HistoryRecord.Parts)
		end,
	}

	-- Deselect parts before deleting
	Selection.Remove(HistoryRecord.Parts, false)

	-- Perform the removal
	SyncAPI:Invoke("Remove", HistoryRecord.Parts)

	-- Register the history record
	History.Add(HistoryRecord)
end
