317 lines
14 KiB
HTML
317 lines
14 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Prefecture Map Generator</title>
|
||
<link rel="stylesheet" href="./styles/styles.css" />
|
||
</head>
|
||
<body>
|
||
<div class="app">
|
||
<main class="page-shell">
|
||
<section class="top-stage">
|
||
<section class="map-section" aria-label="Map area">
|
||
<div class="canvas-shell" id="canvasShell">
|
||
<div class="canvas-stage">
|
||
<canvas id="mapCanvas" class="map-canvas"></canvas>
|
||
</div>
|
||
<svg id="mapSelectionSvg" class="map-selection-svg" aria-hidden="true"></svg>
|
||
<div id="mapSelection" class="map-selection" aria-hidden="true"></div>
|
||
|
||
<div id="toolHint" class="map-hint hidden">
|
||
Patch Area mode: right-drag to select an expansion or regeneration area.
|
||
</div>
|
||
|
||
<div class="zoom-control" aria-label="Map zoom controls">
|
||
<button id="zoomIn" type="button" aria-label="Zoom in">+</button>
|
||
<button id="zoomOut" type="button" aria-label="Zoom out">−</button>
|
||
<button id="zoomReset" type="button">100%</button>
|
||
<button id="centerMap" type="button">Center</button>
|
||
</div>
|
||
|
||
<aside class="map-dock" aria-label="Layer and legend controls">
|
||
<details class="dock-card" open>
|
||
<summary>
|
||
<span>Layer</span>
|
||
<span class="summary-button" aria-hidden="true">Toggle</span>
|
||
</summary>
|
||
<div class="dock-body">
|
||
<div class="field-label">Display mode</div>
|
||
<div id="modeGrid" class="mode-grid"></div>
|
||
|
||
<div class="divider"></div>
|
||
|
||
<label class="checkbox-row">
|
||
<input id="showFeatures" type="checkbox" checked />
|
||
<span>Map features</span>
|
||
</label>
|
||
<label class="checkbox-row">
|
||
<input id="showLabels" type="checkbox" checked />
|
||
<span>Labels</span>
|
||
</label>
|
||
<label class="checkbox-row">
|
||
<input id="showSeamDiagnostics" type="checkbox" checked />
|
||
<span>Seam diagnostics</span>
|
||
</label>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="dock-card">
|
||
<summary>
|
||
<span>Legend</span>
|
||
<span class="summary-button" aria-hidden="true">Toggle</span>
|
||
</summary>
|
||
<div id="mainLegendGrid" class="legend-grid dock-body"></div>
|
||
</details>
|
||
</aside>
|
||
|
||
<div id="generationProgress" class="generation-progress hidden" role="status" aria-live="polite">
|
||
<div class="progress-title">Generating map...</div>
|
||
<div id="generationProgressStage" class="progress-stage">Preparing</div>
|
||
<div id="generationProgressTimings" class="progress-timings"></div>
|
||
</div>
|
||
<div id="mapTooltip" class="map-tooltip" role="status" aria-live="polite"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<aside class="generation-section" aria-label="Generation settings">
|
||
<section class="settings-card settings-header-card">
|
||
<div class="card-heading tight">
|
||
<div>
|
||
<div class="eyebrow">Controls</div>
|
||
<h2>Generation Settings</h2>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="settings-card">
|
||
<label class="field">
|
||
<span class="field-label">Seed</span>
|
||
<input id="seed" class="input" value="114514" />
|
||
</label>
|
||
|
||
<label class="field">
|
||
<span class="field-label">Terrain type</span>
|
||
<select id="generationType" class="input">
|
||
<option value="auto">Auto</option>
|
||
<option value="tohoku_spine">Tohoku spine</option>
|
||
<option value="chubu_mountain">Chubu mountain</option>
|
||
<option value="setouchi_inland_sea">Setouchi inland sea</option>
|
||
<option value="oceanic_archipelago">Oceanic archipelago</option>
|
||
<option value="kanto_alluvial">Kanto alluvial plain</option>
|
||
<option value="mixed_archipelago">Mixed archipelago</option>
|
||
</select>
|
||
</label>
|
||
|
||
<div class="button-stack two-col">
|
||
<button id="generateMap" type="button" class="primary-button">Generate</button>
|
||
<button id="randomSeed" type="button" class="secondary-button">Random</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="settings-card">
|
||
<div class="card-heading">
|
||
<div>
|
||
<div class="eyebrow">Interaction</div>
|
||
<h3>Mode</h3>
|
||
</div>
|
||
</div>
|
||
<div class="segmented-group" aria-label="Interaction mode">
|
||
<button id="toolPan" type="button" class="segmented-button active" data-tool="pan">Pan</button>
|
||
<button id="toolPatch" type="button" class="segmented-button" data-tool="patch">Patch Area</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="settings-card patch-card">
|
||
<div class="card-heading">
|
||
<div>
|
||
<div class="eyebrow">Right-drag selection</div>
|
||
<h3>Patch Generation</h3>
|
||
</div>
|
||
</div>
|
||
|
||
<label class="field">
|
||
<span class="field-label">Patch terrain</span>
|
||
<select id="patchTerrainType" class="input">
|
||
<option value="auto">Auto</option>
|
||
<option value="tohoku_spine">Tohoku spine</option>
|
||
<option value="chubu_mountain">Chubu mountain</option>
|
||
<option value="setouchi_inland_sea">Setouchi inland sea</option>
|
||
<option value="oceanic_archipelago">Oceanic archipelago</option>
|
||
<option value="kanto_alluvial">Kanto alluvial plain</option>
|
||
<option value="mixed_archipelago">Mixed archipelago</option>
|
||
</select>
|
||
</label>
|
||
|
||
<label class="field">
|
||
<span class="field-label">Patch mode</span>
|
||
<select id="patchMode" class="input">
|
||
<option value="auto">Auto (detect expansion)</option>
|
||
<option value="expansion">Expand generated world</option>
|
||
<option value="regeneration">Regenerate existing area</option>
|
||
</select>
|
||
</label>
|
||
|
||
<label class="field">
|
||
<span class="field-label">Variant</span>
|
||
<input id="patchVariant" class="input" type="number" min="0" step="1" value="0" />
|
||
</label>
|
||
|
||
<div class="button-stack two-col">
|
||
<button id="generatePatch" type="button" class="primary-button" disabled>Preview Area</button>
|
||
<button id="alternativePatch" type="button" class="secondary-button" disabled>Alternative</button>
|
||
</div>
|
||
<div class="button-stack two-col">
|
||
<button id="applyPatch" type="button" class="secondary-button" disabled>Apply Preview</button>
|
||
<button id="discardPatch" type="button" class="ghost-button" disabled>Discard</button>
|
||
</div>
|
||
<div class="button-stack two-col">
|
||
<button id="clearPatchSelection" type="button" class="ghost-button" disabled>Clear Selection</button>
|
||
<button id="cancelPatchGeneration" type="button" class="ghost-button" disabled>Cancel Generation</button>
|
||
</div>
|
||
|
||
<p id="patchStatus" class="patch-status">Switch to Patch Area, then right-drag to draw a freeform area.</p>
|
||
</section>
|
||
</aside>
|
||
</section>
|
||
|
||
<section class="summary-section" aria-label="Summary">
|
||
<div class="section-title-row compact">
|
||
<div>
|
||
<div class="eyebrow">Current map</div>
|
||
<h2>Summary</h2>
|
||
</div>
|
||
</div>
|
||
<div id="stats" class="stats summary-stats"></div>
|
||
</section>
|
||
|
||
<section class="advanced-section" aria-label="Advanced and debug data">
|
||
<details class="advanced-details">
|
||
<summary>
|
||
<span>Advanced / Debug Data</span>
|
||
<span class="advanced-summary-actions">
|
||
<button id="copyImportantData" type="button" class="copy-debug-button">Copy Important Data</button>
|
||
<span id="copyDebugStatus" class="copy-debug-status" aria-live="polite"></span>
|
||
<span class="advanced-toggle" aria-hidden="true">Open</span>
|
||
</span>
|
||
</summary>
|
||
<div class="advanced-body">
|
||
<section class="debug-panel wide">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Last 10</div>
|
||
<h3>Full Generation Performance</h3>
|
||
</div>
|
||
<p>Average, max, P95, breakdown, terrain type, area, and seconds per 1,000 cells.</p>
|
||
</header>
|
||
<div id="advancedGenerationStats" class="metric-grid"></div>
|
||
<div id="advancedGenerationHistory" class="perf-history"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel wide">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Last 10</div>
|
||
<h3>Patch / Additional Generation Performance</h3>
|
||
</div>
|
||
<p>Preview and alternative patch generation, including selected area and normalized cost.</p>
|
||
</header>
|
||
<div id="advancedPatchStats" class="metric-grid"></div>
|
||
<div id="advancedPatchHistory" class="perf-history"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel wide">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Last 10</div>
|
||
<h3>Viewport Interaction Latency</h3>
|
||
</div>
|
||
<p>Pan and zoom are aggregated separately for fast redraw and full redraw phases.</p>
|
||
</header>
|
||
<div class="aggregate-header" aria-hidden="true">
|
||
<span>Group</span><small>Count</small><strong>Avg</strong><strong>Max</strong><strong>P95</strong>
|
||
</div>
|
||
<div id="advancedInteractionStats" class="perf-history compact"></div>
|
||
<div id="advancedInteractionHistory" class="perf-history compact"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel wide">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Current render</div>
|
||
<h3>Viewport / Feature Diagnostics</h3>
|
||
</div>
|
||
<p>Drawn cell count, viewport size, canvas size, and feature counts used to separate generation cost from rendering cost.</p>
|
||
</header>
|
||
<div id="advancedViewportDiagnostics" class="diagnostic-grid"></div>
|
||
<div id="advancedFeatureCounts" class="diagnostic-table"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Patch area</div>
|
||
<h3>Selection / Write Ratio</h3>
|
||
</div>
|
||
</header>
|
||
<div id="advancedPatchDiagnostics" class="diagnostic-table"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Patch seam</div>
|
||
<h3>Seam Diagnostics</h3>
|
||
</div>
|
||
<p>Magenta: seam outline. Red: disconnected or critical. Orange: topology/boundary warning. Green: retained transport crossing.</p>
|
||
</header>
|
||
<div id="advancedSeamDiagnostics" class="diagnostic-table"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Runtime</div>
|
||
<h3>Worker / World Diagnostics</h3>
|
||
</div>
|
||
</header>
|
||
<div id="advancedWorkerDiagnostics" class="diagnostic-table"></div>
|
||
<div id="advancedWorldDiagnostics" class="diagnostic-table stacked"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel wide">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Last 10</div>
|
||
<h3>Warnings / Errors</h3>
|
||
</div>
|
||
<p>Recent invalid selections, worker fallbacks, failed generations, and other UI-visible diagnostics.</p>
|
||
</header>
|
||
<div id="advancedWarningHistory" class="diagnostic-log"></div>
|
||
</section>
|
||
|
||
<section class="debug-panel">
|
||
<header class="debug-panel-header">
|
||
<div>
|
||
<div class="eyebrow">Notes</div>
|
||
<h3>Debug Policy</h3>
|
||
</div>
|
||
</header>
|
||
<div class="debug-note flat">
|
||
<strong>Patch workflow</strong>
|
||
<p>Preview Area inspects a candidate patch. Apply Preview commits it; Discard resets it.</p>
|
||
</div>
|
||
<div class="debug-note flat">
|
||
<strong>Readable default UI</strong>
|
||
<p>Verbose debug layers and unused legend entries stay outside the default controls.</p>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</details>
|
||
</section>
|
||
</main>
|
||
</div>
|
||
|
||
<script type="module" src="./src/app.js"></script>
|
||
</body>
|
||
</html>
|