515 lines
24 KiB
HTML
515 lines
24 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>MARTe2 Integrated Client</title>
|
||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||
<link rel="stylesheet" href="/uPlot.min.css">
|
||
<link rel="stylesheet" href="/style.css">
|
||
<script src="/uPlot.iife.min.js"></script>
|
||
</head>
|
||
<body>
|
||
<!-- ── Top bar ───────────────────────────────────────────────── -->
|
||
<div id="topbar">
|
||
<span id="app-title">MARTe2</span>
|
||
<div class="topbar-vsep"></div>
|
||
|
||
<!-- Debug connection menu -->
|
||
<div class="menu-wrap">
|
||
<button class="ctrl-btn" id="conn-menu-btn" onclick="toggleMenu('conn-dropdown')">
|
||
<span id="conn-status"></span>
|
||
Debug ▾
|
||
</button>
|
||
<div class="dropdown" id="conn-dropdown">
|
||
<div class="menu-row">
|
||
<input type="text" id="host" value="127.0.0.1" placeholder="host" style="flex:2">
|
||
<input type="number" id="port" value="8080" placeholder="ctrl" style="width:60px">
|
||
<button id="btn-connect" onclick="toggleConnect()">Connect</button>
|
||
</div>
|
||
<div class="menu-row" id="port-manual-row" style="display:none">
|
||
<label style="color:#a6adc8;font-size:11px;flex-shrink:0">UDP:</label>
|
||
<input type="number" id="udp-port" value="8081" placeholder="udp" style="width:72px">
|
||
<label style="color:#a6adc8;font-size:11px;flex-shrink:0">Log:</label>
|
||
<input type="number" id="log-port" value="8082" placeholder="log" style="width:72px">
|
||
</div>
|
||
<div class="menu-row">
|
||
<label class="form-check" style="margin:0;font-size:11px">
|
||
<input type="checkbox" id="auto-ports" checked onchange="toggleAutoPorts(this.checked)">
|
||
<span style="color:#a6adc8">Auto ports (SERVICE_INFO)</span>
|
||
</label>
|
||
</div>
|
||
<hr class="menu-sep">
|
||
<div class="menu-btn-row">
|
||
<button onclick="discoverCmd()">Discover</button>
|
||
<button onclick="treeCmd()">Tree</button>
|
||
<button onclick="serviceInfoCmd()">Info</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button id="btn-pause" class="ctrl-btn" onclick="togglePause()">⏸ Pause</button>
|
||
<button class="ctrl-btn" onclick="openStepDialog()">⚙ Step</button>
|
||
<button class="ctrl-btn" onclick="openForceDialog()">⚡ Force</button>
|
||
<button class="ctrl-btn" onclick="openBreakDialog()">Break</button>
|
||
<button class="ctrl-btn" onclick="openMsgDialog()">✉ Msg</button>
|
||
|
||
<div class="topbar-vsep"></div>
|
||
|
||
<!-- Scope controls -->
|
||
<button id="btn-layout" class="ctrl-btn layout-toggle" title="Select layout">⊞ 1×1 ▾</button>
|
||
<div class="topbar-sep"></div>
|
||
<div id="cursor-readout">
|
||
<span id="cur-ta">A: —</span><span class="cur-sep">│</span>
|
||
<span id="cur-tb">B: —</span><span class="cur-sep">│</span>
|
||
<span id="cur-dt">ΔT: —</span>
|
||
</div>
|
||
<span class="ctrl-label" id="lbl-window">Window:</span>
|
||
<select id="window-select" class="ctrl-select">
|
||
<option value="1">1 s</option><option value="5" selected>5 s</option>
|
||
<option value="10">10 s</option><option value="30">30 s</option>
|
||
<option value="60">60 s</option>
|
||
</select>
|
||
<button id="btn-cursor" class="ctrl-btn">Cursors</button>
|
||
<button id="btn-zoom-back" class="ctrl-btn" style="display:none">← Back</button>
|
||
<button id="btn-zoom-fit" class="ctrl-btn">Fit</button>
|
||
<button id="btn-csv-all" class="ctrl-btn" title="Export all signals to CSV">⬇ CSV</button>
|
||
<button id="btn-sync-resume" class="ctrl-btn resume-btn" style="display:none">↺ Auto</button>
|
||
<button id="btn-trigger" class="ctrl-btn">⚡ Trigger</button>
|
||
<button id="btn-pause-global" class="ctrl-btn">⏸ Pause</button>
|
||
|
||
<div class="topbar-vsep"></div>
|
||
<span id="udp-stats" style="color:#585b70;font-size:11px">0 pkts</span>
|
||
<div id="status-led"></div>
|
||
<span id="status-text" style="font-size:11px;color:#a6adc8">Disconnected</span>
|
||
<span id="sb-tsage" style="font-size:11px;color:#585b70"></span>
|
||
<button id="btn-stats" class="ctrl-btn" style="height:20px;padding:0 7px;font-size:10px;line-height:1">Stats</button>
|
||
<span id="build-version" style="font-size:10px;color:#585b70;margin-left:4px"></span>
|
||
</div>
|
||
|
||
<!-- ── Trigger bar ───────────────────────────────────────────── -->
|
||
<div id="trigbar">
|
||
<div class="trig-group">
|
||
<span class="trig-label">Signal</span>
|
||
<select id="trig-signal" class="trig-select"><option value="">— none —</option></select>
|
||
</div>
|
||
<div class="trig-sep"></div>
|
||
<div class="trig-group">
|
||
<span class="trig-label">Edge</span>
|
||
<select id="trig-edge" class="trig-select">
|
||
<option value="rising">Rising ↑</option>
|
||
<option value="falling">Falling ↓</option>
|
||
<option value="both">Both ↕</option>
|
||
</select>
|
||
</div>
|
||
<div class="trig-sep"></div>
|
||
<div class="trig-group">
|
||
<span class="trig-label">Threshold</span>
|
||
<input id="trig-threshold" class="trig-input" type="number" value="0" step="any">
|
||
</div>
|
||
<div class="trig-sep"></div>
|
||
<div class="trig-group">
|
||
<span class="trig-label">Window</span>
|
||
<select id="trig-window" class="trig-select">
|
||
<option value="0.0001">100 μs</option><option value="0.001">1 ms</option>
|
||
<option value="0.01">10 ms</option><option value="0.1">100 ms</option>
|
||
<option value="0.5">500 ms</option><option value="1" selected>1 s</option>
|
||
<option value="5">5 s</option><option value="10">10 s</option>
|
||
</select>
|
||
</div>
|
||
<div class="trig-sep"></div>
|
||
<div class="trig-group">
|
||
<span class="trig-label">Pre</span>
|
||
<input id="trig-pre" class="trig-range" type="range" min="0" max="100" value="20">
|
||
<span class="trig-range-val" id="trig-pre-val">20%</span>
|
||
</div>
|
||
<div class="trig-sep"></div>
|
||
<div class="trig-group">
|
||
<span class="trig-label">Mode</span>
|
||
<select id="trig-mode" class="trig-select">
|
||
<option value="normal">Normal</option>
|
||
<option value="single">Single</option>
|
||
</select>
|
||
</div>
|
||
<div class="trig-sep"></div>
|
||
<div class="trig-group" style="gap:8px">
|
||
<span id="trig-status-badge">IDLE</span>
|
||
<button id="btn-trig-stop" style="display:none">Stop</button>
|
||
<button id="btn-trig-rearm">Rearm</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Body ─────────────────────────────────────────────────── -->
|
||
<div id="body">
|
||
<!-- ── Step status bar (inside body, visible when paused) ── -->
|
||
<div id="step-bar">
|
||
<span>⏹ PAUSED at <b id="paused-gam">—</b></span>
|
||
<span id="step-remaining"></span>
|
||
<select id="step-thread" style="width:120px"></select>
|
||
<button onclick="step(1)">Step 1</button>
|
||
<button onclick="step(5)">Step 5</button>
|
||
<button onclick="step(20)">Step 20</button>
|
||
<button class="ok" onclick="togglePause()">▶ Resume</button>
|
||
</div>
|
||
<div id="body-row">
|
||
<!-- LEFT: signal list (scope) + object tree (debugger) -->
|
||
<div id="sidebar">
|
||
<div class="panel-tabs">
|
||
<div class="panel-tab active" onclick="switchSidebarTab('tree')">Object Tree</div>
|
||
</div>
|
||
<!-- Signals tab (hidden — signals come from Traced panel in debugger) -->
|
||
<div id="sidebar-signals" class="sidebar-tab-body" style="display:none">
|
||
<div id="signal-list"></div>
|
||
</div>
|
||
<!-- Object tree tab -->
|
||
<div id="sidebar-tree" class="sidebar-tab-body active">
|
||
<div class="panel-search">
|
||
<input id="tree-search" oninput="filterTree(this.value)" placeholder="Search tree…">
|
||
</div>
|
||
<div class="panel-body" id="tree-body">
|
||
<div class="empty-hint">Connect to MARTe2 then click Tree</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Left resize/collapse strip -->
|
||
<div id="left-strip" class="panel-strip" title="Drag to resize · Click to collapse"></div>
|
||
|
||
<!-- CENTER: plots -->
|
||
<div id="main">
|
||
<div id="plot-grid" class="l1x1"></div>
|
||
</div>
|
||
|
||
<!-- Right resize/collapse strip -->
|
||
<div id="right-strip" class="panel-strip" title="Drag to resize · Click to collapse"></div>
|
||
|
||
<!-- RIGHT: debug tabs (Traced, Forced, Breaks, Msgs) -->
|
||
<div id="right-panel">
|
||
<div class="tabs">
|
||
<div class="tab active" onclick="switchTab('traced')">Traced</div>
|
||
<div class="tab" onclick="switchTab('forced')">Forced</div>
|
||
<div class="tab" onclick="switchTab('breaks')">Breaks</div>
|
||
<div class="tab" onclick="switchTab('msgs')">Msgs</div>
|
||
</div>
|
||
<div class="tab-content active" id="tab-traced">
|
||
<div class="empty-hint" id="no-traced-hint">No signals traced</div>
|
||
</div>
|
||
<div class="tab-content" id="tab-forced">
|
||
<div class="empty-hint" id="no-forced-hint">No signals forced</div>
|
||
</div>
|
||
<div class="tab-content" id="tab-breaks">
|
||
<div class="empty-hint" id="no-breaks-hint">No breakpoints set</div>
|
||
</div>
|
||
<div class="tab-content" id="tab-msgs">
|
||
<div class="empty-hint" id="no-msgs-hint">No messages sent</div>
|
||
</div>
|
||
</div>
|
||
</div><!-- #body-row -->
|
||
|
||
<!-- ── Bottom: Logs ─────────────────────────────────────────── -->
|
||
<div id="log-panel">
|
||
<div id="log-toolbar">
|
||
<button class="panel-toggle" title="Collapse logs" onclick="togglePanel('log-panel','▼','▲',this)" id="log-toggle-btn">▼</button>
|
||
<span style="font-weight:600;color:#89b4fa">Logs</span>
|
||
<label><input type="checkbox" id="lf-service" onchange="renderLogs()"> Service</label>
|
||
<label><input type="checkbox" id="lf-debug" checked onchange="renderLogs()"> Debug</label>
|
||
<label><input type="checkbox" id="lf-info" checked onchange="renderLogs()"> Info</label>
|
||
<label><input type="checkbox" id="lf-warn" checked onchange="renderLogs()"> Warn</label>
|
||
<label><input type="checkbox" id="lf-error" checked onchange="renderLogs()"> Error</label>
|
||
<input type="text" id="log-filter" placeholder="Filter…" oninput="renderLogs()" style="width:150px">
|
||
<button onclick="logs=[];renderLogs()" style="margin-left:auto">Clear</button>
|
||
<label><input type="checkbox" id="log-autoscroll" checked> Auto-scroll</label>
|
||
</div>
|
||
<div id="log-body"></div>
|
||
</div><!-- #log-panel -->
|
||
</div><!-- #body -->
|
||
|
||
<!-- ── Stats panel ─────────────────────────────────────────── -->
|
||
<div id="stats-panel">
|
||
<div id="stats-panel-hdr">
|
||
<span class="stats-hdr-label">Source Statistics</span>
|
||
<select id="stats-source-sel" class="stats-source-sel"></select>
|
||
<button id="btn-stats-close">✕</button>
|
||
</div>
|
||
<div id="stats-body"></div>
|
||
</div>
|
||
|
||
<div id="layout-menu"></div>
|
||
|
||
<!-- ── Signal style context menu ─────────────────────────────── -->
|
||
<div id="sig-ctx-menu" style="display:none">
|
||
<div class="ctx-menu-header">Style:
|
||
<span id="ctx-menu-key" class="ctx-menu-key"></span></div>
|
||
<div class="ctx-row">
|
||
<label>Color</label>
|
||
<input type="color" id="ctx-color">
|
||
</div>
|
||
<div class="ctx-row">
|
||
<label>Width</label>
|
||
<div class="ctx-btns" id="ctx-width-btns">
|
||
<button class="ctx-btn" data-w="1">1px</button>
|
||
<button class="ctx-btn active" data-w="1.5">1.5</button>
|
||
<button class="ctx-btn" data-w="2">2px</button>
|
||
<button class="ctx-btn" data-w="3">3px</button>
|
||
</div>
|
||
</div>
|
||
<div class="ctx-row">
|
||
<label>Line</label>
|
||
<div class="ctx-btns" id="ctx-dash-btns">
|
||
<button class="ctx-btn active" data-dash="solid">——</button>
|
||
<button class="ctx-btn" data-dash="dashed">╌╌</button>
|
||
<button class="ctx-btn" data-dash="dotted">·····</button>
|
||
</div>
|
||
</div>
|
||
<div class="ctx-row">
|
||
<label>Marker</label>
|
||
<div class="ctx-btns" id="ctx-marker-btns">
|
||
<button class="ctx-btn active" data-marker="none">none</button>
|
||
<button class="ctx-btn" data-marker="circle">●</button>
|
||
<button class="ctx-btn" data-marker="square">■</button>
|
||
<button class="ctx-btn" data-marker="cross">✕</button>
|
||
<button class="ctx-btn" data-marker="diamond">◆</button>
|
||
</div>
|
||
</div>
|
||
<div class="ctx-row">
|
||
<label>Size</label>
|
||
<input type="range" class="ctx-range" id="ctx-marker-size" min="2" max="10" value="4">
|
||
<span class="ctx-range-val" id="ctx-marker-size-val">4px</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Array index picker (trigger signal) ──────────────────── -->
|
||
<div id="array-idx-picker" style="display:none">
|
||
<div class="ctx-menu-header">Element index: <span id="aip-sig" class="ctx-menu-key"></span></div>
|
||
<div class="ctx-row">
|
||
<label>Index</label>
|
||
<input type="number" id="aip-idx" class="ctx-num" min="0" step="1" value="0">
|
||
<span id="aip-range" style="font-size:10px;color:var(--overlay0)"></span>
|
||
</div>
|
||
<div class="ctx-row" style="justify-content:flex-end;gap:6px">
|
||
<button class="ctx-btn" id="aip-cancel">Cancel</button>
|
||
<button class="ctx-btn active" id="aip-ok">OK</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── VScale toolbar (moved into plot card when active) ─────── -->
|
||
<div id="vscale-menu" style="display:none">
|
||
<div class="vstb-header">
|
||
<span class="vstb-label">V-Scale: <span id="vscale-menu-key" class="ctx-menu-key"></span></span>
|
||
<div class="ctx-btns" id="vscale-mode-btns">
|
||
<button class="ctx-btn active" data-mode="auto">Auto</button>
|
||
<button class="ctx-btn" data-mode="range">Range</button>
|
||
<button class="ctx-btn" data-mode="manual">Manual</button>
|
||
</div>
|
||
<div id="vscale-manual-row" style="display:none;align-items:center;gap:4px">
|
||
<label class="vstb-lbl">V/div</label>
|
||
<input type="number" id="vscale-vdiv" class="ctx-num" min="1e-30" step="any" value="1">
|
||
</div>
|
||
<div id="vscale-pos-row" style="display:none;align-items:center;gap:4px">
|
||
<label class="vstb-lbl">Pos</label>
|
||
<input type="number" id="vscale-pos" class="ctx-num" step="0.1" value="0">
|
||
</div>
|
||
<div id="vscale-type-row" style="display:none;align-items:center;gap:4px">
|
||
<label class="vstb-lbl">Type</label>
|
||
<div class="ctx-btns" id="vscale-type-btns">
|
||
<button class="ctx-btn active" data-type="analog">Analog</button>
|
||
<button class="ctx-btn" data-type="digital">Digital</button>
|
||
</div>
|
||
</div>
|
||
<button id="btn-vscale-close" class="vstb-close" title="Close">✕</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ═══ DIALOGS ═══ -->
|
||
<!-- Force dialog -->
|
||
<div class="dialog-overlay" id="dlg-force" style="display:none" onclick="if(event.target===this)closeDlg('dlg-force')">
|
||
<div class="dialog">
|
||
<h3>Force Signal</h3>
|
||
<label>Signal</label>
|
||
<input id="force-sig" list="force-sig-list" placeholder="Signal path…">
|
||
<datalist id="force-sig-list"></datalist>
|
||
<label>Value</label>
|
||
<input id="force-val" placeholder="e.g. 42">
|
||
<div class="btns">
|
||
<button onclick="closeDlg('dlg-force')">Cancel</button>
|
||
<button class="active" onclick="doForce()">Force</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Unforce confirm -->
|
||
<div class="dialog-overlay" id="dlg-unforce" style="display:none" onclick="if(event.target===this)closeDlg('dlg-unforce')">
|
||
<div class="dialog">
|
||
<h3>Remove Force</h3>
|
||
<p id="unforce-msg" style="margin-bottom:12px;color:#cdd6f4"></p>
|
||
<div class="btns">
|
||
<button onclick="closeDlg('dlg-unforce')">Cancel</button>
|
||
<button class="danger" onclick="doUnforce()">Unforce</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Break dialog -->
|
||
<div class="dialog-overlay" id="dlg-break" style="display:none" onclick="if(event.target===this)closeDlg('dlg-break')">
|
||
<div class="dialog">
|
||
<h3>Set Breakpoint</h3>
|
||
<label>Signal</label>
|
||
<input id="break-sig" list="break-sig-list" placeholder="Signal path…">
|
||
<datalist id="break-sig-list"></datalist>
|
||
<div class="form-row">
|
||
<div>
|
||
<label>Operator</label>
|
||
<select id="break-op">
|
||
<option>></option><option>>=</option>
|
||
<option><</option><option><=</option>
|
||
<option>==</option><option>!=</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label>Threshold</label>
|
||
<input id="break-thresh" placeholder="0">
|
||
</div>
|
||
</div>
|
||
<div class="btns">
|
||
<button onclick="closeDlg('dlg-break')">Cancel</button>
|
||
<button class="active" onclick="doBreak()">Set Break</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Message dialog -->
|
||
<div class="dialog-overlay" id="dlg-msg" style="display:none" onclick="if(event.target===this)closeDlg('dlg-msg')">
|
||
<div class="dialog">
|
||
<h3>Send Message</h3>
|
||
<label>Destination</label>
|
||
<input id="msg-dest" list="msg-dest-list" placeholder="e.g. App.Functions.GAM1">
|
||
<datalist id="msg-dest-list"></datalist>
|
||
<label>Function</label>
|
||
<input id="msg-func" placeholder="FunctionName">
|
||
<label>Payload (key=value lines)</label>
|
||
<textarea id="msg-payload" placeholder="Key = Value Key2 = Value2"></textarea>
|
||
<div class="form-check">
|
||
<input type="checkbox" id="msg-wait">
|
||
<label for="msg-wait">Wait for reply</label>
|
||
</div>
|
||
<div class="btns">
|
||
<button onclick="closeDlg('dlg-msg')">Cancel</button>
|
||
<button class="active" onclick="doSendMsg()">Send</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Array signal dialog (Trace / Force / Break with index/range selection) -->
|
||
<div class="dialog-overlay" id="dlg-array" style="display:none" onclick="if(event.target===this)closeDlg('dlg-array')">
|
||
<div class="dialog" style="min-width:360px">
|
||
<h3 id="arr-dlg-title">Array Signal</h3>
|
||
<p style="font-size:11px;color:#a6adc8;margin-bottom:14px">
|
||
<b id="arr-dlg-sig" style="color:#cdd6f4"></b>
|
||
· <span id="arr-dlg-n" style="color:#89b4fa"></span> elements
|
||
</p>
|
||
<label style="margin-bottom:6px">Apply to</label>
|
||
<div class="arr-seg">
|
||
<button id="arr-sel-all" class="active" onclick="setArrSel('all')">All</button>
|
||
<button id="arr-sel-idx" onclick="setArrSel('idx')">Index</button>
|
||
<button id="arr-sel-rng" onclick="setArrSel('rng')">Range</button>
|
||
</div>
|
||
<div id="arr-idx-sect" style="display:none">
|
||
<label>Element index <span style="color:#585b70;font-weight:normal">(0 – <span id="arr-idx-max"></span>)</span></label>
|
||
<input id="arr-idx" type="number" min="0" value="0">
|
||
</div>
|
||
<div id="arr-rng-sect" style="display:none">
|
||
<div class="form-row">
|
||
<div>
|
||
<label>From index</label>
|
||
<input id="arr-r0" type="number" min="0" value="0">
|
||
</div>
|
||
<div>
|
||
<label>To index <span style="color:#585b70;font-weight:normal">inclusive</span></label>
|
||
<input id="arr-r1" type="number" min="0" value="0">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div id="arr-force-sect" style="display:none">
|
||
<label>Force value</label>
|
||
<input id="arr-force-val" placeholder="e.g. 0">
|
||
</div>
|
||
<div id="arr-break-sect" style="display:none">
|
||
<div class="form-row">
|
||
<div>
|
||
<label>Condition</label>
|
||
<select id="arr-break-op">
|
||
<option>></option><option>>=</option>
|
||
<option><</option><option><=</option>
|
||
<option>==</option><option>!=</option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label>Threshold</label>
|
||
<input id="arr-break-thr" placeholder="0">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="btns">
|
||
<button onclick="closeDlg('dlg-array')">Cancel</button>
|
||
<button id="arr-ok-btn" class="active" onclick="doArrayOp()">Apply</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Array → plot mode dialog (Sequential / Waterfall) -->
|
||
<div class="dialog-overlay" id="dlg-arr-plot" style="display:none" onclick="if(event.target===this)closeDlg('dlg-arr-plot')">
|
||
<div class="dialog" style="min-width:360px">
|
||
<h3>Plot Array Signal</h3>
|
||
<p style="font-size:11px;color:#a6adc8;margin-bottom:14px">
|
||
<b id="arrp-name" style="color:#cdd6f4"></b>
|
||
· <span id="arrp-n" style="color:#89b4fa"></span> elements
|
||
</p>
|
||
<div class="arr-seg" style="margin-bottom:8px">
|
||
<button id="arrp-sel-sequential" class="active" onclick="setArrpMode('sequential')">Sequential</button>
|
||
<button id="arrp-sel-waterfall" onclick="setArrpMode('waterfall')">Waterfall</button>
|
||
</div>
|
||
<p id="arrp-desc" style="font-size:10px;color:#a6adc8;margin-bottom:16px;min-height:28px"></p>
|
||
<div class="btns">
|
||
<button onclick="closeDlg('dlg-arr-plot')">Cancel</button>
|
||
<button class="active" onclick="doArrayPlotMode()">Add</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Info dialog -->
|
||
<div class="dialog-overlay" id="dlg-info" style="display:none" onclick="if(event.target===this)closeDlg('dlg-info')">
|
||
<div class="dialog" style="max-width:600px;width:90vw">
|
||
<h3 id="info-title">Info</h3>
|
||
<pre id="info-body" style="background:#11111b;padding:8px;border-radius:4px;overflow:auto;max-height:400px;font-size:11px;color:#cdd6f4;white-space:pre-wrap"></pre>
|
||
<div class="btns" style="margin-top:12px">
|
||
<button onclick="closeDlg('dlg-info')">Close</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Step dialog -->
|
||
<div class="dialog-overlay" id="dlg-step" style="display:none" onclick="if(event.target===this)closeDlg('dlg-step')">
|
||
<div class="dialog">
|
||
<h3>Step Execution</h3>
|
||
<div class="form-row">
|
||
<div>
|
||
<label>Count</label>
|
||
<input type="number" id="step-count" value="1" min="1">
|
||
</div>
|
||
<div>
|
||
<label>Thread (optional)</label>
|
||
<input id="step-thread-inp" list="step-thread-list" placeholder="all">
|
||
<datalist id="step-thread-list"></datalist>
|
||
</div>
|
||
</div>
|
||
<div class="btns">
|
||
<button onclick="closeDlg('dlg-step')">Cancel</button>
|
||
<button class="active" onclick="doStep()">Step</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="/app.js"></script>
|
||
</body>
|
||
</html>
|