OpenHub
Key Required

OpenHub

ArsenalKanschkovRobloxAcc1KanschkovRobloxAcc1 311 views 786 executesUpdated Aug 2, 2026
Unrated
00
Lua Script•4191 lines (132057 chars)
local P = game:GetService("Players")
local RS = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local L = game:GetService("Lighting")
local W = game:GetService("Workspace")

local player = P.LocalPlayer
if not player then
	player = P.PlayerAdded:Wait()
end
print("Hub: loaded, player =", player)

local theme = {
	bg = Color3.fromRGB(21, 21, 21),
	bg2 = Color3.fromRGB(29, 29, 29),
	btn = Color3.fromRGB(42, 42, 42),
	btnLight = Color3.fromRGB(58, 58, 58),
	accent = Color3.fromRGB(90, 255, 120),
	accentDark = Color3.fromRGB(0, 150, 60),
	text = Color3.fromRGB(235, 235, 235),
	dim = Color3.fromRGB(165, 165, 165),
	red = Color3.fromRGB(255, 90, 90),
}

local settings = {
	esp = false, espName = true, espBox = true, espHealth = true, espCornerBoxes = false, espDistance = true,
	espHighlight = false, espGun = true, espKills = true, espSkeleton = false, espVelocity = true, tracers = false, bodyType = "Auto",
	fly = false, flySpeed = 50, infJump = false,
	walkspeed = 16, noclip = false, jumpPower = 50,
	aimbot = false, flick = false, flickShoot = true, aim360 = false, multiTarget = false, maxTargets = 3, hitPart = "Head", fov = 45, maxDistance = 500, smoothing = 0, prediction = 0, aimTargetMode = "Crosshair", stickyAim = false,
	noRecoil = false, noSpread = false, antiAim = false, antiAimAngle = 45, autoShoot = false, rapidFire = false, rapidCps = 20, noClickDelay = false, killAura = false, killAuraRange = 30, hitEffects = false, trickShot = false, trickShotKey = nil,
	lowHpTp = false, lowHpTpTrigger = "Low HP", lowHpTpDir = "Behind", lowHpTpThreshold = 15, lowHpTpRange = 100, lowHpTpCooldown = 3,
	massKill = false, massKillDelay = 1, bringAll = false, bringAllDist = 10, stickBehind = false, stickBehindDist = 3,
	hitboxExtend = false, hitboxExtendScale = 2, speedHack = false, speedHackMult = 2,
	lagSwitch = false, lagSwitchKey = nil, lagSwitchMs = 3000,
	enabled = true, silentAim = false, silent360 = false, toggleKey = Enum.KeyCode.F, hideKey = Enum.KeyCode.LeftControl, mouseFreeKey = Enum.KeyCode.LeftAlt,
	checkVisible = true, showFovCircle = true, showTarget = false, fovColor = Color3.fromRGB(90, 255, 120), showTargetV2 = false, showTargetV3 = false,
	teamCheck = false, wallbang = false, semiWallbang = false, semiWallbangThickness = 6, ignoreBarriers = false, ignoreNonCollision = false, ignoreFriends = false, ignoreDead = true,
	antiAfk = false, autoClicker = false, cps = 10, triggerbot = false, freecam = false, autoAim = false,
	chatSpam = false, chatDelay = 1, chatMessage = "Hello",
	fovEnabled = false, camFov = 70,
	clock = false, clockTime = 14,
	fog = false, fogDistance = 500,
	shaders = false, ccBrightness = 0, ccContrast = 0, ccSaturation = 0,
	shaderPreset = "Normal", gloom = false, dof = false, dofFocus = 50, bloom = false, bloomIntensity = 1, skybox = "None", materials = "Normal",
	thirdPerson = false, tpDist = 12, spinbot = false, spinSpeed = 20, tpWalk = false, tpWalkSpeed = 30, gravityChanger = false, gravity = 196.2,
	swimBoost = false, swimSpeed = 24, autoSprint = false, wallClimb = false, flyBoost = false, flyBoostMult = 2.5, clickTp = false, clickTpKey = nil, strafe = false, strafeSpeed = 35, bhop = false, strafeV2 = false, strafeV2Speed = 40,
	chams = false, chamsType = "Outlines", chamsColor = Color3.fromRGB(0, 255, 255), chamsRainbow = false, chamsRainbowSpeed = 10,
	fpsCap = false, fpsCapValue = 60,
	playerFinder = "",
	playerSearch = "",
	serverTarget = "",
	scan = false, cheatSpeed = 100,
	unlocked = false, keyEntry = "",
}

local defaultSettings = table.clone(settings)

if getgenv then
	local saved = getgenv().HubState
	if saved then
		for key, value in pairs(saved) do
			settings[key] = value
		end
	end
end

local function save()
	if getgenv then
		getgenv().HubState = table.clone(settings)
	end
end

local function new(className, props)
	local i = Instance.new(className)
	for key, value in pairs(props) do
		i[key] = value
	end
	return i
end

local function corner(i, radius)
	local c = Instance.new("UICorner")
	c.CornerRadius = UDim.new(0, radius or 6)
	c.Parent = i
end

local function easeOutCubic(t)
	return 1 - (1 - t) ^ 3
end

local function tweenProps(instance, duration, target, done)
	local start = {}
	for k in pairs(target) do
		start[k] = instance[k]
	end
	local elapsed = 0
	local conn
	conn = RS.Heartbeat:Connect(function(dt)
		elapsed += dt
		local t = math.clamp(elapsed / duration, 0, 1)
		local e = easeOutCubic(t)
		for k, v in pairs(target) do
			local sv = start[k]
			if typeof(sv) == "UDim2" then
				instance[k] = UDim2.new(
					sv.X.Scale + (v.X.Scale - sv.X.Scale) * e,
					sv.X.Offset + (v.X.Offset - sv.X.Offset) * e,
					sv.Y.Scale + (v.Y.Scale - sv.Y.Scale) * e,
					sv.Y.Offset + (v.Y.Offset - sv.Y.Offset) * e
				)
			elseif typeof(sv) == "Color3" then
				instance[k] = sv:Lerp(v, e)
			elseif typeof(sv) == "UDim" then
				instance[k] = UDim.new(sv.Scale + (v.Scale - sv.Scale) * e, sv.Offset + (v.Offset - sv.Offset) * e)
			else
				instance[k] = sv + (v - sv) * e
			end
		end
		if t >= 1 then
			conn:Disconnect()
			if done then
				done()
			end
		end
	end)
	return conn
end

local useDrawing = pcall(function()
	local d = Drawing.new("Square")
	d:Remove()
end)
local espDrawings = {}
local flyConn = nil
local flyHrp = nil
local flicking = false
local pendingSilent = false
local restoreCFrame = nil
local cycleIndex = 1

local skeletonDrawings = {}
local highlights = {}
local stats = {}
local charBounds = {}
local centerLines = {}

local lockTarget = nil
local trickActive = false
local trickLockUntil = 0
local trickLockTarget = nil
local scanSus = {}
local scanSample = {}
local scanHits = {}
local scanWatched = {}
local cheaterRows = {}
local cheaterList = nil
local cheaterScroll = nil
local scanTick = nil
local refreshCheatersUI = nil
local scanLastTick = 0
local scanUiTimer = 0
local tpYaw = 0
local tpPitch = 0
local originalCamType = nil
local matTimer = 0
local noRecoilBase = nil
local preShotPitch = nil
local spreadTimer = 0
local lastM1 = false
local lastMousePos = Vector2.zero
local antiAimT = 0
local antiAimFlip = false
local autoShootT = 0
local stickyTarget = nil
local rapidT = 0
local hitMarkers = {}
local killAuraT = 0
local spectateTarget = nil
local fpsCapApplied = nil
local playersScroll = nil
local playersRefreshT = 0
local refreshPlayers = nil
local chamsObjs = {}
local lowHpTpT = 0
local lowHpTrack = {}
local lowHpToolTrack = {}
local lastLowHpTp = 0
local aimTarget = nil
local hitboxParts = {}
local hitboxChar = nil
local hitboxScale = nil
local massKillTick = 0
local stickBehindTarget = nil

local function getCharBounds(char)
	local root = char:FindFirstChild("HumanoidRootPart") or char:FindFirstChild("Torso")
	if not root then
		return nil
	end
	if settings.bodyType == "R6" then
		return {
			topPoint = root.Position + Vector3.new(0, 3.6, 0),
			bottomPoint = root.Position + Vector3.new(0, -3.2, 0),
		}
	end
	if settings.bodyType == "R15" then
		return {
			topPoint = root.Position + Vector3.new(0, 3.8, 0),
			bottomPoint = root.Position + Vector3.new(0, -3.9, 0),
		}
	end
	local head = char:FindFirstChild("Head")
	local maxY, minY = -math.huge, math.huge
	local minX, maxX = math.huge, -math.huge
	local minZ, maxZ = math.huge, -math.huge
	local count = 0
	for _, p in ipairs(char:GetDescendants()) do
		if p:IsA("BasePart") and p.Name ~= "HumanoidRootPart" then
			local c = p.Position
			local s = p.Size
			local topY = c.Y + s.Y / 2
			local botY = c.Y - s.Y / 2
			if topY > maxY then maxY = topY end
			if botY < minY then minY = botY end
			local cx0, cx1 = c.X - s.X / 2, c.X + s.X / 2
			local cz0, cz1 = c.Z - s.Z / 2, c.Z + s.Z / 2
			if cx0 < minX then minX = cx0 end
			if cx1 > maxX then maxX = cx1 end
			if cz0 < minZ then minZ = cz0 end
			if cz1 > maxZ then maxZ = cz1 end
			count += 1
		end
	end
	if count == 0 then
		return {
			topPoint = root.Position + Vector3.new(0, 3.5, 0),
			bottomPoint = root.Position + Vector3.new(0, -3.5, 0),
		}
	end
	local headTop = head and (head.Position.Y + head.Size.Y / 2) or maxY
	local top = math.min(maxY, headTop + 0.1)
	local midX = (minX + maxX) / 2
	local midZ = (minZ + maxZ) / 2
	return {
		topPoint = Vector3.new(midX, top, midZ),
		bottomPoint = Vector3.new(midX, minY, midZ),
	}
end

local function getStats(plr)
	local row = stats[plr]
	if not row then
		row = { kills = 0, deaths = 0, lastAimed = 0 }
		stats[plr] = row
	end
	return row
end

local function getEsp(plr)
	local d = espDrawings[plr]
	if d then
		return d
	end
	d = {
		box = Drawing.new("Square"),
		name = Drawing.new("Text"),
		health = Drawing.new("Line"),
		tracer = Drawing.new("Line"),
		corners = {},
	}
	d.box.Thickness = 1
	d.box.Visible = false
	d.name.Size = 13
	d.name.Center = true
	d.name.Outline = true
	d.name.Visible = false
	d.health.Thickness = 2
	d.health.Visible = false
	d.tracer.Thickness = 1.5
	d.tracer.Visible = false
	for i = 1, 8 do
		local ln = Drawing.new("Line")
		ln.Thickness = 2
		ln.Visible = false
		table.insert(d.corners, ln)
	end
	espDrawings[plr] = d
	return d
end

local function espHide(d)
	d.box.Visible = false
	d.name.Visible = false
	d.health.Visible = false
	d.tracer.Visible = false
	for _, ln in ipairs(d.corners) do
		ln.Visible = false
	end
end

local function espSkeleton(char, col, plr)
	local joints = {}
	for _, child in ipairs(char:GetDescendants()) do
		if child:IsA("Motor6D") and child.Part0 and child.Part1 then
			table.insert(joints, child)
		end
	end
	local entry = skeletonDrawings[plr]
	if not entry or entry.char ~= char then
		if entry then
			for _, l in ipairs(entry.lines) do
				l:Remove()
			end
		end
		local lines = {}
		for i = 1, #joints do
			local line = Drawing.new("Line")
			line.Thickness = 1.5
			line.Color = col
			line.Visible = false
			table.insert(lines, line)
		end
		entry = { joints = joints, lines = lines, char = char }
		skeletonDrawings[plr] = entry
	end
	for i, joint in ipairs(entry.joints) do
		local line = entry.lines[i]
		if line then
			line.Color = col
			line.From = joint.Part0.Position
			line.To = joint.Part1.Position
			line.Visible = true
		end
	end
end

local function espSkeletonHide(plr)
	local entry = skeletonDrawings[plr]
	if entry then
		for _, l in ipairs(entry.lines) do
			l.Visible = false
		end
	end
end

local function hideEsp()
	for _, d in pairs(espDrawings) do
		espHide(d)
	end
end

local function espUpdate()
	local cam = W.CurrentCamera
	if not cam then
		return
	end
	local center = cam.ViewportSize / 2
	local nearestDist = math.huge
	local nearestPlr = nil
	for _, other in ipairs(P:GetPlayers()) do
		local d = getEsp(other)
		local char = other.Character
		if other == player or not char then
			espHide(d)
			espSkeletonHide(other)
		else
			local humanoid = char:FindFirstChildOfClass("Humanoid")
			local root = humanoid and humanoid.RootPart
			local bounds = getCharBounds(char)
			if not root or not bounds then
				espHide(d)
				espSkeletonHide(other)
			else
				local top, topOn = cam:WorldToScreenPoint(bounds.topPoint)
				local bottom, botOn = cam:WorldToScreenPoint(bounds.bottomPoint)
				if not topOn and not botOn then
					espHide(d)
					espSkeletonHide(other)
				else
					local height = math.max(0, bottom.Y - top.Y)
					local boxW = height * 0.55
					local col = (other.Team and other.Team.TeamColor.Color) or Color3.fromRGB(255, 255, 255)
					if settings.espBox then
						d.box.Color = col
						d.box.Position = Vector2.new(bottom.X - boxW / 2, top.Y)
						d.box.Size = Vector2.new(boxW, height)
						d.box.Visible = not settings.espCornerBoxes
					else
						d.box.Visible = false
					end
					if settings.espBox and settings.espCornerBoxes then
						local x0 = bottom.X - boxW / 2
						local y0 = top.Y
						local x1 = bottom.X + boxW / 2
						local y1 = bottom.Y
						local cl = math.max(4, boxW * 0.25)
						d.corners[1].From = Vector2.new(x0, y0)
						d.corners[1].To = Vector2.new(x0 + cl, y0)
						d.corners[2].From = Vector2.new(x0, y0)
						d.corners[2].To = Vector2.new(x0, y0 + cl)
						d.corners[3].From = Vector2.new(x1, y0)
						d.corners[3].To = Vector2.new(x1 - cl, y0)
						d.corners[4].From = Vector2.new(x1, y0)
						d.corners[4].To = Vector2.new(x1, y0 + cl)
						d.corners[5].From = Vector2.new(x0, y1)
						d.corners[5].To = Vector2.new(x0 + cl, y1)
						d.corners[6].From = Vector2.new(x0, y1)
						d.corners[6].To = Vector2.new(x0, y1 - cl)
						d.corners[7].From = Vector2.new(x1, y1)
						d.corners[7].To = Vector2.new(x1 - cl, y1)
						d.corners[8].From = Vector2.new(x1, y1)
						d.corners[8].To = Vector2.new(x1, y1 - cl)
						for _, ln in ipairs(d.corners) do
							ln.Color = col
							ln.Visible = true
						end
					else
						for _, ln in ipairs(d.corners) do
							ln.Visible = false
						end
					end
					if settings.espName then
						local info = other.Name
						if settings.espGun then
							local tool = char:FindFirstChildOfType("Tool")
							info = info .. "\n[" .. (tool and tool.Name or "none") .. "]"
						end
						local row = stats[other]
						if settings.espKills and row then
							info = info .. "\nKills: " .. row.kills .. " Deaths: " .. row.deaths
						end
						if settings.espVelocity then
							info = info .. "\n" .. math.round(root.AssemblyLinearVelocity.Magnitude) .. " m/s"
						end
						if settings.espDistance then
							info = info .. "\n" .. math.round((root.Position - cam.CFrame.Position).Magnitude) .. " studs"
						end
						d.name.Color = col
						d.name.Text = info
						d.name.Position = Vector2.new(bottom.X, top.Y - 16)
						d.name.Visible = true
					else
						d.name.Visible = false
					end
					if settings.espHealth and humanoid then
						local ratio = math.clamp(humanoid.Health / math.max(1, humanoid.MaxHealth), 0, 1)
						d.health.Color = Color3.fromRGB(80, 255, 80)
						d.health.From = Vector2.new(bottom.X - boxW / 2, top.Y - 4)
						d.health.To = Vector2.new(bottom.X - boxW / 2 + boxW * ratio, top.Y - 4)
						d.health.Visible = true
					else
						d.health.Visible = false
					end
					if settings.espSkeleton then
						espSkeleton(char, col, other)
					else
						espSkeletonHide(other)
					end
					if settings.tracers then
						d.tracer.Color = col
						d.tracer.From = Vector2.new(center.X, cam.ViewportSize.Y)
						local tPoint = topOn and Vector2.new(top.X, top.Y) or Vector2.new(bottom.X, bottom.Y)
						d.tracer.To = tPoint
						d.tracer.Visible = true
					else
						d.tracer.Visible = false
					end
					local distToCenter = (Vector2.new(bottom.X, bottom.Y) - center).Magnitude
					if distToCenter < nearestDist then
						nearestDist = distToCenter
						nearestPlr = other
					end
				end
			end
		end
	end
	if nearestPlr and stats[nearestPlr] then
		stats[nearestPlr].lastAimed = os.clock()
	end
end

local function updateHighlights()
	if settings.espHighlight then
		for _, other in ipairs(P:GetPlayers()) do
			if other == player then
				continue
			end
			local char = other.Character
			if not char then
				continue
			end
			local h = highlights[other]
			if not h or h.Parent ~= char then
				if h then
					h:Destroy()
				end
				h = Instance.new("Highlight")
				h.FillTransparency = 0.7
				h.OutlineTransparency = 0
				h.Parent = char
				highlights[other] = h
			end
			local col = (other.Team and other.Team.TeamColor.Color) or Color3.fromRGB(255, 255, 255)
			h.FillColor = col
			h.OutlineColor = col
		end
	else
		for _, h in pairs(highlights) do
			h:Destroy()
		end
		highlights = {}
	end
end

local function chamsColor()
	if settings.chamsRainbow then
		local hue = (os.clock() * math.max(0.1, settings.chamsRainbowSpeed) * 0.5) % 1
		return Color3.fromHSV(hue, 1, 1)
	end
	return settings.chamsColor
end

local function updateChams()
	if not settings.chams then
		for _, obj in pairs(chamsObjs) do
			if obj.model then
				obj.model:Destroy()
			end
			if obj.highlight then
				obj.highlight:Destroy()
			end
		end
		chamsObjs = {}
		return
	end
	local ctype = settings.chamsType
	local col = chamsColor()
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		local char = other.Character
		if not char or not char.PrimaryPart then
			local gone = chamsObjs[other]
			if gone then
				if gone.model then
					gone.model:Destroy()
				end
				if gone.highlight then
					gone.highlight:Destroy()
				end
				chamsObjs[other] = nil
			end
			continue
		end
		local obj = chamsObjs[other]
		local needModel = ctype == "Fullbody" or ctype == "Head"
		local needHighlight = ctype == "Outlines" or ctype == "FullVisible"
		local rebuild = not obj or obj.kind ~= ctype
			or (obj.highlight and obj.highlight.Parent ~= char)
			or (obj.model and obj.model.Parent ~= workspace)
		if rebuild then
			if obj then
				if obj.model then
					obj.model:Destroy()
				end
				if obj.highlight then
					obj.highlight:Destroy()
				end
			end
			obj = { kind = ctype }
			if needModel then
				local model = char:Clone()
				model.Name = "OpenHubCham"
				for _, d in ipairs(model:GetDescendants()) do
					if d:IsA("Script") or d:IsA("LocalScript") or d:IsA("Humanoid") then
						d:Destroy()
					end
				end
				for _, p in ipairs(model:GetDescendants()) do
					if p:IsA("BasePart") then
						p.CanCollide = false
						p.Material = Enum.Material.SmoothPlastic
						p.Transparency = 1
					end
				end
				if ctype == "Head" then
					local head = model:FindFirstChild("Head")
					if head and head:IsA("BasePart") then
						head.Transparency = 0.3
						head.Color = col
						model.PrimaryPart = head
						model.Parent = workspace
						obj.model = model
					else
						model:Destroy()
						chamsObjs[other] = nil
						continue
					end
				else
					for _, p in ipairs(model:GetDescendants()) do
						if p:IsA("BasePart") then
							p.Transparency = 0.3
							p.Color = col
						end
					end
					model.Parent = workspace
					obj.model = model
				end
			elseif needHighlight then
				local h = Instance.new("Highlight")
				h.FillTransparency = (ctype == "FullVisible") and 0.2 or 1
				h.OutlineTransparency = 0
				h.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
				h.FillColor = col
				h.OutlineColor = col
				h.Parent = char
				obj.highlight = h
			end
			chamsObjs[other] = obj
		end
		if obj.highlight then
			obj.highlight.FillColor = col
			obj.highlight.OutlineColor = col
		end
		if obj.model then
			if ctype == "Head" then
				local realHead = char:FindFirstChild("Head")
				local chamHead = obj.model.PrimaryPart
				if realHead and chamHead then
					chamHead.CFrame = realHead.CFrame
				end
			else
				local ok = pcall(function()
					obj.model:PivotTo(char:GetPivot())
				end)
				if not ok then
					obj.model:Destroy()
					chamsObjs[other] = nil
					continue
				end
			end
			for _, p in ipairs(obj.model:GetDescendants()) do
				if p:IsA("BasePart") and p.Transparency < 1 then
					p.Color = col
				end
			end
		end
	end
end

local function centerLineHide()
	for _, line in pairs(centerLines) do
		line.Visible = false
	end
end

local function setNetworkLag(ms)
	local ok = pcall(function()
		sethiddenproperty("Network", "IncomingReplicationLag", ms)
	end)
	if not ok then
		pcall(function()
			settings().Network.IncomingReplicationLag = ms
		end)
	end
end

local function clearHitbox()
	for _, p in ipairs(hitboxParts) do
		if p and p.Parent then
			p:Destroy()
		end
	end
	hitboxParts = {}
	hitboxChar = nil
	hitboxScale = nil
end

local function rebuildHitbox(char)
	clearHitbox()
	for _, v in ipairs(char:GetDescendants()) do
		if v:IsA("BasePart") and v.Transparency ~= 1 then
			local clone = v:Clone()
			clone.Size = v.Size * settings.hitboxExtendScale
			clone.Transparency = 1
			clone.Material = Enum.Material.Neon
			clone.CanCollide = false
			clone.Anchored = false
			clone.CastShadow = false
			clone.Parent = char
			local weld = Instance.new("Weld")
			weld.Part0 = v
			weld.Part1 = clone
			weld.C0 = CFrame.new()
			weld.C1 = CFrame.new()
			weld.Parent = v
			table.insert(hitboxParts, clone)
		end
	end
	hitboxChar = char
	hitboxScale = settings.hitboxExtendScale
end

local function updateCenterLines()
	if not useDrawing then
		return
	end
	local cam = W.CurrentCamera
	if not cam or not (settings.enabled and (settings.showTargetV2 or settings.showTargetV3)) then
		centerLineHide()
		return
	end
	local center = cam.ViewportSize / 2
	local candidates = {}
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		local char = other.Character
		if not char then
			continue
		end
		local humanoid = char:FindFirstChildOfClass("Humanoid")
		if humanoid and humanoid.Health <= 0 then
			continue
		end
		local part = char:FindFirstChild(settings.hitPart)
		if not part then
			part = char:FindFirstChild("HumanoidRootPart")
		end
		if not part then
			continue
		end
		local screenPos, onScreen = cam:WorldToScreenPoint(part.Position)
		if not onScreen then
			continue
		end
		local screenDist = (Vector2.new(screenPos.X, screenPos.Y) - center).Magnitude
		if screenDist > settings.fov then
			continue
		end
		local friend = player.Team ~= nil and other.Team ~= nil and player.Team == other.Team
		table.insert(candidates, { plr = other, pos = Vector2.new(screenPos.X, screenPos.Y), screenDist = screenDist, friend = friend })
	end
	table.sort(candidates, function(a, b)
		return a.screenDist < b.screenDist
	end)
	local nextTarget = nil
	for _, c in ipairs(candidates) do
		if not (c.friend and settings.teamCheck) then
			nextTarget = c
			break
		end
	end
	local active = {}
	for _, c in ipairs(candidates) do
		if settings.showTargetV3 and c ~= nextTarget then
			continue
		end
		local line = centerLines[c.plr]
		if not line then
			line = Drawing.new("Line")
			line.Thickness = 2
			line.Visible = false
			centerLines[c.plr] = line
		end
		if c == nextTarget then
			line.Color = theme.red
		elseif c.friend then
			line.Color = Color3.fromRGB(90, 140, 255)
		else
			line.Color = Color3.fromRGB(255, 255, 255)
		end
		line.From = center
		line.To = c.pos
		line.Visible = true
		active[c.plr] = true
	end
	for plr, line in pairs(centerLines) do
		if not active[plr] then
			line.Visible = false
		end
	end
end

local function onDied(plr)
	local row = getStats(plr)
	row.deaths += 1
	if os.clock() - row.lastAimed < 5 then
		row.kills += 1
	end
end

local function trackPlayer(plr)
	getStats(plr)
	plr.CharacterAdded:Connect(function(char)
		local humanoid = char:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			onDied(plr)
		end)
	end)
	if plr.Character then
		local humanoid = plr.Character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid.Died:Connect(function()
				onDied(plr)
			end)
		end
	end
end
for _, plr in ipairs(P:GetPlayers()) do
	trackPlayer(plr)
end
P.PlayerAdded:Connect(trackPlayer)

P.PlayerRemoving:Connect(function(plr)
	local d = espDrawings[plr]
	if d then
		d.box:Remove()
		d.name:Remove()
		d.health:Remove()
		d.tracer:Remove()
		espDrawings[plr] = nil
	end
	local cl = centerLines[plr]
	if cl then
		cl:Remove()
		centerLines[plr] = nil
	end
	local sk = skeletonDrawings[plr]
	if sk then
		for _, l in ipairs(sk.lines) do
			l:Remove()
		end
		skeletonDrawings[plr] = nil
	end
	local h = highlights[plr]
	if h then
		h:Destroy()
		highlights[plr] = nil
	end
	stats[plr] = nil
end)

local originalClock = L.ClockTime
local originalFogStart = L.FogStart
local originalFogEnd = L.FogEnd
local originalFov = 70

local cce = L:FindFirstChildOfClass("ColorCorrectionEffect")
if not cce then
	cce = Instance.new("ColorCorrectionEffect")
	cce.Parent = L
end

local originalGravity = W.Gravity
local origLighting = {
	Ambient = L.Ambient,
	OutdoorAmbient = L.OutdoorAmbient,
	ColorShift_Top = L.ColorShift_Top,
	ColorShift_Bottom = L.ColorShift_Bottom,
	FogColor = L.FogColor,
	ExposureCompensation = L.ExposureCompensation,
	Brightness = L.Brightness,
}
local originalAtmoDensity = 0.12
local origAtmo = L:FindFirstChildOfClass("Atmosphere")
if origAtmo then
	originalAtmoDensity = origAtmo.Density
end

local dofEffect = L:FindFirstChildOfClass("DepthOfFieldEffect")
if not dofEffect then
	dofEffect = Instance.new("DepthOfFieldEffect")
end
dofEffect.FocusDistance = settings.dofFocus
dofEffect.InFocusRadius = 10
dofEffect.NearIntensity = 0.5
dofEffect.FarIntensity = 0.5
dofEffect.Parent = L

local bloomEffect = L:FindFirstChildOfClass("BloomEffect")
if not bloomEffect then
	bloomEffect = Instance.new("BloomEffect")
end
bloomEffect.Intensity = settings.bloomIntensity
bloomEffect.Size = 24
bloomEffect.Threshold = 2
bloomEffect.Parent = L

local shaderPresets = {
	Sunset = {
		ClockTime = 18.2, Ambient = Color3.fromRGB(110, 60, 35), OutdoorAmbient = Color3.fromRGB(150, 90, 60),
		ColorShift_Top = Color3.fromRGB(255, 170, 90), ColorShift_Bottom = Color3.fromRGB(90, 40, 30),
		FogColor = Color3.fromRGB(200, 110, 60), FogStart = 40, FogEnd = 400, ExposureCompensation = 0.4, Brightness = 1.6, atmoDensity = 0.4,
	},
	["Pink Sunrise"] = {
		ClockTime = 6.4, Ambient = Color3.fromRGB(150, 90, 120), OutdoorAmbient = Color3.fromRGB(180, 110, 150),
		ColorShift_Top = Color3.fromRGB(255, 180, 220), ColorShift_Bottom = Color3.fromRGB(120, 60, 100),
		FogColor = Color3.fromRGB(230, 170, 200), FogStart = 30, FogEnd = 450, ExposureCompensation = 0.3, Brightness = 1.7, atmoDensity = 0.35,
	},
	Snowy = {
		ClockTime = 13, Ambient = Color3.fromRGB(180, 190, 205), OutdoorAmbient = Color3.fromRGB(200, 210, 225),
		ColorShift_Top = Color3.fromRGB(235, 245, 255), ColorShift_Bottom = Color3.fromRGB(170, 180, 200),
		FogColor = Color3.fromRGB(220, 228, 238), FogStart = 60, FogEnd = 300, ExposureCompensation = 0.2, Brightness = 2.2, atmoDensity = 0.5,
	},
	["Summer Hot"] = {
		ClockTime = 14, Ambient = Color3.fromRGB(180, 150, 90), OutdoorAmbient = Color3.fromRGB(220, 190, 120),
		ColorShift_Top = Color3.fromRGB(255, 230, 150), ColorShift_Bottom = Color3.fromRGB(200, 150, 70),
		FogColor = Color3.fromRGB(240, 210, 150), FogStart = 80, FogEnd = 600, ExposureCompensation = 0.8, Brightness = 2.6, atmoDensity = 0.2,
	},
	Toxic = {
		ClockTime = 14, Ambient = Color3.fromRGB(40, 90, 40), OutdoorAmbient = Color3.fromRGB(50, 110, 50),
		ColorShift_Top = Color3.fromRGB(120, 255, 120), ColorShift_Bottom = Color3.fromRGB(30, 80, 30),
		FogColor = Color3.fromRGB(60, 140, 60), FogStart = 30, FogEnd = 350, ExposureCompensation = 0.1, Brightness = 1.9, atmoDensity = 0.45,
	},
}

local function applyShaderPreset(name)
	local atmo = L:FindFirstChildOfClass("Atmosphere")
	if name == "Normal" then
		L.ClockTime = originalClock
		L.Ambient = origLighting.Ambient
		L.OutdoorAmbient = origLighting.OutdoorAmbient
		L.ColorShift_Top = origLighting.ColorShift_Top
		L.ColorShift_Bottom = origLighting.ColorShift_Bottom
		L.FogColor = origLighting.FogColor
		L.FogStart = originalFogStart
		L.FogEnd = originalFogEnd
		L.ExposureCompensation = origLighting.ExposureCompensation
		L.Brightness = origLighting.Brightness
		if atmo then
			atmo.Density = originalAtmoDensity
		end
		return
	end
	local p = shaderPresets[name]
	if not p then
		return
	end
	L.ClockTime = p.ClockTime
	L.Ambient = p.Ambient
	L.OutdoorAmbient = p.OutdoorAmbient
	L.ColorShift_Top = p.ColorShift_Top
	L.ColorShift_Bottom = p.ColorShift_Bottom
	L.FogColor = p.FogColor
	L.FogStart = p.FogStart
	L.FogEnd = p.FogEnd
	L.ExposureCompensation = p.ExposureCompensation
	L.Brightness = p.Brightness
	if atmo then
		atmo.Density = p.atmoDensity
	end
end

local function applyGloom(on)
	if on then
		L.Ambient = Color3.fromRGB(28, 28, 32)
		L.OutdoorAmbient = Color3.fromRGB(35, 35, 40)
		L.FogColor = Color3.fromRGB(18, 18, 22)
		L.FogStart = 15
		L.FogEnd = 110
		L.ExposureCompensation = -0.6
		L.Brightness = 1.2
		local atmo = L:FindFirstChildOfClass("Atmosphere")
		if atmo then
			atmo.Density = 0.75
		end
	else
		applyShaderPreset(settings.shaderPreset)
	end
end

local skyboxChoices = {
	{ "None", nil },
	{ "Blue sky", 12272234 },
	{ "Sunset", 10892027 },
	{ "Night", 63524860 },
}
local sky = nil
local function applySkybox(name)
	if sky then
		sky:Destroy()
		sky = nil
	end
	local id = nil
	for _, s in ipairs(skyboxChoices) do
		if s[1] == name then
			id = s[2]
			break
		end
	end
	if not id then
		return
	end
	sky = Instance.new("Sky")
	local asset = "rbxassetid://" .. id
	sky.SkyboxBk = asset
	sky.SkyboxDn = asset
	sky.SkyboxFt = asset
	sky.SkyboxLf = asset
	sky.SkyboxRt = asset
	sky.SkyboxUp = asset
	sky.Parent = L
end

local chatRemote = nil
local function findChatRemote()
	if chatRemote and chatRemote.Parent then
		return chatRemote
	end
	chatRemote = nil
	local rs = game:GetService("ReplicatedStorage")
	local folder = rs:FindFirstChild("DefaultChatSystemChatEvents")
	if folder then
		chatRemote = folder:FindFirstChild("SayMessageRequest")
	end
	if not chatRemote then
		for _, child in ipairs(rs:GetDescendants()) do
			if child.Name == "SayMessageRequest" and child:IsA("RemoteEvent") then
				chatRemote = child
				break
			end
		end
	end
	return chatRemote
end
local chatTimer = 0

local function setFly(on)
	if on then
		local char = player.Character
		local humanoid = char and char:FindFirstChildOfClass("Humanoid")
		local hrp = humanoid and humanoid.RootPart
		if not humanoid or not hrp then
			print("Hub: no character for fly")
			return false
		end
		flyHrp = hrp
		flyConn = RS.RenderStepped:Connect(function()
			local root = humanoid.RootPart
			if not root then
				return
			end
			humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
			local up = (UIS:IsKeyDown(Enum.KeyCode.Space) and 1 or 0) - (UIS:IsKeyDown(Enum.KeyCode.LeftControl) and 1 or 0)
			local forward = (UIS:IsKeyDown(Enum.KeyCode.W) and 1 or 0) - (UIS:IsKeyDown(Enum.KeyCode.S) and 1 or 0)
			local left = (UIS:IsKeyDown(Enum.KeyCode.A) and 1 or 0) - (UIS:IsKeyDown(Enum.KeyCode.D) and 1 or 0)
			local cam = W.CurrentCamera
			local move = cam.CFrame.LookVector * forward + cam.CFrame.RightVector * left + Vector3.new(0, up, 0)
			local speed = settings.flySpeed
			if settings.flyBoost and UIS:IsKeyDown(Enum.KeyCode.LeftShift) then
				speed = speed * math.max(1, settings.flyBoostMult)
			end
			root.AssemblyLinearVelocity = move * speed
		end)
		return true
	else
		if flyConn then
			flyConn:Disconnect()
			flyConn = nil
		end
		local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
		if humanoid then
			humanoid:ChangeState(Enum.HumanoidStateType.Running)
		end
	end
end

local freecamYaw, freecamPitch = 0, 0
local freecamConn = nil
local function setFreecam(on)
	if on then
		local cam = W.CurrentCamera
		if not cam then
			return false
		end
		local look = cam.CFrame.LookVector
		freecamYaw = math.atan2(-look.X, -look.Z)
		freecamPitch = math.asin(math.clamp(look.Y, -1, 1))
		cam.CameraType = Enum.CameraType.Scriptable
		freecamConn = RS.RenderStepped:Connect(function(dt)
			local mouse = UIS:GetMouseRelative()
			freecamYaw -= mouse.X * 0.0025
			freecamPitch = math.clamp(freecamPitch - mouse.Y * 0.0025, -1.55, 1.55)
			local rot = CFrame.fromOrientation(freecamPitch, freecamYaw, 0)
			local move = Vector3.zero
			if UIS:IsKeyDown(Enum.KeyCode.W) then
				move += rot.LookVector
			end
			if UIS:IsKeyDown(Enum.KeyCode.S) then
				move -= rot.LookVector
			end
			if UIS:IsKeyDown(Enum.KeyCode.D) then
				move += rot.RightVector
			end
			if UIS:IsKeyDown(Enum.KeyCode.A) then
				move -= rot.RightVector
			end
			if UIS:IsKeyDown(Enum.KeyCode.Space) then
				move += Vector3.new(0, 1, 0)
			end
			if UIS:IsKeyDown(Enum.KeyCode.LeftControl) then
				move -= Vector3.new(0, 1, 0)
			end
			local cam2 = W.CurrentCamera
			if cam2 then
				cam2.CFrame = rot + (cam2.CFrame.Position + move * 60 * dt)
			end
		end)
		return true
	else
		if freecamConn then
			freecamConn:Disconnect()
			freecamConn = nil
		end
		local cam = W.CurrentCamera
		if cam and cam.CameraType == Enum.CameraType.Scriptable then
			cam.CameraType = Enum.CameraType.Custom
		end
	end
end

local function teleportTo(plr)
	local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
	local tchar = plr.Character
	local troot = tchar and tchar:FindFirstChild("HumanoidRootPart")
	if root and troot then
		root.CFrame = troot.CFrame * CFrame.new(0, 0, 5)
	end
end

local function bring(plr)
	local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
	local tchar = plr.Character
	local troot = tchar and tchar:FindFirstChild("HumanoidRootPart")
	if root and troot then
		troot.CFrame = root.CFrame * CFrame.new(0, 0, 5)
	end
end

local function bringAllFront()
	local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
	if not root then
		return
	end
	local base = root.CFrame * CFrame.new(0, 0, -settings.bringAllDist)
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		local tchar = other.Character
		local troot = tchar and tchar:FindFirstChild("HumanoidRootPart")
		if troot then
			troot.CFrame = CFrame.lookAt(base.Position, root.Position)
		end
	end
end

local function addHitMarker(pos)
	if not (useDrawing and settings.hitEffects and pos) then
		return
	end
	local mk = { pos = pos, life = 0.18, t = 0, drawings = {} }
	for i = 1, 4 do
		local d = Drawing.new("Line")
		d.Thickness = 2
		d.Color = Color3.fromRGB(255, 255, 255)
		mk.drawings[i] = d
	end
	table.insert(hitMarkers, mk)
end

local function fireAt(pos, cam)
	if not cam then
		return
	end
	local vim = game:GetService("VirtualInputManager")
	local center = cam.ViewportSize / 2
	vim:SendMouseButtonEvent(center.X, center.Y, 0, true)
	vim:SendMouseButtonEvent(center.X, center.Y, 0, false)
	addHitMarker(pos)
end

local function serverHop()
	local ok = pcall(function()
		local HttpService = game:GetService("HttpService")
		local TS = game:GetService("TeleportService")
		local url = "https://games.roblox.com/v1/games/" .. game.PlaceId .. "/servers/Public?limit=100"
		local data = HttpService:JSONDecode(HttpService:GetAsync(url))
		local servers = {}
		for _, s in ipairs(data.data) do
			if s.playing < s.maxPlayers and s.id ~= game.JobId then
				table.insert(servers, s.id)
			end
		end
		if #servers > 0 then
			TS:TeleportToPlaceInstance(game.PlaceId, servers[math.random(1, #servers)], player)
		end
	end)
	if not ok then
		print("OpenHub: server hop failed")
	end
end

local function clearChat()
	pcall(function()
		local chat = game:GetService("Chat")
		for _, m in ipairs(chat:GetChildren()) do
			if m.Name == "ChatMessage" then
				m:Destroy()
			end
		end
	end)
end

local function findTargets(count, allow360, maxDistanceOverride)
	local camera = W.CurrentCamera
	if not camera then
		return {}
	end
	local camPos = camera.CFrame.Position
	local center = camera.ViewportSize / 2
	local maxD = maxDistanceOverride or settings.maxDistance
	local found = {}
	local requireVisible = settings.checkVisible and not settings.wallbang
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		if settings.ignoreFriends and other:IsFriendsWith(player) then
			continue
		end
		local char = other.Character
		if not char then
			continue
		end
		if settings.teamCheck and player.Team ~= nil and player.Team == other.Team then
			continue
		end
		local humanoid = char:FindFirstChildOfClass("Humanoid")
		if humanoid and settings.ignoreDead and humanoid.Health <= 0 then
			continue
		end
		local part = char:FindFirstChild(settings.hitPart)
		if not part then
			part = char:FindFirstChild("HumanoidRootPart")
		end
		if not part then
			continue
		end
		if settings.ignoreInvis and part.Transparency >= 1 then
			if settings.stickyAim and other == stickyTarget then
				stickyTarget = nil
			end
			continue
		end
		local worldDist = (camPos - part.Position).Magnitude
		if worldDist > maxD then
			if settings.stickyAim and other == stickyTarget then
				stickyTarget = nil
			end
			continue
		end
		if requireVisible or (settings.semiWallbang and not settings.wallbang) then
			local params = RaycastParams.new()
			params.FilterType = Enum.RaycastFilterType.Blacklist
			local filter = { player.Character, char }
			if settings.ignoreBarriers then
				filter = { player.Character, char, workspace }
			end
			local result
			for attempt = 1, 6 do
				params.FilterDescendantsInstances = filter
				result = W:Raycast(camPos, (part.Position - camPos).Unit * worldDist, params)
				if not result then
					break
				end
				if settings.ignoreNonCollision and result.Instance:IsA("BasePart") and not result.Instance.CanCollide then
					table.insert(filter, result.Instance)
				else
					break
				end
			end
			if result then
				local allow = false
				if settings.semiWallbang and not settings.wallbang then
					local total = 0
					local dir = (part.Position - camPos).Unit
					local origin = camPos
					local remain = worldDist
					local filter2 = { player.Character, char }
					for i = 1, 12 do
						local segParams = RaycastParams.new()
						segParams.FilterType = Enum.RaycastFilterType.Blacklist
						segParams.FilterDescendantsInstances = filter2
						local seg = W:Raycast(origin, dir * remain, segParams)
						if not seg then
							break
						end
						local exitParams = RaycastParams.new()
						exitParams.FilterType = Enum.RaycastFilterType.Blacklist
						exitParams.FilterDescendantsInstances = { player.Character, char, seg.Instance }
						local exit = W:Raycast(seg.Position + dir * 0.1, dir * 500, exitParams)
						local thickness = exit and (exit.Position - seg.Position).Magnitude or 0.5
						total += thickness
						if total > settings.semiWallbangThickness then
							break
						end
						table.insert(filter2, seg.Instance)
						origin = seg.Position + dir * (thickness + 0.2)
						remain = (part.Position - origin).Magnitude
						if remain <= 0 then
							break
						end
					end
					if total <= settings.semiWallbangThickness then
						allow = true
					end
				end
				if not allow then
					continue
				end
			end
		end
		local isSticky = settings.stickyAim and other == stickyTarget
		local key
		if isSticky then
			key = -math.huge
		elseif allow360 then
			key = settings.aimTargetMode == "Lowest HP" and ((humanoid and humanoid.Health) or math.huge) or worldDist
		else
			local screenPos, onScreen = camera:WorldToScreenPoint(part.Position)
			if not onScreen then
				continue
			end
			local screenDist = (Vector2.new(screenPos.X, screenPos.Y) - center).Magnitude
			if screenDist > settings.fov then
				continue
			end
			if settings.aimTargetMode == "Lowest HP" then
				key = (humanoid and humanoid.Health) or math.huge
			elseif settings.aimTargetMode == "Closest" then
				key = worldDist
			else
				key = screenDist
			end
		end
		table.insert(found, { part = part, key = key, plr = other })
	end
	if lockTarget and lockTarget ~= player then
		local lchar = lockTarget.Character
		local lpart = lchar and (lchar:FindFirstChild(settings.hitPart) or lchar:FindFirstChild("HumanoidRootPart"))
		local lhum = lchar and lchar:FindFirstChildOfClass("Humanoid")
		if lpart and lhum and lhum.Health > 0 and (camPos - lpart.Position).Magnitude <= settings.maxDistance then
			found = { { part = lpart, key = 0, plr = lockTarget } }
		else
			lockTarget = nil
		end
	end
	table.sort(found, function(a, b)
		return a.key < b.key
	end)
	aimTarget = found[1] and found[1].plr or nil
	if settings.stickyAim and #found > 0 then
		stickyTarget = found[1].plr
	end
	local out = {}
	for i = 1, math.min(count, #found) do
		local entry = found[i]
		out[i] = entry.part
		if settings.prediction > 0 then
			local cchar = entry.plr.Character
			local root = cchar and cchar:FindFirstChild("HumanoidRootPart")
			local vel = (root and root.AssemblyLinearVelocity) or (entry.part.AssemblyLinearVelocity or Vector3.new())
			if vel.Magnitude > 120 then
				vel = vel.Unit * 120
			end
			local lead = ((camPos - entry.part.Position).Magnitude / 2000) * (settings.prediction / 100)
			out[i] = { Position = entry.part.Position + vel * lead }
		end
		local row = stats[entry.plr]
		if row then
			row.lastAimed = os.clock()
		end
	end
	return out
end

local function getTargetInfo()
	local camera = W.CurrentCamera
	if not camera then
		return nil
	end
	local camPos = camera.CFrame.Position
	local center = camera.ViewportSize / 2
	local best = nil
	local bestDist = math.huge
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		local char = other.Character
		if not char then
			continue
		end
		if settings.teamCheck and player.Team ~= nil and player.Team == other.Team then
			continue
		end
		local humanoid = char:FindFirstChildOfClass("Humanoid")
		if humanoid and humanoid.Health <= 0 then
			continue
		end
		local part = char:FindFirstChild(settings.hitPart)
		if not part then
			part = char:FindFirstChild("HumanoidRootPart")
		end
		if not part then
			continue
		end
		local screenPos, onScreen = camera:WorldToScreenPoint(part.Position)
		if not onScreen then
			continue
		end
		local screenDist = (Vector2.new(screenPos.X, screenPos.Y) - center).Magnitude
		if screenDist > settings.fov then
			continue
		end
		if screenDist < bestDist then
			bestDist = screenDist
			best = { name = other.Name, dist = math.round((camPos - part.Position).Magnitude) }
		end
	end
	return best
end

UIS.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		if settings.enabled then
			flicking = settings.flick
			if settings.silentAim then
				pendingSilent = true
			end
		end
		if settings.clickTp or (settings.clickTpKey and UIS:IsKeyDown(settings.clickTpKey)) then
			local cam = W.CurrentCamera
			local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
			if cam and root then
				local mousePos = UIS:GetMouseLocation()
				local ray = cam:ViewportPointToRay(mousePos.X, mousePos.Y)
				local params = RaycastParams.new()
				params.FilterType = Enum.RaycastFilterType.Blacklist
				params.FilterDescendantsInstances = { player.Character }
				local result = W:Raycast(ray.Origin, ray.Direction * 500, params)
				if result then
					root.CFrame = CFrame.new(result.Position + Vector3.new(0, 3, 0))
				end
			end
		end
	end
end)

local antiAfkTimer = 0
local clickTimer = 0

local function lowHpCandidate()
	local trigger = settings.lowHpTpTrigger
	if trigger == "Locked target" then
		return lockTarget or aimTarget
	end
	if trigger == "Player clicking" then
		for _, other in ipairs(P:GetPlayers()) do
			if other == player then
				continue
			end
			local char = other.Character
			local tool = char and char:FindFirstChildOfClass("Tool")
			local entry = lowHpToolTrack[other]
			if not tool then
				lowHpToolTrack[other] = nil
				continue
			end
			if not entry or entry.tool ~= tool then
				lowHpToolTrack[other] = { tool = tool, enabled = tool.Enabled }
				continue
			end
			local was = entry.enabled
			entry.enabled = tool.Enabled
			if was == false and tool.Enabled then
				return other
			end
		end
		return nil
	end
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		local char = other.Character
		local hum = char and char:FindFirstChildOfClass("Humanoid")
		local troot = char and char:FindFirstChild("HumanoidRootPart")
		if not hum or not troot then
			lowHpTrack[other] = nil
			continue
		end
		local health = hum.Health
		local entry = lowHpTrack[other]
		if entry and entry.char ~= char then
			entry = nil
		end
		local drop = entry and (entry.health - health) or 0
		lowHpTrack[other] = { char = char, health = health }
		if drop >= settings.lowHpTpThreshold and health > 0 then
			return other
		end
	end
	return nil
end

RS.RenderStepped:Connect(function(dt)
	updateHighlights()
	updateChams()
	updateCenterLines()
	if settings.esp and useDrawing then
		espUpdate()
	elseif useDrawing then
		hideEsp()
	end
	if useDrawing and settings.hitEffects and #hitMarkers > 0 then
		local camH = W.CurrentCamera
		for i = #hitMarkers, 1, -1 do
			local mk = hitMarkers[i]
			mk.t += dt
			if mk.t >= mk.life then
				for _, d in ipairs(mk.drawings) do
					d:Remove()
				end
				table.remove(hitMarkers, i)
			elseif camH then
				local sp, on = camH:WorldToScreenPoint(mk.pos)
				if on then
					local fade = 1 - mk.t / mk.life
					local s = 8
					for _, d in ipairs(mk.drawings) do
						d.Transparency = 1 - fade
					end
					mk.drawings[1].From = sp + Vector2.new(-s, -s)
					mk.drawings[1].To = sp + Vector2.new(s, s)
					mk.drawings[2].From = sp + Vector2.new(-s, s)
					mk.drawings[2].To = sp + Vector2.new(s, -s)
					mk.drawings[3].From = sp + Vector2.new(0, -s)
					mk.drawings[3].To = sp + Vector2.new(0, s)
					mk.drawings[4].From = sp + Vector2.new(-s, 0)
					mk.drawings[4].To = sp + Vector2.new(s, 0)
				else
					for _, d in ipairs(mk.drawings) do
						d:Remove()
					end
					table.remove(hitMarkers, i)
				end
			end
		end
	end
	local cam = W.CurrentCamera
	if cam then
		if settings.fovEnabled then
			cam.FieldOfView = settings.camFov
		elseif cam.FieldOfView ~= originalFov then
			cam.FieldOfView = originalFov
		end
	end
	local customLighting = settings.shaderPreset ~= "Normal" or settings.gloom
	if settings.clock then
		L.ClockTime = settings.clockTime
	elseif (not customLighting) and L.ClockTime ~= originalClock then
		L.ClockTime = originalClock
	end
	if settings.fog then
		L.FogStart = settings.fogDistance * 0.1
		L.FogEnd = settings.fogDistance
	elseif (not customLighting) and L.FogEnd ~= originalFogEnd then
		L.FogStart = originalFogStart
		L.FogEnd = originalFogEnd
	end
	cce.Enabled = settings.shaders
	cce.Brightness = settings.ccBrightness
	cce.Contrast = settings.ccContrast
	cce.Saturation = settings.ccSaturation
	dofEffect.Enabled = settings.dof
	if settings.dof then
		dofEffect.FocusDistance = settings.dofFocus
	end
	bloomEffect.Enabled = settings.bloom
	if settings.bloom then
		bloomEffect.Intensity = settings.bloomIntensity
	end
	if settings.materials ~= "Normal" then
		matTimer += dt
		if matTimer >= 0.5 then
			matTimer = 0
			local mat = Enum.Material[settings.materials]
			if mat then
				for _, p in ipairs(W:GetDescendants()) do
					if p:IsA("BasePart") and p.Material ~= mat then
						p.Material = mat
					end
				end
			end
		end
	end
	if settings.antiAfk then
		antiAfkTimer += dt
		if antiAfkTimer >= 60 then
			antiAfkTimer = 0
			pcall(function()
				local vu = game:GetService("VirtualUser")
				vu:CaptureController()
				vu:Button1Down(Vector2.new(0, 0))
			end)
		end
	end
	if settings.chatSpam and settings.chatMessage ~= "" then
		local remote = findChatRemote()
		if remote then
			chatTimer += dt
			if chatTimer >= settings.chatDelay then
				chatTimer = 0
				pcall(function()
					remote:FireServer(settings.chatMessage, "All")
				end)
			end
		end
	end
	if settings.autoClicker then
		clickTimer += dt
		local interval = 1 / math.max(1, settings.cps)
		if clickTimer >= interval then
			clickTimer = 0
			local vim = game:GetService("VirtualInputManager")
			local mousePos = UIS:GetMouseLocation()
			vim:SendMouseButtonEvent(mousePos.X, mousePos.Y, 0, true)
			vim:SendMouseButtonEvent(mousePos.X, mousePos.Y, 0, false)
		end
	end
	if settings.rapidFire then
		if UIS:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
			rapidT += dt
			if rapidT >= 1 / math.max(1, settings.rapidCps) then
				rapidT = 0
				local vim = game:GetService("VirtualInputManager")
				local mpos = UIS:GetMouseLocation()
				vim:SendMouseButtonEvent(mpos.X, mpos.Y, 0, true)
				vim:SendMouseButtonEvent(mpos.X, mpos.Y, 0, false)
			end
		end
	end
	if settings.noClickDelay then
		local bp = player:FindFirstChild("Backpack")
		if bp then
			for _, tool in ipairs(bp:GetChildren()) do
				if tool:IsA("Tool") then
					tool.Disabled = false
				end
			end
		end
		local equipped = player.Character and player.Character:FindFirstChildOfClass("Tool")
		if equipped then
			equipped.Disabled = false
		end
	end
	if settings.enabled and settings.killAura then
		killAuraT += dt
		if killAuraT >= 0.1 then
			killAuraT = 0
			local camK = W.CurrentCamera
			if camK then
				local targets = findTargets(1, true, settings.killAuraRange)
				if #targets > 0 then
					local aimPos = (type(targets[1]) == "table") and targets[1].Position or targets[1].Position
					camK.CFrame = CFrame.lookAt(camK.CFrame.Position, aimPos)
					fireAt(aimPos, camK)
				end
			end
		end
	end
	if settings.lowHpTp then
		lowHpTpT += dt
		if lowHpTpT >= 0.1 then
			lowHpTpT = 0
			local lroot = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
			local candidate = lowHpCandidate()
			if lroot and candidate then
				local char = candidate.Character
				local troot = char and char:FindFirstChild("HumanoidRootPart")
				if troot
					and os.clock() - lastLowHpTp >= settings.lowHpTpCooldown
					and (lroot.Position - troot.Position).Magnitude <= settings.lowHpTpRange then
					local dir = settings.lowHpTpDir
					local offset = Vector3.new(0, 0, 6)
					if dir == "Forward" then
						offset = Vector3.new(0, 0, -6)
					elseif dir == "Left" then
						offset = Vector3.new(-6, 0, 0)
					elseif dir == "Right" then
						offset = Vector3.new(6, 0, 0)
					elseif dir == "Up" then
						offset = Vector3.new(0, 6, 0)
					elseif dir == "Down" then
						offset = Vector3.new(0, -6, 0)
					end
					lroot.CFrame = troot.CFrame * offset
					lastLowHpTp = os.clock()
					print("OpenHub: LowHP teleported to " .. dir .. " of " .. candidate.Name)
				end
			end
		end
	end
	if spectateTarget then
		local stchar = spectateTarget.Character
		local stroot = stchar and (stchar:FindFirstChild("HumanoidRootPart") or stchar:FindFirstChild("Head"))
		if stroot then
			local scCam = W.CurrentCamera
			if scCam then
				scCam.CFrame = CFrame.lookAt(stroot.Position + Vector3.new(0, 2, 8), stroot.Position + Vector3.new(0, 2, 0))
			end
		else
			spectateTarget = nil
		end
	end
	if settings.stickBehind then
		local sroot = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		if sroot then
			if stickBehindTarget then
				local tchar = stickBehindTarget.Character
				local troot = tchar and tchar:FindFirstChild("HumanoidRootPart")
				local thum = tchar and tchar:FindFirstChildOfClass("Humanoid")
				if not troot or not thum or thum.Health <= 0 then
					stickBehindTarget = nil
				end
			end
			if not stickBehindTarget then
				local best = nil
				local bestD = math.huge
				for _, other in ipairs(P:GetPlayers()) do
					if other == player then
						continue
					end
					if settings.teamCheck and player.Team ~= nil and player.Team == other.Team then
						continue
					end
					if settings.ignoreFriends and other:IsFriendsWith(player) then
						continue
					end
					local char = other.Character
					local hum = char and char:FindFirstChildOfClass("Humanoid")
					local troot = char and char:FindFirstChild("HumanoidRootPart")
					if not hum or not troot or hum.Health <= 0 then
						continue
					end
					local d = (sroot.Position - troot.Position).Magnitude
					if d < bestD then
						bestD = d
						best = other
					end
				end
				stickBehindTarget = best
			end
			if stickBehindTarget then
				local tchar = stickBehindTarget.Character
				local troot = tchar and tchar:FindFirstChild("HumanoidRootPart")
				local thum = tchar and tchar:FindFirstChildOfClass("Humanoid")
				if troot and thum and thum.Health > 0 then
					sroot.CFrame = troot.CFrame * CFrame.new(0, 0, settings.stickBehindDist)
				else
					stickBehindTarget = nil
				end
			end
		end
	end
	if settings.fpsCap and settings.fpsCapValue > 0 then
		if fpsCapApplied ~= settings.fpsCapValue then
			fpsCapApplied = settings.fpsCapValue
			pcall(function() setfpscap(settings.fpsCapValue) end)
		end
	elseif fpsCapApplied then
		fpsCapApplied = nil
		pcall(function() setfpscap(60) end)
	end
	if playersScroll then
		local ptab = playersScroll.Parent and playersScroll.Parent.Parent
		if ptab and ptab.Visible then
			playersRefreshT += dt
			if playersRefreshT >= 1 then
				playersRefreshT = 0
				if refreshPlayers then
					refreshPlayers()
				end
			end
		end
	end
	if restoreCFrame then
		local camera = W.CurrentCamera
		if camera then
			camera.CFrame = restoreCFrame
		end
		restoreCFrame = nil
	end
	if settings.enabled and settings.silentAim and pendingSilent then
		pendingSilent = false
		local camera = W.CurrentCamera
		if camera then
			local targets = findTargets(1, settings.aim360 or settings.silent360)
			if #targets > 0 then
				camera.CFrame = CFrame.lookAt(camera.CFrame.Position, targets[1].Position)
			end
		end
	end
	if settings.enabled and not trickActive and (settings.aimbot or settings.autoAim) then
		local camera = W.CurrentCamera
		if camera then
			local targets = findTargets(settings.multiTarget and settings.maxTargets or 1, settings.aim360)
			if #targets > 0 then
				local pick = targets[settings.multiTarget and cycleIndex or 1]
				if settings.multiTarget then
					cycleIndex = (cycleIndex % #targets) + 1
				end
				if settings.smoothing > 0 then
					local desired = CFrame.lookAt(camera.CFrame.Position, pick.Position)
					local alpha = math.max(1 - settings.smoothing / 100, 0.05)
					camera.CFrame = camera.CFrame:Lerp(desired, alpha)
				else
					camera.CFrame = CFrame.lookAt(camera.CFrame.Position, pick.Position)
				end
			end
		end
	end
	if settings.enabled and settings.flick and flicking then
		local camera = W.CurrentCamera
		if camera then
			local original = camera.CFrame
			local targets = findTargets(settings.multiTarget and settings.maxTargets or 1, settings.aim360)
			if #targets > 0 then
				local vim = game:GetService("VirtualInputManager")
				local viewport = camera.ViewportSize
				for _, target in ipairs(targets) do
					camera.CFrame = CFrame.lookAt(camera.CFrame.Position, target.Position)
					vim:SendMouseButtonEvent(viewport.X / 2, viewport.Y / 2, 0, true)
					vim:SendMouseButtonEvent(viewport.X / 2, viewport.Y / 2, 0, false)
				end
				if settings.flickShoot then
					camera.CFrame = original
				else
					restoreCFrame = original
				end
			end
		end
	end
	if settings.enabled and settings.triggerbot then
		local camera = W.CurrentCamera
		if camera then
			local targets = findTargets(1, false)
			if #targets > 0 then
				local center = camera.ViewportSize / 2
				local sp, on = camera:WorldToScreenPoint(targets[1].Position)
				if on and (Vector2.new(sp.X, sp.Y) - center).Magnitude <= 25 then
					local vim = game:GetService("VirtualInputManager")
					vim:SendMouseButtonEvent(center.X, center.Y, 0, true)
					vim:SendMouseButtonEvent(center.X, center.Y, 0, false)
				end
			end
		end
	end
	if lockTarget and not trickActive then
		local tchar = lockTarget.Character
		local troot = tchar and tchar:FindFirstChild("HumanoidRootPart")
		local tcam = W.CurrentCamera
		if troot and tcam then
			tcam.CFrame = CFrame.lookAt(tcam.CFrame.Position, troot.Position)
		end
	end
	local tpCam = W.CurrentCamera
	if settings.thirdPerson and not trickActive then
		local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		if tpCam and root then
			tpCam.CameraType = Enum.CameraType.Scriptable
			local mouse = UIS:GetMouseLocation()
			local center = tpCam.ViewportSize / 2
			tpYaw += (mouse.X - center.X) * 0.0025
			tpPitch = math.clamp(tpPitch - (mouse.Y - center.Y) * 0.0025, -1.2, 1.2)
			local head = root.Position + Vector3.new(0, 2, 0)
			local back = CFrame.Angles(tpPitch, tpYaw, 0) * CFrame.new(0, 0, settings.tpDist)
			tpCam.CFrame = CFrame.lookAt(head + back.Position, head)
		end
	end
	if settings.spinbot then
		local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		if root then
			root.CFrame = root.CFrame * CFrame.Angles(0, math.rad(settings.spinSpeed) * dt, 0)
		end
	end
	if settings.tpWalk then
		local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		local hum = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
		if root and hum then
			local move = hum.MoveDirection
			if move.Magnitude > 0.01 then
				root.CFrame = root.CFrame + move * (settings.tpWalkSpeed * dt)
			end
		end
	end
	if settings.gravityChanger then
		if W.Gravity ~= settings.gravity then
			W.Gravity = settings.gravity
		end
	elseif W.Gravity ~= originalGravity then
		W.Gravity = originalGravity
	end
	local m1 = UIS:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)
	if settings.noSpread and m1 and not lastM1 then
		local shotCam = W.CurrentCamera
		if shotCam then
			preShotPitch = math.asin(math.clamp(shotCam.CFrame.LookVector.Y, -1, 1))
			spreadTimer = 0.08
		end
	end
	lastM1 = m1
	if settings.noSpread and preShotPitch ~= nil and W.CurrentCamera then
		local camK = W.CurrentCamera
		spreadTimer -= dt
		if spreadTimer > 0 then
			local look = camK.CFrame.LookVector
			local yaw = math.atan2(-look.X, -look.Z)
			local pitch = math.asin(math.clamp(look.Y, -1, 1))
			if math.abs(pitch - preShotPitch) > 0.0005 then
				camK.CFrame = CFrame.lookAt(camK.CFrame.Position, camK.CFrame.Position + (CFrame.Angles(preShotPitch, yaw, 0) * CFrame.new(0, 0, -1)))
			end
		else
			preShotPitch = nil
		end
	end
	if settings.noRecoil and W.CurrentCamera then
		local camR = W.CurrentCamera
		if m1 then
			local mouse = UIS:GetMouseLocation()
			if (mouse - lastMousePos).Magnitude < 0.5 then
				if noRecoilBase then
					camR.CFrame = CFrame.lookAt(camR.CFrame.Position, noRecoilBase.Position + noRecoilBase.LookVector)
				else
					noRecoilBase = camR.CFrame
				end
			else
				noRecoilBase = camR.CFrame
			end
			lastMousePos = mouse
		else
			noRecoilBase = nil
		end
	end
	if settings.antiAim then
		local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		local hum = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
		if root and hum and hum.MoveDirection.Magnitude < 0.1 and hum.FloorMaterial ~= Enum.Material.Air then
			antiAimT += dt
			if antiAimT >= 0.08 then
				antiAimT = 0
				antiAimFlip = not antiAimFlip
			end
			local angle = (antiAimFlip and 1 or -1) * math.rad(settings.antiAimAngle)
			root.CFrame = CFrame.new(root.Position) * CFrame.Angles(0, angle, 0)
		end
	end
	if settings.enabled and settings.autoShoot then
		local camA = W.CurrentCamera
		if camA then
			local targets = findTargets(1, settings.aim360)
			if #targets > 0 then
				local sp, on = camA:WorldToScreenPoint(targets[1].Position)
				local centerA = camA.ViewportSize / 2
				if on and (Vector2.new(sp.X, sp.Y) - centerA).Magnitude <= 20 then
					autoShootT += dt
					if autoShootT >= 0.12 then
						autoShootT = 0
						fireAt(targets[1], camA)
					end
				else
					autoShootT = 0
				end
			end
		end
	end
	local char = player.Character
	local humanoid = char and char:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.WalkSpeed = settings.walkspeed
		humanoid.JumpPower = settings.jumpPower
		if settings.swimBoost and humanoid:GetState() == Enum.HumanoidStateType.Swimming then
			humanoid.WalkSpeed = settings.swimSpeed
		end
		if settings.autoSprint and not settings.fly and humanoid.MoveDirection.Magnitude > 0.1 and humanoid.FloorMaterial ~= Enum.Material.Air then
			humanoid:ChangeState(Enum.HumanoidStateType.Running)
		end
		if settings.wallClimb then
			local wroot = char:FindFirstChild("HumanoidRootPart")
			if wroot and humanoid.FloorMaterial == Enum.Material.Air and UIS:IsKeyDown(Enum.KeyCode.W) then
				local wdir = humanoid.MoveDirection
				if wdir.Magnitude > 0.1 then
					local wparams = RaycastParams.new()
					wparams.FilterType = Enum.RaycastFilterType.Blacklist
					wparams.FilterDescendantsInstances = { char }
					if W:Raycast(wroot.Position, wdir.Unit * 4, wparams) then
						wroot.AssemblyLinearVelocity = Vector3.new(0, 50, 0)
					end
				end
			end
		end
		if settings.strafe then
			if UIS:IsKeyDown(Enum.KeyCode.A) or UIS:IsKeyDown(Enum.KeyCode.D) then
				humanoid.WalkSpeed = settings.strafeSpeed
			end
		end
		if settings.bhop and not settings.fly and humanoid.MoveDirection.Magnitude > 0.1 and humanoid.FloorMaterial ~= Enum.Material.Air then
			humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		end
		if settings.strafeV2 and not settings.fly then
			local vroot = char:FindFirstChild("HumanoidRootPart")
			if vroot then
				local camV = W.CurrentCamera
				if camV then
					local forward = (UIS:IsKeyDown(Enum.KeyCode.W) and 1 or 0) - (UIS:IsKeyDown(Enum.KeyCode.S) and 1 or 0)
					local strafe = (UIS:IsKeyDown(Enum.KeyCode.D) and 1 or 0) - (UIS:IsKeyDown(Enum.KeyCode.A) and 1 or 0)
					local up = (UIS:IsKeyDown(Enum.KeyCode.Space) and 1 or 0) - (UIS:IsKeyDown(Enum.KeyCode.LeftControl) and 1 or 0)
					local move = camV.CFrame.LookVector * forward + camV.CFrame.RightVector * strafe
					if move.Magnitude > 0.01 then
						move = move.Unit * settings.strafeV2Speed
					else
						move = Vector3.new()
					end
					if up ~= 0 then
						vroot.AssemblyLinearVelocity = Vector3.new(move.X, up * settings.strafeV2Speed, move.Z)
					else
						vroot.AssemblyLinearVelocity = Vector3.new(move.X, vroot.AssemblyLinearVelocity.Y, move.Z)
					end
				end
			end
		end
		if settings.infJump and not settings.fly and UIS:IsKeyDown(Enum.KeyCode.Space) then
			if humanoid.FloorMaterial ~= Enum.Material.Air then
				humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			end
		end
		if settings.noclip then
			for _, p in ipairs(char:GetDescendants()) do
				if p:IsA("BasePart") then
					p.CanCollide = false
				end
			end
		end
		if settings.speedHack and not settings.fly then
			local sroot = char:FindFirstChild("HumanoidRootPart")
			if sroot then
				local v = sroot.AssemblyLinearVelocity
				sroot.AssemblyLinearVelocity = Vector3.new(v.X * settings.speedHackMult, v.Y, v.Z * settings.speedHackMult)
			end
		end
		if settings.hitboxExtend then
			if hitboxChar ~= char or hitboxScale ~= settings.hitboxExtendScale then
				rebuildHitbox(char)
			end
		elseif #hitboxParts > 0 then
			clearHitbox()
		end
	end
	if settings.scan then
		scanTick()
	end
end)

local screenGui = Instance.new("ScreenGui")
screenGui.Name = "OpenHub"
screenGui.ResetOnSpawn = false
screenGui.IgnoreGuiInset = true
screenGui.DisplayOrder = 1000
screenGui.Parent = player:WaitForChild("PlayerGui")
print("Hub: gui parented")

local function cleanupOldHubs()
	for _, g in ipairs(player.PlayerGui:GetChildren()) do
		if g:IsA("ScreenGui") and g.Name == "OpenHub" and g ~= screenGui then
			g:Destroy()
		end
	end
end

local main = Instance.new("Frame")
main.Size = UDim2.fromOffset(440, 430)
main.Position = UDim2.new(0.5, -220, 0.5, -215)
main.BackgroundColor3 = theme.bg
main.BorderSizePixel = 0
main.Visible = false
main.Parent = screenGui
corner(main, 6)

local titleBar = Instance.new("Frame")
titleBar.Size = UDim2.new(1, 0, 0, 38)
titleBar.BackgroundColor3 = theme.bg2
titleBar.BorderSizePixel = 0
titleBar.Parent = main
corner(titleBar, 6)

local titleLabel = new("TextLabel", {
	Size = UDim2.new(1, -60, 1, 0),
	Position = UDim2.fromOffset(10, 0),
	BackgroundTransparency = 1,
	Text = "OpenHub",
	TextColor3 = theme.accent,
	TextSize = 15,
	Font = Enum.Font.GothamBold,
	TextXAlignment = Enum.TextXAlignment.Left,
})
titleLabel.Parent = titleBar

local dragging = false
local dragOffset = Vector2.zero
titleBar.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		dragging = true
		dragOffset = UIS:GetMouseLocation() - main.AbsolutePosition
	end
end)
UIS.InputChanged:Connect(function(input)
	if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
		local mouse = UIS:GetMouseLocation()
		main.Position = UDim2.fromOffset(mouse.X - dragOffset.X, mouse.Y - dragOffset.Y)
	end
end)
UIS.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		dragging = false
		flicking = false
	end
end)

local closeBtn = new("TextButton", {
	Size = UDim2.fromOffset(28, 28),
	Position = UDim2.new(1, -34, 0, 5),
	BackgroundColor3 = theme.btnLight,
	Text = "x",
	TextColor3 = theme.text,
	TextSize = 14,
	Font = Enum.Font.GothamBold,
})
closeBtn.Parent = titleBar
corner(closeBtn, 5)
closeBtn.Activated:Connect(function()
	settings.fly = false
	setFly(false)
	setFreecam(false)
	hideEsp()
	if useDrawing then
		for _, d in pairs(espDrawings) do
			d.box:Remove()
			d.name:Remove()
			d.health:Remove()
			d.tracer:Remove()
			for _, ln in ipairs(d.corners) do
				ln:Remove()
			end
		end
		for _, sk in pairs(skeletonDrawings) do
			for _, l in ipairs(sk.lines) do
				l:Remove()
			end
		end
		for _, line in pairs(centerLines) do
			line:Remove()
		end
	end
	for _, h in pairs(highlights) do
		h:Destroy()
	end
	for _, obj in pairs(chamsObjs) do
		if obj.model then
			obj.model:Destroy()
		end
		if obj.highlight then
			obj.highlight:Destroy()
		end
	end
	espDrawings = {}
	skeletonDrawings = {}
	highlights = {}
	chamsObjs = {}
	centerLines = {}
	charBounds = {}
	clearHitbox()
	setNetworkLag(0)
	screenGui:Destroy()
end)

local tabBar = Instance.new("Frame")
tabBar.Size = UDim2.fromOffset(90, 392)
tabBar.Position = UDim2.new(1, -90, 0, 38)
tabBar.BackgroundColor3 = theme.bg
tabBar.BorderSizePixel = 0
tabBar.Parent = main
corner(tabBar, 6)

local tabNames = { "ESP", "Combat", "Movement", "Misc", "World", "Shader", "Server", "Players", "Chams", "AntiCheat", "Settings" }
local tabButtons = {}
local tabFrames = {}
local tabScales = {}
local cursors = {}
local activeTab = "ESP"

local function cursorOf(parent)
	cursors[parent] = cursors[parent] or 10
	return cursors[parent]
end

local function advance(parent, height)
	cursors[parent] = cursorOf(parent) + height + 8
end

local function newContentTab(name)
	local frame = Instance.new("ScrollingFrame")
	frame.Size = UDim2.new(1, -94, 1, -46)
	frame.Position = UDim2.fromOffset(0, 38)
	frame.BackgroundTransparency = 1
	frame.ScrollBarThickness = 4
	frame.CanvasSize = UDim2.fromOffset(0, 10)
	frame.Visible = false
	frame.Parent = main
	local scale = Instance.new("UIScale")
	scale.Scale = 1
	scale.Parent = frame
	tabScales[name] = scale
	tabFrames[name] = frame
	return frame
end

for _, name in ipairs(tabNames) do
	local btn = Instance.new("TextButton")
	btn.Size = UDim2.fromScale(1, 1 / #tabNames)
	local index = table.find(tabNames, name) or 1
	btn.Position = UDim2.fromScale(0, (index - 1) / #tabNames)
	btn.BackgroundColor3 = theme.btn
	btn.Text = name
	btn.TextColor3 = theme.text
	btn.TextSize = 12
	btn.Font = Enum.Font.GothamBold
	btn.BorderSizePixel = 0
	btn.Parent = tabBar
	tabButtons[name] = btn
	btn.Activated:Connect(function()
		activeTab = name
		for n, f in pairs(tabFrames) do
			f.Visible = (n == name)
		end
		for n, b in pairs(tabButtons) do
			b.BackgroundColor3 = (n == name) and theme.accentDark or theme.btn
		end
		local sf = tabScales[name]
		if sf then
			sf.Scale = 0.96
			tweenProps(sf, 0.12, { Scale = 1 })
		end
	end)
end

local minimized = false
local function setMinimized(v)
	minimized = v
	if v then
		main.Size = UDim2.fromOffset(440, 38)
		tabBar.Visible = false
		for _, f in pairs(tabFrames) do
			f.Visible = false
		end
	else
		main.Size = UDim2.fromOffset(440, 430)
		tabBar.Visible = true
		for n, f in pairs(tabFrames) do
			f.Visible = (n == activeTab)
		end
		for n, b in pairs(tabButtons) do
			b.BackgroundColor3 = (n == activeTab) and theme.accentDark or theme.btn
		end
	end
end

local minimizeBtn = new("TextButton", {
	Size = UDim2.fromOffset(28, 28),
	Position = UDim2.new(1, -68, 0, 5),
	BackgroundColor3 = theme.btnLight,
	Text = "-",
	TextColor3 = theme.text,
	TextSize = 14,
	Font = Enum.Font.GothamBold,
})
minimizeBtn.Parent = titleBar
corner(minimizeBtn, 5)
minimizeBtn.Activated:Connect(function()
	setMinimized(not minimized)
end)

local function addSection(parent, text)
	local label = new("TextLabel", {
		Size = UDim2.new(1, -20, 0, 16),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundTransparency = 1,
		Text = text,
		TextColor3 = theme.accent,
		TextSize = 12,
		Font = Enum.Font.GothamBold,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	label.Parent = parent
	advance(parent, 16)
end

local function addToggle(parent, title, default, callback)
	local value = default
	local row = new("Frame", {
		Size = UDim2.new(1, -20, 0, 28),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundTransparency = 1,
	})
	row.Parent = parent
	local box = new("TextButton", {
		Size = UDim2.fromOffset(22, 22),
		Position = UDim2.fromOffset(0, 3),
		BackgroundColor3 = theme.btn,
		Text = "",
		AutoButtonColor = false,
	})
	box.Parent = row
	corner(box, 5)
	local check = new("TextLabel", {
		Size = UDim2.new(1, 0, 1, 0),
		BackgroundTransparency = 1,
		Text = "\u{2713}",
		TextColor3 = theme.bg,
		TextSize = 14,
		Font = Enum.Font.GothamBold,
		Visible = false,
	})
	check.Parent = box
	local label = new("TextButton", {
		Size = UDim2.new(1, -30, 1, 0),
		Position = UDim2.fromOffset(30, 0),
		BackgroundTransparency = 1,
		Text = title,
		TextColor3 = theme.text,
		TextSize = 14,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	label.Parent = row
	local function update()
		if value then
			box.BackgroundColor3 = theme.accent
			check.Visible = true
			label.TextColor3 = theme.accent
		else
			box.BackgroundColor3 = theme.btn
			check.Visible = false
			label.TextColor3 = theme.text
		end
	end
	update()
	local function click()
		value = not value
		update()
		callback(value)
	end
	box.Activated:Connect(click)
	label.Activated:Connect(click)
	advance(parent, 28)
end

local function addSlider(parent, title, min, max, default, callback)
	local value = default
	local label = new("TextLabel", {
		Size = UDim2.new(1, -20, 0, 18),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundTransparency = 1,
		Text = title .. ": " .. string.format("%.0f", value),
		TextColor3 = theme.text,
		TextSize = 13,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	label.Parent = parent
	advance(parent, 18)
	local bar = new("TextButton", {
		Size = UDim2.new(1, -20, 0, 12),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundColor3 = theme.btnLight,
		Text = "",
	})
	bar.Parent = parent
	corner(bar, 6)
	local fill = new("Frame", {
		Size = UDim2.fromScale(0, 1),
		BackgroundColor3 = theme.accent,
		BorderSizePixel = 0,
	})
	fill.Parent = bar
	corner(fill, 6)
	local function setRatio(ratio)
		ratio = math.clamp(ratio, 0, 1)
		value = min + (max - min) * ratio
		fill.Size = UDim2.fromScale(ratio, 1)
		label.Text = title .. ": " .. string.format("%.0f", value)
		callback(value)
	end
	setRatio((default - min) / (max - min))
	local sliderDragging = false
	bar.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			sliderDragging = true
			setRatio((input.Position.X - bar.AbsolutePosition.X) / bar.AbsoluteSize.X)
		end
	end)
	UIS.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			sliderDragging = false
		end
	end)
	UIS.InputChanged:Connect(function(input)
		if sliderDragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
			setRatio((input.Position.X - bar.AbsolutePosition.X) / bar.AbsoluteSize.X)
		end
	end)
	advance(parent, 12)
end

local function addDropdown(parent, title, getOptions, default, callback)
	local current = default
	local button = new("TextButton", {
		Size = UDim2.new(1, -20, 0, 36),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundColor3 = theme.btn,
		Text = title .. ": " .. current,
		TextColor3 = theme.text,
		TextSize = 14,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	button.Parent = parent
	corner(button, 6)
	local menu = new("Frame", {
		Size = UDim2.fromOffset(280, 0),
		Position = UDim2.fromOffset(0, 0),
		BackgroundColor3 = theme.bg2,
		BorderSizePixel = 0,
		Visible = false,
		ZIndex = 50,
	})
	menu.Parent = main
	corner(menu, 6)
	local menuScale = Instance.new("UIScale")
	menuScale.Parent = menu
	local function positionMenu()
		local anchor = button.AbsolutePosition + Vector2.new(0, button.AbsoluteSize.Y)
		menu.Position = UDim2.fromOffset(anchor.X - main.AbsolutePosition.X, anchor.Y - main.AbsolutePosition.Y)
	end
	local function refresh()
		menu:ClearAllChildren()
		local options = getOptions()
		for index, option in ipairs(options) do
			local item = new("TextButton", {
				Size = UDim2.new(1, 0, 0, 32),
				Position = UDim2.fromOffset(0, (index - 1) * 32),
				BackgroundColor3 = option == current and theme.accentDark or theme.btn,
				Text = option,
				TextColor3 = theme.text,
				TextSize = 13,
				Font = Enum.Font.Gotham,
				BorderSizePixel = 0,
				ZIndex = 50,
			})
			item.Parent = menu
			item.Activated:Connect(function()
				current = option
				button.Text = title .. ": " .. current
				menu.Visible = false
				refresh()
				callback(option)
			end)
		end
		menu.Size = UDim2.fromOffset(280, #options * 32)
		positionMenu()
	end
	refresh()
	button.Activated:Connect(function()
		menu.Visible = not menu.Visible
		if menu.Visible then
			refresh()
			menuScale.Scale = 0.85
			tweenProps(menuScale, 0.12, { Scale = 1 })
		end
	end)
	advance(parent, 36)
end

local function addButton(parent, title, callback)
	local button = new("TextButton", {
		Size = UDim2.new(1, -20, 0, 36),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundColor3 = theme.accentDark,
		Text = title,
		TextColor3 = theme.text,
		TextSize = 14,
		Font = Enum.Font.GothamBold,
	})
	button.Parent = parent
	corner(button, 6)
	button.Activated:Connect(callback)
	advance(parent, 36)
end

local function addInfo(parent, text)
	local label = new("TextLabel", {
		Size = UDim2.new(1, -20, 0, 20),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundTransparency = 1,
		Text = text,
		TextColor3 = theme.dim,
		TextSize = 12,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	label.Parent = parent
	advance(parent, 20)
end

local function telekill(plr)
	local start = os.clock()
	local conn
	conn = RS.RenderStepped:Connect(function()
		if os.clock() - start > 2 then
			conn:Disconnect()
			return
		end
		local tchar = plr.Character
		local root = tchar and tchar:FindFirstChild("HumanoidRootPart")
		local hum = tchar and tchar:FindFirstChildOfClass("Humanoid")
		if not root or not hum or hum.Health <= 0 then
			conn:Disconnect()
			return
		end
		root.CFrame = CFrame.new(root.Position.X, root.Position.Y - 500, root.Position.Z)
	end)
end

RS.RenderStepped:Connect(function(dt)
	if settings.massKill then
		massKillTick += dt
		if massKillTick >= math.max(0.5, settings.massKillDelay) then
			massKillTick = 0
			for _, other in ipairs(P:GetPlayers()) do
				if other ~= player then
					telekill(other)
				end
			end
		end
	end
	if settings.bringAll then
		bringAllFront()
	end
end)

local function scanAddSus(plr, reason, points, note)
	local row = scanSus[plr]
	if not row then
		return
	end
	local seen = false
	for i, r in ipairs(row.reasons) do
		if r[1] == reason then
			r[2] = os.clock()
			r[3] = note
			seen = true
			break
		end
	end
	if not seen then
		table.insert(row.reasons, { reason, os.clock(), note })
	end
	row.score = math.min(999, row.score + points)
	if row.score >= 100 then
		row.flagged = true
	end
end

scanTick = function()
	local now = os.clock()
	for _, plr in ipairs(P:GetPlayers()) do
		if plr == player then
			continue
		end
		local char = plr.Character
		if char and not scanWatched[char] then
			scanWatched[char] = true
			local hum = char:FindFirstChildOfClass("Humanoid")
			if hum then
				local lastH = hum.Health
				hum:GetPropertyChangedSignal("Health"):Connect(function()
					local cur = hum.Health
					if cur < lastH then
						local row = scanHits[plr]
						if not row then
							row = { count = 0, t = 0, shooter = nil }
							scanHits[plr] = row
						end
						if now - row.t > 1 then
							row.count = 0
							row.shooter = nil
							row.t = now
						end
						row.count += 1
						local vroot = plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")
						local best, bestDot = nil, -1
						if vroot then
							for _, other in ipairs(P:GetPlayers()) do
								if other == plr or other == player then
									continue
								end
								local och = other.Character
								local oroot = och and och:FindFirstChild("HumanoidRootPart")
								if oroot then
									local toVictim = vroot.Position - oroot.Position
									local d = toVictim.Magnitude
									if d > 1 and d < 200 then
										local dot = oroot.CFrame.LookVector:Dot(toVictim / d)
										if dot > bestDot then
											bestDot = dot
											best = other
										end
									end
								end
							end
						end
						if best then
							row.shooter = best
						end
						if row.count >= 7 then
							if row.shooter then
								scanAddSus(row.shooter, "Rapid fire", 40, "rapid damage on " .. plr.Name)
							end
							row.count = 0
							row.shooter = nil
							row.t = now
						end
					end
					lastH = cur
				end)
			end
		end
	end
	if now - (scanLastTick or 0) < 0.2 then
		return
	end
	scanLastTick = now
	for _, plr in ipairs(P:GetPlayers()) do
		if plr == player then
			continue
		end
		local char = plr.Character
		local row = scanSus[plr]
		if not char then
			scanSus[plr] = nil
			scanSample[plr] = nil
		else
			if not row then
				row = { score = 0, reasons = {}, flagged = false }
				scanSus[plr] = row
			end
			local root = char:FindFirstChild("HumanoidRootPart")
			local hum = char:FindFirstChildOfClass("Humanoid")
			local s = scanSample[plr]
			if root and hum then
				local pos = root.Position
				local vel = root.AssemblyLinearVelocity or Vector3.new()
				local speed = vel.Magnitude
				local airborne = hum.FloorMaterial == Enum.Material.Air or hum:GetState() == Enum.HumanoidStateType.Freefall
				if s then
					local dt = now - s.t
					if dt > 0 and dt < 0.5 then
						local dist = (pos - s.pos).Magnitude
						if dist > 45 then
							scanAddSus(plr, "Teleport", 35, math.floor(dist) .. " studs in " .. math.floor(dt * 100) .. "ms")
						elseif speed > settings.cheatSpeed and (dist / dt) > settings.cheatSpeed then
							scanAddSus(plr, "Speed", 25, math.floor(speed) .. " studs/s")
						end
						if airborne then
							if now - s.airborneSince > 3 and math.abs(vel.Y) < 8 then
								scanAddSus(plr, "Fly", 30, "hovering mid-air")
							end
							if vel.Y > 18 then
								if now - s.upSince > 1 then
									scanAddSus(plr, "Fly", 30, "rising at " .. math.floor(vel.Y) .. " studs/s")
								end
							else
								s.upSince = now
							end
						else
							s.airborneSince = now
							s.upSince = now
						end
						if hum:GetState() == Enum.HumanoidStateType.Running then
							local params = RaycastParams.new()
							params.FilterType = Enum.RaycastFilterType.Blacklist
							params.FilterDescendantsInstances = { char }
							local ray = W:Raycast(pos, Vector3.new(0, 1, 0) * 4, params)
							if ray and ray.Distance < 0.7 then
								scanAddSus(plr, "Noclip", 25, "inside geometry")
							end
						end
					end
				end
				scanSample[plr] = {
					pos = pos,
					t = now,
					airborneSince = s and s.airborneSince or now,
					upSince = s and s.upSince or now,
				}
			else
				scanSample[plr] = nil
			end
		end
		if row then
			row.score = math.max(0, row.score - 0.4)
			if row.score < 40 then
				row.flagged = false
			end
			if #row.reasons > 0 then
				for i = #row.reasons, 1, -1 do
					if now - row.reasons[i][2] > 6 then
						table.remove(row.reasons, i)
					end
				end
			end
			if row.score == 0 then
				row.reasons = {}
			end
		end
	end
	if lockTarget then
		local lchar = lockTarget.Character
		local lhum = lchar and lchar:FindFirstChildOfClass("Humanoid")
		if not (lchar and lhum and lhum.Health > 0) then
			lockTarget = nil
		end
	end
	if now - (scanUiTimer or 0) >= 0.5 then
		scanUiTimer = now
		refreshCheatersUI()
	end
end

local function buildCheaterRow(plr)
	local frame = new("Frame", {
		Size = UDim2.new(1, -8, 0, 56),
		Position = UDim2.fromOffset(6, 6),
		BackgroundColor3 = theme.bg2,
		BorderSizePixel = 0,
	})
	frame.Parent = cheaterScroll
	corner(frame, 6)
	local name = new("TextLabel", {
		Size = UDim2.new(1, -84, 0, 18),
		Position = UDim2.fromOffset(6, 4),
		BackgroundTransparency = 1,
		Text = plr.Name,
		TextColor3 = theme.red,
		TextSize = 13,
		Font = Enum.Font.GothamBold,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	name.Parent = frame
	local score = new("TextLabel", {
		Size = UDim2.new(0, 74, 0, 16),
		Position = UDim2.new(1, -80, 0, 5),
		BackgroundTransparency = 1,
		Text = "risk 0",
		TextColor3 = theme.accent,
		TextSize = 11,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Right,
	})
	score.Parent = frame
	local reasons = new("TextLabel", {
		Size = UDim2.new(1, -12, 0, 16),
		Position = UDim2.fromOffset(6, 21),
		BackgroundTransparency = 1,
		Text = "",
		TextColor3 = theme.dim,
		TextSize = 10,
		Font = Enum.Font.Gotham,
		TextWrapped = true,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	reasons.Parent = frame
	local kill = new("TextButton", {
		Size = UDim2.new(0, 48, 0, 20),
		Position = UDim2.fromOffset(6, 34),
		BackgroundColor3 = theme.red,
		Text = "Kill",
		TextColor3 = theme.bg,
		TextSize = 11,
		Font = Enum.Font.GothamBold,
		BorderSizePixel = 0,
	})
	kill.Parent = frame
	corner(kill, 4)
	kill.Activated:Connect(function()
		telekill(plr)
	end)
	local tp = new("TextButton", {
		Size = UDim2.new(0, 48, 0, 20),
		Position = UDim2.fromOffset(60, 34),
		BackgroundColor3 = theme.accentDark,
		Text = "TP",
		TextColor3 = theme.text,
		TextSize = 11,
		Font = Enum.Font.GothamBold,
		BorderSizePixel = 0,
	})
	tp.Parent = frame
	corner(tp, 4)
	tp.Activated:Connect(function()
		teleportTo(plr)
	end)
	local lock = new("TextButton", {
		Size = UDim2.new(0, 56, 0, 20),
		Position = UDim2.fromOffset(114, 34),
		BackgroundColor3 = theme.btn,
		Text = "Lock",
		TextColor3 = theme.text,
		TextSize = 11,
		Font = Enum.Font.GothamBold,
		BorderSizePixel = 0,
	})
	lock.Parent = frame
	corner(lock, 4)
	lock.Activated:Connect(function()
		lockTarget = (lockTarget == plr) and nil or plr
		refreshCheatersUI()
	end)
	return { frame = frame, name = name, score = score, reasons = reasons, lock = lock }
end

refreshCheatersUI = function()
	if not cheaterScroll then
		return
	end
	local flagged = {}
	for plr, row in pairs(scanSus) do
		if row.flagged then
			table.insert(flagged, plr)
		end
	end
	table.sort(flagged, function(a, b)
		return (scanSus[a].score or 0) > (scanSus[b].score or 0)
	end)
	for plr, row in pairs(cheaterRows) do
		if not scanSus[plr] or not scanSus[plr].flagged then
			row.frame:Destroy()
			cheaterRows[plr] = nil
		end
	end
	for i, plr in ipairs(flagged) do
		local row = cheaterRows[plr]
		if not row then
			row = buildCheaterRow(plr)
			cheaterRows[plr] = row
		end
		row.frame.Position = UDim2.fromOffset(6, (i - 1) * 62 + 6)
		row.frame.Visible = true
		local sus = scanSus[plr]
		row.name.Text = plr.Name
		local reasonText = {}
		for _, r in ipairs(sus.reasons) do
			table.insert(reasonText, r[3] and (r[1] .. " (" .. r[3] .. ")") or r[1])
		end
		row.reasons.Text = #reasonText > 0 and table.concat(reasonText, ", ") or "flagging..."
		row.score.Text = "risk " .. math.floor(sus.score)
		row.lock.Text = (lockTarget == plr) and "Locked" or "Lock"
		row.lock.BackgroundColor3 = (lockTarget == plr) and theme.accent or theme.btn
	end
	if cheaterScroll then
		cheaterScroll.CanvasSize = UDim2.fromOffset(0, #flagged * 62 + 12)
	end
end

local function addTextBox(parent, title, default, callback)
	local label = new("TextLabel", {
		Size = UDim2.new(1, -20, 0, 16),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundTransparency = 1,
		Text = title,
		TextColor3 = theme.dim,
		TextSize = 12,
		Font = Enum.Font.GothamBold,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	label.Parent = parent
	advance(parent, 16)
	local box = new("TextBox", {
		Size = UDim2.new(1, -20, 0, 34),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundColor3 = theme.btn,
		Text = default,
		PlaceholderText = title,
		TextColor3 = theme.text,
		PlaceholderColor3 = theme.dim,
		TextSize = 14,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
		ClearTextOnFocus = false,
	})
	box.Parent = parent
	corner(box, 6)
	box.FocusLost:Connect(function()
		callback(box.Text)
	end)
	advance(parent, 34)
end

local fovPalette = {
	{ "Green", Color3.fromRGB(90, 255, 120) },
	{ "Red", Color3.fromRGB(255, 90, 90) },
	{ "Yellow", Color3.fromRGB(255, 230, 90) },
	{ "White", Color3.fromRGB(255, 255, 255) },
	{ "Cyan", Color3.fromRGB(90, 220, 255) },
	{ "Orange", Color3.fromRGB(255, 160, 80) },
	{ "Pink", Color3.fromRGB(255, 120, 200) },
	{ "Purple", Color3.fromRGB(180, 120, 255) },
	{ "Blue", Color3.fromRGB(90, 140, 255) },
}

local function colorName(c)
	for _, p in ipairs(fovPalette) do
		if p[2] == c then
			return p[1]
		end
	end
	return "Custom"
end

local function addColorPicker(parent, title, default, callback)
	local current = default
	local button = new("TextButton", {
		Size = UDim2.new(1, -20, 0, 36),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundColor3 = theme.btn,
		Text = title .. ": " .. colorName(current),
		TextColor3 = theme.text,
		TextSize = 14,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	button.Parent = parent
	corner(button, 6)
	local swatch = new("Frame", {
		Size = UDim2.fromOffset(20, 20),
		Position = UDim2.new(1, -28, 0.5, -10),
		BackgroundColor3 = current,
		BorderSizePixel = 0,
	})
	swatch.Parent = button
	corner(swatch, 4)
	local menu = new("Frame", {
		Size = UDim2.fromOffset(280, 0),
		Position = UDim2.fromOffset(0, 0),
		BackgroundColor3 = theme.bg2,
		BorderSizePixel = 0,
		Visible = false,
		ZIndex = 50,
	})
	menu.Parent = main
	corner(menu, 6)
	local menuScale = Instance.new("UIScale")
	menuScale.Parent = menu
	local function positionMenu()
		local anchor = button.AbsolutePosition + Vector2.new(0, button.AbsoluteSize.Y)
		menu.Position = UDim2.fromOffset(anchor.X - main.AbsolutePosition.X, anchor.Y - main.AbsolutePosition.Y)
	end
	local function refresh()
		menu:ClearAllChildren()
		for index, p in ipairs(fovPalette) do
			local item = new("TextButton", {
				Size = UDim2.new(1, 0, 0, 28),
				Position = UDim2.fromOffset(0, (index - 1) * 28),
				BackgroundColor3 = p[2] == current and theme.accentDark or theme.btn,
				Text = "   " .. p[1],
				TextColor3 = theme.text,
				TextSize = 13,
				Font = Enum.Font.Gotham,
				BorderSizePixel = 0,
				TextXAlignment = Enum.TextXAlignment.Left,
				ZIndex = 50,
			})
			item.Parent = menu
			local dot = new("Frame", {
				Size = UDim2.fromOffset(12, 12),
				Position = UDim2.fromOffset(8, 8),
				BackgroundColor3 = p[2],
				BorderSizePixel = 0,
				ZIndex = 50,
			})
			dot.Parent = item
			corner(dot, 6)
			item.Activated:Connect(function()
				current = p[2]
				button.Text = title .. ": " .. p[1]
				swatch.BackgroundColor3 = current
				menu.Visible = false
				callback(current)
			end)
		end
		menu.Size = UDim2.fromOffset(280, #fovPalette * 28)
		positionMenu()
	end
	refresh()
	button.Activated:Connect(function()
		menu.Visible = not menu.Visible
		if menu.Visible then
			refresh()
			menuScale.Scale = 0.85
			tweenProps(menuScale, 0.12, { Scale = 1 })
		end
	end)
	advance(parent, 36)
end

local function colorToHex(c)
	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

local function hexToColor(h)
	local clean = (h or ""):gsub("#", ""):gsub("%s", "")
	if #clean == 6 then
		local r = tonumber(clean:sub(1, 2), 16)
		local g = tonumber(clean:sub(3, 4), 16)
		local b = tonumber(clean:sub(5, 6), 16)
		if r and g and b then
			return Color3.fromRGB(r, g, b)
		end
	end
	return nil
end

local function addHexColorPicker(parent, title, default, callback)
	local current = default
	local button = new("TextButton", {
		Size = UDim2.new(1, -20, 0, 36),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundColor3 = theme.btn,
		Text = title .. ": " .. colorToHex(current),
		TextColor3 = theme.text,
		TextSize = 14,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	button.Parent = parent
	corner(button, 6)
	local swatch = new("Frame", {
		Size = UDim2.fromOffset(20, 20),
		Position = UDim2.new(1, -28, 0.5, -10),
		BackgroundColor3 = current,
		BorderSizePixel = 0,
		ZIndex = 50,
	})
	swatch.Parent = button
	corner(swatch, 4)
	local menu = new("Frame", {
		Size = UDim2.fromOffset(260, 190),
		Position = UDim2.fromOffset(0, 0),
		BackgroundColor3 = theme.bg2,
		BorderSizePixel = 0,
		Visible = false,
		ZIndex = 50,
	})
	menu.Parent = main
	corner(menu, 6)
	local menuScale = Instance.new("UIScale")
	menuScale.Parent = menu
	local function positionMenu()
		local anchor = button.AbsolutePosition + Vector2.new(0, button.AbsoluteSize.Y)
		menu.Position = UDim2.fromOffset(anchor.X - main.AbsolutePosition.X, anchor.Y - main.AbsolutePosition.Y)
	end
	local preview = new("Frame", {
		Size = UDim2.fromOffset(24, 24),
		Position = UDim2.fromOffset(222, 12),
		BackgroundColor3 = current,
		BorderSizePixel = 0,
		ZIndex = 50,
	})
	preview.Parent = menu
	corner(preview, 4)
	local hexBox = new("TextBox", {
		Size = UDim2.new(1, -40, 0, 30),
		Position = UDim2.fromOffset(12, 8),
		BackgroundColor3 = theme.btn,
		PlaceholderText = "#RRGGBB",
		Text = colorToHex(current),
		TextColor3 = theme.text,
		TextSize = 13,
		Font = Enum.Font.GothamBold,
		ClearTextOnFocus = false,
		ZIndex = 50,
	})
	hexBox.Parent = menu
	corner(hexBox, 4)
	local sliders = {}
	local function channelOf(name)
		if name == "R" then
			return current.R
		elseif name == "G" then
			return current.G
		end
		return current.B
	end
	local function applyColor(newColor)
		current = newColor
		swatch.BackgroundColor3 = current
		preview.BackgroundColor3 = current
		hexBox.Text = colorToHex(current)
		for _, s in ipairs(sliders) do
			local ch = channelOf(s.ch)
			s.fill.Size = UDim2.fromScale(ch, 1)
			s.label.Text = s.ch .. ": " .. string.format("%.0f", ch * 255)
		end
		callback(current)
	end
	local function makeSlider(ch, y)
		local label = new("TextLabel", {
			Size = UDim2.new(1, -24, 0, 14),
			Position = UDim2.fromOffset(12, y),
			BackgroundTransparency = 1,
			Text = ch .. ": ",
			TextColor3 = theme.text,
			TextSize = 12,
			Font = Enum.Font.Gotham,
			TextXAlignment = Enum.TextXAlignment.Left,
			ZIndex = 50,
		})
		label.Parent = menu
		local bar = new("TextButton", {
			Size = UDim2.new(1, -80, 0, 10),
			Position = UDim2.fromOffset(60, y),
			BackgroundColor3 = theme.btnLight,
			Text = "",
			ZIndex = 50,
		})
		bar.Parent = menu
		corner(bar, 4)
		local fill = new("Frame", {
			Size = UDim2.fromScale(0, 1),
			BackgroundColor3 = theme.accent,
			BorderSizePixel = 0,
			ZIndex = 50,
		})
		fill.Parent = bar
		corner(fill, 4)
		local slider = { ch = ch, label = label, bar = bar, fill = fill }
		local dragging = false
		local function setRatio(ratio)
			ratio = math.clamp(ratio, 0, 1)
			local v = ratio * 255
			fill.Size = UDim2.fromScale(ratio, 1)
			label.Text = ch .. ": " .. string.format("%.0f", v)
			local nc = Color3.fromRGB(
				ch == "R" and v or current.R * 255,
				ch == "G" and v or current.G * 255,
				ch == "B" and v or current.B * 255
			)
			applyColor(nc)
		end
		bar.InputBegan:Connect(function(input)
			if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
				dragging = true
				setRatio((input.Position.X - bar.AbsolutePosition.X) / bar.AbsoluteSize.X)
			end
		end)
		UIS.InputEnded:Connect(function(input)
			if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
				dragging = false
			end
		end)
		UIS.InputChanged:Connect(function(input)
			if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
				setRatio((input.Position.X - bar.AbsolutePosition.X) / bar.AbsoluteSize.X)
			end
		end)
		table.insert(sliders, slider)
		return slider
	end
	makeSlider("R", 46)
	makeSlider("G", 62)
	makeSlider("B", 78)
	hexBox.FocusLost:Connect(function()
		local nc = hexToColor(hexBox.Text)
		if nc then
			applyColor(nc)
		else
			hexBox.Text = colorToHex(current)
		end
	end)
	local presetY = 100
	for i, p in ipairs(fovPalette) do
		local dot = new("TextButton", {
			Size = UDim2.fromOffset(20, 20),
			Position = UDim2.fromOffset(14 + (i - 1) * 24, presetY),
			BackgroundColor3 = p[2],
			Text = "",
			BorderSizePixel = 0,
			ZIndex = 50,
		})
		dot.Parent = menu
		corner(dot, 10)
		dot.Activated:Connect(function()
			applyColor(p[2])
		end)
	end
	button.Activated:Connect(function()
		menu.Visible = not menu.Visible
		if menu.Visible then
			positionMenu()
			applyColor(current)
			menuScale.Scale = 0.85
			tweenProps(menuScale, 0.12, { Scale = 1 })
		end
	end)
	advance(parent, 36)
end

local function addKeybind(parent, title, defaultKey, callback)
	local key = defaultKey
	local rebinding = false
	local button = new("TextButton", {
		Size = UDim2.new(1, -20, 0, 36),
		Position = UDim2.fromOffset(10, cursorOf(parent)),
		BackgroundColor3 = theme.btn,
		Text = title,
		TextColor3 = theme.text,
		TextSize = 14,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Left,
	})
	button.Parent = parent
	corner(button, 6)
	local function updateText()
		if rebinding then
			button.Text = "Press a key (Esc = none)..."
		elseif key then
			button.Text = title .. ": " .. key.Name
		else
			button.Text = title .. ": None"
		end
	end
	updateText()
	button.Activated:Connect(function()
		rebinding = not rebinding
		button.BackgroundColor3 = rebinding and theme.accentDark or theme.btn
		updateText()
	end)
local function findTrickShotTarget()
	local cam = W.CurrentCamera
	if not cam then
		return nil
	end
	local camPos = cam.CFrame.Position
	local best = nil
	local bestD = math.huge
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		if settings.ignoreFriends and other:IsFriendsWith(player) then
			continue
		end
		local char = other.Character
		if not char then
			continue
		end
		if settings.teamCheck and player.Team and player.Team == other.Team then
			continue
		end
		local humanoid = char:FindFirstChildOfClass("Humanoid")
		if humanoid and settings.ignoreDead and humanoid.Health <= 0 then
			continue
		end
		local part = char:FindFirstChild(settings.hitPart) or char:FindFirstChild("HumanoidRootPart")
		if not part then
			continue
		end
		if settings.ignoreInvis and part.Transparency >= 1 then
			continue
		end
		local dist = (camPos - part.Position).Magnitude
		if dist >= bestD or dist > settings.maxDistance then
			continue
		end
		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Blacklist
		params.FilterDescendantsInstances = { player.Character, char }
		if W:Raycast(camPos, (part.Position - camPos).Unit * dist, params) then
			continue
		end
		best = other
		bestD = dist
	end
	return best
end

local function doTrickShot()
	if trickActive or not settings.trickShot then
		return
	end
	trickActive = true
	local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
	end
	local cam = W.CurrentCamera
	if not cam then
		trickActive = false
		return
	end
	local origType = cam.CameraType
	cam.CameraType = Enum.CameraType.Scriptable
	local startCF = cam.CFrame
	local eye = startCF.Position
	local look = startCF.LookVector
	look = Vector3.new(look.X, 0, look.Z)
	if look.Magnitude < 0.01 then
		look = Vector3.new(0, 0, -1)
	end
	look = look.Unit
	local startAng = math.atan2(look.X, look.Z)
	local dur = 0.6
	local t0 = os.clock()
	spawn(function()
		local spun = false
		while trickActive do
			if not cam.Parent then
				trickActive = false
				break
			end
			local el = os.clock() - t0
			if el >= dur and not spun then
				spun = true
				local target = findTrickShotTarget()
				if target and cam.Parent then
					trickLockTarget = target
					trickLockUntil = os.clock() + 1.2
				end
			end
			if spun and os.clock() > trickLockUntil then
				trickActive = false
			end
			if not trickActive then
				break
			end
			if trickLockTarget then
				local tchar = trickLockTarget.Character
				local troot = tchar and (tchar:FindFirstChild(settings.hitPart) or tchar:FindFirstChild("HumanoidRootPart"))
				if troot then
					cam.CFrame = CFrame.lookAt(cam.CFrame.Position, troot.Position)
				end
			else
				local ang = startAng + (el / dur) * math.pi * 2
				local dir = Vector3.new(math.sin(ang), 0, math.cos(ang))
				cam.CFrame = CFrame.lookAt(eye, eye + dir)
			end
			wait()
		end
		trickActive = false
		trickLockTarget = nil
		if cam.Parent and cam.CameraType == Enum.CameraType.Scriptable then
			cam.CameraType = origType or Enum.CameraType.Custom
		end
	end)
end

UIS.InputBegan:Connect(function(input, processed)
		if processed then
			return
		end
		if rebinding and input.KeyCode ~= Enum.KeyCode.None then
			key = (input.KeyCode == Enum.KeyCode.Escape) and nil or input.KeyCode
			rebinding = false
			button.BackgroundColor3 = theme.btn
			updateText()
			callback(key)
		end
	end)
	advance(parent, 36)
end

local function finishTab(name)
	local frame = tabFrames[name]
	frame.CanvasSize = UDim2.fromOffset(0, cursorOf(frame))
end

local espTab = newContentTab("ESP")
addSection(espTab, "ESP")
addToggle(espTab, "Enabled", settings.esp, function(v) settings.esp = v save() end)
addToggle(espTab, "Show names", settings.espName, function(v) settings.espName = v save() end)
addToggle(espTab, "Show boxes", settings.espBox, function(v) settings.espBox = v save() end)
addToggle(espTab, "Corner boxes", settings.espCornerBoxes, function(v) settings.espCornerBoxes = v save() end)
addToggle(espTab, "Distance", settings.espDistance, function(v) settings.espDistance = v save() end)
addToggle(espTab, "Show health", settings.espHealth, function(v) settings.espHealth = v save() end)
addToggle(espTab, "Highlight enemies", settings.espHighlight, function(v) settings.espHighlight = v save() end)
addToggle(espTab, "Gun name", settings.espGun, function(v) settings.espGun = v save() end)
addToggle(espTab, "Kills / Deaths", settings.espKills, function(v) settings.espKills = v save() end)
addToggle(espTab, "Velocity", settings.espVelocity, function(v) settings.espVelocity = v save() end)
addToggle(espTab, "Skeleton", settings.espSkeleton, function(v) settings.espSkeleton = v save() end)
addToggle(espTab, "Tracers", settings.tracers, function(v) settings.tracers = v save() end)
addDropdown(espTab, "Body type", function() return { "Auto", "R15", "R6" } end, settings.bodyType, function(v) settings.bodyType = v save() end)
addInfo(espTab, "Drawing-based, works without guis")
finishTab("ESP")

local fovCircle = Instance.new("Frame")
fovCircle.ZIndex = 5
fovCircle.BackgroundColor3 = settings.fovColor
fovCircle.BackgroundTransparency = 0.85
fovCircle.BorderSizePixel = 0
fovCircle.Visible = false
fovCircle.Parent = screenGui
local fovCircleCorner = Instance.new("UICorner")
fovCircleCorner.CornerRadius = UDim.new(1, 0)
fovCircleCorner.Parent = fovCircle
local fovCircleStroke = Instance.new("UIStroke")
fovCircleStroke.Thickness = 1.5
fovCircleStroke.Color = settings.fovColor
fovCircleStroke.Parent = fovCircle
local function updateFovCircle()
	fovCircle.Visible = settings.showFovCircle
	fovCircle.Size = UDim2.fromOffset(settings.fov * 2, settings.fov * 2)
	fovCircle.Position = UDim2.new(0.5, -settings.fov, 0.5, -settings.fov)
	fovCircle.BackgroundColor3 = settings.fovColor
	fovCircle.BackgroundTransparency = 0.85
	fovCircleStroke.Color = settings.fovColor
end

local targetLabel = Instance.new("TextLabel")
targetLabel.ZIndex = 5
targetLabel.Size = UDim2.new(0, 220, 0, 26)
targetLabel.Position = UDim2.new(0.5, -110, 0, 6)
targetLabel.BackgroundColor3 = theme.bg
targetLabel.TextColor3 = theme.accent
targetLabel.TextSize = 13
targetLabel.Font = Enum.Font.GothamBold
targetLabel.Visible = false
targetLabel.Parent = screenGui
corner(targetLabel, 6)
local targetTimer = 0
RS.RenderStepped:Connect(function(dt)
	if settings.showTarget then
		targetLabel.Visible = true
		targetTimer -= dt
		if targetTimer <= 0 then
			targetTimer = 0.1
			local info = getTargetInfo()
			targetLabel.Text = info and ("Target: " .. info.name .. " (" .. info.dist .. ")") or "Target: none"
		end
	elseif targetLabel.Visible then
		targetLabel.Visible = false
	end
end)

UIS.InputBegan:Connect(function(input, processed)
	if processed then
		return
	end
	if settings.toggleKey and input.KeyCode == settings.toggleKey then
		settings.enabled = not settings.enabled
		save()
	end
	if settings.hideKey and input.KeyCode == settings.hideKey then
		setMinimized(not minimized)
	end
	if settings.mouseFreeKey and input.KeyCode == settings.mouseFreeKey then
		if UIS.MouseBehavior == Enum.MouseBehavior.Free then
			UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
		else
			UIS.MouseBehavior = Enum.MouseBehavior.Free
		end
	end
	if settings.lagSwitch and settings.lagSwitchKey and input.KeyCode == settings.lagSwitchKey then
		setNetworkLag(settings.lagSwitchMs)
	end
	if settings.trickShot and settings.trickShotKey and input.KeyCode == settings.trickShotKey then
		doTrickShot()
	end
end)

UIS.InputEnded:Connect(function(input)
	if settings.lagSwitch and settings.lagSwitchKey and input.KeyCode == settings.lagSwitchKey then
		setNetworkLag(0)
	end
end)

local playerTab = newContentTab("Combat")
addSection(playerTab, "AIM")
addToggle(playerTab, "Aim enabled", settings.enabled, function(v) settings.enabled = v save() end)
addKeybind(playerTab, "Toggle key", settings.toggleKey, function(k) settings.toggleKey = k save() end)
addToggle(playerTab, "Aimbot", settings.aimbot, function(v) settings.aimbot = v save() end)
addToggle(playerTab, "Silent aim", settings.silentAim, function(v) settings.silentAim = v save() end)
addToggle(playerTab, "360 silent aim", settings.silent360, function(v) settings.silent360 = v save() end)
addToggle(playerTab, "360 aimbot", settings.aim360, function(v) settings.aim360 = v save() end)
addToggle(playerTab, "Multi target", settings.multiTarget, function(v) settings.multiTarget = v save() end)
addSlider(playerTab, "Max targets", 1, 10, settings.maxTargets, function(v) settings.maxTargets = v save() end)
addToggle(playerTab, "Flick on click", settings.flick, function(v) settings.flick = v save() end)
addToggle(playerTab, "Flick on shoot", settings.flickShoot, function(v) settings.flickShoot = v save() end)
addDropdown(playerTab, "Hit part", function() return { "Head", "Torso", "HumanoidRootPart" } end, settings.hitPart, function(v) settings.hitPart = v save() end)
addDropdown(playerTab, "Target mode", function() return { "Crosshair", "Lowest HP", "Closest" } end, settings.aimTargetMode, function(v) settings.aimTargetMode = v save() end)
addSlider(playerTab, "Aim FOV", 0, 500, settings.fov, function(v) settings.fov = v save() updateFovCircle() end)
addSlider(playerTab, "Smoothing", 0, 100, settings.smoothing, function(v) settings.smoothing = v save() end)
addSlider(playerTab, "Prediction", 0, 100, settings.prediction, function(v) settings.prediction = v save() end)
addSlider(playerTab, "Max distance", 50, 1000, settings.maxDistance, function(v) settings.maxDistance = v save() end)
addToggle(playerTab, "Team check", settings.teamCheck, function(v) settings.teamCheck = v save() end)
addToggle(playerTab, "Wall check", settings.checkVisible, function(v) settings.checkVisible = v save() end)
addToggle(playerTab, "Wallbang", settings.wallbang, function(v) settings.wallbang = v save() end)
addToggle(playerTab, "Sticky aim", settings.stickyAim, function(v) settings.stickyAim = v save() end)
addInfo(playerTab, "Sticky aim keeps your target until it dies or is out of range")
addSection(playerTab, "TARGET FILTERS")
addToggle(playerTab, "Semi-wallbang", settings.semiWallbang, function(v) settings.semiWallbang = v save() end)
addSlider(playerTab, "Wall thickness", 1, 20, settings.semiWallbangThickness, function(v) settings.semiWallbangThickness = v save() end)
addToggle(playerTab, "Ignore barriers", settings.ignoreBarriers, function(v) settings.ignoreBarriers = v save() end)
addToggle(playerTab, "Ignore no-collision", settings.ignoreNonCollision, function(v) settings.ignoreNonCollision = v save() end)
addToggle(playerTab, "Ignore invisible", settings.ignoreInvis, function(v) settings.ignoreInvis = v save() end)
addToggle(playerTab, "Ignore friends", settings.ignoreFriends, function(v) settings.ignoreFriends = v save() end)
addToggle(playerTab, "Ignore dead", settings.ignoreDead, function(v) settings.ignoreDead = v save() end)
addInfo(playerTab, "Semi-wallbang lets shots pass thin walls")
addToggle(playerTab, "Show FOV circle", settings.showFovCircle, function(v) settings.showFovCircle = v save() updateFovCircle() end)
addColorPicker(playerTab, "FOV circle color", settings.fovColor, function(c) settings.fovColor = c save() updateFovCircle() end)
addToggle(playerTab, "Show targeted player", settings.showTarget, function(v) settings.showTarget = v save() end)
addToggle(playerTab, "Show target lines", settings.showTargetV2, function(v) settings.showTargetV2 = v save() end)
addToggle(playerTab, "Show target line v3", settings.showTargetV3, function(v) settings.showTargetV3 = v save() end)
updateFovCircle()
addSection(playerTab, "AUTO")
addToggle(playerTab, "Auto clicker", settings.autoClicker, function(v) settings.autoClicker = v save() end)
addSlider(playerTab, "Clicks per second", 1, 50, settings.cps, function(v) settings.cps = v save() end)
addToggle(playerTab, "Triggerbot", settings.triggerbot, function(v) settings.triggerbot = v save() end)
addToggle(playerTab, "Auto aim", settings.autoAim, function(v) settings.autoAim = v save() end)
addToggle(playerTab, "Auto shoot", settings.autoShoot, function(v) settings.autoShoot = v save() end)
addSection(playerTab, "TRICK SHOT")
addToggle(playerTab, "Trick shot", settings.trickShot, function(v) settings.trickShot = v save() end)
addKeybind(playerTab, "Trick shot key", settings.trickShotKey, function(k) settings.trickShotKey = k save() end)
addInfo(playerTab, "Press the key to jump, spin 360 and snap-aim at the nearest visible enemy")
addSection(playerTab, "CAMERA CONTROL")
addToggle(playerTab, "No recoil", settings.noRecoil, function(v) settings.noRecoil = v save() end)
addToggle(playerTab, "No spread", settings.noSpread, function(v) settings.noSpread = v save() end)
addInfo(playerTab, "Hold mouse1 to shoot; recoil/spread are cancelled")
addSection(playerTab, "EXTRA COMBAT")
addToggle(playerTab, "Rapid fire", settings.rapidFire, function(v) settings.rapidFire = v save() end)
addSlider(playerTab, "Rapid CPS", 1, 50, settings.rapidCps, function(v) settings.rapidCps = v save() end)
addToggle(playerTab, "No click delay", settings.noClickDelay, function(v) settings.noClickDelay = v save() end)
addInfo(playerTab, "No click delay re-enables tools every frame")
addToggle(playerTab, "Kill aura", settings.killAura, function(v) settings.killAura = v save() end)
addSlider(playerTab, "Kill aura range", 5, 100, settings.killAuraRange, function(v) settings.killAuraRange = v save() end)
addToggle(playerTab, "Hit effects", settings.hitEffects, function(v) settings.hitEffects = v save() end)
addSection(playerTab, "LOWHP TP")
addToggle(playerTab, "LowHP teleport", settings.lowHpTp, function(v) settings.lowHpTp = v save() end)
addDropdown(playerTab, "Trigger", function() return { "Low HP", "Player clicking", "Locked target" } end, settings.lowHpTpTrigger, function(v) settings.lowHpTpTrigger = v save() end)
addDropdown(playerTab, "Direction", function() return { "Behind", "Forward", "Left", "Right", "Up", "Down" } end, settings.lowHpTpDir, function(v) settings.lowHpTpDir = v save() end)
addSlider(playerTab, "Health drop", 5, 100, settings.lowHpTpThreshold, function(v) settings.lowHpTpThreshold = v save() end)
addSlider(playerTab, "Range", 20, 500, settings.lowHpTpRange, function(v) settings.lowHpTpRange = v save() end)
addSlider(playerTab, "Cooldown", 0.5, 10, settings.lowHpTpCooldown, function(v) settings.lowHpTpCooldown = v save() end)
addInfo(playerTab, "Low HP = sudden drop; Clicking = someone fires a tool; Locked = aimbot/silent target")
addSection(playerTab, "DEFENSE")
addToggle(playerTab, "Anti-aim", settings.antiAim, function(v) settings.antiAim = v save() end)
addSlider(playerTab, "Anti-aim angle", 10, 180, settings.antiAimAngle, function(v) settings.antiAimAngle = v save() end)
addInfo(playerTab, "Anti-aim jitters your rotation while standing")
addSection(playerTab, "MASS KILL")
addToggle(playerTab, "Mass kill", settings.massKill, function(v) settings.massKill = v save() end)
addSlider(playerTab, "Kill every (s)", 0.5, 10, settings.massKillDelay, function(v) settings.massKillDelay = v save() end)
addButton(playerTab, "Kill all once", function()
	for _, other in ipairs(P:GetPlayers()) do
		if other ~= player then
			telekill(other)
		end
	end
end)
addInfo(playerTab, "Teleports every player into the void to kill them")
addToggle(playerTab, "Bring all to front", settings.bringAll, function(v) settings.bringAll = v save() end)
addSlider(playerTab, "Bring distance", 5, 40, settings.bringAllDist, function(v) settings.bringAllDist = v save() end)
addButton(playerTab, "Bring all once", function()
	bringAllFront()
end)
addInfo(playerTab, "Brings every player in front of you to shoot them")
addSection(playerTab, "STICK BEHIND")
addToggle(playerTab, "Stick behind", settings.stickBehind, function(v) settings.stickBehind = v save() end)
addSlider(playerTab, "Stick distance", 1, 10, settings.stickBehindDist, function(v) settings.stickBehindDist = v save() end)
addInfo(playerTab, "Follows the nearest enemy from behind; switches when they die")
finishTab("Combat")

local movementTab = newContentTab("Movement")
addSection(movementTab, "MOVEMENT")
addToggle(movementTab, "Fly", settings.fly, function(v)
	settings.fly = v
	if v then
		if not setFly(true) then
			settings.fly = false
		end
	else
		setFly(false)
	end
	save()
end)
addSlider(movementTab, "Fly speed", 10, 200, settings.flySpeed, function(v) settings.flySpeed = v save() end)
addToggle(movementTab, "Fly boost", settings.flyBoost, function(v) settings.flyBoost = v save() end)
addSlider(movementTab, "Fly boost mult", 1, 10, settings.flyBoostMult, function(v) settings.flyBoostMult = v save() end)
addToggle(movementTab, "Swim boost", settings.swimBoost, function(v) settings.swimBoost = v save() end)
addSlider(movementTab, "Swim speed", 10, 100, settings.swimSpeed, function(v) settings.swimSpeed = v save() end)
addToggle(movementTab, "Auto sprint", settings.autoSprint, function(v) settings.autoSprint = v save() end)
addToggle(movementTab, "Wall climb", settings.wallClimb, function(v) settings.wallClimb = v save() end)
addToggle(movementTab, "Click TP", settings.clickTp, function(v) settings.clickTp = v save() end)
addKeybind(movementTab, "ClickTP key", settings.clickTpKey, function(k) settings.clickTpKey = k save() end)
addInfo(movementTab, "Click TP teleports you wherever you click")
addToggle(movementTab, "Strafe", settings.strafe, function(v) settings.strafe = v save() end)
addSlider(movementTab, "Strafe speed", 16, 200, settings.strafeSpeed, function(v) settings.strafeSpeed = v save() end)
addToggle(movementTab, "Bhop", settings.bhop, function(v) settings.bhop = v save() end)
addToggle(movementTab, "Strafe V2", settings.strafeV2, function(v) settings.strafeV2 = v save() end)
addSlider(movementTab, "Strafe V2 speed", 16, 250, settings.strafeV2Speed, function(v) settings.strafeV2Speed = v save() end)
addInfo(movementTab, "Strafe boosts A/D speed; Bhop auto-jumps; V2 is hacked movement")
addSlider(movementTab, "Walk speed", 0, 100, settings.walkspeed, function(v) settings.walkspeed = v save() end)
addSlider(movementTab, "Jump power", 0, 200, settings.jumpPower, function(v) settings.jumpPower = v save() end)
addToggle(movementTab, "Infinite jump", settings.infJump, function(v) settings.infJump = v save() end)
addToggle(movementTab, "Noclip", settings.noclip, function(v) settings.noclip = v save() end)
addToggle(movementTab, "Freecam", settings.freecam, function(v)
	settings.freecam = v
	if v then
		if not setFreecam(true) then
			settings.freecam = false
		end
	else
		setFreecam(false)
	end
	save()
end)
addInfo(movementTab, "Use A key + WASD for fly: W/S/A/D, Space up, Ctrl down")
addSection(movementTab, "EXTRA")
addToggle(movementTab, "Third person", settings.thirdPerson, function(v)
	settings.thirdPerson = v
	if v then
		local cam = W.CurrentCamera
		local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
		if cam and root then
			local diff = cam.CFrame.Position - (root.Position + Vector3.new(0, 2, 0))
			local len = diff.Magnitude
			if len > 0.01 then
				tpYaw = math.atan2(-diff.X, -diff.Z)
				tpPitch = math.asin(math.clamp(diff.Y / len, -1, 1))
			end
			originalCamType = cam.CameraType
		end
	else
		local cam = W.CurrentCamera
		if cam and originalCamType then
			cam.CameraType = originalCamType
		end
	end
	save()
end)
addSlider(movementTab, "Third person distance", 5, 40, settings.tpDist, function(v) settings.tpDist = v save() end)
addToggle(movementTab, "Spinbot", settings.spinbot, function(v) settings.spinbot = v save() end)
addSlider(movementTab, "Spin speed", 5, 100, settings.spinSpeed, function(v) settings.spinSpeed = v save() end)
addToggle(movementTab, "TP walk", settings.tpWalk, function(v) settings.tpWalk = v save() end)
addSlider(movementTab, "TP walk speed", 10, 200, settings.tpWalkSpeed, function(v) settings.tpWalkSpeed = v save() end)
addToggle(movementTab, "Gravity changer", settings.gravityChanger, function(v) settings.gravityChanger = v save() end)
addSlider(movementTab, "Gravity", 0, 500, settings.gravity, function(v) settings.gravity = v save() end)
addToggle(movementTab, "Speed hack", settings.speedHack, function(v) settings.speedHack = v save() end)
addSlider(movementTab, "Speed hack mult", 1, 10, settings.speedHackMult, function(v) settings.speedHackMult = v save() end)
addInfo(movementTab, "Speed hack multiplies your velocity, works even when walkspeed is patched")
addToggle(movementTab, "Hitbox extender", settings.hitboxExtend, function(v) settings.hitboxExtend = v save() end)
addSlider(movementTab, "Hitbox scale", 1, 5, settings.hitboxExtendScale, function(v) settings.hitboxExtendScale = v save() end)
addInfo(movementTab, "Hitbox extender grows invisible hitboxes welded to your character")
finishTab("Movement")

local miscTab = newContentTab("Misc")
addSection(miscTab, "MISC")
addToggle(miscTab, "Anti-afk", settings.antiAfk, function(v) settings.antiAfk = v save() end)
addSection(miscTab, "CHAT SPAM")
addToggle(miscTab, "Chat spam", settings.chatSpam, function(v) settings.chatSpam = v save() end)
addSlider(miscTab, "Delay", 0.1, 10, settings.chatDelay, function(v) settings.chatDelay = v save() end)
addTextBox(miscTab, "Message", settings.chatMessage, function(v) settings.chatMessage = v save() end)
addSection(miscTab, "CAMERA")
addToggle(miscTab, "Camera FOV", settings.fovEnabled, function(v) settings.fovEnabled = v save() end)
addSlider(miscTab, "Camera FOV value", 10, 120, settings.camFov, function(v) settings.camFov = v save() end)
addSection(miscTab, "LAG SWITCH")
addToggle(miscTab, "Lag switch", settings.lagSwitch, function(v) settings.lagSwitch = v save() end)
addKeybind(miscTab, "Lag switch key", settings.lagSwitchKey, function(k) settings.lagSwitchKey = k save() end)
addSlider(miscTab, "Lag ms", 500, 10000, settings.lagSwitchMs, function(v) settings.lagSwitchMs = v save() end)
addInfo(miscTab, "Hold the key to freeze incoming replication")
finishTab("Misc")

local worldTab = newContentTab("World")
addSection(worldTab, "WORLD")
addToggle(worldTab, "Override time", settings.clock, function(v) settings.clock = v save() end)
addSlider(worldTab, "Clock time", 0, 24, settings.clockTime, function(v) settings.clockTime = v save() end)
addToggle(worldTab, "Fog override", settings.fog, function(v) settings.fog = v save() end)
addSlider(worldTab, "Fog distance", 100, 1000, settings.fogDistance, function(v) settings.fogDistance = v save() end)
finishTab("World")

local shaderTab = newContentTab("Shader")
addSection(shaderTab, "SHADERS")
addToggle(shaderTab, "Color correction", settings.shaders, function(v) settings.shaders = v save() end)
addSlider(shaderTab, "Brightness", -1, 1, settings.ccBrightness, function(v) settings.ccBrightness = v save() end)
addSlider(shaderTab, "Contrast", -1, 1, settings.ccContrast, function(v) settings.ccContrast = v save() end)
addSlider(shaderTab, "Saturation", -1, 1, settings.ccSaturation, function(v) settings.ccSaturation = v save() end)
addSection(shaderTab, "PRESETS")
addDropdown(shaderTab, "Shader preset", function() return { "Normal", "Sunset", "Pink Sunrise", "Snowy", "Summer Hot", "Toxic" } end, settings.shaderPreset, function(v) settings.shaderPreset = v applyShaderPreset(v) save() end)
addToggle(shaderTab, "Gloom", settings.gloom, function(v) settings.gloom = v applyGloom(v) save() end)
addSection(shaderTab, "EFFECTS")
addToggle(shaderTab, "Depth of field", settings.dof, function(v) settings.dof = v save() end)
addSlider(shaderTab, "DoF focus", 5, 200, settings.dofFocus, function(v) settings.dofFocus = v save() end)
addToggle(shaderTab, "Bloom", settings.bloom, function(v) settings.bloom = v save() end)
addSlider(shaderTab, "Bloom intensity", 0, 5, settings.bloomIntensity, function(v) settings.bloomIntensity = v save() end)
addSection(shaderTab, "TEXTURES")
addDropdown(shaderTab, "Skybox", function() return { "None", "Blue sky", "Sunset", "Night" } end, settings.skybox, function(v) settings.skybox = v applySkybox(v) save() end)
addDropdown(shaderTab, "Materials", function() return { "Normal", "SmoothPlastic", "Neon", "ForceField", "Glass", "Velvet" } end, settings.materials, function(v) settings.materials = v save() end)
addInfo(shaderTab, "Material override is one-way, Normal stops applying")
finishTab("Shader")

local serverTab = newContentTab("Server")
addSection(serverTab, "SERVER")
if settings.serverTarget == "" then
	local firstPlayer = P:GetPlayers()[1]
	if firstPlayer then
		settings.serverTarget = firstPlayer.Name
	end
end
addDropdown(serverTab, "Target", function()
	local options = {}
	for _, other in ipairs(P:GetPlayers()) do
		table.insert(options, other.Name)
	end
	return options
end, settings.serverTarget, function(v) settings.serverTarget = v save() end)
addButton(serverTab, "Teleport to target", function()
	local plr = P:FindFirstChild(settings.serverTarget)
	if plr then
		teleportTo(plr)
	end
end)
addButton(serverTab, "Bring target", function()
	local plr = P:FindFirstChild(settings.serverTarget)
	if plr then
		bring(plr)
	end
end)
addInfo(serverTab, "Target defaults to the first player in the list")
addSection(serverTab, "PLAYER FINDER")
addTextBox(serverTab, "Player name", settings.playerFinder, function(v) settings.playerFinder = v save() end)
addButton(serverTab, "Find & teleport", function()
	local query = string.lower(settings.playerFinder)
	if query == "" then
		return
	end
	for _, plr in ipairs(P:GetPlayers()) do
		if plr ~= player and string.lower(plr.Name):find(query, 1, true) then
			teleportTo(plr)
			print("OpenHub: teleported to " .. plr.Name)
			return
		end
	end
	print("OpenHub: no player matched '" .. settings.playerFinder .. "'")
end)
addInfo(serverTab, "Partial names work, e.g. 'x1' matches 'x1nematic'")
finishTab("Server")

local playersTab = newContentTab("Players")
addSection(playersTab, "PLAYER LIST")
addTextBox(playersTab, "Search", settings.playerSearch, function(v)
	settings.playerSearch = v
	save()
	if refreshPlayers then
		refreshPlayers()
	end
end)
local playersListFrame = new("Frame", {
	Size = UDim2.new(1, -20, 0, 300),
	Position = UDim2.fromOffset(10, cursorOf(playersTab)),
	BackgroundColor3 = theme.btn,
	BorderSizePixel = 0,
	ClipsDescendants = true,
})
playersListFrame.Parent = playersTab
corner(playersListFrame, 6)
playersScroll = new("ScrollingFrame", {
	Size = UDim2.new(1, 0, 1, 0),
	Position = UDim2.fromOffset(0, 0),
	BackgroundTransparency = 1,
	ScrollBarThickness = 4,
	CanvasSize = UDim2.fromOffset(0, 10),
})
playersScroll.Parent = playersListFrame
advance(playersTab, 300)
addInfo(playersTab, "Kill uses telekill; deactivate AntiCheat scan first")
refreshPlayers = function()
	if not playersScroll then
		return
	end
	for _, child in ipairs(playersScroll:GetChildren()) do
		if child:IsA("Frame") then
			child:Destroy()
		end
	end
	local query = string.lower(settings.playerSearch)
	local rows = {}
	for _, other in ipairs(P:GetPlayers()) do
		if other == player then
			continue
		end
		if query ~= "" and not string.lower(other.Name):find(query, 1, true) then
			continue
		end
		table.insert(rows, other)
	end
	table.sort(rows, function(a, b)
		return a.Name < b.Name
	end)
	local y = 4
	for _, other in ipairs(rows) do
		local row = new("Frame", {
			Size = UDim2.new(1, -8, 0, 28),
			Position = UDim2.fromOffset(4, y),
			BackgroundColor3 = theme.bg,
			BorderSizePixel = 0,
		})
		row.Parent = playersScroll
		corner(row, 4)
		local nameLbl = new("TextLabel", {
			Size = UDim2.new(1, -160, 1, 0),
			Position = UDim2.fromOffset(8, 0),
			BackgroundTransparency = 1,
			Text = other.Name,
			TextColor3 = theme.text,
			TextSize = 12,
			Font = Enum.Font.GothamBold,
			TextXAlignment = Enum.TextXAlignment.Left,
			ClipsDescendants = true,
		})
		nameLbl.Parent = row
		local x = 170
		local actions = {
			{ "TP", theme.accentDark, function() teleportTo(other) end },
			{ "B", theme.accentDark, function() bring(other) end },
			{ "K", theme.red, function() telekill(other) end },
			{ "S", theme.accentDark, function() spectateTarget = (spectateTarget == other) and nil or other end },
		}
		for _, act in ipairs(actions) do
			local b = new("TextButton", {
				Size = UDim2.fromOffset(32, 22),
				Position = UDim2.fromOffset(x, 3),
				BackgroundColor3 = act[2],
				Text = act[1],
				TextColor3 = theme.text,
				TextSize = 11,
				Font = Enum.Font.GothamBold,
			})
			b.Parent = row
			corner(b, 4)
			b.Activated:Connect(act[3])
			x = x + 36
		end
		y = y + 32
	end
	playersScroll.CanvasSize = UDim2.fromOffset(0, y)
end
refreshPlayers()
finishTab("Players")

local chamsTab = newContentTab("Chams")
addSection(chamsTab, "CHAMS")
addToggle(chamsTab, "Chams", settings.chams, function(v) settings.chams = v save() end)
addDropdown(chamsTab, "Chams type", function() return { "Outlines", "Fullbody", "Head", "FullVisible" } end, settings.chamsType, function(v) settings.chamsType = v save() end)
addHexColorPicker(chamsTab, "Chams color", settings.chamsColor, function(c) settings.chamsColor = c save() end)
addToggle(chamsTab, "Rainbow chams", settings.chamsRainbow, function(v) settings.chamsRainbow = v save() end)
addSlider(chamsTab, "RGB speed", 1, 20, settings.chamsRainbowSpeed, function(v) settings.chamsRainbowSpeed = v save() end)
addInfo(chamsTab, "Outlines/FullVisible render through walls")
finishTab("Chams")

local antiTab = newContentTab("AntiCheat")
addSection(antiTab, "ANTI CHEAT")
addToggle(antiTab, "Scan for cheaters", settings.scan, function(v) settings.scan = v save() end)
addSlider(antiTab, "Speed threshold", 40, 400, settings.cheatSpeed, function(v) settings.cheatSpeed = v save() end)
addButton(antiTab, "Clear list", function()
	scanSus = {}
	for _, row in pairs(cheaterRows) do
		row.frame:Destroy()
	end
	cheaterRows = {}
	if cheaterScroll then
		cheaterScroll.CanvasSize = UDim2.fromOffset(0, 10)
	end
end)
addInfo(antiTab, "Flags speed, teleport, fly, noclip, rapid fire")
addSection(antiTab, "DETECTED")
local cheaterListFrame = new("Frame", {
	Size = UDim2.new(1, -20, 0, 210),
	Position = UDim2.fromOffset(10, cursorOf(antiTab)),
	BackgroundColor3 = theme.btn,
	BorderSizePixel = 0,
	ClipsDescendants = true,
})
cheaterListFrame.Parent = antiTab
corner(cheaterListFrame, 6)
local cheaterListScroll = new("ScrollingFrame", {
	Size = UDim2.new(1, 0, 1, 0),
	Position = UDim2.fromOffset(0, 0),
	BackgroundTransparency = 1,
	ScrollBarThickness = 4,
	CanvasSize = UDim2.fromOffset(0, 10),
})
cheaterListScroll.Parent = cheaterListFrame
cheaterList = cheaterListFrame
cheaterScroll = cheaterListScroll
advance(antiTab, 210)
finishTab("AntiCheat")

local settingsTab = newContentTab("Settings")
addSection(settingsTab, "KEY")
addInfo(settingsTab, settings.unlocked and "Hub is unlocked" or "Hub is locked")
addButton(settingsTab, "Reset key", function()
	settings.unlocked = false
	settings.keyEntry = ""
	save()
end)
addInfo(settingsTab, "Re-run the script to enter a new key")
addKeybind(settingsTab, "Hide GUI key", settings.hideKey, function(k) settings.hideKey = k save() end)
addKeybind(settingsTab, "Free mouse key", settings.mouseFreeKey, function(k) settings.mouseFreeKey = k save() end)
addInfo(settingsTab, "Free mouse key toggles the cursor so you can click the menu")
addSection(settingsTab, "SAVE")
addButton(settingsTab, "Save settings", function() save() end)
addInfo(settingsTab, "Settings auto-save on every change")
addButton(settingsTab, "Reset all settings", function()
	for key, value in pairs(defaultSettings) do
		settings[key] = value
	end
	save()
end)
addInfo(settingsTab, "Reload the script to refresh UI toggles")
addSection(settingsTab, "UTILITY")
addButton(settingsTab, "Rejoin server", function()
	pcall(function()
		game:GetService("TeleportService"):Teleport(game.PlaceId, player)
	end)
end)
addButton(settingsTab, "Server hop", serverHop)
addButton(settingsTab, "Clear junk GUI", cleanupOldHubs)
addToggle(settingsTab, "FPS cap", settings.fpsCap, function(v) settings.fpsCap = v save() end)
addSlider(settingsTab, "FPS cap value", 30, 240, settings.fpsCapValue, function(v) settings.fpsCapValue = v save() end)
addInfo(settingsTab, "FPS cap applies on supported executors")
addSection(settingsTab, "ABOUT")
addInfo(settingsTab, "OpenHub - Solara loader")
finishTab("Settings")

for n, f in pairs(tabFrames) do
	f.Visible = (n == "ESP")
end
for n, b in pairs(tabButtons) do
	b.BackgroundColor3 = (n == "ESP") and theme.accentDark or theme.btn
end

print("Hub: gui built")

local loader = Instance.new("Frame")
loader.Size = UDim2.fromOffset(220, 220)
loader.Position = UDim2.new(0.5, -110, 0.5, -110)
loader.BackgroundColor3 = theme.bg2
loader.BackgroundTransparency = 0
loader.BorderSizePixel = 0
loader.ZIndex = 50
loader.Parent = screenGui
local loaderCorner = Instance.new("UICorner")
loaderCorner.CornerRadius = UDim.new(1, 0)
loaderCorner.Parent = loader
local loaderStroke = Instance.new("UIStroke")
loaderStroke.Thickness = 2
loaderStroke.Color = theme.accent
loaderStroke.Parent = loader
local loaderTitle = new("TextLabel", {
	Size = UDim2.new(1, 0, 0, 44),
	Position = UDim2.fromOffset(0, 64),
	BackgroundTransparency = 1,
	Text = "OpenHub",
	TextColor3 = theme.text,
	TextSize = 34,
	Font = Enum.Font.GothamBold,
	ZIndex = 50,
})
loaderTitle.Parent = loader
local loaderText = new("TextLabel", {
	Size = UDim2.new(1, 0, 0, 20),
	Position = UDim2.fromOffset(0, 116),
	BackgroundTransparency = 1,
	Text = "loading",
	TextColor3 = theme.dim,
	TextSize = 14,
	Font = Enum.Font.Gotham,
	ZIndex = 50,
})
loaderText.Parent = loader
local loaderDots = new("TextLabel", {
	Size = UDim2.new(1, 0, 0, 20),
	Position = UDim2.fromOffset(0, 134),
	BackgroundTransparency = 1,
	Text = "",
	TextColor3 = theme.accent,
	TextSize = 14,
	Font = Enum.Font.Gotham,
	ZIndex = 50,
})
loaderDots.Parent = loader
local dotsIndex = 0
spawn(function()
	while loader.Parent do
		dotsIndex = dotsIndex % 3 + 1
		loaderDots.Text = string.rep(".", dotsIndex)
		wait(0.25)
	end
end)
local KEY = "OpenHubOnTop"
local keyScreenShown = false

local function showKeyScreen()
	if keyScreenShown or (main and main.Visible) then
		return
	end
	keyScreenShown = true
	local overlay = Instance.new("Frame")
	overlay.Size = UDim2.fromScale(1, 1)
	overlay.BackgroundColor3 = Color3.fromRGB(8, 8, 12)
	overlay.BackgroundTransparency = 0.2
	overlay.BorderSizePixel = 0
	overlay.ZIndex = 60
	overlay.Parent = screenGui
	local card = Instance.new("Frame")
	card.Size = UDim2.fromOffset(320, 230)
	card.Position = UDim2.new(0.5, -160, 0.5, -115)
	card.BackgroundColor3 = theme.bg2
	card.BorderSizePixel = 0
	card.ZIndex = 61
	card.Parent = overlay
	corner(card, 12)
	local cardTitle = new("TextLabel", {
		Size = UDim2.new(1, 0, 0, 40),
		Position = UDim2.fromOffset(0, 20),
		BackgroundTransparency = 1,
		Text = "OpenHub",
		TextColor3 = theme.text,
		TextSize = 26,
		Font = Enum.Font.GothamBold,
		ZIndex = 61,
	})
	cardTitle.Parent = card
	local cardSub = new("TextLabel", {
		Size = UDim2.new(1, 0, 0, 18),
		Position = UDim2.fromOffset(0, 60),
		BackgroundTransparency = 1,
		Text = "Enter key to continue",
		TextColor3 = theme.dim,
		TextSize = 13,
		Font = Enum.Font.Gotham,
		ZIndex = 61,
	})
	cardSub.Parent = card
	local keyBox = new("TextBox", {
		Size = UDim2.new(1, -40, 0, 36),
		Position = UDim2.fromOffset(20, 90),
		BackgroundColor3 = theme.btn,
		Text = settings.keyEntry,
		PlaceholderText = "Key",
		TextColor3 = theme.text,
		PlaceholderColor3 = theme.dim,
		TextSize = 14,
		Font = Enum.Font.Gotham,
		TextXAlignment = Enum.TextXAlignment.Center,
		ClearTextOnFocus = false,
		ZIndex = 61,
	})
	keyBox.Parent = card
	corner(keyBox, 6)
	local unlockBtn = new("TextButton", {
		Size = UDim2.new(1, -40, 0, 36),
		Position = UDim2.fromOffset(20, 134),
		BackgroundColor3 = theme.accent,
		Text = "Unlock",
		TextColor3 = Color3.fromRGB(10, 10, 14),
		TextSize = 14,
		Font = Enum.Font.GothamBold,
		ZIndex = 61,
	})
	unlockBtn.Parent = card
	corner(unlockBtn, 6)
	local errorLabel = new("TextLabel", {
		Size = UDim2.new(1, 0, 0, 16),
		Position = UDim2.fromOffset(0, 178),
		BackgroundTransparency = 1,
		Text = "",
		TextColor3 = theme.red,
		TextSize = 12,
		Font = Enum.Font.Gotham,
		ZIndex = 61,
	})
	errorLabel.Parent = card
	local function unlock(entry)
		if entry == KEY then
			settings.unlocked = true
			settings.keyEntry = entry
			save()
			overlay:Destroy()
			if loader then
				pcall(function() loader:Destroy() end)
			end
			main.Visible = true
		else
			errorLabel.Text = "Invalid key - script locked"
			errorLabel.Visible = true
			keyBox.Text = ""
			spawn(function()
				local base = card.Position
				for i = 1, 3 do
					card.Position = base + UDim2.fromOffset(math.random(-6, 6), 0)
					wait(0.05)
					card.Position = base
					wait(0.05)
				end
				wait(1.2)
				overlay:Destroy()
			end)
		end
	end
	keyBox.FocusLost:Connect(function()
		unlock(keyBox.Text)
	end)
	unlockBtn.MouseButton1Click:Connect(function()
		unlock(keyBox.Text)
	end)
	keyBox.CaptureFocus()
end

delay(1.4, function()
	pcall(function()
		if not loader.Parent then
			return
		end
		loaderTitle.Visible = false
		loaderText.Visible = false
		loaderDots.Visible = false
		loaderStroke.Transparency = 1
		tweenProps(loaderCorner, 0.4, { CornerRadius = UDim.new(0, 6) })
		tweenProps(loader, 0.4, {
			Size = main.Size,
			Position = main.Position,
			BackgroundColor3 = theme.bg,
		}, function()
			loader:Destroy()
			if settings.unlocked then
				main.Visible = true
			else
				showKeyScreen()
			end
		end)
	end)
end)
delay(4, function()
	if main and not main.Visible then
		if loader then
			loader:Destroy()
		end
		if settings.unlocked then
			main.Visible = true
		else
			showKeyScreen()
		end
	end
end)

Features & Information

idk im bored af so i made this arsenal script (Key is OpenHubOnTop)
#aimbot

Community Comments (0)

No comments yet for this script.

More Scripts for Arsenal