@robosystems/report-components 0.2.0 → 0.2.2

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.
@@ -1,2 +1,2 @@
1
- export { b as CypherAdapterConfig, R as ReportAdapter, g as SecQuery, h as SecReportShell, i as SecSection, l as cypherAdapter, m as fetchSecReportShell, n as fetchSecSection, o as jsonldFileAdapter, p as mergeSecSections, q as parseJsonld, r as parseStore, s as parseStructureDefinition } from '../index-D6FzPTm5.js';
1
+ export { e as CypherAdapterConfig, R as ReportAdapter, o as SecQuery, p as SecReportShell, q as SecSection, v as cypherAdapter, w as fetchSecReportShell, x as fetchSecSection, y as jsonldFileAdapter, z as mergeSecSections, G as parseJsonld, H as parseStore, J as parseStructureDefinition } from '../index-BS6_6h3l.js';
2
2
  import 'n3';
@@ -1,3 +1,3 @@
1
- export { cypherAdapter, fetchSecReportShell, fetchSecSection, jsonldFileAdapter, mergeSecSections, parseJsonld, parseStore, parseStructureDefinition } from '../chunk-POSLHOTN.js';
1
+ export { cypherAdapter, fetchSecReportShell, fetchSecSection, jsonldFileAdapter, mergeSecSections, parseJsonld, parseStore, parseStructureDefinition } from '../chunk-RQXAMFTZ.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -31,14 +31,18 @@ var IRI = {
31
31
  entity: NS.rs + "entity",
32
32
  factSet: NS.rs + "factSet",
33
33
  numericValue: NS.rs + "numericValue",
34
+ stringValue: NS.rs + "stringValue",
34
35
  decimals: NS.rs + "decimals",
35
36
  blockType: NS.rs + "blockType",
36
37
  associationType: NS.rs + "associationType",
37
38
  hasAssociation: NS.rs + "hasAssociation",
38
39
  roleUri: NS.rs + "roleUri",
40
+ structure: NS.rs + "structure",
39
41
  structureName: NS.rs + "structureName",
42
+ structureOrder: NS.rs + "structureOrder",
40
43
  abstract: NS.rs + "abstract",
41
44
  monetary: NS.rs + "monetary",
45
+ itemType: NS.rs + "itemType",
42
46
  legalName: NS.rs + "legalName",
43
47
  country: NS.rs + "country",
44
48
  // skos:
@@ -100,6 +104,99 @@ var BLOCK_TITLES = {
100
104
  equity_statement: "Statement of Changes in Equity"
101
105
  };
102
106
 
107
+ // src/format.ts
108
+ function formatMoney(value, opts = {}) {
109
+ if (value === null || value === void 0 || Number.isNaN(value)) return "\u2014";
110
+ const symbol = opts.currencySymbol ?? "$";
111
+ const abs = Math.abs(value).toLocaleString("en-US", {
112
+ minimumFractionDigits: 2,
113
+ maximumFractionDigits: 2
114
+ });
115
+ return value < 0 ? `${symbol}(${abs})` : `${symbol}${abs}`;
116
+ }
117
+ var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
118
+ function formatDate(iso) {
119
+ if (!iso) return "";
120
+ const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(iso);
121
+ if (!m) return iso;
122
+ const [, year, month, day] = m;
123
+ const idx = Number(month) - 1;
124
+ return `${MONTHS[idx] ?? month} ${Number(day)}, ${year}`;
125
+ }
126
+ function humanizeDuration(value) {
127
+ if (!value) return null;
128
+ const m = /^(-)?P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/.exec(
129
+ value.trim()
130
+ );
131
+ if (!m) return null;
132
+ const [, sign, y, mo, w, d, h, min, s] = m;
133
+ const parts = [];
134
+ const push = (n, unit) => {
135
+ if (n) parts.push(`${n} ${unit}${Number(n) === 1 ? "" : "s"}`);
136
+ };
137
+ push(y, "year");
138
+ push(mo, "month");
139
+ push(w, "week");
140
+ push(d, "day");
141
+ push(h, "hour");
142
+ push(min, "minute");
143
+ push(s, "second");
144
+ if (!parts.length) return null;
145
+ return `${sign ?? ""}${parts.join(" ")}`;
146
+ }
147
+ function formatPeriod(period) {
148
+ if (period.type === "instant") {
149
+ return `As of ${formatDate(period.instant ?? period.end)}`;
150
+ }
151
+ return `${formatDate(period.startDate)} \u2013 ${formatDate(period.endDate ?? period.end)}`;
152
+ }
153
+ function numericKindOf(el) {
154
+ return el.numericKind ?? (el.monetary ? "monetary" : "other");
155
+ }
156
+ var CURRENCY_SYMBOLS = {
157
+ USD: "$",
158
+ EUR: "\u20AC",
159
+ GBP: "\xA3",
160
+ JPY: "\xA5",
161
+ CNY: "\xA5",
162
+ CHF: "CHF ",
163
+ CAD: "CA$",
164
+ AUD: "A$",
165
+ HKD: "HK$",
166
+ INR: "\u20B9",
167
+ KRW: "\u20A9"
168
+ };
169
+ function currencySymbolFor(measure) {
170
+ if (!measure) return null;
171
+ const code = (measure.includes(":") ? measure.split(":").pop() : measure).toUpperCase();
172
+ if (CURRENCY_SYMBOLS[code]) return CURRENCY_SYMBOLS[code];
173
+ return /^[A-Z]{3}$/.test(code) ? `${code} ` : null;
174
+ }
175
+ function formatValue(value, fmt = {}) {
176
+ if (value === null || value === void 0 || Number.isNaN(value)) return "\u2014";
177
+ const kind = fmt.numericKind ?? "monetary";
178
+ const scale = kind === "monetary" ? fmt.scaleFactor ?? 1 : 1;
179
+ const scaled = kind === "percent" ? value * 100 : value / scale;
180
+ let minFrac = 0;
181
+ let maxFrac = 0;
182
+ if (kind === "perShare") {
183
+ minFrac = maxFrac = 2;
184
+ } else if (kind === "monetary") {
185
+ minFrac = maxFrac = scale > 1 ? 0 : 2;
186
+ } else if (kind === "percent") {
187
+ maxFrac = 2;
188
+ } else if (kind === "pure") {
189
+ maxFrac = 4;
190
+ }
191
+ const abs = Math.abs(scaled).toLocaleString("en-US", {
192
+ minimumFractionDigits: minFrac,
193
+ maximumFractionDigits: maxFrac
194
+ });
195
+ const symbol = kind === "monetary" || kind === "perShare" ? fmt.symbol ?? "" : "";
196
+ const suffix = kind === "percent" ? "%" : "";
197
+ return scaled < 0 ? `${symbol}(${abs}${suffix})` : `${symbol}${abs}${suffix}`;
198
+ }
199
+
103
200
  // src/adapters/sec.ts
104
201
  var ENTITY_META_Q = `
105
202
  MATCH (ent:Entity)-[:ENTITY_HAS_REPORT]->(r:Report {identifier: $rid})
@@ -107,32 +204,41 @@ RETURN ent.identifier AS entity_id, ent.name AS entity_name,
107
204
  ent.legal_name AS legal_name, ent.cik AS cik, ent.ticker AS ticker,
108
205
  r.form AS form, r.report_date AS report_date`;
109
206
  var SECTIONS_Q = `
110
- MATCH (r:Report {identifier: $rid})-[:REPORT_HAS_FACT]->(f:Fact {has_dimensions: false})<-[:FACT_SET_CONTAINS_FACT]-(fs:FactSet)<-[:STRUCTURE_HAS_FACT_SET]-(s:Structure)
207
+ MATCH (r:Report {identifier: $rid})-[:REPORT_HAS_FACT]->(f:Fact)<-[:FACT_SET_CONTAINS_FACT]-(fs:FactSet)<-[:STRUCTURE_HAS_FACT_SET]-(s:Structure)
111
208
  RETURN s.identifier AS sid, s.canonical_type AS canonical_type,
112
209
  s.definition AS definition, s.number AS number,
113
210
  collect(DISTINCT fs.identifier) AS factsets
114
211
  ORDER BY number`;
115
212
  var FACTS_Q = `
116
- MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact {has_dimensions: false})-[:FACT_HAS_ELEMENT]->(e:Element),
213
+ MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact)-[:FACT_HAS_ELEMENT]->(e:Element),
117
214
  (f)-[:FACT_HAS_PERIOD]->(p:Period)
118
215
  WHERE f.value IS NOT NULL
119
216
  RETURN f.identifier AS fid, e.qname AS qname, e.name AS ename, e.balance AS balance,
120
217
  e.period_type AS e_period_type, e.is_abstract AS is_abstract, e.is_numeric AS is_numeric,
218
+ e.item_type AS item_type, e.is_shares AS is_shares,
121
219
  f.numeric_value AS numeric_value, f.value AS raw_value, f.decimals AS decimals,
122
220
  p.identifier AS pid, p.period_type AS period_type,
123
221
  p.start_date AS start_date, p.end_date AS end_date
124
222
  LIMIT 2000`;
125
223
  var UNITS_Q = `
126
- MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact {has_dimensions: false})-[:FACT_HAS_UNIT]->(u:Unit)
224
+ MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact)-[:FACT_HAS_UNIT]->(u:Unit)
127
225
  WHERE f.value IS NOT NULL
128
226
  RETURN f.identifier AS fid, u.measure AS unit
129
227
  LIMIT 2000`;
228
+ var DIMS_Q = `
229
+ MATCH (fs:FactSet {identifier: $fsid})-[:FACT_SET_CONTAINS_FACT]->(f:Fact)-[:FACT_HAS_DIMENSION]->(d:Dimension)
230
+ WHERE f.value IS NOT NULL
231
+ RETURN f.identifier AS fid, d.axis AS axis, d.member AS member,
232
+ d.axis_uri AS axis_uri, d.member_uri AS member_uri,
233
+ d.is_explicit AS is_explicit, d.is_typed AS is_typed
234
+ LIMIT 4000`;
130
235
  var ASSOC_Q = `
131
236
  MATCH (s:Structure {identifier: $sid})-[:STRUCTURE_HAS_ASSOCIATION]->(a:Association),
132
237
  (a)-[:ASSOCIATION_HAS_FROM_ELEMENT]->(pe:Element),
133
238
  (a)-[:ASSOCIATION_HAS_TO_ELEMENT]->(ce:Element)
134
- RETURN a.association_type AS association_type, a.order_value AS order_value,
135
- a.weight AS weight, pe.qname AS parent, ce.qname AS child`;
239
+ RETURN a.association_type AS association_type, a.order_value AS order_value, a.weight AS weight,
240
+ pe.qname AS parent, pe.name AS parent_name, pe.is_abstract AS parent_abstract,
241
+ ce.qname AS child, ce.name AS child_name, ce.is_abstract AS child_abstract`;
136
242
  function str(row, key) {
137
243
  const v = row[key];
138
244
  return typeof v === "string" && v !== "" ? v : v == null ? null : String(v);
@@ -150,23 +256,32 @@ function bool(row, key) {
150
256
  function periodType(raw) {
151
257
  return raw === "instant" || raw === "duration" ? raw : null;
152
258
  }
153
- var DENSE_PERIOD_FRACTION = 0.2;
154
- function filterToDominantPeriods(facts, periods) {
155
- const countByEnd = /* @__PURE__ */ new Map();
156
- for (const f of facts) {
157
- const end = periods[f.period]?.end;
158
- if (end) countByEnd.set(end, (countByEnd.get(end) ?? 0) + 1);
259
+ function xbrlQname(uri, local) {
260
+ if (local) {
261
+ const ns = (uri ?? "").split("#")[0];
262
+ if (/fasb\.org\/us-gaap/.test(ns)) return `us-gaap:${local}`;
263
+ if (/fasb\.org\/srt/.test(ns)) return `srt:${local}`;
264
+ if (/xbrl\.sec\.gov\/dei/.test(ns)) return `dei:${local}`;
265
+ if (/robosystems\.ai\/taxonomy\/rs-gaap/.test(ns)) return `rs-gaap:${local}`;
266
+ return local;
159
267
  }
160
- if (countByEnd.size <= 1) return facts;
161
- const max = Math.max(...countByEnd.values());
162
- const threshold = max * DENSE_PERIOD_FRACTION;
163
- const keep = new Set(
164
- [...countByEnd].filter(([, count]) => count >= threshold).map(([end]) => end)
165
- );
166
- return facts.filter((f) => {
167
- const end = periods[f.period]?.end;
168
- return end !== void 0 && keep.has(end);
169
- });
268
+ return uri ? qname(uri) : "";
269
+ }
270
+ function dimLabel(local) {
271
+ if (!local) return "";
272
+ return humanize(local.replace(/(Axis|Member|Domain)$/, "")) || humanize(local);
273
+ }
274
+ function deriveNumericKind(row) {
275
+ const itemType = str(row, "item_type") ?? "";
276
+ if (/perShareItemType/i.test(itemType)) return "perShare";
277
+ if (/sharesItemType/i.test(itemType) || bool(row, "is_shares")) return "shares";
278
+ if (/percentItemType/i.test(itemType)) return "percent";
279
+ if (/pureItemType/i.test(itemType)) return "pure";
280
+ if (/monetaryItemType/i.test(itemType)) return "monetary";
281
+ if (/integerItemType/i.test(itemType)) return "integer";
282
+ if (!bool(row, "is_numeric")) return void 0;
283
+ const balance = str(row, "balance");
284
+ return balance === "debit" || balance === "credit" ? "monetary" : "other";
170
285
  }
171
286
  var CORE_STATEMENT_TYPES = /* @__PURE__ */ new Set([
172
287
  "balance_sheet",
@@ -238,7 +353,20 @@ function accumulateElement(elements, row) {
238
353
  balance: balance === "debit" || balance === "credit" ? balance : null,
239
354
  periodType: periodType(str(row, "e_period_type")),
240
355
  abstract: bool(row, "is_abstract"),
241
- monetary: bool(row, "is_numeric")
356
+ monetary: bool(row, "is_numeric"),
357
+ numericKind: deriveNumericKind(row)
358
+ };
359
+ }
360
+ function registerPresentationElement(elements, qname2, name, isAbstract) {
361
+ if (!qname2 || elements[qname2]) return;
362
+ elements[qname2] = {
363
+ id: qname2,
364
+ qname: qname2,
365
+ label: name ? humanize(isAbstract ? name.replace(/Abstract$/, "") : name) : humanize(qname2),
366
+ balance: null,
367
+ periodType: null,
368
+ abstract: isAbstract,
369
+ monetary: false
242
370
  };
243
371
  }
244
372
  function accumulatePeriod(periods, row) {
@@ -257,9 +385,10 @@ function accumulatePeriod(periods, row) {
257
385
  };
258
386
  }
259
387
  async function fetchSecSection(query, shell, section) {
260
- const [factRowGroups, unitRowGroups, assocRows] = await Promise.all([
388
+ const [factRowGroups, unitRowGroups, dimRowGroups, assocRows] = await Promise.all([
261
389
  Promise.all(section.factsetIds.map((fsid) => query(FACTS_Q, { fsid }))),
262
390
  Promise.all(section.factsetIds.map((fsid) => query(UNITS_Q, { fsid }))),
391
+ Promise.all(section.factsetIds.map((fsid) => query(DIMS_Q, { fsid }))),
263
392
  query(ASSOC_Q, { sid: section.id })
264
393
  ]);
265
394
  const unitByFid = /* @__PURE__ */ new Map();
@@ -268,6 +397,24 @@ async function fetchSecSection(query, shell, section) {
268
397
  const measure = str(row, "unit");
269
398
  if (fid && measure) unitByFid.set(fid, measure);
270
399
  }
400
+ const dimsByFid = /* @__PURE__ */ new Map();
401
+ for (const row of dimRowGroups.flat()) {
402
+ const fid = str(row, "fid");
403
+ if (!fid) continue;
404
+ const memberLocal = str(row, "member");
405
+ const qual = {
406
+ axis: xbrlQname(str(row, "axis_uri"), str(row, "axis")),
407
+ member: memberLocal ? xbrlQname(str(row, "member_uri"), memberLocal) : null,
408
+ axisLabel: dimLabel(str(row, "axis")),
409
+ memberLabel: dimLabel(memberLocal),
410
+ explicit: bool(row, "is_explicit"),
411
+ typedValue: bool(row, "is_typed") ? str(row, "member") : null
412
+ };
413
+ const list = dimsByFid.get(fid) ?? [];
414
+ list.push(qual);
415
+ dimsByFid.set(fid, list);
416
+ }
417
+ for (const list of dimsByFid.values()) list.sort((a, b) => a.axis.localeCompare(b.axis));
271
418
  const elements = {};
272
419
  const periods = {};
273
420
  const units = {};
@@ -287,7 +434,8 @@ async function fetchSecSection(query, shell, section) {
287
434
  units[measure] = {
288
435
  id: measure,
289
436
  measure: compact,
290
- label: compact.includes(":") ? compact.split(":").pop() : compact
437
+ label: compact.includes(":") ? compact.split(":").pop() : compact,
438
+ symbol: currencySymbolFor(compact)
291
439
  };
292
440
  }
293
441
  const value = num(row, "numeric_value");
@@ -300,7 +448,8 @@ async function fetchSecSection(query, shell, section) {
300
448
  factSet: section.id,
301
449
  value,
302
450
  decimals: str(row, "decimals"),
303
- textValue: value === null ? str(row, "raw_value") : null
451
+ textValue: value === null ? str(row, "raw_value") : null,
452
+ dimensions: dimsByFid.get(fid)
304
453
  });
305
454
  }
306
455
  const calcAssociations = [];
@@ -309,6 +458,18 @@ async function fetchSecSection(query, shell, section) {
309
458
  const parent = str(row, "parent");
310
459
  const child = str(row, "child");
311
460
  if (!parent || !child) continue;
461
+ registerPresentationElement(
462
+ elements,
463
+ parent,
464
+ str(row, "parent_name"),
465
+ bool(row, "parent_abstract")
466
+ );
467
+ registerPresentationElement(
468
+ elements,
469
+ child,
470
+ str(row, "child_name"),
471
+ bool(row, "child_abstract")
472
+ );
312
473
  const order = num(row, "order_value") ?? 0;
313
474
  const type = str(row, "association_type")?.toLowerCase();
314
475
  if (type === "calculation") {
@@ -344,7 +505,7 @@ async function fetchSecSection(query, shell, section) {
344
505
  entity: shell.entity,
345
506
  informationBlocks: [informationBlock],
346
507
  structures: [structure],
347
- facts: filterToDominantPeriods(facts, periods),
508
+ facts,
348
509
  elements,
349
510
  periods,
350
511
  units,
@@ -427,7 +588,8 @@ function parseStore(store) {
427
588
  balance: balance === "debit" || balance === "credit" ? balance : null,
428
589
  periodType: periodType2 === "instant" || periodType2 === "duration" ? periodType2 : null,
429
590
  abstract: firstValue(id, IRI.abstract) === "true",
430
- monetary: firstValue(id, IRI.monetary) === "true"
591
+ monetary: firstValue(id, IRI.monetary) === "true",
592
+ itemType: firstValue(id, IRI.itemType) ?? void 0
431
593
  };
432
594
  }
433
595
  const periods = {};
@@ -471,6 +633,7 @@ function parseStore(store) {
471
633
  entity: firstValue(id, IRI.entity),
472
634
  factSet: firstValue(id, IRI.factSet),
473
635
  value: toNumber(firstValue(id, IRI.numericValue)),
636
+ textValue: firstValue(id, IRI.stringValue),
474
637
  decimals: firstValue(id, IRI.decimals)
475
638
  });
476
639
  }
@@ -479,6 +642,10 @@ function parseStore(store) {
479
642
  informationBlocks.push({
480
643
  id,
481
644
  blockType: firstValue(id, IRI.blockType) ?? "",
645
+ // Match a block to its structure by identity (the rs:structure link),
646
+ // not by a semantic blockType — a full-fidelity holon carries no
647
+ // block-type classification, so structureId is how row order is found.
648
+ structureId: firstValue(id, IRI.structure) ?? void 0,
482
649
  factSet: firstValue(id, IRI.factSet),
483
650
  label: firstValue(id, IRI.prefLabel)
484
651
  });
@@ -490,7 +657,10 @@ function parseStore(store) {
490
657
  id,
491
658
  blockType: firstValue(id, IRI.blockType) ?? "",
492
659
  roleUri: firstValue(id, IRI.roleUri),
493
- structureName: firstValue(id, IRI.structureName)
660
+ structureName: firstValue(id, IRI.structureName),
661
+ // Filing sequence (SEC role-definition number) so buildPivots orders all
662
+ // sections by the filer's order rather than the fixed four-primary fallback.
663
+ order: toNumber(firstValue(id, IRI.structureOrder)) ?? void 0
494
664
  });
495
665
  for (const assoc of objects(id, IRI.hasAssociation)) {
496
666
  assocStructure.set(assoc.value, id);
@@ -559,6 +729,6 @@ function jsonldFileAdapter(doc, source = "holon.jsonld") {
559
729
  };
560
730
  }
561
731
 
562
- export { BLOCK_ORDER, BLOCK_TITLES, NS, cypherAdapter, fetchSecReportShell, fetchSecSection, humanize, isExternalFactUrl, jsonldFileAdapter, mergeSecSections, parseJsonld, parseStore, parseStructureDefinition, qname };
563
- //# sourceMappingURL=chunk-POSLHOTN.js.map
564
- //# sourceMappingURL=chunk-POSLHOTN.js.map
732
+ export { BLOCK_ORDER, BLOCK_TITLES, NS, currencySymbolFor, cypherAdapter, fetchSecReportShell, fetchSecSection, formatDate, formatMoney, formatPeriod, formatValue, humanize, humanizeDuration, isExternalFactUrl, jsonldFileAdapter, mergeSecSections, numericKindOf, parseJsonld, parseStore, parseStructureDefinition, qname };
733
+ //# sourceMappingURL=chunk-RQXAMFTZ.js.map
734
+ //# sourceMappingURL=chunk-RQXAMFTZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants.ts","../src/format.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-RQXAMFTZ.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 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 * 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'\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: 'Statement' | 'Disclosure' | 'Document' | 'Cover' | 'Other'\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/** The fast first read: entity + the ordered section list, no fact bodies. */\nexport interface SecReportShell {\n reportId: string\n entity: EntityInfo | null\n sections: SecSection[]\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// 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.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.name AS parent_name, pe.is_abstract AS parent_abstract,\n ce.qname AS child, 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/**\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/**\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: SecSection['kind'] } {\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: SecSection['kind'] = '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// ── 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] = await Promise.all([\n query(ENTITY_META_Q, { rid: reportId }),\n query(SECTIONS_Q, { rid: reportId }),\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 canonicalType: str(row, 'canonical_type'),\n order,\n factsetIds: factsets,\n }\n })\n .filter((s) => s.id && s.factsetIds.length > 0)\n\n return { reportId, entity: mapEntity(entityRows[0]), sections }\n}\n\n// ── Single section ────────────────────────────────────────────────────────────\n\nfunction accumulateElement(elements: Record<string, ElementInfo>, row: Record<string, unknown>) {\n const q = str(row, 'qname')\n if (!q || elements[q]) return\n const balance = str(row, 'balance')\n elements[q] = {\n id: q,\n qname: q,\n label: str(row, 'ename') ? humanize(str(row, 'ename') as string) : 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 name: string | null,\n isAbstract: boolean\n): void {\n if (!qname || elements[qname]) return\n elements[qname] = {\n id: qname,\n qname,\n label: name ? humanize(isAbstract ? name.replace(/Abstract$/, '') : name) : humanize(qname),\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 const qual: DimensionQualifier = {\n axis: xbrlQname(str(row, 'axis_uri'), str(row, 'axis')),\n member: memberLocal ? xbrlQname(str(row, 'member_uri'), memberLocal) : null,\n axisLabel: dimLabel(str(row, 'axis')),\n memberLabel: 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)\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_name'),\n bool(row, 'parent_abstract')\n )\n registerPresentationElement(\n elements,\n child,\n str(row, 'child_name'),\n bool(row, 'child_abstract')\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 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 ElementInfo,\n EntityInfo,\n Fact,\n InformationBlock,\n NormalizedReport,\n PeriodInfo,\n PeriodType,\n PresAssociation,\n StructureInfo,\n UnitInfo,\n} from '../model'\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 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: firstValue(id, IRI.itemType) ?? undefined,\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 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: firstValue(id, IRI.factSet),\n value: toNumber(firstValue(id, IRI.numericValue)),\n textValue: firstValue(id, IRI.stringValue),\n decimals: firstValue(id, IRI.decimals),\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 structures.push({\n id,\n blockType: firstValue(id, IRI.blockType) ?? '',\n roleUri: firstValue(id, IRI.roleUri),\n structureName: firstValue(id, IRI.structureName),\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"]}