function toggleNextSibling (e) {
if (e.nextSibling.style.display=='none') {
e.nextSibling.style.display='block';
} else { e.nextSibling.style.display='none'; }
}
// Globals used by SEC loader (Show.js)
window.SEC_ALIAS_DIR = "";
window.RFV_MENU = [{"category":"Cover","reports":[{"label":"Submission","pos":1,"url":"R1.htm"},{"label":"Offerings","pos":2,"url":"R2.htm"},{"label":"Fees Summary","pos":3,"url":"R3.htm"}]},{"allReports":{"1":"R1.htm","2":"R2.htm","3":"R3.htm","4":"ALL_REPORTS_SYNTHETIC"}}];
window.R_FILES_BY_POS = RFV_MENU.find(o => 'allReports' in o)?.allReports;
function scrollMainContentToTop() {
// Scroll to company info instead of top of page header
const anchor = document.getElementById('company-info');
if (anchor) {
anchor.scrollIntoView({
block: 'start', // top-align it
behavior: 'auto' // no animation unless desired
});
}
}
window.RENDERING_LOGS = RFV_MENU.find(o => 'renderingLogs' in o)?.renderingLogs;
// Log viewer renders selected log into #reportDiv
window.showRenderingLog = function () {
const root = ensureShadow();
clearShadow();
let baseDir = (typeof window.SEC_ALIAS_DIR === 'string' && window.SEC_ALIAS_DIR.length)
? window.SEC_ALIAS_DIR.replace(/\/$/, '')
: (location.pathname.replace(/\/[^/]*$/, '') || '/');
if (!baseDir.endsWith('/')) baseDir += '/';
const reportCssHref = `${baseDir}report.css`; // same folder as R1.htm
const logEntries = window.RENDERING_LOGS || [];
const rows = logEntries.map(entry => {
const type = entry?.type || 'Info';
const text = (entry?.text || '').replace(/\r\n|\r|\n/g, '
');
const cls = type.slice(0,4).toLowerCase(); // 'erro', 'warn', 'info', etc.
return `
| ${type}: ${text} |
`;
}).join('');
const container = document.createElement('div');
container.id = 'rfv-shadow-host';
container.innerHTML = `
Rendering Log
| The rendering log information below will not appear on the EDGAR web site. |
${rows}
`;
root.appendChild(container);
scrollMainContentToTop();
};
function decodeHtmlEntities(s) {
// safest cross-browser decode
const t = document.createElement('textarea');
t.innerHTML = s;
return t.value;
}
function decodeBase64Utf8(b64) {
const bin = atob(b64);
const bytes = Uint8Array.from(bin, c => c.charCodeAt(0));
return new TextDecoder("utf-8").decode(bytes);
}
function sanitizeId(id) {
return id.replace(/[^a-zA-Z0-9\._-]/g, '_'); // Replace invalid chars with underscore
}
/**
* Normalize raw report HTML for extraction across contexts:
* - SECWS: decode entity-escaped HTML (<html> → )
* - sec.gov SGML: keep full and , unwrap … safely
* - Arelle/plain: pass through unchanged
*/
function normalizeReportHtml(raw) {
let src = String(raw || '');
// If looks entity-escaped (e.g., <html>, <TEXT>, etc.), decode first
const looksEscaped = /<\/?(?:html|head|body|TEXT)\b/i.test(src) || /<[a-z]/i.test(src);
if (looksEscaped) {
try { src = decodeHtmlEntities(src); } catch (_) {}
}
// If wrapped in SGML …, unwrap while preserving
const hasSGML = //i.test(src) && /<\/TEXT>/i.test(src);
if (hasSGML) {
const start = src.search(//i);
const end = src.search(/<\/TEXT>/i);
if (start !== -1 && end !== -1 && end > start) {
src = src.slice(start + ''.length, end);
}
}
return src;
}
function ensureShadow() {
const pane = document.getElementById('reportDiv');
if (!pane) return null;
if (!pane.shadowRoot) pane.attachShadow({ mode: 'open' });
// mirror for any legacy code still reading _shadowRoot
pane._shadowRoot = pane.shadowRoot;
// make sure host is visible and not contained
pane.hidden = false;
pane.style.display = 'block';
pane.style.visibility = 'visible';
pane.style.contain = 'none';
return pane.shadowRoot;
}
function clearShadow() {
const root = ensureShadow();
if (root) root.innerHTML = '';
}
function renderIntoShadow(bodyHtml, links, inlineStyles, baseDir) {
const root = ensureShadow();
if (!root) return;
// Always clear previous report
clearShadow();
// pane fades via .rfv-pending; do not change visibility to avoid header repaint
const pane = document.getElementById('reportDiv');
// 1) Inline styles FIRST for immediate styling
if (Array.isArray(inlineStyles)) {
for (const css of inlineStyles) {
if (css) {
const styleEl = document.createElement('style');
styleEl.textContent = css;
root.appendChild(styleEl);
}
}
}
// 2) Safety constraints (layout)
const safety = document.createElement('style');
safety.textContent = `
:host { display:block; width:auto; max-width:100%; }
#rfv-shadow-host { display:block; width:auto; max-width:100%; overflow:visible; }
table.report { width:auto; max-width:100%; border-collapse: collapse; }
img { max-width:100%; height:auto; }
/* Unbeatable forced ring (wins against report CSS with !important resets) */
.rfv-force-focus,
.rfv-focus-ring {
outline: 3px solid #005A9C !important;
outline-offset: 2px !important;
box-shadow: 0 0 0 2px #fff inset !important;
}
:focus-visible {
outline: 3px solid #005A9C !important;
outline-offset: 2px !important;
}
`;
root.appendChild(safety);
// 3) Report body
const container = document.createElement('div');
container.id = 'rfv-shadow-host';
container.innerHTML = bodyHtml;
container.setAttribute('tabindex', '-1'); // make container focusable
container.setAttribute('role', 'region'); // semantic region
container.setAttribute('aria-label', 'All reports content'); // accessible name
root.appendChild(container);
// 4) External CSS: fetch-and-prepend, with fallback
const loadExternalCss = () => {
if (!Array.isArray(links) || !links.length) return Promise.resolve();
// some old R files have css includes to include/report.css but there is no include subdirectory
const absHrefs = links.map(h =>
h.startsWith('/') // absolute → leave unchanged
? h
: h.startsWith('include/') // legacy relative include/
? `${baseDir}${h.slice(8)}`
: `${baseDir}${h}` // standard relative report.css, etc.
);
return Promise.allSettled(
absHrefs.map(h => fetch(h).then(r => (r.ok ? r.text() : '')))
).then(results => {
const cssText = results
.filter(r => r.status === 'fulfilled' && r.value)
.map(r => normalizeReportHtml(r.value))
.join('\n');
const styles = document.createElement('style');
styles.textContent =
cssText && cssText.length
? cssText
: absHrefs.map(h => `@import url("${h}");`).join('\n');
root.insertBefore(styles, root.firstChild);
});
};
// Resolve after external CSS is ready (if any)
return loadExternalCss();
}
// Cache of styles we've already loaded
const RFV_LOADED_STYLES = new Set();
function extractLinksAndBody(fullHtml) {
const doc = new DOMParser().parseFromString(fullHtml, 'text/html');
// External CSS links (e.g., )
const links = Array.from(doc.querySelectorAll('link[rel~="stylesheet"][href]'))
.map(link => (link.getAttribute('href') || '').trim())
.filter(Boolean);
// Inline