Files
Aidem-Media-DLL-Analysis/ams/api/static/style.css
Patryk Gensch b0d3d22445 Body normalisation: per-method similarity score + leaf delta
Turns the dispatch axis from a binary changed/unchanged into a "how much" measure
of code change — the original goal. ams.normalize compares two body fingerprints
(the ordered leaf-call anchors) with difflib after collapsing consecutive-duplicate
anchors (a load-twice codegen artefact), yielding a 0-100 similarity and the exact
leaves that appeared/vanished.

Every dispatch `changed` entry now carries body={similarity, added, removed}, and the
block carries a summary={shared, identical, changed, mean_similarity}.

Golden pair (cross-compiler): 470 shared bodies, 131 identical, mean 66% similar;
Animo SHOW/HIDE/PAUSE/RESUME come out 100% despite MSVC6 vs MSVC8, LOAD 50% with the
swapped leaves spelled out.

- normalize.py: canonical / body_similarity / body_delta
- diff: _dispatch_diff enriches changed with body + adds summary
- render: METHOD BODIES shows %, leaf delta, summary line
- UI: similarity % + leaf delta + axis summary
- tests: 5 new -> 34/34

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 13:23:15 +02:00

125 lines
7.4 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
:root {
--bg: #0d1117; --panel: #131a23; --panel2: #1a2330; --border: #243140;
--fg: #c9d4e0; --dim: #6b7c8f; --accent: #4ea3ff; --accent2: #1f6feb;
--add: #3fb950; --del: #f85149; --chg: #d29922; --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { background: var(--bg); color: var(--fg); font: 13px/1.45 var(--mono); }
.topbar { display: flex; align-items: baseline; gap: 16px; padding: 10px 18px;
background: linear-gradient(180deg, #131c28, #0d1117); border-bottom: 1px solid var(--border); }
.brand { font-size: 16px; font-weight: 600; letter-spacing: .5px; color: #eaf2fb; }
.brand span { color: var(--accent); font-weight: 400; }
.sub { color: var(--dim); font-size: 12px; }
.layout { display: grid; grid-template-columns: 320px 1fr; height: calc(100% - 47px); }
.sidebar { border-right: 1px solid var(--border); overflow-y: auto; background: var(--panel); }
.panel-title { padding: 10px 14px; color: var(--dim); text-transform: uppercase; font-size: 11px;
letter-spacing: 1px; position: sticky; top: 0; background: var(--panel); border-bottom: 1px solid var(--border); }
.panel-title { display: flex; align-items: center; justify-content: space-between; }
.mini-btn { background: #16202c; border: 1px solid var(--border); color: var(--accent);
border-radius: 5px; padding: 2px 8px; cursor: pointer; font-family: var(--mono); font-size: 11px;
letter-spacing: 0; text-transform: none; }
.mini-btn:hover { border-color: var(--accent); }
.upload { display: flex; flex-direction: column; gap: 7px; padding: 10px 12px;
border-bottom: 1px solid var(--border); background: var(--panel2); }
.upload input[type=file] { color: var(--dim); font-family: var(--mono); font-size: 11px; }
.upload input[type=file]::file-selector-button { background: #16202c; color: var(--fg);
border: 1px solid var(--border); border-radius: 5px; padding: 4px 8px; cursor: pointer;
font-family: var(--mono); margin-right: 8px; }
.upload .owner { width: auto; }
.upload .compare { margin-left: 0; }
.upload-msg { color: var(--dim); font-size: 11px; min-height: 14px; }
.upload-msg.err { color: var(--del); }
.jobs { padding: 6px 10px; }
.jobs:empty { padding: 0; }
.jobs-title { color: var(--dim); text-transform: uppercase; font-size: 11px; letter-spacing: 1px; padding: 2px 2px 4px; }
.job { display: flex; align-items: center; gap: 6px; padding: 4px 6px; margin: 2px 0;
border: 1px solid var(--border); border-radius: 6px; background: var(--panel2); font-size: 11px; }
.job .jname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job .jlink { color: var(--accent); cursor: pointer; }
.job .jlink:hover { text-decoration: underline; }
.job .jerr { color: var(--del); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 130px; }
.b-q { background: rgba(107,124,143,.18); color: var(--dim); }
.b-s { background: rgba(78,163,255,.16); color: var(--accent); }
.game { padding: 8px 10px 4px; }
.game-name { color: #eaf2fb; font-weight: 600; padding: 4px 4px; }
.snap { display: flex; align-items: center; gap: 6px; padding: 6px 8px; margin: 3px 0;
border: 1px solid var(--border); border-radius: 6px; background: var(--panel2); }
.snap:hover { border-color: var(--accent2); }
.snap .info { flex: 1; min-width: 0; cursor: pointer; }
.snap .bin { color: var(--fg); }
.snap .meta { color: var(--dim); font-size: 11px; }
.snap .pill { display: inline-block; padding: 0 5px; border-radius: 4px; background: #20303f; color: var(--dim); margin-left: 4px; }
.snap .ab { display: flex; gap: 4px; }
.snap .ab button { width: 24px; height: 24px; border: 1px solid var(--border); background: #16202c;
color: var(--dim); border-radius: 5px; cursor: pointer; font-family: var(--mono); }
.snap .ab button.on { background: var(--accent2); color: #fff; border-color: var(--accent); }
.main { display: flex; flex-direction: column; min-width: 0; }
.controls { display: flex; align-items: center; gap: 12px; padding: 10px 16px; flex-wrap: wrap;
border-bottom: 1px solid var(--border); background: var(--panel); }
.slots { color: var(--dim); }
.slot em { color: var(--accent); font-style: normal; }
.arrow { color: var(--dim); margin: 0 4px; }
.owner { background: #0c141d; border: 1px solid var(--border); color: var(--fg);
padding: 5px 8px; border-radius: 6px; font-family: var(--mono); width: 220px; }
.axes { display: flex; gap: 8px; color: var(--dim); }
.axes label { cursor: pointer; user-select: none; }
.compare { margin-left: auto; background: var(--accent2); color: #fff; border: 0;
padding: 7px 14px; border-radius: 6px; cursor: pointer; font-family: var(--mono); }
.compare:disabled { background: #223; color: #566; cursor: not-allowed; }
.results { padding: 16px; overflow-y: auto; }
.hint { color: var(--dim); text-align: center; margin-top: 60px; line-height: 1.8; }
.diff-head { color: var(--dim); margin-bottom: 14px; }
.diff-head b { color: var(--fg); }
.axis { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 14px; overflow: hidden; }
.axis > summary { list-style: none; cursor: pointer; padding: 9px 14px; background: var(--panel2);
display: flex; align-items: center; gap: 10px; }
.axis > summary::-webkit-details-marker { display: none; }
.axis .title { font-weight: 600; color: #eaf2fb; }
.badge { font-size: 11px; padding: 1px 7px; border-radius: 10px; }
.b-add { background: rgba(63,185,80,.15); color: var(--add); }
.b-del { background: rgba(248,81,73,.15); color: var(--del); }
.b-chg { background: rgba(210,153,34,.15); color: var(--chg); }
.axis .body { padding: 6px 14px 12px; }
.row { padding: 2px 0 2px 18px; position: relative; white-space: pre-wrap; word-break: break-word; }
.row::before { position: absolute; left: 0; font-weight: 700; }
.r-add::before { content: "+"; color: var(--add); }
.r-del::before { content: ""; color: var(--del); }
.r-chg::before { content: "~"; color: var(--chg); }
.r-del { color: var(--dim); }
.delta { color: var(--chg); }
.simpct { color: var(--accent); font-weight: 600; }
.axsum { margin-left: auto; color: var(--dim); font-size: 11px; }
.empty { color: var(--dim); font-style: italic; }
.moved { color: var(--accent); }
.similar { margin: 4px 0 16px; }
.similar-title { color: var(--dim); text-transform: uppercase; font-size: 11px; letter-spacing: 1px; margin-bottom: 6px; }
.simrow { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.simscore { width: 38px; text-align: right; color: var(--accent); font-weight: 600; }
.simbar { flex: 0 0 120px; height: 7px; background: #16202c; border: 1px solid var(--border);
border-radius: 4px; overflow: hidden; }
.simfill { display: block; height: 100%; background: linear-gradient(90deg, var(--accent2), var(--add)); }
.simname { flex: 1; min-width: 0; color: var(--fg); cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.simname:hover { color: var(--accent); text-decoration: underline; }
.simfuzzy { color: var(--dim); font-size: 11px; }
.simdiff { color: var(--accent); cursor: pointer; font-size: 11px; }
.simdiff:hover { text-decoration: underline; }
.browse-filter { margin-bottom: 10px; }
.btab { display: inline-block; padding: 4px 10px; margin-right: 6px; border: 1px solid var(--border);
border-radius: 6px; cursor: pointer; color: var(--dim); }
.btab.on { background: var(--accent2); color: #fff; border-color: var(--accent); }
.bitem { padding: 1px 0; }
.bitem .k { color: var(--dim); }
.err { color: var(--del); }