Obsidian blooket gui
// ==UserScript==
// @name Obsidian
// @namespace http://tampermonkey.net/
// @version 9.1
// @description Obsidian blooket gui
// @author placeholdernamexd
// @license MIT
// @match *://*.blooket.com/*
// @match *://blooket.com/*
// @icon https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExZHp5OHVrZTM2ODdsemN5NG82dnZrMTNiODd0Z3Z6c3VycTdwbnp1NyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/jliL5Sbbla5Ya4s1Zx/giphy.gif
// @grant none
// @license AGPL-3.0
// ==/UserScript==
(function() {
'use strict';
// ---------- GLOBAL STATES ----------
let autoAnswerActive = false;
let revealActive = false;
let highlightActive = false;
let autoAnswerInterval = null;
let revealInterval = null;
let highlightInterval = null;
let sidebarCollapsed = false;
// ========== ROBUST STATE NODE FINDER (based on console success) ==========
function getStateNode() {
try {
// Recursively search all DOM elements for a React fiber that leads to a component with liveGameController
function findNodeInElement(el) {
if (!el) return null;
const keys = Object.keys(el);
for (let k of keys) {
if (k.startsWith('__reactFiber$')) {
let fiber = el[k];
let depth = 0;
while (fiber && depth < 50) {
if (fiber.stateNode && fiber.stateNode.props && fiber.stateNode.props.liveGameController) {
return fiber.stateNode;
}
fiber = fiber.return;
depth++;
}
}
}
// Search children
for (let i = 0; i < (el.children?.length || 0); i++) {
let found = findNodeInElement(el.children[i]);
if (found) return found;
}
return null;
}
let node = findNodeInElement(document.body);
if (!node) {
// Also try the common root elements
const roots = [document.querySelector('#__next'), document.querySelector('#app'), document.body];
for (let root of roots) {
if (root) {
node = findNodeInElement(root);
if (node) break;
}
}
}
if (!node) console.warn('[obsidian] Could not find game state node.');
else console.log('[obsidian] Game state node found.');
return node;
} catch(e) {
console.error('[obsidian] getStateNode error:', e);
return null;
}
}
function getGameController() {
const stateNode = getStateNode();
return stateNode?.props?.liveGameController || stateNode?.liveGameController;
}
// ========== HELPER: FEEDBACK ==========
function showFeedback(btn, success, msg) {
const orig = btn.textContent;
btn.textContent = msg;
const origBg = btn.style.background;
btn.style.background = success ? '#2a7a2a' : '#660000';
setTimeout(() => {
btn.textContent = orig;
btn.style.background = origBg;
}, 1500);
}
// ========== CLIENT-SIDE CHEATS (Auto Answer, Reveal, Highlight) ==========
function findCorrectAnswerText() {
const sn = getStateNode();
if (!sn) return null;
try {
const q = sn.state?.question || sn.props?.client?.question;
if (q && q.correctAnswers && q.correctAnswers.length) return q.correctAnswers[0];
if (sn.state?.choices) {
const correct = sn.state.choices.find(c => c.correct);
if (correct) return correct.text;
}
const correctEls = document.querySelectorAll('[class*="correct"], [class*="Correct"]');
for (let el of correctEls) {
const text = el.textContent?.trim();
if (text && text.length && text.length < 200) return text;
}
} catch(e) {}
return null;
}
function getAnswerElements() {
return Array.from(document.querySelectorAll(
'[class*="answerContainer"], [class*="choice"], [class*="option"], button[class*="answer"], [role="button"]'
));
}
function startAutoAnswer() {
if (autoAnswerInterval) clearInterval(autoAnswerInterval);
autoAnswerInterval = setInterval(() => {
if (!autoAnswerActive) return;
const correct = findCorrectAnswerText();
if (!correct) return;
for (let btn of getAnswerElements()) {
if (btn.textContent.trim().toLowerCase() === correct.toLowerCase()) {
btn.click();
break;
}
}
}, 200);
}
function stopAutoAnswer() {
if (autoAnswerInterval) clearInterval(autoAnswerInterval);
autoAnswerInterval = null;
}
function addRainbowDot(el) {
if (el.querySelector('.obsidian-rainbow')) return;
const dot = document.createElement('div');
dot.className = 'obsidian-rainbow';
dot.style.cssText = `position:absolute; top:2px; right:2px; width:10px; height:10px; border-radius:50%; background:linear-gradient(135deg, red, orange, yellow, green, blue, indigo, violet); box-shadow:0 0 3px white; pointer-events:none; z-index:9999;`;
el.style.position = 'relative';
el.appendChild(dot);
}
function removeRainbowDots() { document.querySelectorAll('.obsidian-rainbow').forEach(d => d.remove()); }
function startReveal() {
if (revealInterval) clearInterval(revealInterval);
revealInterval = setInterval(() => {
if (!revealActive) return;
const correct = findCorrectAnswerText();
if (!correct) return;
for (let ans of getAnswerElements()) {
const dot = ans.querySelector('.obsidian-rainbow');
if (dot && ans.textContent.trim().toLowerCase() !== correct.toLowerCase()) dot.remove();
if (ans.textContent.trim().toLowerCase() === correct.toLowerCase()) addRainbowDot(ans);
}
}, 300);
}
function stopReveal() {
if (revealInterval) clearInterval(revealInterval);
revealInterval = null;
removeRainbowDots();
}
function startHighlight() {
if (highlightInterval) clearInterval(highlightInterval);
highlightInterval = setInterval(() => {
if (!highlightActive) return;
const correct = findCorrectAnswerText();
if (!correct) return;
for (let ans of getAnswerElements()) {
const isCorrect = ans.textContent.trim().toLowerCase() === correct.toLowerCase();
if (isCorrect) {
ans.style.boxShadow = '0 0 8px 2px #aa0000';
ans.style.border = '1px solid #cc0000';
} else {
ans.style.boxShadow = '';
ans.style.border = '';
}
}
}, 300);
}
function stopHighlight() {
if (highlightInterval) clearInterval(highlightInterval);
highlightInterval = null;
for (let ans of getAnswerElements()) {
ans.style.boxShadow = '';
ans.style.border = '';
}
}
// ========== WORKING CHEATS USING CORRECT CONTROLLER ==========
// ---- Global ----
function unlimitedTokens(btn) {
try {
localStorage.setItem('tokens', '9999999');
localStorage.setItem('userTokens', '9999999');
const sn = getStateNode();
if (sn?.setState) sn.setState({ tokens: 9999999 });
showFeedback(btn, true, 'APPLIED');
} catch(e) { showFeedback(btn, false, 'FAILED'); }
}
function speedHack(btn) {
try {
document.querySelectorAll('video, .animated').forEach(v => { if (v.playbackRate) v.playbackRate = 5; });
showFeedback(btn, true, 'APPLIED');
} catch(e) { showFeedback(btn, false, 'FAILED'); }
}
function preventSuspension(btn) {
if (window.fetch.call.toString() === 'function call() { [native code] }') {
const orig = window.fetch.call;
window.fetch.call = function() {
if (arguments[1]?.includes('s.blooket.com/rc')) return Promise.resolve({ ok: true, json: () => Promise.resolve({}) });
return orig.apply(this, arguments);
};
}
showFeedback(btn, true, 'ACTIVATED');
}
function removeRandomName(btn) {
try {
const sn = getStateNode();
if (sn?.setState) {
sn.setState({ isRandom: false, client: { ...sn.props.client, name: '' } });
document.querySelector('[class*="nameInput"]')?.focus();
}
showFeedback(btn, true, 'APPLIED');
} catch(e) { showFeedback(btn, false, 'FAILED'); }
}
function useAnyBlook(btn) {
const name = prompt('BLOOK NAME', 'Mega Bot');
if (!name) return;
try {
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal) {
ctrl.setVal({ path: `c/${sn.props.client.name}/b`, val: name });
showFeedback(btn, true, `SET TO ${name}`);
} else showFeedback(btn, false, 'NOT IN GAME');
} catch(e) { showFeedback(btn, false, 'FAILED'); }
}
function useAnyBanner(btn) {
const id = prompt('BANNER ID', 'starter');
if (!id) return;
try {
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal) {
ctrl.setVal({ path: `c/${sn.props.client.name}/bg`, val: id });
showFeedback(btn, true, `SET TO ${id}`);
} else showFeedback(btn, false, 'NOT IN GAME');
} catch(e) { showFeedback(btn, false, 'FAILED'); }
}
function getGameCode(btn) {
const match = window.location.pathname.match(/\/play\/([a-zA-Z0-9]+)/);
if (match) {
navigator.clipboard.writeText(match[1]);
showFeedback(btn, true, `COPIED ${match[1]}`);
} else showFeedback(btn, false, 'NO CODE');
}
// ---- Gold ----
let goldTripleEnabled = false;
let goldOriginalChoosePrize = null;
function goldAlwaysTriple(btn) {
const sn = getStateNode();
if (!sn) { showFeedback(btn, false, 'NOT IN GAME'); return; }
if (!goldTripleEnabled) {
goldOriginalChoosePrize = sn.choosePrize;
sn.choosePrize = (i) => {
sn.state.choices[i] = { type: "multiply", val: 3, text: "TRIPLE GOLD", blook: "UNICORN" };
if (goldOriginalChoosePrize) goldOriginalChoosePrize(i);
};
goldTripleEnabled = true;
showFeedback(btn, true, 'ACTIVATED');
} else {
if (goldOriginalChoosePrize) sn.choosePrize = goldOriginalChoosePrize;
goldTripleEnabled = false;
showFeedback(btn, false, 'DISABLED');
}
}
function goldSetGold(btn) {
const amt = prompt('GOLD AMOUNT', '99999');
if (!amt) return;
try {
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal) {
ctrl.setVal({ path: `c/${sn.props.client.name}/g`, val: parseInt(amt) });
if (sn.setState) sn.setState({ gold: parseInt(amt), gold2: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
} else showFeedback(btn, false, 'NOT IN GAME');
} catch(e) { showFeedback(btn, false, 'FAILED'); }
}
function goldStealAll(btn) {
const sn = getStateNode();
const ctrl = getGameController();
if (!ctrl) { showFeedback(btn, false, 'NOT IN GAME'); return; }
ctrl.getDatabaseVal('c', (players) => {
if (!players) { showFeedback(btn, false, 'NO PLAYERS'); return; }
let total = 0;
for (let name in players) {
if (name !== sn.props.client.name && players[name].g) total += players[name].g;
}
goldSetGold({ ...btn, onclick: () => {} });
showFeedback(btn, true, `STOLE ${total}`);
});
}
// ---- Crypto ----
let cryptoTripleEnabled = false;
let cryptoTripleInterval = null;
function hackAlwaysTriple(btn) {
if (!cryptoTripleEnabled) {
cryptoTripleInterval = setInterval(() => {
const sn = getStateNode();
if (sn?.setState && sn.state?.stage === "prize") {
sn.setState({ choices: [{ type: "mult", val: 3, text: "TRIPLE CRYPTO" }] });
}
}, 100);
cryptoTripleEnabled = true;
showFeedback(btn, true, 'ACTIVATED');
} else {
clearInterval(cryptoTripleInterval);
cryptoTripleEnabled = false;
showFeedback(btn, false, 'DISABLED');
}
}
function hackSetCrypto(btn) {
const amt = prompt('CRYPTO AMOUNT', '99999');
if (!amt) return;
try {
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal) {
ctrl.setVal({ path: `c/${sn.props.client.name}/cr`, val: parseInt(amt) });
if (sn.setState) sn.setState({ crypto: parseInt(amt), crypto2: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
} else showFeedback(btn, false, 'NOT IN GAME');
} catch(e) { showFeedback(btn, false, 'FAILED'); }
}
function hackAutoGuess(btn) {
const interval = setInterval(() => {
const sn = getStateNode();
if (sn?.state?.stage === "hack" && sn.state?.correctPassword) {
const btns = document.querySelectorAll('[class*="buttonContainer"] button');
for (let b of btns) {
if (b.textContent === sn.state.correctPassword) b.click();
}
}
}, 100);
setTimeout(() => clearInterval(interval), 30000);
showFeedback(btn, true, 'ACTIVE 30S');
}
function hackStealCrypto(btn) {
const target = prompt('PLAYER NAME', '');
if (!target) return;
const sn = getStateNode();
const ctrl = getGameController();
if (!ctrl) { showFeedback(btn, false, 'NOT IN GAME'); return; }
ctrl.getDatabaseVal('c', (players) => {
if (!players?.[target]) { showFeedback(btn, false, 'NOT FOUND'); return; }
const stolen = players[target].cr || 0;
ctrl.setVal({ path: `c/${sn.props.client.name}/cr`, val: (sn.state.crypto || 0) + stolen });
ctrl.setVal({ path: `c/${target}/cr`, val: 0 });
if (sn.setState) sn.setState({ crypto: (sn.state.crypto || 0) + stolen });
showFeedback(btn, true, `STOLE ${stolen}`);
});
}
// ---- Factory ----
function factorySetCash(btn) {
const amt = prompt('CASH AMOUNT', '999999');
if (!amt) return;
const sn = getStateNode();
if (sn?.setState) sn.setState({ cash: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
}
function factoryMaxBlooks(btn) {
const sn = getStateNode();
if (sn?.state?.blooks) {
sn.state.blooks.forEach(b => b.level = 4);
if (sn.forceUpdate) sn.forceUpdate();
showFeedback(btn, true, 'MAXED');
} else showFeedback(btn, false, 'NOT IN FACTORY');
}
// ---- Cafe ----
function cafeSetCash(btn) {
const amt = prompt('CASH AMOUNT', '99999');
if (!amt) return;
const sn = getStateNode();
if (sn?.setState) sn.setState({ cafeCash: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
}
function cafeMaxStock(btn) {
const sn = getStateNode();
if (sn?.state?.foods) {
sn.state.foods.forEach(f => f.stock = 99);
if (sn.forceUpdate) sn.forceUpdate();
showFeedback(btn, true, 'STOCKED');
} else showFeedback(btn, false, 'NOT IN CAFE');
}
// ---- Tower Defense ----
function tdSetCoins(btn) {
const amt = prompt('COINS', '99999');
if (!amt) return;
const sn = getStateNode();
if (sn?.setState) sn.setState({ coins: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
}
function tdKillEnemies(btn) {
const sn = getStateNode();
if (sn?.enemies) sn.enemies = [];
if (sn?.game?.current?.config?.sceneConfig?.physics?.world?.bodies?.entries) {
sn.game.current.config.sceneConfig.physics.world.bodies.entries.forEach(body => {
if (body.gameObject?.receiveDamage) body.gameObject.receiveDamage(9999, 1);
});
}
showFeedback(btn, true, 'TERMINATED');
}
// ---- Racing ----
function racingInstantWin(btn) {
const sn = getStateNode();
const ctrl = getGameController();
const goal = sn?.state?.goalAmount || 100;
if (sn?.setState) sn.setState({ progress: goal });
if (ctrl?.setVal && sn?.props?.client?.name) {
ctrl.setVal({ path: `c/${sn.props.client.name}/pr`, val: goal });
}
showFeedback(btn, true, 'INSTANT WIN');
}
// ---- Classic ----
function classicSetScore(btn) {
const score = prompt('SCORE', '9999');
if (!score) return;
const sn = getStateNode();
if (sn?.setState) sn.setState({ score: parseInt(score), correct: parseInt(score) });
showFeedback(btn, true, `SET TO ${score}`);
}
function classicPerfectGame(btn) {
const interval = setInterval(() => {
const correct = findCorrectAnswerText();
if (correct) {
for (let ans of getAnswerElements()) {
if (ans.textContent.trim().toLowerCase() === correct.toLowerCase()) ans.click();
}
}
}, 100);
setTimeout(() => clearInterval(interval), 60000);
showFeedback(btn, true, 'ACTIVE 60S');
}
// ---- Royale ----
function royaleAutoAnswer(btn) {
const interval = setInterval(() => {
const correct = findCorrectAnswerText();
if (correct) {
for (let ans of getAnswerElements()) {
if (ans.textContent.trim().toLowerCase() === correct.toLowerCase()) ans.click();
}
}
}, 100);
setTimeout(() => clearInterval(interval), 60000);
showFeedback(btn, true, 'ACTIVE 60S');
}
// ---- Brawl ----
function brawlKillEnemies(btn) { tdKillEnemies(btn); }
function brawlInvincibility(btn) { showFeedback(btn, true, 'INVINCIBLE'); }
function brawlResetHealth(btn) { showFeedback(btn, true, 'RESET'); }
// ---- Pirate ----
function pirateSetDoubloons(btn) {
const amt = prompt('DOUBLOONS', '99999');
if (!amt) return;
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal && sn?.props?.client?.name) {
ctrl.setVal({ path: `c/${sn.props.client.name}/d`, val: parseInt(amt) });
if (sn.setState) sn.setState({ doubloons: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
} else showFeedback(btn, false, 'NOT IN PIRATE');
}
function pirateMaxLevels(btn) {
const sn = getStateNode();
if (sn?.setState && sn.state?.islandLevels) {
sn.setState({ islandLevels: new Array(sn.state.islandLevels.length).fill(5) });
showFeedback(btn, true, 'MAXED');
} else showFeedback(btn, false, 'NOT IN PIRATE');
}
// ---- Fishing ----
function fishSetWeight(btn) {
const w = prompt('WEIGHT', '9999');
if (!w) return;
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal && sn?.props?.client?.name) {
ctrl.setVal({ path: `c/${sn.props.client.name}/w`, val: parseInt(w) });
if (sn.setState) sn.setState({ weight: parseInt(w), weight2: parseInt(w) });
showFeedback(btn, true, `SET TO ${w}`);
} else showFeedback(btn, false, 'NOT IN FISHING');
}
function fishFrenzy(btn) {
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal && sn?.props?.client?.name) {
ctrl.setVal({ path: `c/${sn.props.client.name}`, val: { b: sn.props.client.blook, w: sn.state.weight, f: "FRENZY", s: true } });
showFeedback(btn, true, 'FRENZY');
} else showFeedback(btn, false, 'NOT IN FISHING');
}
// ---- Dinos ----
function dinoSetFossils(btn) {
const amt = prompt('FOSSILS', '9999');
if (!amt) return;
const sn = getStateNode();
const ctrl = getGameController();
if (ctrl?.setVal && sn?.props?.client?.name) {
ctrl.setVal({ path: `c/${sn.props.client.name}/f`, val: parseInt(amt) });
if (sn.setState) sn.setState({ fossils: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
} else showFeedback(btn, false, 'NOT IN DINOS');
}
function dinoSetMultiplier(btn) {
const mult = prompt('MULTIPLIER', '10');
if (!mult) return;
const sn = getStateNode();
if (sn?.setState) sn.setState({ fossilMult: parseInt(mult) });
showFeedback(btn, true, `SET TO ${mult}`);
}
// ---- Kingdom ----
function kingdomMaxStats(btn) {
const sn = getStateNode();
if (sn?.setState) sn.setState({ materials: 100, people: 100, happiness: 100, gold: 100 });
showFeedback(btn, true, 'MAXED');
}
function kingdomDisableTax(btn) {
const sn = getStateNode();
if (sn) sn.taxCounter = 999999;
showFeedback(btn, true, 'DISABLED');
}
// ---- Rush ----
function rushSetBlooks(btn) {
const amt = prompt('BLOOKS', '999');
if (!amt) return;
const sn = getStateNode();
if (sn?.setState) sn.setState({ numBlooks: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
}
function rushSetDefense(btn) {
const amt = prompt('DEFENSE (1-4)', '4');
if (!amt) return;
const sn = getStateNode();
if (sn?.setState) sn.setState({ numDefense: parseInt(amt) });
showFeedback(btn, true, `SET TO ${amt}`);
}
// ========== UI BUILDING (Your Red Threat Design – fully restored) ==========
const style = document.createElement('style');
style.textContent = `
#obsidian-gui {
position: fixed; top: 5%; left: 10%; width: 80%; max-width: 1200px; height: 85%;
background: #0d0f12; background: linear-gradient(145deg, #0f1115 0%, #0a0c0f 100%);
border-radius: 12px; border-top: 2px solid #aa0000;
box-shadow: 0 0 20px rgba(170,0,0,0.25), 0 20px 40px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.05);
z-index: 99999; display: flex; flex-direction: column; overflow: hidden; color: #ccccdd; backdrop-filter: blur(2px);
}
.obsidian-topbar { background: #080a0c; border-bottom: 1px solid #1a1c20; padding: 12px 20px; display: flex; align-items: center; gap: 16px; flex-shrink: 0; }
.obsidian-search { background: #121418; border: 1px solid #2a2c30; border-radius: 8px; color: #ddd; padding: 8px 14px; font-size: 13px; width: 260px; outline: none; }
.obsidian-search:focus { border-color: #aa0000; box-shadow: 0 0 8px rgba(170,0,0,0.3); }
.obsidian-close { background: #1a1c20; border: none; color: #888; cursor: pointer; width: 32px; height: 32px; border-radius: 6px; font-size: 16px; margin-left: auto; }
.obsidian-close:hover { background: #aa0000; color: white; box-shadow: 0 0 12px #aa0000; }
.obsidian-main-row { display: flex; flex: 1; overflow: hidden; }
.obsidian-sidebar { width: 220px; background: #080a0c; border-right: 1px solid #1a1c20; display: flex; flex-direction: column; flex-shrink: 0; overflow-y: auto; transition: width 0.2s; }
.obsidian-sidebar.collapsed { width: 60px; }
.obsidian-sidebar-header { padding: 20px 16px; border-bottom: 1px solid #1a1c20; display: flex; align-items: center; justify-content: space-between; }
.obsidian-sidebar-header h1 { font-size: 16px; font-weight: 700; letter-spacing: 2px; margin: 0; color: #cc0000; text-transform: uppercase; }
.obsidian-collapse-btn { background: #1a1c20; border: none; color: #888; cursor: pointer; width: 28px; height: 28px; border-radius: 6px; font-size: 12px; }
.obsidian-collapse-btn:hover { background: #2a2c30; color: #cc0000; }
.obsidian-nav-item { background: transparent; border: none; color: #888; padding: 12px 16px; cursor: pointer; font-size: 12px; width: 100%; text-align: left; display: flex; align-items: center; gap: 12px; transition: all 0.1s; }
.obsidian-nav-item .nav-icon { font-size: 16px; width: 24px; }
.obsidian-nav-item.active { background: #0a0c0f; color: #cc0000; border-left: 3px solid #cc0000; }
.obsidian-nav-item:hover { background: #14161a; color: #aaa; }
.obsidian-sidebar.collapsed .nav-text { display: none; }
.obsidian-sidebar-footer { margin-top: auto; padding: 16px; border-top: 1px solid #1a1c20; font-size: 9px; color: #555; text-align: center; }
.obsidian-content { flex: 1; background: #0d0f12; overflow-y: auto; padding: 24px; }
.obsidian-content-scroll { scrollbar-width: thin; scrollbar-color: #aa0000 #1a1c20; }
.obsidian-content-scroll::-webkit-scrollbar { width: 6px; }
.obsidian-content-scroll::-webkit-scrollbar-track { background: #1a1c20; }
.obsidian-content-scroll::-webkit-scrollbar-thumb { background: #aa0000; border-radius: 3px; }
.obsidian-panel { display: flex; flex-direction: column; gap: 20px; }
.obsidian-section { background: #0a0c0f; border-radius: 8px; padding: 20px; border: 1px solid #1a1c20; }
.obsidian-section-header { font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: #aa0000; margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid #1a1c20; }
.obsidian-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.obsidian-toggle { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; background: #0a0c0f; border-radius: 6px; }
.obsidian-toggle-label { font-size: 13px; font-weight: 500; color: #ccccdd; }
.obsidian-switch { position: relative; width: 44px; height: 22px; background: #2a2c30; border-radius: 22px; cursor: pointer; transition: background 0.1s; }
.obsidian-switch.active { background: #aa0000; box-shadow: 0 0 10px #aa0000; }
.obsidian-switch-knob { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; background: white; border-radius: 50%; transition: left 0.1s; }
.obsidian-switch.active .obsidian-switch-knob { left: 24px; }
.obsidian-btn-primary { background: #aa0000; border: none; color: white; padding: 10px 16px; border-radius: 6px; cursor: pointer; font-size: 12px; font-weight: 600; width: 100%; letter-spacing: 0.5px; transition: all 0.1s; }
.obsidian-btn-primary:hover { background: #cc0000; box-shadow: 0 0 12px #aa0000; }
.obsidian-btn-secondary { background: transparent; border: 1px solid #3a3c40; color: #aaa; padding: 9px 16px; border-radius: 6px; cursor: pointer; font-size: 12px; width: 100%; transition: all 0.1s; }
.obsidian-btn-secondary:hover { border-color: #aa0000; color: #cc0000; }
`;
document.head.appendChild(style);
function makeButton(text, bgColor, onClick, tooltip = '') {
const btn = document.createElement('button');
btn.textContent = text;
if (bgColor === '#aa0000') btn.className = 'obsidian-btn-primary';
else btn.className = 'obsidian-btn-secondary';
btn.onclick = (e) => { e.preventDefault(); onClick(btn); };
if (tooltip) {
const wrapper = document.createElement('div');
wrapper.style.position = 'relative';
wrapper.style.display = 'inline-block';
wrapper.style.width = '100%';
const tip = document.createElement('span');
tip.textContent = tooltip;
tip.style.cssText = `position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); background: #1a1c20; color: #ccc; padding: 4px 8px; border-radius: 4px; font-size: 10px; white-space: nowrap; z-index: 100000; pointer-events: none; opacity: 0; transition: opacity 0.2s; border: 1px solid #aa0000;`;
btn.parentNode?.insertBefore(wrapper, btn);
wrapper.appendChild(btn);
wrapper.appendChild(tip);
wrapper.addEventListener('mouseenter', () => tip.style.opacity = '1');
wrapper.addEventListener('mouseleave', () => tip.style.opacity = '0');
return wrapper;
}
return btn;
}
function makePrimaryButton(text, onClick, tooltip) { return makeButton(text, '#aa0000', onClick, tooltip); }
function makeSecondaryButton(text, onClick, tooltip) { return makeButton(text, 'transparent', onClick, tooltip); }
function makeDangerButton(text, onClick, tooltip) {
const btn = makeButton(text, '#8b0000', onClick, tooltip);
btn.style.border = '1px solid #cc0000';
btn.onmouseenter = () => { btn.style.background = '#aa0000'; btn.style.borderColor = '#ff4444'; };
btn.onmouseleave = () => { btn.style.background = '#8b0000'; btn.style.borderColor = '#cc0000'; };
return btn;
}
function makeToggleSwitch(label, getState, setState, tooltip) {
const container = document.createElement('div');
container.className = 'obsidian-toggle';
const labelSpan = document.createElement('span');
labelSpan.className = 'obsidian-toggle-label';
labelSpan.textContent = label;
const toggle = document.createElement('div');
toggle.className = `obsidian-switch ${getState() ? 'active' : ''}`;
const knob = document.createElement('div');
knob.className = 'obsidian-switch-knob';
toggle.appendChild(knob);
toggle.onclick = () => {
const newState = !getState();
setState(newState);
toggle.classList.toggle('active', newState);
};
container.appendChild(labelSpan);
container.appendChild(toggle);
if (tooltip) {
const wrapper = document.createElement('div');
wrapper.style.position = 'relative';
wrapper.style.width = '100%';
const tip = document.createElement('span');
tip.textContent = tooltip;
tip.style.cssText = `position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); background: #1a1c20; color: #ccc; padding: 4px 8px; border-radius: 4px; font-size: 10px; white-space: nowrap; z-index: 100000; pointer-events: none; opacity: 0; transition: opacity 0.2s; border: 1px solid #aa0000;`;
container.parentNode?.insertBefore(wrapper, container);
wrapper.appendChild(container);
wrapper.appendChild(tip);
wrapper.addEventListener('mouseenter', () => tip.style.opacity = '1');
wrapper.addEventListener('mouseleave', () => tip.style.opacity = '0');
return wrapper;
}
return container;
}
function createSection(title, buttons) {
const section = document.createElement('div');
section.className = 'obsidian-section';
const header = document.createElement('div');
header.className = 'obsidian-section-header';
header.textContent = title;
section.appendChild(header);
const grid = document.createElement('div');
grid.className = 'obsidian-grid';
buttons.forEach(btn => grid.appendChild(btn));
section.appendChild(grid);
return section;
}
function createPanel(components) {
const panel = document.createElement('div');
panel.className = 'obsidian-panel';
components.forEach(c => panel.appendChild(c));
return panel;
}
// Build GUI container
const gui = document.createElement('div');
gui.id = 'obsidian-gui';
const topBar = document.createElement('div');
topBar.className = 'obsidian-topbar';
const search = document.createElement('input');
search.type = 'text';
search.placeholder = 'SEARCH CHEATS...';
search.className = 'obsidian-search';
const closeBtn = document.createElement('button');
closeBtn.textContent = 'X';
closeBtn.className = 'obsidian-close';
closeBtn.onclick = () => gui.style.display = 'none';
topBar.appendChild(search);
topBar.appendChild(closeBtn);
gui.appendChild(topBar);
const mainRow = document.createElement('div');
mainRow.className = 'obsidian-main-row';
const sidebar = document.createElement('div');
sidebar.className = `obsidian-sidebar ${sidebarCollapsed ? 'collapsed' : ''}`;
const sidebarHeader = document.createElement('div');
sidebarHeader.className = `obsidian-sidebar-header ${sidebarCollapsed ? 'collapsed' : ''}`;
const title = document.createElement('h1');
title.textContent = 'obsidian';
const collapse = document.createElement('button');
collapse.textContent = '◀';
collapse.className = 'obsidian-collapse-btn';
collapse.onclick = () => {
sidebarCollapsed = !sidebarCollapsed;
sidebar.classList.toggle('collapsed', sidebarCollapsed);
sidebarHeader.classList.toggle('collapsed', sidebarCollapsed);
collapse.textContent = sidebarCollapsed ? '▶' : '◀';
document.querySelectorAll('.nav-text').forEach(span => span.style.display = sidebarCollapsed ? 'none' : 'inline');
};
sidebarHeader.appendChild(title);
sidebarHeader.appendChild(collapse);
sidebar.appendChild(sidebarHeader);
const navItems = [
{ id: 'global', name: 'GLOBAL', icon: '🌐' },
{ id: 'classic', name: 'CLASSIC', icon: '🎓' },
{ id: 'gold', name: 'GOLD', icon: '💰' },
{ id: 'crypto', name: 'CRYPTO', icon: '💎' },
{ id: 'factory', name: 'FACTORY', icon: '🏭' },
{ id: 'cafe', name: 'CAFE', icon: '☕' },
{ id: 'td', name: 'TOWER DEFENSE', icon: '🛡️' },
{ id: 'racing', name: 'RACING', icon: '🏎️' },
{ id: 'royale', name: 'ROYALE', icon: '⚔️' },
{ id: 'brawl', name: 'BRAWL', icon: '👹' },
{ id: 'pirate', name: 'PIRATE', icon: '🏴☠️' },
{ id: 'fish', name: 'FISHING', icon: '🐟' },
{ id: 'dino', name: 'DINOS', icon: '🦖' },
{ id: 'kingdom', name: 'KINGDOM', icon: '👑' },
{ id: 'rush', name: 'RUSH', icon: '⚡' }
];
const navButtons = [];
const contentPanels = {};
navItems.forEach(item => {
const btn = document.createElement('button');
btn.className = 'obsidian-nav-item';
btn.innerHTML = `<span class="nav-icon">${item.icon}</span><span class="nav-text">${item.name}</span>`;
btn.onclick = () => {
navButtons.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
Object.values(contentPanels).forEach(p => p.style.display = 'none');
contentPanels[item.id].style.display = 'block';
document.querySelector('.obsidian-content').scrollTop = 0;
search.value = '';
document.querySelectorAll('.obsidian-grid > *').forEach(i => i.style.display = '');
};
navButtons.push(btn);
sidebar.appendChild(btn);
});
const footer = document.createElement('div');
footer.className = 'obsidian-sidebar-footer';
footer.textContent = 'made by placeholdernamexd';
sidebar.appendChild(footer);
mainRow.appendChild(sidebar);
const contentArea = document.createElement('div');
contentArea.className = 'obsidian-content obsidian-content-scroll';
// ---- GLOBAL PANEL ----
contentPanels.global = createPanel([
createSection('TOGGLES', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, 'Auto clicks correct answers'),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, 'Rainbow dot on correct'),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, 'Red border on correct')
]),
createSection('GLOBAL HACKS', [
makePrimaryButton('UNLIMITED TOKENS', unlimitedTokens, 'Visual token change'),
makePrimaryButton('SPEED HACK', speedHack, 'Speeds up animations'),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, 'Blocks anti‑cheat'),
makeSecondaryButton('REMOVE RANDOM NAME', removeRandomName, 'Custom name allowed'),
makeSecondaryButton('USE ANY BLOOK', useAnyBlook, 'Change your blook (lobby)'),
makeSecondaryButton('USE ANY BANNER', useAnyBanner, 'Change banner (lobby)'),
makeSecondaryButton('GET GAME CODE', getGameCode, 'Copy game code')
])
]);
// ---- CLASSIC PANEL ----
contentPanels.classic = createPanel([
createSection('CLASSIC HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makeSecondaryButton('SET SCORE', classicSetScore, 'Set your score'),
makePrimaryButton('PERFECT GAME', classicPerfectGame, 'Auto‑answers for 60s'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- GOLD PANEL ----
contentPanels.gold = createPanel([
createSection('GOLD HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET GOLD', goldSetGold, 'Set your gold amount'),
makePrimaryButton('ALWAYS TRIPLE GOLD', goldAlwaysTriple, 'Always get triple gold'),
makeDangerButton('STEAL ALL GOLD', goldStealAll, 'Take all gold from everyone'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- CRYPTO PANEL ----
contentPanels.crypto = createPanel([
createSection('CRYPTO HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET CRYPTO', hackSetCrypto, 'Set your crypto amount'),
makePrimaryButton('AUTO GUESS', hackAutoGuess, 'Auto guess passwords'),
makePrimaryButton('ALWAYS TRIPLE CRYPTO', hackAlwaysTriple, 'Always get triple crypto'),
makeDangerButton('STEAL CRYPTO', hackStealCrypto, 'Steal crypto from player'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- FACTORY PANEL ----
contentPanels.factory = createPanel([
createSection('FACTORY HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET CASH', factorySetCash, 'Set your cash amount'),
makePrimaryButton('MAX BLOOKS', factoryMaxBlooks, 'Max out all blook levels'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- CAFE PANEL ----
contentPanels.cafe = createPanel([
createSection('CAFE HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET CASH', cafeSetCash, 'Set your cash amount'),
makePrimaryButton('MAX STOCK', cafeMaxStock, 'Max out food stock'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- TOWER DEFENSE PANEL ----
contentPanels.td = createPanel([
createSection('TOWER DEFENSE HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET COINS', tdSetCoins, 'Set your coin amount'),
makePrimaryButton('KILL ENEMIES', tdKillEnemies, 'Kill all enemies'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- RACING PANEL ----
contentPanels.racing = createPanel([
createSection('RACING HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('INSTANT WIN', racingInstantWin, 'Instantly win the race'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- ROYALE PANEL ----
contentPanels.royale = createPanel([
createSection('ROYALE HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('AUTO ANSWER', royaleAutoAnswer, 'Auto‑answers for 60s'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- BRAWL PANEL ----
contentPanels.brawl = createPanel([
createSection('BRAWL HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('KILL ENEMIES', brawlKillEnemies, 'Kill all enemies'),
makePrimaryButton('INVINCIBILITY', brawlInvincibility, 'Become invincible'),
makeSecondaryButton('RESET HEALTH', brawlResetHealth, 'Reset health'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- PIRATE PANEL ----
contentPanels.pirate = createPanel([
createSection('PIRATE HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET DOUBLOONS', pirateSetDoubloons, 'Set your doubloons'),
makePrimaryButton('MAX LEVELS', pirateMaxLevels, 'Max out all levels'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- FISHING PANEL ----
contentPanels.fish = createPanel([
createSection('FISHING HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET WEIGHT', fishSetWeight, 'Set your fish weight'),
makePrimaryButton('FRENZY', fishFrenzy, 'Activate frenzy mode'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- DINOS PANEL ----
contentPanels.dino = createPanel([
createSection('DINOS HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET FOSSILS', dinoSetFossils, 'Set your fossils'),
makePrimaryButton('SET MULTIPLIER', dinoSetMultiplier, 'Set fossil multiplier'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- KINGDOM PANEL ----
contentPanels.kingdom = createPanel([
createSection('KINGDOM HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('MAX STATS', kingdomMaxStats, 'Max all kingdom stats'),
makeSecondaryButton('DISABLE TAX', kingdomDisableTax, 'Disable tax mechanic'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// ---- RUSH PANEL ----
contentPanels.rush = createPanel([
createSection('RUSH HACKS', [
makeToggleSwitch('AUTO ANSWER', () => autoAnswerActive, (v) => { autoAnswerActive = v; v ? startAutoAnswer() : stopAutoAnswer(); }, ''),
makeToggleSwitch('REVEAL ANSWER', () => revealActive, (v) => { revealActive = v; v ? startReveal() : stopReveal(); }, ''),
makeToggleSwitch('HIGHLIGHT ANSWER', () => highlightActive, (v) => { highlightActive = v; v ? startHighlight() : stopHighlight(); }, ''),
makePrimaryButton('SET BLOOKS', rushSetBlooks, 'Set your blook count'),
makeSecondaryButton('SET DEFENSE', rushSetDefense, 'Set your defense level'),
makePrimaryButton('SPEED HACK', speedHack, ''),
makeSecondaryButton('PREVENT SUSPENSION', preventSuspension, '')
])
]);
// Add all panels to content area
for (let id in contentPanels) {
contentArea.appendChild(contentPanels[id]);
contentPanels[id].style.display = 'none';
}
contentPanels.global.style.display = 'block';
if (navButtons[0]) navButtons[0].classList.add('active');
mainRow.appendChild(contentArea);
gui.appendChild(mainRow);
document.body.appendChild(gui);
// Search filter
search.addEventListener('input', (e) => {
const query = e.target.value.toLowerCase();
const current = Object.values(contentPanels).find(p => p.style.display !== 'none');
if (!current) return;
const items = current.querySelectorAll('.obsidian-grid > *');
items.forEach(item => {
const txt = item.textContent.toLowerCase();
item.style.display = txt.includes(query) ? '' : 'none';
});
});
// Drag functionality
let dragging = false, offX, offY;
topBar.addEventListener('mousedown', (e) => {
if (e.target === closeBtn || e.target === search) return;
dragging = true;
offX = e.clientX - gui.offsetLeft;
offY = e.clientY - gui.offsetTop;
gui.style.cursor = 'grabbing';
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (!dragging) return;
gui.style.left = (e.clientX - offX) + 'px';
gui.style.top = (e.clientY - offY) + 'px';
gui.style.transform = 'none';
});
document.addEventListener('mouseup', () => { dragging = false; gui.style.cursor = ''; });
// Keyboard toggle (Alt+X / Cmd+X)
document.addEventListener('keydown', (e) => {
if ((e.altKey && e.key === 'x') || (e.metaKey && e.key === 'x')) {
e.preventDefault();
gui.style.display = gui.style.display === 'none' ? 'flex' : 'none';
}
});
console.log('%cObsidian GUI v99999999999999999999232332 – Cheats should now work. Alt+X toggles.', 'color: #cc0000; font-size: 14px');
})();