// Compare the wsids the user pasted (input order, deduped) against the wsids // in WORKSHOP_ITEMS_LINE (sort order). Always available - no "previous sort" // required. Surfaces drops (banned / missing mod.info / unknown / collection // IDs that expanded), additions (collection expansion, branch picks), and // position changes. function computeDiff(inputWsids, outputWsids) { if (!inputWsids || !outputWsids) return null; const inSet = new Set(inputWsids); const outSet = new Set(outputWsids); const added = outputWsids.filter(w => !inSet.has(w)); const removed = inputWsids.filter(w => !outSet.has(w)); const inPos = new Map(inputWsids.map((w, i) => [w, i])); const movers = []; outputWsids.forEach((w, oi) => { if (!inSet.has(w)) return; const ii = inPos.get(w); if (ii !== oi) movers.push({ wsid: w, from: ii, to: oi, delta: oi - ii }); }); movers.sort((a, b) => Math.abs(b.delta) - Math.abs(a.delta)); return { added, removed, movers }; } function DiffPanel({ inputWsids, outputWsids, onClose }) { const diff = computeDiff(inputWsids, outputWsids); if (!diff) { return (
diff: input → sorted
no input or output yet.
); } const { added, removed, movers } = diff; const empty = !added.length && !removed.length && !movers.length; return (
diff: input → sorted +{added.length} −{removed.length} ↕{movers.length}
{empty &&
order matches your input. nothing dropped or added.
} {added.length > 0 && (
added ({added.length}) - collection expansion or branch-picker
{added.slice(0, 30).map(w =>
+ {w}
)} {added.length > 30 &&
…and {added.length - 30} more
}
)} {removed.length > 0 && (
removed ({removed.length}) - dropped, banned, missing mod.info, or a collection ID that expanded
{removed.slice(0, 30).map(w =>
− {w}
)} {removed.length > 30 &&
…and {removed.length - 30} more
}
)} {movers.length > 0 && (
reordered by load order ({movers.length}, top {Math.min(10, movers.length)} shown)
{movers.slice(0, 10).map(({ wsid, from, to, delta }) => (
{delta < 0 ? '↑' : '↓'} {wsid} pos {from + 1} → {to + 1} ({delta > 0 ? '+' : ''}{delta})
))}
)}
); }