@robosystems/report-components 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +1 -1
- package/dist/{chunk-GJL4ILVH.js → chunk-XHHRSCHV.js} +77 -20
- package/dist/chunk-XHHRSCHV.js.map +1 -0
- package/dist/{index-fEwdoTEH.d.ts → index-MeQYBvqk.d.ts} +21 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-GJL4ILVH.js.map +0 -1
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { e as CypherAdapterConfig, R as ReportAdapter,
|
|
1
|
+
export { e as CypherAdapterConfig, R as ReportAdapter, q as SecQuery, r as SecReportShell, s as SecSection, S as SectionKind, x as cypherAdapter, y as fetchSecReportShell, z as fetchSecSection, G as jsonldFileAdapter, H as mergeSecSections, J as parseJsonld, K as parseStore, L as parseStructureDefinition, M as parseStructureName } from '../index-MeQYBvqk.js';
|
|
2
2
|
import 'n3';
|
package/dist/adapters/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { cypherAdapter, fetchSecReportShell, fetchSecSection, jsonldFileAdapter, mergeSecSections, parseJsonld, parseStore, parseStructureDefinition, parseStructureName } from '../chunk-
|
|
1
|
+
export { cypherAdapter, fetchSecReportShell, fetchSecSection, jsonldFileAdapter, mergeSecSections, parseJsonld, parseStore, parseStructureDefinition, parseStructureName } from '../chunk-XHHRSCHV.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -249,11 +249,15 @@ RETURN s.identifier AS sid, s.canonical_type AS canonical_type,
|
|
|
249
249
|
s.definition AS definition, s.number AS number,
|
|
250
250
|
collect(DISTINCT fs.identifier) AS factsets
|
|
251
251
|
ORDER BY number`;
|
|
252
|
+
var LABELS_Q = `
|
|
253
|
+
MATCH (r:Report {identifier: $rid})-[:REPORT_USES_TAXONOMY]->(:Taxonomy)-[tl:TAXONOMY_HAS_LABEL]->(l:Label)
|
|
254
|
+
WHERE tl.element_uri IS NOT NULL
|
|
255
|
+
RETURN tl.element_uri AS element_uri, l.type AS role, l.value AS value`;
|
|
252
256
|
var FACTS_Q = `
|
|
253
257
|
MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact)-[:FACT_HAS_ELEMENT]->(e:Element),
|
|
254
258
|
(f)-[:FACT_HAS_PERIOD]->(p:Period)
|
|
255
259
|
WHERE f.value IS NOT NULL
|
|
256
|
-
RETURN f.identifier AS fid, e.qname AS qname, e.name AS ename, e.balance AS balance,
|
|
260
|
+
RETURN f.identifier AS fid, e.qname AS qname, e.uri AS euri, e.name AS ename, e.balance AS balance,
|
|
257
261
|
e.period_type AS e_period_type, e.is_abstract AS is_abstract, e.is_numeric AS is_numeric,
|
|
258
262
|
e.item_type AS item_type, e.is_shares AS is_shares,
|
|
259
263
|
f.numeric_value AS numeric_value, f.value AS raw_value, f.decimals AS decimals,
|
|
@@ -277,8 +281,8 @@ MATCH (s:Structure {identifier: $sid})-[:STRUCTURE_HAS_ASSOCIATION]->(a:Associat
|
|
|
277
281
|
(a)-[:ASSOCIATION_HAS_FROM_ELEMENT]->(pe:Element),
|
|
278
282
|
(a)-[:ASSOCIATION_HAS_TO_ELEMENT]->(ce:Element)
|
|
279
283
|
RETURN a.association_type AS association_type, a.order_value AS order_value, a.weight AS weight,
|
|
280
|
-
pe.qname AS parent, pe.name AS parent_name, pe.is_abstract AS parent_abstract,
|
|
281
|
-
ce.qname AS child, ce.name AS child_name, ce.is_abstract AS child_abstract`;
|
|
284
|
+
pe.qname AS parent, pe.uri AS parent_uri, pe.name AS parent_name, pe.is_abstract AS parent_abstract,
|
|
285
|
+
ce.qname AS child, ce.uri AS child_uri, ce.name AS child_name, ce.is_abstract AS child_abstract`;
|
|
282
286
|
function str(row, key) {
|
|
283
287
|
const v = row[key];
|
|
284
288
|
return typeof v === "string" && v !== "" ? v : v == null ? null : String(v);
|
|
@@ -311,6 +315,36 @@ function dimLabel(local) {
|
|
|
311
315
|
if (!local) return "";
|
|
312
316
|
return humanize(local.replace(/(Axis|Member|Domain)$/, "")) || humanize(local);
|
|
313
317
|
}
|
|
318
|
+
var STANDARD_LABEL_ROLE = "http://www.xbrl.org/2003/role/label";
|
|
319
|
+
var TERSE_LABEL_ROLE = "http://www.xbrl.org/2003/role/terseLabel";
|
|
320
|
+
var ROLE_SUFFIX_RE = /\s*\[(?:Abstract|Axis|Member|Table|Line Items|Domain)\]\s*$/;
|
|
321
|
+
function stripRoleSuffix(label) {
|
|
322
|
+
const stripped = label.replace(ROLE_SUFFIX_RE, "").trim();
|
|
323
|
+
return stripped || label;
|
|
324
|
+
}
|
|
325
|
+
function buildReportLabels(rows) {
|
|
326
|
+
const byElement = /* @__PURE__ */ new Map();
|
|
327
|
+
for (const row of rows) {
|
|
328
|
+
const uri = str(row, "element_uri");
|
|
329
|
+
const value = str(row, "value");
|
|
330
|
+
if (!uri || !value) continue;
|
|
331
|
+
const role = str(row, "role") ?? STANDARD_LABEL_ROLE;
|
|
332
|
+
let roles = byElement.get(uri);
|
|
333
|
+
if (!roles) {
|
|
334
|
+
roles = /* @__PURE__ */ new Map();
|
|
335
|
+
byElement.set(uri, roles);
|
|
336
|
+
}
|
|
337
|
+
roles.set(role, value);
|
|
338
|
+
}
|
|
339
|
+
return { byElement };
|
|
340
|
+
}
|
|
341
|
+
function labelFor(labels, uri, preferredRole) {
|
|
342
|
+
if (!uri) return null;
|
|
343
|
+
const roles = labels.byElement.get(uri);
|
|
344
|
+
if (!roles) return null;
|
|
345
|
+
const resolved = roles.get(STANDARD_LABEL_ROLE) ?? roles.get(TERSE_LABEL_ROLE);
|
|
346
|
+
return resolved ? stripRoleSuffix(resolved) : null;
|
|
347
|
+
}
|
|
314
348
|
function deriveNumericKind(row) {
|
|
315
349
|
const itemType = str(row, "item_type") ?? "";
|
|
316
350
|
if (/perShareItemType/i.test(itemType)) return "perShare";
|
|
@@ -335,9 +369,15 @@ function mapEntity(row) {
|
|
|
335
369
|
};
|
|
336
370
|
}
|
|
337
371
|
async function fetchSecReportShell(query, reportId) {
|
|
338
|
-
const [entityRows, sectionRows] = await Promise.all([
|
|
372
|
+
const [entityRows, sectionRows, labelRows] = await Promise.all([
|
|
339
373
|
query(ENTITY_META_Q, { rid: reportId }),
|
|
340
|
-
query(SECTIONS_Q, { rid: reportId })
|
|
374
|
+
query(SECTIONS_Q, { rid: reportId }),
|
|
375
|
+
// Report-scoped labels are an enhancement, not a requirement. A graph that
|
|
376
|
+
// predates the `TAXONOMY_HAS_LABEL.element_uri` ingest change binder-errors on
|
|
377
|
+
// LABELS_Q; swallow that so the shell still loads and labels fall back to the
|
|
378
|
+
// humanized qname. This lets the viewer ship ahead of the SEC reprocess and
|
|
379
|
+
// light up automatically once the graph carries element_uri.
|
|
380
|
+
query(LABELS_Q, { rid: reportId }).catch(() => [])
|
|
341
381
|
]);
|
|
342
382
|
const sections = sectionRows.map((row, order) => {
|
|
343
383
|
const { title, kind } = parseStructureDefinition(
|
|
@@ -355,16 +395,24 @@ async function fetchSecReportShell(query, reportId) {
|
|
|
355
395
|
factsetIds: factsets
|
|
356
396
|
};
|
|
357
397
|
}).filter((s) => s.id && s.factsetIds.length > 0);
|
|
358
|
-
return {
|
|
398
|
+
return {
|
|
399
|
+
reportId,
|
|
400
|
+
entity: mapEntity(entityRows[0]),
|
|
401
|
+
sections,
|
|
402
|
+
labels: buildReportLabels(labelRows)
|
|
403
|
+
};
|
|
359
404
|
}
|
|
360
|
-
function accumulateElement(elements, row) {
|
|
405
|
+
function accumulateElement(elements, row, labels) {
|
|
361
406
|
const q = str(row, "qname");
|
|
362
407
|
if (!q || elements[q]) return;
|
|
363
408
|
const balance = str(row, "balance");
|
|
409
|
+
const ename = str(row, "ename");
|
|
364
410
|
elements[q] = {
|
|
365
411
|
id: q,
|
|
366
412
|
qname: q,
|
|
367
|
-
|
|
413
|
+
// Prefer the report's own label (resolved from its per-report taxonomy);
|
|
414
|
+
// humanizing the element name is the fallback when the report defined none.
|
|
415
|
+
label: labelFor(labels, str(row, "euri")) ?? (ename ? humanize(ename) : humanize(q)),
|
|
368
416
|
balance: balance === "debit" || balance === "credit" ? balance : null,
|
|
369
417
|
periodType: periodType(str(row, "e_period_type")),
|
|
370
418
|
abstract: bool(row, "is_abstract"),
|
|
@@ -372,12 +420,13 @@ function accumulateElement(elements, row) {
|
|
|
372
420
|
numericKind: deriveNumericKind(row)
|
|
373
421
|
};
|
|
374
422
|
}
|
|
375
|
-
function registerPresentationElement(elements, qname2, name, isAbstract) {
|
|
423
|
+
function registerPresentationElement(elements, qname2, uri, name, isAbstract, labels) {
|
|
376
424
|
if (!qname2 || elements[qname2]) return;
|
|
425
|
+
const humanized = name ? humanize(isAbstract ? name.replace(/Abstract$/, "") : name) : humanize(qname2);
|
|
377
426
|
elements[qname2] = {
|
|
378
427
|
id: qname2,
|
|
379
428
|
qname: qname2,
|
|
380
|
-
label:
|
|
429
|
+
label: labelFor(labels, uri) ?? humanized,
|
|
381
430
|
balance: null,
|
|
382
431
|
periodType: null,
|
|
383
432
|
abstract: isAbstract,
|
|
@@ -417,11 +466,13 @@ async function fetchSecSection(query, shell, section) {
|
|
|
417
466
|
const fid = str(row, "fid");
|
|
418
467
|
if (!fid) continue;
|
|
419
468
|
const memberLocal = str(row, "member");
|
|
469
|
+
const axisUri = str(row, "axis_uri");
|
|
470
|
+
const memberUri = str(row, "member_uri");
|
|
420
471
|
const qual = {
|
|
421
|
-
axis: xbrlQname(
|
|
422
|
-
member: memberLocal ? xbrlQname(
|
|
423
|
-
axisLabel: dimLabel(str(row, "axis")),
|
|
424
|
-
memberLabel: dimLabel(memberLocal),
|
|
472
|
+
axis: xbrlQname(axisUri, str(row, "axis")),
|
|
473
|
+
member: memberLocal ? xbrlQname(memberUri, memberLocal) : null,
|
|
474
|
+
axisLabel: labelFor(shell.labels, axisUri) ?? dimLabel(str(row, "axis")),
|
|
475
|
+
memberLabel: labelFor(shell.labels, memberUri) ?? dimLabel(memberLocal),
|
|
425
476
|
explicit: bool(row, "is_explicit"),
|
|
426
477
|
typedValue: bool(row, "is_typed") ? str(row, "member") : null
|
|
427
478
|
};
|
|
@@ -441,7 +492,7 @@ async function fetchSecSection(query, shell, section) {
|
|
|
441
492
|
const period = str(row, "pid");
|
|
442
493
|
if (!fid || !element || !period || seenFacts.has(fid)) continue;
|
|
443
494
|
seenFacts.add(fid);
|
|
444
|
-
accumulateElement(elements, row);
|
|
495
|
+
accumulateElement(elements, row, shell.labels);
|
|
445
496
|
accumulatePeriod(periods, row);
|
|
446
497
|
const measure = unitByFid.get(fid) ?? null;
|
|
447
498
|
if (measure && !units[measure]) {
|
|
@@ -476,14 +527,18 @@ async function fetchSecSection(query, shell, section) {
|
|
|
476
527
|
registerPresentationElement(
|
|
477
528
|
elements,
|
|
478
529
|
parent,
|
|
530
|
+
str(row, "parent_uri"),
|
|
479
531
|
str(row, "parent_name"),
|
|
480
|
-
bool(row, "parent_abstract")
|
|
532
|
+
bool(row, "parent_abstract"),
|
|
533
|
+
shell.labels
|
|
481
534
|
);
|
|
482
535
|
registerPresentationElement(
|
|
483
536
|
elements,
|
|
484
537
|
child,
|
|
538
|
+
str(row, "child_uri"),
|
|
485
539
|
str(row, "child_name"),
|
|
486
|
-
bool(row, "child_abstract")
|
|
540
|
+
bool(row, "child_abstract"),
|
|
541
|
+
shell.labels
|
|
487
542
|
);
|
|
488
543
|
const order = num(row, "order_value") ?? 0;
|
|
489
544
|
const type = str(row, "association_type")?.toLowerCase();
|
|
@@ -677,13 +732,15 @@ function parseStore(store) {
|
|
|
677
732
|
typedValue: typedValue ?? null
|
|
678
733
|
});
|
|
679
734
|
}
|
|
735
|
+
const factSets = objects(id, IRI.factSet).map((o) => o.value);
|
|
680
736
|
facts.push({
|
|
681
737
|
id,
|
|
682
738
|
element: firstValue(id, IRI.element) ?? "",
|
|
683
739
|
period: firstValue(id, IRI.period) ?? "",
|
|
684
740
|
unit: firstValue(id, IRI.unit),
|
|
685
741
|
entity: firstValue(id, IRI.entity),
|
|
686
|
-
factSet:
|
|
742
|
+
factSet: factSets[0] ?? null,
|
|
743
|
+
factSets: factSets.length ? factSets : void 0,
|
|
687
744
|
value: toNumber(firstValue(id, IRI.numericValue)),
|
|
688
745
|
textValue: firstValue(id, IRI.stringValue),
|
|
689
746
|
decimals: firstValue(id, IRI.decimals),
|
|
@@ -786,5 +843,5 @@ function jsonldFileAdapter(doc, source = "holon.jsonld") {
|
|
|
786
843
|
}
|
|
787
844
|
|
|
788
845
|
export { BLOCK_ORDER, BLOCK_TITLES, NS, currencySymbolFor, cypherAdapter, fetchSecReportShell, fetchSecSection, formatDate, formatMoney, formatPeriod, formatValue, humanize, humanizeDuration, isExternalFactUrl, jsonldFileAdapter, mergeSecSections, numericKindOf, parseJsonld, parseStore, parseStructureDefinition, parseStructureName, qname };
|
|
789
|
-
//# sourceMappingURL=chunk-
|
|
790
|
-
//# sourceMappingURL=chunk-
|
|
846
|
+
//# sourceMappingURL=chunk-XHHRSCHV.js.map
|
|
847
|
+
//# sourceMappingURL=chunk-XHHRSCHV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/format.ts","../src/sections.ts","../src/adapters/sec.ts","../src/adapters/cypher.ts","../src/adapters/store.ts","../src/adapters/jsonld.ts"],"names":["qname","periodType","Store"],"mappings":"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","file":"chunk-XHHRSCHV.js","sourcesContent":["/**\n * RDF vocabulary and display helpers shared across adapters and projection.\n *\n * A report holon mixes several vocabularies: `rs:` for structure, `skos:` for\n * human labels, and the XBRL family (`xlink:` / `xbrli:` / `link:`) for the\n * networks. These constants are the single source of truth for the full IRIs.\n */\n\nexport const NS = {\n rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',\n rs: 'https://robosystems.ai/vocab/',\n rsgaap: 'https://robosystems.ai/taxonomy/rs-gaap/v1/',\n skos: 'http://www.w3.org/2004/02/skos/core#',\n xlink: 'http://www.w3.org/1999/xlink#',\n xbrli: 'http://www.xbrl.org/2003/instance#',\n link: 'http://www.xbrl.org/2003/linkbase#',\n iso4217: 'http://www.xbrl.org/2003/iso4217#',\n} as const\n\n/** Frequently-referenced full IRIs, pre-concatenated for terseness. */\nexport const IRI = {\n type: NS.rdf + 'type',\n // rs: classes\n Report: NS.rs + 'Report',\n Fact: NS.rs + 'Fact',\n InformationBlock: NS.rs + 'InformationBlock',\n Structure: NS.rs + 'Structure',\n Association: NS.rs + 'Association',\n Element: NS.rs + 'Element',\n Period: NS.rs + 'Period',\n Unit: NS.rs + 'Unit',\n Entity: NS.rs + 'Entity',\n // rs: predicates\n element: NS.rs + 'element',\n period: NS.rs + 'period',\n unit: NS.rs + 'unit',\n entity: NS.rs + 'entity',\n factSet: NS.rs + 'factSet',\n numericValue: NS.rs + 'numericValue',\n stringValue: NS.rs + 'stringValue',\n decimals: NS.rs + 'decimals',\n dimension: NS.rs + 'dimension',\n axis: NS.rs + 'axis',\n member: NS.rs + 'member',\n isExplicit: NS.rs + 'isExplicit',\n typedValue: NS.rs + 'typedValue',\n blockType: NS.rs + 'blockType',\n associationType: NS.rs + 'associationType',\n hasAssociation: NS.rs + 'hasAssociation',\n roleUri: NS.rs + 'roleUri',\n structure: NS.rs + 'structure',\n structureName: NS.rs + 'structureName',\n structureOrder: NS.rs + 'structureOrder',\n abstract: NS.rs + 'abstract',\n monetary: NS.rs + 'monetary',\n itemType: NS.rs + 'itemType',\n legalName: NS.rs + 'legalName',\n country: NS.rs + 'country',\n // skos:\n prefLabel: NS.skos + 'prefLabel',\n // xlink:\n from: NS.xlink + 'from',\n to: NS.xlink + 'to',\n role: NS.xlink + 'role',\n // xbrli:\n instant: NS.xbrli + 'instant',\n startDate: NS.xbrli + 'startDate',\n endDate: NS.xbrli + 'endDate',\n periodType: NS.xbrli + 'periodType',\n balance: NS.xbrli + 'balance',\n measure: NS.xbrli + 'measure',\n // link:\n order: NS.link + 'order',\n weight: NS.link + 'weight',\n} as const\n\n/**\n * Prefixes for compacting concept IRIs to `prefix:Local`. Order matters — the\n * most specific namespace must come first so `rs-gaap:` wins over `rs:`.\n */\nconst PREFIXES: ReadonlyArray<readonly [string, string]> = [\n ['rs-gaap', NS.rsgaap],\n ['disclosures', 'https://robosystems.ai/taxonomy/rs-gaap/disclosures/v1/'],\n ['us-gaap', 'http://fasb.org/us-gaap/'],\n ['dei', 'http://xbrl.sec.gov/dei/'],\n ['rs', NS.rs],\n ['skos', NS.skos],\n ['xbrli', NS.xbrli],\n ['xlink', NS.xlink],\n ['link', NS.link],\n ['iso4217', NS.iso4217],\n]\n\n/** Compact a concept IRI to `prefix:Local` (e.g. `rs-gaap:Assets`). */\nexport function qname(iri: string): string {\n for (const [prefix, ns] of PREFIXES) {\n if (iri.startsWith(ns)) {\n return `${prefix}:${iri.slice(ns.length)}`\n }\n }\n const slash = iri.lastIndexOf('/')\n const hash = iri.lastIndexOf('#')\n return iri.slice(Math.max(slash, hash) + 1)\n}\n\n/**\n * Readable concept name from a local name when no `skos:prefLabel` is present —\n * splits CamelCase into words (`AssetsCurrent` → `Assets Current`). A graceful\n * fallback for bundles that predate label emit.\n */\nexport function humanize(iri: string): string {\n const local = qname(iri).split(':').pop() ?? iri\n return local.replace(/(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g, ' ')\n}\n\n/**\n * A large text-block / policy fact whose HTML (or plain-text) body is too big to\n * store inline, so the platform externalizes it to the public CDN and the fact's\n * value is the URL (`…/fact_<hash>.html` or `.txt`). The renderer fetches and\n * embeds these instead of printing the raw link.\n */\nexport function isExternalFactUrl(value: string | null | undefined): boolean {\n return !!value && /^https?:\\/\\/\\S+\\/fact_[0-9a-f]+\\.(html|txt)$/i.test(value)\n}\n\n/** Stable display order for the canonical statement blocks; others fall after. */\nexport const BLOCK_ORDER: Record<string, number> = {\n balance_sheet: 0,\n income_statement: 1,\n cash_flow_statement: 2,\n equity_statement: 3,\n}\n\n/** Friendly section headings keyed by block type. */\nexport const BLOCK_TITLES: Record<string, string> = {\n balance_sheet: 'Balance Sheet',\n income_statement: 'Income Statement',\n cash_flow_statement: 'Cash Flow Statement',\n equity_statement: 'Statement of Changes in Equity',\n}\n","/**\n * Pure formatting helpers shared by the projection and the components. No React\n * here, so the projection can depend on it without pulling in a renderer.\n */\nimport type { ElementInfo, NumericKind, PeriodInfo } from './model'\n\n/**\n * Accounting-style money: negatives in parentheses, no sign, an em-dash for\n * absent values. Matches the RoboLedger statement renderer.\n */\nexport function formatMoney(\n value: number | null | undefined,\n opts: { currencySymbol?: string } = {}\n): string {\n if (value === null || value === undefined || Number.isNaN(value)) return '—'\n const symbol = opts.currencySymbol ?? '$'\n const abs = Math.abs(value).toLocaleString('en-US', {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })\n return value < 0 ? `${symbol}(${abs})` : `${symbol}${abs}`\n}\n\nconst MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\n\n/** `2024-03-31` → `Mar 31, 2024`. Falls back to the raw string if unparseable. */\nexport function formatDate(iso: string | null | undefined): string {\n if (!iso) return ''\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(iso)\n if (!m) return iso\n const [, year, month, day] = m\n const idx = Number(month) - 1\n return `${MONTHS[idx] ?? month} ${Number(day)}, ${year}`\n}\n\n/**\n * Humanize an ISO-8601 duration value (`P10Y` → \"10 years\", `P1Y6M` → \"1 year 6\n * months\", `P30D` → \"30 days\"), or null when the string is not a duration — so a\n * non-numeric fact that happens to start with \"P\" (a company name) is untouched.\n * XBRL `durationItemType` facts (debt maturities, lease terms) arrive as these\n * strings in the text path.\n */\nexport function humanizeDuration(value: string | null | undefined): string | null {\n if (!value) return null\n const m =\n /^(-)?P(?:(\\d+)Y)?(?:(\\d+)M)?(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+(?:\\.\\d+)?)S)?)?$/.exec(\n value.trim()\n )\n if (!m) return null\n const [, sign, y, mo, w, d, h, min, s] = m\n const parts: string[] = []\n const push = (n: string | undefined, unit: string): void => {\n if (n) parts.push(`${n} ${unit}${Number(n) === 1 ? '' : 's'}`)\n }\n push(y, 'year')\n push(mo, 'month')\n push(w, 'week')\n push(d, 'day')\n push(h, 'hour')\n push(min, 'minute')\n push(s, 'second')\n if (!parts.length) return null\n return `${sign ?? ''}${parts.join(' ')}`\n}\n\n/** A human description of a period — \"As of …\" for instants, a span for durations. */\nexport function formatPeriod(period: PeriodInfo): string {\n if (period.type === 'instant') {\n return `As of ${formatDate(period.instant ?? period.end)}`\n }\n return `${formatDate(period.startDate)} – ${formatDate(period.endDate ?? period.end)}`\n}\n\n/** The effective numeric kind of an element (explicit, else derived from monetary). */\nexport function numericKindOf(el: ElementInfo): NumericKind {\n return el.numericKind ?? (el.monetary ? 'monetary' : 'other')\n}\n\n/** Common currency symbols by ISO-4217 code; null for a non-currency unit. */\nconst CURRENCY_SYMBOLS: Record<string, string> = {\n USD: '$',\n EUR: '€',\n GBP: '£',\n JPY: '¥',\n CNY: '¥',\n CHF: 'CHF ',\n CAD: 'CA$',\n AUD: 'A$',\n HKD: 'HK$',\n INR: '₹',\n KRW: '₩',\n}\n\n/**\n * A display prefix for a monetary unit measure (`iso4217:USD` → `$`), else null.\n * Unknown currencies fall back to their code (`CHF `, `SEK `) rather than a wrong\n * dollar sign — this is what fixes non-USD facts rendering as `$`.\n */\nexport function currencySymbolFor(measure: string | null | undefined): string | null {\n if (!measure) return null\n const code = (measure.includes(':') ? measure.split(':').pop()! : measure).toUpperCase()\n if (CURRENCY_SYMBOLS[code]) return CURRENCY_SYMBOLS[code]\n // A currency-shaped code (3 letters) we don't have a glyph for → code prefix.\n return /^[A-Z]{3}$/.test(code) ? `${code} ` : null\n}\n\nexport interface ValueFormat {\n /** Drives symbol, scaling opt-out, and decimal places. Defaults to `monetary`. */\n numericKind?: NumericKind\n /** Currency symbol for monetary/per-share values (from the fact's unit). */\n symbol?: string | null\n /** Divide monetary values by this (e.g. 1e6 to show millions); default 1. */\n scaleFactor?: number\n}\n\n/**\n * Format a fact value for display: accounting style (negatives in parentheses,\n * em-dash for absent), the fact's own currency symbol (never a hard-coded `$`),\n * and the section scale — with per-share amounts and share counts never rescaled\n * (an EPS of 4.93 stays 4.93 under \"in millions\"). A `percent` fact stores a\n * decimal fraction, so it is scaled ×100 and suffixed with `%` (0.10 → 10%); a\n * `pure` fact is a bare ratio, shown as a plain decimal (no `%`).\n */\nexport function formatValue(value: number | null | undefined, fmt: ValueFormat = {}): string {\n if (value === null || value === undefined || Number.isNaN(value)) return '—'\n const kind = fmt.numericKind ?? 'monetary'\n const scale = kind === 'monetary' ? (fmt.scaleFactor ?? 1) : 1\n const scaled = kind === 'percent' ? value * 100 : value / scale\n\n let minFrac = 0\n let maxFrac = 0\n if (kind === 'perShare') {\n minFrac = maxFrac = 2\n } else if (kind === 'monetary') {\n minFrac = maxFrac = scale > 1 ? 0 : 2\n } else if (kind === 'percent') {\n maxFrac = 2\n } else if (kind === 'pure') {\n maxFrac = 4\n }\n\n const abs = Math.abs(scaled).toLocaleString('en-US', {\n minimumFractionDigits: minFrac,\n maximumFractionDigits: maxFrac,\n })\n const symbol = kind === 'monetary' || kind === 'perShare' ? (fmt.symbol ?? '') : ''\n const suffix = kind === 'percent' ? '%' : ''\n return scaled < 0 ? `${symbol}(${abs}${suffix})` : `${symbol}${abs}${suffix}`\n}\n","/**\n * Shared parsing of an XBRL structure's role definition into a display title, its\n * full raw definition, and a coarse `kind`. Used by BOTH the SEC adapter (whose\n * definitions are always SEC-shaped) and the jsonld/file adapter (whose structure\n * names may be non-SEC), so every source lands the same `StructureInfo` shape —\n * the section header and TOC read identically regardless of where the data came\n * from.\n */\n\n/** Coarse grouping for a section — the basis for a \"Statements / Disclosures\" TOC. */\nexport type SectionKind = 'Statement' | 'Disclosure' | 'Document' | 'Cover' | 'Other'\n\n/**\n * The primary financial statements. Only these `canonical_type`s belong in the\n * TOC's \"Financial Statements\" group — other canonical types (rollforwards,\n * hierarchies, `(Details)` networks) are disclosures, classified by their\n * definition's type word instead.\n */\nconst CORE_STATEMENT_TYPES = new Set([\n 'balance_sheet',\n 'income_statement',\n 'cash_flow_statement',\n 'equity_statement',\n 'comprehensive_income',\n])\n\n/**\n * Split an XBRL `Structure.definition` into a human title + a coarse kind.\n * Definitions look like `\"9952153 - Statement - Consolidated Balance Sheets\"` or\n * `\"0000001 - Document - Cover Page\"` — a `\"NNNN - <Type> - <Title>\"` shape whose\n * middle word (Statement / Disclosure / Document) drives the kind. A core\n * canonical statement always reads as a Statement so the primaries group cleanly.\n */\nexport function parseStructureDefinition(\n definition: string | null,\n canonicalType: string | null\n): { title: string; kind: SectionKind } {\n const raw = (definition ?? '').trim()\n const parts = raw.split(' - ')\n let type = ''\n let title = raw\n if (parts.length >= 3) {\n type = parts[1].trim()\n title = parts.slice(2).join(' - ').trim()\n } else if (parts.length === 2) {\n title = parts[1].trim()\n }\n\n let kind: SectionKind = 'Other'\n if (/cover/i.test(title)) kind = 'Cover'\n else if (type === 'Statement') kind = 'Statement'\n else if (type === 'Disclosure') kind = 'Disclosure'\n else if (type === 'Document') kind = 'Document'\n // A core statement is always a Statement; a non-core canonical type (e.g.\n // GoodwillRollForward) stays whatever its definition type word made it.\n if (canonicalType && CORE_STATEMENT_TYPES.has(canonicalType)) kind = 'Statement'\n\n return { title: title || raw || canonicalType || 'Section', kind }\n}\n\n// A SEC role definition's signature: a leading numeric sort code immediately\n// followed by \" - \". Only names with that shape are parsed; anything else (a\n// non-SEC holon's plain structure name) is left untouched, so this never\n// over-strips a name that merely happens to contain \" - \".\nconst SEC_ROLE_PREFIX = /^\\s*\\d+\\s*-\\s/\n\n/**\n * Parse a structure NAME as carried on a holon's `rs:structureName`, the same way\n * as a SEC definition but only when it is SEC-shaped. Returns the full definition\n * (verbatim, for hover), a clean display title, and the kind (null for a non-SEC\n * name, whose title is just the name).\n */\nexport function parseStructureName(name: string | null): {\n definition: string | null\n title: string | null\n kind: SectionKind | null\n} {\n if (!name) return { definition: null, title: null, kind: null }\n if (!SEC_ROLE_PREFIX.test(name)) return { definition: name, title: name, kind: null }\n const { title, kind } = parseStructureDefinition(name, null)\n return { definition: name, title, kind }\n}\n","/**\n * The SEC adapter — reconstructs a report from the live SEC EDGAR graph\n * (`graph_id = \"sec\"`) via read-only Cypher, one section at a time.\n *\n * A single SEC filing is a large graph: a 10-K is ~90 `Structure`s (the 5 core\n * statements plus dozens of disclosure/document networks), thousands of facts.\n * Loading the whole thing up front is slow, so this module splits the work:\n *\n * - `fetchSecReportShell` — one fast pass that returns the entity + the ordered\n * **section list** (each `Structure` with its title, kind, and factset ids).\n * - `fetchSecSection` — on demand, the facts + presentation/calculation network\n * for **one** section, assembled into a single-section `NormalizedReport` the\n * shared projection/components render unchanged.\n *\n * The library stays transport-agnostic: the caller injects a `SecQuery` (a thin\n * wrapper over `POST /v1/graphs/sec/query`); this module owns only the Cypher and\n * the row → model mapping.\n *\n * ── Query rules (load-bearing; verified against the live graph) ────────────────\n * These are not stylistic — violating them turns a ~120 ms query into a ~14 s one:\n * 1. **Anchor on a primary key.** Lead per-section queries with a direct\n * `{identifier: $id}` match on `FactSet`/`Structure` (indexed). Never expand a\n * whole `Report`'s facts, and never use `WHERE x.identifier IN [list]` (a scan,\n * not an index probe) — issue one query per factset instead.\n * 3. **Always carry a `WHERE f.value IS NOT NULL` predicate** on the fact scan and\n * **always `LIMIT`.** Both flip the planner onto the fast path (~120 ms vs ~7 s).\n * `value` (the raw string) is present on every fact, so this keeps numeric and\n * text facts alike.\n * 4. **No `OPTIONAL MATCH`.** An optional unit join alone cost ~12 s; units come\n * from a separate required-join query, merged client-side.\n * 5. Aggregations must `ORDER BY <alias>` (not `s.number`); `end` is reserved, so\n * alias every `p.end_date AS end_date`.\n */\nimport { humanize, qname as toQname } from '../constants'\nimport { currencySymbolFor } from '../format'\nimport type {\n CalcAssociation,\n DimensionQualifier,\n ElementInfo,\n EntityInfo,\n Fact,\n InformationBlock,\n NormalizedReport,\n NumericKind,\n PeriodInfo,\n PeriodType,\n PresAssociation,\n StructureInfo,\n UnitInfo,\n} from '../model'\nimport { parseStructureDefinition, type SectionKind } from '../sections'\n\n/** Injected transport — runs a read-only Cypher query and returns its rows. */\nexport type SecQuery = (\n cypher: string,\n params?: Record<string, unknown>\n) => Promise<Array<Record<string, unknown>>>\n\n/** One navigable section of a filing (a `Structure` + its facts). */\nexport interface SecSection {\n /** `Structure.identifier` — the section id + the anchor for its associations. */\n id: string\n /** Human title, e.g. \"Consolidated Balance Sheets\" (definition prefix stripped). */\n title: string\n /** Coarse grouping for the table of contents. */\n kind: SectionKind\n /** The full role definition (e.g. \"9952153 - Statement - …\"), for hover/context. */\n definition: string | null\n /** `canonical_type` when the section is a recognized core statement, else null. */\n canonicalType: string | null\n /** Filing sequence (position in the ordered section list). */\n order: number\n /** `FactSet.identifier`s whose facts belong to this section. */\n factsetIds: string[]\n}\n\n/**\n * A report's own label linkbase, resolved once at shell time: element URI →\n * (label-role URI → label text). The SEC graph anchors each label to the filer's\n * per-report extension taxonomy and tags the edge with the element it labels\n * (`element_uri`), so this is the exact, report-scoped label set — free of the\n * cross-filer collisions on the shared, content-addressed `Label` pool. Keyed by\n * URI (not qname) so filer-extension elements resolve too.\n */\nexport interface ReportLabels {\n byElement: Map<string, Map<string, string>>\n}\n\n/** The fast first read: entity + the ordered section list + the label dictionary. */\nexport interface SecReportShell {\n reportId: string\n entity: EntityInfo | null\n sections: SecSection[]\n labels: ReportLabels\n}\n\n// ── Cypher ────────────────────────────────────────────────────────────────────\n\nconst ENTITY_META_Q = `\nMATCH (ent:Entity)-[:ENTITY_HAS_REPORT]->(r:Report {identifier: $rid})\nRETURN ent.identifier AS entity_id, ent.name AS entity_name,\n ent.legal_name AS legal_name, ent.cik AS cik, ent.ticker AS ticker,\n r.form AS form, r.report_date AS report_date`\n\n// Structures reachable from this report's facts, with their factsets. Dimensional\n// facts belong to the same factsets as their consolidated totals, so no\n// `has_dimensions` filter is needed — dropping it also surfaces sections whose\n// content is entirely dimensional (e.g. Schedule II). ORDER BY the alias (Kùzu\n// requires it once `collect` aggregates).\nconst SECTIONS_Q = `\nMATCH (r:Report {identifier: $rid})-[:REPORT_HAS_FACT]->(f:Fact)<-[:FACT_SET_CONTAINS_FACT]-(fs:FactSet)<-[:STRUCTURE_HAS_FACT_SET]-(s:Structure)\nRETURN s.identifier AS sid, s.canonical_type AS canonical_type,\n s.definition AS definition, s.number AS number,\n collect(DISTINCT fs.identifier) AS factsets\nORDER BY number`\n\n// The report's own label linkbase: every label its per-report extension taxonomy\n// defines, tagged with the element it labels (`element_uri`). One small (~1k-row)\n// query yields the report's exact label dictionary, keyed by the report-scoped\n// `element_uri` join key. See the sec-label-scoping design note.\nconst LABELS_Q = `\nMATCH (r:Report {identifier: $rid})-[:REPORT_USES_TAXONOMY]->(:Taxonomy)-[tl:TAXONOMY_HAS_LABEL]->(l:Label)\nWHERE tl.element_uri IS NOT NULL\nRETURN tl.element_uri AS element_uri, l.type AS role, l.value AS value`\n\n// Facts for one factset. Anchored on the factset PK; dimensional and consolidated\n// facts alike come through — the pivot engine keys cells by the full aspect\n// signature (element + period + dimensional coordinate), so segment/component\n// breakdowns no longer collide with the total. Element type signals\n// (`item_type`, `is_shares`) drive the value's numeric kind (monetary / per-share\n// / shares). `WHERE f.value IS NOT NULL` + `LIMIT` keep it on the fast path and\n// retain text facts (Cover Page etc.).\nconst FACTS_Q = `\nMATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact)-[:FACT_HAS_ELEMENT]->(e:Element),\n (f)-[:FACT_HAS_PERIOD]->(p:Period)\nWHERE f.value IS NOT NULL\nRETURN f.identifier AS fid, e.qname AS qname, e.uri AS euri, e.name AS ename, e.balance AS balance,\n e.period_type AS e_period_type, e.is_abstract AS is_abstract, e.is_numeric AS is_numeric,\n e.item_type AS item_type, e.is_shares AS is_shares,\n f.numeric_value AS numeric_value, f.value AS raw_value, f.decimals AS decimals,\n p.identifier AS pid, p.period_type AS period_type,\n p.start_date AS start_date, p.end_date AS end_date\nLIMIT 2000`\n\n// Unit measures for the same factset, as a separate required-join query — an\n// OPTIONAL unit join on the facts query alone cost ~12 s.\nconst UNITS_Q = `\nMATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact)-[:FACT_HAS_UNIT]->(u:Unit)\nWHERE f.value IS NOT NULL\nRETURN f.identifier AS fid, u.measure AS unit\nLIMIT 2000`\n\n// Dimensional qualifiers for the same factset — again a separate required-join\n// query (never OPTIONAL) so a fact with no dimensions simply contributes no rows.\n// One row per (fact, axis); a multi-axis fact yields several, merged client-side.\nconst DIMS_Q = `\nMATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact)-[:FACT_HAS_DIMENSION]->(d:Dimension)\nWHERE f.value IS NOT NULL\nRETURN f.identifier AS fid, d.axis AS axis, d.member AS member,\n d.axis_uri AS axis_uri, d.member_uri AS member_uri,\n d.is_explicit AS is_explicit, d.is_typed AS is_typed\nLIMIT 4000`\n\n// The presentation + calculation networks for one section, anchored on the\n// Structure PK. `association_type` is `Presentation` / `Calculation`. Element\n// names + `is_abstract` come along so presentation-only nodes (abstract section\n// headers, which carry no facts) can be registered — without them the projection\n// can't tell a header from a concrete line and mis-orders it.\nconst ASSOC_Q = `\nMATCH (s:Structure {identifier: $sid})-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association),\n (a)-[:ASSOCIATION_HAS_FROM_ELEMENT]->(pe:Element),\n (a)-[:ASSOCIATION_HAS_TO_ELEMENT]->(ce:Element)\nRETURN a.association_type AS association_type, a.order_value AS order_value, a.weight AS weight,\n pe.qname AS parent, pe.uri AS parent_uri, pe.name AS parent_name, pe.is_abstract AS parent_abstract,\n ce.qname AS child, ce.uri AS child_uri, ce.name AS child_name, ce.is_abstract AS child_abstract`\n\n// ── Row helpers ────────────────────────────────────────────────────────────────\n\nfunction str(row: Record<string, unknown>, key: string): string | null {\n const v = row[key]\n return typeof v === 'string' && v !== '' ? v : v == null ? null : String(v)\n}\n\nfunction num(row: Record<string, unknown>, key: string): number | null {\n const v = row[key]\n if (v === null || v === undefined || v === '') return null\n const n = typeof v === 'number' ? v : Number(v)\n return Number.isNaN(n) ? null : n\n}\n\nfunction bool(row: Record<string, unknown>, key: string): boolean {\n const v = row[key]\n return v === true || v === 'true'\n}\n\nfunction periodType(raw: string | null): PeriodType | null {\n return raw === 'instant' || raw === 'duration' ? raw : null\n}\n\n/**\n * A prefixed qname for a dimension axis/member from its versioned XBRL IRI + local\n * name (`http://fasb.org/us-gaap/2025#…Member` + `…Member` → `us-gaap:…Member`).\n * The graph gives axis/member as bare local names; this keeps them consistent with\n * the `Element.qname`s used in the presentation network (so member ordering lines\n * up), and cell matching is internally consistent regardless (row + column derive\n * from the same mapping).\n */\nfunction xbrlQname(uri: string | null, local: string | null): string {\n if (local) {\n const ns = (uri ?? '').split('#')[0]\n if (/fasb\\.org\\/us-gaap/.test(ns)) return `us-gaap:${local}`\n if (/fasb\\.org\\/srt/.test(ns)) return `srt:${local}`\n if (/xbrl\\.sec\\.gov\\/dei/.test(ns)) return `dei:${local}`\n if (/robosystems\\.ai\\/taxonomy\\/rs-gaap/.test(ns)) return `rs-gaap:${local}`\n return local\n }\n return uri ? toQname(uri) : ''\n}\n\n/** Humanize an axis/member local name, dropping the XBRL `Axis`/`Member`/`Domain` suffix. */\nfunction dimLabel(local: string | null): string {\n if (!local) return ''\n return humanize(local.replace(/(Axis|Member|Domain)$/, '')) || humanize(local)\n}\n\n// ── Report-scoped labels ─────────────────────────────────────────────────────\n\n/** XBRL standard label role — the default display label. */\nconst STANDARD_LABEL_ROLE = 'http://www.xbrl.org/2003/role/label'\n/** Terse label role — the fallback when a concept has no standard label. */\nconst TERSE_LABEL_ROLE = 'http://www.xbrl.org/2003/role/terseLabel'\n\n/**\n * XBRL standard labels tag structural elements with a bracketed role suffix —\n * `Land [Member]`, `Operating Expenses [Abstract]`, and likewise `[Axis]`,\n * `[Table]`, `[Line Items]`, `[Domain]`. That tag is metadata, not part of the\n * display name, so strip a trailing one. If stripping would empty the label\n * (a label that is only the tag), keep the original.\n */\nconst ROLE_SUFFIX_RE = /\\s*\\[(?:Abstract|Axis|Member|Table|Line Items|Domain)\\]\\s*$/\nfunction stripRoleSuffix(label: string): string {\n const stripped = label.replace(ROLE_SUFFIX_RE, '').trim()\n return stripped || label\n}\n\n/** Build the report's element-URI → (role → value) label dictionary from LABELS_Q rows. */\nfunction buildReportLabels(rows: Array<Record<string, unknown>>): ReportLabels {\n const byElement = new Map<string, Map<string, string>>()\n for (const row of rows) {\n const uri = str(row, 'element_uri')\n const value = str(row, 'value')\n if (!uri || !value) continue\n const role = str(row, 'role') ?? STANDARD_LABEL_ROLE\n let roles = byElement.get(uri)\n if (!roles) {\n roles = new Map()\n byElement.set(uri, roles)\n }\n roles.set(role, value)\n }\n return { byElement }\n}\n\n/**\n * The report's label for an element (by URI), preferring `preferredRole` (a\n * presentation arc's periodStart/periodEnd/total variant) when supplied, then\n * the standard label, then terse — with the XBRL `[Member]`/`[Axis]`/… role tag\n * stripped for display. Returns null when the report defined none — the caller\n * then humanizes the qname as a last resort.\n */\nfunction labelFor(\n labels: ReportLabels,\n uri: string | null,\n preferredRole?: string | null\n): string | null {\n if (!uri) return null\n const roles = labels.byElement.get(uri)\n if (!roles) return null\n const resolved =\n (preferredRole ? roles.get(preferredRole) : undefined) ??\n roles.get(STANDARD_LABEL_ROLE) ??\n roles.get(TERSE_LABEL_ROLE)\n return resolved ? stripRoleSuffix(resolved) : null\n}\n\n/**\n * Classify an element's numeric kind from its XBRL `item_type` (+ `is_shares`).\n * Per-share and share counts opt out of monetary rescaling; strings/text are not\n * numeric. Checked before monetary because share/per-share types are also numeric.\n */\nfunction deriveNumericKind(row: Record<string, unknown>): NumericKind | undefined {\n const itemType = str(row, 'item_type') ?? ''\n if (/perShareItemType/i.test(itemType)) return 'perShare'\n if (/sharesItemType/i.test(itemType) || bool(row, 'is_shares')) return 'shares'\n // A percentItemType stores a decimal fraction (0.10 → 10%); a pureItemType is a\n // bare dimensionless ratio (2.5 debt-to-equity), NOT a percentage.\n if (/percentItemType/i.test(itemType)) return 'percent'\n if (/pureItemType/i.test(itemType)) return 'pure'\n if (/monetaryItemType/i.test(itemType)) return 'monetary'\n if (/integerItemType/i.test(itemType)) return 'integer'\n if (!bool(row, 'is_numeric')) return undefined\n // No item_type (older captures): a debit/credit balance marks a monetary item.\n const balance = str(row, 'balance')\n return balance === 'debit' || balance === 'credit' ? 'monetary' : 'other'\n}\n\n// ── Shell ───────────────────────────────────────────────────────────────────\n\nfunction mapEntity(row: Record<string, unknown> | undefined): EntityInfo | null {\n if (!row) return null\n const id = str(row, 'entity_id')\n if (!id) return null\n return {\n id,\n name: str(row, 'entity_name') ?? str(row, 'legal_name') ?? 'Entity',\n legalName: str(row, 'legal_name'),\n country: null,\n }\n}\n\n/** Fetch the entity + ordered section list for a report (the fast first read). */\nexport async function fetchSecReportShell(\n query: SecQuery,\n reportId: string\n): Promise<SecReportShell> {\n const [entityRows, sectionRows, labelRows] = await Promise.all([\n query(ENTITY_META_Q, { rid: reportId }),\n query(SECTIONS_Q, { rid: reportId }),\n // Report-scoped labels are an enhancement, not a requirement. A graph that\n // predates the `TAXONOMY_HAS_LABEL.element_uri` ingest change binder-errors on\n // LABELS_Q; swallow that so the shell still loads and labels fall back to the\n // humanized qname. This lets the viewer ship ahead of the SEC reprocess and\n // light up automatically once the graph carries element_uri.\n query(LABELS_Q, { rid: reportId }).catch(() => []),\n ])\n\n const sections: SecSection[] = sectionRows\n .map((row, order): SecSection => {\n const { title, kind } = parseStructureDefinition(\n str(row, 'definition'),\n str(row, 'canonical_type')\n )\n const factsets = Array.isArray(row.factsets)\n ? (row.factsets as unknown[]).filter((v): v is string => typeof v === 'string')\n : []\n return {\n id: str(row, 'sid') ?? '',\n title,\n kind,\n definition: str(row, 'definition'),\n canonicalType: str(row, 'canonical_type'),\n order,\n factsetIds: factsets,\n }\n })\n .filter((s) => s.id && s.factsetIds.length > 0)\n\n return {\n reportId,\n entity: mapEntity(entityRows[0]),\n sections,\n labels: buildReportLabels(labelRows),\n }\n}\n\n// ── Single section ────────────────────────────────────────────────────────────\n\nfunction accumulateElement(\n elements: Record<string, ElementInfo>,\n row: Record<string, unknown>,\n labels: ReportLabels\n) {\n const q = str(row, 'qname')\n if (!q || elements[q]) return\n const balance = str(row, 'balance')\n const ename = str(row, 'ename')\n elements[q] = {\n id: q,\n qname: q,\n // Prefer the report's own label (resolved from its per-report taxonomy);\n // humanizing the element name is the fallback when the report defined none.\n label: labelFor(labels, str(row, 'euri')) ?? (ename ? humanize(ename) : humanize(q)),\n balance: balance === 'debit' || balance === 'credit' ? balance : null,\n periodType: periodType(str(row, 'e_period_type')),\n abstract: bool(row, 'is_abstract'),\n monetary: bool(row, 'is_numeric'),\n numericKind: deriveNumericKind(row),\n }\n}\n\n/**\n * Register a presentation-network element that has no facts of its own — chiefly\n * an abstract section header. Fact-bearing elements are already registered from\n * the facts query and take precedence (this no-ops on existing keys); this fills\n * in the abstract headers so the projection renders them as headers above their\n * section rather than as empty concrete rows below it. Abstract labels drop the\n * XBRL `Abstract` suffix (`OperatingExpensesAbstract` → `Operating Expenses`).\n */\nfunction registerPresentationElement(\n elements: Record<string, ElementInfo>,\n qname: string | null,\n uri: string | null,\n name: string | null,\n isAbstract: boolean,\n labels: ReportLabels\n): void {\n if (!qname || elements[qname]) return\n // Prefer the report's own label; else humanize the name (abstract headers drop\n // the XBRL `Abstract` suffix: `OperatingExpensesAbstract` → `Operating Expenses`).\n const humanized = name\n ? humanize(isAbstract ? name.replace(/Abstract$/, '') : name)\n : humanize(qname)\n elements[qname] = {\n id: qname,\n qname,\n label: labelFor(labels, uri) ?? humanized,\n balance: null,\n periodType: null,\n abstract: isAbstract,\n monetary: false,\n }\n}\n\nfunction accumulatePeriod(periods: Record<string, PeriodInfo>, row: Record<string, unknown>) {\n const id = str(row, 'pid')\n if (!id || periods[id]) return\n const type = periodType(str(row, 'period_type')) ?? 'duration'\n const startDate = str(row, 'start_date')\n const endDate = str(row, 'end_date')\n periods[id] = {\n id,\n type,\n instant: type === 'instant' ? endDate : null,\n startDate,\n endDate,\n end: endDate ?? '',\n }\n}\n\n/**\n * Load one section into a single-section `NormalizedReport`. All of the\n * section's facts are re-keyed to the structure id as their `factSet`, so the\n * projection groups them as one Information Block regardless of how many raw\n * FactSets the filing split them across.\n */\nexport async function fetchSecSection(\n query: SecQuery,\n shell: SecReportShell,\n section: SecSection\n): Promise<NormalizedReport> {\n const [factRowGroups, unitRowGroups, dimRowGroups, assocRows] = await Promise.all([\n Promise.all(section.factsetIds.map((fsid) => query(FACTS_Q, { fsid }))),\n Promise.all(section.factsetIds.map((fsid) => query(UNITS_Q, { fsid }))),\n Promise.all(section.factsetIds.map((fsid) => query(DIMS_Q, { fsid }))),\n query(ASSOC_Q, { sid: section.id }),\n ])\n\n const unitByFid = new Map<string, string>()\n for (const row of unitRowGroups.flat()) {\n const fid = str(row, 'fid')\n const measure = str(row, 'unit')\n if (fid && measure) unitByFid.set(fid, measure)\n }\n\n // One fact can carry several axes; collect its qualifiers (ordered by axis).\n const dimsByFid = new Map<string, DimensionQualifier[]>()\n for (const row of dimRowGroups.flat()) {\n const fid = str(row, 'fid')\n if (!fid) continue\n const memberLocal = str(row, 'member')\n // Axis/member are elements too — prefer the report's own labels (keyed by the\n // element URI, which matches the dimension's axis_uri/member_uri), humanizing\n // the local name only as a fallback.\n const axisUri = str(row, 'axis_uri')\n const memberUri = str(row, 'member_uri')\n const qual: DimensionQualifier = {\n axis: xbrlQname(axisUri, str(row, 'axis')),\n member: memberLocal ? xbrlQname(memberUri, memberLocal) : null,\n axisLabel: labelFor(shell.labels, axisUri) ?? dimLabel(str(row, 'axis')),\n memberLabel: labelFor(shell.labels, memberUri) ?? dimLabel(memberLocal),\n explicit: bool(row, 'is_explicit'),\n typedValue: bool(row, 'is_typed') ? str(row, 'member') : null,\n }\n const list = dimsByFid.get(fid) ?? []\n list.push(qual)\n dimsByFid.set(fid, list)\n }\n for (const list of dimsByFid.values()) list.sort((a, b) => a.axis.localeCompare(b.axis))\n\n const elements: Record<string, ElementInfo> = {}\n const periods: Record<string, PeriodInfo> = {}\n const units: Record<string, UnitInfo> = {}\n const facts: Fact[] = []\n const seenFacts = new Set<string>()\n\n for (const row of factRowGroups.flat()) {\n const fid = str(row, 'fid')\n const element = str(row, 'qname')\n const period = str(row, 'pid')\n if (!fid || !element || !period || seenFacts.has(fid)) continue\n seenFacts.add(fid)\n\n accumulateElement(elements, row, shell.labels)\n accumulatePeriod(periods, row)\n\n const measure = unitByFid.get(fid) ?? null\n if (measure && !units[measure]) {\n const compact = toQname(measure)\n units[measure] = {\n id: measure,\n measure: compact,\n label: compact.includes(':') ? (compact.split(':').pop() as string) : compact,\n symbol: currencySymbolFor(compact),\n }\n }\n\n const value = num(row, 'numeric_value')\n facts.push({\n id: fid,\n element,\n period,\n unit: measure,\n entity: shell.entity?.id ?? null,\n factSet: section.id,\n value,\n decimals: str(row, 'decimals'),\n textValue: value === null ? str(row, 'raw_value') : null,\n dimensions: dimsByFid.get(fid),\n })\n }\n\n const calcAssociations: CalcAssociation[] = []\n const presAssociations: PresAssociation[] = []\n for (const row of assocRows) {\n const parent = str(row, 'parent')\n const child = str(row, 'child')\n if (!parent || !child) continue\n // Register presentation-only elements (abstract section headers carry no\n // facts, so the facts query never saw them). Fact-bearing elements are\n // already registered and unaffected — registration no-ops on existing keys.\n registerPresentationElement(\n elements,\n parent,\n str(row, 'parent_uri'),\n str(row, 'parent_name'),\n bool(row, 'parent_abstract'),\n shell.labels\n )\n registerPresentationElement(\n elements,\n child,\n str(row, 'child_uri'),\n str(row, 'child_name'),\n bool(row, 'child_abstract'),\n shell.labels\n )\n const order = num(row, 'order_value') ?? 0\n const type = str(row, 'association_type')?.toLowerCase()\n if (type === 'calculation') {\n calcAssociations.push({\n parent,\n child,\n weight: num(row, 'weight') ?? 1,\n order,\n role: null,\n structure: section.id,\n })\n } else if (type === 'presentation') {\n presAssociations.push({ parent, child, order, role: null, structure: section.id })\n }\n }\n\n const informationBlock: InformationBlock = {\n id: section.id,\n blockType: section.canonicalType ?? '',\n factSet: section.id,\n label: section.title,\n structureId: section.id,\n }\n const structure: StructureInfo = {\n id: section.id,\n blockType: section.canonicalType ?? '',\n roleUri: null,\n structureName: section.title,\n definition: section.definition,\n kind: section.kind,\n order: section.order,\n }\n\n return {\n reportId: shell.reportId,\n reportIri: null,\n entity: shell.entity,\n informationBlocks: [informationBlock],\n structures: [structure],\n facts,\n elements,\n periods,\n units,\n calcAssociations,\n presAssociations,\n }\n}\n\n/** Merge single-section reports into one whole-report model (order preserved). */\nexport function mergeSecSections(\n shell: SecReportShell,\n sections: NormalizedReport[]\n): NormalizedReport {\n const elements: Record<string, ElementInfo> = {}\n const periods: Record<string, PeriodInfo> = {}\n const units: Record<string, UnitInfo> = {}\n const informationBlocks: InformationBlock[] = []\n const structures: StructureInfo[] = []\n const facts: Fact[] = []\n const calcAssociations: CalcAssociation[] = []\n const presAssociations: PresAssociation[] = []\n\n for (const part of sections) {\n Object.assign(elements, part.elements)\n Object.assign(periods, part.periods)\n Object.assign(units, part.units)\n informationBlocks.push(...part.informationBlocks)\n structures.push(...part.structures)\n facts.push(...part.facts)\n calcAssociations.push(...part.calcAssociations)\n presAssociations.push(...part.presAssociations)\n }\n\n return {\n reportId: shell.reportId,\n reportIri: null,\n entity: shell.entity,\n informationBlocks,\n structures,\n facts,\n elements,\n periods,\n units,\n calcAssociations,\n presAssociations,\n }\n}\n","/**\n * The cypher adapter — a whole-report `ReportAdapter` over the live SEC graph.\n *\n * This is a convenience wrapper: it loads the section list, then every section,\n * and merges them into one `NormalizedReport`. Apps that want responsive,\n * lazy-per-section loading should call `fetchSecReportShell` + `fetchSecSection`\n * directly (see `./sec`) rather than materializing a whole filing up front.\n */\nimport type { SecQuery } from './sec'\nimport { fetchSecReportShell, fetchSecSection, mergeSecSections } from './sec'\nimport type { ReportAdapter } from './types'\n\nexport interface CypherAdapterConfig {\n /** Injected transport over `POST /v1/graphs/{graphId}/query` (auth lives here). */\n query: SecQuery\n /** The report to materialize — a `Report.identifier`. */\n reportId: string\n}\n\nexport function cypherAdapter(config: CypherAdapterConfig): ReportAdapter {\n return {\n source: `sec:${config.reportId}`,\n load: async () => {\n const shell = await fetchSecReportShell(config.query, config.reportId)\n const sections = await Promise.all(\n shell.sections.map((section) => fetchSecSection(config.query, shell, section))\n )\n return mergeSecSections(shell, sections)\n },\n }\n}\n","/**\n * The shared quad-store → `NormalizedReport` traversal.\n *\n * An adapter fills an N3 quad `Store` from its source, then hands it here. The\n * store is read as a **union** across its graphs (`graph = null`) — the\n * scene/boundary/projection partition is a publication concern, not a rendering\n * one, so the join is identical however the quads arrived (a dataset-form\n * JSON-LD holon, a flat graph, …). No SPARQL engine is required; only store\n * traversal. The only per-source code is how the store gets filled.\n */\nimport { DataFactory, Store } from 'n3'\nimport { IRI, humanize, qname } from '../constants'\nimport type {\n CalcAssociation,\n DimensionQualifier,\n ElementInfo,\n EntityInfo,\n Fact,\n InformationBlock,\n NormalizedReport,\n NumericKind,\n PeriodInfo,\n PeriodType,\n PresAssociation,\n StructureInfo,\n UnitInfo,\n} from '../model'\nimport { parseStructureName } from '../sections'\n\n/**\n * The holon's value-domain `rs:itemType` maps 1:1 onto the numeric kinds that\n * drive formatting/scale. perShare and shares never rescale by the statement\n * factor (else e.g. an EPS of $0.04 in a thousands-scaled statement rounds to\n * 0); percent/pure/integer format distinctly. Text/date/boolean/decimal have no\n * numeric kind — the formatter falls back to monetary-or-other.\n */\nfunction numericKindFromItemType(itemType: string | undefined): NumericKind | undefined {\n switch (itemType) {\n case 'monetary':\n return 'monetary'\n case 'perShare':\n return 'perShare'\n case 'shares':\n return 'shares'\n case 'percent':\n return 'percent'\n case 'pure':\n return 'pure'\n case 'integer':\n return 'integer'\n default:\n return undefined\n }\n}\n\nconst { namedNode } = DataFactory\n\nfunction makeReaders(store: Store) {\n const objects = (s: string, p: string) => store.getObjects(namedNode(s), namedNode(p), null)\n const firstValue = (s: string, p: string): string | null => {\n const os = objects(s, p)\n return os.length ? os[0].value : null\n }\n const subjectsOfType = (type: string): string[] =>\n store.getSubjects(namedNode(IRI.type), namedNode(type), null).map((t) => t.value)\n return { objects, firstValue, subjectsOfType }\n}\n\nfunction toNumber(raw: string | null): number | null {\n if (raw === null || raw === '') return null\n const n = Number(raw)\n return Number.isNaN(n) ? null : n\n}\n\n/** Traverse a populated quad `Store` into the normalized report model. */\nexport function parseStore(store: Store): NormalizedReport {\n const { objects, firstValue, subjectsOfType } = makeReaders(store)\n\n // ── Elements ──\n const elements: Record<string, ElementInfo> = {}\n for (const id of subjectsOfType(IRI.Element)) {\n const balance = firstValue(id, IRI.balance)\n const periodType = firstValue(id, IRI.periodType)\n const itemType = firstValue(id, IRI.itemType) ?? undefined\n elements[id] = {\n id,\n qname: qname(id),\n label: firstValue(id, IRI.prefLabel) ?? humanize(id),\n balance: balance === 'debit' || balance === 'credit' ? balance : null,\n periodType: periodType === 'instant' || periodType === 'duration' ? periodType : null,\n abstract: firstValue(id, IRI.abstract) === 'true',\n monetary: firstValue(id, IRI.monetary) === 'true',\n itemType,\n numericKind: numericKindFromItemType(itemType),\n }\n }\n\n // ── Periods ──\n const periods: Record<string, PeriodInfo> = {}\n for (const id of subjectsOfType(IRI.Period)) {\n const declared = firstValue(id, IRI.periodType)\n const instant = firstValue(id, IRI.instant)\n const startDate = firstValue(id, IRI.startDate)\n const endDate = firstValue(id, IRI.endDate)\n const type: PeriodType =\n declared === 'instant'\n ? 'instant'\n : declared === 'duration'\n ? 'duration'\n : instant\n ? 'instant'\n : 'duration'\n const end = (type === 'instant' ? instant : endDate) ?? instant ?? endDate ?? ''\n periods[id] = { id, type, instant, startDate, endDate, end }\n }\n\n // ── Units ──\n const units: Record<string, UnitInfo> = {}\n for (const id of subjectsOfType(IRI.Unit)) {\n const measureTerm = objects(id, IRI.measure)[0]\n const measure = measureTerm ? qname(measureTerm.value) : 'unknown'\n units[id] = {\n id,\n measure,\n label: measure.includes(':') ? (measure.split(':').pop() as string) : measure,\n }\n }\n\n // ── Entity ──\n let entity: EntityInfo | null = null\n const entityIds = subjectsOfType(IRI.Entity)\n if (entityIds.length) {\n const id = entityIds[0]\n entity = {\n id,\n name: firstValue(id, IRI.prefLabel) ?? firstValue(id, IRI.legalName) ?? 'Entity',\n legalName: firstValue(id, IRI.legalName),\n country: firstValue(id, IRI.country),\n }\n }\n\n // ── Facts ──\n const facts: Fact[] = []\n for (const id of subjectsOfType(IRI.Fact)) {\n // Dimensional coordinate (rs:dimension -> rs:Dimension {axis, member, ...}).\n // Without this every fact reads as consolidated, so a segment breakdown\n // collapses onto the face-statement cell and can overwrite the real total.\n const dimensions: DimensionQualifier[] = []\n for (const d of objects(id, IRI.dimension)) {\n const axis = firstValue(d.value, IRI.axis)\n if (!axis) continue\n const member = firstValue(d.value, IRI.member)\n const typedValue = firstValue(d.value, IRI.typedValue)\n dimensions.push({\n axis,\n member: member ?? null,\n axisLabel: elements[axis]?.label ?? humanize(axis),\n memberLabel: member ? (elements[member]?.label ?? humanize(member)) : (typedValue ?? ''),\n explicit: firstValue(d.value, IRI.isExplicit) === 'true',\n typedValue: typedValue ?? null,\n })\n }\n // A fact can belong to several factSets — a summary concept (Total Assets,\n // Net Income) is presented in more than one structure. Read them ALL; taking\n // only the first (firstValue) drops the fact from every section but one.\n const factSets = objects(id, IRI.factSet).map((o) => o.value)\n facts.push({\n id,\n element: firstValue(id, IRI.element) ?? '',\n period: firstValue(id, IRI.period) ?? '',\n unit: firstValue(id, IRI.unit),\n entity: firstValue(id, IRI.entity),\n factSet: factSets[0] ?? null,\n factSets: factSets.length ? factSets : undefined,\n value: toNumber(firstValue(id, IRI.numericValue)),\n textValue: firstValue(id, IRI.stringValue),\n decimals: firstValue(id, IRI.decimals),\n dimensions: dimensions.length ? dimensions : undefined,\n })\n }\n\n // ── Information Blocks ──\n const informationBlocks: InformationBlock[] = []\n for (const id of subjectsOfType(IRI.InformationBlock)) {\n informationBlocks.push({\n id,\n blockType: firstValue(id, IRI.blockType) ?? '',\n // Match a block to its structure by identity (the rs:structure link),\n // not by a semantic blockType — a full-fidelity holon carries no\n // block-type classification, so structureId is how row order is found.\n structureId: firstValue(id, IRI.structure) ?? undefined,\n factSet: firstValue(id, IRI.factSet),\n label: firstValue(id, IRI.prefLabel),\n })\n }\n\n // ── Structures + association → structure membership ──\n const structures: StructureInfo[] = []\n const assocStructure = new Map<string, string>()\n for (const id of subjectsOfType(IRI.Structure)) {\n // Split the holon's rs:structureName the same way the SEC adapter splits a\n // role definition — a clean title + the full definition + a kind — so File\n // and SEC modes render identical section labels. Non-SEC names pass through.\n const { definition, title, kind } = parseStructureName(firstValue(id, IRI.structureName))\n structures.push({\n id,\n blockType: firstValue(id, IRI.blockType) ?? '',\n roleUri: firstValue(id, IRI.roleUri),\n structureName: title,\n definition,\n kind,\n // Filing sequence (SEC role-definition number) so buildPivots orders all\n // sections by the filer's order rather than the fixed four-primary fallback.\n order: toNumber(firstValue(id, IRI.structureOrder)) ?? undefined,\n })\n for (const assoc of objects(id, IRI.hasAssociation)) {\n assocStructure.set(assoc.value, id)\n }\n }\n\n // ── Associations ──\n const calcAssociations: CalcAssociation[] = []\n const presAssociations: PresAssociation[] = []\n for (const id of subjectsOfType(IRI.Association)) {\n const parent = firstValue(id, IRI.from)\n const child = firstValue(id, IRI.to)\n if (!parent || !child) continue\n const type = firstValue(id, IRI.associationType)\n const order = toNumber(firstValue(id, IRI.order)) ?? 0\n const role = firstValue(id, IRI.role)\n const structure = assocStructure.get(id) ?? null\n if (type === 'calculation') {\n calcAssociations.push({\n parent,\n child,\n weight: toNumber(firstValue(id, IRI.weight)) ?? 1,\n order,\n role,\n structure,\n })\n } else if (type === 'presentation') {\n presAssociations.push({ parent, child, order, role, structure })\n }\n }\n\n // ── Report IRI / id ──\n // Prefer the named-graph name (`<report>#scene` → `<report>`) — present in a\n // dataset-form holon. Fall back to the `rs:Report` subject so a flat,\n // single-graph document still resolves its identity.\n let reportIri: string | null = null\n for (const graph of store.getGraphs(null, null, null)) {\n const hash = graph.value.indexOf('#')\n if (hash > 0) {\n reportIri = graph.value.slice(0, hash)\n break\n }\n }\n if (!reportIri) {\n const reports = subjectsOfType(IRI.Report)\n reportIri = reports.length ? reports[0] : null\n }\n const reportId = reportIri ? (reportIri.split('/').pop() ?? null) : null\n\n return {\n reportId,\n reportIri,\n entity,\n informationBlocks,\n structures,\n facts,\n elements,\n periods,\n units,\n calcAssociations,\n presAssociations,\n }\n}\n","/**\n * The `holon.jsonld` adapter — offline, no backend, no auth.\n *\n * The canonical, API-native holon: **dataset-form JSON-LD** carrying the three\n * named graphs (`#scene`, `#boundary`, `#projection`) as `@id` + nested\n * `@graph`. JSON is native to the RoboSystems JSON API, so this is the one\n * holon file format.\n *\n * N3.js doesn't parse JSON-LD, so this adapter uses the `jsonld` processor to\n * expand the document to N-Quads (which preserves the named-graph labels),\n * parses those into an N3 quad `Store`, and delegates to the shared\n * `parseStore` traversal (`store.ts`).\n */\nimport type { JsonLdDocument } from 'jsonld'\nimport jsonld from 'jsonld'\nimport { Parser, Store } from 'n3'\nimport type { NormalizedReport } from '../model'\nimport { parseStore } from './store'\nimport type { ReportAdapter } from './types'\n\n/** Parse a `holon.jsonld` document (string or parsed object) into the model. */\nexport async function parseJsonld(doc: string | object): Promise<NormalizedReport> {\n const json = (typeof doc === 'string' ? JSON.parse(doc) : doc) as JsonLdDocument\n // `toRDF` with the n-quads format returns a serialized string; each quad\n // carries its graph label, so the holon's named graphs survive the expansion.\n const nquads = (await jsonld.toRDF(json, { format: 'application/n-quads' })) as string\n const store = new Store(new Parser({ format: 'application/n-quads' }).parse(nquads))\n return parseStore(store)\n}\n\n/** A `ReportAdapter` over an in-memory `holon.jsonld` document. */\nexport function jsonldFileAdapter(doc: string | object, source = 'holon.jsonld'): ReportAdapter {\n return {\n source,\n load: () => parseJsonld(doc),\n }\n}\n"]}
|
|
@@ -146,8 +146,14 @@ interface Fact {
|
|
|
146
146
|
unit: string | null;
|
|
147
147
|
/** Entity IRI. */
|
|
148
148
|
entity: string | null;
|
|
149
|
-
/** FactSet IRI — the grouping key shared with an Information Block.
|
|
149
|
+
/** FactSet IRI — the grouping key shared with an Information Block. `factSet`
|
|
150
|
+
* is the first; `factSets` carries all of them (see below). */
|
|
150
151
|
factSet: string | null;
|
|
152
|
+
/** Every FactSet a fact belongs to. A summary concept (Total Assets, Net
|
|
153
|
+
* Income) is presented in more than one structure, so it lands in each — the
|
|
154
|
+
* pivot matches a section by membership, not single-value equality. Absent when
|
|
155
|
+
* the adapter sets a single `factSet` (e.g. the SEC adapter re-keys per section). */
|
|
156
|
+
factSets?: string[];
|
|
151
157
|
value: number | null;
|
|
152
158
|
decimals: string | null;
|
|
153
159
|
/**
|
|
@@ -393,11 +399,23 @@ interface SecSection {
|
|
|
393
399
|
/** `FactSet.identifier`s whose facts belong to this section. */
|
|
394
400
|
factsetIds: string[];
|
|
395
401
|
}
|
|
396
|
-
/**
|
|
402
|
+
/**
|
|
403
|
+
* A report's own label linkbase, resolved once at shell time: element URI →
|
|
404
|
+
* (label-role URI → label text). The SEC graph anchors each label to the filer's
|
|
405
|
+
* per-report extension taxonomy and tags the edge with the element it labels
|
|
406
|
+
* (`element_uri`), so this is the exact, report-scoped label set — free of the
|
|
407
|
+
* cross-filer collisions on the shared, content-addressed `Label` pool. Keyed by
|
|
408
|
+
* URI (not qname) so filer-extension elements resolve too.
|
|
409
|
+
*/
|
|
410
|
+
interface ReportLabels {
|
|
411
|
+
byElement: Map<string, Map<string, string>>;
|
|
412
|
+
}
|
|
413
|
+
/** The fast first read: entity + the ordered section list + the label dictionary. */
|
|
397
414
|
interface SecReportShell {
|
|
398
415
|
reportId: string;
|
|
399
416
|
entity: EntityInfo | null;
|
|
400
417
|
sections: SecSection[];
|
|
418
|
+
labels: ReportLabels;
|
|
401
419
|
}
|
|
402
420
|
/** Fetch the entity + ordered section list for a report (the fast first read). */
|
|
403
421
|
declare function fetchSecReportShell(query: SecQuery, reportId: string): Promise<SecReportShell>;
|
|
@@ -464,4 +482,4 @@ declare function jsonldFileAdapter(doc: string | object, source?: string): Repor
|
|
|
464
482
|
/** Traverse a populated quad `Store` into the normalized report model. */
|
|
465
483
|
declare function parseStore(store: Store): NormalizedReport;
|
|
466
484
|
|
|
467
|
-
export { type AspectKey as A, type BalanceType as B, type CalcAssociation as C, type DimensionQualifier as D, type ElementInfo as E, type Fact as F,
|
|
485
|
+
export { type AspectKey as A, type BalanceType as B, type CalcAssociation as C, type DimensionQualifier as D, type ElementInfo as E, type Fact as F, jsonldFileAdapter as G, mergeSecSections as H, type InformationBlock as I, parseJsonld as J, parseStore as K, parseStructureDefinition as L, parseStructureName as M, type NumericKind as N, type PeriodInfo as P, type ReportAdapter as R, type SectionKind as S, type UnitInfo as U, type NormalizedReport as a, type PivotConfig as b, type PivotTable as c, type PivotRow as d, type CypherAdapterConfig as e, type EntityInfo as f, type PeriodType as g, type PivotCell as h, type PivotColumn as i, type PivotColumnHeader as j, type PivotSlicer as k, type PresAssociation as l, type ReportLabels as m, type ResolvedScale as n, type RowCell as o, type Scale as p, type SecQuery as q, type SecReportShell as r, type SecSection as s, type Statement as t, type StatementColumn as u, type StatementRow as v, type StructureInfo as w, cypherAdapter as x, fetchSecReportShell as y, fetchSecSection as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { N as NumericKind, P as PeriodInfo, E as ElementInfo, a as NormalizedReport, I as InformationBlock, b as PivotConfig, c as PivotTable, S as SectionKind, d as PivotRow, U as UnitInfo } from './index-
|
|
2
|
-
export { A as AspectKey, B as BalanceType, C as CalcAssociation, e as CypherAdapterConfig, D as DimensionQualifier, f as EntityInfo, F as Fact, g as PeriodType, h as PivotCell, i as PivotColumn, j as PivotColumnHeader, k as PivotSlicer, l as PresAssociation, R as ReportAdapter, m as
|
|
1
|
+
import { N as NumericKind, P as PeriodInfo, E as ElementInfo, a as NormalizedReport, I as InformationBlock, b as PivotConfig, c as PivotTable, S as SectionKind, d as PivotRow, U as UnitInfo } from './index-MeQYBvqk.js';
|
|
2
|
+
export { A as AspectKey, B as BalanceType, C as CalcAssociation, e as CypherAdapterConfig, D as DimensionQualifier, f as EntityInfo, F as Fact, g as PeriodType, h as PivotCell, i as PivotColumn, j as PivotColumnHeader, k as PivotSlicer, l as PresAssociation, R as ReportAdapter, m as ReportLabels, n as ResolvedScale, o as RowCell, p as Scale, q as SecQuery, r as SecReportShell, s as SecSection, t as Statement, u as StatementColumn, v as StatementRow, w as StructureInfo, x as cypherAdapter, y as fetchSecReportShell, z as fetchSecSection, G as jsonldFileAdapter, H as mergeSecSections, J as parseJsonld, K as parseStore, L as parseStructureDefinition, M as parseStructureName } from './index-MeQYBvqk.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import 'n3';
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatDate, BLOCK_TITLES, numericKindOf, humanizeDuration, formatValue, formatPeriod, isExternalFactUrl, BLOCK_ORDER, humanize, qname, currencySymbolFor } from './chunk-
|
|
2
|
-
export { BLOCK_ORDER, BLOCK_TITLES, NS, currencySymbolFor, cypherAdapter, fetchSecReportShell, fetchSecSection, formatDate, formatMoney, formatPeriod, formatValue, humanize, humanizeDuration, isExternalFactUrl, jsonldFileAdapter, mergeSecSections, numericKindOf, parseJsonld, parseStore, parseStructureDefinition, parseStructureName, qname } from './chunk-
|
|
1
|
+
import { formatDate, BLOCK_TITLES, numericKindOf, humanizeDuration, formatValue, formatPeriod, isExternalFactUrl, BLOCK_ORDER, humanize, qname, currencySymbolFor } from './chunk-XHHRSCHV.js';
|
|
2
|
+
export { BLOCK_ORDER, BLOCK_TITLES, NS, currencySymbolFor, cypherAdapter, fetchSecReportShell, fetchSecSection, formatDate, formatMoney, formatPeriod, formatValue, humanize, humanizeDuration, isExternalFactUrl, jsonldFileAdapter, mergeSecSections, numericKindOf, parseJsonld, parseStore, parseStructureDefinition, parseStructureName, qname } from './chunk-XHHRSCHV.js';
|
|
3
3
|
import { useState, useEffect, useMemo, useRef } from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -105,7 +105,11 @@ function coordinate(byAxis, axes) {
|
|
|
105
105
|
return axes.map((a) => `${a}=${byAxis.get(a)?.member ?? byAxis.get(a)?.typedValue ?? DOMAIN}`).join("|");
|
|
106
106
|
}
|
|
107
107
|
function sectionFacts(model, ib) {
|
|
108
|
-
|
|
108
|
+
const target = ib.factSet;
|
|
109
|
+
if (target === null) return [];
|
|
110
|
+
return model.facts.filter(
|
|
111
|
+
(f) => (f.factSets ?? (f.factSet !== null ? [f.factSet] : [])).includes(target)
|
|
112
|
+
);
|
|
109
113
|
}
|
|
110
114
|
function localName(qname2) {
|
|
111
115
|
return qname2.includes(":") ? qname2.split(":").pop() : qname2;
|