export declare const DEV_SHELL_BANNER: string; export declare const DEV_SHELL_PAGE_HTML = "\n\n\n\n\nhelix dev \u2014 SIMULATED shell\n\n\n\n
SIMULATED shell \u2014 helix dev. Purchases, saves and achievements are simulated locally; nothing here proves a product is registered or that settlement works.
\n
\n
Simulated purchase

\n \n
\n\n\n\n"; export declare const DEV_SHELL_PAGE_JS = "// Served by `helix dev`. Everything here is SIMULATED \u2014 see the banner.\nconst logEl = document.getElementById('log');\nconst menuEl = document.getElementById('menu');\nconst metaEl = document.getElementById('meta');\nconst frame = document.getElementById('world');\nconst toastEl = document.getElementById('toast');\n\nlet toastTimer = null;\nfunction toast(text) {\n toastEl.textContent = text;\n toastEl.className = 'show';\n if (toastTimer) clearTimeout(toastTimer);\n toastTimer = setTimeout(function () { toastEl.className = ''; }, 4000);\n}\n\n// The real shell's purchase confirm, simulated: one dialog at a time, queued in arrival order.\nconst confirmEl = document.getElementById('confirm');\nlet confirmChain = Promise.resolve();\nfunction confirmPurchase(req) {\n const ask = function () {\n return new Promise(function (done) {\n document.getElementById('confirmTitle').textContent = req.title;\n document.getElementById('confirmPrice').innerHTML = req.isFree\n ? 'Free claim · balance stays ' + req.balanceLix + ' LIX'\n : '' + req.priceLix + ' LIX · balance ' + req.balanceLix + ' → ' + req.balanceAfterLix + '';\n confirmEl.className = 'show';\n const buy = document.getElementById('confirmBuy');\n const cancel = document.getElementById('confirmCancel');\n const settle = function (verdict) {\n confirmEl.className = '';\n buy.onclick = null;\n cancel.onclick = null;\n done(verdict);\n };\n buy.onclick = function () { settle(true); };\n cancel.onclick = function () { settle(false); };\n });\n };\n const result = confirmChain.then(ask);\n confirmChain = result.then(function () {}, function () {});\n return result;\n}\n\nfunction append(text, kind) {\n const line = document.createElement('div');\n if (kind) line.className = kind;\n line.textContent = text;\n logEl.appendChild(line);\n while (logEl.childElementCount > 500) logEl.removeChild(logEl.firstChild);\n logEl.scrollTop = logEl.scrollHeight;\n}\n\nfunction show(value) {\n if (value === undefined) return '';\n try {\n return typeof value === 'string' ? value : JSON.stringify(value);\n } catch (err) {\n return String(value);\n }\n}\n\nfunction button(label, onClick) {\n const el = document.createElement('button');\n el.textContent = label;\n el.addEventListener('click', function () { onClick(el); });\n menuEl.appendChild(el);\n return el;\n}\n\nasync function main() {\n const config = await (await fetch('/dev/config')).json();\n frame.src = config.worldOrigin + '/';\n\n const devShell = await import('/sdk/dev-shell/index.js');\n const prefix = devShell.DEV_SHELL_LOG_PREFIX;\n\n let pending = null;\n let sending = false;\n async function flush() {\n if (sending || pending === null) return;\n sending = true;\n const body = pending;\n pending = null;\n try {\n await fetch('/dev/state', { method: 'POST', headers: { 'content-type': 'application/json' }, body: body });\n } catch (err) {\n append('state was not saved: ' + String(err), 'err');\n }\n sending = false;\n flush();\n }\n\n // A fresh player has no stored state, so the seeded achievement registry is minted into a new one here.\n const freshState = !config.state && config.achievements\n ? devShell.createDevShellState({ identity: config.user, achievements: config.achievements })\n : undefined;\n\n const shell = devShell.createDevShell({\n worldWindow: frame,\n worldOrigin: config.worldOrigin,\n world: config.world,\n user: config.user,\n state: config.state || freshState,\n products: config.products || undefined,\n debug: true,\n onAchievementEarned: function (a) {\n toast('Achievement unlocked (SIMULATED): ' + a.name + (a.points ? ' (+' + a.points + ')' : ''));\n },\n confirmPurchase: confirmPurchase,\n log: function (message, detail) {\n append(detail === undefined ? message : message + ' ' + show(detail), message.indexOf(prefix) === 0 ? 'sim' : null);\n if (detail === undefined) console.log(message);\n else console.log(message, detail);\n },\n onStateChange: function (state) {\n pending = JSON.stringify(state);\n flush();\n },\n });\n window.helixDevShell = shell;\n\n metaEl.innerHTML =\n '
world ' + config.world.title + ' (' + config.world.slug + ')
' +\n '
player ' + config.user.id + '
' +\n '
served from ' + config.worldOrigin + '
';\n\n let failMode = 'off';\n let saveFailure = false;\n let signedIn = true;\n\n button('Grant all entitlements', function () { shell.grantAllEntitlements(); });\n button('Grant one entitlement\u2026', function () {\n const ref = window.prompt('Product key or ref to grant');\n if (ref) shell.grantEntitlement(ref);\n });\n button('Remove one entitlement\u2026', function () {\n const ref = window.prompt('Product key or ref to remove');\n if (ref) shell.removeEntitlement(ref);\n });\n button('Print owned entitlements', function () {\n append(prefix + ' entitlements ' + show(shell.getEntitlementsSnapshot()), 'sim');\n });\n const failButton = button('Purchases always fail: off', function (el) {\n failMode = shell.cyclePurchasesAlwaysFail();\n el.textContent = 'Purchases always fail: ' + failMode;\n el.className = failMode === 'off' ? '' : 'armed';\n });\n failButton.textContent = 'Purchases always fail: ' + failMode;\n button('Reset player document', function () { shell.resetPlayerDocument(); });\n button('Force save failure: off', function (el) {\n saveFailure = !saveFailure;\n shell.setForceSaveFailure(saveFailure);\n el.textContent = 'Force save failure: ' + (saveFailure ? 'on' : 'off');\n el.className = saveFailure ? 'armed' : '';\n });\n button('Exhaust consume fence', function () { shell.exhaustConsumeFence(); });\n button('Set wallet\u2026', function () {\n const lix = window.prompt('Simulated LIX balance', '500');\n if (lix !== null && lix !== '') shell.setWallet({ lix: Number(lix) });\n });\n button('Award achievement\u2026', function () {\n const key = window.prompt('Achievement key to award (must be in the local registry)');\n if (key) shell.awardAchievement(key);\n });\n button('Print achievement progress', function () { shell.getAchievementsProgress(); });\n button('Add 5 min playtime', function () {\n shell.addPlaytime(300);\n append(prefix + ' +300s playtime added', 'sim');\n });\n button('Bump analytics event\u2026', function () {\n const name = window.prompt('Analytics event name (e.g. world_entered) \u2014 real events never reach a shell');\n if (name) shell.bumpAnalyticsEvent(name);\n });\n button('Set MP player var\u2026', function () {\n const field = window.prompt('Persistent playerVar (dot-path, e.g. wins)');\n if (!field) return;\n const value = window.prompt('Numeric value for \"' + field + '\"', '1');\n if (value !== null && value !== '') shell.setMpPlayerVar(field, Number(value));\n });\n button('Reset earned achievements', function () { shell.resetAchievements(); });\n button('Seed leaderboard score\u2026', function () {\n const board = window.prompt('Board name (declared boards are room-written live \u2014 this is the room, by hand)', 'main');\n if (!board) return;\n const player = window.prompt('Player name (empty = the simulated player)');\n const score = window.prompt('Score', '100');\n if (score === null || score === '') return;\n shell.seedLeaderboardScore(board, Number(score), player ? { subject: player, displayName: player } : {});\n });\n button('Set data-store doc\u2026', function () {\n const key = window.prompt('Document key (world-global / mp:world:* / reserved keys allowed \u2014 this is the server, by hand)');\n if (!key) return;\n const raw = window.prompt('JSON value for \"' + key + '\"', '{}');\n if (raw === null) return;\n try { shell.seedDocument(key, JSON.parse(raw)); }\n catch (err) { append('not valid JSON: ' + String(err), 'err'); }\n });\n button('Push shell event\u2026', function () {\n const event = window.prompt('Shell event (avatar-changed, equipment-changed, overlay-open, overlay-closed, \u2026)');\n if (event) shell.pushEvent(event);\n });\n button('Signed in: yes', function (el) {\n signedIn = !signedIn;\n shell.setSignedIn(signedIn);\n el.textContent = 'Signed in: ' + (signedIn ? 'yes' : 'no');\n el.className = signedIn ? '' : 'armed';\n });\n button('Print state', function () { append(prefix + ' state ' + show(shell.getState()), 'sim'); });\n button('Reload world', function () { frame.src = config.worldOrigin + '/?t=' + Date.now(); });\n button('Clear log', function () { logEl.textContent = ''; });\n\n // Playtime evidence accrues while the shell is open \u2014 the local stand-in for the server's rollup.\n setInterval(function () { shell.addPlaytime(15); }, 15000);\n\n append(prefix + ' shell ready \u2014 the room lane (DSL rules, consume/save/saveRoom) is NOT simulated; ' +\n 'the debug menu stands in for awardAchievement and the persistent-var flush.', 'sim');\n}\n\nmain().catch(function (err) {\n append('dev shell failed to start: ' + String(err && err.stack ? err.stack : err), 'err');\n});\n";