@graphty/graph-io 0.3.20 → 0.3.21

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/README.md CHANGED
@@ -8,8 +8,9 @@
8
8
  Importers and exporters for the [@graphty/graph-format](https://www.npmjs.com/package/@graphty/graph-format)
9
9
  snapshot: GEXF, GraphML, GML, DOT (Graphviz), Pajek NET, CSV / TSV, JSON (NetworkX node-link, d3,
10
10
  JSON Graph Format, Cytoscape, graphology, vis.js; NetworkX adjacency_data and tree_data and OBO
11
- Graphs are read only), Neo4j (`neo4j-admin import` CSV), CX2 (the NDEx / Cytoscape exchange format;
12
- its version 1, CX, is read only) and OBO, the ontology format of the Gene Ontology (read only).
11
+ Graphs are read only), Neo4j (`neo4j-admin import` CSV), XGMML (Cytoscape's XML format), CX2 (the
12
+ NDEx / Cytoscape exchange format; its version 1, CX, is read only), Cytoscape sessions (`.cys`, read
13
+ only) and OBO, the ontology format of the Gene Ontology (read only).
13
14
 
14
15
  Every importer streams its input into a `GraphSink` (a `GraphBuilder` or your own sink) one scalar at
15
16
  a time and reports what it could not represent instead of dropping it; every exporter says what it
@@ -154,10 +155,10 @@ reports every column or feature outside it):
154
155
  | CSV | `@graphty/graph-io/csv` | `.csv` `.tsv` `.edges` `.edgelist` | yes | yes | optional | any | bool i32 f64 string dict | no | no | no | no | none | no | no | no |
155
156
  | JSON | `@graphty/graph-io/json` | `.json` | per dialect | yes | per dialect | any | f64 i32 bool string (no declarations) | no | yes | no | Cytoscape | none | per dialect | Cytoscape | no |
156
157
  | Neo4j | `@graphty/graph-io/neo4j` | `.csv` `.tsv` | no | yes | none | any | f32 f64 i32 bool string | yes | no | no | no | none | no | no | no |
157
- | OBO | `@graphty/graph-io/obo` | `.obo` | read only | - | - | - | - | - | - | - | - | - | - | - | - |
158
- | CX2 | `@graphty/graph-io/cx2` | `.cx2` | no | yes | required | integer | f64 i32 bool string | yes | no | yes | no | none | yes | yes | no |
159
158
  | XGMML | `@graphty/graph-io/xgmml` | `.xgmml` `.xml` | yes | yes | optional | any | f64 i32 bool string (long as Long) | yes | no | no | yes | none | yes | yes | no |
159
+ | CX2 | `@graphty/graph-io/cx2` | `.cx2` | no | yes | required | integer | f64 i32 bool string | yes | no | yes | no | none | yes | yes | no |
160
160
  | Session | `@graphty/graph-io/cys` | `.cys` | read only | read only | read only | read only | read only | - | - | - | - | - | - | - | - |
161
+ | OBO | `@graphty/graph-io/obo` | `.obo` | read only | - | - | - | - | - | - | - | - | - | - | - | - |
161
162
 
162
163
  Every importer reads the whole corpus of research note 07 with the manifest counts and every
163
164
  exporter round-trips it (import -> export -> import gives the same ids, topology, orientation,
@@ -260,7 +261,8 @@ losses and format rules, in addition to the table:
260
261
  lists the inferred dtypes only, and `check()` names every f32 / u32 / u8 / dict / list / vector
261
262
  column (they come back f64 / i32 / string / json), integral f64 columns (i32) and every role the
262
263
  dialect has no slot for. Edge ids exist in JGF, Cytoscape, graphology and vis only; positions in
263
- Cytoscape only. A repeated node id is merged with `W_DUPLICATE_NODE`, a repeated edge id skipped
264
+ Cytoscape only, stored y-up as for every Cytoscape-family format (Cytoscape's y grows downward,
265
+ so it is negated at import and negated back on export). A repeated node id is merged with `W_DUPLICATE_NODE`, a repeated edge id skipped
264
266
  with `E_DUPLICATE_EDGE_ID`; an out-of-range d3 index link is `E_BAD_INDEX`. Non-finite numbers
265
267
  are written as `null` and reported. NetworkX `adjacency_data` (`nodes` plus an `adjacency` list
266
268
  per node; an undirected file lists each edge from both ends and it is read once) and `tree_data`
@@ -775,6 +775,15 @@ class CxReader {
775
775
  inGraph(id) {
776
776
  return this.plan.nodes === null || this.plan.nodes.has(id);
777
777
  }
778
+ /**
779
+ * The key of the node and edge row maps for a CX id as an aspect writes it: the id the `ids`
780
+ * option makes of it, which is what idOf() stored the element under.
781
+ * @param raw - the CX id
782
+ * @returns the row key
783
+ */
784
+ key(raw) {
785
+ return this.options.ids === "keep" ? raw : this.coercer.value(raw);
786
+ }
778
787
  /**
779
788
  * Whether a scoped value applies to this graph: unscoped, or scoped to its subnetwork. A scope
780
789
  * naming no subnetwork is counted as dangling.
@@ -1070,7 +1079,7 @@ class CxReader {
1070
1079
  continue;
1071
1080
  }
1072
1081
  const target = refId(value.po);
1073
- const row = target === null ? void 0 : rows.get(this.options.ids === "keep" ? target : this.coercer.value(target));
1082
+ const row = target === null ? void 0 : rows.get(this.key(target));
1074
1083
  if (row === void 0) {
1075
1084
  if (target === null || !root.has(target)) {
1076
1085
  this.dangle(`${domain} attribute target`);
@@ -1248,7 +1257,7 @@ class CxReader {
1248
1257
  report.counts.skippedNodes++;
1249
1258
  continue;
1250
1259
  }
1251
- if (!this.inGraph(id)) {
1260
+ if (!this.inGraph(refId(value["@id"]) ?? id)) {
1252
1261
  continue;
1253
1262
  }
1254
1263
  let row = this.nodeRows.get(id);
@@ -1337,18 +1346,18 @@ class CxReader {
1337
1346
  });
1338
1347
  continue;
1339
1348
  }
1340
- let groupRow = this.nodeRows.get(id);
1349
+ let groupRow = this.nodeRows.get(this.key(id));
1341
1350
  if (groupRow === void 0) {
1342
1351
  if (this.rootNodes.has(id) || !this.hasMemberIn(value.nodes)) {
1343
1352
  continue;
1344
1353
  }
1345
1354
  try {
1346
- groupRow = this.sink.addNode(id);
1355
+ groupRow = this.sink.addNode(this.key(id));
1347
1356
  } catch (err) {
1348
1357
  this.report.recordError(err, { line, element: String(id) });
1349
1358
  continue;
1350
1359
  }
1351
- this.nodeRows.set(id, groupRow);
1360
+ this.nodeRows.set(this.key(id), groupRow);
1352
1361
  this.report.counts.nodes++;
1353
1362
  this.report.warning(
1354
1363
  "coercion",
@@ -1365,7 +1374,7 @@ class CxReader {
1365
1374
  }
1366
1375
  for (const raw of Array.isArray(value.nodes) ? value.nodes : []) {
1367
1376
  const member = refId(raw);
1368
- const row = member === null ? void 0 : this.nodeRows.get(member);
1377
+ const row = member === null ? void 0 : this.nodeRows.get(this.key(member));
1369
1378
  if (row === void 0) {
1370
1379
  if (member === null || !this.rootNodes.has(member)) {
1371
1380
  this.report.error(
@@ -1419,7 +1428,7 @@ class CxReader {
1419
1428
  hasMemberIn(raw) {
1420
1429
  return Array.isArray(raw) && raw.some((item) => {
1421
1430
  const id = refId(item);
1422
- return id !== null && this.nodeRows.has(id);
1431
+ return id !== null && this.nodeRows.has(this.key(id));
1423
1432
  });
1424
1433
  }
1425
1434
  /**
@@ -1501,7 +1510,7 @@ class CxReader {
1501
1510
  continue;
1502
1511
  }
1503
1512
  const node = refId(value.node);
1504
- const row = node === null ? void 0 : this.nodeRows.get(node);
1513
+ const row = node === null ? void 0 : this.nodeRows.get(this.key(node));
1505
1514
  if (row === void 0) {
1506
1515
  if (node === null || !this.rootNodes.has(node)) {
1507
1516
  this.dangle("layout entry");
@@ -1606,7 +1615,7 @@ class CxReader {
1606
1615
  report.counts.skippedEdges++;
1607
1616
  continue;
1608
1617
  }
1609
- if (members !== null && !members.has(id)) {
1618
+ if (members !== null && !members.has(refId(value["@id"]) ?? id)) {
1610
1619
  continue;
1611
1620
  }
1612
1621
  if (value.s === void 0 || value.s === null || value.t === void 0 || value.t === null) {
@@ -1719,7 +1728,7 @@ class CxReader {
1719
1728
  if (isRecord(value) && this.scopePeek(value.s) !== 0) {
1720
1729
  const po = refId(value.po);
1721
1730
  if (po !== null && value.v !== void 0 && value.v !== null) {
1722
- this.weights.set(po, plainJson(value.v));
1731
+ this.weights.set(this.key(po), plainJson(value.v));
1723
1732
  }
1724
1733
  }
1725
1734
  }
@@ -1820,7 +1829,8 @@ class CxReader {
1820
1829
  case "edges": {
1821
1830
  const domain = value.properties_of === "nodes" ? "node" : "edge";
1822
1831
  const target = refId(value.applies_to);
1823
- const row = target === null ? void 0 : (domain === "node" ? this.nodeRows : this.edgeRows).get(target);
1832
+ const rows = domain === "node" ? this.nodeRows : this.edgeRows;
1833
+ const row = target === null ? void 0 : rows.get(this.key(target));
1824
1834
  if (row === void 0) {
1825
1835
  if (target === null || !(domain === "node" ? this.rootNodes : this.rootEdges).has(target)) {
1826
1836
  this.dangle(`${domain} visual property entry`);
@@ -1914,7 +1924,7 @@ class CxReader {
1914
1924
  continue;
1915
1925
  }
1916
1926
  const po = refId(value.po);
1917
- const row = po === null ? void 0 : this.nodeRows.get(po);
1927
+ const row = po === null ? void 0 : this.nodeRows.get(this.key(po));
1918
1928
  if (row === void 0) {
1919
1929
  if (po === null || !this.rootNodes.has(po)) {
1920
1930
  this.dangle("functionTerms entry");
@@ -1932,8 +1942,8 @@ class CxReader {
1932
1942
  }
1933
1943
  const node = refId(value.node);
1934
1944
  const edge = refId(value.edge);
1935
- const row = node === null ? void 0 : this.nodeRows.get(node);
1936
- const edgeRow = edge === null ? void 0 : this.edgeRows.get(edge);
1945
+ const row = node === null ? void 0 : this.nodeRows.get(this.key(node));
1946
+ const edgeRow = edge === null ? void 0 : this.edgeRows.get(this.key(edge));
1937
1947
  if (row === void 0 || edgeRow === void 0) {
1938
1948
  if (node === null || !this.rootNodes.has(node) || edge === null || !this.rootEdges.has(edge)) {
1939
1949
  this.dangle("reifiedEdges entry");
@@ -2002,7 +2012,7 @@ class CxReader {
2002
2012
  const ids = (Array.isArray(value[column]) ? value[column] : []).map(refId).filter((id) => id !== null).map(Number);
2003
2013
  for (const raw of targets) {
2004
2014
  const target = refId(raw);
2005
- const row = target === null ? void 0 : rows.get(target);
2015
+ const row = target === null ? void 0 : rows.get(this.key(target));
2006
2016
  if (row === void 0) {
2007
2017
  if (target === null || !root.has(target)) {
2008
2018
  this.dangle(`${aspectName} entry`);
@@ -2191,4 +2201,4 @@ export {
2191
2201
  CX_ISSUE as C,
2192
2202
  cxImporter as c
2193
2203
  };
2194
- //# sourceMappingURL=importer-BaQpCEcJ.js.map
2204
+ //# sourceMappingURL=importer-DET1tg6s.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importer-DET1tg6s.js","sources":["../../src/formats/cx/importer.ts"],"sourcesContent":["/**\n * The CX version 1 importer (design/graph-io/cytoscape-and-obo/design.md section 1.2; the feature\n * and error inventory is research-cx.md): the JSON exchange format of NDEx and Cytoscape's CX\n * support. A CX document is an array of aspect fragments (`nodes`, `edges`, `nodeAttributes`,\n * `cartesianLayout`, `cySubNetworks`, `cyGroups`, `cyVisualProperties`, ...) that refer to each\n * other by integer ids, in any order.\n *\n * The document is read through the streaming scanner of common/json-elements.ts, so its text is\n * never held as one string; the parsed aspect elements are collected and each graph is built at the\n * end, because a reference may precede what it names.\n *\n * Mapping: every edge is directed; ids follow the CX id rule (design section 1.0.2); `n` is the\n * `name` column (the label), `r` is `represents`, `i` is `interaction`; attributes become columns\n * typed by their `d` (Cytoscape's value rule: \"\" and \"null\" are unset, \"NaN\" is NaN in a double); a\n * subnetwork's values are the unscoped ones and its own (`s`), its own winning. A collection (several\n * `cySubNetworks`) holds one graph per subnetwork: `importAll()` returns them, `import()` reads the\n * one `graphIndex` / `graphName` picks, `listGraphs()` lists them. Positions come from the\n * subnetwork's view, y flipped to y-up, `z` into the `z` column; `cyGroups` give `parent` (or\n * `parents`); per-element visual properties are one column per property (origin namespace\n * \"cx.bypass\") and style rules are kept verbatim in `meta.extra.cx` and not applied\n * (W_STYLES_NOT_IMPORTED, issue #706); provenance aspects become extension tables and list columns.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n type Dtype,\n type GraphMetaPatch,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { declareResolved, uniqueColumnName } from \"../../common/attributes.js\";\nimport {\n AMBIGUOUS_GRAPH_NAME_CODE,\n ASPECT_ORDER_CODE,\n BAD_ASPECT_BLOCK_CODE,\n BAD_VALUE_CODE,\n COLUMN_RENAMED_CODE,\n COUNT_MISMATCH_CODE,\n DANGLING_REFERENCE_CODE,\n DIRECTION_FORCED_CODE,\n DIRECTION_REFUSED_CODE,\n DUPLICATE_ATTRIBUTE_CODE,\n DUPLICATE_EDGE_ID_CODE,\n DUPLICATE_NODE_CODE,\n EMPTY_INPUT_CODE,\n ENCODING_FALLBACK_CODE,\n GRAPH_NOT_FOUND_CODE,\n ID_MERGED_CODE,\n ID_TEXT_TYPE_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n MULTIPLE_GRAPHS_CODE,\n NO_GRAPH_CODE,\n OPTION_IGNORED_CODE,\n PARENT_CYCLE_CODE,\n PRECISION_CODE,\n ROLE_TAKEN_CODE,\n SINK_OPTION_CODE,\n STATUS_FAILED_CODE,\n STATUS_WARNING_CODE,\n STYLES_NOT_IMPORTED_CODE,\n SYNTAX_CODE,\n TOO_LARGE_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ENCODING_CODE,\n UNKNOWN_PARENT_CODE,\n WIDENED_CODE,\n} from \"../../common/codes.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { IdCoercer } from \"../../common/ids.js\";\nimport { textChunks, throwIfAborted } from \"../../common/input.js\";\nimport {\n cxId,\n CxStructure,\n declareFresh,\n ExactInteger,\n flipY,\n inexactLiteral,\n isRecord,\n JsonScanError,\n plainJson,\n positionDecl,\n reportTooDeep,\n scanAspects,\n zDecl,\n} from \"../../common/json-elements.js\";\nimport {\n chooseGraph,\n type ImportFormatDefaults,\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { weightFromValue } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphImporter,\n type GraphListing,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { zAsOption } from \"../cx2/importer.js\";\n\n/** The format name. */\nconst CX_FORMAT = \"cx\";\n\n/** The origin namespace of the per-element visual property columns. */\nconst CX_BYPASS_NAMESPACE = \"cx.bypass\";\n\n/** The format-specific options of the CX importer. */\nexport interface CxImportOptions extends GraphChoiceOptions {\n /**\n * Where a node's `z` goes: \"column\" (default) keeps it in the f64 node column `z` (Cytoscape\n * writes a stacking order there); \"position\" makes it the third component of the position.\n */\n zAs?: \"column\" | \"position\" | undefined;\n}\n\n/**\n * The issue codes the CX importer records (design section 1.2), by name: the codes shared with\n * the other importers (src/common/codes.ts) and the CX-specific ones. A key is the code without\n * its severity and format prefixes.\n */\nexport const CX_ISSUE = Object.freeze({\n /** The input is empty (fatal). */\n EMPTY_INPUT: EMPTY_INPUT_CODE,\n /** The text is not JSON (fatal). */\n SYNTAX: SYNTAX_CODE,\n /** Invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** An encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** The document is not a CX array, or it is CX2 (fatal; the message names CX2). */\n NOT_CX: \"E_CX_NOT_CX\",\n /** numberVerification holds another value than 2^48 - 1, or comes twice. */\n NUMBER_VERIFICATION: \"W_CX_NUMBER_VERIFICATION\",\n /** An old Cytoscape aspect name (visualProperties, subNetworks, ...) read under its cy name. */\n OLD_ASPECT_NAME: \"W_CX_OLD_ASPECT_NAME\",\n /** A cyGroups group whose id is not a node: the group node is added. */\n GROUP_NODE_ADDED: \"W_CX_GROUP_NODE_ADDED\",\n /** Nodes or edges of the root network that no subnetwork holds: Cytoscape shows them in no network; not read. */\n ROOT_ONLY: \"W_CX_ROOT_ONLY\",\n /** The producer marked the document as failed (fatal). */\n STATUS_FAILED: STATUS_FAILED_CODE,\n /** The producer marked the document as successful with an error text. */\n STATUS_WARNING: STATUS_WARNING_CODE,\n /** A member of the array that is not a one-key aspect block, or an element that is not an object. */\n BAD_ASPECT_BLOCK: BAD_ASPECT_BLOCK_CODE,\n /** An aspect after the post-metadata or after the status, a third metaData. */\n ASPECT_ORDER: ASPECT_ORDER_CODE,\n /** A metaData element count disagrees with what was read. */\n COUNT_MISMATCH: COUNT_MISMATCH_CODE,\n /** A value that does not parse as its data type; the cell is unset. */\n BAD_VALUE: BAD_VALUE_CODE,\n /** One attribute name with several data types: the column takes the wider one. */\n WIDENED: WIDENED_CODE,\n /** A data type CX does not define; the value is kept as text. */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** An attribute, layout, bypass, subnetwork member, view or provenance entry naming nothing. */\n DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,\n /** The same attribute twice on one element (or n and a different name attribute); the later wins. */\n DUPLICATE_ATTRIBUTE: DUPLICATE_ATTRIBUTE_CODE,\n /** A group member naming no node. */\n UNKNOWN_PARENT: UNKNOWN_PARENT_CODE,\n /** A group membership that would close a parent cycle; dropped. */\n PARENT_CYCLE: PARENT_CYCLE_CODE,\n /** The style rules of cyVisualProperties are not applied (issue #706). */\n STYLES_NOT_IMPORTED: STYLES_NOT_IMPORTED_CODE,\n /** A node without an @id. */\n MISSING_ID: MISSING_ID_CODE,\n /** An edge without s or t. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id declared twice; the second merges into the first. */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** An edge id declared twice; the second edge is skipped. */\n DUPLICATE_EDGE_ID: DUPLICATE_EDGE_ID_CODE,\n /** An id that is not an integer. */\n INVALID_ID: \"E_INVALID_ID\",\n /** An edge endpoint naming no node of the graph (addMissingNodes false, the default). */\n UNKNOWN_NODE: \"E_UNKNOWN_NODE\",\n /** A weight that is not a number. */\n INVALID_WEIGHT: \"E_INVALID_WEIGHT\",\n /** An id spelled as a string or a non-integer literal; read as the integer. */\n ID_TEXT_TYPE: ID_TEXT_TYPE_CODE,\n /** An integer beyond 2^53: an id kept as its digits, a value stored as the nearest f64. */\n PRECISION: PRECISION_CODE,\n /** Two id texts merged under `ids: \"number\"`. */\n ID_MERGED: ID_MERGED_CODE,\n /** A collection read by import(): the other subnetworks are skipped. */\n MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,\n /** graphIndex or graphName names no subnetwork (fatal). */\n GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,\n /** graphName names several subnetworks (fatal). */\n AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,\n /** The input holds no graph (fatal). */\n NO_GRAPH: NO_GRAPH_CODE,\n /** A column renamed because its name was taken. */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A column that lost its role because another column holds it. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** The sink refused the direction. */\n DIRECTION_REFUSED: DIRECTION_REFUSED_CODE,\n /** Edges forced to the policy's direction. */\n DIRECTION_FORCED: DIRECTION_FORCED_CODE,\n /** A common option CX has no use for. */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder option the caller's sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n /** The input is beyond a size limit (fatal). */\n TOO_LARGE: TOO_LARGE_CODE,\n});\n\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\n/** CX has no undirected edge: defaultDirected never applies (reported W_OPTION_IGNORED). */\nconst FORMAT_DEFAULTS: ImportFormatDefaults = {\n ids: \"keep\",\n defaultDirected: true,\n weightFrom: \"weight\",\n addMissingNodes: false,\n};\n\nconst ABORT_CHECK_INTERVAL = 64;\n\n/** The numberVerification values a reader accepts: 2^48 - 1 and Java's Long.MAX_VALUE. */\nconst NUMBER_VERIFICATION_VALUES: ReadonlySet<string> = new Set([\"281474976710655\", \"9223372036854775807\"]);\n\n/** Old Cytoscape aspect names and the names they are read under. */\nconst OLD_ASPECT_NAMES: Readonly<Record<string, string>> = {\n visualProperties: \"cyVisualProperties\",\n subNetworks: \"cySubNetworks\",\n networkRelations: \"cyNetworkRelations\",\n hiddenAttributes: \"cyHiddenAttributes\",\n};\n\n/** The aspects the importer reads into the graph (everything else is kept verbatim). */\nconst READ_ASPECTS: ReadonlySet<string> = new Set([\n \"nodes\",\n \"edges\",\n \"nodeAttributes\",\n \"edgeAttributes\",\n \"networkAttributes\",\n \"cartesianLayout\",\n \"cySubNetworks\",\n \"cyNetworkRelations\",\n \"cyViews\",\n \"cyGroups\",\n \"cyVisualProperties\",\n \"cyTableColumn\",\n \"citations\",\n \"supports\",\n \"nodeCitations\",\n \"edgeCitations\",\n \"nodeSupports\",\n \"edgeSupports\",\n \"functionTerms\",\n \"reifiedEdges\",\n \"numberVerification\",\n \"metaData\",\n \"status\",\n]);\n\n/** The aspects also kept verbatim in meta.extra.cx although they are read. */\nconst ALSO_KEPT: ReadonlySet<string> = new Set([\n \"cySubNetworks\",\n \"cyNetworkRelations\",\n \"cyViews\",\n \"cyVisualProperties\",\n \"cyTableColumn\",\n \"numberVerification\",\n \"metaData\",\n]);\n\n/** Cytoscape's table-cell style aspects (both spellings): style rules, kept and reported, never read. */\nconst TABLE_STYLE_ASPECTS: readonly string[] = [\"tableVisualProperties\", \"cyTableVisualProperties\"];\n\n/** The first keys that make a head CX for sure, and the other aspect names a CX document may start with. */\nconst CX_FIRST_KEYS: readonly string[] = [\"numberVerification\", \"metaData\"];\nconst CX_ASPECT_KEYS: readonly string[] = [\n \"nodes\",\n \"edges\",\n \"nodeAttributes\",\n \"edgeAttributes\",\n \"networkAttributes\",\n \"cartesianLayout\",\n \"@context\",\n \"cySubNetworks\",\n \"subNetworks\",\n \"cyNetworkRelations\",\n \"networkRelations\",\n \"cyVisualProperties\",\n \"visualProperties\",\n \"cyHiddenAttributes\",\n \"hiddenAttributes\",\n \"cyTableColumn\",\n \"cyGroups\",\n \"cyViews\",\n \"ndexStatus\",\n \"provenanceHistory\",\n \"citations\",\n \"supports\",\n \"functionTerms\",\n];\n\n// ============================================================ values\n\n/** The canonical CX scalar types. */\ntype CxScalar = \"string\" | \"boolean\" | \"integer\" | \"long\" | \"double\";\n\n/** A CX data type. */\ninterface CxType {\n readonly scalar: CxScalar;\n readonly list: boolean;\n}\n\n/** The CX data types, with the Java reader's float aliases. */\nconst SCALARS: Readonly<Record<string, CxScalar>> = {\n string: \"string\",\n boolean: \"boolean\",\n integer: \"integer\",\n long: \"long\",\n double: \"double\",\n float: \"double\",\n};\n\n/**\n * Resolve a `d` value.\n * @param d - the data type (undefined: string)\n * @returns the type, or null when CX does not define it\n */\nfunction cxType(d: unknown): CxType | null {\n if (d === undefined || d === null) {\n return { scalar: \"string\", list: false };\n }\n if (typeof d !== \"string\") {\n return null;\n }\n const list = d.startsWith(\"list_of_\");\n const scalar = SCALARS[list ? d.slice(\"list_of_\".length) : d] as CxScalar | undefined;\n return scalar === undefined ? null : { scalar, list };\n}\n\n/**\n * The type text of a type.\n * @param type - the type\n * @returns `list_of_double`, `string`, ...\n */\nfunction typeText(type: CxType): string {\n return type.list ? `list_of_${type.scalar}` : type.scalar;\n}\n\n/** The widening rank of the scalar types (design 5.1 order; boolean and numbers widen to string). */\nconst RANK: Readonly<Record<CxScalar, number>> = { boolean: 0, integer: 1, long: 2, double: 3, string: 4 };\n\n/**\n * Widen two types to one that holds both.\n * @param a - the type so far\n * @param b - another type\n * @returns the wider type, or null when they cannot share a column (a list and a scalar)\n */\nfunction widenType(a: CxType, b: CxType): CxType | null {\n if (a.list !== b.list) {\n return null;\n }\n if (a.scalar === b.scalar) {\n return a;\n }\n const numeric = (s: CxScalar): boolean => s === \"integer\" || s === \"long\" || s === \"double\";\n if (numeric(a.scalar) && numeric(b.scalar)) {\n return RANK[a.scalar] > RANK[b.scalar] ? a : b;\n }\n return { scalar: \"string\", list: a.list };\n}\n\n/** What parseValue() returns for a value that does not parse. */\nconst BAD = Symbol(\"bad\");\n\n/** What parseValue() returns for a value Cytoscape reads as null (\"\", \"null\"). */\nconst UNSET = Symbol(\"unset\");\n\nconst I32_MIN = -2147483648;\nconst I32_MAX = 2147483647;\nconst INTEGER_TEXT = /^-?[0-9]+$/;\nconst DECIMAL_TEXT = /^-?([0-9]+(\\.[0-9]*)?|\\.[0-9]+)([eE][+-]?[0-9]+)?$/;\n\n/**\n * Whether a text is Cytoscape's null: the empty string or \"null\" in any case.\n * @param text - the text\n * @returns true for a null text\n */\nfunction isNullText(text: string): boolean {\n return text === \"\" || text.toLowerCase() === \"null\";\n}\n\n/**\n * Parse one scalar value (or list item) of a CX attribute by its type, with Cytoscape's value\n * rule: \"\" and \"null\" are unset, \"NaN\" is NaN in a double (unset in an integer or long), native JSON\n * numbers and booleans are accepted, anything else that does not parse is BAD.\n * @param value - the value (never null)\n * @param scalar - the type\n * @param long - the importer's `long` option\n * @param onPrecision - called for a long beyond 2^53\n * @returns the value, UNSET or BAD\n */\nfunction parseScalar(\n value: unknown,\n scalar: CxScalar,\n long: \"f64\" | \"string\",\n onPrecision: (digits: string) => void,\n): unknown {\n if (value instanceof ExactInteger) {\n if (scalar === \"string\" || (scalar === \"long\" && long === \"string\")) {\n return value.digits;\n }\n if (scalar === \"long\" || scalar === \"double\") {\n if (scalar === \"long\") {\n onPrecision(value.digits);\n }\n return Number(value.digits);\n }\n return BAD;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return parseNative(value, scalar, long);\n }\n if (typeof value !== \"string\") {\n return BAD;\n }\n if (scalar === \"string\") {\n return value;\n }\n if (isNullText(value)) {\n return UNSET;\n }\n switch (scalar) {\n case \"boolean\": {\n const lower = value.toLowerCase();\n if (lower === \"true\" || lower === \"false\") {\n return lower === \"true\";\n }\n return BAD;\n }\n case \"integer\":\n case \"long\": {\n if (value === \"NaN\") {\n return UNSET;\n }\n if (!INTEGER_TEXT.test(value)) {\n return BAD;\n }\n const n = Number(value);\n if (scalar === \"integer\") {\n return n >= I32_MIN && n <= I32_MAX ? n : BAD;\n }\n if (long === \"string\") {\n return value;\n }\n if (!Number.isSafeInteger(n)) {\n onPrecision(value);\n }\n return n;\n }\n default: {\n if (value === \"NaN\" || value === \"nan\") {\n return NaN;\n }\n if (value === \"Infinity\" || value === \"-Infinity\") {\n return Number(value);\n }\n return DECIMAL_TEXT.test(value) ? Number(value) : BAD;\n }\n }\n}\n\n/**\n * Parse a native JSON number or boolean by a type.\n * @param value - the value\n * @param scalar - the type\n * @param long - the importer's `long` option\n * @returns the value or BAD\n */\nfunction parseNative(value: number | boolean, scalar: CxScalar, long: \"f64\" | \"string\"): unknown {\n switch (scalar) {\n case \"string\":\n return String(value);\n case \"boolean\":\n return typeof value === \"boolean\" ? value : BAD;\n case \"integer\":\n return typeof value === \"number\" && Number.isInteger(value) && value >= I32_MIN && value <= I32_MAX\n ? value\n : BAD;\n case \"long\":\n if (typeof value !== \"number\" || !Number.isInteger(value)) {\n return BAD;\n }\n return long === \"string\" ? String(value) : value;\n default:\n return typeof value === \"number\" ? value : BAD;\n }\n}\n\n/**\n * Parse an attribute value by its type: a scalar, or a list whose items parse one by one (a null\n * item is NaN in a double list and BAD elsewhere).\n * @param value - the value (never null)\n * @param type - the type\n * @param long - the importer's `long` option\n * @param onPrecision - called for a long beyond 2^53\n * @returns the value, UNSET or BAD\n */\nfunction parseValue(\n value: unknown,\n type: CxType,\n long: \"f64\" | \"string\",\n onPrecision: (digits: string) => void,\n): unknown {\n if (Array.isArray(value) !== type.list) {\n return BAD;\n }\n if (!type.list) {\n return parseScalar(value, type.scalar, long, onPrecision);\n }\n const out: unknown[] = [];\n for (const item of value as unknown[]) {\n let parsed = item === null ? UNSET : parseScalar(item, type.scalar, long, onPrecision);\n if (parsed === UNSET) {\n parsed = type.scalar === \"double\" ? NaN : BAD;\n }\n if (parsed === BAD) {\n return BAD;\n }\n out.push(parsed);\n }\n return out;\n}\n\n/**\n * The column dtype of a type.\n * @param scalar - the scalar type\n * @param long - the importer's `long` option\n * @returns the dtype\n */\nfunction scalarDtype(scalar: CxScalar, long: \"f64\" | \"string\"): ScalarDtype {\n switch (scalar) {\n case \"boolean\":\n return \"bool\";\n case \"integer\":\n return \"i32\";\n case \"long\":\n return long === \"string\" ? \"string\" : \"f64\";\n case \"double\":\n return \"f64\";\n default:\n return \"string\";\n }\n}\n\n/**\n * A parsed value converted to the column's type (a narrower value in a widened column).\n * @param value - the parsed value\n * @param type - the column's type\n * @returns the value to store\n */\nfunction toColumn(value: unknown, type: CxType): unknown {\n if (type.scalar !== \"string\") {\n return value;\n }\n if (type.list) {\n return (value as unknown[]).map((item) => (typeof item === \"string\" ? item : String(item)));\n }\n return typeof value === \"string\" ? value : String(value);\n}\n\n/**\n * A short JSON rendering of a value for a message.\n * @param value - the value\n * @returns the text, at most 60 characters\n */\nfunction shown(value: unknown): string {\n if (value instanceof ExactInteger) {\n return value.digits;\n }\n let text: string;\n try {\n text = JSON.stringify(value) ?? String(value);\n } catch {\n text = String(value);\n }\n return text.length > 60 ? `${text.slice(0, 57)}...` : text;\n}\n\n// ============================================================ the document as read\n\n/** A parsed aspect element with where it came from. */\ninterface Held {\n readonly value: unknown;\n readonly line: number;\n /** Bit 1: @id, bit 2: s, bit 4: t was written as a non-integer literal. */\n readonly inexact: number;\n}\n\n/** Everything the scan collects. */\ninterface CxDocument {\n /** The read aspects by their (cy) name. */\n readonly aspects: Map<string, Held[]>;\n /** Attribute elements by table and attribute name. */\n readonly attributes: {\n readonly node: Map<string, Held[]>;\n readonly edge: Map<string, Held[]>;\n readonly network: Map<string, Held[]>;\n };\n /** Aspects kept verbatim in meta.extra.cx. */\n readonly kept: Map<string, unknown[]>;\n readonly structure: CxStructure;\n}\n\n/**\n * The elements of a read aspect.\n * @param doc - the document\n * @param name - the aspect\n * @returns the elements, empty when absent\n */\nfunction aspect(doc: CxDocument, name: string): readonly Held[] {\n return doc.aspects.get(name) ?? [];\n}\n\n/**\n * The inexact-literal bits of an element.\n * @param text - the element's JSON text\n * @param keys - the id keys to check, bit 1, 2, 4 in order\n * @returns the bits\n */\nfunction inexactBits(text: string, keys: readonly string[]): number {\n if (!/[0-9][.eE]/.test(text)) {\n return 0;\n }\n let bits = 0;\n keys.forEach((key, i) => {\n if (inexactLiteral(text, key)) {\n bits |= 1 << i;\n }\n });\n return bits;\n}\n\n/**\n * The attribute map of an attribute aspect.\n * @param doc - the document\n * @param name - the aspect name\n * @returns the map, or null for another aspect\n */\nfunction attributeTable(doc: CxDocument, name: string): Map<string, Held[]> | null {\n switch (name) {\n case \"nodeAttributes\":\n return doc.attributes.node;\n case \"edgeAttributes\":\n return doc.attributes.edge;\n case \"networkAttributes\":\n return doc.attributes.network;\n default:\n return null;\n }\n}\n\n/**\n * Check a numberVerification element: 2^48 - 1 (or Java's Long.MAX_VALUE), and only one.\n * @param value - the element\n * @param count - how many numberVerification elements were read, this one included\n * @param report - the report\n * @param line - its line\n */\nfunction checkNumberVerification(value: unknown, count: number, report: ImportReportBuilder, line: number): void {\n const raw = isRecord(value) ? value.longNumber : undefined;\n const digits = raw instanceof ExactInteger ? raw.digits : String(raw);\n if (count > 1 || !NUMBER_VERIFICATION_VALUES.has(digits)) {\n report.warning(\n \"validation-error\",\n CX_ISSUE.NUMBER_VERIFICATION,\n count > 1\n ? \"a second numberVerification element; ignored\"\n : `numberVerification holds ${shown(raw === undefined ? null : digits)}, not 281474976710655`,\n { line, element: \"numberVerification\" },\n );\n }\n}\n\n/**\n * Read the whole document through the streaming scanner, checking its structure.\n * @param input - the input\n * @param report - the report\n * @param options - the resolved options\n * @returns what was read\n */\nasync function readDocument(\n input: ImportInput,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n): Promise<CxDocument> {\n const structure = new CxStructure(report);\n const doc: CxDocument = {\n aspects: new Map(),\n attributes: { node: new Map(), edge: new Map(), network: new Map() },\n kept: new Map(),\n structure,\n };\n let sinceCheck = 0;\n let verifications = 0;\n const canonical = (name: string, line: number): string => {\n const renamed = OLD_ASPECT_NAMES[name] as string | undefined;\n if (renamed === undefined) {\n return name;\n }\n report.warnOnce(\n \"coercion\",\n CX_ISSUE.OLD_ASPECT_NAME,\n `the old aspect name \"${name}\" is read as \"${renamed}\"`,\n { line, element: name },\n `${CX_ISSUE.OLD_ASPECT_NAME}:${name}`,\n );\n return renamed;\n };\n const collect = (name: string, value: unknown, text: string, line: number, exact: boolean): void => {\n structure.element(name, value, line);\n if (ALSO_KEPT.has(name) || !READ_ASPECTS.has(name)) {\n if (!doc.kept.has(name)) {\n doc.kept.set(name, []);\n }\n doc.kept.get(name)?.push(exact ? plainJson(value) : value);\n }\n if (!READ_ASPECTS.has(name) || name === \"metaData\" || name === \"status\") {\n return;\n }\n if (name === \"numberVerification\") {\n checkNumberVerification(value, ++verifications, report, line);\n return;\n }\n let inexact = 0;\n if (name === \"nodes\") {\n inexact = inexactBits(text, [\"@id\"]);\n } else if (name === \"edges\") {\n inexact = inexactBits(text, [\"@id\", \"s\", \"t\"]);\n }\n const held: Held = { value, line, inexact };\n const table = attributeTable(doc, name);\n if (table !== null) {\n if (!isRecord(value) || typeof value.n !== \"string\") {\n report.error(\"missing-value\", MISSING_ID_CODE, `a ${name} element has no attribute name n; skipped`, {\n line,\n element: name,\n });\n return;\n }\n const key = value.n;\n if (!table.has(key)) {\n table.set(key, []);\n }\n table.get(key)?.push(held);\n return;\n }\n if (!doc.aspects.has(name)) {\n doc.aspects.set(name, []);\n }\n doc.aspects.get(name)?.push(held);\n };\n try {\n for await (const event of scanAspects(textChunks(input, report, options))) {\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(options.signal);\n }\n switch (event.kind) {\n case \"root\":\n report.fail(\n CX_ISSUE.NOT_CX,\n `a CX document is a JSON array of aspects; found ${isRecord(event.value) ? \"an object\" : shown(event.value)}`,\n { line: event.line },\n );\n break;\n case \"member\": {\n const { value } = event;\n if (isRecord(value) && \"CXVersion\" in value) {\n report.fail(\n CX_ISSUE.NOT_CX,\n `the document is CX2 (CXVersion ${shown(value.CXVersion)}), not CX version 1; read it with the cx2 importer`,\n { line: event.line },\n );\n }\n const keys = isRecord(value) ? Object.keys(value) : [];\n if (isRecord(value) && keys.length === 1 && isRecord(value[keys[0]])) {\n const name = canonical(keys[0], event.line);\n structure.block(name, event.line);\n collect(name, value[keys[0]], \"\", event.line, event.exact);\n break;\n }\n report.error(\n \"parse-error\",\n BAD_ASPECT_BLOCK_CODE,\n `a member of the document is ${keys.length > 1 ? `an object with ${keys.length} keys (${keys.join(\", \")})` : shown(value)}, not a one-key aspect fragment; skipped`,\n { line: event.line, element: keys[0] ?? null },\n );\n break;\n }\n case \"block\":\n structure.block(canonical(event.aspect, event.line), event.line);\n break;\n case \"element\": {\n const name = OLD_ASPECT_NAMES[event.aspect] ?? event.aspect;\n collect(name, event.value, event.text, event.line, event.exact);\n break;\n }\n case \"deep\":\n reportTooDeep(report, event);\n break;\n case \"extraKeys\":\n report.error(\n \"parse-error\",\n BAD_ASPECT_BLOCK_CODE,\n `the \"${event.aspect}\" fragment holds more keys (${event.keys.join(\", \")}); a fragment has one key, the others are skipped`,\n { line: event.line, element: event.aspect },\n );\n break;\n default:\n break;\n }\n }\n } catch (err) {\n if (err instanceof JsonScanError) {\n report.fail(err.empty ? EMPTY_INPUT_CODE : SYNTAX_CODE, err.message, { line: err.line });\n }\n throw err;\n }\n structure.checkCounts();\n return doc;\n}\n\n// ============================================================ graphs (subnetworks)\n\n/** One graph of a document: the root network, or one subnetwork of a collection. */\ninterface GraphPlan {\n readonly index: number;\n readonly name: string | null;\n /** The subnetwork's id, or null for the root network. */\n readonly subnetwork: NodeId | null;\n /** The member node ids, or null for every node. */\n readonly nodes: ReadonlySet<NodeId> | null;\n /** The member edge ids, or null for every edge. */\n readonly edges: ReadonlySet<NodeId> | null;\n /** The views of the graph, the first one first. */\n readonly views: readonly NodeId[];\n}\n\n/**\n * An id of a reference, or null when it is not one.\n * @param raw - the parsed reference\n * @returns the id\n */\nfunction refId(raw: unknown): NodeId | null {\n try {\n return cxId(raw).id;\n } catch {\n return null;\n }\n}\n\n/**\n * A member list: the ids of an array, or null for \"all\".\n * @param raw - the list\n * @returns the set, or null for every element\n */\nfunction memberSet(raw: unknown): Set<NodeId> | null {\n if (raw === \"all\") {\n return null;\n }\n const out = new Set<NodeId>();\n if (Array.isArray(raw)) {\n for (const item of raw) {\n const id = refId(item);\n if (id !== null) {\n out.add(id);\n }\n }\n }\n return out;\n}\n\n/**\n * The graphs of a document, in the order Cytoscape opens them.\n * @param doc - the document\n * @returns one plan per graph (at least one)\n */\nfunction graphPlans(doc: CxDocument): GraphPlan[] {\n const subs = new Map<NodeId, { nodes: Set<NodeId> | null; edges: Set<NodeId> | null }>();\n for (const { value } of aspect(doc, \"cySubNetworks\")) {\n const id = isRecord(value) ? refId(value[\"@id\"]) : null;\n if (id !== null && isRecord(value) && !subs.has(id)) {\n subs.set(id, { nodes: memberSet(value.nodes), edges: memberSet(value.edges) });\n }\n }\n const relationNames = new Map<NodeId, string>();\n const order: NodeId[] = [];\n const views = new Map<NodeId, NodeId[]>();\n const addView = (sub: NodeId, view: NodeId): void => {\n const list = views.get(sub) ?? [];\n if (!list.includes(view)) {\n list.push(view);\n }\n views.set(sub, list);\n };\n for (const { value } of aspect(doc, \"cyNetworkRelations\")) {\n if (!isRecord(value)) {\n continue;\n }\n const child = refId(value.c);\n if (child === null) {\n continue;\n }\n if (value.r === \"view\") {\n const parent = refId(value.p);\n if (parent !== null) {\n addView(parent, child);\n }\n continue;\n }\n if (typeof value.name === \"string\") {\n relationNames.set(child, value.name);\n }\n if (subs.has(child) && !order.includes(child)) {\n order.push(child);\n }\n }\n for (const { value } of aspect(doc, \"cyViews\")) {\n const view = isRecord(value) ? refId(value[\"@id\"]) : null;\n const sub = isRecord(value) ? refId(value.s) : null;\n if (view !== null && sub !== null) {\n addView(sub, view);\n }\n }\n for (const id of subs.keys()) {\n if (!order.includes(id)) {\n order.push(id);\n }\n }\n const networkName = (sub: NodeId | null): string | null => {\n let found: string | null = null;\n for (const { value } of doc.attributes.network.get(\"name\") ?? []) {\n if (!isRecord(value) || typeof value.v !== \"string\") {\n continue;\n }\n const scope = value.s === undefined ? null : refId(value.s);\n if (scope === sub) {\n return value.v;\n }\n if (scope === null) {\n found ??= value.v;\n }\n }\n return found;\n };\n if (order.length <= 1) {\n const sub = order.length === 1 ? order[0] : null;\n const members = sub === null ? undefined : subs.get(sub);\n let graphViews = sub === null ? [] : (views.get(sub) ?? []);\n if (graphViews.length === 0) {\n graphViews = [...new Set([...views.values()].flat())];\n }\n if (graphViews.length === 0) {\n graphViews = layoutViews(doc);\n }\n return [\n {\n index: 0,\n name: (sub === null ? null : (relationNames.get(sub) ?? null)) ?? networkName(sub),\n subnetwork: sub,\n nodes: members?.nodes ?? null,\n edges: members?.edges ?? null,\n views: graphViews,\n },\n ];\n }\n return order.map((sub, index) => ({\n index,\n name: relationNames.get(sub) ?? networkName(sub),\n subnetwork: sub,\n nodes: subs.get(sub)?.nodes ?? null,\n edges: subs.get(sub)?.edges ?? null,\n views: views.get(sub) ?? [],\n }));\n}\n\n/**\n * The distinct views the layout entries name, in order of appearance.\n * @param doc - the document\n * @returns the view ids\n */\nfunction layoutViews(doc: CxDocument): NodeId[] {\n const out: NodeId[] = [];\n for (const { value } of aspect(doc, \"cartesianLayout\")) {\n const view = isRecord(value) && value.view !== undefined ? refId(value.view) : null;\n if (view !== null && !out.includes(view)) {\n out.push(view);\n }\n }\n return out;\n}\n\n/**\n * How many elements a member set holds.\n * @param members - the set, or null for every element\n * @param total - the element count of the root network\n * @returns the count\n */\nfunction memberCount(members: ReadonlySet<NodeId> | null, total: number): number {\n return members === null ? total : members.size;\n}\n\n// ============================================================ the build\n\n/** One attribute column of the graph being built. */\ninterface AttributeColumn {\n readonly name: string;\n readonly type: CxType | null;\n /** null: values are kept as text (an unknown or conflicting type). */\n handle: ColumnHandle;\n}\n\n/** Reads one graph of a collected document into a sink. */\nclass CxReader {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly options: ResolvedImportOptions;\n\n private readonly zAs: \"column\" | \"position\";\n\n private readonly doc: CxDocument;\n\n private readonly plan: GraphPlan;\n\n private readonly direction: DirectionResolver;\n\n private readonly coercer: IdCoercer;\n\n /** Every node id of the root network. */\n private readonly rootNodes = new Set<NodeId>();\n\n /** Every edge id of the root network. */\n private readonly rootEdges = new Set<NodeId>();\n\n /** CX node id -> sink node index, for this graph. */\n private readonly nodeRows = new Map<NodeId, number>();\n\n /** CX edge id -> sink edge index, for this graph. */\n private readonly edgeRows = new Map<NodeId, number>();\n\n /** The subnetwork ids of the document. */\n private readonly subnetworks = new Set<NodeId>();\n\n private readonly dangling = new Map<string, number>();\n\n private nameHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private representsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private interactionHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private edgeIdHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private sinceCheck = 0;\n\n private idType: \"integer\" | \"mixed\" = \"integer\";\n\n private weighted = false;\n\n /**\n * Create the reader.\n * @param sink - the sink\n * @param report - the report\n * @param options - the resolved options\n * @param zAs - where z goes\n * @param doc - the collected document\n * @param plan - the graph to read\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n options: ResolvedImportOptions,\n zAs: \"column\" | \"position\",\n doc: CxDocument,\n plan: GraphPlan,\n ) {\n this.sink = sink;\n this.report = report;\n this.options = options;\n this.zAs = zAs;\n this.doc = doc;\n this.plan = plan;\n this.direction = new DirectionResolver(sink, report, options.onMixedDirection);\n this.coercer = new IdCoercer(options.ids);\n for (const { value } of aspect(doc, \"nodes\")) {\n const id = isRecord(value) ? refId(value[\"@id\"]) : null;\n if (id !== null) {\n this.rootNodes.add(id);\n }\n }\n for (const { value } of aspect(doc, \"edges\")) {\n const id = isRecord(value) ? refId(value[\"@id\"]) : null;\n if (id !== null) {\n this.rootEdges.add(id);\n }\n }\n for (const { value } of aspect(doc, \"cySubNetworks\")) {\n const id = isRecord(value) ? refId(value[\"@id\"]) : null;\n if (id !== null) {\n this.subnetworks.add(id);\n }\n }\n }\n\n /** Build the graph. */\n build(): void {\n const { report } = this;\n this.direction.setHeader(true);\n this.checkMembers();\n this.checkRootOnly();\n const nodeColumns = this.declareAttributes(\"node\");\n this.readNodes();\n this.readGroups();\n this.writeAttributes(\"node\", nodeColumns);\n this.readLayout();\n const edgeColumns = this.declareAttributes(\"edge\");\n this.readEdges();\n this.writeAttributes(\"edge\", edgeColumns);\n this.readNetworkAttributes();\n this.readVisualProperties();\n this.readProvenance();\n for (const [kind, count] of this.dangling) {\n report.warning(\"validation-error\", DANGLING_REFERENCE_CODE, `${count} ${kind}(s) name nothing; ignored`, {\n element: kind,\n });\n }\n this.setMeta();\n }\n\n // ------------------------------------------------------------ helpers\n\n /**\n * Count a reference that names nothing.\n * @param kind - what referred\n */\n private dangle(kind: string): void {\n this.dangling.set(kind, (this.dangling.get(kind) ?? 0) + 1);\n }\n\n /** Check the cancellation signal every ABORT_CHECK_INTERVAL elements. */\n private checkAbort(): void {\n if (++this.sinceCheck >= ABORT_CHECK_INTERVAL) {\n this.sinceCheck = 0;\n throwIfAborted(this.options.signal);\n }\n }\n\n /**\n * Whether a node id belongs to this graph.\n * @param id - the CX id\n * @returns true for a member\n */\n private inGraph(id: NodeId): boolean {\n return this.plan.nodes === null || this.plan.nodes.has(id);\n }\n\n /**\n * The key of the node and edge row maps for a CX id as an aspect writes it: the id the `ids`\n * option makes of it, which is what idOf() stored the element under.\n * @param raw - the CX id\n * @returns the row key\n */\n private key(raw: NodeId): NodeId {\n return this.options.ids === \"keep\" ? raw : this.coercer.value(raw);\n }\n\n /**\n * Whether a scoped value applies to this graph: unscoped, or scoped to its subnetwork. A scope\n * naming no subnetwork is counted as dangling.\n * @param scope - the element's s\n * @returns 1 for an unscoped value, 2 for this graph's own, 0 for another graph's\n */\n private scopeOf(scope: unknown): 0 | 1 | 2 {\n if (scope === undefined || scope === null) {\n return 1;\n }\n const id = refId(scope);\n if (id !== null && id === this.plan.subnetwork) {\n return 2;\n }\n if (id === null || !this.subnetworks.has(id)) {\n this.dangle(\"attribute subnetwork reference\");\n }\n return 0;\n }\n\n /**\n * The id of an element, by the CX id rule and the `ids` option.\n * @param raw - the parsed id\n * @param inexact - whether the literal was not a plain integer\n * @param element - the element name for issues\n * @param edgeId - whether this is an edge's own id (stored in the f64 id column, not kept as digits)\n * @returns the id, or null when it was reported\n */\n private idOf(raw: unknown, inexact: boolean, element: string, edgeId = false): NodeId | null {\n try {\n const parsed = cxId(raw, inexact);\n if (parsed.note === \"text\") {\n this.report.warnOnce(\n \"coercion\",\n ID_TEXT_TYPE_CODE,\n `${element}: the id ${shown(raw)} is not written as an integer; read as ${String(parsed.id)}`,\n { element },\n );\n } else if (parsed.note === \"precision\" && edgeId) {\n // the edge is told apart by its digits, but the id column is f64\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${element}: the edge id ${String(parsed.id)} is beyond 2^53; the id column holds the nearest double`,\n { element },\n `${PRECISION_CODE}:edge`,\n );\n } else if (parsed.note === \"precision\") {\n this.idType = \"mixed\";\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `${element}: the id ${String(parsed.id)} is beyond 2^53; kept as its digits (a string id)`,\n { element },\n );\n }\n return this.options.ids === \"keep\" ? parsed.id : this.coercer.value(parsed.id);\n } catch (err) {\n this.report.recordError(err, { element });\n return null;\n }\n }\n\n /**\n * Record a long value beyond 2^53 (once).\n * @param name - the attribute\n * @param digits - the value\n */\n private precision(name: string, digits: string): void {\n this.report.warnOnce(\n \"precision\",\n PRECISION_CODE,\n `\"${name}\": ${digits} is beyond 2^53; stored as the nearest double`,\n { element: name },\n `${PRECISION_CODE}:value`,\n );\n }\n\n /** Count the subnetwork members that name no node or edge. */\n private checkMembers(): void {\n for (const id of this.plan.nodes ?? []) {\n if (!this.rootNodes.has(id)) {\n this.dangle(\"subnetwork node member\");\n }\n }\n for (const id of this.plan.edges ?? []) {\n if (!this.rootEdges.has(id)) {\n this.dangle(\"subnetwork edge member\");\n }\n }\n }\n\n /**\n * Report the root network's nodes and edges that no subnetwork holds (W_CX_ROOT_ONLY): they\n * belong to no graph Cytoscape opens, so no graph of this file reads them.\n */\n private checkRootOnly(): void {\n const subs = aspect(this.doc, \"cySubNetworks\");\n if (subs.length === 0) {\n return;\n }\n const held = { nodes: new Set<NodeId>(), edges: new Set<NodeId>() };\n const all = { nodes: false, edges: false };\n for (const { value } of subs) {\n if (!isRecord(value)) {\n continue;\n }\n for (const key of [\"nodes\", \"edges\"] as const) {\n const members = memberSet(value[key]);\n if (members === null) {\n all[key] = true;\n } else {\n members.forEach((id) => held[key].add(id));\n }\n }\n }\n const lost = (key: \"nodes\" | \"edges\", root: ReadonlySet<NodeId>): number =>\n all[key] ? 0 : [...root].filter((id) => !held[key].has(id)).length;\n const nodes = lost(\"nodes\", this.rootNodes);\n const edges = lost(\"edges\", this.rootEdges);\n if (nodes + edges > 0) {\n this.report.warning(\n \"unsupported\",\n CX_ISSUE.ROOT_ONLY,\n `${nodes} node(s) and ${edges} edge(s) of the root network belong to no subnetwork (cySubNetworks); they are not read`,\n { element: \"cySubNetworks\" },\n );\n }\n }\n\n /**\n * The handle of a structural column, declared on first use.\n * @param domain - node or edge\n * @param current - the handle so far\n * @param decl - the declaration\n * @returns the handle\n */\n private structural(domain: \"node\" | \"edge\", current: ColumnHandle, decl: ColumnDecl): ColumnHandle {\n return current === INVALID_INDEX ? declareResolved(this.sink, domain, decl, this.report).handle : current;\n }\n\n // ------------------------------------------------------------ attribute columns\n\n /**\n * Type and declare the attribute columns of a table for this graph: each name's type is the\n * wider of the types its applicable elements and its cyTableColumn entries give (W_WIDENED when\n * they differ); a name with a type CX does not define keeps its values as text.\n * @param domain - node or edge\n * @returns the columns by attribute name\n */\n private declareAttributes(domain: \"node\" | \"edge\"): Map<string, AttributeColumn> {\n const columns = new Map<string, AttributeColumn>();\n const declared = this.tableColumns(domain === \"node\" ? \"node_table\" : \"edge_table\");\n const names = new Set<string>([...declared.keys(), ...this.doc.attributes[domain].keys()]);\n for (const name of names) {\n if (name === \"\" || (domain === \"edge\" && name === this.options.weightFrom)) {\n continue;\n }\n const types: CxType[] = [];\n let unknown = false;\n const tableType = declared.get(name);\n if (tableType !== undefined) {\n types.push(tableType);\n }\n for (const { value } of this.doc.attributes[domain].get(name) ?? []) {\n if (!isRecord(value) || this.scopePeek(value.s) === 0) {\n continue;\n }\n const type = cxType(value.d);\n if (type === null) {\n unknown = true;\n continue;\n }\n if (!types.some((t) => t.scalar === type.scalar && t.list === type.list)) {\n types.push(type);\n }\n }\n if (unknown) {\n this.report.warnOnce(\n \"unsupported\",\n UNKNOWN_ATTR_TYPE_CODE,\n `a ${domain} attribute \"${name}\" declares a data type CX does not define; its values are kept as text`,\n { element: name },\n `${UNKNOWN_ATTR_TYPE_CODE}:${domain}:${name}`,\n );\n types.push({ scalar: \"string\", list: false });\n }\n let type: CxType | null = types[0] ?? { scalar: \"string\", list: false };\n for (const other of types.slice(1)) {\n type = type === null ? null : widenType(type, other);\n }\n if (types.length > 1) {\n this.report.warnOnce(\n \"coercion\",\n WIDENED_CODE,\n `the ${domain} attribute \"${name}\" has the data types ${types.map(typeText).join(\", \")}; the column holds ${type === null ? \"their values as JSON\" : typeText(type)}`,\n { element: name },\n `${WIDENED_CODE}:${domain}:${name}`,\n );\n }\n if (this.isStructural(domain, name)) {\n columns.set(name, {\n name,\n type: { scalar: \"string\", list: false },\n handle: INVALID_INDEX as ColumnHandle,\n });\n continue;\n }\n columns.set(name, { name, type, handle: this.declareColumn(domain, name, type) });\n }\n return columns;\n }\n\n /**\n * Whether an attribute name is the column of a core field (n / r on nodes, i on edges).\n * @param domain - node or edge\n * @param name - the attribute name\n * @returns true for name, represents and interaction\n */\n private isStructural(domain: \"node\" | \"edge\", name: string): boolean {\n return domain === \"node\" ? name === \"name\" || name === \"represents\" : name === \"interaction\";\n }\n\n /**\n * The scope of a value without counting a dangling one (for typing, which runs before the values).\n * @param scope - the element's s\n * @returns as scopeOf()\n */\n private scopePeek(scope: unknown): 0 | 1 | 2 {\n if (scope === undefined || scope === null) {\n return 1;\n }\n const id = refId(scope);\n return id !== null && id === this.plan.subnetwork ? 2 : 0;\n }\n\n /**\n * The column types cyTableColumn declares for one table and this graph.\n * @param table - node_table, edge_table or network_table\n * @returns name -> type\n */\n private tableColumns(table: string): Map<string, CxType> {\n const out = new Map<string, CxType>();\n for (const { value } of aspect(this.doc, \"cyTableColumn\")) {\n if (!isRecord(value) || value.applies_to !== table || typeof value.n !== \"string\") {\n continue;\n }\n if (this.scopePeek(value.s) === 0) {\n continue;\n }\n const type = cxType(value.d);\n if (type !== null) {\n out.set(value.n, type);\n }\n }\n return out;\n }\n\n /**\n * Declare one attribute column.\n * @param domain - node or edge\n * @param name - the attribute name\n * @param type - the type, or null for a json column\n * @returns the handle\n */\n private declareColumn(domain: \"node\" | \"edge\", name: string, type: CxType | null): ColumnHandle {\n const { long } = this.options;\n const decl: ColumnDecl =\n type === null\n ? { name, dtype: \"json\", nullable: true, origin: { format: CX_FORMAT, id: null } }\n : {\n name,\n dtype: type.list ? \"list\" : scalarDtype(type.scalar, long),\n ...(type.list ? { itemDtype: scalarDtype(type.scalar, long) } : {}),\n nullable: true,\n origin: { format: CX_FORMAT, id: null, type: typeText(type) },\n };\n return declareResolved(this.sink, domain, decl, this.report).handle;\n }\n\n /**\n * Write the attribute values of a table: per element, its own subnetwork's value beats the\n * unscoped one; a repeated value of the same scope is the later one (W_DUPLICATE_ATTRIBUTE\n * when they differ).\n * @param domain - node or edge\n * @param columns - the columns from declareAttributes()\n */\n private writeAttributes(domain: \"node\" | \"edge\", columns: ReadonlyMap<string, AttributeColumn>): void {\n const rows = domain === \"node\" ? this.nodeRows : this.edgeRows;\n const root = domain === \"node\" ? this.rootNodes : this.rootEdges;\n for (const column of columns.values()) {\n const chosen = new Map<number, { scope: 1 | 2; value: unknown; d: unknown; line: number }>();\n for (const held of this.doc.attributes[domain].get(column.name) ?? []) {\n this.checkAbort();\n const { value, line } = held;\n if (!isRecord(value)) {\n this.report.error(\n \"parse-error\",\n BAD_ASPECT_BLOCK_CODE,\n `a ${domain}Attributes element is not an object`,\n {\n line,\n element: `${domain}Attributes`,\n },\n );\n continue;\n }\n const scope = this.scopeOf(value.s);\n if (scope === 0) {\n continue;\n }\n const target = refId(value.po);\n const row = target === null ? undefined : rows.get(this.key(target));\n if (row === undefined) {\n if (target === null || !root.has(target)) {\n this.dangle(`${domain} attribute target`);\n }\n continue;\n }\n if (value.v === undefined) {\n this.report.error(\n \"missing-value\",\n BAD_VALUE_CODE,\n `a ${domain}Attributes element for \"${column.name}\" has no v; skipped`,\n {\n line,\n element: column.name,\n },\n );\n continue;\n }\n if (value.v === null) {\n continue;\n }\n const previous = chosen.get(row);\n if (previous !== undefined && previous.scope > scope) {\n continue;\n }\n if (\n previous?.scope === scope &&\n JSON.stringify(previous.value) !== JSON.stringify(plainJson(value.v))\n ) {\n this.report.warnOnce(\n \"validation-error\",\n DUPLICATE_ATTRIBUTE_CODE,\n `${domain} ${shown(value.po)} has the attribute \"${column.name}\" twice; the later value wins`,\n { line, element: column.name },\n `${DUPLICATE_ATTRIBUTE_CODE}:${domain}:${column.name}`,\n );\n }\n chosen.set(row, { scope, value: value.v, d: value.d, line });\n }\n for (const [row, { value, d, line }] of chosen) {\n this.writeCell(domain, column, row, value, d, line);\n }\n }\n }\n\n /**\n * Parse and write one attribute cell. The core fields' attributes (name, represents,\n * interaction) go into their columns; a name attribute that differs from n wins with\n * W_DUPLICATE_ATTRIBUTE.\n * @param domain - node or edge\n * @param column - the column\n * @param row - the row\n * @param raw - the value\n * @param d - the data type the value was written with\n * @param line - its line\n */\n private writeCell(\n domain: \"node\" | \"edge\",\n column: AttributeColumn,\n row: number,\n raw: unknown,\n d: unknown,\n line: number,\n ): void {\n const element = `${domain} attribute \"${column.name}\"`;\n let value: unknown;\n if (column.type === null) {\n value = plainJson(raw, (digits) => {\n this.precision(column.name, digits);\n });\n } else {\n const own = cxType(d) ?? { scalar: \"string\", list: false };\n const parsed = parseValue(raw, own, this.options.long, (digits) => {\n this.precision(column.name, digits);\n });\n if (parsed === UNSET) {\n return;\n }\n if (parsed === BAD) {\n this.report.error(\n \"validation-error\",\n BAD_VALUE_CODE,\n `${element}: ${shown(raw)} is not a ${typeText(own)}; the cell is unset`,\n { line, element: column.name },\n );\n return;\n }\n value = toColumn(parsed, column.type);\n }\n let { handle } = column;\n if (this.isStructural(domain, column.name)) {\n handle = this.coreColumn(domain, column.name);\n const prior = this.coreValue(domain, row, column.name);\n if (prior !== undefined && prior !== value) {\n this.report.warnOnce(\n \"validation-error\",\n DUPLICATE_ATTRIBUTE_CODE,\n `a ${domain} has \"${column.name}\" both as its core field and as an attribute with another value; the attribute wins`,\n { line, element: column.name },\n `${DUPLICATE_ATTRIBUTE_CODE}:core:${column.name}`,\n );\n }\n }\n try {\n if (domain === \"node\") {\n this.sink.setNodeValue(handle, row, value);\n } else {\n this.sink.setEdgeValue(handle, row, value);\n }\n } catch (err) {\n this.report.recordError(err, { line, element: column.name });\n }\n }\n\n /** The core field values written per row (n, r), to detect a differing name attribute. */\n private readonly coreValues = new Map<string, Map<number, string>>();\n\n /**\n * The core field value of a row.\n * @param domain - node or edge\n * @param row - the row\n * @param name - name, represents or interaction\n * @returns the value, or undefined\n */\n private coreValue(domain: \"node\" | \"edge\", row: number, name: string): string | undefined {\n return this.coreValues.get(`${domain}:${name}`)?.get(row);\n }\n\n /**\n * The column of a core field.\n * @param domain - node or edge\n * @param name - name, represents or interaction\n * @returns the handle\n */\n private coreColumn(domain: \"node\" | \"edge\", name: string): ColumnHandle {\n if (domain === \"edge\") {\n this.interactionHandle = this.structural(\"edge\", this.interactionHandle, {\n name: \"interaction\",\n dtype: \"string\",\n nullable: true,\n origin: { format: CX_FORMAT, id: \"i\", type: \"string\" },\n });\n return this.interactionHandle;\n }\n if (name === \"name\") {\n this.nameHandle = this.structural(\"node\", this.nameHandle, {\n name: \"name\",\n dtype: \"string\",\n role: \"label\",\n nullable: true,\n origin: { format: CX_FORMAT, id: \"n\", type: \"string\" },\n });\n return this.nameHandle;\n }\n this.representsHandle = this.structural(\"node\", this.representsHandle, {\n name: \"represents\",\n dtype: \"string\",\n nullable: true,\n origin: { format: CX_FORMAT, id: \"r\", type: \"string\" },\n });\n return this.representsHandle;\n }\n\n // ------------------------------------------------------------ nodes, groups, layout\n\n /** Read the nodes of this graph. */\n private readNodes(): void {\n const { report, sink } = this;\n for (const held of aspect(this.doc, \"nodes\")) {\n this.checkAbort();\n const { value, line } = held;\n if (!isRecord(value)) {\n report.error(\n \"parse-error\",\n BAD_ASPECT_BLOCK_CODE,\n `a nodes element is ${shown(value)}, not an object`,\n {\n line,\n element: \"nodes\",\n },\n );\n report.counts.skippedNodes++;\n continue;\n }\n if (value[\"@id\"] === undefined || value[\"@id\"] === null) {\n report.error(\"missing-value\", MISSING_ID_CODE, \"a node has no @id\", { line, element: \"nodes\" });\n report.counts.skippedNodes++;\n continue;\n }\n const element = `node ${shown(value[\"@id\"])}`;\n const id = this.idOf(value[\"@id\"], (held.inexact & 1) !== 0, element);\n if (id === null) {\n report.counts.skippedNodes++;\n continue;\n }\n // membership lists hold CX ids as written, before the ids option coerces them\n if (!this.inGraph(refId(value[\"@id\"]) ?? id)) {\n continue;\n }\n let row = this.nodeRows.get(id);\n if (row !== undefined) {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `${element} is declared more than once; its fields are merged (the later values win)`,\n { line, element },\n );\n } else {\n try {\n row = sink.addNode(id);\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedNodes++;\n continue;\n }\n this.nodeRows.set(id, row);\n report.counts.nodes++;\n }\n this.writeCore(\"node\", row, \"name\", value.n, element, line);\n this.writeCore(\"node\", row, \"represents\", value.r, element, line);\n }\n }\n\n /**\n * Write a core string field (n, r, i).\n * @param domain - node or edge\n * @param row - the row\n * @param name - the column\n * @param raw - the value\n * @param element - the element name\n * @param line - its line\n */\n private writeCore(\n domain: \"node\" | \"edge\",\n row: number,\n name: string,\n raw: unknown,\n element: string,\n line: number,\n ): void {\n if (raw === undefined || raw === null) {\n return;\n }\n if (typeof raw !== \"string\") {\n this.report.error(\n \"validation-error\",\n BAD_VALUE_CODE,\n `${element}: ${name} is ${shown(raw)}, not a string`,\n {\n line,\n element,\n },\n );\n return;\n }\n const handle = this.coreColumn(domain, name);\n if (domain === \"node\") {\n this.sink.setNodeValue(handle, row, raw);\n } else {\n this.sink.setEdgeValue(handle, row, raw);\n }\n const key = `${domain}:${name}`;\n let values = this.coreValues.get(key);\n if (values === undefined) {\n values = new Map();\n this.coreValues.set(key, values);\n }\n values.set(row, raw);\n }\n\n /**\n * Read cyGroups: a group's members get the group node as their parent (parents when a node is in\n * several groups); a group whose id is not a node gets one (W_CX_GROUP_NODE_ADDED); collapsed is\n * a bool column on the group node.\n */\n private readGroups(): void {\n const groups = aspect(this.doc, \"cyGroups\");\n if (groups.length === 0) {\n return;\n }\n const parents = new Map<number, number[]>();\n const collapsed: [number, boolean][] = [];\n for (const { value, line } of groups) {\n if (!isRecord(value)) {\n continue;\n }\n const id = refId(value[\"@id\"]);\n if (id === null) {\n this.report.error(\"missing-value\", MISSING_ID_CODE, \"a cyGroups element has no @id\", {\n line,\n element: \"cyGroups\",\n });\n continue;\n }\n let groupRow = this.nodeRows.get(this.key(id));\n if (groupRow === undefined) {\n if (this.rootNodes.has(id) || !this.hasMemberIn(value.nodes)) {\n continue;\n }\n try {\n groupRow = this.sink.addNode(this.key(id));\n } catch (err) {\n this.report.recordError(err, { line, element: String(id) });\n continue;\n }\n this.nodeRows.set(this.key(id), groupRow);\n this.report.counts.nodes++;\n this.report.warning(\n \"coercion\",\n CX_ISSUE.GROUP_NODE_ADDED,\n `group ${String(id)} is not a node; its group node is added`,\n { line, element: String(id) },\n );\n }\n if (typeof value.n === \"string\" && this.coreValue(\"node\", groupRow, \"name\") === undefined) {\n this.writeCore(\"node\", groupRow, \"name\", value.n, `group ${String(id)}`, line);\n }\n if (typeof value.collapsed === \"boolean\") {\n collapsed.push([groupRow, value.collapsed]);\n }\n for (const raw of Array.isArray(value.nodes) ? (value.nodes as unknown[]) : []) {\n const member = refId(raw);\n const row = member === null ? undefined : this.nodeRows.get(this.key(member));\n if (row === undefined) {\n if (member === null || !this.rootNodes.has(member)) {\n this.report.error(\n \"missing-value\",\n UNKNOWN_PARENT_CODE,\n `group ${String(id)}: the member ${shown(raw)} is not a node`,\n { line, element: String(id) },\n );\n }\n continue;\n }\n if (this.closesCycle(parents, row, groupRow)) {\n this.report.error(\n \"validation-error\",\n PARENT_CYCLE_CODE,\n `group ${String(id)}: making ${shown(raw)} a member would close a parent cycle; that membership is dropped`,\n { line, element: String(id) },\n );\n continue;\n }\n const list = parents.get(row) ?? [];\n if (!list.includes(groupRow)) {\n list.push(groupRow);\n }\n parents.set(row, list);\n }\n }\n this.writeParents(parents);\n if (collapsed.length > 0) {\n const { handle } = declareResolved(\n this.sink,\n \"node\",\n {\n name: \"collapsed\",\n dtype: \"bool\",\n nullable: true,\n origin: { format: CX_FORMAT, namespace: \"cyGroups\" },\n },\n this.report,\n );\n for (const [row, flag] of collapsed) {\n this.sink.setNodeValue(handle, row, flag);\n }\n }\n }\n\n /**\n * Whether a member list names a node of this graph.\n * @param raw - the list\n * @returns true when one member is in the graph\n */\n private hasMemberIn(raw: unknown): boolean {\n return (\n Array.isArray(raw) &&\n raw.some((item) => {\n const id = refId(item);\n return id !== null && this.nodeRows.has(this.key(id));\n })\n );\n }\n\n /**\n * Whether making `child` a member of `group` closes a cycle: the group already is, through its\n * own parents, below the child.\n * @param parents - the memberships so far\n * @param child - the member row\n * @param group - the group row\n * @returns true for a cycle\n */\n private closesCycle(parents: ReadonlyMap<number, readonly number[]>, child: number, group: number): boolean {\n const stack = [group];\n const seen = new Set<number>();\n while (stack.length > 0) {\n const row = stack.pop() as number;\n if (row === child) {\n return true;\n }\n if (seen.has(row)) {\n continue;\n }\n seen.add(row);\n stack.push(...(parents.get(row) ?? []));\n }\n return false;\n }\n\n /**\n * Write the group memberships: a parent column, or a parents list column when a node is in\n * several groups.\n * @param parents - member row -> group rows\n */\n private writeParents(parents: ReadonlyMap<number, readonly number[]>): void {\n if (parents.size === 0) {\n return;\n }\n const several = [...parents.values()].some((list) => list.length > 1);\n const decl: ColumnDecl = several\n ? { name: \"parents\", dtype: \"list\", itemDtype: \"u32\", role: \"parents\", refersTo: \"node\", nullable: true }\n : { name: \"parent\", dtype: \"u32\", role: \"parent\", refersTo: \"node\", nullable: true };\n const { handle } = declareResolved(this.sink, \"node\", decl, this.report);\n for (const [row, list] of parents) {\n this.sink.setNodeValue(handle, row, several ? list : list[0]);\n }\n }\n\n /**\n * Read cartesianLayout for this graph's views: the first view is the position (y flipped), z the\n * z column, every other view a position@n column.\n */\n private readLayout(): void {\n const entries = aspect(this.doc, \"cartesianLayout\");\n if (entries.length === 0) {\n return;\n }\n const { views } = this.plan;\n const knownViews = this.allViews();\n const columns = new Map<number, ColumnHandle>();\n const zHandle = { current: INVALID_INDEX as ColumnHandle };\n const seen = new Set<string>();\n const point: [number, number, number] = [0, 0, 0];\n for (const { value, line } of entries) {\n this.checkAbort();\n if (!isRecord(value)) {\n continue;\n }\n const view = value.view === undefined || value.view === null ? null : refId(value.view);\n if (view !== null && knownViews.size > 0 && !knownViews.has(view)) {\n this.dangle(\"layout view reference\");\n continue;\n }\n const slot = view === null ? 0 : views.indexOf(view);\n if (slot < 0) {\n continue;\n }\n if (typeof value.x !== \"number\" || typeof value.y !== \"number\") {\n this.report.error(\n \"validation-error\",\n BAD_VALUE_CODE,\n `a cartesianLayout element for node ${shown(value.node)} has no numeric x and y; skipped`,\n { line, element: \"cartesianLayout\" },\n );\n continue;\n }\n const node = refId(value.node);\n const row = node === null ? undefined : this.nodeRows.get(this.key(node));\n if (row === undefined) {\n if (node === null || !this.rootNodes.has(node)) {\n this.dangle(\"layout entry\");\n }\n continue;\n }\n const key = `${slot}:${row}`;\n if (seen.has(key)) {\n this.report.warnOnce(\n \"validation-error\",\n DUPLICATE_ATTRIBUTE_CODE,\n `node ${shown(value.node)} has two layout entries for one view; the later wins`,\n { line, element: \"cartesianLayout\" },\n `${DUPLICATE_ATTRIBUTE_CODE}:layout`,\n );\n }\n seen.add(key);\n const z = typeof value.z === \"number\" ? value.z : null;\n point[0] = value.x;\n point[1] = flipY(value.y);\n point[2] = slot === 0 && this.zAs === \"position\" && z !== null ? z : 0;\n this.sink.setNodeValue(this.layoutColumn(columns, slot, views), row, point);\n if (slot === 0 && z !== null && this.zAs === \"column\") {\n zHandle.current = this.structural(\"node\", zHandle.current, zDecl(CX_FORMAT));\n this.sink.setNodeValue(zHandle.current, row, z);\n }\n }\n }\n\n /**\n * Every view id the document names.\n * @returns the set (empty when the document names none)\n */\n private allViews(): Set<NodeId> {\n const out = new Set<NodeId>();\n for (const { value } of aspect(this.doc, \"cyNetworkRelations\")) {\n if (isRecord(value) && value.r === \"view\") {\n const id = refId(value.c);\n if (id !== null) {\n out.add(id);\n }\n }\n }\n for (const { value } of aspect(this.doc, \"cyViews\")) {\n const id = isRecord(value) ? refId(value[\"@id\"]) : null;\n if (id !== null) {\n out.add(id);\n }\n }\n return out;\n }\n\n /**\n * The position column of a view slot, declared on first use.\n * @param columns - slot -> handle\n * @param slot - 0 for the position, n - 1 for position@n\n * @param views - the graph's views\n * @returns the handle\n */\n private layoutColumn(columns: Map<number, ColumnHandle>, slot: number, views: readonly NodeId[]): ColumnHandle {\n let handle = columns.get(slot);\n if (handle === undefined) {\n const base = positionDecl(CX_FORMAT, this.zAs === \"position\" && slot === 0 ? 3 : 2);\n const decl: ColumnDecl =\n slot === 0\n ? base\n : {\n ...base,\n name: `position@${slot + 1}`,\n role: undefined,\n origin: { format: CX_FORMAT, namespace: \"cytoscape\", id: String(views[slot]) },\n };\n ({ handle } = declareResolved(this.sink, \"node\", decl, this.report));\n columns.set(slot, handle);\n }\n return handle;\n }\n\n // ------------------------------------------------------------ edges\n\n /** Read the edges of this graph. */\n private readEdges(): void {\n const { report, sink } = this;\n const members = this.plan.edges;\n for (const held of aspect(this.doc, \"edges\")) {\n this.checkAbort();\n const { value, line } = held;\n if (!isRecord(value)) {\n report.error(\n \"parse-error\",\n BAD_ASPECT_BLOCK_CODE,\n `an edges element is ${shown(value)}, not an object`,\n {\n line,\n element: \"edges\",\n },\n );\n report.counts.skippedEdges++;\n continue;\n }\n if (value[\"@id\"] === undefined || value[\"@id\"] === null) {\n report.error(\"missing-value\", MISSING_ID_CODE, \"an edge has no @id\", { line, element: \"edges\" });\n report.counts.skippedEdges++;\n continue;\n }\n const element = `edge ${shown(value[\"@id\"])}`;\n const id = this.idOf(value[\"@id\"], (held.inexact & 1) !== 0, element, true);\n if (id === null) {\n report.counts.skippedEdges++;\n continue;\n }\n if (members !== null && !members.has(refId(value[\"@id\"]) ?? id)) {\n continue;\n }\n if (value.s === undefined || value.s === null || value.t === undefined || value.t === null) {\n report.error(\n \"missing-value\",\n MISSING_ENDPOINT_CODE,\n `${element} has no ${value.s === undefined || value.s === null ? \"s\" : \"t\"}`,\n {\n line,\n element,\n },\n );\n report.counts.skippedEdges++;\n continue;\n }\n const s = this.idOf(value.s, (held.inexact & 2) !== 0, element);\n const t = s === null ? null : this.idOf(value.t, (held.inexact & 4) !== 0, element);\n if (s === null || t === null) {\n report.counts.skippedEdges++;\n continue;\n }\n if (this.edgeRows.has(id)) {\n report.error(\n \"validation-error\",\n DUPLICATE_EDGE_ID_CODE,\n `${element} is declared more than once; the later edge is skipped`,\n { line, element },\n );\n report.counts.skippedEdges++;\n continue;\n }\n if (!this.endpoint(s, element, line) || !this.endpoint(t, element, line)) {\n report.counts.skippedEdges++;\n continue;\n }\n let weight: number | undefined;\n try {\n weight = this.weightOf(id);\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n continue;\n }\n const before = sink.edgeCount;\n let edge: number;\n try {\n edge = this.direction.addEdge(s, t, \"directed\", weight, { line, element });\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n continue;\n }\n if (weight !== undefined) {\n this.weighted = true;\n }\n report.counts.edges += sink.edgeCount - before;\n this.edgeRows.set(id, edge);\n this.edgeIdHandle = this.structural(\"edge\", this.edgeIdHandle, {\n name: uniqueColumnName(\"id\", \"cx\", (n) => sink.edgeColumn(n) !== INVALID_INDEX),\n dtype: \"f64\",\n role: \"id\",\n nullable: true,\n });\n sink.setEdgeValue(this.edgeIdHandle, edge, typeof id === \"number\" ? id : Number(id));\n this.writeCore(\"edge\", edge, \"interaction\", value.i, element, line);\n }\n }\n\n /**\n * Whether an endpoint is a node of this graph; under addMissingNodes it is created.\n * @param id - the endpoint\n * @param element - the edge name\n * @param line - its line\n * @returns false when the edge is to be skipped (reported)\n */\n private endpoint(id: NodeId, element: string, line: number): boolean {\n if (this.nodeRows.has(id)) {\n return true;\n }\n if (!this.options.addMissingNodes) {\n this.report.error(\n \"missing-value\",\n CX_ISSUE.UNKNOWN_NODE,\n `${element}: the endpoint ${String(id)} is not a node of the graph; the edge is skipped`,\n { line, element },\n );\n return false;\n }\n try {\n this.nodeRows.set(id, this.sink.addNode(id));\n } catch (err) {\n this.report.recordError(err, { line, element });\n return false;\n }\n this.report.counts.nodes++;\n return true;\n }\n\n /** The weight attribute values of the edges, by edge id (built once). */\n private weights: Map<NodeId, unknown> | null = null;\n\n /**\n * The weight of an edge: its weightFrom attribute, parsed as a number.\n * @param id - the edge id\n * @returns the weight, or undefined; E_INVALID_WEIGHT for a non-number\n */\n private weightOf(id: NodeId): number | undefined {\n const { weightFrom } = this.options;\n if (weightFrom === null) {\n return undefined;\n }\n if (this.weights === null) {\n this.weights = new Map();\n for (const { value } of this.doc.attributes.edge.get(weightFrom) ?? []) {\n if (isRecord(value) && this.scopePeek(value.s) !== 0) {\n const po = refId(value.po);\n if (po !== null && value.v !== undefined && value.v !== null) {\n this.weights.set(this.key(po), plainJson(value.v));\n }\n }\n }\n }\n const raw = this.weights.get(id);\n if (typeof raw === \"string\" && isNullText(raw)) {\n return undefined;\n }\n return weightFromValue(raw);\n }\n\n // ------------------------------------------------------------ network, visual properties, provenance\n\n /** Write the network attributes (unscoped and this subnetwork's, its own winning) as graph columns. */\n private readNetworkAttributes(): void {\n for (const [name, elements] of this.doc.attributes.network) {\n let chosen: Record<string, unknown> | null = null;\n let chosenScope = 0;\n for (const { value } of elements) {\n if (!isRecord(value)) {\n continue;\n }\n const scope = this.scopeOf(value.s);\n if (scope !== 0 && scope >= chosenScope) {\n chosen = value;\n chosenScope = scope;\n }\n }\n if (chosen === null || chosen.v === undefined || chosen.v === null || name === \"\") {\n continue;\n }\n const type = cxType(chosen.d);\n if (type === null) {\n this.report.warnOnce(\n \"unsupported\",\n UNKNOWN_ATTR_TYPE_CODE,\n `the network attribute \"${name}\" declares a data type CX does not define; kept as text`,\n { element: name },\n `${UNKNOWN_ATTR_TYPE_CODE}:network:${name}`,\n );\n }\n const effective = type ?? { scalar: \"string\", list: false };\n const parsed = parseValue(chosen.v, effective, this.options.long, (digits) => {\n this.precision(name, digits);\n });\n if (parsed === UNSET) {\n continue;\n }\n if (parsed === BAD) {\n this.report.error(\n \"validation-error\",\n BAD_VALUE_CODE,\n `the network attribute \"${name}\" is ${shown(chosen.v)}, not a ${typeText(effective)}; unset`,\n { element: name },\n );\n continue;\n }\n if ((name === \"name\" || name === \"description\") && typeof parsed === \"string\") {\n continue;\n }\n const scalar = scalarDtype(effective.scalar, this.options.long);\n try {\n this.sink.setGraphValue(name, parsed, {\n dtype: effective.list ? \"list\" : scalar,\n ...(effective.list ? { itemDtype: scalar } : {}),\n origin: { format: CX_FORMAT, id: null, type: typeText(effective) },\n });\n } catch (err) {\n this.report.recordError(err, { element: name });\n }\n }\n }\n\n /**\n * Read cyVisualProperties for this graph's views: per-element and network values become columns\n * (origin namespace cx.bypass); defaults, mappings and dependencies are style rules, kept and not\n * applied.\n */\n private readVisualProperties(): void {\n const entries = aspect(this.doc, \"cyVisualProperties\");\n // Cytoscape's table-cell styles: a visual property aspect graph-io keeps but does not read\n const tableStyles = TABLE_STYLE_ASPECTS.reduce((n, name) => n + (this.doc.kept.get(name)?.length ?? 0), 0);\n // the graph's own view (its first): the one its positions come from; the others stay in meta.extra.cx\n const views = new Set(this.plan.views.slice(0, 1));\n const columns = { node: new Map<string, [number, string][]>(), edge: new Map<string, [number, string][]>() };\n const network = new Map<string, string>();\n let defaults = 0;\n let mappings = 0;\n let dependencies = 0;\n for (const { value } of entries) {\n if (!isRecord(value)) {\n continue;\n }\n const view = value.view === undefined || value.view === null ? null : refId(value.view);\n if (view !== null && views.size > 0 && !views.has(view)) {\n continue;\n }\n const properties = isRecord(value.properties) ? value.properties : {};\n mappings += isRecord(value.mappings) ? Object.keys(value.mappings).length : 0;\n dependencies += isRecord(value.dependencies) ? Object.keys(value.dependencies).length : 0;\n switch (value.properties_of) {\n case \"nodes\":\n case \"edges\": {\n const domain = value.properties_of === \"nodes\" ? \"node\" : \"edge\";\n const target = refId(value.applies_to);\n const rows = domain === \"node\" ? this.nodeRows : this.edgeRows;\n const row = target === null ? undefined : rows.get(this.key(target));\n if (row === undefined) {\n if (target === null || !(domain === \"node\" ? this.rootNodes : this.rootEdges).has(target)) {\n this.dangle(`${domain} visual property entry`);\n }\n continue;\n }\n for (const [property, raw] of Object.entries(properties)) {\n const list = columns[domain].get(property) ?? [];\n list.push([row, typeof raw === \"string\" ? raw : JSON.stringify(raw)]);\n columns[domain].set(property, list);\n }\n break;\n }\n case \"network\":\n for (const [property, raw] of Object.entries(properties)) {\n network.set(property, typeof raw === \"string\" ? raw : JSON.stringify(raw));\n }\n break;\n default:\n defaults += Object.keys(properties).length;\n break;\n }\n }\n for (const domain of [\"node\", \"edge\"] as const) {\n for (const [property, cells] of columns[domain]) {\n const handle = declareFresh(\n this.sink,\n domain,\n {\n name: property,\n dtype: \"string\",\n nullable: true,\n origin: { format: CX_FORMAT, id: null, namespace: CX_BYPASS_NAMESPACE },\n },\n this.report,\n );\n for (const [row, text] of cells) {\n if (domain === \"node\") {\n this.sink.setNodeValue(handle, row, text);\n } else {\n this.sink.setEdgeValue(handle, row, text);\n }\n }\n }\n }\n for (const [property, text] of network) {\n try {\n this.sink.setGraphValue(property, text, {\n dtype: \"string\",\n origin: { format: CX_FORMAT, id: null, namespace: CX_BYPASS_NAMESPACE },\n });\n } catch (err) {\n this.report.recordError(err, { element: property });\n }\n }\n if (defaults + mappings + dependencies + tableStyles > 0) {\n const parts = [\n `cyVisualProperties: ${defaults} default(s), ${mappings} mapping(s), ${dependencies} dependenc(ies)`,\n ];\n if (tableStyles > 0) {\n parts.push(`${tableStyles} table style element(s)`);\n }\n this.report.warning(\n \"unsupported\",\n STYLES_NOT_IMPORTED_CODE,\n `the file's style rules are not applied (${parts.join(\"; \")}); they are kept in meta.extra.cx (style import is issue #706)`,\n { element: \"cyVisualProperties\" },\n );\n }\n }\n\n /**\n * Read the provenance aspects: citations and supports as extension tables cx:citations and\n * cx:supports, the node / edge links to them as list columns, functionTerms as a json column,\n * reifiedEdges as a u32 column referring to edges.\n */\n private readProvenance(): void {\n for (const name of [\"citations\", \"supports\"] as const) {\n this.extensionTable(`cx:${name}`, aspect(this.doc, name));\n }\n for (const [aspectName, domain, column] of [\n [\"nodeCitations\", \"node\", \"citations\"],\n [\"edgeCitations\", \"edge\", \"citations\"],\n [\"nodeSupports\", \"node\", \"supports\"],\n [\"edgeSupports\", \"edge\", \"supports\"],\n ] as const) {\n this.linkColumn(aspectName, domain, column);\n }\n const terms: [number, unknown][] = [];\n for (const { value } of aspect(this.doc, \"functionTerms\")) {\n if (!isRecord(value)) {\n continue;\n }\n const po = refId(value.po);\n const row = po === null ? undefined : this.nodeRows.get(this.key(po));\n if (row === undefined) {\n if (po === null || !this.rootNodes.has(po)) {\n this.dangle(\"functionTerms entry\");\n }\n continue;\n }\n const { po: _po, ...term } = value;\n terms.push([row, plainJson(term)]);\n }\n this.writeColumn(\"node\", \"functionTerm\", \"json\", null, terms);\n const reified: [number, number][] = [];\n for (const { value } of aspect(this.doc, \"reifiedEdges\")) {\n if (!isRecord(value)) {\n continue;\n }\n const node = refId(value.node);\n const edge = refId(value.edge);\n const row = node === null ? undefined : this.nodeRows.get(this.key(node));\n const edgeRow = edge === null ? undefined : this.edgeRows.get(this.key(edge));\n if (row === undefined || edgeRow === undefined) {\n if (node === null || !this.rootNodes.has(node) || edge === null || !this.rootEdges.has(edge)) {\n this.dangle(\"reifiedEdges entry\");\n }\n continue;\n }\n reified.push([row, edgeRow]);\n }\n if (reified.length > 0) {\n const { handle } = declareResolved(\n this.sink,\n \"node\",\n {\n name: \"reifiedEdge\",\n dtype: \"u32\",\n refersTo: \"edge\",\n nullable: true,\n origin: { format: CX_FORMAT, namespace: \"reifiedEdges\" },\n },\n this.report,\n );\n for (const [row, edge] of reified) {\n this.sink.setNodeValue(handle, row, edge);\n }\n }\n }\n\n /**\n * An extension table of a provenance aspect: an f64 `id` column and one json column per field.\n * @param name - the table name\n * @param elements - the elements\n */\n private extensionTable(name: string, elements: readonly Held[]): void {\n const records = elements.map((h) => h.value).filter(isRecord);\n if (records.length === 0) {\n return;\n }\n const fields = [...new Set(records.flatMap((r) => Object.keys(r)).filter((k) => k !== \"@id\"))];\n const decls: ColumnDecl[] = [\n { name: \"id\", dtype: \"f64\", nullable: true },\n ...fields.map((field): ColumnDecl => ({ name: field, dtype: \"json\", nullable: true })),\n ];\n const table = this.sink.addExtensionTable(name, decls);\n for (const record of records) {\n const id = refId(record[\"@id\"]);\n this.sink.addExtensionRow(table, [\n id === null ? null : Number(id),\n ...fields.map((field) => (record[field] === undefined ? null : plainJson(record[field]))),\n ]);\n }\n }\n\n /**\n * A list column of the citation or support ids a node or edge links to.\n * @param aspectName - nodeCitations, edgeCitations, nodeSupports or edgeSupports\n * @param domain - node or edge\n * @param column - citations or supports\n */\n private linkColumn(aspectName: string, domain: \"node\" | \"edge\", column: \"citations\" | \"supports\"): void {\n const rows = domain === \"node\" ? this.nodeRows : this.edgeRows;\n const root = domain === \"node\" ? this.rootNodes : this.rootEdges;\n const links = new Map<number, number[]>();\n for (const { value } of aspect(this.doc, aspectName)) {\n if (!isRecord(value)) {\n continue;\n }\n const targets = Array.isArray(value.po) ? (value.po as unknown[]) : [value.po];\n const ids = (Array.isArray(value[column]) ? (value[column] as unknown[]) : [])\n .map(refId)\n .filter((id): id is NodeId => id !== null)\n .map(Number);\n for (const raw of targets) {\n const target = refId(raw);\n const row = target === null ? undefined : rows.get(this.key(target));\n if (row === undefined) {\n if (target === null || !root.has(target)) {\n this.dangle(`${aspectName} entry`);\n }\n continue;\n }\n links.set(row, [...(links.get(row) ?? []), ...ids]);\n }\n }\n this.writeColumn(domain, column, \"list\", \"f64\", [...links]);\n }\n\n /**\n * Declare a column and write its cells (nothing when there are none).\n * @param domain - node or edge\n * @param name - the column name\n * @param dtype - the dtype\n * @param itemDtype - the list item dtype, or null\n * @param cells - row and value pairs\n */\n private writeColumn(\n domain: \"node\" | \"edge\",\n name: string,\n dtype: Dtype,\n itemDtype: ScalarDtype | null,\n cells: readonly (readonly [number, unknown])[],\n ): void {\n if (cells.length === 0) {\n return;\n }\n const decl: ColumnDecl = {\n name,\n dtype,\n ...(itemDtype === null ? {} : { itemDtype }),\n nullable: true,\n origin: { format: CX_FORMAT, namespace: \"provenance\" },\n };\n const { handle } = declareResolved(this.sink, domain, decl, this.report);\n for (const [row, value] of cells) {\n if (domain === \"node\") {\n this.sink.setNodeValue(handle, row, value);\n } else {\n this.sink.setEdgeValue(handle, row, value);\n }\n }\n }\n\n /** Record the metadata: source format, name, description, id type, the kept aspects. */\n private setMeta(): void {\n const describe = (key: string): string | null => {\n let found: string | null = null;\n for (const { value } of this.doc.attributes.network.get(key) ?? []) {\n if (isRecord(value) && typeof value.v === \"string\") {\n const scope = this.scopePeek(value.s);\n if (scope === 2) {\n return value.v;\n }\n if (scope === 1) {\n found ??= value.v;\n }\n }\n }\n return found;\n };\n const extra: Record<string, unknown> = Object.fromEntries(this.doc.kept);\n const groups = aspect(this.doc, \"cyGroups\").map((h) => plainJson(h.value));\n if (groups.length > 0) {\n extra.groups = groups;\n }\n if (this.plan.subnetwork !== null) {\n extra.subnetwork = this.plan.subnetwork;\n }\n const { weightFrom } = this.options;\n const name = this.plan.name ?? describe(\"name\");\n const description = describe(\"description\");\n const patch: GraphMetaPatch = {\n sourceFormat: CX_FORMAT,\n sourceVersion: \"1\",\n idType: this.idType,\n ...(name === null ? {} : { name }),\n ...(description === null ? {} : { description }),\n ...(this.weighted && weightFrom !== null\n ? { weightOrigin: { format: CX_FORMAT, id: null, title: weightFrom, type: \"double\", namespace: null } }\n : {}),\n extra: { cx: extra },\n };\n this.sink.setMeta(patch);\n }\n}\n\n// ============================================================ the plugin\n\n/**\n * Read a document, then build the graphs `pick` selects.\n * @param input - the input\n * @param options - the caller's options\n * @param sinkFor - the sink of graph i, or null to skip it\n * @param pick - which graph indexes to build, given the plans and the first report\n * @returns one report per built graph\n */\nasync function run(\n input: ImportInput,\n options: (CxImportOptions & CommonImportOptions) | undefined,\n sinkFor: (index: number) => GraphSink,\n pick: (plans: readonly GraphPlan[], report: ImportReportBuilder) => readonly number[],\n): Promise<ImportReport[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const zAs = zAsOption(options?.zAs);\n const first = new ImportReportBuilder(CX_FORMAT, resolved.errorLimit);\n reportUnusedOptions(options, first, USED_OPTIONS);\n const doc = await readDocument(input, first, resolved);\n const plans = graphPlans(doc);\n const chosen = pick(plans, first);\n const reports: ImportReport[] = [];\n chosen.forEach((index, k) => {\n const report = k === 0 ? first : new ImportReportBuilder(CX_FORMAT, resolved.errorLimit);\n const sink = sinkFor(index);\n reportSinkOptions(sink, options, report, true);\n new CxReader(sink, report, resolved, zAs, doc, plans[index]).build();\n throwIfAborted(resolved.signal);\n reports.push(report.finish());\n });\n return reports;\n}\n\n/**\n * The CX version 1 importer plugin (design section 1.2).\n */\nexport const cxImporter: GraphImporter<CxImportOptions> = Object.freeze({\n format: CX_FORMAT,\n extensions: Object.freeze([\".cx\"]),\n mimeTypes: Object.freeze([\"application/json\"]),\n\n /**\n * Confidence that the head is CX version 1: 0.95 when a top-level array starts with an object\n * whose first key is numberVerification or metaData (Cytoscape's file filter), 0.7 for another\n * CX aspect name.\n * @param head - the first bytes\n * @returns the confidence\n */\n sniff(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\").decode(head.subarray(0, 1024)).replace(/^\\uFEFF/, \"\");\n const match = /^\\s*\\[\\s*\\{\\s*\"((?:[^\"\\\\]|\\\\.)*)\"\\s*:/.exec(text);\n if (match === null) {\n return 0;\n }\n if (CX_FIRST_KEYS.includes(match[1])) {\n return 0.95;\n }\n return CX_ASPECT_KEYS.includes(match[1]) ? 0.7 : 0;\n },\n\n /**\n * Read one graph of a CX document into the sink: the root network, or the subnetwork\n * graphIndex / graphName picks (the first by default; W_MULTIPLE_GRAPHS names the others).\n * @param input - the text, bytes or stream\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the import report; ImportError on a fatal error or beyond the error limit\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: CxImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const [report] = await run(\n input,\n options,\n () => sink,\n (plans, first) => {\n const index = chooseGraph(\n plans.map((p) => p.name),\n options,\n first,\n );\n if (plans.length > 1) {\n first.warning(\n \"unsupported\",\n MULTIPLE_GRAPHS_CODE,\n `the collection holds ${plans.length} subnetworks; graph ${index} is read and ${plans.length - 1} skipped (importAll() reads every one)`,\n );\n }\n return [index];\n },\n );\n return report;\n },\n\n /**\n * Read every graph of a CX document: one per subnetwork of a collection, in the order of\n * cyNetworkRelations; the root network for any other document.\n * @param input - the text, bytes or stream\n * @param sinkFor - the sink of the graph with this index, called before its first push\n * @param options - format-specific and common options\n * @returns one report per graph\n */\n importAll(\n input: ImportInput,\n sinkFor: (index: number) => GraphSink,\n options?: CxImportOptions & CommonImportOptions,\n ): Promise<ImportReport[]> {\n return run(input, options, sinkFor, (plans) => plans.map((p) => p.index));\n },\n\n /**\n * List the graphs of a CX document with their names and member counts.\n * @param input - the text, bytes or stream\n * @param options - format-specific and common options\n * @returns one listing per graph\n */\n async listGraphs(\n input: ImportInput,\n options?: CxImportOptions & CommonImportOptions,\n ): Promise<readonly GraphListing[]> {\n const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);\n const report = new ImportReportBuilder(CX_FORMAT, resolved.errorLimit);\n const doc = await readDocument(input, report, resolved);\n const nodes = aspect(doc, \"nodes\").length;\n const edges = aspect(doc, \"edges\").length;\n return graphPlans(doc).map((plan) =>\n Object.freeze({\n index: plan.index,\n name: plan.name,\n nodes: memberCount(plan.nodes, nodes),\n edges: memberCount(plan.edges, edges),\n }),\n );\n },\n});\n"],"names":["type"],"mappings":"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"}
@@ -2,8 +2,8 @@ import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
2
2
  import { V as resolveExportOptions, X as pairFolding, L as declareResolved, q as UNKNOWN_ENCODING_CODE, E as ENCODING_FALLBACK_CODE, r as INVALID_ENCODING_CODE, s as INVALID_UTF8_CODE, O as OPTION_IGNORED_CODE, S as SINK_OPTION_CODE, an as HYPEREDGE_CODE, T as TOO_LARGE_CODE, j as DANGLING_REFERENCE_CODE, A as AMBIGUOUS_GRAPH_NAME_CODE, G as GRAPH_NOT_FOUND_CODE, M as MULTIPLE_GRAPHS_CODE, I as ID_MERGED_CODE, c as DUPLICATE_EDGE_ID_CODE, d as DUPLICATE_NODE_CODE, U as UNKNOWN_PARENT_CODE, B as BAD_VALUE_CODE, e as MISSING_ENDPOINT_CODE, f as MISSING_ID_CODE, t as SYNTAX_CODE, u as EMPTY_INPUT_CODE, v as resolveImportOptions, w as ImportReportBuilder, aG as readText, x as textChunks, F as reportSinkOptions, z as reportUnusedOptions, y as throwIfAborted, K as IdCoercer, J as DirectionResolver, Q as uniqueColumnName, H as chooseGraph } from "./report-B1z4WT9e.js";
3
3
  import { c as capabilities, L as LOSS, a as checkCapabilities, d as countMixedEdges } from "./export-Bh60Dv-n.js";
4
4
  import { e as explicitWeights, f as formatF32, a as formatF64, w as weightFromValue } from "./weights-Dzba96G3.js";
5
+ import { f as flipY, M as MAYBE_UNSAFE_INTEGER, e as rewriteNumbers, g as reviveNonstandard } from "./json-elements-DDS8N2Dd.js";
5
6
  import { j as joinText, e as encodeChunks } from "./writer-C7flM-Ih.js";
6
- import { M as MAYBE_UNSAFE_INTEGER, e as rewriteNumbers, g as reviveNonstandard } from "./json-elements-DDS8N2Dd.js";
7
7
  import { a as OBOGRAPHS_PREDICATE_TAGS, c as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, s as synonymScopeOf, O as OBO_NODE_COLUMNS } from "./ontology-BnrJ4I98.js";
8
8
  const JSON_DIALECTS = Object.freeze([
9
9
  "node-link",
@@ -1266,7 +1266,7 @@ function* writeCytoscape(snapshot, p) {
1266
1266
  w.key("position");
1267
1267
  w.open("{");
1268
1268
  w.member("x", numberText(value[0], f32, c.nonfinite));
1269
- w.member("y", numberText(value[1], f32, c.nonfinite));
1269
+ w.member("y", numberText(flipY(value[1]), f32, c.nonfinite));
1270
1270
  w.close("}");
1271
1271
  }
1272
1272
  }
@@ -3898,7 +3898,7 @@ function importCytoscape(ctx, root) {
3898
3898
  if (position !== void 0 && position !== null) {
3899
3899
  if (isJsonObject(position) && typeof position.x === "number" && typeof position.y === "number") {
3900
3900
  point[0] = position.x;
3901
- point[1] = position.y;
3901
+ point[1] = flipY(position.y);
3902
3902
  ctx.nodes.set(positionColumn, index, point);
3903
3903
  } else {
3904
3904
  report.error(
@@ -4167,4 +4167,4 @@ export {
4167
4167
  rankFormats as r,
4168
4168
  sniffFormat as s
4169
4169
  };
4170
- //# sourceMappingURL=importer-Wv4C4gaF.js.map
4170
+ //# sourceMappingURL=importer-eUREhBGj.js.map