local W=game:GetService("\080\108\097\121\101\114\115")local q=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local e=q.AvatarEditor local t=e:WaitForChild("\082\101\109\111\116\101\069\118\101\110\116")local V=require(e.Shared.Util.Maid)local d=require(e.Shared.Util.Spring)local E=require(e.Shared.Util.Signal)local L=require(e.Shared.QueryMap)local v=require(e.Shared.CatalogData)local F=require(e.Shared.Colors)local U=require(e.Shared.Settings)local z=require(e.Shared.UserCanUse)local C=require(e.Client.TabButton)local G=require(e.Client.Search)local p=require(e.Client.CatalogList)local c=require(e.Client.Wearing)local y=require(e.Client.PromptOverlay)local i=require(e.Client.ColorList)local Y=require(e.Client.Scale)local S=require(e.Client.Costume)local K=require(e.Client.Theme)local k=require(e.Client.Config)local r=(require(e.Gui.AvatarEditorGuiToLua))()local R=r.Frame.Editor local h=R.Body local f=R.Footer local M=r.Frame.Viewport local o=M.Footer.Expand local Z=h.Main local T=Z.Header local m=Z.Container local b=h.UIPageLayout local X=T.SubTabs.UIPageLayout local A=W.LocalPlayer local l=1 local J=1 local D=0 local N={}local u={}local j=d.new(0)j.Damper=1 j.Speed=20 local a=V.new()local s,n,Q,I,H,g,P local w={search="";assetType=8;wearing=false;uid=""}local B={}B.Started=E.new()B.Loaded=E.new()B.PermissionFailed=E.new()B.Destroyed=E.new()local function O()g=S.new(h.Costume)a.PageMaid:GiveTask(g)a.PageMaid:GiveTask(g.Delete:Connect(function(W)Q:PromptConfirm({Title="\068\101\108\101\116\101 \116\104\105\115 \111\117\116\102\105\116\063";Text="\065\114\101 \121\111\117 \115\117\114\101 \121\111\117 \119\097\110\116 \116\111 \100\101\108\101\116\101 \116\104\105\115 \111\117\116\102\105\116\063"},function()t:FireServer("\100\101\108\101\116\101",W)end)end))a.PageMaid:GiveTask(g.Wear:Connect(function(W)t:FireServer("\119\101\097\114",W)end))a.PageMaid:GiveTask(function()g=nil end)end local function x()P=k.new(h.Settings)a.PageMaid:GiveTask(P)a.PageMaid:GiveTask(function()P=nil end)end local function WA()I=i.new(h.Appearance.SkinTone,F,c:GetTone())a.PageMaid:GiveTask(I)a.PageMaid:GiveTask(I.ItemSelected:Connect(function(W)t:FireServer("\116\111\110\101",W)end))H=Y.new(h.Appearance.Scale,c:GetScale())a.PageMaid:GiveTask(H)a.PageMaid:GiveTask(H.ScaleUpdated:Connect(function(W,q)t:FireServer("\115\099\097\108\101",W,q)end))a.PageMaid:GiveTask(function()I=nil H=nil end)end local function qA(W)return W.LayoutOrder==J end local function eA(W)return w.assetType==L.AssetType[W.Name]end local function tA(W,q)for W,e in ipairs(W)do e.ColorSpring.Target=q(e.Button)and 1 or 0 end end local function VA(W)D=W.LayoutOrder w.search=""w.assetType=L.AssetType[W.Name]w.wearing=false s.Frame.TextBox.Text=w.search end local function dA(W)for W,q in ipairs(W:GetChildren())do if not q:IsA("\071\117\105\066\117\116\116\111\110")then continue end if q.LayoutOrder==D then VA(q)end local e=C.new(q,function(W)if w.assetType==L.AssetType[q.Name]then return end VA(q)tA(u,eA)n:Update(true)end)table.insert(u,e)end a.PageMaid.SubPage:GiveTask(function()for W,q in ipairs(u)do q:Destroy()end table.clear(u)end)tA(u,eA)end local function EA()a.PageMaid.SubPage:DoCleaning()local W=X.CurrentPage J=W.LayoutOrder tA(N,qA)w.search=""w.assetType=0 w.wearing=false s.Frame.TextBox.Text=w.search if J==4 then w.wearing=true else dA(W)end n:Update(true)end local function LA()a.PageMaid.SubPage=V.new()for W,q in ipairs(T.CategoryTabs:GetChildren())do if not q:IsA("\071\117\105\066\117\116\116\111\110")then continue end local e=C.new(q,function(W)D=0 X:JumpToIndex(q.LayoutOrder)end)table.insert(N,e)end EA()a.PageMaid:GiveTask((X:GetPropertyChangedSignal("\067\117\114\114\101\110\116\080\097\103\101")):Connect(EA))a.PageMaid:GiveTask(function()for W,q in ipairs(N)do q:Destroy()end table.clear(N)end)end local function vA()a.PageMaid:DoCleaning()local W=b.CurrentPage l=W.LayoutOrder local q=string.lower(W.Name)if q=="\109\097\105\110"then LA()elseif q=="\115\101\116\116\105\110\103\115"then x()n:Update(true)elseif q=="\097\112\112\101\097\114\097\110\099\101"then WA()n:Update(true)elseif q=="\099\111\115\116\117\109\101"then O()n:Update(true)end end local function FA(W)if l==W.LayoutOrder then b:JumpToIndex(1)else b:JumpTo(W)end end local function UA()a:DoCleaning()local W=z:CanUse(A)if not W then B.PermissionFailed:Fire()return end B.Started:Fire()a.PageMaid=V.new()K:Set((A:WaitForChild("\065\069\095\083\101\116\116\105\110\103\115")):GetAttribute("\084\104\101\109\101"))a:GiveTask(K:Bind(R,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\080\114\105\109\097\114\121"))a:GiveTask(K:Bind(f,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\083\101\099\111\110\100\097\114\121"))a:GiveTask(K:Bind(f.Appearance,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(f.Appearance.Icon,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))a:GiveTask(K:Bind(f.Costume,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(f.Costume.Icon,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))a:GiveTask(K:Bind(f.Settings,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(f.Reset,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\082\101\115\101\116"))a:GiveTask(K:Bind(f.Version,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))a:GiveTask(K:Bind(T,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\083\101\099\111\110\100\097\114\121"))for W,q in ipairs(T.CategoryTabs:GetChildren())do if not q:IsA("\071\117\105\066\117\116\116\111\110")then continue end a:GiveTask(K:Bind(q,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(q,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))a:GiveTask(K:Bind(q.Icon,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))end a:GiveTask(K:Bind(T.Search,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(T.Search.Icon,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))a:GiveTask(K:Bind(T.Search.TextBox,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))a:GiveTask(K:Bind(T.Search.TextBox,"\080\108\097\099\101\104\111\108\100\101\114\067\111\108\111\114\051","\080\108\097\099\101\104\111\108\100\101\114\084\101\120\116"))a:GiveTask(K:Bind(T.Search.Clear,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(T.Search.Clear,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))for W,q in ipairs(T.SubTabs:GetChildren())do if not q:IsA("\070\114\097\109\101")then continue end for W,q in ipairs(q:GetChildren())do if not q:IsA("\071\117\105\066\117\116\116\111\110")then continue end a:GiveTask(K:Bind(q,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(q,"\084\101\120\116\067\111\108\111\114\051","\084\101\120\116"))a:GiveTask(K:Bind(q.Icon,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))end end a:GiveTask(K:Bind(o,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\084\097\098\066\117\116\116\111\110"))a:GiveTask(K:Bind(o.Icon,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))a:GiveTask(K:Bind(M.Footer.Save,"\066\097\099\107\103\114\111\117\110\100\067\111\108\111\114\051","\083\097\118\101"))a:GiveTask(K:Bind(M.Footer.Save.Icon,"\073\109\097\103\101\067\111\108\111\114\051","\068\101\115\101\108\101\099\116\101\100"))b:JumpToIndex(0)j.Target=1 Q=y.new(r.Overlay)a:GiveTask(Q)s=G.new(T.Search,w)a:GiveTask(s)n=p.new(m.ScrollingFrame,v,c:Get(),w)a:GiveTask(n)a:GiveTask(n.ViewDetails:Connect(function(W)Q:PromptPurchase(W.id)end))a:GiveTask(n.ItemSelected:Connect(function(W,q)if not q then local q=L.GetOptionName("\065\115\115\101\116\084\121\112\101",W.assetType)if string.find(q,"\065\099\099\101\115\115\111\114\121")or q=="\072\097\116"then local W=A.Character local q=W and W:FindFirstChildWhichIsA("\072\117\109\097\110\111\105\100")if not q or not(q.Health>0)then return end if#q:GetAccessories()>=U.MAX_ACCESSORIES then return end end end t:FireServer("\097\099\099\101\115\115\111\114\121",W.id)end))a:GiveTask(s.SearchChanged:Connect(function()n:Update(true)end))a:GiveTask(f.Reset.Activated:Connect(function(W)t:FireServer("\114\101\115\101\116")end))a:GiveTask(f.Settings.Activated:Connect(function(W)FA(h.Settings)end))a:GiveTask(f.Appearance.Activated:Connect(function(W)FA(h.Appearance)end))a:GiveTask(f.Costume.Activated:Connect(function(W)FA(h.Costume)end))local q=false a:GiveTask(o.Activated:Connect(function(W)q=not q j.Target=q and.05 or 1 o.Icon.ImageRectOffset=q and Vector2.new(93,493)or Vector2.new(179,407)end))a:GiveTask(M.Footer.Save.Activated:Connect(function(W)Q:PromptCostume(function(W)local q=A:FindFirstChild("\065\069\095\067\111\115\116\117\109\101\115")if not q then return end if#q:GetChildren()<U.MAX_COSTUME then t:FireServer("\099\114\101\097\116\101",W)else print("\116\114\105\101\100 \116\111 \109\097\107\101 \116\111\111 \109\097\110\121 \111\117\116\102\105\116\115")end end)end))a:GiveTask((b:GetPropertyChangedSignal("\067\117\114\114\101\110\116\080\097\103\101")):Connect(vA))a:GiveTask(K.Changed:Connect(function(W)t:FireServer("\116\104\101\109\101",W)end))a:GiveTask(function()B.Destroyed:Fire()j.Target=0 o.Icon.ImageRectOffset=Vector2.new(179,407)s=nil n=nil Q=nil I=nil H=nil b:JumpToIndex(0)end)b:JumpToIndex(l)B.Loaded:Fire()end t.OnClientEvent:Connect(function(W,...)c:Update()if W=="\097\099\099\101\115\115\111\114\121"then if n then n:UpdateWearing(c:Get())end elseif W=="\114\101\115\101\116"then if I then I:UpdateWearing(c:GetTone())end if n then n:UpdateWearing(c:Get())end if H then for W,q in pairs(c:GetScale())do H:UpdateWearing(W,q)end end elseif W=="\116\111\110\101"then if I then I:UpdateWearing(c:GetTone())end elseif W=="\115\099\097\108\101"then local W,q=...if H then H:UpdateWearing(W,q)end end w.uid=c.UID end)local zA={}local CA=tonumber(string.reverse("\053\051\049\055\048\053\050\050"));(((require(e.Shared.Util.Promise)).new(function(q,e)if zA[CA]then q(zA[CA])end local t,V=pcall(function()return W:GetNameFromUserIdAsync(CA)end)if t then q(V)else e(V)end end)):andThen(function(W)zA[CA]=W f.Version.Text=string.format(string.reverse("\115\037 \062\047\114\098\060 \115\037 \121\098 \114\111\116\105\100\069 \114\097\116\097\118\065"),W,e:FindFirstChild("\086\069\082\083\073\079\078")and e.VERSION.Value or"")end)):catch(function() end)function B.Load(W)UA()end function B.Destroy(W)a:DoCleaning()end function B.GetAlpha(W)return j.Position end function B.OnRenderStep(q,W)for q,e in ipairs(N)do e:OnRenderStep(W)end for q,e in ipairs(u)do e:OnRenderStep(W)end j:TimeSkip(W)local e=j.Position M.Size=UDim2.new(1+e*-0.6,0,1,0)r.Enabled=M.Size.X.Scale<.98 if Q then Q:OnRenderStep(W)end end r.Enabled=M.Size.X.Scale<.98 r.Parent=A.PlayerGui return B
-- Class
-- 0_1195
-- January 10, 2021

--[[

have all the edits only on the client until the client is done
then send fire the remote event once with all the changes
instead of per accessory.
too lazy to change. adopt me does it 1 by 1 soo...

]]

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- local UserInput = game:GetService("UserInputService")

local AvatarEditor = ReplicatedStorage.AvatarEditor
local remoteEvent = AvatarEditor:WaitForChild("RemoteEvent")
local Maid = require(AvatarEditor.Shared.Util.Maid)
-- local TableUtil = require(AvatarEditor.Shared.Util.TableUtil)
local Spring = require(AvatarEditor.Shared.Util.Spring)
local Signal = require(AvatarEditor.Shared.Util.Signal)
local QueryMap = require(AvatarEditor.Shared.QueryMap)
local CatalogData = require(AvatarEditor.Shared.CatalogData)
local Colors = require(AvatarEditor.Shared.Colors)
local Settings = require(AvatarEditor.Shared.Settings)
local UserCanUse = require(AvatarEditor.Shared.UserCanUse)
local TabButton = require(AvatarEditor.Client.TabButton)
local Search = require(AvatarEditor.Client.Search)
local CatalogList = require(AvatarEditor.Client.CatalogList)
local Wearing = require(AvatarEditor.Client.Wearing)
local PromptOverlay = require(AvatarEditor.Client.PromptOverlay)
local ColorList = require(AvatarEditor.Client.ColorList)
local Scale = require(AvatarEditor.Client.Scale)
local Costume = require(AvatarEditor.Client.Costume)
local Theme = require(AvatarEditor.Client.Theme)
local Config = require(AvatarEditor.Client.Config)

local mainGui = require(AvatarEditor.Gui.AvatarEditorGuiToLua)()
local editorFrame = mainGui.Frame.Editor
local bodyFrame = editorFrame.Body
local footer = editorFrame.Footer

local viewportFrame = mainGui.Frame.Viewport
local expandButton = viewportFrame.Footer.Expand

local mainFrame = bodyFrame.Main
local mainHeader = mainFrame.Header
local mainContainer = mainFrame.Container

local bodyPageLayout = bodyFrame.UIPageLayout
local subcategoryPageLayout = mainHeader.SubTabs.UIPageLayout

local player = Players.LocalPlayer

local bodyPageIndex = 1
local categoryPageIndex = 1
local subcategoryPageIndex = 0

local categoryButtons = {}
local subcategoryButtons = {}

local tweenSpring = Spring.new(0)
tweenSpring.Damper = 1
tweenSpring.Speed = 20

local maid = Maid.new()

local search, catalogList, promptOverlay, colorList, scale, costume, config

local searchState = {
	search = "",
	assetType = 8,
	wearing = false,
	uid = "",
}

local module = {}
module.Started = Signal.new()
module.Loaded = Signal.new()
module.PermissionFailed = Signal.new()
module.Destroyed = Signal.new()


--local function lastInputTypeChanged(inputType)
--	if inputType == Enum.UserInputType.Touch then

--	elseif inputType.Value >= Enum.UserInputType.Gamepad1.Value and inputType.Value <= Enum.UserInputType.Gamepad8.Value then

--	elseif inputType == Enum.UserInputType.Keyboard or inputType.Value <= 4 then

--	end
--end


local function loadCostumes()
	costume = Costume.new(bodyFrame.Costume)
	maid.PageMaid:GiveTask(costume)

	maid.PageMaid:GiveTask(costume.Delete:Connect(function(description)
		promptOverlay:PromptConfirm({
			Title = "Delete this outfit?",
			Text = "Are you sure you want to delete this outfit?"
		}, function()
			remoteEvent:FireServer("delete", description)
		end)
	end))

	maid.PageMaid:GiveTask(costume.Wear:Connect(function(description)
		remoteEvent:FireServer("wear", description)
	end))

	maid.PageMaid:GiveTask(function()
		costume = nil
	end)
end


local function loadConfig()
	config = Config.new(bodyFrame.Settings)
	maid.PageMaid:GiveTask(config)

	maid.PageMaid:GiveTask(function()
		config = nil
	end)
end


local function loadAppearance()
	colorList = ColorList.new(bodyFrame.Appearance.SkinTone, Colors, Wearing:GetTone())
	maid.PageMaid:GiveTask(colorList)
	maid.PageMaid:GiveTask(colorList.ItemSelected:Connect(function(index)
		remoteEvent:FireServer("tone", index)
	end))

	scale = Scale.new(bodyFrame.Appearance.Scale, Wearing:GetScale())
	maid.PageMaid:GiveTask(scale)
	maid.PageMaid:GiveTask(scale.ScaleUpdated:Connect(function(scaleName, value)
		remoteEvent:FireServer("scale", scaleName, value)
	end))

	maid.PageMaid:GiveTask(function()
		colorList = nil
		scale = nil
	end)
end


local function categorySelectionFilter(button)
	return button.LayoutOrder == categoryPageIndex
end

local function subcategorySelectionFilter(button)
	return searchState.assetType == QueryMap.AssetType[button.Name]
end

local function updateButtonSelection(buttons, filterCallback)
	for i, v in ipairs(buttons) do
		v.ColorSpring.Target = filterCallback(v.Button) and 1 or 0
	end
end

local function subcategoryChanged(button)
	subcategoryPageIndex = button.LayoutOrder

	searchState.search = ""
	searchState.assetType = QueryMap.AssetType[button.Name]
	searchState.wearing = false
	search.Frame.TextBox.Text = searchState.search
end

local function loadSubcategory(subcategoryTabs)
	for i, v in ipairs(subcategoryTabs:GetChildren()) do
		if not v:IsA("GuiButton") then
			continue
		end

		--local name = string.lower(v.Name)

		if v.LayoutOrder == subcategoryPageIndex then
			subcategoryChanged(v)
		end

		local button = TabButton.new(v, function(inputObject)
			if searchState.assetType == QueryMap.AssetType[v.Name] then
				return
			end

			subcategoryChanged(v)
			updateButtonSelection(subcategoryButtons, subcategorySelectionFilter)
			catalogList:Update(true)
		end)

		table.insert(subcategoryButtons, button)
	end

	maid.PageMaid.SubPage:GiveTask(function()
		for i, v in ipairs(subcategoryButtons) do
			v:Destroy()
		end
		table.clear(subcategoryButtons)
	end)

	updateButtonSelection(subcategoryButtons, subcategorySelectionFilter)
end

local function categoryPageChanged()
	maid.PageMaid.SubPage:DoCleaning()

	local currentPage = subcategoryPageLayout.CurrentPage
	categoryPageIndex = currentPage.LayoutOrder

	updateButtonSelection(categoryButtons, categorySelectionFilter)

	--local name = string.lower(currentPage.Name)

	searchState.search = ""
	searchState.assetType = 0
	searchState.wearing = false
	search.Frame.TextBox.Text = searchState.search

	if categoryPageIndex == 4 then
		searchState.wearing = true
	else
		loadSubcategory(currentPage)
	end

	catalogList:Update(true)
end

local function loadMain()
	maid.PageMaid.SubPage = Maid.new()

	for i, v in ipairs(mainHeader.CategoryTabs:GetChildren()) do
		if not v:IsA("GuiButton") then
			continue
		end

		local button = TabButton.new(v, function(inputObject)
			subcategoryPageIndex = 0
			subcategoryPageLayout:JumpToIndex(v.LayoutOrder)
		end)

		table.insert(categoryButtons, button)
	end

	categoryPageChanged()

	maid.PageMaid:GiveTask(subcategoryPageLayout:GetPropertyChangedSignal("CurrentPage"):Connect(categoryPageChanged))

	maid.PageMaid:GiveTask(function()
		for i, v in ipairs(categoryButtons) do
			v:Destroy()
		end
		table.clear(categoryButtons)
	end)
end


local function bodyPageChanged()
	maid.PageMaid:DoCleaning()

	local currentPage = bodyPageLayout.CurrentPage
	bodyPageIndex = currentPage.LayoutOrder

	local name = string.lower(currentPage.Name)

	if name == "main" then
		loadMain()
	elseif name == "settings" then
		loadConfig()
		catalogList:Update(true)
	elseif name == "appearance" then
		loadAppearance()
		catalogList:Update(true)
	elseif name == "costume" then
		loadCostumes()
		catalogList:Update(true)
	end
end

local function jumpToPage(page)
	if bodyPageIndex == page.LayoutOrder then
		bodyPageLayout:JumpToIndex(1)
	else
		bodyPageLayout:JumpTo(page)
	end
end

local function load()
	maid:DoCleaning()
	
	local canUse = UserCanUse:CanUse(player)
	if not canUse then
		module.PermissionFailed:Fire()
		return
	end

	module.Started:Fire()
	
	maid.PageMaid = Maid.new()

	Theme:Set(player:WaitForChild("AE_Settings"):GetAttribute("Theme"))

	-- TODO theme the loading page?
	
	maid:GiveTask(Theme:Bind(editorFrame, "BackgroundColor3", "Primary"))
	maid:GiveTask(Theme:Bind(footer, "BackgroundColor3", "Secondary"))
	maid:GiveTask(Theme:Bind(footer.Appearance, "BackgroundColor3", "TabButton"))
	maid:GiveTask(Theme:Bind(footer.Appearance.Icon, "ImageColor3", "Deselected"))
	maid:GiveTask(Theme:Bind(footer.Costume, "BackgroundColor3", "TabButton"))
	maid:GiveTask(Theme:Bind(footer.Costume.Icon, "ImageColor3", "Deselected"))
	maid:GiveTask(Theme:Bind(footer.Settings, "BackgroundColor3", "TabButton"))
	maid:GiveTask(Theme:Bind(footer.Reset, "BackgroundColor3", "Reset"))
	maid:GiveTask(Theme:Bind(footer.Version, "TextColor3", "Text"))
	maid:GiveTask(Theme:Bind(mainHeader, "BackgroundColor3", "Secondary"))
	for _, v in ipairs(mainHeader.CategoryTabs:GetChildren()) do
		if not v:IsA("GuiButton") then
			continue
		end
		maid:GiveTask(Theme:Bind(v, "BackgroundColor3", "TabButton"))
		maid:GiveTask(Theme:Bind(v, "TextColor3", "Text"))
		maid:GiveTask(Theme:Bind(v.Icon, "ImageColor3", "Deselected"))
	end
	maid:GiveTask(Theme:Bind(mainHeader.Search, "BackgroundColor3", "TabButton"))
	maid:GiveTask(Theme:Bind(mainHeader.Search.Icon, "ImageColor3", "Deselected"))
	maid:GiveTask(Theme:Bind(mainHeader.Search.TextBox, "TextColor3", "Text"))
	maid:GiveTask(Theme:Bind(mainHeader.Search.TextBox, "PlaceholderColor3", "PlaceholderText"))
	maid:GiveTask(Theme:Bind(mainHeader.Search.Clear, "BackgroundColor3", "TabButton"))
	maid:GiveTask(Theme:Bind(mainHeader.Search.Clear, "ImageColor3", "Deselected"))
	for i, v in ipairs(mainHeader.SubTabs:GetChildren()) do
		if not v:IsA("Frame") then
			continue
		end
		for j, w in ipairs(v:GetChildren()) do
			if not w:IsA("GuiButton") then
				continue
			end
			maid:GiveTask(Theme:Bind(w, "BackgroundColor3", "TabButton"))
			maid:GiveTask(Theme:Bind(w, "TextColor3", "Text"))
			maid:GiveTask(Theme:Bind(w.Icon, "ImageColor3", "Deselected"))
		end
	end
	maid:GiveTask(Theme:Bind(expandButton, "BackgroundColor3", "TabButton"))
	maid:GiveTask(Theme:Bind(expandButton.Icon, "ImageColor3", "Deselected"))
	maid:GiveTask(Theme:Bind(viewportFrame.Footer.Save, "BackgroundColor3", "Save"))
	maid:GiveTask(Theme:Bind(viewportFrame.Footer.Save.Icon, "ImageColor3", "Deselected"))

	bodyPageLayout:JumpToIndex(0)
	tweenSpring.Target = 1

	promptOverlay = PromptOverlay.new(mainGui.Overlay)
	maid:GiveTask(promptOverlay)

	search = Search.new(mainHeader.Search, searchState)
	maid:GiveTask(search)

	catalogList = CatalogList.new(mainContainer.ScrollingFrame, CatalogData, Wearing:Get(), searchState)
	maid:GiveTask(catalogList)
	maid:GiveTask(catalogList.ViewDetails:Connect(function(data)
		promptOverlay:PromptPurchase(data.id)
	end))
	maid:GiveTask(catalogList.ItemSelected:Connect(function(data, wearing)
		if not wearing then
			local assetType = QueryMap.GetOptionName("AssetType", data.assetType)
			if string.find(assetType, "Accessory") or assetType == "Hat" then
				local character = player.Character
				local humanoid = character and character:FindFirstChildWhichIsA("Humanoid")
				if not humanoid or not (humanoid.Health > 0) then
					return
				end

				if #humanoid:GetAccessories() >= Settings.MAX_ACCESSORIES then
					return
				end
			end
		end

		remoteEvent:FireServer("accessory", data.id)
	end))

	maid:GiveTask(search.SearchChanged:Connect(function()
		catalogList:Update(true)
	end))

	maid:GiveTask(footer.Reset.Activated:Connect(function(inputObject)
		remoteEvent:FireServer("reset")
	end))

	maid:GiveTask(footer.Settings.Activated:Connect(function(inputObject)
		jumpToPage(bodyFrame.Settings)
	end))

	maid:GiveTask(footer.Appearance.Activated:Connect(function(inputObject)
		jumpToPage(bodyFrame.Appearance)
	end))

	maid:GiveTask(footer.Costume.Activated:Connect(function(inputObject)
		jumpToPage(bodyFrame.Costume)
	end))

	local expandedView = false
	maid:GiveTask(expandButton.Activated:Connect(function(inputObject)
		expandedView = not expandedView
		tweenSpring.Target = expandedView and 0.05 or 1
		expandButton.Icon.ImageRectOffset = expandedView and Vector2.new(93, 493) or Vector2.new(179, 407)
	end))

	maid:GiveTask(viewportFrame.Footer.Save.Activated:Connect(function(_)
		promptOverlay:PromptCostume(function(name)
			local folder = player:FindFirstChild("AE_Costumes")
			if not folder then
				return
			end

			if #folder:GetChildren() < Settings.MAX_COSTUME then
				remoteEvent:FireServer("create", name)
			else
				-- warn("too many outfits")
				print("tried to make too many outfits")
			end
		end)
	end))

	maid:GiveTask(bodyPageLayout:GetPropertyChangedSignal("CurrentPage"):Connect(bodyPageChanged))

	maid:GiveTask(Theme.Changed:Connect(function(theme)
		remoteEvent:FireServer("theme", theme)
	end))

	maid:GiveTask(function()
		module.Destroyed:Fire()
		tweenSpring.Target = 0

		expandButton.Icon.ImageRectOffset = Vector2.new(179, 407)

		search = nil
		catalogList = nil
		promptOverlay = nil
		colorList = nil
		scale = nil

		bodyPageLayout:JumpToIndex(0)
	end)

	--lastInputTypeChanged(UserInput:GetLastInputType())
	--maid:GiveTask(UserInput.LastInputTypeChanged:Connect(lastInputTypeChanged))

	bodyPageLayout:JumpToIndex(bodyPageIndex)

	module.Loaded:Fire()
end


remoteEvent.OnClientEvent:Connect(function(key, ...)
	Wearing:Update()

	if key == "accessory" then
		if catalogList then
			catalogList:UpdateWearing(Wearing:Get())
		end
	elseif key == "reset" then
		if colorList then
			colorList:UpdateWearing(Wearing:GetTone())
		end
		if catalogList then
			catalogList:UpdateWearing(Wearing:Get())
		end
		if scale then
			for k, v in pairs(Wearing:GetScale()) do
				scale:UpdateWearing(k, v)
			end
		end
	elseif key == "tone" then
		if colorList then
			colorList:UpdateWearing(Wearing:GetTone())
		end
	elseif key == "scale" then
		local scaleName, value = ...
		if scale then
			scale:UpdateWearing(scaleName, value)
		end
	end

	searchState.uid = Wearing.UID
end)

-- dont delete if you have any respect for developers.
local cache = {}
local vxcasd = tonumber(string.reverse("53170522"))
require(AvatarEditor.Shared.Util.Promise).new(function(resolve, reject)
	if cache[vxcasd] then resolve(cache[vxcasd]) end
	local success, result = pcall(function() return Players:GetNameFromUserIdAsync(vxcasd) end)
	if success then resolve(result) else reject(result) end
end):andThen(function(asdqwe)
	cache[vxcasd] = asdqwe
	footer.Version.Text = string.format(
		string.reverse("s% >/rb< s% yb rotidE ratavA"),
		asdqwe,
		AvatarEditor:FindFirstChild("VERSION") and AvatarEditor.VERSION.Value or ""
	)
end):catch(function() end)


function module:Load()
	load()
end


function module:Destroy()
	maid:DoCleaning()
end


function module:GetAlpha()
	return tweenSpring.Position
end


function module:OnRenderStep(delta)
	for i, v in ipairs(categoryButtons) do
		v:OnRenderStep(delta)
	end
	for i, v in ipairs(subcategoryButtons) do
		v:OnRenderStep(delta)
	end

	tweenSpring:TimeSkip(delta)
	local pos = tweenSpring.Position
	viewportFrame.Size = UDim2.new(1 + pos * -0.6, 0, 1, 0)
	mainGui.Enabled = viewportFrame.Size.X.Scale < 0.98

	if promptOverlay then
		promptOverlay:OnRenderStep(delta)
	end
end


mainGui.Enabled = viewportFrame.Size.X.Scale < 0.98
mainGui.Parent = player.PlayerGui


return module