/** * 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 'Not available'; } 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 ` ${this._escapeHtml(label)} ${valueHtml} `; } /** * Render custom metadata attributes. * @param {Record} 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 ` Custom Attributes ${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 = ` ${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)) : 'Not available')} ${this._renderCustomAttributes(meta.customAttributes)}
`; 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 = '

Select a model to view metadata

'; } } window.MetadataDisplay = MetadataDisplay;