/** * InitializerDisplay - Displays model initializers (constant tensors / weights) * Requirements: 7.1, 7.2, 7.3, 7.4, 7.5 */ class InitializerDisplay { /** * @param {string} containerId - ID of the container element */ constructor(containerId) { this._containerId = containerId; this._container = document.getElementById(containerId); if (!this._container) { console.warn(`[InitializerDisplay] Container #${containerId} not found`); } } // ─── Private ────────────────────────────────────────────────────────────── /** * Escape HTML special characters. * @param {string} str * @returns {string} */ _escapeHtml(str) { const div = document.createElement('div'); div.appendChild(document.createTextNode(String(str))); return div.innerHTML; } /** * Format a shape array to a readable string. * @param {Array} shape * @returns {string} */ _formatShape(shape) { if (!shape || shape.length === 0) return '[]'; return `[${shape.join(', ')}]`; } /** * Resolve a numeric data type to its string name. * @param {number|string} dataType * @returns {string} */ _resolveDataType(dataType) { if (typeof dataType === 'string') return dataType; if (CONFIG && CONFIG.DATA_TYPES && CONFIG.DATA_TYPES[dataType]) { return CONFIG.DATA_TYPES[dataType]; } return String(dataType); } /** * Format a byte count to a human-readable string (e.g. "4.2 KB"). * @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]}`; } /** * Compute the size label for an initializer. * Prefer size in bytes; fall back to element count. * @param {InitializerInfo} init * @returns {string} */ _sizeLabel(init) { if (init.size && init.size > 0) { return this._formatBytes(init.size); } if (init.elementCount && init.elementCount > 0) { return `${init.elementCount.toLocaleString()} elements`; } // Compute element count from shape if available if (init.shape && init.shape.length > 0) { const count = init.shape.reduce((acc, d) => acc * (d || 1), 1); return `${count.toLocaleString()} elements`; } return 'Unknown size'; } /** * Build the HTML for a single initializer item. * @param {InitializerInfo} init * @returns {string} */ _buildItem(init) { const shape = this._formatShape(init.shape); const dtype = this._resolveDataType(init.dataType); const size = this._sizeLabel(init); return `
${this._escapeHtml(init.name)}
${this._escapeHtml(shape)} ${this._escapeHtml(dtype)} ${this._escapeHtml(size)}
`; } /** * Attach click and keyboard handlers to initializer items. */ _attachItemHandlers() { if (!this._container) return; const items = this._container.querySelectorAll('.initializer-item'); items.forEach((item) => { const handler = () => { const name = item.dataset.initName; if (name && window.EventBus) { window.EventBus.emit(CONFIG.EVENTS.NODE_SELECTED, { nodeId: name, source: 'initializer' }); } if (name && window.StateManager) { window.StateManager.setSelectedNodeId(name); } }; item.addEventListener('click', handler); item.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handler(); } }); }); } // ─── Public API ─────────────────────────────────────────────────────────── /** * Render the initializer list for a parsed model. * @param {ParsedModel} model */ render(model) { if (!this._container) return; const initializers = (model && model.initializers) ? model.initializers : (model && model.graph && model.graph.initializers) ? model.graph.initializers : []; if (initializers.length === 0) { this._container.innerHTML = `

No initializers found in this model.

`; return; } const header = `

${initializers.length} initializer${initializers.length !== 1 ? 's' : ''}

`; const items = initializers.map((init) => this._buildItem(init)).join(''); this._container.innerHTML = header + items; this._attachItemHandlers(); } /** * Clear the display. */ clear() { if (!this._container) return; this._container.innerHTML = '

Select a model to view initializers

'; } } window.InitializerDisplay = InitializerDisplay;