local Players = game:GetService("Players")
local UIS = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local LogService = game:GetService("LogService")
local CoreGui = game:GetService("CoreGui")
local HttpService = game:GetService("HttpService")
local lp = Players.LocalPlayer
local NAME = "Hyundax IUM"
local VERSION = "v1.0.2"
local LOGO_URL = "https://files.catbox.moe/z33475.png"
local LOGO_FILE = "HyundaxIUM/logo2.dat"
local FOLDER = "HyundaxIUM"
local DB_FOLDER = "HyundaxIUMDB"
local FONT_FAMILY = "rbxasset://fonts/families/Inter.json"
local PATH = {
auto = FOLDER .. "/autoexec",
img = FOLDER .. "/img",
ui = FOLDER .. "/ui_" .. VERSION .. ".dat",
cloud = FOLDER .. "/cloud.json",
autoIdx = FOLDER .. "/autoexec.json",
saved = FOLDER .. "/saved_scripts.json",
likes = FOLDER .. "/likes.json",
stats = FOLDER .. "/stats.json",
flag = FOLDER .. "/cache_" .. VERSION .. ".ok",
}
PATH.fast = false
PATH.folderMissing = false
pcall(function()
if not (isfile and isfolder) then return end
PATH.folderMissing = not isfolder(FOLDER)
PATH.fast = (not PATH.folderMissing) and isfile(PATH.flag) and isfile(LOGO_FILE) and isfile(PATH.ui) and true or false
end)
if not PATH.fast then
pcall(function() if isfile and delfile and isfile(PATH.flag) then delfile(PATH.flag) end end)
end
pcall(function()
if makefolder and isfolder then
for _, d in ipairs({FOLDER, PATH.auto, PATH.img, DB_FOLDER}) do
if not isfolder(d) then makefolder(d) end
end
end
if writefile and isfile then
for _, d in ipairs({FOLDER, PATH.img}) do
if not isfile(d .. "/.nomedia") then writefile(d .. "/.nomedia", "") end
end
end
if listfiles and delfile then
local fl = listfiles(PATH.img)
if #fl > 400 then
for _, f in ipairs(fl) do
if not f:find("%.nomedia$") then pcall(delfile, f) end
end
end
end
if isfile and delfile and isfile("hyundaxium_logo.png") then pcall(delfile, "hyundaxium_logo.png") end
end)
local function toAsset(path, getData)
local ok, res = pcall(function()
if not (isfile and isfile(path)) then writefile(path, getData()) end
return (getcustomasset or getsynasset)(path)
end)
if ok and res then return res end
return nil
end
local Compat
do
local BRAND = {name = NAME, ver = VERSION}
local CONFIG = {compat = {polyfill = true, semantics = true, sharedGlobals = false, globalize = true, autotest = false, intrusive = false}}
local UserInputSvc = game:GetService("UserInputService")
local round = function(x) return math.floor(x + 0.5) end
local ENV = _G
if type(getgenv) == "function" then
local ok, e = pcall(getgenv)
if ok and type(e) == "table" then ENV = e end
end
local function grab(n)
local v = rawget(ENV, n)
if v == nil then v = rawget(_G, n) end
if v == nil and type(getfenv) == "function" then
local ok, r = pcall(function() return getfenv()[n] end)
if ok then v = r end
end
return v
end
local RAW_PRINT = ENV.print or print
local LOADSTRING = (type(loadstring) == "function" and loadstring) or grab("loadstring")
if type(LOADSTRING) ~= "function" then LOADSTRING = nil end
local EXECUTOR_NAME = "Unknown"
do
local idFn = grab("identifyexecutor")
if type(idFn) == "function" then
local ok, n = pcall(idFn)
if ok and type(n) == "string" then EXECUTOR_NAME = n end
end
end
local Bus = {h = {}}
function Bus.on(evt, fn)
Bus.h[evt] = Bus.h[evt] or {}
table.insert(Bus.h[evt], fn)
end
function Bus.emit(evt, ...)
for _, f in ipairs(Bus.h[evt] or {}) do pcall(f, ...) end
end
Bus.on("compat:state", function() if Compat and Compat.onState then Compat.onState() end end)
local Log = {}
for _, lvl in ipairs({"info", "warn", "error", "ok"}) do
Log[lvl] = function(msg)
local m = tostring(msg)
if #m > 300 then m = m:sub(1, 300) .. "..." end
if Compat and Compat.sink then pcall(Compat.sink, lvl, m) end
end
end
Compat = nil
Compat = { specs = {}, byName = {}, stats = nil, running = false, conns = {} }
do
local ROOT_G = _G
local specs, byName = Compat.specs, Compat.byName
local resolved = {}
local wrapped = setmetatable({}, { __mode = "k" })
local identity = 8
local appActive = true
local rng = Random.new()
pcall(function()
Compat.conns[#Compat.conns + 1] = UserInputSvc.WindowFocused:Connect(function() appActive = true end)
Compat.conns[#Compat.conns + 1] = UserInputSvc.WindowFocusReleased:Connect(function() appActive = false end)
end)
local function R(name) return resolved[name] end
local function expect(c, m) if not c then error(m or "assertion failed", 0) end end
local function need(...)
for _, n in ipairs({ ... }) do
if type(resolved[n]) ~= "function" then error("needs " .. n, 0) end
end
end
local function def(name, cat, poly, test, approx)
local s = { name = name, cat = cat, poly = poly, test = test, approx = approx }
specs[#specs + 1] = s
byName[name] = s
return s
end
local function alias(name, target, cat)
def(name, cat, function(r) return r(target) end,
function(f) expect(type(f) == "function", "not a function") end, "alias of " .. target)
end
local function natives(cat, list)
for _, n in ipairs(list) do def(n, cat) end
end
local function splitPath(p)
local t = {}
for part in p:gmatch("[^%.]+") do t[#t + 1] = part end
return t
end
local function nativeGet(name)
local parts = splitPath(name)
local cur = grab(parts[1])
for i = 2, #parts do
if type(cur) ~= "table" then return nil end
cur = cur[parts[i]]
end
return cur
end
local function hasNative(name)
local s = byName[name]
return s ~= nil and s.native ~= nil
end
local B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local B64REV = {}
for i = 1, 64 do B64REV[B64:byte(i)] = i - 1 end
local function b64enc(data)
data = tostring(data)
local out = {}
for i = 1, #data, 3 do
local a, b, c = data:byte(i, i + 2)
local n = a * 65536 + (b or 0) * 256 + (c or 0)
local c1 = math.floor(n / 262144) % 64
local c2 = math.floor(n / 4096) % 64
local c3 = math.floor(n / 64) % 64
local c4 = n % 64
out[#out + 1] = B64:sub(c1 + 1, c1 + 1) .. B64:sub(c2 + 1, c2 + 1)
.. (b and B64:sub(c3 + 1, c3 + 1) or "=") .. (c and B64:sub(c4 + 1, c4 + 1) or "=")
end
return table.concat(out)
end
local function b64dec(s)
s = tostring(s):gsub("[^%w%+/]", "")
local out = {}
for i = 1, #s, 4 do
local a, b, c, d = s:byte(i, i + 3)
local n1, n2 = B64REV[a], B64REV[b]
if not n1 or not n2 then break end
local n3 = c and B64REV[c]
local n4 = d and B64REV[d]
local n = n1 * 262144 + n2 * 4096 + (n3 or 0) * 64 + (n4 or 0)
out[#out + 1] = string.char(math.floor(n / 65536) % 256)
if n3 then out[#out + 1] = string.char(math.floor(n / 256) % 256) end
if n4 then out[#out + 1] = string.char(n % 256) end
end
return table.concat(out)
end
local function randBytes(n)
local t = {}
for i = 1, n do t[i] = string.char(rng:NextInteger(0, 255)) end
return table.concat(t)
end
local function sgn(x)
x = x % 4294967296
if x >= 2147483648 then x = x - 4294967296 end
return x
end
local function bytesToString(buf, n)
local parts = {}
local i = 1
while i <= n do
local j = math.min(i + 3999, n)
parts[#parts + 1] = string.char(table.unpack(buf, i, j))
i = j + 1
end
return table.concat(parts)
end
local function unhex(h)
return (h:gsub("%x%x", function(x) return string.char(tonumber(x, 16)) end))
end
local function be32(n)
return string.char(bit32.rshift(n, 24) % 256, bit32.rshift(n, 16) % 256, bit32.rshift(n, 8) % 256, n % 256)
end
local function padBE(msg)
local len = #msg
local bits = len * 8
return msg .. "\128" .. string.rep("\0", (55 - len) % 64)
.. be32(math.floor(bits / 4294967296)) .. be32(bits % 4294967296)
end
local K256, H256 = {}, {}
do
local primes, n = {}, 2
while #primes < 64 do
local isP = true
for _, p in ipairs(primes) do
if p * p > n then break end
if n % p == 0 then isP = false; break end
end
if isP then primes[#primes + 1] = n end
n = n + 1
end
for i = 1, 64 do K256[i] = math.floor((primes[i] ^ (1 / 3)) % 1 * 4294967296) end
for i = 1, 8 do H256[i] = math.floor((primes[i] ^ 0.5) % 1 * 4294967296) end
end
local function sha256(msg, iv)
msg = padBE(tostring(msg))
local h = table.clone(iv or H256)
local w = {}
for pos = 1, #msg, 64 do
for i = 0, 15 do
local a, b, c, d = msg:byte(pos + i * 4, pos + i * 4 + 3)
w[i] = a * 16777216 + b * 65536 + c * 256 + d
end
for i = 16, 63 do
local x, y = w[i - 15], w[i - 2]
local s0 = bit32.bxor(bit32.rrotate(x, 7), bit32.rrotate(x, 18), bit32.rshift(x, 3))
local s1 = bit32.bxor(bit32.rrotate(y, 17), bit32.rrotate(y, 19), bit32.rshift(y, 10))
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) % 4294967296
end
local a, b, c, d, e, f, g, hh = h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8]
for i = 0, 63 do
local S1 = bit32.bxor(bit32.rrotate(e, 6), bit32.rrotate(e, 11), bit32.rrotate(e, 25))
local ch = bit32.bxor(bit32.band(e, f), bit32.band(bit32.bnot(e), g))
local t1 = (hh + S1 + ch + K256[i + 1] + w[i]) % 4294967296
local S0 = bit32.bxor(bit32.rrotate(a, 2), bit32.rrotate(a, 13), bit32.rrotate(a, 22))
local maj = bit32.bxor(bit32.band(a, b), bit32.band(a, c), bit32.band(b, c))
local t2 = (S0 + maj) % 4294967296
hh, g, f, e, d, c, b, a = g, f, e, (d + t1) % 4294967296, c, b, a, (t1 + t2) % 4294967296
end
h[1] = (h[1] + a) % 4294967296; h[2] = (h[2] + b) % 4294967296
h[3] = (h[3] + c) % 4294967296; h[4] = (h[4] + d) % 4294967296
h[5] = (h[5] + e) % 4294967296; h[6] = (h[6] + f) % 4294967296
h[7] = (h[7] + g) % 4294967296; h[8] = (h[8] + hh) % 4294967296
end
local out = {}
for i = 1, 8 do out[i] = string.format("%08x", h[i]) end
return table.concat(out)
end
local function sha1(msg)
msg = padBE(tostring(msg))
local h0, h1, h2, h3, h4 = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
local w = {}
for pos = 1, #msg, 64 do
for i = 0, 15 do
local a, b, c, d = msg:byte(pos + i * 4, pos + i * 4 + 3)
w[i] = a * 16777216 + b * 65536 + c * 256 + d
end
for i = 16, 79 do
w[i] = bit32.lrotate(bit32.bxor(w[i - 3], w[i - 8], w[i - 14], w[i - 16]), 1)
end
local a, b, c, d, e = h0, h1, h2, h3, h4
for i = 0, 79 do
local f, k
if i < 20 then f = bit32.bor(bit32.band(b, c), bit32.band(bit32.bnot(b), d)); k = 0x5A827999
elseif i < 40 then f = bit32.bxor(b, c, d); k = 0x6ED9EBA1
elseif i < 60 then f = bit32.bor(bit32.band(b, c), bit32.band(b, d), bit32.band(c, d)); k = 0x8F1BBCDC
else f = bit32.bxor(b, c, d); k = 0xCA62C1D6 end
local temp = (bit32.lrotate(a, 5) + f + e + k + w[i]) % 4294967296
e, d, c, b, a = d, c, bit32.lrotate(b, 30), a, temp
end
h0 = (h0 + a) % 4294967296; h1 = (h1 + b) % 4294967296; h2 = (h2 + c) % 4294967296
h3 = (h3 + d) % 4294967296; h4 = (h4 + e) % 4294967296
end
return string.format("%08x%08x%08x%08x%08x", h0, h1, h2, h3, h4)
end
local MD5K, MD5S = {}, {
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,
}
for i = 0, 63 do MD5K[i] = math.floor(math.abs(math.sin(i + 1)) * 4294967296) end
local function le32(n)
return string.char(n % 256, bit32.rshift(n, 8) % 256, bit32.rshift(n, 16) % 256, bit32.rshift(n, 24) % 256)
end
local function md5(msg)
msg = tostring(msg)
local len = #msg
local bits = len * 8
msg = msg .. "\128" .. string.rep("\0", (55 - len) % 64) .. le32(bits % 4294967296) .. le32(math.floor(bits / 4294967296))
local a0, b0, c0, d0 = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
local M = {}
for pos = 1, #msg, 64 do
for i = 0, 15 do
local a, b, c, d = msg:byte(pos + i * 4, pos + i * 4 + 3)
M[i] = a + b * 256 + c * 65536 + d * 16777216
end
local A, B, C, D = a0, b0, c0, d0
for i = 0, 63 do
local F, g
if i < 16 then F = bit32.bor(bit32.band(B, C), bit32.band(bit32.bnot(B), D)); g = i
elseif i < 32 then F = bit32.bor(bit32.band(D, B), bit32.band(bit32.bnot(D), C)); g = (5 * i + 1) % 16
elseif i < 48 then F = bit32.bxor(B, C, D); g = (3 * i + 5) % 16
else F = bit32.bxor(C, bit32.bor(B, bit32.bnot(D))); g = (7 * i) % 16 end
F = (F + A + MD5K[i] + M[g]) % 4294967296
A, D, C = D, C, B
B = (B + bit32.lrotate(F, MD5S[i + 1])) % 4294967296
end
a0 = (a0 + A) % 4294967296; b0 = (b0 + B) % 4294967296
c0 = (c0 + C) % 4294967296; d0 = (d0 + D) % 4294967296
end
local function leHex(n) return (le32(n):gsub(".", function(ch) return string.format("%02x", ch:byte()) end)) end
return leHex(a0) .. leHex(b0) .. leHex(c0) .. leHex(d0)
end
local IV224 = { 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 }
local function sha224(msg) return sha256(msg, IV224):sub(1, 56) end
local CRCT = {}
for i = 0, 255 do
local c = i
for _ = 1, 8 do
if bit32.band(c, 1) == 1 then c = bit32.bxor(bit32.rshift(c, 1), 0xEDB88320) else c = bit32.rshift(c, 1) end
end
CRCT[i] = c
end
local function crc32(msg)
msg = tostring(msg)
local c = 0xFFFFFFFF
for i = 1, #msg do
c = bit32.bxor(bit32.rshift(c, 8), CRCT[bit32.band(bit32.bxor(c, msg:byte(i)), 0xFF)])
end
return string.format("%08x", bit32.bxor(c, 0xFFFFFFFF))
end
local HASHES = { sha1 = sha1, sha224 = sha224, sha256 = sha256, md5 = md5, crc32 = crc32 }
local function hashFn(data, alg)
alg = tostring(alg or "sha256"):lower():gsub("[%-_]", "")
local h = HASHES[alg]
if not h then error("unsupported hash algorithm: " .. tostring(alg) .. " (sha1, sha224, sha256, md5, crc32)", 2) end
return h(data)
end
local function keystream(key, iv, n)
local out = {}
for i = 0, math.ceil(n / 32) - 1 do out[#out + 1] = unhex(sha256(key .. iv .. be32(i))) end
return table.concat(out):sub(1, n)
end
local function xorStr(a, b)
local out = {}
for i = 1, #a do out[i] = string.char(bit32.bxor(a:byte(i), b:byte(i))) end
return table.concat(out)
end
local function ivOf(iv)
if iv == nil or iv == "" then return randBytes(16) end
iv = tostring(iv)
local d = b64dec(iv)
if #d == 16 then return d end
return iv
end
local function encryptFn(data, key, iv)
if type(data) ~= "string" or key == nil then error("encrypt expects (data, key[, iv, mode])", 2) end
local ivRaw = ivOf(iv)
local ks = keystream(tostring(key), ivRaw, #data)
return b64enc(xorStr(data, ks)), b64enc(ivRaw)
end
local function decryptFn(data, key, iv)
if type(data) ~= "string" or key == nil then error("decrypt expects (data, key, iv[, mode])", 2) end
local raw = b64dec(data)
local ivRaw = ivOf(iv)
return xorStr(raw, keystream(tostring(key), ivRaw, #raw))
end
local function lz4decompress(src, outSize)
src = tostring(src)
local out, o, i, n = {}, 0, 1, #src
while i <= n do
local token = src:byte(i); i = i + 1
local lit = bit32.rshift(token, 4)
if lit == 15 then
repeat local b = src:byte(i); i = i + 1; lit = lit + b until b ~= 255 or i > n
end
for _ = 1, lit do o = o + 1; out[o] = src:byte(i); i = i + 1 end
if i > n then break end
local off = src:byte(i) + src:byte(i + 1) * 256; i = i + 2
if off == 0 or off > o then error("lz4: invalid offset", 2) end
local ml = bit32.band(token, 15)
if ml == 15 then
repeat local b = src:byte(i); i = i + 1; ml = ml + b until b ~= 255 or i > n
end
ml = ml + 4
for _ = 1, ml do o = o + 1; out[o] = out[o - off] end
end
local s = bytesToString(out, o)
if outSize and #s ~= outSize then s = s:sub(1, outSize) end
return s
end
local function lz4compress(src)
src = tostring(src)
local n = #src
local out, o = {}, 0
local function push(b) o = o + 1; out[o] = b end
local function pushLen(v) while v >= 255 do push(255); v = v - 255 end push(v) end
local function emit(litStart, litEnd, off, mlen)
local lit = litEnd - litStart + 1
local tok = math.min(lit, 15) * 16
if mlen then tok = tok + math.min(mlen - 4, 15) end
push(tok)
if lit >= 15 then pushLen(lit - 15) end
for j = litStart, litEnd do push(src:byte(j)) end
if mlen then
push(off % 256); push(math.floor(off / 256))
if mlen - 4 >= 15 then pushLen(mlen - 4 - 15) end
end
end
local ht, anchor, i = {}, 1, 1
local limit = n - 12
while i <= limit do
local key = src:sub(i, i + 3)
local cand = ht[key]
ht[key] = i
if cand and i - cand <= 65535 then
local mlen = 4
while i + mlen <= n - 5 and src:byte(cand + mlen) == src:byte(i + mlen) do mlen = mlen + 1 end
emit(anchor, i - 1, i - cand, mlen)
i = i + mlen
anchor = i
else
i = i + 1
end
end
emit(anchor, n, nil, nil)
return bytesToString(out, o)
end
local VFS = { files = {}, folders = {} }
local function norm(p)
p = tostring(p):gsub("\\", "/")
p = p:gsub("^%./", "")
p = p:gsub("/+$", "")
if p == "." then p = "" end
return p
end
local function parentOf(p) return p:match("^(.*)/[^/]*$") end
local function mkParents(p)
local par = parentOf(p)
while par and par ~= "" do
VFS.folders[par] = true
par = parentOf(par)
end
end
local vfs = {}
function vfs.writefile(path, data) path = norm(path); mkParents(path); VFS.files[path] = tostring(data) end
function vfs.readfile(path)
path = norm(path)
local d = VFS.files[path]
if d == nil then error("file does not exist: " .. path, 2) end
return d
end
function vfs.isfile(path) return VFS.files[norm(path)] ~= nil end
function vfs.isfolder(path) path = norm(path); return path == "" or VFS.folders[path] == true end
function vfs.makefolder(path) path = norm(path); mkParents(path); VFS.folders[path] = true end
function vfs.delfile(path)
path = norm(path)
if VFS.files[path] == nil then error("file does not exist: " .. path, 2) end
VFS.files[path] = nil
end
function vfs.delfolder(path)
path = norm(path)
VFS.folders[path] = nil
local pre = path .. "/"
for k in pairs(VFS.files) do if k:sub(1, #pre) == pre then VFS.files[k] = nil end end
for k in pairs(VFS.folders) do if k:sub(1, #pre) == pre then VFS.folders[k] = nil end end
end
function vfs.listfiles(path)
path = norm(path)
if path ~= "" and not VFS.folders[path] then error("folder does not exist: " .. path, 2) end
local out = {}
local function consider(k)
local par = parentOf(k)
if (par == path) or (path == "" and par == nil) then out[#out + 1] = k end
end
for k in pairs(VFS.files) do consider(k) end
for k in pairs(VFS.folders) do consider(k) end
table.sort(out)
return out
end
def("loadstring", "Core", nil, function(f)
local fn = f("return 21 * 2")
expect(type(fn) == "function", "no chunk returned")
expect(fn() == 42, "wrong result")
local bad, err = f("this is not lua")
expect(bad == nil and type(err) == "string", "syntax error not reported")
end)
def("getgenv", "Environment", function() return function() return ENV end end, function(f)
local g = f()
expect(type(g) == "table", "not a table")
g.__hxProbe = 1
expect(f().__hxProbe == 1, "writes are not persistent")
g.__hxProbe = nil
end)
local RENV_NAMES = { "print", "warn", "error", "assert", "pcall", "xpcall", "type", "typeof", "tostring", "tonumber",
"pairs", "ipairs", "next", "select", "unpack", "rawget", "rawset", "rawequal", "rawlen", "setmetatable",
"getmetatable", "require", "tick", "time", "wait", "spawn", "delay", "task", "game", "workspace", "Instance",
"Vector3", "Vector2", "CFrame", "Color3", "UDim2", "UDim", "Enum", "table", "string", "math", "coroutine",
"os", "debug", "utf8", "bit32", "buffer", "shared" }
def("getrenv", "Environment", function()
return function()
local t = {}
for _, n in ipairs(RENV_NAMES) do t[n] = grab(n) end
t._G = ROOT_G
return t
end
end, function(f)
local r = f()
expect(type(r) == "table", "not a table")
expect(type(r.print) == "function", "print missing")
expect(r.game ~= nil, "game missing")
end, "snapshot of standard globals (not the live game env)")
def("identifyexecutor", "Environment", function()
return function() return (EXECUTOR_NAME ~= "Unknown") and EXECUTOR_NAME or BRAND.name, BRAND.ver end
end, function(f)
local n = f()
expect(type(n) == "string" and n ~= "", "no name")
end, "reports host name")
alias("getexecutorname", "identifyexecutor", "Environment")
def("gethui", "Environment", function()
return function()
local ok, ui = pcall(function() return CoreGui end)
return ok and ui or game:GetService("CoreGui")
end
end, function(f) expect(typeof(f()) == "Instance", "not an Instance") end, "returns CoreGui")
def("isluau", "Environment", function() return function() return true end end,
function(f) expect(f() == true, "should be true") end)
def("isrbxactive", "Input", function() return function() return appActive end end,
function(f) expect(type(f()) == "boolean", "not a boolean") end, "tracks window focus")
alias("isgameactive", "isrbxactive", "Input")
def("getthreadidentity", "Environment", function() return function() return identity end end,
function(f) expect(type(f()) == "number", "not a number") end,
"emulated value (does not change real identity)")
def("setthreadidentity", "Environment", function()
return function(n)
n = tonumber(n)
if not n or n < 0 or n > 8 then error("identity must be a number between 0 and 8", 2) end
identity = math.floor(n)
end
end, function(f)
need("getthreadidentity")
local old = resolved.getthreadidentity()
f(2)
local ok = resolved.getthreadidentity() == 2
f(old)
expect(ok, "identity did not change")
end, "emulated value (does not change real identity)")
alias("getidentity", "getthreadidentity", "Environment")
alias("setidentity", "setthreadidentity", "Environment")
natives("Environment", { "getcustomasset", "saveinstance", "queue_on_teleport", "setfpscap", "getfpscap",
"getactors", "run_on_actor", "setclipboard", "getreg", "getgc", "getsenv" })
alias("toclipboard", "setclipboard", "Clipboard")
def("getinstances", "Instances", function()
return function() return game:GetDescendants() end
end, function(f)
local t = f()
expect(type(t) == "table" and #t > 0, "empty result")
expect(typeof(t[1]) == "Instance", "non-Instance in result")
end, "game:GetDescendants() (cannot see nil-parented instances)")
local function scriptsOf(pred)
return function()
local out = {}
for _, i in ipairs(game:GetDescendants()) do if pred(i) then out[#out + 1] = i end end
return out
end
end
def("getscripts", "Scripts", function()
return scriptsOf(function(i) return i:IsA("LocalScript") or i:IsA("ModuleScript") end)
end, function(f)
local t = f()
expect(type(t) == "table", "not a table")
if t[1] then expect(t[1]:IsA("LuaSourceContainer"), "non-script in result") end
end, "scans game descendants")
def("getloadedmodules", "Scripts", function()
return scriptsOf(function(i) return i:IsA("ModuleScript") end)
end, function(f)
local t = f()
expect(type(t) == "table", "not a table")
if t[1] then expect(t[1]:IsA("ModuleScript"), "non-module in result") end
end, "all ModuleScripts (not only loaded)")
def("getrunningscripts", "Scripts", function()
return scriptsOf(function(i) return i:IsA("LocalScript") and not i.Disabled end)
end, function(f)
local t = f()
expect(type(t) == "table", "not a table")
for i = 1, math.min(#t, 50) do
local v = t[i]
expect(typeof(v) == "Instance" and (v:IsA("LocalScript") or v:IsA("ModuleScript") or v:IsA("Script")),
"non-script in result")
end
end, "enabled LocalScripts (not only currently running)")
def("getcallingscript", "Scripts", function()
return function()
for lvl = 2, 6 do
local ok, env = pcall(getfenv, lvl)
if ok and type(env) == "table" then
local s = rawget(env, "script")
if typeof(s) == "Instance" then return s end
end
end
return nil
end
end, function(f)
local s = f()
expect(s == nil or typeof(s) == "Instance", "must be nil or an Instance")
end, "inspects caller environments via getfenv")
natives("Scripts", { "getscriptclosure", "getscriptbytecode", "getscripthash", "decompile", "getfunctionhash" })
natives("Instances", { "getnilinstances", "getconnections", "firesignal", "setscriptable", "fireclickdetector",
"fireproximityprompt", "firetouchinterest", "getcallbackvalue", "setrbxclipboard" })
natives("Cache", { "cache.replace" })
Compat.cacheGone = setmetatable({}, { __mode = "k" })
def("cache.iscached", "Cache", function()
return function(inst)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
return Compat.cacheGone[inst] ~= true
end
end, function(f)
local p = Instance.new("Part")
p.Parent = workspace
local v = f(p)
p:Destroy()
expect(v == true, "fresh instance not cached")
end, "emulated instance cache")
def("cache.invalidate", "Cache", function()
return function(inst)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
Compat.cacheGone[inst] = true
end
end, function(f)
need("cache.iscached")
local p = Instance.new("Part")
p.Parent = workspace
f(p)
local v = resolved["cache.iscached"](p)
p:Destroy()
expect(v == false, "instance still cached")
end, "emulated instance cache")
Compat.mb = { active = nil }
def("messagebox", "Environment", function()
return function(text, caption, flags)
flags = tonumber(flags) or 0
local kind = flags % 16
local btns
if kind == 1 then btns = { { "OK", 1 }, { "Cancel", 2 } }
elseif kind == 2 then btns = { { "Abort", 3 }, { "Retry", 4 }, { "Ignore", 5 } }
elseif kind == 3 then btns = { { "Yes", 6 }, { "No", 7 }, { "Cancel", 2 } }
elseif kind == 4 then btns = { { "Yes", 6 }, { "No", 7 } }
elseif kind == 5 then btns = { { "Retry", 4 }, { "Cancel", 2 } }
else btns = { { "OK", 1 } } end
local gui = Instance.new("ScreenGui")
gui.Name = "HyundaxIUMMessageBox"
gui.IgnoreGuiInset = true
gui.ResetOnSpawn = false
gui.DisplayOrder = 2147483646
local okp = pcall(function() gui.Parent = CoreGui end)
if not okp or not gui.Parent then
local gh = grab("gethui")
local okh = pcall(function() gui.Parent = (type(gh) == "function") and gh() or CoreGui end)
if not okh or not gui.Parent then
pcall(function() gui.Parent = game:GetService("Players").LocalPlayer:WaitForChild("PlayerGui", 3) end)
end
end
local shade = Instance.new("Frame")
shade.Size = UDim2.new(1, 0, 1, 0)
shade.BackgroundColor3 = Color3.new(0, 0, 0)
shade.BackgroundTransparency = 0.5
shade.BorderSizePixel = 0
shade.Active = true
shade.Parent = gui
local box = Instance.new("Frame")
box.AnchorPoint = Vector2.new(0.5, 0.5)
box.Position = UDim2.new(0.5, 0, 0.5, 0)
box.Size = UDim2.new(0, 320, 0, 150)
box.BackgroundColor3 = Color3.fromRGB(28, 28, 28)
box.BorderSizePixel = 0
box.Parent = shade
local cap = Instance.new("TextLabel")
cap.BackgroundColor3 = Color3.fromRGB(40, 40, 40)
cap.BorderSizePixel = 0
cap.Size = UDim2.new(1, 0, 0, 26)
cap.Font = Enum.Font.SourceSansBold
cap.TextSize = 16
cap.TextColor3 = Color3.fromRGB(230, 230, 230)
cap.Text = " " .. tostring(caption or BRAND.name)
cap.TextXAlignment = Enum.TextXAlignment.Left
cap.Parent = box
local msg = Instance.new("TextLabel")
msg.BackgroundTransparency = 1
msg.Position = UDim2.new(0, 12, 0, 34)
msg.Size = UDim2.new(1, -24, 1, -84)
msg.Font = Enum.Font.SourceSans
msg.TextSize = 16
msg.TextWrapped = true
msg.TextXAlignment = Enum.TextXAlignment.Left
msg.TextYAlignment = Enum.TextYAlignment.Top
msg.TextColor3 = Color3.fromRGB(220, 220, 220)
msg.Text = tostring(text)
msg.Parent = box
local result
local function close(n)
if result ~= nil then return end
result = n
pcall(function() gui:Destroy() end)
end
local bw = 80
local total = #btns * bw + (#btns - 1) * 8
for i, b in ipairs(btns) do
local btn = Instance.new("TextButton")
btn.AnchorPoint = Vector2.new(0, 1)
btn.Position = UDim2.new(0.5, -total / 2 + (i - 1) * (bw + 8), 1, -10)
btn.Size = UDim2.new(0, bw, 0, 28)
btn.BackgroundColor3 = Color3.fromRGB(48, 48, 48)
btn.BorderSizePixel = 0
btn.Font = Enum.Font.SourceSansBold
btn.TextSize = 16
btn.TextColor3 = Color3.new(1, 1, 1)
btn.Text = b[1]
btn.Parent = box
btn.Activated:Connect(function() close(b[2]) end)
end
Compat.mb.active = { close = close }
while result == nil do
if not gui.Parent then result = 1; break end
task.wait()
end
Compat.mb.active = nil
return result
end
end, nil, "emulated dialog")
def("cloneref", "Instances", function()
return function(inst)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
return inst
end
end, function(f)
local c = f(game)
expect(typeof(c) == "Instance" and c.Name == game.Name, "reference unusable")
expect(c ~= game, "returned the same reference (cannot create distinct references in pure Luau)")
end, "returns the SAME reference (Luau cannot mint a distinct one)")
def("compareinstances", "Instances", function()
return function(a, b)
if typeof(a) ~= "Instance" or typeof(b) ~= "Instance" then error("Instance expected", 2) end
return a == b
end
end, function(f)
expect(f(game, game) == true, "same instance not equal")
expect(f(game, workspace) == false, "different instances equal")
end)
local function propRead(inst, prop)
local ok, v = pcall(function() return inst[prop] end)
return ok, v
end
def("gethiddenproperty", "Instances", function()
return function(inst, prop)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
local ok, v = propRead(inst, tostring(prop))
if not ok then error("property '" .. tostring(prop) .. "' not accessible", 2) end
return v, false
end
end, function(f)
local p = Instance.new("Part")
local v, hidden = f(p, "Size")
p:Destroy()
expect(typeof(v) == "Vector3", "wrong value type")
expect(hidden == false, "Size reported hidden")
end, "normal properties only (true hidden properties need native)")
def("sethiddenproperty", "Instances", function()
return function(inst, prop, value)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
local ok, err = pcall(function() inst[prop] = value end)
if not ok then error(tostring(err), 2) end
return false
end
end, function(f)
local p = Instance.new("Part")
f(p, "Size", Vector3.new(5, 5, 5))
local ok = p.Size == Vector3.new(5, 5, 5)
p:Destroy()
expect(ok, "property not set")
end, "normal properties only (true hidden properties need native)")
def("isscriptable", "Instances", function()
return function(inst, prop)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
local ok = propRead(inst, tostring(prop))
return ok
end
end, function(f)
local p = Instance.new("Part")
local a = f(p, "Size")
p:Destroy()
expect(a == true, "Size should be scriptable")
end, "readability probe")
local SERVICE_PREFIX = { "Workspace", "ReplicatedStorage", "ReplicatedFirst", "StarterGui", "StarterPack",
"StarterPlayer", "Players", "Lighting", "ServerStorage", "ServerScriptService", "SoundService", "Chat" }
def("checkcaller", "Closures", function() return function() return true end end,
function(f) expect(f() == true, "should be true inside executor code") end,
"always true (cannot tell game threads apart)")
def("newcclosure", "Closures", function()
return function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
local c = function(...) return fn(...) end
wrapped[c] = true
return c
end
end, function(f)
local fn = function(a) return a * 2 end
local c = f(fn)
expect(type(c) == "function", "not a function")
expect(c(21) == 42, "wrong result")
expect(c ~= fn, "same closure returned")
end, "Lua wrapper tracked as C by iscclosure")
def("iscclosure", "Closures", function()
return function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
if wrapped[fn] then return true end
local ok, s = pcall(debug.info, fn, "s")
return ok and s == "[C]"
end
end, function(f)
expect(f(print) == true, "print should be C")
expect(f(function() end) == false, "Lua function reported as C")
need("newcclosure")
expect(f(resolved.newcclosure(function() end)) == true, "newcclosure result not C")
end, "debug.info based + wrapper tracking")
def("islclosure", "Closures", function(r)
return function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
return not r("iscclosure")(fn)
end
end, function(f)
expect(f(function() end) == true, "Lua function not detected")
expect(f(print) == false, "print reported as Lua")
end)
def("clonefunction", "Closures", function(r)
return function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
local c = function(...) return fn(...) end
local isc = r("iscclosure")
if isc and isc(fn) then wrapped[c] = true end
return c
end
end, function(f)
local fn = function() return 7 end
local c = f(fn)
expect(c ~= fn, "same closure returned")
expect(c() == 7, "clone returns wrong value")
end, "wrapper (shares upvalues, not a bytecode clone)")
def("isexecutorclosure", "Closures", function(r)
return function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
if wrapped[fn] then return true end
local ok, src = pcall(debug.info, fn, "s")
if not ok or src == nil or src == "[C]" then return false end
for _, p in ipairs(SERVICE_PREFIX) do
if src:sub(1, #p) == p then return false end
end
return true
end
end, function(f)
expect(f(function() end) == true, "own closure not detected")
expect(f(print) == false, "print reported as executor closure")
end, "heuristic: chunk name is not a game script path")
alias("checkclosure", "isexecutorclosure", "Closures")
alias("isourclosure", "isexecutorclosure", "Closures")
def("hookmetamethod", "Closures", function()
return function(obj, method, hook)
if type(method) ~= "string" or type(hook) ~= "function" then error("hookmetamethod(obj, name, fn)", 2) end
local mt = getmetatable(obj)
if type(mt) ~= "table" then error("object has no accessible metatable", 2) end
local old = rawget(mt, method)
local ok, err = pcall(function() mt[method] = hook end)
if not ok then error("metatable is locked: " .. tostring(err), 2) end
return old
end
end, function(f)
local obj = setmetatable({}, { __index = function() return "orig" end })
local old = f(obj, "__index", function() return "hooked" end)
local hooked = obj.x == "hooked"
f(obj, "__index", old)
expect(hooked, "metamethod not hooked")
end, "plain tables with unlocked metatables only (not Instances/game)")
natives("Closures", { "hookfunction", "restorefunction", "getnamecallmethod", "setnamecallmethod" })
def("getrawmetatable", "Metatable", function()
return function(t)
local mt = getmetatable(t)
if type(mt) == "table" then return mt end
return nil
end
end, function(f)
local mt = { __index = function() return 1 end }
expect(f(setmetatable({}, mt)) == mt, "wrong metatable")
end, "standard getmetatable only; cannot bypass __metatable locks")
def("setrawmetatable", "Metatable", function()
return function(t, mt) setmetatable(t, mt); return t end
end, function(f)
local t, mt = {}, {}
f(t, mt)
expect(getmetatable(t) == mt, "metatable not set")
end, "standard setmetatable only; cannot bypass __metatable locks")
def("isreadonly", "Metatable", function()
return function(t)
if type(t) ~= "table" then error("table expected", 2) end
return table.isfrozen(t)
end
end, function(f)
local t = {}
expect(f(t) == false, "unfrozen reported readonly")
table.freeze(t)
expect(f(t) == true, "frozen not detected")
end, "table.isfrozen")
natives("Metatable", { "setreadonly" })
def("debug.getinfo", "Debug", function()
return function(target, what)
local src, line, name, np, va
if type(target) == "number" then
src, line, name, np, va = debug.info(target + 1, "slnaf")
else
local ok
ok, src, line, name, np, va = pcall(debug.info, target, "slnaf")
if not ok then return nil end
end
if src == nil then return nil end
local isC = (src == "[C]")
return {
source = isC and "=[C]" or ("@" .. tostring(src)), short_src = src,
currentline = line or -1, linedefined = line or -1, lastlinedefined = -1,
name = name, what = isC and "C" or "Lua", numparams = np or 0,
is_vararg = va and 1 or 0, nups = 0, func = (type(target) == "function") and target or nil,
}
end
end, function(f)
local i = f(print)
expect(type(i) == "table", "not a table")
expect(i.what == "C", "print should be C")
local l = f(function() end)
expect(type(l) == "table" and l.what == "Lua", "Lua function misreported")
local lv = f(1)
expect(type(lv) == "table" and type(lv.currentline) == "number", "level lookup failed")
end, "built on debug.info (nups/lastlinedefined unavailable)")
natives("Debug", { "debug.getupvalue", "debug.getupvalues", "debug.setupvalue", "debug.getconstant",
"debug.getconstants", "debug.setconstant", "debug.getproto", "debug.getprotos", "debug.getstack",
"debug.setstack", "debug.getregistry", "debug.getmetatable", "debug.setmetatable" })
local function tmp() return "hxcompat" .. tostring(rng:NextInteger(100000, 999999)) end
local function waitFor(cond, secs)
local t0 = os.clock()
repeat
local ok, v = pcall(cond)
if ok and v then return true end
task.wait(0.05)
until os.clock() - t0 > (secs or 2)
return false
end
local function rm(n) local d = resolved.delfile; if d then pcall(d, n) end end
local function vfsPoly(n)
return function()
if hasNative("writefile") and hasNative("readfile") then return nil end
return vfs[n]
end
end
local fsTests = {
writefile = function(f)
need("readfile")
local n = tmp() .. ".txt"
local okW, errW = pcall(f, n, "hello")
local ok = waitFor(function() return resolved.readfile(n) == "hello" end)
if not ok then
local isf = resolved.isfile and select(2, pcall(resolved.isfile, n))
local okR, rv = pcall(resolved.readfile, n)
local j = tmp() .. ".json"
pcall(f, j, "{}")
local jok = waitFor(function() return resolved.readfile(j) == "{}" end, 1)
rm(j)
rm(n)
error(string.format("write %s%s · isfile=%s · readfile=%s · .json works=%s",
okW and "ok" or "ERR", okW and "" or (" (" .. tostring(errW) .. ")"), tostring(isf),
okR and "ok" or tostring(rv), tostring(jok)), 0)
end
rm(n)
end,
readfile = function(f)
need("writefile")
local n = tmp() .. ".txt"
resolved.writefile(n, "abc")
local ok = waitFor(function() return f(n) == "abc" end)
rm(n)
expect(ok, "content mismatch")
expect(not pcall(f, n .. ".missing"), "missing file did not error")
end,
isfile = function(f)
need("writefile")
local n = tmp() .. ".txt"
expect(f(n) == false, "missing file reported present")
resolved.writefile(n, "x")
local ok = waitFor(function() return f(n) == true end)
rm(n)
expect(ok, "existing file not detected")
end,
delfile = function(f)
need("writefile", "isfile")
local n = tmp() .. ".txt"
resolved.writefile(n, "x")
expect(waitFor(function() return resolved.isfile(n) end), "setup: written file never appeared")
f(n)
expect(waitFor(function() return resolved.isfile(n) == false end), "file still exists")
end,
makefolder = function(f)
need("isfolder", "delfolder")
local d = tmp()
f(d)
local ok = waitFor(function() return resolved.isfolder(d) == true end)
pcall(resolved.delfolder, d)
expect(ok, "folder not created")
end,
isfolder = function(f)
need("makefolder", "delfolder")
local d = tmp()
expect(f(d) == false, "missing folder reported present")
resolved.makefolder(d)
local ok = waitFor(function() return f(d) == true end)
pcall(resolved.delfolder, d)
expect(ok, "existing folder not detected")
end,
delfolder = function(f)
need("makefolder", "isfolder")
local d = tmp()
resolved.makefolder(d)
expect(waitFor(function() return resolved.isfolder(d) == true end), "setup: folder never appeared")
f(d)
expect(waitFor(function() return resolved.isfolder(d) == false end), "folder still exists")
end,
listfiles = function(f)
need("makefolder", "writefile", "delfolder")
local d = tmp()
resolved.makefolder(d)
waitFor(function() return resolved.isfolder(d) == true end)
resolved.writefile(d .. "/a.txt", "x")
local l
local ok = waitFor(function()
l = f(d)
return type(l) == "table" and #l == 1 and tostring(l[1]):find("a.txt", 1, true) ~= nil
end)
pcall(resolved.delfolder, d)
expect(ok, "wrong listing")
end,
}
for _, n in ipairs({ "writefile", "readfile", "isfile", "delfile", "makefolder", "isfolder", "delfolder", "listfiles" }) do
def(n, "Filesystem", vfsPoly(n), fsTests[n], "in-memory FS (fallback when the native FS is missing or does not persist files)")
end
def("appendfile", "Filesystem", function(r)
local rf, wf, isf = r("readfile"), r("writefile"), r("isfile")
if not (rf and wf and isf) then return nil end
return function(path, data)
if isf(path) then wf(path, rf(path) .. tostring(data)) else wf(path, tostring(data)) end
end
end, function(f)
need("writefile", "readfile")
local n = tmp() .. ".txt"
resolved.writefile(n, "a")
waitFor(function() return resolved.readfile(n) == "a" end)
f(n, "b")
local ok = waitFor(function() return resolved.readfile(n) == "ab" end)
rm(n)
expect(ok, "append mismatch")
end, "composed from readfile + writefile")
def("loadfile", "Filesystem", function(r)
local rf = r("readfile")
if not (rf and LOADSTRING) then return nil end
return function(path)
local ok, src = pcall(rf, path)
if not ok then return nil, tostring(src) end
return LOADSTRING(src, "=" .. tostring(path))
end
end, function(f)
need("writefile")
local n = tmp() .. ".lua"
resolved.writefile(n, "return 99")
waitFor(function() return resolved.readfile(n) == "return 99" end)
local fn = f(n)
rm(n)
expect(type(fn) == "function" and fn() == 99, "chunk not loaded")
local bad, err = f(n .. ".missing")
expect(bad == nil and type(err) == "string", "missing file not reported")
end, "composed from readfile + loadstring")
def("dofile", "Filesystem", function(r)
local lf = r("loadfile")
if not lf then return nil end
return function(path)
local fn, err = lf(path)
if not fn then error(err, 2) end
return fn()
end
end, function(f)
need("writefile")
local n = tmp() .. ".lua"
resolved.writefile(n, "return 5")
waitFor(function() return resolved.readfile(n) == "return 5" end)
local ok, v = pcall(f, n)
rm(n)
expect(ok and v == 5, "dofile did not return chunk result")
end, "composed from loadfile")
for _, n in ipairs({ "crypt.base64encode", "crypt.base64.encode", "base64_encode", "base64.encode" }) do
def(n, "Crypt", function() return b64enc end, function(f)
expect(f("Hello, World!") == "SGVsbG8sIFdvcmxkIQ==", "wrong encoding")
expect(f("") == "", "empty string failed")
expect(f("f") == "Zg==", "1-byte padding failed")
expect(f("fo") == "Zm8=", "2-byte padding failed")
expect(f("foo") == "Zm9v", "3-byte block failed")
local bytes = {}; for i = 0, 255 do bytes[#bytes + 1] = string.char(i) end
expect(#f(table.concat(bytes)) == 344, "binary payload length mismatch")
end, "pure Luau · RFC 4648 vectors")
end
for _, n in ipairs({ "crypt.base64decode", "crypt.base64.decode", "base64_decode", "base64.decode" }) do
def(n, "Crypt", function() return b64dec end, function(f)
expect(f("SGVsbG8sIFdvcmxkIQ==") == "Hello, World!", "wrong decoding")
expect(f("QQ==") == "A", "1-byte padding failed")
expect(f("Zm8=") == "fo", "2-byte padding failed")
expect(f("Zm9v") == "foo", "unpadded block failed")
local bytes = {}; for i = 0, 255 do bytes[#bytes + 1] = string.char(i) end
local raw = table.concat(bytes)
expect(f(b64enc(raw)) == raw, "binary round-trip failed")
end, "pure Luau · RFC 4648 vectors + binary round-trip")
end
def("crypt.generatebytes", "Crypt", function()
return function(n)
n = math.floor(tonumber(n) or 16)
if n < 0 or n > 1048576 then error("invalid size", 2) end
return b64enc(randBytes(n))
end
end, function(f)
local r = f(16)
expect(type(r) == "string" and #b64dec(r) == 16, "wrong length")
expect(f(16) ~= r, "not random")
end, "Random.new() based (not cryptographically secure)")
def("crypt.generatekey", "Crypt", function() return function() return b64enc(randBytes(32)) end end, function(f)
local r = f()
expect(type(r) == "string" and #b64dec(r) == 32, "key is not 32 bytes")
end, "Random.new() based (not cryptographically secure)")
def("crypt.hash", "Crypt", function() return hashFn end, function(f)
expect(f("test", "sha256"):lower() == "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "wrong sha256")
expect(f("test", "sha1"):lower() == "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "wrong sha1")
expect(f("test", "md5"):lower() == "098f6bcd4621d373cade4e832627b4f6", "wrong md5")
expect(f("", "sha256"):lower() == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "wrong empty sha256")
local ok1, h1 = pcall(f, "abc", "sha224")
if ok1 and type(h1) == "string" then
expect(h1:lower() == "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7", "wrong sha224")
end
local ok2, h2 = pcall(f, "123456789", "crc32")
if ok2 and type(h2) == "string" then
expect(h2:lower():gsub("^0+", "") == "cbf43926", "wrong crc32")
end
end, "pure Luau sha1/sha224/sha256/md5/crc32 (no sha384/sha512)")
def("crypt.encrypt", "Crypt", function() return encryptFn end, function(f)
local key = b64enc(randBytes(32))
local enc, iv = f("secret data", key, nil, "CBC")
expect(type(enc) == "string" and type(iv) == "string", "must return (encrypted, iv)")
need("crypt.decrypt")
expect(resolved["crypt.decrypt"](enc, key, iv, "CBC") == "secret data", "round trip failed")
end, "SHA-256 CTR stream cipher (round-trips, NOT AES-compatible)")
def("crypt.decrypt", "Crypt", function() return decryptFn end, function(f)
need("crypt.encrypt")
local key = b64enc(randBytes(32))
local enc, iv = resolved["crypt.encrypt"]("hello", key, nil, "CBC")
expect(f(enc, key, iv, "CBC") == "hello", "round trip failed")
end, "SHA-256 CTR stream cipher (round-trips, NOT AES-compatible)")
def("lz4compress", "Crypt", function() return lz4compress end, function(f)
need("lz4decompress")
local d = string.rep("abcdefgh", 64) .. "tail-data-123456"
local c = f(d)
expect(type(c) == "string", "not a string")
expect(resolved.lz4decompress(c, #d) == d, "round trip failed")
end, "real LZ4 block compressor")
def("lz4decompress", "Crypt", function() return lz4decompress end, function(f)
need("lz4compress")
local d = string.rep("a", 200) .. "xyz"
expect(f(resolved.lz4compress(d), #d) == d, "round trip failed")
end, "real LZ4 block decompressor")
local function mul32(a, b)
a, b = a % 4294967296, b % 4294967296
local ah, al = math.floor(a / 65536), a % 65536
return ((ah * b) % 65536 * 65536 + al * b) % 4294967296
end
local function bswap32(a)
a = a % 4294967296
return sgn(bit32.bor(bit32.lshift(a % 256, 24), bit32.lshift(bit32.rshift(a, 8) % 256, 16),
bit32.lshift(bit32.rshift(a, 16) % 256, 8), bit32.rshift(a, 24) % 256))
end
local bitDefs = {
{ "band", function(a, b) return sgn(bit32.band(a, b)) end, { 0xF0, 0x3C }, 0x30 },
{ "bor", function(a, b) return sgn(bit32.bor(a, b)) end, { 0xF0, 0x0F }, 0xFF },
{ "bxor", function(a, b) return sgn(bit32.bxor(a, b)) end, { 0xFF, 0x0F }, 0xF0 },
{ "bnot", function(a) return sgn(bit32.bnot(a)) end, { 0 }, -1 },
{ "lshift", function(a, b) return sgn(bit32.lshift(a, b)) end, { 1, 4 }, 16 },
{ "rshift", function(a, b) return sgn(bit32.rshift(a, b)) end, { 16, 4 }, 1 },
{ "arshift", function(a, b) return sgn(bit32.arshift(a, b)) end, { -16, 2 }, -4 },
{ "rol", function(a, b) return sgn(bit32.lrotate(a, b)) end, { 1, 31 }, -2147483648 },
{ "ror", function(a, b) return sgn(bit32.rrotate(a, b)) end, { 1, 1 }, -2147483648 },
{ "tobit", function(a) return sgn(a) end, { 0xFFFFFFFF }, -1 },
{ "tohex", function(a, n)
n = n or 8
local s = string.format("%08x", a % 4294967296)
return s:sub(-n)
end, { 255, 4 }, "00ff" },
{ "badd", function(a, b) return sgn(a + b) end, { 1, 2 }, 3 },
{ "bsub", function(a, b) return sgn(a - b) end, { 5, 3 }, 2 },
{ "bmul", function(a, b) return sgn(mul32(a, b)) end, { 3, 7 }, 21 },
{ "bdiv", function(a, b) return sgn(math.floor((a % 4294967296) / (b % 4294967296))) end, { 20, 4 }, 5 },
{ "bswap", bswap32, { 0x11223344 }, 0x44332211 },
{ "btest", function(a, b) return bit32.btest(a, b) end, { 6, 2 }, true },
}
for _, d in ipairs(bitDefs) do
local bs = def("bit." .. d[1], "Bit", function() return d[2] end, function(f)
local r = f(table.unpack(d[3]))
if d[1] == "tohex" then
expect(type(r) == "string" and r:lower():gsub("^0+", "") == "ff", "expected hex ff, got " .. tostring(r))
return
end
expect(r == d[4], "expected " .. tostring(d[4]) .. ", got " .. tostring(r))
end, "bit32 based")
if d[1] == "bsub" or d[1] == "bmul" or d[1] == "bdiv" then bs.force = true end
end
def("request", "Network", function()
return function(opts)
if type(opts) ~= "table" or type(opts.Url) ~= "string" then error("request expects a table with a string Url", 2) end
local method = tostring(opts.Method or "GET"):upper()
local ok, res = pcall(function()
return HttpService:RequestAsync({ Url = opts.Url, Method = method, Headers = opts.Headers, Body = opts.Body })
end)
if ok and type(res) == "table" then
return { Success = res.Success, StatusCode = res.StatusCode, StatusMessage = res.StatusMessage,
Headers = res.Headers or {}, Body = res.Body or "" }
end
if method == "GET" then
local ok2, body = pcall(function() return game:HttpGet(opts.Url) end)
if ok2 then
return { Success = true, StatusCode = 200, StatusMessage = "OK", Headers = {}, Body = body }
end
res = body
end
return { Success = false, StatusCode = 0, StatusMessage = tostring(res), Headers = {}, Body = "" }
end
end, function(f)
expect(not pcall(f), "no error on missing args")
local bad, badErr = pcall(f, { Url = 123, Method = "GET" })
expect(not bad and tostring(badErr):find("Url", 1, true) ~= nil, "invalid URL was not rejected")
for _, m in ipairs({ "GET", "POST" }) do
local r = f({ Url = "https://example.invalid", Method = m })
expect(type(r) == "table", m .. ": response is not a table")
expect(type(r.Success) == "boolean", m .. ": Success must be boolean")
expect(type(r.StatusCode) == "number", m .. ": StatusCode must be numeric")
expect(type(r.Headers) == "table", m .. ": Headers must be a table")
expect(type(r.Body) == "string", m .. ": Body must be a string")
end
end, "HttpService:RequestAsync, falls back to HttpGet; live network test excluded")
alias("http_request", "request", "Network")
alias("http.request", "request", "Network")
natives("Network", { "WebSocket.connect" })
local VIM
local function vim()
if VIM == nil then
local ok, s = pcall(function() return game:GetService("VirtualInputManager") end)
VIM = (ok and s) or false
end
return VIM or nil
end
local function needVim()
local v = vim()
if not v then error("VirtualInputManager unavailable", 3) end
return v
end
local function mouseBtn(btn, down, up)
return function(x, y)
local v = needVim()
local pos = UserInputSvc:GetMouseLocation()
x, y = tonumber(x) or pos.X, tonumber(y) or pos.Y
if down then v:SendMouseButtonEvent(x, y, btn, true, game, 1) end
if up then v:SendMouseButtonEvent(x, y, btn, false, game, 1) end
end
end
local function toKey(code)
if typeof(code) == "EnumItem" then return code end
if type(code) == "number" then
for _, k in ipairs(Enum.KeyCode:GetEnumItems()) do
if k.Value == code then return k end
end
end
if type(code) == "string" and Enum.KeyCode[code] then return Enum.KeyCode[code] end
error("invalid key code", 3)
end
local inputTest = function(f)
expect(type(f) == "function", "not a function")
expect(vim() ~= nil, "VirtualInputManager unavailable")
end
local inputDefs = {
{ "mouse1click", mouseBtn(0, true, true) }, { "mouse1press", mouseBtn(0, true, false) },
{ "mouse1release", mouseBtn(0, false, true) }, { "mouse2click", mouseBtn(1, true, true) },
{ "mouse2press", mouseBtn(1, true, false) }, { "mouse2release", mouseBtn(1, false, true) },
{ "mousemoveabs", function(x, y) needVim():SendMouseMoveEvent(tonumber(x) or 0, tonumber(y) or 0, game) end },
{ "mousemoverel", function(dx, dy)
local p = UserInputSvc:GetMouseLocation()
needVim():SendMouseMoveEvent(p.X + (tonumber(dx) or 0), p.Y + (tonumber(dy) or 0), game)
end },
{ "mousescroll", function(px)
local p = UserInputSvc:GetMouseLocation()
needVim():SendMouseWheelEvent(p.X, p.Y, (tonumber(px) or 0) > 0, game)
end },
{ "keypress", function(code) needVim():SendKeyEvent(true, toKey(code), false, game) end },
{ "keyrelease", function(code) needVim():SendKeyEvent(false, toKey(code), false, game) end },
}
for _, d in ipairs(inputDefs) do
local fn = d[2]
def(d[1], "Input", function() if vim() then return fn end return nil end, inputTest,
"VirtualInputManager (behavior not exercised to avoid real input)")
end
local drawGui
local drawObjs = {}
local renderObjs = setmetatable({}, { __mode = "k" })
local function getDrawGui()
if drawGui and drawGui.Parent then return drawGui end
drawGui = Instance.new("ScreenGui")
drawGui.Name = "HyundaxIUMDrawing"
drawGui.IgnoreGuiInset = true
drawGui.ResetOnSpawn = false
drawGui.DisplayOrder = 2147483647
drawGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
local ok = pcall(function() drawGui.Parent = CoreGui end)
if not ok then
local gh = grab("gethui")
pcall(function() drawGui.Parent = (type(gh) == "function") and gh() or CoreGui end)
end
return drawGui
end
local DRAW_FONTS = { [0] = Enum.Font.Arial, [1] = Enum.Font.SourceSans, [2] = Enum.Font.Code, [3] = Enum.Font.RobotoMono }
local function drawDefaults(kind)
local st = {
Visible = false, Color = Color3.new(1, 1, 1), Transparency = 1, ZIndex = 0, Thickness = 1,
Filled = false, Position = Vector2.new(), Size = Vector2.new(), From = Vector2.new(), To = Vector2.new(),
Radius = 0, NumSides = 0, Text = "", Font = 0, Center = false, Outline = false,
OutlineColor = Color3.new(), PointA = Vector2.new(), PointB = Vector2.new(), PointC = Vector2.new(),
PointD = Vector2.new(), Rounding = 0, Data = "", Transparency_ = 1,
}
if kind == "Text" then st.Size = 13 end
return st
end
local PROP_ALLOWED = {
Line = { "Visible", "Color", "Transparency", "ZIndex", "Thickness", "From", "To" },
Square = { "Visible", "Color", "Transparency", "ZIndex", "Thickness", "Filled", "Position", "Size" },
Circle = { "Visible", "Color", "Transparency", "ZIndex", "Thickness", "Filled", "Position", "Radius", "NumSides" },
Text = { "Visible", "Color", "Transparency", "ZIndex", "Text", "Size", "Font", "Center", "Outline", "OutlineColor", "Position", "TextBounds" },
Triangle = { "Visible", "Color", "Transparency", "ZIndex", "Thickness", "Filled", "PointA", "PointB", "PointC" },
Quad = { "Visible", "Color", "Transparency", "ZIndex", "Thickness", "Filled", "PointA", "PointB", "PointC", "PointD" },
Image = { "Visible", "Color", "Transparency", "ZIndex", "Position", "Size", "Rounding", "Data" },
}
local function newDrawing(kind)
if type(kind) ~= "string" or not PROP_ALLOWED[kind] then
error("invalid drawing type: " .. tostring(kind), 2)
end
local st = drawDefaults(kind)
local allowed = {}
for _, k in ipairs(PROP_ALLOWED[kind]) do allowed[k] = true end
local gui = getDrawGui()
local root = Instance.new("Frame")
root.Name = kind
root.BackgroundTransparency = 1
root.BorderSizePixel = 0
root.Size = UDim2.fromScale(1, 1)
root.Visible = false
root.Parent = gui
local pool = {}
local removed = false
local textLabel, imageLabel, shape, stroke, corner
local function line(idx, a, b)
local fr = pool[idx]
if not fr then
fr = Instance.new("Frame")
fr.BorderSizePixel = 0
fr.AnchorPoint = Vector2.new(0.5, 0.5)
fr.Parent = root
pool[idx] = fr
end
local d = b - a
fr.Visible = true
fr.BackgroundColor3 = st.Color
fr.BackgroundTransparency = 1 - st.Transparency
fr.Size = UDim2.fromOffset(d.Magnitude, math.max(st.Thickness, 1))
fr.Position = UDim2.fromOffset((a.X + b.X) / 2, (a.Y + b.Y) / 2)
fr.Rotation = math.deg(math.atan2(d.Y, d.X))
fr.ZIndex = st.ZIndex
end
local function hideFrom(idx)
for i = idx, #pool do if pool[i] then pool[i].Visible = false end end
end
local function render()
if removed then return end
root.Visible = st.Visible and true or false
root.ZIndex = st.ZIndex
if kind == "Line" then
line(1, st.From, st.To); hideFrom(2)
elseif kind == "Triangle" then
line(1, st.PointA, st.PointB); line(2, st.PointB, st.PointC); line(3, st.PointC, st.PointA); hideFrom(4)
elseif kind == "Quad" then
line(1, st.PointA, st.PointB); line(2, st.PointB, st.PointC)
line(3, st.PointC, st.PointD); line(4, st.PointD, st.PointA); hideFrom(5)
elseif kind == "Square" or kind == "Circle" then
if not shape then
shape = Instance.new("Frame")
shape.BorderSizePixel = 0
shape.Parent = root
stroke = Instance.new("UIStroke"); stroke.Parent = shape
if kind == "Circle" then
corner = Instance.new("UICorner"); corner.CornerRadius = UDim.new(1, 0); corner.Parent = shape
end
end
if kind == "Square" then
shape.AnchorPoint = Vector2.new(0, 0)
shape.Position = UDim2.fromOffset(st.Position.X, st.Position.Y)
shape.Size = UDim2.fromOffset(st.Size.X, st.Size.Y)
else
shape.AnchorPoint = Vector2.new(0.5, 0.5)
shape.Position = UDim2.fromOffset(st.Position.X, st.Position.Y)
shape.Size = UDim2.fromOffset(st.Radius * 2, st.Radius * 2)
end
shape.ZIndex = st.ZIndex
shape.BackgroundColor3 = st.Color
shape.BackgroundTransparency = st.Filled and (1 - st.Transparency) or 1
stroke.Enabled = not st.Filled
stroke.Color = st.Color
stroke.Thickness = st.Thickness
stroke.Transparency = 1 - st.Transparency
elseif kind == "Text" then
if not textLabel then
textLabel = Instance.new("TextLabel")
textLabel.BackgroundTransparency = 1
textLabel.AutomaticSize = Enum.AutomaticSize.XY
textLabel.Parent = root
end
textLabel.Text = tostring(st.Text)
textLabel.TextSize = tonumber(st.Size) or 13
textLabel.Font = DRAW_FONTS[st.Font] or Enum.Font.Arial
textLabel.TextColor3 = st.Color
textLabel.TextTransparency = 1 - st.Transparency
textLabel.TextStrokeColor3 = st.OutlineColor
textLabel.TextStrokeTransparency = st.Outline and 0 or 1
textLabel.AnchorPoint = Vector2.new(st.Center and 0.5 or 0, 0)
textLabel.Position = UDim2.fromOffset(st.Position.X, st.Position.Y)
textLabel.ZIndex = st.ZIndex
elseif kind == "Image" then
if not imageLabel then
imageLabel = Instance.new("ImageLabel")
imageLabel.BackgroundTransparency = 1
imageLabel.BorderSizePixel = 0
imageLabel.Parent = root
corner = Instance.new("UICorner"); corner.Parent = imageLabel
end
imageLabel.Position = UDim2.fromOffset(st.Position.X, st.Position.Y)
imageLabel.Size = UDim2.fromOffset(st.Size.X, st.Size.Y)
imageLabel.ImageColor3 = st.Color
imageLabel.ImageTransparency = 1 - st.Transparency
imageLabel.ZIndex = st.ZIndex
corner.CornerRadius = UDim.new(0, st.Rounding)
if type(st.Data) == "string" and st.Data:find("^rbxasset") then imageLabel.Image = st.Data end
end
end
local function remove()
if removed then return end
removed = true
drawObjs[st] = nil
pcall(function() root:Destroy() end)
end
local proxy = setmetatable({}, {
__index = function(_, k)
if k == "Remove" or k == "Destroy" then return remove end
if k == "TextBounds" and textLabel then return Vector2.new(textLabel.TextBounds.X, textLabel.TextBounds.Y) end
if allowed[k] then return st[k] end
return nil
end,
__newindex = function(_, k, v)
if removed then error("drawing object has been removed", 2) end
if not allowed[k] or k == "TextBounds" then error("invalid drawing property: " .. tostring(k), 2) end
st[k] = v
render()
end,
})
drawObjs[st] = remove
renderObjs[proxy] = true
render()
return proxy
end
def("Drawing.new", "Drawing", function() return newDrawing end, function(f)
local sq = f("Square")
expect(type(sq) == "table" or typeof(sq) == "userdata", "bad object")
sq.Size = Vector2.new(10, 10)
sq.Visible = true
local okProps = sq.Visible == true and sq.Size == Vector2.new(10, 10)
sq.Visible = false
sq:Remove()
expect(okProps, "property round trip failed")
end, "ScreenGui-backed (Image Data needs rbxasset ids)")
def("Drawing.Fonts", "Drawing", function()
return { UI = 0, System = 1, Plex = 2, Monospace = 3 }
end, function(f)
expect(type(f) == "table" and f.UI == 0 and f.Monospace == 3, "bad font table")
end, "font enum table").value = true
def("cleardrawcache", "Drawing", function()
return function()
local list = {}
for _, rm2 in pairs(drawObjs) do list[#list + 1] = rm2 end
for _, rm2 in ipairs(list) do rm2() end
if drawGui then pcall(function() drawGui:ClearAllChildren() end) end
end
end, function(f)
need("Drawing.new")
resolved["Drawing.new"]("Line")
expect(pcall(f), "cleardrawcache errored")
end)
def("isrenderobj", "Drawing", function()
return function(o) return renderObjs[o] == true end
end, function(f)
need("Drawing.new")
local o = resolved["Drawing.new"]("Circle")
local ok = f(o) == true
o.Visible = false
o:Remove()
expect(ok, "drawing not recognised")
end)
def("getrenderproperty", "Drawing", function()
return function(o, k)
if renderObjs[o] ~= true then error("render object expected", 2) end
return o[k]
end
end, function(f)
need("Drawing.new")
local o = resolved["Drawing.new"]("Square")
o.Thickness = 3
local ok = f(o, "Thickness") == 3
o.Visible = false
o:Remove()
expect(ok, "wrong value")
end)
def("setrenderproperty", "Drawing", function()
return function(o, k, v)
if renderObjs[o] ~= true then error("render object expected", 2) end
o[k] = v
end
end, function(f)
need("Drawing.new")
local o = resolved["Drawing.new"]("Square")
f(o, "Thickness", 4)
local ok = o.Thickness == 4
o.Visible = false
o:Remove()
expect(ok, "property not set")
end)
local function T(name, fn)
local sp = byName[name]
if sp then sp.test = fn end
end
local function skip(why) return "skip:" .. why end
local function existOnly(name)
T(name, function(f) expect(type(f) == "function", "not a function") end)
end
local function probeScript(classes)
local lp = game:GetService("Players").LocalPlayer
local ps = lp and lp:FindFirstChildOfClass("PlayerScripts")
if ps then
for _, d in ipairs(ps:GetDescendants()) do
for _, c in ipairs(classes) do if d:IsA(c) then return d end end
end
end
return nil
end
local function rootPart()
local lp = game:GetService("Players").LocalPlayer
local ch = lp and lp.Character
return ch and ch:FindFirstChild("HumanoidRootPart")
end
T("getgc", function(f)
local t = f()
expect(type(t) == "table" and #t > 0, "empty result")
end)
T("getreg", function(f) expect(type(f()) == "table", "not a table") end)
T("getsenv", function(f)
local cands = {}
local lp = game:GetService("Players").LocalPlayer
local ch = lp and lp.Character
local anim = ch and ch:FindFirstChild("Animate")
if anim then cands[#cands + 1] = anim end
local ps = lp and lp:FindFirstChildOfClass("PlayerScripts")
if ps then
for _, d in ipairs(ps:GetDescendants()) do
if d:IsA("LocalScript") or d:IsA("ModuleScript") then cands[#cands + 1] = d end
end
end
local grs = grab("getrunningscripts")
if type(grs) == "function" then
local okr, list = pcall(grs)
if okr and type(list) == "table" then
for _, d in ipairs(list) do cands[#cands + 1] = d end
end
end
if #cands == 0 then return skip("no script to inspect") end
local passed = false
for ci, sc in ipairs(cands) do
if ci > 4 then break end
local ok, env = pcall(f, sc)
if ok and type(env) == "table" then passed = true; break end
end
expect(passed, "environment is not a table")
end)
T("getscriptclosure", function(f)
local sc = probeScript({ "LocalScript", "ModuleScript" })
if not sc then return skip("no script to inspect") end
expect(type(f(sc)) == "function", "not a function")
end)
T("getscriptbytecode", function(f)
local sc = probeScript({ "LocalScript", "ModuleScript" })
if not sc then return skip("no script to inspect") end
expect(type(f(sc)) == "string", "not a string")
end)
T("getscripthash", function(f)
local sc = probeScript({ "LocalScript", "ModuleScript" })
if not sc then return skip("no script to inspect") end
local h = f(sc)
expect(type(h) == "string" and #h > 0, "empty hash")
expect(f(sc) == h, "hash not stable")
end)
T("decompile", function(f)
local sc = probeScript({ "LocalScript", "ModuleScript" })
if not sc then return skip("no script to inspect") end
expect(type(f(sc)) == "string", "not a string")
end)
T("getfunctionhash", function(f)
local fn = function() return 1 end
local h = f(fn)
expect(type(h) == "string" and #h > 0, "empty hash")
expect(f(fn) == h, "hash not stable")
end)
T("getnilinstances", function(f)
local p = Instance.new("Part")
p.Name = "hx_nil_probe"
p.Parent = workspace
p.Parent = nil
local found = false
for _, i in ipairs(f()) do if i == p then found = true; break end end
p:Destroy()
expect(found, "nil-parented instance not listed")
end)
T("getconnections", function(f)
local be = Instance.new("BindableEvent")
local c = be.Event:Connect(function() end)
local cons = f(be.Event)
c:Disconnect()
be:Destroy()
expect(type(cons) == "table" and #cons >= 1, "connection not listed")
end)
T("firesignal", function(f)
local got
local be = Instance.new("BindableEvent")
local c = be.Event:Connect(function(v) got = v end)
f(be.Event, 5)
waitFor(function() return got == 5 end, 1)
c:Disconnect()
be:Destroy()
expect(got == 5, "signal not fired")
end)
T("setscriptable", function(f)
need("isscriptable")
local fire = Instance.new("Fire")
f(fire, "size_xml", true)
local on = resolved.isscriptable(fire, "size_xml") == true
f(fire, "size_xml", false)
local off = resolved.isscriptable(fire, "size_xml") == false
fire:Destroy()
expect(on, "property did not become scriptable")
expect(off, "property did not become unscriptable")
end)
T("fireclickdetector", function(f)
local part = Instance.new("Part")
part.Anchored = true
part.Parent = workspace
local cd = Instance.new("ClickDetector")
cd.Parent = part
local fired = false
cd.MouseClick:Connect(function() fired = true end)
f(cd)
waitFor(function() return fired end, 1)
part:Destroy()
expect(fired, "MouseClick not fired")
end)
T("fireproximityprompt", function(f)
local part = Instance.new("Part")
part.Anchored = true
part.Parent = workspace
local pp = Instance.new("ProximityPrompt")
pp.Parent = part
local fired = false
pp.Triggered:Connect(function() fired = true end)
f(pp)
waitFor(function() return fired end, 1)
part:Destroy()
expect(fired, "Triggered not fired")
end)
T("firetouchinterest", function(f)
local root = rootPart()
if not root then return skip("no character to touch with") end
local part = Instance.new("Part")
part.Anchored = true
part.CanTouch = true
part.Position = Vector3.new(0, 5000, 0)
part.Parent = workspace
local touched = false
part.Touched:Connect(function() touched = true end)
f(root, part, 0)
f(root, part, 1)
waitFor(function() return touched end, 1)
part:Destroy()
expect(touched, "Touched not fired")
end)
T("getcallbackvalue", function(f)
local bf = Instance.new("BindableFunction")
local fn = function() return 1 end
bf.OnInvoke = fn
local v = f(bf, "OnInvoke")
bf:Destroy()
expect(v == fn, "wrong callback")
end)
T("getactors", function(f) expect(type(f()) == "table", "not a table") end)
T("getfpscap", function(f) expect(type(f()) == "number", "not a number") end)
T("setfpscap", function(f)
need("getfpscap")
local old = resolved.getfpscap()
f(30)
task.wait(0.1)
local ok = resolved.getfpscap() == 30
f(old)
expect(ok, "cap did not change")
end)
T("getcustomasset", function(f)
local ws = byName.writefile
if not ws or ws.src ~= "native" then return skip("needs a working native filesystem") end
local n = tmp() .. ".txt"
resolved.writefile(n, "hx")
waitFor(function() return resolved.isfile(n) end, 1)
local a = f(n)
rm(n)
expect(type(a) == "string" and a:find("rbxasset", 1, true) ~= nil, "no rbxasset url")
end)
T("cache.iscached", function(f)
local p = Instance.new("Part")
p.Parent = workspace
local v = f(p)
p:Destroy()
expect(v == true, "fresh instance not cached")
end)
T("cache.invalidate", function(f)
need("cache.iscached")
local p = Instance.new("Part")
p.Parent = workspace
f(p)
local v = resolved["cache.iscached"](p)
p:Destroy()
expect(v == false, "instance still cached")
end)
T("hookfunction", function(f)
local function a() return "a" end
local function b() return "b" end
local old = f(a, b)
local hooked = a() == "b"
local orig = type(old) == "function" and old() == "a"
local rf = resolved.restorefunction
if rf then pcall(rf, a) end
expect(hooked, "hook not applied")
expect(orig, "original not returned")
end)
T("restorefunction", function(f)
need("hookfunction")
local function a() return "a" end
resolved.hookfunction(a, function() return "b" end)
expect(a() == "b", "setup: hook not applied")
f(a)
expect(a() == "a", "function not restored")
end)
T("setreadonly", function(f)
local t = table.freeze({ a = 1 })
f(t, false)
local ok = pcall(function() t.a = 2 end)
expect(ok and t.a == 2, "table still readonly")
end)
T("debug.getupvalue", function(f)
local x = 5
x = x + 0
local function fn() return x end
expect(f(fn, 1) == 5, "wrong upvalue")
end)
T("debug.getupvalues", function(f)
local x = 5
x = x + 0
local function fn() return x end
local u = f(fn)
expect(type(u) == "table" and u[1] == 5, "wrong upvalues")
end)
T("debug.setupvalue", function(f)
local x = 5
x = x + 0
local function fn() return x end
f(fn, 1, 9)
expect(fn() == 9, "upvalue not changed")
end)
T("debug.getconstant", function(f)
local function fn() return "hx_const_probe" end
local found = false
for i = 1, 8 do
local ok, v = pcall(f, fn, i)
if ok and v == "hx_const_probe" then found = true; break end
end
expect(found, "constant not found")
end)
T("debug.getconstants", function(f)
local function fn() return "hx_const_probe", 12345 end
local c = f(fn)
expect(type(c) == "table" and table.find(c, "hx_const_probe") ~= nil, "constant not found")
end)
T("debug.setconstant", function(f)
need("debug.getconstant")
local function fn() return "hx_const_a" end
for i = 1, 8 do
local ok, v = pcall(resolved["debug.getconstant"], fn, i)
if ok and v == "hx_const_a" then f(fn, i, "hx_const_b"); break end
end
expect(fn() == "hx_const_b", "constant not changed")
end)
T("debug.getproto", function(f)
local function fn() local function inner() return 1 end return inner end
local keep = fn()
local ok, p = pcall(f, fn, 1)
if ok and (type(p) == "function" or type(p) == "table") then return end
local ok2, p2 = pcall(f, fn, 1, true)
expect(ok2 and (type(p2) == "function" or (type(p2) == "table" and next(p2) ~= nil)), "no proto returned")
expect(keep ~= nil, "closure lost")
end)
T("debug.getprotos", function(f)
local function fn() local function inner() end return inner end
expect(type(f(fn)) == "table", "not a table")
end)
T("debug.getstack", function(f) expect(f(1) ~= nil, "no stack") end)
T("debug.getregistry", function(f) expect(type(f()) == "table", "not a table") end)
T("debug.getmetatable", function(f) expect(type(f(game)) == "table", "no metatable") end)
T("debug.setmetatable", function(f)
local t = {}
f(t, { __index = function() return 7 end })
expect(t.x == 7, "metatable not set")
end)
local function member(o, k)
local ok, v = pcall(function() return o[k] end)
return ok and v or nil
end
T("setclipboard", function(f)
local get = grab("getclipboard")
local prev
if type(get) == "function" then pcall(function() prev = get() end) end
local probe = "hx_clip_" .. tostring(rng:NextInteger(1000, 9999))
f(probe)
if type(get) == "function" then
local ok, v = pcall(get)
if ok and type(v) == "string" then
expect(waitFor(function() local o, x = pcall(get); return o and x == probe end, 1), "clipboard not updated")
end
end
if type(prev) == "string" then pcall(f, prev) end
end)
T("setrbxclipboard", function(f)
local ok, err = pcall(f, "hx_rbx_clip_probe")
expect(ok, tostring(err))
end)
T("queue_on_teleport", function(f)
local ok, err = pcall(f, "-- hyundax compat probe")
expect(ok, tostring(err))
end)
T("run_on_actor", function(f)
local ga = grab("getactors")
if type(ga) ~= "function" then return skip("getactors unavailable") end
local okA, actors = pcall(ga)
local actor = okA and type(actors) == "table" and actors[1] or nil
local temp
if not actor then
temp = Instance.new("Actor")
temp.Parent = workspace
actor = temp
end
local ok, err = pcall(f, actor, "local x = 1 + 1")
if temp then pcall(function() temp:Destroy() end) end
if not ok and temp then return skip("no usable Actor in this game: " .. tostring(err)) end
expect(ok, tostring(err))
end)
T("WebSocket.connect", function(f)
local ws, err, finished
task.spawn(function()
local ok, r = pcall(f, "wss://echo.websocket.events")
if ok then ws = r else err = r end
finished = true
end)
waitFor(function() return finished end, 4)
if not ws then return skip("could not connect (" .. tostring(err or "timeout") .. ")") end
local got
local om = member(ws, "OnMessage")
if om and type(member(om, "Connect")) == "function" then
pcall(function() om:Connect(function(m) got = m end) end)
end
local okSend, errSend = pcall(function() ws:Send("hx_ws_probe") end)
waitFor(function() return got ~= nil end, 1.5)
pcall(function() ws:Close() end)
expect(type(member(ws, "Send")) == "function" and type(member(ws, "Close")) == "function", "missing Send/Close")
expect(om ~= nil and member(ws, "OnClose") ~= nil, "missing OnMessage/OnClose")
expect(okSend, tostring(errSend))
end)
T("getnamecallmethod", function(f)
need("hookmetamethod")
local hook = resolved.hookmetamethod
local calls, ref = {}, nil
ref = hook(game, "__namecall", function(...)
if #calls < 20 and (...) == game then calls[#calls + 1] = f() end
return ref(...)
end)
local okc = pcall(function() return game:GetService("Lighting") end)
pcall(hook, game, "__namecall", ref)
expect(okc, "namecall failed under hook")
expect(table.find(calls, "GetService") ~= nil, "expected GetService, got " .. tostring(calls[1]))
end)
T("setnamecallmethod", function(f)
need("hookmetamethod")
local hook = resolved.hookmetamethod
local gm = resolved.getnamecallmethod
local ref, armed = nil, true
ref = hook(game, "__namecall", function(...)
if armed and (...) == game then
local okm, m = true, "GetService"
if gm then okm, m = pcall(gm) end
if okm and m == "GetService" then
armed = false
f("GetChildren")
end
end
return ref(...)
end)
local ok, res = pcall(function() return game:GetService("Lighting") end)
armed = false
pcall(hook, game, "__namecall", ref)
expect(ok, "namecall failed under hook")
expect(type(res) == "table", "method was not replaced (got " .. typeof(res) .. ")")
end)
T("debug.setstack", function(f)
need("debug.getstack")
local getstack = resolved["debug.getstack"]
local probe = "hx_stack_" .. tostring(rng:NextInteger(100000, 999999))
local idx
local okS, snap = pcall(getstack, 1)
if okS and type(snap) == "table" then
for i, v in pairs(snap) do if v == probe then idx = i; break end end
end
if not idx then
for i = 1, 24 do
local ok, v = pcall(getstack, 1, i)
if ok and v == probe then idx = i; break end
end
end
expect(idx ~= nil, "could not locate a local on the stack")
f(1, idx, "hx_stack_changed")
expect(probe == "hx_stack_changed", "stack value not changed")
end)
T("cache.replace", function(f)
local part = Instance.new("Part")
local fire = Instance.new("Fire")
local ok, err = pcall(f, part, fire)
expect(ok, tostring(err))
expect(part ~= fire, "objects still equal")
pcall(function() part:Destroy() end)
pcall(function() fire:Destroy() end)
end)
T("messagebox", function(f)
if byName.messagebox.src == "poly" then
local result, done
task.spawn(function()
local ok, r = pcall(f, "Hyundax IUM compat test", "Hyundax IUM", 4)
if ok then result = r end
done = true
end)
waitFor(function() return Compat.mb.active ~= nil or done end, 2)
expect(Compat.mb.active ~= nil, "dialog did not open")
Compat.mb.active.close(6)
waitFor(function() return done end, 2)
expect(result == 6, "expected button result 6")
return
end
if not CONFIG.compat.intrusive then return skip("enable Intrusive tests (shows a dialog)") end
local result, err, done
task.spawn(function()
local ok, r = pcall(f, "Hyundax IUM compat test - click OK", "Hyundax IUM", 0)
if ok then result = r else err = r end
done = true
end)
waitFor(function() return done end, 5)
expect(err == nil, tostring(err))
if done then expect(type(result) == "number", "expected a number result") end
end)
T("saveinstance", function(f)
if not CONFIG.compat.intrusive then return skip("enable Intrusive tests (writes a file)") end
local folder = Instance.new("Folder")
folder.Name = "hx_save_probe"
Instance.new("Part", folder)
local name = "hx_saveprobe" .. tostring(rng:NextInteger(1000, 9999))
local ok, err = pcall(f, { Object = folder, FileName = name, mode = "optimized", noscripts = true })
pcall(function() folder:Destroy() end)
expect(ok, tostring(err))
end)
def("printidentity", "Environment", function()
return function() print("Current identity is " .. tostring(identity)) end
end, function(f) expect(pcall(f), "errored") end, "prints the emulated identity")
def("getexecutorversion", "Environment", function() return function() return BRAND.ver end end,
function(f) expect(type(f()) == "string", "not a string") end, "reports Hyundax IUM version")
def("newlclosure", "Closures", function()
return function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
return function(...) return fn(...) end
end
end, function(f)
local fn = function() return 3 end
local c = f(fn)
expect(c ~= fn and c() == 3, "wrapper misbehaves")
need("islclosure")
expect(resolved.islclosure(c) == true, "not a Lua closure")
end, "Lua wrapper")
Compat.hss = { hooked = setmetatable({}, { __mode = "k" }), store = {} }
Compat.hss.d = function(name, fn, test, note)
def(name, "HSS", function() return fn end, test, note)
end
Compat.hss.apply = function(f, new)
local hf = resolved.hookfunction
if type(hf) ~= "function" then error("hookfunction unavailable", 3) end
if type(f) ~= "function" or type(new) ~= "function" then error("function expected", 3) end
local st = Compat.hss.hooked[f]
if st then
st.new = new
return st.orig
end
st = { calls = 0, new = new }
st.orig = hf(f, function(...)
st.calls = st.calls + 1
return st.new(...)
end)
Compat.hss.hooked[f] = st
return st.orig
end
Compat.hss.restore = function(f)
local st = Compat.hss.hooked[f]
if not st then return false end
local ok = false
local rf = resolved.restorefunction
if type(rf) == "function" then ok = pcall(rf, f) end
if not ok and type(resolved.hookfunction) == "function" then
ok = pcall(resolved.hookfunction, f, st.orig)
end
Compat.hss.hooked[f] = nil
return ok
end
Compat.hss.needHook = function()
if type(resolved.hookfunction) ~= "function" then return skip("needs hookfunction") end
end
Compat.hss.d("hss.hook.apply", function(f, new) return Compat.hss.apply(f, new) end, function(f)
local s = Compat.hss.needHook() if s then return s end
local function a() return "a" end
local old = f(a, function() return "b" end)
local hooked = a() == "b"
local orig = type(old) == "function" and old() == "a"
Compat.hss.restore(a)
expect(hooked, "hook not applied")
expect(orig, "original not returned")
end, "hookfunction wrapper that tracks state")
Compat.hss.d("hss.hook.isHooked", function(f) return Compat.hss.hooked[f] ~= nil end, function(f)
local s = Compat.hss.needHook() if s then return s end
local function a() return 1 end
local before = f(a)
Compat.hss.apply(a, function() return 2 end)
local during = f(a)
Compat.hss.restore(a)
expect(before == false and during == true, "wrong hooked state")
expect(f(a) == false, "still reported hooked")
end)
Compat.hss.d("hss.hook.original", function(f)
local st = Compat.hss.hooked[f]
return st and st.orig or nil
end, function(f)
local s = Compat.hss.needHook() if s then return s end
local function a() return "a" end
Compat.hss.apply(a, function() return "b" end)
local o = f(a)
local ok = type(o) == "function" and o() == "a"
Compat.hss.restore(a)
expect(ok, "original not returned")
end)
Compat.hss.d("hss.hook.restore", function(f) return Compat.hss.restore(f) end, function(f)
local s = Compat.hss.needHook() if s then return s end
local function a() return "a" end
Compat.hss.apply(a, function() return "b" end)
local r = f(a)
expect(a() == "a", "function not restored")
expect(r == true, "restore did not report success")
end)
Compat.hss.d("hss.hook.restoreAll", function()
local list = {}
for fn in pairs(Compat.hss.hooked) do list[#list + 1] = fn end
local n = 0
for _, fn in ipairs(list) do
if Compat.hss.restore(fn) then n = n + 1 end
end
return n
end, function(f)
local s = Compat.hss.needHook() if s then return s end
local function a() return "a" end
local function b() return "b" end
Compat.hss.apply(a, function() return 1 end)
Compat.hss.apply(b, function() return 2 end)
local n = f()
expect(a() == "a" and b() == "b", "functions not restored")
expect(n >= 2, "count too small")
end)
Compat.hss.d("hss.hook.list", function()
local list = {}
for fn in pairs(Compat.hss.hooked) do list[#list + 1] = fn end
return list
end, function(f)
local s = Compat.hss.needHook() if s then return s end
local function a() return 1 end
Compat.hss.apply(a, function() return 2 end)
local found = false
for _, fn in ipairs(f()) do if fn == a then found = true end end
Compat.hss.restore(a)
expect(found, "hooked function not listed")
end)
Compat.hss.d("hss.hook.before", function(f, cb)
if type(cb) ~= "function" then error("function expected", 2) end
local orig
orig = Compat.hss.apply(f, function(...)
cb(...)
return orig(...)
end)
return orig
end, function(f)
local s = Compat.hss.needHook() if s then return s end
local seen
local function a(x) return x * 2 end
f(a, function(x) seen = x end)
local r = a(4)
Compat.hss.restore(a)
expect(seen == 4, "callback not run")
expect(r == 8, "original result changed")
end)
Compat.hss.d("hss.hook.after", function(f, cb)
if type(cb) ~= "function" then error("function expected", 2) end
local orig
orig = Compat.hss.apply(f, function(...)
local r = table.pack(orig(...))
cb(...)
return table.unpack(r, 1, r.n)
end)
return orig
end, function(f)
local s = Compat.hss.needHook() if s then return s end
local seen
local function a(x) return x + 1 end
f(a, function(x) seen = x end)
local r = a(4)
Compat.hss.restore(a)
expect(seen == 4, "callback not run")
expect(r == 5, "original result changed")
end)
Compat.hss.d("hss.hook.count", function(f)
local st = Compat.hss.hooked[f]
return st and st.calls or 0
end, function(f)
local s = Compat.hss.needHook() if s then return s end
local function a() return 1 end
Compat.hss.apply(a, function() return 2 end)
a() a()
local n = f(a)
Compat.hss.restore(a)
expect(n == 2, "expected 2 calls, got " .. tostring(n))
end)
Compat.hss.d("hss.hook.field", function(t, k, new)
if type(t) ~= "table" then error("table expected", 2) end
local old = t[k]
t[k] = new
return old
end, function(f)
local t = { fn = function() return 1 end }
local old = f(t, "fn", function() return 2 end)
expect(t.fn() == 2, "field not replaced")
expect(type(old) == "function" and old() == 1, "original not returned")
end, "pure Lua hook, works without hookfunction")
Compat.hss.d("hss.table.deepclone", function(t)
local seen = {}
local function dc(v)
if type(v) ~= "table" then return v end
if seen[v] then return seen[v] end
local c = {}
seen[v] = c
for k, x in pairs(v) do c[dc(k)] = dc(x) end
return c
end
return dc(t)
end, function(f)
local a = { 1, { 2 } }
a.self = a
local c = f(a)
expect(c ~= a and c[2] ~= a[2] and c[2][1] == 2, "not a deep copy")
expect(c.self == c, "cycle not preserved")
end)
Compat.hss.d("hss.table.merge", function(a, b)
local out = {}
for k, v in pairs(a or {}) do out[k] = v end
for k, v in pairs(b or {}) do out[k] = v end
return out
end, function(f)
local r = f({ a = 1, b = 2 }, { b = 3, c = 4 })
expect(r.a == 1 and r.b == 3 and r.c == 4, "wrong merge")
end)
Compat.hss.d("hss.table.keys", function(t)
local out = {}
for k in pairs(t) do out[#out + 1] = k end
return out
end, function(f)
local k = f({ a = 1, b = 2, c = 3 })
expect(#k == 3, "expected 3 keys")
end)
Compat.hss.d("hss.table.values", function(t)
local out = {}
for _, v in pairs(t) do out[#out + 1] = v end
return out
end, function(f)
local v = f({ a = 10, b = 20 })
expect(#v == 2 and v[1] + v[2] == 30, "wrong values")
end)
Compat.hss.d("hss.table.count", function(t)
local n = 0
for _ in pairs(t) do n = n + 1 end
return n
end, function(f)
expect(f({ 1, 2, a = 3 }) == 3 and f({}) == 0, "wrong count")
end)
Compat.hss.d("hss.table.equals", function(a, b)
local function eq(x, y, seen)
if x == y then return true end
if type(x) ~= "table" or type(y) ~= "table" then return false end
if seen[x] == y then return true end
seen[x] = y
for k, v in pairs(x) do
if not eq(v, y[k], seen) then return false end
end
for k in pairs(y) do
if x[k] == nil then return false end
end
return true
end
return eq(a, b, {})
end, function(f)
expect(f({ 1, { 2 } }, { 1, { 2 } }) == true, "equal tables reported different")
expect(f({ 1, { 2 } }, { 1, { 3 } }) == false, "different tables reported equal")
end)
Compat.hss.d("hss.table.freezeDeep", function(t)
local seen = {}
local function fz(v)
if type(v) ~= "table" or seen[v] then return end
seen[v] = true
for _, x in pairs(v) do fz(x) end
if not table.isfrozen(v) then table.freeze(v) end
end
fz(t)
return t
end, function(f)
local t = f({ a = { b = 1 } })
expect(table.isfrozen(t) and table.isfrozen(t.a), "not frozen")
end)
Compat.hss.d("hss.table.isArray", function(t)
if type(t) ~= "table" then return false end
local n, c = #t, 0
for _ in pairs(t) do c = c + 1 end
return c == n
end, function(f)
expect(f({ 1, 2, 3 }) == true and f({}) == true, "array not detected")
expect(f({ a = 1 }) == false, "dictionary seen as array")
end)
Compat.hss.d("hss.string.split", function(s, sep)
s = tostring(s)
sep = tostring(sep == nil and "," or sep)
local out = {}
if sep == "" then
for i = 1, #s do out[i] = s:sub(i, i) end
return out
end
local pos = 1
while true do
local a, b = s:find(sep, pos, true)
if not a then
out[#out + 1] = s:sub(pos)
break
end
out[#out + 1] = s:sub(pos, a - 1)
pos = b + 1
end
return out
end, function(f)
local r = f("a,b,c", ",")
expect(#r == 3 and r[3] == "c", "wrong split")
local e = f("a,,b", ",")
expect(#e == 3 and e[2] == "", "empty field lost")
end)
Compat.hss.d("hss.string.trim", function(s)
return (tostring(s):match("^%s*(.-)%s*$"))
end, function(f)
expect(f(" hi \n") == "hi", "not trimmed")
end)
Compat.hss.d("hss.string.startswith", function(s, p)
s, p = tostring(s), tostring(p)
return s:sub(1, #p) == p
end, function(f)
expect(f("hyundax", "hyu") == true and f("hyundax", "x") == false, "wrong result")
end)
Compat.hss.d("hss.string.endswith", function(s, p)
s, p = tostring(s), tostring(p)
return p == "" or s:sub(-#p) == p
end, function(f)
expect(f("hyundax", "dax") == true and f("hyundax", "h") == false, "wrong result")
end)
Compat.hss.d("hss.string.hex", function(s)
return (tostring(s):gsub(".", function(c) return string.format("%02x", c:byte()) end))
end, function(f)
expect(f("Hi") == "4869", "wrong hex")
end)
Compat.hss.d("hss.string.unhex", function(h)
h = tostring(h):gsub("%s", "")
if #h % 2 ~= 0 or h:find("%X") then error("invalid hex", 2) end
return (h:gsub("%x%x", function(x) return string.char(tonumber(x, 16)) end))
end, function(f)
expect(f("4869") == "Hi", "wrong unhex")
end)
Compat.hss.d("hss.string.random", function(n, charset)
n = tonumber(n) or 8
charset = tostring(charset or "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
local t = {}
for i = 1, n do
local k = rng:NextInteger(1, #charset)
t[i] = charset:sub(k, k)
end
return table.concat(t)
end, function(f)
local r = f(16)
expect(#r == 16 and r:match("^%w+$") ~= nil, "wrong random string")
expect(f(8, "a") == "aaaaaaaa", "charset ignored")
end)
Compat.hss.d("hss.string.hash", function(s)
s = tostring(s)
local h = 2166136261
for i = 1, #s do
h = bit32.bxor(h, s:byte(i))
h = ((h % 256) * 16777216 + h * 403) % 4294967296
end
return string.format("%08x", h)
end, function(f)
expect(f("") == "811c9dc5", "wrong hash of empty string")
expect(f("a") == "e40c292c", "wrong hash of 'a'")
end, "FNV-1a 32-bit")
Compat.hss.d("hss.func.memoize", function(fn)
local cache = {}
return function(...)
local key = {}
for i = 1, select("#", ...) do key[i] = tostring((select(i, ...))) end
key = table.concat(key, "\0")
local hit = cache[key]
if not hit then
hit = table.pack(fn(...))
cache[key] = hit
end
return table.unpack(hit, 1, hit.n)
end
end, function(f)
local n = 0
local m = f(function(x) n = n + 1 return x * 2 end)
expect(m(3) == 6 and m(3) == 6, "wrong result")
expect(n == 1, "function ran more than once")
end)
Compat.hss.d("hss.func.once", function(fn)
local done, res = false, nil
return function(...)
if not done then
done = true
res = table.pack(fn(...))
end
return table.unpack(res, 1, res.n)
end
end, function(f)
local n = 0
local o = f(function() n = n + 1 return n end)
expect(o() == 1 and o() == 1 and n == 1, "ran more than once")
end)
Compat.hss.d("hss.func.throttle", function(fn, secs)
secs = tonumber(secs) or 0.1
local last, res = -math.huge, nil
return function(...)
local now = os.clock()
if now - last >= secs then
last = now
res = table.pack(fn(...))
end
if res then return table.unpack(res, 1, res.n) end
end
end, function(f)
local n = 0
local t = f(function() n = n + 1 return n end, 5)
t() t()
expect(n == 1, "throttle let a second call through")
end)
Compat.hss.d("hss.func.pcallx", function(fn, ...)
local r = table.pack(xpcall(fn, function(e)
return { err = e, trace = debug.traceback(tostring(e), 2) }
end, ...))
if r[1] then return true, table.unpack(r, 2, r.n) end
return false, r[2].err, r[2].trace
end, function(f)
local ok, err, trace = f(function() error("boom", 0) end)
expect(ok == false and err == "boom", "error not captured")
expect(type(trace) == "string", "no traceback")
local ok2, v = f(function(x) return x end, 7)
expect(ok2 == true and v == 7, "success path broken")
end)
Compat.hss.d("hss.func.timeit", function(fn, ...)
local t0 = os.clock()
local r = table.pack(fn(...))
return os.clock() - t0, table.unpack(r, 1, r.n)
end, function(f)
local dt, v = f(function() return 5 end)
expect(type(dt) == "number" and dt >= 0, "no elapsed time")
expect(v == 5, "result lost")
end)
Compat.hss.d("hss.func.retry", function(fn, n, delay)
n = tonumber(n) or 3
local last
for i = 1, n do
local r = table.pack(pcall(fn, i))
if r[1] then return true, table.unpack(r, 2, r.n) end
last = r[2]
if i < n and tonumber(delay) and delay > 0 then task.wait(delay) end
end
return false, last
end, function(f)
local calls = 0
local ok, v = f(function()
calls = calls + 1
if calls < 3 then error("fail", 0) end
return "done"
end, 3, 0)
expect(ok == true and v == "done" and calls == 3, "retry logic wrong")
local ok2 = f(function() error("x", 0) end, 2, 0)
expect(ok2 == false, "should report failure")
end)
Compat.hss.d("hss.func.bind", function(fn, ...)
local bound = table.pack(...)
return function(...)
local extra = table.pack(...)
local all = table.clone(bound)
for i = 1, extra.n do all[bound.n + i] = extra[i] end
all.n = bound.n + extra.n
return fn(table.unpack(all, 1, all.n))
end
end, function(f)
local add = f(function(a, b, c) return a + b + c end, 1, 2)
expect(add(3) == 6, "partial application wrong")
end)
Compat.hss.d("hss.func.info", function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
local out = { isLua = false }
local ok, src = pcall(debug.info, fn, "s")
if ok and type(src) == "string" then out.isLua = src ~= "[C]"; out.source = src end
local okn, name = pcall(debug.info, fn, "n")
if okn then out.name = name end
local oka, np, va = pcall(debug.info, fn, "a")
if oka then out.params, out.vararg = np, va end
return out
end, function(f)
local r = f(function(a, b) return a end)
expect(type(r) == "table" and type(r.isLua) == "boolean", "wrong info table")
end)
Compat.hss.d("hss.inst.find", function(root, name, recursive)
return root:FindFirstChild(name, recursive ~= false)
end, function(f)
local a, b, p = Instance.new("Folder"), Instance.new("Folder"), Instance.new("Part")
b.Parent, p.Name, p.Parent = a, "x", b
local deep, shallow = f(a, "x"), f(a, "x", false)
a:Destroy()
expect(deep == p, "recursive search failed")
expect(shallow == nil, "non-recursive search found a descendant")
end)
Compat.hss.d("hss.inst.findAll", function(root, class)
local out = {}
for _, d in ipairs(root:GetDescendants()) do
if d:IsA(class) then out[#out + 1] = d end
end
return out
end, function(f)
local a = Instance.new("Folder")
Instance.new("Part", a)
Instance.new("Part", a)
Instance.new("Folder", a)
local r = f(a, "BasePart")
a:Destroy()
expect(#r == 2, "expected 2 parts, got " .. #r)
end)
Compat.hss.d("hss.inst.path", function(inst)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
local names, cur = {}, inst
while cur and cur ~= game do
table.insert(names, 1, cur.Name)
cur = cur.Parent
end
local out = (cur == game) and "game" or "nil"
for _, n in ipairs(names) do
if n:match("^[%a_][%w_]*$") then out = out .. "." .. n
else out = out .. "[\"" .. n .. "\"]" end
end
return out
end, function(f)
local p = Instance.new("Folder")
p.Name = "hx probe"
p.Parent = workspace
local r = f(p)
p:Destroy()
expect(r == "game.Workspace[\"hx probe\"]", "wrong path: " .. tostring(r))
end)
Compat.hss.d("hss.inst.fromPath", function(p)
if type(p) ~= "string" then error("string expected", 2) end
if p:match("^[%a_][%w_]*") ~= "game" then return nil end
local cur, i = game, 5
while i <= #p do
local name, e = p:match("^%.([%a_][%w_]*)()", i)
if not name then name, e = p:match("^%[\"(.-)\"%]()", i) end
if not name then return nil end
cur = cur:FindFirstChild(name)
if not cur then return nil end
i = e
end
return cur
end, function(f)
local p = Instance.new("Folder")
p.Name = "hx probe"
p.Parent = workspace
local r = f("game.Workspace[\"hx probe\"]")
p:Destroy()
expect(r == p, "path not resolved")
expect(f("game.Workspace.hx_does_not_exist") == nil, "missing path should be nil")
end)
Compat.hss.d("hss.inst.waitFor", function(root, name, timeout)
return root:WaitForChild(name, tonumber(timeout) or 5)
end, function(f)
local a, c = Instance.new("Folder"), Instance.new("Part")
c.Name, c.Parent = "child", a
local r = f(a, "child", 1)
a:Destroy()
expect(r == c, "child not returned")
end)
Compat.hss.d("hss.inst.clear", function(root)
local kids = root:GetChildren()
for _, k in ipairs(kids) do k:Destroy() end
return #kids
end, function(f)
local a = Instance.new("Folder")
Instance.new("Part", a)
Instance.new("Part", a)
local n = f(a)
local left = #a:GetChildren()
a:Destroy()
expect(n == 2 and left == 0, "children not cleared")
end)
Compat.hss.d("hss.inst.ancestors", function(inst)
local out, cur = {}, inst.Parent
while cur do
out[#out + 1] = cur
cur = cur.Parent
end
return out
end, function(f)
local a, b = Instance.new("Folder"), Instance.new("Part")
b.Parent = a
local r = f(b)
a:Destroy()
expect(r[1] == a, "wrong parent order")
end)
Compat.hss.d("hss.inst.countDescendants", function(root)
return #root:GetDescendants()
end, function(f)
local a = Instance.new("Folder")
local b = Instance.new("Folder", a)
Instance.new("Part", b)
local n = f(a)
a:Destroy()
expect(n == 2, "expected 2, got " .. n)
end)
Compat.hss.d("hss.version", function()
local n = 0
for _, s in ipairs(specs) do
if s.name:sub(1, 4) == "hss." then n = n + 1 end
end
return "HSS", "1.0", n
end, function(f)
local name, ver, n = f()
expect(name == "HSS" and type(ver) == "string", "wrong identity")
expect(type(n) == "number" and n > 0, "no function count")
end)
Compat.hss.d("hss.store.set", function(k, v)
if k == nil then error("key expected", 2) end
Compat.hss.store[k] = v
end, function(f)
f("hx_t", 5)
expect(Compat.hss.store.hx_t == 5, "value not stored")
Compat.hss.store.hx_t = nil
end, "in-memory store private to HSS")
Compat.hss.d("hss.store.get", function(k)
return Compat.hss.store[k]
end, function(f)
Compat.hss.store.hx_g = "v"
local r = f("hx_g")
Compat.hss.store.hx_g = nil
expect(r == "v" and f("hx_missing") == nil, "wrong value")
end)
Compat.hss.d("hss.store.keys", function()
local out = {}
for k in pairs(Compat.hss.store) do out[#out + 1] = k end
return out
end, function(f)
Compat.hss.store.hx_k = 1
local found = false
for _, k in ipairs(f()) do if k == "hx_k" then found = true end end
Compat.hss.store.hx_k = nil
expect(found, "key not listed")
end)
Compat.hss.d("hss.store.clear", function()
local n = 0
for k in pairs(Compat.hss.store) do
Compat.hss.store[k] = nil
n = n + 1
end
return n
end, function(f)
Compat.hss.store.hx_c = 1
local n = f()
expect(n >= 1 and next(Compat.hss.store) == nil, "store not cleared")
end)
Compat.hss.d("hss.signal.new", function()
local conns = {}
local sig = {}
local function mk(fn, once)
local c = { Connected = true, fn = fn, once = once }
function c:Disconnect() self.Connected = false end
conns[#conns + 1] = c
return c
end
function sig:Connect(fn) return mk(fn, false) end
function sig:Once(fn) return mk(fn, true) end
function sig:Fire(...)
for _, c in ipairs(table.clone(conns)) do
if c.Connected then
if c.once then c.Connected = false end
task.spawn(c.fn, ...)
end
end
local alive = {}
for _, c in ipairs(conns) do
if c.Connected then alive[#alive + 1] = c end
end
conns = alive
end
function sig:DisconnectAll()
for _, c in ipairs(conns) do c.Connected = false end
conns = {}
end
return sig
end, function(f)
local s = f()
local n, once = 0, 0
local c = s:Connect(function(v) n = n + v end)
s:Once(function() once = once + 1 end)
s:Fire(2) s:Fire(3)
expect(n == 5 and once == 1, "signal delivery wrong")
c:Disconnect()
s:Fire(10)
expect(n == 5, "disconnect ignored")
end)
Compat.hss.d("hss.util.uuid", function()
local function hx(n)
local t = {}
for i = 1, n do t[i] = string.format("%x", rng:NextInteger(0, 15)) end
return table.concat(t)
end
return hx(8) .. "-" .. hx(4) .. "-4" .. hx(3) .. "-" .. string.format("%x", rng:NextInteger(8, 11)) .. hx(3) .. "-" .. hx(12)
end, function(f)
local u = f()
expect(u:match("^%x%x%x%x%x%x%x%x%-%x%x%x%x%-4%x%x%x%-[89ab]%x%x%x%-%x+$") ~= nil, "bad uuid: " .. tostring(u))
expect(f() ~= u, "uuids repeat")
end)
Compat.hss.d("hss.math.clamp", function(v, lo, hi) return math.min(math.max(v, lo), hi) end, function(f)
expect(f(5, 0, 3) == 3 and f(-1, 0, 3) == 0 and f(2, 0, 3) == 2, "wrong clamp")
end)
Compat.hss.d("hss.math.lerp", function(a, b, t) return a + (b - a) * t end, function(f)
expect(f(0, 10, 0.5) == 5 and f(2, 4, 0) == 2 and f(2, 4, 1) == 4, "wrong lerp")
end)
Compat.hss.d("hss.math.round", function(n, dec)
local m = 10 ^ (dec or 0)
if n >= 0 then return math.floor(n * m + 0.5) / m end
return math.ceil(n * m - 0.5) / m
end, function(f)
expect(f(3.14159, 2) == 3.14 and f(2.5) == 3 and f(-2.5) == -3, "wrong rounding")
end)
Compat.hss.d("hss.math.sign", function(v) return v > 0 and 1 or (v < 0 and -1 or 0) end, function(f)
expect(f(9) == 1 and f(-3) == -1 and f(0) == 0, "wrong sign")
end)
Compat.hss.d("hss.math.map", function(v, a, b, c, d) return c + (v - a) * (d - c) / (b - a) end, function(f)
expect(f(5, 0, 10, 0, 100) == 50 and f(0, 0, 1, 10, 20) == 10, "wrong map")
end)
Compat.hss.d("hss.math.approx", function(a, b, eps) return math.abs(a - b) <= (eps or 1e-9) end, function(f)
expect(f(0.1 + 0.2, 0.3) == true and f(1, 2) == false, "wrong approx")
end)
Compat.hss.d("hss.math.gcd", function(a, b)
local g, h = math.abs(a), math.abs(b)
while h ~= 0 do g, h = h, g % h end
return g
end, function(f)
expect(f(12, 18) == 6 and f(7, 13) == 1, "wrong gcd")
end)
Compat.hss.d("hss.math.lcm", function(a, b)
local x, y = math.abs(a), math.abs(b)
if x == 0 or y == 0 then return 0 end
local g, h = x, y
while h ~= 0 do g, h = h, g % h end
return x / g * y
end, function(f)
expect(f(4, 6) == 12 and f(0, 5) == 0, "wrong lcm")
end)
Compat.hss.d("hss.math.isPrime", function(n)
if type(n) ~= "number" or n < 2 or n % 1 ~= 0 then return false end
for i = 2, math.floor(math.sqrt(n)) do
if n % i == 0 then return false end
end
return true
end, function(f)
expect(f(2) == true and f(17) == true and f(1) == false and f(9) == false, "wrong prime check")
end)
Compat.hss.d("hss.math.avg", function(t)
if #t == 0 then return 0 end
local s = 0
for _, v in ipairs(t) do s = s + v end
return s / #t
end, function(f)
expect(f({ 1, 2, 3 }) == 2 and f({}) == 0, "wrong average")
end)
Compat.hss.d("hss.array.map", function(t, fn)
local out = {}
for i, v in ipairs(t) do out[i] = fn(v, i) end
return out
end, function(f)
local r = f({ 1, 2, 3 }, function(v) return v * 2 end)
expect(#r == 3 and r[3] == 6, "wrong map")
end)
Compat.hss.d("hss.array.filter", function(t, fn)
local out = {}
for i, v in ipairs(t) do
if fn(v, i) then out[#out + 1] = v end
end
return out
end, function(f)
local r = f({ 1, 2, 3, 4 }, function(v) return v % 2 == 0 end)
expect(#r == 2 and r[1] == 2 and r[2] == 4, "wrong filter")
end)
Compat.hss.d("hss.array.reduce", function(t, fn, init)
local acc = init
for i, v in ipairs(t) do acc = fn(acc, v, i) end
return acc
end, function(f)
expect(f({ 1, 2, 3 }, function(a, v) return a + v end, 10) == 16, "wrong reduce")
end)
Compat.hss.d("hss.array.find", function(t, fn)
for i, v in ipairs(t) do
if fn(v, i) then return v, i end
end
return nil
end, function(f)
local v, i = f({ 5, 8, 12 }, function(x) return x > 6 end)
expect(v == 8 and i == 2, "wrong find")
expect(f({ 1 }, function() return false end) == nil, "should return nil")
end)
Compat.hss.d("hss.array.reverse", function(t)
local out, n = {}, #t
for i = 1, n do out[i] = t[n - i + 1] end
return out
end, function(f)
local r = f({ 1, 2, 3 })
expect(r[1] == 3 and r[3] == 1, "wrong reverse")
end)
Compat.hss.d("hss.array.unique", function(t)
local seen, out = {}, {}
for _, v in ipairs(t) do
if not seen[v] then
seen[v] = true
out[#out + 1] = v
end
end
return out
end, function(f)
local r = f({ 1, 2, 1, 3, 2 })
expect(#r == 3 and r[1] == 1 and r[2] == 2 and r[3] == 3, "wrong unique")
end)
Compat.hss.d("hss.array.flatten", function(t)
local out, seen = {}, {}
local function fl(x)
if seen[x] then return end
seen[x] = true
for _, v in ipairs(x) do
if type(v) == "table" then fl(v) else out[#out + 1] = v end
end
end
fl(t)
return out
end, function(f)
local r = f({ 1, { 2, { 3 } }, 4 })
expect(#r == 4 and r[3] == 3 and r[4] == 4, "wrong flatten")
end)
Compat.hss.d("hss.array.chunk", function(t, n)
n = math.max(1, math.floor(tonumber(n) or 1))
local out = {}
for i = 1, #t do
local g = math.floor((i - 1) / n) + 1
out[g] = out[g] or {}
table.insert(out[g], t[i])
end
return out
end, function(f)
local r = f({ 1, 2, 3, 4, 5 }, 2)
expect(#r == 3 and #r[1] == 2 and #r[3] == 1, "wrong chunks")
end)
Compat.hss.d("hss.array.shuffle", function(t)
local out = table.clone(t)
for i = #out, 2, -1 do
local j = rng:NextInteger(1, i)
out[i], out[j] = out[j], out[i]
end
return out
end, function(f)
local src = { 1, 2, 3, 4, 5, 6 }
local r = f(src)
local sum = 0
for _, v in ipairs(r) do sum = sum + v end
expect(#r == 6 and sum == 21, "elements changed")
expect(src[1] == 1 and src[6] == 6, "original was modified")
end)
Compat.hss.d("hss.array.slice", function(t, i, j)
local n = #t
i, j = i or 1, j or n
if i < 0 then i = n + i + 1 end
if j < 0 then j = n + j + 1 end
i, j = math.max(i, 1), math.min(j, n)
local out = {}
for k = i, j do out[#out + 1] = t[k] end
return out
end, function(f)
local a = f({ 1, 2, 3, 4 }, 2, 3)
expect(#a == 2 and a[1] == 2 and a[2] == 3, "wrong slice")
local b = f({ 1, 2, 3 }, -2)
expect(#b == 2 and b[1] == 2, "wrong negative slice")
end)
Compat.hss.d("hss.string.padleft", function(s, n, ch)
s = tostring(s)
ch = tostring(ch or " "):sub(1, 1)
if ch == "" then ch = " " end
n = tonumber(n) or 0
if #s >= n then return s end
return string.rep(ch, n - #s) .. s
end, function(f)
expect(f("5", 3, "0") == "005" and f("abc", 2) == "abc", "wrong padding")
end)
Compat.hss.d("hss.string.capitalize", function(s)
s = tostring(s)
return s:sub(1, 1):upper() .. s:sub(2):lower()
end, function(f)
expect(f("hELLO") == "Hello" and f("") == "", "wrong capitalize")
end)
Compat.hss.d("hss.string.count", function(s, sub)
s, sub = tostring(s), tostring(sub)
if sub == "" then return 0 end
local n, pos = 0, 1
while true do
local a, b = s:find(sub, pos, true)
if not a then break end
n = n + 1
pos = b + 1
end
return n
end, function(f)
expect(f("aaa", "a") == 3 and f("abab", "ab") == 2 and f("x", "") == 0, "wrong count")
end)
Compat.hss.d("hss.string.replace", function(s, find, rep)
s, find, rep = tostring(s), tostring(find), tostring(rep)
if find == "" then return s end
local out, pos = {}, 1
while true do
local a, b = s:find(find, pos, true)
if not a then
out[#out + 1] = s:sub(pos)
break
end
out[#out + 1] = s:sub(pos, a - 1)
out[#out + 1] = rep
pos = b + 1
end
return table.concat(out)
end, function(f)
expect(f("a.b.c", ".", "-") == "a-b-c", "wrong replace")
end, "plain text, no patterns")
Compat.hss.d("hss.string.reverse", function(s) return tostring(s):reverse() end, function(f)
expect(f("abc") == "cba", "wrong reverse")
end)
Compat.hss.d("hss.string.snake", function(s)
s = tostring(s)
s = s:gsub("(%l)(%u)", "%1_%2")
s = s:gsub("[%s%-]+", "_")
return s:lower()
end, function(f)
expect(f("HelloWorld") == "hello_world", "wrong snake of HelloWorld")
expect(f("my var-name") == "my_var_name", "wrong snake of spaced text")
end)
Compat.hss.d("hss.color.tohex", function(c)
if typeof(c) ~= "Color3" then error("Color3 expected", 2) end
return string.format("%02x%02x%02x", math.floor(c.R * 255 + 0.5), math.floor(c.G * 255 + 0.5), math.floor(c.B * 255 + 0.5))
end, function(f)
expect(f(Color3.fromRGB(255, 0, 128)) == "ff0080", "wrong hex")
end)
Compat.hss.d("hss.color.fromhex", function(h)
h = tostring(h):gsub("^#", "")
if #h ~= 6 or h:find("%X") then error("invalid hex color", 2) end
return Color3.fromRGB(tonumber(h:sub(1, 2), 16), tonumber(h:sub(3, 4), 16), tonumber(h:sub(5, 6), 16))
end, function(f)
local c = f("#ff0080")
expect(typeof(c) == "Color3", "not a Color3")
expect(math.floor(c.R * 255 + 0.5) == 255 and math.floor(c.B * 255 + 0.5) == 128, "wrong channels")
end)
Compat.hss.d("hss.color.lerp", function(a, b, t) return a:Lerp(b, t) end, function(f)
local c = f(Color3.new(0, 0, 0), Color3.new(1, 1, 1), 0.5)
expect(math.abs(c.R - 0.5) < 1e-4 and math.abs(c.G - 0.5) < 1e-4, "wrong blend")
end)
Compat.hss.d("hss.vec.distance", function(a, b) return (a - b).Magnitude end, function(f)
expect(math.abs(f(Vector3.new(0, 0, 0), Vector3.new(3, 4, 0)) - 5) < 1e-4, "wrong distance")
end)
Compat.hss.d("hss.time.now", function() return os.time(), os.clock() end, function(f)
local a, b = f()
expect(type(a) == "number" and a > 0 and type(b) == "number", "wrong time values")
end)
Compat.hss.d("hss.time.format", function(s)
s = math.max(0, math.floor(tonumber(s) or 0))
return string.format("%02d:%02d:%02d", math.floor(s / 3600), math.floor((s % 3600) / 60), s % 60)
end, function(f)
expect(f(3661) == "01:01:01" and f(0) == "00:00:00", "wrong format")
end)
Compat.hss.d("hss.time.parse", function(str)
local total = 0
for p in tostring(str):gmatch("[^:]+") do
local n = tonumber(p)
if not n then error("invalid time", 2) end
total = total * 60 + n
end
return total
end, function(f)
expect(f("01:01:01") == 3661 and f("02:03") == 123 and f("45") == 45, "wrong parse")
end)
Compat.hss.d("hss.time.sleep", function(n)
local t0 = os.clock()
task.wait(tonumber(n) or 0)
return os.clock() - t0
end, function(f)
local dt = f(0.05)
expect(type(dt) == "number" and dt >= 0.04, "did not wait")
end)
Compat.hss.d("hss.player.me", function() return game:GetService("Players").LocalPlayer end, function(f)
local lp = game:GetService("Players").LocalPlayer
if not lp then return skip("no LocalPlayer") end
expect(f() == lp, "not the LocalPlayer")
end)
Compat.hss.d("hss.player.find", function(part)
part = tostring(part):lower()
for _, p in ipairs(game:GetService("Players"):GetPlayers()) do
if p.Name:lower():sub(1, #part) == part or p.DisplayName:lower():sub(1, #part) == part then return p end
end
return nil
end, function(f)
local lp = game:GetService("Players").LocalPlayer
if not lp then return skip("no LocalPlayer") end
expect(f(lp.Name) ~= nil, "player not found")
expect(f("hx_no_such_player_zz") == nil, "should be nil")
end)
Compat.hss.d("hss.player.names", function()
local out = {}
for _, p in ipairs(game:GetService("Players"):GetPlayers()) do out[#out + 1] = p.Name end
return out
end, function(f)
local lp = game:GetService("Players").LocalPlayer
if not lp then return skip("no LocalPlayer") end
local found = false
for _, n in ipairs(f()) do if n == lp.Name then found = true end end
expect(found, "LocalPlayer not listed")
end)
Compat.hss.d("hss.player.character", function()
local lp = game:GetService("Players").LocalPlayer
return lp and lp.Character or nil
end, function(f)
local c = f()
if c == nil then return skip("no character right now") end
expect(typeof(c) == "Instance", "not an Instance")
end)
Compat.hss.d("hss.player.humanoid", function()
local lp = game:GetService("Players").LocalPlayer
local c = lp and lp.Character
return c and c:FindFirstChildOfClass("Humanoid") or nil
end, function(f)
local h = f()
if h == nil then return skip("no humanoid right now") end
expect(h:IsA("Humanoid"), "not a Humanoid")
end)
Compat.hss.d("hss.player.root", function()
local lp = game:GetService("Players").LocalPlayer
local c = lp and lp.Character
return c and c:FindFirstChild("HumanoidRootPart") or nil
end, function(f)
local r = f()
if r == nil then return skip("no root part right now") end
expect(r:IsA("BasePart"), "not a BasePart")
end)
Compat.hss.d("hss.util.typeof", function(v) return typeof(v) end, function(f)
expect(f(Vector3.new()) == "Vector3" and f(1) == "number", "wrong typeof")
end)
Compat.hss.d("hss.util.isCallable", function(v)
if type(v) == "function" then return true end
if type(v) == "table" then
local ok, mt = pcall(getmetatable, v)
return ok and type(mt) == "table" and type(rawget(mt, "__call")) == "function"
end
return false
end, function(f)
expect(f(print) == true and f(1) == false, "wrong function check")
expect(f(setmetatable({}, { __call = function() end })) == true, "callable table not detected")
end)
Compat.hss.d("hss.util.dump", function(v)
local seen = {}
local function d(x)
local tx = type(x)
if tx == "string" then return string.format("%q", x) end
if tx ~= "table" then return tostring(x) end
if seen[x] then return "" end
seen[x] = true
local parts, n = {}, #x
for i = 1, n do parts[#parts + 1] = d(x[i]) end
local keys = {}
for k in pairs(x) do
if not (type(k) == "number" and k >= 1 and k <= n and k % 1 == 0) then keys[#keys + 1] = k end
end
table.sort(keys, function(a, b) return tostring(a) < tostring(b) end)
for _, k in ipairs(keys) do
local ks = (type(k) == "string" and k:match("^[%a_][%w_]*$")) and k or ("[" .. d(k) .. "]")
parts[#parts + 1] = ks .. " = " .. d(x[k])
end
seen[x] = nil
return "{" .. table.concat(parts, ", ") .. "}"
end
return d(v)
end, function(f)
expect(f({ 1, "x" }) == '{1, "x"}', "wrong array dump")
expect(f({ a = 1 }) == "{a = 1}", "wrong dictionary dump")
local c = {}
c.self = c
expect(f(c) == "{self = }", "cycle not handled")
end)
Compat.hss.d("hss.util.range", function(a, b, step)
step = step or 1
if step == 0 then error("step cannot be zero", 2) end
local out = {}
if step > 0 then
for i = a, b, step do out[#out + 1] = i end
else
for i = a, b, step do out[#out + 1] = i end
end
return out
end, function(f)
local r = f(1, 5)
expect(#r == 5 and r[5] == 5, "wrong ascending range")
local d = f(10, 0, -5)
expect(#d == 3 and d[3] == 0, "wrong descending range")
end)
do
local state = Compat.ext or {}
Compat.ext = state
state.hooks = state.hooks or setmetatable({}, { __mode = "k" })
state.nilSeen = state.nilSeen or setmetatable({}, { __mode = "k" })
state.scriptable = state.scriptable or setmetatable({}, { __mode = "k" })
state.cacheRepl = state.cacheRepl or setmetatable({}, { __mode = "k" })
state.clip = state.clip or ""
state.fps = state.fps or 60
state.warned = state.warned or {}
local function P(name, poly, note)
local s = byName[name]
if not s then return end
s.poly = poly
if note then s.approx = note end
end
local function once(key, msg)
if state.warned[key] then return end
state.warned[key] = true
Log.warn("compat: " .. msg)
end
local function fsx(n) local f = grab(n); return type(f) == "function" and f or nil end
local function fnv(s)
local h = 2166136261
for i = 1, #s do
h = bit32.bxor(h, s:byte(i))
h = (h * 16777619) % 4294967296
end
return string.format("%08x", h)
end
local function hash128(s)
return fnv(s) .. fnv(s .. "#1") .. fnv("#2" .. s) .. fnv(#s .. s)
end
local function isScript(sc)
return typeof(sc) == "Instance" and sc:IsA("LuaSourceContainer")
end
local function srcOf(sc)
local ok, src = pcall(function() return sc.Source end)
if ok and type(src) == "string" and src ~= "" then return src end
return nil
end
P("getgc", function()
return function(includeTables)
local out, seen = {}, {}
local function add(v)
if v ~= nil and not seen[v] then seen[v] = true; out[#out + 1] = v end
end
local function scan(root, depth)
if type(root) ~= "table" then return end
pcall(function()
for _, v in pairs(root) do
local tv = type(v)
if tv == "function" then
add(v)
elseif tv == "table" and not seen[v] then
if includeTables then add(v) end
if depth < 2 then scan(v, depth + 1) end
end
end
end)
end
scan(ENV, 0)
scan(_G, 0)
scan(shared, 0)
for _, lib in ipairs({ string, table, math, os, task, coroutine, bit32, utf8, debug }) do scan(lib, 2) end
return out
end
end, "scans globals and library tables (not the real GC heap)")
local function registry() return { ENV, _G, shared } end
P("getreg", function() return registry end, "emulated registry (globals only)")
P("debug.getregistry", function() return registry end, "emulated registry (globals only)")
P("getsenv", function()
return function(sc)
if not isScript(sc) then error("script expected", 2) end
local env = { script = sc }
if sc:IsA("ModuleScript") then
local ok, res = pcall(require, sc)
if ok and type(res) == "table" then
for k, v in pairs(res) do env[k] = v end
end
end
return setmetatable(env, { __index = ENV })
end
end, "module exports plus globals (cannot read real script locals)")
P("getscriptclosure", function()
return function(sc)
if not isScript(sc) then error("script expected", 2) end
local src = srcOf(sc)
if src and LOADSTRING then
local f = LOADSTRING(src, "=" .. sc:GetFullName())
if f then return f end
end
if sc:IsA("ModuleScript") then
return function() return require(sc) end
end
return function() end
end
end, "compiles Source when readable, otherwise wraps require()")
P("getscriptbytecode", function()
return function(sc)
if not isScript(sc) then error("script expected", 2) end
return srcOf(sc) or ("-- bytecode unavailable (" .. sc.ClassName .. "): " .. sc:GetFullName())
end
end, "returns Source when readable (not real bytecode)")
P("getscripthash", function()
return function(sc)
if not isScript(sc) then error("script expected", 2) end
return hash128(srcOf(sc) or (sc.ClassName .. ":" .. sc:GetFullName()))
end
end, "hash of Source or path")
P("decompile", function()
return function(sc)
if not isScript(sc) then error("script expected", 2) end
return srcOf(sc) or ("-- decompiler unavailable on this executor\n-- " .. sc.ClassName .. ": " .. sc:GetFullName())
end
end, "returns Source when readable (no real decompiler)")
P("getfunctionhash", function()
return function(fn)
if type(fn) ~= "function" then error("function expected", 2) end
local ok, key = pcall(function()
local s, l, n = debug.info(fn, "sln")
return tostring(s) .. ":" .. tostring(l) .. ":" .. tostring(n) .. ":" .. tostring(fn)
end)
return hash128(ok and key or tostring(fn))
end
end, "hash of function identity and debug info")
P("getnilinstances", function()
if not state.nilConn then
pcall(function()
state.nilConn = game.DescendantRemoving:Connect(function(inst) state.nilSeen[inst] = true end)
Compat.conns[#Compat.conns + 1] = state.nilConn
end)
end
return function()
local out = {}
for inst in pairs(state.nilSeen) do
local ok, par = pcall(function() return inst.Parent end)
if ok and par == nil then out[#out + 1] = inst end
end
return out
end
end, "tracks instances removed from the game after Hyundax IUM loaded")
P("getconnections", function()
return function(signal)
if typeof(signal) ~= "RBXScriptSignal" then error("signal expected", 2) end
once("getconnections", "getconnections cannot enumerate engine signals here, returning an empty list")
return {}
end
end, "empty list (engine signals cannot be enumerated)")
P("firesignal", function()
return function(signal, ...)
if typeof(signal) ~= "RBXScriptSignal" then error("signal expected", 2) end
once("firesignal", "firesignal cannot fire engine signals here (no native support)")
end
end, "no-op (engine signals cannot be fired)")
P("isscriptable", function()
return function(inst, prop)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
prop = tostring(prop)
local t = state.scriptable[inst]
if t and t[prop] ~= nil then return t[prop] end
return (pcall(function() return inst[prop] end))
end
end, "readability probe plus virtual setscriptable flags")
P("setscriptable", function()
return function(inst, prop, on)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
prop = tostring(prop)
local t = state.scriptable[inst]
if not t then t = {}; state.scriptable[inst] = t end
local was = t[prop]
if was == nil then was = (pcall(function() return inst[prop] end)) end
t[prop] = on and true or false
return was
end
end, "virtual flag only (does not unlock engine properties)")
P("fireclickdetector", function()
return function(cd, dist)
if typeof(cd) ~= "Instance" or not cd:IsA("ClickDetector") then error("ClickDetector expected", 2) end
local part = cd.Parent
local cam = workspace.CurrentCamera
local v = vim()
if not (v and cam and part and part:IsA("BasePart")) then error("cannot simulate a click here", 2) end
local pos, vis = cam:WorldToViewportPoint(part.Position)
if not vis then error("ClickDetector part is not on screen", 2) end
local inset = game:GetService("GuiService"):GetGuiInset()
local old = cd.MaxActivationDistance
pcall(function() cd.MaxActivationDistance = math.max(old, tonumber(dist) or 0, 1e4) end)
v:SendMouseMoveEvent(pos.X, pos.Y + inset.Y, game)
v:SendMouseButtonEvent(pos.X, pos.Y + inset.Y, 0, true, game, 1)
v:SendMouseButtonEvent(pos.X, pos.Y + inset.Y, 0, false, game, 1)
task.delay(.3, function() pcall(function() cd.MaxActivationDistance = old end) end)
end
end, "simulates a mouse click on the part (needs it on screen)")
P("fireproximityprompt", function()
return function(pp, amount)
if typeof(pp) ~= "Instance" or not pp:IsA("ProximityPrompt") then error("ProximityPrompt expected", 2) end
task.spawn(function()
local hold, los, en = pp.HoldDuration, pp.RequiresLineOfSight, pp.Enabled
pcall(function() pp.HoldDuration = 0; pp.RequiresLineOfSight = false; pp.Enabled = true end)
for _ = 1, math.max(1, math.floor(tonumber(amount) or 1)) do
pcall(function() pp:InputHoldBegin() end)
task.wait()
pcall(function() pp:InputHoldEnd() end)
task.wait()
end
pcall(function() pp.HoldDuration = hold; pp.RequiresLineOfSight = los; pp.Enabled = en end)
end)
end
end, "uses ProximityPrompt:InputHoldBegin/End")
P("firetouchinterest", function()
return function(a, b, toggle)
if typeof(a) ~= "Instance" or typeof(b) ~= "Instance" or not a:IsA("BasePart") or not b:IsA("BasePart") then
error("BasePart expected", 2)
end
if toggle == 1 or toggle == false then return end
task.spawn(function()
local cf = a.CFrame
pcall(function() a.CFrame = b.CFrame end)
task.wait(.06)
pcall(function() a.CFrame = cf end)
end)
end
end, "briefly moves the first part onto the second")
P("getcallbackvalue", function()
return function(inst, prop)
if typeof(inst) ~= "Instance" then error("Instance expected", 2) end
local ok, v = pcall(function() return inst[prop] end)
if ok and type(v) == "function" then return v end
return nil
end
end, "reads the property (write-only callbacks return nil)")
P("cache.replace", function()
return function(a, b)
if typeof(a) ~= "Instance" or typeof(b) ~= "Instance" then error("Instance expected", 2) end
state.cacheRepl[a] = b
end
end, "records the replacement only")
local function setClip(s) state.clip = tostring(s) end
P("setclipboard", function() return setClip end, "in-memory clipboard")
P("setrbxclipboard", function() return setClip end, "in-memory clipboard")
P("getclipboard", function() return function() return state.clip end end, "in-memory clipboard")
P("getfpscap", function() return function() return state.fps end end, "stored value (engine cap unchanged)")
P("setfpscap", function()
return function(n)
n = tonumber(n)
if not n then error("number expected", 2) end
state.fps = n
end
end, "stored value (engine cap unchanged)")
P("getactors", function()
return function()
local out = {}
for _, i in ipairs(game:GetDescendants()) do
if i:IsA("Actor") then out[#out + 1] = i end
end
return out
end
end, "scans for Actor instances")
P("run_on_actor", function()
return function(actor, code, ...)
if typeof(actor) ~= "Instance" or not actor:IsA("Actor") then error("Actor expected", 2) end
if type(code) ~= "string" then error("string expected", 2) end
if not LOADSTRING then error("loadstring unavailable", 2) end
local f, err = LOADSTRING(code)
if not f then error(err, 2) end
return f(...)
end
end, "runs the code in the current VM, not inside the Actor")
P("getcustomasset", function()
return function(path)
path = tostring(path)
if path:find("^rbxassetid://") or path:find("^rbxasset://") or path:find("^https?://") then return path end
local g = grab("getsynasset")
if type(g) == "function" then return g(path) end
error("getcustomasset is not supported by this executor", 2)
end
end, "passes asset URLs through, falls back to getsynasset")
local QFILE = "HyundaxIUM/queue_on_teleport.lua"
P("queue_on_teleport", function()
return function(code)
if type(code) ~= "string" then error("string expected", 2) end
state.queue = state.queue or {}
state.queue[#state.queue + 1] = code
local w = fsx("writefile")
if w then pcall(w, QFILE, table.concat(state.queue, "\n")) end
end
end, "saved to HyundaxIUM/queue_on_teleport.lua and run next time Hyundax IUM loads (autoexec)")
task.defer(function()
local i, r, d = fsx("isfile"), fsx("readfile"), fsx("delfile")
if not (i and r and d and LOADSTRING) then return end
local ok, src = pcall(function() if i(QFILE) then return r(QFILE) end end)
if ok and type(src) == "string" and src ~= "" then
pcall(d, QFILE)
local f = LOADSTRING(src)
if f then task.spawn(f) end
end
end)
local function xml(s) return (tostring(s):gsub("[&<>\"]", { ["&"] = "&", ["<"] = "<", [">"] = ">", ['"'] = """ })) end
P("saveinstance", function()
return function(a, b)
local opts = type(a) == "table" and a or (type(b) == "table" and b or {})
local root = typeof(a) == "Instance" and a or game
local w = fsx("writefile")
if not w then error("writefile unavailable", 2) end
local out, n = { '' }, 0
local function walk(inst)
n = n + 1
if n % 1500 == 0 then task.wait() end
local line = '- ' .. xml(inst.Name) .. ""
if inst:IsA("LuaSourceContainer") then
local src = srcOf(inst)
if src then line = line .. '", "]]]]>") .. "]]>" end
end
out[#out + 1] = line .. ""
for _, c in ipairs(inst:GetChildren()) do walk(c) end
out[#out + 1] = "
"
end
walk(root)
out[#out + 1] = ""
local name = opts.FileName or opts.filename or (tostring(game.PlaceId) .. ".rbxlx")
w(name, table.concat(out, "\n"))
return name
end
end, "hierarchy-only .rbxlx export (names, classes and readable Source)")
local function roots()
local list = { ENV, _G, shared, string, table, math, os, task, coroutine, bit32, utf8, debug }
local nested = {}
for _, r in ipairs({ ENV, _G }) do
pcall(function()
for _, v in pairs(r) do
if type(v) == "table" and v ~= ENV and v ~= _G and v ~= shared then nested[#nested + 1] = v end
end
end)
end
for _, v in ipairs(nested) do list[#list + 1] = v end
return list
end
P("hookfunction", function()
return function(f, new)
if type(f) ~= "function" or type(new) ~= "function" then error("function expected", 2) end
local rec = state.hooks[f]
if rec then
for _, loc in ipairs(rec.locs) do pcall(rawset, loc[1], loc[2], new) end
rec.new = new
return f
end
rec = { new = new, locs = {} }
for _, root in ipairs(roots()) do
pcall(function()
for k, v in pairs(root) do
if rawequal(v, f) then
rec.locs[#rec.locs + 1] = { root, k }
end
end
end)
end
for _, loc in ipairs(rec.locs) do pcall(rawset, loc[1], loc[2], new) end
state.hooks[f] = rec
if #rec.locs == 0 then
once("hookfunction", "hookfunction could only wrap global references (local upvalues cannot be redirected)")
end
return f
end
end, "replaces global/library references (cannot patch local upvalues)")
P("restorefunction", function()
return function(f)
local rec = state.hooks[f]
if not rec then return end
for _, loc in ipairs(rec.locs) do pcall(rawset, loc[1], loc[2], f) end
state.hooks[f] = nil
end
end, "undoes the emulated hookfunction")
P("getnamecallmethod", function() return function() return state.ncm end end, "emulated state")
P("setnamecallmethod", function()
return function(m)
if type(m) ~= "string" then error("string expected", 2) end
state.ncm = m
end
end, "emulated state")
P("setreadonly", function()
return function(t, ro)
if type(t) ~= "table" then error("table expected", 2) end
if ro then
if not table.isfrozen(t) then table.freeze(t) end
elseif table.isfrozen(t) then
once("setreadonly", "setreadonly(false) cannot thaw a frozen table without native support")
end
end
end, "can freeze but cannot thaw frozen tables")
local function noVm(name, ret)
P(name, function()
return function(...)
once(name, name .. " needs native VM access; returning an empty fallback")
return ret
end
end, "stub (needs native VM access)")
end
noVm("debug.getupvalue", nil)
noVm("debug.getupvalues", {})
noVm("debug.setupvalue", nil)
noVm("debug.getconstant", nil)
noVm("debug.getconstants", {})
noVm("debug.setconstant", nil)
noVm("debug.getproto", nil)
noVm("debug.getprotos", {})
noVm("debug.setstack", nil)
P("debug.getstack", function()
return function(level, index)
local out = {}
local ok, s = pcall(debug.info, (tonumber(level) or 1) + 1, "slf")
if index ~= nil then return nil end
if ok then out[1] = s end
return out
end
end, "returns frame info only")
P("debug.getmetatable", function()
return function(obj)
local mt = getmetatable(obj)
if type(mt) == "table" then return mt end
return { __index = function(_, k) return obj[k] end, __metatable = mt }
end
end, "returns a proxy table when the metatable is locked")
P("debug.setmetatable", function()
return function(obj, mt)
if type(obj) == "table" then setmetatable(obj, mt) end
return obj
end
end, "tables only")
P("WebSocket.connect", function()
return function(url)
if type(url) ~= "string" then error("string expected", 2) end
local HS = game:GetService("HttpService")
local ok, client = pcall(function()
return HS:CreateWebStreamClient(Enum.WebStreamClientType.WebSocket, { Url = url })
end)
if not ok or not client then error("WebSocket is not supported by this executor", 2) end
local msgEv, closeEv = Instance.new("BindableEvent"), Instance.new("BindableEvent")
pcall(function() client.MessageReceived:Connect(function(m) msgEv:Fire(m) end) end)
pcall(function() client.Closed:Connect(function() closeEv:Fire() end) end)
return {
OnMessage = msgEv.Event,
OnClose = closeEv.Event,
Send = function(_, data) client:Send(data) end,
Close = function() pcall(function() client:Close() end) end,
}
end
end, "uses HttpService:CreateWebStreamClient when the engine offers it")
end
for _, n in ipairs({ "Drawing.new", "Drawing.Fonts", "cleardrawcache", "isrenderobj", "getrenderproperty",
"setrenderproperty", "crypt.encrypt", "crypt.decrypt", "request", "http_request", "http.request",
"mouse1click", "mouse1press", "mouse1release", "mouse2click", "mouse2press", "mouse2release",
"mousemoveabs", "mousemoverel", "mousescroll", "keypress", "keyrelease", "messagebox", "saveinstance",
"run_on_actor", "WebSocket.connect", "getnamecallmethod", "setnamecallmethod", "debug.setstack",
"cache.replace" }) do
if byName[n] then byName[n].safeNative = true; byName[n].intrusive = (n ~= "saveinstance") end
end
local FS_NAMES = { "writefile", "readfile", "isfile", "delfile", "makefolder", "isfolder", "delfolder",
"listfiles", "appendfile", "loadfile", "dofile" }
Compat.fsBroken = false
function Compat.realNative(name)
local ok, v = pcall(nativeGet, name)
if not ok or type(v) ~= "function" then return nil end
local prev = rawget(ENV, "__hyundaxiumPolys")
if type(prev) == "table" and prev[name] == v then return nil end
return v
end
function Compat.probeFS()
Compat.fsBroken = false
local w, r = Compat.realNative("writefile"), Compat.realNative("readfile")
if not (w and r) then return end
local n = "hxprobe" .. tostring(rng:NextInteger(100000, 999999)) .. ".txt"
local good = false
if pcall(w, n, "probe") then
good = waitFor(function() return r(n) == "probe" end, 1.5)
end
local d = Compat.realNative("delfile")
if d then pcall(d, n) end
if not good then
Compat.fsBroken = true
Log.warn("compat: native filesystem does not persist files — using in-memory fallback for file functions")
end
end
function Compat.scan()
local prev = rawget(ENV, "__hyundaxiumPolys")
for _, s in ipairs(specs) do
local ok, v = pcall(nativeGet, s.name)
if not ok then v = nil end
if v ~= nil and not (s.value or type(v) == "function") then v = nil end
if v ~= nil and type(prev) == "table" and prev[s.name] == v then v = nil end
s.native = v
end
if Compat.fsBroken then
for _, n in ipairs(FS_NAMES) do
if byName[n] then byName[n].native = nil end
end
end
local ci, cv = byName["cache.iscached"], byName["cache.invalidate"]
if ci and cv and (ci.native ~= nil or cv.native ~= nil) then
if Compat.cacheGood == nil then
local good = false
if ci.native ~= nil and cv.native ~= nil then
pcall(function()
local p = Instance.new("Part")
p.Parent = workspace
local a = ci.native(p)
cv.native(p)
local b = ci.native(p)
p:Destroy()
good = (a == true and b == false)
end)
end
Compat.cacheGood = good
if not good then Log.warn("compat: native cache.* is unreliable — using emulated instance cache") end
end
if not Compat.cacheGood then
ci.native, cv.native = nil, nil
ci.force, cv.force = true, true
end
end
end
function Compat.resolve()
table.clear(resolved)
for pass = 1, 2 do
for _, s in ipairs(specs) do
if pass == 1 or (s.fn == nil) then
s.fn, s.src = nil, "missing"
if s.force and s.native ~= nil and s.poly and CONFIG.compat.polyfill then
local okp, fp = pcall(s.poly, R)
if okp and type(fp) == "function" then s.fn, s.src = fp, "poly" end
end
if s.fn ~= nil then
elseif s.native ~= nil then
s.fn, s.src = s.native, "native"
elseif s.poly and CONFIG.compat.polyfill then
local ok, f = pcall(s.poly, R)
if ok and f ~= nil and (s.value or type(f) == "function") then s.fn, s.src = f, "poly" end
end
resolved[s.name] = s.fn
end
end
end
end
function Compat.install(target, own)
own = own or {}
local rec = (target == ENV) and (rawget(ENV, "__hyundaxiumPolys") or {}) or nil
local n = 0
for _, s in ipairs(specs) do
if s.src == "poly" and s.fn ~= nil then
pcall(function()
local parts = splitPath(s.name)
local t = target
for i = 1, #parts - 1 do
local cur = t[parts[i]]
if cur == nil then cur = grab(parts[i]) end
if type(cur) ~= "table" then cur = {} end
if not own[cur] then
cur = table.clone(cur)
own[cur] = true
rawset(t, parts[i], cur)
end
t = cur
end
local last = parts[#parts]
if rawget(t, last) == nil or s.force then
rawset(t, last, s.fn)
n = n + 1
if rec then rec[s.name] = s.fn end
end
end)
end
end
if rec then rawset(ENV, "__hyundaxiumPolys", rec) end
return n
end
function Compat.get(name) return resolved[name] end
local CRASH_FILE = "HyundaxIUM/compat_crash.txt"
local crashed = {}
local function fsFn(n) local f = grab(n); return type(f) == "function" and f or nil end
local function crumbSet(name)
local w = fsFn("writefile")
if not w then return end
local mk, isd = fsFn("makefolder"), fsFn("isfolder")
if mk and isd then pcall(function() if not isd("HyundaxIUM") then mk("HyundaxIUM") end end) end
pcall(w, CRASH_FILE, name)
end
local function crumbClear()
local d, i = fsFn("delfile"), fsFn("isfile")
if d and i then pcall(function() if i(CRASH_FILE) then d(CRASH_FILE) end end) end
end
local function crumbLoad()
local i, r = fsFn("isfile"), fsFn("readfile")
if not (i and r) then return end
local ok, name = pcall(function() if i(CRASH_FILE) then return r(CRASH_FILE) end end)
if ok and type(name) == "string" and name ~= "" then
crashed[name] = true
Log.warn("compat: '" .. name .. "' crashed the client last run and will be skipped")
crumbClear()
end
end
local function runTest(s)
if not s.test then return nil, "no behavior test defined" end
if crashed[s.name] then return false, "skipped: crashed the client in a previous run" end
if s.safeNative and s.src == "native" and not (s.intrusive and CONFIG.compat.intrusive) then
if type(s.fn) == "function" or s.value then return true, "native: existence only (behavior test skipped for safety)" end
return false, "not callable"
end
if s.intrusive and CONFIG.compat.intrusive and s.src == "native" then
local scb = grab("setclipboard")
if type(scb) == "function" then pcall(scb, "hyundaxium-last-intrusive-test: " .. s.name) end
pcall(RAW_PRINT, "[sUNC] intrusive test: " .. s.name)
end
crumbSet(s.name)
local state = { done = false }
local th = task.spawn(function()
local ok, err = pcall(s.test, s.fn)
state.ok, state.err, state.done = ok, err, true
end)
local t0 = os.clock()
while not state.done do
if os.clock() - t0 > 8 then
pcall(task.cancel, th)
crumbClear()
return false, "timeout (8s)"
end
task.wait()
end
crumbClear()
if state.ok then
if type(state.err) == "string" and state.err:sub(1, 5) == "skip:" then return nil, state.err:sub(6) end
return true
end
return false, ((tostring(state.err):gsub("^[^:\n]*:%d+:%s*", "")))
end
function Compat.runOne(name)
local s = byName[name]
if not s then return nil, "unknown function" end
Compat.resolve()
if not s.fn then return "missing" end
local ok, note = runTest(s)
s.note = note
if ok == nil then s.status = "untested"
elseif s.src == "native" then s.status = ok and "pass" or "fail"
else s.status = ok and "poly" or "polyfail" end
return s.status, note
end
function Compat.summaryText()
local st = Compat.stats
if not st then
local nat, pol, mis = 0, 0, 0
for _, s in ipairs(specs) do
if s.src == "native" then nat = nat + 1 elseif s.src == "poly" then pol = pol + 1 else mis = mis + 1 end
end
return string.format("%d functions · %d native · %d polyfilled · %d missing\nNot tested yet — press Test for behavior checks", #specs, nat, pol, mis)
end
local function pct(a, denom) return denom > 0 and math.floor(a / denom * 100 + 0.5) or 0 end
return string.format("sUNC %d%% (%d/%d) · UNC %d%% · behavior %d%% (%d/%d tested)\n%d fail · %d pfail · %d missing · %d untested · %d native · %d poly",
pct(st.passAll, st.total), st.passAll, st.total, pct(st.existAll, st.total),
pct(st.passAll, st.testedAll), st.passAll, st.testedAll,
st.fail, st.polyfail, st.missing, st.untested, st.existNative, st.existAll - st.existNative)
end
function Compat.run()
if Compat.running then return false end
Compat.running = true
Bus.emit("compat:state", true)
crumbLoad()
Compat.probeFS()
Compat.scan()
Compat.resolve()
local st = { total = #specs, existNative = 0, existAll = 0, passNative = 0, passAll = 0, testedNative = 0,
testedAll = 0, untested = 0, fail = 0, polyfail = 0, missing = 0, byCat = {} }
local missingNames = {}
for _, s in ipairs(specs) do
s.status, s.note = nil, nil
local c = st.byCat[s.cat or "?"]
if not c then c = { total = 0, pass = 0 }; st.byCat[s.cat or "?"] = c end
c.total = c.total + 1
if not s.fn then
s.status = "missing"
st.missing = st.missing + 1
missingNames[#missingNames + 1] = s.name
else
st.existAll = st.existAll + 1
if s.src == "native" then st.existNative = st.existNative + 1 end
local ok, note, skipped
if s.test then
ok, note = runTest(s)
skipped = (ok == nil)
end
if not s.test or skipped then
s.status = "untested"
s.note = skipped and ("skipped: " .. tostring(note)) or "exists, but no behavior test is defined"
st.untested = st.untested + 1
else
s.note = note
st.testedAll = st.testedAll + 1
if s.src == "native" then
st.testedNative = st.testedNative + 1
if ok then
s.status = "pass"
st.passNative = st.passNative + 1
st.passAll = st.passAll + 1
c.pass = c.pass + 1
else
s.status = "fail"
st.fail = st.fail + 1
end
else
if ok then
s.status = "poly"
st.passAll = st.passAll + 1
c.pass = c.pass + 1
else
s.status = "polyfail"
st.polyfail = st.polyfail + 1
end
end
end
end
end
Compat.stats = st
Compat.running = false
for line in Compat.summaryText():gmatch("[^\n]+") do Log.info("compat: " .. line) end
local cl = {}
for cat, c in pairs(st.byCat) do cl[#cl + 1] = string.format("%s %d/%d", cat, c.pass, c.total) end
table.sort(cl)
Log.info("compat: " .. table.concat(cl, " · "))
local nf = 0
for _, s in ipairs(specs) do
if s.status == "fail" or s.status == "polyfail" then
nf = nf + 1
Log.error(string.format("compat [%s] %s — %s", s.status == "fail" and "FAIL" or "POLYFAIL", s.name, tostring(s.note)))
end
end
if nf == 0 then Log.ok("compat: no failing tests") end
local ut = {}
for _, sp in ipairs(specs) do
if sp.status == "untested" then ut[#ut + 1] = sp.name .. " (" .. tostring(sp.note) .. ")" end
end
if #ut > 0 then Log.warn("compat untested (" .. #ut .. "): " .. table.concat(ut, "; ")) end
Log.info(string.format("compat FINAL: %d/%d verified by behavior · %d failed · %d untested · %d missing",
st.passAll, st.total, st.fail + st.polyfail, st.untested, st.missing))
if #missingNames > 0 then Log.warn("compat missing (" .. #missingNames .. "): " .. table.concat(missingNames, ", ")) end
Bus.emit("compat:state", false)
return true
end
function Compat.report()
local lines = { BRAND.name .. " " .. BRAND.ver .. " compat report · executor: " .. EXECUTOR_NAME, Compat.summaryText(), "" }
for _, s in ipairs(specs) do
lines[#lines + 1] = string.format("%-8s %-30s %s", string.upper(s.status or s.src), s.name, s.note or s.approx or "")
end
return table.concat(lines, "\n")
end
function Compat.cleanup()
for _, c in ipairs(Compat.conns) do pcall(function() c:Disconnect() end) end
Compat.conns = {}
local f = resolved.cleardrawcache
if f then pcall(f) end
if drawGui then pcall(function() drawGui:Destroy() end) end
end
Compat.scan()
Compat.resolve()
if CONFIG.compat.globalize then Compat.install(ENV, {}) end
end
end
local CppBridge = {}
do
local bridgeEnv = _G
if type(getgenv) == "function" then
local ok, env = pcall(getgenv)
if ok and type(env) == "table" then bridgeEnv = env end
end
local host = nil
local function findHost()
local candidate = rawget(bridgeEnv, "HyundaxIUMCppBridge") or rawget(bridgeEnv, "HyundaxCppBridge")
if type(candidate) ~= "table" then
candidate = rawget(bridgeEnv, "__HYUNDAXIUM_CPP_BRIDGE") or rawget(bridgeEnv, "__HYUNDAX_CPP_BRIDGE")
end
if type(candidate) ~= "table" and bridgeEnv ~= _G then
candidate = rawget(_G, "HyundaxIUMCppBridge") or rawget(_G, "__HYUNDAXIUM_CPP_BRIDGE") or rawget(_G, "HyundaxCppBridge") or rawget(_G, "__HYUNDAX_CPP_BRIDGE")
end
return type(candidate) == "table" and candidate or nil
end
local function invoke(method, ...)
if not host then return false, "C++ bridge unavailable" end
local fn = rawget(host, method)
if type(fn) ~= "function" then return false, "C++ bridge method unavailable: " .. method end
local ok, a, b = pcall(fn, ...)
if not ok then return false, tostring(a) end
return true, a, b
end
function CppBridge.refresh()
host = findHost()
return host ~= nil and type(rawget(host, "ping")) == "function"
end
function CppBridge.isAvailable()
return CppBridge.refresh()
end
function CppBridge.ping()
CppBridge.refresh()
local ok, result = invoke("ping")
if not ok then return false, result end
return true, result == nil and true or result
end
function CppBridge.version()
CppBridge.refresh()
if not host then return nil, "C++ bridge unavailable" end
local value = rawget(host, "version")
if type(value) == "function" then
local ok, result = pcall(value)
if not ok then return nil, tostring(result) end
value = result
end
if type(value) ~= "string" then return "unknown" end
return value:sub(1, 64)
end
function CppBridge.log(level, message)
CppBridge.refresh()
level = tostring(level or "info"):lower()
if level ~= "info" and level ~= "warn" and level ~= "error" then
return false, "invalid log level"
end
message = tostring(message or "")
if #message > 500 then message = message:sub(1, 500) end
return invoke("log", level, message)
end
function CppBridge.call(action, ...)
if action == "ping" then return CppBridge.ping() end
if action == "version" then
local value, err = CppBridge.version()
return value ~= nil, value or err
end
if action == "log" then return CppBridge.log(...) end
return false, "action not allowed"
end
function CppBridge.status()
CppBridge.refresh()
local version = CppBridge.version()
local pingOk, pingResult = CppBridge.ping()
return {
available = pingOk and pingResult ~= false,
ping = pingOk and tostring(pingResult) or tostring(pingResult),
version = version or "unknown",
methods = host and {
ping = type(rawget(host, "ping")) == "function",
version = type(rawget(host, "version")) == "function" or type(rawget(host, "version")) == "string",
log = type(rawget(host, "log")) == "function",
} or { ping = false, version = false, log = false },
}
end
CppBridge.refresh()
end
Compat.cppBridge = CppBridge
pcall(rawset, bridgeEnv, "HyundaxIUMCpp", CppBridge)
pcall(rawset, bridgeEnv, "HyundaxCpp", CppBridge)
local T = {
bg = Color3.fromRGB(10, 10, 10),
side = Color3.fromRGB(10, 10, 10),
panel = Color3.fromRGB(18, 18, 18),
panel2 = Color3.fromRGB(34, 34, 34),
line = Color3.fromRGB(42, 42, 42),
text = Color3.fromRGB(255, 255, 255),
muted = Color3.fromRGB(176, 176, 176),
tan = Color3.fromRGB(66, 140, 255),
gold = Color3.fromRGB(255, 206, 48),
bronze = Color3.fromRGB(230, 40, 50),
bronzeHi = Color3.fromRGB(255, 96, 100),
bronzeLo = Color3.fromRGB(150, 18, 30),
dark = Color3.fromRGB(16, 4, 6),
glow = Color3.fromRGB(52, 12, 16),
cardTop = Color3.fromRGB(26, 26, 26),
}
local function font(weight, family)
local ok, f = pcall(function() return Font.new(family or FONT_FAMILY, weight) end)
if ok and f then return f end
return Font.fromEnum(Enum.Font.GothamBold)
end
local F = {
Regular = font(Enum.FontWeight.Medium),
Medium = font(Enum.FontWeight.SemiBold),
SemiBold = font(Enum.FontWeight.Bold),
Bold = font(Enum.FontWeight.ExtraBold),
}
local MONO = Font.fromEnum(Enum.Font.RobotoMono)
local function safeName(n) return (tostring(n):gsub("[^%w_%-]", "_")) end
local function jsonRead(path, default)
local ok, r = pcall(function()
if isfile and isfile(path) then return HttpService:JSONDecode(readfile(path)) end
end)
if ok and type(r) == "table" then return r end
return default
end
local function jsonWrite(path, data)
return pcall(function() writefile(path, HttpService:JSONEncode(data)) end)
end
T.SETTINGS_FILE = FOLDER .. "/settings.json"
T.UI_THEMES = {
["Hyundax IUM Primary"] = {
bg = Color3.fromRGB(10, 10, 10), side = Color3.fromRGB(10, 10, 10), panel = Color3.fromRGB(18, 18, 18),
panel2 = Color3.fromRGB(34, 34, 34), line = Color3.fromRGB(42, 42, 42), text = Color3.fromRGB(255, 255, 255),
muted = Color3.fromRGB(176, 176, 176), tan = Color3.fromRGB(66, 140, 255), gold = Color3.fromRGB(255, 206, 48),
bronze = Color3.fromRGB(230, 40, 50), bronzeHi = Color3.fromRGB(255, 96, 100), bronzeLo = Color3.fromRGB(150, 18, 30),
dark = Color3.fromRGB(16, 4, 6), glow = Color3.fromRGB(52, 12, 16), cardTop = Color3.fromRGB(26, 26, 26),
},
Darkness = {
bg = Color3.fromRGB(0, 0, 0), side = Color3.fromRGB(1, 1, 1), panel = Color3.fromRGB(5, 5, 5),
panel2 = Color3.fromRGB(10, 10, 10), line = Color3.fromRGB(34, 34, 34), text = Color3.fromRGB(255, 255, 255),
muted = Color3.fromRGB(166, 166, 166), tan = Color3.fromRGB(60, 130, 245), gold = Color3.fromRGB(250, 200, 50),
bronze = Color3.fromRGB(200, 40, 52), bronzeHi = Color3.fromRGB(255, 100, 108), bronzeLo = Color3.fromRGB(120, 18, 30),
dark = Color3.fromRGB(8, 8, 8), glow = Color3.fromRGB(14, 14, 14), cardTop = Color3.fromRGB(2, 2, 2),
},
Lite = {
bg = Color3.fromRGB(255, 255, 255), side = Color3.fromRGB(246, 246, 246), panel = Color3.fromRGB(252, 252, 252),
panel2 = Color3.fromRGB(242, 242, 242), line = Color3.fromRGB(211, 211, 205), text = Color3.fromRGB(28, 28, 26),
muted = Color3.fromRGB(103, 103, 96), tan = Color3.fromRGB(30, 100, 220), gold = Color3.fromRGB(200, 150, 0),
bronze = Color3.fromRGB(176, 36, 48), bronzeHi = Color3.fromRGB(214, 84, 92), bronzeLo = Color3.fromRGB(120, 22, 32),
dark = Color3.fromRGB(28, 18, 19), glow = Color3.fromRGB(246, 226, 226), cardTop = Color3.fromRGB(250, 250, 250),
},
Mint = {
bg = Color3.fromRGB(8, 20, 17), side = Color3.fromRGB(11, 29, 24), panel = Color3.fromRGB(16, 39, 32),
panel2 = Color3.fromRGB(24, 55, 45), line = Color3.fromRGB(43, 82, 67), text = Color3.fromRGB(232, 255, 245),
muted = Color3.fromRGB(158, 190, 174), tan = Color3.fromRGB(96, 196, 150), gold = Color3.fromRGB(168, 240, 120),
bronze = Color3.fromRGB(70, 173, 126), bronzeHi = Color3.fromRGB(122, 222, 177), bronzeLo = Color3.fromRGB(30, 105, 75),
dark = Color3.fromRGB(5, 25, 18), glow = Color3.fromRGB(16, 53, 39), cardTop = Color3.fromRGB(18, 45, 36),
},
Ocean = {
bg = Color3.fromRGB(10, 17, 29), side = Color3.fromRGB(13, 23, 39), panel = Color3.fromRGB(20, 32, 52),
panel2 = Color3.fromRGB(29, 45, 69), line = Color3.fromRGB(49, 69, 98), text = Color3.fromRGB(239, 246, 255),
muted = Color3.fromRGB(164, 181, 204), tan = Color3.fromRGB(108, 168, 220), gold = Color3.fromRGB(120, 210, 255),
bronze = Color3.fromRGB(76, 145, 207), bronzeHi = Color3.fromRGB(142, 196, 240), bronzeLo = Color3.fromRGB(40, 87, 137),
dark = Color3.fromRGB(7, 16, 31), glow = Color3.fromRGB(17, 42, 73), cardTop = Color3.fromRGB(22, 37, 60),
},
}
do
local function RGB(r, g, b) return Color3.fromRGB(r, g, b) end
local function mkTheme(bg, side, panel, panel2, line, text, muted, acc, accHi, accLo, gold, glow, dark)
return {bg = bg, side = side, panel = panel, panel2 = panel2, line = line, text = text, muted = muted, tan = acc, gold = gold,
bronze = acc, bronzeHi = accHi, bronzeLo = accLo, dark = dark or RGB(14, 14, 18), glow = glow, cardTop = panel}
end
T.THEME_ORDER = {"Hyundax IUM Primary", "Darkness", "Lite", "Mint", "Ocean"}
T.THEME_DESC = {}
local function addTheme(name, desc, pal) T.UI_THEMES[name] = pal; T.THEME_DESC[name] = desc; T.THEME_ORDER[#T.THEME_ORDER + 1] = name end
addTheme("Sunset Coral", "Warm coral and peach on deep plum.", mkTheme(RGB(28,16,24), RGB(36,20,30), RGB(46,27,38), RGB(62,37,50), RGB(92,56,72), RGB(255,240,235), RGB(214,176,176), RGB(255,107,107), RGB(255,160,140), RGB(190,62,72), RGB(255,190,120), RGB(70,30,40)))
addTheme("Lavender Dream", "Soft purple and lilac, calm and creative.", mkTheme(RGB(22,18,38), RGB(29,23,50), RGB(39,31,66), RGB(54,44,90), RGB(86,72,130), RGB(244,240,255), RGB(186,176,220), RGB(167,139,250), RGB(201,182,255), RGB(111,78,210), RGB(244,170,255), RGB(52,38,92)))
addTheme("Cherry Blossom", "Light pink pastel with rose accents.", mkTheme(RGB(255,245,248), RGB(252,232,240), RGB(255,255,255), RGB(251,225,236), RGB(240,196,214), RGB(66,28,44), RGB(140,92,112), RGB(224,86,132), RGB(244,140,178), RGB(168,48,92), RGB(240,120,70), RGB(253,220,232), RGB(255,255,255)))
addTheme("Forest Earth", "Moss green and earthy tan, natural.", mkTheme(RGB(20,26,18), RGB(26,34,23), RGB(35,45,31), RGB(48,61,43), RGB(78,96,68), RGB(240,245,230), RGB(172,186,158), RGB(140,176,84), RGB(184,214,130), RGB(88,120,48), RGB(224,184,110), RGB(40,56,32)))
addTheme("Golden Hour", "Amber and honey on warm charcoal.", mkTheme(RGB(26,22,14), RGB(34,28,16), RGB(46,38,22), RGB(62,51,28), RGB(96,80,44), RGB(255,247,226), RGB(202,188,150), RGB(250,176,5), RGB(255,212,92), RGB(190,124,0), RGB(255,140,40), RGB(64,48,14)))
addTheme("Neon Night", "Cyberpunk magenta and electric cyan.", mkTheme(RGB(12,10,24), RGB(18,14,34), RGB(26,20,50), RGB(40,30,76), RGB(70,52,120), RGB(246,240,255), RGB(176,164,210), RGB(255,46,166), RGB(255,120,200), RGB(170,20,110), RGB(0,229,255), RGB(52,18,70)))
addTheme("Arctic Ice", "Crisp white and icy sky blue.", mkTheme(RGB(240,247,252), RGB(228,240,249), RGB(255,255,255), RGB(218,234,246), RGB(180,208,230), RGB(18,38,58), RGB(84,110,134), RGB(36,150,214), RGB(104,190,236), RGB(20,98,156), RGB(0,170,170), RGB(214,236,250), RGB(255,255,255)))
addTheme("Midnight Rose", "Charcoal with dusty rose and mauve.", mkTheme(RGB(22,18,22), RGB(30,24,30), RGB(41,33,41), RGB(56,45,56), RGB(88,72,88), RGB(250,238,244), RGB(190,168,182), RGB(222,126,160), RGB(244,170,196), RGB(160,76,106), RGB(240,190,150), RGB(58,36,50)))
addTheme("Tropical Punch", "Teal, turquoise and pineapple yellow.", mkTheme(RGB(8,28,32), RGB(10,38,44), RGB(14,50,58), RGB(20,68,78), RGB(36,104,114), RGB(236,255,252), RGB(150,200,200), RGB(20,200,190), RGB(110,236,224), RGB(10,128,124), RGB(255,214,10), RGB(10,66,70)))
addTheme("Royal Burgundy", "Deep wine red with champagne gold.", mkTheme(RGB(26,10,16), RGB(36,14,22), RGB(50,20,30), RGB(68,28,42), RGB(104,48,66), RGB(255,238,240), RGB(206,166,174), RGB(200,48,76), RGB(236,100,122), RGB(130,22,44), RGB(232,196,120), RGB(74,22,36)))
local function mkCustom(bg, acc)
local W, B = RGB(255,255,255), RGB(0,0,0)
local lum = bg.R * .299 + bg.G * .587 + bg.B * .114
local alum = acc.R * .299 + acc.G * .587 + acc.B * .114
local p
if lum > .55 then
p = mkTheme(bg, bg:Lerp(B,.05), bg:Lerp(W,.6), bg:Lerp(B,.09), bg:Lerp(B,.2), RGB(24,26,32), bg:Lerp(B,.55), acc, acc:Lerp(W,.3), acc:Lerp(B,.35), acc:Lerp(W,.18), bg:Lerp(acc,.2), nil)
else
p = mkTheme(bg, bg:Lerp(W,.04), bg:Lerp(W,.08), bg:Lerp(W,.14), bg:Lerp(W,.24), bg:Lerp(W,.95), bg:Lerp(W,.7), acc, acc:Lerp(W,.3), acc:Lerp(B,.35), acc:Lerp(W,.18), bg:Lerp(acc,.2), nil)
end
p.dark = (alum > .55) and RGB(14,14,18) or RGB(255,255,255)
return p
end
T.mkCustom = mkCustom
do
local st = jsonRead(T.SETTINGS_FILE, {})
local function rd(t, d) if type(t) == "table" and #t == 3 then return RGB(t[1], t[2], t[3]) end return d end
T.CUSTOM_BG = rd(st.customBg, RGB(24, 20, 40))
T.CUSTOM_ACC = rd(st.customAccent, RGB(230, 50, 60))
addTheme("Custom", "Your own palette: drag the dots to pick colors.", mkCustom(T.CUSTOM_BG, T.CUSTOM_ACC))
end
end
T.ACTIVE_THEME = jsonRead(T.SETTINGS_FILE, {}).theme or "Hyundax IUM Primary"
if not T.UI_THEMES[T.ACTIVE_THEME] then T.ACTIVE_THEME = "Hyundax IUM Primary" end
for k, v in pairs(T.UI_THEMES[T.ACTIVE_THEME]) do T[k] = v end
local Store = {
cloud = jsonRead(PATH.cloud, {}),
saved = jsonRead(PATH.saved, {}),
auto = jsonRead(PATH.autoIdx, {}),
likes = jsonRead(PATH.likes, {}),
}
local FX = {scale = 1.5}
FX.posTweens = setmetatable({}, {__mode = "k"})
function FX.stopMove(o)
local old = FX.posTweens[o]
if old then pcall(function() old:Cancel() end) FX.posTweens[o] = nil end
end
local function tween(o, p, t, style, dir)
local moves = p.Position ~= nil
if moves then FX.stopMove(o) end
local tw = TweenService:Create(o, TweenInfo.new((t or .2) * FX.scale, style or Enum.EasingStyle.Quint, dir or Enum.EasingDirection.Out), p)
tw:Play()
if moves then FX.posTweens[o] = tw end
return tw
end
do
local PROPS = {
Frame = {"BackgroundTransparency"}, ScrollingFrame = {"BackgroundTransparency"},
TextLabel = {"BackgroundTransparency", "TextTransparency"}, TextButton = {"BackgroundTransparency", "TextTransparency"},
TextBox = {"BackgroundTransparency", "TextTransparency"},
ImageLabel = {"BackgroundTransparency", "ImageTransparency"}, ImageButton = {"BackgroundTransparency", "ImageTransparency"},
UIStroke = {"Transparency"},
}
local orig = setmetatable({}, {__mode = "k"})
local function collect(o, list)
for _, c in ipairs(o:GetChildren()) do
if #list >= 260 then return end
if c:IsA("GuiObject") then
if c.Visible then
if PROPS[c.ClassName] then list[#list + 1] = c end
collect(c, list)
end
elseif c:IsA("UIStroke") then
list[#list + 1] = c
end
end
end
function FX.cascade(root, span)
span = span or .45
local list = {}
collect(root, list)
local ry, rh = root.AbsolutePosition.Y, math.max(root.AbsoluteSize.Y, 120)
for _, d in ipairs(list) do
local g = d:IsA("UIStroke") and d.Parent or d
local y = 0
if g and g:IsA("GuiObject") then y = math.clamp((g.AbsolutePosition.Y - ry) / rh, 0, 1) end
local st = orig[d]
if not st then st = {}; orig[d] = st end
local goal, any = {}, false
for _, prop in ipairs(PROPS[d.ClassName]) do
local o = st[prop]
if o == nil then o = d[prop] end
if o < 1 then
st[prop] = o
d[prop] = 1
goal[prop] = o
any = true
end
end
if any then
task.delay(y * span * FX.scale, function()
if not d.Parent then return end
local tw = tween(d, goal, .55)
tw.Completed:Connect(function(state)
if state == Enum.PlaybackState.Completed and orig[d] then
for prop in pairs(goal) do orig[d][prop] = nil end
end
end)
end)
end
end
end
end
local function new(class, props, kids)
local o = Instance.new(class)
local parent
for k, v in pairs(props or {}) do
if k == "Parent" then parent = v
elseif k == "NoI18N" then o:SetAttribute("NoI18N", true)
elseif k == "Glass" then o:SetAttribute("Glass", true)
else o[k] = v end
end
for _, c in ipairs(kids or {}) do c.Parent = o end
o.Parent = parent
if FX.cardSkin and props and props.BackgroundColor3 == T.cardTop and (class == "Frame" or class == "TextButton") then
pcall(FX.cardSkin, o)
end
return o
end
local function round(r) return new("UICorner", {CornerRadius = UDim.new(0, r)}) end
local function stroke(c, t)
return new("UIStroke", {Color = c or T.line, Thickness = t or 1, ApplyStrokeMode = Enum.ApplyStrokeMode.Border})
end
local function pad(l, t, r, b)
t = t or l
return new("UIPadding", {
PaddingLeft = UDim.new(0, l), PaddingTop = UDim.new(0, t),
PaddingRight = UDim.new(0, r or l), PaddingBottom = UDim.new(0, b or t),
})
end
local function vlist(p) return new("UIListLayout", {Padding = UDim.new(0, p or 0), SortOrder = Enum.SortOrder.LayoutOrder}) end
local function hlist(p, va, ha)
return new("UIListLayout", {
FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, p or 0), SortOrder = Enum.SortOrder.LayoutOrder,
VerticalAlignment = va or Enum.VerticalAlignment.Center, HorizontalAlignment = ha or Enum.HorizontalAlignment.Left,
})
end
local function text(parent, str, size, weight, color, props)
local p = {
BackgroundTransparency = 1, Text = str, TextSize = size,
FontFace = F[weight or "Regular"], TextColor3 = color or T.text,
TextXAlignment = Enum.TextXAlignment.Left,
Size = UDim2.new(1, 0, 0, size + 4), Parent = parent,
}
for k, v in pairs(props or {}) do p[k] = v end
return new("TextLabel", p)
end
local function scroller(parent, props, kids)
local p = {
BackgroundTransparency = 1, BorderSizePixel = 0, ScrollBarThickness = 3,
ScrollBarImageColor3 = T.tan, CanvasSize = UDim2.new(),
AutomaticCanvasSize = Enum.AutomaticSize.Y, Size = UDim2.fromScale(1, 1), Parent = parent,
}
for k, v in pairs(props or {}) do p[k] = v end
return new("ScrollingFrame", p, kids)
end
local function group(parent, props, kids)
local p = {BackgroundTransparency = 1, Size = UDim2.fromScale(1, 1), Visible = false, BorderSizePixel = 0, ClipsDescendants = true, Parent = parent}
for k, v in pairs(props or {}) do p[k] = v end
return new("Frame", p, kids)
end
local function pressFx(b, amount)
local sc = new("UIScale", {Parent = b})
b.MouseButton1Down:Connect(function() tween(sc, {Scale = (amount or .95) - .015}, .1, Enum.EasingStyle.Quad) end)
local function up() tween(sc, {Scale = 1}, .45, Enum.EasingStyle.Back) end
b.MouseButton1Up:Connect(function() FX.sfx.click() end)
b.MouseButton1Up:Connect(up)
b.MouseLeave:Connect(up)
end
local function hoverFx(b, from, to)
local scale = new("UIScale", {Scale = 1, Parent = b})
b.MouseEnter:Connect(function()
if FX.hover ~= false then tween(b, {BackgroundColor3 = to}, .15) end
if FX.lift ~= false then tween(scale, {Scale = 1.025}, .35, Enum.EasingStyle.Back) end
if FX.hoverSnd then FX.sfx.play("bub_hover") end
end)
b.MouseLeave:Connect(function()
tween(b, {BackgroundColor3 = from}, .2)
tween(scale, {Scale = 1}, .3, Enum.EasingStyle.Quint)
end)
end
FX.sfx = {mute = 1, enabled = true, vol = .32, ids = {}, last = {}, any = 0}
do
local Sfx = FX.sfx
pcall(function() Sfx.enabled = jsonRead(T.SETTINGS_FILE, {}).soundFeedback ~= false end)
local SoundService = game:GetService("SoundService")
local SR = 22050
local PRESETS = {
tab = {{720, 1040, .075, .8}},
click = {{540, 430, .04, .55}},
on = {{520, 520, .05, .8}, {780, 780, .09, .8}},
off = {{780, 780, .05, .7}, {480, 480, .09, .7}},
ok = {{660, 660, .06, .8}, {880, 880, .06, .8}, {1175, 1175, .13, .8}},
err = {{210, 150, .18, .9}},
open = {{440, 660, .08, .8}, {660, 990, .14, .8}},
close = {{880, 560, .08, .7}, {560, 380, .12, .7}},
welcome = {{523, 523, .09, .8}, {659, 659, .09, .8}, {784, 784, .09, .8}, {1047, 1047, .26, .85}},
bub_form = {{240, 820, .12, .85, .02}, {820, 640, .07, .5}},
bub_whoosh = {{160, 540, .26, .5, .10}},
bub_pop = {{1500, 420, .045, .9, .35}},
bub_merge = {{980, 300, .12, .85}, {300, 560, .08, .6}},
bub_hover = {{640, 900, .035, .45}},
bub_sel = {{520, 1040, .06, .85}, {1040, 1560, .13, .7}},
bub_land = {{250, 120, .11, .8, .03}},
bub_shine = {{1568, 1568, .05, .5}, {2093, 2093, .05, .45}, {2637, 2637, .16, .4}},
}
for i = 1, 8 do
local f = 360 * 2 ^ ((i - 1) / 6)
PRESETS["bub_p" .. i] = {{f, f * 2.6, .065, .85, .04}, {f * 2.6, f * 2, .035, .4}}
end
local FALLBACK = {
tab = "rbxasset://sounds/switch.wav", click = "rbxasset://sounds/button.wav",
on = "rbxasset://sounds/electronicpingshort.wav", off = "rbxasset://sounds/switch.wav",
ok = "rbxasset://sounds/electronicpingshort.wav", err = "rbxasset://sounds/button.wav",
open = "rbxasset://sounds/electronicpingshort.wav", close = "rbxasset://sounds/switch.wav",
welcome = "rbxasset://sounds/electronicpingshort.wav",
}
local function wav(notes)
local parts, phase = {}, 0
for _, n in ipairs(notes) do
local cnt = math.floor(SR * n[3])
for i = 0, cnt - 1 do
local u = i / cnt
phase = phase + 2 * math.pi * (n[1] + (n[2] - n[1]) * u) / SR
local env = math.min(1, i / (SR * .004)) * (1 - u) ^ 1.8
local v = (math.sin(phase) * .78 + math.sin(phase * 2) * .14 + (n[5] and (math.random() * 2 - 1) * n[5] or 0)) * env * (n[4] or 1)
parts[#parts + 1] = string.pack(" 0 or not Sfx.enabled then return end
if Sfx.blurred or (Sfx.off and Sfx.off[name]) then return end
local id = Sfx.ids[name]
if not id then return end
local now = os.clock()
if now - (Sfx.last[name] or 0) < .05 then return end
Sfx.last[name], Sfx.any = now, now
pcall(function()
local s = Instance.new("Sound")
s.SoundId = id
s.Volume = (vol or 1) * Sfx.vol
s.Parent = SoundService
s:Play()
task.delay(2, function() s:Destroy() end)
end)
end
function Sfx.click()
if Sfx.mute > 0 or not Sfx.enabled then return end
local t = os.clock()
task.delay(.07, function() if Sfx.any < t then Sfx.play("click") end end)
end
end
function FX.snd(name) FX.sfx.play(name) end
local function swap(items, target)
if items.cur == target then return end
local prev = items.cur
items.cur = target
items.tok = (items.tok or 0) + 1
local tok = items.tok
local veil = items.veil
if not (veil and veil.Parent) then
veil = new("Frame", {
Name = "Veil", Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 1,
BorderSizePixel = 0, ZIndex = 60, Parent = target.Parent,
})
items.veil = veil
end
if prev then
FX.snd("tab")
tween(prev, {Position = UDim2.fromOffset(0, -14)}, .22, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
tween(veil, {BackgroundTransparency = .1}, .18)
end
task.delay(prev and .2 * FX.scale or 0, function()
if items.tok ~= tok then return end
if items.vis and items.vis ~= target then items.vis.Visible = false end
items.vis = target
target.Position = UDim2.fromOffset(0, 24)
target.Visible = true
FX.cascade(target)
tween(target, {Position = UDim2.fromOffset(0, 0)}, .8, Enum.EasingStyle.Back)
tween(veil, {BackgroundTransparency = 1}, .5)
end)
end
local function arc(cx, cy, r, a1, a2, n)
local p = {}
for i = 0, n do
local a = math.rad(a1 + (a2 - a1) * i / n)
p[#p + 1] = cx + math.cos(a) * r
p[#p + 1] = cy + math.sin(a) * r
end
return p
end
local ICONS = {
home = {{3, 11, 12, 3.5, 21, 11}, {5.5, 9.5, 5.5, 20.5, 18.5, 20.5, 18.5, 9.5}, {10, 20.5, 10, 14.5, 14, 14.5, 14, 20.5}},
code = {{8, 7, 3, 12, 8, 17}, {16, 7, 21, 12, 16, 17}, {14, 5, 10, 19}},
play = {{7, 4.5, 19.5, 12, 7, 19.5, 7, 4.5}},
trash = {{4, 7, 20, 7}, {9, 7, 9, 4, 15, 4, 15, 7}, {6, 7, 7, 20.5, 17, 20.5, 18, 7}, {10.5, 11, 10.5, 16.5}, {13.5, 11, 13.5, 16.5}},
folder = {{3, 6, 9, 6, 11, 8.5, 20.5, 8.5, 20.5, 19.5, 3, 19.5, 3, 6}},
save = {{4, 4, 17, 4, 20, 7, 20, 20, 4, 20, 4, 4}, {8, 4, 8, 9, 15, 9, 15, 4}, {8, 20, 8, 14, 16, 14, 16, 20}},
copy = {{9, 9, 20, 9, 20, 20, 9, 20, 9, 9}, {15, 9, 15, 4, 4, 4, 4, 15, 9, 15}},
bolt = {{13, 3, 5.5, 13, 12, 13, 11, 21, 18.5, 10.5, 12, 10.5, 13, 3}},
plus = {{12, 5, 12, 19}, {5, 12, 19, 12}},
x = {{6, 6, 18, 18}, {18, 6, 6, 18}},
minus = {{5, 12, 19, 12}},
square = {{5, 5, 19, 5, 19, 19, 5, 19, 5, 5}},
restore = {{8, 8, 19, 8, 19, 19, 8, 19, 8, 8}, {5, 16, 5, 5, 16, 5, 16, 8}},
menu = {{4, 7, 20, 7}, {4, 12, 20, 12}, {4, 17, 20, 17}},
search = {arc(10, 10, 6, 0, 360, 14), {14.5, 14.5, 20, 20}},
chevD = {{6, 9, 12, 15, 18, 9}},
cloud = {{7, 18.5, 17, 18.5, 20.5, 15.5, 19, 11.5, 15.5, 10.5, 14, 7, 10, 6.5, 8, 9.5, 5, 11, 3.5, 14.5, 7, 18.5}},
refresh = {arc(12, 12, 7, -30, 240, 14), {19, 3.5, 19, 8.5, 14, 8.5}},
layers = {{12, 3, 21, 8, 12, 13, 3, 8, 12, 3}, {3, 12, 12, 17, 21, 12}, {3, 16, 12, 21, 21, 16}},
user = {arc(12, 8, 4, 0, 360, 12), {4.5, 21, 4.5, 19, 8, 15.5, 16, 15.5, 19.5, 19, 19.5, 21}},
filetext = {{6, 3, 14, 3, 19, 8, 19, 21, 6, 21, 6, 3}, {14, 3, 14, 8, 19, 8}, {9, 13, 16, 13}, {9, 17, 16, 17}},
history = {arc(12, 12, 8.5, 0, 360, 16), {12, 7, 12, 12, 15.5, 14}},
file = {{6, 3, 14, 3, 19, 8, 19, 21, 6, 21, 6, 3}, {14, 3, 14, 8, 19, 8}},
}
local function ell(cx, cy, rx, ry, n)
local p = {}
for i = 0, n do
local a = math.rad(360 * i / n)
p[#p + 1] = cx + math.cos(a) * rx
p[#p + 1] = cy + math.sin(a) * ry
end
return p
end
do
local heart = {}
for i = 0, 28 do
local t = math.rad(360 * i / 28)
local x = 16 * math.sin(t) ^ 3
local y = 13 * math.cos(t) - 5 * math.cos(2 * t) - 2 * math.cos(3 * t) - math.cos(4 * t)
heart[#heart + 1] = 12 + x * .58
heart[#heart + 1] = 11.5 - y * .58
end
local star = {}
for i = 0, 10 do
local a = math.rad(-90 + i * 36)
local r = (i % 2 == 0) and 9.5 or 4.2
star[#star + 1] = 12 + math.cos(a) * r
star[#star + 1] = 12.8 + math.sin(a) * r
end
ICONS.heart = {heart}
ICONS.star = {star}
end
ICONS.terminal = {{4, 7, 10, 12, 4, 17}, {12, 18, 20, 18}}
ICONS.globe = {ell(12, 12, 9, 9, 20), {3, 12, 21, 12}, ell(12, 12, 4, 9, 14)}
ICONS.paste = {{8, 4, 16, 4, 16, 7, 8, 7, 8, 4}, {16, 5.5, 18, 5.5, 18, 20.5, 6, 20.5, 6, 5.5, 8, 5.5}}
ICONS.chevL = {{15, 5, 8, 12, 15, 19}}
ICONS.chevR = {{9, 5, 16, 12, 9, 19}}
ICONS.tree = {{4, 4, 10, 4, 10, 8, 4, 8, 4, 4}, {13, 10, 20, 10, 20, 14, 13, 14, 13, 10}, {13, 17, 20, 17, 20, 21, 13, 21, 13, 17}, {7, 8, 7, 19, 13, 19}, {7, 12, 13, 12}}
local ICON_INDEX = {home=0, code=1, play=2, trash=3, folder=4, save=5, copy=6, bolt=7, plus=8, x=9, minus=10, square=11, restore=12, menu=13, search=14, chevD=15, chevL=16, chevR=17, cloud=18, refresh=19, layers=20, user=21, filetext=22, file=23, history=24, heart=25, star=26, terminal=27, globe=28, paste=29, heartFill=30, starFill=31}
local ICON_CELL, ICON_COLS = 64, 8
local ICON_B64 = table.concat({
"iVBORw0KGgoAAAANSUhEUgAAAgAAAAEACAYAAADFkM5nAABZZUlEQVR42u1dZ9gVRdI9RZIgqCCCEYyoKAZYE6isgGJCRMyKOaFiwkUXV11zDouiYs5ZQAkq",
"5pxQBAVMCCpJskqScL4f03z77uv0pDvx3jrP8z7o3Jnuqg7V1dXVVYBCoVAoFAqFQqFQKBSK8odoEygUyYBkbQCbAdgKwBYA6gb8dDGAbwFMBPC9iCzT1lQo",
"ylpWHArgYABzADwqIp+oAqBQFHdCHwXgdgBrl1jUbABnicjT2qqKjMf0lgCap1DVEgATRWR+BbRpPQCvANi92k/3isipOuoUimJN6LVIDmf8GEaysbawIsWx",
"vAbJq0m+QfJ3po+ZJJ8l2bRM27cByc88+H+2nAdXX5KTzN8FOt0UZTKuX05QII5ImZfzSD5NckxIOheRnEDyEZIdyqBP1yV5M8mRJH/MYCH8iOQNJPdJkefD",
"SM5gPjCd5B5luPh/EID3luUmIBuSHOXC6CiSDXQJKXz/7kBywwrl/fgUhOExKfCxDsl3Y6T5DZIbF7RPO5KcxfxgFMkNEub5eeYTh5SJnKhH8u2APO9ZTgKy",
"BcnvPJidQLKFLqMAyd1J7lwQWuuTHEjyjyp9OZ7kXhXWZ+NTEIJjE+ahDcnZCdA9v2hzm2SfnC6EC0kelhDPFzG/mFMOxwEkXwnBc6IWAEmR6V0BDAewls+r",
"8wDsLyIfVujCfwiARwDUN4++ALCPiMzKKb1rAHgVwE4uP68EcCeA/iLye5n3WxM4DnvVsRDAg6aNgrZBQwD7ADihyjj4/6oArJFUe5KcCKBVQs00RkR2KEh/",
"7gjgUwA1ckriSgCHicjzMfLcCsBYAHVy3DUjRWS/AsuJ4QCC0j9DRNYtvAJA8ngA9wKoFfCT5QBOEZGHKmzxbwTgB/zVc/xKEbk0pzQPBtDd57XpcDzZXyjj",
"vusOYLDLT4+IyHERy3wCwJEuPx0gIsMT4OEmAEn741wlIv/KeV+uBuBrAJvmfNitAHB4XEoAyTEAtrP8/B6A0QDmp8BXQwCdAbSx/N5SRKYUTD7UAPB8AFlZ",
"FfeIyOlFF4y3lWDyua3CFIBelna4N8c0zw3Rny8lfX6ZYTtcb+H58BLKPNpS5jUJ0F+T5LIUzLjLSG6X8748jMXBcpIHxsDz7h51dM+oH2ym8m4Fkw1C8qkI",
"fbt30rTVSJDpRiRfAXBOCcWcYzxvG1WIDmCbaONzOrC3hP+Rzv/sXAFMJHm+0YjLCbZ2mFNCmb9anjdJgP52cLfQ/QygB4BGEhCGvv6WemoBeDjnfWnzvRkK",
"oEMVPm0CepDEBAD1ABzlMY5qAniR5MEl8ryJ5fmtIjIko34YZnm+XcFkw8MAwm4EfgfwWiEVAOO4MNpjggDOWX97ALuZ/7ahK4CPy9050ESN62r5Oa+m8yi7",
"+QYAbgbwOcl2UOQFu1qePygig8P4HIjIXBG5BsANNgFu4hpsndO22M3y/FIReT9NQkRkiYg8aWia7fHqMyVaAjazPP88w374wPK8blEmFcm7ARzrs9C7ynwR",
"WVnEhWzXAGbh//H2D3A7gKbMXctYAehma6sc09zZQvNnAfpzFW4n2TBnfDU2d9hnsPiYYXhp7Ceo4jZDkqxL8puE+ZttrizeR7JjTP3vdgtigct7XSw03ZPQ",
"uNzCBMfxwv4Ry77HUl6XDOdhPQu/exREpg/w6asbSU6z/HZQERex4wOcI7re9/eID1D9/PD4MlUAHrDwfG0BFYC7SdYheSnJJQGE+C8ke+SIr7tYfrjTh+dB",
"lu86l9iW7UiuSInHFSQvL/V4ieQ8tw1I1gqAqXNjH8V0aZSAQR4KQOeM5+Ju5s78QpJfkzyzIPL8Rp+xOsDETHENpFW0xatGQGe/27wmZ4hybi23M2SPu9c7",
"55hmXwFIcjMTCCZouNv1c8DX5DJUACZmtQCQ7Jcyr6+VSG9uFYAqSsAvPkrA30OWOSiPCkBBZfm/fcbnIPPelZbfn0uL1hoxMNsQTjIDL2e/5QBOEJFzvc41",
"RGSliJwL5/7zco/yzgXwSrlEDjQmLTfHruki8nGReROR70VkLwDHwfsMEwD2B/BNmToJVixE5HoAA1OsshPJq8q4PX+E4xMw1fJKHQAjwioBilhk+QUAvK5s",
"P1olyU93yzup+XyVaiprAcdJxEtLnAdgjzB3+s27e8DbObAzgM/KxDnQNhCGlpHQegROStwHfV5d5SQ4mmTbjMgdWYay6XW/Lkq4/88E0AdAWqmNLy7BydRt",
"k8KczaefAOwCwHYfvi6A4STb67Kc2uJ/JoCbPF552myEQHIjANu4vPMngBfTorlWCcwGiew3EUDXKEEbRORDkjvAuQph81DdEsAXJFOPHGgihZ1v/vdGEfmy",
"hOJsV3iGpFR/WkJrHoATST4A4AEAm3u8vj2AT8zZddqRBPsbRWRvAM0KLpdmwrlO5Rd8hyn0/wCSQwGcCqALnEA7TRKqrgaA8wAcHdPGyE1BWmH5vi3Jy2Pi",
"YwaAV8yuv3p7/kJyNzje8m4boXoABpPcIuvUukZetQOwXgLFLzQb0U+yijhK8mQAd3i8MgTAUSKyap7ZrgW+LiJ/5F3TCers1zCGunLnHEjy0Gr8L416VmZi",
"r7thgc0MTnJvl/p7ZjAOIp+BFs1JMI9npHGeQRf1DJhkS5KXWGifFLHMoD4ALfIQ7IfkeiR/8Ph+SBb9T7I9yfdS9v/4juS5KY/BY0iu9KBpOMma1b6xZQI8",
"Oc+TLRZnvwTrTdw5kGRPi1fzTxHL+5eFlyc9vplu8YDuUbQFqChOgqoA5N78OsVCf5MIZQVSAMy7c1Na2N7zoXkdHyVgq7T632zaBvosiknjUxOoLOlxd5jP",
"LZdRJsZL1W8aW9pmJcm10pw3NcJ0KmJy9otgOsyFc6BZYJ+ytNt6JKMEqOjuYTJyo6E+gOaWvnwmhohgqUKdBPOzhhac/lGW520ilBXGB+C2lPjbwGce/Qon",
"mNO3llc6pqSINQIwBsAZSDHZnAvaAZgQ5UpkCF4PAvCExzr6Gpy8HdX9Xg61tM075pg0XwpAUs5+ERaLh5CRc6BZWJ+BE3rTDS+IyJKQZTYHsKPLTytgcQAU",
"kUVwTzoDQ9uzRQwiUTAnwXKEFJz+lR5zIo62sLXPVQDSiA44JsAc+hXAEZaf00rNPRD2sMJZ4JEkAo2ZI5khHuPrXQAHichSl992t3zzXNqNUysAo0Gc/b4H",
"0DmNDE1ZOAeaBfVZj87+Ff91yAuDQ22ao48ycY5RhJpYBN7zJA8WkZcKpgQUxUlQLQDB5s2mANZFCc7GIbBuRmN2pbludyWAfySkSE0CcElAer4guQR/DZe7",
"Wwq7/26I5nSZJNYBcBeAY2Lksyu8PfU/BrCf2ay5wSbX5scUzfJPAF+LyIKSFICAaXzfBbB/mgJYRKYYr9IRADpYXlsLwDskS0orbAb1cx6L/0wAu4nILxGK",
"7255PsSH/5/N9Z634e6lXhPAcyQPEpGXC2gNeI/kNgAuAvBPAKtZXq0B4GwAPUj2Ked0w4XRIpzrTZcBODEnJPUiOVNExiVlDTEm3otIXgZgYzMn41IEpgP4",
"tor3eBC4KQD1Umjriy3P/4BzVJJUOuE6cK7UnWI2f9VxNMm+IjIjhvG9F7yvCY82m2EvT37bxvXRmOfiWADXiMjTUT6+NaCzxd8zFDadAtJ4c1RNz+e2wy8k",
"N4lYdkPj3euG5gHL2CRAWNCuCbZ/4pHQ8uIkqE6Agco4NceREC8IwUdgJ8CcKmGh6S+1/0nWt3w/zyiFafH+koWOnjGU3YHkIo8x9iXJNQKU807KY78PPHZQ",
"bgReBcehLghqZjjWgzqCnW+087BmnqEe1o+pANqLyKSItHe3tN3HQTVVU7dfRLChSSoBKVgDCu8kSLIjyQvM9dF6PkrhoebdjmmTWSKPFwO4J8dD6SaSZ6iN",
"JjHsZHl+vQlalBZsR7EdShzfO5qdv23+TgDQMYjZHfYsmUnhBpIbBlpAjSf7BWU4QPtFWPzrWF6ZYhb/UnweulueDwm5QE6Ck1bZTwlIwgmISSwmFj5XOQk+",
"5PNq1XTD+2Q96Eg+CuBNOBHCngHwnfGUrv5eUwDfmHduAvAmyYfT1LVKsdIAuKIAMmCA33U4RWTsaXn+fcp0TIL7TbHdS1z83wCwuuWV7wDsFdSDX0SGIWZz",
"vw9WgxMUy18BCOvJXiCsDNjZiS/+5l7ovnEoAKbPphglYIqHEjA8ASVA4l5MfPicJyInmMn8nc/r28GJh35Chot/S/zV+Wh9AKe5vH4i/urI1otkWpEIS1Ha",
"7kI6jn6loiaA23WtTgS2o7f5aRIhIivg+BxUx8YR5/C2cBzObab9HwHsGda/QER6Abg6xaZxvRlmm7S3wXHAqoqpHp2cN7jReluAzt7LZ/GfBOeq49QS6esK",
"d1PSZBGZGHHgTzGOge/DPSzoqtjg+4vIG0WzAFTj9T0AW5C8FMC/PV6tAeABklNi5DkMdrE8b+3ybAfLuzsAyK0jJ8k9Yb8ePBbAq3BCtaaJ1QF0g7u3dReS",
"m5RwdKeoEJhAQq/DfgPuF7Pznx5Rjl1C8nY4V8G3RzyOmjtZNpdrB1YARORi44V9gHl0DYCmcLwsi4DhcGIFrDL7DxWRSwJ09ks+i/9uIjIzBvq6W54/XUqh",
"IjLVKAHvwP0ubl0AL5FsJyITij5BReQKEzHxHgBezqh7wzHhpY05luduVjbb2eHytJoz4nfXWp7/DGB3EfktI+F9GZwbSjtY5t8tusQpPMZPSyMzmlpemW7G",
"9+QSZdgsOAH2XomB5h1hP77/JYwFACJyYLXCBxVscbjIxYrhhUsB1Lf8NhHA32Na/K3mGEQw/1uUgFUJQtyUgPpwrtYdWw4TVUS+A7AXyePgnP27xUboAEUS",
"QnIfONHn3HBhVou/GRcLSd4GwM2PYsME26SR2c3F7YS6EsCYLNu0wvAi7LElZpud/+QczcXtjLXC5qfwXCgFoAJRw2d3xJg6qoNlkZojIh/FyM8s2CNysUz7",
"cBqSyy5X9ut5hG+usTwfF+nucXo8xX5zyfianItooYfD1DMGwH9E5EEdsom18ZkAtrX8PNcs/hNzRO+qo4o1La+MF5HLwi56lYbLAdgiN7UC8EFMDlndLc+f",
"j2kwrG92/ztbXlkEu9m2iJN1c5JvwLkdYJu0b+nw9t80h2z37nAPYw34px5OC7bod9/EPAbfhhO5sk0KPG0Px69Fx3RyON3y/DcAXUIGlUpa/m0BJyCcbeMz",
"A4A1k6RaAFZJP5GJJr7zSLj7AWxilIBSnQAPsTwfEtPib3MCBJyz5wNjPP9P9RZANV7rwD9SoCoAycGmRH4pIkNzQqPt1stnMY7DK+CE5U4be5K8VESu0KEY",
"Oza1PH8XQDcTHbYULALwJYDPjQ9A1LG3sZFt61he+RXODYVJqgAEUwLeMHH/h3ooAe+TbB9FCTCOlS1dfloM56pJKYKohdEEbYv/n3BCNr9R9H4yxyh+uQIA",
"xwR8LRzzmCK+9j8C7iFXgRDxNhKmcR04cSOq4w8R+TjGqrKMmXIOihF/oWj4A+4e+fubvzjH6dV+DuqW7zYw8t7mpzAHTmCib73K0SOAvyoBL8Nx0vvT8koL",
"owREyTbY3fL8JZeUkWEX//d9Fv+DElj8U70GSHItkg8aTdxv8f8STirO/iHjqCuCLTxu+EREXskJjbYgUG/FOB43gd1xOA00jjvrqQJADNbYEOhP8qGQ4645",
"nJteNmfW+XD8FHwtvWEsAIwwQc6Gc56ydcTGGQ9goIjcmeYCJCIv+1gCWlSxBIQJCNQ97gFnhNA7sMdoWLX4J3GXPLUjAJK94Hj5r+3z6kI4NzpuE5GVUCQx",
"v23xDc7LET8dLc/jtAa1tDwfDWBYzPwcCHefi01hDwAWBvMtz5tV4Fy4EkAv+B8txoXjSN4vIu8GkINrG3m/sYf1opOIjA1ScWJHACT3BvCfEovZGsAdJMeL",
"yJtpWwKMEvCSpZ3WN0rAHkGCihitzS1//YqowsIs/h94TNIkF/90ViUnzOwgeN/zX4XhAE6LIVCTwhtj4DijVcXLIvJBjmi0BSeKU47YbhOMFpHLY54H61kU",
"gLisuDbHtkMBPF5Jg9tkW70Y6caKOA2OZdNrDDQ249dm/VwMYG8R+TxopWEGT9hdXacYG6dTFjtQs3AeAnswlvXhOAYGyQhoy0b1epRUyiRb+Sz+y4u8+JOs",
"YyL9fRVg8Z8K4BAROUAX/3R2LHBCoK7CLwCOz9HY2RiAWwa62SLypXafK2yLxkEkR5HsYfJVVIoScCucMN5jU6pyS58xvQYcP7FtPF7rKiIfhqk0SSfAtWIs",
"q2mGA+FFkofCCaTgpvE3A/AhyV1E5EePorpbng+JuPN/H/arHyvMgljUxT+ok99KAHcC6B9FiVJEnhNjAWxCshMcx9hnAmZBSws2hfFt7T1rn35N8jMA7SzW",
"lM5mbr4gIodUSJs8DuBxs/i2hj1KbBhsCOARl+czPeTh6nAiBe7gUW4XEXknLDF6CyDYQBhilIBnLUrAOgAeg5OQx60DG8J+Jjk4AklPBVj8Xyzgwr8WnHP+",
"IAl8xgA4WURG6wiNZ5hHmBevI583LGwWwze0mz1xOvyvSPYgeYyIPFZB8n8BHGtrHDKuj+WnGZb368O5mr6zR7EHikikW2R6CyD4IBgM4AjYswruZlIpu6Gb",
"RXH4JGwWKVPH3zwW/545uocdhq9eAL4NsPgvhHP1qq0u/oqQCsCb2jSeMm40HMubH9poa0WG7Sj4IxeZuJpZ/Dt4yPvuJr1wJGShAHQRC+AkbcnzBHnOQwn4",
"1COVcnfL86ERaFhidr9ug+FQERlSsIV/MxPJ72H4e/gPB9BKRG5RD3+FZTxtBXe/mJnlkAArBVwIx/HZCwu0mSKNzbUsizlRLRKsSRk/DPYgUysBHFXqZk8t",
"AOEX4GcBHIX/dQxcDqCPpdNrwx48IupifaZL/YcbK0VRJoM6+SmSgC36nwaDCibf5opIN7PRmW3ZaDyjLRUJh8L9qO19EZlbRTbWNGuD7SYLARwnIiX3g/oA",
"RJskT5P81mjLywDc4uFdvDfco0pNFpHxEev/gOROAevP4+KvTn6KpGBTJvX8P6SMA/C0sai0ArAVnHvxQ00GTkV49PDbCJKsAcfhfD+Pck6NywdDFYDoE+QL",
"YwnwQ3fL82dTqj9PC3+lOfl9AWAp/hpQxC3r44cATq327E/Lu4rwFgA9/48mZyYAmIB0o+OVHYwnf2evtYCkAHjCY80AgLNE5L646NIjgORxsJ/WVyEToOKc",
"/ERkNhwrTVXfkBcBPOry+qPmt1VYAuBcEflDp1DgMbY93K8fTwkSrEuhSBDd4e4IPlZEfjL//TCAwz3K6OsRFVctADkUSO3hfl1vTs6ipiXZBhUdyU9EBpC8",
"D8494im27F8isgJO0JWmcILYjBeRxSmSaruNsjVKTFSVImxpT9X8r8ganuZ/koMAHOvx/WUicnPcRKkFIHmtzw0vVMDCr05+/13cF4vIZ0FSf4rILBEZnfLi",
"D7jfLAGAXiTrFWC8bQPgYlUAMsN8y/PVMqClbgj60hib9QB0ta0FJAcAOMWjiJuSSvusFoBk0dNL6yuHdd7yvDWc2OJbBCjjPwAuUSe/zGFTANoCmEnyEbh7",
"hecBG8NJ3mLD8JDlrXB5VrNAfVkjIE9xwhYyt2XKi+26FgVgbIb90RXujuBT4IQbPsvj2ztE5MKkCFMFILmB2Noy+BcDGFXm7LcPuOCcIiKf6WjJhZViEsmR",
"APZ1+bkhnKunRcRDIjIv5Dc/4q9Hd41Ibpf32zYkdwDQyOWnpH0gvrA8P43k3eaIKw2cFZK+NGAz/68FoK/Hd3eJyNlpa4qKeLCv5fkwEVlWJjz+FOGbqk5+",
"uvjnC8cB+K3MeLorxsXs38avJ6+LfwcANlPx50nWLSJfW37aFsBHJDuZmPpJ8b6j8bX5Z54UAHOt7yDLz408Pn1URHonTV8YC8B8y/NRJGNrL8vzU0meGgOt",
"aWJby/MhZbRr/JbkTATPGT4MwBki8ksB2bUtjFnmS29ueb4gYn/OInkSSryimiPcLiKfRPjOtss/CI6jpt/3YeVVKQgqf9NYAK8H0M/leTsYR9IY14ow+AZO",
"SN0ssDccC1oYPG2U8cQRxgIwLo01JaZyxuRA+Hzj8mw2/MNsFg3vBnhnlZPfgQVd/AH7GeKhGdJ0eMgFLIgS8JwR2F8XfFzeJyLnRvz2cQDTy2iO/gznfnnS",
"6I9sz9rdsBxOfpSsrK49Qr4/BE6I31Q0pcALrsloNwWlp/ntYstcRLILgFdLLH8WgE3ycH+a5ENVNLmFAI4uYqIeHx43gOPT4JbPumwi+ZFs47GwvgbgHqTn",
"JLcOnMxtttsVW8cR957khXCOsnaFu2NV3jDJyI/bROSbEnnfA8BbMW5KssJKALtGtIREabdWRgmokxP+LxKR6zOUG78ieDr7F0XkoDTpk5DMnAbg7hLr3EFE",
"xljKbwv/dJR+OFlE7s/RwrEdgEYi8i7KFEY5vBGOR2sD8/hrAH1E5I0y4vMLANvnnMxPRWSnBHhvB2D1nPK8CMC4uK9OkjwHwG0FH7Zni8gdKc+THY3FoVWG",
"fC80i/8dGcqLzQAEDZs8UkT2K4IQvJ3RMc2n7HokZ5ZQftEnazkskjuQ3LBMeduJ+cZKktvqKIzX8kNyDIuHL0humWG71SF5I8kVGfD+HskWORg7ewek93WP",
"VPK5nBSdSD5DclpABheRfJPkrgHKbk/ybZKLA5b9k6Glo4orRQpj/4EcC/1B2kOJ9XsPs/n5PMf9P5rkLSQPzlG7NSV5JMn7SE5KiO/5JIeS7GOuX+eF9y0D",
"Kiv1dYYpFMVYCBqTfCmHwv9FkmtqDykUuZIXb3jM2c9INtBWUiiKN7GPIDkrBwv/LJJHao8oFLmUExuQHOkyb8eSbJI1faJdpFCUNMG3gpMrfQuk5ym/GE5m",
"xYlxePsrFIrE5cRuAI6Gk+hrHIBrNNOnQqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUisjQWwAKhSIQTGS55ilUtQTODYf52uoKhSoACoUi/QV/",
"DQD/gJMM6G9IPxfArwDeAdBbRGZpjygUCoVCkfzifxjJGTmJcjjdZOdTKBRqAVAoFAku/s8jfB7zNNBTRJ7XHirceGoKYIMqf2sCmA7gF/M3Je5MjgpVABSK",
"NIRbYwDbAKiRctUrAXwlInNj5uciANfmtLnnAthSjwNyPycaAdgHwAEA9gXQNMBn4wAMM38fichKbUmFQpFHAXcSyedJTsmBeXwyyedIHh8DX61ILs15mtsR",
"OgJzOy/akRweQx/PM1kN19ZWVQuAQpEXAbcZgEcB7JJTEt8FcJyI/BiRvzEAtrP8/B6A0QDmp8BHQwCdAbSx/N5SRKboiMzNvNgWwDVmxx8n/gBwO4AbROQ3",
"bekyE6YkTzd/m2mLKHI+Xo9jcdArAn+7e5TXPaM2f8VCTzcdkbmYEzVJXkVyRcLjeQbJ9tri5TNwDiK5rEoHLyN5kLaMIqfjtQim8apYau7sx6Hg3JJhu59t",
"oelfOioznxPNSX6Y4pheQfIKkjW19eNDrYzqvaha3bXMs6HaJYq87XIAPAOgToHIrgPgKZJtRWRFwG9sVrjPM+TjA8vzujoyM50T+wJ4DEDjAK//BmAwgPEA",
"5pi/3wGsbb5vCmAvAHv6lFMDwL8AdCR5uIhM154orgKwVcBneZ4EfeAESQGAq0Xkrkqqv4JwCexn0T/COXefDIAp0yUAWhrB2cLl9+0A9AdwRcDy1rE8n5lh",
"24+HEwyoOm2vpDjPdgdwJZxASPULMmYXAfgUwMUi8mHM7dEt4EbtMQAPi8hrAd69wtymOQjAhT5rwe4APiC5k94GKa4GOdfFxDOnQPT3c6F/YIr1D3Spv6+O",
"rETa2hYM594c0fighcZpIcq4x1JG54x5243k2yQXkvya5Jkp1l2P5K8sLmbG3B5bklzkU+fzJFuVUIeYIFQTfer5hGQtlVCqAKRNe02SSyyDcmAK9Q+01P2H",
"no/F3tb1bVfvckjrTxZa6wX8flAeFYCM23R7Fh/bx9QWTUj+7FHPYpIHx9j2tUg+6cPboyqlSkMNbYJYcUaSSoAp+wxt5tRgOxf/Moe02mhqqd2oKFHu1AHw",
"Mpwofm6YDaC9iAyOq04RWS4iR8I5xrIdrx1D8kLtIVUAUoNxqrosbSUgwOJ/eQiHL0Uw2CKYzcghrTanqHW1GyNjIhwfhKJiloiMiaGcCwC0s/w2H8AuIpKI",
"s6iIXAPgVI9XbiC5sQ7VaNAzlGiD8nqSLTwW5DNIQkR6p7T43yUiN2nPqIKcVx5I7mgWkfUSKH4hnNsKn4jI7zHO8yUke6K4ToD9Y+i3Bvivs3F1LAOwr4j8",
"kLC8vY9kawDnWl65FMAJKq4KgqI7AVZdmH3OqAYWoQ6Fte27WNr8nhzSWtIZfhI+ACTbk3wv5TPv70ieq6M3tnHV36Otj0yRDiH5soWOZSQ30t5SBaCslABd",
"/FUBKKICQLKhGbsrM3R++zRsMCSFa19Ot7TvsAxoaWycDd1wnfZWeKgPQOnmqd4AvO7gR/IJCGj27609oMjZgtEIwBgzdrPMNdIOwASS+2ivRO7LtgCaW36+",
"KANZOxeALTLl4Sm3TR+Sv5i/MzLom0zrVwtAgrt13fmrBaCoFgCSj+XtLjzJhjqaI42pKy1t+liWCibJ+Ra6tk6JBo0DowpAMgu3Lv6qABRVASDZLad34R/T",
"0RxpTI2ztGeHjOm620JX/xTqLqs4MHoLIF4TVW+SQMTbAWr2VxQcF1ue/wHgNiSXTrgOgG0AnALA7dz/aJJ9RWSGdlHghWZD06bVsRD2HA1p4WUAp7k8PxjA",
"1RnSFevtrwjrg1oAimoJ0J2/WgCKbAHwiJo4L00PbZIvWejoqSM6VDseagv1mwPa6lfLJvv/GQNTqr9f2rI6wPoQ6QhAnQATsgQghGOg7vwVZYCdLM+vF5Gf",
"UqTjfMvzDtpFodDE8jzzKJgisghOIq6/rGck10ih/usBDPCR7wNiXPwH+KwPA6LGgdEjgASVgCDHAav+Wxd/RcFhS+f6fcp0TAKw3EW27a5dFIsCkJfIiDMB",
"bO7yvDGABSnI9z4mGZFNdp9Fsmapsjvg5rBP1PJVAchYCfApQhd/RVGwvuX5/JTn3AqSfwBYs9pPGi62vBQAGx2NLdaBzDZ5UWV4GpbhGiEJOtek5CwJANZy",
"67gYvH2/zlsUsADHAYVZ/OPq/wSRu/5XFBskdyf5lklHXBQsNDTvWgLrts3h4px0jS3kc92cyfdcx4GpFYKgLgBuzfl83RrArSS/FpFRBbIEFGHx1/5XVNri",
"Xw/A87Anhcor6sM5khkCoFnEMmZZnjfLCY/NQtJdGEtAmj5hYSwAnQo0AdrnjaAQloC8mv21/xWVhlYFXPyrYh2S20f8dqatzJzwZotQmMlVz7gsAWk7hJfr",
"LYC6UFQytP8VitKQdwXAzQKwTER+y/Emz1MJyOI2WBgF4PUCDd7c0RoiiMMZOb3zr/2vqDRMRH6c3qJgloiMifitje+/5UCWNgOwrstPU7OmLaoSkNVV8Boh",
"GBsF4DwA43M84McDOC9v578RIjjlTgnQ/ldUGkRkCYCeAN4GsKhApC8yNB9cQhljAPzp8nx3ko0z5s+W+Gd0TsaNxoHxWRDLOhJg9cW/BG9ejf6Xbd9pJMAM",
"0gnH0BbzXOiYqyM6dDuOtPTpaRnT9baFrmNy1n63+8j324O8kySNGgkw253/XUjgColCoVDEgKGW5+eTzCTVs3Fq3MPlpxUe9GZlCTjHR773MX9eO/9zVAEo",
"08VfRHondY9UoQiJ+ZbnzbRpVAGohi0AnJoRTTZZ+Y6I/J63Bsx7HBhVADJc/EMMElUCFEljnOX5odo0lQkRmQ4nDoIbriBZP2W52h3ALpaf78hxO4ZVAso7",
"Amw5+wCUktVPMwLmri8ryQegtce4G0WyB8mmSdUfc1uoD0B8bdmS5HJL3z6eIh1rk5xmoWN0QdpyoPp9lbECEMcCrkqAKgBZKACmjE8DCKjnVQGouHlwj8d4",
"uCCF+muR/NiDhl0L1JYDK162l6MCEOfCrUqAKgAZKQBtA95OOUYVgIqaB819xsPBCdf/hEfdw8pkrRhYSQOqrBSAJBZsVQJUAUhbATDl3B9AAbhBFYCKmwu9",
"PMbDCpL/SKDONU1SIxtmkVy/oO15ljnSmEKyd6UNprJRAJJcqFUJUAUgAwWgMckXfcZdf1UAKnI+3OwzLh4jWTumujYl+aNPfYOzuo6oUAUglQValQBVANJU",
"AKqUd7jZYVXHcpKbqwJQkfNBSL7mI49+IHkCyVoR61iH5K0kFwU8jhqkSoAqAGW5+KsSoApAVgpAlXK3Itmd5MUkLye5Q5r1Z60AkNzdmKEXsjhYaGjeNYG2",
"bUTykwA0TCZ5Fcl2AcqsS/Jgkg+RXByB37tUWkVDLW2CSJOgH1KM3Rww3/QkEblJeydWrCgDHlaWOPYmAJgAJ7d8pc3zenDuwRctJXB9AHuaPos1kJOI/EZy",
"DwAPADjS49UWAPoD6E/yJwBfA5hj/n4HsDaAJubfXQDUK4Gs00myrO/OqwUgN7TXJLkki924jyXgD5I1dXTF2t4tLW09JIe0vmShtUWRLRBZWgBIbs/iY/sE",
"2/mfJFemxMdMko+rJTReaCTAeJFoBKcSwkoqorX3ZLiHyN0+h+Ru5/JsnohM0Z5UJDQ/rjG79yQD8awAcDeArUTkaAC3ebyrEVPVApAK/f2y1D4tloC+OrIS",
"aevXbc5HOaLxQQuNr6VIww0WGvbPoD3czpEnRSinrtl5FhW/ptTeQvJYklNjpv8tklu71HerWgLigfoARNN8rye5EMA/ASwDcL2IDEyx/t4kx2dVf6VZdQDs",
"5fL8FGPefhfAZABMexgCaAnnrLeFB+1pYazlecuUF/91AdQNQZ/XPFtCsieAKwH8Dc7ZehGwCMCncM7g05BHBPCoiRJ5MYC+lj4Iih8AXCgigy31nWd8os71",
"sARAfQLyu6sa46K1jdGWUeR0vI4o4O7v1ZTbyJZLYGyavikkr7bQcZmO5NT6YHWSfzc+AkNJjif5m6VfZpgwvw+SPJVkmxD1qCWgoAPkIpfOukhbRpHT8bpB",
"iHvJecAikutl0E42fEqyE8k1Eqx7R5L3edDQTUdy5vOovrlWuivJljGVqUpAAQdCDZLHm3vFl5M8iqQ6JCryPGZ7FUgBOCajNroup+0xMa4IdYpczk2/OCm3",
"aispFIpSBc02xqSdV4whuUWG7VOT5Jc5a5NlJLfR0VvxSoA6SSsUipIFTW2SV3rkSM9qkft31PCrMbdPK5JLc9Q2/XTUqhJg4qSo03s1aAxlhSK6wFkfTpS4",
"NTKYS4QTo2C2iEzNWbvsCOAJAK0yJGMhgItE5A4dqZWlBMA9YupCAGuKyHJtJYVCoUhWENcheaNJFZs23ksrAqKiMJYAPQJQKBSKlIVxU5JHGg/9SQkt+PPN",
"dbM+JFtrqytInkVyGskpJDUegEKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUiqJBIwEqFIpUQXJzAMcBWBWjfxyAx0Tk",
"G22dQvTfBgC2NH9rx1h0bQCbA1gTwFQAUwD8AuAlEZmp/CsUCkVxF469SY7wCOgzgmQXban8Km4kP8ogsuNCkocq/wqFQlGsRaM2yeNCZlH80nyjKXzz04/9",
"c5DY6TDlP17oEYBCkbzw2BpAVwCbAmhe7Q8AZpq/X82/PwN4W0TeiVhfEwC3ANjHPBoBoK+IzE2R57XgJGU5C8C6EYuZDmAAgIEiskBHUmbj92gAj+WEnCNE",
"5GnlXxUAhSKvArMmgD0AHGj+NotY1AIAr5oFfLiIzApY/30ATqr2eKCInJkC75sAOB/ACQDqx1TsIgAPArhFRCYVfGzUB7ALgPWrKIAz4Jz1fiwii3JGb3MA",
"3wBolBOSVgDoKSJDlH+FQpGrhZ/kSSR/SsD8t4LkwyQ3DECHW9KdiQnz3oHk4ISz/60g+QLJDgUbF0LyaJKvkFzqwd8SkiNJHkFSckL7v5lPHKX8qwVAociL",
"kD8EwFVwPIOTxFIAAwFcLSJzLLTMg+NJXBXzRKRxAnwfCeA8AH8L+enr+K9Z9RgAnUJ+/ymAW0XkyZyPiz0A3A5g+5CffgHgbBF5P2P6Xwewl8tPwwE8B2By",
"TFVdAOCAkN8cIyKPK/8KhSIrAVmf5EsZ7AAWkPwnyXpuCoDL+3Nj5Hl1kueRnByS5mUknyC5rUuZ25J83LwTBpMNLavncGycR3J5CX28nORZGVu0Flu80mvE",
"XNcgSxvM9WiflSQPV/4VinwIvK1J9jSC7xaSz5mrXXeQPJ9kN5JtzDloOfC7EcmJGZsCJ5JcPw0FgOR6JG8kOT8kjX+QvN3cn/arYwOSt5L8PWQd8w1tG+Rk",
"bNwZYx//JyMe2lnoeS6BumwLYC+S033ap5fyr1CkLyAakzzZ7OpmhBRqQ0juUmDeO4VcCL8mOYDkmSQPMIrQ6uavNcmuJE8heS3JMSHbcgbJ1kkpACR3iLg7",
"n0nyEpJrRKhzDWPhmB7RyrBDhmPjggQUvfMy4KOLhZZ7UlwAO5Pc2Ee+JLITrnT+FQqvhf9qkr/FINjeItm1YPyfE5C3V0keSXKdCHWsT/Jskq+HOBLYLS4F",
"wDiuHWj6Jyy+I3k6ydViaOs6RsmcGHFsdUvToY7kfkYgezn6PWecy3qavytIPk/yTx8hv08lKgDm9yCL4LHKf/ksMn1I/mL+zlD6c8PXZcakGzfGrRrsOef/",
"HwF4+ZbkATHWuSPJoQHbcd9SFQCSJ5L8PkIffpJksBaSh5B8PwJd35M8OYWxUYfkLA86PjdhkG3fb+UTMGkqyTqVqABksQhWOv9ZCtmBLsz1LRD9/VzoH1jw",
"PmlI8uWEz7NXkryeZK2ctsH+AXjok2D9OwRUBH6PogCQXIvkVxH6bajxdk+rH3Ym+UwEOseTbJogXWd51H1vkHFtIic+4FHOqZWqAFRZBH9JYxGsdP7ztPiv",
"ciSqWQD6axozH8tFCSC5ScQdYVR8RrJFztpgSx/LxySS26RES08fczEjKgAjQ5Z5P8lWGY/LgSFpfjtBer6w1DkhzM7dWBLG26wslawAmHc3SmMRrHT+87T4",
"l4sCUDglgOQWJOcEFK7TSD5kzOQnmvPXrsbx7VqST1uC1LhhDsktctIGTUj+7EHriLSvoZHcI6QPxlyf8rYK4WtwA50IachR/1wZYpzunAANa3s4JbaJUN52",
"FqfLlUlaMarR0NnC090J1HWFpa5zPJS/qT79fKTyXx6LfzkcARROCSDZjOSPAQTqbXTi3Qct92CS7wUodwrJ9XLQDk960PhChnS18TlzDqMA+HmuTyV5IclG",
"OR6v9YzjpN+Y7Z9A3Qda6nqlhDLfsJS5XxkqAD08rIH1Ii6Cf5BsoPzbUSsnE3cgnMQhNtwlIjcVRQEQkeuNCdvG0xkkISK9cyxMGwIYBaClx2uDAFwSNEZ9",
"lfYZDGAwyXZwktbsbnl1IwCvkdxNROZn1A7bAzjC8vNYAEelQMPf4UTac4uf8BSAE+Efd58+v9vuz08AcLOI3F+AebcYTvKgAeZu9J0A3CwzGyZQvW2ejCmh",
"zDEA/u7yvAXKD7Z2agtgJslHAMx2+f0ZM/7dFNMGAFoD+ET5L+7Ov7DOc0XmjeSDHnQvohP6No56apC8lN4R057JsB1sXuezqwfgSaj+x2Lyq/jNp55/+/g3",
"9GEBAjjRicx4lo/Pyk0J1Htz3GZYEwTGDdeWmwXA1DcsAX+izsq/HTUynqxBdv69UVAY2u/yeOWMPCoBJHcHcLzl50UA2ovI8zG10UoRuQKAl1nzUJKdMmiH",
"bgB2s/x8kohMTbj+lgCOjqk4P1PoeI/fNoYTz346yevycCzj0lbNSV6H/6YQ3tTj9a+SmO6W50n4LdVBeeJkAL/HXGYT5T+HCkC5L/5FVQKMo+W9lp9XAOgm",
"Il8k0E6vwkmGscLyyqA070Ab3Gh5/o6IDE2h/nVjLKsGyboe7f80gB99ymgEoB+AqcYvYvscjNc2JB81C38/+KdtnSoiDyVAyq+W56VEJNzR8nxGWuIrzHOS",
"55qIlystzotfkzzXYwzOgGPOZow8NEmL/xhkYN74T27xL1ezf9F5Nt77NqSRT/5fHvWfmGI77O1Bx/Yp0dA4QvhdqxNfgPq2Msc7YfAmndDGkvI43Y/kayFp",
"XUKybcrz5vUSynzHUuaxKbVx4GtwHu+6oYtPvX8zykIc6JYG/zG3ey7418W/Ank3XqdueC9FGkZ7eMR2NH97mt3fugnRcIuFhkdS7o8zfa6VBsGyoEcoJtDI",
"IxHq+IbkaSm0x0nmXn1YPJPktVI62Qxtbb9dhPLaklxhKXPzHCoA14Xoi8sD1F3b3Dp5nU72vSx8ADJRANLkv1bKwqwizP4eJp7eJIGc3g4wXvm2HdLJKZJy",
"HIBxLs/bAnjThW4AeBfAawCeFZEJMdBgy08wIOUxcyfJBwC0AVAvxKf1AHQCMAfAABH5I2B9PwLoRfIiAH0BnAJ3T/rq2ALA3SSvgnPkNSDs7RCPcdkEwFkA",
"egMIk1dhCYCHANwoIpMS7qdxJL8DsLmLjH2SZBsRWR6Q3zoAnob7Ee14Efmu4KKwboD2XAbnCO5Gcyy5g884vADOEWK5rBXlxX8l7/yL0hYk77PQ83AGtDxa",
"gtZ7D8m1Sqh7fUu581FhoJOV72KGz8q3pNRIgSRbmQhpi0PWPdsEVmmSclv19qBpUMBQwLVMMC0bTk+Rn0yOACLSOqicLAB54F8X/wprE9oTTXTMgJauJZq9",
"Z5PcP2Ldp1nKfBwVChOe9hRGy8r3chihT3IvcyVqZch6fjSBgOpl2EY/edDnlwxoc/OO13XMminyE2oB9HECXOHnBKgKQBkqALr4F6NtTNQ/V6GTYfv8yNJx",
"fYR677SUdQwqHHTSBHcn+UGEvhhL8niStS0732M84ul7YTTJI/IQKtzj7n5Vy8gLJu5CD5KHmf8eHMDX44iUeanoBVAVAF38K6aNPLzeB2XYNu1j8oR9JmS9",
"T1vKaQNF9f4ZEqE/ppPsTyf7YCM6uSOmRihnJMm9cqgg3Z9AQJf7M+BFFYAy579WggRVtMNfUOTIMdC2uE3MsG3eN9H2ugGonnymBoBtAewM//vyh5LsJyJB",
"rQFrW57PKcjC3AROiOV9zKMRAPqKyNy4+wfA+yQ3A3ARgGMRLEhNcwBXmb+wWA4n/PG1IjI+h/OZJE82dMaVuvcuAGdCoSiIAOqnO//YLQF9E67/hqKavUlu",
"SPLyALuobQOW96Xl+9oFGUtuzpx3Bvy2cVRLx6pofCTnJ7AD/p3krVGjEJoro2ul3A9n+4S49sNyWrLBqQVALQC5tACYc7h/684/dkvA5SRvFZEVCZGwMuTz",
"PLXdz6Z9XoCTHMPmeT4AQMeIFoBF5mpOEeBmFu8UYO5eumruklwMJ9nTDSIyLWA/zABwkbkKeBqAc2FPMhQUM0y/3SkiC0LKog0AXAjnKmM986y/iFyT0rgc",
"QHKMoT9sLIAvAZwlIu+hQKCTqngrxB9ldiWACXFdLVUkOwi8ooldqy1kbbdrvXZACdd9laXewwrYjm95tONBAb7/weW7bwvE/58u9P/k800njzZ7OKj1pFqZ",
"tYxT3LgIu9+J5tZBnQj1bmtotmGvlPtDSB5tbkMs9XEQHGkcGiUH4yjMNcCaJIcyeQx1c/ZUC0A0/pPKBeBlAbhIjwBcO/B2OOeoNlyWMAk2y0LtAjbncXCS",
"Frnh7ADfv+Hy7LWCjKPGlj7zix/vlXSoF4CxZgELvHiKyHIReUREtgWwP4C3A3z2AYCDAWwlIveKyJ8heN+L5Mtw0jT38ng1VW96EaGIPC4iXQGsZawxvQD8",
"w1goehmrTWMR2VdEnhIRFmzOHQvHVydpdDN1KWJArYQG/PUkWyCnEe9yKLSDOEzekjAZNjPvNkVrTxGZYu4bu91g2JNkfRFZ5FHExXCc2fY1itFIAJcUhP3m",
"lud+CkCQ4419AOxD8gsA14nIMyH6ZASAESaPwqEA9oRjKq4F4GsA7wAYLCIfR5g/hxnlOWjinT8zHJuLLApm0bF9mdalKGVhU2fAYrQRyZ0t9Y8ocNvajqL2",
"L+PxtFeU65wm6t7vIc2xk0zQpHoZ8FnP1B02VsQCkpuodA7UxmGOAC5nerjcpX49AsjREcAqbbdQqXBzuvNPy0oyzvK8Az3SyOYcH1mety7jYbVDFAuAiHxj",
"rD3PhahrYwB3A5hG8tI0Qu+SXJvkFcZidTeAliE+fxbANknnBahQPAf7MWKcWAHH0VcRAxJPBpT3BDi6+P9/Py0yjm7VM6Y1BHAQnOQkRcOnAP7u8nyNMh5a",
"+1qejwkwBqbAiZnQAk5ykRMBNAhQ55pw/H76kXwQTvKdKTHPlxZwzstPAFA/xKd/AHgAwC1x06T4n7HzFcldkHxCmmF5jP+gCoAqAYVd/KtghIsCADgOYkVU",
"AEZbnq9epuOqHtyvOa7yYwg6X6cA6EPyX2acng0gyP37+nAC1pxO8jkAV4vIuBJ52hZAfwA9AYQJ9TsNwH8A3B32+mAJtG4E53y6GZyshXE50C4D8CscK84Y",
"c+01j0rAZwA+02VVFQBVAoq3+AOOSfVcl+cHkGwrIqML1ty2iH4LA/RTIwB9jLXgDQCLQ9S7CMBYEVmSMr9dLIvkuyKyOMKcXQDgOpI3AzgKwPmwR4ysipoA",
"DgdwOMnXjUXglZDzZB84XvJhr+x9CScK4pNpxG0w4+R8AD3gRKZMQ4aMhWNyv11EftNlTFGoBbBSHQOLwDvJzzwSudQoWHvfa+Glj893+5YYwY0mhe0pKfP7",
"soWWf8RYRxePerwwxtyFr+lR9qqEQF9GzAvQOeX2PofkXGaH2UlGCtRIgJoMSJWACuOZ5BkeNN5YsDYfHSW4UYyhbJeaHWIavHb0oKNNAvVtTfJBn8A2bphi",
"Fs76Vcqqb1LJTglZ1hKSD5BslfK4akByFPOD4UncxFAFQEMBJ4JKOw4oWGKkB41JczOX3/qSHCMijxegzXeF3SP+Q4/v6iI+J8E6cMISf5oCyzdZnn8kImMT",
"mMPjAZxA8mI4PgJnAQii7GwE4DYAl5F8GIDACYQTJk7/fAADAfxHRGamPK7WAvAu8nWTZD8AH5PcU0TmZTjnGgLoigRDAcNxAlwMhe6KlcfEaPZLw9sx521e",
"3+N++OgA3y+PcXfWKgV+e2bdV6bNzyL5fYI73e9I9s4i7oDhsRbJD5hfvEeyVoz8hokD0JTktBR4/MXNqqYWgAJZACrFElDUlMgmDe/tAGzni6+a9Lq35rTp",
"b4b9fvhdAb5fBOf6Y6n43NyvT3KMbQDgDsvPo0TkrRBl7QvgWjhX/54AcEfQ5Csmwt0dZsx3B9AXwK4xsfm+6dMhYUPkkmxu5uBRcK4E9hORVyPSca8PT5MB",
"vAknsuHXAOJyAq1rLA6t4ThFtrC81x6OI+/JGcy5E+GfljsOrA8n0VShjiMVFWYJKAeeSL4b4OxxsxzR28CSCncVfgxYThDHrt9J3m4ioLn99Us6/SzJuiTH",
"e9DYNkRZrUgudCnjQZKtI9LXjuRzJFdETIX7DMl2EetubWivjj9IbhGhvK5+8zmNgFmmz/1ky14x1RXGAvBUipaOh9QCkDz/eVsw+xZo8e9XDgoNyTWM978f",
"njJBQLKkdfcATmTHByxrXkBBNIPkdhny/JIHbS+ELOs2H15fJtklIp0tSA4wi29QxapFCULb75bCzRHK9TL9H5BB3x/oQc9rMdURRgE4PkUF4HhVAOLhv1Ze",
"GAhwHHA5yVtFZAVyDHPNySsb4l1FOdIQkQVG6H/sYXYE/nvnew6AUXCizv0KJxjL0oTIqwEnx/pO5s8vvvswEXkoZhqaAfiQ5NEiMjjFMVYPwJOwR12bAe+j",
"JxsvXliVCGgsHHN84Hv2JrDQ2SQvMebbgwFUVxg/ADAYwL1hA/eQrI1wcQrWDln+5rCb/q8UkWEZzM2XSF4D4J8uP3ciub6ITE2RpEdNvyadEfBFU5ciBtTK",
"EzEBlICi466i+TOIyEySOwN4AcBuPq83gZNq9YicsTHWKClJoB6AF0heB6C/iKxMePFfF8CrsGdpXAxg7wje8fcE7Lc2AB4GcC3JAWZMLwg4lhYAuAHADcZc",
"vhUAisiYqBYqhItUuAoPhqxqX49x9e8Mx/WlZtHdyuW3A+H4A6QlJ1YAOIhkUyRzC2AFgIlBfVIUBYblOKDoRwDlcKPhOhYPY0muF5LPeRbT9DKfusaR3C3B",
"9m9HcqZH/StLyXRIskcET+5FZr62THEctjR1LgpJ61SS3SLU94ilvJNyMCdPt9B2fwxlaxwA9QHIjKGzjDCaQrK30p8bvtqS/Kggi/8bJBtE4NFNAZjrc+76",
"PymU47z+ZzLg3ROg3gtiqKs2yV4RovEtJ/lsVKe9EApQFKfCLw1PtSPW+3apTpYJtskuFtpeVwVAFYDCKgCK3CsCPUj+kNOFf1Ypi6FNATC/7UDy54B0vEuy",
"LyPmnyfZnGR/Y31IfPG3CMAoYX/fN+NDYqBBTFnvZxUemORkl7JXxHnnvgTa6lt4/0EVAFUACuMEqCgWROQFOGffPQF0BrA3nPzwWeItOL4K9yaViEdEviC5",
"PYAhADr4vN7B/N1I8isAwwBMAjAFwFQ498ZXwEmnu4b52xDOXe/OcM/MWB2/AThcRF5OgNdRAEaR3BpOKt6j4EQ39MNu5u8HkrcCeCBs9DYTKvhEOMmpNg3x",
"6VI4MQyujzEGg1tkyAUisjwH83ARyflmDFXFWiqlFH5QBUBRqgB6Dk5mMpDcGMCWRhit+lstKaUXwDwAswBMB/BxWiFCRWQOyb/DSTcb1GF1G9gd96JiMoDO",
"IvJDwvxWD/t7OoDGAT7dFE6QoitI3g1ggIjM8LN6hKxjFebCCfJ0uzqKxQabc2ezHNLaPCQPyr9CoXBdhKxHAC7v7kHyi5SPOBaTvCaKf0NM7RM17O9SE5xn",
"a5cyoyYXSjw8cJjxkPfxGqGfbf24eo74b0Dyz7iPaSqBf4FCofiLQMVfTarzRKSx5X2BYx6/CvYQxHHhWQAXmrv1eWirQ+Dcvw97+2EknKuHYnb7+4T8/gMA",
"N6URfyHseMj7eA1Z9gQ4Vr3q+BGOBWxMxuzvbMaP27z7SkS2Vf4VCkWYSe/m3PhtgO/qkDyf5JwEdv1jkrxiGEOblRL2N5XwwGmPh3Kgj+Q/WFycp/wrFIqw",
"k/7eUuI4kFyNZEeSV5gMbX9GnMBfkbwq7QWvxLZrQfI/AcP+BkVJ4YGzHg9Fpo9OBsTvCrj4/UCyhvLvDT0CUCj+OunXhhPudl84XvojAfQVkbkRy2sAJ/Tt",
"ZnBuSmxq/t0cQE0AM+HcCpgFJ4zvDwCGJu3cl3AbrgGgNxyHvqhZ4qYCGADg7rDhgfM8HopGn7lKNqpgQ7CTiLyh/CsUCkV2i1NtkscFTCpV9bjj2KiBexSJ",
"9OOFlWz6rnT+FQqFolQh2sVESbRhWNSMg4pU+m+LnEcB/ZQJpicvR/71CEChUKS9kDQA0B5AazjxHL4G8IGILNTWKUT/bQDHM35LhMysmABmA5gIJ1HQL8q/",
"QqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBSKSoQ6ASoUilRgAvmsA6ApgF0BHAvn3vpjAD4G8CuAWXkJc1wir63gZILcsMSifgbwXoyZDRUKhSJzAbkWyTNI",
"7qmtUbZ9vA3JS829/rAYTbI/ya0KxvOeCSWH+oJkex1VKv8UinIY/DOqCLdvSK6vLVM2i/71JL+NcfGbSPJatyyCOeN9/xTueu+jo0zlX1wQC4FNANyC/2bo",
"GoHSQqF2BLAHgA3g5FJuBscUuCqv8oxqf98DGCkiE3PciS0AHGraqDmc3OWNASyFE8p1suHjIwCjROSPkOU3BNAFjql0EzjZnjYFsBqc3OdzAUwD8AqA54tk",
"NiX5MIBe1R4/KiK9VDwUVqhtBicb4mFI7miRAJ4C0F9EfswZ/00AfAOgScJVzQawuYjMV/mn8i8pAu9z0TzvDPF9M5InknyW5PwStN1vSd5kzGo1c9I2h5P8",
"MgIv75I8P0D5F5gEMlGyxfUowODf1IOHTXQpLdzCv76RF8tTjHi2jOQ9JNfNUTv0TJH/7ir/VP4lSeQkNzNcgO9aknwsoZSgU0xM8RoZtUkrkm/FwMd3JA9w",
"Kb+bJa1nWLxGcuMcT4BBHrTfo0tqoRb/I0kuyjD06R8kD8mQ/21M1seOJB9Oke+HqtS7jco/lX9RYTsCmAdgzWqP54lIYw/z12UATgNQJ2GaxxsT4JAUO+04",
"AA/FXOxIOF7QNQA8iv8et8SFo0TkyZwN/nWNadA2Rv4EsL6IzNblNfeL/z0ATk2qeIQ7RrhbRM5Iie8rABwFxxwdBH0BjI5YXVsANwV89wcAj4nI5Sr/VP6V",
"Sug8F+1krst7DUheRvK3DLT/l0jWTaEtbkqQhx9JTk6w/GtyNgFuCUDzTVDkeeFvGSKz31iTq35xhLG70OyWxoWoq2WCfDcj+U4EPrqVUGePCPW9SbK5yj+V",
"f4kqACQ3Ivl9xtmPviK5UYLt8DiLj0dzMvjXCGguXmRyyedp4p5E8kWS15BcvYIX/0MCKvtvkWxrvvnQS0CTvMFrMTNltA1ofv6N5IEJLf6/Rpx/vUuo95yI",
"dU4n2Uzln8q/RBQAkm1Izopwj/UakieT7EqyNcnVzV8bkgeSPJPknSQnhCh3vrllEHcb/Ctg+sWrzfWfrarws7lxXLyc5CclDN6PjYVlD5Kbkaxryt/a1HkN",
"yc8ClHNxDibAFSH4vixHi96dLo6pG1Tg4n9EQEesfap809nnrFbM39se7+1apbz9jNLvh8Nj5v3lEubw8SUqnlExIgX5VxSo/ItLATCL0e8hHDLOiuKtS3Id",
"kkeZMoKgT4z8+5neZplzsaDlbUsnsElQjGaIACgkjyc526O8lUnsjELQ18AypmyYl8bxTgC6O1jom1RJSoDZgS/x6bMbSEq172y7/59INqry3lrGyddqBajy",
"bg2SN/rQsoTkdjFaf0pB5xLq3rvEunslJP+KBpV/cSgADB7o4hmSbWKk50AGCyzSN4a6mviYOYeQbBqx7HMD8HBWCWbK4R7lzs3KtESyr4e5y2YWOy8HC99x",
"Hu1ZEUoAnWt+Xta+pSSPcvnOa/ff1TLHfa0AVd4/ytRtw7Q4zsJpv/I2y3jjX27+3k9xQXuvSr0PkZxjee+zBORfUZFH+eeF87Kc9G4KwO8BF/6tE6TrvAA0",
"7F9iHV67iyti4GFvS1v+QXKvGMq/yoP+6zIaT7bz05tJ3mr5bSrJ2hkvfk19xn1ZKwHmyGm8B/8zSbazfGvb/X/sUd/nQawAVd5v52P5+qKUnRTJWnS/0ry8",
"qgXDvHtsiovZkdXqbkT3OAxLq1tlSpR/RUfe5J8XspN/Ic0Vq0xu3ULWISS3NH8S4rttPMyFqxSVrSLyvb5HuQ/G2L5t+L/er5MY431eOrEYbFgv5bF0hsfO",
"cV3zt8zyzik5WAT9BHvZKgHG8dGGGTYHXJ/d/94e9e0fxgpgvmnhY6F4vgT+t7OU+YbLu43MLjNp/EonSl71+m03FLaOSf6VC/Ii/4LglKwmfhgFYD7JXUpc",
"AH8g2TrE941IjvCg6SeSa0bg2+b48ksCbdyQ5KkkT2DMnuVm5zbNwkv/FMdRTdqv+Qyq8t69lncmh93BJMTH6T5z4EeWWS4DH8VnCcltPb59NuzuP4AV4HGP",
"b9r5+CgcHrENuljKu8fy/mkpLGAnWeoeVKoPQpk5/jHn8i8IspF/IRSA2WEW7irluy3eL0QoZ6gHbY9GKO+TMJMu5wL8VAsvH+ZgEVlRdfdI50rpiiDmTlUC",
"UuG1Br2jsvXw+dbm19EpQN37emw0anh85xWK97sogjSCAiAkb09w8brNxkdMCsAnFaAA5EH+RT7uSYvwOQEIW0hyQBVnlKp//6BHmkOSv7hpOxF3ul970BjG",
"qtDEeIu6OarVKKAQr2P8Ctw8YhulRIPNcfMJl3eftLw7LkdtWhFKAJ08Hjb82+fbzlF3/1XKsPkP7Onz3TUedB+TtAJQ5btOJJ8i+XMMC8BPZm509KmzJAXA",
"Q/6VG/Ig/8JgXBYCIC4v0PtDWBiiZhrc0OMM8M0Q5XSN+wwxB4J8aNSdWAx1d/eYgK1d3m/tMY4OUCUg1d3/T1GFkccOOMy12ZMtZdzk853QSR1sswLUDNkW",
"kRSAjPqtVAWgKysHWcq/KEhM/tWyPI/rTPpEkpeKyNSkGBCRn0meDuA5l587ktxPRIIExbDFKvi8wJu5zwG4OWeuF/Ng3wDAZuZvEwCbA+hgeX2YiHzt0o9f",
"k3wJgNt93UEk3wfwHYBJcNKMfi8iv6TdoCJyN0kAuMvySksA75HskOS4TxCnANjQ8ts/Anx/qOX58BA0vGJ5fiCc2Pq2viHJfgCGuPy8GYDjADwARRj5V47I",
"Uv5FQWLyr5YLM/URbz7v9QAkKghF5HlztuPmKXwTgBElDIrpBR7oM+Ka7HRSVa4a3JtVG/Bhrlpd7fHbNRYFYF0APV1oWgInCcr3Vf79FsCkJPPFl7kSYPM8",
"/kBERvqMkdaWsTUuTIITo9R/A6BVtZ+2INlSRCZ7fDuUzv33dhbeVAFIYVEsN2UnRvkXld5E5F8tlwm0iOQMAHEklFgK4JuUOvUcAJ+4PN+K5N9FxO84YJ2Q",
"i2gRYFNemnsM9HoADoGTiWxLOFnPNo+JnjdF5GMP4f2RObb5e8Dy6gJobf6q84FVkwHARAATALwoIrH0ZzkqASTXNv3uhiABqmzR1l6NQM6rLgoAzNi82efb",
"cwG85/J8Z5JriMgCXe8Dy79yRFbyL26ULP9szm3HAVhRInFLAPQRkd/SaAkR+RSALf3jvgGKmFeGE8MWsXC+ZfA3BPAFnPSc5wLoGvPgD5Kd69oY69vC8HAu",
"gHsAfM6IURxtSgAArzS0q5SAovgEdLU8/0JEvkhZAbAdAxwQoF/eB/CV20+IP+1suWBeBfGalfxLG77yr5ZlAr1Kci0A5wOoB+BtAItDVLwIwFgRWZIyw3cA",
"cLs2sQ/8zy8nWZ63KvAA2NLy/HvL8/4J8vuqiLwWQHiPIjkKQJcEaFjXjI//xKkElJElwKYABD2//5vLs6UA3opAy5sAlrvIqB0Dfj8cwDYWHp/R9T6w/CtH",
"ZCH/8oC/yL9aHoLtdwD/LhJ3IvIByQUAqsd8bkOyqYjMijABtihDBeAHy/MNY65/Fhwz1FcAwmS46mXGXmvT/k1jpKlhAuOuXJQA2+56mN+HJpiVW+jSb0Xk",
"zwhtuojk9y5juBHJ2iKyzKeIYQD6uTzfH4pKVwDSkn95RENfC0DB8SrcPZEPhLcDkG0CdCG5uoj8UaRGoJP4olPICTACwFEhq5oGxzt1lRPKKoeUb0RkYcQF",
"dQaA06rw0sBo5pvBOZNb9e/mCO+8lEggkKIrAeaYwi1Zymwvv40qsB2VzSyBrF8tSmxzAD/79Md7ls3AOiTXEZFfdc1XBSAG+Vc0fFjuCsBIiwLQxkdgTDM7",
"js1cNKYzANxYsHY4F87xTXWMt3lki8jjJNvD+1x7EYDzAHwA5ypK4sc8RpH4HC5XMk2yl80BtAdwi4XnVRggIm8kSOfdJlLbQA8l4G2S7URkfs7GSzPL86DX",
"YNfxWMSjYqZHXT8H+P5zuDuUNiuRrrKDh/wrN5Qq/4qMv8i/GmXI5FjL87UDfHub5XlfZpyZLuRurq5RANxwi48g6O2j7NQHcDGARRn4eLjRu8QoJRf5LP7X",
"i0ifFOi5C0Bvj1c2BXBJDoeNzTN6WoYKwK8h6wpKezNd8kPJv3JCqfKvqAgu/0xYyIdNxq8ZJB8g2TjGBcot1PCcmMpuYYmmNDLAt/VMiGM3XFUgBcAWjW0B",
"yToBy/inT3SqmVGzLsbMaytDixcuyoCujzzoGZzDMXNCBUWCOyZgm1RMJMAA8q8cEKf8KxKs8s9mAbgejiNWM/N3AoArEx7D9Uw2rdVKLGdOVAuAiCwG8Jjl",
"54tJ7lyAxb8TAJum90BQhywRucaYwuixC/uA5I4Z8ro9gI88doQEcJyIXJcyXU8A8BorT+Rw6LSvoJ3u7rrZDy3/ygFxyr9C7AUjyT86Oc6rY2KMAtIr2+BU",
"kucYM3bU8ldETTZEcj2Sv3sk5miY294m1/TIi7Agyh14kkeRXObRX3+Q7JABrx0tyY5WYRnJgzOg6ykfbXxoTsfOpxVkAXhfLQCR5F/Rd/9JyL+8IpD8s1kA",
"3M67N45xvHp5nK4H5yzqR5IXmMhMYbEiBK/VNb9psMcM2BDAi3n0BzCWk+Eelo6zfK5B2trjCTg3KJZaXmkA4DWSXVPkdX84tz0aWF5ZCmA/ERmcIk01SD4L",
"wCv3/MtwCemZo91CpaA2FFHkX5GRlPzLIwLLP9ui6OZ9W4fkmjEReH+Ad5rDieM/lWQ/cxUsiCBubJngM0J0+l0A3rH83BHAC3lKEWyynL0IYDfLKyNF5NES",
"hMLLADoDsF3rWw3ASyR7psDr4YZXmxBfCGAvERmV5uIP4Gmfxf1lAN0C3F/PCl9W0Do3Rpf6yPKviEha/uUJoeRfGAUAiMl7VkQGmp1SkPvQawG4zigCFwU4",
"GrB5M4eNAd8L9uiHBwB4zFz5ynrxF7P47G155Tc4oZ1L7bP3AOwBSxhNOFdKnyF5QoK8ngwn3LNt3M4H0EFEPtDFPzTeR+XgXV3mS5J/RUJa8i8PCC3/MlEA",
"TIM+A+dKVF/YHfeqYg04ceLHkWyWtAIgIlMAeHkLHwng3hx0+hNwklfYcGgU05elTT6H40BlK08APEDy1AQW2t6mvW1K1ywA7UUktd1dGS3+XnP+DgkA2KMI",
"BvreUqYtqNK+Ab+/O6bNQCVaAfzkX1GQpvzLEpHkX42QE2T7mAfZUhG5GcBGcOIwB8nStRm8z6h2iGvSi8gLAE7yeOUkkvdn0dskxZw5H+Hx2jEi8mrMffYV",
"HA/3KR6v3U5ywxh53QTAnR6vTAawk4iM18U/dgUgqNJf6p39MHUHjS7YvMTvK10J8JN/eUdW8i9tRJZ/NgXApkXsl9BAW2SuXWwE57rhwoiCAbBn/hsTkbYH",
"4J3D/sS0lQBj9n/UZ/G5VEQeT6i/foTjb2C7GVIX9rSyUdDO47fxAHb2yhGvi39JCkC7lBSIJBSAndUCUPJc95N/eUWW8i9NxC//SDYiudLlasGSoIEUSqy/",
"McmbSC62XHE40vJdPZLLXd5fHvE2QdWyH/W5dpGKEmB2/o/50PJoSrQ0sVwZJcm9YqxnL0sd35uslWkqXzVIPuvT/iOLFDmyCm+2K6TbBvi2tuXbCSXQ851b",
"gQG/bWuhZ1qI+ivuGmAJ8i9PyIP8SwMly78aFg3nN7gnTVkNyaRprV7/XBHpC6AFgNvxv1cwXhSRJy2f7gOgpsvz90yQi1JoOhbAEB9LQBqC4WEAR3v8PszQ",
"msbuYA6AlXFaXCz4yvJ8pYjMS1HIluPOvyps47t7gLGwDI7DVXVsTrJ+lE0I3K8ezw1YxEGW54OhSEL+5QV5kX9pIDn5R/ISi9YxLG0ujUXiGJL7mStvtvde",
"sdDcLyY6apIcloUlIODO/1WStVLsl/oWOmYkUNdcS131U+K1bHf+VXg80MLX6IDfv235vkcEWg63lPVawO/HWr7vGoIGtQCEl39ZIi/yL03UT4q5th6Vts/h",
"BNjVg942KU+C+2PmLcjiPyzNwe/T5q8mUNdrlrp20sU/Nj5rk1xq4a9tgO8vims+kHzEUtYFJYzLRWH6SBWAQikBeZJ/aaIk+VfDw7wxGvbgILflUH7dYXn+",
"mYiMjdHss8KYF71MibE5BlZx+PMy+w8HcJCILE+5zW1nw2MTqGuc5XmbhCd5uZv9q47tZQBeKWHOj7A8PzACOd1C1hFEFowseh/lYIwEkX9pI2/yL02UJP/8",
"otnZTOftSHbPkfZ7KABbUppzE5oEPVNSAoIu/ityNPjGJVDX2Iwm4UCfxX+EiOxbRgvLQMvzDiYEs9e8GAvgF5efmgaxIFSZz7vAiftRHdNEZILPt909ZMEt",
"uoSnJv/SXvzzJP/KRwnxONebRrJ5Dhb/9T28l0clXHcNki/4mGgGllD+/T5lv+DlE5FC279loWt7n++2IPkMydnm7ymSm/p8YzuSeiNB/jr4tP/wchTwHnN+",
"rF/0Sw9T9KUh6r/SUsadPt8JyW9K8R2oVp4eAZQu/5JEXuVfmngjaSb/5lH5F6Vk7YuBtrokx3vQ1zYFGhJRAgIu/jUyFjpu2fhW2M5ZzbWZOy3ZtZaRvINk",
"E8u3tmtmcxPk77hKW/wDzPkrfL492PLdlCDC2vTzdEsZB/h8e22cskAVgFwrAXmVf2ljbhqMjsxjelOSL3kNkBTpiFUJKMjiv4GFtvEWRe0ik5IzSNrOfm7x",
"Jjx2d+smxGNTS2rUsl38q/A+3KOPenp8V98Si4MkTwtQ71mWb5d6OfCR7OFB75CIbaAKQD6VgDzLvyywbtLMepnZSXKISUebVuPXM3XaMN0nX0BSk+DJUpWA",
"Iiz+hs79LPQ9Xc0ke7TZ/YXFZJOLW6qU95zl3b0T5PNwG38xjJctSXZM4O9vMQS+auPRN0tIbufx7cMeVoDaEXf/93l819bQRItFagtVAHIh/8pi8feRf1lg",
"7zQY9ppkJPl54pqIQ8e6JMd50LEoSOSyBOmLrAQEWPyfZE7SEJtduhv6m993M0dEpeKLVVddSF5meadvwrxuQbIvyX1iKq+NUXCSxGKSZ5RI51Ue5U8juYHl",
"u00txzykk9TJVt85lm+We9S1EckZHnReXgL/qgDEL/9KQRHkXxbomxbTPegeIngVZvo5gJVYfztThw0r/TyV86oEBFn8cyZwbHEJLghwZz4KniV5oeW3hwpm",
"Xk/rHvUSkquXSOson/nezvLdAx6KQ22X91czDqGBF9wA8mBYibyrApAfJaAo8i8LPJQm4xf7EPMnydtszlwR62xiHMSW5UITilkJKNrib2geG8MOdYD5KxWf",
"F0wBmJGicNilRFob0Yk5To+z+Z4u323oMV/7uLx/gUf5G7i835P2oEU0NDdQBSB9BSABJUDlX57kn8dkrYr5xmy6Tgn1NCfZ3+KI9ZedZw4HyQM+NN9uvOK9",
"8EAO+RJzthoFy0neW9VHg+R65tnyiGUupc/1tJy135gUFYAtY6C3FcmFPvVcU70PTJ+6YR7Jjaq8t4nHHB/oMvau86Hld5KtYuBbFYBk5V8QqPzLo/wjuS/J",
"3wISON4sdIeQ3MmcqTYz5dQ1C30r89shJO+i9/W+6l7jXXMs7B8uYfA/nFOe2kTkZ7CXQ5YZF0Milr1VgRSAi1Ja/D+MkeaDA9Q3uupc9LECfEmyjvmb4CHY",
"qgrKAwL6lewXE8+qAKj8K2v5Fzl2soiMJPk3OGFQW/q8vpX5612N4VL7YjKAziLyQ16FvYgcZ/jsFfLTR0TkuJyyFdbJ8mMAfUTkE5+2+hZAd+P09x/Y87nb",
"aJqAYuAGODnpWyZYx2IAD8Q4jgfTibj5OABbSvAdAYwk+RGAviLyPsl7Abg5I7aBE7K3LgCbleIuEZlJJ/fIbQDa+ZD5J4CjRWRETGwvsDxvlsMx1TwkDyr/",
"VP7Fog01oBOAY0mKZs3FxuTYAAVBSE344Zzzcn1APr4m2a2Eeg4KYQm6Coo0+t7P8a4qJhrfnVkR5vhMYzX8NsT77WLmtb6HZWL1HPVJA+N7VR0rmHKCHJV/",
"xZJ/EmOjtIATa7tHwu3/LIALRWRKAYXnwwE04XtF5NSc8/EggOM9XpkG4FIRiSsh0kkArgCwnsdrD4vI8bpEp9L/GwB4CcD2YT4LIW/CvAsAnwM4UESmJcDr",
"BIuF4kezSxuTcXfsDOB0izXpKxHZNkfjRuVfucs/knuQ/CqBXf8YkruVgfAc5MHjoILwcLqHc1dfJhAe2viK9DPOpW64SZfmVMdAvRLOK+NEokHISP6DxcV5",
"Kv9U/mXRQGIc+q4JYcJww1d0gpG0KzPhOaiog78KD9XDMN9AsnEK9TYmeVO1un+iJVCMIvH+OMTDiS9JfE3y4BT4q0XyuwIu/j8wJ0FzVP5VuPwjuTGdIC53",
"knye5DtmgC6kk1DhB/PsefPO+eZIoZwF51kmKMoUekRHyzkPPeiEyl0jg7obkzzVOMwosh0HNUkez2ghn8PiRzpJmmqkyF/nAioAe6n8U/mnUCgUaQmlOiT7",
"hHASDIMZZtGonRFvF6rpX1FuEG0ChUIR82JZG0AHAPuYv+0iyBrCcbB7xfy9JyLLM+ZrCwCPINz1rDTxGYAjReR7HYUKVQAUCkUeFIImcG4MNATQAEB9AFsD",
"6ARgKYBX4cT0WARgIYDfAYwRkTk55WcDODcDtgSwdsbkzAYwEcBEEflFR5tCoVAoFAqFQqFQKBQKheJ/8X8DDW09hR7FdQAAAABJRU5ErkJggg==",
})
local function b64decode(data)
local alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local map = {}
for i = 1, 64 do map[alphabet:byte(i)] = i - 1 end
local out, n, acc = {}, 0, 0
for i = 1, #data do
local v = map[data:byte(i)]
if v then
acc = acc * 64 + v
n += 1
if n == 4 then
out[#out + 1] = string.char(bit32.rshift(acc, 16) % 256, bit32.rshift(acc, 8) % 256, acc % 256)
n, acc = 0, 0
end
end
end
if n == 3 then
acc = acc * 64
out[#out + 1] = string.char(bit32.rshift(acc, 16) % 256, bit32.rshift(acc, 8) % 256)
elseif n == 2 then
acc = acc * 4096
out[#out + 1] = string.char(bit32.rshift(acc, 16) % 256)
end
return table.concat(out)
end
local iconAtlas = toAsset(PATH.ui, function() return b64decode(ICON_B64) end)
local function cat(...)
local r = {}
for _, t in ipairs({...}) do for _, v in ipairs(t) do r[#r + 1] = v end end
return r
end
local ICON2_ORDER = {"lock", "key", "shield", "shieldcheck", "sparkle", "rocket", "sword", "crown", "gauge", "cube", "pulse", "compass", "gear", "arrowR", "check", "download", "bookmark", "flame", "cpu", "login", "bell", "clock", "link", "wand", "tree", "eye", "filter", "sliders", "external", "info", "warning", "image", "edit", "calendar", "tag", "users", "grid", "list", "plug", "sun", "moon", "wifi", "hash", "mail", "send", "target", "trophy", "filecode", "database", "smartphone", "vault", "eyeoff", "chevU", "arrowL", "arrowU", "arrowD", "upload", "checkCircle", "xCircle", "plusCircle", "helpCircle", "pause", "stop", "skipFwd", "skipBack", "volume", "mute", "mic", "camera", "video", "music", "lightbulb", "battery", "folderOpen", "clipboard", "bug", "braces", "codeSlash", "power", "lockOpen", "pin", "share", "undo", "redo", "expand", "shrink", "zoomIn", "swap", "more", "moreV", "barChart", "lineChart", "pie", "ban", "userPlus", "chat", "sidebar", "gitBranch"}
local ICON2_INDEX, ICON2_CELL, ICON2_COLS = {}, 64, 8
for i, n in ipairs(ICON2_ORDER) do ICON2_INDEX[n] = i - 1 end
do
local gear = {}
for i = 0, 7 do
for _, d in ipairs({{-11, 7}, {-8, 9.8}, {8, 9.8}, {11, 7}}) do
local ang = math.rad(i * 45 + d[1])
gear[#gear + 1] = 12 + math.cos(ang) * d[2]
gear[#gear + 1] = 12 + math.sin(ang) * d[2]
end
end
gear[#gear + 1], gear[#gear + 2] = gear[1], gear[2]
local shield = {12, 2.5, 20, 5.5, 20, 12, 12, 21.5, 4, 12, 4, 5.5, 12, 2.5}
local NEW = {
lock = {{5, 11, 19, 11, 19, 21, 5, 21, 5, 11}, cat({8, 11, 8, 7.5}, arc(12, 7.5, 4, 180, 360, 12), {16, 7.5, 16, 11}), {12, 15, 12, 17}},
key = {arc(8, 15.5, 4.2, 0, 360, 18), {11.2, 12.3, 20.5, 3}, {17.5, 6, 20, 8.5}, {15, 8.7, 17, 10.7}},
shield = {shield},
shieldcheck = {shield, {8.5, 12, 11, 14.5, 15.5, 9.5}},
sparkle = {{12, 2.5, 14, 10, 21.5, 12, 14, 14, 12, 21.5, 10, 14, 2.5, 12, 10, 10, 12, 2.5}},
rocket = {{12, 2.5, 15.5, 7.5, 15.5, 15, 8.5, 15, 8.5, 7.5, 12, 2.5}, ell(12, 9, 1.6, 1.6, 12), {8.5, 12, 5, 16, 8.5, 15}, {15.5, 12, 19, 16, 15.5, 15}, {10.5, 17.5, 12, 21.5, 13.5, 17.5}},
sword = {{19.5, 4.5, 8.5, 15.5}, {19.5, 4.5, 21, 3}, {6, 12, 12, 18}, {7.5, 16.5, 4, 20}},
crown = {{3.5, 18.5, 3.5, 8, 8, 12.5, 12, 5, 16, 12.5, 20.5, 8, 20.5, 18.5, 3.5, 18.5}},
gauge = {arc(12, 14.5, 8.5, 180, 360, 18), {12, 14.5, 16.5, 9.5}, {3.5, 14.5, 5.5, 14.5}, {18.5, 14.5, 20.5, 14.5}, {5, 19.5, 19, 19.5}},
cube = {{12, 2.5, 20.5, 7.5, 20.5, 16.5, 12, 21.5, 3.5, 16.5, 3.5, 7.5, 12, 2.5}, {3.5, 7.5, 12, 12.5, 20.5, 7.5}, {12, 12.5, 12, 21.5}},
pulse = {{2.5, 12, 7, 12, 9.5, 5.5, 14, 19, 16.5, 12, 21.5, 12}},
compass = {ell(12, 12, 9.5, 9.5, 28), {15.5, 8.5, 13.5, 13.5, 8.5, 15.5, 10.5, 10.5, 15.5, 8.5}},
gear = {gear, ell(12, 12, 3, 3, 14)},
arrowR = {{4, 12, 20, 12}, {14, 6, 20, 12, 14, 18}},
check = {{4.5, 12.5, 10, 18, 19.5, 6.5}},
download = {{12, 3.5, 12, 15}, {7, 10.5, 12, 15.5, 17, 10.5}, {4, 16, 4, 20.5, 20, 20.5, 20, 16}},
bookmark = {{6, 3.5, 18, 3.5, 18, 21, 12, 16.5, 6, 21, 6, 3.5}},
flame = {{12, 2.5, 17.5, 9, 19, 14, 16, 19.5, 12, 21.5, 8, 19.5, 5, 14, 7, 9.5, 9.5, 12, 12, 2.5}},
cpu = {{6, 6, 18, 6, 18, 18, 6, 18, 6, 6}, {9.5, 9.5, 14.5, 9.5, 14.5, 14.5, 9.5, 14.5, 9.5, 9.5}, {9.5, 2.5, 9.5, 6}, {14.5, 2.5, 14.5, 6}, {9.5, 18, 9.5, 21.5}, {14.5, 18, 14.5, 21.5}, {2.5, 9.5, 6, 9.5}, {2.5, 14.5, 6, 14.5}, {18, 9.5, 21.5, 9.5}, {18, 14.5, 21.5, 14.5}},
login = {{14, 4, 20, 4, 20, 20, 14, 20}, {3.5, 12, 15, 12}, {10.5, 7.5, 15, 12, 10.5, 16.5}},
bell = {cat({5.5, 17.5, 7, 16, 7, 10.5}, arc(12, 10.5, 5, 180, 360, 12), {17, 10.5, 17, 16, 18.5, 17.5, 5.5, 17.5}), {10, 20.5, 14, 20.5}, {12, 3.5, 12, 5.5}},
clock = {ell(12, 12, 9, 9, 28), {12, 7, 12, 12, 16, 14}},
link = {{11, 7.5, 8, 7.5, 4.5, 11, 4.5, 13, 8, 16.5, 11, 16.5}, {13, 7.5, 16, 7.5, 19.5, 11, 19.5, 13, 16, 16.5, 13, 16.5}, {8.5, 12, 15.5, 12}},
wand = {{4, 20, 15, 9}, {17.5, 3, 18.5, 6, 21.5, 7, 18.5, 8, 17.5, 11, 16.5, 8, 13.5, 7, 16.5, 6, 17.5, 3}},
eye = {{2.5, 12, 6, 7.5, 12, 5.5, 18, 7.5, 21.5, 12, 18, 16.5, 12, 18.5, 6, 16.5, 2.5, 12}, ell(12, 12, 3, 3, 12)},
eyeoff = {{2.5, 12, 6, 7.5, 12, 5.5, 18, 7.5, 21.5, 12, 18, 16.5, 12, 18.5, 6, 16.5, 2.5, 12}, ell(12, 12, 3, 3, 12), {3.5, 3.5, 20.5, 20.5}},
vault = {{4, 3.5, 20, 3.5, 20, 20.5, 4, 20.5, 4, 3.5}, {7, 6.5, 17, 6.5, 17, 17.5, 7, 17.5, 7, 6.5}, ell(12, 12, 3.1, 3.1, 20), {12, 9, 12, 15}, {9, 12, 15, 12}, {4, 8, 6, 8}, {18, 16, 20, 16}},
filter = {{3.5, 5, 20.5, 5, 14, 12.5, 14, 19, 10, 21, 10, 12.5, 3.5, 5}},
sliders = {{4, 7, 20, 7}, {4, 17, 20, 17}, ell(9, 7, 2.4, 2.4, 12), ell(15, 17, 2.4, 2.4, 12)},
external = {{14, 4, 20, 4, 20, 10}, {20, 4, 11, 13}, {18, 14, 18, 20, 4, 20, 4, 6, 10, 6}},
info = {ell(12, 12, 9.5, 9.5, 28), {12, 11, 12, 16.5}, {12, 7.5, 12, 8}},
warning = {{12, 3.5, 21.5, 20, 2.5, 20, 12, 3.5}, {12, 10, 12, 14.5}, {12, 17, 12, 17.5}},
image = {{3.5, 5, 20.5, 5, 20.5, 19, 3.5, 19, 3.5, 5}, ell(9, 10, 1.7, 1.7, 10), {3.5, 17, 9, 12, 13, 16, 16, 13.5, 20.5, 17.5}},
edit = {{4, 20, 5, 15.5, 16.5, 4, 20, 7.5, 8.5, 19, 4, 20}, {14.5, 6, 18, 9.5}},
calendar = {{4, 6, 20, 6, 20, 20, 4, 20, 4, 6}, {4, 10.5, 20, 10.5}, {8, 3.5, 8, 7.5}, {16, 3.5, 16, 7.5}},
tag = {{3.5, 12.5, 12.5, 3.5, 20.5, 3.5, 20.5, 11.5, 11.5, 20.5, 3.5, 12.5}, ell(16, 8, 1.4, 1.4, 8)},
users = {ell(9, 8, 3.5, 3.5, 12), {2.5, 20, 2.5, 18.5, 5.5, 15, 12.5, 15, 15.5, 18.5, 15.5, 20}, {15.5, 5, 16.5, 4.7, 18.5, 5.5, 19.3, 8, 18.5, 10.5, 16.5, 11.3}, {18, 15, 21.5, 18, 21.5, 20}},
grid = {{4, 4, 10.5, 4, 10.5, 10.5, 4, 10.5, 4, 4}, {13.5, 4, 20, 4, 20, 10.5, 13.5, 10.5, 13.5, 4}, {4, 13.5, 10.5, 13.5, 10.5, 20, 4, 20, 4, 13.5}, {13.5, 13.5, 20, 13.5, 20, 20, 13.5, 20, 13.5, 13.5}},
list = {{9, 6.5, 20, 6.5}, {9, 12, 20, 12}, {9, 17.5, 20, 17.5}, {4, 6.5, 5, 6.5}, {4, 12, 5, 12}, {4, 17.5, 5, 17.5}},
plug = {{9, 3.5, 9, 8}, {15, 3.5, 15, 8}, {6.5, 8, 17.5, 8, 17.5, 12.5, 14, 16, 10, 16, 6.5, 12.5, 6.5, 8}, {12, 16, 12, 20.5}},
sun = {ell(12, 12, 4, 4, 14), {12, 3, 12, 5}, {12, 19, 12, 21}, {3, 12, 5, 12}, {19, 12, 21, 12}, {5.6, 5.6, 7, 7}, {17, 17, 18.4, 18.4}, {5.6, 18.4, 7, 17}, {17, 7, 18.4, 5.6}},
moon = {cat(arc(12, 12, 9, 5, 275, 24), arc(16.83, 7.17, 7, 216.6, 53.4, 16))},
wifi = {arc(12, 19.5, 4.5, -135, -45, 8), arc(12, 19.5, 9, -135, -45, 10), arc(12, 19.5, 13.5, -135, -45, 12), {12, 19.5, 12, 19.8}},
hash = {{9, 4, 7, 20}, {17, 4, 15, 20}, {4, 9, 20, 9}, {3.5, 15, 19.5, 15}},
mail = {{3.5, 6, 20.5, 6, 20.5, 18, 3.5, 18, 3.5, 6}, {3.5, 6, 12, 13, 20.5, 6}},
send = {{21, 3, 3, 10.5, 10, 13.5, 13, 21, 21, 3}, {10, 13.5, 21, 3}},
target = {ell(12, 12, 9, 9, 24), ell(12, 12, 5, 5, 16), ell(12, 12, 1, 1, 6)},
trophy = {{7, 4, 17, 4, 17, 10, 14.5, 13.5, 9.5, 13.5, 7, 10, 7, 4}, {7, 6, 4, 6, 4, 8.5, 7, 10.5}, {17, 6, 20, 6, 20, 8.5, 17, 10.5}, {12, 13.5, 12, 17}, {8.5, 20.5, 15.5, 20.5}, {9, 17, 15, 17}},
filecode = {{6, 3, 14, 3, 19, 8, 19, 21, 6, 21, 6, 3}, {14, 3, 14, 8, 19, 8}, {10, 12.5, 8.5, 14, 10, 15.5}, {14.5, 12.5, 16, 14, 14.5, 15.5}},
database = {ell(12, 6, 7.5, 2.8, 18), {4.5, 6, 4.5, 18}, {19.5, 6, 19.5, 18}, {4.5, 12, 7, 13.6, 12, 14.8, 17, 13.6, 19.5, 12}, {4.5, 18, 7, 19.6, 12, 20.8, 17, 19.6, 19.5, 18}},
smartphone = {{7, 2.5, 17, 2.5, 17, 21.5, 7, 21.5, 7, 2.5}, {10, 5.5, 14, 5.5}, {11, 18.5, 13, 18.5}},
chevU = {{6, 15, 12, 9, 18, 15}},
arrowL = {{20, 12, 4, 12}, {10, 6, 4, 12, 10, 18}},
arrowU = {{12, 20, 12, 4}, {6, 10, 12, 4, 18, 10}},
arrowD = {{12, 4, 12, 20}, {6, 14, 12, 20, 18, 14}},
upload = {{12, 15, 12, 3.5}, {7, 8.5, 12, 3.5, 17, 8.5}, {4, 16, 4, 20.5, 20, 20.5, 20, 16}},
checkCircle = {ell(12, 12, 9.5, 9.5, 28), {8, 12.5, 11, 15.5, 16, 9}},
xCircle = {ell(12, 12, 9.5, 9.5, 28), {9, 9, 15, 15}, {15, 9, 9, 15}},
plusCircle = {ell(12, 12, 9.5, 9.5, 28), {12, 8, 12, 16}, {8, 12, 16, 12}},
helpCircle = {ell(12, 12, 9.5, 9.5, 28), cat(arc(12, 9.5, 2.8, 180, 400, 10), {12, 13, 12, 14.3}), {12, 17.2, 12, 17.5}},
pause = {{8, 5, 8, 19}, {16, 5, 16, 19}},
stop = {{6, 6, 18, 6, 18, 18, 6, 18, 6, 6}},
skipFwd = {{6, 5, 15, 12, 6, 19, 6, 5}, {18, 5, 18, 19}},
skipBack = {{18, 5, 9, 12, 18, 19, 18, 5}, {6, 5, 6, 19}},
volume = {{4, 9, 8, 9, 13, 5, 13, 19, 8, 15, 4, 15, 4, 9}, arc(14.5, 12, 4, -45, 45, 6), arc(14.5, 12, 8, -45, 45, 8)},
mute = {{4, 9, 8, 9, 13, 5, 13, 19, 8, 15, 4, 15, 4, 9}, {17, 9, 22, 15}, {22, 9, 17, 15}},
mic = {cat({8.8, 8}, arc(12, 8, 3.2, 180, 360, 8), {15.2, 8, 15.2, 12}, arc(12, 12, 3.2, 0, 180, 8), {8.8, 12, 8.8, 8}), cat({5.5, 11}, arc(12, 11.5, 6.5, 180, 0, 12)), {5.5, 11, 5.5, 11.5}, {12, 18, 12, 21.5}, {8.5, 21.5, 15.5, 21.5}},
camera = {{3.5, 8, 8, 8, 9.5, 5, 14.5, 5, 16, 8, 20.5, 8, 20.5, 19, 3.5, 19, 3.5, 8}, ell(12, 13, 3.5, 3.5, 14)},
video = {{3, 6.5, 15, 6.5, 15, 17.5, 3, 17.5, 3, 6.5}, {15, 10.5, 21, 7, 21, 17, 15, 13.5}},
music = {{9, 18, 9, 5, 19, 3, 19, 16}, ell(6.5, 18, 2.5, 2.5, 10), ell(16.5, 16, 2.5, 2.5, 10)},
lightbulb = {cat(arc(12, 9.5, 6, 135, 405, 16), {15, 15.5, 15, 17, 9, 17, 9, 15.5, 7.76, 13.74}), {10, 20, 14, 20}, {10.8, 22.2, 13.2, 22.2}},
battery = {{3, 8, 18, 8, 18, 16, 3, 16, 3, 8}, {18, 10.5, 21, 10.5, 21, 13.5, 18, 13.5}, {6, 10.5, 6, 13.5}, {9, 10.5, 9, 13.5}},
folderOpen = {{3.5, 7, 3.5, 19, 18, 19, 21, 11, 8, 11, 5.5, 19}, {3.5, 7, 3.5, 5, 9, 5, 11, 7.5, 17, 7.5, 17, 11}},
clipboard = {{8, 4, 16, 4, 16, 7, 8, 7, 8, 4}, {16, 5.5, 19, 5.5, 19, 21, 5, 21, 5, 5.5, 8, 5.5}, {8.5, 12, 15.5, 12}, {8.5, 16, 13, 16}},
bug = {ell(12, 13.5, 4.5, 5.5, 16), {12, 8, 12, 19}, {7.5, 12, 3.5, 10.5}, {7.5, 16, 3.5, 17.5}, {16.5, 12, 20.5, 10.5}, {16.5, 16, 20.5, 17.5}, {9, 7, 8, 4.5}, {15, 7, 16, 4.5}},
braces = {{9, 4, 7.5, 4, 7, 5, 7, 10, 5, 12, 7, 14, 7, 19, 7.5, 20, 9, 20}, {15, 4, 16.5, 4, 17, 5, 17, 10, 19, 12, 17, 14, 17, 19, 16.5, 20, 15, 20}},
codeSlash = {{8, 7, 3, 12, 8, 17}, {16, 7, 21, 12, 16, 17}, {14, 4, 10, 20}},
power = {arc(12, 12, 8, -50, 230, 20), {12, 3.5, 12, 11.5}},
lockOpen = {{5, 11, 19, 11, 19, 21, 5, 21, 5, 11}, cat({8, 11, 8, 7.5}, arc(12, 7.5, 4, 180, 360, 12), {16, 7.5, 16, 9}), {12, 15, 12, 17}},
pin = {cat(arc(12, 9.5, 6.5, 150, 390, 16), {12, 21, 6.37, 12.75}), ell(12, 9.5, 2.3, 2.3, 10)},
share = {ell(6, 12, 2.5, 2.5, 10), ell(18, 6, 2.5, 2.5, 10), ell(18, 18, 2.5, 2.5, 10), {8.2, 10.8, 15.8, 7.2}, {8.2, 13.2, 15.8, 16.8}},
undo = {cat({4, 9, 14, 9}, arc(14, 14, 5, -90, 90, 8), {14, 19, 8, 19}), {8, 5, 4, 9, 8, 13}},
redo = {cat({20, 9, 10, 9}, arc(10, 14, 5, -90, -270, 8), {10, 19, 16, 19}), {16, 5, 20, 9, 16, 13}},
expand = {{4, 9, 4, 4, 9, 4}, {15, 4, 20, 4, 20, 9}, {20, 15, 20, 20, 15, 20}, {9, 20, 4, 20, 4, 15}},
shrink = {{9, 4, 9, 9, 4, 9}, {15, 4, 15, 9, 20, 9}, {20, 15, 15, 15, 15, 20}, {4, 15, 9, 15, 9, 20}},
zoomIn = {ell(10, 10, 6, 6, 14), {14.5, 14.5, 20, 20}, {10, 7.5, 10, 12.5}, {7.5, 10, 12.5, 10}},
swap = {{4, 8, 19, 8}, {15, 4, 19, 8, 15, 12}, {20, 16, 5, 16}, {9, 12, 5, 16, 9, 20}},
more = {{5, 12, 5.1, 12}, {12, 12, 12.1, 12}, {19, 12, 19.1, 12}},
moreV = {{12, 5, 12, 5.1}, {12, 12, 12, 12.1}, {12, 19, 12, 19.1}},
barChart = {{6, 20, 6, 12}, {12, 20, 12, 5}, {18, 20, 18, 9}},
lineChart = {{3.5, 4, 3.5, 20.5, 20.5, 20.5}, {7, 16, 11, 11, 14, 14, 19.5, 7}},
pie = {ell(12, 12, 9, 9, 24), {12, 12, 12, 3}, {12, 12, 19.8, 16.5}},
ban = {ell(12, 12, 9, 9, 24), {5.6, 5.6, 18.4, 18.4}},
userPlus = {ell(9, 8, 4, 4, 12), {2.5, 21, 2.5, 19, 5.5, 15.5, 12.5, 15.5, 15.5, 19, 15.5, 21}, {19, 8, 19, 14}, {16, 11, 22, 11}},
chat = {{4, 5, 20, 5, 20, 16, 10, 16, 5.5, 20.5, 5.5, 16, 4, 16, 4, 5}},
sidebar = {{4, 5, 20, 5, 20, 19, 4, 19, 4, 5}, {9.5, 5, 9.5, 19}},
gitBranch = {{6, 3.5, 6, 15.5}, ell(6, 18, 2.5, 2.5, 10), ell(18, 6, 2.5, 2.5, 10), {18, 8.5, 18, 10.5, 15, 13, 9, 13.5, 6, 15.5}},
}
for n, v in pairs(NEW) do
if not ICONS[n] and not ICON_INDEX[n] then ICONS[n] = v end
end
end
local function buildIconPNG()
local CELL, COLS = ICON2_CELL, ICON2_COLS
local rows = math.ceil(#ICON2_ORDER / COLS)
local W, H = CELL * COLS, CELL * rows
local alpha = table.create(W * H, 0)
local k = CELL / 24
local hw = 1.05 * k
for idx, name in ipairs(ICON2_ORDER) do
local ox, oy = ((idx - 1) % COLS) * CELL, math.floor((idx - 1) / COLS) * CELL
for _, s in ipairs(ICONS[name] or {}) do
for i = 1, #s - 3, 2 do
local x1, y1, x2, y2 = s[i] * k, s[i + 1] * k, s[i + 2] * k, s[i + 3] * k
local minx = math.max(0, math.floor(math.min(x1, x2) - hw - 1))
local maxx = math.min(CELL - 1, math.ceil(math.max(x1, x2) + hw + 1))
local miny = math.max(0, math.floor(math.min(y1, y2) - hw - 1))
local maxy = math.min(CELL - 1, math.ceil(math.max(y1, y2) + hw + 1))
local dx, dy = x2 - x1, y2 - y1
local l2 = dx * dx + dy * dy
for py = miny, maxy do
for px = minx, maxx do
local cx, cy = px + .5, py + .5
local t = 0
if l2 > 0 then t = math.clamp(((cx - x1) * dx + (cy - y1) * dy) / l2, 0, 1) end
local ex, ey = cx - (x1 + dx * t), cy - (y1 + dy * t)
local a = math.clamp(hw + .5 - math.sqrt(ex * ex + ey * ey), 0, 1)
local ai = (oy + py) * W + ox + px + 1
if a > alpha[ai] then alpha[ai] = a end
end
end
end
end
if idx % 5 == 0 then task.wait() end
end
local raw = {}
for y = 0, H - 1 do
local row = table.create(W * 4 + 1, 255)
row[1] = 0
local b = 1
for x = 0, W - 1 do
row[b + 4] = math.floor(alpha[y * W + x + 1] * 255 + .5)
b += 4
end
raw[#raw + 1] = string.char(table.unpack(row))
end
local data = table.concat(raw)
local function be32(n) return string.char(bit32.rshift(n, 24) % 256, bit32.rshift(n, 16) % 256, bit32.rshift(n, 8) % 256, n % 256) end
local crcT = {}
for i = 0, 255 do
local c = i
for _ = 1, 8 do
if bit32.band(c, 1) == 1 then c = bit32.bxor(0xEDB88320, bit32.rshift(c, 1)) else c = bit32.rshift(c, 1) end
end
crcT[i] = c
end
local function crc32(s)
local c = 0xFFFFFFFF
for i = 1, #s do c = bit32.bxor(crcT[bit32.band(bit32.bxor(c, s:byte(i)), 255)], bit32.rshift(c, 8)) end
return bit32.bxor(c, 0xFFFFFFFF)
end
local a1, b1 = 1, 0
for i = 1, #data, 4096 do
for _, v in ipairs({data:byte(i, math.min(i + 4095, #data))}) do
a1 = (a1 + v) % 65521
b1 = (b1 + a1) % 65521
end
end
local z, pos, n = {"\120\1"}, 1, #data
while pos <= n do
local len = math.min(65535, n - pos + 1)
local nlen = bit32.bxor(len, 0xFFFF)
z[#z + 1] = string.char((pos + len > n) and 1 or 0, len % 256, bit32.rshift(len, 8), nlen % 256, bit32.rshift(nlen, 8))
z[#z + 1] = data:sub(pos, pos + len - 1)
pos += len
end
z[#z + 1] = be32(b1 * 65536 + a1)
local function chunk(ty, d) return be32(#d) .. ty .. d .. be32(crc32(ty .. d)) end
return "\137PNG\r\n\26\n" .. chunk("IHDR", be32(W) .. be32(H) .. string.char(8, 6, 0, 0, 0)) .. chunk("IDAT", table.concat(z)) .. chunk("IEND", "")
end
local iconAtlas2 = toAsset(FOLDER .. "/ui2_" .. VERSION .. "_a" .. #ICON2_ORDER .. ".dat", buildIconPNG)
local function icon(parent, name, size, color, thickness)
if iconAtlas and ICON_INDEX[name] then
local function rect(n)
local i = ICON_INDEX[n]
return Vector2.new((i % ICON_COLS) * ICON_CELL, math.floor(i / ICON_COLS) * ICON_CELL)
end
local img = new("ImageLabel", {
BackgroundTransparency = 1, Size = UDim2.fromOffset(size, size), Image = iconAtlas,
ImageRectSize = Vector2.new(ICON_CELL, ICON_CELL), ImageRectOffset = rect(name),
ImageColor3 = color or T.text, ScaleType = Enum.ScaleType.Stretch, ZIndex = 2, Parent = parent,
})
local o = {holder = img}
function o.set(c, t)
if t then tween(img, {ImageColor3 = c}, t) else img.ImageColor3 = c end
end
function o.swap(n) if ICON_INDEX[n] then img.ImageRectOffset = rect(n) end end
return o
end
if iconAtlas2 and ICON2_INDEX[name] then
local function rect2(n)
local i = ICON2_INDEX[n]
return Vector2.new((i % ICON2_COLS) * ICON2_CELL, math.floor(i / ICON2_COLS) * ICON2_CELL)
end
local img = new("ImageLabel", {
BackgroundTransparency = 1, Size = UDim2.fromOffset(size, size), Image = iconAtlas2,
ImageRectSize = Vector2.new(ICON2_CELL, ICON2_CELL), ImageRectOffset = rect2(name),
ImageColor3 = color or T.text, ScaleType = Enum.ScaleType.Stretch, ZIndex = 2, Parent = parent,
})
local o = {holder = img}
function o.set(c, t)
if t then tween(img, {ImageColor3 = c}, t) else img.ImageColor3 = c end
end
function o.swap(n) if ICON2_INDEX[n] then img.ImageRectOffset = rect2(n) end end
return o
end
local holder = new("Frame", {BackgroundTransparency = 1, Size = UDim2.fromOffset(size, size), Parent = parent})
local k = size / 24
local th = thickness or math.max(1.8, size / 9)
local segs = {}
for _, s in ipairs(ICONS[name]) do
for i = 1, #s - 3, 2 do
local x1, y1, x2, y2 = s[i] * k, s[i + 1] * k, s[i + 2] * k, s[i + 3] * k
local dx, dy = x2 - x1, y2 - y1
local len = math.sqrt(dx * dx + dy * dy)
segs[#segs + 1] = new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromOffset((x1 + x2) / 2, (y1 + y2) / 2),
Size = UDim2.fromOffset(len + th * .5, th), Rotation = math.deg(math.atan2(dy, dx)),
BackgroundColor3 = color or T.text, BorderSizePixel = 0, Parent = holder,
}, {round(th / 2)})
local seg = segs[#segs]
if seg then seg.Name = "HyundaxIUMIconSegment" end
end
end
local obj = {holder = holder}
function obj.swap() end
function obj.set(c, t)
for _, sg in ipairs(segs) do
if t then tween(sg, {BackgroundColor3 = c}, t) else sg.BackgroundColor3 = c end
end
end
return obj
end
local logoAsset
local logos = {}
function FX.sheen(o, rot)
return new("UIGradient", {
Rotation = rot or 90,
Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(120, 120, 120)),
Parent = o,
})
end
function FX.chip(parent, name, box, color, pos)
local st = stroke(T.bronzeLo, 1)
st.Transparency = .55
local f = new("Frame", {
Size = UDim2.fromOffset(box, box), Position = pos or UDim2.new(), BackgroundColor3 = T.glow,
BorderSizePixel = 0, Parent = parent,
}, {round(math.floor(box * .3)), st})
local ic = icon(f, name, math.floor(box * .56), color or T.tan, 1.5)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
return f, ic
end
do
local function ntk(t, v) return NumberSequenceKeypoint.new(t, v) end
local LAYOUTS = {"UIListLayout", "UIGridLayout", "UIPageLayout", "UITableLayout"}
function FX.cardSkin(o)
if o:GetAttribute("CardSkin") or o:GetAttribute("NoCardSkin") then return end
local corner = o:FindFirstChildOfClass("UICorner")
if not corner or corner.CornerRadius.Offset < 8 then return end
local h = o.Size.Y
if h.Scale == 0 and h.Offset > 0 and h.Offset < 34 then return end
if o.BackgroundTransparency > .5 then return end
o:SetAttribute("CardSkin", true)
if not o:FindFirstChildOfClass("UIGradient") then
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(196, 196, 196)), Parent = o})
end
local st = o:FindFirstChildOfClass("UIStroke")
if st and not st:FindFirstChildOfClass("UIGradient") then
new("UIGradient", {Rotation = 90, Transparency = NumberSequence.new({ntk(0, 0), ntk(1, .55)}), Parent = st})
end
for _, cls in ipairs(LAYOUTS) do
if o:FindFirstChildOfClass(cls) then return end
end
local r = corner.CornerRadius.Offset
new("Frame", {
Name = "CardWash", Size = UDim2.fromScale(1, .9), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = o,
}, {round(r), new("UIGradient", {Rotation = 90, Transparency = NumberSequence.new({ntk(0, .88), ntk(1, 1)})})})
local rim = new("Frame", {
Name = "CardRim", Position = UDim2.fromOffset(r, 0), Size = UDim2.new(1, -r * 2, 0, 1),
BackgroundColor3 = Color3.new(1, 1, 1), BackgroundTransparency = .88, BorderSizePixel = 0, Parent = o,
}, {new("UIGradient", {Transparency = NumberSequence.new({ntk(0, 1), ntk(.5, 0), ntk(1, 1)})})})
o.MouseEnter:Connect(function() tween(rim, {BackgroundTransparency = .5}, .2) end)
o.MouseLeave:Connect(function() tween(rim, {BackgroundTransparency = .88}, .3) end)
end
function FX.sideSkin(side)
if side:GetAttribute("SideSkin") then return end
side:SetAttribute("SideSkin", true)
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(205, 205, 205)), Parent = side})
new("Frame", {
Name = "SideWash", Size = UDim2.new(1, -1, 0, 110), BackgroundColor3 = T.bronze, BorderSizePixel = 0, ZIndex = 0, Parent = side,
}, {new("UIGradient", {Rotation = 90, Transparency = NumberSequence.new({ntk(0, .91), ntk(1, 1)})})})
end
function FX.sideItem(parent, label, iconName, o)
o = o or {}
local b = new("TextButton", {
Size = o.size or UDim2.new(1, 0, 0, 34), Position = o.pos or UDim2.new(), BackgroundTransparency = 1,
AutoButtonColor = false, Text = "", LayoutOrder = o.order or 0, ZIndex = 3, Parent = parent,
})
local st = stroke(T.bronzeLo, 1)
st.Transparency = 1
local fill = new("Frame", {
Name = "SideFill", Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.panel2, BackgroundTransparency = 1,
BorderSizePixel = 0, ZIndex = 3, Parent = b,
}, {round(9), st, new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(190, 190, 190))})})
new("UIGradient", {Rotation = 90, Transparency = NumberSequence.new({ntk(0, 0), ntk(1, .55)}), Parent = st})
local rim = new("Frame", {
Name = "SideRim", Position = UDim2.fromOffset(9, 0), Size = UDim2.new(1, -18, 0, 1), BackgroundColor3 = Color3.new(1, 1, 1),
BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = 4, Parent = b,
}, {new("UIGradient", {Transparency = NumberSequence.new({ntk(0, 1), ntk(.5, 0), ntk(1, 1)})})})
local bar = new("Frame", {
Name = "SideBar", AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, 3, .5, 0), Size = UDim2.fromOffset(3, 0),
BackgroundColor3 = T.gold, BorderSizePixel = 0, ZIndex = 5, Parent = b,
}, {round(2)})
local row = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, ZIndex = 4, Parent = b}, {pad(o.padL or 13, 0), hlist(o.gap or 10)})
local ic = icon(row, iconName, o.iconSize or 16, T.muted, 1.5)
ic.holder.LayoutOrder = 1
local lbl = text(row, label, o.textSize or 12, "SemiBold", T.muted, {
AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 16), LayoutOrder = 2, NoI18N = o.raw,
})
local it = {b = b, ic = ic, lbl = lbl, fill = fill, on = false}
function it.setActive(on)
it.on = on
tween(fill, {BackgroundColor3 = on and T.glow or T.panel2, BackgroundTransparency = on and 0 or 1}, .22)
tween(st, {Transparency = on and .25 or 1}, .22)
tween(bar, {Size = UDim2.fromOffset(3, on and 16 or 0)}, .28, Enum.EasingStyle.Back)
tween(rim, {BackgroundTransparency = on and .8 or 1}, .22)
ic.set(on and T.gold or T.muted, .2)
tween(lbl, {TextColor3 = on and T.text or T.muted}, .2)
end
b.MouseEnter:Connect(function()
if it.on then
tween(rim, {BackgroundTransparency = .5}, .2)
return
end
tween(fill, {BackgroundTransparency = .45}, .15)
tween(st, {Transparency = .65}, .15)
tween(rim, {BackgroundTransparency = .82}, .2)
ic.set(T.tan, .15)
tween(lbl, {TextColor3 = T.text}, .15)
end)
b.MouseLeave:Connect(function()
if it.on then
tween(rim, {BackgroundTransparency = .8}, .3)
return
end
tween(fill, {BackgroundTransparency = 1}, .2)
tween(st, {Transparency = 1}, .2)
tween(rim, {BackgroundTransparency = 1}, .3)
ic.set(T.muted, .2)
tween(lbl, {TextColor3 = T.muted}, .2)
end)
pressFx(b, .96)
return it
end
function FX.pill(parent, str, color, props)
local p = {
AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 16), BackgroundColor3 = color, BackgroundTransparency = .84,
Text = str, TextSize = 9, FontFace = F.Bold, TextColor3 = color, BorderSizePixel = 0, Parent = parent,
}
for k, v in pairs(props or {}) do p[k] = v end
local st = stroke(color, 1)
st.Transparency = .6
return new("TextLabel", p, {round(8), pad(8, 0), st})
end
function FX.card(parent, o)
o = o or {}
local h = o.height or 58
local btn = o.onClick ~= nil
local props = {
Size = UDim2.new(1, 0, 0, h), BackgroundColor3 = o.active and T.glow or T.cardTop, BorderSizePixel = 0,
LayoutOrder = o.order or 0, Parent = parent,
}
if btn then props.AutoButtonColor = false props.Text = "" end
local c = new(btn and "TextButton" or "Frame", props, {
round(12), stroke(o.active and T.gold or T.line, o.active and 1.5 or 1),
})
FX.cardSkin(c)
local x, right = 14, btn and 32 or 14
if o.icon then
local box = math.min(36, h - 14)
FX.chip(c, o.icon, box, o.iconColor or T.gold, UDim2.fromOffset(12, math.floor((h - box) / 2)))
x = 12 + box + 10
end
if o.badge then
FX.pill(c, o.badge[1], o.badge[2] or T.gold, {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, btn and -30 or -12, .5, 0)})
right = right + 70
end
local ty = o.sub and math.floor(h / 2 - 16) or math.floor(h / 2 - 8)
text(c, o.title or "", 12, "SemiBold", T.text, {
Position = UDim2.fromOffset(x, ty), Size = UDim2.new(1, -(x + right), 0, 16),
TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = o.raw or nil,
})
if o.sub then
text(c, o.sub, 10, "Regular", T.muted, {
Position = UDim2.fromOffset(x, ty + 17), Size = UDim2.new(1, -(x + right), 0, 14),
TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = o.raw or nil,
})
end
if btn then
local st = c:FindFirstChildOfClass("UIStroke")
local ch = icon(c, "chevR", 14, T.muted, 1.5)
ch.holder.AnchorPoint = Vector2.new(1, .5)
ch.holder.Position = UDim2.new(1, -10, .5, 0)
c.MouseEnter:Connect(function() tween(st, {Color = T.bronzeLo}, .2) ch.set(T.tan, .2) end)
c.MouseLeave:Connect(function() tween(st, {Color = o.active and T.gold or T.line}, .25) ch.set(T.muted, .25) end)
pressFx(c, .975)
c.Activated:Connect(o.onClick)
end
return c
end
end
local function logoImage(props)
local p = {BackgroundTransparency = 1, ScaleType = Enum.ScaleType.Fit, ImageTransparency = 1}
for k, v in pairs(props) do p[k] = v end
local img = new("ImageLabel", p)
img:SetAttribute("NoTheme", true)
if logoAsset then img.Image = logoAsset img.ImageTransparency = 0 else table.insert(logos, img) end
return img
end
local function loadLogo()
task.spawn(function()
local asset = toAsset(LOGO_FILE, function() return game:HttpGet(LOGO_URL) end)
if asset then
logoAsset = asset
for _, img in ipairs(logos) do
img.Image = asset
tween(img, {ImageTransparency = 0}, .5)
end
end
end)
end
local function avatar(parent, size, pos)
local f = new("Frame", {Size = UDim2.fromOffset(size, size), Position = pos, BackgroundColor3 = T.tan, BorderSizePixel = 0, Parent = parent}, {round(size / 2), stroke(T.bronze, 1)})
local letter = text(f, lp.Name:sub(1, 1):upper(), math.floor(size * .45), "Bold", T.dark, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center})
local img = new("ImageLabel", {
Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, ImageTransparency = 1, ScaleType = Enum.ScaleType.Crop,
Image = ("rbxthumb://type=AvatarHeadShot&id=%d&w=150&h=150"):format(lp.UserId), Parent = f,
}, {round(size / 2)})
local done = false
local function ok()
if done then return end
done = true
tween(img, {ImageTransparency = 0}, .35)
tween(letter, {TextTransparency = 1}, .3)
end
if img.IsLoaded then ok() end
img:GetPropertyChangedSignal("IsLoaded"):Connect(function() if img.IsLoaded then ok() end end)
task.delay(3, function()
if done then return end
local okc, content = pcall(function() return Players:GetUserThumbnailAsync(lp.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size150x150) end)
if okc and content then img.Image = content end
task.delay(1.5, ok)
end)
return f
end
local function getParent()
local ok, h = pcall(function() return gethui and gethui() end)
if ok and h then return h end
if pcall(function() return CoreGui.Name end) then return CoreGui end
return lp:WaitForChild("PlayerGui")
end
local parentGui = getParent()
local old = parentGui:FindFirstChild(NAME)
if old then old:Destroy() end
local I18N = {
lang = "en", nick = "", profile = {},
tracked = setmetatable({}, {__mode = "k"}),
watchers = {}, binds = {},
LANGS = {
{code = "pt", name = "Português (BR)"}, {code = "en", name = "English"}, {code = "es", name = "Español"},
{code = "fr", name = "Français"}, {code = "de", name = "Deutsch"}, {code = "id", name = "Bahasa Indonesia"},
},
}
I18N.flag = function(parent, code, w, h, pos, z)
local zi = z or 3
local C = Color3.fromRGB
local f = new("Frame", {
Name = "NoThemePick", Size = UDim2.fromOffset(w, h), Position = pos or UDim2.new(), BackgroundColor3 = Color3.new(1, 1, 1),
BorderSizePixel = 0, ClipsDescendants = true, ZIndex = zi, Parent = parent,
}, {round(math.max(2, math.floor(h / 6)))})
local function bar(x, y, sw, sh, col, rot, z2)
return new("Frame", {
Position = UDim2.fromScale(x, y), Size = UDim2.fromScale(sw, sh), BackgroundColor3 = col,
BorderSizePixel = 0, Rotation = rot or 0, ZIndex = zi + (z2 or 1), Parent = f,
})
end
local function px(x, y, pw, ph, col, z2, circle)
local o = new("Frame", {
Position = UDim2.fromOffset(x, y), Size = UDim2.fromOffset(pw, ph), BackgroundColor3 = col,
BorderSizePixel = 0, ZIndex = zi + (z2 or 1), Parent = f,
})
if circle then new("UICorner", {CornerRadius = UDim.new(1, 0), Parent = o}) end
return o
end
if code == "pt" then
f.BackgroundColor3 = C(0, 156, 59)
local cx, cy = w / 2, h / 2
local hw, hh = w * .43, h * .40
local n = math.max(12, math.floor(h * 1.2))
for k = 0, n - 1 do
local t = (k + .5) / n * 2 - 1
local half = hw * (1 - math.abs(t))
px(cx - half, cy + t * hh - hh / n, half * 2, hh * 2 / n + .6, C(254, 223, 0), 1)
end
local r = h * .27
px(cx - r, cy - r, r * 2, r * 2, C(0, 39, 118), 2, true)
local segs = 7
for k = 0, segs - 1 do
local u = (k + .5) / segs * 2 - 1
local bx = cx + u * r * .92
local by = cy + r * .22 - (1 - u * u) * r * .5
px(bx - r * .16, by - .5, r * .34, math.max(1, h * .07), C(255, 255, 255), 3)
end
elseif code == "en" then
f.BackgroundColor3 = C(1, 33, 105)
local len = math.sqrt(w * w + h * h) + 4
local ang = math.deg(math.atan2(h, w))
local function diag(rot, th, col, z2)
return new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromOffset(w / 2, h / 2), Size = UDim2.fromOffset(len, th),
Rotation = rot, BackgroundColor3 = col, BorderSizePixel = 0, ZIndex = zi + z2, Parent = f,
})
end
local white, red = C(255, 255, 255), C(200, 16, 46)
diag(ang, h * .2, white, 1) diag(-ang, h * .2, white, 1)
diag(ang, h * .08, red, 2) diag(-ang, h * .08, red, 2)
px(0, h * .5 - h * .17, w, h * .34, white, 3)
px(w / 2 - h * .17, 0, h * .34, h, white, 3)
px(0, h * .5 - h * .1, w, h * .2, red, 4)
px(w / 2 - h * .1, 0, h * .2, h, red, 4)
elseif code == "es" then
f.BackgroundColor3 = C(255, 196, 0)
bar(0, 0, 1, .25, C(170, 21, 27)) bar(0, .75, 1, .25, C(170, 21, 27))
local sx, sy = w * .27, h * .5
local sw, sh = h * .27, h * .36
px(sx - sw / 2 - h * .09, sy - sh / 2 + h * .02, math.max(1, h * .05), sh, C(206, 176, 120), 2)
px(sx + sw / 2 + h * .04, sy - sh / 2 + h * .02, math.max(1, h * .05), sh, C(206, 176, 120), 2)
px(sx - sw / 2, sy - sh / 2 - h * .05, sw, h * .07, C(222, 170, 20), 3)
local shield = px(sx - sw / 2, sy - sh / 2 + h * .02, sw, sh, C(255, 255, 255), 2)
shield.ClipsDescendants = true
new("UICorner", {CornerRadius = UDim.new(.38, 0), Parent = shield})
new("Frame", {Size = UDim2.fromScale(.5, .5), BackgroundColor3 = C(173, 21, 27), BorderSizePixel = 0, ZIndex = zi + 3, Parent = shield})
new("Frame", {Position = UDim2.fromScale(.5, .5), Size = UDim2.fromScale(.5, .5), BackgroundColor3 = C(173, 21, 27), BorderSizePixel = 0, ZIndex = zi + 3, Parent = shield})
new("Frame", {Position = UDim2.fromScale(.5, 0), Size = UDim2.fromScale(.5, .5), BackgroundColor3 = C(222, 170, 20), BorderSizePixel = 0, ZIndex = zi + 3, Parent = shield})
new("Frame", {Position = UDim2.fromScale(0, .5), Size = UDim2.fromScale(.5, .5), BackgroundColor3 = C(222, 170, 20), BorderSizePixel = 0, ZIndex = zi + 3, Parent = shield})
elseif code == "fr" then
f.BackgroundColor3 = C(255, 255, 255)
bar(0, 0, 1 / 3, 1, C(0, 35, 149)) bar(2 / 3, 0, 1 / 3 + .01, 1, C(237, 41, 57))
elseif code == "de" then
f.BackgroundColor3 = C(221, 0, 0)
bar(0, 0, 1, 1 / 3, C(0, 0, 0)) bar(0, 2 / 3, 1, 1 / 3 + .01, C(255, 206, 0))
elseif code == "id" then
f.BackgroundColor3 = C(255, 255, 255)
bar(0, 0, 1, .5, C(206, 17, 38))
else
f.BackgroundColor3 = C(80, 80, 84)
end
local gloss = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, ZIndex = zi + 6, Parent = f})
new("UIGradient", {Rotation = 60, Transparency = NumberSequence.new({
NumberSequenceKeypoint.new(0, .72), NumberSequenceKeypoint.new(.5, .97), NumberSequenceKeypoint.new(1, .88),
}), Parent = gloss})
new("UIStroke", {Color = Color3.new(0, 0, 0), Transparency = .7, Thickness = 1, ApplyStrokeMode = Enum.ApplyStrokeMode.Border, Parent = f})
return f
end
do
local PROFILE_FILE = FOLDER .. "/profile.json"
local COL = {en = 1, pt = 2, es = 3, fr = 4, de = 5, id = 6}
local DICT = {
{"Script execution environment","Ambiente de execução de scripts","Entorno de ejecución de scripts","Environnement d'exécution de scripts","Skript-Ausführungsumgebung","Lingkungan eksekusi skrip"},
{"Quick start","Início rápido","Inicio rápido","Démarrage rapide","Schnellstart","Mulai cepat"},
{"Saved scripts","Scripts salvos","Scripts guardados","Scripts enregistrés","Gespeicherte Skripte","Skrip tersimpan"},
{"Nothing here yet","Nada por aqui ainda","Nada por aquí todavía","Rien ici pour l'instant","Noch nichts vorhanden","Belum ada apa-apa"},
{"Blank tab in the editor","Aba em branco no editor","Pestaña en blanco en el editor","Onglet vide dans l'éditeur","Leerer Tab im Editor","Tab kosong di editor"},
{"Browse community scripts","Explore scripts da comunidade","Explora scripts de la comunidad","Parcourir les scripts de la communauté","Community-Skripte durchsuchen","Jelajahi skrip komunitas"},
{"Inspect game instances","Inspecione instâncias do jogo","Inspecciona instancias del juego","Inspecter les instances du jeu","Spielinstanzen untersuchen","Periksa instance game"},
{"Theme, sounds and more","Tema, sons e mais","Tema, sonidos y más","Thème, sons et plus","Design, Sounds und mehr","Tema, suara, dan lainnya"},
{"Runtime: Ready","Runtime: Pronto","Runtime: Listo","Runtime : Prêt","Runtime: Bereit","Runtime: Siap"},
{"Salted password hashing","Senhas com hash e salt","Contraseñas con hash y sal","Mots de passe hachés avec sel","Passwörter mit Salt-Hash","Hash kata sandi dengan salt"},
{"Accounts stay on this device","Contas ficam neste dispositivo","Las cuentas se quedan en este dispositivo","Les comptes restent sur cet appareil","Konten bleiben auf diesem Gerät","Akun tetap di perangkat ini"},
{"Cached assets, quick startup","Arquivos em cache, início rápido","Archivos en caché, inicio rápido","Fichiers en cache, démarrage rapide","Zwischengespeicherte Dateien, schneller Start","Aset tersimpan, mulai cepat"},
{"Home","Início","Inicio","Accueil","Start","Beranda"},
{"Editor","Editor","Editor","Éditeur","Editor","Editor"},
{"Scripts","Scripts","Scripts","Scripts","Skripte","Skrip"},
{"Console","Console","Consola","Console","Konsole","Konsol"},
{"Overview","Visão geral","Resumen","Aperçu","Übersicht","Ringkasan"},
{"My Scripts","Meus scripts","Mis scripts","Mes scripts","Meine Skripte","Skrip saya"},
{"Account","Conta","Cuenta","Compte","Konto","Akun"},
{"Update Log","Novidades","Novedades","Nouveautés","Änderungen","Pembaruan"},
{"Recent Scripts","Scripts recentes","Scripts recientes","Scripts récents","Letzte Skripte","Skrip terbaru"},
{"Dashboard","Painel","Panel","Tableau de bord","Dashboard","Dasbor"},
{"Settings","Configurações","Ajustes","Paramètres","Einstellungen","Pengaturan"},
{"Themes","Temas","Temas","Thèmes","Themen","Tema"},
{"Appearance","Aparência","Apariencia","Apparence","Darstellung","Tampilan"},
{"Interface","Interface","Interfaz","Interface","Oberfläche","Antarmuka"},
{"Profile","Perfil","Perfil","Profil","Profil","Profil"},
{"Advanced","Avançado","Avanzado","Avancé","Erweitert","Lanjutan"},
{"Look and behavior of the window","Aparência e comportamento da janela","Apariencia y comportamiento de la ventana","Apparence et comportement de la fenêtre","Aussehen und Verhalten des Fensters","Tampilan dan perilaku jendela"},
{"Editor and console preferences","Preferências do editor e do console","Preferencias del editor y la consola","Préférences de l'éditeur et de la console","Einstellungen für Editor und Konsole","Preferensi editor dan konsol"},
{"Language, nickname and account","Idioma, apelido e conta","Idioma, apodo y cuenta","Langue, pseudo et compte","Sprache, Spitzname und Konto","Bahasa, nama panggilan dan akun"},
{"Diagnostics and maintenance","Diagnóstico e manutenção","Diagnóstico y mantenimiento","Diagnostic et maintenance","Diagnose und Wartung","Diagnostik dan pemeliharaan"},
{"Floating button can't be hidden without a keyboard","O botão flutuante não pode ser ocultado sem teclado","El botón flotante no se puede ocultar sin teclado","Le bouton flottant ne peut pas être masqué sans clavier","Der schwebende Button kann ohne Tastatur nicht ausgeblendet werden","Tombol mengambang tidak bisa disembunyikan tanpa keyboard"},
{"Ready-made themes","Temas prontos","Temas listos","Thèmes prêts","Fertige Themen","Tema siap pakai"},
{"Loading from saved files in the HyundaxIUM folder.","Carregando dos arquivos salvos na pasta HyundaxIUM.","Cargando desde los archivos guardados en la carpeta HyundaxIUM.","Chargement depuis les fichiers enregistrés du dossier HyundaxIUM.","Laden aus den gespeicherten Dateien im HyundaxIUM-Ordner.","Memuat dari file tersimpan di folder HyundaxIUM."},
{"Search scripts...","Pesquisar scripts...","Buscar scripts...","Rechercher des scripts...","Skripte suchen...","Cari skrip..."},
{"Choose language","Escolher idioma","Elegir idioma","Choisir la langue","Sprache wählen","Pilih bahasa"},
{"Select the language used by Hyundax IUM","Selecione o idioma usado pelo Hyundax IUM","Selecciona el idioma de Hyundax IUM","Choisissez la langue de Hyundax IUM","Wähle die Sprache für Hyundax IUM","Pilih bahasa yang digunakan Hyundax IUM"},
{"Current language","Idioma atual","Idioma actual","Langue actuelle","Aktuelle Sprache","Bahasa saat ini"},
{"Close","Fechar","Cerrar","Fermer","Schließen","Tutup"},
{"Language changed","Idioma alterado","Idioma cambiado","Langue modifiée","Sprache geändert","Bahasa diubah"},
{"Choose how Hyundax IUM looks","Escolha a aparência do Hyundax IUM","Elige cómo se ve Hyundax IUM","Choisissez l'apparence de Hyundax IUM","Wähle das Aussehen von Hyundax IUM","Pilih tampilan Hyundax IUM"},
{"Tap to pick a ready-made theme","Toque para escolher um tema pronto","Toca para elegir un tema listo","Touchez pour choisir un thème prêt","Tippe, um ein fertiges Thema zu wählen","Ketuk untuk memilih tema siap pakai"},
{"Custom palette","Paleta personalizada","Paleta personalizada","Palette personnalisée","Eigene Palette","Palet kustom"},
{"Drag the dot to choose a color. Press Apply to use it.","Arraste a bolinha para escolher uma cor. Toque em Aplicar para usar.","Arrastra el punto para elegir un color. Pulsa Aplicar para usarlo.","Faites glisser le point pour choisir une couleur. Appuyez sur Appliquer pour l'utiliser.","Ziehe den Punkt, um eine Farbe zu wählen. Tippe auf Anwenden, um sie zu nutzen.","Seret titik untuk memilih warna. Tekan Terapkan untuk menggunakannya."},
{"Background color","Cor de fundo","Color de fondo","Couleur de fond","Hintergrundfarbe","Warna latar"},
{"Accent color","Cor de destaque","Color de acento","Couleur d'accent","Akzentfarbe","Warna aksen"},
{"Apply","Aplicar","Aplicar","Appliquer","Anwenden","Terapkan"},
{"Cancel","Cancelar","Cancelar","Annuler","Abbrechen","Batal"},
{"Confirm","Confirmar","Confirmar","Confirmer","Bestätigen","Konfirmasi"},
{"Are you sure?","Tem certeza?","¿Estás seguro?","Êtes-vous sûr ?","Bist du sicher?","Apakah kamu yakin?"},
{"Script details","Detalhes do script","Detalles del script","Détails du script","Skript-Details","Detail skrip"},
{"ACTIVE","ATIVO","ACTIVO","ACTIF","AKTIV","AKTIF"},
{"Custom theme applied","Tema personalizado aplicado","Tema personalizado aplicado","Thème personnalisé appliqué","Eigenes Thema angewendet","Tema kustom diterapkan"},
{"The original black, red, blue and yellow look.","O visual original preto, vermelho, azul e amarelo.","El aspecto original negro, rojo, azul y amarillo.","Le look original noir, rouge, bleu et jaune.","Der originale Schwarz-Rot-Blau-Gelb-Look.","Tampilan asli hitam, merah, biru, dan kuning."},
{"Pure-black surfaces with red accents.","Superfícies pretas puras com detalhes em vermelho.","Superficies negras puras con acentos rojos.","Surfaces noires pures avec accents rouges.","Rein schwarze Flächen mit roten Akzenten.","Permukaan hitam pekat dengan aksen merah."},
{"A clean, bright white interface.","Uma interface branca, limpa e clara.","Una interfaz blanca, limpia y luminosa.","Une interface blanche, nette et lumineuse.","Eine saubere, helle weiße Oberfläche.","Antarmuka putih yang bersih dan cerah."},
{"Deep green surfaces with mint highlights.","Superfícies verde-escuras com destaques de menta.","Superficies verde oscuro con detalles de menta.","Surfaces vert profond avec reflets menthe.","Tiefgrüne Flächen mit Minz-Akzenten.","Permukaan hijau tua dengan sorotan mint."},
{"Midnight blue with cool blue accents.","Azul meia-noite com detalhes em azul frio.","Azul medianoche con acentos azules fríos.","Bleu nuit avec accents bleus froids.","Mitternachtsblau mit kühlen Blau-Akzenten.","Biru tengah malam dengan aksen biru sejuk."},
{"Warm coral and peach on deep plum.","Coral e pêssego quentes sobre ameixa escura.","Coral y durazno cálidos sobre ciruela oscura.","Corail et pêche chauds sur prune foncée.","Warmes Koralle und Pfirsich auf tiefem Pflaume.","Koral dan persik hangat di atas ungu tua."},
{"Soft purple and lilac, calm and creative.","Roxo suave e lilás, calmo e criativo.","Morado suave y lila, calmado y creativo.","Violet doux et lilas, calme et créatif.","Sanftes Lila und Flieder, ruhig und kreativ.","Ungu lembut dan lilac, tenang dan kreatif."},
{"Light pink pastel with rose accents.","Rosa pastel claro com detalhes rosados.","Rosa pastel claro con acentos rosados.","Rose pastel clair avec accents rosés.","Helles Pastellrosa mit Rosé-Akzenten.","Merah muda pastel lembut dengan aksen mawar."},
{"Moss green and earthy tan, natural.","Verde musgo e bege terroso, natural.","Verde musgo y beige terroso, natural.","Vert mousse et beige terreux, naturel.","Moosgrün und erdiges Beige, natürlich.","Hijau lumut dan cokelat tanah, alami."},
{"Amber and honey on warm charcoal.","Âmbar e mel sobre carvão quente.","Ámbar y miel sobre carbón cálido.","Ambre et miel sur charbon chaud.","Bernstein und Honig auf warmem Anthrazit.","Amber dan madu di atas arang hangat."},
{"Cyberpunk magenta and electric cyan.","Magenta cyberpunk e ciano elétrico.","Magenta cyberpunk y cian eléctrico.","Magenta cyberpunk et cyan électrique.","Cyberpunk-Magenta und elektrisches Cyan.","Magenta cyberpunk dan sian listrik."},
{"Crisp white and icy sky blue.","Branco nítido e azul-céu gelado.","Blanco nítido y azul cielo helado.","Blanc éclatant et bleu ciel glacé.","Klares Weiß und eisiges Himmelblau.","Putih tajam dan biru langit sedingin es."},
{"Charcoal with dusty rose and mauve.","Carvão com rosa envelhecido e malva.","Carbón con rosa empolvado y malva.","Charbon avec rose poudré et mauve.","Anthrazit mit Altrosa und Mauve.","Arang dengan mawar pudar dan mauve."},
{"Teal, turquoise and pineapple yellow.","Verde-azulado, turquesa e amarelo abacaxi.","Verde azulado, turquesa y amarillo piña.","Sarcelle, turquoise et jaune ananas.","Petrol, Türkis und Ananasgelb.","Teal, pirus, dan kuning nanas."},
{"Deep wine red with champagne gold.","Vinho profundo com dourado champanhe.","Rojo vino profundo con dorado champán.","Rouge vin profond avec or champagne.","Tiefes Weinrot mit Champagnergold.","Merah anggur pekat dengan emas sampanye."},
{"Start","Início","Inicio","Début","Start","Mulai"},
{"Forge","Forja","Forja","Forge","Schmiede","Forge"},
{"Browse","Explorar","Explorar","Parcourir","Durchsuchen","Jelajahi"},
{"Explorer","Explorador","Explorador","Explorateur","Explorer","Penjelajah"},
{"Finder","Buscador","Buscador","Recherche","Suche","Pencari"},
{"Cloud Scripts","Scripts na nuvem","Scripts en la nube","Scripts cloud","Cloud-Skripte","Skrip cloud"},
{"Cloud scripts","Scripts na nuvem","Scripts en la nube","Scripts cloud","Cloud-Skripte","Skrip cloud"},
{"Autoexec","Execução automática","Ejecución automática","Exécution auto","Autoausführung","Eksekusi otomatis"},
{"Autoexecute","Execução automática","Ejecución automática","Exécution auto","Autoausführung","Eksekusi otomatis"},
{"AutoExec","Execução automática","Ejecución automática","Exécution auto","Autoausführung","Eksekusi otomatis"},
{"loadstring is not available in this environment.","loadstring não está disponível neste ambiente.","loadstring no está disponible en este entorno.","loadstring n'est pas disponible dans cet environnement.","loadstring ist in dieser Umgebung nicht verfügbar.","loadstring tidak tersedia di lingkungan ini."},
{"loadstring unavailable","loadstring indisponível","loadstring no disponible","loadstring indisponible","loadstring nicht verfügbar","loadstring tidak tersedia"},
{"Syntax error","Erro de sintaxe","Error de sintaxis","Erreur de syntaxe","Syntaxfehler","Kesalahan sintaks"},
{"[ok] finished","[ok] concluído","[ok] terminado","[ok] terminé","[ok] fertig","[ok] selesai"},
{"Executed","Executado","Ejecutado","Exécuté","Ausgeführt","Dijalankan"},
{"Version","Versão","Versión","Version","Version","Versi"},
{"Status","Status","Estado","Statut","Status","Status"},
{"Ready","Pronto","Listo","Prêt","Bereit","Siap"},
{"Executions","Execuções","Ejecuciones","Exécutions","Ausführungen","Eksekusi"},
{key = "Dica: arraste a barra superior para mover a janela. Use o botão com a logo para mostrar ou ocultar.", "Tip: drag the top bar to move the window. Use the logo button to show or hide it.","Dica: arraste a barra superior para mover a janela. Use o botão com a logo para mostrar ou ocultar.","Consejo: arrastra la barra superior para mover la ventana. Usa el botón del logo para mostrarla u ocultarla.","Astuce : faites glisser la barre du haut pour déplacer la fenêtre. Utilisez le bouton du logo pour l'afficher ou la masquer.","Tipp: Ziehe die obere Leiste, um das Fenster zu verschieben. Mit dem Logo-Button blendest du es ein oder aus.","Tips: seret bilah atas untuk memindahkan jendela. Gunakan tombol logo untuk menampilkan atau menyembunyikannya."},
{"Your personal script library","Sua biblioteca pessoal de scripts","Tu biblioteca personal de scripts","Votre bibliothèque personnelle de scripts","Deine persönliche Skriptbibliothek","Pustaka skrip pribadimu"},
{"< Back","< Voltar","< Volver","< Retour","< Zurück","< Kembali"},
{"Edit Script","Editar script","Editar script","Modifier le script","Skript bearbeiten","Edit skrip"},
{"Script title","Título do script","Título del script","Titre du script","Skripttitel","Judul skrip"},
{"Notes or description (optional)","Notas ou descrição (opcional)","Notas o descripción (opcional)","Notes ou description (facultatif)","Notizen oder Beschreibung (optional)","Catatan atau deskripsi (opsional)"},
{"Paste or write Luau code here...","Cole ou escreva o código Luau aqui...","Pega o escribe código Luau aquí...","Collez ou écrivez du code Luau ici...","Luau-Code hier einfügen oder schreiben...","Tempel atau tulis kode Luau di sini..."},
{"Could not save to file","Não foi possível salvar no arquivo","No se pudo guardar en el archivo","Impossible d'enregistrer dans le fichier","Speichern in die Datei fehlgeschlagen","Gagal menyimpan ke berkas"},
{"No scripts yet. Tap + New to create your first one.","Nenhum script ainda. Toque em + Novo para criar o primeiro.","Aún no hay scripts. Toca + Nuevo para crear el primero.","Aucun script pour l'instant. Touchez + Nouveau pour créer le premier.","Noch keine Skripte. Tippe auf + Neu, um das erste zu erstellen.","Belum ada skrip. Ketuk + Baru untuk membuat yang pertama."},
{"Untitled Script","Script sem título","Script sin título","Script sans titre","Unbenanntes Skript","Skrip tanpa judul"},
{"No notes","Sem notas","Sin notas","Aucune note","Keine Notizen","Tanpa catatan"},
{"New","Novo","Nuevo","Nouveau","Neu","Baru"},
{"+ New","+ Novo","+ Nuevo","+ Nouveau","+ Neu","+ Baru"},
{"Save","Salvar","Guardar","Enregistrer","Speichern","Simpan"},
{"Run","Executar","Ejecutar","Exécuter","Ausführen","Jalankan"},
{"Enter a script title","Digite um título para o script","Escribe un título para el script","Saisissez un titre de script","Gib einen Skripttitel ein","Masukkan judul skrip"},
{"Add some Luau code","Adicione algum código Luau","Añade algo de código Luau","Ajoutez du code Luau","Füge etwas Luau-Code hinzu","Tambahkan kode Luau"},
{"Script saved","Script salvo","Script guardado","Script enregistré","Skript gespeichert","Skrip disimpan"},
{"Script is empty","O script está vazio","El script está vacío","Le script est vide","Das Skript ist leer","Skrip kosong"},
{"Saved Script","Script salvo","Script guardado","Script enregistré","Gespeichertes Skript","Skrip tersimpan"},
{"Delete","Excluir","Eliminar","Supprimer","Löschen","Hapus"},
{"Save this script before deleting it","Salve este script antes de excluir","Guarda este script antes de eliminarlo","Enregistrez ce script avant de le supprimer","Speichere dieses Skript vor dem Löschen","Simpan skrip ini sebelum menghapusnya"},
{"Script deleted","Script excluído","Script eliminado","Script supprimé","Skript gelöscht","Skrip dihapus"},
{"Run this session","Executados nesta sessão","Ejecutados en esta sesión","Exécutés cette session","In dieser Sitzung","Dijalankan sesi ini"},
{"Total executed","Total executado","Total ejecutado","Total exécuté","Insgesamt ausgeführt","Total dijalankan"},
{"Errors","Erros","Errores","Erreurs","Fehler","Kesalahan"},
{"Liked scripts","Scripts curtidos","Scripts que te gustan","Scripts aimés","Gelikte Skripte","Skrip disukai"},
{"Sessions","Sessões","Sesiones","Sessions","Sitzungen","Sesi"},
{"Session time","Tempo de sessão","Tiempo de sesión","Durée de session","Sitzungsdauer","Waktu sesi"},
{"Account age","Idade da conta","Antigüedad de la cuenta","Âge du compte","Kontoalter","Usia akun"},
{"Executor","Executor","Ejecutor","Exécuteur","Executor","Executor"},
{"Game","Jogo","Juego","Jeu","Spiel","Game"},
{"Place ID","ID do lugar","ID del lugar","ID du lieu","Place-ID","ID tempat"},
{"First used","Primeiro uso","Primer uso","Première utilisation","Erste Nutzung","Pertama dipakai"},
{"Unknown","Desconhecido","Desconocido","Inconnu","Unbekannt","Tidak diketahui"},
{"Stats","Estatísticas","Estadísticas","Statistiques","Statistiken","Statistik"},
{"Oct 25","25 out","25 oct","25 oct.","25. Okt.","25 Okt"},
{"First release of Hyundax IUM","Primeiro lançamento do Hyundax IUM","Primer lanzamiento de Hyundax IUM","Première version de Hyundax IUM","Erste Version von Hyundax IUM","Rilis pertama Hyundax IUM"},
{"Draggable, maximizable window with a black, red, blue and yellow theme","Janela arrastável e maximizável com tema preto, vermelho, azul e amarelo","Ventana arrastrable y maximizable con tema negro, rojo, azul y amarillo","Fenêtre déplaçable et agrandissable au thème noir, rouge, bleu et jaune","Verschiebbares, maximierbares Fenster im Schwarz-Rot-Blau-Gelb-Design","Jendela yang bisa digeser dan diperbesar dengan tema hitam, merah, biru, dan kuning"},
{"Home: Dashboard, Settings, Overview, My Scripts, Update Log, Recent Scripts and sUNC tests","Início: Painel, Configurações, Visão geral, Meus scripts, Conta, Novidades, Scripts recentes e testes sUNC","Inicio: Panel, Ajustes, Resumen, Mis scripts, Cuenta, Novedades, Scripts recientes y pruebas sUNC","Accueil : tableau de bord, paramètres, aperçu, mes scripts, compte, nouveautés, scripts récents et tests sUNC","Start: Dashboard, Einstellungen, Übersicht, Meine Skripte, Konto, Änderungen, letzte Skripte und sUNC-Tests","Beranda: Dasbor, Pengaturan, Ringkasan, Skrip saya, Akun, Pembaruan, skrip terbaru, dan tes sUNC"},
{"Editor: tabs, line numbers, line highlight, console mirroring F9, AutoExec, Exec Clipboard","Editor: abas, números de linha, destaque de linha, console espelhando o F9, AutoExec, Exec Clipboard","Editor: pestañas, números de línea, resaltado de línea, consola que replica F9, AutoExec, Exec Clipboard","Éditeur : onglets, numéros de ligne, surlignage de ligne, console reflétant F9, AutoExec, Exec Clipboard","Editor: Tabs, Zeilennummern, Zeilenmarkierung, Konsole als F9-Spiegel, AutoExec, Exec Clipboard","Editor: tab, nomor baris, sorotan baris, konsol cermin F9, AutoExec, Exec Clipboard"},
{"Forge: stack ready-made modules into one script","Forja: empilhe módulos prontos em um único script","Forja: apila módulos listos en un solo script","Forge : empilez des modules prêts à l'emploi dans un seul script","Schmiede: Fertige Module zu einem Skript stapeln","Forge: tumpuk modul siap pakai menjadi satu skrip"},
{"Scripts: ScriptBlox browser with 3x3 cards, likes and Cloud Scripts","Scripts: navegador do ScriptBlox com cards 3x3, curtidas e Cloud Scripts","Scripts: navegador de ScriptBlox con tarjetas 3x3, me gusta y Cloud Scripts","Scripts : navigateur ScriptBlox avec cartes 3x3, j'aime et Cloud Scripts","Skripte: ScriptBlox-Browser mit 3x3-Karten, Likes und Cloud-Skripten","Skrip: peramban ScriptBlox dengan kartu 3x3, suka, dan Cloud Scripts"},
{"Radar: live player radar with spectate, teleport and highlight","Radar: radar de jogadores ao vivo com observar, teleportar e destacar","Radar: radar de jugadores en vivo con espectar, teletransportar y resaltar","Radar : radar des joueurs en direct avec observation, téléportation et surlignage","Radar: Live-Spielerradar mit Zuschauen, Teleportieren und Hervorheben","Radar: radar pemain langsung dengan tonton, teleportasi, dan sorot"},
{"Dex: instance explorer and Finder, with code injection on the selected object","Dex: explorador de instâncias e Buscador, com injeção de código no objeto selecionado","Dex: explorador de instancias y Buscador, con inyección de código en el objeto seleccionado","Dex : explorateur d'instances et recherche, avec injection de code sur l'objet sélectionné","Dex: Instanz-Explorer und Suche, mit Code-Injektion auf das gewählte Objekt","Dex: penjelajah instans dan pencari, dengan injeksi kode pada objek terpilih"},
{"sUNC + HSS compatibility layer (~200 functions, polyfilled and tested)","Camada de compatibilidade sUNC + HSS (~200 funções, com polyfill e testadas)","Capa de compatibilidad sUNC + HSS (~200 funciones, con polyfill y probadas)","Couche de compatibilité sUNC + HSS (~200 fonctions, avec polyfill et testées)","sUNC- + HSS-Kompatibilitätsschicht (~200 Funktionen, mit Polyfill und getestet)","Lapisan kompatibilitas sUNC + HSS (~200 fungsi, dengan polyfill dan diuji)"},
{"Animated background waves, smooth animations and a floating logo button","Ondas animadas de fundo, animações suaves e um botão flutuante com a logo","Ondas animadas de fondo, animaciones suaves y un botón flotante con el logo","Vagues animées en arrière-plan, animations fluides et un bouton flottant avec le logo","Animierte Hintergrundwellen, flüssige Animationen und ein schwebender Logo-Button","Gelombang latar belakang beranimasi, animasi halus, dan tombol logo melayang"},
{"No recent scripts yet.","Nenhum script recente ainda.","Aún no hay scripts recientes.","Aucun script récent pour l'instant.","Noch keine letzten Skripte.","Belum ada skrip terbaru."},
{"Load","Carregar","Cargar","Charger","Laden","Muat"},
{"All","Todos","Todos","Tous","Alle","Semua"},
{"Native","Nativo","Nativo","Natif","Nativ","Asli"},
{"Issues","Problemas","Problemas","Problèmes","Probleme","Masalah"},
{"Running tests... this can take up to a minute.","Executando testes... isso pode levar até um minuto.","Ejecutando pruebas... puede tardar hasta un minuto.","Exécution des tests... cela peut prendre jusqu'à une minute.","Tests laufen... das kann bis zu einer Minute dauern.","Menjalankan tes... ini bisa memakan waktu hingga satu menit."},
{"Run tests","Executar testes","Ejecutar pruebas","Lancer les tests","Tests ausführen","Jalankan tes"},
{"Tests already running","Testes já em execução","Las pruebas ya se están ejecutando","Tests déjà en cours","Tests laufen bereits","Tes sudah berjalan"},
{"Copy report","Copiar relatório","Copiar informe","Copier le rapport","Bericht kopieren","Salin laporan"},
{"Report copied","Relatório copiado","Informe copiado","Rapport copié","Bericht kopiert","Laporan disalin"},
{"setclipboard unavailable","setclipboard indisponível","setclipboard no disponible","setclipboard indisponible","setclipboard nicht verfügbar","setclipboard tidak tersedia"},
{"Signed in","Conectado","Conectado","Connecté","Angemeldet","Masuk"},
{"Search files...","Buscar arquivos...","Buscar archivos...","Rechercher des fichiers...","Dateien suchen...","Cari berkas..."},
{"file APIs unavailable","APIs de arquivo indisponíveis","APIs de archivos no disponibles","API de fichiers indisponibles","Datei-APIs nicht verfügbar","API berkas tidak tersedia"},
{"file was not created","o arquivo não foi criado","el archivo no se creó","le fichier n'a pas été créé","Datei wurde nicht erstellt","berkas tidak dibuat"},
{"saved file missing","arquivo salvo não encontrado","falta el archivo guardado","fichier enregistré introuvable","gespeicherte Datei fehlt","berkas tersimpan hilang"},
{"No scripts yet","Nenhum script ainda","Aún no hay scripts","Aucun script pour l'instant","Noch keine Skripte","Belum ada skrip"},
{"-- Write your Luau here","-- Escreva seu Luau aqui","-- Escribe tu Luau aquí","-- Écrivez votre Luau ici","-- Schreibe hier dein Luau","-- Tulis Luau-mu di sini"},
{"Type a command and press Enter...","Digite um comando e pressione Enter...","Escribe un comando y pulsa Enter...","Tapez une commande et appuyez sur Entrée...","Befehl eingeben und Enter drücken...","Ketik perintah lalu tekan Enter..."},
{"Welcome","Boas-vindas","Bienvenido","Bienvenue","Willkommen","Selamat datang"},
{"Open script","Abrir script","Abrir script","Ouvrir le script","Skript öffnen","Buka skrip"},
{"New script","Novo script","Nuevo script","Nouveau script","Neues Skript","Skrip baru"},
{"Create a blank editor tab","Criar uma aba de editor em branco","Crear una pestaña de editor en blanco","Créer un onglet d'éditeur vide","Leeren Editor-Tab erstellen","Buat tab editor kosong"},
{"Open a local Hyundax IUM script","Abrir um script local do Hyundax IUM","Abrir un script local de Hyundax IUM","Ouvrir un script Hyundax IUM local","Lokales Hyundax IUM-Skript öffnen","Buka skrip Hyundax IUM lokal"},
{"Explore scripts","Explorar scripts","Explorar scripts","Explorer les scripts","Skripte entdecken","Jelajahi skrip"},
{"Browse the ScriptBlox Hub","Navegar no ScriptBlox Hub","Explorar el ScriptBlox Hub","Parcourir le ScriptBlox Hub","ScriptBlox Hub durchsuchen","Telusuri ScriptBlox Hub"},
{"Getting started","Primeiros passos","Primeros pasos","Premiers pas","Erste Schritte","Memulai"},
{"Current game","Jogo atual","Juego actual","Jeu actuel","Aktuelles Spiel","Game saat ini"},
{"CURRENT GAME","JOGO ATUAL","JUEGO ACTUAL","JEU ACTUEL","AKTUELLES SPIEL","GAME SAAT INI"},
{"Tip of the day","Dica do dia","Consejo del día","Astuce du jour","Tipp des Tages","Tips hari ini"},
{"TIP OF THE DAY","DICA DO DIA","CONSEJO DEL DÍA","ASTUCE DU JOUR","TIPP DES TAGES","TIPS HARI INI"},
{"Save scripts to AutoExec from the editor toolbar to run them when Hyundax IUM starts.","Salve scripts no AutoExec pela barra do editor para executá-los quando o Hyundax IUM iniciar.","Guarda scripts en AutoExec desde la barra del editor para ejecutarlos al iniciar Hyundax IUM.","Enregistrez des scripts dans AutoExec depuis la barre de l'éditeur pour les exécuter au démarrage de Hyundax IUM.","Speichere Skripte über die Editor-Leiste in AutoExec, damit sie beim Start von Hyundax IUM ausgeführt werden.","Simpan skrip ke AutoExec dari bilah editor agar dijalankan saat Hyundax IUM dimulai."},
{"Recent scripts","Scripts recentes","Scripts recientes","Scripts récents","Letzte Skripte","Skrip terbaru"},
{"No recent scripts yet. Execute a script to see it here.","Nenhum script recente ainda. Execute um script para vê-lo aqui.","Aún no hay scripts recientes. Ejecuta un script para verlo aquí.","Aucun script récent. Exécutez un script pour le voir ici.","Noch keine letzten Skripte. Führe ein Skript aus, um es hier zu sehen.","Belum ada skrip terbaru. Jalankan skrip agar muncul di sini."},
{"Open a blank tab in the editor","Abrir uma aba em branco no editor","Abrir una pestaña en blanco en el editor","Ouvrir un onglet vide dans l'éditeur","Leeren Tab im Editor öffnen","Buka tab kosong di editor"},
{"Browse the Script Hub","Navegar no Script Hub","Explorar el Script Hub","Parcourir le Script Hub","Script Hub durchsuchen","Telusuri Script Hub"},
{"Explore the game","Explorar o jogo","Explorar el juego","Explorer le jeu","Spiel erkunden","Jelajahi game"},
{"Inspect instances with Dex","Inspecione instâncias com o Dex","Inspecciona instancias con Dex","Inspectez les instances avec Dex","Instanzen mit Dex untersuchen","Periksa instance dengan Dex"},
{"Get started","Começar","Comenzar","Commencer","Loslegen","Mulai"},
{"Clipboard read is unavailable","Leitura da área de transferência indisponível","Lectura del portapapeles no disponible","Lecture du presse-papiers indisponible","Zwischenablage nicht lesbar","Pembacaan clipboard tidak tersedia"},
{"Clipboard read unavailable","Leitura da área de transferência indisponível","Lectura del portapapeles no disponible","Lecture du presse-papiers indisponible","Zwischenablage nicht lesbar","Pembacaan clipboard tidak tersedia"},
{"Execute","Executar","Ejecutar","Exécuter","Ausführen","Eksekusi"},
{"Editor is empty","O editor está vazio","El editor está vacío","L'éditeur est vide","Der Editor ist leer","Editor kosong"},
{"Could not save AutoExec","Não foi possível salvar o AutoExec","No se pudo guardar el AutoExec","Impossible d'enregistrer l'AutoExec","AutoExec konnte nicht gespeichert werden","Gagal menyimpan AutoExec"},
{"[autoexec] could not write files (writefile unavailable?)","[autoexec] não foi possível gravar arquivos (writefile indisponível?)","[autoexec] no se pudieron escribir archivos (¿writefile no disponible?)","[autoexec] impossible d'écrire les fichiers (writefile indisponible ?)","[autoexec] Dateien konnten nicht geschrieben werden (writefile nicht verfügbar?)","[autoexec] tidak bisa menulis berkas (writefile tidak tersedia?)"},
{"AutoExec saved","AutoExec salvo","AutoExec guardado","AutoExec enregistré","AutoExec gespeichert","AutoExec disimpan"},
{"Paste","Colar","Pegar","Coller","Einfügen","Tempel"},
{"Pasted into editor","Colado no editor","Pegado en el editor","Collé dans l'éditeur","In den Editor eingefügt","Ditempel ke editor"},
{"Exec Clipboard","Executar área de transferência","Ejecutar portapapeles","Exécuter le presse-papiers","Zwischenablage ausführen","Jalankan clipboard"},
{"Clipboard is empty or unavailable","Área de transferência vazia ou indisponível","El portapapeles está vacío o no disponible","Le presse-papiers est vide ou indisponible","Zwischenablage leer oder nicht verfügbar","Clipboard kosong atau tidak tersedia"},
{"Clear","Limpar","Limpiar","Effacer","Leeren","Bersihkan"},
{"Open","Abrir","Abrir","Ouvrir","Öffnen","Buka"},
{"Could not save","Não foi possível salvar","No se pudo guardar","Échec de l'enregistrement","Speichern fehlgeschlagen","Gagal menyimpan"},
{"Copy","Copiar","Copiar","Copier","Kopieren","Salin"},
{"Copied","Copiado","Copiado","Copié","Kopiert","Disalin"},
{"Untitled","Sem título","Sin título","Sans titre","Unbenannt","Tanpa judul"},
{"Universal Script","Script universal","Script universal","Script universel","Universelles Skript","Skrip universal"},
{"Search ScriptBlox...","Buscar no ScriptBlox...","Buscar en ScriptBlox...","Rechercher sur ScriptBlox...","ScriptBlox durchsuchen...","Cari di ScriptBlox..."},
{"Latest","Recentes","Recientes","Récents","Neueste","Terbaru"},
{"Trending","Em alta","Tendencias","Tendances","Im Trend","Tren"},
{"Saved","Salvos","Guardados","Enregistrés","Gespeichert","Tersimpan"},
{"Could not reach ScriptBlox.\nCheck your connection / HttpGet support.","Não foi possível acessar o ScriptBlox.\nVerifique sua conexão / suporte a HttpGet.","No se pudo acceder a ScriptBlox.\nRevisa tu conexión / soporte de HttpGet.","Impossible d'atteindre ScriptBlox.\nVérifiez votre connexion / la prise en charge de HttpGet.","ScriptBlox ist nicht erreichbar.\nPrüfe deine Verbindung / HttpGet-Unterstützung.","Tidak bisa menjangkau ScriptBlox.\nPeriksa koneksi / dukungan HttpGet."},
{"No saved scripts yet.\nTap the star on a script to save it.","Nenhum script salvo ainda.\nToque na estrela de um script para salvá-lo.","Aún no hay scripts guardados.\nToca la estrella de un script para guardarlo.","Aucun script enregistré pour l'instant.\nTouchez l'étoile d'un script pour l'enregistrer.","Noch keine gespeicherten Skripte.\nTippe auf den Stern eines Skripts, um es zu speichern.","Belum ada skrip tersimpan.\nKetuk bintang pada skrip untuk menyimpannya."},
{"No scripts found.","Nenhum script encontrado.","No se encontraron scripts.","Aucun script trouvé.","Keine Skripte gefunden.","Skrip tidak ditemukan."},
{"SCRIPT DETAILS","DETALHES DO SCRIPT","DETALLES DEL SCRIPT","DÉTAILS DU SCRIPT","SKRIPT-DETAILS","DETAIL SKRIP"},
{"NO KEY","SEM KEY","SIN KEY","SANS KEY","KEIN KEY","TANPA KEY"},
{"Copy Script","Copiar script","Copiar script","Copier le script","Skript kopieren","Salin skrip"},
{"Script copied","Script copiado","Script copiado","Script copié","Skript kopiert","Skrip disalin"},
{"Copy Loadstring","Copiar loadstring","Copiar loadstring","Copier le loadstring","Loadstring kopieren","Salin loadstring"},
{"Loadstring copied","Loadstring copiado","Loadstring copiado","Loadstring copié","Loadstring kopiert","Loadstring disalin"},
{"Copy Link","Copiar link","Copiar enlace","Copier le lien","Link kopieren","Salin tautan"},
{"Link copied","Link copiado","Enlace copiado","Lien copié","Link kopiert","Tautan disalin"},
{"Open in Editor","Abrir no editor","Abrir en el editor","Ouvrir dans l'éditeur","Im Editor öffnen","Buka di editor"},
{"Copy Game ID","Copiar ID do jogo","Copiar ID del juego","Copier l'ID du jeu","Spiel-ID kopieren","Salin ID game"},
{"Game ID copied","ID do jogo copiado","ID del juego copiado","ID du jeu copié","Spiel-ID kopiert","ID game disalin"},
{"Like removed","Curtida removida","Me gusta eliminado","J'aime retiré","Like entfernt","Suka dihapus"},
{"Liked","Curtido","Te gusta","Aimé","Geliked","Disukai"},
{"Removed from Cloud Scripts","Removido dos Cloud Scripts","Eliminado de Cloud Scripts","Retiré des Cloud Scripts","Aus Cloud-Skripten entfernt","Dihapus dari Cloud Scripts"},
{"Saved to Cloud Scripts","Salvo nos Cloud Scripts","Guardado en Cloud Scripts","Enregistré dans les Cloud Scripts","In Cloud-Skripten gespeichert","Disimpan ke Cloud Scripts"},
{"Search objects...","Buscar objetos...","Buscar objetos...","Rechercher des objets...","Objekte suchen...","Cari objek..."},
{"No results","Sem resultados","Sin resultados","Aucun résultat","Keine Ergebnisse","Tidak ada hasil"},
{"No results.","Sem resultados.","Sin resultados.","Aucun résultat.","Keine Ergebnisse.","Tidak ada hasil."},
{"Instance","Instância","Instancia","Instance","Instanz","Instans"},
{"No character yet","Ainda sem personagem","Aún sin personaje","Pas encore de personnage","Noch kein Charakter","Belum ada karakter"},
{"Refreshed","Atualizado","Actualizado","Actualisé","Aktualisiert","Disegarkan"},
{"Nothing selected","Nada selecionado","Nada seleccionado","Rien de sélectionné","Nichts ausgewählt","Tidak ada yang dipilih"},
{"Tap an object in the tree.","Toque em um objeto na árvore.","Toca un objeto en el árbol.","Touchez un objet dans l'arborescence.","Tippe auf ein Objekt im Baum.","Ketuk objek di pohon."},
{"State","Estado","Estado","État","Zustand","Status"},
{"not in the game tree","fora da árvore do jogo","fuera del árbol del juego","hors de l'arborescence du jeu","nicht im Spielbaum","tidak ada di pohon game"},
{"Children","Filhos","Hijos","Enfants","Kinder","Anak"},
{"Select an object first","Selecione um objeto primeiro","Selecciona un objeto primero","Sélectionnez d'abord un objet","Wähle zuerst ein Objekt","Pilih objek terlebih dahulu"},
{"Copy Path","Copiar caminho","Copiar ruta","Copier le chemin","Pfad kopieren","Salin path"},
{"Path copied","Caminho copiado","Ruta copiada","Chemin copié","Pfad kopiert","Path disalin"},
{"Copy Name","Copiar nome","Copiar nombre","Copier le nom","Namen kopieren","Salin nama"},
{"Name copied","Nome copiado","Nombre copiado","Nom copié","Name kopiert","Nama disalin"},
{"Reveal","Revelar","Revelar","Révéler","Anzeigen","Tampilkan"},
{"Select Parent","Selecionar pai","Seleccionar padre","Sélectionner le parent","Übergeordnetes wählen","Pilih induk"},
{"Already at the top","Já está no topo","Ya está arriba","Déjà tout en haut","Schon ganz oben","Sudah di atas"},
{"Teleport","Teleportar","Teletransportar","Téléporter","Teleportieren","Teleportasi"},
{"Teleported","Teleportado","Teletransportado","Téléporté","Teleportiert","Teleportasi berhasil"},
{"Can't teleport there","Não dá para teleportar para lá","No se puede teletransportar allí","Impossible de se téléporter là","Dorthin kann nicht teleportiert werden","Tidak bisa teleportasi ke sana"},
{"Destroy","Destruir","Destruir","Détruire","Zerstören","Hancurkan"},
{"Tap again","Toque de novo","Toca de nuevo","Touchez à nouveau","Nochmal tippen","Ketuk lagi"},
{"Destroyed","Destruído","Destruido","Détruit","Zerstört","Dihancurkan"},
{"Can't destroy that","Não dá para destruir isso","No se puede destruir eso","Impossible de détruire cela","Das kann nicht zerstört werden","Itu tidak bisa dihancurkan"},
{"Inject code","Injetar código","Inyectar código","Injecter du code","Code injizieren","Suntik kode"},
{"Runs on the selected object. Use `target` (or script.Parent) in your code.","Roda no objeto selecionado. Use `target` (ou script.Parent) no seu código.","Se ejecuta en el objeto seleccionado. Usa `target` (o script.Parent) en tu código.","S'exécute sur l'objet sélectionné. Utilisez `target` (ou script.Parent) dans votre code.","Läuft auf dem gewählten Objekt. Verwende `target` (oder script.Parent) in deinem Code.","Berjalan pada objek terpilih. Gunakan `target` (atau script.Parent) di kodemu."},
{"Anchor","Ancorar","Anclar","Ancrer","Verankern","Jangkar"},
{"No collide","Sem colisão","Sin colisión","Sans collision","Keine Kollision","Tanpa tabrakan"},
{"Red","Vermelho","Rojo","Rouge","Rot","Merah"},
{"Print tree","Imprimir árvore","Imprimir árbol","Afficher l'arbre","Baum ausgeben","Cetak pohon"},
{"Click","Clicar","Clic","Clic","Klick","Klik"},
{"Write some code first","Escreva algum código primeiro","Escribe algo de código primero","Écrivez d'abord du code","Schreibe zuerst etwas Code","Tulis kode terlebih dahulu"},
{"Injected","Injetado","Inyectado","Injecté","Injiziert","Disuntik"},
{"[loop] target is gone, stopped","[loop] o alvo sumiu, parado","[loop] el objetivo desapareció, detenido","[loop] la cible a disparu, arrêté","[loop] Ziel ist weg, gestoppt","[loop] target hilang, dihentikan"},
{"Loop started","Loop iniciado","Bucle iniciado","Boucle démarrée","Schleife gestartet","Loop dimulai"},
{"Loop","Loop","Bucle","Boucle","Schleife","Loop"},
{"Stop all","Parar tudo","Detener todo","Tout arrêter","Alle stoppen","Hentikan semua"},
{"Loops stopped","Loops parados","Bucles detenidos","Boucles arrêtées","Schleifen gestoppt","Loop dihentikan"},
{"Search instances by name or class...","Buscar instâncias por nome ou classe...","Buscar instancias por nombre o clase...","Rechercher des instances par nom ou classe...","Instanzen nach Name oder Klasse suchen...","Cari instans berdasarkan nama atau kelas..."},
{"Type a name or pick a filter.","Digite um nome ou escolha um filtro.","Escribe un nombre o elige un filtro.","Saisissez un nom ou choisissez un filtre.","Gib einen Namen ein oder wähle einen Filter.","Ketik nama atau pilih filter."},
{"Use","Usar","Usar","Utiliser","Nutzen","Pakai"},
{key = "chip:Parts", "Parts","Partes","Partes","Parties","Teile","Part"},
{key = "chip:Models", "Models","Modelos","Modelos","Modèles","Modelle","Model"},
{key = "chip:Sounds", "Sounds","Sons","Sonidos","Sons","Sounds","Suara"},
{key = "chip:Lights", "Lights","Luzes","Luces","Lumières","Lichter","Lampu"},
{key = "PLAYERS", "PLAYERS","JOGADORES","JUGADORES","JOUEURS","SPIELER","PEMAIN"},
{key = "FRONT", "FRONT","FRENTE","FRENTE","AVANT","VORNE","DEPAN"},
{key = "RANGE", "RANGE","ALCANCE","ALCANCE","PORTÉE","REICHWEITE","JANGKAUAN"},
{"Live player radar: spectate, teleport and highlight","Radar de jogadores ao vivo: observe, teleporte e destaque","Radar de jugadores en vivo: espectea, teletransporta y resalta","Radar des joueurs en direct : observez, téléportez et surlignez","Live-Spielerradar: zuschauen, teleportieren und hervorheben","Radar pemain langsung: tonton, teleportasi, dan sorot"},
{"Spectate","Observar","Espectar","Observer","Zuschauen","Tonton"},
{"Highlight","Destacar","Resaltar","Surligner","Hervorheben","Sorot"},
{"Highlight: on","Destaque: ligado","Resaltado: activado","Surlignage : activé","Hervorhebung: an","Sorot: aktif"},
{"Tap a player first","Toque em um jogador primeiro","Toca un jugador primero","Touchez d'abord un joueur","Tippe zuerst auf einen Spieler","Ketuk pemain terlebih dahulu"},
{"No character to watch","Nenhum personagem para observar","Ningún personaje para observar","Aucun personnage à observer","Kein Charakter zum Zuschauen","Tidak ada karakter untuk ditonton"},
{"Stop","Parar","Detener","Arrêter","Stopp","Berhenti"},
{"Highlight on","Destaque ligado","Resaltado activado","Surlignage activé","Hervorhebung an","Sorot aktif"},
{"Highlight off","Destaque desligado","Resaltado desactivado","Surlignage désactivé","Hervorhebung aus","Sorot nonaktif"},
{"Copy name","Copiar nome","Copiar nombre","Copier le nom","Namen kopieren","Salin nama"},
{"Tap modules to stack them into one script","Toque nos módulos para empilhá-los em um único script","Toca los módulos para apilarlos en un solo script","Touchez des modules pour les empiler dans un seul script","Tippe auf Module, um sie zu einem Skript zu stapeln","Ketuk modul untuk menumpuknya menjadi satu skrip"},
{"Search modules...","Buscar módulos...","Buscar módulos...","Rechercher des modules...","Module suchen...","Cari modul..."},
{"No modules selected","Nenhum módulo selecionado","Ningún módulo seleccionado","Aucun module sélectionné","Keine Module ausgewählt","Tidak ada modul dipilih"},
{"To Editor","Para o editor","Al editor","Vers l'éditeur","In den Editor","Ke editor"},
{"Pick at least one module","Escolha pelo menos um módulo","Elige al menos un módulo","Choisissez au moins un module","Wähle mindestens ein Modul","Pilih setidaknya satu modul"},
{"Run all","Executar tudo","Ejecutar todo","Tout exécuter","Alle ausführen","Jalankan semua"},
{"Movement","Movimento","Movimiento","Mouvement","Bewegung","Gerakan"},
{"Utility","Utilidades","Utilidades","Utilitaires","Hilfen","Utilitas"},
{"Server","Servidor","Servidor","Serveur","Server","Server"},
{"Copied place info","Info do lugar copiada","Info del lugar copiada","Infos du lieu copiées","Place-Info kopiert","Info tempat disalin"},
{"Hello World","Olá, mundo","Hola mundo","Bonjour le monde","Hallo Welt","Halo Dunia"},
{"Prints a message to the console","Imprime uma mensagem no console","Imprime un mensaje en la consola","Affiche un message dans la console","Gibt eine Nachricht in der Konsole aus","Mencetak pesan ke konsol"},
{"Player List","Lista de jogadores","Lista de jugadores","Liste des joueurs","Spielerliste","Daftar pemain"},
{"Lists every player in the server","Lista todos os jogadores do servidor","Lista a todos los jugadores del servidor","Liste tous les joueurs du serveur","Listet alle Spieler auf dem Server auf","Menampilkan semua pemain di server"},
{"Speed & Jump","Velocidade e pulo","Velocidad y salto","Vitesse et saut","Tempo & Sprung","Kecepatan & lompat"},
{"Infinite Jump","Pulo infinito","Salto infinito","Saut infini","Unendlicher Sprung","Lompat tak terbatas"},
{"Jump again while in the air","Pule de novo no ar","Salta de nuevo en el aire","Sautez à nouveau en l'air","Springe erneut in der Luft","Lompat lagi saat di udara"},
{"Stops the idle kick","Impede o kick por inatividade","Evita la expulsión por inactividad","Empêche l'expulsion pour inactivité","Verhindert den Inaktivitäts-Kick","Mencegah kick karena tidak aktif"},
{"Removes darkness and fog","Remove escuridão e neblina","Elimina la oscuridad y la niebla","Supprime l'obscurité et le brouillard","Entfernt Dunkelheit und Nebel","Menghilangkan kegelapan dan kabut"},
{"Reset Character","Resetar personagem","Reiniciar personaje","Réinitialiser le personnage","Charakter zurücksetzen","Reset karakter"},
{"Respawns your character","Faz seu personagem renascer","Reaparece tu personaje","Fait réapparaître votre personnage","Lässt deinen Charakter respawnen","Memunculkan ulang karaktermu"},
{"Walk through walls","Atravesse paredes","Atraviesa paredes","Traversez les murs","Durch Wände gehen","Tembus dinding"},
{"Rejoin","Reentrar","Volver a entrar","Se reconnecter","Erneut beitreten","Gabung ulang"},
{"Reconnects to this server","Reconecta a este servidor","Se reconecta a este servidor","Se reconnecte à ce serveur","Verbindet erneut mit diesem Server","Terhubung ulang ke server ini"},
{"Server Hop","Trocar de servidor","Cambiar de servidor","Changer de serveur","Server wechseln","Pindah server"},
{"Joins another public server","Entra em outro servidor público","Entra en otro servidor público","Rejoint un autre serveur public","Tritt einem anderen öffentlichen Server bei","Bergabung ke server publik lain"},
{"Spin","Girar","Girar","Tourner","Drehen","Berputar"},
{"Spins your character","Gira seu personagem","Hace girar a tu personaje","Fait tourner votre personnage","Dreht deinen Charakter","Memutar karaktermu"},
{"Day Time","Dia","Día","Jour","Tag","Siang"},
{"Sets the clock to noon","Ajusta o relógio para meio-dia","Pone el reloj al mediodía","Règle l'horloge sur midi","Stellt die Uhr auf Mittag","Mengatur jam ke tengah hari"},
{"Remove Fog","Remover neblina","Quitar niebla","Supprimer le brouillard","Nebel entfernen","Hapus kabut"},
{"Clears distance fog","Limpa a neblina de distância","Limpia la niebla lejana","Efface le brouillard lointain","Entfernt den Distanznebel","Menghapus kabut jarak jauh"},
{"FPS Boost","Aumentar FPS","Mejorar FPS","Booster les FPS","FPS-Boost","Tingkatkan FPS"},
{"Less shadows and effects","Menos sombras e efeitos","Menos sombras y efectos","Moins d'ombres et d'effets","Weniger Schatten und Effekte","Lebih sedikit bayangan dan efek"},
{"Click Teleport","Teleporte por clique","Teletransporte con clic","Téléportation par clic","Klick-Teleport","Teleportasi klik"},
{"Tap anywhere to teleport there","Toque em qualquer lugar para teleportar","Toca en cualquier lugar para teletransportarte","Touchez n'importe où pour vous y téléporter","Tippe irgendwohin, um dich dorthin zu teleportieren","Ketuk di mana saja untuk teleportasi ke sana"},
{"Teleport To Player","Teleportar até jogador","Teletransportar a jugador","Se téléporter vers un joueur","Zu Spieler teleportieren","Teleportasi ke pemain"},
{"Edit the name and run","Edite o nome e execute","Edita el nombre y ejecuta","Modifiez le nom et exécutez","Name ändern und ausführen","Ubah namanya lalu jalankan"},
{"List Remotes","Listar remotes","Listar remotes","Lister les remotes","Remotes auflisten","Daftar remote"},
{"Prints every RemoteEvent/Function","Imprime todos os RemoteEvent/Function","Imprime todos los RemoteEvent/Function","Affiche tous les RemoteEvent/Function","Gibt alle RemoteEvent/Function aus","Mencetak semua RemoteEvent/Function"},
{"Copy Place Info","Copiar info do lugar","Copiar info del lugar","Copier les infos du lieu","Place-Info kopieren","Salin info tempat"},
{"Tune the interface and the editor","Ajuste a interface e o editor","Ajusta la interfaz y el editor","Réglez l'interface et l'éditeur","Passe die Oberfläche und den Editor an","Atur antarmuka dan editor"},
{"Animation speed","Velocidade das animações","Velocidad de animación","Vitesse des animations","Animationsgeschwindigkeit","Kecepatan animasi"},
{"How slow the interface animates","Quão lenta é a animação da interface","Qué tan lenta se anima la interfaz","Lenteur d'animation de l'interface","Wie langsam die Oberfläche animiert","Seberapa lambat antarmuka beranimasi"},
{"Slow","Lenta","Lenta","Lente","Langsam","Lambat"},
{"Normal","Normal","Normal","Normale","Normal","Normal"},
{"Fast","Rápida","Rápida","Rapide","Schnell","Cepat"},
{"Background waves","Ondas de fundo","Ondas de fondo","Vagues d'arrière-plan","Hintergrundwellen","Gelombang latar"},
{"Wavy lines and glowing dots behind the UI","Linhas onduladas e pontos brilhantes atrás da interface","Líneas onduladas y puntos brillantes detrás de la interfaz","Lignes ondulées et points lumineux derrière l'interface","Wellenlinien und leuchtende Punkte hinter der Oberfläche","Garis bergelombang dan titik bercahaya di belakang antarmuka"},
{"Line numbers","Números de linha","Números de línea","Numéros de ligne","Zeilennummern","Nomor baris"},
{"Show the gutter in the editor","Mostrar a margem no editor","Mostrar el margen en el editor","Afficher la gouttière dans l'éditeur","Zeilenrand im Editor anzeigen","Tampilkan kolom nomor di editor"},
{"Word wrap","Quebra de linha","Ajuste de línea","Retour à la ligne","Zeilenumbruch","Bungkus baris"},
{"Wrap long lines in the editor","Quebrar linhas longas no editor","Ajustar líneas largas en el editor","Renvoyer les longues lignes dans l'éditeur","Lange Zeilen im Editor umbrechen","Bungkus baris panjang di editor"},
{"Console auto-scroll","Rolagem automática do console","Desplazamiento automático de la consola","Défilement auto de la console","Konsole automatisch scrollen","Gulir otomatis konsol"},
{"Follow new console lines","Acompanhar novas linhas do console","Seguir las nuevas líneas de la consola","Suivre les nouvelles lignes de la console","Neuen Konsolenzeilen folgen","Ikuti baris konsol baru"},
{"Floating button","Botão flutuante","Botón flotante","Bouton flottant","Schwebender Button","Tombol melayang"},
{"Hide it and use RightShift to open","Oculte e use RightShift para abrir","Ocúltalo y usa RightShift para abrir","Masquez-le et utilisez RightShift pour ouvrir","Ausblenden und mit RightShift öffnen","Sembunyikan dan gunakan RightShift untuk membuka"},
{"Invalid value","Valor inválido","Valor no válido","Valeur invalide","Ungültiger Wert","Nilai tidak valid"},
{"Invalid font name","Nome de fonte inválido","Nombre de fuente no válido","Nom de police invalide","Ungültiger Schriftname","Nama font tidak valid"},
{"Font applied","Fonte aplicada","Fuente aplicada","Police appliquée","Schrift angewendet","Font diterapkan"},
{"Disable pill and line","Desativar pílula e linha","Desactivar píldora y línea","Désactiver la pilule et la ligne","Pille und Linie deaktivieren","Nonaktifkan pil dan garis"},
{"When enabled, closing hides the UI but keeps the toggle bubble","Quando ativado, fechar oculta a interface, mas mantém a bolinha de alternância","Al activarlo, cerrar oculta la interfaz, pero mantiene la burbuja de alternancia","Lorsque cette option est activée, fermer masque l’interface mais conserve la bulle de bascule","Wenn aktiviert, wird beim Schließen die Oberfläche ausgeblendet, aber die Umschaltkugel bleibt sichtbar","Jika aktif, menutup akan menyembunyikan UI tetapi tetap menampilkan tombol gelembung"},
{"Toast messages","Mensagens rápidas","Mensajes emergentes","Messages éphémères","Kurzmeldungen","Pesan singkat"},
{"Small pop-up notices at the bottom","Pequenos avisos na parte inferior","Pequeños avisos en la parte inferior","Petites notifications en bas","Kleine Hinweise am unteren Rand","Pemberitahuan kecil di bagian bawah"},
{"Run AutoExec on load","Executar AutoExec ao carregar","Ejecutar AutoExec al cargar","Exécuter AutoExec au chargement","AutoExec beim Laden ausführen","Jalankan AutoExec saat dimuat"},
{"Run saved AutoExec scripts when Hyundax IUM starts","Executa os scripts AutoExec salvos quando o Hyundax IUM inicia","Ejecuta los scripts AutoExec guardados al iniciar Hyundax IUM","Exécute les scripts AutoExec enregistrés au lancement de Hyundax IUM","Führt gespeicherte AutoExec-Skripte beim Start von Hyundax IUM aus","Menjalankan skrip AutoExec tersimpan saat Hyundax IUM dimulai"},
{"Clear console","Limpar console","Limpiar consola","Vider la console","Konsole leeren","Bersihkan konsol"},
{"Remove every line from the console","Remove todas as linhas do console","Elimina todas las líneas de la consola","Supprime toutes les lignes de la console","Entfernt alle Zeilen aus der Konsole","Hapus semua baris dari konsol"},
{"Console cleared","Console limpo","Consola limpiada","Console vidée","Konsole geleert","Konsol dibersihkan"},
{"Copy debug info","Copiar info de debug","Copiar info de depuración","Copier les infos de débogage","Debug-Infos kopieren","Salin info debug"},
{"Executor, game and version for bug reports","Executor, jogo e versão para relatar bugs","Executor, juego y versión para reportar errores","Exécuteur, jeu et version pour les rapports de bugs","Executor, Spiel und Version für Fehlerberichte","Executor, game, dan versi untuk laporan bug"},
{"Debug info copied","Info de debug copiada","Info de depuración copiada","Infos de débogage copiées","Debug-Infos kopiert","Info debug disalin"},
{"Run sUNC tests","Executar testes sUNC","Ejecutar pruebas sUNC","Lancer les tests sUNC","sUNC-Tests ausführen","Jalankan tes sUNC"},
{"Check which executor functions work","Veja quais funções do executor funcionam","Comprueba qué funciones del ejecutor funcionan","Vérifiez quelles fonctions de l'exécuteur fonctionnent","Prüfe, welche Executor-Funktionen funktionieren","Cek fungsi executor mana yang berfungsi"},
{"Tests started, see Home > sUNC","Testes iniciados, veja Início > sUNC","Pruebas iniciadas, mira Inicio > sUNC","Tests lancés, voir Accueil > sUNC","Tests gestartet, siehe Start > sUNC","Tes dimulai, lihat Beranda > sUNC"},
{"Reset statistics","Redefinir estatísticas","Restablecer estadísticas","Réinitialiser les statistiques","Statistiken zurücksetzen","Atur ulang statistik"},
{"Zero the total and error counters","Zera os contadores de total e erros","Pone a cero los contadores de total y errores","Remet à zéro les compteurs de total et d'erreurs","Setzt die Zähler für Gesamt und Fehler zurück","Nol-kan penghitung total dan kesalahan"},
{"Reset","Redefinir","Restablecer","Réinitialiser","Zurücksetzen","Atur ulang"},
{"Statistics reset","Estatísticas redefinidas","Estadísticas restablecidas","Statistiques réinitialisées","Statistiken zurückgesetzt","Statistik diatur ulang"},
{"sec","s","s","s","Sek.","dtk"},
{"Language","Idioma","Idioma","Langue","Sprache","Bahasa"},
{"Choose the interface language","Escolha o idioma da interface","Elige el idioma de la interfaz","Choisissez la langue de l'interface","Wähle die Sprache der Oberfläche","Pilih bahasa antarmuka"},
{"Language changed","Idioma alterado","Idioma cambiado","Langue modifiée","Sprache geändert","Bahasa diubah"},
{"Nickname","Apelido","Apodo","Surnom","Spitzname","Nama panggilan"},
{"How Hyundax IUM calls you (optional)","Como o Hyundax IUM chama você (opcional)","Cómo te llama Hyundax IUM (opcional)","Comment Hyundax IUM vous appelle (facultatif)","Wie Hyundax IUM dich nennt (optional)","Cara Hyundax IUM memanggilmu (opsional)"},
{"Nickname saved","Apelido salvo","Apodo guardado","Surnom enregistré","Spitzname gespeichert","Nama panggilan disimpan"},
{"Ask on startup","Perguntar ao iniciar","Preguntar al iniciar","Demander au démarrage","Beim Start fragen","Tanya saat memulai"},
{"Show the nickname and language screen when Hyundax IUM starts","Mostrar a tela de apelido e idioma ao iniciar o Hyundax IUM","Mostrar la pantalla de apodo e idioma al iniciar Hyundax IUM","Afficher l'écran du surnom et de la langue au lancement de Hyundax IUM","Bildschirm für Spitzname und Sprache beim Start von Hyundax IUM anzeigen","Tampilkan layar nama panggilan dan bahasa saat Hyundax IUM dimulai"},
{"Set up before you start","Configure antes de começar","Configura antes de empezar","Configurez avant de commencer","Einrichten, bevor es losgeht","Atur sebelum memulai"},
{"Login","Entrar","Iniciar sesión","Connexion","Anmelden","Masuk"},
{"Register","Criar conta","Registrarse","S'inscrire","Registrieren","Daftar"},
{"Sign in to continue","Entre para continuar","Inicia sesión para continuar","Connectez-vous pour continuer","Melde dich an, um fortzufahren","Masuk untuk melanjutkan"},
{"Create your account","Crie sua conta","Crea tu cuenta","Créez votre compte","Erstelle dein Konto","Buat akunmu"},
{"Username","Usuário","Usuario","Nom d'utilisateur","Benutzername","Nama pengguna"},
{"Password","Senha","Contraseña","Mot de passe","Passwort","Kata sandi"},
{"Confirm password","Confirmar senha","Confirmar contraseña","Confirmer le mot de passe","Passwort bestätigen","Konfirmasi kata sandi"},
{"Sign in","Entrar","Entrar","Se connecter","Anmelden","Masuk"},
{"Create account","Criar conta","Crear cuenta","Créer le compte","Konto erstellen","Buat akun"},
{"Sign in to account","Entrar em conta","Entrar a la cuenta","Se connecter","Im Konto anmelden","Masuk ke akun"},
{"Back","Voltar","Volver","Retour","Zurück","Kembali"},
{"Color ping by quality","Colorir ping pela qualidade","Colorear ping por calidad","Colorer le ping selon la qualité","Ping nach Qualität einfärben","Warnai ping sesuai kualitas"},
{"Compact mode","Modo compacto","Modo compacto","Mode compact","Kompaktmodus","Mode ringkas"},
{"Transparent background","Fundo transparente","Fondo transparente","Fond transparent","Transparenter Hintergrund","Latar transparan"},
{"Eco","Econômico","Económico","Éco","Sparsam","Hemat"},
{"Stay signed in","Manter conectado","Mantener sesión","Rester connecté","Angemeldet bleiben","Tetap masuk"},
{"Fill in every field","Preencha todos os campos","Rellena todos los campos","Remplissez tous les champs","Fülle alle Felder aus","Isi semua kolom"},
{"Username: 3-16 letters, numbers or _","Usuário: 3-16 letras, números ou _","Usuario: 3-16 letras, números o _","Nom : 3-16 lettres, chiffres ou _","Name: 3-16 Buchstaben, Zahlen oder _","Nama: 3-16 huruf, angka atau _"},
{"Password needs at least 4 characters","A senha precisa de pelo menos 4 caracteres","La contraseña necesita al menos 4 caracteres","Le mot de passe doit avoir au moins 4 caractères","Das Passwort braucht mindestens 4 Zeichen","Kata sandi minimal 4 karakter"},
{"Passwords do not match","As senhas não coincidem","Las contraseñas no coinciden","Les mots de passe ne correspondent pas","Passwörter stimmen nicht überein","Kata sandi tidak cocok"},
{"That username is already taken","Esse usuário já existe","Ese usuario ya existe","Ce nom est déjà pris","Dieser Name ist bereits vergeben","Nama pengguna sudah dipakai"},
{"Account not found","Conta não encontrada","Cuenta no encontrada","Compte introuvable","Konto nicht gefunden","Akun tidak ditemukan"},
{"Wrong password","Senha incorreta","Contraseña incorrecta","Mot de passe incorrect","Falsches Passwort","Kata sandi salah"},
{"Could not save the account","Não foi possível salvar a conta","No se pudo guardar la cuenta","Impossible d'enregistrer le compte","Konto konnte nicht gespeichert werden","Gagal menyimpan akun"},
{"Accounts are saved only on this device","As contas ficam salvas só neste aparelho","Las cuentas se guardan solo en este dispositivo","Les comptes sont enregistrés uniquement sur cet appareil","Konten werden nur auf diesem Gerät gespeichert","Akun hanya disimpan di perangkat ini"},
{"Sign out","Sair","Cerrar sesión","Se déconnecter","Abmelden","Keluar"},
{"Log out and return to the login screen","Sai da conta e volta para a tela de login","Cierra la sesión y vuelve a la pantalla de inicio","Se déconnecter et revenir à l'écran de connexion","Abmelden und zum Anmeldebildschirm zurückkehren","Keluar dari akun dan kembali ke layar masuk"},
{"Nickname (optional)","Apelido (opcional)","Apodo (opcional)","Surnom (facultatif)","Spitzname (optional)","Nama panggilan (opsional)"},
{"Type a nickname...","Digite um apelido...","Escribe un apodo...","Saisissez un surnom...","Spitznamen eingeben...","Ketik nama panggilan..."},
{"Continue","Continuar","Continuar","Continuer","Weiter","Lanjutkan"},
{"Quick actions","Ações rápidas","Acciones rápidas","Actions rapides","Schnellaktionen","Aksi cepat"},
{"Favorites","Favoritos","Favoritos","Favoris","Favoriten","Favorit"},
{"You can change this later in Settings","Você pode mudar isso depois em Configurações","Puedes cambiarlo después en Ajustes","Vous pourrez le modifier plus tard dans Paramètres","Das kannst du später unter Einstellungen ändern","Kamu bisa mengubahnya nanti di Pengaturan"},
{"Plugins","Plugins","Plugins","Plugins","Plugins","Plugin"},
{"Extend and customize Hyundax IUM with plugins","Estenda e personalize o Hyundax IUM com plugins","Amplía y personaliza Hyundax IUM con plugins","Étendez et personnalisez Hyundax IUM avec des plugins","Erweitere und personalisiere Hyundax IUM mit Plugins","Perluas dan sesuaikan Hyundax IUM dengan plugin"},
{"Post a plugin","Postar um plugin","Publicar un plugin","Publier un plugin","Plugin veröffentlichen","Kirim plugin"},
{"Give it a name, paste the code below and post. It changes Hyundax IUM right away.","Dê um nome, cole o código abaixo e poste. Ele modifica o Hyundax IUM na hora.","Ponle un nombre, pega el código abajo y publícalo. Modifica Hyundax IUM al instante.","Donnez-lui un nom, collez le code ci-dessous et publiez. Il modifie Hyundax IUM aussitôt.","Gib ihm einen Namen, füge den Code unten ein und poste ihn. Er verändert Hyundax IUM sofort.","Beri nama, tempel kode di bawah, lalu kirim. Plugin langsung mengubah Hyundax IUM."},
{"Plugin name","Nome do plugin","Nombre del plugin","Nom du plugin","Plugin-Name","Nama plugin"},
{"Paste the plugin code here...","Cole o código do plugin aqui...","Pega el código del plugin aquí...","Collez le code du plugin ici...","Plugin-Code hier einfügen...","Tempel kode plugin di sini..."},
{"Post plugin","Postar plugin","Publicar plugin","Publier le plugin","Plugin posten","Kirim plugin"},
{"Template","Modelo","Plantilla","Modèle","Vorlage","Templat"},
{"Plugins run with full executor access. Only post code you trust.","Plugins rodam com acesso total do executor. Poste apenas códigos em que você confia.","Los plugins se ejecutan con acceso total del executor. Publica solo código de confianza.","Les plugins s'exécutent avec un accès complet à l'executor. Ne publiez que du code de confiance.","Plugins laufen mit vollem Executor-Zugriff. Poste nur Code, dem du vertraust.","Plugin berjalan dengan akses penuh executor. Kirim hanya kode yang kamu percaya."},
{"Installed plugins","Plugins instalados","Plugins instalados","Plugins installés","Installierte Plugins","Plugin terpasang"},
{"Search plugins...","Buscar plugins...","Buscar plugins...","Rechercher des plugins...","Plugins suchen...","Cari plugin..."},
{"No plugins found.","Nenhum plugin encontrado.","No se encontraron plugins.","Aucun plugin trouvé.","Keine Plugins gefunden.","Plugin tidak ditemukan."},
{"Created by","Criado por","Creado por","Créé par","Erstellt von","Dibuat oleh"},
{"Official","Oficial","Oficial","Officiel","Offiziell","Resmi"},
{"Custom","Personalizado","Personalizado","Personnalisé","Eigenes","Kustom"},
{"Custom plugin.","Plugin personalizado.","Plugin personalizado.","Plugin personnalisé.","Eigenes Plugin.","Plugin kustom."},
{"Edit","Editar","Editar","Modifier","Bearbeiten","Ubah"},
{"Sure?","Certeza?","¿Seguro?","Sûr ?","Sicher?","Yakin?"},
{"Remove","Remover","Quitar","Retirer","Entfernen","Hapus"},
{"Plugin posted","Plugin postado","Plugin publicado","Plugin publié","Plugin gepostet","Plugin terkirim"},
{"Plugin enabled","Plugin ativado","Plugin activado","Plugin activé","Plugin aktiviert","Plugin diaktifkan"},
{"Plugin disabled","Plugin desativado","Plugin desactivado","Plugin désactivé","Plugin deaktiviert","Plugin dinonaktifkan"},
{"Plugin deleted","Plugin excluído","Plugin eliminado","Plugin supprimé","Plugin gelöscht","Plugin dihapus"},
{"Plugin error, see Console","Erro no plugin, veja o Console","Error del plugin, mira la Consola","Erreur du plugin, voir la Console","Plugin-Fehler, siehe Konsole","Kesalahan plugin, lihat Konsol"},
{"Name and code are required","Nome e código são obrigatórios","Nombre y código son obligatorios","Le nom et le code sont requis","Name und Code sind erforderlich","Nama dan kode wajib diisi"},
{"Syntax error in plugin code","Erro de sintaxe no código do plugin","Error de sintaxis en el código del plugin","Erreur de syntaxe dans le code du plugin","Syntaxfehler im Plugin-Code","Kesalahan sintaks pada kode plugin"},
{"Editing plugin: press Post to update it","Editando plugin: aperte Postar para atualizar","Editando plugin: pulsa Publicar para actualizarlo","Modification du plugin : appuyez sur Publier pour le mettre à jour","Plugin wird bearbeitet: Posten zum Aktualisieren","Mengedit plugin: tekan Kirim untuk memperbarui"},
{"Active","Ativos","Activos","Actifs","Aktiv","Aktif"},
{"Installed","Instalados","Instalados","Installés","Installiert","Terpasang"},
{"Code copied","Código copiado","Código copiado","Code copié","Code kopiert","Kode disalin"},
{"Set any image link (catbox.moe...) as the Hyundax IUM background, with optional glass panels.","Use qualquer link de imagem (catbox.moe...) como fundo do Hyundax IUM, com painéis de vidro opcionais.","Usa cualquier enlace de imagen (catbox.moe...) como fondo de Hyundax IUM, con paneles de cristal opcionales.","Utilisez n'importe quel lien d'image (catbox.moe...) comme fond de Hyundax IUM, avec des panneaux en verre en option.","Nutze einen beliebigen Bildlink (catbox.moe...) als Hyundax IUM-Hintergrund, optional mit Glas-Panels.","Pakai tautan gambar apa saja (catbox.moe...) sebagai latar Hyundax IUM, dengan panel kaca opsional."},
{"Search bar to jump to pages, settings, themes, recent scripts and plugin commands. Shortcut: Ctrl+K.","Barra de busca para ir a páginas, configurações, temas, scripts recentes e comandos de plugins. Atalho: Ctrl+K.","Barra de búsqueda para ir a páginas, ajustes, temas, scripts recientes y comandos de plugins. Atajo: Ctrl+K.","Barre de recherche pour accéder aux pages, paramètres, thèmes, scripts récents et commandes de plugins. Raccourci : Ctrl+K.","Suchleiste für Seiten, Einstellungen, Themes, letzte Skripte und Plugin-Befehle. Kürzel: Strg+K.","Bilah pencarian untuk membuka halaman, pengaturan, tema, skrip terbaru, dan perintah plugin. Pintasan: Ctrl+K."},
{"Animated rainbow glow around the Hyundax IUM window, with speed and thickness options.","Brilho arco-íris animado ao redor da janela do Hyundax IUM, com opções de velocidade e espessura.","Brillo arcoíris animado alrededor de la ventana de Hyundax IUM, con opciones de velocidad y grosor.","Halo arc-en-ciel animé autour de la fenêtre de Hyundax IUM, avec réglages de vitesse et d'épaisseur.","Animiertes Regenbogenleuchten um das Hyundax IUM-Fenster, mit Optionen für Tempo und Dicke.","Cahaya pelangi beranimasi di sekitar jendela Hyundax IUM, dengan opsi kecepatan dan ketebalan."},
{"Draggable overlay showing your FPS, ping and memory.","Painel arrastável que mostra seu FPS, ping e memória.","Panel arrastrable que muestra tus FPS, ping y memoria.","Surimpression déplaçable affichant vos FPS, votre ping et votre mémoire.","Verschiebbares Overlay mit FPS, Ping und Speicher.","Overlay yang bisa digeser untuk FPS, ping, dan memori."},
{"Three notepads that save themselves. Copy a note or send it to the editor.","Três blocos de notas que se salvam sozinhos. Copie uma nota ou envie para o editor.","Tres blocs de notas que se guardan solos. Copia una nota o envíala al editor.","Trois bloc-notes qui s'enregistrent seuls. Copiez une note ou envoyez-la à l'éditeur.","Drei Notizblöcke, die sich selbst speichern. Notiz kopieren oder an den Editor senden.","Tiga buku catatan yang tersimpan otomatis. Salin catatan atau kirim ke editor."},
{"Paste a direct link to a png or jpg image, like a catbox.moe link.","Cole um link direto para uma imagem png ou jpg, como um link do catbox.moe.","Pega un enlace directo a una imagen png o jpg, como uno de catbox.moe.","Collez un lien direct vers une image png ou jpg, comme un lien catbox.moe.","Füge einen direkten Link zu einem PNG- oder JPG-Bild ein, z. B. von catbox.moe.","Tempel tautan langsung ke gambar png atau jpg, seperti tautan catbox.moe."},
{"Image strength","Intensidade da imagem","Intensidad de la imagen","Intensité de l'image","Bildstärke","Kekuatan gambar"},
{"GIF quality","Qualidade do GIF","Calidad del GIF","Qualité du GIF","GIF-Qualität","Kualitas GIF"},
{"Higher quality = sharper, smoother GIFs, but slower to load and uses more memory. Ultra may be heavy on phones.","Mais qualidade = GIFs mais nítidos e fluidos, mas carregam mais devagar e usam mais memória. O Ultra pode pesar em celulares.","Más calidad = GIF más nítidos y fluidos, pero cargan más lento y usan más memoria. Ultra puede ser pesado en móviles.","Plus de qualité = GIF plus nets et plus fluides, mais chargement plus lent et plus de mémoire. Ultra peut être lourd sur mobile.","Höhere Qualität = schärfere, flüssigere GIFs, aber längeres Laden und mehr Speicher. Ultra kann auf Handys schwer sein.","Kualitas lebih tinggi = GIF lebih tajam dan mulus, tapi lebih lama dimuat dan memakai lebih banyak memori. Ultra bisa berat di ponsel."},
{"Ultra","Ultra","Ultra","Ultra","Ultra","Ultra"},
{"Glass panels","Painéis de vidro","Paneles de cristal","Panneaux en verre","Glas-Panels","Panel kaca"},
{"Low","Baixa","Baja","Faible","Niedrig","Rendah"},
{"Medium","Média","Media","Moyenne","Mittel","Sedang"},
{"High","Alta","Alta","Élevée","Hoch","Tinggi"},
{"Off","Desligado","Apagado","Désactivé","Aus","Mati"},
{"Soft","Suave","Suave","Doux","Sanft","Lembut"},
{"Strong","Forte","Fuerte","Fort","Stark","Kuat"},
{"Loading image...","Carregando imagem...","Cargando imagen...","Chargement de l'image...","Bild wird geladen...","Memuat gambar..."},
{"Background applied","Fundo aplicado","Fondo aplicado","Fond appliqué","Hintergrund angewendet","Latar diterapkan"},
{"Background removed","Fundo removido","Fondo quitado","Fond retiré","Hintergrund entfernt","Latar dihapus"},
{"Could not load the image. Check the link (png or jpg).","Não foi possível carregar a imagem. Verifique o link (png ou jpg).","No se pudo cargar la imagen. Revisa el enlace (png o jpg).","Impossible de charger l'image. Vérifiez le lien (png ou jpg).","Bild konnte nicht geladen werden. Prüfe den Link (PNG oder JPG).","Gagal memuat gambar. Periksa tautan (png atau jpg)."},
{"Search","Buscar","Buscar","Rechercher","Suchen","Cari"},
{"Search pages, settings, themes, scripts, commands...","Busque páginas, configurações, temas, scripts, comandos...","Busca páginas, ajustes, temas, scripts, comandos...","Rechercher pages, paramètres, thèmes, scripts, commandes...","Seiten, Einstellungen, Themes, Skripte, Befehle suchen...","Cari halaman, pengaturan, tema, skrip, perintah..."},
{"Nothing found.","Nada encontrado.","No se encontró nada.","Rien trouvé.","Nichts gefunden.","Tidak ada hasil."},
{"Open page","Abrir página","Abrir página","Ouvrir la page","Seite öffnen","Buka halaman"},
{"Settings tab","Aba de configurações","Pestaña de ajustes","Onglet des paramètres","Einstellungs-Tab","Tab pengaturan"},
{"Apply theme","Aplicar tema","Aplicar tema","Appliquer le thème","Theme anwenden","Terapkan tema"},
{"Remove every console line","Remove todas as linhas do console","Quita todas las líneas de la consola","Supprime toutes les lignes de la console","Entfernt jede Konsolenzeile","Hapus semua baris konsol"},
{"Open in the editor","Abrir no editor","Abrir en el editor","Ouvrir dans l'éditeur","Im Editor öffnen","Buka di editor"},
{"Page","Página","Página","Page","Seite","Halaman"},
{"Theme","Tema","Tema","Thème","Theme","Tema"},
{"Command","Comando","Comando","Commande","Befehl","Perintah"},
{"Action","Ação","Acción","Action","Aktion","Aksi"},
{"Press Ctrl+K or tap the search button in the title bar to open the search.","Aperte Ctrl+K ou toque no botão de busca na barra de título para abrir a busca.","Pulsa Ctrl+K o toca el botón de búsqueda en la barra de título para abrir la búsqueda.","Appuyez sur Ctrl+K ou touchez le bouton de recherche dans la barre de titre pour ouvrir la recherche.","Drücke Strg+K oder tippe auf die Suchschaltfläche in der Titelleiste, um die Suche zu öffnen.","Tekan Ctrl+K atau ketuk tombol cari di bilah judul untuk membuka pencarian."},
{"Open search","Abrir busca","Abrir búsqueda","Ouvrir la recherche","Suche öffnen","Buka pencarian"},
{"Speed","Velocidade","Velocidad","Vitesse","Tempo","Kecepatan"},
{"Thickness","Espessura","Grosor","Épaisseur","Dicke","Ketebalan"},
{"Thin","Fina","Fino","Fine","Dünn","Tipis"},
{"Thick","Grossa","Grueso","Épaisse","Dick","Tebal"},
{"Show ping","Mostrar ping","Mostrar ping","Afficher le ping","Ping anzeigen","Tampilkan ping"},
{"Show memory","Mostrar memória","Mostrar memoria","Afficher la mémoire","Speicher anzeigen","Tampilkan memori"},
{"Reset position","Redefinir posição","Restablecer posición","Réinitialiser la position","Position zurücksetzen","Reset posisi"},
{"Quick Notes","Notas rápidas","Notas rápidas","Notes rapides","Schnellnotizen","Catatan cepat"},
{"Note 1","Nota 1","Nota 1","Note 1","Notiz 1","Catatan 1"},
{"Note 2","Nota 2","Nota 2","Note 2","Notiz 2","Catatan 2"},
{"Note 3","Nota 3","Nota 3","Note 3","Notiz 3","Catatan 3"},
{"Write anything here. It saves automatically.","Escreva qualquer coisa aqui. Salva automaticamente.","Escribe lo que quieras aquí. Se guarda solo.","Écrivez ce que vous voulez ici. Enregistrement automatique.","Schreib hier alles auf. Es wird automatisch gespeichert.","Tulis apa saja di sini. Tersimpan otomatis."},
{"Send to editor","Enviar ao editor","Enviar al editor","Envoyer à l'éditeur","An Editor senden","Kirim ke editor"},
{"Compact interface", "Interface compacta", "Interfaz compacta", "Interface compacte", "Kompakte Oberfläche", "Antarmuka ringkas"},
{"Prefer denser spacing in interface panels", "Prefira espaçamento mais compacto nos painéis da interface", "Prefiere un espaciado más compacto en los paneles de la interfaz", "Préférer un espacement plus compact dans les panneaux de l’interface", "Kompaktere Abstände in den Oberflächenbereichen bevorzugen", "Utamakan jarak yang lebih rapat pada panel antarmuka"},
{"Show section descriptions", "Mostrar descrições das seções", "Mostrar descripciones de las secciones", "Afficher les descriptions des sections", "Abschnittsbeschreibungen anzeigen", "Tampilkan deskripsi bagian"},
{"Keep helper descriptions visible in settings", "Manter as descrições de ajuda visíveis nas configurações", "Mantener visibles las descripciones de ayuda en los ajustes", "Garder les descriptions d’aide visibles dans les paramètres", "Hilfebeschreibungen in den Einstellungen sichtbar halten", "Jaga deskripsi bantuan tetap terlihat di pengaturan"},
{"Hover highlights", "Destaques ao passar o cursor", "Resaltado al pasar el cursor", "Mise en évidence au survol", "Hervorhebung beim Darüberfahren", "Sorotan saat kursor diarahkan"},
{"Highlight buttons when the pointer passes over them", "Destacar botões quando o cursor passar sobre eles", "Resaltar botones al pasar el cursor sobre ellos", "Mettre les boutons en évidence au survol du pointeur", "Schaltflächen hervorheben, wenn der Mauszeiger darüberfährt", "Sorot tombol saat penunjuk melewatinya"},
{"Confirm destructive actions", "Confirmar ações destrutivas", "Confirmar acciones destructivas", "Confirmer les actions destructrices", "Destruktive Aktionen bestätigen", "Konfirmasi tindakan yang merusak"},
{"Ask for confirmation before destructive actions", "Pedir confirmação antes de ações destrutivas", "Pedir confirmación antes de acciones destructivas", "Demander une confirmation avant les actions destructrices", "Vor destruktiven Aktionen nach einer Bestätigung fragen", "Minta konfirmasi sebelum tindakan yang merusak"},
{"Sound feedback", "Feedback sonoro", "Respuesta sonora", "Retour sonore", "Akustische Rückmeldung", "Umpan balik suara"},
{"Enable optional UI sound feedback", "Ativar sons opcionais de resposta da interface", "Activar sonidos opcionales de respuesta de la interfaz", "Activer les sons de retour facultatifs de l’interface", "Optionale akustische Rückmeldungen der Oberfläche aktivieren", "Aktifkan suara umpan balik antarmuka opsional"},
{"Reduced motion", "Movimento reduzido", "Movimiento reducido", "Animations réduites", "Weniger Bewegung", "Gerakan dikurangi"},
{"Prefer less animated transitions", "Preferir transições com menos animações", "Preferir transiciones con menos animaciones", "Préférer des transitions moins animées", "Weniger animierte Übergänge bevorzugen", "Utamakan transisi dengan lebih sedikit animasi"},
{"Extra contrast", "Contraste extra", "Contraste adicional", "Contraste renforcé", "Erhöhter Kontrast", "Kontras ekstra"},
{"Prefer stronger contrast for interface elements", "Preferir contraste mais forte nos elementos da interface", "Preferir un contraste más fuerte en los elementos de la interfaz", "Préférer un contraste plus marqué pour les éléments de l’interface", "Stärkeren Kontrast für Oberflächenelemente bevorzugen", "Utamakan kontras yang lebih kuat untuk elemen antarmuka"},
{"Remember last page", "Lembrar última página", "Recordar la última página", "Mémoriser la dernière page", "Letzte Seite merken", "Ingat halaman terakhir"},
{"Remember the last page between sessions", "Lembrar a última página entre sessões", "Recordar la última página entre sesiones", "Mémoriser la dernière page entre les sessions", "Die letzte Seite sitzungsübergreifend merken", "Ingat halaman terakhir antar sesi"},
{"Show keyboard hints", "Mostrar dicas de teclado", "Mostrar sugerencias de teclado", "Afficher les raccourcis clavier", "Tastaturhinweise anzeigen", "Tampilkan petunjuk keyboard"},
{"Show shortcut hints where available", "Mostrar dicas de atalhos quando disponíveis", "Mostrar sugerencias de atajos cuando estén disponibles", "Afficher les indications de raccourcis lorsqu’elles sont disponibles", "Verfügbare Tastenkürzel-Hinweise anzeigen", "Tampilkan petunjuk pintasan jika tersedia"},
{"Keep status indicators", "Manter indicadores de status", "Mantener indicadores de estado", "Conserver les indicateurs d’état", "Statusanzeigen beibehalten", "Pertahankan indikator status"},
{"Show small status indicators when available", "Mostrar pequenos indicadores de status quando disponíveis", "Mostrar pequeños indicadores de estado cuando estén disponibles", "Afficher de petits indicateurs d’état lorsqu’ils sont disponibles", "Verfügbare kleine Statusanzeigen anzeigen", "Tampilkan indikator status kecil jika tersedia"},
{"Auto-indent", "Indentação automática", "Sangría automática", "Indentation automatique", "Automatischer Einzug", "Indentasi otomatis"},
{"Keep indentation when creating a new line", "Manter a indentação ao criar uma nova linha", "Mantener la sangría al crear una línea nueva", "Conserver l’indentation lors de la création d’une nouvelle ligne", "Einrückung beim Erstellen einer neuen Zeile beibehalten", "Pertahankan indentasi saat membuat baris baru"},
{"Highlight current line", "Destacar linha atual", "Resaltar línea actual", "Mettre en évidence la ligne actuelle", "Aktuelle Zeile hervorheben", "Sorot baris saat ini"},
{"Highlight the line containing the cursor", "Destacar a linha que contém o cursor", "Resaltar la línea que contiene el cursor", "Mettre en évidence la ligne contenant le curseur", "Die Zeile mit dem Cursor hervorheben", "Sorot baris yang berisi kursor"},
{"Syntax color hints", "Dicas de cores de sintaxe", "Indicaciones de color de sintaxis", "Indications de couleur syntaxique", "Syntax-Farbhinweise", "Petunjuk warna sintaks"},
{"Enable syntax-color preference for the editor", "Ativar a preferência de cores de sintaxe do editor", "Activar la preferencia de colores de sintaxis del editor", "Activer la préférence de couleurs syntaxiques de l’éditeur", "Syntaxfarbpräferenz für den Editor aktivieren", "Aktifkan preferensi warna sintaks editor"},
{"Show minimap", "Mostrar minimapa", "Mostrar minimapa", "Afficher la mini-carte", "Minikarte anzeigen", "Tampilkan minimap"},
{"Show a compact overview when supported", "Mostrar uma visão geral compacta quando houver suporte", "Mostrar una vista general compacta cuando sea compatible", "Afficher un aperçu compact lorsque cette fonction est prise en charge", "Eine kompakte Übersicht anzeigen, sofern unterstützt", "Tampilkan ikhtisar ringkas jika didukung"},
{"Warn before clearing code", "Avisar antes de limpar o código", "Avisar antes de borrar el código", "Avertir avant d’effacer le code", "Vor dem Löschen des Codes warnen", "Peringatkan sebelum menghapus kode"},
{"Ask before clearing editor contents", "Pedir confirmação antes de limpar o conteúdo do editor", "Pedir confirmación antes de borrar el contenido del editor", "Demander confirmation avant d’effacer le contenu de l’éditeur", "Vor dem Leeren des Editorinhalts nachfragen", "Minta konfirmasi sebelum menghapus isi editor"},
{"Restore editor tabs", "Restaurar abas do editor", "Restaurar pestañas del editor", "Restaurer les onglets de l’éditeur", "Editor-Tabs wiederherstellen", "Pulihkan tab editor"},
{"Restore open editor tabs when possible", "Restaurar as abas abertas do editor quando possível", "Restaurar las pestañas abiertas del editor cuando sea posible", "Restaurer les onglets ouverts de l’éditeur lorsque c’est possible", "Geöffnete Editor-Tabs nach Möglichkeit wiederherstellen", "Pulihkan tab editor yang terbuka jika memungkinkan"},
{"Keep console timestamps", "Manter horários no console", "Mantener marcas de tiempo en la consola", "Conserver les horodatages de la console", "Zeitstempel in der Konsole beibehalten", "Pertahankan stempel waktu konsol"},
{"Include timestamps in new console entries", "Incluir horários nas novas entradas do console", "Incluir marcas de tiempo en las nuevas entradas de la consola", "Inclure des horodatages dans les nouvelles entrées de la console", "Zeitstempel in neuen Konsoleneinträgen anzeigen", "Sertakan stempel waktu pada entri konsol baru"},
{"Color console errors", "Colorir erros do console", "Colorear errores de la consola", "Colorer les erreurs de la console", "Konsolenfehler einfärben", "Warnai kesalahan konsol"},
{"Emphasize errors in console output", "Destacar erros na saída do console", "Destacar errores en la salida de la consola", "Mettre en évidence les erreurs dans la sortie de la console", "Fehler in der Konsolenausgabe hervorheben", "Tegaskan kesalahan pada keluaran konsol"},
{"Auto-close brackets", "Fechar colchetes automaticamente", "Cerrar corchetes automáticamente", "Fermer automatiquement les délimiteurs", "Klammern automatisch schließen", "Tutup tanda kurung otomatis"},
{"Automatically close paired brackets when supported", "Fechar automaticamente pares de delimitadores quando houver suporte", "Cerrar automáticamente pares de delimitadores cuando sea compatible", "Fermer automatiquement les paires de délimiteurs si cette fonction est prise en charge", "Zusammengehörige Klammern bei Unterstützung automatisch schließen", "Tutup pasangan tanda kurung secara otomatis jika didukung"},
{"Editor focus on open", "Foco no editor ao abrir", "Enfocar el editor al abrir", "Donner le focus à l’éditeur à l’ouverture", "Editor beim Öffnen fokussieren", "Fokus editor saat dibuka"},
{"Focus the editor when its page opens", "Focar o editor quando sua página for aberta", "Enfocar el editor al abrir su página", "Donner le focus à l’éditeur lorsque sa page s’ouvre", "Den Editor beim Öffnen seiner Seite fokussieren", "Fokuskan editor saat halamannya dibuka"},
{"Verbose diagnostics", "Diagnósticos detalhados", "Diagnósticos detallados", "Diagnostics détaillés", "Ausführliche Diagnose", "Diagnostik terperinci"},
{"Keep more diagnostic detail in local preferences", "Manter mais detalhes de diagnóstico nas preferências locais", "Guardar más detalles de diagnóstico en las preferencias locales", "Conserver davantage de détails de diagnostic dans les préférences locales", "Mehr Diagnoseinformationen in lokalen Einstellungen speichern", "Simpan lebih banyak detail diagnostik dalam preferensi lokal"},
{"Show startup checks", "Mostrar verificações de inicialização", "Mostrar comprobaciones de inicio", "Afficher les vérifications au démarrage", "Startprüfungen anzeigen", "Tampilkan pemeriksaan saat mulai"},
{"Show startup-check status where available", "Mostrar o status das verificações de inicialização quando disponível", "Mostrar el estado de las comprobaciones de inicio cuando esté disponible", "Afficher l’état des vérifications au démarrage lorsqu’il est disponible", "Status der Startprüfungen anzeigen, sofern verfügbar", "Tampilkan status pemeriksaan awal jika tersedia"},
{"Safe mode preference", "Preferência de modo seguro", "Preferencia de modo seguro", "Préférence du mode sans échec", "Bevorzugter abgesicherter Modus", "Preferensi mode aman"},
{"Save a preference to limit optional startup features", "Salvar uma preferência para limitar recursos opcionais na inicialização", "Guardar una preferencia para limitar funciones opcionales al iniciar", "Enregistrer une préférence pour limiter les fonctions facultatives au démarrage", "Eine Einstellung speichern, um optionale Startfunktionen zu begrenzen", "Simpan preferensi untuk membatasi fitur opsional saat mulai"},
{"Log plugin errors", "Registrar erros de plugins", "Registrar errores de plugins", "Journaliser les erreurs des plugins", "Pluginfehler protokollieren", "Catat kesalahan plugin"},
{"Keep plugin-error logging enabled where available", "Manter o registro de erros de plugins ativo quando disponível", "Mantener activo el registro de errores de plugins cuando esté disponible", "Maintenir la journalisation des erreurs de plugins lorsqu’elle est disponible", "Die Protokollierung von Pluginfehlern aktiv halten, sofern verfügbar", "Aktifkan pencatatan kesalahan plugin jika tersedia"},
{"Check UI integrity", "Verificar integridade da interface", "Comprobar la integridad de la interfaz", "Vérifier l’intégrité de l’interface", "Integrität der Oberfläche prüfen", "Periksa integritas UI"},
{"Enable the preference for UI integrity checks", "Ativar a preferência para verificações de integridade da interface", "Activar la preferencia para comprobar la integridad de la interfaz", "Activer la préférence de vérification de l’intégrité de l’interface", "Die Einstellung für Integritätsprüfungen der Oberfläche aktivieren", "Aktifkan preferensi pemeriksaan integritas UI"},
{"Show memory diagnostics", "Mostrar diagnóstico de memória", "Mostrar diagnósticos de memoria", "Afficher les diagnostics mémoire", "Speicherdiagnose anzeigen", "Tampilkan diagnostik memori"},
{"Show memory diagnostics when available", "Mostrar diagnósticos de memória quando disponíveis", "Mostrar diagnósticos de memoria cuando estén disponibles", "Afficher les diagnostics mémoire lorsqu’ils sont disponibles", "Verfügbare Speicherdiagnosen anzeigen", "Tampilkan diagnostik memori jika tersedia"},
{"Keep debug history", "Manter histórico de depuração", "Mantener historial de depuración", "Conserver l’historique de débogage", "Debugverlauf beibehalten", "Pertahankan riwayat debug"},
{"Keep a local debug-history preference", "Manter uma preferência local para o histórico de depuração", "Guardar una preferencia local para el historial de depuración", "Conserver une préférence locale pour l’historique de débogage", "Eine lokale Einstellung für den Debugverlauf speichern", "Simpan preferensi lokal untuk riwayat debug"},
{"Warn on unsupported APIs", "Avisar sobre APIs não compatíveis", "Avisar sobre API no compatibles", "Avertir en cas d’API non prises en charge", "Bei nicht unterstützten APIs warnen", "Peringatkan tentang API yang tidak didukung"},
{"Prefer warnings for unsupported APIs", "Preferir avisos para APIs não compatíveis", "Preferir advertencias para API no compatibles", "Préférer les avertissements pour les API non prises en charge", "Warnungen bei nicht unterstützten APIs bevorzugen", "Utamakan peringatan untuk API yang tidak didukung"},
{"Maintenance reminders", "Lembretes de manutenção", "Recordatorios de mantenimiento", "Rappels de maintenance", "Wartungserinnerungen", "Pengingat pemeliharaan"},
{"Show reminders for maintenance tasks", "Mostrar lembretes de tarefas de manutenção", "Mostrar recordatorios de tareas de mantenimiento", "Afficher des rappels pour les tâches de maintenance", "An Wartungsaufgaben erinnern", "Tampilkan pengingat tugas pemeliharaan"},
{"Detailed error notices", "Avisos de erro detalhados", "Avisos de error detallados", "Notifications d’erreur détaillées", "Detaillierte Fehlermeldungen", "Pemberitahuan kesalahan terperinci"},
{"Prefer more detailed error notices", "Preferir avisos de erro mais detalhados", "Preferir avisos de error más detallados", "Préférer des notifications d’erreur plus détaillées", "Detailliertere Fehlermeldungen bevorzugen", "Utamakan pemberitahuan kesalahan yang lebih terperinci"},
{"Save nickname locally", "Salvar apelido localmente", "Guardar el apodo localmente", "Enregistrer le surnom localement", "Spitznamen lokal speichern", "Simpan nama panggilan secara lokal"},
{"Keep the nickname in local settings", "Manter o apelido nas configurações locais", "Guardar el apodo en los ajustes locales", "Conserver le surnom dans les paramètres locaux", "Den Spitznamen in den lokalen Einstellungen speichern", "Simpan nama panggilan di pengaturan lokal"},
{"Show account status", "Mostrar status da conta", "Mostrar el estado de la cuenta", "Afficher l’état du compte", "Kontostatus anzeigen", "Tampilkan status akun"},
{"Show account status details where available", "Mostrar detalhes do status da conta quando disponíveis", "Mostrar detalles del estado de la cuenta cuando estén disponibles", "Afficher les détails du compte lorsqu’ils sont disponibles", "Kontostatusdetails anzeigen, sofern verfügbar", "Tampilkan detail status akun jika tersedia"},
{"Remember language", "Lembrar idioma", "Recordar idioma", "Mémoriser la langue", "Sprache merken", "Ingat bahasa"},
{"Reuse the selected language on next launch", "Usar novamente o idioma selecionado na próxima inicialização", "Volver a usar el idioma seleccionado en el próximo inicio", "Réutiliser la langue choisie au prochain lancement", "Die ausgewählte Sprache beim nächsten Start wiederverwenden", "Gunakan kembali bahasa yang dipilih saat mulai berikutnya"},
{"Show welcome tips", "Mostrar dicas de boas-vindas", "Mostrar consejos de bienvenida", "Afficher les conseils de bienvenue", "Willkommenstipps anzeigen", "Tampilkan tips sambutan"},
{"Show helpful tips when opening Hyundax IUM", "Mostrar dicas úteis ao abrir o Hyundax IUM", "Mostrar consejos útiles al abrir Hyundax IUM", "Afficher des conseils utiles à l’ouverture de Hyundax IUM", "Beim Öffnen von Hyundax IUM hilfreiche Tipps anzeigen", "Tampilkan tips berguna saat membuka Hyundax IUM"},
{"Usage counters", "Contadores de uso", "Contadores de uso", "Compteurs d’utilisation", "Nutzungszähler", "Penghitung penggunaan"},
{"Allow local usage counters to be displayed", "Permitir a exibição de contadores de uso locais", "Permitir mostrar contadores de uso locales", "Autoriser l’affichage des compteurs d’utilisation locaux", "Lokale Nutzungszähler anzeigen dürfen", "Izinkan penghitung penggunaan lokal ditampilkan"},
{"Show update notes", "Mostrar notas de atualização", "Mostrar notas de actualización", "Afficher les notes de mise à jour", "Aktualisierungshinweise anzeigen", "Tampilkan catatan pembaruan"},
{"Show release notes when available", "Mostrar notas de versão quando disponíveis", "Mostrar notas de versión cuando estén disponibles", "Afficher les notes de version lorsqu’elles sont disponibles", "Verfügbare Versionshinweise anzeigen", "Tampilkan catatan rilis jika tersedia"},
{"Compact profile card", "Cartão de perfil compacto", "Tarjeta de perfil compacta", "Carte de profil compacte", "Kompakte Profilkarte", "Kartu profil ringkas"},
{"Use a compact layout for profile information", "Usar um layout compacto para as informações do perfil", "Usar un diseño compacto para la información del perfil", "Utiliser une disposition compacte pour les informations du profil", "Ein kompaktes Layout für Profilinformationen verwenden", "Gunakan tata letak ringkas untuk informasi profil"},
{"Profile notifications", "Notificações do perfil", "Notificaciones del perfil", "Notifications du profil", "Profilbenachrichtigungen", "Notifikasi profil"},
{"Allow profile-related notices", "Permitir notificações relacionadas ao perfil", "Permitir avisos relacionados con el perfil", "Autoriser les notifications liées au profil", "Profilbezogene Hinweise zulassen", "Izinkan pemberitahuan terkait profil"},
{"Remember sign-in choice", "Lembrar preferência de entrada", "Recordar la opción de inicio de sesión", "Mémoriser le choix de connexion", "Anmeldeoption merken", "Ingat pilihan masuk"},
{"Remember the preferred sign-in flow", "Lembrar o fluxo de entrada preferido", "Recordar el flujo de inicio de sesión preferido", "Mémoriser le mode de connexion préféré", "Den bevorzugten Anmeldeablauf merken", "Ingat alur masuk yang disukai"},
{"Show nickname in header", "Mostrar apelido no cabeçalho", "Mostrar el apodo en el encabezado", "Afficher le surnom dans l’en-tête", "Spitznamen in der Kopfzeile anzeigen", "Tampilkan nama panggilan di header"},
{"Display your nickname in the header when supported", "Exibir seu apelido no cabeçalho quando houver suporte", "Mostrar tu apodo en el encabezado cuando sea compatible", "Afficher votre surnom dans l’en-tête lorsque cette fonction est prise en charge", "Den Spitznamen in der Kopfzeile anzeigen, sofern unterstützt", "Tampilkan nama panggilan di header jika didukung"},
{"Explore / activate", "Explorar / ativar", "Explorar / activar", "Explorer / activer", "Durchsuchen / aktivieren", "Jelajahi / aktifkan"},
{"Create / export", "Criar / exportar", "Crear / exportar", "Créer / exporter", "Erstellen / exportieren", "Buat / ekspor"},
{"Explore and activate plugins", "Explore e ative plugins", "Explora y activa plugins", "Explorez et activez les plugins", "Plugins durchsuchen und aktivieren", "Jelajahi dan aktifkan plugin"},
{"Create plugins and export themes", "Crie plugins e exporte temas", "Crea plugins y exporta temas", "Créez des plugins et exportez des thèmes", "Plugins erstellen und Designs exportieren", "Buat plugin dan ekspor tema"},
{"Publish plugins or turn your theme into a plugin", "Publique plugins ou transforme seu tema em um plugin", "Publica plugins o convierte tu tema en un plugin", "Publiez des plugins ou transformez votre thème en plugin", "Plugins veröffentlichen oder ein Design in ein Plugin umwandeln", "Terbitkan plugin atau ubah tema menjadi plugin"},
{"Export theme as plugin", "Exportar tema como plugin", "Exportar tema como plugin", "Exporter le thème comme plugin", "Design als Plugin exportieren", "Ekspor tema sebagai plugin"},
{"Turn colors and a background image into a plugin you can toggle, copy and share. Leave a color empty to use the current theme.", "Transforme cores e uma imagem de fundo em um plugin que você pode ativar, copiar e compartilhar. Deixe uma cor vazia para usar o tema atual.", "Convierte colores y una imagen de fondo en un plugin que puedes activar, copiar y compartir. Deja un color vacío para usar el tema actual.", "Transformez les couleurs et une image d’arrière-plan en un plugin que vous pouvez activer, copier et partager. Laissez une couleur vide pour utiliser le thème actuel.", "Verwandle Farben und ein Hintergrundbild in ein Plugin, das aktiviert, kopiert und geteilt werden kann. Lasse eine Farbe leer, um das aktuelle Design zu verwenden.", "Ubah warna dan gambar latar menjadi plugin yang dapat diaktifkan, disalin, dan dibagikan. Kosongkan warna untuk memakai tema saat ini."},
{"Theme name", "Nome do tema", "Nombre del tema", "Nom du thème", "Designname", "Nama tema"},
{"Background image link (optional, png or jpg)", "Link da imagem de fundo (opcional, png ou jpg)", "Enlace de imagen de fondo (opcional, png o jpg)", "Lien de l’image d’arrière-plan (facultatif, png ou jpg)", "Link zum Hintergrundbild (optional, png oder jpg)", "Tautan gambar latar (opsional, png atau jpg)"},
{"Background color, e.g. #181428", "Cor de fundo, por exemplo #181428", "Color de fondo, p. ej., #181428", "Couleur d’arrière-plan, p. ex. #181428", "Hintergrundfarbe, z. B. #181428", "Warna latar, misalnya #181428"},
{"Accent color, e.g. #E63946", "Cor de destaque, por exemplo #E63946", "Color de acento, p. ej., #E63946", "Couleur d’accent, p. ex. #E63946", "Akzentfarbe, z. B. #E63946", "Warna aksen, misalnya #E63946"},
{"Create plugin", "Criar plugin", "Crear plugin", "Créer un plugin", "Plugin erstellen", "Buat plugin"},
{"Copy code", "Copiar código", "Copiar código", "Copier le code", "Code kopieren", "Salin kode"},
{"Use current", "Usar atual", "Usar actual", "Utiliser l’actuel", "Aktuelles verwenden", "Gunakan saat ini"},
{"Search and manage installed plugins", "Pesquise e gerencie plugins instalados", "Busca y administra plugins instalados", "Recherchez et gérez les plugins installés", "Installierte Plugins suchen und verwalten", "Cari dan kelola plugin terpasang"},
{"Vault","Cofre","Bóveda","Coffre","Tresor","Brankas"},
{"Keys and notes for this account","Chaves e notas desta conta","Claves y notas de esta cuenta","Clés et notes de ce compte","Schlüssel und Notizen für dieses Konto","Kunci dan catatan untuk akun ini"},
{"Lock","Bloqueio","Bloqueo","Verrou","Sperre","Kunci"},
{"Vault locked","Cofre bloqueado","Bóveda bloqueada","Coffre verrouillé","Tresor gesperrt","Brankas terkunci"},
{"Draw your pattern to unlock","Desenhe seu padrão para desbloquear","Dibuja tu patrón para desbloquear","Dessinez votre schéma pour déverrouiller","Zeichne dein Muster zum Entsperren","Gambar pola untuk membuka"},
{"Enter your PIN to unlock","Digite seu PIN para desbloquear","Introduce tu PIN para desbloquear","Saisissez votre PIN pour déverrouiller","PIN zum Entsperren eingeben","Masukkan PIN untuk membuka"},
{"Enter your code to unlock","Digite seu código para desbloquear","Introduce tu código para desbloquear","Saisissez votre code pour déverrouiller","Code zum Entsperren eingeben","Masukkan kode untuk membuka"},
{"Wrong code","Código incorreto","Código incorrecto","Code incorrect","Falscher Code","Kode salah"},
{"Vault lock","Bloqueio do cofre","Bloqueo de la bóveda","Verrou du coffre","Tresorsperre","Kunci brankas"},
{"Choose a lock type","Escolha o tipo de bloqueio","Elige el tipo de bloqueo","Choisissez le type de verrou","Sperrtyp wählen","Pilih jenis kunci"},
{"Pattern","Padrão","Patrón","Schéma","Muster","Pola"},
{"PIN","PIN","PIN","PIN","PIN","PIN"},
{"Numbers","Números","Números","Chiffres","Zahlen","Angka"},
{"No lock","Sem bloqueio","Sin bloqueo","Sans verrou","Keine Sperre","Tanpa kunci"},
{"Draw a new pattern","Desenhe um novo padrão","Dibuja un nuevo patrón","Dessinez un nouveau schéma","Zeichne ein neues Muster","Gambar pola baru"},
{"Enter a new PIN","Digite um novo PIN","Introduce un nuevo PIN","Saisissez un nouveau PIN","Neuen PIN eingeben","Masukkan PIN baru"},
{"Enter a new number code","Digite um novo código numérico","Introduce un nuevo código numérico","Saisissez un nouveau code numérique","Neuen Zahlencode eingeben","Masukkan kode angka baru"},
{"Confirm your code","Confirme seu código","Confirma tu código","Confirmez votre code","Code bestätigen","Konfirmasi kodemu"},
{"Codes do not match","Os códigos não coincidem","Los códigos no coinciden","Les codes ne correspondent pas","Die Codes stimmen nicht überein","Kode tidak cocok"},
{"Lock saved","Bloqueio salvo","Bloqueo guardado","Verrou enregistré","Sperre gespeichert","Kunci disimpan"},
{"Lock removed","Bloqueio removido","Bloqueo eliminado","Verrou supprimé","Sperre entfernt","Kunci dihapus"},
{"Pattern needs at least 4 dots","O padrão precisa de pelo menos 4 pontos","El patrón necesita al menos 4 puntos","Le schéma doit avoir au moins 4 points","Das Muster braucht mindestens 4 Punkte","Pola butuh minimal 4 titik"},
{"Code needs at least 4 digits","O código precisa de pelo menos 4 dígitos","El código necesita al menos 4 dígitos","Le code doit avoir au moins 4 chiffres","Der Code braucht mindestens 4 Ziffern","Kode butuh minimal 4 digit"},
{"Edit Item","Editar item","Editar elemento","Modifier l'élément","Eintrag bearbeiten","Edit item"},
{"Key","Chave","Clave","Clé","Schlüssel","Kunci"},
{"Note","Nota","Nota","Note","Notiz","Catatan"},
{"Item title","Título do item","Título del elemento","Titre de l'élément","Titel des Eintrags","Judul item"},
{"Paste your key or write your note here...","Cole sua chave ou escreva sua nota aqui...","Pega tu clave o escribe tu nota aquí...","Collez votre clé ou écrivez votre note ici...","Füge deinen Schlüssel ein oder schreibe deine Notiz...","Tempel kunci atau tulis catatanmu di sini..."},
{"No items yet. Tap + New to add a key or note.","Nenhum item ainda. Toque em + Novo para adicionar uma chave ou nota.","Aún no hay elementos. Toca + Nuevo para añadir una clave o nota.","Aucun élément. Touchez + Nouveau pour ajouter une clé ou une note.","Noch keine Einträge. Tippe auf + Neu, um einen Schlüssel oder eine Notiz hinzuzufügen.","Belum ada item. Ketuk + Baru untuk menambah kunci atau catatan."},
{"Enter a title","Digite um título","Introduce un título","Saisissez un titre","Titel eingeben","Masukkan judul"},
{"Add some content","Adicione algum conteúdo","Añade algo de contenido","Ajoutez du contenu","Füge Inhalt hinzu","Tambahkan konten"},
{"Item saved","Item salvo","Elemento guardado","Élément enregistré","Eintrag gespeichert","Item disimpan"},
{"Item deleted","Item excluído","Elemento eliminado","Élément supprimé","Eintrag gelöscht","Item dihapus"},
{"Clipboard unavailable","Área de transferência indisponível","Portapapeles no disponible","Presse-papiers indisponible","Zwischenablage nicht verfügbar","Papan klip tidak tersedia"},
{"Save this item before deleting it","Salve este item antes de excluí-lo","Guarda este elemento antes de eliminarlo","Enregistrez cet élément avant de le supprimer","Speichere diesen Eintrag vor dem Löschen","Simpan item ini sebelum menghapusnya"},
{"Customize account","Personalizar conta","Personalizar cuenta","Personnaliser le compte","Konto anpassen","Sesuaikan akun"},
{"Paste an image link (https://...)","Cole um link de imagem (https://...)","Pega un enlace de imagen (https://...)","Collez un lien d'image (https://...)","Bildlink einfügen (https://...)","Tempel tautan gambar (https://...)"},
{"Remove logo","Remover logo","Quitar logo","Retirer le logo","Logo entfernen","Hapus logo"},
{"Logo updated","Logo atualizado","Logo actualizado","Logo mis à jour","Logo aktualisiert","Logo diperbarui"},
{"Logo removed","Logo removido","Logo eliminado","Logo retiré","Logo entfernt","Logo dihapus"},
{"Could not load the logo","Não foi possível carregar o logo","No se pudo cargar el logo","Impossible de charger le logo","Logo konnte nicht geladen werden","Gagal memuat logo"},
{"Accounts","Contas","Cuentas","Comptes","Konten","Akun"},
{"Accounts on this device","Contas neste aparelho","Cuentas en este dispositivo","Comptes sur cet appareil","Konten auf diesem Gerät","Akun di perangkat ini"},
{"Tap a card to switch. Each account keeps its own data.","Toque em um card para trocar. Cada conta mantém seus próprios dados.","Toca una tarjeta para cambiar. Cada cuenta conserva sus propios datos.","Touchez une carte pour changer. Chaque compte garde ses propres données.","Tippe auf eine Karte zum Wechseln. Jedes Konto behält seine eigenen Daten.","Ketuk kartu untuk beralih. Setiap akun menyimpan datanya sendiri."},
{"Tap to switch","Toque para trocar","Toca para cambiar","Touchez pour changer","Zum Wechseln tippen","Ketuk untuk beralih"},
{"Auto-execute","Auto-execução","Auto-ejecución","Exécution auto","Auto-Ausführung","Eksekusi otomatis"},
{"Ping","Ping","Ping","Ping","Ping","Ping"},
{"n/a","n/d","n/d","n/d","k. A.","n/a"},
{"Draw your pattern", "Desenhe seu padrão", "Dibuja tu patrón", "Dessinez votre schéma", "Zeichne dein Muster", "Gambar pola Anda"},
{"Enter your PIN", "Digite seu PIN", "Introduce tu PIN", "Saisissez votre PIN", "PIN eingeben", "Masukkan PIN Anda"},
{"Enter your password", "Digite sua senha", "Introduce tu contraseña", "Saisissez votre mot de passe", "Passwort eingeben", "Masukkan kata sandi Anda"},
{"Enter your number code", "Digite seu código numérico", "Introduce tu código numérico", "Saisissez votre code numérique", "Zahlencode eingeben", "Masukkan kode angka Anda"},
{"Use 8–64 characters. Letters, numbers and symbols are accepted.", "Use de 8 a 64 caracteres. Letras, números e símbolos são aceitos.", "Usa de 8 a 64 caracteres. Se aceptan letras, números y símbolos.", "Utilisez 8 à 64 caractères. Lettres, chiffres et symboles acceptés.", "8–64 Zeichen. Buchstaben, Zahlen und Symbole sind erlaubt.", "Gunakan 8–64 karakter. Huruf, angka, dan simbol diperbolehkan."},
{"4–6 digits · Existing 4-digit PINs still work", "4–6 dígitos · PINs de 4 dígitos continuam funcionando", "4–6 dígitos · Los PIN de 4 dígitos siguen funcionando", "4 à 6 chiffres · Les PIN à 4 chiffres fonctionnent toujours", "4–6 Ziffern · Bestehende 4-stellige PINs funktionieren weiter", "4–6 digit · PIN 4 digit lama tetap berfungsi"},
{"Connect at least 4 different dots", "Conecte pelo menos 4 pontos diferentes", "Conecta al menos 4 puntos distintos", "Reliez au moins 4 points différents", "Verbinde mindestens 4 verschiedene Punkte", "Hubungkan setidaknya 4 titik berbeda"},
{"Use 4–16 digits", "Use de 4 a 16 dígitos", "Usa de 4 a 16 dígitos", "Utilisez 4 à 16 chiffres", "4–16 Ziffern verwenden", "Gunakan 4–16 digit"},
{"Hide", "Ocultar", "Ocultar", "Masquer", "Verbergen", "Sembunyikan"},
{"Show", "Mostrar", "Mostrar", "Afficher", "Anzeigen", "Tampilkan"},
{"PIN must have 4 to 6 digits", "O PIN deve ter de 4 a 6 dígitos", "El PIN debe tener de 4 a 6 dígitos", "Le PIN doit comporter 4 à 6 chiffres", "Die PIN muss 4 bis 6 Ziffern haben", "PIN harus 4 sampai 6 digit"},
{"Password must have at least 8 characters", "A senha deve ter pelo menos 8 caracteres", "La contraseña debe tener al menos 8 caracteres", "Le mot de passe doit comporter au moins 8 caractères", "Das Passwort muss mindestens 8 Zeichen haben", "Kata sandi minimal 8 karakter"},
{"Code must have 4 to 16 digits", "O código deve ter de 4 a 16 dígitos", "El código debe tener de 4 a 16 dígitos", "Le code doit comporter 4 à 16 chiffres", "Der Code muss 4 bis 16 Ziffern haben", "Kode harus 4 sampai 16 digit"},
{"Vault password", "Senha do cofre", "Contraseña de la bóveda", "Mot de passe du coffre", "Tresor-Passwort", "Kata sandi brankas"},
{"Enter your vault password", "Digite a senha do cofre", "Introduce la contraseña de la bóveda", "Saisissez le mot de passe du coffre", "Tresor-Passwort eingeben", "Masukkan kata sandi brankas"},
{"Enter your number code to unlock", "Digite seu código numérico para desbloquear", "Introduce tu código numérico para desbloquear", "Saisissez votre code numérique pour déverrouiller", "Zahlencode zum Entsperren eingeben", "Masukkan kode angka untuk membuka"},
{"Recover your vault", "Recupere seu cofre", "Recupera tu bóveda", "Récupérez votre coffre", "Tresor wiederherstellen", "Pulihkan brankas Anda"},
{"Enter the recovery key you received when you set the lock", "Digite a chave de recuperação recebida ao definir o bloqueio", "Introduce la clave de recuperación que recibiste al crear el bloqueo", "Saisissez la clé de récupération reçue lors de la création du verrou", "Gib den Wiederherstellungsschlüssel ein, den du beim Einrichten der Sperre erhalten hast", "Masukkan kunci pemulihan yang Anda terima saat mengatur kunci"},
{"Unlock", "Desbloquear", "Desbloquear", "Déverrouiller", "Entsperren", "Buka kunci"},
{"This lock has no recovery key", "Este bloqueio não tem chave de recuperação", "Este bloqueo no tiene clave de recuperación", "Ce verrou n'a pas de clé de récupération", "Diese Sperre hat keinen Wiederherstellungsschlüssel", "Kunci ini tidak memiliki kunci pemulihan"},
{"Recovered. Set a new lock", "Recuperado. Defina um novo bloqueio", "Recuperado. Crea un nuevo bloqueo", "Récupéré. Définissez un nouveau verrou", "Wiederhergestellt. Neue Sperre festlegen", "Berhasil dipulihkan. Atur kunci baru"},
{"Wrong recovery key", "Chave de recuperação incorreta", "Clave de recuperación incorrecta", "Clé de récupération incorrecte", "Falscher Wiederherstellungsschlüssel", "Kunci pemulihan salah"},
{"Erase vault and remove lock", "Apagar cofre e remover bloqueio", "Borrar bóveda y quitar bloqueo", "Effacer le coffre et retirer le verrou", "Tresor löschen und Sperre entfernen", "Hapus brankas dan lepas kunci"},
{"Tap again to confirm", "Toque novamente para confirmar", "Toca de nuevo para confirmar", "Touchez à nouveau pour confirmer", "Zum Bestätigen erneut tippen", "Ketuk lagi untuk konfirmasi"},
{"Vault erased", "Cofre apagado", "Bóveda borrada", "Coffre effacé", "Tresor gelöscht", "Brankas dihapus"},
{"Forgot code?", "Esqueceu o código?", "¿Olvidaste el código?", "Code oublié ?", "Code vergessen?", "Lupa kode?"},
{"Choose how to protect this vault", "Escolha como proteger este cofre", "Elige cómo proteger esta bóveda", "Choisissez comment protéger ce coffre", "Wähle, wie dieser Tresor geschützt wird", "Pilih cara melindungi brankas ini"},
{"Password accepts 8–64 characters. Saved vault entries remain in local JSON and are not encrypted.", "A senha aceita de 8 a 64 caracteres. Os itens salvos ficam em JSON local e não são criptografados.", "La contraseña acepta de 8 a 64 caracteres. Los elementos guardados permanecen en JSON local y no están cifrados.", "Le mot de passe accepte 8 à 64 caractères. Les éléments enregistrés restent dans un JSON local et ne sont pas chiffrés.", "Das Passwort akzeptiert 8–64 Zeichen. Gespeicherte Einträge bleiben in lokalem JSON und sind nicht verschlüsselt.", "Kata sandi menerima 8–64 karakter. Item tersimpan tetap di JSON lokal dan tidak dienkripsi."},
{"Recovery key", "Chave de recuperação", "Clave de recuperación", "Clé de récupération", "Wiederherstellungsschlüssel", "Kunci pemulihan"},
{"Save it somewhere safe. It is shown only once and unlocks the vault if you forget your code.", "Guarde em um lugar seguro. Ela aparece só uma vez e abre o cofre se você esquecer o código.", "Guárdala en un lugar seguro. Solo se muestra una vez y abre la bóveda si olvidas tu código.", "Conservez-la en lieu sûr. Elle n'est affichée qu'une fois et ouvre le coffre si vous oubliez votre code.", "Bewahre ihn sicher auf. Er wird nur einmal angezeigt und entsperrt den Tresor, falls du deinen Code vergisst.", "Simpan di tempat aman. Hanya ditampilkan sekali dan membuka brankas jika Anda lupa kode."},
{"Done", "Concluído", "Listo", "Terminé", "Fertig", "Selesai"},
{"Create a new pattern", "Crie um novo padrão", "Crea un nuevo patrón", "Créez un nouveau schéma", "Neues Muster erstellen", "Buat pola baru"},
{"Create a 4–6 digit PIN", "Crie um PIN de 4 a 6 dígitos", "Crea un PIN de 4 a 6 dígitos", "Créez un PIN de 4 à 6 chiffres", "Erstelle eine 4–6-stellige PIN", "Buat PIN 4–6 digit"},
{"Create an 8–64 character password", "Crie uma senha de 8 a 64 caracteres", "Crea una contraseña de 8 a 64 caracteres", "Créez un mot de passe de 8 à 64 caractères", "Erstelle ein Passwort mit 8–64 Zeichen", "Buat kata sandi 8–64 karakter"},
{"Create a number code", "Crie um código numérico", "Crea un código numérico", "Créez un code numérique", "Erstelle einen Zahlencode", "Buat kode angka"},
{"Confirm your password", "Confirme sua senha", "Confirma tu contraseña", "Confirmez votre mot de passe", "Passwort bestätigen", "Konfirmasi kata sandi Anda"},
{"Confirm your PIN", "Confirme seu PIN", "Confirma tu PIN", "Confirmez votre PIN", "PIN bestätigen", "Konfirmasi PIN Anda"},
{"Confirm your pattern", "Confirme seu padrão", "Confirma tu patrón", "Confirmez votre schéma", "Muster bestätigen", "Konfirmasi pola Anda"},
{"Confirm your number code", "Confirme seu código numérico", "Confirma tu código numérico", "Confirmez votre code numérique", "Zahlencode bestätigen", "Konfirmasi kode angka Anda"},
{"Entries do not match", "As entradas não coincidem", "Las entradas no coinciden", "Les saisies ne correspondent pas", "Eingaben stimmen nicht überein", "Input tidak cocok"},
{"Private Vault", "Cofre privado", "Bóveda privada", "Coffre privé", "Privater Tresor", "Brankas pribadi"},
{"Vault item", "Item do cofre", "Elemento de la bóveda", "Élément du coffre", "Tresor-Eintrag", "Item brankas"},
{"Service / item title (e.g. Roblox)", "Serviço / título do item (ex.: Roblox)", "Servicio / título del elemento (p. ej., Roblox)", "Service / titre de l'élément (ex. : Roblox)", "Dienst / Eintragstitel (z. B. Roblox)", "Layanan / judul item (mis. Roblox)"},
{"Username / email (optional)", "Usuário / e-mail (opcional)", "Usuario / correo (opcional)", "Nom d'utilisateur / e-mail (facultatif)", "Benutzername / E-Mail (optional)", "Nama pengguna / email (opsional)"},
{"Paste a key, password or note...", "Cole uma chave, senha ou nota...", "Pega una clave, contraseña o nota...", "Collez une clé, un mot de passe ou une note...", "Schlüssel, Passwort oder Notiz einfügen...", "Tempel kunci, kata sandi, atau catatan..."},
{"Show password", "Mostrar senha", "Mostrar contraseña", "Afficher le mot de passe", "Passwort anzeigen", "Tampilkan kata sandi"},
{"Hide password", "Ocultar senha", "Ocultar contraseña", "Masquer le mot de passe", "Passwort verbergen", "Sembunyikan kata sandi"},
{"Password / secret value", "Senha / valor secreto", "Contraseña / valor secreto", "Mot de passe / valeur secrète", "Passwort / geheimer Wert", "Kata sandi / nilai rahasia"},
{"Write your note here...", "Escreva sua nota aqui...", "Escribe tu nota aquí...", "Écrivez votre note ici...", "Schreibe deine Notiz hier...", "Tulis catatan Anda di sini..."},
{"Paste your key or token here...", "Cole sua chave ou token aqui...", "Pega tu clave o token aquí...", "Collez votre clé ou jeton ici...", "Schlüssel oder Token hier einfügen...", "Tempel kunci atau token Anda di sini..."},
{"Your vault is empty", "Seu cofre está vazio", "Tu bóveda está vacía", "Votre coffre est vide", "Dein Tresor ist leer", "Brankas Anda kosong"},
{"Tap + New to save a password, key or private note.", "Toque em + Novo para salvar uma senha, chave ou nota privada.", "Toca + Nuevo para guardar una contraseña, clave o nota privada.", "Touchez + Nouveau pour enregistrer un mot de passe, une clé ou une note privée.", "Tippe auf + Neu, um ein Passwort, einen Schlüssel oder eine private Notiz zu speichern.", "Ketuk + Baru untuk menyimpan kata sandi, kunci, atau catatan pribadi."},
{"Nothing to copy", "Nada para copiar", "Nada que copiar", "Rien à copier", "Nichts zu kopieren", "Tidak ada yang disalin"},
{"Copied to clipboard", "Copiado para a área de transferência", "Copiado al portapapeles", "Copié dans le presse-papiers", "In die Zwischenablage kopiert", "Disalin ke papan klip"},
{"Security", "Segurança", "Seguridad", "Sécurité", "Sicherheit", "Keamanan"},
{"Title", "Título", "Título", "Titre", "Titel", "Judul"},
{"Username / email", "Usuário / e-mail", "Usuario / correo", "Nom d'utilisateur / e-mail", "Benutzername / E-Mail", "Nama pengguna / email"},
{"Secret value", "Valor secreto", "Valor secreto", "Valeur secrète", "Geheimer Wert", "Nilai rahasia"},
{"Key or token", "Chave ou token", "Clave o token", "Clé ou jeton", "Schlüssel oder Token", "Kunci atau token"},
{"Login and secret", "Login e segredo", "Acceso y secreto", "Identifiant et secret", "Login und Geheimnis", "Login dan rahasia"},
{"API key or token", "Chave de API ou token", "Clave de API o token", "Clé API ou jeton", "API-Schlüssel oder Token", "Kunci API atau token"},
{"Private text", "Texto privado", "Texto privado", "Texte privé", "Privater Text", "Teks pribadi"},
{"Draw 4–9 dots", "Desenhe 4–9 pontos", "Dibuja 4–9 puntos", "Dessinez 4–9 points", "4–9 Punkte zeichnen", "Gambar 4–9 titik"},
{"4–6 digits", "4–6 dígitos", "4–6 dígitos", "4 à 6 chiffres", "4–6 Ziffern", "4–6 digit"},
{"8–64 characters", "8–64 caracteres", "8–64 caracteres", "8 à 64 caractères", "8–64 Zeichen", "8–64 karakter"},
{"4–16 digits", "4–16 dígitos", "4–16 dígitos", "4 à 16 chiffres", "4–16 Ziffern", "4–16 digit"},
{"Remove protection", "Remover proteção", "Quitar protección", "Retirer la protection", "Schutz entfernen", "Hapus perlindungan"},
{"Visual","Visual","Visual","Visuel","Optik","Visual"},
{"Fonts","Fontes","Fuentes","Polices","Schriftarten","Font"},
{"Window","Janela","Ventana","Fenêtre","Fenster","Jendela"},
{"Notifications","Notificações","Notificaciones","Notifications","Benachrichtigungen","Notifikasi"},
{"Sound","Som","Sonido","Son","Ton","Suara"},
{"Behavior","Comportamento","Comportamiento","Comportement","Verhalten","Perilaku"},
{"Privacy","Privacidade","Privacidad","Confidentialité","Datenschutz","Privasi"},
{"Transparency, size, corners and effects","Transparência, tamanho, cantos e efeitos","Transparencia, tamaño, esquinas y efectos","Transparence, taille, coins et effets","Transparenz, Größe, Ecken und Effekte","Transparansi, ukuran, sudut, dan efek"},
{"Typeface, weight and text size","Fonte, peso e tamanho do texto","Tipografía, grosor y tamaño del texto","Police, graisse et taille du texte","Schriftart, Stärke und Textgröße","Jenis huruf, ketebalan, dan ukuran teks"},
{"Position, size, open behavior and title bar","Posição, tamanho, abertura e barra de título","Posición, tamaño, apertura y barra de título","Position, taille, ouverture et barre de titre","Position, Größe, Öffnen und Titelleiste","Posisi, ukuran, perilaku buka, dan bilah judul"},
{"Pop-up notices and their timing","Avisos pop-up e o tempo deles","Avisos emergentes y su duración","Notifications pop-up et leur durée","Pop-up-Hinweise und ihre Dauer","Pemberitahuan pop-up dan durasinya"},
{"Volume and interface sounds","Volume e sons da interface","Volumen y sonidos de la interfaz","Volume et sons de l'interface","Lautstärke und Oberflächentöne","Volume dan suara antarmuka"},
{"Running, saving and startup options","Opções de execução, salvamento e inicialização","Opciones de ejecución, guardado e inicio","Options d'exécution, d'enregistrement et de démarrage","Optionen für Ausführen, Speichern und Start","Opsi menjalankan, menyimpan, dan memulai"},
{"Hide personal and game details","Oculte detalhes pessoais e do jogo","Oculta datos personales y del juego","Masquer les détails personnels et du jeu","Persönliche und Spieldetails ausblenden","Sembunyikan detail pribadi dan game"},
{"Window transparency","Transparência da janela","Transparencia de la ventana","Transparence de la fenêtre","Fenstertransparenz","Transparansi jendela"},
{"Make the whole window see-through","Deixa a janela inteira transparente","Hace transparente toda la ventana","Rend toute la fenêtre transparente","Macht das ganze Fenster durchsichtig","Membuat seluruh jendela tembus pandang"},
{"Interface size","Tamanho da interface","Tamaño de la interfaz","Taille de l'interface","Oberflächengröße","Ukuran antarmuka"},
{"Scale the whole window","Redimensiona a janela inteira","Escala toda la ventana","Redimensionne toute la fenêtre","Skaliert das ganze Fenster","Skala seluruh jendela"},
{"Corner roundness","Arredondamento dos cantos","Redondez de las esquinas","Arrondi des coins","Eckenrundung","Kebulatan sudut"},
{"Shape of panels and buttons","Formato de painéis e botões","Forma de paneles y botones","Forme des panneaux et des boutons","Form von Panels und Schaltflächen","Bentuk panel dan tombol"},
{"Borders","Bordas","Bordes","Bordures","Rahmen","Bingkai"},
{"Outline style on panels","Estilo do contorno nos painéis","Estilo del contorno en los paneles","Style du contour des panneaux","Konturstil der Panels","Gaya garis tepi panel"},
{"Scrollbar","Barra de rolagem","Barra de desplazamiento","Barre de défilement","Bildlaufleiste","Bilah gulir"},
{"Thickness of scrollbars","Espessura das barras de rolagem","Grosor de las barras de desplazamiento","Épaisseur des barres de défilement","Dicke der Bildlaufleisten","Ketebalan bilah gulir"},
{"Floating button size","Tamanho do botão flutuante","Tamaño del botón flotante","Taille du bouton flottant","Größe des schwebenden Buttons","Ukuran tombol mengambang"},
{"Size of the minimized ball","Tamanho da bolinha minimizada","Tamaño de la bola minimizada","Taille de la bulle réduite","Größe der minimierten Kugel","Ukuran bola yang diminimalkan"},
{"Floating button opacity","Opacidade do botão flutuante","Opacidad del botón flotante","Opacité du bouton flottant","Deckkraft des schwebenden Buttons","Opasitas tombol mengambang"},
{"How solid the minimized ball looks","Quão sólida a bolinha minimizada aparece","Qué tan sólida se ve la bola minimizada","Opacité de la bulle réduite","Wie deckend die minimierte Kugel wirkt","Seberapa solid bola yang diminimalkan terlihat"},
{"Disable gradients","Desativar gradientes","Desactivar degradados","Désactiver les dégradés","Verläufe deaktivieren","Nonaktifkan gradien"},
{"Use flat colors instead of gradients","Usa cores sólidas em vez de gradientes","Usa colores planos en lugar de degradados","Utilise des couleurs unies au lieu de dégradés","Einfarbige Flächen statt Verläufen verwenden","Gunakan warna polos, bukan gradien"},
{"Tab underline","Linha sob a aba","Subrayado de pestaña","Soulignement de l'onglet","Tab-Unterstreichung","Garis bawah tab"},
{"Show the line under the active tab","Mostra a linha sob a aba ativa","Muestra la línea bajo la pestaña activa","Affiche la ligne sous l'onglet actif","Zeigt die Linie unter dem aktiven Tab","Tampilkan garis di bawah tab aktif"},
{"Hover lift","Elevar ao passar o mouse","Elevar al pasar el cursor","Élévation au survol","Anheben beim Darüberfahren","Angkat saat disorot"},
{"Buttons grow slightly when hovered","Os botões crescem um pouco ao passar o mouse","Los botones crecen un poco al pasar el cursor","Les boutons grossissent légèrement au survol","Schaltflächen wachsen leicht beim Darüberfahren","Tombol sedikit membesar saat disorot"},
{"Dim game behind window","Escurecer o jogo atrás da janela","Oscurecer el juego tras la ventana","Assombrir le jeu derrière la fenêtre","Spiel hinter dem Fenster abdunkeln","Gelapkan game di belakang jendela"},
{"Darken the game while the window is open","Escurece o jogo enquanto a janela estiver aberta","Oscurece el juego mientras la ventana está abierta","Assombrit le jeu tant que la fenêtre est ouverte","Dunkelt das Spiel ab, solange das Fenster offen ist","Menggelapkan game saat jendela terbuka"},
{"Blur game behind window","Desfocar o jogo atrás da janela","Difuminar el juego tras la ventana","Flouter le jeu derrière la fenêtre","Spiel hinter dem Fenster weichzeichnen","Buramkan game di belakang jendela"},
{"Blur the game while the window is open","Desfoca o jogo enquanto a janela estiver aberta","Difumina el juego mientras la ventana está abierta","Floute le jeu tant que la fenêtre est ouverte","Zeichnet das Spiel weich, solange das Fenster offen ist","Mengaburkan game saat jendela terbuka"},
{"Font","Fonte","Fuente","Police","Schriftart","Jenis huruf"},
{"Typeface used by the interface","Fonte usada pela interface","Tipografía usada por la interfaz","Police utilisée par l'interface","Von der Oberfläche verwendete Schriftart","Jenis huruf yang dipakai antarmuka"},
{"Text weight","Peso do texto","Grosor del texto","Graisse du texte","Textstärke","Ketebalan teks"},
{"Make text lighter or bolder","Deixa o texto mais leve ou mais grosso","Hace el texto más ligero o más grueso","Rend le texte plus léger ou plus gras","Macht den Text leichter oder fetter","Membuat teks lebih tipis atau tebal"},
{"Text size","Tamanho do texto","Tamaño del texto","Taille du texte","Textgröße","Ukuran teks"},
{"Scale interface text","Redimensiona o texto da interface","Escala el texto de la interfaz","Redimensionne le texte de l'interface","Skaliert den Oberflächentext","Skala teks antarmuka"},
{"Editor font size","Tamanho da fonte do editor","Tamaño de fuente del editor","Taille de police de l'éditeur","Schriftgröße des Editors","Ukuran font editor"},
{"Size of the code in the editor","Tamanho do código no editor","Tamaño del código en el editor","Taille du code dans l'éditeur","Größe des Codes im Editor","Ukuran kode di editor"},
{"Console font size","Tamanho da fonte do console","Tamaño de fuente de la consola","Taille de police de la console","Schriftgröße der Konsole","Ukuran font konsol"},
{"Size of the console lines","Tamanho das linhas do console","Tamaño de las líneas de la consola","Taille des lignes de la console","Größe der Konsolenzeilen","Ukuran baris konsol"},
{"Gotham, Ubuntu, Roboto...","Gotham, Ubuntu, Roboto...","Gotham, Ubuntu, Roboto...","Gotham, Ubuntu, Roboto...","Gotham, Ubuntu, Roboto...","Gotham, Ubuntu, Roboto..."},
{"Type here...","Digite aqui...","Escribe aquí...","Saisissez ici...","Hier eingeben...","Ketik di sini..."},
{"Default","Padrão","Predeterminado","Par défaut","Standard","Default"},
{"None","Nenhuma","Ninguna","Aucune","Keine","Tidak ada"},
{"Use full screen area","Usar a tela inteira","Usar toda la pantalla","Utiliser tout l'écran","Gesamten Bildschirm nutzen","Gunakan seluruh layar"},
{"Draw under the Roblox top bar","Desenha sob a barra superior do Roblox","Dibuja bajo la barra superior de Roblox","Dessine sous la barre supérieure de Roblox","Zeichnet unter der Roblox-Leiste","Menggambar di bawah bilah atas Roblox"},
{"Layer order","Ordem da camada","Orden de capa","Ordre des calques","Ebenenreihenfolge","Urutan lapisan"},
{"Draw order above other interfaces","Ordem de desenho acima de outras interfaces","Orden de dibujo sobre otras interfaces","Ordre d'affichage au-dessus des autres interfaces","Zeichenreihenfolge über anderen Oberflächen","Urutan gambar di atas antarmuka lain"},
{"Open animation","Animação de abrir","Animación de apertura","Animation d'ouverture","Öffnungsanimation","Animasi buka"},
{"How the window appears","Como a janela aparece","Cómo aparece la ventana","Comment la fenêtre apparaît","Wie das Fenster erscheint","Cara jendela muncul"},
{"Pop","Pop","Pop","Pop","Pop","Pop"},
{"Fade","Esmaecer","Desvanecer","Fondu","Ausblenden","Memudar"},
{"Close animation","Animação de fechar","Animación de cierre","Animation de fermeture","Schließanimation","Animasi tutup"},
{"How the window disappears","Como a janela some","Cómo desaparece la ventana","Comment la fenêtre disparaît","Wie das Fenster verschwindet","Cara jendela menghilang"},
{"Shrink","Encolher","Encoger","Réduire","Schrumpfen","Mengecil"},
{"Hide when idle","Ocultar quando ocioso","Ocultar al estar inactivo","Masquer en cas d'inactivité","Bei Inaktivität ausblenden","Sembunyikan saat tidak aktif"},
{"Close the window after no activity","Fecha a janela após ficar sem atividade","Cierra la ventana tras un tiempo sin actividad","Ferme la fenêtre après un temps d'inactivité","Schließt das Fenster nach Inaktivität","Menutup jendela setelah tidak ada aktivitas"},
{"Dim when idle","Escurecer quando ocioso","Atenuar al estar inactivo","Assombrir en cas d'inactivité","Bei Inaktivität abdunkeln","Redupkan saat tidak aktif"},
{"Darken the window after 8 seconds without input","Escurece a janela após 8 segundos sem interação","Oscurece la ventana tras 8 segundos sin interacción","Assombrit la fenêtre après 8 secondes sans action","Dunkelt das Fenster nach 8 Sekunden ohne Eingabe ab","Menggelapkan jendela setelah 8 detik tanpa input"},
{"Lock position","Travar posição","Bloquear posición","Verrouiller la position","Position sperren","Kunci posisi"},
{"Prevent dragging the window","Impede arrastar a janela","Impide arrastrar la ventana","Empêche de déplacer la fenêtre","Verhindert das Verschieben des Fensters","Mencegah jendela diseret"},
{"Lock size","Travar tamanho","Bloquear tamaño","Verrouiller la taille","Größe sperren","Kunci ukuran"},
{"Prevent maximizing and restoring","Impede maximizar e restaurar","Impide maximizar y restaurar","Empêche d'agrandir et de restaurer","Verhindert Maximieren und Wiederherstellen","Mencegah memaksimalkan dan memulihkan"},
{"Remember position","Lembrar posição","Recordar posición","Mémoriser la position","Position merken","Ingat posisi"},
{"Reopen where you left the window","Reabre onde você deixou a janela","Reabre donde dejaste la ventana","Rouvre là où vous avez laissé la fenêtre","Öffnet dort, wo du das Fenster gelassen hast","Dibuka kembali di tempat terakhir jendela"},
{"Keep on screen","Manter na tela","Mantener en pantalla","Garder à l'écran","Auf dem Bildschirm halten","Tetap di layar"},
{"Pull the window back if dropped outside","Traz a janela de volta se for solta fora da tela","Devuelve la ventana si se suelta fuera","Ramène la fenêtre si elle est lâchée en dehors","Holt das Fenster zurück, wenn es außerhalb abgelegt wird","Menarik jendela kembali jika dilepas di luar layar"},
{"Snap to edges","Encaixar nas bordas","Ajustar a los bordes","Aimanter aux bords","An Rändern einrasten","Tempel ke tepi"},
{"Stick to screen borders when dropped nearby","Gruda nas bordas da tela quando solta perto","Se pega a los bordes de la pantalla al soltarla cerca","Se colle aux bords de l'écran si elle est lâchée près","Haftet an Bildschirmrändern, wenn es nahe losgelassen wird","Menempel ke tepi layar saat dilepas di dekatnya"},
{"Start maximized","Iniciar maximizada","Iniciar maximizada","Démarrer agrandie","Maximiert starten","Mulai dimaksimalkan"},
{"Open at full size","Abre em tamanho total","Abre en tamaño completo","S'ouvre en taille réelle","Öffnet in voller Größe","Dibuka dalam ukuran penuh"},
{"Start minimized","Iniciar minimizada","Iniciar minimizada","Démarrer réduite","Minimiert starten","Mulai diminimalkan"},
{"Open as the floating ball","Abre como a bolinha flutuante","Abre como la bola flotante","S'ouvre en bulle flottante","Öffnet als schwebende Kugel","Dibuka sebagai bola mengambang"},
{"Open on load","Abrir ao carregar","Abrir al cargar","Ouvrir au chargement","Beim Laden öffnen","Buka saat dimuat"},
{"Show the window when Hyundax IUM loads","Mostra a janela quando o Hyundax IUM carrega","Muestra la ventana al cargar Hyundax IUM","Affiche la fenêtre au chargement de Hyundax IUM","Zeigt das Fenster beim Laden von Hyundax IUM","Menampilkan jendela saat Hyundax IUM dimuat"},
{"Center on open","Centralizar ao abrir","Centrar al abrir","Centrer à l'ouverture","Beim Öffnen zentrieren","Tengahkan saat dibuka"},
{"Always reopen in the center","Sempre reabre no centro","Siempre reabre en el centro","Rouvre toujours au centre","Öffnet immer in der Mitte","Selalu dibuka di tengah"},
{"Double click to maximize","Clique duplo para maximizar","Doble clic para maximizar","Double-clic pour agrandir","Doppelklick zum Maximieren","Klik dua kali untuk memaksimalkan"},
{"Double click the title bar","Clique duas vezes na barra de título","Haz doble clic en la barra de título","Double-cliquez sur la barre de titre","Doppelklick auf die Titelleiste","Klik dua kali bilah judul"},
{"Esc closes window","Esc fecha a janela","Esc cierra la ventana","Échap ferme la fenêtre","Esc schließt das Fenster","Esc menutup jendela"},
{"Hide the window with the Escape key","Oculta a janela com a tecla Esc","Oculta la ventana con la tecla Esc","Masque la fenêtre avec la touche Échap","Blendet das Fenster mit der Esc-Taste aus","Sembunyikan jendela dengan tombol Esc"},
{"Confirm close","Confirmar ao fechar","Confirmar al cerrar","Confirmer la fermeture","Schließen bestätigen","Konfirmasi tutup"},
{"Ask before closing the window","Pergunta antes de fechar a janela","Pregunta antes de cerrar la ventana","Demande avant de fermer la fenêtre","Fragt vor dem Schließen des Fensters","Tanya sebelum menutup jendela"},
{"Hide on death","Ocultar ao morrer","Ocultar al morir","Masquer à la mort","Beim Tod ausblenden","Sembunyikan saat mati"},
{"Close the window when your character dies","Fecha a janela quando seu personagem morre","Cierra la ventana cuando tu personaje muere","Ferme la fenêtre quand votre personnage meurt","Schließt das Fenster, wenn deine Figur stirbt","Menutup jendela saat karaktermu mati"},
{"Clock in title bar","Relógio na barra de título","Reloj en la barra de título","Horloge dans la barre de titre","Uhr in der Titelleiste","Jam di bilah judul"},
{"Show the current time","Mostra a hora atual","Muestra la hora actual","Affiche l'heure actuelle","Zeigt die aktuelle Uhrzeit","Tampilkan waktu saat ini"},
{"FPS in title bar","FPS na barra de título","FPS en la barra de título","FPS dans la barre de titre","FPS in der Titelleiste","FPS di bilah judul"},
{"Show frames per second","Mostra quadros por segundo","Muestra fotogramas por segundo","Affiche les images par seconde","Zeigt Bilder pro Sekunde","Tampilkan frame per detik"},
{"Ping in title bar","Ping na barra de título","Ping en la barra de título","Ping dans la barre de titre","Ping in der Titelleiste","Ping di bilah judul"},
{"Show network ping","Mostra o ping da rede","Muestra el ping de red","Affiche le ping réseau","Zeigt den Netzwerk-Ping","Tampilkan ping jaringan"},
{"Notice duration","Duração dos avisos","Duración de los avisos","Durée des notifications","Anzeigedauer der Hinweise","Durasi pemberitahuan"},
{"How long notices stay","Quanto tempo os avisos ficam","Cuánto tiempo permanecen los avisos","Durée d'affichage des notifications","Wie lange Hinweise sichtbar bleiben","Berapa lama pemberitahuan tampil"},
{"Notice position","Posição dos avisos","Posición de los avisos","Position des notifications","Position der Hinweise","Posisi pemberitahuan"},
{"Where notices appear","Onde os avisos aparecem","Dónde aparecen los avisos","Où les notifications apparaissent","Wo Hinweise erscheinen","Tempat pemberitahuan muncul"},
{"Bottom right","Inferior direito","Abajo a la derecha","En bas à droite","Unten rechts","Kanan bawah"},
{"Bottom left","Inferior esquerdo","Abajo a la izquierda","En bas à gauche","Unten links","Kiri bawah"},
{"Top right","Superior direito","Arriba a la derecha","En haut à droite","Oben rechts","Kanan atas"},
{"Top left","Superior esquerdo","Arriba a la izquierda","En haut à gauche","Oben links","Kiri atas"},
{"Max notices","Máx. de avisos","Máx. de avisos","Notifications max.","Max. Hinweise","Maks. pemberitahuan"},
{"How many show at once","Quantos aparecem ao mesmo tempo","Cuántos se muestran a la vez","Combien s'affichent en même temps","Wie viele gleichzeitig erscheinen","Berapa banyak tampil sekaligus"},
{"Success notices","Avisos de sucesso","Avisos de éxito","Notifications de succès","Erfolgshinweise","Pemberitahuan sukses"},
{"Show success messages","Mostra mensagens de sucesso","Muestra mensajes de éxito","Affiche les messages de succès","Zeigt Erfolgsmeldungen","Tampilkan pesan sukses"},
{"Error notices","Avisos de erro","Avisos de error","Notifications d'erreur","Fehlerhinweise","Pemberitahuan error"},
{"Show error messages","Mostra mensagens de erro","Muestra mensajes de error","Affiche les messages d'erreur","Zeigt Fehlermeldungen","Tampilkan pesan error"},
{"Warning notices","Avisos de alerta","Avisos de advertencia","Notifications d'avertissement","Warnhinweise","Pemberitahuan peringatan"},
{"Show warnings","Mostra alertas","Muestra advertencias","Affiche les avertissements","Zeigt Warnungen","Tampilkan peringatan"},
{"Info notices","Avisos informativos","Avisos informativos","Notifications d'information","Infohinweise","Pemberitahuan info"},
{"Show general info","Mostra informações gerais","Muestra información general","Affiche les informations générales","Zeigt allgemeine Infos","Tampilkan info umum"},
{"Run notices","Avisos de execução","Avisos de ejecución","Notifications d'exécution","Ausführungshinweise","Pemberitahuan eksekusi"},
{"When a script is executed","Quando um script é executado","Cuando se ejecuta un script","Quand un script est exécuté","Wenn ein Skript ausgeführt wird","Saat skrip dijalankan"},
{"Save notices","Avisos de salvamento","Avisos de guardado","Notifications d'enregistrement","Speicherhinweise","Pemberitahuan simpan"},
{"When something is saved","Quando algo é salvo","Cuando algo se guarda","Quand quelque chose est enregistré","Wenn etwas gespeichert wird","Saat sesuatu disimpan"},
{"Copy notices","Avisos de cópia","Avisos de copia","Notifications de copie","Kopierhinweise","Pemberitahuan salin"},
{"When text is copied","Quando um texto é copiado","Cuando se copia texto","Quand du texte est copié","Wenn Text kopiert wird","Saat teks disalin"},
{"Load notices","Avisos de carregamento","Avisos de carga","Notifications de chargement","Ladehinweise","Pemberitahuan muat"},
{"When something loads","Quando algo carrega","Cuando algo se carga","Quand quelque chose se charge","Wenn etwas geladen wird","Saat sesuatu dimuat"},
{"Plugin notices","Avisos de plugins","Avisos de plugins","Notifications de plugins","Plugin-Hinweise","Pemberitahuan plugin"},
{"Messages that mention plugins","Mensagens que mencionam plugins","Mensajes que mencionan plugins","Messages mentionnant des plugins","Meldungen, die Plugins erwähnen","Pesan yang menyebut plugin"},
{"Update notices","Avisos de atualização","Avisos de actualización","Notifications de mise à jour","Update-Hinweise","Pemberitahuan pembaruan"},
{"Messages about updates","Mensagens sobre atualizações","Mensajes sobre actualizaciones","Messages sur les mises à jour","Meldungen zu Updates","Pesan tentang pembaruan"},
{"Welcome notices","Avisos de boas-vindas","Avisos de bienvenida","Notifications de bienvenue","Willkommenshinweise","Pemberitahuan selamat datang"},
{"Hello and sign in messages","Mensagens de olá e de login","Mensajes de saludo e inicio de sesión","Messages de bienvenue et de connexion","Begrüßungs- und Anmeldemeldungen","Pesan sapaan dan masuk"},
{"Theme notices","Avisos de tema","Avisos de tema","Notifications de thème","Design-Hinweise","Pemberitahuan tema"},
{"Messages about themes","Mensagens sobre temas","Mensajes sobre temas","Messages sur les thèmes","Meldungen zu Designs","Pesan tentang tema"},
{"Language notices","Avisos de idioma","Avisos de idioma","Notifications de langue","Sprachhinweise","Pemberitahuan bahasa"},
{"Messages about the language","Mensagens sobre o idioma","Mensajes sobre el idioma","Messages sur la langue","Meldungen zur Sprache","Pesan tentang bahasa"},
{"Group repeated notices","Agrupar avisos repetidos","Agrupar avisos repetidos","Regrouper les notifications répétées","Wiederholte Hinweise gruppieren","Kelompokkan pemberitahuan berulang"},
{"Do not repeat a notice that is already visible","Não repete um aviso que já está visível","No repite un aviso que ya está visible","Ne répète pas une notification déjà visible","Wiederholt keinen bereits sichtbaren Hinweis","Tidak mengulang pemberitahuan yang sudah terlihat"},
{"Notice icons","Ícones dos avisos","Iconos de los avisos","Icônes des notifications","Hinweis-Symbole","Ikon pemberitahuan"},
{"Icon on each notice","Ícone em cada aviso","Icono en cada aviso","Icône sur chaque notification","Symbol bei jedem Hinweis","Ikon pada setiap pemberitahuan"},
{"Notice timer bar","Barra de tempo dos avisos","Barra de tiempo de los avisos","Barre de temps des notifications","Zeitleiste der Hinweise","Bilah waktu pemberitahuan"},
{"Bar showing the remaining time","Barra que mostra o tempo restante","Barra que muestra el tiempo restante","Barre indiquant le temps restant","Leiste mit der verbleibenden Zeit","Bilah yang menunjukkan sisa waktu"},
{"Click to dismiss","Clique para dispensar","Clic para descartar","Cliquer pour fermer","Zum Schließen klicken","Klik untuk menutup"},
{"Tap a notice to close it","Toque em um aviso para fechá-lo","Toca un aviso para cerrarlo","Touchez une notification pour la fermer","Tippe auf einen Hinweis, um ihn zu schließen","Ketuk pemberitahuan untuk menutupnya"},
{"Compact notices","Avisos compactos","Avisos compactos","Notifications compactes","Kompakte Hinweise","Pemberitahuan ringkas"},
{"Smaller notice cards","Cartões de aviso menores","Tarjetas de aviso más pequeñas","Cartes de notification plus petites","Kleinere Hinweiskarten","Kartu pemberitahuan lebih kecil"},
{"Volume","Volume","Volumen","Volume","Lautstärke","Volume"},
{"Loudness of interface sounds","Intensidade dos sons da interface","Intensidad de los sonidos de la interfaz","Intensité des sons de l'interface","Lautstärke der Oberflächentöne","Keras suara antarmuka"},
{"Tab sounds","Sons de abas","Sonidos de pestañas","Sons des onglets","Tab-Töne","Suara tab"},
{"Sound when changing tabs","Som ao trocar de aba","Sonido al cambiar de pestaña","Son lors du changement d'onglet","Ton beim Tabwechsel","Suara saat berpindah tab"},
{"Click sounds","Sons de clique","Sonidos de clic","Sons de clic","Klicktöne","Suara klik"},
{"Sound on buttons","Som nos botões","Sonido en los botones","Son sur les boutons","Ton bei Schaltflächen","Suara pada tombol"},
{"Toggle sounds","Sons de interruptor","Sonidos de interruptor","Sons des interrupteurs","Schaltertöne","Suara sakelar"},
{"Sound on switches","Som nos interruptores","Sonido en los interruptores","Son sur les interrupteurs","Ton bei Schaltern","Suara pada sakelar"},
{"Notice sounds","Sons de avisos","Sonidos de avisos","Sons des notifications","Hinweistöne","Suara pemberitahuan"},
{"Sound on success and error notices","Som nos avisos de sucesso e erro","Sonido en avisos de éxito y error","Son sur les notifications de succès et d'erreur","Ton bei Erfolgs- und Fehlerhinweisen","Suara pada pemberitahuan sukses dan error"},
{"Open and close sounds","Sons de abrir e fechar","Sonidos de abrir y cerrar","Sons d'ouverture et de fermeture","Öffnen- und Schließen-Töne","Suara buka dan tutup"},
{"Sound when showing or hiding the window","Som ao mostrar ou ocultar a janela","Sonido al mostrar u ocultar la ventana","Son lors de l'affichage ou du masquage de la fenêtre","Ton beim Ein- und Ausblenden des Fensters","Suara saat menampilkan atau menyembunyikan jendela"},
{"Bubble sounds","Sons de bolha","Sonidos de burbuja","Sons de bulle","Blasentöne","Suara gelembung"},
{"Whoosh when the window opens and closes","Whoosh quando a janela abre e fecha","Whoosh al abrir y cerrar la ventana","Whoosh à l'ouverture et à la fermeture de la fenêtre","Whoosh beim Öffnen und Schließen des Fensters","Whoosh saat jendela dibuka dan ditutup"},
{"Hover sounds","Sons ao passar o mouse","Sonidos al pasar el cursor","Sons au survol","Hover-Töne","Suara saat disorot"},
{"Soft sound when hovering buttons","Som suave ao passar o mouse nos botões","Sonido suave al pasar el cursor por los botones","Son doux au survol des boutons","Leiser Ton beim Überfahren von Schaltflächen","Suara lembut saat menyorot tombol"},
{"Startup sound","Som de inicialização","Sonido de inicio","Son de démarrage","Startton","Suara startup"},
{"Play a sound when Hyundax IUM loads","Toca um som quando o Hyundax IUM carrega","Reproduce un sonido al cargar Hyundax IUM","Joue un son au chargement de Hyundax IUM","Spielt einen Ton beim Laden von Hyundax IUM","Putar suara saat Hyundax IUM dimuat"},
{"Mute when unfocused","Silenciar sem foco","Silenciar sin foco","Couper le son sans focus","Stumm ohne Fokus","Bisukan saat tidak fokus"},
{"Silence sounds when the game loses focus","Silencia os sons quando o jogo perde o foco","Silencia los sonidos cuando el juego pierde el foco","Coupe les sons quand le jeu perd le focus","Schaltet Töne stumm, wenn das Spiel den Fokus verliert","Membisukan suara saat game kehilangan fokus"},
{"Start page","Página inicial","Página de inicio","Page de démarrage","Startseite","Halaman awal"},
{"Page shown when Hyundax IUM loads","Página mostrada quando o Hyundax IUM carrega","Página mostrada al cargar Hyundax IUM","Page affichée au chargement de Hyundax IUM","Seite, die beim Laden von Hyundax IUM angezeigt wird","Halaman yang ditampilkan saat Hyundax IUM dimuat"},
{"Last used","Última usada","Última usada","Dernière utilisée","Zuletzt verwendet","Terakhir dipakai"},
{"How many recent scripts to keep","Quantos scripts recentes manter","Cuántos scripts recientes conservar","Combien de scripts récents conserver","Wie viele letzte Skripte gespeichert bleiben","Berapa banyak skrip terbaru disimpan"},
{"Indent size","Tamanho do recuo","Tamaño de sangría","Taille de l'indentation","Einrückungsgröße","Ukuran indentasi"},
{"Spaces added by auto-indent","Espaços adicionados pela indentação automática","Espacios añadidos por la sangría automática","Espaces ajoutés par l'indentation automatique","Leerzeichen durch automatisches Einrücken","Spasi yang ditambahkan indentasi otomatis"},
{"Confirm before run","Confirmar antes de executar","Confirmar antes de ejecutar","Confirmer avant d'exécuter","Vor Ausführung bestätigen","Konfirmasi sebelum menjalankan"},
{"Ask before executing a script","Pergunta antes de executar um script","Pregunta antes de ejecutar un script","Demande avant d'exécuter un script","Fragt vor dem Ausführen eines Skripts","Tanya sebelum menjalankan skrip"},
{"Clear console on run","Limpar console ao executar","Limpiar consola al ejecutar","Vider la console à l'exécution","Konsole beim Ausführen leeren","Bersihkan konsol saat menjalankan"},
{"Start each run with an empty console","Começa cada execução com o console vazio","Inicia cada ejecución con la consola vacía","Démarre chaque exécution avec une console vide","Startet jeden Lauf mit leerer Konsole","Mulai setiap eksekusi dengan konsol kosong"},
{"Minimize on run","Minimizar ao executar","Minimizar al ejecutar","Réduire à l'exécution","Beim Ausführen minimieren","Minimalkan saat menjalankan"},
{"Shrink the window after executing","Encolhe a janela após executar","Encoge la ventana tras ejecutar","Réduit la fenêtre après l'exécution","Verkleinert das Fenster nach dem Ausführen","Mengecilkan jendela setelah menjalankan"},
{"Trim spaces on save","Remover espaços ao salvar","Recortar espacios al guardar","Supprimer les espaces à l'enregistrement","Leerzeichen beim Speichern entfernen","Pangkas spasi saat menyimpan"},
{"Remove trailing spaces when saving","Remove espaços no fim das linhas ao salvar","Quita los espacios finales al guardar","Supprime les espaces en fin de ligne à l'enregistrement","Entfernt Leerzeichen am Zeilenende beim Speichern","Menghapus spasi di akhir baris saat menyimpan"},
{"Hide nickname","Ocultar apelido","Ocultar apodo","Masquer le pseudo","Spitznamen ausblenden","Sembunyikan nama panggilan"},
{"Do not show your nickname in notices or the title bar","Não mostra seu apelido nos avisos nem na barra de título","No muestra tu apodo en avisos ni en la barra de título","N'affiche pas votre pseudo dans les notifications ni la barre de titre","Zeigt deinen Spitznamen nicht in Hinweisen oder der Titelleiste","Tidak menampilkan nama panggilanmu di pemberitahuan atau bilah judul"},
{"Anonymous console","Console anônimo","Consola anónima","Console anonyme","Anonyme Konsole","Konsol anonim"},
{"Replace your player name in new console lines","Substitui seu nome de jogador nas novas linhas do console","Reemplaza tu nombre de jugador en las nuevas líneas de la consola","Remplace votre nom de joueur dans les nouvelles lignes de la console","Ersetzt deinen Spielernamen in neuen Konsolenzeilen","Mengganti nama pemainmu di baris konsol baru"},
{"Redact tokens","Ocultar tokens","Ocultar tokens","Masquer les jetons","Tokens schwärzen","Samarkan token"},
{"Hide long keys and tokens in new console lines","Oculta chaves e tokens longos nas novas linhas do console","Oculta claves y tokens largos en las nuevas líneas de la consola","Masque les longues clés et jetons dans les nouvelles lignes de la console","Blendet lange Schlüssel und Tokens in neuen Konsolenzeilen aus","Menyembunyikan kunci dan token panjang di baris konsol baru"},
{"Hide executor in debug info","Ocultar executor nas infos de debug","Ocultar executor en la info de depuración","Masquer l'exécuteur dans les infos de débogage","Executor in Debug-Infos ausblenden","Sembunyikan executor di info debug"},
{"Leave it out of Copy debug info","Deixa de fora ao copiar infos de debug","Lo deja fuera al copiar la info de depuración","L'exclut de la copie des infos de débogage","Wird beim Kopieren der Debug-Infos weggelassen","Dikecualikan saat menyalin info debug"},
{"Hide PlaceId in debug info","Ocultar PlaceId nas infos de debug","Ocultar PlaceId en la info de depuración","Masquer le PlaceId dans les infos de débogage","PlaceId in Debug-Infos ausblenden","Sembunyikan PlaceId di info debug"},
{"Hide JobId in debug info","Ocultar JobId nas infos de debug","Ocultar JobId en la info de depuración","Masquer le JobId dans les infos de débogage","JobId in Debug-Infos ausblenden","Sembunyikan JobId di info debug"},
{"Confirm copying debug info","Confirmar cópia das infos de debug","Confirmar copia de la info de depuración","Confirmer la copie des infos de débogage","Kopieren der Debug-Infos bestätigen","Konfirmasi penyalinan info debug"},
{"Ask before copying it","Pergunta antes de copiar","Pregunta antes de copiarla","Demande avant de la copier","Fragt vor dem Kopieren","Tanya sebelum menyalin"},
{"Do not save recents","Não salvar recentes","No guardar recientes","Ne pas enregistrer les récents","Letzte nicht speichern","Jangan simpan terbaru"},
{"Never store recent scripts","Nunca guarda scripts recentes","Nunca guarda scripts recientes","Ne stocke jamais les scripts récents","Speichert nie letzte Skripte","Tidak pernah menyimpan skrip terbaru"},
{"Do not count statistics","Não contar estatísticas","No contar estadísticas","Ne pas compter les statistiques","Statistiken nicht zählen","Jangan hitung statistik"},
{"Stop counting runs and errors","Para de contar execuções e erros","Deja de contar ejecuciones y errores","Arrête de compter les exécutions et les erreurs","Zählt Ausführungen und Fehler nicht mehr","Berhenti menghitung eksekusi dan error"},
{"Settings reset to default","Configurações restauradas ao padrão","Ajustes restablecidos a los valores predeterminados","Paramètres réinitialisés par défaut","Einstellungen auf Standard zurückgesetzt","Pengaturan dikembalikan ke default"},
{"Show a shortcut hint line at the bottom of the window","Mostra uma linha de atalhos na parte inferior da janela","Muestra una línea de atajos en la parte inferior de la ventana","Affiche une ligne de raccourcis en bas de la fenêtre","Zeigt unten im Fenster eine Zeile mit Tastenkürzeln","Tampilkan baris petunjuk pintasan di bagian bawah jendela"},
{"Reset all settings","Redefinir todas as configurações","Restablecer todos los ajustes","Réinitialiser tous les paramètres","Alle Einstellungen zurücksetzen","Atur ulang semua pengaturan"},
{"Put every setting, the theme and the window back to the default Hyundax IUM","Volta todas as configurações, o tema e a janela ao padrão do Hyundax IUM","Devuelve todos los ajustes, el tema y la ventana a los valores de Hyundax IUM","Remet tous les paramètres, le thème et la fenêtre aux valeurs par défaut de Hyundax IUM","Setzt alle Einstellungen, das Design und das Fenster auf den Hyundax-IUM-Standard zurück","Mengembalikan semua pengaturan, tema, dan jendela ke default Hyundax IUM"},
{"Reset ALL settings to default?","Redefinir TODAS as configurações ao padrão?","¿Restablecer TODOS los ajustes?","Réinitialiser TOUS les paramètres ?","ALLE Einstellungen zurücksetzen?","Atur ulang SEMUA pengaturan ke default?"},
{"Reset visual settings","Redefinir configurações visuais","Restablecer ajustes visuales","Réinitialiser les paramètres visuels","Visuelle Einstellungen zurücksetzen","Atur ulang pengaturan visual"},
{"Restore Visual, Fonts and Window options","Restaura as opções de Visual, Fontes e Janela","Restaura las opciones de Visual, Fuentes y Ventana","Restaure les options Visuel, Polices et Fenêtre","Stellt die Optionen für Optik, Schriftarten und Fenster wieder her","Memulihkan opsi Visual, Font, dan Jendela"},
{"Reset Visual, Fonts and Window settings?","Redefinir as configurações de Visual, Fontes e Janela?","¿Restablecer los ajustes de Visual, Fuentes y Ventana?","Réinitialiser les paramètres Visuel, Polices et Fenêtre ?","Einstellungen für Optik, Schriftarten und Fenster zurücksetzen?","Atur ulang pengaturan Visual, Font, dan Jendela?"},
{"Visual settings reset, reopen the tab","Configurações visuais redefinidas, reabra a aba","Ajustes visuales restablecidos, reabre la pestaña","Paramètres visuels réinitialisés, rouvrez l'onglet","Visuelle Einstellungen zurückgesetzt, Tab neu öffnen","Pengaturan visual direset, buka kembali tab"},
{"Reset all new settings","Redefinir todas as configurações novas","Restablecer todos los ajustes nuevos","Réinitialiser tous les nouveaux paramètres","Alle neuen Einstellungen zurücksetzen","Atur ulang semua pengaturan baru"},
{"Restore every option from the extra tabs","Restaura todas as opções das abas extras","Restaura todas las opciones de las pestañas extra","Restaure toutes les options des onglets supplémentaires","Stellt alle Optionen der zusätzlichen Tabs wieder her","Memulihkan semua opsi dari tab tambahan"},
{"Reset all settings from the extra tabs?","Redefinir todas as configurações das abas extras?","¿Restablecer todos los ajustes de las pestañas extra?","Réinitialiser tous les paramètres des onglets supplémentaires ?","Alle Einstellungen der zusätzlichen Tabs zurücksetzen?","Atur ulang semua pengaturan dari tab tambahan?"},
{"Settings reset, reopen the tab","Configurações redefinidas, reabra a aba","Ajustes restablecidos, reabre la pestaña","Paramètres réinitialisés, rouvrez l'onglet","Einstellungen zurückgesetzt, Tab neu öffnen","Pengaturan direset, buka kembali tab"},
{"Copy settings","Copiar configurações","Copiar ajustes","Copier les paramètres","Einstellungen kopieren","Salin pengaturan"},
{"Copy your settings as JSON","Copia suas configurações como JSON","Copia tus ajustes como JSON","Copie vos paramètres au format JSON","Kopiert deine Einstellungen als JSON","Salin pengaturanmu sebagai JSON"},
{"Settings copied","Configurações copiadas","Ajustes copiados","Paramètres copiés","Einstellungen kopiert","Pengaturan disalin"},
{"Clear the console?","Limpar o console?","¿Limpiar la consola?","Vider la console ?","Konsole leeren?","Bersihkan konsol?"},
{"Copy debug info to the clipboard?","Copiar infos de debug para a área de transferência?","¿Copiar la info de depuración al portapapeles?","Copier les infos de débogage dans le presse-papiers ?","Debug-Infos in die Zwischenablage kopieren?","Salin info debug ke papan klip?"},
{"Reset the run statistics?","Redefinir as estatísticas de execução?","¿Restablecer las estadísticas de ejecución?","Réinitialiser les statistiques d'exécution ?","Ausführungsstatistiken zurücksetzen?","Atur ulang statistik eksekusi?"},
{"Print every setting change in the console","Imprime toda mudança de configuração no console","Imprime cada cambio de ajuste en la consola","Affiche chaque changement de paramètre dans la console","Gibt jede Einstellungsänderung in der Konsole aus","Cetak setiap perubahan pengaturan di konsol"},
{"Auto-Execute","Auto-execução","Auto-ejecución","Exécution auto","Auto-Ausführung","Eksekusi otomatis"},
}
local PREFIX = {
{"> Executing ","> Executando ","> Ejecutando ","> Exécution de ","> Ausführen: ","> Menjalankan "},
{"Welcome to ","Bem-vindo ao ","Bienvenido a ","Bienvenue sur ","Willkommen bei ","Selamat datang di "},
{"Signed in as ","Conectado como ","Conectado como ","Connecté en tant que ","Angemeldet als ","Masuk sebagai "},
{"Place ID ","ID do lugar ","ID del lugar ","ID du lieu ","Place-ID ","ID tempat "},
{"Teleported to ","Teleportado para ","Teletransportado a ","Téléporté vers ","Teleportiert zu ","Teleportasi ke "},
{"> Destroyed ","> Destruído ","> Destruido ","> Détruit : ","> Zerstört: ","> Dihancurkan "},
{"> Inject into ","> Injetar em ","> Inyectar en ","> Injecter dans ","> Injizieren in ","> Suntik ke "},
{"Animations: ","Animações: ","Animaciones: ","Animations : ","Animationen: ","Animasi: "},
{"Saved to workspace/","Salvo em workspace/","Guardado en workspace/","Enregistré dans workspace/","Gespeichert in workspace/","Disimpan di workspace/"},
{"No files in workspace/","Nenhum arquivo em workspace/","Sin archivos en workspace/","Aucun fichier dans workspace/","Keine Dateien in workspace/","Tidak ada berkas di workspace/"},
{"[autoexec] could not read ","[autoexec] não foi possível ler ","[autoexec] no se pudo leer ","[autoexec] lecture impossible : ","[autoexec] konnte nicht gelesen werden: ","[autoexec] tidak bisa membaca "},
{"Hello, ","Olá, ","Hola, ","Bonjour, ","Hallo, ","Halo, "},
{"Added ","Adicionado em ","Añadido el ","Ajouté le ","Hinzugefügt am ","Ditambahkan "},
{"Opened ","Aberto: ","Abierto: ","Ouvert : ","Geöffnet: ","Dibuka: "},
{"Created by ","Criado por ","Creado por ","Créé par ","Erstellt von ","Dibuat oleh "},
}
local PATTERNS = {
{"^No access lock · (%d+) saved items$", "No access lock · %1 saved items", "Sem bloqueio · %1 itens salvos", "Sin bloqueo · %1 elementos guardados", "Sans verrou · %1 éléments enregistrés", "Keine Sperre · %1 gespeicherte Einträge", "Tanpa kunci · %1 item tersimpan"},
{"^Lock enabled · (%d+) saved items$", "Lock enabled · %1 saved items", "Bloqueio ativo · %1 itens salvos", "Bloqueo activo · %1 elementos guardados", "Verrou activé · %1 éléments enregistrés", "Sperre aktiv · %1 gespeicherte Einträge", "Kunci aktif · %1 item tersimpan"},
{"^No access lock · 1 saved item$", "No access lock · 1 saved item", "Sem bloqueio · 1 item salvo", "Sin bloqueo · 1 elemento guardado", "Sans verrou · 1 élément enregistré", "Keine Sperre · 1 gespeicherter Eintrag", "Tanpa kunci · 1 item tersimpan"},
{"^Lock enabled · 1 saved item$", "Lock enabled · 1 saved item", "Bloqueio ativo · 1 item salvo", "Bloqueo activo · 1 elemento guardado", "Verrou activé · 1 élément enregistré", "Sperre aktiv · 1 gespeicherter Eintrag", "Kunci aktif · 1 item tersimpan"},
{"^Switched to (.-)$", "Switched to %1", "Trocou para %1", "Cambiado a %1", "Changé pour %1", "Gewechselt zu %1", "Beralih ke %1"},
{"^(%d+) days$", "%1 days", "%1 dias", "%1 días", "%1 jours", "%1 Tage", "%1 hari"},
{"^Signed in as (.-) · Session active$", "Signed in as %1 · Session active", "Conectado como %1 · Sessão ativa", "Conectado como %1 · Sesión activa", "Connecté en tant que %1 · Session active", "Angemeldet als %1 · Sitzung aktiv", "Masuk sebagai %1 · Sesi aktif"},
{"^Page (%d+) / (%d+)$", "Page %1 / %2", "Página %1 / %2", "Página %1 / %2", "Page %1 / %2", "Seite %1 / %2", "Halaman %1 / %2"},
{"^Ln (%d+), Col (%d+) Spaces: 4 UTF%-8 Luau$", "Ln %1, Col %2 Spaces: 4 UTF-8 Luau", "Lin %1, Col %2 Espaços: 4 UTF-8 Luau", "Ln %1, Col %2 Espacios: 4 UTF-8 Luau", "Ln %1, Col %2 Espaces : 4 UTF-8 Luau", "Z %1, Sp %2 Leerzeichen: 4 UTF-8 Luau", "Brs %1, Kol %2 Spasi: 4 UTF-8 Luau"},
{"^Loops running: (%d+)$", "Loops running: %1", "Loops em execução: %1", "Bucles activos: %1", "Boucles actives : %1", "Laufende Schleifen: %1", "Loop berjalan: %1"},
{"^1 result$", "1 result", "1 resultado", "1 resultado", "1 résultat", "1 Ergebnis", "1 hasil"},
{"^(%d+) results$", "%1 results", "%1 resultados", "%1 resultados", "%1 résultats", "%1 Ergebnisse", "%1 hasil"},
{"^(%d+) selected · (%d+) lines$", "%1 selected · %2 lines", "%1 selecionados · %2 linhas", "%1 seleccionados · %2 líneas", "%1 sélectionnés · %2 lignes", "%1 ausgewählt · %2 Zeilen", "%1 dipilih · %2 baris"},
{"^PLAYERS %((%d+)%) · sorted by distance$", "PLAYERS (%1) · sorted by distance", "JOGADORES (%1) · por distância", "JUGADORES (%1) · por distancia", "JOUEURS (%1) · triés par distance", "SPIELER (%1) · nach Entfernung", "PEMAIN (%1) · urut jarak"},
{"^@(.-) · no character$", "@%1 · no character", "@%1 · sem personagem", "@%1 · sin personaje", "@%1 · pas de personnage", "@%1 · kein Charakter", "@%1 · tanpa karakter"},
{"^> Loop on (.-) every (.-)s$", "> Loop on %1 every %2s", "> Loop em %1 a cada %2s", "> Bucle en %1 cada %2s", "> Boucle sur %1 toutes les %2s", "> Schleife auf %1 alle %2s", "> Loop pada %1 setiap %2s"},
{"^%[autoexec%] '(.-)' saved locally; it will run each time Hyundax IUM loads%.$", "[autoexec] '%1' saved locally; it will run each time Hyundax IUM loads.", "[autoexec] '%1' salvo localmente; vai rodar toda vez que o Hyundax IUM carregar.", "[autoexec] '%1' guardado localmente; se ejecutará cada vez que Hyundax IUM cargue.", "[autoexec] '%1' enregistré localement ; il s'exécutera à chaque chargement de Hyundax IUM.", "[autoexec] '%1' lokal gespeichert; läuft bei jedem Start von Hyundax IUM.", "[autoexec] '%1' disimpan lokal; akan berjalan setiap Hyundax IUM dimuat."},
{"^Forged 1 module$", "Forged 1 module", "1 módulo forjado", "1 módulo forjado", "1 module forgé", "1 Modul geschmiedet", "1 modul dibuat"},
{"^Forged (%d+) modules$", "Forged %1 modules", "%1 módulos forjados", "%1 módulos forjados", "%1 modules forgés", "%1 Module geschmiedet", "%1 modul dibuat"},
{"^Tab #(%d+)$", "Tab #%1", "Aba #%1", "Pestaña #%1", "Onglet #%1", "Tab #%1", "Tab #%1"},
{"^([%d%.]+) yrs$", "%1 yrs", "%1 anos", "%1 años", "%1 ans", "%1 Jahre", "%1 thn"},
{"^%[sUNC%] (%d+) functions known, (%d+) polyfilled for this executor%. Home > sUNC to run tests%.$", "[sUNC] %1 functions known, %2 polyfilled for this executor. Home > sUNC to run tests.", "[sUNC] %1 funções conhecidas, %2 com polyfill neste executor. Início > sUNC para rodar os testes.", "[sUNC] %1 funciones conocidas, %2 con polyfill en este ejecutor. Inicio > sUNC para ejecutar pruebas.", "[sUNC] %1 fonctions connues, %2 avec polyfill pour cet exécuteur. Accueil > sUNC pour lancer les tests.", "[sUNC] %1 Funktionen bekannt, %2 mit Polyfill für diesen Executor. Start > sUNC für Tests.", "[sUNC] %1 fungsi dikenal, %2 dengan polyfill untuk executor ini. Beranda > sUNC untuk menjalankan tes."},
{"^(Hyundax IUM v[%d%.]+) ready%.$", "%1 ready.", "%1 pronto.", "%1 listo.", "%1 prêt.", "%1 bereit.", "%1 siap."},
}
local EXACT, UPPERIDX = {}, {}
for _, row in ipairs(DICT) do
local k = row.key or row[1]
EXACT[k] = row
if not k:find("[\128-\255]") then
local u = k:upper()
if u ~= k and not UPPERIDX[u] then UPPERIDX[u] = row end
end
end
local UPMAP = {
["á"] = "Á", ["à"] = "À", ["â"] = "Â", ["ã"] = "Ã", ["ä"] = "Ä", ["é"] = "É", ["è"] = "È", ["ê"] = "Ê", ["ë"] = "Ë",
["í"] = "Í", ["ì"] = "Ì", ["î"] = "Î", ["ï"] = "Ï", ["ó"] = "Ó", ["ò"] = "Ò", ["ô"] = "Ô", ["õ"] = "Õ", ["ö"] = "Ö",
["ú"] = "Ú", ["ù"] = "Ù", ["û"] = "Û", ["ü"] = "Ü", ["ç"] = "Ç", ["ñ"] = "Ñ",
}
local function upperU(s)
return (s:gsub(utf8.charpattern, function(ch) return UPMAP[ch] or ch:upper() end))
end
local function fillTpl(tpl, caps)
return (tpl:gsub("%%(%d)", function(d) return caps[tonumber(d)] or "" end))
end
function I18N.tr(s, lang)
if type(s) ~= "string" or s == "" or #s > 400 then return s end
local idx = COL[lang or I18N.lang]
if not idx then return s end
local lead, core, trail = s:match("^(%s*)(.-)(%s*)$")
if not core or core == "" then return s end
local row = EXACT[core]
if row then return lead .. (row[idx] or core) .. trail end
for _, p in ipairs(PATTERNS) do
local c1, c2, c3 = core:match(p[1])
if c1 ~= nil then return lead .. fillTpl(p[idx + 1] or p[2], {c1, c2, c3}) .. trail end
end
for _, p in ipairs(PREFIX) do
local pre = p[1]
if core:sub(1, #pre) == pre then
return lead .. (p[idx] or pre) .. I18N.tr(core:sub(#pre + 1), lang) .. trail
end
end
if core == core:upper() and core:find("%a") then
local r = UPPERIDX[core]
if r then return lead .. upperU(r[idx] or core) .. trail end
end
return s
end
function I18N.shownName()
return I18N.nick ~= "" and I18N.nick or lp.DisplayName
end
function I18N.save()
jsonWrite(PROFILE_FILE, {lang = I18N.lang, nick = I18N.nick, setupDone = I18N.profile.setupDone == true, user = I18N.user})
end
function I18N.setNick(n)
n = (tostring(n or ""):gsub("%c", " "):gsub("^%s+", ""):gsub("%s+$", ""))
pcall(function()
local len = utf8.len(n)
if len and len > 20 then n = n:sub(1, utf8.offset(n, 21) - 1) end
end)
I18N.nick = n
for _, f in ipairs(I18N.watchers) do pcall(f) end
I18N.save()
end
local function onI18NChange(o, prop)
local rec = I18N.tracked[o]
local p = rec and rec[prop]
if not p then return end
local cur = o[prop]
if cur == p.shown then return end
p.orig = cur
local t = I18N.tr(cur)
p.shown = t
if t ~= cur then o[prop] = t end
end
local function trackI18N(o)
local cn = o.ClassName
local isBox = (cn == "TextBox")
if not (cn == "TextLabel" or cn == "TextButton" or isBox) then return end
if I18N.tracked[o] or o:GetAttribute("NoI18N") then return end
local prop = isBox and "PlaceholderText" or "Text"
if not isBox then
local okM, isMono = pcall(function() return o.FontFace.Family == MONO.Family end)
if okM and isMono then
local t = I18N.tr(o.Text)
if t ~= o.Text then o.Text = t end
return
end
end
local cur = o[prop]
local t = I18N.tr(cur)
I18N.tracked[o] = {[prop] = {orig = cur, shown = t}}
if t ~= cur then o[prop] = t end
o:GetPropertyChangedSignal(prop):Connect(function() onI18NChange(o, prop) end)
end
function I18N.attach(g)
g.DescendantAdded:Connect(function(o) pcall(trackI18N, o) end)
for _, o in ipairs(g:GetDescendants()) do pcall(trackI18N, o) end
end
function I18N.set(code)
if not COL[code] then return end
I18N.lang = code
for o, rec in pairs(I18N.tracked) do
if o.Parent then
for prop, p in pairs(rec) do
local cur = o[prop]
if cur ~= p.shown then p.orig = cur end
local t = I18N.tr(p.orig)
p.shown = t
if cur ~= t then o[prop] = t end
end
end
end
for _, f in ipairs(I18N.binds) do pcall(f) end
end
function I18N.bind(o, key, fallback)
local function upd()
if not o.Parent then return end
local t = I18N.tr(key)
if t == key then t = I18N.tr(fallback or key) end
o.Text = t
end
I18N.binds[#I18N.binds + 1] = upd
upd()
end
function I18N.langName(code)
for _, l in ipairs(I18N.LANGS) do
if l.code == (code or I18N.lang) then return l.name end
end
return code
end
do
local prof = jsonRead(PROFILE_FILE, {})
I18N.profile = prof
local code = prof.lang
if not COL[code or ""] then
code = "en"
pcall(function()
local loc = tostring(game:GetService("LocalizationService").RobloxLocaleId or ""):lower()
local pre = loc:match("^(%a%a)")
if pre and COL[pre] then code = pre end
end)
end
I18N.lang = code
I18N.nick = type(prof.nick) == "string" and prof.nick or ""
I18N.user = (type(prof.user) == "string" and prof.user ~= "") and prof.user or nil
end
local ACCOUNTS_FILE = DB_FOLDER .. "/accounts.json"
local ACCOUNTS_BAK = DB_FOLDER .. "/accounts.bak.json"
local function ensureDB()
pcall(function() if makefolder and isfolder and not isfolder(DB_FOLDER) then makefolder(DB_FOLDER) end end)
end
ensureDB()
pcall(function()
local old = FOLDER .. "/accounts.json"
if isfile and readfile and writefile and not isfile(ACCOUNTS_FILE) and isfile(old) then
writefile(ACCOUNTS_FILE, readfile(old))
end
end)
local function dbRead()
ensureDB()
local a = jsonRead(ACCOUNTS_FILE, nil)
if not (a and type(a.users) == "table") then a = jsonRead(ACCOUNTS_BAK, nil) end
if not (a and type(a.users) == "table") then a = {users = {}} end
return a
end
local function dbWrite(a)
ensureDB()
a.version, a.updated = 1, os.time()
local ok = jsonWrite(ACCOUNTS_FILE, a)
if ok then jsonWrite(ACCOUNTS_BAK, a) end
return ok
end
FX.dbRead = dbRead
local goSetup
local SHA_K = {1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298}
local function sha256(msg)
local band, bxor, bnot, rr, rs = bit32.band, bit32.bxor, bit32.bnot, bit32.rrotate, bit32.rshift
local h = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}
local len = #msg
msg = msg .. "\128" .. string.rep("\0", (55 - len) % 64) .. string.pack(">I8", len * 8)
for chunk = 1, #msg, 64 do
local w = {}
for i = 0, 15 do w[i] = string.unpack(">I4", msg, chunk + i * 4) end
for i = 16, 63 do
local s0 = bxor(rr(w[i - 15], 7), rr(w[i - 15], 18), rs(w[i - 15], 3))
local s1 = bxor(rr(w[i - 2], 17), rr(w[i - 2], 19), rs(w[i - 2], 10))
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) % 4294967296
end
local a, b, c, d, e, f, g, hh = table.unpack(h)
for i = 0, 63 do
local S1 = bxor(rr(e, 6), rr(e, 11), rr(e, 25))
local ch = bxor(band(e, f), band(bnot(e), g))
local t1 = (hh + S1 + ch + SHA_K[i + 1] + w[i]) % 4294967296
local S0 = bxor(rr(a, 2), rr(a, 13), rr(a, 22))
local maj = bxor(band(a, b), band(a, c), band(b, c))
local t2 = (S0 + maj) % 4294967296
hh, g, f, e, d, c, b, a = g, f, e, (d + t1) % 4294967296, c, b, a, (t1 + t2) % 4294967296
end
local add = {a, b, c, d, e, f, g, hh}
for i = 1, 8 do h[i] = (h[i] + add[i]) % 4294967296 end
end
local out = {}
for i = 1, 8 do out[i] = string.format("%08x", h[i]) end
return table.concat(out)
end
local function hashPass(salt, pass)
local ok, r = pcall(sha256, salt .. "|" .. pass .. "|hyundaxx")
if ok then return r end
return salt .. pass
end
FX.hashPass = hashPass
do
local C = {url = "https://hyundax-default-rtdb.europe-west1.firebasedatabase.app", users = {}, assets = {}}
FX.cloud = C
function C.enabled() return type(C.url) == "string" and C.url:match("^https?://") ~= nil end
function C.cs(url)
local n = 0
for i = 1, #url do n = (n * 31 + url:byte(i)) % 4294967296 end
return string.format("%08x", n)
end
local function candidates()
local list, seen = {}, {}
local function add(tag, f)
if type(f) == "function" and not seen[f] then seen[f] = true list[#list + 1] = {tag = tag, f = f} end
end
local function sub(t, k) if type(t) == "table" then local ok, v = pcall(function() return t[k] end) if ok then return v end end end
local envs = {}
pcall(function() if getgenv then envs[#envs + 1] = getgenv() end end)
pcall(function() envs[#envs + 1] = _G end)
pcall(function() envs[#envs + 1] = shared end)
pcall(function() if getfenv then envs[#envs + 1] = getfenv(0) end end)
pcall(function() for _, n in ipairs({"request", "http_request", "http.request", "syn.request", "fluxus.request"}) do add("real:" .. n, Compat.realNative(n)) end end)
for _, e in ipairs(envs) do
pcall(function()
add("request", sub(e, "request")) add("http_request", sub(e, "http_request"))
add("http.request", sub(sub(e, "http"), "request")) add("syn.request", sub(sub(e, "syn"), "request"))
add("fluxus.request", sub(sub(e, "fluxus"), "request")) add("krnl.request", sub(sub(e, "krnl"), "request"))
end)
end
pcall(function() add("syn.request", syn and syn.request) end)
pcall(function() add("http.request", http and http.request) end)
pcall(function() add("http_request", http_request) end)
pcall(function() add("request", request) end)
return list
end
local function readRes(res)
if type(res) ~= "table" then return nil, "no table: " .. tostring(res) end
local code = tonumber(res.StatusCode or res.Status or res.status_code or res.statusCode)
local b = res.Body
if b == nil then b = res.body end
if code and code >= 300 then return nil, "HTTP " .. code .. " " .. tostring(b):sub(1, 50) end
if res.Success == false and not code then return nil, "failed " .. tostring(res.StatusMessage) end
if b == nil or b == "" or b == "null" then return true, nil end
local ok, d = pcall(function() return HttpService:JSONDecode(b) end)
if not ok then return nil, "bad json: " .. tostring(b):sub(1, 50) end
return true, d
end
function C.call(method, path, body)
if not C.enabled() then C.lastErr = "cloud disabled" return false, C.lastErr end
local url = (C.url:gsub("/+$", "")) .. "/" .. path .. ".json"
local payload
if body ~= nil then
local okE, enc = pcall(function() return HttpService:JSONEncode(body) end)
if not okE then C.lastErr = "encode failed" return false, C.lastErr end
payload = enc
end
local hdr = {["Accept"] = "application/json, text/plain, */*", ["User-Agent"] = "Mozilla/5.0"}
if method ~= "GET" then hdr["Content-Type"] = "application/json" end
local opts = {Url = url, Method = method, Headers = hdr, Body = payload, Timeout = 12}
local tries = {}
for _, c in ipairs(candidates()) do
local f = c.f
tries[#tries + 1] = {c.tag, function() return f(opts) end}
if method ~= "GET" then
tries[#tries + 1] = {c.tag .. "+override", function()
return f({Url = url .. "?x-http-method-override=" .. method, Method = "POST", Headers = {["Content-Type"] = "application/json", ["X-HTTP-Method-Override"] = method}, Body = payload})
end}
end
end
if method == "GET" then
tries[#tries + 1] = {"HttpGet", function() return {StatusCode = 200, Body = game:HttpGet(url)} end}
tries[#tries + 1] = {"HttpGet2", function() return {StatusCode = 200, Body = game:HttpGet(url, true)} end}
tries[#tries + 1] = {"HttpGetAsync", function() return {StatusCode = 200, Body = game:HttpGetAsync(url)} end}
else
tries[#tries + 1] = {"HttpPost", function()
return {StatusCode = 200, Body = game:HttpPost(url .. "?x-http-method-override=" .. method, payload or "", "application/json")}
end}
end
tries[#tries + 1] = {"RequestAsync", function() return HttpService:RequestAsync(opts) end}
if C.good then
for i, t in ipairs(tries) do
if t[1] == C.good then table.remove(tries, i) table.insert(tries, 1, t) break end
end
end
local errs = {}
for _, t in ipairs(tries) do
for attempt = 1, 2 do
local ok, res = pcall(t[2])
if ok then
local rok, data = readRes(res)
if rok then C.good, C.lastErr = t[1], nil return true, data end
errs[#errs + 1] = t[1] .. ": " .. tostring(data):sub(1, 40)
if tostring(data):match("^HTTP 4") then break end
else
errs[#errs + 1] = t[1] .. ": " .. tostring(res):sub(1, 40)
break
end
task.wait(.3)
end
end
C.lastErr = #tries .. " tries | " .. table.concat(errs, " | "):sub(1, 220)
return false, C.lastErr
end
function C.fetchUsers()
local ok, d = C.call("GET", "users")
if ok then C.users = type(d) == "table" and d or {} end
return ok
end
function C.nameBlocked(key)
local ok, r = C.call("GET", "users/" .. key)
if not ok then C.offline = true return false end
C.offline = false
if r then C.blockMsg = "That username is already taken" return true end
return false
end
function C.pushMine(name)
local key = tostring(name):lower()
local m = jsonRead(DB_FOLDER .. "/acc_meta.json", {})
local a = dbRead().users[key]
local body = {name = name, seen = os.time(), created = a and a.created or os.time()}
if m[key] and m[key].logo then body.logo = m[key].logo end
return C.call("PATCH", "users/" .. key, body)
end
function C.avatar(badge, letter, key, size)
local u = C.users[key]
local url = u and u.logo
if type(url) ~= "string" or not url:match("^https?://") then return end
task.spawn(function()
local ent = C.assets[key]
local a
if ent and ent.url == url then a = ent.asset else
a = toAsset(PATH.img .. "/rl_" .. key .. "_" .. C.cs(url) .. ".dat", function() return game:HttpGet(url) end)
if a then C.assets[key] = {url = url, asset = a} end
end
if not a or not badge.Parent then return end
if letter then letter.Visible = false end
new("ImageLabel", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Image = a, ScaleType = Enum.ScaleType.Crop, Parent = badge}, {round(size / 2)})
end)
end
end
function FX.tetris(host, w, h, radius, opts)
opts = opts or {}
local RS = game:GetService("RunService")
local COLORS = {Color3.fromRGB(235, 52, 62), Color3.fromRGB(58, 132, 245), Color3.fromRGB(255, 205, 48)}
local BASE = {
{{0, 0}, {1, 0}, {2, 0}, {3, 0}},
{{0, 0}, {1, 0}, {0, 1}, {1, 1}},
{{0, 0}, {1, 0}, {2, 0}, {1, 1}},
{{1, 0}, {2, 0}, {0, 1}, {1, 1}},
{{0, 0}, {1, 0}, {1, 1}, {2, 1}},
{{0, 0}, {0, 1}, {1, 1}, {2, 1}},
{{2, 0}, {0, 1}, {1, 1}, {2, 1}},
}
local SHAPES = {}
for _, base in ipairs(BASE) do
local rots, seen, cur = {}, {}, base
for _ = 1, 4 do
local mx, my = math.huge, math.huge
for _, c in ipairs(cur) do
mx = math.min(mx, c[1])
my = math.min(my, c[2])
end
local norm, pw, ph = {}, 0, 0
for i, c in ipairs(cur) do
norm[i] = {c[1] - mx, c[2] - my}
pw = math.max(pw, norm[i][1] + 1)
ph = math.max(ph, norm[i][2] + 1)
end
table.sort(norm, function(a, b)
if a[2] ~= b[2] then return a[2] < b[2] end
return a[1] < b[1]
end)
local parts = {}
for i, c in ipairs(norm) do parts[i] = c[1] .. "," .. c[2] end
local key = table.concat(parts, ";")
if not seen[key] then
seen[key] = true
rots[#rots + 1] = {cells = norm, w = pw, h = ph}
end
local nxt = {}
for i, c in ipairs(cur) do nxt[i] = {-c[2], c[1]} end
cur = nxt
end
SHAPES[#SHAPES + 1] = rots
end
local alpha = opts.alpha or .08
local strokeA = opts.strokeAlpha or .45
local speedMin, speedMax = opts.speedMin or 9, opts.speedMax or 13
local gapT = opts.gap or .3
local fillF = opts.fill or .64
local useTp = opts.tp ~= false
local G = opts.cellGap or 2
local auto = (w == nil or h == nil)
local zi = opts.z or 0
local function mkCorner()
if radius == "full" then return new("UICorner", {CornerRadius = UDim.new(.5, 0)}) end
return round(radius or 14)
end
local root = new("Frame", {
Name = "TetrisBG", Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, BorderSizePixel = 0,
ClipsDescendants = true, ZIndex = zi, Parent = host,
}, {mkCorner()})
root:SetAttribute("NoTheme", true)
if opts.shade ~= false then
local shade = new("Frame", {
Name = "TetrisShade", Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.fromRGB(6, 6, 10),
BackgroundTransparency = opts.shade or .45, BorderSizePixel = 0, ZIndex = zi, Parent = host,
}, {mkCorner()})
shade:SetAttribute("NoTheme", true)
end
local cols, rows = 8, 8
local occ, rowN, top = {}, {}, {}
local flying, landed = {}, {}
local busy, speed, gen = false, 11, 0
local basisW, basisH = 0, 0
local function resetBoard()
occ, rowN, top = {}, {}, {}
for y = 1, rows do
occ[y] = {}
rowN[y] = 0
end
for x = 1, cols do top[x] = rows + 1 end
end
local function fits(cells, x, y)
for _, c in ipairs(cells) do
local cx, cy = x + c[1], y + c[2]
if cx < 1 or cx > cols or cy > rows then return false end
if cy >= 1 and occ[cy][cx] then return false end
end
return true
end
local function choose(shape)
local best, bestScore
local hts = {}
for x = 1, cols do hts[x] = rows + 1 - top[x] end
for ri, rot in ipairs(shape) do
for x = 1, cols - rot.w + 1 do
local y = 1 - rot.h
if fits(rot.cells, x, y) then
while fits(rot.cells, x, y + 1) do y = y + 1 end
if y >= 1 then
local nh = {}
for i = 1, cols do nh[i] = hts[i] end
local holes, lines = 0, 0
local lowest, touched = {}, {}
for _, c in ipairs(rot.cells) do
local cx, cy = x + c[1], y + c[2]
local hh = rows + 1 - cy
if hh > nh[cx] then nh[cx] = hh end
if not lowest[cx] or cy > lowest[cx] then lowest[cx] = cy end
touched[cy] = (touched[cy] or 0) + 1
end
for cx, by in pairs(lowest) do
local gap = top[cx] - 1 - by
if gap > 0 then holes = holes + gap end
end
for cy, k in pairs(touched) do
if rowN[cy] + k == cols then lines = lines + 1 end
end
local agg, bump = 0, 0
for i = 1, cols do
agg = agg + nh[i]
if i < cols then bump = bump + math.abs(nh[i] - nh[i + 1]) end
end
local score = -0.51 * agg + 0.9 * lines - 0.7 * holes - 0.2 * bump + math.random() * 0.9
if not bestScore or score > bestScore then
bestScore = score
best = {rot = rot, ri = ri, x = x, y = y}
end
end
end
end
end
return best
end
local function reserve(pick)
for _, c in ipairs(pick.rot.cells) do
local cx, cy = pick.x + c[1], pick.y + c[2]
occ[cy][cx] = true
rowN[cy] = rowN[cy] + 1
if cy < top[cx] then top[cx] = cy end
end
end
local function layoutPiece(p, rot, x)
p.curX, p.curW, p.curH = x, rot.w, rot.h
p.frame.Size = UDim2.fromScale(rot.w / cols, rot.h / rows)
for i, c in ipairs(rot.cells) do
local cell = p.cells[i].f
cell.Position = UDim2.new(c[1] / rot.w, G * .5, c[2] / rot.h, G * .5)
cell.Size = UDim2.new(1 / rot.w, -G, 1 / rot.h, -G)
end
end
local function place(p)
p.frame.Position = UDim2.fromScale((p.curX - 1) / cols, (p.y - 1) / rows)
end
local function flash(p, k)
for _, c in ipairs(p.cells) do
c.f.BackgroundColor3 = c.base:Lerp(Color3.new(1, 1, 1), k)
TweenService:Create(c.f, TweenInfo.new(.28), {BackgroundColor3 = c.base}):Play()
end
end
local function teleport(p)
p.step = p.step + 1
local rot = p.shape[(p.startIdx + p.step - 1) % #p.shape + 1]
layoutPiece(p, rot, p.xFor(rot))
flash(p, .75)
end
local function toFinal(p)
if p.step >= p.nsteps then return end
p.step = p.nsteps
layoutPiece(p, p.finalRot, p.finalX)
flash(p, .75)
end
local function canShow(p, rot, x)
local y = p.y
for c = x, x + rot.w - 1 do
if y + rot.h > top[c] then return false end
end
for _, q in ipairs(flying) do
if q ~= p and x < q.curX + q.curW and q.curX < x + rot.w and y < q.y + q.curH and q.y < y + rot.h then
return false
end
end
return true
end
local function spawn()
local shape = SHAPES[math.random(#SHAPES)]
local pick = choose(shape)
if not pick then return false end
reserve(pick)
local col = COLORS[math.random(#COLORS)]
local nrot = #shape
local startIdx = pick.ri
if useTp and nrot > 1 and math.random() < .8 then startIdx = math.random(nrot) end
local nsteps = (pick.ri - startIdx) % nrot
local fracs = {}
for i = 1, nsteps do fracs[i] = .1 + math.random() * .5 end
table.sort(fracs)
local function xFor(rot)
return math.clamp(pick.x + math.floor((pick.rot.w - rot.w) / 2), 1, cols - rot.w + 1)
end
local startRot = shape[startIdx]
local f = new("Frame", {BackgroundTransparency = 1, BorderSizePixel = 0, Parent = root})
f:SetAttribute("NoTheme", true)
local cells = {}
for i = 1, 4 do
local st = new("UIStroke", {
Color = col:Lerp(Color3.new(1, 1, 1), .55), Thickness = 1, Transparency = strokeA,
ApplyStrokeMode = Enum.ApplyStrokeMode.Border,
})
st:SetAttribute("NoTheme", true)
local cell = new("Frame", {
BackgroundColor3 = col, BackgroundTransparency = alpha, BorderSizePixel = 0, Parent = f,
}, {round(math.max(1, math.floor(G + 1))), st})
cell:SetAttribute("NoTheme", true)
cells[i] = {f = cell, st = st, y = pick.y, base = col}
end
local p = {
frame = f, cells = cells, shape = shape, startIdx = startIdx, step = 0, nsteps = nsteps, fracs = fracs,
xFor = xFor, finalRot = pick.rot, finalX = pick.x, ty = pick.y, y = 1 - startRot.h,
}
p.y0 = p.y
p.D = math.max(pick.y - p.y, .001)
layoutPiece(p, startRot, xFor(startRot))
place(p)
flying[#flying + 1] = p
return true
end
local function clearAll()
gen = gen + 1
for _, p in ipairs(flying) do p.frame:Destroy() end
for _, p in ipairs(landed) do p.frame:Destroy() end
flying, landed = {}, {}
busy = false
end
local function restart()
clearAll()
local wp, hp = w, h
if auto then
local a = root.AbsoluteSize
wp, hp = a.X, a.Y
end
if not wp or not hp or wp < 8 or hp < 8 then wp, hp = 400, 300 end
basisW, basisH = wp, hp
local C = opts.cell or math.clamp(math.floor(math.min(wp, hp) / 17), 16, 30)
cols = math.max(4, math.floor(wp / C + .5))
rows = math.max(4, math.floor(hp / C + .5))
resetBoard()
speed = speedMin + math.random() * (speedMax - speedMin)
end
restart()
if auto then
local pending = 0
root:GetPropertyChangedSignal("AbsoluteSize"):Connect(function()
pending = pending + 1
local mine = pending
task.delay(.35, function()
if mine ~= pending or not root.Parent then return end
local a = root.AbsoluteSize
if a.X < 8 or a.Y < 8 then return end
if math.abs(a.X - basisW) / basisW > .15 or math.abs(a.Y - basisH) / basisH > .15 then restart() end
end)
end)
end
local function wipe()
busy = true
local myGen = gen
task.spawn(function()
while #flying > 0 and root.Parent and myGen == gen do task.wait(.1) end
if not root.Parent or myGen ~= gen then return end
task.wait(.6)
if myGen ~= gen then return end
local maxD = 0
for _, p in ipairs(landed) do
for _, c in ipairs(p.cells) do
local d = (rows - c.y) * .035 + math.random() * .15
if d > maxD then maxD = d end
task.delay(d, function()
if not c.f.Parent then return end
TweenService:Create(c.f, TweenInfo.new(.18), {BackgroundColor3 = Color3.new(1, 1, 1)}):Play()
task.wait(.18)
if not c.f.Parent then return end
TweenService:Create(c.f, TweenInfo.new(.35), {BackgroundTransparency = 1}):Play()
TweenService:Create(c.st, TweenInfo.new(.35), {Transparency = 1}):Play()
end)
end
end
task.wait(maxD + .9)
if not root.Parent or myGen ~= gen then return end
for _, p in ipairs(landed) do p.frame:Destroy() end
landed = {}
resetBoard()
speed = speedMin + math.random() * (speedMax - speedMin)
busy = false
end)
end
local function shown()
local o = root
while o do
if o:IsA("GuiObject") then
if not o.Visible then return false end
elseif o:IsA("ScreenGui") then
if not o.Enabled then return false end
end
o = o.Parent
end
return true
end
local acc, chk, vis = gapT, 1, true
local conn
conn = RS.Heartbeat:Connect(function(dt)
if not root.Parent then
conn:Disconnect()
return
end
chk = chk + dt
if chk > .25 then
chk = 0
vis = shown()
end
if not vis then return end
dt = math.min(dt, .1)
for i = #flying, 1, -1 do
local p = flying[i]
p.y = p.y + speed * dt
if p.step < p.nsteps then
if p.y >= p.ty - (p.finalRot.h + 2) then
toFinal(p)
else
local fr = p.fracs[p.step + 1]
if fr and (p.y - p.y0) / p.D >= fr then
local nrot = p.shape[(p.startIdx + p.step) % #p.shape + 1]
if canShow(p, nrot, p.xFor(nrot)) then teleport(p) end
end
end
end
if p.y >= p.ty then
p.y = p.ty
toFinal(p)
table.remove(flying, i)
landed[#landed + 1] = p
for ci, c in ipairs(p.cells) do
c.y = p.ty + p.finalRot.cells[ci][2]
end
flash(p, .6)
end
place(p)
end
if busy then return end
acc = acc + dt
if acc < gapT then return end
for _, p in ipairs(flying) do
if p.y < 1.2 then return end
end
acc = 0
local minTop = rows + 1
for x = 1, cols do
if top[x] < minTop then minTop = top[x] end
end
if minTop <= math.floor(rows * (1 - fillF)) or not spawn() then wipe() end
end)
return root
end
function FX.backdrop(host, radius)
do
local g1 = new("Frame", {Name = "BgGlow", Size = UDim2.new(1, 0, 0, 260), BackgroundColor3 = (T.ACTIVE_THEME == "Darkness") and Color3.new(0, 0, 0) or T.bronze, BackgroundTransparency = .86, BorderSizePixel = 0, ZIndex = 0, Parent = host}, {round(radius)})
new("UIGradient", {Rotation = 90, Transparency = NumberSequence.new(0, 1), Parent = g1})
local g2 = new("Frame", {Name = "BgGlow2", AnchorPoint = Vector2.new(1, 1), Position = UDim2.fromScale(1, 1), Size = UDim2.new(.65, 0, 0, 220), BackgroundColor3 = (T.ACTIVE_THEME == "Darkness") and Color3.new(0, 0, 0) or T.bronzeLo, BackgroundTransparency = .9, BorderSizePixel = 0, ZIndex = 0, Parent = host}, {round(radius)})
new("UIGradient", {Rotation = 270, Transparency = NumberSequence.new(0, 1), Parent = g2})
local RS = game:GetService("RunService")
local gc
gc = RS.Heartbeat:Connect(function()
if not g1.Parent then gc:Disconnect() return end
local t = os.clock()
g1.BackgroundTransparency = .85 + .035 * math.sin(t * 1.1)
g2.BackgroundTransparency = .9 + .03 * math.sin(t * .8 + 1.7)
end)
end
do
local waves = new("Frame", {
Name = "BackgroundWaves", Size = UDim2.fromScale(1, 1),
BackgroundTransparency = 1, BorderSizePixel = 0, ClipsDescendants = true,
ZIndex = 0, Parent = host,
})
local waveColor = (T.ACTIVE_THEME == "Darkness") and Color3.new(0, 0, 0) or T.bronzeLo
local function makeWave(x0, y0, width, amp, period, thickness, transparency, phase)
local steps = math.max(24, math.floor(width / 13))
local px, py
for i = 0, steps do
local x = x0 + width * i / steps
local y = y0 + math.sin((i / steps * width / period) * math.pi * 2 + phase) * amp
if px then
local dx, dy = x - px, y - py
local len = math.sqrt(dx * dx + dy * dy)
local seg = new("Frame", {
Name = "WaveSegment", AnchorPoint = Vector2.new(0, .5),
Position = UDim2.new(px, 0, py, 0), Size = UDim2.fromOffset(len + 1, thickness),
Rotation = math.deg(math.atan2(dy, dx)), BackgroundColor3 = waveColor,
BackgroundTransparency = transparency, BorderSizePixel = 0, ZIndex = 0, Parent = waves,
})
end
px, py = x, y
end
end
makeWave(.02, .17, .34, .012, .19, 1, 0, .4)
makeWave(.64, .25, .34, .009, .22, 1, 0, 2.1)
makeWave(.04, .72, .29, .010, .17, 1, 0, 1.2)
makeWave(.68, .82, .28, .013, .20, 1, 0, 2.8)
makeWave(.36, .93, .25, .006, .16, 1, 0, .7)
makeWave(.30, .30, .26, .007, .15, 1, 0, 2.5)
makeWave(.30, .40, .30, .010, .18, 1, 0, 1.6)
makeWave(.36, .52, .34, .012, .21, 1, 0, 3.3)
makeWave(.28, .63, .30, .009, .17, 1, 0, .2)
makeWave(.34, .74, .28, .008, .16, 1, 0, 4.1)
local RunService = game:GetService("RunService")
local dotColor = (T.ACTIVE_THEME == "Darkness") and Color3.new(0, 0, 0) or T.bronzeHi
local dots = {}
local function addDots(x0, y0, width, amp, period, phase, count, speed)
for i = 1, count do
local f = new("Frame", {
Name = "WaveDot", AnchorPoint = Vector2.new(.5, .5), Size = UDim2.fromOffset(5, 5),
BackgroundColor3 = dotColor, BorderSizePixel = 0, ZIndex = 0, Parent = waves,
}, {round(4)})
dots[#dots + 1] = {
f = f, x0 = x0, y0 = y0, width = width, amp = amp, period = period, phase = phase,
offset = (i - 1) / count, speed = speed,
}
end
end
addDots(.02, .17, .34, .012, .19, .4, 8, .045)
addDots(.64, .25, .34, .009, .22, 2.1, 8, .040)
addDots(.04, .72, .29, .010, .17, 1.2, 7, .050)
addDots(.68, .82, .28, .013, .20, 2.8, 7, .042)
addDots(.36, .93, .25, .006, .16, .7, 6, .038)
addDots(.30, .30, .26, .007, .15, 2.5, 6, .036)
addDots(.30, .40, .30, .010, .18, 1.6, 7, .044)
addDots(.36, .52, .34, .012, .21, 3.3, 8, .040)
addDots(.28, .63, .30, .009, .17, .2, 7, .048)
addDots(.34, .74, .28, .008, .16, 4.1, 6, .039)
local conn
conn = RunService.Heartbeat:Connect(function()
if not waves.Parent then conn:Disconnect() return end
local t = os.clock()
for _, d in ipairs(dots) do
local u = (d.offset + t * d.speed) % 1
local x = d.x0 + d.width * u
local y = d.y0 + math.sin((u * d.width / d.period) * math.pi * 2 + d.phase) * d.amp
local pulse = .5 + .5 * math.sin(t * 3 + d.offset * 6.283)
local edge = math.clamp(math.min(u, 1 - u) * 8, 0, 1)
local s = 4 + pulse * 3
d.f.Position = UDim2.fromScale(x, y)
d.f.Size = UDim2.fromOffset(s, s)
d.f.BackgroundTransparency = 1 - edge * (.6 + .4 * pulse)
end
end)
end
end
local function startupFX(card, title)
local RS = game:GetService("RunService")
local kp = NumberSequenceKeypoint.new
local sw = new("Frame", {
Name = "StartupSweep", AnchorPoint = Vector2.new(.5, .5), Rotation = 18, Size = UDim2.new(0, 110, 1.9, 0),
Position = UDim2.fromScale(-.25, .5), BackgroundColor3 = Color3.new(1, 1, 1), BackgroundTransparency = .5,
BorderSizePixel = 0, ZIndex = 30, Parent = card,
})
new("UIGradient", {Transparency = NumberSequence.new({kp(0, 1), kp(.5, 0), kp(1, 1)}), Parent = sw})
tween(sw, {Position = UDim2.fromScale(1.25, .5)}, 1.3, Enum.EasingStyle.Quad)
task.delay(1.5, function() sw:Destroy() end)
if title then
local pos = title.Position
local ts = title.TextTransparency
title.TextTransparency = 1
title.Position = pos - UDim2.fromOffset(0, 26)
task.delay(.25, function()
if not title.Parent then return end
tween(title, {TextTransparency = ts, Position = pos}, .7, Enum.EasingStyle.Back)
end)
end
local em = {}
for i = 1, 28 do
local sz = math.random(2, 4)
local d = new("Frame", {
Name = "Ember", AnchorPoint = Vector2.new(.5, .5), Size = UDim2.fromOffset(sz, sz), BackgroundColor3 = T.bronzeHi,
BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = 0, Parent = card,
}, {new("UICorner", {CornerRadius = UDim.new(1, 0)})})
em[i] = {f = d, x = math.random(), sp = .04 + math.random() * .08, ph = math.random() * 6.28, off = math.random(), amp = .01 + math.random() * .03}
end
local conn
conn = RS.Heartbeat:Connect(function()
if not card.Parent then conn:Disconnect() return end
local t = os.clock()
for _, e in ipairs(em) do
local u = (e.off + t * e.sp) % 1
e.f.Position = UDim2.fromScale(e.x + math.sin(t * 1.3 + e.ph) * e.amp, 1.03 - u * 1.08)
e.f.BackgroundTransparency = 1 - math.sin(u * math.pi) * .8
end
end)
end
local function runSetup(needAuth, needSetup)
local prevMute = FX.sfx.mute
FX.sfx.mute = 0
local sg = new("ScreenGui", {
Name = NAME .. "Setup", ResetOnSpawn = false, IgnoreGuiInset = true,
ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 1000, Parent = parentGui,
})
I18N.attach(sg)
local vp = workspace.CurrentCamera.ViewportSize
local W = math.clamp(vp.X * .82, 460, 1280)
local H = math.clamp(vp.Y * .88, 320, 820)
local fit = math.clamp(math.min(vp.X / (W + 16), vp.Y / (H + 16)), .55, 1)
local colW = math.min(W - 32, 440)
local dim = new("TextButton", {
Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = .25,
AutoButtonColor = false, Text = "", BorderSizePixel = 0, Parent = sg,
})
local card = new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromOffset(W, H),
BackgroundColor3 = T.bg, BorderSizePixel = 0, ClipsDescendants = true, Parent = dim,
}, {round(14)})
do
local cs = stroke(Color3.new(1, 1, 1), 1.4)
cs.Parent = card
new("UIGradient", {Rotation = 40, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.45, T.tan), ColorSequenceKeypoint.new(1, T.bronzeLo)}), Parent = cs})
end
local cardScale = new("UIScale", {Scale = .88 * fit, Parent = card})
tween(cardScale, {Scale = fit}, .55, Enum.EasingStyle.Back)
FX.backdrop(card, 14)
local HERO = W >= 760
local PANE_TOP = HERO and 76 or 100
local col
if HERO then
col = new("Frame", {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -20, .5, 0), Size = UDim2.new(0, colW, 1, -40),
BackgroundColor3 = T.bg, BackgroundTransparency = .2, BorderSizePixel = 0, ClipsDescendants = true, Parent = card,
}, {round(14), stroke(T.line, 1)})
else
col = new("Frame", {
AnchorPoint = Vector2.new(.5, 0), Position = UDim2.fromScale(.5, 0), Size = UDim2.new(0, colW, 1, 0),
BackgroundTransparency = 1, Parent = card,
})
end
local head = new("Frame", {Size = UDim2.new(1, -32, 0, PANE_TOP - 12), Position = UDim2.fromOffset(16, 8), BackgroundTransparency = 1, Parent = col})
local bigTitle, subtitle
if HERO then
local heroW = W - colW - 40
local hero = new("Frame", {Name = "Hero", Size = UDim2.new(0, heroW, 1, 0), BackgroundTransparency = 1, Parent = card})
for _, orb in ipairs({{-60, -60, 220, .9}, {heroW - 140, H - 150, 260, .93}}) do
new("Frame", {
Position = UDim2.fromOffset(orb[1], orb[2]), Size = UDim2.fromOffset(orb[3], orb[3]), BackgroundColor3 = T.bronze,
BackgroundTransparency = orb[4], BorderSizePixel = 0, Parent = hero,
}, {round(math.floor(orb[3] / 2))})
end
local stack = new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.new(1, -48, 0, H >= 440 and 388 or 298),
BackgroundTransparency = 1, Parent = hero,
})
logoImage({AnchorPoint = Vector2.new(.5, 0), Size = UDim2.fromOffset(80, 80), Position = UDim2.new(.5, 0, 0, 0), ZIndex = 2, Parent = stack})
bigTitle = text(stack, "HYUNDAX IUM", 52, "Bold", Color3.new(1, 1, 1), {Position = UDim2.fromOffset(0, 88), Size = UDim2.new(1, 0, 0, 80), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true})
new("UIGradient", {Rotation = 90, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.5, T.gold), ColorSequenceKeypoint.new(1, T.tan)}), Parent = bigTitle})
new("Frame", {AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 180), Size = UDim2.fromOffset(140, 2), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = stack}, {
new("UIGradient", {Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeLo), ColorSequenceKeypoint.new(.5, T.bronzeHi), ColorSequenceKeypoint.new(1, T.bronzeLo)}), Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(.5, 0), NumberSequenceKeypoint.new(1, 1)})}),
})
if H >= 440 then
local chips = new("Frame", {AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 200), Size = UDim2.new(0, math.min(heroW - 48, 290), 0, 3 * 52 + 12), BackgroundTransparency = 1, Parent = stack}, {vlist(6)})
for i, d in ipairs({{"shieldcheck", "Secure", "Salted password hashing"}, {"lock", "Private", "Accounts stay on this device"}, {"rocket", "Fast", "Cached assets, quick startup"}}) do
FX.card(chips, {order = i, height = 52, icon = d[1], iconColor = T.tan, title = d[2], sub = d[3]})
end
else
local chips = new("Frame", {AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 204), Size = UDim2.fromOffset(150, 3 * 26 + 12), BackgroundTransparency = 1, Parent = stack}, {vlist(6)})
for i, d in ipairs({{"shieldcheck", "Secure"}, {"lock", "Private"}, {"rocket", "Fast"}}) do
local r = new("Frame", {Size = UDim2.new(1, 0, 0, 26), BackgroundTransparency = 1, LayoutOrder = i, Parent = chips})
local ci = icon(r, d[1], 15, T.tan, 1.5)
ci.holder.AnchorPoint = Vector2.new(0, .5)
ci.holder.Position = UDim2.new(0, 0, .5, 0)
text(r, d[2], 13, "SemiBold", T.text, {Position = UDim2.fromOffset(26, 0), Size = UDim2.new(1, -26, 1, 0)})
end
end
subtitle = text(head, "Sign in to continue", 17, "Bold", T.text, {Position = UDim2.fromOffset(4, 18), Size = UDim2.new(1, -8, 0, 24)})
else
bigTitle = text(head, "HYUNDAX IUM", 34, "Bold", Color3.new(1, 1, 1), {Position = UDim2.fromOffset(0, 0), Size = UDim2.new(1, 0, 0, 52), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true})
new("UIGradient", {Rotation = 90, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.5, T.gold), ColorSequenceKeypoint.new(1, T.tan)}), Parent = bigTitle})
subtitle = text(head, "Sign in to continue", 11, "Regular", T.muted, {Position = UDim2.fromOffset(0, 58), Size = UDim2.new(1, 0, 0, 16), TextXAlignment = Enum.TextXAlignment.Center})
end
startupFX(card, bigTitle)
task.defer(function() pcall(FX.cascade, col, .7) end)
new("Frame", {Size = UDim2.new(1, -32, 0, 1), Position = UDim2.fromOffset(16, PANE_TOP - 8), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = col}, {
new("UIGradient", {Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.line), ColorSequenceKeypoint.new(.5, T.bronze), ColorSequenceKeypoint.new(1, T.line)})}),
})
local function paneOf(reserve)
return scroller(col, {Position = UDim2.fromOffset(0, PANE_TOP), Size = UDim2.new(1, 0, 1, -(PANE_TOP + reserve)), Visible = false}, {pad(16, 4, 16, 4), vlist(10)})
end
local function label(parent, order, ic, str)
local f = new("Frame", {Size = UDim2.new(1, 0, 0, 16), BackgroundTransparency = 1, LayoutOrder = order, Parent = parent})
local i = icon(f, ic, 12, T.tan, 1.4)
i.holder.Position = UDim2.fromOffset(0, 2)
text(f, str, 11, "SemiBold", T.text, {Position = UDim2.fromOffset(18, 0), Size = UDim2.new(1, -18, 1, 0)})
return f
end
local function field(parent, order, placeholder, init, ico)
local b = new("TextBox", {
Size = UDim2.new(1, 0, 0, 38), BackgroundColor3 = T.panel, BorderSizePixel = 0, Text = init or "",
PlaceholderText = placeholder, PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 12,
FontFace = F.Medium, TextXAlignment = Enum.TextXAlignment.Left, ClearTextOnFocus = false, LayoutOrder = order, Parent = parent,
}, {round(10), stroke(T.line), pad(ico and 38 or 12, 0, 12, 0)})
local e = b:FindFirstChildOfClass("UIStroke")
if ico then
local fi = icon(b, ico, 15, T.muted, 1.5)
fi.holder.AnchorPoint = Vector2.new(0, .5)
fi.holder.Position = UDim2.new(0, -26, .5, 0)
b.Focused:Connect(function() fi.set(T.bronze, .25) end)
b.FocusLost:Connect(function() fi.set(T.muted, .3) end)
end
b.Focused:Connect(function() tween(e, {Color = T.tan}, .25) tween(b, {BackgroundColor3 = T.panel2}, .2) end)
b.FocusLost:Connect(function() tween(e, {Color = T.line}, .3) tween(b, {BackgroundColor3 = T.panel}, .25) end)
return b
end
local BUL = "•"
local function secret(parent, order, placeholder, ico)
local b = field(parent, order, placeholder, nil, ico)
local st = {v = {}, busy = false, box = b}
b:GetPropertyChangedSignal("Text"):Connect(function()
if st.busy then return end
local old, nv, k, fresh = st.v, {}, 1, 0
for _, c in utf8.codes(b.Text) do
local ch = utf8.char(c)
if ch == BUL then
nv[#nv + 1] = old[k] or ""
k += 1
else
nv[#nv + 1] = ch
fresh += 1
end
end
if fresh == 0 and #nv < #old then
local d = #old - #nv
local pos = math.clamp(b.CursorPosition - 1, 0, #old - d)
nv = {}
for i = 1, #old do
if i <= pos or i > pos + d then nv[#nv + 1] = old[i] end
end
end
st.v = nv
st.busy = true
b.Text = string.rep(BUL, #nv)
b.CursorPosition = math.min(b.CursorPosition, #b.Text + 1)
st.busy = false
end)
function st.get() return table.concat(st.v) end
return st
end
local authPane = paneOf(8)
local setupPane = paneOf(64)
local done = false
local mode = "login"
local tabs = new("Frame", {Size = UDim2.new(1, 0, 0, 40), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 3, Parent = authPane}, {round(10), stroke(T.line), pad(3), hlist(2)})
local tabBtn, tabIc = {}, {}
local function paintTabs()
for k, b in pairs(tabBtn) do
tween(b, {BackgroundColor3 = (k == mode) and T.bronze or T.panel}, .3)
b.TextColor3 = (k == mode) and T.dark or T.text
if tabIc[k] then tabIc[k].set((k == mode) and T.dark or T.muted, .25) end
end
end
for i, d in ipairs({{"login", "Login"}, {"register", "Register"}}) do
local b = new("TextButton", {
Size = UDim2.new(.5, -1, 1, 0), BackgroundColor3 = T.panel, AutoButtonColor = false, Text = d[2],
TextSize = 12, FontFace = F.Bold, TextColor3 = T.text, LayoutOrder = i, Parent = tabs,
}, {round(8)})
pressFx(b, .95)
local ti = icon(b, i == 1 and "login" or "plus", 14, T.muted, 1.6)
ti.holder.AnchorPoint = Vector2.new(0, .5)
ti.holder.Position = UDim2.new(0, 14, .5, 0)
tabIc[d[1]] = ti
tabBtn[d[1]] = b
end
label(authPane, 4, "user", "Username")
local uBox = field(authPane, 5, "Username", "", "user")
label(authPane, 6, "lock", "Password")
local pSec = secret(authPane, 7, "Password", "lock")
local cLabel = label(authPane, 8, "shieldcheck", "Confirm password")
cLabel.Visible = false
local cSec = secret(authPane, 9, "Confirm password", "shieldcheck")
cSec.box.Visible = false
local keep = true
local keepRow = new("TextButton", {
Size = UDim2.new(1, 0, 0, 24), BackgroundTransparency = 1, Text = "", AutoButtonColor = false, LayoutOrder = 10, Parent = authPane,
})
local chk = new("Frame", {Size = UDim2.fromOffset(18, 18), Position = UDim2.fromOffset(0, 3), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = keepRow}, {round(5), stroke(T.bronzeHi)})
local chkIc = icon(chk, "check", 12, T.dark, 2)
chkIc.holder.AnchorPoint, chkIc.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
text(keepRow, "Stay signed in", 11, "SemiBold", T.text, {Position = UDim2.fromOffset(26, 0), Size = UDim2.new(1, -26, 1, 0)})
keepRow.Activated:Connect(function()
keep = not keep
FX.snd(keep and "on" or "off")
tween(chk, {BackgroundColor3 = keep and T.bronze or T.panel2}, .25)
chkIc.holder.Visible = keep
end)
local err = text(authPane, "", 11, "SemiBold", Color3.fromRGB(226, 92, 82), {
Size = UDim2.new(1, 0, 0, 16), TextWrapped = true, LayoutOrder = 11, TextXAlignment = Enum.TextXAlignment.Center,
})
local go = new("TextButton", {
Size = UDim2.new(1, 0, 0, 40), BackgroundColor3 = T.bronze, AutoButtonColor = false, Text = "Sign in",
TextSize = 14, FontFace = F.Bold, TextColor3 = T.dark, LayoutOrder = 12, Parent = authPane,
}, {round(6), stroke(T.bronzeHi)})
pressFx(go, .96)
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(200, 150, 150)), Parent = go})
local goIc = icon(go, "arrowR", 16, T.dark, 2)
goIc.holder.AnchorPoint = Vector2.new(1, .5)
goIc.holder.Position = UDim2.new(1, -16, .5, 0)
text(authPane, "Accounts are saved only on this device", 10, "Regular", T.muted, {
Size = UDim2.new(1, 0, 0, 14), LayoutOrder = 13, TextXAlignment = Enum.TextXAlignment.Center,
})
if not HERO then
local frow = new("Frame", {Size = UDim2.new(1, 0, 0, 30), BackgroundTransparency = 1, LayoutOrder = 14, Parent = authPane}, {hlist(6, nil, Enum.HorizontalAlignment.Center)})
for i, d in ipairs({{"shieldcheck", "Secure"}, {"lock", "Private"}, {"rocket", "Fast"}}) do
local c = new("Frame", {Size = UDim2.new(1 / 3, -4, 1, 0), BackgroundColor3 = T.glow, BorderSizePixel = 0, LayoutOrder = i, Parent = frow}, {round(9), stroke(T.bronzeLo, 1)})
local fic = icon(c, d[1], 13, T.tan, 1.5)
fic.holder.AnchorPoint = Vector2.new(0, .5)
fic.holder.Position = UDim2.new(0, 10, .5, 0)
text(c, d[2], 10, "SemiBold", T.muted, {Position = UDim2.fromOffset(30, 0), Size = UDim2.new(1, -34, 1, 0)})
end
end
local function setMode(m)
mode = m
paintTabs()
cLabel.Visible = (m == "register")
cSec.box.Visible = (m == "register")
go.Text = (m == "register") and "Create account" or "Sign in"
subtitle.Text = (m == "register") and "Create your account" or "Sign in to continue"
err.Text = ""
end
for k, b in pairs(tabBtn) do b.Activated:Connect(function() setMode(k) end) end
local function fail(msg)
FX.snd("err")
err.Text = msg
local p = go.Position
for _, dx in ipairs({6, -6, 4, -4, 0}) do
tween(go, {Position = p + UDim2.fromOffset(dx, 0)}, .05)
task.wait(.05)
end
end
local function finishAuth(name)
FX.snd("ok")
I18N.user = keep and name or nil
I18N.session = name
if FX.cloud then task.spawn(function() pcall(FX.cloud.pushMine, name) end) end
if I18N.nick == "" then I18N.nick = name end
I18N.save()
if needSetup then
subtitle.Text = "Set up before you start"
authPane.Visible = false
setupPane.Visible = true
goSetup.Visible = true
else
done = true
end
end
local busy = false
go.Activated:Connect(function()
if busy then return end
busy = true
local name = uBox.Text:gsub("%s", "")
local pass = pSec.get()
local accounts = dbRead()
accounts.users = accounts.users or {}
local key = name:lower()
if name == "" or pass == "" then
fail("Fill in every field")
elseif mode == "register" then
if not name:match("^[%w_]+$") or #name < 3 or #name > 16 then
fail("Username: 3-16 letters, numbers or _")
elseif #pass < 4 then
fail("Password needs at least 4 characters")
elseif pass ~= cSec.get() then
fail("Passwords do not match")
elseif accounts.users[key] then
fail("That username is already taken")
elseif FX.cloud.enabled() and FX.cloud.nameBlocked(key) then
fail(FX.cloud.blockMsg)
else
local salt = HttpService:GenerateGUID(false)
accounts.users[key] = {name = name, salt = salt, hash = hashPass(salt, pass), created = os.time()}
if dbWrite(accounts) then
finishAuth(name)
else
fail("Could not save the account")
end
end
else
local u = accounts.users[key]
if not u then
fail("Account not found")
elseif hashPass(u.salt, pass) ~= u.hash then
fail("Wrong password")
else
finishAuth(u.name)
end
end
busy = false
end)
setMode("login")
do
local formParts = {}
for _, c in ipairs(authPane:GetChildren()) do
if c:IsA("GuiObject") and c.LayoutOrder >= 3 then formParts[#formParts + 1] = c end
end
local landing = new("Frame", {
Size = UDim2.new(1, 0, 0, 120), BackgroundTransparency = 1, LayoutOrder = 3, Parent = authPane,
}, {new("UIListLayout", {Padding = UDim.new(0, 10), HorizontalAlignment = Enum.HorizontalAlignment.Center, VerticalAlignment = Enum.VerticalAlignment.Center, SortOrder = Enum.SortOrder.LayoutOrder})})
local backLink
local function showForm(m)
for _, c in ipairs(formParts) do c.Visible = true end
landing.Visible = false
backLink.Visible = true
setMode(m)
cLabel.Visible = (m == "register")
cSec.box.Visible = (m == "register")
end
local function showLanding()
for _, c in ipairs(formParts) do c.Visible = false end
landing.Visible = true
backLink.Visible = false
subtitle.Text = "Welcome to " .. NAME
err.Text = ""
end
local function link(label, order, m, primary, ico)
local b = new("TextButton", {
Size = UDim2.new(1, 0, 0, 42), BackgroundColor3 = primary and T.bronze or T.panel, AutoButtonColor = false, Text = label,
TextSize = 13, FontFace = F.Bold, TextColor3 = primary and T.dark or T.text, LayoutOrder = order, Parent = landing,
}, {round(10), stroke(primary and T.bronzeHi or T.line)})
if primary then
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(200, 150, 150)), Parent = b})
end
local li = icon(b, ico, 15, primary and T.dark or T.muted, 1.8)
li.holder.AnchorPoint = Vector2.new(0, .5)
li.holder.Position = UDim2.new(0, 16, .5, 0)
local st = b:FindFirstChildOfClass("UIStroke")
b.MouseEnter:Connect(function()
tween(b, {BackgroundColor3 = primary and T.bronzeHi or T.panel2}, .18)
tween(st, {Color = primary and T.bronzeHi or T.tan}, .18)
li.set(primary and T.dark or T.tan, .18)
end)
b.MouseLeave:Connect(function()
tween(b, {BackgroundColor3 = primary and T.bronze or T.panel}, .22)
tween(st, {Color = primary and T.bronzeHi or T.line}, .22)
li.set(primary and T.dark or T.muted, .22)
end)
pressFx(b, .96)
b.Activated:Connect(function() FX.snd("tab") showForm(m) end)
return b
end
link("Sign in to account", 1, "login", true, "login")
link("Create account", 2, "register", false, "plus")
text(landing, "Accounts are saved only on this device", 10, "Regular", T.muted, {
Size = UDim2.new(1, 0, 0, 14), LayoutOrder = 3, TextXAlignment = Enum.TextXAlignment.Center,
})
backLink = new("TextButton", {
Size = UDim2.new(1, 0, 0, 22), BackgroundTransparency = 1, AutoButtonColor = false, Text = "Back",
TextSize = 11, FontFace = F.SemiBold, TextColor3 = T.muted, LayoutOrder = 40, Visible = false, Parent = authPane,
})
backLink.Activated:Connect(function() FX.snd("tab") showLanding() end)
showLanding()
end
label(setupPane, 1, "user", "Nickname (optional)")
local box = field(setupPane, 2, "Type a nickname...", I18N.nick, "sparkle")
box:GetPropertyChangedSignal("Text"):Connect(function()
local t = box.Text
local n = utf8.len(t)
if n and n > 20 then box.Text = t:sub(1, utf8.offset(t, 21) - 1) end
end)
local BADGE = {pt = "PT", en = "EN", es = "ES", fr = "FR", de = "DE", id = "ID"}
local langSets = {}
local function paintLang(anim)
for _, set in ipairs(langSets) do
for code, p in pairs(set) do
local on = (code == I18N.lang)
local bgc = on and T.bronze or T.panel2
if anim then tween(p.b, {BackgroundColor3 = bgc}, .25) else p.b.BackgroundColor3 = bgc end
local st = p.b:FindFirstChildOfClass("UIStroke")
if st then st.Color = on and T.bronzeHi or T.line end
p.bd.BackgroundColor3 = on and T.dark or T.panel
p.bl.TextColor3 = on and T.bronze or T.tan
p.nm.TextColor3 = on and T.dark or T.text
end
end
end
local function langGrid(parent, order)
local n = #I18N.LANGS
local row = new("Frame", {Size = UDim2.new(1, 0, 0, 50), BackgroundTransparency = 1, LayoutOrder = order, Parent = parent}, {hlist(6, nil, Enum.HorizontalAlignment.Center)})
local set = {}
langSets[#langSets + 1] = set
for i, l in ipairs(I18N.LANGS) do
local b = new("TextButton", {
Size = UDim2.new(1 / n, -6, 1, 0), BackgroundColor3 = T.panel2, AutoButtonColor = false, Text = "", LayoutOrder = i, Parent = row,
}, {round(8), stroke(T.line)})
local bd = new("Frame", {
AnchorPoint = Vector2.new(.5, 0), Size = UDim2.fromOffset(32, 22), Position = UDim2.new(.5, 0, 0, 6),
BackgroundColor3 = T.panel, BorderSizePixel = 0, Parent = b,
}, {round(4), stroke(T.line, 1)})
I18N.flag(bd, l.code, 32, 22, UDim2.new(), 3)
local bl = text(bd, "", 9, "Bold", T.tan, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center, Visible = false})
local nm = text(b, BADGE[l.code] or l.code:upper(), 9, "Bold", T.text, {
Position = UDim2.new(0, 0, 1, -17), Size = UDim2.new(1, 0, 0, 12), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true,
})
pressFx(b, .95)
set[l.code] = {b = b, bd = bd, bl = bl, nm = nm}
b.Activated:Connect(function()
I18N.set(l.code)
I18N.save()
paintLang(true)
end)
end
return row
end
langGrid(authPane, 15)
label(setupPane, 3, "globe", "Language")
langGrid(setupPane, 4)
paintLang(false)
text(setupPane, "You can change this later in Settings", 10, "Regular", T.muted, {
Size = UDim2.new(1, 0, 0, 28), TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 5,
})
goSetup = new("TextButton", {
Position = UDim2.new(0, 16, 1, -52), Size = UDim2.new(1, -32, 0, 40), BackgroundColor3 = T.bronze,
AutoButtonColor = false, Text = "Continue", TextSize = 14, FontFace = F.Bold, TextColor3 = T.dark,
Visible = false, Parent = col,
}, {round(10), stroke(T.bronzeHi)})
pressFx(goSetup, .96)
do
local gsi = icon(goSetup, "arrowR", 16, T.dark, 2)
gsi.holder.AnchorPoint = Vector2.new(1, .5)
gsi.holder.Position = UDim2.new(1, -16, .5, 0)
end
goSetup.Activated:Connect(function() done = true end)
if needAuth then
authPane.Visible = true
else
subtitle.Text = "Set up before you start"
setupPane.Visible = true
goSetup.Visible = true
end
task.delay(.08, function() if card.Parent then FX.cascade(card, .5) end end)
while not done and sg.Parent do task.wait(.05) end
if needSetup then
I18N.setNick(box.Text)
I18N.profile.setupDone = true
end
I18N.save()
FX.sfx.mute = prevMute
sg:Destroy()
end
function I18N.login()
runSetup(true, false)
end
do
local oldSetup = parentGui:FindFirstChild(NAME .. "Setup")
if oldSetup then oldSetup:Destroy() end
local needSetup = not I18N.profile.setupDone or not COL[I18N.profile.lang or ""]
local needAuth = I18N.user == nil
if needAuth or needSetup then
local okS, errS = pcall(runSetup, needAuth, needSetup)
if not okS then warn("[Hyundax IUM] setup screen failed: " .. tostring(errS)) end
local leftover = parentGui:FindFirstChild(NAME .. "Setup")
if leftover then leftover:Destroy() end
end
end
end
local function runLoader()
local RunService = game:GetService("RunService")
local ContentProvider = game:GetService("ContentProvider")
local sg = new("ScreenGui", {
Name = NAME .. "Loader", ResetOnSpawn = false, IgnoreGuiInset = true,
ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 1001, Parent = parentGui,
})
local dim = new("TextButton", {
Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 1,
AutoButtonColor = false, Text = "", BorderSizePixel = 0, Parent = sg,
})
tween(dim, {BackgroundTransparency = .12}, .6)
local vp = workspace.CurrentCamera.ViewportSize
local W, H = 560, 340
local base = math.clamp(math.min(vp.X / (W + 40), vp.Y / (H + 40)), .55, 1)
local card = new("CanvasGroup", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromOffset(W, H),
BackgroundColor3 = T.bg, BorderSizePixel = 0, GroupTransparency = 1, Parent = dim,
}, {round(14)})
local rim = stroke(Color3.new(1, 1, 1), 1.4)
rim.Parent = card
new("UIGradient", {Rotation = 40, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.45, T.tan), ColorSequenceKeypoint.new(1, T.bronzeLo)}), Parent = rim})
local cardScale = new("UIScale", {Scale = base * .86, Parent = card})
tween(cardScale, {Scale = base}, .6, Enum.EasingStyle.Back)
tween(card, {GroupTransparency = 0}, .5)
FX.backdrop(card, 14)
pcall(FX.tetris, card, W, H, 14)
local parts = {}
for i = 1, 18 do
local s = math.random(2, 4)
local d = new("Frame", {AnchorPoint = Vector2.new(.5, .5), Size = UDim2.fromOffset(s, s), BackgroundColor3 = T.bronzeHi, BorderSizePixel = 0, ZIndex = 1, Parent = card}, {round(2)})
parts[i] = {f = d, x = math.random(), sp = .03 + math.random() * .05, ph = math.random() * 6.28, off = math.random()}
end
local title = text(card, "HYUNDAX IUM", 40, "Bold", Color3.new(1, 1, 1), {Position = UDim2.fromOffset(0, 22), Size = UDim2.new(1, 0, 0, 62), TextXAlignment = Enum.TextXAlignment.Center, ZIndex = 3, NoI18N = true})
new("UIGradient", {Rotation = 90, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.5, T.gold), ColorSequenceKeypoint.new(1, T.tan)}), Parent = title})
local logo = logoImage({AnchorPoint = Vector2.new(.5, 0), Size = UDim2.fromOffset(74, 74), Position = UDim2.new(.5, 0, 0, 88), ZIndex = 3, Parent = card})
local halo = new("Frame", {AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromOffset(66, 228), Size = UDim2.fromOffset(76, 76), BackgroundColor3 = T.bronze, BackgroundTransparency = .9, BorderSizePixel = 0, ZIndex = 2, Parent = card}, {round(38)})
local ring = new("Frame", {AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromOffset(66, 228), Size = UDim2.fromOffset(56, 56), BackgroundColor3 = T.glow, BorderSizePixel = 0, ZIndex = 3, Parent = card}, {round(28)})
local ringStroke = stroke(Color3.new(1, 1, 1), 2.5)
ringStroke.Parent = ring
local ringG = new("UIGradient", {
Color = ColorSequence.new(T.bronzeHi, T.bronzeLo),
Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 0), NumberSequenceKeypoint.new(.6, .1), NumberSequenceKeypoint.new(.72, 1), NumberSequenceKeypoint.new(1, 1)}),
Parent = ringStroke,
})
local ringIc = icon(ring, "download", 24, T.gold, 1.8)
ringIc.holder.AnchorPoint = Vector2.new(.5, .5)
ringIc.holder.Position = UDim2.fromScale(.5, .5)
local capt = text(card, "Loading Hyundax IUM", 15, "Bold", T.text, {Position = UDim2.fromOffset(120, 190), Size = UDim2.new(1, -220, 0, 20), ZIndex = 3, NoI18N = true})
local pct = text(card, "0%", 15, "Bold", T.bronzeHi, {Position = UDim2.new(1, -96, 0, 190), Size = UDim2.fromOffset(64, 20), TextXAlignment = Enum.TextXAlignment.Right, ZIndex = 3, NoI18N = true})
local stepLbl = text(card, "Starting...", 11, "Regular", T.muted, {Position = UDim2.fromOffset(120, 212), Size = UDim2.new(1, -152, 0, 16), ZIndex = 3, NoI18N = true})
local track = new("Frame", {Position = UDim2.fromOffset(120, 238), Size = UDim2.new(1, -152, 0, 8), BackgroundColor3 = T.panel2, BorderSizePixel = 0, ZIndex = 3, Parent = card}, {round(4)})
local fill = new("Frame", {Size = UDim2.fromScale(0, 1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, ClipsDescendants = true, ZIndex = 4, Parent = track}, {round(4)})
new("UIGradient", {Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronze), ColorSequenceKeypoint.new(.5, T.gold), ColorSequenceKeypoint.new(1, T.tan)}), Parent = fill})
local shimmer = new("Frame", {Size = UDim2.new(0, 70, 1, 0), BackgroundColor3 = Color3.new(1, 1, 1), BackgroundTransparency = .6, BorderSizePixel = 0, ZIndex = 5, Parent = fill})
new("UIGradient", {Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(.5, 0), NumberSequenceKeypoint.new(1, 1)}), Parent = shimmer})
local curLabel, curName, curPath = "Starting...", nil, nil
local function refreshLbl()
if curName then
stepLbl.Text = ("%s (%s | %s)"):format(curLabel, curName, curPath or "-")
else
stepLbl.Text = curLabel
end
end
local function setItem(name, path)
curName, curPath = tostring(name), tostring(path)
refreshLbl()
end
local function baseName(pth) return tostring(pth):match("[^/\\]+$") or tostring(pth) end
stepLbl.TextTruncate = Enum.TextTruncate.AtEnd
local STAGES = {
{"Checking executor environment", 1.2, .08, function()
local names = {"writefile", "readfile", "isfile", "makefolder", "listfiles", "getcustomasset", "gethui", "request", "loadstring", "setclipboard", "isfolder", "delfile"}
local have = 0
for _, n in ipairs(names) do
setItem(n, "executor API")
local ok, v = pcall(function() return getfenv()[n] end)
if ok and type(v) == "function" then have += 1 end
task.wait()
end
end},
{"Reading local storage", 1.6, .10, function()
pcall(function()
for _, d in ipairs({FOLDER, PATH.auto, PATH.img, DB_FOLDER}) do
setItem(baseName(d), d)
if makefolder and isfolder and not isfolder(d) then makefolder(d) end
end
end)
for _, p in ipairs({PATH.cloud, PATH.saved, PATH.autoIdx, PATH.likes, PATH.stats, ACCOUNTS_FILE}) do
setItem(baseName(p), p)
jsonRead(p, {})
task.wait()
end
end},
{"Loading logo", 1.8, .10, function()
setItem(baseName(LOGO_FILE), LOGO_FILE)
local asset = toAsset(LOGO_FILE, function() return game:HttpGet(LOGO_URL) end)
if asset then
logoAsset = asset
for _, img in ipairs(logos) do
img.Image = asset
tween(img, {ImageTransparency = 0}, .5)
end
if not PATH.fast then
local probe = Instance.new("ImageLabel")
probe.Image = asset
pcall(function() ContentProvider:PreloadAsync({probe}) end)
probe:Destroy()
end
end
end},
{"Loading icons", 2.2, .12, function()
if PATH.fast then return end
local probes = {}
for ai, a in ipairs({iconAtlas, iconAtlas2}) do
if a then
setItem(ai == 1 and baseName(PATH.ui) or "icons2", ai == 1 and PATH.ui or a)
local p = Instance.new("ImageLabel")
p.Image = a
probes[#probes + 1] = p
end
end
pcall(function() ContentProvider:PreloadAsync(probes) end)
for _, p in ipairs(probes) do p:Destroy() end
end},
{"Loading fonts", 1.8, .10, function()
if PATH.fast then return end
local probes = {}
for fname, f in pairs(F) do
pcall(function() setItem(fname, f.Family) end)
local l = Instance.new("TextLabel")
l.FontFace = f
l.Text = "Hyundax IUM"
probes[#probes + 1] = l
end
pcall(function() ContentProvider:PreloadAsync(probes) end)
for _, p in ipairs(probes) do p:Destroy() end
end},
{"Loading your avatar", 1.6, .08, function()
if PATH.fast then return end
setItem("AvatarHeadShot", "rbxthumb://id=" .. tostring(lp.UserId))
local p = Instance.new("ImageLabel")
p.Image = ("rbxthumb://type=AvatarHeadShot&id=%d&w=150&h=150"):format(lp.UserId)
pcall(function() ContentProvider:PreloadAsync({p}) end)
local t = os.clock()
while not p.IsLoaded and os.clock() - t < 3 do task.wait(.1) end
p:Destroy()
end},
{"Caching auto execute scripts", 1.8, .10, function(rep)
if listfiles and isfolder and isfolder(PATH.auto) then
local ok, fl = pcall(listfiles, PATH.auto)
if ok and type(fl) == "table" then
for i, f in ipairs(fl) do
setItem(baseName(f), f)
pcall(readfile, f)
rep(i / #fl)
task.wait()
end
end
end
end},
{"Preloading game assets", 5, .22, function(rep)
if PATH.fast then return end
local list = {}
local n = 0
for _, d in ipairs(workspace:GetDescendants()) do
n += 1
if n % 4000 == 0 then task.wait() end
if d:IsA("Decal") or d:IsA("Texture") or d:IsA("MeshPart") or d:IsA("Sound") or d:IsA("ParticleEmitter") or d:IsA("SurfaceAppearance") then
list[#list + 1] = d
if #list >= 600 then break end
end
end
local total = #list
if total == 0 then return end
for i = 1, total, 40 do
local batch = {}
for j = i, math.min(i + 39, total) do batch[#batch + 1] = list[j] end
pcall(function() setItem(list[i].Name, list[i]:GetFullName()) end)
pcall(function() ContentProvider:PreloadAsync(batch) end)
rep(math.min(1, (i + 39) / total))
end
end},
{"Finalizing interface", 3, .10, function()
setItem("interface", FOLDER)
if PATH.fast then return end
pcall(function() game:GetService("TextService"):GetTextSize("Hyundax IUM", 14, Enum.Font.GothamBold, Vector2.new(400, 100)) end)
collectgarbage("collect")
task.wait(.2)
end},
}
local bars = new("Frame", {Position = UDim2.fromOffset(120, 262), Size = UDim2.new(1, -152, 0, 4), BackgroundTransparency = 1, ZIndex = 3, Parent = card}, {hlist(4)})
local dots = {}
for i = 1, #STAGES do
dots[i] = new("Frame", {Size = UDim2.new(1 / #STAGES, -4, 1, 0), BackgroundColor3 = T.panel2, BorderSizePixel = 0, LayoutOrder = i, ZIndex = 3, Parent = bars}, {round(2)})
end
text(card, PATH.fast and "Loading from saved files in the HyundaxIUM folder." or (PATH.folderMissing and "HyundaxIUM folder not found in workspace. Reloading everything as the first time." or "First load is slower while Hyundax IUM prepares files, fonts, icons and game assets."), 10, "Regular", T.muted, {Position = UDim2.fromOffset(0, 302), Size = UDim2.new(1, 0, 0, 14), TextXAlignment = Enum.TextXAlignment.Center, ZIndex = 3, NoI18N = true})
local target, shown, activeIdx = 0, 0, 0
local conn
conn = RunService.Heartbeat:Connect(function(dt)
if not sg.Parent then conn:Disconnect() return end
local t = os.clock()
shown += (target - shown) * math.min(1, dt * 6)
fill.Size = UDim2.fromScale(math.clamp(shown, 0, 1), 1)
pct.Text = math.floor(shown * 100 + .5) .. "%"
shimmer.Position = UDim2.new(((t * .8) % 1.6) - .3, 0, 0, 0)
ringG.Rotation = (t * 220) % 360
logo.Position = UDim2.new(.5, 0, 0, 92 + math.sin(t * 2) * 3)
halo.BackgroundTransparency = .9 + .04 * math.sin(t * 2.4)
local pulse = .5 + .5 * math.sin(t * 5)
if dots[activeIdx] then dots[activeIdx].BackgroundColor3 = T.bronzeLo:Lerp(T.bronzeHi, pulse) end
for _, p in ipairs(parts) do
local u = (p.off + t * p.sp) % 1
p.f.Position = UDim2.new(p.x + .02 * math.sin(t + p.ph), 0, 1 - u, 0)
p.f.BackgroundTransparency = 1 - math.sin(u * math.pi) * .7
end
end)
local t0 = os.clock()
local acc = 0
for i, st in ipairs(STAGES) do
if os.clock() - t0 >= 50 then break end
activeIdx = i
curLabel, curName, curPath = st[1], nil, nil
capt.Text = ("Loading Hyundax IUM (%d/%d)"):format(i, #STAGES)
tween(stepLbl, {TextTransparency = 1}, .12)
task.delay(.14, function() refreshLbl() tween(stepLbl, {TextTransparency = 0}, .2) end)
local stDur = PATH.fast and math.min(st[2], .08) or st[2]
local sub, done = .92, false
task.spawn(function()
pcall(st[4], function(p) sub = math.clamp(p, 0, 1) * .96 end)
done = true
end)
local ts = os.clock()
while os.clock() - t0 < 50 do
local el = os.clock() - ts
local timeP = math.clamp(el / stDur, 0, 1)
local p = math.min(timeP, done and 1 or sub)
target = acc + st[3] * p
if done and el >= stDur then break end
task.wait()
end
acc += st[3]
target = acc
if dots[i] then dots[i].BackgroundColor3 = T.bronze end
activeIdx = 0
end
target = 1
if not PATH.fast then
pcall(function() if writefile then writefile(PATH.flag, VERSION) end end)
end
local tw = os.clock()
while shown < .995 and os.clock() - tw < (PATH.fast and .25 or .8) do task.wait() end
capt.Text = "Ready"
stepLbl.Text = "All set"
ringIc.swap("check")
for _, d in ipairs(dots) do d.BackgroundColor3 = T.bronze end
task.wait(PATH.fast and .1 or .45)
tween(cardScale, {Scale = base * 1.06}, .45, Enum.EasingStyle.Quint)
tween(card, {GroupTransparency = 1}, .45)
tween(dim, {BackgroundTransparency = 1}, .5)
task.wait(.55)
if conn then conn:Disconnect() end
sg:Destroy()
end
do
local okL, errL = pcall(runLoader)
if not okL then warn("[Hyundax IUM] loader failed: " .. tostring(errL)) end
local leftover = parentGui:FindFirstChild(NAME .. "Loader")
if leftover then leftover:Destroy() end
end
local gui = new("ScreenGui", {
Name = NAME, ResetOnSpawn = false, IgnoreGuiInset = true,
ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 999, Parent = parentGui,
})
I18N.attach(gui)
local TITLE_H, BAR_H, SIDE_W = 36, 0, 128
local CONTENT_SCALE = .86
local function viewport() return workspace.CurrentCamera.ViewportSize end
local function normalSize()
local vp = viewport()
return Vector2.new(math.clamp(vp.X * .82, math.min(460, vp.X - 16), 1280), math.clamp(vp.Y * .88, math.min(320, vp.Y - 16), 820)) / math.max(FX.uiScale or 1, .3)
end
local function maxSize()
local vp = viewport()
return Vector2.new(vp.X - 16, vp.Y - 16) / math.max(FX.uiScale or 1, .3)
end
local sizeNormal = normalSize()
local root = new("Frame", {
Name = "Root", AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5),
Size = UDim2.fromOffset(sizeNormal.X, sizeNormal.Y), BackgroundTransparency = 1, Parent = gui,
})
local rootScale = new("UIScale", {Scale = .88, Parent = root})
local main = new("Frame", {
Name = "Main", Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.bg, BorderSizePixel = 0,
ClipsDescendants = true, Parent = root,
}, {round(14)})
FX.backdrop(main, 14)
local mainVeil = new("Frame", {
Name = "Veil", Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0), BorderSizePixel = 0, ZIndex = 200, Parent = main,
}, {round(14)})
local borderStroke = stroke(Color3.new(1, 1, 1), 1.4)
new("UIGradient", {Rotation = 40, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.45, T.tan), ColorSequenceKeypoint.new(1, T.bronzeLo)}), Parent = borderStroke})
borderStroke.Transparency = 1
FX.borderFrame = new("Frame", {Name = "HXBorder", Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, ZIndex = 100, Parent = root}, {round(14), borderStroke})
local S = {autoscroll = true, lineNums = true, wrap = false}
local shown = false
local function setShown(v)
shown = v
FX.snd(v and "open" or "close")
FX.snd(v and "bub_whoosh" or "bub_merge")
local C = S.cfg or {}
if S.winFx then S.winFx(v) end
if v then
FX.stopMove(root) root.Position = UDim2.fromScale(.5, .5)
local oa = C.openAnim or 1
if oa == 1 and not root.Visible then rootScale.Scale = .88 end
root.Visible = true
if oa == 1 then tween(rootScale, {Scale = S.uiScale or 1}, .7, Enum.EasingStyle.Back) else rootScale.Scale = S.uiScale or 1 end
if oa == 3 then
mainVeil.BackgroundTransparency = 1
borderStroke.Transparency = 0
else
tween(mainVeil, {BackgroundTransparency = 1}, .4)
tween(borderStroke, {Transparency = 0}, .3)
end
if FX.show then FX.show() end
else
local ca = C.closeAnim or 1
if ca == 1 then tween(rootScale, {Scale = .9}, .24, Enum.EasingStyle.Quad, Enum.EasingDirection.In) end
if ca == 3 then
mainVeil.BackgroundTransparency = 0
borderStroke.Transparency = 1
root.Visible = false
else
tween(mainVeil, {BackgroundTransparency = 0}, .2)
tween(borderStroke, {Transparency = 1}, .22)
task.delay(.26 * FX.scale, function() if not shown then root.Visible = false end end)
end
end
end
FX.TS = {list = {}, H = 38, GAP = 8, LIFE = 3.4}
function FX.TS.corner()
local c = (S.cfg and S.cfg.toastPos) or 1
return c == 2 or c == 4, c == 3 or c == 4
end
function FX.TS.anchor()
local left, top = FX.TS.corner()
return Vector2.new(left and 0 or 1, top and 0 or 1)
end
function FX.TS.pos(i, n, off)
local left, top = FX.TS.corner()
local step = FX.TS.H + FX.TS.GAP
local xs, xo
if left then xs, xo = 0, off and -(off + 30) or 16 else xs, xo = 1, off and (off + 30) or -16 end
if top then return UDim2.new(xs, xo, 0, 44 + (i - 1) * step) end
return UDim2.new(xs, xo, 1, -(40 + (n - i) * step))
end
function FX.TS.layout()
local n = #FX.TS.list
for i, t in ipairs(FX.TS.list) do
tween(t.f, {Position = FX.TS.pos(i, n)}, .45, Enum.EasingStyle.Back)
end
end
function FX.TS.dismiss(t)
if t.gone then return end
t.gone = true
local i = table.find(FX.TS.list, t)
if i then table.remove(FX.TS.list, i) end
FX.TS.layout()
if t.f and t.f.Parent then
local ox = FX.TS.pos(1, 1, t.w)
tween(t.f, {Position = UDim2.new(ox.X.Scale, ox.X.Offset, t.f.Position.Y.Scale, t.f.Position.Y.Offset)}, .22, Enum.EasingStyle.Quint, Enum.EasingDirection.In)
task.delay(.26, function() if t.f then t.f:Destroy() end end)
end
end
local function toast(msg, kind)
if S.toasts == false then return end
msg = tostring(msg)
local low = msg:lower()
local function has(...)
for _, w in ipairs({...}) do if low:find(w, 1, true) then return true end end
return false
end
if not kind then
if has("error", "fail", "invalid", "denied", "cannot", "could not", "can't", "unavailable", "wrong", "syntax") then kind = "err"
elseif has("enter ", "add some", "empty", "select ", "needs at least", "pick at least", "tap a player", "required", "write some",
"save this", "no character", "do not match", "already", "paste an image") then kind = "warn"
elseif has("saved", "injected", "executed", "copied", "success", "loaded", "applied", "enabled", "deleted", "removed",
"updated", "switched", "posted", "forged", "teleported", "reloaded", "refreshed", "imported", "destroyed") then kind = "ok"
else kind = "info" end
end
do
local C = S.cfg or {}
if (kind == "ok" and C.toastSuccess == false) or (kind == "err" and C.toastErrors == false) or (kind == "warn" and C.toastWarn == false) or (kind == "info" and C.toastInfo == false) then return end
if kind ~= "err" then
if (C.toastRun == false and has("executed")) or (C.toastSave == false and has("saved")) or (C.toastCopy == false and has("copied"))
or (C.toastLoad == false and has("loaded")) or (C.toastPlugin == false and has("plugin")) or (C.toastUpdate == false and has("updated"))
or (C.toastLogin == false and has("signed", "hello,", "welcome")) or (C.toastTheme == false and has("theme")) or (C.toastLang == false and has("language")) then return end
end
if C.toastGroup ~= false then
for _, t0 in ipairs(FX.TS.list) do if t0.msg == msg and not t0.gone then return end end
end
end
if kind == "err" then FX.snd("err") elseif kind == "ok" then FX.snd("ok") end
local acc
if kind == "ok" then acc = Color3.fromRGB(98, 214, 138)
elseif kind == "err" then acc = Color3.fromRGB(255, 104, 104)
elseif kind == "warn" then acc = Color3.fromRGB(255, 196, 70)
else acc = T.tan end
local tint = kind == "info" and 0 or 1
local bgc = T.panel:Lerp(acc, .06 * tint)
local edge = T.line:Lerp(acc, .38 * tint)
local f = new("Frame", {
AnchorPoint = FX.TS.anchor(), Size = UDim2.fromOffset(200, FX.TS.H), BackgroundColor3 = bgc, BorderSizePixel = 0,
ZIndex = 50, Parent = main,
}, {round(12), stroke(edge, 1)})
f:SetAttribute("NoGlass", true)
local chip = new("Frame", {
Position = UDim2.new(0, 9, .5, -12), Size = UDim2.fromOffset(24, 24), BackgroundColor3 = acc, BackgroundTransparency = .86,
BorderSizePixel = 0, ZIndex = 51, Parent = f,
}, {round(8)})
local TOAST_ICON = {ok = "check", err = "x", warn = "warning", info = "info"}
local okIcon = pcall(function()
local ic = icon(chip, TOAST_ICON[kind] or "info", 12, acc, 1.8)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
ic.holder.ZIndex = 52
end)
if not okIcon then
text(chip, kind == "warn" and "!" or (kind == "err" and "x" or (kind == "ok" and "+" or "i")), 13, "Bold", acc, {
Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center, ZIndex = 52,
})
end
local lx = (S.cfg and S.cfg.toastIcons == false) and 14 or 42
if lx == 14 then chip.Visible = false end
local lbl = text(f, msg, 12, "Medium", T.text, {
Position = UDim2.fromOffset(lx, 0), Size = UDim2.new(0, 300, 1, -3), TextTruncate = Enum.TextTruncate.AtEnd, ZIndex = 52,
})
local tw = math.ceil(lbl.TextBounds.X)
if tw <= 0 then tw = #msg * 6.5 end
tw = math.min(tw + 2, 280)
lbl.Size = UDim2.new(0, tw, 1, -3)
local w = lx + tw + 14
f.Size = UDim2.fromOffset(w, FX.TS.H)
local bar = new("Frame", {
AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 12, 1, -4), Size = UDim2.new(1, -24, 0, 2), BackgroundColor3 = acc,
BackgroundTransparency = .4, BorderSizePixel = 0, ZIndex = 52, Parent = f,
}, {round(1)})
bar.Visible = not (S.cfg and S.cfg.toastProgress == false)
local t = {f = f, w = w, msg = msg}
local close = new("TextButton", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Text = "", ZIndex = 55, Parent = f})
if not (S.cfg and S.cfg.toastClickDismiss == false) then close.MouseButton1Click:Connect(function() FX.TS.dismiss(t) end) end
table.insert(FX.TS.list, t)
while #FX.TS.list > (S.toastMax or 3) do FX.TS.dismiss(FX.TS.list[1]) end
f.Position = FX.TS.pos(#FX.TS.list, #FX.TS.list, w)
FX.TS.layout()
tween(bar, {Size = UDim2.new(0, 0, 0, 2)}, FX.TS.LIFE, Enum.EasingStyle.Linear)
task.delay(FX.TS.LIFE, function() FX.TS.dismiss(t) end)
end
FX.POP = {stack = {}}
function FX.popBtn(parent, label, kind, cb, props)
local primary, danger = kind == "primary", kind == "danger"
local base = primary and T.bronze or (danger and Color3.fromRGB(150, 44, 48) or T.panel2)
local hov = primary and T.bronzeHi or (danger and Color3.fromRGB(190, 60, 64) or T.line)
local p = {
Size = UDim2.new(1, 0, 0, 32), BackgroundColor3 = base, AutoButtonColor = false, Text = label,
TextSize = 11, FontFace = F.SemiBold, TextColor3 = T.text, Parent = parent,
}
for k, v in pairs(props or {}) do p[k] = v end
local b = new("TextButton", p, {round(9), stroke(primary and T.bronzeHi or (danger and hov or T.line), 1)})
hoverFx(b, base, hov)
pressFx(b, .96)
if cb then b.Activated:Connect(cb) end
return b
end
function FX.popup(o)
o = o or {}
local parent = o.parent or gui
local name = o.name or "HXPopup"
local stale = parent:FindFirstChild(name)
if stale then stale:Destroy() end
local HEAD = o.title and 56 or 0
local buttons = o.buttons
local FOOT = (buttons or o.footer) and (o.footerH or 58) or 0
local m = o.margin or 10
local overlay = new("TextButton", {
Name = name, Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 1,
BorderSizePixel = 0, Text = "", AutoButtonColor = false, ZIndex = o.z or 400, Parent = parent,
})
overlay:SetAttribute("HXPopup", true)
for k, v in pairs(o.attrs or {}) do overlay:SetAttribute(k, v) end
tween(overlay, {BackgroundTransparency = .5}, .2)
local scale = new("UIScale", {Scale = .95})
local dlg = new("Frame", {
Name = "Card", AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5),
Size = UDim2.new(1, -m * 2, 1, -m * 2), BackgroundColor3 = T.panel, BorderSizePixel = 0,
ClipsDescendants = true, Active = true, Parent = overlay,
}, {round(14), stroke(T.line, 1), scale, new("UISizeConstraint", {MaxSize = Vector2.new(o.w or 420, o.h or 340)})})
dlg:SetAttribute("NoGlass", true)
dlg:SetAttribute("PopupStyled", true)
tween(scale, {Scale = 1}, .3)
local p = {overlay = overlay, dlg = dlg, scale = scale, actions = {}, buttons = {}}
local closing = false
function p.close()
if closing or not overlay.Parent then return end
closing = true
tween(scale, {Scale = .96}, .14)
tween(overlay, {BackgroundTransparency = 1}, .14)
task.delay(.16 * FX.scale, function() if overlay.Parent then overlay:Destroy() end end)
if o.onClose then task.spawn(o.onClose) end
end
if o.dismiss ~= false then overlay.Activated:Connect(p.close) end
table.insert(FX.POP.stack, p)
local esc = UIS.InputBegan:Connect(function(inp)
if inp.KeyCode == Enum.KeyCode.Escape and FX.POP.stack[#FX.POP.stack] == p and o.escape ~= false then p.close() end
end)
overlay.Destroying:Connect(function()
esc:Disconnect()
local i = table.find(FX.POP.stack, p)
if i then table.remove(FX.POP.stack, i) end
end)
if HEAD > 0 then
local acts = o.actions or {}
local rm = (o.noClose and 14 or 46) + #acts * 32
local tx = o.icon and 54 or 18
if o.icon then FX.chip(dlg, o.icon, 30, o.iconColor or T.gold, UDim2.fromOffset(14, 13)) end
local tp = {
Position = UDim2.fromOffset(tx, o.subtitle and 10 or 0), Size = UDim2.new(1, -(tx + rm), 0, o.subtitle and 18 or HEAD),
TextTruncate = Enum.TextTruncate.AtEnd,
}
if o.raw then tp.NoI18N = true end
text(dlg, o.title, 14, "Bold", T.text, tp)
if o.subtitle then
text(dlg, o.subtitle, 10, "Regular", T.muted, {
Position = UDim2.fromOffset(tx, 29), Size = UDim2.new(1, -(tx + rm), 0, 14), TextTruncate = Enum.TextTruncate.AtEnd,
})
end
local function hbtn(ico, x, quiet)
local b = new("TextButton", {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, x, 0, HEAD / 2), Size = UDim2.fromOffset(28, 28),
BackgroundColor3 = T.panel2, AutoButtonColor = false, Text = "", Parent = dlg,
}, {round(8)})
local ic = icon(b, ico, quiet and 12 or 14, quiet and T.muted or T.text, 1.6)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
pressFx(b, .9)
if quiet then
b.MouseEnter:Connect(function() tween(b, {BackgroundColor3 = T.line}, .15) ic.set(T.text, .15) end)
b.MouseLeave:Connect(function() tween(b, {BackgroundColor3 = T.panel2}, .2) ic.set(T.muted, .2) end)
end
return b, ic
end
local x = -12
if not o.noClose then
local cb = hbtn("x", x, true)
cb.Activated:Connect(p.close)
p.closeBtn = cb
x -= 32
end
for i = #acts, 1, -1 do
local a = acts[i]
local b, ic = hbtn(a.icon, x, false)
if a.cb then b.Activated:Connect(a.cb) end
p.actions[i] = {b = b, ic = ic}
x -= 32
end
new("Frame", {
Position = UDim2.fromOffset(0, HEAD), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line,
BackgroundTransparency = .3, BorderSizePixel = 0, Parent = dlg,
})
end
if FOOT > 0 then
new("Frame", {
AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 0, 1, -FOOT), Size = UDim2.new(1, 0, 0, 1),
BackgroundColor3 = T.line, BackgroundTransparency = .3, BorderSizePixel = 0, Parent = dlg,
})
local foot = new("Frame", {
AnchorPoint = Vector2.new(0, 1), Position = UDim2.fromScale(0, 1), Size = UDim2.new(1, 0, 0, FOOT),
BackgroundTransparency = 1, Parent = dlg,
}, {pad(14, 0, 14, 0)})
p.footer = foot
if buttons then
new("UIListLayout", {
FillDirection = Enum.FillDirection.Horizontal, Padding = UDim.new(0, 8), SortOrder = Enum.SortOrder.LayoutOrder,
VerticalAlignment = Enum.VerticalAlignment.Center, HorizontalAlignment = Enum.HorizontalAlignment.Center, Parent = foot,
})
local n = #buttons
for i, bd in ipairs(buttons) do
p.buttons[i] = FX.popBtn(foot, bd.label, bd.kind or (bd.primary and "primary") or "ghost", function()
if bd.first and bd.cb then bd.cb() end
if bd.close ~= false then p.close() end
if not bd.first and bd.cb then bd.cb() end
end, {Size = UDim2.new(1 / n, -8 * (n - 1) / n, 0, 32), LayoutOrder = i})
end
end
end
local top = HEAD > 0 and HEAD + 1 or 0
local bot = FOOT > 0 and FOOT + 1 or 0
p.body = new("Frame", {
Name = "Body", Position = UDim2.fromOffset(0, top), Size = UDim2.new(1, 0, 1, -(top + bot)),
BackgroundTransparency = 1, ClipsDescendants = true, Parent = dlg,
})
return p
end
function S.confirm(msg, onYes, o)
o = o or {}
local p = FX.popup({
name = "HXConfirm", z = 450, w = 320, h = 186, title = o.title or "Are you sure?", icon = o.icon or "helpCircle",
buttons = {
{label = "Cancel"},
{label = o.yes or "Confirm", kind = o.danger and "danger" or "primary", cb = onYes},
},
})
text(p.body, msg, 12, "Medium", T.text, {
Position = UDim2.fromOffset(20, 0), Size = UDim2.new(1, -40, 1, 0), TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Center,
})
end
function FX.uiRatio(t)
local par = t.Parent
local pa = (par and par:IsA("GuiBase2d")) and par.AbsoluteSize or viewport()
local ex = t.Size.X.Offset + t.Size.X.Scale * pa.X
if ex < 1 or t.AbsoluteSize.X < 1 then return 1 end
return math.clamp(t.AbsoluteSize.X / ex, .25, 4)
end
function FX.clampAbs(t, ax, ay, margin, lenient)
local vp, sz = viewport(), t.AbsoluteSize
local nx = math.clamp(ax, math.min(margin, vp.X) - sz.X, math.max(0, vp.X - margin))
local my = (sz.Y <= 80) and sz.Y or 40
local ny
if lenient then ny = math.clamp(ay, 40 - sz.Y, math.max(0, vp.Y - 40))
else ny = math.clamp(ay, 0, math.max(0, vp.Y - my)) end
return nx, ny
end
function FX.keepReachable(t, margin, lenient)
if t.AbsoluteSize.X < 1 then return end
local ap = t.AbsolutePosition
local nx, ny = FX.clampAbs(t, ap.X, ap.Y, margin, lenient)
if nx ~= ap.X or ny ~= ap.Y then
local r = FX.uiRatio(t)
local p = t.Position
tween(t, {Position = UDim2.new(p.X.Scale, p.X.Offset + (nx - ap.X) / r, p.Y.Scale, p.Y.Offset + (ny - ap.Y) / r)}, .25, Enum.EasingStyle.Quint)
end
end
local function draggable(handle, target, onTap, canDrag, onDrop, clampMargin)
local SLOP, TAP_TIME = 6, .45
local dragging, dragInput, startIn, startPos, moved, t0 = false, nil, nil, nil, false, 0
local baseAbs, ratio = Vector2.zero, 1
local function finishDrag()
if not dragging then return end
dragging = false
local quick = (os.clock() - t0) <= TAP_TIME
if not moved and quick and onTap then pcall(onTap) end
if moved and onDrop then pcall(onDrop) end
dragInput, startIn, startPos = nil, nil, nil
end
handle.InputBegan:Connect(function(i)
if i.UserInputType ~= Enum.UserInputType.MouseButton1 and i.UserInputType ~= Enum.UserInputType.Touch then return end
if canDrag and not canDrag() then return end
FX.stopMove(target)
dragging, dragInput, moved, t0 = true, i, false, os.clock()
startIn, startPos = Vector2.new(i.Position.X, i.Position.Y), target.Position
end)
UIS.InputChanged:Connect(function(i)
if not dragging or not startIn or not startPos then return end
local isMouseMove = dragInput and dragInput.UserInputType == Enum.UserInputType.MouseButton1 and i.UserInputType == Enum.UserInputType.MouseMovement
local isTouchMove = dragInput and dragInput.UserInputType == Enum.UserInputType.Touch and i.UserInputType == Enum.UserInputType.Touch and i == dragInput
if not (isMouseMove or isTouchMove) then return end
if canDrag and not canDrag() then return end
local cur = Vector2.new(i.Position.X, i.Position.Y)
if not moved then
if (cur - startIn).Magnitude <= SLOP then return end
moved = true
startIn = cur
FX.stopMove(target)
startPos = target.Position
baseAbs = target.AbsolutePosition
ratio = FX.uiRatio(target)
end
local d = cur - startIn
local m = clampMargin and clampMargin()
if m then
local nx, ny = FX.clampAbs(target, baseAbs.X + d.X, baseAbs.Y + d.Y, m)
d = Vector2.new(nx - baseAbs.X, ny - baseAbs.Y)
end
d = d / ratio
target.Position = UDim2.new(startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y)
end)
UIS.InputEnded:Connect(function(i)
if not dragging or not dragInput then return end
local mouseEnded = dragInput.UserInputType == Enum.UserInputType.MouseButton1 and i.UserInputType == Enum.UserInputType.MouseButton1
local touchEnded = dragInput.UserInputType == Enum.UserInputType.Touch and i == dragInput
if mouseEnded or touchEnded then finishDrag() end
end)
end
local bar = new("Frame", {Size = UDim2.new(1, 0, 0, TITLE_H), BackgroundTransparency = 1, BorderSizePixel = 0, Parent = main})
new("Frame", {Name = "BarClip", Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, BorderSizePixel = 0, ClipsDescendants = true, ZIndex = 0, Parent = bar}, {
new("Frame", {Name = "BarFill", Size = UDim2.new(1, 0, 0, TITLE_H + 14), BackgroundColor3 = T.bg, BorderSizePixel = 0, ZIndex = 0}, {round(14)}),
})
new("Frame", {Size = UDim2.new(1, 0, 0, 1), Position = UDim2.new(0, 0, 1, -1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = bar}, {
new("UIGradient", {Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.line), ColorSequenceKeypoint.new(.5, T.bronze), ColorSequenceKeypoint.new(1, T.line)})}),
})
local dragArea = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Active = true, Parent = bar})
FX.titleLbl = text(bar, NAME, 15, "Bold", T.text, {Position = UDim2.fromOffset(14, 0), Size = UDim2.new(0, 70, 1, 0)})
local pageOrder = {"Home", "Editor", "Scripts", "Account", "Dex", "Settings"}
local pageIcon = {Home = "home", Editor = "code", Scripts = "globe", Account = "user", Dex = "tree", Settings = "gear"}
local NAV_BTN, NAV_PAD = 32, 4
local nav = new("Frame", {
AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 0), Size = UDim2.fromOffset(NAV_BTN * #pageOrder + NAV_PAD * (#pageOrder - 1), TITLE_H),
BackgroundTransparency = 1, Parent = bar,
}, {hlist(NAV_PAD, nil, Enum.HorizontalAlignment.Center)})
local navIndicator = new("Frame", {
AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, (1 - (#pageOrder + 1) / 2) * (NAV_BTN + NAV_PAD), 0, TITLE_H - 3), Size = UDim2.fromOffset(18, 2),
BackgroundColor3 = T.gold, BorderSizePixel = 0, ZIndex = 3, Parent = bar,
}, {round(1)})
local ctrls = new("Frame", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -4, 0, 0), Size = UDim2.fromOffset(100, TITLE_H),
BackgroundTransparency = 1, Parent = bar,
}, {hlist(2, nil, Enum.HorizontalAlignment.Right)})
local function ctrlBtn(ico, hoverColor, order)
local b = new("TextButton", {
Size = UDim2.fromOffset(30, 26), BackgroundColor3 = T.bg, AutoButtonColor = false, Text = "", LayoutOrder = order, Glass = true, Parent = ctrls,
}, {round(9)})
local ic = icon(b, ico, 12, T.muted, 1.5)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
b.MouseEnter:Connect(function() tween(b, {BackgroundColor3 = hoverColor or T.panel2}, .15) ic.set(T.text, .15) end)
b.MouseLeave:Connect(function() tween(b, {BackgroundColor3 = T.bg}, .2) ic.set(T.muted, .2) end)
pressFx(b, .88)
return b, ic
end
local btnMin = ctrlBtn("minus", nil, 1)
local btnMax, maxIc = ctrlBtn("square", nil, 2)
local restoreIc = icon(btnMax, "restore", 12, T.muted, 1.5)
restoreIc.holder.AnchorPoint, restoreIc.holder.Position, restoreIc.holder.Visible = Vector2.new(.5, .5), UDim2.fromScale(.5, .5), false
local btnClose = ctrlBtn("x", T.bronze, 3)
local content = new("Frame", {
ClipsDescendants = true, Position = UDim2.fromOffset(0, TITLE_H), Size = UDim2.new(1, 0, 1, -(TITLE_H + 10)), BackgroundTransparency = 1, Parent = main,
})
local pages = new("Frame", {Size = UDim2.fromScale(1 / CONTENT_SCALE, 1 / CONTENT_SCALE), BackgroundTransparency = 1, ClipsDescendants = true, Parent = content}, {new("UIScale", {Scale = CONTENT_SCALE})})
local panels, lineCount, lineId = {}, {}, 0
local LOG = {
store = {}, live = {}, max = 1000, shown = 200, filter = "all",
colors = {
out = Color3.fromRGB(255, 255, 255),
info = Color3.fromRGB(86, 160, 255),
warn = Color3.fromRGB(255, 205, 64),
err = Color3.fromRGB(255, 84, 84),
},
kinds = {
[Enum.MessageType.MessageOutput] = "out",
[Enum.MessageType.MessageInfo] = "info",
[Enum.MessageType.MessageWarning] = "warn",
[Enum.MessageType.MessageError] = "err",
},
}
local function logStamp(ts)
ts = math.floor(tonumber(ts) or os.time())
local ok, s = pcall(function() return DateTime.fromUnixTimestamp(ts):FormatLocalTime("HH:mm:ss", "en-us") end)
if ok and type(s) == "string" then return s end
return os.date("%H:%M:%S", ts)
end
function LOG.scroll()
local sf = panels.Console
if sf and S.autoscroll then
task.defer(function() tween(sf, {CanvasPosition = Vector2.new(0, sf.AbsoluteCanvasSize.Y)}, .25) end)
end
end
function LOG.make(e, animate)
local sf = panels.Console
if not sf then return end
local l = new("TextLabel", {
BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y,
TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top,
FontFace = MONO, TextSize = S.consoleSize or 11, TextColor3 = ((e.kind == "err" and S.errColors == false) and LOG.colors.out or e.color), TextTransparency = animate and 1 or 0, RichText = true,
Text = (S.stampOn == false and "" or ('' .. e.stamp .. ' ')) .. tostring(e.msg):gsub("[&<>\"']", {["&"] = "&", ["<"] = "<", [">"] = ">", ['"'] = """, ["'"] = "'"}), LayoutOrder = e.id, Parent = sf,
})
if animate then tween(l, {TextTransparency = 0}, .3) end
LOG.live[#LOG.live + 1] = l
if #LOG.live > LOG.shown then
table.remove(LOG.live, 1):Destroy()
end
end
function LOG.pass(e)
return LOG.filter == "all" or LOG.filter == e.kind
end
function LOG.add(kind, msg, color, ts, quiet)
msg = tostring(msg)
if S.anonLogs then
local lpl = game:GetService("Players").LocalPlayer
if lpl then
for _, nm in ipairs({lpl.Name, lpl.DisplayName}) do
if #nm > 2 then msg = msg:gsub((nm:gsub("%p", "%%%0")), "Player") end
end
end
end
if S.redactLogs then
msg = msg:gsub("[%w_%-%.]+", function(w) if #w >= 32 and w:find("%d") and w:find("%a") then return "[redacted]" end end)
end
if #msg > 2000 then msg = msg:sub(1, 2000) .. "..." end
lineId += 1
local e = {id = lineId, kind = kind, msg = msg, color = color or T.text, stamp = logStamp(ts)}
local st = LOG.store
st[#st + 1] = e
if #st > LOG.max + 200 then
local n = #st
table.move(st, 201, n, 1)
for i = n - 199, n do st[i] = nil end
end
if not quiet and LOG.pass(e) then
LOG.make(e, true)
LOG.scroll()
end
end
function LOG.rerender()
for _, l in ipairs(LOG.live) do l:Destroy() end
table.clear(LOG.live)
local pick, st = {}, LOG.store
for i = #st, 1, -1 do
if LOG.pass(st[i]) then
pick[#pick + 1] = st[i]
if #pick >= LOG.shown then break end
end
end
for i = #pick, 1, -1 do LOG.make(pick[i], false) end
LOG.scroll()
end
function LOG.setFilter(f)
LOG.filter = f
LOG.rerender()
end
function LOG.clear()
for _, l in ipairs(LOG.live) do l:Destroy() end
table.clear(LOG.live)
table.clear(LOG.store)
end
function LOG.start()
local ok, hist = pcall(function() return LogService:GetLogHistory() end)
if ok and type(hist) == "table" then
for i = math.max(1, #hist - LOG.max + 1), #hist do
local h = hist[i]
local k = LOG.kinds[h.messageType] or "out"
LOG.add(k, h.message, LOG.colors[k], h.timestamp, true)
end
LOG.rerender()
end
LogService.MessageOut:Connect(function(msg, typ)
local k = LOG.kinds[typ] or "out"
LOG.add(k, msg, LOG.colors[k])
end)
end
local function addLine(name, msg, color, kind)
if name ~= "Console" or not panels.Console then return end
kind = kind or (color == T.bronzeHi and "err" or "hyundaxium")
LOG.add(kind, I18N.tr(msg), color or T.text)
end
local recents, execCount, execLabel = {}, 0, nil
Store.refreshEditorStart = nil
Store.openEditorPane = nil
local Stats = jsonRead(PATH.stats, {})
Stats.total = tonumber(Stats.total) or 0
Stats.errors = tonumber(Stats.errors) or 0
Stats.sessions = (tonumber(Stats.sessions) or 0) + 1
Stats.first = tonumber(Stats.first) or os.time()
Stats.seconds = tonumber(Stats.seconds) or 0
local sessionStart, lastSave = os.clock(), 0
local function saveStats(force)
if not force and os.clock() - lastSave < 5 then return end
lastSave = os.clock()
local copy = {total = Stats.total, errors = Stats.errors, sessions = Stats.sessions, first = Stats.first, seconds = Stats.baseSeconds + (os.clock() - sessionStart)}
jsonWrite(PATH.stats, copy)
end
Stats.baseSeconds = Stats.seconds
saveStats(true)
local function statTick(isError)
if S.noStats then return end
if isError then Stats.errors += 1 else Stats.total += 1 end
saveStats()
if Stats.refresh then Stats.refresh() end
end
local function runCode(code, name, silent)
name = name or "script"
if S.confirmRun and not silent and not S.runOk then
S.confirm("Run " .. name .. "?", function()
S.runOk = true
runCode(code, name, silent)
S.runOk = false
end)
return
end
if S.clearOnRun and not silent then LOG.clear() end
execCount += 1
statTick(false)
if execLabel then execLabel.Text = tostring(execCount) end
if not silent then
if not S.noRecent then
table.insert(recents, 1, {name = name, code = code})
while #recents > (S.recentLimit or 30) do table.remove(recents) end
end
if Store.refreshEditorStart then task.defer(Store.refreshEditorStart) end
addLine("Console", "> Executing " .. name, T.tan)
end
local ls = loadstring
if not ls then
addLine("Console", "loadstring is not available in this environment.", T.bronzeHi)
toast("loadstring unavailable")
return
end
local fn, err = ls(code)
if not fn then
addLine("Console", tostring(err), T.bronzeHi)
statTick(true)
toast(S.detailErr and ("Syntax error: " .. tostring(err):sub(1, 70)) or "Syntax error")
return
end
task.spawn(function()
local ok, e = pcall(fn)
if ok then
if not silent then addLine("Console", "[ok] finished", T.gold) end
else
addLine("Console", tostring(e), T.bronzeHi)
statTick(true)
if S.detailErr then toast("Error: " .. tostring(e):sub(1, 70)) end
end
end)
if not silent then toast("Executed") end
if S.minRun and not silent and S.doMin then task.defer(S.doMin) end
end
local pageItems = {}
local pageMap = {}
local newTab, showPage
local function section(parent, str, order)
return text(parent, str:upper(), 10, "SemiBold", T.muted, {Size = UDim2.new(1, 0, 0, 14), LayoutOrder = order or 0})
end
local function split(title)
local page = group(pages, {})
local side = new("Frame", {Size = UDim2.new(0, SIDE_W, 1, 0), BackgroundColor3 = T.side, BorderSizePixel = 0, Parent = page})
FX.sideSkin(side)
new("Frame", {Size = UDim2.new(0, 1, 1, 0), Position = UDim2.new(1, -1, 0, 0), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = side})
text(side, title, 17, "Bold", T.text, {Position = UDim2.fromOffset(14, 8), Size = UDim2.new(1, -28, 0, 24)})
new("Frame", {Position = UDim2.fromOffset(16, 36), Size = UDim2.fromOffset(24, 2), BackgroundColor3 = T.gold, BorderSizePixel = 0, Parent = side}, {round(1)})
local api = {page = page, side = side}
local list = scroller(side, {Position = UDim2.fromOffset(6, 48), Size = UDim2.new(1, -12, 1, -54), ScrollBarThickness = 0}, {pad(2, 2), vlist(3)})
api.list = list
local body = new("Frame", {Position = UDim2.fromOffset(SIDE_W, 0), Size = UDim2.new(1, -SIDE_W, 1, 0), BackgroundTransparency = 1, Parent = page})
list.ZIndex = 2
local views, btns, refresh, vitems, n = {}, {}, {}, {}, 0
function api.add(name, builder, iconName)
n += 1
local item = FX.sideItem(list, name, iconName or "file", {order = n})
local view = group(body, {})
local r = builder(view)
if type(r) == "function" then refresh[name] = r end
views[name] = view
btns[name] = {b = item.b, ic = item.ic, lbl = item.lbl, idx = n, item = item}
item.b.Activated:Connect(function() api.select(name) end)
end
function api.select(name)
for k, o in pairs(btns) do o.item.setActive(k == name) end
if refresh[name] then refresh[name]() end
swap(vitems, views[name])
end
pageMap[title] = page
return api
end
local home = split("Home")
FX.accountPage = split("Account")
FX.settingsPage = split("Settings")
home.add("Overview", function(view)
local sc = scroller(view, {}, {pad(14), vlist(12)})
local CENTER = Enum.TextXAlignment.Center
local hero = new("Frame", {
Size = UDim2.new(1, 0, 0, 158), BackgroundColor3 = T.glow, BorderSizePixel = 0, LayoutOrder = 1,
ClipsDescendants = true, Parent = sc,
}, {round(16), stroke(T.bronzeLo, 1)})
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(150, 150, 150)), Parent = hero})
new("Frame", {
Position = UDim2.fromOffset(-50, -80), Size = UDim2.fromOffset(190, 190), BackgroundColor3 = T.bronze,
BackgroundTransparency = .88, BorderSizePixel = 0, Parent = hero,
}, {round(95)})
new("Frame", {
AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(1, 50, 1, 60), Size = UDim2.fromOffset(190, 190),
BackgroundColor3 = T.bronze, BackgroundTransparency = .92, BorderSizePixel = 0, Parent = hero,
}, {round(95)})
local logo = logoImage({AnchorPoint = Vector2.new(.5, 0), Size = UDim2.fromOffset(62, 62), Position = UDim2.new(.5, 0, 0, 12), Parent = hero})
pcall(function()
TweenService:Create(logo, TweenInfo.new(2.4, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true), {Position = UDim2.new(.5, 0, 0, 18)}):Play()
end)
text(hero, "Welcome to " .. NAME, 20, "Bold", T.text, {Position = UDim2.fromOffset(0, 76), Size = UDim2.new(1, 0, 0, 26), TextXAlignment = CENTER})
text(hero, "Script execution environment", 11, "Regular", T.muted, {Position = UDim2.fromOffset(0, 103), Size = UDim2.new(1, 0, 0, 16), TextXAlignment = CENTER})
local who = new("Frame", {
AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 126), Size = UDim2.fromOffset(0, 22),
AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = T.bg, BackgroundTransparency = .35, BorderSizePixel = 0, Parent = hero,
}, {round(11), stroke(T.bronzeLo, 1), pad(10, 0), hlist(6)})
new("Frame", {Size = UDim2.fromOffset(6, 6), BackgroundColor3 = T.gold, BorderSizePixel = 0, LayoutOrder = 1, Parent = who}, {round(3)})
local whoLbl = text(who, "Signed in as " .. I18N.shownName(), 10, "SemiBold", T.muted, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 22), LayoutOrder = 2})
I18N.watchers[#I18N.watchers + 1] = function() whoLbl.Text = "Signed in as " .. I18N.shownName() end
local row = new("Frame", {Size = UDim2.new(1, 0, 0, 70), BackgroundTransparency = 1, LayoutOrder = 2, Parent = sc}, {hlist(8)})
local function stat(title, value, color, ico)
local c = new("Frame", {Size = UDim2.new(1 / 3, -6, 1, 0), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, Parent = row}, {round(12), stroke(T.line)})
FX.chip(c, ico, 22, color, UDim2.new(1, -30, 0, 8))
text(c, title:upper(), 9, "SemiBold", T.muted, {Position = UDim2.fromOffset(12, 11), Size = UDim2.new(1, -44, 0, 12)})
return text(c, value, 18, "Bold", color or T.text, {Position = UDim2.fromOffset(12, 33), Size = UDim2.new(1, -20, 0, 26)})
end
stat("Version", VERSION, T.tan, "code")
stat("Status", "Ready", T.gold, "bolt")
execLabel = stat("Executions", "0", T.text, "play")
section(sc, "Quick start", 3)
local grid = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 4, Parent = sc}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -4, 0, 58), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local function goPage(name) if showPage then showPage(name) end end
local TILES = {
{"wand", "New script", "Blank tab in the editor", function() if newTab then newTab("New script", "") end goPage("Editor") end},
{"compass", "Script Hub", "Browse community scripts", function() goPage("Scripts") end},
{"tree", "Explorer", "Inspect game instances", function() goPage("Dex") end},
{"gear", "Settings", "Theme, sounds and more", function() goPage("Settings") end},
}
for i, t in ipairs(TILES) do
FX.card(grid, {order = i, height = 58, icon = t[1], title = t[2], sub = t[3], onClick = t[4]})
end
local cols = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 5, Parent = sc}, {hlist(8, Enum.VerticalAlignment.Top)})
local function column(order, title, ico)
local col = new("Frame", {Size = UDim2.new(.5, -4, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = order, Parent = cols}, {vlist(6)})
local h = new("Frame", {Size = UDim2.new(1, 0, 0, 18), BackgroundTransparency = 1, LayoutOrder = 0, Parent = col})
local hi = icon(h, ico, 13, T.tan, 1.5)
hi.holder.Position = UDim2.fromOffset(0, 2)
text(h, title:upper(), 10, "SemiBold", T.muted, {Position = UDim2.fromOffset(20, 0), Size = UDim2.new(1, -20, 1, 0)})
return col
end
local recentCol = column(1, "Recent", "history")
local savedCol = column(2, "Saved scripts", "star")
local function clearCol(col)
for _, c in ipairs(col:GetChildren()) do
if c:IsA("GuiObject") and c.LayoutOrder > 0 then c:Destroy() end
end
end
local function emptyCard(col, msg)
local f = new("Frame", {Size = UDim2.new(1, 0, 0, 46), BackgroundTransparency = 1, LayoutOrder = 1, Parent = col}, {round(12), stroke(T.line)})
f:FindFirstChildOfClass("UIStroke").Transparency = .35
text(f, msg, 10, "Regular", T.muted, {Size = UDim2.fromScale(1, 1), TextXAlignment = CENTER})
end
local function fill()
clearCol(recentCol)
clearCol(savedCol)
local n = 0
for _, s in ipairs(recents) do
if n >= 3 then break end
n = n + 1
FX.card(recentCol, {
order = n, height = 46, icon = "file", iconColor = T.tan, title = s.name, sub = #s.code .. " chars", raw = true,
onClick = function() if newTab then newTab(s.name, s.code) end goPage("Editor") end,
})
end
if n == 0 then emptyCard(recentCol, "Nothing here yet") end
local m = 0
for _, e in ipairs(Store.saved or {}) do
if m >= 3 then break end
m = m + 1
local notes = tostring(e.notes or ""):gsub("\n", " ")
FX.card(savedCol, {
order = m, height = 46, icon = "star", iconColor = T.gold, title = tostring(e.title or "Untitled"),
sub = notes ~= "" and notes or "No notes", raw = true,
onClick = function() if newTab then newTab(tostring(e.title or "Saved"), tostring(e.code or "")) end goPage("Editor") end,
})
end
if m == 0 then emptyCard(savedCol, "Nothing here yet") end
end
fill()
local tip = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.cardTop,
BorderSizePixel = 0, LayoutOrder = 6, Parent = sc,
}, {round(12), stroke(T.line), pad(12), hlist(10, Enum.VerticalAlignment.Top)})
local tipChip = FX.chip(tip, "bolt", 26, T.gold)
tipChip.LayoutOrder = 1
text(tip, "Dica: arraste a barra superior para mover a janela. Use o botão com a logo para mostrar ou ocultar.", 11, "Regular", T.muted,
{TextWrapped = true, AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, -38, 0, 0), LayoutOrder = 2})
local foot = new("Frame", {Size = UDim2.new(1, 0, 0, 20), BackgroundTransparency = 1, LayoutOrder = 7, Parent = sc})
new("Frame", {Position = UDim2.fromOffset(2, 7), Size = UDim2.fromOffset(7, 7), BackgroundColor3 = Color3.fromRGB(112, 200, 130), BorderSizePixel = 0, Parent = foot}, {round(4)})
text(foot, "Runtime: Ready", 10, "Medium", T.muted, {Position = UDim2.fromOffset(16, 0), Size = UDim2.new(.5, -16, 1, 0)})
local exName = "Unknown"
pcall(function() if identifyexecutor then exName = tostring((identifyexecutor())) end end)
text(foot, exName, 10, "Medium", T.muted, {Position = UDim2.fromScale(.5, 0), Size = UDim2.fromScale(.5, 1), TextXAlignment = Enum.TextXAlignment.Right, NoI18N = true})
return fill
end, "layers")
home.add("My Scripts", function(view)
local saved = Store.saved or {}
Store.saved = saved
local selectedId
local root = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = view})
local listPage = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = root})
local editPage = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Visible = false, Parent = root})
local listScroll = scroller(listPage, {Size = UDim2.fromScale(1, 1)}, {pad(14), vlist(10)})
local heading = new("Frame", {Size = UDim2.new(1, 0, 0, 46), BackgroundTransparency = 1, LayoutOrder = 1, Parent = listScroll})
local headingIcon = icon(heading, "filetext", 18, T.tan)
headingIcon.holder.Position = UDim2.fromOffset(0, 2)
text(heading, "My Scripts", 16, "Bold", T.text, {Position = UDim2.fromOffset(25, 0), Size = UDim2.new(1, -115, 0, 22)})
text(heading, "Your personal script library", 11, "Regular", T.muted, {Position = UDim2.fromOffset(25, 24), Size = UDim2.new(1, -35, 0, 15)})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(1, 0, 0, 2), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = heading})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(0, 42, 0, 2), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = heading})
local function button(parent, label, pos, size, primary, callback)
local b = new("TextButton", {Position = pos, Size = size, BackgroundColor3 = primary and T.bronze or T.panel2, BorderSizePixel = 0, Text = label, TextColor3 = T.text, TextSize = 11, FontFace = F.SemiBold, AutoButtonColor = false, Parent = parent}, {round(6), stroke(primary and T.bronzeHi or T.line)})
hoverFx(b, primary and T.bronze or T.panel2, primary and T.bronzeHi or T.panel); pressFx(b, .96); b.Activated:Connect(callback); return b
end
local cards = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 2, Parent = listScroll}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -4, 0, 58), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder})
})
local editorScroll = scroller(editPage, {Size = UDim2.fromScale(1, 1)}, {pad(12), vlist(8)})
local editorHeader = new("Frame", {Size = UDim2.new(1, 0, 0, 40), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 1, Parent = editorScroll}, {round(8), stroke(T.line)})
local switchSubPage
button(editorHeader, "< Back", UDim2.fromOffset(7, 7), UDim2.fromOffset(62, 26), false, function() switchSubPage(false) end)
local editIcon = icon(editorHeader, "code", 16, T.tan)
editIcon.holder.Position = UDim2.fromOffset(79, 12)
text(editorHeader, "Edit Script", 14, "Bold", T.text, {Position = UDim2.fromOffset(102, 9), Size = UDim2.new(1, -110, 0, 22)})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(1, 0, 0, 2), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = editorHeader})
local function makeInput(parent, placeholder, height, multi)
local field = new("TextBox", {Size = UDim2.new(1, 0, 0, height), BackgroundColor3 = T.panel, BorderSizePixel = 0,
Text = "", PlaceholderText = placeholder, PlaceholderColor3 = T.muted, TextColor3 = T.text,
TextSize = 12, FontFace = multi and MONO or F.Regular, TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = multi and Enum.TextYAlignment.Top or Enum.TextYAlignment.Center, ClearTextOnFocus = false,
MultiLine = multi or false, Parent = parent}, {round(6), stroke(T.line), pad(8, 6)})
local edge = field:FindFirstChildOfClass("UIStroke")
field.Focused:Connect(function() tween(field, {BackgroundColor3 = T.panel2}, .16); if edge then tween(edge, {Color = T.tan, Thickness = 1.4}, .18) end end)
field.FocusLost:Connect(function() tween(field, {BackgroundColor3 = T.panel}, .18); if edge then tween(edge, {Color = T.line, Thickness = 1}, .2) end end)
return field
end
local titleBox = makeInput(editorScroll, "Script title", 32, false); titleBox.LayoutOrder = 2
local notesBox = makeInput(editorScroll, "Notes or description (optional)", 54, true); notesBox.LayoutOrder = 3
local codeBox = makeInput(editorScroll, "Paste or write Luau code here...", 210, true); codeBox.LayoutOrder = 4; codeBox.TextWrapped = false
local editorActions = new("Frame", {Size = UDim2.new(1, 0, 0, 30), BackgroundTransparency = 1, LayoutOrder = 5, Parent = editorScroll}, {hlist(6)})
local function persist()
Store.saved = saved
local ok = jsonWrite(PATH.saved, saved)
if not ok then toast("Could not save to file") end
return ok
end
local pageToken = 0
switchSubPage = function(showEditor)
pageToken += 1
local token = pageToken
local outgoing = showEditor and listPage or editPage
local incoming = showEditor and editPage or listPage
incoming.Visible = true
FX.cascade(incoming)
incoming.Position = UDim2.fromOffset(showEditor and 14 or -14, 0)
tween(incoming, {Position = UDim2.fromOffset(0, 0)}, .28, Enum.EasingStyle.Quint)
tween(outgoing, {Position = UDim2.fromOffset(showEditor and -8 or 8, 0)}, .18, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
task.delay(.3, function() if pageToken == token then outgoing.Visible = false; outgoing.Position = UDim2.fromOffset(0, 0) end end)
end
local function openEditor(entry)
selectedId = entry and entry.id or nil
titleBox.Text = entry and (entry.title or "") or ""
notesBox.Text = entry and (entry.notes or "") or ""
codeBox.Text = entry and (entry.code or "") or ""
switchSubPage(true)
end
local function refreshList()
for _, child in ipairs(cards:GetChildren()) do if child:IsA("GuiObject") and not child:IsA("UIGridLayout") then child:Destroy() end end
if #saved == 0 then
local empty = new("Frame", {Size = UDim2.new(1, 0, 0, 58), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 1, Parent = cards}, {round(8), stroke(T.line)})
text(empty, "No scripts yet. Tap + New to create your first one.", 11, "Regular", T.muted, {Position = UDim2.fromOffset(8, 8), Size = UDim2.new(1, -24, 1, -16), TextWrapped = true})
return
end
for i, entry in ipairs(saved) do
local card = new("Frame", {BackgroundColor3 = T.panel, BackgroundTransparency = 1, BorderSizePixel = 0, LayoutOrder = i, Parent = cards}, {round(8), stroke(T.line)})
local cardScale = new("UIScale", {Scale = .96, Parent = card})
card.MouseEnter:Connect(function()
tween(card, {BackgroundColor3 = T.panel2}, .16)
tween(cardScale, {Scale = 1.025}, .2, Enum.EasingStyle.Back)
end)
card.MouseLeave:Connect(function()
tween(card, {BackgroundColor3 = T.panel}, .2)
tween(cardScale, {Scale = 1}, .2)
end)
task.delay(math.min(i * .045, .32), function()
if card.Parent then
tween(card, {BackgroundTransparency = 0}, .26)
tween(cardScale, {Scale = 1}, .32, Enum.EasingStyle.Back)
end
end)
new("Frame", {Position = UDim2.fromOffset(0, 0), Size = UDim2.new(1, 0, 0, 2), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = card})
local scriptIcon = icon(card, "file", 15, T.tan)
scriptIcon.holder.Position = UDim2.fromOffset(9, 11)
text(card, tostring(entry.title or "Untitled Script"), 11, "SemiBold", T.text, {Position = UDim2.fromOffset(30, 8), Size = UDim2.new(1, -62, 0, 17), TextTruncate = Enum.TextTruncate.AtEnd})
text(card, tostring(entry.notes or "No notes"):gsub("\n", " "), 10, "Regular", T.muted, {Position = UDim2.fromOffset(30, 29), Size = UDim2.new(1, -62, 0, 14), TextTruncate = Enum.TextTruncate.AtEnd})
local arrow = new("TextButton", {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -5, .5, 0), Size = UDim2.fromOffset(24, 26), BackgroundColor3 = T.panel2, BorderSizePixel = 0, Text = "", Glass = true, Parent = card}, {round(6), stroke(T.line)})
local arrowIcon = icon(arrow, "chevR", 13, T.tan)
arrowIcon.holder.AnchorPoint = Vector2.new(.5, .5)
arrowIcon.holder.Position = UDim2.fromScale(.5, .5)
hoverFx(arrow, T.panel2, T.panel)
pressFx(arrow, .96)
arrow.Activated:Connect(function() openEditor(entry) end)
local open = new("TextButton", {Size = UDim2.new(1, -36, 1, 0), BackgroundTransparency = 1, Text = "", Parent = card})
open.Activated:Connect(function() openEditor(entry) end)
end
end
local newButton = button(heading, "New", UDim2.new(1, -78, 0, 4), UDim2.fromOffset(78, 28), true, function() openEditor(nil) end)
local newIcon = icon(newButton, "plus", 13, T.text)
newIcon.holder.Position = UDim2.fromOffset(8, 7)
newButton.TextXAlignment = Enum.TextXAlignment.Center
newButton.Text = " New"
local function action(label, primary, callback)
local b = new("TextButton", {Size = UDim2.new(1/3, -4, 1, 0), BackgroundColor3 = primary and T.bronze or T.panel2, BorderSizePixel = 0, Text = label, TextColor3 = T.text, TextSize = 11, FontFace = F.SemiBold, AutoButtonColor = false, Parent = editorActions}, {round(6), stroke(primary and T.bronzeHi or T.line)})
hoverFx(b, primary and T.bronze or T.panel2, primary and T.bronzeHi or T.panel); pressFx(b, .96)
local iconName = label == "Save" and "save" or (label == "Run" and "play" or "trash")
local actionIcon = icon(b, iconName, 12, T.text)
actionIcon.holder.Position = UDim2.new(.5, -24, .5, -6)
b.Text = " " .. label
b.Activated:Connect(callback); return b
end
action("Save", true, function()
local title = titleBox.Text:gsub("^%s+", ""):gsub("%s+$", "")
if title == "" then toast("Enter a script title"); return end
if codeBox.Text:gsub("%s", "") == "" then toast("Add some Luau code"); return end
local entry
for _, item in ipairs(saved) do if item.id == selectedId then entry = item; break end end
if not entry then entry = {id = HttpService:GenerateGUID(false)}; table.insert(saved, 1, entry) end
entry.title, entry.notes, entry.code = title, notesBox.Text, codeBox.Text
persist(); refreshList(); toast("Script saved")
switchSubPage(false)
end)
action("Run", false, function()
if codeBox.Text:gsub("%s", "") == "" then toast("Script is empty"); return end
runCode(codeBox.Text, titleBox.Text ~= "" and titleBox.Text or "Saved Script")
end)
action("Delete", false, function()
if not selectedId then toast("Save this script before deleting it"); return end
for i, item in ipairs(saved) do if item.id == selectedId then table.remove(saved, i); break end end
persist(); selectedId = nil; refreshList(); switchSubPage(false); toast("Script deleted")
end)
refreshList()
Store.refreshSaved = refreshList
return refreshList
end, "filetext")
FX.accountPage.add("Account", function(view)
local sc = scroller(view, {}, {pad(14), vlist(10)})
local c = new("Frame", {Size = UDim2.new(1, 0, 0, 76), BackgroundColor3 = T.glow, BorderSizePixel = 0, LayoutOrder = 1, Parent = sc}, {round(14), stroke(T.bronzeLo, 1)})
avatar(c, 48, UDim2.fromOffset(14, 14))
text(c, lp.DisplayName, 15, "Bold", T.text, {Position = UDim2.fromOffset(74, 17), Size = UDim2.new(1, -86, 0, 20)})
text(c, "@" .. lp.Name .. " · ID " .. lp.UserId, 10, "Regular", T.muted, {Position = UDim2.fromOffset(74, 40), Size = UDim2.new(1, -86, 0, 14)})
local grid = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 2, Parent = sc}, {
new("UIGridLayout", {CellSize = UDim2.new(1 / 3, -6, 0, 62), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local vals = {}
local order = 0
local function card(key, title, color, iconName)
order += 1
local f = new("Frame", {BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = order, Parent = grid}, {round(12), stroke(T.line)})
FX.chip(f, iconName, 20, color or T.tan, UDim2.new(1, -28, 0, 8))
text(f, title:upper(), 9, "SemiBold", T.muted, {Position = UDim2.fromOffset(11, 10), Size = UDim2.new(1, -42, 0, 12)})
vals[key] = text(f, "-", 17, "Bold", color or T.text, {Position = UDim2.fromOffset(11, 30), Size = UDim2.new(1, -18, 0, 24), TextTruncate = Enum.TextTruncate.AtEnd})
end
card("session", "Run this session", T.tan, "play")
card("total", "Total executed", T.gold, "bolt")
card("errors", "Errors", Color3.fromRGB(226, 120, 100), "x")
card("cloud", "Cloud scripts", T.tan, "cloud")
card("auto", "Auto-execute", T.tan, "refresh")
card("liked", "Liked scripts", T.gold, "heart")
card("sessions", "Sessions", T.text, "history")
card("time", "Session time", T.text, "history")
card("age", "Account age", T.text, "user")
local info = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = 3, Parent = sc}, {round(12), stroke(T.line), pad(14, 10), vlist(5)})
local infoVals = {}
local function row(key, label)
local r = new("Frame", {Size = UDim2.new(1, 0, 0, 16), BackgroundTransparency = 1, LayoutOrder = #info:GetChildren(), Parent = info})
text(r, label, 10, "Medium", T.muted, {Size = UDim2.new(.35, 0, 1, 0)})
infoVals[key] = text(r, "-", 10, "SemiBold", T.text, {Position = UDim2.fromScale(.35, 0), Size = UDim2.fromScale(.65, 1), TextXAlignment = Enum.TextXAlignment.Right, TextTruncate = Enum.TextTruncate.AtEnd})
end
row("exec", "Executor")
row("game", "Game")
row("place", "Place ID")
row("first", "First used")
row("ping", "Ping")
local gameName
task.spawn(function()
local ok, inf = pcall(function() return game:GetService("MarketplaceService"):GetProductInfo(game.PlaceId) end)
gameName = ok and inf and inf.Name or ("Place " .. game.PlaceId)
end)
local execName = "Unknown"
pcall(function() if identifyexecutor then execName = tostring((identifyexecutor())) end end)
local function fmtTime(sec)
sec = math.floor(sec)
local h, m = math.floor(sec / 3600), math.floor(sec % 3600 / 60)
if h > 0 then return ("%dh %02dm"):format(h, m) end
return ("%dm %02ds"):format(m, sec % 60)
end
local function liked() local n = 0 for _ in pairs(Store.likes) do n += 1 end return n end
local function refresh()
vals.session.Text = tostring(execCount)
vals.total.Text = tostring(Stats.total)
vals.errors.Text = tostring(Stats.errors)
vals.cloud.Text = tostring(#Store.cloud)
vals.auto.Text = tostring(#Store.auto)
vals.liked.Text = tostring(liked())
vals.sessions.Text = tostring(Stats.sessions)
vals.time.Text = fmtTime(os.clock() - sessionStart)
vals.age.Text = lp.AccountAge >= 365 and ("%.1f yrs"):format(lp.AccountAge / 365) or (lp.AccountAge .. " days")
infoVals.exec.Text = execName
infoVals.game.Text = gameName or "..."
infoVals.place.Text = tostring(game.PlaceId)
infoVals.first.Text = os.date("%d/%m/%Y", Stats.first)
local okp, ping = pcall(function() return game:GetService("Stats").Network.ServerStatsItem["Data Ping"]:GetValue() end)
infoVals.ping.Text = okp and (math.floor(ping) .. " ms") or "n/a"
end
Stats.refresh = function() if view.Visible then refresh() end end
task.spawn(function()
while view.Parent do
if view.Visible then refresh() end
task.wait(1)
end
end)
return refresh
end, "user")
FX.accountPage.add("Accounts", function(view)
local META = DB_FOLDER .. "/acc_meta.json"
local assets = FX.accAssets or {}
FX.accAssets = assets
local function logoPath(key) return PATH.img .. "/acclogo_" .. key .. ".dat" end
local function getLogo(key, url, cb)
if type(url) ~= "string" or url == "" then cb(nil) return end
local c = assets[key]
if c and c.url == url then cb(c.asset) return end
task.spawn(function()
local a = toAsset(logoPath(key) .. FX.cloud.cs(url), function() return game:HttpGet(url) end)
if a then assets[key] = {url = url, asset = a} end
cb(a)
end)
end
local function activeKey()
local o = (jsonRead(DB_FOLDER .. "/active.json", {}) or {}).owner
return o or tostring(I18N.user or I18N.session or ""):lower()
end
local function badgeLogo(badge, letter, key, meta, size)
local url = meta[key] and meta[key].logo
if not url then FX.cloud.avatar(badge, letter, key, size) return end
getLogo(key, url, function(asset)
if not asset or not badge.Parent then return end
letter.Visible = false
new("ImageLabel", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Image = asset, ScaleType = Enum.ScaleType.Crop, Parent = badge}, {round(size / 2)})
end)
end
local sc = scroller(view, {}, {pad(14), vlist(10)})
text(sc, "Accounts on this device", 16, "Bold", T.text, {Size = UDim2.new(1, 0, 0, 22), LayoutOrder = 1})
text(sc, "Tap a card to switch. Each account keeps its own data.", 11, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 16), LayoutOrder = 2, TextWrapped = true})
local panelHost = new("Frame", {Size = UDim2.new(1, 0, 0, 124), BackgroundTransparency = 1, LayoutOrder = 3, Parent = sc})
local grid = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 4, Parent = sc}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -4, 0, 72), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local rebuild
local function buildPanel(meta, list, owner)
for _, c in ipairs(panelHost:GetChildren()) do c:Destroy() end
local me
for _, a in ipairs(list) do if a.key == owner then me = a end end
if not me then panelHost.Visible = false return end
panelHost.Visible = true
local p = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.glow, BorderSizePixel = 0, Parent = panelHost}, {round(12), stroke(T.bronzeLo, 1)})
local badge = new("Frame", {Size = UDim2.fromOffset(44, 44), Position = UDim2.fromOffset(12, 10), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = p}, {round(22)})
local letter = text(badge, me.name:sub(1, 1):upper(), 20, "Bold", T.dark, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true})
badgeLogo(badge, letter, owner, meta, 44)
text(p, "Customize account", 13, "Bold", T.text, {Position = UDim2.fromOffset(66, 12), Size = UDim2.new(1, -78, 0, 18)})
text(p, me.name, 10, "Regular", T.muted, {Position = UDim2.fromOffset(66, 32), Size = UDim2.new(1, -78, 0, 14), NoI18N = true})
local box = new("TextBox", {Position = UDim2.fromOffset(12, 62), Size = UDim2.new(1, -24, 0, 26), BackgroundColor3 = T.panel, BorderSizePixel = 0,
Text = (meta[owner] and meta[owner].logo) or "", PlaceholderText = "Paste an image link (https://...)", PlaceholderColor3 = T.muted, TextColor3 = T.text,
TextSize = 11, FontFace = F.Regular, TextXAlignment = Enum.TextXAlignment.Left, ClearTextOnFocus = false, ClipsDescendants = true, Parent = p}, {round(6), stroke(T.line), pad(8, 4)})
local function mini(label, x, w, primary, cb)
local b = new("TextButton", {Position = UDim2.fromOffset(x, 94), Size = UDim2.fromOffset(w, 24), BackgroundColor3 = primary and T.bronze or T.panel2, BorderSizePixel = 0, Text = label, TextColor3 = T.text, TextSize = 11, FontFace = F.SemiBold, AutoButtonColor = false, Parent = p}, {round(6)})
pressFx(b, .96)
b.Activated:Connect(cb)
end
mini("Apply", 12, 80, true, function()
local url = box.Text:gsub("%s", "")
if not url:match("^https?://") then toast("Paste an image link (https://...)") return end
pcall(function() if delfile and isfile(logoPath(owner)) then delfile(logoPath(owner)) end end)
assets[owner] = nil
local m = jsonRead(META, {})
m[owner] = m[owner] or {}
m[owner].logo = url
jsonWrite(META, m)
getLogo(owner, url, function(a)
if a then
task.spawn(function() FX.cloud.call("PATCH", "users/" .. owner, {logo = url}) end)
toast("Logo updated")
else
m[owner].logo = nil
jsonWrite(META, m)
toast("Could not load the logo")
end
if rebuild then rebuild() end
end)
end)
mini("Remove logo", 100, 100, false, function()
pcall(function() if delfile and isfile(logoPath(owner)) then delfile(logoPath(owner)) end end)
assets[owner] = nil
local m = jsonRead(META, {})
if m[owner] then m[owner].logo = nil end
jsonWrite(META, m)
task.spawn(function() FX.cloud.call("PATCH", "users/" .. owner, {logo = ""}) end)
toast("Logo removed")
if rebuild then rebuild() end
end)
end
rebuild = function()
for _, c in ipairs(grid:GetChildren()) do if c:IsA("GuiObject") then c:Destroy() end end
local list = {}
local okDb, db = pcall(FX.dbRead)
for key, u in pairs(okDb and db and db.users or {}) do list[#list + 1] = {key = key, name = u.name or key, created = u.created} end
do
local have = {}
for _, a in ipairs(list) do have[a.key] = true end
for key, u in pairs(FX.cloud.users or {}) do
if type(u) == "table" and not have[key] then list[#list + 1] = {key = key, name = u.name or key, created = u.created, remote = true} end
end
end
table.sort(list, function(a, b) return a.key < b.key end)
local owner = activeKey()
local meta = jsonRead(META, {})
buildPanel(meta, list, owner)
for i, a in ipairs(list) do
local on = a.key == owner
local card = new("TextButton", {
BackgroundColor3 = on and T.glow or T.cardTop, AutoButtonColor = false, Text = "", BorderSizePixel = 0, LayoutOrder = i, Parent = grid,
}, {round(12), stroke(on and T.gold or T.line, on and 1.5 or 1)})
FX.cardSkin(card)
if on then
FX.pill(card, "Active", T.gold, {AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -10, 0, 12)})
elseif not a.remote then
local chv = icon(card, "chevR", 14, T.muted, 1.5)
chv.holder.AnchorPoint = Vector2.new(1, .5)
chv.holder.Position = UDim2.new(1, -10, .5, 0)
end
local badge = new("Frame", {Size = UDim2.fromOffset(40, 40), Position = UDim2.fromOffset(12, 16), BackgroundColor3 = on and T.bronze or T.panel2, BorderSizePixel = 0, Parent = card}, {round(20)})
local letter = text(badge, a.name:sub(1, 1):upper(), 18, "Bold", on and T.dark or T.text, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true})
badgeLogo(badge, letter, a.key, meta, 40)
text(card, a.name, 13, "Bold", T.text, {Position = UDim2.fromOffset(60, 15), Size = UDim2.new(1, on and -128 or -88, 0, 18), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
text(card, on and "Active" or (a.remote and "Online profile") or (a.created and os.date("%d/%m/%Y", a.created) or "Tap to switch"), 10, "Regular", on and T.gold or T.muted, {Position = UDim2.fromOffset(60, 37), Size = UDim2.new(1, -88, 0, 14)})
pressFx(card, .96)
card.Activated:Connect(function()
if on then return end
if a.remote then toast(a.name .. " (online profile)") return end
if FX.accSwitch and FX.accSwitch(a.name) then toast("Switched to " .. a.name) end
end)
end
end
FX.accRefreshCards = function() if view.Parent then rebuild() end end
rebuild()
local function pull() task.spawn(function() if FX.cloud.fetchUsers() and view.Parent then rebuild() end end) end
pull()
return function() rebuild() pull() end
end, "layers")
FX.accountPage.add("Vault", function(view)
local VF = DB_FOLDER .. "/vault_"
local V, unlocked, selectedId, route = {items = {}}, false, nil, nil
local function ownerKey()
local o = (jsonRead(DB_FOLDER .. "/active.json", {}) or {}).owner
return o or tostring(I18N.user or I18N.session or "default"):lower()
end
local curKey = ownerKey()
local function load()
curKey = ownerKey()
V = jsonRead(VF .. curKey .. ".json", nil) or {items = {}}
V.items = V.items or {}
end
local function save() return jsonWrite(VF .. curKey .. ".json", V) end
load()
local function secretChars(value)
local chars = {}
local str = tostring(value or "")
local ok = pcall(function()
for _, codepoint in utf8.codes(str) do
chars[#chars + 1] = utf8.char(codepoint)
end
end)
if not ok then
chars = {}
for i = 1, #str do chars[#chars + 1] = str:sub(i, i) end
end
return chars
end
local function secretMask(value)
return string.rep("●", #secretChars(value))
end
local function secretLimit(value, maxChars)
local chars = secretChars(value)
if #chars > maxChars then
for i = maxChars + 1, #chars do chars[i] = nil end
end
return table.concat(chars)
end
local root = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = view})
local function mkPage() return new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Visible = false, Parent = root}) end
local pages = {lock = mkPage(), list = mkPage(), edit = mkPage(), set = mkPage(), recover = mkPage()}
local function go(name)
for k, p in pairs(pages) do
if k == name then
if not p.Visible then p.Visible = true; FX.cascade(p) end
else
p.Visible = false
end
end
end
local function button(parent, label, pos, size, primary, cb)
local b = new("TextButton", {Position = pos, Size = size, BackgroundColor3 = primary and T.bronze or T.panel2, BorderSizePixel = 0, Text = label, TextColor3 = T.text, TextSize = 11, FontFace = F.SemiBold, AutoButtonColor = false, Parent = parent}, {round(6)})
hoverFx(b, primary and T.bronze or T.panel2, primary and T.bronzeHi or T.panel)
pressFx(b, .96)
b.Activated:Connect(cb)
return b
end
local function makeInput(parent, placeholder, height, multi)
local field = new("TextBox", {Size = UDim2.new(1, 0, 0, height), BackgroundColor3 = T.panel, BorderSizePixel = 0,
Text = "", PlaceholderText = placeholder, PlaceholderColor3 = T.muted, TextColor3 = T.text,
TextSize = 12, FontFace = multi and MONO or F.Regular, TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = multi and Enum.TextYAlignment.Top or Enum.TextYAlignment.Center, ClearTextOnFocus = false,
MultiLine = multi or false, Parent = parent}, {round(6), stroke(T.line), pad(8, 6)})
local edge = field:FindFirstChildOfClass("UIStroke")
field.Focused:Connect(function() tween(field, {BackgroundColor3 = T.panel2}, .16); if edge then tween(edge, {Color = T.tan, Thickness = 1.4}, .18) end end)
field.FocusLost:Connect(function() tween(field, {BackgroundColor3 = T.panel}, .18); if edge then tween(edge, {Color = T.line, Thickness = 1}, .2) end end)
return field
end
local function chip(parent, iconName, label, primary, cb, order, fill)
local b = new("TextButton", {
Size = UDim2.fromOffset(0, 32), AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = primary and T.bronze or T.panel2,
BorderSizePixel = 0, Text = "", AutoButtonColor = false, LayoutOrder = order or 0, Parent = parent,
}, {round(9), stroke(primary and T.bronzeHi or T.line)})
local inner = new("Frame", {BackgroundTransparency = 1, Size = UDim2.new(0, 0, 1, 0), AutomaticSize = Enum.AutomaticSize.X, Parent = b}, {hlist(7)})
if fill then
b.AutomaticSize = Enum.AutomaticSize.None
b.Size = fill
inner.AnchorPoint, inner.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
else
new("UIPadding", {PaddingLeft = UDim.new(0, 11), PaddingRight = UDim.new(0, 11), Parent = b})
end
local ic = icon(inner, iconName, 14, T.text)
ic.holder.LayoutOrder = 1
local lbl = text(inner, label, 11, "SemiBold", T.text, {
Size = UDim2.new(0, 0, 1, 0), AutomaticSize = Enum.AutomaticSize.X, LayoutOrder = 2,
TextXAlignment = Enum.TextXAlignment.Center,
})
hoverFx(b, primary and T.bronze or T.panel2, primary and T.bronzeHi or T.panel)
pressFx(b, .96)
b.Activated:Connect(cb)
return b, lbl, ic
end
local function entryPad(parent, kind, order, onSubmit, fixedLength)
local o = {}
local isPassword = kind == "password"
local boxHeight = isPassword and 194 or (kind == "pattern" and 310 or 300)
local box = new("Frame", {
Size = UDim2.new(1, 0, 0, boxHeight), BackgroundColor3 = T.panel, BorderSizePixel = 0,
LayoutOrder = order, Parent = parent,
}, {round(14), stroke(T.line, 1)})
local title = kind == "pattern" and "Draw your pattern"
or (kind == "pin" and "Enter your PIN" or (isPassword and "Enter your password" or "Enter your number code"))
text(box, title, 14, "Bold", T.text, {
Position = UDim2.fromOffset(10, 10), Size = UDim2.new(1, -20, 0, 20),
TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 1,
})
local hintText = isPassword and "Use 8–64 characters. Letters, numbers and symbols are accepted."
or (kind == "pin" and "4–6 digits · Existing 4-digit PINs still work"
or (kind == "pattern" and "Connect at least 4 different dots" or "Use 4–16 digits"))
text(box, hintText, 10, "Regular", T.muted, {
Position = UDim2.fromOffset(10, 32), Size = UDim2.new(1, -20, 0, 18),
TextXAlignment = Enum.TextXAlignment.Center, TextWrapped = true,
})
local code, seq, nodes = "", {}, {}
local pinLength = kind == "pin" and (fixedLength or 6) or nil
local maxLen = isPassword and 64 or (kind == "pin" and pinLength or (kind == "number" and 16 or 12))
local shown = text(box, "", 18, "Bold", T.gold, {
Position = UDim2.fromOffset(10, 53), Size = UDim2.new(1, -20, 0, 24),
TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true,
})
local passwordField, maskLabel, revealButton, revealLbl, revealIcon
local passwordVisible, passwordBusy, passwordFocused = false, false, false
local function syncPasswordDisplay()
if not passwordField then return end
local hidden = not passwordVisible and #code > 0
if maskLabel then
maskLabel.Text = secretMask(code)
maskLabel.Visible = hidden
end
local textColor = passwordVisible and T.text or (passwordFocused and T.panel2 or T.panel)
if passwordField.TextColor3 ~= textColor then tween(passwordField, {TextColor3 = textColor}, .16) end
end
local function paint()
if kind == "pattern" then
shown.Text = #seq > 0 and string.rep("● ", #seq):sub(1, -2) or ""
for i, node in pairs(nodes) do
local selected = table.find(seq, i) ~= nil
node.BackgroundColor3 = selected and T.bronze or T.panel2
local edge = node:FindFirstChildOfClass("UIStroke")
if edge then edge.Color = selected and T.gold or T.line end
end
elseif kind == "pin" then
shown.Text = string.rep("●", #code) .. string.rep("○", pinLength - #code)
elseif isPassword then
shown.Text = ""
syncPasswordDisplay()
if revealButton then
revealLbl.Text = passwordVisible and "Hide" or "Show"
if revealIcon then revealIcon.swap(passwordVisible and "eyeoff" or "eye") end
end
else
shown.Text = string.rep("●", #code)
end
end
local function value()
return kind == "pattern" and table.concat(seq, "-") or code
end
local function valid()
if kind == "pattern" then return #seq >= 4 and #seq <= 9 end
if kind == "pin" then return fixedLength and #code == fixedLength or (not fixedLength and #code >= 4 and #code <= 6) end
if isPassword then local len = #secretChars(code); return len >= 8 and len <= 64 end
return #code >= 4 and #code <= 16
end
function o.reset()
code, seq, passwordVisible = "", {}, false
if passwordField then passwordField.Text = "" end
paint()
end
local function submit()
if not valid() then
local msg = kind == "pattern" and "Pattern needs at least 4 dots"
or (kind == "pin" and "PIN must have 4 to 6 digits"
or (isPassword and "Password must have at least 8 characters" or "Code must have 4 to 16 digits"))
toast(msg)
return
end
onSubmit(value())
end
if isPassword then
passwordField = makeInput(box, "Vault password", 42, false)
passwordField.Position = UDim2.new(0, 12, 0, 82)
passwordField.Size = UDim2.new(1, -24, 0, 42)
passwordField.TextXAlignment = Enum.TextXAlignment.Center
passwordField.TextSize = 14
passwordField.ZIndex = 2
maskLabel = text(box, "", 14, "Regular", T.text, {
Position = passwordField.Position, Size = passwordField.Size, ZIndex = 3,
TextXAlignment = Enum.TextXAlignment.Center, TextYAlignment = Enum.TextYAlignment.Center,
TextTruncate = Enum.TextTruncate.AtEnd, Active = false, NoI18N = true,
})
maskLabel.FontFace = F.Regular
maskLabel.Visible = false
passwordField.Focused:Connect(function() passwordFocused = true; syncPasswordDisplay() end)
passwordField.FocusLost:Connect(function() passwordFocused = false; syncPasswordDisplay() end)
passwordField:GetPropertyChangedSignal("Text"):Connect(function()
if passwordBusy then return end
local nextCode = secretLimit(passwordField.Text, maxLen)
if nextCode ~= passwordField.Text then
passwordBusy = true
passwordField.Text = nextCode
passwordBusy = false
end
code = nextCode
paint()
end)
local row = new("Frame", {Position = UDim2.new(0, 12, 0, 140), Size = UDim2.new(1, -24, 0, 32), BackgroundTransparency = 1, Parent = box}, {hlist(8)})
revealButton, revealLbl, revealIcon = chip(row, "eye", "Show", false, function()
passwordVisible = not passwordVisible
paint()
end, 1, UDim2.new(.34, -4, 1, 0))
button(row, "Clear", UDim2.new(), UDim2.new(.33, -4, 1, 0), false, function() o.reset() end)
button(row, "Continue", UDim2.new(), UDim2.new(.33, -4, 1, 0), true, submit)
elseif kind == "pattern" then
local grid = new("Frame", {
AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 82),
Size = UDim2.fromOffset(180, 180), BackgroundTransparency = 1, Parent = box,
}, {new("UIGridLayout", {CellSize = UDim2.fromOffset(52, 52), CellPadding = UDim2.fromOffset(12, 12), SortOrder = Enum.SortOrder.LayoutOrder})})
for i = 1, 9 do
local node = new("TextButton", {
BackgroundColor3 = T.panel2, Text = "", AutoButtonColor = false,
LayoutOrder = i, Parent = grid,
}, {round(26), stroke(T.line)})
nodes[i] = node
node.Activated:Connect(function()
if not table.find(seq, i) and #seq < 9 then
seq[#seq + 1] = i
paint()
end
end)
end
local row = new("Frame", {AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 270), Size = UDim2.fromOffset(180, 32), BackgroundTransparency = 1, Parent = box}, {hlist(8)})
button(row, "Clear", UDim2.new(), UDim2.fromOffset(86, 32), false, function() o.reset() end)
button(row, "Continue", UDim2.new(), UDim2.fromOffset(86, 32), true, submit)
else
local grid = new("Frame", {
AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 82),
Size = UDim2.fromOffset(208, 200), BackgroundTransparency = 1, Parent = box,
}, {new("UIGridLayout", {CellSize = UDim2.fromOffset(64, 44), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder})})
for i, key in ipairs({"1", "2", "3", "4", "5", "6", "7", "8", "9", "C", "0", "OK"}) do
local keyButton = new("TextButton", {
BackgroundColor3 = (key == "OK") and T.bronze or T.panel2, Text = key,
TextColor3 = T.text, TextSize = 16, FontFace = F.SemiBold, AutoButtonColor = false,
LayoutOrder = i, NoI18N = true, Parent = grid,
}, {round(9), stroke(key == "OK" and T.bronzeHi or T.line)})
pressFx(keyButton, .94)
keyButton.Activated:Connect(function()
if key == "C" then
code = ""
paint()
elseif key == "OK" then
submit()
elseif #code < maxLen then
code ..= key
paint()
if kind == "pin" and #code == pinLength then submit() end
end
end)
end
end
paint()
o.frame = box
return o
end
local lockHolder
local function buildLock()
if lockHolder then lockHolder:Destroy() end
lockHolder = scroller(pages.lock, {Size = UDim2.fromScale(1, 1)}, {pad(12, 30, 12, 20), vlist(8)})
local kind = V.lock.kind
text(lockHolder, "Vault locked", 16, "Bold", T.text, {Size = UDim2.new(1, 0, 0, 22), TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 1})
text(lockHolder, kind == "pattern" and "Draw your pattern to unlock" or (kind == "pin" and "Enter your PIN to unlock" or (kind == "password" and "Enter your vault password" or "Enter your number code to unlock")), 11, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 16), TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 2})
local pd
pd = entryPad(lockHolder, kind, 3, function(code)
if V.lock and FX.hashPass(V.lock.salt, kind .. ":" .. code) == V.lock.hash then
unlocked = true
route()
else
toast("Wrong code")
pd.reset()
end
end, V.lock.length or (kind == "pin" and 4 or nil))
end
local recHolder, buildSet
local function buildRecover()
if recHolder then recHolder:Destroy() end
recHolder = scroller(pages.recover, {Size = UDim2.fromScale(1, 1)}, {pad(12, 16, 12, 20), vlist(8)})
text(recHolder, "Recover your vault", 16, "Bold", T.text, {Size = UDim2.new(1, 0, 0, 22), TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 1})
text(recHolder, "Enter the recovery key you received when you set the lock", 11, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 30), TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 2})
local kb = makeInput(recHolder, "XXXX-XXXX-XXXX", 34, false)
kb.LayoutOrder, kb.TextXAlignment = 3, Enum.TextXAlignment.Center
local row = new("Frame", {Size = UDim2.new(1, 0, 0, 30), BackgroundTransparency = 1, LayoutOrder = 4, Parent = recHolder}, {hlist(6)})
button(row, "Back", UDim2.new(), UDim2.new(.5, -3, 1, 0), false, function() route() end)
button(row, "Unlock", UDim2.new(), UDim2.new(.5, -3, 1, 0), true, function()
local k = (kb.Text:upper():gsub("[^%w]", ""))
if not (V.lock and V.lock.rhash) then
toast("This lock has no recovery key")
elseif FX.hashPass(V.lock.salt, "rec:" .. k) == V.lock.rhash then
unlocked = true
toast("Recovered. Set a new lock")
buildSet()
go("set")
else
toast("Wrong recovery key")
end
end)
local erase
local armed = false
erase = button(recHolder, "Erase vault and remove lock", UDim2.new(), UDim2.new(1, 0, 0, 28), false, function()
if not armed then
armed = true
erase.Text = "Tap again to confirm"
task.delay(3, function()
armed = false
if erase.Parent then erase.Text = "Erase vault and remove lock" end
end)
return
end
V = {items = {}}
save()
unlocked = true
toast("Vault erased")
route()
end)
erase.LayoutOrder = 5
end
local forgot = new("TextButton", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -12, 0, 8), Size = UDim2.fromOffset(110, 20), BackgroundTransparency = 1,
AutoButtonColor = false, Text = "Forgot code?", TextSize = 11, FontFace = F.SemiBold, TextColor3 = T.muted, ZIndex = 5, Parent = pages.lock,
})
forgot.MouseEnter:Connect(function() tween(forgot, {TextColor3 = T.tan}, .15) end)
forgot.MouseLeave:Connect(function() tween(forgot, {TextColor3 = T.muted}, .2) end)
forgot.Activated:Connect(function() buildRecover(); go("recover") end)
local setScroll = scroller(pages.set, {Size = UDim2.fromScale(1, 1)}, {pad(14), vlist(8)})
buildSet = function()
for _, c in ipairs(setScroll:GetChildren()) do if c:IsA("GuiObject") then c:Destroy() end end
local hdr = new("Frame", {Size = UDim2.new(1, 0, 0, 40), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 1, Parent = setScroll}, {round(8), stroke(T.line)})
button(hdr, "< Back", UDim2.fromOffset(7, 7), UDim2.fromOffset(62, 26), false, function() route() end)
text(hdr, "Vault lock", 14, "Bold", T.text, {Position = UDim2.fromOffset(79, 9), Size = UDim2.new(1, -90, 0, 22)})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(1, 0, 0, 2), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = hdr})
text(setScroll, "Choose how to protect this vault", 12, "SemiBold", T.text, {Size = UDim2.new(1, 0, 0, 18), LayoutOrder = 2})
text(setScroll, "Password accepts 8–64 characters. Saved vault entries remain in local JSON and are not encrypted.", 10, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 30), TextWrapped = true, LayoutOrder = 3})
local row = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 4, Parent = setScroll}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -4, 0, 56), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local area = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 5, Parent = setScroll}, {vlist(8)})
local function newKey()
local rnd, alpha, out = Random.new(), "ABCDEFGHJKLMNPQRSTUVWXYZ23456789", {}
for i = 1, 12 do
local k = rnd:NextInteger(1, #alpha)
out[i] = alpha:sub(k, k)
end
local raw = table.concat(out)
return raw:sub(1, 4) .. "-" .. raw:sub(5, 8) .. "-" .. raw:sub(9, 12), raw
end
local function showKey(k)
for _, c in ipairs(area:GetChildren()) do if c:IsA("GuiObject") then c:Destroy() end end
local recoveryCard = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.glow, BorderSizePixel = 0, LayoutOrder = 1, Parent = area}, {round(12), stroke(T.gold, 1), pad(12), vlist(8)})
text(recoveryCard, "Recovery key", 14, "Bold", T.text, {Size = UDim2.new(1, 0, 0, 20), TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 1})
text(recoveryCard, "Save it somewhere safe. It is shown only once and unlocks the vault if you forget your code.", 11, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 38), TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 2})
local kb = new("Frame", {Size = UDim2.new(1, 0, 0, 44), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 3, Parent = recoveryCard}, {round(8), stroke(T.bronze, 1)})
text(kb, k, 18, "Bold", T.gold, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true})
local r = new("Frame", {Size = UDim2.new(1, 0, 0, 32), BackgroundTransparency = 1, LayoutOrder = 4, Parent = recoveryCard}, {hlist(6)})
button(r, "Copy", UDim2.new(), UDim2.new(.5, -3, 1, 0), false, function()
if setclipboard then pcall(setclipboard, k); toast("Copied") else toast("Clipboard unavailable") end
end)
button(r, "Done", UDim2.new(), UDim2.new(.5, -3, 1, 0), true, function() route() end)
end
local function choose(kind)
for _, c in ipairs(area:GetChildren()) do if c:IsA("GuiObject") then c:Destroy() end end
local first
local prompt = text(area, kind == "pattern" and "Create a new pattern" or (kind == "pin" and "Create a 4–6 digit PIN" or (kind == "password" and "Create an 8–64 character password" or "Create a number code")), 12, "SemiBold", T.text, {Size = UDim2.new(1, 0, 0, 22), TextXAlignment = Enum.TextXAlignment.Center, LayoutOrder = 1})
local pd
pd = entryPad(area, kind, 2, function(code)
if not first then
first = code
prompt.Text = kind == "password" and "Confirm your password"
or (kind == "pin" and "Confirm your PIN"
or (kind == "pattern" and "Confirm your pattern" or "Confirm your number code"))
pd.reset()
elseif code == first then
local salt = HttpService:GenerateGUID(false)
local keyText, keyRaw = newKey()
V.lock = {kind = kind, length = kind == "pin" and #code or nil, salt = salt, hash = FX.hashPass(salt, kind .. ":" .. code), rhash = FX.hashPass(salt, "rec:" .. keyRaw)}
save()
toast("Lock saved")
showKey(keyText)
else
first = nil
toast("Entries do not match")
prompt.Text = kind == "pattern" and "Create a new pattern" or (kind == "pin" and "Create a 4–6 digit PIN" or (kind == "password" and "Create an 8–64 character password" or "Create a number code"))
pd.reset()
end
end)
end
local CHOICES = {
{"pattern", "Pattern", "grid", "Draw 4–9 dots"},
{"pin", "PIN", "hash", "4–6 digits"},
{"password", "Password", "lock", "8–64 characters"},
{"number", "Numbers", "list", "4–16 digits"},
}
local function choiceCard(order, iconName, title, sub, cb)
local card = new("TextButton", {BackgroundColor3 = T.panel2, BorderSizePixel = 0, Text = "", AutoButtonColor = false, LayoutOrder = order, Parent = row}, {round(12), stroke(T.line)})
local ci = icon(card, iconName, 18, T.gold)
ci.holder.AnchorPoint, ci.holder.Position = Vector2.new(0, .5), UDim2.new(0, 14, .5, 0)
text(card, title, 12, "Bold", T.text, {Position = UDim2.fromOffset(44, 10), Size = UDim2.new(1, -52, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd})
text(card, sub, 9, "Regular", T.muted, {Position = UDim2.fromOffset(44, 29), Size = UDim2.new(1, -52, 0, 14), TextTruncate = Enum.TextTruncate.AtEnd})
hoverFx(card, T.panel2, T.panel)
pressFx(card, .97)
card.Activated:Connect(cb)
return card
end
for i, k in ipairs(CHOICES) do
choiceCard(i, k[3], k[2], k[4], function() choose(k[1]) end)
end
choiceCard(5, "lockOpen", "No lock", "Remove protection", function()
V.lock = nil
save()
toast("Lock removed")
route()
end)
end
local listScroll = scroller(pages.list, {Size = UDim2.fromScale(1, 1)}, {pad(14), vlist(10)})
local heading = new("Frame", {Size = UDim2.new(1, 0, 0, 54), BackgroundTransparency = 1, LayoutOrder = 1, Parent = listScroll})
local headingIcon = icon(heading, "vault", 22, T.gold)
headingIcon.holder.Position = UDim2.fromOffset(0, 8)
text(heading, "Private Vault", 16, "Bold", T.text, {Position = UDim2.fromOffset(32, 2), Size = UDim2.new(1, -200, 0, 22), TextTruncate = Enum.TextTruncate.AtEnd})
local vaultMeta = text(heading, "No access lock · 0 saved items", 10, "Regular", T.muted, {Position = UDim2.fromOffset(32, 28), Size = UDim2.new(1, -200, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(1, 0, 0, 2), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = heading})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(0, 42, 0, 2), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = heading})
local cards = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 2, Parent = listScroll}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -4, 0, 72), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local editScroll = scroller(pages.edit, {Size = UDim2.fromScale(1, 1)}, {pad(12), vlist(10)})
local eh = new("Frame", {Size = UDim2.new(1, 0, 0, 46), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 1, Parent = editScroll}, {round(12), stroke(T.line)})
local backChip = chip(eh, "arrowL", "Back", false, function() route() end)
backChip.Position = UDim2.fromOffset(8, 7)
text(eh, "Vault item", 14, "Bold", T.text, {AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, 108, .5, 0), Size = UDim2.new(1, -120, 0, 22), TextTruncate = Enum.TextTruncate.AtEnd})
new("Frame", {Position = UDim2.new(0, 14, 1, -2), Size = UDim2.fromOffset(42, 2), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = eh})
local kindRow = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 2, Parent = editScroll}, {
new("UIGridLayout", {CellSize = UDim2.new(1 / 3, -6, 0, 72), CellPadding = UDim2.fromOffset(9, 9), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local itemKind = "key"
local kindBtns = {}
local fields = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 3, Parent = editScroll}, {
round(12), stroke(T.line), pad(12), vlist(6),
})
local function caption(str, order)
return text(fields, str, 10, "SemiBold", T.muted, {Size = UDim2.new(1, 0, 0, 14), LayoutOrder = order})
end
caption("Title", 1)
local titleBox = makeInput(fields, "Service / item title (e.g. Roblox)", 38, false)
titleBox.LayoutOrder = 2
local usernameCap = caption("Username / email", 3)
local usernameBox = makeInput(fields, "Username / email (optional)", 38, false)
usernameBox.LayoutOrder = 4
local valueCap = caption("Key or token", 5)
local valueBox = makeInput(fields, "Paste a key, password or note...", 124, true)
valueBox.LayoutOrder = 6
valueBox.TextWrapped = true
valueBox.ZIndex = 2
local maskOverlay = text(valueBox, "", 12, "Regular", T.text, {
Position = UDim2.fromOffset(9, 4), Size = UDim2.new(1, -18, 1, -8), ZIndex = 4,
TextXAlignment = Enum.TextXAlignment.Center, TextYAlignment = Enum.TextYAlignment.Center,
TextTruncate = Enum.TextTruncate.AtEnd, Active = false, NoI18N = true,
})
maskOverlay.FontFace = F.Regular
maskOverlay.Visible = false
local passwordVisible, passwordFocused = false, false
local function renderEditorValue()
local hidden = itemKind == "password" and not passwordVisible and valueBox.Text ~= ""
maskOverlay.Text = secretMask(valueBox.Text)
maskOverlay.Visible = hidden
local textColor = (itemKind == "password" and not passwordVisible)
and (passwordFocused and T.panel2 or T.panel) or T.text
if valueBox.TextColor3 ~= textColor then tween(valueBox, {TextColor3 = textColor}, .16) end
end
local revealRow = new("Frame", {Size = UDim2.new(1, 0, 0, 32), BackgroundTransparency = 1, LayoutOrder = 7, Parent = fields}, {hlist(6)})
local revealButton, revealLbl, revealIcon
revealButton, revealLbl, revealIcon = chip(revealRow, "eye", "Show password", false, function()
passwordVisible = not passwordVisible
renderEditorValue()
revealLbl.Text = passwordVisible and "Hide password" or "Show password"
revealIcon.swap(passwordVisible and "eyeoff" or "eye")
end, 1)
revealRow.Visible = false
valueBox.Focused:Connect(function() passwordFocused = true; renderEditorValue() end)
valueBox.FocusLost:Connect(function() passwordFocused = false; renderEditorValue() end)
valueBox:GetPropertyChangedSignal("Text"):Connect(renderEditorValue)
local actions = new("Frame", {Size = UDim2.new(1, 0, 0, 36), BackgroundTransparency = 1, LayoutOrder = 4, Parent = editScroll}, {hlist(8)})
local function paintKind()
for kind, b in pairs(kindBtns) do
local active = kind == itemKind
b.BackgroundColor3 = active and T.bronze or T.panel2
local edge = b:FindFirstChildOfClass("UIStroke")
if edge then edge.Color = active and T.gold or T.line end
end
local isPassword = itemKind == "password"
usernameBox.Visible = isPassword
usernameCap.Visible = isPassword
valueCap.Text = isPassword and "Secret value" or (itemKind == "note" and "Note" or "Key or token")
valueBox.Size = UDim2.new(1, 0, 0, isPassword and 44 or 124)
valueBox.MultiLine = not isPassword
valueBox.TextWrapped = not isPassword
valueBox.TextYAlignment = isPassword and Enum.TextYAlignment.Center or Enum.TextYAlignment.Top
valueBox.TextXAlignment = isPassword and Enum.TextXAlignment.Center or Enum.TextXAlignment.Left
maskOverlay.TextXAlignment = isPassword and Enum.TextXAlignment.Center or Enum.TextXAlignment.Left
valueBox.PlaceholderText = isPassword and "Password / secret value" or (itemKind == "note" and "Write your note here..." or "Paste your key or token here...")
passwordVisible = false
renderEditorValue()
revealRow.Visible = isPassword
revealLbl.Text = "Show password"
revealIcon.swap("eye")
end
for order, option in ipairs({
{"password", "Password", "lock", "Login and secret"},
{"key", "Key", "key", "API key or token"},
{"note", "Note", "filetext", "Private text"},
}) do
local card = new("TextButton", {BackgroundColor3 = T.panel2, BorderSizePixel = 0, Text = "", AutoButtonColor = false, LayoutOrder = order, Parent = kindRow}, {round(12), stroke(T.line)})
local ki = icon(card, option[3], 18, T.gold)
ki.holder.AnchorPoint, ki.holder.Position = Vector2.new(.5, 0), UDim2.new(.5, 0, 0, 10)
text(card, option[2], 12, "Bold", T.text, {Position = UDim2.fromOffset(4, 31), Size = UDim2.new(1, -8, 0, 16), TextXAlignment = Enum.TextXAlignment.Center, TextTruncate = Enum.TextTruncate.AtEnd})
text(card, option[4], 9, "Regular", T.muted, {Position = UDim2.fromOffset(4, 49), Size = UDim2.new(1, -8, 0, 14), TextXAlignment = Enum.TextXAlignment.Center, TextTruncate = Enum.TextTruncate.AtEnd})
pressFx(card, .96)
kindBtns[option[1]] = card
card.Activated:Connect(function()
itemKind = option[1]
paintKind()
end)
end
local function openEditor(entry)
selectedId = entry and entry.id or nil
itemKind = entry and (entry.kind or "key") or "key"
if itemKind ~= "password" and itemKind ~= "note" then itemKind = "key" end
titleBox.Text = entry and (entry.title or "") or ""
usernameBox.Text = entry and (entry.username or "") or ""
valueBox.Text = entry and (entry.value or "") or ""
paintKind()
go("edit")
end
local function refreshList()
vaultMeta.Text = (V.lock and "Lock enabled" or "No access lock") .. " · " .. tostring(#V.items) .. (#V.items == 1 and " saved item" or " saved items")
for _, child in ipairs(cards:GetChildren()) do
if child:IsA("GuiObject") then child:Destroy() end
end
local oldEmpty = listScroll:FindFirstChild("VaultEmpty")
if oldEmpty then oldEmpty:Destroy() end
if #V.items == 0 then
local empty = new("Frame", {Name = "VaultEmpty", Size = UDim2.new(1, 0, 0, 150), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 3, Parent = listScroll}, {round(14), stroke(T.line)})
local badge = new("Frame", {AnchorPoint = Vector2.new(.5, 0), Position = UDim2.new(.5, 0, 0, 18), Size = UDim2.fromOffset(46, 46), BackgroundColor3 = T.panel2, BorderSizePixel = 0, Parent = empty}, {round(14), stroke(T.line)})
local ei = icon(badge, "vault", 24, T.gold)
ei.holder.AnchorPoint, ei.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
text(empty, "Your vault is empty", 14, "Bold", T.text, {Position = UDim2.fromOffset(12, 74), Size = UDim2.new(1, -24, 0, 20), TextXAlignment = Enum.TextXAlignment.Center})
text(empty, "Tap + New to save a password, key or private note.", 11, "Regular", T.muted, {Position = UDim2.fromOffset(16, 98), Size = UDim2.new(1, -32, 0, 36), TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Center})
return
end
for index, entry in ipairs(V.items) do
local kind = entry.kind == "password" and "password" or (entry.kind == "note" and "note" or "key")
local card = new("Frame", {BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = index, Parent = cards}, {round(12), stroke(T.line)})
FX.cardSkin(card)
local badge = new("Frame", {Position = UDim2.fromOffset(10, 18), Size = UDim2.fromOffset(36, 36), BackgroundColor3 = T.panel2, BorderSizePixel = 0, Parent = card}, {round(10), stroke(T.line)})
local ic = icon(badge, kind == "password" and "lock" or (kind == "note" and "filetext" or "key"), 18, T.gold)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
text(card, tostring(entry.title or "Untitled"), 12, "SemiBold", T.text, {
Position = UDim2.fromOffset(56, 10), Size = UDim2.new(1, -66, 0, 17),
TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true,
})
local subtitle
if kind == "note" then
subtitle = tostring(entry.value or ""):gsub("\n", " ")
elseif kind == "password" then
subtitle = (entry.username and entry.username ~= "") and tostring(entry.username) or "••••••••"
else
subtitle = "••••••••"
end
text(card, subtitle, 10, "Regular", T.muted, {
Position = UDim2.fromOffset(56, 29), Size = UDim2.new(1, -66, 0, 14),
TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true,
})
text(card, kind == "password" and "PASSWORD" or (kind == "note" and "NOTE" or "KEY"), 8, "Bold", T.tan, {
Position = UDim2.fromOffset(56, 48), Size = UDim2.new(1, -66, 0, 12),
})
local open = new("TextButton", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Text = "", ZIndex = 5, Parent = card})
open.Activated:Connect(function() openEditor(entry) end)
end
end
chip(actions, "check", "Save", true, function()
local title = titleBox.Text:gsub("^%s+", ""):gsub("%s+$", "")
if title == "" then toast("Enter a title") return end
if valueBox.Text:gsub("%s", "") == "" then toast("Add some content") return end
local entry
for _, it in ipairs(V.items) do if it.id == selectedId then entry = it break end end
if not entry then entry = {id = HttpService:GenerateGUID(false), created = os.time()}; table.insert(V.items, 1, entry) end
entry.title, entry.value, entry.kind = title, valueBox.Text, itemKind
entry.username = itemKind == "password" and usernameBox.Text or nil
save(); refreshList(); toast("Item saved")
go("list")
end, 1, UDim2.new(.4, -6, 1, 0))
chip(actions, "copy", "Copy", false, function()
if valueBox.Text == "" then toast("Nothing to copy") return end
if setclipboard then
local ok = pcall(setclipboard, valueBox.Text)
toast(ok and "Copied to clipboard" or "Clipboard unavailable")
else
toast("Clipboard unavailable")
end
end, 2, UDim2.new(.3, -5, 1, 0))
chip(actions, "trash", "Delete", false, function()
if not selectedId then toast("Save this item before deleting it") return end
for i, it in ipairs(V.items) do if it.id == selectedId then table.remove(V.items, i) break end end
save(); selectedId = nil; refreshList(); go("list"); toast("Item deleted")
end, 3, UDim2.new(.3, -5, 1, 0))
local headActions = new("Frame", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, 0, 0, 6), Size = UDim2.fromOffset(0, 32),
AutomaticSize = Enum.AutomaticSize.X, BackgroundTransparency = 1, Parent = heading,
}, {hlist(8, Enum.VerticalAlignment.Center, Enum.HorizontalAlignment.Right)})
chip(headActions, "shieldcheck", "Security", false, function() buildSet(); go("set") end, 1)
chip(headActions, "plus", "New", true, function() openEditor(nil) end, 2)
route = function()
if V.lock and not unlocked then
buildLock()
go("lock")
else
refreshList()
go("list")
end
end
FX.accRefreshVault = function() unlocked = false; load(); route() end
route()
return function() unlocked = false; load(); route() end
end, "vault")
home.add("Mailbox", function(view)
local C = FX.cloud
local function me() return tostring(I18N.user or I18N.session or ""):lower() end
local function myName() return tostring(I18N.user or I18N.session or "") end
local function sf(kind) return DB_FOLDER .. "/mail_" .. kind .. "_" .. me() .. ".json" end
local function arr(x)
if type(x) ~= "table" then return {} end
if #x > 0 then return x end
local r = {}
for _, v in pairs(x) do r[#r + 1] = v end
return r
end
local msgs, pins, reads, loadedFor, sig, route, curThread, first, tick, reply, busy = {}, {}, {}, nil, "", "list", nil, true, 0, nil, false
local atts = {}
local KIND_ICON = {text = "filetext", script = "codeSlash", plugin = "plug", file = "file"}
local root = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = view})
local P = {}
for _, k in ipairs({"list", "thread", "compose"}) do
P[k] = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Visible = k == "list", Parent = root})
end
local renderList, renderThread, refresh
local function go(n) route = n for k, p in pairs(P) do p.Visible = k == n end end
local function btn(parent, label, pos, size, primary, cb, anchor)
local b = new("TextButton", {Position = pos, Size = size, AnchorPoint = anchor or Vector2.new(0, 0), BackgroundColor3 = primary and T.bronze or T.panel2, BorderSizePixel = 0, Text = label, TextColor3 = T.text, TextSize = 11, FontFace = F.SemiBold, AutoButtonColor = false, Parent = parent}, {round(6)})
pressFx(b, .96)
b.Activated:Connect(cb)
return b
end
local function field(parent, ph, h, multi, order)
return new("TextBox", {Size = UDim2.new(1, 0, 0, h), BackgroundColor3 = T.panel, BorderSizePixel = 0, Text = "", PlaceholderText = ph, PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 12,
FontFace = multi and MONO or F.Regular, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = multi and Enum.TextYAlignment.Top or Enum.TextYAlignment.Center,
ClearTextOnFocus = false, MultiLine = multi or false, TextWrapped = multi or false, LayoutOrder = order or 0, ClipsDescendants = true, Parent = parent}, {round(6), stroke(T.line), pad(8, 6)})
end
local function loadState()
if loadedFor == me() then return end
loadedFor = me()
pins = jsonRead(sf("pins"), {})
reads = jsonRead(sf("reads"), {})
msgs, sig, first = {}, "", true
end
local function threads()
local map = {}
for _, m in pairs(msgs) do
local t = map[m.thread]
if not t then t = {id = m.thread, items = {}, last = 0}; map[m.thread] = t end
t.items[#t.items + 1] = m
if m.ts >= t.last then t.last, t.lastMsg = m.ts, m end
end
local out = {}
for _, t in pairs(map) do
table.sort(t.items, function(a, b) return a.ts < b.ts end)
t.subject = t.items[1].subject or ""
t.unread = 0
for _, m in ipairs(t.items) do if m.fromKey ~= me() and not reads[m.id] then t.unread += 1 end end
out[#out + 1] = t
end
table.sort(out, function(a, b)
local pa, pb = pins[a.id] and 1 or 0, pins[b.id] and 1 or 0
if pa ~= pb then return pa > pb end
return a.last > b.last
end)
return out
end
local function togglePin(id)
pins[id] = (not pins[id]) or nil
jsonWrite(sf("pins"), pins)
end
local function badgeFor(parent, key, name, size, pos)
local badge = new("Frame", {Size = UDim2.fromOffset(size, size), Position = pos, BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = parent}, {round(size / 2)})
local letter = text(badge, tostring(name or "?"):sub(1, 1):upper(), size * .42, "Bold", T.dark, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true})
C.avatar(badge, letter, key, size)
return badge
end
local function clearKids(o) for _, c in ipairs(o:GetChildren()) do if c:IsA("GuiObject") then c:Destroy() end end end
text(P.list, "Mailbox", 16, "Bold", T.text, {Position = UDim2.fromOffset(14, 8), Size = UDim2.new(1, -200, 0, 22), NoI18N = true})
local sub = text(P.list, "", 11, "Regular", T.muted, {Position = UDim2.fromOffset(14, 32), Size = UDim2.new(1, -28, 0, 16), NoI18N = true})
local listSc = scroller(P.list, {Position = UDim2.fromOffset(0, 54), Size = UDim2.new(1, 0, 1, -54)}, {pad(14, 4, 14, 14), vlist(8)})
local openCompose
btn(P.list, "Compose", UDim2.new(1, -14, 0, 10), UDim2.fromOffset(80, 26), true, function() openCompose(nil) end, Vector2.new(1, 0))
btn(P.list, "Refresh", UDim2.new(1, -100, 0, 10), UDim2.fromOffset(70, 26), false, function() task.spawn(function() pcall(refresh) end) end, Vector2.new(1, 0))
local function openThread(id)
curThread = id
go("thread")
renderThread()
end
renderList = function()
clearKids(listSc)
local list = threads()
local un = 0
for _, t in ipairs(list) do un += t.unread end
if me() == "" then sub.Text = "Sign in to use the mailbox"
elseif not C.enabled() then sub.Text = "Cloud not configured: set C.url in the Cloud block"
else sub.Text = #list .. " conversations, " .. un .. " unread" end
for i, t in ipairs(list) do
local lm = t.lastMsg
local other = lm.fromKey == me() and arr(lm.toKeys)[1] or lm.fromKey
local nm = tostring((C.users[other or ""] and C.users[other].name) or (lm.fromKey == me() and arr(lm.toNames)[1]) or lm.from or other or "?")
local card = new("TextButton", {Size = UDim2.new(1, 0, 0, 62), BackgroundColor3 = t.unread > 0 and T.glow or T.cardTop, AutoButtonColor = false, Text = "", BorderSizePixel = 0, LayoutOrder = i, Parent = listSc}, {round(12), stroke(pins[t.id] and T.gold or T.line, 1)})
badgeFor(card, other, nm, 38, UDim2.fromOffset(12, 12))
text(card, t.subject, 13, t.unread > 0 and "Bold" or "SemiBold", T.text, {Position = UDim2.fromOffset(60, 10), Size = UDim2.new(1, -140, 0, 18), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
local snip = (tostring(lm.body or ""):gsub("%s+", " "))
local na = #arr(lm.att)
text(card, (lm.fromKey == me() and "You" or nm) .. ": " .. snip:sub(1, 70) .. (na > 0 and (" [" .. na .. " att]") or ""), 11, "Regular", T.muted, {Position = UDim2.fromOffset(60, 32), Size = UDim2.new(1, -140, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
text(card, os.date("%d/%m %H:%M", t.last), 10, "Regular", T.muted, {AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -44, 0, 10), Size = UDim2.fromOffset(70, 14), TextXAlignment = Enum.TextXAlignment.Right, NoI18N = true})
if t.unread > 0 then new("Frame", {Size = UDim2.fromOffset(9, 9), AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -18, 0, 42), BackgroundColor3 = T.bronzeHi, BorderSizePixel = 0, Parent = card}, {round(5)}) end
local pb = new("TextButton", {Position = UDim2.new(1, -34, 0, 4), Size = UDim2.fromOffset(26, 26), BackgroundTransparency = 1, Text = "", Parent = card})
local ic = icon(pb, "pin", 14, pins[t.id] and T.gold or T.muted, 1.5)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
pb.Activated:Connect(function() togglePin(t.id) renderList() end)
pressFx(card, .97)
card.Activated:Connect(function() openThread(t.id) end)
end
if #list == 0 and me() ~= "" then
text(listSc, "No messages yet. Tap Compose to write the first one.", 12, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 40), TextWrapped = true, NoI18N = true})
end
end
local thHead = text(P.thread, "", 14, "Bold", T.text, {Position = UDim2.fromOffset(84, 12), Size = UDim2.new(1, -290, 0, 22), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
local thSc = scroller(P.thread, {Position = UDim2.fromOffset(0, 48), Size = UDim2.new(1, 0, 1, -48)}, {pad(14, 4, 14, 14), vlist(8)})
btn(P.thread, "Back", UDim2.fromOffset(14, 10), UDim2.fromOffset(60, 26), false, function() curThread = nil go("list") renderList() end)
local function copyText(data)
local ok = pcall(function() (setclipboard or toclipboard)(data) end)
toast(ok and "Copied" or "Clipboard unavailable")
end
local function useAttachment(a)
local data = tostring(a.data or "")
if a.kind == "script" then
table.insert(Store.saved, 1, {id = HttpService:GenerateGUID(false), title = tostring(a.name), notes = "Received in Mailbox", code = data})
jsonWrite(PATH.saved, Store.saved)
pcall(function() if Store.refreshSaved then Store.refreshSaved() end end)
toast("Script saved to My Scripts")
elseif a.kind == "plugin" then
local ok = pcall(FX.Plugins.install, tostring(a.name), data, true)
toast(ok and "Plugin installed (disabled). Review it in Settings > Plugins" or "Could not install plugin")
elseif a.kind == "file" then
pcall(function() if makefolder and not isfolder(FOLDER .. "/mail_files") then makefolder(FOLDER .. "/mail_files") end end)
local safe = tostring(a.name):gsub("[^%w%._%-]", "_")
local ok = pcall(writefile, FOLDER .. "/mail_files/" .. safe, data)
toast(ok and "File saved to HyundaxIUM/mail_files" or "Could not save file")
else
copyText(data)
end
end
local function threadItems()
local items = {}
for _, m in pairs(msgs) do if m.thread == curThread then items[#items + 1] = m end end
table.sort(items, function(a, b) return a.ts < b.ts end)
return items
end
renderThread = function()
clearKids(thSc)
local items = threadItems()
if #items == 0 then curThread = nil go("list") renderList() return end
thHead.Text = items[1].subject or ""
local dirty = false
for i, m in ipairs(items) do
if not reads[m.id] then reads[m.id] = true dirty = true end
local card = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = m.fromKey == me() and T.glow or T.cardTop, BorderSizePixel = 0, LayoutOrder = i, Parent = thSc}, {round(12), stroke(T.line, 1), pad(12, 10, 12, 10), vlist(6)})
local row = new("Frame", {Size = UDim2.new(1, 0, 0, 26), BackgroundTransparency = 1, LayoutOrder = 1, Parent = card})
badgeFor(row, m.fromKey, m.from, 26, UDim2.fromOffset(0, 0))
text(row, tostring(m.from or m.fromKey), 12, "Bold", T.text, {Position = UDim2.fromOffset(34, 0), Size = UDim2.new(.6, -34, 1, 0), NoI18N = true})
text(row, os.date("%d/%m/%Y %H:%M", m.ts), 10, "Regular", T.muted, {AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, 0, 0, 0), Size = UDim2.new(.4, 0, 1, 0), TextXAlignment = Enum.TextXAlignment.Right, NoI18N = true})
local body = tostring(m.body or "")
if body ~= "" then
text(card, body, 12, "Regular", T.text, {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = 2, NoI18N = true})
end
for j, a in ipairs(arr(m.att)) do
local r = new("Frame", {Size = UDim2.new(1, 0, 0, 32), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 10 + j, Parent = card}, {round(8), stroke(T.line, 1)})
local ic = icon(r, KIND_ICON[a.kind] or "file", 14, T.tan, 1.5)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(0, .5), UDim2.new(0, 10, .5, 0)
text(r, tostring(a.kind or "file"):upper() .. ": " .. tostring(a.name) .. " (" .. #tostring(a.data or "") .. " B)", 11, "SemiBold", T.text, {Position = UDim2.fromOffset(32, 0), Size = UDim2.new(1, -170, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
btn(r, "Copy", UDim2.new(1, -6, .5, -11), UDim2.fromOffset(46, 22), false, function() copyText(tostring(a.data or "")) end, Vector2.new(1, 0))
local lbl = ({script = "Save", plugin = "Install", file = "Save file"})[a.kind]
if lbl then btn(r, lbl, UDim2.new(1, -58, .5, -11), UDim2.fromOffset(64, 22), true, function() useAttachment(a) end, Vector2.new(1, 0)) end
end
end
if dirty then jsonWrite(sf("reads"), reads) end
end
btn(P.thread, "Reply", UDim2.new(1, -14, 0, 10), UDim2.fromOffset(64, 26), true, function()
local items = threadItems()
if #items == 0 then return end
local set, to = {}, {}
for _, m in ipairs(items) do
set[m.fromKey] = true
for _, k in ipairs(arr(m.toKeys)) do set[k] = true end
end
for k in pairs(set) do if k ~= me() then to[#to + 1] = k end end
if #to == 0 then to[1] = me() end
openCompose({thread = curThread, subject = items[1].subject or "", to = table.concat(to, ", ")})
end, Vector2.new(1, 0))
btn(P.thread, "Pin", UDim2.new(1, -86, 0, 10), UDim2.fromOffset(46, 26), false, function() if curThread then togglePin(curThread) toast(pins[curThread] and "Conversation pinned" or "Unpinned") end end, Vector2.new(1, 0))
btn(P.thread, "Delete", UDim2.new(1, -138, 0, 10), UDim2.fromOffset(52, 26), false, function()
local id = curThread
local items = threadItems()
curThread = nil
for _, m in ipairs(items) do msgs[m.id] = nil end
go("list") renderList()
task.spawn(function() for _, m in ipairs(items) do C.call("DELETE", "mail/" .. me() .. "/" .. m.id) end end)
toast("Conversation deleted")
end, Vector2.new(1, 0))
local cSc = scroller(P.compose, {}, {pad(14), vlist(8)})
text(cSc, "New message", 16, "Bold", T.text, {Size = UDim2.new(1, 0, 0, 22), LayoutOrder = 1})
local toBox = field(cSc, "To: username (separate several with commas)", 32, false, 2)
local subBox = field(cSc, "Subject", 32, false, 3)
local bodyBox = field(cSc, "Write your message...", 150, true, 4)
local attHost = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 5, Parent = cSc}, {vlist(4)})
local attBar = new("Frame", {Size = UDim2.new(1, 0, 0, 28), BackgroundTransparency = 1, LayoutOrder = 6, Parent = cSc}, {hlist(6)})
local actBar = new("Frame", {Size = UDim2.new(1, 0, 0, 32), BackgroundTransparency = 1, LayoutOrder = 7, Parent = cSc}, {hlist(8)})
local renderAtts
renderAtts = function()
clearKids(attHost)
for i, a in ipairs(atts) do
local r = new("Frame", {Size = UDim2.new(1, 0, 0, 28), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = i, Parent = attHost}, {round(8), stroke(T.line, 1)})
text(r, " " .. a.kind:upper() .. ": " .. a.name .. " (" .. #a.data .. " B)", 11, "SemiBold", T.text, {Size = UDim2.new(1, -40, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
btn(r, "x", UDim2.new(1, -4, .5, -10), UDim2.fromOffset(24, 20), false, function() table.remove(atts, i) renderAtts() end, Vector2.new(1, 0))
end
end
local picker = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.panel, BorderSizePixel = 0, Visible = false, Parent = P.compose})
local pTitle = text(picker, "", 14, "Bold", T.text, {Position = UDim2.fromOffset(14, 12), Size = UDim2.new(1, -100, 0, 22), NoI18N = true})
local pList = scroller(picker, {Position = UDim2.fromOffset(0, 44), Size = UDim2.new(1, 0, 1, -44)}, {pad(14, 4, 14, 14), vlist(6)})
local pText = field(picker, "Type or paste text...", 150, true)
pText.Position, pText.Visible = UDim2.fromOffset(14, 52), false
local pAdd
local function closePicker() picker.Visible = false cSc.Visible = true end
btn(picker, "Close", UDim2.new(1, -14, 0, 10), UDim2.fromOffset(60, 26), false, closePicker, Vector2.new(1, 0))
local function addAtt(kind, name, data)
data = tostring(data or "")
if #data > 200000 then toast("Too large (200 KB max)") return end
atts[#atts + 1] = {kind = kind, name = tostring(name), data = data}
renderAtts()
closePicker()
end
pAdd = btn(picker, "Add text", UDim2.fromOffset(14, 212), UDim2.fromOffset(90, 28), true, function()
if pText.Text:gsub("%s", "") == "" then toast("Type something first") return end
addAtt("text", "Text " .. (#atts + 1), pText.Text)
end)
pAdd.Visible = false
local function openPicker(title, items, onPick)
cSc.Visible, picker.Visible = false, true
pTitle.Text = title
pText.Visible, pAdd.Visible, pList.Visible = false, false, true
clearKids(pList)
if #items == 0 then text(pList, "Nothing available.", 12, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 20), NoI18N = true}) end
for i, it in ipairs(items) do
local b = new("TextButton", {Size = UDim2.new(1, 0, 0, 34), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, Text = " " .. it.label, TextColor3 = T.text, TextSize = 12, FontFace = F.SemiBold, TextXAlignment = Enum.TextXAlignment.Left, TextTruncate = Enum.TextTruncate.AtEnd, AutoButtonColor = false, LayoutOrder = i, Parent = pList}, {round(8), stroke(T.line, 1)})
pressFx(b, .97)
b.Activated:Connect(function() onPick(it) end)
end
end
local function chipBtn(label, cb) btn(attBar, label, UDim2.new(), UDim2.fromOffset(78, 28), false, cb) end
chipBtn("+ Script", function()
local items = {}
for _, sv in ipairs(Store.saved or {}) do
if type(sv.code) == "string" and sv.code ~= "" then items[#items + 1] = {label = "[Saved] " .. tostring(sv.title or "Untitled"), name = tostring(sv.title or "Untitled"), data = sv.code} end
end
for _, sv in ipairs(Store.cloud or {}) do
local nm = tostring(sv.title or sv.name or sv.slug or "Script")
items[#items + 1] = {label = "[Downloaded] " .. nm, name = nm, entry = sv, data = type(sv.code) == "string" and sv.code or nil}
end
for _, sv in ipairs(Store.auto or {}) do
local nm = tostring(sv.name or "AutoExec")
items[#items + 1] = {label = "[AutoExec] " .. nm, name = nm, file = sv.file or (PATH.auto .. "/" .. nm .. ".lua")}
end
openPicker("Attach a script", items, function(it)
task.spawn(function()
local data = it.data
if not data and it.entry then pcall(function() data = Store.ensureCode(it.entry) end) end
if not data and it.file then local ok, r = pcall(readfile, it.file) if ok then data = r end end
if type(data) ~= "string" or data == "" then toast("Could not read this script") return end
addAtt("script", it.name, data)
end)
end)
end)
local function resetCompose()
toBox.Text, subBox.Text, bodyBox.Text = "", "", ""
atts, reply = {}, nil
renderAtts()
end
local function send()
if busy then return end
if me() == "" then toast("Sign in first") return end
if not C.enabled() then toast("Cloud not configured") return end
local keys, seen = {}, {}
for w in toBox.Text:gmatch("[^,%s]+") do
local k = w:gsub("^@", ""):lower()
if k ~= "" and not seen[k] then seen[k] = true keys[#keys + 1] = k end
end
if #keys == 0 then toast("Add at least one recipient") return end
local body = bodyBox.Text
if body:gsub("%s", "") == "" and #atts == 0 then toast("Write a message or attach something") return end
busy = true
task.spawn(function()
local names = {}
for _, k in ipairs(keys) do
if k:match("[^%w_]") then toast("Invalid username: " .. k) busy = false return end
local ok, u = C.call("GET", "users/" .. k)
if not ok then toast("Server: " .. tostring(C.lastErr):sub(1, 110)) busy = false return end
if not u then toast("User not found: " .. k) busy = false return end
names[#names + 1] = u.name or k
end
local id = tostring(os.time()) .. HttpService:GenerateGUID(false):sub(1, 8)
local subj = subBox.Text:gsub("^%s+", ""):gsub("%s+$", "")
if subj == "" then subj = reply and reply.subject or "(no subject)" end
if reply and not subj:match("^Re:") then subj = "Re: " .. subj end
local msg = {from = myName(), fromKey = me(), toKeys = keys, toNames = names, subject = subj, body = body, ts = os.time(), thread = reply and reply.thread or id, att = (#atts > 0) and atts or nil}
local parts, all = {me()}, true
for _, k in ipairs(keys) do if k ~= me() then parts[#parts + 1] = k end end
for _, k in ipairs(parts) do
local ok = C.call("PUT", "mail/" .. k .. "/" .. id, msg)
all = all and ok
end
busy = false
if all then
resetCompose()
toast("Message sent")
go("list")
pcall(refresh)
else
toast("Some deliveries failed")
end
end)
end
btn(actBar, "Send", UDim2.new(), UDim2.fromOffset(90, 32), true, send)
btn(actBar, "Cancel", UDim2.new(), UDim2.fromOffset(80, 32), false, function() resetCompose() go("list") end)
openCompose = function(rep)
if me() == "" then toast("Sign in first") return end
reply = rep
closePicker()
if rep then toBox.Text, subBox.Text = rep.to, rep.subject:match("^Re:") and rep.subject or ("Re: " .. rep.subject) end
renderAtts()
go("compose")
end
refresh = function()
loadState()
if me() == "" or not C.enabled() then renderList() return end
tick += 1
if tick % 6 == 1 or next(C.users) == nil then pcall(C.fetchUsers) end
local ok, d = C.call("GET", "mail/" .. me())
if not ok then sub.Text = "Offline: " .. tostring(C.lastErr):sub(1, 90) return end
local nm, newest, cnt, un = {}, 0, 0, 0
for id, m in pairs(d or {}) do
if type(m) == "table" and m.thread and tonumber(m.ts) then
m.id, m.ts = id, tonumber(m.ts)
nm[id] = m
cnt += 1
if m.ts > newest then newest = m.ts end
if m.fromKey ~= me() and not reads[id] then un += 1 end
if not first and not msgs[id] and m.fromKey ~= me() then toast("New mail from " .. tostring(m.from) .. ": " .. tostring(m.subject)) end
end
end
msgs, first = nm, false
local s = cnt .. ":" .. newest .. ":" .. un
if s ~= sig then
sig = s
if route == "list" then renderList() elseif route == "thread" then renderThread() end
end
end
task.spawn(function()
task.wait(1.5)
while view.Parent do
pcall(refresh)
local w, lim = 0, view.Visible and 6 or 20
while w < lim and view.Parent do task.wait(1) w += 1 end
end
end)
renderList()
return function() task.spawn(function() pcall(refresh) end) end
end, "mail")
home.add("Update Log", function(view)
local sc = scroller(view, {Position = UDim2.fromOffset(0, 48), Size = UDim2.new(1, 0, 1, -48)}, {pad(14, 4, 14, 14), vlist(12)})
local rb = scroller(view, {Position = UDim2.fromOffset(0, 48), Size = UDim2.new(1, 0, 1, -48), Visible = false}, {pad(14, 4, 14, 14), vlist(8)})
local bar = new("Frame", {
Position = UDim2.fromOffset(14, 12), Size = UDim2.new(1, -28, 0, 28), BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = .35, BorderSizePixel = 0, Parent = view,
}, {round(8), stroke(T.line, 1), hlist(2, nil, Enum.HorizontalAlignment.Center)})
local panels, btns, loadRoblox = {["Hyundax IUM"] = sc, Roblox = rb}, {}, nil
local function pickTab(k)
for name, b in pairs(btns) do
tween(b, {BackgroundTransparency = name == k and 0 or 1}, .15)
panels[name].Visible = name == k
end
if k == "Roblox" and loadRoblox then loadRoblox() end
end
for i, k in ipairs({"Hyundax IUM", "Roblox"}) do
btns[k] = new("TextButton", {
Size = UDim2.new(.5, -3, 1, -6), BackgroundColor3 = T.bronze, BackgroundTransparency = k == "Hyundax IUM" and 0 or 1, AutoButtonColor = false,
Text = k, TextSize = 10, FontFace = F.Bold, TextColor3 = T.text, LayoutOrder = i, Parent = bar, NoI18N = true,
}, {round(6)})
btns[k].Activated:Connect(function() pickTab(k) end)
end
local LOG = {
{VERSION, true, "Oct 29", {"First public release of Hyundax IUM", "Draggable, maximizable window with a black, red, blue and yellow theme", "Home: Dashboard, Settings, Overview, My Scripts, Update Log, Recent Scripts and sUNC tests", "Update Log > Roblox now lists mobile client versions only, with a dedicated phone icon",
"Hyundax IUM availability for this release is marked unverified because this build has no uptime history", "Editor: tabs, line numbers, line highlight, console mirroring F9, AutoExec, Exec Clipboard", "Forge: stack ready-made modules into one script", "Scripts: ScriptBlox browser with 3x3 cards, likes and Cloud Scripts", "Bubble animation on Script Hub cards, with the same card glow on the pill bubbles", "Source icons (ScriptBlox, Rscripts, HaxHell, Roblox Scripts) in the filters, cards and details, plus 24 new icons", "Quick Run button on Script Hub cards", "Radar: live player radar with spectate, teleport and highlight", "Dex: instance explorer and Finder, with code injection on the selected object", "sUNC + HSS compatibility layer (~200 functions, polyfilled and tested)", "Redesigned login screen, universal card design and a new Overview welcome", "UI sound effects for tabs, toggles, buttons and notices (Settings > Sound feedback)", "Tab names on hover or long press in the top bar", "Animated background waves, smooth animations and a floating logo button", "Plugins: post your own code in Settings > Plugins, plus 5 ready plugins (Image Personalization, Spotlight Search, Neon Border, FPS & Ping HUD, Quick Notes)"}},
}
for i, e in ipairs(LOG) do
local latest = e[2]
local entry = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = latest and T.glow or T.cardTop,
BorderSizePixel = 0, LayoutOrder = i, Parent = sc,
}, {round(12), stroke(latest and T.gold or T.line, 1), pad(14, 12), vlist(7)})
FX.cardSkin(entry)
local hdr = new("Frame", {Size = UDim2.new(1, 0, 0, 28), BackgroundTransparency = 1, LayoutOrder = 0, Parent = entry})
FX.chip(hdr, latest and "rocket" or "history", 28, latest and T.gold or T.tan, UDim2.fromOffset(0, 0))
local left = new("Frame", {Position = UDim2.fromOffset(38, 0), Size = UDim2.new(1, -140, 1, 0), BackgroundTransparency = 1, Parent = hdr}, {hlist(8)})
text(left, e[1], 15, "Bold", T.text, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 20), LayoutOrder = 1, NoI18N = true})
if latest then FX.pill(left, "LATEST", T.gold, {LayoutOrder = 2}) end
text(hdr, e[3], 10, "Regular", T.muted, {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, 0, .5, 0), Size = UDim2.fromOffset(100, 16),
TextXAlignment = Enum.TextXAlignment.Right,
})
new("Frame", {Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line, BorderSizePixel = 0, LayoutOrder = 1, Parent = entry})
for j, line in ipairs(e[4]) do
local brow = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = j + 1, Parent = entry,
}, {hlist(8, Enum.VerticalAlignment.Top)})
local holder = new("Frame", {Size = UDim2.fromOffset(8, 16), BackgroundTransparency = 1, LayoutOrder = 1, Parent = brow})
new("Frame", {Position = UDim2.fromOffset(1, 6), Size = UDim2.fromOffset(5, 5), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = holder}, {round(3)})
text(brow, line, 11, "Regular", T.muted, {LayoutOrder = 2, TextWrapped = true, AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, -16, 0, 0)})
end
end
local function rbGet(url)
local req = request or http_request or (syn and syn.request)
if type(req) == "function" then
local ok, res = pcall(req, {Url = url, Method = "GET", Headers = {["User-Agent"] = "Mozilla/5.0"}, Timeout = 15})
if ok and type(res) == "table" then
local status = tonumber(res.StatusCode or res.Status) or 200
local body = res.Body or res.body
if status >= 200 and status < 300 and type(body) == "string" and #body > 0 then return body end
end
end
local ok, body = pcall(function() return game:HttpGet(url) end)
if ok and type(body) == "string" and #body > 0 then return body end
end
local function currentVersion()
local ok, v = pcall(function() return version() end)
if ok and type(v) == "string" and v ~= "" then return (v:gsub("%s*,%s*", ".")) end
end
local PLAT = {
{"AndroidApp", "Mobile · Android", "smartphone"},
{"iOS", "Mobile · iOS", "smartphone"},
}
local cur = currentVersion()
local mobile = UIS.TouchEnabled
local head = new("Frame", {
Size = UDim2.new(1, 0, 0, 66), BackgroundColor3 = T.glow, BorderSizePixel = 0, LayoutOrder = 1, Parent = rb,
}, {round(12), stroke(T.gold, 1)})
FX.cardSkin(head)
local iconBox = new("Frame", {
Position = UDim2.fromOffset(12, 11), Size = UDim2.fromOffset(44, 44), BackgroundColor3 = T.panel2, BorderSizePixel = 0, Parent = head,
}, {round(12), stroke(T.bronzeLo, 1)})
local fbIcon = icon(iconBox, "cube", 24, T.tan, 1.5)
fbIcon.holder.AnchorPoint, fbIcon.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
local rbImg = new("ImageLabel", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromScale(.74, .74), BackgroundTransparency = 1,
ScaleType = Enum.ScaleType.Fit, ImageTransparency = 1, ZIndex = 3, Parent = iconBox,
}, {round(8)})
rbImg:SetAttribute("NoTheme", true)
text(head, "Roblox", 15, "Bold", T.text, {Position = UDim2.fromOffset(68, 12), Size = UDim2.new(1, -80, 0, 20), NoI18N = true})
local headSub = text(head, "", 10, "SemiBold", T.tan, {Position = UDim2.fromOffset(68, 34), Size = UDim2.new(1, -80, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
local function paintHead()
if cur then
headSub.Text = "Running " .. cur .. " \u{2022} " .. (mobile and "Mobile" or "Desktop")
else
headSub.Text = "Running version unavailable in this executor"
end
end
paintHead()
task.spawn(function()
local path = PATH.img .. "/roblox_icon.dat"
local function good(d)
return type(d) == "string" and #d > 16 and (d:sub(1, 4) == "\137PNG" or d:sub(1, 3) == "\255\216\255")
end
pcall(function() if isfile(path) and not good(readfile(path)) then delfile(path) end end)
local asset = toAsset(path, function()
for _, u in ipairs({
"https://www.google.com/s2/favicons?domain=roblox.com&sz=128",
"https://www.google.com/s2/favicons?domain=www.roblox.com&sz=64",
"https://www.roblox.com/apple-touch-icon.png",
}) do
local d = rbGet(u)
if good(d) then return d end
end
error("no roblox icon")
end)
if asset and rbImg.Parent then
rbImg.Image = asset
fbIcon.holder.Visible = false
tween(rbImg, {ImageTransparency = 0}, .3)
end
end)
local list = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 2, Parent = rb,
}, {vlist(8)})
local busy, loaded = false, false
local function clearList()
for _, c in ipairs(list:GetChildren()) do
if c:IsA("GuiObject") then c:Destroy() end
end
end
local function note(msg, order)
return text(list, msg, 11, "SemiBold", T.muted, {
LayoutOrder = order or 1, TextWrapped = true, AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, 0, 0, 0), NoI18N = true,
})
end
local function statusCard(order)
FX.card(list, {
order = order or 1, height = 62, icon = "info", iconColor = T.tan,
title = "Hyundax IUM availability · " .. VERSION,
sub = "This build has no uptime telemetry or outage log. Historical online/offline status cannot be verified.",
badge = {"UNKNOWN", T.tan}, raw = true,
})
end
loadRoblox = function(force)
if busy or (loaded and not force) then return end
busy = true
cur = currentVersion()
paintHead()
clearList()
note("Loading Roblox versions...")
task.spawn(function()
local rows, hist = {}, {}
for _, pl in ipairs(PLAT) do
local body = rbGet("https://clientsettingscdn.roblox.com/v2/client-version/" .. pl[1])
if body then
local ok, d = pcall(function() return HttpService:JSONDecode(body) end)
if ok and type(d) == "table" and d.version then
rows[#rows + 1] = {pl = pl, ver = tostring(d.version), up = tostring(d.clientVersionUpload or "")}
end
end
end
local dh = rbGet("https://setup.rbxcdn.com/DeployHistory.txt")
if dh then
for kind, up, date, fv in dh:gmatch("New (%S+) (version%-%x+) at ([^,\r\n]+), file version: ([%d, ]+)") do
if kind == "AndroidApp" or kind == "iOS" then
local v = (fv:gsub("%s*,%s*", "."):gsub("[%.%s]+$", ""))
hist[#hist + 1] = {up = up, date = date, ver = v, platform = kind == "AndroidApp" and "Android" or "iOS"}
if #hist > 8 then table.remove(hist, 1) end
end
end
end
busy = false
if not list.Parent then return end
clearList()
if #rows == 0 and #hist == 0 then
statusCard(1)
note("Could not reach Roblox servers.\nCheck your connection / HttpGet support.", 2)
FX.card(list, {order = 99, height = 40, icon = "refresh", title = "Try again", onClick = function() loadRoblox(true) end})
return
end
loaded = true
statusCard(1)
local order, found = 1, false
local function nextOrder() order += 1 return order end
local function title(msg)
text(list, msg, 10, "Bold", T.tan, {LayoutOrder = nextOrder(), Size = UDim2.new(1, 0, 0, 14), NoI18N = true})
end
if #rows > 0 then
title("LATEST MOBILE RELEASES")
for _, r in ipairs(rows) do
local isCur = cur ~= nil and cur == r.ver
found = found or isCur
FX.card(list, {
order = nextOrder(), height = 50, icon = r.pl[3], iconColor = isCur and T.gold or T.tan, title = r.ver,
sub = r.pl[2] .. " \u{2022} " .. r.up, badge = isCur and {"CURRENT", T.gold} or nil, active = isCur, raw = true,
})
end
end
if #hist > 0 then
title("RECENT MOBILE BUILDS")
for i = #hist, 1, -1 do
local h = hist[i]
local isCur = cur ~= nil and cur == h.ver
found = found or isCur
FX.card(list, {
order = nextOrder(), height = 50, icon = "history", iconColor = isCur and T.gold or T.tan, title = h.ver,
sub = (h.platform and (h.platform .. " · ") or "") .. h.date, badge = isCur and {"CURRENT", T.gold} or nil, active = isCur, raw = true,
})
end
end
if cur and not found then
local n = note("Your version (" .. cur .. ") is not in the mobile lists above. It may be older, a beta, a custom build or a desktop client.", nextOrder())
end
FX.card(list, {order = 99, height = 40, icon = "refresh", title = "Refresh", onClick = function() loadRoblox(true) end})
end)
end
pickTab("Hyundax IUM")
end, "filetext")
home.add("Recent Scripts", function(view)
local sc = scroller(view, {}, {pad(14), vlist(6)})
local empty = text(view, "No recent scripts yet.", 12, "Regular", T.muted, {Position = UDim2.fromOffset(14, 16), Size = UDim2.new(1, -28, 0, 18), Visible = false})
return function()
for _, c in ipairs(sc:GetChildren()) do if c:IsA("Frame") then c:Destroy() end end
for i, s in ipairs(recents) do
local r = new("Frame", {Size = UDim2.new(1, 0, 0, 52), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = i, Parent = sc}, {round(12), stroke(T.line)})
FX.chip(r, "file", 32, T.tan, UDim2.fromOffset(10, 10))
text(r, s.name, 12, "SemiBold", T.text, {Position = UDim2.fromOffset(52, 9), Size = UDim2.new(1, -168, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd})
text(r, #s.code .. " chars", 10, "Regular", T.muted, {Position = UDim2.fromOffset(52, 28), Size = UDim2.new(1, -168, 0, 14)})
local function mini(label, x, bg, fg, cb)
local b = new("TextButton", {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, x, .5, 0), Size = UDim2.fromOffset(46, 26),
BackgroundColor3 = bg, AutoButtonColor = false, Text = label, TextSize = 11, FontFace = F.SemiBold, TextColor3 = fg, Parent = r,
}, {round(8)})
hoverFx(b, bg, bg == T.bronze and T.bronzeHi or T.line)
pressFx(b)
b.Activated:Connect(cb)
end
mini("Run", -10, T.bronze, Color3.new(1, 1, 1), function() runCode(s.code, s.name) end)
mini("Load", -60, T.panel2, T.text, function() if newTab then newTab(s.name, s.code) end if showPage then showPage("Editor") end end)
end
empty.Visible = (#recents == 0)
end
end, "history")
home.add("sUNC", function(view)
local C_OK, C_BAD, C_POLY = Color3.fromRGB(112, 200, 130), Color3.fromRGB(226, 92, 82), T.tan
local filter = "All"
local sc = scroller(view, {Position = UDim2.fromOffset(0, 84), Size = UDim2.new(1, 0, 1, -84)}, {pad(14, 0, 14, 10), vlist(3)})
local sum = text(view, "", 11, "Medium", T.text, {Position = UDim2.fromOffset(14, 10), Size = UDim2.new(1, -28, 0, 30), TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top})
local function chip(label, x, w, primary, cb)
local b = new("TextButton", {
Position = UDim2.fromOffset(x, 48), Size = UDim2.fromOffset(w, 24), BackgroundColor3 = primary and T.bronze or T.panel2,
AutoButtonColor = false, Text = label, TextSize = 11, FontFace = F.SemiBold, TextColor3 = T.text, Parent = view,
}, {round(8), stroke(primary and T.bronzeHi or T.line)})
hoverFx(b, primary and T.bronze or T.panel2, primary and T.bronzeHi or T.panel)
pressFx(b)
b.Activated:Connect(cb)
return b
end
local function rowsFor()
local list = {}
for _, s in ipairs(Compat.specs) do
local st = s.status or (s.fn and (s.src == "native" and "native" or "poly") or "missing")
local keep = filter == "All"
or (filter == "Native" and s.src == "native")
or (filter == "Poly" and s.src == "poly")
or (filter == "Issues" and (st == "fail" or st == "polyfail" or st == "missing"))
if keep then list[#list + 1] = {s = s, st = st} end
end
return list
end
local function colorOf(st)
if st == "pass" or st == "native" then return C_OK end
if st == "poly" then return C_POLY end
if st == "fail" or st == "polyfail" then return C_BAD end
return T.muted
end
local function refresh()
for _, c in ipairs(sc:GetChildren()) do if c:IsA("Frame") then c:Destroy() end end
if Compat.running then
sum.Text = "Running tests... this can take up to a minute."
else
sum.Text = Compat.summaryText()
end
for i, r in ipairs(rowsFor()) do
local f = new("Frame", {Size = UDim2.new(1, 0, 0, 22), BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = i, Glass = true, Parent = sc}, {round(5)})
new("Frame", {Size = UDim2.fromOffset(3, 12), Position = UDim2.fromOffset(5, 5), BackgroundColor3 = colorOf(r.st), BorderSizePixel = 0, Parent = f}, {round(2)})
text(f, r.s.name, 11, "SemiBold", T.text, {Position = UDim2.fromOffset(16, 0), Size = UDim2.new(.45, -16, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd})
text(f, (r.s.cat or "") .. " · " .. r.st:upper(), 9, "Medium", colorOf(r.st), {Position = UDim2.new(.45, 0, 0, 0), Size = UDim2.new(.55, -8, 1, 0), TextXAlignment = Enum.TextXAlignment.Right, TextTruncate = Enum.TextTruncate.AtEnd})
end
end
chip("Run tests", 14, 80, true, function()
if Compat.running then toast("Tests already running") return end
task.spawn(Compat.run)
end)
chip("Copy report", 100, 92, false, function()
local ok = pcall(function() setclipboard(Compat.report()) end)
toast(ok and "Report copied" or "setclipboard unavailable")
end)
local fx = 202
for _, name in ipairs({"All", "Native", "Poly", "Issues"}) do
local w = name == "Issues" and 54 or 46
chip(name, fx, w, false, function() filter = name refresh() end)
fx += w + 6
end
Compat.onState = function() if view.Parent then refresh() end end
return refresh
end, "bolt")
do
home.list.Size = UDim2.new(1, -12, 1, -96)
local foot = new("Frame", {Position = UDim2.new(0, 6, 1, -46), Size = UDim2.new(1, -12, 0, 40), BackgroundTransparency = 1, Parent = home.side})
new("Frame", {Size = UDim2.new(1, 0, 0, 1), Position = UDim2.fromOffset(0, -4), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = foot})
avatar(foot, 26, UDim2.fromOffset(4, 7))
local footName = text(foot, I18N.shownName(), 11, "SemiBold", T.text, {Position = UDim2.fromOffset(36, 5), Size = UDim2.new(1, -40, 0, 14), TextTruncate = Enum.TextTruncate.AtEnd})
I18N.watchers[#I18N.watchers + 1] = function() footName.Text = I18N.shownName() end
text(foot, "Signed in", 10, "Regular", T.muted, {Position = UDim2.fromOffset(36, 20), Size = UDim2.new(1, -40, 0, 12)})
end
local EXP_W, STATUS_H, HEAD_H, PANEL_H, GUTTER_W = 124, 18, 22, 66, 30
local TOOL_H, INPUT_H = 30, 22
local TOP_H = 30 + TOOL_H
local ed = group(pages, {ClipsDescendants = true})
pageMap.Editor = ed
local expl = new("Frame", {Size = UDim2.new(0, EXP_W, 1, 0), BackgroundColor3 = T.side, BorderSizePixel = 0, ClipsDescendants = true, Parent = ed})
new("Frame", {Size = UDim2.new(0, 1, 1, 0), Position = UDim2.new(1, -1, 0, 0), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = expl})
text(expl, "Explorer", 14, "Bold", T.text, {Position = UDim2.fromOffset(12, 8), Size = UDim2.new(1, -24, 0, 22)})
do
local sb = new("TextBox", {
Position = UDim2.fromOffset(8, 36), Size = UDim2.new(1, -16, 0, 24), BackgroundColor3 = T.panel, Text = "",
PlaceholderText = "Search files...", PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 11, FontFace = F.Regular,
ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, Parent = expl,
}, {round(8), pad(24, 0, 8, 0)})
local st = stroke(T.line, 1)
st.Parent = sb
local si = icon(expl, "search", 12, T.muted, 1.3)
si.holder.Position = UDim2.fromOffset(15, 42)
sb.Focused:Connect(function() tween(st, {Color = T.tan}, .2) si.set(T.tan, .2) end)
sb.FocusLost:Connect(function() tween(st, {Color = T.line}, .2) si.set(T.muted, .2) end)
sb:GetPropertyChangedSignal("Text"):Connect(function()
if Store.filter then Store.filter(sb.Text) end
end)
end
local expList = scroller(expl, {Position = UDim2.fromOffset(8, 68), Size = UDim2.new(1, -16, 1, -74), ScrollBarThickness = 0}, {vlist(4)})
Store.API = "https://scriptblox.com/api/script/"
Store.NATIVE = {"autoexec", "Autoexec", "AutoExec", "autoexecute", "Autoexecute", "AutoExecute", "../autoexec", "../Autoexecute", "../AutoExecute"}
function Store.popupBG(host, r)
if not host or host:GetAttribute("PopupStyled") then return end
host:SetAttribute("PopupStyled", true)
host:SetAttribute("NoGlass", true)
host.BackgroundTransparency = 0
end
local function httpGet(url, headers)
local req = request or http_request or (syn and syn.request)
if type(req) == "function" then
local h = { ["Accept"] = "application/json, text/plain, */*", ["User-Agent"] = "Mozilla/5.0" }
if type(headers) == "table" then for k, v in pairs(headers) do h[k] = v end end
local ok, res = pcall(req, {Url = url, Method = "GET", Headers = h, Timeout = 12})
if ok and type(res) == "table" then
local status = tonumber(res.StatusCode or res.Status) or 200
local body = res.Body or res.body
if status >= 200 and status < 300 and type(body) == "string" and #body > 0 then return body end
end
end
local ok, body = pcall(function() return game:HttpGet(url) end)
if ok and type(body) == "string" and #body > 0 then return body end
return nil
end
local function decodeJSON(url, headers)
local body = httpGet(url, headers)
if type(body) ~= "string" then return nil end
local ok, data = pcall(function() return HttpService:JSONDecode(body) end)
if ok and type(data) == "table" then return data end
return nil
end
function Store.apiGet(path)
return decodeJSON(Store.API .. tostring(path or ""))
end
local function isSourceCode(code)
if type(code) ~= "string" or code:gsub("%s", "") == "" then return false end
local head = code:sub(1, 300):lower():gsub("^%s+", "")
if head:match("^%-%- could not fetch script") then return false end
if head:sub(1, 1) == "<"
or head:match('^%{%s*"')
or head:match("^error[%s:]")
or head:match("^unauthorized[%s:]")
or head:match("^forbidden[%s:]")
or head:match("^not found[%s:]")
or head:match("^too many requests") then return false end
return true
end
function Store.ensureCode(s)
if type(s) ~= "table" then return nil end
if isSourceCode(s.code) then return s.code end
local code
if type(s.raw) == "string" and s.raw ~= "" then
local body = httpGet(s.raw, { ["Accept"] = "text/plain, */*" })
if isSourceCode(body) then code = body end
end
if not code and s.src == "scriptblox" then
local slug = tostring(s.slug or "")
if slug ~= "" then
local res = Store.apiGet(slug)
local detail = res and (res.script or res.result or res.data or res)
if type(detail) == "table" then
local scriptData = detail.script
if type(scriptData) == "table" then scriptData = scriptData.script or scriptData.source or scriptData.code end
if isSourceCode(scriptData) then code = scriptData end
end
if not code then
local body = httpGet("https://scriptblox.com/raw/" .. HttpService:UrlEncode(slug), { ["Accept"] = "text/plain, */*" })
if isSourceCode(body) then code = body end
end
end
elseif not code and Store.codeOf then
local ok, fetched = pcall(Store.codeOf, s)
if ok and isSourceCode(fetched) then code = fetched end
end
if isSourceCode(code) then s.code = code; return code end
return nil
end
function Store.realGameName()
if Store.gname then return Store.gname end
local name
pcall(function() name = game:GetService("MarketplaceService"):GetProductInfo(game.PlaceId).Name end)
if type(name) ~= "string" or name == "" or name:lower() == "ugc" then
name = tostring(game.Name)
if name:lower() == "ugc" or name == "" then name = nil end
end
if name then Store.gname = name end
return name or "this game"
end
function Store.gameNames()
if Store.gnames then return Store.gnames end
local names, seen = {}, {}
local function add(n)
if type(n) == "string" then
n = n:gsub("^%s+", ""):gsub("%s+$", "")
if n ~= "" and n:lower() ~= "ugc" and not seen[n:lower()] then
seen[n:lower()] = true
names[#names + 1] = n
end
end
end
add(Store.realGameName())
local req = request or http_request or (syn and syn.request)
if req and game.GameId and game.GameId ~= 0 then
for _, lang in ipairs({"pt-BR", "en-US", "es-ES", "fr-FR", "de-DE", "id-ID"}) do
pcall(function()
local r = req({Url = "https://games.roblox.com/v1/games?universeIds=" .. game.GameId, Method = "GET", Headers = {["Accept-Language"] = lang}})
local d = r and r.Body and HttpService:JSONDecode(r.Body)
add(d and d.data and d.data[1] and d.data[1].name)
end)
pcall(function()
local r = req({Url = "https://apis.roblox.com/universes/v1/universes/" .. game.GameId .. "/places/" .. game.PlaceId .. "?locale=" .. lang, Method = "GET", Headers = {["Accept-Language"] = lang}})
local d = r and r.Body and HttpService:JSONDecode(r.Body)
add(d and d.name)
end)
end
end
Store.gnames = names
return names
end
task.spawn(function() pcall(Store.realGameName) pcall(Store.gameNames) end)
function Store.saveCloud() jsonWrite(PATH.cloud, Store.cloud) end
function Store.saveLikes() jsonWrite(PATH.likes, Store.likes) end
function Store.cloudIndex(slug)
for i, s in ipairs(Store.cloud) do
if s.slug == slug then return i end
end
end
function Store.removeCloud(slug)
local i = Store.cloudIndex(slug)
if i then
table.remove(Store.cloud, i)
Store.saveCloud()
end
if Store.refresh then Store.refresh() end
end
function Store.runCloud(s)
task.spawn(function()
local code = Store.ensureCode(s)
if not isSourceCode(code) then toast("Could not fetch script source") return end
runCode(code, s.title)
end)
end
function Store.addAuto(name, code)
local fname = safeName(name) .. ".lua"
local localPath = PATH.auto .. "/" .. fname
local ok = pcall(function()
if not (writefile and isfile and readfile) then error("file APIs unavailable") end
writefile(localPath, code)
if not isfile(localPath) then error("file was not created") end
end)
if not ok then return nil end
for i, e in ipairs(Store.auto) do
if e.name == name then table.remove(Store.auto, i) break end
end
table.insert(Store.auto, {name = name, file = localPath, native = nil})
jsonWrite(PATH.autoIdx, Store.auto)
if Store.refresh then Store.refresh() end
return false
end
function Store.removeAuto(name)
for i, e in ipairs(Store.auto) do
if e.name == name then
pcall(function()
if delfile then
delfile(e.file)
if e.native then delfile(e.native) end
end
end)
table.remove(Store.auto, i)
break
end
end
jsonWrite(PATH.autoIdx, Store.auto)
if Store.refresh then Store.refresh() end
end
function Store.runAuto()
for _, e in ipairs(Store.auto) do
local path = e.file or (PATH.auto .. "/" .. safeName(e.name) .. ".lua")
local ok, code = pcall(function()
if not (isfile and isfile(path) and readfile) then error("saved file missing") end
return readfile(path)
end)
if ok and type(code) == "string" and code:gsub("%s", "") ~= "" then
runCode(code, "AutoExec: " .. tostring(e.name or "script"))
else
addLine("Console", "[autoexec] could not read " .. tostring(e.name or path), T.bronzeHi)
end
end
end
do
local function expSection(title, ico, order)
local wrap = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = order, Parent = expList}, {vlist(3)})
local head = new("TextButton", {Size = UDim2.new(1, 0, 0, 26), BackgroundColor3 = T.panel, AutoButtonColor = false, Text = "", LayoutOrder = 1, Parent = wrap}, {round(6), stroke(T.line)})
local left = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = head}, {pad(8, 0), hlist(6)})
local ic = icon(left, ico, 13, T.tan, 1.4)
ic.holder.LayoutOrder = 1
text(left, title, 11, "SemiBold", T.text, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14), LayoutOrder = 2})
local count = text(head, "0", 10, "Bold", T.tan, {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -22, .5, 0), Size = UDim2.fromOffset(24, 14), TextXAlignment = Enum.TextXAlignment.Right,
Visible = false, NoI18N = true,
})
local ch = icon(head, "chevD", 10, T.muted, 1.4)
ch.holder.AnchorPoint, ch.holder.Position = Vector2.new(1, .5), UDim2.new(1, -6, .5, 0)
local items = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 2, Parent = wrap}, {vlist(3)})
local sec = {items = items, count = count, open = true, rows = {}}
hoverFx(head, T.panel, T.panel2)
pressFx(head, .97)
head.Activated:Connect(function()
sec.open = not sec.open
items.Visible = sec.open
tween(ch.holder, {Rotation = sec.open and 0 or -90}, .25)
end)
return sec
end
local function expClear(sec)
for _, c in ipairs(sec.items:GetChildren()) do
if not c:IsA("UIListLayout") then c:Destroy() end
end
sec.rows = {}
end
local function expRow(sec, label, ico, onClick, onDelete, order)
local r = new("TextButton", {Size = UDim2.new(1, 0, 0, 24), BackgroundColor3 = T.panel, AutoButtonColor = false, Text = "", LayoutOrder = order, Parent = sec.items}, {round(5)})
local i = icon(r, ico, 10, T.tan, 1.4)
i.holder.Position = UDim2.new(0, 7, .5, -5)
text(r, label, 10, "SemiBold", T.text, {Position = UDim2.fromOffset(22, 0), Size = UDim2.new(1, -46, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd})
local x = new("TextButton", {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -2, .5, 0), Size = UDim2.fromOffset(20, 20), BackgroundTransparency = 1, Text = "", Parent = r})
local xi = icon(x, "x", 9, T.muted, 1.3)
xi.holder.AnchorPoint, xi.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
x.MouseEnter:Connect(function() xi.set(T.bronzeHi, .15) end)
x.MouseLeave:Connect(function() xi.set(T.muted, .2) end)
hoverFx(r, T.panel, T.panel2)
pressFx(r, .97)
r.Activated:Connect(onClick)
x.Activated:Connect(onDelete)
table.insert(sec.rows, {frame = r, label = tostring(label):lower()})
end
local secCloud = expSection("Cloud Scripts", "cloud", 1)
local secAuto = expSection("Auto-Execute", "refresh", 2)
function Store.refresh()
expClear(secCloud)
expClear(secAuto)
for i, s in ipairs(Store.cloud) do
expRow(secCloud, s.title, "play", function() Store.runCloud(s) end, function() Store.removeCloud(s.slug) end, i)
end
for i, e in ipairs(Store.auto) do
expRow(secAuto, e.name, "refresh", function()
local ok, code = pcall(readfile, e.file)
if ok and type(code) == "string" then
newTab(e.name, code)
showPage("Editor")
end
end, function() Store.removeAuto(e.name) end, i)
end
if #Store.cloud == 0 then
text(secCloud.items, "No scripts yet", 10, "Medium", T.muted, {Size = UDim2.new(1, 0, 0, 16), LayoutOrder = 1})
end
if #Store.auto == 0 then
text(secAuto.items, "No scripts yet", 10, "Medium", T.muted, {Size = UDim2.new(1, 0, 0, 16), LayoutOrder = 1})
end
secCloud.count.Text = tostring(#Store.cloud)
secAuto.count.Text = tostring(#Store.auto)
end
function Store.filter(q)
q = tostring(q):lower()
for _, sec in ipairs({secCloud, secAuto}) do
for _, r in ipairs(sec.rows) do
r.frame.Visible = (q == "" or r.label:find(q, 1, true) ~= nil)
end
end
end
Store.refresh()
end
local em = new("Frame", {Position = UDim2.fromOffset(EXP_W, 0), Size = UDim2.new(1, -EXP_W, 1, 0), BackgroundTransparency = 1, Parent = ed})
local tabsRow = new("Frame", {Size = UDim2.new(1, 0, 0, 30), BackgroundTransparency = 1, Parent = em})
local expToggle = new("TextButton", {Size = UDim2.fromOffset(28, 30), BackgroundTransparency = 1, Text = "", Parent = tabsRow})
local menuIc = icon(expToggle, "menu", 14, T.muted, 1.4)
menuIc.holder.AnchorPoint, menuIc.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
expToggle.MouseEnter:Connect(function() menuIc.set(T.tan, .15) end)
expToggle.MouseLeave:Connect(function() menuIc.set(T.muted, .2) end)
pressFx(expToggle, .85)
local tabList = scroller(tabsRow, {
Position = UDim2.fromOffset(28, 0), Size = UDim2.new(1, -28, 1, 0), ScrollingDirection = Enum.ScrollingDirection.X,
AutomaticCanvasSize = Enum.AutomaticSize.X, ScrollBarThickness = 0, CanvasSize = UDim2.new(),
}, {new("UIListLayout", {FillDirection = Enum.FillDirection.Horizontal, VerticalAlignment = Enum.VerticalAlignment.Bottom, Padding = UDim.new(0, 3), SortOrder = Enum.SortOrder.LayoutOrder})})
local toolbar = new("Frame", {Position = UDim2.fromOffset(0, 30), Size = UDim2.new(1, 0, 0, TOOL_H), BackgroundTransparency = 1, Parent = em})
local toolRows = {}
toolRows[1] = scroller(toolbar, {
Position = UDim2.fromOffset(0, 2), Size = UDim2.new(1, 0, 0, 26), ScrollingDirection = Enum.ScrollingDirection.X,
AutomaticCanvasSize = Enum.AutomaticSize.X, ScrollBarThickness = 0, CanvasSize = UDim2.new(),
}, {pad(6, 0), new("UIListLayout", {FillDirection = Enum.FillDirection.Horizontal, VerticalAlignment = Enum.VerticalAlignment.Center, Padding = UDim.new(0, 4), SortOrder = Enum.SortOrder.LayoutOrder})})
local codeArea = new("Frame", {Position = UDim2.fromOffset(0, TOP_H), Size = UDim2.new(1, 0, 1, -(TOP_H + 40)), BackgroundColor3 = T.bg, BackgroundTransparency = 1, BorderSizePixel = 0, ClipsDescendants = true, Parent = em})
new("Frame", {Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = codeArea}, {
new("UIGradient", {Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.line), ColorSequenceKeypoint.new(.5, T.bronze), ColorSequenceKeypoint.new(1, T.line)}), Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(.5, .35), NumberSequenceKeypoint.new(1, 1)})}),
})
local codeScroll = scroller(codeArea, {
ScrollingDirection = Enum.ScrollingDirection.XY, AutomaticCanvasSize = Enum.AutomaticSize.None, ScrollBarThickness = 4,
})
local gutter = new("TextLabel", {
BackgroundTransparency = 1, Text = "1", TextSize = 13, FontFace = MONO, TextColor3 = Color3.fromRGB(150, 40, 48), TextStrokeColor3 = Color3.new(0, 0, 0), TextStrokeTransparency = .6,
TextXAlignment = Enum.TextXAlignment.Right, TextYAlignment = Enum.TextYAlignment.Top, Size = UDim2.fromOffset(GUTTER_W, 100), Parent = codeScroll,
})
local box = new("TextBox", {
BackgroundTransparency = 1, Text = "", MultiLine = true, ClearTextOnFocus = false, TextWrapped = false,
TextSize = 13, FontFace = MONO, TextColor3 = T.text, PlaceholderText = "-- Write your Luau here", PlaceholderColor3 = T.muted, TextStrokeColor3 = Color3.new(0, 0, 0), TextStrokeTransparency = .55,
TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top,
Position = UDim2.fromOffset(GUTTER_W + 8, 0), Size = UDim2.fromOffset(200, 100), Parent = codeScroll,
})
do
local HL = {}
local LIMIT = 40000
local KW, CONST, BI, EXEC, OPS = {}, {}, {}, {}, {}
local function fill(set, list) for w in list:gmatch("[%w_]+") do set[w] = true end end
fill(KW, "and break continue do else elseif end for function if in local not or repeat return then until while export type")
fill(CONST, "true false nil")
fill(BI, "print warn error assert game workspace script shared task wait spawn delay tick time os pcall xpcall select require next unpack pairs ipairs type typeof tostring tonumber rawget rawset rawequal rawlen setmetatable getmetatable getfenv setfenv newproxy collectgarbage Instance Vector2 Vector3 Vector2int16 Vector3int16 CFrame Color3 UDim UDim2 Enum Random TweenInfo NumberRange NumberSequence NumberSequenceKeypoint ColorSequence ColorSequenceKeypoint Ray Rect Region3 BrickColor Font Axes Faces PhysicalProperties DateTime OverlapParams RaycastParams string table math coroutine bit32 utf8 debug buffer _G _VERSION")
fill(EXEC, "getgenv getrenv getreg getgc getsenv getinstances getnilinstances getscripts getloadedmodules getrunningscripts getconnections firesignal fireclickdetector fireproximityprompt firetouchinterest hookfunction hookmetamethod restorefunction newcclosure clonefunction iscclosure islclosure checkcaller isexecutorclosure checkclosure getrawmetatable setrawmetatable setreadonly isreadonly getnamecallmethod setnamecallmethod getcallingscript request http_request writefile readfile isfile isfolder makefolder delfile delfolder listfiles appendfile loadfile dofile setclipboard getclipboard toclipboard queue_on_teleport identifyexecutor getexecutorname cloneref compareinstances gethui getcustomasset getsynasset saveinstance decompile getscriptbytecode getscripthash getscriptclosure getfunctionhash setfpscap getfpscap getthreadidentity setthreadidentity getidentity setidentity isscriptable setscriptable gethiddenproperty sethiddenproperty getproperties getactors run_on_actor mouse1click mouse1press mouse1release mouse2click mouse2press mouse2release mousemoveabs mousemoverel mousescroll keypress keyrelease messagebox Drawing WebSocket crypt cache lz4compress lz4decompress getcallbackvalue hss")
for ch in ("+-*/%^#=~<>"):gmatch(".") do OPS[ch] = true end
local PAL_DARK = {kw = "#FF6B6B", const = "#D49BE8", str = "#9CCC7A", esc = "#FF9AA2", num = "#FFA7A0", com = "#6F6F6F", bi = "#E5484D", exec = "#6FB7E9", fn = "#F2D0D0", def = "#FFD6D6", prop = "#D2B8B8", self = "#FF8A94", op = "#B89A9A", attr = "#FF8A94"}
local PAL_LIGHT = {kw = "#B3202A", const = "#8E3FA8", str = "#2F7D32", esc = "#A33340", num = "#C23B3B", com = "#8A8A8A", bi = "#8E1B24", exec = "#0B6FA8", fn = "#5A2A2A", def = "#3F1418", prop = "#6B4545", self = "#B03030", op = "#7A5050", attr = "#B03030"}
local function pal()
local bg = T.bg
return (bg.R * .299 + bg.G * .587 + bg.B * .114) > .55 and PAL_LIGHT or PAL_DARK
end
local ESC = {["&"] = "&", ["<"] = "<", [">"] = ">", ['"'] = """, ["'"] = "'"}
local function esc(t) return (t:gsub("[&<>\"']", ESC)) end
HL.esc = esc
local function col(c, t) return '' .. esc(t) .. "" end
local function strOut(C, s)
local out, pos = {}, 1
while true do
local a = s:find("\\", pos, true)
if not a then break end
local b = a + 1
local nx = s:sub(b, b)
if nx == "x" then
b += 2
elseif nx == "u" then
local _, e = s:find("^u%b{}", b)
b = e or b
elseif nx:match("%d") then
local _, e = s:find("^%d%d?%d?", b)
b = e or b
end
if a > pos then out[#out + 1] = col(C.str, s:sub(pos, a - 1)) end
out[#out + 1] = col(C.esc, s:sub(a, b))
pos = b + 1
end
if pos <= #s then out[#out + 1] = col(C.str, s:sub(pos)) end
return table.concat(out)
end
function HL.render(src)
if #src > LIMIT or S.editorSyntaxHints == false then return esc(src) end
local C = pal()
local out, i, n = {}, 1, #src
local prevWord, prevOp = "", ""
local function push(s) out[#out + 1] = s end
while i <= n do
local c, j = src:sub(i, i), nil
if c == "-" and src:sub(i, i + 1) == "--" then
local lvl = src:match("^%-%-%[(=*)%[", i)
if lvl then
local _, e = src:find("]" .. lvl .. "]", i, true)
j = e or n
else
j = (src:find("\n", i, true) or (n + 1)) - 1
end
push(col(C.com, src:sub(i, j)))
elseif c == '"' or c == "'" or c == "`" then
j = i + 1
while j <= n do
local d = src:sub(j, j)
if d == "\\" then
j += 2
elseif d == c then
break
elseif d == "\n" and c ~= "`" then
j -= 1
break
else
j += 1
end
end
j = math.min(j, n)
push(strOut(C, src:sub(i, j)))
prevWord, prevOp = "", ""
elseif c == "[" and src:match("^%[=*%[", i) then
local lvl = src:match("^%[(=*)%[", i)
local _, e = src:find("]" .. lvl .. "]", i, true)
j = e or n
push(col(C.str, src:sub(i, j)))
prevWord, prevOp = "", ""
elseif c:match("%d") or (c == "." and src:sub(i + 1, i + 1):match("%d")) then
local _, e = src:find("^0[xX][%x_]+", i)
if not e then _, e = src:find("^0[bB][01_]+", i) end
if not e then
_, e = src:find("^%.?%d[%d_]*%.?[%d_]*", i)
local _, e2 = src:find("^[eE][%+%-]?%d+", (e or i) + 1)
if e2 then e = e2 end
end
j = e or i
push(col(C.num, src:sub(i, j)))
prevWord, prevOp = "", ""
elseif c:match("[%a_]") then
local _, e = src:find("^[%w_]*", i)
j = e or i
local w = src:sub(i, j)
local nxt = src:match("^%s*(.)", j + 1)
if prevOp == "." or prevOp == ":" then
if nxt == "(" or nxt == '"' or nxt == "'" or nxt == "{" then push(col(C.fn, w)) else push(col(C.prop, w)) end
elseif KW[w] then push(col(C.kw, w))
elseif CONST[w] then push(col(C.const, w))
elseif w == "self" then push(col(C.self, w))
elseif prevWord == "function" then push(col(C.def, w))
elseif EXEC[w] then push(col(C.exec, w))
elseif BI[w] then push(col(C.bi, w))
elseif nxt == "(" then push(col(C.fn, w))
else push(esc(w)) end
prevWord, prevOp = w, ""
elseif c:match("%s") then
local _, e = src:find("^%s+", i)
j = e or i
push(src:sub(i, j))
else
j = i
if c == "@" then
local _, e = src:find("^@[%w_]+", i)
if e then j = e; push(col(C.attr, src:sub(i, j))) else push(esc(c)) end
prevOp = ""
elseif c == "." and src:sub(i, i + 1) == ".." then
j = (src:sub(i, i + 2) == "...") and i + 2 or i + 1
push(col(C.op, src:sub(i, j)))
prevOp = ".."
elseif OPS[c] then
push(col(C.op, c))
prevOp = c
elseif c:match("[%(%)%{%}%[%],;]") then
local _, e = src:find("^[%(%)%{%}%[%],;]+", i)
j = e or i
push(esc(src:sub(i, j)))
prevOp = src:sub(j, j)
else
push(esc(c))
prevOp = c
end
prevWord = ""
end
i = j + 1
end
return table.concat(out)
end
S.hl = new("TextLabel", {
Name = "SyntaxLayer", BackgroundTransparency = 1, Text = "", RichText = true, TextSize = 13, FontFace = MONO, TextColor3 = T.text,
TextStrokeColor3 = Color3.new(0, 0, 0), TextStrokeTransparency = .55, TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Top, Position = box.Position, Size = box.Size, ZIndex = 1, Active = false, Parent = codeScroll,
})
box.ZIndex = 2
box.TextTransparency = 1
local hlTok = 0
local function hlUpdate()
hlTok += 1
local my, txt = hlTok, box.Text
if #txt < 6000 then
S.hl.Text = HL.render(txt)
return
end
S.hl.Text = HL.esc(txt)
task.delay(#txt < 20000 and .08 or .2, function()
if my == hlTok then S.hl.Text = HL.render(box.Text) end
end)
end
box:GetPropertyChangedSignal("Text"):Connect(hlUpdate)
S.highlightLua = HL.render
end
;(function()
local lineHi = new("Frame", {
Name = "LineHighlight", Size = UDim2.fromOffset(200, 16), BackgroundColor3 = T.bronze, BackgroundTransparency = .9,
BorderSizePixel = 0, ZIndex = 0, Parent = codeScroll,
}, {round(3)})
local lineState = {ln = 1}
local function placeHi(animate)
local lines = select(2, gutter.Text:gsub("\n", "")) + 1
local lh = gutter.TextBounds.Y / math.max(lines, 1)
if lh < 8 then lh = 15 end
local goal = {
Position = UDim2.fromOffset(0, (lineState.ln - 1) * lh),
Size = UDim2.fromOffset(math.max(codeScroll.CanvasSize.X.Offset, 40), lh),
}
if animate then
tween(lineHi, goal, .25)
else
for k, v in pairs(goal) do lineHi[k] = v end
end
end
box.Focused:Connect(function() tween(lineHi, {BackgroundTransparency = .84}, .3) end)
box.FocusLost:Connect(function() tween(lineHi, {BackgroundTransparency = .94}, .4) end)
local panelBody = new("Frame", {Size = UDim2.new(1, 0, 0, PANEL_H), BackgroundColor3 = T.bg, BorderSizePixel = 0, ClipsDescendants = true, Parent = em})
local panelHead = new("Frame", {Size = UDim2.new(1, 0, 0, HEAD_H), BackgroundColor3 = T.bg, BorderSizePixel = 0, Glass = true, Parent = em})
new("Frame", {Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = panelHead})
local statusRow = new("Frame", {Size = UDim2.new(1, 0, 0, STATUS_H), Position = UDim2.new(0, 0, 1, -STATUS_H), BackgroundColor3 = T.bg, BorderSizePixel = 0, Glass = true, Parent = em})
panels.Console = scroller(panelBody, {Size = UDim2.new(1, 0, 1, -INPUT_H)}, {pad(8, 3), vlist(0)})
local panelOpen = true
local relayout
do
local btn = new("TextButton", {Size = UDim2.fromOffset(104, HEAD_H), BackgroundTransparency = 1, Text = "", Parent = panelHead})
local inner = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = btn}, {pad(8, 0), hlist(6)})
local cIc = icon(inner, "terminal", 12, T.tan, 1.5)
cIc.holder.LayoutOrder = 1
text(inner, "CONSOLE", 10, "Bold", T.text, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14), LayoutOrder = 2})
new("Frame", {Size = UDim2.new(1, -16, 0, 2), Position = UDim2.new(0, 8, 1, -2), BackgroundColor3 = T.gold, BorderSizePixel = 0, Parent = btn}, {round(1)})
btn.Activated:Connect(function()
panelOpen = not panelOpen
relayout(true)
end)
local clr = new("TextButton", {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -6, .5, 0), Size = UDim2.fromOffset(26, 18), BackgroundTransparency = 1, Text = "", Parent = panelHead})
local ci = icon(clr, "trash", 12, T.muted, 1.4)
ci.holder.AnchorPoint, ci.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
clr.MouseEnter:Connect(function() ci.set(T.bronzeHi, .15) end)
clr.MouseLeave:Connect(function() ci.set(T.muted, .2) end)
pressFx(clr, .85)
clr.Activated:Connect(function()
LOG.clear()
end)
local chipsF = new("Frame", {
Position = UDim2.fromOffset(106, 0), Size = UDim2.new(1, -106 - 62, 1, 0), BackgroundTransparency = 1, ClipsDescendants = true, Parent = panelHead,
}, {hlist(3)})
local chipObj = {}
local function paintChips()
for k, o in pairs(chipObj) do
local on = (k == LOG.filter)
tween(o.b, {BackgroundColor3 = on and T.panel2 or T.bg}, .15)
tween(o.l, {TextColor3 = on and (LOG.colors[k] or T.gold) or T.muted}, .15)
end
end
for i, d in ipairs({{"all", "ALL"}, {"out", "OUT"}, {"info", "INFO"}, {"warn", "WARN"}, {"err", "ERR"}}) do
local b = new("TextButton", {
Size = UDim2.fromOffset(0, 16), AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = T.bg, AutoButtonColor = false,
Text = "", LayoutOrder = i, Parent = chipsF,
}, {round(4), pad(5, 0)})
local l = text(b, d[2], 9, "Bold", T.muted, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 16)})
chipObj[d[1]] = {b = b, l = l}
b.Activated:Connect(function()
LOG.setFilter(d[1])
paintChips()
end)
end
paintChips()
local ex = new("TextButton", {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -34, .5, 0), Size = UDim2.fromOffset(26, 18), BackgroundTransparency = 1, Text = "", Parent = panelHead})
local exPlus = icon(ex, "plus", 12, T.muted, 1.4)
local exMinus = icon(ex, "minus", 12, T.muted, 1.4)
for _, o in ipairs({exPlus, exMinus}) do
o.holder.AnchorPoint, o.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
end
exMinus.holder.Visible = false
ex.MouseEnter:Connect(function() exPlus.set(T.tan, .15) exMinus.set(T.tan, .15) end)
ex.MouseLeave:Connect(function() exPlus.set(T.muted, .2) exMinus.set(T.muted, .2) end)
pressFx(ex, .85)
ex.Activated:Connect(function()
S.tall = not S.tall
exPlus.holder.Visible, exMinus.holder.Visible = not S.tall, S.tall
if not panelOpen then panelOpen = true end
relayout(true)
LOG.scroll()
end)
local row = new("Frame", {AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 0, 1, 0), Size = UDim2.new(1, 0, 0, INPUT_H), BackgroundColor3 = T.panel, BorderSizePixel = 0, Glass = true, Parent = panelBody})
new("Frame", {Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = row})
text(row, ">", 12, "Bold", T.tan, {Position = UDim2.fromOffset(9, 0), Size = UDim2.fromOffset(12, INPUT_H), FontFace = MONO})
local cmd = new("TextBox", {
Position = UDim2.fromOffset(24, 0), Size = UDim2.new(1, -32, 1, 0), BackgroundTransparency = 1, Text = "",
PlaceholderText = "Type a command and press Enter...", PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 11,
FontFace = MONO, ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, Parent = row,
})
cmd.FocusLost:Connect(function(enter)
local c = cmd.Text
if not enter or c:gsub("%s", "") == "" then return end
cmd.Text = ""
addLine("Console", "> " .. c, T.tan)
if not loadstring then
addLine("Console", "loadstring is not available in this environment.", T.bronzeHi)
return
end
local f = loadstring("return " .. c)
if f then
task.spawn(function()
local ok, res = pcall(f)
if not ok then addLine("Console", tostring(res), T.bronzeHi)
elseif res ~= nil then addLine("Console", tostring(res), T.text) end
end)
else
runCode(c, "console", true)
end
end)
end
local statusName = text(statusRow, "Tab #1", 10, "Regular", T.muted, {Position = UDim2.fromOffset(8, 0), Size = UDim2.new(.4, 0, 1, 0)})
local statusPos = text(statusRow, "Ln 1, Col 1 Spaces: 4 UTF-8 Luau", 10, "Regular", T.muted, {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -8, 0, 0), Size = UDim2.new(.6, 0, 1, 0), TextXAlignment = Enum.TextXAlignment.Right,
})
local function refreshCode()
local lines = select(2, box.Text:gsub("\n", "")) + 1
local nums = table.create(lines)
for i = 1, lines do nums[i] = tostring(i) end
gutter.Text = table.concat(nums, "\n")
local gw = S.lineNums and GUTTER_W or 0
gutter.Visible = S.lineNums
box.Position = UDim2.fromOffset(gw + (S.lineNums and 8 or 6), 0)
local win = codeScroll.AbsoluteSize / math.max(rootScale.Scale, .01)
local tb = box.TextBounds
local w = S.wrap and math.max(win.X - gw - 14, 40) or math.max(win.X - gw - 14, tb.X + 24)
local h = math.max(win.Y, tb.Y + 16)
box.TextWrapped = S.wrap
box.Size = UDim2.fromOffset(w, h)
S.hl.Size, S.hl.Position, S.hl.TextWrapped = box.Size, box.Position, S.wrap
gutter.Size = UDim2.fromOffset(GUTTER_W, h)
codeScroll.CanvasSize = UDim2.fromOffset(gw + w + 14, h)
placeHi(false)
end
local function updateCursor()
local pos, ln, col = box.CursorPosition, 1, 1
if pos > 0 then
local before = box.Text:sub(1, pos - 1)
ln = select(2, before:gsub("\n", "")) + 1
col = #(before:match("[^\n]*$") or "") + 1
end
statusPos.Text = ("Ln %d, Col %d Spaces: 4 UTF-8 Luau"):format(ln, col)
if lineState.ln ~= ln then
lineState.ln = ln
placeHi(true)
end
end
relayout = function(animate)
local bodyH = 0
if panelOpen then
bodyH = PANEL_H
if S.tall then
bodyH = math.clamp(math.floor(em.AbsoluteSize.Y / math.max(rootScale.Scale, .01)) - 165, PANEL_H, 260)
end
end
local goals = {
{codeArea, {Size = UDim2.new(1, 0, 1, -(TOP_H + STATUS_H + HEAD_H + bodyH))}},
{panelHead, {Position = UDim2.new(0, 0, 1, -(STATUS_H + HEAD_H + bodyH))}},
{panelBody, {Position = UDim2.new(0, 0, 1, -(STATUS_H + bodyH)), Size = UDim2.new(1, 0, 0, bodyH)}},
}
for _, g in ipairs(goals) do
if animate then tween(g[1], g[2], .4) else for k, v in pairs(g[2]) do g[1][k] = v end end
end
if not animate then refreshCode() end
end
local WELCOME = "-- Welcome to Hyundax IUM\n-- Write your Luau code here and press Execute.\n"
local tabs, active, counter = {}, 2, 1
tabs[1] = {name = "Welcome", text = WELCOME}
tabs[2] = {name = "Tab #1", text = ""}
local tabUI = {}
local renderTabs, plusBtn
local function setActive(i)
if active ~= i then FX.snd("tab") end
active = i
box.Text = tabs[i].text
statusName.Text = tabs[i].name
box.TextTransparency, S.hl.TextTransparency, gutter.TextTransparency = 1, 1, 1
tween(S.hl, {TextTransparency = 0}, .45)
tween(gutter, {TextTransparency = 0}, .45)
renderTabs()
refreshCode()
updateCursor()
end
newTab = function(name, txt)
counter += 1
table.insert(tabs, {name = name or ("Tab #" .. counter), text = txt or ""})
setActive(#tabs)
task.defer(function() tween(tabList, {CanvasPosition = Vector2.new(tabList.AbsoluteCanvasSize.X, 0)}, .3) end)
end
local function closeTab(t)
local i = table.find(tabs, t)
if not i then return end
table.remove(tabs, i)
if #tabs == 0 then newTab() return end
setActive(math.clamp(active >= i and active - 1 or active, 1, #tabs))
end
local TAB_H, TAB_R = 26, 10
local TAB_IDLE, TAB_HOVER = T.panel, T.panel2
local function buildTab(t)
local f = new("Frame", {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, TAB_H), BackgroundTransparency = 1, ClipsDescendants = true, Parent = tabList})
local card = new("Frame", {Size = UDim2.new(1, 0, 0, TAB_H + TAB_R), BackgroundColor3 = TAB_IDLE, BorderSizePixel = 0, Glass = true, Parent = f}, {round(TAB_R)})
local fill = card
local row = new("Frame", {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, TAB_H), BackgroundTransparency = 1, ZIndex = 2, Parent = f}, {hlist(0), pad(4, 0, 0, 0)})
local lead = new("Frame", {Size = UDim2.fromOffset(18, TAB_H), BackgroundTransparency = 1, LayoutOrder = 0, ZIndex = 2, Parent = row})
local lic = icon(lead, t.name == "Welcome" and "home" or "file", 11, T.muted, 1.4)
lic.holder.AnchorPoint, lic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
lic.holder.ZIndex = 3
local b = new("TextButton", {
AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, TAB_H), BackgroundTransparency = 1, Text = t.name,
TextSize = 11, FontFace = F.SemiBold, TextColor3 = T.muted, TextTransparency = 1, LayoutOrder = 1, ZIndex = 2, Parent = row,
}, {pad(4, 0, t.name == "Welcome" and 12 or 4, 0)})
local u = {f = f, card = card, fill = fill, b = b, lic = lic, on = false}
b.Activated:Connect(function() local i = table.find(tabs, t) if i then setActive(i) end end)
if t.name ~= "Welcome" then
local xhold = new("Frame", {Size = UDim2.fromOffset(18, TAB_H), BackgroundTransparency = 1, LayoutOrder = 2, ZIndex = 2, Parent = row})
local x = new("TextButton", {
AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, 0, .5, 0), Size = UDim2.fromOffset(16, 16),
BackgroundColor3 = T.line, BackgroundTransparency = 1, Text = "", ZIndex = 2, Parent = xhold,
}, {round(8)})
local xi2 = icon(x, "x", 8, T.muted, 1.3)
xi2.holder.AnchorPoint, xi2.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
xi2.holder.ZIndex = 3
x.MouseEnter:Connect(function()
xi2.set(T.bronzeHi, .2)
tween(x, {BackgroundTransparency = .35}, .2)
tween(xi2.holder, {Rotation = 90}, .35, Enum.EasingStyle.Back)
end)
x.MouseLeave:Connect(function()
xi2.set(T.muted, .25)
tween(x, {BackgroundTransparency = 1}, .25)
tween(xi2.holder, {Rotation = 0}, .3)
end)
x.Activated:Connect(function() closeTab(t) end)
end
u.ul = new("Frame", {
AnchorPoint = Vector2.new(.5, 1), Position = UDim2.new(.5, 0, 1, 0), Size = UDim2.new(0, 0, 0, 2),
BackgroundColor3 = T.gold, BorderSizePixel = 0, ZIndex = 3, Parent = f,
}, {round(1)})
b.MouseEnter:Connect(function()
if u.on then return end
tween(card, {BackgroundColor3 = TAB_HOVER}, .25)
tween(fill, {BackgroundColor3 = TAB_HOVER}, .25)
tween(b, {TextColor3 = T.text}, .25)
lic.set(T.tan, .25)
end)
b.MouseLeave:Connect(function()
if u.on then return end
tween(card, {BackgroundColor3 = TAB_IDLE}, .3)
tween(fill, {BackgroundColor3 = TAB_IDLE}, .3)
tween(b, {TextColor3 = T.muted}, .3)
lic.set(T.muted, .3)
end)
for _, o in ipairs({card, row}) do
local goal = o.Position
o.Position = goal + UDim2.fromOffset(0, TAB_H)
tween(o, {Position = goal}, .6, Enum.EasingStyle.Quint)
end
tween(b, {TextTransparency = 0}, .5)
return u
end
renderTabs = function()
for t, u in pairs(tabUI) do
if not table.find(tabs, t) then
tabUI[t] = nil
local w = u.f.AbsoluteSize.X / math.max(rootScale.Scale, .01)
u.f.AutomaticSize = Enum.AutomaticSize.None
u.f.Size = UDim2.fromOffset(w, TAB_H)
tween(u.f, {Size = UDim2.fromOffset(0, TAB_H)}, .45, Enum.EasingStyle.Quint)
tween(u.b, {TextTransparency = 1}, .25)
task.delay(.5 * FX.scale, function() u.f:Destroy() end)
end
end
for i, t in ipairs(tabs) do
local u = tabUI[t]
if not u then u = buildTab(t) tabUI[t] = u end
u.f.LayoutOrder = i
local on = (i == active)
u.on = on
local col = on and T.panel2 or T.panel
tween(u.card, {BackgroundColor3 = col}, .4)
tween(u.fill, {BackgroundColor3 = col}, .4)
tween(u.b, {TextColor3 = on and T.text or T.muted}, .4)
u.lic.set(on and T.gold or T.muted, .4)
tween(u.ul, {Size = on and UDim2.new(1, -16, 0, 2) or UDim2.new(0, 0, 0, 2)}, .55, Enum.EasingStyle.Quint)
end
if not plusBtn then
plusBtn = new("TextButton", {Size = UDim2.fromOffset(24, 24), BackgroundTransparency = 1, Text = "", LayoutOrder = 9999, Parent = tabList})
local pi = icon(plusBtn, "plus", 13, T.muted, 1.5)
pi.holder.AnchorPoint, pi.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
plusBtn.MouseEnter:Connect(function() pi.set(T.gold, .2) tween(pi.holder, {Rotation = 90}, .45, Enum.EasingStyle.Back) end)
plusBtn.MouseLeave:Connect(function() pi.set(T.muted, .3) tween(pi.holder, {Rotation = 0}, .4) end)
pressFx(plusBtn, .8)
plusBtn.Activated:Connect(function() newTab() end)
end
end
box:GetPropertyChangedSignal("Text"):Connect(function()
tabs[active].text = box.Text
refreshCode()
end)
box:GetPropertyChangedSignal("TextBounds"):Connect(refreshCode)
box:GetPropertyChangedSignal("CursorPosition"):Connect(updateCursor)
codeScroll:GetPropertyChangedSignal("AbsoluteSize"):Connect(refreshCode)
local order = 0
local function tbtn(label, ico, cb, primary, row)
order += 1
local base = primary and T.bronze or T.panel
local b = new("TextButton", {
AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 24), BackgroundColor3 = base, AutoButtonColor = false,
Text = "", LayoutOrder = order, Parent = toolRows[1],
}, {round(8), pad(10, 0), hlist(5), stroke(primary and T.bronzeHi or T.line)})
if primary then
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(190, 140, 140)), Parent = b})
end
local ic = icon(b, ico, 15, T.text, 1.8)
ic.holder.LayoutOrder = 1
text(b, label, 11, "SemiBold", T.text, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14), LayoutOrder = 2})
hoverFx(b, base, primary and T.bronzeHi or T.panel2)
pressFx(b)
if not primary then
b.MouseEnter:Connect(function() ic.set(T.gold, .25) end)
b.MouseLeave:Connect(function() ic.set(T.text, .35) end)
end
b.Activated:Connect(cb)
return b
end
local function openDialog()
local ok, files = pcall(function() return listfiles(FOLDER) end)
local p = FX.popup({
name = "HXPopupOpen", parent = ed, z = 20, w = 340, h = 320, margin = 14,
title = "Open script", subtitle = "Open a local Hyundax IUM script", icon = "folderOpen",
})
local sc = scroller(p.body, {ScrollBarThickness = 2}, {vlist(5), pad(12, 12, 12, 12)})
local count = 0
if ok and files then
for _, path in ipairs(files) do
count += 1
local nm = path:match("[^/\\]+$") or path
local b = new("TextButton", {
Size = UDim2.new(1, 0, 0, 34), BackgroundColor3 = T.panel2, AutoButtonColor = false, Text = "",
LayoutOrder = count, Parent = sc,
}, {round(9)})
local ic = icon(b, "filecode", 14, T.tan, 1.5)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(0, .5), UDim2.new(0, 11, .5, 0)
text(b, nm, 11, "Medium", T.text, {
Position = UDim2.fromOffset(36, 0), Size = UDim2.new(1, -46, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true,
})
hoverFx(b, T.panel2, T.line)
pressFx(b, .97)
b.Activated:Connect(function()
local okr, data = pcall(readfile, path)
if okr then newTab(nm, data) toast("Opened " .. nm) end
p.close()
end)
end
end
if count == 0 then
text(sc, "No files in workspace/" .. FOLDER, 11, "Regular", T.muted, {
Size = UDim2.new(1, 0, 0, 60), TextXAlignment = Enum.TextXAlignment.Center, TextWrapped = true,
})
end
end
local function readClipboard()
local ok, value = pcall(function()
if getclipboard then return getclipboard() end
if get_clipboard then return get_clipboard() end
error("Clipboard read is unavailable")
end)
if ok and type(value) == "string" then return value end
end
local btnExec
btnExec = tbtn("Execute", "play", function()
runCode(box.Text, tabs[active].name)
tween(btnExec, {BackgroundColor3 = T.gold}, .1)
task.delay(.15, function() tween(btnExec, {BackgroundColor3 = T.bronze}, .4) end)
end, true, 1)
tbtn("AutoExec", "refresh", function()
local code = box.Text
if code:gsub("%s", "") == "" then
toast("Editor is empty")
return
end
local name = tabs[active].name
local native = Store.addAuto(name, code)
if native == nil then
toast("Could not save AutoExec")
addLine("Console", "[autoexec] could not write files (writefile unavailable?)", T.bronzeHi)
else
toast("AutoExec saved")
addLine("Console", "[autoexec] '" .. name .. "' saved locally; it will run each time Hyundax IUM loads.", T.gold)
end
end, false, 1)
tbtn("Paste", "paste", function()
local value = readClipboard()
if value then
box:CaptureFocus()
local cursor = math.max(box.CursorPosition, 1)
local before = box.Text:sub(1, cursor - 1)
local after = box.Text:sub(cursor)
box.Text = before .. value .. after
box.CursorPosition = cursor + #value
toast("Pasted into editor")
else
toast("Clipboard read unavailable")
end
end, false, 1)
tbtn("Exec Clipboard", "bolt", function()
local value = readClipboard()
if not value or value:gsub("%s", "") == "" then
toast("Clipboard is empty or unavailable")
return
end
runCode(value, "clipboard")
end, false, 1)
tbtn("Clear", "trash", function()
if S.cfg and S.cfg.editorClearConfirm and box.Text ~= "" then S.confirm("Clear all code in the editor?", function() box.Text = "" end) else box.Text = "" end
end, false, 1)
tbtn("Open", "folder", openDialog, false, 1)
tbtn("Save", "save", function()
local ok = pcall(function()
local out = box.Text
if S.cfg and S.cfg.trimSpaces then
out = out:gsub("[ \t]+\n", "\n")
out = out:gsub("[ \t]+$", "")
end
writefile(FOLDER .. "/" .. safeName(tabs[active].name) .. ".lua", out)
end)
toast(ok and "Saved to workspace/" .. FOLDER or "Could not save")
end, false, 1)
tbtn("Copy", "copy", function()
local ok = pcall(function() setclipboard(box.Text) end)
toast(ok and "Copied" or "setclipboard unavailable")
end, false, 1)
local expOpen = true
expToggle.Activated:Connect(function()
expOpen = not expOpen
tween(expl, {Size = UDim2.new(0, expOpen and EXP_W or 0, 1, 0)}, .4)
tween(em, {Position = UDim2.fromOffset(expOpen and EXP_W or 0, 0), Size = UDim2.new(1, expOpen and -EXP_W or 0, 1, 0)}, .4)
end)
;(function()
local PER_PAGE, PAGER_H = 9, 28
local hub = group(pages, {ClipsDescendants = true})
pageMap.Scripts = hub
local HUB_SIDE_W = 116
local hubSide = new("Frame", {Size = UDim2.new(0, HUB_SIDE_W, 1, 0), BackgroundColor3 = T.side, BorderSizePixel = 0, Parent = hub})
FX.sideSkin(hubSide)
new("Frame", {Position = UDim2.new(1, -1, 0, 0), Size = UDim2.new(0, 1, 1, 0), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = hubSide})
local hubContent = new("Frame", {Position = UDim2.fromOffset(HUB_SIDE_W, 0), Size = UDim2.new(1, -HUB_SIDE_W, 1, 0), BackgroundTransparency = 1, ClipsDescendants = true, Parent = hub})
text(hubSide, "Script Hub", 14, "Bold", T.text, {Position = UDim2.fromOffset(10, 9), Size = UDim2.new(1, -20, 0, 20)})
local hubState = {mode = "latest", query = "", page = 1, total = 1, token = 0, loaded = false, trending = nil}
local cards, badges, imageCache = {}, {}, {}
local chips, setMode, hubLoad = {}, nil, nil
local hubTitle, chipFrame, styleChips, paintHubNav
local function fmt(n)
n = tonumber(n) or 0
if n >= 1e6 then return ("%.1fM"):format(n / 1e6) end
if n >= 1e3 then return ("%.1fK"):format(n / 1e3) end
return tostring(math.floor(n))
end
local function parse(s)
local g = type(s.game) == "table" and s.game or {}
local function imageUrl(value, base)
if type(value) ~= "string" or value == "" then return nil end
if value:sub(1, 2) == "//" then return "https:" .. value end
if value:sub(1, 1) == "/" then return (base or "https://scriptblox.com") .. value end
return value
end
local gameImg = imageUrl(g.imageUrl or g.thumbnailUrl or g.iconUrl or g.image, "https://scriptblox.com")
local img = imageUrl(s.image or s.imageUrl or s.thumbnailUrl or s.bannerUrl, "https://scriptblox.com") or gameImg
local slug = tostring(s.slug or s._id or s.id or "")
local scriptData = s.script
if type(scriptData) == "table" then scriptData = scriptData.script or scriptData.source or scriptData.code end
return {
src = "scriptblox", slug = slug, rid = tostring(s._id or s.id or slug), title = s.title or "Untitled", game = g.name or g.title or "Universal Script",
gameId = g.placeId or g.gameId or g.universeId, image = img, gameImage = gameImg, views = tonumber(s.views) or 0, likes = tonumber(s.likeCount or s.likes) or 0,
saves = tonumber(s.saveCount or s.saves or s.bookmarkCount or s.favoriteCount) or 0,
verified = s.verified and true or false, key = (s.key or s.keySystem or s.isKeySystem) and true or false, free = (s.scriptType ~= "paid" and not s.isPaid),
universal = s.isUniversal and true or false, patched = s.isPatched and true or false,
created = type(s.createdAt) == "string" and s.createdAt:sub(1, 10) or nil,
code = type(scriptData) == "string" and scriptData or nil,
raw = slug ~= "" and ("https://scriptblox.com/raw/" .. slug) or nil,
url = slug ~= "" and ("https://scriptblox.com/script/" .. slug) or nil,
}
end
local function toggleLike(s)
if Store.likes[s.slug] then
Store.likes[s.slug] = nil
toast("Like removed")
else
Store.likes[s.slug] = {
slug = s.slug, title = s.title, game = s.game, image = s.image, views = s.views, likes = s.likes, saves = s.saves,
src = s.src, rid = s.rid, raw = s.raw, url = s.url, loadstr = s.loadstr,
key = s.key, verified = s.verified, free = s.free, universal = s.universal, patched = s.patched, created = s.created,
}
toast("Liked")
end
Store.saveLikes()
if hubState.mode == "favorites" then hubLoad(hubState.page) end
end
local function toggleSave(s, done)
if Store.cloudIndex(s.slug) then
Store.removeCloud(s.slug)
toast("Removed from Cloud Scripts")
if done then done() end
if hubState.mode == "saved" then hubLoad(hubState.page) end
else
task.spawn(function()
Store.ensureCode(s)
table.insert(Store.cloud, 1, s)
Store.saveCloud()
Store.refresh()
toast("Saved to Cloud Scripts")
if done then done() end
end)
end
end
local function copy(txt, msg)
local ok = pcall(function() setclipboard(txt) end)
toast(ok and msg or "setclipboard unavailable")
end
local function imgOk(d)
if type(d) ~= "string" or #d < 16 then return false end
local h = d:sub(1, 4)
return h == "\137PNG" or h:sub(1, 3) == "\255\216\255" or h == "GIF8" or (h == "RIFF" and d:sub(9, 12) == "WEBP")
end
local function httpData(url)
local headers = {
["User-Agent"] = "Mozilla/5.0", ["Accept"] = "image/png,image/jpeg,image/webp,image/gif,*/*;q=0.8",
["Referer"] = "https://" .. (url:match("^https?://([^/]+)") or ""),
}
local d = httpGet(url, headers)
if imgOk(d) then return d end
end
local function jget(url)
local ok, r = pcall(function() return HttpService:JSONDecode(game:HttpGet(url)) end)
if ok and type(r) == "table" then return r end
end
local function robloxThumb(s)
local function ico(place, id)
local r = jget(("https://thumbnails.roblox.com/v1/%s?%s=%s&returnPolicy=PlaceHolder&size=256x256&format=Png&isCircular=false"):format(place and "places/gameicons" or "games/icons", place and "placeIds" or "universeIds", tostring(id)))
local u = r and r.data and r.data[1] and r.data[1].imageUrl
return type(u) == "string" and httpData(u) or nil
end
if tonumber(s.gameId) then
local d = ico(true, s.gameId) or ico(false, s.gameId)
if d then return d end
end
local n = s.game
if type(n) == "string" and n ~= "" and n ~= "Universal Script" then
local r = jget("https://apis.roblox.com/search-api/omni-search?searchQuery=" .. HttpService:UrlEncode(n) .. "&sessionId=" .. HttpService:GenerateGUID(false) .. "&pageType=all")
local g = r and r.searchResults and r.searchResults[1] and r.searchResults[1].contents and r.searchResults[1].contents[1]
if g and g.universeId then return ico(false, g.universeId) end
end
end
local function bannerKey(s)
local slug = tostring(s.slug or s.rid or s.title or "asset"):sub(1, 64)
local raw = tostring(s.src or "local") .. "|" .. slug .. "|" .. tostring(s.image or "auto")
local h = 17
for i = 1, #raw do h = (h * 31 + raw:byte(i)) % 2147483647 end
return safeName(tostring(s.src or "local") .. "_" .. slug) .. "_" .. tostring(h)
end
local function runBanner(s, img, ph)
do
local key = bannerKey(s)
local asset = imageCache[key]
if not asset then
local path = PATH.img .. "/" .. key .. ".dat"
pcall(function() if isfile(path) and not imgOk(readfile(path)) then delfile(path) end end)
asset = toAsset(path, function()
local d
local u = s.image
if type(u) == "string" and u ~= "" then
local inner = u:match("[?&]url=([^&]+)")
if inner then
inner = inner:gsub("%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)
if inner:sub(1, 1) == "/" then inner = (u:match("^(https?://[^/]+)") or "") .. inner end
d = httpData(inner)
end
d = d or httpData(u)
end
d = d or robloxThumb(s)
if not d then error("no image") end
return d
end)
if asset then imageCache[key] = asset end
end
if asset and img.Parent then
img.Image = asset
tween(img, {ImageTransparency = 0}, .35)
if ph and ph.Parent then tween(ph, {TextTransparency = 1}, .3) end
end
end
end
local BQ = {q = {}, active = 0, MAX = 2, grads = {}, conn = nil}
local function bqShimmer()
if BQ.conn then return end
BQ.conn = game:GetService("RunService").Heartbeat:Connect(function()
local n = 0
local off = ((os.clock() * .9) % 2) - 1
for g in pairs(BQ.grads) do
if g.Parent then g.Offset = Vector2.new(off, 0); n += 1 else BQ.grads[g] = nil end
end
if n == 0 and BQ.conn then BQ.conn:Disconnect(); BQ.conn = nil end
end)
end
local function bqSkeleton(banner)
if not (banner and banner:IsA("GuiObject")) then return nil end
local c0 = T.panel2
local c1 = c0:Lerp(Color3.new(1, 1, 1), .10)
local sk = new("Frame", {Name = "BannerSkeleton", Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, ZIndex = 0, Parent = banner})
sk:SetAttribute("NoTheme", true)
local g = new("UIGradient", {Color = ColorSequence.new({ColorSequenceKeypoint.new(0, c0), ColorSequenceKeypoint.new(.5, c1), ColorSequenceKeypoint.new(1, c0)}), Parent = sk})
BQ.grads[g] = true
bqShimmer()
return sk
end
local function bqPump()
while BQ.active < BQ.MAX and #BQ.q > 0 do
local job = table.remove(BQ.q, 1)
if job.img.Parent then
BQ.active += 1
task.spawn(function()
pcall(runBanner, job.s, job.img, job.ph)
if job.sk then job.sk:Destroy() end
task.wait(.08)
BQ.active -= 1
bqPump()
end)
elseif job.sk then
job.sk:Destroy()
end
end
end
local function loadBanner(s, img, ph, prio)
if not img or not img.Parent then return end
local banner = img.Parent
if banner:IsA("GuiObject") then banner.ClipsDescendants = true end
if imageCache[bannerKey(s)] then
task.spawn(runBanner, s, img, ph)
return
end
local job = {s = s, img = img, ph = ph, sk = bqSkeleton(banner)}
if prio then table.insert(BQ.q, 1, job) else BQ.q[#BQ.q + 1] = job end
bqPump()
end
local CARD_W, CARD_H, PS = 184, 148, 12
local SRCS = {"scriptblox", "rscripts", "haxhell", "robloxscripts"}
local SRCNAME = {scriptblox = "ScriptBlox", rscripts = "Rscripts", haxhell = "HaxHell", robloxscripts = "Roblox Scripts"}
local FL = {sources = {scriptblox = true, rscripts = true, haxhell = true, robloxscripts = true}, game = "", show = "All", sort = "Relevance", order = "Descending"}
local SRC = {}
local NOREACH = "Could not reach ScriptBlox.\nCheck your connection / HttpGet support."
local SI = {
site = {scriptblox = "scriptblox.com", rscripts = "rscripts.net", haxhell = "haxhell.com", robloxscripts = "robloxscripts.com"},
fallback = {scriptblox = "cube", rscripts = "filecode", haxhell = "flame", robloxscripts = "globe"},
assets = {}, waiting = {},
}
function SI.urls(k)
local d = SI.site[k]
if not d then return {} end
return {
("https://www.google.com/s2/favicons?domain=%s&sz=128"):format(d),
("https://www.google.com/s2/favicons?domain_url=https://%s&sz=64"):format(d),
("https://%s/apple-touch-icon.png"):format(d),
("https://%s/favicon-32x32.png"):format(d),
("https://%s/favicon.png"):format(d),
("https://%s/logo.png"):format(d),
}
end
function SI.load(k, cb)
local got = SI.assets[k]
if got then cb(got) return end
if got == false or not SI.site[k] then return end
local q = SI.waiting[k]
if q then q[#q + 1] = cb return end
SI.waiting[k] = {cb}
task.spawn(function()
local path = PATH.img .. "/srcicon_" .. safeName(k) .. ".dat"
pcall(function() if isfile(path) and not imgOk(readfile(path)) then delfile(path) end end)
local asset = toAsset(path, function()
for _, u in ipairs(SI.urls(k)) do
local ok, d = pcall(httpData, u)
if ok and d then return d end
end
error("no source icon")
end)
SI.assets[k] = asset or false
local list = SI.waiting[k] or {}
SI.waiting[k] = nil
if asset then
for _, f in ipairs(list) do pcall(f, asset) end
end
end)
end
function SI.badge(parent, k, size, props)
local st = stroke(T.bronzeLo, 1)
st.Transparency = .55
local f = new("Frame", {
Size = UDim2.fromOffset(size, size), BackgroundColor3 = T.glow, BorderSizePixel = 0, Parent = parent,
}, {round(math.floor(size * .3)), st})
for pk, pv in pairs(props or {}) do f[pk] = pv end
local fb = icon(f, SI.fallback[k] or "globe", math.max(math.floor(size * .6), 8), T.tan, 1.5)
fb.holder.AnchorPoint, fb.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
local img = new("ImageLabel", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromScale(.74, .74),
BackgroundTransparency = 1, ScaleType = Enum.ScaleType.Fit, ImageTransparency = 1, ZIndex = 3, Parent = f,
}, {round(math.max(math.floor(size * .16), 2))})
img:SetAttribute("NoTheme", true)
local on, loaded = true, false
local function paint()
if loaded then tween(img, {ImageTransparency = on and 0 or .55}, .15) end
fb.set(on and T.tan or T.muted, .15)
end
SI.load(k, function(asset)
if not img.Parent then return end
img.Image = asset
loaded = true
fb.holder.Visible = false
tween(img, {ImageTransparency = on and 0 or .55}, .3)
end)
return {frame = f, set = function(v) on = v and true or false paint() end}
end
local function getJSON(url, headers)
return decodeJSON(url, headers)
end
local function absU(u, base)
if type(u) ~= "string" or u == "" then return nil end
if u:sub(1, 2) == "//" then return "https:" .. u end
if u:sub(1, 1) == "/" then return base .. u end
return u
end
local function lstr(url) return ('loadstring(game:HttpGet("%s"))()'):format(url) end
local function unent(h)
h = tostring(h or ""):gsub("
", "\n"):gsub("
", "\n"):gsub("<[^>]+>", "")
h = h:gsub(""", '"'):gsub("?38;", "&"):gsub("<", "<"):gsub(">", ">"):gsub("‘", "'"):gsub("’", "'"):gsub("“", '"'):gsub("”", '"'):gsub("–", "-"):gsub("'", "'"):gsub("'", "'"):gsub("&", "&")
return h
end
local function listOf(r, d)
if type(r) ~= "table" then return end
if r[1] ~= nil then return r end
if (d or 0) > 2 then return end
for _, k in ipairs({"scripts", "data", "results", "items", "posts", "result"}) do
local l = listOf(r[k], (d or 0) + 1)
if l then return l end
end
end
SRC.scriptblox = {fetch = function(o)
local res
if o.kind == "trending" then
if o.page > 1 then return nil end
res = Store.apiGet("trending?max=20")
else
local sb2
if o.q ~= "" then
sb2 = ({Relevance = "accuracy", Views = "views", Likes = "likeCount", Newest = "createdAt"})[FL.sort] or "accuracy"
else
sb2 = ({Relevance = "createdAt", Views = "views", Likes = "likeCount", Newest = "createdAt"})[FL.sort] or "createdAt"
end
local extra = "&sortBy=" .. sb2 .. "&order=" .. (FL.order == "Ascending" and "asc" or "desc")
if o.q ~= "" then extra = extra .. "&strict=false" end
if o.place then
res = Store.apiGet(("fetch?max=%d&page=%d&placeId=%d"):format(PS, o.page, game.PlaceId))
elseif o.q ~= "" then
res = Store.apiGet(("search?q=%s&max=%d&page=%d%s"):format(HttpService:UrlEncode(o.q), PS, o.page, extra))
else
res = Store.apiGet(("fetch?max=%d&page=%d%s"):format(PS, o.page, extra))
end
end
local sc = res and res.result and res.result.scripts
if type(sc) ~= "table" then return nil end
local out = {}
for _, x in ipairs(sc) do out[#out + 1] = parse(x) end
return out, (tonumber(res.result.totalPages) or o.page) > o.page
end}
local RSCRIPT_API_KEY = "rsc_live_tt_-JT3qZOCcfl70FHbNB_YZ9cek0U8o"
local function getRscriptsApiKey()
local apiKey = RSCRIPT_API_KEY
pcall(function()
if type(getgenv) == "function" then
local configured = getgenv().HYUNDAXIUM_RSCRIPT_API_KEY
if type(configured) == "string" and configured ~= "" then apiKey = configured end
end
end)
return apiKey
end
local function rsParse(x)
if type(x.script) == "table" then x = x.script end
local base = "https://rscripts.net"
local g = type(x.game) == "table" and x.game or {}
local u = type(x.user) == "table" and x.user or type(x.creator) == "table" and x.creator or {}
local stats = type(x.stats) == "table" and x.stats or {}
local slug = tostring(x.slug or x._id or x.id or "")
local id = tostring(x._id or x.id or slug)
local inline = type(x.script) == "string" and x.script or nil
local rawValue = x.rawUrl or x.raw
if not rawValue and type(x.rawScript) == "string" then
if x.rawScript:match("^https?://") or x.rawScript:sub(1, 1) == "/" or x.rawScript:sub(1, 2) == "//" then
rawValue = x.rawScript
else
inline = inline or x.rawScript
end
end
local raw = absU(rawValue, base)
if not raw and slug ~= "" then raw = base .. "/raw/" .. slug end
local gameName = g.title or g.name or "Universal Script"
local gameImg = absU(g.thumbnailUrl or g.logoUrl or g.iconUrl or g.imgurl or g.imgUrl or g.image, base)
local image = absU(x.imageUrl or x.image or x.bannerUrl, base) or gameImg
local code = isSourceCode(inline) and inline or nil
return {
src = "rscripts", rid = id, sourceSlug = slug, slug = "rscripts-" .. id, title = x.title or "Untitled", game = gameName,
gameId = g.placeId or g.gameId or g.universeId, image = image, gameImage = gameImg,
views = tonumber(x.views or stats.views) or 0, likes = tonumber(x.likes or stats.likes) or 0, saves = tonumber(x.saves or stats.favorites or stats.bookmarks) or 0,
verified = (u.verified or u.isVerified) and true or false, key = (x.keySystem or x.isKeySystem or x.key) and true or false,
free = not (x.paid or x.isPaid), universal = gameName == "Universal Script" or x.isUniversal == true, patched = (x.isPatched or x.patched) and true or false,
created = type(x.createdAt or x.lastUpdatedAt) == "string" and (x.createdAt or x.lastUpdatedAt):sub(1, 10) or nil,
code = code, raw = raw, url = x.url or x.webpage or (slug ~= "" and (base .. "/script/" .. slug) or nil),
}
end
SRC.rscripts = {fetch = function(o)
local q = o.q ~= "" and ("&q=" .. HttpService:UrlEncode(o.q)) or ""
local sortMap = {Views = "most-views", Likes = "most-likes", Newest = "newest", Relevance = "recommended"}
local listSort = FL.sort == "Relevance" and "newest" or (sortMap[FL.sort] or "newest")
local sortName = o.kind == "trending" and "trending" or (o.q == "" and o.kind == "latest" and listSort or (sortMap[FL.sort] or "recommended"))
local legacySort = o.kind == "trending" and "views" or (o.q == "" and o.kind == "latest" and ((FL.sort == "Relevance") and "date" or ({Views = "views", Likes = "likes", Newest = "date"})[FL.sort]) or ({Views = "views", Likes = "likes", Newest = "date"})[FL.sort])
local legacyOrder = (o.kind ~= "trending" and FL.order == "Ascending") and "asc" or "desc"
local r = getJSON(("https://rscripts.net/api/v2/scripts?page=%d%s%s"):format(o.page, q, legacySort and ("&orderBy=" .. legacySort .. "&sort=" .. legacyOrder) or ""))
local l = listOf(r)
if not l then
local apiKey = getRscriptsApiKey()
if apiKey ~= "" then
local url = ("https://api.rscripts.net/v1/scripts?page=%d&limit=%d&sort=%s%s"):format(o.page, PS, sortName, q)
local headers = { ["Accept"] = "application/json", ["Authorization"] = "Bearer " .. apiKey, ["X-Api-Key"] = apiKey }
r = decodeJSON(url, headers)
l = listOf(r)
end
end
if not l then
local apiKey = getRscriptsApiKey()
if apiKey == "" then return nil, "Rscripts needs an API key if its legacy endpoint is unavailable." end
return nil, "Rscripts did not return usable JSON."
end
local out = {}
for _, x in ipairs(l) do if type(x) == "table" then out[#out + 1] = rsParse(x) end end
local meta = type(r.meta) == "table" and r.meta or type(r.info) == "table" and r.info or {}
local more = meta.hasNextPage
if more == nil then more = (tonumber(meta.totalPages or meta.maxPages) or (o.page + (#l > 0 and 1 or 0))) > o.page end
return out, more
end, detail = function(x)
local apiKey = getRscriptsApiKey()
if apiKey == "" then return nil end
local slug = tostring(x.sourceSlug or x.rid or x.slug or "")
slug = slug:gsub("^rscripts%-", "")
if slug == "" then return nil end
local headers = { ["Accept"] = "application/json", ["Authorization"] = "Bearer " .. apiKey, ["X-Api-Key"] = apiKey }
local r = decodeJSON("https://api.rscripts.net/v1/scripts/" .. HttpService:UrlEncode(slug), headers)
local d = r and (r.data or r.script or r)
if type(d) == "table" and isSourceCode(d.script) then return d.script end
end}
local function genParse(src, base, x)
local g = type(x.game) == "table" and x.game or {}
local stats = type(x.stats) == "table" and x.stats or {}
local flags = type(x.flags) == "table" and x.flags or {}
local media = type(x.media) == "table" and x.media or {}
local links = type(x.links) == "table" and x.links or {}
local author = type(x.author) == "table" and x.author or {}
local slug = tostring(x.slug or x._id or x.id or x.uuid or x.title or "")
local id = tostring(x._id or x.id or x.uuid or slug)
local source = type(x.source) == "table" and x.source or {}
local code = x.script or x.code or x.content or x.sourceCode or source.code
if type(code) ~= "string" or #code < 8 then code = nil end
local raw = absU(links.raw or source.rawUrl or x.rawUrl or x.raw or x.rawScript or x.raw_url, base)
local gameName = (type(x.game) == "string" and x.game) or g.name or g.title or g.gameName or x.gameName or "Universal Script"
local gameImg = absU(g.thumbnailUrl or g.iconUrl or g.imageUrl or g.image, base)
local image = absU(x.imageUrl or x.image or x.thumbnail or x.banner or media.thumbnailUrl or media.bannerUrl or media.coverUrl, base) or gameImg
return {
src = src, rid = id, sourceSlug = slug, slug = src .. "-" .. id, title = tostring(x.title or x.name or "Untitled"), game = gameName,
gameId = g.placeId or g.gameId or g.universeId or x.gameId,
image = image, gameImage = gameImg,
views = tonumber(x.views or x.viewCount or stats.views) or 0, likes = tonumber(x.likes or x.likeCount or stats.likes) or 0,
saves = tonumber(stats.favorites or x.saves) or 0, verified = (x.verified or flags.verified or author.isScripterVerified) and true or false,
key = (x.key or x.keySystem or x.hasKey or flags.keySystem) and true or false,
free = not (x.paid or flags.isPaid), universal = x.isUniversal == true or g.name == "Universal Script" or gameName == "Universal Script",
patched = x.isPatched == true or flags.patched == true,
created = type(x.createdAt) == "string" and x.createdAt:sub(1, 10) or nil,
code = code, raw = raw, url = links.webpage or x.url or (slug ~= "" and (base .. "/scripts/" .. slug) or nil),
}
end
SRC.haxhell = {fetch = function(o)
local q = o.q ~= "" and ("&q=" .. HttpService:UrlEncode(o.q)) or ""
local sort = o.kind == "trending" and "views" or (FL.sort == "Newest" and "latest" or FL.sort == "Views" and "views" or "latest")
local r = getJSON(("https://haxhell.com/api/v1/scripts?page=%d&limit=%d&sort=%s%s"):format(o.page, PS, sort, q))
local l = listOf(r)
if not l then
r = getJSON(("https://haxhell.com/api/scripts?page=%d&limit=%d%s%s"):format(o.page, PS, q, o.kind == "trending" and "&sort=views&order=desc" or ""))
l = listOf(r)
end
if not l then return nil end
local out = {}
for _, x in ipairs(l) do if type(x) == "table" then out[#out + 1] = genParse("haxhell", "https://haxhell.com", x) end end
local pg = type(r.pagination) == "table" and r.pagination or {}
local more = pg.hasMore
if more == nil then more = #l >= PS end
return out, more
end, detail = function(x)
local slug = tostring(x.sourceSlug or x.rid or "")
local r = getJSON("https://haxhell.com/api/v1/scripts/" .. HttpService:UrlEncode(slug))
local d = r and (r.script or r.data or r)
if type(d) == "table" then
local srcData = type(d.source) == "table" and d.source or {}
local c = d.script or d.code or d.content or d.sourceCode or srcData.code
if type(c) == "string" and isSourceCode(c) then return c end
end
end}
SRC.robloxscripts = {fetch = function(o)
local base = "https://robloxscripts.com"
local url = ("%s/wp-json/wp/v2/posts?_embed=1&per_page=%d&page=%d&order=%s"):format(base, PS, o.page, FL.order == "Ascending" and "asc" or "desc")
if o.q ~= "" then url = url .. "&search=" .. HttpService:UrlEncode(o.q) end
local r = getJSON(url)
if not (r and r[1]) then return nil end
local out = {}
for _, p in ipairs(r) do
local emb = type(p._embedded) == "table" and p._embedded or {}
local fm = type(emb["wp:featuredmedia"]) == "table" and emb["wp:featuredmedia"][1] or {}
local tm = type(emb["wp:term"]) == "table" and type(emb["wp:term"][1]) == "table" and emb["wp:term"][1][1] or nil
local html = type(p.content) == "table" and tostring(p.content.rendered or "") or ""
local pre = html:match("]*>(.-)
")
local code = pre and unent(pre) or unent(html):match("loadstring%b()%(%)")
local id = tostring(p.id)
local gname = tm and tm.name and unent(tm.name) or "Universal Script"
if gname == "Uncategorized" then gname = "Universal Script" end
out[#out + 1] = {
src = "robloxscripts", rid = id, slug = "robloxscripts-" .. id, title = unent(type(p.title) == "table" and p.title.rendered or "Untitled"), game = gname,
image = type(fm) == "table" and absU(fm.source_url, base) or nil, views = 0, likes = 0, saves = 0, verified = false, key = false, free = true,
universal = gname == "Universal Script", patched = false, created = type(p.date) == "string" and p.date:sub(1, 10) or nil,
code = (code and #code > 8) and code or nil, url = type(p.link) == "string" and p.link or nil,
}
end
return out, #r >= PS
end}
function Store.codeOf(x)
if type(x.raw) == "string" and x.raw ~= "" then
local r = httpGet(x.raw, { ["Accept"] = "text/plain, */*" })
if isSourceCode(r) then return r end
end
local sr = SRC[x.src]
if sr and sr.detail then
local ok, c = pcall(sr.detail, x)
if ok and isSourceCode(c) then return c end
end
return nil
end
local function mineOf(list, names)
local out = {}
for _, x in ipairs(list) do
local gn, tt = tostring(x.game or ""):lower(), tostring(x.title or ""):lower()
local ok = x.gameId ~= nil and tostring(x.gameId) == tostring(game.PlaceId)
if not ok then
for _, n in ipairs(names) do
local ln = n:lower()
if (gn ~= "" and gn ~= "ugc" and (gn == ln or gn:find(ln, 1, true) or ln:find(gn, 1, true))) or (x.src ~= "scriptblox" and tt:find(ln, 1, true)) then ok = true break end
end
end
if ok then out[#out + 1] = x end
end
return out
end
local function gather(o)
local act = {}
for _, k in ipairs(SRCS) do if o.all or FL.sources[k] then act[#act + 1] = k end end
if #act == 0 then return nil, "Select at least one source\nin Filters." end
local jobs, names = {}, nil
if o.kind == "game" then
names = Store.gameNames()
if #names == 0 then names = {Store.realGameName()} end
for _, k in ipairs(act) do
for _, n in ipairs(names) do jobs[#jobs + 1] = {k, {kind = "latest", q = n, page = o.page}} end
if k == "scriptblox" then jobs[#jobs + 1] = {k, {kind = "latest", q = "", page = o.page, place = true}} end
end
else
for _, k in ipairs(act) do jobs[#jobs + 1] = {k, o} end
end
local res, errs, more, pending = {}, {}, false, #jobs
for i, j in ipairs(jobs) do
task.spawn(function()
local ok, l, m = pcall(SRC[j[1]].fetch, j[2])
if ok and type(l) == "table" then
res[i] = names and mineOf(l, names) or l
if m then more = true end
else
errs[j[1]] = not ok and tostring(l) or tostring(m or "No response")
end
pending -= 1
end)
end
local t0 = os.clock()
while pending > 0 and os.clock() - t0 < 24 do task.wait(.05) end
local timedOut = pending > 0
local out, seen, maxn, any = {}, {}, 0, false
for i = 1, #jobs do if res[i] then any = true maxn = math.max(maxn, #res[i]) end end
if not any then
local failed = {}
for _, k in ipairs(act) do
local name = SRCNAME[k] or k
if errs[k] and k == "rscripts" and tostring(errs[k]):find("API key", 1, true) then
failed[#failed + 1] = name .. " (API key required)"
else
failed[#failed + 1] = name
end
end
return nil, "Could not load selected sources: " .. table.concat(failed, ", ") .. ". Check connection / API availability."
end
for n = 1, maxn do
for i = 1, #jobs do
local x = res[i] and res[i][n]
if x and not seen[x.slug] then seen[x.slug] = true out[#out + 1] = x end
end
end
if FL.sort ~= "Relevance" then
local key = FL.sort == "Views" and "views" or FL.sort == "Likes" and "likes" or "created"
local asc, d = FL.order == "Ascending", key == "created" and "" or 0
table.sort(out, function(a, b)
local u, v = a[key] or d, b[key] or d
if u == v then return tostring(a.title or "") < tostring(b.title or "") end
if asc then return u < v end
return u > v
end)
elseif type(o.q) == "string" and o.q:gsub("%s", "") ~= "" then
local query = o.q:lower():gsub("^%s+", ""):gsub("%s+$", "")
local terms = {}
for term in query:gmatch("[%w_%-]+") do if #term > 1 then terms[#terms + 1] = term end end
local function relevance(x)
local title, gameName = tostring(x.title or ""):lower(), tostring(x.game or ""):lower()
local score = 0
if title == query then score += 120 end
if title:find(query, 1, true) then score += 70 end
if gameName == query then score += 90 end
if gameName:find(query, 1, true) then score += 45 end
for _, term in ipairs(terms) do
if title:find(term, 1, true) then score += 24 end
if gameName:find(term, 1, true) then score += 18 end
end
return score
end
table.sort(out, function(a, b)
local sa, sbv = relevance(a), relevance(b)
if sa ~= sbv then return sa > sbv end
return tostring(a.created or "") > tostring(b.created or "")
end)
end
return out, more or timedOut
end
local sbWrap = new("Frame", {AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -44, 0, 6), Size = UDim2.new(1, -190, 0, 26), BackgroundTransparency = 1, Parent = hubContent})
local sb = new("TextBox", {
Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.panel, Text = "",
PlaceholderText = "Search scripts...", PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 10, FontFace = F.SemiBold,
ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, Parent = sbWrap,
}, {round(8), pad(26, 0, 7, 0)})
local sbSt = stroke(T.line, 1)
sbSt.Parent = sb
local sbIc = icon(sbWrap, "search", 12, T.muted, 1.4)
sbIc.holder.Position = UDim2.fromOffset(9, 7)
sb.Focused:Connect(function() tween(sbSt, {Color = T.bronze}, .2) sbIc.set(T.bronze, .2) end)
sb.FocusLost:Connect(function(enter)
tween(sbSt, {Color = T.line}, .2)
sbIc.set(T.muted, .2)
if not enter then return end
if sb.Text:gsub("%s", "") == "" then
setMode("latest")
else
hubState.mode, hubState.query, hubState.total = "search", sb.Text, 1
hubTitle.Text = "Search results"
styleChips()
paintHubNav()
hubLoad(1)
end
end)
hubTitle = text(hubContent, "Browse scripts", 14, "Bold", T.text, {Position = UDim2.fromOffset(8, 8), Size = UDim2.fromOffset(118, 20), TextTruncate = Enum.TextTruncate.AtEnd})
chipFrame = new("Frame", {Visible = false, Size = UDim2.new(), BackgroundTransparency = 1, Parent = hubContent})
styleChips = function() end
local gearB = new("TextButton", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -8, 0, 6), Size = UDim2.fromOffset(28, 26), BackgroundColor3 = T.panel,
AutoButtonColor = false, Text = "", Glass = true, Parent = hubContent,
}, {round(7), stroke(T.line)})
local gearIc = icon(gearB, "filter", 14, T.text, 1.5)
gearIc.holder.AnchorPoint, gearIc.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
hoverFx(gearB, T.panel, T.panel2)
pressFx(gearB, .9)
local feed = scroller(hubContent, {
Position = UDim2.fromOffset(0, 40), Size = UDim2.new(1, 0, 1, -40), AutomaticCanvasSize = Enum.AutomaticSize.Y,
ScrollingDirection = Enum.ScrollingDirection.Y,
}, {vlist(8), pad(8, 2, 8, 10)})
local statusLbl = text(hubContent, "", 12, "Bold", T.muted, {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.new(.5, 0, .5, -4), Size = UDim2.new(1, -40, 0, 44),
TextXAlignment = Enum.TextXAlignment.Center, TextWrapped = true,
})
local function setStatus(msg)
statusLbl.Text = msg or ""
statusLbl.Visible = (msg ~= nil and msg ~= "")
end
local function openFilters()
local p = FX.popup({
name = "HXPopupFilters", parent = hub, z = 20, w = 460, h = 720, margin = 8,
title = "Script Filters", subtitle = "Refine how the hub is browsed", icon = "filter",
onClose = function() if FL.dirty then FL.dirty = false hubLoad(1) end end,
buttons = {
{label = "Reset", first = true, cb = function()
FL.sources = {scriptblox = true, rscripts = true, haxhell = true, robloxscripts = true}
FL.game, FL.show, FL.sort, FL.order, FL.dirty = "", "All", "Relevance", "Descending", true
end},
{label = "Apply", kind = "primary"},
},
})
local body = scroller(p.body, {ScrollBarThickness = 2}, {vlist(8), pad(12, 10, 12, 10)})
local function card(order, title, ico)
local c = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = .5, LayoutOrder = order, Parent = body}, {round(10), stroke(T.line, 1), vlist(6), pad(10, 8, 10, 10)})
if ico then
local head = new("Frame", {Size = UDim2.new(1, 0, 0, 14), BackgroundTransparency = 1, LayoutOrder = 0, Parent = c}, {hlist(5)})
local hi = icon(head, ico, 12, T.tan, 1.5)
hi.holder.LayoutOrder = 1
text(head, title, 10, "Bold", T.tan, {LayoutOrder = 2, AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14)})
else
text(c, title, 10, "Bold", T.tan, {LayoutOrder = 0, Size = UDim2.new(1, 0, 0, 14)})
end
return c
end
local c1 = card(1, "SOURCES (pick one or more)", "layers")
local sg = new("Frame", {Size = UDim2.new(1, 0, 0, 62), BackgroundTransparency = 1, LayoutOrder = 1, Parent = c1}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -3, 0, 28), CellPadding = UDim2.fromOffset(6, 6), SortOrder = Enum.SortOrder.LayoutOrder}),
})
for i, k in ipairs(SRCS) do
local b = new("TextButton", {Text = SRCNAME[k], TextSize = 10, FontFace = F.Bold, TextColor3 = T.text, BackgroundColor3 = T.panel2, AutoButtonColor = false, LayoutOrder = i, Parent = sg, NoI18N = true}, {round(8), pad(26, 0, 16, 0)})
local st = stroke(T.line, 1)
st.Parent = b
local logo = SI.badge(b, k, 18, {AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, -22, .5, 0)})
local ck = icon(b, "check", 11, T.gold, 1.8)
ck.holder.AnchorPoint, ck.holder.Position = Vector2.new(1, .5), UDim2.new(1, 13, .5, 0)
local function paint()
local on = FL.sources[k]
ck.holder.Visible = on and true or false
logo.set(on)
tween(b, {BackgroundColor3 = on and T.bronze or T.panel2}, .15)
tween(st, {Color = on and T.bronzeHi or T.line}, .15)
end
paint()
pressFx(b, .94)
b.Activated:Connect(function() FL.sources[k] = not FL.sources[k] FL.dirty = true paint() end)
end
local c2 = card(2, "GAME", "cube")
local gw = new("Frame", {Size = UDim2.new(1, 0, 0, 28), BackgroundTransparency = 1, LayoutOrder = 1, Parent = c2})
local gb = new("TextBox", {
Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.panel2, Text = FL.game, PlaceholderText = "Search a Roblox game...", PlaceholderColor3 = T.muted,
TextColor3 = T.text, TextSize = 10, FontFace = F.SemiBold, ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, Parent = gw,
}, {round(8), pad(26, 0, 8, 0), stroke(T.line, 1)})
local gi = icon(gw, "search", 12, T.muted, 1.4)
gi.holder.Position = UDim2.fromOffset(9, 8)
gb.FocusLost:Connect(function() if gb.Text ~= FL.game then FL.game = gb.Text FL.dirty = true end end)
local function seg(par, o, opts, key)
local f = new("Frame", {Size = UDim2.new(1, 0, 0, 28), BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = .35, LayoutOrder = o, Parent = par}, {round(8), stroke(T.line, 1), hlist(2, nil, Enum.HorizontalAlignment.Center)})
local bs = {}
local function paint() for v, b in pairs(bs) do tween(b, {BackgroundTransparency = FL[key] == v and 0 or 1}, .15) end end
for i, v in ipairs(opts) do
bs[v] = new("TextButton", {
Size = UDim2.new(1 / #opts, -3, 1, -6), BackgroundColor3 = T.bronze, BackgroundTransparency = 1, AutoButtonColor = false,
Text = v, TextSize = 10, FontFace = F.Bold, TextColor3 = T.text, LayoutOrder = i, Parent = f,
}, {round(6)})
bs[v].Activated:Connect(function() FL[key] = v FL.dirty = true paint() end)
end
paint()
end
seg(card(3, "SHOW", "eye"), 1, {"New", "Trending", "All"}, "show")
local c4 = card(4, "SORT BY", "sliders")
seg(c4, 1, {"Relevance", "Views", "Newest", "Likes"}, "sort")
text(c4, "ORDER", 10, "Bold", T.tan, {LayoutOrder = 2, Size = UDim2.new(1, 0, 0, 14)})
seg(c4, 3, {"Descending", "Ascending"}, "order")
end
gearB.Activated:Connect(openFilters)
local hubNavButtons = {}
local navList = {}
paintHubNav = function()
local activeKey = hubState.mode
if hubState.mode == "latest" or hubState.mode == "trending" or hubState.mode == "search" then activeKey = "browse" end
for key, item in pairs(hubNavButtons) do item.setActive(key == activeKey) end
end
local function hubNav(key, label, ico, y, cb)
local it = FX.sideItem(hubSide, label, ico, {
pos = UDim2.fromOffset(7, y), size = UDim2.new(1, -14, 0, 30), padL = 9, gap = 8, iconSize = 14, textSize = 10, raw = true,
})
hubNavButtons[key] = it
navList[#navList + 1] = {b = it.b, label = label}
it.b.Activated:Connect(cb)
return it.b
end
hubNav("browse", "Browse", "compass", 72, function() setMode("latest") end)
hubNav("game", "Game", "cube", 106, function() setMode("game") end)
hubNav("saved", "Saved", "bookmark", 140, function() setMode("saved") end)
hubNav("recent", "Recent", "history", 174, function() setMode("recent") end)
hubNav("favorites", "Favorites", "heart", 208, function() setMode("favorites") end)
local sideWrap = new("Frame", {Position = UDim2.fromOffset(8, 36), Size = UDim2.new(1, -16, 0, 26), BackgroundTransparency = 1, Parent = hubSide})
local sideBox = new("TextBox", {
Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.panel, Text = "", PlaceholderText = "Search...", PlaceholderColor3 = T.muted,
TextColor3 = T.text, TextSize = 10, FontFace = F.SemiBold, ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, Parent = sideWrap,
}, {round(8), pad(24, 0, 7, 0)})
local sideSt = stroke(T.line, 1)
sideSt.Parent = sideBox
local sideIc = icon(sideWrap, "search", 12, T.muted, 1.4)
sideIc.holder.Position = UDim2.fromOffset(8, 7)
sideBox.Focused:Connect(function() tween(sideSt, {Color = T.bronze}, .2) sideIc.set(T.bronze, .2) end)
sideBox.FocusLost:Connect(function() tween(sideSt, {Color = T.line}, .2) sideIc.set(T.muted, .2) end)
sideBox:GetPropertyChangedSignal("Text"):Connect(function()
local q = sideBox.Text:lower():match("^%s*(.-)%s*$")
local y = 72
for _, it in ipairs(navList) do
local show = q == "" or it.label:lower():find(q, 1, true) ~= nil
it.b.Visible = show
if show then it.b.Position = UDim2.fromOffset(7, y); y = y + 34 end
end
end)
text(hubSide, "Powered by ScriptBlox.com", 8, "Regular", T.muted, {AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 8, 1, -8), Size = UDim2.new(1, -16, 0, 22), TextWrapped = true})
local function clearCards()
for _, c in ipairs(cards) do c:Destroy() end
cards, badges = {}, {}
end
local function makeCard(s, idx, par)
local cell = new("Frame", {BackgroundTransparency = 1, LayoutOrder = idx, Size = UDim2.fromOffset(CARD_W, CARD_H), Parent = par})
local sc = new("UIScale", {Scale = .92})
local st = stroke(T.line, 1)
local card = new("CanvasGroup", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromScale(1, 1),
BackgroundColor3 = T.cardTop, BorderSizePixel = 0, GroupTransparency = 1, Parent = cell,
}, {round(8), st, sc})
local banner = new("Frame", {Size = UDim2.new(1, 0, .58, 0), BackgroundColor3 = T.panel2, BorderSizePixel = 0, ClipsDescendants = true, Parent = card})
new("Frame", {AnchorPoint = Vector2.new(0, 1), Position = UDim2.fromScale(0, 1), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line, BorderSizePixel = 0, ZIndex = 3, Parent = banner})
local ph = text(banner, (s.game:match("%w") or "S"):upper(), 20, "Bold", T.tan, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center})
local img = new("ImageLabel", {AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, ScaleType = Enum.ScaleType.Crop, ResampleMode = Enum.ResamplerMode.Default, ImageTransparency = 1, Parent = banner})
new("TextLabel", {
AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 4, 1, -4), AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14),
BackgroundColor3 = Color3.fromRGB(20, 20, 22), BackgroundTransparency = .25, Text = fmt(s.views) .. " views", TextSize = 9,
FontFace = F.Bold, TextColor3 = T.text, Parent = banner,
}, {round(4), pad(6, 0)})
local badge = new("Frame", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -4, 0, 4), Size = UDim2.fromOffset(18, 18),
BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = .3, Visible = Store.cloudIndex(s.slug) ~= nil, Parent = banner,
}, {round(9)})
local bi = icon(badge, "starFill", 11, T.gold, 1.5)
bi.holder.AnchorPoint, bi.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
badges[s.slug] = badge
local stats = new("Frame", {
AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(1, -4, 1, -4), AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14),
BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = .3, Parent = banner,
}, {round(4), pad(5, 0), hlist(3)})
local function statItem(ico, order)
local i = icon(stats, ico, 9, T.gold, 1.4)
i.holder.LayoutOrder = order
return text(stats, "0", 9, "Bold", T.text, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 12), LayoutOrder = order + 1})
end
local likeLbl, saveLbl = statItem("heart", 1), statItem("star", 3)
local hIc, sIc
local function paintCard()
local lk = Store.likes[s.slug] and true or false
local sv = Store.cloudIndex(s.slug) ~= nil
hIc.swap(lk and "heartFill" or "heart")
hIc.set(lk and T.gold or T.text, .15)
sIc.swap(sv and "starFill" or "star")
sIc.set(sv and T.gold or T.text, .15)
likeLbl.Text = fmt((s.likes or 0) + (lk and 1 or 0))
saveLbl.Text = fmt((s.saves or 0) + (sv and 1 or 0))
end
local function qbtn(x, ico, cb)
local b = new("TextButton", {
Position = UDim2.fromOffset(x, 4), Size = UDim2.fromOffset(22, 22), BackgroundColor3 = Color3.fromRGB(20, 20, 22),
BackgroundTransparency = .3, AutoButtonColor = false, Text = "", ZIndex = 6, Parent = card,
}, {round(6), stroke(Color3.fromRGB(255, 255, 255), 1)})
local ic = icon(b, ico, 12, T.text, 1.5)
ic.holder.AnchorPoint, ic.holder.Position, ic.holder.ZIndex = Vector2.new(.5, .5), UDim2.fromScale(.5, .5), 7
b.MouseEnter:Connect(function() tween(b, {BackgroundTransparency = .05}, .15) end)
b.MouseLeave:Connect(function() tween(b, {BackgroundTransparency = .3}, .2) end)
b.Activated:Connect(cb)
return ic
end
hIc = qbtn(4, "heart", function() toggleLike(s) paintCard() end)
sIc = qbtn(30, "star", function() toggleSave(s, paintCard) end)
local xIc = qbtn(56, "play", function()
if s.localRecent then
if s.code then runCode(s.code, s.title) end
else
toast("Running " .. tostring(s.title or "script"))
Store.runCloud(s)
end
end)
xIc.set(T.gold, .15)
if s.localRecent then
for _, q in ipairs({hIc, sIc}) do if q and q.holder and q.holder.Parent then q.holder.Parent.Visible = false end end
end
paintCard()
text(card, s.title, 11, "Bold", T.text, {Position = UDim2.new(0, 10, .58, 4), Size = UDim2.new(1, -20, .2, 0), TextTruncate = Enum.TextTruncate.AtEnd})
local srcX = 10
if SI.site[s.src] then
SI.badge(card, s.src, 13, {AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, 10, .58, 4 + 17 + math.floor(CARD_H * .16 / 2))})
srcX = 28
end
text(card, s.game .. " • " .. (SRCNAME[s.src] or tostring(s.src or "Local")), 9, "SemiBold", T.muted, {Position = UDim2.new(0, srcX, .58, 4 + 17), Size = UDim2.new(1, -(srcX + 10), .16, 0), TextTruncate = Enum.TextTruncate.AtEnd})
local hit = new("TextButton", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Text = "", ZIndex = 5, Parent = card})
hit.MouseEnter:Connect(function() tween(st, {Color = T.bronze}, .15) tween(sc, {Scale = 1.015}, .22, Enum.EasingStyle.Quint) tween(img, {Size = UDim2.fromScale(1.12, 1.12)}, .4, Enum.EasingStyle.Quint) end)
hit.MouseLeave:Connect(function()
tween(st, {Color = T.line}, .2)
tween(img, {Size = UDim2.fromScale(1, 1)}, .4, Enum.EasingStyle.Quint)
tween(sc, {Scale = 1}, .3, Enum.EasingStyle.Back)
end)
hit.MouseButton1Down:Connect(function() tween(sc, {Scale = .94}, .08) end)
hit.MouseButton1Up:Connect(function() tween(sc, {Scale = 1}, .3, Enum.EasingStyle.Back) end)
hit.Activated:Connect(function()
if s.localRecent then
newTab(tostring(s.title or "Recent script"):sub(1, 22), s.code or "")
showPage("Editor")
if Store.openEditorPane then Store.openEditorPane() end
else
Store.openDetail(s)
end
end)
local popped = false
pcall(function()
if FX.bub and FX.bub.cardPop then popped = FX.bub.cardPop(cell, card, sc, idx) == true end
end)
if not popped then
task.delay(math.min(idx - 1, 8) * .035, function()
if card.Parent then
tween(card, {GroupTransparency = 0}, .3)
tween(sc, {Scale = 1}, .45, Enum.EasingStyle.Back)
end
end)
end
loadBanner(s, img, ph)
table.insert(cards, cell)
end
local function gameTile(g, idx, par)
local cell = new("TextButton", {Size = UDim2.fromOffset(CARD_W, CARD_H), BackgroundColor3 = T.cardTop, AutoButtonColor = false, Text = "", LayoutOrder = idx, ClipsDescendants = true, Parent = par}, {round(8), stroke(T.line, 1)})
local ph = text(cell, (g.name:match("%w") or "G"):upper(), 24, "Bold", T.tan, {Size = UDim2.new(1, 0, .62, 0), TextXAlignment = Enum.TextXAlignment.Center})
local img = new("ImageLabel", {Size = UDim2.fromScale(1, .62), BackgroundTransparency = 1, ScaleType = Enum.ScaleType.Crop, ImageTransparency = 1, Parent = cell})
text(cell, g.name, 11, "Bold", T.text, {Position = UDim2.new(0, 8, .62, 4), Size = UDim2.new(1, -16, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
text(cell, g.count .. " scripts \u{2022} " .. fmt(g.views) .. " views", 9, "SemiBold", T.muted, {Position = UDim2.new(0, 8, .62, 21), Size = UDim2.new(1, -16, 0, 14), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
loadBanner({slug = "game-" .. g.name, image = g.image}, img, ph)
cell.Activated:Connect(function()
hubState.query = g.name
sb.Text = g.name
setMode("search")
hubTitle.Text = g.name
end)
table.insert(cards, cell)
end
local function topGames(list)
local by, arr = {}, {}
for _, x in ipairs(list) do
local n = x.game
if type(n) == "string" and n ~= "" and n ~= "Universal Script" and n:lower() ~= "ugc" then
local g = by[n]
if not g then g = {name = n, count = 0, views = 0, image = x.gameImage or x.image} by[n] = g arr[#arr + 1] = g end
g.count += 1
g.views += tonumber(x.views) or 0
g.image = g.image or x.gameImage or x.image
end
end
table.sort(arr, function(a, b) return a.views > b.views end)
return arr
end
local function mkSection(title, order, wrap)
local frame = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = order, Parent = feed}, {vlist(6)})
text(frame, title, 12, "Bold", T.text, {LayoutOrder = 1, Size = UDim2.new(1, 0, 0, 16)})
local cont
if wrap then
cont = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 2, Parent = frame}, {
new("UIGridLayout", {CellSize = UDim2.fromOffset(CARD_W, CARD_H), CellPadding = UDim2.fromOffset(10, 10), SortOrder = Enum.SortOrder.LayoutOrder}),
})
else
cont = scroller(frame, {
Size = UDim2.new(1, 0, 0, CARD_H + 10), LayoutOrder = 2, AutomaticCanvasSize = Enum.AutomaticSize.X,
ScrollingDirection = Enum.ScrollingDirection.X, ScrollBarThickness = 3,
}, {hlist(10, Enum.VerticalAlignment.Top)})
end
return {frame = frame, cont = cont, wrap = wrap, n = 0}
end
local needMore
local function addItems(sec, list)
local added = 0
for _, x in ipairs(list) do
if not sec.seen[x.slug] then
sec.seen[x.slug] = true
sec.n += 1
added += 1
makeCard(x, sec.n, sec.cont)
end
end
return added
end
local function loadMore(sec)
if sec.busy or sec.done or sec.token ~= hubState.token or type(sec.fetch) ~= "function" then return end
sec.busy, sec.page = true, sec.page + 1
task.spawn(function()
local ok, list, more = pcall(sec.fetch, sec.page)
if not ok then list, more = nil, "Search failed: " .. tostring(list) end
if sec.token ~= hubState.token then return end
if type(list) ~= "table" and not sec.retried then
sec.busy = false
sec.page = math.max(0, sec.page - 1)
sec.retried = true
task.delay(1, function() if sec.token == hubState.token then loadMore(sec) end end)
return
end
sec.retried = false
sec.busy = false
local added = type(list) == "table" and addItems(sec, list) or 0
local fetchError = type(more) == "string" and more or nil
if fetchError or not more then
sec.done = true
elseif added == 0 then
sec.emptyPages = (sec.emptyPages or 0) + 1
if sec.emptyPages >= 3 then sec.done = true end
else
sec.emptyPages = 0
end
if sec.after and type(list) == "table" then pcall(sec.after, list) end
if sec.n == 0 and not sec.note then
local msg = fetchError or "No scripts found."
sec.note = text(sec.frame, msg, 10, "SemiBold", T.muted, {LayoutOrder = 3, Size = UDim2.new(1, 0, 0, 42), TextWrapped = true})
end
task.delay(.5, function() if sec.token == hubState.token and needMore(sec) then loadMore(sec) end end)
end)
end
needMore = function(sec)
if sec.wrap then return feed.CanvasPosition.Y + feed.AbsoluteWindowSize.Y >= feed.AbsoluteCanvasSize.Y - 150 end
local c = sec.cont
return c.CanvasPosition.X + c.AbsoluteWindowSize.X >= c.AbsoluteCanvasSize.X - 200
end
feed:GetPropertyChangedSignal("CanvasPosition"):Connect(function()
local t = hubState.tail
if t and needMore(t) then loadMore(t) end
end)
hubLoad = function()
hubState.token += 1
local tk = hubState.token
clearCards()
for _, c in ipairs(feed:GetChildren()) do if c:IsA("Frame") then c:Destroy() end end
feed.CanvasPosition = Vector2.new(0, 0)
setStatus(nil)
hubState.tail = nil
local m, q = hubState.mode, hubState.query
if m == "latest" and FL.game ~= "" then m, q = "search", FL.game end
if m == "game" then q = Store.realGameName() end
local function sec(title, order, wrap, fetch)
local x = mkSection(title, order, wrap)
x.fetch, x.page, x.token, x.seen = fetch, 0, tk, {}
if not wrap then
x.cont:GetPropertyChangedSignal("CanvasPosition"):Connect(function() if needMore(x) then loadMore(x) end end)
end
return x
end
if m == "saved" or m == "recent" or m == "favorites" then
local list = {}
if m == "saved" then
for _, x in ipairs(Store.cloud) do list[#list + 1] = x end
elseif m == "recent" then
for i, entry in ipairs(recents) do
list[#list + 1] = {slug = "recent-" .. tostring(i), title = entry.name or "Recent script", game = game.Name, code = entry.code or "", views = 0, likes = 0, saves = 0, localRecent = true}
end
else
for _, v in pairs(Store.likes) do if type(v) == "table" then list[#list + 1] = v end end
table.sort(list, function(a, b) return tostring(a.title) < tostring(b.title) end)
end
if #list == 0 then
setStatus(m == "saved" and "No saved scripts yet.\nTap the star on a script to save it." or m == "recent" and "No recently executed scripts yet." or "No scripts found.")
return
end
local x = sec(m == "saved" and "Saved" or m == "recent" and "Recent" or "Favorites", 1, true, nil)
x.done = true
addItems(x, list)
return
end
local function fx(kind, all) return function(p) return gather({kind = kind, q = q, page = p, all = all}) end end
if m == "search" or m == "game" then
local x = sec(m == "game" and ("Scripts for " .. q) or "Results", 1, true, m == "game" and fx("game", false) or fx("latest", false))
hubState.tail = x
loadMore(x)
elseif FL.show == "New" or FL.show == "Trending" then
local x = sec(FL.show, 1, true, fx(FL.show == "New" and "latest" or "trending"))
hubState.tail = x
loadMore(x)
else
local ft = sec("Featured", 1, false, fx("trending"))
local gs = sec("Popular games", 2, false, nil)
gs.frame.Visible = false
gs.done = true
local nw = sec("New", 3, true, fx("latest"))
ft.after = function(list)
if gs.filled then return end
gs.filled = true
local arr = topGames(list)
if #arr == 0 then return end
gs.frame.Visible = true
for i = 1, math.min(#arr, 15) do gameTile(arr[i], i, gs.cont) end
end
hubState.tail = nw
loadMore(ft)
loadMore(nw)
end
end
setMode = function(m)
hubState.mode, hubState.total = m, 1
if m ~= "search" then hubState.query = "" sb.Text = "" end
if m == "game" then hubTitle.Text = "Scripts for " .. (Store.gname or tostring(game.Name))
elseif m == "saved" then hubTitle.Text = "Saved scripts"
elseif m == "recent" then hubTitle.Text = "Recent scripts"
elseif m == "favorites" then hubTitle.Text = "Favorites"
elseif m == "search" then hubTitle.Text = "Search results"
else hubTitle.Text = "Browse scripts" end
styleChips()
paintHubNav()
hubLoad(1)
end
function Store.hubOpen()
if not hubState.loaded then
hubState.loaded = true
setMode("latest")
end
end
function Store.openDetail(s)
local p = FX.popup({
name = "HXPopupDetail", parent = hub, z = 20, w = 700, h = 560, margin = 10,
title = "Script details", icon = "filecode",
actions = {{icon = "heart"}, {icon = "star"}},
})
local closeDlg = p.close
local heartB, heartIc = p.actions[1].b, p.actions[1].ic
local starB, starIc = p.actions[2].b, p.actions[2].ic
local left = new("Frame", {Position = UDim2.fromOffset(12, 12), Size = UDim2.new(.4, -14, 1, -24), BackgroundTransparency = 1, Parent = p.body}, {vlist(6)})
local banner = new("Frame", {Size = UDim2.new(1, 0, 0, 80), BackgroundColor3 = T.panel2, BorderSizePixel = 0, LayoutOrder = 1, ClipsDescendants = true, Parent = left}, {round(8)})
local ph = text(banner, (s.game:match("%w") or "S"):upper(), 28, "Bold", T.tan, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center})
local img = new("ImageLabel", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, ScaleType = Enum.ScaleType.Crop, ResampleMode = Enum.ResamplerMode.Default, ImageTransparency = 1, Parent = banner}, {round(8)})
loadBanner(s, img, ph, true)
local function fitBanner() banner.Size = UDim2.new(1, 0, 0, math.floor(left.AbsoluteSize.X * 9 / 16)) end
left:GetPropertyChangedSignal("AbsoluteSize"):Connect(fitBanner)
task.defer(fitBanner)
text(left, fmt(s.views) .. " views", 11, "Bold", T.text, {LayoutOrder = 2, Size = UDim2.new(1, 0, 0, 14)})
local likesLbl = text(left, "", 11, "Bold", T.text, {LayoutOrder = 3, Size = UDim2.new(1, 0, 0, 14)})
if s.created then text(left, "Added " .. s.created, 10, "SemiBold", T.muted, {LayoutOrder = 4, Size = UDim2.new(1, 0, 0, 14)}) end
local right = scroller(p.body, {Position = UDim2.new(.4, 4, 0, 12), Size = UDim2.new(.6, -16, 1, -24), ScrollBarThickness = 2}, {vlist(6)})
text(right, s.title, 14, "Bold", T.text, {TextWrapped = true, AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, 0, 0, 0), LayoutOrder = 1})
text(right, s.game, 11, "SemiBold", T.tan, {TextWrapped = true, AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, 0, 0, 0), LayoutOrder = 2})
local srcRow = new("Frame", {Size = UDim2.new(1, 0, 0, 18), BackgroundTransparency = 1, LayoutOrder = 3, Parent = right}, {hlist(6)})
if SI.site[s.src] then
SI.badge(srcRow, s.src, 16, {LayoutOrder = 1})
end
text(srcRow, "Source: " .. (SRCNAME[s.src] or tostring(s.src or "Local")), 10, "SemiBold", T.muted, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 16), LayoutOrder = 2})
local tags = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 4, Parent = right}, {
new("UIListLayout", {FillDirection = Enum.FillDirection.Horizontal, Wraps = true, Padding = UDim.new(0, 4), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local tagN = 0
local function pill(txt, bg)
tagN += 1
new("TextLabel", {
AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 16), BackgroundColor3 = bg, Text = txt, TextSize = 9,
FontFace = F.Bold, TextColor3 = T.text, LayoutOrder = tagN, Parent = tags,
}, {round(4), pad(6, 0)})
end
pill(s.free and "FREE" or "PAID", s.free and T.bronzeLo or Color3.fromRGB(110, 24, 32))
if s.verified then pill("VERIFIED", T.bronzeLo) end
pill(s.key and "KEY" or "NO KEY", T.panel2)
if s.universal then pill("UNIVERSAL", T.panel2) end
if s.patched then pill("PATCHED", Color3.fromRGB(80, 44, 30)) end
local actions = {}
local function abtn(label, ico, primary, cb)
actions[#actions + 1] = {label, ico, primary, cb}
end
local function withCode(fn)
task.spawn(function()
local code = Store.ensureCode(s)
if not isSourceCode(code) then toast("Could not fetch source from " .. (SRCNAME[s.src] or "this source")) return end
fn(code)
end)
end
abtn("Execute", "play", true, function()
withCode(function(code) runCode(code, s.title) end)
end)
abtn("Copy Script", "copy", false, function()
withCode(function(code) copy(code, "Script copied") end)
end)
abtn("Copy Loadstring", "copy", false, function()
if type(s.loadstr) == "string" and s.loadstr ~= "" then
copy(s.loadstr, "Loadstring copied")
elseif type(s.raw) == "string" and s.raw ~= "" then
copy(('loadstring(game:HttpGet("%s"))()'):format(s.raw), "Loadstring copied")
else
toast("This source has no direct raw URL")
end
end)
abtn("Copy Link", "globe", false, function()
copy(s.url or ("https://scriptblox.com/script/" .. s.slug), "Link copied")
end)
abtn("Open in Editor", "code", false, function()
withCode(function(code)
newTab(s.title:sub(1, 22), code)
showPage("Editor")
closeDlg()
end)
end)
if s.gameId then
abtn("Copy Game ID", "copy", false, function() copy(tostring(s.gameId), "Game ID copied") end)
end
local rows = math.ceil(#actions / 2)
local btnGrid = new("Frame", {Size = UDim2.new(1, 0, 0, rows * 26 + (rows - 1) * 4), BackgroundTransparency = 1, LayoutOrder = 5, Parent = right}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -3, 0, 26), CellPadding = UDim2.fromOffset(6, 4), SortOrder = Enum.SortOrder.LayoutOrder}),
})
for i, a in ipairs(actions) do
local base = a[3] and T.bronze or T.panel2
local b = new("TextButton", {BackgroundColor3 = base, AutoButtonColor = false, Text = "", LayoutOrder = i, Parent = btnGrid}, {round(7), stroke(a[3] and T.bronzeHi or T.line)})
if a[3] then
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(190, 140, 140)), Parent = b})
end
local inner = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = b}, {hlist(5, nil, Enum.HorizontalAlignment.Center)})
local ic = icon(inner, a[2], 12, T.text, 1.5)
ic.holder.LayoutOrder = 1
text(inner, a[1], 10, "Bold", T.text, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14), LayoutOrder = 2})
hoverFx(b, base, a[3] and T.bronzeHi or T.line)
pressFx(b, .94)
b.Activated:Connect(a[4])
end
local function refreshLikes()
likesLbl.Text = fmt((s.likes or 0) + (Store.likes[s.slug] and 1 or 0)) .. " likes"
end
local function paintHeart()
local on = Store.likes[s.slug] and true or false
heartIc.swap(on and "heartFill" or "heart")
heartIc.set(on and T.gold or T.text, .15)
tween(heartB, {BackgroundColor3 = on and Color3.fromRGB(70, 52, 26) or T.panel2}, .2)
end
local function paintStar()
local on = Store.cloudIndex(s.slug) ~= nil
starIc.swap(on and "starFill" or "star")
starIc.set(on and T.gold or T.text, .15)
tween(starB, {BackgroundColor3 = on and Color3.fromRGB(70, 52, 26) or T.panel2}, .2)
local bd = badges[s.slug]
if bd and bd.Parent then bd.Visible = on end
end
refreshLikes()
paintHeart()
paintStar()
heartB.Activated:Connect(function()
toggleLike(s)
paintHeart()
refreshLikes()
end)
starB.Activated:Connect(function()
if Store.cloudIndex(s.slug) then
Store.removeCloud(s.slug)
toast("Removed from Cloud Scripts")
paintStar()
if hubState.mode == "saved" then hubLoad(hubState.page) end
else
task.spawn(function()
Store.ensureCode(s)
table.insert(Store.cloud, 1, s)
Store.saveCloud()
Store.refresh()
toast("Saved to Cloud Scripts")
paintStar()
end)
end
end)
end
end)()
;(function()
local ROW_H, INDENT, LEFT = 22, 12, .52
local page = group(pages, {ClipsDescendants = true})
pageMap.Dex = page
local treePane = new("Frame", {Size = UDim2.new(LEFT, 0, 1, 0), BackgroundColor3 = T.side, BorderSizePixel = 0, ClipsDescendants = true, Parent = page})
new("Frame", {Size = UDim2.new(0, 1, 1, 0), Position = UDim2.new(1, -1, 0, 0), BackgroundColor3 = T.line, BorderSizePixel = 0, ZIndex = 5, Parent = treePane})
local insp = new("Frame", {Position = UDim2.new(LEFT, 0, 0, 0), Size = UDim2.new(1 - LEFT, 0, 1, 0), BackgroundTransparency = 1, ClipsDescendants = true, Parent = page})
local function esc(s) return (tostring(s):gsub("&", "&"):gsub("<", "<"):gsub(">", ">")) end
local function safe(f, ...)
local ok, r = pcall(f, ...)
if ok then return r end
end
local function byName(a, b) return a.Name:lower() < b.Name:lower() end
local function clip(txt, msg)
local ok = pcall(function() setclipboard(txt) end)
toast(ok and msg or "setclipboard unavailable")
end
local function pathOf(inst)
local chain, cur = {}, inst
while cur and cur ~= game do
table.insert(chain, 1, cur)
cur = cur.Parent
end
if cur ~= game then return "-- nao esta no game: " .. inst.Name end
local out = "game"
for i, o in ipairs(chain) do
if i == 1 and pcall(game.GetService, game, o.ClassName) then
out = out .. (':GetService("%s")'):format(o.ClassName)
elseif o.Name:match("^[%a_][%w_]*$") then
out = out .. "." .. o.Name
else
out = out .. ("[%q]"):format(o.Name)
end
end
return out
end
local function btn(parent, label, primary, cb, size, order)
local base = primary and T.bronze or T.panel2
local b = new("TextButton", {
BackgroundColor3 = base, AutoButtonColor = false, Text = "", LayoutOrder = order or 0, Parent = parent,
}, {round(7), stroke(primary and T.bronzeHi or T.line)})
if size then b.Size = size end
if primary then
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(190, 140, 140)), Parent = b})
end
local l = text(b, label, 10, "Bold", T.text, {Size = UDim2.fromScale(1, 1), TextXAlignment = Enum.TextXAlignment.Center})
hoverFx(b, base, primary and T.bronzeHi or T.line)
pressFx(b, .94)
b.Activated:Connect(cb)
return b, l
end
local function iconBtn(parent, ico, pos, cb)
local b = new("TextButton", {
Position = pos, Size = UDim2.fromOffset(24, 24), BackgroundColor3 = T.panel, AutoButtonColor = false, Text = "", Glass = true, Parent = parent,
}, {round(6), stroke(T.line)})
local ic = icon(b, ico, 13, T.muted, 1.4)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
b.MouseEnter:Connect(function() ic.set(T.tan, .15) end)
b.MouseLeave:Connect(function() ic.set(T.muted, .2) end)
pressFx(b, .88)
b.Activated:Connect(cb)
return b
end
local function dotColor(i)
if i.Parent == game then return T.gold end
local ok, c = pcall(function()
if i:IsA("LuaSourceContainer") then return T.bronzeHi end
if i:IsA("BasePart") then return T.text end
if i:IsA("Model") or i:IsA("Folder") then return T.tan end
if i:IsA("GuiBase") or i:IsA("LayerCollector") then return T.muted end
return T.bronzeLo
end)
return ok and c or T.muted
end
local sb = new("TextBox", {
Position = UDim2.fromOffset(6, 6), Size = UDim2.new(1, -66, 0, 24), BackgroundColor3 = T.panel, Text = "",
PlaceholderText = "Search objects...", PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 11, FontFace = F.Regular,
ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, Parent = treePane,
}, {round(6), pad(24, 0, 8, 0)})
local sbStroke = stroke(T.line, 1)
sbStroke.Parent = sb
local sbIc = icon(treePane, "search", 12, T.muted, 1.3)
sbIc.holder.Position = UDim2.fromOffset(14, 12)
sb.Focused:Connect(function() tween(sbStroke, {Color = T.tan}, .2) sbIc.set(T.tan, .2) end)
sb.FocusLost:Connect(function() tween(sbStroke, {Color = T.line}, .2) sbIc.set(T.muted, .2) end)
local sc = scroller(treePane, {
Position = UDim2.fromOffset(0, 36), Size = UDim2.new(1, 0, 1, -36), ScrollingDirection = Enum.ScrollingDirection.XY,
AutomaticCanvasSize = Enum.AutomaticSize.None, CanvasSize = UDim2.new(), ScrollBarThickness = 3,
})
local emptyLbl = text(treePane, "No results", 11, "Medium", T.muted, {
Position = UDim2.fromOffset(0, 46), Size = UDim2.new(1, 0, 0, 16), TextXAlignment = Enum.TextXAlignment.Center, Visible = false,
})
local expanded = setmetatable({}, {__mode = "k"})
local visible, pool = {}, {}
local dexMarker = new("Frame", {Name = "DexMarker", BackgroundTransparency = 1, Size = UDim2.fromOffset(1, 1), Position = UDim2.fromOffset(0, 0), Active = false, Parent = sc})
local selected, results
local canvasW = 200
local build, render, toggle, choose, inspect, reveal
local function scaleNow() return math.max(rootScale.Scale, .01) end
local function paint(r, e, idx)
local inst = e.inst
if e.kids == nil then
e.kids = (not e.flat) and (safe(inst.FindFirstChildWhichIsA, inst, "Instance") ~= nil) or false
end
r.entry = e
local b = r.btn
b.Visible = true
b.Position = UDim2.fromOffset(0, (idx - 1) * ROW_H)
b.Size = UDim2.fromOffset(canvasW, ROW_H)
b.BackgroundTransparency = (inst == selected) and 0 or 1
local x = e.depth * INDENT + 2
r.arrow.Position = UDim2.fromOffset(x, 0)
r.arrow.Visible = e.kids
local open = expanded[inst] == true
r.icR.holder.Visible = e.kids and not open
r.icD.holder.Visible = e.kids and open
r.dot.Position = UDim2.fromOffset(x + 20, (ROW_H - 6) / 2)
r.dot.BackgroundColor3 = dotColor(inst)
local txt = esc(inst.Name) .. ' ' .. esc(inst.ClassName) .. ""
if e.flat then
local p = inst.Parent
txt = txt .. ' in ' .. esc(p and p.Name or "nil") .. ""
end
r.lbl.Position = UDim2.fromOffset(x + 30, 0)
r.lbl.Size = UDim2.new(0, math.max(canvasW - x - 30, 60), 1, 0)
r.lbl.Text = txt
end
local function mkRow()
local r = {}
r.btn = new("TextButton", {
Size = UDim2.fromOffset(200, ROW_H), BackgroundColor3 = T.panel2, BackgroundTransparency = 1, BorderSizePixel = 0,
AutoButtonColor = false, Text = "", Visible = false, Parent = sc,
})
r.arrow = new("TextButton", {Size = UDim2.fromOffset(18, ROW_H), BackgroundTransparency = 1, Text = "", ZIndex = 2, Parent = r.btn})
r.icR = icon(r.arrow, "chevR", 10, T.muted, 1.4)
r.icD = icon(r.arrow, "chevD", 10, T.tan, 1.4)
for _, ic in ipairs({r.icR, r.icD}) do
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
end
r.dot = new("Frame", {Size = UDim2.fromOffset(6, 6), BorderSizePixel = 0, Parent = r.btn}, {round(3)})
r.lbl = new("TextLabel", {
BackgroundTransparency = 1, RichText = true, FontFace = F.Medium, TextSize = 11, TextColor3 = T.text,
TextXAlignment = Enum.TextXAlignment.Left, Size = UDim2.new(0, 400, 1, 0), Text = "", Parent = r.btn,
})
r.btn.Activated:Connect(function()
local e = r.entry
if not e then return end
if selected == e.inst and e.kids and not e.flat then toggle(e.inst) else choose(e.inst) end
end)
r.arrow.Activated:Connect(function()
local e = r.entry
if e and e.kids and not e.flat then toggle(e.inst) end
end)
return r
end
render = function()
local y0 = math.max(0, (sc.AbsolutePosition.Y - dexMarker.AbsolutePosition.Y) / scaleNow())
local first = math.max(1, math.floor(y0 / ROW_H) - 1)
local count = math.max(16, math.ceil(sc.AbsoluteSize.Y / scaleNow() / ROW_H) + 5)
for i = 1, count do
local r = pool[i]
if not r then
r = mkRow()
pool[i] = r
end
local e = visible[first + i - 1]
if e then paint(r, e, first + i - 1) else r.btn.Visible = false; r.entry = nil end
end
for i = count + 1, #pool do pool[i].btn.Visible = false; pool[i].entry = nil end
end
local renderPending = false
local function schedRender()
if renderPending then return end
renderPending = true
task.defer(function() renderPending = false; render() end)
end
sc:GetPropertyChangedSignal("CanvasPosition"):Connect(schedRender)
dexMarker:GetPropertyChangedSignal("AbsolutePosition"):Connect(schedRender)
sc:GetPropertyChangedSignal("AbsoluteSize"):Connect(schedRender)
build = function()
table.clear(visible)
if results then
for _, inst in ipairs(results) do visible[#visible + 1] = {inst = inst, depth = 0, flat = true} end
else
local function walk(inst, depth)
visible[#visible + 1] = {inst = inst, depth = depth}
if expanded[inst] then
local kids = safe(inst.GetChildren, inst)
if kids then
table.sort(kids, byName)
for _, k in ipairs(kids) do walk(k, depth + 1) end
end
end
end
local list = safe(game.GetChildren, game) or {}
table.sort(list, byName)
for _, r in ipairs(list) do walk(r, 0) end
end
local w = 0
for _, e in ipairs(visible) do
local n = e.inst
local est = e.depth * INDENT + 40 + (#n.Name + #n.ClassName + (e.flat and 14 or 3)) * 6.4
if est > w then w = est end
end
canvasW = math.max(w, sc.AbsoluteSize.X / scaleNow())
sc.CanvasSize = UDim2.fromOffset(canvasW, #visible * ROW_H + 6)
emptyLbl.Visible = #visible == 0
render()
end
toggle = function(inst)
expanded[inst] = (not expanded[inst]) or nil
build()
end
choose = function(inst)
selected = inst
render()
inspect(inst)
end
reveal = function(inst)
if not inst then return end
results = nil
if sb.Text ~= "" then sb.Text = "" end
local p = inst.Parent
while p and p ~= game do
expanded[p] = true
p = p.Parent
end
build()
for i, e in ipairs(visible) do
if e.inst == inst then
local want = math.max(0, (i - 3) * ROW_H)
sc.CanvasPosition = Vector2.new(0, want * scaleNow())
task.defer(function()
local cur = math.max(0, (sc.AbsolutePosition.Y - dexMarker.AbsolutePosition.Y) / scaleNow())
if math.abs(cur - want) > ROW_H * 2 and sc.CanvasPosition.Y > 0 then
sc.CanvasPosition = Vector2.new(0, sc.CanvasPosition.Y * (want / math.max(cur, 1)))
end
end)
break
end
end
choose(inst)
end
local searchTok = 0
sb:GetPropertyChangedSignal("Text"):Connect(function()
searchTok += 1
local tok = searchTok
local q = sb.Text:lower()
if q == "" then
results = nil
build()
return
end
task.delay(.35, function()
if tok ~= searchTok then return end
local res = {}
pcall(function()
for i, d in ipairs(game:GetDescendants()) do
if d.Name:lower():find(q, 1, true) or d.ClassName:lower() == q then
res[#res + 1] = d
if #res >= 300 then break end
end
if i % 4000 == 0 then
task.wait()
if tok ~= searchTok then return end
end
end
end)
if tok ~= searchTok then return end
results = res
sc.CanvasPosition = Vector2.new(0, 0)
build()
end)
end)
iconBtn(treePane, "user", UDim2.new(1, -58, 0, 6), function()
local c = lp.Character
if c then reveal(c) else toast("No character yet") end
end)
iconBtn(treePane, "refresh", UDim2.new(1, -30, 0, 6), function()
build()
inspect(selected)
toast("Refreshed")
end)
local isc = scroller(insp, {ScrollBarThickness = 3}, {pad(8), vlist(6)})
local headLbl = new("TextLabel", {
BackgroundTransparency = 1, RichText = true, TextWrapped = true, AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, 0, 0, 16),
TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top, FontFace = F.Bold, TextSize = 13,
TextColor3 = T.text, Text = "", LayoutOrder = 1, Parent = isc,
})
local pathLbl = text(isc, "", 9, "Regular", T.muted, {
AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, 0, 0, 12), TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = 2,
})
local propLbl = new("TextLabel", {
BackgroundTransparency = 1, RichText = true, TextWrapped = true, AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, 0, 0, 12),
TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top, FontFace = MONO, TextSize = 10,
TextColor3 = T.text, Text = "", LayoutOrder = 3, Parent = isc,
})
local PROPS = {"Position", "Size", "Transparency", "Anchored", "CanCollide", "Color", "Material", "Value", "Text", "Enabled", "Visible", "Disabled", "Health", "WalkSpeed", "Volume", "Brightness"}
local function show(v)
local t, s = typeof(v), nil
if t == "Instance" then
s = safe(v.GetFullName, v) or v.Name
elseif t == "Vector3" then
s = ("%.2f, %.2f, %.2f"):format(v.X, v.Y, v.Z)
elseif t == "Color3" then
s = ("%d, %d, %d"):format(math.floor(v.R * 255 + .5), math.floor(v.G * 255 + .5), math.floor(v.B * 255 + .5))
else
s = tostring(v)
end
if #s > 48 then s = s:sub(1, 46) .. ".." end
return esc(s)
end
inspect = function(inst)
if not inst then
headLbl.Text = "Nothing selected"
pathLbl.Text = "Tap an object in the tree."
propLbl.Text = ""
return
end
headLbl.Text = esc(inst.Name) .. ' ' .. esc(inst.ClassName) .. ""
pathLbl.Text = safe(inst.GetFullName, inst) or inst.Name
local lines = {}
local function add(k, v) lines[#lines + 1] = ('%s %s'):format(k, v) end
if inst.Parent == nil and inst ~= game then add("State", "not in the game tree") end
local kids = safe(inst.GetChildren, inst)
add("Children", tostring(kids and #kids or 0))
if inst.Parent then add("Parent", esc(inst.Parent.Name)) end
for _, p in ipairs(PROPS) do
local ok, v = pcall(function() return inst[p] end)
if ok and v ~= nil then add(p, show(v)) end
end
propLbl.Text = table.concat(lines, "\n")
end
inspect(nil)
local function need()
if not selected then toast("Select an object first") return nil end
return selected
end
local grid = new("Frame", {Size = UDim2.new(1, 0, 0, 3 * 24 + 8), BackgroundTransparency = 1, LayoutOrder = 4, Parent = isc}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -3, 0, 24), CellPadding = UDim2.fromOffset(6, 4), SortOrder = Enum.SortOrder.LayoutOrder}),
})
btn(grid, "Copy Path", false, function()
local i = need()
if i then clip(pathOf(i), "Path copied") end
end, nil, 1)
btn(grid, "Copy Name", false, function()
local i = need()
if i then clip(i.Name, "Name copied") end
end, nil, 2)
btn(grid, "Reveal", false, function()
local i = need()
if i then reveal(i) end
end, nil, 3)
btn(grid, "Select Parent", false, function()
local i = need()
if i and i.Parent then
if i.Parent == game then toast("Already at the top") else reveal(i.Parent) end
end
end, nil, 4)
btn(grid, "Teleport", false, function()
local i = need()
if not i then return end
local ok = pcall(function() lp.Character:PivotTo(i:GetPivot()) end)
toast(ok and "Teleported" or "Can't teleport there")
end, nil, 5)
local destroyTok, destroyArmed = 0, false
local _, destroyLbl
_, destroyLbl = btn(grid, "Destroy", false, function()
local i = need()
if not i then return end
if not destroyArmed then
destroyArmed = true
destroyLbl.Text = "Tap again"
destroyTok += 1
local tok = destroyTok
task.delay(2, function() if tok == destroyTok then destroyArmed = false destroyLbl.Text = "Destroy" end end)
return
end
destroyArmed = false
destroyTok += 1
destroyLbl.Text = "Destroy"
local ok = pcall(function() i:Destroy() end)
toast(ok and "Destroyed" or "Can't destroy that")
if ok then
addLine("Console", "> Destroyed " .. i.Name, T.tan)
selected = nil
build()
inspect(nil)
end
end, nil, 6)
section(isc, "Inject code", 5)
text(isc, "Runs on the selected object. Use `target` (or script.Parent) in your code.", 9, "Regular", T.muted, {
AutomaticSize = Enum.AutomaticSize.Y, Size = UDim2.new(1, 0, 0, 12), TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = 6,
})
local chips = scroller(isc, {
Size = UDim2.new(1, 0, 0, 22), ScrollingDirection = Enum.ScrollingDirection.X, AutomaticCanvasSize = Enum.AutomaticSize.X,
CanvasSize = UDim2.new(), ScrollBarThickness = 0, LayoutOrder = 7,
}, {hlist(4)})
local codeWrap = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.panel, BorderSizePixel = 0, LayoutOrder = 8, Parent = isc,
}, {round(6), stroke(T.line)})
local codeBox = new("TextBox", {
BackgroundTransparency = 1, Size = UDim2.new(1, 0, 0, 90), AutomaticSize = Enum.AutomaticSize.Y, MultiLine = true, TextWrapped = true,
ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top, FontFace = MONO,
TextSize = 11, TextColor3 = T.text, PlaceholderText = "-- code to run on the target", PlaceholderColor3 = T.muted, Text = "", Parent = codeWrap,
}, {pad(6)})
for i, sn in ipairs({
{"Transparency", "target.Transparency = 0.5"},
{"Anchor", "target.Anchored = true"},
{"No collide", "target.CanCollide = false"},
{"Red", "target.Color = Color3.fromRGB(255, 0, 0)"},
{"Print tree", "for _, d in ipairs(target:GetDescendants()) do\n\tprint(d:GetFullName())\nend"},
{"TP to", "local c = game.Players.LocalPlayer.Character\nif c then c:PivotTo(target:GetPivot()) end"},
{"Click", "fireclickdetector(target:FindFirstChildOfClass(\"ClickDetector\") or target)"},
{"Prompt", "fireproximityprompt(target:FindFirstChildOfClass(\"ProximityPrompt\") or target)"},
{"Destroy", "target:Destroy()"},
}) do
local c = new("TextButton", {
Size = UDim2.fromOffset(0, 20), AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = T.panel2, AutoButtonColor = false,
Text = "", LayoutOrder = i, Parent = chips,
}, {round(5), stroke(T.line), pad(8, 0)})
text(c, sn[1], 9, "Bold", T.text, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 20)})
hoverFx(c, T.panel2, T.line)
pressFx(c, .92)
c.Activated:Connect(function() codeBox.Text = sn[2] end)
end
local HEADER = 'local target=...;local part,selected=target,target;local script={Name="HyundaxIUMInject",ClassName="LocalScript",Parent=target};'
local function compile(code)
if not loadstring then
addLine("Console", "loadstring is not available in this environment.", T.bronzeHi)
toast("loadstring unavailable")
return nil
end
local fn, err = loadstring(HEADER .. code)
if not fn then
addLine("Console", tostring(err), T.bronzeHi)
statTick(true)
toast("Syntax error")
return nil
end
return fn
end
local loops = {}
local loopsLbl
local function refreshLoops()
loopsLbl.Text = ("Loops running: %d"):format(#loops)
end
local function inject(inst, code, loop, interval)
if not inst then toast("Select an object first") return end
if code:gsub("%s", "") == "" then toast("Write some code first") return end
local fn = compile(code)
if not fn then return end
execCount += 1
statTick(false)
if execLabel then execLabel.Text = tostring(execCount) end
local nm = inst.Name
if not loop then
addLine("Console", "> Inject into " .. nm .. " (" .. inst.ClassName .. ")", T.tan)
task.spawn(function()
local ok, e = pcall(fn, inst)
if ok then
addLine("Console", "[ok] finished", T.gold)
else
addLine("Console", tostring(e), T.bronzeHi)
statTick(true)
end
end)
toast("Injected")
else
local entry = {on = true}
loops[#loops + 1] = entry
refreshLoops()
addLine("Console", ("> Loop on %s every %.2fs"):format(nm, interval), T.tan)
task.spawn(function()
while entry.on do
if inst.Parent == nil and inst ~= game then
addLine("Console", "[loop] target is gone, stopped", T.muted)
break
end
local ok, e = pcall(fn, inst)
if not ok then
addLine("Console", "[loop] " .. tostring(e), T.bronzeHi)
statTick(true)
break
end
task.wait(interval)
end
entry.on = false
local i = table.find(loops, entry)
if i then table.remove(loops, i) end
refreshLoops()
end)
toast("Loop started")
end
end
local ivBox
local runRow = new("Frame", {Size = UDim2.new(1, 0, 0, 26), BackgroundTransparency = 1, LayoutOrder = 9, Parent = isc}, {hlist(4)})
btn(runRow, "Run", true, function()
inject(need(), codeBox.Text, false)
end, UDim2.fromOffset(52, 26), 1)
btn(runRow, "Loop", false, function()
local iv = math.clamp(tonumber(ivBox and ivBox.Text) or .25, .03, 60)
inject(need(), codeBox.Text, true, iv)
end, UDim2.fromOffset(52, 26), 2)
ivBox = new("TextBox", {
Size = UDim2.fromOffset(44, 26), BackgroundColor3 = T.panel, Text = "0.25", TextColor3 = T.text, TextSize = 11, FontFace = MONO,
ClearTextOnFocus = false, LayoutOrder = 3, Parent = runRow,
}, {round(6), stroke(T.line)})
text(runRow, "sec", 9, "Regular", T.muted, {Size = UDim2.fromOffset(20, 26), LayoutOrder = 4})
local loopRow = new("Frame", {Size = UDim2.new(1, 0, 0, 24), BackgroundTransparency = 1, LayoutOrder = 10, Parent = isc})
loopsLbl = text(loopRow, "", 10, "Medium", T.muted, {Size = UDim2.new(.6, 0, 1, 0)})
local stopB = btn(loopRow, "Stop all", false, function()
for _, e in ipairs(loops) do e.on = false end
table.clear(loops)
refreshLoops()
toast("Loops stopped")
end, UDim2.fromOffset(64, 22))
stopB.AnchorPoint, stopB.Position = Vector2.new(1, .5), UDim2.new(1, 0, .5, 0)
refreshLoops()
Store.dexOpen = function()
build()
inspect(selected)
end
task.defer(build)
end)()
local navBtns = {}
FX.NAV = {i = nil, w = 0, active = 1}
function FX.NAV.pos(i)
local N = FX.NAV
local x = (i - (#pageOrder + 1) / 2) * (NAV_BTN + NAV_PAD)
if N.i then
x = x - N.w / 2 + (i > N.i and N.w or (i == N.i and N.w / 2 or 0))
end
return UDim2.new(.5, x, 0, TITLE_H - 3)
end
FX.pageLoad = {tok = 0, frame = nil, spin = nil, conn = nil}
function FX.ensurePageLoader()
local PL = FX.pageLoad
if PL.frame and PL.frame.Parent then return PL.frame end
local f = new("Frame", {
Name = "PageLoader", Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.bg, BackgroundTransparency = 1,
BorderSizePixel = 0, Visible = false, ZIndex = 50, Parent = content,
})
local spin = new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromOffset(72, 72),
BackgroundTransparency = 1, ZIndex = 51, Parent = f,
})
for i = 1, 8 do
local a = math.rad((i - 1) * 45)
new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.new(.5, math.floor(math.cos(a) * 30 + .5), .5, math.floor(math.sin(a) * 30 + .5)),
Size = UDim2.fromOffset(6, 6), BackgroundColor3 = T.gold, BackgroundTransparency = 1 - i / 8,
BorderSizePixel = 0, ZIndex = 51, Parent = spin,
}, {round(3)})
end
logoImage({
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromOffset(48, 48),
ZIndex = 52, Parent = f,
})
PL.frame, PL.spin = f, spin
return f
end
function FX.runPageLoader(name)
local PL = FX.pageLoad
local f = FX.ensurePageLoader()
local spin = PL.spin
PL.tok = PL.tok + 1
local tok = PL.tok
f.Visible = true
tween(f, {BackgroundTransparency = .35}, .2)
if PL.conn then PL.conn:Disconnect() end
PL.conn = game:GetService("RunService").Heartbeat:Connect(function()
if not spin.Parent then return end
spin.Rotation = (os.clock() * 540) % 360
end)
local nb = navBtns[name]
if nb and nb.ic then
nb.ic.holder.Rotation = 0
tween(nb.ic.holder, {Rotation = 360}, .55, Enum.EasingStyle.Quint)
end
task.delay(.55, function()
if PL.tok ~= tok then return end
if PL.conn then PL.conn:Disconnect() PL.conn = nil end
tween(f, {BackgroundTransparency = 1}, .25)
task.delay(.25, function()
if PL.tok == tok then f.Visible = false end
end)
if nb and nb.ic then nb.ic.holder.Rotation = 0 end
end)
end
showPage = function(name)
if pageItems.cur ~= nil and pageMap[name] and pageItems.cur ~= pageMap[name] then
local okLoad, errLoad = pcall(FX.runPageLoader, name)
if not okLoad then warn("[Hyundax IUM] page loader: " .. tostring(errLoad)) end
end
swap(pageItems, pageMap[name])
for i, n in ipairs(pageOrder) do
local o = navBtns[n]
o.ic.set(n == name and T.gold or T.muted, .25)
tween(o.pill, {BackgroundTransparency = n == name and .15 or 1}, .3)
if n == name then
FX.NAV.active = i
tween(navIndicator, {Position = FX.NAV.pos(i)}, .5, Enum.EasingStyle.Back)
end
end
if S.cfg and S.cfg.startPage == 5 and S.cfg.lastPage ~= name then
S.cfg.lastPage = name
if S.save then S.save() end
end
if name == "Editor" then
task.delay(.1, refreshCode)
if S.cfg and S.cfg.editorFocusOnOpen then
pcall(function() local b = S.hl.Parent:FindFirstChildWhichIsA("TextBox", true) if b then b:CaptureFocus() end end)
end
end
if name == "Scripts" and Store.hubOpen then Store.hubOpen() end
if name == "Dex" and Store.dexOpen then Store.dexOpen() end
end
for i, name in ipairs(pageOrder) do
local b = new("TextButton", {
Size = UDim2.fromOffset(NAV_BTN, 30), BackgroundTransparency = 1, Text = "", AutoButtonColor = false, LayoutOrder = i, Parent = nav,
})
local pill = new("Frame", {
Size = UDim2.new(1, 0, 1, -8), Position = UDim2.fromOffset(0, 4), BackgroundColor3 = T.glow,
BackgroundTransparency = 1, BorderSizePixel = 0, Parent = b,
}, {round(9)})
local ic = icon(b, pageIcon[name], 17, T.muted, 1.6)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.new(0, NAV_BTN / 2, .5, 0)
local tagLbl = text(b, name, 11, "Bold", T.text, {
AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, NAV_BTN - 3, .5, 0), Size = UDim2.fromOffset(120, 16), TextTransparency = 1,
})
local function expand()
local w = math.ceil(tagLbl.TextBounds.X)
if w <= 0 then w = #name * 7 end
w += 4
FX.NAV.i, FX.NAV.w = i, w
tween(b, {Size = UDim2.fromOffset(NAV_BTN + w, 30)}, .35, Enum.EasingStyle.Back)
tween(tagLbl, {TextTransparency = 0}, .2)
tween(navIndicator, {Position = FX.NAV.pos(FX.NAV.active)}, .35, Enum.EasingStyle.Back)
end
local function collapse()
if FX.NAV.i == i then FX.NAV.i, FX.NAV.w = nil, 0 end
tween(b, {Size = UDim2.fromOffset(NAV_BTN, 30)}, .3, Enum.EasingStyle.Quint)
tween(tagLbl, {TextTransparency = 1}, .1)
tween(navIndicator, {Position = FX.NAV.pos(FX.NAV.active)}, .3, Enum.EasingStyle.Quint)
end
b.MouseEnter:Connect(function()
if pageItems.cur ~= pageMap[name] then ic.set(T.text, .15) end
expand()
end)
b.MouseLeave:Connect(function()
if pageItems.cur ~= pageMap[name] then ic.set(T.muted, .2) end
collapse()
end)
pressFx(b, .85)
b.InputBegan:Connect(function(inp)
if inp.UserInputType == Enum.UserInputType.Touch then expand() end
end)
b.InputEnded:Connect(function(inp)
if inp.UserInputType == Enum.UserInputType.Touch then task.delay(.6, collapse) end
end)
navBtns[name] = {b = b, ic = ic, pill = pill}
b.Activated:Connect(function() showPage(name) end)
end
local state = {min = false, max = false}
draggable(dragArea, root, nil, function() return not state.max and not (S.cfg and S.cfg.lockPos) end, function() if S.onWinDrop then S.onWinDrop() end end)
local downBar = new("Frame", {
Name = "DownBar", AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 0, 1, 0), Size = UDim2.new(1, 0, 0, 12),
BackgroundTransparency = 1, Active = true, ZIndex = 20, Parent = main,
})
new("Frame", {
Name = "DownBarGrip", AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromOffset(38, 3),
BackgroundColor3 = T.line, BackgroundTransparency = .35, BorderSizePixel = 0, ZIndex = 21, Parent = downBar,
}, {round(2)})
draggable(downBar, root, nil, function() return not state.max and not (S.cfg and S.cfg.lockPos) end, function() if S.onWinDrop then S.onWinDrop() end end)
local function applyState()
downBar.Visible = not state.min
local sz
if state.min then
sz = Vector2.new(root.Size.X.Offset, TITLE_H)
task.delay(.12, function() if state.min then content.Visible = false end end)
else
sz = state.max and maxSize() or sizeNormal
content.Visible = true
end
tween(root, {Size = UDim2.fromOffset(sz.X, sz.Y)}, .6, Enum.EasingStyle.Back)
task.delay(.8, refreshCode)
end
S.toggleMax = function()
if S.cfg and S.cfg.lockSize then toast("Window size is locked") return end
state.min = false
state.max = not state.max
maxIc.holder.Visible, restoreIc.holder.Visible = not state.max, state.max
tween(root, {Position = UDim2.fromScale(.5, .5)}, .45)
applyState()
end
btnMax.Activated:Connect(S.toggleMax)
local Lighting = game:GetService("Lighting")
local function bronzeWave(globalWave)
local Lighting = game:GetService("Lighting")
local blur = Lighting:FindFirstChild("HyundaxIUMTapBlur")
if not blur then
blur = Instance.new("BlurEffect")
blur.Name = "HyundaxIUMTapBlur"
blur.Size = 0
blur.Parent = Lighting
end
local tint = new("Frame", {
Name = "HyundaxIUMBronzeBlur",
Size = UDim2.fromScale(1, 1),
Position = UDim2.fromScale(0, 0),
BackgroundColor3 = T.bronze,
BackgroundTransparency = 1,
BorderSizePixel = 0,
ZIndex = 900,
Parent = gui,
})
tween(blur, {Size = globalWave and 16 or 8}, .8, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
tween(tint, {BackgroundTransparency = globalWave and .84 or .92}, .8, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
task.delay(globalWave and 1.1 or 1.0, function()
if tint.Parent then
tween(tint, {BackgroundTransparency = 1}, 1.0, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
end
if blur.Parent then
tween(blur, {Size = 0}, 1.1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
end
task.delay(1.15, function()
if tint.Parent then tint:Destroy() end
end)
end)
end
local pillLineDisabled = false
local floatBtn = new("Frame", {
Position = UDim2.new(0, 12, .5, -27), Size = UDim2.fromOffset(54, 54),
BackgroundColor3 = T.bg, Active = true, Visible = false, ZIndex = 120, Parent = gui,
}, {round(27), stroke(Color3.new(1, 1, 1), 2)})
local floatScale = new("UIScale", {Parent = floatBtn})
local floatMin = false
local navPill
local function ballAllowed()
local C = S.cfg
return not (C and C.float == false) or not UIS.KeyboardEnabled
end
local function showBallOnly(force)
navPill.Visible = false
floatMin = force or ballAllowed()
floatBtn.Visible = floatMin
if floatMin then
floatScale.Scale = .4
tween(floatScale, {Scale = 1}, .5, Enum.EasingStyle.Back)
end
end
do
local fs = floatBtn:FindFirstChildOfClass("UIStroke")
if fs then
new("UIGradient", {Rotation = 0, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.33, T.gold), ColorSequenceKeypoint.new(.66, T.tan), ColorSequenceKeypoint.new(1, T.bronzeHi)}), Parent = fs})
end
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(190, 190, 190)), Parent = floatBtn})
end
logoImage({Size = UDim2.fromOffset(42, 42), AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), ZIndex = 3, Parent = floatBtn})
local expandedPillSize = UDim2.fromOffset(math.min(#pageOrder * 42 + 58, 360), 56)
local collapsedLineSize = UDim2.fromOffset(148, 14)
navPill = new("Frame", {
AnchorPoint = Vector2.new(.5, 1), Position = UDim2.new(.5, 0, 1, 100),
Size = expandedPillSize, BackgroundColor3 = T.bg, BackgroundTransparency = .04,
BorderSizePixel = 0, Active = true, Visible = false, ZIndex = 130, Parent = gui,
}, {round(28), stroke(T.bronze, 1.8)})
local pillScale = new("UIScale", {Parent = navPill})
navPill:GetPropertyChangedSignal("Visible"):Connect(function()
if pillLineDisabled and navPill.Visible then navPill.Visible = false end
end)
do
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(196, 196, 196)), Parent = navPill})
local pst = navPill:FindFirstChildOfClass("UIStroke")
if pst then
new("UIGradient", {Rotation = 0, Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeHi), ColorSequenceKeypoint.new(.33, T.gold), ColorSequenceKeypoint.new(.66, T.tan), ColorSequenceKeypoint.new(1, T.bronzeHi)}), Parent = pst})
end
end
local pillRow = new("Frame", {Name = "PillRow", Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = 131, Parent = navPill})
do
local okT, tr = pcall(FX.tetris, navPill, expandedPillSize.X.Offset - 28, 56 - 12, "full", {cell = 8, alpha = .82, strokeAlpha = .75, shade = false, speedMin = 5, speedMax = 7, gap = .25, fill = .7, cellGap = 1})
if okT and tr then
tr.Size = UDim2.new(1, -28, 1, -12)
tr.Position = UDim2.fromOffset(14, 6)
local function sync() tr.Visible = navPill.AbsoluteSize.Y >= 30 end
navPill:GetPropertyChangedSignal("AbsoluteSize"):Connect(sync)
sync()
end
end
local pillLayout = new("UIListLayout", {
FillDirection = Enum.FillDirection.Horizontal, HorizontalAlignment = Enum.HorizontalAlignment.Center,
VerticalAlignment = Enum.VerticalAlignment.Center, Padding = UDim.new(0, 3), SortOrder = Enum.SortOrder.LayoutOrder,
Parent = pillRow,
})
new("UIPadding", {PaddingLeft = UDim.new(0, 7), PaddingRight = UDim.new(0, 7), Parent = pillRow})
local pillButtons = {}
for index, pageName in ipairs(pageOrder) do
local item = new("TextButton", {
Size = UDim2.fromOffset(34, 34), BackgroundColor3 = T.bronze,
BackgroundTransparency = .88, BorderSizePixel = 0, Text = "", AutoButtonColor = false,
LayoutOrder = index, ZIndex = 131, Parent = pillRow,
}, {round(17)})
local itemIcon = icon(item, pageIcon[pageName], 18, T.text, 1.5)
itemIcon.holder.AnchorPoint = Vector2.new(.5, .5)
itemIcon.holder.Position = UDim2.fromScale(.5, .5)
item.Activated:Connect(function()
bronzeWave(false)
pcall(function() if FX.bub then FX.bub.pick(item) end end)
showPage(pageName)
setShown(true)
floatBtn.Visible = floatMin
tween(navPill, {Position = UDim2.new(.5, 0, 1, 100)}, .38, Enum.EasingStyle.Quint, Enum.EasingDirection.In)
tween(pillScale, {Scale = .7}, .38, Enum.EasingStyle.Sine, Enum.EasingDirection.In)
task.delay(.4, function() navPill.Visible = false end)
end)
pillButtons[#pillButtons + 1] = item
end
local pillX = new("TextButton", {
Size = UDim2.fromOffset(40, 40), BackgroundColor3 = T.bronze,
BackgroundTransparency = .08, BorderSizePixel = 0, Text = "×",
TextColor3 = T.text, TextSize = 34, FontFace = F.Bold, AutoButtonColor = false,
LayoutOrder = 999, ZIndex = 132, Parent = pillRow,
}, {round(20), stroke(T.bronzeHi, 1.5)})
do
local okMod, errMod = pcall(function()
local RS = game:GetService("RunService")
local B = {tok = 0}
local PILL_H = 56
local GAP = pillLayout.Padding.Offset
local layer = Instance.new("Frame")
layer.Name = "HyundaxIUMBubbleLayer"
layer.BackgroundTransparency = 1
layer.BorderSizePixel = 0
layer.Size = UDim2.fromScale(1, 1)
layer.ZIndex = 140
layer.Active = false
layer.Parent = gui
pcall(function()
if not navPill:FindFirstChildOfClass("UIGradient") then
local ng = Instance.new("UIGradient")
ng.Rotation = 90
ng.Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(196, 196, 196))
ng.Parent = navPill
end
local nst = navPill:FindFirstChildOfClass("UIStroke")
if nst and not nst:FindFirstChildOfClass("UIGradient") then
local nsg = Instance.new("UIGradient")
nsg.Rotation = 90
nsg.Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 0), NumberSequenceKeypoint.new(1, .55)})
nsg.Parent = nst
end
end)
local function K() return (FX.scale or 1.5) / 1.5 end
local function clamp(x, a, b) return x < a and a or (x > b and b or x) end
local function lerp(a, b, t) return a + (b - a) * t end
local E = {}
E.outCubic = function(t) return 1 - (1 - t) ^ 3 end
E.inCubic = function(t) return t * t * t end
E.inOutCubic = function(t)
if t < .5 then return 4 * t * t * t end
return 1 - ((-2 * t + 2) ^ 3) / 2
end
E.outBack = function(t, s)
s = s or 1.7
local u = t - 1
return 1 + (s + 1) * u * u * u + s * u * u
end
E.outElastic = function(t)
if t <= 0 then return 0 elseif t >= 1 then return 1 end
return 1 + .6 * (2 ^ (-10 * t) * math.sin((t * 10 - .75) * (2 * math.pi / 3)))
end
E.outSpring = function(t, amp)
if t <= 0 then return 0 elseif t >= 1 then return 1 end
return 1 + (amp or 1) * (2 ^ (-8.5 * t) * math.sin((t * 9.5 - .75) * (2 * math.pi / 3)))
end
local function screen()
local s = layer.AbsoluteSize
if s.X < 10 then s = gui.AbsoluteSize end
return s.X, s.Y
end
local function relCenter(o)
local p, s, l = o.AbsolutePosition, o.AbsoluteSize, layer.AbsolutePosition
return p.X + s.X / 2 - l.X, p.Y + s.Y / 2 - l.Y
end
local function circle(f)
local c = Instance.new("UICorner")
c.CornerRadius = UDim.new(.5, 0)
c.Parent = f
end
function B.drops() end
function B.bubbles() end
function B.ring() end
local runs = {}
local function drive(fn, fin, keep)
local t0 = os.clock()
local h = {}
h.conn = RS.RenderStepped:Connect(function()
if h.dead then return end
local ok, done = pcall(fn, (os.clock() - t0) / K())
if not ok or done then
h.dead = true
h.conn:Disconnect()
runs[h] = nil
if fin then pcall(fin) end
end
end)
if not keep then runs[h] = true end
return h
end
function B.reset()
B.tok = B.tok + 1
for h in pairs(runs) do
h.dead = true
pcall(function() h.conn:Disconnect() end)
end
runs = {}
for _, c in ipairs(layer:GetChildren()) do pcall(function() c:Destroy() end) end
end
local function allItems()
local t = {}
for _, b in ipairs(pillButtons) do t[#t + 1] = b end
t[#t + 1] = pillX
return t
end
local function ntk(t, v) return NumberSequenceKeypoint.new(t, v) end
local function cardGlow(g, round)
if not g:FindFirstChildOfClass("UIGradient") then
local grad = Instance.new("UIGradient")
grad.Rotation = 90
grad.Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(196, 196, 196))
grad.Parent = g
end
local st = g:FindFirstChildOfClass("UIStroke")
if st and not st:FindFirstChildOfClass("UIGradient") then
local sg = Instance.new("UIGradient")
sg.Rotation = 90
sg.Transparency = NumberSequence.new({ntk(0, 0), ntk(1, .55)})
sg.Parent = st
end
local wash = Instance.new("Frame")
wash.Name = "CardWash"
wash.Size = UDim2.fromScale(1, .9)
wash.BackgroundColor3 = T.bronzeHi
wash.BackgroundTransparency = 1
wash.BorderSizePixel = 0
wash.ZIndex = 1
wash.Active = false
if round then circle(wash) end
local wg = Instance.new("UIGradient")
wg.Rotation = 90
wg.Transparency = NumberSequence.new({ntk(0, .5), ntk(1, 1)})
wg.Parent = wash
wash.Parent = g
local rim = Instance.new("Frame")
rim.Name = "CardRim"
rim.AnchorPoint = Vector2.new(.5, 0)
rim.Position = UDim2.new(.5, 0, 0, 3)
rim.Size = UDim2.new(.52, 0, 0, 1)
rim.BackgroundColor3 = Color3.new(1, 1, 1)
rim.BackgroundTransparency = 1
rim.BorderSizePixel = 0
rim.ZIndex = 3
rim.Active = false
local rg = Instance.new("UIGradient")
rg.Transparency = NumberSequence.new({ntk(0, 1), ntk(.5, 0), ntk(1, 1)})
rg.Parent = rim
rim.Parent = g
return function(a)
a = clamp(a, 0, 1)
wash.BackgroundTransparency = 1 - a
rim.BackgroundTransparency = lerp(1, .35, a)
end
end
B.cardGlow = cardGlow
local function makeGhost(it)
local ok, g = pcall(function() return it:Clone() end)
if not ok or not g then
g = Instance.new("Frame")
circle(g)
end
g.Name = "BubbleGhost"
g.AnchorPoint = Vector2.new(.5, .5)
g.Size = UDim2.fromOffset(it.Size.X.Offset, it.Size.Y.Offset)
g.BackgroundColor3 = T.bronze
g.BackgroundTransparency = 0
g.ZIndex = 143
g.Visible = false
g.Rotation = 0
pcall(function() g.Active = false end)
pcall(function() g.Interactable = false end)
local sc = Instance.new("UIScale")
sc.Scale = 1
sc.Parent = g
local rim
if not g:FindFirstChildOfClass("UIStroke") then
rim = Instance.new("UIStroke")
rim.Color = T.bronzeHi
rim.Thickness = 1.5
rim.Transparency = .1
rim.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
rim.Parent = g
end
local glow = cardGlow(g, true)
glow(1)
g.Parent = layer
return {f = g, sc = sc, glow = glow, rim = rim, w = it.Size.X.Offset, h = it.Size.Y.Offset, final = it.BackgroundTransparency}
end
local function makeNeck()
local n = Instance.new("Frame")
n.AnchorPoint = Vector2.new(.5, .5)
n.BackgroundColor3 = T.bronze
n.BorderSizePixel = 0
n.ZIndex = 142
n.Visible = false
circle(n)
n.Parent = layer
return n
end
local function smooth(x)
x = clamp(x, 0, 1)
return x * x * (3 - 2 * x)
end
function B.expand()
B.reset()
local tok = B.tok
local items = allItems()
local m = #items
local W, H = screen()
local cx = W / 2
local bottom = H - 18
local cy = bottom - PILL_H / 2
local pillW = expandedPillSize.X.Offset
local total, offs = 0, {}
for i, it in ipairs(items) do total = total + it.Size.X.Offset + (i > 1 and GAP or 0) end
local x = -total / 2
for i, it in ipairs(items) do
local w = it.Size.X.Offset
offs[i] = x + w / 2
x = x + w + GAP
end
navPill.Visible = true
navPill.Position = UDim2.new(.5, 0, 1, -18)
pillScale.Scale = 1
for _, it in ipairs(items) do it.Visible = false end
navPill.BackgroundColor3 = T.bronze
navPill.BackgroundTransparency = 0
navPill.Size = collapsedLineSize
local ghosts, necks, flags = {}, {}, {}
for i, it in ipairs(items) do
ghosts[i] = makeGhost(it)
necks[i] = makeNeck()
flags[i] = {}
end
local core = Instance.new("Frame")
core.AnchorPoint = Vector2.new(.5, 0)
core.Size = UDim2.fromOffset(20, 1)
core.BackgroundColor3 = Color3.new(1, 1, 1)
core.BackgroundTransparency = 1
core.BorderSizePixel = 0
core.ZIndex = 144
local coreG = Instance.new("UIGradient")
coreG.Transparency = NumberSequence.new({ntk(0, 1), ntk(.5, 0), ntk(1, 1)})
coreG.Parent = core
core.Parent = layer
local T_BALL, T_SPLIT, STAG, TRAVEL, BAR = .62, .5, .055, .62, .8
local END = T_SPLIT + (m - 1) * STAG + TRAVEL + .42
local st = {}
local function finish()
if tok ~= B.tok then return end
for _, g in ipairs(ghosts) do pcall(function() g.f:Destroy() end) end
for _, n in ipairs(necks) do pcall(function() n:Destroy() end) end
pcall(function() core:Destroy() end)
navPill.Size = expandedPillSize
navPill.BackgroundColor3 = T.bg
navPill.BackgroundTransparency = .04
pillScale.Scale = 1
for _, it in ipairs(items) do it.Visible = true end
drive(function(el2)
if tok ~= B.tok then return true end
pillScale.Scale = 1 + .07 * math.exp(-7 * el2) * math.sin(26 * el2)
return el2 > .8
end, function() if tok == B.tok then pillScale.Scale = 1 end end)
end
drive(function(el)
if tok ~= B.tok then return true end
if not st.form then
st.form = true
FX.snd("bub_form")
B.ring(cx, cy, 20, 74, .6, 2.6)
B.bubbles(cx, cy - 12, 5, 50)
end
if not st.whoosh and el >= T_SPLIT - .06 then
st.whoosh = true
FX.snd("bub_whoosh")
B.ring(cx, cy, 30, 96, .5, 2)
end
local e = E.outSpring(clamp(el / T_BALL, 0, 1), 1.1)
local wBall = lerp(148, PILL_H, e)
local hBall = lerp(14, PILL_H, e)
local bt = clamp((el - T_SPLIT) / BAR, 0, 1)
local w = wBall + (pillW - PILL_H) * E.outBack(bt, 2.7)
local h = hBall * (1 - .2 * math.sin(math.pi * bt))
navPill.Size = UDim2.fromOffset(math.max(w, 2), math.max(h, 2))
local cf = clamp(bt * 1.25, 0, 1)
navPill.BackgroundColor3 = T.bronze:Lerp(T.bg, cf)
navPill.BackgroundTransparency = .04 * cf
local ht = clamp((el - .05) / .15, 0, 1)
core.BackgroundTransparency = 1 - .62 * ht * (1 - clamp(bt * 1.6, 0, 1))
core.Size = UDim2.fromOffset(math.max(wBall * .5, 4), 1.5)
core.Position = UDim2.fromOffset(cx, bottom - hBall + math.max(hBall * .2, 2))
for i = 1, m do
local g, nk, fl = ghosts[i], necks[i], flags[i]
local u = (el - (T_SPLIT + (i - 1) * STAG)) / TRAVEL
if u >= 0 then
local uu = clamp(u, 0, 1)
if not fl.go then
fl.go = true
g.f.Visible = true
FX.snd("bub_p" .. math.min(i, 8))
B.drops(cx, cy, 3, 90, true)
end
local p = E.outBack(uu, 2.4)
local gx = cx + offs[i] * p
local dtL = math.max(u - 1, 0) * TRAVEL
local gy = cy - (16 + (i % 3) * 6) * math.sin(math.pi * uu) - 7 * math.exp(-7 * dtL) * math.abs(math.sin(16 * dtL))
g.f.Position = UDim2.fromOffset(gx, gy)
local s = 1 + .85 * math.sin(math.pi * uu) * (1 - .4 * uu)
local wob = .13 * math.exp(-7.5 * dtL) * math.sin(30 * dtL)
g.f.Size = UDim2.fromOffset(g.w * s * (1 + wob), g.h / (s ^ .6) * (1 - wob * .85))
g.sc.Scale = .2 + .8 * E.outBack(clamp(uu * 1.2, 0, 1), 2.8)
g.f.Rotation = (offs[i] >= 0 and 1 or -1) * 24 * math.sin(math.pi * uu) * (1 - uu)
local fd = smooth((uu - .55) / .45)
g.f.BackgroundTransparency = lerp(0, g.final, fd)
g.glow(1 - fd)
if g.rim then g.rim.Transparency = lerp(.1, 1, fd) end
local th = lerp(PILL_H * .7, 0, clamp(uu / .6, 0, 1) ^ .6)
if uu < .6 and th > 1.5 then
local dx, dy = gx - cx, gy - cy
nk.Visible = true
nk.Size = UDim2.fromOffset(math.sqrt(dx * dx + dy * dy), th)
nk.Position = UDim2.fromOffset(cx + dx / 2, cy + dy / 2)
nk.Rotation = math.deg(math.atan2(dy, dx))
elseif nk.Visible then
nk.Visible = false
B.drops(cx + (gx - cx) * .45, cy, 2, 60, true)
end
if u >= 1 and not fl.land then
fl.land = true
B.ring(gx, gy, g.w * .5, g.w * .5 + 20, .4, 1.8)
end
end
end
if el >= END then
FX.snd("bub_shine")
B.bubbles(cx, cy - 20, 6, pillW * .7)
return true
end
end, finish)
end
function B.collapse()
B.reset()
local tok = B.tok
local items = allItems()
local m = #items
local W, H = screen()
local cx = W / 2
local bottom = H - 18
local cy = bottom - PILL_H / 2
local pillW = expandedPillSize.X.Offset
local ghosts, flags, x0, y0 = {}, {}, {}, {}
for i, it in ipairs(items) do
local gx, gy = relCenter(it)
x0[i], y0[i] = gx, gy
local g = makeGhost(it)
g.f.Position = UDim2.fromOffset(gx, gy)
g.f.BackgroundTransparency = g.final
g.glow(0)
if g.rim then g.rim.Transparency = 1 end
g.f.Visible = true
ghosts[i] = g
flags[i] = {}
end
for _, it in ipairs(items) do it.Visible = false end
navPill.Visible = true
navPill.Size = expandedPillSize
navPill.BackgroundColor3 = T.bg
navPill.BackgroundTransparency = .04
pillScale.Scale = 1
local TRAVEL, STAG, BAR_AT, BAR_T = .44, .05, .1, .58
local LINE_AT, LINE_T = BAR_AT + BAR_T + .01, .62
local END = LINE_AT + LINE_T
local st = {}
local function wobble(el)
local s = 0
for i = 1, m do
local dt = el - ((m - i) * STAG + TRAVEL)
if dt > 0 then s = s + .17 * math.exp(-7 * dt) * math.sin(28 * dt) end
end
return s
end
local function finish()
if tok ~= B.tok then return end
for _, g in ipairs(ghosts) do pcall(function() g.f:Destroy() end) end
navPill.Size = collapsedLineSize
navPill.BackgroundColor3 = T.bronze
navPill.BackgroundTransparency = 0
pillScale.Scale = 1
end
drive(function(el)
if tok ~= B.tok then return true end
if not st.a then
st.a = true
FX.snd("bub_merge")
end
for i = 1, m do
local g, fl = ghosts[i], flags[i]
local u = (el - (m - i) * STAG) / TRAVEL
local uu = clamp(u, 0, 1)
if uu > 0 and not fl.go then
fl.go = true
FX.snd("bub_p" .. math.min(i, 8))
end
if u >= 1 then
if not fl.land then
fl.land = true
g.f.Visible = false
B.ring(cx, cy, 14, 40, .38, 1.8)
B.drops(cx, cy, 2, 70, true)
end
elseif uu > 0 then
local p = E.inCubic(uu)
g.f.Position = UDim2.fromOffset(lerp(x0[i], cx, p), lerp(y0[i], cy, p) - 18 * math.sin(math.pi * uu))
local s = 1 + .8 * math.sin(math.pi * uu)
g.f.Size = UDim2.fromOffset(g.w * s, g.h / (s ^ .6))
g.sc.Scale = 1 - .8 * p
g.f.Rotation = (x0[i] >= cx and -1 or 1) * 26 * math.sin(math.pi * uu)
local toBall = smooth(uu / .35)
g.f.BackgroundTransparency = lerp(g.final, 0, toBall) + (1 - lerp(g.final, 0, toBall)) * smooth((uu - .8) / .2)
g.glow(toBall)
if g.rim then g.rim.Transparency = lerp(1, .1, toBall) end
end
end
local bt = clamp((el - BAR_AT) / BAR_T, 0, 1)
local be = E.inOutCubic(bt)
local lt = clamp((el - LINE_AT) / LINE_T, 0, 1)
local le = E.outBack(lt, 3.0)
local wb = wobble(el)
local w = lerp(lerp(pillW, PILL_H, be), 148, le)
local h = lerp(PILL_H, 14, le)
navPill.Size = UDim2.fromOffset(math.max(w * (1 + wb), 2), math.max(h * (1 - wb * .8), 2))
navPill.BackgroundColor3 = T.bg:Lerp(T.bronze, smooth(bt * 1.2))
navPill.BackgroundTransparency = .04 * (1 - smooth(bt * 1.2))
if not st.line and el >= LINE_AT then
st.line = true
FX.snd("bub_land")
end
if el >= END then
B.ring(cx, bottom - 7, 12, 56, .5, 2)
B.bubbles(cx, bottom - 16, 3, 40)
return true
end
end, finish)
end
function B.show()
B.reset()
local tok = B.tok
for _, it in ipairs(allItems()) do it.Visible = false end
navPill.Visible = true
navPill.BackgroundColor3 = T.bronze
navPill.BackgroundTransparency = 0
pillScale.Scale = 1
local W, H = screen()
local cx = W / 2
local DUR = 1.05
local st = {}
local function finish()
if tok ~= B.tok then return end
navPill.Size = collapsedLineSize
navPill.Position = UDim2.new(.5, 0, 1, -18)
end
drive(function(el)
if tok ~= B.tok then return true end
if not st.a then
st.a = true
FX.snd("bub_whoosh")
end
local rise = clamp(el / .62, 0, 1)
local py = lerp(110, -18, E.outBack(rise, 1.4))
local sway = 10 * math.sin(el * 9) * (1 - rise)
navPill.Position = UDim2.new(.5, sway, 1, py)
local base = lerp(16, 34, E.outBack(clamp(el / .22, 0, 1), 1.5))
local mt = E.outElastic(clamp((el - .3) / .7, 0, 1))
local w, h = lerp(base, 148, mt), lerp(base, 14, mt)
navPill.Size = UDim2.fromOffset(math.max(w, 2), math.max(h, 2))
local n = math.floor(el / .15)
if n > (st.n or 0) and n <= 3 then
st.n = n
B.bubbles(cx + sway, H + py - h / 2, 1, 14)
end
if not st.land and el >= .55 then
st.land = true
FX.snd("bub_land")
B.ring(cx, H - 25, 20, 92, .55, 2)
end
return el >= DUR
end, finish)
end
local function bounceScale(it)
local sc = it:FindFirstChild("BounceScale")
if not sc then
sc = Instance.new("UIScale")
sc.Name = "BounceScale"
sc.Parent = it
end
return sc
end
function B.pick(it)
pcall(function()
local sc = bounceScale(it)
drive(function(el)
sc.Scale = 1 - .3 * math.exp(-5.5 * el) * math.cos(20 * el)
it.Rotation = 9 * math.exp(-6 * el) * math.sin(24 * el)
return el > 1
end, function() sc.Scale = 1; it.Rotation = 0 end, true)
end)
local x, y = relCenter(it)
FX.snd("bub_sel")
B.ring(x, y, 17, 54, .55, 2.4)
B.drops(x, y, 8, 170, true)
B.bubbles(x, y, 4, 30)
end
function B.hook(it)
local base = it.BackgroundTransparency
it.MouseEnter:Connect(function()
if not it.Visible then return end
local x, y = relCenter(it)
B.ring(x, y, 17, 34, .5, 1.6)
FX.snd("bub_hover")
if base > .3 then tween(it, {BackgroundTransparency = base - .3}, .18) end
pcall(function() tween(bounceScale(it), {Scale = 1.18}, .5, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out) end)
end)
it.MouseLeave:Connect(function()
if base > .3 then tween(it, {BackgroundTransparency = base}, .25) end
pcall(function() tween(bounceScale(it), {Scale = 1}, .45, Enum.EasingStyle.Back, Enum.EasingDirection.Out) end)
end)
end
function B.jelly(frame, sc)
local x, y = relCenter(frame)
FX.snd("bub_pop")
B.ring(x, y, 24, 60, .55, 2.4)
B.drops(x, y, 6, 130, false)
drive(function(el)
sc.Scale = 1 - .32 * math.exp(-5 * el) * math.cos(18 * el)
return el > 1.2
end, function() sc.Scale = 1 end, true)
end
local cardJobs, cardConn, lastCardSnd = {}, nil, 0
local function cardStep()
local now, k = os.clock(), K()
for i = #cardJobs, 1, -1 do
local j = cardJobs[i]
local ok, done = pcall(j.step, (now - j.t0) / k)
if not ok or done then
table.remove(cardJobs, i)
pcall(j.fin)
end
end
if #cardJobs == 0 and cardConn then
cardConn:Disconnect()
cardConn = nil
end
end
function B.cardPop(cell, card, sc, order)
local okSetup, res = pcall(function()
local corner = card:FindFirstChildOfClass("UICorner")
local baseR = corner and corner.CornerRadius.Offset or 8
local skin = Instance.new("Frame")
skin.Name = "BubbleSkin"
skin.Size = UDim2.fromScale(1, 1)
skin.BackgroundColor3 = T.bronze
skin.BorderSizePixel = 0
skin.ZIndex = 50
skin.Active = false
skin.Parent = card
local glow = cardGlow(skin, false)
glow(1)
local delay = math.min(math.max(order - 1, 0), 11) * .045
local TRAVEL = .62
local sign, started = 1, false
local function settle()
pcall(function() skin:Destroy() end)
if not card.Parent then return end
card.GroupTransparency = 0
card.Position = UDim2.fromScale(.5, .5)
card.Size = UDim2.fromScale(1, 1)
card.Rotation = 0
sc.Scale = 1
if corner then corner.CornerRadius = UDim.new(0, baseR) end
end
local job = {t0 = os.clock(), fin = settle}
job.step = function(el)
if not card.Parent or not cell.Parent then return true end
local e = el - delay
if e < 0 then return false end
if not started then
started = true
card.GroupTransparency = 0
if os.clock() - lastCardSnd > .7 then
lastCardSnd = os.clock()
pcall(function() FX.snd("bub_p" .. math.min(math.max(order, 1), 8)) end)
end
end
local uu = clamp(e / TRAVEL, 0, 1)
local ox = 0
local par = cell.Parent
if par and par:IsA("GuiObject") then
local ls = cell.AbsoluteSize.X / math.max(cell.Size.X.Offset, 1)
if ls < .01 then ls = 1 end
local pc = par.AbsolutePosition.X + par.AbsoluteSize.X / 2
local cc = cell.AbsolutePosition.X + cell.AbsoluteSize.X / 2
local span = math.max(cell.Size.X.Offset, 1) * 2.4
ox = clamp((pc - cc) / ls, -span, span)
end
if ox ~= 0 then sign = ox <= 0 and 1 or -1 end
local p = E.outBack(uu, 1.0)
local lift = (9 + (order % 3) * 4) * math.sin(math.pi * uu)
card.Position = UDim2.new(.5, ox * (1 - p), .5, -lift - 12 * (1 - p))
local s = 1 + .6 * math.sin(math.pi * uu) * (1 - .4 * uu)
local w = 0
if e > TRAVEL then
local dt = e - TRAVEL
w = .07 * math.exp(-9 * dt) * math.sin(30 * dt)
end
card.Size = UDim2.fromScale(s * (1 + w), (1 / (s ^ .6)) * (1 - w * .8))
sc.Scale = .28 + .72 * E.outBack(clamp(uu * 1.2, 0, 1), 1.6)
card.Rotation = sign * 14 * math.sin(math.pi * uu) * (1 - uu)
if corner then corner.CornerRadius = UDim.new(0, lerp(70, baseR, smooth(uu / .8))) end
local fd = smooth((uu - .5) / .5)
skin.BackgroundTransparency = fd
glow(1 - fd)
return e >= TRAVEL + .5
end
cardJobs[#cardJobs + 1] = job
if not cardConn then cardConn = RS.RenderStepped:Connect(cardStep) end
return true
end)
return okSetup and res == true
end
for _, it in ipairs(allItems()) do B.hook(it) end
FX.bub = B
end)
if not okMod then warn("[Hyundax IUM] bubble fx disabled: " .. tostring(errMod)) end
end
local pillCollapsed = false
local function expandPill(animated)
if pillLineDisabled then return end
pillCollapsed = false
if animated and FX.bub then
navPill.Visible = true
FX.bub.expand()
bronzeWave(false)
return
end
if FX.bub then FX.bub.reset() end
for _, b in ipairs(pillButtons) do b.Visible = true end
pillX.Visible = true
navPill.Visible = true
navPill.BackgroundColor3 = T.bg
navPill.BackgroundTransparency = .04
if animated then
navPill.Size = collapsedLineSize
navPill.BackgroundColor3 = T.bronze
navPill.BackgroundTransparency = 0
pillScale.Scale = .82
tween(navPill, {Size = expandedPillSize, BackgroundTransparency = .04}, .85, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
tween(pillScale, {Scale = 1}, .8, Enum.EasingStyle.Back, Enum.EasingDirection.Out)
bronzeWave(false)
else
navPill.Size = expandedPillSize
pillScale.Scale = 1
end
end
local function collapsePill()
if not navPill.Visible or pillCollapsed then return end
pillCollapsed = true
if FX.bub then
FX.bub.collapse()
return
end
for _, b in ipairs(pillButtons) do b.Visible = false end
pillX.Visible = false
navPill.BackgroundColor3 = T.bronze
navPill.BackgroundTransparency = 0
tween(pillScale, {Scale = 1}, .35, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
tween(navPill, {Size = collapsedLineSize, BackgroundTransparency = 0}, .85, Enum.EasingStyle.Quint, Enum.EasingDirection.InOut)
end
local function showPill()
if pillLineDisabled then showBallOnly() return end
floatBtn.Visible = false
navPill.Visible = true
navPill.Size = collapsedLineSize
navPill.BackgroundColor3 = T.bronze
navPill.BackgroundTransparency = 0
navPill.Position = UDim2.new(.5, 0, 1, 100)
pillScale.Scale = .86
pillCollapsed = true
for _, b in ipairs(pillButtons) do b.Visible = false end
pillX.Visible = false
if FX.bub then
FX.bub.show()
return
end
tween(navPill, {Position = UDim2.new(.5, 0, 1, -18)}, .65, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
tween(pillScale, {Scale = 1}, .65, Enum.EasingStyle.Sine, Enum.EasingDirection.Out)
end
pillX.Activated:Connect(function()
bronzeWave(false)
collapsePill()
end)
navPill.InputBegan:Connect(function(input)
if not pillCollapsed then return end
if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then
expandPill(true)
end
end)
S.doMin = function()
local ap, as = root.AbsolutePosition, root.AbsoluteSize
floatBtn.Position = UDim2.fromOffset(ap.X + as.X / 2 - 27, ap.Y + as.Y / 2 - 27)
floatBtn.ZIndex = 120
floatMin = true
local okS, errS = pcall(setShown, false)
if not okS then warn("[Hyundax IUM] minimize: " .. tostring(errS)) end
navPill.Visible = false
floatBtn.Visible = true
floatScale.Scale = .4
tween(floatScale, {Scale = 1}, .5, Enum.EasingStyle.Back)
pcall(function() FX.keepReachable(floatBtn, 54) end)
end
btnMin.Activated:Connect(S.doMin)
S.doClose = function()
setShown(false)
bronzeWave(true)
pcall(saveStats, true)
if pillLineDisabled then
showBallOnly()
else
task.delay(.22, function()
if shown then return end
if pillLineDisabled then showBallOnly() else showPill() end
end)
end
end
S.requestClose = function()
if S.cfg and S.cfg.closeConfirm then S.confirm("Close Hyundax IUM?", S.doClose) else S.doClose() end
end
btnClose.Activated:Connect(function() S.requestClose() end)
draggable(floatBtn, floatBtn, function()
if FX.bub then
FX.bub.jelly(floatBtn, floatScale)
else
floatScale.Scale = .82
tween(floatScale, {Scale = 1}, .45, Enum.EasingStyle.Back)
end
bronzeWave(false)
if pillLineDisabled then navPill.Visible = false end
floatMin = false
floatBtn.Visible = false
setShown(true)
end, nil, function() FX.keepReachable(floatBtn, 54) end, function() return 54 end)
do
local function onResize()
sizeNormal = normalSize()
local sz = state.max and maxSize() or sizeNormal
if state.min then sz = Vector2.new(sz.X, TITLE_H) end
tween(root, {Size = UDim2.fromOffset(sz.X, sz.Y)}, .25)
if FX.titleLbl then FX.titleLbl.Visible = sz.X >= 440 end
task.delay(.3, function()
FX.keepReachable(floatBtn, 54)
end)
end
local function hook()
local cam = workspace.CurrentCamera
if cam then cam:GetPropertyChangedSignal("ViewportSize"):Connect(onResize) end
end
hook()
FX.onResize = onResize
workspace:GetPropertyChangedSignal("CurrentCamera"):Connect(function() hook() onResize() end)
onResize()
end
UIS.InputBegan:Connect(function(i, gpe)
if not gpe and i.KeyCode == Enum.KeyCode.RightShift then
setShown(not shown)
if FX.bub then FX.bub.reset() end
navPill.Visible = false
if shown then floatMin = false end
floatBtn.Visible = floatMin
end
end)
do
local SUB_H, PILL_W, PILL_GAP, PILL_X = 30, 108, 4, 10
local picks = {}
local function mini(parent, label, w, primary, cb)
local b = new("TextButton", {
Size = UDim2.fromOffset(w, 24), BackgroundColor3 = primary and T.bronze or T.panel2, AutoButtonColor = false,
Text = label, TextSize = 10, FontFace = F.SemiBold, TextColor3 = primary and T.dark or T.text, Parent = parent,
}, {round(8), stroke(primary and T.bronzeHi or T.line)})
if primary then
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(Color3.new(1, 1, 1), Color3.fromRGB(200, 150, 150)), Parent = b})
end
hoverFx(b, primary and T.bronze or T.panel2, primary and T.bronzeHi or T.line)
pressFx(b, .94)
b.Activated:Connect(cb)
return b
end
local function heading(parent, title, sub, iconName, order)
local h = new("Frame", {Size = UDim2.new(1, 0, 0, 54), BackgroundTransparency = 1, LayoutOrder = order or 1, Parent = parent})
FX.chip(h, iconName, 34, T.gold, UDim2.fromOffset(0, 2))
text(h, title, 17, "Bold", T.text, {Position = UDim2.fromOffset(46, 2), Size = UDim2.new(1, -46, 0, 22)})
text(h, sub, 11, "Regular", T.muted, {Position = UDim2.fromOffset(46, 25), Size = UDim2.new(1, -46, 0, 15)})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = h})
new("Frame", {Position = UDim2.new(0, 0, 1, -2), Size = UDim2.fromOffset(46, 2), BackgroundColor3 = T.gold, BorderSizePixel = 0, Parent = h}, {round(1)})
return h
end
local function panelRow(parent, title, desc, order, h, rightW, raw)
rightW = rightW or 140
local r = new("Frame", {Size = UDim2.new(1, 0, 0, h or 50), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = order, Parent = parent}, {round(12), stroke(T.line)})
FX.sheen(r)
local st = r:FindFirstChildOfClass("UIStroke")
local accent = new("Frame", {
Position = UDim2.fromOffset(0, 10), Size = UDim2.new(0, 3, 1, -20), BackgroundColor3 = T.gold,
BackgroundTransparency = 1, BorderSizePixel = 0, Parent = r,
}, {round(2)})
text(r, title, 12, "SemiBold", T.text, {Position = UDim2.fromOffset(14, 8), Size = UDim2.new(1, -rightW, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = raw or nil})
if desc then
local dl = text(r, desc, 10, "Regular", T.muted, {Position = UDim2.fromOffset(14, 26), Size = UDim2.new(1, -rightW, 0, 14), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = raw or nil})
dl.Name = "HXDesc"
end
r.MouseEnter:Connect(function()
if FX.hover == false then return end
tween(r, {BackgroundColor3 = T.panel2}, .2)
tween(st, {Color = T.bronzeLo}, .2)
tween(accent, {BackgroundTransparency = 0}, .2)
end)
r.MouseLeave:Connect(function()
tween(r, {BackgroundColor3 = T.cardTop}, .3)
tween(st, {Color = T.line}, .3)
tween(accent, {BackgroundTransparency = 1}, .3)
end)
return r
end
local function btnBox(row, w)
return new("Frame", {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -10, .5, 0), Size = UDim2.fromOffset(w, 24),
BackgroundTransparency = 1, Parent = row,
}, {hlist(4, nil, Enum.HorizontalAlignment.Right)})
end
local function emptyNote(parent, msg, order)
text(parent, msg, 11, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 18), LayoutOrder = order, TextWrapped = true})
end
local function addSubTabs(pageName, defs)
local pg = pageMap[pageName]
local host = new("Frame", {
Name = "SubHost", Position = UDim2.fromOffset(0, SUB_H), Size = UDim2.new(1, 0, 1, -SUB_H),
BackgroundTransparency = 1, ClipsDescendants = true,
})
local panes = {}
local firstUsesExisting = defs[1] and (defs[1].existing or not defs[1].build)
local existingPane = new("Frame", {Name = "SubExisting", Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Visible = firstUsesExisting and true or false, Parent = host})
for _, c in ipairs(pg:GetChildren()) do c.Parent = existingPane end
host.Parent = pg
for i, def in ipairs(defs) do
if def.existing or (i == 1 and not def.build) then
panes[i] = existingPane
else
local pane = new("Frame", {Name = "SubPane" .. i, Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Visible = i == 1, Parent = host})
panes[i] = pane
if def.build then def.build(pane) end
end
end
local strip = new("Frame", {Name = "SubTabs", Size = UDim2.new(1, 0, 0, SUB_H), BackgroundTransparency = 1, Parent = pg})
new("Frame", {Position = UDim2.new(0, 0, 1, -1), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = strip}, {
new("UIGradient", {
Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeLo), ColorSequenceKeypoint.new(1, T.line)}),
Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, .2), NumberSequenceKeypoint.new(1, 1)}),
}),
})
local ind = new("Frame", {
Position = UDim2.fromOffset(PILL_X + 18, SUB_H - 3), Size = UDim2.fromOffset(PILL_W - 36, 2),
BackgroundColor3 = T.gold, BorderSizePixel = 0, ZIndex = 3, Parent = strip,
}, {round(1)})
local pills, cur = {}, 1
local items = {cur = panes[1], vis = panes[1]}
for i, def in ipairs(defs) do
local btn = new("TextButton", {
Position = UDim2.fromOffset(PILL_X + (i - 1) * (PILL_W + PILL_GAP), 2), Size = UDim2.fromOffset(PILL_W, SUB_H - 7),
BackgroundColor3 = T.glow, BackgroundTransparency = 1, AutoButtonColor = false, Text = "", Parent = strip,
}, {round(9), stroke(T.bronzeLo, 1)})
btn:FindFirstChildOfClass("UIStroke").Transparency = 1
local inner = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = btn}, {hlist(6, nil, Enum.HorizontalAlignment.Center)})
local ic = icon(inner, def.icon, 12, T.muted, 1.4)
ic.holder.LayoutOrder = 1
local lbl = text(inner, def.name, 11, "SemiBold", T.muted, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14), LayoutOrder = 2})
local pill = {btn = btn, ic = ic, lbl = lbl, on = false, st = btn:FindFirstChildOfClass("UIStroke")}
pills[i] = pill
btn.MouseEnter:Connect(function()
if pill.on then return end
tween(btn, {BackgroundTransparency = .6}, .25)
tween(lbl, {TextColor3 = T.text}, .25)
end)
btn.MouseLeave:Connect(function()
if pill.on then return end
tween(btn, {BackgroundTransparency = 1}, .3)
tween(lbl, {TextColor3 = T.muted}, .3)
end)
end
local function paint(i, anim)
local function set(o, props)
if anim then tween(o, props, .4) else for k, v in pairs(props) do o[k] = v end end
end
for j, pill in ipairs(pills) do
local on = (j == i)
pill.on = on
pill.ic.set(on and T.gold or T.muted, anim and .4 or nil)
set(pill.lbl, {TextColor3 = on and T.text or T.muted})
set(pill.btn, {BackgroundTransparency = on and 0 or 1})
set(pill.st, {Transparency = on and .45 or 1})
end
local indGoal = UDim2.fromOffset(PILL_X + (i - 1) * (PILL_W + PILL_GAP) + 18, SUB_H - 3)
if anim then tween(ind, {Position = indGoal}, .5, Enum.EasingStyle.Back) else ind.Position = indGoal end
end
paint(1, false)
local function pick(i)
if not panes[i] or i == cur then
if defs[i] and defs[i].onShow then defs[i].onShow() end
return
end
cur = i
paint(i, true)
swap(items, panes[i])
if defs[i].onShow then defs[i].onShow() end
end
for i, pill in ipairs(pills) do pill.btn.Activated:Connect(function() pick(i) end) end
return pick
end
local cfg = jsonRead(T.SETTINGS_FILE, {})
cfg.theme = cfg.theme or T.ACTIVE_THEME
local HX = {}
HX.FONT_LIST = {
{"Default"}, {"Gotham", "rbxasset://fonts/families/GothamSSm.json"}, {"Builder Sans", "rbxasset://fonts/families/BuilderSans.json"},
{"Montserrat", "rbxasset://fonts/families/Montserrat.json"}, {"Ubuntu", "rbxasset://fonts/families/Ubuntu.json"},
{"Roboto", "rbxasset://fonts/families/Roboto.json"}, {"Arial", "rbxasset://fonts/families/Arial.json"},
{"Source Sans", "rbxasset://fonts/families/SourceSansPro.json"}, {"Nunito", "rbxasset://fonts/families/Nunito.json"},
{"Oswald", "rbxasset://fonts/families/Oswald.json"}, {"Merriweather", "rbxasset://fonts/families/Merriweather.json"},
}
HX.EXTRA = (function()
local function tg(key, title, desc, def) return {"t", key, title, desc, def = def} end
local function ch(key, title, desc, opts, def) return {"c", key, title, desc, opts, def = def} end
local function sl(key, title, desc, def, min, max, step, unit) return {"s", key, title, desc, def = def, min = min, max = max, step = step or 1, unit = unit or ""} end
local function tx(key, title, desc, def, hint) return {"x", key, title, desc, def = def, hint = hint} end
return {
look = {
sl("winAlpha", "Window transparency", "Make the whole window see-through", 0, 0, 80, 1, "%"),
sl("uiScale", "Interface size", "Scale the whole window", 100, 60, 150, 1, "%"),
sl("corners", "Corner roundness", "Shape of panels and buttons", 100, 0, 200, 5, "%"),
sl("borders", "Borders", "Outline style on panels", 100, 0, 100, 5, "%"),
sl("scrollbar", "Scrollbar", "Thickness of scrollbars", 3, 0, 14, 1, " px"),
sl("floatSize", "Floating button size", "Size of the minimized ball", 100, 40, 200, 5, "%"),
sl("floatAlpha", "Floating button opacity", "How solid the minimized ball looks", 100, 10, 100, 5, "%"),
tg("noGradients", "Disable gradients", "Use flat colors instead of gradients", false),
tg("tabUnderline", "Tab underline", "Show the line under the active tab", true),
tg("cardLift", "Hover lift", "Buttons grow slightly when hovered", true),
tg("dimGame", "Dim game behind window", "Darken the game while the window is open", false),
tg("blurGame", "Blur game behind window", "Blur the game while the window is open", false),
},
fonts = {
tx("fontFamily", "Font", "Typeface used by the interface", "Default", "Gotham, Ubuntu, Roboto..."),
sl("fontWeight", "Text weight", "Make text lighter or bolder", 0, -2, 2, 1, ""),
sl("textScale", "Text size", "Scale interface text", 100, 70, 150, 1, "%"),
sl("codeFontSize", "Editor font size", "Size of the code in the editor", 0, -6, 14, 1, " px"),
sl("consoleFontSize", "Console font size", "Size of the console lines", 11, 8, 24, 1, " px"),
},
window = {
tg("guiInset", "Use full screen area", "Draw under the Roblox top bar", true),
sl("displayOrder", "Layer order", "Draw order above other interfaces", 999, 1, 10000, 1, ""),
ch("openAnim", "Open animation", "How the window appears", {"Pop", "Fade", "None"}, 1),
ch("closeAnim", "Close animation", "How the window disappears", {"Shrink", "Fade", "None"}, 1),
sl("idleTimeout", "Hide when idle", "Close the window after no activity", 0, 0, 60, 1, " min"),
tg("dimIdle", "Dim when idle", "Darken the window after 8 seconds without input", false),
tg("lockPos", "Lock position", "Prevent dragging the window", false),
tg("lockSize", "Lock size", "Prevent maximizing and restoring", false),
tg("rememberPos", "Remember position", "Reopen where you left the window", true),
tg("clampScreen", "Keep on screen", "Pull the window back if dropped outside", true),
tg("snapEdges", "Snap to edges", "Stick to screen borders when dropped nearby", false),
tg("startMax", "Start maximized", "Open at full size", false),
tg("startMin", "Start minimized", "Open as the floating ball", false),
tg("autoOpen", "Open on load", "Show the window when Hyundax IUM loads", true),
tg("centerOpen", "Center on open", "Always reopen in the center", false),
tg("dblClickMax", "Double click to maximize", "Double click the title bar", false),
tg("escClose", "Esc closes window", "Hide the window with the Escape key", false),
tg("closeConfirm", "Confirm close", "Ask before closing the window", false),
tg("hideOnDeath", "Hide on death", "Close the window when your character dies", false),
tg("showClock", "Clock in title bar", "Show the current time", false),
tg("showFps", "FPS in title bar", "Show frames per second", false),
tg("showPing", "Ping in title bar", "Show network ping", false),
},
notify = {
sl("toastLife", "Notice duration", "How long notices stay", 3.4, 1, 20, .1, " s"),
ch("toastPos", "Notice position", "Where notices appear", {"Bottom right", "Bottom left", "Top right", "Top left"}, 1),
sl("toastMax", "Max notices", "How many show at once", 3, 1, 12, 1, ""),
tg("toastSuccess", "Success notices", "Show success messages", true),
tg("toastErrors", "Error notices", "Show error messages", true),
tg("toastWarn", "Warning notices", "Show warnings", true),
tg("toastInfo", "Info notices", "Show general info", true),
tg("toastRun", "Run notices", "When a script is executed", true),
tg("toastSave", "Save notices", "When something is saved", true),
tg("toastCopy", "Copy notices", "When text is copied", true),
tg("toastLoad", "Load notices", "When something loads", true),
tg("toastPlugin", "Plugin notices", "Messages that mention plugins", true),
tg("toastUpdate", "Update notices", "Messages about updates", true),
tg("toastLogin", "Welcome notices", "Hello and sign in messages", true),
tg("toastTheme", "Theme notices", "Messages about themes", true),
tg("toastLang", "Language notices", "Messages about the language", true),
tg("toastGroup", "Group repeated notices", "Do not repeat a notice that is already visible", true),
tg("toastIcons", "Notice icons", "Icon on each notice", true),
tg("toastProgress", "Notice timer bar", "Bar showing the remaining time", true),
tg("toastClickDismiss", "Click to dismiss", "Tap a notice to close it", true),
tg("toastCompact", "Compact notices", "Smaller notice cards", false),
},
sound = {
sl("sndVolume", "Volume", "Loudness of interface sounds", 32, 0, 100, 1, "%"),
tg("sndTab", "Tab sounds", "Sound when changing tabs", true),
tg("sndClick", "Click sounds", "Sound on buttons", true),
tg("sndToggle", "Toggle sounds", "Sound on switches", true),
tg("sndNotice", "Notice sounds", "Sound on success and error notices", true),
tg("sndOpen", "Open and close sounds", "Sound when showing or hiding the window", true),
tg("sndBubble", "Bubble sounds", "Whoosh when the window opens and closes", true),
tg("sndHover", "Hover sounds", "Soft sound when hovering buttons", false),
tg("sndStartup", "Startup sound", "Play a sound when Hyundax IUM loads", true),
tg("sndMuteBlur", "Mute when unfocused", "Silence sounds when the game loses focus", false),
},
behavior = {
ch("startPage", "Start page", "Page shown when Hyundax IUM loads", {"Home", "Editor", "Scripts", "Settings", "Last used"}, 1),
sl("recentLimit", "Recent scripts", "How many recent scripts to keep", 30, 5, 200, 1, ""),
sl("editorTab", "Indent size", "Spaces added by auto-indent", 4, 1, 12, 1, ""),
tg("confirmRun", "Confirm before run", "Ask before executing a script", false),
tg("clearConsoleRun", "Clear console on run", "Start each run with an empty console", false),
tg("minimizeRun", "Minimize on run", "Shrink the window after executing", false),
tg("trimSpaces", "Trim spaces on save", "Remove trailing spaces when saving", false),
},
privacy = {
tg("hideNick", "Hide nickname", "Do not show your nickname in notices or the title bar", false),
tg("anonLogs", "Anonymous console", "Replace your player name in new console lines", false),
tg("redactTokens", "Redact tokens", "Hide long keys and tokens in new console lines", false),
tg("hideExecutor", "Hide executor in debug info", "Leave it out of Copy debug info", false),
tg("hidePlaceId", "Hide PlaceId in debug info", "Leave it out of Copy debug info", false),
tg("hideJobId", "Hide JobId in debug info", "Leave it out of Copy debug info", false),
tg("confirmCopyInfo", "Confirm copying debug info", "Ask before copying it", false),
tg("noRecent", "Do not save recents", "Never store recent scripts", false),
tg("noStats", "Do not count statistics", "Stop counting runs and errors", false),
},
}
end)()
HX.SPEC = {animSlow = {def = 100, min = 20, max = 300, step = 5, unit = "%"}}
function HX.rowDef(row) return row.def end
function HX.migrate()
if cfg.cfgVer == 2 then return end
local MAP = {
winAlpha = {0, 10, 20, 30, 40, 50}, uiScale = {80, 90, 100, 110, 120}, corners = {30, 100, 150}, borders = {100, 40, 0},
scrollbar = {0, 3, 3, 10}, floatSize = {80, 100, 125}, floatAlpha = {100, 75, 50, 30}, fontWeight = {-1, 0, 1},
textScale = {90, 100, 110, 120}, codeFontSize = {-2, 0, 2, 4}, consoleFontSize = {9, 11, 13, 15},
displayOrder = {999, 50, 9999}, idleTimeout = {0, 1, 5, 15}, toastLife = {2, 3.4, 5, 8}, toastMax = {2, 3, 5, 8},
sndVolume = {10, 20, 32, 50, 80}, recentLimit = {15, 30, 50, 100}, editorTab = {2, 4, 8},
}
for k, m in pairs(MAP) do
if cfg[k] ~= nil then cfg[k] = m[tonumber(cfg[k]) or 0] end
end
if type(cfg.fontFamily) == "number" then cfg.fontFamily = HX.FONT_LIST[cfg.fontFamily] and HX.FONT_LIST[cfg.fontFamily][1] or "Default" end
if cfg.animSlow == nil and cfg.speed ~= nil then cfg.animSlow = ({147, 100, 53})[tonumber(cfg.speed) or 2] or 100 end
cfg.cfgVer = 2
end
function HX.resolveFont(v)
local s = tostring(v or ""):match("^%s*(.-)%s*$")
if s == "" or s:lower() == "default" then return nil, true end
for _, f in ipairs(HX.FONT_LIST) do
if f[2] and f[1]:lower() == s:lower() then return f[2], true end
end
if s:find("^rbxasset") then return s, true end
for _, e in ipairs(Enum.Font:GetEnumItems()) do
if e.Name:lower() == s:lower() then
local okF, ff = pcall(Font.fromEnum, e)
if okF and ff then return ff.Family, true end
end
end
return nil, false
end
HX.EXTRA_ORDER = {"look", "fonts", "window", "notify", "sound", "behavior", "privacy"}
S.cfg = cfg
function HX.fill()
for _, rws in pairs(HX.EXTRA) do for _, row in ipairs(rws) do if cfg[row[2]] == nil then cfg[row[2]] = row.def end end end
for k, v in pairs({compactInterface = false, showDescriptions = true, hoverHighlights = true, confirmDestructive = false, extraContrast = false, keyboardHints = false,
editorAutoIndent = true, editorCurrentLine = true, editorSyntaxHints = true, editorClearConfirm = false, consoleTimestamps = true, consoleErrorColors = true,
editorAutoBrackets = false, editorFocusOnOpen = false, verboseDiagnostics = false, memoryDiagnostics = false, detailedErrorNotices = false,
profileWelcomeTips = true, profileNicknameHeader = false}) do if cfg[k] == nil then cfg[k] = v end end
end
local defaults = {speed = 2, waves = true, lineNums = true, wrap = false, autoscroll = true, float = true, toasts = true, autorun = true, askStart = true, disablePillLine = false, soundFeedback = true}
for k, v in pairs(defaults) do if cfg[k] == nil then cfg[k] = v end end
HX.migrate()
if cfg.animSlow == nil then cfg.animSlow = HX.SPEC.animSlow.def end
HX.fill()
local SPEEDS = {2.2, 1.5, .8}
HX.ORIG = setmetatable({}, {__mode = "k"})
HX.WEIGHTS = Enum.FontWeight:GetEnumItems()
table.sort(HX.WEIGHTS, function(a, b) return a.Value < b.Value end)
HX.lookActive, HX.lookQueued = false, false
function HX.lookStyle(o, light)
if o.Name == "Veil" then return end
local ob = HX.ORIG[o]
if not ob then ob = {} HX.ORIG[o] = ob end
if light and not (o:IsA("TextLabel") or o:IsA("TextButton") or o:IsA("TextBox") or o:IsA("UICorner")) then return end
if not light and o:IsA("GuiObject") then
local alpha = math.clamp((tonumber(cfg.winAlpha) or 0) / 100, 0, .95)
local cur = o.BackgroundTransparency
if ob.last == nil or math.abs(cur - ob.last) > 1e-4 then ob.bt = cur end
if ob.bt < 1 then
local n = ob.bt + (1 - ob.bt) * alpha
o.BackgroundTransparency = n
ob.last = n
else
ob.last = cur
end
end
if o:IsA("TextLabel") or o:IsA("TextButton") or o:IsA("TextBox") then
if o.Name == "HXDesc" then o.Visible = cfg.showDescriptions ~= false end
local ff = o.FontFace
if not ob.ff then ob.ff, ob.fw, ob.ts = ff.Family, ff.Weight, o.TextSize end
if not tostring(ob.ff):lower():find("mono") then
local fam = HX.famPath or ob.ff
local shift = math.floor(tonumber(cfg.fontWeight) or 0)
local wi = 1
for i, w in ipairs(HX.WEIGHTS) do if w == ob.fw then wi = i break end end
pcall(function() o.FontFace = Font.new(fam, HX.WEIGHTS[math.clamp(wi + shift, 1, #HX.WEIGHTS)], ff.Style) end)
if not light then o.TextSize = math.max(6, math.floor(ob.ts * ((tonumber(cfg.textScale) or 100) / 100) + .5)) end
end
elseif o:IsA("UICorner") then
if not ob.cr then ob.cr = o.CornerRadius end
o.CornerRadius = UDim.new(ob.cr.Scale, math.floor(ob.cr.Offset * ((tonumber(cfg.corners) or 100) / 100) + .5))
elseif o:IsA("UIStroke") then
if ob.sk == nil then ob.sk, ob.th = o.Transparency, o.Thickness end
local bv = math.clamp((tonumber(cfg.borders) or 100) / 100, 0, 1)
o.Enabled = bv > 0
if o == borderStroke then
o.Thickness = ob.th * (.4 + .6 * bv) * (cfg.extraContrast and 1.3 or 1)
else
local tr = ob.sk + (1 - ob.sk) * (1 - bv)
if cfg.extraContrast then tr = 0 end
o.Transparency = tr
o.Thickness = ob.th * (cfg.extraContrast and 1.6 or 1)
end
elseif o:IsA("UIGradient") then
if o:FindFirstAncestor("NoThemePick") then return end
if ob.ge == nil then ob.ge = o.Enabled end
local flat = cfg.noGradients and true or false
o.Enabled = ob.ge and not flat
local par = o.Parent
local prop = par and ((par:IsA("UIStroke") and "Color") or (par:IsA("GuiObject") and "BackgroundColor3")) or nil
if prop and ob.ge then
local pb = HX.ORIG[par]
if not pb then pb = {} HX.ORIG[par] = pb end
if flat then
if pb.gc == nil and par[prop] == Color3.new(1, 1, 1) then
local kp = o.Color.Keypoints
pb.gc = par[prop]
par[prop] = kp[math.max(1, math.ceil(#kp / 2))].Value
end
elseif pb.gc ~= nil then
par[prop] = pb.gc
pb.gc = nil
end
end
elseif o:IsA("UIListLayout") then
if not ob.pd then ob.pd = o.Padding end
if o.FillDirection == Enum.FillDirection.Vertical then
o.Padding = UDim.new(ob.pd.Scale, math.floor(ob.pd.Offset * (cfg.compactInterface and .5 or 1)))
end
elseif o:IsA("ScrollingFrame") then
if not ob.sb then ob.sb = o.ScrollBarThickness end
o.ScrollBarThickness = (tonumber(cfg.scrollbar) == 3 or cfg.scrollbar == nil) and ob.sb or math.floor(tonumber(cfg.scrollbar))
end
end
main.DescendantAdded:Connect(function(o) if HX.lookActive then task.defer(HX.lookStyle, o) end end)
HX.SKIP = {HXDim = true, HyundaxIUMBronzeBlur = true, HXBorder = true}
function HX.outside(o)
if o == floatBtn or o:IsDescendantOf(root) or o:IsDescendantOf(floatBtn) then return false end
local a = o
while a and a ~= gui do
if HX.SKIP[a.Name] then return false end
a = a.Parent
end
return a == gui
end
gui.DescendantAdded:Connect(function(o)
if not HX.lookActive then return end
task.defer(function() if o.Parent and HX.outside(o) then HX.lookStyle(o, true) end end)
end)
function HX.applyEditor()
if not (S.hl and S.hl.Parent) then return end
local cs = S.hl.Parent
local box = cs:FindFirstChildWhichIsA("TextBox", true)
local lh = cs:FindFirstChild("LineHighlight")
if lh then lh.Visible = cfg.editorCurrentLine ~= false end
local syn = cfg.editorSyntaxHints ~= false
S.hl.Visible = syn
if box then box.TextTransparency = syn and 1 or 0 end
local d = math.floor(tonumber(cfg.codeFontSize) or 0)
HX.edSize = HX.edSize or setmetatable({}, {__mode = "k"})
for _, o in ipairs(cs:GetChildren()) do
if o:IsA("TextLabel") or o:IsA("TextBox") then
if not HX.edSize[o] then HX.edSize[o] = o.TextSize end
o.TextSize = HX.edSize[o] + d
end
end
if box and not HX.edHooked then
HX.edHooked = true
local prev = box.Text
local PAIRS = {["("] = ")", ["["] = "]", ["{"] = "}", ['"'] = '"', ["'"] = "'"}
local CLOSERS = {[")"] = true, ["]"] = true, ["}"] = true, ['"'] = true, ["'"] = true}
box:GetPropertyChangedSignal("Text"):Connect(function()
local cur = box.Text
if #cur == #prev + 1 then
local pos = box.CursorPosition
local c = cur:sub(pos - 1, pos - 1)
if c == "\n" and cfg.editorAutoIndent ~= false then
local before = cur:sub(1, pos - 2)
local line = before:sub((before:match(".*\n()") or 1))
local indent = line:match("^[ \t]*") or ""
local tl = line:gsub("%s+$", "")
local opens = tl:match("%f[%w]then$") or tl:match("%f[%w]do$") or tl:match("%f[%w]else$") or tl:match("%f[%w]repeat$")
or tl:match("[{(]$") or (tl:match("%)$") and tl:match("function"))
if opens then indent = indent .. string.rep(" ", math.clamp(math.floor(tonumber(cfg.editorTab) or 4), 1, 16)) end
if indent ~= "" then
box.Text = cur:sub(1, pos - 1) .. indent .. cur:sub(pos)
box.CursorPosition = pos + #indent
end
elseif cfg.editorAutoBrackets then
local nxt = cur:sub(pos, pos)
if CLOSERS[c] and nxt == c and prev:sub(pos - 1, pos - 1) == c then
box.Text = cur:sub(1, pos - 2) .. cur:sub(pos)
box.CursorPosition = pos
elseif PAIRS[c] and not (c:match("[\"']") and (cur:sub(pos - 2, pos - 2):match("[%w_]") or nxt:match("[%w_]"))) then
box.Text = cur:sub(1, pos - 1) .. PAIRS[c] .. cur:sub(pos)
box.CursorPosition = pos
end
end
end
prev = box.Text
end)
end
end
function HX.applyLook()
HX.famPath = HX.resolveFont(cfg.fontFamily)
pcall(function() gui.IgnoreGuiInset = cfg.guiInset ~= false end)
pcall(function() gui.DisplayOrder = math.floor(tonumber(cfg.displayOrder) or 999) end)
S.uiScale = math.clamp((tonumber(cfg.uiScale) or 100) / 100, .5, 2)
FX.uiScale = S.uiScale
if shown then tween(rootScale, {Scale = S.uiScale}, .3) end
if FX.onResize and FX.uiScaleDone ~= S.uiScale then FX.uiScaleDone = S.uiScale pcall(FX.onResize) end
FX.TS.LIFE = math.clamp(tonumber(cfg.toastLife) or 3.4, .5, 60)
FX.TS.H = cfg.toastCompact and 30 or 38
S.toastMax = math.clamp(math.floor(tonumber(cfg.toastMax) or 3), 1, 20)
FX.sfx.vol = math.clamp((tonumber(cfg.sndVolume) or 32) / 100, 0, 1)
FX.sfx.off = {
tab = cfg.sndTab == false, click = cfg.sndClick == false, on = cfg.sndToggle == false, off = cfg.sndToggle == false,
ok = cfg.sndNotice == false, err = cfg.sndNotice == false, open = cfg.sndOpen == false, close = cfg.sndOpen == false,
bub_whoosh = cfg.sndBubble == false, bub_merge = cfg.sndBubble == false,
}
FX.hover, FX.lift, FX.hoverSnd = cfg.hoverHighlights ~= false, cfg.cardLift ~= false, cfg.sndHover == true
S.stampOn, S.errColors = cfg.consoleTimestamps ~= false, cfg.consoleErrorColors ~= false
local cs = math.clamp(math.floor(tonumber(cfg.consoleFontSize) or 11), 6, 40)
if (S.consoleSize or 11) ~= cs then S.consoleSize = cs pcall(LOG.rerender) end
S.anonLogs, S.redactLogs = cfg.anonLogs, cfg.redactTokens
S.recentLimit = math.clamp(math.floor(tonumber(cfg.recentLimit) or 30), 1, 1000)
S.noRecent, S.noStats, S.confirmRun = cfg.noRecent, cfg.noStats, cfg.confirmRun
S.clearOnRun, S.minRun, S.detailErr = cfg.clearConsoleRun, cfg.minimizeRun, cfg.detailedErrorNotices
navIndicator.Visible = cfg.tabUnderline ~= false
if HX.hint then HX.hint.Visible = cfg.keyboardHints == true end
if S.winFx then S.winFx(shown) end
local fa = 1 - math.clamp((tonumber(cfg.floatAlpha) or 100) / 100, .05, 1)
floatBtn.BackgroundTransparency = fa
for _, d in ipairs(floatBtn:GetDescendants()) do
if d:IsA("ImageLabel") then d.ImageTransparency = fa elseif d:IsA("UIStroke") then d.Transparency = fa end
end
local fs = floatBtn:FindFirstChild("HXSize") or new("UIScale", {Name = "HXSize", Parent = floatBtn})
fs.Scale = math.clamp((tonumber(cfg.floatSize) or 100) / 100, .3, 3)
pcall(HX.applyEditor)
local isDefault = (tonumber(cfg.winAlpha) or 0) == 0 and HX.famPath == nil and (tonumber(cfg.fontWeight) or 0) == 0 and (tonumber(cfg.textScale) or 100) == 100
and (tonumber(cfg.corners) or 100) == 100 and (tonumber(cfg.borders) or 100) == 100 and (tonumber(cfg.scrollbar) or 3) == 3 and not cfg.noGradients
and not cfg.compactInterface and not cfg.extraContrast and cfg.showDescriptions ~= false
if not isDefault then HX.lookActive = true end
if not HX.lookActive or HX.lookQueued then return end
HX.lookQueued = true
task.defer(function()
HX.lookQueued = false
HX.lookStyle(main)
for _, o in ipairs(main:GetDescendants()) do HX.lookStyle(o) end
local bf = FX.borderFrame
if bf then
HX.lookStyle(bf)
for _, o in ipairs(bf:GetDescendants()) do HX.lookStyle(o) end
end
for _, c in ipairs(gui:GetChildren()) do
if c ~= root and c ~= floatBtn and not HX.SKIP[c.Name] then
HX.lookStyle(c, true)
for _, o in ipairs(c:GetDescendants()) do HX.lookStyle(o, true) end
end
end
end)
end
function HX.start()
local RunService, StatsSvc, Lighting, Players = game:GetService("RunService"), game:GetService("Stats"), game:GetService("Lighting"), game:GetService("Players")
local hud = text(bar, "", 10, "SemiBold", T.muted, {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -108, .5, 0), Size = UDim2.fromOffset(170, 16),
TextXAlignment = Enum.TextXAlignment.Right, Visible = false, ZIndex = 4,
})
HX.hint = text(main, "RightShift: hide window | Ctrl+K: search", 9, "Regular", T.muted, {
AnchorPoint = Vector2.new(.5, 1), Position = UDim2.new(.5, 0, 1, -14), Size = UDim2.fromOffset(260, 12),
TextXAlignment = Enum.TextXAlignment.Center, ZIndex = 15, Visible = cfg.keyboardHints == true,
})
local dimFrame = new("Frame", {Name = "HXDim", Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0), BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = 0, Active = false, Parent = gui})
function S.winFx(v)
tween(dimFrame, {BackgroundTransparency = (v and cfg.dimGame) and .55 or 1}, .3)
local blur = Lighting:FindFirstChild("HyundaxIUMWinBlur")
if v and cfg.blurGame then
if not blur then blur = Instance.new("BlurEffect") blur.Name = "HyundaxIUMWinBlur" blur.Size = 0 blur.Parent = Lighting end
tween(blur, {Size = 14}, .3)
elseif blur then
tween(blur, {Size = 0}, .3)
task.delay(.4, function() if blur.Parent and not (shown and cfg.blurGame) then blur:Destroy() end end)
end
end
S.lastInput = os.clock()
local function touch()
S.lastInput = os.clock()
if S.dimmed then S.dimmed = false tween(mainVeil, {BackgroundTransparency = 1}, .2) end
end
UIS.InputBegan:Connect(function(i)
touch()
if cfg.escClose and shown and i.KeyCode == Enum.KeyCode.Escape then S.requestClose() end
end)
UIS.InputChanged:Connect(touch)
UIS.WindowFocused:Connect(function() FX.sfx.blurred = false end)
UIS.WindowFocusReleased:Connect(function() FX.sfx.blurred = cfg.sndMuteBlur == true end)
dragArea.InputBegan:Connect(function(i)
if not cfg.dblClickMax then return end
if i.UserInputType ~= Enum.UserInputType.MouseButton1 and i.UserInputType ~= Enum.UserInputType.Touch then return end
local n = os.clock()
if n - (S.lastTap or 0) < .35 then S.lastTap = 0 S.toggleMax() else S.lastTap = n end
end)
function S.onWinDrop()
if cfg.snapEdges then
local vp, ap, as = viewport(), root.AbsolutePosition, root.AbsoluteSize
local dx, dy = 0, 0
if math.abs(ap.X) < 24 then dx = -ap.X elseif math.abs(vp.X - (ap.X + as.X)) < 24 then dx = vp.X - (ap.X + as.X) end
if math.abs(ap.Y) < 24 then dy = -ap.Y elseif math.abs(vp.Y - (ap.Y + as.Y)) < 24 then dy = vp.Y - (ap.Y + as.Y) end
if dx ~= 0 or dy ~= 0 then
local p = root.Position
tween(root, {Position = UDim2.new(p.X.Scale, p.X.Offset + dx, p.Y.Scale, p.Y.Offset + dy)}, .2)
end
end
if cfg.clampScreen ~= false then pcall(FX.keepReachable, root, 40, true) end
if cfg.rememberPos ~= false then
task.delay(.4, function()
local p = root.Position
cfg.winPos = {p.X.Scale, p.X.Offset, p.Y.Scale, p.Y.Offset}
S.save()
end)
end
end
if cfg.rememberPos ~= false and type(cfg.winPos) == "table" and #cfg.winPos == 4 then
root.Position = UDim2.new(cfg.winPos[1], cfg.winPos[2], cfg.winPos[3], cfg.winPos[4])
task.delay(.6, function() pcall(FX.keepReachable, root, 40, true) end)
end
local lp = Players.LocalPlayer
local function hookChar(c)
local h = c:WaitForChild("Humanoid", 5)
if h then h.Died:Connect(function() if cfg.hideOnDeath and shown then S.doClose() end end) end
end
if lp then
if lp.Character then task.spawn(hookChar, lp.Character) end
lp.CharacterAdded:Connect(function(c) task.spawn(hookChar, c) end)
end
local frames, last = 0, os.clock()
RunService.RenderStepped:Connect(function() frames += 1 end)
task.spawn(function()
while task.wait(1) do
local now = os.clock()
local fps = math.floor(frames / math.max(now - last, .01) + .5)
frames, last = 0, now
local parts = {}
if cfg.profileNicknameHeader and not cfg.hideNick and I18N.nick ~= "" then parts[#parts + 1] = I18N.nick end
if cfg.showClock then parts[#parts + 1] = os.date("%H:%M") end
if cfg.showFps then parts[#parts + 1] = fps .. " FPS" end
if cfg.showPing then
local ok, v = pcall(function() return StatsSvc.Network.ServerStatsItem["Data Ping"]:GetValue() end)
if ok and v then parts[#parts + 1] = math.floor(v) .. " ms" end
end
if cfg.memoryDiagnostics then parts[#parts + 1] = math.floor(StatsSvc:GetTotalMemoryUsageMb()) .. " MB" end
hud.Text = table.concat(parts, " | ")
hud.Visible = #parts > 0 and root.AbsoluteSize.X / math.max(rootScale.Scale, .01) >= 600 and not state.min
local idle = now - S.lastInput
local lim = (tonumber(cfg.idleTimeout) or 0) * 60
if shown and lim > 0 and idle > lim then S.doClose() end
local dim = shown and cfg.dimIdle and idle > 8
if dim and not S.dimmed then S.dimmed = true tween(mainVeil, {BackgroundTransparency = .6}, .4) end
end
end)
task.delay(1.2, function()
if cfg.startMax and not state.max then S.toggleMax() end
if cfg.startMin and shown then S.doMin() end
end)
HX.applyLook()
end
local function applyCfg()
FX.scale = cfg.reducedMotion and .15 or (1.5 * math.clamp((tonumber(cfg.animSlow) or 100) / 100, .1, 5))
S.lineNums, S.wrap, S.autoscroll = cfg.lineNums, cfg.wrap, cfg.autoscroll
S.toasts, S.autorun = cfg.toasts, cfg.autorun
FX.sfx.enabled = cfg.soundFeedback ~= false
pillLineDisabled = cfg.disablePillLine == true
floatBtn.Visible = floatMin
if pillLineDisabled then navPill.Visible = false end
local w = main:FindFirstChild("BackgroundWaves")
if w then w.Visible = cfg.waves end
pcall(HX.applyLook)
pcall(refreshCode)
end
local function saveCfg() jsonWrite(T.SETTINGS_FILE, cfg) end
S.save = saveCfg
applyCfg()
pcall(HX.start)
local function rgbKey(c)
return math.floor(c.R * 255 + .5) * 65536 + math.floor(c.G * 255 + .5) * 256 + math.floor(c.B * 255 + .5)
end
local function setTheme(themeName)
local nextPalette = T.UI_THEMES[themeName]
if not nextPalette or T.THEME_BUSY then return end
T.THEME_BUSY = true
local oldPalette = table.clone(T)
local remap = {}
local ROLES = {"bg", "side", "panel", "panel2", "line", "text", "muted", "bronze", "bronzeHi", "bronzeLo", "gold", "dark", "glow", "cardTop", "tan"}
local oldRoles = {}
for _, role in ipairs(ROLES) do
local oc = oldPalette[role]
if typeof(oc) == "Color3" and nextPalette[role] then
local k = rgbKey(oc)
if not remap[k] then remap[k] = nextPalette[role] end
oldRoles[#oldRoles + 1] = {oc, nextPalette[role]}
end
end
local oldLum = oldPalette.bg and (oldPalette.bg.R * .299 + oldPalette.bg.G * .587 + oldPalette.bg.B * .114) or 0
local newLum = nextPalette.bg.R * .299 + nextPalette.bg.G * .587 + nextPalette.bg.B * .114
local flip = (oldLum > .5) ~= (newLum > .5)
local approx = {}
for role, color in pairs(nextPalette) do T[role] = color end
TAB_IDLE, TAB_HOVER = T.panel, T.panel2
local function convert(c)
if typeof(c) ~= "Color3" then return c end
local k = rgbKey(c)
local hit = remap[k]
if hit then return hit end
if approx[k] then return approx[k] end
local best, bd = nil, 1e9
for _, pr in ipairs(oldRoles) do
local dr, dg, db = (c.R - pr[1].R) * 255, (c.G - pr[1].G) * 255, (c.B - pr[1].B) * 255
local d = dr * dr + dg * dg + db * db
if d < bd then bd, best = d, pr end
end
if best and bd < 2800 then
local sgn = flip and -1 or 1
local r = math.clamp(best[2].R + (c.R - best[1].R) * sgn, 0, 1)
local g = math.clamp(best[2].G + (c.G - best[1].G) * sgn, 0, 1)
local b = math.clamp(best[2].B + (c.B - best[1].B) * sgn, 0, 1)
local res = Color3.new(r, g, b)
approx[k] = res
return res
end
return c
end
local function convertSequence(seq)
local points = {}
for _, kp in ipairs(seq.Keypoints) do points[#points + 1] = ColorSequenceKeypoint.new(kp.Time, convert(kp.Value)) end
return ColorSequence.new(points)
end
local COLOR_PROPS = {"BackgroundColor3", "TextColor3", "PlaceholderColor3", "ImageColor3", "BorderColor3", "ScrollBarImageColor3", "TextStrokeColor3"}
local function getProp(o, p) return o[p] end
local function setProp(o, p, v) o[p] = v end
local darkT = themeName == "Darkness"
local all = gui:GetDescendants()
local propCache = {}
local function propsFor(o)
local cn = o.ClassName
local l = propCache[cn]
if l then return l end
l = {}
for _, prop in ipairs(COLOR_PROPS) do
local ok, value = pcall(getProp, o, prop)
if ok and typeof(value) == "Color3" then l[#l + 1] = prop end
end
propCache[cn] = l
return l
end
local skipTree = {}
local t0 = os.clock()
for _, obj in ipairs(all) do
if os.clock() - t0 > .005 then task.wait(); t0 = os.clock() end
local par = obj.Parent
if par then
local nm = obj.Name
local inNoPick = skipTree[par] == true or nm == "NoThemePick"
if inNoPick then skipTree[obj] = true end
if not inNoPick and not obj:GetAttribute("NoTheme") then
if nm == "BgGlow" then obj.BackgroundColor3 = darkT and Color3.new(0, 0, 0) or T.bronze
elseif nm == "BgGlow2" then obj.BackgroundColor3 = darkT and Color3.new(0, 0, 0) or T.bronzeLo
elseif nm == "WaveSegment" then obj.BackgroundColor3 = darkT and Color3.new(0, 0, 0) or T.bronzeLo
elseif nm == "WaveDot" then obj.BackgroundColor3 = darkT and Color3.new(0, 0, 0) or T.bronzeHi end
local list = propsFor(obj)
for k = 1, #list do
local prop = list[k]
local value = obj[prop]
local changed = convert(value)
if changed ~= value then pcall(setProp, obj, prop, changed) end
end
if obj:IsA("UIStroke") then pcall(setProp, obj, "Color", convert(obj.Color))
elseif obj:IsA("UIGradient") then pcall(setProp, obj, "Color", convertSequence(obj.Color)) end
end
end
end
T.THEME_BUSY = false
T.ACTIVE_THEME = themeName
cfg.theme = themeName
saveCfg()
pcall(refreshCode)
return true
end
function T.makePicker(parent, label, startColor, order, onCommit)
local h, sat, val = startColor:ToHSV()
local card = new("Frame", {Size = UDim2.new(1, 0, 0, 180), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = order, Parent = parent}, {round(11), stroke(T.line)})
text(card, label, 12, "Bold", T.text, {Position = UDim2.fromOffset(12, 10), Size = UDim2.new(1, -110, 0, 16)})
local hexLbl = text(card, "", 10, "Bold", T.muted, {AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -12, 0, 11), Size = UDim2.fromOffset(90, 14), TextXAlignment = Enum.TextXAlignment.Right, NoI18N = true})
local area = new("Frame", {Name = "NoThemePick", BackgroundTransparency = 1, Position = UDim2.fromOffset(12, 36), Size = UDim2.new(1, -24, 0, 132), Parent = card})
local svWrap = new("Frame", {Size = UDim2.new(1, -38, 1, 0), BackgroundTransparency = 1, BorderSizePixel = 0, Parent = area})
local svBox = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.fromHSV(h, 1, 1), BorderSizePixel = 0, ClipsDescendants = true, Parent = svWrap}, {round(8)})
new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = svBox}, {new("UIGradient", {Transparency = NumberSequence.new(0, 1)})})
new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0), BorderSizePixel = 0, Parent = svBox}, {new("UIGradient", {Rotation = 90, Transparency = NumberSequence.new(1, 0)})})
local svDot = new("Frame", {AnchorPoint = Vector2.new(.5, .5), Size = UDim2.fromOffset(16, 16), BackgroundColor3 = startColor, BorderSizePixel = 0, ZIndex = 5, Parent = svWrap}, {round(8), new("UIStroke", {Color = Color3.new(1, 1, 1), Thickness = 2.5})})
local hueBar = new("Frame", {AnchorPoint = Vector2.new(1, 0), Position = UDim2.fromScale(1, 0), Size = UDim2.new(0, 22, 1, 0), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = area}, {round(8)})
local kps = {}
for i = 0, 6 do kps[#kps + 1] = ColorSequenceKeypoint.new(i / 6, Color3.fromHSV(i / 6 == 1 and 0 or i / 6, 1, 1)) end
new("UIGradient", {Rotation = 90, Color = ColorSequence.new(kps), Parent = hueBar})
local hueDot = new("Frame", {AnchorPoint = Vector2.new(.5, .5), Size = UDim2.new(1, 6, 0, 10), BackgroundTransparency = 1, ZIndex = 5, Parent = hueBar}, {round(5), new("UIStroke", {Color = Color3.new(1, 1, 1), Thickness = 2.5})})
local function refresh()
local c = Color3.fromHSV(h, sat, val)
svBox.BackgroundColor3 = Color3.fromHSV(h, 1, 1)
local aw, ah = math.max(svBox.AbsoluteSize.X, 40), math.max(svBox.AbsoluteSize.Y, 40)
svDot.Position = UDim2.fromScale((10 + sat * (aw - 20)) / aw, (10 + (1 - val) * (ah - 20)) / ah)
svDot.BackgroundColor3 = c
local hh = math.max(hueBar.AbsoluteSize.Y, 32)
hueDot.Position = UDim2.fromScale(.5, (8 + h * (hh - 16)) / hh)
hexLbl.Text = string.format("#%02X%02X%02X", math.floor(c.R * 255 + .5), math.floor(c.G * 255 + .5), math.floor(c.B * 255 + .5))
return c
end
refresh()
task.defer(function() task.wait(.1); pcall(refresh) end)
local inset = game:GetService("GuiService"):GetGuiInset()
local dragging, calib, scrollHold = nil, Vector2.zero, nil
local function upd(inp)
local p = Vector2.new(inp.Position.X, inp.Position.Y) + calib
if dragging == "sv" then
sat = math.clamp((p.X - svBox.AbsolutePosition.X - 10) / math.max(svBox.AbsoluteSize.X - 20, 1), 0, 1)
val = 1 - math.clamp((p.Y - svBox.AbsolutePosition.Y - 10) / math.max(svBox.AbsoluteSize.Y - 20, 1), 0, 1)
elseif dragging == "hue" then
h = math.clamp((p.Y - hueBar.AbsolutePosition.Y - 8) / math.max(hueBar.AbsoluteSize.Y - 16, 1), 0, .999)
end
refresh()
end
local function hook(btnParent, kind)
local btn = new("TextButton", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Text = "", ZIndex = 6, Parent = btnParent})
btn.InputBegan:Connect(function(inp)
if inp.UserInputType == Enum.UserInputType.MouseButton1 or inp.UserInputType == Enum.UserInputType.Touch then
local rawP = Vector2.new(inp.Position.X, inp.Position.Y)
local function inside(q) local a, z = btn.AbsolutePosition, btn.AbsoluteSize; return q.X >= a.X and q.Y >= a.Y and q.X <= a.X + z.X and q.Y <= a.Y + z.Y end
local first = Vector2.zero
local second = inset
if inside(rawP + first) then calib = first elseif inside(rawP + second) then calib = second else calib = first end
scrollHold = btn:FindFirstAncestorWhichIsA("ScrollingFrame")
if scrollHold then scrollHold.ScrollingEnabled = false end
dragging = kind; upd(inp)
end
end)
end
hook(svBox, "sv"); hook(hueBar, "hue")
UIS.InputChanged:Connect(function(inp)
if dragging and (inp.UserInputType == Enum.UserInputType.MouseMovement or inp.UserInputType == Enum.UserInputType.Touch) then upd(inp) end
end)
UIS.InputEnded:Connect(function(inp)
if dragging and (inp.UserInputType == Enum.UserInputType.MouseButton1 or inp.UserInputType == Enum.UserInputType.Touch) then
dragging = nil
if scrollHold then scrollHold.ScrollingEnabled = true; scrollHold = nil end
onCommit(Color3.fromHSV(h, sat, val))
end
end)
return card
end
local themeCards = {}
local function buildThemes(pane)
local sc = scroller(pane, {}, {pad(14), vlist(8)})
heading(sc, "Appearance", "Choose how Hyundax IUM looks", "sparkle", 1)
local order = T.THEME_ORDER
local ROW = 50
local baseDesc = {["Hyundax IUM Primary"] = "The original black, red, blue and yellow look.", Darkness = "Pure-black surfaces with red accents.", Lite = "A clean, bright white interface.", Mint = "Deep green surfaces with mint highlights.", Ocean = "Midnight blue with cool blue accents."}
local header = new("TextButton", {Size = UDim2.new(1, 0, 0, 46), BackgroundColor3 = T.cardTop, AutoButtonColor = false, Text = "", LayoutOrder = 2, Parent = sc}, {round(11), stroke(T.line)})
local hSw = new("Frame", {Position = UDim2.fromOffset(12, 17), Size = UDim2.fromOffset(78, 12), BackgroundTransparency = 1, Parent = header}, {hlist(4)})
local hName = text(header, "Ready-made themes", 12, "Bold", T.text, {Position = UDim2.fromOffset(104, 8), Size = UDim2.new(1, -150, 0, 16)})
local hDesc = text(header, "", 10, "Regular", T.muted, {Position = UDim2.fromOffset(104, 25), Size = UDim2.new(1, -150, 0, 13)})
local arrow = text(header, "v", 12, "Bold", T.gold, {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -14, .5, 0), Size = UDim2.fromOffset(16, 16), TextXAlignment = Enum.TextXAlignment.Center, NoI18N = true})
pressFx(header, .98)
local listH = math.min((#order - 1) * (ROW + 4), 5 * (ROW + 4))
local list = new("Frame", {Size = UDim2.new(1, 0, 0, 0), BackgroundTransparency = 1, ClipsDescendants = true, Visible = false, LayoutOrder = 3, Parent = sc})
local ls = scroller(list, {ScrollBarThickness = 3}, {vlist(4), pad(0, 0, 4, 0)})
local rows = {}
local function paintHeader()
local pal = T.UI_THEMES[cfg.theme] or T.UI_THEMES["Hyundax IUM Primary"]
for _, c in ipairs(hSw:GetChildren()) do if c:IsA("Frame") then c:Destroy() end end
for _, c in ipairs({pal.bg, pal.panel, pal.panel2, pal.bronze, pal.gold}) do
new("Frame", {Size = UDim2.fromOffset(12, 12), BackgroundColor3 = c, BorderSizePixel = 0, Parent = hSw}, {round(6), stroke(pal.line, 1)})
end
hDesc.Text = (cfg.theme == "Custom") and "Tap to pick a ready-made theme" or cfg.theme
for name, r in pairs(rows) do
local active = name == cfg.theme
r.status.Text = active and "ACTIVE" or ""
r.row.BackgroundColor3 = active and T.panel2 or T.cardTop
end
end
local open = false
local function setOpen(v)
open = v
arrow.Text = v and "^" or "v"
if v then
list.Visible = true
tween(list, {Size = UDim2.new(1, 0, 0, listH)}, .22)
else
tween(list, {Size = UDim2.new(1, 0, 0, 0)}, .18)
task.delay(.2, function() if not open then list.Visible = false end end)
end
end
header.Activated:Connect(function() setOpen(not open) end)
for i, themeName in ipairs(order) do
if themeName == "Custom" then continue end
local pal = T.UI_THEMES[themeName]
local row = new("TextButton", {Size = UDim2.new(1, 0, 0, ROW), BackgroundColor3 = T.cardTop, AutoButtonColor = false, Text = "", LayoutOrder = i, Parent = ls}, {round(9), stroke(T.line)})
local sw = new("Frame", {Position = UDim2.fromOffset(10, 19), Size = UDim2.fromOffset(78, 12), BackgroundTransparency = 1, Parent = row}, {hlist(4)})
for _, c in ipairs({pal.bg, pal.panel, pal.panel2, pal.bronze, pal.gold}) do
new("Frame", {Size = UDim2.fromOffset(12, 12), BackgroundColor3 = c, BorderSizePixel = 0, Parent = sw}, {round(6), stroke(pal.line, 1)})
end
text(row, themeName, 12, "Bold", T.text, {Position = UDim2.fromOffset(100, 7), Size = UDim2.new(1, -190, 0, 16), NoI18N = true})
text(row, T.THEME_DESC[themeName] or baseDesc[themeName] or "", 9, "Regular", T.muted, {Position = UDim2.fromOffset(100, 25), Size = UDim2.new(1, -190, 0, 20), TextWrapped = true, TextYAlignment = Enum.TextYAlignment.Top})
local status = text(row, "", 9, "Bold", T.gold, {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -12, .5, 0), Size = UDim2.fromOffset(70, 14), TextXAlignment = Enum.TextXAlignment.Right})
rows[themeName] = {status = status, row = row}
row.Activated:Connect(function()
setTheme(themeName)
paintHeader()
setOpen(false)
toast("Theme: " .. themeName)
end)
end
paintHeader()
text(sc, "Custom palette", 13, "Bold", T.text, {LayoutOrder = 5, Size = UDim2.new(1, 0, 0, 20)})
text(sc, "Drag the dot to choose a color. Press Apply to use it.", 10, "Regular", T.muted, {LayoutOrder = 6, Size = UDim2.new(1, 0, 0, 14)})
local pendBg, pendAcc = T.CUSTOM_BG, T.CUSTOM_ACC
local prev = new("Frame", {Size = UDim2.new(1, 0, 0, 22), BackgroundTransparency = 1, LayoutOrder = 9, Parent = sc}, {hlist(4)})
local function paintPrev()
for _, c in ipairs(prev:GetChildren()) do if c:IsA("Frame") then c:Destroy() end end
local pp = T.mkCustom(pendBg, pendAcc)
for _, c in ipairs({pp.bg, pp.side, pp.panel, pp.panel2, pp.line, pp.text, pp.bronze, pp.bronzeHi, pp.gold}) do
new("Frame", {Name = "NoThemePick", Size = UDim2.fromOffset(22, 22), BackgroundColor3 = c, BorderSizePixel = 0, Parent = prev}, {round(6), new("UIStroke", {Color = Color3.fromRGB(128, 128, 128), Thickness = 1})})
end
end
paintPrev()
T.makePicker(sc, "Background color", pendBg, 7, function(c) pendBg = c; paintPrev() end)
T.makePicker(sc, "Accent color", pendAcc, 8, function(c) pendAcc = c; paintPrev() end)
local btns = new("Frame", {Size = UDim2.new(1, 0, 0, 34), BackgroundTransparency = 1, LayoutOrder = 10, Parent = sc}, {hlist(8)})
local applyBtn = new("TextButton", {Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.bronze, AutoButtonColor = false, Text = "Apply", TextSize = 12, FontFace = F.Bold, TextColor3 = T.dark, LayoutOrder = 1, Parent = btns}, {round(8)})
pressFx(applyBtn, .95)
applyBtn.Activated:Connect(function()
T.CUSTOM_BG, T.CUSTOM_ACC = pendBg, pendAcc
T.UI_THEMES["Custom"] = T.mkCustom(pendBg, pendAcc)
local function arr(c) return {math.floor(c.R * 255 + .5), math.floor(c.G * 255 + .5), math.floor(c.B * 255 + .5)} end
cfg.customBg, cfg.customAccent = arr(pendBg), arr(pendAcc)
task.spawn(function()
setTheme("Custom")
paintHeader()
toast("Custom theme applied")
end)
end)
end
FX.SECTION_META = {
interface = {"Interface", "Look and behavior of the window", "cube"},
editor = {"Editor", "Editor and console preferences", "code"},
profile = {"Profile", "Language, nickname and account", "user"},
advanced = {"Advanced", "Diagnostics and maintenance", "cpu"},
look = {"Visual", "Transparency, size, corners and effects", "sparkle"},
fonts = {"Fonts", "Typeface, weight and text size", "file"},
window = {"Window", "Position, size, open behavior and title bar", "cube"},
notify = {"Notifications", "Pop-up notices and their timing", "bolt"},
sound = {"Sound", "Volume and interface sounds", "play"},
behavior = {"Behavior", "Running, saving and startup options", "gear"},
privacy = {"Privacy", "Hide personal and game details", "user"},
}
function HX.resetAll()
for k in pairs(cfg) do cfg[k] = nil end
for k, v in pairs(defaults) do cfg[k] = v end
cfg.cfgVer = 2
cfg.animSlow = HX.SPEC.animSlow.def
cfg.theme = "Hyundax IUM Primary"
HX.fill()
pcall(function()
T.CUSTOM_BG, T.CUSTOM_ACC = Color3.fromRGB(24, 20, 40), Color3.fromRGB(230, 50, 60)
T.UI_THEMES["Custom"] = T.mkCustom(T.CUSTOM_BG, T.CUSTOM_ACC)
end)
HX.lookActive = true
S.dimmed = false
tween(mainVeil, {BackgroundTransparency = 1}, .2)
if state.max then S.toggleMax() else tween(root, {Position = UDim2.fromScale(.5, .5)}, .45) end
applyCfg()
saveCfg()
if T.ACTIVE_THEME ~= "Hyundax IUM Primary" then
FX.accTheme = "Hyundax IUM Primary"
task.spawn(function() pcall(setTheme, "Hyundax IUM Primary") end)
end
task.defer(function()
for which, pane in pairs(HX.built or {}) do
if pane and pane.Parent and HX.build then
for _, c in ipairs(pane:GetChildren()) do c:Destroy() end
pcall(HX.build, pane, which)
end
end
toast("Settings reset to default")
end)
end
local function buildSettings(pane, which)
HX.build = buildSettings
HX.built = HX.built or {}
HX.built[which] = pane
local sc = scroller(pane, {}, {pad(14), vlist(8)})
local meta = FX.SECTION_META[which]
heading(sc, meta[1], meta[2], meta[3], 1)
local function show(g) return g == which end
local function fmtVal(spec, v)
local s
if spec.step < 1 then s = string.format(spec.step < .1 and "%.2f" or "%.1f", v) else s = tostring(math.floor(v + .5)) end
return s .. (spec.unit or "")
end
local function parseVal(spec, str)
local n = tonumber(tostring(str):gsub(",", "."):match("-?%d*%.?%d+"))
if not n then return nil end
n = math.floor(math.clamp(n, spec.min, spec.max) / spec.step + .5) * spec.step
return math.clamp(n, spec.min, spec.max)
end
local function verbose(key, v)
if cfg.verboseDiagnostics then addLine("Console", "[settings] " .. key .. " = " .. tostring(v), T.muted) end
end
local function sliderRow(order, title, desc, key, spec)
local r = panelRow(sc, title, desc, order, 64, 150)
local function cur() return tonumber(cfg[key]) or spec.def end
local box = new("TextBox", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -10, 0, 8), Size = UDim2.fromOffset(74, 22),
BackgroundColor3 = T.panel2, BorderSizePixel = 0, Text = fmtVal(spec, cur()), TextColor3 = T.text, TextSize = 10,
FontFace = F.SemiBold, ClearTextOnFocus = false, PlaceholderText = "...", PlaceholderColor3 = T.muted, Parent = r,
}, {round(6), stroke(T.line), pad(4, 0, 4, 0)})
box:SetAttribute("NoI18N", true)
local rst = new("TextButton", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -90, 0, 8), Size = UDim2.fromOffset(22, 22),
BackgroundColor3 = T.panel2, AutoButtonColor = false, Text = "", Glass = true, Parent = r,
}, {round(6), stroke(T.line)})
local okIc = pcall(function()
local ic = icon(rst, "undo", 12, T.muted, 1.4)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
end)
if not okIc then rst.Text = "R" rst.TextSize = 10 rst.FontFace = F.Bold rst.TextColor3 = T.muted end
local hit = new("TextButton", {
Position = UDim2.new(0, 14, 1, -26), Size = UDim2.new(1, -28, 0, 22), BackgroundTransparency = 1, Text = "", AutoButtonColor = false, Parent = r,
})
local rail = new("Frame", {
AnchorPoint = Vector2.new(0, .5), Position = UDim2.fromScale(0, .5), Size = UDim2.new(1, 0, 0, 6),
BackgroundColor3 = T.panel2, BorderSizePixel = 0, Parent = hit,
}, {round(3), stroke(T.line)})
local fill = new("Frame", {Size = UDim2.fromScale(0, 1), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = rail}, {round(3)})
local knob = new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(0, .5), Size = UDim2.fromOffset(16, 16),
BackgroundColor3 = T.text, BorderSizePixel = 0, ZIndex = 3, Parent = hit,
}, {round(8), stroke(T.bronzeHi, 1.5)})
local function paint(v, animate)
local f = math.clamp((v - spec.min) / math.max(spec.max - spec.min, 1e-6), 0, 1)
if animate then
tween(fill, {Size = UDim2.fromScale(f, 1)}, .15)
tween(knob, {Position = UDim2.fromScale(f, .5)}, .15)
else
fill.Size = UDim2.fromScale(f, 1)
knob.Position = UDim2.fromScale(f, .5)
end
box.Text = fmtVal(spec, v)
end
paint(cur())
local dragging, lastApply, scrollHold = false, 0, nil
local function setFromX(x)
local w = math.max(hit.AbsoluteSize.X, 1)
local f = math.clamp((x - hit.AbsolutePosition.X) / w, 0, 1)
local v = spec.min + f * (spec.max - spec.min)
v = math.clamp(math.floor(v / spec.step + .5) * spec.step, spec.min, spec.max)
if cfg[key] ~= v then
cfg[key] = v
paint(v)
local now = os.clock()
if now - lastApply > .12 then lastApply = now applyCfg() end
end
end
hit.InputBegan:Connect(function(inp)
if inp.UserInputType == Enum.UserInputType.MouseButton1 or inp.UserInputType == Enum.UserInputType.Touch then
dragging = true
scrollHold = hit:FindFirstAncestorWhichIsA("ScrollingFrame")
if scrollHold then scrollHold.ScrollingEnabled = false end
tween(knob, {Size = UDim2.fromOffset(20, 20)}, .12)
setFromX(inp.Position.X)
end
end)
local c1 = UIS.InputChanged:Connect(function(inp)
if dragging and (inp.UserInputType == Enum.UserInputType.MouseMovement or inp.UserInputType == Enum.UserInputType.Touch) then setFromX(inp.Position.X) end
end)
local c2 = UIS.InputEnded:Connect(function(inp)
if dragging and (inp.UserInputType == Enum.UserInputType.MouseButton1 or inp.UserInputType == Enum.UserInputType.Touch) then
dragging = false
if scrollHold then scrollHold.ScrollingEnabled = true scrollHold = nil end
tween(knob, {Size = UDim2.fromOffset(16, 16)}, .3, Enum.EasingStyle.Back)
applyCfg()
saveCfg()
verbose(key, cfg[key])
end
end)
r.AncestryChanged:Connect(function(_, p)
if not p then c1:Disconnect() c2:Disconnect() if scrollHold then scrollHold.ScrollingEnabled = true end end
end)
box.FocusLost:Connect(function()
local v = parseVal(spec, box.Text)
if v == nil then paint(cur()) toast("Invalid value") return end
cfg[key] = v
paint(v, true)
applyCfg()
saveCfg()
verbose(key, v)
end)
rst.Activated:Connect(function()
FX.snd("click")
cfg[key] = spec.def
paint(spec.def, true)
applyCfg()
saveCfg()
verbose(key, spec.def)
end)
end
local function textRow(order, title, desc, key, spec)
local r = panelRow(sc, title, desc, order, 50, 220)
local bx = btnBox(r, 190)
local box = new("TextBox", {
Size = UDim2.fromOffset(136, 22), BackgroundColor3 = T.panel2, BorderSizePixel = 0, Text = tostring(cfg[key] or spec.def or ""),
PlaceholderText = spec.hint or "Type here...", PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 10,
FontFace = F.Medium, ClearTextOnFocus = false, LayoutOrder = 1, Parent = bx,
}, {round(5), stroke(T.line), pad(6, 0)})
box:SetAttribute("NoI18N", true)
local function commit()
local v = box.Text:match("^%s*(.-)%s*$")
if key == "fontFamily" then
local _, ok = HX.resolveFont(v)
if not ok then
box.Text = tostring(cfg[key] or "Default")
toast("Invalid font name")
return
end
if v == "" then v = "Default" end
end
cfg[key] = v
box.Text = v
applyCfg()
saveCfg()
verbose(key, v)
toast("Font applied")
end
mini(bx, "Apply", 44, true, commit).LayoutOrder = 2
box.FocusLost:Connect(function(enter) if enter then commit() end end)
end
local function toggleRow(order, title, desc, key)
local r = panelRow(sc, title, desc, order, 50, 80)
local on = cfg[key] and true or false
local track = new("TextButton", {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -12, .5, 0), Size = UDim2.fromOffset(42, 22),
BackgroundColor3 = on and T.bronze or T.panel2, AutoButtonColor = false, Text = "", Parent = r,
}, {round(11), stroke(on and T.bronzeHi or T.line)})
local knob = new("Frame", {
AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, on and 22 or 2, .5, 0), Size = UDim2.fromOffset(18, 18),
BackgroundColor3 = T.text, BorderSizePixel = 0, Parent = track,
}, {round(9)})
track.Activated:Connect(function()
on = not on
if key == "float" and not on and not UIS.KeyboardEnabled then
on = true
toast("Floating button can't be hidden without a keyboard")
return
end
cfg[key] = on
if cfg.verboseDiagnostics then addLine("Console", "[settings] " .. key .. " = " .. tostring(on), T.muted) end
FX.snd(on and "on" or "off")
knob.Size = UDim2.fromOffset(24, 16)
tween(knob, {Position = UDim2.new(0, on and 12 or 2, .5, 0)}, .12, Enum.EasingStyle.Quad)
task.delay(.1 * FX.scale, function()
if not knob.Parent then return end
tween(knob, {Size = UDim2.fromOffset(18, 18), Position = UDim2.new(0, on and 22 or 2, .5, 0)}, .5, Enum.EasingStyle.Back)
end)
tween(track:FindFirstChildOfClass("UIStroke"), {Color = on and T.bronzeHi or T.line}, .4)
tween(track, {BackgroundColor3 = on and T.bronze or T.panel2}, .4)
applyCfg()
saveCfg()
end)
end
if show("interface") then
sliderRow(2, "Animation speed", "How slow the interface animates", "animSlow", HX.SPEC.animSlow)
toggleRow(3, "Background waves", "Wavy lines and glowing dots behind the UI", "waves")
toggleRow(7, "Floating button", "Hide it and use RightShift to open", "float")
toggleRow(8, "Toast messages", "Small pop-up notices at the bottom", "toasts")
toggleRow(10, "Disable pill and line", "When enabled, closing hides the UI but keeps the toggle bubble", "disablePillLine")
toggleRow(20, "Compact interface", "Prefer denser spacing in interface panels", "compactInterface")
toggleRow(21, "Show section descriptions", "Keep helper descriptions visible in settings", "showDescriptions")
toggleRow(22, "Hover highlights", "Highlight buttons when the pointer passes over them", "hoverHighlights")
toggleRow(23, "Confirm destructive actions", "Ask for confirmation before destructive actions", "confirmDestructive")
toggleRow(24, "Sound feedback", "Enable optional UI sound feedback", "soundFeedback")
toggleRow(25, "Reduced motion", "Prefer less animated transitions", "reducedMotion")
toggleRow(26, "Extra contrast", "Prefer stronger contrast for interface elements", "extraContrast")
toggleRow(28, "Show keyboard hints", "Show a shortcut hint line at the bottom of the window", "keyboardHints")
end
if show("editor") then
toggleRow(4, "Line numbers", "Show the gutter in the editor", "lineNums")
toggleRow(5, "Word wrap", "Wrap long lines in the editor", "wrap")
toggleRow(6, "Console auto-scroll", "Follow new console lines", "autoscroll")
toggleRow(9, "Run AutoExec on load", "Run saved AutoExec scripts when Hyundax IUM starts", "autorun")
toggleRow(30, "Auto-indent", "Keep indentation when creating a new line", "editorAutoIndent")
toggleRow(31, "Highlight current line", "Highlight the line containing the cursor", "editorCurrentLine")
toggleRow(32, "Syntax color hints", "Enable syntax-color preference for the editor", "editorSyntaxHints")
toggleRow(34, "Warn before clearing code", "Ask before clearing editor contents", "editorClearConfirm")
toggleRow(36, "Keep console timestamps", "Include timestamps in new console entries", "consoleTimestamps")
toggleRow(37, "Color console errors", "Emphasize errors in console output", "consoleErrorColors")
toggleRow(38, "Auto-close brackets", "Automatically close paired brackets when supported", "editorAutoBrackets")
toggleRow(39, "Editor focus on open", "Focus the editor when its page opens", "editorFocusOnOpen")
end
local function guard(msg, fn)
return function()
if cfg.confirmDestructive then S.confirm(msg, fn) else fn() end
end
end
local function choiceRow(order, title, desc, key, opts)
local r = panelRow(sc, title, desc, order, 50, 150)
local bx = btnBox(r, 124)
local b
b = mini(bx, opts[cfg[key]] or opts[1], 120, false, function()
cfg[key] = ((tonumber(cfg[key]) or 1) % #opts) + 1
b.Text = opts[cfg[key]]
FX.snd("click")
if cfg.verboseDiagnostics then addLine("Console", "[settings] " .. key .. " = " .. tostring(opts[cfg[key]]), T.muted) end
applyCfg()
saveCfg()
end)
end
if HX.EXTRA[which] then
for i, row in ipairs(HX.EXTRA[which]) do
if row[1] == "t" then toggleRow(100 + i, row[3], row[4], row[2])
elseif row[1] == "s" then sliderRow(100 + i, row[3], row[4], row[2], row)
elseif row[1] == "x" then textRow(100 + i, row[3], row[4], row[2], row)
else choiceRow(100 + i, row[3], row[4], row[2], row[5]) end
end
end
local function actionRow(order, title, desc, label, primary, fn, danger)
local r = panelRow(sc, title, desc, order, 50, 120)
local bx = btnBox(r, 84)
local b = mini(bx, label, 76, primary, fn)
if danger then
local red, redHi = Color3.fromRGB(214, 48, 49), Color3.fromRGB(240, 84, 84)
b.BackgroundColor3, b.TextColor3 = red, Color3.new(1, 1, 1)
local bs = b:FindFirstChildOfClass("UIStroke")
if bs then bs.Color = redHi end
b.MouseEnter:Connect(function() tween(b, {BackgroundColor3 = redHi}, .15) end)
b.MouseLeave:Connect(function() tween(b, {BackgroundColor3 = red}, .2) end)
b.MouseButton1Up:Connect(function() b.BackgroundColor3 = red end)
end
return b
end
if which == "interface" or which == "advanced" then
actionRow(which == "advanced" and 16 or 400, "Reset all settings", "Put every setting, the theme and the window back to the default Hyundax IUM", "Reset", false, function()
S.confirm("Reset ALL settings to default?", HX.resetAll)
end, true)
end
if which == "behavior" then
local function resetGroups(list)
for _, g in ipairs(list) do for _, row in ipairs(HX.EXTRA[g]) do cfg[row[2]] = row.def end end
if table.find(list, "look") then cfg.animSlow = HX.SPEC.animSlow.def end
saveCfg()
applyCfg()
end
actionRow(300, "Reset visual settings", "Restore Visual, Fonts and Window options", "Reset", false, guard("Reset Visual, Fonts and Window settings?", function()
resetGroups({"look", "fonts", "window"})
toast("Visual settings reset, reopen the tab")
end))
actionRow(301, "Reset all new settings", "Restore every option from the extra tabs", "Reset", false, guard("Reset all settings from the extra tabs?", function()
resetGroups(HX.EXTRA_ORDER)
toast("Settings reset, reopen the tab")
end), true)
actionRow(302, "Copy settings", "Copy your settings as JSON", "Copy", false, function()
local ok = pcall(function() setclipboard(HttpService:JSONEncode(cfg)) end)
toast(ok and "Settings copied" or "setclipboard unavailable")
end)
end
if show("advanced") then
actionRow(11, "Clear console", "Remove every line from the console", "Clear", false, guard("Clear the console?", function()
LOG.clear()
toast("Console cleared")
end))
actionRow(12, "Copy debug info", "Executor, game and version for bug reports", "Copy", false, function()
local ex = "Unknown"
pcall(function() ex = tostring((identifyexecutor())) end)
local parts = {NAME .. " " .. VERSION}
if not cfg.hideExecutor then parts[#parts + 1] = "executor: " .. ex end
if not cfg.hidePlaceId then parts[#parts + 1] = "place: " .. game.PlaceId end
if not cfg.hideJobId then parts[#parts + 1] = "job: " .. game.JobId end
local info = table.concat(parts, " | ")
local function doCopy()
local ok = pcall(setclipboard, info)
toast(ok and "Debug info copied" or "setclipboard unavailable")
end
if cfg.confirmCopyInfo then S.confirm("Copy debug info to the clipboard?", doCopy) else doCopy() end
end)
actionRow(13, "Run sUNC tests", "Check which executor functions work", "Run", true, function()
if Compat.running then toast("Tests already running") return end
task.spawn(Compat.run)
toast("Tests started, see Home > sUNC")
end)
actionRow(14, "Reset statistics", "Zero the total and error counters", "Reset", false, guard("Reset the run statistics?", function()
Stats.total, Stats.errors = 0, 0
saveStats(true)
if Stats.refresh then Stats.refresh() end
toast("Statistics reset")
end))
toggleRow(50, "Verbose diagnostics", "Print every setting change in the console", "verboseDiagnostics")
toggleRow(55, "Show memory diagnostics", "Show memory diagnostics when available", "memoryDiagnostics")
toggleRow(59, "Detailed error notices", "Prefer more detailed error notices", "detailedErrorNotices")
end
if show("profile") then
do
local lr = panelRow(sc, "Language", "Choose the interface language", 15, 76, 160)
local chooseLang = new("TextButton", {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -10, .5, 0), Size = UDim2.fromOffset(146, 30),
BackgroundColor3 = T.panel2, AutoButtonColor = false, Text = "", Parent = lr,
}, {round(8), stroke(T.line)})
local chooseFlag = I18N.flag(chooseLang, I18N.lang, 24, 16, UDim2.new(0, 8, .5, -8), 3)
local chooseName = text(chooseLang, "English", 10, "Bold", T.text, {Position = UDim2.fromOffset(38, 0), Size = UDim2.new(1, -58, 1, 0), TextXAlignment = Enum.TextXAlignment.Left})
local chooseChevron = icon(chooseLang, "chevD", 10, T.muted, 1.4)
chooseChevron.holder.AnchorPoint, chooseChevron.holder.Position = Vector2.new(1, .5), UDim2.new(1, -8, .5, 0)
local function paintCurrentLanguage()
local found
for _, language in ipairs(I18N.LANGS) do if language.code == I18N.lang then found = language break end end
if found then
chooseName.Text = found.name
chooseFlag:Destroy()
chooseFlag = I18N.flag(chooseLang, found.code, 24, 16, UDim2.new(0, 8, .5, -8), 3)
end
end
local function openLanguagePopup()
local p = FX.popup({
name = "HyundaxIUMLanguagePopup", z = 400, w = 420, h = 322,
title = "Choose language", subtitle = "Select the language used by Hyundax IUM", icon = "globe", footer = true,
})
local grid = scroller(p.body, {ScrollBarThickness = 2}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -6, 0, 46), CellPadding = UDim2.fromOffset(10, 8), SortOrder = Enum.SortOrder.LayoutOrder}),
pad(14, 14, 14, 14),
})
text(p.footer, "Current language", 10, "SemiBold", T.muted, {Size = UDim2.new(.5, 0, 1, 0)})
local currentValue = text(p.footer, I18N.langName(I18N.lang) or "English", 10, "Bold", T.text, {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.fromScale(1, 0), Size = UDim2.new(.5, 0, 1, 0),
TextXAlignment = Enum.TextXAlignment.Right, NoI18N = true,
})
local choices = {}
local function paintChoices()
for code, item in pairs(choices) do
local active = code == I18N.lang
item.button.BackgroundColor3 = active and T.bronze or T.panel2
item.stroke.Color = active and T.bronzeHi or T.line
item.check.Visible = active
end
end
for i, language in ipairs(I18N.LANGS) do
local b = new("TextButton", {BackgroundColor3 = language.code == I18N.lang and T.bronze or T.panel2, AutoButtonColor = false, Text = "", LayoutOrder = i, Parent = grid}, {round(10)})
local st = stroke(language.code == I18N.lang and T.bronzeHi or T.line, 1); st.Parent = b
I18N.flag(b, language.code, 30, 20, UDim2.new(0, 10, .5, -10), 3)
text(b, language.name, 10, "SemiBold", T.text, {Position = UDim2.fromOffset(50, 0), Size = UDim2.new(1, -74, 1, 0), TextXAlignment = Enum.TextXAlignment.Left, ZIndex = 3, NoI18N = true})
local check = icon(b, "check", 12, T.text, 1.7)
check.holder.AnchorPoint, check.holder.Position, check.holder.ZIndex = Vector2.new(1, .5), UDim2.new(1, -10, .5, 0), 3
choices[language.code] = {button = b, stroke = st, check = check.holder}
hoverFx(b, language.code == I18N.lang and T.bronze or T.panel2, T.line)
b.Activated:Connect(function()
I18N.set(language.code)
I18N.save()
paintChoices()
paintCurrentLanguage()
toast("Language changed")
currentValue.Text = language.name
task.delay(.12, p.close)
end)
end
paintChoices()
end
chooseLang.Activated:Connect(openLanguagePopup)
paintCurrentLanguage()
local nr = panelRow(sc, "Nickname", "How Hyundax IUM calls you (optional)", 16, 50, 190)
local nb = btnBox(nr, 150)
local nbox = new("TextBox", {
Size = UDim2.fromOffset(100, 22), BackgroundColor3 = T.panel2, BorderSizePixel = 0, Text = I18N.nick,
PlaceholderText = "Type a nickname...", PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 10,
FontFace = F.Medium, ClearTextOnFocus = false, LayoutOrder = 1, Parent = nb,
}, {round(5), stroke(T.line), pad(6, 0)})
mini(nb, "Save", 44, true, function()
I18N.setNick(nbox.Text)
nbox.Text = I18N.nick
toast("Nickname saved")
end).LayoutOrder = 2
toggleRow(43, "Show welcome tips", "Show helpful tips when opening Hyundax IUM", "profileWelcomeTips")
toggleRow(49, "Show nickname in header", "Display your nickname in the header when supported", "profileNicknameHeader")
end
actionRow(17, "Sign out", "Log out and return to the login screen", "Sign out", false, guard("Sign out of your account?", function()
I18N.user = nil
I18N.save()
gui.Enabled = false
task.spawn(function()
pcall(I18N.login)
pcall(FX.accSync)
gui.Enabled = true
end)
end), true)
end
end
local SNIPPETS = {
{"Hello World", "Prints a message to the console", [==[print("Hello from Hyundax IUM!")]==]},
{"Player List", "Lists every player in the server", [==[for _, p in ipairs(game:GetService("Players"):GetPlayers()) do
print(p.Name, p.UserId)
end]==]},
{"Speed & Jump", "WalkSpeed 50 and JumpPower 80", [==[local lp = game:GetService("Players").LocalPlayer
local hum = lp.Character and lp.Character:FindFirstChildOfClass("Humanoid")
if hum then
hum.WalkSpeed = 50
hum.JumpPower = 80
end]==]},
{"Infinite Jump", "Jump again while in the air", [==[local UIS = game:GetService("UserInputService")
local lp = game:GetService("Players").LocalPlayer
UIS.JumpRequest:Connect(function()
local hum = lp.Character and lp.Character:FindFirstChildOfClass("Humanoid")
if hum then hum:ChangeState(Enum.HumanoidStateType.Jumping) end
end)]==]},
{"Anti-AFK", "Stops the idle kick", [==[local vu = game:GetService("VirtualUser")
game:GetService("Players").LocalPlayer.Idled:Connect(function()
vu:CaptureController()
vu:ClickButton2(Vector2.new())
end)]==]},
{"Fullbright", "Removes darkness and fog", [==[local l = game:GetService("Lighting")
l.Brightness = 2
l.ClockTime = 14
l.FogEnd = 1e6
l.GlobalShadows = false
l.Ambient = Color3.new(1, 1, 1)]==]},
{"Reset Character", "Respawns your character", [==[local lp = game:GetService("Players").LocalPlayer
local hum = lp.Character and lp.Character:FindFirstChildOfClass("Humanoid")
if hum then hum.Health = 0 end]==]},
{"Noclip", "Walk through walls", [==[game:GetService("RunService").Stepped:Connect(function()
local c = game:GetService("Players").LocalPlayer.Character
if not c then return end
for _, p in ipairs(c:GetDescendants()) do
if p:IsA("BasePart") then p.CanCollide = false end
end
end)]==]},
{"Rejoin", "Reconnects to this server", [==[local TS = game:GetService("TeleportService")
local lp = game:GetService("Players").LocalPlayer
TS:TeleportToPlaceInstance(game.PlaceId, game.JobId, lp)]==]},
{"Server Hop", "Joins another public server", [==[local HS = game:GetService("HttpService")
local res = HS:JSONDecode(game:HttpGet("https://games.roblox.com/v1/games/" .. game.PlaceId .. "/servers/Public?sortOrder=Asc&limit=100"))
for _, s in ipairs(res.data) do
if s.id ~= game.JobId and s.playing < s.maxPlayers then
game:GetService("TeleportService"):TeleportToPlaceInstance(game.PlaceId, s.id, game:GetService("Players").LocalPlayer)
break
end
end]==]},
{"Spin", "Spins your character", [==[local root = game:GetService("Players").LocalPlayer.Character:WaitForChild("HumanoidRootPart")
local av = Instance.new("BodyAngularVelocity")
av.MaxTorque = Vector3.new(0, 1e6, 0)
av.AngularVelocity = Vector3.new(0, 20, 0)
av.Parent = root]==]},
{"Day Time", "Sets the clock to noon", [==[local l = game:GetService("Lighting")
l.ClockTime = 12
l.Brightness = 2]==]},
{"Remove Fog", "Clears distance fog", [==[local l = game:GetService("Lighting")
l.FogEnd = 1e6
for _, a in ipairs(l:GetChildren()) do
if a:IsA("Atmosphere") then a.Density = 0 end
end]==]},
{"FPS Boost", "Less shadows and effects", [==[game:GetService("Lighting").GlobalShadows = false
for _, d in ipairs(workspace:GetDescendants()) do
if d:IsA("ParticleEmitter") or d:IsA("Trail") or d:IsA("Fire") or d:IsA("Smoke") then
d.Enabled = false
end
end]==]},
{"Click Teleport", "Tap anywhere to teleport there", [==[local lp = game:GetService("Players").LocalPlayer
local mouse = lp:GetMouse()
mouse.Button1Down:Connect(function()
if mouse.Hit and lp.Character then
lp.Character:PivotTo(CFrame.new(mouse.Hit.Position + Vector3.new(0, 4, 0)))
end
end)]==]},
{"Teleport To Player", "Edit the name and run", [==[local name = "PlayerName"
for _, p in ipairs(game:GetService("Players"):GetPlayers()) do
if p.Name:lower():sub(1, #name) == name:lower() and p.Character then
game:GetService("Players").LocalPlayer.Character:PivotTo(p.Character:GetPivot())
break
end
end]==]},
{"List Remotes", "Prints every RemoteEvent/Function", [==[for _, d in ipairs(game:GetDescendants()) do
if d:IsA("RemoteEvent") or d:IsA("RemoteFunction") then
print(d.ClassName, d:GetFullName())
end
end]==]},
{"Copy Place Info", "Copies PlaceId and JobId", [==[setclipboard("PlaceId: " .. game.PlaceId .. "\nJobId: " .. game.JobId)
print("Copied place info")]==]},
}
local CAT_OF = {
["Hello World"] = "Dev", ["Player List"] = "Server", ["Speed & Jump"] = "Movement", ["Infinite Jump"] = "Movement",
["Anti-AFK"] = "Utility", ["Fullbright"] = "Visual", ["Reset Character"] = "Utility", ["Noclip"] = "Movement",
["Rejoin"] = "Server", ["Server Hop"] = "Server", ["Spin"] = "Movement", ["Day Time"] = "Visual",
["Remove Fog"] = "Visual", ["FPS Boost"] = "Visual", ["Click Teleport"] = "Movement",
["Teleport To Player"] = "Movement", ["List Remotes"] = "Dev", ["Copy Place Info"] = "Dev",
}
local CAT_COLOR = {
Movement = Color3.fromRGB(255, 206, 48), Visual = Color3.fromRGB(66, 140, 255), Utility = Color3.fromRGB(255, 90, 90),
Server = Color3.fromRGB(46, 100, 200), Dev = Color3.fromRGB(206, 200, 190),
}
local function buildSnippets(pane)
local BAR_H = 46
local picked, cards, cat, query = {}, {}, "All", ""
local counter
local sc = scroller(pane, {Size = UDim2.new(1, 0, 1, -BAR_H)}, {pad(14), vlist(8)})
heading(sc, "Forge", "Tap modules to stack them into one script", "bolt", 1)
local search = new("TextBox", {
Size = UDim2.new(1, 0, 0, 28), BackgroundColor3 = T.panel, BorderSizePixel = 0, Text = "", PlaceholderText = "Search modules...",
PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 11, FontFace = F.Regular, TextXAlignment = Enum.TextXAlignment.Left,
ClearTextOnFocus = false, LayoutOrder = 2, Parent = sc,
}, {round(6), stroke(T.line), pad(10, 0)})
local chipRow = scroller(sc, {
Size = UDim2.new(1, 0, 0, 24), ScrollingDirection = Enum.ScrollingDirection.X, AutomaticCanvasSize = Enum.AutomaticSize.X,
CanvasSize = UDim2.new(), ScrollBarThickness = 0, LayoutOrder = 3,
}, {hlist(4)})
local grid = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 4, Parent = sc}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -4, 0, 72), CellPadding = UDim2.fromOffset(8, 8), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local bar = new("Frame", {AnchorPoint = Vector2.new(0, 1), Position = UDim2.new(0, 0, 1, 0), Size = UDim2.new(1, 0, 0, BAR_H), BackgroundColor3 = T.bg, BorderSizePixel = 0, Parent = pane})
new("Frame", {Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = bar})
counter = text(bar, "", 11, "Bold", T.text, {Position = UDim2.fromOffset(14, 0), Size = UDim2.new(1, -230, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd})
local acts = new("Frame", {AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -10, .5, 0), Size = UDim2.fromOffset(210, 26), BackgroundTransparency = 1, Parent = bar}, {hlist(4, nil, Enum.HorizontalAlignment.Right)})
local function combine()
local parts, n, lines = {}, 0, 0
for i, sn in ipairs(SNIPPETS) do
if picked[i] then
n += 1
parts[#parts + 1] = ("-- [%d] %s\ndo\n%s\nend\n"):format(n, sn[1], sn[3])
lines += select(2, sn[3]:gsub("\n", "")) + 1
end
end
if n == 0 then return nil, 0, 0 end
return ("-- Hyundax IUM Forge: %d module%s\n\n"):format(n, n == 1 and "" or "s") .. table.concat(parts, "\n"), n, lines
end
local function updateBar()
local _, n, lines = combine()
counter.Text = n == 0 and "No modules selected" or ("%d selected · %d lines"):format(n, lines)
counter.TextColor3 = n == 0 and T.muted or T.gold
end
local function clearPicks()
table.clear(picked)
for _, c in ipairs(cards) do c.paint() end
updateBar()
end
mini(acts, "Clear", 48, false, clearPicks).LayoutOrder = 1
mini(acts, "To Editor", 70, false, function()
local code, n = combine()
if not code then toast("Pick at least one module") return end
newTab("Forge x" .. n, code)
showPage("Editor")
picks.Editor(2)
toast("Forged " .. n .. " module" .. (n == 1 and "" or "s"))
end).LayoutOrder = 2
mini(acts, "Run all", 64, true, function()
local code, n = combine()
if not code then toast("Pick at least one module") return end
runCode(code, "Forge x" .. n)
end).LayoutOrder = 3
local function applyFilter()
for _, c in ipairs(cards) do
local okCat = (cat == "All") or (c.cat == cat)
local okQ = (query == "") or (c.key:find(query, 1, true) ~= nil)
c.frame.Visible = okCat and okQ
end
end
for i, sn in ipairs(SNIPPETS) do
local category = CAT_OF[sn[1]] or "Utility"
local color = CAT_COLOR[category] or T.tan
local card = new("TextButton", {
BackgroundColor3 = T.panel, AutoButtonColor = false, Text = "", LayoutOrder = i, Parent = grid,
}, {round(9), stroke(T.line)})
local st = card:FindFirstChildOfClass("UIStroke")
local accent = new("Frame", {Size = UDim2.new(0, 3, 1, -16), Position = UDim2.fromOffset(0, 8), BackgroundColor3 = T.gold, BorderSizePixel = 0, Visible = false, Parent = card}, {round(2)})
local title = text(card, sn[1], 12, "Bold", T.text, {Position = UDim2.fromOffset(12, 8), Size = UDim2.new(1, -46, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd})
text(card, sn[2], 9, "Regular", T.muted, {Position = UDim2.fromOffset(12, 27), Size = UDim2.new(1, -22, 0, 13), TextTruncate = Enum.TextTruncate.AtEnd})
local tag = new("TextLabel", {
Position = UDim2.new(0, 12, 1, -20), AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14),
BackgroundColor3 = color, BackgroundTransparency = .82, Text = category:upper(), TextSize = 8, FontFace = F.Bold,
TextColor3 = color, Parent = card,
}, {round(4), pad(6, 0)})
local lineN = select(2, sn[3]:gsub("\n", "")) + 1
text(card, lineN .. (lineN == 1 and " line" or " lines"), 9, "Medium", T.muted, {
AnchorPoint = Vector2.new(1, 1), Position = UDim2.new(1, -10, 1, -6), Size = UDim2.fromOffset(60, 14), TextXAlignment = Enum.TextXAlignment.Right,
})
local run = new("TextButton", {
AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -6, 0, 6), Size = UDim2.fromOffset(24, 22),
BackgroundColor3 = T.panel2, AutoButtonColor = false, Text = "", ZIndex = 3, Glass = true, Parent = card,
}, {round(6)})
local ri = icon(run, "play", 11, T.tan, 1.5)
ri.holder.AnchorPoint, ri.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
ri.holder.ZIndex = 4
pressFx(run, .88)
run.Activated:Connect(function() runCode(sn[3], sn[1]) end)
local entry = {frame = card, cat = category, key = (sn[1] .. " " .. sn[2] .. " " .. category):lower()}
function entry.paint()
local on = picked[i] and true or false
accent.Visible = on
tween(card, {BackgroundColor3 = on and T.panel2 or T.panel}, .25)
tween(st, {Color = on and T.gold or T.line}, .25)
tween(title, {TextColor3 = on and T.gold or T.text}, .25)
end
card.MouseEnter:Connect(function() if not picked[i] then tween(st, {Color = T.bronzeLo}, .2) end end)
card.MouseLeave:Connect(function() if not picked[i] then tween(st, {Color = T.line}, .25) end end)
card.Activated:Connect(function()
picked[i] = (not picked[i]) or nil
entry.paint()
updateBar()
end)
cards[#cards + 1] = entry
end
local chipObj = {}
local function paintChips()
for name, c in pairs(chipObj) do
local on = (name == cat)
tween(c.b, {BackgroundColor3 = on and T.bronze or T.panel2}, .3)
tween(c.l, {TextColor3 = on and T.text or T.muted}, .3)
end
end
for i, name in ipairs({"All", "Movement", "Visual", "Utility", "Server", "Dev"}) do
local b = new("TextButton", {
Size = UDim2.fromOffset(0, 22), AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = T.panel2, AutoButtonColor = false,
Text = "", LayoutOrder = i, Parent = chipRow,
}, {round(8), pad(10, 0), stroke(T.line)})
local l = text(b, name, 10, "SemiBold", T.muted, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 22)})
pressFx(b, .94)
chipObj[name] = {b = b, l = l}
b.Activated:Connect(function()
cat = name
paintChips()
applyFilter()
end)
end
paintChips()
search:GetPropertyChangedSignal("Text"):Connect(function()
query = search.Text:lower()
applyFilter()
end)
updateBar()
end
local function buildRadar(pane)
local RunService = game:GetService("RunService")
local CS = 180
local HALF = CS / 2
local range = 250
local sel, spectating, hlOn = nil, false, false
local dots, rows, dists = {}, {}, {}
local highlight
local sc = scroller(pane, {}, {pad(14), vlist(8)})
heading(sc, "Radar", "Live player radar: spectate, teleport and highlight", "user", 1)
local top = new("Frame", {Size = UDim2.new(1, 0, 0, CS + 14), BackgroundTransparency = 1, LayoutOrder = 2, Parent = sc})
local radar = new("Frame", {
Position = UDim2.fromOffset(2, 7), Size = UDim2.fromOffset(CS, CS), BackgroundColor3 = T.panel, BorderSizePixel = 0,
ClipsDescendants = true, Parent = top,
}, {new("UICorner", {CornerRadius = UDim.new(.5, 0)}), stroke(T.bronze, 1.4)})
for _, f in ipairs({.66, .33}) do
new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromScale(f, f),
BackgroundTransparency = 1, Parent = radar,
}, {new("UICorner", {CornerRadius = UDim.new(.5, 0)}), stroke(T.line, 1)})
end
new("Frame", {AnchorPoint = Vector2.new(.5, 0), Position = UDim2.fromScale(.5, 0), Size = UDim2.new(0, 1, 1, 0), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = radar})
new("Frame", {AnchorPoint = Vector2.new(0, .5), Position = UDim2.fromScale(0, .5), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line, BorderSizePixel = 0, Parent = radar})
text(radar, "FRONT", 8, "Bold", T.muted, {Position = UDim2.fromOffset(0, 5), Size = UDim2.new(1, 0, 0, 10), TextXAlignment = Enum.TextXAlignment.Center})
local sweep = new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.new(1, 0, 0, 2),
BackgroundColor3 = T.gold, BorderSizePixel = 0, Parent = radar,
}, {new("UIGradient", {Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, 1), NumberSequenceKeypoint.new(.5, .45), NumberSequenceKeypoint.new(1, 1)})})})
new("Frame", {
AnchorPoint = Vector2.new(.5, .5), Position = UDim2.fromScale(.5, .5), Size = UDim2.fromOffset(9, 9),
BackgroundColor3 = T.gold, BorderSizePixel = 0, ZIndex = 4, Parent = radar,
}, {new("UICorner", {CornerRadius = UDim.new(.5, 0)}), stroke(Color3.new(1, 1, 1), 1)})
local info = new("Frame", {
Position = UDim2.fromOffset(CS + 14, 7), Size = UDim2.new(1, -(CS + 16), 0, CS), BackgroundColor3 = T.panel, BorderSizePixel = 0, Parent = top,
}, {round(10), stroke(T.line), pad(10, 8), vlist(6)})
text(info, "RANGE", 9, "SemiBold", T.muted, {Size = UDim2.new(1, 0, 0, 12), LayoutOrder = 1})
local rangeRow = new("Frame", {Size = UDim2.new(1, 0, 0, 22), BackgroundTransparency = 1, LayoutOrder = 2, Parent = info}, {hlist(4)})
local rangeBtns = {}
local function paintRange()
for v, b in pairs(rangeBtns) do tween(b, {BackgroundColor3 = (v == range) and T.bronze or T.panel2}, .3) end
end
for i, v in ipairs({100, 250, 500, 1000}) do
local b = new("TextButton", {
Size = UDim2.fromOffset(44, 22), BackgroundColor3 = T.panel2, AutoButtonColor = false, Glass = true, Text = v >= 1000 and "1k" or tostring(v),
TextSize = 10, FontFace = F.SemiBold, TextColor3 = T.text, LayoutOrder = i, Parent = rangeRow,
}, {round(5), stroke(T.line)})
pressFx(b, .92)
rangeBtns[v] = b
b.Activated:Connect(function() range = v paintRange() end)
end
paintRange()
local infoLbl = new("TextLabel", {
BackgroundTransparency = 1, RichText = true, TextWrapped = true, Size = UDim2.new(1, 0, 0, 62), LayoutOrder = 3,
TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top, FontFace = F.SemiBold, TextSize = 11,
TextColor3 = T.text, Text = "", Parent = info,
})
local acts = new("Frame", {Size = UDim2.new(1, 0, 0, 54), BackgroundTransparency = 1, LayoutOrder = 4, Parent = info}, {
new("UIGridLayout", {CellSize = UDim2.new(.5, -3, 0, 24), CellPadding = UDim2.fromOffset(6, 6), SortOrder = Enum.SortOrder.LayoutOrder}),
})
local listLbl = text(sc, "PLAYERS", 10, "SemiBold", T.muted, {Size = UDim2.new(1, 0, 0, 14), LayoutOrder = 3})
local list = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 4, Parent = sc}, {vlist(6)})
local function rootOf(p) return p and p.Character and p.Character:FindFirstChild("HumanoidRootPart") end
local function humOf(p) return p and p.Character and p.Character:FindFirstChildOfClass("Humanoid") end
local function shown()
local o = pane
while o and o ~= gui do
if o:IsA("GuiObject") and not o.Visible then return false end
o = o.Parent
end
return o == gui
end
local specBtn, hlBtn
local function stopSpectate()
if spectating then
local h = humOf(lp)
if h then workspace.CurrentCamera.CameraSubject = h end
end
spectating = false
if specBtn then specBtn.Text = "Spectate" end
end
local function applyHighlight()
if highlight then highlight:Destroy() highlight = nil end
if hlOn and sel and sel.Character then
highlight = Instance.new("Highlight")
highlight.Adornee = sel.Character
highlight.FillColor = T.gold
highlight.FillTransparency = .65
highlight.OutlineColor = Color3.new(1, 1, 1)
highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
highlight.Parent = gui
end
if hlBtn then hlBtn.Text = hlOn and "Highlight: on" or "Highlight" end
end
local function paintSel()
for p, d in pairs(dots) do
local on = (p == sel)
d.BackgroundColor3 = on and T.gold or T.tan
d.Size = on and UDim2.fromOffset(11, 11) or UDim2.fromOffset(8, 8)
d.ZIndex = on and 5 or 3
end
for p, r in pairs(rows) do
local on = (p == sel)
tween(r.frame, {BackgroundColor3 = on and T.panel2 or T.panel}, .25)
tween(r.st, {Color = on and T.gold or T.line}, .25)
end
end
local function select(p)
sel = p
paintSel()
if spectating then
local h = humOf(p)
if h then workspace.CurrentCamera.CameraSubject = h else stopSpectate() end
end
applyHighlight()
end
local function need()
if not sel or not sel.Parent then toast("Tap a player first") return nil end
return sel
end
specBtn = mini(acts, "Spectate", 60, true, function()
local p = need()
if not p then return end
if spectating then stopSpectate() return end
local h = humOf(p)
if not h then toast("No character to watch") return end
workspace.CurrentCamera.CameraSubject = h
spectating = true
specBtn.Text = "Stop"
end)
specBtn.LayoutOrder = 1
mini(acts, "Teleport", 60, false, function()
local p = need()
if not p then return end
local r = rootOf(p)
local ok = r and pcall(function() lp.Character:PivotTo(r.CFrame * CFrame.new(0, 0, 4)) end)
toast(ok and ("Teleported to " .. p.DisplayName) or "Can't teleport there")
end).LayoutOrder = 2
hlBtn = mini(acts, "Highlight", 60, false, function()
hlOn = not hlOn
applyHighlight()
toast(hlOn and "Highlight on" or "Highlight off")
end)
hlBtn.LayoutOrder = 3
mini(acts, "Copy name", 60, false, function()
local p = need()
if not p then return end
local ok = pcall(setclipboard, p.Name)
toast(ok and "Name copied" or "setclipboard unavailable")
end).LayoutOrder = 4
local function addPlayer(p)
if p == lp or dots[p] then return end
local d = new("TextButton", {
AnchorPoint = Vector2.new(.5, .5), Size = UDim2.fromOffset(8, 8), BackgroundColor3 = T.tan, BorderSizePixel = 0,
Text = "", AutoButtonColor = false, ZIndex = 3, Visible = false, Parent = radar,
}, {new("UICorner", {CornerRadius = UDim.new(.5, 0)})})
d.Activated:Connect(function() select(p) end)
dots[p] = d
local fr = new("TextButton", {
Size = UDim2.new(1, 0, 0, 44), BackgroundColor3 = T.panel, BorderSizePixel = 0, AutoButtonColor = false, Text = "", Parent = list,
}, {round(8), stroke(T.line)})
local st = fr:FindFirstChildOfClass("UIStroke")
new("ImageLabel", {
Position = UDim2.fromOffset(8, 7), Size = UDim2.fromOffset(30, 30), BackgroundColor3 = T.panel2, BorderSizePixel = 0,
Image = ("rbxthumb://type=AvatarHeadShot&id=%d&w=100&h=100"):format(p.UserId), Parent = fr,
}, {new("UICorner", {CornerRadius = UDim.new(.5, 0)})})
text(fr, p.DisplayName, 12, "Bold", T.text, {Position = UDim2.fromOffset(48, 6), Size = UDim2.new(1, -60, 0, 16), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
local sub = text(fr, "@" .. p.Name, 10, "Regular", T.muted, {Position = UDim2.fromOffset(48, 24), Size = UDim2.new(1, -60, 0, 14), TextTruncate = Enum.TextTruncate.AtEnd})
fr.Activated:Connect(function() select(p) end)
rows[p] = {frame = fr, st = st, sub = sub}
end
local function removePlayer(p)
if dots[p] then dots[p]:Destroy() dots[p] = nil end
if rows[p] then rows[p].frame:Destroy() rows[p] = nil end
dists[p] = nil
if sel == p then
stopSpectate()
sel = nil
applyHighlight()
end
end
for _, p in ipairs(Players:GetPlayers()) do addPlayer(p) end
Players.PlayerAdded:Connect(addPlayer)
Players.PlayerRemoving:Connect(removePlayer)
local last, lastSlow = 0, 0
local conn
conn = RunService.Heartbeat:Connect(function()
if not gui.Parent then conn:Disconnect() return end
if not shown() then return end
local t = os.clock()
if t - last < .05 then return end
last = t
sweep.Rotation = (t * 90) % 360
local cam = workspace.CurrentCamera
local me = rootOf(lp)
local origin = me and me.Position or cam.CFrame.Position
local look = cam.CFrame.LookVector
local fwd = Vector3.new(look.X, 0, look.Z)
fwd = fwd.Magnitude > .01 and fwd.Unit or Vector3.new(0, 0, -1)
local right = fwd:Cross(Vector3.yAxis)
for p, d in pairs(dots) do
local r = rootOf(p)
if r then
local rel = r.Position - origin
dists[p] = rel.Magnitude
local x, y = rel:Dot(right) / range * (HALF - 6), -rel:Dot(fwd) / range * (HALF - 6)
local len = math.sqrt(x * x + y * y)
local out = len > HALF - 8
if out then x, y = x / len * (HALF - 8), y / len * (HALF - 8) end
d.Position = UDim2.fromOffset(HALF + x, HALF + y)
d.BackgroundTransparency = out and .6 or 0
d.Visible = true
else
dists[p] = nil
d.Visible = false
end
end
if t - lastSlow > .4 then
lastSlow = t
local n = 0
for p, rw in pairs(rows) do
n += 1
local dd = dists[p]
rw.frame.LayoutOrder = dd and math.floor(dd) or 99999
rw.sub.Text = dd and ("@%s · %d studs"):format(p.Name, dd) or ("@%s · no character"):format(p.Name)
end
listLbl.Text = ("PLAYERS (%d) · sorted by distance"):format(n)
if sel and sel.Parent then
local h = humOf(sel)
infoLbl.Text = ('%s\n@%s\nDistance %s\nHealth %s\nTeam %s'):format(
sel.DisplayName, sel.Name,
dists[sel] and (math.floor(dists[sel]) .. " studs") or "n/a",
h and (math.floor(h.Health) .. " / " .. math.floor(h.MaxHealth)) or "n/a",
sel.Team and sel.Team.Name or "none")
else
infoLbl.Text = 'Tap a dot on the radar or a player below.'
end
end
end)
end
local function pathOf(inst)
local names, cur = {}, inst
while cur and cur ~= game do
table.insert(names, 1, cur.Name)
cur = cur.Parent
end
local out = (cur == game) and "game" or "nil"
for _, n in ipairs(names) do
if n:match("^[%a_][%w_]*$") then
out = out .. "." .. n
else
out = out .. '["' .. (n:gsub('"', '\\"')) .. '"]'
end
end
return out
end
local function buildFinder(pane)
local filter, token, deb = "All", 0, 0
local input = new("TextBox", {
Position = UDim2.fromOffset(14, 10), Size = UDim2.new(1, -28, 0, 28), BackgroundColor3 = T.panel, BorderSizePixel = 0,
Text = "", PlaceholderText = "Search instances by name or class...", PlaceholderColor3 = T.muted, TextColor3 = T.text,
TextSize = 12, FontFace = F.Regular, TextXAlignment = Enum.TextXAlignment.Left, ClearTextOnFocus = false, Parent = pane,
}, {round(9), stroke(T.line), pad(26, 0, 8, 0)})
local edge = input:FindFirstChildOfClass("UIStroke")
local si = icon(pane, "search", 12, T.muted, 1.3)
si.holder.Position = UDim2.fromOffset(22, 18)
si.holder.ZIndex = 3
input.Focused:Connect(function() tween(edge, {Color = T.tan}, .25) si.set(T.tan, .25) end)
input.FocusLost:Connect(function() tween(edge, {Color = T.line}, .3) si.set(T.muted, .3) end)
local chipRow = new("Frame", {Position = UDim2.fromOffset(14, 46), Size = UDim2.new(1, -28, 0, 22), BackgroundTransparency = 1, Parent = pane}, {hlist(4)})
local results = scroller(pane, {Position = UDim2.fromOffset(0, 76), Size = UDim2.new(1, 0, 1, -76)}, {pad(14, 0, 14, 10), vlist(4)})
local function clearResults()
for _, c in ipairs(results:GetChildren()) do
if c:IsA("GuiObject") then c:Destroy() end
end
end
local function render(found, q)
clearResults()
if #found == 0 then
text(results, (q == "" and filter == "All") and "Type a name or pick a filter." or "No results.", 11, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 18), LayoutOrder = 1})
return
end
text(results, ("%d result%s"):format(#found, #found == 1 and "" or "s"), 10, "SemiBold", T.muted, {Size = UDim2.new(1, 0, 0, 14), LayoutOrder = 0})
for i, inst in ipairs(found) do
local path = pathOf(inst)
local isPart = inst:IsA("BasePart")
local r = panelRow(results, inst.Name, inst.ClassName .. " · " .. path, i, 44, isPart and 168 or 128, true)
local bx = btnBox(r, isPart and 132 or 92)
mini(bx, "Copy", 40, false, function()
local ok = pcall(setclipboard, path)
toast(ok and "Path copied" or "setclipboard unavailable")
end).LayoutOrder = 1
mini(bx, "Use", 36, true, function()
newTab(inst.Name, "local target = " .. path .. "\nprint(target)\n")
showPage("Editor")
picks.Editor(2)
end).LayoutOrder = 2
if isPart then
mini(bx, "TP", 32, false, function()
pcall(function()
local ch = lp.Character
if ch then ch:PivotTo(inst.CFrame + Vector3.new(0, 5, 0)) end
end)
end).LayoutOrder = 3
end
end
FX.cascade(results, .3)
end
local function matches(inst, q)
if filter == "Parts" and not inst:IsA("BasePart") then return false end
if filter == "Scripts" and not inst:IsA("LuaSourceContainer") then return false end
if filter == "Remotes" and not (inst:IsA("RemoteEvent") or inst:IsA("RemoteFunction")) then return false end
if filter == "GUIs" and not (inst:IsA("GuiObject") or inst:IsA("LayerCollector")) then return false end
if filter == "Models" and not inst:IsA("Model") then return false end
if filter == "Sounds" and not inst:IsA("Sound") then return false end
if filter == "Lights" and not inst:IsA("Light") then return false end
if q == "" then return filter ~= "All" end
return inst.Name:lower():find(q, 1, true) ~= nil or inst.ClassName:lower():find(q, 1, true) ~= nil
end
local function search()
token += 1
local mine = token
local q = input.Text:lower()
if q == "" and filter == "All" then render({}, q) return end
task.spawn(function()
local ok, all = pcall(function() return game:GetDescendants() end)
if not ok then render({}, q) return end
local found = {}
for i, inst in ipairs(all) do
if mine ~= token then return end
if matches(inst, q) and not inst:IsDescendantOf(gui) then
found[#found + 1] = inst
if #found >= 80 then break end
end
if i % 2500 == 0 then task.wait() end
end
if mine == token then render(found, q) end
end)
end
local chips = {}
local function paintChips()
for name, c in pairs(chips) do
local on = (name == filter)
tween(c.b, {BackgroundColor3 = on and T.bronze or T.panel2}, .3)
tween(c.l, {TextColor3 = on and T.text or T.muted}, .3)
end
end
for i, name in ipairs({"All", "Parts", "Models", "Scripts", "Remotes", "GUIs", "Sounds", "Lights"}) do
local b = new("TextButton", {
Size = UDim2.fromOffset(0, 22), AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = T.panel2, AutoButtonColor = false,
Text = "", LayoutOrder = i, Parent = chipRow,
}, {round(8), pad(10, 0), stroke(T.line)})
local l = text(b, name, 10, "SemiBold", T.muted, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 22), NoI18N = true})
I18N.bind(l, "chip:" .. name, name)
pressFx(b, .94)
chips[name] = {b = b, l = l}
b.Activated:Connect(function()
filter = name
paintChips()
search()
end)
end
paintChips()
input:GetPropertyChangedSignal("Text"):Connect(function()
deb += 1
local d = deb
task.delay(.35, function() if d == deb then search() end end)
end)
render({}, "")
end
local function buildEditorStart(pane)
local sc = scroller(pane, {}, {pad(16), vlist(10)})
local top = new("Frame", {Size = UDim2.new(1, 0, 0, 82), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = 1, Parent = sc}, {round(12), stroke(T.line)})
new("Frame", {Size = UDim2.new(0, 3, 1, -22), Position = UDim2.fromOffset(0, 11), BackgroundColor3 = T.bronze, BorderSizePixel = 0, Parent = top}, {round(2)})
text(top, "Hyundax IUM", 21, "Bold", T.text, {Position = UDim2.fromOffset(16, 12), Size = UDim2.new(1, -28, 0, 26), NoI18N = true})
text(top, "Signed in as " .. I18N.shownName() .. " · Session active", 10, "Regular", T.muted, {Position = UDim2.fromOffset(17, 44), Size = UDim2.new(1, -30, 0, 16)})
local splitRow = new("Frame", {Size = UDim2.new(1, 0, 0, 198), BackgroundTransparency = 1, LayoutOrder = 2, Parent = sc}, {hlist(10)})
local startCard = new("Frame", {Size = UDim2.new(.52, -5, 1, 0), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, Parent = splitRow}, {round(12), stroke(T.line), pad(10), vlist(6)})
local quickCard = new("Frame", {Size = UDim2.new(.48, -5, 1, 0), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, Parent = splitRow}, {round(12), stroke(T.line), pad(10), vlist(7)})
section(startCard, "Start", 1)
local function startAction(order, ico, title, desc, cb)
local b = new("TextButton", {Size = UDim2.new(1, 0, 0, 43), BackgroundColor3 = T.panel, BackgroundTransparency = 0, AutoButtonColor = false, Text = "", LayoutOrder = order, Parent = startCard}, {round(8), stroke(T.line)})
local ic = icon(b, ico, 14, T.gold, 1.5)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(0, .5), UDim2.new(0, 9, .5, 0)
text(b, title, 11, "Bold", T.text, {Position = UDim2.fromOffset(32, 5), Size = UDim2.new(1, -42, 0, 15)})
text(b, desc, 9, "Regular", T.muted, {Position = UDim2.fromOffset(32, 21), Size = UDim2.new(1, -42, 0, 14)})
hoverFx(b, T.panel, T.panel2)
pressFx(b, .96)
b.Activated:Connect(cb)
end
startAction(2, "plus", "New script", "Create a blank editor tab", function()
newTab("New script", "")
showPage("Editor")
if picks.Editor then picks.Editor(2) end
end)
startAction(3, "folder", "Open script", "Open a local Hyundax IUM script", function()
showPage("Editor")
if picks.Editor then picks.Editor(2) end
openDialog()
end)
startAction(4, "globe", "Explore scripts", "Browse the ScriptBlox Hub", function() showPage("Scripts") end)
section(quickCard, "Getting started", 1)
local placeInfo = text(quickCard, "CURRENT GAME", 9, "Bold", T.muted, {Size = UDim2.new(1, 0, 0, 12), LayoutOrder = 2})
text(quickCard, tostring(game.Name), 12, "SemiBold", T.text, {Size = UDim2.new(1, 0, 0, 18), LayoutOrder = 3, TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
text(quickCard, "Place ID " .. tostring(game.PlaceId), 9, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 14), LayoutOrder = 4})
local tip = new("Frame", {Size = UDim2.new(1, 0, 0, 76), BackgroundColor3 = T.glow, BorderSizePixel = 0, LayoutOrder = 5, Parent = quickCard}, {round(8), stroke(T.bronzeLo), pad(8), vlist(4)})
text(tip, "TIP OF THE DAY", 9, "Bold", T.gold, {Size = UDim2.new(1, 0, 0, 12)})
text(tip, "Save scripts to AutoExec from the editor toolbar to run them when Hyundax IUM starts.", 9, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true})
section(sc, "Recent scripts", 3)
local recentHolder = new("Frame", {Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 4, Parent = sc}, {vlist(5)})
local function refreshRecent()
for _, child in ipairs(recentHolder:GetChildren()) do if child:IsA("GuiObject") and not child:IsA("UIListLayout") then child:Destroy() end end
if #recents == 0 then
text(recentHolder, "No recent scripts yet. Execute a script to see it here.", 10, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 18)})
return
end
for i = 1, math.min(4, #recents) do
local entry = recents[i]
local row = new("TextButton", {Size = UDim2.new(1, 0, 0, 34), BackgroundColor3 = T.panel, AutoButtonColor = false, Text = "", LayoutOrder = i, Parent = recentHolder}, {round(7), stroke(T.line)})
local ic = icon(row, "file", 13, T.tan, 1.4)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(0, .5), UDim2.new(0, 9, .5, 0)
text(row, tostring(entry.name or "Recent script"), 10, "SemiBold", T.text, {Position = UDim2.fromOffset(30, 0), Size = UDim2.new(1, -42, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true})
hoverFx(row, T.panel, T.panel2)
row.Activated:Connect(function()
newTab(tostring(entry.name or "Recent script"):sub(1, 22), entry.code or "")
showPage("Editor")
if picks.Editor then picks.Editor(2) end
end)
end
end
refreshRecent()
Store.refreshEditorStart = refreshRecent
end
FX.Plugins = (function(E)
local new, round, stroke, pad, vlist, hlist = E.new, E.round, E.stroke, E.pad, E.vlist, E.hlist
local text, scroller, icon, tween, pressFx = E.text, E.scroller, E.icon, E.tween, E.pressFx
local T, F, FX, I18N, gui, main = E.T, E.F, E.FX, E.I18N, E.gui, E.main
local toast, addLine, mini = E.toast, E.addLine, E.mini
local lp = E.lp
local FILE = E.FOLDER .. "/plugins.json"
local data = E.jsonRead(FILE, {})
if type(data.custom) ~= "table" then data.custom = {} end
if type(data.enabled) ~= "table" then data.enabled = {} end
if type(data.store) ~= "table" then data.store = {} end
do
local clean = {}
for _, p in ipairs(data.custom) do
if type(p) == "table" and type(p.id) == "string" and type(p.name) == "string" and type(p.code) == "string" then
clean[#clean + 1] = p
end
end
data.custom = clean
end
local saveQueued = false
local function save()
if saveQueued then return end
saveQueued = true
task.delay(.4, function()
saveQueued = false
E.jsonWrite(FILE, data)
end)
end
local running = {}
local errors = {}
local commands = {}
local titleBtns = 0
local editingId
local formName, formCode, formBanner
local refreshBanner = function() end
local refreshList = function() end
local function nextOrder(parent)
local n = (parent:GetAttribute("_n") or 0) + 1
parent:SetAttribute("_n", n)
return n
end
local function trim(s)
return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end
local ui = {
new = new, round = round, stroke = stroke, pad = pad, vlist = vlist, hlist = hlist,
text = text, scroller = scroller, icon = icon, tween = tween, pressFx = pressFx, hoverFx = E.hoverFx,
}
function ui.chip(parent, ico, box, color, pos)
local f = FX.chip(parent, ico, box, color, pos)
return f
end
function ui.label(parent, str, size, color, props)
local p = {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true,
TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = nextOrder(parent),
}
for k, v in pairs(props or {}) do p[k] = v end
return text(parent, str, size or 11, "Regular", color or T.muted, p)
end
function ui.button(parent, label, w, primary, cb)
local b = mini(parent, label, w, primary, cb)
b.LayoutOrder = nextOrder(parent)
return b
end
function ui.row(parent, gap, h)
return new("Frame", {
Size = UDim2.new(1, 0, 0, h or 26), BackgroundTransparency = 1,
LayoutOrder = nextOrder(parent), Parent = parent,
}, {hlist(gap or 4)})
end
function ui.input(parent, placeholder, default, props)
local p = {
Size = UDim2.new(1, 0, 0, 30), BackgroundColor3 = T.panel, Text = default or "",
PlaceholderText = placeholder or "", PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 11,
FontFace = F.Regular, ClearTextOnFocus = false, TextXAlignment = Enum.TextXAlignment.Left,
LayoutOrder = nextOrder(parent), Parent = parent,
}
for k, v in pairs(props or {}) do p[k] = v end
local box = new("TextBox", p, {round(8), pad(10, 0, 10, 0)})
local st = stroke(T.line, 1)
st.Parent = box
box.Focused:Connect(function() tween(st, {Color = T.tan}, .2) end)
box.FocusLost:Connect(function() tween(st, {Color = T.line}, .2) end)
return box
end
function ui.codeBox(parent, placeholder, default, height)
local h = height or 150
local holder = new("ScrollingFrame", {
Size = UDim2.new(1, 0, 0, h), BackgroundColor3 = T.panel, BorderSizePixel = 0, ScrollBarThickness = 3,
ScrollBarImageColor3 = T.tan, CanvasSize = UDim2.new(), AutomaticCanvasSize = Enum.AutomaticSize.XY,
ScrollingDirection = Enum.ScrollingDirection.XY, LayoutOrder = nextOrder(parent), Parent = parent,
}, {round(8)})
local st = stroke(T.line, 1)
st.Parent = holder
local box = new("TextBox", {
BackgroundTransparency = 1, Text = default or "", PlaceholderText = placeholder or "", PlaceholderColor3 = T.muted,
MultiLine = true, ClearTextOnFocus = false, TextWrapped = false, TextSize = 12, FontFace = E.MONO,
TextColor3 = T.text, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Top,
AutomaticSize = Enum.AutomaticSize.XY, Size = UDim2.fromOffset(280, h), Parent = holder,
}, {pad(8)})
box.Focused:Connect(function() tween(st, {Color = T.tan}, .2) end)
box.FocusLost:Connect(function() tween(st, {Color = T.line}, .2) end)
return box, holder
end
function ui.segmented(parent, options, index, cb)
local row = ui.row(parent, 4, 26)
local btns = {}
local cur = index or 1
local function paint()
for i, b in ipairs(btns) do
tween(b, {BackgroundColor3 = (i == cur) and T.bronze or T.panel2}, .25)
b.TextColor3 = (i == cur) and T.dark or T.text
end
end
for i, label in ipairs(options) do
local b = new("TextButton", {
Size = UDim2.new(1 / #options, -4, 1, 0), BackgroundColor3 = (i == cur) and T.bronze or T.panel2,
AutoButtonColor = false, Text = label, TextSize = 10, FontFace = F.SemiBold,
TextColor3 = (i == cur) and T.dark or T.text, LayoutOrder = i, Parent = row,
}, {round(7), stroke(T.line)})
pressFx(b, .95)
btns[i] = b
b.Activated:Connect(function()
cur = i
paint()
if cb then cb(i, label) end
end)
end
return {row = row, set = function(i) cur = i paint() end}
end
local function makeToggle(parent, on, cb)
local track = new("TextButton", {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, 0, .5, 0), Size = UDim2.fromOffset(42, 22),
BackgroundColor3 = on and T.bronze or T.panel2, AutoButtonColor = false, Text = "", Parent = parent,
}, {round(11), stroke(on and T.bronzeHi or T.line)})
local knob = new("Frame", {
AnchorPoint = Vector2.new(0, .5), Position = UDim2.new(0, on and 22 or 2, .5, 0), Size = UDim2.fromOffset(18, 18),
BackgroundColor3 = T.text, BorderSizePixel = 0, Parent = track,
}, {round(9)})
local st = track:FindFirstChildOfClass("UIStroke")
local function paint(v)
on = v
knob.Size = UDim2.fromOffset(24, 16)
tween(knob, {Position = UDim2.new(0, on and 12 or 2, .5, 0)}, .12, Enum.EasingStyle.Quad)
task.delay(.1 * FX.scale, function()
if not knob.Parent then return end
tween(knob, {Size = UDim2.fromOffset(18, 18), Position = UDim2.new(0, on and 22 or 2, .5, 0)}, .5, Enum.EasingStyle.Back)
end)
tween(st, {Color = on and T.bronzeHi or T.line}, .4)
tween(track, {BackgroundColor3 = on and T.bronze or T.panel2}, .4)
end
track.Activated:Connect(function()
local want = not on
local keep = cb and cb(want)
if keep == false then return end
paint(want)
end)
return track, paint
end
function ui.switch(parent, title, value, cb)
local r = new("Frame", {
Size = UDim2.new(1, 0, 0, 38), BackgroundColor3 = T.cardTop, BorderSizePixel = 0,
LayoutOrder = nextOrder(parent), Parent = parent,
}, {round(10), stroke(T.line), pad(12, 0, 12, 0)})
text(r, title, 11, "SemiBold", T.text, {Size = UDim2.new(1, -56, 1, 0), TextTruncate = Enum.TextTruncate.AtEnd})
return makeToggle(r, value and true or false, function(v)
if cb then return cb(v) end
end)
end
local function openPopup(title, w, h, build, pluginId, raw, creator)
local p = FX.popup({
name = "HyundaxIUMPluginPopup", z = 400, w = w or 420, h = h or 340,
title = title, raw = raw, subtitle = creator and ("Created by " .. tostring(creator)) or nil,
icon = pluginId and "code" or "layers", attrs = pluginId and {PluginId = pluginId} or nil,
})
local body, closeFn = p.body, p.close
if build then
local ok, err = pcall(build, body, closeFn)
if not ok then
addLine("Console", "[popup] " .. tostring(err), T.bronzeHi)
toast("Plugin error, see Console")
end
end
return body, closeFn
end
local ROLES = {"bg", "side", "panel", "panel2", "line", "text", "muted", "bronze", "bronzeHi", "bronzeLo", "gold", "dark", "glow", "cardTop", "tan"}
local function capture(pal)
local o = {}
for _, r in ipairs(ROLES) do
local c = pal[r]
if typeof(c) == "Color3" then
o[r] = {math.floor(c.R * 255 + .5), math.floor(c.G * 255 + .5), math.floor(c.B * 255 + .5)}
end
end
return o
end
local function fixTitleWidth()
E.ctrls.Size = UDim2.fromOffset(100 + 32 * titleBtns, E.TITLE_H)
end
local function stopPlugin(id)
local ctx = running[id]
if not ctx then return end
running[id] = nil
ctx.dead = true
for i = #ctx.cleanups, 1, -1 do pcall(ctx.cleanups[i]) end
for _, c in ipairs(ctx.conns) do pcall(function() c:Disconnect() end) end
for _, o in ipairs(ctx.objects) do pcall(function() o:Destroy() end) end
for i = #commands, 1, -1 do
if commands[i].id == id then table.remove(commands, i) end
end
for _, b in ipairs(ctx.titleButtons) do
pcall(function() b:Destroy() end)
titleBtns = math.max(0, titleBtns - 1)
end
fixTitleWidth()
local pop = gui:FindFirstChild("HyundaxIUMPluginPopup")
if pop and pop:GetAttribute("PluginId") == id then pop:Destroy() end
end
local function makeAPI(p, ctx)
local S = {}
S.id, S.name, S.creator, S.version = p.id, p.name, p.creator, E.VERSION
S.gui, S.root, S.main, S.theme, S.fonts, S.mono = gui, E.root, main, T, F, E.MONO
S.borderStroke, S.player, S.ui = E.borderStroke, lp, ui
S.apiVersion = 2
function S.toast(m) toast(tostring(m)) end
function S.log(m, c) addLine("Console", "[" .. p.name .. "] " .. tostring(m), c or T.tan) end
function S.onCleanup(fn) ctx.cleanups[#ctx.cleanups + 1] = fn end
function S.track(o) ctx.objects[#ctx.objects + 1] = o return o end
function S.connect(signal, fn)
local c = signal:Connect(fn)
ctx.conns[#ctx.conns + 1] = c
return c
end
function S.onOpen(fn)
ctx.openFn = fn
task.defer(refreshList)
end
function S.save(key, value)
if value ~= nil and not pcall(function() return game:GetService("HttpService"):JSONEncode(value) end) then return false end
data.store[p.id] = data.store[p.id] or {}
data.store[p.id][tostring(key)] = value
save()
return true
end
function S.load(key, default)
local st = data.store[p.id]
local v = st and st[tostring(key)]
if v == nil then return default end
return v
end
function S.addCommand(title, fn, hint)
commands[#commands + 1] = {id = p.id, title = tostring(title), hint = hint and tostring(hint) or p.name, creator = p.creator, fn = fn}
end
function S.getCommands()
local out = {}
for _, c in ipairs(commands) do
out[#out + 1] = {
title = c.title, hint = c.hint, creator = c.creator,
run = function()
local ok, err = pcall(c.fn)
if not ok then addLine("Console", "[" .. c.hint .. "] " .. tostring(err), T.bronzeHi) end
end,
}
end
return out
end
function S.addTitleButton(ico, cb)
local b = new("TextButton", {
Size = UDim2.fromOffset(30, 26), BackgroundColor3 = T.bg, AutoButtonColor = false, Text = "", LayoutOrder = 1, Glass = true, Parent = E.ctrls,
}, {round(9)})
local ic = icon(b, ico or "bolt", 12, T.muted, 1.5)
ic.holder.AnchorPoint, ic.holder.Position = Vector2.new(.5, .5), UDim2.fromScale(.5, .5)
b.MouseEnter:Connect(function() tween(b, {BackgroundColor3 = T.panel2}, .15) ic.set(T.text, .15) end)
b.MouseLeave:Connect(function() tween(b, {BackgroundColor3 = T.bg}, .2) ic.set(T.muted, .2) end)
pressFx(b, .88)
b.Activated:Connect(function()
local ok, err = pcall(cb)
if not ok then addLine("Console", "[" .. p.name .. "] " .. tostring(err), T.bronzeHi) end
end)
ctx.titleButtons[#ctx.titleButtons + 1] = b
titleBtns = titleBtns + 1
fixTitleWidth()
return b
end
function S.popup(title, w, h, build)
return openPopup(title or p.name, w, h, build, p.id, true, p.creator)
end
function S.pages() return table.clone(E.pageOrder) end
function S.showPage(name) E.showPage(name) end
function S.selectSettings(name) pcall(FX.settingsPage.select, name) end
function S.themes() return table.clone(T.THEME_ORDER) end
function S.setTheme(name) E.setTheme(name) end
function S.recents() return E.recents() end
function S.newTab(name, code) E.newTab(name, code) E.showPage("Editor") end
function S.run(code, name) E.runCode(code, name or p.name) end
function S.clearConsole() E.clearConsole() end
function S.http(url) return E.httpGet(url) end
function S.copy(str)
local ok = pcall(setclipboard, tostring(str))
toast(ok and "Copied" or "setclipboard unavailable")
return ok
end
function S.asset(url, force)
url = tostring(url or "")
if not url:match("^https?://") then return nil, "invalid url" end
local h = 5381
for i = 1, #url do h = (h * 33 + url:byte(i)) % 4294967296 end
local path = E.FOLDER .. "/plugin_" .. string.format("%08x", h) .. ".dat"
if force and isfile and delfile and isfile(path) then pcall(delfile, path) end
local a = E.toAsset(path, function()
local body = E.httpGet(url)
if not body then error("download failed") end
return body
end)
if not a then return nil, "could not load the image" end
return a
end
function S.fetch(url)
url = tostring(url or "")
if not url:match("^https?://") then return nil, "invalid url" end
local body = E.httpGet(url)
if type(body) ~= "string" or #body == 0 then return nil, "download failed" end
return body
end
function S.onStop(fn) ctx.cleanups[#ctx.cleanups + 1] = fn end
function S.after(sec, fn)
return task.delay(sec, function()
if ctx.dead then return end
local ok, e = pcall(fn)
if not ok then S.log(e, T.bronzeHi) end
end)
end
function S.every(sec, fn)
task.spawn(function()
while not ctx.dead do
task.wait(sec)
if ctx.dead then break end
local ok, e = pcall(fn)
if not ok then S.log(e, T.bronzeHi) end
end
end)
end
function S.currentTheme() return T.ACTIVE_THEME end
function S.palette() return capture(T) end
function S.addTheme(name, desc, pal)
name = tostring(name or ""):gsub("^%s+", ""):gsub("%s+$", ""):sub(1, 28)
if name == "" or type(pal) ~= "table" then return false, "invalid theme" end
if T.UI_THEMES[name] and not (ctx.themes and ctx.themes[name]) then return false, "theme name already in use" end
local base = T.UI_THEMES["Hyundax IUM Primary"]
local out = {}
for _, r in ipairs(ROLES) do
local v = pal[r]
if typeof(v) == "Color3" then out[r] = v
elseif type(v) == "table" and #v == 3 then out[r] = Color3.fromRGB(v[1], v[2], v[3])
else out[r] = base[r] end
end
T.UI_THEMES[name] = out
T.THEME_DESC[name] = tostring(desc or "Plugin theme.")
local found = false
for _, n in ipairs(T.THEME_ORDER) do if n == name then found = true end end
if not found then
local at = #T.THEME_ORDER + 1
for i, n in ipairs(T.THEME_ORDER) do if n == "Custom" then at = i break end end
table.insert(T.THEME_ORDER, at, name)
end
ctx.themes = ctx.themes or {}
if not ctx.themes[name] then
ctx.themes[name] = true
ctx.cleanups[#ctx.cleanups + 1] = function() S.removeTheme(name) end
end
return true
end
function S.removeTheme(name)
if not (ctx.themes and ctx.themes[name]) then return false end
if T.ACTIVE_THEME == name then E.setTheme("Hyundax IUM Primary") end
T.UI_THEMES[name], T.THEME_DESC[name] = nil, nil
for i, n in ipairs(T.THEME_ORDER) do if n == name then table.remove(T.THEME_ORDER, i) break end end
ctx.themes[name] = nil
return true
end
function S.background(url, strength)
local ALPHAS = {.8, .55, .3}
local img = S.track(new("ImageLabel", {
Name = "PluginBackgroundImage", Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1,
ImageTransparency = 1, ScaleType = Enum.ScaleType.Crop, ZIndex = -1, Parent = main,
}, {round(14)}))
img:SetAttribute("NoTheme", true)
local shade = S.track(new("Frame", {
Name = "PluginBackgroundShade", Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = -1, Parent = main,
}, {round(14)}))
shade:SetAttribute("NoTheme", true)
local st = tonumber(strength) or 2
local h = {}
local function paint()
if img.Image ~= "" then
img.ImageTransparency = ALPHAS[st] or .55
shade.BackgroundTransparency = .45
else
img.ImageTransparency, shade.BackgroundTransparency = 1, 1
end
end
function h.setStrength(i) st = i paint() end
function h.clear() img.Image = "" paint() end
function h.set(u, force)
task.spawn(function()
local a, err = S.asset(u, force)
if not a then S.log(err or "could not load the image", T.bronzeHi) return end
if ctx.dead then return end
img.Image = a
paint()
end)
end
if url and tostring(url) ~= "" then h.set(url) end
return h
end
return S
end
local function startPlugin(p)
if running[p.id] then return true end
local ls = loadstring
if not ls then return false, "loadstring is not available in this executor" end
local fn, err = ls("local HyundaxIUM, Plugin = ...; local HyundaxX = HyundaxIUM; local Sparta = HyundaxIUM; " .. p.code)
if not fn then return false, tostring(err) end
local ctx = {cleanups = {}, conns = {}, objects = {}, titleButtons = {}, openFn = nil}
running[p.id] = ctx
local api = makeAPI(p, ctx)
task.spawn(function()
local ok, e = pcall(fn, api, {id = p.id, name = p.name, creator = p.creator})
if not ok then
stopPlugin(p.id)
errors[p.id] = tostring(e)
data.enabled[p.id] = false
save()
addLine("Console", "[plugin:" .. p.name .. "] " .. tostring(e), T.bronzeHi)
toast("Plugin error, see Console")
task.defer(refreshList)
end
end)
return true
end
local BUILTIN = {}
BUILTIN[#BUILTIN + 1] = {
id = "b_image", name = "Image Personalization", creator = "Hyundax Team", builtin = true,
desc = "Set any image link as the Hyundax IUM background. Clean style keeps the picture fully visible with see-through panels.",
code = [==[
local ui, T = HyundaxIUM.ui, HyundaxIUM.theme
local main = HyundaxIUM.main
local TS = game:GetService("TweenService")
local img = HyundaxIUM.track(ui.new("ImageLabel", {
Name = "PluginBackgroundImage", Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1,
ImageTransparency = 1, ScaleType = Enum.ScaleType.Crop, ZIndex = -1, Parent = main,
}, {ui.round(14)}))
img:SetAttribute("NoTheme", true)
local shade = HyundaxIUM.track(ui.new("Frame", {
Name = "PluginBackgroundShade", Size = UDim2.fromScale(1, 1), BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = -1, Parent = main,
}, {ui.round(14)}))
shade:SetAttribute("NoTheme", true)
local CLASSIC = {.8, .55, .3}
local CLEAN = {.3, .12, 0}
local PANELS = {0, .45, .85}
local DIMS = {1, .8, .6}
local SHOW_T = {0, 30, 90, 300}
local FITS = {Enum.ScaleType.Crop, Enum.ScaleType.Fit, Enum.ScaleType.Stretch}
local style = HyundaxIUM.load("style", 2)
local strength = HyundaxIUM.load("alpha", 2)
local panels = HyundaxIUM.load("panels", 3)
local fit = HyundaxIUM.load("fit", 1)
local dim = HyundaxIUM.load("dim", 1)
local show = HyundaxIUM.load("show", 1)
local status
local AssetService = game:GetService("AssetService")
local RunService = game:GetService("RunService")
local hasImage = false
local reqId, playId, gifEI = 0, 0, nil
local MB = 1024 * 1024
local GQ = {
{name = "Low", max = 320, budget = 64 * MB, taps = 1},
{name = "Medium", max = 480, budget = 112 * MB, taps = 2},
{name = "High", max = 720, budget = 192 * MB, taps = 3},
{name = "Ultra", max = 1024, budget = 320 * MB, taps = 3},
}
local gq = HyundaxIUM.load("gq", 3)
local gifCache = {url = nil, body = nil}
local function stopPlayback()
playId += 1
pcall(function() img.ImageContent = Content.none end)
if gifEI then
local e = gifEI
gifEI = nil
pcall(function() e:Destroy() end)
end
gifCache.url, gifCache.body = nil, nil
end
local function clearImage()
reqId += 1
stopPlayback()
img.Image = ""
hasImage = false
end
local function u16(str, p)
local a, b = str:byte(p, p + 1)
return (a or 0) + (b or 0) * 256
end
local function lzwDecode(data, minCode, total, tick)
local band, bor, lsh, rsh = bit32.band, bit32.bor, bit32.lshift, bit32.rshift
local out = buffer.create(math.max(total, 1))
if minCode < 1 or minCode > 8 then return out, 0 end
local clear = lsh(1, minCode)
local eoi = clear + 1
local size = minCode + 1
local mask = lsh(1, size) - 1
local avail = clear + 2
local prefix, suffix, stack = {}, {}, {}
for i = 0, clear - 1 do suffix[i] = i end
local bits, nbits, pos, len = 0, 0, 1, #data
local old, first, n, iter = -1, 0, 0, 0
while n < total do
iter += 1
if tick and iter % 4096 == 0 then tick() end
while nbits < size do
if pos > len then return out, n end
bits = bor(bits, lsh(data:byte(pos), nbits))
nbits += 8
pos += 1
end
local code = band(bits, mask)
bits = rsh(bits, size)
nbits -= size
if code == clear then
size = minCode + 1
mask = lsh(1, size) - 1
avail = clear + 2
old = -1
elseif code == eoi then
break
elseif old == -1 then
if code >= clear then break end
buffer.writeu8(out, n, code)
n += 1
first, old = code, code
else
local inCode, sp = code, 0
if code >= avail then
if code > avail then break end
sp += 1
stack[sp] = first
code = old
end
while code >= clear do
sp += 1
stack[sp] = suffix[code]
code = prefix[code]
end
first = code
sp += 1
stack[sp] = first
if avail < 4096 then
prefix[avail] = old
suffix[avail] = first
avail += 1
if band(avail, mask) == 0 and avail < 4096 then
size += 1
mask = lsh(1, size) - 1
end
end
old = inCode
for k = sp, 1, -1 do
if n >= total then break end
buffer.writeu8(out, n, stack[k])
n += 1
end
end
end
return out, n
end
local function scanGif(str)
local band, lsh = bit32.band, bit32.lshift
local packed = str:byte(11) or 0
local pos, len = 14, #str
if band(packed, 0x80) ~= 0 then pos += 3 * lsh(2, band(packed, 7)) end
local count = 0
while pos <= len do
local b = str:byte(pos)
pos += 1
if b == 0x21 then
pos += 1
while pos <= len do
local sz = str:byte(pos)
pos += 1 + sz
if sz == 0 then break end
end
elseif b == 0x2C then
local ip = str:byte(pos + 8) or 0
pos += 9
if band(ip, 0x80) ~= 0 then pos += 3 * lsh(2, band(ip, 7)) end
pos += 1
while pos <= len do
local sz = str:byte(pos)
pos += 1 + sz
if sz == 0 then break end
end
count += 1
else
break
end
end
return count
end
local function decodeGif(str, my, cfg, onProgress)
local band, lsh, rsh = bit32.band, bit32.lshift, bit32.rshift
if str:sub(1, 4) ~= "GIF8" then return nil, "That link is not a GIF file." end
local W, H = u16(str, 7), u16(str, 9)
if W == 0 or H == 0 then return nil, "Invalid GIF." end
local count = scanGif(str)
if count == 0 then return nil, "Could not read any frame from this GIF." end
local packed = str:byte(11)
local pos, len = 14, #str
local function readPal(n)
local pal = {}
for i = 0, n - 1 do
local r, g, b = str:byte(pos, pos + 2)
pal[i] = (r or 0) + (g or 0) * 256 + (b or 0) * 65536 + 4278190080
pos += 3
end
return pal
end
local gct
if band(packed, 0x80) ~= 0 then gct = readPal(lsh(2, band(packed, 7))) end
local sc = math.min(1, cfg.max / math.max(W, H))
local w, h = math.max(1, math.floor(W * sc + .5)), math.max(1, math.floor(H * sc + .5))
local scaled = (w ~= W) or (h ~= H)
local bytes, full = w * h * 4, W * H * 4
local maxFrames = math.max(1, math.floor(cfg.budget / bytes))
local stride = math.max(1, math.ceil(count / maxFrames))
local k = 1
if scaled then k = math.max(1, math.min(cfg.taps, math.ceil(math.max(W / w, H / h)))) end
local xs, ys = {}, {}
if scaled then
for x = 0, w - 1 do
for j = 0, k - 1 do xs[x * k + j] = math.min(W - 1, math.floor((x + (j + .5) / k) * W / w)) end
end
for y = 0, h - 1 do
for j = 0, k - 1 do ys[y * k + j] = math.min(H - 1, math.floor((y + (j + .5) / k) * H / h)) end
end
end
local last = os.clock()
local function pace()
if os.clock() - last > 0.012 then
task.wait()
last = os.clock()
if reqId ~= my then error("cancelled", 0) end
end
end
local cv = buffer.create(full)
local frames, delays = {}, {}
local gce = {disp = 0, delay = 10}
local pending
local fi = 0
local function fillRect(left, top, fw, fh)
local cw = math.min(fw, W - left)
if cw <= 0 then return end
for r = 0, fh - 1 do
local y = top + r
if y >= H then break end
buffer.fill(cv, (y * W + left) * 4, 0, cw * 4)
end
end
local function downscale(snap)
if k == 1 then
for y = 0, h - 1 do
local ro, o = ys[y] * W, y * w * 4
for x = 0, w - 1 do
buffer.writeu32(snap, o + x * 4, buffer.readu32(cv, (ro + xs[x]) * 4))
end
if y % 32 == 31 then pace() end
end
return
end
local kk = k * k
for y = 0, h - 1 do
local yb = y * k
local o = y * w * 4
for x = 0, w - 1 do
local xb = x * k
local r, g, b, cnt = 0, 0, 0, 0
for jy = 0, k - 1 do
local ro = ys[yb + jy] * W
for jx = 0, k - 1 do
local c = buffer.readu32(cv, (ro + xs[xb + jx]) * 4)
if c ~= 0 then
cnt += 1
r += band(c, 255)
g += band(rsh(c, 8), 255)
b += band(rsh(c, 16), 255)
end
end
end
if cnt == 0 then
buffer.writeu32(snap, o + x * 4, 0)
else
local d2 = cnt * 2
local a = (cnt * 510 + kk) // (kk * 2)
buffer.writeu32(snap, o + x * 4, (r * 2 + cnt) // d2 + ((g * 2 + cnt) // d2) * 256 + ((b * 2 + cnt) // d2) * 65536 + a * 16777216)
end
end
if y % 16 == 15 then pace() end
end
end
while pos <= len do
if reqId ~= my then return nil, nil end
local b = str:byte(pos)
pos += 1
if b == 0x21 then
local label = str:byte(pos)
pos += 1
if label == 0xF9 then
local pk = str:byte(pos + 1) or 0
gce = {
disp = band(rsh(pk, 2), 7),
transp = (band(pk, 1) == 1) and str:byte(pos + 4) or nil,
delay = u16(str, pos + 2),
}
end
while pos <= len do
local sz = str:byte(pos)
pos += 1 + sz
if sz == 0 then break end
end
elseif b == 0x2C then
local left, top, fw, fh = u16(str, pos), u16(str, pos + 2), u16(str, pos + 4), u16(str, pos + 6)
local ip = str:byte(pos + 8)
pos += 9
local pal = gct
if band(ip, 0x80) ~= 0 then pal = readPal(lsh(2, band(ip, 7))) end
if not pal then return nil, "Invalid GIF (no color table)." end
local interlace = band(ip, 0x40) ~= 0
local minCode = str:byte(pos)
pos += 1
local parts = {}
while pos <= len do
local sz = str:byte(pos)
pos += 1
if sz == 0 then break end
parts[#parts + 1] = str:sub(pos, pos + sz - 1)
pos += sz
end
local pix = lzwDecode(table.concat(parts), minCode, fw * fh, pace)
if pending then
if pending.disp == 2 then
fillRect(pending.left, pending.top, pending.fw, pending.fh)
elseif pending.disp == 3 and pending.saved then
buffer.copy(cv, 0, pending.saved, 0, full)
end
end
local saved
if gce.disp == 3 then
saved = buffer.create(full)
buffer.copy(saved, 0, cv, 0, full)
end
local rowOf
if interlace then
rowOf = {}
local r = 0
for _, ps in ipairs({{0, 8}, {4, 8}, {2, 4}, {1, 2}}) do
for y = ps[1], fh - 1, ps[2] do
rowOf[y] = r
r += 1
end
end
end
local transp = gce.transp
local cw = math.min(fw, W - left)
if cw > 0 then
for r = 0, fh - 1 do
local y = top + r
if y >= H then break end
local base = (rowOf and rowOf[r] or r) * fw
local o = (y * W + left) * 4
for x = 0, cw - 1 do
local idx = buffer.readu8(pix, base + x)
if idx ~= transp then
local c = pal[idx]
if c then buffer.writeu32(cv, o + x * 4, c) end
end
end
if r % 24 == 23 then pace() end
end
end
fi += 1
local d = gce.delay or 10
if d <= 1 then d = 10 end
if (fi - 1) % stride == 0 then
local snap = buffer.create(bytes)
if scaled then
downscale(snap)
else
buffer.copy(snap, 0, cv, 0, bytes)
end
frames[#frames + 1] = snap
delays[#delays + 1] = d / 100
else
delays[#delays] += d / 100
end
pending = {disp = gce.disp, left = left, top = top, fw = fw, fh = fh, saved = saved}
gce = {disp = 0, delay = 10}
if onProgress then onProgress(fi, count) end
pace()
elseif b == 0x3B then
break
else
break
end
end
if #frames == 0 then return nil, "Could not read any frame from this GIF." end
return frames, delays, w, h, stride, fi
end
local function playGif(frames, delays, w, h)
local ei
pcall(function() ei = AssetService:CreateEditableImage({Size = Vector2.new(w, h)}) end)
if not ei then
pcall(function()
ei = Instance.new("EditableImage")
ei.Size = Vector2.new(w, h)
end)
end
if not ei then return false end
local size, useTable = Vector2.new(w, h), false
local function put(buf)
if not useTable then
if pcall(function() ei:WritePixelsBuffer(Vector2.zero, size, buf) end) then return true end
useTable = true
end
local t = table.create(w * h * 4)
for i = 0, w * h * 4 - 1 do t[i + 1] = buffer.readu8(buf, i) / 255 end
return pcall(function() ei:WritePixels(Vector2.zero, size, t) end)
end
if not put(frames[1]) then
pcall(function() ei:Destroy() end)
return false
end
local oldEI = gifEI
playId += 1
local myPlay = playId
if not pcall(function() img.ImageContent = Content.fromObject(ei) end) then
pcall(function() ei:Destroy() end)
return false
end
gifEI = ei
if oldEI then pcall(function() oldEI:Destroy() end) end
local n = #frames
if n > 1 then
task.spawn(function()
local i = 1
local nextT = os.clock() + delays[1]
while playId == myPlay do
RunService.Heartbeat:Wait()
if playId ~= myPlay then break end
local now = os.clock()
if now >= nextT then
local guard = 0
while now >= nextT and guard < n do
i = i % n + 1
nextT += delays[i]
guard += 1
end
if now >= nextT then nextT = now + delays[i] end
put(frames[i])
end
end
end)
end
return true
end
local function say(msg, bad)
if status and status.Parent then
status.Text = msg
status.TextColor3 = bad and Color3.fromRGB(240, 84, 84) or T.muted
end
end
local function fade(o, prop, v)
TS:Create(o, TweenInfo.new(.35, Enum.EasingStyle.Quad), {[prop] = v}):Play()
end
local function applyImage()
img.ScaleType = FITS[fit] or FITS[1]
if not hasImage then
fade(img, "ImageTransparency", 1)
fade(shade, "BackgroundTransparency", 1)
elseif style == 2 then
fade(img, "ImageTransparency", CLEAN[strength] or .12)
fade(shade, "BackgroundTransparency", DIMS[dim] or 1)
else
fade(img, "ImageTransparency", CLASSIC[strength] or .55)
fade(shade, "BackgroundTransparency", .45)
end
end
local touched = setmetatable({}, {__mode = "k"})
local function eligible(o)
if not (o:IsA("Frame") or o:IsA("TextButton") or o:IsA("ScrollingFrame") or o:IsA("TextBox")) then return false end
if o.BackgroundTransparency ~= 0 or o:GetAttribute("NoTheme") or o:GetAttribute("NoGlass") then return false end
local n = o.Name
if n == "Veil" or n:find("Wave") or n:find("Glow") or n:find("Popup") or n:find("Plugin") then return false end
if o.BackgroundColor3 == T.text then return false end
if o:FindFirstAncestor("BackgroundWaves") then return false end
if o:GetAttribute("Glass") then return true end
local s = o.AbsoluteSize
return s.X >= 40 and s.Y >= 20
end
local function currentPanelAlpha()
if not hasImage then return 0 end
return PANELS[panels] or 0
end
local token = 0
local function restorePanels()
for o, orig in pairs(touched) do
if o.Parent then o.BackgroundTransparency = orig end
end
touched = setmetatable({}, {__mode = "k"})
end
local function applyPanels()
token += 1
local my = token
local a = currentPanelAlpha()
if a == 0 then
restorePanels()
return
end
task.spawn(function()
local n = 0
for _, o in ipairs(main:GetDescendants()) do
if touched[o] == nil and eligible(o) then touched[o] = o.BackgroundTransparency end
if touched[o] ~= nil then o.BackgroundTransparency = a end
n += 1
if n % 120 == 0 then
task.wait()
if token ~= my then return end
end
end
end)
end
local function refresh()
applyImage()
applyPanels()
end
local queue, qHead = {}, 1
HyundaxIUM.connect(main.DescendantAdded, function(o)
if currentPanelAlpha() == 0 or #queue - qHead > 300 then return end
if not (o:IsA("Frame") or o:IsA("TextButton") or o:IsA("ScrollingFrame") or o:IsA("TextBox")) then return end
queue[#queue + 1] = {o, os.clock()}
end)
HyundaxIUM.connect(game:GetService("RunService").Heartbeat, function()
if qHead > #queue then
if #queue > 0 then queue, qHead = {}, 1 end
return
end
local a = currentPanelAlpha()
local now, done = os.clock(), 0
while qHead <= #queue and done < 20 do
local item = queue[qHead]
if now - item[2] < .15 then break end
qHead += 1
done += 1
local o = item[1]
if a > 0 and o.Parent and touched[o] == nil and eligible(o) then
touched[o] = o.BackgroundTransparency
o.BackgroundTransparency = a
end
end
end)
HyundaxIUM.onCleanup(function()
token += 1
panels = 1
clearImage()
restorePanels()
end)
local function pushRecent(url)
local list = HyundaxIUM.load("recent", {})
local out = {url}
for _, u in ipairs(list) do
if u ~= url and #out < 5 then out[#out + 1] = u end
end
HyundaxIUM.save("recent", out)
end
local function setImage(url, force, quiet)
url = tostring(url or ""):gsub("%s", "")
if url == "" then
clearImage()
refresh()
HyundaxIUM.save("url", "")
say("Background removed")
return
end
reqId += 1
local my = reqId
task.spawn(function()
say("Loading image...")
local path = url:lower():gsub("[%?#].*$", "")
if path:match("%.gif$") then
local body
if gifCache.url == url and gifCache.body and not force then
body = gifCache.body
else
body = HyundaxIUM.fetch(url)
if reqId ~= my then return end
if not body then
say("Could not download the GIF. Check the link.", true)
return
end
gifCache.url, gifCache.body = url, body
end
local cfg = GQ[gq] or GQ[3]
say("Decoding GIF...")
local lastPct = -1
local ok, frames, delays, w, h, stride, total = pcall(decodeGif, body, my, cfg, function(i, n)
local pct = math.floor(i * 100 / math.max(n, 1))
if pct ~= lastPct and pct % 5 == 0 then
lastPct = pct
say("Decoding GIF (" .. cfg.name .. ")... " .. pct .. "%")
end
end)
if reqId ~= my then return end
if not ok then
say("GIF error: " .. tostring(frames), true)
return
end
if not frames then
say(tostring(delays or "Could not read the GIF."), true)
return
end
if not playGif(frames, delays, w, h) then
say("Animated GIFs need EditableImage support in your executor.", true)
return
end
hasImage = true
refresh()
HyundaxIUM.save("url", url)
if not quiet then pushRecent(url) end
if stride > 1 then
say(string.format("GIF applied (%s, %dx%d, %d of %d frames kept to fit memory)", cfg.name, w, h, #frames, total))
else
say(string.format("GIF applied (%s, %dx%d, %d frames)", cfg.name, w, h, #frames))
end
return
end
local asset = HyundaxIUM.asset(url, force)
if reqId ~= my then return end
if not asset then
say("Could not load the image. Check the link (png, jpg or gif).", true)
return
end
stopPlayback()
img.Image = asset
hasImage = true
refresh()
HyundaxIUM.save("url", url)
if not quiet then pushRecent(url) end
say("Background applied")
end)
end
local acc = 0
HyundaxIUM.every(5, function()
local sec = SHOW_T[show] or 0
if sec == 0 then acc = 0 return end
acc += 5
if acc < sec then return end
acc = 0
local list = HyundaxIUM.load("recent", {})
if #list < 2 then return end
local cur, idx = HyundaxIUM.load("url", ""), 1
for i, u in ipairs(list) do if u == cur then idx = i end end
setImage(list[idx % #list + 1], false, true)
end)
local function setStyle(i)
style = i
HyundaxIUM.save("style", i)
panels = (i == 2) and 3 or 1
HyundaxIUM.save("panels", panels)
refresh()
end
local saved = HyundaxIUM.load("url", "")
if saved ~= "" then setImage(saved) end
task.delay(.6, refresh)
HyundaxIUM.addCommand("Image: Clean style", function() setStyle(2) end, "Image Personalization")
HyundaxIUM.addCommand("Image: Classic style", function() setStyle(1) end, "Image Personalization")
HyundaxIUM.addCommand("Image: Next recent image", function()
local list = HyundaxIUM.load("recent", {})
if #list < 2 then return HyundaxIUM.toast("Add at least 2 images first") end
setImage(list[2])
end, "Image Personalization")
HyundaxIUM.addCommand("Image: Remove background", function() setImage("") end, "Image Personalization")
HyundaxIUM.onOpen(function(body)
ui.label(body, "Paste a direct link to a png, jpg or gif (catbox.moe works great).", 10, T.muted)
local box = ui.input(body, "https://files.catbox.moe/abc123.png", HyundaxIUM.load("url", ""))
local row = ui.row(body, 4)
ui.button(row, "Apply", 84, true, function() setImage(box.Text, true) end)
ui.button(row, "Remove", 84, false, function() box.Text = "" setImage("") end)
ui.label(body, "GIF quality", 10, T.text)
ui.segmented(body, {"Low", "Medium", "High", "Ultra"}, gq, function(i)
gq = i
HyundaxIUM.save("gq", i)
local u = HyundaxIUM.load("url", "")
local p = u:lower():gsub("[%?#].*$", "")
if u ~= "" and p:match("%.gif$") then setImage(u, false, true) end
end)
ui.label(body, "Higher quality = sharper, smoother GIFs, but slower to load and uses more memory. Ultra may be heavy on phones.", 9, T.muted)
ui.label(body, "Style", 10, T.text)
ui.segmented(body, {"Classic", "Clean"}, style, setStyle)
ui.label(body, "Clean shows the full image with no dark layer and see-through panels.", 9, T.muted)
ui.label(body, "Image strength", 10, T.text)
ui.segmented(body, {"Soft", "Normal", "Full"}, strength, function(i)
strength = i
HyundaxIUM.save("alpha", i)
applyImage()
end)
ui.label(body, "Readability (dark layer)", 10, T.text)
ui.segmented(body, {"None", "Light", "Medium"}, dim, function(i)
dim = i
HyundaxIUM.save("dim", i)
applyImage()
end)
ui.label(body, "Panels", 10, T.text)
ui.segmented(body, {"Solid", "Glass", "Clear"}, panels, function(i)
panels = i
HyundaxIUM.save("panels", i)
applyPanels()
end)
ui.label(body, "Image fit", 10, T.text)
ui.segmented(body, {"Fill", "Fit", "Stretch"}, fit, function(i)
fit = i
HyundaxIUM.save("fit", i)
applyImage()
end)
ui.label(body, "Slideshow (rotates your recent images)", 10, T.text)
ui.segmented(body, {"Off", "30s", "90s", "5 min"}, show, function(i)
show = i
acc = 0
HyundaxIUM.save("show", i)
end)
local recent = HyundaxIUM.load("recent", {})
if #recent > 0 then
ui.label(body, "Recent images", 10, T.text)
for _, u in ipairs(recent) do
local short = u:gsub("^https?://", "")
if #short > 34 then short = short:sub(1, 31) .. "..." end
ui.button(body, short, 230, false, function()
box.Text = u
setImage(u)
end)
end
end
status = ui.label(body, "", 10, T.muted, {NoI18N = true})
end)
]==],
}
BUILTIN[#BUILTIN + 1] = {
id = "b_search", name = "Spotlight Search", creator = "Hyundax Team", builtin = true,
desc = "Search bar to jump to pages, settings, themes, recent scripts and plugin commands. Shortcut: Ctrl+K.",
code = [==[
local ui, T = HyundaxIUM.ui, HyundaxIUM.theme
local UIS = game:GetService("UserInputService")
local KIND_ICON = {Page = "home", Settings = "gear", Theme = "sparkle", Script = "file", Command = "bolt", Action = "play"}
local function collect(query)
local q = tostring(query or ""):lower()
local out = {}
local function add(kind, title, hint, run)
title = tostring(title)
local pos = (q == "") and 1 or title:lower():find(q, 1, true)
if not pos and q ~= "" and tostring(hint or ""):lower():find(q, 1, true) then pos = 50 end
if pos then out[#out + 1] = {kind = kind, title = title, hint = hint or "", run = run, score = pos * 1000 + #out} end
end
for _, pg in ipairs(HyundaxIUM.pages()) do
add("Page", pg, "Open page", function() HyundaxIUM.showPage(pg) end)
end
for _, tab in ipairs({"Appearance", "Interface", "Visual", "Fonts", "Window", "Editor", "Behavior", "Notifications", "Sound", "Privacy", "Profile", "Advanced", "Plugins"}) do
add("Settings", tab, "Settings tab", function() HyundaxIUM.showPage("Settings") HyundaxIUM.selectSettings(tab) end)
end
for _, th in ipairs(HyundaxIUM.themes()) do
add("Theme", th, "Apply theme", function() HyundaxIUM.setTheme(th) end)
end
add("Action", "Clear console", "Remove every console line", function() HyundaxIUM.clearConsole() end)
for _, r in ipairs(HyundaxIUM.recents()) do
local nm = tostring(r.name or "Script")
add("Script", nm, "Open in the editor", function() HyundaxIUM.newTab(nm:sub(1, 22), r.code or "") end)
end
for _, c in ipairs(HyundaxIUM.getCommands()) do add("Command", c.title, c.hint, c.run) end
table.sort(out, function(a, b) return a.score < b.score end)
return out
end
local function openSearch()
HyundaxIUM.popup("Search", 460, 380, function(body, close)
local box = ui.input(body, "Search pages, settings, themes, scripts, commands...", "", {
Position = UDim2.fromOffset(14, 0), Size = UDim2.new(1, -28, 0, 32), LayoutOrder = 0,
})
local list = ui.scroller(body, {
Position = UDim2.fromOffset(14, 42), Size = UDim2.new(1, -28, 1, -52), ScrollBarThickness = 3,
}, {ui.vlist(4)})
local current = {}
local function run(it)
close()
task.defer(function()
local ok, err = pcall(it.run)
if not ok then HyundaxIUM.log(err) end
end)
end
local function render(q)
for _, c in ipairs(list:GetChildren()) do
if c:IsA("GuiObject") then c:Destroy() end
end
current = collect(q)
if #current == 0 then
ui.text(list, "Nothing found.", 11, "Regular", T.muted, {Size = UDim2.new(1, 0, 0, 20)})
return
end
for i = 1, math.min(#current, 40) do
local it = current[i]
local row = ui.new("TextButton", {
Size = UDim2.new(1, 0, 0, 38), BackgroundColor3 = (i == 1) and T.panel2 or T.cardTop,
AutoButtonColor = false, Text = "", LayoutOrder = i, Parent = list,
}, {ui.round(9), ui.stroke((i == 1) and T.bronzeLo or T.line)})
ui.chip(row, KIND_ICON[it.kind] or "file", 26, T.gold, UDim2.fromOffset(6, 6))
ui.text(row, it.title, 11, "SemiBold", T.text, {
Position = UDim2.fromOffset(40, 4), Size = UDim2.new(1, -120, 0, 16),
TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true,
})
ui.text(row, it.hint, 9, "Regular", T.muted, {
Position = UDim2.fromOffset(40, 20), Size = UDim2.new(1, -120, 0, 14), TextTruncate = Enum.TextTruncate.AtEnd,
})
ui.text(row, it.kind:upper(), 8, "Bold", T.tan, {
AnchorPoint = Vector2.new(1, .5), Position = UDim2.new(1, -10, .5, 0), Size = UDim2.fromOffset(70, 12),
TextXAlignment = Enum.TextXAlignment.Right,
})
ui.pressFx(row, .97)
row.Activated:Connect(function() run(it) end)
end
end
box:GetPropertyChangedSignal("Text"):Connect(function() render(box.Text) end)
box.FocusLost:Connect(function(enter)
if enter and current[1] then run(current[1]) end
end)
render("")
task.defer(function()
if box.Parent then box:CaptureFocus() end
end)
end)
end
HyundaxIUM.addTitleButton("search", openSearch)
HyundaxIUM.addCommand("Open search", openSearch, "Spotlight Search")
HyundaxIUM.connect(UIS.InputBegan, function(input, processed)
if processed or not HyundaxIUM.root.Visible then return end
if input.KeyCode == Enum.KeyCode.K and (UIS:IsKeyDown(Enum.KeyCode.LeftControl) or UIS:IsKeyDown(Enum.KeyCode.RightControl)) then
openSearch()
end
end)
HyundaxIUM.onOpen(function(body, close)
ui.label(body, "Press Ctrl+K or tap the search button in the title bar to open the search.", 11, HyundaxIUM.theme.muted)
ui.button(body, "Open search", 110, true, function()
close()
openSearch()
end)
end)
]==],
}
BUILTIN[#BUILTIN + 1] = {
id = "b_neon", name = "Neon Border", creator = "Hyundax Team", builtin = true,
desc = "Animated glowing border with Rainbow, Theme, Ice, Sunset and Mint modes plus a breathing glow.",
code = [==[
local ui, T = HyundaxIUM.ui, HyundaxIUM.theme
local RS = game:GetService("RunService")
local stroke = HyundaxIUM.borderStroke
local grad = stroke and stroke:FindFirstChildOfClass("UIGradient")
if not grad then
HyundaxIUM.toast("Neon Border: window border not found")
return
end
local oldColor, oldThickness = grad.Color, stroke.Thickness
local SPEEDS, THICK = {.05, .12, .3}, {1.4, 2.4, 3.6}
local RANGES = {[3] = {.48, .66}, [4] = {.88, 1.08}, [5] = {.25, .45}}
local mode = HyundaxIUM.load("mode", 1)
local speed, thick = HyundaxIUM.load("speed", 2), HyundaxIUM.load("thick", 2)
local pulse = HyundaxIUM.load("pulse", true)
local sat = HyundaxIUM.load("sat", 2)
local rev = HyundaxIUM.load("rev", false)
local SATS = {.45, .75}
stroke.Thickness = THICK[thick] or 2.4
HyundaxIUM.connect(RS.Heartbeat, function()
local clock = os.clock()
local t = clock * (SPEEDS[speed] or .12) * (rev and -1 or 1)
local keys = {}
for i = 0, 4 do
local c
if mode == 1 then
c = Color3.fromHSV((t + i * .2) % 1, SATS[sat] or .75, 1)
else
local wave = .5 + .5 * math.sin(t * 6.283 + i * 1.5708)
if mode == 2 then
c = T.bronze:Lerp(T.gold, wave)
else
local r = RANGES[mode] or RANGES[3]
c = Color3.fromHSV((r[1] + (r[2] - r[1]) * wave) % 1, SATS[sat] or .7, 1)
end
end
keys[#keys + 1] = ColorSequenceKeypoint.new(i / 4, c)
end
grad.Color = ColorSequence.new(keys)
if pulse then
stroke.Thickness = (THICK[thick] or 2.4) * (1 + .22 * math.sin(clock * 2.2))
end
end)
HyundaxIUM.onCleanup(function()
grad.Color = oldColor
stroke.Thickness = oldThickness
end)
HyundaxIUM.addCommand("Neon: next color mode", function()
mode = mode % 5 + 1
HyundaxIUM.save("mode", mode)
end, "Neon Border")
HyundaxIUM.onOpen(function(body)
ui.label(body, "Color mode", 10, T.text)
ui.segmented(body, {"Rainbow", "Theme", "Ice", "Sunset", "Mint"}, mode, function(i)
mode = i
HyundaxIUM.save("mode", i)
end)
ui.label(body, "Speed", 10, T.text)
ui.segmented(body, {"Slow", "Normal", "Fast"}, speed, function(i)
speed = i
HyundaxIUM.save("speed", i)
end)
ui.label(body, "Thickness", 10, T.text)
ui.segmented(body, {"Thin", "Normal", "Thick"}, thick, function(i)
thick = i
stroke.Thickness = THICK[i]
HyundaxIUM.save("thick", i)
end)
ui.label(body, "Saturation", 10, T.text)
ui.segmented(body, {"Soft", "Vivid"}, sat, function(i)
sat = i
HyundaxIUM.save("sat", i)
end)
ui.switch(body, "Reverse direction", rev, function(v)
rev = v
HyundaxIUM.save("rev", v)
end)
ui.switch(body, "Breathing glow", pulse, function(v)
pulse = v
if not v then stroke.Thickness = THICK[thick] end
HyundaxIUM.save("pulse", v)
end)
end)
]==],
}
BUILTIN[#BUILTIN + 1] = {
id = "b_packs", name = "Theme Packs", creator = "Hyundax Team", builtin = true,
desc = "Seven ready-made themes (Ocean, Sakura, Emerald, Crimson, Violet, Sunset, Amoled) with optional day/night auto switch.",
code = [==[
local ui, T = HyundaxIUM.ui, HyundaxIUM.theme
local function C(h, s, v) return Color3.fromHSV(h % 1, math.clamp(s, 0, 1), math.clamp(v, 0, 1)) end
local function make(h, s, amoled)
local k = amoled and .35 or 1
return {
bg = amoled and Color3.new(0, 0, 0) or C(h, s * .55, .07),
side = amoled and C(h, s * .4, .03) or C(h, s * .55, .09),
panel = C(h, s * .5, .12 * k + (amoled and .03 or 0)),
panel2 = C(h, s * .5, .16 * k + (amoled and .05 or 0)),
line = C(h, s * .45, .24 * k + (amoled and .08 or 0)),
text = C(h, .06, .96), muted = C(h, .18, .68),
bronze = C(h, s, .85), bronzeHi = C(h, s * .7, 1), bronzeLo = C(h, s, .55),
gold = C(h + .04, s * .7, 1), dark = C(h, s * .6, .04), glow = C(h, s, 1),
cardTop = C(h, s * .5, .14 * k + (amoled and .04 or 0)), tan = C(h, s * .35, .82),
}
end
local PACKS = {
{"Midnight Ocean", .58, .8, "Deep blue with icy highlights."},
{"Sakura", .94, .45, "Soft pink on a calm dark base."},
{"Emerald Forest", .4, .75, "Rich green, easy on the eyes."},
{"Crimson Night", .99, .85, "Blood red on near black."},
{"Violet Dream", .75, .7, "Purple neon vibes."},
{"Sunset", .07, .8, "Warm orange glow."},
{"Mocha", .08, .38, "Coffee browns, cozy and warm."},
{"Arctic", .53, .4, "Cold, clean and crisp."},
{"Cyber Mint", .45, .95, "Neon mint on dark."},
{"Rose Gold", .02, .5, "Elegant rose tones."},
{"Slate", .6, .18, "Neutral grey-blue, minimal."},
{"Pure Amoled", .58, .55, "True black, saves battery on OLED.", true},
}
local names = {}
for _, p in ipairs(PACKS) do
local ok = HyundaxIUM.addTheme(p[1], p[4], make(p[2], p[3], p[5]))
if ok then names[#names + 1] = p[1] end
HyundaxIUM.addCommand("Theme: " .. p[1], function() HyundaxIUM.setTheme(p[1]) end, "Theme Packs")
end
local prev = HyundaxIUM.load("prev")
if not prev then
prev = HyundaxIUM.currentTheme()
HyundaxIUM.save("prev", prev)
end
HyundaxIUM.onCleanup(function()
HyundaxIUM.save("prev", nil)
HyundaxIUM.setTheme(prev)
end)
local auto = HyundaxIUM.load("auto", 1)
local shuffleAcc = 0
local lastAuto
local function randomPack()
local p = PACKS[math.random(1, #PACKS)]
HyundaxIUM.setTheme(p[1])
HyundaxIUM.toast(p[1])
end
local function tick()
if auto == 3 then
shuffleAcc += 60
if shuffleAcc >= 300 then shuffleAcc = 0 randomPack() end
return
end
if auto ~= 2 then return end
local h = tonumber(os.date("%H")) or 12
local want = (h >= 19 or h < 6) and "Midnight Ocean" or "Sunset"
if want ~= lastAuto then
lastAuto = want
HyundaxIUM.setTheme(want)
end
end
HyundaxIUM.every(60, tick)
HyundaxIUM.addCommand("Theme: random pack", randomPack, "Theme Packs")
task.delay(1, tick)
HyundaxIUM.onOpen(function(body)
ui.label(body, "Pick a theme pack to apply it instantly.", 10, T.muted)
ui.button(body, "Surprise me", 130, true, randomPack)
local row
for i, p in ipairs(PACKS) do
if i % 2 == 1 then row = ui.row(body, 4) end
ui.button(row, p[1], 150, false, function()
HyundaxIUM.setTheme(p[1])
HyundaxIUM.toast(p[1])
end)
end
ui.label(body, "Automatic", 10, T.text)
ui.segmented(body, {"Manual", "Day / Night", "Shuffle"}, auto, function(i)
auto = i
lastAuto, shuffleAcc = nil, 0
HyundaxIUM.save("auto", i)
tick()
end)
ui.label(body, "Day / Night uses Sunset by day and Midnight Ocean after 7 PM. Shuffle swaps every 5 min.", 9, T.muted)
end)
]==],
}
BUILTIN[#BUILTIN + 1] = {
id = "b_studio", name = "Accent Studio", creator = "Hyundax Team", builtin = true,
desc = "Create your own theme: pick color, saturation and background depth.",
code = [==[
local ui, T = HyundaxIUM.ui, HyundaxIUM.theme
local NAME = "Accent Studio"
local HUES = {"Red", "Orange", "Gold", "Green", "Cyan", "Blue", "Purple", "Pink"}
local HV = {0, .06, .12, .38, .5, .6, .76, .9}
local DEPTH = {"Light", "Normal", "Deep"}
local DV = {1.6, 1, .6}
local SAT = {"Muted", "Vivid", "Neon"}
local SV = {.45, .75, .95}
local ACC = {"Match", "Warm", "Cool"}
local AV = {.04, -.06, .12}
local hue, depth, sat = HyundaxIUM.load("hue", 6), HyundaxIUM.load("depth", 2), HyundaxIUM.load("sat", 2)
local accent = HyundaxIUM.load("accent", 1)
local prev = HyundaxIUM.load("prev")
if not prev then
prev = HyundaxIUM.currentTheme()
HyundaxIUM.save("prev", prev)
end
local function C(h, s, v) return Color3.fromHSV(h % 1, math.clamp(s, 0, 1), math.clamp(v, 0, 1)) end
local function palette()
local h, s, d = HV[hue] or .6, SV[sat] or .75, DV[depth] or 1
return {
bg = C(h, s * .55, .07 * d), side = C(h, s * .55, .09 * d),
panel = C(h, s * .5, .12 * d), panel2 = C(h, s * .5, .16 * d),
line = C(h, s * .45, .24 * d), text = C(h, .06, .96), muted = C(h, .18, .68),
bronze = C(h, s, .85), bronzeHi = C(h, s * .7, 1), bronzeLo = C(h, s, .55),
gold = C(h + (AV[accent] or .04), s * .7, 1), dark = C(h, s * .6, .04), glow = C(h, s, 1),
cardTop = C(h, s * .5, .14 * d), tan = C(h, s * .35, .82),
}
end
local function apply()
HyundaxIUM.addTheme(NAME, "Your own accent, built in Accent Studio.", palette())
HyundaxIUM.setTheme(NAME)
end
HyundaxIUM.onCleanup(function()
HyundaxIUM.save("prev", nil)
HyundaxIUM.setTheme(prev)
end)
local function persist()
HyundaxIUM.save("hue", hue) HyundaxIUM.save("depth", depth) HyundaxIUM.save("sat", sat) HyundaxIUM.save("accent", accent)
end
if HyundaxIUM.load("applied", false) then
HyundaxIUM.addTheme(NAME, "Your own accent, built in Accent Studio.", palette())
else
HyundaxIUM.save("applied", true)
apply()
end
HyundaxIUM.addCommand("Accent Studio: randomize", function()
hue, depth, sat = math.random(1, #HUES), math.random(1, 3), math.random(1, 3)
accent = math.random(1, 3)
persist()
apply()
end, "Accent Studio")
HyundaxIUM.onOpen(function(body)
ui.label(body, "Build your own theme from three sliders.", 10, T.muted)
ui.label(body, "Color", 10, T.text)
ui.segmented(body, HUES, hue, function(i) hue = i persist() apply() end)
ui.label(body, "Saturation", 10, T.text)
ui.segmented(body, SAT, sat, function(i) sat = i persist() apply() end)
ui.label(body, "Background depth", 10, T.text)
ui.segmented(body, DEPTH, depth, function(i) depth = i persist() apply() end)
ui.label(body, "Highlight tone", 10, T.text)
ui.segmented(body, ACC, accent, function(i) accent = i persist() apply() end)
ui.label(body, "My presets", 10, T.text)
local slots = HyundaxIUM.load("slots", {})
local row = ui.row(body, 4)
for n = 1, 3 do
ui.button(row, slots[n] and ("Load " .. n) or ("Save " .. n), 90, slots[n] ~= nil, function()
if slots[n] then
local p = slots[n]
hue, depth, sat, accent = p[1], p[2], p[3], p[4]
persist()
apply()
else
slots[n] = {hue, depth, sat, accent}
HyundaxIUM.save("slots", slots)
HyundaxIUM.toast("Saved to slot " .. n .. ". Reopen to load it.")
end
end)
end
ui.button(body, "Clear presets", 110, false, function()
slots = {}
HyundaxIUM.save("slots", {})
HyundaxIUM.toast("Presets cleared")
end)
end)
]==],
}
local SHARE_PREFIX = "SPARTAPLUGIN1:"
local function shareString(p)
local ok, js = pcall(function() return game:GetService("HttpService"):JSONEncode({n = p.name, c = p.code, d = p.desc}) end)
return SHARE_PREFIX .. (ok and js or "")
end
local function parseShare(str)
str = trim(str)
if str:sub(1, #SHARE_PREFIX) ~= SHARE_PREFIX then return nil end
local ok, t = pcall(function() return game:GetService("HttpService"):JSONDecode(str:sub(#SHARE_PREFIX + 1)) end)
if ok and type(t) == "table" and type(t.n) == "string" and type(t.c) == "string" then
local code = t.c
if type(t.d) == "string" and not code:match("^%s*%-%-%s*desc:") then code = "-- desc: " .. t.d .. "\n" .. code end
return t.n, code
end
end
local function installCode(nm, code, noStart)
nm = trim(nm)
if #nm > 28 then nm = nm:sub(1, 28) end
local creator = I18N.shownName()
if type(creator) ~= "string" or creator == "" then creator = lp.Name end
local entry
for _, p in ipairs(data.custom) do
if p.name:lower() == nm:lower() then entry = p end
end
if entry then
stopPlugin(entry.id)
entry.name, entry.code, entry.creator, entry.username, entry.userId = nm, code, creator, lp.Name, lp.UserId
entry.updated = os.time()
else
entry = {
id = "c" .. os.time() .. math.random(100, 999), name = nm, code = code, creator = creator,
username = lp.Name, userId = lp.UserId, created = os.time(),
}
table.insert(data.custom, 1, entry)
end
errors[entry.id] = nil
local ok, err = true, nil
if noStart then
data.enabled[entry.id] = false
else
ok, err = startPlugin(entry)
data.enabled[entry.id] = ok == true
if not ok then
errors[entry.id] = tostring(err)
addLine("Console", "[plugin:" .. nm .. "] " .. tostring(err), T.bronzeHi)
toast("Plugin error, see Console")
end
end
save()
refreshList()
return entry, ok
end
local function genThemeCode(name, pal, url, strength)
name = name:gsub("[\r\n]", " ")
local L = {}
L[#L + 1] = "-- desc: Theme " .. name .. (url ~= "" and " (colors + background image)" or " (colors)")
L[#L + 1] = "local NAME = " .. string.format("%q", name)
L[#L + 1] = "local pal = {"
for _, r in ipairs(ROLES) do
local v = pal[r]
if v then L[#L + 1] = string.format("\t%s = {%d, %d, %d},", r, v[1], v[2], v[3]) end
end
L[#L + 1] = "}"
L[#L + 1] = 'local prev = HyundaxIUM.load("prev")'
L[#L + 1] = 'if not prev then prev = HyundaxIUM.currentTheme() HyundaxIUM.save("prev", prev) end'
L[#L + 1] = 'HyundaxIUM.addTheme(NAME, "Exported theme.", pal)'
L[#L + 1] = "HyundaxIUM.setTheme(NAME)"
if url ~= "" then L[#L + 1] = "HyundaxIUM.background(" .. string.format("%q", url) .. ", " .. tostring(strength) .. ")" end
L[#L + 1] = "HyundaxIUM.onCleanup(function()"
L[#L + 1] = '\tHyundaxIUM.save("prev", nil)'
L[#L + 1] = "\tHyundaxIUM.setTheme(prev)"
L[#L + 1] = "end)"
return table.concat(L, "\n") .. "\n"
end
local function allPlugins()
local list = {}
for _, p in ipairs(data.custom) do list[#list + 1] = p end
for _, p in ipairs(BUILTIN) do list[#list + 1] = p end
return list
end
local function descOf(p)
if p.desc then return p.desc, false end
local d = p.code:match("^%s*%-%-%s*desc:%s*([^\r\n]+)")
if d then return d, true end
return "Custom plugin.", false
end
local function danger(b)
local red, redHi = Color3.fromRGB(214, 48, 49), Color3.fromRGB(240, 84, 84)
b.BackgroundColor3, b.TextColor3 = red, Color3.new(1, 1, 1)
local bs = b:FindFirstChildOfClass("UIStroke")
if bs then bs.Color = redHi end
b.MouseEnter:Connect(function() tween(b, {BackgroundColor3 = redHi}, .15) end)
b.MouseLeave:Connect(function() tween(b, {BackgroundColor3 = red}, .2) end)
b.MouseButton1Up:Connect(function() b.BackgroundColor3 = red end)
end
local GREEN, GREEN_HI, GREEN_BG = Color3.fromRGB(88, 224, 140), Color3.fromRGB(46, 160, 98), Color3.fromRGB(20, 56, 38)
local function makeCard(parent, p, order)
local on = data.enabled[p.id] == true
local ctx = running[p.id]
local function rest() return (data.enabled[p.id] == true) and T.bronzeLo or T.line end
local c = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.cardTop,
BorderSizePixel = 0, LayoutOrder = order, Parent = parent,
}, {round(12), stroke(rest(), 1.2), pad(12, 12, 12, 12), vlist(8)})
FX.sheen(c)
local cst = c:FindFirstChildOfClass("UIStroke")
c.MouseEnter:Connect(function() tween(cst, {Color = T.bronze}, .2) end)
c.MouseLeave:Connect(function() tween(cst, {Color = rest()}, .25) end)
local head = new("Frame", {Size = UDim2.new(1, 0, 0, 32), BackgroundTransparency = 1, LayoutOrder = 1, Parent = c})
FX.chip(head, p.builtin and "star" or "code", 32, T.gold, UDim2.fromOffset(0, 0))
text(head, p.name, 13, "Bold", T.text, {
Position = UDim2.fromOffset(42, 0), Size = UDim2.new(1, -104, 0, 17),
TextTruncate = Enum.TextTruncate.AtEnd, NoI18N = true,
})
local by = new("Frame", {Position = UDim2.fromOffset(42, 18), Size = UDim2.new(1, -104, 0, 14), BackgroundTransparency = 1, Parent = head}, {hlist(4)})
text(by, "Created by", 9, "Regular", T.muted, {Size = UDim2.fromOffset(0, 14), AutomaticSize = Enum.AutomaticSize.X, LayoutOrder = 1})
local who = tostring(p.creator or "Unknown")
if not p.builtin and p.username and tostring(p.username):lower() ~= who:lower() then who = who .. " @" .. tostring(p.username) end
text(by, who, 9, "Bold", T.gold, {Size = UDim2.fromOffset(0, 14), AutomaticSize = Enum.AutomaticSize.X, LayoutOrder = 2, NoI18N = true})
local tags = new("Frame", {Size = UDim2.new(1, 0, 0, 16), BackgroundTransparency = 1, LayoutOrder = 2, Parent = c}, {hlist(5)})
local function pillLabel(txt, bg, fg, sc, ord)
return new("TextLabel", {
Size = UDim2.fromOffset(0, 16), AutomaticSize = Enum.AutomaticSize.X, BackgroundColor3 = bg, BorderSizePixel = 0,
Text = txt, TextSize = 8, FontFace = F.Bold, TextColor3 = fg, LayoutOrder = ord, Parent = tags, NoI18N = true,
}, {round(8), stroke(sc, 1), pad(8, 0, 8, 0)})
end
pillLabel(p.builtin and "OFFICIAL" or "CUSTOM", T.glow, T.gold, T.bronzeLo, 1)
local pill = pillLabel("ACTIVE", GREEN_BG, GREEN, GREEN_HI, 2)
pill.Visible = on
local function paintState(v)
pill.Visible = v
tween(cst, {Color = v and T.bronzeLo or T.line}, .25)
end
makeToggle(head, on, function(want)
if want then
errors[p.id] = nil
local ok, err = startPlugin(p)
if not ok then
errors[p.id] = tostring(err)
addLine("Console", "[plugin:" .. p.name .. "] " .. tostring(err), T.bronzeHi)
toast("Plugin error, see Console")
task.defer(refreshList)
return false
end
data.enabled[p.id] = true
paintState(true)
toast("Plugin enabled")
else
stopPlugin(p.id)
data.enabled[p.id] = false
paintState(false)
toast("Plugin disabled")
end
save()
task.delay(.6, refreshList)
end)
local desc, rawDesc = descOf(p)
text(c, desc, 10, "Regular", T.muted, {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, TextWrapped = true,
TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = 3, NoI18N = (not p.builtin and rawDesc) or nil,
})
if errors[p.id] then
new("TextLabel", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = Color3.fromRGB(58, 20, 22),
BorderSizePixel = 0, Text = tostring(errors[p.id]), TextSize = 9, FontFace = F.Regular,
TextColor3 = Color3.fromRGB(240, 110, 110), TextWrapped = true, TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = 4, Parent = c, NoI18N = true,
}, {round(8), stroke(Color3.fromRGB(214, 48, 49), 1), pad(9, 7, 9, 7)})
end
new("Frame", {Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = T.line, BorderSizePixel = 0, LayoutOrder = 5, Parent = c})
local brow = new("Frame", {Size = UDim2.new(1, 0, 0, 24), BackgroundTransparency = 1, LayoutOrder = 6, Parent = c}, {hlist(4)})
local n = 0
local function btn(label, w, primary, cb)
n = n + 1
local b = mini(brow, label, w, primary, cb)
b.LayoutOrder = n
return b
end
if ctx and ctx.openFn then
btn("Open", 64, true, function()
local live = running[p.id]
if not live or not live.openFn then return end
openPopup(p.name, 440, 380, function(body, close)
local sc = scroller(body, {}, {pad(14), vlist(8)})
live.openFn(sc, close)
end, p.id, true, p.creator)
end)
end
btn("Copy", 58, false, function()
local ok = pcall(setclipboard, p.code)
toast(ok and "Code copied" or "setclipboard unavailable")
end)
if not p.builtin then
btn("Edit", 58, false, function()
if formName and formCode then
formName.Text, formCode.Text = p.name, p.code
editingId = p.id
refreshBanner()
toast("Editing plugin: press Post to update it")
pcall(function() formName:FindFirstAncestorWhichIsA("ScrollingFrame").CanvasPosition = Vector2.new(0, 0) end)
end
end)
local del
local armed = false
del = btn("Delete", 66, false, function()
if not armed then
armed = true
del.Text = "Sure?"
task.delay(2.5, function()
if del and del.Parent then
armed = false
del.Text = "Delete"
end
end)
return
end
stopPlugin(p.id)
for i, q in ipairs(data.custom) do
if q.id == p.id then table.remove(data.custom, i) break end
end
data.enabled[p.id], data.store[p.id], errors[p.id] = nil, nil, nil
if editingId == p.id then editingId = nil refreshBanner() end
save()
toast("Plugin deleted")
refreshList()
end)
danger(del)
end
local brow2 = new("Frame", {Size = UDim2.new(1, 0, 0, 24), BackgroundTransparency = 1, LayoutOrder = 7, Parent = c}, {hlist(4)})
local m = 0
local function btn2(label, w, cb)
m = m + 1
local b = mini(brow2, label, w, false, cb)
b.LayoutOrder = m
return b
end
if ctx then
btn2("Reload", 66, function()
stopPlugin(p.id)
errors[p.id] = nil
local ok, err = startPlugin(p)
if not ok then
errors[p.id] = tostring(err)
data.enabled[p.id] = false
save()
end
toast(ok and "Plugin reloaded" or "Plugin error, see Console")
task.defer(refreshList)
end)
end
btn2("Share", 58, function()
local ok = pcall(setclipboard, shareString(p))
toast(ok and "Share code copied" or "setclipboard unavailable")
end)
btn2("Duplicate", 78, function()
local base, k, nm = p.name, 1, p.name .. " Copy"
while true do
local used = false
for _, q in ipairs(data.custom) do if q.name:lower() == nm:lower() then used = true end end
if not used then break end
k = k + 1
nm = base .. " Copy " .. k
end
local code = p.code
if p.desc and not code:match("^%s*%-%-%s*desc:") then code = "-- desc: " .. p.desc .. "\n" .. code end
installCode(nm, code, true)
toast("Plugin posted")
end)
end
local function doPost(nameBox, codeBox)
local nm = trim(nameBox.Text)
local code = codeBox.Text
if nm == "" or trim(code) == "" then toast("Name and code are required") return end
if #nm > 28 then nm = nm:sub(1, 28) end
local ls = loadstring
if ls then
local fn, err = ls("local HyundaxIUM, Plugin = ...; local HyundaxX = HyundaxIUM; local Sparta = HyundaxIUM; " .. code)
if not fn then
addLine("Console", "[plugin:" .. nm .. "] " .. tostring(err), T.bronzeHi)
toast("Syntax error in plugin code")
return
end
end
local creator = I18N.shownName()
if type(creator) ~= "string" or creator == "" then creator = lp.Name end
local entry
if editingId then
for _, p in ipairs(data.custom) do
if p.id == editingId then entry = p end
end
end
if not entry then
for _, p in ipairs(data.custom) do
if p.name:lower() == nm:lower() then entry = p end
end
end
if entry then
stopPlugin(entry.id)
entry.name, entry.code, entry.creator, entry.username, entry.userId = nm, code, creator, lp.Name, lp.UserId
entry.updated = os.time()
else
entry = {
id = "c" .. os.time() .. math.random(100, 999), name = nm, code = code, creator = creator,
username = lp.Name, userId = lp.UserId, created = os.time(),
}
table.insert(data.custom, 1, entry)
end
editingId = nil
refreshBanner()
errors[entry.id] = nil
local ok, err = startPlugin(entry)
data.enabled[entry.id] = ok == true
if ok then
toast("Plugin posted")
else
errors[entry.id] = tostring(err)
addLine("Console", "[plugin:" .. nm .. "] " .. tostring(err), T.bronzeHi)
toast("Plugin error, see Console")
end
save()
nameBox.Text, codeBox.Text = "", ""
refreshList()
end
local TEMPLATE = "-- desc: Example plugin with a title bar button and a command\nHyundaxIUM.addTitleButton(\"bolt\", function()\n\tHyundaxIUM.toast(\"Hello from \" .. Plugin.name .. \" by \" .. Plugin.creator .. \"!\")\nend)\nHyundaxIUM.addCommand(\"Say hello\", function() HyundaxIUM.toast(\"Hello!\") end, Plugin.name)\n"
local listHolder, filterBox
local filterMode = 1
local statNum = {}
local function refreshStats()
local total, active = 0, 0
for _, p in ipairs(allPlugins()) do
total = total + 1
if data.enabled[p.id] == true then active = active + 1 end
end
local function put(k, v)
local l = statNum[k]
if l and l.Parent then l.Text = tostring(v) end
end
put("total", total) put("active", active) put("custom", #data.custom)
end
refreshList = function()
if not listHolder or not listHolder.Parent then return end
for _, ch in ipairs(listHolder:GetChildren()) do
if ch:IsA("GuiObject") then ch:Destroy() end
end
refreshStats()
local q = ((filterBox and filterBox.Text) or ""):lower()
local n = 0
for _, p in ipairs(allPlugins()) do
local hay = (p.name .. " " .. tostring(p.creator or "")):lower()
local modeOk = filterMode == 1
or (filterMode == 2 and data.enabled[p.id] == true)
or (filterMode == 3 and p.builtin == true)
or (filterMode == 4 and not p.builtin)
if modeOk and (q == "" or hay:find(q, 1, true)) then
n = n + 1
makeCard(listHolder, p, n)
end
end
if n == 0 then
local empty = new("Frame", {
Size = UDim2.new(1, 0, 0, 96), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = 1, Parent = listHolder,
}, {round(12), stroke(T.line)})
FX.chip(empty, "layers", 34, T.muted, UDim2.new(.5, -17, 0, 14))
text(empty, "No plugins found.", 11, "SemiBold", T.muted, {
Position = UDim2.fromOffset(0, 58), Size = UDim2.new(1, 0, 0, 16), TextXAlignment = Enum.TextXAlignment.Center,
})
end
end
local function buildPlugins(pane)
local nav = new("Frame", {
Position = UDim2.fromOffset(0, 0), Size = UDim2.new(1, 0, 0, SUB_H),
BackgroundTransparency = 1, Parent = pane,
})
new("Frame", {Position = UDim2.new(0, 0, 1, -1), Size = UDim2.new(1, 0, 0, 1), BackgroundColor3 = Color3.new(1, 1, 1), BorderSizePixel = 0, Parent = nav}, {
new("UIGradient", {Color = ColorSequence.new({ColorSequenceKeypoint.new(0, T.bronzeLo), ColorSequenceKeypoint.new(1, T.line)}), Transparency = NumberSequence.new({NumberSequenceKeypoint.new(0, .2), NumberSequenceKeypoint.new(1, 1)})})
})
local indicator = new("Frame", {Position = UDim2.fromOffset(PILL_X + 18, SUB_H - 3), Size = UDim2.fromOffset(PILL_W - 36, 2), BackgroundColor3 = T.gold, BorderSizePixel = 0, ZIndex = 3, Parent = nav}, {round(1)})
local browsePane = new("Frame", {
Position = UDim2.new(0, 0, 0, SUB_H), Size = UDim2.new(1, 0, 1, -SUB_H),
BackgroundTransparency = 1, Parent = pane,
})
local createPane = new("Frame", {
Position = UDim2.new(0, 0, 0, SUB_H), Size = UDim2.new(1, 0, 1, -SUB_H),
BackgroundTransparency = 1, Visible = false, Parent = pane,
})
local function makeSubtab(label, ico, index)
local btn = new("TextButton", {
Position = UDim2.fromOffset(PILL_X + (index - 1) * (PILL_W + PILL_GAP), 2),
Size = UDim2.fromOffset(PILL_W, SUB_H - 7), BackgroundColor3 = T.glow,
BackgroundTransparency = 1, AutoButtonColor = false, Text = "", Parent = nav,
}, {round(9), stroke(T.bronzeLo, 1)})
btn:FindFirstChildOfClass("UIStroke").Transparency = 1
local inner = new("Frame", {Size = UDim2.fromScale(1, 1), BackgroundTransparency = 1, Parent = btn}, {hlist(6, nil, Enum.HorizontalAlignment.Center)})
local ic = icon(inner, ico, 12, T.muted, 1.4)
ic.holder.LayoutOrder = 1
local lbl = text(inner, I18N.tr(label), 11, "SemiBold", T.muted, {AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 14), LayoutOrder = 2})
pressFx(btn, .98)
return {btn = btn, ic = ic, lbl = lbl, stroke = btn:FindFirstChildOfClass("UIStroke")}
end
local browseTab = makeSubtab("Explore / activate", "layers", 1)
local createTab = makeSubtab("Create / export", "plus", 2)
local function selectSubtab(which)
local browsing = which == "browse"
browsePane.Visible, createPane.Visible = browsing, not browsing
for i, tab in ipairs({browseTab, createTab}) do
local on = (i == 1 and browsing) or (i == 2 and not browsing)
tab.ic.set(on and T.gold or T.muted, .25)
tween(tab.lbl, {TextColor3 = on and T.text or T.muted}, .25)
tween(tab.btn, {BackgroundTransparency = on and 0 or 1}, .25)
tween(tab.stroke, {Transparency = on and .45 or 1}, .25)
end
tween(indicator, {Position = UDim2.fromOffset(PILL_X + (browsing and 0 or 1) * (PILL_W + PILL_GAP) + 18, SUB_H - 3)}, .5, Enum.EasingStyle.Back)
end
browseTab.btn.Activated:Connect(function() selectSubtab("browse") end)
createTab.btn.Activated:Connect(function() selectSubtab("create") end)
local sc = scroller(browsePane, {}, {pad(14), vlist(10)})
local createSc = scroller(createPane, {}, {pad(14), vlist(10)})
E.heading(sc, "Plugins", "Search and manage installed plugins", "layers", 1)
E.heading(createSc, "Create / export", "Publish plugins or turn your theme into a plugin", "plus", 1)
local stats = new("Frame", {Size = UDim2.new(1, 0, 0, 54), BackgroundTransparency = 1, LayoutOrder = 2, Parent = sc}, {hlist(8)})
local function tile(i, key, label, color)
local t = new("Frame", {
Size = UDim2.new(1 / 3, -6, 1, 0), BackgroundColor3 = T.cardTop, BorderSizePixel = 0, LayoutOrder = i, Parent = stats,
}, {round(12), stroke(T.line)})
FX.sheen(t)
statNum[key] = text(t, "0", 20, "Bold", color, {Position = UDim2.fromOffset(12, 5), Size = UDim2.new(1, -24, 0, 24), NoI18N = true})
text(t, label, 10, "SemiBold", T.muted, {Position = UDim2.fromOffset(12, 31), Size = UDim2.new(1, -24, 0, 14)})
end
tile(1, "total", "Installed", T.text)
tile(2, "active", "Active", GREEN)
tile(3, "custom", "Custom", T.gold)
local postCard = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.cardTop,
BorderSizePixel = 0, LayoutOrder = 3, Parent = createSc,
}, {round(12), stroke(T.line), pad(12), vlist(8)})
FX.sheen(postCard)
local ph = new("Frame", {Size = UDim2.new(1, 0, 0, 30), BackgroundTransparency = 1, LayoutOrder = nextOrder(postCard), Parent = postCard})
FX.chip(ph, "plus", 28, T.gold, UDim2.fromOffset(0, 1))
text(ph, "Post a plugin", 13, "Bold", T.text, {Position = UDim2.fromOffset(38, 0), Size = UDim2.new(1, -38, 1, 0)})
ui.label(postCard, "Give it a name, paste the code below and post. It changes Hyundax IUM right away.", 10, T.muted)
formBanner = new("TextLabel", {
Size = UDim2.new(1, 0, 0, 26), BackgroundColor3 = T.glow, BorderSizePixel = 0, Text = "Editing plugin: press Post to update it",
TextSize = 10, FontFace = F.SemiBold, TextColor3 = T.gold, TextXAlignment = Enum.TextXAlignment.Left,
Visible = editingId ~= nil, LayoutOrder = nextOrder(postCard), Parent = postCard,
}, {round(8), stroke(T.bronzeLo, 1), pad(10, 0, 10, 0)})
refreshBanner = function()
if formBanner and formBanner.Parent then formBanner.Visible = editingId ~= nil end
end
formName = ui.input(postCard, "Plugin name", "")
formCode = ui.codeBox(postCard, "Paste the plugin code here...", "", 170)
new("TextLabel", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.glow, BorderSizePixel = 0,
Text = "Plugins run with full executor access. Only post code you trust.", TextWrapped = true, TextSize = 9,
FontFace = F.SemiBold, TextColor3 = T.gold, TextXAlignment = Enum.TextXAlignment.Left,
TextYAlignment = Enum.TextYAlignment.Top, LayoutOrder = nextOrder(postCard), Parent = postCard,
}, {round(8), stroke(T.bronzeLo, 1), pad(10, 7, 10, 7)})
local row = ui.row(postCard, 6, 26)
ui.button(row, "Post plugin", 108, true, function() doPost(formName, formCode) end)
ui.button(row, "Template", 76, false, function()
if trim(formName.Text) == "" then formName.Text = "My Plugin" end
formCode.Text = TEMPLATE
end)
ui.button(row, "Clear", 60, false, function()
formName.Text, formCode.Text, editingId = "", "", nil
refreshBanner()
end)
local row2 = ui.row(postCard, 6, 26)
ui.button(row2, "Import share code", 128, false, function()
local src = formCode.Text
if trim(src):sub(1, #SHARE_PREFIX) ~= SHARE_PREFIX and getclipboard then
local ok, clip = pcall(getclipboard)
if ok and type(clip) == "string" then src = clip end
end
local nm, code = parseShare(src)
if not nm then toast("Invalid share code") return end
formName.Text, formCode.Text, editingId = nm, code, nil
refreshBanner()
toast("Share code imported: press Post")
end)
local themeCard = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundColor3 = T.cardTop,
BorderSizePixel = 0, LayoutOrder = 4, Parent = createSc,
}, {round(12), stroke(T.line), pad(12), vlist(8)})
FX.sheen(themeCard)
local thh = new("Frame", {Size = UDim2.new(1, 0, 0, 30), BackgroundTransparency = 1, LayoutOrder = nextOrder(themeCard), Parent = themeCard})
FX.chip(thh, "sparkle", 28, T.gold, UDim2.fromOffset(0, 1))
text(thh, "Export theme as plugin", 13, "Bold", T.text, {Position = UDim2.fromOffset(38, 0), Size = UDim2.new(1, -38, 1, 0)})
ui.label(themeCard, "Turn colors and a background image into a plugin you can toggle, copy and share. Leave a color empty to use the current theme.", 10, T.muted)
local tName = ui.input(themeCard, "Theme name", "")
local tImg = ui.input(themeCard, "Background image link (optional, png or jpg)", "")
local tBg = ui.input(themeCard, "Background color, e.g. #181428", "")
local tAcc = ui.input(themeCard, "Accent color, e.g. #E63946", "")
local swatch = new("Frame", {Size = UDim2.new(1, 0, 0, 22), BackgroundTransparency = 1, LayoutOrder = nextOrder(themeCard), Parent = themeCard}, {hlist(4)})
local strength = 2
ui.label(themeCard, "Image strength", 10, T.text)
ui.segmented(themeCard, {"Low", "Medium", "High"}, 2, function(i) strength = i end)
local function hex(str)
str = trim(str):gsub("^#", "")
if #str == 3 then str = str:gsub(".", function(ch) return ch .. ch end) end
if #str ~= 6 or not str:match("^%x+$") then return nil end
return Color3.fromRGB(tonumber(str:sub(1, 2), 16), tonumber(str:sub(3, 4), 16), tonumber(str:sub(5, 6), 16))
end
local function toHex(c)
return string.format("#%02X%02X%02X", math.floor(c.R * 255 + .5), math.floor(c.G * 255 + .5), math.floor(c.B * 255 + .5))
end
local function resolvePal()
local bg, ac = hex(tBg.Text), hex(tAcc.Text)
if not bg and not ac then return T end
return T.mkCustom(bg or T.bg, ac or T.bronze)
end
local function paintSwatch()
for _, ch in ipairs(swatch:GetChildren()) do if ch:IsA("Frame") then ch:Destroy() end end
local pal = resolvePal()
for _, key in ipairs({"bg", "side", "panel", "panel2", "bronze", "bronzeHi", "gold", "text"}) do
new("Frame", {Size = UDim2.fromOffset(22, 22), BackgroundColor3 = pal[key], BorderSizePixel = 0, Parent = swatch}, {round(11), stroke(T.line, 1)})
end
end
tBg:GetPropertyChangedSignal("Text"):Connect(paintSwatch)
tAcc:GetPropertyChangedSignal("Text"):Connect(paintSwatch)
paintSwatch()
local function buildThemeCode()
local nm = trim(tName.Text)
if nm == "" then toast("Name and code are required") return nil end
return nm, genThemeCode(nm, capture(resolvePal()), (trim(tImg.Text):gsub("%s", "")), strength)
end
local trow = ui.row(themeCard, 6, 26)
ui.button(trow, "Create plugin", 108, true, function()
local nm, code = buildThemeCode()
if not nm then return end
installCode("Theme: " .. nm, code)
toast("Plugin posted")
end)
ui.button(trow, "Copy code", 84, false, function()
local nm, code = buildThemeCode()
if not nm then return end
local ok = pcall(setclipboard, code)
toast(ok and "Code copied" or "setclipboard unavailable")
end)
ui.button(trow, "Use current", 92, false, function()
tBg.Text, tAcc.Text = toHex(T.bg), toHex(T.bronze)
end)
local toolbar = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1, LayoutOrder = 5, Parent = sc,
}, {vlist(8)})
local searchRow = new("Frame", {Size = UDim2.new(1, 0, 0, 32), BackgroundTransparency = 1, LayoutOrder = 0, Parent = toolbar})
filterBox = new("TextBox", {
Size = UDim2.fromScale(1, 1), BackgroundColor3 = T.panel, Text = "", PlaceholderText = "Search plugins...",
PlaceholderColor3 = T.muted, TextColor3 = T.text, TextSize = 11, FontFace = F.Regular, ClearTextOnFocus = false,
TextXAlignment = Enum.TextXAlignment.Left, Parent = searchRow,
}, {round(9), pad(32, 0, 10, 0)})
local fst = stroke(T.line, 1)
fst.Parent = filterBox
local si = icon(searchRow, "search", 12, T.muted, 1.3)
si.holder.AnchorPoint, si.holder.Position = Vector2.new(0, .5), UDim2.new(0, 12, .5, 0)
si.holder.ZIndex = 3
filterBox.Focused:Connect(function() tween(fst, {Color = T.tan}, .2) si.set(T.tan, .2) end)
filterBox.FocusLost:Connect(function() tween(fst, {Color = T.line}, .2) si.set(T.muted, .2) end)
filterBox:GetPropertyChangedSignal("Text"):Connect(function() refreshList() end)
ui.segmented(toolbar, {"All", "Active", "Official", "Custom"}, filterMode, function(i)
filterMode = i
refreshList()
end)
local bulk = ui.row(toolbar, 6, 26)
ui.button(bulk, "Reload all", 88, false, function()
for _, p in ipairs(allPlugins()) do
if running[p.id] then
stopPlugin(p.id)
errors[p.id] = nil
local ok, err = startPlugin(p)
if not ok then errors[p.id] = tostring(err) data.enabled[p.id] = false end
end
end
save()
toast("Plugin reloaded")
task.defer(refreshList)
end)
ui.button(bulk, "Disable all", 92, false, function()
for _, p in ipairs(allPlugins()) do
if running[p.id] then stopPlugin(p.id) end
data.enabled[p.id] = false
end
save()
toast("Plugin disabled")
task.defer(refreshList)
end)
E.section(sc, "Installed plugins", 6)
listHolder = new("Frame", {
Size = UDim2.new(1, 0, 0, 0), AutomaticSize = Enum.AutomaticSize.Y, BackgroundTransparency = 1,
LayoutOrder = 7, Parent = sc,
}, {vlist(10)})
refreshList()
selectSubtab("browse")
return function() refreshList() end
end
local function init()
for _, p in ipairs(allPlugins()) do
if data.enabled[p.id] == true then
local ok, err = startPlugin(p)
if not ok then
errors[p.id] = tostring(err)
data.enabled[p.id] = false
addLine("Console", "[plugin:" .. p.name .. "] " .. tostring(err), T.bronzeHi)
end
end
end
save()
end
return {build = buildPlugins, init = init, ui = ui, install = installCode, list = function() return data.custom end}
end)({
new = new, round = round, stroke = stroke, pad = pad, vlist = vlist, hlist = hlist,
text = text, scroller = scroller, icon = icon, tween = tween, pressFx = pressFx, hoverFx = hoverFx,
T = T, F = F, FX = FX, I18N = I18N, gui = gui, main = main, root = root,
toast = toast, addLine = addLine, mini = mini, heading = heading, section = section,
lp = lp, FOLDER = FOLDER, VERSION = VERSION, MONO = MONO, TITLE_H = TITLE_H,
ctrls = ctrls, borderStroke = borderStroke, pageOrder = pageOrder, viewport = viewport,
jsonRead = jsonRead, jsonWrite = jsonWrite, httpGet = httpGet, toAsset = toAsset,
runCode = runCode, setTheme = setTheme,
popupBG = function(h, r) return Store.popupBG(h, r) end,
popup = function(o) return FX.popup(o) end,
recents = function() return recents end,
newTab = function(name, code) return newTab(name, code) end,
showPage = function(name) return showPage(name) end,
clearConsole = function() return LOG.clear() end,
})
;(function(cfg, defaults, applyCfg, saveCfg, setTheme)
local ACC_FILES = {
{"cloud", PATH.cloud}, {"saved", PATH.saved}, {"autoIdx", PATH.autoIdx},
{"likes", PATH.likes}, {"stats", PATH.stats}, {"settings", T.SETTINGS_FILE},
}
local ACTIVE_FILE = DB_FOLDER .. "/active.json"
local function dataFile(key) return DB_FOLDER .. "/data_" .. key .. ".json" end
local function rawRead(p)
local ok, r = pcall(function() if isfile and isfile(p) then return readfile(p) end end)
return ok and type(r) == "string" and r or nil
end
local function snapshot(key)
local b = {files = {}, auto = {}, profile = {lang = I18N.lang, nick = I18N.nick}}
for _, fl in ipairs(ACC_FILES) do b.files[fl[1]] = rawRead(fl[2]) end
pcall(function()
for _, p in ipairs(listfiles(PATH.auto)) do
local n = tostring(p):match("[^/\\]+$")
local c = n and rawRead(p)
if c then b.auto[n] = c end
end
end)
jsonWrite(dataFile(key), b)
end
local function applyBundle(key)
local b = jsonRead(dataFile(key), nil) or {files = {}, auto = {}, profile = {}}
for _, fl in ipairs(ACC_FILES) do
local c = b.files and b.files[fl[1]]
pcall(function()
if type(c) == "string" then writefile(fl[2], c)
elseif isfile and isfile(fl[2]) and delfile then delfile(fl[2]) end
end)
end
pcall(function()
for _, p in ipairs(listfiles(PATH.auto)) do if delfile then delfile(p) end end
for n, c in pairs(b.auto or {}) do writefile(PATH.auto .. "/" .. n, c) end
end)
return b
end
local function refill(t, src)
for k in pairs(t) do t[k] = nil end
for k, v in pairs(src) do t[k] = v end
end
local function reloadMemory(b, name)
refill(Store.cloud, jsonRead(PATH.cloud, {}))
refill(Store.saved, jsonRead(PATH.saved, {}))
refill(Store.auto, jsonRead(PATH.autoIdx, {}))
refill(Store.likes, jsonRead(PATH.likes, {}))
local st = jsonRead(PATH.stats, {})
Stats.total = tonumber(st.total) or 0
Stats.errors = tonumber(st.errors) or 0
Stats.sessions = (tonumber(st.sessions) or 0) + 1
Stats.first = tonumber(st.first) or os.time()
Stats.baseSeconds = tonumber(st.seconds) or 0
sessionStart = os.clock()
saveStats(true)
for k in pairs(cfg) do cfg[k] = nil end
for k, v in pairs(jsonRead(T.SETTINGS_FILE, {})) do cfg[k] = v end
cfg.theme = cfg.theme or "Hyundax IUM Primary"
for k, v in pairs(defaults) do if cfg[k] == nil then cfg[k] = v end end
HX.fill()
applyCfg()
if T.UI_THEMES[cfg.theme] and cfg.theme ~= FX.accTheme then
FX.accTheme = cfg.theme
pcall(setTheme, cfg.theme)
end
local p = b.profile or {}
I18N.user, I18N.session = name, name
if p.lang then pcall(I18N.set, p.lang) end
I18N.setNick((type(p.nick) == "string" and p.nick ~= "") and p.nick or name)
I18N.save()
pcall(function() if Stats.refresh then Stats.refresh() end end)
pcall(function() if Store.refresh then Store.refresh() end end)
pcall(function() if Store.refreshSaved then Store.refreshSaved() end end)
pcall(function() if Store.refreshEditorStart then Store.refreshEditorStart() end end)
pcall(function() if Store.hubOpen and pageItems.cur == pageMap.Scripts then Store.hubOpen() end end)
pcall(function() if FX.accRefreshCards then FX.accRefreshCards() end end)
pcall(function() if FX.accRefreshVault then FX.accRefreshVault() end end)
end
FX.accTheme = cfg.theme
function FX.accSwitch(name)
local key = tostring(name):lower()
local owner = (jsonRead(ACTIVE_FILE, {}) or {}).owner
if owner == key then return false end
pcall(saveCfg)
pcall(saveStats, true)
if owner then pcall(snapshot, owner) end
local b = applyBundle(key)
jsonWrite(ACTIVE_FILE, {owner = key})
reloadMemory(b, name)
return true
end
function FX.accSync()
local name = I18N.user or I18N.session
if not name then return end
local key = name:lower()
local owner = (jsonRead(ACTIVE_FILE, {}) or {}).owner
if not owner then jsonWrite(ACTIVE_FILE, {owner = key}) return end
if owner ~= key then FX.accSwitch(name) end
end
end)(cfg, defaults, applyCfg, saveCfg, setTheme)
do
local sp = FX.settingsPage
sp.add("Appearance", function(view) buildThemes(view) end, "sparkle")
sp.add("Interface", function(view) buildSettings(view, "interface") end, "cube")
sp.add("Editor", function(view) buildSettings(view, "editor") end, "code")
FX.accountPage.add("Profile", function(view) buildSettings(view, "profile") end, "user")
sp.add("Visual", function(view) buildSettings(view, "look") end, "sparkle")
sp.add("Fonts", function(view) buildSettings(view, "fonts") end, "file")
sp.add("Window", function(view) buildSettings(view, "window") end, "cube")
sp.add("Behavior", function(view) buildSettings(view, "behavior") end, "gear")
sp.add("Notifications", function(view) buildSettings(view, "notify") end, "bolt")
sp.add("Sound", function(view) buildSettings(view, "sound") end, "play")
sp.add("Privacy", function(view) buildSettings(view, "privacy") end, "user")
sp.add("Advanced", function(view) buildSettings(view, "advanced") end, "cpu")
sp.add("Plugins", function(view) return FX.Plugins.build(view) end, "layers")
task.delay(.9, FX.Plugins.init)
sp.select("Appearance")
end
picks.Editor = addSubTabs("Editor", {
{name = "Start", icon = "home", build = buildEditorStart},
{name = "Editor", icon = "code", existing = true, onShow = function() task.delay(.45, refreshCode) end},
{name = "Forge", icon = "bolt", build = buildSnippets},
})
Store.openEditorPane = function() if picks.Editor then picks.Editor(2) end end
picks.Scripts = addSubTabs("Scripts", {
{name = "Browse", icon = "globe"},
{name = "Radar", icon = "user", build = buildRadar},
})
picks.Dex = addSubTabs("Dex", {
{name = "Explorer", icon = "tree"},
{name = "Finder", icon = "search", build = buildFinder},
})
end
FX.show = function() FX.cascade(bar, .5) end
do
local RunService = game:GetService("RunService")
local grad = borderStroke:FindFirstChildOfClass("UIGradient")
local fStroke = floatBtn:FindFirstChildOfClass("UIStroke")
local fGrad = fStroke and fStroke:FindFirstChildOfClass("UIGradient")
local conn
conn = RunService.Heartbeat:Connect(function()
if not gui.Parent then conn:Disconnect() return end
local t = os.clock()
if grad then grad.Rotation = (40 + t * 14) % 360 end
if fStroke then fStroke.Thickness = 1.8 + .7 * (.5 + .5 * math.sin(t * 1.6)) end
if fGrad then fGrad.Rotation = (t * 70) % 360 end
navIndicator.BackgroundTransparency = .2 * (.5 + .5 * math.sin(t * 2))
end)
end
do
local function autoPress(b)
task.defer(function()
if not b.Parent or b:FindFirstChildOfClass("UIScale") then return end
local sz = b.AbsoluteSize
if sz.X > 400 or sz.Y > 200 then return end
pressFx(b, .96)
end)
end
for _, d in ipairs(gui:GetDescendants()) do if d:IsA("GuiButton") then autoPress(d) end end
gui.DescendantAdded:Connect(function(d) if d:IsA("GuiButton") then autoPress(d) end end)
end
loadLogo()
home.select("Overview")
FX.accountPage.select("Account")
pcall(FX.accSync)
task.spawn(function() local n = I18N.user or I18N.session; if n and FX.cloud then pcall(FX.cloud.pushMine, n) end end)
setActive(2)
relayout(false)
do
local C = S.cfg or {}
local sp = ({"Home", "Editor", "Scripts", "Settings"})[tonumber(C.startPage) or 1]
if C.startPage == 5 and pageMap[C.lastPage or ""] then sp = C.lastPage end
showPage(sp or "Home")
end
if S.cfg and S.cfg.autoOpen == false then pcall(showPill) else setShown(true) end
FX.sfx.mute = 0
if not (S.cfg and S.cfg.sndStartup == false) then task.delay(.4, function() FX.snd("welcome") end) end
if I18N.nick ~= "" and not (S.cfg and (S.cfg.profileWelcomeTips == false or S.cfg.hideNick)) then task.delay(1.2, function() toast("Hello, " .. I18N.nick .. "!") end) end
LOG.start()
addLine("Console", NAME .. " " .. VERSION .. " ready.", T.tan)
do
local bridgeStatus = Compat.cppBridge.status()
local detail = bridgeStatus.available and ("connected (" .. tostring(bridgeStatus.version) .. ")") or "not connected"
addLine("Console", "[C++ bridge] " .. detail, T.muted)
end
Compat.sink = function(lvl, msg)
addLine("Console", "[sUNC] " .. msg, lvl == "error" and T.bronzeHi or (lvl == "ok" and T.gold or T.tan))
end
do
local n = 0
for _, sp in ipairs(Compat.specs) do if sp.src == "poly" then n += 1 end end
addLine("Console", ("[sUNC] %d functions known, %d polyfilled for this executor. Home > sUNC to run tests."):format(#Compat.specs, n), T.muted)
end
task.delay(1.2, function() if S.autorun ~= false then Store.runAuto() end end)
end)()