local V={}local N={"\072\101\097\100";"\070\097\099\101","\083\104\105\114\116","\080\097\110\116\115","\071\114\097\112\104\105\099\084\083\104\105\114\116";"\072\101\097\100\067\111\108\111\114";"\076\101\102\116\065\114\109\067\111\108\111\114";"\076\101\102\116\076\101\103\067\111\108\111\114","\082\105\103\104\116\065\114\109\067\111\108\111\114","\082\105\103\104\116\076\101\103\067\111\108\111\114";"\084\111\114\115\111\067\111\108\111\114"}local q={"\095\075\070\105\114\101","\095\075\083\109\111\107\101","\095\075\083\112\097\114\107\108\101\115";"\095\075\076\105\103\104\116";"\095\075\080\097\114\116\105\099\108\101\069\102\102\101\099\116"}function V.applyDescription(V,N)V:ApplyDescriptionReset(N)V:ApplyDescription(N)end function V.updateDescription(V,N,q,E,I)local m="\095\075"..E local M=m.."\079\114\105\103\105\110\097\108"if not V:GetAttribute(M)then V:SetAttribute(M,q[E])end q[E]=I or V:GetAttribute(M)end function V.reapplyDescription(q)local E=q.Character and q.Character:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")local I=E and E:FindFirstChildOfClass("\072\117\109\097\110\111\105\100\068\101\115\099\114\105\112\116\105\111\110")if not I then return end local m for N,M in N do local w=q:GetAttribute("\095\075"..M)if w then m=true V.updateDescription(q,E,I,M,w)end end if m then V.applyDescription(E,I)end end function V.attributeDescription(N,q,E)local I=N.Character and N.Character:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")local m=I and I:FindFirstChildOfClass("\072\117\109\097\110\111\105\100\068\101\115\099\114\105\112\116\105\111\110")if not m then return end V.updateDescription(N,I,m,q,E)N:SetAttribute("\095\075"..q,E)V.applyDescription(I,m)end function V.resetDescription(E)local I=E.Character and E.Character:FindFirstChild("\072\117\109\097\110\111\105\100\082\111\111\116\080\097\114\116")or E.Character.PrimaryPart if I then for V,N in q do local q=I:FindFirstChild(N)if q then q:Destroy()end end end local m=E.Character and E.Character:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")local M=m and m:FindFirstChildOfClass("\072\117\109\097\110\111\105\100\068\101\115\099\114\105\112\116\105\111\110")local w=E:FindFirstChild("\095\075\072\117\109\097\110\111\105\100\068\101\115\099\114\105\112\116\105\111\110")if w then M:Destroy()w.Name="\072\117\109\097\110\111\105\100\068\101\115\099\114\105\112\116\105\111\110"w.Parent=m M=w end for V,N in N do local q="\095\075"..N local I=q.."\079\114\105\103\105\110\097\108"local m=E:GetAttribute(I)if m==nil then continue end E:SetAttribute(I,nil)if M then M[N]=m end end if m and M then V.applyDescription(m,M)end end return V
local Humanoid = {}

local properties = {
	"Head",
	"Face",
	"Shirt",
	"Pants",
	"GraphicTShirt",
	"HeadColor",
	"LeftArmColor",
	"LeftLegColor",
	"RightArmColor",
	"RightLegColor",
	"TorsoColor",
}
local particles = { "_KFire", "_KSmoke", "_KSparkles", "_KLight", "_KParticleEffect" }

function Humanoid.applyDescription(humanoid, description)
	humanoid:ApplyDescriptionReset(description)
	humanoid:ApplyDescription(description)
end

function Humanoid.updateDescription(player, humanoid, description, property, value)
	local attribute = "_K" .. property
	local original = attribute .. "Original"
	if not player:GetAttribute(original) then
		player:SetAttribute(original, description[property])
	end
	description[property] = value or player:GetAttribute(original)
end

function Humanoid.reapplyDescription(player)
	local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
	local description = humanoid and humanoid:FindFirstChildOfClass("HumanoidDescription")
	if not description then
		return
	end

	local change
	for _, property in properties do
		local value = player:GetAttribute("_K" .. property)
		if value then
			change = true
			Humanoid.updateDescription(player, humanoid, description, property, value)
		end
	end

	if change then
		Humanoid.applyDescription(humanoid, description)
	end
end

function Humanoid.attributeDescription(player, property, value)
	local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
	local description = humanoid and humanoid:FindFirstChildOfClass("HumanoidDescription")
	if not description then
		return
	end

	Humanoid.updateDescription(player, humanoid, description, property, value)
	player:SetAttribute("_K" .. property, value)

	Humanoid.applyDescription(humanoid, description)
end

function Humanoid.resetDescription(player)
	-- reset particles
	local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		or player.Character.PrimaryPart
	if root then
		for _, particle in particles do
			local existing = root:FindFirstChild(particle)
			if existing then
				existing:Destroy()
			end
		end
	end

	local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
	local description = humanoid and humanoid:FindFirstChildOfClass("HumanoidDescription")

	local originalDescription = player:FindFirstChild("_KHumanoidDescription")
	if originalDescription then
		description:Destroy()
		originalDescription.Name = "HumanoidDescription"
		originalDescription.Parent = humanoid
		description = originalDescription
	end

	-- reset properties
	for _, property in properties do
		local attribute = "_K" .. property
		local original = attribute .. "Original"
		local originalValue = player:GetAttribute(original)
		if originalValue == nil then
			continue
		end
		player:SetAttribute(original, nil)
		if description then
			description[property] = originalValue
		end
	end

	-- TODO: reset scale, accessories

	if humanoid and description then
		Humanoid.applyDescription(humanoid, description)
	end
end

return Humanoid
