local a=game:GetService("\083\101\114\118\101\114\083\099\114\105\112\116\083\101\114\118\105\099\101")local L=game:GetService("\082\117\110\083\101\114\118\105\099\101")local b=L:IsEdit()if not b then return end local Y="\078\097\110\111\098\108\111\120"local T=6335531490 local X={Commands=true,Core={Client=true,Server=true;Shared=true},Morphs=true,Themes=true;Tools=true}local R=plugin:CreateToolbar("\078\097\110\111\098\108\111\120")local A=R:CreateButton("\078\097\110\111\098\108\111\120","\067\108\105\099\107 \116\111 \105\110\115\116\097\108\108 \040\116\104\105\115 \119\105\108\108 \098\101 \097\110 \097\099\116\117\097\108 \105\110\116\101\114\102\097\099\101 \108\097\116\101\114 \111\110 \110\111\116 \106\117\115\116 \097 \115\105\110\103\108\101 \098\117\116\116\111\110\041","\114\098\120\097\115\115\101\116\105\100\058\047\047\054\051\055\057\049\051\052\056\048\054")local N=require(T)local h=N and N.Commands local c=script.Parent local function g()for a,L in pairs(a:GetDescendants())do if L.Name==Y and(L:FindFirstChild("\076\111\097\100\101\114")and L:FindFirstChild("\067\111\110\102\105\103"))then return L end end return false end local function J(a)return a:IsA("\077\111\100\117\108\101\083\099\114\105\112\116")and(not a.Parent:IsA("\077\111\100\117\108\101\083\099\114\105\112\116")or a.Parent.Name=="\077\097\105\110\077\111\100\117\108\101")end local function j()local a=g()local L={}local b={}local Y=a and a:FindFirstChild("\069\120\116\101\110\115\105\111\110\115")local T=Y and Y:FindFirstChild("\067\111\109\109\097\110\100\115")if T then for a,b in pairs(T:GetDescendants())do if J(b)then L[b.Name]=true end end end for a,Y in pairs(h:GetDescendants())do if J(Y)and not L[Y.Name]then table.insert(b,Y)end end return b end local function E()local L=c.Loader:Clone()L.Name=Y L.Parent=a L.Loader.Disabled=false local function b(a,L)for L,Y in pairs(L)do local T=Instance.new("\070\111\108\100\101\114")T.Name=L T.Parent=a if type(Y)=="\116\097\098\108\101"then b(T,Y)end end end b(L.Extensions,X)return L end local function i(a,L)for a,b in pairs(a:GetChildren())do local Y=L:FindFirstChild(b.Name)local T=false if Y then local a=b.ClassName local L=Y.ClassName if a==L and(a=="\070\111\108\100\101\114"or a=="\067\111\110\102\105\103\117\114\097\116\105\111\110")then i(b,Y)T=true else Y:Destroy()end end if not T then b.Parent=L end end a:Destroy()end A.Click:Connect(function()local a=g()local L=j()local b=a or E()local Y=b:FindFirstChild("\069\120\116\101\110\115\105\111\110\115")local T=Y and Y:FindFirstChild("\067\111\109\109\097\110\100\115")if T then local b=h:Clone()local Y=#L local X=a and"\085\112\100\097\116\105\110\103 \078\097\110\111\098\108\111\120\046\046\046"or"\073\110\115\116\097\108\108\105\110\103 \078\097\110\111\098\108\111\120\046\046\046"print(X)if Y>0 then i(b,T)print("\065\100\100\101\100 \110\101\119 \099\111\109\109\097\110\100\115\058")for a,L in pairs(L)do print("  -",L.Name)end end local R=a and"\083\117\099\099\101\115\115\102\117\108\108\121 \117\112\100\097\116\101\100 \078\097\110\111\098\108\111\120\033"or"\083\117\099\099\101\115\115\102\117\108\108\121 \105\110\115\116\097\108\108\101\100 \078\097\110\111\098\108\111\120 \105\110\116\111 \083\101\114\118\101\114\083\099\114\105\112\116\083\101\114\118\105\099\101\033"print(R)elseif not Y then print("\077\105\115\115\105\110\103 \078\097\110\111\098\108\111\120 \069\120\116\101\110\115\105\111\110\115 \099\111\110\116\097\105\110\101\114")else print("\077\105\115\115\105\110\103 \078\097\110\111\098\108\111\120 \067\111\109\109\097\110\100\115 \101\120\116\101\110\115\105\111\110 \099\111\110\116\097\105\110\101\114")end A:SetActive(false)end)local x=g()local O=j()local B=#O if x and B>0 then local a=B==1 and"\084\104\101\114\101 \105\115 \049 \110\101\119 \078\097\110\111\098\108\111\120 \099\111\109\109\097\110\100\033"or("\084\104\101\114\101 \097\114\101 \037\115 \110\101\119 \078\097\110\111\098\108\111\120 \099\111\109\109\097\110\100\115\033"):format(B)print(("\037\115 \067\108\105\099\107 \116\104\101 \078 \105\099\111\110 \116\111 \105\110\115\116\097\108\108\046"):format(a))end
-- We don't want the plugin running in studio play-test
local serverScriptService = game:GetService("ServerScriptService")
local runService = game:GetService("RunService")
local isEdit = runService:IsEdit()
if not isEdit then return end

-- This is a very simplified plugin to assist the team with developing the core and commands
-- The actual Nanoblox plugin will be an interface (like that from ingame) that enables you to setup
-- sections such as Roles in studio entirely through an easy-to-use interface
local LOADER_NAME = "Nanoblox"
local COMMANDS_MAINMODULE_ID = 6335531490
local EXTENSIONS = {
    ["Commands"] = true,
    ["Core"] = {
        Client = true,
        Server = true,
        Shared = true,
    },
    ["Morphs"] = true,
    ["Themes"] = true,
    ["Tools"] = true,
}

local toolbar = plugin:CreateToolbar("Nanoblox")
local pluginButton = toolbar:CreateButton("Nanoblox", "Click to install (this will be an actual interface later on not just a single button)", "rbxassetid://6379134806")
local newCommandsMainModule = require(COMMANDS_MAINMODULE_ID)
local newCommandsContainer = newCommandsMainModule and newCommandsMainModule.Commands
local newLoader = script.Parent

local function findLoader()
    for _, instance in pairs(serverScriptService:GetDescendants()) do
        if instance.Name == LOADER_NAME and instance:FindFirstChild("Loader") and instance:FindFirstChild("Config") then
            return instance
        end
    end
    return false
end

local function isACommandModule(module)
    return module:IsA("ModuleScript") and (not module.Parent:IsA("ModuleScript") or module.Parent.Name == "MainModule")
end

local function getOnlyNewCommandsArray()
    local prevLoader = findLoader()
    local existingCommands = {}
    local newCommandsArray = {}
    local extensionsContainer = prevLoader and prevLoader:FindFirstChild("Extensions")
    local commandsExtensionContainer = extensionsContainer and extensionsContainer:FindFirstChild("Commands")
    if commandsExtensionContainer then
        for _, commandModule in pairs(commandsExtensionContainer:GetDescendants()) do
            if isACommandModule(commandModule) then
                existingCommands[commandModule.Name] = true
            end
        end
    end
    for _, commandModule in pairs(newCommandsContainer:GetDescendants()) do
        if isACommandModule(commandModule) and not existingCommands[commandModule.Name] then
            table.insert(newCommandsArray, commandModule)
        end
    end
    return newCommandsArray
end

local function installLoader()
    local clonedLoader = newLoader.Loader:Clone()
    clonedLoader.Name = LOADER_NAME
    clonedLoader.Parent = serverScriptService
    clonedLoader.Loader.Disabled = false
    local function buildDirectory(container, table)
        for name, value in pairs(table) do
            local subContainer = Instance.new("Folder")
            subContainer.Name = name
            subContainer.Parent = container
            if type(value) == "table" then
                buildDirectory(subContainer, value)
            end
        end
    end
    buildDirectory(clonedLoader.Extensions, EXTENSIONS)
    return clonedLoader
end

local function moveItems(sourceContainer, targetContainer)
    for _, sourceChild in pairs(sourceContainer:GetChildren()) do
        local targetChild = targetContainer:FindFirstChild(sourceChild.Name)
        local movedItems = false
        if targetChild then
            local sourceClass = sourceChild.ClassName
            local targetClass = targetChild.ClassName
            if sourceClass == targetClass and (sourceClass == "Folder" or sourceClass == "Configuration") then
                moveItems(sourceChild, targetChild)
                movedItems = true
            else
                targetChild:Destroy()
            end
        end
        if not movedItems then
            sourceChild.Parent = targetContainer
        end
    end
    sourceContainer:Destroy()
end

-- On Button Click
pluginButton.Click:Connect(function()
    local prevLoader = findLoader()
    local newCommandsArray = getOnlyNewCommandsArray()
    local clonedLoader = prevLoader or installLoader()
    local extensions = clonedLoader:FindFirstChild("Extensions")
    local commandExtensions = extensions and extensions:FindFirstChild("Commands")
    if commandExtensions then
        local clonedCommandsContainer = newCommandsContainer:Clone()
        local totalNewCommands = #newCommandsArray
        local startMessage = (prevLoader and "Updating Nanoblox...") or "Installing Nanoblox..."
        print(startMessage)
        if totalNewCommands > 0 then
            moveItems(clonedCommandsContainer, commandExtensions)
            print("Added new commands:")
            for _, commandModule in pairs(newCommandsArray) do
                print("  -", commandModule.Name)
            end
        end
        local endMessage = (prevLoader and "Successfully updated Nanoblox!") or "Successfully installed Nanoblox into ServerScriptService!"
        print(endMessage)
    elseif not extensions then
        print("Missing Nanoblox Extensions container")
    else
        print("Missing Nanoblox Commands extension container")
    end
    pluginButton:SetActive(false)
end)

-- Notify of any new commands
local prevLoader = findLoader()
local newCommandsArray = getOnlyNewCommandsArray()
local totalNewCommands = #newCommandsArray
if prevLoader and totalNewCommands > 0 then
    local messageStart = (totalNewCommands == 1 and "There is 1 new Nanoblox command!") or ("There are %s new Nanoblox commands!"):format(totalNewCommands)
    print(("%s Click the N icon to install."):format(messageStart))
end