jzxiao commited on
Commit
3d62f04
·
verified ·
1 Parent(s): d70efe6

Align final operator implementations and 169-dataset catalog

Browse files
Files changed (11) hide show
  1. README.md +5 -3
  2. app.js +88 -18
  3. apply_dataset_scope.py +107 -0
  4. build_ui_payload.py +3 -1
  5. data.json +2 -2
  6. dataset-catalog.json +0 -0
  7. index.html +19 -7
  8. manifest.json +18 -54
  9. reference-catalog.json +0 -0
  10. style.css +4 -0
  11. ui-data.json +0 -0
README.md CHANGED
@@ -21,10 +21,11 @@ From the source project checkout, regenerate the snapshots with:
21
 
22
  ```bash
23
  python3 deploy/huggingface-compressionbenchmark/export_results.py
 
24
  python3 deploy/huggingface-compressionbenchmark/build_ui_payload.py
25
  ```
26
 
27
- Publish `README.md`, `index.html`, `style.css`, `app.js`, `ranking.js`, `reference-catalog.json`, `data.json`, `ui-data.json`, `manifest.json`, `export_results.py`, and `build_ui_payload.py` to the static Space. The manifest records the exact source-file identities and metric boundaries. The compact browser payload retains the full snapshot's measurements and SHA-256 identity. The reference catalog is an independent documentation payload and does not affect leaderboard measurements.
28
 
29
  Only measurements in the authoritative current project scope are exported. Missing metrics and missing coverage are displayed explicitly. Existing results do not imply independently verified round trips or uniform hardware environments unless those checks are recorded in the source.
30
 
@@ -34,10 +35,11 @@ Only measurements in the authoritative current project scope are exported. Missi
34
  - Sortable metrics, optional columns, and CSV download of the selected ranking
35
  - Compression rate versus encoding/decoding cost plots
36
  - Dataset-level method details, snapshot provenance, and metric definitions
 
37
  - Overall composite score and average dataset Rank, with 36 valid positive one-decimal weight combinations
38
- - Searchable Methods and Operators documentation with presentation-note references and external source links
39
 
40
- The default family view selects the best measured compression-rate configuration independently for each dataset. Switch to **Exact configuration** to hold a configuration fixed. Runtime results stay separate.
41
 
42
  The Overall score is `a × average rate + b × normalized average encode time + c × normalized average decode time`. Time normalization is linear min–max across all eligible rows in the selected runtime, scope and row mode; an equal-time range normalizes to zero. Search, family and coverage filters only hide rows and never change the reference. Average Rank averages per-dataset composite-score ranks with dataset-local time normalization and fractional ties. Missing results are omitted. Coverage and candidate counts can differ across datasets; method details expose dataset scores, ranks and candidate counts. CSV downloads include weights, normalization bounds and rank coverage. The default weights are `a=0.4, b=0.3, c=0.3`.
43
 
 
21
 
22
  ```bash
23
  python3 deploy/huggingface-compressionbenchmark/export_results.py
24
+ python3 deploy/huggingface-compressionbenchmark/apply_dataset_scope.py
25
  python3 deploy/huggingface-compressionbenchmark/build_ui_payload.py
26
  ```
27
 
28
+ Publish `README.md`, `index.html`, `style.css`, `app.js`, `ranking.js`, `reference-catalog.json`, `dataset-catalog.json`, `data.json`, `ui-data.json`, `manifest.json`, `export_results.py`, `apply_dataset_scope.py`, and `build_ui_payload.py` to the static Space. The manifest records the exact source-file identities and metric boundaries. The compact browser payload retains the full snapshot's measurements and SHA-256 identity. The reference and dataset catalogs are independent documentation payloads and do not create benchmark measurements.
29
 
30
  Only measurements in the authoritative current project scope are exported. Missing metrics and missing coverage are displayed explicitly. Existing results do not imply independently verified round trips or uniform hardware environments unless those checks are recorded in the source.
31
 
 
35
  - Sortable metrics, optional columns, and CSV download of the selected ranking
36
  - Compression rate versus encoding/decoding cost plots
37
  - Dataset-level method details, snapshot provenance, and metric definitions
38
+ - Searchable 169-dataset catalog grouped into six source categories, with explicit measurement availability and source links
39
  - Overall composite score and average dataset Rank, with 36 valid positive one-decimal weight combinations
40
+ - Searchable Methods documentation and a 30-family operator catalog with 102 implementation-directory entries, references, I/O contracts, examples, and status
41
 
42
+ The dataset catalog and the measured benchmark scope are separate. All 169 catalog entries are searchable and selectable, while only datasets with published measurements participate in the leaderboard; pending entries show **No published measurements** and are never converted to zero-valued results. The default family view selects the best measured compression-rate configuration independently for each measured dataset. Switch to **Exact configuration** to hold a configuration fixed. Runtime results stay separate.
43
 
44
  The Overall score is `a × average rate + b × normalized average encode time + c × normalized average decode time`. Time normalization is linear min–max across all eligible rows in the selected runtime, scope and row mode; an equal-time range normalizes to zero. Search, family and coverage filters only hide rows and never change the reference. Average Rank averages per-dataset composite-score ranks with dataset-local time normalization and fractional ties. Missing results are omitted. Coverage and candidate counts can differ across datasets; method details expose dataset scores, ranks and candidate counts. CSV downloads include weights, normalization bounds and rank coverage. The default weights are `a=0.4, b=0.3, c=0.3`.
45
 
app.js CHANGED
@@ -1,4 +1,4 @@
1
- import {WEIGHT_TENTHS,parseWeights,addRankingMetrics} from './ranking.js?v=20261008-rank-v1';
2
  const $ = (id) => document.getElementById(id);
3
  const escape = (value) => String(value ?? '').replace(/[&<>"']/g, (c) => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
4
  const number = (v) => v != null && Number.isFinite(Number(v)) ? Number(v) : null;
@@ -20,7 +20,7 @@ const cols = [
20
  {key:'original_bytes',label:'Original bytes',digits:0,visible:false},
21
  ];
22
  let snapshot, records=[], methods=new Map(), datasets=new Map(), currentRows=[], activeTab='overall';
23
- let referenceCatalog=null,referenceCatalogError=null;
24
  let sort={key:'compression_rate',direction:1};
25
  let selectedMethod=null;
26
  const state = () => ({runtime:$('runtime').value,dataset:$('dataset').value,dtype:$('dtype').value,precision:$('precision').value,family:$('family').value,mode:$('row-mode').value,search:$('search').value.trim().toLowerCase(),complete:$('complete-only').checked});
@@ -72,7 +72,10 @@ function renderTable() {
72
  function refresh() {
73
  if(!snapshot)return;
74
  $('precision').disabled=$('dtype').value!=='float';
75
- if(scopeKey()==='float'&&!records.some(r=>r.scope==='float')) {
 
 
 
76
  // The exporter must publish an explicit all-float scope; never combine
77
  // preaggregated fixed/non-fixed metrics and call it an all-float result.
78
  $('results-note').textContent='All-float measurements are not available in this snapshot. Select a precision category.';
@@ -83,10 +86,10 @@ function refresh() {
83
  $('audit-notice').textContent=audit?'DBP measurement audit: '+audit.timing+' '+audit.storage+' Float end-to-end losslessness is not established. See method details.':'';
84
  const weights=parseWeights($('weights').value);
85
  $('score-note').textContent=`Score = ${weights[0].toFixed(1)} × average rate + ${weights[1].toFixed(1)} × normalized encode + ${weights[2].toFixed(1)} × normalized decode. Lower is better. Time normalization: (time − minimum) / (maximum − minimum), across all measured rows in this runtime, scope and row mode. Search and visibility filters keep the reference fixed. Average Rank: mean of per-dataset score ranks with dataset-local time normalization; ties share their average position. Missing results are omitted. Dataset candidate counts differ, so compare rank coverage and inspect method details.`;
86
- const s=state(),scope=scopeKey(),ds=s.dataset==='all'?'all measured datasets':s.dataset;
87
  const names={overall:'all numeric columns',integer:'integer columns',float:'floating-point columns',fixed_float:'fixed-precision float columns',nonfixed_float:'non-fixed-precision float columns'};
88
  $('selection-summary').textContent=`${runtimeName(s.runtime)} · ${names[scope]||scope} · ${ds} · ${currentRows.length} methods`;
89
- $('view-title').textContent=activeTab==='dataset'?`${s.dataset==='all'?'Dataset':s.dataset} leaderboard`:activeTab==='tradeoffs'?'Storage and execution trade-offs':'Overall leaderboard';
90
  renderTable();
91
  if(activeTab==='tradeoffs')renderChart();
92
  if(selectedMethod)showMethod(selectedMethod,false);
@@ -94,12 +97,13 @@ function refresh() {
94
  function setTab(tab) {
95
  activeTab=['overall','dataset','tradeoffs','methods','operators','about'].includes(tab)?tab:'overall';
96
  for(const b of document.querySelectorAll('[data-tab]')){b.classList.toggle('active',b.dataset.tab===activeTab);if(b.dataset.tab===activeTab)b.setAttribute('aria-current','page');else b.removeAttribute('aria-current');}
97
- $('results-view').hidden=['methods','operators','about'].includes(activeTab);$('methods-view').hidden=activeTab!=='methods';$('operators-view').hidden=activeTab!=='operators';$('about-view').hidden=activeTab!=='about';$('chart-view').hidden=activeTab!=='tradeoffs';
98
  $('score-controls').hidden=activeTab!=='overall';
99
  for(const input of $('column-options').querySelectorAll('input'))input.parentElement.hidden=Boolean(cols.find(c=>c.key===input.dataset.column)?.overallOnly&&activeTab!=='overall');
100
  if(activeTab!=='overall'&&cols.find(c=>c.key===sort.key)?.overallOnly)sort={key:'compression_rate',direction:1};
101
  if(activeTab==='dataset'&&$('dataset').value==='all'){const first=[...datasets.keys()].find(k=>records.some(r=>r.dataset===k&&r.runtime===$('runtime').value));if(first)$('dataset').value=first;}
102
  if(activeTab==='overall')$('dataset').value='all';
 
103
  refresh();
104
  }
105
  function showMethod(method,focus=false) {
@@ -139,8 +143,9 @@ function safeHttpUrl(value) {
139
  }
140
  function publicNote(value) {
141
  const note=typeof value==='string'?value.trim():'';
142
- return /(?:\/Users\/|[A-Za-z]:\\|file:\/\/|\.pptx\b)/i.test(note)?'':note;
143
  }
 
144
  function referenceMap() {
145
  return new Map((referenceCatalog?.references||[]).map(reference=>[String(reference.id),reference]));
146
  }
@@ -183,16 +188,36 @@ function renderOperatorDocumentation() {
183
  if(referenceCatalogError){status.textContent='Operator documentation could not be loaded.';container.innerHTML=`<p class="documentation-error">${escape(referenceCatalogError.message)}</p>`;return;}
184
  if(!referenceCatalog){status.textContent='Loading operator documentation…';container.innerHTML='';return;}
185
  const query=$('operator-doc-search').value.trim().toLowerCase(),all=referenceCatalog.operators||[];
186
- const visible=all.filter(operator=>!query||[operator.id,operator.name,operator.group,operator.description,referenceSearchText(operator.reference_ids)].join(' ').toLowerCase().includes(query));
187
  const groups=new Map();
188
- for(const operator of visible){const group=operator.group||'Other';if(!groups.has(group))groups.set(group,[]);groups.get(group).push(operator);}
189
- status.textContent=`${visible.length} of ${all.length} operators shown`;
190
- container.innerHTML=visible.length?[...groups].sort((a,b)=>a[0].localeCompare(b[0])).map(([group,operators])=>`<section class="operator-group"><h3>${escape(group)}</h3><div class="documentation-grid">${operators.sort((a,b)=>String(a.name).localeCompare(String(b.name))).map(operator=>`<article class="documentation-card operator-card"><div class="documentation-card-head"><div><h4>${escape(operator.name||operator.id)}</h4>${operator.id&&operator.id!==operator.name?`<span class="documentation-code">${escape(operator.id)}</span>`:''}</div></div><p class="documentation-description">${escape(operator.description||'Description not available.')}</p>${renderReferences(operator.reference_ids)}</article>`).join('')}</div></section>`).join(''):'<p class="documentation-empty">No operator documentation matches this search.</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  }
192
  function renderDocumentationViews() { renderMethodDocumentation();renderOperatorDocumentation(); }
193
  async function loadReferenceCatalog() {
194
  try {
195
- const response=await fetch('./reference-catalog.json?v=20261008-docs-v1',{cache:'no-cache'});
196
  if(!response.ok)throw new Error(`Reference catalog request returned ${response.status}.`);
197
  const catalog=await response.json();
198
  if(!catalog||!Array.isArray(catalog.methods)||!Array.isArray(catalog.operators)||!Array.isArray(catalog.references))throw new Error('Reference catalog has an invalid schema.');
@@ -200,6 +225,49 @@ async function loadReferenceCatalog() {
200
  } catch(error) { referenceCatalogError=error instanceof Error?error:new Error('Reference catalog is unavailable.'); }
201
  if(snapshot)renderDocumentationViews();
202
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  function renderAbout() {
204
  const b=snapshot.benchmark||{},s=snapshot.source||{},c=snapshot.coverage||{};
205
  const notes=[b.scope_note,b.aggregation_note,b.selection_note,...(b.notes||[]),...(b.measurement_boundaries||[])].filter(Boolean);
@@ -207,7 +275,8 @@ function renderAbout() {
207
  for(const [method,audit] of Object.entries(b.method_audits||{}))$('methodology').innerHTML+=`<div class="notice"><strong>${escape(method)} measurement audit · ${escape(audit.audited_at)}</strong>${[audit.implementation,audit.timing,audit.storage,audit.roundtrip,audit.comparison].map(n=>`<p>${escape(n)}</p>`).join('')}</div>`;
208
  const definitions=b.metric_definitions||{};if(Object.keys(definitions).length)$('methodology').innerHTML+=`<dl class="definitions">${Object.entries(definitions).map(([k,v])=>`<div><dt>${escape(k.replaceAll('_',' '))}</dt><dd>${escape(typeof v==='string'?v:JSON.stringify(v))}</dd></div>`).join('')}</dl>`;
209
  const exclusions=c.exclusions||c.excluded_datasets||snapshot.exclusions||[];
210
- const info={ 'Snapshot exported':snapshot.exported_at||s.exported_at||'Not reported','Dataset scope generated':s.generated_at||'Not reported', 'Source checkout':s.git_commit||'Not reported','Source files':`${s.source_files?.length??0} metadata inputs and ${s.result_csv_files_used?.length??0} result CSVs (hashes in manifest)`,'Result entries across scopes':`${records.length} (scope slices can reuse a measurement)`,'Worktree source state':s.worktree_dirty_inputs?.length?'Includes current local changes; input file hashes identify the published snapshot.':'See manifest for source file hashes.','Runtime environment':b.hardware||'Hardware details are not recorded in this exported result snapshot.','Lossless evidence':b.roundtrip_evidence||'Lossless-design method filter from the source project; per-run round-trip verification is not recorded here.'};
 
211
  $('provenance').innerHTML=`<table class="provenance-table"><tbody>${Object.entries(info).map(([k,v])=>`<tr><th>${escape(k)}</th><td class="source-code">${escape(v)}</td></tr>`).join('')}</tbody></table>${exclusions.length?`<h3>Excluded or unavailable results</h3><p class="source-code">${escape(typeof exclusions==='string'?exclusions:JSON.stringify(exclusions))}</p>`:''}`;
212
  }
213
  function init() {
@@ -218,9 +287,9 @@ function init() {
218
  for(const r of records)if(!methods.has(r.method))methods.set(r.method,{name:r.method,family:r.family});
219
  const runtimes=[...new Set(records.map(r=>r.runtime))].sort((a,b)=>['cpp','java','python'].indexOf(a)-['cpp','java','python'].indexOf(b));
220
  $('runtime').innerHTML=runtimes.map(r=>`<option value="${escape(r)}">${escape(runtimeName(r))}</option>`).join('');
221
- $('dataset').innerHTML='<option value="all">All measured datasets</option>'+[...datasets.values()].sort((a,b)=>(a.key??a.dataset).localeCompare(b.key??b.dataset)).map(d=>`<option value="${escape(d.key??d.dataset)}">${escape(d.key??d.dataset)}</option>`).join('');
222
  $('family').innerHTML='<option value="all">All method families</option>'+[...new Set(records.map(r=>r.family))].sort().map(f=>`<option value="${escape(f)}">${escape(f)}</option>`).join('');
223
- $('dataset-count').textContent=countFmt(new Set(records.map(r=>r.dataset)).size);$('method-count').textContent=countFmt(new Set(records.map(r=>r.family)).size);$('runtime-count').textContent=runtimes.length;$('record-count').textContent=countFmt(snapshot.coverage?.runtime_configuration_count??new Set(records.map(r=>`${r.runtime}\0${r.method}`)).size);
224
  const exported=snapshot.exported_at||snapshot.source?.exported_at||'not reported';$('snapshot').textContent=`Result snapshot exported · ${String(exported).replace('T',' ').slice(0,19)}${exported==='not reported'?'':' UTC'}`;$('footer-snapshot').textContent=`Source inputs documented in the manifest`;
225
  $('column-options').innerHTML=cols.map(c=>`<label><input type="checkbox" data-column="${c.key}" ${c.visible?'checked':''}>${escape(c.label)}</label>`).join('');
226
  $('weights').innerHTML=WEIGHT_TENTHS.map(w=>`<option value="${w.join(',')}" ${w.join(',')==='4,3,3'?'selected':''}>a = ${(w[0]/10).toFixed(1)} · b = ${(w[1]/10).toFixed(1)} · c = ${(w[2]/10).toFixed(1)}</option>`).join('');
@@ -229,8 +298,8 @@ function init() {
229
  for(const id of ['runtime','dtype','precision','dataset','family','row-mode','complete-only'])$(id).addEventListener('change',refresh);$('search').addEventListener('input',refresh);$('chart-metric').addEventListener('change',renderChart);$('download').addEventListener('click',csv);
230
  $('reset').addEventListener('click',()=>{$('runtime').value=runtimes.includes('cpp')?'cpp':runtimes[0];$('dtype').value='overall';$('precision').value='all';$('dataset').value='all';$('row-mode').value='family';$('search').value='';$('family').value='all';$('weights').value='4,3,3';$('complete-only').checked=false;selectedMethod=null;$('method-detail').hidden=true;sort={key:'compression_rate',direction:1};setTab(activeTab);});
231
  for(const tab of document.querySelectorAll('[data-tab]'))tab.addEventListener('click',()=>{history.replaceState(null,'',`#${tab.dataset.tab}`);setTab(tab.dataset.tab);});
232
- $('method-doc-search').addEventListener('input',renderMethodDocumentation);$('operator-doc-search').addEventListener('input',renderOperatorDocumentation);
233
- renderAbout();renderDocumentationViews();setTab(location.hash.slice(1)||'overall');
234
  document.documentElement.dataset.ready='true';
235
  }
236
  function setupTheme() {
@@ -242,5 +311,6 @@ function setupTheme() {
242
  }
243
  setupTheme();
244
  void loadReferenceCatalog();
245
- try { const response=await fetch('./ui-data.json?v=20261008-rank-v1',{cache:'no-cache'});if(!response.ok)throw new Error(`Snapshot request returned ${response.status}`);snapshot=await response.json();init(); }
 
246
  catch(e){$('load-error').hidden=false;$('load-error').textContent=`The result snapshot could not be loaded. Please reload the page or download the JSON from the repository. ${e.message}`;$('snapshot').textContent='Snapshot unavailable';$('leaderboard').querySelector('tbody').innerHTML='<tr><td class="empty-cell">Results unavailable.</td></tr>';}
 
1
+ import {WEIGHT_TENTHS,parseWeights,addRankingMetrics} from './ranking.js?v=20261008-scope169-v1';
2
  const $ = (id) => document.getElementById(id);
3
  const escape = (value) => String(value ?? '').replace(/[&<>"']/g, (c) => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
4
  const number = (v) => v != null && Number.isFinite(Number(v)) ? Number(v) : null;
 
20
  {key:'original_bytes',label:'Original bytes',digits:0,visible:false},
21
  ];
22
  let snapshot, records=[], methods=new Map(), datasets=new Map(), currentRows=[], activeTab='overall';
23
+ let referenceCatalog=null,referenceCatalogError=null,datasetCatalog=null,datasetCatalogError=null;
24
  let sort={key:'compression_rate',direction:1};
25
  let selectedMethod=null;
26
  const state = () => ({runtime:$('runtime').value,dataset:$('dataset').value,dtype:$('dtype').value,precision:$('precision').value,family:$('family').value,mode:$('row-mode').value,search:$('search').value.trim().toLowerCase(),complete:$('complete-only').checked});
 
72
  function refresh() {
73
  if(!snapshot)return;
74
  $('precision').disabled=$('dtype').value!=='float';
75
+ const selectedDataset=state().dataset,selectedHasMeasurements=selectedDataset==='all'||records.some(r=>r.dataset===selectedDataset);
76
+ if(!selectedHasMeasurements) {
77
+ $('results-note').textContent='No published measurements are available for this catalog dataset. It is excluded from rankings rather than treated as zero.';
78
+ } else if(scopeKey()==='float'&&!records.some(r=>r.scope==='float')) {
79
  // The exporter must publish an explicit all-float scope; never combine
80
  // preaggregated fixed/non-fixed metrics and call it an all-float result.
81
  $('results-note').textContent='All-float measurements are not available in this snapshot. Select a precision category.';
 
86
  $('audit-notice').textContent=audit?'DBP measurement audit: '+audit.timing+' '+audit.storage+' Float end-to-end losslessness is not established. See method details.':'';
87
  const weights=parseWeights($('weights').value);
88
  $('score-note').textContent=`Score = ${weights[0].toFixed(1)} × average rate + ${weights[1].toFixed(1)} × normalized encode + ${weights[2].toFixed(1)} × normalized decode. Lower is better. Time normalization: (time − minimum) / (maximum − minimum), across all measured rows in this runtime, scope and row mode. Search and visibility filters keep the reference fixed. Average Rank: mean of per-dataset score ranks with dataset-local time normalization; ties share their average position. Missing results are omitted. Dataset candidate counts differ, so compare rank coverage and inspect method details.`;
89
+ const s=state(),scope=scopeKey(),measuredCount=new Set(records.map(r=>r.dataset)).size,ds=s.dataset==='all'?`all ${measuredCount} measured datasets`:datasetDisplayName(s.dataset);
90
  const names={overall:'all numeric columns',integer:'integer columns',float:'floating-point columns',fixed_float:'fixed-precision float columns',nonfixed_float:'non-fixed-precision float columns'};
91
  $('selection-summary').textContent=`${runtimeName(s.runtime)} · ${names[scope]||scope} · ${ds} · ${currentRows.length} methods`;
92
+ $('view-title').textContent=activeTab==='dataset'?`${s.dataset==='all'?'Dataset':datasetDisplayName(s.dataset)} leaderboard`:activeTab==='tradeoffs'?'Storage and execution trade-offs':'Overall leaderboard';
93
  renderTable();
94
  if(activeTab==='tradeoffs')renderChart();
95
  if(selectedMethod)showMethod(selectedMethod,false);
 
97
  function setTab(tab) {
98
  activeTab=['overall','dataset','tradeoffs','methods','operators','about'].includes(tab)?tab:'overall';
99
  for(const b of document.querySelectorAll('[data-tab]')){b.classList.toggle('active',b.dataset.tab===activeTab);if(b.dataset.tab===activeTab)b.setAttribute('aria-current','page');else b.removeAttribute('aria-current');}
100
+ $('results-view').hidden=['methods','operators','about'].includes(activeTab);$('methods-view').hidden=activeTab!=='methods';$('operators-view').hidden=activeTab!=='operators';$('about-view').hidden=activeTab!=='about';$('chart-view').hidden=activeTab!=='tradeoffs';$('dataset-catalog-panel').hidden=activeTab!=='dataset';
101
  $('score-controls').hidden=activeTab!=='overall';
102
  for(const input of $('column-options').querySelectorAll('input'))input.parentElement.hidden=Boolean(cols.find(c=>c.key===input.dataset.column)?.overallOnly&&activeTab!=='overall');
103
  if(activeTab!=='overall'&&cols.find(c=>c.key===sort.key)?.overallOnly)sort={key:'compression_rate',direction:1};
104
  if(activeTab==='dataset'&&$('dataset').value==='all'){const first=[...datasets.keys()].find(k=>records.some(r=>r.dataset===k&&r.runtime===$('runtime').value));if(first)$('dataset').value=first;}
105
  if(activeTab==='overall')$('dataset').value='all';
106
+ if(activeTab==='dataset')renderDatasetCatalog();
107
  refresh();
108
  }
109
  function showMethod(method,focus=false) {
 
143
  }
144
  function publicNote(value) {
145
  const note=typeof value==='string'?value.trim():'';
146
+ return /(?:\/Users\/|[A-Za-z]:\\|file:\/\/|codex:\/\/threads\/|\.pptx\b)/i.test(note)?'':note;
147
  }
148
+ function publicText(value,fallback='') { const text=publicNote(value);return text||fallback; }
149
  function referenceMap() {
150
  return new Map((referenceCatalog?.references||[]).map(reference=>[String(reference.id),reference]));
151
  }
 
188
  if(referenceCatalogError){status.textContent='Operator documentation could not be loaded.';container.innerHTML=`<p class="documentation-error">${escape(referenceCatalogError.message)}</p>`;return;}
189
  if(!referenceCatalog){status.textContent='Loading operator documentation…';container.innerHTML='';return;}
190
  const query=$('operator-doc-search').value.trim().toLowerCase(),all=referenceCatalog.operators||[];
191
+ const rows=all.map(operator=>{const implementations=Array.isArray(operator.implementations)?operator.implementations:[];const familySearch=[operator.id,operator.name,operator.name_en,operator.name_zh,operator.group,operator.description,referenceSearchText(operator.reference_ids)].join(' ').toLowerCase();const matchingImplementations=query&&!familySearch.includes(query)?implementations.filter(entry=>operatorImplementationSearch(entry).includes(query)):implementations;return {operator,implementations:matchingImplementations,familyMatch:!query||familySearch.includes(query)};}).filter(row=>row.familyMatch||row.implementations.length);
192
  const groups=new Map();
193
+ for(const row of rows){const group=row.operator.group||'Other';if(!groups.has(group))groups.set(group,[]);groups.get(group).push(row);}
194
+ const shownEntries=new Set(rows.flatMap(row=>row.implementations.map(entry=>entry.id||`${row.operator.id}:${entry.name||entry.name_en||''}`))).size,totalEntries=new Set(all.flatMap(operator=>(operator.implementations||[]).map(entry=>entry.id||`${operator.id}:${entry.name||entry.name_en||''}`))).size;
195
+ status.textContent=`${rows.length} of ${all.length} operator families shown · ${shownEntries} of ${totalEntries} directory entries shown`;
196
+ renderOperatorSummary();
197
+ container.innerHTML=rows.length?[...groups].map(([group,groupRows])=>`<section class="operator-group"><h3>${escape(publicText(group,'Other'))}</h3><div class="documentation-grid">${groupRows.map(({operator,implementations})=>renderOperatorCard(operator,implementations)).join('')}</div></section>`).join(''):'<p class="documentation-empty">No operator family or implementation entry matches this search.</p>';
198
+ }
199
+ function operatorImplementationSearch(entry) {
200
+ return [entry.id,entry.name,entry.name_en,entry.name_zh,entry.layer,entry.description,entry.inputs,entry.outputs,entry.example,entry.status,referenceSearchText(entry.reference_ids)].join(' ').toLowerCase();
201
+ }
202
+ function renderOperatorSummary() {
203
+ const target=$('operator-summary');if(!target||!referenceCatalog)return;
204
+ const summary=referenceCatalog.operator_summary||{},families=number(summary.family_count??summary.operator_family_count)??(referenceCatalog.operators||[]).length;
205
+ const entries=number(summary.entry_count??summary.directory_entry_count??summary.implementation_count)??(referenceCatalog.operators||[]).reduce((sum,item)=>sum+(item.implementations?.length||0),0);
206
+ const parts=[['Families',families],['Directory entries',entries],['Mechanisms',summary.mechanism_count],['Configurations',summary.configuration_count],['Compositions',summary.composition_count],['Adapters',summary.adapter_count]];
207
+ target.innerHTML=parts.filter(([,value])=>number(value)!==null).map(([label,value])=>`<div><strong>${countFmt(value)}</strong><span>${escape(label)}</span></div>`).join('');
208
+ }
209
+ function renderOperatorCard(operator,implementations) {
210
+ const allEntries=Array.isArray(operator.implementations)?operator.implementations:[],name=publicText(operator.name_en??operator.name,operator.id||'Operator family'),nativeName=publicText(operator.name_zh),description=publicText(operator.description,'Description not available.');
211
+ return `<article class="documentation-card operator-card"><div class="documentation-card-head"><div><h4>${escape(name)}</h4>${nativeName&&nativeName!==name?`<span class="documentation-native-name">${escape(nativeName)}</span>`:''}${operator.id&&operator.id!==name?`<span class="documentation-code">${escape(publicText(operator.id))}</span>`:''}</div><span class="documentation-count">${implementations.length}${implementations.length!==allEntries.length?` / ${allEntries.length}`:''} entries</span></div><p class="documentation-description">${escape(description)}</p>${renderReferences(operator.reference_ids)}${implementations.length?`<details class="implementation-details"><summary>Implementation directory (${implementations.length}${implementations.length!==allEntries.length?` matching of ${allEntries.length}`:''})</summary><div class="implementation-list">${implementations.map(renderOperatorImplementation).join('')}</div></details>`:'<p class="reference-empty">No implementation entry matches this search.</p>'}</article>`;
212
+ }
213
+ function renderOperatorImplementation(entry) {
214
+ const name=publicText(entry.name_en??entry.name,entry.id||'Implementation entry'),nativeName=publicText(entry.name_zh),layer=publicText(entry.layer,'entry'),fields=[['Principle',entry.description],['Input',entry.inputs],['Output',entry.outputs],['Example',entry.example],['Status',entry.status]].filter(([,value])=>publicText(value));
215
+ return `<article class="implementation-entry"><div class="implementation-head"><div><strong>${escape(name)}</strong>${nativeName&&nativeName!==name?`<span class="documentation-native-name">${escape(nativeName)}</span>`:''}${entry.id?`<span class="documentation-code">${escape(publicText(entry.id))}</span>`:''}</div><span class="implementation-layer">${escape(layer)}</span></div>${fields.length?`<dl>${fields.map(([label,value])=>`<div><dt>${escape(label)}</dt><dd>${escape(publicText(value))}</dd></div>`).join('')}</dl>`:''}${entry.reference_ids?.length?renderReferences(entry.reference_ids):''}</article>`;
216
  }
217
  function renderDocumentationViews() { renderMethodDocumentation();renderOperatorDocumentation(); }
218
  async function loadReferenceCatalog() {
219
  try {
220
+ const response=await fetch('./reference-catalog.json?v=20261008-scope169-v1',{cache:'no-cache'});
221
  if(!response.ok)throw new Error(`Reference catalog request returned ${response.status}.`);
222
  const catalog=await response.json();
223
  if(!catalog||!Array.isArray(catalog.methods)||!Array.isArray(catalog.operators)||!Array.isArray(catalog.references))throw new Error('Reference catalog has an invalid schema.');
 
225
  } catch(error) { referenceCatalogError=error instanceof Error?error:new Error('Reference catalog is unavailable.'); }
226
  if(snapshot)renderDocumentationViews();
227
  }
228
+ function datasetKey(entry) { return String(entry?.key??entry?.dataset??''); }
229
+ function datasetDisplayName(key) { const entry=datasets.get(key);return entry?.label&&entry.label!==key?`${entry.label} (${key})`:key; }
230
+ function datasetEntries() {
231
+ const source=Array.isArray(datasetCatalog?.datasets)&&datasetCatalog.datasets.length?datasetCatalog.datasets:[...(snapshot?.datasets||[])];
232
+ const unique=new Map();for(const entry of source){const key=datasetKey(entry);if(key)unique.set(key,entry);}return [...unique.values()];
233
+ }
234
+ function datasetCategory(entry) { return String(entry.category_label??entry.category??'Other'); }
235
+ function datasetSearchText(entry) { return [datasetKey(entry),entry.label,entry.category,entry.category_label,entry.source].join(' ').toLowerCase(); }
236
+ function humanBytes(value) { const amount=number(value);if(amount===null)return '';const units=['B','KB','MB','GB','TB'];let scaled=amount,index=0;while(scaled>=1000&&index<units.length-1){scaled/=1000;index++;}return `${scaled.toLocaleString('en-US',{maximumFractionDigits:index?1:0})} ${units[index]}`; }
237
+ function populateDatasetControls() {
238
+ if(!snapshot)return;
239
+ const entries=datasetEntries(),selected=$('dataset').value||'all',measured=new Set(records.map(record=>record.dataset)),groups=new Map();
240
+ for(const entry of entries){const group=datasetCategory(entry);if(!groups.has(group))groups.set(group,[]);groups.get(group).push(entry);datasets.set(datasetKey(entry),entry);}
241
+ $('dataset').innerHTML='<option value="all">All measured datasets</option>'+[...groups].map(([group,items])=>`<optgroup label="${escape(group)}">${items.sort((a,b)=>datasetKey(a).localeCompare(datasetKey(b))).map(entry=>{const key=datasetKey(entry),label=entry.label&&entry.label!==key?`${entry.label} (${key})`:key;return `<option value="${escape(key)}">${escape(label)}${measured.has(key)?'':' · No published measurements'}</option>`;}).join('')}</optgroup>`).join('');
242
+ $('dataset').value=[...$('dataset').options].some(option=>option.value===selected)?selected:'all';
243
+ const groupSelect=$('dataset-group-filter'),previousGroup=groupSelect.value||'all',categories=[...groups.keys()];
244
+ groupSelect.innerHTML='<option value="all">All groups</option>'+categories.map(group=>`<option value="${escape(group)}">${escape(group)} (${groups.get(group).length})</option>`).join('');
245
+ groupSelect.value=categories.includes(previousGroup)?previousGroup:'all';
246
+ const catalogCount=number(datasetCatalog?.summary?.dataset_count??snapshot.coverage?.catalog_dataset_count)??entries.length,measuredCount=number(datasetCatalog?.summary?.published_result_dataset_count??datasetCatalog?.summary?.published_measurement_dataset_count??datasetCatalog?.summary?.measured_dataset_count??snapshot.coverage?.measured_dataset_count)??measured.size;
247
+ $('dataset-count').textContent=countFmt(catalogCount);$('dataset-count-label').textContent=`datasets in catalog · ${countFmt(measuredCount)} measured`;
248
+ }
249
+ function renderDatasetCatalog() {
250
+ const container=$('dataset-catalog'),status=$('dataset-catalog-status');if(!container||!status||!snapshot)return;
251
+ const all=datasetEntries(),query=$('dataset-catalog-search').value.trim().toLowerCase(),group=$('dataset-group-filter').value,measured=new Set(records.map(record=>record.dataset));
252
+ const visible=all.filter(entry=>(group==='all'||datasetCategory(entry)===group)&&(!query||datasetSearchText(entry).includes(query))),groups=new Map();
253
+ for(const entry of visible){const category=datasetCategory(entry);if(!groups.has(category))groups.set(category,[]);groups.get(category).push(entry);}
254
+ const measuredVisible=visible.filter(entry=>measured.has(datasetKey(entry))).length;
255
+ status.textContent=`${visible.length} of ${all.length} datasets shown · ${measuredVisible} shown entries have published measurements · rankings use ${measured.size} measured datasets`;
256
+ if(datasetCatalogError&&!all.length){container.innerHTML=`<p class="documentation-error">${escape(datasetCatalogError.message)}</p>`;return;}
257
+ container.innerHTML=visible.length?[...groups].map(([category,entries])=>`<section class="dataset-category"><h3>${escape(category)} <span>${entries.length}</span></h3><div class="dataset-list">${entries.sort((a,b)=>datasetKey(a).localeCompare(datasetKey(b))).map(entry=>renderDatasetEntry(entry,measured.has(datasetKey(entry)))).join('')}</div></section>`).join(''):'<p class="documentation-empty">No dataset matches this search and group filter.</p>';
258
+ for(const button of container.querySelectorAll('[data-dataset-key]'))button.addEventListener('click',()=>{$('dataset').value=button.dataset.datasetKey;refresh();renderDatasetCatalog();$('leaderboard-wrap').scrollIntoView({block:'nearest'});});
259
+ }
260
+ function renderDatasetEntry(entry,isMeasured) {
261
+ const key=datasetKey(entry),label=publicText(entry.label,key),rows=number(entry.row_count),payload=humanBytes(entry.size_bytes),metadata=[rows===0?'Empty dataset':rows!==null?`${countFmt(rows)} rows`:'',number(entry.column_count)!==null?`${countFmt(entry.column_count)} columns`:'',number(entry.numeric_column_count)!==null?`${countFmt(entry.numeric_column_count)} numeric`:'',payload?`${payload} numeric payload`:'' ].filter(Boolean),sourceUrl=safeHttpUrl(entry.source_url),datasetUrl=safeHttpUrl(entry.dataset_url),source=publicText(entry.source,'Source'),snapshotDiff=entry.published_result_row_count_matches_catalog===false;
262
+ return `<article class="dataset-entry ${isMeasured?'measured':'pending'} ${state().dataset===key?'selected':''}"><button type="button" data-dataset-key="${escape(key)}"><span><strong>${escape(label)}</strong>${label!==key?`<small>${escape(key)}</small>`:''}</span><span class="dataset-state">${isMeasured?'Measured':'No published measurements'}</span></button>${metadata.length?`<p>${metadata.map(escape).join(' · ')}</p>`:''}${snapshotDiff?'<p class="dataset-snapshot-note">Published measurements use an earlier prepared snapshot.</p>':''}<div class="dataset-links">${sourceUrl?`<a href="${escape(sourceUrl)}" target="_blank" rel="noopener noreferrer">${escape(source)} ↗</a>`:entry.source?`<span class="dataset-source">${escape(source)}</span>`:''}${datasetUrl&&datasetUrl!==sourceUrl?`<a href="${escape(datasetUrl)}" target="_blank" rel="noopener noreferrer">Dataset files ↗</a>`:''}</div></article>`;
263
+ }
264
+ async function loadDatasetCatalog() {
265
+ try {
266
+ const response=await fetch('./dataset-catalog.json?v=20261008-scope169-v1',{cache:'no-cache'});if(!response.ok)throw new Error(`Dataset catalog request returned ${response.status}.`);
267
+ const catalog=await response.json();if(!catalog||!Array.isArray(catalog.datasets)||!catalog.summary)throw new Error('Dataset catalog has an invalid schema.');datasetCatalog=catalog;
268
+ } catch(error) { datasetCatalogError=error instanceof Error?error:new Error('Dataset catalog is unavailable.'); }
269
+ if(snapshot){populateDatasetControls();renderDatasetCatalog();renderAbout();}
270
+ }
271
  function renderAbout() {
272
  const b=snapshot.benchmark||{},s=snapshot.source||{},c=snapshot.coverage||{};
273
  const notes=[b.scope_note,b.aggregation_note,b.selection_note,...(b.notes||[]),...(b.measurement_boundaries||[])].filter(Boolean);
 
275
  for(const [method,audit] of Object.entries(b.method_audits||{}))$('methodology').innerHTML+=`<div class="notice"><strong>${escape(method)} measurement audit · ${escape(audit.audited_at)}</strong>${[audit.implementation,audit.timing,audit.storage,audit.roundtrip,audit.comparison].map(n=>`<p>${escape(n)}</p>`).join('')}</div>`;
276
  const definitions=b.metric_definitions||{};if(Object.keys(definitions).length)$('methodology').innerHTML+=`<dl class="definitions">${Object.entries(definitions).map(([k,v])=>`<div><dt>${escape(k.replaceAll('_',' '))}</dt><dd>${escape(typeof v==='string'?v:JSON.stringify(v))}</dd></div>`).join('')}</dl>`;
277
  const exclusions=c.exclusions||c.excluded_datasets||snapshot.exclusions||[];
278
+ const catalogCount=number(datasetCatalog?.summary?.dataset_count??c.catalog_dataset_count)??datasetEntries().length,measuredCount=number(datasetCatalog?.summary?.published_result_dataset_count??datasetCatalog?.summary?.published_measurement_dataset_count??datasetCatalog?.summary?.measured_dataset_count??c.measured_dataset_count)??new Set(records.map(r=>r.dataset)).size;
279
+ const info={ 'Snapshot exported':snapshot.exported_at||s.exported_at||'Not reported','Dataset catalog':`${catalogCount} datasets; ${measuredCount} currently have published measurements and participate in rankings`,'Dataset scope generated':s.generated_at||'Not reported', 'Source checkout':s.git_commit||'Not reported','Source files':`${s.source_files?.length??0} metadata inputs and ${s.result_csv_files_used?.length??0} result CSVs (hashes in manifest)`,'Result entries across scopes':`${records.length} (scope slices can reuse a measurement)`,'Worktree source state':s.worktree_dirty_inputs?.length?'Includes current local changes; input file hashes identify the published snapshot.':'See manifest for source file hashes.','Runtime environment':b.hardware||'Hardware details are not recorded in this exported result snapshot.','Lossless evidence':b.roundtrip_evidence||'Lossless-design method filter from the source project; per-run round-trip verification is not recorded here.'};
280
  $('provenance').innerHTML=`<table class="provenance-table"><tbody>${Object.entries(info).map(([k,v])=>`<tr><th>${escape(k)}</th><td class="source-code">${escape(v)}</td></tr>`).join('')}</tbody></table>${exclusions.length?`<h3>Excluded or unavailable results</h3><p class="source-code">${escape(typeof exclusions==='string'?exclusions:JSON.stringify(exclusions))}</p>`:''}`;
281
  }
282
  function init() {
 
287
  for(const r of records)if(!methods.has(r.method))methods.set(r.method,{name:r.method,family:r.family});
288
  const runtimes=[...new Set(records.map(r=>r.runtime))].sort((a,b)=>['cpp','java','python'].indexOf(a)-['cpp','java','python'].indexOf(b));
289
  $('runtime').innerHTML=runtimes.map(r=>`<option value="${escape(r)}">${escape(runtimeName(r))}</option>`).join('');
290
+ populateDatasetControls();
291
  $('family').innerHTML='<option value="all">All method families</option>'+[...new Set(records.map(r=>r.family))].sort().map(f=>`<option value="${escape(f)}">${escape(f)}</option>`).join('');
292
+ $('method-count').textContent=countFmt(new Set(records.map(r=>r.family)).size);$('runtime-count').textContent=runtimes.length;$('record-count').textContent=countFmt(snapshot.coverage?.runtime_configuration_count??new Set(records.map(r=>`${r.runtime}\0${r.method}`)).size);
293
  const exported=snapshot.exported_at||snapshot.source?.exported_at||'not reported';$('snapshot').textContent=`Result snapshot exported · ${String(exported).replace('T',' ').slice(0,19)}${exported==='not reported'?'':' UTC'}`;$('footer-snapshot').textContent=`Source inputs documented in the manifest`;
294
  $('column-options').innerHTML=cols.map(c=>`<label><input type="checkbox" data-column="${c.key}" ${c.visible?'checked':''}>${escape(c.label)}</label>`).join('');
295
  $('weights').innerHTML=WEIGHT_TENTHS.map(w=>`<option value="${w.join(',')}" ${w.join(',')==='4,3,3'?'selected':''}>a = ${(w[0]/10).toFixed(1)} · b = ${(w[1]/10).toFixed(1)} · c = ${(w[2]/10).toFixed(1)}</option>`).join('');
 
298
  for(const id of ['runtime','dtype','precision','dataset','family','row-mode','complete-only'])$(id).addEventListener('change',refresh);$('search').addEventListener('input',refresh);$('chart-metric').addEventListener('change',renderChart);$('download').addEventListener('click',csv);
299
  $('reset').addEventListener('click',()=>{$('runtime').value=runtimes.includes('cpp')?'cpp':runtimes[0];$('dtype').value='overall';$('precision').value='all';$('dataset').value='all';$('row-mode').value='family';$('search').value='';$('family').value='all';$('weights').value='4,3,3';$('complete-only').checked=false;selectedMethod=null;$('method-detail').hidden=true;sort={key:'compression_rate',direction:1};setTab(activeTab);});
300
  for(const tab of document.querySelectorAll('[data-tab]'))tab.addEventListener('click',()=>{history.replaceState(null,'',`#${tab.dataset.tab}`);setTab(tab.dataset.tab);});
301
+ $('method-doc-search').addEventListener('input',renderMethodDocumentation);$('operator-doc-search').addEventListener('input',renderOperatorDocumentation);$('dataset-catalog-search').addEventListener('input',renderDatasetCatalog);$('dataset-group-filter').addEventListener('change',renderDatasetCatalog);
302
+ renderAbout();renderDocumentationViews();renderDatasetCatalog();setTab(location.hash.slice(1)||'overall');
303
  document.documentElement.dataset.ready='true';
304
  }
305
  function setupTheme() {
 
311
  }
312
  setupTheme();
313
  void loadReferenceCatalog();
314
+ void loadDatasetCatalog();
315
+ try { const response=await fetch('./ui-data.json?v=20261008-scope169-v1',{cache:'no-cache'});if(!response.ok)throw new Error(`Snapshot request returned ${response.status}`);snapshot=await response.json();init(); }
316
  catch(e){$('load-error').hidden=false;$('load-error').textContent=`The result snapshot could not be loaded. Please reload the page or download the JSON from the repository. ${e.message}`;$('snapshot').textContent='Snapshot unavailable';$('leaderboard').querySelector('tbody').innerHTML='<tr><td class="empty-cell">Results unavailable.</td></tr>';}
apply_dataset_scope.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Apply the public dataset catalog to an existing measured snapshot.
2
+
3
+ This is a scope filter, not a benchmark runner: retained individual measurements
4
+ are copied unchanged, excluded measurements are removed, and aggregates are
5
+ recomputed. Catalog-only datasets receive no fabricated measurement rows.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from collections import defaultdict
10
+ import datetime
11
+ import hashlib
12
+ import json
13
+ from pathlib import Path
14
+
15
+ from export_results import _aggregate_rows
16
+
17
+ ROOT = Path(__file__).resolve().parent
18
+
19
+
20
+ def sha(path: Path) -> str:
21
+ return hashlib.sha256(path.read_bytes()).hexdigest()
22
+
23
+
24
+ def apply() -> None:
25
+ catalog_path = ROOT / "dataset-catalog.json"
26
+ catalog = json.loads(catalog_path.read_text())
27
+ data_path = ROOT / "data.json"
28
+ data = json.loads(data_path.read_text())
29
+ allowed = {d["key"] for d in catalog["datasets"]}
30
+ if len(allowed) != 169 or len(catalog["datasets"]) != 169:
31
+ raise ValueError("The reviewed public catalog must contain 169 unique datasets")
32
+ excluded = {d["key"] for d in catalog.get("excluded", [])}
33
+ if allowed & excluded:
34
+ raise ValueError("Excluded datasets are present in the public catalog")
35
+ old_rows = data["dataset_results"]
36
+ rows = [r for r in old_rows if r["dataset"] in allowed]
37
+ if not rows:
38
+ raise ValueError("The snapshot has no measurements in the reviewed scope")
39
+ measured = {r["dataset"] for r in rows}
40
+ old_sha = sha(data_path)
41
+ data["dataset_results"] = rows
42
+ data["datasets"] = [{**d, "has_published_measurements": d["key"] in measured}
43
+ for d in catalog["datasets"]]
44
+ configurations = defaultdict(list)
45
+ families = defaultdict(list)
46
+ for original in rows:
47
+ r = dict(original)
48
+ # Preserve the exporter's 8-byte-equivalent denominator, including
49
+ # historical rows whose source byte totals are not divisible by eight.
50
+ r["point_count"] = r["original_size_bytes"] / 8.0
51
+ r["compression_time_ns"] = r["compression_time_ns_per_point"] * r["point_count"]
52
+ r["decompression_time_ns"] = r["decompression_time_ns_per_point"] * r["point_count"]
53
+ configurations[r["runtime"], r["scope"], r["family"], r["method"]].append(r)
54
+ if r["is_best_rate_in_family"]:
55
+ families[r["runtime"], r["scope"], r["family"]].append(r)
56
+ data["configuration_aggregates"] = [
57
+ _aggregate_rows(rs, runtime=rt, scope_key=sc, family=fa, method=me, algorithm_variant=me)
58
+ for (rt, sc, fa, me), rs in sorted(configurations.items())]
59
+ data["family_best_aggregates"] = [
60
+ _aggregate_rows(rs, runtime=rt, scope_key=sc, family=fa, method=fa, algorithm_variant=None)
61
+ for (rt, sc, fa), rs in sorted(families.items())]
62
+ method_keys = {(r["method"], r["family"]) for r in rows}
63
+ data["methods"] = [m for m in data["methods"] if (m["name"], m["family"]) in method_keys]
64
+ data["report_availability"] = [r for r in data["report_availability"] if r["dataset"] in allowed]
65
+ # Retire the unrelated older paper aggregation instead of presenting it as
66
+ # evidence for the new catalog scope.
67
+ data.pop("paper_table3", None)
68
+ data["dataset_overview"] = {
69
+ "dataset_count": 169, "measured_dataset_count": len(measured),
70
+ "total_rows": sum(d.get("row_count") or 0 for d in catalog["datasets"]),
71
+ "total_rows_available_dataset_count": sum(d.get("row_count") is not None for d in catalog["datasets"]),
72
+ "provenance_note": "Dataset catalog statistics follow the reviewed 169-dataset scope. Compression metrics use only published measurement rows."}
73
+ benchmark = data["benchmark"]
74
+ benchmark.pop("paper_result_selection", None)
75
+ benchmark["metric_definitions"] = {k: v for k, v in benchmark["metric_definitions"].items() if not k.startswith("paper_")}
76
+ for field in ("notes", "measurement_boundaries"):
77
+ benchmark[field] = [s for s in benchmark.get(field, []) if "paper" not in s.lower()]
78
+ benchmark["scope_note"] = f"The dataset catalog contains 169 reviewed datasets (18 legacy + 151 THULab). Published measurement rows currently cover {len(measured)} of them. Catalog inclusion does not imply completed experiments or full-column coverage."
79
+ benchmark["publication_note"] = "The new Native86 evaluation is a separate, incomplete experiment. Its partial outputs are not mixed with this published multi-runtime snapshot."
80
+ source = data["source"]
81
+ source["source_files"] = [s for s in source["source_files"] if s.get("role") not in ("paper_table3", "dataset_scope", "dataset_catalog")]
82
+ source["source_files"].append({"role": "reviewed_dataset_catalog", "path": "dataset-catalog.json", "sha256": sha(catalog_path), "status": "reviewed_public_catalog"})
83
+ source["result_csv_files_used"] = [s for s in source["result_csv_files_used"] if len(Path(s["path"]).parts) >= 3 and Path(s["path"]).parts[2] in allowed]
84
+ source["scope_applied_at"] = datetime.datetime.now(datetime.timezone.utc).isoformat()
85
+ source.setdefault("scope_input_snapshot_sha256", old_sha)
86
+ source["scope_catalog_sha256"] = sha(catalog_path)
87
+ coverage = data["coverage"]
88
+ coverage.update(dataset_count=169, catalog_dataset_count=169, measured_dataset_count=len(measured),
89
+ dataset_result_row_count=len(rows), configuration_aggregate_row_count=len(data["configuration_aggregates"]),
90
+ family_best_aggregate_row_count=len(data["family_best_aggregates"]),
91
+ method_family_count=len({r["family"] for r in rows}), method_configuration_count=len({r["method"] for r in rows}),
92
+ runtime_configuration_count=len({(r["runtime"], r["method"]) for r in rows}),
93
+ source_report_file_count=len(source["result_csv_files_used"]), paper_leaderboard_row_count=0,
94
+ excluded_datasets=sorted(excluded | set(coverage.get("excluded_datasets", []))))
95
+ data["dataset_summary"] = {**catalog["summary"], "published_measurement_dataset_count": len(measured)}
96
+ data_path.write_text(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, allow_nan=False) + "\n")
97
+ manifest_path = ROOT / "manifest.json"
98
+ manifest = json.loads(manifest_path.read_text())
99
+ manifest.update(counts=coverage, data_sha256=sha(data_path), source_files=source["source_files"],
100
+ result_csv_files=source["result_csv_files_used"], dataset_catalog_sha256=sha(catalog_path))
101
+ manifest_path.write_text(json.dumps(manifest, ensure_ascii=False, indent=2, sort_keys=True) + "\n")
102
+ print(json.dumps({"catalog_datasets": 169, "measured_datasets": len(measured), "retained_rows": len(rows),
103
+ "removed_rows": len(old_rows) - len(rows), "data_sha256": sha(data_path)}))
104
+
105
+
106
+ if __name__ == "__main__":
107
+ apply()
build_ui_payload.py CHANGED
@@ -21,7 +21,9 @@ def build() -> None:
21
  r['compression_rate'], r['compression_time_ns_per_point'],
22
  r['decompression_time_ns_per_point'], r['original_size_bytes'],
23
  r['compressed_size_bytes']])
24
- payload = {key: data[key] for key in ('schema_version','benchmark','coverage','datasets','methods','scopes','source','paper_table3')}
 
 
25
  payload['exported_at'] = datetime.datetime.now(datetime.timezone.utc).isoformat()
26
  payload['source_data_sha256'] = hashlib.sha256(source.read_bytes()).hexdigest()
27
  payload['record_tables'] = tables
 
21
  r['compression_rate'], r['compression_time_ns_per_point'],
22
  r['decompression_time_ns_per_point'], r['original_size_bytes'],
23
  r['compressed_size_bytes']])
24
+ payload = {key: data[key] for key in ('schema_version','benchmark','coverage','datasets','methods','scopes','source')}
25
+ if 'dataset_summary' in data:
26
+ payload['dataset_summary'] = data['dataset_summary']
27
  payload['exported_at'] = datetime.datetime.now(datetime.timezone.utc).isoformat()
28
  payload['source_data_sha256'] = hashlib.sha256(source.read_bytes()).hexdigest()
29
  payload['record_tables'] = tables
data.json CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:47ddcf459b1eedd8b1dcf89d07ee544e10b527e6da24c64f81de18628b324454
3
- size 28048937
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7618054cc2699fd855f673bfd41f7f5b94ee466028043bc669e457ead1984f63
3
+ size 34661683
dataset-catalog.json ADDED
The diff for this file is too large to render. See raw diff
 
index.html CHANGED
@@ -6,8 +6,8 @@
6
  <meta name="description" content="THULab time-series compression benchmark: measured compression rates, encoding and decoding costs, and dataset coverage.">
7
  <meta name="color-scheme" content="light dark">
8
  <title>THULab | Time Series Compression Benchmark</title>
9
- <link rel="stylesheet" href="style.css?v=20261008-docs-v1">
10
- <script src="app.js?v=20261008-docs-v1" type="module"></script>
11
  </head>
12
  <body>
13
  <a class="skip-link" href="#content">Skip to results</a>
@@ -19,11 +19,11 @@
19
  <section class="intro" aria-labelledby="title">
20
  <p class="eyebrow">Time-series systems research</p>
21
  <h1 id="title">Time Series Compression Leaderboard</h1>
22
- <p class="intro-text">Compare measured storage, encoding, and decoding costs across real time-series datasets.</p>
23
  <p class="snapshot" id="snapshot">Loading benchmark snapshot…</p>
24
  </section>
25
  <div class="summary-strip" id="summary" aria-label="Snapshot coverage">
26
- <div><strong id="dataset-count">…</strong><span>datasets with results</span></div>
27
  <div><strong id="method-count">…</strong><span>method families</span></div>
28
  <div><strong id="runtime-count">…</strong><span>implementation runtimes</span></div>
29
  <div><strong id="record-count">…</strong><span>runtime / codec configurations</span></div>
@@ -38,6 +38,17 @@
38
  </nav>
39
  <div id="load-error" class="error-message" role="alert" hidden></div>
40
  <section id="results-view" aria-label="Compression results">
 
 
 
 
 
 
 
 
 
 
 
41
  <div class="filters" id="filters">
42
  <label>Runtime<select id="runtime"></select></label>
43
  <label>Data type<select id="dtype"><option value="overall">All numeric</option><option value="int">Integer</option><option value="float">Floating point</option></select></label>
@@ -82,10 +93,11 @@
82
  </section>
83
  <section id="operators-view" class="text-view documentation-view" hidden>
84
  <div class="documentation-head">
85
- <div><h2>Operators</h2><p class="muted">Reusable transforms and coding primitives that appear across time-series compression methods.</p></div>
86
- <label class="documentation-search">Search operators<input id="operator-doc-search" type="search" placeholder="Name, group, description, or reference" autocomplete="off"></label>
87
  </div>
88
- <p class="reference-source">References from the presentation Notes (slides 2–3). External links open in a new tab.</p>
 
89
  <p id="operator-doc-status" class="documentation-status" aria-live="polite">Loading operator documentation…</p>
90
  <div id="operator-catalog" class="operator-groups"></div>
91
  </section>
 
6
  <meta name="description" content="THULab time-series compression benchmark: measured compression rates, encoding and decoding costs, and dataset coverage.">
7
  <meta name="color-scheme" content="light dark">
8
  <title>THULab | Time Series Compression Benchmark</title>
9
+ <link rel="stylesheet" href="style.css?v=20261008-scope169-v1">
10
+ <script src="app.js?v=20261008-scope169-v1" type="module"></script>
11
  </head>
12
  <body>
13
  <a class="skip-link" href="#content">Skip to results</a>
 
19
  <section class="intro" aria-labelledby="title">
20
  <p class="eyebrow">Time-series systems research</p>
21
  <h1 id="title">Time Series Compression Leaderboard</h1>
22
+ <p class="intro-text">Browse the 169-dataset catalog and compare published storage, encoding, and decoding measurements.</p>
23
  <p class="snapshot" id="snapshot">Loading benchmark snapshot…</p>
24
  </section>
25
  <div class="summary-strip" id="summary" aria-label="Snapshot coverage">
26
+ <div><strong id="dataset-count">…</strong><span id="dataset-count-label">datasets in catalog</span></div>
27
  <div><strong id="method-count">…</strong><span>method families</span></div>
28
  <div><strong id="runtime-count">…</strong><span>implementation runtimes</span></div>
29
  <div><strong id="record-count">…</strong><span>runtime / codec configurations</span></div>
 
38
  </nav>
39
  <div id="load-error" class="error-message" role="alert" hidden></div>
40
  <section id="results-view" aria-label="Compression results">
41
+ <section id="dataset-catalog-panel" class="dataset-catalog-panel" aria-labelledby="dataset-catalog-title" hidden>
42
+ <div class="dataset-catalog-head">
43
+ <div><h2 id="dataset-catalog-title">Dataset catalog</h2><p class="muted">Browse all cataloged datasets. Entries without published measurements remain visible but are excluded from rankings.</p></div>
44
+ <div class="dataset-catalog-controls">
45
+ <label>Dataset group<select id="dataset-group-filter"><option value="all">All groups</option></select></label>
46
+ <label>Search datasets<input id="dataset-catalog-search" type="search" placeholder="Name, category, or source" autocomplete="off"></label>
47
+ </div>
48
+ </div>
49
+ <p id="dataset-catalog-status" class="documentation-status" aria-live="polite">Loading dataset catalog…</p>
50
+ <div id="dataset-catalog" class="dataset-catalog"></div>
51
+ </section>
52
  <div class="filters" id="filters">
53
  <label>Runtime<select id="runtime"></select></label>
54
  <label>Data type<select id="dtype"><option value="overall">All numeric</option><option value="int">Integer</option><option value="float">Floating point</option></select></label>
 
93
  </section>
94
  <section id="operators-view" class="text-view documentation-view" hidden>
95
  <div class="documentation-head">
96
+ <div><h2>Operators</h2><p class="muted">Thirty operator families organize a 102-entry implementation directory. Directory entries include mechanisms, configurations, compositions, and adapters; they are not 102 distinct atomic operators.</p></div>
97
+ <label class="documentation-search">Search operators<input id="operator-doc-search" type="search" placeholder="Family, A-ID, implementation, I/O, or reference" autocomplete="off"></label>
98
  </div>
99
+ <div id="operator-summary" class="operator-summary" aria-label="Operator catalog summary"></div>
100
+ <p class="reference-source">The family split follows the final operator registry; references include the presentation Notes and official implementation sources. STOP, Concat, and continuous Split are control or graph operations and are excluded from the 30-family count. Split (columnize) remains family 29. External links open in a new tab.</p>
101
  <p id="operator-doc-status" class="documentation-status" aria-live="polite">Loading operator documentation…</p>
102
  <div id="operator-catalog" class="operator-groups"></div>
103
  </section>
manifest.json CHANGED
@@ -1,17 +1,22 @@
1
  {
2
  "counts": {
 
3
  "configuration_aggregate_row_count": 4653,
4
- "dataset_count": 19,
5
- "dataset_result_row_count": 67200,
6
  "excluded_datasets": [
7
- "poisson_timestamps"
 
 
 
8
  ],
9
  "family_best_aggregate_row_count": 1383,
 
10
  "method_configuration_count": 311,
11
  "method_family_count": 93,
12
  "missing_measurement_policy": "Missing report and dataset/scope/runtime/configuration combinations are omitted; the UI must display them as unavailable, never as zero.",
13
  "missing_source_report_count": 0,
14
- "paper_leaderboard_row_count": 80,
15
  "runtime_configuration_count": 931,
16
  "runtime_count": 3,
17
  "runtimes": [
@@ -20,10 +25,11 @@
20
  "python"
21
  ],
22
  "scope_count": 5,
23
- "source_report_file_count": 114
24
  },
25
  "data_file": "data.json",
26
- "data_sha256": "47ddcf459b1eedd8b1dcf89d07ee544e10b527e6da24c64f81de18628b324454",
 
27
  "excluded_content": [
28
  "raw datasets",
29
  "user uploads",
@@ -63,36 +69,6 @@
63
  "sha256": "904c9c0253c10953b6cbfa73a13440bfc3024d02e41a3e43ea1f7ae5bfd6b196",
64
  "size_bytes": 119582
65
  },
66
- {
67
- "path": "backend/dataset/Arade/Arade_float_cpp_compression_result.csv",
68
- "sha256": "79f2c8905a794fde576f216de22ae0abf6f1eff9ca91e05bc738b0637f44a6c7",
69
- "size_bytes": 71234
70
- },
71
- {
72
- "path": "backend/dataset/Arade/Arade_float_java_compression_result.csv",
73
- "sha256": "dcab3fcf3bd332c951c5f64c23407be20e6f57ac6dc600c2496fa6787f874999",
74
- "size_bytes": 72638
75
- },
76
- {
77
- "path": "backend/dataset/Arade/Arade_float_python_compression_result.csv",
78
- "sha256": "03681d3372fbf73ea66c09cdace5c31ea255e5d1387377a85999224cde60446a",
79
- "size_bytes": 13884
80
- },
81
- {
82
- "path": "backend/dataset/Arade/Arade_int_cpp_compression_result.csv",
83
- "sha256": "93e718edce0a6800cdb68bb33c512dcae657be9b3a5d35e2a02c8e655a38a1cd",
84
- "size_bytes": 35581
85
- },
86
- {
87
- "path": "backend/dataset/Arade/Arade_int_java_compression_result.csv",
88
- "sha256": "3bffb83c23d2865f7776657327274a1f67ddeb3c194df5bc1004e7d4ad2eca38",
89
- "size_bytes": 36864
90
- },
91
- {
92
- "path": "backend/dataset/Arade/Arade_int_python_compression_result.csv",
93
- "sha256": "2aa8734913bbb9ca28de8465f1ed201a39068ad7134bed1e54606cb8b7a38ad7",
94
- "size_bytes": 32329
95
- },
96
  {
97
  "path": "backend/dataset/Bar-Crawl/Bar-Crawl_float_cpp_compression_result.csv",
98
  "sha256": "736ffdaaac2a5863546262128c58cb1b63062e4bcff2094d54114a32e72bf5dd",
@@ -606,29 +582,17 @@
606
  ],
607
  "schema_version": 1,
608
  "source_files": [
609
- {
610
- "path": "backend/myapp/paper_table3_snapshot.json",
611
- "role": "paper_table3",
612
- "sha256": "cfe4316a0e4cd9109f749ce7f8e0e4e66da9fbba4558dd4a92663a5bb632c66c",
613
- "status": "tracked_clean"
614
- },
615
- {
616
- "path": "benchmark/reference/datasets/ledger_public_compress_summary.json",
617
- "role": "dataset_scope",
618
- "sha256": "f3b6927bfe31eb2c7914ed7f7c247760ad9ad06692be8e0a2bb5c54b172bef61",
619
- "status": "tracked_modified"
620
- },
621
- {
622
- "path": "backend/dataset_result/catalog_public_items.json",
623
- "role": "dataset_catalog",
624
- "sha256": "01d818203612f3c96beaf0bd39fa5b6e895f6055f7bc8329c1e1635d5669a94d",
625
- "status": "generated_or_ignored"
626
- },
627
  {
628
  "path": "benchmark/reference/methods/method_operator_pipelines.json",
629
  "role": "method_pipelines",
630
  "sha256": "dd2bce587b2a2d4169a8e5b005b665cd4ca67af525334c46ad314363bf3987fe",
631
  "status": "tracked_modified"
 
 
 
 
 
 
632
  }
633
  ]
634
  }
 
1
  {
2
  "counts": {
3
+ "catalog_dataset_count": 169,
4
  "configuration_aggregate_row_count": 4653,
5
+ "dataset_count": 169,
6
+ "dataset_result_row_count": 63906,
7
  "excluded_datasets": [
8
+ "Arade",
9
+ "poisson_timestamps",
10
+ "supply_chain_customer",
11
+ "supply_chain_location"
12
  ],
13
  "family_best_aggregate_row_count": 1383,
14
+ "measured_dataset_count": 18,
15
  "method_configuration_count": 311,
16
  "method_family_count": 93,
17
  "missing_measurement_policy": "Missing report and dataset/scope/runtime/configuration combinations are omitted; the UI must display them as unavailable, never as zero.",
18
  "missing_source_report_count": 0,
19
+ "paper_leaderboard_row_count": 0,
20
  "runtime_configuration_count": 931,
21
  "runtime_count": 3,
22
  "runtimes": [
 
25
  "python"
26
  ],
27
  "scope_count": 5,
28
+ "source_report_file_count": 108
29
  },
30
  "data_file": "data.json",
31
+ "data_sha256": "7618054cc2699fd855f673bfd41f7f5b94ee466028043bc669e457ead1984f63",
32
+ "dataset_catalog_sha256": "a5930a8a0cd52cfbd15c176e8384184fbbdb8778b67ee8e3fe923d5c00cfac82",
33
  "excluded_content": [
34
  "raw datasets",
35
  "user uploads",
 
69
  "sha256": "904c9c0253c10953b6cbfa73a13440bfc3024d02e41a3e43ea1f7ae5bfd6b196",
70
  "size_bytes": 119582
71
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  {
73
  "path": "backend/dataset/Bar-Crawl/Bar-Crawl_float_cpp_compression_result.csv",
74
  "sha256": "736ffdaaac2a5863546262128c58cb1b63062e4bcff2094d54114a32e72bf5dd",
 
582
  ],
583
  "schema_version": 1,
584
  "source_files": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
585
  {
586
  "path": "benchmark/reference/methods/method_operator_pipelines.json",
587
  "role": "method_pipelines",
588
  "sha256": "dd2bce587b2a2d4169a8e5b005b665cd4ca67af525334c46ad314363bf3987fe",
589
  "status": "tracked_modified"
590
+ },
591
+ {
592
+ "path": "dataset-catalog.json",
593
+ "role": "reviewed_dataset_catalog",
594
+ "sha256": "a5930a8a0cd52cfbd15c176e8384184fbbdb8778b67ee8e3fe923d5c00cfac82",
595
+ "status": "reviewed_public_catalog"
596
  }
597
  ]
598
  }
reference-catalog.json CHANGED
The diff for this file is too large to render. See raw diff
 
style.css CHANGED
@@ -10,3 +10,7 @@
10
  .score-controls{display:flex;align-items:start;gap:20px;padding:12px 14px;margin:6px 0 12px;border:1px solid var(--line);border-radius:var(--radius);background:var(--soft)}.score-controls label{min-width:320px}.score-controls p{font-size:11px;line-height:1.7;margin:0;max-width:90ch}.score-controls select{height:35px}@media(max-width:768px){.score-controls{flex-direction:column;gap:10px}.score-controls label{min-width:0;width:100%}}
11
  .audit-badge{display:block;color:var(--muted);font-size:10px;margin-top:4px}.audit-notice{font-size:12px;padding:10px 14px;margin:8px 0;border-left:3px solid var(--accent);background:var(--accent-soft);color:var(--text)}
12
  .documentation-view{max-width:1180px}.documentation-head{display:flex;justify-content:space-between;align-items:end;gap:28px;margin-bottom:10px}.documentation-head>div{min-width:0}.documentation-search{width:min(390px,42%);flex:0 0 auto}.reference-source{margin:8px 0 4px;color:var(--muted);font-size:12px}.documentation-status{margin:14px 0;color:var(--muted);font-size:12px}.documentation-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.documentation-card{min-width:0;padding:18px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius)}.documentation-card h3,.documentation-card h4{margin:0;color:var(--text);line-height:1.35}.documentation-card h4{font-size:16px}.documentation-card-head{display:flex;justify-content:space-between;align-items:start;gap:16px}.documentation-code{display:block;margin-top:3px;color:var(--muted);font:11px "SFMono-Regular",Consolas,monospace;overflow-wrap:anywhere}.documentation-count{flex:0 0 auto;padding:3px 7px;border-radius:4px;background:var(--soft);color:var(--muted);font-size:10px}.documentation-description{margin:12px 0;color:var(--text);font-size:13px;line-height:1.65}.documentation-note{margin:10px 0;padding:9px 11px;border-left:2px solid var(--line);color:var(--muted);font-size:12px}.documentation-references{margin-top:12px;font-size:12px}.documentation-references>strong{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}.documentation-references ul{list-style:none;padding:0;margin:6px 0 0}.documentation-references li{padding:5px 0;border-top:1px solid var(--line);overflow-wrap:anywhere}.documentation-references small{display:block;margin-top:1px;color:var(--muted);font-size:10px}.reference-empty{margin:12px 0 0;color:var(--muted);font-size:11px}.configuration-details{margin-top:13px;border-top:1px solid var(--line);padding-top:10px}.configuration-details summary{cursor:pointer;color:var(--accent);font-size:12px;font-weight:600}.configuration-details ul{display:flex;flex-wrap:wrap;gap:6px;list-style:none;padding:10px 0 0;margin:0}.configuration-details li{max-width:100%;padding:4px 7px;border-radius:4px;background:var(--soft);font:10px "SFMono-Regular",Consolas,monospace;overflow-wrap:anywhere}.operator-group{margin-top:24px}.operator-group>h3{margin:0 0 10px;padding-bottom:8px;border-bottom:1px solid var(--line)}.operator-card{padding:16px}.documentation-error,.documentation-empty{grid-column:1/-1;margin:0;padding:22px;border:1px solid var(--line);border-radius:var(--radius);color:var(--muted);background:var(--surface)}.documentation-error{border-left:3px solid #b34938;color:var(--text)}@media(max-width:768px){.documentation-head{align-items:stretch;flex-direction:column;gap:14px}.documentation-search{width:100%}.documentation-grid{grid-template-columns:1fr}.documentation-card{padding:15px}.documentation-card-head{gap:10px}}
 
 
 
 
 
10
  .score-controls{display:flex;align-items:start;gap:20px;padding:12px 14px;margin:6px 0 12px;border:1px solid var(--line);border-radius:var(--radius);background:var(--soft)}.score-controls label{min-width:320px}.score-controls p{font-size:11px;line-height:1.7;margin:0;max-width:90ch}.score-controls select{height:35px}@media(max-width:768px){.score-controls{flex-direction:column;gap:10px}.score-controls label{min-width:0;width:100%}}
11
  .audit-badge{display:block;color:var(--muted);font-size:10px;margin-top:4px}.audit-notice{font-size:12px;padding:10px 14px;margin:8px 0;border-left:3px solid var(--accent);background:var(--accent-soft);color:var(--text)}
12
  .documentation-view{max-width:1180px}.documentation-head{display:flex;justify-content:space-between;align-items:end;gap:28px;margin-bottom:10px}.documentation-head>div{min-width:0}.documentation-search{width:min(390px,42%);flex:0 0 auto}.reference-source{margin:8px 0 4px;color:var(--muted);font-size:12px}.documentation-status{margin:14px 0;color:var(--muted);font-size:12px}.documentation-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.documentation-card{min-width:0;padding:18px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius)}.documentation-card h3,.documentation-card h4{margin:0;color:var(--text);line-height:1.35}.documentation-card h4{font-size:16px}.documentation-card-head{display:flex;justify-content:space-between;align-items:start;gap:16px}.documentation-code{display:block;margin-top:3px;color:var(--muted);font:11px "SFMono-Regular",Consolas,monospace;overflow-wrap:anywhere}.documentation-count{flex:0 0 auto;padding:3px 7px;border-radius:4px;background:var(--soft);color:var(--muted);font-size:10px}.documentation-description{margin:12px 0;color:var(--text);font-size:13px;line-height:1.65}.documentation-note{margin:10px 0;padding:9px 11px;border-left:2px solid var(--line);color:var(--muted);font-size:12px}.documentation-references{margin-top:12px;font-size:12px}.documentation-references>strong{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}.documentation-references ul{list-style:none;padding:0;margin:6px 0 0}.documentation-references li{padding:5px 0;border-top:1px solid var(--line);overflow-wrap:anywhere}.documentation-references small{display:block;margin-top:1px;color:var(--muted);font-size:10px}.reference-empty{margin:12px 0 0;color:var(--muted);font-size:11px}.configuration-details{margin-top:13px;border-top:1px solid var(--line);padding-top:10px}.configuration-details summary{cursor:pointer;color:var(--accent);font-size:12px;font-weight:600}.configuration-details ul{display:flex;flex-wrap:wrap;gap:6px;list-style:none;padding:10px 0 0;margin:0}.configuration-details li{max-width:100%;padding:4px 7px;border-radius:4px;background:var(--soft);font:10px "SFMono-Regular",Consolas,monospace;overflow-wrap:anywhere}.operator-group{margin-top:24px}.operator-group>h3{margin:0 0 10px;padding-bottom:8px;border-bottom:1px solid var(--line)}.operator-card{padding:16px}.documentation-error,.documentation-empty{grid-column:1/-1;margin:0;padding:22px;border:1px solid var(--line);border-radius:var(--radius);color:var(--muted);background:var(--surface)}.documentation-error{border-left:3px solid #b34938;color:var(--text)}@media(max-width:768px){.documentation-head{align-items:stretch;flex-direction:column;gap:14px}.documentation-search{width:100%}.documentation-grid{grid-template-columns:1fr}.documentation-card{padding:15px}.documentation-card-head{gap:10px}}
13
+ .operator-summary{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:1px;margin:16px 0;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}.operator-summary>div{padding:12px;background:var(--surface);text-align:center}.operator-summary strong{display:block;font-size:20px;line-height:1.2;font-variant-numeric:tabular-nums}.operator-summary span{display:block;margin-top:4px;color:var(--muted);font-size:10px}.documentation-native-name{display:block;margin-top:2px;color:var(--muted);font-size:11px}.implementation-details{margin-top:14px;padding-top:11px;border-top:1px solid var(--line)}.implementation-details>summary{cursor:pointer;color:var(--accent);font-size:12px;font-weight:650}.implementation-list{display:grid;gap:9px;margin-top:11px}.implementation-entry{padding:12px;border:1px solid var(--line);border-radius:6px;background:var(--soft)}.implementation-head{display:flex;align-items:start;justify-content:space-between;gap:12px}.implementation-head strong{font-size:12px}.implementation-layer{flex:0 0 auto;padding:2px 6px;border:1px solid var(--line);border-radius:999px;color:var(--muted);font-size:9px;text-transform:uppercase;letter-spacing:.05em}.implementation-entry dl{display:grid;gap:6px;margin:10px 0 0}.implementation-entry dl>div{display:grid;grid-template-columns:62px minmax(0,1fr);gap:8px}.implementation-entry dt{color:var(--muted);font-size:10px;font-weight:650;text-transform:uppercase;letter-spacing:.04em}.implementation-entry dd{margin:0;font-size:11px;line-height:1.5;overflow-wrap:anywhere}.implementation-entry .documentation-references{font-size:11px}.implementation-entry .documentation-references>strong{font-size:9px}
14
+ .dataset-catalog-panel{margin:18px 0 20px;padding:18px;border:1px solid var(--line);border-radius:var(--radius);background:var(--surface)}.dataset-catalog-head{display:flex;align-items:end;justify-content:space-between;gap:24px}.dataset-catalog-head>div:first-child{min-width:0}.dataset-catalog-controls{display:grid;grid-template-columns:180px minmax(220px,320px);gap:10px;flex:0 0 auto}.dataset-catalog{max-height:430px;overflow:auto;padding-right:5px}.dataset-category{margin-top:18px}.dataset-category:first-child{margin-top:0}.dataset-category>h3{position:sticky;top:0;z-index:1;display:flex;align-items:center;gap:8px;margin:0;padding:8px 2px;background:var(--surface);border-bottom:1px solid var(--line);font-size:14px}.dataset-category>h3 span{padding:2px 6px;border-radius:999px;background:var(--soft);color:var(--muted);font-size:9px}.dataset-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;padding-top:8px}.dataset-entry{min-width:0;padding:10px;border:1px solid var(--line);border-radius:6px;background:var(--bg)}.dataset-entry.measured{border-left:3px solid var(--accent)}.dataset-entry.selected{box-shadow:inset 0 0 0 1px var(--accent);background:var(--accent-soft)}.dataset-entry button{display:flex;align-items:start;justify-content:space-between;gap:8px;width:100%;padding:0;border:0;background:transparent;color:var(--text);text-align:left}.dataset-entry button:hover strong{color:var(--accent);text-decoration:underline}.dataset-entry strong{display:block;font-size:12px;line-height:1.35;overflow-wrap:anywhere}.dataset-entry small{display:block;margin-top:2px;color:var(--muted);font:9px "SFMono-Regular",Consolas,monospace;overflow-wrap:anywhere}.dataset-state{flex:0 0 auto;max-width:92px;padding:2px 5px;border-radius:4px;background:var(--soft);color:var(--muted);font-size:8px;line-height:1.35;text-align:right}.dataset-entry.measured .dataset-state{background:var(--accent-soft);color:var(--accent)}.dataset-entry p{margin:7px 0 0;color:var(--muted);font-size:9px;line-height:1.45}.dataset-entry .dataset-snapshot-note{color:#9a5a16}.dataset-links{display:flex;flex-wrap:wrap;gap:4px 10px;margin-top:6px}.dataset-links a,.dataset-source{font-size:9px;overflow-wrap:anywhere}
15
+ @media(max-width:1000px){.operator-summary{grid-template-columns:repeat(3,1fr)}.dataset-list{grid-template-columns:repeat(2,minmax(0,1fr))}.dataset-catalog-head{align-items:stretch;flex-direction:column;gap:12px}.dataset-catalog-controls{width:100%;grid-template-columns:1fr 1.5fr}}
16
+ @media(max-width:768px){.operator-summary{grid-template-columns:repeat(2,1fr)}.implementation-entry dl>div{grid-template-columns:1fr;gap:1px}.dataset-catalog-panel{padding:14px}.dataset-catalog-controls,.dataset-list{grid-template-columns:1fr}.dataset-catalog{max-height:520px}}
ui-data.json CHANGED
The diff for this file is too large to render. See raw diff