"use strict"; function ensureWorldBootstrap() { let currentWorld = globalThis.world; if (currentWorld?.update) return currentWorld; try { currentWorld = new World(); if (typeof window !== "undefined") window.world = currentWorld; if (typeof globalThis !== "undefined") globalThis.world = currentWorld; return currentWorld; } catch (error) { throw error; } } let world = ensureWorldBootstrap(); let last = nowSec(); let statsTimer = 0; window.__tarinaiFps = 0; const LOADING_SPRITES = SPRITES .filter(asset => asset && !asset.actionOnly) .slice(0, 11) .map(asset => asset.path); let loadingSpriteTimer = 0; function shuffledLoadingSprites() { const list = [...LOADING_SPRITES]; for (let i = list.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [list[i], list[j]] = [list[j], list[i]]; } return list.slice(0, 4); } function renderLoadingSprites() { const strip = document.getElementById("loadingSpriteStrip"); if (!strip) return; strip.innerHTML = ""; const frag = document.createDocumentFragment(); for (const src of shuffledLoadingSprites()) { const card = document.createElement("div"); card.className = "loading-sprite-card"; const img = document.createElement("img"); img.src = src; img.alt = ""; img.loading = "eager"; card.appendChild(img); frag.appendChild(card); } strip.appendChild(frag); } function initLoadingShowcase() { renderLoadingSprites(); if (loadingSpriteTimer) clearInterval(loadingSpriteTimer); loadingSpriteTimer = window.setInterval(renderLoadingSprites, 1200); } function setLoadingProgress(text = "", ratio = 0) { const screen = document.getElementById("loadingScreen"); if (!screen) return; const pct = clamp(Number(ratio) || 0, 0, 1); const label = document.getElementById("loadingText"); const bar = document.getElementById("loadingBar"); const percent = document.getElementById("loadingPercent"); if (label && text) label.textContent = text; if (bar) bar.style.width = `${Math.round(pct * 100)}%`; if (percent) percent.textContent = `${Math.round(pct * 100)}%`; } function hideLoadingScreen() { if (loadingSpriteTimer) { clearInterval(loadingSpriteTimer); loadingSpriteTimer = 0; } document.getElementById("loadingSpriteStrip")?.replaceChildren(); setLoadingProgress("\u8d77\u52d5\u5b8c\u4e86", 1); const screen = document.getElementById("loadingScreen"); if (!screen) return; window.setTimeout(() => screen.classList.add("hidden"), 120); } function loop() { const t = nowSec(); const rawDt = t - last; const dt = clamp(rawDt, 0, 0.05); last = t; window.TarinaiPerf.observeFrameDelta(rawDt); window.TarinaiPerf.beginFrame(); const endUpdate = window.TarinaiPerf.begin("update.total"); world.update(dt); if (endUpdate) endUpdate(); const endRender = window.TarinaiPerf.begin("render.total"); render(); if (endRender) endRender(); window.TarinaiPerf.endFrame(); if (window.TarinaiPerf.consumeResizeRequest() && typeof resizeCanvas === "function") resizeCanvas(); statsTimer += dt; const statsInterval = 2.5; if (statsTimer > statsInterval) { renderStats(); statsTimer = 0; } requestAnimationFrame(loop); } initLoadingShowcase(); setLoadingProgress("\u521d\u671f\u753b\u50cf\u3092\u8aad\u307f\u8fbc\u307f\u4e2d", 0.08); loadImages((done, total) => { const p = total > 0 ? done / total : 1; setLoadingProgress(`\u521d\u671f\u753b\u50cf\u3092\u8aad\u307f\u8fbc\u307f\u4e2d ${done}/${total}`, 0.08 + p * 0.46); }).then(() => { setLoadingProgress("UI\u3092\u6e96\u5099\u4e2d", 0.62); bindUI(); setLoadingProgress("\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u69cb\u7bc9\u4e2d", 0.72); applyFieldLayout("garden"); world.reset(null, "garden"); window.TarinaiGroundUI?.bind?.(world); selectTool("observe"); setLoadingProgress("\u8868\u793a\u3092\u521d\u671f\u5316\u4e2d", 0.84); renderLog(world.logs); renderArchive(); render(); renderStats(); syncTopButtons(); startBackgroundImageLoading(); setLoadingProgress("\u30b7\u30df\u30e5\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u958b\u59cb\u4e2d", 0.94); loop(); requestAnimationFrame(hideLoadingScreen); }); if ("serviceWorker" in navigator) { window.addEventListener("load", () => { const swUrl = window.TARINAI_APP?.withVersion?.("./service-worker.js") || "./service-worker.js"; navigator.serviceWorker.register(swUrl, { updateViaCache: "none" }).catch(() => undefined); }); }