Spaces:
Running
Running
File size: 3,961 Bytes
9bd422a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /**
* MetadataDisplay - Displays ONNX model metadata
* Requirements: 6.1, 6.2, 6.3, 6.4, 6.5, 6.6
*/
class MetadataDisplay {
/**
* @param {string} containerId - ID of the container element
*/
constructor(containerId) {
this._containerId = containerId;
this._container = document.getElementById(containerId);
if (!this._container) {
console.warn(`[MetadataDisplay] Container #${containerId} not found`);
}
}
// βββ Private ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/**
* Return a display value, falling back to "Not available".
* @param {*} value
* @returns {string}
*/
_displayValue(value) {
if (value === null || value === undefined || value === '') {
return '<span class="text-muted fst-italic">Not available</span>';
}
return this._escapeHtml(String(value));
}
/**
* Escape HTML special characters.
* @param {string} str
* @returns {string}
*/
_escapeHtml(str) {
const div = document.createElement('div');
div.appendChild(document.createTextNode(str));
return div.innerHTML;
}
/**
* Build a metadata row.
* @param {string} label
* @param {string} valueHtml - Already-escaped HTML string
* @returns {string}
*/
_row(label, valueHtml) {
return `
<tr>
<th scope="row" class="text-nowrap pe-3" style="width:40%">${this._escapeHtml(label)}</th>
<td>${valueHtml}</td>
</tr>`;
}
/**
* Render custom metadata attributes.
* @param {Record<string, any>} attrs
* @returns {string} HTML string
*/
_renderCustomAttributes(attrs) {
if (!attrs || Object.keys(attrs).length === 0) {
return '';
}
const rows = Object.entries(attrs)
.map(([key, val]) => this._row(key, this._displayValue(val)))
.join('');
return `
<tr>
<td colspan="2" class="pt-3 pb-1">
<strong class="text-secondary small text-uppercase">Custom Attributes</strong>
</td>
</tr>
${rows}`;
}
// βββ Public API βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
/**
* Render metadata for a parsed model.
* @param {ParsedModel} model
*/
render(model) {
if (!this._container) return;
const meta = (model && model.metadata) ? model.metadata : {};
const html = `
<table class="table table-sm table-borderless mb-0">
<tbody>
${this._row('Producer Name', this._displayValue(meta.producerName))}
${this._row('Producer Version', this._displayValue(meta.producerVersion))}
${this._row('Opset Version', this._displayValue(meta.opsetVersion))}
${this._row('IR Version', this._displayValue(meta.irVersion))}
${this._row('File Name', this._displayValue(meta.fileName))}
${this._row('File Size', meta.fileSize ? this._displayValue(this._formatBytes(meta.fileSize)) : '<span class="text-muted fst-italic">Not available</span>')}
${this._renderCustomAttributes(meta.customAttributes)}
</tbody>
</table>`;
this._container.innerHTML = html;
}
/**
* Format bytes to a human-readable string.
* @param {number} bytes
* @returns {string}
*/
_formatBytes(bytes) {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
}
/**
* Clear the metadata display.
*/
clear() {
if (!this._container) return;
this._container.innerHTML = '<p class="text-muted">Select a model to view metadata</p>';
}
}
window.MetadataDisplay = MetadataDisplay;
|